From 23efcd2a26fd4e4651ec03183cef4808087f84a3 Mon Sep 17 00:00:00 2001 From: Howard Abrams Date: Fri, 25 Oct 2024 22:05:22 -0700 Subject: [PATCH] Minor fixes to work better with demonstrating hamacs --- ha-config.org | 16 ++-- ha-demos.org | 97 +++++++++++++++++++-- ha-email.org | 125 +++++++++++++++------------- ha-eshell.org | 2 + ha-evil.org | 36 ++++---- ha-org-word-processor.org | 8 +- ha-org.org | 66 ++++++++------- snippets/org-mode/python-src-block | 2 +- support/ha-org-graphviz-example.png | Bin 21997 -> 22179 bytes 9 files changed, 232 insertions(+), 120 deletions(-) diff --git a/ha-config.org b/ha-config.org index 7c6b306..cd76b4c 100644 --- a/ha-config.org +++ b/ha-config.org @@ -422,14 +422,14 @@ The following defines my use of the Emacs completion system. I’ve decided my / I don’t find the Emacs completion system obvious, with different interfaces, some distinct, some connected. As ~TAB~ is often overloaded. Emacs can have a cascade of functions. Here’s the summary as I understand (as well as the overriding keybindings I use): - #+BEGIN_EXAMPLE - ╭─▷ indent-for-tab-command ╭───────╮ - │ ╷ ╭──┤ M-TAB │ ╭─────╮ - │ ╰─▶ completion-at-point ◁──╯ ╰───────╯ │ M-/ │ - ╭──┴──╮ (completion-at-point-functions) ╰──┬──╯ - │ TAB │ ╷ │ - ╰─────╯ ╰─▶ hippie and dabbrev ◁──────────────╯ - #+END_EXAMPLE +#+BEGIN_EXAMPLE + ╭─▷ indent-for-tab-command ╭───────╮ + │ ╷ ╭──┤ M-TAB │ ╭─────╮ + │ ╰─▶ completion-at-point ◁──╯ ╰───────╯ │ M-/ │ + ╭──┴──╮ (completion-at-point-functions) ╰──┬──╯ + │ TAB │ ╷ │ + ╰─────╯ ╰─▶ hippie and dabbrev ◁──────────────╯ +#+END_EXAMPLE In =org-mode=, ~TAB~ calls [[help:org-cycle][org-cycle]], which is even more overload and context-specific. In the context of typing text, calls the binding for ~TAB~, which is the [[help:indent-for-tab-command][indent-for-tab-command]]. If the line is /indented/, it then completes the word: diff --git a/ha-demos.org b/ha-demos.org index 0ac7dea..93cda64 100644 --- a/ha-demos.org +++ b/ha-demos.org @@ -2,7 +2,7 @@ #+author: Howard X. Abrams #+date: 2024-10-18 #+filetags: emacs hamacs -#+lastmod: [2024-10-19 Sat] +#+lastmod: [2024-10-24 Thu] A literate programming file for creating and running demonstrations @@ -114,8 +114,8 @@ Instead of executing a sequence of demonstration steps, demonstrations key on #+BEGIN_SRC emacs-lisp :tangle no (define-ha-demo ha-simple-demo - (:head "New Demonstration" :i 0) (message "Howdy") - (:head "New Demonstration" :i 1) (message "Hi there")) + (:heading "New Demonstration" :i 0) (message "Howdy") + (:heading "New Demonstration" :i 1) (message "Hi there")) (global-set-key (kbd "") 'ha-simple-demo) (global-set-key (kbd "") 'org-present-next) @@ -136,7 +136,7 @@ To make the contents of the expression easier to write, the =define-ha-demo= as (define-demo demo1 (:buffer \"demonstrations.py\") (message \"In a buffer\") (:mode 'dired-mode) (message \"In a dired\") - (:head \"Raven Civilizations\" (message \"In an org file\"))) + (:heading \"Raven Civilizations\" (message \"In an org file\"))) Calling `(demo1)' displays a message based on position of the point in a particular buffer or place in a heading in an Org file. @@ -151,7 +151,7 @@ To make the contents of the expression easier to write, the =define-ha-demo= as (interactive) (let ((state (list :buffer (buffer-name) :mode major-mode - :head (when (eq major-mode 'org-mode) + :heading (when (eq major-mode 'org-mode) (org-get-heading))))) (cond ,@(seq-map (lambda (tf-pair) @@ -214,7 +214,7 @@ Let’s test: '(:a 1 :i 5) '((:a 1) (:b 2) (:c 3)))))) #+END_SRC -But can I check if I have triggered a state once before? Let’s keep track of the /states/ that have returned true before, in a hash table where the key is the /state/ (a list of =:buffer=, =:mode=, =:head=, etc.) and the /value/ is the number of times triggered at that state: +But can I check if I have triggered a state once before? Let’s keep track of the /states/ that have returned true before, in a hash table where the key is the /state/ (a list of =:buffer=, =:mode=, =:heading=, etc.) and the /value/ is the number of times triggered at that state: #+BEGIN_SRC emacs-lisp (defvar ha-demo-prev-state (make-hash-table :test 'equal) @@ -239,6 +239,91 @@ Let’s create a function that could accept a list of /triggering keys/, and the (not (seq-difference triggers state))) #+END_SRC +* Demonstration Support +What sort of functions will I often be doing? + +** Display File +Displaying a File with: + - On the side or covering the entire frame + - Larger font size + - Modeline or no modeline + - Going to a particular text or line + - Moving the cursor to the top or middle of the buffer window + +All options? Should I use Common Lisp’s =cl-defun= for the keyword parameters? + +#+BEGIN_SRC emacs-lisp + (cl-defun ha-demo-show-file (filename &key position size modeline + line heading shift commands) + "Show a file, FILENAME, in a buffer based on keyed parameters. + POSITION can be 'full 'right or 'below and positions the window. + SIZE is an integer for the font size based on the default size. + MODELINE is shown if non-line, default is to hide it. + LINE is either a line number or a regular expression to match. + SHIFT is the number of lines above the point to show, in case + the LINE shouldn't be at the top of the window. + + COMMANDS is a lambda expression that can contain any other + instructions to happen to the buffer display." + (unless position + (setq position :right)) + + ;; Step 1: Create a window + (pcase position + ('full ) + ('right (progn (split-window-horizontally) (other-window 1))) + ('below (progn (split-window-vertically) (other-window 1)))) + ;; We could do :left and :top by not doing the other window bit... + + ;; Step 2: Load the file + (find-file filename) + (goto-char (point-min)) + + ;; Step 3: Increase the font size + (when size + (text-scale-set size)) + + (when line + (if (integerp line) + (goto-line line) + (re-search-forward line nil t))) + + (when heading + (re-search-forward (rx bol (one-or-more "*") (one-or-more space) + (literal heading)) + nil t)) + + ;; If SHIFT is positive integer, left that many line above point, + ;; otherwise don't do anything to leave it in the middle. + ;; If SHIFT is null, move it to the top of the buffer window: + (if shift + (when (integerp shift) + (recenter-top-bottom shift)) + (recenter-top-bottom 0)) + + (unless modeline + (setq-local mode-line-format nil)) + + (when commands (funcall commands)) + ) + + (funcall (lambda () (message "Hello"))) +#+END_SRC + +Let try it all together: + +#+BEGIN_SRC emacs-lisp :tangle no + (ha-demo-show-file "ha-config.org" :position 'right :size 1 :modeline nil :line 418 :shift 4) +#+END_SRC + +Or: + +#+BEGIN_SRC emacs-lisp :tangle no + (ha-demo-show-file "ha-config.org" :modeline t + :heading "Text Expanders" + :commands (lambda () (jinx-mode -1))) +#+END_SRC + * Technical Artifacts :noexport: Let's =provide= a name so we can =require= this file: diff --git a/ha-email.org b/ha-email.org index 43f6a73..99d2ec3 100644 --- a/ha-email.org +++ b/ha-email.org @@ -64,6 +64,11 @@ To use these, we set the =:noweb yes= (to pull in the /name/ of the code block) smtpmail-smtp-server "smtp.gmail.com" smtpmail-smtp-service 587) #+end_src +* Sending Mail +#+BEGIN_SRC emacs-lisp +(require 'smtpmail) +#+END_SRC + * Installation and Basic Configuration To begin, we need the code. On Ubuntu, this is: #+begin_src shell :tangle no @@ -304,17 +309,17 @@ The following option is supported here: exclude_tags=deleted;spam; #+end_src *** Maildir compatibility configuration -The following option is supported here: +This section support the following option: - - =synchronize_flags= :: Valid values are true and false. If true, then the following maildir flags (in message filenames) will be synchronized with the corresponding notmuch tags: +- =synchronize_flags= :: Valid values are true and false. If true, then notmuch synchronizing the following maildir flags (in message filenames) with the corresponding notmuch tags: - | Flag | Tag | - |------+---------------------------------------------| - | D | draft | - | F | flagged | - | P | passed | - | R | replied | - | S | unread (added when 'S' flag is not present) | + | Flag | Tag | + |------+---------------------------------------------| + | D | draft | + | F | flagged | + | P | passed | + | R | replied | + | S | unread (added when 'S' flag is not present) | The =notmuch new= command will notice flag changes in filenames and update tags, while the =notmuch tag= and =notmuch restore= commands will notice tag changes and update flags in filenames. @@ -325,7 +330,7 @@ The =notmuch new= command will notice flag changes in filenames and update tags, That should complete the Notmuch configuration. ** =pre-new= -Then we need a shell script called when beginning a retrieval, =pre-new= that simply calls =mbsync= to download all the messages: +We call this shell script when beginning a retrieval, =pre-new= that calls =mbsync= to download all the messages: #+begin_src shell :tangle ~/.mail/.notmuch/hooks/pre-new :shebang "#!/bin/bash" # More info about hooks: https://notmuchmail.org/manpages/notmuch-hooks-5/ @@ -344,11 +349,9 @@ And a =post-new= hook based on a filtering scheme that mimics the Hey.com workfl # Based On: https://gist.githubusercontent.com/frozencemetery/5042526/raw/57195ba748e336de80c27519fe66e428e5003ab8/post-new # Note: We now tangle this file from ~/src/hamacs/ha-email.org # -# Install this by moving this file to /.notmuch/hooks/post-new -# NOTE: you need to define your maildir in the vardiable nm_maildir (just a few lines below in this script) -# Also create empty files for: -# 1. thefeed.db (things you want to read every once in a while) -# 2. spam.db (things you never want to see) +# Create empty files for: +# 1. thefeed.db (mail you want to read every once in a while) +# 2. spam.db (mail you never want to see) # 3. screened.db (your inbox) # 4. ledger.db (papertrail) # in the hooks folder. @@ -422,8 +425,6 @@ do done timer_end "Screened" -# Projects... - timer_start "Old-Projects" notmuch tag +old-project 'subject:/.*howardabrams\/node-mocks-http/' notmuch tag +old-project 'subject:/.*Pigmice2733/' @@ -434,12 +435,12 @@ notmuch tag +screened 'subject:[Web]' echo "Completing not-much 'post-new' script" #+end_src * Hey -I originally took the following configuration from [[https://youtu.be/wuSPssykPtE][Vedang Manerikar's video]], along with [[https://gist.github.com/vedang/26a94c459c46e45bc3a9ec935457c80f][the code]]. The ideas brought out were to mimic the hey.com email workflow, and while not bad, I thought that maybe I could improve upon it slowly over time. +I originally took the following configuration from [[https://youtu.be/wuSPssykPtE][Vedang Manerikar's video]], along with [[https://gist.github.com/vedang/26a94c459c46e45bc3a9ec935457c80f][the code]]. The ideas brought out were to mimic the hey.com email workflow, and while not bad, I thought I could improve it over time. -To allow me to keep Vedang's and my code side-by-side in the same Emacs variable state, I have renamed the prefix to =hey-=, however, if you are looking to steal my code, you may want to revisit the source. +To allow me to keep Vedang's and my code side-by-side in the same Emacs variable state, I have renamed the prefix to =hey-=, buf, if you are looking to steal my code, you may want to revisit the original source. ** Default Searches -A list of pre-defined searches act like "Folder buttons" at the top to quickly see files that match those /buckets/: +A list of pre-defined searches act like "Folder buttons" at the top to see files that match those /buckets/: #+begin_src emacs-lisp (use-package notmuch @@ -451,6 +452,7 @@ A list of pre-defined searches act like "Folder buttons" at the top to quickly s (:name "Previously Seen" :query "tag:screened AND NOT tag:unread" :key "I") + (:name "Sent" :query "tag:sent") (:name "Unscreened" :query "tag:inbox AND tag:unread AND NOT tag:screened AND NOT date:..14d AND NOT tag:thefeed AND NOT tag:/ledger/ AND NOT tag:old-project" :key "s") @@ -479,7 +481,7 @@ A list of pre-defined searches act like "Folder buttons" at the top to quickly s #+end_src ** Helper Functions -With good bucket definitions, we should be able to scan the mail quickly and deal with the entire lot of them: +With good bucket definitions, we should be able to scan the mail and deal with the entire lot: #+begin_src emacs-lisp (defun hey-notmuch-archive-all () @@ -495,7 +497,7 @@ With good bucket definitions, we should be able to scan the mail quickly and dea (hey-notmuch-archive-all)) (defun hey-notmuch-search-delete-and-archive-thread () - "Archive the currently selected thread. Add the deleted tag as well." + "Archive the selected thread. Add the deleted tag as well." (interactive) (notmuch-search-add-tag '("+deleted")) (notmuch-search-archive-thread)) @@ -526,38 +528,41 @@ A key point in organizing emails with the Hey model, is looking at the "from" ad And we can create a filter, /search/ and tagging based on this "from" function: #+begin_src emacs-lisp -(defun hey-notmuch-filter-by-from () - "Filter the current search view to show all emails sent from the sender of the current thread." - (interactive) - (notmuch-search-filter (concat "from:" (hey-notmuch-search-find-from)))) + (defun hey-notmuch-filter-by-from () + "Filter the current search view to show all emails sent from the sender of the current thread." + (interactive) + (notmuch-search-filter (concat "from:" (hey-notmuch-search-find-from)))) -(defun hey-notmuch-search-by-from (&optional no-display) - "Show all emails sent from the sender of the current thread. -NO-DISPLAY is sent forward to `notmuch-search'." - (interactive) - (notmuch-search (concat "from:" (hey-notmuch-search-find-from)) - notmuch-search-oldest-first nil nil no-display)) + (defun hey-notmuch-search-by-from (&optional no-display) + "Show all emails sent from the sender of the current thread. + NO-DISPLAY is sent forward to `notmuch-search'." + (interactive) + (notmuch-search (concat "from:" (hey-notmuch-search-find-from)) + notmuch-search-oldest-first nil nil no-display)) -(defun hey-notmuch-tag-by-from (tag-changes &optional beg end refresh) - "Apply TAG-CHANGES to all emails from the sender of the current thread. -BEG and END provide the region, but are ignored. They are defined -since `notmuch-search-interactive-tag-changes' returns them. If -REFRESH is true, refresh the buffer from which we started the -search." - (interactive (notmuch-search-interactive-tag-changes)) - (let ((this-buf (current-buffer))) - (hey-notmuch-search-by-from t) - ;; This is a dirty hack since I can't find a way to run a - ;; temporary hook on `notmuch-search' completion. So instead of - ;; waiting on the search to complete in the background and then - ;; making tag-changes on it, I will just sleep for a short amount - ;; of time. This is generally good enough and works, but is not - ;; guaranteed to work every time. I'm fine with this. - (sleep-for 0.5) - (notmuch-search-tag-all tag-changes) - (when refresh - (set-buffer this-buf) - (notmuch-refresh-this-buffer)))) + (defun hey-notmuch-tag-by-from (tag-changes &optional beg end refresh) + "Apply TAG-CHANGES to all emails from the sender of the current thread. + + While defined (since `notmuch-search-interactive-tag-changes' + returns them), this function ignores BEG and END (for the + region). + + If REFRESH is true, refresh the buffer from which we started the + search." + (interactive (notmuch-search-interactive-tag-changes)) + (let ((this-buf (current-buffer))) + (hey-notmuch-search-by-from t) + ;; This is a dirty hack since I can't find a way to run a + ;; temporary hook on `notmuch-search' completion. So instead of + ;; waiting on the search to complete in the background and then + ;; making tag-changes on it, I sleep for a short amount of time. + ;; This is generally good enough and works, but is not guaranteed + ;; to work every time. I'm fine with this. + (sleep-for 0.5) + (notmuch-search-tag-all tag-changes) + (when refresh + (set-buffer this-buf) + (notmuch-refresh-this-buffer)))) #+end_src ** Moving Mail to Buckets @@ -573,8 +578,8 @@ We based the Hey buckets on notmuch databases, we combine the =hey-notmuch-add-a "For the email at point, move the sender of that email to the feed. This means: 1. All new email should go to the feed and skip the inbox altogether. -2. All existing email should be updated with the tag =thefeed=. -3. All existing email should be removed from the inbox." +2. All existing email updated with the tag `thefeed'. +3. All existing email removed from the inbox." (interactive) (hey-notmuch-add-addr-to-db (hey-notmuch-search-find-from) (format "%s/thefeed.db" notmuch-hooks-dir)) @@ -584,8 +589,8 @@ This means: "For the email at point, move the sender of that email to the papertrail. This means: 1. All new email should go to the papertrail and skip the inbox altogether. -2. All existing email should be updated with the tag =ledger/TAG-NAME=. -3. All existing email should be removed from the inbox." +2. All existing email updated with the tag `ledger/TAG-NAME'. +3. All existing email removed from the inbox." (interactive "sTag Name: ") (hey-notmuch-add-addr-to-db (format "%s %s" tag-name @@ -597,8 +602,8 @@ This means: (defun hey-notmuch-move-sender-to-screened () "For the email at point, move the sender of that email to Screened Emails. This means: -1. All new email should be tagged =screened= and show up in the inbox. -2. All existing email should be updated to add the tag =screened=." +1. All new email tagged `screened' and show up in the inbox. +2. All existing email updated to add the tag `screened'." (interactive) (hey-notmuch-add-addr-to-db (hey-notmuch-search-find-from) (format "%s/screened.db" notmuch-hooks-dir)) @@ -759,3 +764,7 @@ Let's =provide= a name so we can =require= this file: #+options: num:nil toc:t todo:nil tasks:nil tags:nil date:nil #+options: skip:nil author:nil email:nil creator:nil timestamp:nil #+infojs_opt: view:nil toc:t ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js + +# Local Variables: +# jinx-local-words: "notmuch" +# End: diff --git a/ha-eshell.org b/ha-eshell.org index c21951a..efda46e 100644 --- a/ha-eshell.org +++ b/ha-eshell.org @@ -73,12 +73,14 @@ If any program wants to pause the output through the =$PAGER= variable, well, we #+end_src ** Argument Completion Shell completion uses the flexible =pcomplete= mechanism internally, which allows you to program the completions per shell command. To know more, check out this [[https://www.masteringemacs.org/article/pcomplete-context-sensitive-completion-emacs][blog post]], about how to configure =pcomplete= for git commands. The [[https://github.com/JonWaltman/pcmpl-args.el][pcmpl-args]] package extends =pcomplete= with completion support for more commands, like the Fish and other modern shells. I love how a package can gives benefits without requiring learning anything. + #+begin_src emacs-lisp (use-package pcmpl-args) #+end_src Note that this will work with =shell-command= as well. ** Better Command Line History On [[http://www.reddit.com/r/emacs/comments/1zkj2d/advanced_usage_of_eshell/][this discussion]] a little gem for using IDO to search back through the history, instead of =M-R= to prompt for the history. + #+begin_src emacs-lisp (defun eshell-insert-history () "Displays the eshell history to select and insert back into your eshell." diff --git a/ha-evil.org b/ha-evil.org index 49b0bc1..91108f4 100644 --- a/ha-evil.org +++ b/ha-evil.org @@ -91,31 +91,39 @@ I’m not a long term VI user, and I generally like /easy keys/, e.g. ~w~, have #+begin_src emacs-lisp (use-package evil - :config - (require 'evil-commands) - (evil-define-key '(normal visual motion operator) 'global + :config (require 'evil-commands) + (evil-define-key + '(normal visual motion operator) 'global "w" 'evil-forward-WORD-begin "W" 'evil-forward-word-begin "e" 'evil-forward-WORD-end - "E" 'evil-forward-word-end + "E" 'evil-forward-word-end) +#+END_SRC - ;; This may be an absolute heresy to most VI users, - ;; but I'm Evil and really, I use M-x and SPC instead. - ;; Besides, I don't know any : colon commands... - ":" 'evil-repeat-find-char-reverse) +The ~b~ key bindings seems to need their own call, and I’m not sure why I can’t include it in the ~w~ and ~e~ bindings. - ;; The `b' key seems to need its own configuration setting: - (evil-define-key '(normal visual motion operator) 'global - "b" 'evil-backward-WORD-begin) - (evil-define-key '(normal visual motion operator) 'global - "B" 'evil-backward-word-begin)) - ;; Note that evil-backward-word-end is on the `g e': +#+BEGIN_SRC emacs-lisp + (evil-define-key + '(normal visual motion operator) 'global + "b" 'evil-backward-WORD-begin) + (evil-define-key + '(normal visual motion operator) 'global + "B" 'evil-backward-word-begin) #+end_src In other words, with the above settings in place, ~w~ and ~e~ should jump from front to back of the entire line, but ~W~ and ~E~ should stop as /subword/: - =word-subword-subword= - =word_subword_subword= +Note I don’t bind =evil-backward-word-end= with a single key, but bind it to ~g e~ below. + +While an absolute heresy to most VI users, I'm Evil and use ~M-x~ and ~SPC~ instead of ~:~ for running commands. I bind the ~:~ as a reverse of the ~;~ which continues the search from ~f~ and ~t~: +#+BEGIN_SRC emacs-lisp + (evil-define-key + '(normal visual motion operator) 'global + ":" 'evil-repeat-find-char-reverse)) +#+END_SRC + This clever hack from [[https://manueluberti.eu//emacs/2022/10/16/back-last-edit/][Manuel Uberti]] got me finding these useful bindings: - ~g ;~ :: [[help:goto-last-change][goto-last-change]] - ~g ,~ :: [[help:goto-last-change-reverse][goto-last-change-reverse]] diff --git a/ha-org-word-processor.org b/ha-org-word-processor.org index f19772e..9604f34 100644 --- a/ha-org-word-processor.org +++ b/ha-org-word-processor.org @@ -59,12 +59,12 @@ The =org-indent-indentation-per-level=, which defaults to =2= doesn’t really w :custom-face (org-indent ((t (:inherit fixed-pitch))))) #+end_src -Finally, let’s add frame borders and window dividers: +The following adds frame borders and window dividers to give space between window buffers. Do I need this when my Org files indent the text? Dunno, but it makes the view more pleasant. #+begin_src emacs-lisp (modify-all-frames-parameters - '((right-divider-width . 20) - (internal-border-width . 20))) + '((right-divider-width . 2) + (internal-border-width . 10))) (dolist (face '(window-divider window-divider-first-pixel @@ -385,7 +385,7 @@ However, I'm just going to have to write a function to clean this. (replace-match (match-string 1) nil :no-error))) #+end_src Now that is some complicated regular expressions. -* Technical Artifacts :noexport: +* Technical Artifacts :noexport: Note, according to [[https://www.reddit.com/r/emacs/comments/vahsao/orgmode_use_capitalized_property_keywords_or/][this discussion]] (and especially [[https://scripter.co/org-keywords-lower-case/][this essay]]), I’m switching over to lower-case version of org properties. Using this helper function: Let's provide a name so we can =require= this file: diff --git a/ha-org.org b/ha-org.org index 29decd9..90db979 100644 --- a/ha-org.org +++ b/ha-org.org @@ -283,7 +283,15 @@ Came up with a great way to search a project for Org-specific files, and wrote [ (ha-leader "f o" '("load org" . org-find-file))) #+end_src -Now that my paragraphs in an org file are on a single line, I could use =rg= (or some other =grep= program), but being able to use an /indexed search system/, like [[https://ss64.com/osx/mdfind.html][mdfind]] on Macos, or [[https://www.lesbonscomptes.com/recoll/][recoll]] on Linux, gives better results than line-oriented search systems. Let’s create operating-system functions the command line for searching: +Now that my paragraphs in an org file are on a single line, I could use =rg= (or some other =grep= program), but being able to use an /indexed search system/, like [[https://ss64.com/osx/mdfind.html][mdfind]] on Macos, or [[https://www.lesbonscomptes.com/recoll/][recoll]] on Linux, gives better results than line-oriented search systems. + +While =mdfind= is builtin to MacOS, we need to install =recoll=: + +#+BEGIN_SRC sh + sudo apt install -y recoll +#+END_SRC + +Let’s create operating-system functions the command line for searching: #+begin_src emacs-lisp (defun ha-search-notes--macos (phrase path) @@ -322,9 +330,12 @@ This function calls the above-mentioned operating-system-specific functions, but #+end_src Let’s see it in action: #+begin_src emacs-lisp :tangle no :results replace - (ha-search-notes--files "openstack grafana" '("~/Notes")) + (ha-search-notes--files "bread" '("~/personal")) #+end_src +#+RESULTS: +: ':3:common/rclinit.cpp:391::Recoll 1.36.1 + Xapian 1.4.22 [/home/howard/.recoll]' + Returns this string: #+begin_example "'/Users/howard.abrams/Notes/Sprint-2022-25.org' '/Users/howard.abrams/Notes/Sprint-2022-03.org' '/Users/howard.abrams/Notes/Sprint-2020-45.org' '/Users/howard.abrams/Notes/Sprint-2022-09.org' '/Users/howard.abrams/Notes/Sprint-2022-05.org' '/Users/howard.abrams/Notes/Sprint-2022-01.org' '/Users/howard.abrams/Notes/Sprint-2022-19.org'" @@ -384,14 +395,6 @@ And turn on ALL the languages: (plantuml . t))) #+end_src -The [[https://github.com/isamert/corg.el][corg project]] does completing feature for all the block header values. To do this, type ~M-Tab~ (not just regular ~Tab~). - -#+begin_src emacs-lisp :results list :hlines yes - (use-package corg - :straight (:host github :repo "isamert/corg.el") - :hook (org-mode . 'corg-setup)) -#+end_src - *** Searching Literate Files A noweb definition, e.g. =<>= could /jump/ to the =#name= definition. Since [[https://github.com/BurntSushi/ripgrep][ripgrep]] is pretty fast, I’ll call it instead of attempting to build a [[https://stackoverflow.com/questions/41933837/understanding-the-ctags-file-format][CTAGS]] table. Oooh, the =rg= takes a =—json= option, which makes it easier to parse. @@ -470,7 +473,21 @@ And let’s try this: #+end_src *** Graphviz -The [[https://graphviz.org/][graphviz project]] can be written in org blocks, and then rendered as an image: +Using the [[https://graphviz.org/][graphviz project]], create charts with /textual instructions/ (code), and then rendered as an image. First setup Graphviz configuration using [[https://github.com/ppareit/graphviz-dot-mode][graphviz-dot-mode]]: + +#+begin_src emacs-lisp + (use-package graphviz-dot-mode + :mode "\\.dot\\'" + :init + (setq tab-width 4 + graphviz-dot-indent-width 2 + graphviz-dot-auto-indent-on-newline t + graphviz-dot-auto-indent-on-braces t + graphviz-dot-auto-indent-on-semi t)) +#+end_src + +Next, add it to org-babel: + #+name: ob-graphviz #+begin_src emacs-lisp :tangle no (add-to-list 'org-src-lang-modes '("dot" . "graphviz-dot")) @@ -547,7 +564,7 @@ Here is a sequence diagram example to show how is looks/works: #+attr_org: :width 800px [[file:ha-org-plantuml-example.png]] *** Pikchr -No, not Pikachu, but close. The [[https://pikchr.org/home/doc/trunk/homepage.md][Pikchr project]] is similar to Graphviz and Plantuml, but makes the boxes more positional and really allows one to place things more precisely. Yet another steep learning curve. +No, not Pikachu, but close. Unlike Graphviz and Plantuml, the [[https://pikchr.org/home/doc/trunk/homepage.md][Pikchr project]] makes boxes more positional and allows one to place the parts more precisely. Yet another steep learning curve. Not sure if anyone has made a /package/, so we need to download and build locally: #+begin_src sh :dir ~/bin @@ -556,17 +573,18 @@ Not sure if anyone has made a /package/, so we need to download and build locall gcc -DPIKCHR_SHELL -o ~/bin/pikchr ~/bin/pikchr.c -lm # to build the pikchr command-line tool #+end_src -Of course, since we are dealing with Emacs, any good idea will be assimilated. Johann Klähn created [[https://github.com/kljohann/pikchr-mode][pikchr-mode]]: +Of course, since we are dealing with Emacs, where we assimilate any good idea. Johann Klähn created [[https://github.com/kljohann/pikchr-mode][pikchr-mode]]: #+begin_src emacs-lisp (use-package pikchr-mode :straight (:local-repo "~/src/pikchr-mode") + ;; :straight (:host github :repo "kljohann/pikchr-mode") :custom (pikchr-executable "~/bin/pikchr")) #+end_src Let’s see this in action: -#+begin_src pikchr :file ha-org-pikchr-01.svg :results file :exports both +#+begin_src pikchr :file ha-org-pikchr-01.png :results file :exports both bgcolor = 0x1d2021 fgcolor = 0xeeeeee line; box "Hello," "World!"; arrow @@ -592,7 +610,7 @@ At work, I’ve been integrating [[https://mermaidjs.github.io/][Mermaid]] into Assuming we have installed the [[https://github.com/mermaid-js/mermaid-cli][Mermaid CLI]]: #+BEGIN_SRC sh -npm install -g @mermaid-js/mermaid-cli + npm install -g @mermaid-js/mermaid-cli #+END_SRC We edit the code with [[https://github.com/abrochard/mermaid-mode][mermaid-mode]]: @@ -600,7 +618,9 @@ We edit the code with [[https://github.com/abrochard/mermaid-mode][mermaid-mode] #+BEGIN_SRC emacs-lisp (use-package mermaid-mode :config - (setq mermaid-mmdc-location "/opt/homebrew/bin/mmdc")) + (setq mermaid-mmdc-location (if (file-exists-p "/opt/homebrew") + "/opt/homebrew/bin/mmdc" + "/usr/local/bin/mmdc"))) #+END_SRC We can make Mermaid diagrams in Emacs Org files using [[https://github.com/arnm/ob-mermaid][ob-mermaid]]: @@ -608,7 +628,7 @@ We can make Mermaid diagrams in Emacs Org files using [[https://github.com/arnm/ #+BEGIN_SRC emacs-lisp (use-package ob-mermaid :config - (setq ob-mermaid-cli-path "/opt/homebrew/bin/mmdc")) + (setq ob-mermaid-cli-path mermaid-mmdc-location)) #+END_SRC #+BEGIN_SRC mermaid :file ha-org-mermaid.png :theme dark :background-color transparent @@ -752,18 +772,6 @@ I have a special version of tweaked [[file:elisp/ox-confluence.el][Confluence ex "o E" '("to confluence" . ox-export-to-confluence))) #+end_src -And Graphviz configuration using [[https://github.com/ppareit/graphviz-dot-mode][graphviz-dot-mode]]: -#+begin_src emacs-lisp - (use-package graphviz-dot-mode - :mode "\\.dot\\'" - :init - (setq tab-width 4 - graphviz-dot-indent-width 2 - graphviz-dot-auto-indent-on-newline t - graphviz-dot-auto-indent-on-braces t - graphviz-dot-auto-indent-on-semi t)) -#+end_src - *** HTML Style I’m not afraid of HTML, but I like the idea of doing my HTML work in a Lisp-like way using the [[https://github.com/tonyaldon/jack][jack-html project]]: diff --git a/snippets/org-mode/python-src-block b/snippets/org-mode/python-src-block index 5c9ae24..2c94ac4 100644 --- a/snippets/org-mode/python-src-block +++ b/snippets/org-mode/python-src-block @@ -1,6 +1,6 @@ # -*- mode: snippet -*- # name: python-src-block -# key: #sp +# key: 4H{z~~5&qtz2 z0(JEpFGxy>jMY`tsa>cu^2hLa=i=TOcw;HM*rK>YU~B56be zq@GrEwMUZ<>~L2&ct&7_>1gw#|zwF1M@G84*lhk49%Tn{$Fz~im% zt?7?7&f}tgr6tT&U$<0>N$YxXpe7&&+_zIUHuKVgwgOH% z&d@kZWltK5Ay#&o^G&yVllHH?iJysZ+;KDkad*iF;Lg1 zktMRGU-Fv??3@wv*i)*Mi2UkQFCdTh%8f?3gb^_jk#Eg&FGyc12LF2tZcLnv*Wd>0 zEf-}yJ&HdAuW8SYCfy4n?aFWI?h`{J5FLS_#=H zj#pY$3>9dy+ELtFp7`*XviQ#H7i%LWa+$>ylDb|pC^7quyQ5^_LQw^pa2kIR5s`|C z)uDp;II(uqh8&g;o{Jh&&t`+i`qG5(dpjUMJSUSI^U>Q!@jS1YM8aQ<6=)`o3K$iu z=_#JtPXsurr|{`|oGxcLgJzASi(38G96#hpSZpOv>rXQ%rB2V6Zz*=vPi9kmx`e#p zy=p*|Z0VkIzsz_(L2gU@cysc&!Z9-#79?holJ5i`moqf9;AyGs$lLhWohZK-J@fII z`$RwxuaXj{^t5-%>x_)X$=dQ9=vMDoq0CLt)7sRT#cfP6Y9SI1eRLP2M*3+LJ)A&4*?-Sw{2ylrp`=`XQT4ESy*!!;+;+e!DZ{EZyUG66S0^_51dznsv<)(y0@|!pP+wEtSQHwJA2#3#6XxUS>`{!zbx+7am zHy(r!y;Z?=SC`;&mbUxx9=KaTm8sV~`q6}-n`=1A1 zOAK{{h8}E;Q%2g&6(lNl&a~|beyVey<+z^Z@q&0x8r++pI(~VJPE~{J|`n*yq`s#K5NV^01&AO5I zLCoQtt=P-6)zNpf3Ag_+K^PPa7y6pZkn^-p0Nh~@&J)4=(F;`I4hx=S`dXeHZ5BDb zy6yExUxfq;I9!k5)6JYKt7`B3^X*O1n$vhC`y7XboJJ;*dPFJez9wjsVL(8OrTn`T1!I6#Xp!w*lS_Xm-qhtcy!euwV9(NgkZuVh+g_LL(OI%9&xk8 zKNu}F>^QlkR62(szq8Fo&mQ(?$|EmAi^r;LIu3H*J!dsxW4LNjOXc=tqr1&Rv!ln~ zG9wHNG`J-s_LFj_1Gn2uKl+L=h*`gs_#rRh;p*Tk5K1=Hv`~F@gF`+SJzyvewK4w| z;>2txZxN6&8Q6JZbi~@|oX0D>!B7<8mA`oLVmS1Ys>!q4&d}M^C)HH=XnFl-Sy5Kl z>)T#@qRmTaZK2mkV7OW;d9Pn5R99Drm3dW>j7WY97hGqQz3RLq%cck2BvE8r9Fc8- z#}AgiCclzEoXu8G6Z|4)CVMjJ8uv1;R2$8>**WwIrj8tm`D;%S-0$kG`8MU&Dl0;uj7^ z^p*ZP508u_p0FsHRolWyNJw~~Vr|;IQaY(?t?wQ+|uY{0AUjoSTdv9&fj7h<>Q9HfUgQls_0$9q8{Ds&Ner z2Pf(S0YIg{wsNxB>+yV(=OSCryTA`!AUZGpG_j#?aGiy?Od2@UmrHf{=^%qunePiz zQ&V|?M}LRFGkgE>uoYOZ!j&%8^b@ESZlDwU#|mWRuYzCiwdQ|s+}oMGcji<)zc4?( zml=~I9CUfQ@=D&n_QS)T1QVCZcJ&61?qowFgu2-bm;dHev)5+L!yegmhu*P8RuFGQ zFHd@uWcOEoG-_*Ww+nbGgiN?LW4*wwe}b#FuYWe*FHsJ@})GnP+#c zu>8N(0w#q3NfJ_0P6@JtII0CwNCGL!H=)^}0h)m-f}o_olyj_5D0pJ?#5&IR%72!b zxVNA0^;h`s|LILVmvsJM1V*g0^s~*)h|IXy*GTRRk#NmdeCfz~19HTxKG+^1iHc_=oI<@Yhxq z7U-7SRJ8PrAFg}*X|WG@N+7>p&#aETbi&tK9Qbo?P{CZK*R(+RD+}jOu}%dz#_TA2 zQiu}PM1YZl+=M>p-8agIMB~(W8ZFX)N=QllTpuaXFLa-6&j-69nf1~FC!w=wnS?MY z=P@o2NxW9R$1g80tCM$qmC)VSf_~usqSge`u;25 zvwt;t@)}oJ$1nG1O!lXXJoNPRgtNrE#dSZZf?mPqB%t;jvAw&Tm-ugSr=)7mBB*?h zxgMcPQE7!q^7xn$s0GK5WGmm3D*OFyl-E}4{&%|!%cs4~Ao`SX#&t_tjc0=;D%16M zU5vfG{pzM(D?t*aE$)CHdA{_r{$w(l2=NECfCx->-R?M z!kvb+D*0|tKbFf#_D1#zK{gcVL!_eeO^rPXbhd-@U48_9uQgm6J*D#0mgvAzXPD5m{cE)pFZhF~)7ppY zUGjMtW1Zsl39Sac2m}fI2Tya3J*@YQ{f0oqlJ1OmsVeH065nZv!O?rtURo{D7lA<;=}&LNd_JaOspRy6S1`8UBqau1#Y?_a*--#(~*=Uk3Wvr3iZy zv~!!`&-&WK)TkvQG@({QvaMW{{i=Hl_v_90m(S3xY7HC_JX?MiC!suM3qAuF+|J}3 zjgZ-tpgZV`53Pn{RSv(ZDB!F~L0=~4gCe)=yd!vaxnHa7v7?Kni-?xpXnT|4q*~fS z({sAX8GL;#)V+D|WAr)CS1F~4PDbPrck{FbBgwR=sQ`SWH8qy-+J?+G*7}2tcLlOZ z@(D{MXr=c8`8?da#i-CjhB2(>O{<3Du6f64PIO%?Gu&iI;UJsJZ)ELpo2{H;dBKy2 z1uA55VD@+TZS95}-ubm@-976Ga|mVsxW(Vmq;Kr56_VokmdKxE7e0$bgr_MoNBe0? zqhD~ki^BcqOS5fO{Tj9PsfaxXcWJ444Z)c@-w(%%20a0E^WjT}-V*te^=uTqQH4+NF>{}axnC@B#z+csol^B$!CAkK-Q_@w zB~2;cb^G>*1tCp*eA}H};y?#CRu**(&t9ppu;jJS_u-m&v1OQ|1kOhdPb_-VcqBJr z?i7|G`XD7MtMrpeGTxxVH>^mnCAy?<%*d+MaQ;?HhD11xn83aqTA;RmlmLCv#@5)_ z_19e;jo8CMpRIEI){Q=VUz_Bjz6bSMI5^*Ci^=~Wm?WRQ<(bp%L}*CO1b2TM2pxsO zH+sj6XlWdm&_ukS-Xo-Yy?Lh>qI3$3N6^U)rgGb1sWa5DG>W|HeP z*=@_FGclIlGu&Rs{durI4MEx9?6CGXZD^zMJvDq<0po79@_rv4*b|8E7^cH6%^X?(rR zZ(Qp1c@{o)g3|%U6Saq<4CsvNDMMCthQCovxR9_ZJ96DSC9uR~=feov!7yjbtWUnB zx5J6LT~y_%@H8%l5j^V_trV;U7Qyp^=uE~W5L7c=f>o5C5>4}JUJta%ReM^@SWVbB z#wgZGP8YYdSzFJK^J0m9=FQoy3G)S5@6n8G+G21y-zjo}BI|D|@t~Jh`@$*rAB9v6 zaF9MSp&(Gg=x$;b{fT3&f!dx;ZT)9b^vZt5FYBmp*KZ>m+PU7o**Qx%{+N-vtNwCn zr1r3z)*bKSxpcl>>~Gsx60V8Jtxv-f%j1DG%;=6|4VvYe)*t=IqqK?<%GQoGH8JsS z!5x@Z2;AavYo5hQ2xIScFc>G$v{kx(+uB{#iGT&--l+a~!9F9Ffk%91Z$-a-dM|8{ zR;$}!tiBeb?>~N5ew~gbJ{x}khXk`%tc#rS;XZt zB(>(ck*I2dJ9@F@co{3Zs==of`Rsn4-0yQ~N~<42+_w!I6qUFqzMZv+rBtXJ;;#O& z=tj=)Sj6QHwmon8dyijZPYBIiTi=TzHBY=pRrjZF?2oiJ?W6HzNqc9*d$=v6HO^Y! zAEI-cc}}6}@|9uRw0miHok@BPmtPoHy6A?e9)DK7LA!*f**OJv&x^1+z@n&L)ONEy z=Yz~~p5VPzMA1Q-uxjWpp)Kw&T-&H)yNomJYbbwagAvwbN@PeEy+_3x{z`cmXGa`@ zy_M3kA~Ku_tv?KXLWOWC{@8pF3NIn$KI#Mf1PA`3@Z(NEyo-nf6(oxb_I!9&<0~2k zL-M*K+EDd-P6W}U_)DuuyC8}=0jP0vwj~?gT8}vl4D2tj62z?JMY zT;j>u{USX=;g$@&N_?=pzagqTf`d72shr)C(d($IlU#X0Dk}c(U@Z&~(k}7y$!cl@ z>U=pYs4J5EYj5u-kmo*_4LNfKm;YJps0g!VK@BRpI;*5z*d%u>=$fAE?-@cJut94g zL$=iEb%Sx-v3{rpCSyqCDbDpFn7qpm@KdAO+SwDX0_hfx;+XfRUGa|AU zKfL?@1I{h}{|RuuC+NfeL~YfS`#=OF+>ib_loXHlqST*4sMpYU8pKI6W&)tD*7WrB zF_(kYp)cKx*SE}m$FoW=w4ZH#Fs`%|Kwjcwc!{u;`Fo+{T&JR_07SH6NSzJqx+P|B zn8_H&lsA0m1KrLO?#~wrfk&TlDdpcvyJej)s-}G2|Dlu^Lwj8o5zPit{ugh!m^D(d z&TcC>kk|ZHR#oh?v-&(yf^t?!p8Q!}a2q9`x9&&|&+Q<S(o$QE z&kp)rENF80t8Ifmr{wEY2?>u}auz4zs0Kvz^sdXt zTTg27@dkcE2@z*e(b9;Kx)pD$4!^!s0j+5>=&gDj!z;z$mLb3m9)V~;^tRbvs}H-o ztPb%_71-tFea909$?8Ygxd~CtCqmj#M#Q=A!snQO?@Gqv%Vt@?w0oT6&o|uazn>my zHxM?p?+LDd(D6)uB@_x_th%+Rl1*$1RYD#(sHmVP9}}q_3@98=6&$V(bw&N@(g959 zhX0;@m-x#?Dc!((XtL$d&~q#sidO4UPxCa3Q3lQ!6I4aY-5%rhF`hU1tIkSpXuDT8 zy~*e1wa;&L-`qNxoV{f5WLsf?R8}bXv1d!6+@Dt%*<7W{og{OPkUw#{Uo?C;H0)aWX)P*}&Nqzbl@(%+{x_Y<=AJRXmvs z6DfAQB-#3>NrktLtp)KaQR$K?jzOdokZ3zIhRj>8v49-#$jPw+3Ps@^HB5<3IhQ~M zLUl9ChApws)3_VFYHk*@<}fAj#o)Zcpo`9p40h;wNU z*RjaLTpF}I!Pc2yH4I3%U37m%&ff48MFffoH#K@AuwN;^|lGw(SLF9Qx}a`ETf1y z9wf8-nb+o}0w7a$PCxtHwW6rpv4M=Kt)z`gTG!;gm_wN;Y$G`}Ny)la{eL@_+`o(_ zkB;I9AaZnctafDu#98wy9JHT4n(|KJyq@^}i$F=%3sYfVVN@{`bbE}uA3Gbm%`xdb zR&F*}T=r7`63dAiM>fzPT;h!0{N!`QW$4v|zC&~Ux?GvX?Bnghfl8T`3?|n8*JQm{ zA&6gC`19|2=Uo7&d8DNoLoYULhDr?!FjDo-;}jmx-X=cRhv}qab+ol1$j-b`I8pyH zm%Pz(e;MNIe)r9Z*1Bpu=gnMtVD`4=V!DHrw!Z#x!J5-ho+_dD*3@Z9)yHSs32xIZ zc0f{-@tA{hg7$hbQfb8Kc5+qw(~g5@LV_gQQVAg^HbjPhr^6K>8eHSMm3GN5ahOQv zln_KV+I_MKMpcsaTrO;(=etj)Tcj9-O{x5xaObw}1r+{sPzCokUis9^3%Akge$WAS z5(-Em3;DH`oC+g#o4Ie)bp3m<%J?C8$~X7RPR&QE?NlL5rPW8AMk_w#Llg$R;H!{p~OQ&Pg3y;dHK@Ey0w zcrJX-Ee?%{i1-C|YY%Fe{`2rX?H75zCfE;j0HE}d^muCjrvy7%VqpO1}{K7hI9GTm~Rv`xxw%S3P$hCz%{8CfFBah=rIo@x6AloCSNd2V8H z;YkNi$jLmR%WOM40MSo=zNa4^9xikw?!>~Sas9vssfu%xGog^hF4=`_E~u%;^Zbuc zmw0>5jfWa5-~k|DII*aAx^^wF<-M?JH3Xs+HDnZg>smLKeyH5+!yp_@u!Lo6%BYyx zD2OLvq~yK>$y8+2>B|rdM1hTgTkr(kNAof-u;d{h5O{s`etO3p* zmJn)5A(N*Toxm9@f}Vy`sZ6IGXD!OeUCjfvwswU|Vap~eoea@<)AZ&3wHG7?mtv}@ zODyE}cjs*EKoyyZQoo7s7J^I~cV@ImmvRD2$^uZsNCsU__yq($g%i`>0UHQdHP{UH zVL4R(*%0mGPW4CsI3CechwEZqu$B+cZ9Ty24fU}K#a4dYx=Bh(ihGNlgCk&-`_J-n z+OGx$9@~*VY|;Xj?ZjsPFBMwAmK>@c{b4_({no*39HDh=&!HipT{VhcP!*-b4}A-P&u z0rF?tj(s-{?=`rjoWT~2d{<8ShUT$_t&+W!LN(J!1ue;Z|5??#N5UES_eN6hth*xi z-0Nyjb*ndny@y%AEMYGc<+ow#48secwy(u2C!HU=FcUTFVTD%(&qpx+z47piOgjDc z`+@m+u!wYThhhVJYRkvjdzv|vnRvqYLaT-G1|^VTTFGmAPdQMW;Z!F5V+*^^paW%h zKhwrXafZn7EJC$5rs)w^anKK(6grOnGEJmeEf}{K3MI8NU?ia72WEy|ena}rR`*HY#{W$)8KeE*1e3_XOj~#-V>z^peQSyb3>*R~%y&+x8G83&t(0%$ zsTKxReV^Xe9;u5-SUlg#^7>xW^OCtB>eN)%0q9qA%_})wAATr0lX8!}F80TtI*h9> zIN#=-c{H8~T?&R16_PmK#4GQBHJK9)88)PM4T3!IaRk+76gg`#CF?CRu&k$7tX+Zs ztH1yp05_lg{be`N5KK8m>KN7%sb~#$S$Mr{&@3^x8^F8ZWR&x=!qK=t>OVo^i1EXk zWMtv|V4fiWP?VgKk+K2S*q zecFsQt`c3)(GNiQ29}lPHkXN;42+DL`9rG>K+q+b60FFDl{&9jfaC)CI^wtnK{UIa zs&jxkWPm`*9pNJ4S$KP@mc0!eP^CLE0DrgEvQ_6gIpzWsH#je^Dlk3V1~D!vGn2$> zJUKHn7N{Bv3lBa&xbb(kgA=T@U{fTQb$%WsBrR@2a$FCa+o{{>hV-0*daz$ zIb3#ftDbgbCRq~M7EvwS>Ttd0g4yFaqkt$$xGx1P5)(&pJ>;hrHM5~QpisGbTPa1_ zT$HyhV4NF!4WRdS^J`a|g5D%c8$LlK`j%L7IpdIq5@ALhx16tbg7yAFD zawNi!lzK~GY+~U=t%}B-%6oV%_Wfft#>k_CAnz=ovo1vdrvH4ZIsNPFEd>}I>|_rq zR^BBH^MEiDwGsU2%qo~9-&&xtTRvg=k8rBqz|Q(~BJKwsVd=o_q$D769DtsUq`7UI zO)=*+!9#=6e~Xjeso8p0;v-~#>MFzyc0c!^4xDO4Lpt6ZEyRv&NE1;@9(BQ+JKJpv zCo}bk%3+y8oWyqRGozSL*8jQWA&>;`wm`oK=PV`=oj|~araB{?%u9Dt$p6VUuc{`eeH#Ih@oKx;bzC>OGDzJvHKQ#D*B~`LuI|{~~N09k~(mTkA9G zCq9b&*fKqTy%Zcb>++n$G-?nZBkO*wW9Y*Gts-iZUASWlfmwq@h8ZIWIw47a&Ul6B zfaA7$HUfP56{lLGAzH0VPO*l-iCt%&(*mm7A5jL_1TBktIPaDx`2I(a!Guf{Pyo;c(%*bsI2b09H{z2%V(SX z67y{re8)h<-Hx9`C?#_5q{|vw3z5nZhmmdxc;Gsb3vmdez{3&xixktiXcI$Mtu66H zTIYT;TM*8iFgo(8vmR285|KiK1Q-==H7>?me7AEkB12y9uf9@^ua-CO(!DSl&8hcb z)cjdzKsQqrdnbsWy!(@Vl71yyYjgBwHf}pgVT$tB#xVIODIYVfONU2<~BGSrJ5p zTduP2-{$h<{M}VNt4*M90n0v6x_kdQv`@3R`P)ccdnrZ=WvSjx8i4!b_A+XHPZqh8 zT%DRw9c0!MdouJygxW*r^cEL$Sm3o_?kUx@P~K*COrnQ=EX`9iy=S zlL{l+q(1J_L|KEsH!47rh1dpaGL6<#2CX;r50izt*OG#)8phOKEQ!EpdCcZchvCdZ zD>iSIyeG`*V~BhCX3k0zIX9!+v{!F1DmxVLvAeytht1hM7tp52gqrA-s>Iaha()QM z5jT!jAPi~mY=02zY42pIo{3_8CD;YqiKjy7TD|YVgKS{c6#Kw@Vj&JBOypW%*%qEK z_h$_@|K}G&Ty=0-1Q97lyh-KVO)_9kD7{_8D{M2?qsm+@KLevGTY7v3wX(fUFH|Ag zy*6cQGr_N;tV>KU^*NBA#>X*yc~?>JvPc(738(6YZD{d*fqhk9R?)#1R(GwQGs2LF zz*z(2UeIsSG$dDu4RQM?G>({4`#jb$r+$WHNN)X}*q|!cNrU){Tg}!nB~k~q3WOUF z7uKs0?cPB3p7?*uOT|S*camJjAq?*ekA9L8hF-mpkWj}kknM!dqSN=pjBs%3 z>kyDzSAGVn=W;pDyj{Tjy+zDkS6?*rey#s6xk0PY|KxKgdF93e)y)aSL} zX@_bQ#Z{^Zop)keDhryLOiyhLuOYW!;&+K|+@5hgW3LW?PF&$M&BL|jFTqv5e3#!J zc;f4OtMAlv5i!|UgX0B#qZIHF*a(yEW@p7m- zKi3)rHotySGp;?nwvLe7n9qeum-yYPwxi!)rN%A84!mb8`O1JDr2JE%R?1(H*P2R` zJ&bV7lR<%b57`6>7NyyL$wd5EAw+K(uS!I$5QK zabk;6v%c=X#d*0yxY@E%8AcV8>uY3SfC9MlHz}hi9b6OF&lDJNK}Uu&puf${bdG8g z?b?BZx8&L??3g$UOG+BCAWe47@>_`69pj}(11}s4hyM~a33m?Qj=oJMHWB!s`%1Yd zXx!Gd#kfCr`Zd~QqtcjT)EGFt25#u`>F2nx1s@FUj?u7O*&?TW#;qC_Wj+A^7D-e` z9XJ0~&qdh>LbEul08^f6Xy2#gZ;&Kg?6SF7H_^XSY$McH{?qB{$71R(QnprRwVLB;BTdQIh8s0Wp9{&bOQ|oQZJGl9?qHyZq0_&{aFP z^o;WCJ`8Hvw^fk?Vekf@C?g`O@TGZls5_ zcI^3+a}Q@+!!Ge#=l{k#+$2KI{boro+5mz8Dc%>c_UqxwfaVR=IT~ewBzJYBgwp=y z%`1a%oM_8e0N`eoU{mZ#6UrBq5Wtq=0B8h%9tWutCD=&bgJLb=V6NgKXYg!aP<3V` z1T>+1O6-^tf#=G?eJDSIvmx{oplt?Vw87QpHmW+lJWN!G92mF*%;wyHU|kvHKyO6? zJMrQdR`>8?d<)@2V0#4)K-xP!p0YS6qEO27f1D7ABc8xtb!BG-8}_cUDvkg;7XVwD z_P@*3*!QB9CDV95VPjd8_kKWIREWC$f{Q-E1SjC5-vSx9Z1wlyQbS%zr%@tsG%f_- z9?9lpBO!G4L^Um;b#}%q-0eW-{I$Qo>*9EpGrIEbRk!x0TweroDY_Ag<;UN%a+qjtk*K8Sv)5kGVA~q1=d);Ki{)i zOI^Ff#s8N9_?+T$)`?Xci>ti<=i3d(;X=$N!QW8zZ;nK{zC_Qpang$&O>)6qJyO>< zov;kOID}AFMBHOC!^)Q#P*R+?jk&&^t5`s~7t$@h!17|RBi|U0vzjOQ zt3S|8$d--D0TI3mtN=D%DSQNOAHfGVAcc!MS`92CaFqgi?5-3Zm^c+rAWmFkb!XFW z4{A&&MXg#+96pTIxlGVp8Fj(afGbvl&dzoP!}>A9;nde0PIoB=fQD=1MNp!$r)Q0t zloBlpOJ85W9V8rPWr%SiR1SBPy_@qyk_5APPsQtRO%F(d68CGm!aK3R#0+}-Vr_$6 z&es;mLp1cwcypoZn@>Q_Dl9sV9Xj^&m3jwF2^OwL8~v< zHmcc(Nif*h-=30FdpFw+hFFY)A*CY5aPt1zYOvUVcu@dkiRY6_z(F@BlaTwJxCr}3 z+C8BpH^jW*CD(aXDLXTfj4eIn=IhDS+uN(6r9~{-y3>hC(S$woF4<`L&k;s59Ia9Uv0?(|nRN6JJt7}FcPc)+LPt31$NW1>_9tHE@30}P(NOAuI{TOFy z5nR`<;eX4NiaV=cm%1wbD0+Q#9d`0t)9CpbCp1=JVNz5tVKrV<{uqBXRGpmbHXEh@ zWYG;xLUQNl=RjiZ5jC$PQV1kSx%b!M2H}IU;?~_StS>bRgdWzsn$5oE0VavDv9WD~ z69NUgkj%!21=UBX6za_MB_HTAh7K$KSJK6H+i?zUT=xrpyrOfP1k^=UDKqnq=O=cV zJKcsOl08>`-DLH+(Wfxz{A?D>*BbfBXyhoQeg zZ1`M1^yTjB?wv~Xnz(md`06}L_cBQO%$q3x;!00WShU2qeSW1S##WDvov{Jt_p2co z6og1zLE^{Xvu=ktp<^90fz!B7!u7Xg+>#VD^B?sxcE^aNIw+gQc!h*6YKaV5+Xm~+ zYe1`Iz_M0!@6JvfDE65Lv$!5$zkQk>Pf?h-QA6>~tNlZN+wsgKA%+xhfxcE#cHkgb}X3)IRZTit>(QvL$<7K2i{Zx&>}vqMYSI~B5^ zorB6xWl@ocXjsVace)sysk8a5QJ;%;pulNrykxQi(?N{8SODPTD_kfJ+RTb+EOwm1 zo8#@ReXrAb7CO`F?+XkD`TuO@RrVf2Hl*Bcatm?JDz3Q30yIBjphzG*!#be1!8I_~!7LP4oERlwVIhJorpP_QvE%Xn}B6>`y~H~;`n zeWeRJ;E#Xb<}r`Z9jW6K=?|d77(oqzf7wx+2#-&W6Yl(b#{ELNld;WkK|CRZZ#Y9T` zzPtDCgKmMKg8dDbzlzwYsq0+F*o?nwAWC63}4=??T zjvPG8T@r`%aZlJVKM~P|*t2W0@K8$IR;v8u*@hPsrpt~bjZ?0Vq1TYPTEWl}BANjp zRxajmU%!@)1C8b@nDqekx#*6NL{Oc%PR=|q8$0%pa304wA;36|*6i`Z^+2e9{|mPJ%%TqGS<^IB%r2`rYi|DhO?*b*a3^i*{6; zNLmO5Hsp4dVfbyqCugzmRrhq!RbR)bNkD-L6M6#vEG0{|wms3e@HDrO>y%LJNt@Pi zV?Q~aRMe6QJXispB3_E};fDvJr!@E2-D`g9TMS?5@3EmLwJLf2(RV~*Z59;nk!a0u zS?KT+sYVggTCYs&?@6IGpd-Y5D7r#R6z;F=ldv;)VTIgtnJ`DFn9AN^;_}ZMx3l3h zo1k~yZD3}>ro2pI(;wzOCF|WO+8e)t%-O^*_m~}Gq_bNWzsc=?qc;qWWxZFu_c!u8 z7A|(pO!;YZMqOzVUN0+v17z?;uJaOmdM^KKC~4T8us6ikCEG%DhylDo@-20Yj+Qmt z?59b7tjfY%?GgMDCVP57FTtAJSlL;QGbMp(d2cwNt+YqmRzQpeiJJp*o*Vej+HFD@V zqv$=;3K6l;EJcn|7+Lklla_etj;8z0fP=%uY* zmh>eYlcSxHGuN*UJfQHBX+2C2Mb{y%g)H>d;c?h^wTp`+y`_yIQfdw92Fb$g#q!qG znXC9^c|ar3xOtjuuZb2~8>2Fs*sVt`3C#Q%BnFL(wOuQ*_VyTQ-bOBmn*<=d>`G7O;br@x8ZH|!59?H zg}<<06}PSqh+E203q)TJ!zSY0_YJD&@_*SlH=_f3IC+&latk(e+$wS?VZZTCG-eCC zt_+U9hCBks?x2pSYWer5+{C0i_~N9PH4pcPmzK5gZaXSO5E&OMMih!;?o^ve@*qK3 za)0KSKp-^p73Z~zle6@n685GzY`hbQS;zhcCk!=3w(ITbPRJs(czl`A@yL)rx?*~% zz*-B>$1dW7n~F%9Lhe~JH~dT$|DNPRcD#Nv27PBhl#cu*j(yJ_$`5}7twOdjE+TpG zUVLRlll0b*!#$L%_BpsFz zcHdVXnQ-kiTlfs1PeNn^el>)Gz0II{@WEb-gp&$!2Y(P(Sq|!_5h)SXv&T*Hg=^xM znXbD#HF-!u5&QOC7Bpq0ZZZ zMa)~e_G={PeDhr@we+ZGbCvjM!;rELw9(%d6hZaC)Zlj?V$Toagudc?BvU=eC1c;^ zGd$d2*&g^$2?%=T81#zwKk0;WG@Mf2K>tFxN!Gi?7x*TF>3f&;xwUZu~c#HUul_Ku#n?$XOFw;;;~lj%~_?W zr4V#gZGvU5NEf!3gchjPOYoM0(!NzOi--JN6Xj@%hsguGpR5U{S(UZrmT0~AT|^IN zT*N+5OjFR*VN=+RYkXUebNb2dPR?`Pj@)t(SdKBAJ~`J}HC_{*breRApV~U(gf9%aTnsj5~JR2g%}{k|bn)y_WwS zndj~Jz^=mUqe*x2-rQA28!b-xN^tml-l_6e$cVN7!^Z#d?|Oo_KQ?b zdOX=D&w}dBkTobXkTX7<>Ywy%(1)dPU~O^-Ha=G90N;ZO!vRgg&P_=zLN%5a zKpPfmsr&&G=fFrovWrCb`AtuM-yaBEXw$hl**I&hc=y6)oZBpSi+jHh?bZJvh0P3C z0%vP>fd!%knG15h(IPWJ>^^p$%KSd^dqt`h*|rg@H6Wnn|Wy0x^t%*_y& zS6GO5_3i>-2B`+`E?8Pwc?g77;9kjo{pJm8jjIKyq6e_a&@T_ohNz9W8_;!P?!Jr@0ev~>!pCY` zC|qW|w)_AIU#N2)|Na;FMCt&d2HQjirHky5krD8wffr9CV?picr&?h)84oC7(H6K} zezgTkgWBuo;Q!fytoVO^twPtPYWu=7%sOnY5%4MP{@R=74KB=bz(-vGHp5@RD-{4i zEE|oc!YN0P-v+yL-%WF2n|3zfL#)XVHtP%{q+ADYMYyTEPY)Ssr9)rC%bT}v1 zQP;z%K05!4i%cCn<#e;Uh9A;GYRiQxo43CH2NT?sx}Cv?5`%#qxkukc`TxaxJ^S$G zWP@uL;Oo^vr%#2=>-f`ib2+8R9%eXZR^gn8p?)klRg;C_l}kchWL->lnU6{q6Xd=F zj6xcJ^*#rXktn_@V;hmYDtKR7TG|15;RjIAT7OmHJZlZe7CX!ZUmS)B4W}Z+q5mV6 zchphrxc$4~0uSZ?JeK%2d=hHH!7O`}SQa^36vgyYpya}-Qd+ljt2X{^CM+K4=;(Nf zHqGG_=;tb~&a}yq@&4ki`XApOF-JkPpdpWI45~hvBRwfmUjPwf0DzX}N_k<^9R)YK z3v88nnu#1it9enML7qMaDzC5ndDIw#TM%L!d%C}}2ms%W3{fj5V2Jn$_(0s!Zs^oo zi%;HMC~oL`xEyUXBqIZSrL2z!UU`C!DgmO&glZ(&(An{JVk+Gls~>~{^mMU)+(*`C0|^ony8O2LIYPg?seC!>~0?n zuqh9c(kyfPsp(pN<`>jnK;Wk#|DQIlJRHjP{lBt}tU0z&D3yIl2%&}%BH4<_7-NZK z357U>Cz*K_wS!S=DJ+h%sVsh^UVF+_h;*U zC+jC<>Dc^vJu;KmOZEZghN+VOpJhxt1~(&sJZWAep}V>qNJdDg@{W42iI zg?Ab~J+Gq#Y!x`~&}SyppD0i%8jaCFpKJLI*7gMFWczyIPHNL;xDaNy8; zR~CeypPwM1oe~-rX2!H401Nvh=yBqInlipKV>=JIWOiAlL11@Z=}LWCXlP}sGKnb5 zM537y7ikY4c0ID$v?9FRW$pZaJj_yO_>V#&u@5#(3Gj@zph+1GP8vqRUTt}Mmz%eF zpdSDWlk2WUgASWDQ9_Oxw_3|j{oO~kUuk`KxTCtoBP}Dt4OTlmFmT!4+*>GGN__QA zvu-hBZ_jTCvh5w_2iLphckA2l*?{>0bpX}c^3wip7W<>o{<_;~vu0OM`MyB8qjlPJ ze<@a#|Df;eV=oyydwU${^eW5B%8dKhCy`=zVf3uBF zpGG!+En3}N9Myl&e^g1&l_;OFGc~K4sEv|Y?Jssb%r9l|+1Dv zi3K5mzbM>KO41k>`8PB)RQl*qlTq;Nm*T|u0~oeH`rpVTtP4#?^nvE`+tSjK$cc&t z0TB@}YJFNw5>-vX6JBsiA4i&**TalIl`}W-^({W@=H`}AEY(RqCkl}qj|#|S4D_}a z{8#S$>A(%z+3Op6wrAxDD_%tXbp!5*8qd?ln@ko4M77fN{2?!9(m*$rO6@~LxMq4~ zw^`^D0n)(6La2|Ns%iq9i-5BV2nxouwwlJp-FrdzBktro^g#qel%=I*$j0YMh&PD^ zk>)EGiR11lK|#Un-e!9!_4mlno?!tvlj-&QUDC8Ic`=_#eGX8UdsI|Zzr*)95Vw;~ zg$cq2Zz;nyErD9S*EX<%>v9>`lejP=g`=;y1qQ2k?S zJj~D;{qQw9h&FSpAy0_^arj5l>}1Tk=pCxu$0S7n(ta#jCv}i5p_n2-Y>T} zivwz|(JJ93`Rd>qaD}?9hJUsRu_mnM-j@)SIP&3HzW6&oNe(n z6c3NFt7{&I^vCq=tbccbvt!9?uZ`F!FZ1&8GB!4*K+)<-tM{$BC%=h( z6R{r|pPN&x94kC@I!cB@71xAlqa4R=J;@YZ{PQY-g9rI6d%{_k*aI#N-SFaT<2&uc zn;QE%eElt8W{cs|INO;BEpPx=~=i;H;xOy0awdgSQQ zy;gNRs4grj?ty`4in_i19N~o?klaF7J4OZ;Zsuvl{CiA%qU<2jsUX-G78WL>q%>dB z4{W4mh{NdUs2WdGdYu7WdU#j@xp3vm!rH*XBgmy0Ylfeu8ort5;navnQqsEU9&+z+ zySfRgNTd2Pcg-ivmX^qmcY~4{oJj4f9GjcPXP^|su@iKk!nSoK)Y(YduJQBovLnv5 z7qs7f=;+|Z;czH!?%2%C%nPr6V4`=>@T{8u)IGIs74$4O{L0cuuxIHt5v?()2Ms@1 z5?U*F6crU^+R7E*t7CS7eT^1~nVu7-1I^N~7_H?I9pZRK5rtB_?VpSC@Zy_0 zC1Y%O`)BdFWS{5ImP^!^NQK};3ukBmRujb3_i%A>0X$Bd%fg8<6(P`xu+ujt8&GWD zRoN_i&I4t3qQSeG)#kzl1bvV1nAtWdH-yhIWA!}9>6ytf^`rH-nHrfzCqu?#{iK2d zS)?lGct?Ct%GZ`ujpi)HClHi2=2^jPx(Dh*6kYz_@POk{Mota|B?I1?6VKDt)s=PJ zV{f~u+A-58nE*ybij<+jogkGY^PtzzU6Ty4IjA!|CuENt!9nB^lN^9b*awrxnT&5= z3FuSD>qDuY*;Lojg2iU+sGwv=MX&M1H@k7!D4~d-2xf@Tzm57@89E$#B)$R%z2vV zaJH@k=v)JI)$5kISEXa2z*&ET$>3h1poE>|zI`&4w8Aoc3!h)b;0k1pt-GpQ?&@tQ zmw&F@S;W9woFr3cXQ1OQ1D7GHZZD7?rI?{wB8(0B`T1y;rJ{sQ`H+1YE}1`hhV zo^C0-yrQBJ1ab77SirN4IBt%`x^Caio7-%Gmca8;iL?4}+QlYdPtAofAB^=e^0Sen zkU``K)Ij%8W*ug^ky9#w5hfqqacHw*jV95x$?e99FP?|2DxZrRKYyYjA`YB?dUtI$ z{nxAN#@NgXmD=Q?)_3~*4}YgHj}mOuwx%383ArcO)V-^1(T!!Rfqx%8dPE+6UV1<{ zq3I6uG$~hFWP4zbef4K5c$y^D0I5+VDpkQLI5_wZWnj?QZ?xh5KN?=M+R*vZ#s12E z-2cDhJJ8%Z?JWNRUH2%^K6~VJRBm?`t^j$pOd^rQA&=&5B=wB8U0i-*&`uAO-Y0Y5 z>?=!;`EL)N2Y7+w@MDi6r=@TN7?pATufJexb_ln$>?np)u!gDY@KNn+kO0rkUI-=A zzaM14OOKpB4ZgXh6UZWgK)}I`KMD>rWjA-H@nr4MaVT~1II*vY(23t1{jM|qB|C>| z8^!dT?d(pxC@&`l7rdI8pZ5iyL$n!j4NF?x^`k`MB}I_=blD>8<;$0^hK8P;febp0 z4&RXg#xj`X+@O6U1sQPB4?eOiU-RD;3S@A@$3E8A+iS|qc`H))KLq-vGiY=SPOLeT z@G>kp%nE-%WSSJ!p~F7{u}PE>zs&a5yRv((^uGipbOwp!8^CzR`WstuJ%${0c7i8b zYISAhv5Ja{iG>Bh-E+K5aS(pY(23B+@WcD@s>sz|Epjs`YF$aI?nu-SG?h>J5?J9- zdgZ^fSZx9n`_!i=RzWvzND^KiW7!(<&G|v^rr`qwPcxW3jl7or@zEP4Y`E4kJIlw_-42nI2Ab4eMHHz{G9{1Wz>1_tmHLs z<{GHR;~ffXbuaa>-V`hr-jz@BIe9sLZ#MU zBo;h?&DjQq!h}?-xle)}Voi)(z2%7nsaX#X53nR(LK;%TKXz)zXIzd)9g5pJHodix zmnV$}p0}E57WDJ;Q(jwEKI`o*&+N`XvL_agv$HnGaxTea%eX1RYHUBf z3ds8kEpm1H(iFb)P6V6;%T)}R%w}QsB_1)`B&b(Q(#cbQ-#k~E^Ycht!=CXl7)-zb zW&O{|!2B7O)HEAO-Cz^|2pTW}K`xOvc}*EKCbizwK;GD#M{+u3DlM~|O^8r@tP$Bq;ai}=gM!$WFhVx?r zs`(I*d3FpPAC%rQnnthZsrbIYSGX%W$h0GzT_Xu!^=^gE(hIqJ!lY5G2)%Cn{7AkS=kW`@f#V*(y6djcS4>S}g8oIqb8a6nE`5l<$QD=CzFpBut#Szu0# zQs+4wtNxSMCkl__67ERZ{)M?t9Z*9eS$;zYEnr66+Kpy$~;!$)`7IjZv{v)x=8ZC{nj&XPV@j+*?U2OFW zsVyECDu9-gnaq$i<3qRdGQx@qy$xC9*aHs2ef0ipn>+{r#Q*b`&%3faFVI%HFJ!G5 QQfCn}%z5Jyv}?@&0X8S%hyVZp literal 21997 zcmZ^L2Q-|)+wZ$p??es4%IY;jv_x41L6oQwEm5ME=n*!0NR-v0mxxGoLUfx*utao% z=mgOvdf7Yv-}l{f?mhP&XE|r>JMX;DJoC)_%IpihyXsWrm&qXrqSDk*HGm+PFnF1h z5`%Z#@7GX*Kg18U)Kww;#ZO+#yCewWf;3f?4gIs$vjhB%Mn*bjo<%BYpwYJpLg@(M z)acjqkRhEgd1xqi9woJ5>5~%Dm?zFcGPQ=K1hwS+!!SjW&}e=^HCtL`qVQ;qWMbNO zTCN5M|2D-RWD>}PxtyB5mhrY_+$EhaX70wDmVPwO6-4|DE^{zBi0w^^a?vpq)THw38#jqEhm zuN^bs!aYuz85vG~>p%6q!K<&gSMBayYHy49lFz-F(vQZg?Mz#PWIai*Ve`= zI!}-OUUT@7^)r%+%|LtTfvef*b*PAdpWNsrw;qU`Vd`d)qk@~6@kv$|yTdH@dEnM` zi++i*$ao_Jm6%j?I9IfEe3}WK^kIM3<(bt+;C~r=cYK0jM4d=jO-;5(vUgde$7!tA z*<`sW({0fFlbeY7y#@v*rib0h0HS*rPgA~`;F@x(R68G%?JyUen3%)|6{>1J*Ssx4RL1r!b#Ly3PlE`I z2NJx=%Y&qUd4#3p=C)1MZTx^*Q_3_wy+NRpxg~X;;>2H;fQKy2_3U7+-Xr``ZqXzj zbm$>3CgxsaXT~u%Wp1d-qEiQ{*&e>3o&U45&^Z=uO$6=z8EOC9r|2%}G+bQenDG}H zP6e&nf>t3VX~fr-gPD-F(f9ZG#_yxvDu)rjmUP58X4tdo4CN%3se9TE3*;9(w_)M* z-I~6&7bm}2oak;ObGrN-OgdxD_tXsOxHT4&}W?R0J<5{QyT9I7%c6+r*BbJk~%BR7>wbE|W8 zco4Yyw%TV_5r0I}=(`cK)RXq8H$%#xR?>Z%{auz<4AHFMdlZ9R0fBMvTdf-V-iKyp zW(I1)=5>^^vas{Y1J2=_Ko)KQFHgX z^OLPkP>02z9sg@@ZSz{X6ZCID9YTMLWnTD9!ufS`s!3&}9=yHM*h+wI&JIyaFOGR5 zl{N$`1=*0+pRYnPexEyRL1ty5w#3NP^pF{%=^lL}!y?uGp&`gI5y4_*RQ*vTiG>Oilj=2(U|x>*N)wC%?6KmeQ=cN4Zll82XnS@}poW zU_wV!@9}rvCKCSE(^%f-H)i2yrlzJ=U90ivSH0)=zCJNe_GRPo`wUB9l?bhKwWbv3gOUA!5j^lossD+bu zV^4uv>~@sm>1RgNO|{($aM!q(U}_uOz&tqH8?!o?`Q)A}bFyB8Q1$9813`T>Sg5&~ zDq?Og6Zg024W1&xWf-I9$>pBFzQ5VDCHJV~rKjs;Y8jvSMOvMnAGG-?o^Go&6&4n9 z;1sH*1meJKj5$lt=1I@a&E@Rr>Z+`0_q2V&?g+&h_TeViL=(K*^Yxm>db6 znrzznC(w1x;M>)iF0W#C^$9jd_}c@-#esek6&$ z3t5tQq|rW1!f(iB6ut7ZI5__ML%y%!VEXAEuTF->(0!vjckXO|p%Am4|N0`1cAl-L zT9l-+t~8e?Kos2u9ZI1OV7~;yO&JRwe52EYl|-U;{UI8Nh1!}7Jwt)$7E&4+k?ehe zivA5&vXLliju>L9!jbb5aj-c6#p|`WO=zuM57VS))(Pw-i8aT@%<bhGu1;5JGWFQvLA^T}LR`fu-Z|m=Bxp>fpDQ-EN`1Cw;e=tK~J8mzL&UNl#-l z-CG^ECO^?YmYx;|bcTPqujAyPO=5BKX@xNkRJ31-h^f9KsFARQ?*!u1SX!tC`W1v# zFf!7Fd8FI0eEL~8B`YG*yE$5xIneUd&vVqwA^&c++(^nZ!v|yEK(!JNIS*<+*=(vh zJw0U@lKd;u6Uc;ZgIr#`yM^KVoawq3wcI%wPCN5$D00557@hLpEHY7!;=JnwtEzk)C_gjXpxVyStTvdrrbu zt-s9bTv%gcV_zjFC-+vFx)7t&Aq67Zl{0R|y*YR2K6dibNfK?rZ_BTgbc~f42FwQR zCP^L~9fF;dq<*9)Mc^^b;rHv>Ka7^BY@0)0&ig7;?IE8j*U{4Sk&lk|u3o=>&waR< zZg6NQF*TLgVhsF_G!>4VpMUuE;kEVY7PiSx?ww$k{R#~wcnUU)6VokEsi1lggjlfj zG}r3pD(Dg%vS3XRr}GwxKLB! zeGW7Mv^KZ&;+a~tJlX`xLdY*+t=tret@(q^+?IQW3-yqMNHN|cIIavCb@W^%G7g61 zz_`K#Te*&iaARTq!A4x;>5G>!Pc`DW-*2u8GT13sU%}!2y}n(YuPP#k8$rG!a#@zZ zh~lh>9N$SKllCgY<>qY| zGGX4GOvH@1Xys$iW4q&zv?|6l>~AY2t&;TV$>kkuSz~U>Q$9_3UU+-gSMjk3@A!St zB#Io_$I}pJi@>qjt_egeQk{Dht3}^Xw0r>F00fA`)j4@xMY;+aKAir)x76;GJP-b8(BQ4u1zMwU0Pi#vk)`a^4T6zW5*=XOC1Vg zpukT@(h0vbb}7dL1!EP3erZ?8svvigB-;4QwCYm-C{=&TUD(g%KQT`%OjuX;Vs6oD zBCE3U;X-C6{LvQ-+s84qpS@FgXwm*Y(?iszuNbmR?Lwfyl z3`z_q8E@(N^^)zHJ`z*~WzK@mnb%xn>eM^~`;i5$W5#A0S9Ha$-N;2SXc!JFonFc{ zIZYpt0>~vw_2#qKT}OK(u5@KDx)x`1*NZmjkVB`xK5+aC9On^!kuk$C5>)kPwyj*D z&@bw*H%Kx~2uF;>Yi<4MHUn)i^ZF78EK2N_#BzRA*p^;^uih;zMjSrnvpUQiB5NB{ zs`&1XnjU}`_$^fxoRHE&3&l8B($=ZuGMiXQNz!$oci>wiqBxqhs5S@ zioy*BbxaYq8l#9KvKD!Z@#?*=Y#8Q~nvyQxwfEHjKwsa^e%#jtU z40%x*wK!wz{DK)Nw)k1*94*2%ZdKPRo|m>Q--DmhqTW_}x%dR!=~4*sS*zlkyD<~i zF%n$k$gzRLf$SJxex2J#(_^b))_$vAKgGazf!Wvi`?!1P?<_+>1BacxjL)hhh`? z)wP7M7Rs~T%9SZ~XED&Dey!7IxprbNXpjO=KCXyR`6ZmzfQZQ`RlmiP=yadh|GV3{ zpK@K}(Z7A!yGdo&HCCnsf|AF(j2`NbX(toEeH80OEv#k`C z(TT)um-GL#&kR|fI|<-HcJ_=iBa!mQZ3lMMwfrBTmY@lDKjgA#I_ zeiUKZt7<7CsunhyZ`uiL>|{fqr3tUV6NqL}2tvD9S#m0vByj?ai&04g@_~LrzHkp{ z9jg3>_nx+=dd%lh)zYs;CD+@@k)u}MFiYV;XB-do#Qh*!+` z`@8oE04W)7pYE>*&|qDl+|O*bQt4;soHty4MgX)Mlnu6LPtK0_s{D^b`f_d+6*;Ds zul0!ZWJHl3<}O}^+z31hXbUt_zA zkJJai>z1@MGawxL_YS9C4)|~YO0hFp;9jNos)6wRkNn1ZdI=9Re&6V+wj|n?KhRZu*p#xe7=FA76zGF(gm(!ncpJ(|$yz^yl$cRj%$4scb%r`Hr>+2+tq;6W z&(y!dA65ORlUh6HCM#flo=EAKJDQDpK)F4mMr6r&Ay|vE*$lM87w#{_FK_hrHnA|~ z8PrTP`v9Suz?PLw+3qiL>(<%Ni>6uvc{VL3{%;EM`AV*!Al?Lq*@B8i!dIBS{w+~? zMPV9zx&03098Rm8N^nIa{O}%Nj(1kx#Q&kXj0}GC7;`w*b{+x9z9v-k5y1UqV#*R1 z4>fg{2HN@}FKflPwQLfV!BSZc-)3)qweJIa-7lqcLV}ySsvgG>MnV%wi(C3_RAM|= zH|bUb7^>RO)uo$Ia6;KCl#DNV5hAtW4CRs{Zh!qdKEl&*j!}PJ2orlX2S%?M2=!}JBbV@pyYvvn^hjlw-Xj7g zO)BgZWXXgorNMsXjG#4%=Tx**TzHu=a9n2D66k+^wEXJ!tIJY1be>#UoQ}VD9{&b^ zwkC@w_ITEu!%E|%jV17qMc;#7Qp}D|h0`8Phv3idzq^}F;2-4e*q;Xj2;VlNX#Doj zM?M~$-Z@PNUJR0XW$TueYi{RcfNf;PuA!nU7EXT=N7^)d%|$Rbrdb6CWN~J*NV-li z#NXVFo@?CPg2J=q^G-Pv@Da4Juu=jKi{>0N3nx`9_c)`{Q~$KAh2Gb4K7S%u%3adMtP_9^e_-i0G)2>O*sch+PS8ykuo zXMO?b{TurnzHquyeRTS_PhU^Zqkl|NN9Fcy;>*%*FW1-C^}Lh6{qD^iC@~T1tlN-> zZe9w-^`C|C1Afu8#-3`l%$x*42tcprgyTD9(&u3GyjS`Wk|N5WPQaWv}#= zQfn%O!J1Tb3{^y!7rVpe015E2qHw1Bp!{ATh2W`_Ey zuq3by%x^rPMkrY&2#=1A0Q2(2rl$DxH0Xiflu!M9j1X;I9oMPut{@~v@K{)$Pw2ga zDRKz*0OXDgi4e46Kk3`?HqG+#a_1Ee1mWP|AoWQgh=1_en$?@aLP8G`a|XdCUHUL|PDFo!g`7u2#BRnKH%(Be?KwL|nvMudD<$IVvGa^cd3G z3+me(EH$fn{nG4vB0mSx=TFz<)s0^bHR%|PmonDA@DTqlHyF@S&1j%AE&M5|5ItBH zZTV-A<<%{K5Il+SKbdjY+of*aL8jQ!n6|^dQ$D=xoMFFwz3=9Ap6R|a!Sc2FH}MKz zel1hiDi{Jr1S?{u(LJv;GTTwZ=O)B23% z+CxIO)+77(%)w_#cVM%G(DU^GaF64?X`UBFI&UVqN3v6KJAY zV*e#eMaucP|02B=qt#7fmUEs`198B#$yWr>dJzt}&zQ7Qg+I5`C{miiq^@3l^G`9J zsyk8`pLT=LGpmbn;g>G$IWvmkB)jrN=^^$`HxB~G0ENL$?~&4JXqt`r0E(OA)u@-x zpJ8QC`#pN4#%5bjHrrzug~Wk?ux)R%E5sWUZWCvfzMkbp&t$su?tDp?s^g`=k5J74)aE`9`nq3eJ9}wdMZ=R^VM$ zC@2M7ii(^d1M?>%r@4uV&jAC+3WoFjyBxXszH+k~UZfGprDRZsfSM_Wp56&^ zv(soqt5u6OvyT4b+W7jgO3b*zQpE1+oBDc|$xlz8z9;#8>@wZVs;hV=>21+D`#H=` z13p{(VNkLcg;qPWJ;s9syB&Y!);3_<7xJU7pfojc$}=;~0oShtAKC~6m@3Vl<7v=2 z!Pma`Yj)@yXw6xiXR#L2VJJ*WO$VY1ul#=T>q`X1&hJe3FV(^j7Th5*B_#svw78|D z82Pfj={KAI-t8(StNkyg{)^8P<_+F^Bw-0KYW^YfFZet_jem4{xN}i7C+b{dU%sRa z0&hK@YLs$oSYpcZpMR16N07%F-xoRtEeQM9l<8?UmdFNo(wLCa{rkA*4V72|!e39U z{x(OaXFrhON-8V2#h@#c{f4%uZO&t&i%UzN#VKta98`X)WKiTP1b=mZV>IxZN^hR2&2f8rW?}&Zh8?VY&|6z-qM8pAQE;6p}K9 zeqY4x%|;b}e@|a<10AP)LiQPKQ(W4`6>gL22qfca_>lNE znpt5?zWTB)g=reWYq4ER6N_^}CARwAXtsyw1(FnwR-e zhR8HNk7B_0k$41a)a@r}!%Aq-Z zD$$Y9D}?Xa!H2-I?o``o>_bRR?5?@9)yr)MleY|j6Lvp8J^Jw|{ub}qu%I?jw!@!p zwT$hVYq#)fM(&0jo{L%dM&9q_7a(9l--EH!%v!v-%v4`4|G48NYtWzf@057)^=8ff z*W8*mZbU75kNK$INquw5$$hRcdLPQa5vrYv_MvNTRP5nd^AB6B1UkaN1=(*g8Ruv8 zdu98F{MKv-o4dE`Wbl;Flru~ff#SzU^`M~acFETa>6^%9*r6urHH|u^+?kce^N@Gh zz8Ob{3-N3qrGfh4_OtF)+u4S@|IRmN*j7x(RP^miIoc&WEtf1M_Am5@0zuFe>BB_^ z*4T7%_xo}tb*XUwKF_Q;Afum`yU(=lHwXN+U3)>1dBgP!m@FIb@4aJcciy~4KR{uO z-VHGoCeWj>Oq$ozIAmqQQNWr>^4`-u2GE4tCBJC`h0XkIBBeT(^?R~L=xZM!+VU&d;yk3`-?hfOiEvacd#DWZe%wyg| zx8juXTNR=DH(w>{4^S=C!icGCo#nvF@qa58b5e!1w$3HUZahrcO98zVK|2;3i@hys#j=y;98Bd|V>#w(r|Qy_{O z%jJochV3g;l#di4jW{BYD%t{9mVJ6T>qJS|I^>Z_JD&?ktprJ^?Ku5FY801P+i{Dqrhcc~{E zEH_p4^*=QGCt45!0?kz+HH7$bIKV)J7!F>cOLcoOvOV%l(RzVZ606s&MS~eW&%@z@Os(D z=45P@r(LZ?SgUYa-Ja1)T(z)|&;8DdrO-u@Hj)7K6JmTU#&r1J%f}^saLg!kybnfH zb?9RO5Ro_8q?`=HuK$pEB!}LES|g=p2v$3?3Ju5cNQ#G5Km8!`gs-3!v!idIqWjk# z@lYal^VQ2;MD!zU9cI+|aH9npmKxJ{B$9KSUu3OLvtqA6R$WZ=HmT50irKO12!2dP z1tiJE>Tm2;KvJq3L5q9ZUYkLRc(@&!3WP{50g;2i!2U>jS?e=$?89+xdUSj~K`OV> zsloM0XpzuW2mxopNkV*ZQ-rw|!S*#Y6JSG`3N)N{A;REWqTs*H@81zu(6-KZ1(9rDveI{8O z|CTgnFowQ2OcLV(qfpZFr@Ci^{lJBa&fY$K3;ItRPTMq_5-5kzkbl8aIRW#So$4_# zWWTsBLq`v`CO!c>>`**2FwD}0K3+{nm`8Iv>cdJXCkRY=%vA|?uQmT+&)-kHH_Q*7 zB#a$$wvE-0JYBowoVQ=a@VSai$v1(RUJ&#OmPNWnYNQ{a5IWImK-ftGWgOQ2AwU3{ zquDxzfU)vJHy`AsS=0kUcITX=LVn4_sz zZHSSD0@#4!CN9RCqK)MYtbdZ_1?$o1zD5&mG1ZgRMlsSTfR-=b=c-(@dcjb6=lbKeqz~M(Kyhn8 z>WrfpG&`w_S(%_b0rWFewBF?#yt16_LIY1CFGgRbw=yU$D($$USiyPDHSU95KKFF- zE#ce+*eSocs>Cd(V#zaMHQHju$}OIIN(TGUfd zwO0@M&~nN?eVT>nxAvwxc8tw_Dz(CfUz4)Wmjjh=-b4_ja+X~OTHh~PRQ-12YH?_A zjDK}Ip1n)KcoBf+u*DtZJ(|Pao$c|KLfCDkdniu)VrUGd00mvsKjGnOk|+4~dVr&EL|BwOyyh%OT(4 zMn7n1Yuxx}r9KtvAH0|vuCPVG?><`CE|eq;or*}R;gnUNwE46%BKY*#cX-uoN~00~ zhtQ=E>ct5YL-^>^ZGw9N^-wDls`#ze5(~ww7PLi`79>=amZ*V;EK^CS(ni%!Q zy;6}iGSwDEY6E8>7voQfA_K-Sqj%nsj9uscNO)?WFjVE$`iTPjkG2*`g^CuNB|6!) zHzRP;EH36g&*aumvNu)O%3rsdAP`q3)n~8Hv7LuOZ2H0d1~4ss4i`d(N^S~V;Q0${ zvv=V-c57PR8ad0kA5+zOWiiHIIe^${dFgA-Rrz*$)H*>WJ4r6n1T@WnDkdCs;toF~ z#Uf9um-V_W5vuyEc-8!3{u@rSSD2vh9iMxc;8-gjN6p)}34T&<4c8`@VLtL>NGPN{ zXeglH^J!MUh_+K`=iBJ_kc{WT`+@AIa(V|+j3aM5h)dr>zMR{5!4$*~QiMJHP`a5p zox(clfm#eQ&z@Kq5e~P`!M8O*-xK)x(i@1TImD?1NwoBzJs@N-FYrAwBkAwLcR_h= z0JfQnww-zf0prS(K82I@AJG11AshWbvitfv;k1g0&5YQOoFS*4V$Hu9Shvrw_{_E3 z-T&gOQhr(?bD5V~@w?_@gE_{yCL-(;K=}tXAZqrgJ2|2)4 zfFma&Zo%8bVoY00tLA>KQv@(0{{4DMSJmF0SK|70&+ped^MD_!Uy{nv(ed%G`fE2_ zC&GcY4iNwPuZBwiM*&ynq@JE0+P&>8btdTVt6I;6+wGq0z2Yx9kjyf1*EzA1dM6T$ zyCJbmA|9tZop7x3`Irv}0G-|V7;enFa{C&dEKdM~P)3pC7BJ>e29JN&y^)M(G}xhVw-f@5&U9a#1NIJy zM~h>|0sQd={26Eq3GoDD+&Q2+0vZA=48s2VYa0=Z#$idyN42h#G%$aTrLpNdNYG9q zx{$&;k9K~ia9u0s6|zERj2MxW6C^ zd^a+j%b(M}$o0KvY8rj*QHKn0YcU|z;r4S%-v+womCllv_L#0#)Z2Us-+L@Hp+$Nl-(v7q3^t*LMw+Xg0$qzI;t zlcN+eQxU3mQ~xhye3Dtfei`t~v-6v|mhIte7>x%oddZfrwQk7#NRjaximbf2`4vnr z%mwP#C#5?GOOCPBb8*S|O~RKO(9-q+nt{$<|=SasOV>s(}4oFi@WY}zBczJFKs_4VbK>z+?BvHTC%9rH1V9V!qe z<)4HM6sY~IT3C7U+oH)=&B@7$G$vR%6whdcUd)EvE};k|OnWkI93yRh-Fn=g*H26V zWdV5K)z{Yv{8Sz@&kk&WwsRpZgc4DRdo61GTN!`@-`b4LdPs{d@dBHAYiPk$Df~6`8XfG@ zSKk5e5L3pDA<2sg{RFu4#sKOk{+x`gO@sN^<24wVA#n8fbWgKi2GiuCliblc}J8ii=U3o*1uQc*mc zec(H8SLxb>K$j~|yePnHu}avIe#zS7&@ct*5W5XewP9iQ-uxw-aO2j zZj|V}uLH&4ruSq+Lqm}biv@usohDvBE=)6t*9NeP20r1lA!>WYQ3(f?)i6@lp2Qe~ z`*-X>p=D7B@-MCfc5BuAwPQ_~+o}2&JYXXxx6C^|D{b0|Pfu%3%PkRyR{FQ%h$;n( zqtX~FqMKmr}2(WN1XFa*QvJcGuFpIG;@4L2Vz=vxh`M4hfM0eyu zm%u&7i>wW|weWYZf6ntKg|V^@9{n{~&Fm$cH1!2^%=Vjpk(HIzzroDJgc|zDm3_$( z561%POlX)-g7o6ff09RUkxN;ZjY;<2Z}N53yAj{@yVo+ecYc1pz4aXEP4mE$+5r~g z2mt=O6QU~G&L^sbodeLk+;jM;CK|;HFZO3pQMkg2n8eY_0XB+R}%o zvAp7RK32?2tYHz8x1Nf-m@{_W4A3-|^`^f#nB?#w$^13ByE1cx+PMlG?{Wg2iW~1B zUN8z7*O#vmk0X^c@IV261xg%j`z{#?B?}t3e82cutWVTZfVs%=u!;ppK8zpA4N$w_ zd2Ek!;S{Dz7QyEW*E-p+{{d+$E>%{brkRurK=j-MI5C1Af(0?=2`u3yNC)sSf=XU8 zXub&A=Nz7C(wEO`0ag8IfP3$@FV_WgaL>S?RcSj6;A~3NzqSG=!i+&EnX~f7>!OAg zK>izy2PlBL^BJ(`Q@|w`Py1Z}&xz^+bKsRWVf`F6dpr1VY9W>5(V}C-@3xEI#4GnYaTI z_9+g-qx|OuA#w-o$7XBCEZ?j(nh+eS0y!^4ZP@X5NSrFxi=&ejaG>AmuHLQ(-f1#} zBtu|z2dOy)*3JoJ6m+OKo{@K25v}kRCe+W9Z}}qENAm}v9=_#ZS{{f=gl)$o6$#qu zKQpD>J9MO{Y{e{_>%aO;X+h0A=0mWH)wV~4=GHJ3b{rM04oJ;$lcu%CO-|?m9;71^ z&6S%!yZdOoiCHd#SX==TzeC7hP@iPuhUl;-)lwNUC6alxMqM8OGmc81CVLtJW*;gqrOfH9GBofu}l_E5E3joAX(lI3Q` zz`!tjvEB()G|$V#)%4VDs6*OH52b%=Yv9L9OxzCu`vXq&WC3$N2Z}W1TTWiWDHGNf z@zpBy^J0PZ1aY-WJO!~+NS#nFQ72nuE=aOTBja^DI% zg<~z>&(CZ1T<|vQudh8io(^0qy9)@Ut6L!$W&(dYEHPw4ifBy|G}d?2__N(H;Dd@z z3;W2p1@3hf8e@(0Omdyn$&_+tYC4>cy(d~fOYqTgh&P$12Sle5?2ntl`k18{(%RzC zccoqYWxVTT4z%@8fT=z@0TIBBrV;L$cmnEc+a8!L)LMl2Bp0GtAOG}0m2g^I=BLE) z1Q+Tps%001YTkISGEu34B$N&P)6&#rrH%b|`CU=bghNh1QCDy8$mB=IFkrNuuV09h zpLh}%y&!W4G>$}Y#34n<m*RRe?KE7JG&R09lI(dq~-jx67grWEH*irVYu9a4OG{kH4ZfFou5HK^b8Hdflzz; zZ%FqCjpC{G^73+K+`{Ak7-*VJg>TScJI~bztya0li7hW<;~}ueO&%*m?4I+cYh>{FT`u+ zz}#QFCa^}+q8N!{#gUvO{YIpTLgumF8kU-7x88D71CMM7cLUlsQ0YeDVXo~hjC;aI zjqcUJ{9;<<3{qC5E>0tlz<502J5NLQB0J_iY$EY@2qtuKBe*{>$=14;ioqyqF%1cC z!6bBh1F~I261m9Xymt=6 z{G@SX8X1V6vEg{lE4p3?T#J*3DhYlIg=tGIYnC%tvrvIh@{oF?AdsNrj0| z^ww0+l?Z%)Dn*HD+lL!p0>?#^lZjtyYwUA3#4q;P5DCq=EdssR026^sJJF0K*Gy=R zTfBnFw`Etwrs(48D@7x+iw*E)ru7aHDjr^fp*R7;XmRt)akcrj7#YJ}a_~CtY{Ry9(UReUFW@s&QQaVwyn6peg?iVxlCk-#dQ+LfRI=e?59JQPBw`YzW~B@$ah_7RYf7A$X@eFr3_G#NYFQS+tq6lo;4-ui(J^E7K@1 zG*QvE>okF5HqP4f?*Shp15VQV4&r^{DIbm=^UQ8dmLB&z=u#-?QQ3cyyP?8wbfhB|v{Q#PTf;vcfcW;O9LpR6~zJT|ZrQhSov6aKo zXu2WBjq7qgV2aNxsKL0XhcB)nXOhdVVvzG_M7r|sy^sLU43}FY2)Z*)G0>@=aN8@m zDBGXLT3=*Ts$tEefcH48rA1BI>*^V99JV9IX_Y7-Ef7`Yi+|L*yE1_$iZ?JfHS2Qx z6Ex0g$U)G~64vK(X|M2^Yaun0VJg*hEvZv%7{{Xo{&O1mhjsr1c9q?yX8R);aq0vY z;@L|OFIp7X29a6@glO7_1 z0zwVsLEL;RE8fZ4_p|~MP7>j+Rt?ZZ?W%^5)rT%tfuoYj$!B6o8Lv5XC3H*>n4@mDtSxNb|Tj}Ay(M` zsq))lqJ9=^qe^g41ntAerW4fRwrtQA{3q$`L&R56R=Ihdf2k?w@r zYK}zOYC&r>hlBP|CL~GJPk|i+6*RI=LwQ%o_~kXszgoVAl*LZuT6aG!QvV>t&<11I zIi$7ZL35Njc}}vLqLHDy``k9e%=j|KZ)lQPhF+AXkUC*qsiL%l0JCZ{NfX9@qDW^= zZ`XO!);VBFLXEp_=bS=}v$s>-SIK5Lt`fvOz)WiXK%`%;JFATTfWJh>tGVHivEt;h z{-&WIVE)c~Wvcy2w`s+9eG5FYd5&1;frX9T@=RDF1X4&b!~@Ke@1r29awEG z%_aQ$j8$dukfGLaKBesQysX*Wr^mj4OSc@fpsn zMRiw|cP#^Z4XAl;kL(;-uNbY~^zQ$OtRTaVnqFxhSnn5dY>r?2n88qbhinKh1vAbA z_tO7&=acHg_~hyJ%F?pu+<^k(F$Nmc0_|qkIvRw9aF14c3#h;G91->W9Qr^OzJ$*p zj8EXu-3^+V5yg2*_@tt$omm&YAdbw(C%8#)jW_+}oUWk-qyF7c?UC>B(^Q~!&wQa| zdS3BjJ7L{FFh!wmCyljCYd4E@#l@(DZIt^;WoL;DgsIp`(@{)YT=EPK4yY+n2^($M z`IyO1xPi~0#4Tuw7Jh2J|1C`VlL%%_K=vp(iZA}YVcBX=)S?}Uj0?>|bKN`XCb>a@ zuIHx;Idzww=bc#%Ash#_P@>McT}6cwU!xxXV&%D&7-=gKC_sdi<@wR4kgA?*k#ct+ zEwNcRXaCZ3uCof66^Wfh%Mb^R(fW=tOeg6B>6nStH0r!Wd?F&ezYUyT&NqHyh)9g2ss5X>5~ zza=N?nQ4kS+VbB@_)fL{DJ|X*Kjy7bG}vToY3a53Tn4Fb{P`vN;1dghbt$kZfRnh3 z&Kbs`D(7+P$NrlQ%fA4Y*u1XuH1u`&e8D zr_KNi&FJOj_5G6WO*$Zt0{-YLfRABd7pyWQS@`xXFpyCIi%#^nhZp9FAKCI%u9G)h zChIQF>s}aEj{tTs1yZRbd*=XU`%h)B=L<4_=cFX2yz^KvA;jYJZQmzIl znaa}J60`!~Syp)BmWf+P$QeJ=0J!a9qY@?{@ah5J4z}nmPY*6&@dda2$z2_oDKE?tQqH5+ z|LtL}0$b>NLy}r!drPTyy>M|htiyJPULGMwr5vn&Lj0wW%j6GmZrgJ`>&XvI9QbAd zH#bpWCVY?|MT)?Z4<|ffCjn&4Hy}q>fsMHX*b@H&XF`FSSFoqr9(s+cCR9>rHj9Mk zkz$9S96FRs#UHWD`rOMQ{yr%TKW8ZNIMK@66E7OJryo#rq%onzpe&JaQ17O9pvd$h zS!{J_-TU|NeSvXL4ZQX)=<~%zrLl#luRH+~G6e_mQpK#|Kmfi0Py|rSF907)AWPzH z#|KnblxSf>99X>}N%vael08knY+DQO0X2JYBDep8Q3>=tCEm{LaJ{DQ;tU}ey)jWi z!NK#Rz7V(i{RwA44ANmuAv^^^W!@7J3^3mKEZ{2)(d(zC(>}| zpzhA4Gz;hx8G`rFs!b30P#%nJr03*pg6||~zhLBl$gK&#wy!s_9ILR32Nr=xKeA-2 z03TQg2!o00QU^#oLK+dxwnJ&U3YAOi{0)Yvz!7x8|E3LR&SU+%nW?Fiilb{6I#$szD15cU@q$-Oo83f{INM-L0;3wl1B>{3>|!m$Pr zFCy&Bu5wlR=u2s`;L|X+=QIqMSFnGRRgXH|*G5Xl+@_lYSmb?6|Hqh}DpK))oPy#S zV1cwVZ}ir=Hg(l)3_!e}GX;#(0lKA*w9)pp_%sEMWY^BMN2v$qv3Fmb{sd(H3HU~X zu?X5r7GoS#TQbu6dgr>q5|TP>TDzY>E&0Uxbp2Wla9;6?il&y8pw@p@!2uiI0TAT_ zogw4*;9+ zc0-qn2Mq=Z%_P`M#b1n-j0lY3?c$bv0p|dbmRmgOm7?X|8FIULVEgYZ4s%~3LKh!H z@jau4)ZKWgumM!GqR-|pRuIbK={#llc;E*r&C@k2{FlR>1q;O2pvk%lRUU`ol>gPn zbq7NI|Nl3gRmPQd%HFa%j*O6TRwSHcePkA{qO9|=^D&N(BrB1+jIy#K+b2;dqpKtt zSD$=jQ)b+KpMHP;?vMNP?)`ebU*q|FEWKr-Z~n|HKq40*4T1=mvy=iL)5WEw6oALz z(OR~kEo=?Q&%v*`nFJVL*f!W6(XjqgwCgp5Q~2+LIXU?|jKxCeB46Eq)%l;s8k%s9 zgvxth9x8n_*;GoAm0vJh!<5&vA=%}5zDa$llHy_GkCl_w)mTUCx{+c&NBo(uEtVV3 zEp)UPJ>(r53X5SSlI4tEdHJ)>vDh) zCY-UisbTr!D#*mmx_j-~vAfGVuQR0=Go=--e(%qI2Vl|q$8R{I<}rXBl%G{rF0e{? zOUI^OA-TJ-DH-5x)44Dwy21dkCMTKYo_RHz0CeSH*iR$u5-tiQ^$(V_Cs#V>hZ<0} zeD*$0_iF(TR**CrRUdMF9`#$(cj&%#<@tFH2Ztmk`D=@MSDIyl?fGOzhlYmQfGI3d z*ZT{2*WKL{fzzjh0E52iWZYHPtz&`R9UYDNBT|z5wGB>RbNG9z%OODkEfe$dFj#eU zYE@%nsANenuk&5&CY_5Zl&ugrrh37LTypve8v=T#EbYHG^@ocD=VQ{ zVL^-&CR3((?Z9`Rv4l>+e4|hzI^!-0c>Fd zRmS;>ji;9v*5d`LRKEWx@>VpF=r{OpBV&%Z1cM38Bj zl1ff>D9w9+S5$9pg@=K5|z?LbQ6b%&v72p$DjIU&y~H44JNKCv@U=YGz#KhFe)rA}{zgJUfkQ<_g`JZVg*@>bdHzkkhrIHcOStF|w0@9H`Y z&Xi^g5sSet#t=TdVPs?*0Lg1Z2^qJB(T`p`&CbNQxrqQP``4LV6_0@&Wst@X z@6{zIv%l==k&uvJT3?TR^!@rq5gS=)AZ2xRm8|qLm9Rvk#VOdAUIcRp1bC=|pz`Nw z5=^b6l$6Ia=fff*T=ipbtdAk^kl>-ZatJ|liT|cuPkNLmPo@GP?WCcl^{H=7_}kLb zq~|uIm`pDZ8LTb0*ulODdH&RZtZ)iOQ-BZEOzu z9d(3dYz(*YbS8&zbiidkX;55C3j;S9f$2>kVJZBx%z&3^x^UmggBOmCwT7uiMn#3B zSWYi5^T6!s#@-$znyE4rj~}lAD^&3OM=lNyj<+8{G)%1h;#A_QD7Z=+8QBGG4 zd@%$oSt`cNC!Mu&GPG511yqDL>MG638XE1%9fIn z5_sdrx6<1;8Lnu2ZRcdv8{c{wpy2^)J0)jwgU|guxm0zJ1BpjYWnB7aB=*Cx(@E?o zL0EE7etcnUgJwJr+fA!dJ{hsGz+p`-5SlkW$vAe&Axnq*pf)55p;%cZH8ln5l%(Y3 zlIAb61g;hxO31h$u~`eQHYo*#Cw=ok7~_HUiZR@rg+Y94YKO7mE;cjArlzX+y>c!# zyCu2_={mHT8CJ_D>TgHh#-#QzBhMq7x38R~)9GmZVc&Y82;mnq(*}a_B`Oh{Sf`xT zeTb1XL8aQWX~cXxNej-e+|hOJE=L_bYZqn$K|Yj#->|JRr2Fp9%+7T7c*a#!C|0|7 z?n`7fU2M>(iLZe{D@BJgr6-miM_FA1L3PnniiK~G*#W@PpOdJsjh2%8`z@0xvsUmT zI-vpr@dbx`$rc!AnwzEsw6=y=EHbZ#zSsYlchl}^s-2II&$p&deb<@GT`l5d$_~6B zZ3n^`+#jTBxA}1Glc{7f&cVS(rFWE-|XTJ;c&`VF_BH%PwmEO>*#(dcZSs5P4i(ZF>E> z8kECq$m1tZ{sD3z{PS^LP~C4Go#3Ep%8O^aYV;W+E9&i;IO>g@skK zAu@}}1zJJOuq=@i>|IWBnjbuNkbEz$~xUEeX zF0%Jmn_>nYYIie|rWXtZ2@ZRqa7{N*C`Q*5L=u%<8qrQUH-@e3$iB-b2@ckSLqp4G z$L;j4QTLd)7%xra$*IrkyD{iV`VCL1l7?MySI}C`-y1?})C1_dIIj`?S+kC^a>l>r znOUnqls#!PP6@_A#eEZs(VOTxc5VUY!UP&aFLp7sxuK?9YLk3sNGp%<`LSDIp_w{}|cSi4_j~sc| zaa>m`Yu`C)4#!~&o?YnBw8|xp|0^w6Ed9=3xw2RQcg9r+8R2cQ)Ld@N1VafdBFl?u zGRWm1u43i5Lg0-w8!i((rPL@gqJ)9}&J`k-`r>X+YGXs6SpyzDn0 z+k^3H74pi_`*Y(09Ev9{cE!HR_#9;Gz~9%`httz@^GbV*TA7Lnh^H~`ywFBEfhV(4 zQB*Vz4sLj`+3Rs>UyY&U`aHwVGR)4B!EyRtx`Lji3a%e>hHdy8`0S+S=I2+zWHlRF z`bNmLHIxe)QYnA~*0bKlpjIxmYwWRhGvscnBWu7yVv2He<Pjficzw$b@B1>pWx=Hfkx*{1e;_454W&ZY}h0z2`V60 z$%L1PR%w$g8-{KmvwA+_Ul8)Dp{SVc^=OpZt`03M!l90;+#hmJ}B!=a*iQPOxGfUVUM5 zDtUjl;yGn{wr?YX^RPJitC*0NIx{nK z!+xY7E_ye7f@eVIg>Sutvhu#P52S9;j>jN10)@KRG8l##(+T&?;#=NM8&>A#8PI`n zi;0P~hiE+P=n#eW=|X2TOv0Rl1v;TB>)kEnRA_9~M)cLAP_G|B)Lq@&upx5<5(pDo zu7yh{Ohc0aO0=Y$d-oK{l<+&~I^nJ+#6OsSv;#vAi~7R!CfkREEqM=nirfL%nw__| zbhvLuXu=2o9yrTZ_BN;PeE#f=m_N#*Grbk|rt4`1JWAq;b*fVul1f0qo%>nND(~V^ zbze>;fkU}2IdgOV!Uoa8kT|yhevjgo7Uvuv?Id)a0GCbC!dbzGVu=hlG2U25ZznLb zy*3XE3sZx}SX)-s6qGJnxkS?}y8_)XZZ;m#m#{z<;VzTK+xElR$J!-}d|#X>tq&_r zLFl4gggbq>w^y5fH@CE8Le0Vs`nzm+1S2D(;ihX-ul!A@IM^sy zSjdB3oOMc!2jz1yOy+Fo*0y5o%3iE6`ou9^1iWqOVWY%@@v*?Dnu=%=^ZX!%ik*Wa zZj2bckfg@X&tKzQ1)X_s-yOMUuu^JTT6D&|)!gdG7sp3dgurQAhA*0K&)#rCR5{|& z$^+LM%FElCx+W&vH1559Gdk+HvA)jV-qtovqcPp-LkS8B=2^)S9326mgYRz;@K!TM z+=8sKXNr#18Fh7Pcq+~ojk31otC+aTI22p(r~9IQf0!pHqg7uY`GXnlqjr~W=+9=--$VDy#Ds*!5%~6K8n<Vl9rm6AcPbUxwB+^>ezDAtABg>AbH!sC* z&PX9!#-f}bWyp(Ptrlkw!&xiJB)BpKvUJ%X>6Mjqj2H_2UQ@y6|umdHK{hb82>*!p>&S`