rdbnomics/0000755000176200001440000000000013616610265012240 5ustar liggesusersrdbnomics/NAMESPACE0000644000176200001440000000031413616554211013453 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(dbnomics) export(rdb) export(rdb_by_api_link) export(rdb_last_updates) export(rdb_providers) import(curl) import(data.table) import(jsonlite) rdbnomics/README.md0000644000176200001440000003436613604427673013541 0ustar liggesusers# rdbnomics [![CRAN\_Status\_Badge](http://www.r-pkg.org/badges/version/rdbnomics)](https://cran.r-project.org/package=rdbnomics) [![pipeline status](https://git.nomics.world/dbnomics/rdbnomics/badges/master/pipeline.svg)](https://git.nomics.world/dbnomics/rdbnomics/commits/master) [![status](https://tinyverse.netlify.com/badge/rdbnomics)](https://CRAN.R-project.org/package=rdbnomics) ## DBnomics R client This package provides you access to DBnomics data series. DBnomics is an open-source project with the goal of aggregating the world's economic data in one location, free of charge to the public. DBnomics covers hundreds of millions of series from international and national institutions (Eurostat, World Bank, IMF, ...). To use this package, you have to provide the codes of the provider, dataset and series you want. You can retrieve them directly on the website. You have access to the API through this link and the documentation is here. DBnomics is hosted on its own gitlab platform. However, in order to install the package more easily, we created a mirror of this package on github. To install `rdbnomics` from CRAN: ```r install.packages("rdbnomics") library(rdbnomics) ``` To install `rdbnomics` from github: ```r remotes::install_github("dbnomics/rdbnomics", build_vignettes = TRUE, force = TRUE) library(rdbnomics) ``` After installation, a vignette is available to the user: ```r vignette("rdbnomics") ``` ## Examples ### Fetch time series by `ids`: ```r # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") # Fetch two series from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df2 <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) # Fetch two series from different datasets of different providers: df3 <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "IMF/BOP/A.FR.BCA_BP6_EUR")) ``` In the event that you only use the argument `ids`, you can drop it and run: ```r df <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` ### Fetch time series by `mask` : ```r # Fetch one series from dataset 'Balance of Payments' (BOP) of IMF: df1 <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") # Fetch two series from dataset 'Balance of Payments' (BOP) of IMF: df2 <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") # Fetch all series along one dimension from dataset 'Balance of Payments' (BOP) of IMF: df3 <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") # Fetch series along multiple dimensions from dataset 'Balance of Payments' (BOP) of IMF: df4 <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") ``` In the event that you only use the arguments `provider_code`, `dataset_code` and `mask`, you can drop the name `mask` and run: ```r df4 <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR") ``` ### Fetch time series by `dimensions`: ```r # Fetch one value of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df1 <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea12")) # or df1 <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea12"]}') # Fetch two values of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df2 <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea12", "dnk"))) # or df2 <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea12", "dnk"]}') # Fetch several values of several dimensions from dataset 'Doing business' (DB) of World Bank: df3 <- rdb("WB", "DB", dimensions = list(country = c("DZ", "PE"), indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"))) # or df3 <- rdb("WB", "DB", dimensions = '{"country": ["DZ", "PE"], "indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}') ``` ### Fetch time series with a `query`: ```r # Fetch one series from dataset 'WEO by countries' (WEO) of IMF provider: df1 <- rdb("IMF", "WEO", query = "France current account balance percent") # Fetch series from dataset 'WEO by countries' (WEO) of IMF provider: df2 <- rdb("IMF", "WEO", query = "current account balance percent") ``` ### Fetch one series from the dataset 'Doing Business' of WB provider with the link: ```r df1 <- rdb(api_link = "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") ``` In the event that you only use the argument `api_link`, you can drop the name and run: ```r df1 <- rdb("https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") ``` ## Proxy configuration or connection error `Could not resolve host` When using the function `rdb`, you may come across the following error: ```r Error in open.connection(con, "rb") : Could not resolve host: api.db.nomics.world ``` To get round this situation, you have two possibilities: 1. configure **curl** to use a specific and authorized proxy. 2. use the default R internet connection i.e. the Internet Explorer proxy defined in *internet2.dll*. ### Configure **curl** to use a specific and authorized proxy In **rdbnomics**, by default the function `curl_fetch_memory` (of the package **curl**) is used to fetch the data. If a specific proxy must be used, it is possible to define it permanently with the package option `rdbnomics.curl_config` or on the fly through the argument `curl_config`. Because the object is a named list, its elements are passed to the connection (the `curl_handle` object created internally with `new_handle()`) with `handle_setopt()` before using `curl_fetch_memory`. To see the available parameters, run `names(curl_options())` in *R* or visit the website https://curl.haxx.se/libcurl/c/curl_easy_setopt.html. Once they are chosen, you define the curl object as follows: ```r h <- list( proxy = "", proxyport = , proxyusername = "", proxypassword = "" ) ``` #### Set the connection up for a session The curl connection can be set up for a session by modifying the following package option: ```r options(rdbnomics.curl_config = h) ``` When fetching the data, the following command is executed: ```r hndl <- curl::new_handle() curl::handle_setopt(hndl, .list = getOption("rdbnomics.curl_config")) curl::curl_fetch_memory(url = <...>, handle = hndl) ``` After configuration, just use the standard functions of **rdbnomics** e.g.: ```r df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` This option of the package can be disabled with: ```r options(rdbnomics.curl = NULL) ``` #### Use the connection only for a function call If a complete configuration is not needed but just an "on the fly" execution, then use the argument `curl_config` of the function `rdb`: ```r df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h) ``` ### Use the default R internet connection To retrieve the data with the default R internet connection, **rdbnomics** will use the base function `readLines`. #### Set the connection up for a session To activate this feature for a session, you need to enable an option of the package: ```r options(rdbnomics.use_readLines = TRUE) ``` And then use the standard function as follows: ```r df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` This configuration can be disabled with: ```r options(rdbnomics.use_readLines = FALSE) ``` #### Use the connection only for a function call If you just want to do it once, you may use the argument `use_readLines` of the function `rdb`: ```r df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE) ``` ## Transform time series with filters The **rdbnomics** package can interact with the *Time Series Editor* of DBnomics to transform time series by applying filters to them. Available filters are listed on the filters page [https://editor.nomics.world/filters](https://editor.nomics.world/filters). Here is an example of how to proceed to interpolate two annual time series with a monthly frequency, using a spline interpolation: ```r filters <- list( code = "interpolate", parameters = list(frequency = "monthly", method = "spline") ) df <- rdb( ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), filters = filters ) ``` If you want to apply more than one filter, the `filters` argument will be a list of valid filters: ```r filters <- list( list( code = "interpolate", parameters = list(frequency = "monthly", method = "spline") ), list( code = "aggregate", parameters = list(frequency = "bi-annual", method = "end_of_period") ) ) df <- rdb( ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), filters = filters ) ``` The `data.table` columns change a little bit when filters are used. There are two new columns: - `period_middle_day`: the middle day of `original_period` (can be useful when you compare graphically interpolated series and original ones). - `filtered` (boolean): `TRUE` if the series is filtered, `FALSE` otherwise. The content of two columns are modified: - `series_code`: same as before for original series, but the suffix `_filtered` is added for filtered series. - `series_name`: same as before for original series, but the suffix ` (filtered)` is added for filtered series. ## Transform the `data.table` object into a `xts` object For some analysis, it is more convenient to have a `xts` object instead of a `data.table` object. To transform it, you can use the following functions: ```r library(xts) library(data.table) library(rdbnomics) to_xts <- function( x, needed_columns = c("period", "series_code", "series_name", "value"), series_columns = c("series_code", "series_name") ) { if (is.null(x)) { return(NULL) } all_cols <- length(setdiff(needed_columns, colnames(x))) != 0 if (all_cols) { stop( paste0( "To export as a xts object, some columns are missing. Needed columns ", "are \u0022", paste0(needed_columns, collapse = "\u0022, \u0022"), "\u0022" ), call. = FALSE ) } x <- x[, .SD, .SDcols = needed_columns] data.table::setcolorder(x, needed_columns) attr_names <- NULL if (!is.null(series_columns)) { attr_names <- unique(x[, .SD, .SDcols = series_columns]) } if (nrow(x) > 0) { x <- data.table::dcast.data.table( x, period ~ series_code, value.var = "value" ) } else { orig <- Sys.Date() - as.numeric(Sys.Date()) x <- data.table( period = as.Date(numeric(), origin = orig), no_code = numeric() ) } x <- data.table::as.xts.data.table(x) xts::xtsAttributes(x) <- list(codename = attr_names) x } rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") #> ... original_value period provider_code REF_AREA Reference Area series_code ... #> 1: NA 1940-01-01 IMF ES Spain A.ES.BCA_BP6_EUR #> 2: NA 1941-01-01 IMF ES Spain A.ES.BCA_BP6_EUR #> --- ... ... ... ... ... ... #> 159: -15136.8 2018-01-01 IMF FR France A.FR.BCA_BP6_EUR #> 160: NA 2019-01-01 IMF FR France A.FR.BCA_BP6_EUR to_xts(rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR")) #> A.ES.BCA_BP6_EUR A.FR.BCA_BP6_EUR #> 1940-01-01 NA NA #> 1941-01-01 NA NA #> 1942-01-01 NA NA #> ... ... ... #> 2017-01-01 31086 -16397.700 #> 2018-01-01 23283 -15136.800 #> 2019-01-01 NA NA ``` In the `xts` object, the series codes are used as column names. If you prefer the series names (or apply a function to them), you can utilize the function: ```r library(magrittr) rdb_rename_xts <- function(x, fun = NULL, ...) { nm <- xts::xtsAttributes(x)$codename cols <- nm$series_name[match(names(x), nm$series_code)] if (is.null(fun)) { names(x) <- cols } else { names(x) <- sapply(X = cols, FUN = fun, ..., USE.NAMES = FALSE) } x } rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") %>% to_xts() %>% rdb_rename_xts() #> Annual – Spain – Current Account, Total, Net, Euros Annual – France – Current Account, Total, Net, Euros #> 1940-01-01 NA NA #> 1941-01-01 NA NA #> 1942-01-01 NA NA #> ... ... ... #> 2017-01-01 31086 -16397.700 #> 2018-01-01 23283 -15136.800 #> 2019-01-01 NA NA rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") %>% to_xts() %>% rdb_rename_xts(stringr::word, start = 3) #> Spain France #> 1940-01-01 NA NA #> 1941-01-01 NA NA #> 1942-01-01 NA NA #> ... ... ... #> 2017-01-01 31086 -16397.700 #> 2018-01-01 23283 -15136.800 #> 2019-01-01 NA NA ``` ## P.S. Visit https://db.nomics.world/ ! rdbnomics/man/0000755000176200001440000000000013616545645013024 5ustar liggesusersrdbnomics/man/rdbnomics.Rd0000644000176200001440000000035213616554211015260 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rdbnomics.R \docType{package} \name{rdbnomics} \alias{rdbnomics} \title{Package rdbnomics} \description{ DBnomics R client (). } rdbnomics/man/rdb_by_api_link.Rd0000644000176200001440000001203313604436273016412 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rdb_by_api_link.R \name{rdb_by_api_link} \alias{rdb_by_api_link} \title{Download DBnomics data using API link (deprecated).} \usage{ rdb_by_api_link( api_link, use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config"), filters = getOption("rdbnomics.filters") ) } \arguments{ \item{api_link}{Character string. DBnomics API link of the search.} \item{use_readLines}{Logical (default \code{FALSE}). If \code{TRUE}, then the data are requested and read with the base function \code{readLines} i.e. through the default R internet connection. This can be used to get round the error \code{Could not resolve host: api.db.nomics.world}.} \item{curl_config}{Named list (default \code{NULL}). If not \code{NULL}, it is used to configure a proxy connection. This configuration is passed to the function \code{curl_fetch_memory} of the package \pkg{curl}. A temporary \code{curl_handle} object is created internally with arguments equal to the provided list in \code{curl_config}.\cr For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. For available curl options see \code{\link[curl]{curl_options}}, \code{names(curl_options())} and \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}.} \item{filters}{List (default \code{NULL}). This argument must be a named list for one filter because the function \code{toJSON} of the package \pkg{jsonlite} is used before sending the request to the server. For multiple filters, you have to provide a list of valid filters (see examples).\cr A valid filter is a named list with an element \code{code} which is a character string, and an element \code{parameters} which is a named list with elements \code{frequency} and \code{method} or a NULL.} } \value{ A \code{data.table}. } \description{ \code{rdb_by_api_link} downloads data series from \href{https://db.nomics.world/}{DBnomics}. } \details{ This function gives you access to hundreds of millions data series from \href{https://api.db.nomics.world/}{DBnomics API} (documentation about the API can be found \href{https://api.db.nomics.world/v22/apidocs}{here}). The API link is given on the \href{https://db.nomics.world/}{DBnomics website}. } \examples{ \dontrun{ # Fetch two series from different datasets of different providers : df1 <- rdb_by_api_link( paste0( "https://api.db.nomics.world/v22/", "series?observations=1&series_ids=AMECO/ZUTN/EA19.1.0.0.0.ZUTN,IMF/CPI/A.AT.PCPIT_IX" ) ) # Fetch one series from the dataset 'Doing Business' of WB provider : df2 <- rdb_by_api_link( paste0( "https://api.db.nomics.world/v22/series/WB/DB?dimensions=\%7B\%22", "indicator\%22\%3A\%5B\%22IC.REG.PROC.FE.NO\%22\%5D\%7D&q=Doing\%20Business", "&observations=1&format=json&align_periods=1&offset=0&facets=0" ) ) ## Use a specific proxy to fetch the data # Fetch one series from the dataset 'Doing Business' of WB provider : h <- list( proxy = "", proxyport = , proxyusername = "", proxypassword = "" ) options(rdbnomics.curl_config = h) df2 <- rdb_by_api_link( paste0( "https://api.db.nomics.world/v22/series/WB/DB?dimensions=\%7B\%22", "indicator\%22\%3A\%5B\%22IC.REG.PROC.FE.NO\%22\%5D\%7D&q=Doing\%20Business", "&observations=1&format=json&align_periods=1&offset=0&facets=0" ) ) # or to use once df2 <- rdb_by_api_link( paste0( "https://api.db.nomics.world/v22/series/WB/DB?dimensions=\%7B\%22", "indicator\%22\%3A\%5B\%22IC.REG.PROC.FE.NO\%22\%5D\%7D&q=Doing\%20Business", "&observations=1&format=json&align_periods=1&offset=0&facets=0" ), curl_config = h ) ## Use R default connection to avoid a proxy failure (in some cases) # Fetch one series from the dataset 'Doing Business' of WB provider : options(rdbnomics.use_readLines = TRUE) df2 <- rdb_by_api_link( paste0( "https://api.db.nomics.world/v22/series/WB/DB?dimensions=\%7B\%22", "indicator\%22\%3A\%5B\%22IC.REG.PROC.FE.NO\%22\%5D\%7D&q=Doing\%20Business", "&observations=1&format=json&align_periods=1&offset=0&facets=0" ) ) # or to use once df2 <- rdb_by_api_link( paste0( "https://api.db.nomics.world/v22/series/WB/DB?dimensions=\%7B\%22", "indicator\%22\%3A\%5B\%22IC.REG.PROC.FE.NO\%22\%5D\%7D&q=Doing\%20Business", "&observations=1&format=json&align_periods=1&offset=0&facets=0" ), use_readLines = TRUE ) ## Apply filter(s) to the series # One filter df3 <- rdb_by_api_link( "https://api.db.nomics.world/v22/series/IMF/WEO/ABW.BCA?observations=1", filters = list( code = "interpolate", parameters = list(frequency = "daily", method = "spline") ) ) # Two filters df3 <- rdb_by_api_link( "https://api.db.nomics.world/v22/series/IMF/WEO/ABW.BCA?observations=1", filters = list( list( code = "interpolate", parameters = list(frequency = "quarterly", method = "spline") ), list( code = "aggregate", parameters = list(frequency = "annual", method = "average") ) ) ) } } \seealso{ \code{\link{rdb}} } \author{ Sebastien Galais } rdbnomics/man/rdb.Rd0000644000176200001440000002106013604436273014052 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rdb.R \name{rdb} \alias{rdb} \title{Download DBnomics data.} \usage{ rdb( provider_code = NULL, dataset_code = NULL, ids = NULL, dimensions = NULL, mask = NULL, query = NULL, api_link = NULL, filters = getOption("rdbnomics.filters"), use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config"), verbose = getOption("rdbnomics.verbose_warning"), ... ) } \arguments{ \item{provider_code}{Character string (default \code{NULL}). DBnomics code of the provider.} \item{dataset_code}{Character string (default \code{NULL}). DBnomics code of the dataset.} \item{ids}{Character string (default \code{NULL}). DBnomics code of one or several series.} \item{dimensions}{List or character string (single quoted) (default \code{NULL}). DBnomics code of one or several dimensions in the specified provider and dataset. If it is a named list, then the function \code{toJSON} (from the package \pkg{jsonlite}) is applied to generate the json object.} \item{mask}{Character string (default \code{NULL}). DBnomics code of one or several masks in the specified provider and dataset.} \item{query}{Character string (default \code{NULL}). A query to filter/select series from a provider's dataset.} \item{api_link}{Character string. DBnomics API link of the search. It should starts with \code{http://} or \code{https://}.} \item{filters}{List (default \code{NULL}). This argument must be a named list for one filter because the function \code{toJSON} of the package \pkg{jsonlite} is used before sending the request to the server. For multiple filters, you have to provide a list of valid filters (see examples).\cr A valid filter is a named list with an element \code{code} which is a character string, and an element \code{parameters} which is a named list with elements \code{frequency} and \code{method} or a NULL.} \item{use_readLines}{Logical (default \code{FALSE}). If \code{TRUE}, then the data are requested and read with the base function \code{readLines} i.e. through the default R internet connection. This can be used to get round the error \code{Could not resolve host: api.db.nomics.world}.} \item{curl_config}{Named list (default \code{NULL}). If not \code{NULL}, it is used to configure a proxy connection. This configuration is passed to the function \code{curl_fetch_memory} of the package \pkg{curl}. A temporary \code{curl_handle} object is created internally with arguments equal to the provided list in \code{curl_config}.\cr For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. For available curl options see \code{\link[curl]{curl_options}}, \code{names(curl_options())} and \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}.} \item{verbose}{Logical (default \code{FALSE}). Show warnings of the function.} \item{...}{Arguments to be passed to the internal function \code{.rdb}.} } \value{ A \code{data.table}. } \description{ \code{rdb} downloads data series from \href{https://db.nomics.world/}{DBnomics} using shortcuts like \code{ids}, \code{dimensions}, \code{mask}, \code{query} or using an \code{api_link}. } \details{ This function gives you access to hundreds of millions data series from \href{https://api.db.nomics.world/}{DBnomics API} (documentation about the API can be found \href{https://api.db.nomics.world/v22/apidocs}{here}). The code of each series is given on the \href{https://db.nomics.world/}{DBnomics website}. \cr\cr In the event that only the argument \code{ids} is provided (and those in the ellipsis \code{...}), the argument name can be dropped. The character string vector is directly passed to \code{ids}. \cr If only the argument \code{api_link} is provided (and those in the ellipsis \code{...}), then the argument name can be dropped. The character string vector is directly passed to \code{api_link}. \cr In the same way, if only \code{provider_code}, \code{dataset_code} and \code{mask} are provided then the arguments names can be dropped. The last character string is automatically passed to \code{mask}. } \examples{ \dontrun{ ## By ids # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") # or when no argument names are given (provider_code -> ids) df1 <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN") # Fetch two series from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df2 <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) # Fetch two series from different datasets of different providers: df3 <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "IMF/BOP/A.FR.BCA_BP6_EUR")) ## By dimensions # Fetch one value of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df1 <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea12")) # or df1 <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea12"]}') # Fetch two values of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider: df2 <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea12", "dnk"))) # or df2 <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea12", "dnk"]}') # Fetch several values of several dimensions from dataset 'Doing business' (DB) of World Bank: dim <- list( country = c("DZ", "PE"), indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS") ) df3 <- rdb("WB", "DB", dimensions = dim) # or dim <- paste0( '{"country": ["DZ", "PE"],', '"indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}' ) df3 <- rdb("WB", "DB", dimensions = dim) ## By mask # Fetch one series from dataset 'Balance of Payments' (BOP) of IMF: df1 <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") # or when no argument names are given except provider_code and dataset_code (ids -> mask) df1 <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR") # Fetch two series from dataset 'Balance of Payments' (BOP) of IMF: df2 <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") # Fetch all series along one dimension from dataset 'Balance of Payments' (BOP) of IMF: df3 <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") # Fetch series along multiple dimensions from dataset 'Balance of Payments' (BOP) of IMF: df4 <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") ## By query # Fetch one series from dataset 'WEO by countries' (WEO) from IMF : df1 <- rdb("IMF", "WEO", query = "France current account balance percent") # Fetch series from dataset 'WEO by countries' (WEO) from IMF : df2 <- rdb("IMF", "WEO", query = "current account balance percent") ## By api_link # Fetch two series from different datasets of different providers : df1 <- rdb( api_link = paste0( "https://api.db.nomics.world/v22/", "series?observations=1&series_ids=AMECO/ZUTN/EA19.1.0.0.0.ZUTN,IMF/CPI/A.AT.PCPIT_IX" ) ) # Fetch one series from the dataset 'Doing Business' of WB provider : df2 <- rdb( api_link = paste0( "https://api.db.nomics.world/v22/series/WB/DB?dimensions=\%7B\%22", "indicator\%22\%3A\%5B\%22IC.REG.PROC.FE.NO\%22\%5D\%7D&q=Doing\%20Business", "&observations=1&format=json&align_periods=1&offset=0&facets=0" ) ) # or when no argument names are given (provider_code -> api_link) df1 <- rdb( paste0( "https://api.db.nomics.world/v22/", "series?observations=1&series_ids=AMECO/ZUTN/EA19.1.0.0.0.ZUTN,IMF/CPI/A.AT.PCPIT_IX" ) ) ## Use a specific proxy to fetch the data # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider : h <- list( proxy = "", proxyport = , proxyusername = "", proxypassword = "" ) options(rdbnomics.curl_config = h) df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") # or to use once options(rdbnomics.curl_config = NULL) df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h) ## Use R default connection to avoid a proxy failure (in some cases) # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider : options(rdbnomics.use_readLines = TRUE) df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") # or to use once df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE) ## Apply filter(s) to the series # One filter df1 <- rdb( ids = c("IMF/WEO/ABW.BCA", "IMF/WEO/ABW.BCA_NGDPD"), filters = list( code = "interpolate", parameters = list(frequency = "daily", method = "spline") ) ) # Two filters df1 <- rdb( ids = c("IMF/WEO/ABW.BCA", "IMF/WEO/ABW.BCA_NGDPD"), filters = list( list( code = "interpolate", parameters = list(frequency = "quarterly", method = "spline") ), list( code = "aggregate", parameters = list(frequency = "annual", method = "average") ) ) ) } } \author{ Sebastien Galais } rdbnomics/man/figures/0000755000176200001440000000000013616545645014470 5ustar liggesusersrdbnomics/man/figures/logo.png0000644000176200001440000007544013371134545016137 0ustar liggesusersPNG  IHDRsRGBgAMA a pHYs&?zIDATx^kՙ?/&fb3q]TA\;(A@䦀"((" (>\џcTbjRIa̔5J%T*Ij|_uڬ{g_ߪOW^g=W*zlLSs[G?3Rt̔w:ɜ^ |?DU;RZRI8cesb+3&@J`\Xλʜ6]eZL3SA칀IB:'yl*1!iZ&݈W|Zr?UZʔ ZMIjt̻|e! jșt"E4l2h9cWzWz%pCL.ؗ$=\DΜ-5 fF-VŶA_ A#<06&;&=G'˜FcHLpCmͦdl{͘ņ hkٿA3g3}vۘ=c,6lG͜?mLvM\0BFo^Sf X3g~ K`+27|<ɚ7n Fn;[NϻvlدM=}e`Ǘ_fG :ͶH9kq帿fQw'D?306t=ImÎ~'?o2J%|) MzxFΜ2վ"e^af^ikmC3qJVLeZI&jeWpi-`Lң=XpeZȤUfy?%#œ=70I^\3{)ISLTJTg*$3ysqf=s;qt§#g&S iNS]8]dpDƥC2TJTҸ3IH^IDƵIR|0W`WlD{x"V&݃kFܑ3I2Llxxsb$N ڝҁ3W0s 3W0sJ̹ap'}G2W.3v7|hg_Ȇueۃ[s6-g後t촗M{߭!7= n65˰3FPi,m~bqDܦd ˜ *茀`q_hlŕX ٗa^66`=+%3g_zȿazyI7ޡ_`or cm8so_Wxmm&d 79Glx3z:7m{mNG_7G<һ Ww7J,(Ǟ{YV!j;¬ڼu\+͝+XRfr""=*&{f 6]&)~h#NTMl:I^2r#N&Mrґ{")!I`o,K!gr0tIy qI`Օ/lVBg*(7ARwwsj+SAIp3Qզ2^'PiAx-pg*(7nO2<;1A_n&&.ljQn/ NuU*u:yc9Bh@bH{5 oKǩ+_Ԣѕi]*H@:7^4ɣ\I7w&T.`|rHWKHiLҔA]ʓnh e wƥwe)ږx eR9bxx\p+eTFX;cugRBDBxt5'v #ѹv} 2gVc"EẂrN@ǭS-$EJǭS-$EJǭS-$EJǭS-$EJǭS-$EJǭS-$EJǭS-$EJǭS-$EJǭS-$EJǭS-$EZ.R\v w[=EYܣR:0RZAR"U6nj)-`]~A"]k"Upº۰ n}nwݰkqx-V~7<ea܃BRa+"Hqr%.p> ߐ-ASgv_1`ceL{P0BΖC%Enj)-`Tqvw2Hq2|X=%ZºJ܊VnYj)-`:u`܃HIu`܃HIu`܃lDv oKw_ <2 O;FM R8M˳6ۣցrB$Hm/a,Y^g̛y_I7|WU3ћ_Suc]I}|<_knk`_٠?|}ZCW:/{uX,ȇæo2Zǂ~z{}y~ąJM.}=<,iūv|Q]6g?L{# ;?{Co ?whI7omFbIO`z L=r[x'2}=#VK }>|T}Uz߬]Q(8=Sfd07_rg])s_X!{y$E8r1$:RPNGCRϸv9w)'}$1HͿI R ZZbm-qe{ucVoI;|# j;-BF&L@x-^c`_؋'N{l5Sd`B L)W.[I~"[L򨨒 xTS0 ~`NO%JV5,cw*Jqp1*J >]!|]`:J(UNE739oLQT:p;bɭ,,mP"U)IϺBTR/~s8UmI9׀OMTTڊ3EB:%]mVrLR<uSQIH*O=!VJTTATR&D\:G?NCo S*$XC&=dD m/ͼM/QAI,pFJ 0ITW;¬6RZZ2Io>SX n(wxAѳ&+!0C*ZmԸ2 BUQ&].eT*zAʏ^U̝-D%,ey;xA^)ڗHʀFCwM?:|ֻXJU 3ب%jnʹuj&XZP&SLup7\JfO%22EX=FH 7NÑ L+3׶-HsYegc7Y 'H#YcXK]oN %T} [ibHH嬌?MUDIGLty`\Ac9*S-:J{|s2VZrҲj).VZSq!IVZJCJL+㩸e[=JCʪRVZǓ\vpj+ b$}XiuH֓:43VT\i)zC+춡s&q=)lEVo=N+mpj[feWYظXiŁ2Kl`~pǭ 0щa6f ㆳ@a-(| O@?(&(.wn 0TڲVȸݭ_~7n+w v|wYJHOumh ]pE`˽~Ȑ|%\ֳ_}6.7>ܰu?Ea¶J@^=vÈRimQ*9v=n1(Űআ-WU^:n+ _slQli@ˮ Vl\n|冗iJ+EAJ bns+{י * %x?f+~qU}}{ H+wq%]iQ}ZcvpURi_~7sBJ0vko׿vυ2Ec~֞UY*nMYx> , G}r7Q F—So>ڂ4VdyT>g((lCcʍ[Osv;L~-maT.v=_Tڷo"G迯n_r.qΫō{ɝ>q{g־*‚tXT1*uH]n'q KaC-;Gj9yCu՛Z9*o*mE̹u]m (}RP 6;*^{C1s~rmA.ye޷vNQ7v(?=#ϼةnXܬe+bσswy

&锪 $h˅R:T~gJ%X u˾ʒ>LҨb]0X.][m($*% ӭr'?+XV5I*T-0gc9%Bƻ\"$҂v1r89T 8]v0W:LT䲟IVE K UmIPY~Cg:Ra=njEVoTYX:jUf+lќ76F|l(* GBeܐ(*M AYo(WN]Oީ~qH 5#=' _4r!4|=uzgL(̵+DC[tad|jAG?qd$iV1u$՘ .0EL5 KDbw90\ưY*/ ̔1EO5ps#DR.4 XI*G]xerCreOW͍ZkZaE;%"2iHRJCI![WjTx*UZ+5Rrr9T5Rc~+9$U: V7 ,d+FױĊ%MTi"Tc%ƤӭOMӡ %:'+Vi>ʙ<:Mk.)wP* ,*4!.Nƻ960?NM k%(!Q)sNTSX:_X!i}KP\QK.)zB,B0-Oj"jӼ;VGr^w1Ajr&O9/柾?n'eդ R;yZĘEN$g!RF7%$#`m_$)5yژI2NP 4c&H:_DH"0fH!0fH!AKߐNBc#͆dU1+ "QFH Hv@c#$$;P3IFIhlِ*ƆWҨHv@c#$$;HN.NBc#͆dؒ{;sƻT: 4ۍW{d Bbl\u4$jla_失fCL.ޘJ|)S: 4dZeTFHTخ?DL!dMelRڤpCL.@ G7ZGjk[7I: ˢUi.zF_Hm aL%hl! V'I}}u8ch$9gQ&c Up}͞`R>kst{>>hL9`qY![#?텶tKA8ւBJEj5kl~?liD#jڤc7fKb ytE:+4`Cw uuH+QOVx\\UcoqÄJ c-N"%(x^D2pˈڅgis ^<m~0Jm\7*]]C¹X헌5bz:<<=ر$AzS$ ~tb1\z5m}a-_X)~b%Upm@Pp_)p~>,AJ5r+ɘ.P7A $jҌ*VAewb\V8VJys=!`%wC1Cj 46!\[ÊZݞ\R޾*ƆYIp;i#p.#ۋa48 𩖍goT Z1X.ERc*U-cAqFM[0N{,2oZS ga%U{{O_G^A\Cdhh*vӨ t6T40-aN"%FFH)c ԣ۶dz]znڍ-'or}A;7TY?ea?% C=_o/w?i/Jv`$E19rL{°>*1/߰ߴ瀿iA0sۖ:Gg>ȿsj87ޡ}eam;MCe>?x?r=hlyظ{`ו x`w<,0'^|Ea}ksu[>ߛ*K_}=o=x~^ϱoSog4*OK˗:uP*7B;*[37=y!]&5POzg_>eI_ _s_XRu<~S;c,}~۪gfu ?uC R߼PDZ.6sΟ1Ǎvw\ &P;z{8̐i\uUO_- .U1LkIAOhlSEE】P(`jnYtCcYmkoWߋ`{ ǠRlEZ\cCg 2I5$¸yJa|yn,6hd&@׷?}PhlضrV4#@>q+TmxPs4dw]t]Xc_jטu[ԙLV?nޓAφ:)":hlGZ^Q<Ϯۤ;lG]ϖϗ1=;GO9aSz;:{ ^cҝ#3Tɳ3MSl 36Ɠwzn>N Qacf?!6} s=#7Gu]T]QZO4@xbflרtm\r3yqf-C(C<Zv1B08=t0co4 Kl\΁N~muPMba޼վtͭ:]\cn^s kn'P/HOIu@OWweW`H jaϥn}u126CPog/kR\q!Ìo%ai:!mH[~v{*Ut 7XovX\4(O5MT>v;w?;OV*ځ1d$H "QyehLt %FFHR%֜!ځ1d$H "QIFc&H:DHBc#J46BdI2NҨH6$#@J!dI2N`1k4"۾ŘI2N 1b0fwt0n}2Bj.0 YTG-I 2)t Z+ULki#90gXwHlhӦy׶TOpFʀ!$.#/ۜH.|W-gbBW+DeLJv%fژR^wb]XXp#Nj;X*wiͥtP$пξbbɎ bfLsA'[͍gM({-p+i /{RkPqqvb+6|TOLΛc2F$qbIz>kq{.LonԊN.*'~L+Tk\Xg pebHNufzRI`© HtA42Kz/FJt,]%VhFDbASggNT{}fj$3yz5f Fi-'I> r9M7UB5ʝ<0ljt O$^_x{_2EO5Ե^.~Wbk%\v)Z W/;(0 aX08kl؎mIR~5)BLxBj\6ܮA^oجM]L̗LW(*y3yka4khnR%Ե8SU=;y^6402;TĶ^=$O&7ܠjNq.)l2qN^팤\ kXa`֓OI`:Eվ\ 1K~QCAk\2Y g&UR^jx@\!<y^O"Ӛ$WN4{Vޠ\ʽc@Q) !Rނ6?&9 EQp$Nd(*Gx<٨Α9]jS6\?&.STgƫuJCJ EQ$YF_R-|P9E+S!XDMQT=&O)k Fu7ɜWx0-cV\˟w9-E5A $ Ȃ`8~jal2|俜(bDQ'xIU ,'ќ7$_^ړD#*aK ?DյYqKݳ{7enNQrg 5C4(wلL.djWjȘĒDH |DJG8_Ϭ8U,; ̼1@5Ԑq$6zņEd!2T HJBegLR"yL릚zQd ,' 5 R>~Ke,U[+k;G,s <~1GՃbTxR#!ɁUʚu֛nE;Ib 遥ӥ AD+K T,.ՍH.STG 0HxqZD5vrBBv}beU[x#L3f &ǐ:ȴfvIPIKpG ybou*<$ Kz+e:b\JT2ރf+/֖: aoU,Gܗ,Vi -%𬕫8GP9qSd`Q%-dde<0N -gg,k~q' :\׬Lk>%wҼ; RiWy;i^f~dW*ĝ4/xZΫNrVqVF4.>LR폸Uiҵ';i^/'I L ;^R!RM0Vj"Ms8)#WyrWO|2JHP*θnL!=5GI2yRdګ60jڅ /HЛ{swnxeiwЭg(E16t@`Ѯ~&" `$I'R\R@2RDI[JX 1y7W.嵂=X Q ܼð+i6*l,(Pv AZ$#@J[zF)F1щa{N%mn|^}oWA5(VaA\ k`V6Rp#헰 -.R{Lt %%hlR $C\o%mxq3^} %I0(=$nDQ8W(gjB26(U)}"`$I'R\• ?dR8ܱ6)nx` Rk7Wb?}V!J򘮂$ܡ$0Aat1crw Ej I2NO r)Փt6M' "/&7 =Ӛva\ۋ^YCPl(f&헰*ج*`$ qF1d$K r)غU` ~)0a^r#AQ)f VQXUjlQ_Qk0b$I'H:h / "/&7 T3J Z6@jI2Nu}pd1Ԫ؊4HzguAb$I'H0d C_E)A ec0//M*U.v`1f$ml.)}pRܓ_XZ.ww#Jꩭj*}ܑ:(-c&H:As60RpASa- p(flG[բK0falF\ֳ_)}nX<.8, \Q؀Ua;$U{0zQ=c&H:F J* L2bH R͝TjkhXժW 5N|x}IY$#䩔 J* HQ )}Q ^a㴸K26'4&4Fz*@j؀+T0OnG;#LEjI2N3Ƌa ;6Fŕ_"wSJ.Vnl5br *E61d$ mcft)}n<@Ea[F-Q͂+ 2.z06VQMXP9Ib$I'bl4c&H:4c&H:4c&H:4c&H:4c&H:_DH"0fH!0fH!0fH!0fH!AKksc&H: 4I:ؾvcvqSw+ H/_t{oq-^߾gAFNs(|톮u_i`)ƀ3~ KblW_Nwf󮿽ݶ=ދ\zn}7;yc[kw (hᆵNڵ0#T|?OU7am9'yAzmuXeqӹA칿|֖ͭs|.ۇ_U]o=>&`,p.nl }]oGal9ڼߴ砿I[0??owAd>(_ixmѠ̜.Q^go;{{J7so0C6b|;ϼF;c4xTͽw8hD>wOu;;һ[wadڧlgqֳ+-woگӷikߧ;2x_ pɝTgP⦷ty _"/2G-jmz|lرW u y!'mDv6[o߼n#G[ 6e3mmSiGY@n۩es#s]p5ow(Oju }{"Ax/'S mOܧ215"Q_6*`%U!1@AYc٥T|h8q`̰cpklhHUͥE8p~) νGŇ#~cs},~80r8pH+8j`tm_A|xs2S<}>W]7xa?=xk9m` z6luN}*lcG\xs{ c{Wt+x?DDkÜkחGGge6:ؐ81 tn2Jel zxdwм{0ӗ,չ|fhЃ?M{:AiS m[{oËa\c6rä0ǢAظUdʛ#zu6'4m𶳖c;͖z'_^@6F]1"[sxv= < zVؐ/4fx C׿2.; piG7-؂C;^wGwqaslcf??ͭ~j$M)3tgۅuѻHv3f56T6zS0ႠP (kUn}_߱N[l롁wok@0iO+d4;FMPfpnR0c8׿oPCa?x`? oѦuA^6 >l^0du-F#J yro!`ŌJUNY oG!6]wZJ?VMVyO=1|:|:]ztIx4 bûHvqƦ :wa]ؐi&Eۇˍ1aQJق vG\F164@穂u]g־\ЀƁksAKQtP=۽ۮ,\~Ew7fa%hp5wGfVbl}I: iAĈ"xǼCoFkU^X.k`1|!SeabuxN`lCE1o` 8\èm`Cgqάe+>ol(y/ E?RPkl {Q}q`ԚcS ݠ ./|n(6Yt#}J jȂS7{$c1z1(m?HC٣˲lG#EH.o@ nA.X~Xx|t4F)O,1˺! 9`>#<5 nq7F=o$=_ܴ@~{>8EoÈbN16~OuҸ@؇k ;4 zT߈C1hӟ^ޖ-~o>E  AnݾaO:>><싚v)M=('N!!iB^-t͍᷻'O)m^j D@^^= †'L>?)T؆m,Hv@c#$$;$jlN{I'fCelc*9]*F ZrTFHIhldU1cfY,Hv@c#$$;I6Ihlِ -3_46BڐFH Hv@c#$$;] Bhld46BR@!) AMNBc#͆dc*Ec# bl[|9jB wbl`LJńHٻbU36̵+DR,|k]nl*!@S-A-g҉$n7Մ2hhR1e?N(1C"-ccRK.g9L|~9Bj V"Ӛ1YJP|T@jirUwr8=uRERے2v7MqU\K Q*\B,$ \ژv0dJ>$2IQɯRC΃1_a\v|ݢCS|U0 Ux6Zf˾zxhø-|KYqW׼ 7U}&R#ԯZ~MYGܩ M^偑Yofo~ùaj#T 30Bn`CAwh[uwyU*Θ6j[Z]~ĝj^akaJZDkT&Mĝj^3>qd}\p#x7;>N5]yKFP 02;T#TYviP(f7kS+!VJ ZQ*a\08כ5Gܩ}.uýفk?9F~U͟70 G)Q& ~m$zj|%C㣢~ĝ"  _?NQ(sƻT20w),L%dw*-< ( ɏST*wg ?NQK]su /Eŕ2%A#JI-YO?NQզnob(NSMۤ1(-%|˘ZHv (VBy8**ώSQEQT:#zBy.)Zʹ,?1hʯsQEQфye+/TZW8gOQEQm?vԮp3EQVxF)v1YMHse0Uj;qQG?0MFF7'XbbGFHprr˴zL(Qώ`+~\ݻ?H6-[;1ʘEQ$,Hsٸ+/aG-~4i.lc1jM 4&~`fۭ;BI 7+…)uw2O%Cu\?HMo_'(:uNQďVoA?~RsR[Yj.LQ Ӗ[Zϔ`+u3i.ܬ3gD)"eO%ezVv4t4 HkKHHj8R`&prr WL&~`QSqBH#unV'鮩bu# en8Ҍp[zy5g@1/>;[dBifR]5{n>|ֻX] $.qĊ$R]99,܌T'~䲟b+'~BH2 5#sup3jW+Әx(*U!H\9QR +e <~l*ł'R\ٸ^].(8|H*XB!O 77R{ؖج J*@B! nxA=ذeOr!4Xߥ0=ذZT BG,a7R{c#ұ=0!?X\^0nDF!бBi(!4 YB[sFjOHB!qc#PбBi(ұ\B, B!"2 ͥ RஜбBq!4 2?ʉ.B2ۯ= c#ƥL7R{,CF! !BHCx:idžJA!yeбBq!4tlBpl3ޥre!q)˱ۍ+-ѱBбBi(!4Mغ !g'c#RбBi(!4z Br[[f\ImBBHCAF!hJv=C RH~ خ?D, B!A֠He$!dɑ%Q7'?Ò0$cHNLB:FaѪܤ$y+ul-gRàckTFұA$'&!KH@ֱHW(gƕԖǝ$&8:He$!Drbұ4 tla\Im-RIHt,!$A֠He$!DrbұRF8z  YHB:6$c !$.Wh&FGA#Q>ЎGϿg?XTFұA$'&!k  Kl~6?~Swo4)&z3c;,$lwe&SˠQ6[rC9kKt "`MLU7ː>! :6j96 5D\p%' 9$d (gIIR$,ҒOAӰ#mRJCPSi!DY%B4{(W/Mpxp^]ڂÕ?moQR :$pccU'0Ix#Xstpq ڒ6*8RBڒX [PQBT89GZ:+%%NU/g WI[WpErxp5mX(8H~,[/G΁3:ti#`[G.yDZk8]8K|a;ڒ@85I hDF!rq#':6B!BHCAF!hJǶd0!?_"a7R{*DZ=0!?W,0=ѱBtlBqlϥKбBHRc˴fhHI]}.%ZBز7R{c#bNw_IiH2G;ʏ.ݿ@ٝZ\I=ն::倴[+)ۼM/[; _kPByf>5Q5b8"=G[_tp ;⦷t}\v _z׀0FSmeC?[nRشc}`Bì?eR[ W.h+@ο?*c.N,͵5ϋ}L86xs0,09?5un#'б G]cCl9?fѱ-~5#tl >w^δA0z(g$1'3eR5л߰;?c ޱᮜ4c|}-^yy{pψv]vc(cwl^g>;apq=΂o8GYV^XG{PpqSf?2;tW=؟)|t}iw,F)%+^N_|G_qČ0h?r>>Ry:^c:Qe.o2ߙ9.:6tn;Nd=DuPO?of {טus7eAcdotSM)<|5xBϘW?vX`[C! 3G p<:,Q߸{AYPHNѮt>z}H_62ʰۈLukO}αssW wD~9>Ϝ_rg1NaG=;|uimzԁ@(VqW:鉧W1s~QdžzB1/6^;BQiTMG/~0߹=ucGaGxDZV{X;U " PWOUhh?} ~~02gnwpa6t]on#h{QM5 :64 ảۯ*ﺁNt7<*)v}@F9gkߧK#x?h,]ayQxcrjcycj8nÏ;. 4^c}WmթXpelA`=~ҍ몾Cӿ[u:,wti61]߸6U0L!cC,P)KAzs> o86 6ث_Uuߺ :l)l0焑p,}PuG|0l>n>5ݠM|{ NwGE >|T]:SG\?p쵍t.mmg.GtTǴ='s e}Q(9q||m }-*#TGvUW6oگ8^^ s᪵:hҪ΍:N?u^8CcMg(j,Wc zQf$(tlVo~[s+G}߽vʶ D/%wmNL1Y;p6Χ:vTG9d:6#+w/`];jCT@rx`F'\a~G͛ҏiO~F?1o*<Y㛷ܩmfMtlhrBƕ4"(`{ņ;arv[e؆ ǩPhaF]}5rI 8FDʴՄKwW7r3U6f[rt?FcC1jZdž_i)1߱>x[ȭ07 ޢIJReP̱pn[He{ |8tfW>6ڎA* vǏ>!XA(::5 hUDžF*iu5OZcۭFT/;&)b43-8Rt0h`TC &d :HSaDaWHt1sO,!y[P *NJۈk1:XsjGO * #5Cs LTlw0uP[~ bx]:#0BpTŹs[Z\xz*s]>H F{qa 8uYʼnrGv;r@c&`f(҆ŦyC:NmV0u6QA-b?Pˇ1ij_tjx|gl;xO&؈uxq纁};ʱXHcTYcbf=c2~V $ǡm g8qc,[ĉvhܮGPum;u(smS}+ i`m+p >u?)k0ֶ7҆:mL҉4 H4cU RԲMe!8tlB :6B! EC8R92tlҸrƕԖ!X!4tlBtl]N BHбBu!4tlBplGr^w1!бBHRc˴zˌ+-+Ràc#ƅBHCAF!hJQbaBP%Ʊ]ٿ+ńBBH#aбBy~?ulGs)aбBH"a(ǶڒJ$)aбBH"aWR[c#b0ƱKC,B!wg]>0-k'!kO4csw jBj =Iw%Ԭc;je.%:.Kvl39B g796g+]e>.3ٿ;?==K,|B!0p p,r?grѸ0>37_kX1BmXUď(?[xKh<8]J.V!ty`?)VKGr8~#N0 %f;]zqJ7〻r;gv*sƻT^;D*O.5y{_RD9+/.XB3x5GX?wšbN~eNtw\@b$J2wv*?D[K[ĉU 7q5GAgt]<]cfpEQͯ>qRAGGjs/IpPx.1LU2Wb3 1T&~δz iEQJ{f!8^z/6+>c)EQT͙\Cړ.k9do-:)iڽ{+z7m3{rEQJ/ܜw(وvF"̬#s5v=?/{2{aEQTX*)8.8,{5&-, fЂ^).9]jEQT(텛\K} UБ٫s$LKR}?rN(ne.vn1Y~`u ]i7n!]ď6JgxMӠ(酛smίRv]yf-ELWYVb0}fGgwĝuGkv%'~P4:Q|* 7%F\W_)}3{{ѝp9/Keg& 3ULQռ[RZϺ'gnn5Z0nrf{TJ(J0S[y[kkbf8#{uev&#ĂéKe ֛ΉEQ W;٘`~LC5cqdvE8C{pûG4&~Qd(JRIif"-pk~Eg&M]NpJ^a(ٌͭ9ew1yP'*?,xUf'~`)qL1EKQEu\Wss 7pûz+mN|q!EQUJsfwf| #sRi?(@S Kc-܌Y!'o(jDai'A", proxyport = )) } } \seealso{ \code{\link{rdb_providers}} } \author{ Sebastien Galais } rdbnomics/man/rdb_providers.Rd0000644000176200001440000000364313604436273016156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rdb_providers.R \name{rdb_providers} \alias{rdb_providers} \title{Download list of DBnomics providers.} \usage{ rdb_providers( code = FALSE, use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config") ) } \arguments{ \item{code}{Logical (default \code{FALSE}). If \code{TRUE}, then only the providers are returned in a vector.} \item{use_readLines}{Logical (default \code{FALSE}). If \code{TRUE}, then the data are requested and read with the base function \code{readLines} i.e. through the default R internet connection. This can be used to get round the error \code{Could not resolve host: api.db.nomics.world}.} \item{curl_config}{Named list (default \code{NULL}). If not \code{NULL}, it is used to configure a proxy connection. This configuration is passed to the function \code{curl_fetch_memory} of the package \pkg{curl}. A temporary \code{curl_handle} object is created internally with arguments equal to the provided list in \code{curl_config}.\cr For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. For available curl options see \code{\link[curl]{curl_options}}, \code{names(curl_options())} and \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}.} } \value{ A \code{data.table} or a vector. } \description{ \code{rdb_providers} downloads the list of providers from \href{https://db.nomics.world/}{DBnomics}. } \details{ By default, the function returns a \code{data.table} containing the list of providers from \href{https://db.nomics.world/}{DBnomics} with additional informations such as the region, the website, etc. } \examples{ \dontrun{ rdb_providers() rdb_providers(code = TRUE) rdb_providers(use_readLines = TRUE) rdb_providers(curl_config = list(proxy = "", proxyport = )) } } \seealso{ \code{\link{rdb_last_updates}} } \author{ Sebastien Galais } rdbnomics/man/dbnomics.Rd0000644000176200001440000000167413604436273015112 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dbnomics.R \name{dbnomics} \alias{dbnomics} \title{DBnomics ggplot2 theme} \usage{ dbnomics(color_palette = "Set1", ...) } \arguments{ \item{color_palette}{Character string (default \code{"Set1"}) to change the default color palette. If you want to use the default palette, set it to \code{NULL}.} \item{...}{Arguments to be passed to the function \code{\link[ggplot2]{theme}}.} } \description{ \code{dbnomics} is a simple ggplot2 theme for drawing nicer graphics. We do not recommend to use it. It has been included in the package to avoid errors when reproducing the vignette examples. } \examples{ \dontrun{ library(magrittr) library(ggplot2) rdb("IMF", "WEO", query = "France current account balance percent") \%>\% ggplot(aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() } } \author{ Sebastien Galais } rdbnomics/DESCRIPTION0000644000176200001440000000170713616610265013753 0ustar liggesusersPackage: rdbnomics Type: Package Title: Download DBnomics Data Version: 0.5.2 Authors@R: c(person("Sebastien", "Galais", role = c("cre", "ctb"), email = "s915.stem@gmail.com"), person("Thomas", "Brand", role = c("aut"), email = "thomas.brand@cepremap.org")) Description: R access to hundreds of millions data series from DBnomics API (). Depends: R (>= 3.1.0) License: AGPL-3 URL: https://github.com/dbnomics/rdbnomics BugReports: https://github.com/dbnomics/rdbnomics/issues Encoding: UTF-8 LazyData: true Imports: curl, jsonlite, data.table RoxygenNote: 7.0.2 Suggests: knitr, rmarkdown, dplyr, magrittr, ggplot2, DT, testthat VignetteBuilder: knitr NeedsCompilation: no Packaged: 2020-02-05 15:01:57 UTC; sebas Author: Sebastien Galais [cre, ctb], Thomas Brand [aut] Maintainer: Sebastien Galais Repository: CRAN Date/Publication: 2020-02-05 19:00:05 UTC rdbnomics/build/0000755000176200001440000000000013616554345013345 5ustar liggesusersrdbnomics/build/vignette.rds0000644000176200001440000000032113616554345015700 0ustar liggesusersb```b`fcb`b2 1# '-JIL. MAtq))$d敠)C(AF2aD 0!)eKM-FZ]?4-ީE0=(jؠjX2sRad9.nP&c0Gq?gQ~poݣ9JI,IK+\Wrdbnomics/tests/0000755000176200001440000000000013616545645013413 5ustar liggesusersrdbnomics/tests/testthat/0000755000176200001440000000000013616610265015242 5ustar liggesusersrdbnomics/tests/testthat/test-rdb.R0000644000176200001440000000545313574256275017132 0ustar liggesuserscontext("Right combination of arguments for rdb") library(rdbnomics) test_that("Fetch by dimensions", { expect_error(rdb(dimensions = "x", provider_code = NULL, dataset_code = "y")) expect_error(rdb(dimensions = "x", provider_code = "y", dataset_code = NULL)) expect_error(rdb(dimensions = "x", provider_code = NULL, dataset_code = NULL)) expect_error(rdb(dimensions = c("x1", "x2"), provider_code = "y", dataset_code = "z")) expect_error(rdb(dimensions = list(), provider_code = "y", dataset_code = "z")) expect_error(rdb(dimensions = list("x1", "x2"), provider_code = "y", dataset_code = "z")) expect_error(rdb(dimensions = list(elt1 = "x1", "x2"), provider_code = "y", dataset_code = "z")) }) test_that("Fetch by mask", { expect_error(rdb(mask = "IMF", provider_code = NULL, dataset_code = "y")) expect_error(rdb(mask = "IMF", provider_code = "y", dataset_code = NULL)) expect_error(rdb(mask = "IMF", provider_code = NULL, dataset_code = NULL)) expect_error(rdb(mask = c("x1", "x2"), provider_code = "y", dataset_code = "z")) }) test_that("Fetch by mask with wrong provider_code", { expect_error(rdb(mask = "x", provider_code = "y", dataset_code = "z")) }) test_that("Fetch by ids", { expect_error(rdb(ids = character())) }) test_that("Nothing provided", { expect_error(rdb()) }) test_that("api_link length is greater than one or equal to zero", { expect_error(rdb(api_link = c("url1", "url2"))) expect_error(rdb(api_link = character())) }) test_that("api_link is not a character string", { expect_error(rdb(api_link = 0)) }) test_that("use_readLines is NULL", { expect_error(rdb(api_link = "url", use_readLines = NULL)) }) test_that("use_readLines length is greater than one or equal to zero", { expect_error(rdb(api_link = "url", use_readLines = c(TRUE, FALSE))) expect_error(rdb(api_link = "url", use_readLines = logical())) }) test_that("use_readLines is not a logical", { expect_error(rdb(api_link = "url", use_readLines = "TRUE")) }) test_that("curl_config is not a curl_handle object or a named list", { expect_error(rdb(api_link = "url", curl_config = TRUE)) expect_error(rdb(api_link = "url", curl_config = list(1))) }) test_that("filters is not a valid list", { expect_error(rdb(api_link = "url", filters = TRUE)) expect_error(rdb(api_link = "url", filters = "filters")) expect_error(rdb(api_link = "url", filters = list())) expect_error(rdb(api_link = "url", filters = list(code = "interpolate", parameter = NULL))) expect_error(rdb(api_link = "url", filters = list(code = "interpolate", parameters = list()))) expect_error(rdb(api_link = "url", filters = list(list(code = "interpolate", parameters = list(frequency = "quarterly", method = "spline")), list(code = "aggregate", parameters = list())))) }) rdbnomics/tests/testthat/test-rdb_last_updates.R0000644000176200001440000000033713442307062021657 0ustar liggesuserscontext("Right arguments for rdb_last_updates") library(rdbnomics) test_that("all is logical and of length one", { expect_error(rdb_last_updates(all = logical())) expect_error(rdb_last_updates(all = "TRUE")) }) rdbnomics/tests/testthat/test-rdb_providers.R0000644000176200001440000000033113442307054021177 0ustar liggesuserscontext("Right arguments for rdb_providers") library(rdbnomics) test_that("code is logical and of length one", { expect_error(rdb_providers(code = logical())) expect_error(rdb_providers(code = "TRUE")) }) rdbnomics/tests/testthat.R0000644000176200001440000000010213363162572015360 0ustar liggesuserslibrary(testthat) library(rdbnomics) test_check("rdbnomics") rdbnomics/vignettes/0000755000176200001440000000000013616554345014256 5ustar liggesusersrdbnomics/vignettes/dbnomics002.png0000644000176200001440000026432513414003374017003 0ustar liggesusersPNG  IHDRMƜsRGBgAMA a pHYs%%IR$IDATx^wUgy/gfr}}sJ4YoКcoǹV d>:,Q_tCx'+~"K'LӝjM8zQs<3(#3uǭ6LΗЂާTc*ss'ۘ)9_=+LeE^xKCeSK=/\0Ykk}c9 f^y7-Z>sRL+˚3~3r9Q^4q nbYT>Y<;nΝ-}8mxW5y v2e #|6ܩcGˣޔGˇ_CՌKG=d7 װ;-r(,)UiO,Oɞ ٹOO.LI,=oiٜZU@"{_ ?߽PG~AY0mѧG'䓢?/ACЩSsg>=F[$ǧE?{cd/}('jMӆϻegG^rͰ'؞>-w>6BT[uqwOeytQsknﶩZG<{1QY\#;g1ܢ /::;E[1Csc-Ic_>x{l/~`ΰFzݸɣV-%{YCǥyU+3cgOFHixgqYi7?3cX3oܴ@n6fcXeސڟjs7N6hŠwh/3H> fzcnw[c>9K,aӬ7 qGAGLc\!`sbOyyy#Ӛɹfۙ5eL^1FwIwslDs<&eÌ+!3dĹ1ᅲs{fv-YoP[~1n|S3fH1sF?$.Yn.Qs;~Sf>3b"ԗNOwwcIco~Jm,2\;v6Sn4d:6!{L7/K[UrۇߥHF7:V;Gٺݞ~-xhOO2VgͼU:/>x\ ns=D-{p3ӟNs[94k~im:={Iż4{H;x.C~:jd;cF<|özlF<1jӴ,1qY:,5aqŭ3fHsΝuy2sz'F`dG<[$g!}{;njR eG:#ITҫwmNUL媉+iţS&8Cߺۣʝ>?O"7!{ԵVMbGQJ2;AO϶9dxde`OvUzz?uVݽcLj-hz)֙wG9kƌ0/>ovyCE?!.6#|uCo\oѐ!#[tQ_YUι|)`=%#qzUn 9= 3b&LQofdI(9#W\OZ{Λ! 3uYه<iڼn?Y1'%EJTԓ)sM em.̜1CRΪrnJ}]lXдS09cƓ1FG#3O=kG}gfjؚ3Fg<}ܟX<]OZ)3f΍$eў .$PLgL*Dg̐"&A \O}֞3՟$5cfCy%:MBaz?3qwoGaYc : RxFlMel>=c=׻=] ,GҴ=! 2ד3m&3l(z57'3fɨtٞ02OW"jg܃3(9sxYOG)@ewې;M}iM~/cp\ң\nag'aj!Ü7VacXCz䧴zΛ'dww 3_]Ԍ,mۧg>sg=oóz̛@mwmݼP tnX4a6X&Ҹ Wa7䚻G=aSyNnĊ;~[X}JzT<??=uݼQX"f9UvZ}njYU6=k쩫9ϵ۷sW9δoΗ6nQjD繞g9ڶ@ٓs䎡Ɠ=Qh챭}w]7׳'-~. z>jлYtK9X\ܹs٫^V*î',eGjn}(Ct[7 T\O&_K+jh+gZT]s=Yą>-SlN^w=$E'JGǹ%6oi7vQ/b?nWA[('ވ{?}oVvvvo&@$ɒ뉒S>4c;:Ή;|zѯ0ZL^w߬>zp88F%mWgwڴEΞnGǞ_rF?=7`svt+D(W%[xyzbXԔzwCFUgi:2lLe765Jgg疝,z61j w'쮴u["k{}e*z²ϝ;g`+Q\HL'uG/+jnzc[!P$2RwM؊XlNRA\ᣎxXV ~rp=J~vWڄ%;?vk;:;϶՞lزs%|6{~b'CF_ŎsO=xƳJeg>R3g8,\ROu;fQc[)|#\6qh:quYN\{✗z3{7 w89V+>=F\*ؠܲ(bɫ;vu{VWs%ΘqE\(ĹZϬ8V?PygΊjmLH 0Tic+{MS*{qys3g~JJS6e/7H*5*ي8][SVanrsoy8k~cYiKk;V gv7>=1V0Ky3m ;_o7Yq"N-H⍌Jf;#vI&l+W7y=lq/n/=vVמx-Ӿ(gL>rX3V[N\Y϶+tKnV tu bG`kIA/J8'>h`-">k ܾ->=Y\;RDO|ST"כ|U?}yP^`F?=R{Aqio7+b6Lx{ RZԟ^q5,}r%~zqnņW{1['|'bD{?+m=wXH>tʨ iƆl%6|t|^w;YϭPl+ޚ΂v(Wt T֝iU%C'=?3g<=Oi\'ҧ[&ʩӿ0Cپ' D8r70jS|^$=Ɔl%Rt#FnGGum+Eo,xu2\s˙OUo\TS/}ߎ{%M8H9FyTjtt=ٰT1UNl'gѯ׸Wٿr=ye}r&s'e]'jq%HKOSk~;Epé:^7'r2q=3g7*%w=1֞.>XY+޳]iχO44܋S~r'Ta}oV7a<)d}?`;nۮ'"Eٶ^- # f+; )5ok ^+6jJ,H\\gg3*,u~zjq\/Rm;Ӊy'׾o^cڹR͓{|~|UG>cW|^XhO|o {&`1{-E$z%ܲᣎxX,AOD#R$6kJ\O<=Oپ%n1YSs=qW|:aHy{Yu<G_"8K~e``H\oی يGY}xV̳yzt)< z!ps"U[\G/{w;:ʎLiHk鿺IEzNT],IgJolg=J(3ד~9zgNR d׺?<ѱ`=OLQVwR?z?-g#ƦE^ݬVD "i|I=6k6PqC{nE Ϥ#([J(zԓ'<:;q=F d?c%EZR}-|[x^'?@óԿ4qReuń%M^d+E|T{hleu-)r6nqrwIZdt%I'{}=OZԌ캷C3fWsDgsK=i2=,ݕjӖ]D8];%~Vq1GI+񹞸-?v⤱[9r=R~4$U/sxDzq癚%U繺(3od]'l-)uO.l/յ'<R?z'܏?on]is_x艷"M+xiɪuʊwHN6%rm{}eʊQsHןzG+=݆׊m37\6F1kJ\1wQvPmGz8st(ybJf%ODzw>:ssέذI,)0*ي2mnt~mJM!بr=Ά-g[GNTjFk&U٣Px,>E\c ҍX=c)gsK W/JOb4!1=4c,onw42\op#j;R/yΨteęJHDMR$<3H~~σ=r=yTC+5=~ό8XBwZ{G>Rzowmr1O׃x^KNbriskDj@xtV{83q_f$7osgFK\Ǟ% Z}D$O 3N56ֱ>VC.1UJMg+J\Cƶyn}6?g̈́F0(\YYeGj"jN{hs+U~r}oVml[[Je7:g"R?zBF [3gEI\opoyL,8ja^fUeA6">~"^tsk nx˶rW*ﴇWS"6=13ժ'(%?޳9yg z*z=P%MG޼-Ҵ Qr[wj#8?ϯTjZٸ-~G׹zܨ,b|u LC'W)ārD8UӞq̬ZiTQ<W4kggƷ-~.J)8N࿹~ybJ뤺ģvb; dkIiz\|.7 %^ޑ#e%NLx%HM)3>O]y[M+_$sKsH=b)/rpUn;I䎡[KNdFUEgsCutt(b&wB ok>׳Y@7oS&%mK*1sxIyσY|0@KX'nˋk/GS6߄%&ՍY:;;W,^z<y<>_OB"z%׫iʖ={*䃽{Ƣ K ynG{>sV|ҕyrBz玿uRlWrxD3_δZX3ayhnq$Svsk7ՋG]>޻k G9q5w?zsQ"TDUsX.ړ 1AE/bʎj\\gٶ3U51y^~ri4,RBᄏ@Nf" #M bqfWZGجQ3K!λϜ}StFĉZrq3_ym?(4ò%\OzhCG;" Q艷"M-"ZgCQ ;R{WEÉsD=OLYyۛG[ζړSM;zf*&ݕGδZ8Soz7K[Aq:;;ϴKrs^.f"8;ט8yݟwoũZRDԯl-lWx_q>(oB-gTM&NYaz){Y&v?T@2#K9^+6<[ jHfz,/mܢ@# ag{r?c򒧟ݕ~POybRI\/ 6xgwXsmQHlܹs/m,TV@# $,mCGo{}e֒ں:K<\u# uԞlɌ\/zfzԓ\ݎ-;o\/~vW^:z-)n#wC1-@l;re[KJ=~Yew;:δVmx?+MYE$k7kwV]-XWPnUMH\o^7 z=K|sᆖQ#R_7;Ymx[;Z]mwd>Hh} 6k*jcUMƮ+Y=wa̬FhZjffD]ڲcӬ=g SWmL}[rBozYB맘ՆOl,v=\dWMpiܵ4ewX.gjr=ۖ%T!~νK4X/ U.TrHp<%.BuuWӳޠ,<2sG-;$} [оz[ WexY++v[!v`P5xG{j(\>WMGW\ks)kX0TeV<^f5pWsLv'<7f\^fWeƶPx9k-GPçpͱB%9z(N-jcFuRH\]5z`WMNZ\oZciWޜj.e.@j\Żkی:bX.g^N#׳gm-nӺ +k(l9oFO>O" jHAZv3ӖZ5*_kvKlwb kn]oMݻ=gܴ33Z;#׳EBCozj=ZgM޺ M]kpKDߑ&_nRZy e\dPUbɤRxC^=z`2֜0tl:퀏\/C@j\Vuj*=rkPcَפ--XB3Ҍfɛ~m^8/;[>W5k{Ua#d@gΰ}z\2A>r}"zbor}]Zs YXPt6R^7s=wiٵy#\\L(M"a(O1y+[{f6k<6+womW!\fw׋띭\a]Fae[т-D,TSt- 56PCAVAY{di[_o{֋PMaxcl,6{S\Gmr=j'e,5+ʙbHH+:b6tþ-9i֐|:F`+}ƚFsGwgfx?8l_(kf֮:-:BAOmW.넚WwȐUg-{;mJfq]-vO{x; ̼!:R]`"\r= x!'r=` \r= x!\r= x!\r= x 9]]]Esܽ- xr5]j,Z<ޠ *_.MXUxC?gduvw[=i̛Ѥ-+khZp]ZNa}eBuN=&DZ/wqՌ`xgRY{:dl2 V^G-LP3E]%8#KFF`ޠݍ2j+?\(O&\c_}^nkh߼]ߓڳ]k MlCUZsQgJ5<텽z}\oPF}}y: 7mnaςrZK¼í{zcw/Zk֔mh1>dNHQzj00&5 Dz#W:ExK 3KTkgp5+Yz[4u">:- Uf{nfk,͹6iWs5oڼ)_eyM͛LiYuFExz5%/XM,(~GZx!Hu=$3a < .Z]]'vjpKn*T%>Cn5L/\/k4B7]dd!w jVZx,,NG7k^ۡL%ZYOTԝIjUi Gez+H#%z;2EL˝q.B;fXK!󤼯 +kfZ5Mu+3o0]dR; {*(ؙ6֖m>؂ߨNRՋސkҞl=ڱ<}Js`5m}Oex#>BW{2)m>Z^YѴ5| -֓=! Z 36QS렬m%ezOF}"KcZ]k~[_ dr] zS2ͱ짨wnj5'ğEY ynv1׻m외>`vwc+}Y>j+=yɱ&ő Z|Tjz4gW]5l]CrvW55MXWb~|ą]D0H"빣K Ü@V;ƃ&CVj1gwV 5UF*_&Rmjz}Z #ū̒ KGmݮƝ;6SުS9(#D,;o21|IJ-&e6qjdR[(XW3vi6s{i55]U%>Fu4/ 'y$ YijK_ ܢOrrI쉏|l}vOKvi'SYAs_~Ag $d`6\Zնr,fJB9hK:ېmc]#; E a>5miլgRC̚F<䥇!Q֕o5zh*dj(ŕw'7虅ɗl*Dۂ(M{gXrJ$lO*{*`VK:E!/2*Y:KVe]ސ眉yN,5K &=i{_ j%Z^5GkX{M:ߖ)N]x݌r#`b4dR_zf4-˕k zI_^J):LTr8+%Z,\v' #QɮdceءL,yDNY`vCwPfc/fg{)j\8ñ\>Y '5=i\/B%\=st 5XTs͎}#כMk Y6X2v-! Zo?73v=}Sfk`||@\;P0{>4x\zʒަVjtzK-?}z$db=j4, fW0*IGzzW>9D!B1As!9Pw%9#ՇMXpr"zY: 9x\k#3z$Vμoɸr=54S dee}Er=,Ѻnqw 0^r=&+xCNy6wP}Z,11BzyKN*'ڠ>*agr=[Z }hN&JLt's RYk z 8 ^ZP$P\XrqHk&UثUh,T+z#s1dr(!;><=N˧BKlЛ^f5:K5#\W!דe0Ĝ#AY{53(6yjsH Nч$`q6~CrPL#91Z¼uV`<&-ιs[- d9aBWs 3 7mQ뉅VeЄuվj=j 3O)9ڢ"G0x1=Ub(SPիs͚'ҟNr!RBe0s=a+uW]feSZWO"z6%Ruodոsiq"-;Z{h%y;6X~H [djP%є+D.}rԽmuk1Ӯzyh{\T9"g/Ԣ ݋YGWW(xtotڠ 9klfmɱ7޼8D]c NW4wx {d$wcB[/BS̃\OA!J[s6|3*m-yA_/Ӈc2ܡ}%8#4aUQ3 Vm"z×AGrRG/No+m\Urwbu޼ܚe QZk˶Ϙd*7R>vުPRU?_iZ:YpXz ,t|abW>nnm 5=3* {pWҴteYwK;]~sǗWRw\l kyp{ Ͽ7ܢQG'M[jxzgޫfR0wŝ EmV)jwېk_We\;w{R[\Fdk_X~Z#]~e+\s۰wnONݎ C{!{~X3CtwMXSQvF:/0?zز\yǃ/*sYM&z 3smSw2KKe[WSz1*_ yV Ts=iUzJ}bzC>ElGqoܺ}/Yݴ}._Ó[²MMWtxkn҃r#::*?xN`zb5#w뭜TYqzOmݞ&a[?-[+7YXq~vM%ffѯmўx/TnmvL*?8rKHz {?:*Y,6~UkoWl0}7*RU%7jXZ\\8 ~Q?_(`n.2{s|gO=ngy㦍e5#>ڦq_ a*,ǭ.?lp<=@ܺoT/zƆ\I)+}+h2u쟷HSUOjWez094C\s)k\OC6#fj[Tjvƻf:žRm 0Z#Iskw͖L#9i4FB4#23 2 \kt"s='2s{Nrҏ01fN*]+SN+3ho^wr*kE;דHEfFfݱB:݄yeva2۴ݡ/Bgv't/*??82\Fn #0 4#~9aR߇|f|Vf^r6 /LVo-7Л1o z|qz`#ٺ8r=\w?Yo1r8q棬 Vk9]8[XݲUNaQI_R]}x[ܹgfz=:\ u3כ>=JxDnܺ]vr[#Ny^=+hΙjqz+v6Dž\(fLn/\ ŝ-/pC Ų&-YXzckeo%/ -'q.+bwG-ğ?رvXڰaalwgչVfj (Վ>G@j#+8ƽOE.2;~|垏 t|a6^Kiyī߯W|{ÓȦO3 ;k_ կEv+\Q汧du{bܵۆؘܸCEKyZOw $Hm~s/,T<_ẑʖn.\~yMS}ҼOlvʼ2+kjvwq~x#_ogƈqz-˯;if~MepSy\̕yzu/d/k17(R\"%k@#.r=$^w q\C]zHr"@C1&wn@"Th_#t (NhY@CɝAxD+VZߏ8r=BJ Rhk=fa \/'>D?غ@\z]H*tK57cM (#ՈWzJ Giq@JT\18H %A*P`PZ$ (@Lz0(-HI| k &r= $>H5 JR\@)Rr D @b"׃Aiq@JT\18H %A*P`PZ$ (@Lz0(-HI| k &r= $>H5 JR\@)Rr Dۚ_U\:i$^|<WNuWWWk\u9ߦd5vRWW1쾹{[ɫ.P*Z|@B(Oh|Р.kx鈲?)@LH;3o/VW+nK_|vqPM}ҙ7:zhJi 5V]z`W(2Z+;ֱ|x[etTWA:QXY{:djޜbWaffڲc⑑sX{Ⅾ(Ck3\/3glq4hYzj]E\uvҍ\\H*J.k9R\W|ydWA_zWA[>JL}crouAXc-땞W.$- djo ӖP3E]ŗ̢ڳ59~$WHAl%דwuVRӸkih/-H˕XpMU}k{+|Qmv܍Fm59:YQ}Sr%Pkњ -U\ի#kwY3 ~g%T'n2?iKdڊU}aowڕX QwwrS#;\O'L JN T^Ans8v 2̮pj|4[S^2 EP..>ckI8흒S-j.ժIj'D5%N3Ju;zkvZϯ/.rg%T'n2YW64+]{\Os˫!\_er=H޹d>[yDy)&rݢ ;d!6:-1&T%W\}8EDTz@RQyzja]rcR%mfKvbQMY?)^"c/r=T1nȧzc1Ir ^Z=?}+69%gm.1TjWSM,z^PIEI|-[i^h'\1%6X~u/6w;cY5hoµ:眳UlyKߘ|w7M;͡dHHWe@~P\O&zJq| v)Ӷ-WͷXz7z}t@q^ۯ毛yC6Zmj Y8WN7WwJ ߬0u嚲6ㅮPsU 6'8P90Yc9֤?g( =( <#K־)͋%|ކ/Ъz7<}}/Y&9ݰoK{{ai;Xn5 wWu֫0}譠]3d^`Xi2[b }`qV$Af.;_Vߨ~~znX'^ѿ7Oکկݖ-F=m.o?XΏlE.Zp7_*4k}m͞szpqݾ0v.Z㿋?s.+oV8Jl(ڊ7|QGر}Vf?ifϵ|7JPOP~I?m OFS8|qg<ǯ kNMw_DF9rߏW3mZٖH&n;)e]ߟ9hUOj/EtiJ{_j:_xۯg0su&7by\/}vւc3Y|r{rW?oF msS1V_j[E"|߿Ҫ}f3%q#n|~VOFh硞\1%,{|WzMk}-Vϵ ;?T.vSMVֶ# kQ=Zk=׳q=FFuW.|\渞]-g¯_X| }m6VUK8U\O c뜝hmn4Z^rً$Mt~ƚPj[Ygjv*uABܴo2#&S6m 8zT )z6s;;C +5G̻SZΌG#>o8 YM7|JnpP-iK8+4C!C˻8i9ZʣC fO.OIfo*34)..u╾{X[l6.Z0jkQΎێ5hݞkת}g8B\{w/6MW`ZNߜGk`eos̹V.q|oɑ8ŗS|0chu\O|x[^cia-s Xndlk^#6 G%-Jwr}Yثol}S[Fc Um-v's;*\}3-ߔZu/!ڗ%G tk?Ԣ?^ ͗bW]k2ۏ/mԻ]w񂞢|cnVoDf?`](}g0ڵ;&R;d%POP3Mpu bK窬`KxK??Z{=-=ܜ6y49X.jYo8o4$0۩'?~s74D=ɓiޣ8\}f#ǽzs35FTVo42tܹĕ%>Gɞn=)-}lF`"dfvκSz0 eRP泚y_*RXwJ#/UzYZ81ͳI~Zrk=VvKvj?"x{ǝ/z1?2}U3 @RUxQD/տpǥ#2Z.q9L*޽qximR1О_Me(5y2xWݸFv xs=GI|08w5kqq k"dM&%5'FF/뤱 $>q ~䄭A>{Å2g'ږmIp-RiZ83r|VVTrm~a5g,e 'ǔ/8F,ɚgA+їVm}E8(ySB%K4B=yViC"3eZLAY;o?sVڧ)3f7hxZw2ͪ ô;^Ϡjr\{d4}֓ p\W J ڧFZ)+V}sr#>rk:V$*WU\.7?;L]A5'e}3>[gz|SO˝v=nUMezO/@{fA9ݛ- 5S"fҷ+vsL68y+_]|}V ٛ/bI\+%]I?sa<¬o>LB(-A\ ߿6)%G}*nn00Q۴dU.B/MuEkD[Ĉv3oqcoܵo,)dioGҟW kr=N)B&`DټǓj.Tަ.EUޥG89/Ty=Xppr'#V+Iq2SNX}Ƅ QД{f&eOz'׋ź&ηvz_~תbwTy[u\8?˶3ci?Ig{#ZnsgW>~~wVc_y_oh_;QN3ikrgbyyx}YQWѓM (Obz#T:Rw{7*k_"5q\n`N1aQ*!O(%K7L* HϠ֜.|^_)qwyz:nǫp>gb[KRO'yhΆr_ܦgL;8ћf^\ϻ3ikr|Y]3xStRz$>q♏Q쌬=p{?~rT['udd=dB=׳֕; wԉrzs9knkxmcRڤW.6KN}uYCrp}Ta_!jgxq۱tGiq7GrFٖG5D|}S$ J_FitIYP/5sjyޘefE#ʿn_[݃(+yR|$У?l2QJ_俓:yDj81FL"*;9,9pWdlɌ:è{Fp c&ηvnY_^Ͼ3!G8tE8^#.unO~=k==݇L;z52cQ\dzӜloH[SJ0_z4*G9m?~z)q^?hIWMOYr|y ܐ^ZxfľG4C"snȧ=oEtȑ#߹⼃{Cn>?KLM6YW5c7W chBr{7\Ԗ.o~ox7sr|χd9vr=9WCJ[;x\yߙv.HW]uO8OvON'G*Gl9`,:`z\Xއz3Gb4:A3~Yj}I9<]ze_F-Jȹ?k OFq<f|~ֈ.7i.kvkO'{cwAk }c^}ū~QgھޑP70\σwR&}ɋ>/:*3Bly4fa5swyud#uۺÛ's\J6]:I[]21\/e3hi/=~z)]*gfm\A+ikwΖsMZN_}wC+SG)-G[Yu5cV8]cǥ}Tl3ظ'dž7eq4cZ\!_o/+*KX-Um$CRyze>ӂ?|}lk{׿)+ /ϮnuֻNǘt2not/gW2zSIϕ/pE u|xr9w f?6 o_=ϚYcO_B%R;skʥ3F*',|6寿'|֨pE7˭kͱX+~ZwrK\O/Ļ|h9I '_|w܁m9`!+֡]f=MJ@P@Ei12ݾ(Wr]{^;"#CP^߂DR_ )nnC5Ezo/Hi!Y_I>kl{ՇkTCaS;sYYzٸk=\LWH;!W6.8o/5nSac^5(/qg@/h\٬}E}ԿBu%wٗdL.h]Q\+?`2+|Ic8ղ8򁙨˟i//Qq÷__jiv޿htKi^59okO`v9: [Qsleo8nwTs]]a\}汉COmݤ8!P]n>alѢa߆<;l݁26Ylƣ33%یPkfk`^jW{<Fo`P_p=|ƤW+kOw!r9rwwgنUg^UOWkw}Ӛָrڏnz'<5\¼23E%:ȷʞc?sxufQDhko!>PQ ~>/ߟAax W~PӤ9K+[;x\ߙo}HW]$@͖ώڽ{%_\Kؿ;B\OX{"~˶0;0z_o>s=AqB-{Ė?S~-0]zee, .诇$$>qx:{ɗBWjc>t-]}7#ʷ}mWhT{+tABof+skjՍG! fiө#c@{d1WVdnj %A*P`PZU_m#Ӂ%ѹ|7vgC (Rr D$6cFNYTivA (@Lz0(-}JоRAIh'jiX@P\X[Ro̳^ \`c@(Rr D@`Փ#cZ׫HzLW`P\@)Rr D @b"׃Aiq@JT\18H %A*P`PZ$ (@Lz0(-HI| k &9J D _>D+@L~s (IѾJ;[}0Wzw$AHD*-Pr lŕk &@z$!쥎nt=hom*ZVikpaD{@hk#ד3~¬LtE;-I;i4Ѧe%\@‘CD[)~@ " )l)\0@x r=V>cVoݱH֎{4';7Z̅#'>5aDbx8rKWu~@ Rr;yRHR7^3_W) %Uog$OR7[uG߾øP(T-JFN|JHR7{6o7 E R̅OFx (o) E%Jq>d$J[)~@ ;Z BI[P~2%Ń?| Q(JEId$J[)~@ "ףP(jAHRDGP(q%Ղ()l)\BP.J'#QR8yW %Wn-'׋;vm/ y'W_/_R GGP(q%Ղ(}l7woAbz9ծ i ZBb^ښ6.ԖDO);yOä tδЅӺf֗5/T޲v|G!׻µҝߟ_1tN2Eiყ\zC>:.OOFAwڷ2\A5כra՟NI%r?>^q2wĕ-XuX+|Z^c%#OVG`ze;b:ՅjoAr=rG<1btԣ|Бk<=}hQO>3-wS|OZ:j/^S~ ՚mUݩs?iT5y3'>igDqϓY"σ“ʨQ~QmY3ɘ>m񚢪^.}tro~޴7jm Wʚ.VyaK'gaezyt)>-Jό ʥ6Y{]t k-r ؊;Y :[g7rnͬ)\RZ9О++9$ݫuߨuCkYc%#fa +/oUN°[ gVlԞhι;xHk\` It<7eLQTЈ^3KVM*fs#ΛF3' ;jŵ?f,8qayo\0{S\ϟf쀹y#+X yhq8ΓodRq㐹U&粊^>.V)ѻA#^<| jMz?^{Ӳ\oSUGǬ%d$J[7xgmIXލ[ {QJ0Εf(ZH.$Fd], Rl*絿^Pvpχa]jz߼W8Chkc,CmǼc 3*rv'_Ҷ6qm}S2׋fY<-^XZx_8}/vfϚƟk|I=S?ڱsXdKU.}#.pc۹lNj,O+{s#+fb ~7z|d'.M[6iqϫ!o,/(n)'/-wcbe M}YHG\oԶeں6[k;| jō\oA\ϐu@OBY}DK+szö6Mn:K\pAlY?G|d2>'^uڦ%ɁRNr/׌㯆*Bvbc7??*Ҳ\GW?+1&k}zz`be';K"diOhg#cSzLv)~+J7rVr=Ru (3R9gG<\}卶jg6.4GSs鹛D (#5iSVoCyrʁROr=C-X2H9ڧGg7%v'{=Cn/izE,뵾*Gϫ_5 V,WU'GNm;6wЭ9%<׻zO\fwJ?%Պ\ϝٗDO)ocUů|O*_V aƋrk_Wa'#Q ؊7כaȴ ^Y&*=b-,( KzG+*.s[+\xاs"NnSZ.vugN\>fTMi/=\lV{Zy֌ cVq 7\OZAͷBYJPvdDd2;(8bt(xH˧1B.{y\6-s>ٛ)6IޒwҞxu톿5Nv)~,Jz;ҥ>7_ ?sP|꣯/}җ,fw?WEq]\D`Kz]]mvU337Օ)mnlܵ67nF^p]m䎊¡MM7ep%5Z';WF_]}1kZ{G6W7i2XChoSG\zz7=3wYkO?WΛK3׳Nȅʭ-lTx`K~^r–Mtzzcx.╣]:M;u[MznΘfLڭ}ta<^W({Q{p)#=Yޠss=' NGqͤ>ҟEI\O~wME-r5ʧo1\o_uNkv(}lG8sIV֞602Vն*G)vWWTthIˉ>,5f\Bj=*ߟ_1fө>fTEVv0sLIl-+sc~I} E-f07CqSش9<"%^)jQѓL˜+RlyG~fA2כ8ެi?fyr\`~p\O+{y{nKj5xz6Ǔ _qNs!haY<\C\o*QԓCG61sxBϢZq|{ܬ\o_?mhX|)s^xjZ7)?VrKRP"sid'""/T}bV*1Õ^ +[\eԋJ(i^q]:ɵ6qGMuvS\9i5QwG=J2%Պ~N_|t\/jҦs 2OluMHR\Ox.⌊4T@{ի`\|Q6givczyk~yR;͛}r9|]dַmKv),J>|Gz7HE>?'p%'#QR59oF}OHR\MLR8J.`1oF.]=Lԙ5R>ԗ^.N\l{Q,J{ڼ 7>){Hs=`2]#v5L^B鿢Zq\{ӫUXK" pR\O,;0C,|PyOL }zW~S9Dži'˵~v`b݌# tj]1cwwkd_z;| ߊjŭs#f7oz pR\KG(FO#t9Cmd+zz忳HQ_^кWw,2QO?~0v8qČMMVzf8=K [/oO~ܺc;HwDܗ>™yuV{'XZ}㓽.>OEIKm?[Sq召v?| %29Z=ͨ㟔K2=OQ"GE*pJyg,ƌvi域{YOĄF9i`ԔF? z]&m=Si8ݛ2v8Z(z:NNǡ>ng3tU߹^x6>׫XZ1m ҽçP(Vz+{]K7Fǽm_%W\Vo>|yk]r'HA 厪/,?;>5o+|z⨧} ??٫1g &s=Oc<+<Ҧ]*;{^>Ovy'޺ya>LY=kX إM{O}RM)bCe>cj <WcEF/>EI[^vֆˎ?^9';Kk?1"( e@%Ղ()l)\BP.J'#QR( %ZP~2%Ń?| Q(JEId$J[)~@ "ףP(jAHRDGP(q%Ղ()l)\BP.J'#QRGXejwA垏+ﴪe(Zb5%}^,&׻P]o XarR# z-X)Oɯ/]3}V~x#}TKE}mvmVr/j_ڽ\@BPQmGf<^SWlU[3r"DlֻWKxWIjw#cTvxH{lkL8ZHޮqF-[˭溵k7'7X:%)i"hXE<կYnuu {Gu(UTޥwQ)CQ -m0FG!e-mؖd\W@ ,r%BDȼm Qb]NUvIJyNwϴFFzzԮ3}4}"j qYgL]'y)8;7C/ݥLO[mcݵsM~0ZfwWnwשlַ~vg<lG^ cEY|[w׺Cn'2f w(lw6rgl}jZsp%7U5ZATWsz,6o5϶ZⰩDQݱ>eM=IX{T7~u=&ou 'V%~}by%$vNgy0r\T}#cϧmno.{}b>E VwNJMO5r$lpbHΔmaD~|DUoU9/p{f}[sDmʷ:zDkҟlNvt=Ξםۨ)I8oEYnSqZ7:^|d 2N9=1) vY% ^s?m3s3lܮ&yp΋ uguGs>nz8PwR= LyR%w]ҟh<|jeEV=39x:;fݱutAGeMr[s-jKܝ2f~ ~USfoڨQ?YoǚଟlE$4 (7>pĉ3;Ig`:ԧ™'dQs w'NvFD^֨^ur+UۘDrw9[B7K=7׻D $8tWdKeɖB+ ҢM+KjRz70Eo'R]r4dUg9; 8K/)Fvqo HF:Nʃ&ʔz$۝(jLJgƺG}#D䔅'^TQkmz%7 0=ptM W۽:[PףHo @X|SSN|t5^Eu7K0Ѧ;vRܥIF.O/׹xfSjNN>IlzdQ^\զsƻΩG"s3'gf|mE*vbM7q&Zq@&*ں[FH26r8SQoYMmmr#N꫖Q\ϜwmMEMIP |4;5vuS HUW3âZЄ9Mvg6Ml^ TT ;JU&Cy &݋ g85f?Έ46)%3ӵ#[Iw6!<6p+>^?ួ\45<܇XKm+w>%S"d9s_EMkC/đI]6K'z)qT~oM#uzcM/?Aw}Dtg̨zDo N}@&iWS޾ÉFkj]֏ɔD "& {\ @u}YCGלnգD5p~?PtN:f ӭq =^wJ6ToO[3p_7q͸m& 5iBA7^ؕ=þ=1sG3#ݗj;fӻl^;~V~'4'K >PDg}]WeWlŦ0RZ!-.mK/Lb.a]|;3X~ތ\o-ȗ{K/e%T&RdPz M|I'OjF;dǜ:R\/8B*ooEHLEw1em-rT\/<6D.]VΌ[£5AF;oL0d00ʬ+101~Ȏ?J$BWo'&zgGS*αխM Q>A{o)5j~^'2ÍYwP AT"9OIw*zXɪD^nNͿ_hdgifG-ݖ|g`Sƹo &w33\;,U;IKv)d):Y/Ń\o׋=\^cz)-~X@{ƙpc|P>L?(UzD^hV?{YoI;QB1=+ی=cnoRspتaOlQr}nYyO4tPV1ITD{e(Fԫu[㌸ ^!۫z ⢇p(^nM0qC,-eqL αcOtҥz#N{C9RDRqvD~):یuB[}o! /ռ6svL3E}ELQ_ň<`$W%E{#/m̸zФuyN,.G T\{&rgom 5e]2~zŃOʥF^ Bxsƕ+[Yn~:|ƕKOMu`~8p[3+ӓu5׸7.Xܝʷ%sZ(}zꩇFH{|P6˱|~Wȝ;/!hTUzJQ]]) ڻf΀'i,a3n5!j- w'J1K^j=<|Zϓmt=dU?Y?>39utJO(o?_Psњ~/0N$~>(}[^_S+ؚzՐUo}v߫D] /i6jlQQQ5Eo% 3MAۑ941GMgmN9_}1ǛVy|Ʀjƺ}k-qU Ry!:/vjǡzc=~or=$#ѵo*t~v8uyz[NMz3"}K*$֏K]k7ەEho{4f-\55=F>ty_nF=C`ùLHLh ByԦZ6'5dNHrߎ_d>99치fD31 IBTHjZFrg}Ÿ(j7Ǵp94)u$u3"WPXFr˾j'_]q o0?8멓}h/{W}gfXBo}Wrɷo98rdm㉱ӭGm)WS~_û^xF-➯Ţ܉rߺ"z_ ׻i[M!sZ)[sφMϙŁ2\omͳַXYdr]Ŀj|,|忮wx;:z"NLwT۶Vb>@5ԃ8ŕ<:>h%pf fۼ&V;7*&ܝ($ތx 1.6Oۭ^>J{Ό[*^Qs'Oݍ%^B"0ͣ \8uW؝kl%(a/86=tK^}љJEEYpGn`flNM}rVLY<_K^#r8wt3}́z.j،pŝG&xA[j&{m)XQ=g]_B\ 'g')oG7c'WРkh{l{MWh‡6U ZF#6=I>j!|QykҘ O]t= G|Hd_džc;O["'}MΙ3߇pw >qNvDŧ N6_٤Hz{NM wc|$QiLW7` зiyvoYV8]C׉:g߇(2jp(ՃݜNM owpŝGʥ%ȁi{u#Wp:H`G̔UՊԚcMG߳?Gix:V7ƺ'dH޲op!ЙWlͫ j ;'x\Op q#яm2Ƶp:Y6)W.gCHwi#Iڳ߬.qg|n0w4s+W.xF\Ϸ$. Ź/^cs`6VHݷBn"6mۻ?$K>Mz=h\e@1ru/mg-37=3?rU@r=Y>%qW.ukûΐopnqMfP~a^ٻzEW۷B^8q+6\f5V|ZNz9#׃|/K~P]Zoz'_ރ;3l(Oq.[7X^9۫[!.8ܻwr+?htG͘|y3\rz[7JE*YU}}Ok?R|=!2K}{YzwF݇yzy\J8;<2xqH NrWzw4}Zǿ1Qşg0EԃGMUo+̇,\t]X][}O6=&e6ފTpVtzݽkxhY5֩"<޵^"^:XΛZƀ-uO=FJK[dS߀G%oC 7`|A>mx*8Ų0aw*H* _p(<{3**r .'tr}Nw2Y9D,Fz'#?KV$7QOzgTK?}mv`KVkkoOxwz;%)5[\GK;:zόtOOwJokJ^vkiIy#ͺ47x?/4rH}ױܳ%ևp͝:ʷ˫kkl:^۳z̓ҋأ' ;tR Wܳ`DE7 4B;׻*k6&˜땮-g;h&1r= Bd_d,PcOc(VX*eD}:jr*lYqڢm:f3)+u}?V!z_Mtrnk+էj4nݴ_zZ]z=@r=[nn݅Aҽ(vaGU!*dr|7-'f͊ޝD;[ri>92`͚qкS73C|U׶=uz\BP(}u. ,:׋ Y6Us״r=I%Vq^P,ɍ"qObF.TT1gUU{BD}c\OU=&n"';N6XM^r\BP(}u. ,&Ʒ,yd2qn)UiH4[y{ݯY|5:3Y\lc[b7+$&pщk z޾f7jNJGK^40Ī[{@R&V(٫&jyaS-(HMY}wtT3d$E 4ow*3B\}_YX<s7\ ( }W뒱QR9«>eLiHMyኹ7ʞr=Q*GcpcG%׳JwԦ-S*ǏUmt-N?!j ]zz\8\/~(7&pKie!r؞X\ ( }W뒱QZ"{o,FE+ Uk:዗x"oYBY@FϨG/[5n1y ^NwZ5A#:ĺ#BV^}Iٽ%a6oڒ +W;o%P5z$f0\Ow`HJcz Bɾ諃uX`I:d|@5if] Xc=-'md(5*bq3 &Gŷn> jJ2$tZe@av~s=IGH5z:kg:Q-}id|@͎mEE/QJUOp @Q( %%cEd w6UsPi뻑~➡sX)J|rz?RTQ9UQJgP<͟ \/\|=ui;>*!e^NӞN޿F,Vޒzt{Y#5Qwr|hoUœ-'CĖ<|TQd{^ڗ 2zVw#Kkz Bɾ諃uX`^$7v=.Pr\BP(}u. lr=h4wr=#ףP(JE_Kӹ^ޒ-%[*`_| BP/`]2XY` /O$r= Bd_d\BP(}u.< ףP(JE_K ( }Wr= BYz E_K ( e$ެB=Qd\BPQI6E_K ( eyh/PO}u.< ףP(eW^v(`]2y@GP(˱C=Qd\BPi\B=Qd\BPo:X @Q( %%z Bɾ諃uBP/`]2y@GP(싾:X @Q( %%z Bɾ諃uBP/`]2y@GP(싾:X @Q( %%z Bɾ諃uBP/`]2y@GP(싾:X @Q( %%z Bɾ諃uBP/`]2y@GP(싾:X @Q( %%Is_\(znMOBP(˾4 uA\oGct( 싸(K@X @$4_W ٣P((r . .%Is=aGcS'|W_Q( eq q9/ eQ( BQE\ĥXc#766fzu BYfE\ą@\  fXpz@! PxCr=7G˗גVFFo;We-rPouzEgc;=!k_yǵϖ37ΏTW[$rW~蔨όV/e@_o: ό:ڻ^r=1x荞'cڦ뢫?Ԧ$3*֏vu_n/G ZW}w GF|PP߮]ne͞n^sc' heq ׋CXvnTwi%g8 i+hhMosGk.o$&\ 1\o!쎿I5Mѯks1F{zqQrheKD3 fz3/=) i%Fon_|^m>/+-\!,J:0ٻ=|+yP]}jz:8^Ŋ]M:F,\Oظa-z r=TQYߴo]٭nn[P2a53Smt>M?ɻ}/_:~˿PSQZRK#n_{QL|ĥ1ЩU)^q|63>(;[V67:ѳwo#J>0l8{br͏qj@Tc}ƌ ^XkU9c6W6y+g}f{m5XQQ}[8K~@Mk{ލ8Jw'+ urIu6w`NiQ$E!}fjW9>^}TT\z\t.^zm'ov@'O:=O:oY:ubT(lB&k)?ᚧVst}]G)?tJ$oWzOۺF|5-+YRƄ%zݣ}UZN~ J^m΁Q[, :ws79ʶ<:%WS_%YJzDž盪;۹lQEY9:͊ zEKϵ v;o[CNl2>Q/%2!)Dtl=)tau|yOs%w{tn}D5.q[/?3x禑IgQ6Nd?Q a!dQSl>qty8cW߬T;n?x `7ZhIwSSS}ם9>V>PO ,bf[' mb/J,'mA TRL5Jm4<ӝt7ҟu2yTƇtO' ѵm-ZJ5+P-zp&J*+{TS $.}i:s?j0z;āZ228SIȬsYC~[",vztؙ˲35 `&+(fKڻ?TF0}iDF^^ Gݖ܉9|l|UskӰIzzX')߼}J~o!MGQe`8Gz2 ^cc^1+6;vբ'"X*!s¢+oeWJ}xUҢ{d3[;Or_lcs?j:uG8Λ\oƲގn}%l+a<:%x{ot>P=objϟs[8zEOϲ*}X~ 4) t4I ?zhA+w:HiD Yn>7dHqtB.L tƘ'ȳBgKҒd&+cyil2O TEU ]MQ5;wF7Cn7{M sb2"~L'BuOwnt*3op~/r;a?iuq!Y.^.eͳ-n9_VX?q(XZ ay"CҢrp4>|mPx[m9S ts][6YlcG?]G}?h\oϾ3ꕟ[~=Է|[Sfѕ+W|'n~Nz?7m)sCkEF>;&}\zy<{Sp0/\/|Wr乞\ou_wiuR/,^ni9\{+|9rKK=;|Uy/%+Vokz%|v[J+iznnr|Eo~vozcS]'4<}&u{Y#qWg/K/|\_o98rKz'|kLZ^dߤY({/,\_ǍPgOHM-KJ~l^ٻja;hFDzlz^,m9juCr}޶)':~b# Ufbʤ(Seu-O4lz}>*>\,-KnyXϬ넇B}G]zy43wOo_Fw3|i%vNf+6Z|g| x(멄+WܵKo{ ,ӇOݪL=__]x͡w%Ȧ'HT cnzj ȋ/,[4oyNr=ϏeWTjLA&T=霻hz_M~V۟9ߞ 9oGʟO#ȋ?U/=9Or+pM=3g[[/ۍ5WmXTwh}śoXB5FSEy3|ܕ+8r:ֿ}?yǙX#0o7լ/}ƿxxźg{oNr{}^\7{_pC"Ez6Ֆû6eo}Q:n}롆w1[]|r];zy8[q7dWoF߬8KQNQJIY>;l*|TɹeVt7޵E[|f(|fތoo'Z[_TyxkvPOzZROѓx%V<,cgw-?z+{O3e^شYKC3Dz`e^kɩ3Ұw7Ն }Xcz͉8ӏՓ%@^&דʷI/oD۷j۷>gf+>荶go>].N_R~yr1oPCF*Ϟ!on  .yIj#֮~@\Q+{UZ}z溽8U'>jocd"+B_\uJzy1\o9rݿ_-=EGZZk6 " r=>ܩW-\Gۥ@z{o+\~oɖʒ-EYb JLy@Vm^YR#?r=F生IܣYӞ^O^~d?{,\dUy~{0Ӹw[no}7.U;4[۵ #m_:@SpWȃz߄$,+ya* )v0_~vV,~[|5v6U}/%)~3t2*SoysiDGȪ ek'[{i~9:jZE͗/#:n;MYE_K akkA޾ir,r?Ļ:=k_n_Yu&vhw]{o.[spaP6Y XzT~_89O-L@SpWȃ|ד˩-\\/\/] ➟$q^dHdI$i?2{%U#~IrhO@SpWȃ<=_% z*?O<%?p<3n=m̍wHU?}}yljK;Í4Q6ލ%=#*SaJϫ)1.(Mܓd0\OWfy雯~@|cz~-u"kzdPˁ,᢯%7Cym C=!7~ZXMyzWC]ٳ~:ȗZF;M?8G:cWu77=+#q/LG~__i8:λ~NG+MrV5ZO|a˩MkINMV-iy=mGzrck{_Q_V-~х <Ơԋb~}no-Is9Д%\d wU3d^jVP^َ@???|?.뽜 wLS_MUT] (0NS_ӱT|노#w>wf{d]4M~?iٴo~y1qvz^zZ}?}ݫnL?͟kN^y4?lfu箅;w.:X @,x4zMC*r} 2{r-WorٷL I~'D _$,^y`_\:?te{ntzj_gҥ{x4Qr녩UW O*|d맨B!^.כÁ,᢯% |^\/>RMwvٳ=uxVzX Ru7HѼ'dn~_IUw g^wg'2Oq |~serlk~b|Ջ??FQ> -w\4e }u.Vй4q¶2(od.\gA9C?L ʧ4{?sn/YY3=M?^㷟}dYt4qϒm?\#R`6[,;\JMZc:X @-*3k˒z97ϝ:;683!T޳}WNڹ\oe Dɒn&xs͍ʋ^ 9[}_Aƚ^KO~BVj/ ]]K^#~>VvOωC+B"zz&F4d<ДZd,,AO8.9ZFj)$5[9K%}*Kyk.vz`r=E}fmuьq |%Fow/\>_?ԏnmcvs\BP(˶諃uXP q^:z>6!pPܢ]#׋M-FdH=հ2j|XեzG|1nZG?g!ףP(E\lDIR:X0#K\obsB.QmV:zM%݂S3UXz7́A :=͕j ͡a|ޗj]/um>󫚛M1ynQy\2Dq7xSCWwO4=տffD,|ؒkM]=}n8*33zLEN~RZ~UWљQQEuVL .g"l~lLWml#O)j#uBoi[*ωoFˆ >Ǩ4-VMZfЖknY֩ܜ<lKPB4<*;{{WxVy5"j qCL]'y)8;7C/ݥLO[mcݵsMY4ZfwWnwשlַ~vg<lG^ cEY|C$uVNCe:#"/mջQj'˪Tjravq|SGu?Mp"ףP(ZdxF(ڋ[E_KRE=Ս_zwdϩ9ͱno᤹J.d߯O,DoOyg #G[I|E1ҩ?|JvH1S77-V3]`77{ޣXI^5&Sdw Y ݙr3۽-"-*nܬTr|N6Z@j㓟4M2͉zA^rzzst$lC`!.gMk蔛z8{ݦw遏!Cdz ( ܲqi:/'="VY|=sNG!i6OA3ZκKgp2uVZXSӪ'?3p&^OP'rGԬ;>(stOy >us6ݼE Swlگ|>/j*S]#=X Q&u~8q|',L944[8䞔l3tpNa?ΈKիOY՘Oϋܘ;w׆#v-佁5׷mIB, 'Y0IPd,4E72ݳ'[T3tЙgtI%>]7ro Ì4uzƕMJ)H;QόuFȉeOtF{j_ ZKn@zvo'0 (juB?ݰ3Ԕo~!$%zek*-o6f]}?[8w!WkNQuE}pOyٌ6'?aLuޭ]oCD: Gsno[WhN(fNCQcw"2 Du|u8\>w_tMv=ze.Zњr;Ŝ/b/`|Cf#tɦ^C']im0HjKG߷$NvFIg~b]]~^"1LLzA٭ex=7r= BYyڜnM6E_KƢQz M|'OjF;dǜ'=~)ay!7Θ\w"MLE{JϏ k3ZRS~8 wrEiŗfŵޚ 2jy$e!VfX!=ѭ ]&Џ?e%BWo'&zg(αmQ>A{o)5j~^'2ÍYwP AT"9OIw*ɪEnNͿ_hdgifG-ݖ|g`Sƹo &w33\;kE!X?$tgz/(f6{5WҶFGP(PڇgT67-q^(`]2Ң7iDR3ǐObO)CBJˊ~K݉`IRfߤvS>}sZ?;V ޓ;>hIDAT`,gijp}nɢyO4t뗊h ňz~uA5B,ӷWEP 4`(4XN[(f?c445KBG ?_4+,CЋ`BzB=Qd,B+}URTnWJ=i}n=[3 $%pƭ&Dm%D]4#D6#ryiK'^yһ)GqCQzGykv)<x{ѝ%YGo)rTz~MANckUHz;3^%۵f_φy4j6ްKf64'~ɷ#:[>1GyWZUtןC^GbG0~d:#u3MOH^9 |bvI N +6n׬Vè^q }f=X(+~x\/h/PO}u.՗d52GejoYq mz, .f;>\(O%=룛G_'C &rQC^GP';#u _Z\TJJNUlܮYUV ,8sH?雜WXTġ @4 (JNK %\B=Qd,FAB=b]"b4Nݯ=lq~wڮi݉᝷_pF%z{osP$ËN]Hћ"4ј9s?#<Qsf΄ w7s&y&`G!WwxkփdGTY@a(*8ho'7ͽ諃uXP&  &\$/#o+yTޚ,4&aS'dW Lp'tNuO~lCùqN%>}=} w'dGtXζa.>mp&EһsjZ>n|Wp}c Mc⯐0o7o:ay(~yvZ ѱU'ΛO?-s=u|팎kP}Q5L5U5;t,x; _'}ەT u_T'.tR=N@v玶 G!Zy;}U';KK>F#1S*WU+Rk5}}ϲu"حbj`P9{tBwr=3UqgJnѕDۓI`gvs#'W/(kSmK 0WzRWKGKޖhPڣмZO83AQߨJ%V];;bKf:7Fĭ)MpUM>~.e֪ 've1썪lG.t5іM ? G!ZyshtfT{e f̗ -<2]*]< ku>ix:V7ƺ'dH޲op!ЙWlͫ j ;'x\Op q#яm2Ƶp:Y6)W.gCHwi3zI U.(3@a(\d`l"DLe\KtDt,,r=:X ;X$u/{Y8f,4r=:X 3 X/3zE\sEG,碯%9>T7`zr} r=+__ Af0Wzr.`]23QrrIg.ћ#Mdr\r=:X L%W}gF'Z'`BB"ףPsWȃ~sel /]'|Mh91v|>;6R9;N.k{_|oGOO]g'x|-z 7%1(\dsN׽~Hku`(9o7_N-T\SPkb=7]w_˫'Qt o._ zz'[\BYE_K e;z.CN:;D`n|/K3 _><9jlG_|D|oևͼ [(\d ލ6}wF~rK/k^}L]}r`Hk?o'ro~7}VJ`\BYE_K 1^OFx/4rI SG<nј}pz?QS? Rcr?~˞WS?܇\BYE_K |=02zh}9|jd+Ojo4 +Tw|B` .$c:ۯ?pe^}2zWz^\qޟth\BYE_K 7o{zBy3_h1+m=S:]7Ϟѻ~T;7~BX>…w^|C>uv9ѹ_i8:λUJGڹ5f%G!cŇ/^Y|N͞?]zr.`]2y\2/=4e=k/N\OQ=kG[/Ppկ+o[-'%?}ݫw]g'-2׫~쯽e`. BdG!c'75̶Q(˹諃u M)I'#m7U NYD"UwZ`7.2׳:iPĸ\q4(dnzj_gQ(˹諃u=_/A4~OFNBE'hX1gG_X}(dԍg'nzj(JdWȃ|z2F{4:x* 9ZÏi͘>vs=G!YmBɪ諃uAr&[e(iFe "1ֈ{/j&n'mErߒ&SQ(Ȣ%y7mxF^7*{~ޗrțdPqb}2zj7B諃uX`Yl[<挔@*y3!׻k^7ïΛVpկu7djճ9%R~;}Vk1zIQȘl.bܢ+>^~[l/wQ(˹諃uX`:׫[dKE}Y|9FK̮Hkt]oU;gk_i8:λ}צ6DgV{ :W9 ͇;*gLB\O|#,񹞜(\d,0f/?q\ 9/&/T΄_g?/w*{63ī_\/y]}2z^-7bs+=F}.r= e9}u. ,wZZd/ϵ۟Jx^r=+\/nDz ڗz.]zr.`]2X(+'|^╚"m5b-_izؾݕw_v׮c--?qļYƺOZZ77ܲ:{6U4-hム~sK{y_M?Q"ףPsW뒱Bޚcr=2,,&gis[%vgw=}WL$WtIXaOE0Qxr%(X?P|N\{ fbVغݱY'.{rW(^qφuX'\/'sEUD5lUW.r\/T7/՗w⣾{駬5w?s,o?;[t*zr.`]2X(SDZ'1TP_m`Uxγ79J|j6uVܻh!ٌGʟkiix{JMw~_9ǏUo{v=yǟWS_-=[{j@'pHMuު w.ׯ١]lYbLvdZB?,yCrRoQڬݩ{NCoh%#֬)~H.ZŔ2r=#'́|Iv]g'GzF(\d,\/2dTq]3"PU\76=iE:KrcG}u\Ӈx|q=UrYcFd+P#|ߘ)S1tkv"'; OwޥuK3zgWUm/Zzc8^ɺO'T@a(\d,pYTұg5O+Ʌ̳cÍ76&{U[l%resn:iVzߞpwV-{kr>-cﲖRTݪ#To%۶Smޘzk=;Fd}"52^ 7X#B7rlzzr.`]2XLӍoYdR@i>Ȼ_?&jtg gژ@i>V%f8J!}CBbr=8@wOj{6xD?_ωxtiݏOCyǹQDKb2XY5Љt)WqE ^&ˬ;:ZjEբ;u@_7r\sEG,碯%c.5PKrW]}PsDrp|ИJ|tGVoSS7xܗ4C c;;V߇{a&kywC-ib\[fy7ג%Px.g0]uC}f w\s/pgvZEH4 (2+`]2X8zh\bņgYw5%*|"[*g eUz?4on|;^#z)x9}ޭkǏX3 gHYzWGP'e>f}ۼjK"B\zɾCՈI r=k'oz!q (\d,ˤ2>Se ̚ 4Y.XɅ?fiʞs6q2\W1n\τbcl[75fQl2 0;#=5( Zeީrm!r=}t6i@tᚢPе%,[uvdrr=AGP(e[d,\F6L}|Q\gF Q-}XgGXr\BP(}u. ,"O%UnȶBv* {{cO3tb+R]7Vo'Y\"?X*jsB錷*S!녋/gC7btG"lrkשzڳթ|Ū\[\/\ٙnϲػ>:}ĢY9^2X6n@yTDcz Bɾ諃uX`H}mEV$X4pj|$pkڿӖ&栗&'mj$s'=t555/EVmmkwՉx=A7Y~ѽKvUr%V s\zr [ƓZ}jSEzMh_2"׋|r=\#ףP(JE_Kr$άsvvGcz Bɾ諃uX`G˥76WS]w7tBP/`]2l,Ra Wcu\ gzxQ?BP}qi뒱tgJ'ȋ!r&i71yo:s BYE\ĥA\ K z{ۯ~+Q( Eq9qiȃ0O>ꫯ?t( ̊ L 2\(F B". `],1\Ozё3: B,".B .O,8r=\(+a}-}i:כj./oRMr8\^r=b{ßZzi'?fY^m%o8zzZiߠWr8zEIF7{o5tX-\OgޫXSBin#SE'l~Q勰m>/4\!,NeMVܕ&ۼ* %#+V:?3A#.۷:㧺 <7E/4b޺կN\/ ZUډg3Caee}N=||vZ9«T˖c'&+hD5wn̘,VU>VmC{esBzgF'ƓQ=|r/zۯF^_Tҁs盶xWt?Z"=1/uDM2F{ zEdb/"\7.zߩɞΫ~cޤz I9vviv ?El|׹ &eN` _955T8|R׏:nodyrXD:3$kZ|ù^NʘfZB{F:3$,wvkXh5wj|dƺv_?rqqclj_vcDW8 d1[R;⋃w]5>xI['lìdrSձws9݈;d4޼z`2@_M /P{)[(KTmsHXhvGEU>PJw0[Z4l.c"r=Z yAh~;X^'P{\益ԌfƁ̓~: m0HݺxMwT'^TZv^nA {=:}"ҷvZrv^lŬqmi-\9"ùzݩdr=ѫN%V7j4+C':n}Tvr=E9H[ջwׯ?e|'u}ۯModdR29B`Tme&yؠPB1R>rՊ{$cM/K\V ޹i$yҙn3DK6{bHGmz;Gk=vN%W`/z?取t7՞:55wyОSsou.7O'136n|Q %*Pa)Tb6r[G} }Oκi<*GZ{Oxr=3I #:L!\/MM!KʸœWeu*oOB]}:fc(ϟ{_['3+EdgB@NDRfިG$[#GݩAj{=^-$Yh)oN(*R/!K[t cEz50aZ-2BR- s>j&s`?4igi6ҜrdM~@Sۼbn7=骼)OHB[CP #'dd"l.\/StvRUU{^cE#}v1J%,QALEl6io 0磶Hrr}6lnT2כ-~~sou \a oB=n8:#1__}jh` :J5#Q3$,\OG]qq~wc~|Z`jWZQVM:UW|̧G*z3H\u~"?a>w֩dFeF5ĺqYz8q9DX3eg>jXMVQ~3}ޭ+Vuwͳ)`҈$4-1sR[Vo֦a$/ N&Ryd:B\O0pd1 9G47N bVlhWwEoOREUBEGWD+ʮݫE@g2v, nت>nSB~tp7֍eK'KVt^y0uJ3f}*e%?z,ņ;Vy?VpeUJ@hR M i29(DWt7&@\K}boȐ\,!215uCO;gML;Mϖŋ%LVǢ'd/ѱ2',:059jַ?vn 7<.o8#0[eE*UON39\TDg^^5lwNÖ.7S)\/3Cᙳ]6ϵ-r=gj{ufѹߍkΥJvćV;8Q4\OHx@W>pBr*WF9Br=\([77Z+/jz+\oSkzZ.= _Z[4P['oww.zeW5`>[um/49XnK_jo֊' uWkh}z-}cG:E?Z2ܧҽbGW!3]g6]X~'P'._x{`xgC)6jo{\90 `)]ЌGҡS4[1]&[z`>r؄Mޢ;xmDS +Ƨ\]JwYP6qus\\$ ҡS4[]B |zqwj[zc^o{{E%?)7z, `)45Ӊ >z7́A :=͕j ͡a|>j]/um>󫚛M1ynQy\2Dq7xSCWwO4=տffD,|ؒkM]=}n8*33zLEN~RZ~UWљQQEuVL .wBQ. Ύ?MD򦨍 1n<'vֿ13oo.6zwԶlZ5kqDNWA[vܮfU[[ssj-CS^? ѼlOW{W{U{o:c Gf:eeoZgd}57{ޣXI^5&Sdw Y ݙr3۽-"-*uYߩV\'mm'?Q%e:tzQ΁ґQ6?n|SnNv CdC=Nex ( ܲqi:/'=w-4nhݣ88PwR= LyR%w]ҟh<|jeEVzQG<3=!"'VO9{SGծ2걗܀z5)\mlB?_" VY'Dnc+>oLM:KwmWQE]Rk;LC.|K-ڙC.:T،uJyC)')ߑ-{`Vq>kT}x9~]D<;sy|p28|iGPZԯk)? tg:S ^m-#$gη} ì6w^OR'\lUKY٨}yg;Ͷz"}[$rRnw>;`_sO;j%FgƇE! Łsޛ쬟lXsؼ@.7wr p,L ?ό,qj<i.mRJgkGj,旧~'0@ ^swzÚnEw@",A>fhD/%. q4=R_wz)i7Rt7@wΌzdzDo N}@&IpWcnOFka1TW`QGz f|dYՄV[jս_/@u)}Y叮9ݪGՉjt 8=ee3v; Onu?b:uޭ]oCD: G)\7p_7[+H4Udst3 =MzݎbWv "2 Du|u8>(sFܻ/vͦww^^97<p@s$y_: UKt'%Jzu \vͶ^l #ի. |ߒ:&q9Ucqj;_$t>INE^9Y-Щ M=x;7#lvߣےo,}8בB-S;u3NfkGj,M#_cG'CT5㫫-:&PK[iQWOHy8nǓԝ^KV m3D%ӓ4=޸-߳I?&᫽G훣\/1jXc9 oLso^81oh!kSE-E&?[Ռ_f K`[vRANcõw{O]Mߚ=RKc ;q QoI;QBQ/#D6#ryiK'^yһ.qlհ VqCQV5NIu j.ZGwf(gƛQU5;!<{^[߹*1Cxc~=F:CfwBF6x"fD/v$*t\>1G /uWED#O:4;r=r`墺vowy$M'i,aS=<2ѷvEmp[gvB%]3DۋxkrB>* n2: w ErDgg6+'LQξH?Գ9#¿Z<9뙅-x=QH͕1I<:@",%&  F/ 5'Ot^7ĕ<* Kc6<~Bv5}t= G|Hd_dž;O["'}MΙ3߇pw >qNvDl'lR$=wE ǻ1wI>4& p͛GCuX0n5=_;gݦ3Cag}gtsCuSO?$\O_h;6L/oKn [s\>3̅5;t,x; _'}@{R|'tjjOs7e-< 8UP.-@L߫;9G;WU+Rk5}}r\/IvUSWg&s3NL 퐂h{2,}'B\۟7PߌlSQκH_9%NrF)Sߜݨۤ"s==0S@l W+os?@!,%O6xҍ XEϰrEaZyڞS&w#>贓]4Ϗ 1f,{Ky3EIv'rPNquN8I-ûWٛ'J7`ˎ0PUrd|c&Rw%wˣ%o 4[(_Quh~ 'P@yj7EgswN8ؒMIqkCwUsS`Kf‰]Aj{`it{FU/uT, rL_ZmD CmpŝG;FgLWZ`|)#ӥ5Ӱ,\WgmAY|c{B6-kf[y GyּC}' g<x6 "+kjul0R\Է:Ҧ==gvlηE]۟7ZI~tϳ~t,vz5\I{i3>n0w>ֳP\3,=zX$u/{Y8 ~ }.6%\bw6wr5qvx>eF>Q$XO6 )t\F_9r\#熧sP,+f)ըS] XG%\Go4u!r=` f^-%\ŪђΫ3#eqr=` suOeb PxCr=\(\[_f[w:nyf3ԑ%kf ٲ yIG9Bpkw9A\ZOLl8X!Gj9.)e~~H\ KKtl8izJrнI+YE$>r>,cŌc64'[UL({LܬEm_Ov6/mxBn.]' 6n^Jo9[>srh~גáN}/xxz `i G]E%{Qc,o=DgއqolL$o(J0 Ot&>ubs 6W=3\֭r[z2z}Zz Oe-UGliޤ 'e*m9!S1G\os{}k`Ewkkdn6,2z%&Ʒ,yd2qB JὕG}5Ws=e8J-1T 'mH ׻ 5ɍUu$V:ZҴǧ!VM%#^t#qgKjݡ1`ý]MCѰk<ݻ!4۷p`z+葃?wfV [fy7ג%Px.s `i G]KVLS3k]Pxi'lƪ% Tl$J|T쿹UPx뙧zU?b,!O N0"d_ߗ]rm[-x~ rUo &ZU#z{HbRz `iL!3\"ϬL5BTg5KsolTx{izָv#z&Lf+ߺ1+ʐ'gkep$!5lv@Ip>"5,NusTo \QM-fؚ%r=E\z4:a5;䋊\U*#ý*@tOu*PMn e%>-uF9fN^r=}-V[[[jQZEWs{0H 7,cBw.5c]o=ypwU'Jys7S'gת5;3zixlE \,/M9ZKC]bL'"ź; r=E\DD] w6UpBaFNsol{YbT*$KS~+CDDWTEmN(v^S\"QdضVpvW\tcx5ݻdwa]%Ǜ[bU0ze':x=j<9n)ߧ6Uުׄ%=r=E\ޚ:g DϷ 8r=#,-G˥76WS]w7t`iѹ^ޒ-%[*`_| `iѹ) /O$r=\(׻f}}Pr{wq띷jgM[˴S]+ ~%!ТZ[řGn} \U0WM s;ϾYX-XiǬ^"\Mg\?>;LX~8F{zݐHި__BݚyU3kz\ v͹U8/okls?_J*B% ~Sq͂n˫w$(hi`tazZ,r=˽o*.ay^hB=  ~Wo{q=P2Zyޯ]R;w>,MOyGՏvew'~?ȧN0zyToo=djא{=-A˺ylD/>;P7{hN;Zo~$дǴ>oEz6hδ`NvE׉ޥzr=@L{_z;Kd~MwUܠ^+[G|դdREͮ!SA׽_e29 &ToOݭvUQ&b>GU}͢K  7zcξcV\/ yi[p'aYvjUjؒ-ک7o&6jS +nʼnMmfVow-@nexTTvJ׎'La%m̷[*jq z7 |Mwra{#2ڻPB+ T=3r[=`- ̙+HX$y]U9ժ>UT\Qgsx[S7>xs=K+^κtv_<λ -_l;Xnvi$`yfCOjGf2ZJIZs{WM`k96l*YR߄%z}Ƣf&w9pO32"svsf;eR+-ULϿG|-?M?}0׻Hnbg&f-HȈN+,zؒV}C$/E!0Kڱn}W;BxS 5V$ ] t M0S#޹zQ졺s".C>5\r[KH߽cuz]/2_\naϽ=6B{L|pX( z#6? 9hjB=  RDSq7]\O򲈙%u}W>F'x$28I—=3˃7㙥Y5gY %Di"׋Xq"̾s8937W:*&}&h)2|([7[GpnsGIn<0؛qwMߙ.f>l3{=Gu^ PB1@'>pXMF$CN[$h0y tX !E{]'Vz,y&/'{ҟJV6+Kn r=I=F$L!^!q]c=ѷȭ\|غ:PxzB|.֠ŝyN^P]#r=@[EM3/s6"YΙ/ʈ$~,uɿ_忰Y^-d\ܑ݌_?E@+29=uU;kϼ$1CsȚ0a*,2BRѷȭ\)hPar:U-/pb^w&Iy2F," &2ʯ<B(]'pda瀑L=],ӻ@%fr^Ivdw\cMf}zr=Hӂ1=X+pG.*,[PKqF tOֿU08`y;'|qjxUXsFAG=d?Rgz7z }rЋzan'{MX3yϬfNla=#Ռu}sR=|v(Y1gSa1+RGf3k⯖S[ԿgWeaZD>z9-m%iY甑ia+LRYiSY2?i*#Hj(Q?cB˫ 3yvբ5{zϣt5qeCTC04{zXz;g #˰O¥)O{ۈڌfE&{Q&B{۟%ȁN륨dAFuUbr=aU@ tmEwEV~aDWDXs'9ZGmF  2K3'9wfW?M{V{0<:OG%֕9;.o{$?dڨ/ev XI tmDU XT(֯Zvw:pݔ^9٨A/hU5rW͙ejt[FհTF[.x@2`mY#ֻfhiƌJ~IiZ6g=z[T X=STVh=E]DFjMhssWB"mQXITS'99Ղ(`qS}ψ,iMj)_dJ0ڥ)/9yƣ?KܫVVckYE7V0t9ɋH X'Dw~0R(f4hcxĻO/I>1WV5w_ [KxG2UUoZzXƫ?{0X*_*XѢ16 X~#Be3yϬ/M~͝z_?[VZX0ŧT9OJhVKK0}Ug̝W3x2WL2#4'oٰY`C 毞"e\7K[aƝ+Y<ᩏwNV=榎\c{6G-XAj֋+F=|/:lҲٲBs,%\ I׆f̾]y@{ T+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+D !@H+瀵۰Vo{.]Z]ˇO6o?(;Ey/t. X&╃M^=TBxDt"qXg.Z~J~DᷕI@'ҪA#7xU+N-|{T2S}WfwM'+3hg_XXz3Lb-&]XȩO̚ 2`}tŒ'pVbQ H |eV0=Fy ._[_Vj&%$``‵kRM;]}[TK8`}ճYc澢I$,`7voN~JC OUmw[ I0 `}`ĸMZi{׳r:/}/[Ubv֬\HnsT--gO,Sc1٢*+?-X3V{_xkR?N<2-o=UkvqUFSޮ;,|uVTY9Y)7';Ś[G M5{TkYk mbּb{f(sy6{΂@pAnÒN~V/$W:wډ3]{護/c¶Q*Od.h:v>RڃǕ qdg>Z Ϙ|飔W)x\+7vJm+8IN4[={Z&%i=݆%g4`M_# qfυ+T|d3KI6ԪYvRbXl>qx/ =gįJ8zess B3қμo-ͽԑcAUkIe3jUJREI?+OgC OЀ>T XgR]G `sa| J(X>;gR! V~BA~cLx>{yɦݍ GO:wۗ*Hgt Q4`猂UyZ̨J)`zw KV*DA OЀ5+׬qSB|%?`.\ĚcLVjt Xg.\eEaJ/w]gUO._;y'cVYXD-X-;ouﱓ i7_hn+J+g?q撕6VoPFS~s5+YZ ްFLMUĬy,|'K_ݨTp{ehg- XHo:8 o8>oaGNXKB ,`Q/\P\2V{z'1HyqE󥏬%!`Z3hYةORjF7sM;K][k_U<:aVe֥n`%f17PUpB^z̦]\;|d Wbss_W<0b\VM9W XOrg™qK7jId;x%UO_Ъ:A9YLJݪ 9o+=/+1Gs'?kNh5֪=2Nu X>c}-Y{-̥l~11Ţm [kYo*aѓosߜcVcTBvgD X e-+5߄ K*kzAsi**au`ſ<#'޽xEB ynSiYJq;}kr{vz*5"B"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $VB"`X $V]6所t82)߿AUtRbWj\d*' ą8X@g'ˀh5!*xZV4ąW+do*Hb],vRϟ삕q!*V)QhXh<?xV.ą8X@$  &{Oɻ$'ċ8X@$  &{mtV2P `⸗ XX@g%  &{mtV2P `⸗ XX@g%  &{mtV2P `⸗ XX@g%  &{mtV2P `⸗ XX@g%  &{mtV2P `⸗ XX@g%  &{mtV2P `⸗ X=ۿ>;j~g/߽Y}s `L7B$8>3Aߟξ[dX@g% u2r/4V{ړ᪌ǽ~~97v F :+n(ck;g*2gS;6Z8jqs$!sW?0&1.X@g% udZ6F-9Nq/edzeaΒ]\OFȻ:XߺxژHƸ `L7!` ҜRHB_N?c:>N~pFTSR:*`AOWv_ݴGO6^oX˖ڪxT$Ͽ;`7W,~Ux:c=wi,P*+dNuM5%keX~XRipyNmy)FZ =X}D4R 5鳌o(/)Œ*jbNАVX.nWΑFkZZ*+e3_-?.sؚT`9t{2zWkq/wjojUh'% 8L3xgM׵̑sXk(Yh沢FV³k^俌 .}relZ|JJaȀ-BF_٣QxG^Y(iP7Шm|qfaFbV6זJ|mwTGs2k ^> CwiahNcSqηoҚS&pw٪-f/Jcմ^[UKrXso?=Rkp7M 5y]]Z'`f_3ܕ]*⎀tV2P [O+Oז;lafLG ͱMdېv֦[%F+QH5|1YȲGmvNscusHr2Xth-*r.\ËA%VwL++#OeйK/_D'3?} jZ 9}|mT, X|j^k ¦ʝw>Vgߟ_cNmNXUH_W/}rEX@g% udxӅ8euRQyOU"Z%["ɩwd KNIm#uT=I;oupEYS*4l-=mv X i!`U^M=GgCTI :#tG-Vd* > ck?%`jjMYN?5UstFOVgKl3VYtC)l w8;`L!"D)F/OhFJy;r ͵sjja֤ϊBjOjMP[?g6hZ}Gי?Nsj~ G[.i_ŵ߾|5\l2z5<2P [ƭ~]PZF׮WVg.2`-߇m3sEmޚ|jm+ ˕S9}[͹uɿ1"Ϟr{W7gdKl[ڻt]+vY+;|~*e5{ln ]{LJaS|1wy7]뵰5V°Ťj33״ǥ՟WdלO~r Wf W +W4Y|GXVAxkf韮5!uؒec.s" ]?֤ѹtC)lv X='u|)~RU1$[kvK(ڪ--7_߾[|_g׌rFwmuHYfj~kT-j\'&`h_2P ['Xz~_u_}|}QV>ӏio/f@eeѫ+VXKyà\oҚ)zZ`=!J~,=-}eX,mkq/?!y ÈߟظN}׊W}3֯/Xͺc1ILŻZ&{z;`nm1frQ?_963O|l\D\EVv% uwjUkֺ}}u|Y/7KrGr{( Q 76ڔogyR73徺-3:x_IΛJ_wiW?G\Z2_Vm5ͷ(-mxqqX;v)ۜ]o_ը鿿~tWk¨%<BKlo/طg=˯>nӎHS^Fg⭋3Co9 X4o[+Vkim? L͔pXomUpFJJaʀ5iÖWmڠ$|\7_d:C /UpF {O('VбtC)Zn޾'uupd*' R[++d"ȰL) +N 7l%`L7B$)< VX\qjttV)" WɈY ``TA) 灴瞗lfRCUH :vC[RN,9kՀyJ{ tBcc}P)75CYYJy8i1A+`uӓV[P7X@28cjr8P)KBOͿ=ؘ>=Ͻ-fԀ \1%My tJ?rxrpmFpuhkYw- ]z_+/-nϽdP\h۱2s/ ^YE[ƑFbVA : WzW]wLKg&F2Vt4t|zt@g c%`/択 "߻K8X;Vphj+ X#9JG R+V- `pSk$cUQ:VЖFտ"`ę 9JG L櫂+0D+A|lw#VVFbUW2տVMy W5R% `pȓv#OM+hV 8:nNy[Zy37TK&KN)'HY[gK1},j(yuƼKtzmG?WbM^̼+j9)9O|wdG䙱>`U=`5 JGz6W__+SNYWsn[M]7̝+k0ϗ.]`qzƌ 2uaFY/ ]>=+K j/?T]\0%U;'-X} BWz yƃm:^X@ B^=Q[,y7G7,LΪ9+Mbek6.}~m_yь-8X0y悴š#G+&mᢱ5Z8sތdwKN[m y(6#͖͵mǟuVό]LW=}l+Pyo}u5%`=_:sSVIj{(`-_)9/ZOXSzDn#Hhc(2٨ X09_kêO̒Eo]fUX X@{ BZ=oKΪ9)!``ŒgY}ۦm;jkͫ" sf2WTzz䔍>oZ[5znw3+tU<ά=`W<֟vo٘n9sĬgj_^W2o%=Sg+` 8.U o\Ґ7BFrJ}s١SnQ~3??T@#~ 4/Go˹ bk8_Ye&ҧ`G:MliymD yΚ_TrzUSͥoEzTm-|Y]悔yk}k6ft]k]$w,K\6Y=Q!wQ˯mrgW fW9uaZ~[}#{Jn7 6hٮ>\oYc8X0eQQȫ7oXyp-]H /ٞ1wu$ӓL|ic~Qf B!@->ZW'\!׎n.fmn'~>uM[XyŬj*2Y[OiS0: MeFV16rmVGcxU[6eAZqCݑm~tk~qg{$sx?f݈QU+`:7fo͜JdLoKFI5|e,yK]kzʯڠX rϚ%{[k,RqQ蕨*1~}4Kh d}w]khM.Ʈ<-;cd<1/N_n Xu*h6h 2T=Zac켴uFq+d;z/צY,Wv}{c~餒4_Q5|y)Ib|ǐO=}g%lRM^cy}- XH֦81Ǣ]D}VAWp:}sJ댭 7G:مB=` ֑&17_tXe[ozbՖo;xxqfV-c%`qԢtUG_XZũdjC<kk ]]Tavr2`u.WĩT1o~A_ MGMZUІӇ S}׌r}j6ߔ7̅sF_xf,9C̚tV3c%`m!DjKW;ZzJѿjPk)kdD2;ǯ.˗87 DI - X?jin1ŵ *}k^*˴q~WfI[}^RW^46X̍(`շ^Tqfvm5uH+-Wq_U `櫂=`O >ڊ3drdo"-nQk?`; BrDcE}H(-[2s:FR1=;BC;>X=ʽ XZ+ڬd'.ZnaO׏ls# X S GZsĩ3U ^2`c f3e=,Lx̼d4s+A&VQj9B7.5T;,r8"*Ku󫵞C *}~}cG`NFs7G-/AL 3=t;`5XSIVO<5[ٖASkve7;=m3&s# X_ԭwHC\o\2Rn4Եi XVZ Zj}7+`JCFʼԼ7,ϙW=ڬd+/M]VXS}fcڜy3e悹pAZqCݑyn[i aAEoK֗i枧u阂Bo]lꕨ=`iiʲ=Mu۶{ y bS7Uo[[gĩyKwdiaĔei`ה7^X?x:πU|>=ej?xYDƃG`|qE{xzqD-Sچ]*Vбz#'J*8 5_:@w4,BԅeM 5^py)K7VqEW ]k}4`sKuG{F7%/i]虨F]0J圳GbSLLEyNF_}ܶ) R᛼%cЧK[獷lȐjĬ+`;T`>Ĺy{./N׬OՒ}˲TP@CyQaԍ,`k\3Rgn/*yI>DU ` 8+`E8S> +TAkd[:vVLW X;7)E6vi> 퇡OU `q"`M"`M^֡mw-کic|9)k;@ f?@ -V3 `8F XVZ I#`QYVX$C ÀU, ZaJm:v@ X=`r"`qC XVX$C A| X\V :- XG ?H4pVXd XLE ⃀@?֟8 `h+hk_V XiP>S-wȽXݴ2I-ڔ~](w| X}4tFٹ\WNREX<Y4. tۘX{^\JIdWqV-X}ddMճlM~myQo?3W;jѿ_٣RzT,Xm]/)fxVqJops=\ss9Ab7z)N*:^ޞ:.tSMFmz>{!OޟD X\A?GZǾrև+[DrS9OӖ_UnXkO7V*쫾ERZ٬5i#W.?Fض:7ebJQ\6榥->DҡN5Iu&nm(էЎiWk۬];:wۘo\w$$`7HKR=]jT#`pyԤZnE]=]t;w-~8^Mf5:ԩ'WW5Nl 9ocBEV5atuWڻv5HC k&}]j݄bjc֔IXEǾ yKbmd.hVXCjnozr Xo*}XCԟζ6&[de XFXY\K 5 V]3eiJ#Usrz$,=|~QʳګBe5t_c}2zfjCQ*tV5Aa~t}V{XhY55~d:67bnr)RUcJkg=[eyry˫;K?2i-2ru}&:*OmVMǼ6{o퇢NbM 0b[r?2/\yd3}1NQR˿m y\\4]쎴|j/X#r?<]*Ѭ[%2v1>A訧;/tiQuSD?մSiʴ?=BZZz-g]ǃk'1խu4mZkq4`jBgӝP71L Tl!\uJI?)ɳ=@:'l}u ˘VZ#Bl.Y+JS% P\Rtn-'k w-~WJ`qs֩S~ި?`DFkWk]+|q.{hկCwinh=^S[h^ڇ7nشKo,6͘L1\#hܒ./(_Ny囷l^⺢*ޘuR!7v/Iy\!&֤aTaIUbQ6)ߑd[j{ Gy|Bk{$soNN"nˬEb5hka:@wugh˳U,E.Ϙ˭8T-j7@Jf0+`yerc#\-ʱ\]"m#m`5>bW6>]K$Fm&HP#i$S[[̃F^Y_}Au)싄94Mg!92޴b5xm7]f-ȃDǚʋܷ8,?#=X^9QOw^lӢ4ziɧqd]ֈCQwAWyZ^ S8rx0>cө6tdΖOpċ 7N -Z_~5NϠ,1? )>]^l*%#ܜ~ӾWJ<̓X:*FQ^Xׅ(צb+;tv!w6cN}Z xq媗@;3IZ״U6lq0-Ffx0N)2$ҙuq]\bl>s!k\ܢ+9xx}Ұxp'k/祡fM'Ab`vEYXkwx]rd'͍]S{t 1- Xյ6:BOyYkj]~ ܧ9IC#ШF4y{qSn}o\lk;RkYd]ʐY~G넶̾uQOcr^=4[*YOf;;\kNn~vup|%QUȀUL *`4E4]v^_7JLN}q=P%ol`~u}J rڽHޞw*׿r t^e@Z/y*ڠt"Yd1-.0>1-i ٵ9`[+eNSn=5wy=M!{Le_8/*Q{Ry]5j#܂:a|!_٤CTdW`kۣӅ̽xԽm2n-_;y{<>+vD߾[̝{{="mkʝ(xvA賫)>Z_ns}v"Z.}ck6;݆ Zhr⑛Tsb5]'#Nd-'4tG٦GiM{ TfMBx.z&5ùUBBkSL1Z~khߪ\gML6ƹQ-ĸ\ x[O;?PgHW_Y~!nnmRG*;~d#</v/d}escw5Q߭/Ab Ze#m|$ru‘⓲Uk|m gmIXk{o¶)gڂz+,` jW\IӴi}Ogv]VXdo5`~-i]n+qM<-w5۸wd N5v J FCqe%_jӭ`ť`Yf{ Ȏ¨}khdذ6ڕ{ŝf=#׺ȯLev>c)?嶎s܏#{D).1ִּsICs hmVک+DN[l~z攳!9%;dpG >;/tiQsS>a`|pd|݇(CdSgؾ; 3l2&>)&{qU &]OV/r]~Ӿ}|{5mّ%u]}mIQ:%G|oPv3*#cV/41kcF˓ 31JwlQrJG>r!kFwDjʏFcIEU^hE6ZenU!g1oōUS\W@OTӒ-htZLomHKdߕkəT>G>ߨֽ^unV*&Z_޸TlzK|+<+0`5. {&y꼹]5"1;l5=y}u9ʣ}Gr_ ziWaU^ݽqS_S{tv.@'=?yᗏF]-swQ|;{Ol斻j/dt+rrܕֽN:_CqبM]Ͻ^fס5@fL=HivKmdle}H=yqa|/o:OM}MŞ[L q_h JlGkfM`_~M7Pkߕr9N8z>\t\wVۑ6 R >k㢟jt{^I$P_N >ڂ=3S&$+`Q{r5PIkv-#Nqٶ&Aբ1vG':̍mԔmjNy Qr4/kh_I_pw;Yln ߃%J0eNJ <Mm;͒ng0 kl{$Ԣ^O%}}G9\IMXе}?B; \2\MgM3\]6< ze {ܶUc]bu^Dsh pKlAW(;E_}Eoٲ+FYxSKouAW=㽾B zJT;}V^/̃O [AOr 3e ]JϣZ81} G>-{-zy8h xd9զU~4|W_}E6Q<;Nղ_mT=`=H`!JT3>MVkjEVg( Ɣno܁_W\{;>e'-X‘U,5޵H:^ʽrswQ|;MSi~o/Zel"y{qcл:!MS2Ԗyn`2e٨9o{[Xr|% x u#Mr,qݛ!^kvb~zֹ͑c4E;9ֵhl} 6ZuAfsj&i<Y y-%lpn SMk?j6ǼIk.ޛu^ =ljѮ.Oj0Jwp-dl4=kR}MٿQOerJGNymj=%A~:rRn$%6},>NnIq^1-,8h>yޝF_hO@t+gqyK%e^גu6&x]+ߧ@9h#;)zʖrU9Rn>v-c]t\6`]fD Xf\h&2VfgYqU]zhXs~zIՔWd&y'u<|ގg<)ޫ<A*_9%*gX́ʔN`jy󭏘) w<뮼.9Ry_w5O,ɶ`>wV': 2qC\k$sbȍQ;ڳW;m.|M}iRMXۋys{Sm\}ȅmvʻ|2ad8W1}ϚC:f5+rl,{=O#r \=%)^ɾ9ϵDZd'O7d]yToӽsK}ݕqB@\/yBϷn@K=/Ҹp 9Kخ}n5[W41ivw{ׅe89HGk;(]OJ'zyVldd?ʛU3_\呩weD9fHs2vykjd_t|~c:^\8xoj!-DFo}Hc^\Sv=35h֔eʆȟ+"'". N vdx=]S6ӫn*k}L6ëdžܤ1o'[+Fm-]]kS,Z>k(A~`eF>ǒC^3\<erdzlEύMwJU7OqtVUE`ʅcߠ_12QzX?Rc$[Zr[B?rm)z ׫Iƭ46pg6Jɩ 7unDQm@vǑ:•4C vX+)&9o CPZy.u4R!+ X}&ѸH]\Kwݝ,*.Z7=/wC*/.l5[-c[Zyym(+v 4WiW5l-7̿- {X[]kv+ذ5T{IVP-t\Z+3q_'-Ws m_U}+-vg~S3N:a+K1`>J >ڂ Lc&}(Q2fUMP&-~ڹ&ƣ56iޠ%_+nF,㽙3Ѽt5]\Kw5V]{טa͘=mi彡|ō;uA|)u0 TZfjhS8rtOkvc|_g-6Qu=yNNZQ|sؖcU}IٔF5Ƒs{j7хnn.v۰y/qjss2_W*{dfo* :* [_dn#`5:MhwҚsjF38"v D`xoXk(FU3&^:U[ uằtK[BYzbS@J*-Y5v<6M]5K"`psqN7ۻ~ӸtUصg|U$Yoo&Q$`z$;YkʪǬ?YXY ֖I*ZX.G=>j9qH,*nicSW7ʡjҝ7Yd`/) Ͻ-vP[8[G X])j&`~ AyI*D-}@C'*|+;,t+[ES <\ڹ"DՃiNUi`G k$&krL舺Z6blcV56U{X}G:AvP[8['1wՉOZ?_ V &~?.*c4X! 77GJzAwޫRr { ERc+}oޑª> `&֙Y| Y*dykl0mSSO~QhW$*/O1ߞzգs7_Tic"`F'~bVoVn0`=t(uA* V &쵅iO?YZ-xU+ Xm x寭DZmK]Æ X4tqdPWD Xf… dAj,l`a1F(|xhA OmRUm-po2jN?,m!֯.ӟWwZg5XM(a*&e"! ?{_Y>خd%_䆝FUc>~΅"nˀjG=m}&7l:j8)U]jO @+h7#㒓'YWW+ƭ=eK>=:Yk9YWfO,~t p2M{jۺ TVy,u@w9fx&}ƌ\~B.g6TUC̢ik"/W9#i3vέLȫI5jkv.@ 7`ޤU%92zUcFZq&@.Vj%sjKWSky,V^23߸H[-3V[Nucjey>Sj"`h68{v2D,K7*۷tk#`}X4wmIawfhj}n.fa4=m.j.]뫴 xFX;O ?V&ۋv(sbg^iq XeCڪc *πU&UӬtU'a+#!lU*Y++X$]?4QΒ5f/V%\V}K`5^9tTW*۽ggpdIJnw+1H4 XݩRZUS+ʔfQKSC )y:Z-K_>+`5;aTSTπXX$xIie‘U24ejHKΖ7X@c:6xSٱi$`CXπǖ.ҨTpx]fW:lamvS/!OF~@ ?V&g*PmT# WݦerXLnRTzڦ[FWڽ6kqRϠEEڤNkJ ?V&-X%}RQi;ې1{W!zoڰNjw*kcUMX\M&!]iM2~}X.jܾ}:5%`+DǀyezK9ZYE{pv[|V"54l-.KEז4ֈ9o[l=[_zX,FIZ}smڰ5Ԙ UZ֓V2kx5=[)+X$x5Ed[kL r%u=3ҊYwf% 2ȕl#3b5 ZQf '<>+N D5n>}X r+Y4}Nةr FkJ ?V&k|X@E tUֺu tRMXx@F t؀g}\~VЙH4-`ц/7F:G7!`ѽ?E7:?1wHT-`i_\:DXDU!V3+p+h+H`V* [.`XF ͭ d@#` XlDB ͭb\2lXij牍VZ$Vn?`rѺDZ ׼)W]j+z{XڒE|ɽO,O Xʒin%6Yvf?3IvZ(>;D+̮Ub'h%$Vn?`Lې<9"S"%ɓ\w+ϮOӳ-JFV*+s#mc:+F5s#il si\QwΡO]/!vC'L5¾x,`=ZK'c-IXpw5RD MB_o](ཱུZ?3u.ofwJCmu\#WWd'kMY|$ \|]oloI->_!v]:KU׮jU>8X?ؔ7t=֬uTѱ{G- >jy_\=X6PYn^٭sżlMX@IAdj5h?/_#SU/< }sVYϬ\M>RooҺ/ꓚLQ%@KÈ!vhkpDZ/`FrOY.nU]Q`{3ԅ4 uMWMe5M_Zٓib ca "`톀5N<VZc̒-O蝱_m7E*cvJzƿdZW#?Ojcs}vn $<VnX#`4\d0Һ^^G;{o*mw;vTzu3}wXɛ\deC;Yd]B kx}yd(|"wOݹpU㴇e׫kwu69p1)Cu`ax`g`m_Vrg__\o+YQm u|CΦ#|lz.Wۼ^h+4|vhɀ!ݧd }XIU$:VnX3`iڃ"gFh6{5?=z>krt 蚟hw!ZCH>u`i;>UordJ3`ջ+$O'g9Ak+:X@Iujj҂oQ&Z>ɻWIL4)MD7L|>jhX,1"`i;QUW__[` b.E˻L{!{++?;εwM5HΣF_xVX$J{¤9,fsќHW>xhtg̅;8.*jj*2IOW1scuv5ښuM*xo7ǒV)RǬPmoL7#c5`5m.qd?޶ƒ@ `hnFZ[ߏjZk>o1⹺OO%F<#8[<*'V9NUzU;M5Ƕ6L-<ش컵W =KkzSӦoLחs˼zD^^-~i#dcҮ:_''2o[%m2 5Ǥmãf$[]m7#6ccn(wŚ[XX^#ZUoݻݪZ~?:guzcYC7N^'ܪM$;G~Ơ4dyNtR^Ez_F,zl`+$VIC1k꽶,kдy4 X%i ަU,sz- X#~Vг]@@ `hnFk5U놘U,zCx5t&2slIi黚vVG2J^&~\ǒK/9:HIƍp*^}T(ٴ=c<Dƚc٣#ӑ#O\Ľ.iN.u 6fFm.U﹨}vi5Sf7Wzw%zޒLcabֈWRUڃFh<{2ju!`A 䀵nŞ7Ua\i[k'Mʌ*+F'+ud̦ŋEU9[ qt;iXo,J6zHetSTj`k0#`Jo̐c++Ϛ$JJ*vqn^wmsvgǩW"`A Ѵsn?q@Ez+$V&1.(ROw(rd-c(x#`A ѴUX: ہD @!`EE @i+DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DC +DCvPߟ.O/Ly p `hXNޤzݽlL9_ER X$Vu}ӆܱe'H_Hh +ډ Sʪ$.VDv;_-㓵wZs>) @!`E߿G-I{I}SGJ0*ᭅOg_:Exqbی)m5\TV&JyLسsFU{O8aI?yT)O\X)hr^uzR 턀+iУR]n}dVi/4zl=|I˲k{=,+Ѐ{~=>6oYv^Ѳ?~Oe5@K5`CݮJ5$V"`=z=5wIK@*Q#\jo+g,_ 5meoLYG>!?m긗YL{Ѯ|o)$Xq#-'>[CU~~=n={~=*Q|SVXVMes}-CS ޞ†̓g?+XuEU{ʷۼo;OܡLXIkBb?eo{a}{Ox㿶JKl**?U+?;{|Ь ̚+~l4)l+{UHukZiRz\+t9kW<>;bQن vUzOY_2q@立 fѻgMY0c鶺K_*\\t__W7Ql{bUvT99˲ʛ.mF3 /e:/X NeᲉ)ZJOܸX<3Yo_^W^6w6 ,ݶo3'͙}8}oK{IWʂ2uz&k^gN^ɉKךJrm5s†ӟJ`5wgUZ_yFYo.ޖ!_,I3_ܳ5Fm** /ojNֶ櫗ktOፏ&ʛ*0CٶBifٞe[f|f颅71`; `mtJyt}?wg>? F?}e͝# cχGO_^Sٽeo=k€9l~gۊΚ>{{{ gصWTSQyobe;DMENYokNUIڊS%y??^wOr ~<`q&#E;Tm}y-{ drZ[ucMMV^Yp=M7,/e|2t$Zh Z uGVn(0c+`uM`ƦչG?7%ּ mT].,꯯{OqaHK.ycF漖nJO4͝V_ȵF;|.5`][[xAZaMXwcE>1O\Tl=5K-H^\&ؒ5F06ݎ9yK,w}῾VX۰3W UWS1o-Xe(*9JS64߰ ;onNrJAe7īFSFho%?6¥klj5=>٫W>Wrc(*?쪥kl~{׭=y0g:os7hyz?rG1ّ:?b;G!6&`OE;On~nֵϬ){kݽI<DWϝ䴍>_+u%/ Pg˰erۮ%Mf+rmQ}#rᗕ^2J6)j%5 6W9N䌊vhFfYw(4+T:_z=|k!`p>O(uϯG\zʧ^/zS1a ѮCÿ>:m{*VWW vĻԞ|aS/͟v0Ybz?w};dg<Ը1cxqϬ\3 [۳~؅&N\cäe~}n 6_qX"(?(erp)GY:Rѥbk_etQdŸeѤtŗ=8>뫓=UwzR=ԛj*B12K<V猜}E٤BVzzGW9挭FY@CŵvoPV󷟎ĸ `X=~5?]y_*^OO^_}rN~]y;5/yk6{Ӊ7,1?9z@tQO_W|q[Y9U%+7!nY+nx惘T~A__WQߔQ9X=CGbny+(+&qщK^cv %%DUT氌4*l0⣆2952Yz5%(ʭ L5AC&}':`{ҍj-J#:I}"mcvraQWjҬ=`ușAˎ ^k:Υ^%< ~G++fdNTͭhFWGzn޺vՉcqSf_V>џ4zUKKkr/^⍍*_}+B=!شkk,޾v!|u+66!0-#plTz|5OŌ%߿_%?ڭo ~Z}5zgrj3!W#` &9/k@Šg6=[yym=x Иg(DboMg_ZV!ˇ_3 n(9ZV՘{k|#M.־`rԲԼ=l},X[厇?_k~?Լު3O^~zNszjW_RlӺC-Sr sn(tuGKߪxgw{(ڷU<%wяyn֜+|I ʵt漚'd/bN]-??pʊEu>Tܒ9`=aw뇳"O2`[Z 0R 9:A֫{ uQY:AZx42!ڞ'{#xn:>)zި^]k5hF) {ݾVC"c[kHPT=65{ԣSQQ"ū)_~p>o~CӦxӉ7O.۹QOSG:|%uvȇ<7K؎U ׮66ĉs^5FF|vJ-Ջ=ŇW{ˎ׌Hޏ3t ~%wcdm{e9U\UKhE1(ufbJ9VJȷS%Qwj$,J-Ɖ s[>ѣXG Y}(kt6SڶCιzVnmkxM5 3=so~V.vMJQVE??l[UZꝏ=T%\*ꈚcm?H[wzñj7l fZꡪ=ϯ8ma]e2E}l쭚.On}ȩZ' Ee9jG>1eŋ(I~q~ZJ|m%M{{~I,?}e=?kBߧ'{i(kj?-@JF]DEԲcf%6ja69Y:vjCYc"17q.ѲZ3طT%r5`he^:CWŀƛq-ׯV-N^Ԝ̪ߺX_Ypħp֬ʼےW}|si˶%)ũyyM0oiҊj[Jjڛme^QXzyj5޺w:sGVYHBp?4)綴֫0nUU %-ڭ%b]yZ{U;BvdˊDNebEY_my(ΖmⓍUe~[ߜQ/׭bO'9c[Nj~pLvqζf.ڵm̪'.^z\v._?v˻Ζ&3g½Eu_]CQ)SR&sZusJrM%~\y KCZs+s9C.l8v@zJ?X{yy+SoAꎭ%nkN*f׿+'G_YTzw\S<]ֽ붥杻߼Uuƍ6iCJ-'_.ŹS.ոE^3'\FbSbЄ6ϽXa>F֦¶3{Sūfc@/+BW&'o{Zi7wok){_O5|noxvV[^:'OY_RՇr (G +[ǎxqBz+F17# /+ϼ3oX]գX[եW6ۛuto|V2(dS-}cEڀ`r[_*J[vJxǭyKS>\jK؊XOJc =%umv_^)^Hۙ/_]>e~]Uc/+ Yy2?K[/k#.2/I_=ȗyX=?lΑ}tU/ '5}`c֒:ooKWimeV:=sq QoǾ2'KI}ReaRfQٔumޱ?c}s~wF29ፄYʗG-[fX79`}{)ڗMZ7Po:uWrΖ]>UsתnXg/GZwdߛ3f[+oL5v?!qoΘpOS OY3ݙ.U̗n_q s e '&]#HVM Xڷ+ 'O?7|ԵΖu=d~k疓Xy`gt#o߮=U{|mX7}&`~=*X[ԳS7}=af=WNݿ|Vc&R7\\;sA `@O!`ѣMҘI[N.s^~g]I-5.Un*98cerN>:u$nٲ#9v z +qG5<=x q~6zI)&&Mx^I}3yO_V?hή=~ZS9gʆkmҘI?zk|Xo[QLz?!-uǎyzc?aԊ׭1`ūSv-=}rՃ/;fV-yNX}('ѓ7}{<F ylkt{ dز1&Li} JG?Xv6U?h:[:q]O7pw 2]p熏~]-l+gߍ{{ܿ;Y./4#mg*?Xrκܒqĭ*7; d?V+}lᮏVܵĿ8z ~1Wz%VM?zk.߿c5Gqâމ}fH1%nٲš_^ɽXqu%yO\ꅻ>z#a0>eMrul4_,PY# X74fĵɇUgĤE_>+fŻ3?)fpQB%eϟ@2Rxnht[??7~@_C ʀFǿ*L[<]5mʽXd}Y2p3Rӛ_3iЄR֬>{+N?pXsQoNJS@E 鲀3wˇ m[6x/4J7\Lpqϼ3 o$?~@ei/֮?g#\M[upپ7n*9xVtQNÉ_^ԑKʑ~ưg?~@ekƬ_ߕqk.Y2ha -?nٲ)n)}Kc&r@E _,xt),xi$u熏a۳ɗ@e샵`Ox!q4n@:ngߍ/'+VᕘƼڄqo ;ⅸO@ӕ+@PVc{hYɳOds֞<Vcyzt󇎙<{qs ef+19`ؙ䪊{_>R `=9yGYjܤY]l(T `=YMr˗߼;sK ?Àz3?6gQfhn5[y]Q~Nޟ4mxɠG63:yWu%BƝj &Nv%wa} i 4qނ ?mvܺ~HZ]tO>~]&fXWe:L V K WoD\u/e˻|_Fx\M9~f`ܺ X4yL'KɈڝ9:(Sə'M3sOuu *kHï$k̴e)շ3wiUپO-g '?E[gwN/6tAΎbro$w봔pNW[`v|b8;rfcVkmZHҊtL5[fDd ` ~6\6T 5/)R֌uӶsG!9]ssA}oW0fZBW'}Okr>[*m>ќhc[JݱiRU/Gj5.?_2D zLX7g:f?뿝>+~>柂RNSOk]T01Wy3Wv(+u0`;N}#|rVR-_VᚮJK_d ӢvJ+1}>`p/?](*;-^7wlytuQznS?4k1gu2?WlݹΜ,_KpF_?3q5ڟ2[s{<@+w:`yXsʟES~,)rt7%`ՅuZr0+8uT i]|Q=-y9Rh9r ` 8]qꆋh)1jۧw~Z n{Z7Z'hA~/:8ok+#ȳ72ƌ9gCnA[q7!.ۜ:t%bo2ğns1=蹵ֶyNY{ 7k>fTʳj/:i3`ޕ8:.|ԭd5pV_-V; t!Ӈ֯(l}Aswퟮ4,]nj=mqݵe7轸:>cќFzh6MTM4-C[uK$'cv ęc֝ ӷ'G-ړlq:R\]l,Z:R 7:Xu`@+1}8`+*.ͦm9$m'!uk'+$DgNwnH_ s e6-S3ӔmNYM3λ5oֹ%=Wwrhy.Xs_M;s{Zjю2ޡj-vx jj\ XC"`=&X{AM϶<_Y{.Mۿe)r6ዎoCSMo'{zOw^SzЇH* 5bW p}d0%ָ]niSGF+c4&P*w_$ψ| VL[Wc/kHu⬅2[rK`'e-[,do F26cMGfmwfZAM= o0 VtҲo՞:`NNWX-]iKK.Prjrl?-G*WACv Pג];#h &` >NDfd I˕$k*|rK!,N=#[`) [&-JSեU]q3fLSn?5]YKt6XPUՖ /w[v0hzA6Ū{EonN ֐X@5?mUzenLgb4XT5235D_*~Ŧ@}@oXEz=m},:훚枲l-#w9< zRl֎c߉Sȶ"8Ӈ֢f~:{ꛟ=ӿoږc$0 q7_x@_nx~qv>qҥͬioWaxj˟{֮z*~7%[4 26͸l]Imt=-fZ_w$Oi. 3_7dGv(f5ڢL٦U[٭~dݏ?|z@ROO ե/U@+1};`}hd9Y>:eێ fQ)lujfۘsVe49Eu2 \FRVF4m|qm X[Ƥue,=9iYi{dT;F6gҶKduϙb?)i}FᅻEuV+֠X@TTv:ukً'Z-VrD!ᭀ'+1$` Xe!O.VcX0V}iW~LC z cVǻyYt2[TVVy?W kwKnX 4'WXӵ@.6)k2*%VcX7tszYn*zI4X7f,`}t=` /c9 +̬X@w#`ߘ+nl C- mf&&=iUZnfa㼕8g9+S,OY?{Y\V >2V/cVA >uY A]"@YV.i*(d?t}jXkty:cdOW X@D ++pE Jg2c%`Ij4buXV=`Uj'+:z^2`7bJG9ttN[s,[+: XC@uNUOW X@W鮀FzK:=`}tV!nX_;@wmB4_5tN^| i{޼1t-Q|z {Ez-r348b\]J= Y UJ*5NOW X@׊%@X4DX%%U13DNDF:w+5R?,Ѫ`0t5DUVЅ"XjGk,*LW%%Y.Ut'@kJ PV/X͌՚he>v\.=]@ Vk^k1[+qZ"d4`#`][{ pdJD18Ơ6z9v\Nz#t|U` u&` ވUFjĬzW GXW\Un6J-3V.yX8L=KƪƬJ51(!^~*WthBV .Ѫ?>tU `] ×ȈD2r%OFIm JP.Lr {bUZ=4.骠T>:GUth+_JbƬx8@WQ5;jr0k ZHJͣSUAX@׊,`̀5Z 2XT%LJ.PVAF J^AYUt7b ?ck5FyS^X)d̪^K(uAmt.`]uI# (鉟tWtJm~JmKWEd X+rB2VAQ@>Ja3UV/cuYdBSl@\>J]aca̚GVDVkЅX-1,@\vJ-acXhUtEX%$vJBIgEu *_}bd̚W+&]ԈU0= JK؍RW)F4]X@8`,wXD M%4%x)Wh(J !J u4c|d %R&BJ(ZK^ f'Ut6bgP9K9yG3533:4{um@XV~edk-ɩ0U Xi`ujDYfy|缶ӛYz*'iFUdWSAUiQE-Tf=][μls*>/C+% kS\?-IX|66;y QsŮrL]Q(z'x8HuΘi/4!s4*T{NZyxKUrOrt(NP؅G-7 \,V';o:@Ju!²aY:s:U6@waC'~8$?sğ_N˔'g|_^?s׎_1*Β\<&J[7Ӓ6y[;u-/m/[Tߩvdy{v_T'>h>l>ze9÷/w\<|9n/VZfesWʌmM-bi՟Um;0G4w鲆7l;ܜA_j~޽7/(m?4mm]1-kD'w&c텋V{Y[*^ ciV)V[yNd-p۹ՍLYd'?>{mLLs;-ܦL\d){{\¶!3^zPtzm^`NEn:t`AV^ܠֶ3E%*Z'%\Ժ{*4W/εnz+6mW+!Ъ? t4yIxK}'mç؞P~{_x{@e,ΪoIUܯ床ӯ胰wlF|)6ގ esNⵗ>6ZF-Kcr~mYzQk./?w'U~س..26U ߓ_-P oӦW|._݈Z( T_=j[.fԶmbyR[e0Vd4en 2< [E+IgP8zQ޴%`zZv55ӛ+>[Q6[^K6rcJۮ>}^jQVr9hji, m3vT}=*ˣR-vE}IXY8?WwگɇRok\+k|rߤ7ڕ֕ʻaWk|_ 'T;K>v(ڪOmryu wPa|+K{=_$KҰD>449>\-vʷLYz^+2]؎=E961~RT_!l#)`d*XY{-e[E:GDtPe+vBzvKstα`4ҼF%,6y/W+}V˔Q[NjXݹ&4xQ_i`L X^l~؅($Re_ы /9oVkTZi<JXUڿ-0`u8=i~x2}T8o [%8^NmSrq;j PSI{MF^?}LcGT]2֯~{!mog|_kzm(`Lq XKjIٯ[~~l\KTtZz~}9q́z_s"6lOOF{SuhplmJOyS|!G|D1\X);ǜM5Df26\M^l?֌Ii |3x9L[;}I\̻'ʲ%OsS\~lU>zT2V,5g$[y(D;/kVLE툗sA5`5rKzǶն5t[-]RS?K|Sgkms^eee8*7Vqk~CIqou۷q$o=we[8mlhUP [j/i7$3|RVQz(МnNVR|BYJL=n?b E#gTgVYBq(O,'@G-J ڕ'ύ9IG`=`@st%~}3t }1gmՋ<4 9׿Rp<h!@u禇jҐEr tU1uVj#kL,WǥA,Ƈ<]WVor{S%Wvy/7(X` 9TG;cN:5@W?"Zqr(=^bNPzՇmsΛcVQ6cXSS[mpJO|}舚 羹~RNԂ 6e˾Gm uf0M(kRI)zzK|Ai1eY-5̕։Eٿi]y5+ϭ[aL,f+>˶h)n;4Ɯ(:`i%*Uȕ>u׮6Q Ēۊ<\՛ȕU?y9;bb{[ٿԊqZRQ1ڦ$ncin rB6JwV nS=uټ> *Ij< XoPȼgIw75~(6]-7B}ΏI.78Pȏ⶘) /lgyeN{~F~6=> XN9/-`@ !:y( XJXdi(de̜Xd\sb'0yntL< :,9"B+e+K"_A)fuj2 _>&6>X~cNpaQbSCghP>y;r j(ޮJi 9ZLJ19O PYnfc~G9q(^b_Cˢ YJU9F~VNi_?5_Nu贒TmX^ryͭgnݷ7E˛Z~Kj9Y3"\Xa/=yKQƳ_[r1XNsv2}ļ++?ǾnYm2-ezXMW-mK}J9vpl߂mcg}ԑ+'_RۀfliEN¤ )Vi8@jj?dZ+)ZAssM ns;-._q!?E RN-uve֎QcPI.Y XWswJhS[3H6o窂RD=T -3ڨƷN=0ɻX_Kc9Pn-d-6LJmTYIDzuinλ^A{Rq)ӽse.G.ਔU1Ѓtڙ)9 < sJ'Xf}p< ٦攇* U8GDtPekk$-JljNnm@U;.M؏uSjH2wہvtҹuJά|6vd'm8Wr6M'%׍{Q[NiߔɟδZ6YJrŜbCFJ^M7Q\c#nB\:z nA9@\+XA!qnX[J5Խ)Py}wF'se][Q˕?"N7z]E+^Ʉqq+j+| Jq{Q>l`7[RslR gs&eVw ^25X_K)A=^/1Np<r瀺.5:y8:sBn*_pQ!ְj*7bKMo։C:PWF8\o>yeҨܓg[iiElZ dsoTVj_[~y\(k>z~*`^y+?>A–`~___9q̮}#'_TX% "{'t9@t=l~l<zZi?BlJ veVK}T:qu;ݧGZ~WgꦔFn@@2`^n y}?W,5Cd[!ԨloY~fr3㦥<(xCvkO?.nζ6'Zu MҩwA<9ȥL^΁=}HBU.#zk>cLZ Z`\Kۡx9jm6f'!tߜ9"B0Y+;~~p?HAGc:j-g Rbj )@e @O q:\y8rmעpvT@'luckq/j)-ݬU,*,GJSr#QzT]c{\96i`vP es:RLw6*3f}tӕR vo(Hw^Dpzx9.^?%s[Q+5brdpUt_Qqq+j+| Jq{g2F;[Z9^~VslR gs&eV%qk9z@g%)arP^.@u&fZ|q6J~b=:@BЭWeעac3P1ڷG^]vu[uG!OހS9"XU/2{m?kmklO5z*#`ֻxx}Qg.csKeZyjU %{u⦻ <}6]mKзjZ+&PsR9>* o^a U%: "Ҁhٜfb7 A+ aܴ@!8| l];D祓lۺ\6II[_q;{/@˴-[ߒ]y4#!@+Ig,z Ql3fV,]0K+{mv'!tߜ2{r}N_S z9"B K,P3 o%MAYX mԌ;'&.Gfͩ vݧCǍZUMgJUs>VkX{Q;%6p|{W~rD--ԠTﲢP({ٳNyWvع2BqY뜁>ڹMm Z@gus7ǭr;Ub_8 Fs[Q˪b}NT^WʲW2a_cWXW! g]koXslRn($"~~=j-W~RTơz,bז^T? }S}UyszZêܸuj_ X21ʇƟYI,@+wǭ헭z8P8IMw8VVj/V^'i ih.nuچ}X4ɜzbg-NIZwK_Ze(ffDy8` Zgog\{vߚ+^<}IJ7-YG;(!Qz'ˆ\bױI:ct:ߗtbpml罜]JMDOvJ¿&ǡ`+xU82Mx(=`FW釾'9N9/םGĬ҇ q8"˸k1KQ3jAl5sр|}*ԧCeᲯ+C)1e͐딀z½U"6@Etc-En]#mirw]#7\7*"wHaM]É߶Q΍ۦ_^jD.rV:] mr|u;Ux8~d>v9߿ $ԉjUJ&+| Jq=eb;T.[IXn[u֜j! 릏BNrJy<Б?j%%C T'(<A%y8:u[vuqkުVIj*7gVLI5:um /`eö7[i_[_MVj-*;d8}'!Jo_+gv1%[ʈVMSZgych麮h \\wV[%/[gs?Ϝ_?`3ii퓲 şjV̰'=h:"\,ާeMGzbO蠘h.܌(T2>[LԖçBlF/c$ E"(<ݮZzS¹igI"|P(/A#גohFֺYPG~M朽,ϋZf_ܔf~u{)g#ZVNNS^b-nQ>;(_ܕ噩 Y%?Xb[\KI .n ڳL\]e#1#!>@LJ6JQ.~%F%q}3d[/iHU@ ՝mn\^:y24d7lvqŽlr%9~?JL8e\ EdY]c#n甭ƛFsxܐEۡfZQhxK~.hBߛB ]k;/U$rzQJ]Kvފ轪jA5X[+u="ЕV2Ttyl¸R\#5eltXjqrO=`uvF6ǚ{=)@Y=(gVA.]4UƲZ8/1:!m27\wr6v Qc;TnϺ[*%Z bYeo\mxVVaIEl[͡^Bk/#&_jxz0?S?ߴOxYvWZ:%6ѥZQjΈYwO=U̜n~VTc}cl;zyVZ\̀ye_iy,Ԋػ@ y*_AV1}MQ?pQ V>&XZO5jT^u{ji-tK>XtrbSE;KmSk{z5]ۧN:]i'~ԢmPٌʬ1TƻW/mwkZk&%5k XfV!n!ͶFjܴ?57Wa^GmOKn^4>UU`h%cZuGEǠ6h]Vɇp@f`ojۣuQqQ-0Y|;Z_$g{oס>QsQ协RͳE 9ϲ\`R3zi?j)J5shz3ݭAZ 퓌 }<kѯmz9o^Yȣc}uǎ8;3Ԋ_]U͇58q@?,߅|Uwnz^Bpj:yU|׻$\{Q;NimTa\nI R3CO߱Pw*+j".MαN/ }s Č鲜 s\^ 9ҮwkYi[h T{ aPĎ8KZ9^.1:A>vhCJ瀾Pp#e>tqaTJMONg]_m`$<)VLLtIXi;sԮK޸tFԥ_4Aˌlmi\ۙ/^:ҩcğ G[ޢkiuxڥuz5{1Xz՜J󋓉J+MڪKnv~)i^77<.mp}O3jJ^J3晡ިm[zf}:bWyZe|w m5aml_}uXD~}.5`ON)W%T:vx]'i^=sNQmg"-;ȒbY&s84m,;zQ-}Y]2O+yCYw)/ӶYK3ku*`gqR|CjZ~4j!̔vJы;DQc]^Ӫ_l#jZuT'}P Ӕ >W[&M.0),me^%X;gg> 7F|3x]ikPcxXIj6{PC7#x:BkSJX~QsC l{<#Sn?SRC<_zq~1&ۀg|FۙP~xf;Xlam᱃zL.S<\f5l;Kc9Ю՝mEsV5*} -T +ȱv;-ղZs'tVޗ&Sky:[|䵓6QYV|Fz; <2\*wSi 6?]9 ύ"\VԒQ]6ԩ5*]Ync+|M˕Ȁՙ*aCnu(Ɩ{z(Tt!;Kͩ/szEq5\N4u@X:@p]K2%^', cB>*ܺurMqTfܸu^$Ou=`)5`o_jCղgZK X?5p]Vg:dv泚ec6nMt V]^݈7/u\ښ0U,kZ,jFo(7}-&huQ>ԓ5m!k2ΎğcVm1BoU8S{] 1k7֜2cM7ȣ3כq6褴Ϭ?fxaQgc蜟&U}Se\GOTv= 7^"]yqzo{4fj9{ȾI}Եg*hSo6ˁGC?.m7:1f݌Xѽy]ͥ9-Es+m3n\>u=1W^^ѕgO8ڎ羹De*S)x= Л X!2*t݊9ě}nʴjЍ&,^R_Ub޶ n@^el$i:KZ^̓\?ӟ̚Ӎ6^;zV_{iSOF/G "`@X B!V+D"D "`@X B!V+D"D "`@X B!V+D"Nuʍ{~oU[NjR>ͪsƥRtNn۽+u_P n(*IDAT?aX?rLפd4"+mw*Ϝ6=lы_l1ijUQWX,VP*Uc[f̊4},ir9W7]i} W>-=ypH Ҹ^wr?4E-YDߢZ]ݝ2@1߮OV~Fo\+-j63?rkӧe츠,qْ;3Kpݒ'3h lQ_D+xH 7_^nM_2q m'VÝbkAL, X;+$]6W^XCky'w1]=be5:x{ 8Rl}5\_~K.NY^s`qϨyky8ZWjPtK YSztPk!S¨n+ݓh(P=FĿ"{GMi{hyVboɦ%/ǿިfj`*) kJoZd$`@_MF|LBo\]3?A/xKO昶F!8bN=}9e3W3o8TJj[tFL[,Q_5ZQ)֪DmuuV>yt{cO$`{脷Ӛ|yTS7,o /s~^yuuld\1R.\EB[OoOwÙ)n._SJ.Ek'hNK`*x X{aAzaa~%On샵4_{ըlcK'{(9וʖ٧JxJs"U34hǞ ~jJslcOYxX3bDemo];e 1.晸OvО/-\{Z5e(`5vv5cCɰ?Zsp}Yrpm=({#X]q/oTenOJ}+FZ;Srmk?nO_i@/v;U߻R=Q수>WXqX[V*\Z1j/ΆxtS^Z>ReT`MT6Y֜91k>D Wn\Z1^yh}D'`X5X,cy9֫&Q֏TH\ %i,y S"`x0ycq9^?e XЗu WFǦrhL.}y.@߸-QzSգ@TT~|JE3--FjG]U%AeZ脑.iҖ6X KUZ/V XuCXk*YzzY[X$KB=sq/QHd{d=^̂-ZYVM¢jٯmQ!V.`]ciuD rI/+$‚ Kftxb}-z^o{OhcŬG-[^m3nt{7ʢ}w14AeV(ЧUjeb͠sUV[.AKzQzX$A\83ܸs82NlƽYEo̸.ʍ skA*NI.A`Ka}?evr7T[uCi>7DF4s^+ X޷e)+N^mX;5+,5i+pV+D"D "`@X B!V+D"D "`@X B!V+D"f(_3s烣|}篯3A" 29`;﬚?wW?{]e6vy<닣'1}ֳCF*ӻ" wfߋ=ĒS/Jz=aSy{뉀#2Rq#ǎY/v2s=L7SZos~աEHk'c=7鳤wenQ{RM&\@y[Y/N޹pyS}GN ue:`h|ܲM?8^ HO^(Ty颸e̙ɔԵ*\̪)VU$ԽKΖN\,oS^tYvSo(eL-fɿZ}KneZK w}|옧wSrղ9lGşgVMڱת8[zɇ6mL&LMؼuJF'͗mWS !Z8cƉ뒥[6:Nߟ,3U'Þ}7nM]Sh %ɻ|j1j"!#ߘ>q˖m;}?Z )WܕZ)~pѠ S̒}Y5̪̙7 &\rJ/GU<ⅸqoΘ=qmche?XM!YI'sReŊi֋w%QoA3Ƭ`q?^Rևwj~ynͮ= ){+o;;#}Sy/Mٰ2R,o{B ^xqBZ+/e:[*Hۙmb3_/o: &~ҥnYW"5jO04^o` D0Ug[Ǯ ġ_^)l9qWU}=a֏G)oyg+/}~n濞Yb?9E@$֛US\v&%3w)teU_4 b3 /jm7>eg}1llitb"ߘ>!#6]>uu۷,cy[dgB$9ղ}Yb s̗ގ4ax{Fe)͕׉5,?ҘI/č#a`J~ 3^X{d熏mKŒsΖ.ۗ5N.VZBpVFˑڽeG?/yRu|ʚW&'7l3jTogzt^o$zer3h{w1Ez?-UkG[6=;ƺL.4mQ՛Jo ߙ3om^RՃf!jժ9e19`}noHڱux qO}o fO;#e/]Lhewe36oTr0ZNj4S݃WNp %]gK)2F;h´eF-_{<=x q/{7+ӃK4a갅en6{/i]upU+gmMˮ=~쓳79c qれqQXj'jA+:qXsG4zҏ޲5h5;[_ ˹9VS/ XIIZ݀#2jXfUQ&`?^F,Ysb,Y[9Ikzxϒ=OٔĭS/_3gE&K1j?nc7) DWU lG_b]K%mrF-ߚuNfMNM|ekkGCnG?{EW9gTNo1Vޠ~9%*1%\㣖\cKogDff|6 -7RQW^-𽫣BvCk[dリtc<mSGYD̴{Jk5aGE2Kv5*z"i rFۦ8mJus|S9':q踆fmb~Gmrʝ<.u|{7mj/I#76ݶI]gߍYwXCvq1XxvHûq?x有%թ1jg36oTr0Zɻ]8yjձO4-ٓ9bX;VySXUkHg2&]EzT_Svٜ9\Z-Y\Unĩ 3s7>j}1oE66o}јmUXKSZ8ؐĘbI5ncBsN󵗌,gwL/4W N/kH]oXeTz(n{,CIZ7ivꕷW5Ct3sCD6 g~=U߆þd]/ .$@NjYdN 㴩]i[`rvYhIr3#`֮GEtpe4gj^2lw#0L-f;tA*d{{ͳ}xI9,ـGO^/9/ 0uE:V[Ų~\_rʌM%yfٵ?:uⳋ7={[ K3mr/fC斚izQ|-@-Qb-O9_̫"0^9&6ᢞl̵6ތJLbI 9VId́%2.lJO3[ W6cT2>+RloZh9gdkf~f-ubS4v\S>ȟGZoR[+i+?Qp׌zU#i#gG fڍGIq"8{/)*ԎW ɾx;Lll9iq*ɽX1pdg("`}E'O.SvfuGerl*;&~MyOm._[k|옧W@ocDZ6/YW]8C_+ӿ}߰ʒ! 2@̔S%#3{㾧^_dMF I Kr9?uuҴ"ez@3s8`u gJʍbv- ΈꪖXQlcqF~k=XT.Ю/ʀw:y?m%.;j{0U;SB?95ZJ{rtsKF~h}Y8)nNңخ XGO̿WԽZ"@qW&dޛ_MNt,ܰ/:8N߿\~BVM-, Ԫ97o=8JBQb 4k>azlRmrQj#S2'm0.[ m k_<1e3`64։FAS3=dʁDMX~4fSN^hJ0Ne?,'_g}Y^5g^<%ӜxF.@'t팗O=xt RdX14AwXᣧu5LAvtUXɳCޜ1{m޲]8YIeŁfâމ}fHS烣;EY=ϙDɦyD˴H)cy1prf?2Z[V6R\+ek}s}䎷䮛V!Sڎ,~IcvMԻV1MN^Y&zkSVW[w*` ttld7]O^av5{ҽKјjʆQľ2ק?FjڋEY=-Z:|S  Yjvj`!*kߩ_ejU/T1?% UR(XN?8`%5r,YY%5Ro XcVehK{ﴑ_6Z50` zt{<&–Yl`2 vLKkO 'E ޔ1C룖>9 ԧESX< 1a\<#XmGUd!u-4y=Hot ЏGE'_9c>6@crl;^c8`LJS# :3fSLyk{ؐ[mi6ـU_\\tϗia[+T pVVm1rZf/wI X[%s6vC*D%._y뫶c0[n'-u.9讉%ꡭelW^2`zR%ʳ:}{ii7|= Z6y5ku"`ԣ!>z<&!*1%<5]X)&Lx?]o_/wL_o[J@?CNz;'1q1$z<9xw>ݿyw[@?CJ[Ǿ>{ְGW^+V+D"D "`@X B!V+D"D "`@X B!V+D"D "`@X B!V+D"D "`@X B!V+D"D  .H(JL+4@X "61IENDB`rdbnomics/vignettes/rdbnomics.Rmd0000644000176200001440000005457613604711711016710 0ustar liggesusers--- title: "DBnomics R client" author: "Sébastien Galais^[Banque de France, [https://github.com/s915](https://github.com/s915)], Thomas Brand^[CEPREMAP]" output: html_document: highlight: default theme: simplex smart: false toc: true toc_float: true number_sections: true rmarkdown::html_vignette: highlight: default theme: simplex smart: false toc: true toc_float: true number_sections: true vignette: > %\VignetteIndexEntry{DBnomics R client} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- # DBnomics: the world's economic database Explore all the economic data from different providers (national and international statistical institutes, central banks, etc.), for free, following the link [db.nomics.world](https://db.nomics.world) (*N.B.: in the examples, data have already been retrieved on december 11rd 2019*). [![](dbnomics001.png)](https://db.nomics.world) # Fetch time series by `ids` First, let's assume that we know which series we want to download. A series identifier (`ids`) is defined by three values, formatted like this: `provider_code`/`dataset_code`/`series_code`. ## Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, echo = FALSE} library <- function(...) { suppressWarnings( suppressPackageStartupMessages(base::library(..., quietly = TRUE)) ) } ``` ```{r} library(magrittr) library(dplyr) library(ggplot2) library(rdbnomics) ``` ```{r, echo = FALSE} reorder_cols <- function(x) { cols <- c( "provider_code", "dataset_code", "dataset_name", "series_code", "series_name", "original_period", "period", "original_value", "value", "@frequency" ) if ("unit" %in% colnames(x)) { cols <- c(cols, "unit", "Unit") } if ("geo" %in% colnames(x)) { cols <- c(cols, "geo", "Country") } if ("freq" %in% colnames(x)) { cols <- c(cols, "freq", "Frequency") } cols_add <- setdiff(colnames(x), cols) cols <- c(cols, cols_add) cols <- cols[cols %in% colnames(x)] cols <- match(cols, colnames(x)) dplyr::select(x, cols) } knitr::opts_chunk$set(dev.args = list(bg = "transparent")) dbnomics <- function(color_palette = "Set1", ...) { # Check if ggplot2 is installed. ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) if (inherits(ggplot2_ok, "try-error")) { stop( "Please run install.packages('ggplot2') to use dbnomics().", call. = FALSE ) } # DBnomics vignette theme result <- list( ggplot2::scale_x_date(expand = c(0, 0)), ggplot2::scale_y_continuous( labels = function(x) { format(x, big.mark = " ") } ), ggplot2::xlab(""), ggplot2::ylab(""), ggplot2::theme_bw(), ggplot2::theme( legend.position = "bottom", legend.direction = "vertical", legend.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.key = ggplot2::element_blank(), panel.background = ggplot2::element_rect( fill = "transparent", colour = NA ), plot.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.title = ggplot2::element_blank() ), ggplot2::theme(...), ggplot2::annotate( geom = "text", label = "DBnomics ", x = structure(Inf, class = "Date"), y = -Inf, hjust = 1.1, vjust = -0.4, col = "grey", fontface = "italic" ) ) if (!is.null(color_palette)) { result <- c( result, list(ggplot2::scale_color_brewer(palette = color_palette)) ) } result } display_table <- function(DT) { DT_ok <- FALSE if ( "rmarkdown" %in% installed.packages()[, "Package"] & "DT" %in% installed.packages()[, "Package"] ) { if (rmarkdown::pandoc_available()) { if (rmarkdown::pandoc_version() >= numeric_version("1.12.3")) { DT_ok <- TRUE } } } if (DT_ok) { DT::datatable( DT, rownames = FALSE, options = list(pageLength = 5, scrollX = TRUE) ) } else { dplyr::as.tbl(DT) } } ``` ```{r, eval = FALSE} df <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df001 ``` In such data.frame (data.table or tibble), you will always find at least ten columns: - `provider_code` - `dataset_code` - `dataset_name` - `series_code` - `series_name` - `original_period` (character string) - `period` (date of the first day of `original_period`) - `original_value` (character string) - `value` - `@frequency` (harmonized frequency generated by DBnomics) The other columns depend on the provider and on the dataset. They always come in pairs (for the code and the name). In the data.frame `df`, you have: - `unit` (code) and `Unit` (name) - `geo` (code) and `Country` (name) - `freq` (code) and `Frequency` (name) ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` In the event that you only use the argument `ids`, you can drop it and run: ```{r, eval = FALSE} df <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` ## Fetch two series from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, eval = FALSE} df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df002 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch two series from different datasets of different providers ```{r, eval = FALSE} df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "Eurostat/une_rt_q/Q.SA.TOTAL.PC_ACT.T.EA19")) %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df003 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics(legend.text = element_text(size = 7)) ``` # Fetch time series by `mask` The code mask notation is a very concise way to select one or many time series at once. ## Fetch one series from dataset 'Balance of Payments' (BOP) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df004 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ``` In the event that you only use the arguments `provider_code`, `dataset_code` and `mask`, you can drop the name `mask` and run: ```{r, eval = FALSE} df <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR") ``` ## Fetch two series from dataset 'Balance of Payments' (BOP) of IMF You just have to add a `+` between two different values of a dimension. ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df005 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch all series along one dimension from dataset 'Balance of Payments' (BOP) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") %>% filter(!is.na(value)) %>% arrange(desc(period), REF_AREA) %>% head(100) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df006 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ## Fetch series along multiple dimensions from dataset 'Balance of Payments' (BOP) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") %>% filter(!is.na(value)) %>% group_by(INDICATOR) %>% top_n(n = 50, wt = period) ``` ```{r, eval = TRUE, echo = FALSE} df <- ungroup(rdbnomics:::rdbnomics_df007) ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` # Fetch time series by `dimensions` Searching by `dimensions` is a less concise way to select time series than using the code `mask`, but it works with all the different providers. You have a "*Description of series code*" at the bottom of each dataset page on the [DBnomics website](https://db.nomics.world). ## Fetch one value of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, eval = FALSE} df <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea19")) %>% filter(!is.na(value)) # or # df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19"]}') %>% # filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df008 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch two values of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, eval = FALSE} df <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea19", "dnk"))) %>% filter(!is.na(value)) # or # df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19", "dnk"]}') %>% # filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df009 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch several values of several dimensions from dataset 'Doing business' (DB) of World Bank ```{r, eval = FALSE} df <- rdb("WB", "DB", dimensions = list(country = c("DZ", "PE"), indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"))) %>% filter(!is.na(value)) # or # df <- rdb("WB", "DB", dimensions = '{"country": ["DZ", "PE"], "indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}') %>% # filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df010 ``` ```{r, echo = FALSE} df %>% arrange(series_name, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` # Fetch time series with a `query` The query is a Google-like search that will filter/select time series from a provider's dataset. ## Fetch one series from dataset 'WEO by countries' (WEO) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "WEO", query = "France current account balance percent") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df014 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch series from dataset 'WEO by countries' (WEO) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "WEO", query = "current account balance percent") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df015 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = `WEO Country`)) + geom_line(size = 1.2) + geom_point(size = 2) + ggtitle("Current account balance (% GDP)") + dbnomics(legend.direction = "horizontal") ``` # Fetch time series found on the web site When you don't know the codes of the dimensions, provider, dataset or series, you can: - go to the page of a dataset on [DBnomics website](https://db.nomics.world), for example [Doing Business](https://db.nomics.world/WB/DB), - select some dimensions by using the input widgets of the left column, ![](dbnomics002.png) - click on "*Copy API link*" in the menu of the "*Download*" button, ![](dbnomics003.png) - use the `rdb(api_link = ...)` function such as below. ```{r, eval = FALSE} df <- rdb(api_link = "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df011 ``` ```{r, echo = FALSE} df %>% arrange(period, series_name) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ``` In the event that you only use the argument `api_link`, you can drop the name and run: ```{r, eval = FALSE} df <- rdb("https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") ``` # Fetch time series from the cart On the cart page of the [DBnomics website](https://db.nomics.world), click on "*Copy API link*" and copy-paste it as an argument of the `rdb(api_link = ...)` function. Please note that when you update your cart, you have to copy this link again, because the link itself contains the ids of the series in the cart.

![](dbnomics005.png)
```{r, eval = FALSE} df <- rdb(api_link = "https://api.db.nomics.world/v22/series?observations=1&series_ids=BOE/6008/RPMTDDC,BOE/6231/RPMTBVE") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df012 ``` ```{r, echo = FALSE} df %<>% mutate( series_name = sapply( series_name, function(y) { paste0( paste0( strsplit(y, "institutions' ")[[1]], collapse = "institutions'\n" ), "\n" ) } ) ) ``` ```{r, echo = FALSE} df %>% arrange(period, series_name) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` # Proxy configuration or connection error `Could not resolve host` When using the function `rdb`, you may come across the following error: ```{r, eval = FALSE} Error in open.connection(con, "rb") : Could not resolve host: api.db.nomics.world ``` To get round this situation, you have two options: 1. configure **curl** to use a specific and authorized proxy. 2. use the default R internet connection i.e. the Internet Explorer proxy defined in *internet2.dll*. ## Configure **curl** to use a specific and authorized proxy In **rdbnomics**, by default the function `curl_fetch_memory` (of the package **curl**) is used to fetch the data. If a specific proxy must be used, it is possible to define it permanently with the package option `rdbnomics.curl_config` or on the fly through the argument `curl_config`. Because the object is a named list, its elements are passed to the connection (the `curl_handle` object created internally with `new_handle()`) with `handle_setopt()` before using `curl_fetch_memory`. To see the available parameters, run `names(curl_options())` in *R* or visit the website https://curl.haxx.se/libcurl/c/curl_easy_setopt.html. Once they are chosen, you define the curl object as follows: ```{r, eval = FALSE} h <- list( proxy = "", proxyport = , proxyusername = "", proxypassword = "" ) ``` ### Set the connection up for a session The curl connection can be set up for a session by modifying the following package option: ```{r, eval = FALSE} options(rdbnomics.curl_config = h) ``` When fetching the data, the following command is executed: ```{r, eval = FALSE} hndl <- curl::new_handle() curl::handle_setopt(hndl, .list = getOption("rdbnomics.curl_config")) curl::curl_fetch_memory(url = <...>, handle = hndl) ``` After configuration, just use the standard functions of **rdbnomics** e.g.: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` This option of the package can be disabled with: ```{r, eval = FALSE} options(rdbnomics.curl = NULL) ``` ### Use the connection only for a function call If a complete configuration is not needed but just an "on the fly" execution, then use the argument `curl_config` of the function `rdb`: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h) ``` ## Use the default R internet connection To retrieve the data with the default R internet connection, **rdbnomics** will use the base function `readLines`. ### Set the connection up for a session To activate this feature for a session, you need to enable an option of the package: ```{r, eval = FALSE} options(rdbnomics.use_readLines = TRUE) ``` And then use the standard function as follows: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` This configuration can be disabled with: ```{r, eval = FALSE} options(rdbnomics.use_readLines = FALSE) ``` ### Use the connection only for a function call If you just want to do it once, you may use the argument `use_readLines` of the function `rdb`: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE) ``` # Transform time series with filters The **rdbnomics** package can interact with the *Time Series Editor* of DBnomics to transform time series by applying filters to them. Available filters are listed on the filters page [https://editor.nomics.world/filters](https://editor.nomics.world/filters). Here is an example of how to proceed to interpolate two annual time series with a monthly frequency, using a spline interpolation: ```{r, eval = FALSE} filters <- list( code = "interpolate", parameters = list(frequency = "monthly", method = "spline") ) ``` The request is then: ```{r, eval = FALSE} df <- rdb( ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), filters = filters ) ``` If you want to apply more than one filter, the `filters` argument will be a list of valid filters: ```{r, eval = FALSE} filters <- list( list( code = "interpolate", parameters = list(frequency = "monthly", method = "spline") ), list( code = "aggregate", parameters = list(frequency = "bi-annual", method = "end_of_period") ) ) df <- rdb( ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), filters = filters ) ``` The data.frame (data.table or tibble) columns change a little bit when filters are used. There are two new columns: - `period_middle_day`: the middle day of `original_period` (can be useful when you compare graphically interpolated series and original ones). - `filtered` (boolean): `TRUE` if the series is filtered, `FALSE` otherwise. The content of two columns are modified: - `series_code`: same as before for original series, but the suffix `_filtered` is added for filtered series. - `series_name`: same as before for original series, but the suffix ` (filtered)` is added for filtered series. ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df013 ``` ```{r, echo = FALSE} df %>% arrange(filtered, series_name, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(filter(df, !is.na(value)), aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` # Appendix ## ggplot2 function `dbnomics()` used in the vignette We show the function `dbnomics()` as an information. ```{r, eval = FALSE} dbnomics <- function(color_palette = "Set1", ...) { # Check if ggplot2 is installed. ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) if (inherits(ggplot2_ok, "try-error")) { stop( "Please run install.packages('ggplot2') to use dbnomics().", call. = FALSE ) } # DBnomics vignette theme result <- list( ggplot2::scale_x_date(expand = c(0, 0)), ggplot2::scale_y_continuous( labels = function(x) { format(x, big.mark = " ") } ), ggplot2::xlab(""), ggplot2::ylab(""), ggplot2::theme_bw(), ggplot2::theme( legend.position = "bottom", legend.direction = "vertical", legend.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.key = ggplot2::element_blank(), panel.background = ggplot2::element_rect( fill = "transparent", colour = NA ), plot.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.title = ggplot2::element_blank() ), ggplot2::theme(...), ggplot2::annotate( geom = "text", label = "DBnomics ", x = structure(Inf, class = "Date"), y = -Inf, hjust = 1.1, vjust = -0.4, col = "grey", fontface = "italic" ) ) if (!is.null(color_palette)) { result <- c( result, list(ggplot2::scale_color_brewer(palette = color_palette)) ) } result } ``` rdbnomics/vignettes/dbnomics004.png0000644000176200001440000021266513414003034016776 0ustar liggesusersPNG  IHDR~ sRGBgAMA a pHYs%%IR$IDATx^wW{f=sf/3c=x0`I&IY EAd02 alB q  ƀMϮջ[RIꖾY,T]aWuҮw/VCD=kD}6Kmn=[КuuƀCՋYOkVRݗ $[>ڸs0XwiNwVZ?-5;xHNuy"'K3#zӶ>~>hcj_Ƶ/}*X?tM9yUC, =wM\uMcKu_Ͱ!]'sZAYkgc5Lۯi/V33?(^-xVFկms\ޣvRnf Q]4]`GvfKbJ5)>4/'+#z,&e#J6Y+oٲh630ͻt ]_k`EM}~b[֣=&zpavC^Ƶ[_~m!0Y'X#cO^iQ_|b[EٵG\|Es+]s[Wk׫IAѳ<Dg} VJl0N/zeѳqt0G:Hm\g]ob ƍ5hDsjZG,1==cYgdm,A:C~" : pBڣvuĿ?5׆գoZh)zV@:zn r 3K=ˇ6QlP{>Htܨ&}K N>e+Ѯ$@EuRlRO|kz|+I[f ûY10h}^ Ra +fb"3jգ]/]u1YX%_|qڢokdr } uz*-j>i-}Ѫ;_oU7n׿iw=[L!}U'W2"^Ye`Ub;$=[Af6y߬s߽ޤTm]4 \?a~eiV=-|g]ߘ=idlާ룷ӫwFu1fqJ`0SZV^DKō(gP`mՕEf>ynqGoEJ?Dk3 q؈8,%3ee@oTHu:ݟ=m-H)sn}?`|OVa@ß|{M6]Qa[i "%z^n.c}|CGr$/k6K|8ġ%0MAoT dgBEn8#k%D 3DgE :=(B сDgD TZ%};&Wx~y)U5U~_z#26d8tDA|an^Oy* . f(,J_LQZ=Dlc^Ě:{b{投hޣ?SDL;L̮}~ .CGKG1}XD~O3\iVrdd5 Kޘ]iev086F7cl:+MjGJ\$|.:\t*G/5n7ez;ė-3W8 o^^J3DHuuڵ{K[+-^#;~h+sU5MYn :wlٿZݜqݟ79xHĜ?c9n]-V^!?p萱Ȑme^n.cCBXiݮ}0ҼT8q08`acmB)F[%Ȏ:sb 7B*z.%e.CgYaF7ՙ[܄bͲs/7m'ʘxJ0ݱlclk_Yw 3^-zM+?D¬yr?c?0W&7ZuSeK?eYIbY_-}JkGbO)s3;^oiuk[y=R[֮0zFl8NPfw$E)ELӍa)ӕZLOw_u=UM۳ÊD:ۼOL ƲZ)%תߐùƬ]WtR})úZbOs<0z,N7s)/QKV1څSakcbW؊y,j߁:ؙbw$Aδg*T|siJ{GaecvovÓ9KIbRͪNsu ?可V;;~{SAsN?gE*ZZii~ZqS4M(Ui)8`N~ͷiW%W8q"h-]Θ\k:*͂E'gQ>l--X#GOЃ *GPʫlt[Ū$LQZ*qWT ̣yz WD =;yHbъFkK48 [!fejf/YnW?zNJ)jm!1u MرE;v}8#ak:{;S]7y=r?]F~!E+,*((H_}kr J3G{9qn vc#ak`@pO<ߠN# ˆE[c DZmcbفXE "S [v촏8p|=r+ V<\{M} yRKBp#ǽl;=n2ak쯙, JLtq]2\%]&DώA q^v}r9竫!*؏^$zQBEn[:`XaƷO0s/OY' >ؕnp JR6oUx0։]cWak7tQbyVWyeoH~=;v{Z}ZCGrSf +zvy 3"DZyBDZ}KX%`Ѽc>JgV˭ֹOXepGb+}%v؉J_}F'5M݆.]TPzѳ`aMۥ,K?{ԘuV3툞@!z:nH ˓h >\D{:wlJ`@M6yT.2_b?c^[?nn?%7bGҋlĪϘ.{C*{DpSFkKc]@ z:FZoLJҰ[CGK憨cO9yA )3ǥ))"ѳVpeFVû+mdLt42qjf:{T9ZԮ={v4v$:aGiqS+ӥ2_=/[Z)kcקƲ}u87EJb7J5z~Ma=n@ѻ>Z<[v4f"45@!i`Mؽ5ѳV0XF&*k}bV׮?/:Dtb+y`mo=V;qęJWdE`u>e_L.Z 5ۘ m۬(pIMP$gJ!2pI bÅxo2%(JZv@-:ojmXi:Q}JֹIb1HѴ5fr"tO"'zJiYՙ[Lӱۤi|S =EXQPѳ践uy6fm \#o6Qb&XyHF9c*q4vQ!*69qb6nR^ Pƈ*je<}y=[b{c(s3p4ѴXQs)/emޞr"~= 4ooe)G}sW☟{MY*"BU) P4|, WͲY(xظ)gVo="A,Ҽf0n~$LqN,XM, CJO=kUz/}/N+Gl2v(꜈" [){*7/OxN,r7xb&bTPPp$qS}Qzlewv,Bv2C 3cD='wM |A-?7[>˅kWg6WNА}^ׯӕ銹[jsXn_e// XVe1]˗l\gUaSv{e=wl}hpTJ1)O2l_k sfAZoX'v\uNϷh_n.o=g,b֑:Rre'rٓ/97Jo _xM# {zlG7_7텗.^7~cWHZE 'gAU=Ϯg1}.a,=b#z( fdl/=2zsk=+|g6nNɽe/}{GZ_=uk5=xh9i׵fNX`a-:1"=MYO~2;mi ݹ>_bDϷ~yxrր+o殐_OK2tz{ ?h_?ˬ{b?=7|m;Z~)gQO矔d)yrַ/Z׃N sb_\rAqtr9mΖ0W "i38v\3e#zz px KTqw_S=D>V@ޑmfA7sƁL=ɝgTlD% 7Nmȣe|l}S5f҇e竕骩W~X-G+[|=~{uCXa/'#u?J~WR>-ezmIY$c==.2n9Oe-wsܼ}7/zM7XV{; DϨ؈(7J6ѳ% ^͇ b2Ris\9)iyt#w- Xxl1_ѳؗ :tXOoHok\s&X϶-#uFF>0_`>}nˬY,F-gTlD% [$D A܍kOx3`?m#cÒPw/ڱz9ݶD}flg+#l|)om6h;1:bܒEl=z6_+g3F D@"z( f(zg:xkͧ[!01C0PAϔ(|GDtir fLC*p2zcZ{>_~DobF r$:RҲc}megT=Pn3le=;fP׿P~ڌ14ߎFO gʍ`g1f^<>>oN,7[9т;{+=6r ;`O?sP\ֽ2{UjmæV"zNvz<8 ~}/GOKOZ?0>L߸G|U'w+sÔ=.A6 ‡}@;x_ANC?/0W{Wmצ=r$a㇅l.m<·W˗^PTk- (޵Wu̳EYo)%W_#/_UEWy.Qwojߺ+ =\0)սR>cZ]?^M3{}Km2ԛed,xa9%[bGσ;v|L߹~Er[lYʇ2{Ώ}[M-~x1<nr$aѳcn$zz\oUxօS-/4,u#,vjiwE>`0̼g o_|yG>{O76DzmãVJ%zwo?gL^F|,^rӻ׏Qi*~ s+BJ= 2i$΢́FnosvWE(e^ kbgT=Pn3ѳ7\DeqhC􌊍r$ȳYq% F%eG\=b#z( f(z~S+eG\=b#z( f$zUZׯmߪs%G􌊍r$do޻v]{6gA٭=WrDϨ؈(7JJ=o;߾݊C٭=WrDϨ؈(7J(V+9gTlD%DRv{Dϕ3*6gʍ`"J)=J3FI0s%G􌊍r$Rnu蹒#zFF @QLD)eG\=b#z6V 1uNTv{l;=W6sAD/gM>CQGDeͬcmi]P{%D$vb[qH( (77k䘈:b'*սg7Ǝ{ۧu~mbwn=!$@"zv)3 &t-Ǐ NM=_lQ̈etמK7eǮ=0z~㦘UBO[v<ެ.3/ʗcK!bH`>4X՟mز]A#Ə|xY?;tb+N|h|[w}/}qH ;yqJ=2]ѣrݻbM:[+oL-"zOevP^K#֭ [v =q_}N9zWsa8} [߸i߮\bisU(|޻rqڪO˕͊WnvǣG;w>cm~RÇ_a-c&MG]g>' 1E62>=kq%bvmg?^緐+Ah|Xu+K$Ξ/2S2uǫWm.Kbge/+OS˫,N>zInR؃jmJc_ČH4b|Y'g>z|Ҍ#AT߿c1f?rܹsk+Vo{Vsߋ9$LPΝ1#er'*E7ZkԲ*Tm9 q<$߼_o)]JEoeصsSRCD'O}5mNYc~=tďVո"p; o"]_ 9a Sj,HMrNJQ MY~+Wҭ+oLkO^x SVHHL_y%s+tmmbуF$nٵ3ug]ٓbn6ox{Ib}7i]{ː7tɍ2geLUÇ{{VĤ}鋗ɢC޻'ȉc'}~'TY8zO,,,ѣߝ]Ft1-M7Ї2w3yORB9+q\t:@բբ{gݝ;bʋ)f^fEʼDZ, #GM"q2{bMb´93I4 =qƭo4n,!&Ď4z4iᶝo 亍0uJX5uO8}1L>oϿ蹰aΑcⵃF>=CGO+'wⴳ_SeʆsvޢrrY_7ڻT@11C*P1ۙ;^XX?q<!dŚ`fܨ`{?6VZ3O~}=V;W[4K eQ9vXY%x ۢ!!s(P%)I{/ID.]9EWZޫbnb>@-)XV#l9f=|h\k3|]No}x /?x`QbD7nn| [8mNS_#8G&$fe"#{1cN l:fɇ}b m/suK 0eϜ}ݻ>ٻ_lqmxRt,g(JUGek|I~$ʦQ8DeU9/\t@Pq6A(:GtȄHmG&o;'n9;+xgb_((s|o'O)eSDKEJ]qs-:/G Ízr7+P{d:z~'{GMf͑]q㦤\$ܽo\bj9Ѿ]2oɹNa:.xxbǽPG6=(XMSLeP!Qr_hCэ2}o{嶈2f] ǒ+cc(g\ blL͡"PE2.\,ۈRB{E $!q\Ag´97XKFϕ1~=2o;(/=?y9ǖ^?mfl&zS<9bD~[w|(Fϣk>r6f,Cv9̅l#c1CE։)d w/>"sN1GP_Җw2ЗU[qEu2 sqVZ0#i9T1թFhL~e;;vX`ѳ mcLRf.;?72!Q[*r_yP 6Ϝ]8M|9\ ם9K&L؁WDKDEυ]!̜ 2sME)c,>\bM̈9H9 M4SE%;\ȉgzbѓ]*mzEM'&hNnL!Cl(/4WX*sƽpiٟe171O%ӭke3QܔKFcq3LZ+?S}R\a.G2*u]{FOff|v]Ї}gɲb%sRR߼gw?\&2%+Μ=g@n)sKDE{oˎ]޺-X#<3|TJR9簢g99)_}[0_)\1cS CL/ ]bw3v aC/4WX*n_6d=z$sXWeCD[J)se)'Vbo~wTRј+sѓCl{/I\LmDK^OK׈U!(iQ)\%c'{^^O<[AF3ir~rCždY *=si+ 7e@ M:ۚA=2o;(/=\J^G+VEf8m΂ϿaW`22zW_J1gJf،/vZR^.ۘѳ-Y28}5TKLQRH{Q%RXX龃'N d;"=.`]+57‡{>3iXCGO8DRј+1c'&Hv,g.Z]?_r&q2.zCˋeĎ>sP"u%k?\\bY Jߟew1~_x\'ɓ'ݲcװ'M{(XaaWJ_qYɬSCFMߟAgķśA\rnaEf)%6DXso3QJƸև)%()E^/Ŀ]U5C1qoFfu_?ϕ?-X7PפsSܹ^9uwyǍ8{~Sbb/X6hD>sVtݻ3v }T[Fct-mW]xYK<#9aly (>L8yŎ,^(^.fbެE/CW5љl[rY{A՟i<7l!:Cžd)cF&L6E=%8ߝ;Bc7EL8|h3dD1I3暋3g%NY1F$$O9O[ѳhp]Jb:&L!\{ɻ'H=v~O]bB*^lF ',XvZ^(V^l1gs>b=|8kh ۈ=8>q֔d]+t^Jdsr<(4&uHmTc&۔ufC((!Ǡ0Wúb_qS8:{A~)SD]S[Lylc-s8&yΗ,P,YA(ͷ%b#ڋX;,])eRquDQ'O~>uc& .8z`fMSRwjcF$$[ts뀹>,8圔DRJ\VΝ{>˙0mΠd}O)e '>B1[D5=z77ڷKI! D/zӵo6"=i)˿;w^L|h8mL8#19~l3LA/;pur'H8|srr=|H6.^ZnӨ S1?(DYKF9Ok?<~9)9G~a֭[?{`vhi{LJJ|뛷,f.JiN{_oxgbbbĦ 3⸳Dُa1Cbe*ōoֆ-;.xEۏ~'ކqѺ8|T4˦*hΈiݻ2ļvaӛ2Lg\M)TjeYvޙ֍-mQ#s/Rr)OJ81krc*U0mRvzɩW;>RT+* \#fype4DρVf }3/lJBk˷֯:7eWeYmnnW h/9W~pI\2W2s^1QԲ*x6D{viZEgSS+@ɱ'NB-~=Ogg^?7E]ĐD} i\ՒF"=vVaDϫcy},˘[V|kg){'oUŋ֯wĜe}>ۢe[RVFP1sv3o(Xɶ59uI#J'yav\̹%fۣsS|"z(***߽1pvY`l75+z~6e1pfS6pۢg1Jj ,8+)~2=OS#ekC`g|l mZC 3EQQW=gQ̎nEiSΤǧvQIbbXѳyCSl>fJ,RSe=N{ZMIk` m#܈^#z(**gC1kئsb_ߢbh1ۢg~5;h&(preԙrnYgejG.T=Y|ynaK-ѥ~YڶJQ&D@LQTU4F=bfMiP߽1aYhw̉7 SLy#LiIBVJfϧ}׺SZˌ]}rݮ=2u~װYm{#YQڰ$#SZ7_hݸNܔ]{Ege?5طwѳ1?+(g"'z>y2XjpM`l6<}7mjNm[7srnzmi?W]a)-&^-IU='o_L[V&n/a7Pg^}N_/_#82_Yߊ7eg|S̍u=rnSJMk/dIzg^r9vNzr&?J虢HjXM`ܪӼM;-NٽmYj‡;&yV[\^oSԘQS2J|z\|OkϬNXE10mجIfb3=,~ߙJG:/̞:ø=YۊS⭏ t= { 1³IɧH^8T7a"z(**hRgSgSgSgSgSgSgSgSgSgSgSgSgSgSgSgSg~3h׿0zK.?_1kN}8hL(<9|mf$:e[޳όYs~1ɻ3oնð.1)H=|0kێ6;^o'O?1hH]fN} |_č]psn[?Y۶(8)+S~9_G/^cƍlܬ읏=b)1%{&[ 5FvXS_rU,g(((H/gQ7o֪]DzEg>./V. 6J,yvaߝ=kLݻw.[ޠq߼yӘ+1ELYmr Jg*83RTe??E&^r޽Uk7ma:Xٺ'O>۾Sמ}S}ӡs#GI&Ǩ""]dFOgI^_W_LJ;Qc7ky6s[Y6gڴyK:2t~akK믿.Y^REw={aėbm7p ZF˶ޛ:=uR1n.^k˯kxtckkPj/~V7e9dL7v#/.9^+oTйgN3X_jM駟miުM1:DO~{ODʷ"]EO<9{cnmwlpl޲i'LtrySjjͽ{d۩KMAyIܸ{nѳ\Μ5G~cŢw~p?Y/^9:~oN+u[=knrZׯ__Wި^ =w1Bwĉco)8r՚S)*Š EZ,onݶúѧ8뻽́ m2uϳf'cjCViGϲoPVVOwiߩ?uΝu7?{𫯿; Kǎ/e23tfmFQVD.2gـ @F[o470#iYe=7lҼOA3gUVUp|,xW Vݻw/c՚M[(syy[i~_r՚Vm;~DtRDT3@Yܻ/JN V?޽go}{߲M}*+Wiۡ˲_3rtŋIAo4PM9nGwjު]|cǎ7Cnu|}ʽ"]E2~mӾaeleHݫbUfE "-z~Ώw5m^}7#G?ݳ˟_=w^6׭xK/0ya7nƯ(^,J.:~zC_1QO<;?DI9^b+fM70Fl1I۷o/O_YV׫.7&8{֬r_1"1Q27)۷?L]ҬewjѺUkD߳Խ{-Ow)*B EZ,KVQV_jױ˔'4j߯9kn7 fmkֲ .],^hӾu y /aq#GXy^Ŏ'k?,fGyv%uM2Ll1""]FϢ ɍY7dڻm;3йC?/[ -נ9hyܹM+ogξr%` =Kʕ%˖Ӭ_P;I~st軆O(34qڌ~ɘ+1+WېnbETy&[͛"f2._N[ޥ{OI֪`¤)' q_v\cEEB=D+sݼys>|$ʾݻ"cUhʷ"syՓ'O0hyo޼iL-cØPT3@#z.ǺuGK{^s7oΛos}e(*t=D:/?!fXrvC>gKVܾ}ۘJQZD虢+gHGLQT3@#z(* =SuE 鈞)"ztDEE]=D:g"3EQQWD虢+gHGLQT3@#z(* =SuE 鈞)"ztDEE]=D:g"3EQQWD虢J='$-3Jnӣ] G&#R&Ή,]DUD2@oaJ˽Y^~z6yZҩ,d{au8@Ze#RO#Le_%Edl['ez (7DEE]7zW3{R?,<稉jwA=N+6%ַ}+->yfa6$ѳ)Lw7BSՅey r2٦g8fMrl׺=P2ܦ;l_OL8C,C["kS{ݝySvOc|Ɂ_#;Ma^vҥՍX41iX a}a?[w;]vBu5̟t7+b{a:k%NiS]i}{lp^A.c)~68O]wazz\wǨ ?Vx'a ݴVlxu.z ۽^S}my4+;*oMN-1\"?upysv3[>58n<,u^7J?M~Yǡ9Y?x/sY :@<Y\EЍ==OW$\:2U=;m*k+m,ppsj͔s~Ѧȯėw_cqu9܉~*3]qYv2 os짵vO/̃P?nzN) O Wwn+o-/t~_x芾pwXCrʵ) vV!g>C^qֶKMn,Ѻ\vhBSE%H3EQQW%bxC8MlH9 ISRxbSJ|66'Y2gY_Qg0E_$?W:d]cI>@&OnW=5|֎Jx:=y|+e}(\83LަmHF2Yزw\XʹK |q͝&Z@gk0԰۠|}/vT8˯=rj8Q\lxA.z2_,:vj~m?9x^H+fZ{Jt6T#֥򻲥ۃ)Zɾ[ PD=m%G=Ϫ>G;ByR!Zro`>ɤÿٞ mr&;M|HvBlSTc/eab˳U%9B[\ϼ^u3vq;i Bn#OȤ#ڑ_Tosp8-ӆh[wu=c>& ZRdΛR$qmO]W"?Tol݀ǟȷ 2fXoPyCzXj;o:n,OON&]ܭsظxJG^Bvqܚ'd1+y+/LQDl;9;e\J H6##|ƦxYjsFI[>ppB~9]/C%Bړ+yk[Gj,߽^rDžrs_#(DEE]. u%jGXͿuO'7-vp⛡%7kGSI– zd=){D߾m6g=e%7?KՋlJrG8@)q.:u2ӵ9=X(8xYP>ख़+VJ2_?ryhwrߧnS€ &5c3@LU4rg q]1`FTㄌGufS'sڤm:hw4n0_Al2֝TnWmw}d/gD֏U%:"5إoi75l$YjUwom⭝>2𶻢vwzf[#,o:uS\ǃ/l`?q{s]rJTk1]s,g l҉|wFO䖓p-˒[-A޶l C}F*˻x GQ(q]iKW Y{꡿v2q9s-Za^ ^K5M& X15gs9p}u-|qE]x(0v _ԅ7W,S"V҃ԓzx/ߘ^q; q(+DEE]y=k.A,،/}\u@b |֦TA^:,zV[?|2S2-qŜ7!}7ڤpb0pTOJ,~ z>nY3JE~2w/UEQ,HT|S v.y{%suHp Wf3CrSVuoW}ғs THf51>`bG2bF۫rV 5#QliXU>)>O ^u6Nb=V6_4?Θ"Oӣ!P/۲pNqgG`pB\)nN># 2tPq(Ș=_A7}A޶o)659pY:==9R}ßqNl'l5%䚛SZtba^W9[^]yeXo".<\Hu~]-աb񋼐vBaNg'چ.=zx/ߘb^q< T矯Ϙ5{>4&QE,%s"R" e B Ipv8atiGخck+ПؓY7?Zzu5;klx.;~nwuLJ!:xO>ޛ$}yVw#}Ii7+͸N?RrӖ)6J _2m g1vU9fäqp,rm\:d\x*Jx<'E3J1m5-fvwQYҴ߅܆xpwp}ܾ|-mk)Lo:/̎9Wӛ?EƚNn[K6{uCRm!m ~8pn,GPW'gxNmVॅ!qzZ;._&P襇SO=-Żry.y@)(蹰nyN!&oFүǏ8;|ҴO ZܻwhK/0 ȸs~6bTB/GrsǎKV5i/QOʿ]AcsylWSLK ʿ c~w@rBuH[CHcA{ĘXVeڧ/&3qzW]@y vJJ3ԩepEEIѴQ#AͤE-3}Lk;wp)Тn/Ӕ8x8߯͌eʰ O 2Q5tu~6y6eu۾).%<;+k7AoO{:ƕF}[q\-p<+i,s]ݮE}mNگ%[ rFe5/]}Lw󖷯|or2tanOD\qw%4t'3dvb2zLD.|@`{Nٕ[` >$&|TvֺSmh.dlfvBG0Eޡ)/BAY׷hKY?Z}qnmQ!d} |y[ն T}ԡ3N-Kz<72Gޗp&}ixJʉE*` }-73w'4lVg|4z[ -?pg<~XLrߪ;o~͛7e3Q2 nѺ={e"۷,M[Qq}wVoӜCGd,C 7jΫנXC} UbqU9HR?l: ?v@Oq|ݜnOc z 8#W~> 2y쟟)Wű[~ǿ=ltVQa-3BƁvSGS@/OӺUK43&:۷vS쵁)A1zFx,'}Za,˔1t`3Y'MHoLYz ] -΍_Q[Ky{+rc#]`N!޶n[k+f[UuA8v}m~q^qp9ƣ;QSV# v1Lwvs7.<\Hu{ wJ7S϶ՁǼ_W\.O%>o(Dngy[AC駟̉GrvܭY6f,Ũ۠5.2z٘útyx1)Hɡ<ެYL=z]M[beק@EU.zc5qE^ ngyyI/x>jL l9~'G*T7ͺ!V3+l[o' w9 Gmq`sKfW=P>{;MyK>7Ǿ26%خqmS!jZ[z|*GQpgǍJk u͑C_=׷Ah>FOdGY ?)^ݹ|{ܽ\xKWp`'NsV.2ʼn|~(ugj< mۢ-]q; s(+Dnw.]W;w=zȘow]" ˏ?l6;0/4??E>cR8s].;w;{ɓ'}?|Ԙ-dm!ou coIUQټ% +ƟfdGVʢ%ڙv/䥕-Uml|[]:2 JNkHjVIK5в3Y~lμ)qjO դtٮȶcjlџr$LV2pѿ{Ntm3-Ը9x|=(K~J&eg KfI) G>fڥ}n]#ki!v [4԰Ym}j:׷+/ǤyTԩcRXzvV2$V_O}hoKCAϷ.sG_vsE:7S0+)yj:(][UVuzuAOZuf~u`=c/-+rsoDۀC M\OĞ3NﹻsWW>|Qn~:q};%zu6bs;gj߮7_tI ދ蹰p歍9& T!Æiɓ'?tmum;tK 4k"ڵk%sfI^_W_Le~>jXXcd[Qu79q M/h"zoԤ֬m:֭۷?ZV~)Ϟ~4>sղ߿r՚^}CEST)/gwԤicRmJY=[^K[kO\/K[(?r8U+]71+f5=;3Y&e`sr sO?y+6y_0liMdⓏvkuli XJS#*+/<6cR۴c2r粖+&3C]vO;>+$) xp'E`JƲmƒvSeѻ;Ӭ[q&u&1f|օq?%S{FڜNLg8/.иݖj,Nۧ[bn瞷W[a7߹Bw X8A߶:K atYcz@zf@~Nu AȬVkd;p`_yכzrAWwp՝(ąnP vʕ%{spK\˥?y駞V|ӉPc2rI8#@و̻0M2'/nӾGKnݾ-<~8h^=נOÅY6j}&MIܭ/cH~cfM~1Wb>mѺ]>ߛXsƷ*2z8׮f-lvAJbYScԡ(X\~-ܠ*Ty=!j/ȧħ܈ qݓpυMͪi ß/G ׶Vt'%W:O%]jiu}< j웢ݛl.i#5;3OGҟ tE'f})wdJ^e]aAtiIFN'di]uϓ&L}V:E$b{a&A1̀W߶cR| yLMk תŧ+8onSwǷp֩X& ǖ>\IHkVX hW|k;U8 O kG;hY$C93jWOŬ)pѳ;w^V׿u}w5g+чb7m!vẁ^/Jt`|˗4&QTFϕx}*6Cxя9-Z 1o7#)ysc,oV2z.j"IT^s^~FM7m4{<3$w^ƪ5;u]f̚nPn0uI-=F/̛Һm%tqHQY<O<9p0MN/ R~r=zѩ/5&[n=l!)Z广4o%3t}"z.L4R2JL/g'T)E=0s [*ӽ:JGixmNEyEn3xƎKngc!5|Ԙ]>b,뻳gc?֭[ ?\ܩ2Gv=߽{wɲ1CÃT}*Ͽd,ѳ8Q04nYzWmYrըU3ֺv3g 6ȧRTts kda;io@c<ͫUór1rEy@?GC* }'H?~|`N!S_?2Me ܤys߯נq aC +zUXX=-ZkиA9Hw{us`!%%.6n$3Uk )~, []#SZY\~:..QR ;y%@􌲐0-i|.1o znYQy2:zȘj+7ѳ\~߰T}LMoT9͛7OY3g]vMN,v|x~=qEl{^wwͼ[788v/(B3@suM2]mն9lЮc-ZgLoܸܹ*7q3}.,,<{={߸!t=м)7EN1Sw 2oNoNm;ƊEFϧO={_~e,sҥi3n%)׮]>sV:okkrl)JNVs|ߥզQDڛ4oڢMNK-qFǏoնt;a7 m!׿ 0rL|z z(}ҴoԨUu2etFoΚVٳ1CYj,%׮Y1C洘"gַn0qrh#_{kXL'Lk7Y0/eԓ'Oع5  ,z[&Ua ҕWv&sYs_4mE-ubѣoNN=V׿U}!?]cHGrcFokܶ#].[oo={E^w1:1oTp_%g떚8oܼwU)6DxFm1o]}LgQof:W^8Q PT)gHWs4֓'O?py#]DlE STXE 鈞]|~Cɵi%;`Бܣn=D:g%<4nJ+WS#X;`ҴRT+gHG fm٧$GO<1C?A>*^=D:g"3EQQWD虢+gHGLQT3@#z(* =SuUC-[YÍF. l 虢Eϱ}jhWE*5լ8fG KDEE],zF,) %R;*n~U :A^=3EQQW^FeF iذ]{ ?^o3vtn%KQ*|C [L|A/ ߳Az\{9S-ZdYsyq['c(sUmseAV5z }bfm̲DF㌽3Ω uZ4F~KC kDEE]flNmeLT\*f(~n|4{vo $$4;aGFj`,z6Qr3ݺ9E,S1bZ\7,YLCZZڻ"5'ѻugs/4͘wZACT3B|mzg;ɫmŶjj?55TKYy?ؗkUi3D]=mג屭pXBh%j7= 3EQQW= z33z#0]OHۯ2WT6uA ӂ~?ؘj n#&&R mK_5o6=Kzh/n=ZkAs^]O>KfR*Gwmdqvc;[%m>ջhlz=3EQQW=ͦ !7i5ڈ#eSb^=;_QwnU7ahN/Vj-d>s 2G6F(y\p~Ŋn7遯LdP?}nL^Ui?fˀv2z\n0nlۣY^j}[_17p虢+ϣN_(R;-K$Bv]9g[F_1}`^,ѪjA9#7x'NL!S.rǏ5"]wlnMuz1;7Z5ѷBK/s@E;y'xۭ}4nDw'IXٷ_9=3EQQW=SzЗHō_{A>3g`w Vyo&@mr=jƂWBx\ABw;dPd\w4 >?Gkk?괼u:`h 3=Suy}6-Vb>;jij{Qs-LN5Gj?./aT610_Uk^\K(B+ZUƭNHݪ]}G0'yQb7ĭŸFkcn3n[oVGzQDd!J4blk}AOp虢Ru5kk|]^0ڌxǯG:NH4N˗og91xtJ&/$tTbl-=EfdNzg\#z(*lg9Xp/?*ej _[\8}ƁKK"=ж}zxsT٩%Ws3_~0nl!wjev\{׈)*oWbpjh/?SFТjԣ1)wPC*3o_O99zv]. #FD.FL$LD%1$1jDc&Lz$LDQTU׵4Iu*Uz׻_λDs59W9w(<rlq$*Xl+O&4*z[G+ b[?s֯?@_gqEZh%O/&B:* z 4g&&7-0Ft3NgS2}}#/#3}?{Cc.Hɏ zO~Ө{Zǽ2枘yMDL:O1@Wgn=1蛈ݩK+6\&6= =3yMD.ݢÇ<+n}?{*k/o:ܿ{-uY^^t{;/獷Yvz9n{ŚyΕ6./kg׾;B$Vt^|so~'&/U'|ɧk6\_|cU=ġ#e7oe{pQ:zuUx`ȝbmbfd$ ߯X]-ā*VۢݖX۶&E|Gß^xza zO$&k4QbNr./q\ĉ;j&gtsU#w./w{{_Ҋb$ػ/׉a麍nZ};7o+\ry[oޮk҅\Q^UfZQ񒒵y믿1rNzeU7vxuk?'~&vAXXlH\V&wSez]Zk%Wn3F{{xꛭ2\wc}l"^+f+ŗE[{[nuXƪ{y#J+w銞*knܹfCbxDGǎ}|emb(.بޮXEɻ-YW Q'b?zQ0!g]8G'>xY^u8DkGPo-3@KZ]_C=P]{Gs9rZ}gub(^{mwxEvk~w6oiy=zgxʚv:rڲc/{Ž^=W_wv[Yw6[xСzn[!W{Um>0/^.V"V%s?wUX}o%f%zu4{}cm'#=Uuto>#^kEnu~Ul~;>/ )^UnCA,ɧm!W=W&6JK7zDuAk鶎Ě knÏ>~O/uV$' | 椪0Vl 1Y3Oxtږx_ ǎ}~U73@;UrGEǂVfO>LĤQ+3g۪oc^'ׯaǣ7<JnuxPE+ʫvw=V_lElKO[;bY{dߜ^qL7s|qaZwc;~߽6QNQZQ]%6!6d%z}n5ۧyn XQo 2zvMB\Ï[Xs-⨉cy[:=#wm_XIN7u`JqN +6޺?}:Z+|:?-Y!(ѣ^㭇}[֩$D!knZLw>kohz5ᖧyN7AWz1=#~Q6QBQN1*}(u+Z)vAU?V9]ѳ~}W_}媨O?m1?hz%CewLb&+_1}͡'xʛn>Bf+ N֦{SlQ ^+%F?wb}tWݴt庒5~^+^b,yol v?r_|[ wm3zS=e%(\L./~kDŤ/֦VZwC-f,㡞^~ksɻ-1'lY+|l.k/R[?19}Ϲ6ܖ>Gժյoc"zHw'?zoXy'c clcCS8¤Վ =j:%ǟ|޹|1w,M/lySemھ'0i'"zHwDϩNt,}~~qۃ;ӏ"4'q#Gd'c~g{uwb'g:IO =j: ѳXXRpu"EZon|vpw˝d&v<&gtGDG?|Ïe*-;q=ptOG,Z컨Q6x?5yҦYt3ӈ3ӈ3ӈ3ӈ3ӈ3ӈ3ӈ3ӈ3ӈ3ӈ3ӈߟ=#j=5g#3@#z0=;g#3@#z0=;g#3@#z0=;g#3@#z0=[e`og{>Fqkʫ:ű>[[=q`tYP ûϯ, *2-E Jj݋=PwSnjAY5{:j_ܴ#wWc˂h)DF gmNoi9ډ_)2kl!)Ɋu秚;*m3ssw&lʴf!y%HgJ۵T;wDFgV<˞ *:u(=glEc}Ʉƃ [/|R\DLצi[lNGV7g#zvs0kۖ;4ֈhGm׌,r+i)h7.z[BR& z^P;e\=GzϠӇ'~Y,fUލ+kTt<3[|Vpz᭛2o2j 씝k-ݼ[|MoZ.kV.4cm}gVnلԒf..m`C79qa܆ F[c4X@wc4fpNl׮=ZZ!!wDV__/\Ў9mt%7zۻ0"=褃ޅr+DF/XW͜eAp5*,(vdjb`Vpz4*Xq˗Vt0ga_$SrV޲Mc]qtFkb] 2".ȦmNӪN\ggO,W=Ѿ;u.iY2w.9Qf%ŋ#2nьb3h-Tǃ]5ЙˀA+7ǡv9յYvu>4qV}6$밴$.la*P-}[uآP\muΚ5|ai?~jY{m%]K7;gɿ}9S~{O\ >hS]׬zmoO>Y?y;o|k7z~7\>ޖ> =c#zQJHutpY6]"ÌqeTjKTdV#"^kzŪz"uUH]l:z[gdP5FϽ]=2PWd[-[[sH[|͡hW̃\sNHzL[wnEX7={ck>}iF=쮰86z{6WP>My-CdkZ&_|^IiglʥΞ3e欹Ozž]Ϣآbw\ x깿{$kn̜_/ɼpzC7zIg YD0Z866g quװ͈&[Yhi#Ax jrG5}ZCEQO}MKsgO*D;ѳÁh~3|߹w |c;b{tU9FjV1@gJ9:Aί"(8ѳxX񱫕xw}1ֶ .zoAƗnX!91Zj>͢GޅIW*kCxK櫯y`^xżrmmO?s-rſg=S,vy_sI=3F:gfH^c8Olt bb:#3F8:x65CwMCpfoĈ&sCm! H`W暾z纭>E:ѳY9s{|{agnW Lݕ78O^uL՜E{ko2/6BOpd+ i@_qkL*(#O4@GC1ж;zP6DϯQzL?7۫׬׿im^2ѳǟ74Ξe뽟C $F/Jxͅѳ=sj cUhw`+{ BFϕ-тc[42>W/Y2GaS{Dv{}<7tM,i|O^k~EϮ6ΗQ9Ƥ}2en46v&S_ntܛoߦG>yyWXK7^}f!(zC=}ż|+%zE JwxPݨeS55ʸeoYs]zUXZ?);d?.-KYvU3{O5cwlѳ9:s4,AHRI"z3!S=ǫ1TB=_;]1/gC$/v>tդ??b=ҵz͡=[gf}بؖ 6:7ro{'+ zlO?hU?gw>#+n}xgQO>Ìs: -yb/ﭬpCl?{Xkޏ~1l߰3fz`]+T?;qj?"ٻ9|Za4N'h`<pѳop|~-Kyqzfc؍򑀾sLCEz {^ޯ?{I"z6nH7 [Mu۶o)kң]y\vWWz'5gK%"?O4MwZᩎb.%W_s%X_U}9oWԮC{7f_v/x`}EK]ž_yyc_,(zC7OŜF ~[-z kĿ.)6択?M;^/-gt ^'q}{_:EKXBanwi[scX9nҊfYƅܾb|mʼnZ{槚l}USrle͚RF,PRrf,[wN5Zwh(Ua 'Ԣ}6ӶqKkJ#طjL㵹gYd٘f_ =_ s篿9Ў+ܾ̏>tÏ>3/^aoTT?/[^2=kFK6ݟWGhŗjd s_ά8{e~ʮ@97w<{Er]9ٗV{냥+.'#bNj?=gsL4Wm?pnyKf?-ͿWYׯ,{u_ɝ1"=6p$n#UCM{Xueydm1 Cu4#x,[:_+6 =<&WQ{-*jfOGMErdVnYeE5ѮHIS{뭦UrpT,7$kiߐ:Bӎ{ QcfZ5ӿt#NlCu} {b)p+ ls91̽l^; UNeʲկi_X!ilOu|U7Y/vDGϟ3>xŴ#a㩍5b?^_rdz=NJz끎Ξ_>rgD0A{B?q+Ҭ\a?.4My`!rfi[W2D##Vy}[!gkʫJToEϓ2&om4:JuUԹ~*ѳ5BȠ9D֬ѦA#W5>Fѣ3uzÏ6ݵhq9 {^qEh[|?IozyjG{<|ko|=o{Θ9kIѵ/B ݝ#xWpÍ.:]͟@GƮuBBZokѿ: >r]Oˡ2EKNϿϔ_d̉g;MN=S~~99ss./ڦ=x -{gКWZK2}qerg,D$Gς8pTeA ~.t;|(֢e=۫׬_PlszEK\5{WgS.xܜĜ 9Zo;ֳ) *t֜ n~gtwg=\K4g}W-m,w^7]ls:"+?p^uܼpqXT_Q15Jg͸#ͣgXͷv<_0?v 3@;Gv=3' w=;+[d(pM{z֌]0'Kg=gSfΒ ^7+U?[lō7ݼpqљϚ2u{[>sb/(\U+gͩpʲs33XX^Rh̘9Klw ;=@G֌K<#e9gt7֢7޺tVjݨDC 8DC 8DC 8DC ̟ ]Scbbb!d=5g&&7=;g&&7=;g&&7=;g&&7=;g&&7=;g&&7=?5Ύ?z0111$.V⒥s\4gtuM|ue0111$.V%.\庠=8 [ھ;#abbbJI\J\ąK\\4g4;>/.,xWzطFĔ6c^~2%sg.3@ZNׄ4g?\FזV[|+-+ ( &L<;Ά8e\0j0 ň)F H1g@=RbD#z3 ň)F H1g@=RbD#z3 ň)F H1g@=RbD#z3 ň)F H1g@=RbD#z3 ň)6Hr|)={#[G΃eiih(po)ߦ̈ttR+0)j݃|1%}}ꌺȾny=V4rʮcnT=yNz?rޗpNZ:[2rzs~yN޴'0$ޅ_-8 <XeLSsaIWWTEWMtW+is1wAl#ѳ͓$nĕqiuyOc@sI:_ O=V)s@u9MI$Q0t7R#=esP,om54%O'oqݞ=uAUlQϯ;v?n=NYth|=D&9}}jzqL#3=:&C҉='DO,*ܞ=5{OD4 v(Dϡ%Q|I)z*=m;anM|꜠ lʝr==@o.D MM{w5_,Euݎ}#JW`C;AKHTyv| w z>Qؔ;$zNwDo.D ppx/ip/ eyE="#&6"z9_I|6&z%/#ESDψ w z>Qؔ;$zNwDo.D ˍwWZ@X[;Qx?DMu')[녻[n}KbanfӿnܑnuzKX}׊q_iz-_Z>8\z}ɠ[ הWt鱳cYXdJ 5+6rgagQ۾zks#ܪVپ۸ v45/ Ѱ*^z &j<\Ob:UJzukmkkC5Vpr԰Zab0'pg^ߍ*k#U66;z֬v7^diZ~UnX4ϫ|R GTQ/h|FJ.*:lgG,O1T'IP :ŎȪ QNmfP'E[:ćeVWbU&c$ e'Jj xO7kqKu m6XЖoCY9ђYXc3s u7l8 nN+Zn*AV57c7C+I\Bqƣ0=;\Y'_5~8!Ir}ђApJCy5m'{:ѳƜ{sQB]9õ|&-JJd#A['q66] 5};zWd k1)_zg%B.<]olPZB0o`Uw7?%F폩qr)UGo+)a<"v@K]_c݀ (vJGH@s..[pl Nn~2OX^O2Y(8+ՂqDnQ4G3ԓjfsT[ޮvqB*ӟkD 08|0[@v,o{Tλ_17a?({dM$,Y+jč`\qoq7=欻E7cf}V XBgROm}\LR,ϐz¾H-ga0/ݭrWw`S}q'-oc{7^ZK99B[(o7j_dQD|rCs Z[[9ٺo]cr u[i+GءTBl︗"˩5?B\h5l>%]e;23K\q%q%8{چ`oq38lK$6@uP4vnE%g3 n*>¯8v&ĕ![X3|3L_Jk߯*rgw~%)"9듸 wvtX-dYf!G2+v6u[Mԇ.}üPuC_y; S03nKoS:ο63چPǖq>}WpoJ]iabzvC!J'DOw0oh[7ulՒĈoRA7p-$+Hw'}b}cѿGO?!wUjOgO~٧~ྻL_#t^O*gWhFW ߰3؍^>5G[e +>ZwFk8nDE,jFNq :4>C{KGP+Ek$!fG_!OmRimHt׺q+5 9sfc8C\8%]ߖ%ss%A]p|jN_bP$>k>A9upSJb;7 qͨq3I:]xcr/t1=ܡ.M=g}enkݫu?F ^N ~5ܸ7rw9۳[K7i:F_wGy?þEn-Ԇ5'/WO}v?ĵv=*SmN|;qu}D wuđLl~}fП͛}O!lWŭNzX0nčU.C|;˭!ݭ>qܜyx??yGesG2ku}椌|Yf- ›v[@I#:}& OU'ޏfm5CχZpU`n?VX5ك c7jP80[v?m5յWU6VמR[UCCVaw!C[JuSV8N:G 7L4[aOm]ώTD;e֜?n.=kxB\Sd.q' Ȝx{ia&'Oc.I}+mqm!} n*ɬ:v&ԕ!H.q8fx 3[5~kKKӰ>Yj*sл5?u؜*RB҇۷bͣ7(ԅo\Nۙfm:|c L(Yӧ5Tˡ3 >+[g_i|iQ֍rdVscla6;q Kxg"P߱]w]c=XlsNL~o..bþn8ACr}wAR3>i>?ݭ8vz%|u]}~6U =m~s,[ ېqD/סt̅KxT'&X k32&ok0}~WP*>/וS3]rF5=2ZE5.^Z!?٪=B'p¡]>ߵ+[2XNFc!hn_hAU=3UEmYn1r7%&\{8~;RzO7u[]ij朐T<"2d !ql:uZ?n?+*N j7,׼;IP=~f1wgb$S{;zc@vaUF_OG֩*IVAs%t4CbC!J'\œ2zu5$Rǹտr{NLz]Ēi YIF_2^:8oͻf̊qd~,0;>X`ǻ7Un S@>zlcܡW)[α5Xp-5o@P:ËPpI5OلچslXO)Srr{ǭV%5CSՕ#Kuep~M>;jsjoȘpkU-ƹ?:4>\p}*[r!^4~]iYG^`KixZ3A0;T=oQuN\Ctq%Nc|R7Fm8N_Y1JrV$xmsBKpSHڻV;!PFtqk@ jm[m"ѥIIW>Oڨt>:uZRk^׊MڷT`~o;IP=qflшH9滊a^Al|+g~e`KE}|} /G zO9=O&}Unɷl7;qB*)eB[ dfqnDw~AgiZ^Ēi YF϶瓸T"8ol: 40;>X`'5fm*?fk~; =׼wjN?vߧNoϝͿ׭QncPpI5OdoU.4׹WɜذI`wu1SدSdhfcq,~,{|{+6i#/A"k-|I]7.#VЮ̹Llzmׯ>7-El Gѳy5y,.7r}i=S4{c&^UW t6s1 q ݪqm=V3HuGJ/~l'n%ci<:7yk6ߪj=w~Ak Q`@y,'AQѬ[Wg}N+gyv9QAƇ/?=ϙz{d)n>Jܟk5t s^Lp^r1~{Hq?%=W$/qG:Ą0d%x$WE%l]ý28HqD]Jw'_w7t.v1as>}JT1=uU'`YmkUCF'^%K]o9߷wmeސeL5V`ݭ΃]5 M\'=͡~W-0M&efvݴ=P ='xuՒm~l1l\ƄHGckb}s3wʛr>YX&ݍ;USTɚ5z]eNiTdYx?EIUdfEr|첫U,w=Ggy+C>{K[I7RR;4k#_Ɩ^{Q' d|NjϖjS;Rp}z[wJ5KE񲃤t 'wTѾ^wf֌Uf{#t<3CpR} n*>"w&>+W3xYGE}צ_WQo.zmWb'v y54 6G}Z-9uxmGo@mfƪ:q8W+YݑؾoN4  >X/u# פ1v[_Ŏ >#[gH1Vfn( S*!)/mmzp[ xGvg}P >"6v<ѳq]m51(BJ)S{.{=5 On͍Ad zxJhЯVݪS#s}[k__Zl uw"%StD%J`OUhL5o4*?={5O`۲YwڼlUa{_,l f<}oU2qS.<zIkVW꧖J*8^m6KQ#d*b2S8Ծt\¨f/~nJN{Q' 蠡[j=1.j5̩tL|̺O^2WR3/VIƻԛVjF?R-zK/NNR} n*ὉڤkYCm5QV(`s.IpmB]g.Fϯކϩĝ$nAجݟ7Tᅦ >?AW0s_[ ^&mP>Қ{qz:0o..bɴ|㋞`A]'7=ʸ v>YI ?9gLh㾅 ߠR-h=zӝ(pq$﫢E޺_a@z9k:k[[zšr ms#H=q tԦk:]KѳHgEt3]pڈ!DU|jyڼNPUmF!؞7g~ {񭱬Y3;F!XVG;]W{ ooD} }h& V='t V= H=4>|Oԥ#sL,}<N>m,iˍk5tL| /-.C] ;wyJq&?/¦8E݋m5qe$+Ħ[C\ |۶j_JU47q ^8xWmR!p@ȔE r*ցM3'EEK|iq?s*uxX}%\n\F4 ~ęYxWxoٝ4 p=`P-FI[S^m~5(\vUQNw=Up TB8 K%>ewYl]0.r1@ޖc:P~o.j~+0 HyLs'[v`-?cN @#08;ɑ/_ F=FA@ aL뮩w?Dִ=dOO`ңRy;cu@lяkD 0͏Ga=HB~}-1Î.z }2 !BV.[0>R֐msy|~YL@ הhւm_qd@#۾e`A wsN)c sioS, ʅlOOTtyҧ445Y۷i&yJtslI\^3Vg LKѝKC{S=N0nKW4sPwhY4zwUAaoss}Ku ]Jӡ}_6mifbJ`#z3 ň)F H1g@=RbD#z3 ň)F H1g@%Yx]5Kf4ڍ"Fpsɒisrɞpg_ƄKDɝVXJ 5k.sBkFX|uW?":_xޏ]g`9'Wbu/ʺpZVWˬ] _ϲ-E:6(ϙx}el̟^4maʵņYې=?Vb9,U]֓LsVTV˛a?^656BfsX#w'?u/8;#_/V3 g9&Jɺ8:~zԫ^e}Vg_D =iműe&\QRn̷MP8̂|9bw*z䭩ipK/:13٘,zs[Edɤ?xJtkw_صO,+ǯ4g`9y_s2X4ǘ_~9Xf??w HWߚW,7>s5ˋ&s#6xWsbN?' =o5bk ͸ZlbqygkgeXfTxEeS_xb#z߯Nιl~iI9EɈyٙZ\xaޤ"*ծZ[R= j1+z#0Wezo󏳽WLBþ.\.}ꏼvTg-ⰻOrOϱx twcU94_h_(_wK|V21+^9d= Vqm,Wz&׬ zƠD?ťYŪgFLV|arѳStv|ٟ%ySd]+ kIxNiMjicĉG,Zis\% p:z_xޏ|3uMj٩6 g[s>%O- ѷU| zƞ䒋gsټ^u=9j g^<;W~9GsvGR1s4=r]^|UIelחf=8_7gYE)7zvLV.=zK_o*~• .*_eeM!=_9=cO3zD;9h M[(u BW*pEdl#KĞh9[v6:=SƆdݍ]hYl4%:Ɏ1vptbq:N;'n9O-(B\tP1h^/Q NԒ~WLYϖareSϛ0gz\^e5Ĭg_VrՓyyr; .VWV.pV 3MIFו_lN25j^˸ݥ?ۻNGVΛDWUD?|C/B56Hi3012Η~]gg̪Kuv Bt\YYqmn,hy̗}oY c Dl=Dr5ֳͿ^iyZirpg]0m.qQ!(ƃ&ס'zƞFz`qUأCFƯP==)EԊ[[wq*Lv.ֆ=ռ*zv<̾^,+ɨ^sz `d ʺޖ8ѳ V"=ϳĜkvD6:Y^{UsN#BAc=F2{Rg-\ʗ؆`kLRw5m]{_̗C3{P{&$30"z^ygQɜ%ה˱/T$wqyB9ʹٳ)56t%9#f9Zt.BbM rh;MniZ7z>0dؚSE$bD#z3 ň)F H1g@=RbD#z3 ň)F H1g@=RbD#z3 ň)F H1g@=RbD#z3 ň)F H1g@=RbD#z3 ň)F H1g@=Ce`og{>Fqkʫ:ű>[[@-=D!ZfsOk>@ #ӂ޵x~eYPQ'i)Z WWU^,M9lLWkg.,w{kKTr"࠘5#_֪Јk#`[sgwuQg-W1%GVf@KZjY-_X٨XU5=lN֜vҵd[y_ܪif녙S䱶n-ZM;kʫzEVEm_zy5VnE>T߮=ڹˉˠDStV>רӉVu0q_15 XXy֬i*Fre0&nF^ grg@#zmEV왠>QNVA]k[t:WLhNhfU9{7Nm?Pj$hhY0&[1S뙇:ƠFh}Nٹ֒ͻef|`O6cm}gVnلԒf..m`C79;۰"{k nlv܉-ڵGK+;䎨R٪H=O*U;bWj/R8.O+>9o{W#l~g:%BBZLu{GB=Ȧޅr+=D9F/XW͜eAp5*,(vdjb`Vpz4*ӫXq˗Vt03)a_$SrV޲Mc]qtFkb] 2".mNӪN\ggO,W]ݙsI^g͒s1]Ρ2+)^\aYwjcuXZmzdVjɽݢ~皯TmCt֬ K]sVk+.1O\ggKYa]/f>~kȞ*#?u6l}_^e鯑GDw*mŶ!C\"]59wgDYMɝ;gtTGg ?rt$tPЃx z[Z[@UEꪸՑ;غuni ,2Ɯ蹷}+-ז~-EDc]lw fNc̃\sNFcbe5Ds+ƺi-O7awDZ߳]un:mo};nI{ [ 5!gWx&z`Sll+>cqۏqZs\+؜yj.9h;.D066$,ΌFzVrR@ ke*NP:o?'ܠ.wDNYӧ5T40GtDϮB=;9w}{' b b{`U9FjolZNm$ 'N.`/&c=V|j3ޝfi*^[E[7V!̯|g7˖ѳn-z@$=KuPaj0Py绫]uD8*:]UǽD*;hnK!gJɝ/g񌞪f^c8O@V(c#jTyrcmC1_* ȳLB3ꍑ|}5}-2Du[}trgs-: 䊞=7mC2> =.틍*; HM6bA^}L=-GI5e'~S={vM ([%WM&S:V6jR%W:6;Ч0x%DMѳPprg3|fOU =+q =sԍTW+LjRWsO{]LVw"ZpzlFgVYGϒ9 #TʹhsVc3}PAWߴ@Lj0tċ]!>_Fml0=i_qkL'S־Jcc{kR@R/Qի=j]A~EVW G4w&rg7!zQ@]So 3;qc6HnԲ?JW-~p릆u.CCr+,RQpJgUVmf> O׌m iYoxBZ^E:FBOѳn=zb8x׿&՘R*l$19i=gaRbړvǴ-T`~k.$g/1tS=[cwDYaF웪dLE֊Ԓ5n^Iѳ1&}{/4esy zQAۚ|76?t=+싖؃9 voK3Qfvw8:B ;7./a I.Ƭ_1uVqgޅ=[Ap{_nwwՔbYfTGcsPѳC5ͳl]ff~|6A}-ѾQ4*O~A-j3mF;}ۑ9>>^+VJ69k pѳ8)BrfdF75 Ҷl_vA% _QYkax-(w7t.o.#Z͍2D5bov zazn_ⶸ\9CM{Xueydm10]'3־Nlk@ BfRVJԃݚ{"*yVqg=5 =]AeS{t[ILGJ"'M=cKTﵮVƹ{hX~GKORѳܐ|}Cp M; xgGG5k[Lj0ZU8ѳyu57[Pw.àQBSk'-tK ?ab yqjWkb.yDW[^ =)A ?+T-:aMWS$w]i&C~ac)HHeVLjܚ.-[sy2x[^C]uߦJpl9A֬&+n/Cyѳ0~]iYΈQu5~ɣ7R!D$= Y26ԴgS}YpXwhY4r;CՀYڙňk1]˛b\l[š)v3 W-c@pA #z-_Xd^V8zB\"b˗Xwa\>D@J=RbD#z3 ň)F H1g@=RbD#z3 ň)F H1g@JM.4;sIENDB`rdbnomics/vignettes/dbnomics001.png0000644000176200001440000026014213414003142016764 0ustar liggesusersPNG  IHDR gE;gsRGBgAMA a pHYs%%IR$IDATx^݇__M/ݨFņ+Eb`EhFcbI,1cLb=rpٝ]>9s`6뛙^Y$ +E z^$ +E z^$ +E z^$ +E z^$ ?+U ֫y.BˁXݚw޿fv#b?lZPAyf鱭3>Y94ob]S3%)ոC{ rH/3SeݶC([ϕ+YAD7}{[o_qԙW `zO=T :%GtSJ*cnd_VM{|./M 1w}f-Yq۳W_sǟooduQRhFfYp/]s+WOwnm}Z_yP\Z[phðY+l]Ԅb], O9` ӔEz*?'rƍz([Tr„̯9 ˯N@qؘ>_g&l{}㓕S ?+e$?{:Ï_[y>خwxRQ_?GP k-vM\4eܚYfg7uG6[{VnDi| Ul!3?n"[M8?UO-Z(}bڸ7RQIX߮ZgÎqi¥e6ޡ|E?vs< (=J5~]$ϖ򛐓v᪵~A!;P/}̋ٶg*״A߬7ػܰb_-5vGݾsWG$:SٟakhpWM%ʽXujv фJH, k>ߩ>S|Ԩyw3޼u ֓ƍ͸}oUj9~#ݻ/v}NǾ%a]#>EJ>SDZUcW4y\UeMhT߳ݺ}{q=0~|*>z(k\7F~˿vܸ^1īpNHX\JL֘5?֒Q_Hsl'Ͼ)iodǶ*Y, [/]Qfe7kOMX)QnIixrRS2=߯ ( ?j^٧5_v]ǁ2=C„LSvG=(9NA|WʥUjԞ8}潀֛ B 7܄U(QAZ2* kUg*Tjj,}[), ҵ,-Z{jZ/,B￿V+>-oE*XwYSQ5uI<o[ X֠n._G٪vYdݬ7xƟb5l\ 'ϔ(7l$K2:uKuid+,}7۳?bIX\[VЉoψ>|8nj +*;kɚV3.U6I ?d8e`IX7G[w?\we7k%j6/Ğ~xDٛO]n+e[3yڟn _9lW O^X 9=a$s>[fbT kyF]eSX'.ݼuK|ohSֵ[_DeS,7 Ξ@$X֌Y W}?~}KWmۙh# kG̛SMu ͛*[劄zdt?hȲIsXKo;|;&v.{>dNVV6=BWrE /kwl*R$m砰NX߯ҕW7&?S{>]M"_H:yּwoI<5}+WD|+B -W$e7$ m(,زIO~!zy Sj ?yˢ;Y[m[= e5+>zWP  uHG6[[rtʓ;-o_ujW I/}X].M)in=)a.c{^Ў' l*R~<ۦ+a}ߑ'+= jiٳzs?\nٮl 'BݴX??r2'M"8Vy,zJGM̝ϴ5}W YP\klI: lNXNږM^-5~)y1#^PU3%ʾSySdeϾ HX+|~+ѣG|C~jz-aʦ"jVePd*غgxQLL]xի&8([1he-FQCS z>}dQ93(9Sݗ+dTwp}]ʩ3aޮQwꎥ>Sv(kY= =^rEpڵvWjU-8TT$ߤlLXbnݾ-^ߺUM)~QlReyS*[*N1C[2O;&9=#wJʞfx\VN԰BT$xKCZ}-kߨZ˲ILr&[=IOMX_)럻`'߬R O?o+?}!iZB$<)a}/'Rϡ# XO~{J5,$aQLNլSKSOz@^n&gdK7>CVVkRư)qeyD%e P^wW$gM$9?[꯻OXc-}RW)[MԄUxb ?_z1z5~/~tEeka~ C2 =++נُ ~5+[ݐ!krB׭^w'$x$(;gUohf䜄ޘPgd4KWL[5g̉Г [_zMÁI_䂖}D9eka *TI nM{s?\ٲ kC{od?)[`?wXe~5ܣ'NPO|O8ǹg +T7jʼndb;OXi3:K*;BgSܻwO) '%%k6s; а?;?|lVF* 3^lj5/VZ`rUC([X}\VBhT+m{>OV{YF$xVT}جkSB5 {uOݱgߪqLX8|TY'%␷|GgMWvNVsÎ)`;a֡FVU˺m;긍TrޢeC[WnZ[-7}1 e?2{9?z>}-]Igu@x"̰$ÇdsR-;wU-q ElVJBv}[J[R`2}yVvB'$ :z(Sp'Աk[I}3 oaCS2?geX;:%.ݲOvBXAxpRwHym+вyԮ]Z~⻭hPc}Z{ɤgD|W .w*12m>KAiz'%-K&*޿/, k] 4 Z vc&*}̢?aZuy떶'%B.=wϝ;w_\&I7h@2?_v*77k]i+u PN#1=m ;>Zx%j6{ϯ!zKe*Nɹs{YWe>("KTF}1K/oI%=:?F)P"nYF~4k bSc<>]דjNc_u{qAM{qZIC, )vxgO#MTʎB&=c,I6\PLvg_V`&ڵUqz֩A*'InJ)]d- g8a?tBZ~!e204:d-+` @IWɌO9XĂQ "j!HVf\R:hLrbLl^o[0mՄ_kJ†і=ƽ?z e*ZQ)o,lGs[Y4dLmQ6֗T }ҧ zM7;uo~'6.[#XSVOXVݣϞ:wA}8}d__p,bӔUFbwW1s?j)wب4klϾ+VҢ!zKX^1)%Z76#9->jM RHaOOX&ΔZkotyJrl|nߥUQ3NN{R.2 xO펞3#Yv˿o w I(`u3рȂ?ftfʷVCt|>욵oME8NyEC]ac56Ry 5E WQm(HX=c,BKO' ׮]o ņ=~EMX6!o4_ gr\*!ږ#yYUюc GwiE3o;%&hxA9ڷ&g ޴O+JW:FDʵ4޿6wHoسh*4 E&Bf 8};Z[>;T - 7IXM=tޢ՝w|~"lϰtrqK |K=ͷs lю#5YSHV_XZ9Э}(lJ(vkuxVVY-;X(aO7H0JnAJ48JWz݈Vу E/(|1%k[^+S-VS k V ,8M,sMobϵ'ϾV@kH5*ݨ惠%6OZPAy,ީYT K٪aެ^2V5%jo+FhO$Һ{k+[ {Lr5Խo|RČGoשtF8RŇ̟a-t'a:M16Q񅲩J_8F&gdN0jt.*6j򇕕$:W~VŔ%NI2=nĨ u.[Yhu-SW0&5я|,5ڙW(ű;kV7".0RV'R!V74T "?R32bwzਧfZF ,b h&݆3'5+;.~pS'sZZxOA$s3Z -:a^|"K3::SߵjT'oY#V"т"P@832:C45g_d %EE&'W,Kn똨L2Z$8)yD>f}"c𰡩 &,FXݜRoaf*/oU2kt59MB1qpLAp/=UeS):aRpSow ~i@lxikFb_ ʧOxc ]8OIX[p83eNXVq?Ua;{…^1֢׵l5+[d*wnm׍7LlB XZ):&D2u!0&VlJieQxp;LTֲMOʳQ?hO.h5G#ڬ|2H|zi@HX'^*7~s*<9jVzȄ "_|*5} V65E'.=r{Dvn>Xk"d$we &cq&?2cz7;I<~utm=06i!{l174/(yvYgΐhK<TOYѿV!wBÈ *nIz\B&F ѩ!E$9iÃO/#+JkN$ |Cc˱:|ZÔ|6ྞ9 q=/r OL*sȰ[(EфkXpip?.iS 91s}( JX 78j|ɉ11-ߤ!wj?&3N|)hyDNrFjV_oڿgF ,SzVQvԬ츤!Sl-萟 )xpat\AQ8aMϏEX Bɐ Ws O f1$y)(|bjZepKIHXOXQgl׿_Kyc᜘n: e_3b}]|m=0&MBrFfИV>!am\_J\dZ ԎN+ JHHK o]i K =#6q @QtN ޤۈS;>9D4C$1֖kgZ MMȰ >$HXŒ*{5Vv!aHXloV\)?bl)w}7z|UgJ!R_yQTzzYO3^ a5ҕ*6jBJWUzLBʛUjY^)F\+iR5F&7 "x -~˿Vϕ1nhE*4l>:s OȤ5b=KmX]{ ϖ,Aj[3&[oT!^yZ]+HLcڼE6Q^׌Jj-Z|BCFN#뭞+}du:}":5tb:u $4hy:7knA%nXqڭp lQOj5ϖԸk\)?!JKmҕ*4l.T {j-m?ӨT5jվ|`񊒰dyU̪F7*լZ'zEbnkl/^S{P/y[1*MZi"TvkRʖo5+6j^ux-J5 D. _iwG'bJbkfb2b5m"C͖<D%0,BVMGK**B^0W10)uXZ Yu C,m1m,~"b1g%~Vif̟-Y^kh'f+Z{PL@Lfv& kA#2g7MZWިT#%s]c hKկW1(9-&!]R}*&ͳ%ˏΚVu?kf͜e0Ke*Ǎːw-kxBBzf~L9!d''L8s!M;u( _PHʤ:8FMKXB䀡 '0jtȔ?~gJ1*=󀡝N̘ܲkomS6YG kXBF-ċjō8`MK4aE*\k嫍&jxZz$2Tʞ`pʸɚֺGb&sf~XmҌZ sȑ'1r8BLǍhVjBm=@,XX Z4qZW3yۨ#+blqZ*8:s8vdq%4Kk.ȔIJ4m4qIJ4! :=Ǐ$5w ׼K/&||]5MǴ)ӓ&NyDk73Snh9 Ͽ_Б; q̔߮ZGVNX{BQ1M[LKXUj"i1Z*MZi7mhUs.m+ Ku䀡F&k߾[=pZp(6ÒEZrkqP#ECx˘ib5/"-]͢ZH)c_+_O\bhTߔRvHcH|lKئ㸩3$վX'/2)/(D2NXGgu8LL -Vh<}=bb:txy͖[r+ceTzfr5{t*MeR[nYKVds DH*ֆ#MXfO m"ӢGUmma:?A-$JWѢm:kXB̹.Z_@^10T,}c[~\Ži9* )/EM.~(UZn:_]cg͜m xEPxv̼9%jD OjޥТkVݣlyJ5GedwOY&qa z3CXm~#[5[;[z@%+9&!E}f?ݰzHQY4v[vQauw?${΂"\=PLL 0Թ 0R~1 )G Ft\J5:?kl4iN97l4qJPqȡ=LkviSEͻ3yZ9ؑltQbtqPbxRM::blƬ%_,]I6<-]xWM{ K>6}LִBk*VCt1ǐ81y&F&gΜkIX'͘-&# ^߶xrsglN`&K?zh[2ףXc?~(;hN<P,OXQֽ% LJAOjQCߨTSjucRK$+WeaO1:sj${ZTijxZz29td_)[E~XɠIJԐȞڥBx-116CwWw3pSDt CkTcM>x8qtb*v;:kڸ'v7JY^1bnCnj/];[vɦv1nxB}PX'iA~N gڬAŸyT{ M"G%5[ RlԸbTVtCF7`Ԙ]z.}j䴱ٹq&6]k嫶/XEDޯP︩3YL)ܦgN<-urN.Ͻ?[в[)9b Ŝ>a=lqDZzZƿ_G,}LĦ)c-3P,OXא^$ +E z^$ +E z^$ +E z^$ +E z^$ ++Ѓ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/VЋ"aHX@/Vl0*&8Yz]Xur璣[}>o;Mڴp9#N:|P`[O p^3^Γ=yu3mI ɛn:uzfxzmҺM .h/>qsۥ޼;w^v_;{ק|~{Oo؆{]<cL|O6&>Njqƍ{ W_߾ѓ3f46GLJC@z#zt:*1+g5??a\*~vg;|6tʵi9ooH]KQS` 0%Ws%G73#atR+G}<7ai+f4_YK؁b3ѱJ(K_n}V>fO_˯O޼uo.=t8yJnNQXL O)˫1e)|֫U9SK|vO1ة n:nR.]2"$#fy}~)*\95gaظrMH0 +5J6?dڢ/7͛j(Y>o%ExfFCF,Z~)"Ω+׮ٶsDݕ9WGNVZnWQ.rHR|,Vϝwޕ:xG'w|͹ ?eua}{[oAЏ[,a6iӂԄ:*|*a65s''E˔V>ՐWԉ[vȅpa}vXC#YW\'ab&[|r!\[(>~#)“nAvu҅vgӧad/eHX䭋↼^ EA{*Y(|+k khAyV/v}4[;rOQ j3$aթNxsFqIS?jM*?Y'ϞYKЏ[VŬ}kUg=U3iӂVCR>S9>͗>UB;եצ.XZ#2aoY^;8zVشMg.[S=\#O[w([|'a,jkL-Bu$rv-o?jUđET%JCE$n<"}W|+؍kM=)>zTQr)*Vmx}w-ݰ%>UGhpծHRX#a_Kpa+O蝙Zqse5 ka ZDQz&^R'i~UԦzwY#JCORU$$*.P=ݶX|Ggu(n`]jm%S&IF̝쉑9< 3)=} "*.}5hG-[,L9(Y_m:}B.EĂlxo*-*1+G.1 0R~]}Wx@Sot`"HXU1hDe NNh?TY=Af%&Κ4)>Fŧ%yH^ZKo.Q/X9pOdY}OvoȵsHXPm6[ۨ.]r.V/y< [w*KAWˣO@F -$6<]YbGj#`bbQ|+ G1_{Vgۥwޕ]X&g4G\2=|0a:n<x{ǥbP#ipf}Vm1g9 J>")9dd1L˛b?bQ.۸UY% +p`rwTVx'g6h,&`Y<~Rؽ^<WniRVNቍ"{iJwp _Břᐹg}#PoF.垿uYV{<*'"6bH;eW-Q/r#zMJ[u7d#ǟ}LmڽWN uNSIke\C16}_v]:M(3` װ>Uܼ)ʢ#V%,TMXjtO,nv'&rΩeLiKԨEX_PY9ʸܳOE!VeFg$S PkҦϠ*մ[qs>;|LvBZZme_"'m^ݸyS@LUm+ݰe+6m} u=+CHXkX[q!auD zXW`XKM羟8k3~m^hsd{HfW#ݜg}PgGp/J:rL*$}'a]yҧTP3EGg`GTg:-\Pe zͿnmtq-n$BªS~ VՌ䁬Y>?v\˻ٽyGGQrm#/Z~ϛr`ʳ.1>eX̔dRg# k΢rՊMZNx)9y?Ā6~7>p䱎_aGN9'3xSHXأ/2#auиs%3=k1SἘ+A ܲӈXWP|6f5vVr[8+UFى{Y&eIT nױ2 Kr&Ulj2Xmc7߆4/^Q);sW[t1VuH*SVQwUFV^{o_4(-C•F޺CƤ;c;_v2 >ir+b}xww b ?y;9!MF+CQrմެPi&#׳| +nig9he mPR17ge 0qZrte-e[YPNX?;rL[ywj1\12D4/i9\~) 2rYN@8s: 5}ƟrE߭TXl'Nۇ@g @ۥ c.Uo"aZÔnxN2!whݫ͈Q)cV{:8o2UW*YTIX?2քլ{H:Cnju>w'9]#nygX>Jp(f +3HNԱZvÿS ystD`sXa]) =Hn}JIQE q$w 6|6.YC(sp /NX57krQ.VyJϏuyKWI;PYs)m]yr6vJ7l,^TߋxVlkXofJ$ۗV2US=Syʚ.t e\6e-zh27{%6a}bϏ}-g@ tvg6{zw ^@.=:LX3fΓtR?|^J[۰k}NhX۩gɳ|)ܓ=;KXCz):PWUں*~y;T']1vУ59~vhīhHX;xF4xJ6 Qv6IX5 zE)n.\LkxYZm[(m=E&18PKV(m݄=+#o˵pBƧ)[>\)QGo`ж$Oɕ0^#*۴{/*$}װZ%Q3W)cAV!+7 !.NXEUmQwur~־/(==݉n߹SY;pY_*#cB83r~gG)==KtQ]yJOko:~ mn*  +xq*T1uR%T3c[ޭTԩ|0ar`쬥pye=ٽnWUGNz=wyh2wJ%Z3K@D'e8?:{e I+aݱ2O5 뇍[ߺsGNxmۻ_i쎎ZcҰع欟x2׫Y3>u*˕j+ = v_"6RY +5ݕh,Wr_NX(︬Q';kYnE&a>Y̮j5Zi$ks[:x8 ۪-;;0&amK̮8p 8r{j)Jlݠ^[|'a:kX74TrOXw+U(E;k)ۤ**5osٽۜNH5Wp朅J岄5%;WڋSu Pa딀qcVrַ+zQ=Q"9 6l[R3,hޑMJ2^3Vy+rM( VQ*{;wcvr:#bCJ7oRIkN!_PF - ]&*)o?&aVRAG S`,o˗TikurZƫQdoɚH6^[|6a}jeǶ*I:b:VͨEӔw +t21a2ҕr]uMBZ |6XVSZG3o J5h.`e1U~cHX VljʋU i+xEŧ(̵裍r$#mgJHXgVa©J栔3!LGª3AY|GB'VaPwYmV[(?轇+#guoW!Wc3X6o,$yA*'dtRZy#7XQZK9?`/' {)I٬ a:VMױ;bԢiJHd-EZc=*U^I7IX%y]}nv'I?.kt𬟵|`_M߿/H_^{`:C`;/ͼ|9fjYjo-߸U<:a}?M/˘"`[NiU,L9; !_5XO쾄D>UE g 'd<vz&+JHXT6 9I\$eAy yϧro{\ ȱSV |0yMnGiYg1UZy~J`:zzKb>둰`'9(msU]YvX2P$&wy|]uR +mݓG'mcw)|Ag*Yg}L8`}J+RI< 5|BJn0X${=Gsd=Vl!ao9"wJHXAʲ;"}DnX6HXewD8;a/co)/tO=^` ^#^!Hݻ_S,L<듧y[NzʲKk=|P8kJ  *h/gc~OibTEϏ[HXu,%rs+u!LDAYpCx$߹{Wͮƣ֑#ogRZgk< V`Wΐ7XE~mtuû70=*ۤ x1Vl!a1!Yf&"a`.G?95kׅȟ0Fi +Dn*8DD>~z-ʂ;$;.CnţVCm:)|ĺQs۵+Y1r+ lHXM׾09vg7m? )$BZ[7%usPVN!yvPa .KXtoD lu[N`ݛd֊5r VhAJ+3_~`%MQZOy-{=  z%)J+&ɟEizu»= ?o*V9iբg`nt958m ūQgc:tފ[HXK5no۽2|9an:+S͕ !~{m2ur6F+W>cpD kDd9㬷WHTJ+yrF˯O*}ɝ  2(7 Xw^?X$BF %xsP~&لu):;.G?_JFwLwrȅSVfv.ijFF;8amѣG]/[xtºa9#u92R;$gcN?*Pt VIJ+kr'Ej:qVy.YF1^$x Vl!a}bM%xsP!L 3KQ|ĻvH1iӂU'w(kRX%ߴg8aR͔-9+*=݁G'<*gc|vIfQZ/NVf\OQ  Y)gcAqcW-ݰEi + KnV%GtH7&ΈWΣS:eܼ)OTBճ* W '}WLZWĠ8gl>O˘9OizN:~cJ+D S-3X$g SibJ:(Bvl+.`"Vl!af[ILMPȧ2F.,),zJe8/&1eF̝>}bIXv#[?|ZˣC_1RT=*I(\yg~Vc\l9K#*TZ)t⬔1Xuû)r?!{k%JOMHXUu$9D|'am1x+kkѽἘ_=+ۂCju ;%aM'V)=G'u)}|Gr 之V缳~,Zs}%9K#'J,VӉR`gʟ'0 + ig)1#OR6h6d$eUM4lv28BV7e rWr^T=Ӻ: t ̍{%!a=r9#}JQ7\F9-rϰx9?U~Ҫ0rǣVqV,VVpsV?$j˞}B# ` `n7w'B4fAg]*,jkʸ^yMPDxrmePW kp~uOol-.~ͷr6FjJQ] +g29OWQZcNk7(}$6X$gVi7ae~R1JsHXU07a5щ k^MSV: zf(n1+^VaB\]BY\<:a=Y9#~Y]RN=߮Xm4jt+^m 33X:Ǖ{,VӉR`}ؽ~ca͔X[JHXU07aJUkWV1| ޿VYC'L[5W9v'IY6y^xVѯdG{}aJb 멳lG?Vjr VRs;CĹ>RZ u;v)J2z9'#u7J{ ;Dyt*J9F gGɟyu+ֶ=P x Vl!aMX8V$ SYIowrr.e2 o催EC_}1C. ?e*}|Gr ւ5V炳qho+[ d =t⬔1X*n&ZNSge]ԤkePHXU07a7 :,*"tỆdn}ox/ .%6+}|Gm*EmTZk}_o3X(\oB\9#(}lo3X$gzb-之iu7rur%xx[HXs!3')MDjīBl]&{Re2^MV!2oӕ<:ar6Fj JaVr K欏'f:r/_1Rqnq,fHXM'J9#Cց#_{~!׈,Y''"aV܄u,HX i7r^ Nʔ$8|no;Xi2r6FjuJAr r7Sߝ4Xbt2< +  Y)gcܽ;?6ֹ ? &5M aV܄uJˍMb|QOᣆ+b; n}V!`:q?σ<:aKr6FjʵJQ~\rv0z|ڱʕ>}FHeYy*NEj:qV7o*}No>L?o:v;g0a^ l8 + &&"ac)eBZ)K27/RBʬ[%B%r{+k"kxtj=Qg-_6`lݩr=WjjKi30X4WZ=|"a58+lה>pkvv]'Wl6.wvT\ron[HXsքӔ&"am־WQ+HYbQ]21/n Kk;uZaoUںG'^1R3Tw4`>\y֏Ξ!lkw; g`}Q飇|"a58+lԯ\R#gZ~ $O޼gR8[HXs%ӕ&"aF蒚L˸[*?Tao}ͷVu6NX^!gcr-Wj5`6ڣr=W/W#~߲wcm#Vz7,VӉRHxWh,eeE/ϐ3a}rߞ#[-{P:G'7oݖ1R-VW/W`md\|ֿBxts1`=Pi|"a58+l7}gyV+_Qӑ` `nšʉEZXʲJa픅5muļ{&BH֑߼\y<:a}箜ʜP;^`\/۸U0XӜ^Qg>"<:agځ=Gߤ\"^791+N1 + $^ ~~v@rI* R,ݢL˸>koƒr0{+c<ؽ޻w_He̜T#W`Piz?k- ֕k]w^)Jd Ej:qV'N)}ju/fk74K9L`A -$w  _Beo_,EXq|21/ ?:{Ngo5_i$>xPHM1W;^XK}߱bMTZ9qxFW>.t⬔1R~Gݾ+6m Q$B*&/U-"% 5n+P,|AqU4(Ngo}+T:G'g+}|~5*O>Rizrַ=Pv1XϝWZ93ȉJCdEj:qVO8uݎmRG -:v&aݕdD$:MX7Vdey =+y7OXYW!-\j Ç\:.wwP\J++ȉod#mx\ˑ KXv1X$g1嬳Wy# H9L| +p `nšpD$t,3A9b[dOX]ߟ[=)mM <5=uu7/W-W`sY,}NX>#>FFt⬔1R_|}B/Sy){?rC_oҵr&Vl!aMX;t'KYC6~rŢߔļ'B9u9>޹{WHM@;^RWڱp`=PieνJ+d#Ej:|iU]/c{m$]ss(MDje>۶WX4PScbܕɁq}h+ ۷lyU'W`mۻ_izxeL ֺVfY~H-۰Ec`C$YG'⬔1R'|S//gu l>[U07a6ۉLj)+e&] yOIXS#~c[N2=:aq󦜍ʞD;^h W`m/UCw4j%ZLx,eHXM'J9#u|GͶѣR/^ˣ޼%'<>}bx(Vl!aMX̜7 ޤ,x!č$Brl{kcJOytz 9#5m2xfC kǟ(\xvkj(sBH>pHc`C$YG'⬔1RϪݾksV; _Kʁ#HX &fd(MDꈤ%ӕ&"(bmF V}7k1jrx{yoJCz59#dw]\弻WgAkf${mAX}d;daRH]w2c숔e9ͭw/Օ2y| +p `n:0']o"VuJWkX)2+oOʔOf-FU~3tVښ£?\1RyV)}|6`nۥrb?^';9 V>!K5RΞSMv4X$g$6n::vD乫>襫U3T$B*:^o"ΣGLaFڲh־5˾ڪ,k:PYUf``]dg%Bd9{CKlk>d` kՖJ++/8Lv4Xw{V#ݾ{H9Zc7`Nr6FڍJ@6kڭ1/Zk~Ub>}F^[K`nϙQ ۠i}f],S5;RN\ƺؖ+J >('aotG']H[es1=A-*)\ Ȧ+1+Gie.CGɎFʵJGȦt⬔1RnQxz&M_|F9f,;R| +p `n'+Mo"/KXo<Wx-m 4_Ą:M/\Ej[i NXzf JQQ+ k-J+s>SO`s_ie=T¤JGȦt⬔1R*tÖa'O]e.CĄU5rJOytu>lP M} VL8QM ˕k+!,VӉR`=WCi8_pXEmtRcD2"ފ[K`n3#Eo"_HX5; IW\:)zk4wprNwS&<4aȺRs1Rp9fqkfD- 0\5XRZ|VHM]T `Nr6*uVkԏrE4N=vmx@$5 kJNªi3b&J[j2~Q9^-=-&%lC+SO<:a=9#-.`.׺Yy`E SZW!b>hRi `Nr6V+nܜuʼx%VlV!c|%:rDJZ*Ԍ\zlfi7r2("t5ъDxE6xn*DJv?G'~oOеj2\r笏I'[S-]ە>  Ψޮ(~wu Q}HXkX+#&(M f:"oWu%޿V9dS,9rpVaŦmrBVJOxtwl>Zr eVVgWewլ='kuoyS0RwUZ9N6X$g*Q/XiĬ{XmdC -$+#"Sl*Lܸ@YjS4_VP\e{A͔|[e-v(ՠ\sGPtęr6FjJЦ\5cJY?:{n컨4~b|{rH0NXY)gcJ}h۞@Etː` w VءdHh3bD {V*%\ΚƘrU'vt=5V_X9'{kǾJO;xt7EU0X9+\ϭjƫF9oOg"a58+l VfmV@R~qD !aa}j]%FrP~&d_lTq~=/ y^s'>S9vRykqnӲFeNSzeJCz7r6Fj˞}JQ'\5uRY?}V޲UJ+ۺH4RgAc9rH0NXY)gc*WZ`ewꓘ` ;(IR0'BHe5!Y[j|@΄%G6++`Ê;bvJ+ k-rE̮zQ`J[C<:a=|gJQc kJ+szre6~qXHN1`Nr6zNJ+M,\QU:4` w yk%RrPΑ&"aO~տ2{r]v4ne_mUVcՉ3?]#64Aת*oeޑ F3ݯ4ģC_1R;TzU0Xs*\ 1 քsVOܣ|Mt⬔1XuwUZc7ծфGHXkX;( *m a"V|6ʚ;A(> 5˶Q(*: IX,'go4U驟G'~%gcv8"{U0XgWZC#+WUҭHl1RI\s9"a58+l VNN [e5^Q)HXQJ2!!LDª12ޓx }ظk}M+ Gl'M`&yr5"}Ҫ*-*N`g 8+l VJ+Ħ_Vō^[KpCAmLD$/ci2P7%#Ֆ=:ytj)[0\;[izyևDa s+ pHM_Bc.9"a58+l VV[yJSgWōފ[1Jk6P0 9Y;: !%†]{)JO=<:aݹJ?ʜr==돝:-G2XFVZYOo]TF-V,V%O.gcMlj?X8 +;YIRZ&"ah1xGB?KX7ks?,;wjEiT(}|3*iJ+s۳Qr$uWJ+k2m>#,V ;Q`=^ij5:E+k~b]=ps$]4WIfHX-ޭDY|*ʇU-i^Sytº裍r6ڍV>br VJ+s_~1CV]QdwSNdHXM;aJ4Ui1䯬q @ -\Ú*%isԝ˔"a~mPxe*l5|B6NXs1X[WZU[%0XVZ;g =*4Q)r#cJg,VE 1XfUZnȿU+k`:Vl!a]q|9bKڰkWl VAJ+qwr {͔Vg}z<9ZnҪyr:w' {6S`-h pOWkŦmJ+ +55:wV26uI a.Vk%+ !k^ ӵTz>G'v?665]i#~tY.z +g֓*-í[ٶKn0R}Z7q9"a5]9nn_#'N)$װdlj1x2HXZ*ߪ2`ͻ-}QyzhҶHN݇?[44prqr(G/pxXH5h $%"!"-{{{#swo;3̩h=)`ο|ŗj<"{ҧ̗ {FRk?^rccH6%=&;]Z7jN} 5* ~s/J @ ްf.S[@ Q/.VsjѠ5~ ^f3o~UJd93ͩ}Qlݜ?ԨEzߍW/üS/YTg3_chXC̩?|a/& d8g QQAYj=&"\'5eO֡K穗 rj-c&Ӱ6>^K5K2" +oiN31YiןOӾCի'͎*V;ڝQ]L6cF;/\ 3}5* +Nj5kNk5>LJhX}j9Iu-[ќz9j1dDZ]O1ӖVx9VըEc.6_;9I)`DTҽa>#Ϝ yH<\9Şz9-Ԩ2cnQ Ѱ6rU=ڪW  kПv@հ9~3i=!ӽa{UfEn{W^r=5nNjT5ʜ/5Rѓ51lT Ѱ%x5] h@>}Z(W!#մQA ͹zSo5Z k3 >UfĜs9jT%W3Shj/14pOy}evCƚs1G^?5*d鎆'5w~Oa>SL۞{?ҰjZ =z ^MkXłuyǏ<)ҽam}9A2؁_?kζhN 2[*߽Ϝsfk"sMx̘ըHw48 eyZ \*@ooKZUǷK8ӽafyY 2Θ1wU.iׯ߳ߜ$ʕRƜaM7=iNٯFs <5I4?Qe]1~ɍ!~ߙ+czF@aI lX{UZp{m))hXc̝B@z @ Xa9'~SgG {i?Z*S!yT^WϘvnLVʘS14Iuds9ǟQUt}_9m}̉$V4yؚ;?yg!>92<; [QhXpR!K^-V/$4U\UU&73go>/;t7Ɩ kaϓRc<qUs=г/U4_/G14o1G_C*#.]eΰǜׅ;TcC+c}=аF5MUZ(=OPаXBpFܰ%|~,1 hX׎1:{e9 ͹+׫U4 kNGH9H1s:<5y|p>eέ(Q]Ma yԨ489 wZ>Ubp\ZC*[P_i7=iΒ$#հ)"Ք$ñwN=mQcF׿I #-PO1s:<&;Zf4A񏚽МU2-uVGY/*ܢF@aIiX'n\ya6P ',B]KXZaΒ{IFa R0GmF1:oΧOz^_`NM|gjœf1 똹)/~ |:÷l6g{:V#DUl y_ը 485j[GnFbRuˏUH1VCA>9k?Zqs|ew>yɿV#v_r՜ x kRpSs籧~F$o=5︤>eٲT @ nXݰEUkE&7+G-l7V@Su9oMV[=׮]koaZ[1s|%oF5j{M kau1'chXmJSڀ)j_OسO 9þ}gVcM/T?DSV,Ѱ{/Da|9qrW͹_gmUv`s|eŖjŜ aMwF~ڦ1g{>M۫qQnךfۇ" Vddk_YTE0M3,ʜUj_Yc&m*.1g{?'ְ6806՟%ÖW}qk)P3%O>OuK4ʪ{9LU"ذOʜ>|gIf*v>eNbEG5ڴvW9~Ej{}^r^I2'chXSc|svǞjiѓ|ٜ_q{{D>C/fy#ӖV# а$M~󔉳v/~*R}v:YuJe*mO;s"hX-/' /w?{3s*; [1G\(kjё1{̈'mGb5(ȼUYs*ֺMh#1>hNϙFoمEd2WΞ;f8$48Iͳ4oS;TOJnQJְݴmaÆ,Z)`jOéd?$' ]ʜ`iЭsd䝿wGj^b֔ySO˜ӱsd53Oϙ7y^65|nR#UIJBA ֣-C}rȮS'Zz>ScK_ﱜ=wy{ܣaI߹TSUa:I-1#% ;_Gm8'oZom2wq+֪GC Kwy԰GX=5Şz9psϙ3 QcN_yMT3W%%'4 ^4g8ix*B|*Cz8re8eԜ`ź]G {}Dcdpp9:YjQ|Ns7߹~s5d ϾâvlV7{ܜV@ A V&meiXC1f`7Zu=ɜ% h|c>jwB] Xf،<^b?9s7z VF=߽jN\|ŗ SOX6i.U"nҢ~|֜`t9'4n_-B~J+199~*~ҲS>tGWIqy>7sȤE+KD{}DchX{)~}e6m^";{3sgjwҌ]Pn2ِ rɡg_T SѰՍ6i[ua ij.ѵq3l'!iѰ=~u9aG6^(LSWczzbsz kuỷ#GipAvzڜ0~>aظܜPs݇9zW SѰJ?T gа4}ZHZ66ǜ$$]VyDs˿/~~ϾJk20аVoNwH93W;z1>k|HyŗԫR>C-/<|F=۪׭.;|RR 2Ո'44A-EĦ~Eh鋮ť}svҨafj{HI˅}nz_ 5/ r^bjtSFr%蓳Z ^.\g?zhOԎ?uGRNx%'>xVc` {hXpBd5fÇ xBҍ3jҫaӗ1'= yo_mw#ԋ㖝F^pŗͱ'!uAhGX=zÜ$_O߳w6h^ןZw8evI~ަԋV 9'?NQNZ7n&#\4nnȘɋWzk9agSZ݃PаN)ղVW-L+z5g>Ԥ]*f\oN}Wfkgu p6ΞvWwNJZ.~i>"14ծE'-._~7o) Er :}ޖ'sc|oMz5Aˤ~&1t-z iЛ}wyZг/$3xjVа&֑c{1hXQjI>еx9%VudsR?:cڱs<ӈ =M6}E+lU7߾_H~NZ&邽>"14QtW˜= vW'_:(wΣ';>oEEw>;Ocb;WW>8WxsYmwMӗ^l̒G3q6o{x_?9ٕWͱ0jPCаUYlq^}RVn.]'7?OΚ i* kC3{U-4^bֈv}Qz0(w·bN(Ψ@A x9 J-HadoyZDUi")۰}sRcZ酽>"14~~sNjL_wUCGz5 +NhXŊû|gx4. _>_-: 8n3D{jX؜͉2jt^b3qZ7`>揨yc&9 E@ D ްyWItҰVi;  Ma.ɌU2*㒎Ղ0аFS.}2j|-oϜ߼JnfaImX ~ЪZ G`͛"vz\1 x2#\CY7nyeP{p~#~}w,ռ_Y-j2V̆uܺ%?E-@j'pŷ5?ysqH&5+~OK<܋-C]bsz k 2o0g/seE;\c09{5#G^փF@ G հncJ&H;t- :\( !=k V a.VaMGiѳn|kӰմe{Hϼ{3 }i{5w  +N2a}[g}VLROݺw쪖P-ZB#rҰ"س~p5[5GX=5}=_|a|43 KMm mMOt\4K/3&Pа$ֽgonIS\B 릗߿yŝLݭdy]K(ۨh"14ަ] Gs)TGsrQF=ɃH?5}}TM< +Nz̘ gY=gM;}F62~|[jjS=>cJIZdM  i%,C35&E{焹,_=3xoׯϽfsz kyGs<%sq$9_]^lunR*~Ϟ\՚OУ3Vm9`zݚ>"u) Njrsgܶ?u5R./+?yuP/ ~١{I3d=K;|.]??ԯ.[M @XhX螬]Lp{Jy;'?=/dsU_c=p˨ )k7&191Ml11ũo>¦J/_Ӵx#Ըn:{u1ayWG_ݮ\|'|Oy {YU}ܔuU/ BA )n ZYu}ѾMzi;xL#>vǞ?i6֭ѷvOVZw~SF=8 { HxínIo=[ӸyϒU֠[&}Zw.?.~Yq7?X:H6VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahXPX5$X{ߎǟT=I  7nv7C#Ԑ('@M]J pMڵ8RQd1sz# ` { T+mՐaRf6iتN^  #Qk⏨/&j0a5 +QA RlX&h6mbNuK7o^s50BDZsаaR5@Mjd!a9hX@B @TаDC }JPGxwgQа4FajmԺðq&L5d +J4142};CRk?+K lXSCѰM]:|5@(hXTaa~ں:)hX6oCѰ}Ұ5@ƻN֖5WU@J 2 +U9V аа QGQְ&@J 2 +UQ +hXchX7j8q2ur0T5aqNjfiXiX@Fa WhX @C#9Kߪ{zrCj05wfd$V~8u414j;7өuP?GԴ0 + +H4TaY +hXchXSցSfaa*LZ\#a2@lX hX@c5ai k44 #ѰP9V ̆5 5m%OaQMkXeҰҰD @6=аf6ƶbN5 !i k44 #Ѱ[4V' +jfzwV5+׫aQjXo{SAJ 2 +NkY 4@ n?Xil/Uհu5d$V4JxfN&kT!C8a?hA 2?n).&mlNc`޷mFDX6;T֗ GL˿6s|1dyۮj07R߰PO[wEur1nJ#Q5!UU?AY]?B6$c}\˼׺2|Q:Θ#Ywkoi;QY==2||lȦUcϛdGui3ht2Iro=jEwr$/w3w:VČk;NV׫*X8Km:>oɖ_iwVwcF#f-P)K2xe"cnc`N~ק6֒C[w,.58mkag-w*4t-,~Y*{u>#p~ZVm3(wOZU* Ѱ_9~lrP!ka;ƿ"NJse-*j+{jF$r=dI:oWBHS| 7gw6hydlZv{aSq,%v9DO r凲M]ajS6zwVs7nSl{ o~g$t/=vh5>~ KO2F^(G<[@9#rM/4pl55X(d,ے~!n-E Uާivh-SְuBz-e2X:*^NaO2H|" J jU K[>47\v@5dxvǞS[6,YýMۏ[rewV5d2=jo5{2UzϽn5(ͣH޸cZ VU,VnLvhW2/ U*^eڸ^7 _XtoGLP N-[z9gmpGCzzZ4E ݐ1O BoXokT$,Җ8SϲsZ -/&BE[DEfޠFɦ IlX(ໍZ;\oΪ_R '˒Ѱ>ЩwlTrH ~Rcժ{Rsy';ˎ&[Z]-a w{A/ N<2+k>jB5IzCPalcbn.uòa42W>ufy}|ӾC=%º0 :䓛OGBdCQcOK'o1$aөn5fBaQ X6TٰGb+IrۥOBqĄ M6PAQM%ܛnsX% dA5O(Ѱ`rzGA߸-?Ľ:xzf1X$}:R3^}Qk5moRe:7VfpVwhHva85fOdM5,ذ^gɦmY=J->V( >%!nרa6s?n_go?v~˃M"O$Ӹ5~I$jyv{M% isnpePU[15 ,ð 9Gb&})we'a;[և {4cB { B6o^12=YhX8.3՘}f?XH#42 "Ć ^g.ݼ=}=ںtkݦ[nns|ҍLYR -g\siYjTXY6#o{ٲ:.~UJjd[~5,i*xgtg׎q[X<عjA >."247\ Qhf:ķ5n@;rϖ mnEao{HN,X_M'y );M۫WI]bw =}JCfmGVGP ~bf<Җ?|~B\hm.箇['Gcrdd<VLl]YDX kUr,Y9`ʬ^yKO,ѷZ|vaaaQzu;{u3w֒CjxC&B1f5Xd6N@h~J'=i1est'8Ak9`D9 9;/hAnٰ_1k3*%amڷ+~dðq{I ?d\metVV2t<٤eG)9ݐ1'Nz~!یl굼JlXmQV団QySÏZtt|;[rd([: ;I,s^ˆU6[+.,G!y[^ZK6xs`Y+|y*s^eCf԰ʮTo*KCʆ={#ͷd^(d 5;&)]>%:H]lخb/1=ݔτj$O cxNj52-Vm#pڲd e yW#T|,4F{r;Ɂ]>i{|ĕ7_cl- ?rOna]ѭRMMv oQt@аpOZu6yo;s5jD?nIJ y6FP3Bmo)1Uoˀn_4k2S aw Z!SAigg-/ncsHb(;i/o( >W;`,ɘ {._42[۲}#ph`G9,%ٝ:'IXۨlW5 9¡9WOd#NC.Y6ʒMdY~a#=,?!l|DHY$eF,znհYav_ ryHR:|FgL󘹋n)У} P}Z!~vU>8HkT5,n EGY~%F~Q _ٔqc )vK Ur$ZwVnݼ>6G{_#&|/4;]˧;TǓG w]v1#Pˏ@ @a_"I7af.>p+kNd٠gP0[lr +2 tfw~$fW5;TAݤR=)KV'O]ZAFnw ˆEKKL6&ٗ9>T%_"&`:2 =W lvkMDa<ϸݞkg{6= k\ShoÜUK^) =ZL2;vKg_7^F}lM:Q6  kju8>:>w`wތkUٰʇ3w6hiy{C]6v%kXѰʱ]0f"E/G\˱>:czr 6Hz{OH]db,v~K32`Ow 51]?* Y6jwN^jlBC# ͮwx-9޺|Gw^Y_&r a[q;2ď@ri.jH2 +N"Ұn_~8id{}O+ 󗪑vCƨRw7[ =I 얺M욌1sߢčM\LlXVHnf-YJFÚkak!71nc݉(4iJMxn:mL]ikfœdQsa'E-۬0O4dz/5nkן9аFmTasA7rYG%.97.+[6M\P_nEY.|K7= Y^@6q #Լx!GCXg6|l=gfsʆUf{9,bQ8,mՐ97vա6`!檁݋^YhL  z-^rP#ST1hXpuR{T1x:sCˊvQ8MoyvbOd &F{$>ke+K?eڍ,H46z2y>VLݕU^dDza7vo{z*ә @`w2 eBH|:#e+cm`-Sbw{[Pn۴Qnc%orhװ{0eLYN޶'< 1?oղ}OSaE|lP;s! am>vSu} njv >T'd ]=/GLUήvAՐ^a5 SE 놽E@woe-*|l{>ep&P |yD'ްn_c,/]ZrY c-UOI<eDNG^~΃{^ERA^2swV +׃:7KW%^7uQ2[Q QhX-Ou6N .n\jv˞xT^2VH A6*n\id3,+FeWCIj< u)y˽aYSe{SFvלm+yS] A^nzkݦ2*\m^͎aYmuc k@S5`̫75.﷜ȮaO!G!56CCԐ)c|(c,8f'߷V_vs  +Na1n̽ĜUj07,6p7J<ҖpY^y{߮k"?e}ecb,An)zU#4ˡa]c^U ]gdB:fb5U`j܆QjT5|D 6W͎!sG̜&aQ Uz5">1,Rdװy7تqZ^0"7nS#Iiud5"7*DN( ~@dѰ p1X[KyZ &FޱW f)"E;w=*''(-Sz/}S57ԥՐn84&R bljy_(Avfy ph{zz^YmԯnT>|q[5 V5t1Aмp5 ˧~Z|]mVj$Sf!{"2,Ć5/aX~seQ5{6c;TC ,f[yғh6vG ]H;FkX ,C5dXyXhIS5"1tF(>@ @aIZ7퇎Uczneɨʲtm!=w=JMsNҷK3qOsbhDz^i̙ݭ7"f[֮aw'6v WDay[?iQNY͈Zr(%`7/SݘYajdA?[ڎ7Q;*Cǩ ov='8 >n>bڢݭ[ Y%g=j0BlXMxCtfd?lX$CMkX-N2V1u;n=E VOm_{_Rofԫ y 5[6I:(}48Iծz cN8>fIEnYLlݥKpVˆ>-Ԑ۬Cm`UYND{\ uԘ 9 ԐUlXvh6Y_7FV5^M з[6Qcwj5W44Vac E MYl*.MHw=Jz@HШ^ @ ,SI2z"5dԉ b%`奱?l,&w*5PmndM@ƽ fFjWp(7Bfhjaظ5W#^vBޱWMZ{MWvdHP,,5lX%Ԑ}w5fkdiXK Fd1:: pt& ?WIZ4 iBKkXYwjH5;^2 } '/'G а8eThv{9>W l97lUٝ&ӭU]i%–MPU)3z6Z * xsoO@l-94qᲇۭR̮K{Րn5 YjHngqktᣐf+{uWm\38+u~۵v쮡qh6sf_7|a87{+'%9_ F !#5W)kXo\'/Zare@*omF&5NװʇC5Nq̷j\hul}Gě$ՈY hXpBjyn})+,^ 'NS3+,SߛpŦY[5{LS V%aYjH]Fnn5hX. ^E*nհI_Pp&ƖJv5;LBj?t$CX{]FMT`i.jH,*O׋f* w6h"aoLr-Ʋz VCz(VK#j5rOaO=h,5'5?vwȑM&fjU #Zm^j.aæ2 +NhX-q򂶂`[C[OIF!6smV#+QU)3V WCz k̭uʁHrW.+2 hjbDuyeV"%}&NWCV) 5[MqjHg4^ھGG`i#_Ȑ |;[sܫ~Ő^ FkTU#~ˠs)y gܨz_cɧ,*ɟ]M 3wqWf/V9[mV;48aAKjg}75btIx0Ъ.6M4Q,+ڡ(ܳڍqoӪ%`YRsV /wW#1t1A U717j5pdF9g4C bv~5a2~ԢCjHZLC4z6-7W>!Ѱz5oF5!j4"TCzz*o(jl1 8]C5Mᬂu xiѰm='Fp'mle-1yk7_rd'4bj "sѴvWfGTy>nW,YW3G#$3fjlB"jlhXߤߥ2a5Pa~|L͑aVayU}"dWVMt2nrJ|ߛQ95f# k= a2mfԐhXOj<;TC Yj^ 9 Ԑ^۰G&˫W7>V;(j tiXefիCY,LRpjwηmqy%ky봼Qn~]_Y аULZ\AL[4(WYaƿ&>5p*L[~z W ųYGՐ>]n5d2aQY>p4xea 6O;ZrH ݪ)217<,7lUS%6>VK|nޮg<*vxt/ lº̂ujvBUj<OXxyN5W6,Rx!-5OMGaby!݈lÚ@Al_mMRc>uaq;蘶l䉀j =?ZTĐ nR Ujko&BZ(4ໍZ_749H ,ѰUuCge:}Ou -q%^d,Ԑ^5"eLjWS I6m9`qw;5 bs3$?ֻν8 'NSCنծ&l&A4^ɛȦ5*`^+ƳMx ذZ#x iѰS/!Z s# : c.VC:DADaft9YnKaeG VrXe ϋ2ݓ:Y*ܳFww}wgy<5^XޮVl-"2XnV8x}j!-V5~ƥ7mnУ}Ր,o"U>&>(}=j0g]LVc0۴$a =0l2cX nc` ߵcy]};4Cp 6|I."۬Fh3a~s˥vW-,,/Ѱ.٤, P 2w=rj A{Np |dԐ.Eavtn9\~MݍWmߓʂ0 Z]o5!Dx oXns) |e^`Pø&yk7|/}i85 +NfZwJQnXohjJ+cV0]C3Ԑnt uOBae8J J?oUMa[?i*On{e"\hCEa~vL-غ&wwAPtv56 4X>[A#9+"Ćs+>lX-0ܿn\ߠsi۟%yjHdS2810.|OjGA6W~h~аdҢOMh,QnXlnš?v^~K6CxdekwdSqɍ^N'>0{7igykʍͣj*}72a{ ֒Cl] Lv|S"VIjTÑ-?ա%92flw9j 2Z}uls|fYi0XzQnXN;!Ȯuz%Vz Vc31G$ki%'\dw`!n5f}Y~1kXs[}\oW E+`>zBvɮaݲg!!x Ej$O}& 5`U~s/QZ{-T [@ а.n, HҰrn㼽^şwTTsgF^~ٍ &>JKw<"d^<ݱ]:|FؽLjXewUc3ZvyvֺM-ONjH:(w'u*ƛdY^廧K$dzR6Cybɦmky(2I.uwjg2eE;boƊ=L oZ MַF7l?/wSûU,P[~v#n_ o, ٞ=]_Cf17lMF<%lNvc5͖&Aj 6w+1C'Ri ]kXl?"G˻ W_1r8U9n7${JN~+f\vhyU8NVe!{8A>6xj̅-#򢝾@Ѱݐ1?M[:=eM%r# Ym@CѾLJN\M:Dzkcz*BwߪҘHpo%'sKe8)yg#g/կ7 ԰ kb6>V"òVƽ[[TkQhXkwG cIyk7! 3%9~kݦFfھGAqըbd 1nJmS.}[;z$DGz؝^{_끣UU0U IVaw7r7oƴk./c:vcԯа y:frʺ&YY]۱%{'\z }IZa}]=@98ijH,#$[dv6βɞ0@ {uPo&j~QkLWB^ؿzO~*~پ!_ׄgu^doeqĄe_VSuWgS9M%>N:{-o,}I;SB[.]~_&CR-61֚pn ְ9 ?|FC:LF=L-+Ѭ0CQe//hЭN-8i9m+y""w,GcVn=t<tgz'퇎1se`KN[Ȟ8v^~VAjͬݐ1rXVxÂI]gM7B[ L6-YMEz] 2ۡ[kyB27rUN>ɱBic|$9{'$= 󗪉>@n-v]{ObN5{-w% G^`xsWQlXSfcOo{+r;f~ѥ*? $0m,Ƿβɇ~gDawb U.4d,y4!?:{C LY v r,Xr4F> ɇXҪsG S>l?F|{zE2 +Ufэx ׵ϾUBp3wލd9t0J>u˯!#tE{װ۴LܶZ[uȴj{|Ȓ|Ѿ9>wƊ_h7dzjtOV[{!*斺Mf\ii򶵼hq0v^Fl2ɟ WҢae?gap~_@r$nY~ꋷj-?Xn]V; 9ʝ->u:2XwE[Uoيbd~7 e!K#e r.Y6Ӗ{Ԉ9.ްUv UQïp9qɖfЄ,4Vsfw e/X& (4%w H3[4J>y&п? @DаP&}]zR2]V]oGͷhR4{[cKC.]YmnՒMBYeװ[+4!ZNd7k>y 5U]P3{#ZzWڍ,ScmyUlp;;ĤEjh=pT]K>ud5~hX$,/Yퟋma]U5cl_ݰ rѥ#&R?k*k8]t_j?-pe:b|y d'Uaw{+1*۴M&<7sK&LjS 9ߞҖRqF VX}O!cB9$ZW[>۸56?EJmjw '3 R]ed*~پ{Ѿ՘]utCbJc[Y*Hް@#h#B6*,93Whrȓrml_Q*vS壾$6on k(tpʯV!Qyk7gبo ao!jEVoY6.,.nWW{O,V:tim[ yc{QԆU۬C5rgkwU_8Hd]KvX77]Vlˣ_=Q"`j5aL;p尡4B2yU`YH,-k%քĦY Rb*aԶ}o7ȧpl:y,L5ꜽ`;_IA1gUzu;2UW0l #Ѱuz;{ +rt}.]ydvkqjuQS/%_wofHe{8}VU'M|,oɋV 6Ѿ[N'vU0eC7nTcO57iKҼss Fټm؜%%HM&@vgKjddXXXdtJD#ʞZean&}9X%sneE;dfGZroaqN]FM=E {,ްUv;Sv ]e YU{ơlc23V=gKj#,2m8evޚ1ȂZTeG%~&g+T 6tMMҙkyWiqLrE St֝ըDuuL!cr_?nȮzyk6f/X?gf#C9JY6E 2aRXeg_!b4s'&LR+j wz 6vpvm; ul!Oy;ETeU) 㗃Wva9[ąˌkSCMҥ&r?U}JC̪AXd!Fl6.dӶ+˶$[T242[>'G]&r}lNT} RhX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-V u`FIDATpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-VpܢahX-Vpܢaɷ6ay+nWH5hzO%Vaa:Ӵ(@XhXHU@XhX躱N#U +аѕxsfÆ,ݷu3߯d^;tlN,HV nkTի٫ՇULfF{ZT?p^+pw/} B!B!BIiX%+b4@}nzٰ!Ƨ%[!B!B!اF5D D 7Q hрB!B!BcjZtu@аQtW }[߽d~4 B!B!☚ְv1Jg<4@ݼU|úQgB!B!BԴlu@аQV㣀B!B!BHUi P$ +E4B!B!$4"VB!B!B VC D +!B!B! +aB!B!B@аQDJ!B!B!AB yhX(a%B!B! a<4@ѰB!B!BHаHV hX !B!B!$HhX$ +E4B!B!$4"VB!B!B VC D +!B!B! +aB!B!B@аQDJ!B!B!AB yhX(a%B!B! IA:juOz/o엗}v_?{~=g*5p "VB!B!B 6v捣|1yOئ~1yfC D +!B!B!I֒W<=דGg<4@Ѱ[gə5fII ̻e@Κ#?1weGϚ?HלEW샧~k┓ELѻB!BiIRzϚ/:>sZ$IyfC D аF(Nț5fڒ'?IMhX+zְ WkcOzz%crM?x^a%B!d46ǞsGߕsϪQ%: yhX(JYz^=;\[[SۊъJ,ūra y|dN:}1Ȕ+\eWhX !B!'usq9}֏Z?;~}z46LT4.ۿ&9oFaP̫ה5ՙj5²YXtO +!B!ް捣+?aboTɠ3HV ߰^~kwyi3+{YN}pˋ_|yS>W"/] *VR/ٰzɊϙ?HTOf.YY> ^O8 kkVWr JWϾ}t59y&B!$+6c \ syjeyIyfC DQ?)?GꙗDJ14f19jϹ#lE8 kkVW9ܚD5 ܻy&B!$/6PX'_(G>QKg<4@%a5ﺙ[5'VBêBZUhX384BJ!B۰{sYoοhNyfZ: yhX(Jvj. |` CBJhXUhX kUhX !B!p3U:2U wʳ]j]꽙ʞ6ge=wU_U.ynycf,zq'}ysfF^xƿpï>J _]1p髋_xꗧ^.Ylav+> K~ket5'2;o͊g6z>s *Ɯ3/g6 ׅ}ֺv҆ۼ{m4d[NWlrw8r|c{W,:+-JRN(twʖ_xqN]6ß?+ߖx칕f0ysfTi+W^҃́-XonSbnWVcb-2G޳!B!D%܆_.^P`K_+ϞPHg<4@%9c?tٝr+J~Uw|_ddǻKn- ]t<׾q{*ξ&Op1RߎX cKRL+,MZo+9-/_hb J܊(^?pk^-{&lo'w֦Clu^[Yא<8GJ[oGV_g-[UpǬ}KeӋOj  ǝEzвٴX e3u.luV/>w.o9Aֳ^wYYyc6sDˍm#ۻYrS_˒Y0WDcx|EĿJ5GO}^6+>yԜTĦp6mk&n/}Kʥ +O [ٶdlQT[9֍oy70}VweקKˮa]%O:4k}9g㑲mVϟ>bhl֢by r8i^{9SC13w1}cUF\u7E;׌oQʅG̣2c9Uj²7c9 9;ߎsgMcf?GVʌWe5e.%e ?o}WTz+WlBVh7FT[+oEUtQ椮޼"w^'{/ //\|in7)Ȝ5;X}}5/ĪbCK-_;w{ sv5wxTB!BH a_<ߙV%%!R$ +E)hXꙗIda~k+ʇV+?U⹗Oۥc_n̟<#<&waћ\=Q\~9Nvi\u+UO 0|Q%^u ?ş5. WqT,ɜz kk񏿯8d˿=_^Ӽtn[ԊNfE~ḣ= L.U>mmxX6X5W~scsi$n'^U8lN2!JX,$I5bنbQT2bl֦eeT+ԛopdGK([9񖭛/yc/Q\ayߖ׬UYIK)ے91P k(:q\u^z,w m _͟T%@tpgִ+vxKe,3o_t_A8:wsb݈!S1UO_nmZ1X-6>`sWy_^$k9ۥEseڒ;ۧ>ߖ׬UY8U7۪C%sb{s][Mߝ߼+^NQ6Uo3:N.slGKEdj,Cs<^a-}iR-ׅMaU_xBʊIrB!BqJ 8//^:]/?|q?6ۘF.u@аQT k쮟l5#[>'"_gx99peasb8vy~1>2`CV<.r**ʱe?jYm~UKϩ,Q'-imZc0ZibNt sfNC8Q\>%[ìoQ V+\e,Nk԰%w7cvO{st2x46O4ϣnZdx2C'*6=6ߌ$ֻ^E5ˌ76nv4B!Bqd4gN/+kܡF"u@аQT yr9gEGΘ?pyĨy rZ׊2,ᦸvIJÚek+r^|.P>_9^6=6^ߌvXk8 -$.*w4B!Bq$5B=`9+JEg<4@%a=C˕Ng?řk_8 ? _~kQAyiXĨ+->fuyV|B0beX-'=?)o_tn*z!+@S|*~9{nXj.§?6ιבӊ0^ڴoǘG&,+M}s}xUQ* M}q|>f-VȾX^;wd+ k6F|vXoKPH.$۹ͻ6Ż&=zտ^|X ޴*~Bk[SRֲI}/4V_-Ê(T>5Dbk5,)}X/Tٌڰz}3_Ͽh٠zBy46;!B!LVҳWT|l0"{yIF5Pd7i\9IŅN?{Mq^雏+ ЕK>x;Dw?)?춍jjcMC~xbe.~!naZ,C *e%k<󟊅川V6֦]Κe@& /|596l^cQ~_Y0&`N}Rw.yyc©ΚXqקK+[T=_&^)>yl{^zjݰ.H"ESmnNNka u]K'}޽-%Բ}حrXp8s?\qfM$gcېZٛK٦^>Nb{Mٯ,,zr: V_hRֵ׆Ϳ@Z鋲0^xx vy9-Db^.{_W?7lvz*0K!BiIj*F}~tK~~?2n<ld[7v$hďsᘳl+/?8\3C^vDeU~VɅEe巕%k^NiEKϩ,Qi;6k>O,e>dU`]'wɎw?2ɒʿR1IʦX 91.!g,Nͯ4)oW\lˍ$D_gt0nl}P׵{޹ϻ^eZʜϿiXWܜ3ug_<~1(4fښ'L[qxeyֵU_w7TLр=4xBiSisbaB!R5f޵'|xy <ܽՐ?y NUg-zȻ r{X&t\#8}WV/1$+ ׆,W/\Ɋe;o;;y6;r/o^0׼@j̴W.}[_9H3,X_bH!󮏹| Ōg*׎lX*+p;:s9%3p\.֦sd)-vhS`\9;/j+m`U\װB!BՍ[.W3s3wPC3HV ްB-W\8kVcB\Q0f)铯oeBjB!B^"հ%%/~/Vj yfC D +!D|f2{׆x&(EKOHT~l S~ŭ !B!$bZ*[W?z[ : yhX(a%Tʥos ڰ~xd:EK*OH4֫ǶOW.?|.&B!{"ذ{W`>9cr5@<3ar=νVudžeE{dH4g/qjHxʲ !B!ih6b>sZ[ u@аQDJH [(>{\\υ<&[ʙƠVB9ܰ^zkO̟B!Bz"۰&: yhX(a%쐬?Qh +IT_zn8kLB!>a<4@ѰRs=wx%gT9/(p/a +IT_zjQW͟B!BIаHV hX !B!B!$HhX$ +E4B!B!$4"VB!B!B VC D +!B!B! +aB!B!B@аQDJ!B!B!AB yhX(a%B!B! a<4@ѰB!B!BHаHV hX !B!B!$HhX$ +E4B!B!$4"VB!B!B VC DjX>sP> | GB!B!B!i k<3a&-֥Gÿ{h@!B!B!15a8c: yhX(a5@> m0?B!B!BqLMkX3HV Uq|l-OB!B!BSl3HV i:d^o| +pw/LVB!B!BqHjX 0H*V nk4a/Yn&2#QG DwT%kaCr ۺ@Qed8QMG@a:ײҽݼ: аvY +аQwcF xB ,4@zA{Zp1+D ,4@:Vw4lvWQ`GիB~θ?4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ[4 +E nѰ:?MTHPt_4HEAh&' u$Bu$J_i%^,@٬D]AlX*UH<3s;wfI?W)a<gf\9K K K K K K K K K K K K K K K K K K K K K K K K K K K K K K K K K K #ϕ8_IHy9< nk 6S^>0,ïnL'|wns_^^^|ʏ:9{twONjD6VW :6x9]^<퇧g^m;8Plxuto7ytzN>w毞jeݧ擇_T~8xyiyHuɛKU~HXG].^*^'a}zgߺ̆o9 P+ 84.7oL,g?à !I_F'OZIXGݽpGz,^&!y|ܯϗ<,󡟶V^Y / L陰nWl<}zm}k,MZJUV2?8}f!9,|}Xy9ol"VV{ud.+8;lLqޚp 외z]mNũn2ήOw}s9|d#[J0 +_x,|6Ե>$auVV7>s&Uw9tqᦁyw ?e݋.-/]"^OJ!O&+:.VYHXWh[3Wsm ڜwc=H!e".ܻ+v󑮻}u೴|&_/-$럯|mڶ?{VJkH lE]cBº6VVzyZνVv"zֽ53.Mi-yut#;8|-=3dh;_3!8򥲪o~b`}-ȡ%J[Sm|lv_͝`wu,bqNrlhj~xz||u Ɨ޽0p;[-dO\hh+}gkzAnEf-/L\{sW7?w|cfl ڲt/K0fHe2ټkOkGKWO T.uxWW^|v<.aݴ{df(zw:! m暏d~=tՕwꝧsJt|:u߶׾N~e)gZ?kCGKW 0Mzjj2 ?z'G)l)1{vF.&͍t7L&a]:;T^cd?(}ZOm;X>Ƀ4S:w6^ #c*0}t/m + H:[{fZ\U֨]xzs_K˃Snw>S ʡ37Vr^:o^:΋6<`͓ =e`R5֍㮍 VvT8T3pymtn7pK(Vļ71$Y@i˭aaL~-Jg5gRIb|8@K"zL(K5~ڵڬ^Om7O<9/ξ_0mp Gܺv[WKܿhRPZoVQG$%< +݂lbk.>H,߸vҕV%BLZhͳسKyd/BC\5EWK#Od++A__b$W1&w/]\YSEU;zmH[é; زSh ̛ݚ:dvj|,67xbA; BVM3k\&?O5'C`\L s?Mvz '{cNO{) ;c3念ݝsEfm~/mɢVy ѕLoLVUk]C5xj5^~;Nf9Sx'+d̠‹oN7xU #eSGy/vɪuBja@ץi9X_OG %]#$)R2~?!Z|Wқ7k|0?eH>ኇ( {> +u`rKȞj zmAEKb+x|jdZ'ŕ[>Vs4+s\^8~7F5/<ޚ{Zanc,9:'k~^' dޑ~i[ gIo^f_Vۺc|&l=>nGfY/c]=~% ޥCY׽+hbkVs?ֆxnA" kYA;־YYngh,99j{glx 0l45+L~T eMs#/4ټ:z5ZyWkFsLe-*|Q2sv"y߲m] 6|׷|u^ dyp#˛m Na~rgLӿ-tB͚y ޛ׼;\۠yyO0't?3^mmvx ?X,%?@Pɉ7-|},f,ދpԅyj]v?v`poLM-Qe PC!t2Th'4OI0XVf[ mi+dv}f/%jTfgZ G2A{#]8y&fiІP:6O,'^%o׆ny߆>݉Jchf3~l[O(CtN]wCɁ7ο~ε皥u;MGLXC'ԅ}7 q[% 4WȄ2n_JC*iD5ItyRuxͻ_狽Sp +dzv yt:cRI@y֍'<]胕 P/VI0.D5gͶy耵tepk9rO i_Ash.g3=;ټ-9WACݕ{UnȐ2H97jZn?>UFOm>ʳh&XLdG/A|7b3U uԎ¼h9ᆩ-F܊cCw_m֩{kUU8S1pA8/h>lrc=Ņؼߪ++O UC G3zCSLʅُmέ c;CP֋ٲr~y>hr\!GW_hLjxgi>t%BCvF6yWWsgʼeOZ3mV 8aO˶\y륓6x"ʋ_mc(jR*ս13}:o-/:ćTY/ũ*M}AQʤK%&YWPm֩+D~4B@]#a-ٖKwfOd;=֞xԅn U&R;Zyb{/N{ѭ,mRpilVl.nOgZ^~~؛1NN論K6Vnn757Z&MGO9$݅9MC0n-D(0[;s~83}C짅^Vb֏J oAhtLՕ|:.{P,[<86gӽC|%[K?A)&]Hͻvg']^z/4l:kǭ|Ka:xZ#Z%xe\7agYɎÍ:M[8-+p"C&Y|FIg|Ƈ>Îj\d\9ST0RAS/r~bţCZױ7rgzUE};Wzl~/f3x]_PReҥʍH"jN]9W$kUUv]YY*Qݰ)̶U9RsѴPc*|"n R;͛Vڜpvٶl6;.N򗪴j%$kG)a$ MK:$~uZQ[sny?;oǞknu9aBScF:8$o1 i(y=?s~0C>n~d9\{]Q/[/yj+JUeQ_[P#cXZ=LUa /'*V#ũ6fXw*ڍW+]Pд"6ԕJVU}ʏQv)x..*a 8-[ڍ gk/8;Ud[w8Զ7tdOapdk[lkRר jW{wڪħ;mynltc}2?ѳ|v=ؕKGvGu^{(]{>8Px6 &>άsɶoʑW#^: PJKmZuk;gf?kzǧda/hd&u~)./=1ED};WNeiz2qTƫI>6{m w,B_Q 3aoxԮP__u@|ymSҵiepf<,VQ׫-QM/fҚژ%8mb8?{ko߹9zԵe뎓W,//]2?6{l<%$fX9kiN5<|s`Ut3=Pέ٫WrHǟy⪚M?~~n6<e .yĒ]|f2=u EW^\~c#y_NUP'iOtR_P6^Slޛ c~J͟hFSE]m֩ʗZUPfr4KP* ?/6.2a-oͲ- DboΕ._5#au=Z&NmauO筥Y{h-Ns}h4ԞMmR/L4Rlm-[Jt20Y:…_wѫ4fڰ񫍶QD{JY7<`;f/WӲ6aM<7ũo/Ox٥fw>Mc׻3ھfqa{yLnPFÚQ|F\W P(|`>amBOkUl}%m:m<<?jg^d%YKl2xf&l<<򑳍~;E_z/}N3g'+zn=1*YJ*wLmxuoӖ'%{Q ElkWpjW+Y1Vw qy:|YJ0b1o>3s1j:u'`PgێۋJv)VJz÷5Oϝ^:o}jk'9G[pSnjnL mSu}K|oڢPU3D:^Nur>ma];ofNuRfگ|Ur`W}:\5!7#];yx$|KXܔ 9>634֧pzj0fy1) kѳ^띄m~kHX#d}N:ԁrXY٬S#ܫ-Y7٤t떄GS\iWcG{P$]Z,`^x6zTIxY#[w|kri Uƿ#ח{Nf pIXx ~67>4dK#gN}$7$IpWa뎓7/V~HXx ^N;KW.^6Rٱgvք_\OZCHXxl|襹Y|,-޸6>jWC$agb_~獥 :"a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a!]TZx/m :Vycw'~z_$ NvW)oǣ7_?6 ٝ{$a.Ɵ} YKjs'JHXx6Rt_Bx5] oJg=]߽Ri}'a螃:d}@@ CsP*>fUր$UֆQ*kF T Z^"+$#+JLū= +Kdn*^ࡐLOū<,V֣jU( +*BV*kE!x5 a`] Yū +]ϐU WXKV !x5&aQ Yū= +f*^ࡐ_BXVXVXVXVXVXVXVXVXVXVXVXV82T~g7IENDB`rdbnomics/vignettes/dbnomics003.png0000644000176200001440000035003313414003460016770 0ustar liggesusersPNG  IHDR-jsRGBgAMA a pHYs%%IR$IDATx^݋wU?x=Yz|98 N ^@$ A% n!\$!1@"p1$5$! I !&$2(E軫vuuNwgHˮ],~upI4]$wDE pI4]$wDEũ3bGlZ5q|F^Ɗ =7fؿ R"#]?3>}_)57Y3g\rHESI䦿ǎl{|\tʉݩ7n6fN]ĐE}EtL8x V~lYq=s]jMD',3[]jR3GݯTvYJ5dEEl➧q>\OF}i࿍y^{i̱ZWƎO{v hISL&ѳO5?ڌc|@}$zw thgaZutkw٭t$/h)wW"wcF49?چg n˟"8o{7BHBQۃI'=qKF$z` $ڑ~5j5p{tm"DwOE/nLɔM2}|ƌIZl{V0|ТʳG{XO;Ea)>/J~;j)ĎMkm\0ߜ5fdquo˯=}f}ѴD#f$͸K5fx>1kBo,N~z٣Mt=Lw=>;>}ó& ^4C&'wF޹P7}"b'hY1B)P+I[bx'|4}lˬFrF桜>Ac;!JDyW< |^ue{[S؄(I$V=Õ[Dwgɘxo0V g>0ܷQ>e>8:c͠?.0ߠ]aԄ*ZMxhc'wD!/(1omNk'Ow/8Sc+g 6;#J8:mD_먉Wyznmw 2tm(3n-4*kd0exڋw=n|z#͓㢴q暇 LIcm\=6nԼ܋-lß5|?|2D'VL@AyӖ C4&:ܵ }dSp_7j3w?2$mm֔I-(7&u$S)돺!SVeIQ ^$Zﻕc$ھ0qm6laU#q߄zikokx,}>o8ȋ[ ݠ;&, {B)$z#7i!Z4hj{sgvKd'egqm3Xi9: Y+٧h>n[F٥ͨ80do,3n S`K$ietʾsk=ͳ!hqĚ|\azĨ ?ͷ婸6% ^("P"uhV!\-p“U(D?uwx<уtL39$z}S=$W[lcA~UئQŘh'miqɋmA}}ᵌ}3~Z&U[ɗ|1=$U1TWx|?Xg \0ٺMgRw.Wg;QoGkY_?PD˘{xs br1?#Z4A[nʣZ'*|鶥Klz3e=?ᅪ(Gz*s+/2I@leʼnʓ3vn+*|p* A;r.wO {3Y_nU$Zޮy(:;I7YZ-" ٥9#saG'%d*mU()wdAf9LW/hmckgzLy)U#ghIs#h-k:`o*sLkJ;j1L&JHIeNb5zRhI U*ڗD:X(<99f>0\hb/[r$}i; LwrII $5E{*S'ק^9q~7+PoW9a~ю I4_j-JoyJc*WD1w nN/y]I6X?E笉ÚVgI w=&2%͓U&ܪL!g_"6*Qߍ9^zٷh}4zވZ׵[^|qw@IoeW>[w*7aTz3G%;Lԛ~;ym@t+ѱm]PrLH'={oW,|t6  Jofi٣I/>V=Gz׾jLpヵ7vʙhs?0C?єTkkߨ'B\ӧ?+M+VZ} %VFX[sڵV .ӘʧZP&Ɇ֟L!x~rpz(ֵ %DϞ?iz!fEptcv{e=uf>`x{I0#lZR}_™YU؞QD >Gk[Ҧ<cĢ|wIEh(c٣'GڽV!+DV۳V!:JGU]BW $.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"$.hH"^ZHUcv RhQl/(19D}xoinnN^N &.&юD}COOww>uڸbK:5aAD[Kss#,F;z+=Ћ[ tvmuV3JO>\ $Ѳ477_v###A~kJe$Zc5cf)gr²%Zʉ'&(a$Z` k|)yN&Лtq-JS9ymŶb6h\^u.ڨThQʏTC;577ˑc>5N &]Dܼpw 84|[D{NWz`wqF%!7O9~/p)u O55m[a:@/ItAIRtk^SMMF#\I"+5%񄤮FǨ_j=8f $ݫkjlym^YMa/L;aԶzKH_h|tcgSvAҶ$Z+'N}HI}&;^g`)$@/5I0}q)"65>II8D@%ѿ?hcve{AR93wKʣhnn9|Hպۆ0]QٱԸ6lN=.щU*N4?zai'N#jj:ZS+.NwUh;J;XJ֫nLXZ^!.Ox=۳/6e+{G>; l^OCc U@œ)"Њ#".ْ$U5>I+q̷(6͡gݞbWں֙đ8)ԵXkuY-eģǍXʱuTvarwu[m/'N,}9ƻ#8zabatCnQR풯{ ͘^N77 hKu oGq* 1;=ڜDkWb-AV, ڶR Ey+#HDF%o#.I&e3Skf51xg/Mk0cf>OFP "GkVLgiw,ܯNӕIjV(riƠ+)j6G9]&#t E\ 1`ˍ=[+91yɆco9^h(k''ёc_(-?lT C(:*o9y xF6xض{C9,m,kcW 1%y}CDC̠ei'ک1sos23!F'H[SG%^V[w9R~JN9 ѕj}B+ȣcbmī囝D23N$OF et,MM2(w4`C1v +$C`Y= Ĩri'ک;d%1z#UF7=$(G$:mp/9-m'q!}!zĨ-OtӒ{n/Iua h񿌞_ў7W;upchQ_j.F8%n$Z^PhRţ77dw౐J+^~51s͊ / 2rm݉a/LSo$hM7,W%M\h`LI!ᚚNZ'8ctm-3{i}VvZyN477>6/uŠˁ>=uu:R){ֽ$ZI,uTt\Y)DS\Ԕ~C㶚&d FwBV=qb%a:'$>\tA/0BQItA7<P,=:/ląŽ4ݯECZM+ҚA=O>kh,6D;Γ;@ޱ1$z2Hm8TB'W-p}'W r:'v|82V+!I%zaRj䔙' t)_gLtx3f-V9ސ}_'\I5mQ6Y8@I;$~3v5N.:!v|s؟a/L;aT^ }uaeTN j.NGLqA/yQjm7\OIO!6*ՂhO]OE|xdewt.NW6vnOi͑Dw$ZXyhhl3WnYmG&N)9Ta<{ b-Bl)Y=7z]ÙEij:fKnѷ >'/o}h@]D6xGX忿!kv&l$$с+ vUUA, k-R{,f:B4Pt6)˕X5[r0N~_j||SrwT)MM2(teQi^{|־FY.ؔ3:.nXUItXD;*v] ڳtS䝨Wov#:!ǞOzٍwGL[|MM[,⥹)ʎnoxHT %AcgSv@$: fG3JeDž fcgKq s +;!vALި>D;އ6<ƿ?ȟÎSv>}z^ e!:!!#7w##WlhYƒq 4eǎ}E%&g.;}tBjШd)[wQWC@QRlPj D;;Y?dBR3 [%юE1s%ĶgRK⹊K]:~bwKD {K-%;%6j_ܖ8Kx8qc5A NIc,7v/t世]LRj"jƞ(IcJh}w$qF؅JM?q2[pcE,Gkf-uNEgq~At<Gg s`Y,&<19>-osss+[`O97L|4p0 ULBEt$/'=nc)X?4}IRS(a=v u{bwKD;Y3Gvj'&_h=7=$(Xږra䔙Je;iVGBONHw5,tB"t(t$zȱ^?b_DB!G6n7@)I88QR6/9:)mN_y-8Dtw;;kmkN#FOlre_;dMqacsc5>5N,ID5>o۱,+H sɣ}ձjVzw DԸ@Ii'&(ľvdĕ ۛ*KqVoQ悗ox#u͆ zxHSʏT=2qr 43}Vlؔ&yպͲ}oal{&¤ ]ESlw`=PtqEo$mE\ }$ʣnjE[]S+v7k=ꂁh喖'6n>vּAOWcďٯ(s pg-,J"ٯN^ .I:!:t D ū77dȄh#I(sX%plL8Py"n$:(V9nS\|hdMmQ5"n_k19mCij:j 1ڞ)/xesحAk7(GmG,&9 'Iԩ4lrЍ[s8\ygVC&M xg>t{buH]yf̌8Ȏ½r;mIxƂLmhA\m;6>~x+GslT(pUu(sU%D75>qa JBnיIVbx~%b/Lp_V=IhN屚2),7C6$ѧem rKNNqL+,;h=GcF// eCǭ$tsɆں%e/g:v ~Є9 M/ϩS>;hA4?bfw&l3DyKdXO55?qr_Ե ӅOō*޹ T E>clvauw'#_`hjhQG;[w 2o#ăۈynwqIA8|Itާƥݰ@zkvxv=/_9x7q w?Q_oGذ)9v;6B?2R<GDeӚO7N[܆Mw=Ld\q7ĭޒW>c&eN55M9y!6\1sE )6BQWvq '_4z5N9t9o}N^COT'gQ<ɖyœZZRW5 ZUV=fm#3)&8ExD_nds@ %'uDpǸՖټzTq.=GHF*c/f[ ak* +CoQYC U+)?)X ,h_9YUV㘫FF,/;&be5f9-lٴhZIĬz\%O}Uuƛ,Mzph5?2sD]D~┇*x 2&3/|cijp]Wh{,u#вiOQotHyyy7{=[](c;d]+NIuӼt6roń>+":fs1B\+NI沜f C'ͬL0 V Q<ߘA"">\S[Μ/ Z&FEԵ(30i^}xvroEme]RCqћsL[oQg7iŏ1 hQ0#ENN=r6v}+USe#}sB-nNWbFo6\и܊jsw|o+1jVN}ăj'hJڀJ=j.G~02}̻ok-21++12O2@``iU sQj-To:x.C_У4V]0FZ9`Y/ە?k(%i/7W&#JBqIcT1 H2_0vq'(ӿ3~6)9ڲ!NC0`͑*${w҂TKGL^/byhN| ljj7S{A!_%w hJefY)sR˜zz#;+Kϼ -SZ&a+ y8[Ǔ V%jixZj4Mz<57[KGᨡ5Jƾյ՞lZD:%rv JMDslD|]Syo,L66HҪ` s$ZxT"X'9^ @ȼ4y*;1{-D{Slx 6'fv4+@ LE6Sܺ:2@5z/5R":H&r-뗬m,L?ʅZo_*9pݮD<7r"6#._kmHrt2k,-<& QޤI奠ItmDrrV"*}/o=Ioh*LT g;0[qa9G@M$z9.gCLޣY`fmMUC,+nc=MY^и{;a-6gV&@$Zބe1GZyS(Jbq$!ehMsdne_ /}nQ(6&kYEs8Jj/@-Sc mqm^<ǫJ;* ٬eQhL2n^ؠϺ%ѶG-}$DLМˆ뿩22rZ`Q\Oҡ5*pyh_ŪQIx}ڜxǙMbܜILéyLN\_.q9AS·,;V}jQxc@ItD= 1G[3"w:WJQ6Wh$2dg\@hr#>;F>P_AaI:W~1'C.XV!ah9ºMI2Mmp·L&졮ז$ +iI ;Y{)sh\!'2yl,L4|Bhe#h[qrD%FD?W8 ]KT=Es-ʝБIttCWYh[R.h D 1]q1x@[;46NtQt?ON nIt3.#'m$Fz+oYIYffL)Y玡Qd:rڜœiSfD;R}g7z~m-k (Bk IFYg_m*g#Ph=4wGrg9d4ogs$X D}Yk=hvu1Ѣiv%['i4W,4v_}q226G*<$D{J2c<}jht$MA|dV)Sm/mⲒlbi3bTeWS[\Q-O]m D':Y%R/&JcqߨPFm5޻XyRWYQP^C:$ZbqW_Ó`U4[׳-(ח7lvU[?Uo "Zqnm,ϱg͉vUuF]#2eK+S};ZJ}Y2q6T=8mשvUyӈD D[KxUAnNQ]KS} ?~PZij;[훧QYorBCmInfoIEF,/U,#Zm;I VC˻#rXF7ܯYo -֧2m$蔬8S_E$Z{ Tx߇[}(qH샶]-a٦89Km1j%|ὓ+Hw-aT:f~.]}3SRo'ЗD;4ﵕǔJ&{%mQCvȏu0i-Z$ЗDK*smxqʳڹrʞU_H $Zn1tN&w ҕ9ڹ6âI $ZJ.^J͐DpэYVnf4ftSݲgopޓR::0c9whyI[Gʗ)+*NtF?H2}+^;TWθY&3h7SGW5gL|Piy/ܼIV7EK56ڒDK7JDg ['eIwIٸZ&;ȣcƽk62| h&2^k4 #_T-|w_ yL3tv۩h{ =JVh9w uxE=;ls\\c@D{Y;3V,T#c!$2\:$*Xc7B iK鍝R3d$ѷy'%˛GY?&ַdmLavt4u&Ph`s&ӄDO\yR-[og9=(+M]pAGrNٳڏCپêNmkpǣэbeuPX8Ndi>I4&$z~^ƭXݺ:"I4&$:ȫ=lp$E56fvryڄuy9gy0dN}:M3+Ѳi nItyg~Xrw^?v{*ƽv1xƊuym9yu5I4$:j,ecIEWEgZtmYV)kJwۼA&&55mjj4UټwK7խ N줚I-{2E?,Z$vJ.W=`VDiZI P pB>hItH $#pD$A>hI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$wDE pI4]$΍#nyx<1?$zgE^VHy{Ԉ?@qz%hSJߕ'}HxbP<@/C  FFw #g3'Ϝ2'~j"\E?Tt IOGT(>gE*=.0g4z~D=5|LE^}mz$(kDCVgƁ,R1)O=<3Ơ=+WJAyBޡ$(%zkPk9h2VK>2VσCI4{7Eе Rf4t_ z>,Z<',QػUzt&eH}a%Do%0U4z֓h%D8L?5$S觞Tw I4]$/#FA hIt_F$$t%辌$}I4HJ$}I4hDЕH2h$ +De$;HA @W"HwD$DݗD I4]$/#FA hIt_F$$t%辌$}I4HJ$}I4hDЕH2h$ +De$;HCVp꫚g =+>{@EonomW[{׉WnGgʭ=PBsDK./7Smӻߋ_zwsDp;>e-+ׯ]yӶi}/^Q4oΟx[$eZrOuyQF-VQ~##6oa_KKcMEI14jUQqstmZGhS֊V/߻6*¯B8FkAKmd%礵댌X -,1a_O/.Dx)?@s$1=(}>8h>T֣Օ"Ϻx)T벓'C'Ι]ƉgB>35JGx'Oymw k{E-Ԫ:}82I{GmU;n>.^l+otUUߘ!@BvqAÂ|b#-Of}I+"׉ן1fy{ޖi;s V~hU:73лo_:o||7K4:ݬPmSEA[LP;{Ggj?;ez#~҅l[Km3.#$I+WV:T\ƆC#HZ FEI+O}.Z_V_^x_wovQq/~wz"qDj9k/~~E#o=YOǩ󵗂'[~}$-[LۦsFxj ˬk4yWӯzÝ1zƧ#'!\wzyFi9= #E+.dVW^e9[ޔJ{qY>!L.Zd~hCUXZS>B66i)Ȟ=ւ#qY~&3YSQleb9wHϙ[N^ƍVo{֗D'lCCޘ!c&sCYKPU2>vVNx~D]V^--g )n1(߅]Uk5>9dnIA_꓏?I<~ʧUKjo(6|^޻3YBۛCFp__xᓏ/|mŗ!IsMe6r{mO?(TYG^Rs\;y{{}'+eHIF'HwtA$}m͙}Ʃ;F;[?>}'OnX._~h9&:w1.ݿ[!mw^[ڄhKi2\vqƴCz|nwW>kjE-W^ᜤNqZO;}EmNZ56da 22bVI) Y)".b=fdĪ =2Nb0+@ߨ՚cD.z4߀b[˹db^$ڛhSW-:ؘGb-Օ/")f5]51"mJ+ (#Qh-+FiXZcxZH4 rrI)X][5It()'͵ yJJt+ TX-{ 6'4N{园C##Re\9LjW D]f1߆s[ŌWL7=|3?B>U"/`Ni~}Vs3X&Կ#ÙmD|c#s<x'BbCd2{hv|u&x+$Z|~_Ǽ1[wG'[ď҇+w)M3*[KunAk+fO!#-J[v}XM׏}aQ bL4NOeRukǙ+_54y.==fRǏO#u ?6]g6y7}M0lX I(=-S/[Itr{ZrvfϘ^~l'7XFpjb4 }ܿ}& u%ng -D$_]zEg|u3^?$8ܢY>yj IS9Moln$z_z5ȓZi޻q*$ڞ/X/] #Y7ToJ'$6_AbNCPhb3B,aV;vRݳ`c_DoZm0߆XxGw D+Q(c[G6#LR;Ogatch$}Gg%r{ٟ>>?j~EF7}j[McFWܻh9oyyҫUt~JS!ɤ"#M\[owӐ'glɑјwN׽*c[FaDÎȤb1{{ z%Ō Nu y{6ws櫹H|olL)˨.jYDߣ%q4J($ړ3߷E#k|8^P︀+ylcÞh(BNsTrnʐF0`UZ'W* m fZ$ mW*_?Z7X ]>-m̔p MXȅOշ?u"oirR(X& ;V;IǼ1uAJD~|^uy ?Id|6S!&N!/'.J?3YOaf{i=~|w|UQQ-Fz?7rYOroEmwQ_ܙ 逥;$N(IJ^h&Z;'JҔ m8TFH򿯖jEG7STe6a#AR%#sꥦ"{eXnE9/7w~YY_Y,|0-퀷'z).+sH0 f&>TBrUy''^ V͒UAs DۺAσˡ?6A;N^d;NٟBN-ԥX. TKsY3I[}7ub>EJ}?g3v휯-`{4^UqW?yv':ʿ;V_T(mty r{m@GSͫҧ ]h9X(:KqLXdB}J\u-_^eĘ'v=reZ$ڈgYrK2z+>S} 4 It"FDgȘgI\ЉܟfU>7"7ge]~:zmsDyR}M[+Μ39'Z$|J@Oe»b+9OUβ}RriіN۸;Ue#.^fk,̘-rOut~t)ZTe\O^d 4SʳG$ʎ!UXAd\g:z*Fs&M\W]*0]f/y ?̮AhAj6JN)aڏs>ivUOڠ)k^lK^?yc~ !s1Cw#6:s~k-v`{O:V7 H~;ytrmLdÈh|?[p@}uڴ?,жizKm=6[Ƿ/$@ C-B)}ÖC.c0U[~tѿKw^NuIaɆM_yg)Fq詂GHN_hJ91emq09Bqi a2+Mqg`Ӳٜ ]zzp= FN/2%s|KMr1w˼,TM['ѡ?A:Nr+3 F:#oX7NAgѕWtvH#VރrJ8lHIt>3e NzHG]#M-f0Tq16;z52&L0*\r~leq`l@GSJ0gg'h$:-mo[tAgL!SkA_״1^נ(Agm-J{|Y1n&:GW$ѱ9_l0s5(_9)u]hZv[BI5izK(==Ui@\fa>1e멊c2b7J''a$XYXĿ'פ 5ȉ\Bs;2)2_R5cb8cq`Qǹ;BJCۜb$m>x;o_5Q̭Y<򛧬-8 p(hOIЉy=_ 0)&qr0zrNkv3ũ$wGQ0)f6h=,n,ܣζƻ")bV9[)">[.t5 o5eLX.1g'4o/_"ǯ V:=h.C򣴯<%]tF2=\}嫦M~iKTFl]\n{Zs~s+ˀWky8/?FL{JښD]_\:CgLP'x_Y[mzch_."ݼu%HuUhꫧ>?a2~y/|wY|4'0*\I_4^t g}i_pU9oMiQ.]g`ۜDO=J.p{>7>l 7@5in7SajQ++6[\:7_Qx9곥I U&}UVVe#j&VAߘ*S\QG5WTk5!9]S0cZkqj@fIBYAym7UY9EHbZ-O9ZEUyk'!?B8oW>pQsᎽQ_lǍ=eƜN}\K*v4T=of#}R>#v~ B|Z?CZN#,^w$}ˣw4@O]:vd+|x?Vf- mXg.t5 !P}6qǢw@4I~/\_n5/EQLTҾ+I.wnNi}5Y\I_Lrl/5%ooF:kW|']2ҋooW$YcBÎ]|6'3i9uIt_ڧQr֣7>QrwZz%gyejW i_s#Em?m,:+Z/N:j{ѻޗY O5kD~i?nBFJ@O%#$ki4*JvdLӒhwqћ?u욢㾋,IM~Lx[e.'u0)&촫*RMHՆF-f721xrl wx-x "f%枢xlm86Vk?FgN!ڛot|5xD;?!Ȉ|Oިߙu$ocMEYX@O]:'{0>',:#8ܥޘ#Npy%wƉA[I ߸iqd!ڿA{掎t>K;> X1=/ht$r_nզjhe#M\ʽ jr:JP:PZ׎$Zx.}qѵ?;[2vۨ=m^.^U e҆ _1菵C1O49N(=@כ6z%G&~kkdZ :8FB$$nvm̱v>5:#A,]D9Z t$}I4hDmQkt}Bh}–ڬV֡辌$}I4HӍ/h'%:O&r”9It_F$$豖UV%XK3*kuMdU\]S?RyH2h$ @L:#^E$Z[rьGAݗD I4]$/#FA hIt_F$$t%辌$}I4HJ$}I4hDЕH2h$ +De$;ZỎWK& $OqHF(O;Daf"F;xck~2 BE|R+-?$͚{1Bt">ħVa$ȿmr֕WBPwWSK|vO03D ЍnԬFCP(=O-=KL3Dt#$ 'h$BB ГDS(XHzh  I4@OBMPzb!IH)JO,$= I4B鉅$'!P(=D$$ 'h$BB ГDS(XHzh  I4@OBMPzb!IH)JO,$= I4B鉅$'!P(=D$$ 'h$BB ГDS(XHzh  I4@OBMPzb!IH)JO,$= I4B鉅$'!P(=D$=.ʏYjÖڦҁr,?89stOvXiٵdvscv{R퉆Cg?ZJGDZY!4B Гt~9fʊ5Sc<)IכϤef%,HZVZ~pUV.N9x$W_C%f9Zͷ)jj9Rڙ~ͷr6:c$ ]z']f_DE-ON/*+_Zܫ׮j~3#+[tIh˗kxiZH̉Oޔ/ZO?/_S͉Ch~e_iOwck'h@_QϽ=c 6V+=IK}WI6~˻g?Xe/oj>sJ^vx}U; _k{>9٫JZrM],jC?46lqh8ֶJwt]ѹڷ["P-:ソzQmł%[^)n#cٹ_YJ/ \du`B6]x5oWjfNkYH}#Yd"Z-ڮ hD[>߼mEeGB C+C,x({)sտtTG۔|Ն3oϮK)m@%ә߈%L[$4kAի'84}U\6ʏ?xuq2KL;x/_v=+vyÏAđY2kN4\rÏmxy 9\\=7xmݱ?0vV!~)cQ&ȍRm-a4#z9tZ}Umҏ{|wbRJMZ᪓oZ~s$^^$5r& qݞ ik.Ln~e/3?;{RġaSV~S좝^ꄴLtZ!~QϽ(che{_ hq蹺a-9MS.yzUMBZ#Ϙh Y%ϟ.'-{Yy.#ȁRV<\%yUqmUYÊ7b_swN:&?7N kX˗ڋol".c KH[93o~ s[|2'G\;ɧ}'M8.!5owO>5V2qq :&~^8Uŗ*RoK:\U#3E6c\vxWen\'?dq0zJnT\ե-U"7.HZvWʍO?7Pw¥l37q٫=C(%p񜋛&n}kq+MH-.^l1N+$/zƬ"Qբ(su$Z&e1q q tj"lz"q˩Y.y I\k⥰h Ϝ8{IK.IJKKLKYi CW=|8¥ ._7NI|8(.s$3ТprM|tNnK'/yiItr⌬v/̘Uqo}y+8_e/žh[^G_~]\UrVEyk^*O*%9=nb\'%^Ǒσu˜9PRY\CωO~[ ՍM-{֞2)'DeQVx ),]h@.OQkuS⎉&;#n^YUBQsw$qq4qskszko+9$% ¤vբ(su$w~!#3o}ŚWf:UM|띟~o-,-]YW(#39i> w K͎_jV)8u|rzEձKP"Hev%uEʔSlūt{VV.{y]o-8fO5'Dv~E.>=nɦm;}rʕ+U5uQi6ᄐ΂3$-{y}˙[{󟉍RK.|ek;g'ˑB&%>)qQv30R>ǧ_͛_~W׈h!~EeF)9YQʽb.Y).?>5{49e\ѡ[7ga7s|zyյ'\**%٫=C(nE c6{{(ZDjw .sȞE~)cmSs I4KЋ}a_}`#:3E+Ga6s2yphPVY * :f-XnA|q GrEn4"/N])[-7%SK{×n𜾮qNs.2e 5'rQރGhb(tr<O,pQ32֊+"y4e8y1f[űED7Y\p$:e9x<^Y/4|ާ&?ůkl۹w\fl|C=y6$W\}J+' OkzF%u$Ztv-2l8U{dlwo[r++1n1P ig|}˩-DwrY)AN)7_J!Py]NE6l[QqL/}}KJe;{R#G%?5#KܜoN.>N>NUCx5$Yݳ۔+~e{~r-J\ tDz>>-z9U>xQʊk_Igic*:g+&.AD֋c!%Gu.ȍDWg-LZfsw5-Ve߲ 47Z%  Vceb6jK+7nͳB8t?>9/&iUYvU)%=D1^6[ŘdcWv}vVoWʃ˙:̑㲂0|źFT+SX؛ᄏtpՂef4|_;tUrw(7|#.vqRyu~re{V ]~l)I4G}OwK\so$X=wQMT(y2T9$Zxo=95p4 ZZrrcrm|rzu 9QuE\U)+6;:1yq̽[̱ eO25,rqWO'Vf7y}cSQhl+R\l*3|v៯*W#ihu pW?ͷ߉ Y,\Xg>OKrFUYnr媜En/g?(7)Sc'K򭗐i ;Dz>>-15<م-MHպSƸf(ӱ ğPy:P2gfi^Ot^GE]1h9Sf%xh򗭉.EIDiWobիW= iYUEl\Krm=QvY̼U)tת-\qY #!ѱ(m4z8`։eȧˋ_)gN,Z-.9Oο}¥kj:,/|j.I%гlq"Pk|G"2gB:^bxzD/HZzu͏W\}.~LHuzܒ}ѹׯم= ~K_Wh\zkIY Ϝak}qw=+^{"Vm^h#Y"o|/A"S]|J%AWmI+By19/#+[lڔ4|ͷO66MG8Mʵ N-r U)t|Ms=˗O|r8W[iR.ʁ8y,|TrꄴL9YmwZ8Hu+Wȇmv|Q.bNRZqĉģ+zM̂_<^&]=?>=)w8ff|\\x/o8h~gU.cy I^>~+ 0⎉o~|W#'@ݒh9tT &.ab$-_r#R3E iٌ%by i^Ce3o/_^l6w3sA8UC]+vpi\B{ʊ5NHEO嵝9D7+؋3s>bWi"@ $LϘnS@uuuUuuWoAYS )Vlo>@N4A(8Af(ś A= N4A52:.nvt>DCd AdM1>,`[]8٣DCYS )V6oQn~}qf6]񜝐06]8٣DCYS )h+6hLDPL^P{/7Kz,8/ ]S\$d p!G 0SFGVl8#dڜC:6o#sN4T ' Țb|XLEXpen.scksCX pN4A(8Af(D2 =\v:uloBN=hFֳ۠J4R.D|i#¬$oi>]EsōhuhG b`|g&-Af:pѹU40uigEIyyk)+:G GL<:הsj 2ywz*sʝy\ N^Σ985-TKɤ@iOWiIEU=\&PZUvjmfr4d,8٣DCYS>Gn6` f;gG2t8^$ۥxi2>)">5qBʉ- RxBRNtDg(?9ݏIٵ cp;N4Aw?~Ȩ=glZ>{Q$!|F$n;z᭐UeM󖧗/p>)y!\o_=?qm?WCUH] m/ dDA)?4駫OjWP?_s\[qysuOczN.4{ٖ=:AsnFߡY;'@fGKAm*Ƈm6 tͳ7wN '"m`6ۉ0dQLiYD;W[^#V9{4BX ։^-- SYVu35 bVKrzOH}vkJ)"p;N4A(vd@sxPT׹M)?A['~^R'zD)ĖBQ Ug qӅl\hJ!TA{m`* 綐I;%S g-2!&qE=P'ݛ,iCNtފ^>_J()h+q/'nVx2st.'$!p3 >*'Z!㊲9zظ=įT b%Oe}ɲd!6>;Rf>[D5h A=VI8WqbۍB"k%߯m\rQ?-JW&/:Ѻ;b8CeAkm_d-V%!<ĹMV?}\yw=7$AwFU_J*hm*Unbgc!w9#]؜ΙD*<2T˰.͇v6D߫`͢v$I/‰h+N4χ3Wow3^8t39Qq\JmfDLaIbhq-bXmT%UäkcЉ 6~/)VG+ N4`W eN{{&59(ZD-uY"gP=#ɐ*m"6-L 3ҩOx>r rˢM'eD5T u(QwLiBP:#/ΝwL}mY!NtVl hA~;x?LA؉{8O90xYDK!8d8zq {ӄ։NJ!Eq|tt&ε&4ޝmCjÉ:p!G٢dQǭ=ӒE:H"f'卜{0%l1D}gy ),鄽ꟽx'zrTzQ#ge3etm`6׉\l nO cFHH":AM&:$6D5W>G1'Z]N4A(s͔KT"YNtCFyɢ97_zN$8/'y(9v:G L,&RUH.N7J[Ul˚A(Ƈm6v7q[Gg¯'rh{/?}z;Ptx%R\Y0SFGV,uO`)Q:B҃y~==S.1c{wABÉ&8*YuI~+GK+#*\+.Gw4D|D+Əc!ەa`K eNYӬ9w?eRq1{%u'OsgZ7imfʉ~}|w ;:ytӽ-'Qn0HXs(>‰6rڥHE!i-ED7Ԟb|fCh^yZDo$6^?4WE?*P'7GWɲf(܊mx:p!G٨=E6ST,<$9hݖ<~u9]rZ_lщV1r1k) H+W-bn٢`zV1yf>/ ldl?')v&e1>lN7@N4A(s͔|}L\."kNtci< -P{|TkNivLƼ_Q2Ž|JX")ЀSO% 3|۶qE5T|?$/gmY!=ͦ s/uD?<ʸf(ś A='\qi^slTE'Zp`= :f2prչ '+!#-T8FQ{:䆕_#emY!ͦ͝7O= H;q)Vlo>@N4A(sh,]3= LI͐ey74v,4lO$zf[:%N;&Iך s.M܎oX>KODFXN ܲCPaM:9K):ttt>DﹻGu{. _|So=ZjόcDž$:B6D D0"slwۀ7s{)wMhyZf* } j3(wgQ{;d9]^xe͇v66t#\{CKNGo>@.̘_a=а9c뀁_;pkֶ I\~[ֶϹo׬]NzIHƋ.I\7r?z0w^CO6"{c9!(CrMܖ}gϞlLyڤ'S"oLaȱ}Gt[fB-&?/ pٛQnM_8}ȹyW%Q|\-_Ȑ{{8{=kl6(IV[.woC%J[DVč偳i!. v7-چʍ!{/?Ro.O UZlj6~8n5l-\BȾ__c@/?w<)Nt7N+51KcGu <1l1;oW˗-н{3mO߲-˟Ϝ3cV/\Ǐډ&nٚ;ӿhc#⇈\Z]]Ԓe=_˄I$[ma"ћ@zr/׿y޽{w1.n~/]6~v-0hCr>zxmR򬀹NsdQ'QElne4HOݟ 4EOQ7^%77pv*YHN^rKqz{swKpLRFM}MIHz@[Dpf &U-YU@h'FN߯ں*?kt~MyUvMeʈҜIXOPwK˚A!Ƈm6r7O {aqt«ˇ\xG/55΅|ͨq/+VGBD w0iނ>޿yhkb]'l幀߭\$pqL ϓC޽~FaѾsUWZCI\w]ꞓoݾ]| szPHxV?HJC#Ǹ[D\zneݻ [:ќU9OJ' rSqmѓm84}/Yf6.V>:њh,n^->F;L:oƽgIg!M[DKK\i[Lͤz|$kl'UHvfR31W,55DիhMF5f_5XlDD$}HݛO^6ߔ7~yjŎӉp;]8Tov-rqܞN?Kِ:c#G57n/XӐi?ԠzM\רҋ/6o:|tڤ'OH I1z֬t: ATrECw!:0SFGŭ.|hq_8NDT̝;wi˗/>j|d>3f .]7;pS? ? \CN4A52:.nvt>l։nc%Z$Ơ>?lv-+zjgrU=.&1{!jԃy<'$?gxN.]Eω~K||if$ D;Nnޮׯ-h0SN-5ޏ&y;^ff۷#"z~}S,;wFDv!v' Țb|XLEbx:D766:6nŃT-c\&ϥ=HOTr، A+8Af(śA'SOtg׻5uqw'OMJ2!k/_R[}WJ oMt/^Xti5}rܡ"ȥ<'֭ۡ #_JShHW%$z7ߗt⌦M#J{y;W%$vg߶}ǫWT1 0SFGŭ.|· :tI;swɝPest)+5A3ϓr}g2&q&_MD_t]\0W^7Zr9rQrihQ'NϘO fƭ5UZL%?ьMZ7sv`gϞ Idc AdM1>,`[]tv-0hzgR6{N|aoa~8:d9A!/+ܼ]xmNxtK/G@ իW?#{9h~hZX׉R{/vϟ;ondk AdM1>,`[]tF||%H}a[:}>zy\vi `*),'ݻw?>Bи?3w 6._8J+5ɗrKR lMp!)Ƈ̔Qtq+7aN KPZa_X_rljv9fƬ4Ht{if&sˬ;˔ɓIO϶m2aƴH 9d پDCYS )Vlo>@h@w_.={o_?ƍ7;/xիmwL4%}K˗/ov`ˆ[n Ib@Coڜf߾}[|3gΆGFOJrʃH"~h ka3et]܊|ؠMP0KرovEٝƍ:ao5ȚZD{&yGF߾m2TTA <^vmG-$U1"3!>hIS׭4JԳ7:DCYS )V,AAu͟?߿HR;o߾=pШӦU9+эNtȣǏɯ=z:awz;wG/2A0eN4WNCR6=+FtZ,LR."9\ l1yacǍ1e۶;H dze~573 h ka3etCAAP :D 30&OYEQF=~ظh񋣗ܾsݻK!AW1! fm}ˬV覦.Θϗ+N1Ͽ~ͦׯsvME%? ^|YXoqo{/ռ(ՙA +88scAu1Vlg_3eZO;]YO1lQc]%fXru/˜Vw1s皚Lի 5?lQ]ubщ&( 9˯=_۷H}p!u"Q<ʊsCtٜ___Ʀ[oQ.MEL:RE @h+VGBjɸR6swޑ{/˯MJ~ Ft_fuu+9|Dj 2lM;wR{UUlƯH x9'@©gr\lenNS\7җ>W:Ħ QQK%w6KuNΠԲxH'&' q+-  YܠMǤtR|_աn\[qfG!7,8,#&6h5nuiYnWCh-p :MMMg+.VM,?uzK'O&%:\n[tϜ4kׄ$-"9t3S63AFpt9?([USU[H,es\!ezlD[8ux(̡#0~p&M'سkn,Dd9`P7dP>_ 4}/ϋ{R yiQmhֶ2p'ڠŋ[ϘU|۷o?xŖYN8/^rΝw\zlDEd&(Cr I:2xE;wFDͻtAEptGS?rl˸̘4)[X<)7NtT|:)V{=?n.Π9bif2"jx8y;u\jYOez'MR{xf˓t]lӉnll,ؽw"nܨRkΛ?~;vN{el|!=dVWjMoC%?N3toޜ\]f:94dبjk 9ƅԟBa>όYǎѦ+zjf&}.BPh]jX\'p38[׶ h{-h]O9 ܑu)Z,m8SIMnKߋC~ݷgm.6&D9egW^xDM354wޝ:]1C/XL ? 8"xЏǍgϽ|f,Y1?!öe4Ǐoܨ%L:~ϥhHׯ_޳w8Wڂq߼ySXLmwP[oNX?v)JIE'ѣG~_:7i3fhW%RTDT̝;w$=}jm9\7 n9R%ϔ0 uFzN=WG6Mʹ4ZeaݜG볃sDђV|N}3/рYI4vaR]AbTs˲K'DuԫF(RKI_K"uZZԲ8 /qEkI){drIL'BBe]I-]gpWLz#$VXݭ4V^ =G;0^6Tn zZ(ZMHL0VD5M. qq4C\r,RwAs䔟NA:n{ӹ<;nO{?bC#8\領ͽibA{/Kj?ٳ;WĴyH&=Tx;99ȟh'kb7 #Y%`fMy4Ȳ`t_&U!pi`3 )ͩ-R83/6RZLbi-ܲt:Љ:|b1ƺJNX+y/_ھc挭7oXft?).dzi? 5VoG'OMJv0IZUMuhiO&q-hjj:vlDޟ{O DqO,1 sCa%Y"ō!d 'c-UmZN!(/Δپ;(J҂1_2C 3_D)CU]>'Ye xʨ&V^Cũ3?_#cnӉdY`-M=֠7&iIEIc3s8<%ʝi̻[@ ĺ`Ca.h# qGF\`4* @VB%'jཧT;Zw@p ;eubMi%=9:הHJ!;h[˄&= |RPa]Kd&&}C//406i8#b ̶rfU7^\w<8&+>B kSpcGcEmМڤ^eҬ-Ќ mCS"<9|AmCtmd7#-`:]p53:&cIB6:3u03U`Gxh8 /ilu,Դdnű)GbgcҏU٩ >!#|~6Lgih .QQ?z&Wk| sj e9"\:ȦVA,}J<#Sў$\7-tWʷM+ٜGSOS̆܄=uΣG&J.j~U\SG9:$ f :Ob'#xyU\ԩ,Tt8٪>WYjfJ"2DDT@Bj ^ N4Ye'tۚY'Z8؟="ŻD K"bſN3UJ8\❟]yMeRU9=dЉVnp>NҩL,5G _냷(IΔ^5tqE^e4ډVQ>tj*ɂ(La4%CT9M 93~Z~F, YլB6zLtlFB0hdM@b<,j FV:fڕSa#_# UR[m[r0cEK@0cFljVqC}=AsMi=ENo"_OI~ !^:*wH\v=D(􃩱ƞzaxX~jV~)曠cI>2<2@(\Eh|Q{"zʹL sG13k(ƦrPoSI QnظMcPM;D-[?A]:+`/3g+i #xKB8/_Lߒ9m_a7oqi :bsֆ޽+9|dӦwlMDȹ oTHoI)'hkֻV~̀Et+'`Gg|C$m PWŅ٥;U_>A0Dj hןPsPU؄^5T4m=sT(|~rΎ.b?dj>5椗 4vW30N) ]]2i |j|It(4-N=LmcӅa8Zpa4{0xZωVqC}BU9CޢC#mY ]114ȡ_ *hQzWt!vɑ^;ՂчʷKW-'^}*ѫ"]^Wsj7 Cl+МЌ0ЖزMWMisFs͟1x :#Foڮ^ Lظ'+>'Vxܼ]_RƂ{ E& yڤdGo[Ç4eN4iO%'OY{WRsNpˆ[n I)d'zu`VWJ IՅ=\VZY~ w*A[sTW<1|)^($g޸XXFu噲m# \z#"p")%55ngm ѩc{L4X|mNikxrqo8;ֲZfW >ǯ)-5G}|5aA0he#h՟`s_XW tG1PRƙ^RNfzwvaZQ -㷔$fO# ۅ&)YĠUtЛ^!#t﷚I8Y"e}|MUˣcN6|>Zȷi]P ZJB>fzH֐V:wPsU.鐅)64M7B /WQX4U򁪂>˩z" Wz!P;z/F(oŀ0:և TQӫXz"ߺ"|zF6lլm-ʵo fw/;1c*\߾}{! 4)ƺ8(ď?|𻕫Gbt466OJ{ED.Pߙ4,rCC挭 tGoS-!9?Ūf9ѿ^4OA"ϗ_ ^G ?vt?0ʕBhRKYK򐫓~C"$'k=7RHHܼ]3ޖ .N%MJ 9wgHn/#NTKNtPRcINxo(I;2M'G7y4Wļ3{3)0`!*AVuE-\9: , _~<{^xb>Cdx,>RM ZRĿ&mqK-) 'QSΧ ;f@Y8@br\Ì7F ud||D7S֟hsJ1xzMMlFX:dFUu-̣]m| =g>ghXHOvjvAz՞oVx򞗼iz&2[ :Q?J9 %gDVܼsǍ1us7D# "B$CI\B =!Y{pcNѧkV z5:#\xar+ y\;=Zv6^ګӡ1ګj@{ҁN7#?>Ukno:|X$6y۷WjjW' <ÿϿ s/pҍ'OC^ϿhSqA'YCƴf>r\FzD7nԇ. :J̘uwdl͜鿿dY*r-R`sHRݿ;WE@PQ8g_~ߛ,]f]E#Zm<.Ң?Կ[?r{ڬ=m!́e? '#_ _eP_ H>؜Yqzŋ ̚)O'vh3tzvSNa+)U|]F9I?],U%eGF!t5eab!6 f,;nOTqSCG{Gh+kLM{j7.INĵK^ߥ7Z3MLܘm'}j=jTN_W7n~R"Zhl چҩ\ipA!N=dYs&=yDHa]!Yj'Pd5eq2:YȎA ǎ*:fμ?SqJ8H [H%LJ'(f9֛vb!bX3hq˰O'yR!aԼ}M<}>IѺoIk9ѽǺ/⊙?ýW/Ͼ5{܉?u>Lc.:gʇփ_/h!Qa>lRgM>{YieD4.G;Fpmϥt,%B gSC?+ rH!e19b ԑX\!8/*E2ܣ' 5=ל=sl1Eu$NJ* HY=iSb+@YIK +ЮbQ $jFjf}aP~nԋU(ȦGӋeȩRb?/@KƠUt/K_0T`eHkY .'̈́i}D ?r+WfBˑk9$pzr gFevDgNeb wAH:}"[8`.fψ!t0wE|΂CڑLW[;*2ȯi%ܹmf kS"O}Md+OűG+!_t<AoHCFF8uHwCQ_/j#OMج2~s҈0kmoKrÉh :Y~J$Dz(?uk AU8хMM] }M&hj':dX^!dcxoҊ&'LA"ډVٺƉ^<ДgzM:f~T⹃>3e0s-]'7v#f)$XBt6Du.94k"INDH2b0oSF4m8%.R/PW,Zu!-4͝}9y \JB Ne~mv|G9b_ ;. fY$N}3͕y!-[iL1- s+4K_ʌPucňvwlMIK IV,Uu^'kz4ΣG f+_~zeJiܐ۹jMP8%1E ͌͗NmP }_ю$5N,PInM|cEjBآ\ݽKDܔsաly=LK+̪Lpn)AR\`~q0up{xI]_[ZuVEkc:Q>~qNR_wBPϑ=u%ܐ08Z ==o *VXVj?h7< ӏf)':}Y:jX3j5ӉwI ́n c h5pa;mvFhX& ,p!GـOv!6NfnL{ļܞ|AnB봠,? sdK; رPrmƉ.m{rfl/ɱx˰ohhlƉ~"zT&N4Aۋ?  xr#nX ,p!Gـk,г:ѽWFKr'Z ڨ~ 6J:uxP8юH af,~'j πYS;|htXَ_zqdpF)tvsT>4rrhqc@7Oθ N4DŗF "[`+'[N4 eN4L2jW9o E]-5X1XE%̱UɪI^baj;UWY!'WG1C<{!'𾳧#G.1rY܅)?13B+Gr8h‡cdr&MD  D867$iBF ,p!GYʼnBtLD '6m]D '6NtcuqLa@\Tk8:%p!G -H4ƉptJDCd `O ' A= N4=' {h{N4A(8hQt/S|ŋ!.)2L"p!GYljף|Q:VAAD&250* e':{Wsׯ_YSSP6AD2L dj`& U A= NoӧO_xݻwBAPȤ@2A0S e':{Wӧ?~, AuyIL 6,+(I |hgF O$Q' {OƂh H@&f`Se3GϣB8@3 A= Ni^ByAċ̔P'zx6 3N4 DCd ALL{:_xDE͟:M6N Z2M 48٣DCAm":;0SFr"kvHx;p?&dXpǟ|0** ׏,N R~Eܨőa <C.aQQ:'x~87 45"IASʳ);<>'hp!G Dtv`FDD82I&YLaRQA^zHg5Pʟ] .DCN3TKNܔLj018LHIab;(п[as4D־NbN.==9fe'ڱhy ' jف2:v }`_$8,"f|mJ/drwXԁ !ȼG=ZӁryjy^TTOz3B2ELk~kO'ە[F!|s}s cN4]n&hy ' jف2:k&yoו̕ΙAushDqK $kT*=?}>tOԉ8TU=p?MyІv5uG0kn! & gکs[BgB3~ Tt8~(y0Rᤐ(e t,B!UDy"Ґc*Xie֎9˼Oj6kiI;_847oZ:cxܦLЈMw˂}[YN4cpJ[N4<:ЉXF%? f' jف2: L8×O,}͌`c6ްc󚉘?++~N4vu eѳM*tсԂ$_nyl/mDsP3{:x~]RuMNp~F:$0,8@ u| AL=';\ z5Wfn2N=iD1Cv1hΆZ`d2jEι䖽B]!_s4gFMͮ?sEK`Nnm0W^1'^| =Ǐ֤7X}@? 4߉mL· OBf}.;HhuͪN3Q6Si(E\pu~<{ Lȑt  'zOoh ?QȆ 4t_|UtyK~>~r] bw>y{SSӃw0D-.ҧ?N3/[6b%G ?F-]x)RwrG.ÅKW޾}+ ĭ!"#?xسg BK|٪uȉ—nښ} R _x\!-riRAr]S3Vְ||^K~ÉSgF/]Qoȹ| *nM3^76L-~SYyE}Qקe\+Su5iIo}}jwX#ǯ*@J#eȋܲK5i[.!ȍސEQDkBnܞ;I!߭I>yw*͛OoH:t;I12 644dE$ܗ/^ңFp!6)phfg!ag5R Yx!b:ruY1*QZ9Zԑ%4 !;kUG'vNU^XcNZ20gȳbeSQ*ӳ%Nt~uދηFuRt%44<2)E/ݵw?9$E/'-{ ڝEp!6)prt~kT)S:#5TX)`!b#%,2ށؐ1#fywTDlGLF(LjM=$Y hKvpkdM4AX5oǥXv9xpBD\u?}j@ʶ֚h f.>i,?w 7k:ܚhkkI5L9:Jč7>XMzc M}DĖټY})?d,Jژ^S{ݻw/^Hiv"9U**ɹ\]>w6g^qGXrAT쁒^毬Г8u/֐_XDՒ.MD*FC=ysִի~:+O=uܷHiI:׺4nEԉ&EH^y{c6j+NJxKzm˜=fj\JB"wd=$W_$'DH~#׺s~Qw׮XA:t׵i{=w7)Yn2R_O&eEu.rM[I{$ZLgIR[;ͺ9rMmSSSc㛟G~f}_j!8AP̔h8V`ČVo$/{Dͣ9za J%3$UΜ;OU?ݽo˜2o&)@tC ϹE ϟw08|UN#LNM#cpeUSSSEeR~'2Z$3q4Jקf\^ߚݹ{olRgի,VԽҲeEԉ-[nll1q|rr-G9$;{ GIDATH~9ڽ䞮۸׺$WT|&޼}+ՓqܬU4;\\H2di\k1j|ȱKWHί*cЉf\Y;-]Aw4ϭ;wS3N' jف2:rf"fX/<v8'hDǯpr =˗? _M UA$9tRfj N@GEKKׯz}mǝ ԗ&b<ִ:KW9v%RRJ$-哺zVK>sKQ! !RHdh)=KYQ?CZD/^xfמק7VX2}(%;ݑ:._uMr9K #!8AP̔P':xƀnƺ1OQ h9&H@tKLC /_d_'2R_[:hT1,ԇԊ,K|1kKWSl-dTS{mͤ+,^]W'-Zah(]aO !bEGZrm欜r Ν(- AL"vAN4`{quz$]+IQf_:!/bI\hr?DR zִ¥5LRbikiE>Vn$ERh-"({iR@yOZ<ؖK5&s-$_~武&R+U>d.g왑kU̪*8AP̔h=D769s٢%iFRZl4'75 4_QM?<2ooY0',:c[[Ӻkקf7?y.:D5#`ATk޽{GJ×Xc_sf@ ~7nk]%&'XrIoW~TCiִsƐJ9vucWKO[#ͷԇYKH't`_֬X8u[wHCnݾ\N.ZzQ[w7r"w +Vҕ6-ywoll襃×,#%+sI v<Ӛ555]k"oPbEk}64*Vm9*9DFZDCjEFjHIRHn$)oZfK ^Ztk(w/^͏4$`bů]"\̵$ǖe&E,]AQj+gy{[IJn_1x[wnښM2Т $͔!8AP̔h=vD555ߺmgAXr$~*jR Dׁ.[`q?.%%gP-EK\HZ:[v _ *~SgtT1ڴ9J'bH}HHH EI<‰&5[DQCJD'[ԁҽL|e$1`AThEU~I۲\k?.Z)d%GUVX2{TPt^d>\zfZd:\EXuǮk߾}K3t |r1)z:ĉ.Z̎Bj,;PYjx; N4AdȌn MDgf8VT8{?GQHJzݩ3KK]UV^ѱ+۳26h y364)zD[QmD2V]{ٻ̋vl"M>sٙW%oTTV/_~d7nަGYj-N4A$Hόn MDgf8VT;8ѤdR?^H~c:f-zNX-$,_»w|M5' 2ImF̆&3eZh+覦ڻDtm̮[^&LZMNz鍼=o߽GG^jTmAp! ftmh":;0S ' bEDtv` @ A= N4AֿL' {h MDgf8٣DCAm":;0S ' jف2N4A(8AP̔h=p!G Dtv` @ A= N4A&3eZhQp!6)zDCd AL' {h MDgfD/ML~ւ AY_tv` @ GDCAm":;0S#p!6)zD8AP̔h=ph MDgf8{N4A&3eZh=' jف2N4 AL'`X>Y^~w AE&25 2N4ӏ? ˋL dj 3eZh=b'7lӧ/^eAȤ@2A0S#Vp ٻ N7/џnw1 DD?kx^U}~M1c]?{?ŜyE?lSܻ !qEuo0G ;ٿ?=雕\/gUyxzR"ډ{~BbI[3=zT"p'@'WjF/Y?ٿ3nX׾|9z?3+Lr_ڤ9L+"ҮqF󏞽)N_)ؽYsN4N4=QNWϞ>㟽_vlqW5W-سR~[YyN8cۤ ~{Ccn_3M$ٲw NReNtk 8DG9Wk ]>h ?x}X(riߧlt=E&MxQRrʘq3>y;I @s t$eQlz=n[__^Τwb:ĉ~̬ƌnE;wWyEϜ66m{a>yg'yHF0h hC9G2rɵwƯ^ ï*6 KȪ/ίK:$QS__ 'Zeh~RrMކ|OnR|_QX߉`IXhYn2zW1!Nџ0)x_14zo}87nE<ܳW k%/:^ӗǭ1sְE,Y:f#GK_|uoc\OdSkg.i/AM.\=}$)+ΐ_/\$u^~BMωYÎS6>I5'g^,WK'R7 \:ēh/':,3щ]N\I0h\:5߉nx"=W'ܽw9k׭w<$fɲ_Q{|!3վԙfa#FlH~PA_t13Y/^s.Nk8e–YuzNtڐ&N/_:}>|䨱$Oc痎g̜}UZ܉~-q7?KaCN4;Z9GvWqBr :NDĥ+V ؞ccN4_Ɵx W74q] Vi~«i<ttݻ@:QzI&Zǎ;qP5Wn]'!ä֔WΘ9{X?)kyƌ4^ ޠg}:@8; XuVN4u~S\yE$K N49ўSTu 9^ 7I`άI3&=~1ٙqu}uz8C8Mi}|ӳW+Wݨ)n]'cjb܍[rNe.!=c3fW 8l|hL.˯+L-9G,ZS\4hal<*DaetLepœ i+У}QXLeWBmvl{E!{dri|+5)?=\A3%Mdq6'f Mfи:Nibn Nnb]݊Luwt2e0szmnrI4xZx48߉~C?M\ l2s^ޤ@Rڙ/_>|g.XgϘiq'O߲5}`e'={˗TӋ3uS~pzu N'L,$&N8\L9 虗s2Ǚxj8%p^3geǖ$^]º`{RU+:?%됟)QX:qG 򕗓PGE}Hzs)34%,Z9!j}>$i&dg2'Ym- o/ᷔ$GkvUd<~9 驵\ NtϴWi"҄-ݗ,K!$q&__yT}޵!$y.ouܹjpMˊ-Fd&PkϮ.`[rWά=$_.]wES`=g}C:AIq8j:ĉ&'zL:jXCxrl8NV|V9!qҢWG4A`5ds!gʊ 2X%^Jq\#2:t܉&g#)d8nBb*M 1c.EBZ[.hDu˾Hyxr6nav7SiWJ˝h̜>䔟uY'tZ@r6* 3xīOw=8Nqk6@C-qCo3G~"O1Ӽ3B'4GI?l܉&[YXcꐡvw)DGxs|35U;N4543]iģj뚄`\_v9:$BhUl j7љedʼnJjVBkUm͗~ k>55M2'Z:fSnf5[r_|uXN_)ؽWYǎscᑣ?OBjPg!Ö~\R~bdfsU~E̱W׮[?| : i=rX);$;G:h]{!PMDKoN˯/;lgM^x Й?&a(=| z@[Yh%5N u=8=7t"G[Ʋ.DAzXi*(] BXRJ`DwTF0V6:f4+ Xj5[r ?ؚٷ>6 )N/\-ؽ;w^8%jFUG]?]D̂м_I0c+PPu?-X.+Tp^9OaNMnr4/~CN雳Nlm4F k6D<}!?WǁǺ5fg?r4gҜWkEDF}/.5'4uf=-8c8ר%~8>')CsRh#GiܐCy8efWCj:.'JZW{C`F{N4;ELIfA+`)hi 8q‰4 ]H̯?7@! ˜=ĭklVi)PZj':$QUS…TFp~NfOډ֬A whWoޑ;={_ L)pL=߭+#Leh~<ZDpltqK-5h]I'ںYP'z h 8e06P#BjSy$&d`z8|du53aȉt$imʉ欞AO2lBSH3=)vB=uw,S{?J.yZD9M/ p1tnj'H*X;]I]i ЭCR|Y ) +s9d!*ySʬ!2Ք#2:"GD&[>,Σ=ʸeyfh"VBwtԩuZ b7s8n/: Y'Xt[\x*LaJwtؐߵiny'y(_tF?V te'X8e¢}(N4{&.%wNa9xK\tj}*h'(+y-y_a΅Ra:95DKu.̪L'Ϊ|.ј)uy)4:bw@EbeAX9>F}I\*Zh hDz!r2lt0eK>mNF`-P+ayХ|d8:/^:rsw7ꙣNtwPcRe 3_h?QД ZW6CR\Bn/GaΥ̘b[H!1S&!@WU+JySNR%a1,gYD;\NcN4a4$-L-ۜn9F2G[`f.ޏp!V[.Α㒈a74(1>s|Jo#Hj *Պ!-44m]|Gӵ]Љ^}o8#GK_|8]͉e|P?Y^A Gos5Reʄ.,?nX̃VիkFkuuV [ d^S {+3ۗ؃p{N4=e~̕|Njjd|:%~T{5;vU?rNt~+pi/8S0_aˀ-'pUODoQJnM::4i܉s{M:*_Lr+vD*8: $GpSE=QQ }}(o/)[$ZܯASS,'bތ%Ӝu_(t!S9#f}H+gI _`r9_S h#pm: XDgd,ٵ][9.1e׹ KDm}fIb2ЋtI9AA~CJi&"pVNqty ΊwZO?$.t,K X8{ NKF?(D>sJ-On}(E2O[e \$`ȉCS;DhE%Uh:ѽǺ/"Qg%7{O]Zz.þ3g=c/ʬnԉ&Z2lzSI#NҍAr?`#I`FهQ/l/pk'`X6K>ڃ=1CkM_ejB)s)N4 ۷LzI1UH.DllDxq@EI5D/ v(egz,CN|_YloFpU.a1Ϯs"݇ ucR Vkhk3N,*N|B@S:Mr9”qfwAe1Q'Z-qg$ΙuVLw<.x9N4` DCd-q呙G S}dNtɍb5N|$SS>̔;s}Ƥۮ-k{L'p!GYy >ĥ|AGv[*v,<}YW g-? }&oڈ-۷1lYpdMh>xE|D9| i!E b])ՎNt:s?0jF X8٣D^(*9 &ЖlAj- i-?ː9)P' π$5|;~:alB~@~Aayv,4_~"#"OL lh;Ѵ}J :sFyДI.a:&;h e'~ VhтM迴@tZ#ۦ˨ҖIA%ضWNt7SjApBũ"ZM'Wɼ̥i!M vL Cĉ(ʴa'*'p!GYɉpv۶d!W:7c(٪&/v)!Cu噊҃>4"\@yE%߳Ǝ[l-߷ 'ʠFlj&=/.^0>t9Ѥpj.\ԑy'p!GYщ %IkOB߉|8x. o-''?&uc`@ٶx's&'ڄ<:Gٶp6]ĉ>SiiCpkסϔ_*x<A-"o-"o0&'ZCe饂 ]]}x AD0mXT_( F j8@+zӿ|uJf7o VET}EZE`;MN,># ,UHN D/ G\Zhee+~F{ lIr8hh։(\-f`6t?h}X^BЇlh-CQMe&(hm hm hmK3hxe KLd" 3AǐG)>$APLzrw;W}gϞ555AuI)Ld: @NoӧO_xݻwAuaL dj 3ehbىUpǏ AE&25`Y4 bى>Y^~i, $IL d` M,;ѧy A3eh' jL Z":;0SFG1;$3V97ܩv"j #D+ZXPg)` 3;7a )y? ]Ptv` MZDլ<|\K&dlBƉ0b4P')@;ѕBHƓp;t#F)΄ ubف24 3%Og̍:Lm3aFCXtv` MD6ČAә0sN,:;0S&pAbƠLP')@8Ѡ 1cPbt&h̔ hІ1(1~:fn4ԉEgfN4hC? 37Ģ3eh'!f J΄ ubف24 3e?;Bdo]ze V ?PgJAٱ@n1OhZJ(Rzsw3džgWWExȦ߫޹%Z.5n4ԉEgfĮurvx1[޺hԬ>AL}EYqI(CR[ԝ<%w'ܺsJ_7xZqEƌAٱƜeu1p~FvnntåCݹt 7g wN5n4ԉEgfФU19vZ D+@ TNm#"K9-w 6xn:x˔r6קd/2mS6NAihZ4ZD_/[,'XɉVhK17* [% nRN0-qh̔I:u[Ë.W_j~IWca'ً'2Y F ʪ,U)US)'l:vVGt9f J㧡*&`ȵ} ;)ĉDR3'l]g剥ѻFCXtv` MvM4g: /J#Nhh'ENY "~:%.Ԙ Mh}܌u\8l t'S6;Vl|0IX ժe+H3Dܙf&fۚ ubف24i'ً';y61'Z;'3Jn,ׇ?s.tuWe\'}Xzm %n}tG 䋠Uo9*RjA`cr[6(θJ1D?;lf 挟Gg2U J:4ωhE9c鋊g 2'XD i8qP{z F80 (Jѿnkn4ԉEgfФD60Ę}^^ eNDxYj){%Ѥ%2HpM E='Z4PnKX2(~7ڼͯ6[ٌAi|(D60ZN~0KDӈ۫ey~NeΉnō:LtDhf1'Z?]b ѝK'xSh(gƉVU|ɲJɯTѺ Oj3ׄx&m*U JuJ,Xz%p5o['Z#Ne3ښN㺊c6f@C;jwUpZM3RK_57Ģ3ehҶNzBfUhU㇥ќ&,`}܌M~ޤ^@ b] P.d(E_uN4SVecX2(:qɵL[mDmhE3ZN4EX`2W_o"_"_vt-e )@6udE)s^ھq3D3[Kd˝DNSTwŴ.VpH#)R %Q UbΉ棑}Ć'=`'_Y"5^SL]*'4 Jrig'2sh̔IGYpN^$pywRw+yfb':W7 Jlx !8Z C~ډTӡbfBJ90ÎEgfФ=v,lmD%DTRjp6DKW)#—*b)Ų[Y*MIRUŢl%o26dj6f ʎ?›TK)4|\ N'%Y\Eўk6Zrщۖ$m͍:Lt!'ZksرzsOھm͍Axxju9+'mú}KJH,E ؼiӁ eH㶹[Ntó%k7>S,g5l' sM UcǏFtxܝAUay.g$mڹ[ak9 ϪH uVE;:1 9M_57Ģ3ehҕhnmr^/&,th̉&bmxQ=!N[:߬ NA˝T !ۂ}U51!D1Jat2n4ԉEgf`9? Peh~RrMtUQ^|hmNDr㍣0Ù6 cNtv+tqG+4; =+:;g>{)fKBf{rT׎i"f*3:-wn>CW $O⍆:L hr*GΑsuW&e ܓ4+;QX핃軹h8C~tv@)'h'Z!Ø#y;u\jYOez'MR{xvTh AuYف2:jX\'p38[$۶ ,!{-h]O9 ܑu)Z,m8SIMnKߋC~ݷx]8A6w5dP;̔ѡDNtsua%dg^+~;&aP^)1=˧06E;hu)㜙t+ Ad{Wþ_ u4k5ZWtv`:#fRAzmus!-8ib!gfn%:>AU~_SߌK4kaVe"]zDFTWXlI7- w\-]:$<^54E\ʌH_1G槥 in;vcq~mv|>"eWwtZ:ɓ)w7^(B ݰ6ɼ .*zIo ˣʫhˆ DYBosC[Ep,!ӥa#..s(+U%VpmLϑS~:ml)u=L hʗCdMW=q}kBz7uh=H3J3xY*Ws>ɞ5nؒh']C5)GG;)^;Oixy*q3kʛF8N.G0 14,2 (M-$s? M?snE:IO;7?ӊxrCDrOuwGh"l 9=]0ҽ?ڜ&XR%kNYzђm9ZΠ fs)ݢ4S 5gԐ/jrOI_h.>i]Ar*>woW]a'/uI][&c8UqeD+/@Y诂17VVw_,YGQX*557VLL*J3垙=!\.|TfY3dޝ|?q-&N]v0{8#.ԀJZbd| +~l5\GVSmf՝h;nO:B\OkJ -etx|XQ{C0߮%2>__41JOfXO}s^*ًJ/FFLCXHC)|C1?#16DhNmhJ2+c2_/t^wRr4fdBqseu32`8A6)R)TRR"c@tv`I263"MӏfRdnű)GbgcϴU٩ >!#|6L'g, :C܈D}Z5G …9Uxn~CstjndӇM+ [>rdiN4Bi9 Nm]48{YkzdK),!iqZUU\)8i8:d_HC]І$2_;9R+-,E>'tTv񵵞qǍԐhY89 7;s' A "Z2JjGQ/F²'=Yea }_[CEȍ575&2TO#rtxyܒfŷMBb _I*~Q{"Lm!\Z;Z^} VS"; XL1<|smf䖜G eDC٪sVC1eCف2ludSsn()|}gu "V*KFl!RϷiNCgP5G j䔅rxE$rMh]t@ 5L?Ea fi/]Te9biB7AԮS`mY!}VGӕˤEM4u7dΑ bng_?LJdEV ߲M7őj̰Ua ¯GEKf*a<螜#nptwPH/v5کwC4>4{_u5Ļpbh &l9kV$npvZsL~yb>ͦ2k-U=65 BU&׋&=fzN(>T,' Ȇ%ДV0oF7׆&3e ,z:uT}XrzO@)I?j~ :ma}`JL,5G ?>M']9J3W &]\W?.DW;4ʇNM%Yp.bd*i!g|X("KUȦZI׌Kv`𵅱zF -8"ke[MejWNN|!x/T}pZr0cEK@0cFljVqC}=AsMi=ENo"_OI~ !|_ds(y{a5_[}(o%Yz3 ȈypţmEm52--L]aVMeҤz疱,R%fh-&at2p!lZo/KJόn MDgfʰ1m -TS^T̅Q e9rgQ`rTy*'ZMU+Wm_@ &CW U w[mʆLh0/t+:ԗP#XBFHsK:J&'tuI3m)AM36:]6JQ cwA6JNzLO~h7'\MMh<2^JØzt/xduT(z~U=OdFHaxXzj_B~)z/F[Qc`襫 Q_]>yUt.D9e!ͣz=&Ch,z!뽾0&7LmXj/F .fʉNյKAz2APzkftlh":;0S ҝkkg{-3+HZ#zi F^6V 6G  O+cĭ/31aZQ -㷔$fO# {O&W[Ɛ3g< 7%]BGo5@3H[qD~K/PU'Wr9pUSp X 3NooQzˁƉKnF؆&3e$eF2HbhT)uA!Jv`k l|.cy:zݧLjWF.q&E~mHSda}L"sA=㩗K`ltd5džG AzMSXEsS$]~šЍXyM is I=5|1!t"X1t,1$MPĸ2:~9Fza$? !3i.bpG=o]LQMZ^|~TՊ1u^ӘCK3l3thMWCًs/D`S[O€ ȪRT6[cCف2lf㦱7F ud||DY2kmXb7OIW~<;UX']!1WzK7hW[6fo%=O#`셄R_;nOǍh3 Jۼ!j,NP"YJBhXQFګs>_ZSGi t[1`8#_ƞݷM[Lh;S59]3SH ghr'.eIk'.c@YO64h{DgfPBb*ܾCN\'jyD#Ѕ2 \dslrU#Qi[gqbfhA ?FKtzv)ܶ,_`L+Zb!ȵB{8=P#Mֱt3زtzu-m#u>-q[]r~3Q4.YqH;q}B`GEYf6-;^’R&1G_S&p{w'z+i_< pN7B7"qꛑD h iN#fh!V[(]RfL{(,F?`GnJZg$x+:G f+_~zeJi۹jMP8%1@ ͌͗Nm?ǦRkhB9>~%IjRXXyܚjFdE{F!)eq#8XBfU&qT7Y*/_\!L-m#uRŻ)FApXnk}_'sdOq]Ar 7$ CCpp-.n[ֻa'`' C/29טY7t.pph崮ެ'Fo:>VN4Av1_UsfJ\q˩{._i0N 68‚2F6(cA Ń(^iLeWoQ;.faT^];djOu[w9}$!?}KT"s SncTF#\{@0oPDNIͰQqnwvE#\{@/ 10o$ѐ Ur?ߙ=~#ܑDSJ.e̼ F i 7+|[鲧]3X`ADcH)j%~w2`z/4`ݔƉ9a, huoyfo[QD;j$ј;hZɥ ,}JK.:~%MI4P[$ј;hZɥ ,'Ν>cnԥ@DE#\{>?qm]'߽/9Xm^nMnֿj]H%w%h?+Sr\V3~/<ݟeK~=K~x+[$Vrw- nMu\Jmtw:w?1X$zǿ_~ߨ*J9twD3?gY7׿U$;Zϻ?7v]$Z/k{s-"\{q=;+$ѿٻ.Y6D_=NЏ~/_O c$h;=9 /=gf AϿrF>g$Vrw- DҡQDDUHi{tDKFItc,D{ھ=Ӽ?'S.u_-$K;xoQ5'ڎ B$G gp$WF}ѷlȻEoݣzD m':_{bR_̜97qߥO>.rB$Sߎͩ$_ʤS$K;xoQ:+C epS?{;8'?{d3?གྷJݣ>d{/~ɟٓ;&?IO?<#όj։jX}]I/>ِx[n%7]Vx֙KIM;6KFeߧKyIt]1 h.XO~Uv$K;xoQ~OtQEhqq̼=GgV~}_ gENIaݪMٓL#?ο;/9tw-?2(TJohu?uI)j%~w2<Ip-;lye3O=jokj68ю}u|ô͛ꬠ̳rN=֚/(IxP[Ɔ]]R~go7^ؘBID/;D˭i_tL%hZɥ;,H׽x8'VIos.+<#ߓ,ҤrBίEPb͍BIt\NWHN$z׺r>ܾ}d4]~ՃO6B& 4[NHsko*$Z۱I4EOٯ?:ԧ"ݟ%dW򫟝xs/DSJ.eaAןYoc\nW?ֺ Ԕs31+,m'wP$GVeΪ֯v@cj+/~Ao?#m{>b_O^#}: @y \{˸pV r:ymgWL_2u:wX_6ʙ1KKhQGJ# S%<h%J:z릴bg+-Sh} ՖՐȿ] cmNl$D_WgW+%xU!^~_ E[nk?ry ;Ic3uڪpd;،* ?w\Qfy_]M}i^vooжC9;~I?1/?;} wnW#{v~љC{}l}wv=G>p*JЭ5{눜%_)P=ѥ ~&f ^'H#oZ3y[%H 3 (Za;, gS.yyՓ/zy[CLXY8 8tcJ S^=_uIl :O=[w!g;TȔW; sJ˯Πvz|N=۲[UK"D뉼U,Pvh=c;ydߕĮG7H#Xĩ'\{˸"d૖|;/kSw?o3bi=Ć{v'_nݻY;p}9IEcԸZnYϖ}ǼB󻏈nIC[u|h_;eu;Y^~I>;[7/`CB'ίqn_b6ˊ]J,'Vy%EQԊ-eayI}퇒DχM/kZ"s<ܚ?c>ظme {ie_llvM2%%z g\'yx_ [_}V_?7vuU̔S}yݑ۶=}nɃj^Ywv8ZK6Q}]ɗe+oK>)\^׽ȁ̱/L-h%9rxv_/: vwW x8.A-l0xWGbk$H)9~w2H8gjUj23 onVqD3À1#9ɠ_^2JjbgjpTt#(Xs<1;09 N3c$:,+m|&'٦s.I~ڽ5G!8uB[$:0YYgng}7=n)moڰm/D (T{˸"I3Nֽn}`U7طIk^9"[h5O.DK_;%@͟;;ŶhA7^^衍 ^]r^j:_w-d-6)pOhg?۴G5UomcdItIDSEQs+ea$z1c}XE]$I4EQ5[V$ZM\fƌ#7I4h(jN;L']/5 eDN=^kx$|!Vp565}h`9!,1:==LL|+xhZINyΞcP%D,$Zش%DK+yOV2hRuM8g :Wޛ-T l5s~L}ĭ3}OObrSO 7(Ob4y豫fwƮu~4>vuR_=\jg#KGg |gO]Ļn01pB&ЉWu =Cf74A EfFnKRX[tɍtN$zmIWuGM^U6;jsL}t̔۱Nl.0.~B͟(pJu@ʄ@$0kI,~.$ѥқל!ZrlھޑaɐTT,`M=JnjI^[уI0nK2hϰ O=ȌBl5=f HPfdMؿ;0`H]a.%}It'鉆 'ό L&N:|.@$%IOwf4ʨ ,t+u4f.xKj3*cU Wf^Wi:^YnM;:Ȭ\9>8cf3 G>EHI氿QGO<2 TEFT >kK'v[ 4ӥ/9ItD̾R;QUM;o_f.Ͱ%iFޒraLӤ&՗杪\:Ja8vzIG'Ѷ[S7F_(5{[?5HUy)# к7|uky:őDj$P[$"I4HE -h@mDj$P[$"I4HE -h@mDj$P[$"I4HE -h@mDj$P[$"I4HE -h@mDj$pRܽqe$p>XHE -h@mDj$P[$"I4HE -h@mDj$P[$"I4HE -h@mDj$P[$"I4HE -h@mDj$P[$"I4HE -h`l=~_鉙n9G/4|[< KI4`9`cįॾv{-֮k LJZ޾L͞j~Ĩ+uzT4xhN61xvzl~oҰ/Ԫ&NYh>hrqYA)ct'oڞ>kAܱ5vJM}kJ7ijLSg7y+/i$sw7'ky[.=~ =?jAH]{k.^Pם<%^͆?娎fs/I4KI4`[mm~ȱt~ -p?,6sn¯Պ$MO4 <|g)[s# 6qsl=70fneG&nO [IZ'ψ1QT{ٙ - $<Ф z$k|rBƧ.ʛdk{;""͔7UfG\z+yb|)Yj=>!`!,#fr5ZD jDͳz才Cֶ!㮦so/)Bfu&o!`!,:)39Π=i$wpP-΍`:n37mi}kL-$t[j|tãNsN^=ȷ~>ܓ5k &'&mp]3]^ytf^3"˝M9KCN~jbnN69]w E:[[/ 툽uF>zG=1 fO`rC7Q?P1`{V-æ-ƼޖC=9vkEBy.O꾾=åXRҞ?G? quabXGãk]=׈j~ .ؼt>+}"ϵ2? G:vqӽN˖;sXWuoxtw\޲=7W eGxgãˬQ f?F|Ms ZmtWH8].BU"omͣ|xV-t׽CNLN}xӞ2'/զ@Y$eBM)~OtQΠ-O2o>귿l0u=/aQ۹~{5>7;]X3v ݤCi!6+$~Rw/VJNi9E$i9NMK/432'|TOzkrpjis5uI;iLt?h>˃6YP7C3"/Wя:&x:wx%G][&zS{i8Ɍ&?>p\F!.`1~gav7pY]>AXZ ANjv<({̰yNedIvt^[sҽT#\vSv+*˛9Ity Ns=p%~R ٓcՔXۄ=A `u\oZy/n:'7/~T/UW}5/NFx笉 gĺH0ehZ8{%9f\vi(7ݓvȭ{;mMw95mљfmH8?[l@鼭rk}벎j\sriN/ef>gߨ٤)E3ӹ]e'~\G;݋ɦesu'vº<]$,+D65zɽE1иK:˟8=lĕ96ӝu]2Agzřxf5څK#gHr-6L׷OugM7;4l$]&g0& _ztoVklP}51;5&%͟ĉK[쪯e6tO4I5ecq͘yK0_ċcS3to?/B](&dVzXv͜r9qswo^5=Fw !,+_O_3MD~΋PC+5Mb=T4y݂z{t|pz" Qkj'8t7J&u\v+]֏$#Kdu1XmUO&bIh;p$L&MO{sYtc%):̆i9Ӹޑa+GmzLNv+ FڇaYz *=&iVw&b.gA`2_=eMuƬ]n=]B&/'sWݤ̛~}OdPLfhi^9^iF\+b&K'/'P W;3qǹU_eZ^P"ʽIeܟ(|z,'עnl5,hx=Ǔ=}V|E [j8!]I3󦽦u= yUI{w-lJ2T:pEnRL5[ܑwR8[;=G\J 'p7wPj`Fs;#Luf5c{sMw e&6՛2, kt7Z7fr²0 ac߱$"[zv.gA3 c)CO4a7m ?Otp I9Wݻy'e\D)~E*zߐsB2ZkG9K*$# B.B]H5mVxXu/xуTKɄg 'pI4`j\s55W55*PZk_/9H JՂV@B48c5#X{o)j0u~+i 7Gg,#dsKoW+@&oNJ/^m}#t_##oy8`$U.==$\~omf^UJ~z,gozbv8c7'DjkQ3(_Կ5 HY0bgIMH:?@6˭G5P`Dk Ψһ]޸ǒޚqG^"J@Eå3+%ّNӄ-̗_ݞ}}eɜYt[˯)үoR6|a\%', -\3lTtړVwa膍^wd-s!臬d9D?7H*t%w"C2DzM@ x)gz^359Xc>>WC*",kzB_Gˆア,z`D k#_>L)z81:X+yz6fg'AuzϪom7;5/ۡx|X So?F7ƾ5΢/w%_g|M{U1U Ok}9a\#ցi o/'}ܪ&=!ruC8Mp&N?:) !o,>#7~K^_fcTkrFy<T} u+"UPi(MsV4xFϔڠԉ HCؕ-əxk Jt1c oߐu~]׿'wH=;$#ّV' S N8DoKqO|?n|t^vmn@d?I GHW5my13HsXGA9MvG2k3Y:.FbIDN.):mjpb5t׼wJFHC-鈊ѱz9;a3i鱫}ٰA5O{^O 6 l͊`ƙ8;[+ g΄[[/ uc(k8ٸ机6wƋI25=q);- 鞹9)^d2q򸂯S]n21"1x$U/}Q%Լ_0<#rF/\᫮vX,Xm:_*Z5E[ >>!NZ"",:ew%_?q/d}nSO&ߴ-7YxurLld GآܯVGKÃWLV\<"ٴjhux<W 1=bkW6>SǯȉGOFny55|UNl*IC:9hü=5j?>d2koMe׏_0s0hlw"' NCnOOo-NodI7N.wJkk)m][(v (pw&Α2B?x#5=ό 's,T8 qyQxtR}b[WW*4׈s 6aEjɞ3IQAmJך{Us˔O 'v"S,n߀ &Ez!ox S3p9s0R*{ⅺQ|YeeCQ$Zpfd`BM!UkQ]O\`1D.1S C]BSKn0S5cʉ{7[u]l$;lA~+*"蹓:ۼ>%o,;́t7F qm}ǒCeljy N$ έAur4iĐ [x;IeGO>4OͣǒKy|ºsP'8'O$B]8RdtsgޚԌv\}9/Mmmm=1 ݤzXomjꉖ!?K}&\,]G:&f'O8N02;=\hڸν ;6}߲gBhuE9$ 9SpK8r tJA^8*\B(y 72oY】rWB](֦O}LeG[SY_E'a^ʫ ,wh޾K= /X75=qbDN,{k0 $FݛrV=Q~+lRwvO?M, $,=+ԗP \:uJ=`=,h`:5zuxP}K I4KO N \LG7.FHedH~KĭҚ= K I4HE -h@mDj$P[$"I4HE -h@mDj$\A7zz?Vȶ3W}ޣVhr讗mixy Yzlk$XH˅Nl6>*I4ґDLvכwh$e#HF7>O<ҾFvU=ogW}q뽽/kɺW<]_r&=rg7~^WKxI/(ojkPhϞuP^䈂- O?׸=W=t٣v-ʾ&o3_7L;z^;м <-كoj' e{;ml!췽_yl}h~e弲GI4h$^qY~[$~Hsko"&HEDg[*jN/~ubQ)fX3cW%jGYxϣO 졶I2-fU_\4#զWz{_r%*/|]G^o}kž~qO{Zy:L[{6o1]'s{u Z~ImT]sl\t:if#ꓮ3k{֫fyv7,G}8qݘ=,<դ[<6/Te@$I4`و'Xps^-5/fRmN?Ӡ9Q]%я5$Vy_M*H=X)Vw\h6rҼ0}YOx̺[k%Rϋf̻3n*헬1Ey_s)$D0cAު̵gm/H3rR9Xw_N݌sյԗemk?޾c[sܧ{foy9=~KgW)8gVwg}d# oYЭ5{눜%_)P=ѥ3~בDhr_)Լɗ{Nͭ!Pk&qae3 Ϙ Nc,Ta{ K<9IyA牾g}7āzg yjGaNItl-޳-]$2O[Ų ow 3 'ZOmM]I4y#,pds2UewuO}],-3cF,-]_p$M{W77}/'6hW:ٲOVȔ~~¡M_6ty}KrNkH֨[_ݡ۝H9ܺI}:q~}s?<,{߷YI4y#,yI}퇒DχM/Z"s<ܚ?c>ظme {ie_llvM2%%z g\'yx_ [_}7Sx%׵V1SŃG^o}%yg)k-FIt'_9MX/Irz_#3Ǿ0I(Q< w3$tٶ^%ExA `HE$35*5778O~ɚ̘md//WUY_GmW5B8st*QvHsk9AlxY1U6>dNlSA>$zT?ޚ#ߐK:!hVpf<?<;"o'ݭ#آ֒D$\DhsgS{Qڻ$n2xp+yz 3f8k]m/l[}">ԹљBݲW"I߻5}o|sD<=тkX}9\R9_9$w$Jvm?Ewvm/=т o.CvuWu0~[$Z-lRhruϾij(9RI4D X.r'3f#"D ,JefX(_j#IѼqS5tȰ5o?zCo?M7]f?׺HRGőd{8nz6L OgОZGzym:sȞȹ؝D7myjbt6U g-ͪ6ސPYʠ=+$Vuo _2V Cָ#xspO Ц'd' sjsuZ0D^9{Y&$S2 K.g<)jbAя:ٙM}guvfX&J;'7=bL0t"UBϐͷM998#7;xCds=k#ֿ<.ָ|0]r#݅S1^[RbiGUQSWոM2z~\/%D>3v-LP' 3n|v-Lے̤,3"S%OYtJv㶰u1S=zv߿ZG3;548.s[Y20m]>.;6Lb&5i.׼Vqkgg?|zӖ7TftR6;9W6lMש_:.WS%s 훮|?SDWsBrA13ydNhbh I4` zt۟u|3Dhi}vW=G[z@J^7Otf\gwJNfIi\jB7g9e؟6L˦NJWi_'ɦ7u\<$:9 u>^Fgm%=Ɍ7Ov)$ڿpjJ/ 5J;|ޣ.@$NggOlȟ|6HuOԳnبU?Q2ez2Vnd4Kn.o:W:Zν#gM& 2Mw2HJId钔?Ot9Mw>6 Cm6aFJwN#=w]ՏsLׯz_&՟Ц'{:.<>32|30::ێoA G XI~ofL ²,O~|PGc&Rt6ӭ2VՀk}eqUV^ٴʕ3ff[?Ӽ`~_$|dud$LO#.AXdD*0ﳶth*?M9]J^>՝OYsԓ I4`i2SH?71D_3Ow} ̔Ko˛|GQ:8gM(D?rI襣Kfa .CDԄS7'}r_^il]$:ړ3je ΌZ}֖L,s:3r)+.vB{fGzvܛ:U!,Uj ZO}<7C- 9M+i"oyS$2x|X]Ga"T]n6^Rg3u];炰hŏvX 2Xt)M "2]>kK$nsdq5.9&UP=?T$d|*O|9"TkhQ{}g _wtA׭% %A'|pI%: 4tznn9kZ}IDtדI')`B&֊^Dݏ)=D:?k-B$iGU;d| lfbR::W~=T$t;pO_{|uNل 69?QZS2Dˢ(uk|f~}fW>3f2BIVf5m>#l#In'5t9 $YLۓےFu<nO~\Z *g:l;RYRص:[޸S2jɽY3<z>uϚAzyD譛6 s\}Icn'?*eLZIs!Kε6{fΏŞGƧ݈@Pсgqy]F6̞[NW(oU C!G}v=xEǵcOZ=?:ݚ1rB8hwAKiIPֽ}LC#^K]\s($P[$"I4HE -h@mDj$P[$"I4HE {!>#~GQEQEQEQ_nޯI4EQEQEQ0w[_>a4DSEQEQEQ VؓL<$EQEQEQB֙rODSEQEQEQ Y}o> V8h(((jC/`#(((H$(((Z"h(((j$xH)(קGů>ҁgudywf~kJ2qi-G句3.exDO$N}\~J-}}#}?Ϊrӹ]⓺:qC3|^:$)g}-7t[U;F<Σsţjrw" `5dKFfݯ)pM-LQx_^sڟ3o>^shAEO cbO»:%f#xMjvI X"Ww9e{&᎖XCNx}9]mV F~V)tENhғbǥW5CpyTr/?Ku'K H.vibnIyo Y{=\5ϑ_/SKC^J\w9InK泲Tg}\?Vl,})Վ=ީgty(~P:-uonSUP&U'T$9e>CZ D{XͳSZYrd(yJo)Wkꂵ_zj|bfZijku슴J3ܝWS#䳒6*d"m🫟uy/J=Cq_k}y#[yonGZдwOlJ@Dܬ$x-׸Gyt<@{⠲  s>(F$*U`!U'T0=iuߚD냻~zvhf'yp#rz/jrvֵOC%cµ_Ux:슜\ɆEvCP9MJR*uj:H6FN(F ;]-+$}9#3ܚD;_j˶٫2PjCg6r%לۦ^=pKM */A޵JXe6 %tAΔ*jAA/V_>)@ h๻h dz0oG>)Cq|:s㓺,qú<@]n0늬W}BvP[Tm{C=l}YLҟJMQ%4}\A{ ȜJگ+94gX)KIe=V]ER_nO-:8rWTɡO~imܬ9U*k#?&ɇ ǪZ8{-wvBrv\^~ r6hVY-*e+]M\ʆz(۬ѽ 1e%+ThGךCdUyaɕuk5ݩY>Sr{hbḱuңvFJ>ѻ<A1Tϵ`%: ul)hQDO!G3lrG6e>+Xӵ3sX&ٲaN,/w]SߌBU c/!vM9{/]nTkyd{}{PރUޱ5+k$GarYu ;+됓 G$1g$x3<}*'w>Kr>ͨO0ӕ}\ԇ*En?mI) l>[Gͪ >/S wǼOcN {R%{˪j_VMegY,s^~?~9GdҤynVl^i6#uX?#}: ݈(g;y*WvFZG"k_,kU4g**WIE ^> ?Gj?*e}~-1Q-ԟ˶*xT>r^bÖ8'E~QQ?F;NדUK{N$ Ǫ]ecoMץE* n`tNqXTAoˊ.,PI6'Gd/l2=7*(k8*{8UtwE^|[>rf~i"Ns{qzۮdu[z{w6Ra֬.Te`Oc4?m.~w U.NBZ'T4B8&\Ь1Hzm.f+ 7cyYP[{,v;b{ONWrwJR.T:A?ZlRMJ0Nv{L=T*4/biʰOm:{e72|>* )N`~Mw] _=:۴wCYņwVUypH'LEeX'|g"EGURKlS5Cn-ێ8!,(ǕVvDUGF)+Dg}~ /_I̚!Z߈hq{}y]"YϚ\Ձe7T:"*Tsۚ|q&-YGKYzJZmjmZ w3h1'^*u!*wtBtu[?s/ =wOQZ1Q3$U 5c1*7 ޑٴgѢ^eK\)8O+IresS-76;jeׂ_ лEGa FNV#.NpW埈W3n >,w*7샭}eWK.sW,Q{t :3e;@TãP,%\"iiJ׻>!G0{JW ~MK=XI).g}5U·BgѴGlS&[sXlP|-76FU0~\YE?Vq %O{v-I^ :;U҇;Hߗ-*_qUA\nYldlE@E~YXdSʖs-ls*<ݹ%ΝYKa*Y[aHّ]Pi[C-ˎ-]'GI}fQŲw-?fۉu~++!|s+o vŷ_IqڟZRc2W鱋d]MeN?S1_ +[%7k@k%/5WuImL>\w ;P-IPn, $gUaH޸7띎?YQfg,*T/?x>VP};f@dP+[{/]'r>JgY߉_XMe]*4P]6G%7heotJoko2N3)Kuww'IE׊.,SVlR j/xM%|9!8lY3V=}vJn$zաFzr dNiެjLreN:e(JZdj'c*/5t7k곯<%Ӥrr[_M7Eگo;}6>QOwJo0RGD 8T?価 ."9w+Ҧ fkIQa3BUVvihv8 !؍ε?GgDt({#UWOrӫ{\ vT{Ǜ~z'Vh^FғT,8<*֔BtR-r %wꍖgJjsPםl>䜣(4U۴ώ}\ɪtem9䥸odθ:I4Dh1H|Ѭ2g>oM3\9\>OCȧ#Zȧ[S곚mpn^ {:}T ܋ٰnrsMbv-Wvt6xn,șu-V}]dT ۅuBK&({{ZydN9h/3-}܂I`fqb?j~A(B8+Eۉ'˝)Qv#8@厢8LW[AYD.7btB'z ).|n"TjaI$(2}W۹VIQ%CZ$% #' ggplot(aes(x = period, y = value, color = series_name)) + #' geom_line(size = 1.2) + #' geom_point(size = 2) + #' dbnomics() #' } #' @author Sebastien Galais #' @export dbnomics <- function(color_palette = "Set1", ...) { # Check if ggplot2 is installed. ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) if (inherits(ggplot2_ok, "try-error")) { stop( "Please run install.packages('ggplot2') to use dbnomics().", call. = FALSE ) } # DBnomics vignette theme result <- list( ggplot2::scale_x_date(expand = c(0, 0)), ggplot2::scale_y_continuous( labels = function(x) { format(x, big.mark = " ") } ), ggplot2::xlab(""), ggplot2::ylab(""), ggplot2::theme_bw(), ggplot2::theme( legend.position = "bottom", legend.direction = "vertical", legend.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.key = ggplot2::element_blank(), panel.background = ggplot2::element_rect( fill = "transparent", colour = NA ), plot.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.title = ggplot2::element_blank() ), ggplot2::theme(...), ggplot2::annotate( geom = "text", label = "DBnomics ", x = structure(Inf, class = "Date"), y = -Inf, hjust = 1.1, vjust = -0.4, col = "grey", fontface = "italic" ) ) if (!is.null(color_palette)) { check_argument(color_palette, "character") result <- c( result, list(ggplot2::scale_color_brewer(palette = color_palette)) ) } result } rdbnomics/R/sysdata.rda0000644000176200001440000004330613574262552014614 0ustar liggesusersBZh91AY&SYMQ]x{x,t<k\;0Ω ZVO7wv6RT;ldx@6 g˨}:l;vzv;`owà HP64 cIխ҅*Qh$@ jڂt]ws46P&#S& )SИ1112zi&L&&C& Ѥ4&MMM AԚM!DzG4=F4 Mhh 444JhPH ?j2 !ID(4?OU4y O 0ɴChbzFFF@ Fb10$`3SM400MU"M (٢M GSQifzOHd'h̦$='426bG<zFF JQ 4&&A2iM2F@b0jL2fMhOi1jzL$~i<ީꞧ<5ODO҆M)zM77Hg3-/[L!4 ,"3 0 ppF0'10"$\2 30 J\̰rK0 ȣ'?tcyb=@jfCFp^?ѝ#FЫC{`z!t #ƄI AehǍAs#F#^Ơ֝fwXҧR+yv=q:dy&FtA_#HFLA#(Fp[$5F{ѾPj #Srg;QL6>2wo?*Q} -]QIi$n{ .7]f:u6;u|G9MR s 'Wx04Bi*!jkncv i;OPZh[ 6egĘ8Bӎ?H8~!O&aʅolѩi"mƈT^rHcI''!$PB2p~asH{2Oqz*nvzŨٟ CHǑp|ZPE@4! 3XƯ84Ϙ ) hkHJA}٦+U5b/m4"UnAd `3>=!|G 9#6hADtGAA`l՞99?*]U}ɷ \dnf>D.ݕ67[WWNw۫Ew}7e5nSґ_E%77+/eRD+9 RŪ}56gt hc9:^=Q"4)Z.kjڕWlj̒|!/x+j̠ߗ3zt\|%"q^7 UhZZE&Вq ^؆n eY`;8u{0U3UZ+=*%=HقI"ËD^c_Pu@Y⵰F3s1ϟ.9;0 3jt!yPfphȑkfscueK\^y[mp*![b1E`aBbyn=L]GW$bUsDRҊvj>J:=͡gxpC8 MzB(<( 8oq_`ksh.Sm,EoC}bX!2Ku3TgZ%N$w:[sg2Nl׭zd9g"w٧T. Uw4Лtүdrn4jwR7tMN!sB.C;Wuas dsZ F,5ZZj4m-6MMjm2b6gs#Kj™᭪2kgisB[تfxtg"ސCjCFƆ Jv~]v绔ԧ\B~z.U. þS>SvTmkhqCaaif!!Aaif!!"!B' 8"!B,8!0 0 ,8!!Eq!EBaabBaabBaVB7vz7O*U3RK7|z cz&pZ}u*;*} %NfHiSIEvH蓾wchNtm)]p$8_s1Hmml͝8FaW瞥;N& bH崞:9z TRw#xIMJ;XUaW9Jy^Iad^V%M1G8FaW⃷ؒuE6dIHrSPh52U<(?{ xyJJd=Ҕv+|`z<wrII$ H0 '{ QAߌ|^`;Ru{ݯ:RFËFDߏ̯|l+/q}F*&?ӵ<>p]61cY˙yI2KTo[k5'Un4svnBNY峙z&].h%'#65m@{?Քm;~J~5!${q<99$oھO]UrQǩ>1Zu;Rp)hӍG XF1(0C-K(׳5`.T\` %+\eվ6FcKQCPB-1=/\7o;BS՚cݝP3c6k2m l٨ g#d^ jh`֛hhڨ3/,7[RF^RvͶ[fv2U1 Ak1!mkOτ̒4ښn[JO70Lcx' q)ƖM6a )7{[Dؖvɳ)JeE 362m5chُb!r-Lc̔j ڼr?}yX&>~dvh56?558 7qe>3M?lH~! I~bINy0-9T[ &BI4C!騣e}}=>eI .ME$ j0fԚ U`]i0fzSr}cibƫn1oI*0(eYesdF@nh'Ō`"${ad6j6p\ܶ ;4չ-}2gFlȢJ9xgҖe-ht0Ѐqq+[ʬ1Sf9N~͜{>4bWR%t5\à4ŷb&sDLZb+P0w4汆 F:vcv+LnNt M:])8fV#-[H晆xmlD֧~3imFPĢ!zi51`flE;P0,mc*Ħ:`Ūf4] tƎjDZR}nj6yc1?R`[QJg2p)*FD6Qxgcl~ Sݓn5u*b\!A,N[V)8((x7MDAAADAAAfef}uu+lG|ٶZI$;4a((f`^{mP7yՋM z[i{=w $O͵3V~rfGN6JSy0sI78,bfnG"ʝ]1i& Շ 4{Q*85b 9f:{MfK #q ; PA1yIf2xWTeR4)Jgنty@ir7M]fodLH ªؖv4-(\{c5'5!+7Y^^E#+@$%WToCS-#rx<; C[x;y7 HL%_y@loj3E_M'_Ώð36ps6?Ro([8^;Vs6qv  ہAn``AAFaa-cS#CH# 20#X٩a420fFda0r)~2KKl:uh,a[H%;ұOWSU7h,ԛ]0$$$$$$$$$$$IDADAAADAAAr3:+?m\I*(QEQGi<5'zQbKu=7ro^cu. -`0d1, K%ZbX K@h`1`1`5&1XEmpc#+f'K4=ѿ wjjA:rEbFvTt9:Ǟه3BVHoemRNZ||%ߏmʌ gF,Qjԅp+˲ktozehE]:K\W;\fs_EAg.|G+]soiBK[ [YO/֕Hff]SSln/fȸlNzNFr)i!!!!!!!!&71WvFKJ5 atJI$ ((=YPNImἙiFO['?}hfndBwl]"Aم팱% s>%5Yan|~Xc{>dNѧceOQu9e0a~Th?rߠ7˷7|+k}[\k|k'Eս_Kp8.jtsRݿ~%1Œyʕ0Fe̔tk}pyA:_!59|k|׭1WD(%p3zdNkN)An:\^QSO3$$$$$$$$$+e:zyKcktۧ7NIYf((۟s#So}D6xH Q .=Mx׏~iDe1k/ϫ$9'%{B[sǛAWuܳ|+Kn[Zp ]֯Sl8bBѕ hUUbK"1qw=ڊش*i5:H\~ԞOqVX<:ЍoЏCMެDzkuyVLo6p-A)E}p7+0l I%&4QEQEzǰ32c;z`߰Ͳd𦃨s>nc\D#ݒUM: 5P7oΡܹ~-DO{}sËM{Fkzyv 5WeHs\ȧZS#A+ֶ&>.wࣈ$Œp|jc ;>xrމNzOpsm*+L N֎mKkJG8oQ U;NlF"-̊ 'DTo I$ 0((u'3D7<ywxj)s7S 7 =a=/O-:p*~%օ,_wQ0*+؍Ȫ{E8PuF_QZ 0Nl֘[d<2SW^lN;O\˒R±]jw/o?8rа u4GH0yha5tȳ33w}YV3  &[Xq$NYQEQG/Ki`GJlٴ `V`cLx <ŗw6onNst>odьNSnlk>T 4NE~f1NO9Svr9ˆ);&@YA%VrF9in#q[7ɢrwl*TƗ)B~U_kqf{LSr]| 4v N6;oKHXfg[ۯk+.6rt6E:reѢr.iHe]\ wqZӻl((go.L|GM,dxOf%oY /c '6*hmj2P7:] LSL|9RNV{M}|m nvj+}sQ)i]du"ڛNՑk7=E`VGDF}dC6 ]&qN<@$pNzPx ًnq|vm}tDK!ߟL4:B:4mK(P6?-F5踫۾iS|C1Z@3Noa=3!B5wq-0J(( 0 4Dzf1qp5,Þ~ >KQ̰Wbmpr'^>Q(uych=(>]:6sx_lϑ )SW3Y;TE;cj2"wF~fu7jdE/|px6s^Wwj3x^ L_Ot-99sSϓGi b%>?T覯[Í=1$8FN(Y,Y>]'y<ӄxes-|[t@MjNy֯NORx OOv'U ]Kmlz]s|'"kNuI~?gK<4 S C4~ 50 6aap[MV{c4(sbv bVe 귻6 GWͺB?wF4:ܲ1l[xw9 ` X $ٜ) c뎦?[ :C4rvXB}{ndo=f1͔v?#UK1@7ca! HKQ21T}2ACn@L&p`֜b&*Bb!ii"  &M d`(`?\6 bb F &"&&"b F&"&" V bbf"b&%&ab&"%V!&Q)%Nc d10DD"L-K@Op2"Z(LC^ڮ?%}S"^=/hBlS5~so21QbBwI[t#kz%boV^b]/QG9g(|#TOm~W8f12Sؾ{*"/WjzA L>i`*hD4^ʮ ^nVww\YڋyzGb_/ ^*aWU4"'Ik|^80=1 &8k =Uڔ%eAĹSS9=w?8f%;HEQGtw MN=t)9CCY?2S!Lv,/qVu71YcwyfmgG+AdwgN䃜ү,(GVJ*e*+O>=_՛XJJp$*XIn/CKEp"ʯCztOS".EU|^S)FtINҨbx}ѻ1%l+w.ɡZHPԓ%)%R7}bIt yTs z5jP|Be63*,tfMLIC#D=J?E}".ɼDxBoۺJW1Ur<Ѭxs(e=PrdlBHJ! ~JIЦ9yLn\C%HXsP*0 4HgL4=_犮҈ߔ9TQo7"t`N\pI.$ow`}F@vJSLC݄Wӵy«0A]6^J7Û\*Oì*_=ѦeT 4EJ/ܪOQzqUCP_ȞmCEҜ•zyjFj$0` :eVj"SD&u- .!|kxe[%KıJVBtعKu/Kz%_>^%"_ŸO3^aӷĒ@=",`SHh0 L&%=Wwͤu<*\aU⊭!y##‰iR6C r)4!/9O'Ͻi*r%6*TڤyGEI}ԜaC ̐aRU~5MʸM$&}N7AGjpx8J/VċZh%lTJՅr;'"cĩ[VEѵCc.}YgYV޶٪ Zjyo"_DstQ[݄C 6~lD1$Yl`nմg>''r=GU=^Tk_ݓV֦O[ >TIiPyB^ky G`Z',TϼBnrc$=KEFW}'{B׫HW_SXn%o"}[؁$;E^Q+m^wF!!7ʵ5Z4nı6*&&Wm?o&[+cb}^7.-注L` Lj+F 0jh2IR:Z*)O+M!}Tv2IjRvҏM̘a CH*~UcUvX%Mn27)0C&[e^}`)7MDzJ(kh6*Pd9R 5T`U`A8Lr J]<@Hbٕ6e\*%UK0*IuA'%ʷȗAE(ܡ\AUV^r)8_j"w+>sEĂ]1JM^Z5\{B5}/wkZʋ*.r "SS0 a$pST>UlC%1'~,/6z#CU=)S C}4>S"}=iNVcZiU5U0Ra)Mc4.fŤ5j%'%]ӵWY)E SV*[QˠTܽÐRAYT~7.G_[;AT.UJ R7hdyoVx S`mUb,< V*\H+(JbRUb 딪=]_i'}SלeY@UaNJu I]mPG9i;BVU ':CbW4ʵ6ĈZ][o*鏴!~_s`C-I,*PTn0Þ[W UcB>W~lL4&ѕȀkhR @$8%Uc|9{&I1%0<0UhUU\\xz=Ua%}a;_z}>g,L/7Qޔ$}vL^?)Nr6*C޸'TEW*!9 1ҋITmsR d!\i&!*mlTl)Up)2T9Z `:v^|fwcmΆ1J)ZiS@eRFԨ4՝tA5 \qN#hR`&bhQGح}1듪sCڥZbZ*r_B* &1"C\h-M' +^g+SJÁPю*-!DJ#B(`Ul O!jI0' *N$~DJʵRjGe"\RUUr MnTC`9StաV( $ To M)SCU`Ѱc P(m@vhbR 8\ Hh &4j2{Y|1*vt]P$%G~9qI{^T9;I0G{3:] qH"Њkѷg0e}; B+jBK) A?@ A@*xCWģ4g>zKf_߭&s=5VVZRg//|rIah7:/K-pWk-0 gnmۿ̊,R g?Xڿ+<ӴsDN]Ea?C x44B8\q21N -Di dy1EHϔ EWYp¶[玳QUÙ^k1q?ݠ1Hυ'UOBHkiIduTbdQG64/n뷨m! 44$Rѱ*?a|Yo#Rpt@Ch.=˷BF$(T"xe"Kms z+hPo亾pm6V7v{sS1BHRT$nE#ZS)-_aDH}sٳ&߱X9jpB4}TY)"@L6-qp3T",ljXHLI=4R?aT^*t*uwE VtzZe!0yTuQTav7Wc2>cj{U,!6yf#3ZPf<{/`jkn/?vZiVp1eխ[^C! 1SRۅrUn')H2@0[?U_ZAy)-1@G?[Cp<:Q}\++)7oR^3A )@?}z^.u1ijq{eYM ",yZfUdT`S" _ArGLE<3x~jyOg?ͩ1fUDÖ-Ig~x垈|V Z^` +_AOW(j8 pk'ky?k*?~ݶW^GXV+6qiؑqOe4N <;??'>+}FK4Kbg0:dy hZ\,+~/zǍid\Ϝ]̑L TTbWMtմs9qb1YDҫO61x,x`n0$lU+B@"7@Y(~G,fpUr)3- 0) { sys_sleep <- getOption("rdbnomics.sleep_run") check_argument(sys_sleep, c("integer", "numeric")) Sys.sleep(sys_sleep) } tryCatch({ if (userl) { # Only readLines if (as.numeric(R.Version()$major) >= 3) { if (as.numeric(R.Version()$minor) < 2) { suppressMessages(suppressWarnings(utils::setInternet2(TRUE))) } } verb_warn_rl <- getOption("rdbnomics.verbose_warning_readLines") check_argument(verb_warn_rl, "logical") if (verb_warn_rl) { response <- try(readLines(x), silent = TRUE) } else { response <- try(suppressWarnings(readLines(x)), silent = TRUE) } if (inherits(response, "try-error")) { stop("BAD REQUEST", call. = FALSE) } else { jsonlite::fromJSON(response) } } else { # With curl if (!is.null(curl_args)) { if (inherits(curl_args, "curl_handle")) { curl_args <- list(handle = curl_args) } if (!inherits(curl_args, "list")) { stop( paste0( "Argument 'curl_config' or option 'rdbnomics.curl_config' can ", "only be of class 'curl_handle' or 'list'." ), call. = FALSE ) } if (inherits(curl_args, "list")) { if (is.null(names(curl_args))) { stop("The list 'curl_config' must be named.", call. = FALSE) } if (length(curl_args) <= 0) { stop("The list 'curl_config' is empty.", call. = FALSE) } nm <- names(curl_args) nm <- no_empty_char(nm) if (length(curl_args) != length(nm)) { stop("All elements of 'curl_config' must be named.", call. = FALSE) } } } try(curl::handle_reset(tmp_curl), silent = TRUE) if (!list_has_curl_handle(curl_args)) { tmp_curl <- list(handle = curl::new_handle()) if (!is.null(curl_args)) { curl::handle_setopt(tmp_curl$handle, .list = curl_args) } } else { tmp_curl <- curl_args } if (!is.null(headers) & !is.null(opt)) { curl::handle_setheaders(tmp_curl$handle, .list = headers) curl::handle_setopt(tmp_curl$handle, .list = opt) } response <- do.call(curl::curl_fetch_memory, c(list(url = x), tmp_curl)) check_x <- curl::parse_headers(response$headers) check_x <- utils::head(check_x, 1) http_ok <- getOption("rdbnomics.http_ok") check_argument(http_ok, "character") if (grepl(http_ok, toupper(check_x))) { response <- rawToChar(response$content) if (!is.null(jsonlite::fromJSON(response)$errors)) { stop( "\n", jsonlite::fromJSON(response)$errors$message, " : ", jsonlite::fromJSON(response)$errors$provider_code, "/", jsonlite::fromJSON(response)$errors$dataset_code, "/", jsonlite::fromJSON(response)$errors$series_code, call. = FALSE ) } jsonlite::fromJSON(response) } else { errormessage <- try( paste0( "\n", check_x, "\n", jsonlite::fromJSON(rawToChar(response$content))$error ), silent = TRUE ) if (inherits(errormessage, "try-error")) { errormessage <- paste0("\n", check_x) } stop(errormessage, call. = FALSE) } } }, error = function(e) { try_run <- getOption("rdbnomics.try_run") check_argument(try_run, c("integer", "numeric")) myerror <- try( grepl("'curl_config'", e$message) | grepl("BAD[[:blank:]]+REQUEST", toupper(e$message)), silent = TRUE ) if (!inherits(myerror, "try-error")) { if (myerror) { try_run <- -1L } } if (run < try_run) { get_data(x, userl, curl_args, headers = headers, opt = opt, run = run + 1) } else { stop(e) } }) } #------------------------------------------------------------------------------- # deploy deploy <- function(DT, columns = NULL, reference_column = "value") { if (!data.table::is.data.table(DT)) { stop("DT is not a data.table.", call. = FALSE) } if (nrow(DT) <= 0) { return(DT) } if (ncol(DT) <= 0) { return(DT) } has_list <- sapply(1:ncol(DT), function(x) { inherits(DT[[x]], "list") }, USE.NAMES = FALSE) has_list <- sum(has_list, na.rm = TRUE) has_list <- (has_list > 0) if (has_list) { DT[, dotI := .I] DT <- split(DT, DT$dotI) DT <- lapply(DT, function(y) { y <- as.list(y) # Reference length to_list_length <- length(y[[reference_column]][[1]]) # Transform lists into vectors if (is.null(columns)) { for (iv in names(y)) { v <- y[[iv]] if (inherits(v, "list")) { v <- unlist(v) if (length(v) == 1 & to_list_length != 1) { # New col y[[iv]] <- paste0(trim(v), ",") } else if ( (length(v) == to_list_length + 1) | (length(v) == 2 & to_list_length != 2) ) { # New col y[[iv]] <- paste0(trim(v[1]), ",", utils::tail(v, -1)) } else if (length(v) != to_list_length) { y[[iv]] <- paste(unique(v), collapse = ",") } else { y[[iv]] <- v } } } } else { for (i in columns) { y[[i]] <- unlist(y[[i]]) } } data.table::as.data.table(y) }) DT <- data.table::rbindlist(DT, use.names = TRUE, fill = TRUE) DT[, dotI := NULL] } DT[] } #------------------------------------------------------------------------------- # list_has_dataframe list_has_dataframe <- function(x) { check_for_dataframe <- lapply(x, function(y) { y <- sapply(y, inherits, what = "data.frame", simplify = FALSE) unlist(y) }) check_for_dataframe <- unlist(check_for_dataframe) check_for_dataframe <- sum(check_for_dataframe, na.rm = TRUE) (check_for_dataframe > 0) } #------------------------------------------------------------------------------- # no_empty_char no_empty_char <- function(x) { if (inherits(x, "character")) { x <- x[x != "" & !is.na(x)] } x } #------------------------------------------------------------------------------- # dataframe_to_columns dataframe_to_columns <- function(x) { has_dataframe <- sapply(x, function(y) { if (inherits(y, "data.frame")) { return(NULL) } "" }, simplify = FALSE) has_dataframe <- Filter(is.null, has_dataframe) if (length(has_dataframe) <= 0) { return(x) } for (i in names(has_dataframe)) { # cols <- colnames(x[[i]]) x <- cbind(x, x[[i]]) # names(x)[(ncol(x) - length(cols) + 1):ncol(x)] <- paste( # i, cols, # sep = "_" # ) x[[i]] <- NULL } x } #------------------------------------------------------------------------------- # get_version get_version <- function(x) { if ("python_project_version" %in% names(x$`_meta`)) { api_version <- numeric_version(x$`_meta`$python_project_version) } else if ("version" %in% names(x$`_meta`)) { api_version <- numeric_version(x$`_meta`$version) } else { stop("Can't find the version.", call. = FALSE) } api_version <- unlist(api_version) api_version <- api_version[api_version != 0] api_version <- utils::head(api_version, 1) authorized_version(api_version) api_version } #------------------------------------------------------------------------------- # authorized_version authorized_version <- function(x) { versions <- getOption("rdbnomics.authorized_api_version") check_argument(versions, c("integer", "numeric"), len = FALSE) name <- deparse(substitute(versions)) if (is.null(versions)) { stop(paste0(name, " cannot be NULL."), call. = FALSE) } if (!inherits(versions, c("numeric", "integer"))) { stop( paste0(name, " must be of class 'integer' or 'numeric'."), call. = FALSE ) } if (length(versions) <= 0) { stop(paste0(name, " must be of length greater than 0."), call. = FALSE) } if (x %notin% versions) { stop( paste0( "Only versions ", paste0(versions, collapse = ", "), " are supported." ), call. = FALSE ) } invisible() } #------------------------------------------------------------------------------- # trim trim <- function(x) { gsub("^[[:blank:]]+|[[:blank:]]+$", "", x) } #------------------------------------------------------------------------------- # date_format date_format <- function(x) { x <- no_empty_char(x) if (length(x) <= 0) { return(FALSE) } sum(grepl("^[0-9]{4}-[0-9]{2}-[0-9]{2}$", trim(x)), na.rm = TRUE) == length(x) } #------------------------------------------------------------------------------- # timestamp_format timestamp_format <- function(x, y) { x <- no_empty_char(x) if (length(x) <= 0) { return(FALSE) } sum(grepl(y, trim(x)), na.rm = TRUE) == length(x) } #------------------------------------------------------------------------------- # check_argument check_argument <- function(x, type, len = TRUE, n = 1, not_null = TRUE) { name <- deparse(substitute(x)) if (not_null) { if (is.null(x)) { stop(paste0(name, " cannot be NULL."), call. = FALSE) } } if (!inherits(x, type)) { stop( paste0( name, " must be of class '", paste0(type, collapse = "', '"), "'." ), call. = FALSE ) } if (len) { if (length(x) != n) { stop(paste0(name, " must be of length ", n, "."), call. = FALSE) } } invisible() } #------------------------------------------------------------------------------- # to_json_if_list to_json_if_list <- function(x) { if (inherits(x, "list")) { if (is.null(names(x))) { stop("The list 'dimensions' must be named.", call. = FALSE) } if (length(x) <= 0) { stop("The list 'dimensions' is empty.", call. = FALSE) } nm <- names(x) nm <- no_empty_char(nm) if (length(x) != length(nm)) { stop("All elements of 'dimensions' must be named.", call. = FALSE) } return(jsonlite::toJSON(x)) } x } #------------------------------------------------------------------------------- # transform_date_timestamp transform_date_timestamp <- function(DT) { timezone <- getOption("rdbnomics.timestamp_tz") check_argument(timezone, "character") from_timestamp <- c( "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]+Z$", "^[0-9]{4}-[0-9]{2}-[0-9]{2}[[:blank:]]+[0-9]{2}:[0-9]{2}:[0-9]{2}$" ) to_timestamp <- c( "%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%OSZ", "%Y-%m-%d %H:%M:%S" ) cols <- copy(colnames(DT)) cols <- cols[ (tolower(cols) != "observations_attributes") & !grepl("name$", tolower(cols)) ] if (length(cols) > 0) { DT[ , (cols) := lapply(.SD, function(x) { if (inherits(x, "character")) { if (date_format(x)) { return(suppressWarnings(as.Date(x))) } for (i in seq_along(from_timestamp)) { if (timestamp_format(x, from_timestamp[i])) { return( suppressWarnings( as.POSIXct(x, tz = timezone, format = to_timestamp[i]) ) ) } } } x }), .SDcols = cols ] } invisible(DT) } #------------------------------------------------------------------------------- # avoid_partial_argument avoid_partial_argument <- function(x) { x <- as.list(x) x <- names(x) x <- no_empty_char(x) if (is.null(x)) { return(invisible()) } if (length(x) <= 0) { return(invisible()) } args_ok <- c(names(formals(rdb)), names(formals(rdb_by_api_link))) args_ok <- args_ok[args_ok %notin% c("...", "api_link")] if (length(setdiff(x, args_ok)) > 0) { stop("Please avoid partial argument matching.", call. = FALSE) } invisible() } #------------------------------------------------------------------------------- # correct_argument correct_argument <- function() { args_ok <- c(names(formals(rdb)), names(formals(rdb_by_api_link))) args_ok[args_ok %notin% c("...", "api_link")] } #------------------------------------------------------------------------------- # call_ok call_ok <- function(x) { x <- as.list(x) x <- names(x) modif_arg <- FALSE if (is.null(x)) { modif_arg <- TRUE } if (!is.null(x)) { x <- no_empty_char(x) if (length(x) <= 0) { modif_arg <- TRUE } else { x <- pmatch(x, correct_argument(), duplicates.ok = TRUE) if (sum(is.na(x)) <= 0) { modif_arg <- TRUE } } } modif_arg } #------------------------------------------------------------------------------- # remove_columns remove_columns <- function(DT, x, expr = FALSE) { if (expr) { cols <- grep(x, colnames(DT), value = TRUE) } else { cols <- intersect(x, colnames(DT)) } if (length(cols) > 0) { DT[, (cols) := NULL] } invisible(DT) } #------------------------------------------------------------------------------- # reduce_to_one reduce_to_one <- function(DT) { x <- DT[ , lapply(.SD, function(y) { length(unique(y)) }) ] x <- as.list(x) x <- Filter(function(y){ y > 1 }, x) x <- names(x) DT[, (x) := NULL] invisible(DT) } #------------------------------------------------------------------------------- # filter_type filter_type <- function(x) { test <- tryCatch({ res <- "ko" n <- length(x) y <- sapply(x, filter_ok) y <- sum(y, na.rm = TRUE) if (y == n) { res <- "list" } res }, error = function(e) { "ko" }) if (test == "ko") { test <- tryCatch({ res <- filter_ok(x) if (res) { res <- "notlist" } else { res <- "ko" } res }, error = function(e) { "ko" }) } test } #------------------------------------------------------------------------------- # filter_ok filter_ok <- function(x) { tryCatch({ res <- FALSE nm1 <- names(x) nm2 <- names(x$parameters) if (identical(nm1, c("code", "parameters"))) { if (is.null(nm2)) { res <- TRUE } if (identical(nm2, c("frequency", "method"))) { res <- TRUE } } res }, error = function(e) { FALSE }) } #------------------------------------------------------------------------------- # get_geo_colname get_geo_colname <- function(x) { y <- try( { expr <- "dimensions_label[s]*\\." elt <- grep(expr, names(unlist(x)), value = TRUE) if (is.null(x$dataset$code)) { codes <- gsub(".*/|\\..*", "", elt) } else { codes <- x$dataset$code if (length(codes) == 1) { codes <- rep(codes, length(elt)) } } lapply(seq_along(elt), function(i) { z <- elt[i] ref_elt <- gsub(".*\\.", "", z) elt_ <- gsub('\\.', '"]][["', z) elt_ <- paste0('[["', elt_, '"]]') c(codes[i], ref_elt, eval(parse(text = paste0("x", elt_)))) }) }, silent = TRUE ) if (inherits(y, "try-error")) { return(NULL) } y } #------------------------------------------------------------------------------- # get_geo_names get_geo_names <- function(x, colname) { y <- try( { codes <- sapply(colname, `[[`, 1) nm <- sapply(colname, `[[`, 2) DTs <- lapply(seq_along(codes), function(i) { expr <- paste0( "(", paste0(codes[i], collapse = "|"), ")*", "\\.dimensions_value[s]*_label[s]*\\.(", paste0(nm[i], collapse = "|"), "){1}\\." ) elt <- grep(expr, names(unlist(x)), value = TRUE) for (y in nm) { elt <- gsub(paste0(y, '\\..*'), y, elt) } elt <- unique(elt) if (length(elt) > 0) { elt_ <- gsub('\\.', '"]][["', elt) elt_ <- paste0('[["', elt_, '"]]') y <- eval(parse(text = paste0("x", elt_))) suppressWarnings( setnames( data.table(X1 = codes[i], X2 = names(y), X3 = unname(unlist(y))), c("dataset_code", colname[[i]][2:3]) )[] ) } else { NULL } }) DTs <- Filter(Negate(is.null), DTs) if (length(DTs) <= 0) { NULL } else { DTs } }, silent = TRUE ) if (inherits(y, "try-error")) { return(NULL) } y } #------------------------------------------------------------------------------- # list_has_curl_handle list_has_curl_handle <- function(x) { if (is.null(x)) { return(FALSE) } if (!inherits(x, "list")) { return(FALSE) } y <- sapply(x, inherits, what = "curl_handle") y <- sum(y, na.rm = TRUE) y <- y > 0 if (y) { TRUE } else { FALSE } } rdbnomics/R/zzz.R0000644000176200001440000000323013521150705013410 0ustar liggesusers.onAttach <- function(libname, pkgname) { packageStartupMessage("Visit .") } .onLoad <- function(libname, pkgname) { # To ensure backward compatibility pkg <- getNamespace(pkgname) assign( "strrep", function (x, times) { x <- as.character(x) if (length(x) == 0L) { return(x) } unlist(.mapply(function(x, times) { if (is.na(x) || is.na(times)) { return(NA_character_) } if (times <= 0L) { return("") } paste0(replicate(times, x), collapse = "") }, list(x = x, times = times), MoreArgs = list()), use.names = FALSE) }, envir = pkg ) # Package options opts <- list( rdbnomics.use_readLines = FALSE, rdbnomics.sleep_run = 1L, rdbnomics.try_run = 2L, rdbnomics.verbose_warning = TRUE, rdbnomics.api_base_url = "https://api.db.nomics.world", rdbnomics.editor_base_url = "https://editor.nomics.world", rdbnomics.api_version = 22, rdbnomics.editor_version = 1, rdbnomics.authorized_api_version = c(21, 22), rdbnomics.verbose_warning_readLines = FALSE, rdbnomics.timestamp_tz = "GMT", rdbnomics.http_ok = "200[[:blank:]]+OK$", rdbnomics.curl_config = NULL, rdbnomics.rdb_no_arg = TRUE, rdbnomics.metadata = TRUE, rdbnomics.filters = NULL, rdbnomics.progress_bar = TRUE, rdbnomics.translate_codes = TRUE ) opts <- append( opts, list(rdbnomics = sort(gsub("rdbnomics\\.", "", names(opts)))), 0 ) op <- options() op.rdbnomics <- opts toset <- !(names(op.rdbnomics) %in% names(op)) if (any(toset)) options(op.rdbnomics[toset]) invisible() } rdbnomics/R/rdb_by_api_link.R0000644000176200001440000001300213604412433015661 0ustar liggesusers#' Download DBnomics data using API link (deprecated). #' #' \code{rdb_by_api_link} downloads data series from #' \href{https://db.nomics.world/}{DBnomics}. #' #' This function gives you access to hundreds of millions data series from #' \href{https://api.db.nomics.world/}{DBnomics API} (documentation about #' the API can be found \href{https://api.db.nomics.world/v22/apidocs}{here}). #' The API link is given on the #' \href{https://db.nomics.world/}{DBnomics website}. #' #' @param api_link Character string. DBnomics API link of the search. #' @param use_readLines Logical (default \code{FALSE}). If \code{TRUE}, then #' the data are requested and read with the base function \code{readLines} i.e. #' through the default R internet connection. This can be used to get round the #' error \code{Could not resolve host: api.db.nomics.world}. #' @param curl_config Named list (default \code{NULL}). If not #' \code{NULL}, it is used to configure a proxy connection. This #' configuration is passed to the function \code{curl_fetch_memory} of the package #' \pkg{curl}. A temporary \code{curl_handle} object is created internally #' with arguments equal to the provided list in \code{curl_config}.\cr #' For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. #' For available curl options see \code{\link[curl]{curl_options}}, #' \code{names(curl_options())} and #' \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}. #' @param filters List (default \code{NULL}). This argument must be a named #' list for one filter because the function \code{toJSON} of the package \pkg{jsonlite} #' is used before sending the request to the server. For multiple filters, #' you have to provide a list of valid filters (see examples).\cr #' A valid filter is a named list with an element \code{code} which is a character string, #' and an element \code{parameters} which is a named list with elements \code{frequency} #' and \code{method} or a NULL. #' @return A \code{data.table}. #' @examples #' \dontrun{ #' # Fetch two series from different datasets of different providers : #' df1 <- rdb_by_api_link( #' paste0( #' "https://api.db.nomics.world/v22/", #' "series?observations=1&series_ids=AMECO/ZUTN/EA19.1.0.0.0.ZUTN,IMF/CPI/A.AT.PCPIT_IX" #' ) #' ) #' #' # Fetch one series from the dataset 'Doing Business' of WB provider : #' df2 <- rdb_by_api_link( #' paste0( #' "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22", #' "indicator%22%3A%5B%22IC.REG.PROC.FE.NO%22%5D%7D&q=Doing%20Business", #' "&observations=1&format=json&align_periods=1&offset=0&facets=0" #' ) #' ) #' #' #' ## Use a specific proxy to fetch the data #' # Fetch one series from the dataset 'Doing Business' of WB provider : #' h <- list( #' proxy = "", #' proxyport = , #' proxyusername = "", #' proxypassword = "" #' ) #' options(rdbnomics.curl_config = h) #' df2 <- rdb_by_api_link( #' paste0( #' "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22", #' "indicator%22%3A%5B%22IC.REG.PROC.FE.NO%22%5D%7D&q=Doing%20Business", #' "&observations=1&format=json&align_periods=1&offset=0&facets=0" #' ) #' ) #' # or to use once #' df2 <- rdb_by_api_link( #' paste0( #' "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22", #' "indicator%22%3A%5B%22IC.REG.PROC.FE.NO%22%5D%7D&q=Doing%20Business", #' "&observations=1&format=json&align_periods=1&offset=0&facets=0" #' ), #' curl_config = h #' ) #' #' #' ## Use R default connection to avoid a proxy failure (in some cases) #' # Fetch one series from the dataset 'Doing Business' of WB provider : #' options(rdbnomics.use_readLines = TRUE) #' df2 <- rdb_by_api_link( #' paste0( #' "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22", #' "indicator%22%3A%5B%22IC.REG.PROC.FE.NO%22%5D%7D&q=Doing%20Business", #' "&observations=1&format=json&align_periods=1&offset=0&facets=0" #' ) #' ) #' # or to use once #' df2 <- rdb_by_api_link( #' paste0( #' "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22", #' "indicator%22%3A%5B%22IC.REG.PROC.FE.NO%22%5D%7D&q=Doing%20Business", #' "&observations=1&format=json&align_periods=1&offset=0&facets=0" #' ), #' use_readLines = TRUE #' ) #' #' #' ## Apply filter(s) to the series #' # One filter #' df3 <- rdb_by_api_link( #' "https://api.db.nomics.world/v22/series/IMF/WEO/ABW.BCA?observations=1", #' filters = list( #' code = "interpolate", #' parameters = list(frequency = "daily", method = "spline") #' ) #' ) #' #' # Two filters #' df3 <- rdb_by_api_link( #' "https://api.db.nomics.world/v22/series/IMF/WEO/ABW.BCA?observations=1", #' filters = list( #' list( #' code = "interpolate", #' parameters = list(frequency = "quarterly", method = "spline") #' ), #' list( #' code = "aggregate", #' parameters = list(frequency = "annual", method = "average") #' ) #' ) #' ) #' } #' @seealso \code{\link{rdb}} #' @author Sebastien Galais #' @export rdb_by_api_link <- function( api_link, use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config"), filters = getOption("rdbnomics.filters") ) { .Deprecated("rdb(api_link = ...)", old = "rdb_by_api_link(api_link = ...)") .rdb( api_link = api_link, use_readLines = use_readLines, curl_config = curl_config, filters = filters ) } rdbnomics/R/rdb.R0000644000176200001440000004274513604412310013333 0ustar liggesusers#' Download DBnomics data. #' #' \code{rdb} downloads data series from #' \href{https://db.nomics.world/}{DBnomics} using shortcuts like \code{ids}, #' \code{dimensions}, \code{mask}, \code{query} or using an \code{api_link}. #' #' This function gives you access to hundreds of millions data series from #' \href{https://api.db.nomics.world/}{DBnomics API} (documentation about #' the API can be found \href{https://api.db.nomics.world/v22/apidocs}{here}). #' The code of each series is given on the #' \href{https://db.nomics.world/}{DBnomics website}. \cr\cr #' In the event that only the argument \code{ids} is provided (and those in the #' ellipsis \code{...}), the argument name can be dropped. The character string #' vector is directly passed to \code{ids}. \cr #' If only the argument \code{api_link} is provided (and those in the #' ellipsis \code{...}), then the argument name can be dropped. The character string #' vector is directly passed to \code{api_link}. \cr #' In the same way, if only \code{provider_code}, \code{dataset_code} and #' \code{mask} are provided then the arguments names can be dropped. The #' last character string is automatically passed to \code{mask}. #' #' #' @param provider_code Character string (default \code{NULL}). DBnomics code #' of the provider. #' @param dataset_code Character string (default \code{NULL}). DBnomics code #' of the dataset. #' @param ids Character string (default \code{NULL}). DBnomics code of one or #' several series. #' @param dimensions List or character string (single quoted) (default \code{NULL}). #' DBnomics code of one or several dimensions in the specified provider and dataset. #' If it is a named list, then the function \code{toJSON} (from the #' package \pkg{jsonlite}) is applied to generate the json object. #' @param mask Character string (default \code{NULL}). DBnomics code of one or #' several masks in the specified provider and dataset. #' @param query Character string (default \code{NULL}). A query to #' filter/select series from a provider's dataset. #' @param api_link Character string. DBnomics API link of the search. It should #' starts with \code{http://} or \code{https://}. #' @param filters List (default \code{NULL}). This argument must be a named #' list for one filter because the function \code{toJSON} of the package \pkg{jsonlite} #' is used before sending the request to the server. For multiple filters, #' you have to provide a list of valid filters (see examples).\cr #' A valid filter is a named list with an element \code{code} which is a character string, #' and an element \code{parameters} which is a named list with elements \code{frequency} #' and \code{method} or a NULL. #' @param use_readLines Logical (default \code{FALSE}). If \code{TRUE}, then #' the data are requested and read with the base function \code{readLines} i.e. #' through the default R internet connection. This can be used to get round the #' error \code{Could not resolve host: api.db.nomics.world}. #' @param curl_config Named list (default \code{NULL}). If not #' \code{NULL}, it is used to configure a proxy connection. This #' configuration is passed to the function \code{curl_fetch_memory} of the package #' \pkg{curl}. A temporary \code{curl_handle} object is created internally #' with arguments equal to the provided list in \code{curl_config}.\cr #' For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. #' For available curl options see \code{\link[curl]{curl_options}}, #' \code{names(curl_options())} and #' \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}. #' @param verbose Logical (default \code{FALSE}). Show warnings of the function. #' @param ... Arguments to be passed to the internal function \code{.rdb}. #' @return A \code{data.table}. #' @examples #' \dontrun{ #' ## By ids #' # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider: #' df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") #' # or when no argument names are given (provider_code -> ids) #' df1 <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN") #' #' # Fetch two series from dataset 'Unemployment rate' (ZUTN) of AMECO provider: #' df2 <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) #' #' # Fetch two series from different datasets of different providers: #' df3 <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "IMF/BOP/A.FR.BCA_BP6_EUR")) #' #' #' ## By dimensions #' # Fetch one value of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider: #' df1 <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea12")) #' # or #' df1 <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea12"]}') #' #' # Fetch two values of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider: #' df2 <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea12", "dnk"))) #' # or #' df2 <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea12", "dnk"]}') #' #' # Fetch several values of several dimensions from dataset 'Doing business' (DB) of World Bank: #' dim <- list( #' country = c("DZ", "PE"), #' indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS") #' ) #' df3 <- rdb("WB", "DB", dimensions = dim) #' # or #' dim <- paste0( #' '{"country": ["DZ", "PE"],', #' '"indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}' #' ) #' df3 <- rdb("WB", "DB", dimensions = dim) #' #' #' ## By mask #' # Fetch one series from dataset 'Balance of Payments' (BOP) of IMF: #' df1 <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") #' # or when no argument names are given except provider_code and dataset_code (ids -> mask) #' df1 <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR") #' #' # Fetch two series from dataset 'Balance of Payments' (BOP) of IMF: #' df2 <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") #' #' # Fetch all series along one dimension from dataset 'Balance of Payments' (BOP) of IMF: #' df3 <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") #' #' # Fetch series along multiple dimensions from dataset 'Balance of Payments' (BOP) of IMF: #' df4 <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") #' #' #' ## By query #' # Fetch one series from dataset 'WEO by countries' (WEO) from IMF : #' df1 <- rdb("IMF", "WEO", query = "France current account balance percent") #' # Fetch series from dataset 'WEO by countries' (WEO) from IMF : #' df2 <- rdb("IMF", "WEO", query = "current account balance percent") #' #' #' ## By api_link #' # Fetch two series from different datasets of different providers : #' df1 <- rdb( #' api_link = paste0( #' "https://api.db.nomics.world/v22/", #' "series?observations=1&series_ids=AMECO/ZUTN/EA19.1.0.0.0.ZUTN,IMF/CPI/A.AT.PCPIT_IX" #' ) #' ) #' #' # Fetch one series from the dataset 'Doing Business' of WB provider : #' df2 <- rdb( #' api_link = paste0( #' "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22", #' "indicator%22%3A%5B%22IC.REG.PROC.FE.NO%22%5D%7D&q=Doing%20Business", #' "&observations=1&format=json&align_periods=1&offset=0&facets=0" #' ) #' ) #' # or when no argument names are given (provider_code -> api_link) #' df1 <- rdb( #' paste0( #' "https://api.db.nomics.world/v22/", #' "series?observations=1&series_ids=AMECO/ZUTN/EA19.1.0.0.0.ZUTN,IMF/CPI/A.AT.PCPIT_IX" #' ) #' ) #' #' #' ## Use a specific proxy to fetch the data #' # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider : #' h <- list( #' proxy = "", #' proxyport = , #' proxyusername = "", #' proxypassword = "" #' ) #' options(rdbnomics.curl_config = h) #' df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") #' # or to use once #' options(rdbnomics.curl_config = NULL) #' df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h) #' #' #' ## Use R default connection to avoid a proxy failure (in some cases) #' # Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider : #' options(rdbnomics.use_readLines = TRUE) #' df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") #' # or to use once #' df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE) #' #' #' ## Apply filter(s) to the series #' # One filter #' df1 <- rdb( #' ids = c("IMF/WEO/ABW.BCA", "IMF/WEO/ABW.BCA_NGDPD"), #' filters = list( #' code = "interpolate", #' parameters = list(frequency = "daily", method = "spline") #' ) #' ) #' #' # Two filters #' df1 <- rdb( #' ids = c("IMF/WEO/ABW.BCA", "IMF/WEO/ABW.BCA_NGDPD"), #' filters = list( #' list( #' code = "interpolate", #' parameters = list(frequency = "quarterly", method = "spline") #' ), #' list( #' code = "aggregate", #' parameters = list(frequency = "annual", method = "average") #' ) #' ) #' ) #' } #' @author Sebastien Galais #' @export rdb <- function( provider_code = NULL, dataset_code = NULL, ids = NULL, dimensions = NULL, mask = NULL, query = NULL, api_link = NULL, filters = getOption("rdbnomics.filters"), use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config"), verbose = getOption("rdbnomics.verbose_warning"), ... ) { # Checking 'verbose' check_argument(verbose, "logical") # Setting API url api_base_url <- getOption("rdbnomics.api_base_url") check_argument(api_base_url, "character") # Setting API version api_version <- getOption("rdbnomics.api_version") check_argument(api_version, c("numeric", "integer")) authorized_version(api_version) # Setting API metadata metadata <- getOption("rdbnomics.metadata") check_argument(metadata, "logical") # Building API base url api_base_url <- paste0(api_base_url, "/v", api_version, "/series") # Checking arguments provider_code_null <- is.null(provider_code) provider_code_not_null <- !provider_code_null dataset_code_null <- is.null(dataset_code) dataset_code_not_null <- !dataset_code_null dimensions_null <- is.null(dimensions) dimensions_not_null <- !dimensions_null mask_null <- is.null(mask) mask_not_null <- !mask_null ids_null <- is.null(ids) ids_not_null <- !ids_null query_null <- is.null(query) query_not_null <- !query_null api_link_null <- is.null(api_link) api_link_not_null <- !api_link_null # provider_code is considered as api_link in some cases if ( provider_code_not_null & dataset_code_null & dimensions_null & mask_null & ids_null & query_null & api_link_null & getOption("rdbnomics.rdb_no_arg") ) { is_http <- grepl("^http(s)*://", tolower(provider_code)) if (sum(is_http, na.rm = TRUE) > 0) { fcall <- sys.call() modif_arg <- call_ok(fcall) if (modif_arg) { api_link <- provider_code provider_code <- NULL provider_code_null <- TRUE provider_code_not_null <- !provider_code_null api_link_null <- FALSE api_link_not_null <- !api_link_null } } } # By api_link i.e. .rdb(api_link = api_link) if (api_link_not_null) { check_argument(api_link, "character", not_null = FALSE) if (api_version == 22) { return( .rdb( api_link = api_link, filters = filters, use_readLines = use_readLines, curl_config = curl_config, ... ) ) } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } } # provider_code is considered as ids in some cases if ( provider_code_not_null & dataset_code_null & dimensions_null & mask_null & ids_null & query_null & api_link_null & getOption("rdbnomics.rdb_no_arg") ) { fcall <- sys.call() modif_arg <- call_ok(fcall) if (modif_arg) { ids <- provider_code provider_code <- NULL provider_code_null <- TRUE provider_code_not_null <- !provider_code_null ids_null <- FALSE ids_not_null <- !ids_null } } # ids is considered as mask in some cases if ( provider_code_not_null & dataset_code_not_null & dimensions_null & mask_null & ids_not_null & query_null & api_link_null & getOption("rdbnomics.rdb_no_arg") ) { fcall <- sys.call() modif_arg <- call_ok(fcall) if (modif_arg) { mask <- ids ids <- NULL mask_null <- FALSE mask_not_null <- !mask_null ids_null <- TRUE ids_not_null <- !ids_null } } # By dimensions if (dimensions_not_null) { if (provider_code_null | dataset_code_null) { stop( paste0( "When you filter with 'dimensions', you must specifiy ", "'provider_code' and 'dataset_code' as arguments of the function." ), call. = FALSE ) } dimensions <- to_json_if_list(dimensions) check_argument(dimensions, c("character", "json"), not_null = FALSE) check_argument(provider_code, "character", not_null = FALSE) check_argument(dataset_code, "character", not_null = FALSE) if (api_version == 21) { link <- paste0( api_base_url, "?provider_code=", provider_code, "&dataset_code=", dataset_code, "&dimensions=", dimensions ) } else if (api_version == 22) { link <- paste0( api_base_url, "/", provider_code, "/", dataset_code, ifelse(metadata, "?", paste0("?metadata=", as.numeric(metadata), "&")), "observations=1&dimensions=", dimensions ) } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } return( .rdb( api_link = link, filters = filters, use_readLines = use_readLines, curl_config = curl_config, ... ) ) } # By mask if (mask_not_null) { if (provider_code_null | dataset_code_null) { stop( paste0( "When you filter with 'mask', you must specifiy 'provider_code' ", "and 'dataset_code' as arguments of the function." ), call. = FALSE ) } check_argument(mask, "character", not_null = FALSE) check_argument(provider_code, "character", not_null = FALSE) check_argument(dataset_code, "character", not_null = FALSE) if (api_version == 21) { link <- paste0( api_base_url, "?provider_code=", provider_code, "&dataset_code=", dataset_code, "&series_code_mask=", mask ) } else if (api_version == 22) { link <- paste0( api_base_url, "/", provider_code, "/", dataset_code, "/", mask, ifelse(metadata, "?", paste0("?metadata=", as.numeric(metadata), "&")), "observations=1" ) } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } return( .rdb( api_link = link, filters = filters, use_readLines = use_readLines, curl_config = curl_config, ... ) ) } # By ids if (ids_not_null) { if (provider_code_not_null | dataset_code_not_null) { if (verbose) { warning( paste0( "When you filter with 'ids', ", "'provider_code' and 'dataset_code' are not considered." ) ) } } if (!is.character(ids)) { stop("'ids' must be of class 'character'.", call. = FALSE) } if (length(ids) <= 0) { stop("'ids' is empty.", call. = FALSE) } if (api_version == 21) { link <- paste0( api_base_url, "?series_ids=", paste(ids, collapse = ",") ) } else if (api_version == 22) { link <- paste0( api_base_url, ifelse(metadata, "?", paste0("?metadata=", as.numeric(metadata), "&")), "observations=1&series_ids=", paste(ids, collapse = ",") ) } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } return( .rdb( api_link = link, filters = filters, use_readLines = use_readLines, curl_config = curl_config, ... ) ) } # By query if (query_not_null) { if (provider_code_null | dataset_code_null) { stop( paste0( "When you filter with a 'query', you must specifiy 'provider_code' ", "and 'dataset_code' as arguments of the function." ), call. = FALSE ) } check_argument(query, "character", not_null = FALSE) if (verbose) { if (query == "") { warning( paste0( "Your 'query' is empty, the entire dataset ", provider_code, "/", dataset_code, " will be downloaded. It can be long !" ) ) } } if (api_version == 22) { link <- paste0( api_base_url, "/", provider_code, "/", dataset_code, "?q=", utils::URLencode(query), ifelse(metadata, "&", paste0("&metadata=", as.numeric(metadata), "&")), "observations=1" ) } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } return( .rdb( api_link = link, filters = filters, use_readLines = use_readLines, curl_config = curl_config, ... ) ) } stop( "Please provide correct 'provider_code', 'dataset_code', 'dimensions', ", "'mask', 'ids', 'query', 'api_link' or 'filters'.", call. = FALSE ) } rdbnomics/R/rdbnomics.R0000644000176200001440000000067413604412702014544 0ustar liggesusers#' Package rdbnomics #' #' DBnomics R client (). #' #' @docType package #' @name rdbnomics #' #' @import curl jsonlite data.table #' NULL if (getRversion() >= "2.15.1") { vars <- c( ".", ":=", "value", "dotI", "period", "period_start_day", "series_code", "filtered", "original_period", "series_name", "original_value", "period_middle_day" ) utils::globalVariables(unique(vars)) }rdbnomics/R/dot_rdb.R0000644000176200001440000002745713574256420014222 0ustar liggesusers.rdb <- function( api_link, use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config"), filters = getOption("rdbnomics.filters") ) { # Checking 'api_link' if (is.null(api_link)) { return(NULL) } check_argument(api_link, "character") # Checking 'use_readLines' check_argument(use_readLines, "logical") # Checking 'filters' if (!is.null(filters)) { check_filter <- filter_type(filters) if (check_filter == "ko") { stop( paste0( "If only one filter is applied then 'filters' must be a named list ", "with two elements : 'code' and 'parameters'." ), "\n", paste0( "'code' is a character string and 'parameters' is an empty list ", "or a named list ('frequency' and 'method')." ), "\n", "For more informations, visit .", "\n", paste0( "If multiple filters are applied then 'filters' must be a unnamed ", "list of valid filters." ), call. = FALSE ) } if (use_readLines) { warning( "When applying filters, the curl functions must be used.", "\n", "As a consequence, 'use_readLines' is set to FALSE.", call. = FALSE ) use_readLines <- FALSE } } # Fetching data DBlist <- get_data(api_link, use_readLines, curl_config) # Getting API version api_version <- get_version(DBlist) if (api_version == 21) { data_elt <- "data" } else if (api_version == 22) { data_elt <- "docs" } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } # If data is empty, return NULL if (is.data.frame(DBlist$series[[data_elt]])) { if (nrow(DBlist$series[[data_elt]]) <= 0) { return(NULL) } } if (inherits(DBlist$series[[data_elt]], "list")) { if (length(DBlist$series[[data_elt]]) <= 0) { return(NULL) } } # Checking if the limit has been reached num_found <- DBlist$series$num_found limit <- DBlist$series$limit # Additional informations to translate geo, freq, ... if (!getOption("rdbnomics.translate_codes")) { additional_geo_column <- additional_geo_mapping <- NULL } else { additional_geo_column <- get_geo_colname(DBlist) additional_geo_mapping <- get_geo_names(DBlist, additional_geo_column) # Check coherence if (is.null(additional_geo_column) | is.null(additional_geo_mapping)) { additional_geo_column <- additional_geo_mapping <- NULL } if (!is.null(additional_geo_column) & !is.null(additional_geo_mapping)) { if (length(additional_geo_column) != length(additional_geo_mapping)) { if ( length(additional_geo_column) == 0 | length(additional_geo_mapping) == 0 ) { additional_geo_column <- additional_geo_mapping <- NULL } else { check_agc <- sapply(additional_geo_column, paste0, collapse = "|") additional_geo_column <- stats::setNames(additional_geo_column, check_agc) check_agm <- sapply(additional_geo_mapping, function(u) { u1 <- u$dataset_code[1] u2 <- colnames(u)[2:3] u2 <- paste0(u2, collapse = "|") paste0(u1, "|", u2) }) additional_geo_mapping <- stats::setNames(additional_geo_mapping, check_agm) keep <- intersect(check_agc, check_agm) if (length(keep) == 0) { additional_geo_column <- additional_geo_mapping <- NULL } else { additional_geo_column <- additional_geo_column[sort(keep)] additional_geo_mapping <- additional_geo_mapping[sort(keep)] } } } } } # Extracting data DBdata <- list(DBlist$series[[data_elt]]) rm(DBlist) if (num_found > limit) { DBdata0 <- DBdata rm(DBdata) sequence <- seq(1, floor(num_found / limit), 1) # Modifying link if (grepl("offset=", api_link)) { api_link <- gsub("\\&offset=[0-9]+", "", api_link) api_link <- gsub("\\?offset=[0-9]+", "", api_link) } sep <- ifelse(grepl("\\?", api_link), "&", "?") DBdata <- lapply(sequence, function(i) { # Modifying link tmp_api_link <- paste0(api_link, sep, "offset=", i * limit) # Fetching data DBlist <- get_data(tmp_api_link, use_readLines, curl_config) # Extracting data DBlist$series[[data_elt]] }) DBdata <- append(DBdata, DBdata0, 0) rm(DBdata0) } # Transform data.frames inside DBdata if (list_has_dataframe(DBdata)) { DBdata <- lapply(DBdata, dataframe_to_columns) } # Transforming into data.table DBdata <- lapply(DBdata, data.table::setDT) # Gathering data DBdata <- data.table::rbindlist(DBdata, use.names = TRUE, fill = TRUE) # Expanding list columns DBdata <- deploy(DBdata) # To reproduce the Python module, we copy the 'value' element DBdata[ , original_value := format( value, scientific = FALSE, decimal.mark = ".", big.mark = "", trim = TRUE, drop0trailing = TRUE ) ] # Transforming date format and timestamp format transform_date_timestamp(DBdata) # Modifying column names tryCatch({ data.table::setnames(DBdata, "period", "original_period") }, error = function(e) { stop( paste0( "The retrieved dataset doesn't have a column named 'period', it's not ", "normal please check ." ), call. = FALSE ) }) tryCatch({ data.table::setnames(DBdata, "period_start_day", "period") }, error = function(e) { stop( paste0( "The retrieved dataset doesn't have a column named ", "'period_start_day', it's not normal please check ." ), call. = FALSE ) }) # DBnomics editor if (!is.null(filters)) { if (check_filter == "notlist") { filters <- list(filters) } # Filters are applied by 'series_code' codes <- unique(DBdata$series_code) multicodes <- length(codes) > 1 # A progress bar is displayed if there are more than one code if (multicodes & getOption("rdbnomics.progress_bar")) { pb <- utils::txtProgressBar(min = 0, max = length(codes), style = 3) } DBlist <- lapply(seq_along(codes), function(i) { x <- codes[i] tmpdata <- DBdata[series_code == x] # 'series' for the POST request series <- list( frequency = unique(tmpdata$`@frequency`), period_start_day = tmpdata$period, value = tmpdata$value ) # POST request header headers <- list( "Content-Type" = "application/json", "Accept" = "application/json" ) # POST elements opt <- list( customrequest = "POST", postfields = as.character( jsonlite::toJSON( list(filters = filters, series = list(series)), auto_unbox = TRUE ) ) ) # Editor url editor_link <- paste0( getOption("rdbnomics.editor_base_url"), "/api/v", getOption("rdbnomics.editor_version"), "/apply" ) request <- get_data(editor_link, FALSE, curl_config, headers, opt) request <- dataframe_to_columns(request$filter_results$series) data.table::setDT(request) request <- deploy(request) request[ , original_value := format( value, scientific = FALSE, decimal.mark = ".", big.mark = "", trim = TRUE, drop0trailing = TRUE ) ] transform_date_timestamp(request) # Some columns from the original dataset will be replaced by the # filtered dataset tmpdata <- remove_columns( tmpdata, c( "@frequency", "original_period", "period", "value", "original_value", "indexed_at", "series_code" ) ) try( { cols_to_remove <- sapply(additional_geo_column, `[[`, 2) tmpdata <- remove_columns(tmpdata, cols_to_remove) rm(cols_to_remove) }, silent = TRUE ) tmpdata <- remove_columns(tmpdata, "^observation", expr = TRUE) # The aim is to keep only unique informations tmpdata <- unique(tmpdata) if (nrow(tmpdata) > 1) { reduce_to_one(tmpdata) tmpdata <- unique(tmpdata) } if (multicodes & getOption("rdbnomics.progress_bar")) { utils::setTxtProgressBar(pb, i) } # Entire dataset with replaced columns cbind(tmpdata, request) }) if (multicodes & getOption("rdbnomics.progress_bar")) { close(pb) } DBlist <- stats::setNames(DBlist, codes) DBlist <- data.table::rbindlist( DBlist, use.names = TRUE, fill = TRUE, idcol = "series_code" ) # Add filtered suffix DBlist[, series_code := paste0(series_code, "_filtered")] DBlist[, series_name := paste(series_name, "(filtered)")] # We rename the column 'frequency' try( setnames( DBlist, "frequency", grep("^[@]*frequency$", colnames(DBdata), value = TRUE) ), silent = TRUE ) tryCatch({ data.table::setnames(DBlist, "period", "original_period") }, error = function(e) { stop( paste0( "The retrieved dataset doesn't have a column named 'period', it's not ", "normal please check ." ), call. = FALSE ) }) # In case of different classes, the class of the column 'original_period' # is set to 'character' if ( inherits(DBdata$original_period, "character") & !inherits(DBlist$original_period, "character") ) { DBlist[, original_period := as.character(original_period)] } if ( !inherits(DBdata$original_period, "character") & inherits(DBlist$original_period, "character") ) { DBdata[, original_period := as.character(original_period)] } tryCatch({ data.table::setnames(DBlist, "period_start_day", "period") }, error = function(e) { stop( paste0( "The retrieved dataset doesn't have a column named ", "'period_start_day', it's not normal please check ." ), call. = FALSE ) }) # Add boolean to distinct be filtered and non-filtered series DBdata[, filtered := FALSE] DBlist[, filtered := TRUE] # For R 3.1 diff_cols <- setdiff(colnames(DBlist), colnames(DBdata)) if (length(diff_cols) > 0) { DBdata[, period_middle_day := as.Date(NA)] } DBdata <- list(DBdata, DBlist) DBdata <- data.table::rbindlist(DBdata, use.names = TRUE, fill = TRUE) } # Additional informations translations if (!is.null(additional_geo_column) & !is.null(additional_geo_mapping)) { for (i in seq_along(additional_geo_mapping)) { addcol <- additional_geo_column[[i]][3] suffix <- "" if (addcol %in% colnames(DBdata)) { suffix <- "_add" newcol <- paste0(addcol, suffix) setnames(additional_geo_mapping[[i]], addcol, newcol) } DBdata <- merge( DBdata, additional_geo_mapping[[i]], by = c("dataset_code", additional_geo_column[[i]][2]), all.x = TRUE, all.y = FALSE, sort = FALSE, allow.cartesian = FALSE ) if (suffix != "") { DBdata[, (addcol) := ifelse(is.na(get(newcol)), get(addcol), get(newcol))] DBdata[, (newcol) := NULL] } } } # We reorder the columns by their names setcolorder(DBdata, sort(colnames(DBdata))) DBdata[] } rdbnomics/R/rdb_providers.R0000644000176200001440000000532713604412577015442 0ustar liggesusers#' Download list of DBnomics providers. #' #' \code{rdb_providers} downloads the list of providers from #' \href{https://db.nomics.world/}{DBnomics}. #' #' By default, the function returns a \code{data.table} #' containing the list of providers from #' \href{https://db.nomics.world/}{DBnomics} with additional informations such as #' the region, the website, etc. #' #' @param code Logical (default \code{FALSE}). If \code{TRUE}, then only the #' providers are returned in a vector. #' @param use_readLines Logical (default \code{FALSE}). If \code{TRUE}, then #' the data are requested and read with the base function \code{readLines} i.e. #' through the default R internet connection. This can be used to get round the #' error \code{Could not resolve host: api.db.nomics.world}. #' @param curl_config Named list (default \code{NULL}). If not #' \code{NULL}, it is used to configure a proxy connection. This #' configuration is passed to the function \code{curl_fetch_memory} of the package #' \pkg{curl}. A temporary \code{curl_handle} object is created internally #' with arguments equal to the provided list in \code{curl_config}.\cr #' For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. #' For available curl options see \code{\link[curl]{curl_options}}, #' \code{names(curl_options())} and #' \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}. #' @return A \code{data.table} or a vector. #' @examples #' \dontrun{ #' rdb_providers() #' #' rdb_providers(code = TRUE) #' #' rdb_providers(use_readLines = TRUE) #' #' rdb_providers(curl_config = list(proxy = "", proxyport = )) #' } #' @seealso \code{\link{rdb_last_updates}} #' @author Sebastien Galais #' @export rdb_providers <- function( code = FALSE, use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config") ) { # Checking arguments check_argument(code, "logical") check_argument(use_readLines, "logical") # Setting API url api_base_url <- getOption("rdbnomics.api_base_url") check_argument(api_base_url, "character") # Setting API version api_version <- getOption("rdbnomics.api_version") check_argument(api_version, c("numeric", "integer")) authorized_version(api_version) providers <- paste0(api_base_url, "/v", api_version, "/providers") providers <- get_data(providers, use_readLines, curl_config) providers <- providers$providers$docs data.table::setDT(providers) if (code) { providers <- providers$code providers <- no_empty_char(providers) providers <- sort(providers) } else { transform_date_timestamp(providers) providers <- providers[order(code)] } providers[] } rdbnomics/R/rdb_last_updates.R0000644000176200001440000000644213604413025016101 0ustar liggesusers#' Download informations about the last DBnomics updates. #' #' \code{rdb_last_updates} downloads informations about the last updates from #' \href{https://db.nomics.world/}{DBnomics}. #' #' By default, the function returns a \code{data.table} #' containing the last 100 updates from #' \href{https://db.nomics.world/}{DBnomics} with additional informations. #' #' @param all Logical (default \code{FALSE}). If \code{TRUE}, then the full #' dataset of the last updates is retrieved. #' @param use_readLines Logical (default \code{FALSE}). If \code{TRUE}, then #' the data are requested and read with the base function \code{readLines} i.e. #' through the default R internet connection. This can be used to get round the #' error \code{Could not resolve host: api.db.nomics.world}. #' @param curl_config Named list (default \code{NULL}). If not #' \code{NULL}, it is used to configure a proxy connection. This #' configuration is passed to the function \code{curl_fetch_memory} of the package #' \pkg{curl}. A temporary \code{curl_handle} object is created internally #' with arguments equal to the provided list in \code{curl_config}.\cr #' For \code{curl_fetch_memory} arguments see \code{\link[curl]{curl_fetch}}. #' For available curl options see \code{\link[curl]{curl_options}}, #' \code{names(curl_options())} and #' \href{https://curl.haxx.se/libcurl/c/curl_easy_setopt.html}{libcurl}. #' @return A \code{data.table}. #' @examples #' \dontrun{ #' rdb_last_updates() #' #' rdb_last_updates(all = TRUE) #' #' rdb_last_updates(use_readLines = TRUE) #' #' rdb_last_updates(curl_config = list(proxy = "", proxyport = )) #' } #' @seealso \code{\link{rdb_providers}} #' @author Sebastien Galais #' @export rdb_last_updates <- function( all = FALSE, use_readLines = getOption("rdbnomics.use_readLines"), curl_config = getOption("rdbnomics.curl_config") ) { # Checking arguments check_argument(all, "logical") check_argument(use_readLines, "logical") # Setting API url api_base_url <- getOption("rdbnomics.api_base_url") check_argument(api_base_url, "character") # Setting API version api_version <- getOption("rdbnomics.api_version") check_argument(api_version, c("numeric", "integer")) authorized_version(api_version) updates <- paste0(api_base_url, "/v", api_version, "/last-updates") updates <- get_data(updates, use_readLines, curl_config) if (api_version == 21) { updates <- updates$datasets data.table::setDT(updates) } else if (api_version == 22){ n <- updates$datasets$num_found lim <- updates$datasets$limit updates <- updates$datasets$docs data.table::setDT(updates) if (all) { sequence <- seq(0, floor(n / lim) * lim, lim) updates <- lapply(sequence, function(x) { link <- paste0( api_base_url, "/v", api_version, "/last-updates?datasets.offset=", x ) dataset <- get_data(link, use_readLines, curl_config) data.table::setDT(dataset$datasets$docs) }) updates <- data.table::rbindlist(updates, use.names = TRUE, fill = TRUE) } } else { stop( paste0("Don't know what to do for API version ", api_version, "."), call. = FALSE ) } transform_date_timestamp(updates) updates[] } rdbnomics/NEWS.md0000644000176200001440000000454413616554077013355 0ustar liggesusers# rdbnomics 0.5.2 * Correction of a bug in the internal function `deploy`. The cases `to_list_length = 1` and `to_list_length = 2` are now well handled (@julia.schmidt, 20200205 forum.db.nomics.world). # rdbnomics 0.5.1 * New argument 'query' for function `rdb()`. * New argument 'api_link' for function `rdb()` to replace `rdb_by_api_link()`. * New internal function `.rdb()` because `rdb_by_api_link()` is deprecated. * New function `dbnomics()` which is used in the vignette (@blu2ego, #2 github). * Small class correction for R 3.1. # rdbnomics 0.5.0 * New filters tool from . * If the retrieved dataset contains columns with codes (like ISO codes, geographic codes, ...), then correspondences are performed to translate these codes if possible. * Internal function `get_data` better handles errors. The message is clearer. # rdbnomics 0.4.7 * Use of `metadata` from the API to download less data. # rdbnomics 0.4.6 * Internal function `deploy` better handles recursive lists. # rdbnomics 0.4.5 * The vignette "rdbnomics-tutorial" is now named "rdbnomics". * `rdb()` and `rdb_...()` functions now have an argument to configure curl. It is also an option of the package. The vignette "rdbnomics" is modified consequently. * `rdb()` and `rdb_by_api_link()` functions return an error if the columns `period` and `period_start_day` don't exist. * `rdb()` function passes argument `provider_code` to `ids` if only `provider_code` is provided. It is considered that the user wants to use `ids` without naming the arguments. * `rdb()` function passes argument `ids` to `mask` if only `provider_code`, `dataset_code` and `ids` are provided. It is considered that the user wants to use `mask` without naming the argument. # rdbnomics 0.4.4 * Change of the API version from 21 to 22. * The vignette "rdbnomics-tutorial" is modified to be backward compatible with R Markdown v1 (i.e. without pandoc or rmarkdown). * The vignette "rdbnomics-tutorial" has an appendix. * New `rdb_providers()` returns the available providers. * New `rdb_last_updates()` shows the last updates. * In the functions, dates and timestamps are transformed using `as.Date()` and `as.POSIXct()`. * `dimensions` in `rdb()` can be a list (@Iwo, #1 gitlab). # rdbnomics 0.4.3 * First release on CRAN. rdbnomics/MD50000644000176200001440000000350413616610265012552 0ustar liggesusersea7bac5280ca6e92edb02da94889c02a *DESCRIPTION e382fd94b131156a8f7c628bdd76dcc8 *NAMESPACE a91776d680f8944051147568704209ab *NEWS.md 5141b95cc468772793f9dc084215383f *R/dbnomics.R a32f71e3fd46e5cf35667d14613cc9f6 *R/dot_rdb.R 479cf12e9b7e5f7a500734ba88675865 *R/rdb.R df0c048ebd28d9c2d402e3396a8dbadc *R/rdb_by_api_link.R 1a91ca82d8d309a64d1ca5eae9597fc8 *R/rdb_last_updates.R ae5d791ae4ac127a6ca17358fad37ea2 *R/rdb_providers.R 4ba920927b28c01085b4c7c202173070 *R/rdbnomics.R d4c8432e0c0760f4cd5b81845afabd7a *R/sysdata.rda 62b49dc1da4e754e60c00bbb6646e2c1 *R/utils.R 39aaba834a2dd721bccc3dcbdcbf737a *R/zzz.R d793796e88c38ccffb506a8f55cb49f6 *README.md b064f45ddabb14f8a586becdf0355cc3 *build/vignette.rds faa2935314b4671ed7183794d2edb021 *inst/doc/rdbnomics.R 8587a8239e22874a02dc5d1f375b2527 *inst/doc/rdbnomics.Rmd 03b3937135f19e92c1f14a13d18f0f12 *inst/doc/rdbnomics.html 51f0fe4504ec8e0c634b448d32216b58 *man/dbnomics.Rd 54193b888f996476a11b1e5968e1ae04 *man/figures/logo.png 4a723f1afc60b97d8c1a03b8e14bb7ee *man/rdb.Rd 8a9ef40c5114f2c0be1c6fae63af9b76 *man/rdb_by_api_link.Rd 90ba31aee2b88d77c3677c98c8e23387 *man/rdb_last_updates.Rd 6962c6209acb27c8a9b545c5ce8b1251 *man/rdb_providers.Rd b34afbed06fa3c99f3883ad3881fa4ea *man/rdbnomics.Rd 326c31d08a11df871813c2aa0128759e *tests/testthat.R 8de9ebd7dab2bbfc9ef5163f10a3fd8b *tests/testthat/test-rdb.R fcbaf04293dfff6555324693fc7dcbdd *tests/testthat/test-rdb_last_updates.R be63d85138d790a464646dbe7650b4b8 *tests/testthat/test-rdb_providers.R e98953a1eb427a74175b91efdad549e1 *vignettes/dbnomics001.png 0c459913b70e2638e3667fece3af2c8a *vignettes/dbnomics002.png de513c0de5c2be3212c475914c98615d *vignettes/dbnomics003.png 34946e93869403ca124b2ed6c5dab526 *vignettes/dbnomics004.png fab6a1c58f5207ef75d20afbf2f987a1 *vignettes/dbnomics005.png 8587a8239e22874a02dc5d1f375b2527 *vignettes/rdbnomics.Rmd rdbnomics/inst/0000755000176200001440000000000013616554345013223 5ustar liggesusersrdbnomics/inst/doc/0000755000176200001440000000000013616554345013770 5ustar liggesusersrdbnomics/inst/doc/rdbnomics.html0000644000176200001440001217765313616554345016664 0ustar liggesusers DBnomics R client

1 DBnomics: the world’s economic database

Explore all the economic data from different providers (national and international statistical institutes, central banks, etc.), for free, following the link db.nomics.world
(N.B.: in the examples, data have already been retrieved on december 11rd 2019).

2 Fetch time series by ids

First, let’s assume that we know which series we want to download. A series identifier (ids) is defined by three values, formatted like this: provider_code/dataset_code/series_code.

2.1 Fetch one series from dataset ‘Unemployment rate’ (ZUTN) of AMECO provider

library(magrittr)
library(dplyr)
library(ggplot2)
library(rdbnomics)
df <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") %>%
  filter(!is.na(value))

In such data.frame (data.table or tibble), you will always find at least ten columns:

  • provider_code
  • dataset_code
  • dataset_name
  • series_code
  • series_name
  • original_period (character string)
  • period (date of the first day of original_period)
  • original_value (character string)
  • value
  • @frequency (harmonized frequency generated by DBnomics)

The other columns depend on the provider and on the dataset. They always come in pairs (for the code and the name). In the data.frame df, you have:

  • unit (code) and Unit (name)
  • geo (code) and Country (name)
  • freq (code) and Frequency (name)
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

In the event that you only use the argument ids, you can drop it and run:

df <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN")

2.2 Fetch two series from dataset ‘Unemployment rate’ (ZUTN) of AMECO provider

df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

2.3 Fetch two series from different datasets of different providers

df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "Eurostat/une_rt_q/Q.SA.TOTAL.PC_ACT.T.EA19")) %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics(legend.text = element_text(size = 7))

3 Fetch time series by mask

The code mask notation is a very concise way to select one or many time series at once.

3.1 Fetch one series from dataset ‘Balance of Payments’ (BOP) of IMF

df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_step(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

In the event that you only use the arguments provider_code, dataset_code and mask, you can drop the name mask and run:

df <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR")

3.2 Fetch two series from dataset ‘Balance of Payments’ (BOP) of IMF

You just have to add a + between two different values of a dimension.

df <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_step(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

3.3 Fetch all series along one dimension from dataset ‘Balance of Payments’ (BOP) of IMF

df <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") %>%
  filter(!is.na(value)) %>%
  arrange(desc(period), REF_AREA) %>%
  head(100)

3.4 Fetch series along multiple dimensions from dataset ‘Balance of Payments’ (BOP) of IMF

df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") %>%
  filter(!is.na(value)) %>%
  group_by(INDICATOR) %>%
  top_n(n = 50, wt = period)

4 Fetch time series by dimensions

Searching by dimensions is a less concise way to select time series than using the code mask, but it works with all the different providers. You have a “Description of series code” at the bottom of each dataset page on the DBnomics website.

4.1 Fetch one value of one dimension from dataset ‘Unemployment rate’ (ZUTN) of AMECO provider

df <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea19")) %>%
  filter(!is.na(value))
# or
# df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19"]}') %>%
#   filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

4.2 Fetch two values of one dimension from dataset ‘Unemployment rate’ (ZUTN) of AMECO provider

df <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea19", "dnk"))) %>%
  filter(!is.na(value))
# or
# df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19", "dnk"]}') %>%
#   filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

4.3 Fetch several values of several dimensions from dataset ‘Doing business’ (DB) of World Bank

df <- rdb("WB", "DB", dimensions = list(country = c("DZ", "PE"), indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"))) %>%
  filter(!is.na(value))
# or
# df <- rdb("WB", "DB", dimensions = '{"country": ["DZ", "PE"], "indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}') %>%
#   filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

5 Fetch time series with a query

The query is a Google-like search that will filter/select time series from a provider’s dataset.

5.1 Fetch one series from dataset ‘WEO by countries’ (WEO) of IMF

df <- rdb("IMF", "WEO", query = "France current account balance percent") %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

5.2 Fetch series from dataset ‘WEO by countries’ (WEO) of IMF

df <- rdb("IMF", "WEO", query = "current account balance percent") %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = `WEO Country`)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  ggtitle("Current account balance (% GDP)") +
  dbnomics(legend.direction = "horizontal")

6 Fetch time series found on the web site

When you don’t know the codes of the dimensions, provider, dataset or series, you can:

  • go to the page of a dataset on DBnomics website, for example Doing Business,

  • select some dimensions by using the input widgets of the left column,

  • click on “Copy API link” in the menu of the “Download” button,

  • use the rdb(api_link = ...) function such as below.

df <- rdb(api_link = "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_step(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

In the event that you only use the argument api_link, you can drop the name and run:

df <- rdb("https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0")

7 Fetch time series from the cart

On the cart page of the DBnomics website, click on “Copy API link” and copy-paste it as an argument of the rdb(api_link = ...) function. Please note that when you update your cart, you have to copy this link again, because the link itself contains the ids of the series in the cart.
df <- rdb(api_link = "https://api.db.nomics.world/v22/series?observations=1&series_ids=BOE/6008/RPMTDDC,BOE/6231/RPMTBVE") %>%
  filter(!is.na(value))
ggplot(df, aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

8 Proxy configuration or connection error Could not resolve host

When using the function rdb, you may come across the following error:

Error in open.connection(con, "rb") :
  Could not resolve host: api.db.nomics.world

To get round this situation, you have two options:

  1. configure curl to use a specific and authorized proxy.

  2. use the default R internet connection i.e. the Internet Explorer proxy defined in internet2.dll.

8.1 Configure curl to use a specific and authorized proxy

In rdbnomics, by default the function curl_fetch_memory (of the package curl) is used to fetch the data. If a specific proxy must be used, it is possible to define it permanently with the package option rdbnomics.curl_config or on the fly through the argument curl_config. Because the object is a named list, its elements are passed to the connection (the curl_handle object created internally with new_handle()) with handle_setopt() before using curl_fetch_memory.

To see the available parameters, run names(curl_options()) in R or visit the website https://curl.haxx.se/libcurl/c/curl_easy_setopt.html. Once they are chosen, you define the curl object as follows:

h <- list(
  proxy = "<proxy>",
  proxyport = <port>,
  proxyusername = "<username>",
  proxypassword = "<password>"
)

8.1.1 Set the connection up for a session

The curl connection can be set up for a session by modifying the following package option:

options(rdbnomics.curl_config = h)

When fetching the data, the following command is executed:

hndl <- curl::new_handle()
curl::handle_setopt(hndl, .list = getOption("rdbnomics.curl_config"))
curl::curl_fetch_memory(url = <...>, handle = hndl)

After configuration, just use the standard functions of rdbnomics e.g.:

df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN")

This option of the package can be disabled with:

options(rdbnomics.curl = NULL)

8.1.2 Use the connection only for a function call

If a complete configuration is not needed but just an “on the fly” execution, then use the argument curl_config of the function rdb:

df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h)

8.2 Use the default R internet connection

To retrieve the data with the default R internet connection, rdbnomics will use the base function readLines.

8.2.1 Set the connection up for a session

To activate this feature for a session, you need to enable an option of the package:

options(rdbnomics.use_readLines = TRUE)

And then use the standard function as follows:

df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN")

This configuration can be disabled with:

options(rdbnomics.use_readLines = FALSE)

8.2.2 Use the connection only for a function call

If you just want to do it once, you may use the argument use_readLines of the function rdb:

df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE)

9 Transform time series with filters

The rdbnomics package can interact with the Time Series Editor of DBnomics to transform time series by applying filters to them.
Available filters are listed on the filters page https://editor.nomics.world/filters.

Here is an example of how to proceed to interpolate two annual time series with a monthly frequency, using a spline interpolation:

filters <- list(
  code = "interpolate",
  parameters = list(frequency = "monthly", method = "spline")
)

The request is then:

df <- rdb(
  ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"),
  filters = filters
)

If you want to apply more than one filter, the filters argument will be a list of valid filters:

filters <- list(
  list(
    code = "interpolate",
    parameters = list(frequency = "monthly", method = "spline")
  ),
  list(
    code = "aggregate",
    parameters = list(frequency = "bi-annual", method = "end_of_period")
  )
)

df <- rdb(
  ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"),
  filters = filters
)

The data.frame (data.table or tibble) columns change a little bit when filters are used. There are two new columns:

  • period_middle_day: the middle day of original_period (can be useful when you compare graphically interpolated series and original ones).
  • filtered (boolean): TRUE if the series is filtered, FALSE otherwise.

The content of two columns are modified:

  • series_code: same as before for original series, but the suffix _filtered is added for filtered series.
  • series_name: same as before for original series, but the suffix (filtered) is added for filtered series.
ggplot(filter(df, !is.na(value)), aes(x = period, y = value, color = series_name)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  dbnomics()

10 Appendix

10.1 ggplot2 function dbnomics() used in the vignette

We show the function dbnomics() as an information.

dbnomics <- function(color_palette = "Set1", ...) {
  # Check if ggplot2 is installed.
  ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE)
  if (inherits(ggplot2_ok, "try-error")) {
    stop(
      "Please run install.packages('ggplot2') to use dbnomics().",
      call. = FALSE
    )
  }

  # DBnomics vignette theme
  result <- list(
    ggplot2::scale_x_date(expand = c(0, 0)),
    ggplot2::scale_y_continuous(
      labels = function(x) { format(x, big.mark = " ") }
    ),
    ggplot2::xlab(""),
    ggplot2::ylab(""),
    ggplot2::theme_bw(),
    ggplot2::theme(
      legend.position = "bottom", legend.direction = "vertical",
      legend.background = ggplot2::element_rect(
        fill = "transparent", colour = NA
      ),
      legend.key = ggplot2::element_blank(),
      panel.background = ggplot2::element_rect(
        fill = "transparent", colour = NA
      ),
      plot.background = ggplot2::element_rect(
        fill = "transparent", colour = NA
      ),
      legend.title = ggplot2::element_blank()
    ),
    ggplot2::theme(...),
    ggplot2::annotate(
      geom = "text", label = "DBnomics <https://db.nomics.world>", 
      x = structure(Inf, class = "Date"), y = -Inf,
      hjust = 1.1, vjust = -0.4, col = "grey", 
      fontface = "italic"
    )
  )

  if (!is.null(color_palette)) {
    result <- c(
      result,
      list(ggplot2::scale_color_brewer(palette = color_palette))
    )
  }

  result
}

  1. Banque de France, https://github.com/s915

  2. CEPREMAP

rdbnomics/inst/doc/rdbnomics.R0000644000176200001440000004463113616554343016101 0ustar liggesusers## ---- echo = FALSE------------------------------------------------------------ library <- function(...) { suppressWarnings( suppressPackageStartupMessages(base::library(..., quietly = TRUE)) ) } ## ----------------------------------------------------------------------------- library(magrittr) library(dplyr) library(ggplot2) library(rdbnomics) ## ---- echo = FALSE------------------------------------------------------------ reorder_cols <- function(x) { cols <- c( "provider_code", "dataset_code", "dataset_name", "series_code", "series_name", "original_period", "period", "original_value", "value", "@frequency" ) if ("unit" %in% colnames(x)) { cols <- c(cols, "unit", "Unit") } if ("geo" %in% colnames(x)) { cols <- c(cols, "geo", "Country") } if ("freq" %in% colnames(x)) { cols <- c(cols, "freq", "Frequency") } cols_add <- setdiff(colnames(x), cols) cols <- c(cols, cols_add) cols <- cols[cols %in% colnames(x)] cols <- match(cols, colnames(x)) dplyr::select(x, cols) } knitr::opts_chunk$set(dev.args = list(bg = "transparent")) dbnomics <- function(color_palette = "Set1", ...) { # Check if ggplot2 is installed. ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) if (inherits(ggplot2_ok, "try-error")) { stop( "Please run install.packages('ggplot2') to use dbnomics().", call. = FALSE ) } # DBnomics vignette theme result <- list( ggplot2::scale_x_date(expand = c(0, 0)), ggplot2::scale_y_continuous( labels = function(x) { format(x, big.mark = " ") } ), ggplot2::xlab(""), ggplot2::ylab(""), ggplot2::theme_bw(), ggplot2::theme( legend.position = "bottom", legend.direction = "vertical", legend.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.key = ggplot2::element_blank(), panel.background = ggplot2::element_rect( fill = "transparent", colour = NA ), plot.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.title = ggplot2::element_blank() ), ggplot2::theme(...), ggplot2::annotate( geom = "text", label = "DBnomics ", x = structure(Inf, class = "Date"), y = -Inf, hjust = 1.1, vjust = -0.4, col = "grey", fontface = "italic" ) ) if (!is.null(color_palette)) { result <- c( result, list(ggplot2::scale_color_brewer(palette = color_palette)) ) } result } display_table <- function(DT) { DT_ok <- FALSE if ( "rmarkdown" %in% installed.packages()[, "Package"] & "DT" %in% installed.packages()[, "Package"] ) { if (rmarkdown::pandoc_available()) { if (rmarkdown::pandoc_version() >= numeric_version("1.12.3")) { DT_ok <- TRUE } } } if (DT_ok) { DT::datatable( DT, rownames = FALSE, options = list(pageLength = 5, scrollX = TRUE) ) } else { dplyr::as.tbl(DT) } } ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df001 ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df002 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "Eurostat/une_rt_q/Q.SA.TOTAL.PC_ACT.T.EA19")) %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df003 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics(legend.text = element_text(size = 7)) ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df004 ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR") ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df005 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") %>% # filter(!is.na(value)) %>% # arrange(desc(period), REF_AREA) %>% # head(100) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df006 ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") %>% # filter(!is.na(value)) %>% # group_by(INDICATOR) %>% # top_n(n = 50, wt = period) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- ungroup(rdbnomics:::rdbnomics_df007) ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea19")) %>% # filter(!is.na(value)) # # or # # df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19"]}') %>% # # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df008 ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea19", "dnk"))) %>% # filter(!is.na(value)) # # or # # df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19", "dnk"]}') %>% # # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df009 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("WB", "DB", dimensions = list(country = c("DZ", "PE"), indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"))) %>% # filter(!is.na(value)) # # or # # df <- rdb("WB", "DB", dimensions = '{"country": ["DZ", "PE"], "indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}') %>% # # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df010 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(series_name, period) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "WEO", query = "France current account balance percent") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df014 ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("IMF", "WEO", query = "current account balance percent") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df015 ## ---- echo = FALSE------------------------------------------------------------ df %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = `WEO Country`)) + geom_line(size = 1.2) + geom_point(size = 2) + ggtitle("Current account balance (% GDP)") + dbnomics(legend.direction = "horizontal") ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb(api_link = "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df011 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(period, series_name) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb("https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb(api_link = "https://api.db.nomics.world/v22/series?observations=1&series_ids=BOE/6008/RPMTDDC,BOE/6231/RPMTBVE") %>% # filter(!is.na(value)) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df012 ## ---- echo = FALSE------------------------------------------------------------ df %<>% mutate( series_name = sapply( series_name, function(y) { paste0( paste0( strsplit(y, "institutions' ")[[1]], collapse = "institutions'\n" ), "\n" ) } ) ) ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(period, series_name) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # Error in open.connection(con, "rb") : # Could not resolve host: api.db.nomics.world ## ---- eval = FALSE------------------------------------------------------------ # h <- list( # proxy = "", # proxyport = , # proxyusername = "", # proxypassword = "" # ) ## ---- eval = FALSE------------------------------------------------------------ # options(rdbnomics.curl_config = h) ## ---- eval = FALSE------------------------------------------------------------ # hndl <- curl::new_handle() # curl::handle_setopt(hndl, .list = getOption("rdbnomics.curl_config")) # curl::curl_fetch_memory(url = <...>, handle = hndl) ## ---- eval = FALSE------------------------------------------------------------ # df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ## ---- eval = FALSE------------------------------------------------------------ # options(rdbnomics.curl = NULL) ## ---- eval = FALSE------------------------------------------------------------ # df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h) ## ---- eval = FALSE------------------------------------------------------------ # options(rdbnomics.use_readLines = TRUE) ## ---- eval = FALSE------------------------------------------------------------ # df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ## ---- eval = FALSE------------------------------------------------------------ # options(rdbnomics.use_readLines = FALSE) ## ---- eval = FALSE------------------------------------------------------------ # df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE) ## ---- eval = FALSE------------------------------------------------------------ # filters <- list( # code = "interpolate", # parameters = list(frequency = "monthly", method = "spline") # ) ## ---- eval = FALSE------------------------------------------------------------ # df <- rdb( # ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), # filters = filters # ) ## ---- eval = FALSE------------------------------------------------------------ # filters <- list( # list( # code = "interpolate", # parameters = list(frequency = "monthly", method = "spline") # ), # list( # code = "aggregate", # parameters = list(frequency = "bi-annual", method = "end_of_period") # ) # ) # # df <- rdb( # ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), # filters = filters # ) ## ---- eval = TRUE, echo = FALSE----------------------------------------------- df <- rdbnomics:::rdbnomics_df013 ## ---- echo = FALSE------------------------------------------------------------ df %>% arrange(filtered, series_name, period) %>% reorder_cols() %>% display_table() ## ---- fig.align = 'center'---------------------------------------------------- ggplot(filter(df, !is.na(value)), aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ## ---- eval = FALSE------------------------------------------------------------ # dbnomics <- function(color_palette = "Set1", ...) { # # Check if ggplot2 is installed. # ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) # if (inherits(ggplot2_ok, "try-error")) { # stop( # "Please run install.packages('ggplot2') to use dbnomics().", # call. = FALSE # ) # } # # # DBnomics vignette theme # result <- list( # ggplot2::scale_x_date(expand = c(0, 0)), # ggplot2::scale_y_continuous( # labels = function(x) { format(x, big.mark = " ") } # ), # ggplot2::xlab(""), # ggplot2::ylab(""), # ggplot2::theme_bw(), # ggplot2::theme( # legend.position = "bottom", legend.direction = "vertical", # legend.background = ggplot2::element_rect( # fill = "transparent", colour = NA # ), # legend.key = ggplot2::element_blank(), # panel.background = ggplot2::element_rect( # fill = "transparent", colour = NA # ), # plot.background = ggplot2::element_rect( # fill = "transparent", colour = NA # ), # legend.title = ggplot2::element_blank() # ), # ggplot2::theme(...), # ggplot2::annotate( # geom = "text", label = "DBnomics ", # x = structure(Inf, class = "Date"), y = -Inf, # hjust = 1.1, vjust = -0.4, col = "grey", # fontface = "italic" # ) # ) # # if (!is.null(color_palette)) { # result <- c( # result, # list(ggplot2::scale_color_brewer(palette = color_palette)) # ) # } # # result # } rdbnomics/inst/doc/rdbnomics.Rmd0000644000176200001440000005457613604711711016422 0ustar liggesusers--- title: "DBnomics R client" author: "Sébastien Galais^[Banque de France, [https://github.com/s915](https://github.com/s915)], Thomas Brand^[CEPREMAP]" output: html_document: highlight: default theme: simplex smart: false toc: true toc_float: true number_sections: true rmarkdown::html_vignette: highlight: default theme: simplex smart: false toc: true toc_float: true number_sections: true vignette: > %\VignetteIndexEntry{DBnomics R client} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- # DBnomics: the world's economic database Explore all the economic data from different providers (national and international statistical institutes, central banks, etc.), for free, following the link [db.nomics.world](https://db.nomics.world) (*N.B.: in the examples, data have already been retrieved on december 11rd 2019*). [![](dbnomics001.png)](https://db.nomics.world) # Fetch time series by `ids` First, let's assume that we know which series we want to download. A series identifier (`ids`) is defined by three values, formatted like this: `provider_code`/`dataset_code`/`series_code`. ## Fetch one series from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, echo = FALSE} library <- function(...) { suppressWarnings( suppressPackageStartupMessages(base::library(..., quietly = TRUE)) ) } ``` ```{r} library(magrittr) library(dplyr) library(ggplot2) library(rdbnomics) ``` ```{r, echo = FALSE} reorder_cols <- function(x) { cols <- c( "provider_code", "dataset_code", "dataset_name", "series_code", "series_name", "original_period", "period", "original_value", "value", "@frequency" ) if ("unit" %in% colnames(x)) { cols <- c(cols, "unit", "Unit") } if ("geo" %in% colnames(x)) { cols <- c(cols, "geo", "Country") } if ("freq" %in% colnames(x)) { cols <- c(cols, "freq", "Frequency") } cols_add <- setdiff(colnames(x), cols) cols <- c(cols, cols_add) cols <- cols[cols %in% colnames(x)] cols <- match(cols, colnames(x)) dplyr::select(x, cols) } knitr::opts_chunk$set(dev.args = list(bg = "transparent")) dbnomics <- function(color_palette = "Set1", ...) { # Check if ggplot2 is installed. ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) if (inherits(ggplot2_ok, "try-error")) { stop( "Please run install.packages('ggplot2') to use dbnomics().", call. = FALSE ) } # DBnomics vignette theme result <- list( ggplot2::scale_x_date(expand = c(0, 0)), ggplot2::scale_y_continuous( labels = function(x) { format(x, big.mark = " ") } ), ggplot2::xlab(""), ggplot2::ylab(""), ggplot2::theme_bw(), ggplot2::theme( legend.position = "bottom", legend.direction = "vertical", legend.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.key = ggplot2::element_blank(), panel.background = ggplot2::element_rect( fill = "transparent", colour = NA ), plot.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.title = ggplot2::element_blank() ), ggplot2::theme(...), ggplot2::annotate( geom = "text", label = "DBnomics ", x = structure(Inf, class = "Date"), y = -Inf, hjust = 1.1, vjust = -0.4, col = "grey", fontface = "italic" ) ) if (!is.null(color_palette)) { result <- c( result, list(ggplot2::scale_color_brewer(palette = color_palette)) ) } result } display_table <- function(DT) { DT_ok <- FALSE if ( "rmarkdown" %in% installed.packages()[, "Package"] & "DT" %in% installed.packages()[, "Package"] ) { if (rmarkdown::pandoc_available()) { if (rmarkdown::pandoc_version() >= numeric_version("1.12.3")) { DT_ok <- TRUE } } } if (DT_ok) { DT::datatable( DT, rownames = FALSE, options = list(pageLength = 5, scrollX = TRUE) ) } else { dplyr::as.tbl(DT) } } ``` ```{r, eval = FALSE} df <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df001 ``` In such data.frame (data.table or tibble), you will always find at least ten columns: - `provider_code` - `dataset_code` - `dataset_name` - `series_code` - `series_name` - `original_period` (character string) - `period` (date of the first day of `original_period`) - `original_value` (character string) - `value` - `@frequency` (harmonized frequency generated by DBnomics) The other columns depend on the provider and on the dataset. They always come in pairs (for the code and the name). In the data.frame `df`, you have: - `unit` (code) and `Unit` (name) - `geo` (code) and `Country` (name) - `freq` (code) and `Frequency` (name) ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` In the event that you only use the argument `ids`, you can drop it and run: ```{r, eval = FALSE} df <- rdb("AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` ## Fetch two series from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, eval = FALSE} df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN")) %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df002 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch two series from different datasets of different providers ```{r, eval = FALSE} df <- rdb(ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "Eurostat/une_rt_q/Q.SA.TOTAL.PC_ACT.T.EA19")) %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df003 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics(legend.text = element_text(size = 7)) ``` # Fetch time series by `mask` The code mask notation is a very concise way to select one or many time series at once. ## Fetch one series from dataset 'Balance of Payments' (BOP) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df004 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ``` In the event that you only use the arguments `provider_code`, `dataset_code` and `mask`, you can drop the name `mask` and run: ```{r, eval = FALSE} df <- rdb("IMF", "BOP", "A.FR.BCA_BP6_EUR") ``` ## Fetch two series from dataset 'Balance of Payments' (BOP) of IMF You just have to add a `+` between two different values of a dimension. ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A.FR+ES.BCA_BP6_EUR") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df005 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch all series along one dimension from dataset 'Balance of Payments' (BOP) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A..BCA_BP6_EUR") %>% filter(!is.na(value)) %>% arrange(desc(period), REF_AREA) %>% head(100) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df006 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ## Fetch series along multiple dimensions from dataset 'Balance of Payments' (BOP) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "BOP", mask = "A.FR.BCA_BP6_EUR+IA_BP6_EUR") %>% filter(!is.na(value)) %>% group_by(INDICATOR) %>% top_n(n = 50, wt = period) ``` ```{r, eval = TRUE, echo = FALSE} df <- ungroup(rdbnomics:::rdbnomics_df007) ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` # Fetch time series by `dimensions` Searching by `dimensions` is a less concise way to select time series than using the code `mask`, but it works with all the different providers. You have a "*Description of series code*" at the bottom of each dataset page on the [DBnomics website](https://db.nomics.world). ## Fetch one value of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, eval = FALSE} df <- rdb("AMECO", "ZUTN", dimensions = list(geo = "ea19")) %>% filter(!is.na(value)) # or # df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19"]}') %>% # filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df008 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch two values of one dimension from dataset 'Unemployment rate' (ZUTN) of AMECO provider ```{r, eval = FALSE} df <- rdb("AMECO", "ZUTN", dimensions = list(geo = c("ea19", "dnk"))) %>% filter(!is.na(value)) # or # df <- rdb("AMECO", "ZUTN", dimensions = '{"geo": ["ea19", "dnk"]}') %>% # filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df009 ``` ```{r, echo = FALSE} df %>% arrange(series_code, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch several values of several dimensions from dataset 'Doing business' (DB) of World Bank ```{r, eval = FALSE} df <- rdb("WB", "DB", dimensions = list(country = c("DZ", "PE"), indicator = c("ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"))) %>% filter(!is.na(value)) # or # df <- rdb("WB", "DB", dimensions = '{"country": ["DZ", "PE"], "indicator": ["ENF.CONT.COEN.COST.ZS", "IC.REG.COST.PC.FE.ZS"]}') %>% # filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df010 ``` ```{r, echo = FALSE} df %>% arrange(series_name, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` # Fetch time series with a `query` The query is a Google-like search that will filter/select time series from a provider's dataset. ## Fetch one series from dataset 'WEO by countries' (WEO) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "WEO", query = "France current account balance percent") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df014 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` ## Fetch series from dataset 'WEO by countries' (WEO) of IMF ```{r, eval = FALSE} df <- rdb("IMF", "WEO", query = "current account balance percent") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df015 ``` ```{r, echo = FALSE} df %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = `WEO Country`)) + geom_line(size = 1.2) + geom_point(size = 2) + ggtitle("Current account balance (% GDP)") + dbnomics(legend.direction = "horizontal") ``` # Fetch time series found on the web site When you don't know the codes of the dimensions, provider, dataset or series, you can: - go to the page of a dataset on [DBnomics website](https://db.nomics.world), for example [Doing Business](https://db.nomics.world/WB/DB), - select some dimensions by using the input widgets of the left column, ![](dbnomics002.png) - click on "*Copy API link*" in the menu of the "*Download*" button, ![](dbnomics003.png) - use the `rdb(api_link = ...)` function such as below. ```{r, eval = FALSE} df <- rdb(api_link = "https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df011 ``` ```{r, echo = FALSE} df %>% arrange(period, series_name) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_step(size = 1.2) + geom_point(size = 2) + dbnomics() ``` In the event that you only use the argument `api_link`, you can drop the name and run: ```{r, eval = FALSE} df <- rdb("https://api.db.nomics.world/v22/series/WB/DB?dimensions=%7B%22country%22%3A%5B%22FR%22%2C%22IT%22%2C%22ES%22%5D%7D&q=IC.REG.PROC.FE.NO&observations=1&format=json&align_periods=1&offset=0&facets=0") ``` # Fetch time series from the cart On the cart page of the [DBnomics website](https://db.nomics.world), click on "*Copy API link*" and copy-paste it as an argument of the `rdb(api_link = ...)` function. Please note that when you update your cart, you have to copy this link again, because the link itself contains the ids of the series in the cart.
![](dbnomics005.png)
```{r, eval = FALSE} df <- rdb(api_link = "https://api.db.nomics.world/v22/series?observations=1&series_ids=BOE/6008/RPMTDDC,BOE/6231/RPMTBVE") %>% filter(!is.na(value)) ``` ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df012 ``` ```{r, echo = FALSE} df %<>% mutate( series_name = sapply( series_name, function(y) { paste0( paste0( strsplit(y, "institutions' ")[[1]], collapse = "institutions'\n" ), "\n" ) } ) ) ``` ```{r, echo = FALSE} df %>% arrange(period, series_name) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(df, aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` # Proxy configuration or connection error `Could not resolve host` When using the function `rdb`, you may come across the following error: ```{r, eval = FALSE} Error in open.connection(con, "rb") : Could not resolve host: api.db.nomics.world ``` To get round this situation, you have two options: 1. configure **curl** to use a specific and authorized proxy. 2. use the default R internet connection i.e. the Internet Explorer proxy defined in *internet2.dll*. ## Configure **curl** to use a specific and authorized proxy In **rdbnomics**, by default the function `curl_fetch_memory` (of the package **curl**) is used to fetch the data. If a specific proxy must be used, it is possible to define it permanently with the package option `rdbnomics.curl_config` or on the fly through the argument `curl_config`. Because the object is a named list, its elements are passed to the connection (the `curl_handle` object created internally with `new_handle()`) with `handle_setopt()` before using `curl_fetch_memory`. To see the available parameters, run `names(curl_options())` in *R* or visit the website https://curl.haxx.se/libcurl/c/curl_easy_setopt.html. Once they are chosen, you define the curl object as follows: ```{r, eval = FALSE} h <- list( proxy = "", proxyport = , proxyusername = "", proxypassword = "" ) ``` ### Set the connection up for a session The curl connection can be set up for a session by modifying the following package option: ```{r, eval = FALSE} options(rdbnomics.curl_config = h) ``` When fetching the data, the following command is executed: ```{r, eval = FALSE} hndl <- curl::new_handle() curl::handle_setopt(hndl, .list = getOption("rdbnomics.curl_config")) curl::curl_fetch_memory(url = <...>, handle = hndl) ``` After configuration, just use the standard functions of **rdbnomics** e.g.: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` This option of the package can be disabled with: ```{r, eval = FALSE} options(rdbnomics.curl = NULL) ``` ### Use the connection only for a function call If a complete configuration is not needed but just an "on the fly" execution, then use the argument `curl_config` of the function `rdb`: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", curl_config = h) ``` ## Use the default R internet connection To retrieve the data with the default R internet connection, **rdbnomics** will use the base function `readLines`. ### Set the connection up for a session To activate this feature for a session, you need to enable an option of the package: ```{r, eval = FALSE} options(rdbnomics.use_readLines = TRUE) ``` And then use the standard function as follows: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN") ``` This configuration can be disabled with: ```{r, eval = FALSE} options(rdbnomics.use_readLines = FALSE) ``` ### Use the connection only for a function call If you just want to do it once, you may use the argument `use_readLines` of the function `rdb`: ```{r, eval = FALSE} df1 <- rdb(ids = "AMECO/ZUTN/EA19.1.0.0.0.ZUTN", use_readLines = TRUE) ``` # Transform time series with filters The **rdbnomics** package can interact with the *Time Series Editor* of DBnomics to transform time series by applying filters to them. Available filters are listed on the filters page [https://editor.nomics.world/filters](https://editor.nomics.world/filters). Here is an example of how to proceed to interpolate two annual time series with a monthly frequency, using a spline interpolation: ```{r, eval = FALSE} filters <- list( code = "interpolate", parameters = list(frequency = "monthly", method = "spline") ) ``` The request is then: ```{r, eval = FALSE} df <- rdb( ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), filters = filters ) ``` If you want to apply more than one filter, the `filters` argument will be a list of valid filters: ```{r, eval = FALSE} filters <- list( list( code = "interpolate", parameters = list(frequency = "monthly", method = "spline") ), list( code = "aggregate", parameters = list(frequency = "bi-annual", method = "end_of_period") ) ) df <- rdb( ids = c("AMECO/ZUTN/EA19.1.0.0.0.ZUTN", "AMECO/ZUTN/DNK.1.0.0.0.ZUTN"), filters = filters ) ``` The data.frame (data.table or tibble) columns change a little bit when filters are used. There are two new columns: - `period_middle_day`: the middle day of `original_period` (can be useful when you compare graphically interpolated series and original ones). - `filtered` (boolean): `TRUE` if the series is filtered, `FALSE` otherwise. The content of two columns are modified: - `series_code`: same as before for original series, but the suffix `_filtered` is added for filtered series. - `series_name`: same as before for original series, but the suffix ` (filtered)` is added for filtered series. ```{r, eval = TRUE, echo = FALSE} df <- rdbnomics:::rdbnomics_df013 ``` ```{r, echo = FALSE} df %>% arrange(filtered, series_name, period) %>% reorder_cols() %>% display_table() ``` ```{r, fig.align = 'center'} ggplot(filter(df, !is.na(value)), aes(x = period, y = value, color = series_name)) + geom_line(size = 1.2) + geom_point(size = 2) + dbnomics() ``` # Appendix ## ggplot2 function `dbnomics()` used in the vignette We show the function `dbnomics()` as an information. ```{r, eval = FALSE} dbnomics <- function(color_palette = "Set1", ...) { # Check if ggplot2 is installed. ggplot2_ok <- try(utils::packageVersion("ggplot2"), silent = TRUE) if (inherits(ggplot2_ok, "try-error")) { stop( "Please run install.packages('ggplot2') to use dbnomics().", call. = FALSE ) } # DBnomics vignette theme result <- list( ggplot2::scale_x_date(expand = c(0, 0)), ggplot2::scale_y_continuous( labels = function(x) { format(x, big.mark = " ") } ), ggplot2::xlab(""), ggplot2::ylab(""), ggplot2::theme_bw(), ggplot2::theme( legend.position = "bottom", legend.direction = "vertical", legend.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.key = ggplot2::element_blank(), panel.background = ggplot2::element_rect( fill = "transparent", colour = NA ), plot.background = ggplot2::element_rect( fill = "transparent", colour = NA ), legend.title = ggplot2::element_blank() ), ggplot2::theme(...), ggplot2::annotate( geom = "text", label = "DBnomics ", x = structure(Inf, class = "Date"), y = -Inf, hjust = 1.1, vjust = -0.4, col = "grey", fontface = "italic" ) ) if (!is.null(color_palette)) { result <- c( result, list(ggplot2::scale_color_brewer(palette = color_palette)) ) } result } ```