From 709a382746ce445e6b082691065d6d078add948d Mon Sep 17 00:00:00 2001 From: vincent guyader Date: Wed, 13 Jul 2022 14:34:36 +0200 Subject: [PATCH] feat: add support for docker & {renv} (#882) Co-authored-by: Colin Fay --- DESCRIPTION | 8 +- NAMESPACE | 3 + NEWS.md | 10 + R/add_dockerfiles.R | 411 ++++++++++++++++------- R/add_dockerfiles_renv.R | 331 ++++++++++++++++++ R/utils.R | 4 +- README.Rmd | 2 +- README.md | 64 ++-- inst/shinyexample/dev/02_dev.R | 1 + inst/shinyexample/dev/03_deploy.R | 6 +- man/dockerfiles.Rd | 106 +++++- man/document_and_reload.Rd | 2 +- man/figures/logo.png | Bin 103244 -> 0 bytes tests/testthat/helper-config.R | 13 +- tests/testthat/test-add_deploy_helpers.R | 52 --- tests/testthat/test-renv_stuff.R | 33 ++ vignettes/a_start.Rmd | 4 +- vignettes/b_dev.Rmd | 4 +- vignettes/c_deploy.Rmd | 76 +++++ 19 files changed, 885 insertions(+), 245 deletions(-) create mode 100644 R/add_dockerfiles_renv.R delete mode 100644 man/figures/logo.png create mode 100644 tests/testthat/test-renv_stuff.R diff --git a/DESCRIPTION b/DESCRIPTION index a64825f8..d63fc9b1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: golem Title: A Framework for Robust Shiny Applications -Version: 0.3.2 +Version: 0.3.3 Authors@R: c(person(given = "Colin", family = "Fay", @@ -68,7 +68,7 @@ Suggests: rlang, covr, devtools, - dockerfiler (>= 0.1.4), + dockerfiler (>= 0.2.0), knitr, pkgbuild, pkgdown, @@ -82,11 +82,11 @@ Suggests: testthat, tools, withr, - attachment + attachment (>= 0.2.5) VignetteBuilder: knitr Config/testthat/edition: 3 Encoding: UTF-8 Language: en-US Roxygen: list(markdown = TRUE) -RoxygenNote: 7.1.2 +RoxygenNote: 7.2.0 diff --git a/NAMESPACE b/NAMESPACE index 7f527830..f31af341 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,9 @@ export(add_css_file) export(add_dockerfile) export(add_dockerfile_heroku) export(add_dockerfile_shinyproxy) +export(add_dockerfile_with_renv) +export(add_dockerfile_with_renv_heroku) +export(add_dockerfile_with_renv_shinyproxy) export(add_fct) export(add_html_template) export(add_js_file) diff --git a/NEWS.md b/NEWS.md index 5d483926..6d0f6614 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,15 @@ > Notes: the # between parenthesis referes to the related issue on GitHub, and the @ refers to an external contributor solving this issue. +# golem 0.3.3 + +## New functions + ++ `add_dockerfile_with_renv()`, `add_dockerfile_with_renv_heroku()` and `add_dockerfile_with_renv_shinyproxy()` build Dockerfiles that rely on `{renv}` + +### Soft deprecated + ++ `add_dockerfile`, `add_dockerfile_shinyproxy()` and `add_dockerfile_heroku()` now recommend to switch to their `_with_renv_` counterpart + # golem 0.3.2 ### Soft deprecated diff --git a/R/add_dockerfiles.R b/R/add_dockerfiles.R index 6bd0dc07..df3bb111 100644 --- a/R/add_dockerfiles.R +++ b/R/add_dockerfiles.R @@ -1,7 +1,18 @@ +talk_once <- function(.f, msg = "") { + talk <- TRUE + function(...) { + if (talk) { + talk <<- FALSE + cat_red_bullet(msg) + } + .f(...) + } +} + #' Create a Dockerfile for your App #' -#' Build a container containing your Shiny App. `add_dockerfile()` creates -#' a generic Dockerfile, while `add_dockerfile_shinyproxy()` and +#' Build a container containing your Shiny App. `add_dockerfile()` and `add_dockerfile_with_renv()` creates +#' a generic Dockerfile, while `add_dockerfile_shinyproxy()`, `add_dockerfile_with_renv_shinyproxy()` and #' `add_dockerfile_heroku()` creates platform specific Dockerfile. #' #' @inheritParams add_module @@ -9,7 +20,12 @@ #' @param path path to the DESCRIPTION file to use as an input. #' @param output name of the Dockerfile output. #' @param from The FROM of the Dockerfile. Default is -#' FROM rocker/r-ver:`R.Version()$major`.`R.Version()$minor`. +#' +#' FROM rocker/verse +#' +#' without renv.lock file passed +#' `R.Version()$major`.`R.Version()$minor` is used as tag +#' #' @param as The AS of the Dockerfile. Default it NULL. #' @param port The `options('shiny.port')` on which to run the App. #' Default is 80. @@ -18,13 +34,12 @@ #' @param sysreqs boolean. If TRUE, the Dockerfile will contain sysreq installation. #' @param repos character. The URL(s) of the repositories to use for `options("repos")`. #' @param expand boolean. If `TRUE` each system requirement will have its own `RUN` line. -#' @param open boolean. Should the Dockerfile be open after creation? Default is `TRUE`. +#' @param open boolean. Should the Dockerfile/README be open after creation? Default is `TRUE`. #' @param build_golem_from_source boolean. If `TRUE` no tar.gz is created and #' the Dockerfile directly mount the source folder. #' @param update_tar_gz boolean. If `TRUE` and `build_golem_from_source` is also `TRUE`, #' an updated tar.gz is created. #' @param extra_sysreqs character vector. Extra debian system requirements. -#' Will be installed with apt-get install. #' #' @export #' @rdname dockerfiles @@ -40,10 +55,28 @@ #' if (interactive()) { #' add_dockerfile() #' } +#' # Crete a 'deploy' folder containing everything needed to deploy +#' # the golem using docker based on {renv} +#' if (interactive()) { +#' add_dockerfile_with_renv( +#' # lockfile = "renv.lock", # uncomment to use existing renv.lock file +#' output_dir = "deploy" +#' ) +#' } #' # Add a Dockerfile for ShinyProxy #' if (interactive()) { #' add_dockerfile_shinyproxy() #' } +#' +#' # Crete a 'deploy' folder containing everything needed to deploy +#' # the golem with ShinyProxy using docker based on {renv} +#' if (interactive()) { +#' add_dockerfile_with_renv( +#' # lockfile = "renv.lock",# uncomment to use existing renv.lock file +#' output_dir = "deploy" +#' ) +#' } +#' #' # Add a Dockerfile for Heroku #' if (interactive()) { #' add_dockerfile_heroku() @@ -55,7 +88,7 @@ add_dockerfile <- function( output = "Dockerfile", pkg = get_golem_wd(), from = paste0( - "rocker/r-ver:", + "rocker/verse:", R.Version()$major, ".", R.Version()$minor @@ -71,54 +104,96 @@ add_dockerfile <- function( build_golem_from_source = TRUE, extra_sysreqs = NULL ) { - check_is_installed("dockerfiler") - - required_version("dockerfiler", "0.1.4") - - where <- path(pkg, output) - - usethis::use_build_ignore(path_file(where)) - - dock <- dockerfiler::dock_from_desc( + add_dockerfile_( path = path, - FROM = from, - AS = as, + output = output, + pkg = pkg, + from = from, + as = as, + port = port, + host = host, sysreqs = sysreqs, repos = repos, expand = expand, - build_from_source = build_golem_from_source, + open = open, update_tar_gz = update_tar_gz, + build_golem_from_source = build_golem_from_source, extra_sysreqs = extra_sysreqs ) +} - dock$EXPOSE(port) +add_dockerfile_ <- talk_once( + function( + path = "DESCRIPTION", + output = "Dockerfile", + pkg = get_golem_wd(), + from = paste0( + "rocker/verse:", + R.Version()$major, + ".", + R.Version()$minor + ), + as = NULL, + port = 80, + host = "0.0.0.0", + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + open = TRUE, + update_tar_gz = TRUE, + build_golem_from_source = TRUE, + extra_sysreqs = NULL + ) { + check_is_installed("dockerfiler") - dock$CMD( - sprintf( - "R -e \"options('shiny.port'=%s,shiny.host='%s');%s::run_app()\"", - port, - host, - read.dcf(path)[1] + required_version("dockerfiler", "0.1.4") + + where <- path(pkg, output) + + usethis::use_build_ignore(path_file(where)) + + dock <- dockerfiler::dock_from_desc( + path = path, + FROM = from, + AS = as, + sysreqs = sysreqs, + repos = repos, + expand = expand, + build_from_source = build_golem_from_source, + update_tar_gz = update_tar_gz, + extra_sysreqs = extra_sysreqs ) - ) - dock$write(output) + dock$EXPOSE(port) - if (open) { - if (rstudioapi::isAvailable() & rstudioapi::hasFun("navigateToFile")) { - rstudioapi::navigateToFile(output) - } else { - try(file.edit(output)) + dock$CMD( + sprintf( + "R -e \"options('shiny.port'=%s,shiny.host='%s');%s::run_app()\"", + port, + host, + read.dcf(path)[1] + ) + ) + + dock$write(output) + + if (open) { + if (rstudioapi::isAvailable() & rstudioapi::hasFun("navigateToFile")) { + rstudioapi::navigateToFile(output) + } else { + try(file.edit(output)) + } } - } - alert_build( - path = path, - output = output, - build_golem_from_source = build_golem_from_source - ) + alert_build( + path = path, + output = output, + build_golem_from_source = build_golem_from_source + ) - return(invisible(dock)) -} + return(invisible(dock)) + }, + "golem::add_dockerfile() is not recommended anymore.\nPlease use golem::add_dockerfile_with_renv() instead." +) #' @export #' @rdname dockerfiles @@ -128,7 +203,7 @@ add_dockerfile_shinyproxy <- function( output = "Dockerfile", pkg = get_golem_wd(), from = paste0( - "rocker/r-ver:", + "rocker/verse:", R.Version()$major, ".", R.Version()$minor @@ -142,47 +217,84 @@ add_dockerfile_shinyproxy <- function( build_golem_from_source = TRUE, extra_sysreqs = NULL ) { - check_is_installed("dockerfiler") - required_version("dockerfiler", "0.1.4") - - where <- path(pkg, output) - - usethis::use_build_ignore(output) - - dock <- dockerfiler::dock_from_desc( + add_dockerfile_shinyproxy_( path = path, - FROM = from, - AS = as, + output = output, + pkg = pkg, + from = from, + as = as, sysreqs = sysreqs, repos = repos, expand = expand, - build_from_source = build_golem_from_source, + open = open, update_tar_gz = update_tar_gz, + build_golem_from_source = build_golem_from_source, extra_sysreqs = extra_sysreqs ) +} + +add_dockerfile_shinyproxy_ <- talk_once( + function( + path = "DESCRIPTION", + output = "Dockerfile", + pkg = get_golem_wd(), + from = paste0( + "rocker/verse:", + R.Version()$major, + ".", + R.Version()$minor + ), + as = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + open = TRUE, + update_tar_gz = TRUE, + build_golem_from_source = TRUE, + extra_sysreqs = NULL + ) { + check_is_installed("dockerfiler") + required_version("dockerfiler", "0.1.4") + where <- path(pkg, output) - dock$EXPOSE(3838) - dock$CMD(sprintf( - " [\"R\", \"-e\", \"options('shiny.port'=3838,shiny.host='0.0.0.0');%s::run_app()\"]", - read.dcf(path)[1] - )) - dock$write(output) + usethis::use_build_ignore(output) - if (open) { - if (rstudioapi::isAvailable() & rstudioapi::hasFun("navigateToFile")) { - rstudioapi::navigateToFile(output) - } else { - try(file.edit(output)) + dock <- dockerfiler::dock_from_desc( + path = path, + FROM = from, + AS = as, + sysreqs = sysreqs, + repos = repos, + expand = expand, + build_from_source = build_golem_from_source, + update_tar_gz = update_tar_gz, + extra_sysreqs = extra_sysreqs + ) + + dock$EXPOSE(3838) + dock$CMD(sprintf( + " [\"R\", \"-e\", \"options('shiny.port'=3838,shiny.host='0.0.0.0');%s::run_app()\"]", + read.dcf(path)[1] + )) + dock$write(output) + + if (open) { + if (rstudioapi::isAvailable() & rstudioapi::hasFun("navigateToFile")) { + rstudioapi::navigateToFile(output) + } else { + try(file.edit(output)) + } } - } - alert_build( - path, - output, - build_golem_from_source = build_golem_from_source - ) + alert_build( + path, + output, + build_golem_from_source = build_golem_from_source + ) - return(invisible(dock)) -} + return(invisible(dock)) + }, + "golem::add_dockerfile_shinyproxy() is not recommended anymore.\nPlease use golem::add_dockerfile_with_renv_shinyproxy() instead." +) #' @export #' @rdname dockerfiles @@ -192,7 +304,7 @@ add_dockerfile_heroku <- function( output = "Dockerfile", pkg = get_golem_wd(), from = paste0( - "rocker/r-ver:", + "rocker/verse:", R.Version()$major, ".", R.Version()$minor @@ -206,77 +318,116 @@ add_dockerfile_heroku <- function( build_golem_from_source = TRUE, extra_sysreqs = NULL ) { - check_is_installed("dockerfiler") - required_version("dockerfiler", "0.1.4") - - where <- path(pkg, output) - - usethis::use_build_ignore(output) - - dock <- dockerfiler::dock_from_desc( + add_dockerfile_heroku_( path = path, - FROM = from, - AS = as, + output = output, + pkg = pkg, + from = from, + as = as, sysreqs = sysreqs, repos = repos, expand = expand, - build_from_source = build_golem_from_source, + open = open, update_tar_gz = update_tar_gz, + build_golem_from_source = build_golem_from_source, extra_sysreqs = extra_sysreqs ) +} - dock$CMD( - sprintf( - "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');%s::run_app()\"", - read.dcf(path)[1] +add_dockerfile_heroku_ <- talk_once( + function( + path = "DESCRIPTION", + output = "Dockerfile", + pkg = get_golem_wd(), + from = paste0( + "rocker/verse:", + R.Version()$major, + ".", + R.Version()$minor + ), + as = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + open = TRUE, + update_tar_gz = TRUE, + build_golem_from_source = TRUE, + extra_sysreqs = NULL + ) { + check_is_installed("dockerfiler") + required_version("dockerfiler", "0.1.4") + where <- path(pkg, output) + + usethis::use_build_ignore(output) + + dock <- dockerfiler::dock_from_desc( + path = path, + FROM = from, + AS = as, + sysreqs = sysreqs, + repos = repos, + expand = expand, + build_from_source = build_golem_from_source, + update_tar_gz = update_tar_gz, + extra_sysreqs = extra_sysreqs ) - ) - dock$write(output) - alert_build( - path = path, - output = output, - build_golem_from_source = build_golem_from_source - ) + dock$CMD( + sprintf( + "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');%s::run_app()\"", + read.dcf(path)[1] + ) + ) + dock$write(output) - apps_h <- gsub( - "\\.", - "-", - sprintf( - "%s-%s", - read.dcf(path)[1], - read.dcf(path)[1, ][["Version"]] + alert_build( + path = path, + output = output, + build_golem_from_source = build_golem_from_source ) - ) - cat_rule("From your command line, run:") - cat_line("heroku container:login") - cat_line( - sprintf("heroku create %s", apps_h) - ) - cat_line( - sprintf("heroku container:push web --app %s", apps_h) - ) - cat_line( - sprintf("heroku container:release web --app %s", apps_h) - ) - cat_line( - sprintf("heroku open --app %s", apps_h) - ) - cat_red_bullet("Be sure to have the heroku CLI installed.") - cat_red_bullet( - sprintf("You can replace %s with another app name.", apps_h) - ) - if (open) { - if (rstudioapi::isAvailable() & rstudioapi::hasFun("navigateToFile")) { - rstudioapi::navigateToFile(output) - } else { - try(file.edit(output)) + apps_h <- gsub( + "\\.", + "-", + sprintf( + "%s-%s", + read.dcf(path)[1], + read.dcf(path)[1, ][["Version"]] + ) + ) + + cat_rule("From your command line, run:") + cat_line("heroku container:login") + cat_line( + sprintf("heroku create %s", apps_h) + ) + cat_line( + sprintf("heroku container:push web --app %s", apps_h) + ) + cat_line( + sprintf("heroku container:release web --app %s", apps_h) + ) + cat_line( + sprintf("heroku open --app %s", apps_h) + ) + cat_red_bullet("Be sure to have the heroku CLI installed.") + cat_red_bullet( + sprintf("You can replace %s with another app name.", apps_h) + ) + if (open) { + if (rstudioapi::isAvailable() & rstudioapi::hasFun("navigateToFile")) { + rstudioapi::navigateToFile(output) + } else { + try(file.edit(output)) + } } - } - usethis::use_build_ignore(files = output) - return(invisible(dock)) -} + usethis::use_build_ignore(files = output) + return(invisible(dock)) + }, + " +golem::add_dockerfile_heroku() is not recommended anymore.\nPlease use golem::add_dockerfile_with_renv_heroku() instead. +" +) alert_build <- function( path, @@ -294,4 +445,4 @@ alert_build <- function( ) ) } -} \ No newline at end of file +} diff --git a/R/add_dockerfiles_renv.R b/R/add_dockerfiles_renv.R new file mode 100644 index 00000000..80fb9d61 --- /dev/null +++ b/R/add_dockerfiles_renv.R @@ -0,0 +1,331 @@ +add_dockerfile_with_renv_ <- function( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + FROM = "rocker/verse", + AS = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + extra_sysreqs = NULL, + update_tar_gz = TRUE + # build_golem_from_source = TRUE, +) { + check_is_installed("renv") + check_is_installed("dockerfiler") + required_version("dockerfiler", "0.2.0") + check_is_installed("attachment") + + # Small hack to prevent warning from rlang::lang() in tests + # This should be managed in {attempt} later on + x <- suppressWarnings({ + rlang::lang(print) + }) + + dir.create(output_dir) + + # add output_dir in Rbuildignore if the output is inside the golem + if (normalizePath(dirname(output_dir)) == normalizePath(source_folder)) { + usethis::use_build_ignore(output_dir) + } + + if (is.null(lockfile)) { + lockfile <- attachment::create_renv_for_prod(path = source_folder, output = file.path(output_dir, "renv.lock.prod")) + } + + file.copy(from = lockfile, to = output_dir) + + socle <- dockerfiler::dock_from_renv( + lockfile = lockfile, + distro = distro, + FROM = FROM, + repos = repos, + AS = AS, + sysreqs = sysreqs, + expand = expand, + extra_sysreqs = extra_sysreqs + ) + + socle$write(as = file.path(output_dir, "Dockerfile_base")) + + my_dock <- dockerfiler::Dockerfile$new(FROM = paste0(golem::get_golem_name(), "_base")) + + my_dock$COPY("renv.lock.prod", "renv.lock") + + my_dock$RUN("R -e 'renv::restore()'") + + if (update_tar_gz) { + old_version <- list.files(path = output_dir, pattern = paste0(golem::get_golem_name(), "_*.*.tar.gz"), full.names = TRUE) + # file.remove(old_version) + if (length(old_version) > 0) { + lapply(old_version, file.remove) + lapply(old_version, unlink, force = TRUE) + cat_red_bullet( + sprintf( + "%s were removed from folder", + paste( + old_version, + collapse = ", " + ) + ) + ) + } + + if ( + isTRUE( + requireNamespace( + "pkgbuild", + quietly = TRUE + ) + ) + ) { + out <- pkgbuild::build( + path = ".", + dest_path = output_dir, + vignettes = FALSE + ) + if (missing(out)) { + cat_red_bullet("Error during tar.gz building") + } else { + cat_green_tick( + sprintf( + " %s created.", + out + ) + ) + } + } else { + stop("please install {pkgbuild}") + } + } + + # we use an already built tar.gz file + my_dock$COPY( + from = + paste0(golem::get_golem_name(), "_*.tar.gz"), + to = "/app.tar.gz" + ) + my_dock$RUN("R -e 'remotes::install_local(\"/app.tar.gz\",upgrade=\"never\")'") + my_dock$RUN("rm /app.tar.gz") + my_dock +} + +#' @param source_folder path to the Package/golem source folder to deploy. +#' default is current folder '.' +#' @param lockfile path to the renv.lock file to use. default is `NULL` +#' @param output_dir folder to export everything deployment related. +#' @param distro One of "focal", "bionic", "xenial", "centos7", or "centos8". +#' See available distributions at https://hub.docker.com/r/rstudio/r-base/. +#' @param dockerfile_cmd What is the CMD to add to the Dockerfile. If NULL, the default, +#' the CMD will be `R -e "options('shiny.port'={port},shiny.host='{host}');{appname}::run_app()\` +#' @inheritParams add_dockerfile +#' @rdname dockerfiles +#' @export +add_dockerfile_with_renv <- function( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + from = "rocker/verse", + as = NULL, + sysreqs = TRUE, + port = 80, + host = "0.0.0.0", + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + open = TRUE, + extra_sysreqs = NULL, + update_tar_gz = TRUE, + dockerfile_cmd = NULL +) { + base_dock <- add_dockerfile_with_renv_( + source_folder = source_folder, + lockfile = lockfile, + output_dir = output_dir, + distro = distro, + FROM = from, + AS = as, + sysreqs = sysreqs, + repos = repos, + expand = expand, + extra_sysreqs = extra_sysreqs, + update_tar_gz = update_tar_gz + ) + if (!is.null(port)) { + base_dock$EXPOSE(port) + } + if (is.null(dockerfile_cmd)) { + dockerfile_cmd <- sprintf( + "R -e \"options('shiny.port'=%s,shiny.host='%s');%s::run_app()\"", + port, + host, + golem::get_golem_name() + ) + } + base_dock$CMD( + dockerfile_cmd + ) + base_dock + base_dock$write(as = file.path(output_dir, "Dockerfile")) + + out <- sprintf( + "docker build -f Dockerfile_base --progress=plain -t %s . +docker build -f Dockerfile --progress=plain -t %s . +docker run -p %s:%s %s +# then go to 127.0.0.1:%s", + paste0(golem::get_golem_name(), "_base"), + paste0(golem::get_golem_name(), ":latest"), + port, + port, + paste0(golem::get_golem_name(), ":latest"), + port + ) + + cat(out, file = file.path(output_dir, "README")) + + open_or_go_to( + where = file.path(output_dir, "README"), + open_file = open + ) +} + +#' @inheritParams add_dockerfile +#' @rdname dockerfiles +#' @export +#' @export +add_dockerfile_with_renv_shinyproxy <- function( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + from = "rocker/verse", + as = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + extra_sysreqs = NULL, + open = TRUE, + update_tar_gz = TRUE +) { + add_dockerfile_with_renv( + source_folder = source_folder, + lockfile = lockfile, + output_dir = output_dir, + distro = distro, + from = from, + as = as, + sysreqs = sysreqs, + repos = repos, + expand = expand, + port = 3838, + host = "0.0.0.0", + extra_sysreqs = extra_sysreqs, + update_tar_gz = update_tar_gz, + open = open, + dockerfile_cmd = sprintf( + "R -e \"options('shiny.port'=3838,shiny.host='0.0.0.0');%s::run_app()\"", + golem::get_golem_name() + ) + ) +} + +#' @inheritParams add_dockerfile +#' @rdname dockerfiles +#' @export +#' @export +add_dockerfile_with_renv_heroku <- function( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + from = "rocker/verse", + as = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + extra_sysreqs = NULL, + open = TRUE, + update_tar_gz = TRUE +) { + add_dockerfile_with_renv( + source_folder = source_folder, + lockfile = lockfile, + output_dir = output_dir, + distro = distro, + from = from, + as = as, + sysreqs = sysreqs, + repos = repos, + expand = expand, + port = NULL, + host = "0.0.0.0", + extra_sysreqs = extra_sysreqs, + update_tar_gz = update_tar_gz, + open = FALSE, + dockerfile_cmd = sprintf( + "R -e \"options('shiny.port'=$PORT,shiny.host='0.0.0.0');%s::run_app()\"", + golem::get_golem_name() + ) + ) + + apps_h <- gsub( + "\\.", + "-", + sprintf( + "%s-%s", + golem::get_golem_name(), + golem::get_golem_version() + ) + ) + + readme_output <- file.path(output_dir, "README") + + write_there <- function(...) { + write(..., file = readme_output, append = TRUE) + } + + write_there("From your command line, run:\n") + + write_there( + sprintf( + "docker build -f Dockerfile_base --progress=plain -t %s .", + paste0(golem::get_golem_name(), "_base") + ) + ) + + write_there( + sprintf( + "docker build -f Dockerfile --progress=plain -t %s .\n", + paste0(golem::get_golem_name(), ":latest") + ) + ) + + write_there("Then, to push on heroku:\n") + + write_there("heroku container:login") + write_there( + sprintf("heroku create %s", apps_h) + ) + write_there( + sprintf("heroku container:push web --app %s", apps_h) + ) + write_there( + sprintf("heroku container:release web --app %s", apps_h) + ) + write_there( + sprintf("heroku open --app %s\n", apps_h) + ) + write_there("> Be sure to have the heroku CLI installed.") + + write_there( + sprintf("> You can replace %s with another app name.", apps_h) + ) + + # The open is deported here just to be sure + # That we open the README once it has been populated + open_or_go_to( + where = readme_output, + open_file = open + ) +} diff --git a/R/utils.R b/R/utils.R index e95d3b2d..ae3200ea 100644 --- a/R/utils.R +++ b/R/utils.R @@ -17,8 +17,8 @@ darkgrey <- function(x) { } #' @importFrom fs dir_exists file_exists -dir_not_exist <- Negate(dir_exists) -file_not_exist <- Negate(file_exists) +dir_not_exist <- Negate(fs::dir_exists) +file_not_exist <- Negate(fs::file_exists) #' @importFrom fs dir_create file_create create_if_needed <- function( diff --git a/README.Rmd b/README.Rmd index c06f5466..ad948985 100644 --- a/README.Rmd +++ b/README.Rmd @@ -88,7 +88,7 @@ This package is part of a series of tools for Shiny, which includes: These are examples from the community. Please note that they may not necessarily be written in a canonical fashion and may have been written with different versions of `{golem}` or `{shiny}`. - -- +- - - diff --git a/README.md b/README.md index 8ceefc47..19bddce1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ - [![Lifecycle: @@ -24,33 +23,33 @@ You’re reading the doc about version : ``` r desc::desc_get_version() -#> [1] '0.3.2' +#> [1] '0.3.3' ``` ## Tool series This package is part of a series of tools for Shiny, which includes: - - `{golem}` - - - `{shinipsum}` - - - `{fakir}` - - - `{shinysnippets}` - +- `{golem}` - +- `{shinipsum}` - +- `{fakir}` - +- `{shinysnippets}` - ## Resources ### The Book : - - - - [paper version of the book “Engineering Production-Grade Shiny +- +- [paper version of the book “Engineering Production-Grade Shiny Apps”](https://www.routledge.com/Engineering-Production-Grade-Shiny-Apps/Fay-Rochette-Guyader-Girard/p/book/9780367466022) ### Blog posts : *Building Big Shiny Apps* - - Part 1: +- Part 1: - - Part 2: +- Part 2: [*Make a Fitness App from @@ -58,34 +57,34 @@ scratch*](https://towardsdatascience.com/production-grade-r-shiny-with-golem-pro ### Slide decks - - useR\! 2019 : [A Framework for Building Robust & Production Ready +- useR! 2019 : [A Framework for Building Robust & Production Ready Shiny Apps](https://github.com/VincentGuyader/user2019/raw/master/golem_Vincent_Guyader_USER!2019.pdf) - - ThinkR x RStudio Roadshow,Paris : [Production-grade Shiny Apps with +- ThinkR x RStudio Roadshow,Paris : [Production-grade Shiny Apps with {golem}](https://speakerdeck.com/colinfay/production-grade-shiny-apps-with-golem) - - rstudio::conf(2020) : [Production-grade Shiny Apps with +- rstudio::conf(2020) : [Production-grade Shiny Apps with golem](https://speakerdeck.com/colinfay/rstudio-conf-2020-production-grade-shiny-apps-with-golem) - - barcelonar (2019-12-03) : [Engineering Production-Grade Shiny Apps +- barcelonar (2019-12-03) : [Engineering Production-Grade Shiny Apps with {golem}](https://www.barcelonar.org/presentations/BarcelonaR_Building_Production_Grade_Shiny_Apps_with_golem.pdf) ### Video - - [{golem} and Effective Shiny Development +- [{golem} and Effective Shiny Development Methods](https://www.youtube.com/watch?v=OU1-CkSVdTI) - - [Hands-on demonstration of +- [Hands-on demonstration of {golem}](https://www.youtube.com/watch?v=3-p9XLvoJV0) - - useR\! 2019 : [A Framework for Building Robust & Production Ready +- useR! 2019 : [A Framework for Building Robust & Production Ready Shiny Apps](https://youtu.be/tCAan6smrjs) - - 🇫🇷 [Introduction to {golem}](https://youtu.be/6qI4NzxlAFU) - - rstudio::conf(2020) : [Production-grade Shiny Apps with +- 🇫🇷 [Introduction to {golem}](https://youtu.be/6qI4NzxlAFU) +- rstudio::conf(2020) : [Production-grade Shiny Apps with golem](https://www.rstudio.com/resources/rstudioconf-2020/production-grade-shiny-apps-with-golem/) - - 🇫🇷 Rencontres R 2021 : [Conception d’applications Shiny avec +- 🇫🇷 Rencontres R 2021 : [Conception d’applications Shiny avec {golem}](https://www.youtube.com/watch?v=0f5Me1PFGDs) ### Cheatsheet - - [{golem} cheatsheet](https://thinkr.fr/golem_cheatsheet_v0.1.pdf) +- [{golem} cheatsheet](https://thinkr.fr/golem_cheatsheet_v0.1.pdf) ### Examples apps @@ -93,31 +92,27 @@ These are examples from the community. Please note that they may not necessarily be written in a canonical fashion and may have been written with different versions of `{golem}` or `{shiny}`. - - - - - - - - +- +- +- +- You can also find apps at: - - - - +- +- ## Installation - - You can install the stable version from CRAN with: - - +- You can install the stable version from CRAN with: ``` r install.packages("golem") ``` - - You can install the development version from +- You can install the development version from [GitHub](https://github.com/Thinkr-open/golem) with: - - ``` r # install.packages("remotes") remotes::install_github("Thinkr-open/golem") @@ -125,8 +120,7 @@ remotes::install_github("Thinkr-open/golem") ## Launch the project -Create a new package with the project -template: +Create a new package with the project template: diff --git a/inst/shinyexample/dev/02_dev.R b/inst/shinyexample/dev/02_dev.R index 82478726..67699ea7 100644 --- a/inst/shinyexample/dev/02_dev.R +++ b/inst/shinyexample/dev/02_dev.R @@ -15,6 +15,7 @@ ## Dependencies ---- ## Amend DESCRIPTION with dependencies read from package code parsing +## install.package('attachment') # if needed. attachment::att_amend_desc() ## Add modules ---- diff --git a/inst/shinyexample/dev/03_deploy.R b/inst/shinyexample/dev/03_deploy.R index 464d59fd..2f9595ef 100644 --- a/inst/shinyexample/dev/03_deploy.R +++ b/inst/shinyexample/dev/03_deploy.R @@ -33,10 +33,8 @@ golem::add_shinyserver_file() ## Docker ---- ## If you want to deploy via a generic Dockerfile -golem::add_dockerfile() +golem::add_dockerfile_with_renv() ## If you want to deploy to ShinyProxy -golem::add_dockerfile_shinyproxy() +golem::add_dockerfile_with_renv_shinyproxy() -## If you want to deploy to Heroku -golem::add_dockerfile_heroku() diff --git a/man/dockerfiles.Rd b/man/dockerfiles.Rd index bbeb97b4..53129521 100644 --- a/man/dockerfiles.Rd +++ b/man/dockerfiles.Rd @@ -1,16 +1,19 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/add_dockerfiles.R +% Please edit documentation in R/add_dockerfiles.R, R/add_dockerfiles_renv.R \name{add_dockerfile} \alias{add_dockerfile} \alias{add_dockerfile_shinyproxy} \alias{add_dockerfile_heroku} +\alias{add_dockerfile_with_renv} +\alias{add_dockerfile_with_renv_shinyproxy} +\alias{add_dockerfile_with_renv_heroku} \title{Create a Dockerfile for your App} \usage{ add_dockerfile( path = "DESCRIPTION", output = "Dockerfile", pkg = get_golem_wd(), - from = paste0("rocker/r-ver:", R.Version()$major, ".", R.Version()$minor), + from = paste0("rocker/verse:", R.Version()$major, ".", R.Version()$minor), as = NULL, port = 80, host = "0.0.0.0", @@ -27,7 +30,7 @@ add_dockerfile_shinyproxy( path = "DESCRIPTION", output = "Dockerfile", pkg = get_golem_wd(), - from = paste0("rocker/r-ver:", R.Version()$major, ".", R.Version()$minor), + from = paste0("rocker/verse:", R.Version()$major, ".", R.Version()$minor), as = NULL, sysreqs = TRUE, repos = c(CRAN = "https://cran.rstudio.com/"), @@ -42,7 +45,7 @@ add_dockerfile_heroku( path = "DESCRIPTION", output = "Dockerfile", pkg = get_golem_wd(), - from = paste0("rocker/r-ver:", R.Version()$major, ".", R.Version()$minor), + from = paste0("rocker/verse:", R.Version()$major, ".", R.Version()$minor), as = NULL, sysreqs = TRUE, repos = c(CRAN = "https://cran.rstudio.com/"), @@ -52,6 +55,54 @@ add_dockerfile_heroku( build_golem_from_source = TRUE, extra_sysreqs = NULL ) + +add_dockerfile_with_renv( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + from = "rocker/verse", + as = NULL, + sysreqs = TRUE, + port = 80, + host = "0.0.0.0", + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + open = TRUE, + extra_sysreqs = NULL, + update_tar_gz = TRUE, + dockerfile_cmd = NULL +) + +add_dockerfile_with_renv_shinyproxy( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + from = "rocker/verse", + as = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + extra_sysreqs = NULL, + open = TRUE, + update_tar_gz = TRUE +) + +add_dockerfile_with_renv_heroku( + source_folder = ".", + lockfile = NULL, + output_dir = fs::path(tempdir(), "deploy"), + distro = "focal", + from = "rocker/verse", + as = NULL, + sysreqs = TRUE, + repos = c(CRAN = "https://cran.rstudio.com/"), + expand = FALSE, + extra_sysreqs = NULL, + open = TRUE, + update_tar_gz = TRUE +) } \arguments{ \item{path}{path to the DESCRIPTION file to use as an input.} @@ -61,7 +112,12 @@ add_dockerfile_heroku( \item{pkg}{Path to the root of the package. Default is \code{get_golem_wd()}.} \item{from}{The FROM of the Dockerfile. Default is -FROM rocker/r-ver:\code{R.Version()$major}.\code{R.Version()$minor}.} + +\if{html}{\out{
}}\preformatted{FROM rocker/verse + +without renv.lock file passed +`R.Version()$major`.`R.Version()$minor` is used as tag +}\if{html}{\out{
}}} \item{as}{The AS of the Dockerfile. Default it NULL.} @@ -77,7 +133,7 @@ Default is 0.0.0.0.} \item{expand}{boolean. If \code{TRUE} each system requirement will have its own \code{RUN} line.} -\item{open}{boolean. Should the Dockerfile be open after creation? Default is \code{TRUE}.} +\item{open}{boolean. Should the Dockerfile/README be open after creation? Default is \code{TRUE}.} \item{update_tar_gz}{boolean. If \code{TRUE} and \code{build_golem_from_source} is also \code{TRUE}, an updated tar.gz is created.} @@ -85,15 +141,27 @@ an updated tar.gz is created.} \item{build_golem_from_source}{boolean. If \code{TRUE} no tar.gz is created and the Dockerfile directly mount the source folder.} -\item{extra_sysreqs}{character vector. Extra debian system requirements. -Will be installed with apt-get install.} +\item{extra_sysreqs}{character vector. Extra debian system requirements.} + +\item{source_folder}{path to the Package/golem source folder to deploy. +default is current folder '.'} + +\item{lockfile}{path to the renv.lock file to use. default is \code{NULL}} + +\item{output_dir}{folder to export everything deployment related.} + +\item{distro}{One of "focal", "bionic", "xenial", "centos7", or "centos8". +See available distributions at https://hub.docker.com/r/rstudio/r-base/.} + +\item{dockerfile_cmd}{What is the CMD to add to the Dockerfile. If NULL, the default, +the CMD will be \verb{R -e "options('shiny.port'=\{port\},shiny.host='\{host\}');\{appname\}::run_app()\\}} } \value{ The \code{{dockerfiler}} object, invisibly. } \description{ -Build a container containing your Shiny App. \code{add_dockerfile()} creates -a generic Dockerfile, while \code{add_dockerfile_shinyproxy()} and +Build a container containing your Shiny App. \code{add_dockerfile()} and \code{add_dockerfile_with_renv()} creates +a generic Dockerfile, while \code{add_dockerfile_shinyproxy()}, \code{add_dockerfile_with_renv_shinyproxy()} and \code{add_dockerfile_heroku()} creates platform specific Dockerfile. } \examples{ @@ -102,10 +170,28 @@ a generic Dockerfile, while \code{add_dockerfile_shinyproxy()} and if (interactive()) { add_dockerfile() } +# Crete a 'deploy' folder containing everything needed to deploy +# the golem using docker based on {renv} +if (interactive()) { + add_dockerfile_with_renv( + # lockfile = "renv.lock", # uncomment to use existing renv.lock file + output_dir = "deploy" + ) +} # Add a Dockerfile for ShinyProxy if (interactive()) { add_dockerfile_shinyproxy() } + +# Crete a 'deploy' folder containing everything needed to deploy +# the golem with ShinyProxy using docker based on {renv} +if (interactive()) { + add_dockerfile_with_renv( + # lockfile = "renv.lock",# uncomment to use existing renv.lock file + output_dir = "deploy" + ) +} + # Add a Dockerfile for Heroku if (interactive()) { add_dockerfile_heroku() diff --git a/man/document_and_reload.Rd b/man/document_and_reload.Rd index 8d0c84ec..95b60561 100644 --- a/man/document_and_reload.Rd +++ b/man/document_and_reload.Rd @@ -24,7 +24,7 @@ which defaults to \code{c("collate", "namespace", "rd")}.} \item{load_code}{A function used to load all the R code in the package directory. The default, \code{NULL}, uses the strategy defined by -the \code{load} roxygen option, which defaults to \code{\link[roxygen2:load]{load_pkgload()}}. +the \code{load} roxygen option, which defaults to \code{\link[roxygen2:load_pkgload]{load_pkgload()}}. See \link[roxygen2]{load} for more details.} \item{clean}{If \code{TRUE}, roxygen will delete all files previously diff --git a/man/figures/logo.png b/man/figures/logo.png deleted file mode 100644 index a149d47866c88809bce0d6dd26bc354b516d498b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103244 zcmZs@1z1$w*EdXzFqEWpH`3DGp@^e&w}hm0cS}0bEiDq#4bt7+F?4sscewxYJn#3u zUKa}EnSIXQd+qg$wT7^dALKAliBaL;;4t3GODn;_!JosyAxMCcfLF={?#O+YyH{LkkZxK%Em#^RfPJVD+Gb>pI>IDru^p;M@tcE4aJX?QnvP=DS6nq**K_0 zQ7I`Yh3!pD1(l>_|NVC0ClP9MM@KtBc6JvR7d96zHd}i$c1{5S0d|fz>~G$%0#~p) zxY;-wy0Y3h(EMwV|BNI3*}>S}!p_mc)`s$VTtg#UCr1%#>gOB%_s_qd)7tL8H?nc~ z_pE^VvAY`Dv2(IZf_cgGNI{6b#b;oy&odI`6lVXwUi1$vT;cbdkWBcy|ZOcg?L@ zzgvNjgv%8>knqbnQLrfe0%6&N9Mnh>yeRrThrw3m3d9XJg$FNVphQ(>vncqK zB^C0MbV8BO`nP3z#d%BBK>AaQme$r4g~wj2jd#oEetcVN>tdIu#|KXDsh?m*1Y8RE z;SLJ_C~@qMpwQOM!4$7~eD)|mExDV=?VDpW<3HQ#528LYv^dxq%j~gs+nweEE=Nn< zKG()eQfn;^TSMTb*MI$Ze#XTUC2Pg2Lp(YNcXj z{KO~c(0G@Bv+Gl$6mj?ee57x52PvSz2OLxFiz;uJm)pV`Cj}kBvsgyX1dz50RvmACUJ_5Jte2r~} znReLIudr#IO%wjMq5mZX2*YW{P-J728Wj(p?jOfHxm|JriMZE^Zk!~Y;j0h;8OorwC zF=*-H$O-2?Sj0`wK?h=kK8M3+0!te$mBLxchl4{pi!}lJY>n)vfCY^(!7BNtNQyw(P$L!9M*dkpX!RfP#-~8e=qSIToGK)3+9GU=_ca~tk?RyjfamVKXEg~)D}g!L-z<2?HqPZ z(qi;`YiARQ>91S#w8K-09Qiey3f!Np_^b748EZ}K#5rI}8FOc)*%W4=HFx{=7q$zv ze`=YPj$aUFKVXB+sK5-JOZTj}?x!ZQHj4{uw@&Anh9<^fn!A|bSVbhoCOK^R=LZ=_ zFHp+|N1*yqxt~_MEZty3XfL}dVO&geQ6ZKW(Z5Re^-V7J)Z2Q3Db77au0&5}0`6vC z)l^d5>5k*S@+Z=RZkysj?z1r)$=BJ3 z98|`Qd;#knikd8CXzLLrI&*I++Zsjo?nPY>A#!q1z}IbpU=zLoW-kZ-UGFEbt*!V+ z^-e-fVU>9;4!3_-Qn z;TO$w6jVPB#pyw;n2mnf1pb+qw@@69BI>v)7^lfPrVEn}z&U;uHmu%Sdvu+S?j(y= zcOqeE!iBe1B-stL;C?!}w=}+Tb=^XK z<|=l0MwLQz4x`Mbtst6$dc1eNvdf{c){D=(omA2kRg6mWRAX~)VY+eKxL(9;`;eS+ zVow)g#ZT%%DHU(j zLlF@mp}82S6|3uB4**fp{vPL8wet8%4MrbF#vGvoputFN#gjZWOo%ISjn#!&0)B;2zMP4YX|e+CR7A%roA zkQ7^xgtyX)x7KG_bD?fux>%Ql2L+ zT?|YzTf=fg83ddJWs{#yiG?&A+$bnx$=*0Q9%%f7^|k2>AdR<8xt7xg7cfJO(kpq* zUdN=-F*emWE{V)SF&CT+-KSCdRfek%Q6hxWT zH;5znNft4L5RzRU7^kB$2VW5l-776?3b@}}2smxJwg0{I3ep@c%^oL~bspf#=VL?& zz$UyK7rXX;$N|6q0$Q*!FPd^0xbkS!Hq>$E+o2ByPC4}#1(x_vC-qcg=E09JPlFU< zwYLuIkxD8bnLgE~Q$04URw}1}15^F57C8DikZNa~-oK=nXC$pc-=O{;dTd30hZ`1{8e^&XRVq7O7~SV| zt}p0Kajs%tAF;tW(iMB?^dge&G}%M}TNyqaUVBJ8qW$KArEJU6v=48I{#A#-$%I647?xE{?(F{+J`hNdfX^7Nb}jJCPA=Vj~CqZ7%i-{#z?0 zfT_h~dm^7^chNvoN;#1ed76_@WGRvF$m-=5#|)*V+JTfDon@vqkFcGsJ~=%El!tmb zcXvVTADc`&!gt?4)*PN~bk|*=<2sZ4F#AY2dq2}DCKGY*eXcWJ871s>+m8qEm0P?N zJF>$`aIHX7&En-@Fu(VV*5^((g3gE;JGQRDrR%DcYCqJ+f_o`M%Cvj~#YXJc^O3 zdcNGTO!(^4VDf3=4nSv`OpwSp*z!T(n>YaPZ{jLzY}q1S1vkTOaE~YBOE!LZ-L+hv z%^-LBgCk<;7xNZPpLWWR1Rj!y+Ny^B$nGCWbLN>_*(uru?Bue}d~H3>ky3=3>}@^n zhKYpU=*XGFM@uKi6*}f$+lC0?i3mu_L|DVc*{EVjgk;#LetIP#fUQpI$CInAYtLxX zHTL%&#SQRL82MXRZlL4hqF>so;_-O;9Iv6%Ducm{Lc?}#@$?%@G+#Q84>`(*JKKT# zU}vOplxyT{QX)OnNB;uD6#|*260-VhlRD^(Y*Z~ReA}HN~*}M(F z+<;J1eaPVzL0@GTuf=bDgcB#Ga~Ksl;~RsfbX2SMWlNL>44U~#FNDWE51xqq2689VjLnG_-%kSIJ{K+} z=k7+@s~wH89rO(riXxP-rmmjiTtf`WYPL88=+uv3mmTnQa*=Ynv7rf~{5UZxxt#CP z-KFsD$W>T!>;g+L%(Ne$c-rCn{iOIBao8 zSe3`@dWE<00ITbbVRxP%=I5I-zjl{xhAfIEc={^PvN$5dGFRVT?Y_5=0aFs9r#TgF zS8SPEZXY}f)kbt*6SyE3DAK=5J}-GdT(m!hq1o^M2#!r7gd|+rQ&VwVI46X03(ZaM zQE|vOHamOCA+t=^xIg%Hg83z*_$^np-d6gDHt1=5v_6M9@tnoJ`Q5tRo94?hO)_Be zltwsO`IV zK02`pay_>p4i88SiM(+|U+N@c8DOIi-Ncuq=N4sA#3;(CJCP-9QC;KUT(VH);y?ac zD46w3sMp`X&uxR`fK(02XziVOs7+5rotXI#7>4dr_%dTkQ)e-vFV~)#&0q{}GUTTV zlh(2D#G%DvU|1+Bkc`xJ+ig@%O?~$U^%UdIr=rk&qv~o~MSjp5Zh{D3u6Reyc+I>Q zL(s~mjv+;;r=bf;S&I9Q3ahc6ag3HTx@ym86qt9nw_kRYVrI4B1-7zCD;8Ne)BW`Q zz#Z5L2#QAg!XuXQIuX|VAz@5O3i0g)$zR%b`5U`(1=M8vDZbMD3hsuEL}MJ~JH9G= zJ$TPM8uWWg2p{yEE^H1oj>7uX^eM~mnG_APf9Q(1VIkSNJsKrVEwEiUp&2^qqFXwz zPuuW!|3QCWs`v^%)L6VC_G$s^_!~iV-|D&tOmdo}r%BH!R0vaFld*CVPS=cZ77G9b zY}re{qY7OYgKU;_sg#c(S!rM~Lr1nTXT@7t>pkbKk8CmI+5sxFgz09DUk=WhHyEo} z55|9al~q{4JyjeN-?gEnqGBD|Gl4pt9H|M(!?0hgdnL<@^HOBzMCNGmqNiPKD|F2= zDgRrI2qV0IzYKQk))f%LMp)Lh4*MtF;G`FA+r#p^&5C<*mOA)pZgq$w%i z(-Qv|;YiM5p9h0+Yn)wfLrp$QM3iF}=~Dm}aUn~xW`$@qS`ES)E5X|`s(T|$>F(oc2Dpi}eC)xr=X(OUvX|c(HgBNMw4rnEu)Cm< zzfvzOC1!!~f=$N2>iOW4=(#(cg3-sIHMTR3xK>FuxA)E3nKZ~Dab6;I%leGt#Pd0S zyu)ByasJAfvGYnIZl?~Z8$zrMA86{N31@Zf|J-qGR-m8BH+eXp@0ImkDGyViATNW! z`U_R-S=OL-`@KC%>p96VD83A3HgLyb#zrjxY`bri^HYn9YZpN+FOfF0-%r4oqzbW3 z8_GWP&ITg8-`HK3OB+*J{ML=C%wx`}tyQ~#rRJdM1f$XPa~Go{NVg4rKj0`Y3-!U1 zYiB=nyO$d-d${Jxymj)=qBDNJ3t^?!pGhb?5=j+Zz5PZvqTlJzuwTj2-qnk~@?r)v zjVY|LWVN{A09UU_l^+l;(9&+Nfch=t`}0?poyQ}k?QCmf8)x?SurvFgXBO!FXy2}X z@_!mG^In|u?r1H(qaN9lntp5&_g=AtSS>pTU)N*S;F8%M_#9GYHfS6U_R?;T;+F!b zQqc&x2N*nnqM`#gveK53u@~5hAT*m1EcuzF^Pp4@ z^(&O?(xbQv0zJQBP0r@w{&>Rl1%6{HiPw07M-srQ1MxH>yc2Rxli8qo%bC{4^Agy= z;ueS8Y25kUiyJrQ+3MJ=P|2pBl!HZDezHxaEvp+%#o1QK?+J9yddPJ%^IJAG+?zN3+YkM~d zHM699KjU1W4+)GFakzwAYd`wl|FA{NF8<^sO~M1q%g(^Xl&l_0Cy#@99O%xp`G7F!Ix<2n;nO9X+rGD;V$>->a!|>O71iBmyw$0q* z?IUUK--eHMw@;a>RCpIo@>y@Mfyzi9WAEY(jb1(paUC;jc&j;<-BfrOBIYYaIxDtc zecE)SDDTvVu}_cbQ|8Tg->nj}X|U5GV6)gn19~*Ld&hX(l-7yx9y4`9nH8FB9VKLcd@#ARt6x(;<$7q`aQ3lu?dy zT*J-EXaG0rO9CXowHGix7sns6?l5M`Up}od>Y3~G>a;dJWxu+*bpMOK*d?!?(U(z$ zPp1y&RAM}jVl2Yf$)P`&quh=-th0IR;;vfwrULncL+zoIOL9o*q~gbC(K!;P;8Bys zu-s_79OoEq4M+z>?d7|N$HvWCF@eRAdkb3^`5+V#x0)aLd?}TAld8qw+1?1Pu2M3W z?Q$}N6z>5n1ls*Nd|CXExw|Xj%T^bv^zhN<&l!7lgIMTV2OtS?moAhypNRH10g-uk zD`fLG_{16j-gs*3?iGv!GsohO{=+!v7xLsrHV`R;#M^qA?-Y!|JPjw7>L>LQ@=yJu z&temBtVD0;*0!;Gw&_J~ZMNgq{d~1eYHq8qs&9Wj-mMbcQQ@eALc)9l1Ktitk!bNR zgyj7k)2NZuB2G~F^ob|(ur)55dB4;=sXwqZ6_0y=4N6n@JvF1!77$6Iy{}6X z5{oJ}TB2$(Wwr3pLjIS*34g^Ul5=qQEcmRDjO;`M5M7&4%NOD{rd(X<9nNt19*& zAO4GyS^uCU;i%x<&$WxMdQ5ZogxF;v5NSJ^r89US{EP!3>=0%kw#QM;4pld&3ag46 z8ansTe8~LrMZc`cDMM^DS0iqr6)3wKJN~i?7hUxmfNYCdThp3^ZY_NuC8zWA{paY@ zW{zu*g#xUX+doM`Ra4}~s0>s4C$qY@Fc#y{J?Zvtlec~*x{bLBb9n&+rUV4Q&2Hq%CnOST-wrl)@pa9{h!aJcpg`pC4Ag2*C;XI6Whc^Cv5 z3NU;4-XZLxq{?xeQDeI-+IsYdPvgW8d)EVAR)h6R_tCEBqUTnNoXeZ9$(G3T^-bkKuJpIi>*2{=hD;TlQ z3}|2NM5u3I8l9z$%?$Y3ikf*XJCy6BQzZIno2Z&Xz4yd1_Uj+``SI_Xpf~k(X4QLI z4FTf!S=^-0zRtyn#&SsanKF2~51HSeAufGEa}0X5e#}96!P6fj{W{Bg}TeggZb%u-t+%yOxTq)>YMiaZ;7&CNj=bNAQ73W7>;s-rS zv8R6#3$E2Asl1_q_sy}pFNOTJegJ;*Hv+DE;~z)S=@{Nf_g4wn&P{^kC2DwM{F$~_Bl-$0S+_8$Ah1;`kOPO%Xw)`+e%sW?Om z8ql$4Iql-uA)H=30%dpJ>8+sDLmrP-45#jB^Z$|r#E(B1TooIL`)JIq94xpP0&qcu8v$8`=H#NhKS zQ1_+ba~o3ys$RVl3VCb@u&F}-pHKAwQ)L9IAKhFLR4>#*yYA)VyRM9h?V{v_k**z zaJQGC=iQjiCJusHi|C`FiC-A9jg4NQ_e(>9n-3^J#o~6mn$0`9sk^~CWzoYPMd+Y^ z5@3!k#L(1Rq}$&TJJ{1U+t;+|e^^JL)14PE?%;kUt?{znU^TTji+~UCE7gJ@UC}aG zSwU8aYZZ%-RQ9s1GaIn5ZR$q6uw)(RT)PnXIn25TBRx0Y| zDV=@&VJmYURhoJPI&LKlJpKff>(X6uLo#%FS{$+z+VwRvlO*{Tx;64^wB)@S27gDD(Y2jF1&D(Vzd;Lu9iQlqAi6r<%WT=4}SpcjO{FJIOkUk)JCoXAhYK7XI3c< zH!NglI@+Tkz`Bmoi=N1&q+3g+!7<|iLjA^ZgP52U?IT&yV z+6}XpM{|@E)UfULdgtf)2)a1(FbNSWaY_G5rhsR0l%R8x{NdlQG}{ zky+1OUe8gRjwu7ykrR$rhHX+;$PyPr+ zD(r3j?dW392WbPwy&MZKPU3Hi4Ob^2-UIXN-{qYgNXX)u^mBz=`mpqB{GZeE{GrBP znClLtISR>qB+hIyV_~-!jY`WlAl(zivtMBZ8DrXgQF8(fD7nkD{`m^vqky1<=6*cR zIlBMB6d-2)jg6z4V!Ic&i6p7{YHJyveC&B8YMkmbN0plX*a(E)pfa(QsEW8DZRr)M zfyyKQ1&>zi=?Vu-62q-lK;5#97N}eH#Zh2_`h>)g>)lJ22^jmE(}h9LCC&KZAlD|0 z(s6XZ8h87bdI{o4@xE$>;0Rm>utxig`YsMQKwmyW9em=NuIJ|WI zsf|r&DvDz6d;#OE&2oDC$uMm|yml&iw+=j(TIzmUIaH&T2Zp^yn8FV>a>bxYDRTJn z=*=Vn!ORP|fbAXW>|AtIQ+tide*C&yP?5v1<>($MCJ?!x6*E;?Xjq7c_d}us80P$a z70|x%o)q-kTZCM;x<&g#s=Gu~#+>E8DS{skI_QM0Ozv|fWh?E2krxN4ktc@dwL~lK z%_%#D*EM+FsfeCyE}H3M9nLu(!)y~FV9*qVblr-wEI|wp-qDgqt$Z@foB$l>yOYe9 z@?L{)Kp~n;baYOehN?cNcnq4h>L7Z4fF=sI_c#M)vGO{xEWU-72mDSA^I3pTwb$Jx zd}9c~h-q}5g`#y9FgYBtYzCJxlrE$6>WdW7^%M7IKgbbn5X+0LRb<3g zYvy&jeR~Iw_Ptnkk(-%-r#>~-fXbJD_^Ua{L*hB9Gld=q;oCRPqy->~zuoMI&vghZKDHZ`rwh&x{y68Oh`gaO%aw;s3P1Ip)Sj!I#(zw- zA>^o6#FiJP+r23yHgKOx;p9r(Pe&p7dWGQk)}Y^nkGmY@Jv}eGG8sQiu&QTB3u#>b7w?g1J(M#>Sm7kJ#7{du750@ z4VXV?SsC{BD(F5BbiY7et`UG*pXXhu!xrb%*$Xdldg}X5lKlA=d9A*9=eZE3%jhSb zH3?leDb~3;#w}QWjS${CgH2g8Boah=Ctjxh!MPdz+x227w}9{Uv7sq?)^c$%m`QvO1;D!PNC5z7O*p%xU&(_V_p-M&Mwv`{OQ(bh7P!B%>m|KkXT z;sq=~z0CW$83~;VYx%sj80xEE>xwtK;N0JN2(&pQ5U!=O^6{aMU?vzyH=&VVb-Ue4{$N8Q;4e@v90d@T`@?pdJ#@g5IWyz>3E9Njri`cnB9w74>F0xFlua1=kb zW(u9EtpD}uC;M$g@S5ejd`oH(ojG-Yl~aoAA^m(C92>O#aGr!H+u~jKq$8|Y#4z;7 z%&~G`x+CC2B1~;{1d0{sz0*sE`QTsNMOUP}G-&-=IrQHM>;LMGmC(3SIfslSp)#*C z^tc+|LXm)KMCuO;`ucX|o7)2O4WMTz6Rd*_-#}nNIJ?)%T_Of~>wh=}Ep0w{C~h|2 z-YcVh;_xS(smxO`GSh$z;g-I&Bz^`{;JK456utd2k%NikG9KpTgb-gGkmcbp8qJw zNHI5{CN>J4RvX4Pm94<>E-HHGrdEX@^W14y?%OI4*dumTgZ<20A|o8-nu(#VxX`pr zOu(*Nbne!IbSU_oI_a4FgOI|ZAgPF|rLh_M$O{Epu~LxNh+Xll_Tk)jV4X}50HV+$ z7{P*Qj?_gH!NR5H0V{13J(|wApGC|U*sKk7Rtkwts{}0;GuUdoxO|%?cof8+mWvEB zp|!dv;q2B#nI;ZKBW9f>*^3WIl!EB#6al{f{%fuL=WZ!xg!nQpSJU_P^^l&?b&rkx zAobQBymn&-%sV}`Z6*@-;@THua{%y04 z0XD1E^0!{re}Sx9sY?8?-#;K5L6w@vLpCiUN1_hIb_8|IKR#pxf|u$BG&IxpzZi>) zWB0!>*837b*zMkioPtc=5{8Tr+%L_$y`@^-w?V*T10?cy%6wH@k0fIB#|k1gD@y<0 ziOK*}nNV*33uc-02pioVj@FEN-L;fyKc2Mp6u$t{BuV@`LvJ9H4IbkbO+Ih@A+R3B||7;?}TvHhcdDwY?9p*DwT3Bc?@9Yn(QVhro>-bM%zV$=iuxn#_DNr{g zgIIovpnlWTnl$yJ%jTaBprJQw7kzz1YcfW!0AG>Vt5_e1A$oFzAHG6{CU-yyga;rJ zU2jv(L0&PgUI({PFOOH21Jga<;@O~L9heMbV65H4cj&US6nx)NJW$dW!aO88sm#N| zO^mRxNM$U32Mh;boj+XXam0_erP+^sl5=@*FLFJRJ>*#xkn`x&B-c{RFf6zAEwnL_;y>qwMC~@HA zm4YlS*dd0x2Wf_Wx~{h5tqdzaugU-pI>*w#PA4y!L+lx7@wszn=$oy_kq2}8gI}qu z(Vt=W2Y8B(z4tDtHvHP|r|>9p{~Oj+An8%61x}2>F~^hjHFC9D6QGcFX4r|$63A;8 zxYi%SIcJr(tRIe>ay$r*f=J3c=(kdshwk+<>6w87BJg*6nR+qX+?yIr>fc*xGEc@; zlwIGi^zjs1$o`$~dj&Ms_EBaUnkZ-N>dg5x@ER4NVMPG1Rw5+#EOd8Yp~@*#*#OcLB?gmjUd4 zUn#XHy}ub1HP%BnOaQ+?fzWX;4{|@PMKjJzc+nU_Mo&-gQqJGY`d47AN2l<^yQ2E zH1CAi=QX_rK795>5j=;b=mH`DBjpgDs~I?O`Oor=gs&3dnlvL&7X^#26(XHHg+TB};BqGSE0ei)GkNuMppK~ulschV)ZI%I`?1Ptcd+d+5rgJii5Z|_ zvxNN&(~oMuj#SpU5eP?-8$}YqC2Z{BnumW>-Jjq2JO_T5ZhzieYB6J6d@BzD-`go}Yb-djzEZJ<+x z+q5W=pL~ zSHU*eUo+r%%{oYDuihplZ>gm>Wz`|jbr>a70F>$EuzWuioL>Ze9&LMlv$(7&WL0|E zV*jrBAuT^Qiw!eGg>JjuKS%$ABxwI{JX?q1jA)vugF#XRslWxx1e9P?y*E|!=!fR`d~QJ*YQFILOS4e- z&65#)Jik#I@g_q?(zxAU2%2>ZrI|y z4fZ_~di-;IalWHBTeU^2A`28Zz@>VkC|GvsFAg{S#QjvLB-B)ISWtre$GmpHKa?Yg zD0&>#H<%~N`MGfJ*@gPu#yrxg|Fid=Y++H7Eel;SN%A5V zm&iD9+GAJ{7Jf?xXA<-!t5R-%l^nV)kb@ni<$IV+>(OoZ8vVXfd9#iVWo%;i z4o#_|huqjMj_C#Lo3W6K4N9rb&53ws<(b1;>KE{HI!y?p%20Ry11t6 zA_HmWs&;#z_9!z+R%VMC;+1S}y9<8{=yoT^?lB+uWip4(=sv zyZxI&Zq8(nx8_*Kc(+bv`!OGf|K33=E7=N)bVqI{4&^8gKGT^5j?)E0;+`qu^7)XE ztyMD5)6s+Ia+5)bWoxY2TZm2P9@Td5DBD`eGCIIhlr%ZX>^S>K8doCAA{3tmK|9znM~h_7;>@mxjKLb^N^LP~qCQ>5V;b*_ z4=uT7ci%&2!iOH0$Nq{kOuu>J4B_X`5OAO)T+U|tr2=;F@d?Am7%eJ|kSUoUikmQ{ zh*y*F2--b4_{M7ls!k#z5GoKOef@19J}~|Mr^=6^H>+CAhKt)g?)IBsSHq~sn|k&M ztDOI#;dp+IR0ccnrvZerWmz^^Dk_yaC^RIJnSWRUV?Q$h9o3&UsexhuI<@}+(B=04 zCf!bOKJ>g+jRN{i^8-EJe`dk6{a8B%cp6KH?l%lr6f9Zcq@`b#VG?B}eir(wR zl-UV(e&$gYHoE6Eq8XS}+D%TBn?Rea#!IlV79Om+H;${=;yra}!xGzBCPV&*K=0rv zSKY9iM1#q14y5ptSzFg2iz|8-1T}w>7YDv6+TJMsd{ytr6cnpn}9))=8%4X@e&`U&XFB3^VR$n#Olv~`c z*>(vpwIHiEV+E4F7VcT#8j91F{E#NcIL2J1`px8V-$lXr!N@q55MKSmO?~+EqNVgQ z1pm4A8J{%q6-JMc!#?oMAfWcuE7iBwgF4c<#lfQsOgj{{aDwgT4mk}(RS-^$6+7$` zSFcxPsq+)U#)n;-MBnu8W+9IU9AN^T#|FPjXTuDgwzXrX95a}UcapXFyr>;Dt5>c^ zfNpCl`;EtlKkFw+400ddKEin-_bcS}SH@Q<=?b7RFwkcitdP;cz82UY2K_WLZV8fU zgJay(T>1M=B+{q*$bly*^njtuw|jsb-&zuEMrum9Ngd^99Pu_{h4vBiuY7taqpyoG^YljpdR>FlIr(td)ddFPg3_`^0`z^e8ph9cZnDgD3Z5q zAtwZWm^@=1n{J&)XUWKZYBT3WLujr!Sbw_FPQ9)N1Kh~G5$WKGnn%7FUh6B}Op!{L z%{rhXB4Y0xbuWugMD!nB5i>jB*akXDHzMA7eacclJ@Yh8wMuDGjDJHI%~%$i$X#+T z3Mbt7^-Mh~>1_9;BZlIy*>TTsjS3g8D|!uEt&%Kt#{zp9NKwZ#%Fhy4o49KQTkMe# zG2_8Zf7V9`3F&8fNY$T#{1a($Go&(`TjYI**2^%03`}w(XP-YCGQtlu0te?=G?i=D7d|FyA0;E(UfZr@%|@s)P;PRQbVo(B zpyQ{0{_1&2EFvH@rPA^)nZ&lEOCJS}#ue)tOJ~O($>XPL^ecE9l?5zz9rU*{Zs`Nb zn&BF7aZ3975g5$AiqNrmLNFbQq`aUId#`p#18lISenV0n%a7td7>vGnpB6bSasc~P zi$Z{(V=M3`=XLHE;n4GQX@itlWP%=}B!O%lVv_LO9NOiGzaffAq&kEs%1B6(_K$6! z1?(%4eHQt9^?6%Ve;^NZi8!(tcm9}$+HuZnRWDA>uyM8oR(rV9#6)boRW^!swK3irF@#~DGS?p0=Gz(Q1JfWng4fRU+%e30$!M9Rxpm&WxN_)M; zq?00?_?47r((O${)xvf5`@Q zhzCZ@)gj=+0P69SZzF0i=3WOdvmT>rH2&o0Mu#gp+q#8S@v*HO{d7b6_4;(cFE&J* zwa(W!4Y|Hlt#4jz91>vmC^fu7l(O1 z)VS4i>|;Rx+=*`teqH~M@Hxr3r#gq-@aG;Et`?LOTAFnh;)hSu$oqBI?(wLiopAh? zy-cN7>BnUq!aXDtnd~}$tfXqSSY1eMzzR(KB|p_-oXny-1}B1dhSN|pUz7r)cfVYq zn{8=PCihtblgBG4>H5*47O*2sg?6loHTq!dD4-6QmAqh+v%lLaBYMoBX#T>xrjmd} z2TG`0)er9(lZhLvu7A5ZRQPvOAHB`jLfcv|0JIXfZ#hNXY!<3sRo$ zB&%Lt35IxDUlEayP7?LyR&R5E>y3ijRA?r7I+5;1BQ{PyuYLWb=XsNJf7%P>Ck({e zW*RnFrLWE|?5_*4jVpfyIh zvmzSU?Nwr|CBqBDtKsy$II|2fs;9>ustN4x<==g~aBDaBO|Ik)1x$DgcQJx)X|ZLi zNi5lz4NU|L*c^jnFO>ZwVW#vE`-fD(Ctz6io|WQX>SYAxh8?wXn}v}#ueHqBi_?XT zfEo=xABm5>7Rl{EVb5;wP3xCl5sOP?*QM8aUe`c}`(>{!E<68rn zHv^?*GYctSD0uHP#J+y?KKEG;tR1)XW{_w(QmFA&=xb2QKih2U>_3gP6*B|}5^zr! zPTzQOms({Q^LvOgI%xO9ylRGHgV1(k|5zN~OcI4Ow2>6urA^Kb=`G?MK9HvB;4h;!nH0erNPyU~`Bq;cB@KF66J) z)$r!WzZU}L59k4tL@SjCA$PE(tzp8jP$U#$(0Z-UN;14er|_-au^@XlM3kLDFry2{ z|J|s5pxaO;p(v;OIJnk{;>DKveJRqZzjpe3^8-5jN!6nB^nBi6@)bKJETe17ojRDk-&kA&rcWd;XQPssbC8I9rsUX*i3|6)tm$Rie&0 zOS}QpJo?;BZe0g*7_M{DD6p}jCK!309$03r$ORUb(W};L;B?Pv@DTT|+AE-f9Y&5# zxj#Imc?|h^H0*g5pHhg0G6oF33Z`+ng<!gMRNTjhO>!W<#brW#$ zZrwJ4j^0#Q|9bP~%bOJIL2LyFmX;d|g8noYmiRd>=FeZd;#kP(I&aENz6J~=snW9_ zh|xT(m{_P|>%V^KIqk)x(OR8VUHwsQVJ5IDj=$%tSIkNV|0wIQunX#uOnCSyj4MNn zuHV+mnT&d0;#A9_FRILzln>M8Y;)?Jlvmci+wPB@nucuJ&HUjP8@eP~Fg~$zrQN-E zgTt^*xqt-gesa&kDb1*_7Z(@3kLv92-eO1i9F)886&`h?z?+G_O~ElVF*BfO1nn$w z{;t~(iG8tXN;vD0SH-q1bUEdh?=@~ZbT=)oC!x)chamKxog3H^%V1Or#vC3Decn~A zlq`k}ArG346bE$5DAz@JcB!3{MW#K7Cb3@ic#mT5VQd9|s0?VmRzBooGTt|o7wy1IA)rQd!@l^J@ze#H`pvA3x+ znl1R?ax45JG3i6+lf&)4&fdb_g0ikE3v)bAU$3&R{k4249zm2>fN5G1{Wk4pQA%sxjT?KK*sN3>rzy zdNUd?y-1gxBMV{O{ODDZMC)&~qH^9#-5gz+poq==N1ZfyjJ_0Q;3-E=m_`k_%~MPNRl>-BW&WHJW}zj_mt@Qyp$wb zucW_kBUWUcydC>q0k(7h?LE(s@p%2t;!8P6UImi?nG3I^nW!6t5fs3`4G!QCT{DZ9 z_O?|Jt}RqdQKQPZ-j3ujDWB$d%G--G-VRD$!KKg*CS4yN+#Gm3&0NE?`FZaU%^V>* zUJ(5SiJ0vVxtZsXt6Pf$X19`_9%aizN)arWZn8@wyn`zN_0C~Oi7+vt$4qpQo|W~L zdJfe~a(uJ~0RiK6msF{5$gEulI(0rb*DiGv%{64H4X!6X`*v~=x+^6s~nuUIxb0U(~#0Uv5->rwwnX4 z7pTdOv`uUb=JN_&y{cK~gPkB17xc~1hMaC{3y{iO5#)ex;_oWS#YS8V3^8Fd}7hFgvm7GW-PVXuV5b_cHHlFqqar!$rZx!PxyMR9@^h zRz?=jlF#r`j5D~yg&J^DU>AHtJ%9Pw`;saW6n(biRnT`pkrkT*C0+Wg(tp&BhFIqc zduKB(2rn{38zmptTK3;KeT-|3^k_u8liRZmKNGu|FEXs`I_{Oio0jUXuBu+ON+f89 z48=GUB{#KTn6b~lR*JFjcXk3n$}cD(9l6LtS9RFCi^dR#TQ9B@6cTpMw`Hl+@!a=8 zl6evYoF#eQPfO#&zRoNQG*cpp*6|!FpU}lWrtxdv%I1CWP@`=n#>Q?;emH-9(W8it zj)_lXv-9d^i*f6ACP8|i8Vg2zuX8snTK`)+;F8&$scvJe$<^s}_vOA)fO-3jD^$yA zi{o#w=Hme?ymd|vlvre-lBp^A0*Uj1*T)|0S@JVCa}h#bKJv+75?T$s;3+UA)W(jj zm|R`;I-`hJl1Z0?8valG&HEguMcugUu3_Xr~CO z{h!eMSF4sDN5j>lf=5suGUP}b-a~lOEeA;OGFxKo>p zOLwmdM`+{sYo9qw+A@uYkGH|R^`FM|GaSlQioP4>OkTo1=)*;j0Al8D@dm zA4zQ9TA;k_aIK2}&Yk8|ib66^hVZlvguPk%xGich39l!tz@rc(!O8Bsv|N6upxH{u zRwPO;a40HRBlp=qUu|T8eStS3tASi`kgM-F)J2?toZqlN%+m@GLlxiwy}VYBXmmF$ z5Sgrp<|UT29n=!T9~>Vl5Q_1*KlBcUb8DeS8=ze{)*48G<5?*aP{$7y8ZH&R{_gzXa~*;LlQ22Hn@+3}xz?O*(I2_1g7q;4JaK3XhH$^TkrA z6l(m?uF$&AGg=Z-OG001Y{m>lzQ_z@oJHjc^;bL8w00vfr3PQ0Kazw7y?kCYFzX+A z0W;Hl;BX%|pu3!g;BYRUV$UQ_=lZm>b8P^sI`9Z-2TQ`?`3`|%eC(g0P#~XrbZ?Pn zT{-0s;mrF%gP8VXTW{}zM@e|@L7)W3C5}VUB|0uSJLRan!5-G`Rc8Vbk>5k*%NV@_ zlILxcHk-y&N5vmA9=_Y}x28L9ZFGcPD%JBJm^AGN(_QWGDMMG8lKw;|V;e8i1NTSm z^L`EnlqTJ)8wjG8M6y|Q*&2dpzsNXh?n0`00|(>K^s2eV>9f@@D1|#M{P6Ey-0XiC zAz<(x-VOEsI!O@vxX?QS!IMb_<)iY-(TDU0?l}MxFOTImpmFPUy%b00207BUdc`-i zgp!kCZw3;FcQ&PV2l=EJQE>XvT^@B6HcH4JKvVh`=n+d_o6H;^bI*DFrqYh+K2EH4 z$u5-k%6h!A`hPk5=UD?Q)773fKMyVGpYu|FoZIV(JE0QYSY%)Hjav459N6=_s3tj2 zx)}+mi=Hb*bs=pMYBA}a=lJ5l{a)$~d0$AN11!6W*li#VHB~mCb5c0>P5|ZHrqPX& z>=3+OUQY*kYyXsJHe*-!zu=dk6|?Fxw~M9Fw;&R&BGrENHwy*f2bwv@rg84 z!2fEq!V34gL!GM0IVE`q)IQuN{dmT}zB5ot667V*Tx)q13&x?P# zd2|u0&%YZv|6$2c!yAf-Ilc{Ao2J~|`WQaUe?=waszw1pO9ypG7=XU>__5=Gw+V|3R3Jvtkn6l3BeX`ocI#@lJ6LM*zpp2WSoyff z&4HeRUjBX?mDF$fO3-Y4VJM-m@9)nlh4%I0^NY=)?U8_v5FA%W7idW9IrqZ=wYI~M z9kkbx8q^7ck&`QU6T{{27=AOJ0)FC@m&=&Oe_jCSOvs?KEgDuCv3WyR= zk61N9Jn!kZ;+*{Z1P5hQUlnakZp$G4o!#fFZCVFffgw{1ofdYqh@QhY;scQNN{=3wLQ#y99&8f&>OsiWR zoYp`AOx8rH*{ru3!{_shi_N$w?OU3cbh=vES~S$ zGlO&PqPo?}?*fNtHLno&r-uE1n6e&8v{?Pv7Uenc45s)VAu%2n#<5{dZ>BL4Rqup_ zy2R~t-bhUsqcWps2^C3`FddnHfbooG#@Bl2B5hK8Hp0~;M@hJPy!LmAqeH)ea8mF4 z;DHY2xmY@#4B@uoEc8P7wlmZwL&$h;hpDq4naFicRc5F(lBnEj z9NlsUk{qu|KL(Xrym&&1yn-qA?Ikoj3hgtk{-bHNM(xtd`VfuOePg~!%d zh-0$E?<+?ojengFLL|D)Fk<7=*m{2Oegb%w!z|H79(L>FO!(j;$(3dz85{RlDkFIC z0?pS?x7n4~H zU7MFkoQ2=|D;tH`tv01}Eq&STxqiESp!b_m3g)N47XHE3{j_uPQ21isJ&<`+k7*fuV8#+l%SHO|zu~gHi!-Q~`w20(E{B9rnu7o{i z7~>bkw!)$cG}K~tfd~WkD4Zk4sr5y2J8#;-vXVOmX*0SLYlHvZYwn zZu*PztjFwZ`FFWW<+aC&d`!4>v06twieggW>i+6qhM$#e>1#{Q+3~(kMPMR{q(%DE zmYW6Y&b!(a*Z6~n-!hGEIxc_zN)!{Av+co~Z%${O!y5k1p!%C~23Aur*GDYl`Rxe1 zn%djc(moa*t>@kCu~V8YEQy42MZ|91%hau$5lWUULOS_t%3@;SwOv2M-W-;SZutV~ z3Q40_gc`VwX@IaJXj0dtwX(ycr@Q2T+G#8*H&&VgJK0DFrME@-;2#65El8{1S1t?= zryui)BiI<4eb2olLCNpGl}P*FQ5Y0*+uIm3pXFS4>ILC44NW9);0a4~g?vCNM6oKV zT|g43sat!Ai_yo}wd!cBP_DN)`PxS+FE>_(6M+@+9&!Z2IW9e>ndsUL14aICX3NCA=#m{YNSsrdMXMAd+5Yn|j1{eW7)h z_vJQ!16b?^$jY_TY|hZ9;U<=qBbeMB_jV98|uZA#-b={rqKCsn*E&k=UM$=H|VA-SxQ z9TZrFjVRdMh$*32d;*HLzamo>XV^rkf$F;?K3wT&+dt%nafC&tO!_2-6C`0;9OJiH zCd>ubM{V#s8fO4isOY^&@bN=M122sIc(IV*-l9g+O$pU>TU_e&GhmH^_0~^v?*a!t4i1^_$+xviw5a@g06_aqP#X$PQ3oYkM@H; z!A3v=1(gj%K~1SEhuUKUKZWw5noU4obc z6~;htN!c|}5XkI2iu)(I(95iuGs;GUm1UZH+dUYcA^vsJ3a};uNDttv*_^rR!)wp` z72-;iFULpVo@J989S7PL79*8R^y8wMiM5(Nemmx0XgPJ=M73S(-57W&2_qxcEG$4N z>0k1kROeed2?P}bxB&(NFV|7}hc-t#0&mu`T&Vg*zL~}VhuoqkmnS2!j+ndCtH-Dd zZ46u|ol%^Ja93uz3^DGI3OZuYh1jX9cvJs_5DHE>9u@iut$$z3f-WMWUg9Y0dO!dk z-V|>lvh_xU@DxSdZhz>Xf!s-Cs>ACA6qHB^E^Um?oyg&cwa^ciBKza&tV)rr_MM%u zu-C_hn1(7x5bd8l~=gE@ilvpod&Wh^Icr7 zV4&K)11`k6?fa4kfg8HBj}bjVk`U9%6N;y@W~y_)0Z0=5gmheMWKr{s{Tm}VcD)D~ z;=iy6*&H29||)dTDn?_ZtA34%Flq1 zSAf2T9!y80Ri!`whVxF2(;$QA>Au5%+sy3!1_Hh^Ws37h{dChEmCR@x zd9alGu90ZJsGU*%*9t4(YcNDJx(!d&22c3To|gO)PMY|sr(7}mmH)WOk%p6fKX!yg zMTN~kJw{b2I~EBB-mk{rzsXFA*8vMj8qA#+%P?86y6r%18i*; zJXb+b1f6=;M^ zcCqGtvkXV=0wVqHOK?}ts?}*>Hkg|%CivJ~^n3pZm$)pd313V})o}m2GZZ>nocly* z{}b9xnxXV@=3nxMmKa&B9OWz}iH23Ba(Uonv5p9a&ysdsC`2m{^=|{mu=w`-9|Jp# z?1p?BTht#pw#>q*dzjgkN2xHGk_Jepp6G_Wp*SUaB+{a2!bn_A`HxW#Y^{^!W4|gA z@~(Vk$(EZFOFXGaS*D%^=YwsTf!u)`S$y_~a}3xup=|MsS_j-cTDm`rUkmTSAZvfZ z04y%3vrL3Y;-WD-lY1W`$W=`&?A4Zi6sa7DVaAN&VyFFjMu+DDnks1^@%wZ|{CHbY zYu|d#r+m}h&ysg-?z3i-PMC@%n=db{;)=I~N-nJL#GbL}w_@ci@LH32N#-qm;zT8A ztDKo_Ru2^=TrR?ZB7sr=vk1)`#h4BHOx)7_bn0`&gfJuyPg*% zRA5itB2?^+#meOEWpY>j8NT<`80bY?jxn_TEQBhVzRSqk@ECfUI94*#PajGOtzX*W zwkIG!iA+iPlrB)QuuR1LWYVPZqa6&nr3Cj1r@sR3rfUEtwN!2ED-;|ghPYFFwmF>e z0t0zoK(Y!ERHK!I^B9~>Wg@Q^^^%3XHOn{dd%pAN`@fpw6gcmv@Jwl84q}()@B6sL;W@5Obuef=O!(#%)$Jf?M4(oRt}3EO4Zw``63OJ2ad~`l zfEB9QI8_cuZUGVhsqZiSb-VM1g`SMOjH(8GMGE*fWr9KBy`a^v#adc8o$&Q2T#(1< z?pLcxi&$Uucm^48nrp{Qx1X?T%-VPO$R0PI;`N-X8Ne1+%i!jNqVYC2ULvBCzW0*x zx9DEVsJDM5TqU))C^vlR-1q9d4?=31iA5niwyV3H@1l}UE)ZG zFVY31>?vHBi5*WjWffQZ0RivTRg5WXTRbXLIeP(=j#Hf{A=ci#EX<5=QO8tq%oAby z>F!NLSz$YoOu5h^ic}wu9K24^xzY=WhGCEURmPm9(Wec)&1c3+O2V95jc7Wa1C;5G zx=zs$0U`)(aRoHmfOy@s*brMF*qNyE3RKUP0G96p;N^`rNj=Lne5Uk-a7;hR|) zgCe+7$%0RunQ{`r_BiL`EnmrUE0(nM$pM$IPZts2iakH<+-RBe`rBz>?d~(;iW(pH z-hze%*%F#Gf3VC05{)sF>XB?};($Hvh9qNWIV+iv*I8H=_lgg;l1tdjuV>dAsa### z&xP3n=JyR)z0S}yN)Di>^eyN6?9j9vk6ynIm2uO*pDOrhSQMAWDB(xMz%YNG%N4Kv za!X^refis4pBwO93DNIIC~-MNg6lhrm!8@ya$d)B{fp<3&tgbgxjb~k+RlQxLR&O^ zzP|FbWA)S7e9$x`u&^Z0-D~>&y@)#8z~C*OLHyf4gupTT_aRZdOW61l{$C?*qg088 zK2zTH#O0JzIjCb3$3-_Qiq-z*#iQaSdmR6WxWT--S5NNo)3l@Q$ojEf_vG>fJqSMw z5TFs=Dnk9<%4gqs*R$A=LQAJ}HE13|vy(R$ZVFtddke>qVRi6P<5KedNMG_wRVMP~wBQFkf0!&$a z(DvivSk|Ibfi+MhBovZFFsmP+PYe~@9D;ZMAaO8H+AU(|;Z<>5l$qAv{(cn01t!)K z)+yQsQF&eRT!3v^_XFWn{)ea2>kwTm;w^3%(Bi%G0b;H;1=wOwtM=_zyM^0jSr?g% zj&?TKBT5X*?ek`1>{(kSJh<)d{^9%KX8%jPa5m`a;EfwT+&%P80<0y5!h{JD>Z58U zI=%Zoqd}5?VG2C*w5Rc|+=|m)n(oz<24IBphL&oO?=Hh{`UTpwm^Kmpa(xTO+#ox7 z2W(@o3`B`&WMs&i4mHqP`mf<3BD5Y%*!l=PA49IxbYZ`EMO0tQ{l<5G*ZeTv>bs(O zofWGdp%H8X$|~c8KJog{D1A(nERI$GBu*Ii^A(Tj&5IF_6EUy|p2qkk9-th2Gw0v% zr#v;fc{1M8;hCW7N)Mwg^)Wjk_nezn4V!b}%wfswl+U>*p!%a*z-0#JO6ybK$z7t4 zLk;x>BJRTIp_!`arJpi5>H&w_L*lTk{*sUz+K;Tr0fZ}VFB&JQVF_19Q*T~i;$Y^? z>ijK=GgY0U#a0pB`O7QIhRe78)!L^TAkP4krQ$MIFhss)dnCB%sl2W~yqcw#3k_gC zlKbY`^>*7$;t%Nhp0c%k_IaQw5XF$vu?o_0Kew_*Cszza{A&kklpHt(xpS!4@s-cd zL&wf^pm8FgsDUqJ4c_Nk7p4(MGZy zLvzD2)5rTO(+KICov>N+A`)BbPaXNB`6kb{NV$*B&dL`uq7-_ZQN3DU;_qv-wi7j;CJoIDQx2pcwJ>&N-r~2{g5JG09jB z{`U!%=Mq0(Sa|q0pX>GtIhaZ^D!2~wLhGuoNCe@tfc=2bE%s6AFQ&}r1sEmM4{Vpk zkXkwPTI&{|39f691O3Hr)a-k9;4lwbS2t+QJPOtu(tG#WhY@R6@-O5o2uxic^)_X{ z1+eSbbeR+&;UY<5XXi{x7cxhx45j!?Ddy-{wL|y5ZE0(;2njMKqzAeJa)9vfivKo6 zkpG6*u*>*%CKC-#ynfp+F^h)%D+jXud9u%*jk~gO+GPkuTB{ ze+(D*__mmdC@?dx+{^%kRpP>F#}S-w)%_dsPg4X>2csV^sT!uQ-K5MurrMMZ7ruP& z^;_Dz{f<|$gE8~Zg0q;u(|wMle4A8$&z%B*iFtTk#|t#)d6Bo_+F8Qhz3@>tkp(}{ zKrfwp+zhYyQp{RR{1)Q>7?6BF4#tiB8E(B zTAsgOwr_M>{zJFYe%}=y0l{T@F}zUrG5_&MtCKf1>a{7LXf|2NO4#hB)3KoA6y_Oh4c&7@p-~j@5eGdsX;4Ph&KzdJhZjaz!VM(D zqjb<@*{n9(-Q%XuZ(JiS}- zwdWi6zLJX3OIq6GhM)DzDn->^+hz*?tx}?54~6)a289!-U8i~5o_}78&X<`LmhVRO zxDwNAIp0e!*gdLN=Jt&RrgT}>_PONeBUYf76LMq{Z93UJkx+-W}?3TOyqszNGFzlSq9%puKjxH{F=*?}W=!WmX7cgXv?wH2B zwmR=$%oH=y3Pg70-y8OpE_;q!JPr;9b+@ZRRyH=QySVoHvF{t7ZzgWd_n%XzMnl{h zM!O~<_9Z>0k77$j%mU*nM&oKm#ODFZXk?K zIhiC~d)z#@A)MZIHnhDqN6`%z8A$dH09NNS}&m)B^N%P zmx{?BZ;l`*6t?`cG+qJ&B_7g}Cm3Gqv6~A2O`jgUHjB`>y8C$%Hqejuoco=E#5C;F z2&eB&Js65NWn5>XRJ2~xfTI4!X{bPsv`$Y#Vchq!oJ&@dkKDUbFW|JViA%|IcyKkV zM+6iFGOK^mMmqd)3ncicRg^b#2HI?mXcD!38MI{P--nFq4b$6PLWq2?xn6p_`i@Dn zz5W=}`<+!S6QGj4;%^M_b^#2fz;eG`iyN)&uI{mkEeU~{$bL}ML6s?1nS;U2Ogneo zlmvk|h}LFz-$f4b5amSl(&_bI$Za})V&c8OdmfmG`)8s&3PemylCGy7Z4M$Qcwx1U zL0}1Z)Pw+mHg(aE04{jB57U<_KbZKjO^;K4F&(0q*i7E75BFEPx^pReX=3_|W9nop z7BJn@$|0lp!0oTs^3eT!gwTYxHlwE!Trw4{9wO#tc#P{v?zAjH=aqd9q40hLpFinu zg)qCW4_}C3Qud6tq%Ed(0eX%3^~e|!pdzn&HzXk5bM>S0K!XS>Jjt9@`6tJ1T4rS| zQrD{|DIGlj;u0>4nta$do;Q{*q1tP*6WH4PSJKnsP47xP9!+NE$(aN@`cmHGR;<1q z?opFWZAc`fjvaQ@QWpm&!^cmg-N^QDlE^N(zizH%4rABsr4v~(h zQ#3c+YANI5z#<@8Z^Xnk%DLcN@jHx@co#xNdYha)9+e<_V8|1xViDD9+d z>H9NkT9eqX+vV$*;h6h@)`Ho;d=1(0g7wIuap__RVOlJ!Chhy8$ZD+BKfMb#h-fb5 zQlz67a33F=K!pnD7ghD}3PMiDt|s!!<7JU@jFa&XrV*bZb`J1dfGSvCPBxIn6sl&ZcL zMv)1Dl1A0l#fdNtFIQ-IJw9kg0{XqbLPZsHKVrcL8@NCY5+pEFIQ3pfpclvh-zN9| zIof@sR!J&@*3cXZON!}r2bGayNIiwGInb1Ef5D5~ZtHd8YmftS)Jh&Lyumyp*o6b< zFVRCaBuh7b3C*GXrE=wa@**1v?exlLZg5BPgpG>#&cb68YE6n9aLCb-1OJP$g+=1? zue4pdB3JcBbXOYjbA;JPIi}p8*Lf;qaIQ!7KdTz-Z1jBIR{m=9;1;nE_xBu9|eD~A{1V^=OjrQ|fF)()<=SdBY+^z1nClHRfSB2&`DCsnKl z2S=;^xBA7IriD=u>SE^F>53lHdOqlVwmE9rliKxgNmAHP?O$_b(15r%r$G5OvMA?W zJt`mq{oO_*8kthbNOrHLRe5AQx^2KHG-xsZ_Gb0e{GjLba3^^?F-1=$kyQv5r>P>mK}Y3gC<&v)khiMW=FPA;a;N0O^lzU-f^@ z8ti^Hm@6rEqMi}!8OVOy_nOk;f**adOdxVqQp%y%TQC6O9h|=f3-b7Np%S@&{{;=0 zk0`aJ&`T?Yr@r_JN#9GSLo(-peSVd*2A*T{VHa4S0Wu-}D_SZ9iQ``wM?H55U9xIr>o7WP zf0Oli6jx|5C8)ohZwXM)*;S^d&sP+7bz$i=pt^85ig#?L(L2(Z+gBG}WGijw1a!R} zDiU$oGMn@C+w*3<-k&UNfivg9Gm-!>ApKTo5m7|znVW#7up*M^K5|%XoVF1uT+i4j@3 z&5hfQlwgFHO(iN?h2`l$a=j{g=14hq!N z2v*%aH(;Y|OjqJAcs{>@>c3;U#fGFzk(pjCwG01HC9C(DzQnIC?|7$on6oMK?FIDz1*v+^>5-crr zyhE$-bk^%3&@QvzqxGIn)%zu?vp=X1EVTLn|M_9`VXxX<0uZ;ryiJ38bv^)#6lyP| z5ncP!jce-z-GUBd?6Wu7SJDffO~n`f!zcIE4jXX~d|z{hu?g$z)c)*gLFJEs0e?NT z<&Q9+H*dAXp$E6hl-dk5STsGN{^H~2=+}jI3C(i+de!8&F0@}qP58yy7{et)OiT); zFs{=IhgB9GDGy}8>(MlUefktVm+8xnLvWBB?Iedgp!)D0ZeZ~AH_9>lw9H)dNUkf7 z!wvJX=!+6~hJbhhj?zbqPw`$7E*QCdKRpXS`@_c-${er3*4?-Hgvck3rcq+D93QVx zAiNQioTLb}=cdla`@ZF*Z06`<#G>-`Rp(#3UteVi=BlbQq!h_1CJ2*(`Ij}UtWtM< z!pl;paYY&C6BJe`6=n1gHqoCvYd$lBkM5ak6JGB6aAP-z4w7;J7C977xQfvOL0S5o zn~BQ|IAL+*wNZmKrMH*y_;SNT+Ql0rd+qMMXhKF2q3D~$5H3(ZDZN&v3YGAl=h9@K z!|gV17ypfEo%6c2vO{KU%*y0C!MLc^BRiAKT3Rm6B>MFSVu0q~r>PL}1ZrVOtY^kUqQ< zs!4pi=_wcA>Aw;RF;4eIpMMJvoii=3K>aRwuu_pEW!|KTwpNuZB~Wrbdqn?SE#&`!^cZo zkRM(9R?;jJYfMmLNbJt3g8L@;%ek8uFV(i+@i>CgkdQQ$xZta0xH&2ff}S4jykl81 zI=)Q1Nf_lNO2n}KXX66ho0IX!4BSVr{uROMVc<*#dgM%1yZSc(ixY}cF#%s~ZuThbY`s>5liw8@@GhZpZBT;)gGj?Bz5BP8 z@m7~`*^Qopo9VIL+T_1|%Gytr_pGkVH@j1LW@ku`sj_bm8 zojT!5XE}$kbHFcm3dN@oi#f{7>@a2|@U2P~Iny)7-j$g2pb1RprVJ*a*?Wt78gfdv zh><-yg-5xLW5&K$dnj26`ECr(wYWz+*3|Rgs$u(;^8MbTgYpoAh%Gf{a%1cGQg(Qr za}*8~fTlQ%I2z7wv=I`o~l?hcILeA`#NYq?V4h%3Zas6#q)&+5}ViRcSbj z?o_cIYQVR0Rv~Vgp;ZJv^6Mu3#-A{->N5duS_o=+I7EzhLV>kVO&r=XQ!>1%L7o_= zpj*3*`wLfb_>M!MxH0r@q>GHe4ckS4uJ^#vnC{Kry|II{5DYC{^f-)aZ78x8?vczn zwo#6FrS3$u`eTQi!(*dS5ttG#D##zPgs42S^EfLie%)2HWHcJ^2X7KoH?w~^>admH zfS|CqpG!6T>*i$#U$NN>;R+FTF7H#qP-&mfwMjXvF%>$920)ypyQ%ot`~rJw$U+-@ zMX$KfP~KSextGVyE6MPpTm`@OGUU52JcB-e7Y4*l2*f#k&9>iqNLqL5$CW?-5!Fu_!QKMEgPmBe=1r;M7(?Y=I(O?j<^*79x9yXV=rczpj9FK3wA ztO4r#xN#^m_2-f$I8&c*-#2SJMD+rRK|3+%&$~bo%TamWlrg-sn*!-D%n*i7BoI_{ z<`S$u$V=aQ}9T3VFN0Q_6`seq?2h054Jq4dIeu(wBdzBS zLh;z0&4t2|UhS1#PHitl5MK^4PcC#*idGb?ZCXY1fF)X2j+?`j{4|V?zuWYI1J(2} z@XHmld0f-14t-#MpFNJR=<%_#6s9(ItXc0o^&3SBu716Ep)Hc$E$CAL+|!=Vk|^;< zo{r1t7Jl`UDz!{Bh8Ov|>7RZm5rg%5lfjJX?R?s4b_;?!2pfC6k+<*F91EoIUw>7B zZ?pn-Mg0?aRLUOi&yzFlpD-}``2Ca0BPk(c?}eRIGYm>MtqV0$-%ciYpTQJt2i&E# z$7?w7kNAK1$TE??@{_tzXKwFEnV(%^`=YAeiaghwnmVx(J?C7;$RakNao}O}?Tt9W zzw&Tkzx%YC%n$JuHdN}J5ULYIhj{iK?o}P};6OnMbgofioQt_vpiZWDHN=op9n6GG zMJgDh)S!Wj9DM;_h*w;CbqI2I*(Pj(PE>%}7)#3*p;XEJ)SZL_57jmC`mJ@cDM{|p zKLiruoe*U(rVol&!KqiC{skBWp>7OJsm|M|SFb7L&-;izz=m-a!SmqaKIqprT*vcA z(2meI$qu$D@8+Z=bum~{l>o9-!o1-xP>EpA*nW$(mYi^ac+w(IByvUn$>xO2-1d<5W4 z%M1%czw0Q*01SC~LUkJcqmSd4_X#lrCSQy+>45B3H*QR*sZKnn!zDax4Gk{5KadFS zC|Ghoai=akTM&|ELT8ce?jo~0vPUGSKgArYpW;543Yw5*BFS-X$ICUz+v<2MHgJt4qTxVaYCJoD(yA9 z(jaIuvEpEBiA!2#+1#UYuWyju+DzNhI`-GXG2PV#_QA~=mE69`z{-4+0> zLe^HPQMGH437U|b7*yv@^!*Ljcdo>lU9twFCd=A$|AEq-*iee?Ke+7ULL@3y?06Nz zCkO)vUOq)YJ)Mu!>5-~z!if_{*%KZYMFA5?@;ExW_MwfLn4Q}Be_)wVDSwlT_*DHi zQWFq^F+54|Ny{c1qksuRQYfQMl8~)rR-?=(*cZq&4`ZtPxc&(eyVRyI0*yd$M_)$uN0Oj`VNE%yzc-_!Me5| zzTQ9ngpZe`fA&WcDvqWq+j4(DEOfmzlfKZ@!!fM=PmSmk!1utT(xaXOfS^E24?0tpmj4p%>|a9>w^nIXxF2m z=b22ID!#t_IM5J!U6aQgE^^@~55(WO9_8X1MUVxmbiHFiaGNpzeE-9&ICJRV1)sFA zG0GwhGzIDieOzzht#@wvhctY{*WIXXLH8FXpL*(Oxt?DHyV}w~J8%K3Sta*+zqJN7 z|EmVaI0aboZ&k)lmmbkhtT!1ICW4)IaoI&tn_$m~5^UgJ)q*_gk@W!i*4mgwe z?B3n*iH|w(58Q?Rp)Gpy(G76inpKQ*%hyqnYe1}i=*&Drz2wtEZkY{dn+D3MtY61i z;}i%xmi$7NPwLT)r)KEY>J>i(%@beNYE@4k7njoFx(jMh_#IJ#t%~aR)I82+^<`<3 znNh+ORO9EX^GWgn6O2$(C6!4t#F0m`$Ms%o_f~At5Je)qy|x=SrTm}~#qHTm=6J{$ z8DkKp-s+`}y4}JMn{H~bw{PYGKK50YTJjC)DXpp3dW^~?OG|gd^-quM;C3{)(!B}M z3&hnXZ!-THj;x{Q0Wwn8S?4cMu>StGT$d-S4bGq73Ypl4O!Il4fs1-E4>B8A?s* zS0CRO7)Qz+-(^NYFYoLu?Q=H#0|NhBJoQ|sR&S@<%PLmHHuqY*nAQ2)!1kP?88in* z?Z6qeR5gocwNo}OfTm(!OUK>r#$4^C>GI?$W$*yaPE`EcEFyuaN7?lLSB-WL-%Ips zlPuoEY45`c3E+PAl_G%RcTeO18@(F{WK|eNtWLud7-EMN0FA!wLS~Ne-lK9%BVpi6 z(c^Aj?vlQ+za!+k#oa5BXJx*5{S$3GHV$x*WOZ+mJK8RCcSKzTGx`|E;yaKpWr?kv5JQXtf&&JKWbA8C}A|m|RVCdD_^+Q71 z_EQMEO%!mVQAUiGC*At&KuhC&mJ~h4lH4 z$O%)&5}CD#*00U8%;01eH?0K||5ssp)b+P;XATYA?D_YW4AU!rGcwE1oz^1lOPb z5?i~8SLo)>-?3~mP;%WY9qdymjS<>=t3Ik99nZ}-Fo5Lqq8!{CIYbhaOZr|@5GTX zbv8s9nf@{)**?j8qVrr;;>C4#T<)3sxv)(elENT8mIyGChDmmBO%ikm1t(Kc3?M>+ zq{yZyZY_A{@HpEc&7@K)vnq*Wi_Z98E&vLmaRyBU8?EpnD-EfZKyvQPt?2RB*zyEt zYwtSvLcQ~1wk+3N5|1N4DiTsLE6o^VE5+Q&_TNimOi)v$>nHE-pB7ZuyPGAZ)t>-l zGDs;WQ4&(y9Pex@8{E5-w$%@cpS9D=R}uFZo#NyS!piSj4^B@{zZJcu85Y%q$$imb z;%gS7uI_rvYt20&)xdj{w`Ms7$WOouAJOJd^S*iZ@<{kY3nBQNrVN{0<{ZjH;oGya z?)(LT4fWl?E)4`D1^fAd!Ds3g?pYO&YX$ zuE7Y1++_Zww=61D>{%7?`6=OF{<9eMe3;(-F(l|OC*eHR{DK^Gq_C;L@kE;MugXAV9HYJt6ua#Q_o!eOy+rQAQ zyw{^8(37GM-^?sv%@84Z`-+rhJnZ@}C#eKB^A=j>LdZ5Z@#31O@363Fq z*UBG-^L~Kbw;DCYd+G5o6VOr-_9GoF359!gxrJvo&QH zFpg7;uB_~#WxV$WWVJ$d&RLeNZcRcnI)||5lbN?E9b!Q?TEQJ9UoGlJINYyvX|2Au zT;^Q%Gzpq4);IV0M<5W{S}RdN^af$Hi7EVKrTSv^)OcMVE?k`2UH1$*kafw%a!5Xq z)l3GxGD{xYVa>xDXQ`1h$(JzS=uTKBfm9lqgEG}XKSl?Pjcu&H80fE z0r7&hA|xa=ariLB%|O9YdS~JY@PpJhRt#MJ0x82#)90fTtLwl~Hd5#IFcOYafWuk-Nj74O_el$Z^Sj}? zII7LDYUktKSyHNA2mF@xKwsq+5qL3@Z%=VQ0aYPU!dn&Lo!SaXz%{h-A;o}EJeONE zZW|A3LF^viCY~`$%|mBA{E!rn3&!8g(9x2oN|3C3&nzl7Jy898)U%_ub2!aaFDdV( zNMG_B8vh>vwR*0bGh-Db~358ucd$I1_6>f%_WyDDU*+_EHSEgrtpo% zhfIZTzxAtdg6uY`cP61>e_>(Y;EN)O-G|H%x={pX9f1r5=RrcwgHznBw_Yz;^awz; z>hZ$qDP$aU$A6hda-H*LNNx;M`^xbZa#D3j9pUEZ?SEaZZPoiKr0l)v?0R{}V_mWws`uT| zUI~EIpLy~+sjhC4s_G@uhd$HQxm|{bd(C;+PnI;FAj?*qEbKd}WFjNEzwR>ng(5Jc z2w1wK94|qs1SbHYJ1r{TI7Lv8p9TU@lX7(}+Qbi4nwFd>$DeqK3=j5T;BE)GSBWd$ zFME?BHCVOl|E#RUppBy)Jwb=Mx_&Q!l9TK{Zh%v7PNvf)zPzpVML0vfXpZ;!%du!jzpR49wgaI}Kf&TFOTu0m zgQT9(z8`QM{V;zKpz1vculIMas5FGm85@$w!H*(>zEc8|Oc>u_L6>AyN+d<=Ih-S1 zNHSC{Bg1W2we4E@vv+^lXm`fPx#)}IA$Iku(1spaiHRIz)KkbLm&A(`KvH!)({w*ZKazP#>0%_K z*(@FHugQv4r%N&c!sh_1MG=@S1n97tTc4Xa$_OdB%h?m>nXM-4b&3!HO6P7kEp>PA zmX_TcAeq<7cw$(fK^H^j7^^nRCGIfi%wY5nbop;IPm)Y4n$O zFE5wRuP!rWPTvVi<~EtHL8{*?mxkos$ORuq*Ps+1i&6|i^$a`0moA~2vU+tBr z2a`f+oY}%yj2e|*QYfEXTPs0~@|4`P6bAw%^$2eG`kIjZ`w5jMT#>5xHc0D>(K-Hc zQ@=dh6Or|`Ap^)R*xB95h@V zkVJ^8_YgiuGZVY7ztjV-c(?o&7I$Isr>!;BTXt`hL_7*YcP#G|CFa`bxkEsE?A&3m zSDpd_98@VS?b-dj+1s5Mm3864;mP&Wm zR!kt

~HG9s7|Q`TV*XsSbFMuU+}v08)e-+n)X=ge$&#alqv9uZ9?7 zM?U;!XFr@Nt^P8Ktb@!P#}bJQW+e372iYQoTbn$W2)M8wI=U-@eR3~Oj?Mk5dSo#m zV8Ycf7*T(Ve(` z76Z-;y^ZW1C79&>Z6?=yDOjEka*UMtZCeaxo0z<*(rX+oUC8auGC0_U@W-Uu(HDB> zSWxYQA4tya$uPO2*+9-0*8__K0g|y>#>On-4j}7WXA*=Cf$9(KWAaF6%)k(_`yxJ7 zQ6xk8@aiflN1E59O6LZTV&1Sz#K7t&R|n-IE5gPcQwOj2p^R4N{6|p|V5|$mk zvwbVp31F6k+=s|w#$4Mzy9jUyBp2u2Tdi?Zb(yn!--_&NRws+YL5ancF%bFj{=x2; zbc5ToJ8%HI?}6?7v~sVU28X$%O6LYQ-5?((20NyOeJ}F(v#_sF*TdY`FOH;SZ!B%x zEK(Vh&fs7t?C1E-9_M(F7DZqt5y%K8#u%RCb+X6998aN#DFQQtfU%!riOWGaD6!C% z&SGcxV&}~WS>}5>JhA-s(G^0Kyh`T=4&49&+m?PpRZu>NyabGhs6hv!f}Nz!o@2&S zkT}ce=%87oMI{ykhi+yA0ekXj|IOi=Zu)~bI6j9<>LH52R1t6)J7#}ht2rQrl&*H6 zbd^o!9F%)8NVA;Xz(qK;C;|r}KwEkklfHMas4zd!md>${q;B^YODgwBZ}(Q1dIpSE zNIl&T#8E%Z3<7o^%;oIt$9RoX$WcDe1wlP##u1>plLPGNXurAEc*bGrU>Bw{9FxlY z?Mkd~UE)(`xPyUIc!7Ov`NdAi4AqZk}tx5I(E>nBAZ zPY6u-qd8!9_rytZu9SB8oT1YLkB9)nfMd~7vmY1OI8S?jKm68*q?Lk}071g*rDut=Fl>y6kZt?p;_t!6r7Xi~P&{a;YwX(x?!c2o4Gg$?p zKS(IUl7jz+RSw?oGC%4cMWA310HJGVEttEZ6`4SQl9E}J1=9II-(K@Q)$a!@;mm;i zzUGiLAS)O%!yPb2AM7Cgt|$?p+MT%xnqiiC3vv~VVfYJ7LW0hiEa@~oHMA!gFmy8u z2sq?o9B$=ucX*yzXsKSJ2od1G8jFodJU$GmiNo%}3B5X_ZojOl)PyEw<(Vl$)U?S* zLV&#}fIjnfqy=WF&O}F;57#>pY8YNp~S|1IQew(0Xx(~X79(plPwDN zv9sNVg?>HaOb%aK>N8DcAL9M7??oCZU|AwaXp~Mf7X46n&+MifMIes|-t6<)-_6xu)`eP}#*jtmd(p2*@OJk~XC!pyb3c@sXRhk5 z*Hr`#h5(;C_G^pKtv$?l2isY{Qv~J;0oyUjTFR1L^uR(wrycZor1kWHMJE%i6N{6vv)KpeX%4~`btYjBq^<9DH(x#^(bB>cov33F($eMGk|g=!C4&g zn1y6KNOjA0guHI4#lkXtadJS?=XHF>ynqP;PD5V-p3WE|@RtwtbPCVw#X&sIK9u!J zLsq3XIR8@lVNWFR_K=0g^E~vj2~;Uz9S+VkxDc#1&nuggR*a_dvIay%R+4miJl;m+-I|JBE*Tu+Nyvd^dR1k z@=Fw(&|}dNgNKV?WqzB@I_kBG5dmipLbilHee|@SPaiWqVj2kS?_h_rW7^$643Y5Q zls}EjO<`9K`MeG#~SD`*6&D#*I-`r=XxV@ z`6Hc2+C4A7uL-(kX_;3}KwVF-4N7C!Cr6d}F#+&^!~8Z|58z>{pg%201gJhw z!^3^dwC-TGOvaz@%*3Cs06CbqGuR<1q){R!`P{sFQ2y%a9#c1l%`rjA7zlv_e+dYR ze|u4({%J5lCC(GZu~e-yEh*nKZ#|`0O0aA%i9e3(w1f2@9Y~tj&-aYUPfl~2)x@Tw zq3~rEyIBjn1*`%Y)xK4CPAW)x_;0D)O-rrMnYRc0LA53(C!CnDo-9<|(`j)_G>unW z?(K$8#MWW++gX^9ytTPhEy(X|IkP7Ao z9^K3e0_>Ge3ccL5C;|nD03~udC)rDSvFnKpZp01%}MQRK3xZ zeBq7hM#)Rp9fM*tje&3rwr+xRgAhrYaN z-c&XmSZYzXAWmM6b_a1@PEL3&rd#E;p2URY$$eSR} zDi?CF5AQ)KGz2U(Cy>;$Z(Y(PmdOJc<_fw|1ZExqCG?rcSg(*H0^=Y&h7PgVw)E^% znG9bTZyOn|MiF*~3Ws!huJ^*O{HbT!<>vO791U@K2N)`VA4!fa6lp=JpIcojZ-n~0 zI^cz~o7=4VMv`LT9^9A3{K<%aJe2n8LD;lM@QT2hE&+n+jwa>Rp}6cAPDmGQ-6X(v zGLAiQz}t4tbI^3!s3{Fk1qSZJ>sP_yj%71v29pX^lW`rXyf0R26Ob%;md!(gWjrN81dizDMbz+cxEbH$IC85@^>W$}<3>p7Xo;26 z9oM4`-RBQWJQg#V3TI@Nm{V=_poNS8pD!nUoyRMoFXSFF&)dch8jo4zXgey|O=8EV zikZcYkha6E#AfZ4+m;+jQtyXKd~K;$YQ5v~2n^jM^RJyyDSx}V+7Ki|yC~&exF~E0 z{R9|_2S8F3;Hl9bMqRt{p_^;Gnv!j;oqpY#K!V4VVKRUic9MSzL&29%u9Kzq(y<3Q zC9g~(e{C=(JBDILl};@JC1^VOFS zYse~0##jQp*=E`@E*>N@VqvDjjMoD`IT>!v>2#wA91;Ppe0t=k=#YnVCQ3pdM=y2K zQJoxnn9Au-MT`Jd=N^#xs0(dK zC=Ydv%BMG4Ys_=^d=*k49p32Mfcb{dLeJ~f;){(DkR;wSu?{B;9#oJj|Nnb@jWl5r z^5G3u#K1!rE;eLOOlP`q!oa0=k4A(9ONiiQ;Iz#lse_~&HaqJ^5hy?e5VnS=Z04Vx z0&KcgsZbHXn2&DhmXVQO86E8uueTISSz6(1cAZI^jLbe2iC5}C3{$lq+s9A$FA0h) z=?6Jg`U8fjD4}v9LDC{Q@IeZZ;ZZ2f8o~&LWO!^$hPQ7w-%n*jGO4VrlwdF@e!maW zq8DTXX*@Gysly~-u&-B!2L_E7c>q)U&dlWDaOY)V zd~8TYc0EWyGy%{_G+AHPgcFRnFDo~g8t?W@d-73-Bb|da2{5w_N*p-w z9qW`zM){R=b#6z5MH2my`Ub1s<_Fy<0(nM&lW2!s-=UX#o*Sg6Qv@soERwNf&<}=+ zk(e>QGUFJfz}XsW?FVi$dGdP_JstGkROgpFI%7x;OA-J+ z{3*bh2numy9Rh)XtY5$0Xap!_^X2s-t*p-n4T0bMPHh2SA!r=<3d4+G|Kt%FD~eWiqa%GK6j}J+ZN?YHJPb&l5Y$;2T~G%{QLzybKcq*@SNA zJ?QJ*XYPv+@#@@Hiy}~{2(Ujpc8Z(L2e43q)OzI?0g?h&S=-n4iaBv2aiF@LU($BY zL@aNt1JOWTOG23IzDP0+fDA8fDlvo}h>Xf&*v@ac+3-#+szrC<{J$w*gM0d>ETwhwU}`G_RW-0Ca=TnqL9S-pC-+<4=S zQdd`J$cy;19PBT@vtMSXLu^jso!2Z;SK7@!w zW0qi4h0E=e_I;aVc&JNi>z1KUCMGap+q5VG`9uKIYsaT^&z`l)ab5KUMS=hcgEq{L z_HCxc>6EpEYIgH&yDS$i@nQc$ke*lva^)JNF*OC5#wh)=kkDCdk~AL{`-?BWXpW9Sl4q$04xHG4lMXqtvFq2!cr_GnI%Onr)-4`K95$qK)|V1CUzE`K z;`e-U^1;bSb{i(wm6`+=niW{QI3@zE0!vu|O1X48q}TmAL=3Q4$WU@mK_gLZz8gk@ z8CAI(D0DMp2w1)>PEL=h_PEuH^Dr}TQV~5?5wH;;LD0d9-tFyen?NEV46YVQ*!%D= z$;tc$eK~&=taCZtQn00_;OO#z90Ss9LA3{Zti(7!``OQoDxGA=HXf?*cl%{a^4WiF zGPNaih>hk{jHR}JJJh-PJtbiht0_2^8U&V(4l9~~6Nu@Q$#o_1vpoO&^X6|9<^v{< zS%vI5CYv269IQkE6jp<`0`njf{>Lh121HXkdm`D>vj-E*IO?7KtJy_2ia^02z(}C% z9(w3ereLb96Q+_=$H^KgWIxOUjbwYRs+U3cAOcJ;wD!E#b{z}UtQM9Tbhz=jVwSEgf$ zBvTTAB+fE`oa#=CT|e6Y@4N3lbGqn=wGhkk)qbgfBut5zI2BUiq=a>2A-UTnnY6SY zExTR-q0=!g>qmPh{i_HR5CYkRo>OntSwI2Z%>_^uk~!7wogLdvYmx~DryW>0^!8;K zow3Y^Q!^iU3Qjlcccl2*?E>Xyc_ICEZI&)_WA)Wd!EBR>^BolyNzaN-6#SDg#a8{olZJ) zngtXT2wIs!LV!{b9pYMcThgp8C1uxHFz?BsfMks&}LG4}JpPTAY? z91@n;t6UujggxX2Aqq3kIfq#Ly94)}n@=QG=4XHZswz_fE+WHtbC#>Fy2`|#QxcvI zadKZ0WN&Y;Tz&P`=3JvlF2hW+mo@lJ{5w;%9tj6(5a>L2G1eewDTM}P#flXs_Wgwy zUNGNHr(Wg&Y&bz-{k9{44%fD)8yE_~*vrn$?6@fe=fai}+ag%!RbT7as!s$7tdrjSc;UWN)`#|45 z)4o8U;&t|O{$Tf5KM37)zXC(UmeNnF4as{TrSC?rbMNqwEM2-(o_z92`QG=wXKG9W zoGN+R`#t>d!_wW|Ez6fLmonrTXL%d)qjTYwsi?Dw7x7yMiJ65t=!cN(hUG^;`jJU+ zlgng-$1q0zo8SDVIhPyW?KLi|M(SJJJNDJ02+Rxu&POwf3ED$v=I-cOr-=Xu%M{e@dt0m!FMBYZd>ShaE7hc4 z%Vy;KIhcG2$DeH}{qK*hG3P3QRNT_iBFmRAm(PFx^K#vF*O~9x<|C=!`8x@dME>bd zf7%?^jf`>;UIgXzy0Ar*Q^3JYHXtdlLjLj(E)Po=Id`DXIPU%Sx4)I&|Ni&poSZ<| zlL+(0AvU&T&Yx*g`0jVVYueZkuX#>nmLt*5d5tB;&!OPhe406Oa&`c@G*5(3#hD*OGBj?4a?$2rs=VJ={%1G!cqyE^*5xDlW_ z)(r`9M0W0Y#z2uySq@c`aVa4yp{$>xXZPgeXX7)g$Q8^e3IErLRVEeeN*Mp?&_+r9 z$}6vwU;gr!rYg2XOmeiz!X{Lk%=!7+Yp*qvf~F-)q&yxmWc-CS8P`9wfmJT zE6w%GKxWLlUR6~kfBxrxF3&vkjF~{#lMTCG*>$q($-2|gk6G(J`q7UXGB<6cqXWv- zr_?~5?X}eH=9|LYc+vM*j2}W)6&YdS50sm4`um|dvYM5(hrU$=oFkCkt+L-w^UQV} z`ZN!l*xe>_2UVCjm%b@x1Ss@y5t6>%RvGATLAV++j3M#K!AdYQ4dp6pelTYt3rviW zzj9Tjykl`dc4EoZrO@oQw6+?F`2FvHzx?w*|Fg8>Gs%f{ z`HCUTHtcUR%R85sPdl-WEv27Q6O>ONypED|BP7vS!is4>(!NlSh@x#Z9HgNiZ`9Gi@uh4M#Dq5zoTa;3kh| ziMSOBu!rGm&>*qxS`>joL?Am#qY&$-bt)1BI7X7dyE=Acwb)uLg9ENTb>xrx3EXms z%Q~Q--g4Mym{=L&$-a6@gKX$)la^=-q@I>Nd-fP-G?Fx5-}=_K`0>=WQ(m$=tLFWWEa% zgf~_DDNM~K-P=>i9QG{Smo8IEiLQ6`3k-PmZs?Cm+qD`-tgyAR#uDq z!^uyfw#urvZi^2AdyNYRE!R%%06aZ3g8T zm_7E`V-w#kftsB*c$>`s2KMiFV1+U+2$M@8jts9`hI&16;Uam{{rjW`-!+X5OQ**# z&CShn!wol>*Wu332?(9xdN4sb3T>ifetM-(e)NV$qiW~sX@xAEvqKRkq_3w%Dk>V#W+s|B95VWwA~4$sj6>y~+jubBHP!1aU<7E7rL)lh zY?N)S8^!B`8W}2JlKHxFuQWmGv&o#pZiGf)ltRo6ZYnluLqdySIn`A#5j=4568US8 z@eU9l)>9E*cf0sO4ogAUD_5>CN79p>WX=UnR<2wrRgjKj`&wlsaG+$)`1UWJSdTTt zoq3M4UL@R8YeMqi1y%~!Hdr~9jwj6ZYOyB!DqNrB&K1>|%e}g~+GrN|eLZaM>E130 z_je0Z=a9@lb#$p*|E9&V6mjtdPv)8X#7PkswmGE)fS_0@W->o!{-iPy1+A?wgUof2 zmIKkzPfigqBU*-wGk0krH0}@24*u~7zj=D>9SW+VcG6Y*fx2-C{InINM{Zq$P%ejk6jGBGE zkU87WJHXid3gnxY(Ss-FNG7d5xaF0HcIpeG@{F|;Pe*z(t>yZzY85_!*x3OO0lH1!qv zAai2OLi}hJScy=!t501d?^zj@JN6FCjeACAZya^vYH2Z&*Ma4P5|6yODU7tPCCDWo zlxn0;r5c|$bGCKfl#ECeGCA&%nm4QBb~EVTK}StGZ1(l;mFA`E&}Xs4s=Y(jG5S^! z$PIx^N6hVDBb$3Q3O!f!^tgN=Ky^D;=o%P+1K8F_%o@~XkXR`rp4m_$4TxiAVIJ^_ z60<+mz?3&C1Q8=em*5aWyn&qEp#@%QE^{pSY}V(~`9y^ZD4) zS%Fh8k^=&EU(4ap%prJw=jY>>dz1CZLPP*5O}qD)iiLtz5=vN0j-H4Z?h%j)i{06& za_0vw7s`bQz%%o%7#hHa1j-Tyi=KqGde9ycCwS2mlB+$BAz|8TY;(M|OJ27;FE4Eq zGqb1BL||Pn`>GbXv#y++aDQ?e>pC9`+swK*1TBRnGsoFIj$ZoJxDg%5nQw=$ZH43J z2`63*uYaZ{&fKi|*l?}$f&h(mv+t5r#F|T>M=8h0HqwRHNAV+bJjJGYLju% zlt!0g1+gtd)@owWjJ>uj!y0dD2pQFN=Ia@&-%OsEPY_?^b*j8aVVCA#E}+5}-;aST zZQ`FT!nChL{{)gX>%bJT`(M`N0$-cL{pa&&z-Dk!mX)Ozp(84ALhZgX=)%G>@M%B^ zz)jN!hs}L$o1`DShOdxyp?`|*e12~L~rD}xrH$1;)-Qi7YZ7?L9g;mp^wSnHX&6q;hBMEi5J0v`blt4^=ya-;<6+aegzmeb5wO(l32ANFY})BcM$G`q4{Ixf(go+R zrv|OmG6{Ug;dYp#ElLgSof#9f`K%j7AXfx9lCdwO6}9d)^i-U zm#TAXF_socI&ByvYo*F4}{Eo!L=0ia-ts zuwSu129SAgRk=mn7NN6;iM%!#!}oq!1_zE7dIDzFNZ+;dSu9Yai?tY#bW;EbP~~p* z+1x8*kFvR+L60m#1T1xXQrh=zHLZ6;@)^YfAuJ~#go_DE9_oyk&qEnCdpM&5U5^-P zFW%esbhDFg6afbau;($J{#-;)urQj!_Tt}(NQ)Z32l)alwRW&} zSjsZ~M{j_WQV4^u+R!arbn6@eP7WFO&rnGg+R*Lw)c)9)lmWz{Gb0{L85}q1z{%3r z*J=pe(jl3zbfXB&2?87@-A)DcIjOl`bY3GsX~tfRrM>MXEXGnM6>iJB{c@<=DJUBg)+UR%O@f(B zAM1u=9CIIBQtvlwrhAgs0yf*XJ|Xeg82X|TdOq%hp2GnGh~q^sbUG?JJ>EeB^w4>U z00%!h6Ybiu!PK9zy>vEOg%#9R!zpP5>dkxiS*u$ygowqK$xp5DNGimtPr?W`up3AgQwcj^K>JM z^)%K{=cx4{^gNu!Q5E#yVnV>m4(FE9(SF&w5L3uy2&d7>}u#*6Q1rdFnl!QdHF;a`XhEYHWR*Eu4@5Lfg)DenN#gu_K}R+ahWlroQWz^#LP&Oo-u z`V+DXc@fq?gR};#;I-j57aTcR_Fx?XD}2q-aB9w_8%4kg0`6S%#5uXB9$UN!P~DzN zCnxOZ9=z|NK^%p#z7d43-QRAh+wE{QE}1cq*{3e#Gqz51fNm6lJR(5hgcHRwq=0?r za!a*d2DN*WS>g{q9K&%bhr{Ltjh2l)G;U=v+>1?wTE= z(vSQI%QCU*OoU{uoh~vs(18Vp)Q&zocWGf>#c9-z3;ooQphF^8L1|%ju9;~SH9XiS)u( zt|~PbVW=c0n4C$z*cXvwD*SR>iATD?-|nPkN8b%QdMd>Hvl>8 zeHNuFsW1G_mY)_vx=yFeDpfq62cE%Q8Qb^@I2-L6NyxAEMx+|OawsG0a2(wQQN0wl z%rzAOiDOW8I+M*$Tl6do6#)w5OapsPMzzifWhB!dAB2Ag7Qm46p;2N9WbEkOUAs-@ zLz_hG61|HqaFajJAsW_@Z0;5l@ zDK}TEg2YanI?MCDW3ni0#h@o)HxKwNY2A3b8qlE>ot{PIM8syQnC+$wCyg{fB};! zVLx(AxsjHP{e145p*1K11Ze4rK~u!caF-*0`|VwEtg>b`{N{Zz*%#?F>4*7E3~7v6 zh76&zA3GUP&8c*w2uvFROhTb@*S@3qU2)7^(ybnU1!duR0QheAM?PdyYe`h8vzFbQRl>b16Rxtw_N6%rZil=AW= zGUy6QHA2xU!Qdowdwy9D>6~FfpIcofE3rPhdbj8GcIe5bfB?-q2sM|}>O!&v*=87R zK{F6bDD&6jD}`jGn z>5Y)m*+(PTcsxN#BA@%(<1dvzx%_hyE~!K;I_>E?C>G33ESid-Lyo(~nI_v|(a!4- zz@jQd%vS{>f+L*tO@$rj37)mOak_1A4$)tFGC$^G_aCiqN5eaMdg4GtZ)d zSsR*91TegDu6f~NB$;`xPxe7dH_q<93Q5EV<;*v}-%L=MFe!MIYKRK|r;U#&;6B7mNXag&5ztO#hk z=Li9kIy1&GCOr)m<*pspLM=(C-l9@%rSoEsx;!M+t^%#giHX znR9~alJ~5vP&NCU+!ej(WCSRsC!u#QhsXODPpmUPGto>e+6TLN0|@E7( zPBXvK*+V7tymlT$_Jgdf2ioy`E3Y*xq?5VaZY*RGmnR>;&Q#0o2}q4AZNh>sZ}7_{ zO{E&9R!BEY>tYZvx+BamuUu6r%>lQxfYi&7zS!%taw|Oi;7=qTk7n|@>+^r`Zex#+ z2me*S%^d;uI7~cM2Fe{m>qwi#>FMh81JEGlOm8`1nhpszuASK;>b4BgoT8D@x})8 zQ#G_o^mgY`z}vSzf~bwVjHkQW)3cGoD2V5tm~dQV=qf&B#>WHqE9Otm+|x@ZZ8 z-Led-%XSQu*PdK0>yWcOJ50?QR9ztaqVNoFZ^=1gz<|3t?%Hx=mk0 z7#eoXCU&acBj~HA)rRGo6RTtor1TZ&zmc&nL+TGb@ISDpZ^+ow8Sqxz#U^r^*iuL= zH9Fca{r#=R8J5BiNuK+t;FBK+@(_n!d>z*6fJ`jm<3v-2LEgJ}J}*x_{%b7IfMh8s z{y>>rbnz!-)zN22Fj$5d)%e6LwfGRTX6SB@N4O%@eRp4LAfW2K8f&8OMl8^|)joOG ziV8`ahueOj+*js-0(xxE+>)i&o7fi!xO4@O82 zhvcttq%8qPmA2%ssAL$&ETRUPVl&w9|XZ%5Kx#0`)S0DPZ z)YY%dtdU-Pa+5{mSS$n+_+&CBJGVb08=k&N2C+EP$WWWCS$mP3u0+bU8Ed2$9hwXKIh)Pak;pmt1zid08xP2xW6g5aNTd8T8J1tf z%fy!~m&Kl>)OtqEo+<3j{h8-I1k=#TH9`5GZ9^undkF^A6tc&q({b6l<#Aba?0JT) z(pX}(m`IA_q$TXQrL$w3(6`|6M}8v1Lme0whsEXgNl({yjGgyMNBa)(`-2h=S4bdG zVsIi}EX9KvwG?UT=z1BGp9tE`wf&}7fR$@}+|}<{vSQ7@;7}#>!{BETIYX%PS##*W0rV``&|&90jpAAWK@6IY%)) zf2Z@kug0xi2w1YV%Mf`S{pN|-BKg{I zvwRgKeiZr`^1{h#xE(*9^2_zH3MoyOpsz(RiHuN=M>;N-S#51m$Sdd81?88!M`SVV z>HW~e1%ox{-@Ouzjme6Yry9F4pMix=P#h=S(7G`kb$F;tUU=?yx%2m5#u&KEm?M~X zq5>260G`wo%x!^S6(U`>%4@Ga2;t{x<9ieiS7Ll9Go)sOAKZt9jvHE-A@t3T2pv%M zd6uj^RweZ8Cq3)^ej@jqZyA=d@rAqOwwwP&_Uzh#&KpFhtd#LoOls3(g1Na_P-G0V z_obe3c)X5E(i1|Ab+zo>vjH9a_jq3kVqauBElJ(JM%HB))LXXC>kZ(cZjoRA;uCl{ zeaNyE!QeM;){_3f(vW=m_*z57eh@P=VLusbG=uB^i zTE}E1?CIU{F+*VcS~tSI2tc}V$TqIw*x|lN1SUs4GDeaYG;HF)oE?@(XV@O=JOX59TfH-KK?yD zdt~GDx5*v1ep&XmyZ~o6sN(!($Tl%5b>m~k_QsXLM)AB}wWdr?tnkVGy>ZxhLG0d? z48%soz-IbtS}ShNL`NS-eV z;$K%C6c5a4zweC6a*%oto_Qvn*}nB*DJyS~MT?FxQrN;GbcUeOPL3sG@o!)2D{}um z--WIGx8}Bx%;V8sS&WG~pZ6iW-qjS8)ukSJdMIfYxM}jF#D|1ZQH+huyq8Qyq4j)9 zp5JgY#@G@mDXGHbs2t-6or_cEdJ9it&yR!-8X=)Ow4ob9rwx7n7mHM_4r++JdpA1P zt#a3GUzOIqo6x~3#OE!M@x+icNCYGVvPUPSME+05mdiEk>*Q@%9gORDpHmx5X9(rO)^&2NEk3aS+ zq<4M7w4J^Mi!tDFsnq+WhsS^U`at z-Y<=dkCmF5rFh1Z3qpl#o^OyWZRP#_?eff1H^{wz_=XG)v>ELLiMbl)$8u=T_Q8}E zfWN^nቛ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

Iw`cPY_ozCrlIKG8yo#XoSbV&&wTQN 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 diff --git a/tests/testthat/helper-config.R b/tests/testthat/helper-config.R index d9af3ab9..9273c45d 100644 --- a/tests/testthat/helper-config.R +++ b/tests/testthat/helper-config.R @@ -3,6 +3,12 @@ library(golem) library(withr) old_usethis.quiet <- getOption("usethis.quiet") options("usethis.quiet" = TRUE) +# Small hack to prevent warning from rlang::lang() in tests +# This should be managed in {attempt} later on +x <- suppressWarnings({ + rlang::lang(print) +}) + ### Funs remove_file <- function(path) { if (file.exists(path)) unlink(path, force = TRUE) @@ -56,13 +62,16 @@ fakename <- sprintf( gsub("[ :-]", "", Sys.time()) ) + +## random dir +randir <- paste0(sample(safe_let(), 10, TRUE), collapse = "") + tpdir <- normalizePath(tempdir()) unlink(file.path(tpdir, fakename), recursive = TRUE) create_golem(file.path(tpdir, fakename), open = FALSE) pkg <- file.path(tpdir, fakename) -## random dir -randir <- paste0(sample(safe_let(), 10, TRUE), collapse = "") + fp <- file.path("inst/app", randir) dir.create(file.path(pkg, fp), recursive = TRUE) diff --git a/tests/testthat/test-add_deploy_helpers.R b/tests/testthat/test-add_deploy_helpers.R index 8aef7553..7057e65a 100644 --- a/tests/testthat/test-add_deploy_helpers.R +++ b/tests/testthat/test-add_deploy_helpers.R @@ -76,60 +76,8 @@ test_that("add_dockerfiles repos variation", { } }) }) -test_that("add_dockerfiles multi repos", { - skip_if_not_installed("dockerfiler", "0.1.4") - - repos <- c( - bioc1 = "https://bioconductor.org/packages/3.10/data/annotation", - bioc2 = "https://bioconductor.org/packages/3.10/data/experiment", - CRAN = "https://cran.rstudio.com" - ) - - - with_dir(pkg, { - for (fun in list( - add_dockerfile, - add_dockerfile_heroku, - add_dockerfile_shinyproxy - )) { - burn_after_reading( - "Dockerfile", - { - output <- testthat::capture_output( - fun( - pkg = pkg, - sysreqs = FALSE, - open = FALSE, - repos = repos, - output = "Dockerfile" - ) - ) - - expect_exists("Dockerfile") - - - test <- stringr::str_detect( - output, - "Dockerfile created at Dockerfile" - ) - expect_true(test) - to_find <- "RUN echo \"options(repos = c(bioc1 = 'https://bioconductor.org/packages/3.10/data/annotation', bioc2 = 'https://bioconductor.org/packages/3.10/data/experiment', CRAN = 'https://cran.rstudio.com'), download.file.method = 'libcurl', Ncpus = 4)\" >> /usr/local/lib/R/etc/Rprofile.site" - # for R <= 3.4 - to_find_old <- "RUN echo \"options(repos = structure(c('https://bioconductor.org/packages/3.10/data/annotation', 'https://bioconductor.org/packages/3.10/data/experiment', 'https://cran.rstudio.com'), .Names = c('bioc1', 'bioc2', 'CRAN')), download.file.method = 'libcurl', Ncpus = 4)\" >> /usr/local/lib/R/etc/Rprofile.site" - - expect_true( - sum( - readLines(con = "Dockerfile") %in% c(to_find, to_find_old) - ) == 1 - ) - } - ) - } - }) -}) - test_that("add_rstudio_files", { with_dir(pkg, { for (fun in list( diff --git a/tests/testthat/test-renv_stuff.R b/tests/testthat/test-renv_stuff.R new file mode 100644 index 00000000..43d74c15 --- /dev/null +++ b/tests/testthat/test-renv_stuff.R @@ -0,0 +1,33 @@ +test_that("add_dockerfiles_renv and add_dockerfile_with_renv_shinyproxy all output file are present", { + skip_if_not_installed("dockerfiler", "0.2.0") + + with_dir(pkg, { + for (fun in list( + add_dockerfile_with_renv, + add_dockerfile_with_renv_shinyproxy, + add_dockerfile_with_renv_heroku + )) { + deploy_folder <- file.path( + tempdir(), + make.names( + paste0( + "deploy", + round( + runif(1, min = 0, max = 99999) + ) + ) + ) + ) + + fun(output_dir = deploy_folder, open = FALSE) + + expect_exists(file.path(deploy_folder, "Dockerfile")) + expect_exists(file.path(deploy_folder, "Dockerfile_base")) + expect_exists(file.path(deploy_folder, "README")) + expect_exists(file.path(deploy_folder, "renv.lock.prod")) + + expect_length(list.files(path = deploy_folder, pattern = "tar.gz$"), 1) + unlink(deploy_folder, force = TRUE, recursive = TRUE) + } + }) +}) diff --git a/vignettes/a_start.Rmd b/vignettes/a_start.Rmd index 002671ec..3d93116e 100644 --- a/vignettes/a_start.Rmd +++ b/vignettes/a_start.Rmd @@ -122,7 +122,7 @@ golem::fill_desc( ) ``` -About [the DESCRIPTION file](https://r-pkgs.org/description.html). +About [the DESCRIPTION file](https://r-pkgs.org/Metadata.html#sec-description). ### Add `{golem}` options @@ -155,7 +155,7 @@ Create a template for tests: golem::use_recommended_tests() ``` -About [tests in a package](https://r-pkgs.org/tests.html). +About [tests in a package](https://r-pkgs.org/testing-basics.html). ### Use Recommended Packages diff --git a/vignettes/b_dev.Rmd b/vignettes/b_dev.Rmd index aaa3dd82..052bbf95 100644 --- a/vignettes/b_dev.Rmd +++ b/vignettes/b_dev.Rmd @@ -45,7 +45,7 @@ Note that the `{attachment}` package should be installed on your machine. attachment::att_amend_desc() ``` -About [package dependencies](https://r-pkgs.org/namespace.html). +About [package dependencies](https://r-pkgs.org/Metadata.html#sec-namespace). ### Add modules @@ -139,7 +139,7 @@ Add more tests to your application: usethis::use_test("app") ``` -About [testing a package](https://r-pkgs.org/tests.html). +About [testing a package](https://r-pkgs.org/testing-basics.html). ## Documentation diff --git a/vignettes/c_deploy.Rmd b/vignettes/c_deploy.Rmd index 4021cd03..cf434e2f 100644 --- a/vignettes/c_deploy.Rmd +++ b/vignettes/c_deploy.Rmd @@ -69,6 +69,10 @@ golem::add_shinyserver_file() ### Docker +#### without using {renv} + + + ```{r} # If you want to deploy via a generic Dockerfile golem::add_dockerfile() @@ -80,3 +84,75 @@ golem::add_dockerfile_shinyproxy() golem::add_dockerfile_heroku() ``` +#### using {renv} + + +#### CASE 1 : you didn't use renv during developpment process + + +> this functions will create a "deploy" folder containing : + +```{txt} +deploy/ ++-- Dockerfile ++-- Dockerfile_base ++-- yourgolem_0.0.0.9000.tar.gz ++-- README +\-- renv.lock.prod +``` + +then follow the README file + + +```{r} +# If you want to deploy via a generic Dockerfile +golem::add_dockerfile_with_renv(output_dir = "deploy") + +# If you want to deploy to ShinyProxy +golem::add_dockerfile_with_renv_shinyproxy(output_dir = "deploy") + +``` + +If you would like to use {renv} during developpement, you can init a renv.lock file with + +```{r} +attachment::create_renv_for_dev(dev_pkg = c("renv", "devtools", "roxygen2", + "usethis", "pkgload", "testthat", "remotes", "covr", "attachment", + "pak", "dockerfiler","golem")) +``` +an activate {renv} with + +```{r} +renv::activate() +``` + + + + + +#### CASE 2 : you already have a renv.lock file for your project + + +```{r} + +# If you want to deploy via a generic Dockerfile +golem::add_dockerfile_with_renv(output_dir = "deploy",lockfile = "renv.lock") + +# If you want to deploy to ShinyProxy +golem::add_dockerfile_with_renv_shinyproxy(output_dir = "deploy",lockfile = "renv.lock") + + +``` + +> this functions will create a "deploy" folder containing : + +```{txt} +deploy/ ++-- Dockerfile ++-- Dockerfile_base ++-- yourgolem_0.0.0.9000.tar.gz ++-- README +\-- renv.lock.prod +``` + +then follow the README file \ No newline at end of file