From 18e1f4dc45138802ae7fb3cb95b3a8b3f4a26b92 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:03:31 +0200 Subject: [PATCH 1/9] Stop folder collapsing without touching css styles --- src/events/MutationObserver.ts | 8 +-- src/events/handleClick.ts | 54 ------------------- src/functions/folderNoteFunctions.ts | 2 +- src/main.ts | 81 +++++++++++++++++++++++----- styles.css | 34 ------------ 5 files changed, 71 insertions(+), 108 deletions(-) diff --git a/src/events/MutationObserver.ts b/src/events/MutationObserver.ts index ba749a0..c2c71a3 100644 --- a/src/events/MutationObserver.ts +++ b/src/events/MutationObserver.ts @@ -1,7 +1,7 @@ import { Keymap, Platform } from 'obsidian'; import FolderNotesPlugin from 'src/main'; import { getFolderNote } from 'src/functions/folderNoteFunctions'; -import { handleFolderClick, handleViewHeaderClick } from './handleClick'; +import { handleViewHeaderClick } from './handleClick'; import { getExcludedFolder } from 'src/ExcludeFolders/functions/folderFunctions'; import { applyCSSClassesToFolder } from 'src/functions/styleFunctions'; @@ -122,12 +122,6 @@ async function setupFolderTitle(folderTitle: HTMLElement, plugin: FolderNotesPlu if (Platform.isMobile && plugin.settings.disableOpenFolderNoteOnClick) return; - folderTitle.addEventListener('auxclick', (event: MouseEvent) => { - if (event.button === 1) handleFolderClick(event, plugin); - }, { capture: true }); - - folderTitle.onclick = (event: MouseEvent) => handleFolderClick(event, plugin); - plugin.registerDomEvent(folderTitle, 'pointerover', (event: MouseEvent) => { plugin.hoveredElement = folderTitle; plugin.mouseEvent = event; diff --git a/src/events/handleClick.ts b/src/events/handleClick.ts index 208cc44..91c6617 100644 --- a/src/events/handleClick.ts +++ b/src/events/handleClick.ts @@ -46,57 +46,3 @@ export async function handleViewHeaderClick(event: MouseEvent, plugin: FolderNot event.target.onclick = null; event.target.click(); } - -export async function handleFolderClick(event: MouseEvent, plugin: FolderNotesPlugin) { - if (!(event.target instanceof HTMLElement)) return; - event.target.setAttribute('data-initialized', 'false'); - if (!event || !event.target) return; - - if (!event.shiftKey) { - event.stopImmediatePropagation(); - } else { - return; - } - - const folderPath = event.target.parentElement?.getAttribute('data-path'); - if (!folderPath) { return; } - - const excludedFolder = getExcludedFolder(plugin, folderPath, true); - if (excludedFolder?.disableFolderNote) { - event.target.onclick = null; - event.target.click(); - return; - } else if (excludedFolder?.enableCollapsing || plugin.settings.enableCollapsing) { - event.target.onclick = null; - event.target.click(); - } - - const folderNote = getFolderNote(plugin, folderPath); - - if (folderNote) { - if (plugin.settings.openByClick) { - return openFolderNote(plugin, folderNote, event); - } else if (plugin.settings.openWithCtrl && Keymap.isModEvent(event) === 'tab') { - return openFolderNote(plugin, folderNote, event); - } else if (plugin.settings.openWithAlt && event.altKey) { - return openFolderNote(plugin, folderNote, event); - } else { - if (plugin.settings.enableCollapsing) return; - event.target.parentElement?.click(); - return; - } - } else if (event.altKey || Keymap.isModEvent(event) === 'tab') { - if ((plugin.settings.altKey && event.altKey) || (plugin.settings.ctrlKey && Keymap.isModEvent(event) === 'tab')) { - await createFolderNote(plugin, folderPath, true, undefined, true); - addCSSClassToTitleEL(folderPath, 'has-folder-note', plugin); - removeCSSClassFromEL(folderPath, 'has-not-folder-note', plugin); - return; - } - } else if (!folderNote) { - if (plugin.settings.enableCollapsing) return; - return event.target.parentElement?.click(); - } - - event.target.onclick = null; - event.target.click(); -} diff --git a/src/functions/folderNoteFunctions.ts b/src/functions/folderNoteFunctions.ts index 89f73fe..fe8eb9b 100644 --- a/src/functions/folderNoteFunctions.ts +++ b/src/functions/folderNoteFunctions.ts @@ -223,7 +223,7 @@ export async function tempDisableSync(plugin: FolderNotesPlugin, folder: TFolder export async function openFolderNote(plugin: FolderNotesPlugin, file: TAbstractFile, evt?: MouseEvent) { const path = file.path; - const focusExistingTab = plugin.settings.focusExistingTab; + const focusExistingTab = plugin.settings.focusExistingTab && plugin.settings.openInNewTab; const activeFilePath = plugin.app.workspace.getActiveFile()?.path; // If already active and not opening in new tab, do nothing diff --git a/src/main.ts b/src/main.ts index 0e0c851..990387a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,11 @@ -import { Plugin, TFile, TFolder, TAbstractFile, MarkdownPostProcessorContext, parseYaml, Notice, Keymap, WorkspaceLeaf, requireApiVersion } from 'obsidian'; +import { Plugin, TFile, TFolder, TAbstractFile, MarkdownPostProcessorContext, parseYaml, Notice, Keymap, WorkspaceLeaf, requireApiVersion, Platform } from 'obsidian'; import { DEFAULT_SETTINGS, FolderNotesSettings, SettingsTab } from './settings/SettingsTab'; import { Commands } from './Commands'; import { FileExplorerWorkspaceLeaf } from './globals'; -import { handleFolderClick } from './events/handleClick'; import { registerFileExplorerObserver, unregisterFileExplorerObserver } from './events/MutationObserver'; import { handleRename } from './events/handleRename'; -import { getFolderNote, getFolder, openFolderNote } from './functions/folderNoteFunctions'; +import { getFolderNote, getFolder, openFolderNote, createFolderNote } from './functions/folderNoteFunctions'; import { handleCreate } from './events/handleCreate'; import { FrontMatterTitlePluginHandler } from './events/FrontMatterTitle'; import { FolderOverviewSettings } from './obsidian-folder-overview/src/modals/Settings'; @@ -14,7 +13,7 @@ import { FolderOverview } from './obsidian-folder-overview/src/FolderOverview'; import { TabManager } from './events/TabManager'; import './functions/ListComponent'; import { handleDelete } from './events/handleDelete'; -import { addCSSClassToTitleEL, getEl, updateAllFileStyles } from './functions/styleFunctions'; +import { addCSSClassToTitleEL, getEl, removeCSSClassFromEL, updateAllFileStyles } from './functions/styleFunctions'; import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import { FileExplorerView, InternalPlugin } from 'obsidian-typings'; import { getFocusedItem } from './functions/utils'; @@ -139,6 +138,19 @@ export default class FolderNotesPlugin extends Plugin { this.registerMarkdownCodeBlockProcessor('folder-overview', (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => { this.handleOverviewBlock(source, el, ctx); }); + + this.registerEvent( + this.app.workspace.on('layout-change', () => { + const fileExplorerLeaf = this.app.workspace.getLeavesOfType('file-explorer')[0]; + if (!fileExplorerLeaf) return; + const container = fileExplorerLeaf.view.containerEl; + if (container) { + this.registerDomEvent(container, 'click', (evt: MouseEvent) => { + this.handleFileExplorerClick(evt); + }, true); + } + }) + ); } onLayoutReady() { @@ -152,6 +164,16 @@ export default class FolderNotesPlugin extends Plugin { this.tabManager = new TabManager(this); this.tabManager.updateTabs(); + const fileExplorerLeaf = this.app.workspace.getLeavesOfType('file-explorer')[0]; + if (fileExplorerLeaf) { + const container = fileExplorerLeaf.view.containerEl; + if (container) { + this.registerDomEvent(container, 'click', (evt: MouseEvent) => { + this.handleFileExplorerClick(evt); + }, true); + } + } + const fileExplorerPlugin = this.app.internalPlugins.getEnabledPluginById('file-explorer'); if (fileExplorerPlugin) { const originalRevealInFolder = fileExplorerPlugin.revealInFolder.bind(fileExplorerPlugin); @@ -219,6 +241,49 @@ export default class FolderNotesPlugin extends Plugin { }; } + handleFileExplorerClick(evt: MouseEvent) { + const target = evt.target as HTMLElement; + if (evt.shiftKey) return; + + if (Platform.isMobile && this.settings.disableOpenFolderNoteOnClick) return; + + // Check if the click is on a folder + const folderTitleEl = target.closest('.nav-folder-title') as HTMLElement; + if (!folderTitleEl) return; + + const onlyClickedOnFolderTitle = !!target.closest('.nav-folder-title-content'); + if (!this.settings.stopWhitespaceCollapsing && !onlyClickedOnFolderTitle) return; + + // Ignore clicks on the collapse icon + if (target.closest('.collapse-icon')) return; + + const folderPath = folderTitleEl.getAttribute('data-path'); + if (!folderPath) return; + + const excludedFolder = getExcludedFolder(this, folderPath, true); + if (excludedFolder?.disableFolderNote) return; + + const folderNote = getFolderNote(this, folderPath); + if (!folderNote && (evt.altKey || Keymap.isModEvent(evt) === 'tab')) { + if ((this.settings.altKey && evt.altKey) || (this.settings.ctrlKey && Keymap.isModEvent(evt) === 'tab')) { + createFolderNote(this, folderPath, true, undefined, true); + addCSSClassToTitleEL(folderPath, 'has-folder-note', this); + removeCSSClassFromEL(folderPath, 'has-not-folder-note', this); + return; + } + } + if (!(folderNote instanceof TFile)) return; + + if (this.settings.openWithCtrl && !evt.ctrlKey) return; + if (this.settings.openWithAlt && !evt.altKey) return; + + if (!this.settings.enableCollapsing) { + evt.preventDefault(); + evt.stopImmediatePropagation(); + } + + openFolderNote(this, folderNote, evt); + } handleOverviewBlock(source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) { const observer = new MutationObserver(() => { @@ -358,14 +423,6 @@ export default class FolderNotesPlugin extends Plugin { }); } - reloadHandlers() { - document.querySelectorAll('div.nav-folder-title-content') - .forEach((element: HTMLElement) => { - if (element.onclick) return; - element.onclick = (event: MouseEvent) => handleFolderClick(event, this); - }); - } - onunload() { unregisterFileExplorerObserver(); document.body.classList.remove('folder-notes-plugin'); diff --git a/styles.css b/styles.css index a7a0f85..ce65659 100644 --- a/styles.css +++ b/styles.css @@ -1,37 +1,3 @@ - - -.fn-whitespace-stop-collapsing .nav-folder-title-content { - flex-grow: 1 !important; - display: flex; - padding-bottom: 4px !important; - padding-top: 4px !important; -} - -.version-1-7-2.fn-whitespace-stop-collapsing .nav-files-container .collapse-icon { - padding-top: 4px !important; -} - -.mod-rtl .fn-whitespace-stop-collapsing .nav-folder-title-content { - padding-left: 8px !important; -} - -.fn-whitespace-stop-collapsing .nav-folder-title { - padding-bottom: 0 !important; - padding-top: 0 !important; -} - -body:not(.mod-rtl).fn-whitespace-stop-collapsing .nav-folder-title { - padding-right: 0 !important; -} - -.mod-rtl.fn-whitespace-stop-collapsing .nav-folder-title { - padding-left: 0 !important; -} - -.fn-whitespace-stop-collapsing .nav-folder-collapse-indicator { - margin-top: 4px !important; -} - body:not(.is-grabbing) .tree-item-self.fn-is-active:hover, body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { color: var(--nav-item-color-active); From b429ec20419bb879295d43505a52e2b1c6016ebb Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:07:07 +0200 Subject: [PATCH 2/9] Cleaner & more organized css file --- styles.css | 212 +++++++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 103 deletions(-) diff --git a/styles.css b/styles.css index ce65659..4d1c982 100644 --- a/styles.css +++ b/styles.css @@ -1,3 +1,27 @@ +/* ========================================================================== + General States & Utilities + ========================================================================== */ + +.hide, +.hide-folder .folder-name, +.hide-folder-note .is-folder-note { + display: none; +} + +.pointer-cursor, +.has-folder-note .nav-folder-title-content:hover, +.has-folder-note.view-header-breadcrumb:hover, +.nav-folder-collapse-indicator:hover, +.fn-delete-confirmation-modal-buttons span:hover, +.fn-delete-confirmation-modal-buttons input:hover { + cursor: pointer !important; +} + + +/* ========================================================================== + Tree Items + ========================================================================== */ + body:not(.is-grabbing) .tree-item-self.fn-is-active:hover, body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { color: var(--nav-item-color-active); @@ -5,36 +29,17 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { font-weight: var(--nav-item-weight-active); } -.has-folder-note .nav-folder-title-content:hover, -.has-folder-note.view-header-breadcrumb:hover { - cursor: pointer; -} -.hide { - display: none; -} - -.hide-folder-note .is-folder-note { - display: none; -} - -.hide-folder .folder-name { - display: none; -} - -.nav-folder-collapse-indicator:hover { - cursor: pointer; -} +/* ========================================================================== + Exclude Folder Settings + ========================================================================== */ .fn-excluded-folder-heading { margin-top: 0 !important; border-top: 1px solid var(--background-modifier-border); } -.add-exclude-folder-item { - padding-bottom: 0 !important; -} - +.add-exclude-folder-item, .fn-exclude-folder-list { padding-bottom: 0 !important; } @@ -57,7 +62,10 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { width: 100%; } -/* Modal styles */ + +/* ========================================================================== + Modal Styles + ========================================================================== */ .fn-backup-warning-modal .fn-modal-button-container { display: flex; @@ -69,9 +77,13 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { padding-bottom: 0; } +.fn-confirmation-modal .setting-item { + border-top: 0 !important; + padding-top: 0 !important; +} + :not(.is-phone) .fn-confirmation-modal-button { margin-right: 0.7rem; - } :not(.is-phone) .fn-delete-confirmation-modal-buttons { @@ -80,11 +92,6 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { margin-top: 10px; } -.fn-delete-confirmation-modal-buttons span:hover, -.fn-delete-confirmation-modal-buttons input:hover { - cursor: pointer; -} - :not(.is-phone) .fn-delete-confirmation-modal-buttons .fn-confirmation-modal-button { margin-left: auto; } @@ -103,32 +110,24 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { margin-top: 10px; } -/* Folder overview */ + +/* ========================================================================== + Folder Overview + ========================================================================== */ .folder-overview-container.fv-remove-edit-button .folder-overview-edit-button { display: none; } -.fn-folder-overview-collapse-icon { - display: block !important; -} - -.fn-has-no-files .collapse-icon { - display: none !important; -} - .folder-overview-list { - margin-top: 0 !important; - margin-bottom: 0 !important; - padding-bottom: 1.200 !important; - padding-top: 1.200 !important; + margin: 0 !important; + padding: 1.2em 0 !important; } .folder-overview-list-item { display: flex; } - .folder-overview-list::marker { color: var(--text-faint); } @@ -143,12 +142,17 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { grid-template-columns: repeat(3, 1fr); } +.folder-overview-grid-item { + flex: 1 1 auto; + margin: 0 1.2rem 1.2rem 0; +} + .folder-overview-grid-item-article article { - padding: 15px; - flex: 1; display: flex; flex-direction: column; justify-content: space-between; + padding: 15px; + flex: 1; } .folder-overview-grid-item-article a { @@ -170,52 +174,9 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { } -.folder-overview-grid-item { - flex: 1 1 auto; - margin-right: 1.200rem; - margin-bottom: 1.200rem; -} - -.fn-confirmation-modal .setting-item { - border-top: 0 !important; - padding-top: 0 !important; -} - -.pointer-cursor { - cursor: pointer !important; -} - - -/* Setting tab style */ -.fn-settings-tab-bar { - display: flex; - flex-direction: row; - padding-bottom: 1rem; -} - -.fn-settings-tab { - display: flex; - flex-direction: row; - align-items: center; - gap: var(--size-4-2); - padding: 10px; - border: 1px solid var(--background-modifier-border) -} - -.fn-settings-tab-active { - background-color: var(--color-accent); - color: var(--text-on-accent); -} - -.fn-settings-tab-name { - font-weight: bold; -} - -.fn-settings-tab-icon { - display: flex; -} - -/* File explorer & path styles */ +/* ========================================================================== + File Explorer & Path Styling + ========================================================================== */ .folder-note-underline .has-folder-note .nav-folder-title-content { text-decoration-line: underline; @@ -241,15 +202,57 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { font-style: italic; } -.fn-hide-collapse-icon .has-folder-note.only-has-folder-note .tree-item-icon { - display: none; + +/* Collapse Icon Handling */ + +.fn-folder-overview-collapse-icon { + display: block !important; } +.fn-has-no-files .collapse-icon, +.fn-hide-collapse-icon .has-folder-note.only-has-folder-note .tree-item-icon, .fn-hide-empty-collapse-icon .fn-empty-folder .tree-item-icon { display: none; } +/* ========================================================================== + Settings Tabs + ========================================================================== */ + +.fn-settings-tab-bar { + display: flex; + flex-direction: row; + padding-bottom: 1rem; +} + +.fn-settings-tab { + display: flex; + flex-direction: row; + align-items: center; + gap: var(--size-4-2); + padding: 10px; + border: 1px solid var(--background-modifier-border); +} + +.fn-settings-tab-active { + background-color: var(--color-accent); + color: var(--text-on-accent); +} + +.fn-settings-tab-name { + font-weight: bold; +} + +.fn-settings-tab-icon { + display: flex; +} + + +/* ========================================================================== + Suggestion Container + ========================================================================== */ + .fn-suggestion-container { position: absolute; overflow: hidden; @@ -265,12 +268,11 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { } -/* Mobile style overrides */ -.is-phone .fn-overview-folder-path .setting-item-control{ - display: block; -} +/* ========================================================================== + Whitelist Folder Input (Desktop & Mobile) + ========================================================================== */ -/* Default desktop layout */ +/* Default Desktop Layout */ .fn-whitelist-folder-input-container { display: flex; justify-content: space-between; @@ -282,9 +284,9 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { .fn-whitelist-folder-input-container input { flex-grow: 1; width: auto; - box-sizing: border-box; margin-right: 8px; - height: 40px; /* Ensure consistent height */ + height: 40px; + box-sizing: border-box; } .fn-whitelist-folder-buttons { @@ -296,12 +298,12 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { flex-shrink: 0; } -/* Mobile-specific layout */ +/* Mobile Overrides */ @media (max-width: 768px) { .fn-whitelist-folder-input-container { display: block; width: 100%; - text-align: center; /* Center elements vertically when stacked */ + text-align: center; } .fn-whitelist-folder-input-container input { @@ -316,4 +318,8 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { align-items: center; width: 100%; } + + .is-phone .fn-overview-folder-path .setting-item-control { + display: block; + } } From 415ccdd57f77640be6ed3b8e99dba77f3e792313 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:02:53 +0200 Subject: [PATCH 3/9] Clearer function names for style functions --- src/Commands.ts | 6 +- src/events/MutationObserver.ts | 4 +- src/events/handleClick.ts | 6 +- src/events/handleCreate.ts | 16 +-- src/events/handleDelete.ts | 12 +-- src/events/handleRename.ts | 40 ++++---- src/functions/folderNoteFunctions.ts | 20 ++-- src/functions/styleFunctions.ts | 141 ++++++++++++++------------- src/main.ts | 16 +-- src/settings/GeneralSettings.ts | 4 +- styles.css | 2 +- 11 files changed, 138 insertions(+), 129 deletions(-) diff --git a/src/Commands.ts b/src/Commands.ts index fb38b7f..8bf273c 100644 --- a/src/Commands.ts +++ b/src/Commands.ts @@ -4,7 +4,7 @@ import { getFolderNote, createFolderNote, deleteFolderNote, turnIntoFolderNote, import { ExcludedFolder } from './ExcludeFolders/ExcludeFolder'; import { getFolderPathFromString, getFileExplorerActiveFolder } from './functions/utils'; import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; -import { applyCSSClassesToFolder } from './functions/styleFunctions'; +import { updateCSSClassesForFolder } from './functions/styleFunctions'; @@ -406,7 +406,7 @@ export class Commands { this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter( (folder) => (folder.path !== file.path) && folder.showFolderNote); this.plugin.saveSettings(false); - applyCSSClassesToFolder(file.path, this.plugin); + updateCSSClassesForFolder(file.path, this.plugin); }); }); } else { @@ -424,7 +424,7 @@ export class Commands { excludedFolder.hideInSettings = true; excludedFolder.showFolderNote = true; addExcludedFolder(this.plugin, excludedFolder, false); - applyCSSClassesToFolder(file.path, this.plugin); + updateCSSClassesForFolder(file.path, this.plugin); }); }); } diff --git a/src/events/MutationObserver.ts b/src/events/MutationObserver.ts index c2c71a3..5b7aea8 100644 --- a/src/events/MutationObserver.ts +++ b/src/events/MutationObserver.ts @@ -3,7 +3,7 @@ import FolderNotesPlugin from 'src/main'; import { getFolderNote } from 'src/functions/folderNoteFunctions'; import { handleViewHeaderClick } from './handleClick'; import { getExcludedFolder } from 'src/ExcludeFolders/functions/folderFunctions'; -import { applyCSSClassesToFolder } from 'src/functions/styleFunctions'; +import { updateCSSClassesForFolder } from 'src/functions/styleFunctions'; let fileExplorerMutationObserver: MutationObserver | null = null; @@ -114,7 +114,7 @@ async function setupFolderTitle(folderTitle: HTMLElement, plugin: FolderNotesPlu if (!folderPath) return; folderTitle.dataset.initialized = 'true'; - await applyCSSClassesToFolder(folderPath, plugin); + await updateCSSClassesForFolder(folderPath, plugin); if (plugin.settings.frontMatterTitle.enabled) { plugin.fmtpHandler?.fmptUpdateFolderName({ id: '', result: false, path: folderPath, pathOnly: false }, false); diff --git a/src/events/handleClick.ts b/src/events/handleClick.ts index 91c6617..c4f46f0 100644 --- a/src/events/handleClick.ts +++ b/src/events/handleClick.ts @@ -2,7 +2,7 @@ import { Keymap, Platform } from 'obsidian'; import FolderNotesPlugin from 'src/main'; import { openFolderNote, createFolderNote, getFolderNote } from 'src/functions/folderNoteFunctions'; import { getExcludedFolder } from 'src/ExcludeFolders/functions/folderFunctions'; -import { addCSSClassToTitleEL, removeCSSClassFromEL } from 'src/functions/styleFunctions'; +import { addCSSClassToFileExplorerEl, removeCSSClassFromFileExplorerEL } from 'src/functions/styleFunctions'; export async function handleViewHeaderClick(event: MouseEvent, plugin: FolderNotesPlugin) { event.stopImmediatePropagation(); @@ -38,8 +38,8 @@ export async function handleViewHeaderClick(event: MouseEvent, plugin: FolderNot } else if (event.altKey || Keymap.isModEvent(event) === 'tab') { if ((plugin.settings.altKey && event.altKey) || (plugin.settings.ctrlKey && Keymap.isModEvent(event) === 'tab')) { await createFolderNote(plugin, folderPath, true, undefined, true); - addCSSClassToTitleEL(folderPath, 'has-folder-note', plugin); - removeCSSClassFromEL(folderPath, 'has-not-folder-note', plugin); + addCSSClassToFileExplorerEl(folderPath, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderPath, 'has-not-folder-note', plugin); return; } } diff --git a/src/events/handleCreate.ts b/src/events/handleCreate.ts index c1e6eff..bc130ee 100644 --- a/src/events/handleCreate.ts +++ b/src/events/handleCreate.ts @@ -2,7 +2,7 @@ import { TAbstractFile, TFolder, TFile } from 'obsidian'; import FolderNotesPlugin from 'src/main'; import { createFolderNote, getFolder, getFolderNote, turnIntoFolderNote } from 'src/functions/folderNoteFunctions'; import { getExcludedFolder } from 'src/ExcludeFolders/functions/folderFunctions'; -import { removeCSSClassFromEL, addCSSClassToTitleEL } from 'src/functions/styleFunctions'; +import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl } from 'src/functions/styleFunctions'; export async function handleCreate(file: TAbstractFile, plugin: FolderNotesPlugin) { if (!plugin.app.workspace.layoutReady) return; @@ -10,9 +10,9 @@ export async function handleCreate(file: TAbstractFile, plugin: FolderNotesPlugi const folder = file.parent; if (folder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToTitleEL(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); } else { - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } } @@ -32,7 +32,7 @@ async function handleFileCreation(file: TFile, plugin: FolderNotesPlugin) { turnIntoFolderNote(plugin, file, newFolder); } else if (folder instanceof TFolder) { if (folder.children.length >= 1) { - removeCSSClassFromEL(folder.path, 'fn-empty-folder', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'fn-empty-folder', plugin); } const detachedFolder = getExcludedFolder(plugin, folder.path, true); @@ -40,8 +40,8 @@ async function handleFileCreation(file: TFile, plugin: FolderNotesPlugin) { const folderNote = getFolderNote(plugin, folder.path); if (folderNote && folderNote.path === file.path) { - addCSSClassToTitleEL(folder.path, 'has-folder-note', plugin); - addCSSClassToTitleEL(file.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); } else if (plugin.settings.autoCreateForFiles) { if (!file.parent) { return; } const newFolder = await plugin.app.fileManager.createNewFolder(file.parent); @@ -56,7 +56,7 @@ async function handleFolderCreation(folder: TFolder, plugin: FolderNotesPlugin) const attachmentFolderPath = plugin.app.vault.getConfig('attachmentFolderPath') as string; const cleanAttachmentFolderPath = attachmentFolderPath?.replace('./', '') || ''; const attachmentsAreInRootFolder = attachmentFolderPath === './' || attachmentFolderPath === ''; - addCSSClassToTitleEL(folder.path, 'fn-empty-folder', plugin); + addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', plugin); if (!plugin.settings.autoCreateForAttachmentFolder) { if (!attachmentsAreInRootFolder && cleanAttachmentFolderPath === folder.name) return; @@ -71,5 +71,5 @@ async function handleFolderCreation(folder: TFolder, plugin: FolderNotesPlugin) if (folderNote) return; createFolderNote(plugin, folder.path, openFile, undefined, true); - addCSSClassToTitleEL(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); } diff --git a/src/events/handleDelete.ts b/src/events/handleDelete.ts index 324c9d5..3a9799b 100644 --- a/src/events/handleDelete.ts +++ b/src/events/handleDelete.ts @@ -1,16 +1,16 @@ import { TAbstractFile, TFolder, TFile } from 'obsidian'; import FolderNotesPlugin from 'src/main'; import { getFolderNote, getFolder, deleteFolderNote } from 'src/functions/folderNoteFunctions'; -import { removeCSSClassFromEL, addCSSClassToTitleEL } from 'src/functions/styleFunctions'; +import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl } from 'src/functions/styleFunctions'; import { getFolderPathFromString } from 'src/functions/utils'; export function handleDelete(file: TAbstractFile, plugin: FolderNotesPlugin) { const folder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(file.path)); if (folder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToTitleEL(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); } else { - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } } @@ -19,14 +19,14 @@ export function handleDelete(file: TAbstractFile, plugin: FolderNotesPlugin) { if (!folder) { return; } const folderNote = getFolderNote(plugin, folder.path); if (folderNote) { return; } - removeCSSClassFromEL(folder.path, 'has-folder-note', plugin); - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } if (!(file instanceof TFolder)) { return; } const folderNote = getFolderNote(plugin, file.path); if (!folderNote) { return; } - removeCSSClassFromEL(folderNote.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); if (!plugin.settings.syncDelete) { return; } deleteFolderNote(plugin, folderNote, false); } diff --git a/src/events/handleRename.ts b/src/events/handleRename.ts index e0753df..8b3c91f 100644 --- a/src/events/handleRename.ts +++ b/src/events/handleRename.ts @@ -3,7 +3,7 @@ import FolderNotesPlugin from 'src/main'; import { extractFolderName, getFolderNote, getFolderNoteFolder } from '../functions/folderNoteFunctions'; import { getExcludedFolder, addExcludedFolder, updateExcludedFolder, deleteExcludedFolder, getDetachedFolder } from '../ExcludeFolders/functions/folderFunctions'; import { ExcludedFolder } from 'src/ExcludeFolders/ExcludeFolder'; -import { removeCSSClassFromEL, addCSSClassToTitleEL } from 'src/functions/styleFunctions'; +import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl } from 'src/functions/styleFunctions'; import { getFolderPathFromString, removeExtension, getFileNameFromPathString } from 'src/functions/utils'; export function handleRename(file: TAbstractFile, oldPath: string, plugin: FolderNotesPlugin) { @@ -12,17 +12,17 @@ export function handleRename(file: TAbstractFile, oldPath: string, plugin: Folde const isRename = (file.parent?.path === getFolderPathFromString(oldPath)); if (folder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToTitleEL(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); } else { - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } } if (oldFolder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(oldFolder)) { - addCSSClassToTitleEL(oldFolder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(oldFolder.path, 'only-has-folder-note', plugin); } else { - removeCSSClassFromEL(oldFolder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder.path, 'only-has-folder-note', plugin); } } @@ -84,9 +84,9 @@ export async function handleFileMove(file: TFile, oldPath: string, plugin: Folde } else if (oldFolder && oldFolder.name === oldFileName && newFolder?.path !== oldFolder.path) { // the note has been moved somewhere and is no longer a folder note // cleanup css on the folder and note - removeCSSClassFromEL(oldFolder.path, 'has-folder-note', plugin); - removeCSSClassFromEL(file.path, 'is-folder-note', plugin); - removeCSSClassFromEL(oldPath, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldPath, 'is-folder-note', plugin); } } @@ -103,7 +103,7 @@ export async function handleFolderRename(file: TFolder, oldPath: string, plugin: const excludedFolder = getExcludedFolder(plugin, file.path, true); if (excludedFolder?.disableSync && !folderNote) { - return removeCSSClassFromEL(file.path, 'has-folder-note', plugin); + return removeCSSClassFromFileExplorerEL(file.path, 'has-folder-note', plugin); } if (!plugin.settings.syncFolderName) { return; } @@ -143,21 +143,21 @@ export async function fmptUpdateFileName(file: TFile, oldPath: string, plugin: F const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file); if (!excludedFolder?.disableFolderNote && folderName === newFolder?.name && !detachedExcludedFolder) { - addCSSClassToTitleEL(file.path, 'is-folder-note', plugin); - addCSSClassToTitleEL(newFolder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(newFolder.path, 'has-folder-note', plugin); return; } else if (excludedFolder?.disableFolderNote || (folderName !== newFolder?.name)) { - removeCSSClassFromEL(file.path, 'is-folder-note', plugin); - removeCSSClassFromEL(newFolder?.path || '', 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(newFolder?.path || '', 'has-folder-note', plugin); } if (excludedFolder?.disableSync || !plugin.settings.syncFolderName) { return; } if (folderName === newFolder?.name) { - addCSSClassToTitleEL(file.path, 'is-folder-note', plugin); - removeCSSClassFromEL(oldFolder?.path, 'has-folder-note', plugin); - addCSSClassToTitleEL(newFolder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder?.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(newFolder.path, 'has-folder-note', plugin); return; } @@ -175,12 +175,12 @@ export async function fmptUpdateFileName(file: TFile, oldPath: string, plugin: F async function renameFolderOnFileRename(file: TFile, oldPath: string, oldFolder: TAbstractFile, plugin: FolderNotesPlugin) { const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename); if (!newFolderName) { - removeCSSClassFromEL(oldFolder.path, 'has-folder-note', plugin); - removeCSSClassFromEL(file.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); return; } else if (newFolderName === oldFolder.name) { - addCSSClassToTitleEL(oldFolder.path, 'has-folder-note', plugin); - addCSSClassToTitleEL(file.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(oldFolder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); return; } diff --git a/src/functions/folderNoteFunctions.ts b/src/functions/folderNoteFunctions.ts index fe8eb9b..69b104d 100644 --- a/src/functions/folderNoteFunctions.ts +++ b/src/functions/folderNoteFunctions.ts @@ -7,7 +7,7 @@ import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcluded import { ExcludedFolder } from '../ExcludeFolders/ExcludeFolder'; import { openExcalidrawView } from './excalidraw'; import { AskForExtensionModal } from 'src/modals/AskForExtension'; -import { getEl, addCSSClassToTitleEL, removeCSSClassFromEL } from 'src/functions/styleFunctions'; +import { getFileExplorerElement, addCSSClassToFileExplorerEl, removeCSSClassFromFileExplorerEL } from 'src/functions/styleFunctions'; import { getFolderNameFromPathString, getFolderPathFromString, removeExtension } from 'src/functions/utils'; const defaultExcalidrawTemplate = `--- @@ -60,7 +60,7 @@ export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: st if (detachedFolder && folderNote?.extension !== extension && folderNote) { deleteExcludedFolder(plugin, detachedFolder); - removeCSSClassFromEL(folderNote?.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote?.path, 'is-folder-note', plugin); const folder = plugin.app.vault.getAbstractFileByPath(folderPath) as TFolder; if (!folderNote || folderNote.basename !== fileName) return; let count = 1; @@ -128,7 +128,7 @@ export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: st const folder = getFolder(plugin, folderNote); if (!folder) { return; } - plugin.activeFolderDom = getEl(folder.path, plugin); + plugin.activeFolderDom = getFileExplorerElement(folder.path, plugin); if (plugin.activeFolderDom) plugin.activeFolderDom.addClass('fn-is-active'); } await leaf.openFile(folderNote); @@ -144,8 +144,8 @@ export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: st const folder = plugin.app.vault.getAbstractFileByPath(folderPath); if (!(folder instanceof TFolder)) return; - addCSSClassToTitleEL(path, 'is-folder-note', plugin, true); - addCSSClassToTitleEL(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(path, 'is-folder-note', plugin, true); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); } export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, folder: TFolder, folderNote?: TFile | null | TAbstractFile, skipConfirmation?: boolean) { @@ -156,7 +156,7 @@ export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, if (plugin.settings.showRenameConfirmation && !skipConfirmation && !detachedExcludedFolder) { return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open(); } - removeCSSClassFromEL(folderNote.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); const [excludedFolder, excludedFolderExisted, disabledSync] = await tempDisableSync(plugin, folder); @@ -190,15 +190,15 @@ export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, } await plugin.app.fileManager.renameFile(file, path); - addCSSClassToTitleEL(path, 'is-folder-note', plugin, true); - addCSSClassToTitleEL(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(path, 'is-folder-note', plugin, true); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); if (plugin.activeFolderDom) { plugin.activeFolderDom.removeClass('fn-is-active'); plugin.activeFolderDom = null; } - plugin.activeFolderDom = getEl(folder.path, plugin); + plugin.activeFolderDom = getFileExplorerElement(folder.path, plugin); if (plugin.activeFolderDom) plugin.activeFolderDom.addClass('fn-is-active'); } @@ -265,7 +265,7 @@ export async function deleteFolderNote(plugin: FolderNotesPlugin, file: TFile, d (excludedFolder) => (excludedFolder.path !== folder.path) && excludedFolder.showFolderNote); plugin.saveSettings(false); - removeCSSClassFromEL(folder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); switch (plugin.settings.deleteFilesAction) { case 'trash': await plugin.app.vault.trash(file, true); diff --git a/src/functions/styleFunctions.ts b/src/functions/styleFunctions.ts index 7211e55..8e2e065 100644 --- a/src/functions/styleFunctions.ts +++ b/src/functions/styleFunctions.ts @@ -6,37 +6,40 @@ import { getFileExplorer } from './utils'; import { ExcludedFolder } from 'src/ExcludeFolders/ExcludeFolder'; import FolderOverviewPlugin from 'src/obsidian-folder-overview/src/main'; -export function updateAllFileStyles(forceReload = false, plugin: FolderNotesPlugin) { +/** + * @description Refreshes the CSS classes for all folder notes in the file explorer. + */ +export function refreshAllFolderStyles(forceReload = false, plugin: FolderNotesPlugin) { if (plugin.activeFileExplorer === getFileExplorer(plugin) && !forceReload) { return; } plugin.activeFileExplorer = getFileExplorer(plugin); plugin.app.vault.getAllLoadedFiles().forEach(async (file) => { if (!(file instanceof TFolder)) { return; } const folderNote = getFolderNote(plugin, file.path); if (!folderNote) { - removeCSSClassFromEL(file?.path, 'has-folder-note', plugin); - removeCSSClassFromEL(file?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file?.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file?.path, 'only-has-folder-note', plugin); plugin.isEmptyFolderNoteFolder(file); return; } const excludedFolder = getExcludedFolder(plugin, file.path, true); - // cleanup after ourselves - // Incase settings have changed if (excludedFolder?.disableFolderNote) { - removeCSSClassFromEL(folderNote.path, 'is-folder-note', plugin); - removeCSSClassFromEL(file.path, 'has-folder-note', plugin); - removeCSSClassFromEL(file?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file?.path, 'only-has-folder-note', plugin); } else { if (!excludedFolder?.showFolderNote) { - addCSSClassToTitleEL(folderNote.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(folderNote.path, 'is-folder-note', plugin); } - addCSSClassesToFolder(file, plugin); + markFolderWithFolderNoteClasses(file, plugin); } }); } - -export async function applyCSSClassesToFolder(folderPath: string, plugin: FolderNotesPlugin) { +/** + * @description Updates the CSS classes for a specific folder in the file explorer. + */ +export async function updateCSSClassesForFolder(folderPath: string, plugin: FolderNotesPlugin) { const folder = plugin.app.vault.getAbstractFileByPath(folderPath); if (!folder || !(folder instanceof TFolder)) { return; } @@ -44,123 +47,127 @@ export async function applyCSSClassesToFolder(folderPath: string, plugin: Folder const detachedFolderNote = getDetachedFolder(plugin, folder.path); if (folder.children.length === 0) { - addCSSClassToTitleEL(folder.path, 'fn-empty-folder', plugin); + addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', plugin); } if (!folderNote || detachedFolderNote) { - removeCSSClassFromEL(folder?.path, 'has-folder-note', plugin); - removeCSSClassFromEL(folder?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder?.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder?.path, 'only-has-folder-note', plugin); return; } const excludedFolder = getExcludedFolder(plugin, folder.path, true); if (excludedFolder?.disableFolderNote) { - removeCSSClassFromEL(folderNote.path, 'is-folder-note', plugin); - removeCSSClassFromEL(folder.path, 'has-folder-note', plugin); - removeCSSClassFromEL(folder?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder?.path, 'only-has-folder-note', plugin); } else { - addCSSClassesToFolder(folder, plugin); + console.log('updateCSSClassesForFolder', folder.path, 'has folder note'); + markFolderWithFolderNoteClasses(folder, plugin); if (excludedFolder?.showFolderNote) { - removeCSSClassFromFolderNote(folderNote, plugin); + unmarkFileAsFolderNote(folderNote, plugin); return; } if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToTitleEL(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); } else { - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } } - addCSSClassesToBothFolderAndNote(folderNote, folder, plugin); + markFolderAndNoteWithClasses(folderNote, folder, plugin); } -export async function applyCSSClassesToFolderNote(filePath: string, plugin: FolderNotesPlugin) { +/** + * @description Updates the CSS classes for a folder note file in the file explorer and then also updates the folder it belongs to. + */ +export async function updateCSSClassesForFolderNote(filePath: string, plugin: FolderNotesPlugin) { const file = plugin.app.vault.getAbstractFileByPath(filePath); if (!file || !(file instanceof TFile)) { return; } const folder = getFolder(plugin, file); if (!folder || !(folder instanceof TFolder)) { return; } - applyCSSClassesToFolder(folder.path, plugin); - + updateCSSClassesForFolder(folder.path, plugin); } -export function addCSSClassesToBothFolderAndNote(file: TFile, folder: TFolder, plugin: FolderNotesPlugin) { - addCSSClassToFolderNote(file, plugin); - addCSSClassesToFolder(folder, plugin); +export function markFolderAndNoteWithClasses(file: TFile, folder: TFolder, plugin: FolderNotesPlugin) { + markFileAsFolderNote(file, plugin); + markFolderWithFolderNoteClasses(folder, plugin); } -export function removeCSSClassesFromBothFolderAndNote(folder: TFolder, file: TFile, plugin: FolderNotesPlugin) { - removeCSSClassFromFolderNote(file, plugin); - removeCSSClassesFromFolder(folder, plugin); +export function clearFolderAndNoteClasses(folder: TFolder, file: TFile, plugin: FolderNotesPlugin) { + unmarkFileAsFolderNote(file, plugin); + clearFolderNoteClassesFromFolder(folder, plugin); } -export function addCSSClassesToFolder(folder: TFolder, plugin: FolderNotesPlugin) { - addCSSClassToTitleEL(folder.path, 'has-folder-note', plugin); +export function markFolderWithFolderNoteClasses(folder: TFolder, plugin: FolderNotesPlugin) { + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToTitleEL(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); } else { - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } } -export function addCSSClassToFolderNote(file: TFile, plugin: FolderNotesPlugin) { - addCSSClassToTitleEL(file.path, 'is-folder-note', plugin); +export function markFileAsFolderNote(file: TFile, plugin: FolderNotesPlugin) { + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); } -export function removeCSSClassFromFolderNote(file: TFile, plugin: FolderNotesPlugin) { - removeCSSClassFromEL(file.path, 'is-folder-note', plugin); +export function unmarkFileAsFolderNote(file: TFile, plugin: FolderNotesPlugin) { + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); } -export function removeCSSClassesFromFolder(folder: TFolder, plugin: FolderNotesPlugin) { - removeCSSClassFromEL(folder.path, 'has-folder-note', plugin); - removeCSSClassFromEL(folder.path, 'only-has-folder-note', plugin); +export function clearFolderNoteClassesFromFolder(folder: TFolder, plugin: FolderNotesPlugin) { + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); } -export async function addCSSClassToTitleEL(path: string, cssClass: string, plugin: FolderNotesPlugin, waitForCreate = false, count = 0) { - const fileExplorerItem = getEl(path, plugin); +/** + * @param path Can be a folder or file path + * @returns nothing + */ +export async function addCSSClassToFileExplorerEl(path: string, cssClass: string, plugin: FolderNotesPlugin, waitForCreate = false, count = 0) { + const fileExplorerItem = getFileExplorerElement(path, plugin); if (!fileExplorerItem) { if (waitForCreate && count < 5) { - // sleep for a second for the file-explorer event to catch up - // this is annoying as in most scanarios our plugin recieves the event before file explorer - // If we could guarrantee load order it wouldn't be an issue but we can't - // realise this is racey and needs to be fixed. await new Promise((r) => setTimeout(r, 500)); - addCSSClassToTitleEL(path, cssClass, plugin, waitForCreate, count + 1); + addCSSClassToFileExplorerEl(path, cssClass, plugin, waitForCreate, count + 1); return; } return; } fileExplorerItem.addClass(cssClass); - const viewHeaderItems = document.querySelectorAll(`[data-path='${CSS.escape(path)}']`); - viewHeaderItems.forEach((item) => { + if (cssClass === 'only-has-folder-note') { + fileExplorerItem.parentElement?.parentElement?.addClass('fn-only-has-folder-note'); + } + document.querySelectorAll(`[data-path='${CSS.escape(path)}']`).forEach((item) => { item.addClass(cssClass); }); } -export function removeCSSClassFromEL(path: string | undefined, cssClass: string, plugin: FolderNotesPlugin) { +/** + * @param path Can be a folder or file path + * @param cssClass The CSS class to remove from the file explorer element + * @returns nothing + */ +export function removeCSSClassFromFileExplorerEL(path: string | undefined, cssClass: string, plugin: FolderNotesPlugin) { if (!path) return; - const fileExplorerItem = getEl(path, plugin); - const viewHeaderItems = document.querySelectorAll(`[data-path='${CSS.escape(path)}']`); - viewHeaderItems.forEach((item) => { + const fileExplorerItem = getFileExplorerElement(path, plugin); + document.querySelectorAll(`[data-path='${CSS.escape(path)}']`).forEach((item) => { item.removeClass(cssClass); }); if (!fileExplorerItem) { return; } fileExplorerItem.removeClass(cssClass); } -export function getEl(path: string, plugin: FolderNotesPlugin | FolderOverviewPlugin): HTMLElement | null { +export function getFileExplorerElement(path: string, plugin: FolderNotesPlugin | FolderOverviewPlugin): HTMLElement | null { const fileExplorer = getFileExplorer(plugin); - if (!fileExplorer) { return null; } - if (!fileExplorer.view) { return null; } - if (!fileExplorer.view.fileItems) { return null; } + if (!fileExplorer?.view?.fileItems) { return null; } const fileExplorerItem = fileExplorer.view.fileItems?.[path]; - if (!fileExplorerItem) { return null; } - if (fileExplorerItem.selfEl) return fileExplorerItem.selfEl; - return fileExplorerItem.titleEl; + return fileExplorerItem?.selfEl ?? fileExplorerItem?.titleEl ?? null; } - export function showFolderNoteInFileExplorer(path: string, plugin: FolderNotesPlugin) { const excludedFolder = new ExcludedFolder(path, plugin.settings.excludeFolders.length, undefined, plugin); excludedFolder.subFolders = false; @@ -172,12 +179,14 @@ export function showFolderNoteInFileExplorer(path: string, plugin: FolderNotesPl excludedFolder.hideInSettings = true; excludedFolder.showFolderNote = true; addExcludedFolder(plugin, excludedFolder, false); - applyCSSClassesToFolder(path, plugin); + addCSSClassToFileExplorerEl(path, 'show-folder-note-in-explorer', plugin); + updateCSSClassesForFolder(path, plugin); } export function hideFolderNoteInFileExplorer(path: string, plugin: FolderNotesPlugin) { plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter( (folder) => (folder.path !== path) && folder.showFolderNote); plugin.saveSettings(false); - applyCSSClassesToFolder(path, plugin); + removeCSSClassFromFileExplorerEL(path, 'show-folder-note-in-explorer', plugin); + updateCSSClassesForFolder(path, plugin); } diff --git a/src/main.ts b/src/main.ts index 990387a..96b4b4f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,7 +13,7 @@ import { FolderOverview } from './obsidian-folder-overview/src/FolderOverview'; import { TabManager } from './events/TabManager'; import './functions/ListComponent'; import { handleDelete } from './events/handleDelete'; -import { addCSSClassToTitleEL, getEl, removeCSSClassFromEL, updateAllFileStyles } from './functions/styleFunctions'; +import { addCSSClassToFileExplorerEl, getFileExplorerElement, removeCSSClassFromFileExplorerEL, refreshAllFolderStyles } from './functions/styleFunctions'; import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import { FileExplorerView, InternalPlugin } from 'obsidian-typings'; import { getFocusedItem } from './functions/utils'; @@ -123,7 +123,7 @@ export default class FolderNotesPlugin extends Plugin { const folderNote = getFolderNote(this, folder.path); if (!folderNote) { return; } if (folderNote.path !== openFile.path) { return; } - this.activeFolderDom = getEl(folder.path, this); + this.activeFolderDom = getFileExplorerElement(folder.path, this); if (this.activeFolderDom) this.activeFolderDom.addClass('fn-is-active'); })); @@ -267,8 +267,8 @@ export default class FolderNotesPlugin extends Plugin { if (!folderNote && (evt.altKey || Keymap.isModEvent(evt) === 'tab')) { if ((this.settings.altKey && evt.altKey) || (this.settings.ctrlKey && Keymap.isModEvent(evt) === 'tab')) { createFolderNote(this, folderPath, true, undefined, true); - addCSSClassToTitleEL(folderPath, 'has-folder-note', this); - removeCSSClassFromEL(folderPath, 'has-not-folder-note', this); + addCSSClassToFileExplorerEl(folderPath, 'has-folder-note', this); + removeCSSClassFromFileExplorerEL(folderPath, 'has-not-folder-note', this); return; } } @@ -345,7 +345,7 @@ export default class FolderNotesPlugin extends Plugin { const attachmentsAreInRootFolder = attachmentFolderPath === './' || attachmentFolderPath === ''; const threshold = this.settings.storageLocation === 'insideFolder' ? 1 : 0; if (folder.children.length === 0) { - addCSSClassToTitleEL(folder.path, 'fn-empty-folder', this); + addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', this); } if (folder.children.length === threshold) { @@ -358,7 +358,7 @@ export default class FolderNotesPlugin extends Plugin { const attachmentFolder = this.app.vault.getAbstractFileByPath(folderPath); if (attachmentFolder instanceof TFolder && folder.children.length <= threshold + 1) { if (!folder.collapsed) { - getEl(folder.path, this)?.click(); + getFileExplorerElement(folder.path, this)?.click(); } } return folder.children.length <= threshold + 1; @@ -371,7 +371,7 @@ export default class FolderNotesPlugin extends Plugin { async changeFolderNameInExplorer(folder: TFolder, newName: string | null | undefined, waitForCreate = false, count = 0) { if (!newName) newName = folder.name; - let fileExplorerItem = getEl(folder.path, this); + let fileExplorerItem = getFileExplorerElement(folder.path, this); if (!fileExplorerItem) { if (waitForCreate && count < 5) { await new Promise((r) => setTimeout(r, 500)); @@ -462,7 +462,7 @@ export default class FolderNotesPlugin extends Plugin { await this.saveData(this.settings); // cleanup any css if we need too if ((!this.settingsOpened || reloadStyles === true) && reloadStyles !== false) { - updateAllFileStyles(true, this); + refreshAllFolderStyles(true, this); } } diff --git a/src/settings/GeneralSettings.ts b/src/settings/GeneralSettings.ts index a6a76fb..fd33180 100644 --- a/src/settings/GeneralSettings.ts +++ b/src/settings/GeneralSettings.ts @@ -5,7 +5,7 @@ import AddSupportedFileModal from '../modals/AddSupportedFileType'; import { FrontMatterTitlePluginHandler } from '../events/FrontMatterTitle'; import ConfirmationModal from './modals/CreateFnForEveryFolder'; import { TemplateSuggest } from '../suggesters/TemplateSuggester'; -import { updateAllFileStyles } from '../functions/styleFunctions'; +import { refreshAllFolderStyles } from '../functions/styleFunctions'; import BackupWarningModal from './modals/BackupWarning'; import RenameFolderNotesModal from './modals/RenameFns'; @@ -186,7 +186,7 @@ export async function renderGeneral(settingsTab: SettingsTab) { settingsTab.plugin.settings.storageLocation = value; await settingsTab.plugin.saveSettings(); settingsTab.display(); - updateAllFileStyles(undefined, settingsTab.plugin); + refreshAllFolderStyles(undefined, settingsTab.plugin); }) ) .addButton((button) => diff --git a/styles.css b/styles.css index 4d1c982..cff3b4e 100644 --- a/styles.css +++ b/styles.css @@ -322,4 +322,4 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { .is-phone .fn-overview-folder-path .setting-item-control { display: block; } -} +} \ No newline at end of file From fd44ed7873b21eff157c433fac276b2652315210 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:05:56 +0200 Subject: [PATCH 4/9] Update obsidian-folder-overview --- src/obsidian-folder-overview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/obsidian-folder-overview b/src/obsidian-folder-overview index 331d3ae..07f17df 160000 --- a/src/obsidian-folder-overview +++ b/src/obsidian-folder-overview @@ -1 +1 @@ -Subproject commit 331d3aea842fea661f8979a923b466ebed161379 +Subproject commit 07f17df3395beb34f22642cf13ed988a51e08b3e From 17251a4826d9f79cb0dce37782a7b04ad04686d9 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:47:54 +0200 Subject: [PATCH 5/9] Fix #171 --- src/Commands.ts | 21 ++------ src/events/handleClick.ts | 4 +- src/events/handleCreate.ts | 14 +++--- src/events/handleDelete.ts | 10 ++-- src/events/handleRename.ts | 38 +++++++------- src/functions/folderNoteFunctions.ts | 14 +++--- src/functions/styleFunctions.ts | 74 ++++++++++++++++------------ src/main.ts | 6 +-- styles.css | 3 +- 9 files changed, 92 insertions(+), 92 deletions(-) diff --git a/src/Commands.ts b/src/Commands.ts index 8bf273c..2155075 100644 --- a/src/Commands.ts +++ b/src/Commands.ts @@ -3,8 +3,8 @@ import FolderNotesPlugin from './main'; import { getFolderNote, createFolderNote, deleteFolderNote, turnIntoFolderNote, openFolderNote, extractFolderName, detachFolderNote } from './functions/folderNoteFunctions'; import { ExcludedFolder } from './ExcludeFolders/ExcludeFolder'; import { getFolderPathFromString, getFileExplorerActiveFolder } from './functions/utils'; -import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; -import { updateCSSClassesForFolder } from './functions/styleFunctions'; +import { deleteExcludedFolder, getDetachedFolder, getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; +import { hideFolderNoteInFileExplorer, showFolderNoteInFileExplorer } from './functions/styleFunctions'; @@ -403,10 +403,7 @@ export class Commands { item.setTitle('Hide folder note in explorer') .setIcon('eye-off') .onClick(() => { - this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter( - (folder) => (folder.path !== file.path) && folder.showFolderNote); - this.plugin.saveSettings(false); - updateCSSClassesForFolder(file.path, this.plugin); + hideFolderNoteInFileExplorer(file.path, this.plugin); }); }); } else { @@ -414,17 +411,7 @@ export class Commands { item.setTitle('Show folder note in explorer') .setIcon('eye') .onClick(() => { - const excludedFolder = new ExcludedFolder(file.path, this.plugin.settings.excludeFolders.length, undefined, this.plugin); - excludedFolder.subFolders = false; - excludedFolder.disableSync = false; - excludedFolder.disableAutoCreate = false; - excludedFolder.disableFolderNote = false; - excludedFolder.enableCollapsing = false; - excludedFolder.excludeFromFolderOverview = false; - excludedFolder.hideInSettings = true; - excludedFolder.showFolderNote = true; - addExcludedFolder(this.plugin, excludedFolder, false); - updateCSSClassesForFolder(file.path, this.plugin); + showFolderNoteInFileExplorer(file.path, this.plugin); }); }); } diff --git a/src/events/handleClick.ts b/src/events/handleClick.ts index c4f46f0..d5106e7 100644 --- a/src/events/handleClick.ts +++ b/src/events/handleClick.ts @@ -38,8 +38,8 @@ export async function handleViewHeaderClick(event: MouseEvent, plugin: FolderNot } else if (event.altKey || Keymap.isModEvent(event) === 'tab') { if ((plugin.settings.altKey && event.altKey) || (plugin.settings.ctrlKey && Keymap.isModEvent(event) === 'tab')) { await createFolderNote(plugin, folderPath, true, undefined, true); - addCSSClassToFileExplorerEl(folderPath, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(folderPath, 'has-not-folder-note', plugin); + addCSSClassToFileExplorerEl(folderPath, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folderPath, 'has-not-folder-note', false, plugin); return; } } diff --git a/src/events/handleCreate.ts b/src/events/handleCreate.ts index bc130ee..213380e 100644 --- a/src/events/handleCreate.ts +++ b/src/events/handleCreate.ts @@ -10,9 +10,9 @@ export async function handleCreate(file: TAbstractFile, plugin: FolderNotesPlugi const folder = file.parent; if (folder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } } @@ -32,7 +32,7 @@ async function handleFileCreation(file: TFile, plugin: FolderNotesPlugin) { turnIntoFolderNote(plugin, file, newFolder); } else if (folder instanceof TFolder) { if (folder.children.length >= 1) { - removeCSSClassFromFileExplorerEL(folder.path, 'fn-empty-folder', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'fn-empty-folder', false, plugin); } const detachedFolder = getExcludedFolder(plugin, folder.path, true); @@ -40,8 +40,8 @@ async function handleFileCreation(file: TFile, plugin: FolderNotesPlugin) { const folderNote = getFolderNote(plugin, folder.path); if (folderNote && folderNote.path === file.path) { - addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); - addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', false, plugin); } else if (plugin.settings.autoCreateForFiles) { if (!file.parent) { return; } const newFolder = await plugin.app.fileManager.createNewFolder(file.parent); @@ -56,7 +56,7 @@ async function handleFolderCreation(folder: TFolder, plugin: FolderNotesPlugin) const attachmentFolderPath = plugin.app.vault.getConfig('attachmentFolderPath') as string; const cleanAttachmentFolderPath = attachmentFolderPath?.replace('./', '') || ''; const attachmentsAreInRootFolder = attachmentFolderPath === './' || attachmentFolderPath === ''; - addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', plugin); + addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', false, plugin); if (!plugin.settings.autoCreateForAttachmentFolder) { if (!attachmentsAreInRootFolder && cleanAttachmentFolderPath === folder.name) return; @@ -71,5 +71,5 @@ async function handleFolderCreation(folder: TFolder, plugin: FolderNotesPlugin) if (folderNote) return; createFolderNote(plugin, folder.path, openFile, undefined, true); - addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); } diff --git a/src/events/handleDelete.ts b/src/events/handleDelete.ts index 3a9799b..af11cfd 100644 --- a/src/events/handleDelete.ts +++ b/src/events/handleDelete.ts @@ -8,9 +8,9 @@ export function handleDelete(file: TAbstractFile, plugin: FolderNotesPlugin) { const folder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(file.path)); if (folder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } } @@ -19,14 +19,14 @@ export function handleDelete(file: TAbstractFile, plugin: FolderNotesPlugin) { if (!folder) { return; } const folderNote = getFolderNote(plugin, folder.path); if (folderNote) { return; } - removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } if (!(file instanceof TFolder)) { return; } const folderNote = getFolderNote(plugin, file.path); if (!folderNote) { return; } - removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', false, plugin); if (!plugin.settings.syncDelete) { return; } deleteFolderNote(plugin, folderNote, false); } diff --git a/src/events/handleRename.ts b/src/events/handleRename.ts index 8b3c91f..b9bbe39 100644 --- a/src/events/handleRename.ts +++ b/src/events/handleRename.ts @@ -12,17 +12,17 @@ export function handleRename(file: TAbstractFile, oldPath: string, plugin: Folde const isRename = (file.parent?.path === getFolderPathFromString(oldPath)); if (folder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } } if (oldFolder instanceof TFolder) { if (plugin.isEmptyFolderNoteFolder(oldFolder)) { - addCSSClassToFileExplorerEl(oldFolder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(oldFolder.path, 'only-has-folder-note', true, plugin); } else { - removeCSSClassFromFileExplorerEL(oldFolder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder.path, 'only-has-folder-note', true, plugin); } } @@ -84,9 +84,9 @@ export async function handleFileMove(file: TFile, oldPath: string, plugin: Folde } else if (oldFolder && oldFolder.name === oldFileName && newFolder?.path !== oldFolder.path) { // the note has been moved somewhere and is no longer a folder note // cleanup css on the folder and note - removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); - removeCSSClassFromFileExplorerEL(oldPath, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(oldPath, 'is-folder-note', false, plugin); } } @@ -103,7 +103,7 @@ export async function handleFolderRename(file: TFolder, oldPath: string, plugin: const excludedFolder = getExcludedFolder(plugin, file.path, true); if (excludedFolder?.disableSync && !folderNote) { - return removeCSSClassFromFileExplorerEL(file.path, 'has-folder-note', plugin); + return removeCSSClassFromFileExplorerEL(file.path, 'has-folder-note', false, plugin); } if (!plugin.settings.syncFolderName) { return; } @@ -143,21 +143,21 @@ export async function fmptUpdateFileName(file: TFile, oldPath: string, plugin: F const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file); if (!excludedFolder?.disableFolderNote && folderName === newFolder?.name && !detachedExcludedFolder) { - addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); - addCSSClassToFileExplorerEl(newFolder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', false, plugin); + addCSSClassToFileExplorerEl(newFolder.path, 'has-folder-note', false, plugin); return; } else if (excludedFolder?.disableFolderNote || (folderName !== newFolder?.name)) { - removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); - removeCSSClassFromFileExplorerEL(newFolder?.path || '', 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(newFolder?.path || '', 'has-folder-note', false, plugin); } if (excludedFolder?.disableSync || !plugin.settings.syncFolderName) { return; } if (folderName === newFolder?.name) { - addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); - removeCSSClassFromFileExplorerEL(oldFolder?.path, 'has-folder-note', plugin); - addCSSClassToFileExplorerEl(newFolder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(oldFolder?.path, 'has-folder-note', false, plugin); + addCSSClassToFileExplorerEl(newFolder.path, 'has-folder-note', false, plugin); return; } @@ -175,12 +175,12 @@ export async function fmptUpdateFileName(file: TFile, oldPath: string, plugin: F async function renameFolderOnFileRename(file: TFile, oldPath: string, oldFolder: TAbstractFile, plugin: FolderNotesPlugin) { const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename); if (!newFolderName) { - removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', false, plugin); return; } else if (newFolderName === oldFolder.name) { - addCSSClassToFileExplorerEl(oldFolder.path, 'has-folder-note', plugin); - addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(oldFolder.path, 'has-folder-note', false, plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', false, plugin); return; } diff --git a/src/functions/folderNoteFunctions.ts b/src/functions/folderNoteFunctions.ts index 69b104d..2338217 100644 --- a/src/functions/folderNoteFunctions.ts +++ b/src/functions/folderNoteFunctions.ts @@ -60,7 +60,7 @@ export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: st if (detachedFolder && folderNote?.extension !== extension && folderNote) { deleteExcludedFolder(plugin, detachedFolder); - removeCSSClassFromFileExplorerEL(folderNote?.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote?.path, 'is-folder-note', false, plugin); const folder = plugin.app.vault.getAbstractFileByPath(folderPath) as TFolder; if (!folderNote || folderNote.basename !== fileName) return; let count = 1; @@ -144,8 +144,8 @@ export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: st const folder = plugin.app.vault.getAbstractFileByPath(folderPath); if (!(folder instanceof TFolder)) return; - addCSSClassToFileExplorerEl(path, 'is-folder-note', plugin, true); - addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(path, 'is-folder-note', false, plugin, true); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); } export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, folder: TFolder, folderNote?: TFile | null | TAbstractFile, skipConfirmation?: boolean) { @@ -156,7 +156,7 @@ export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, if (plugin.settings.showRenameConfirmation && !skipConfirmation && !detachedExcludedFolder) { return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open(); } - removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', false, plugin); const [excludedFolder, excludedFolderExisted, disabledSync] = await tempDisableSync(plugin, folder); @@ -190,8 +190,8 @@ export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, } await plugin.app.fileManager.renameFile(file, path); - addCSSClassToFileExplorerEl(path, 'is-folder-note', plugin, true); - addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(path, 'is-folder-note', false, plugin, true); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); if (plugin.activeFolderDom) { plugin.activeFolderDom.removeClass('fn-is-active'); @@ -265,7 +265,7 @@ export async function deleteFolderNote(plugin: FolderNotesPlugin, file: TFile, d (excludedFolder) => (excludedFolder.path !== folder.path) && excludedFolder.showFolderNote); plugin.saveSettings(false); - removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); switch (plugin.settings.deleteFilesAction) { case 'trash': await plugin.app.vault.trash(file, true); diff --git a/src/functions/styleFunctions.ts b/src/functions/styleFunctions.ts index 8e2e065..03ab8f4 100644 --- a/src/functions/styleFunctions.ts +++ b/src/functions/styleFunctions.ts @@ -16,20 +16,20 @@ export function refreshAllFolderStyles(forceReload = false, plugin: FolderNotesP if (!(file instanceof TFolder)) { return; } const folderNote = getFolderNote(plugin, file.path); if (!folderNote) { - removeCSSClassFromFileExplorerEL(file?.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(file?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file?.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(file?.path, 'only-has-folder-note', true, plugin); plugin.isEmptyFolderNoteFolder(file); return; } const excludedFolder = getExcludedFolder(plugin, file.path, true); if (excludedFolder?.disableFolderNote) { - removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); - removeCSSClassFromFileExplorerEL(file.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(file?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(file.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(file?.path, 'only-has-folder-note', true, plugin); } else { if (!excludedFolder?.showFolderNote) { - addCSSClassToFileExplorerEl(folderNote.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(folderNote.path, 'is-folder-note', false, plugin); } markFolderWithFolderNoteClasses(file, plugin); } @@ -47,31 +47,31 @@ export async function updateCSSClassesForFolder(folderPath: string, plugin: Fold const detachedFolderNote = getDetachedFolder(plugin, folder.path); if (folder.children.length === 0) { - addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', plugin); + addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', false, plugin); } if (!folderNote || detachedFolderNote) { - removeCSSClassFromFileExplorerEL(folder?.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(folder?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder?.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folder?.path, 'only-has-folder-note', true, plugin); return; } const excludedFolder = getExcludedFolder(plugin, folder.path, true); if (excludedFolder?.disableFolderNote) { - removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', plugin); - removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(folder?.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folderNote.path, 'is-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folder?.path, 'only-has-folder-note', true, plugin); } else { - console.log('updateCSSClassesForFolder', folder.path, 'has folder note'); markFolderWithFolderNoteClasses(folder, plugin); if (excludedFolder?.showFolderNote) { + addCSSClassToFileExplorerEl(folder.path, 'show-folder-note-in-explorer', true, plugin); unmarkFileAsFolderNote(folderNote, plugin); return; } if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } } @@ -102,44 +102,48 @@ export function clearFolderAndNoteClasses(folder: TFolder, file: TFile, plugin: } export function markFolderWithFolderNoteClasses(folder: TFolder, plugin: FolderNotesPlugin) { - addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); if (plugin.isEmptyFolderNoteFolder(folder)) { - addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', plugin); + addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } } export function markFileAsFolderNote(file: TFile, plugin: FolderNotesPlugin) { - addCSSClassToFileExplorerEl(file.path, 'is-folder-note', plugin); + addCSSClassToFileExplorerEl(file.path, 'is-folder-note', false, plugin); } export function unmarkFileAsFolderNote(file: TFile, plugin: FolderNotesPlugin) { - removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', plugin); + removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', false, plugin); } export function clearFolderNoteClassesFromFolder(folder: TFolder, plugin: FolderNotesPlugin) { - removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', plugin); - removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); } /** * @param path Can be a folder or file path * @returns nothing */ -export async function addCSSClassToFileExplorerEl(path: string, cssClass: string, plugin: FolderNotesPlugin, waitForCreate = false, count = 0) { +export async function addCSSClassToFileExplorerEl(path: string, cssClass: string, parent = false, plugin: FolderNotesPlugin, waitForCreate = false, count = 0) { const fileExplorerItem = getFileExplorerElement(path, plugin); if (!fileExplorerItem) { if (waitForCreate && count < 5) { await new Promise((r) => setTimeout(r, 500)); - addCSSClassToFileExplorerEl(path, cssClass, plugin, waitForCreate, count + 1); + addCSSClassToFileExplorerEl(path, cssClass, parent, plugin, waitForCreate, count + 1); return; } return; } - fileExplorerItem.addClass(cssClass); - if (cssClass === 'only-has-folder-note') { - fileExplorerItem.parentElement?.parentElement?.addClass('fn-only-has-folder-note'); + if (parent) { + const parentElement = fileExplorerItem?.parentElement; + if (parentElement) { + parentElement.addClass(cssClass); + } + } else { + fileExplorerItem.addClass(cssClass); } document.querySelectorAll(`[data-path='${CSS.escape(path)}']`).forEach((item) => { item.addClass(cssClass); @@ -151,14 +155,22 @@ export async function addCSSClassToFileExplorerEl(path: string, cssClass: string * @param cssClass The CSS class to remove from the file explorer element * @returns nothing */ -export function removeCSSClassFromFileExplorerEL(path: string | undefined, cssClass: string, plugin: FolderNotesPlugin) { +export function removeCSSClassFromFileExplorerEL(path: string | undefined, cssClass: string, parent: boolean, plugin: FolderNotesPlugin) { if (!path) return; const fileExplorerItem = getFileExplorerElement(path, plugin); document.querySelectorAll(`[data-path='${CSS.escape(path)}']`).forEach((item) => { item.removeClass(cssClass); }); if (!fileExplorerItem) { return; } - fileExplorerItem.removeClass(cssClass); + if (parent) { + const parentElement = fileExplorerItem?.parentElement; + if (parentElement) { + parentElement.removeClass(cssClass); + } + return; + } else { + fileExplorerItem.removeClass(cssClass); + } } export function getFileExplorerElement(path: string, plugin: FolderNotesPlugin | FolderOverviewPlugin): HTMLElement | null { @@ -179,7 +191,7 @@ export function showFolderNoteInFileExplorer(path: string, plugin: FolderNotesPl excludedFolder.hideInSettings = true; excludedFolder.showFolderNote = true; addExcludedFolder(plugin, excludedFolder, false); - addCSSClassToFileExplorerEl(path, 'show-folder-note-in-explorer', plugin); + addCSSClassToFileExplorerEl(path, 'show-folder-note-in-explorer', true, plugin); updateCSSClassesForFolder(path, plugin); } @@ -187,6 +199,6 @@ export function hideFolderNoteInFileExplorer(path: string, plugin: FolderNotesPl plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter( (folder) => (folder.path !== path) && folder.showFolderNote); plugin.saveSettings(false); - removeCSSClassFromFileExplorerEL(path, 'show-folder-note-in-explorer', plugin); + removeCSSClassFromFileExplorerEL(path, 'show-folder-note-in-explorer', true, plugin); updateCSSClassesForFolder(path, plugin); } diff --git a/src/main.ts b/src/main.ts index 96b4b4f..e17f6dd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -267,8 +267,8 @@ export default class FolderNotesPlugin extends Plugin { if (!folderNote && (evt.altKey || Keymap.isModEvent(evt) === 'tab')) { if ((this.settings.altKey && evt.altKey) || (this.settings.ctrlKey && Keymap.isModEvent(evt) === 'tab')) { createFolderNote(this, folderPath, true, undefined, true); - addCSSClassToFileExplorerEl(folderPath, 'has-folder-note', this); - removeCSSClassFromFileExplorerEL(folderPath, 'has-not-folder-note', this); + addCSSClassToFileExplorerEl(folderPath, 'has-folder-note', false, this); + removeCSSClassFromFileExplorerEL(folderPath, 'has-not-folder-note', false, this); return; } } @@ -345,7 +345,7 @@ export default class FolderNotesPlugin extends Plugin { const attachmentsAreInRootFolder = attachmentFolderPath === './' || attachmentFolderPath === ''; const threshold = this.settings.storageLocation === 'insideFolder' ? 1 : 0; if (folder.children.length === 0) { - addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', this); + addCSSClassToFileExplorerEl(folder.path, 'fn-empty-folder', false, this); } if (folder.children.length === threshold) { diff --git a/styles.css b/styles.css index cff3b4e..696dd47 100644 --- a/styles.css +++ b/styles.css @@ -211,7 +211,8 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { .fn-has-no-files .collapse-icon, .fn-hide-collapse-icon .has-folder-note.only-has-folder-note .tree-item-icon, -.fn-hide-empty-collapse-icon .fn-empty-folder .tree-item-icon { +.fn-hide-empty-collapse-icon .fn-empty-folder .tree-item-icon, +.only-has-folder-note:not(.is-collapsed):not(.show-folder-note-in-explorer) > .nav-folder-children { display: none; } From d1e2aa1c6441854b1f5cd8e2a4d6ce9bf0ea4d5e Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Wed, 18 Jun 2025 12:30:25 +0200 Subject: [PATCH 6/9] Fix rename handler & active folder highlight --- src/events/handleCreate.ts | 2 +- src/events/handleDelete.ts | 5 +- src/events/handleRename.ts | 85 +++++++++++++++++++++------- src/functions/folderNoteFunctions.ts | 19 ++----- src/functions/styleFunctions.ts | 40 ++++++++++--- src/main.ts | 12 ++-- 6 files changed, 109 insertions(+), 54 deletions(-) diff --git a/src/events/handleCreate.ts b/src/events/handleCreate.ts index 213380e..0cbcaee 100644 --- a/src/events/handleCreate.ts +++ b/src/events/handleCreate.ts @@ -9,7 +9,7 @@ export async function handleCreate(file: TAbstractFile, plugin: FolderNotesPlugi const folder = file.parent; if (folder instanceof TFolder) { - if (plugin.isEmptyFolderNoteFolder(folder)) { + if (plugin.isEmptyFolderNoteFolder(folder) && getFolderNote(plugin, folder.path)) { addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); diff --git a/src/events/handleDelete.ts b/src/events/handleDelete.ts index af11cfd..b2b644c 100644 --- a/src/events/handleDelete.ts +++ b/src/events/handleDelete.ts @@ -1,13 +1,13 @@ import { TAbstractFile, TFolder, TFile } from 'obsidian'; import FolderNotesPlugin from 'src/main'; import { getFolderNote, getFolder, deleteFolderNote } from 'src/functions/folderNoteFunctions'; -import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl } from 'src/functions/styleFunctions'; +import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl, hideFolderNoteInFileExplorer } from 'src/functions/styleFunctions'; import { getFolderPathFromString } from 'src/functions/utils'; export function handleDelete(file: TAbstractFile, plugin: FolderNotesPlugin) { const folder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(file.path)); if (folder instanceof TFolder) { - if (plugin.isEmptyFolderNoteFolder(folder)) { + if (plugin.isEmptyFolderNoteFolder(folder) && getFolderNote(plugin, folder.path)) { addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); @@ -21,6 +21,7 @@ export function handleDelete(file: TAbstractFile, plugin: FolderNotesPlugin) { if (folderNote) { return; } removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); + hideFolderNoteInFileExplorer(folder.path, plugin); } if (!(file instanceof TFolder)) { return; } diff --git a/src/events/handleRename.ts b/src/events/handleRename.ts index b9bbe39..52837f1 100644 --- a/src/events/handleRename.ts +++ b/src/events/handleRename.ts @@ -3,15 +3,15 @@ import FolderNotesPlugin from 'src/main'; import { extractFolderName, getFolderNote, getFolderNoteFolder } from '../functions/folderNoteFunctions'; import { getExcludedFolder, addExcludedFolder, updateExcludedFolder, deleteExcludedFolder, getDetachedFolder } from '../ExcludeFolders/functions/folderFunctions'; import { ExcludedFolder } from 'src/ExcludeFolders/ExcludeFolder'; -import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl } from 'src/functions/styleFunctions'; +import { removeCSSClassFromFileExplorerEL, addCSSClassToFileExplorerEl, markFileAsFolderNote, unmarkFileAsFolderNote, unmarkFolderAsFolderNote, markFolderWithFolderNoteClasses, hideFolderNoteInFileExplorer, removeActiveFolder, setActiveFolder } from 'src/functions/styleFunctions'; import { getFolderPathFromString, removeExtension, getFileNameFromPathString } from 'src/functions/utils'; export function handleRename(file: TAbstractFile, oldPath: string, plugin: FolderNotesPlugin) { const folder = file.parent; const oldFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(oldPath)); - const isRename = (file.parent?.path === getFolderPathFromString(oldPath)); + if (folder instanceof TFolder) { - if (plugin.isEmptyFolderNoteFolder(folder)) { + if (plugin.isEmptyFolderNoteFolder(folder) && getFolderNote(plugin, folder.path)) { addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); @@ -19,7 +19,7 @@ export function handleRename(file: TAbstractFile, oldPath: string, plugin: Folde } if (oldFolder instanceof TFolder) { - if (plugin.isEmptyFolderNoteFolder(oldFolder)) { + if (plugin.isEmptyFolderNoteFolder(oldFolder) && getFolderNote(plugin, oldFolder.path)) { addCSSClassToFileExplorerEl(oldFolder.path, 'only-has-folder-note', true, plugin); } else { removeCSSClassFromFileExplorerEL(oldFolder.path, 'only-has-folder-note', true, plugin); @@ -27,22 +27,45 @@ export function handleRename(file: TAbstractFile, oldPath: string, plugin: Folde } if (file instanceof TFolder) { - plugin.tabManager.updateTab(file.path); - updateExcludedFolderPath(file, oldPath, plugin); - if (isRename) { - return handleFolderRename(file, oldPath, plugin); + const folder = file; + plugin.tabManager.updateTab(folder.path); + updateExcludedFolderPath(folder, oldPath, plugin); + if (isFolderRename(folder, oldPath)) { + return handleFolderRename(folder, oldPath, plugin); } else { - return handleFolderMove(file, oldPath, plugin); + return handleFolderMove(folder, oldPath, plugin); } } else if (file instanceof TFile) { - if (isRename) { + if (isFileRename(file, oldPath)) { + console.log('File rename detected'); return fmptUpdateFileName(file, oldPath, plugin); } else { + console.log('File move detected'); return handleFileMove(file, oldPath, plugin); } } } +function isFileRename(file: TFile, oldPath: string): boolean { + const oldFolderPath = getFolderPathFromString(oldPath); + const newFolderPath = file.parent?.path; + const oldName = getFileNameFromPathString(oldPath); + const newName = file.name; + + return oldFolderPath === newFolderPath && oldName !== newName; +} + + +function isFolderRename(folder: TFolder, oldPath: string): boolean { + const oldName = getFileNameFromPathString(oldPath); + const newName = folder.name; + const oldParent = getFolderPathFromString(oldPath); + const newParent = folder.parent?.path; + + return oldParent === newParent && oldName !== newName; +} + + export function handleFolderMove(file: TFolder, oldPath: string, plugin: FolderNotesPlugin) { // Soon @@ -54,12 +77,19 @@ export async function handleFileMove(file: TFile, oldPath: string, plugin: Folde const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename) || file.basename; const oldFileName = removeExtension(getFileNameFromPathString(oldPath)); const newFolder = getFolderNoteFolder(plugin, file, file.basename); - const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file); let excludedFolder = getExcludedFolder(plugin, newFolder?.path || '', true); const oldFolder = getFolderNoteFolder(plugin, oldPath, oldFileName); + const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file); - // file has been moved into position where it can be a folder note! - if (folderName === newFolder?.name && folderNote) { + + const isFileNowFolderNoteInNewFolder = folderName === newFolder?.name; + const isFileMovedFromOldFolderNote = oldFolder && oldFolder.name === oldFileName && newFolder?.path !== oldFolder.path; + + // this is for turning files into folder notes for folders that already have a folder note + // e.g. Turn into folder note for "Folder name" + const isFileNowFolderNoteWithExistingNote = folderName === newFolder?.name && folderNote; + + if (isFileNowFolderNoteWithExistingNote) { let excludedFolderExisted = true; let disabledSync = false; @@ -81,12 +111,28 @@ export async function handleFileMove(file: TFile, oldPath: string, plugin: Folde updateExcludedFolder(plugin, excludedFolder, excludedFolder); } }); - } else if (oldFolder && oldFolder.name === oldFileName && newFolder?.path !== oldFolder.path) { - // the note has been moved somewhere and is no longer a folder note - // cleanup css on the folder and note - removeCSSClassFromFileExplorerEL(oldFolder.path, 'has-folder-note', false, plugin); - removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', false, plugin); - removeCSSClassFromFileExplorerEL(oldPath, 'is-folder-note', false, plugin); + } else if (isFileNowFolderNoteInNewFolder) { + if (!excludedFolder?.disableFolderNote) { + markFileAsFolderNote(file, plugin); + if (newFolder instanceof TFolder) { + markFolderWithFolderNoteClasses(newFolder, plugin); + if (plugin.app.workspace.getActiveFile()?.path === file.path) { + removeActiveFolder(plugin); + setActiveFolder(newFolder.path, plugin); + } + } + if (oldFolder instanceof TFolder) { + hideFolderNoteInFileExplorer(oldFolder.path, plugin); + unmarkFolderAsFolderNote(oldFolder, plugin); + } + } + } else if (isFileMovedFromOldFolderNote) { + unmarkFileAsFolderNote(file, plugin); + if (oldFolder instanceof TFolder) { + removeActiveFolder(plugin); + hideFolderNoteInFileExplorer(oldFolder.path, plugin); + unmarkFolderAsFolderNote(oldFolder, plugin); + } } } @@ -96,7 +142,6 @@ export async function handleFolderRename(file: TFolder, oldPath: string, plugin: if (fileName === oldFileName) { return; } - const folderNote = getFolderNote(plugin, oldPath); if (!(folderNote instanceof TFile)) return; diff --git a/src/functions/folderNoteFunctions.ts b/src/functions/folderNoteFunctions.ts index 2338217..3b05db4 100644 --- a/src/functions/folderNoteFunctions.ts +++ b/src/functions/folderNoteFunctions.ts @@ -7,7 +7,7 @@ import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcluded import { ExcludedFolder } from '../ExcludeFolders/ExcludeFolder'; import { openExcalidrawView } from './excalidraw'; import { AskForExtensionModal } from 'src/modals/AskForExtension'; -import { getFileExplorerElement, addCSSClassToFileExplorerEl, removeCSSClassFromFileExplorerEL } from 'src/functions/styleFunctions'; +import { addCSSClassToFileExplorerEl, removeCSSClassFromFileExplorerEL, removeActiveFolder, setActiveFolder } from 'src/functions/styleFunctions'; import { getFolderNameFromPathString, getFolderPathFromString, removeExtension } from 'src/functions/utils'; const defaultExcalidrawTemplate = `--- @@ -120,16 +120,12 @@ export async function createFolderNote(plugin: FolderNotesPlugin, folderPath: st if (openFile) { if (plugin.app.workspace.getActiveFile()?.path === path) { - if (plugin.activeFolderDom) { - plugin.activeFolderDom.removeClass('fn-is-active'); - plugin.activeFolderDom = null; - } + removeActiveFolder(plugin); const folder = getFolder(plugin, folderNote); if (!folder) { return; } - plugin.activeFolderDom = getFileExplorerElement(folder.path, plugin); - if (plugin.activeFolderDom) plugin.activeFolderDom.addClass('fn-is-active'); + setActiveFolder(folder.path, plugin); } await leaf.openFile(folderNote); if (plugin.settings.folderNoteType === '.excalidraw' || extension === '.excalidraw') { @@ -193,13 +189,8 @@ export async function turnIntoFolderNote(plugin: FolderNotesPlugin, file: TFile, addCSSClassToFileExplorerEl(path, 'is-folder-note', false, plugin, true); addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); - if (plugin.activeFolderDom) { - plugin.activeFolderDom.removeClass('fn-is-active'); - plugin.activeFolderDom = null; - } - - plugin.activeFolderDom = getFileExplorerElement(folder.path, plugin); - if (plugin.activeFolderDom) plugin.activeFolderDom.addClass('fn-is-active'); + removeActiveFolder(plugin); + setActiveFolder(folder.path, plugin); } export async function tempDisableSync(plugin: FolderNotesPlugin, folder: TFolder): Promise<[excludedFolder: ExcludedFolder | undefined, excludedFolderExisted: boolean, disabledSync: boolean]> { diff --git a/src/functions/styleFunctions.ts b/src/functions/styleFunctions.ts index 03ab8f4..7dd1e28 100644 --- a/src/functions/styleFunctions.ts +++ b/src/functions/styleFunctions.ts @@ -44,6 +44,7 @@ export async function updateCSSClassesForFolder(folderPath: string, plugin: Fold if (!folder || !(folder instanceof TFolder)) { return; } const folderNote = getFolderNote(plugin, folder.path); + // console.log('Updating CSS classes for folder:', folder.path, 'Folder Note:', folderNote); const detachedFolderNote = getDetachedFolder(plugin, folder.path); if (folder.children.length === 0) { @@ -68,7 +69,7 @@ export async function updateCSSClassesForFolder(folderPath: string, plugin: Fold unmarkFileAsFolderNote(folderNote, plugin); return; } - if (plugin.isEmptyFolderNoteFolder(folder)) { + if (plugin.isEmptyFolderNoteFolder(folder) && getFolderNote(plugin, folder.path)) { addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); @@ -103,7 +104,7 @@ export function clearFolderAndNoteClasses(folder: TFolder, file: TFile, plugin: export function markFolderWithFolderNoteClasses(folder: TFolder, plugin: FolderNotesPlugin) { addCSSClassToFileExplorerEl(folder.path, 'has-folder-note', false, plugin); - if (plugin.isEmptyFolderNoteFolder(folder)) { + if (plugin.isEmptyFolderNoteFolder(folder) && getFolderNote(plugin, folder.path)) { addCSSClassToFileExplorerEl(folder.path, 'only-has-folder-note', true, plugin); } else { removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); @@ -118,6 +119,11 @@ export function unmarkFileAsFolderNote(file: TFile, plugin: FolderNotesPlugin) { removeCSSClassFromFileExplorerEL(file.path, 'is-folder-note', false, plugin); } +export function unmarkFolderAsFolderNote(folder: TFolder, plugin: FolderNotesPlugin) { + removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); + removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); +} + export function clearFolderNoteClassesFromFolder(folder: TFolder, plugin: FolderNotesPlugin) { removeCSSClassFromFileExplorerEL(folder.path, 'has-folder-note', false, plugin); removeCSSClassFromFileExplorerEL(folder.path, 'only-has-folder-note', true, plugin); @@ -144,10 +150,10 @@ export async function addCSSClassToFileExplorerEl(path: string, cssClass: string } } else { fileExplorerItem.addClass(cssClass); + document.querySelectorAll(`[data-path='${CSS.escape(path)}']`).forEach((item) => { + item.addClass(cssClass); + }); } - document.querySelectorAll(`[data-path='${CSS.escape(path)}']`).forEach((item) => { - item.addClass(cssClass); - }); } /** @@ -195,10 +201,26 @@ export function showFolderNoteInFileExplorer(path: string, plugin: FolderNotesPl updateCSSClassesForFolder(path, plugin); } -export function hideFolderNoteInFileExplorer(path: string, plugin: FolderNotesPlugin) { +export function hideFolderNoteInFileExplorer(folderPath: string, plugin: FolderNotesPlugin) { plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter( - (folder) => (folder.path !== path) && folder.showFolderNote); + (folder) => (folder.path !== folderPath) && folder.showFolderNote); plugin.saveSettings(false); - removeCSSClassFromFileExplorerEL(path, 'show-folder-note-in-explorer', true, plugin); - updateCSSClassesForFolder(path, plugin); + removeCSSClassFromFileExplorerEL(folderPath, 'show-folder-note-in-explorer', true, plugin); + updateCSSClassesForFolder(folderPath, plugin); +} + +export function setActiveFolder(folderPath: string, plugin: FolderNotesPlugin) { + const fileExplorerItem = getFileExplorerElement(folderPath, plugin); + if (fileExplorerItem) { + fileExplorerItem.addClass('fn-is-active'); + plugin.activeFolderDom = fileExplorerItem; + } +} + +export function removeActiveFolder(plugin: FolderNotesPlugin) { + if (plugin.activeFolderDom) { + plugin.activeFolderDom.removeClass('fn-is-active'); + plugin.activeFolderDom?.removeClass('has-focus'); + plugin.activeFolderDom = null; + } } diff --git a/src/main.ts b/src/main.ts index e17f6dd..7c0bb5a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,7 +13,7 @@ import { FolderOverview } from './obsidian-folder-overview/src/FolderOverview'; import { TabManager } from './events/TabManager'; import './functions/ListComponent'; import { handleDelete } from './events/handleDelete'; -import { addCSSClassToFileExplorerEl, getFileExplorerElement, removeCSSClassFromFileExplorerEL, refreshAllFolderStyles } from './functions/styleFunctions'; +import { addCSSClassToFileExplorerEl, getFileExplorerElement, removeCSSClassFromFileExplorerEL, refreshAllFolderStyles, setActiveFolder, removeActiveFolder } from './functions/styleFunctions'; import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import { FileExplorerView, InternalPlugin } from 'obsidian-typings'; import { getFocusedItem } from './functions/utils'; @@ -109,10 +109,7 @@ export default class FolderNotesPlugin extends Plugin { })); this.registerEvent(this.app.workspace.on('file-open', async (openFile: TFile | null) => { - if (this.activeFolderDom) { - this.activeFolderDom.removeClass('fn-is-active'); - this.activeFolderDom = null; - } + removeActiveFolder(this); if (!openFile || !openFile.basename) { return; } @@ -123,8 +120,7 @@ export default class FolderNotesPlugin extends Plugin { const folderNote = getFolderNote(this, folder.path); if (!folderNote) { return; } if (folderNote.path !== openFile.path) { return; } - this.activeFolderDom = getFileExplorerElement(folder.path, this); - if (this.activeFolderDom) this.activeFolderDom.addClass('fn-is-active'); + setActiveFolder(folder.path, this); })); this.registerEvent(this.app.vault.on('rename', (file: TAbstractFile, oldPath: string) => { @@ -429,7 +425,7 @@ export default class FolderNotesPlugin extends Plugin { document.body.classList.remove('folder-note-underline'); document.body.classList.remove('hide-folder-note'); document.body.classList.remove('fn-whitespace-stop-collapsing'); - if (this.activeFolderDom) { this.activeFolderDom.removeClass('is-active'); } + removeActiveFolder(this); if (this.fmtpHandler) { this.fmtpHandler.deleteEvent(); } From 256b254c0a3ad9569cb8fc97b73dec6cbb516ac7 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Fri, 20 Jun 2025 11:17:27 +0200 Subject: [PATCH 7/9] Add missing css code --- src/events/handleRename.ts | 2 -- styles.css | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/events/handleRename.ts b/src/events/handleRename.ts index 52837f1..abdb5d3 100644 --- a/src/events/handleRename.ts +++ b/src/events/handleRename.ts @@ -37,10 +37,8 @@ export function handleRename(file: TAbstractFile, oldPath: string, plugin: Folde } } else if (file instanceof TFile) { if (isFileRename(file, oldPath)) { - console.log('File rename detected'); return fmptUpdateFileName(file, oldPath, plugin); } else { - console.log('File move detected'); return handleFileMove(file, oldPath, plugin); } } diff --git a/styles.css b/styles.css index 696dd47..86b8b4f 100644 --- a/styles.css +++ b/styles.css @@ -120,8 +120,10 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { } .folder-overview-list { - margin: 0 !important; - padding: 1.2em 0 !important; + margin-top: 0 !important; + margin-bottom: 0 !important; + padding-bottom: 1.200 !important; + padding-top: 1.200 !important; } .folder-overview-list-item { From f98472457c2168aa5d777a3f45fa268aa17c16dc Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Fri, 20 Jun 2025 17:48:32 +0200 Subject: [PATCH 8/9] Update obsidian-folder-overview --- src/obsidian-folder-overview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/obsidian-folder-overview b/src/obsidian-folder-overview index 07f17df..192ecd3 160000 --- a/src/obsidian-folder-overview +++ b/src/obsidian-folder-overview @@ -1 +1 @@ -Subproject commit 07f17df3395beb34f22642cf13ed988a51e08b3e +Subproject commit 192ecd3cd7ca983db1a9d4a97ec90333bdbc8fd8 From 7c12335581dd2ea8bf8ac87c1bb1184d25d26bf9 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Fri, 20 Jun 2025 17:50:39 +0200 Subject: [PATCH 9/9] Update folder overview docs --- docs/docs/Folder overview.md | 15 +++++++-------- docs/docs/assets/ngkJjEcxUUTkX6eB4mSs.png | Bin 52052 -> 0 bytes docs/docs/assets/screenshots/b4QOtkzJs0.png | Bin 0 -> 89672 bytes 3 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 docs/docs/assets/ngkJjEcxUUTkX6eB4mSs.png create mode 100644 docs/docs/assets/screenshots/b4QOtkzJs0.png diff --git a/docs/docs/Folder overview.md b/docs/docs/Folder overview.md index f04e2cf..9339a3b 100644 --- a/docs/docs/Folder overview.md +++ b/docs/docs/Folder overview.md @@ -1,8 +1,4 @@ # Folder overview - -This page will be updated soon and there also will be new features. -This feature/plugin creates a code block - This feature/plugin creates a [code block](https://help.obsidian.md/Editing+and+formatting/Basic+formatting+syntax#Code+blocks) that provides an overview of your entire vault or specific folders. Instructions for creating or editing a folder overview, along with additional guidance, can be found further down the page. Currently there are two styles available: **file explorer** & **list style**, with more coming soon. The **overview updates** itself **automatically** when you create, delete or modify a file. You can also integrate it into **templates**, as explained further down below this page. @@ -13,11 +9,14 @@ There are two options to create a folder overview in a note - Use the command "Insert folder overview" from the [command palette](https://help.obsidian.md/Plugins/Command+palette) - On desktop right click and click on the option "Create folder overview" ## Edit overview -If the overview shows no files or folders yet you can just click on the button that says "Edit overview". But if there are already files/folders it's a bit more complicated than the button and to then edit the overview you have to hover over the overview and click on the "Edit this block" button on the right top corner of the overview with only an icon. +If the overview shows no files or folders yet you can just click on the button that says "Edit overview". But if there are already files/folders you can use the command "Edit folder overview" from the [command palette](https://help.obsidian.md/Plugins/Command+palette) or click on the button as showed in the video below. -The video below shows the steps explained in the text. ![type:video](../assets/n5AGi3VCxF5JcNx2Wm5O.mp4) ## Default settings -To edit the settings for a new folder overview that hasn't been created yet you have to open the plugin settings and go to the folder overview tab and click on the manage button. -![Screenshot](../assets/ngkJjEcxUUTkX6eB4mSs.png) +To edit the default values for new folder overviews you can either use the command "Edit folder overview" or open the plugins settings tab and then the folder overview tab to the edit the default settings. + + +![Screenshot](../assets/screenshots/b4QOtkzJs0.png) +(On the left is the plugin settings tab and the right the view you see when you use the "Edit folder overview" command) + diff --git a/docs/docs/assets/ngkJjEcxUUTkX6eB4mSs.png b/docs/docs/assets/ngkJjEcxUUTkX6eB4mSs.png deleted file mode 100644 index 8a50481c7b2dfc832aa6e1e4ee911d1b76c9cfe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52052 zcmd?Rc|27A|My==yh}u-5{jZyRElgfgpjS(k}V0zGT9AgCJ{+UvSk^GD9b2}eMS*k z2Vt1OkY#LR8O)gdcl7ywuJ7k}yKdL@?{(d7*UfE?+0LAEUa!}4c|Bi``-#12VI=a; z(SLUA*dbzKY;b$W4*ogdK@k!J-jVh(vVx^6$|gABz??E8=knoJG2WkQu5^-P}~ydsIp8 z$T0_pswejXgBz>9gz@k^4vAMKc1`F+)b^&tNv>D_zn({(InJl^_g!F<&i8-v19|Iu z!l2b951yC@dOUPdqrgxg^xtQB!ANMi6ixUtwPNC-`wmh&lj!zve$nVjD)Xuvq-@;&C&$D-O>X-utmFS z@9MFjs-z8}jej?e^Od^?*q_uJJ+!!6Q^ff~Q>DkKxg+YH} z6=?yYAx->sR}*zb|9t|=a;M6J2_A(q2NCO;q|x!MR`sAH$E1yJHKJF+Rq%X%GJ#0q z(r6829TcSs@2K=~p;+!eT3_CPnV_{iEJJ-06OhD>R&Q{2J((?poswRuxt#^3*W$eK zSng(66fCgM-yk>U->2*!)qCi?N|KK-t6dQ}DzlNhy9!1htCkL1`bv>r32EEaQY+bE z-rBnanyeB;pV3Yik z#GDIiJ>p(jfdkbyG6zvU+drbR8bmi~v;2={u;Djo6^5upt>1Y90lJ7qBp_*(g_{M- zQ;=X}vGISj_v}mej*H=TEdQMKEHrDme!Dl(6fBRcL|R^EY>3Z8x5XkZAA;r3isSQ){<}MhKL{{Etfk*M>}kd7HZXV18>d5G zy0t#3I%`mq)*SnOrJ4liDB_ocs_UyLXrl6ei~vy~FI;lmo0anBeGV^isrw8xJ}mny ztGtT)??E>7Onf4}5?hYE;N(#E|7*5cxt_S%Px}9T0T*`t$0)g@`@j02Nl?Cb@dW4Z za4M%|T$b5$BI;@1@B@K5+1I2XqIa|A!%XjL4_J!pOjr47# z2C5+am~!8*U+FIvop?-dyhE_JHI_NZI_%Xyd=9YY7cP6;UQ^sV`_8N>(0% zMKfMFq5QKKD|P6E#<9mMQq}w`ArHeA8bSRzPZR0UIJ5%Q@Osfkv?8OHX*1!N6*}-j+da6aUdbhQb8MW@ueyQjB;{L7@AT|0&RE6 zY=+2(i_ z%T$LyA$sF7OytSoJ*;x{Qwq^JM!N2}{0##U@62~6{wrB!jONS^4tv%x-$+-Tnvif4urw$_7tRP&t-`X9Z`X;_H&`t zcG}J-dxMvgvKq=ymzdkLf<}GYQuuW89!(k6d-BBRm_J*GBnR*<2HU+}A}!b3oHa=n z+9=1w>WVHN#bbmvc2Hy@fWK=(p2fr_;gAj!1wA}t5o=ObnA_Bw+HnP!bv`z zt|RaSV7E+Q|1w_+Fc^E6_s?zHc)1$zbNpAjBWhD~!jaO+7~LvW`E+@^^Ho{oM#q8n^rtwCvRy=<=EF_f6<+_iqzs zkem1hBdG7A=A%6&_G#Nh6=e{<4~gE@l)#HcHorC3)(sEN8Lb3cgpEYV%UsGxlexgC z8M(Uf{iBN@qaATulWj!c7!m(2w?#=PUNnb= ztTF_91|9%H!pOA_O}JBU;lr3c1SMH)Ic$B(Gz^a2>iHHl+j*$EdAV@{oY&ZoSw0fi zW67e-P&g>t{sctJ589t3@7R1?6NJ6?zVO@=q}KZAxB`|rPNjXW&L&!fcl`(&hAGHa zE7unBIUJY|#n(HAao3Tgo~u)@gNAI~tAa7>*&O@e@u?~l%=>RhL+weXrYm{f9;f&O z*Z)mu8l32L_^NsmXPFb;P|k1H)}Cn-KE9rVA7_oz(dv!!=9Hww@JB?C!ffS$cO`7& zmzb@eDvnT2*mky)vl^wiv5p9Yu8(v>;OlVMEz)+jLZMY-IfyO4QFVedD7-@LLFbG8 zb1Ac}>KI?GrSj%bX-2>>X%wS8Go1bAs z;y4XWdsnDk0K`n6b@5#e*6&1p{E{;(n?=D5q%aE*V;arlvVy^mqjK{L{?5DVKqyL< zY#=Ub+rL zvPKJG3wMxD_DCvwIkEpp66IyqUM|PfnrW^M0`?a}3A13Wo-rlV#t}<+@Xbb7%5Y52 zx#FC6xHpk27sbacorbxzn1f{LF+!V#L;pSu8Szhm2Pt4Rk5)}WB59^88r9jC#j|0y z;R2zB0?f}UHUo;53nUz-s-$tDeGl;j{eAdo-E`hR8|G>w`J!c(V9o{&IQ2TtCJNz= z;IT+7jY<2qMEJ(XAm9boVe%jA^z=4+=VYqcGHg~A>49K$IuX>djP9Ubz1^F7)EC)H z{>mM!zX>s=@;CF!q9T}KqV?ycJhQ6zIIQ2dxS8t0Jt>3XP#{1@Qy^oqOYomcj(tCQ z3slUXgQ($UzqI;F71+Efr)E2y8%slr{*Gr|*XoLa3<81>S&QU>gVQR=mnT)dAODV%>#fROpIWNG`5>6Tk)g;fGMG2gc9bx# zL2q1vp?2>AQhKe;m-H{xG(|JbqaV|k`h$IfDl#{XgtJT)I=NeI;2?{ulTny%j0vNA z7i~MM`ay8{cxcY&rVl(3w&X%2gXp!Or_31@#0Y3LLUd#2!ikt;{qj;i`N*vnMS=vd zg}cZHr8r;k+_Bxpm?;QxSanpiPd>8m2Bdu9`g!m3wwG_#_NSCpUIK49@*n1xh7JTF zI(NHuO+r}3_6R3NhxM}S{yDi>!ALA?Y=!w?^@J$YxH>RfXd`LvP!$(Xax4i;>^|S@wvcE=slO%?q+>u0+cwX0y zl^wq2!R9ti2`5;}b8_pwFrzkP@Mwh(XC*1!X#mbk&ZtxnHdwR_-*~MHe)vvtKlt3@ z#4Xz#TX*c`4kalzz|x4865s%%($l>J$5QOsG~aPqqUmU7c)|UHP07& z)dFrrQLnhI2fwMdu;N39wr!Q2Yuj3K9Se+h5xqa$qwVI)8aP5mTQl&l_u%H08*JPMAa zNY?al+;tXh9bP&x`_mkuAdMc43)-UIbov(UL|Sc^D?w-3Hxcf@n72d_eiqGra9KDe zokK2D>9Hkd-UUM@SuoMV>$N zUHkh@T^{fN2bu4*$J`79%x{+Qn6R-$M^5N`ofZD`H}fFEggbH}VWA{3wS@$w7C+g*T>TYs>eLrex6N*=jdb&zZI~?%7I8ujIw!kR!ZV zeaWgjITb}j>X7`QcrU=iA8h?O^8qkQ90W=Gv1fKq@~&{Xv348?!IR3VFN$;d!#$Yj zG;9HWfCl^$ipmM`^?BPha z1Pz~)80*w4n#-HG`vczZ95pd_+Z+q|aq~e|AWnLctVPJc51-~Ud8mA60#;ZD%)a0{JWXV5MIHRe zo46VR9Ps9~vMLb#4v(yr9&a_Bt?!~f+mp7sRjGdhB7@0a{1J~67b7{R-oHBfv^ee5 zy1_MJx8#Fmo@L;`Y(IzFyt>v^iSKf-|D_V z#AdP6=FWFVp7I}xyqdJXPuyd>_(hw62{vvq@z`HAvphC-EgrJrqGLA;X)}?Rb%nO}iQkEoRG<1RF-J$nei29HH5+I; zpUcB+Wv!>>v#K9|e?=>xD|@4k#6G+=ihnJ>u8NK@(`*z(w&uW0i?`m87b*p4sjXLVZD!H*}&Y=1)*CD90~ za=$NC#i<{<1i4NeTv?QL7=o`dTy;b-)FrNo zyj@jaeS*U%Jb3&@6tj9`^q>v_PBk7zkbj#Rk-R+{OU<5lX**s>1`~0bKE7ey$&%<5 zSkU~hn2y5?CPh{0Xh(3xMG{~3)`{?}YP3{H;a(`}CN$A+?G(5;GwdtqkG7x1 zf)aK8WrV*ORtahT+=*0%SEGH!9r~!>{CG*L$fx%-%?Xk5vqJOJ2wBg6QG;eub@M)TIqqxnsdLN$=TyQgd zotNj50vQt%**iM1H)rD0{3rKS_Y0=aSU$DyGe7$64cU8a^pVKpeL#^I9vK{27Jj5=@Mzqmn$dMar@I{!NY=Da!z@VT@$6Qu<{SO7XOOQT)!+7fJ?vzpL~!Q*3xxp z@jk)gGJ=&X-&dEf$Vx=CELDTPRyI0h!y&c{G_fY^J85Bj z_XQ;1n8tjTs&SwUY(~jx{`u|83)j`_Zb`-o#H|0+B|)ED5lPY=y((+CDWn$(BWL;# zLC-ivdhsJ9BBuDp@-w`1^skuMTpN8xIQgF9<(Kd+^Ow86aC)6ZlNuUK*1*lnHA8(K z_SB-x@cighwm8Wl^WV?+F8M)W**spTCO1fqHQ>v>3Tx{#C0JsE#@EOR z{R#aI^M-LmMN(bI zEIcX8nwPZ7oBM1^AUb}l;Y=61;)^UGw*4Ru`V_1n0+AqjMcvm~JfcbY);Xu*z2oZC zZgnuGr0}OGrlzFP{qCWQD@fz3TIVBp9lLuR&U7HOsWI%W4ufa}f;&j1Rf(Q=ux%qH z5K^z=1*xAAV0QmE8Y4KH2*LVqH~UT{_~CmxRm0 zgR+TbkerBA3t0H8XZJh0X2nIzOypouHB6H>$3MikfzMwd?X4Zc4C+R74{MH}jA$3w z?Kyqh!p(D}rB(<6|Fk%<_L%!A|!|7dkM8&_FV~_gZ@HAii_o zFI3bC(qsOa4(p6?*K6&Kl?qXnabfSdJ%X;rQ#p&{cZyAhjgNauzzkvD!F!!4+!;_I zs!sO)+P&m!9lda?-2Eu_WVo~Ft#%My4Q80_nb)k7Dk3xXrW&-8mFn0ys$bxb3R0$K zV^$j8RC9mrCd3TergL1RZ-}t>f!k|6M>U9)jdkta zqWIrQwK)32;beDiy9hp>klVSV=RtH6n$(os=u^}|=R2Zq(kb7#x7GhqDz)~ORE>>~ z4ZnM22rmD~N%J^ehAThID*sK!`rhW3S*FkVM&2n1iWsRPH zagtNK!!v7Zx9;clgY&RP?_{w>*qhy^;|mP`&I%o{k4EU=x}|*I6Wf~V;V?LBQC22) zG()aFgw{oqG|CHSe9PDX%Lp%5Bsh)2>Ay3m29;nqp%!)oZiq9iN6_M3DfLJP0#|31 zEQ+nEgoT}4!ZGk&YQ+b}8Mj?k9^+~`&$&ZP6zu7IM|%ts=5NdDFIu7&$0h|!lQU>P zDPc$*94bzjQ2@L4Xy)Y4xm7IJ2Z}T(KZoUht}sae^FrS}*g!(CSH$UgbOC0qJa(Oj z!|D*YvHnEx^_h&KEiO5YMjmDOHLSc=C8@;9V`7ELAJ*H%edI=J&+>Wjb!*IrrwlQ? zdM(9FT$=1nZ;HGTfg66%Rx}fkYLPgK#)zU$U8>JoePmrNY0d(M*Qu?lv z(n7YMUcyaQVKJWLUMrf>47aO00p+(;e1rWjreD74o9q{<*fZ8J`fIFV?DSaI*mU=@ z)SJU%Qbjd-p`KqT@YWXHj_&@Zv94;@2x^doS{O?E;qwsmSodJ}P%ytSv30eReY_iW#{pPhox|S-x?Q?>tpmK%~e&hNaPXyO6!xzUz>XyNPN6u4^!st zfX*t8L^hgJAZk0jc)6sofRegcQEGYVHJ7uL*-1QuvmJ%4juLrcciVn?GoXEsBzETL zBY4G`&n_3zH}jqUu&yAG~#r&Lm_k*^o-;gFdZ#5@o)Q<9s;b%-2M^%HAfld$kj&XE(4 zst6bJqV(QgxZEFEO;-~wR?E*u5gjZSg=I=_y21>bHF#P3mkjDsB+!}0wp%MhnAPP1 z7&UkNJ@)J@>qtPdYu@7oRP{&GkJzxU@7RXZS?f_z>#mlvF(kQ#8yzBE?$lpdxl)(pB7Tp-Q;*O9wxX_<}5g_uzMe9YXWm4 z=5SJK&D*p^;qP*#i&1l@`X1{#Mtb6R;3b0gn?^-i{vkkB-a0-sznfz$pRjj8*a@!; zD#sb@maX0Ql_-t?1)UGjNx2?HNAT!~dg-Xo;RS*5aux<&!WUh?R4kTx=4pyS7A9uy zhg-C)rK~J`=NTyI$y@S0{{DQI($75?D-<}$5wivtvyn zse3^$ebwEOv{)Mc*{|cC_XU`{9L0l2-zGiHg2vUSrPwN4TwogIN<^dJ{l*W*1N9`Q zu$mC4+M41Q*v<%$c#qRz;Xzz{RG#Y$H+DG`O4zgfE!Q^Bp^tiMkGnvf>+(Tw$!vvI z9e&PhyRL>?+!RauVT+LIAGD!n$!ez@`d-aRbFr`?nElOEUB!vCEXB8tEz1-mC?-^) zfB6(d$?e-h9u}Lzd6O}RLF_Tw+-f#vi?=F>gM68_-Fs%vX{h^7A|)Hz*K31qdKYIi z0@3eVwwivmUC~=(A(dB@#2RiU!eT~U^bnma6^yFKc;- zolMAv3CyB)5JMxnja0BQFkfJ!o(8s6{8)`4fhsNvSz}!bej+9D>!v9DjUq2iH(1m^ zu`gy+ag>+uUR_iV0xS0p-f|drc@c}2?4Fg9*iW5SO$^FtxsZ{I)DRt0A8W39F?fXF zgbYR{qiA^W%#6%}W4ljZ2zNm8-3Ls6*Cz7>C0uCZ{;pdpu@$5$BSg`l^dOeev=tRn z?KRdCsR^ih;1A>+?-#p{@-~&wDZ0C{9`fk=puY==8-SHbmAaJ|! z@KNIl+d9mucAr@n)Z=}1Bw_|;Y7MgUhF*!dk;_|dBgb8T&Wc3I#xAe-?~ir-Gwa?8 zLJak%B)JmX(rQ>_h8N@8yh9t#pc@=ct))1$otro9-~c^Cf2)N|P2o*8kc(sQ77Ltn zrAKd`#k~!`W|iI8IO;z;j`sQ7=prAA%ZVP)I(ct-wtf3xBMv6gIq>ZuU_j~k9XI{5v3O$?f4t8OGcC(!4igS?{gM{$JtYxX zbkLAps2r8${vvko!{)%-l}R>$(Zt?r%hbLJ-c*Sw+qaY zy4sg}Jb;P}K0mf@RSBEfH5oT396;X}IGy+bQnGZGl>WNcY1rLhb?ZdGq`^N^Mr9fP_XX;N zCA=5LpCGwSyfUy==zz{B%uc!_|2H{XML|+H;GwOKX|9xIjhgVGVae@Mi=+y$46#rB znz~`+OeiBMGiNSc@9N%nPbRz%ksgdr^iAl85(|>7E;pMyO*cL0kM9*3Saai=<`Ne%k2N%S%uN*7F34)#OMp)zy`48~6re1L`T>_uEKKx2KPB$(O@8`#Rxv-08)0diE zea?O(CB156%)j$gR9a%xEX%RBhF2D17|L0Hz5W9cJDXGOyn$04b#x3O?2)WS!B^R7 zZTsIT?0#t~N9u>*l93wXb5Z$-goC?~Cwu!yvmhqBORFdGQH4WGP2K|6)?$T@J+DQ7 zy%l5O*uSX3cK=*MIz}&HEh4MRIpHV$78!wZ4oqsdEF9giX9K8yt{Jm?rl&HPA9N+> zL2lD4q78)1MI1c|k=lj4EWQFy9Dj68#~-Dg1W5{3+eeaveEZ=Sh9tDh3o58v$d(AL zqKrnt0X|`Erjky%-VCzmM~cFkebSqWA7tHKFamY!BaF!`-y97@mLkZoUL;yrnkcmE z7WjFMqY#;WDtg-W86`_X`0`fpvW8LYkv<6H*B#rkgH$!$p!f@qgT^IfI@D|wUcD5- z@7NE`GqUY?;ctKcj}f%T7ngK@=k(Dj!tqOm+AL0~%!0|W{Vo;40Y6fPulP971xgys5>}lU*AYsjA|>!I#A)bP|L{mcjR*q#Oa!S1SskIPO=gS&-|DMj%c z!89%K)~_{YVpu76N*hJ5K8;&YImh>PO38g*xE)WN#z0$&Hkj4A(N%`bwgnM?YFJkq{*=p71q(9Zb9PI>z z{2)gU(7w$(1FDsN4Xf!7aQtXIDGpd5qhslkvxm)I)`+dPoR3(DHh5NFdt|Ti3gg1z z^a0(b2RGn?l$>mTeRbWVKI(HcR<+_w794goZc&ar7wH{o1wGvRK9C#}c&b;&#qpMxin>I^c|c}mY1-*T-!OE@ zO5jNZa$Dw2nRY#f_D-zI7Ze=1@vFn#A>xo|Em=cn!7F2H6F*jYiD|X48BWEX00|MatbcFU?ciH$YY4|C8lmv~6BVte&Xy~?{2*F> zw-Q6}U_Sc+lIlXZ(H3@%5l5hd5g21xu4>9p* zLqfHjdMa5pDvB3n`5NUs1WS4#Kicc178=ykPbp;S_bARAcuOn(V}3KFEF<@V?x7D= zuZcSd428r{x4Zeh7Yz!G53lJ3RQ#OIx|D_LxLBhAH_(`or);AOAHN&awRz^>QVSCn zEsE5ufBZfI^IbLKM#*Qpk*TYja@5wJ9>M{6x}0Oy&qw^6^FAmX9LPjXpMhNa{^a=c zw+Laewl65pqZi%73VO6Y7X!)UWd&a`!2KUK(vCk9T6WOa|`RosK!}92a0v z8d{#BVlUbl)eYzV(fVN=g|G4|<3uBsU+F4Zq!jNnC~M!nsT9$J4L5o%ZpJogs++Zg z{q%X>6{RdCbP0FNk{S>9?tdv89au~Y(k4BY1ozX)6<+WK5*)h+IVpO>prr-dS zN`4SYR*A8%Sj#fdkL-ATp!z?!wXoWno}OejD}rm`xm(Z9V`^T1qx`|p}o zdHMd;_{FH$YvrV^W+?e;kj>{@gom}w&p)H8=%iFjMmMxf)&}-nF!_QN>u;V06e;#> z{5alTQJ9*4RP5E;BXb8aac2+r*6zQt^84A(+)=J(>qP2<3(qcvRFZ<)q#o6O&gd(n z$cdq)8bXx^9@J3%f2#?prdufn9xzd#P=74x>#JWHk-oANob@u>?_7*(Z}Rw#_Gi!I zsmH|!GDK(psKPPje2qNNmT|a5{fbnqpJ{GmNOwh#Tv?QhrMmdD{{8PD;p2HSUsKRx z(h9Q;8%wLKbC27=>@4oX%dD3Ol_;$(nLVL!xOII3ugSOu8TjK5H`!CrY7W9o%IDQCQG@BY{c$~D_&eEK z%M57XrJYo?yt~(=3b-(6Nlz6{KO^qgc1Xcc8@s&q-fSY6#qN@339;|ws8$SM(Q!k? zE~VNw(vtUbwSq;WW2ZC`i}o>(Q)89#2+(Q!wR!E!Lg<8{WMWVDExu zPr2UC!li)oLrz<-4hJVrShE=2n@E-61x@8wrI5_MvnptoUH$#O+jWHC*o@ zSX#H0ea7k_q*z3{`25B_E}mZcquf%~4^vcu@vy6s=H0KeTorFMkRcW)KJkR#u?)O; zF|V{^w^zT@LY7}wxpMzitD|%a@+*qhQ$&^d*nsK#I->;gN35~pLzMK^@3Z`{C|PnS z<=MBbKR<*5iW0xx7->&bm>;>=)kb0#(R!;lrST_}wg!Op%kQGpfmr~==%*$vCZWqf zcj3th2if5Z4Vdl%<^F$ZBIWrw+N0^Cdqw^cIoamBj{1J!opY{gPMMrJEzS!c{X>D5WGyDz+$&%$B^L>vFQk zz(m;kTH+h!2uqj#L#&>a?Ehw)B3G4MgARn{_E1hUNlz4`i&1_i<4uYRP7 zbf$3C`^z@a5+GfW){BbeT4lapd~6ja3Vn%#pg z>1rl@4Byv?Z^C{AqV7?OVrmQ*2=rt=%;BaW)|adg+2Nha(9>i-Vv1JD)RUSbzDB_h zJ@X?y!Q^QFwnBf`5E)JE;<2|@AZjtCIsBN>z!20LiicYNaY-MiPeScH7LTDS-;`0M z2}KD@pTnc~qBN3k=J*wqQfI7LgM~E7d$_Z9jnUBZ0tJZ}HH`#La`+v_Yu15<ikrXwOJML) zSGM_U#YOx^1;yz%rI-jF1$pqUCim}6bdY9;CkcdJ6nAk5=+S#;qW@YvXk^1Xjo#k|EMWM=n*0m^67Tp-j2Ujr25cR!{J{iPvoG69R$XvP7%!6bnFuav>| z&+R1W@Bx2OVnYhR`#r1vz-}bqdx7zuP6DCN{_j5Qx9`FMkpU#nCYjm9ZIqPs+B6r; zaYRBCWqRu#{NwE4y98H-EiYGx^xueB&cZ=uhYpp&1WbfC0N|hu@^5&{2@o|54>O-L z-1VOb1awN2>{;S^03#KftN8pcUnO!q*J<%SenH(#PNzg?8;wKb zMQF!F?$UjN8yNb8Mjy_*AiAB-#i+nm9iPo;+gK~gi!ZyXMx_>Cl#eDso|dtK%M=~gc(4LH1yIF?YR_Cg&s?= ziz;^<_8@y!dd4#!0!*56FV3ER!2>Z|Q-mqM=!DoN>(Ia@x^3PTI?<&H{8Wrol8swW+^rrxCNL`CmsE4jGvc(EM=z=qbJ`1+mR_jl+j_5dnsn z_#sAy(4)QHMFVJz>TEzxo}C7uG?Z=8k_trm)+O}*4SG$R4nfIr?G+7>vZERSG4C=I zGj9%gvQ78a&!zeFuQ@k=V0KlN1(wo^jC8(a!O<1`EwQu=wZhb03?9c8w09z0Kg_n--ZbTbtcp6n~CJ4dzSC@ zzxW6jP^Y4|XCm1ZJ(|U1vuf2D>l2ygc?G+r18%aq+(Ey$C&<+R#ha*uTLB0f*i#j% zniD!^{>9diJD_l9ZJHc~Em|U&cUS-@)C*u%E0vPit)CP@^%^~7{!z)u$-Jp!@?Ww^ z)^+_UOoL)%v~?XhDnDKoOt`ddVa`(z z018&HUa%3szhQ)JHk+1)Wf!sq(*N5hUPF;&or+0e~ISbcQqGTNC!|l7B!G^IzB~=Kn)|Y#yi&U+i@4Hu?xj6 zv|*RTod38|i8;Y01FzUgSFoq?Ld0!CX&aOc zOme`--+&Mu062+O;;vKNI4J_e&Cdt-De!I6#T&7@-t!~t+ln8Z=gXRRy%~VYy4a}K z)79+1yG3#?YH1r_0FDJKg#pmX3jgFbS*65iQ3Un<{;S99JB#~h*?}+zC|OT_nBexk z2w18B!XwKXZX?8iHa>9S&$UJ;_t}c;Bn~jlI%Ax((@<6jYEkT}{0Tn5}&eZC${CK#Moax3q zf6q=<+xic$8JE%M!9j0r(ptb2qx9_9h3ZZNPh0F+ zb?k`sxe&dN?p+1)H8ZCOKK)S_P#bxF9H$Gj%K)^JzH#r9acI@4X^qM-bf|S$*DUcK zgReq*5AmX1Z8G)!J9K)S&c8gQmedPf^$Tim6q-~3oRju_L+l};iLk>z-Cg9WNIymL zlvJVM^i*5fXI&IlG3AsBYv^vSRx8>BO|<&sG8zQnw$;+jY=uEsU`dB^ms=**Th7JIa6v3WyG9hTK(uuD3S(!p=AGIMHW{`y`QYf zds>+Y%*fVi|{0fMrSh{b;*mJ7mL zHV>jge&+P7q-(W??Ku0#ao!=uU^I5+iIUox)I*k2)YiPfS_O5kq`M?|7#;I92m>I!G1AugYfk)7m2zsH&b7P_@b;Y{ z;v6^f9C4YW(+U)T?g*_GRS+@Y4!8sYOD*OvA1emwP&_ObB^2*j)4s-|I?+d$v}k}w zhJ&MZT+>`~m;;5hY6okgl~l-~FzrURED&r;%~0{3GAfI=SEv&8`@rl~p!gyCAkKw0 z;*MOlD^|^?&xfdpRp2UqvVD;5Y3GyC@1TzpFXaFj9xdfq)$QjTs*027IzDmp#WrI& z=7_s&?MNE~l&veU58+K#j8|y8pzee<&4oQotIb{TzF;Ikww6>@^)pZHM0YqLoym=W zrggdSn*`kCyUJPPHg|*1l3zUR=Fd8*++WYC3h;7WKiNSiyerMYm92mEnp)h31HFNy zk3tTO{q;d~L4#^SVZSue&LgXo!rkXsj3PDV((98^zn)MPoQ+ zVi#na{o~3vwms2)m1{;mZ~{?mHwGx+I(G7|sx*8?QWhrrb}>YWcCbNr;C?2H9tiPUr&ri=XrDYqiu;+MxRe6fcLF7WH7*z~T3A zBL;Wdy9|H(Lff}(Rl_#1y0RamVoo)ShW17>A29uqEPGsAXC_-fyrHWdC)dsb+@hzX zYD>5@*gC>dt}Qt75e|7n9szEjJr&eJD`{xZ{`iFF#W(gKL*@S??#<(&djI(EEQJcg zB$ez8St5zD%t#~IlkCe_lAV+#j9r*y%UWU(+4p@Np%k)ZoyktdGM2H<*zPlZe)so& zJnld4fA4?GIgdH#I_Emq^?tuzucx}DPw7ZinX_%((Spk|0kB|_paV;{t*3(0jreFa zsfW`xx86t~vo286xWzvpZAMVtomIGb=KCzWLvv(*(5Z`?pJ{&=u5f}MLo6a!5|YZ0 zwr(`wGkou+SdkxMY1XaPDhGK=Qg<;GwC`($exmNgq5qGIzQ# za3~>Tn6M?>S�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 diff --git a/docs/docs/assets/screenshots/b4QOtkzJs0.png b/docs/docs/assets/screenshots/b4QOtkzJs0.png new file mode 100644 index 0000000000000000000000000000000000000000..4253594910a811e3462789143c27d0d4aecec20f GIT binary patch literal 89672 zcmd?RcTiJX)Hh6%B2`fVDG3%VR6$W%Lb+BDupvl^5doD@6bUs1rKvO(X_pePfJ$$P z)MyY80z?660U}a@B%u>XNO=$5d%x#C^UnR}`|F$e&J1&g!`b`nwf1Viwbtgbz3pk~ zt-H4h2na}@J@dy!0f8;z0s_Jv;-bKl!KXMHa1#u;c-m5+v|HsD@Qa9-#d!+>fr?~F z4txvnyM+H4rvL!~ndZ$O!8X6QHw6UvZ_fT4BVmGb=CJO2pEB($pNh?S{<@xf%04;-d0@o{>8?^fe*U!2MLVK+ju? z>OjwIC9hVcK-yUM*ee5HJSlMC+S;|C(bbY`H4X!_ZZ-Y&WwgLIS5=z|-_I35!i#44 zEI&R2zqvqxkDbFo6jZa>+K7A;XG%9t+4qBb!(yVJO&Sr88@Xpa*n|pmtVj9;lgVRg z!}E5$Njm|7w|)Ex{u#l|@t(1=5^IC*$pnA<^>||efr9u*x!=#9NlSnt*2n*^=R@^l ztECH>q;L)TV8vd%_%3KX^TDUE#Tk|3|@Z3h9o#mofs8zxIGdfImb!{b;s8P3NKSK9-f>{(CM1EnSt% zC)M-+*EF%JK_hp^znump#zvj9B4|5fqnl-+4K*XMK0yIJSCQz=Rp?1hcV?z2%e)8J zV-V6@0nZwCg=EqKW#gY%IQZD>D5c$pgFJj=* za&j-vz1ks~w>#UQ+2=*l{M!}zkGH^J5rNB(Bg;j_#V@?MuvOSzx;t~+@LXHaWwyli zqknV7QCKAUZO_3N!MCE+PJiV$6DEhbB6_lKi2m+U*0z5w?_AIKV zMhGcN|IOZh0YUZmN6*0p-hcZ41G(K#3v)vc+nhfilVcJTyEoZXzpCjALM$4(vB;NR zS}o!))|anN;Jb^jLWjBJoAne<+dLsfIU>agdgo^G&CW^d*48qNcGPZBEtd~^Hnz4J z&;wb9J{`sL4p5@J=GD?pM9S&ebkt4sp|-MlWPN6TS-`2*uWLcZculX~Jhgg#c3^lR z?R`<{*0Lt{odKxdNzn?7z*o)R@+E2r?u*whdmkU2X_yl~<|bsRY|GM>;Bc5H#l^#x zISPCO4ig`$yc{vRU#eVT*6j*3g)6mE;G8QfR?i3;T6jxG8kD35oSK<8vqQ_yh8p1} zRjM{tmg?^rO3zkkzJj$4_))ZhZyh|fDRw;{w?v<`h|ZXc;UO}+PwEQ7&7^y!2rn_j z_c|j*QY-Iu?7Zq$hbfig7ls&~*L0}~GdsXXqWtwPqr$_K#8jb&E~Nt+YJTLe)gK10 zRNd!nc@Uoa_k{EJg$cgG7RizRA6B-Du1r{t7U_R2sxy_Yq}$+pUq~l+_#W>KHS+pH z7rz!dRpJe%i*=P*MA^K}LSp}BX$nS%L^-}}pOt3=-Lv>(3( z?J;}}+qL`hxtxnQzcNOgud-$vb|X%gZ}{#K1kb+8|9+=Xn~1gUSj8+4`;p%Twx+eG zC&hC#VG+f|nf+2T_w#+xqAS!^w-xf&&-{iN(ldTYs*iiVwVNZ=%V?JLPTP)^X%~U| zhHWy#VmkQQZR~Mk8Vc(>x_h*Ht*Z=&hgD0N$?(?x1mW~IIZ#LmtGL@vZUe==bT4?) zT0%GSCI>8c9WU&tf=X62t%u&&7+Q8q%IPm753UkGQ0KDj<>CIpVCuW2_2DDwSeE;b zwu4v*wk#peOpH#U`mO+`NAdD+Etj@2zopyR;Wn}^c?vy#UAGv?7)~APcDs%|tcl$A zO5qMq$Ym(vv(D>|*{kMn)i2SBqOgkVU9nL-Vyr_*;EW+etGBEnQm@RE)x&IgSUXtR z0GSD9UBA?H^g}Ol5KPjI|E{EYsp$!`LcIWcK7C4+yr(f*uwofDD2d`4eZ|B(K2_Lo z`nK9DA-+6ZSl!^5LB%cJz$;gqom_2g)z}r?@|jHwJZzn|GZ8oM^~|kX>D#Y0w{IV2 zAdM;p7d%Hgva5#GhDadVV67_6IsrQ>7I|*?c~C^lY|T=uiCt>j0QNNd>#q}&s~0-j zoxO-_KC`dWBZNNYZMw6|x33FXhCRD{AFf#c_G`R|YXNys-UtM4)7W9%Bf)Ac5D z__$}CU_Spjm{^MYgpvMn^!2hJoIa(DHI?SyP=Dj9F-0~n?nQiX8!ldDFX$L*+NIw% zp&Mc$a596Ywe>L95Sd9iMb_b;GwRtjYKLo=yciEi{G{t!vfgK217w3i(5wnBq7jS2VnVo&5@S@Mquo03K85%)gq(*} z$}i4X#ip3JnWr7sL4te&5OfpOs>+G}U)igu1vKahdpo%`O<^PJW}CX3ndt#hVT^U*wK1Mg^F5$+Je@ZKOJCEJ-d4+8u zebD^#v7+QQA5@2E2xL8>rf4SPOS)ecV&l7ZqJG3;8QvOV9p)BVcQ?KY#IFpM5WbK`^#<#vR+!SLM>v^aqP(2UI#aX2{}%YkuIAPUY}Z4 zRt(6-GX*ef;=&F&=Dp62q^yI+Uha%%9=%4b5w$+vV<9^xXsfID0ZVsvhibg9kmabM zUqi?LrrUm|E#JfH3~Q_#vf{G< zzeTrhyGq;1b~$|rmK+6<{YJW@Rg|s=p69GRA*9(_oT5{|^GAsK{N+>y#m^l?$)it( zcNX=gV-)D?a&3IxQXreb2@bs$@ohfcQHi+*S8B{Qc=^_quy!14r`x90@1?05{iNnQ z?sVFDs^Uh#A!P28m)EQ@P)9!(Fd z4SSM(Gf~v$`UX_7tzbUZ75mJ1lE~~`(=OxYj?VEp@69gRlZ&~(j=F^aJH6D6Cb~@$ z@jNe58eEr79J!&g;nd@S9UCOU3zs?;@{@E1u!EsKP*h_D1y+~H!24b`lsdG$v0pd( z&?~^1-M^C#N*@GF!C&&elNX-iQ87W?*lr?=2&r&K;Ff*j6Jf<}_@+&|8O~#afKU3k z@;f*>YA={y4v1Rlwwt;K8wR%o(S^?I-syO;v)+D@*y#B7S&;gb*C5~>^-O-HV4AGB z&rpS~^5?0pzTV34N7Lk)R6y07O=M1@z9R2$6^}_uj2L3vKrQ?9=$d#ElCqdY(w9!} zO9udRcaj?7X1-k#xk3dq1GaC3)W9F6D;R(N9C08xfF9A&iR=E;lw-LOVMWvdZvuqoNyahx*eq290j>Z67x**IjBH zogG-zHbxTEpiqaNvO$WgvxcC0o&9cHxm{94n3yVOTR4)l) zw2J_@u`w;&(a_W~3_I!>%Asd$FzUZqE86dfZYMpGcE15dSD0J{qCFVFetVZ@5~4X&fY_l;M=Q#!Un)Z1`Z?J|?b@uW}ZD10BRb z@~FiLZfpsGs3)5d_L~P%;?Mf6&BZ5w9h3SvvwJF_z((95=${z9IZrgY2;~F(BOh`_eVAB+047!c?X5a09>EGNa53fA-%KyF)w$8cX4GS?b6EaA_2)8e2N0Bw`)wsL z^sDG@WL1qIUs-Pj(2Jp_gJ9EJi^F>Gj-f{HJ;ko!fpGJKx(S0#0hL^rj{}pLk>1Te ztr*Cn=0B=B+qJEml{9g2uI$`XPWmxWL50RI%r= zNZ~kbbhb z1E|W06tihn^8KOUdR<(>nk%+3#1vnnJ#wAs`f`IVMKck3A7BgHW!TR6I6ahH4;xl8 zbe+QG$nP4hHKT{OXUC_QG&2L^n=R_j7nL~4d)xSD9NFe@oOsKx*G=Ohm6;#kJba*Q z`S1aZ+ZwX*M0|EQ8dTk|d8i*-Jk7@RBlYMep%ka^30 zb5|s~F!sA$o!9b^Lhv8HwOx|p&ZI!%iz*X(|4@hy*mTvMOoo%@M&WBX8)sx<7PUE3 zfc{HDUXHcUVibWI92!BcO&q^DP^cwIb~SOf$QC)P(Kw+=0huJp!wIGam3KRz z5ZalGK5K`dV6A}yWdhdk*cu47yM!25;bmH0RS{0*wtPy<$vNc1ORLUbY!nG)_}EF~ z{QTm=kR}!0#Gcj@F89%chiHhw3`D&N0>)yN&pgQa1!?Mc#BDf}n;Bho#$wT=n8%*i zvv?tcN^?+3b?qws^s8F#+~}}qSW>ryHI9DAk8G-T7PjYsiT$zvg5!Gfg5&SpyPkU8 z2^wU5{XRbE8M)t}347c8r*CbdXmo(h2duZVV}YLtWM!nhAHpYzMz?wUSDV<3gq$)F zF?i5Z8rSXPOOg5bd@5O2l3J$}a$&&FJ0|Uy-eJ!RgRfEjO;g>)2JReIkutGvHd*Pk zYE?jQ)iG!Fw9fEq2BPM+KEk`}BT+)U{?;Y$f;?$XcO8Cb`IFYpb56$#zw>OVgVM<~ zsm}~}rje(Zwi~E_Y=k#bw=;b04@d8@gQGIJfJxEF&g#}~RTZ|BSZ}IpI@a71TU;{1 zW#Zxjj_pfT7#S(5QlUn>mnr$-uMCSuYm|@Gep8Xnj5&cd*6LUhe!ENXKavq|_ka`b z#N7AP815}-vW?&jgHqr6;xk1_NP&Kq1AL;N8L-7fEZS3ay!3p@kV{Ek+sL_* zYfMgozi(wRnU`^Qg~aqeGJdm&#PC2G-Y^BzD}ncXcC&wJeF6+0$FuxR+uBRd;7l?T zYc#EB(}>kH#d!oeh9;O$I%^$2$D&Zu;(I+j2Wr|(*~`75r(Q{Sk$l7wd$2j=W;TuF z1BGpyG59Yjwm)gED0%u?CsFO^c&5beu1-9{eml&wrvJ33Zin?jjoj=<$^#0=KMR#_ z?@TCJsam};j5|y1+J)#`@g`|_lWx(l(401#>W61?jt$L{y8Zc1Nb=zNeR2U3|6JkC zOz=JfshZ+bjft5tzS;NM<4q~L4(!E^5)Bkdjq1hx=cuYGe2LOqwf|C-nK1KPgsMSzmuqZ|w>=9q*L8-cWaY%!Lmdi>oC= z(X_Cw)iPUgw5%#;lpp?N$QqMeFKO@!SJT$a=xhSe_ay^cR2DT_S#7}hr(ph{uW;Vf zEs5qa|EUvvVZw^DV*up_-E+(%>iPYQ6E)tZE+wQ4la<->+g{zy31!3mbtePXy3dc_ zS&k(ewP{IvW5RV1ceZFQ3KVCzFuWwsxsr$hlwJSC5IyB|!LSY5oL)sooF6il++A*v zdH#b5f}fG~tN#l6Uh9#UJ8kDihHhCMr4yAfI^;f?Mvdmz*;Y*H4r9@jltg_7IZ0BB zd}1u3DDY=rIWv>4oKnVX5WSNaP{DO+G8!M;@7?^_AnW2p^$Z*(@ujr<*B&VCtEt@* z5CJ_?F1sT{Fd9eZ7-fZ8uUL$aTw&nU3WW&q{juk1D?V+~0oO=}SNu9e-=8-BkG!hq z9`K8D&(+?!kXuZryJd{6S!u7E(-HQ2rla3DA1%K-MgLQrbTZdNk?ggGL&lAEW#0Ui zdDTeJ(FyW4;ZG?tG;Pgu$h~>E>`$Lp>aNGR?aFPBCVF)jzH~dthfMUkW)16V+zt(` zc}I-)%?w?t>9C$1RYg)`Dgx4C?_T2ddHaSzZ8bOu1Sa>vfQ(8Y%0#MI1AO1WF3acE zD&w{^rAv_(AW`E-(Wg$9-WS-qBK%)+nvof4ud-uT8Ceb4bd&I8GzCsg?~g0GWPsoO z(&B7U_TzGE;gkVnoU2`_bi8aLp8gtcdtzex{CKTvfvQJUbh@j(fnXS~Z zx zYv@IZb6NoT*?#IDvm>ECK}*cBn)toCQyBrL9GPDO7y)PKW2#6q12qRPtX~7?X1W>? zSP?_h$0?pLeBk_v!}+Dyckd(1jmSt&kw!vxxK08kJXYznyqp?d3&EZ(?PDF^Po-E9 zhjkHx?6+l`WrL64MSi1@K;V9SFQ-K{GW6Ey?m5dd*9}*-fqW5gt%wP#+g~ljQoycD zPKh6FHnZ>o0+D~JgGEF~fWUAdy+8KNfh;mc)>Wk+GSoB`Om!R!(0-7)3B`bGvqB+t zV!5GpvNnl1^mwVb+XBzbQ5xv zaI3;VVrpc8YQ0&d0Vs{k;_;&{-P_P(!6LuQUBByBec46<7vXXw zmFR3?X79Dp!C-3u1U6Bpn1H)U2yk#heYT(lmR@Ob{KC@ZVCEQo=~dD-P;O4>{_ycr_y!;{cmW+Or7+KBgt8>Z*!y8m$Flc;CuVTK?rX#c}->e_P?p79Rs^??{BeC5meW+FHn^;v}(Aoc*{@Mx7d$l zY$yoZw_xqL4}ybSL2j4pNch7fthOeRN;4Sucn!g8y@U2UFnY0`COkIlXQjTuLD%|f zZbZG!k83;!A7z=@N;j*&rAqN0;5Q51cFV@^rRkGvbjqs?WU2(mXZ7H^9QVL|RSKhq zW+QVA!Ni+&*@ai@jWr0fgAnZbCO79(n&mDz98KB*wZzq-?+QirdATC@tJkb~LjvNjtV(z@^@=WAmM6H$ypR;U0jQ>X_0PY~fLWbnddpy)c zJKxg)BVHI)w5Gy^YEQlOT60oq#q_UEdC3_*v?en>-}b-PB&T&&+H9co1~@818l$Ih zonp~BvyXk}*;Jh1p7-M7y;WnCpE6Uoj_!FtsTLy4uO`CJXHyjjMYUGCnN^x7{1<-g2(_N)rpY1PrEp>KHl?k=Zr+{FpF zG?2Ce91J_l*Zl3#gNT?Qp5gVqx?meh65<%{acq)9d!+sFuKK{*T6AdabvOIMDq;5? zK{(c|!dzGP5xq(6cHv6?sM~-p`1BRQe9;@UOM)0#s;9dsJTx|!o9#AsC?S4Jbcn}E zPq|YMiMxE(8cEpJ_ZM<=J`HA$+~5?V*@c-@=??AI%5Fc{%^yO9N_D4i*pvC^5vVKU z*#kc2j(yXWr;dP&^`ldGUyf*+$bUo#>4xw*2}zi3TuIIuy@R^@D%A5E%Ku1X z`Ix*rZ+^?~Q!2WwkvZIt-F*>YvaZC<`^IR?*J1R2cv2zD}K`G9;fdBJD7-u=aAJCKvx^hGGa#NG#Gxzx$j= zjtH(;{v$cw48}0Jh_yXL7HjO0LEFT$)je*RRJ#r!Lm7kG zt>1pwcG0z4UmmO1-G129*P{F2ExQZB3bidCKB&p(b~KgvWWnKgl%AH=MJ~M6W75}} z*YJEB#VXrr1`e6!c=wD&unXA~O zX)HG3MJuF4A5R@lQIsTw&xegqwUrX-l*6!^*=Hy>nPiH6rPi+j>*P4v2oj4Rm(gBR zkQ>Tsvbyy?9Z#>@mk#aU*RVDgmNL&Z^yu3IUQvG}Dg~5E1e)Uvb75tIPo<-enl1%y z)M*X1#@b#?k~W{L!VaYu!4uNnJ zIyv!1(4lbQ47N%=TUC>y=7ZKkT#g7Qz9^i4Czq8K-Es+Zxj}8Jq`t;lLpMTKU1kex z@g-(u^oR(PdfT+yA)zk&623EDo4U@COaL)mxmpGo?Luxs^>j%&Z;NWCeHWc7Tsv7M z+vgA`A@92r|N8aK42PBH&pVqEpZdHEA^YBOT{fKUTOzhLN7qXm?UvJ^X*7TCO&MC% z0n=UV>PuIU43A9X$VZ2TEu~_&NbcGoMSWsbUs*I5?$EUrW!TrC(cYlaww zJiP=tu}D7W1X-xe&yy9`mcB9x16^k^Ur38{vF|UTxsWCqkR=O3^(c^bF~1d6_i_rEDXlRXP$)nsOP}{)K?W=G z-z?=nlRkHY_*$#6q^BnoWj=!|3l+_u)8xKb3dGoQSKXZYKZ`MI3Ct9JkucCseKhC*J??hsk+=0lVSQj*{C zsg~heZ7*-RxNjh@%_r9<75O;h0`Fw9mv@;Iob4IDK$2j?Ziwa^&owmbpy}AUQ3~nd1*e$x7{*_b)5V#W(PNhmx^uM zgg2K7V3@ppoC>(y1F)z*cm=03TuyBIX2{&-uKe>0)^Mkc7|2O8kTq~}HiGPcapognMY?jnt%zKRm-N&Z80lN1#+Gx}ZW8v;9_>x~D7Vn|{dvI0T={!R>&vZs!GCzrOX_(JS2id54nVj( z=12hPvf_P$#DSYadqFx~)j+pe_*)jQ`zX3$N~N3{oxPXWu=o!o0q%}~>$tI9BnLTs zdmJ#Re($b-jdOV`hE{R6$j=tOr}M=~of->;-T2p#x41@z&-h1SSsNksz@_#BUWC1% zqwo{!6IyL!xsvyM|F3ZW>5tQ@XwG7Z{jG6A%y{1=JLxvnAQ$~topI;RxgCDOUTCvx zKa%FI-R6?im@9VAb`U@l&|Lsqfa^CFQRaw;bdPXY%PEm(8u;9KyEFFpnL}Q2%iSir z;Xi~y;tDSQ79NoGPqHshM`+dWZ@ZZEPQ}@%HMC)MomdN|Mnmm5A+P^M!upTXR+gD( z3*g_JymC@S&Yo5cygZ2Jb5ndc^YVQuD%M5?_YhNx#ESk29jdvO%0BRKz^V=)wFE;D z+tCk2b8a4~4M=hFkldvuJ|Em>qK~)IbD0E&q`B*~xpfPo-R^Idkoetq zDa+h351z@7^Na|({-OQIKxFyBeJj+Ie_`-bDYBtA#(%hlF;Yivu+wl2`N2H!tcXsEzbb_c6^PbEL32~n@XZ{BaCa3|L zNU*p&2#?!u@P+fwYl8sCMvsRJmggXwi1|a@(x)Uo_6h3RzyizYZ>3iY!<9 z*~nRV*;$t=zc@9;iuCsge&71Z+4XPiAU?AnXyn=>C{-#fYpOROD5mlhfbzZ_yp4Ix ziA}JKH!yZuSs*^ke0U`~L?pTj4uJ7*o7?mc+n))15{ndwjhFRr7^Ht1^OTz&x#;bu zn>JrqaE)F}plewv3;h|X_wJSJDZ{6i6H&vfnaCF35L@kl4clUbPkMBod{!0>CX)p^ zbXZgQrp5+txUXTqNkABu?j?Ky^t4;bBw_%6D!nI zc?}V30)a^d;$%-(8-pJPpWNyoc)T`rOsu4S+rkhkzT;fkvVoQ|{8jb0RlBG@hmAMc z*;Etew!f4rK>%Rb2i8Js5d?f+-OFL9usSC}XwO zV<*#M;5at*UX2us_b%>uTsouE`YP4t;8yYFf9EHDPq_TRZl_?rbc;UxPrTU&7|?07 z>jo^Y`b}-3G?nA?mFF;RgL%?%uBPfP*}uTWm2#(Q<%*>h3s+$~Y}SiYko+s%p(rR4 z{n3AUJTYBC<_RE*hRY_eiciVm^i^j)Jg2)>0M}A|TVO!u=e3Pfgp)e~$kNfVlAqUA z$9Ug0?qT3uaU|*F#%gl5Ft6cn-BJfK2vWyEW5FSU<7#2_BPEgLW|AbcfUlx{?S_mW zL@36N(7I7m}$p0L>38 zUE1^|!Lo76C~U)*iTu%LeQu8+yrCHJbVwY+II$xpBM~_nlgiy}WCX6gKw~bTDbI|l~Zi2u&<{2sLV+{*ls?O&Gfx(J{J%`I`qfR4*= zk42*){|NP_S(B0l_3fw-loeE80?Y^M-{wO~3?zVjt{}5rj_|ioZUZ`de?PS}f26-8 z1Zd-5nG5qopgm=k+Kjj5(90Z804C^Pt9g4I#7q5l-hBNRUPcja2!z!6&}2_jaKr5T zB0^DF({4kb;TKL~n-m`el0}=Z2LcvJ$a06$Oyt75!rZO(NXAx^pgF12Y9Tj0QA(R| zJ0&FrKGl($8Mrx2?=Y|j?4@y-5~Obtmk6x)@K%776R!mGMZ&hroGU+`6Zv-<3V6|Y z8FJo`Q(=BMEAgTj?VQ%Lo1E59ytgof%Qu`EH%0bn8J_ThbgV_By_DVM zZm?}LCZ9~nn`>A@Na1pMLGYGLs0_$t8PnX>%})2dP*NbqvnWYcxRO$Kx zu)IlNc_~064C;%5^DfEB8{`&CsKojtE4Cu@VW?y|%y)pO_0jQ>m+&XYjT_?_X>s@8 z@zs|g`iLf>G6rh%u>LYQn2C=y+0O5;*#|bI9T?})(7T&>Q?M8`FN-gQXC?EMCuw}n zEI$^6S{oRzJ&jiCcjcv&b2>qB&bxSex8wZCd6~ZEAA+sJrhm*977`}YT70vA)iKEADv+`@xL-TLbBJskI^G0PBla1F-JZiPwC?vM$$errJ!tZzGG&2!lAOQ&B2H z1RfjBNBc=0hpcpUE*UF*i2Mpgld5oQt%T|bv1m(L8grc-RpY|q4S8YC$7KIDHs*o5 zRPG0SU?iZ$aR;il9NV$-fMR#a0SVqHc3LSLpQ7^2Bt%S5D260oGo0Ru-ipiNz4BkO zIPNuk;!J^p-0*d6zg^d$ZKoU8t&BfFNAGKUg2n@JM(eO<9|dq0N+56SFNW|RkN zOue3U1TtzG;Ln{4pI}aqFNd~@0ZBtUA%dB#X-&U6TnkL!v7LDg2)joPOOrTKW}s;n zIoSQT$Sj#wV9#+YU50mhJ6|x*z)1u05?MVl?e@%6K~GugPw+xEW@SO1}kQvi0O=Yd@CP6yqZGc2Dor(mhIyU>fC)lumy z12u3!fM)Qs8@~K8OeLF&7s$(bS~ks8BESlxI@@Pk{G1F)W-CPJ;VJ?5jY8roBc2kQ zy;a<#Uv?!~mfNwUZi^NsRQR9v9D1 zL^0h9y$hXVvqiWKwsS&^XdH8whdOzfoQ?{n-rl$$29g;zZ0$HKFV{M|$lcW5Q$wuz z5O9dZOeixV)`F(HTm~hP2qkwZ73}3jKCVSWODA*?afR>J#a(R}IiBdwOebcPs zcA3lOC#32c&np36HV@G^vCB2dkQQ^*%h)Q2b~=Nl+^6x+xQ?tYt&;g{*Y(Mh(6heB z)IK{!0|=LeW3j2LExv7uBdy9nul4K~=iCGJjeQhx?fuaSH6?oB1g1oW5@2VEaVHEw zaGBft9?qjcn@efJlELn< z31LgtduPD&IaUlNm;*}`_hd^BP^C{7at}M5>In%nmOq&cEkpFYh0wE z!tM`ErY-6{%al-@|1C?`v4G%8fqty}`xgii_Q@e)@3pU$$murf>|&4JjXz`{!CnbK zl1C!Ttv258k`$jRvQ>v?MgozdNVL&XZqR0+kheQsg&({`|FqKisnzGRp`wl01HR_K z`(>Wj#cmRM3B#)^Ei4;wTc^NTN_<5fqX_2$Mpa2+q+TY2+HAU4{%4Kf>UT2A0H^5v zGy{=>T0F~PPN|&T=!8@Z#n$>+=_mjRm)Z!AVWG=k#Lylre}AShVbDNy|BR+M_adGB z1uLuu=#(oE6%wAzEK6|>L^oyZGL^m7cu`SidP`K1b42PMa#_<4FJ5RVwG6{u_9HAA z@DI80o6-$@Fg|8mqMO0S?%Na*zc(@paL?{ZMjG;pftTez*7zMsv)A1ym|!Z$@6E^H zS3le$?-q&1^SaRA_xv5p*ee54<)_{6CF9v_p}e&~*usukPwT<3X|=idh}C%hR?Y79 zyB}7oK_0^p@~LCsgf4Lr(HvP`$I>{Ey7F1*1&m9Li)DSKfe5!L0%Zos1ba#seQZG; zfWv=J4&A)OlesTDmFoB{$0yi+K@x*ErHqq1k zi}fjcJAj^Mv8bx;a)vOO8-9nFB(P0DKJ4&9@6vtLUI80?_2-6>n~|GeYq#V1N8@>jC_$(ek)QnS@JHe@gI z+bz-TY^z*_N5;QHA;p9(K&Y3^GY}swX*ROR8@Z=~E-J_D9292_lM_#RD$cS2+wx7y z(s^F1q2&Z~bq&o=K6_?n4J0yhLuym53@4{ROQI9|z||x*M7Np^#UWcp#Qi2d)r;>O zqkD+8HfcB$pB$#u%N#Pi1C*D&Ae>ENfhL!4KZOZs{u=)lO7}q?6`1jF4!VE(bUcon z5^3*d`y9o*PEWf5+InsK!H$H_>A9>cvp-7*%J{rY4A4Tsxx1-@`haWzy_Bfmfq)be zD1Zm{U4V~bxXv0!EsYGpFZ>ty%Y1Hg`2-%C6+X6XH>R96#=7r`vDmYT#s5MTHRbbU zSy@dWGWo)285ND@o2b*?6vw5V=NnE?cvr=Xc5$sftR|q(4F4iSfP(b{_QE*KDTnZ> zA#&lVm5c-~f=SE#AwG4>{Ox$2sn^1)pVwom4kXZFBYch@*w`y?G;tr5a}q#t z$(W7h9uin<>sAj;GG@7|oJ|15p*I%&!so8e(l#iZwaqX~IW32Y6E+I72e82E4=cRy zI&cSNu?Mw>wk%kCkGaDML&Llj+S=6%DuEc zfacVY_*?N!{G~F&lK`HEmI-&BP_Y4fcAJ(5&@=lfE@E_H{JIvnQ&M7$?1%T~O&#|T z+P7lsDRb_`L73n0vRUS8)b*|$v{LD{6Wfxq!aOvH@ucPUB0ZhG4C>tzRSNaao7%L3{_x;SS_Hc3_i?(66hRP14JXc~Cl~*SoCI zkj1_HeO|!`6ht5Vwzw8jSa-9L!zFHH3Fbj}sf1gv4-RSULv-&+h>b=%A#ZbzT>+@^-?=9jZo~2 zwAWFaf)1v-*~r{8pV{duV!iOQ`SVM?t*j@lA;!k4DZmjJUPH#A9QJTYooIArP6E2@ z(=8>gF-*+jyWlv2YkI#(hf!SB5Kxd#(KY-+n+}2%0!M5g4DB_LxcY_B+HP&#qYl4o zpRvD64jR!-YG!zGy?;lhv@%xQLX9rZl(Qbk-xk3I;m-?w;x89bV)0?C=s0NDB!%#2 z3p!mS3a6F5wQUZ+uNP|pp!B{dS#I5U^QVTVdb;57-mI}5W8Ar*xQQf;LTQ8hrKO+S z$9zpq)z;a32@E$LE#sUUq8+|SBsVXUpdciq$|QVc5-*e96?Qn#?X!?2+HLh1xKHvv zx*~9cfjhwe<_Z{i-CGL^FGgKngSF=gck7H*<%J00BGIhh`zu8FrUU#hwI`FvN9h> zz`~sU$L`sY3)G|f$8}XaOiWBJ4wnfgju@v7Aj#C1@w5g=t0g$h!f!2wH;b%v)5&`c zs^o0e8&}Tij&T;NP+j%l6fOc4^2vGZ?o*%n4--lK85{05$v*~I@wVvkTW!RCU4BQ! zlbTCwHErg!N3Q0>6}=1wq)97`&Zu}6cn!;?C#R&nqPHvjx#3$$sZ)u zCMC}osvaL2;33!%A=r{0(64kT)O~f`U5#AYNs3a%?BNAf_G<^0I8|vJI)Jn#FL6KI zR=QH%n+t2QHA>Sj#oDIgAZ2s5)TfO2Q9IHhCCz$_?>rGG3kD?=f$TQIWInF66RmBHf}I@03G(ByYiN^^ zh<?sO<9d%1TX;)U1t2zoJE2JmHt05&~kAKdj$H#RQy%h3Xh4CuMe7+p#XZ{ywQvxsPUP`Fxk$>WuYE`FbjF40i50V3Ia0YT|(9 zUMmGvy_`6NVN`qzT%8IZ=7fZR!R3G3z<);^QZ4B#<-{g&g4n*S@fp4 z?Tp?>uV0y4c+-W8N!g=*eH-Y<<(+cO?K^fEbJ_j_t6n!F>^xNN-u~du2pqqUZ_t4F z_oex>8p@(Ir_BcZe_n0g*>&CC3NKs8xw5{%`H+0{Z25YZLX|~c>;p?rvBT1$$5g@@ zH3QExqqfWN7UG~%BtC16a9V-BHJy~DSRAQ0f8#QX561Dosn&~E@fYXUc2*|qR4Ei7 z8?~$6CN_nKSxm6*aZkQz{IH;~|601Acd_)fbe*b=or#HkhgOOBh@5iN@)U86_w$Qi zp}RJ@eN8`w5Rv3+)0$+5s7)$iegX-Tk>~`3vPq6JlDr40#aOFg0>_x$LCSuv1HY=K zNL#{qLjk2T*|>0MAR5hM^QLRc=oJ;T<)p9+AVfVkghtk(e{f3JHZ?YN1Bb?_8#h_*7qH<_okpwy zGGeIGoo2#-UB&2MA*1`DV%_Lt%#}p~)@#uGNQ)R)Z>H;$+akw)EK4AXiZLBaUrRR7_m) zSx*_aBX$ozm0>-l-9nys%8e*N5c>sx49H)7oPx0fJhfl-7cYtJ7+#O{JGrm14}O|Z zShn#ZQJeojV7nCCf5DG8?MFygpc;{TPG6?6n-0!c$okt@Z2H7v`OmeI)7LMx9Q%h#5bgfzs_?Q1 z6jBN>G?=Rtn6@>EH5lrQD5yXNoqf#?IYso8WHqNZt-SfHfM0JZpS#%D672e+dZ(z{?*52z$@YM$&pGkR zMC$0u&}3%761|p$=B123zhxe5wHF*tbSAt^m5mE4Ginuy28k1)RXQ$#39{lOX&mCi z{%rS$gaF@K-I4na6B~Qeie+ei#wOXQUUqo|s`;++55==mZY**Nb+@}wM4WIW4^GDT(FRX|BhK#NpIN$f1xypXr*Z5jkz=giZWXx=f zo1jS5+$fe%*gPqpfQaaMOImv1MDIQ7D!~T4kBm3_q?LbRPk(+e_z=HMDMKGMp$N{&|&`#e3r)k>(9kA&I^y#cEpT@Y-?}7ro zC;JEc^}0WmT)XiW@hu*Zw>HvCid$r*>xVHAd?Ee>b_h-FTR41RnWR^M^QU{lQ`KX$ ziq;Gc1MxVq=n_TV4>ni3co7z}xel^`bM6kE$Kh|+j?oyW~qPn>YJ{#kd@W@g=FwjVIJ91ru87w zIS!o?(78A4 zL6%wKOIMJ36fCW>6e%k>*;B0YQW>Qi`bZE&Ehx(}$GwTTaL1d=MGiO=IId z@33bmb6)748=4!eY|;z1W1tnAorDmy$JZ(h2Ku)P5iT1Ac~#OMDG>%lw0pDenpY|a z@J~c#^bYSE*KWu#hc2^Hm>E?Px2ZHVtU5@?cc!~Sn6^Q`Rz%Kt zh-FKpz^|w5;7^6~>tcqOn_m^Y33aQ(latyG_lk15Z`DR0s=^w}%~e zrk(e!fKr+7);4xJH!C#}l+<9~Nl$OXsP^_dSGUKP!HZz4)7VYJdCE0B5P2h_U#zSA z?gSjB#aF+A)?6jBCkp#|84zGd*t0uh)$ zXi#zAA>v^|s`j3pfhCxj+J)v3wkl>ui+`i!;qy6SBSJSTa1EnopHkEt`xn_U=+nU( z?){kbS7iO+6;I_RTwUJKfUH_q??l+uMzrHHB3{D@O0llZ7@=`s?A)i?+w&uQTw3|7 z;hIX!TaS5_+deh&T`gR0J}Oa~&Uogomt&7@UDvTRkZWzd)+(^#Z&JPk)w=agwP7hn zKm=vqg(3-7mfm+XID6Nb#(Z2%z#h@}P1Lz%f05Y0mx#{v2`wWYl?By?b_3p>IuF}2 zC4xuZ(UEnNIxVXSgB~6}@$dwsZ|g1#gF}PZw{miZ{a|0NRxvD@{nk3um~Q_>W7F-h z9I|^`q=X_u%W;rsxkrieMO|`w z6ORg(m?7YLamKyuF-CuU)k@4~Q>vb({MP1x|#b(O`cR%+|3Bg=2p^s!hd zj291C2@~qWXzjLlTnS=UgDWgHeNK?zYJD@zL-^V8R=J>5tG|>!a^Lb6rU(As7n{kl z?|rJK)P=PWy<7}el`E%R`QYFMJbNPhMI-ooz9?hU& z2kx?L$Eg-yGo-|OS1pXvAP-aQFrYwwJ5Eh&{Rmx8uC<4j;He|Jgwd8WJfs@-1{J%I z8tWnYB7FXfz3dJVs=tfkK8q~`^H~euBfdi(>-j-|{a`A^or82Nzjenp_s&Tr<<IMrg%&}2_Ozb(>KtxgMhYci2`eq!*MfJjnD zhpPFOCibkk$NtCK=J7rS<{k%zceVG(Efi#2!)e-2QquWI!w3Uq)%4Zx^NC4gRS%B3 zT6+lUcnD!V`CFzxr9MkXo_kR9#INk2U9O)H4C{T}-+^#IGx#g2GD10q(o7s5O z3G!>vF81$@L}Olc95Hp`IY}+b6GQo=JfFR4_^_1CKGLzV!F_ zLK8d(FzydVr%$k;g{keaPt70PG9KT3Wt=#gf?b4#^zgrpda^3C|LxEwH%h!eZ zd!wzWfsTi_8m{)l#c?fUx;u|#U5$QyJ*d*z?x38Z|Kz)CRBzj~R>NfSoShUjnA$dD zpW#q!D`8qof8e&qnXU6v;$qpBvi&d9S}SL}uZl71T6K~=C49q1pIb=YoK$Pf_w#E| zDNK(gw%QGLO&f#iLzm7_Y`_*myS(ON*+}&Bt!@66x1n+#-2{IwZ z{fR_^ExrGKKYWb6exqz>G0Rf~3zIlP)b6VH2~QEA54JX64w}O7czGD6pm=j&DU-L) z^2Or!!FsadJz1axW6d~gi}o+uwD+Pa?y9wrw@zW$^Wa6mjr?N-ZCXExV3 zbWZ}o5w5J07joF$16PF}iwZt~OE{n2(W;*C#KEIgJkGBz;dBUPTt{zYisuxB@b)eF zQTK6)t&xQxjHWhO%DDX-SMD5*cTBaWNpwPCLT!a!(Y||*%$bb^RfwpL_wMlK6ogVJmfLY~9mEkVcTRL}?WsjRa_PPJQAY$1pPD*`|p z$1Ci+H`G)d+z>#smDrK{fUtN~zIX4V-4K3=ZRZZ5q;Nl$DZzBM8a5bKU#Wt8!%`gm z(g_i`r$CxRY>g3gbdJ@QRcti1PJb~D9IcUv z62UMlMpJ&SOn+YSG0xh5(;;jMS31m|u{o>keqF7M+lm!Z88&84Q*m0iWUi24{9$Zd zm;{>HP%oSW2%V3Jfia<}D6QZfKTWOB`@xS+1rI$IC$p}Sv^yuhBL(D|jiC|a%li8@WTFKKVzeqIfjVXfHm8AV;x1Is2 zL~96ii5@L-+Ykbj8)_0!SK4q=Bu@x`2((+=)G6TJ(GMLO7y)Q_1{|EoD=1ZtlD~Brdz&H@!9Tbvq>1m#NvY zI1%?h=k|ew~>*mVlcervq9!D9!y5)V_2?&i4vKM!ztP zzAoOscm??>$_2gt{wL>issH`CU;lhgxhdw{6^60oxAmYa&5#MnF#JEt%s;lJ%Rf1T zmQ!ltJ9!%U>9RH?KJG9~ed9+0{0ZzT<1gjbsBH;|8H*1*nUfSWUuQV`v26QF&}M;E zx~;C^_$s7ND91Xs4;mO;xt^^Nqd~nBT)O_o9v7)GbjMDSsp36+9wSV_!UZX^)q1V5 zTMcyN4L76N4a^s@TKg|F+@@6vOA`W!t1$WL=OX>QQHTj2k}L(eY4|8{@yUNU%f+V8 z`64;lZ5iij|9WIc_uDM(Kn7#}>q;nL3>}=nO{>k&jXJMO7DR+nVhC9YVLF4zi#pv4 z@AU7bx_@wP8To4)>d zIen(o4fSF6vb7TBZG=I;4vbj}hp#ka4^4W%k%fq!!IinsosD}7539y(n-0>YpN;Qa z+ih0qNlCqmE=9ox(x<{gC`~2TJM$Wnvu<6=6*-Y@@=<1HWOxt}94eF);9;==L|${H z4*rzlAh+P$ut%ghFGLwCv~r@fX{PB4h*qtXv04 z`)J-kv8-0`StCdgMiOAz%<1!sQuo^*>Bhv!hN>E_^tt}2SutDVl*)NP?3%QlKcQxG zlOxoT*Kxe(d{}N*EOfJKzKX0pcyFepQ1n)3OH2c*_qwzVbloqAiT7?ONqo6oi_8~( z8p)q#N;ddsLen`D`ccgeCfh_@E^F2F=GB%W+|*1$_J|VOPML4>YU_BnTTC0uzM;7P zbDVIJh2KO3X$cF;t>~WXWvIeWhh)y>PBky7c-C0RNImqD>0iEJ_VoK~@A{Yu;9?&( zQaK!kwk;Ws3hSKFe?Gz*NgKxQEFU9dTUT;c@7&yElq}r_F=^N_NedKqgmRkN7D$5h z%gR=%DOudr;=jW~FrVAuG=Q`}p1-%{ddR9o!$e9}+ID`8I=Z0qOw7_9S6*7oH4PQJ zeb5THJ#$n+YCcocH)MX%xveoVeE!vU=k-l#!tKK1`7WS84m1jyu8<~-Ux|Hj|62*I znhlk(aqQrKCH0xsQmia?(b)sAJVAMUd@|HXIjoqoE8LJ|(zE&%;VoNt$@I&)nMq1J z?X)Q;R5VTa93Nj<{G2Vk2laGM)}cJ4t=9mp(;jHs0u*$3wCbKitXA@Zo~-L!-CCJ z$h9uon)oPNuz`p>mTj6xSI`^;wqnZMIawDTrcdy2 zc2&&;;av8fKZgs~+G|{R$JYI+3GSQlsN;Y^wbfQ%i_|Q*`uIWWUFDk*+0#DdOe{Jp zY5Uhwl9Uz&>GWb|mD_nZu=7V7A|vcWK!otuZ%1j@-Z3^74hiuKw%mq)-Dk2F+YwGD~U0k<`!gMe2gAh&|my z)RECV&$80?5Y++R)KHy>`B(Fg763JZcG~%S$`u;n>?e8k>lF$D2{xlx-rKSY$ zE8rC-V#5B}S+!2^MYg^C0t+qPs4_9?%S7!KEGx~iNcV%QJ}I=COETc=BMVJg3hcV+`7NvlQC;wnhtPVv zWPAJmFh@lqJ~g};N$o<>=Y=u)#8=1+>-^G1UNdEV@0@Q znT!8AAmoBPhon##JSN(gT%m7bS%6znd*kP;7~6QG{a{r zv>AI`!)m+_8!kCtb~C7Hk4l@F$#8Y?CAF28?H0>rXA1XjZ@EVz_Dn2QTrxNaUnCCl z#mOX;%$X!iSl@cmldya|!a8{-RO_;(?-8{8pq9?i-bjSigEZ2t*PurMPO8Wonq=*0 z`-(aNEVJYXdzSKTY}0n|H#TAhrDRb{onJO|ukZ7%tp`Q~zIwj3G+TKMO|OqN^WsC> zB9B1jrFWzEc{~>3ie>u!s}j1Y&rOq?+$FbTH){B`Q+(n`MEaLzTr@e|b7u<81akmt zA$1JuChdlwiTDJWJFsbZ@!#j&uv4^Uy1<|OK$_Qlu&`Uw0h+c`NsY2kN5kMyS?xm+ zwEjZQ#Vl6GN01iPUnEwEhshrLce}6ViwqIGJzMzs)6+$oMG=zO^++Vu8nMX?{7HuV zV>o{+cNUl`Od*eJ$w0RrZs0qgClO{yn*VP=g%P=#+Yn>y&g>9a{*mCicN6*OUwISw z866?w6*9(?E2kMg9k=h)T*r^YR~v#CkjvA)I**NlhOm#{d#Mhe-KH zM@IYE@ZvDD<7Nlbs4yOh;k^$NY57N%!O?^PWs>*%pAD~_X%W?qEPr}C&Wp4pr zB=76_`nK-nVYOZ;S@4KD)n<{_zsvV?()k$@lqWZL4^89KUg?5w397DhP@L(j@V&j|U8?%leDzdv;B=e(tk4E?ndG+qT0! zmEC{8x?O{=UA(x=?y&Tf9N1XbalC*6%*hfw3l8on+<2w^9=>e1Q1;z#X3jo7sf8mIPygsae4Oo6n%GE8blTnXQ_5_WKO<=fi{BS#rhV zUNM7#)0E?90gJ73j7Rq6)s@;8o#EEZVp7;1fYcdwp2CiIJ5M*)mtJpqI)}is#=Egc z+<6Rk3i8Jih-szEjZMmXMA!T|6QEzL#fJ$V2WcvxS(x^O37V&*PSml}d=&?qvL+@#WF zR&^xA6t)Lk!bs+;*6(BcGSkxLSx)&yPMeHW8qoN*MTQN{bJ773YZe?g7w8gq%lt&* zl(&&`PG)`Gl?NKqZjA&Di0G83^b4~pe|AAug(qNl1FgHrPZ#9zR9q|09!d#`D!dA7AQcET~Y!U*Hj*DloQ+W(XOm%0_}jRnXrqq($lcbLdE>%T@T1DtcE3bXB z{4!9uKZikgZRt_Mz|)~}OYXblc5*JoKRx{!vp%W>U8JwkQ|x`s6#0{B5r78hXYIKY zWCn_nl3Q)TMm*{LR}~jLdKwI^Ws&fK`OF|j{>P&84JA-k-k(#B5OuNziZ;0>J`+j! zf9#cR*tDi=DGB_@4*Ds8SzcaJKtNNhLCD}f78Uu;lDg6l)OIf)iagf5w$8HV{j;5i z+ua7XEK1xol1BY>89uwdU7ucHG2a_!dsca7=?^8D3-HEwMkm2$hyL!tnkq}I2Qgvyht0(K;mtM7RKx`8>qbK<+j-0*QN zz^j7EZQyv60b8nqkO>27`qoImGxprN}ll0lv2m_`(Pm zeQsyPzH>l0){G62_P>iclh%X3(%)|JBq}Iw<`U@{CF{<~3VAh>Z2*%sUp0mf1G zgz^O^dZ24fR*$qG|HjNc#@jNIe&@~8bIqGn5UuYEK(mQb{pAXYtoWJ&33M=wBERMU1-HSNshY?( zGg3CDtu51&bj9xd*(wR_;Z;07G9rTMBK83&)Mci|BK;M)ykoqAKWE$b2=(2qZ&fuA z{?S_6s%lAI12dVEFXO{C>uND@u?=+ynDeY=t>2@K3Ly)x z@8`6tckhi3*{>*ZPHc+xvdDg|$t8Gy^GoQRj(@z8_+0umE#B~yH0gAv2Z@EhJ*gj> z@o{TlAT{V=s*QRvsl1aqV85nA^dg(Pp z;kOALSHA&gNIsdsgh88)EDaaFSoG;ST*R$ABx9K?0UwIEozvycBGSM2N9hP9#rqCb zS5yGruW|e!gYK!ghMIwY4kn#|XGGt<79(P?F@4sno;RS^F%<4gfnyd4nv{EmS3QsJ z`Tl|1xgXzz?JBldd+B<;`<@eC3H>@DEUhCSuy$uSK^n}Jlzbi~bgnL`f2UYUMV!3fAjhad z@I&?1i1+Wqt-lcJ3G;<_jc$5Oo89QWo}H{f8pPfn+frj89h(ie&AW~QBBEcC+<7Oe z8n153HdCK{_*i|o7Qo16i`4^SQs}iVjPHh3zU4Z#;J~*%UP%Z~T~KWae6gW;?8Y}h zEag24b=xTw-@Gbyi)DQVI`Mrbm2K39Ym2r8em5>!EO}<<##mYTl?XWwr*yZyCsEF( zXoWbJ(R;N%>)XP2#zqjSUPo?mjJ@z|4rKnL{q=S913?29cv4T&)f5QC-qI)cr3Q7i zKO2KbQegd7DMf&1%u-!GYotusowbNn1CwEtc$kM^TYNZ8}01pdiPx&5+kJ}j@l0?5J%r^&Ka|_YF=JqUuh9ks%Ndj9* zK^BXUpjD^waRAG4`hqdDkH+&HlnP z7g{o~lbTvBn^6V~+yLP2A9tl7tJs(Y&4V;S#N+VCPt@-*1JBvd^WM+ zbv&ro;hsC8z7!9dles;p_XPzm6M`egtgjd7TnM&M)sp-1!pSal*Zt3gMJv$hh3-7s zbtk$XS9Idq_#9J2MqF|dW;ICDg$*sMSH3iLL!42C-f!~Fjs@eIA_l35E1^3#rboQ z&WZDCiNWm{5y<&0U#e|TsyP*%8ItW>rQ@+??{UT{f9=KR_df3e*1|iUUpaP$Ysy$Q zbbs$0owxuUX&nzl!%F8{cyAbbX`n`Yl;2XHt(hhwr|Z4 zkAwu-;R~~X+u8jN(5a{t75Dw>u9U_Bg=tCfpk@}ha}e)lUhno!f+@MMcbB*~wcxmO zoF*bJ_FHCSl*>;r>Xu9saB~RV2~P0xlH*UrRaa8RH`aI%I!|w8O<*v=w{2u0LgP`9 zb?pbHIk+>X^&5lR8gO&qwy)R&pNPDsVl7{%HHC8+CjlKkWiO>^5x#go^~$d9#+B5$ zjkGUc*4&6M^M-xbZuOTi?xzX=7^S}Q6dhPtoVf3x#O|Nanz~&i*N&36q1uNysX^rF{&Q$ZME_06OKH^dvaa zc6@bphEyYL^A(EC(vh3Kj7Z0?Vf(C$lvTUP)fi#HfUpyRjH24T$M=X1KyOJK)HT}n zuveN|9v7~{#jjmWhnfcmkK~W7jZ6~@er0lO4O&3F9iGl{#*`1Q`Mt^3GIlE3T!8#O zBCv|&vbAwMs|;VBnR_$$HI-EStB64Lt;? z)rPwHkF~=eU)38PlZ$-y?4h}o?VBxVwQJ?d`+!RB0#xV;c-&91Yb*EuhtVjPmbr%r z$SndpQq~j1HK)^H-!A?qeRD<>4576kLIiqTfFBHZQVZ{eYF2B43bl@K5V`fh6om>R zW^hk`{drnd+0UN6$D`LrAWHYMMYhB;Z*=fQ*1q9DIj%FD9(b(<_dq1t3~!Qf49X$1 zLN-G{^q%BLjtS3V`hm~>-+TE7oMeY>26K>Uz;N)y6^Ft@jjaEX(fHI#;hYCt zv(L=c7wnvRoicP0vui6qLHm|g*<_uyz|?_Wd2Q6pH80T$E{DCtACulZRIj8p9Y zbt$r_-$GEJ--`q#8!ZktgA>;jCdmfhNQ_n|sN=1gk7~9%o9;b{*)4d0{{EwGzPGCC z0!hUhIXDrsdqfX4?V54w?FirHvyNL{?WdVS8Hw{#ABxuYX)Z2vf>@uy$|L>nTKuff zrq|V`efc-t1B?jzw)ehhQb%ZzMIQ5>jk(dX`nvR`7j|m5%vAOc>g=&CC*?c<9`G9S zRduE<_c}qcksu`t1fHuj*zZMH!yG_O^FT0USe0e#YYL@Bia&!ZbO2+Fez}gW^oVbJ zsCeJMuo=|x{ufs~-nf%1@y4y%&hggjv#`U0FZ8#%pgvr^n-{8&tmy*LwIQRnUhmGh zJXySZZxmy0f6TsTPv-)vd=7#o!V1YjsHR9fTUu)cJ=Fdh0Ota)6Tt@9hd4uD$Deq7N)$x^^uTx`_iTuAyt ziy*&iz`Y}~ue7rhOD!~eOEUY?cFXGaTHTwCS3?w;Lnlt$)3Q<5+yWp{3q+N3T}j@} z5KpXG#(JZJXNl+`HSv_RPYT)xRmz~U2i~qE{%9N`VN^Q*76tjEku^ui~hdtH|`LcE*shF%PqkltC0|w)-vZeh7uw8u`I}GqMEqQ z!0nE?w=$blTPliu5WY3q7Bs!&jKL^uX^-d`!c$ASgHf7*TT8p#5_?xvydJ0ZC3CZ4f4rJUbesq2&aGxhxXaRh!Al>pmZXq0(p{DOBm@@3?;+!~=rx=jCV!NhsRJ1e5O6~xuUx{$9XBY)m`Zv+`--E&r z9D#9C%j&NRL?!1agh`%%_0R{D_q zZ*FC+EaWHd8*8JU=IAEg+ltN_5@CPfPo^<|44}=dnB!MfCCDwVy!iDe&EyxqSs5VB z4m!@Zg&5`Kq}OfhM?iq-np@Y*7?vC-t$W5qrJwBU+3U?zV7G*L#gr3q7kElC5O}@s zHdI9?%uMWX_N`to>%5t#VKX}DeX5i&XA{GI^2f!EZ%3#=F#Q2mQjK&f-ytIc$IV$e z?nSRJGV%Sl+Xa8zx;R;~h3URY`F#{r%CQ<|wct zc_|cZDTUk3v!MWUWt5GFZF)$9ZSCc`GAYri5D1r9v1^1Br2MPCG_RK)G@QZq;(AB9 z`ERPXTt;q?z6CO8T#)m*%Psi8s<{t6_Qy7l z1jE0VJc`S48Ye33Y4y^)Nj?wUIr9V4HFN{f=2g{okeb@tiz9+uMs{MNOido6-Zyhaxj}YR`N;Jsvx0cVIHNTwV6F|?o|+z znz(LvPrh3<8%Lc0sC5U2uNKE&UUM2;dg=c2$J_J>G3LNLi#`q2sZG>JY3BPF{c0$Z zbPDYBXE_qeY~`kSly-ZYzAK6Sj?vX2#0NMUxVXRF<3@p)xsCsvMrUgQ*ll22Ypf*BSHfrwPFw46+0xBEYZR|88lUr`mq+Z&ZrIi@?~J09`}4N$eh=rTu8Aev9N!;JlV_2f^LPDmyH^G`9_G-k0bk#6mUMY@; z9Q8mCzAaqYcC=*VKSc7%e?~vl1gmfJ6&Jj74B6#L z^7^_*uyA^j<|8LAIPP*x@>zH@)TtxJKuU5lqie2a9Jt^yjlA*p&2@?=ED+jC zKSjJok^G=*f~`k^YNc0^$`UB#Sgccfb+YoFe99U zcr8!Xo2ysJm$e&A<-I0I;OC>}fzPO0Pk{M@<}xzW0Qt)Vax2kuF(r5ynDPGZ>MXj% z@h@e-XzL8){qR)iS*LaVZVn*2(YI4H<&PZ)?*&k;$Tnbdl<**(q+6y={`S^9$>@Ub zi4}VF1;tU)B@e2xApcvnZ;BfhM#uO48C-mL@m3DD(0tg!8>y6a_oCQ}!|lf1=>fs< z$A3O_!*Cj)mwl9WKZ!SVUr~_z@~4r8kiiy$80YJswcfN6;cw$LhVv;MMwnh#B%qgOMn(ijt&5P;)lscU2%HeD2^BB z6!xZleZBiN3O&`EB_+y1@Pz>pyKcVP2gdiQ_|LJNmtP7Fql;pq>fpU9Q%{I=EG5Hn zLn(HkR`K=SvDU@?+3l5!?3Q{Rqhv122gij6%MFJdp_s5uR-v4AOZ>J7d|{w8>uO6m zCIL8zcduYKO7=$Tz;62<>fh0?_2=&-d9saUE+88G6?>^A!)>{h>DnL0Y0T4UFPG|KN-p z%omvA@E2gR9$TTNE}8wf*LsBL*3(#Ek5lh=B%H4QC>@-WF;9Czh0d{SkB){)pIWmI zaa|t!K0`0QpPjr@#i@6v=nlyLoC)781lHn&(tRqh-6w!za+)2mcq}b64C^nV+c^GG zbfKjqHOK<01`*aNfTDhy`vy433wv>&Qzv_gYrp>2(54jSc1buPZ;P#?X76AGAH5^u8B(!>3jJ4HkO zTJM3L5?}RQ+fJpuc)|Z+gK__AX;|TwjJj}&s~)1mX!Z=P3$uBb+3E>RGJNef`Ry$Y zm=mAH_HzR9AJ!)cDn+$NFEwdC-u5h95+CkY&27`nRk$bT`;_Jp?cIt!eeMcuiLO=X zM0w%d@)pUzHF)js-bS`5TRqnNlls(}Ih7XBd!sJ%Y0HPxH#vla2b?JJW$v1c=z9h8 zlt>Vqd8CL)Z#g--w=TSR=Zgx2@d|}#^8ULO1qJ$4+`Ku~g7z|0U2!+8tG<#_^!n|U z!0OuR6}(37i9*k9SnUUdz~2{9{_y2*8&-&V(BdLwsOv))n||945X9KGW2v&kQ$_JH z6h#^2z7cWtkmt zvdNk`R+dj0IZPq7a;ij{ERj3)X#MwwzGY@jd5{qvt~^}&cK-VpbT4u{Yuz}v4c;bK zD5C>1)$;qwoG+>5l^S0S#AZ{iOt3!1W95Vsm(Xu!KsoEp+7vyu!i=5jYwB9#!!>#8 zWak;obg2icWMN9O&z*>OK&U29`>u08`3NfN+FTc*h146KI%`K6V6*M00DTKYDbz$R1q_rUsBjq_&*A;UVN? zlqSKiO?Y?ntOECCm3?>iU%8b-ewfQ6~=w*mQTaUZ?!ype4a zGyPci6=^_-EQ4?z1C5-z=au&e9TI+USDID8{b&}!BQ2o2R2F@!x~Nd2$hY2b&$M#A zC4Dg`8(tHwftR&1fz-eqVQ_m>d|gX({JUQZwCLcFq_}i1Ja|=$cWu(KUyf zccVXg?w;_W2viIMbiO=}x{3X0`ze2Y<%*0h;BT@NF$#G}Sf;B-LLv-}wl~nhW}yw# zE~R+am0pieA8OCO2LPO0nAHlfZnAjE{ZgNywTC^|*WZH)*Mz-P0p?-??@Ha*JbyeF z=wnQgAM(2R{_fLBcSr5uUu>ditYYpoQd07DcY<~hm)P7-3IGR2r{G~pPE0YVOVr%0 zYk$gMZ|^rvWp$kEr5ueNkQ993)8|5eSeP`1N7rC@wejb#;a0k^2YWmVi7}V2VSOQ# z-qev^Vv}{>kHgq34N`);qg@H~Cab!&cZ^l-Ld;Da8E4C{GpEp}C-P^C5FfB@+0rE= zS1;$ToS#aWa}RvAvCn`PbT1hIhC0ul8llN-YaZaxLQeTlWVNxKf7vc5pX;zV7cj(U zwL+z#+N9=acj(|X8AS`ZJ_jSo3>n*FDpu4V-Vw*BskQD3JlM0=si4Y1AzRolo+c_^ zEE3@-J%NRHe&-Y^R%}lj#|WE(5`}TRutzyMR3$Ij3t@bvL}zV2SJ~oOz|or4R63=I zaZ>KN#DT`O0+LUdnlNO;HnaqYsHj9sE&j#$4@JEnNrFCb1Ehl^Sdl){sHY#Olo1s+ zlM$f!4)LL5@pD3y3}~_O;xeF_JjG@FYcktj~zt<8(Q9Rs$zNFX;j?7#G)+m4|LK6$F|uB6+!TO*!{> zOVo46VXt@fmC}bgjfA*5K5$58mS2U`AO)j!jeWd2)kVVEKF8&0k6T}S`vC%m(!UyG z$ndUh=dZ=gdCE!$J)eAsHNoS^+q!`-%$O5I=P;}%y8uU4PF|T*HHPg8%t9av)I+bM z>d;x!lt}^;V8A72RNkxJw$$ugB>`842 zg0_jF@b70vGjA7)`=%#S6>_qKhme}@KHu=jcvL)qRjN>x7TwdEREByV)(;Q21i?4Q zIFVM~Whv;H9qe&@;fuHy{XUvLhTs%wz@KglkW4xtUfG!9=`mjQRLySg0kj@8lM>e} z6Sbe2#Ah!}8yyNeYGIh=kmAc{T>zLeov%*Q0LJrGxg(m3+KIr^?zjnQeNDi*_=_}rEw+bMz)@xC%SE=j9u`3g8$s zS#VeXEriQ`X@``=L<8RwThAp24tVZuDZShwklYOi{*6D>aD&eb%mJZI!vfn6a#+XL z=NrIO9A0MVzCv*49OG0J|I?}y;8CoLFyDs0mB+3Y><62|mI9vl-6ZNm{5H<}0lFgn8vCh{2#RJt zPg5d&tgMdtQqDi`;%BT+YmCA)*=Jbb-=-~XDsien~(6|D{bljXK)ecy!UT*%vYfui6d_Q$lv8Hi{~ z9x*x9G5acChaCu~hiz1yF@|?Kib!QQK0k27yfsht073c|!s3L?Q#;2qLt6+wp#uD| z|NTzDxW+&rVr4K>ES*FmVU(jQ>PT)7`i<6>9s?$E{}_(G+4Z~f?D4yqR|R8@dLN$>NG z_nVh94!En|ogu-CZt}h;guj5Rzu2vJ^8f4hegdwXAb^)&RmlgPUxBve7<7n-18%*w z+U8|%X6HNFHIucJ!OK7PP=<$H_SFp8t{fVmHuEB7R_+9N02>9D>z9WgPX6~R%+&&9 zs>$i$VoZl18enP<(_$d9Af2KS$w|bNeUu2+;xBW4ahAMRMmdGUaXZ|Jz7ZXLTj4>~ zp#C&EJ%pb>^gD^l|L-2?sJ_XS+;!fll8RVd z7;Ils`}9<{o-&|nwHn(MQJ62#y zk#$r5=gvXgeALA6`}-?}q8&+;$L`}VBO|UvMY6ba{18V1Kiet#c}GXa%`DG+TB(ZI zEc`mFpdj<0>I`b}BI2Ya?u5f8OVEl`2wUFcx`mMUe+CZH_5q;3P9#|K(YsY_A~_*K z@R^*j{f~qNR)I^q#oh*G@w2ar{?DTZw%;jl_tUmXTz_h(`-Gq0(?%og;Ge7tVD^Vp zF?p=pEr1mxus$*N5Pb#tKi~HNHKDcq|Gi*i!bJmm|NBw3*aBUkq!ScYh7|oHCoFJ! zW;Y!BMm3l+&3vp0D;+*8`)Pr0FXCG6Rby3h0-u-gPI^_xZ%D!b~|M3&7o1)yNV>oSA zra|H&y<=M*kKVnpeJc|IN`H3jPoirhuua#cPYEM0r%uQvYqpYwG9Weuh^@yRwwY-a zB8-!sn6Zosf}TW!9(zZUO3U#wxXpe562zcE+*3wmr!YrAXkbz|?T`OkGU1eb?5-;P zmqr0>x01dH^kN35Uk``>Bo4@Lrz|3#!DIofIw*B_-mea<7b z!c%sw^crsJ%*y$~GVTlSTZ61q)p0w~UL9_pCIi+5yQ9wxh!s(mln}vgLU4+dYwAZ5 zwy4hOPR~z9i3MvigaIVr7Iz2#AL8CKs;TX77X?&`R6!|H0)l`_6Oi77t)L=cqlh$- zq7tHF=m{vrtyHB(q=^bhZ;5mTr3DGnAwWb*AfZD7gmz|N@BjP0eZQd5-dFj)N?sDfksF5@hP6EtsQse`PAIIR_Uex z$NA=u$K)aebx>wQGY(}v>=}7phM4m%kA9RQ+W^-eQ^Wh|^YxRV^#STMI0Xu`QaXi4PQ2SZ>jUAfKg*0Tu2< zXWO2fI@oMdWel6mnAAGc>^Ow?Dn%rJ3=G z#H0E+kxj)Ly4dF4!Pj(m;)@qQlqK#lB z^=l*kxfzRw9J6QfBhvh`G?zM4Nc;WiDa_J0lpS!ck07;zeeAL*zG+z^t9%>~YM=#c z+tG(U)^QQc9bR}6W|G0xIxgNf@C6hhHzxU;WYC!rej8l;Sldm?w=E!|gfrspCORbh zDNk=Qr#n;0JN&B~*tiAlgQlNTGIBKo6#2|9R*DxH>CXwCgf2o)Q}XLOzTGY@;#Tl# z7<#IE3qUHR2tgY`ajpH!1#&z^@f+TWcJ>(`U0Rmys=Yt%A9^py-6>QM z9x%7lBxO7o_Jv;>H!C8w0n?o%Bpg&v549j&YWUn=I}dNgss?6+J!logT6148NOliZ znzPmDerD+u+rxod_S`llD0>)UdJ3`>ES50|7Z05K#adTB`X}QQzHiuVeq;N@CVv<- zO1wy7lYiVhr5mvzl7Eh5;}o3$b*>sNp?FTEM&B>P)%`?`Ke*60sQ0P41gs}M!=O9_ z+>h+R2S{Pz2S1pU0>}jk>Jer?m}+apOY#06MA%s9Iu^?Sms;+1xq|M*89aGyZG7xN z<3PR%0eM82PEGD%XB=x6ssr0eEE|O(BL;9MnhX`NEM5)F4@(&Gb9BJt3?6*+Gie+@ z*57QRsdeTWmG5@6T*S}Oh+j_vEd+(NZR-LRGe4we3bM1hpo;jwmr|t9C#+}b(Z%Y@AUSj6~?6cLz>c-pJWd&1R7X> z5|fzp7^ymUtml#t(nd%Rc2Jgk2+xY$(pcG~JU&ur}SkmFhfV(pou zz5Ya*#~R?0pH=yUgg^n6XOa_Frwe`~hnuNklpbM+a@nJvh1-Gh*9n$&OE0iY>iZjk zsC5QYcV9PbDSjhXu8&JUuY)Djg;X**IOzxXJw7@a^`d}K6j$nuh@_14kN1PRJ_89( z0}8h2eaY0H2t_mbBwSI=^5s2zIo(P8+i$Qpi0W+);=D!o(v`wT07W2&AHxMc9f=0M z-7c-j()xJdz;l|DV_m3)k2R&~n>Qb&8>pz66?SA^$iI8Cow z!$tS%OA8gS;T*2l-@`N<*Z1q$b1Hm*pBUUpxO@i_Y~gvfZtCqrWt?!lZKO*oLCDp^jz|lqB5tuDiaZf-MF6yipO}W=4Q3--^i;0$Du%- zNV1#2Z2)!b7rs5F^+4La^HL_w{pay`7dS9#+v@w6|p+!;u2*A+S-Ua2uc-31(jQjJ)^B5&gj;DI2JS}RdgdB{+-h>J z1?}AGzgtwzd7Qz5?ceX^<9Q#@c#Ma?U0k(nx9j{J9qZXUpYS-A&?#@%qF>R#FqB4} z!?hBZYP=a3KJ6#o1JI-abxsG=h!-R^L7s)4OxbQzLo)lHH{0)@*~^K0F#D66hj3gy zrMAzUoGtIpdwl(1w=)#g>)~ZdU%S`Gj5Z2L(3=EC0f*-kZ z(xU`})g?i~wE5-6g7aLg2!pPL;Ld)l4-l}j?pzXd32F2k(r(iV3+(;{HIQvKi_V-S z_WQv#>W0!k2LY*G&H*qS^iGwaH|RZ3m_~6X)u7WG_xo9J@lWtQAZ=SDyN1Tb8X(#H z*;Kqg;u<&Wh3pl6Kr{d*yJdS_XV4ON%4V?WXHT_rZ)C5WP8zhLyRS<$@tNzqMxmzH z5}>LBSRjrQ-ikElWTodqTc+x*mv74+UflAo(_^zh#5x}U!MH<0Z;_GtHA`)_VrLvo zs>^ki#r)u#NE-Ef8>adDi#NAFMPIS6ci8|v(l>}nYhZRf+-Z^9Zhbl60|)d)kK*J5 z*#v=}ABJkSJEA_rujBK!6O{Y%ZQ|nP=l0UrB`VUYmy041`Su02F}WR%<@#5y?|`;? z*7zCdDs*jf^3W4MJe+3Jq0Lf$RoSx3(xDJq1_SwzjqS{#^!zsIPQwZ={jEn}0)Dk1 z+ZtHAqThrwsV)Bcdcu1%gOf@1Q6~b50M|UJcd%qjtH2yjBqw>_pB^KZ%z9s-Y|KrR zQAeUfxPL7-@Dl6^7j23%Q3Q3%80Pb8e|3vr)=LuQhM)%@^LY1tf@Z;D<}h2fM^)S0 zpth)zc$`{GoMQ+23Oa)F6Jq302g~+IQRhc;P<)#@PU?G}w!ApH&M(SBh$*E^ZOaLy z9;hmS$moNdS8y&#zHdRP>aSIx^SV$5?7eT!CYDHxgH|>jIaa&*a*6R3C-Ys2(ENVX z9i+o+fvo`wy8XQxE%pRI(p|I!UOLfCf0hP&}u{g z)V3|!IDgx4=mU0kZD@1=iB_yDs)N;SDLdcC#4WgdO5YX{R>u=T->vypzYoo?MZ2%0 zYB{mFslR{ZzD`72{}TkBvej3*rB~t{Z6?bdBCd^3{UDkeKWi{tLSXN$_r!Cyl83j?7*7WdazhKe?B zu=Muos4kF*hiDl)pw1Z+$neKV-l2%w*~4~D+1As3I_qv`B(w+&?ip<$CiSj_=B2TC z)C_ z>mVN_{ODS3i8pCO4K`ZS{)IJw>wD9W=*nFVhOarX#UxIcuhA1S*_J@-djy1$28y5b;Q0+24dM;qC+Lj^hQ3oEE2V!Kbnj@P zAB0&C%9)1y%L%4vLgUeNjJ_#t9 z%L+tKZg@{uSvzcN9%FBK<;v4Un;F!)3ypQT-n0ocpgm_-7@h1PD+B({(EfCnfWWyO zs>t6_?DU;*4j*|=Dt=*dA(OkZvzA^Z3td5UWQB)-Z7J9Z^nolCcARmSu=LYz;!}ck zvLxY(taw?n>R*3{L6G|LD(EQU0VT*3tMEG$(Yo~1f#2Wzv*DK)Gta+Lz>JIU(iTsC z>h>KhS=&4eS^hpmHcC|i3Lpsy>F3c@X zV%>HOkfv3+Km*_m zXTb#3imh~Kk$YEZ>lWV}(T5>^fBIfj+6QT^-x$SD4B_7s)k8Uij zj_ZPCA4Y~-C&Wb@;ar}bJSnN!QaX`8zo*>4ATcH0ZS%QZ>>xwNw->i_!T}ILKQn-~ z$QVP{Z%J=kc@lQ?A{n-l%IS|^6b}Vya~b}6(}tQz5td_M24!5{JHP}uG{bFbm& zN@+8o^Rh~6f5ITB3WgE)+p{AKOQjQ3s#v z1zu^$-=pn#L*%%|6|aVY29G3p89a%ce`0KNP-zDmxKvi&EIx{L<>lf4H_`~i-{5DA z=3;i&W1e+wZK&h`ZIw2QWt4499K%^QK1r3s{idP0xuAVB7w3~#+BcY-DGMU}-W3$gGZUHqntbk9T2xX`=OHQk+nE|`*= zd^?eiRl9e*UwsHw*bj?Kyx;xyrKw+T$={)G>PGa$+k1XFU6f&HKf3p9IHL9ts;^%E z9icMlpBR4aWzum{GkeQVjh=bveK>1YuG%-Fm+R{r3Xx@Ree1?!Ws| z>4;6@;Z=}B`tbr&LyIrX`x7=kxC{4c70>W>mOd}QNg;O7o_E^hi{u!ak{!U0G|&C5 z!uAod^QW-Px@B?$+LdXk%HV||s7>JBmu*gk`@CLMv^B0uyP15dZ1aQJ2Bxwdqniak z^H}XWHaa4=?3SyVk|{;^N#2ty*Q$dhsAx>BJg{DZ{ZMVypq0$+t9u?S&^H=-JUAQ6 zwMxlojT4%f36T}zh{qfBMntvpazhn*7W!pQTv04|qq7}bP$pXwaWFKMRI=GZjq-l* z6$K3_oal3c9Bn$#aI^Rnfv6L7woG2>&*(;nk92)=v@Ug^-C3+tSIAh%T*yklkIwpK zu=pJX3v_-GFsQdV%Ljl$ho_gCt~QxB{fd!y*3oDa$v!WwnCMI2({S=(CI@s=2@)68t?k$%~{% z$H(k!T?1|eN$0c+)dP`c%1f5OI(Ma)-x%rU(+>+HREE;ZX{W$8*f11?X$g2YG} zXPx!C&G$Qx@VqC4D~taX_606D{g-Q5?W8wjUfUD3A zb)b#+aY-D6FUzUd2Wm+b9|>AD4*JXB@4DAsS31t>61My_gh9ddhpSA=FZYr5taF4)AA*xpp1 zQIuR9ye<+bx$a8y@SJd<+JrH5Nqu;OwRD!H@>`0m zzct3~*5}tPG>#;>m<9}Hr_=o2wRHtA=9hIm_<2;WYSOyl{76U98Ng?CxuoQ~HsbRF zhoqL-(L*#DIstbVrT&N!SShf_G0>GFD0nShh0}f%^7g1r#e-YEAa$l;FLuIr=?}dh zEd}FV!TXg)c?4`sCcS_Kjtd_U0`ODn-LbfEv-I`vGH-(07Km5fA~$oB&d#}{BgtS4 zuN*LZ{PSGD)R^Nn1KE4qPhA1J^Pc0sLpT{eVBlhci?7@|6bc0CH+s28m>Jp?z*V4< zlT8{?ZKNt~Mmr@o+#q#z;SYq556m-INv`?CHAk6hcf z*H9OTzQTpidS)Xa%tIw^SGsgdE$!gnygXE8`smOt>QGcJUzbYmFEVdSKyT10AYJ-{Q<9Jk zljWj$2)iD%I*j`cG{6}gM{AcdUlL*5iHlbaPf2`>@sJ!#3BAmF`;yX0r=(C@BpRd` z%kDafJ9WG1t)QgZhtN>l<+V#8r`TkHO%Y1!ug!sGy~Hi(>kK1uteT0tP`qcgeBdUYVAh}k z;b}{r8z_+!Qaojq2-o5QPB9+J^G`%P0YqKw`t$9FsO#w>lAODRU;ez3IvS6>1KgN$ z{au9F4o&LB&V5kGT>*yDxX3Fqx5Tnh;*6<_SZ#@Y0)Fr)<&3!884xIBlVqcp^J&wX z<5~*Pep^>XaW(<+czY|-7UP*}349gson~YTV+O%|Xa=*i#bHQ*jo}LzbD(iO67Y?Z zVi&U7ZM1_T78pfm9M@A_+G4*b$4QgA^XBXHQZocLC-W?7OQC+|Q_5}ZGLV3xrA*%} zUIUW!Z-)e=g7j5yz6myeE{l5har4q(m)hq0ql5O(FSGSel(k331)DNy*t#95wYx>* z3Fxzv8Hp~5rCxHFaF_{+d>vhzTATf>AU}@5q7QEqS`~9Jh?ijqm9DkJOS_~bvwK+y z1Jo4v2+Gapn{GE*HC-Ub8{8np|GpmGO3$&EN{)Xb)zdpJ^)16gad*he`P=hDD4SO< zHxciueqCviSygkcuZf!h6cU1?a@`KmswF6ZHg~oPoNnpMz~rr^y%AGVD>FAzsE;9r zpp`)hi`wCL2HJp9mEAzZS-lV4F6i{S*_z+KVlHIYZ5Z$|ScpR2P5=wdzvNopEE?}H zyUX6ZdC{XXeNOrtDxP?N%f^*%()Gf1WD!@of~z`{m2_5tkEhK;myPJLi*VT1ORVLz zZROBM9Rs=Pnq1T`4+Q1NQU>w6^RYJ1lml)UI#-en42?Js0OtX#32iDT!*;G_Y1-YLG*w+mqd6&Wx8#$BMiFgw2mgO@Rsi1$kSv6vi0q zCjsrp*JKOxP{|tbtbTRgD;lyAnGU0%hSPfOXyIx<5NnZ6p1}OvUyy(mEUCHS%ukEr z5>Gqwrq)mK{KJfygN6OUoh%3!kbw!!jz2}v-<&PWRZHY#b)Jj<^(ZcbhvD#j#xOKdUPdign4u zXgREw=nFHPcn?0zMfiSJ{w}$Ghx~zSCM5psNN}-3bFOf$&J_zcv9u>`r%-UvXnD^e zyoYIDJItDtPdL()gu}@}{#r?jc_B(px|fKfL+(rfSkIC<*Y|}P!SC&#MgBKGP2YLtRK-U6DgAqCo7eV|?6PT7RG<+b!(b`f@ zyl43%=k>IMq23641M8{2X&oeJq;%8A3fO+guJAiQ-lp`+oKM=~h74L7>f6{)%~kT6 zwdSk(eae_sq?r7c75GtN8@n=eTyiY&pnXZ_rAyPRW86U+Wy55bNbN(RrBR{KAs-5FRv@?WZ?}1>mSZ%zgrv(r42Is zluuD-sO(+X4a>>c`NzvSe4vAHMr^7*s`0cxw;sVkl*ml1tJL1+a#*8}GX zo)R#JJ~cf0M-wwRO+nr|(geqW<72KZP3JsHXu98zSBgp-Hau_eH%jRaqmy&ErIvg0 z9^(V1_w=}ImLO<9Sgy>G*L*o%0CtKmB>EN~qth^mua+k_SecqwX9pL*0{d$w8!H^O zt-oDmp3hOx>?s`J_ad+lT5gAI%1DIdX~&E-uSxPRvK81i=-FC%pfjMD#cyuv&_fLI z#Q&U>fuQU>xbsm{!@-MgT-4=R0PBFuG6fcW2{roxX&nkroi6jbm(!^rZ+No)2}skr z?$Xrw=4oY=P|We+1nDTxs~J6hBaS-;e{W$ph(EOeLe2GGk3@i%fi!EtcK9SmytqZ;eI;3J zK&oaAE9+T4P`$N>E80uS-G{{mdWLcDY&?o`{6rZfRNXhKFj3-z-kA3ugddM}-)<%L z`S+tuz6#8Ryykki<*gQ4ijcL1y;$nP`8mJ7?~uJDtKTuRJ&Z=`Zw%|`cQIP}iySB3 zs)m&m=lx20s_lhUrATi^#=LmEeMiaj*IAW0Fu8?RX%-5U700G>A$}0>sqfha@v65Q zU9Xx8tY^M@47fTAo_w>YxWdsurCFivUE18+Wj*GSa-A1Vi6w&1gCBie7mBBs?Hqdl zx!e0%sU3%XJ!qY5{{elj5Wsh(e9zRJBR2_2|Qi#@?{xOVBMd$ z6*QT`oyM+ey7_5;UzUhxdj(VnPBqH#dq0Mf)WuNn%5f3)*9gI((V~&jS)_MOAc#X+ znQX4}aj9}1NltawcZ+eWs$E*{-o_SU#*;;F_(WT45`#cG&iWAT1kvoYlBf=l*8gH> zYGCB6hTjHN|JUDmz;9Om#^x_G-YUpl2g+IC44TXaT5~i5sRG%Sm*EgP^F$6XPn;E$ z>4D}sP)O=E&3$h3)l=zdVaKP6j1QJ-HyT<#X^<eB@^zru{6i||b+T@YJv~64jlL4qd1p^m+o3)k4{$)W@si_2qpko?;%Cfv-&-O)w7TyuMkS`ngR{6l-R zlH%|DKt;!JbD9pJ41knwWyZr*GUKxJF-6ymtG4XT^i$#<2YL0r%lZP0Jr^)a4kSKp zNjNAd>T2wgC__l%&<3^&DP_1ohW?jxL9TM4!*x~m>;BzkqisF-$2F%pSgVEHPN}bm z)ZElQJ{f(^ZT2G-%VvzQ<+}vhpw_25ue^A2!9{IoGF{hQ&v@N?eK`(y5|~aWUkpN@ zP$t&z3cXIxn_YKpXnpSG+zA??I(yZ;wA0J>oIjQWqb*-r*N=snMJ~;r@p{Lc02-eq z3Oo9-&rXW~F>oUvkMwZ~%UR1Ckc@kVpIuqsZ_>o`kND5{^96qJtc9OXsFzn)|9ziu z`xJ$r`R;3U(}80?)t}^xD(bn51MBT#Z+;#PA71Kua+pe)BWs9#Y_F*ep;+5%OXu3E!s_*3zz61>b8 zLz>>6_~&sk2x{^U)a+1-%Thk#}FyP2BkB&q%gs4L9Fy9FlyI=*tJBzq($3e}eGyO-p8!zJIFK>!1C8##@Opa$zE0wHt3kszisSo~G+tD}e4+4N6W$U;B?XRX=peV3us`k*3-G36Q zs_i9C5}oovVjC+SJS|}v^}(0$ ztYBr0Q{Ro=Gdltgg|lGQ+c|YE{6UK^3HpQnVuFSw(}N>CudvMxAeFil%NQvoY~LE8 z8X9^#Sxgjb-?*-ygbJ5Pi#g57CQa6lY9E312D6RjWt#;<{ z5h}3L-mtUOXZAGtCTY1@K^|8?En+tR@18gv&-)76Uc(uJpZzPvxDgSogi2_cJx?br z{PW{RavkyTBjsi{0BY?(rI#C>Gpqt^h*yo;-YBa>hvIEm=nrBKdjH%59ut!a zTZh!68@yj53Bc;;SQaoUVBTPNKvzmK^8fiC7` zmxLK(5Rp(-PUphy`!bvco%VRpSst*IwobWpFqCp%2K<}S=e^M+1pqFxYPaLnorJ+~ zf8o+pxU6bkZ4M0J4Y^og< z7wSaEdM7{JIpsilO$!ue7TW7F0xHY7@;3&j_}kbx<2_6!LoRSGcno|vpAc@Pm(fk} zMiHc&SfX4=(Fvl}wYNjGtJ4D^?9)&6w?)`#a>92>bwl0`>H1<_3V3RbQ0Q?>Qk`BX zh5S(`KwA@BLg&ka@CE<=>NgAv#f@B7=sO!C3vPnA4zqhs*O?h407BpCR0(3psZ14? zxhI@x)#+u4xAIp1nv<(${iIXv5^;2D6Dy=xVHnE)614 zbC^9fU54;NAW_@)+iw7o9&KuBY5kCWwaO`4y^XOZPld z_ngbh8!=F@Ndsz^Dj*4UWpsv{mRPj1Se7_mHu05aOz~JSk{>jt_9Ni6+|4?W*@RqR zuZ^7Ooy6yirPrS9C%h%QO-?SkoDt@ssoA2_OG=-jVA+e?)Mi024%7GkAC1eobpLnb za`4{mS(bw}WZ$y9u{c7ZN_NA_t)g{Joe=2dsp0zbslh<*)ezuRuJ>blNm3TPrUpXZ zQ@>SkI^$knfn721D|c#ra}s3%LXEhFVjso2?ePphtI~bSYd{8~+C-_##^mwfR(4(0 ziMY~x!qxfUECw=nvB1T&$b9o-CThVg5>lj7VqreuJ=IH0A|^~Wf8x`>2<|9Y2DjDy z=+WJ~4aA_2b;u2@LpU8IaKv2{6(3MXpr9Z*E?#o3 zm*SmTM0bu|{J*g+58i(hTl9+*__a2I+gU=rQHkS53bxsbiu|u8UmkJ>vzlUb;2c0g zeJ%i@9hbB7O}If0c9~R0A*~#NqUy{`EN*W21L7kC0Ep9w-Q0xLKjVYh3udKq5FGaH2(_!_NHs2Kyi|DhC zjTWs%%He=8HvyE}L>qy36J{KnU1Svag!}IwGtsby8vwvwV2U}^r4hW`6H8-#vf9LV zUdq_~HQ;2!RzJMr%;D(0PYO*wMt21wc!KTCQ4GS>WN3Il8@A~Ij`pH@!^dxBzk70d z;LBs@_0AW1@isD2g7Fk92L#+TmDnu!PqUao>CA-ur)~dBFS(gk_6#Ynr~PA@-oXX& zJf^LDM~|AY*pPR_>A~e197+=Z!nV)mQb)^cWSDTC*oC)s^$Jy%h+Vn$s=~uwX zqQB8WU-g_XQ>mAF6@NtN=!cDyiy`DbOdqX~ zQh&KJzrF4Xp>qPBT`>M>RQ z)ZHGd&sVfXc#d!Ea%y3BXW`s}?RxX`rpyC|>`Dcx zLsY1w_%IhIW=My&6=PiPg*~Pi6&@o=m;qMFI@%mT0}y*gCG?hV3# z9qX%}`sNM=iI+jI5fv<7yb#DMt3n#Pf4N1SC$$Q2=QS4Ty&d#+hL3M{+;Z@n>6$(J z=L%u{E+xeWs|RHqdwHXGgXoYZy1OiZ0}k^qcQ@})X0b`^a8srq{`d%U%WScL%&Jvg zMRF!7w6FhL<2PL3lnQ%T$i?RMFO|z}XUP34fD?JGb|rP;VB%e3OscWB-i&6Sz}{&+ zxL~Q86$VxS5^!Da9xm#~aR;q8l0X-Y;ON8cZ}270hx_fv0}T?5I_mdOS=_7(`J=Y_ zW?LqdW9+}{mL?`1JFURx-_3gkQ8tpe@*1%YMQK|DwY|CK4mtK!f!20Aq^#a*XB&CO zv2Al34c|%{4Wf5*B!FPlo5iAdD@n0Acu_sC=#ExCmje>*zv{eZxrUq#q%?fAZhlD` zS*XYOPv|>*=Bi(zkOqkgH)FOoZ}ev2Y}_{}q%Fmd@WgfJAN*WXdU3@O(Myk=d;;y@ zy|>_BoP#1}7k>U!CveF9=zwU)%m$XOJV0rK6cPIB=aDe7})ma zZy8a5b(0)?EhGH-Yda5{>hgkWfX`^F4qw*2UCUGF_~F}v^wyd~zP+AKzPkD6iLlGCZLyj1y3u0O* zZ*7tkQLks0q*)k+oXS8-J3+LXnxBQK7X@vT$x6*TeFJ16!ROmPJsoGX>-jm^Fvoe2 z%W>)X^q%FtZG~bq-Pb3tu#QIZ-=J$fx91)-A^W!rAS^5_wKV5V>y4_>0SHT8|4uK| z*be_C@>xYaZfou1xKlk|lOKo8oa@@i-gZc&OrqSu}5XV)c& zz8>Lk`6}AJ6m8Z^l1VGd9)YuW6r#FM^yzx0D6bOi81R&E^_tAO;*yNTt&J55aN^$% zoO|eyhg=c}dMrQoTLF3Y(mjFa{*U{yu}*2irR~31LOp4$u=yk7ri!D&w9Y-l5@qe%J^jjF^<_=09ICXksw^Eqo=S z;H+Inxt-L|kGFQiRL)yNZ9@scO$se9xZdZ>o$02{*EfIt1iho?l7r;FW+oC-$lxMN z*4lltGE#xaS#f$@uVObo%zrcLC8hECrwc^C9L;Nak((!0sw3ePzwUAfSxlY5I&q|g z7$ZzTtc~;n(=z+otz~Sl{?53*C0*}8G2dM^?{(OvI9LH+#vHRW9h(KWUD27tEaw>H zmYQG5=l7uJj#snxL{!_Wwx`Ia7bt{_&vbRm#5tSm>F&1I46V4WxZG}8o7*Pc8(+V) zA%HuF)p_VJarVs0UAUS6Pv4{)X@rRr)AmGSv`2bgd@DyZpwfS=WRn=9;Z}FaFCkb- zfUD|)p`qw_R>wTa9}K*0?YQWI$#YRhSt>zK8^>Q6@u&c}W3N86Sk5&^eBR++NLH}O zPyP6)QQ?6;P-sxOLRJmsZ(A9ZDVBrfheEWx+bf4VLp??(N$38izjjImljq?7EM zOKXE{nZZAEu|Pf}SF*Y-mcLi$IaI=ELZL6fQsfbM@veGxz#<0Zxt5J(ls#Icx2a3* zX9OW|{(%7k3d9V|UCKGYG1;NLkdG?^ZmZP_27%Q})$Gm&j=R6sj1PFlEYO_m{oUS+ z2}9Tw3am!exD{%+I1%}^OY$-53Aj3=zE&29lzP{e*ZA*_N>JMlsp^aE^)9f9wYm4k}>#2?N zLcD^OJ0o;1H)B$RZW{;IlD4L6XkWLgWu{>JSEqWSzn*!IJ5K3w*7 z;lN>Bs@Y*%=Sc)$P456w=!GiR{azc+9D(fl#A zC%dVUPz+(N!kL0!q9!|u@I6e~O)W)?qlZPPsq6$UN1uVPpTMiSiBv@{%v1E%kz0M# zX>IW3FuO=m{SJ+GV5FIsLra*i_6zyK0nB~b{+covZ^O^|6FtuHo(p_Dq_bx8;^jPN zD^t$;B#niGjk1rQhq}c-E^L028!<*Mg9+$ujZTsV3F)5XCHW@x(d|tCbS$zaEGlTL znS+&8ND?D@NcI@kS2%xe{#&v5%mPPV>>?lL9PD zcfS$JHRGZropp>~3(MFI=+7=h)2{H6 zK{Dso?Y8!LMF1f|ICnq!us?|X=p*DA8*Xcz3daAU!QWR0D}#&4S26anKiJu8#TVz0 z=X0Cic3m(U7Q=cx%u0mSCn?n2tzK<7?Nfufs+eYqKXlUrHa{SX86nSgUo5a~mPD(l z_nnS@El(WEnDiB{Df|L^M|O|f?yGX%tPruImX;TI2iBNS33$@2#~!NiRrVDe4M%J^#W9dv=BS z6mkmsTo-hRY7M+f!RRSpfkqK;ZRx73Ax+;oLmvimx}y+NRSS2%>oI&495|F=KTLV= zl%~+{eMY{}9xPpfW; z5O`-_uje`uBX*%u?E(JJp_g6$UIN!kYL}i%+ph|W9)RXy)P2q#okTZBd@NMEExN?? ztM8%qR^i)W>of9-KFH|{nK5}WFZ&=^uasFIIU{`01X?S-PIh_y z!2T_;U6P9Ax{s=amuzF}?7db*_s7xawcpDXTatrFoZ!v->3^!wY7)bKj-+tuBjPnzG+($bUy%K29EqX$g=il4bb@O&rQ91M1Z~CamK@Bgk~wE;k>ONOJbVy%IVjG9X}lVO&C_+fx3wHE5qvj zZf9_~qA$8&W->#e?!wL2wQF=n_?tB`1?3_!-84Hqp<+N`!K?q>G$GGdf#mzcSpZB; zJU?!!@NA3FXI$L^Y`YKETfbR~kP40on7?!C=apeA;wauuOQr%cMAfh?;f6jbvMs{) z`&FVvcE!rKulA#l!{VsF`r$v}>6Hw@B_;bWcB2mc#r`s#6mPn~{|=%bbki59{`;w2 ze^PwU`S-&Y*1sa**YuMf8F_vg3zzy01e-eWNcB_9q15U_&(MI?81#kf0CYqVWNGz# zq(W^^N=b=-e?Jd)gL`%mZ2_JkVal+ZaYEe>jk<4Z&Rzmc)au$wOf`Hf3Nd4NQjF*_ zMZGqJ?mCq6QXmrPF{6U2kz07NT}b&}9d>!{r=5s5G)BM@EW8m<@t&JWB(F;L>N^{i z8(q%hUxxfSIiH|=VSHd#|MfVfBPh3KeW-K$3GuVy!`;B@nCdpcCPtA97c<;hzY?IfbQ zS1O=pLp##VPXh7E$>?BA&t_Z!&4K+spkgWBdZ;$$=^B$D_d9?!Snmm~8$c zQrOw?e%yENXVE8+0D0T)x;eSs^-IKSE^Sr%eqR~$alk9ec zHK0Ed?!F6b$_NXqtmYO5DK(Wg{dc^s@;-6$Q%eI=e1dU|?l?4<`WzY~VyiK|IfK?? zW&M?OC?rOI$Ct8!3qt0`J|Z$1jtiJpHpdSsSOg9#=xk}!Ixa@2$Xk&k;nQb7vLA)o z&OHB#jbzM(EWq7=^D4TR7trKOKT@X@xUz=5YkfT)I(t~vd|lf{+^N|97@<-x7%{iB zTx0HkEob}z-g&!nW8h|eg+0u{(|&IKda4$Z=E7>9R;PACUeaDFNulpb(J|fK6Nszs zDOL7GT7=tmo(ozKT1P}j{Y&C?kC-(5C5juO8`dpfA)!A1x-V-kk{D5eYqp6Y-|pLp zB3juBUm-s1fA@V!dFkA7{N2p~Yg)tc5OCFak;k`B7=`KR*dJj9{VWIq7Lw2DN z$Y-s9$Q#ldwh)M^T0CMGQxXB{AzNwsdtS za9}~ap3jmqCby*Yl2dkb;vtg{`#wKo{hPwLJ%45&~5EE0m+ejK=ucziwUC=l%bn8oqz zPM9P@?2IKnD^p#Jr{gip*fp0J!61;_byW}6DRveOtqS@_!1G@}FssgMtKlw@SqL*S z_*;RWV@Tl5_t?(5;_rPkb{65m#KXd5$EG(N_`~{19MR z#R&2$@Nog#O*#Up!92@kp*UZR9`>`$Pw<3Pd2@t7ZA2&21?`LdK0*rO z->(rR#+1i0K;RDeRIu~cz2`!9^C`S<5jIz{(W!YmJSZ(=L?{Ozf9NF^=?NU{)WZJ9 z(B(s7jxF$~aHnRuSSz_RW}X_k%ayFz2g zaSNx-r_qTnfV(N`em*no8UMi{EpBG$wz3bG*8lb(wt0984I5A8Pgx-+t=_O^4>WP3=dE8L zkN5OCy=MuI3+`m96_iRt*c&!zZB^f#)Binb8j}(hdV8()!LA=u!$*;4!JXC`$?R;p zB3pFzot8<@_=(gkJNk+7e>|x|2|Hluf-vRb%Y0Tjtn`6gm8+PHj;J>(PE-$BX4R?)%m1!$_ZMp7G=~@Hm zRefM4?N1Q0a(-o!2q_rV9U*42uNYS-1`$7!25WEhvMG)?3b@8N)vtcfCH*31Zz2}} zoCDE4J1E1(x=^6E+XcYHKXKh!W;e5`_Br-wwSkhLogbu{-a%GYP`zxA^%FPmAS?Z; zYYVC9@n58{#zqo3K<2Zs{)4&7JGz@Q!g<2_+a3V$ybd30TtV3TPObFzD_+HZ0qIaH zqfLi=P1c10I!TB3i0(;0f)~HP*h@7l5{#+DDEUsFOa?5i|_xqqlS%4IzRq)IU6J;1Pm_zHq z?M{Nbn#`Vu$vNya#q}Dkjo9k0?jq3sGm47pObvYS0Uztyt>&1U+4BK8TD!N{Pv~xK zTEM@Nf~Jh%c1gR-Pbgh{3yJ;!?Hv0k@ENyD%_WV-=-ME*m%;FM5%U66#=Cy(8GKRo=Xk+YQ`v|r;*5#OanXg;Jzfq*}<6MgCGHwS(YM%Ar$A>K(2UID-c z$~c@{eL#S1>v+1C2G?=3$sS+`0ZCioYoG-4HR#_V+6BLvigC+E9YnQ6y@aw7c#@Lf0=2m-S)=#NIT=gZsU=dr63r`ud7a(`?K! zTaDyR(*`vyRdT5JiuTTN2c^5@KS?R3^(QNjDCiYC*sWImSt#4CC>;4TcGJuac*kXuRuqRs z!+sibqGB2jWgV%eF^NiDjDytS}a8`&){v@6EU_!iV3pUJ;I_PuXcRKUW;1rRAqz<_<$VZcJ4ueW&f-AK$uqKT7 zY><27)&err*{1lpS#=+6rIOBgvpBI%S=NU<8k$O~yN;OrSY$;s*STH0xEw}$j;Q+s z+3hHA?*&npEQswB5}6&p3L|`u?DUv#-`rjR+A!N%pgA;a5X&e^@vO?#i}~YM(J~UU zADhZ>u}OiI^2gKV2TVwT0QVgR>qYk&@&Coxd&ecY{{Q2&?c_Rjj+(o1TJCbEVp>^Q z+IHYb$((3vZUH-*)iI%^R<5i}&4H$Z6UtIbat{<#GE!7TGX)g{e-~Eg{dqq=-^cI! zw7^?DAo*lK=rp8bV+k$_Q<6)Vb}=yX@Tm`36?PTa#1Yoon|V>4gN znD2tjoS=zIL$$f8i;@iybkjPclKke|DvxoBt>mhluB*S%^FsCI^xl{0Jk*t&f>6GN z`t)C2DMtfRNxTX95jkACEFnQ)CMpFUTfHv;+j6t@_qdUtd-4Za z*+8-Z)#X9L`94*!gYSS)er_-Kwy6(bKnF+x9aw0yhDoF+T-kcZf%~!cW22J3ufNa_JaMY6ajm@qL8SlLr-! z_kRa^d=uy}#s%~Fflvcil6HED444sbX2f+%g-+)+4dNnW*yo7I$iB~Se@=8w42Vi} zUnH+hP=$nVg@ft){`N$pynB&YDp9`|S19($g^254lDFfo9{JHyLotU}_eC*qXqT7> z(R`<7kJoLrGSSj-2#S4SBHy>Tqm@5ae*10q46?{Y0~%2`^R%6;~aMnx5lr~B* zRl;A++)8T$7dXFJJ62*dw09gW^=ZxWqLGr2e@i zd;l9!tGZ_8ja1A6g_I!I6XdU}8_w2#v2ac;p^ms9#oY*jbO5iq(Ft+l7m$zIx~I1+ zw=FM1Q-pmaF}i}y#Sikj;K6lTK&4d=6309QXz5;{Cpwu8h!8AqR8_upUF4a)3tfh( zJW7iF$~2f=$uwGji$Kpuc;{RiC*$cTJV_*&e*%xNRH&BV}uTW6v(e=fXABHP?k#x2aViRM%SomRR}Ib|2$>Zj`Rms}{W^3WR(a_VPx5I-^@kKy2Fk*vEkL@cdj0sE^w-Wq>AMVK!xrDhrlR_Vw{Cu zY&~T(_;9VWLRRZ=NhyB35zsJKMkNGdc=^LYaOk084}wje`~%fjx(bKl7H$ChmWDn1 z=VbaZ6HB)RMR%pIUzCIY&t{4D&(dw;N^uw~GeTSVs7%HCzn=@l4{=gu1f>InEd~MY>akp6ifSnnB zXsAaEam!&UyndDIu2>~{IK2(LNeQrt{m*Z$wwQeYXg@vR${I075M^|^z_cVW3?te;% z$brCX!ZW2M#IWSOV7WQNI+Sg$y>t%BJ=X&k$#aZtk>CZL2Wl}fLYx*onm&d7bBlC? zc$rJA=#BdZ%7r*-X=%j(*8%UIxc0wy>C^^|T^4Yqh&2sGVK;oN%Pk!D_%n;?ClV*p zTNYUs^VJi;D5oT?w&@QD% z`jo$1J$g@XqrC!7WNDmQhSnk|!E`fM_NG#p*;0~+hvd4A>+hAHwRF7c+4TnDrz$b! zX4$7PMi~oJ2Hn_=-z@9wGvaYUTm4SNI{doxWlIXO&X47e`6^ry^hN8?tu^RvQzewa z+xZ@;8v;>v>w?OXc`*gb{@E(!W0|qYhpVmR$u5LOWGW|JiySozF;r!;={yjQ8<%*h zAJe_1ZMz{sT>n?RWe(!7f&RFwi#+AxxNiYrGv7*UBJHSa-spydyI;@P5RDkVck|@T z>{{DZ9%fCHIa5#BD|Dm@-iAJL{mFD;M6<66B0DO7TP|B^SBau*35}rey}wMf^+7c} z3=PB3#UXD6%uv0ey~sQOW^osW9ifZ&Bw?|+`W=t74VQC)%kVz<@EOVJ?XaLj-8#Zf zou1|ByWV8_V07*qkjYbY8=uirze6G$K5}`qbxr3$S>bnCd+Q?{>@*!RSus>~F&oZdg=LrNLc)R7N2r2oa?MgOhv z$3&UpcEeGv)MIl-Sr91sJb<0!2dK14tL>WbYJH5 zwO_1{zdA;2{9Xgh?uKaEprMcg;8_y2a6w|ELH=(ag|ziCuLBh?F9wHQ{qtS<$)~B4 z4?e6-HlHw5l(qZ2qAy4-NkR5y#Kd1YujZdq2XF81eQZ;=dzD)N^_sLI^FE%klWA03 zj*za9gy@32CQs@g{mc7RFON(;P10BI7Rp!0x2KvP_7~iLI8b(Gukv8`j;3l}aVG(< z*DI8N3{3eTkixYITV`vU_4i~Xo~u4MZPor_81~%7T_<8gFV+Z()^km(ejcbT1>}u0 zHCby6k?*Uf@=}Yj+q|uanj6`>UO=703t9sN2-oO*UQ9*P0h)+*7wxBWHHS z>7GkHVP&yHc+ZfHikA0&&UkE7>a8eD<*l)7YF(GWH};41v93S0_&&k5jbJp!wT}(P z=xKKAYV`VY$Bl$EV%aG-Y-+i$>#7{5+#r!u3*L>T*;=6T9R35#rFkVkuKjBR$zyec zY^T#{16OFRElvS*gqHQ!1b$@QYAa5RXWr@tRnE6)iQiULIQm=OVjfxp6?Ze+;Id_( zWS#!qbjOL`;W`4kpr=1i$3U&HC+vuC%ze|}*r54aG@F?Xw6>ycYZ@jks<}Y(w6^4w zX)5G1$aU=hvCfwRLSmZ*?rrZ*{U;mz7iITuY<+nh1}9B=&!&(h4wKIB)alB~3iDp` zu0&_=#}tIXcg*Cxv2)lQkkKH{5zF7#KnyFcQ!VV8P~Ep@C%8Dc%a8BXOuQ<* z^7iSv2({$}av>`#ri4!?3F#An+#bvY;t1!(nhvkTw!Ju2^wP`(3oT+jC=I%BaUN*d zpCufj6ZWk1DMVo__}ix%^PbvpXw$eVpg{o6{sit-Nw%7B%%%sB`JD#C>4H!-2t5E10Qb|q6K zJ~=>2qj*thRcQ-gn)yV?6_t@O1`Du<>l0KrYYQHWl@-9}*B5iudDZCM_F3JZf`+q! z&bjGEVe0Q|to+j}&(H^d`q-`n_yHH|V!nZJ^5rPfRv7zvjat54hH*#I`uN;g8W|YGf`q{~he@3*fVv0SzTcMog8F++DAYgYY$!!K9 z1_(&>D*P;sH&J(f?i-0K&Dl{`!x|Qfa!%Md)oyMt@(T34^^*CN0^5I{SGu&*NF|S2621 zo-usikR&{w{s7VS?PUb?zWU)Jji*lSrlU>G8H2+A+-bLzgo6eyFDw)7I-4G_TYXMv zZ`AjXyA7ByKAH65aQquXMM*!)4{1R4O8f|A0hWD#-am=YE@_<<4Bpr*(Vg>lsnuGm zkXY!4ua63V!z9fVy;9dCInlLrKMn{L=F@|+(;S?$Wvm)ditP_+2enwADza%MPUbm6 zQ`Dm2(3a8XPOKAfMS&LFnV`|-CiTiQrc&p)`5InKPIS`9`>0l^X+}x5CW}t*?%SQv z50d7wwTXc$tnBWN*!mN&6FBNXESdS5o+pI<+5GS>ky>}BPaN+-ufzhRlW!|wu1$Oz zF&*fVElo;{SCsv)!Iip6qIMec#N~6_d_kJ`@cW%rk2bhJ`0Ryux%r##CBscmUq>t* zPya`7yvo;0o_8QR!a=3^y%27m9Cw=ka3Hw9bI4cWoa9lnqM6qdUQw4TyN`0vY~EB< zR!>^OKc;9EPNoWuDL1#*`#MVJV$gx}8ENNC?Rt%x9luI9boFFabj)*4Q`tT|cX}?% zz3T+dAu}i?ARF)1+k0iPp5^sk%%bXEm9tn56&z^cr}CpfZ3G%=>BA|<`w41)B?2_n zWbtcPAHUTp>3`qyBZ12PemyS50cYEgc)Q|Lh*Fx2MCkR$l@T@CcrE$Ui3h8k>98^8 z$=Bu>CmW^8licuQb|t{_qt+krb$kihv2*3$2g{hq`m8yjV3rgMfEsf?CGD(7IjdMjU!U@{sHb zt=KDn<%+w^^(>9XI9<#k@?ze73ofeuCG){Cd>$G)8m6hMvqOG*dn~Aw8_cqWvtZjO zm!3_miD_Tc;5DuKQ+`Z$KV@CQW6K=>+O^Uj*P+R-{(57+%3X4ve-z2d`i=E1OE>gQ z_wsgKKQYg{a=Nz@y!LH(PmMHZ9^*gbbd9{I*Fq+nQaX5*+?d7a2cflR7!~GP9vOIp ztt3l#jbQh|)U^p(tn3r~ZUOfR#(sN$R_lcW>H&M%x2l2Acp;%~L@P{T{&8FE(Q;C& znn3QW7|vxoXr7<*G%^0a7JeWF^dJc(b;21`ovWF9)}w&@fb>q&)h{n2g|+JsM}f8B z0X!)?lB7(wsXqy-%akfpX?CM{kcm z0{+~!rCkH>g>o2*&BRzgH!FBYDa4Kk;4DT5pvJDn4BKA%9-HQ4e|NgX@HZs1nDpUz zt@Cy9x&_cs(YivSo6@Z79yGDuTz%49$L7NY2Umlbfxdi|R*GVSc-gP%2AM2Ao#C{V#zBIWHY|U@(VlG%N0I{J9H*enT0el=s zP->knT&@hmw-9&HQb`~ax05X8F*pK*udAqaqXt~Um>8g$FP2a9ykuBnNHlCUf8qm6S&-{t%i0RdWQD8lB&Y6^q1W@&W?7O05a`I;;=`YD!9}dwTEzA?vsPXk=EGfy;#iSeMPFcN=t6C*874#e{^@Q5VXvkirdzlvtF~mAhqxqNcUL^$ zh@7`O4(bY-kM?>;Q@?E8$ZTyM z2!3#P{94!*2H|-AZceY|z5=w|z(ke3YHnt-KhVH3u^&W!{Kz3(%g${HJ7|5{TuCPT zrtZxV!=~T~|MKR} zR`;9zpU+Vy56V9#4*S4jKyF{2?iydC)k(g~DY32Vyt_lBnbe zjmh?Ay7T|uH0r%nGa9K>&JH)oNdgN)D&v|IU zqA9YA$wd8|&iIE93gC+tZPrB}g9SYzqR!2-`M3_sL!ObZrK82o^Lvl^Cxn&1zMMg8 zxQukEFT>Rx{qpEoqyn89o0%(UdV}l0c|JC0HBiW9Wxa9j)@At5pVX`|Z!^|;%4ID+ z|Ck$cBF7CgbSR%Z5i+IVZyyjJhz4cse}s2Dp7jn7yO&5+M}x7rUFPYKh)3A{c75+O z$N>jPVIO7Bu%9pyrQzbC*r?vz7-zXgVK72f|HbvQ65D92Q>+f^zxkM&u1v)j(L3*I z54H3>y?(MF*@JY=?8zZauWLq{%V5X`$A^W4t&)}4L(ip)BXTWl9jnkUO%EtdfBbHC z62m%S@_zCO<3;iHKwFwB{ob7;dk<3x23Zctp_&H`YqSvlvj%rlq5Xv7Pg$YY;obnq zJ$rCe|MP*|ZyF`@pHI$ftn)K*#;O)ldRv2#Y*=zF?~6qZI_<35lC+JCHOCz!6z4g; z(ke#a5xsL7?U&x$ce}rO3ZAm9X|Rd(hpHZwNi`tTFL6M1*zLahKB=kE>+$P#YjA55 z%E|jiW}0`-o$;;ek}L^`(To7zS@blE=7M3n0Q-704^uRb@(3t@3#0QcyIEN}N)GMhodD1}MINWfvtf|az1`m_mJ->LKzW5vS1UpntN;|+^bzWptyZLLWl<%2h@ zSa&8=@7RgIl{UV+|J3X0L5XrNLV*8zA_so=!1-(>qf7K*As`BEG4(h!*G$Kh1aPrf zTfsfND@ZFiTpTT_evrhrUE~S{SZr2zgvTx|-Yyls~pW?SrUm8i;Q* zHe@3X<)kw3L$q-UFD6jD?A=)>H|j1dL?3}v{$)62D6)|M)Yj2uNTz$PyoCJ`%70~h zr*3)`%aDE8O;LT;{nl>V-46*Cr?iGKsxU?i&|rFmCl%~CeVdy$HTe%5MmV_Mdb6rQ zQ&cp;A$))nA@!(Pm>*waygqqmLNWgD9KIPR4K*|vYl1EbFjqf0`ZQp_$ebUFiYB|6 z+5P>w3QfZv7w}q*1j_RWjdH5X=f3_(%Y66uId3y5=AHw)T{JqP=Nw&o!^1mlZlt76 zhj9C*(cgEY&mzSjO6=Yn81PhUPt&P#U^v-W)0KmgDs6S9qVL7EpZuFRy5rUZgkp`p z8tf#o(NV4OP6S3vNw(EWUMDo@<3Wiop3&bGsfLCVX{E&qsV&WSn151|5sy)VKtuKJ z5PodZ%;PKl$?fG{k`)10H_-5GJgxPSr2|pQ$E>uc9;d@_8H}1i;0VUi! z-SCf($if3Sulnb@4x<4uI(Qr>f6GULPU%hKUoxX|b@txQc5wWST36@tCjS~#tGuEp z;&;@zt^1Qfp%3HLB%QxLp<2hi!*nuYlSJ{71rqGsWcgLyyviFk;6=6nd{GBAaRw(> z$H6awISGwc8d%BR zAMkF~R8|L1Uib-H4ry&T1She1h@@3Hf%HGw8UKBene?nMz+bhjI05lmm2<-mVE&CJ zEOi49YOnH;#KaChTXhx|S<$>?oW3D%wqjGbxw^~z&!MtXCmfcZ(J>t^->?c|>0Y?@ zw5lv>;hmbD>L!qTL}9b*Cj~TtyvDn%*wXz0=_+hCqJM}!mKjuLb}$e&+zD)t+;1MK z8S1T{ub)2E%L3gBnp_rK0iibO$iH9QQE!nN+#0aFV8X~(JT z(o?VC$k7&9jQ(h7>zZxQ-gnOxesgxx`*xcw_(#%9wD2cdadX3kzHJ|?9l1)2r>%|npd|EKI|L#@{u zt3m3>gkxh3D-tFSAvQqXyj}^gj|QYb_Q?-98pGL>Wfx@@uaWSUA1Hg)B{V_L+0)CV zv9z8tQ=ka$qe|WXpUeD3c7Ps zU-iovydZo7O-lS$=FI7hxk_$0MOS`BkC22w+%%6LK6L)a!VP9)@5MD%0xYS1Z#%d4 zl05AS7k2QP@L6Czx0kP%EIyowD}NL&QR;$CdRUJ~w%2U;Ir|=A7othmz0M?i<@f45KGV?@X67eQOa{g&$+0TJ6D3z}5De;R{)H{1%ndcgVg~}{pkL4NpY5i`hXjGxq=}54Qo!OV zQ?I|U(4A*-;if6#Z4ZE;BG}Rrwj)0-cgWIMoL(U-{pzj%tm>erDtkdq@$xLEX-dZI`5&_7UHh#OcXrf3P z{m=XYyr|KsTjx|m7A)|S!;jR|-W4ibiGnc6P5cvK>}aV+i9YE=EneGFdVYVmAK_4f zAmY{|RQ3B&GnfNX{Oz!8|3Z=5z5`Ul9=yE+)N>&>^cmBOBq$4ZFJ`o16+Tr~?!{YE zIt@(*?Wt)^1M#FPSMt!rKde&&B?4y?#I{|K&pxwnKrQ#n?pHvy%5bA$DM}pQRR8am zD$0fr_FR5@RPw5)?DK86g63;y=Nz}Zd+u`Sr5C>P48{EgLeH_B!Lci=DmwIlaOB-C zPCV70%qEsizp}S{R7mnSyWp$l%IKA0FsO|Tp<~cFYDPu!ZTw!II|YFBE0l2#^v!Kp zm(Tg+u|*b~8w#Bd{rIS|QU-F>%<jBMq(_6F5DdIb(->5t@%*4EM+0h@W9BECfGP z(viwuip1Fpa&jJamHjiqpAN1I@fvM9m%{U9+i3Uw!*SiI-fi-+IF$C%k-D9Ayriu< znz`6v1d84q?YAsF zn+Z-P;E*idz@1^1KKhr>)wo(4O4WJ3c}afaqPr!YFu>cag}#ShB=RE5I7(>-4?~jH zCnT-4(!1IfBAh2~J6Do@ugbtKUTV1 zYf2q6NZ8j=x>sJ7k3u$ghmSm*(4}GVZR&SspR&#Y4$H;)3wVoOB|(W7H<#t)`>7HO z0&Y6F`9r3TDeznL20dt2S4vjbYF_~0QTL0>KsY*SB71oj?ItWo^V)P}mF$%ql-!lP z(UTP##-6Aqct1!BtR!=K6=fA=h#^?Nrf=l;vaM-aJ7<{s55M0%P3bX(t3;pND+{Yc zD1LFId#b0v1@8?j*ZJcE=%LJ4MR(3R=7xQ34p6eE;<3Fs!cqh(19L{%TVRAbP_`Zs z92n;A#n!4w_990MGIk@7fd`=#gU+dK&$DH!zcbAMaS;NMpFUr%b6!{O>Lo`DeA3W` zrlmXN*P(SlW(UA}K(QW_+un>uKKlLL9!XoWBkO6hYM~e0Xv}QfY-;sN^H+9QjDmPj zgOrlb);@$O8qn4O-fJb*6}Q6(hZP*h{|`*eANbO=;mc`?KytEkN*7OrtfAk7SFI^W-bONCK zo+~Q=H)Y#jS1MeWunjV~zxiKugmwwc8wt?`Hge$Lu~MEBQwA>miwFd_HjwQe$zFUs z@wF>W5xd(czG`(;#bRfdclmW!|Ne5keFL!{)s~$(eU3m_T$p=tC(1ICw^%9!mEhwD z4T!S!uS?T^lVC%168*Y9;|z9wnq+Qsm6SM0$+~f;O!%O7ozgZBib_IDd+_V*#D|cp z%D?&u0OZ|ms?>D_(=jU7HcoUf%SJD=a{7SItS5z=Xgu*QMaE@6WhZMUl^QjJ0 zw-|)@JkSFG{)C>`etf@0v~oCuw%SS{1I)QVnr2;eeL13c7hqa?rGV4w@R#$OAvMQ! z(-NW;WqEsRyLp$9ChFa_>o!VU7nK0e)ej(>Xa?)B%q5Aa6Ts33C9cDEPe#DJ=>ckV z2P`=dCiV>jA4e=_9pIgKeB8du!=^tMzncv%lT$C`1mRE|DymqTQ;PyWp<+5hN^5`R zNdZLWN<2Y((I%#=ZJB*0Jcr}^Ax*4K@0hv{Db|nI-!QpU2A9}K{vq@NIeO*bsvLCn zEmYx5V@Oo_{u>;AZ&SGD019- zF*OxCCGBrQN0C7Wy!CBRM16YU zMJb1jtN!hEaih{1MVOV6H$%~aBp}U+#hYZ05Z!pHP^<^a<1j+aCa(e8(&>(*w;h2RjY35j#TGt(%<`_JsCziI(lBU@(u5VW`s<^MZ^aBGV`lq%6bz)F`p18Dp zG7PIlVxO!;mpWv&P7<`kgc~-@8dex1MNetyg{;fM_n@RK6i$4q6=UmgX5Os&FZ z8nZ!8G#JIo>~W14ys$D*`ls=&V6G>`Gs}5^B6FY?Ql4~BUWdkC>kqi9gWKOeWp@Gh zPOhW3Z2Nqb1)}dE5z#cGHyU@f|Fu9lBEww+yfIxAC})+c2kzQpT>OV@Rte8)F(&U? z3`XUFug#&DN0mfb#A&VqfxE*ypXg-LQthjD?vm=}=+k3v0H50Z#gu`)desH&e52YY zv@8XkX+(Y4)RrQ|+3cj|3=5&Uy0RNXk8=QOf?Si})s}u?gx^DGaWxxocgRl&M7B+z z+MBrrsA@Qjqq7aAxX!B}my|97`P9!YR7CX$12oJDBKnbUKl2s9udjkF*qW;{%}LwUp3Gs56-HbMET}5(&&MY zYSz7*+80dDS0m><+vlR`j%kP+`U`1eG_+e@Jg*bkB zE?zR_toIJba-_BS151QzpaH*Uj8c)=XqY>ko9OpZ6deHTr(rX41*300Bo-CnPe}2) zQve!Qq4uWZH5e{B`{q__d{45gSNKO>8?|k-4sXe-Nyl!^lT09o)!1X)&hrWmI^d_b z=zIgK$o#suE?cRx}uV@j|*GP|^U`JFqFZtBezwk`DkFKun<>?U+f59Fn%9aBLlfq4`yTfb?Q$2ed`l8pRI(Bnr_UR2$`_- zQ?*L@`{Qi@X&g?u9kHu5zH)$Ah6Dn3t@L|=N>+8xbvi{0#1TCJzN>x>kMiyRDEe5p z#&`m(6g30u%Da+up3CpgO~Ogkk59lSn7;c>DtUm%Yxfc{c9^xd9w(Tf4ZmAiP_wd zYaOV^114SG85No;NyNFTv+iM}0mkYso@oSvnaZx^q^H~TM5rbkWh;2>~lC=u>3K5>G*3q3ItNrwhs_*9{K^m<$5>Y{s*;lJi9Pt6X3P^ zUQLrBg$Vp^rQ(sDZTgp#x|<_pOF9X${j+x~Z7ll)vpZHP{|Q(RnXblTu7{)VdCqy3 zT2=Gs{fL%b^UUL0;V!;7V76j&VwNbRkEsT?#%1COtw zDzw?|Yt_Xid#ExG*tSza&oFT1fBWvyd&6;jXW5sP~8eeyp1DDqj!wA@DM12a- zt-5h?YW11%8-a|PPJWE@oM079&|8fS@!E+2H9>ZPcWRmqD4(#{f)qF_L&cj* ztFeG@fGG4ft#0Udjq`PSrEP7M+rNWQ>~ZeE?gVP5jDqBC6&3?v}K$W_=5)uw& zA(mAq7_kFhC%whl;bRCh^-r#M#~V}K5@_p=O*L3k1&t4ps!!Y%oSpFYF4Uts*D5ic z{DH>QUY79tCKHY~2IFvie7l}lPo>5#t@2K%sq57J!rl8)^4PY*i_Y%8lVSB3QcD3| z!-x^BT42GMD#!9DKIx%eBbcr*Q#q4rwIm!W0!kO4GsSr)FPAe zLThcpo3irWxYMMyZ~N9At2^D1^v84gBSd8#w-EVQRL;ZNm^~KTdynee=l2#1OGo;o zbzpQ4cExh=0NAivIFD>K1l&QvGlUz_@?0d`SIid7KkdFqCr^l)9f+N#Hb+^ov{NNI zuPW?IlKD^AieLyLk;{fY>DL14GZu{0Bix=W)O4d#<`8+)Z0>|1f^eG^6L^OYjFHC< zK&$m;!=g1ImxKV#9Bj7px*Fsf085X_kDj3(c`>sIGq4Vy_WZ3~(K$+aSgtU|?fesq zFcyDU-es!8MyR&$%MsZb^kS++lfmE4LhB6SCv%Y%4TjXA=iWfbDrF1lqhxk+dh86EQc zd<{o>hk!cYHA`lFz+mBb3mwRNG4)wSZb6eVfy5JXnPfc4JvfuFjdz61ct6uK`xeup z@_a6%-3u&Yc2gN2lD(%4sD`N~xrXD)ERo??+6y=b@hRClz`F=a#of2yTtkHRhZED9 z@(TxCp!`qRlsw$vSrxE$ZC5`G#1SA#&i>&1xmuILG`V3dmfT;(zJ8XTl|4F@Y~ zfP7pqfLXQv{Wg1fF&oF@@m`S@l1TZY8MWoI6#y2RpND=WVl6La_n`Uq%LUP&uWz_7 z23}9E0I#j-c>iC`0SB?tFtHIF`)d2&HPD54Xg+|WsafXrQPZx&&-nCpknX4LiGH!$aS+w%L*j#H%4%ODD3{EN`db;s>?|O0b09I(hZaw zYH`H0yX$k%8Bl@?cM?>z)W-dr<$^$9zfY?!xi7QPzM}wHxgvz)ez*7L3jEq(db=36 z{sYqmd2_K({<@>_!fpFlt8!v4$}M)L(e!hdZYfBW>g}xHalVM9YyahPUeXY!R!rjr zz&NhR3DD7aEo8X~Ur3+B-klZUessbLxAG^f3>FNKRMb_&peL4H!Nt)c4oOHj{*7?U z<(Lnr8y_S_D_uJFk;&DQtE;GrSC`a1?*E_ zx6k%m=&jM|EMAJ78R*H{Z0_9@*dx*mk)C{wM^zwThb6zunJm|cv>QXh=!PS$#oJc@ zS^gp8S~8<%nWy}h;YAT+>O+IG66?t5U!Bx<+F4!JnQb%&R|~%yH?)l_)#MpH4JlQC zpM8a(Ye&tdGh7J4Dp&=7b;oDJm$ZMpK*ZxDzz{hBVqBV1_QEK6D8CM<1>?|a6Uk@X z`H9O_qEc3-O(VQNZ34-<3* zif0ka$y+HV5x}g8if|#PJ@k=veD)Ruo)@z!&(VqEM9oS{So6m3qNWcEnHz)MW6r^Y z{)kN{6?7U|h2LRxe5UXdDfq=5eoaFQ%L8pf7vanCoSUjodbU{q74%%~xmOd=fvdvx zsxXvkC{}A`I)X4#Me23(vsW%OmfNSQHa*&X@W{2+FUnDiG#v!i4ZL_jWuc6BOg$JlM(@6yKM2kux>xs&9VOQu5hirU3X9>^6ntea!T7pQL_3#wd6c^j6 z;9R0;*#k>Jb#iVmRoh%X7K&D>;FcE$4mz-OiLK9E+!2}6)75hLq!sZM_gvSS9nHdS5=49jHZmL;EHo_EGE<>^)F2?J`t4<_on2|_BZcs!Sz07`%f9_LmtL{#Z0bhk8+>JK#Zwnd@@u_cptJYTO^t&)(DHyX<%CeoXmL zp7Qb_&4=y@6G}Z%%cHmg6*m3TAIg}_^tS`)O`S?!TNsW4$EKNE%q!MC z7WarDOs9f>_Ls8UaNkV)B+h;CCF?SyhFke;pj03CYz& zRnM3@DP-#wD68JxIq-N<8)Z*@;C4h(N2pm=VQyJZNd2i`7-Oc(Q0qIvhHPJ%8S0GF z5}1&VW!3;fDv=kIv3pP_bt}0QPmgxT3%^wN>@tGlU7}At8DOjlvKbF6VI4UhtFquS z_L@Ku0ZBu9a_hKqbY`#3pd8DAUV!A9XxG2|Qs-xWkJo`AtHnr5mE54z$w z$pUT^V}$eFq&s|KscH5VC$>oE>fVVlQ!c#DXhKYgKJ zqPoM0?AU-VAUS;oP0U^tkd|XsvawHt$Ku+X+Gqs`hT+QA3Dy}!v~|(jBe83kg2i-& z!7G!=cW_BT-JFQp2kP3aAo0v?OQC>2;v5iBkl~0+%ZccIk4jCgltf@F z-->WiOVExpEx4!+ej?Buz(chq=v?BYpSK@6YCv!ve6=@R6p_ zw`85vV%A9vf!v7lr85;KT*!vLk6YA%1dU`nsg#s>C*`GZqMcVLFc361MQ)d z`D8eg`5D9}jR)hQfNO)-K*&eo9M0_9fG~hSkPxxuK{I)B1Y8ky-0G z*kcQ~2nI5u9=&8V&q&yuX^V*OsP338=hXePRD~zafcN+slin42!d>2#6`H{qsQz4m ztC<|(S1T?vTyPp1jeb3?y|;DVv@#WK0`t}|Sa$l|Bd!Yq#D&a@@l`hs;M zO!I(SwCcXWp?lo*Q;WC8Qol1DD=R6KIb^IVjbA{U=ta1Cu}$Ow zSlLhM<}tE9kla9AOO675QV#AgXNN%OV5$bSvFuaI?`^}!$ZzM9nUl;*BiyYpd6ov1 z2WFSaxK|_9Ho*NMyB2?(Ol&hD`DCK9U?#bcr^P2hK?AKM>^SGnn{}CQ>!{W@T|Z+` z09PaLqP8h(?daq^Obun_22sOi20p6fg*h5u!E*7L6c8a{5Vx6mBYRW?AUja~yP%h6 zbT~>t8;Tfl%N|NBAr;VgB{LtANvR&5YGGzeL1(9wLzC{LW$idY@Q>jdbYJ{2&qD14 zq$IJ%4=9uX&_bcSTjZfxQg61{NGe}7^7HlFDb?=Ny06R1!+l{9Vu6NB$HW}OuT8WO5pO`2;#91WDz%vRtMz++W&3H+)eT zGfQcnLl(P0hiD3Ep$G?OQkqg*3lS}ILUn#=9;|%=7h~@IW$}gJ$-n}; zYRs&O^e3^nJ1c)Wa@^$EwHR1-?ZiJt4CLyD64IZwU!;N}tyN^5Pe+QD7WqoIYf(UC z1$RMw!mLWYdR3nEXs4KlBk79(M-(H&nKOwCNAo$!_p}5`^_}oP`A55e>};HJ5LSi7 z@N|jZ;a`Mw#fD$2--Z$I1cO8z(P^^0h%;k!k66NKDL~8$uNBQnz3eRWEp*WN`-=-r zkALb}?(E^VdsXgqIM6R*kdM*fMK0NG#@eX2p9M{!N6EW-nH&s)Ff+%YxzTk{o4f-p zzAWP84RTGHkt1LETiOa;pqZ&^?&S#1{^;SC?AnQ-!h;T&-sfK9?B=w}EMr5rz!Ds= zlk?w0AnK3u=MS?xfqy9~#wog$Q1ABtwRhf8O{M?32Skd})RA5l+t7P&;;2YdL_p~v z0fbNmqz7q^A}An5`XHdvA%rGGL5UEWgpv@7P6UJyP(wlq$bEx@Ge6HccinT=S?k<& z*UdjsR?5!a@BY5+c|K1uHd>|=Z!c)8)A(moSg2t70`^As)N!cq^cPzyy+~d_Ip7^N z=lCiy)G?%3Sbj#&N`ULh_j9)!(E|!l_a}kbUY$pxxg);8d$HW4K-=(^3{r@k+P6w* zxc$w%0nOxNwbjiU2$CjWWS4k;bi3nXN@e|6&Pe&p!ums+&>s{5DJh@EVB#%Ao0y`m zXg_T#Sl3f4BHU-QLC-&2m=%xuCi-a_GU@y9%U9^ebfC^?V+f_WQdXwXT;Br?jg|`j zeTQI=KX*j?+Ztg6Er+z*BItc{-En0DeEqiN7R7NpC#vK308pMvJ z`rk8eec!SEO9u1TcJs>zs$iDKdLf!xUr?!c{aRz?UAaj5X0)H(&Xixd2R7JK>s!;h z{f*{Mic{zcrh$UU6AnufEeNv!EQPL(rw}v+(og~vLd2Z zd;_M9W9ZE1TdXThF?7ol{{g0sUaG7W(2Riz*LU$ijlb01IE;7|*KDb*PNd?bZ(qNz z9w$qr2&j+Ved8dZ1Oo^wH|Ucoz$AG&i`RKy-%8F0sqzb8Hut=Jb4G3quRTcCTHWM# z^qsL;2f!mzlO2x$-c|cLJhH6{o1u!JqhY|Yn%ZiLYlqZo4qsdZTAM$e7(d_^TsYS6 z9uMJ0u%r>WK9Ab#G9phwxjoG zKP5^K3n0%2_4|`Y+C6YBI=HbO?t=J}k*1=tRTMTgMyKmwM7=u=@Qc6BJ15vRC&Ne}W&x*qDbeLV3Bw?h02O_GjB#RL2+s}i zr|9guoR~5ny{ja>YSMm)v&%J<^e+{L<^ttU?7^nH7swWSeeabc$L0#wPM?2Is~xT! zNCsE@S$EF0eM5x4x&k|+3Y#}O^5&MZopG!_=llhLsw1`vQheH*Qbeaqh7-@8RQGhB zIDzM4;BRgKDrhEU&ObLI%nGONKjF1`Rv7%ijDgw^TnQ2kz9@K10^}3l1e}=brY(T`bSQ3D-AK2rRc?;JGogigT^!0i$ zH}@9TX}lhg7oi(I_m74THlEk#CsKF@4Nq?c6I8)X3LXe&fYumh%u2kiCCWpkO&~vK z-v&08QR{1ta^}k?;nVem*ehG0blju>i6WPmlWRGl?c}U`Bc}q&i<>R;Vfbr)`sc_i z0M5p(Csv&bWyGLRNF<~4(YK37SJz`6j;cK>M|Btx)1X8?i$AJ?$fHiTV7ZBqypXpX zabomk*Ju~E>lzBVpRB}H-dnq?vjIR0ZQ2VK2&R>^k`o^2XmN14ODfI__g+q_z91vp zezb1Dim%NcFoO692nWWZ6%|_)ykc$@$j;_Al7Q*W+}b|qiipnyK!XKw`O&S8oZjBh zBxnV+mo@fe288G6bqHww-eP|P${*+ZEuz+E zeS@trAfjn}L1g*Xxr5$LN{g2)b7Ch%Am6Pi$G%@cdBq)&uT5qzVbJFBUS2xUib8Ef z>aeTS2!u?9y6dp+s&bqDq5=cFA)Qa$S&n>{H6SXS6n~hCC3pde$OhL5PVg>Osw%50 zpMpM6a3>E5H|}btb|B$ajF1Zeu$0l_l=d~xs6SASPr0~}w)Si1 zA^1@pt2Ul-s{$;8kK?vI1*?O7)|#$t&tcC`z6>&F9%=;6_U?Wj zM6^OSVy<;$zvGq5SN-K zs9>ft{NG#}pAv>&ryg2u%N88vGi*aSvb`FXT+Eg+?>x@E4vBdrCg*knwY(??m#TZDnHe$t2y2YP>TjZi6msUM7hxUMUOOQe3Fx0&Zy_w%S9bMFq{;BS<$J)M#6u zuAYLW`khKJH{v-a{W?2d^S=H`KDM4b-Xr}lCc%LiGlnIH4)tHA$0dvd0-fTn^)6*Suc+FD&LhriLh)(6J z5i0Zr6!09s?yHa!?NL3z!+VVJ!{!&v#yw+5jJ@Dj_>=+m0M97RSAwIrcJOU`#SxbC zR5xCP*(&t%PQ$Rcn2{7R5v|$Z+?-d}j2TeKHJ)oBC+oG{^M41cDSvVJ-!uWryTf&+ zKbR&~eWLgC2J4nWZ|O~BW3>^rGA!x$714}#*7&;`B*2|50>}Mjc(k_V=Z>_-O zeY}_}`?QqO6unmCsA4AL@7P2!uo_EW$CzI z8P0-X$)v~2z>M5c);*a>)|x)4?`8QW;?jIY3m`l79p<3T#pKd@EnJdEH)3O+fi^i}LQhP=HpaF&z{@t<>-B67d1DAnH z9k6tV;E$tmg{Jrl^fjN^n zKt%W}bDYt86?{JOP_=*W;=75^nvn=;Y{?9~v9fguw_HX|jZPa>%9sWNtU})nT=Mga z!P~H!lHT51OPWkiCoj^!;kS~Mv&(mX?jwjt*>NohWBn{--)qtueE2`^ySC3Y<8AK@p%O^{#A#(8)0?-zaiUTFsu$ zruovG1%+f+hnD)Jb%C-O(Kzn_Ay^*hNy_ z5GC>e&sk9i{&0?=<*<$oEI;jNnLRl3N@n+Z{lCw07y#GnL+Jq?E|~;=YW%*g4o;2% zRLH~kch&_m-DYj*8#MHR8XeK{3U3f}F^9!Uv@35sr%LZB9f~FFZZPd_%h9rk-2(Nx zJ~F4MfF%yFJM^U7w?AMe8J&%DT&}iM4n*Cju=WL;j7OG^*F$OB$c1e^{6NOs)_uYs z1|AcLkh`!NNftpHJ&|qMFzw)ie&-)@azNhUwQyt7;O5lPF3+5!jTl_xV3dKAX8?xi z)`WB+8h&D|bY3K)q)z!x?!zrXqRJ-@bef+WOW3?fToA1!vc0WY##%HzL6|=ydG!yt z_M&KB{ck^h7avclgtbg)uG&)O{=qRX3;uNKGkQg8OpF05u{$O%XN{Bi+!JRlm~mJy_F{+pmfb6U z_`JKoLOUmBKs-0`W||iDh3PdbxuSx!7Q+Ii0t2ilj~VLNs!browhhojof7|XLR7`> z>{uYj1DZLQY&8#1_&(Cc+9>(tu{e z=Rbe0(Tw=!4GEvZ&4n*+gS@2q&lU~a`VgTE>lEVke&A;DE_goomP(^W1u53+5GUR& zeEtkVI>yu%v7r;?eJ_J|+g-&kJPDt>`eM^X_FHYRL<+Pe9~HNYtsi-l>@*0nJ%(I> zW8g4?^wYcOWyv6(*@ZqY4p9}iYu5qF%b`G%@IG_1>Kf=ekkaGc*IVa=^FJ3B|KZlb z!3IxfQwOhyzq&B>l{9}?pTbdJ1Iu?E_lgP#i@%O8P%A$o{`yDlt2oGW{KIdZ+BVsd zx^`cb{yd(N+Anq`x#*&7VfNy*jdh|?{L7={lPjCGBZ!t00gRR+Q?CK+wL==fUY8_H zw|pVt#amXv^)DphLs1t(r&83#(iA(~m1cYT9#zKVt`@;{-svv&eNky{9#MP@HSZZz zojI*IKUY#V0O?1<7rR^sbsZ@h2k=wE?j&;V65s3)UYazFs%eM>yq+=F;z$k6uI4Xw zQRj2qD%`7!xgT%Q^uVVVD$b!5}QuznZ!@y*7>B=~#QoFJA; z+!o86FnYv3oEmvByRi1$wPMr#LYB-aC-Nh@S>>ctUS(W^&~;|+@XH?WXf0n~MD z>HJz^osLa*!>KrxzM%PHLf_}hJ!S|H1B#$Ln`OJ{Fj< zU({72EO)?KqA)Kru(rY1NT>AX5^X5U9dGduj^Z*yL%G=kQo5VhAMlX-}7s6(Yb?cA4kU|UcZRI2hXqHn{S!O z^Bv0nX!g9SC2dA|t=uT<%IanG=u0VfwS57M=B0Yi!z%&<(=&2J@ci-=jvSZJZtTZV z;;q9gx@Kd>t!V)_G(}anJ#q8vEo%{{@{rf4xu1}nF;W@N z&yKA^YGI{!TR;(DukPPoIjz%ZF4*%#VnF(Qjh|CXRB)z)0?%Ezjxi8!?`Mu1Up+JZ z;J8r7FSpBiIy_#cCn#$kZw`_nq-P~s%(OSAmyxqbA-~RNW+*9H>SGn$MM(LqKBSpX znRj6 z`t(jp{c|0%%`q=>!$PUz-9M4Fk|U7?tbF4G(ww#z>Lg6+^_n+s<^j3*$x7oCuQJMW zi_q>3Z{+2+6bvPstOCu9@+oDp5V&S;6{3Oj@6A^VON6fG&Y}+hU9Wvn^*Hr<@(o3n z_`16^_c6DPyZ3+eSE}OPQ4$I7V8^11s$Rvg`gq4U{*BiDYgb#5d6ycF2K^7UwiPM*|@@eB|A1)H+ zLT9zn6~-v(Mp>nE0ZYBxqfh2aGmZ6|Yhr33)4A8Z6$uZ()g)Ql zh%LNbJ;nF3FQxgGte)t#;8l?%%;)k;!S!v={E|{UtNM(v>fHS&wsi6DSY>>DzNxR= z)T^APg;i-3;9Bzaa@u`TH8K7dV*Az+_vYZs>+2nm-4ZV?#KWYo%VGNHw4Jc&?%e{O zGe8s)$L^vCcs4#Neum|*eifujz)BAA9NDei^hLJ+9NzBdAw;&T7>MQQ2(z)*&cvz0 zC{f|W-AxXcpp_e!2YkzPQu~3wH^pl@hVkzXJy}iM4zcKfI=~}3(7tESE=yRzS6{t3 zd!yD$+S>qV2{`Og_{{nuU{O&KO?~b4Xi32Zj!SxT?Fhz&51JmLsEvx6z(b9>*=FHO_-A zg$^okAIlih(pQSzrn~qP29B8^RPeuyso+DNjq3r>C()G<+)hqw(1fj&s+M72xA$vBgg|<~4uuuENv|qO(K@fjG8bThXTd#mVbN z;}6--r$xe!eg{Vb^C;-CJO21s)pEARf~zKg=;Cyl^^#H6A2ah`BkZNixgg_AQk>Ds z*MA)?8H&pCc9euIh@x}hrX@TV#?)flBU;IXKS&Q%J)CR`NvA3YSW^KEA>^7hA#2et z_)(5*NPkL_Y1=lL4-<5a#qZ3I_6p_(DT)0-tZ|hgzB5d@iyL<9f^4NR&PRmeJU^#b zm!Bdfc2kcXdQwU_8KQ7}NcFJcQxn(-$2&#JC-pUZe}O(aD*O}P%-%?t*AdI@ZYT5wO7A7ANRA|{W>trxWS)+cgKLugw5J%rI6<(G+#aOVM0p@^ule~ zO!n6q``B8$0zScN6jTq^9iu@!#5U5sGO`MASqXtYyjH6MTJPC*m#@LdTbkLC(-ZcH z``u8`dR-9GZkh1RkzzZp#8JbCMnT1Cl!nI!)bvC8Wrz4ES-pN#&1L*c-H=zUP z-z|bUFzz;vL9`3k&7fL~O8RC3Fi|Uy3p_R42^wmg`-O-wSGqPCJa(>+m-t^v2UN@5_Qm<^yEL_#RE4z@OzD(nKkqu%5my zEkto+(uZEwL|_603G&a(JK^;MUV1G6G)Br@4zF!d=LEUS@JZfH`^7BuQa~F0Kqj)* zTTDb=9@zB&*Wc9lD1BwLk?mb7>_pkeR-mV~e;=lL+_30gBl#vl)dCrC8jf5 zCM(B&kxXMc=6kDC=($%_b7{+m1fl0@$o0Mv+o`V^4K;O@T;=G6;oyp0Y&Qh>|4aiI zM_q;n4=@C0$KM1#czcnlza{W96q`J&)r$rohwu9&;vwh?LtuG zdtsBVDQnl%JtQV$xpi%}MjW@Uj8MqMVp~tc0O7eD@6%ez$GHb@V_RW5-v8Tf*%K~- z)qI0o+Y;7fz+M928;Z2>1RjqOt|8CS1LDg=UJyi##J?-y;Rw%g+Ah2l_XaeLWKG%& zJ#JR9@I?g>C$f!oMG0=oT%fDqGq+4m|D)n#wP_YSU^g!9g!v7+vK?ctmlqd>zQb75 z&^P{+wDiyFuPQaAvj#A|m&riZ4)Q>`El-%`e)=u;mBsm{Mf-mNn_s0K6AwQH-0CZk8-L_Tx9jz(e%(?4U%o5trNoq8K_r&;%kEf zUURi^BEUE@WD0;$pK45B&_jOSk9@!!eeZ32+^7{anjRJd9^aAg(%YM_06R7O@t4XK zayfFNd<2BP0?Gqhm8r!x2uhK(!o6&a>Vs9*``_Qr%@)K8yP*xg%f~UGF z(em~3Dhis)H0zPLW?x_K4b5Gjx6WuM^2x{U69vObzVl++sRuck@E-C{86_Mo=*vM2 zsMlWs2hAXD(6eJtGjJP~Q6GQcWpp+Szk>kM@yv#Au#2%3R4QEk#@ySxTkrhegxLr7 zsZdbq^VO@W@s1Kk@M1 zY!i+9kwlV3i271*1vE{!AOASn{+Z7GZw<`OU)I(qb7v^c)PV(=$^qtp+DICAfm#1O z3*_;b;q30>0gQ$$N$Vlfbp(G1%w8_3Z7k1OXv@_FWv{#9S_YnwMy;nsX%ms()KF^u zM%HZ^dzU=D(B zI#T#T_QnOT7XA~_-y6VKQSMo%Vj{g8Wh8u_p4fP&NEKc?Uz<7?&z& zd5eKyU`Su~7YH!DT{huP4$7<_<4|iOVF=n!zrc!XrC+%tbjGWhWXx00d&>jESc`fy zlgx`Nv%_3qmlwyR{T`2%zjFP3YJS!g@8PJu`s5pg?XgyLnHkCGz1H&B6VgF%wf+x~ zJJ!p3UWpUVLa3Vh{tW8zEu-bHBenP7=0-X7gr_0<69bL9Do!kTgAF4VGnRWPG1>HVs6~D(w&>8pQ#o+t+bn$$)dOitxYG z$E&BrZw6h&p5VWcAUaR|OncV$aXRAV19l~4Y0tQQ7_AJ;s>RWO05<@XM8Ho7b(~#? zok9cx^de4;*|-mOan1rzIgzRQJ!nMazE_q@O;scB8`SgIUEQwA7S2tPm8_5H^-IO?^GvSXm;%&V)TG@dX)7alJ-`1AAL-jO# zARl1zVyTjv=-;T zDQ7$EC_ign8VkvGY%)SHsVCz6%g4*Be+2C#nJ+~=9F)7zGmy}c2JO=|LA72A*2SWY zQC>yhuwVbTLApU6QGpTUIN#Sv#t+KgCllN-b=*S(qPcSJ9{j24IF7@Ms}>9+gI38t z<;yEMvP4Akj05SN;_Zz!Y_vd1z)3gBx8=llh0jCPT#ibcEGc>=Tq}t>7GwE@j0?z3 zu&&kXizH}_>*jZB*ey$K?L(=eUM1h(>L1D3KhQ#yP9F1)jucTz@sv7><7GmQ`mc<= zUZ2lv#{`A>q*rdN{`sk9fCl_o#D#%FD_Z+V)3!d%B@iSn437fYa_bo%rfs|(&(|%w zbJ5A&^nNEBL=7SR2DAgP{;vu|a~u}EYKBErO-}EZk`tOT(&t|tJEtL}+2grF*qllY z0Zq)EdduHf$guT7O2ERJn%mM!PC}f6!wXyEJR8d`RgH(>21`MdfpTl3 zRvA9fzH;_mgKBboIFL(rivtvER_t{Q9=vx)3~v{5U-Kg{6CGp22tlcAH8_ z`)a6}}-lfbVN~`4V){w$S=C5zbFML}DFz;?}TT2?Bi*(0^wg9s2a*JtD()6=7(ZCv7 zLT;H`C9$EdJVB#CtKZz4u73lMq~0OM53T){wD1V;pP zLHpQds!r}__%j}vAWErQo@O(gO=%OArC2q$XQ&CaNz@6nd>hU7~I zlRf4AA>-d#ro!y2`kT*g>rAjkzGaoHuc_rdx41gau1qA zJ=X8~jI;TR@%V|YQUCok)zkg$LEoaOsi-@Z)1$mP=47`7vOGLwiccrAC*VU?V^L^S zPcSs?h3IiNRs5x>KF{#}UKDalt~XJ5%-eV@6dSBN4UA5e^%G-2FY)Z6J0v*=^<)dR zu{(~HKFlN7TnwCh<9nlmkt<7oAif4QR~_~79ma4pDc{P9V^v_-N4oRsjq*wsD~Dk2 zObN(SbSzOEQpkn}wMVyU6Ys&#bzQ^%5}W#sPzHU>q8B;-AgSPSx=3RtAP5f2Sd{hS zw9k9x^UWx#WKH0?(SjL>lPqx(zj*hf=`k#QV`jE6O-z93nZB_Y*08=A+}fCdz2NKq z)xJE8W@6-=wPa)-qQSqthrfUJ4Dr?R-6OA16YsUlP1HZem!*y$Rj<0_DEr{#-t*0o za}t*XOXC7kosM7%l9a_4ZO^vI2pnavdi=rilXa=-%wR9EKk2HXZl8uX)Nm-|p_Eo{ zJxief){!99{*u#pTXed@ba)dkW7DoQwYhgB$8+0+<0zi$h3EAM??KOp&f`xIzv2Ul zl;tx%Q8{iOH`4NvaywXIfw`WmWC$f!otl`^JRBUMm`MGnjU8oq;JXB+P zU?ul4+&}7DaPB~WED_r)842CbI7fP$ETsBlF1E$!EGYd%@;unVHPU}N!@C4SlZ5sp z0%QNy!R&xCRRJDe!@~~~G{&hNYi>(lF;11(1e0kYMK`rM9DbOikGDE7>_u*U8%-gn z9y2m^a~oHOK>ntf8CErX+A%0%W6FTvQy>OW_98bwv)z77WuS7U3C@LYBrKm98e7?f zvc&0h?e+Se`Us$3Q!u}caEZb@ElXBCAROjIJVWi2TAV!PtMr+y3IB8!k!GhO7dp8c zpTYbrf*}=($_zxkC{5k88OZiN=-ZVxPm2tMl)>-rd>DG4+%!0F1|2n?kCg zk5vdQ@fGM7exMy?xGTOh)NYjcCB4+f73J!&faAaSItT-f$HCg6|3fkB@SCzkAzaj-Yau< zS}JBXt12(S(#X_^Krj%7_d@h~ipmgWUZDpMCXfr?&2|U}=M8kL&#KU#SNrN9XMBy( z{7yPQ3KbXI*b^1)J$|px+oT+g*6$SV z??gjINwi9w0OupRk zi#gA>R!1s`LcSXAFz4N~%EKcnQAQm{9=2-a=HH2yVp|TD6CXy%-t6a4hKwe}GWIYA z?+&oQj{Jc?7z>9;d*bc8n5x?@&xbLAU|QCZsZObkJ&W?Yoji!t(6o6bCZ&_bYF>ZN z^n{DYFjkLQv4nC-3DyGo5HUkh+x)nTqEwTm!3+37Z$~x{?X_ASXp4^6SAM=A~+d_Q}; zYg6NBs*`!=0(`ULiSYYRyX&>|bum_3Q{Jy8h7Y{OQ`zqb8aVN!=rvfA^dcY*!EM4! zEw>`nWpSh9?Iw7a?0SY%$-jj)+PTu0K#$<`M)l2?9#M=1#H#?){#x9UvY(BXncaV7 zqA^l<2v*gM^f6z!&~#w z6D(z4jMM^l5A9L*el8Vplb&p<=^lM(fse12JKVlI%WV%SgJ3+vaE@(vsPPrhey~H7 z_`>VFmJO`eZye;wtLo1!U^b|q*$NebI-ASheB8~fIs@~I8gr>PAt6u2|6XT`=AMmQ zz&h^HFTvZ=?6O*Ke`9n;Dq=#DUOCXzJs6(Sh*Wr0M({$`eAb3;ig-nq3mDxC44xJxMo{r4*lI5KmX35Ahp)I;=VqzJXG9rhcMvyoFZRCq!2H1g)O!Jdw= zX$jp}c`{a6-r^r^4s!6dve==#IEQwh>Mt5GWRyWpkxg;#klNeP=Cl@{8 zhRDKV;f$H|j;gcKlCSR)l$vP@Alj%)0aLYkt52-0uhA9}LcJ>nz*j4(1`#g04l|xQxa%lyFSkmsxCB*I0^^V}bdPpPg!g#Q<|5!}gg;M+{ z4I#UAlm7e{dE)HN>cjK$s^>en*e)U8 zia8DjAcp)t?Mkxm_2iGA{L-b?Udy#tMi~C!GoZ(sP#IzNU$>buY;iDe69_%cgu&=H Lvolqvoo@dxm4j;O literal 0 HcmV?d00001