From 34afdae7a59b31ab1599ca70f40772d1277aa29e Mon Sep 17 00:00:00 2001 From: Bai Li - NOAA <59936250+Bai-Li-NOAA@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:56:11 +0000 Subject: [PATCH 1/7] add GHA checks * call checks from {ghactions4r} for building and updating pkgdown site, checking documentation and style, adding a PR checklist, running R cmd check, checking spelling * copy GHA workflows from FIMS to adding all contributors and greetings * develop a reusable workflow update-data-r.yml for updating data files in the package when changes are made to the /data-raw --- .Rbuildignore | 4 + .devcontainer/devcontainer.json | 2 +- .github/.gitignore | 1 + .github/workflows/call-allcontributors.yml | 41 ++++++++ .github/workflows/call-build-pkgdown.yml | 14 +++ .github/workflows/call-doc-and-style-r.yml | 16 ++++ .github/workflows/call-pr-checklist.yml | 42 ++++++++ .github/workflows/call-r-cmd-check.yml | 17 ++++ .github/workflows/call-spell-check.yml | 15 +++ .github/workflows/call-update-data-r.yml | 17 ++++ .github/workflows/call-update-pkgdown.yml | 11 +++ .github/workflows/greetings.yml | 26 +++++ .github/workflows/update-data-r.yml | 106 +++++++++++++++++++++ .gitignore | 1 + DESCRIPTION | 1 + R/get_functional_groups.R | 2 +- R/load_.R | 2 +- README.md | 33 +++++++ data-raw/ewe_nwatlantic.R | 8 +- inst/WORDLIST | 14 +++ man/ewe_nwatlantic_base.Rd | 4 +- man/get_functional_groups.Rd | 2 +- man/load_csv_ewe.Rd | 2 +- pkgdown/_pkgdown.yml | 4 + pkgdown/extra.css | 1 + 25 files changed, 375 insertions(+), 11 deletions(-) create mode 100644 .github/.gitignore create mode 100644 .github/workflows/call-allcontributors.yml create mode 100644 .github/workflows/call-build-pkgdown.yml create mode 100644 .github/workflows/call-doc-and-style-r.yml create mode 100644 .github/workflows/call-pr-checklist.yml create mode 100644 .github/workflows/call-r-cmd-check.yml create mode 100644 .github/workflows/call-spell-check.yml create mode 100644 .github/workflows/call-update-data-r.yml create mode 100644 .github/workflows/call-update-pkgdown.yml create mode 100644 .github/workflows/greetings.yml create mode 100644 .github/workflows/update-data-r.yml create mode 100644 inst/WORDLIST create mode 100644 pkgdown/_pkgdown.yml create mode 100644 pkgdown/extra.css diff --git a/.Rbuildignore b/.Rbuildignore index 5ca465b..95b3786 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -2,3 +2,7 @@ ^\.Rproj\.user$ ^data-raw$ ^\.devcontainer$ +^\.github$ +^_pkgdown\.yml$ +^docs$ +^pkgdown$ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aa53181..d2886ca 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -13,7 +13,7 @@ "packages": "clang,clang-format,clang-tidy,cmake,doxygen,g++,gcc,libxt6,libxtst6,make,ninja-build" }, "ghcr.io/rocker-org/devcontainer-features/r-packages:1": { - "packages": "dplyr,devtools,ggplot2,jsonlite,methods,mockery,Rcpp,RcppEigen,scales,snowfall,TMB,tibble,tidyr,usethis", + "packages": "dplyr,devtools,ggplot2,jsonlite,methods,mockery,Rcpp,RcppEigen,scales,snowfall,spelling,TMB,tibble,tidyr,usethis", "installSystemRequirements": true }, // option to run rstudio. you can type rserver into the command line to diff --git a/.github/.gitignore b/.github/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/.github/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/.github/workflows/call-allcontributors.yml b/.github/workflows/call-allcontributors.yml new file mode 100644 index 0000000..c7183b6 --- /dev/null +++ b/.github/workflows/call-allcontributors.yml @@ -0,0 +1,41 @@ +# Runs allcontributors::add_contributors() to add, or update, an alphabetized +# list of contributors to the README.md file and open a new PR with those +# changes. +name: Collect contributors + +on: + push: + workflow_dispatch: + +jobs: + run-r-script: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup R + uses: r-lib/actions/setup-r@v2 + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + packages: | + gh + allcontributors + - name: Collect contributor data + run: Rscript -e 'allcontributors::add_contributors(files = c("README.md"))' + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "chore: Updates contributors" + branch: update-contributors + base: main + title: "Update contributors" + body: "This PR updates the contributors list." + labels: "auto-update" + add-paths: | + README.md \ No newline at end of file diff --git a/.github/workflows/call-build-pkgdown.yml b/.github/workflows/call-build-pkgdown.yml new file mode 100644 index 0000000..b3dc470 --- /dev/null +++ b/.github/workflows/call-build-pkgdown.yml @@ -0,0 +1,14 @@ +# Checks that the pkgdown site builds for a repository, assuming that one +# already exists, but it does not actually deploy it. See +# call-update-pkgdown.yml for that. +name: call-build-pkgdown + +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + call-workflow: + uses: nmfs-ost/ghactions4r/.github/workflows/build-pkgdown.yml@main \ No newline at end of file diff --git a/.github/workflows/call-doc-and-style-r.yml b/.github/workflows/call-doc-and-style-r.yml new file mode 100644 index 0000000..15d7db7 --- /dev/null +++ b/.github/workflows/call-doc-and-style-r.yml @@ -0,0 +1,16 @@ +# Runs devtools::document() and styler::style_active_package(), then opens a +# pull request to the branch that had changes in the push that triggered the +# workflow. +name: call-doc-and-style-r + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + call-workflow: + uses: nmfs-ost/ghactions4r/.github/workflows/doc-and-style-r.yml@main + secrets: + PAT: ${{ secrets.PAT }} \ No newline at end of file diff --git a/.github/workflows/call-pr-checklist.yml b/.github/workflows/call-pr-checklist.yml new file mode 100644 index 0000000..e9f558a --- /dev/null +++ b/.github/workflows/call-pr-checklist.yml @@ -0,0 +1,42 @@ +# Adds a comment to a newly opened PR letting reviewers know what should be +# included in their review. +name: Add a comment with reviewer checklist when PR opened + +on: + pull_request: + types: [opened] + +jobs: + pr-checklist: + runs-on: ubuntu-latest + name: pr-checklist + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: 'Comment PR' + uses: actions/github-script@v0.3.0 + if: github.event_name == 'pull_request' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var msg = `# Instructions for code reviewer + + Hello reviewer, thanks for taking the time to review this PR! + + - Please use this checklist during your review, checking off items that you have verified are complete, but feel free to skip over items that are not relevant! + - See the [GitHub documentation for how to comment on a PR](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/commenting-on-a-pull-request) to indicate where you have questions or changes are needed before approving the PR. + - Please use conventions in the [guidelines for conventional commit messages](https://www.conventionalcommits.org/) for both commit messages and comments. + - PR reviews are a great way to learn so feel free to share your tips and tricks. However, when suggesting changes to the PR that are optional please include \`nit:\` (for nitpicking) as the comment type. For example, \`nit:\` I prefer using a \`data.frame()\` instead of a \`matrix\` because ... + - Engage with the developer when they respond to comments and check off additional boxes as they become complete so the PR can be merged in when all the tasks are fulfilled. Make it clear when the PR is approved by selecting the approved status, and potentially by commenting on the PR with something like \`This PR is now ready to be merged, no additional changes are needed\`. + + ## Checklist + + - [ ] The PR is requested to be merged into the appropriate branch (typically dev). + - [ ] The code is well-designed. + - [ ] The functionality is good for the users of the code. + - [ ] Code coverage remains high, indicating the new code is tested. + - [ ] The code is commented and the comments are clear, useful, and mostly explain why instead of what. + - [ ] Code is appropriately documented. + ` + const { issue: { number: issue_number }, repo: { owner, repo } } = context; + github.issues.createComment({ issue_number, owner, repo, body: msg }); \ No newline at end of file diff --git a/.github/workflows/call-r-cmd-check.yml b/.github/workflows/call-r-cmd-check.yml new file mode 100644 index 0000000..ce9994c --- /dev/null +++ b/.github/workflows/call-r-cmd-check.yml @@ -0,0 +1,17 @@ +# Runs R CMD CHECK on the package. +name: call-r-cmd-check + +on: + push: + workflow_dispatch: + +# no permissions are needed by the default github token for this workflow to +# run, so don't pass any. +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: {} + +jobs: + call-workflow: + uses: nmfs-ost/ghactions4r/.github/workflows/r-cmd-check.yml@main + with: + gha_timeout_minutes: 60 \ No newline at end of file diff --git a/.github/workflows/call-spell-check.yml b/.github/workflows/call-spell-check.yml new file mode 100644 index 0000000..f73da2e --- /dev/null +++ b/.github/workflows/call-spell-check.yml @@ -0,0 +1,15 @@ +# Runs devtools::spell_check(). +name: call-spell-check + +on: + pull_request: + branches: + - main + push: + branches: + - main + workflow_dispatch: + +jobs: + call-workflow: + uses: nmfs-ost/ghactions4r/.github/workflows/spell-check.yml@main \ No newline at end of file diff --git a/.github/workflows/call-update-data-r.yml b/.github/workflows/call-update-data-r.yml new file mode 100644 index 0000000..465285b --- /dev/null +++ b/.github/workflows/call-update-data-r.yml @@ -0,0 +1,17 @@ +# Update data files in /data whenever changes are made to files in /data-raw. +# This workflow automatically commits changes directly to the working branch. +name: call-update-data-r + +on: + push: + paths: + - 'data-raw/**' + workflow_dispatch: + +jobs: + call-workflow: + uses: NOAA-FIMS/ecosystemdata/.github/workflows/update-data-r.yml + secrets: + PAT: ${{ secrets.PAT }} + with: + commit-directly: true \ No newline at end of file diff --git a/.github/workflows/call-update-pkgdown.yml b/.github/workflows/call-update-pkgdown.yml new file mode 100644 index 0000000..8134a6a --- /dev/null +++ b/.github/workflows/call-update-pkgdown.yml @@ -0,0 +1,11 @@ +# Updates the exiting pkgdown site for a repository by deploying the changes +# made to the pkgdown site to a branch called gh-pages. +name: call-update-pkgdown + +on: + push: + branches: [main] + +jobs: + call-workflow: + uses: nmfs-ost/ghactions4r/.github/workflows/update-pkgdown.yml@main \ No newline at end of file diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 0000000..24b36de --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,26 @@ +name: Greetings + +on: [pull_request_target, issues] + +jobs: + greeting: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: > + Thank you for contributing to {ecosystemdata} and opening your first issue + here! We are happy to have your contributions. We encourage you to + introduce yourself to the community on the [introduction thread in + our Discussions](https://github.com/orgs/NOAA-FIMS/discussions/801). + pr-message: > + Thank you for contributing to {ecosystemdata} and opening your first PR + here! We are happy to have your contributions. Please ensure that the + PR is made to the dev branch and let us know if you need any help! + Also, we encourage you to introduce yourself to the community on the + [introduction thread in our + Discussions](https://github.com/orgs/NOAA-FIMS/discussions/801). \ No newline at end of file diff --git a/.github/workflows/update-data-r.yml b/.github/workflows/update-data-r.yml new file mode 100644 index 0000000..eef64b6 --- /dev/null +++ b/.github/workflows/update-data-r.yml @@ -0,0 +1,106 @@ +# Update /data when files in /data-raw are changed +# This workflow runs R code to regenerate data in /data when files in /data-raw are changed. +# Once the update is complete, the changes are committed. +# If 'commit-directly' is set to false (the default), a pull request will be opened +# to the branch where the workflow was triggered. The PR will contain the commit with updated data. +# If 'commit-directly' is set to true, changes are pushed directly to the triggering branch. +# Note that the job will fail if force pushing is required. +on: + workflow_call: + secrets: + PAT: + required: false + inputs: + commit-directly: + required: false + type: boolean + default: false + +# Give the fewest permissions possible. content and pull-requests are necessary. +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token +permissions: + contents: write + pull-requests: write + +# Cancel runs happening simultaneously on the same branch. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +name: update data + +jobs: + update-data-r: + name: update R data from /data-raw + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.PAT }} + steps: + - name: setup env using GITHUB_TOKEN, if no pat + if: env.GITHUB_PAT == '' + run: echo "GITHUB_PAT=${{ secrets.GITHUB_TOKEN}}" >> "$GITHUB_ENV" + + - name: checkout, make changes and submit as pr on new branch + if: inputs.commit-directly == false + uses: actions/checkout@v4 + + - name: checkout, make changes directly + if: inputs.commit-directly == true + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: | + devtools + + - name: Run R code to update files in /data + run: | + devtools::install() + r_scripts <- list.files("data-raw", pattern = "\\.R$", full.names = TRUE) + if (length(r_scripts) > 0) { + for (script in r_scripts) { + system(paste("Rscript ", shQuote(script))) + } + } else { + message("No R scripts found in /data-raw.") + } + shell: Rscript {0} + + - name: commit if using commit directly + if: inputs.commit-directly == true + uses: stefanzweifel/git-auto-commit-action@v6 + with: + commit_message: 'update data from /data-raw' + + - name: specify base branch + id: specify-base + if: ${{ inputs.commit-directly == false }} + run: | + if [ -n ${{ github.head_ref }} ]; then + echo "base=${{github.head_ref}}" >> "$GITHUB_OUTPUT" + elif [ -n ${{ github.ref_name }} ]; then + echo "base=${{github.ref_name}}" >> "$GITHUB_OUTPUT" + else + echo "both github.head_ref and github.ref_name do not exist" >&2 + exit 1 + fi + + - name: Create Pull Request + if: ${{inputs.commit-directly == false}} + uses: peter-evans/create-pull-request@v7 + with: + commit-message: 'update R data from /data-raw' + token: ${{ env.GITHUB_PAT }} + branch: update-data-${{ github.ref_name }} + base: ${{ steps.specify-base.outputs.base }} + title: 'update R data' + body: | + Auto-generated by [update-data-r.yml][1] + + [1]: https://github.com/NOAA-FIMS/ecosystemdata/tree/main/.github/workflows/update-data-r.yml diff --git a/.gitignore b/.gitignore index 7cc8b6a..b27cb91 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ po/*~ # RStudio Connect folder rsconnect/ .Rproj.user +docs diff --git a/DESCRIPTION b/DESCRIPTION index 0790c43..e7c0ff7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -31,3 +31,4 @@ Config/testthat/edition: 3 Depends: R (>= 3.5) LazyData: true +Language: en-US diff --git a/R/get_functional_groups.R b/R/get_functional_groups.R index c289961..20fe9b1 100644 --- a/R/get_functional_groups.R +++ b/R/get_functional_groups.R @@ -4,7 +4,7 @@ utils::globalVariables(c("V1", "V2")) #' #' @description #' Functional group names are useful for the column names of output data from -#' an EeW model, and thus, this function is a way to get them automatically +#' an EwE model, and thus, this function is a way to get them automatically #' from the EwE output. The functional group names come from the basic #' estimates file. #' diff --git a/R/load_.R b/R/load_.R index cd97355..99ceecf 100644 --- a/R/load_.R +++ b/R/load_.R @@ -7,7 +7,7 @@ utils::globalVariables(c("timestep", "group", "fleet", "month", "type", "year")) #' #' @param file_path The path to the CSV file containing the EwE output data. #' @param model_years A vector of years corresponding to the model years. TODO: this can be removed -#' after havgina a utility function to extract model years globally from annual data +#' after having a utility function to extract model years globally from annual data #' @param functional_groups A vector of names of the functional groups in the model. #' #' @export diff --git a/README.md b/README.md index 17df434..7d61547 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,35 @@ # ecosystemdata Ecosystem operating model output data. + +## Contributors + + + + + + +All contributions to this project are gratefully acknowledged using the [`allcontributors` package](https://github.com/ropensci/allcontributors) following the [all-contributors](https://allcontributors.org) specification. Contributions of any kind are welcome! + +
|
+
+ +Bai-Li-NOAA + |
+
+
+ +kellijohnson-NOAA + |
+
lb-}5m@}TeETfOxLT-}9of&;}8hX z5bD4)n7jg(HG3p-jW2gURLU|oIR7RGUP)Q?iK_z|aWEqYGMfn3c^pYMwAM-cnv5{P z0S>@3K^OcXkDU{E&s43U*DP2E<78vIRd7S!CV0?5rH%Wv5t0>-7)wKQWlsgEo2kC~ zYLp5U?X$s#pqp2m) Qh+9Y?FNH6#dq)5XnmWaQX!70+fh34O`I=FMdZm@&~5Xr zpD~0(BNB2?8X0G0V0xZC7u?7?$iuP~&IYfA2E3@0r16ARLH{7`Gr5nJc0Ax;wYCRA z10nW`A#APEGph%YXJxK9t(t(>J8@W_4*v|y&|o@uKJ^_=%_aV8zYiGs >EHq8d%j=CcCfsFv&DNkM{KV5hUdZ z+!LsL1>hTy<##{;Ac6=O(o<8&V9EYw^VU;sM`M(NQ@E}r`!jhyz28essGnbd@+=GQ zL=f%% uFsV~uS`3d(~-6m zz{V(2_~s>1RFtm-!%YtIYrnpCi4a<6)jKvLOBwB)c39fj@HmI#QL*Wa$D0v%8JEo& zg$Knry6fBuSrYam#maNSq3^6HKqKEfSwCp6b9TOOA1AFEB3qocMJPT)m}9JpjCrtS zu#+`iuSDWIq6seJCKRU5YKM?qg$k-=O{4CZk)#CM6d{kdPCTfl^6FEEHQN#s4Qq~8 zR>nxE@prNxfMHMB*w;qs%(8|J#)LBaPUpl)@qd(P4((i_I3HX!jQg`gtsGAK!KUza z86EBYT`Mp>KH`6!t=vWi)JPat*Su|BG=u@uiY@S>WJw&Xvi5y0+_?Rx^PLp+KA$18 zjRytFh^>DZ_I>P)?3YPjKp_sIVZdWw{DXOYnCWf+Z9tH?f5cn_g0aHIP6wp?U?gy@ zl Ta8$8>`J1fiBTeUyooM z6>?-UZI@d@^-h3%sd$+Fn^flL0!Jd`km;V`rs3$Dem Ly8z9BAo7HQ^U+FL=JVZ-&6Ur4Ujymp3fgrJ!dW=GHHEu`r@Y8QJc zox*1&(tgF!{$soV0tg_1SWJZ3tL6J%(ZU$zS6(*?AC VV8M*T#KDoi$6f2J=h_-}HC-SQ_PGF#u4KXb0#Kn-EJ8|l$ zxPQ_Vw8@Acx!m96I{=Wbc238hPXsI^2y>^_@y*#K<`p=NFyTNF#qU}QiF_+$MQPmy zp8GHz3mecox2N`pT41dk5esY4>@7V#lEDDS7VcW^xLb2B1o6tMCai#Ar>dX(DRlhV zr`C|wJq`zW!V8WrQGf+A!fcQ%_K80m(x~4<;FATtccU#rD$*S$w#o^a)-*MRa8J?; z-c-<}y;om2Db5Dsy}6g6ZIv3=DYKI}d1G-0)@+U0{D!$^N`x?8xt+HMzB~;j1WvHz zFx5H+V?SRpGb=cq{g$WE_K?!AN3# {W;7*F2C?Nh`~4DqGC6CtfhsP2!_>2Ndl@qYk9V#R~+!4MiHR@XO4%1~#hNV99jJlMCk4TMAa+ z&Wj-yiWsbs9` 6`-5J7XsqE&>QH4TI~`!}?!`l8S}fc?gPI@Smk zA)$*CMMki-Ha<27r$0Gz;gsJjxx8aS)(U}Ddo%lJQUy%UgOdy3K}PIfQG{^3KJ(s* zZkP8}C@xUck+U_!IR<8u{P{Gz&MzwnvKSqD4@!jog{f0p=Rl^j8aRKMcGmhrqJOKn z2DS4L1Jk>r3a~&=31U2qD>}w QMfg40;9FM}ixnC{pDuFZ7(#!{45D`eCJy zkH3;K2ob-Xq7Bqqu>?Xu==t1;LW?zhmA3Q9Oe|EkI%Gr38`5nHA4yR3@I9N3&x5W9 z+7E8ca`gjGWBuxa@}Am(67S S#?fPFiq#es!O|lomIE}mkhF! zmaan&s5|dUgmJ|Z7waWL_G{Qhe~KZ0?%*sX -_*CRoVT_{@FI)Pc zTob~%=*ho!gM{N6RC+l9e16N4fG--VLEa9ain~H>h0rz&pj!ei`#crGZ&bje1tEH^ zD5rgMs$A#jwucqdEPhmk-y@G_CaH#9zSmbGmj~6+^Ep(uS>a-GGpI&`kol$lI&+Fi z@f;;hTvcp$-x_Y43nt?G!k1z{fA8}BHPR_i80e G0##QtC`epWDpk>JrkdE z%b|2k*@NcNqMGbsWZrOD7;vs@sg>RIy35?Yok&+Rw&a5j`UDMk$z$G!Kxlz6Q%Y?N z9tm8I{qZfL@SmTLBOg~y*4FTB2xgB)@+kWORqy-0s^eqlT^~$MxzvsDXTxN=v Fk&bD z1@Hi8I`)>GjmpILM^w022h%!g53{;?P~F2$)f 6r20!pGp}{RCJ=Y0X}-Gt zWV)S?>e2B^`sRPxS3%xz!NA$MCm9csQPa5iQc<+6-nVsjjKu;yhfhi_qh1Z{S^nl0 ztl)#R@$h;pp8Ewmn+kNvE57prU9COe$|NCDS`S^b9lU)=jaV(H!x2>B%~LNwhfZj} zO2;pQz%U`|o4Xi3Gl$wr->7-iaTYFWYBuibH3Ej`b|uzi?nHQWtJNkRxETtkS3NLj zeR5&2wj=PM>B}p$OVZqS7$Mx=RbY{WyE&6aKtx8aEGLHVzQ|$QU9R{IIgrkC*|>BT zdH$LMo|2cssN*ldd#`6hPnpCZeG<#IrR2^@`&LJBO(Em^a(c$2@m4lB9}ur_(r?aO zknyg4Z3Xi~+U{JPqZIO2aPSc2_Yz2BA0(fj>v76EC+t5V<;&x5JwEzAQ~8D9N;txd zsVW@rWAqq_TM)`tWqXvn=Xc>&Ne0Y(!W?r5Y8%ckQ4Vvlq{MmP2tU+&SIy8xDRj`; z4K2kSUIR98*@#XNWm7w3A!uW|r%EYu$JhIHUj0%9&B41&VwJrk#0as=0MxA;+X`Q@ z+yG$;jm*&m%hh2*g`7Re6tP`P 3L-sNa#=TA(of9(auB@@8w%t;V(Z z$>`K5F%;xN!>TuN5-GT*9I}2pN2MMZT~_&IAX>-xXKs~bz&*kXZ(-bk9*#sV@p__J zv*9cFV}mUK)n(foc9yDjN9kQ(#_vIoanNq|!%tc%*fE?$g^QR-ibB%nrnT zWu-APb(90; z$>*(Gef_juApI#$hxoZ@I$h970@O@(>xSK=2ozvFp;K#2_1nhokEo%{&*UWt`Er2v zoXgy)^pi45@^}+-mTP(tw=e|7T49=wJQi@5v&OR`YeueG(t1iAXD37l2;o%%E$~M@ zH1fmZ!NJAa&bMubcjfKf SjS{5jXF52^lk z!_Bf+KE9j!v(=^2cba;{r-iP71~Kz >2~-|C>z zHhh{Pu=iyWI8czAn@09er7kdgvHh7!>GDfKxk&Gg7tx#f#m!SrOl7ICs{{WAW$We) zRvi3bhnC~K+W00b4A{UFdezdVc}Hai&{1q7wZsU?0?t?X>S?uu0{GL>xtYuOd*BuO zb!*G&=!l!Bi}y9+vs+v1!93x22%lD|;?Y|nA%B+uoLv9$Sl|>b`Nzi67FwT7hV{ft zu9h{+@(jcm>}#Yv+5nN1vO6}$YFEgOT}=^?GM$HsHYj9lJWI2=sNTznPFSUv75`7# z0dv!oAr^ly-N#16 IRyEGA&w2Hh%J11ZCbl u&coCjX;KAlXxcaJw$D&8Vnvu$Xe!&$i zciyo6#^ei%;0)V@=knj4G=6D@M%AtvD>jhW7ro~l!~Q^;Mwk-b=UH$f(06g+cmfHn zoK=Bz-hUPob+(q-{W5UEYvkc4@GCqToE`KlhPDlQu58>pZq{MzSVc(EqN8vN^nBf$ z$~tMYJ{ImE0U8+RjdJ_F)>-Co-b?eq3(I>sCiK)eHBvnm6`#=Xt5>-K?^*~Z4VaE= zX|a`>=vKH2T30svV(F6;f566iY#pBHU%gw+Vk86KwJ++5_d;8CXxK0owOU0d(c$EO zH5W*gM7eQsDWETIX~|ug!&(V#^*ypFoGzAc?qHrd3ILsoz)+Dn>ihw4xnimUp oBn|M^D6YN-Fu&%*|iskvxw&KlGU!CC}Tj_sA~1`9n9=Y z@$(tx_my7_i2R5BHzT}dZ>?N^zWjB|6nRA1iVhumR%LAlOs!4k^462N^VZxK?Nu`6 zLu7M^@6*q=A3WY~3*$!}&U5{1kmoS@A5)!S>&5k}HK@~@)0?NbU)kF7U&~IDNuu_B z+enZ{AhNGwqQuAC@ON#>GD#GSGaFEJsU+<5-ltgi%Y0@2Ugg_gL^rD|ICBFHRBoUz zdR_Uc&oDy>?W)>(XzFnK<_b5N=4iQi>+>)m#%M>mq$8|lZ(zqM09nY02SuN&XxsW{ zs;!_J={PTY>NC&=+pjL+Wv9o@EMt_b_M86k1(I$*!*yVxwR&iU4`JA93EpUSz%Vas zTyRfw^lAX}Q&2ac$6b#o07S8K%yd71PL?B-;C;o6du7j=NexPZxb&RHVxN!;114t| zhA3UCc8b!ySXc`cEc#a&Un^ITZvOF4gzN(Gc?( vdbWRkA7y-XzE#i>!cfsqp z ={vD1$+G4AbwiP1EeVOE$;d#M@LjR0IL{;zY RU_$~sYVz{% zcR5Xl2RtA;P~B`1*2$0M$_=mhagrdqBiIYQ01vo^Q9L|7GpvUa8^)-#8>elA6YEt2 zCfi}oU99CxFB@vT12>9UL6_Pj(4c(RK2@`lysD}`@}7%4P6?vl?rsm vxQ418A8{3YI$+0TF~DSQQsS%&i-<6o};jx z4yAO7Bx$?dSsmU7HYNo%^fdh9xo%@;9?@o!0i%S;o@d>i>mg!k?y5p{im{00-BdAT zUUsz`?Y?(1xY8k$ &cR8nv_@ZMXlh!$+V>LNcmIE80v(IID;4GEkR&2T~O$b9{v z^pZF?q_7# m)Ad#9_9vj z&+f|96q|rLe;?}w;+D4dhlpGEyzB*KE7un4u~tf|A6WzI8K`qqSXgS;GJTt%%mAH! zFpYg#cXVDGulL;(@Tdi%i5{r_6?uX+?SNOu?0CC(uuMxCKTNW-_(>n87b>AcgbluO zQjz&9(VVYus-H44UZ2NR`4|K8G~}B+@J>QSS|3e zymk~GTB$UGn#^R-ff_I1rq*>5XR75g;T)T5m2il%X*@f#_ci^c;tdxe$Q6@~D|9?> zBcP)&@M0MEJf(myC~G9{9Agwld~0=WUrw_kC7>}X>36z!o2MbfDQH32m%qi;`dKpr z)_wRi3rxxY3Zk|z^tj?!EknDlwff>Xja(~Z*XH6r3j{nXQbN|%$@NS9iLHUKDV-+@ z4+L$b-!>LgM6XRjv?QoTGZ)x}@S>=kaS(GKHbQY|p*7@CzE(GebdAI6WW`0ko8X@o zfh(2EC8Np L@mGPiL8At~`s^?8$m>1T6Ue;irl%-_* YySc=jy#&LP~pkE1xcrs=z9lrQFPmO}Y1f04G)6L`crplWGeq zXM~MtY55mt))roO;MtL}4x%bT4DM~rTAa}g#atb!0+_OwPmr2c7n9{gtlFK1djOB{ zX=1d~c?*A~qaEXZdziK&09S3*4vhi_CT&+B+q)=u=P7f$aMG6GQ*WfKEDeJJ{)wbMGIZ5vP%$2Fu{FVo0M^%-hnlJN&neVc zj^ E1TDF9(|$w+IM$X3h6;T!j 56zh^@@x-1IzDN8TvYm6;+|}K)3LYi zAj+R#RFng&QU>@Lz+U$+QT(x@xocLrkL(qdKpRlf#?P=Ti>coti+*=A`Kv~vE&xrp zPdi|OvzM2}u5CSq-tMc1vyckxIClRta~#ZT6(iL=kO{1%x 9zV)WfaxFJp&jY|KRGY;*bL?JnzJ z^M9~o 1jR)f*B2vF85qKmnklbu%_2sjP8Q=C2wLgIGF+5)XeK z@OS`dq^DHrESVF)xk1H84q&kx!Q6oW|D+W*ohp`~JiiZbnC*oNIxnxJR)NIl8uS}C zo(M&Oj+@uIEVWN0={#y|jsX$xiC)lK-hgx@y8Mac&$72dOiTZS#lXI|vsYr^(q|6! ztRXV`$Vxu?HkyT$&VCP$W{GwH;|SrI3a75C-F0*o-#?J36W+tlk?$7k+)NhFR(!q& zMdrJyks+uWsvgowmHRIL9M~3*3O^nRF4Y?ve1pOQkqgXTi9}-TXWR#h3arY!RLlzd z704uNE38z0;qB&o3g(0fX!OydWYpQGv|>3|wRQo82|O<3XGc2e{$O7P3P8wY3Hf40 zZ=11Da@e}RVU3&uNxn7DHo#KwReKJkSmS#cEw#jzd`m)!4#%2W*~ey(i_z5LfM^G_ z^av_ 3ETu<^QK9of(`b|n+@s0(Dm)^hS5 p+Q{#TT1Y%hfK4U=YzROU|vj$OMreZXXdk;7~`v>TTh`ilW-3X&5R1;>*074O3` zhyI1Zl@|;=qJluQ`nwc?a_Qt|s!nB8)_PN8#t0#OtY(!-!NG(#k!=LY>N5QPmFNCG zbMDvi1#-Z?pI=$9RbimFce(wNDwyxcq@Dp6;Um8=F@!`tET^h?D8jDJV@x8NXUDZ2 zx$n_n`*XRUYUP+k=vY2W7d{z`y(pKPoLOVY|4P*tLkgxf;|g;H9d!9oT8$Y; gq{30}MR?gr^@>isqLMsis3hhozpi3^_|t=s&w@5w8D zB=Cfi&l<|j>F|!`%~ppyVc>7$$;h@8<^H@h=YlocqMBVQ3DSbxy?1&{4Bt=L(5_a& zG3i?aGfF8~GNj>91HqC@RfE-T>!?lsS}hVCS;3BQR}mpWW8s| v@* z{*0y1a?cpHmq)wI$+;TmVzr+n4+J$U6zIltpDBgbv5syHcoEOc?4BRZB9skR5h4zR zh?Gm$8(Qhgzu!pFWx#w~cf=F4=({m=U%69zKc1hXyl~-uBb?0z{6+1II$sDO=xnry zIT9%V0&434JqGY+!x~1TN0v{il48 B72O y >-5>Jpl9m@#w zg*`oW4G^jp9v1&XlMwq-(V$W>xa%fky;NoyH~QJRS&jLFqMVa=Gn1=X@4G{JceBbl zKYWSFm*hI5eeo=?xwPvTO0K%*9Lq5QVa39P%Ln%HF^`eLJCR|FU(}seUyp6wn;odq zl@VdHdh<_2chFMudAe|)XjYlyxkw+JGY&)a`DQz`gBP2*+J)isIvA0{lycK(MKROD z)xXPY&Lt_BtuN`kUNsIRp2s>OM0qrp4}aWG9{CVdXUc56SW|#L#LYM`S~57t@u$Ij z&gdOCch_nU%0rTEI#sBUSR)X(?XI7)6?ahm3yMQ?7&m(2@8#-yyK7#|ULo^K+o)pV zZU=|NUYnI8BA(Cr4jyMu9JSZiGS@nz_iXbq0pK+U7d;7SY$Nr?fG{TTNQsfs?8&62 zFKvn%c ?Hq>_^9B|P%q*2;87lfsV6E7x2?0K81W03CN~@0-{E2rKs$ zj4QDCG cVa-Sznp9o8eT8oV4NUkC8Y+X!Hh5HHC W z($23EQW|T@;Tr#%=Q0(f;|8BNh _wk>L6ew6 znYmn+NE4?C$F?W^Xies%NmxAt;a2<664VgjV-Y81Mr!}H=>Y2eFizI9l;x)42Iy83 z?w58wizPV7cR{AgC|y#&MPGp^8+wISf`ZnC)DR^?f+|!mRhX|~DqGq=h|K>R@LD+@ zMA9 WUB%X{dTwj+(fe zo_Mg99-CuVWoA53G)3S84SiT?mdli@6A-DNsG|hKkXlT;cWPw$3&nfc_=XPv25Zjp zQi+ZQ*qgm~HBl2yp93Y-klTTdm$ E4{}=O_{DDvA50w9pa9oqim+xvaN$)M{N8fDX#- z6l!ih62+$`pB_aaLNGuLZk|q09eh2nr)YrmFBywFHk3ZxdFVZeFt74?0aXqDIpKyi zKNuy%uZ9?TjwMS!r(CW-O4LX~Ovn#OKLSy0k5>V@qZ|*`1e 0m}=9e}cqU35|>f{IYlO`YYgTax14{P|T zu69KbN)IH*dUcMx2R*B4HaFVdoG7b+3#O@zH@zBxd=dZPH)d9*GS14#6PizF_7&Kl zLZ|w?G!`5+(BT@xLoa&4e{h$P7I2l^Ruz7dIzta2zP%o }Db$L_r9M5fFK+tX-C0@z}B!7gn(G!43TO z`^66f?}_oW$V2K}E-hw;@>6MRJEumDYpXWY-mGW;d)!_|kt4(@GS?hBAE}XgnEHaO zvpl*=PbIA}&-0`@WAQ`mvOegAN#P=2^TVp{nAbnQT*)EF=B<4 ^tJ z*l>*{gQ;bl<`QsO|35s{K9_Jkd~In^xqkUAFPer_SmS34z_8NdLf7xZYV*~xW-&y@ zO1y(mgD(rgx99OO!ujs?$G{&`?bRzKGSE1_5x%2iVtvJF{q8^jh=@P$zyt_^5FhRI zK2EQ40003Iez6uu{#I#LKQ8)?03bv}L#oq$tmEk*07OJOSn1ZRjviYum2H4{ujM@D zG%EPqO|kDLGcWU2j#h-k$f|0q|FLkm{eD?`q4D}_XldR9?VkYPVn;_`^F3++1(tAn ze&}fo)47H+J(vP^D|Gif7=AY<$rJSM`#xb-=qYB(j4b#8M52GO=YqUIaP(lUmR@PZ zMr|-dA2mAW{oaT=%RlgBmxXek=(x*6bFyiAbqxbmqfcG;IHtb lN2UPWL{I&Nx zFXA8w2wfz}j{HLZeCL{nv64dnJj<%PLUhw-Fw|Z+7yVBdRl9p&A7+2@<@**Vo %eOQ+WJ6QcU!Gc#tn?foeM5<(&T*rK!Xz?W?It( z3%FngV=uvGpp-?0JgJvd!1eFYyM_v+U<*N$h%gKpUW{&x0a7v-gDOGL7#D*rIf}WL zB*;`uK$xh51xqpPn?eQdsUZ-VG8ZEv!X1SW3VGWMMdncc93>UA@P+G>LL)L73Oz2C zumz _ zc3l0P>lIDkl-*dh%->1_cE3_uZgPhChmn$LjjmgJvHH=o=Parzb5r^~8&^v2=efzV z3%HBO{1;!Hdd$%aav5Nyoc=} xl_M)EA?3T1$ss#khVVA|I-mlYByD~ >52gG4PLn>Q=R?iE3LDbP*in?F!{%7h34n{ z &_J?X%IyMpr3zZ8!hfJAK> Hbv;dp0nhSmH4k`9Sn3K< z?5rH-Yxs8P8Jw+fUi}yw)`!8Pc0-YUP{YYTZ@k0IAbA;+`cVwL?p5`9b#O|>e0rgI z!8+qCt|)c#(I)lBmxDa1`dLN&(8~PZ%RxQrH0#@g;2q6MkVv#u%+knX>jmeHnCjc; zGORoI3%-ud?8Zk{qYx)sK7F*aS5sUz*Sm1f6gnc*|I7oj_m~uUjA=x7oLe+9>6X4= z*8p(B_QQa>Rq+P2x=w{<)jK3TwK}22GEH-+E}c@-@wwD`GrX?P4r@q72#Yk z*=Hba_WzG89ZOe(D^n4F+bUizwl(wiWNCQt%=? Ll-A1q+ir`tK$1jnu;!NjmdKmI`85+t7;%p7FO*{bzJ^lW zV520-p>8wKc(~YRqPU(4behPXQntr%q=$#*{5EYlhGAv&2bMNyVRm)K%rSnicG+5r z&WZE`l%?$iY_i+`ste?Mh(Q^UOvfRhci?hYRQg22HEsujCgE<@x*$M8G)32eob!9L zBy_KpM>&hUyd0ka>wy+q8aW=v ?{7Tir5hl0Aa4N#ht>#!0NI__n+Keh6M86EB(V z*k_B4uQ=W0Cv&S1r6~}GbvWvfi59s%mkS@EHeIR8kM7}ix>?Yglcu@U)eaBVlqu|1 zjL`VEAPkxKYVlp(e(~th`vFJRIP?FFw_)mh3qgjo`D=LqFg%7{;H}^%Fk9hgK0yE0 zitk}LC7pL$Z%Y^6t6lh#ThTqk1i-?}Q%~t4rYx?%{p6aC4l^@2UPT6y0jQ_ZPsOVi zz4N!@C#Y*igk&z7FT-3m)QrSAyJs$-PjjVV%VLN%gh5yURpFO*?AZorpts9_bq8S6 z!Frhcn{BsodN1myCCD<(F|!Rfyb9@)9m!!~f4`qH@b>BUL}`fZPn{!*`FQ8cEQSpv zHanCJn(xTP8+=>`w*QP}PvEzs``uQSv+eOMk7k+El^N16WVCq3ROnh}gXIFRBPZzr zUXeGSS7mE3%m;u5{r{4(C{WlWu4LEVOw9%nH{d1bAAaaNJgztcF^QFTK3+40lXj$F zK~*atL(On7qBwiAtu(EgC1^z}^ B+%9^>)f6vByWY6o7FR?*N zz;k$T-Hk6@*bY0d+}h$ 0W#8$~-y1qhb>;99%ga#;7$bAQ1nHHjCq%=)8( zC0bfMe<%1E;hB>~@Dgzl6{IQ!zrX&?qP|LaSYV2*Yn=W2>tG=NTio3sU+>R#r zav(|?<9-#^tM5p)_z6MHVg|gB#1%{6hoR8v>vs &??wkAJ8fHtI4*fnDBm>FYEYaNay$<(h>|o42}y0K_BJ$5h{;vH=!PfS zpSLoxfqq?pCjw~%blamXIUI*^Rh=$dm&31gJqwSsnu?XIy)QrU#s?28&No= 6?F%I>G{s6)P|$FK0Du4?$4tkf=J;DRIUt$1hPSzjEytxF2Kq0(MQ!(l z>!?|OM|PW^&eBBnpp~yqK1*@x_XZFgsXuEJez}kPOTFT3<>5>(Qui=r`1Cj33~BZX zXWmz1Gx>jy8P6skIeK3X?x^ t1|dlNDxThmeP2t>yh8B`tLSnJClWZqoy5GhjGDWo<&VJB;{D_P7aaN+xm_ z$TzwT3xWmkv|CC{xD&k%N)m&MdknQ2hRjg#AgKhCVAYn{FO5Pnti5+_4W7>imt? z6QU>sp`LXXrLChfL?hm-o&yvM#CEGxrpdje)g0^g4mP3It_XXTXQV&O&gb5(lp3kR znIr#y;7>-NFnG)^$q3kj#dc?sr)}!hR8Z!7p}pme7b1MCEWp8orQDdfng%hzIkwqi zR8Z(l_g=%pqkeS_N69#r=0M4@FQv{Hy*Pa76ux-*-UQL5_!Ge12kShSt7?>*A(8 zSwP|kPP!VjhF3HzEPS)feQ@iv7n_*E${)P-Z?OQ3csa$+r(<&OwlJf=Sw?~fb=pVc z?(SRlmy#r*K~!2Q`>;(EAs9=L5E#l{zYZb+D6kx?eF1kN;61?1^_Qe#9Q%c-nRAYU zYE(S5CMEnH=c7_Q64hp!aoMApy)jo`;pi4j|5V*HAf!)vudgj|L{niT~y zmoanZ*Ez1!KFc~jc{Vx^dKkBsyxfX1O2da;ZInYw0wzp#7=}6e=lw&)G-VNCA>R@c z9vnfqSiTQh0c_f~ceC~ZEVFEba@J(oWSc?O5W cVwqF z)6S^$^|V>UK$U4tS7N2^LR!mW$NGA;GfrcW-o#OImH!;|Ng38Jh?mBxV7AtjV&{p| z0+iOxIyKVKDTM+X5Gqu*q!T`}eqgi>JZq!BIIwk`fWptAN#Ubl2E|V@lWk8yhcEn! zvM`DfUK{}UsG7&eB(R0$b1x!OQ)D{GlceQ00XF2voyk%BC0F+QKWcGS9@v;m=FPK> zhQZS9LNFJHjqSY4Ne!p%JUhx|an4#hYs??{jm&Wt45)XW0c`(CC(EYVZ$O&dBRn zA)V{)vIou`T((kcUe8DZbP%>Zl_&Rr$szlu>EGa8j>0siExLK9y95LJvE>NGCJNrM zUd&vVBu${jH|eQqQE-tQ0x=Pi3GI;&CdIgiVi(W|`6Q|U+$nV1&gY#YfHO?1S(5_^ zQo@f~@@bGHBmPFe$oETLKQf=oyN1#rFM?aV<}ue~*E4{5gLCqajcw zmDLqiLb608n93&kI*~$?6u=+8viRpK@<1)RxwJ2`>yQh)7JWUcn6Y;;@^t4X>1VOV z%FSKb2N70?70*}w7B!K*RuAn2esDdZ6z0g{I&DQL);xkD)Hiw!bI8|$cWWk@i7WCn zMOiJ;b&PQo7i4wZap?tt&W%yujhCsN46sBvPpYkkU rd zSim}c0hx1{zWtgNZRK=iV{-+G%wMnd0`X1=9%x^lfobTX^2jbR{#40|;F9K?cB#Ef ze!y@b<@WSpz`v9s(qK9Ki(sVK^_>;uCff`3GWrfSA7IuLJ}L oA>oeq74}3S9Ee@|yjR+LLL$o#bwl>}c+Q09!z$zx0~OsGN;4 zQz+&~P?QlEDnX=;#mYGK83-6$Zb95%M3&oNQNkKn8VgHgy!gON^VQJvjQ}C -1G;MRJhQFT@4sWICGkLGM4bOI{G3vB1f2ky z`FwgrNZdMh${@a^mM~7WqwRZvbr3#*-m>Ylt4;ZXX!nbTQm`Q3wp|TBGC0BE-1@Yy za5>z&O0js=LhVZUh_LiwUi|j7>i+%0vlO*P+OtZ#%bc|^P45&p{bB(A )5C?b!aPq63a}&K(oIK3KVT9hZdb6}%Y!FpPa_1XrjFum&FjdstW4L5Mj?Ue7=t zUog6{9Xr+q*UzNDR*R=SIe^X_st2vf!r4h}mJK|A^|C?qRWhYe*wWTmDcBeiQ=tkZ z%XW@&w=~21r4PcvJXf;A4#}~F-^cz(NTo``DMx$pt^g01@Jq2rFKb!i&jHcsyPF?T zI_(!flj}ueRV4Ju^@o7BOA>XZ8~k={!Nb7hFv0?YyyXfgL~8zhP@YLJIkjN?3&Q*> zU$3U4cpp`tCfFtmMT3JawW!N2SvS{&i(wFT&+$}wSZOUm{n=WvZj^8PHZH&W-d%hO zXn$r9)pD|ocgKAC7`|`h&I-|nYF%k`$9rFx00;XFyRW*ur*(+Njf%hpj}NQ&@n307 z0K^unxg)4_;dGNPMB>uHl&J=}0!$!zpL%!@A|5jd>uqJWhmpKa?x5jysuX5mK9dPk z=uW=t_?wMQvxy3$xre^=>Y>S(20R&_a lxW_`Q-5byx%i!<7kU1f{3^RwmaFYBj%>3?KPve}((*y<;A{Mu+k1nJE%-o8DZ z8V<9sm@sQ{)45MkiT&@_h+FR?AIvGJO6pwuMv2*1KOF=)(McKK?0BcY&4V?I=O@;4 zO#gH0F*DOCpAY1tvbkX4)gQ`%sIaW_jDHL58xe$2RRgP>4SYSMwEA|a0b0HvNrh5+ zPn?*@!U4|r8rdK^KpJ1JgzB}YeXj-R6sAFU<2Joi^Z{Lb`Gwcn_MXnNXeu)?Vu} nCL+R+xaviubM86|nbzyubH#sF|-Iz|Z+36p9ZRPAE*p3@i7G-D+oJVzGN%GAK zF6wM^2kpjKh!NeqaCTyd Fsho4;2U255*ba z#->eDBnEuQy+A$#_vSeYG^Sc3QbPTJpt^NL@|Gtte!|H6=X$1K^_?$_dfS=v?1c!2 z0)xBtu2e4#^bgb`)MBC_Okt@(#Ie&(XL!DiUMSlzJ6pAVSthPlB&TOdM?2?6cZ)vt zmVlI({^JpP3(oYxR2gB{L&LU;VQwmv(Y&s4QfwAM&%M{45%D}KH5C3J6e5Je9Zi(k z9m!lT!uo_4I`=HB%q*V0_+58%lC+$P*4UeQSw0;Jh}7KKy1}TFa2mOR#S-21H3MQT zAB^}YeL#D>>%5d2_D+?(u4W%(ujx{erPwCBiaF@{lF=s(A$^~7M}^q`O;QY-b?m-l z(_!lWB;C%%FAz%j&`Cry&RJ0)lK-EL?d7b3$``8Li6#GQ%?az9u~1i{ldSoK*UQtv zuw6x8(F4FTh?Q1yC@wJdJzzthwR6EaHodb&f~lI|pufvMdOnpCa|VA^CDdL>pkO<+ zWluoIG^4J+|4cHcfK02Yi9vFnY3c=eXXRh1>`dcKYMR&le?JKr=`C{? 4ak=QN5+Ok(i1wc; j=3V3KCpaP;1M=#H-tvDlw=&Fh+3;#wccd-99OB z78TR|U~t9V=h-o+W^=oMu5^qchJz8EI%Bp%fPYs#y6bGsF`j$yPOtP0bN!Q;l-0>| z8Ou0j-tS4f(=m67C+ST$PY!2g;#w`!e^f_b5?JePJxltV&-1XLw1NzrU@}TVz7f1q zzLReWU9$_5*9S!>h`?%glTPNZ*(NW5 QlcF~pu?n2I*oVyir#=-*dOx;z7VtfM=p0` z`iN8iLZLRaAAyr7tw%xB)NCvV47 ;=7tzpN4oJ&&OVvo!2Yx0hMl6_ko$2VZY5I6G4D@erUClfn(*SJ zS`d1FEBWQbcTziFYLRmO8^C(j1{P}Se-J?X58w(+>v#x*W@<$SvwN!u#10zeW|o~u zB<<=y_P+wApP1;9@l5|IArls78iHR#{pOT_frEu}emFh3+E74_AJn$K@;-X4zvN64 z7FN{9of{iE4s6SrtlPh_!^numD<`(d%u3usm0?o_UX=H){9oQ(Y}9ir^X5#F4}4V# zMc}$yl3!prY;z=+RIm_J24{V1hns+3X}~xM>G8obZWn{Yr7J1sOakv>9zJ!sPi^fe zM9ts_4=m5iQjh)AKX7f2DC0^7z!VYvcg4-iLSOaO^iDL%%No}Gqc``<+HCI`p9pH) zoEJWKlu{-G`;pHRv^m#+!_P(RjdCs(EYCCDQ*Tj~NwJ;~%&@;4|KP4ab%)@ZEM%ts z^$+2o91|-MQ^P^o7m=z@72e?S3LrReXtB}c&3`weKOjLZV9|V(|HD;p72(|E4oL;j z!nR`*rqA?|1EhS>Sv}iL@n>xyIRhfKVtMXgcmxJnzY9EweEZo~@X1s>%>fCW)A9tq zjmMD2{Zk`Td=t>WNqVgu4>f}a3mk}XwU_!+6xueHA@$a+Aut5&<`jJB0ZDpIjk_dN zsd9ZU0$r*l0Kk#tF{AeL@RIgASD}09gGAa{qK{39D{QQq>f(oTvZew*^?V>Dz1J4= z+pD$~5CdFb6lsAoU_c0l@^J_kEjL)$JqMN|yW<1Rw99s{ZV!qEV(W5pkWRWa z*oZQVwE7C#lsM**K^(jH_;4^@irb1Z#fLA(ioyxviC lpE*xDpa7c^N*W;BA)s?o-V~Ocy(3wsEOs{|A z*F`=AzRNu+Z*wF4E>&-pAtGsJBi>m)r6(!pfmm^*$HvbFa8 A9!Vi0mildofkxM1EMU-;!3@0 zQUKY0HT$_zQi8oK8#Y=9a;5OW-?h(N5 CD zVzT2t-lO&E{Sp0z e&K(sg0P_n=+zg0TmPJswd9(q$;;TRNc_hBwm?22YP8D6Z3W94LNH z`IxC%7W#1B)zsATYYQBBB=xl;N6aNaJWylSy5B-R_4aDkKqRdCV2)s1lcCy5Z*-Bm z)SaR4atbef;J2Cq!)?J4ICf*M0N0}z;jF)5oE>-xDYLW8*fkH+iusw>`kZ_z5=;Fz zb<@Q6*qF?7J@Hd7^G^TWH@yBrm|RQ*ytV4bzQY@RlNw((+ponSb!jW8yH6nl(<9oO zKH8<7_qCMGEq3s3my=(+^=lVbHHQ+PZs8UsVD~;wjEv6$p8M*QWT({CeQ$6GXQFjQ zBr%i)xm3+szcR9pmyNDZ_%YvaaAoz&BZ1=SGHRFD+_7FdqX6AU{BliU3Xk{Yg~<0M zCy-b4|8mJI9OSQPBeaOjx`!LT3ZWQzZfap(4Kye4JtM_WdBEnWfK*ZeNv)WkgZpMA zI;_7(zQjQ`EzH-YJ4lcw8O!5%v#dIjX
iY>}_2`IMjn0 zV`HjVf~lK7+S`@HJt?Qyv1v@U7eY^_`6&iFuu$s9W#1Go=S&&&{m3D33{j%?YJM<% zZH#fOH&Mx2Jl?qo4uOw75&<|2jKCSw1X(i?#zZfiG%dlAN_xTp0Gx$*K5(a7#pwXH zLxZVt;2SPwq2=Q&*EC+qp(wbiJBfjygT37FJ5?S0<~1XdpB9|h$axqyap2OOb56^i zp8C^H0IuBTuH(-)-A%Y*EQWc&I3#l;!Wcww`Os{6S0`w900m-(z!8#dcgrsGThiam zU9I1RNC=p(c0$NbPD@g;U(=>*MD?+T96+VAO`#EOn}uL_98q_9r+X07wx3gZ=xPLh z3yNVVhi3Z0NdUGKb9Y; 1#7$i#O4eCb}5l}0B3sOKc@kO0bQ Ui)S4s*S}-f#VJU5C~NA|HnDKctr5 z5r0gJQ*{VH!Ri5y`G$7vqOs;xY4jIU;TXwbf&;XmeK2gv$ULq`#1vj#styq|q`9Hy z4?1J+VerINCxPdTTnB>`RP-B6>I&)2m}GV{!*&e}WJYm9iW>>ySaYe+3gr8S!9yDL z4f_jIj>>Mu*hB~E+@&IAImd>X@vGy#Oo<*&bp@xUhI hXxMpvVyn8>*VEz3t$LKyUhFUC&r zwj}|aKdv<;2--|?j^!X?D9W1GtYP&sx0xHxAwe+d-L0Uc9WCJ@DyS;P)(i)+Je5xh zN*L5zH|h<%BrW;-PWED)=nz=Ub*2*PWWrGjuLtl@8q+GF>2W+oiDCKbAP^T6iZC%i z%9Lebvu%`H^A3yXGs_p;=8t-8=06vd;~m(> N=uf&hx}!U z=AhqF&{M3QWdQH6lTirc1uLpRJcqb5Fi*QAE6p_ksF?I4(u7%qBNg-Bm>-i7&ImwW zKM7yaz^kd~RR4a8{HBljFwOcUjPkh3fbkGrb7!O3JW|Jjb3jV Uk{$`}5DFK*tZLp`;KHlSHLC zRd(ARa`2y&%?#oTJc>gb$InZ?9h(MGjFuIe0c#%<^sK4c&YKSms9cJ7j8-4YEl3FL z_Sn@_`)FA6iZ-)PN?D9ik5pi;W<~8X#hz;quK z5eqhc)GWY$J=4&x7J6K*tDepzzp7Ovy1q%@)_VsB7d?|+G{%YBHf!x=fo9+_tFH@L z$y!veX0pDc;L`oG^RY(6Myzq5spcYX@u<_&uh}?tcxdibTV5f)#4G%kY7aXkSzYgu z%}8~JtSVTI@O>|3I7Vl9dLob{;fIoHOci&^(E&a>WH@f*PO{M-1om$a39S71!9u5= zjpMohj5 _PtirgP;>F(p<2h7JWH@ z+BYkh{h97v7T7)=nYwv62Zhdky6H!iRL}^FZX6PW3rd6?CsW5Om<3X!bMD0>DRF&% z xJFft!raiKW$+XfKZ($LIH3uA*iSL+9aU*E zktBDMAq?SXi)mXRYLcsswc|nTbh$-XgX1p61Ix^??D)6pxb~7b#6v(h+!sGa3p|0? zp$SQsDOn-{?)_mgEhY;mXOPir%BnLoOBdS4NWQSWe8Sy-!j)$??EHpQIF}rFG;dvP z9Qv!h?=9-9ZWxiUHU&b@>GOdJ4NB~tD=JPRPNABs^E4P7K8_4b7LQ+0VY$rSox5tQ zwblTX2|-U`Bi#JCO6jpOB8BHkkX(w0WP-Zf!+yzdvxX2RGrV8NqP&hEdO$R1Nk#1X zu_0iDO2FnOgSWqdIDNyLn4aj3)QI_b{_p5c+;xsO-MxQX2Ey~~ztw~A15(g46pimL zVap3(O5p5W)^X#BB;5ed9l&3zk4Oc1WVm-8lW2rBs%&yw|6l}~pE~RBU2^%db;r0K ztZ=PEUYjl!b48MAi^j>T+eEO6mtE*O ;q=8}A$&{q|$_+|;l_jsSTk64dO_4UkY@B4nDTORJI>uTP~qFt9MGMg)- z8n(A9dr?mj4Wnv#EAPc9`!6q {{U%qp z%Xc#Zp8{h)$?||`jP|1|PDTxJFKES7p)>Lgv_heoteq!sH|M*N BLQ22(QaP{zQIb#cvj)OBY9&&XqD({aIY z&G>e`CxM^A-gds}qg?be>ZetpH_@=FOMKogoxcOYm4fn}1|=3cs6U7wcr8ZO($p9x zJrW~b@V-3BdbCUL8Ls*8)SyE>g0s9hr?Ou@!c2+mtTRFemFa1o01EJMbQ0}qcLSxB z;vW9|7_BWz<8ZNt2iGqR5!!dyC3c(wSk65u{K29uys45JQX#*wve}p>@*#~MU6;ol zSc)(*{eFGu?Qz)7@BwU@37F7{ZDjXcN<|1gSOI}nXDi0|{ew?M)oZ!X5#~5x6lh3g z`wS$M?qsJk_j~iazO)-;Y9IU`h*l}8py}58mT1&BR@xm_nA7XqaHaCgi #;Ip@^*F#h!A%dy90UNj+vbw>2gbDA|!32C2g(zh5TFYs3_BMZFS2Pm#kWNwvgYG z2x41-g@(vT-et8<(-(TRb43 Lv$%)M&~T<-!sT!baX zse|i;M5WwRQ6IcViZ =y{^VPbY>=AM<6!VBlj!@~p-zAOAIVM)}0Jwr}(cd1OV0KVO+S8wn4-gzX9 z2S`g(Q3SF3pv&c)p8t#I7 ZBwnEo+YxE+tY(| z8j6ea9_`@H_rD+335h#E>yL{O{3dfAnv+i>qt~ptLXZpwpD0=*_ZE41SMH4C1JdQu z+TFU5mF73b*R$SSGX8>1LW09)-QZ1e8XFv~M)meY0!tw@?|CZ#*)e(VK2Ia xto|H znJND~xKs+3J$k0CM23cwRJ`#KX#>D70xaDnF+Y&uV{Bq#!!0lH$zcbZFVSsWSC)4O zLqx16-rGcm52s$fKuC^o9o4qdNJgxns-)iS!{sM2eVE4|{`Zd=B?|wqs~$1}JH1d* zAS6(aO_J1t-%d|p$~!xd RbgzJHN{zekuCO8MqVY-6c9`S$}!TpiBS)2q1u0sn=DxzH(LM)00o6 zVLhOR?VaOFy1|J^T)iSU!rNr~bYi#9@hHbhcJ%9i_N`Yd{!xI|WINl=uJ6acHux+K zm}F*9FBj%VEmU!N|L6)ICZ&_p`Tms|zldG=^$*5*`Nq9em>thngv_6v4y&}6tl`ft zxyWPY_jb0Y*CB<}M(?lDrxd%|k}zu>ti;LBwZ6>_S)C^zHS8iF5{`NncnMYvTdmry z@A@`(;fgC>UCD{p#CiA082c47`gk2Z*{>AOMxM@lZ0>JIm^ojN4RFSGvi*7c0`QUZ z8i9?}T8Bs5V*Y7~{aeK1dkz@UiRjz-W3YlpE<;I9AK%UD-Oo8g!ugLb{0vA(ZJdUi z;i$~{e0$JVx2TX17>`)>u)4-glk`ob$wB)RE@N36TTDIyWl3T%R~%-*+;kDcVib$r ztK>>q_bm#}L>yMOm40%b(L(^KhwLL}!~{GioT9Vm+T#+fys724v03FGAr9rb6chq2 zmU2AOc|nFdxg#dO8mCTTVYw&JLW4P(69002z!_ Z6FbO-i?i 2HA|OOVjsPMe8NRPhc&XQKj`rVcqivvx@0Rqx-o5b~ zAJ2 1*|3$FtHeq=mhj<;VH*q}L<_FZOM45jjl}r2@j@Buvtlhx+g4_) zle!R*1&L=SOqO*1Z`l5y^H(0es~X-l2T-!?7y^t@E767}nm8q|K490Cn>*fGYci&s zntTfn3)#PB_dp-Ls1HeKRg@~>9Lyz017Vc+P-T+b!-JW0E& Q%d_XOx=q zcgqP`n;vNE)i;23qm;qhv5?+ TsjXmMrYaV1Zlz zK#K0qu_^XYO>eGcpOQ#S5l|k66DPq^ylISsI{gUdDZ&YCr$CCP>bd?pvTMT5mbNOuM)*OKGUSS6v^C0Hm zqVUB?HlIRnX0LcCdA*ZM);#1V)QJF7<6QerkwCvFV72u#g4`7j9xu{dLGBpgT8ZPa z2nQMi=X3Lu4G%wIt`Wv5AjRPP%Y?+Pb`?L>p_38t)UO#o!E&^<51by ML_*akKv>+)XRY@TYV_eGFH{Z@SIv3f?zfA~Z3h2^#O&MW9slk= z>rz9MP^ozd&a>2YP1d`E8a!U%>6h9Wj)oKm*lOKIFjf^C+|tdLE=9Es3lo4hOP}o} z6@wh#^Nx0rz5eZ)k5fCCE=kmVg
1}@n(Q_a}3_QQE= z{}2WfgfGC-8H4#61@aFh5|hkuNjv0o7W8#`J?OI(oC?fl%bdH9zqWi N@ZQP+)Tr_g`(cbKbK)37wtSgYLo`Eu zGXGpnAcD1J53IJ{DBC6QTdcQkk6z A`+1-fcEfZ 4^#kINmE5b^EN0b*slQ`Q;SP9G#v6_6X%d{;#uzHSGa-}Iq5)qoFUwD|s10X1x zgVd930JM+z V}O^!R;!z=p^V_LQli2AUT@dX&Q^PD2Emb#y9EE>o)!f zp#ODrrF=1*>3Yxfi1fwqeJ(cSumerG63pJ*dgGjS4xla@@5cZW?%ej+`Z(u@ihVL9 zs*-t+D5}lP&S_cJoYOYv^n^qRh;egc*bnbq?7shmLB+(%j2$m|+891+OP9XQs+ktf&v& z@Ra>W(a7L%pZ6$3AZq-+X9hJ|G_RI~q3Z~0a2Tf4-5_5p^+S=`U%qghnVNJnaqxZl zG|#!dSXF2GkIZI`4i 7FoceL`C4SCb`1p^jGZ_8S z#7&cu*?1p;du3!19o#mjPH66>yfc`6&1uV;ap {2%0f3R60&N_YxwRJB (cbn?EMvi3@#yEFbVd z^VIt*c^yIf#Z>gQaO?PWiWjU~$dy^JtR(%$AUgg^Bq95;r@#l!#;pg)evd@XhAcu1 z5Qmd#p#swah{#2+B{c@nQs?hE8wbyEm$vi-DWQKJ?J~+ZG?5AF=*^=TeiOF}1%rb? znd@utCu_rg7{7=}CWTa4cKQJJgmjRF!95SR#QiWpy0oQQmRkI!1R9h(k27m*cgWTh zLIn@_uRE HEpKTY;0!h!D{zF6wqMxu 3Ej@e~_b>sNwL-E|cEy4q{r z@Q8sC1+)W;6w_nkX53NjgJ1(+Fy|EL|4A!sOM+qF%u~Ymm~eVETA$+!xezz2Nk^bf z7zfYr4U2GTNrXv{g#m@V2BK&}VQ_c (LV3?V;>OYFr`RZdpgUHDEABI{_K9+mnA {l4wOk)+& z%%8cw8|Uq`GCc1y5D}Cj`+8__2sO6eA>beXuMy>El2R?tkMJYwk3w=|EODVhogT~? zY7fG6ay!{c$c4LdRkEhxzq#!{){pr6lxWAl0AUtsIWA+&u6@u22B4d9q^5bQsh$+V z0AnxE6zlLac@e0*ht~@WK>7?5k7WG68?b@wkX}O%%88~4X#}Rak< g2tZyji7`{ZfpfqD6;gq-%p`EQZ@$Agyrk!+RjVx ztaBisOC+P40V~R!d7B}Z*5#KYc1L<(>3*PC@;qEG)zbvGf7Q0$8h;2#7hw=K8~W&6 zyKX!VV^=B;x@lW&U62Yf_O%c>w(-D^xPZ=<{8x}C{J!6<9gWtctC-dM1~Z(Z2g!n= z@9t8>-ATGIIulEyAnD@ (BkZ3Yeh9BEiTXy`-0TFAm$t+ypYO1^8G%g-@%m}W( z1(9`0PPzj9WeYbNveYdz8&Ti0-_I|kCm`y6uG`XaSn)FY|Iw#Z=l@SR3XA>UE5n@H zpNR>gheI{Mp5~^%Ro{EbE3b~*zKHV__sYlbDB_v8s8ghM)ARqh_p%Eo6mpDpcQSLJ zI&U3Z+;hO<*YB*OY5g5Bjrs*Q=EWf_c*1M1g-^ty!nrq9^w1FqhHwPLE25Tky%IZM zBd*Gd#U6vU&&1Zau=XDIt9Mf7;tagbAA3Jv9L*s&-)Ee(jp?Au&(AqqAOu`rEgNTf zRYcS7$_s%mZ~AdhCAZE4(LfNHASLe(1Vga+NX`H{gayc)g7&yRL?AameP4ubL^;4S z=#^qkVMdRp{Bw*9ESYw5=}**L{kZTb%KTzg3h0l%akjc@HzX|q7dqA#SoLKaBdyUt zQlSwl+y|`d{g^^s5jgjq(#ews!rJq<3!1 6$1A#czj6MTmY*nNF$EUQD9z z!j29{iewBZZeRG-%C;{nnr|UCC?0YAmDrSrOyNrpVk=e;Q~LIeUgO9knbzOY=VC04 z&-7yqkasgoBy;ruLA-00^R@&m5n@xjfY=lQ&J`74?H2A+8HK;QS^WTqn *Wf6l9!9KoE{R%WJu;EDFgYl`Md%4BqQtAfX>=Ky<4Os(%{^?+^!we1l z+0?T&UQK|4(tZuCa}?Od>pjTEsNFiD9TSv!zk5C&X+^e0%rz5myV2(@0D=et2q12U zHbcGE0eYsB{FDVMsJ_!{Z6EMb$0=` Rk SvMV8GZw4I&{5zm1L_ww8LWEqPu0dc00|myoEuu@WZed+7!^`b&N+t zyIBBE3sjAEv-Y9#DkbmX`M}29li{O`MjXk|nBHV%t3!d3`s*Y}+IU-U`z0fSvo~2M z_+4(;Lx(^0x=nu1<*W8h1VRDcKp39#C(X H+#SC{J;_hn7hD)DEX+m`c$M*Pw$b>3mJT HACOSB%U0oV-f-OqW>kuRKol7UheGDft0>iY*jv6 Vm7w&z2Lyaly}YTbrJB+Qmo2eutGGa=t~+ zv66GUJY4Ue6lbEGLEPH!kAB(oa^DwB@(gxWLkV#*ivdNyEuQ$Dm8KdwF;an0qyD&$ zh#ylFQ?ryy^hU~?>&{@PmPToah2gZz& wUwZ4kxq{aaF$Y_uS-JQ`W^W zj@YY#zkB_sP>LTkRQhf5S LK+fO}d7A zZ6R%UT>Wz whB$npWdDHq&l7e@V)hPpIUK})q1Y)s zS8(iW9gyA^0v#@P4;~trAl5u%b1zXb6YhH>xr0|02efLoni2!ODJ8M|2NxL)?(7oo zcfuu)bep`nkNc;#&I}``5K-G7091fX3CRPu_k_Jg123vLabturQa-v310W>V@Ko8v zJ>1L~-WKew4`;@Th#>7iZWEP1GQz#`+h$p<7ou)-6RuN8R3%H8Or{NXDwY+nz=9}z zl6idrKXlgr bwIQOHV{3};XT+TTsCX+w)Guv1_!F?vIF*ksi9%V@Kd?=Ent{KC z6Ma*dt>bp6T5qSdd~EzD`Ax5%(6%Hu{ICIr00FY_Bn*~#G5 D^l)3HaCxD?^<(^Dca->#MX>`d7IN^aF9>D8b!vrca#yNhc+=evs@AOhtb8q zkJoKJ?^nP1nfqxQEp1@e WQo!Dml4aVpBKwk0q>|dd^lhxS8rFL7c(=S=%5KlSW_W3_6>~N6#6AS z-Dt`oP?(F6&CTVSKWqPAwsbfeNJD@s#vn6WZ7xFeM+*2Klq7UqT#jn*B`D|l1+KAJ zC$YnL9fah-F^Gyo!_75ZTQ5poEKIwgW**t6*e#uf5&MK5e0_i}FTwnVD!$YryL8 thgp8b3bh^xfU6o}p?%W39?10bU%u z34jat#ox6&OaGAtnRtRcy6cY`2zxC&wf#Yr0>kDto$yy|FM;Er2&2ZvI*R!G8`!#u z)r<2M4R<~agBUVBU|*1SKK=eiBbayoyF3-|2XT@4+m+kM_(3a}g~b(!GqCP@VhS#= zkyTxVGnKe&n8TFe&8z%icU@GwN2{L z>yIs=4}WF>x!lWf*qJ<6tw}+sk#f?QOEiKG As70A8S)5}_ z_QzlvEkA>PS!2xp!k4UdS^QOid|>a^* 9OLbRWZFH X?L-h&~k~ouS|;C z-4fq^FE?!*4fZbM$0ag!Ca9J1GeiOwMUFtkw@2OS+5%3rA{f4jQ~5veSql+*{lu{7 zFitdqXME3;=b6oa&wj`&!7c`l^hU!5Aa&x7EV>o0nWsHsxAU}D|IBT|&mZFbQ=ikv zR$-FkOAWW{Idguh 2W(AP)L-^zer83pj60iNG#e9~0~}+K|HLUVewCuV3F!| zZXy*u+J9L7|3qqfnkb$7c#qFPlWcO4Yxl}Kye&*h2- W&?BZ4*_&_CZnzWcWu-VKx*pY{wpNLbYcmhKh;1=JKDMxPAh+QosHl0(b7`@PK z^ gg&Fbf~{g{v= zvADhruOAvvzq(_@^=HJ)`43B#W@aw&WT!8)a(SmG$R-GqQWwQwF _RYJLo1jK3R`y4vnHPt~u`1u;Eb>i9Ip zsvwpWEVc`-x38bdAvpissNrzCzCc8P3mGdvcFpS>9+>lb8&)zG`Kh#aoxrypA%!_x zh4mtcttaxtT_Ac}_IEEqYJ^lrbUK@=r10n8Y};(s@!r~0(Z9>2pD;z=2s;qR{Pup! zCA^W?`4yX2hdi{M90Qi1$^D3Q`xl+k`?@>n3ltTk|AUhRR s-TNB$St=-jt$tqoD%x@oWnmkSCtujj1+n$DkMEv3eX{)uo5?T@s6#oLP$}K zg)sS!&50JIVqidR%+fgbOaY-iWt8n8$nYcUmNJ$Bmm 0)bXf}u>Yelf7Ak479KDk2Hv zPTWW_ztuGv2W1JJTf~YiEY=n?sAtAKg!ubN+#HG}ZsDe@ye4PRDRarAwrW@VSG5|F z`f+ddcw@5=NKEq9kbdLg_zY(UYy8a{k#h%B(&iTYNuH+taHFLTuDarIXE`;z_z zQX#k6TVGML6~5=17bA^eQ^ymqRq<-c zB%a