nanotime/0000755000176200001440000000000014740327722012074 5ustar liggesusersnanotime/tests/0000755000176200001440000000000014506433733013236 5ustar liggesusersnanotime/tests/POSIXt.R0000644000176200001440000000047713023330507014443 0ustar liggesusers library(nanotime) format(nanotime(Sys.time()), lcltzstr="America/Chicago", tgttzstr="America/Chicago") format(nanotime(as.POSIXlt(Sys.time())), lcltzstr="America/Chicago", tgttzstr="America/Chicago") format(nanotime(Sys.Date()), lcltzstr="America/Chicago", tgttzstr="America/Chicago") nanotime/tests/data.frame.R0000644000176200001440000000142013713656775015374 0ustar liggesusers library(nanotime) set.seed(42) N <- 300 shine <- nanotime(Sys.time()) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- nanotime(Sys.time()) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) if (requireNamespace("data.table", quietly=TRUE)) { suppressMessages(library(data.table)) suppressMessages(library(bit64)) raw <- data.table(shine=shine, rain=rain) df <- data.frame(val=c(rain,shine), key=rep(c("rain", "shine"), each=N+1)) head(df) ## now on differences ddf <- data.frame(val=as.numeric(c(diff(rain),diff(shine))), # need to cast to numeric after diffs key=rep(c("rain", "shine"), each=N)) head(ddf) ## simpler data.frame, inserts 'formatted' newdf <- data.frame(rain=rain, shine=shine) head(newdf) } nanotime/tests/simpleTests.R0000644000176200001440000000201514506433733015673 0ustar liggesusers library(nanotime) z <- RcppCCTZ:::parseDouble("1970-01-01T00:00:00.000000001+00:00") cat("z is: ") print(z) x <- nanotime("1970-01-01T00:00:00.000000001+00:00") cat("x is: ") print(x) format(x) cat("x+1 is: ") x <- x + 1 print(x) format(x) cat("y is: ") y <- nanotime(z) print(y) #print(class(y)) format(y) cat("y+1 is: ") y <- y + 1 print(y) format(y) print(x == y) od <- getOption("digits.secs") options("digits.secs"=6) as.POSIXct(x) as.POSIXct(x+1000) as.POSIXlt(x) as.POSIXlt(x+1000) as.Date(x) as.Date(x, tz="UTC") options("digits.secs"=od) y <- nanotime(1L) # integer, may dispatch via nanotime.numeric print(y) y <- nanotime(1) # numeric print(y) ## v <- nanotime:::nanotime.default(1) # forced call, gets imprecise value ## print(v) options("nanotimeFormat"="%Y-%m-%d %H:%M:%S") format(x <- nanotime("1970-01-01 00:00:00")) options("nanotimeFormat"="%Y-%m-%d %H:%M:%E*S") format(x <- nanotime("1970-01-01 00:00:00.123456789")) options("nanotimeFormat"="%Y-%m-%d %H:%M:%E*S%Ez") # default cat("Done\n") nanotime/tests/tinytest.R0000644000176200001440000000077713722745304015256 0ustar liggesusers if (requireNamespace("tinytest", quietly=TRUE) && utils::packageVersion("tinytest") >= "1.0.0") { ## Set a seed to make the test deterministic set.seed(42) ## R makes us to this Sys.setenv("R_TESTS"="") ## there are several more granular ways to test files in a tinytest directory, ## see its package vignette; tests can also run once the package is installed ## using the same command `test_package(pkgName)`, or by director or file tinytest::test_package("nanotime") } nanotime/tests/zooTests.R0000644000176200001440000000056713023270367015216 0ustar liggesusers library(nanotime) suppressMessages(library(zoo)) set.seed(42) x <- 100 + cumsum(rnorm(10)) y <- 100 + cumsum(rnorm(10)) mat <- cbind(x, y) now <- Sys.Date() z <- zoo(mat, now + 0:9) z now <- Sys.time() z <- zoo(mat, now + 0:9) z now <- nanotime(Sys.time()) z <- zoo(mat, now + 11*(0:9)) # inc. by 11 to more visible, 1 works too z nanotime/MD50000644000176200001440000000743314740327722012413 0ustar liggesusersaf5d253f474daa9235db1bdf45e005a1 *ChangeLog df10d162e402a840c740258685a46525 *DESCRIPTION f349dc361de2c1a48c65e6af2c5f7e1f *NAMESPACE d0e5f558664e47ad9849a0a8c0917c4f *R/RcppExports.R 9d122087a3def1d637c75968740e157d *R/nanoduration.R 46489eee3d93d706f1ab095f88d99c9f *R/nanoival.R 27723524500edbc441429058d2870910 *R/nanoperiod.R 194d9dbdf840f848a872ed108bb8370f *R/nanotime.R a92cd6caad33c2ab0445bf6208a85206 *README.md ef052e127055a5770c320c6115fb8ad0 *build/vignette.rds 5e2d19193e19de97094be5c8e1475da1 *cleanup 726b20da634fe98aa451eb12bd46959f *demo/00Index 524ee00e164d537a07a28be1f0cfb8ee *demo/nanosecondDelayExample.R dfe26df0c9ba8ad3b30cf84c21ddb9f0 *inst/NEWS.Rd f6411e74660ca98c5c9c0f6a3684cf21 *inst/doc/nanotime-introduction.Rnw bb984c4c9fdbfb23d4a5ce5556fe2de3 *inst/doc/nanotime-introduction.pdf adef692683d6f7ce9ffee8b6865d25ec *inst/include/nanotime/duration.hpp a9a428be2c0d0c284a7bc45639e3b6a0 *inst/include/nanotime/globals.hpp e25cee68302afbd4f5bc70a7639e2d2c *inst/include/nanotime/interval.hpp b58539199b6fcd48d5d3f57f68dd471b *inst/include/nanotime/period.hpp a13eea50f9badce56334241a50681f1c *inst/include/nanotime/pseudovector.hpp fafda05ad8776c7de2c8c18651a005ef *inst/include/nanotime/utilities.hpp 2ad49f5aaf90657b593f9e2762025a13 *inst/tinytest/test_data.frame.R 40a0ec652117210b75f2615b69e5b69d *inst/tinytest/test_data.table.R 9896774341556f8f92aebca6ae6b0232 *inst/tinytest/test_nanoduration.R 08b5d03fc4f060c49a83cb31d98922a5 *inst/tinytest/test_nanoival.R 22cefaf58fdaca58c3c22c33bad868cb *inst/tinytest/test_nanoperiod.R 6da7bc0c7b98be42a14476e2ff7c25c0 *inst/tinytest/test_nanotime.R c0e44816ea79a16af48d3568a1a763c9 *inst/tinytest/test_ops.R 985688e5b84e698baddf7b7e013194ea *inst/tinytest/test_xts.R ce988f09bb89783380d2cf72c0577f40 *inst/tinytest/test_zoo.R c881528535bf44cd672760b9d3e11fa3 *man/all.equal.nanoduration.Rd cd85072a1633e78678f5e7c0ef08e6b0 *man/all.equal.nanoival.Rd 092f3c40f2ec232f0ff633199b1dced4 *man/all.equal.nanoperiod.Rd 67ea3efd6fff04887004caf3ae3b07ea *man/all.equal.nanotime.Rd df466ea394744f11ed3323d2102279d5 *man/is.unsorted-nanoival-method.Rd 4e1ca21fcf9d2ebd6097a55a2d99d3e6 *man/nano_year.Rd ec0df853748b4efd818d49862c1aeb64 *man/nanoduration.Rd 2a3cad0702180a6ae5d227ce57d24ece *man/nanoival.Rd 97cb9a083b30d37b92a7cf2df0a4a34d *man/nanoperiod.Rd b88194e5cc07668fdcdae537f94fdb6b *man/nanoperiod.month.Rd e45622ec3b1ddd9192e2a22b0055bcb7 *man/nanotime.Rd 784605b1b089aee1c9bc078683bed7d3 *man/rep-nanoduration-method.Rd 9608e24a432294bc0623ce608305b44f *man/rep-nanoival-method.Rd 537777f3c7e989dbe97f8def8717710a *man/rep-nanoperiod-method.Rd 78612f4ed57aa6c9eca664cf2cc4d1c8 *man/rep-nanotime-method.Rd 89f650bf096d03511cad102b051c8b57 *man/rounding.Rd 91b842a9b6b872593dd936ae6601d42b *man/seq-nanoival-method.Rd dc0abaddeca76a45f2c7bfecc8f4b89b *man/seq.nanoduration.Rd 85133c918e850455542a54660f211c6d *man/seq.nanotime.Rd 78f5cf6b044e00166c73e165e82d20d5 *man/set_operations.Rd 28ff2a81b9f145882a904c265ca8b56d *man/sort-nanoival-method.Rd 5924e7d45cdd5fc156ed03ec09584359 *src/Makevars 5924e7d45cdd5fc156ed03ec09584359 *src/Makevars.win 802357aec14ee107e79036ad7546eb8a *src/RcppExports.cpp 335131307ca491c6a7fd435f65028f16 *src/duration.cpp c7f11bdc18ef54f1d61d662a4b907f47 *src/interval.cpp dc36c0c1a7b65733dcbd75e3d2d58493 *src/nanotime.cpp 3d8f8a9488e48aa2b6ccd5ad4b2f9987 *src/period.cpp ed8fe9cef2698c95c4109862a5a02e37 *src/rounding.cpp 4ce68f543c2378a92e4940c057e825fe *src/strnlen.cpp 22fdad0781464eb37925e754e70a041a *tests/POSIXt.R e958ebec4bc936256837695de174e3da *tests/data.frame.R 673772e8aa1f2db67364a1adcdece41c *tests/simpleTests.R 2b1891b86303f721d20555599d42b0af *tests/tinytest.R 988d5f8134b41899d48aa1c6ae939042 *tests/zooTests.R dff1a3abb31a8ca44c16fdbfa9c85da4 *vignettes/nanotime-intro.pdf f6411e74660ca98c5c9c0f6a3684cf21 *vignettes/nanotime-introduction.Rnw nanotime/R/0000755000176200001440000000000014737237252012301 5ustar liggesusersnanotime/R/RcppExports.R0000644000176200001440000002044114670020720014700 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 duration_from_string_impl <- function(str) { .Call(`_nanotime_duration_from_string_impl`, str) } duration_to_string_impl <- function(dur) { .Call(`_nanotime_duration_to_string_impl`, dur) } duration_is_na_impl <- function(dur) { .Call(`_nanotime_duration_is_na_impl`, dur) } make_duration_impl <- function(h_nv, m_nv, s_nv, n_nv) { .Call(`_nanotime_make_duration_impl`, h_nv, m_nv, s_nv, n_nv) } nanoduration_subset_numeric_impl <- function(v, idx) { .Call(`_nanotime_nanoduration_subset_numeric_impl`, v, idx) } nanoduration_subset_logical_impl <- function(v, idx_p) { .Call(`_nanotime_nanoduration_subset_logical_impl`, v, idx_p) } nanoival_intersect_idx_time_interval_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_intersect_idx_time_interval_impl`, nv1, nv2) } nanoival_intersect_idx_time_interval_logical_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_intersect_idx_time_interval_logical_impl`, nv1, nv2) } nanoival_intersect_time_interval_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_intersect_time_interval_impl`, nv1, nv2) } nanoival_setdiff_time_interval_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_setdiff_time_interval_impl`, nv1, nv2) } nanoival_union_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_union_impl`, nv1, nv2) } nanoival_intersect_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_intersect_impl`, nv1, nv2) } nanoival_setdiff_impl <- function(nv1, nv2) { .Call(`_nanotime_nanoival_setdiff_impl`, nv1, nv2) } nanoival_is_unsorted_impl <- function(nvec, strictlyvec) { .Call(`_nanotime_nanoival_is_unsorted_impl`, nvec, strictlyvec) } nanoival_sort_impl <- function(nvec, decreasingvec) { .Call(`_nanotime_nanoival_sort_impl`, nvec, decreasingvec) } nanoival_sort_impl2 <- function(nvec, decreasing) { .Call(`_nanotime_nanoival_sort_impl2`, nvec, decreasing) } nanoival_lt_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_lt_impl`, n1, n2) } nanoival_le_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_le_impl`, n1, n2) } nanoival_gt_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_gt_impl`, n1, n2) } nanoival_ge_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_ge_impl`, n1, n2) } nanoival_eq_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_eq_impl`, n1, n2) } nanoival_ne_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_ne_impl`, n1, n2) } nanoival_plus_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_plus_impl`, n1, n2) } nanoival_minus_impl <- function(n1, n2) { .Call(`_nanotime_nanoival_minus_impl`, n1, n2) } nanoival_setdiff_idx_time_interval_impl <- function(nv1, cv2) { .Call(`_nanotime_nanoival_setdiff_idx_time_interval_impl`, nv1, cv2) } nanoival_new_impl <- function(sv, ev, sopenv, eopenv) { .Call(`_nanotime_nanoival_new_impl`, sv, ev, sopenv, eopenv) } nanoival_get_start_impl <- function(cv) { .Call(`_nanotime_nanoival_get_start_impl`, cv) } nanoival_get_end_impl <- function(cv) { .Call(`_nanotime_nanoival_get_end_impl`, cv) } nanoival_get_sopen_impl <- function(cv) { .Call(`_nanotime_nanoival_get_sopen_impl`, cv) } nanoival_get_eopen_impl <- function(cv) { .Call(`_nanotime_nanoival_get_eopen_impl`, cv) } nanoival_isna_impl <- function(cv) { .Call(`_nanotime_nanoival_isna_impl`, cv) } nanoival_make_impl <- function(nt_v, tz_v) { .Call(`_nanotime_nanoival_make_impl`, nt_v, tz_v) } nanoival_subset_numeric_impl <- function(v, idx) { .Call(`_nanotime_nanoival_subset_numeric_impl`, v, idx) } nanoival_subset_logical_impl <- function(v, idx_p) { .Call(`_nanotime_nanoival_subset_logical_impl`, v, idx_p) } nanotime_wday_impl <- function(tm_v, tz_v) { .Call(`_nanotime_nanotime_wday_impl`, tm_v, tz_v) } nanotime_mday_impl <- function(tm_v, tz_v) { .Call(`_nanotime_nanotime_mday_impl`, tm_v, tz_v) } nanotime_month_impl <- function(tm_v, tz_v) { .Call(`_nanotime_nanotime_month_impl`, tm_v, tz_v) } nanotime_year_impl <- function(tm_v, tz_v) { .Call(`_nanotime_nanotime_year_impl`, tm_v, tz_v) } nanotime_make_impl <- function(nt_v, tz_v) { .Call(`_nanotime_nanotime_make_impl`, nt_v, tz_v) } nanotime_subset_numeric_impl <- function(v, idx) { .Call(`_nanotime_nanotime_subset_numeric_impl`, v, idx) } nanotime_subset_logical_impl <- function(v, idx_p) { .Call(`_nanotime_nanotime_subset_logical_impl`, v, idx_p) } period_from_string_impl <- function(str) { .Call(`_nanotime_period_from_string_impl`, str) } period_from_parts_impl <- function(months_v, days_v, dur_v) { .Call(`_nanotime_period_from_parts_impl`, months_v, days_v, dur_v) } period_to_string_impl <- function(prd) { .Call(`_nanotime_period_to_string_impl`, prd) } period_from_integer64_impl <- function(i64) { .Call(`_nanotime_period_from_integer64_impl`, i64) } period_from_integer_impl <- function(iint) { .Call(`_nanotime_period_from_integer_impl`, iint) } period_from_double_impl <- function(dbl) { .Call(`_nanotime_period_from_double_impl`, dbl) } plus_period_period_impl <- function(e1_nv, e2_nv) { .Call(`_nanotime_plus_period_period_impl`, e1_nv, e2_nv) } minus_period_impl <- function(e1_cv) { .Call(`_nanotime_minus_period_impl`, e1_cv) } minus_period_period_impl <- function(e1_cv, e2_cv) { .Call(`_nanotime_minus_period_period_impl`, e1_cv, e2_cv) } eq_period_period_impl <- function(e1_p, e2_p) { .Call(`_nanotime_eq_period_period_impl`, e1_p, e2_p) } ne_period_period_impl <- function(e1_p, e2_p) { .Call(`_nanotime_ne_period_period_impl`, e1_p, e2_p) } plus_period_integer64_impl <- function(e1_cv, e2_nv) { .Call(`_nanotime_plus_period_integer64_impl`, e1_cv, e2_nv) } minus_period_integer64_impl <- function(e1_cv, e2_nv) { .Call(`_nanotime_minus_period_integer64_impl`, e1_cv, e2_nv) } multiplies_period_integer64_impl <- function(e1_cv, e2_nv) { .Call(`_nanotime_multiplies_period_integer64_impl`, e1_cv, e2_nv) } divides_period_integer64_impl <- function(e1_cv, e2_nv) { .Call(`_nanotime_divides_period_integer64_impl`, e1_cv, e2_nv) } multiplies_period_double_impl <- function(e1_cv, e2_nv) { .Call(`_nanotime_multiplies_period_double_impl`, e1_cv, e2_nv) } divides_period_double_impl <- function(e1_cv, e2_nv) { .Call(`_nanotime_divides_period_double_impl`, e1_cv, e2_nv) } minus_integer64_period_impl <- function(e1_nv, e2_cv) { .Call(`_nanotime_minus_integer64_period_impl`, e1_nv, e2_cv) } plus_nanotime_period_impl <- function(e1_nv, e2_cv, tz_v) { .Call(`_nanotime_plus_nanotime_period_impl`, e1_nv, e2_cv, tz_v) } minus_nanotime_period_impl <- function(e1_nv, e2_cv, tz_v) { .Call(`_nanotime_minus_nanotime_period_impl`, e1_nv, e2_cv, tz_v) } plus_nanoival_period_impl <- function(e1_cv, e2_cv, tz_v) { .Call(`_nanotime_plus_nanoival_period_impl`, e1_cv, e2_cv, tz_v) } minus_nanoival_period_impl <- function(e1_cv, e2_cv, tz_v) { .Call(`_nanotime_minus_nanoival_period_impl`, e1_cv, e2_cv, tz_v) } period_month_impl <- function(e_n) { .Call(`_nanotime_period_month_impl`, e_n) } period_day_impl <- function(e_n) { .Call(`_nanotime_period_day_impl`, e_n) } period_duration_impl <- function(e_n) { .Call(`_nanotime_period_duration_impl`, e_n) } period_isna_impl <- function(cv) { .Call(`_nanotime_period_isna_impl`, cv) } period_seq_from_to_impl <- function(from_nv, to_nv, by_cv, tz) { .Call(`_nanotime_period_seq_from_to_impl`, from_nv, to_nv, by_cv, tz) } period_seq_from_length_impl <- function(from_nv, by_cv, n_nv, tz) { .Call(`_nanotime_period_seq_from_length_impl`, from_nv, by_cv, n_nv, tz) } period_subset_numeric_impl <- function(v, idx) { .Call(`_nanotime_period_subset_numeric_impl`, v, idx) } period_subset_logical_impl <- function(v, idx_p) { .Call(`_nanotime_period_subset_logical_impl`, v, idx_p) } ceiling_tz_impl <- function(nt_v, prd_v, orig_v, tz_v) { .Call(`_nanotime_ceiling_tz_impl`, nt_v, prd_v, orig_v, tz_v) } ceiling_impl <- function(nt_v, dur_v, orig_v) { .Call(`_nanotime_ceiling_impl`, nt_v, dur_v, orig_v) } floor_tz_impl <- function(nt_v, prd_v, orig_v, tz_v) { .Call(`_nanotime_floor_tz_impl`, nt_v, prd_v, orig_v, tz_v) } floor_impl <- function(nt_v, dur_v, orig_v) { .Call(`_nanotime_floor_impl`, nt_v, dur_v, orig_v) } nanotime/R/nanoduration.R0000644000176200001440000006345714633656052015142 0ustar liggesusers##' @rdname nanoduration setClass("nanoduration", contains = "integer64") ##' Duration type with nanosecond precision ##' ##' The type \code{nanoduration} is a length of time (implemented as ##' an S4 class) with nanosecond precision. It is a count of ##' nanoseconds and may be negative. The expected arithmetic ##' operations are provided, including sequence generation. ##' ##' A \code{nanoduration} can be constructed with the function ##' \code{as.nanoduration} which can take the types \code{integer64}, ##' \code{integer} and \code{numeric} (all indicating the count in ##' nanosecond units) or the type \code{character}. ##' ##' It can also be constructed by specifying with individual arguments ##' the hours, minutes, seconds and nanoseconds with a call to ##' \code{nanoduration}. ##' ##' A \code{nanoduration} is displayed as hours, minutes, seconds and ##' nanoseconds like this: \code{110:12:34.123_453_001}. The nanosecond ##' precision displayed is adjusted as necessary, so e.g. 1 second is ##' displayed as \code{00:00:01}. ##' ##' @param hours number of hours ##' @param minutes number of minutes ##' @param seconds number of seconds ##' @param nanoseconds number of nanoseconds ##' @param x a \code{nanoduration} object ##' @param ... further arguments passed to or from methods. ##' @param e1 Operand of class \code{nanoival} ##' @param e2 Operand of class \code{nanoival} ##' @param object argument for method \code{show} ##' @param i index specifying elements to extract or replace. ##' @param j Required for \code{[} signature but ignored here ##' @param drop Required for \code{[} signature but ignored here ##' @param value argument for \code{nanoduration-class} ##' @param na.rm if \code{TRUE} NA values are removed for the ##' computation ##' @param quote indicates if the output of \code{print} should be ##' quoted ##' @return A nanoduration object ##' @author Dirk Eddelbuettel ##' @author Leonardo Silvestri ##' @examples ##' ## constructors: ##' nanoduration(hours=10, minutes=3, seconds=2, nanoseconds=999999999) ##' as.nanoduration("10:03:02.999_999_999") ##' as.nanoduration(36182999999999) ##' ##' ## arithmetic: ##' as.nanoduration(10e9) - as.nanoduration(9e9) ##' as.nanoduration(10e9) + as.nanoduration(-9e9) ##' as.nanoduration("24:00:00") / 2 ##' as.nanoduration("24:00:00") / as.nanoduration("12:00:00") ##' ##' ## comparison: ##' as.nanoduration("10:03:02.999_999_999") == 36182999999999 ##' as.nanoduration("10:03:02.999_999_999") > as.nanoduration("10:03:02.999_999_998") ##' as.nanoduration("10:03:02.999_999_998") < "10:03:02.999_999_999" ##' ##' @seealso ##' \code{\link{nanotime}} ##' ##' @aliases *,ANY,nanoduration-method ##' @aliases *,nanoduration,ANY-method ##' @aliases *,nanoduration,nanoduration-method ##' @aliases +,ANY,nanoduration-method ##' @aliases /,ANY,nanoduration-method ##' @aliases /,nanoduration,ANY-method ##' @aliases Complex,nanoduration-method ##' @aliases Logic,ANY,nanoduration-method ##' @aliases Logic,nanoduration,ANY-method ##' @aliases Logic,nanoduration,nanoduration-method ##' @aliases Math2,nanoduration-method ##' @aliases Math,nanoduration-method ##' @aliases Summary,nanoduration-method ##' ##' @rdname nanoduration nanoduration <- function(hours = 0L, minutes = 0L, seconds = 0L, nanoseconds = 0L) { if (nargs()==0) { as.nanoduration(NULL) } else { make_duration_impl(as.integer64(hours), as.integer64(minutes), as.integer64(seconds), as.integer64(nanoseconds)) } } setOldClass("difftime") ##' @noRd setGeneric("as.nanoduration", function(x) standardGeneric("as.nanoduration")) ##' @rdname nanoduration ##' @aliases as.nanoduration setMethod("as.nanoduration", "character", function(x) { duration_from_string_impl(x) }) setAs("character", "nanoduration", function(from) as.nanoduration(from)) ##' @rdname nanoduration setMethod("as.nanoduration", "integer64", function(x) { new("nanoduration", x) }) setAs("integer64", "nanoduration", function(from) as.nanoduration(from)) ##' @rdname nanoduration setMethod("as.nanoduration", "numeric", function(x) { nm <- names(x) res <- new("nanoduration", as.integer64(x)) if (!is.null(nm)) { names(res) <- nm } res }) setAs("numeric", "nanoduration", function(from) as.nanoduration(from)) ##' @rdname nanoduration setMethod("as.nanoduration", "integer", function(x) { nm <- names(x) res <- new("nanoduration", as.integer64(x)) if (!is.null(nm)) { names(res) <- nm } res }) setAs("integer", "nanoduration", function(from) as.nanoduration(from)) ##' @rdname nanoduration setMethod("as.nanoduration", "difftime", function(x) { x <- as.numeric(x, units = "secs") s <- as.integer(x) # seconds n <- as.integer(1e9 * (x - s)) # nanoseconds nanoduration(seconds = s, nanoseconds = n) }) setAs("difftime", "nanoduration", function(from) as.nanoduration(from)) ##' @rdname nanoduration setMethod("as.nanoduration", "NULL", function(x) { new("nanoduration", as.integer64(NULL)) }) ##' @rdname nanoduration setMethod("as.nanoduration", "missing", function(x) { new("nanoduration", integer64()) }) ##' @rdname nanoduration setMethod("show", signature("nanoduration"), function(object) print(object)) ##' @rdname nanoduration setMethod("print", "nanoduration", function(x, quote=FALSE, ...) { if (length(x) == 0) { print("nanoduration(0)", quote=quote) } else { print(duration_to_string_impl(x), quote=quote) } }) ##' @rdname nanoduration format.nanoduration <- function(x, ...) { as.character(x) } ##' @rdname nanoduration ##' @method as.integer64 nanoduration as.integer64.nanoduration <- function(x, ...) { S3Part(x, strictS3=TRUE) } ##' @rdname nanoduration setMethod("as.character", signature("nanoduration"), function(x) { duration_to_string_impl(x) }) ##' @rdname nanoduration setMethod("is.na", "nanoduration", function(x) { duration_is_na_impl(x) }) ## ------------ `-` ## nanoduration - other ##' @rdname nanoduration setMethod("-", c("nanoduration", "nanoduration"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) - S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("-", c("nanoduration", "integer64"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) - e2) }) ##' @rdname nanoduration setMethod("-", c("nanoduration", "integer"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) - e2) }) ##' @rdname nanoduration setMethod("-", c("nanoduration", "numeric"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) - e2) }) ##' @rdname nanoduration setMethod("-", c("nanoduration", "difftime"), function(e1, e2) { e1 - as.nanoduration(e2) }) ##' @rdname nanoduration setMethod("-", c("nanoduration", "ANY"), function(e1, e2) { if (missing(e2)) { new("nanoduration", -S3Part(e1, strictS3=TRUE)) } else { stop("invalid operand types") } }) ## other - nanoduration ##' @rdname nanoduration setMethod("-", c("nanotime", "nanoduration"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) - e2) }) ##' @rdname nanoduration setMethod("-", c("nanotime", "difftime"), function(e1, e2) { e1 - as.nanoduration(e2) }) ##' @rdname nanoduration setMethod("-", c("integer64", "nanoduration"), function(e1, e2) { new("nanoduration", e1 - S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("-", c("integer", "nanoduration"), function(e1, e2) { new("nanoduration", e1 - S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("-", c("numeric", "nanoduration"), function(e1, e2) { new("nanoduration", e1 - S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("-", c("difftime", "nanoduration"), function(e1, e2) { as.nanoduration(e1) - e2 }) ##' @rdname nanoduration setMethod("-", c("ANY", "nanoduration"), function(e1, e2) { stop("invalid operand types") }) ## ----------- `+` ##' @rdname nanoduration setMethod("+", c("nanoduration", "ANY"), function(e1, e2) { if (missing(e2)) { e1 } else { stop("invalid operand types") } }) ##' @rdname nanoduration setMethod("+", c("nanoduration", "nanoduration"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) + e2) }) ##' @rdname nanoduration setMethod("+", c("nanoduration", "integer64"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) + e2) }) ##' @rdname nanoduration setMethod("+", c("nanoduration", "numeric"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) + e2) }) ##' @rdname nanoduration setMethod("+", c("nanoduration", "difftime"), function(e1, e2) { e1 + as.nanoduration(e2) }) ##' @rdname nanoduration setMethod("+", c("nanotime", "nanoduration"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) + S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("+", c("nanotime", "difftime"), function(e1, e2) { e1 + as.nanoduration(e2) }) ##' @rdname nanoduration setMethod("+", c("nanoduration", "nanotime"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) + S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("+", c("difftime", "nanotime"), function(e1, e2) { as.nanoduration(e1) + e2 }) ##' @rdname nanoduration setMethod("+", c("nanoival", "nanoduration"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e1, e2)) }) ##' @rdname nanoduration setMethod("-", c("nanoival", "nanoduration"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e1, -e2)) }) ##' @rdname nanoduration setMethod("+", c("nanoduration", "nanoival"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e2, e1)) }) ##' @rdname nanoduration setMethod("+", c("nanoival", "difftime"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e1, as.nanoduration(e2))) }) ##' @rdname nanoduration setMethod("-", c("nanoival", "difftime"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e1, -as.nanoduration(e2))) }) ##' @rdname nanoduration setMethod("+", c("difftime", "nanoival"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e2, as.nanoduration(e1))) }) ##' @noRd setMethod("+", c("ANY", "nanoduration"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoduration setMethod("+", c("integer64", "nanoduration"), function(e1, e2) { new("nanoduration", e1 + S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("+", c("numeric", "nanoduration"), function(e1, e2) { new("nanoduration", e1 + S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("+", c("difftime", "nanoduration"), function(e1, e2) { as.nanoduration(e1) + e2 }) ## ----------- `*` ##' @noRd setMethod("*", c("nanoduration", "nanoduration"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoduration setMethod("*", c("nanoduration", "numeric"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) * e2) }) ##' @rdname nanoduration setMethod("*", c("nanoduration", "integer64"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) * e2) }) ##' @rdname nanoduration setMethod("*", c("numeric", "nanoduration"), function(e1, e2) { new("nanoduration", e1 * S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoduration setMethod("*", c("integer64", "nanoduration"), function(e1, e2) { new("nanoduration", e1 * S3Part(e2, strictS3=TRUE)) }) ##' @noRd setMethod("*", c("nanoduration", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @noRd setMethod("*", c("ANY", "nanoduration"), function(e1, e2) { stop("invalid operand types") }) ## ----------- `/` ##' @rdname nanoduration setMethod("/", c("nanoduration", "nanoduration"), function(e1, e2) { S3Part(e1, strictS3=TRUE) / S3Part(e2, strictS3=TRUE) }) ##' @rdname nanoduration setMethod("/", c("nanoduration", "integer64"), function(e1, e2) { new("nanoduration", as.integer64(S3Part(e1, strictS3=TRUE) / e2)) }) ##' @rdname nanoduration setMethod("/", c("nanoduration", "numeric"), function(e1, e2) { new("nanoduration", as.integer64(S3Part(e1, strictS3=TRUE) / e2)) }) ##' @noRd setMethod("/", c("nanoduration", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @noRd setMethod("/", c("ANY", "nanoduration"), function(e1, e2) { stop("invalid operand types") }) ## ---------- other ops ##' @rdname nanoduration setMethod("Arith", c("nanoduration", "ANY"), function(e1, e2) { callNextMethod(S3Part(e1, strictS3=TRUE), e2) }) ##' @rdname nanoduration setMethod("Compare", c("nanoduration", "character"), function(e1, e2) { ne2 <- as.nanoduration(e2) callNextMethod(e1, ne2) }) ##' @rdname nanoduration setMethod("Compare", c("character", "nanoduration"), function(e1, e2) { ne1 <- as.nanoduration(e1) callNextMethod(ne1, e2) }) ##' @rdname nanoduration setMethod("Compare", c("nanoduration", "ANY"), function(e1, e2) { callNextMethod(S3Part(e1, strictS3=TRUE), e2) }) ##' @noRd setMethod("Logic", c("nanoduration", "nanoduration"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @noRd setMethod("Logic", c("nanoduration", "ANY"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @noRd setMethod("Logic", c("ANY", "nanoduration"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @rdname nanoduration setMethod("abs", c("nanoduration"), function(x) { new("nanoduration", callNextMethod(S3Part(x, strictS3=TRUE))) }) ##' @rdname nanoduration setMethod("sign", c("nanoduration"), function(x) { callNextMethod(S3Part(x, strictS3=TRUE)) }) ##' @noRd setMethod("Math", c("nanoduration"), function(x) { ## this is the same error message that R gives for abs("A") stop("non-numeric argument to mathematical function") }) ##' @noRd setMethod("Math2", c("nanoduration"), function(x, digits) { ## this is the same error message that R gives for round("A") stop("non-numeric argument to mathematical function") }) ##' @noRd setMethod("Summary", c("nanoduration"), function(x, ..., na.rm = FALSE) { ## this is the same error message that R gives for sum("A") stop("invalid 'type' (nanoduration) of argument") }) ##' @rdname nanoduration setMethod("sum", c("nanoduration"), function(x, ..., na.rm = FALSE) { new("nanoduration", callNextMethod()) }) ##' @rdname nanoduration setMethod("min", c("nanoduration"), function(x, ..., na.rm = FALSE) { new("nanoduration", callNextMethod()) }) ##' @rdname nanoduration setMethod("max", c("nanoduration"), function(x, ..., na.rm = FALSE) { new("nanoduration", callNextMethod()) }) ##' @rdname nanoduration setMethod("range", c("nanoduration"), function(x, ..., na.rm = FALSE) { new("nanoduration", callNextMethod()) }) ##' @noRd setMethod("Complex", c("nanoduration"), function(z) { ## this is the same error message that R gives for Arg("A") stop("non-numeric argument to function") }) ## non-ops: ## ------- ## subset/subassign ##' @rdname nanoduration setMethod("[[", signature("nanoduration"), function (x, i, j, ..., drop=FALSE) { new("nanoduration", callNextMethod()) }) ##' @rdname nanoduration setMethod("[", signature("nanoduration", "numeric"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoduration' subsetting") } if (isTRUE(any(i < 0))) { new("nanoduration", S3Part(x, strictS3=TRUE)[i]) } else { nanoduration_subset_numeric_impl(x, i) } }) ##' @rdname nanoduration setMethod("[", signature("nanoduration", "logical"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoduration' subsetting") } nanoduration_subset_logical_impl(x, i) }) ##' @rdname nanoduration setMethod("[", signature("nanoduration", "character"), function (x, i, j, ..., drop=FALSE) { ## we don't implement 'period_subset_character_impl' but ## do the gymnastic of finding the NAs here at R level; ## it's not as efficient, but using 'character' indexing ## is by itself inefficient, so the overhead should have ## no practical consequences. if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoduration' subsetting") } na_index <- !(i %in% names(x)) | is.na(i) res <- new("nanoduration", S3Part(x, strictS3=TRUE)[i]) res[na_index] <- NA_nanoduration_ res }) ##' @rdname nanoduration setMethod("[", signature("nanoduration", "ANY"), function (x, i, j, ..., drop=FALSE) { stop("']' not defined on 'nanoduration' for index of type 'ANY'") }) ##' @rdname nanoduration setMethod("[<-", signature("nanoduration"), function (x, i, j, ..., value) { new("nanoduration", callNextMethod()) }) ##' @rdname nanoduration c.nanoduration <- function(...) { as.nanoduration(c.integer64(...)) } ##' @rdname nanotime as.data.frame.nanoduration <- function(x, ...) { ret <- as.data.frame(S3Part(x, strictS3=TRUE), ...) ## this works, but see if there's a more idiomatic and efficient way ## of doing this: ret[] <- as.nanoduration(S3Part(x, strictS3=TRUE)) ret } ##' Sequence Generation ##' ##' Generate a sequence of \code{nanoduration} ##' ##' @param ... arguments passed to or from methods ##' @param from,to the starting and (maximal) end values of the ##' sequence ##' @param by the increment of the sequence ##' @param length.out integer indicating the desired length of the sequence ##' @param along.with take the length from the length of this argument. ##' ##' @examples ##' seq(from=as.nanoduration(0), by=as.nanoduration("01:00:00"), length.out=10) ##' @method seq nanoduration seq.nanoduration <- function(from, to=NULL, by=NULL, length.out=NULL, along.with=NULL, ...) { ## workaroud 'bit64' bug: if (is.null(by)) { if (is.null(length.out)) { length.out <- length(along.with) } by = (to - from) / (length.out - 1) } as.nanoduration(seq(as.integer64(from), to, as.integer64(by), length.out, along.with, ...)) } ##' Test if Two Objects are (Nearly) Equal ##' ##' Compare \code{target} and \code{current} testing \sQuote{near ##' equality}. If they are different, comparison is still made to ##' some extent, and a report of the differences is returned. Do not ##' use \code{all.equal} directly in \code{if} expressions---either ##' use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if ##' appropriate. ##' ##' @param target,current \code{nanoduration} arguments to be compared ##' @param ... further arguments for different methods ##' @param tolerance numeric >= 0. Differences smaller than ##' \code{tolerance} are not reported. The default value is close ##' to \code{1.5e-8}. ##' @param scale \code{NULL} or numeric > 0, typically of length 1 or ##' \code{length(target)}. See \sQuote{Details}. ##' @param countEQ logical indicating if the \code{target == current} cases should be ##' counted when computing the mean (absolute or relative) ##' differences. The default, \code{FALSE} may seem misleading in ##' cases where \code{target} and \code{current} only differ in a few ##' places; see the extensive example. ##' @param formatFUN a \code{function} of two arguments, \code{err}, the relative, absolute ##' or scaled error, and \code{what}, a character string indicating ##' the _kind_ of error; maybe used, e.g., to format relative and ##' absolute errors differently. ##' @param check.attributes logical indicating if the \code{attributes} of \code{target} ##' and \code{current} (other than the names) should be compared. ##' ##' @seealso \code{\link{identical}}, \code{\link{isTRUE}}, ##' \code{\link{==}}, and \code{\link{all}} for exact equality ##' testing. ##' ##' @method all.equal nanoduration ##' all.equal.nanoduration <- function(target, current, tolerance = sqrt(.Machine$double.eps), scale = NULL, countEQ = FALSE, formatFUN = function(err, what) format(err), ..., check.attributes = TRUE) { ## a bit of a kludge, but both 'nanoduration' and 'nanotime' are ## based on 'integer64'; because of a bug in 'all.equal.integer64' ## we have to redefine 'all.equal.nanotime' and it is correct for ## all 'integer64'-based S4 classes; in theory they would all ## three be the same function: if (inherits(target, "nanoduration")) target <- as.nanotime(target) if (inherits(current, "nanoduration")) current <- as.nanotime(current) all.equal.nanotime(target, current, tolerance, scale, countEQ, formatFUN, ..., check.attributes=check.attributes) } ##' @rdname all.equal.nanoduration setMethod("all.equal", c(target = "nanoduration", current="ANY"), all.equal.nanoduration) ##' @rdname nanoduration NA_nanoduration_ <- as.nanoduration(NA_integer_) ## rounding ops: ##' @rdname rounding setMethod("nano_ceiling", c(x="nanotime", precision="nanoduration"), function(x, precision, origin=nanotime()) { if (!inherits(origin, "nanotime")) { stop("'origin' must be of class 'nanotime'") } ceiling_impl(x, precision, origin) }) ##' @rdname rounding setMethod("nano_floor", c(x="nanotime", precision="nanoduration"), function(x, precision, origin=nanotime()) { if (!inherits(origin, "nanotime")) { stop("'origin' must be of class 'nanotime'") } floor_impl(x, precision, origin) }) ##' Replicate Elements ##' ##' Replicates the values in 'x' similarly to the default method. ##' ##' @param x a vector of \code{nanoduration} ##' @param ... further arguments: ##' ##' 'times' an integer-valued vector giving the (non-negative) ##' number of times to repeat each element if of length ##' 'length(x)', or to repeat the whole vector if of length ##' 1. Negative or 'NA' values are an error. A 'double' ##' vector is accepted, other inputs being coerced to an ##' integer or double vector. ##' ##' 'length.out' non-negative integer. The desired length of the ##' output vector. Other inputs will be coerced to a double ##' vector and the first element taken. Ignored if 'NA' or ##' invalid. ##' ##' 'each' non-negative integer. Each element of 'x' is repeated ##' 'each' times. Other inputs will be coerced to an integer ##' or double vector and the first element taken. Treated as ##' '1' if 'NA' or invalid. setMethod("rep", c(x = "nanoduration"), function(x, ...) { new("nanoduration", callNextMethod()) }) nanotime/R/nanoival.R0000644000176200001440000007737314671560065014252 0ustar liggesusers## TODO: ## - prevent matrix, array, cbind, rbind, compared with non-interval ## ##' @rdname nanoival setClass("nanoival", contains="complex") ##' Interval type with nanosecond precision ##' ##' \code{nanoival} is a time interval type (an S4 class) with ##' nanosecond precision. One of its purposes is to allow quick ##' subsetting of a \code{nanotime} vector. \code{nanoival} is ##' composed of a \code{nanotime} pair which defines the start and end ##' of the time interval. Additionally, it has a pair of logical ##' values which determine if the start and end of the time interval ##' are open (true) or closed (false). ##' ##' An interval object can be constructed with the constructor ##' \code{nanoival} which takes as arguments two \code{nanotime} ##' objects that define the start and the end of the interval, ##' together with two \code{logical} arguments that define if the ##' start and the end of the interval are open (true) or closed ##' (false) (note that these objects can all be vector, and therefore ##' the interval object is not necessarily scalar). Alternatively, an ##' interval can be constructed with a \code{character}: the format ##' follows that of \code{nanotime}; the start time is preceeded by ##' either \code{-} or \code{+} indicating if the interval start is ##' open (-) or closed (+); the start and end times are separated by ##' an arrow \code{->}; the end is folloed by either \code{-} or ##' \code{+} which have the same semantics as the start time. ##' ##' The most important set of methods defined for \code{interval} are ##' set functions \code{intersect}, \code{union} and \code{setdiff}. ##' ##' Additionally, \code{interval} allows the subsetting into a ##' \code{nanotime} vector. Note that subsetting is allowed only if ##' the \code{nanotime} vector is sorted. ##' ##' Finally, accessors are provided to get the interval start ##' (\code{start}), the end (\code{end}), the open/close status of the ##' start (\code{sopen}) and the open/close status of the end ##' (\code{eopen}). The former return a \code{nanotime} while the ##' latter return a \code{logical}. ##' ##' @section Output Format: ##' ##' Formatting and character conversion for \code{nanoival} objects is ##' identical to \code{nanotime} objects. The default format is ##' ISO3339 compliant: \code{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez}. It ##' specifies a standard ISO 8601 part for date and time --- as well ##' as nine digits of precision for fractional seconds (down to ##' nanoseconds) and on offset (typically zero as we default to UTC). ##' It can be overriden by using \code{options()} with the key of ##' \code{nanotimeFormat} and a suitable value. Similarly, ##' \code{nanotimeTz} can be used to select a different timezone. ##' ##' @param x,from a \code{nanoival} object ##' @param tz \code{character} indicating a timezone ##' @param ... further arguments passed to or from methods. ##' @param e1 Operand of class \code{nanoival} ##' @param e2 Operand of class \code{nanoival} ##' @param format A character string. Can also be set via ##' \code{options("nanotimeFormat")} and uses ##' \sQuote{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez} as a default and ##' fallback ##' @param object argument for method \code{show} ##' @param i index specifying elements to extract or replace. ##' @param j Required for \code{[} signature but ignored here ##' @param drop Required for \code{[} signature but ignored here ##' @param value argument for \code{nanoival-class} ##' @param start \code{nanotime} start of interval ##' @param end \code{nanotime} end of interval ##' @param sopen logical indicating if the start of the interval is open ##' @param eopen logical indicating if the end of the interval is open ##' @param quote indicates if the output of \code{print} should be ##' quoted ##' @return A nanoival object ##' @author Dirk Eddelbuettel ##' @author Leonardo Silvestri ##' @examples ##' \dontrun{ ##' ## creating a \code{nanoival}, with the start time included ('+') and the end ##' ## time excluded ('-') ##' as.nanoival("+2012-03-01T21:21:00.000000001+00:00->2015-01-01T21:22:00.000000999+04:00-") ##' ##' ## a \code{nanoival} can also be created with a pair of \code{nanotime} objects, a start ##' ## and an end, and optionally two logicals determining if the interval start(end) are open ##' ## or closed; by default the start is closed and end is open: ##' start <- nanotime("2012-03-01T21:21:00.000000001+00:00") ##' end <- nanotime("2013-03-01T21:21:00.000000001+00:00") ##' nanoival(start, end) ##' ##' ## a vector of 'nanotime' can be subsetted by a 'nanoival': ##' one_second <- 1e9 ##' a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) ##' idx <- c(as.nanoival("-2012-12-12 12:12:10+00:00 -> 2012-12-12 12:12:14+00:00-"), ##' as.nanoival("+2012-12-12 12:12:18+00:00 -> 2012-12-12 12:12:20+00:00+")) ##' a[idx] ##' } ##' @aliases +,ANY,nanoival-method ##' @aliases +,nanoival,ANY-method ##' @aliases +,nanoival,nanoival-method ##' @aliases -,ANY,nanoival-method ##' @aliases -,nanoival,ANY-method ##' @aliases -,nanoival,nanoival-method ##' @aliases Arith,nanoival,ANY-method ##' @aliases Compare,nanoival,ANY-method ##' @aliases Complex,nanoival-method ##' @aliases Logic,ANY,nanoival-method ##' @aliases Logic,nanoival,ANY-method ##' @aliases Logic,nanoival,nanoival-method ##' @aliases Math2,nanoival-method ##' @aliases Math,nanoival-method ##' @aliases Summary,nanoival-method ##' ##' @seealso \code{\link{intersect.idx}}, \code{\link{setdiff.idx}}, ##' @rdname nanoival nanoival <- function(start, end, sopen=FALSE, eopen=TRUE) { if (nargs() == 0) { new("nanoival", as.complex(NULL)) } else { nanoival_new_impl(as.integer64(start), as.integer64(end), as.logical(sopen), as.logical(eopen)) } } ##' @noRd setGeneric("nanoival.start", function(x) standardGeneric("nanoival.start")) ##' @rdname nanoival ##' @aliases nanoival.start setMethod("nanoival.start", "nanoival", function(x) { res <- nanoival_get_start_impl(x) oldClass(res) <- "integer64" new("nanotime", res) }) ##' @noRd setGeneric("nanoival.end", function(x) standardGeneric("nanoival.end")) ##' @rdname nanoival ##' @aliases nanoival.end setMethod("nanoival.end", "nanoival", function(x) { res <- nanoival_get_end_impl(x) oldClass(res) <- "integer64" new("nanotime", res) }) ##' @noRd setGeneric("nanoival.sopen", function(x) standardGeneric("nanoival.sopen")) ##' @rdname nanoival ##' @aliases nanoival.sopen setMethod("nanoival.sopen", "nanoival", function(x) { nanoival_get_sopen_impl(x) }) ##' @noRd setGeneric("nanoival.eopen", function(x) standardGeneric("nanoival.eopen")) ##' @rdname nanoival ##' @aliases nanoival.eopen setMethod("nanoival.eopen", "nanoival", function(x) { nanoival_get_eopen_impl(x) }) ##' @rdname nanoival format.nanoival <- function(x, ...) { if (length(x) == 0) { "nanoival(0)" } else { s <- paste0(ifelse(nanoival.sopen(x), "-", "+"), format(nanoival.start(x), ...), " -> ", format(nanoival.end(x), ...), ifelse(nanoival.eopen(x), "-", "+")) if (!is.null(attr(x, "names", exact=TRUE))) { names(s) <- names(x) } s[nanoival_isna_impl(x)] = NA_character_ s } } ##' @rdname nanoival setMethod("print", "nanoival", function(x, quote=FALSE, ...) { s <- format(x, ...) max.print <- options()$max.print if (length(x) > max.print) { ## #nocov start f <- head(x, max.print) print(f, quote=quote) cat(paste(' [ reached getOption("max.print") -- omitted', length(x) - max.print, "entries ]\n")) } ## #nocov end else { print(s, quote=quote) } invisible(s) }) ##' @rdname nanoival setMethod("show", signature("nanoival"), function(object) print(object)) .secondaryNanoivalParse <- function(x, format="", tz="") { format <- .getFormat(format) tz <- .getTz(x, tz) ## parse the +-, split on -> and process the two s1 = substr(x, 1, 1) if (any(s1 != '-' & s1 != '+')) { stop("`nanoival` must start with '+' or '-'") } sopen <- s1 == "-" xlen <- nchar(x) e1 <- substr(x, xlen, xlen) if (any(e1 != '-' & e1 != '+')) { stop("`nanoival` must end with '+' or '-'") } eopen <- e1 == "-" start_stop <- strsplit(substr(x, 2, xlen-1), "->") start <- sapply(start_stop, function(x) head(x, 1)) end <- sapply(start_stop, function(x) tail(x, 1)) res <- nanoival(nanotime(start, format, tz), nanotime(end, format, tz), sopen, eopen) names(res) <- names(x) res } ##' @noRd setGeneric("as.nanoival", function(from, format="", tz="") standardGeneric("as.nanoival")) ##' @rdname nanoival ##' @aliases as.nanoival setMethod("as.nanoival", "character", function(from, format="", tz="") { if (!is.character(tz)) { stop("argument 'tz' must be of type 'character'") } tryCatch(nanoival_make_impl(from, tz), error=function(e) { if (grepl("Cannot retrieve timezone", e$message)) { stop(e$message) } else { .secondaryNanoivalParse(from, format, tz) } }) }) setAs("character", "nanoival", function(from) as.nanoival(from)) ##' @rdname nanoival setMethod("as.nanoival", "NULL", function(from, format="", tz="") { new("nanoival", as.complex(NULL)) }) ##' @rdname nanoival setMethod("as.nanoival", "missing", function(from, format="", tz="") { new("nanoival", as.complex(NULL)) }) ##' @rdname nanoival setMethod("is.na", "nanoival", function(x) { nanoival_isna_impl(x) }) ##' @rdname nanoival setMethod("is.na<-", "nanoival", function(x, value) { x[value] <- NA_nanoival_ x }) ## ------------ logical comp ##' @rdname nanoival setMethod("<", c("nanoival", "nanoival"), function(e1, e2) { nanoival_lt_impl(e1, e2) }) ##' @rdname nanoival setMethod("<=", c("nanoival", "nanoival"), function(e1, e2) { nanoival_le_impl(e1, e2) }) ##' @rdname nanoival setMethod(">", c("nanoival", "nanoival"), function(e1, e2) { nanoival_gt_impl(e1, e2) }) ##' @rdname nanoival setMethod(">=", c("nanoival", "nanoival"), function(e1, e2) { nanoival_ge_impl(e1, e2) }) ##' @rdname nanoival setMethod("==", c("nanoival", "nanoival"), function(e1, e2) { nanoival_eq_impl(e1, e2) }) ##' @rdname nanoival setMethod("!=", c("nanoival", "nanoival"), function(e1, e2) { nanoival_ne_impl(e1, e2) }) ## ------------ `-` ##' @noRd setMethod("-", c("nanoival", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoival setMethod("-", c("nanoival", "integer64"), function(e1, e2) { new("nanoival", nanoival_minus_impl(e1, e2)) }) ##' @rdname nanoival setMethod("-", c("nanoival", "numeric"), function(e1, e2) { new("nanoival", nanoival_minus_impl(e1, as.integer64(e2))) }) ##' @noRd setMethod("-", c("ANY", "nanoival"), function(e1, e2) { stop("invalid operand types") }) ##' @noRd setMethod("-", c("nanoival", "nanoival"), function(e1, e2) { stop("invalid operand types") }) ## ----------- `+` ##' @noRd setMethod("+", c("nanoival", "nanoival"), function(e1, e2) { stop("invalid operand types") }) ##' @noRd setMethod("+", c("nanoival", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoival setMethod("+", c("nanoival", "integer64"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e1, e2)) }) ##' @rdname nanoival setMethod("+", c("nanoival", "numeric"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e1, as.integer64(e2))) }) ##' @noRd setMethod("+", c("ANY", "nanoival"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoival setMethod("+", c("integer64", "nanoival"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e2, e1)) }) ##' @rdname nanoival setMethod("+", c("numeric", "nanoival"), function(e1, e2) { new("nanoival", nanoival_plus_impl(e2, as.integer64(e1))) }) ##' @noRd setMethod("+", c("nanoival", "nanoival"), function(e1, e2) { stop("invalid operand types") }) ## ---------- other ops ##' @noRd setMethod("Arith", c("nanoival", "ANY"), function(e1, e2) { stop("operation not defined for \"nanoival\" objects") }) ##' @noRd setMethod("Compare", c("nanoival", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @noRd setMethod("Logic", c("nanoival", "nanoival"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @noRd setMethod("Logic", c("nanoival", "ANY"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @noRd setMethod("Logic", c("ANY", "nanoival"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @noRd setMethod("Math", c("nanoival"), function(x) { ## this is the same error message that R gives for abs("A") stop("non-numeric argument to mathematical function") }) ##' @noRd setMethod("Math2", c("nanoival"), function(x, digits) { ## this is the same error message that R gives for round("A") stop("non-numeric argument to mathematical function") }) ##' @noRd setMethod("Summary", c("nanoival"), function(x, ..., na.rm = FALSE) { ## this is the same error message that R gives for sum("A") stop("invalid 'type' (nanoival) of argument") }) ##' @noRd setMethod("Complex", c("nanoival"), function(z) { ## this is the same error message that R gives for Arg("A") stop("non-numeric argument to function") }) ## ----------- non ops ##' @rdname nanoival setMethod("[[", signature("nanoival"), function (x, i, j, ..., drop=FALSE) { new("nanoival", callNextMethod()) }) ##' @rdname nanoival setMethod("[", signature("nanoival", "logical"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoival' subsetting") } nanoival_subset_logical_impl(x, i) }) ##' @rdname nanoival setMethod("[", signature("nanoival", "numeric"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoival' subsetting") } if (isTRUE(any(i < 0))) { new("nanoival", unclass(x)[i]) } else { nanoival_subset_numeric_impl(x, i) } }) ##' @rdname nanoival setMethod("[", signature("nanoival", "character"), function (x, i, j, ..., drop=FALSE) { ## we don't implement 'period_subset_character_impl' but ## do the gymnastic of finding the NAs here at R level; ## it's not as efficient, but using 'character' indexing ## is by itself inefficient, so the overhead should have ## no practical consequences. if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoival' subsetting") } na_index <- !(i %in% names(x)) | is.na(i) res <- new("nanoival", unclass(x)[i]) res[na_index] <- NA_nanoival_ res }) ##' @rdname nanoival setMethod("[", signature("nanoival", "ANY"), function (x, i, j, ..., drop=FALSE) { stop("']' not defined for on 'nanoival' for index of type 'ANY'") }) ##' @rdname nanoival setMethod("[<-", signature("nanoival", "logical", "ANY", "nanoival"), function (x, i, j, ..., value) { new("nanoival", callNextMethod()) }) ##' @rdname nanoival c.nanoival <- function(...) { args <- list(...) s3args <- lapply(args, function (x) S3Part(x, strictS3=TRUE)) res <- do.call(c, s3args) names(res) <- names(args) new("nanoival", res) } ## S4 'c' doesn't handle names correctly, and couldn't find a way to rectify that: ## ##' @rdname nanoival ## ## setMethod("c", ## signature("nanoival"), ## function(x, ...) { ## print("method ccc") ## args <- list(...) ## res <- callNextMethod() ## names(res) <- names(args) ## print(names(args)) ## new("nanoival", res) ## }) ##' @rdname nanoival setMethod("t", c("nanoival"), function(x) { ## identity, like POSIXct, because nanoival doesn't support arrays x }) ## ##' @rdname nanoival ## ## setMethod("cbind2", ## signature("nanoival", "nanoival"), ## function (x, y, ...) { ## print(dimnames(x)) ## print("calling next method") ## res <- callNextMethod() ## print(attributes(res)) ## new("nanoival", res) ## }) ## ##' @rdname nanoival ## ## setMethod("cbind2", ## signature("nanoival", "nanoival"), ## function (x, y, ...) { ## x <- t(x) ## y <- t(y) ## print(dimnames(x)) ## print("calling next method") ## res <- callNextMethod() ## print(attributes(res)) ## new("nanoival", res) ## }) ## ##' @rdname nanoival ## ## setMethod("rbind2", ## signature("nanoival", "nanoival"), ## function (x, y, ...) { ## print("rbind2") ## dim(x) ## x <- t(x) ## y <- t(y) ## print(dim(x)) ## print(dim(y)) ## print("rbind2 dimnames") ## print(dimnames(x)) ## new("nanoival", callNextMethod()) ## }) ## set functions ## ------------- ##' Set operations ##' ##' Performs set intersection, union and difference between vectors of ##' temporal types from the \code{nanotime} package. ##' ##' Set operations between \code{nanoival} operands allow the ##' construction of complex interval vectors (i.e. a \code{nanoival} ##' vector can specify any number of inclusions and exclusions of ##' time). Set operations between \code{nanotime} and \code{nanoival} ##' allow to subset time vectors with interval vectors. In addition to ##' the generic set functions, the function \code{intersect.idx} is ##' defined which returns the indices of the intersection, and the ##' operator \code{\%in\%} is overloaded for \code{nanotime-nanoival} ##' which returns a logical vector that indicates which elements ##' belong to the interval vector. ##' ##' ##' @param x,y a temporal type ##' @param table \code{nanoival}: used in \code{\%in\%} ##' @return \code{intersect}, \code{union}, \code{setdiff} return ##' temporal types that are the result of the intersection. For ##' instance, set operations on two \code{nanoival} return a ##' \code{nanoival}, whereas intersection between a ##' \code{nanoival} and a \code{nanotime} returns a ##' \code{nanotime}. \code{intersect.idx} return a list of vectors ##' representing the element indices that intersect and ##' \code{setdiff.idx} returns a vector representing the element ##' indices to be removed. ##' @examples ##' \dontrun{ ##' ## a vector of 'nanotime' can be subsetted by a 'nanoival' which is equivalent to 'intersect': ##' one_second <- 1e9 ##' a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) ##' idx <- c(as.nanoival("-2012-12-12 12:12:10+00:00 -> 2012-12-12 12:12:14+00:00-"), ##' as.nanoival("+2012-12-12 12:12:18+00:00 -> 2012-12-12 12:12:20+00:00+")) ##' a[idx] ##' intersect(a, idx) ##' ##' ## 'nanoival' also has the set operations 'union', 'intersect', 'setdiff': ##' a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) ##' i <- as.nanoival("-2012-12-12 12:12:14+00:00 -> 2012-12-12 12:12:18+00:00-") ##' setdiff(a, i) ##' ##' i1 <- as.nanoival("+2012-12-12 12:12:14+00:00 -> 2012-12-12 12:12:17+00:00-") ##' i2 <- as.nanoival("+2012-12-12 12:12:16+00:00 -> 2012-12-12 12:12:18+00:00-") ##' union(i1, i2) ##' ##' ## 'intersect.idx' returns the indices of the intersection: ##' a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) ##' idx <- as.nanoival("+2012-12-12 12:12:14+00:00 -> 2012-12-12 12:12:19+00:00+") ##' idx_intersect <- intersect.idx(a, idx) ##' ##' ## Intersection can be performed using these indices: ##' a[idx_intersect$x] ##' ##' ## which is equivalent to: ##' a[idx] ##' ##' ## The logical vector indicating intersection can be obtained like this: ##' a %in% idx ##' } ##' @rdname set_operations ##' setMethod("intersect", c("nanoival", "nanoival"), function(x, y) { x <- sort(x) y <- sort(y) res <- nanoival_intersect_impl(x, y) new("nanoival", res) }) ##' @rdname set_operations setMethod("union", c("nanoival", "nanoival"), function(x, y) { x <- sort(x) y <- sort(y) res <- nanoival_union_impl(x, y) new("nanoival", res) }) ##' @rdname set_operations setMethod("setdiff", c("nanoival", "nanoival"), function(x, y) { x <- sort(x) y <- sort(y) res <- nanoival_setdiff_impl(x, y) new("nanoival", res) }) ## nanotime and nanoival: ## --------------------- ##' @rdname nanoival setMethod("[", signature("nanotime", "nanoival"), function (x, i, ..., drop=FALSE) { if (is.unsorted(x)) stop("x must be sorted") i <- sort(i) nanoival_intersect_time_interval_impl(x, i) }) ##' @noRd setGeneric("intersect.idx", function(x, y) standardGeneric("intersect.idx")) ##' @rdname set_operations ##' @aliases intersect.idx setMethod("intersect.idx", c("nanotime", "nanoival"), function(x, y) { if (is.unsorted(x)) stop("x must be sorted") y <- sort(y) nanoival_intersect_idx_time_interval_impl(x, y) }) ##' @rdname set_operations ##' @method %in% nanotime `%in%.nanotime` <- function(x, table) { if (inherits(table, "nanoival")) { if (is.unsorted(x)) stop("x must be sorted") table <- sort(table) nanoival_intersect_idx_time_interval_logical_impl(x, table) } else { NextMethod() } } ##' @rdname set_operations setMethod("%in%", c("nanotime", "nanoival"), function(x, table) { if (is.unsorted(x)) stop("x must be sorted") ## #nocov table <- sort(table) ## #nocov nanoival_intersect_idx_time_interval_logical_impl(x, table) ## #nocov }) ##' @rdname set_operations setMethod("intersect", c("nanotime", "nanoival"), function(x, y) { x <- sort(x) y <- sort(y) nanoival_intersect_time_interval_impl(x, y) }) ##' @rdname set_operations setMethod("setdiff", c("nanotime", "nanoival"), function(x, y) { x <- sort(x) y <- sort(y) res <- nanoival_setdiff_time_interval_impl(x, y) oldClass(res) <- "integer64" new("nanotime", res) }) ##' @noRd setGeneric("setdiff.idx", function(x, y) standardGeneric("setdiff.idx")) ##' @rdname set_operations ##' @aliases setdiff.idx setMethod("setdiff.idx", c("nanotime", "nanoival"), function(x, y) { if (is.unsorted(x)) stop("x must be sorted") y <- sort(y) nanoival_setdiff_idx_time_interval_impl(x, y) }) ## provide 'nanotime'-'nanotime' set operations and document here ## --------------------- ##' @rdname set_operations setMethod("intersect", c("nanotime", "nanotime"), function(x, y) { res <- callNextMethod() oldClass(res) <- "integer64" new("nanotime", res) }) ##' @rdname set_operations setMethod("union", c("nanotime", "nanotime"), function(x, y) { res <- callNextMethod() oldClass(res) <- "integer64" new("nanotime", res) }) ##' @rdname set_operations setMethod("setdiff", c("nanotime", "nanotime"), function(x, y) { res <- if (getRversion() >= "4.5.0") setdiff(as.integer64(x), as.integer64(y)) else callNextMethod() oldClass(res) <- "integer64" new("nanotime", res) }) ## misc functions: ## -------------- ##' Test if Two Objects are (Nearly) Equal ##' ##' Compare \code{target} and \code{current} testing \sQuote{near ##' equality}. If they are different, comparison is still made to ##' some extent, and a report of the differences is returned. Do not ##' use \code{all.equal} directly in \code{if} expressions---either ##' use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if ##' appropriate. ##' ##' @param target,current \code{nanoival} arguments to be compared ##' @param ... further arguments for different methods ##' @param check.attributes logical indicating if the ##' \code{attributes} of \code{target} and \code{current} (other than ##' the names) should be compared. ##' ##' @seealso \code{\link{identical}}, \code{\link{isTRUE}}, ##' \code{\link{==}}, and \code{\link{all}} for exact equality ##' testing. ##' ##' @method all.equal nanoival ##' all.equal.nanoival <- function(target, current, ..., check.attributes = TRUE) all.equal.raw(target, current, ..., check.attributes) ##' @rdname all.equal.nanoival setMethod("all.equal", c(target = "nanoival", current="ANY"), all.equal.nanoival) ##' Test if a \code{nanoival} vector is Not Sorted ##' ##' Test if an object is not sorted (in increasing order), without the ##' cost of sorting it. ##' ##' @param x a \code{nanoival} vector ##' @param na.rm logical. Should missing values be removed before ##' checking? ##' @param strictly logical indicating if the check should be for ##' _strictly_ increasing values. ##' ##' @seealso \code{\link{sort}} ##' setMethod("is.unsorted", "nanoival", function(x, na.rm=FALSE, strictly=FALSE) { if (!is.logical(strictly)) { stop("argument 'strictly' must be a logical") } if (na.rm == TRUE) { nanoival_is_unsorted_impl(x[!is.na(x)], strictly) # we could code this more efficiently! } else { if (any(is.na(x))) { # same here... NA_nanoival_ } else { nanoival_is_unsorted_impl(x, strictly) } } }) ##' Sorting or Ordering Vectors ##' ##' Sort (or _order_) a vector of \code{nanoival} into ascending or ##' descending order ##' ##' @param x a vector of \code{nanoival} ##' @param decreasing logical. Should the sort be increasing or ##' decreasing? ##' @seealso \code{\link{is.unsorted}} ##' setMethod("sort", c("nanoival"), function(x, decreasing=FALSE) { if (!is.logical(decreasing)) { stop("argument 'decreasing' must be logical") } new("nanoival", nanoival_sort_impl(x, decreasing)) }) ##' Sequence Generation ##' ##' Generate a sequence of \code{nanoival} ##' ##' @param ... arguments passed to or from methods; the only ##' interesting additional argument is \code{tz} where the ##' \code{to} argument is of type \code{nanoperiod} ##' @param from,to the starting and (maximal) end values of the ##' sequence ##' @param by \code{nanoduration} or \code{nanoperiod} increment of ##' the sequence; note that if the class is \code{nanoperiod} the ##' additional argument \code{tz} must be speficied and is of ##' \code{character} type indicating a timezone ##' @param length.out an integer desired length of the sequence ##' @param along.with take the length from the length of this argument. ##' @examples ##' \dontrun{ ##' from <- as.nanoival("-2018-01-14T13:00:00+00:00 -> 2018-01-14T15:00:00+00:00+") ##' seq(from, by=as.nanoperiod("1m"), length.out=5, tz="America/New_York") ##' } setMethod("seq", c("nanoival"), function(from, to = NULL, by = NULL, length.out = NULL, along.with = NULL, ...) { if (is.null(to)) { start <- seq(nanoival.start(from), by=by, length.out=length.out, along.with=along.with, ...) } else { start <- seq(nanoival.start(from), nanoival.start(to), by, length.out, along.with, ...) } if (is.null(by)) { end <- seq(nanoival.end(from), by=start[2]-start[1], length.out=length(start), ...) } else { end <- seq(nanoival.end(from), by=by, length.out=length(start), ...) } nanoival(start, end, nanoival.sopen(from), nanoival.eopen(from)) }) ##' @rdname nanoival NA_nanoival_ <- new("nanoival", complex(1, -4.9406564584124654418e-324, -4.9406564584124654418e-324)) ##' Replicate Elements ##' ##' Replicates the values in 'x' similarly to the default method. ##' ##' @param x a vector of \code{nanoival} ##' @param ... further arguments: ##' ##' 'times' an integer-valued vector giving the (non-negative) ##' number of times to repeat each element if of length ##' 'length(x)', or to repeat the whole vector if of length ##' 1. Negative or 'NA' values are an error. A 'double' ##' vector is accepted, other inputs being coerced to an ##' integer or double vector. ##' ##' 'length.out' non-negative integer. The desired length of the ##' output vector. Other inputs will be coerced to a double ##' vector and the first element taken. Ignored if 'NA' or ##' invalid. ##' ##' 'each' non-negative integer. Each element of 'x' is repeated ##' 'each' times. Other inputs will be coerced to an integer ##' or double vector and the first element taken. Treated as ##' '1' if 'NA' or invalid. setMethod("rep", c(x = "nanoival"), function(x, ...) { new("nanoival", callNextMethod()) }) ##' @rdname nanoival as.character.nanoival <- function(x, ...) { format(x, ...) } nanotime/R/nanoperiod.R0000644000176200001440000005760114624352363014567 0ustar liggesusers##' @rdname nanoperiod setClass("nanoperiod", contains = "complex") ##' Period type with nanosecond precision ##' ##' \code{nanoperiod} is a length of time type (implemented as an S4 ##' class) with nanosecond precision. It differs from ##' \code{nanoduration} because it is capable of representing calendar ##' months and days. It can thus represent years (12 months) and weeks ##' (7 days). A period is a somewhat abstract representation of time: ##' it is only when anchored to a point in time and in a specific time ##' zone that it is possible to convert it to a specific ##' duration. This means that many of the operations involving periods ##' need the additional argument \code{tz}. ##' ##' @section Constructors: ##' ##' The true constructor is ##' ##' @section Output Format: ##' ##' A \code{nanoperiod} is displayed as months, days, and \code{nanoduration} ##' like this: \code{10m2d/10:12:34.123_453_000}. ##' ##' @section Details: ##' ##' ##' ##' Adding or subtracting \code{nanoperiod} and \code{nanotime} ##' require a timezone as third argument. For this reason it is not ##' possible to use the binary operator `\code{+}`. Instead the ##' functions `\code{plus}` and `\code{minus}` are defined. These ##' functions attempt to keep the same offset within a day in the ##' specified timezone: this means for instance that adding a day when ##' that day crosses a time zone adjustment such as a daylight saving ##' time, results in a true time increment of less or more than 24 ##' hours to preserve the offset. Preserving the offset works for ##' increments that are smaller than a day too, provided the increment ##' results in a datetime where the timezone adjustment is valid. When ##' this is not the case, adding a `nanoperiod` behaves in the same ##' way as adding a `nanoduration`. ##' ##' ##' @param x,value An object of class \code{nanoperiod} ##' @param ... further arguments ##' @param e1 Operand of class \code{nanoperiod} ##' @param e2 Operand of class \code{nanoperiod} ##' @param object argument for method \code{show} ##' @param i index specifying elements to extract or replace. ##' @param j Required for \code{[} signature but ignored here ##' @param drop Required for \code{[} signature but ignored here ##' @param months Used in the constructor to indicate the number of ##' months of the \code{nanoperiod} ##' @param days Used in the constructor to indicate the number of ##' days of the \code{nanoperiod} ##' @param duration Used in the constructor to indicate the duration ##' component of the \code{nanoperiod} ##' @param quote indicates if the output of \code{print} should be ##' quoted ##' @param tz \code{character} indicating a timezone ##' @author Dirk Eddelbuettel ##' @author Leonardo Silvestri ##' @examples ##' \dontrun{ ##' p <- nanoperiod(months=12, days=7, duration="01:00:00") ##' print(p) ##' ##' # when adding a \code{nanoperiod} to a \code{nanotime} or to a ##' # \code{nanoival}, a time zone must be specified: ##' y <- nanotime("1970-01-01T00:00:00+00:00") ##' plus(y, p, tz="America/Chicago") ##' } ##' ##' @seealso \code{\link{nanotime}}, \code{\link{nanoduration}}, ##' \code{\link{nanoival}}, \code{\link{nanoperiod.month,nanoperiod-method}} ##' ##' @aliases Compare,ANY,nanoperiod-method Compare,nanoperiod,ANY-method ##' @aliases -,ANY,nanoperiod-method -,nanoperiod,nanotime-method ##' @aliases -,nanotime,nanoperiod-method ##' @aliases /,ANY,nanoperiod-method /,nanoperiod,ANY-method ##' @aliases Complex,nanoperiod-method Math,nanoperiod-method Math2,nanoperiod-method ##' @aliases Summary,nanoperiod-method ##' @aliases minus,nanoperiod,nanoival,character-method ##' ##' @rdname nanoperiod nanoperiod <- function(months=0, days=0, duration=as.nanoduration(0)) { if (nargs() == 0) { as.nanoperiod(NULL) } else { if (!is.numeric(months)) { stop("argument 'months' must be numeric") } if (!is.numeric(days)) { stop("argument 'days' must be numeric") } period_from_parts_impl(as.integer(months), as.integer(days), as.nanoduration(duration)) } } ##' @noRd setGeneric("nanoperiod") ##' @noRd setGeneric("as.nanoperiod", function(x) standardGeneric("as.nanoperiod")) ##' @rdname nanoperiod ##' @aliases as.nanoperiod setMethod("as.nanoperiod", "character", function(x) { period_from_string_impl(x) }) setAs("character", "nanoperiod", function(from) as.nanoperiod(from)) ##' @rdname nanoperiod setMethod("as.nanoperiod", "integer64", function(x) { period_from_integer64_impl(x) }) setAs("integer64", "nanoperiod", function(from) as.nanoperiod(from)) ##' @rdname nanoperiod setMethod("as.nanoperiod", "numeric", function(x) { period_from_double_impl(x) }) setAs("numeric", "nanoperiod", function(from) as.nanoperiod(from)) ##' @rdname nanoperiod setMethod("as.nanoperiod", "integer", function(x) { period_from_integer_impl(x) }) setAs("integer", "nanoperiod", function(from) as.nanoperiod(from)) ##' @rdname nanoperiod setMethod("as.nanoperiod", "nanoduration", function(x) { period_from_integer64_impl(x) }) setAs("nanoduration", "nanoperiod", function(from) as.nanoperiod(from)) ##' @rdname nanoperiod setMethod("as.nanoperiod", "NULL", function(x) { period_from_string_impl(character()) }) ##' @rdname nanoperiod setMethod("as.nanoperiod", "missing", function(x) { period_from_string_impl(character()) }) ##' @rdname nanoperiod setMethod("show", signature("nanoperiod"), function(object) print(object)) ##' @rdname nanoperiod setMethod("print", "nanoperiod", function(x, quote=FALSE, ...) { if (length(x)==0) { print("nanoperiod(0)", quote=quote) } else { print(period_to_string_impl(x), quote=quote) } }) ##' @rdname nanoperiod format.nanoperiod <- function(x, ...) { period_to_string_impl(x) } ##' @rdname nanoperiod setMethod("as.character", signature("nanoperiod"), function(x) { period_to_string_impl(x) }) ##' @rdname nanoperiod setMethod("is.na", "nanoperiod", function(x) { period_isna_impl(x) }) ##' @rdname nanoperiod setMethod("is.na<-", "nanoperiod", function(x, value) { x[value] <- NA_nanoperiod_ x }) ## accessors ## ----------- non ops ##' @rdname nanoperiod setMethod("[[", signature("nanoperiod", "ANY"), function (x, i, j, ..., drop=FALSE) { new("nanoperiod", callNextMethod()) }) ##' @rdname nanoperiod setMethod("[", signature("nanoperiod", "numeric"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoperiod' subsetting") } if (isTRUE(any(i < 0))) { new("nanoperiod", unclass(x)[i]) } else { period_subset_numeric_impl(x, i) } }) ##' @rdname nanoperiod setMethod("[", signature("nanoperiod", "logical"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoperiod' subsetting") } period_subset_logical_impl(x, i) }) ##' @rdname nanoperiod setMethod("[", signature("nanoperiod", "character"), function (x, i, j, ..., drop=FALSE) { ## we don't implement 'period_subset_character_impl' but ## do the gymnastic of finding the NAs here at R level; ## it's not as efficient, but using 'character' indexing ## is by itself inefficient, so the overhead should have ## no practical consequences. if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanoperiod' subsetting") } na_index <- !(i %in% names(x)) | is.na(i) res <- new("nanoperiod", unclass(x)[i]) res[na_index] <- NA_nanoperiod_ res }) ##' @rdname nanoperiod setMethod("[", signature("nanoperiod", "ANY"), function (x, i, j, ..., drop=FALSE) { stop("']' not defined on 'nanoperiod' for index of type 'ANY'") }) ##' @rdname nanoperiod setMethod("[<-", signature("nanoperiod", "ANY", "ANY", "ANY"), function (x, i, j, ..., value) { new("nanoperiod", callNextMethod()) }) ##' @rdname nanoperiod c.nanoperiod <- function(...) { args <- list(...) s3args <- lapply(args, function (x) S3Part(x, strictS3=TRUE)) res <- do.call(c, s3args) names(res) <- names(args) new("nanoperiod", res) } ##' @noRd setGeneric("nanoperiod.month", function(x) standardGeneric("nanoperiod.month")) ##' Nanoperiod accessors ##' ##' These functions allow access to the components of a \code{nanoperiod} ##' ##' @rdname nanoperiod.month ##' @aliases nanoperiod.month nanoperiod.day nanoperiod.nanoduration ##' @param x A \code{nanoperiod} ##' @return \code{nanoperiod.month} and \code{nanoperiod.day} return ##' an \code{integer64} whereas \code{nanoperiod.nanoduration} ##' returns a \code{nanoduration} ##' @examples ##' p <- as.nanoperiod("2y1m1d/12:00:00") ##' nanoperiod.month(p) ##' nanoperiod.day(p) ##' nanoperiod.nanoduration(p) ##' @author Dirk Eddelbuettel ##' @author Leonardo Silvestri ##' @seealso \code{\link{nanoduration}} setMethod("nanoperiod.month", "nanoperiod", function(x) { period_month_impl(x) }) ##' @noRd setGeneric("nanoperiod.day", function(x) standardGeneric("nanoperiod.day")) ##' @rdname nanoperiod.month setMethod("nanoperiod.day", "nanoperiod", function(x) { period_day_impl(x) }) ##' @noRd setGeneric("nanoperiod.nanoduration", function(x) standardGeneric("nanoperiod.nanoduration")) ##' @rdname nanoperiod.month setMethod("nanoperiod.nanoduration", "nanoperiod", function(x) { period_duration_impl(x) }) ##' @rdname nanoperiod setMethod("names", signature("nanoperiod"), function(x) { callNextMethod() }) ##' @rdname nanoperiod setMethod("names<-", signature("nanoperiod"), function(x, value) { names(S3Part(x, strictS3=TRUE)) <- value new("nanoperiod", x) }) ## ----------- make sure ops that don't make sense error out ##' @noRd setMethod("Ops", c("nanoperiod", "ANY"), function(e1, e2) { stop("operation not defined for 'nanoperiod' objects") }) ##' @noRd setMethod("Ops", c("ANY", "nanoperiod"), function(e1, e2) { stop("operation not defined for 'nanoperiod' objects") }) ##' @noRd setMethod("Math", c("nanoperiod"), function(x) { stop("operation not defined for 'nanoperiod' objects") }) ##' @noRd setMethod("Math2", c("nanoperiod"), function(x, digits) { stop("operation not defined for 'nanoperiod' objects") }) ##' @noRd setMethod("Summary", c("nanoperiod"), function(x, ..., na.rm = FALSE) { stop("invalid 'type' (nanoperiod) of argument") }) ##' @noRd setMethod("Complex", c("nanoperiod"), function(z) { stop("operation not defined for 'nanoperiod' objects") }) ## ------------ `-` ##' @rdname nanoperiod setMethod("-", c("nanoperiod", "ANY"), function(e1, e2) { if (missing(e2)) { minus_period_impl(e1) } else { stop("invalid operand types") } }) ##' @rdname nanoperiod setMethod("-", c("nanoperiod", "nanoperiod"), function(e1, e2) { minus_period_period_impl(e1, e2) }) ## -- ##' @rdname nanoperiod ##' @aliases -,nanoperiod,ANY-method setMethod("-", c("nanoperiod", "nanoduration"), function(e1, e2) { minus_period_integer64_impl(e1, e2) }) ##' @rdname nanoperiod setMethod("-", c("nanoperiod", "integer64"), function(e1, e2) { minus_period_integer64_impl(e1, e2) }) ##' @noRd setMethod("-", c("nanotime", "nanoperiod"), function(e1, e2) { stop(paste0("binary '-' is not defined for 'nanotime' and 'nanoperiod' objects; instead use 'minus(e1, e2, tz)'")) }) ##' @noRd setMethod("-", c("nanoperiod", "nanotime"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoperiod setMethod("-", c("nanoperiod", "numeric"), function(e1, e2) { minus_period_integer64_impl(e1, as.integer64(e2)) }) ## -- ##' @noRd setMethod("-", c("ANY", "nanoperiod"), function(e1, e2) { stop("invalid operand types") }) ## -- ##' @rdname nanoperiod setMethod("-", c("nanoduration", "nanoperiod"), function(e1, e2) { minus_integer64_period_impl(e1, e2) }) ## -- ##' @rdname nanoperiod setMethod("-", c("integer64", "nanoperiod"), function(e1, e2) { minus_integer64_period_impl(as.integer64(e1), e2) }) ## -- ##' @rdname nanoperiod setMethod("-", c("numeric", "nanoperiod"), function(e1, e2) { minus_integer64_period_impl(as.integer64(e1), e2) }) ## ----------- `+` ##' @rdname nanoperiod ##' @aliases +,ANY,nanoperiod-method setMethod("+", c("nanoperiod", "ANY"), function(e1, e2) { if (missing(e2)) { e1 } else { stop("invalid operand types") } }) ##' @rdname nanoperiod setMethod("+", c("nanoperiod", "nanoperiod"), function(e1, e2) { plus_period_period_impl(e1, e2) }) ## -- ##' @noRd setMethod("+", c("ANY", "nanoperiod"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoperiod setMethod("+", c("nanoperiod", "nanoduration"), function(e1, e2) { plus_period_integer64_impl(e1, S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanoperiod setMethod("+", c("nanoperiod", "integer64"), function(e1, e2) { plus_period_integer64_impl(e1, e2) }) ##' @rdname nanoperiod setMethod("+", c("nanoperiod", "nanotime"), function(e1, e2) { stop(paste0("binary '+' is not defined for 'nanoperiod' and 'nanotime' objects; instead use 'plus(e1, e2, tz)'")) }) ##' @rdname nanoperiod setMethod("+", c("nanoival", "nanoperiod"), function(e1, e2) { stop(paste0("binary '+' is not defined for 'nanoival' and 'nanoperiod' objects; instead use 'plus(e1, e2, tz)'")) }) ##' @rdname nanoperiod setMethod("+", c("nanoperiod", "nanoival"), function(e1, e2) { stop(paste0("binary '+' is not defined for 'nanoperiod' and 'nanoival' objects; instead use 'plus(e1, e2, tz)'")) }) ##' @rdname nanoperiod setMethod("+", c("nanotime", "nanoperiod"), function(e1, e2) { stop(paste0("binary '+' is not defined for 'nanotime' and 'nanoperiod' objects; instead use 'plus(e1, e2, tz)'")) }) ##' @rdname nanoperiod setMethod("+", c("nanoperiod", "numeric"), function(e1, e2) { plus_period_integer64_impl(e1, as.integer64(e2)) }) ## -- ##' @rdname nanoperiod setMethod("+", c("nanoduration", "nanoperiod"), function(e1, e2) { plus_period_integer64_impl(e2, e1) }) ##' @rdname nanoperiod setMethod("+", c("integer64", "nanoperiod"), function(e1, e2) { plus_period_integer64_impl(e2, e1) }) ##' @rdname nanoperiod setMethod("+", c("numeric", "nanoperiod"), function(e1, e2) { plus_period_integer64_impl(e2, as.integer64(e1)) }) ## ----------- `*` ##' @noRd setMethod("*", c("ANY", "nanoperiod"), function(e1, e2) { stop("invalid operand types") }) ##' @noRd setMethod("*", c("nanoperiod", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoperiod ##' @aliases *,nanoperiod,ANY-method *,ANY,nanoperiod-method setMethod("*", c("nanoperiod", "integer64"), function(e1, e2) { multiplies_period_integer64_impl(e1, e2) }) ##' @rdname nanoperiod setMethod("*", c("nanoperiod", "numeric"), function(e1, e2) { multiplies_period_double_impl(e1, e2) }) ##' @rdname nanoperiod setMethod("*", c("integer64", "nanoperiod"), function(e1, e2) { multiplies_period_integer64_impl(e2, e1) }) ##' @rdname nanoperiod setMethod("*", c("numeric", "nanoperiod"), function(e1, e2) { multiplies_period_double_impl(e2, e1) }) ## ----------- `/` ##' @rdname nanoperiod ##' @noRd setMethod("/", c("ANY", "nanoperiod"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoperiod ##' @noRd setMethod("/", c("nanoperiod", "ANY"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanoperiod setMethod("/", c("nanoperiod", "integer64"), function(e1, e2) { divides_period_integer64_impl(e1, e2) }) ##' @rdname nanoperiod setMethod("/", c("nanoperiod", "numeric"), function(e1, e2) { divides_period_double_impl(e1, e2) }) ## Compare ## ------- ##' @noRd setMethod("Compare", c("ANY", "nanoperiod"), function(e1, e2) { stop("operation not defined for 'nanoperiod' objects") }) ##' @noRd setMethod("Compare", c("nanoperiod", "ANY"), function(e1, e2) { stop("operation not defined for 'nanoperiod' objects") }) ##' @rdname nanoperiod setMethod("==", c("nanoperiod", "nanoperiod"), function(e1, e2) eq_period_period_impl(e1, e2)) ##' @rdname nanoperiod setMethod("!=", c("nanoperiod", "nanoperiod"), function(e1, e2) ne_period_period_impl(e1, e2)) ## ---------- plus/minus ops with nanotime and nanoperiod (which require 'tz') ##' @noRd setGeneric("plus", function(e1, e2, tz) standardGeneric("plus")) ##' @noRd setGeneric("minus", function(e1, e2, tz) standardGeneric("minus")) ##' @rdname nanoperiod ##' @aliases plus setMethod("plus", c("nanotime", "nanoperiod", "character"), function(e1, e2, tz) { plus_nanotime_period_impl(e1, e2, tz) }) ##' @rdname nanoperiod setMethod("plus", c("nanoperiod", "nanotime", "character"), function(e1, e2, tz) { plus_nanotime_period_impl(e2, e1, tz) }) ##' @rdname nanoperiod ##' @aliases minus setMethod("minus", c("nanotime", "nanoperiod", "character"), function(e1, e2, tz) { minus_nanotime_period_impl(e1, e2, tz) }) ##' @rdname nanoperiod setMethod("minus", c("nanoperiod", "nanotime", "character"), function(e1, e2, tz) { stop("operation not defined for 'nanoperiod' objects") }) ## ---------- plus/minus ops with nanoival and nanoperiod (which require 'tz') ##' @rdname nanoperiod setMethod("plus", c("nanoival", "nanoperiod", "character"), function(e1, e2, tz) { plus_nanoival_period_impl(e1, e2, tz) }) ##' @rdname nanoperiod setMethod("plus", c("nanoperiod", "nanoival", "character"), function(e1, e2, tz) { plus_nanoival_period_impl(e2, e1, tz) }) ##' @rdname nanoperiod setMethod("minus", c("nanoival", "nanoperiod", "character"), function(e1, e2, tz) { minus_nanoival_period_impl(e1, e2, tz) }) ##' @rdname nanoperiod ##' @noRd setMethod("minus", c("nanoperiod", "nanoival", "character"), function(e1, e2, tz) { stop("operation not defined for 'nanoperiod' objects") }) ##' Test if Two Objects are (Nearly) Equal ##' ##' Compare \code{target} and \code{current} testing \sQuote{near ##' equality}. If they are different, comparison is still made to ##' some extent, and a report of the differences is returned. Do not ##' use \code{all.equal} directly in \code{if} expressions---either ##' use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if ##' appropriate. ##' ##' @param target,current \code{nanoperiod} arguments to be compared ##' @param ... further arguments for different methods ##' @param check.attributes logical indicating if the ##' \code{attributes} of \code{target} and \code{current} (other than ##' the names) should be compared. ##' ##' @seealso \code{\link{identical}}, \code{\link{isTRUE}}, ##' \code{\link{==}}, and \code{\link{all}} for exact equality ##' testing. ##' ##' @method all.equal nanoperiod ##' all.equal.nanoperiod <- function(target, current, ..., check.attributes = TRUE) all.equal.raw(target, current, ..., check.attributes) ##' @rdname all.equal.nanoperiod setMethod("all.equal", c(target = "nanoperiod", current="ANY"), all.equal.nanoperiod) ##' @rdname nanoperiod NA_nanoperiod_ <- new("nanoperiod", complex(1, -1.0609978954826362e-314, 0)) ##' @rdname rounding ##' @param origin a \code{nanotime} scalar indicating the origin at which the rounding is considered ##' @param tz a \code{character} scalar indicating the time zone in which to conduct the rounding setMethod("nano_ceiling", c(x="nanotime", precision="nanoperiod"), function(x, precision, origin=nanotime(), tz) { if (!inherits(origin, "nanotime")) { stop("'origin' must be of class 'nanotime'") } if (!is.character(tz)) { stop("'tz' must be of type 'character'") } if (is.unsorted(x)) { stop("'x' must be sorted") } ceiling_tz_impl(x, precision, origin, tz) }) ##' @rdname rounding setMethod("nano_floor", c(x="nanotime", precision="nanoperiod"), function(x, precision, origin=nanotime(), tz) { if (!inherits(origin, "nanotime")) { stop("'origin' must be of class 'nanotime'") } if (!is.character(tz)) { stop("'tz' must be of type 'character'") } if (is.unsorted(x)) { stop("'x' must be sorted") } floor_tz_impl(x, precision, origin, tz) }) ##' Replicate Elements ##' ##' Replicates the values in 'x' similarly to the default method. ##' ##' @param x a vector of \code{nanoperiod} ##' @param ... further arguments: ##' ##' 'times' an integer-valued vector giving the (non-negative) ##' number of times to repeat each element if of length ##' 'length(x)', or to repeat the whole vector if of length ##' 1. Negative or 'NA' values are an error. A 'double' ##' vector is accepted, other inputs being coerced to an ##' integer or double vector. ##' ##' 'length.out' non-negative integer. The desired length of the ##' output vector. Other inputs will be coerced to a double ##' vector and the first element taken. Ignored if 'NA' or ##' invalid. ##' ##' 'each' non-negative integer. Each element of 'x' is repeated ##' 'each' times. Other inputs will be coerced to an integer ##' or double vector and the first element taken. Treated as ##' '1' if 'NA' or invalid. setMethod("rep", c(x = "nanoperiod"), function(x, ...) { new("nanoperiod", callNextMethod()) }) nanotime/R/nanotime.R0000644000176200001440000011567514737237252014255 0ustar liggesusers##' @rdname nanotime setClass("nanotime", contains = "integer64") ## setClass("nanotime", contains = "numeric") also possible if we don't want integer64 ##' Nanosecond resolution datetime functionality ##' ##' Functions to operate on nanosecond time resolution using integer64 ##' bit representation. Conversion functions for several standard R ##' types are provided, and more will be added as needed. ##' ##' Notice that the conversion from POSIXct explicitly sets the last ##' three digits to zero. Nanosecond time stored in a 64-bit integer ##' has nineteen digits precision where doubles (which are used ##' internally for POSIXct as well) only have sixteen digits. So ##' rather than showing three more (essentially \emph{random}) digits ##' it is constructed such that these three additional digits are ##' zeros. ##' ##' @section Caveats: ##' ##' Working with dates and times is \emph{difficult}. One needs a ##' representation of both \emph{time points} and \emph{time ##' duration}. In R, think of \code{Date} or \code{POSIXct} objects ##' for the former, and \code{difftime} for the later. Here we have ##' time points \code{nanotime}, an interval type \code{nanoival} and ##' two flavors of duration which are a simple count of nanoseconds ##' \code{nanoduration} and a calendar duration that is able to track ##' concepts such as months and days \code{nanoperiod}. Point in time ##' and intervals are all based on durations relative to the epoch of ##' January 1, 1970. ##' ##' @section Input and Output Format: ##' ##' Formatting and character conversion for \code{nanotime} objects is ##' done by functions from the \pkg{RcppCCTZ} package relying ##' on code from its embedded \code{CCTZ} library. The default format ##' is ISO3339 compliant: \code{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez}. It ##' specifies a standard ISO 8601 part for date and time --- as well ##' as nine digits of precision for fractional seconds (down to ##' nanoseconds) and on offset (typically zero as we default to UTC). ##' It can be overriden by using \code{options()} with the key of ##' \code{nanotimeFormat} and a suitable value. Similarly, ##' \code{nanotimeTz} can be used to select a different timezone. ##' ##' For input, some slack it cut, and various shortened formats are ##' accepted by default such as \code{2020-03-10} or \code{2020-03-10 ##' 18:16:00}, or \code{2020-03-10 18:16:00.001} (and the \sQuote{T} ##' separator is optional. ##' ##' @section \code{tz} parameter usage in constructors: ##' ##' The \code{tz} parameter is allowed only when constructing a ##' \code{nanotime} from a \code{character}. This is because any ##' \code{numeric}, \code{Date} and \code{POSIXct} is de facto ##' considered an offset since the epoch. On the contrary, a ##' \code{character} is considered interpretable and hence if it does ##' not contain a timezone in its representation, it is possible to ##' specify the \code{tz} argument to specify in which timezone it ##' should be interpreted. This is useful in particular if one wants ##' to convert a \code{Date} to be aligned to the beginning of the day ##' in a specific timezone; in this case one should convert the ##' \code{Date} to a \code{character} before calling the ##' \code{nanotime} constructor with the desired timezone. ##' ##' @param x,from \code{nanotime} objects ##' @param tz character specifying a timezone which is required for ##' \code{as.POSIXct}, \code{as.POSIXlt} and can be specified for ##' \code{as.nanotime}, \code{format} and \code{print}; it can ##' also be set via \code{options("nanotimeTz")} and uses ##' \sQuote{UTC} as a default and fallback ##' @param ... further arguments passed to or from methods. ##' @param e1 Operand of class \code{nanotime} ##' @param e2 Operand of class \code{nanotime} ##' @param format A character string. Can also be set via ##' \code{options("nanotimeFormat")} and uses ##' \sQuote{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez} as a default and ##' fallback ##' @param digits Required for \code{Math2} signature but ignored here ##' @param object argument for method \code{show} ##' @param na.rm a logical indicating whether missing values should be ##' removed. ##' @param i index specifying elements to extract or replace. ##' @param j Required for \code{[} signature but ignored here ##' @param drop Required for \code{[} signature but ignored here ##' @param z Required for \code{Complex} signature but ignored here ##' @param value argument for \code{nanotime-class} ##' @param quote indicates if the output of \code{print} should be ##' quoted ##' @param accurate in the conversion from \code{POSIXct} to ##' \code{nanotime}, indicates if one wants to preserve the ##' maximum precision possible; the default is \code{TRUE}, but in ##' most situations the loss of precision is negligible, and ##' setting this parameter to \code{FALSE} will make the ##' conversion nearly an order of magnitude faster ##' @return A nanotime object ##' @author Dirk Eddelbuettel ##' @author Leonardo Silvestri ##' @examples ##' \dontrun{ ##' x <- nanotime(1) ##' print(x) ##' as.nanotime("1970-01-01T00:00:00.000000001+00:00") ##' as.nanotime("2020-03-10 Europe/Berlin") ##' as.nanotime("2020-03-10 18:31:23.001", tz="America/New_York") ##' as.nanotime("2020-03-10T040947190301440", format="%Y-%m-%dT%H%M%S%E*f") ##' x <- x + 1 ##' print(x) ##' format(x) ##' x <- x + 10 ##' print(x) ##' format(x) ##' nanotime(Sys.time()) + 1:3 # three elements each 1 ns apart ##' seq(x, by=as.nanoperiod("1d"), length.out=5, tz="Asia/Tokyo") ##' } ##' @seealso \code{\link{nanoival}}, \code{\link{nanoduration}}, ##' \code{\link{nanoperiod}}, \code{\link{seq.nanotime}} as well as ##' the documentation in package \pkg{RcppCCTZ}. nanotime <- function(from, ...) { if (missing(from)) { from = NULL } new("nanotime", as.integer64(from, keep.names=TRUE)) } ##' @noRd setGeneric("nanotime") ##' @rdname nanotime as.nanotime <- function(from, ...) { if (missing(from)) { from = NULL } new("nanotime", as.integer64(from, keep.names=TRUE)) } ##' @noRd setGeneric("as.nanotime") setAs("integer64", "nanotime", function(from) new("nanotime", as.integer64(from, keep.names=TRUE))) .getTz <- function(x, tz="") { if (tz=="") { if (!is.null(tzone <- attr(x, "tzone"))) tz <- tzone else tz <- getOption("nanotimeTz", default="UTC") } tz } .getFormat <- function(format="") { if (format=="") { format <- getOption("nanotimeFormat", default="%Y-%m-%dT%H:%M:%EXS%Ez") } format } .secondaryNanotimeParse <- function(x, format="", tz="") { if (length(x) == 0) return(character(0)) # nocov format <- gsub("%EXS", "%E9S", .getFormat(format)) tz <- .getTz(x, tz) n <- names(x) d <- RcppCCTZ::parseDouble(x, fmt=format, tzstr=tz) res <- new("nanotime", as.integer64(d[,1]) * as.integer64(1e9) + as.integer64(d[, 2])) if (!is.null(n)) { names(S3Part(res, strictS3=TRUE)) <- n } res } .nanotime_character <- function(from, format="", tz="") { tryCatch(nanotime_make_impl(from, tz), error=function(e) { if (grepl("Cannot retrieve timezone", e$message) || e$message == "timezone is specified twice: in the string and as an argument") { stop(e$message) } else { .secondaryNanotimeParse(from, format, tz) } }) } ##' @rdname nanotime setMethod("nanotime", "character", .nanotime_character) ##' @rdname nanotime setMethod("as.nanotime", "character", .nanotime_character) setAs("character", "nanotime", function(from) .nanotime_character(from)) ##' @rdname nanotime ## This does not lead to S3 dispatch, the call must be 'nanotime.matrix' nanotime.matrix <- function(x) { n <- names(x) res <- new("nanotime", as.integer64(x[,1]) * as.integer64(1e9) + as.integer64(x[, 2])) if (!is.null(n)) { names(res) <- n ## #nocov } res } .nanotime_posixct <- function(from, accurate=TRUE) { n <- names(from) from <- as.numeric(from) if (accurate) { frac <- from - trunc(from) res <- new("nanotime", bit64::as.integer64(from)*1e9 + round(frac*1e9)) } else { res <- new("nanotime", bit64::as.integer64(as.numeric(from) * 1e9)) } if (!is.null(n)) { names(S3Part(res, strictS3=TRUE)) <- n } res } ##' @rdname nanotime setMethod("nanotime", signature(from="POSIXct"), .nanotime_posixct) ##' @rdname nanotime setMethod("as.nanotime", signature(from="POSIXct"), .nanotime_posixct) setAs("POSIXct", "nanotime", function(from) .nanotime_posixct(from)) ##' @rdname nanotime setMethod("nanotime", "POSIXlt", function(from) nanotime(as.POSIXct(from))) ##' @rdname nanotime setMethod("as.nanotime", "POSIXlt", function(from) nanotime(as.POSIXct(from))) setAs("POSIXlt", "nanotime", function(from) nanotime(as.POSIXct(from))) ##' @rdname nanotime setMethod("nanotime", "Date", function(from) nanotime(as.POSIXct(from))) ##' @rdname nanotime setMethod("as.nanotime", "Date", function(from) nanotime(as.POSIXct(from))) setAs("Date", "nanotime", function(from) nanotime(as.POSIXct(from))) ##' @rdname nanotime setMethod("print", "nanotime", function(x, format="", tz="", quote=FALSE, ...) { format <- .getFormat(format) tz <- .getTz(x, tz) max.print <- options()$max.print if (length(x) > max.print) { ## #nocov start f <- head(x, max.print) print(format(f, format, tz, ...), quote=quote) cat(paste(' [ reached getOption("max.print") -- omitted', length(x) - max.print, "entries ]\n")) } ## #nocov end else { print(format(x, format, tz, ...), quote=quote) } invisible(x) }) ##' @rdname nanotime setMethod("show", signature("nanotime"), function(object) print(object)) ## #nocov ##' @rdname nanotime format.nanotime <- function(x, format="", tz="", ...) { if (length(x) == 0) { "nanotime(0)" } else { format <- .getFormat(format) tz <- .getTz(x, tz) if (length(x) == 0) { return(character(0)) ## #nocov } bigint <- as.integer64(x) secs <- as.integer64(bigint / as.integer64(1000000000)) nanos <- bigint - secs * as.integer64(1000000000) nanos_notna <- nanos[!is.na(nanos)] ## EXS has special meaning for us: print with the least number of nanotime digits if (length(nanos_notna) != 0 && isTRUE(as.logical(grep("%EXS", format)))) { if (all(nanos_notna %% 1000000000 == 0)) { format <- gsub("%EXS", "%S", format) } else if (all(nanos_notna %% 1000000 == 0)) { format <- gsub("%EXS", "%E3S", format) } else if (all(nanos_notna %% 1000 == 0)) { format <- gsub("%EXS", "%E6S", format) } else { format <- gsub("%EXS", "%E9S", format) } } isna <- is.na(x) if (any(isna)) { secs[isna] <- 0 nanos[isna] <- 0 } res <- RcppCCTZ::formatDouble(as.double(secs), as.double(nanos), fmt=format, tgttzstr=tz) res[isna] <- as.character(NA) n <- names(x) if (!is.null(n)) { names(res) <- n } res } } ##' @rdname nanotime index2char.nanotime <- function(x, ...) { bigint <- as.integer64(x) secs <- as.integer64(bigint / as.integer64(1000000000)) nanos <- bigint - secs * as.integer64(1000000000) RcppCCTZ::formatDouble(as.double(secs), as.double(nanos), fmt=getOption("nanotimeFormat", default="%Y-%m-%dT%H:%M:%E9S%Ez"), tgttzstr=getOption("nanotimeTz", default="UTC")) } ##' @rdname nanotime as.POSIXct.nanotime <- function(x, tz="", ...) { ## if (verbose) warning("Lossy conversion dropping precision") if ((tz == "" || is.null(tz)) && length(attr(x, "tzone")) > 0) { tz <- attr(x, "tzone") } pt <- as.POSIXct(as.double(S3Part(x, strictS3=TRUE)/1e9), tz=tz, origin="1970-01-01") pt } setAs("nanotime", "POSIXct", function(from) as.POSIXct.nanotime(from)) ##' @rdname nanotime as.POSIXlt.nanotime <- function(x, tz="", ...) { as.POSIXlt(as.POSIXct(x, tz=tz)) } setAs("nanotime", "POSIXlt", function(from) as.POSIXlt.nanotime(from)) ##' @rdname nanotime as.Date.nanotime <- function(x, ...) { arguments <- list(...) if (!("tz" %in% names(args))) { arguments <- c(arguments, list(tz="UTC")) } other_args <- setdiff(names(arguments), list('x', 'tz')) if (length(other_args) > 0) { stop(paste("'as.Date' called with arguments other than 'tz': ", paste0("'", other_args, "'", collapse=", "))) } as.Date(ISOdate(year = nano_year(x, arguments$tz), month = nano_month(x, arguments$tz), day = nano_mday(x, arguments$tz))) } setAs("nanotime", "Date", function(from) as.Date(as.POSIXct(from))) ##' @rdname nanotime as.data.frame.nanotime <- function(x, ...) { ret <- as.data.frame(S3Part(x, strictS3=TRUE), ...) ## this works, but see if there's a more idiomatic and efficient way ## of doing this: ret[] <- nanotime(S3Part(x, strictS3=TRUE)) ret } ##' @rdname nanotime ##' @method as.integer64 nanotime as.integer64.nanotime <- function(x, ...) { S3Part(x, strictS3=TRUE) } setAs("nanotime", "integer64", function(from) S3Part(from, strictS3=TRUE)) ## ------------ `-` ##' @rdname nanotime setMethod("-", c("nanotime", "character"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanotime setMethod("-", c("nanotime", "nanotime"), function(e1, e2) { new("nanoduration", S3Part(e1, strictS3=TRUE) - S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanotime setMethod("-", c("nanotime", "integer64"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) - e2) }) ##' @rdname nanotime setMethod("-", c("nanotime", "numeric"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) - e2) }) ##' @rdname nanotime setMethod("-", c("ANY", "nanotime"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanotime setMethod("-", c("nanotime", "ANY"), function(e1, e2) { if (missing(e2)) { stop("unary '-' is not defined for \"nanotime\" objects") } else { stop("invalid operand types") ## #nocov } }) ## ----------- `+` ##' @rdname nanotime setMethod("+", c("nanotime", "ANY"), function(e1, e2) { if (missing(e2)) { stop("unary '+' is not defined for \"nanotime\" objects") ## #nocov } else { stop("invalid operand types") } }) ##' @rdname nanotime setMethod("+", c("nanotime", "integer64"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) + e2) }) ##' @rdname nanotime setMethod("+", c("nanotime", "numeric"), function(e1, e2) { new("nanotime", S3Part(e1, strictS3=TRUE) + e2) }) ##' @rdname nanotime setMethod("+", c("ANY", "nanotime"), function(e1, e2) { stop("invalid operand types") }) ##' @rdname nanotime setMethod("+", c("integer64", "nanotime"), function(e1, e2) { new("nanotime", e1 + S3Part(e2, strictS3=TRUE)) ## #nocov }) ##' @rdname nanotime setMethod("+", c("numeric", "nanotime"), function(e1, e2) { new("nanotime", e1 + S3Part(e2, strictS3=TRUE)) }) ##' @rdname nanotime setMethod("+", c("nanotime", "nanotime"), function(e1, e2) { stop("invalid operand types") }) ## ---------- other ops ##' @rdname nanotime setMethod("Arith", c("nanotime", "nanotime"), function(e1, e2) { stop("operation not defined for \"nanotime\" objects") }) ##' @rdname nanotime setMethod("Arith", c("nanotime", "ANY"), function(e1, e2) { stop("operation not defined for \"nanotime\" objects") }) ##' @rdname nanotime setMethod("Arith", c("ANY", "nanotime"), function(e1, e2) { stop("operation not defined for \"nanotime\" objects") ## #nocov }) ##' @rdname nanotime setMethod("Compare", c("nanotime", "character"), function(e1, e2) { ne2 <- nanotime(e2) callNextMethod(e1, ne2) }) ##' @rdname nanotime setMethod("Compare", c("character", "nanotime"), function(e1, e2) { ne1 <- nanotime(e1) callNextMethod(ne1, e2) }) ##' @rdname nanotime setMethod("Compare", c("nanotime", "POSIXt"), function(e1, e2) { ne2 <- nanotime(e2) callNextMethod(e1, ne2) }) ##' @rdname nanotime setMethod("Compare", c("POSIXt", "nanotime"), function(e1, e2) { ne1 <- nanotime(e1) callNextMethod(ne1, e2) }) ##' @rdname nanotime setMethod("Compare", c("nanotime", "ANY"), function(e1, e2) { if (inherits(e2, "nanotime")) { e2 <- S3Part(e2, strictS3=TRUE) } callNextMethod(S3Part(e1, strictS3=TRUE), e2) }) ##' @rdname nanotime setMethod("Logic", c("nanotime", "ANY"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @rdname nanotime setMethod("Logic", c("ANY", "nanotime"), function(e1, e2) { ## this is the same error message that R gives for "A" | "A" stop("operations are possible only for numeric, logical or complex types") }) ##' @rdname nanotime setMethod("Math", c("nanotime"), function(x) { ## this is the same error message that R gives for abs("A") stop("non-numeric argument to mathematical function") }) ##' @rdname nanotime setMethod("Math2", c("nanotime"), function(x, digits) { ## this is the same error message that R gives for round("A") stop("non-numeric argument to mathematical function") }) ##' @rdname nanotime setMethod("Summary", c("nanotime"), function(x, ..., na.rm = FALSE) { ## this is the same error message that R gives for sum("A") stop("invalid 'type' (nanotime) of argument") }) ##' @rdname nanotime setMethod("min", c("nanotime"), function(x, ..., na.rm = FALSE) { new("nanotime", callNextMethod()) }) ##' @rdname nanotime setMethod("max", c("nanotime"), function(x, ..., na.rm = FALSE) { new("nanotime", callNextMethod()) }) ##' @rdname nanotime setMethod("range", c("nanotime"), function(x, ..., na.rm = FALSE) { new("nanotime", callNextMethod()) }) ##' @rdname nanotime setMethod("Complex", c("nanotime"), function(z) { ## this is the same error message that R gives for Arg("A") stop("non-numeric argument to function") }) ## ----------- non ops ##' @rdname nanotime setMethod("[[", signature("nanotime"), function (x, i, j, ..., drop=FALSE) { new("nanotime", callNextMethod()) }) ##' @rdname nanotime setMethod("[", signature("nanotime", "numeric"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanotime' subsetting") } if (isTRUE(any(i < 0))) { new("nanotime", S3Part(x, strictS3=TRUE)[i]) } else { nanotime_subset_numeric_impl(x, i) } }) ##' @rdname nanotime setMethod("[", signature("nanotime", "logical"), function (x, i, j, ..., drop=FALSE) { if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanotime' subsetting") } nanotime_subset_logical_impl(x, i) }) ##' @rdname nanotime setMethod("[", signature("nanotime", "character"), function (x, i, j, ..., drop=FALSE) { ## we don't implement 'period_subset_character_impl' but ## do the gymnastic of finding the NAs here at R level; ## it's not as efficient, but using 'character' indexing ## is by itself inefficient, so the overhead should have ## no practical consequences. if (!missing(j) || length(list(...)) > 0) { warning("unused indices or arguments in 'nanotime' subsetting") } na_index <- !(i %in% names(x)) | is.na(i) res <- new("nanotime", S3Part(x, strictS3=TRUE)[i]) res[na_index] <- NA_nanotime_ res }) ##' @rdname nanotime setMethod("[", signature("nanotime", "ANY"), function (x, i, j, ..., drop=FALSE) { stop("']' not defined on 'nanotime' for index of type 'ANY'") }) ##' @rdname nanotime setMethod("[<-", signature("nanotime"), function (x, i, j, ..., value) { new("nanotime", callNextMethod()) }) ##' @rdname nanotime c.nanotime <- function(...) { nanotime(c.integer64(...)) } ##' @rdname nanotime ##' @name nanotime-package NULL ##' @rdname nanotime setMethod("names<-", signature("nanotime"), function(x, value) { names(S3Part(x, strictS3=TRUE)) <- value x }) ##' @rdname nanotime setMethod("is.na", signature("nanotime"), function(x) { callNextMethod(S3Part(x, strictS3=TRUE)) }) ##' Sequence Generation ##' ##' Generate a sequence of \code{nanotime} ##' ##' @param ... arguments passed to or from methods; the only ##' interesting additional argument is \code{tz} where the ##' \code{to} argument is of type \code{nanoperiod} ##' @param from,to the starting and (maximal) end values of the ##' sequence ##' @param by \code{nanoduration} or \code{nanoperiod} increment of ##' the sequence; note that if the class is \code{nanoperiod} the ##' additional argument \code{tz} must be speficied and is of ##' \code{character} type indicating a timezone ##' @param length.out integer indicating the desired length of the sequence ##' @param along.with take the length from the length of this argument. ##' @examples ##' \dontrun{ ##' from <- as.nanotime("2018-01-14T12:44:00+00:00") ##' to <- as.nanotime("2019-01-14T12:44:00+00:00") ##' seq(from, to, by=as.nanoperiod("1m"), tz="America/New_York") ##' seq(from, by=as.nanoperiod("1y"), length.out=4, tz="Europe/London") ##' } ##' @method seq nanotime seq.nanotime <- function(from, to = NULL, by = NULL, length.out = NULL, along.with = NULL, ...) { if((One <- nargs() == 1L)) { stop("'seq.nanotime' cannot be called with only one argument") } if (sum(is.null(to), is.null(by), is.null(length.out) && is.null(along.with)) > 1) { stop("at least two of 'to', 'by', and 'length.out' or 'along.with' must be specified") } is.logint <- function(.) (is.integer(.) || is.logical(.)) && !is.object(.) if (!missing(along.with) && !is.null(along.with)) { length.out <- length(along.with) } else if(!missing(length.out) && !is.null(length.out)) { len <- length(length.out) if(!len) stop("argument 'length.out' must be of length 1") if(len > 1L) { warning("first element used of 'length.out' argument") length.out <- length.out[1L] } if(!(intn1 <- is.logint(length.out))) length.out <- as.numeric(ceiling(length.out)) } if (length(from) != 1L) stop("'from' must be of length 1") if (!missing(to) && !is.null(to) && length(to) != 1L) stop("'to' must be of length 1") if (!missing(to) && !is.null(to) && !(inherits(to, "nanotime"))) stop("'to' must be a 'nanotime'") if (is.null(length.out)) { if (missing(by) || is.null(by)) stop("'by' must be specified if 'length.out' is NULL") else { # dealing with 'by' if (length(by) != 1L) stop("'by' must be of length 1") if (inherits(by, "nanoperiod")) { ## fish out the 'tz' parameter: args <- list(...) if (!any("tz" %in% names(args))) { stop("'tz' is a mandatory argument for sequences with a 'period' step") } period_seq_from_to_impl(from, to, by, args$tz) } else { nanotime(seq(as.integer64(from), as.integer64(to), by=by)) } } } else if(!is.finite(length.out) || length.out < 0L) stop("'length.out' must be a non-negative number") else if (length.out == 0L) nanotime() else if (missing(by) || is.null(by)) { ## cannot be with 'period', so just call the S3 function: ## calculate 'by' because of 'bit64' bug: by = as.integer64((to - from) / (length.out - 1)) nanotime(seq(as.integer64(from), as.integer64(to), by, NULL, NULL, ...)) } else if (missing(to) || is.null(to)) { if (length(by) != 1L) stop("'by' must be of length 1") if (inherits(by, "nanoperiod")) { ## fish out the 'tz' parameter: args <- list(...) if (!any("tz" %in% names(args))) { stop("'tz' is a mandatory argument for sequences with a 'period' step") } period_seq_from_length_impl(from, by, as.integer64(length.out), args$tz) } else { nanotime(seq(as.integer64(from), by=as.integer64(by), length.out=length.out, along.with=along.with, ...)) } } else stop("too many arguments") } ##' @rdname seq.nanotime setMethod("seq", c("nanotime"), seq.nanotime) ##' Test if Two Objects are (Nearly) Equal ##' ##' Compare \code{target} and \code{current} testing \sQuote{near ##' equality}. If they are different, comparison is still made to ##' some extent, and a report of the differences is returned. Do not ##' use \code{all.equal} directly in \code{if} expressions---either ##' use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if ##' appropriate. ##' ##' @param target,current \code{nanotime} arguments to be compared ##' @param ... further arguments for different methods ##' @param tolerance numeric >= 0. Differences smaller than ##' \code{tolerance} are not reported. The default value is close ##' to \code{1.5e-8}. ##' @param scale \code{NULL} or numeric > 0, typically of length 1 or ##' \code{length(target)}. See \sQuote{Details}. ##' @param countEQ logical indicating if the \code{target == current} cases should be ##' counted when computing the mean (absolute or relative) ##' differences. The default, \code{FALSE} may seem misleading in ##' cases where \code{target} and \code{current} only differ in a few ##' places; see the extensive example. ##' @param formatFUN a \code{function} of two arguments, \code{err}, the relative, absolute ##' or scaled error, and \code{what}, a character string indicating ##' the _kind_ of error; maybe used, e.g., to format relative and ##' absolute errors differently. ##' @param check.attributes logical indicating if the \code{attributes} of \code{target} ##' and \code{current} (other than the names) should be compared. ##' ##' @seealso \code{\link{identical}}, \code{\link{isTRUE}}, ##' \code{\link{==}}, and \code{\link{all}} for exact equality ##' testing. ##' ##' @method all.equal nanotime ##' all.equal.nanotime <- function(target, current, tolerance = sqrt(.Machine$double.eps), scale = NULL, countEQ = FALSE, formatFUN = function(err, what) format(err), ..., check.attributes = TRUE) { if (inherits(target, "nanotime")) target <- as.integer64(target) if (inherits(current, "nanotime")) current <- as.integer64(current) if (!is.numeric(tolerance)) stop("'tolerance' should be numeric") if (!is.numeric(scale) && !is.null(scale)) stop("'scale' should be numeric or NULL") if (!is.logical(check.attributes)) stop(gettextf("'%s' must be logical", "check.attributes"), domain = NA) msg <- NULL msg <- if (check.attributes) attr.all.equal(target, current, tolerance = tolerance, scale = scale, ...) if (data.class(target) != data.class(current)) { msg <- c(msg, paste0("target is ", data.class(target), ", current is ", data.class(current))) return(msg) } lt <- length(target) lc <- length(current) cplx <- is.complex(target) if (lt != lc) { if (!is.null(msg)) msg <- msg[-grep("\\bLengths\\b", msg)] msg <- c(msg, paste0(if (cplx) "Complex" else "Numeric", ": lengths (", lt, ", ", lc, ") differ")) return(msg) } out <- is.na(target) if (any(out != is.na(current))) { msg <- c(msg, paste("'is.NA' value mismatch:", sum(is.na(current)), "in current", sum(out), "in target")) return(msg) } out <- out | target == current if (all(out)) return(if (is.null(msg)) TRUE else msg) if (countEQ) { N <- length(out) sabst0 <- sum(abs(target[out])) } else { sabst0 <- 0 } target <- target[!out] current <- current[!out] if (!countEQ) N <- length(target) ## the following is in the orignal function, but can't be reached here: ## if (is.integer(target) && is.integer(current)) ## target <- as.double(target) xy <- sum(abs(target - current))/N what <- if (is.null(scale)) { xn <- (sabst0 + sum(abs(target)))/N if (is.finite(xn) && xn > tolerance) { xy <- xy/xn "relative" } else { "absolute" } } else { stopifnot(all(scale > 0)) xy <- xy/scale if (all(abs(scale - 1) < 1e-07)) "absolute" else "scaled" } if (cplx) what <- paste(what, "Mod") # nocov if (is.na(xy) || xy > tolerance) msg <- c(msg, paste("Mean", what, "difference:", formatFUN(xy, what))) if (is.null(msg)) { TRUE # nocov } else msg } ##' @rdname all.equal.nanotime setMethod("all.equal", c(target = "nanotime", current="ANY"), all.equal.nanotime) ##' @rdname nanotime NA_nanotime_ <- nanotime(NA) ##' Get a component of a date time ##' ##' Get a component of a date time. \code{nano_wday} returns the ##' numeric position in a week, with Sunday == 0. \code{nano_mday} ##' returns the numeric day (i.e. a value from 1 to ##' 31). \code{nano_month} returns the month (i.e. a value from 1 to ##' 12). \code{nano_year} returns the year. ##' ##' Note that the \code{tz} parameter is mandatory because the day ##' boundary is different depending on the time zone and ##' \code{nanotime} does not store the timezone as it is just an ##' offset in nanoseconds from the epoch. ##' ##' @param x a \code{nanotime} object ##' @param tz \code{character} a string representing a timezone ##' @examples ##' \dontrun{ ##' nano_wday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/New_York") ##' nano_wday(as.nanotime("2020-03-14 23:32:00 America/New_York"), "Europe/Paris") ##' nano_mday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/New_York") ##' nano_mday(as.nanotime("2020-03-14 23:32:00 America/New_York"), "Europe/Paris") ##' nano_month(as.nanotime("2020-12-31 23:32:00-04:00"), "America/New_York") ##' nano_month(as.nanotime("2020-12-31 23:32:00 America/New_York"), "Europe/Paris") ##' nano_year(as.nanotime("2020-12-31 23:32:00-04:00"), "America/New_York") ##' nano_year(as.nanotime("2020-12-31 23:32:00 America/New_York"), "Europe/Paris") ##' } ##' ##' @rdname nano_year ##' @aliases nano_wday ##' @aliases nano_wday,nanotime-method nano_mday,nanotime-method ##' @aliases nano_month,nanotime-method nano_year,nanotime-method ##' setGeneric("nano_wday", function(x, tz) standardGeneric("nano_wday")) setMethod("nano_wday", c("nanotime"), function(x, tz) nanotime_wday_impl(x, tz)) ##' @rdname nano_year ##' @aliases nano_mday ##' setGeneric("nano_mday", function(x, tz) standardGeneric("nano_mday")) setMethod("nano_mday", c("nanotime"), function(x, tz) nanotime_mday_impl(x, tz)) ##' @rdname nano_year ##' @aliases nano_month ##' setGeneric("nano_month", function(x, tz) standardGeneric("nano_month")) setMethod("nano_month", c("nanotime"), function(x, tz) nanotime_month_impl(x, tz)) ##' @rdname nano_year ##' setGeneric("nano_year", function(x, tz) standardGeneric("nano_year")) setMethod("nano_year", c("nanotime"), function(x, tz) nanotime_year_impl(x, tz)) ## rounding ops: ##' Rounding down or up a \code{nanotime} type ##' ##' The functions \code{nano_floor} and \code{nano_ceiling} round down or up, respectively. Although ##' the underlying implementation of \code{nanotime} has negative numbers for values before ##' 1970-01-01 UTC, the rounding is always done backward in time for \code{nano_floor} and forward ##' in time for \code{nano_ceiling}. The functions take a \code{nanotime} argument \code{x} which is ##' the instance to round, together with a second argument \code{precision} which indicates an ##' arbitrary precision to which the rounding should be performed. This argument can be either a ##' \code{nanoduration} or or a \code{nanoperiod}. In the latter case, the argument \code{tz} must ##' also be specified in order to give the \code{nanoperiod} a meaning. Finally, the \code{nanotime} ##' argument \code{origin} can be optionally specified to fix the rounding to a specific point in ##' time. ##' ##' This flexible rounding must be understood in the context of a vector. The rounding precision can ##' then be considered as an interval that defines a grid over which the elements are either ##' assigned to the starting value of the interval to which they belong (\code{nano_floor}) or the ##' ending value of the interval to which they belong (\code{nano_ceiling}). This allows for a ##' grouping of a \code{nanotime} vector on which a statistic may then be run. In the examples ##' below, such a use case is shown in the context of a \code{data.table} object. ##' ##' If "business" concepts such as month or days are needed, the \code{argument} precision must be ##' of type \code{period}. It is then mandatory to specify the timezone argument \code{tz} as this ##' ensures timezone correctness of the intervals including for example for the rare hourly ##' transitions of some countries going from a timezone with a whole hour difference with UTC to one ##' with a fractional hour difference. In the case of a \code{period}, the functions align the ##' rounding if the precision is an integer divisor of a larger quantity. For instance, if one ##' specifies a rounding of 6 hours, a divisor of a day, the hours are aligned on days and the ##' rounding is made to a grid at hours 0, 6, 12 and 18 in the specified timezone. If the precision ##' is not a divisor, the grid is aligned to the nearest hour before the first element of the vector ##' to round. ##' ##' The argument \code{origin} controls the reference point of the rounding, allowing arbitrary ##' specification of the reference point of the rounding. ##' ##' @param x a \code{nanotime} object which must be sorted ##' @param precision a \code{nanoduration} or \code{nanoperiod} object ##' indicating the rounding precision ##' @param ... for future additional arguments ##' @examples ##' \dontrun{ ##' ## "classic" rounding: ##' nano_floor(as.nanotime("2010-10-10 11:12:15 UTC"), as.nanoduration("01:00:00")) ##' ## rounding with arbitrary precision: ##' nano_floor(as.nanotime("2010-10-10 11:12:15 UTC"), as.nanoduration("06:00:00")) ##' nano_floor(as.nanotime("2010-10-10 11:23:15 UTC"), as.nanoduration("00:15:00")) ##' nano_ceiling(as.nanotime("2010-10-10 11:23:15 UTC"), as.nanoduration("01:15:23")) ##' ## controlling the reference point via the 'origin' argument: ##' nano_ceiling(as.nanotime("2010-10-10 11:23:15 UTC"), ##' as.nanoduration("01:15:23"), ##' origin=as.nanotime("2010-10-10 11:23:15 UTC")) ##' ## using business concepts and rounding across a daylight saving change: ##' v <- seq(as.nanotime("2020-03-08 America/New_York"), ##' by=as.nanoperiod("06:00:00"), length.out=8, tz="America/New_York") ##' print(nano_floor(v, as.nanoperiod("1d"), tz="America/New_York"), tz="America/New_York") ##' ## using the concept in a 'data.table': ##' library(data.table) ##' n <- 3 * 24 ##' idx <- seq(as.nanotime("2020-03-07 America/New_York"), ##' by=as.nanoperiod("01:00:00"), length.out=n, tz="America/New_York") ##' dt <- data.table(idx, a=1:n, b=2:(n+1)) ##' dt_mean <- dt[, list(mean = mean(a)), ##' by=nano_ceiling(idx, as.nanoperiod("1d"), tz="America/New_York")] ##' } ##' ##' @aliases nano_floor ##' ##' @rdname rounding setGeneric("nano_ceiling", def = function(x, precision, ...) standardGeneric("nano_ceiling")) ##' @rdname rounding setGeneric("nano_floor", def = function(x, precision, ...) standardGeneric("nano_floor")) ##' Replicate Elements ##' ##' Replicates the values in 'x' similarly to the default method. ##' ##' @param x a vector of \code{nanotime} ##' @param ... further arguments: ##' ##' 'times' an integer-valued vector giving the (non-negative) ##' number of times to repeat each element if of length ##' 'length(x)', or to repeat the whole vector if of length ##' 1. Negative or 'NA' values are an error. A 'double' ##' vector is accepted, other inputs being coerced to an ##' integer or double vector. ##' ##' 'length.out' non-negative integer. The desired length of the ##' output vector. Other inputs will be coerced to a double ##' vector and the first element taken. Ignored if 'NA' or ##' invalid. ##' ##' 'each' non-negative integer. Each element of 'x' is repeated ##' 'each' times. Other inputs will be coerced to an integer ##' or double vector and the first element taken. Treated as ##' '1' if 'NA' or invalid. setMethod("rep", c(x = "nanotime"), function(x, ...) { new("nanotime", callNextMethod()) }) ##' @rdname nanotime as.character.nanotime <- function(x, ...) { format(x, ...) } if (getRversion() > "4.5.0") { ##' @rdname nanotime setMethod("unique", "nanotime", function(x) { res <- callNextMethod() oldClass(res) <- "integer64" new("nanotime", res) }) } nanotime/cleanup0000755000176200001440000000012114740324203013432 0ustar liggesusers#!/bin/sh rm -fr src/*.o src/*.so src/*.dll src/*.dylib *~ */*~ vignettes/auto/ nanotime/demo/0000755000176200001440000000000014671560166013024 5ustar liggesusersnanotime/demo/00Index0000644000176200001440000000011214671560153014144 0ustar liggesusersnanosecondDelayExample Simulated example of network delay in nanoseconds nanotime/demo/nanosecondDelayExample.R0000644000176200001440000000266313035016762017567 0ustar liggesuserslibrary(nanotime) suppressMessages(library(data.table)) suppressMessages(library(ggplot2)) set.seed(42) N <- 300 rainyday <- ISOdatetime(2016,9,28,8,30,0) # made up shinyday <- ISOdatetime(2016,9,21,8,30,0) # made up too rdsent <- nanotime(rainyday) + cumsum(10*rpois(N, lambda=4)) # random sent time sdsent <- nanotime(shinyday) + cumsum(10*rpois(N, lambda=4)) # identical sent process for both rdrecv <- rdsent + 10*rlnorm(N, 0.30, 0.25) # postulate higher mean and sd sdrecv <- sdsent + 10*rlnorm(N, 0.10, 0.20) # for rainy than shiny raw <- data.table(rdsent, rdrecv, sdsent, sdrecv) raw[, `:=`(rainy=as.numeric(rdrecv-rdsent), shiny=as.numeric(sdrecv-sdsent))] ## melt into long format plotdata <- melt(raw[,.(rainy,shiny)], measure.vars=1:2, variable.name="day", value.name="time") ## and plot ggplot(plotdata, aes(day, time)) + geom_violin(aes(fill=day)) + coord_flip() + ylab("Message Time in Nanoseconds") + xlab("Weather Conditions") + ggtitle("Nanosecond Delay", "Under Different Weather Conditions") tfile <- tempfile(pattern="raw", fileext=".csv") fwrite(raw, file=tfile) cooked <- fread(tfile) ## csv files are not 'typed' so need to recover types explicitly cooked[, `:=`(rdsent=nanotime(rdsent), rdrecv=nanotime(rdrecv), sdsent=nanotime(sdsent), sdrecv=nanotime(sdrecv))] ## now saved and restrored data are identical all.equal(raw, cooked) nanotime/vignettes/0000755000176200001440000000000014740324203014073 5ustar liggesusersnanotime/vignettes/nanotime-intro.pdf0000644000176200001440000065542313705546565017571 0ustar liggesusers%PDF-1.5 %ÐÔÅØ 103 0 obj << /Length 4648 /Filter /FlateDecode >> stream xÚÕ;]“Û6’ïþªÜ‹¦Î¢ €Ho݃7Ù¤œÚK.ñä²[ñÖEQÏ©ÔL&µ?~»Ñ ~4;©«ÝØ1Ah4ú»P¸Ø-ÂÅW/Âù3“H¨E(+µ§‰4‹>_øôýW/þxûâÕ—*\H$ÂÆ‹ÛíB‹ ÖÉŠ$ˆb¹¸Ý,~ZViUwÅ!}³Šâdùæf¥Œ]nÒ.Ç^|3˲XߨpÙ¤7J,›r_t{j!ˆ6Ïêjsó·Û¯å•T°¦ ŽnRž7+±l‹ºÂA£=â܉ûx¿úRHµ°ˆ´B¤œ ´IÜEóáf%m¼üÓæF„ËM^®od¸<å]——D Xk`¢ ¶ÑB‘ÒCøaãutÇÉb5–Ò†Îà¸øÉaðç¼®ÒWßÔ„Ó»¢¼ËÛ®)Î!ë@$vŒˆ¼ŸfF¥À™+¡M €¿+aÊÑ6.ÌŽ&Ú&8[a ¨Ë<ù"?Þ«(\v‡¼ê÷zË{èÒ®h»"ko„^¾¤ÎªâîFêeÞ´E÷0ð¶,‹ª.&ÛuZ¥«Ï÷éᘻ±¬øËÛ?û!ïÞüá™Û—¡ L¨£ÈOÞûÓ$»nòºÿýÅ —b€ÿ~=$ü€—ýIDÞžâ 4®ãqNùkVŽE™o˜<äk§ %³H ÞM8–úPYã$ ,l%Ñ‚ÄÐ{©4Û`Þ;Ži†à?¤¨y;Pèpé¾DË÷¡‰jJL˜ô{½:Å9¯¶:ê›6Ñ¢Z?‡ž³„&C‘̧’‚V8:­­ñŸ»b“·Œ}Ìê}ÞZ@g›wÔíÄ:ºüp¬›´¤ÞîáHÓ#¿^nOUÖÓ¸Ÿ,¥'([JFì"²7K –)-·½²¬‘á÷+²«À)‰fcXTÀÙ‹(^¦MN}³=nÀÂ+/uá¶C‹Šg;K/H´‚þ.o\ÇÎv[…áÈãû}‘!ÿö4óâ€zÙ§ˆí/ŸV4«>æ¼LÝÐÓÉP „ØÐ{Û¡1‚¾îU^mI OÞ5ÂÅS^çtHd“ [àUÚ‘’Dl–Îìª= ˜Ç¤Ez:ÚAÜ;ÔU·é]Ù˜Üy—ŒžÌoŒS“:=qŒŒÀß}»Å/fyô;+²S‰mîÈ òMC¿°Û 6.~É9€#Îè²IY°Üºùû0”UÎÑØÝí$ÜD¹pè*·cì»ÏË’jib·çáÛ4ë<ŒÔãçG{©NKçÜNhP±C<έ«qyZÕ€´w%ÊÈuía§%.-$Ä ÊPŠñSš‘ô¶ü¾)¶[ä+&vq|­_ë*o‘òQD*„•3ð÷}ÐY7“´Å­Óððuê䛎Ž0é{þâìTQv«¢z4Ÿ£ „ijò-2%+z<‹Ã±Ì^F3[̉EÊ›„ ¬E—®qÇH ‘™„†>ŸZî-*²ê±ÅPƆÎ_Ú(@sè B$—Û&Z1ÿ‘‚¨Gø±ŒÔ šˆ­Å V>^½þ?à8pæ1P™Òô}z¤ÒÒt®1A›ÔÖD”:ÖèHê"=¯‹Œ‰ Â\Ñ'éØU3îòs»•60àŠy½ÿùöÝÛ¿€RœCL`O{Ä*|¨Q± QŒí=:fc“²9þC &‚0œÙuò8Ù„,Шò|ãl¦NÈ|A_ÑÑóŒCƒÞuí<&*AÙ‹†^ÀÕå‰ '.Tyàä¢ ÆÓ}l³S@n1CÆ"qO¶oꎑ&CB-Ç<€‡Æ¢ó#Ú}}*7Œ0÷Áö[ØFã·[T“mîõvŒ4R‚ƒ$e=JDYŽmœáˆ×QÌÙ¯ÉlÐ ƒ yËŸ 1 öäŠsrqÍéãÅéyn}à¨êöTR»¨X‹Þ_A'í›:;F¾ ¿­ë“ÃÆ²èâz烰pptô)Ùâÿç,R$àŠÖ&â G¨˜Go'sškôTEaøæ,ò8Ü£"Ä1’n IŒ‹æÁZ«E”€e rXô º9в{l„}L£ØÕ.„¢ë°÷+ G+ ^’nˆ­ít™¹¥»„¢„œ7¶³ÉÀùé.§ÕÉ,Ä#ÿBø¡s ¸0FWƣ〗ø¸öØ®×D«µ³$ÐÑÉ’T-ß0 ¾§‘û”ß«Úi/d²'+–¢Óuå÷ëì,0I«XãW¡Hé—O’røSÂ)èˤ£%Ã8ˆÍ ¯&/ Ç]XždLø ö8 ×Ò¨@ƒ¯˜Àá}˜è»˜ÍÆÓÚ# ƒ7'aÖ\“°(­1r H|›HÆ g3ñžŸÐ}›ïË6Û—ïÁvî¨ó)9›Õ}’:ÏÙ/jr&i¬ ðÊaÿƒ—zI©G,=sVÛa×£„!†Àø®.ø3™h¼EXÃÒgMµmOd`¥¶­³"ígŸ“q-p5 /’¡¦È îæ ²‘#(Á/ÅÁ[ \)­vùt‡T0 Þ¶Œ'ýJac” ^nÈs˜_ÞÄPh10¶›â’ŽèÉ´HfÖ\ˆˆ%„Gçä³P´-‹Ýž=Z›Þõ>˪`ù¶¬Û¼¹Ë]"D.ÒCáÔ±ÊÞÒ'©è}Šá½ò¦_|>ZF;Jèå»âP€YuŠ õƒ1†T²«°Ã´÷Ô3Jè(‰œP©í–ʺ¨º{t2íKVlzx¡D;Á*ï„o>0áòãK³CÆ:ЋȧeÍ$RÑtÊ3eM@Nhãd:wÈÂ"5äö-½oÁ@Rk¤1ø†›ÄíÏ=°×çp—’&ò“pWYk=ÛŸÝ:ä¸óø]Å$p1±1)îÒò &‘‚]DÙåg Å °$~ŒHæid´aÔò16}Ü¢§Ò .°œy‘‹TÃÉW|eU1ƒ„(3 {<„Ö›L§¬ÌñÇÑ€9'hÛVC… #ÇüÀÃÈ4)ï0¡µ†°òy±›¡ضÏ¢ÈwÿÔ¾wzvÒ2JoX1<ŸàJ#ТÐî²=ä¨Î“,µ€igÓmÌPÇS_×›”¦÷ùÈÓ9»­¥žBy~‰åóºÌ× úUþ©Õ@õÒ‰8žH…âšK•Q¼ÉÊÓº)0¯¿²}™H0³Éƒ¡äžO‹¯ Æáä4%ñ—ÂŽÙ‡}zømDóéxîtZEuº"P:Œ%fÄpª•àikð¤¯ÑR1…óQ[=_mëëºÑ B¡1N¬ DˆO˜éÕxª?Þ[ë³'C!´Y¶ãóKΠöèØEоfÌ.»Áøð…k9¡2ƒj[3©¢ºF ’Úò"_§wŒÄiÇß=;Ñêy¸‘v`-“»xtT‘|ÌU˜»´jg o 3Ö§¦›]•û˜Zj‚‚]¬¥~jüö›.$R;?Ï÷úX;;d]×¼¬³*P¥üIÎÓÎ2 âDLg\9IŒxù–™Î¥3n<Ô7CQ§¥÷”\;Æ&Ý 0ýÝÓ_ ˜jAó„Wª3: ~rð£øf˜[—WyÑ3+!e;§ÖNž!|VX;ÏXƒ(—5´W:¢y’®Êi3†võpÄ£" ZJ@&³‡Ã‘mSæG4œ”ñšañäˆÇ@ZgÕ ƒÙ&FMϱØM˜æ-¬áê‘î‹RþaOR¤F8 ‘„AzAï«q_MD–ï$¶E•峓Ú÷RªüXg{hDã²i¼‰ W¡€¿|õòöó€F<©Ä 0–rŠß%î÷¦4&lv¶9ÖbD/L*>1U6ð9®|à'•h†ýqVŽ›¢=–éC¾sÌrÑÄÒ%«Æõ+›¾ªåM‰¿+ðÔI¦†­ƒ²NÐØº[ —¨ç7 ã(ˆŒ˜N…Ðý©ÕÔtʱAѼ²˜’ÀgagxúË• N¶/·×Ýx–åG¾5‘^&WÚìNþö³Aeòræð…1A”$*od˜AÏøTk´ øHÜåÅU“§›”ª:Ö2Pðý_UZºª§ZrØT0ð](BKG†^>\©¬ð‘Ÿ™Yª¼¤A§öä »þ&ßæ ‹¢!]Ú³ìŒ(: tÎ-G'gØÅQýõ ^`¦K€ ¶Öù᛫0A¥_^£Bì¨d¯”à=/hꂾ¥K«Ð‚tãtœÙà ó 3çC1w|èï{'gOšü7ºXæóƒI6Éòxj޵;Ór·Ÿ ãÒ±X¬€¨ ÄaŽDg*dñ¥{x3jk1»Ú7+‘¯s_ü®Ú®9eýáV^à©£ÎÎcÞ³f<±î>C`FÉ‘TÍW8·@éRØ‹b¶OñF^Þœ…¹¿U~èë ÿtûb¦VJØEvxñó†}µpc|Äzq¿ÀnøûÝè_„5/š:°ÀœrñB‡Xê‡ú|'ކŽý¹ìÇÅ‹j´z@*Úa)zÅ+a ÛeÐ@£/ôò‚cÀa@$¾û=Áoº=½F$ƒ1H^°Ë1„p÷¿ç¢ïFkú˜ÿ£¦Ò€ÞïÁdL8 "U(‚¹‹ÿÛÙa1˜‹¿s‰•ÛhE¶fÒæÆ/¾û¬ôbîÌ.¬î~Û‘Ð!a~È"mƒ± g`Ò–ëUhd ¯#8CÈ ÷€aý‰¾_DÀÈÀšs()§#¬dk<î!ƒü™Ðq(mŽþûì|œ­¥î‹"Þe´ÊÉŠ ð“ÎrÅÓ•P `Èó¿þ¯mêpù“ø­‘>FÂ2¹ õë0„¿ÿéþþZîã N]ÀoæðsìvôÙ°%Ú¢P¯…„žäLÞ7‡Or_}“ßÿý¯uóaΉß¼›g³@ÄsTÏ1ãŒ#p*ÕëÜwƒ1X‘5X æà»ÅØnÐßj1î~:°xúë`È7­çä,ÁôWrý½À]çFòì»îؾ~õ*kðšqZÍêf ¼¨ˆž?¨›Ý«þ&ò.ÿ¯©T=¹g­»Ù#.µúßþޏJ.ÿ1ÜÀÐ6:ï ø—oüû’‹¿~ïb«ûèçì±+0ñ9‡y^З\’•j ± endstream endobj 131 0 obj << /Length 2584 /Filter /FlateDecode >> stream xÚÝkoã¸ñûþ áîÃ)HÄER‹^½bw‹bQ`w}(Š»ÃU±•D=[J%;Ûúã;|É”,ÙI¬ï6p,iÌá<9œ 7Þ¾ÀöJà$H8ŠYÌ,˜¯^ü'€Ao=òFq*“àS Àðyï}«fÿÕÎ-•SÀ\/#IbA‡j4n‡Âdÿ^”uŒ(K±ðG8»ÚÙÎx2 ôøð§Ç(‰‘zZ"ךõVwžú`œR5b©$L©yjÒ=Š™-Ìúƒwë®f€s ÈA‚¨T>B¬±Õ¿?_=ÿqs"+^SøJâ hòaë’Q"‘Œã „ 4ÑNùÃìÅå)‚¥œò`vØA‚2~;[?…YƒÊ¬¬ÖÅ*?ûeö·–øå‚¥*€"ƒŸ4ÖÏ8Áf8Šĵ(ÔðØÁOQB“ðŠ)Ž0‰hz¦$~IèK Ãì‰pÏßt±Ø@‘XŠ WD”11;šyJ<æ#Ë}¤•“¾=‹ˆþD~1ülù›Ùgícxîp殯gÛÈ`¼5Âû­7DÚ"çïßķ |ðÖ¸&àD^ÄÑÆ%””à¿TIÉ%x† x ÚÒùæŒ'aUŸET¤a¶Xä s;¯Êû¼,òrž_Hs[Õks{]Õ«Æ¢Ô¹½Y6•¸¹»ƒ¡ùâeG¾ »ƒ¦‹Ž¨L$ïFÂaèP|lGŽHwõˆ`Q.Òn°†zqåö@”œ”ÒBå¤ô/ñ²}JüäX "÷†OÎàGÏ?wcçëM]Ýå—ïªrQ•ý€ùÌÁRGFø …Ș §dÜ%|"ýªèOàcž^]×Å<»|—ÝTÍ—T6ÀÎD c_£²a·u _åZã³üf3/n²å]vb'‡Œ åñQ¹À6 “ €)ÓÆ„­L Ç¥E ;üÓ‡·Gbï¤í†n“8H¤B{„’Àv“Ô¨S¹RqF1$¨ïO̶ÇÔQK9ø+Ûδ‚™^)ì¾:0øVÃÐΖq”aïáVWÿÎç*’4\äͼ.®òƪ¦Ðx"A–N?i|\CíZÓ´ÔŽáàkjªÅ"†mWI`”tnÓýRˆˆbœªßõÜ‘D· ñ÷üÓ¯ÿ¬êß 4ú³k(\ºÅM^ªæL<Œ{~Šþ…'_{¤a›#¢Ì(6R˜aç{µƒˆ‚a‰¡n£šïOуÍpDóŠ „Ekü5® w”OŸÞ¸zŒ»ŒZ<ˆ¤µ‰n×Oï_$_»úvVÌcÕ÷a[{û ³+²öó Ã3Øì¨eL8¤îŒºé¿5³ªv‘ºÚüÃ<4*cøþÍE®¯³^ç÷0i«(œˆçOŽvX4qSz3]<Øsì³Ñ÷ãÕìÕ¾¾ó>š~þdú®0Ýfcµ»ÿbjÇí¨{ÙĤ§ë^–=~ºCØLí»¯æó¼iªºiÍÝYùÒA6®¾¨VwU™—k;V÷…tÕ0TŠr¥Nê‡æ±öc(!mü°tïèþ®®î‹Åáóz ± ë « †JˆŒ{UÆ0x°Êh‡>®ÊP½BLïåÝÃà#«Œ#hMTeÁÁï´ÊØ© (•(|»6»e€ PWa&ÌZÐ+Æ„¨SäS§ª`~œýe™ΧM­fÀ–Þµ‘) ö©Â9¥‰¯…xÜŽeç> stream xÚå[mã¶þ~¿BHÀ‹]3|)òи¹´AÑ"É¢ýÖæ®ÕÈ’+É»·E|‡"©·“d{í½¤íÁw–)g83Î<äáà!ÀÁWo°ÿFX…„±ˆrßB *‚^O¼úö\ê?ܾùâ=¡,(RQp{p‚$WADC…Áí:ø~‘ÅY¾ÓE’¯ÑÕ·_7, e(ÄEH )FJ €à%ša¶0Ì;C 4X2 ñ„‚½þ-[G8ÉLDH¨>q~÷½ª®–4’‹Bï ]ê¬*íïj£íÃ*Nu¶Ž û+¯¿£Å”²»}™dº,á9´oýäúÝÛïØ~­÷E\%yf=%ÕfÈ%ÏVzç™{êm~E™ïgõ$»³ò†0Š‘ÜÎj?_-ÐÕ’¤·ž…þûÉvÅQCY:ëW‰hŸýœåO™ÿQ%©{ïôýâlµÉ í¨«¼?pžd•£sCUÉV·“«_Åe™¯’¸²ƒt•»Qšå™®g)`– „r0F’*«œZPIAÚ>Ô2J²¨žrÛPè¸Ì³ò­ÕÞ˜„EYÙWwzïKG[ºmní-›Ø þI|—jÛÜç¡ÚܘÌMú”L¾NŸmŸÞȉc·M6•}_îâ¬Ã–#§þ5 ?&Ùƒ›ˆQÑé«AH‰¤÷üÕ&Î4jL0$ D$"Nc_Æ«ÍÜ¢”†•}šãWeq†¨›e)ˆµ|¯òí./kŸ€_µÇ o4xØÅEU›LDµ†„3LMÖ¡ÔV¶Æ&B´o¥_µk‘Å_òJ;v›¸òOºÔɲ:pŒi]„ 1§õmül]x?j·öv0­¤r¿Êä!+'­ÂÂØéèý^#nDÈu–h!fJÜÇûª¬Šýªò}Ë笊?Øç8Mó§Òµïô*¹¶nÄéâYÇ…{eõOZÿ\:wûÊ6«gׯÐy »‚MÜ ='EmmS\HæNq‰‹TMMœðÃØ´¿ç|yûf0Šx°Ú¾ùgݾ ê¾°2aó)0Íðù¦ó¯éˆ°ÙƒíGv®ˆS¤ÁŽ}`לh5ý¡a3ÚÆû{ð&ë€ Žÿ½m›À¸÷ãÂ|¢ÕÓXÎ]àY Š‡Wât_O¢QdG—ÐÕè…J’ÐèüUø×aÛáÕ¶9é<úoÛÁ{bðÑ Ü†8û›¿ÝçÕ6¸Ô0akR¯:¹‚}#ÎlÆÕkD˳^‚{0_[13ìëLFðk»JPdL —¨x»IX/vC.¤hÎÒý€9¶Ý#&ñ«§F­Œ½úFžÉ–<‘õ˜¼­?—ðOö/ù¬ÇÙOÜðu^ÉŒÉ0±Ã÷Z¾µé"éHºt¢. AŠs+ðo®–d^|O~¼ZrÊ„må¸4=aޱÁ@͸ÏùHýrŠGô{˜¿Ù&ê(÷»è¸¶ùG:ÝõZ,)aCíßœÀ¹Ö¥ §CÞÒ8–]MÜkùXmk("¼–'Oå#…"(?Ühäü)º ~8Íã¼ßø†Ï…„…G8úÒ­;#B_þ‘ݯmù¦ oKß–>À}tã ýdA·¹NvO]¶›ª«»IžKZ¸ |K;w«”Kyávð{ÈIFK.lÖÎ|& óSf‡µ};™˜Í —VíŠü1YëõÛYBÉZ±Ë¥ ›”’î^B0Þ:–&4=OJ”É©¹ˆúÛäxëyiÂË9]&Mx9ÿ_kš0LÂÈy› –Š]ß!CaèÖ,€ÒÆŠß.ÞÔÏØ !M—a›ý)ÈÉ„¬dr*@˜›«dLëÎÕXé¼íÂyh»xµü˜inÒC”òËNÚiE“–¯7góØ`gs“'Ô0P—½tÞæ‡³à©<¡kÎJ^ˆQBªR™ÎÎß ÝL tÓàÝ!SˆFÎï¾Óû4ÎQ{DyøVa›opØÞC u‚ƒ8,Lk >í@½þ¸“˜81!vÇJ²J¥ÁÐÆÑ·FEHÙ#¾™å&)R²O°ÏÜj˜ãDÁgM>Ø%txö/ 3ÃPtI@9ëäþþ 7¡ 8Q}n…S°ÏžjYƒ)Þëbíz’"yÈ‹|_zœ7[§ ÞZc‘HÖ}qj[k<Â/å©Aª Þŵœ:SœD=:“?ê"Íc·ža¢îÇžÅ8ð~»UßÓNƒ›Wc4“PGÃÚœš•›¼¨6 m¼6YíÓ¸HÈ_î“ʹb×_m<Ø¿¿Õ:“5Çpö|kYB¡][Ví‘Z<ºÔ̼-„×q#Ëûˆ¢9Ýoý¡Ã’)è'¹îµ/¤›ŠºÌ·îIˆ·»T—‡jk¢ a…Ýôbµ5d0¢2”ÑÍcÕuÛõ¤òÚ…‘bƒúr¢ù¼û^—)±Ï‘à¿¥È&WTÎÙf›!°WÚ’ !Ÿ²Æf ÒÔØ«y蹃”ž<Ï:㸪>qùÌ4oÓ,|qM ¹[bŸk oãÅò÷VÙð:ì¾^ŽÖù7/.ôø½Ø÷ §ÎíÜn ­ÁÝ®º*ÿÃ*ˆæ­/OÝWض EÔ ²„~Rp,B8úÔËhi—…Ï”"ÁÕ(Ⱦ¾¾4\ÖÕ»ó¡^I29ñ¾ºÌÄ!ÐÞX©Árç¡'nðy𤣻ÛZ9F?ãëÐ…¢A·áQ×aA‡pS#u2œ]2]_k þICR§¯dH7ø¼!;{É!CŠKRÌ2:N&y”Lç²S¶Oš²Ÿ{\Ø”nð‹™r|é^_~M.'Ûë»×P&öJî5w²åÿ7˜¸SÄÎÀÄDH­™Þ7V÷šë$jüKÜï\î6~&)íì¡}‘T›­®’ÕüÅnbR«/¥`,Ð… ¥Å·&‹²ŠÍuêµùEúò½¶ï↗}ÛQ’{¯í‹µ6s3OWƒ+æÁܼ­qZÓ©†Um{ro›jõ›†§Î\/{•Ó46ìZn5.ÔÎÌ[ØXÜ/+“»´¾‰¬ðâO[k!TeO[5Wy׃®‡ ý•û»ªˆWUX=Ç $H4}a¢3† ö)ó➌B1Oú„ÝS±9¦‚#ŒyŸÖCtÍÝèû"ß!‡n%‰úƒ™ Û_žÄœu™åpúìC© ÕÇ\}^?Õ3‚„¢}Zç7ÍF¯m!FÝ"²®c€¸´Æ9Í•Ø}Z%;9¶—b“훇±ž ~GŸös´À›~S€¸„-¡©Uæ¼ 'ÍpöŽ·8ï¼ô\\ÅfÕB‡îõ ˆ0ò‚v¸„a#9¸Ö;Ö8z«×uœƒqïš«„RIBUÒ¿æ:Úê@ÏþE á¹L/ŒÂŽlNµ~©[»…B“ÏÝÚ%8‚ ŠôP³^  ˜â%†9j¯ °·TÚ_ï¶VñÎËŸÞe:Õå*pò}Ps–KXsæúä‹—ç\%½€§”:9÷þ¸…˜€Œó•K«ó[¬¬ºÍ­ øB\Üà<»¢û…œÉÀfv×/Æžì9„›ÿD.á9GßvZ<ê¦O}Ó9z¹&ÃW¹LÌ Ä2AÜ”jÌ(oû<®lÝHØáÜ,n·uWfÉÀ€>‘êTYL@%ãföåz­Ó»+Š{]U:½±5ÖwIúxóÔe™ዤΰB û´Ý+Æíÿ)ü[ò™1 ?atñoŸÊ°ŽÄ’†üëšmzÃ?Û!(qü~=}w E¼`”…D> stream xÚí[mÛ6þž_!l¿ÈhÌå«D-š¹\Ü¡w@“-‡^Qhmy­‹-m$y·)îÇßðMµ²¼^;›¦(°‰hŠä¼pHÎ<âà:ÀÁ›gØ> üˆ1΂ˆ1$¢`¶~ö!€6oÝðF,‘"¸ T5üýÐù_5D0ü[ß+LáœÄÁ*x&0C’°˜îªV= b9܆üWð¬èð€å Žý6®Ò=-ñH WzÜtI`”ÄÂÈzB -B«ÉŽ2¡¥R<â‰$\)ýSסÚ!µ­³Ò)º§ià,‡Bç@ *•Õ;ýzî;åÙ:èY”S™˜—b“ ‚Z¿æíÖF§B"ÉX0¸¢÷—ËgçßJ‚%‚ËE`Å”£˜—óà§ð«¯&SAE8O?®òëec~Õém^\›r“¯3[ªÒ¢Î›¼,.&?_þ½Ã(aJ­‰bF½`ôü;w8ÁÁ””a¸¸YmjoHàËN{ öFa˜æÿÁ›æ‡S†é`nœ´FEZ”ZÂ1ê"†±øuúG‘žGj¨{5@ÚŸQLñ³)Ž ½Àì‚ʯ1¾ÀøÌ#mÆ'Ï+‰(2íIx“Uy9•1ŠQ’ˆGËHæ£rGÊÐóÛte;î’†sµè¸ß÷n™Ï–†tne(«yVe–Í++CÞÔN˜´jÆXtºÇê%[0Âa"“÷º¢É4Âqø·"¼*›¥)iFjS6j‡Böa“®žC9†JS5›pë&,¡Pk¹\oÛ \gvœ« ôo‡J õÔS\túh~d—v9¦Î(¢à{bÕzØ=$céwlEm–¶P§ëÌŠ u–kõF‡”HæÏŒH°V³nÖ®ŠÉ”J.Ó`¬6?\¥&¥ Y1W–‹í›Ñ)‰H¨Or̺ìRس8ì^çç†î]®Ì@•Ró¨—eÕd•á./ ¨„~"j7\•Ýwz®Jð*'p†F§2ŽÀéIî˳u Ç$ &s¿{yõßlÖhǽ¿†ø*ê ×íæ%ð'!(Ï–émfJ©y¬³´I›•ù­²]5Òs˜³Ê©~VÙ:Í SÞvñû[d÷1œqAa‹'Œã‰@ ¬9êÅñÃÕƒq|ÛtwïžèVuÃ2‚Ðe‡«;aïrO(bZˆæOÌÁï% ï?àÞ ðá ½‰Ö{ðƒ[ÓHñ# wÌ~ª ÷k0qˆ™¬O/T ‹Í¯/_Y¿ïÛn|ÍùŽæÓ“Æ)TЬ‹¿éyæûe<È‹Ÿ2¦ îǘO4Ó'‰GÄ6Ž.ßþøúÄ(Óƒ°gÊßËB{rR›õ@¯o^|Z›5øËqx؃tDOkM„*9’§7§“@7ŸÉªZˆåÛ§0ªƒ ‰ÿ^l ¸¡ ß~÷òûw¯†ªúæä†M›¦Rb??CïØ«UZ×g[!N0~Ëö™ 6 €ˆøÙ1˜ŽïñŃ08`' ér£¿w¡gÅLÇqø&+,~2ŽÉ¨ *v Œ ˆ‚m·Ã®ýa% ¯ÛaÍï¼6Ï›ª¼ÍçÙÜüÚµ@ÔÍeξØÕ1Éx„’„øU6F0Жß'¸ Ûéä8A“~gZ"DáåÒª'/fôe…Š#% g©US–«ÐД¯ |ÐA#ÜlBHO$·ÉqD¢ØïÐßÀÆÀ7š¨Éë^*î1N—ð–ÒáÝAz‡,Å*FïÑ ‚bÃw¹11Í~Ø!uY[<ëLß»µ-›Ò>—®B T¥ßÊB—¢PàPcá8¯}‹1Úúô}f)ݬҙ†~0nŸ~ Ž9¢Ôà|®?<¶æäûlâÄÍoƒŠbˆÐ¶MZ]o¬)øaSÛÒ•…:ëMáåà¬Á43ÙºAuöa®Ôg±is§Q.pÕ8ˆ£µ)ÿ,$hû)o܇(¾mëŸØ§ƒJÌô@¡Îf¥ƒV²_ÓõÍ*Û‡žPÎà$HNˆžpµVbÙOk±×ò0è„+ÍɘõÀ„áê#¡“#h:9‚ƒ?tr!B’Qè„©5ç<=»¤wúªD (!§ÊJ Ý•þø8õ°œ„e!XGÿêã‹cƒ,Â0ŠEÒK`øìßÇVÅ*+®›%*7Í‹ƒ?Šßûô}t Ccˆ䞀`k—ZðgSü×IÿõÉBÖã„áqRdžð.ðßËÿìJŸmaÌ@óÛáH RÀëMj>ÿ|¾²81¤K#‚I¾¸ HQ¶“Tß]ê–ý²¢£[=Ü7Ó›â+Çßžö»Žž4ÂîOšÿÁ4Ýf£_ÖÁ4 +Ž{é£U^4ãù£‹“ç>èøð¨ªÙú›®»0{ú=wýçž»gÏýClÿìDEããÛÿñ[ÉéêóÄ}žÈž¸Ï9ާhÇádyãIìåi'žß ˆÁóïaë”Èbë}ð×­êóŠ (œªÌA}ÿ,…Oñ8l–éh¾ÔÂþùÝ÷ç4¹Þô"Âï­‘P =+«*›5æ‡MÙ‚R•Õ7mµ†GÕÓ ¢P²¨¨êŸ®f›•ɯT‰_*ÁïVcð²,œ|¶u¥SãTiYn*•|©ÊªCcù¹S™O¦˜ÚÎíeŒ!𔂱Øaϳ٦² à¢*×^ê•åJ–{…F.ufQ+¼NòÙ[ŽG(ÏóÅ8³ŸE£“G î2ÃV‹ IÂé0‘}ð$Á âô„ðd¢X! D×Á“m˃àIèEb!¹Ì ×N>žÒi ÉÇÓÿ#“„pãq`R}ŠŽÿ</9Èã%_ì=-©3žØD(J/:ÞÉË:OÏ_•«r}UëÉM-§žor lÅSÿ“¹ùÚé8Æ4xsäHߟáû÷µÇzÞ'µ›¾ã©è“1vÌ%;Ä$Û‹¹wéÖÚ×8êàAÛ×Ì{ý ð KJt §Nà5q¯Å{èå¥ÎÿÅ'Ît|¬‰3R ’0£ëO$³´šDX߈eø²0~_ìrûeø×tBqøQ5ÞŸQÃÚ„ Øð¢¤¥§¼Ý›|~±Î4ÌÜ:Q7$º)4L§ÐèByÕ¤ya¯Y0ó‘ZsuÕ6_§)Û;%LÝ™¶—/½7wYöÞ”Ü^ºó^FDQGžjÓþåN¾ïVLEÌ}ñÍ~Òe‡;F™bÔæÆ`î{Î1ƒóVš!l‚€ ×nžä^9†qbo-Æz‡]ˆ`ˆ÷xpbéǰC Uø?zŒ= Q•ÏDâ{ ڭɶŒ}Tæý ¾ƒ£ Nè{|é!ö°Åb8¦#¾ƒ-ÙIKÉð:¿ÍŠQÛãpÀÀjï33rß­å…KØN“Ä뫳µpøv x]g뫬rŠÒkG³f¯v%½«]]К°a'°Q#”L" ˆŠ+S¬›²2Ë{䘕BdqáQÛ“×2J¸Ô<òúSx{3é¹ý]š§½é%{ÅɾOW«¶£),6ÅÌ^ÇÔõé{û"µ5m¶ŽªÛ¦/É6ÊÛ1A£0·qâ-ŠÂ*0µRí.Ýö:\vÞàÿœ+˜D:ÇÊfo¾}³çm𾌆˦¹©/ÎÏgÕ„€ ª¦“©$jgVéJ¨¬®ÏoÒ™:Þ§×Ù ßçgÀù-êæ¡mþðëù<[]©7YÓd+»¥¼ËW·8׳ºc""ÌûÀÂÿ‚FJ” endstream endobj 156 0 obj << /Length 3088 /Filter /FlateDecode >> stream xÚí\moÛ8þž_!ô¾(hÌòU¢ŠÛºwí¢‹»-Ú¦w8´‹…bÓ±.¶äJrÒ,îÇßðE2¥ØŠó⤇ ZEr†g†3Cª88 pðÓv×^¼!” §Áñ4 ã^  )’ ¦Å<8^ŸÃ:[¨Ãeø{‘›»8,Õ×UVª‰-Ÿ¥-®gYe‹ÆÅb¹ªÓú„Y‘£Ã‹qøKQ»žê¼rMTÓ"?Wy µí שljÄá$½´%Å´×öB©3[ÔÐOíã¸Xåµc²,¶»~ û¹N²zÖTøõøg£ ¡(–Âb2Mçó,?ÕÕ“Ðrœ„W¹f‘0"ÝC‹ùëãƒ^g"HŒ_¨÷S`*`Ä qèbø{ïýêŠz‹+·„ÅHF”ÇÁ<8˜! %t[±n³ÍU¡Ë¹ÇF”'ZFÜu±.ÒÍ"rC„*[J›6–´O£$€=PššA´XzpBU =â‰$\þú=²­u™“ï¶¹Ú ôPh 2„¨Ô’Cœ˜ù÷îÇ‹ 'U½N›kÓíHpÄ\bŒ$3RiÍ–`&’ˆFÚLØJQB%,8žhÓE°ÀáŸGVà´T 4(L·äƒÇ‚^§~³u;%P÷Å{°HC ­ ñ´ByšÆ<ùÚv…ïzãM«/ÀîμBýg“dD舑Ñ "¤ø%ÖÏ:D¡æ‘ëöúaŸMOõï?túØ•£OǽB†Ev¦ßƒu”pD@ïG„ D‹“†ö· mφ°å1Â1ó±­G7€×àðìÕªªËtž¥/þ¡æ'ŪÌÕÐE¤ûÒJ†‰í¸SbH(ñGèøìŒðONv?“_í̲ÞlÜHüˆ.T™Ó¿¨‹ßþ]”g½/ü"¿Åá7µð¥YYœd"}dâ·(rðjÍ#E ó»â÷6ŸdiþâƒZåàÁÝ3~ŽÅaüöߥJˇ¾ lßÛòlUW£¹˜â.|ò¼p±@¢8‰^8OÃØbÜ'&Æïg”…ï–ªLuÀR¡¾Œôã+êH. ¼l{ÕÁıc!át•Mº»¾¤µ> –G²Û…Öé¼(J×t4bˆcÖmæ“AŠê2¶âXe& ¦É¸D”&=š¥ô²,γ‰%Áa–ÛÒ¢œ¨ÒÞê8ÍTT%Ä„ [¯\Ï„W%ÍMäÑ„ìÅ[ T…6”O2p7JLÒè«qV¹ U$á«| „*Ý‹2;ÍòM xŒ8A\Ò'§«…2*0b¢Z QíåR N‡€nµx=ùŽð<½„u™§¹¥¢,ýb©e\Pµ€¾`ÂM¸&p6 Oõé6ÓÕ|n !Œ¯ËÂ=çMªCQ© ‘ÊÇjSŒ-ˆÔl;ÆfE¥\hí’Iò'­ Û¸d¤#Z°TT '­ŠU¦aä)™‰õêòt^¹„€M 8@ੲª‹bb˳¼“~°cVß\BÃ&'¢ð\뢬ÚÂe"B`£;ͨ?ZŽ!c²Û¸8ùP¯,#3Uªǭл̊Òó›+×"m´(¡Ýùá ?‘pósZfIZ•çéܤyâlxãƒ-Yx‘1Ël|fïR{)UZÔÌUóÜȉiiÊít»yvškíqTßæ®ç´¬³ñj 7!4)¸@H¢«^±E àî¤!mW.›.M¬ýЈ®Æ³N¿6Á™h0,óE ‰z pT¤£ ºo†Ëù±÷z¬Ñ–m¢’Z‰9†Õ c_Zz$Ž‘¬K0C m1Lë† C˜“nÖ=2ÞBÆd"œ¸T3m¢˜Û²·øÈ^#w%Ô-Ÿ¸©%„ã]–î*3¨î:°Â"¼jvI·/«-NgN‚_dF¦¾-çÙ8«Íª)¹¿j½1çö•yá´“7is¸#ºRMu3rÙ¢eÝ =kú2¢¯@øÁîYËÆÃe‘宵³œÍà$÷–NТDkQ6•|-’¿m ŒäŽ} ­êM‹9gÉXº‰/6ÚZ-0²‰žt2Â@wQ {)â—˜o”4myÔ4uØnr¶)e#a‰“°¤¥ç,GB7¶MĶøºŒ?  p~ï-ãO)_ŽÔþ–âMÿuÕeüu³Hr–tSÞ[Šï–ó¿ ­ûÉúß…ƒï5ï¿Kr¤¿7@q r,ÚX¹“:±u ìF ¿NŸ´é ²O·Íb:¿5°Ù`!BQK[¾-at댽c¼“Õqƒž¬lRbpà±D\D·8v{ ଑#»[Ί0²“rVüc÷熱}ä½dÇV\#ŠbmžÄùöâÝRœÅw+Îà'rq+qæ÷&Δ!XBþð¦yOLÀË‹$é r)Øn0b°twÜhËfôÍF³ß é[¨ x¥&æßYgˆ´@<™ÿ'•ùƒª ™Á¢»ˆnWyܬzOKÌ>ôe§{ ö¯Bdñ¸Ê³çÃ.„ $è®ñ&ǘïcñ‰žŸ'eúÿW¦Ýcyq.m;”âå¦ãPʶºr„ÅK+·GXL‹ÙEo±X –8ƒò©RÝï2œ¤uЦeÚôwÙm÷¢NO çj×S.@U€l¡Ãr·óóÊîa4 z)Ã\]¸’Ë¥Ùy†²L˜¬Æf« ^\®Ù]Ž}ší™ˆ°iâ5;èí‰à–“¨Ûv™ŽÏÒSe‰Û#Ò~ÔÖ™Û£N,€Cûúq„"Aº]{X3ÆAqÜm|ÍI.`ê%ß@°6;ëÃ(Æ=}{–躮5&í£µ$+.`›fϬ·¢“!»ÝÜe–gçi•æÛSÓ4ÛPú€öF›e7¬ìQ³×%Ã/í–Õ,=o÷ÊÒ¼ÙÚš(ýIËàÑ ÆDvqÝÙ›¶q™³eÆãb¾Zt¶¹·-¸r;l*­Ü¶¢9›׿Ć‚{ \Œ*0çªﻦ†=åÓÙ…\UƒÇŒšù‚H\pO¥`¾æ›†Ê¡¡Í2X­N*U×ͱˆ¤ìþöÅôñŸ„÷¿xÙ\ºiW¬­9´)†ý-"hqÑûdc¡£wÍ.ØÝ:¿Õ¶×ÝHÞó>¬_qB÷ò…KLöWË ¸p&`ùµbœM¾Yå1>p©Ô×AÇ“%ä¾þ¼}ºËÙ½}LŸßc.æäò‡»Æ^„ì‰äÁ“Rdr?ÌU~ZÏP±ªûP`CPÿHçºwJ,½SàßËGMàæ&’n1©T7 b²]ߺNÕ \`QnŒé9¹Õlö¿ˆÐžb‘­guJ6˜…÷/oÌÃ4<3s¢vNï¬ï]ƒ;žK{OÁ¯‰õùãŸ^oï.˜ñ¾yõ÷¯‡¶'A=$C8ê}îa<¶Ô”îâàlhã6Þ> stream xÚÅYmsÛDþ®_± §{éfBCJ ™¸Ì2ù :jc°%#ËÐòëyVŠã¸ib%5ÍLœ³¤½Õ³»Ïííž-IŠd$%ò‰”¢„ÿ_ð±øÃàð‡›‘T’ø–Š4þŒÎ´&m >¤>ŽtÄó@FK|%c «6Þ’Qd">†,TKÖ$2l™‰d#Hrx§Uä jÃK.J²ž<ÀÙ@žU,t:I>zHSP!s†‚ÃMG!:rž"&x„ Fâ¹×£… ŠÉ‘w”4ôzJx§”‚Îà„„éA‘’ÊS€ýÒ`„/¤xFØà ¥pÍ>ZÜRŠõ²ë s”–>‹ìChìDü\4@84Udwâ9ܦ`<¬5n&Ŏկ⥠NZf ^Žxà)ñÜóПØçxy‚Ó­6Eã §$Ü$áþK\y ÖfŠÝ*Oç{„K!âV±( ´šãY`(¼ÑÌe1ë ‰y‹Gk#“„ã½Î”š$a0ügŒS0Ü&˜¤q§€YqÌ5ßá¨2ãœAÄÀ‚YPã¬gÅÁUP 28©žìbèK#f†dÌ ‰°+KU'ƒˆ³ C¼ÑÂ( rÞKííQ>¢üyý²¦ü€žÔã¯GmÑ´_зßfOŽfói9+«¶h'uEõj/JjËÙ¼nŠ)µïçåâ‹mJ^Nf%ý[WCD·h^”cò¥P½|UTu õÃ$'Óa’ç˦³x˜ô¼l&õùvÙQÙ wªXw¸¬º *ªóa3u?s¿™´³²Œ·Ë>«gó¢™,î´V¯,økYVã’ž—U¹ÕE—“~+‹æ+ú¹®Ú‹ÎƒâýöI'õ²:ŸToéÅ=ÌþuQÒ?°œÎ‹¶ošÄã7v—mñzZn×qTÍ—m7ëŲ寇u3+Ú;&šÁ\4ƒ¹hîÅEs.šÕJ_T“1–ÚAÙ“ébû”ã²yþ@üo wÞãbÎS„½¤Ër6+š÷¥÷çó1wCü{‹¤Ê'í‹îíeùKdÊ‹·e–?·¤¼s±d–Ÿ”‹zÙŒËE—Á»[?—ç“â»úJÜðØ“CÒgT4˜‹ÔŸz¹ý q\Ð)¶Ñî­ØÃºÁ÷Cè‡ØÝÞúAõƒî‡t굤^K굤^K굤^ ï\ýØë9Ë6Lípeùhùºí®šTfùwus^6Iò,ÿ!?ÊŸá ÎØ ã–N±‰àPF¨ nŠJ4_Ï›ú(uó6Ÿã?QL~sU`<Ükª»¸¢ÐèÛ{ä.²_¿é±9Pˆ ëZüê·ß‰=ex™zGÕr:=»MTõ¢XáuðQ.@´MCD»Ïø!¢Fó&5DRX¥ì Qj [ÍuQB/0­›¢YÒå”ã¢m˦¢¾,Ï¿×>µHêÔ—ÙY~ˆö¡ Ã!ŸIwÙl UóØÕˆ…«+>Š—W|–$ÓêQw $WWVvG‹—W’OÑVÝ Ç(µ~Ÿ¨õ*aL~ÜÔc>18…‡”¿,ßµö¶?FÝhtz`ûÃ&ÞÞ†l_°6t»Éå‚E‘øî³,Xð…£°&Œyë¶³)ë;Y—P(ø8HV+,/o‡éEªt»¤ì&÷6ùuQ7 ¼AîM&*ÙPýÁ¼L7xi½xyÝ«qp.Ü”½L[¥ŸôƒdUŒ`o& ½ò#Iv¨ì'òàÎlµA‹MÆ|À‘Oµ 7bmÝCsµŸšƒø€|ƒ2äçËAÖÏA²}®ðÚ =H’·b©†iE5)¤O»åÞuÝ™‘†m©åžó7¸çìC¹çzËù·’ntf—ÇrN‚üã¾Cx<ÿ~å&¯¶t×N´w×)÷¶Âú0àMrÂò‚Ýa4÷Æór|Uÿ endstream endobj 170 0 obj << /Length 2644 /Filter /FlateDecode >> stream xÚíksÛÆñ»~Æ¡‰q¾Mó!Mm·f:¶éqZ;“@D¢%+Óß½H)‰„l5‡&ÀÅÞ¾ïnwqÂÎÌÁΫl¯¾±C_ Æ™#C¾p¦‹“_ÀyåhÄŒX(}çÚQ`ø¼n}+DDàÿbë–`‚ç$p2çÄÇ Iº ¬F`>Œ $ß;'yKŒ(qÐÅi€ÍÕrðþ0°#M›FaàýÇgt©UX[²eLÀT†G<”„+£?û·-®-V˜ Öms5MäPìøˆJ5ĺ_û¾u?]8½ˆêÅŸçK$s<Áà†+Zšœ<I°tB *œÉ¥c‘ÊQÀIì|pãúC:ûaò7PC9Ä„b‰8t!o^E´2a ¦u𿧆R£1bj¼ÐJPC±y³±J_V*ñiC:½Š²¬”¾‡)'abhv ZJBI‹–'( Àƒ!(ô}Còggú®Òßó©ï^‘3ŒÝ+ÚSãv–€h¨‹ uìc—œÚSìaîa‚ñ¹þ|¥¿-7h/¿ùûÛ‡3÷»ÌiŸ¹fîÛëäÍ»ñ˜³>ó`˜¹xÍy9Ù6»zLÄì~Ÿ¹fþ f}æÁ0óÝf·×“ÍîfÖÍÚòz³~yzóšìµÓ^çÌ'wÚàÍ’eöLo³iš%‹r˜º°äR5ua‘ÌŽÑP:‚`FœÉÔ~W%0i%w‹KuõÝzne±Êã4Ÿ™_—«|Z§E^¬EôsR™'im®Ë¢ªÒ‹,±d MÊË¢\˜ÑlV&³¨E§È•íúkW£"“°‘„¤+qÕª#ÅÉ Ý©/g`UÑS8Í«:ʧô«:ÍÒʪ kY]5Ú\ƒä«LñXËãû° †ŽÀ!bJREï§jé]Ü<…Aè qTå^’"fM¾¸R€Àn(Ö8çÐj‡”q>,ÀˆÀÊ<^Æ$9’>ƒYÑ͘†ÁƒÓuwÆÔ\[y„&0ç²—4 ƒ[ Æü–¤id^äM#KðHR'¼#•_§RœîïÏ¥|BÜH›¥4™Ä=›«Ü=ÿÁH%R°\¨µžÜä¶ì«J~éL¶­EÉG"\O̰WXïÍL¾æU(ò¢NÉ^î~´ø÷Û-øOÌnÆ<,ßM¾}Òágˆ’g‡êD°Š\ù…Ô"x,µ`?&!覣7_÷2Œû[¨?Ö@ñªÔÛá^#q•¾h$•µH\-£þë=R<‚ì’¬(®¿Ü„ìnô»Cˆ"†;!ËÈ=þA+õý‹±c¿¤Í ;c[Òtïlx·¿›ôn–ä³z¾×D]»Zõ¼Pp"ë{ÿÃ3ãt¯õ†.’(?zÊØ²ÓÊ­HîU“ÂÞO;+tÔ(iÕXOãûË¢=µ35wœ&;Bæ¸O&­ÂáÑÙŸ 1I¿Ä"L ´s 9¢¹À Ïa‚—c€²vÝ“juQ%v9ÊW‹¤L§OƨúBl:þ„¥0ð·Ã혪²ÛÆPûðVU©;'yÖ:¡<Å@H‚üj[h®„õLø˜\ùW9À5Äcrõû\Ãá^cr\ÅP‡‚ŽÉ5ØæÚ÷«æM½–\å6WÊF¦°Ç•àA¿Ò`;šv6ZÕÐ1Ý=äz—€Z[ë#¤ZHM†2øèÍçµÕŸjõ(lƒŠ©.‡µ­Îß  Á–5Žøk¾\©¶R Ý(ÍÍ?Võø²(QÝÏØQñ¨ÑF‰‚0н'ˆ&B&69‚.€<Š]Ôß»MµÕ³Á.€°:,€‚ŠÙ&ÓD5åenj Ã(7†Q°ÂFÝ_Ãèû8¹ŒV™ÅVý8üH);ýç¡ë.¼Óxrú—óÓïÎO_|ÿöôůð˜ÄëyRZ¦uÃý§ïŸjÕ2™¦1᪦žDær•i“°·•j| ÙF%ØÂ/’ÒS½G*Ngº§` ‰•Üp÷µ=«dZ½U‹®Ti‚ÉH„û~žäž¿¸JÊ25-LKÑÚ†»ie9&J‹<‰!Ad,h˜ñ–Q¹{f™AOói¶Š”<»ÙˆØéZu}Œ dŒ¾e’%WQ^›.a+6àײsV*…Ó?µêêÆôbáæ*™Ö ð:­çÅÊÒ)ÓÙ¼ö–Q'±üš”Een#{­æÅµ%æ=Ê—E–צÿ ?“OÑb™%·µ)‡ •á˜/j!”fSïEí xøEmƒz¿¶# #ŒÑW9>²íx¯‘ÚŽGHðHÛŽw©¢¶Z“”ûPr„ë-©Ûž3H Š- 8z-¿ÜÞp¶ŠlU›±ÿåþ ¡ðYg:7ÿ¾Ú_ú^ù…ÜVø È6$цî¥ÿN†æ±:YÉö»£Gt4÷Ågs´¸§£A¶ß}=®¯>ÎI½[¶ÝåskÇõðD+“8=Ñ*aìá (Ÿf¶†ùsRGi¦³lfP¼I­7µ˜® ¦©iÕj„¨´˜Ë²¸JmÏÕ¹ µ„¸ÓÕ"ÉëÖP["´¸­ò8)³›É3÷Ûo'ÿ2(YzQF¥%jèD]àPëfBkýÓ¼QßÏÓÚRWÅæpMG!0Ìmï RJÊ^¸y ÓN\ï嬛.C ¥&P–¦Óù™&©k8ÅÉ2+n”õÔ–­¿J#²å8—ã¶s›|Ê4 eZG“7ÓåR›pèˆÆÆ4T/ {c—Ñôçh–œÝSñPÄe«¤®“¬o€gwóšR{—ý Næ\6u2H¦ëdЩ“¾®“áØX¹ª›Ðïú€æ„Ú‰Ð.£©$Í!"¦(›Ã5Äë‚nªbaŸÃ0œ|J/Ò,­o È4|$Þ±…²"gJ~ócÙ› û´X¤`»e½ßÄqª£ Êt¸ۗ­J@ºÍQJèÀ$R$CÚU÷éÐáµö¯_>ý8D³½;<Ýqxicfˆ(ê]Æ[*¯ª$j= ØxÔg±TÀ(œlZM;EýÖç˜lÇÀ¬e¡Ë´-‰û¶¸SÛ j:ª_¢à~;bZ”e2­³›Ûz BÖb#¶ˆD‚qNz­…að`kaº¯µ€;…6 aêT¯Ð[¦·ôŽgpPáx¶ãvFAȾ\ï  bo뀈$øGa¸‡Ùþ£0‡ç|VÀý9ßFŒþ+“qÓúÏnUõ¶‹²õ»Ÿ6¯¸Ý¼<¿1ó"òXâw#ÑoÐÈ”=>37íž±Ì,ƒ™™.vïbìµïfÇÙ.}7»á!9°NµÖ/fÕ_ ¡>M’¯ÎޱÀZR4I«lá™5fûÏ •[ËBru½¬ÎŸ?Ÿ–gCU€JïÌS5@YüIT”³çPiQìªjëë®÷ ИŸ ÕúYŸ03˜¢hª°gæmóÛ4»:÷%U]ªÃAnÚwØ\+~ endstream endobj 190 0 obj << /Length 3188 /Filter /FlateDecode >> stream xÚí[Ýsã¶¿¿‚Ó>Dž;Áø˜‡Î¤M.MÚIâ¶ÓI2Z¢mö(QéSÜéßÅIДhÙò9wÓß‘^ØÅbÝßb“ë'_¿ÂþIàœD¤EšÈ”!ÆD²X½úw¾NlËW±T‹d—2ü|×ûß4D0 ü[Ý{å1©„HÊä•À iÂÝC5íp3ÚÆûGòjÝ#ÊS¬¢&ž~|!¹ãľ(}¥J¸©ŸšÍ•¿UaO‹ÐÐhñTn´}zæ?ôxöu4o½×ðt ‚ÅPè vƒ¨6ÖBü²›ý÷Å*XRdƒ̈ŒI²jLù¾3ιà†<—©F’Xëüãū󷄒$E©¤2¹¸J\#E9R<¹X&?Î~6'XàÙäç³¹ bF1ÅsÌç˜]ú9eŸcŒƒ—J§¯1†ßÏ~¾ø¶'$aF¥©Ž9!# yþV«ž8™‚RP¶!«Ñ:[WM±Ê£‘Ax¬ûÂ+ŽÃ'Ûë'Ú5G ”€¤U&uDÚÿnÏÄ~™ýSs³ÿÛÅŸ~ á8Ïiz=†Ÿ{©ÝŒå©”îŸ_]t§“]ÚÞò×ÙáÜâsì@Ò1}J„¥:ÞJ>6R9KZ#®NçÝUЏLaàÈSǼ{Ûr¿wÏžãƒ^”bAc'7NíùÛ RNðñ'åÿ›qóÃç<êÐí 8žUw:GîÖ{!Z§ÿ=®Û—˜û'û nVL»YëSáçchÎ1?ÿ¿VŸ9Nü­Å†ÇD„ÝÉð¤€ær»^à”ìĤ6Ó°ÿôý×Oì}/í|³AY¢‘J•]uï¾%`ÎêÒ˜KñþŒâYV¢¡ÍÄ1‚1Ç-…H7ÎÊ„*&vb\ΪÛfsÛ˜w5»ª¶«¬qô«£Ä–&@Rc"Ô —•£!K'e ¥â¾Õå¿òES;æEíºÌê|éå\‡Q‡ëûâ„­u@&8q×Ì ’dª%@ú(pèœó1Ä*XT«MÕiáÊ=/«æÆ}?(a° AaÃèiÅØ­3 æKâ¾u“mŠMËYî^D+½!º]ÌvyYúöµûÒì*G¸¬ª2ÏÖ|“ù‹õ²Xø ~» ßóÐív½Ì¶Eî;VWŽÞ6(ÖM¾5 àÙzrµqˆ@ÎL³Eiôj7‘™8ÒD©‚c¤q»] ËO·ãèO¸14 ³ðäË;×t³Í„ÿZ¬¯£Aô ¹‰?í ³Ææ­:þEÏ7x0ÑzH#Ù0®?“Ió8¼ØW §Ðèˆï> úpf÷Áq²¾Þ'+y¸°Ðæ1c{KwHu·vß[õ<¬œ11kCƒMG5Òu¾¨B8¼—›HK;Ž› "~yY;–Ã8•S˜U*\ÓMµµ‹ïn)®üÅÉh$J$:‡@%çHZ:™º² )œöŠŸ.’$T"Å»+rŽSÇ"ɶåQ‘¤é yJí!?-–| ¯ÓD“O‘àSŠ'a7ìà‡âI@œöz¹­ôOÞ½‹ÒˆßôȈ%¤[Olx©mêùD±ž|1í!ò’úCä¹î!>¬){Y-BœþIhÑ•Ô<§.åtÙ}: ³yi ×ê>ˆÕs<?Äê…€{!•bKÕÅ €ÜÕròb ‡K~˜¤²¨EX6öË¥AÂòï‡ïÆ4À6ÚI·/#d¢€jjÄÝ ŸÍÊÚgi[`eS¸tö.Ü@tGýX¾ IÞM¶mjßõm±­}oè¿™{¬ªu¸‡ð9| 8Ø ` ’:a—™¹îÐÌ21¸OóÙî¦XÜ8ª•H.³l%ª½"êAÔJ´@Š‘˜ÝC`k§\‚Eý7.¹2ø[(ÂÉÈ¢Ä=Ç÷í… ¬SƒÑ'óøç»ÄèÏŠÉÔ–ŽEŒíâªÙ7k?£5Øò7«»<ÛÖ~aìúÖþÃ.ÏßùÕq@ƒÕ ¤pÓÖ:lœÂyêµÞä‹Â\fë뮲¼QÕÅõ:|4v×ùÖ}w6Q¬¯ß¸ÛÜ Öïóò®½;‰/Åʼ™º‰¬FBN®ËÝã/—:ƒÀH+3~3eB‚±#E]=úÎŽô,ˆÂ×#$U°ò€Å&i«³ÝÓEÕ ³Ë.ªq%ìØõ_>}ý9(¥ƒÝÑ»\±"ùÑœNT‘ühþŸR^@!É¡´@ DIœ˜ê‚þ½ÀU*”¦âñÀõŽ¬ÈŽ,ÏýÜ3äV¼ˆÈ•­t,Åódž_¥sz÷œ ”{ïcù wüXµ÷ÒvˆûJ¼o†ûÒ'Ýþ~‰ìÉìu/×Òùã6ÕB`1à@ï%[¦ˆbþÔIâY¾8#xv³v·¸”}™7YQÖ“ù—~­%˜. z’úÚ»/J?Ö:ßùœÅÝ&÷IͶz_,ÛbËu(‹ IM¶x—]ç]až Šn‹²UþÀ}ž¤Ìê:ä< ¼… ¬{å™îù}(ß,V…£‚‚`Œfƒô D“¾ï6·%©5¾Üt¢\W1‹VŽ©a¿£õ{¶—{2)DØòÄ~— h˜‰‘Óˆ¸]3"ìaaŠ_·€ÚË;»Ù-=”rÃëáRnª° ÆbÁªÛËr²Žs$8‰:¾/2ÇÓBûbÖìPQ·€X0Ö¤OPH>UÓ5lõ½ÚV«Nןã~ÿ¶:óX©—E3ÍTqðñ¬Û]`øî¶EÓ[´«pòTâÔáNñöWs„ÇpPÀn•¤´ß ÍoÊzqSþÄ8¿ÎËÁù>§„Dã£mUј‡0@ Nòð÷ž‡   †ï‹x¨¿_ÄLè4ê:±mÌß.¤ŒG]ö§uû¼L‚eÈËP /¿9(œ¦Sç`«Iúƒ _æ¿NAaa¦Ê¢ž­Ž]fäÈLò­v‚8Ðĺ©¶îL%,‘Pí`£ >˜´t>ÿÇõ‘ ЉDDZ¸à1iÓ¦V¨¯–˼¼4àrkòzåZåû36¯SÝ$f…ÅÔfËiy¿ Åöù»I26æ/ atöß "Ö“DÚÄ ïþ­e[žÁð>ÉH‰çìt8Îí_GøFY€âUK©!2þºÿÈë endstream endobj 209 0 obj << /Length 3334 /Filter /FlateDecode >> stream xÚå[msÛ6þî_ÁÉŒ§ÔÄ‚ AßõCê&½öÚ^c;Óëµ”¢ ˜ Eª$;½»ÿ~»øjI–}NÓ¦™$A`±xv±»X@ÔyåP糺åùÉÅÁñ3Æ='$ =çbápJI@#'ä!¡s.æÎ÷îÅDR7žMu35™òPºŒL¦žï»§År—iU䦾X˜g\‘<΋:]Bèwdªgqe œÙvùÜqUëÖ?^|Ñ2øôâà—Eê0`M’0yDxÜI–ßÿH9|ü¡Ĥs¥›.I‰Ê™s~𼙨t"¢0Ôe> }ß ©O$f¢µªj`—y‚¹¥Zei×i‘WP'wU¯*5·o%¼Öé› ®áz3·(•Åm1â–Û¸š0áöpŽ$ÉPø˜"‹”xÔ‡²€zNd$Og‘(ð6Ryy•Ö—/ºE‰]Ýe ˜øTFcÒahIƒ<"Ú'Íw®LæÓ1µ¨£J¶Ñoþqþù?¥2Pa$ˆ$|ˆ”ÂÂMdôÔ@ÙZ:‘äÞˆF…e†¬ß*ÝÀ€Û;Iw´ø|'""ð9J™ègñ|Ï (,C„s œ'EþF•Uª×®H½v ÄY²Î´ªê) TúÕÊ2Sz¥rUÆöÅh 6,VPkU¿€N¿5¥fúR+7°êÓ« ž/ˆ`#FOO/þe;m›Ÿ2†£~Y:+ãÒ2ðxÔ 4Iرìz¯gŸ@·o/ÓÚΧ…ä«4ËT90&Ðòh/‚š§œŽ»KÌOóZ•‹8Qs3îìí.¬0E$@³3׳dµÚ'æ –Ã°ïþÐ<ÏU6[«ºVÙ}Á·ƒN ôÝÏ-iþ à"·.&ºŸµîÔ]”ÅÒ”Ní„=±E1Ð^r>œðãÇ·©,w.İWZ™!çE®Li]ÃÛõZ‚O ÅM™ÝˆÏ8ÈkØm'¯ãW–…{Ênç³2Îðü°€)ÞGª=Ť8Ié&˜á–SÆÆDÿ²¯ªD74°¼‡•äćµ@1VõD÷Š32sŒ0§„³¨éu´?;Û5× ‘Ö <ðÀÛü Hÿ–½L|Æ("nÃL}¦G|¬CD¾A§kpÂÑm/ã¤RÛgÓ1« [³\ej©Àh͇&̦™©õám®ÐÀÁmxIÀ†.z!ÆfDøÈ;p%¢€x·ÖÓ ØmV‹yõ ·ÐêEÖ;Ø`¡æƒaßÖt!û›®å,ÎÕë{zœ(X¡`³ûENÔu¢²Ê”1:Å&:ªµÇzmôñ²­-§©ÅÇ~o2Ѐպ¶`ãú©7™®¾Ì8,п ôm²öÑÒFÃ~è-õLt´Úo ±•!ø—~çú_\œ‚†zî'cç@¹;ke";|+f?«¤ýõuŸ˜ºJk>–=w¦òär—¯Í§zðÎ0Æv 2ؽ.á{Õ48¢¦ ×ñdešW—Å•mQ_ÆuSÚ½|˜„}J8˜g»©ÙŒ'‡V°¥mœ ¬®“Zo`0Z«Œ—Y®“K1gE¥ìW¬DšK]1ñ¢1¢&^t±°nZ¬€·8Û5)ŸŽ8»Ý(´O6E ûÃV»cû2Î-ãEŸ=(,‹Ò2Ú„ý;W¨Ãv›sÐ)FL¶Ê°·±ÛQ«BÀcÌlø#·R–“‹Iºñ,Sûûîq¢+Z¨P˜«:N³êëÈ©õà½óõV£Î•¼Ý麧°½ïoä¦ï·鹪¥JÊt¦:Þà/ 4XNíZk¾¯•öìE²‘{u™êå„ëa±€© åÌ#).U >¶Qƒºii{»RMÕFÃÍ(Ö–>rX)P0ÛrUª$Å01|A@dÔ¦Æ!÷=ŸLi- >¾ÆGrm ÌžÍØ'SÚíUÁhSÀ|@sh}~l$d ;w8Âè½øÆò¢­Óln¶+¸ÁÌŠäuÓ¤°uØÂ4¶+^2Ãè¼U³5µ[bfö¬ªª[šMQÇ34©>G$íVÊš0@uй†²Q󭵎 §Z]wßd|Ò@òF¯ÀuŤn¬ÃNáÃV¬m‹ OÁ ¦ªúñ‘$ñOV+•ÏÓë˘#ÂÀÝ AåYØEî Ü ïß¹.~Õ•ù†k 7E-<ø^ßÁ4cÖí†i†ÊØè  Èç†~aDZj-tTÝ dëyÓp¦2X˜€“öH-oHÌÀÐç¦pߤ±©V×*Y7)¯À]çsã;jš\Ù@·‘i@LOx“uò l.²–ë<·‚¨¥Å³u^¯'vGItNu` ¾Lóõµ)¾Ven6ì‘+Ÿz‘] ycðÌÓ&¶aNeHéßÍÛé7ƒ’q.|´B™çI‰0ùø‹í>stc-ApäWVÃßç½ÿ±!¡¨¬ÎòF‘Ã’<ì}æ€'’.o«ÆPq¹¹)üÖ9È{<Ê~à7ÏeW…Ýé{Q3h;8Æ-ÕM/3xªs6¯ÞÙX =‘ϤÐáÇÌ/óúwÄÁyoàÞh]Õ–^±yšm›à΂p‰êìà¿~9Y:#ÕÚv¢D´åã`'ˆðŒÝÔ€éhFž I¤‡Á#l—¥Ðú«“á2ìyÛȃÄcöªÉìãÀ³À8`m~ ·K§Ö;%cángvÄÍÔ’¼÷c§l-óï„¡&?аÓÑöÀZ6Ƽ~¹*ªô:Ñ»äP¸6Þ‚¡«Óú­ÃèלÝMIFÓŒ"KÐh3`›r(Êë—ݱžÇ` ÿ'ÂÜôö˜ÒJß/þúÀ’‰?—Êw"0õO–p'ññ×êêåwEùú=‹$IP(H攉ÇT\¼¿eq/ŸÔŠ ˜§ÝmDva懄†þý0›ò€`¦v -ºÖ(=÷ï¬7¶ã¿T®Kýk€¥ÍMˆ~vn+¦‚ãõ>¦­7YcœÀî4 BÜÝŽîe5?¨ñ¨1j¡el·c¹‡Å: !Þ Õüà°îß»+Öƒ ÿ€mhš ?–ê_?øNX—~ø!Xº§8‹ì+¬‚Û%`Îé>)Hðì÷ÀR8ÚÛ‰Û©8?Œ¹oÄr¸œΧ‡ß]þíäð«“çÑùáÓ ÄÝ {°7å>Å{õ9¼ÙzËú]¢ ›qФãc°l½ÜÆÔµCûðV9’Ý*A¸wÿ°ï¾n )÷!¡'ü¨/˜ g¯Ü>cúº®Ú¨–]Ø»!Ûj2Q½lÕó.6Õy´i“H{îôÓmæoîô«ÿ§]žÎ¤™§½ˆ©ñùÓïO_57ø¿²WòÏñÐï@™«ìqÛ«üOö9O$åø(o¢eêÄüJàéu­r{q¹÷#ŸtãE‰ª/ÕO›äÂ'‚ó‘`ì¯Vq‚ã4gÒÒ5·ñËn(F ¿´S}â<={ò593ò[•…¾sƒRíqöñ’‡0‡;ì¾|ÍÍK¤»3*ÝOûRätûRá$ŠZýon'Ÿ˜ÞáûG¦üIšÏÍ5 ý³ö‡ðbO€¡=öµí¿LgFÀ%^rßn2ØðÆêÛ[Èà@Iø~eÜ¿ÎýÒåà!?¦Ø&Þ°ýqͳ‰/\ƒu{;¸ÿ[»’Yss þsY·ëô\ÅËLUÕæŸèœ>~l xpù Ç1ƒ¯Ÿ07'ðB‘¢¿I¿¸Ïˆ-nLzœ Ây «bûá¼XÔWhºð|yƒòD ü.7rÔ4ñúÆDÝ™‡O7QýúÁ“D˜,² f0ùn¼Bß)T0ù æ«õëOS*ÿ/—`Àü8p}n„ ]bàN–†f¾²C¤kÊô9rÉbÊŒy¼]V‰UURÂÒ2÷`6.­ávh?ü€OІùñÚi\_š[RÕÖ ŽcÀÿ‡ƒ© endstream endobj 228 0 obj << /Length 1650 /Filter /FlateDecode >> stream xÚÅXÛnÛ8}ÏWØ ­iÞD‰úÐ\Ûô¶ë¸íC³d™±•È’aÉM[ìÇïð"[òÚín×E ¢Ij†A+]×:ú,ŠÐiôصÏ¢e@ JŠ´Ì*×;´£=Ëó$[j×yðõk滋6f¿¸y/}÷Ë@T®Ü?¼‘᪪tî}¿ñ3“ZWnü4 ù¹'³d>Ö˪ñh;¯IHüÁ“âàÏÑåàº÷ ÀC‚C.:0 ÓÅâIÐç‚£+ÌŠr]5[u¤˜øÕb¶E5.¹r.G3XÌÐÛ….\ ¶Z¸¦ÏD²ÉDJØLôí—Ž“Ê_-tš]ÂR{3¨\Zù ‘ GC;ž˜4ï‰ÎT˜¾®„‰SémÚÂÓ›ºÊŠÔ›ªÝš8:[@uP¦3“ãèÞׯEp†%°¯ :†L±áÓøê…Dåƒ÷_O\Ò)HlŸïaó& á]o\~bn3Œƒ³ ãÇ'±Åj\ÙŠª„ºû› 7=@Ú²€£¬Í¤’J)ª"¥Ÿýoð^Ü|OnÒY² ÂÖM¿ÕÉô†ÑЋÕOºø¼[Ž“BßûœÕ©–ä^u“ ,jRMkIU·î3çAh»|v©³<«}u¾*ÒÍí¦“7Wß]%^9ùk—g'ðfS‡z1Ú••ÀPüÿhr4—aökScÔƒeH±%[4Ä4ôJùa–Õ^é7w"…^gy®}|.þCòk\QNí™ìøò;ʳ±;àûÏ:ªM …à¶M©¹¯å hŽ ý]EkŸ‹’±½5û $MO³OYîílêúUµ6ä4.K¬ò&µºjÌ¥Xÿ¶k}5§¼,¬®âËr’ôG>D»nƒ0 7–],-Õ¡s'†!Ù †ÕØœ#{É›–å4׃4­¿þ¯’ÚmRÂ&"eOZ—R\bÞ(ãö7•ýRL$Æñæ&³þàŠålZ0Ÿr†þÚ\s6+‘€ìæ†eÝæ&V^wXSëênµy_…k;]Ä8ŒÖŸpT—³ÑÑßÔ½ endstream endobj 247 0 obj << /Length1 1456 /Length2 6754 /Length3 0 /Length 7738 /Filter /FlateDecode >> stream xÚtuXTÓ> Ò±ˆÀÒËÒÝ) )-,° KìKw+ÝÝ’JƒH£ÒeÒ%]ÒüV¿Oüžïó¾ÿ¼×¹Î¹ÎùÌÌ}ÏÌ=sX™µõxälVPe$ÅÃÏ "deUp…BPp$B‚‚Šô (€Ò ƒÅÀâ`0€_L 퇣ÜPh_'€¾·3ÀøÐvEÚºBœÐv¤³·+ÜÖõ'q@w„³»•#ÜÍjðDº:¬¼ÿ? 5„5/7@âdå ·±…r4åxÑHrŽŽ€?HnW¨ÔÕjÃû‡ƒÛ@(8ÄmpvE:»Â¡(ˆ«7…ü.:À€W òä©’®–¦’–>@WIO_WMA_I «¦¢ª¯‡öÑ·ƒ»Ü0”'Ä @¡+ƒA¬¡¿¡mÜ­Q´ýê¦EçGÙý7/ÀÀ ÊF²qwv„[ÿi%é °»Y;"ÝÜѨèšQvP€ ÒêŠpBðÖÍÝÊŠf@'Ž.å ·þé†BwÎ ŠÀ®h>8âO,Špƒ ¶®Pèˆß @•åtB`^0X„‡_ ´æÁè[âÍÖAT„ãwjžvPâü'?+GtŸÑùýFý÷Ñ_Uºý΀„ý1*>QüƒîæŽöúÉFÿƒKÄ/ð»ø_Q ÍÊ/„~È¡5qüC.Êñ›è¿½D8ÐHÿáÇû[\”+Ä…tås‚ ÜÑ" Ð­sýÝ©¿ÍËï,ø…ÊpW7@m€¢þ6C˜_Ìû3‹Æ m wCA]Ñb¢Él NôD¢ËýÛäðó£ÕCKc…vGòýžs5 ûë-ô?MhAÿª Ì ú½Nh ˆ áè °Âù´(´pàÿq7þÇMø=àý;£²»££Ä Íùo(;ˆ+ºj€<ÒÑæ¿ü!NpGïÿ%âïΆÐ?5ÿ' 5=Kr[ô0þ:‚»)ý 6Úp”µqDÏïŸs„ ÔÕŽ€j#Ýàö…‡$ö7z1­P77€Ø_pPôÀÿ-w´02çSÓP|ª¤Áõ´åõy~gø—“6Ž@ýùcþõ?Ø¿¾5!èô˜‚xA ~´#úúç›ùßH•ÖH8Â=z脸Úüëà_hòòH/€/¿°0€, à ƒbÂþÿ eíîêŠVñÏL¡‹ûç7 Žî êµ&œžDZsª’]V¿8+‰z0ºÖÝöZi‡Þy,M;;·ÀWܨ¾qTÖl90ˆ¡20BS#cgò\̳6·Ô4ˆq˜°E&„¹†¢Uù@äæœÂ¬à¼H£L%šz6¯ô‹¸µ‰j­L9¾~J8æ9Úݳ,²ŒkMžŽÐQfîñd­°X2˜¬Ïyü,Ñ•R§‹áéèhØøE>×RÅe ddš¿pt¯þžCª²~6Š>1º×<¦½¤›/¨TRÿ~ö£™&>‚¬ÄŒÙH¶«‰×¸u^67 3ö-¢\[¯zZC7ƒ!7M[—€¼„Ï7õd¥RŸ ÑsÏv ÓtÓ¾ñïg}üÍå”ÁƒJ L¬+ï—]‚©ö2j£YîŒNš÷Ýäu¦ñ:Œ¢® ª•y¹œIK¬Ú“5 2¿†Ä¨ÑÇrß;TŒ”Š˜«‰È’ƒØ‡(CzîÅ?Añn¬¤UdPíá |¦G”ê òI´’¥Cr++>žœ{é¼Ì#H¥+`ÄFeM©æÇäôƒ§Pò}ì=–?—˜2‡ß®«-’:Ë(ù:¤ˆž‚ò¤Œ‚ý b™×¹sÒéõB7`¶"ežÞZ:ÇKXpm?|O´ÎgÉÌÌnÊŠC,äoWäò@NIîîôéÐëÓõ’Em`Æ[¼~üѶŒ)ûªû£Žç7‰=Kï,æt+x>)„ó7^ Ì\|âh–kã(‹†}*¬ÿÆíhîN·Å1Š/U b^=,¡)‹Bú¿H4P ,ELÉ_¤Âç>ˆ©¤¸…ñ½VHk?äâxÆÎA¼‹ûéËŠ²¦ß^%ç']Íd¶éa\I^”üw71Gv¦Žãp‡^µ¯3‡¢–ßv RûµX<¯Ç0´å=ÒÅ|ú®s¹I¿&µíÞy«=ϺôÓ ŸðšI°ã³Ç¬Iü÷ƒêh¶ºÄõ32¦Øá—"~×ËÁŸÓ§A.&9CW'Š”›x®UÉÒ%¹–  .ÁŸñ dP:xÉ/gÔið1GAù£Ê¤MLøÚƒûb­É1 t\Wé¤å?¬&ß8C ›ù“Õó0žg«èW™p­¨Îß)çÃe4Ç7râ\zÝùœÝ74™#噬&ãpCã1áÌ}mØwîAÈ^›Íœ@£(7eHõ]¬c¦¤¶9 ìYHθÈìÞÙaUðûÞüRõت}Gœ¬Âþ,ö ¦ÇéMØ#¼Ý#å~ÄwZÑNbÕ)õ]©ªãˆ»ØoޱXÛè¶r:ÅÕÓ73wŸåwŸa¢Øu!Ï¡u“x^Ôy:æþŠøÒ¢iGˆœ³÷ß/=“½>®, ¯Ð¶ß—#­ ðá Ðôí2hli¯dìXR8ŸŸQtÈP… óÒseí„ I|W¶nõSÅOrŸ¸¤§¿¢]mÝ,•‹] ›¯DòG¯…)5r¾ÒÆâŽXÕ’Éx¬p@Y»t¦³.ºª8¡\`Ç᫚ÿÝ-¥ò=Qý™е—4;CçÜ‹FÚ$ᚥ{.˜ˆý1ìv:Žø¡î8F?ϯOJJwœWG'©³9'4e²’æÎÃLR`1"¤¦¬R3?Wï@²¾[Z‰å­†}Ë*:_?ª´Éÿ\ð.ŸfóC2ÌàÓO ±³'íµýù2G•ÙŒ·º比¼rLQk2 ÓŸãQÕS= åçQzÙîAÃ-ÎÑ°ÞÆ¿y³–ê’5Åx¶»˜^ $¸ ô©Ù”TÔAòà,”#wÓ8ËnŒ[Œ9G,ñRI­&ØëÝïz9Òá]Q’*[A¡&î‘‹Ô‘¢÷òM ]Ôű…X˜÷}6y }âo4ß¿ž¦PLßpîrÒ¾?Él¨Þ¥úÚò$º®¡ñc0qqýÉú·Apëù› ’É#F…œÊ‰î%ñQ¤·cûDG|;ìå«TµƒOÕ‘…ÎÚÏ;¥SÜΛù~ÜNv¤Y⧸»óÂÌ] vè¬0~•üHŠúHm¶úJòPÚÇ?*³Àþsdáù•»ªäÃîºjlçlàr\ªo‰<é+¦Øó… ýÖ›À¶`åȇ¾…™·1aþ5J5½â_9W|bUrp†³¿‡´°Ì‰cçŸoa>d`ÊÈMÐ'–ëÛÖµõ6Õä`³'ãtžŸ2N¤#ÄÇöîú¼ó} ÖO×DnðóaR½äDÕŸiÛ3³Fp»0°Åë£H0ñLÓª‡¤ÅÄ룙ÊsøÙ’»¿ËZ$vµŠ¦ô¶¾«tû¢<È"Ö%öا@(™FÀã5,ÀÅ0^’]ÕùV{C¾‚h¶M³YåHä'¦EÉúk-.†ÏT|‡“~éÑâž¹…{¨§Û¦ f?J ¶ƒÎñ½ô£áWüiÄŽKRˆÁo×óëž±qï:݈ålCïQÿÀ)±Ö2±>z`îÏ£OCÄ,â^FNªR¥Ù„Þ¸ú›/#­±­Ó#e†Iœ½˜ï3|5¿×PcqÄûïÝ^x4É^áÁ|%wÏrÛÞó²v¬o¯Èýx8A9wÑ ÇFÔÖôpà¿°qqtȉ./}ÈÏ«kÚŽ´¾ÍÓñjEIÎâ4›úÈÉŠÁ’n †ýUn« ©MF~[W÷ä¶%nÊdMóÒO|üHö¾‚E~.zfŠÞ¾ª¦¡ž”JŠí«Rp_o•¤Ž#骨ÁÆ•º Dq]Tw$RhâšS ¿we¨pÚ L†éhVGwÀæšÓbsµ¸ µÓ£ceY‘–'¤V‚róñ¤ýï̪YSÆñZ¼]%êÏl-ž ØÒÐÈÅ1¤Vlœ¬jqwR‘<-òuÎ,i‰>4¨È“^€5AwtÅóÁ5®Å<"¯†Ÿá¯nW³ UZï±RX&Jßî©Ô“EžÑöTR•WsÊ^åRöšZÁð÷ÂßÉPf7r”çv‰0áÏû°ŽY‡œœŽ—\QͪøÀ¶CÊ3« ·VýØëÆ ½wd”I¥÷ž= Óg£ Þ1˜ jj:y7ý~Œƒ<'JV¥Žn°õ÷óS¾ŒÆÚR¡ô/í=­Em%œ_‘‘/L®ºDK6&½§“ñesëÆŒŠŽÂË­ª:n•JzÕüãÖ©ãWZœ:¶z3„2•«mCQFê‰Øqõ'/SîT»UçòMcG7“#KÔÍþ˜Ã(ã½ø’šú„-Úýò]oÙ›‡ i–“E䈯ϨZbPuú€‡–:OñuŒ‚ýO¿ŠWWžéŠ'3O 0%_šÀ1VÚ>|K°d*^á±?ðµuy¹’X#°}|xâ„%´£Y·aW¨f{>Ãa±M8VÓðiê«o`ME’¿]ëQrtÐ¥/;Ì>ö„V‰?´˜,Å\Q¶1–ª7ÐØ=ý…£“m2sá(•ùxgnšQ÷vN.йO •Z‹²{¬St -*zqu?¨ökÛ÷¶ã®Åêpc7²L¯okìêÀ$É[‰UH\·¹€… f9ùt³D=cqÖ¥Ö"$Uq$ 7P›´ÑäçeOäæ[ð.0Åß`ðüS¾ºc¥Ã"FHÚâ}jYãW*%]Ët™bš¢dÍô²(kb²LiC³ÆHÀ(à Oʶ+ÀO÷¹V‰/é¼)–ÌOl¥°»R® U–D¸¬Š-˜Æß"!…®–™Yc0ÿíÙ)¶¤=f̨¢Ë¿D2€8fÜm{ꜵn;ž]˜œûXZѺD½—œúÉ'u'šÇ6ùHŽZœÅvu6wÁ÷Z¾æ6mO-ÃÿØfø’¨obÏÌñÍö£cºY,n¹t Šn³ –áæxcé³V¶Æ–wÏ„£Æ„g¢H~Íñ³ˆt#ä,¨ ¤[4¨4¬EYÞ¨~~GoÓ?M4+î‡ )°r UÂlíâ£õ; >9|+<‘ÒGÄ­á4s–IJ ­Uq‡wÁ7©ËìÍ£æ[O-ºµáÌ÷XJ›ö.(N`Då`M¨/"¦#&¨}Äø±0þ– cîÙ-mR~’Tý¨álü³j Ölå+ñøÆ`.þØKÀ›é¾‹…mçöq¦y·¹rbY± 5óÇ’ØFOšb¹›‡Në¤Û‚üï+~{S÷Ï?³ÁtÞURSz­Îœ)_šÚç¹ÚóI¶uª›ÿhñžBqÅ©AͳV§cåt Û¼UÎ_ÉÅÉ~WyY#,QY—Nò’¸|×µÃy#àký+fÏo •Åxǽ“'†—ÎA<úþ­ëÖÈ2èî3ü²’žÉùS_•¯Ÿ($–ábŸ¤O(þ<³—òí###UË”­ôÄ?a¦ñ)p&6>M¿¬dóîú!¬ŸAÿê"ÇO~¹¶î¸švc"ËĪ«±ÉË™Ú_ ê²ËšeKJ¯=ó÷r¬;7~0÷M½GñæÃ#¾ _—Çé<Ã߯úø) j™í'˜IEµ®ìúdÕ üÉÎ5õyh t±!þ,g©ÚE‘>ïB’Í$ó6ß ¯ÝWÍ~2“qK$µe\¹ÐÑ«VgFõ[ÒlÀ0Ÿ7õ,‰‹yWKásÀî)ãkz'ŠçŒ=4IξÜÓbzh@ŒºÇÞ÷v~ŸŸGø5ˆòËd£DÐÇdéëGб ì¦Vœgon¸úólq¦Hºîô» +°÷À •𑳰§e­#bñf¬ûÏÂ…p¬™Ÿ| sJ™¬ì»´ø‘<¸tßg #×RÌjÂŬŸvàÀz›õ(Y6"$"Ä'@ô"[©“²Ôˆ±vFù“X TÑùœ(Ιlw6Å’ÂYiM¥û£“WºYA±ˆ®é$l ª²úPƒXz²ÇeÛ_ÿ勇$}ïÙ÷‡Ý“ÍÔHf]{²ÐRÊ)CâBrÎá«9ÿ ‘EÆA]Ÿé)é.Aûø¼v×¢â«llÈàœjG(uå®gºáSêý°`Ê™²8 Öw´äÁßFßâ–`KD•*ë/©ÖµúŒ¾¼ª½ô9æ7 ÖS =ÔïÊý 1¯ª,Rúš‚»}™ëVÓ¾1¼¦„“oÌO¾\o¸Iæa_oð/–Û¡¸û«t±œÌ^&¸‘"ÍKº{!ÔC UóxlÖ(6ÞqÐs±q†±¢Ú,ærŠÅ s^Ëd4°ÿô¢ƕ䇣[yGû*«*ÿÑÖA"—/P{å¡* '"*ËùJù%쫈yPqHŒÒµä#_»Ö,ýåüÏÖ7¹Ö{ÎçÁ_É Î%Êl ý˜c#“#|7—Pî9…¶Èq¨c‚FÉíGwFœDV—å-Å@y*ëäâ´’…~³Úôôx¹G}ª#¯‘‘ÕÑÇ‹:.÷i#ü µu¿þ[΃ qRÂýgz\Ÿ›’Å'¦uU ˆÏ–™Ä$:eÒb핵GaÙÚ¬xgþ| G©G¿\3‘]žÆÞ«™=¥O‚KˆìÓ¥_ó›¾OsÊeÌð Ô0j~?œ_]vœî¼\s?äjêLPÀš2:x²¸j­šï8è[ÛsÒr¡©£%5 b+|pççGÐàýwÛ¬„´‡Œ3Ýd³âÅ€¿~ö<A<˜u£òäÐÅ?#«×½9ž¦(í}ôEhU{Iñ1¢N%Äê´­(ï¾ižŽÒÎjA!§¦þ%IK[û’­jfŸõ&ˆðBè>¦rÌ[¤›/RòÐ1ཀ®áû$?]§šQ¤Í{ZôCœ›÷ZiV°,‡ªh;GP¤ŽQfu—­a£5¼šþéëj>‘QåCN¥œf£ m¬(Wl3O”!Òû{¸ ç¯]aoƒe’|Ø¥‹ˆÞéۤǎ”â…Gð„š°Ì¯Z14¢7[Å Õ3Ð<“àÆeß×çAÔéæYuì{šuI.éù¦~QçÓóQÖWö”âYZ!ëïÙÌå(KÊX½çýYq»+Ûgqß¹HX*K…:Æýäœ[ÕÍ‹nJ=¥ñS°Ük#‡ßMBË\lL3˜è+í9¥V•ƒÒÃ:‰\”hp® p׫1`6¹ƒ„0Œ¥1cXBˆ=ùkU÷‡­'‘Übþ -…Sº]>]`¨$§›AÇ †”q:‹;>ý :õ+ŸÌµSs† n¤Z¯«ñ_š‘>}´ïz\-“x¢¢g¾§=”ÅF2x0Ü ÷¨Ä5¦=mÝ’°Skkóù`,áZ´ùÁ>çöÉ 0®õɦÊÜ‚½˜ÐæL)ækúìU}ÁÅR-}÷Â:þé#[6=¾â3UH²YòþþlÔzü½ nÛÃWS" z[ž4©!Ì=VÞÂ]¾“rƒ^$šZtËw/~Ьë~¾Ý æQ Ô¼ö2")Kò~KéŽuú†MivM÷îmÊwÎ1_¼Ü3ýÁw©5ø|jÁM¶ZK_M4,/úK¹E%)©ÏØ \^z¥]\ã” Â Rò‡M8‰-Xôú•«lÜ»ŽoüršK_f¸úO|ÅÞ€”ë×|R«Xž{a¤1V"^¨àj“æ´5K î¨=«f⬵ˆ8-@Pû˜é˜ðˆâ„Üö$¦YŽ×=z0_Œ;6V½µœ§lj"TxVšŸ%±ô^4†µ˜ilã­}ã;­;9êo‡ÈWvyØz4柨RaÌÕ@§$/+~áMv.Æ”CÈóä˜(}&º{'NoRhا¿ÄߥÀ~¾Ði¸eÅ[À­»x?L“à Ù<ߤy¤ÙÆTƒ#¶z.ɼw¶ßq^U?7š¬jîN•ÂÛúE?½.MUÅ,ù(Jãá;$·C‚, QôU! ÷ŽN3aRÇZ/XÁØ10'8ÅnÝ ê“ð7œ2 9ÐR$mO,öwq±­jþnIs~Ÿ‘k¨xrèÎ ^ô'¿`­ÂfÓ»`™Lîs 6¦½ýßÓ&xÚ3³éÍõs·n{5m2<lüŽÝF«3ænÕŠÙKz{Ú Rï³=ØÁÅ|_J£¶œ5dS ®˜Ùeò1½zÓþm޹¨£™EWd‰Œé(¢²4¸¯s9>ž•çñÚâb¯nRÓ¬¬ç€@–(Å¢’½Ðf`q…b*®€Z‡ÞÏÒZ€öïT|þ1¡'dÔûkzös–âsŒf÷Ôõyçø$ñ¡pJ¤â¹"çÂÈŒöýðEæëȶDaE¢~ãW/7¿‡ _ç¿QЬñï•ü9ÜÌÅ3èFud¾C'kKp÷[ö¥ÐB·]B¬º×iìÃòBŒÈÅÖUcÓ] ˆw_³Æ2xœ< P¶x`É4Q©6e³Þgk8pƒa”ÔA²ÜaÔ+alçþ9;LöaËØ¾d¸È=ö™´é©‚ ¡ª';ãÄ"‘2› lÖéÞ† ‡y}[ïÓëYðõVÊ3*Ñ·ÛQ¼ª»’~„U^×/¾’wò`O´H·²@{”“ ì¸iÁæmlOñ6Kø¥ Ü ¯yíø‹~­'“ì¼dzë3¥ù²\ óyÌØÂÝÐÆˆ)8ï¦XÎÓuÙrD©Lg/Q}Êøâª–%RØß1¥½†1†¸=?z7mAÛÜ¢ï•W+ÙZ !>$”GFåõÙMNÉìÁíÁYèÁX‹’cM™\{©”ªÝÕ•ú„3$>;î¸HÎJ×398Ó¶ºòä4ÅLx¬{¨ÿŒ«Æ³5°îáæ*F¹÷•êO©×¹âÏ´7 =cØt°"Üg™nób]ìßÞº[ä‹ü (M¼Í½ñ8¶¯~±a.î«jŒè;]ÅÛÜK•,÷üRެ¯¢Òûq©îFÇšÙP£d@œüÉF–7j²lk¿å(a-ܺ9s´ã-.75ë­11¥æP{)O6”ÞfÙ¢:§ ˆº"±ò¢ÝHˆñ1˜J—è57ínKÞí‹Èâ5µ½9»ž-–;ÝTÏ¿ŽÿaÀfgñ*DáAžù½ŽÍC¥ØCÞô‰¬rlk—W2züöðø÷ôÍ{€¼ü,ãò8ù…¨¨êkDsîÞª‡g[A=+³G¨¹wµêìy·ÂXÊgDˆ âÛмú0±žn<½ŸŸð‡aú—L‚,:ª¢:)á:°fïùž´æ‹zL=ö›Ýûo/E9÷¤ª¿>MÁµ®â5â¿T·Û¼yË\_ïj°M/ºÈf^òãçkš×ãÇæI¸Aƒïë2}^I.D2Œ°r‰¥Ú^Ž"À]“ö᛹ÕwÞD§ Èã¹SÍf¾ÜõLå‘28a[HœX!¢‰8žÝh>1ª_fX™Ìè‡1v©ƒ… âmSÕŒÒav³BFï”6Ðfgì™­ÄÔ–7Ædß|ÅJ׳wô—Vˆ)”¥ ²÷¯§ˆÌ@áñßfn¸Dénë…VÞ¬¼ ³›éz\ä¥stkùêø{}f—€kŒ¸›ZÌÅ¿¬”l³Ž‹­I_$PU=غ’VBp¾¬r즓©^ì,E‚çmÿ1ÜqÜLbXÞçC ‹är¿YZË©QÖÌuD» Éí¥Ÿ BÃNHÑ^GÚí·}€ù‡è¹Ð+å4AùÍKúnÃÂ=FðÒ¦ôô pv¦:ȇ3ñ¡ýRV”ÐWOe;ÎÃ4_]Z;ªc‰Â à~üI@×ÍåÛ3ߘàV\âõsÍÉB=¦úqQ Fè“6Ai¼0_,ɞˉk¡FÇfÈ~#ü©vÞcãm2lXÜEÏüOEsßsë6vÏ,sÜ ‰¶©à—ãfµ¹Š8ïœô¹>-> stream xÚœ¶stdí×-š¤ãtlWرmÛ¶+¶mÛ¶mÛN:vÒ±:Iwìää}¿ƒûýÎýãŽ;jT½ŸµÖœ síÚdD Ê´‚&vF@1;[gZF:X22aG ¡³…­ˆ¡3 æh³s09¹¸™¿.8¿üBÎNÎ_¾6{ €ð@ÁÑÎÌÑÐæË.lgïáhafîüoÀÐ `h p±µw1²¶p2šÜì­Fÿ I[c:€°¡‘£…‰ +H÷…$hm øÉ àt:ºMèþ%°5µ0Ú:[Za›ìíì-€Î†Žg»ÿÀý P¥S¦ˆË«‰*ÉÉŠÊ©”D•U”$…UDEJ’â*Ê_>*æN';Sg7CG Àù«2SCcà?Ð&.ÆÎ€/ã×¥ëíWþÎæÿ7@Õ Hó…dâbomaüo+vŽ 'ck;'—/Ô¯šÍq;W £­ÍWÿÀ:¹Y¿¾ÿ*ÒÙÑÂøŸH§/ ¯Î9¦vŽ_|¶ÿÆ~!m€C3G ð_ˆðeT°2Ñ11±Ó2r(Œ)L__YCš¯9p°Sþ“š›9Ð`hÿo~FÖ_}þÊïÔÿsô_U:ý“ÀÎô_£ˆ¼È¿èN._^ÿr~!1ýO.v†/a|•`bñ_Q Ã/VFÖ¯Á¯™XÿKÎAùÑÿíÅNù…ôßüèþ®³£¡±³#½¡­Ëל¿ZçøO§þC/ÿdÁÈ ³ptr(€Îÿ¡!# ÝÓìŽáW£Í,œœŽ_Ãü"3Ú~)ò«ÜÿP#ã×ô¾Fcôån KÿÎ%mMíœÿuü5èÿeúèÕÅDÇðÏ:Q~QšØÙZ{L€¦°ôrvÎ_ƒPüÿÜÿ×Møo{@÷ŸŒb.ÖÖr†6_œÿJØÜÐñ«êÿËÕÐÆÂÚãÿ£³:ðßô)äìm ­ÿÓ*élø%$A[³/%1üב…“˜…;ÐDÁÂÙØ`jhý%ÞÏUmM€ŽÖ¶@;'‹—…–‘ó?l_[ile tr°1þk~©ý?²ÿšÊ¿¹Ó+ ÉJ ÊSÿÏÄ…Th•ì¾$ô_^ †¶Îÿ>¯þOØÿ|~ýï{Yïõsh3Ð100~9~}þוî°ŠÚÛ™XØš} ïk Mþ÷ÁÿF²sxÑ2~eNËÄÌ`dädp²1ûüw(cGǯþ«¨¯êþ×½©ÅW @w 1ìúŠ1•ÊkmÄSI…+cÃ爑BÐ7i>œ­í]úâf©ÓÛ²võ°ñ ññiì:~s­¦bÚãíýÖ ›øs„`VÐcgñA8'«¤d"aû=l1LŽ”§…0ÿGz„ÎVÌã2±¸Æ5ŠE·™¡áöHcÔ4[E1¢a7² ý}Õ•Æli½G Å>|µ™™à¥—<(ê}_´×Ãéu$è‚™?ðV¡ÎÕ[‘x Q#ºÑÝ%Côþ¥<*ÈY¤­ô0™ » [aäoËU î&×Vñ=–Ôç•ÃAg†̭節|¨ø¹F”RÞôŸÀ(˜m=â¡Û)ì!œŸ¸±~ã»U‡|W ÅDBCù˜À¾©xÀœ»FöAoTâŽ×=Nè´ûM$^Tƒ=ÑA‚LÐpæº-œî»a´$^ õüÈDoèv]h¦ ¡e ‚á0|œ¼3ÝéajE:æ[ÏõiÑÆ|bzîNT4ÿêŠÙûgwÅ¢\˜Ü|‚ ŠPÌ5‰¼è\€Š?Áú/ÌkúÙ‘;¡gî5]‹ÏÉ=${~Q/k˜dކ\^oÕ"ûšì4<å SS3ö2íH=®µ¯»i@}:äà ½‰¿74 Xî„ûgÑü·¼¿ƒ úy‘Æt² ‚/âMúRÇ…”ëˆw†•4º q[l+4aËÈ-3AÅñ7ÅUpaBõý«”ë†8ô@ê5ª׳d#pc°j É‘šç%ã¡[5{ã”ìšY‡âR®’±ðq)˜gÉEú˜áÔ¸”›ÍvÓ³»wù}“b„ÆÔ°Šx|^‹?¥ø¬Ä~½‹ÎõYûPÜXÂûb3?Î#L€¥òuÙNýÝ.–Y N6_BB2}%{}«Öê%_¨×…†W€Üʲš÷Å}g—((FY‰?½ í´{vþÑ'ЉnΈåiœJAéAÞÁèhðª‚Av„.Ùàÿ‹ƒÛ7FRø“•Q3 ×-fnr›¨«ÝaªË¦€ ·[0µÉ݆žÁ‰ÒÞÀ[.+mD ˜~3Â4ÇØ(Š|˜×jÒÛHÊq_f½|ùp©ú¾½»4«¼£’ï§f%GãÇo‘(™üÓ¼´_N”Si^‰Ìüû—á2u+u÷ ,¦¬•?ø `9#vøöö¡ÄÑ·ü2l<Û¥ýµËv×ÈÛ̱4N¾ÖÓ–'¦’¤wÅ틘 'Yöô5)bϰ¢ãûÇŽ—óÛ.¿1 <Ýžýä ÇÏ ÏÚ&f/ý5)ÇB ØdkJò~Kì}Óƒ7s§Œ9zç\AO®TÞŽêà Ÿb}GgåÚÜ—¬¡~~ ˆg~_|¾M Õ<Ôô¯»fµ;ž”i\ëЄ¯Î0y7¢Š‘Ë-ltw/:ð'«o”‘ @a¼!¿ÖĤNLlþ±ÁlÊÊ º¸:‰ñQñÄS¯œŠ/÷nàmJ”fd§;>ŒóëÎ9ÜjkÚ²à-´’PìãXÇå$Ü'À}N •È Ú'v7ÒŽFM?I­¹]¯>ü´{ŽŽ2š5¸î°Y8Â{Y¦†¨íÙ”7 l-´à?§¢-ôÒveIÊbHƇ]_KäÛç[r•^Ôo´W倚ڌ?–åPÂŒ ×Á* óËsQ?>†íÀý¶'Ô¤Yh5^Yè‡òq¢È¼^¼ìP•ÖW]ºÀ$ƼÓ~Ž1™œyß§ï9=Œôˆ§V0úJq¹2g™ˆñyt ÏÐ>ÉܧzȬXs¶$°YXÿ±p_³¤êyfÖ'Lîmpxù8Œ“¡%JÛÀp¼)†ÐWÔX€òå3Ãò^\øY‚ ö X ü­~4Þ×LC©ÆN±ˆÌ}ÀhCã†ñÎ<ÉǧaY°³Â‰óÁŒÀ©ªee_ó å£édhcÜ`^o Ù-Hk!ƒo“˜¬Éº®1Èâ‚ÉÝÙ¦ç¹ö,`8sYãýû-¢º\$ï½ôããR+uTº˜.zK•ª³¬žù¤Pÿ™œµQ…“…ê**‘é»5ßè…0‚b£¾ÃwÊòÀPí â#Û¼ó‹‘¡?#Ú¿-aø>ݾ°}Hr¶‡V™[,þŽç;,+hÅ[o`mÖUƒ»ØÑÙûïq£0ÒN½s*~ÚáÝä¿þèúqÅÒêšÞVô½ô F&éù+2wíÕ vÅòLj' F³†wÿ„ ÄÒT&­® 8l<Ih›[ºo*ZC«×dþû:ëEÅÂ~†x+ 9f½å@˜ ƒ„ß9ϵBKfŸ‚üíþƒìÀZÉÖEr2‚Ö‡6báäÖÏ‹X–š]˜Ï þ#íÇÁ²‚«Ð{⢑˜Ô“L ú-²Ú¾çÓnœW´c)Þ{èPªà¦C)œ²xdJ­dÛ./oç£èj"( »ë·Â0d$þ6}@æ7«#ƒzQÝ8xI­lúþÇZ¤ˆ®x~S1ñ~À>ä9ûDÇ€\]«£H¯ÚõÒ6´ øDR®çÀ³ûY‚îçœ íÈÓ®ÏæL¢šÇë_qô\ÂÛXí¡d¿Û0¥óC½¼œd+MõÛëP×§ýÁTqÈÌDà{NcãtY±úDÈHÁ¥L g¤•\Éòo[äçßAtye|ðKYv÷ôE@ÚÙášõtÔ¦ÂuI’¹dг.íà ºrøtOÇqû,²õ²ÂÃK "« k?(ZŸT¤)B2ô~³°Š^W°É}2V¥÷øQ¼P //˜¶¨$çrùGn¯=Î AÝï¡Õ6·P0xŒÏn]^®okz¿OëÐêxƉÖ—áÓå'Zv–ú¯AUKŠ”¾ÜrY„P´êÛCàŸnŒ…RuM,éH}%ÿÄ5Cʫإkl±ÍŠÅ—K=RuáI‰•#ü½¬ù,°›_h—FÑHòƒ ºù.LjnáÊúƒxƒœ¨ïpÔ¬p$÷§ÚÝ`º ¿ÛZ}‹9ùT”=—{Ôð½K"᫇þ°•'„1½¹bk×ʪ¹ òï[¾§ÈiõŠp?”ǧL脹Ç,Œ!?ÌW yj±Õùß-Ú‹ôÖ͉UsŒìRÁgÑQ~NFF£YþP–œ–÷7ÓãTôI}²íýÎó™-qÁÔ°ÖÄ/ûó5·Ë<.übÞCøÍ:Eâ*‰qJ³÷W¾p»…ðQÒðb9“]+‚eK'°€"xoÚ9ÉíÒij)6êöý—{­TûÝ /n4íËô¨^*B«N u¹AK³Ë9óüÁ+‰£ávÓÛ¨Ìæ.6ßøHEb¢å wå7ZP½ÚÁîÐ,˵-S«T§Ï{Q+ý?Ä„à˜{Htnhp¯gEË‘@Ó©Æ7´[ªÁopò¡éˆ¬id^Mç%.ó+ zF‰ û³êÂÉdj¯Ø‚Je ~x%çJ,b?œÆ¼ÒüÎqP[ÑöpG-$ámÝa›CT¢à 0»O›6­¸p’UÊS{·õô7à¯ð§šÑñí~·‘ã´ç¿Ù:‰lPÖdS³\:@Sq#×ö%–@^d8ßY~„|{”«×I‚î(ã§u Ï“¶Ù½¹™JV(ÄËÍÌæÊÉ5ð½|`t§ás@nî° µ­¦–³K jœòösO@®GËðb[c#üðVÓõñ°uþŧÆÃ Öæ¸ÃwL¤ å´ë[å ä]FtTÒ°Šu_‡pÍh›ÛÁ[89óãt‡¡æ­ë–,yÌB¤fjRG‚î½Ñâ@ü|Kj’œÌ¦«Î+öšÖHo/ ôLq»)HiëÕ=V·Ç™*õ8VCÓI‡o··8H,<(Aàkêzá¿/"ÖTOe#ìp³WÍ ô¼änÌ—“è•Tò:rb›-ý¾í2WÁ” .I'¡t’ÇûÈn=”Ü$1Gѽ Ç“h–ÎúD’’Oùø³v9™ÓÇN»ÿct$³ªXK÷²ç[!aV^‡Fæ·–n‹ô?‡ÞCBÈÜ$*9ëÃdžϿ콽wBQ†! dƒ|€ócÚë¼%qÄ v.³äµ¸tÜZqy|^èüÌP5Òeç$¢Ÿìi¬’ )±™¢Nw‚“béO‰qêYnå×&² a2‡ÜµÊ”íŽHJÙg—±éƒ—VSjAëd÷¿ØRàIß™rAó¼T/ð'Šê×Èbï©æïÒumûëJÑßa2ÔÍ7YžÃöR!¢ž=E¼eã_>ÄÒö+¥9b•ïÖòÞÏE“RjÞ©¾áˆ÷9_6·:|Àr`Û;=̪ÉÙ[w> ®·è0†.¼ ‹Û—mö³íø ²¹¢Ýç°ñ¢Öê`mÌÿVÅó°1J¡£ÊǯʉJû¹— R"JCübWÙòú1gz9,mY‚P–’Y8lÊ“Ž•D§Æþcšv˜•°¹ð&Q¿ÈÔ¬BšñN5zJÃöñâv¼¯±_ ‡}«ÂuòŽ«pgL#’\Ñâÿ¾ +*È Ò;ÿÐ[ˆ»¢ìݽS‘Û‚ª3ÃUÆ^dÒˆí÷‰!ܤÎlá þn~5š4`éÆQ¹ ݺÛÝŒVZ1½ÄÝ-þ$ë‚ú×Ãòz䎫P²6Há×XZé,Ø%~7Í·ÂT$“˜’q,‘hå†È¶a:­aœ^ìÉ™mieÙØÈ;ePW·Új½Ž&8q=%<” Ùðcº" ¦)Dàån5‰òÛ»,Ì„˜Ìs ¸Ï•y ]Ór²ý˜±UãÅ×/]Ü~‘û0;7]qèÌs3iw˜×àiAY|bâC§ŒØúÕØ?¹£Õ Še¼íÝóàŽGÑ/£Bç°GG>ËÈ;*6¦¢ªX"ÅáûoåF)²._h àåYέß3Æœ´>MÝÎ^¡N½ðîlø­d{­ã{_Ò¨Ëcë@˜{FÅ1¨qDFØÓÓñ‚ZhÛrã?´KéN®j¸hùÔŸCȣΙ\Q»³eL7Éàhrh¤•*þxñ¥˜ª›”{XÊ›š¡¢«Vþ²’jËoyæRTÜGÃŽÌ€í_µß ˆä­Ì¾^0f KK¤ÝPž/ÚÒ. ~©”ÇèàN3-è7­E࡬>éˆÞ0ç?—°2#}‚÷’=•è¦Ïv¬S) Z“¦X=œœÞÏO©sŽû“b aâÉGž}Þv*šÒ¾%ŽLJOíÝ98í‘»Þî+×jÚö¬ñ ´H/‰sòî€ ŠÔBTTñXêó˜ü©Û Ñqß*YOpáy–[ò”^TmÏŒaàæ.J\kH XìíÉHâ«Ã4ˆ"šr¨ÃeÈ$þ½¨ÃÂ5AûCù¼œî{™g úÝ–jÝ÷Fx0ñÞZ6V“DÚ-Wâ=tÅÂÏ Óš”›%å¯Ù(ú@œO šµ:r¾ÝÚŒæJ“^ëŠ1³ßÓnÇBâLNà' O‡E¸øGì‹G\kZóRmTïøŸÂ~ú8évq~³Ðß•áOðß²êŽì=_ú‘SÆ-Ì– l~/yLy,îXè/€NžõQ‹åbh”ò‹ÀýÉÏ3‰Ý1ÅTŽéÓ©0Ópì·^ø™Ënf£H°3–¦š\»\¥˜>\‰È+¬‰cöÉf"pÆÐb]-;¹e™û¹Ùíº@Uƒò}”:(lõô5fWpvÒò‚­öõ¼t-é$Ïktç×rÖ(Š9¥ Hù»ë!¨ù ±^²ù2ù4âá²p)‡ sÁYZ„`E"b´~ʆqÐ’{·å“aþEÊš2šQï°XŒ$Û\|\ú9[ª}}áSÈuƒAè#Iù¼ ðR™ õØ´eC™;¬©þøp¡4ä»Þ2ݧxV¦ÌG4ÐY n''acLåÈÿæ´Ÿ5š£%ô¬/xÖËcÎÂÒ•+ÀÊ1òSžËå)wJ äi‰³ñÑ®”rÜE@ì ¥¡¤ÕF~•9#Ú`ºÂ÷%»˜dNAóË29Üì\FC×ÈߘîHÌâfÃ7Ä—•G‚n_? \-‡°'Ö¹2ÞãxÝz1ߌBK1žÌ&Ì }éôÀª:UÔR×&u3 WjEôD¨"Åæ¨‡¨Ùd'8Áe@OdýQ€úÞ½µ AŒ4Vy­ë@1s FlŸõù€b[jSz&å{}ÿ>—tý=¾mKÓ€Ê8å’”·¹”ÕTœH7µ í~?[Z¢¿Üþ½šïÀõׯI Ÿ'ÇÝ@Xþ>QŸøÏïž26þ>ÓÑè&µï("È© 6Ù¾2d°bN†1‚þ&þ‡áiû…ÊÞDé|Y'Kí¿Ã·ÜMÊÛÏ/­¬êZ¤A¤]Û (0†ˆÜ»´šÐLÄ ÿba —eÈj³ùêÎ ÇÌœ©Ã!UbþÁè 'fâÑ2c>#hÉdi"Ðõ†Y‡”VþªÇÖ„àÑ^ÐcW’ÀbÆóîÃI)ŒUœÜ ûBLæ~‹_7ûMSŸnÆêD\¨Ï¬þÄøåv£ó°ë‰,ï#‘DþiýÜÀ«5¾Ç.ZŒÍÊ“È8#˜¤•ñFö…#ð/øy]\¢ øøÔ‘ÃèÔ#‘wBžªHàYvýíþE”öL.kcúŸl{¶|É\2J5±n¶[ò}–“‹Pé!$±ä£ḦÚ>§Û 7z^dÔ:‘ORIâàNòôÈqk*êò¨Ÿ> ‚ðŒSÉK¤eBùkçj†fžékFºémÌJUòèŠ_LC/rºúŸ@Bº›t„ž†rø:éaZônþÂ¥L·£˜°L’"Ð×ño±n«Uø~´jé´poxa¨äîÌc §PÕ£èøÕMêÐsØaNa2óAjêÌcç ¥tƒKiZˆ'íììéw¥(íÍ›‰Ó9”3醌®?™Ý6h@¿?¬nd†\CΖ‹È+ôj&Ö€š@ÖÞ™!¾ä4ökÜ k«…ºJ뮳ôg–gBNÀ© RNÝmwšà“Zo“ƒ c­v‚¸E7tnù,¯öÁ©(¸Ò®2‚ÛävÍ`Ú%-Á¼Î7 åL35-´¯¿ˆ8g¼•‡4ö Þ)jIP@+®Å»‡pÌ)× LUÌ"tÓÔb5…Iç¸f€`³ˆÎ;é?\P—(Á´»Ê (ØVGéˆ>ÓÅ ‹T…gÖïÄ“`áR—â>~zæwMTÄ ïÂç&–ß9ç¹ægUÁVÍÅÒ¬ÃùD@Ór0¡ÅòïØÇsZ­»ÞÆ~?^úõóN¹s|èf= e?¯—<ÑìØÎå7CÊ;3êpæÎ»8Þª’í1R¿É³*øˆ6sf–ÍÜBróâ¾bÒ§”Ø#!#xe\ÅÊV”Œ‡}q?7¨o'a{ÂJyhu¥6x¬ôÂ7÷¤#hUT)ÿ—ÏÈ£<7$ã—™Ò(Žº%þi”vM?%¬¢Z³òž™ùWMèäiK0Ѫ…òŸum«V)/·*Íâhx«Þó1 ù:1›õe#Юˆ¹ Þ‘ƒtz(36A–Uk9b„"ÏRH¯µßÃ@|Ω0²:cPñ~õ´Êç€ÿTšùöaÄÖ»ù=áj<Òcß4I)¶>?G f‘’§z8:00B8­·`œ‹qßÈß]ö Ùyšuž_NüÙʰ1ü,EdàÀ­èEùÇíµ³e rµJ@À—íQrDuÝô„¿,³TBÇ–¿•-ºäÆ$§§wýAfŽ Û.UY_7CëaaKÁâSV[/°À‹=Yõ['zÜۻݩˆSoƒÂAðEIýéî‡Ìñ¸EV óͱŒíÃiæ ­òSqç@`Ç=^ÁuR²3™9Ýrѳ6þèšÐ–~±! åÆCV‘|9ð™•*øä.tÓ„:Û²uØ…8º›ëªÊu§ø&•µÍõ½:GøHÔýÓF &áô 0uœt"þ<{M}’]%¹ ±òEÒÒPÙ·×;öòþk¶9låô ô…hKú =S‡å{£®ÈþÏjî. &M`6£ùÍúAÊU`ÒæýÛnìp\Ö©r“ý#†ëöÔZßõWÈ÷¾3Éu͹Ð-œb("~K}lÝݾc/É’À–˜æü‹å˜çÁ3<·1úbYåô{íW„<Ç3g{MúYä‰:ëö,mOMz¬¢øjã~…9¨ µžU®”Ÿ¿üxŸBœ%Go]û¢ÿÎãþX(é˜'1ÎÃÛ-”&@ç¹ÝyE®ß4Í`¶¶m!7Hð*—ŠÎO£¸Ü ž†ž²E–PuÒpž<ÏtÒ·ÚË©‹í@dÕiãÖþg/ÚÍ›™’ÊTUHh~Oô:æßT¥¡è m„–ùü17ÒÄb);ïEáÐ34*y½0ÂþG™°³6 uç~K^ó·jà š2üªI·~À££6‡Ïñ°…FSXUy9ÆVÃà!ÕÃ3‡Ž£°˜Ìλêùtc´|Vã(›Þ™yŽFÞ x%S¼\5érã~JxÖÓ9µ‰A¨»eŠ}šÅÂ÷è€jæaÿʉ+$âƒxJIÊÎ(„Œ{7ÉÑ8¢j*ê§*é½A´U!|!_ŠTk†ç&îÀ"ÝeAWÆu…VpdýhÅÔ…ÖŽvªû¦ùEFPyä£aód¼ ™òPÌꔥéÖbÊTeˆ‚Sè†dŸÜ—V¥×Áªiƒ Ëå¶,% |exèÖz—Ú"‹š_m@.lòØ_Â9ÁŒ>ä2BÙà±V̾ \=N‹íŠsz¤Á+"HZ{k¢ûgÀ09߯0y&°U%ã½dOÝîÕëðÂóFƒ3ÏRoMõqc&èÔF\€‡*s`¥FÔ˜TöÇÌ_ðA²÷e7Q(ú¨ÓQ—Ø¥$ÍN¿úÎaÄ•`l? aÀA½p(ðâyÒTÛAg«óg XìhõXJù³0¬ËR˜'Êt*•Q¶ÿéÝ”Ç/<}³£(»°‚rœ‡†¢Ïk3({69V¯ L¨-ËšÃJûʃ õéÎitÃ(SÞz‹DJ:¹SÁSÙ|Ä[FoBñµkâæ«¤?ÜÊŸ|&W‘¶jïRÛ6ѱuFöÉs4b8ÉßNhSDÑ B?H Ü=Ü ÙKs‘nŽÜä`å/DáK*ç…Xb©ž=HÄ95NÌ«O³Î|pñ àG:¼¶}ß9`g¿{CwbfsX‚]þ^KwÊ"G€çÛ-Öp%’ÍÐé`wœ^Ñ C“¢¡ëdkPDÏmHЧéS…JãGí¯ ØDµûèïìöÒåm(fãZ‰oWù²¨Ž<ÜF‚w5–{N~è‘+'ÏéAÐϲg5›‹ÇÔe5«Ãë†Xh"ìJ\Ï´pz/Ùu·aô³Iٟغ—OÈ¡B…újIçí¢µ-›Yº›ÚéC‘úµ¥tQÞy±Ë½¥1ý×Ó‘¿`É¢…,ÔOÿÍŠÆä ª°ˆq¹{ôÝ §Áëî³Ü&¥B~öWú&¹î zƒÃЧ}Ô^Îél‡A¾í7î»ËB¨»8j¶~Ý“Ç{5ûI<¹!ÛEzh`*„Œï>už¼ ¬¯~AÙ%äŸÃýÆ‹—ŒoÃë(1·á4`¹úQEÏg {É [ݦ5õlÔÕ½ìŠW "ó’Dè;ã±c¸µBŠºÍ*Iv5«—>ò™B"(¥–Çt}d<¡ŸzEGÉþá5™Ã¹MÌ‹0€ÉÑë6 ¡%?C¥Ô¤Ð|{­Øi7¿emSVq·kóU~mT;³÷ã0K@‡«úå‡K=¿ìžSÕÄ:ÌÌBÜ*-Ÿ‹v,k]ö&ç!ÂÎgåS.‚X¦Ra#¯ífâë;—‘¯)óM‡äçÝ9¿â±jùƒÊB‘<ûœk^Ðn‚×S¹í€èO‚ϵñHt¦%E‰ñéœù)„¡²@)_ -³V¦aeü»MCß9ÙtÚ,RÏéÛ7ó§Û7m0c4çwÞ$¼dCv%fû‹ÕoéILÒ§å;´Ð`ÙtÍìß­ê¯ãçEÏ~¥æîdÿE7b©Iô^o3ýÕb«r‚©ÁÉîð Sï=)Ñ œ¼kÒ½Ì~Ä6!¨Ž÷¢¸¬ ˈ-‡´º÷ä‚Aw'#œ—{aðÖ~ÈLÜ[éo ¿ÃÀÞ±ïkƒ2æ탠LåžsðW|‹1p†pêÀr»@AâE$6¹¸¯ÍWnªr°î ˜ª>ê¨Ç»Ë©¢¾Èaºe‹²Ãf¤ž]+Jñ­ÃE=?çv§ÇÖÄvCŽ{_‚ ƒÒP³²auƶŒñzq÷ ˆ´x­ñˆa$9ÕS îOøjqŽ«ò¡.J¥¶î/Lî‹vÐri9½¯É¤ï„'ÂöÖýô }×Îë“*.Ÿ|6X8JǤZF"ˆ”çWÜ·YX‚ŸÄÿ¦Ñ«°ú3H³^)¬d¯˜Ÿê©‘Fûü›Y#‡ôÔ@™VìpžÚ‘ÝÝ>Œ.¿ˆ¡ð/ï/d°:6Ió8l ýÁŸ?ü°`˜ïqã³… E»þ2»{$Cª @ô|¸¿pí ²RM¨[«SIî}09Ù–)åµÍÌÜÌs#Ö°ÈõBÇ:¡ºSã4_…pèWTPËådO¾>s_•ëÿ=cqE¯(ÞÕÄÛO~è æ¦zCß!Nb±„~¹ƒGy3‡VÆÍâ²¶S‰©=”Pö4 >,/=Ót²Rä¼è¿e·ºZW}Œ‹v€`ˆ’¨xv§¹{IòMŸ¾B½õDì …ÙOü;BJ{.ˆEœë®«cE(Šù fXÐ[ø„´‰øóˆlË÷‘ûˆÓè¾Çp‹…RØAqâKÅúûÉÕñvÛm_Y…³Sí'Ÿö‡ÛßÐÔ¢º¼k‹¹‚ˆxïž~ŽIM¡?G>F‰ž]'ýÚ`ü°ˆ¿’!Tpôk¤á&^°3 Ål®ª±M\P³2h&‚,Bá™y¢C±8“rkjÉïH—†‹*TÅÎ-A4êx#&z­7žMdõi5xåÇRÛ '˜žE^î€91?:ÿ2Ì\<Üýéjü)âÆëöCpšä uÅ 6+r.vyKÜâÈñ×F˜U^ü}©?‡Sѹ‚]N'g%¾ Ê„°óU«ºÆnŸ-Š1Y»â/ױњÁ´ú©õ¢î®&9cÄ ¸3oD\tSQ¥úÜÞÉ8†Çdûè©›E" Œû)•ú‘ò½ÓSó¿ÝËqõŠ&Ùæ?+ý~ò›Vb!^óShËÊ ïÓÁŸx¡ŸÅ@cÙš\¤7†³Ž®M™¿Ž.Ë~­ÒÔ`‹‡%¾9Ìçky>­Ãšp›E£sòÎ!mÜÈ¥ ˜zg*Œ8…úæú8ì!‰’ø]o`D,˜Ö÷rýÇŽ·ÉJÍXÈPز³Ç² à͹êaè ¦þê!Ψ±ü|4±^˶š*]…¡¸ÔMq]ѽü½É‘áÔu—çiøâ u‹ñVkQl5üÒ~u/Ìyvõ6*yãU]õ³6lQKc+ q.N¾µœÇóë¯5‹ìcO`îøžxˆÉÚ?K`+Ã%B¥ÌèÀ8*^ùˆ'Vþm:¶5¤ü1dp>Èú¶ñ¦ ΤeØ1Ñ*'“b3Yt thóÑsµf½^™à©×6ÏÓZšDÉÄ• Ù2”;Áó+‰ŽÏÊŠãua¨UK-v—ä¾l)@¼¾’…»OºË¨<ö¨›â ÞÂôN gf1d=‚^mÕsmÃðX9íË¾Ç ]Gµ¿»™²}6­z]zQ½§×‹Œnì³tX8o.éu” ~—Ê0#,À›œ¯ºg š-pœ—žÜJâSw—ª]ÄL¤qs½¸+B´ì ǹóûxivǶÉà˜H‡Ö‘è軚‚lƒÂQ)·æ]Z.­³1Eî·ÏÁ®·íŒâjŒèš´yj+“ý0æçá“€,©2´ìÔ11^’Ý5××·íßØï ¦* ‰¥‹M>ˆ! ýÁ` <®;zv-ÒÖS¤:-­ZÌÕÎQ±‹ÂtÕ.†"lNE¦çÿì($8òüÛ!àl3 0ƒäÜ3ÐâÃÄõÄ'TÁþ$ËsXÿ‰®úÀÍm lYÖÞ¤áNä –Œ¬*g8(Aô2!lÙ6˜þ(k…ÅYÍØêr”H©«;|dŒ€š?¢gŽöçÔ¶ø$K]Í)ŒŠ’Ÿ —ÓÕ´§+â’Òîß%µP(¿¸}ÚÌë¾Ëz¤oÁ#;5,N†Lqç¯Ü ŒÒÇ€7—xM— Û{#º7é (! Áä¤kCYÚ¹·R@äó!Ma0÷ëk<ÌØ¿…)@÷öZ3Me^áhªiËxúÍ¥®í··`Žåt5mþsKÿ@TÔ™†zoq‹H&Ü™b#RI~u&t€âu=/ðŒ¹:bþ´\Χb¼‹ß¡]Åéyèu‰-ifÆØN)1~lE‹W¸egÌ3TÄ¢¿÷¬þ'¦‘Ú—Øþ>¸‰lq!ðØx!Ä?fƒ Z^#ÌLF5½ýH|>Qœðb‡ÃÇ]òñ—ÒÍß~tí&@¿’±ú|X™­w~ζÎ]AüÛ>sÁ·cR9¤—Ï¥vžHEí7¸Ã2ŽLL'N÷÷†×‡ºVj•Ó5ÔVmTeUÜI¹¡(ÜJ¤ Þ£òíîIØÞ7ÄB)õ¥›I>™€4ú¦—íÅ1A³?—;±Âø8+cyï9±usÅu%VKCÖÎ!‰Û²VöÕº ýèØ¶‡ª-ÛÚ²¤£â"¢’Â${L‹®KˆÎ3…¢c Ê8aIª“v^‘ò¤å¬·±Wñä&[½’69©„ÔL¨„¹äOÝ„jÙóOŒÎÛi)5Á£jjƒ›ws#øFž¡2¯ TˆbæøpñM5òÓW!ÅHlôãòFHX½Qñ­¯æîpæ…g@÷3nŸµGÕ¢gFKõ¸{‚ãþXv2Nnj¢“xúBB:9ä*JYê_e;ó÷ilá“á|쓇e–2Ó¥8:®Xч»…‘ª83¤ÌÉÏúÛŽ•Nw)±OH> m6ïfU†K¯Yâtß;mq›ŽHZJ_^=œ(šÉàQé¦É+7_Çïê¢öh6äÙãx6ìË1F(Y3~F§=\œÐzœHÁjSRzX!\=9 Bk|ÄÈŠí»ß…æ Õœ³ŽnjO|ÙB·üþ œhŽín)„¶o†D% ¾þîÆ¨‚^ì”"snL°…£¸…:žS|9-òº¶œB‡e+]é?ÒîAÃTÝVNœ.”žrp_›B’Í40•ZüÖõá˜=ÑyÆ<ü%l{í¹~¦73¥ Šª1Œþ–¨…Z´Ý> Êjñ{f:P‹¨Êoà™<õd²WñØAHq¨ZaÓa伡;ãxãÊ[‚ÐŽh3ǘw'–áê¶½’S…5]œ›ß~B š:eGãÝ¡¤)²KÒ=ê§z[ˆ?&FbVð”cÉÉ OeZ "Þ ©ƒÓ±9„üvn³qmñꄞoÞjñÑ‚Ÿ€ÙØÖ¡WbYB}}щŸü›¡§äšg~˪nˆfþ0P®o Ÿ®2åÁS°^¥Ÿd—H±ˆÅ¿“Ëõ¡keƒ¤¨¬ÛK?WX«qPœ °•C!s³ø-"j;7."ÇuÞÔxÃOï;&QáŠÜ›9dȰÄO°ã«D»˜u+«/iâÓ‡JοÓÅPŒÓ5º²K ùÓ¬¤ÿæIQ ç…1SÔgžúpö×GL8.  ó~Yô¡p[¡T×&ÊPjÔ ‡³±.ÛÓc€ ­·Œ}²]&Q/!o‹šª{ „7½Pe^†±~¾G66l|ÀYá´”ë-[!¬§³-ÓPËúÿà¿÷vr ûMpèjNϪ\fˆ>³»ú#Çç"…up¦úˆ÷MbÕ+R:+t±åÖH…]¥ ý0R×%»69J”?V`4Þ±… X9жœy«Ê…¼øï»ó­AÑ_ sÍÊK£5œ±ú_²~ F-bZV¸‚,I)V/»¨UõßðŒ¹‚Ï™•ȳ3TˆÑò–ϱJ%¨]B¨|c‚l¶¿þøáJ@ 5WÄM="—¡&Vi¾f¸>2¿ÃõúY^Û ס±eGªoh5©LÒÆ»ž .*u"Õöí0Ò'P^}wI´¦þ·U´R¸"ŸYnpÑEv¤Ê­˜ÔßDÜèiª'óÓ‰ôÎ,­F•n÷4é7S&£¼v¢kh½ñ$'Òª|ªžûQè-Jè8UàxÂØo•dÕ@’] c,½8&¬Ûœ" ÐîÏ,> –ÌÏ®6®á¤½ÉV„Œ‰ Ëù¶I1ØÎîi漫ƒ¡£$–®@„Cm¨ï8£p¦Â\xˇäh‹ioßߌ?K„|“ñ„˜“Bu° ßž´o'ñ ržœSråœhòZA{ꃶÁ;Š Åè‹Ùe¥xy½EØo|Þ-ô)Üû.Ý{sƒeg¤å àë&Ë\'¾/·©?ø)¹)Ù ý­ê™?ÎÙ;çNˆJL¼CЇnÎZ5/a_ªÍ$1“°+Œ/c‰§£æV’\ü ·?ûa$3éW>ã¾6¡O¹Á:–%Á×ümíNt§~ù—@HN‡êƒ1ææ¡~4 e¡nž7âÙÑî%cbzIKÿ7?WÆ_Qgå °Iúp¯®ƒ™KÑbŨqHº $rrS•¹;n„w#½#H@vT ÖÐV³©^ \Z]épÒy•ý™ÄL— ä–ˆ‚¶>(L åò!žÉ'Є1‹e™”™õ0ÐígÊЂ’ݺŽy‚pÕAv—þFDC³Êµ³ªµ5á£n‚æš}ñþœîŠ´ ¿ðò.8Ô©8 ¥Ð„ø.!‘•só1´4!'^³wïyéÿ¶»và #1Ló=l´ÕYÒ¯»£‡?UuÊ稻Œö0$p ¼_+Î øh­%PYÖ[JÙ¢LKˆá‘·\O­7“Ÿ‹f©W[o ß-ÅC‘Z9ÚÞfeø;´ÍtÉv^IS˜S<…?²‡¤_ˆ¨[[Õ„ œ³Ñ-p0¹ z›ÁAËõ%À£ñEx¬yò+‡à¿ZŒ’ävß®¥ƒì9/+’˜¼Â6(/ÔDGþ=w˜æ pØ#,wIÅÉ,«CûùWÞ} ÿízDûÌÏšøB«(z•\å:Æn-ÙûìøøØì<ÊMµ¾¾öÒ"ÅÂUöDCOï†ï¹4€Ð´)lXâR…JN›à¯ÉH°ƒúˆ´µr bZçe3q§~ !øutÕmÄ$Tå‰#ò¶—ªØ ‹jó"¯º± X1n ³FTvTÁn׺º­%A²¥ø«›ke/üº×ÐŒ¾ŒùONb6“2ú+™oöÚ§HCÐ÷T—N"ü<Ö5>2v2·b…PD¹ "QèxZ˪®Œ!¢nßQa·¹a¯YÒ闚Ѥ=¬ž"X´®ˆm~5ƒË`î9‘U×õ'ú ¼Ä_r-)L×DU ôA§ý\’z3 @èc‚û¦à4ð—rLí–aÒ¿Ü3#CäÖì$Õωß÷!yB«£÷Γ :ðœ){ïåzØè§9Ê­xճΠþiT|{¿GPЂˆ«®}âT÷„”eœoKúÐX>ƒ¦\s¹r~åZvO äò®ºÞ=±Õ³`nt—+'€IA ù‰B4¾’™5X¨´¢Æðí" Þ¢’üFؾÙ]S3YôÍŽýÐíI㛕çâ^´ÁyžDFóMÛlCÚ=˜:ËͲýÎâèš6ˆù†(m×:<^$‡ÓV×W}uø–‘„ÈPûêÓòĈ/s¦ªœ´¿¹Ö>KºPˆ¹»E&™\Æ]ëý×jj¤#Ò¤JpÅoÿ¨ÑâÔû™öTU¾^ò ’›Ó¢ÓÙªùËË,I¢%Ý9l¿!dr7`fZÞMÍ~ºÉM‡Q–»WvB‹VÈiú×?Þ‡b*8æ1SÊOgvE¬¹wI©mîÆÍ–$<…ë‹ 1ìC¯zBŽ˜÷K^÷ì\XùÌžâ×Y>ç½åà®uTò°f ìû´ûÞ¿}|?iïým1iH±‘ é4vt?ó‡pqJgfXŒOˆ2Ñ­µÒjvc9ÃV­ILD]íê>ŸøtJtAƒ5¥©ÀÒïSDá"i~];eè@Õåí¿ͤk-»âGh¾Z$©wNÌ5?DT^ˆ hU² ™üıl¡6öƒµÆÁr †¯ŽdcÁ‚NÕšÝwýÜuU©éý{ÌúaZød£¦±xŽí…S³Î 2¢ò‘`ǰþRo27]·Óé4%ídg@¬žëp1Ö 1|¨ý½[–7<Œšeï–ê&í¢wÙ·ÄÙ°@PcÜ,e‹äâ¬×sÁ3Å ä9SKëŸòÊÇc×S8Ú¦}K›I’M™zÝä-Á?y0ë¼FYD!m™Q} ñ„ЦÈs¥üvÛ‚á3ÇÔeÏî2i·¨i”²åx»rö¦*±û^5ÑéR,É_ŠÓ }¾#+êJþÛ9áîõößUPƒ·;ªvzÉØø(ºÞVpâÍg´§ær\m2šÝŒ8£½ÂoÅ|ú¨7ƒÅ<²—@÷:i!eñ÷+ç­ì諭“^ŒðÂXŒÄçYƒÑ“Û=°ô€p½­ý½Õ¥LbŽsô~V.»M™øQØ Fbb‘$§TÖ‘‰Òjr˃¼mC~†–X níEÄDÈz?ë’8E[ùÉ!ó0ˆèp8Zg[ÖÙ$›èe­¼V&Ô‘EŸ²•ä 3®F~…WEÒÌý ’<@‚ˆå¾Š])quL]Ž.@Åe·<Y.“Æx"œ­`ÜK > êòD ÕúVà•°Ò1´ƒùT¿1d;ú½ÉnZ”• çÞ¡Þpô|¯¦ÒÍé LblN½éðó‡5ÖÙx0¡Óµ6nž¯öXkÕ±¢†ZRÙN[%üßô×ëÖϱON‰Ð4üÿZ¥øM1ú´°â¿Àå} ó@*´–ÜgÖÝ­-è;0SËùQ›žFe0ò-èg¶å‘òDˆCcìœb‰‘J¥>jokÛ…y¦¢¼¶q))¡ŸÂÿãžI ]è‡Ï]ÿÇ?ô=Õ°ì„•PF7Pä㣺=_7Ó¶œ@}3…±J˜BxÇÚ]N¸Ò8Ô´T˜E å±8#”{°Âwçx¹@ ÿÉ*X¼Ã2ß|8û¥ÐƒpÇ»#,d£™Õ*¡;‚Õ›ˆ½7vˆWlí<_Q ¢{Ê! êKææâôË›ptË»°J¥ï¥«°¤+ èijt @~® Ü]³½Š«¹…]䃙M@ ¾ÀZÝ<,ÞRc?4Õ¹( ù«î68wS÷’k.ÚT§Ec¿wÆp´<TYê%Ê2ŸôÒÿ°…ÇXãñ6$ ãþ 1$ ”¹[Ô°Û*IÇÕÆwd~‡Õ†‚bõ“É"×ç'šMç€Å/þk¹Ë- ªÿóYö‰ñ<ç¦é /pêJáw”@}‰ž|„¼Í«Œòˆ®[u7§tÜž(ÊÝT'NζÎâor–‹}ÔjÞ#3?£‰­0¿é –§R)ÏWÅ­˜v:gÿmûlèúÂ<÷|#M°QòbÍ[ZF,ÉíÆ¯ ý—›Ûuý<ÀÍŒOš£èß®±¦ùTx=À 箊4§„ó°!~(Düeü®ßå šŠ^½Žâ\‹åÈþ?Ú¶¢›K9 gÛu"ovh²ÔF!œß¶²~g×ÝP¹õ"ÊôÐ DÀå«#À¼Ë#3¤Z£hiÈæ wÑ‚Coë{#›ÊÊûÍÞÚýÖ ZOê»@à½'gj¹° b`PíS@(8ö ­?fÊ=–ÎÿÛ;¶èówMm¾‘VŽÙ×V6³­Z›óŠy,ÆøêÕæßí2J©ms=0ÄÓš,“²¦:‰À@³ä¥Í»N¾>eK¿i;½¾…³8^«‚ȰxÎwŒoÈg!àW€Cœ¦éÂ."lnbPpNHáa0 ¢¥±Š`•C¹ö§éúÝyös@ýâlG3ùŸõÊõÂyW©{Wßß"!DÙÀ†€ÅP7SÖÇ6ƒ{Ңǟñ2ލßùË®u¢]îîíŸÏ„ ¨´PØyÓZ4îZ@&ÔFf\[‡¿ÉxÎ ²¾±]îz±×(ÍášÿùYÐ8öÙhÀh˜kÁ~¾¡§pmiM‡)Uk¡Z`Þm9›Å5‚¢^YD1–}åJ¸kÓ_a6ßÏ”Q£û¦Œ·i`½›Ã«Gú¢¥Z3çŠÛö%hÜú©dx…w‘EÞ·³q2›aÊf<^ï$ ^µ!ŽÅÈNg$¤$.rh!&;Û„ŸÐËCéݻըŠ|{›‡ äW™¿šIØ,ïWˆ+JÑ®ÀÕ¾i!²m¬/æaíìHÝÐmOý J+(Gþ®Ì$(“ÙtþÍÆ®Í“¶¨ÇCšJàå˵­tïIÝÄä{LvÇûìg~“‚+ÝDͶ·Ad³ÖëÑåöäôË<¯Ñ¬äùU[Tzøø\= !ôsÛ뀨í@·©aì3‡¦dç—îPNÑxZˆNÂ0*×Ûd–éÚ\Ki걯Þww€8Ï%¥Ý¯F"¦é †N$Ig‹L­ØÆƒ,Ȥ‹zU»nàŽÂþotCåW«LוÝâñ ¿u°'>þ+FlµºÐçQóVà €ïÏ †Ô’gç%Óe ºyIÕ“Be¿+CÚ²–Sü¿ý *{þge‘÷ûjQp¶àô/?IÔóÿ²ˆ ,×ïàÍÛ@êH4ry‘z}¥+OÚ0à—ÌXíÞ+âÐ ñ gJ ˆ¥|tœ›Ç§oþÈÍ´œ†^©ä´mYíீ9#xz#øä]XIF¡0´¦Ñ×„| Âb±)`6c®BLOýOÏw|¡Å;ÑFé9Ö2Ölv~uñ?$¿MÙÎî­Y¿²B%'œõWVFn€Þê—sÒ‘ê()nAd*Ì ’†w\e\`ñ^;×êW“¦:9¯I‚¢Wa³úo”*ù¢`0ÿrN‰¤Ö‡V‚G(‰×,—BûãÉFuC!°¨ç)Öx Ó’1írŽ Ö»À6ªâ>Xåc£|ì™P¨lÄLr¬þ¬ßEå§qY窉û1ZÄÿÃCÇsÅ}!BVõºè‰EÙ“èÒ9§föE½56Z»BùÍ““›ùKå~¬ý´fLÓaˆ»ž¶×¬©Áôx‰ÛÓ”Èb['r‚ÈZüÂ[= Pa6~8Œ§ÓÑ=æ ´UÏørÈ})Ô±í“ Ö«6£bú×ì¨ÑEh£•æú «\©°ÓÒ‘ZplE³ÔË—PØ©†ÑÖ|*îøÈF ÁÐB1ÑPø]á(7 endstream endobj 251 0 obj << /Length1 1468 /Length2 9240 /Length3 0 /Length 10218 /Filter /FlateDecode >> stream xÚwuT[}Ó-®Å]Ü (nÅÝ%@€ „à. ¥H‹»»·+ŽXñ"¥8´7íûÉ}ŸïÞûÇMV²N~3³÷Ì왳rX´õxdí 6 %(Î#ÀËÃÂ"á`(D=(ÁÀM¨@ þœ_蹈0âBáÃ=à_W€¾¯ øƒІA`@W„]êæ ;8Âÿ€ à qó´q{8‚ìÞP˜3ÀÆ÷R…Øòrä®60°ˆ !Ë‹@’uqüEòÀ@ ˜ÈŽ÷/Äl‚ÀÁ@¶À uƒAp ̇þ`À«Ç PÖ2TÔÕÔPÔÔè*êéëªÊë+*tU•Uôõ>úŽ`€Ôî „pDeö@[Ðh;O[8aD\z!hùƒáŽÿƒ`àâF Ùyº¹€mÿ¶…ìÀ¶.PO*¢f¸#  õÁ ®ˆþÀzxÚ8 ˆÄEÂa`Û?‘ Dç<@p€=†àCþÆ"AèþBüi¨$« äå°ÛrØ  /7B1QŽ?©y;‚  Ûßül\}Fä÷õ¿þU¥ÇŸ Pû¿F-…¿èž¯¿œ$ÁÿàåúS‚ø_Qv ‚U@ñ%‹ÐÄå/¹Ç¢ÿé%Ê@ú7?Þ?âÂa@[8Æç „x"D€#ZûÓ©ÌËŸ,DJ`˜ ‡0€àÿ˜!¿ €° ï¿Í,ˆh´Ø‚!ÄDÙ\ˆ‰D”ûÉ@¨‡ÆáÁáû3çª{(@ü_Ç¡ÿÓ„ô_u òòÿY'Ð qñØìqø4¡p„pöÿÏÝø?n¿íï?•<]\4®Îÿ†’wÂUTá@„Üÿ#è vñý¿ÄüÓÙô· vM(ÌèòOë¿d!ˆ@´ñú—ì¡öÙiƒá¶Ž{  b’ÿž@ì@00¤ õÿÝ~ñØ+jë yxž ü5£ÿý­€OAWEYO‰ë?Ò—ÓçùWNÿrÓ‚!ð¿w/þÿŽû»ÙýÖ"–Ñ`ÆÈ_áˆxÿç•Å?h!¶P;0Ä1†ˆuÂìþëà¿Ðää >AÁgA¡gˆ¶ˆ ÄÅøÿÊÖC(úw¾åýço{0¢“ ÈgijË©B|_óú¦8žÝ‹Vÿ{ÀF;UíõêÚ_ч—û¥­FQCÃHÊCcTµÒަM‚E<»k[ÍÃH?ñ#DwáÔʽ¸ÎïÞ3È»mR)Qˆ%߬kG…\óá·7Sì–*Å7,ʰÏx÷õo‹ncØ’¤Bt”ú½YÊ­¶ æ²Ô,aä:=t†ãã³w¹˜\[A¤÷mÀ±%B¬üñÓ<çHxUÃj mbì€Å›Îâ>¾I}¢Læåf>ìŒÄ ¤Õ(Ö‡¹JŒz»_çÎ Ë]Nmb\‡ýíá¡À_B͇÷€<Ì„©_ Ä%Ri“ Xì5Kƾ‹Qª>ê¦ÀøÏm.¸_ÑyQƒ(Ù‡ëË>ËlÙ+‡NùwPmwÇ&­ûðºQGŽùüˆ¡­©“.ÜN§ÆWïÏX‚àZ<ß¨ÒÆqÍâýPŽ’Š\«Ì:…)áûñâµà¼û;)åi§è¿¥1ņ‰vãT`vpUùÄå­Nav2Mý0{¤qÆ¢J~ýÒWŠsa¾‰Ÿr·‹àß{ª›„nÒŠþ.ØïÅ®øs¤ŒC âÜö¸³RiõÂ÷íDK<u4.AÖ¢ö¡u¥ ¬W'­6Ý1IÅ¡GC¿•Ö´\~ŒÎXžÓª6>ºm}ª6‘§•n‹ÿ½™Ì‚Ãv?åúÑ>|ðÑé9ß—eRXc š7€`„>q}öËtIPðªî[¤4›ç€¦ÐòDà† ñà°h”ðµ÷×›ö‰tYäh­5ØÌ‘çJ ÁGê@–›ci#Tj³¿á,-6ú­˜)Ò {d<œ6 ×~ÙVØœS,P'í0¹˜\Cæä-ê×½ÞVŘišÆÌ!3xB×þÅ ¬ßmýÈÊõãú¢ï×~ÓÖ˜]¯÷ƃÂlË©’XÈô¦Éã”'y/}!¦wLâT¥˜/>eb`z³„P0MmH‹Ûi¦ø eóËç™åÉ A,¥ðäÚ6UO£ sÜøfzÅ ’±ì¹‚½i°ö›îD,Þ[ñ[SÄC1×z•òQÕ….°ìHÈÒè”BÒõ¥Ó°YˆæΜÉoÝòLÙ~7Æ-Œ¢Þ>ªLúbèž,‘P8/9oÐME#G¢ÍÌæZ Ôå½¼Ù+]b 5šÕˆo¶ýä`1xŸæàá¤Ä½ .÷rlDõüø•/‰ñ Ã%­AŒú?‚é»pÉ´½}”±Ä&¥Kxû¤Ú’x˜žq®d;2€ƒ¹ŽE X~Yé\'lаÎçp»úÖ(¾{…U9%wÓõñþ(¶¬laCNDotSùžâýÐ=7ø('¸ƒwÞn–4×úèEëciHJ2ž„‘9ŽðÞ*??¥‚ŸÛíW»…«)ê¾½(íÝ>QÞÊ 1™Ö=Î[v„==_.“ÀÛûÃÔe´{o¶Ô˜ýzËÜeµf(G#Í×åtŠXîo¦ñÏ@b²ã&ñ–Ç.Y}QùÁÈ_ŸÂjr~Ò¤YEfZ.q]’TO‡³¢­ÎOhrL­¿Wå±:M‘fÏ5¹R´«lûójâ}œpp³— kàE¹ÄúØ«@üjÈ—éž\£|ÚU¶câ|:£HÃ<¸ÞÈgvÜ¥s‡ñt&ò‚õ¡—µ]IgBï&¯‹‹»JèÓlV4¶Uɨ3pcTò Žæp*:ñß/:1ÈUª¼oˆÓT¨åöÛˆfF¬-Ž‹«:9¢É?Ë;¨/øáƸÀõyîkÿÁ-­Ü8¤v8k]C»çëäÄ€uÃPAyþ¨8^ëYnîÉÍÐþ¡œSMH}oê{Š!™ÏÝIë*ÜñMzþ¯‘Ò7ÚüÃ#3.Ë»£¬l—>šoàèd©4ê;¢¦Ô¹/ðˆÞp¸·1&$ô%ʾ.¾àâ£Ï±¯Î ”L™÷’¹È êµdk)±PŠ_L¨ Xk02rÙµ<$áLˆ§Ñi\ýTëhT->Óµ½C¾)åÌĆNïߪ±¦±¦¬¿Ü÷òcD#ÆX/‹SÀq¬ÃG“¼¹Ôþ¼:„E…øx-%´˜·å9Ö«A“U‰DíÓ’HŸ qßèÁ3ºŽŠlhÓÃdýJø³û¢Ã“¼Ý:QÕÀ!Kt%t4<&ÂQ{XùVGíÔrÌðªÄ!?7^Ù“ß­És!‡GÐÛ!2²ÈŽÝÐ×ôF—ùé£M!k0ƒ¥Ëõ=Oi,’1lw*˜QnG9­¾’B²¬Ë jÝ·“èauûþyŠ›ˆ Ò=õôYT÷ØjIî†{i¯ñwxáMôm„btf²`Ðìiƒƒ"Ù·$ä²¹ ×`<Î%V¹d]ªåÜÄ`kï%#òoU˜NòéðÑ`¢Î,oí׳É^LJçãÔ£*…Gã ßÞ´Ùêæ,nn õ6lrz5Ñyàõ«=cü¿eIT¸srv¾P˜šæ |~fQºÂ"xIòÒ$Œ?õ…°% 7‘¶¤è>¸§õŒåò,Zþ×ø¤‹_@ïûàk”]Ù‚/÷¿>#±l°©€eªYœ- Áûºsý¹Ð¼a½^ Gtò6;Ï.ã'\ׇÚlencòþ-±—ÐÕ fÿ\x!#ñ'G0ù3²@®ˆ‘ï7P¡æ¾Iíä›Á¢BÈ\k{²#óÞÏ|ßø,ÛïE%ÆØS™oËW²ôëjdà œÏlæèNcßEÕÄþLöèÝkIpFüóßâ°JŒ=ôI¥ïÖ¿šÚ­RPO³mÖbûk^lkB#ž;a]ûE_‰îÀ:BÚó$ëw‚vàWVßYlÂôy2yà}â±ÈñÙX—^'­ÙLvß·é·’ò‡â£y9.ˆ¾²y¢Àƒ µÕénû9ÚÚ|òòùö÷ùcù’¤8BŽppJ(u´Ò×Z¿Ç}‚{„lôˆÀ8$rê8Ï€qŠ„Óßšxë¬(ù EÀ§kåÕ¤y â…ãM’Wµ1s4 mŒ9æ+W3Í–Xèu äÍS÷¸â¿Å¿ôcõd%)˜.=¬Äê­vó¤þ†>ŃÝܱÍí£Ñ…ã]ÍïbÔ’Y_o,» ç úJÈ ¥Ê»ØZVLi¨ØËêij¥~?(D’”âŽ{’p=îéôøhtÌ9´Ó0‘ìC®VbÑŒß6@=/ç÷Ų@¹þŒŸÖ‚ã9m"u1¬mW~Ž‹;C‘rmÓÍG ¥Ì"«•DC]¯ûhR¿téÐÄ84×|CâTM󗉶‰Dõõ›ÈTæ|Wš¤ô²êmëãÆG, d[MrjñÔ›¯ LøÌC*ZÝײ¢zE8ëŒöÕ$*xتk˜ïí®¯·Ü FIr“(èz¾‡Õ·Ñß6S¨;Ó;‡“Ò´¶ô 7uci3îÆKàX° OAž~)iå)¡žiY¸ß;FC­†ªË^š+‘º0½@ReV3ºv”å’ÖSìZ’žSsxd,åüpªÍ4ec˜ÍœÕç=J†~01ÿÁF—¸¦îör7_æÃRãø±6âTI×3qK;æöÌÇLœ5„¦pæŒLñ6ó†AKœD’-%ÃÞ=Iýõ&)ž–îÓZN¶VldrC¥=©Åx´â8Áuؼ.¶îdoJ&‘‰9œb²Ÿ0~Ü"íe÷;û S-ÿi:^qFÖÖóó.Z|Ø ëÉy‰‚bF×M°7ãµK%Y½îMü¢ÓÉžWŠZ7é l\‹?H,úMØZÇW6«ù½m´ŽOç×a1Úéu©4ã%#ç‡^žµ¶½I­'„£W­7…›/²ùŠZ.‘Ìýl‡ËpT|Ít<Œxå&‘<ˆQ–%W|jæ¤ÓÈIíšÌ$”-ÑÔiŸYê²Oxì!»T ð ðnN[½Gb·G³ Z™ßãBjõ>­áÉGÕÙ‰¯=.«\êÕ%Í«¢Qù‰ÄÙîv¹÷òè[‡Ã±Äÿº‡¯Ý¹¾±#ñªç I:—Ìõ³Ó Ðt$`Wä››µ ›‹šMúêW®ÓC¸Ãk3dáX1Gâ' ž²EŸÏC¨sÁû€Ìq=38ÂâèŒÜàÇê÷=¢–3û 7®J3Z@à +ÆRV€>3 Ã'üûþ¼ŸÖûÁ¬ãö±xN”/KÍ2õ%¾F„U¡æzÿÂS«Gc#â05<ä¸0 ¢„W0QîrÈ«Š¶MH¤@‹ Í&Æ>uÔ#‰4þ ùR´3ý¢Ã0Êqb¯É7–6¥›QßþÁ©²îo‡1˜3¬ò†Ý!G +8Œ¾×Þ&ÌЄ¬¢iúUOS¼ÇeF;êÒ¬¥mñĸ”Иk±q«£‰¹õCø½“q~Ãx¶{Ymˆôqà^V"!ŠqD—n}©<´Á/Ï?õ5JçtìAn¯ƒN†Ï¦<ë)WôÙ:º©Âš¡Ûiô¢#©r‘ fÓb6A?Vbr€ ©m(ûüv¸vËóDkV q sö·kë¬ØóOØÂIUèmp ¶„Aø.[c›UKzÄ4VÙI,ý˜ƒœnrj1*§"G_]ë$V¹g—óx/¹Æ_uèŒçÄTPýPö­Ïúñ\º òËð:޵™_~-5É`–>YŠÂÛ3ÀÏä¦{"}…TÑìsUã%¾ÞHç.Y»Ÿ”%ІT ëÑDbSˆ”¡»sVP‘ÉcD‚­²š*f\d'$?{dÄLòÙÐ’C\L%âõ]¹·Àe¦5eõÛ“ÊO[ Õ{­ñ㥑Œ•{¦¯ºìW·Ž W5 BáëCªNŠlØ”bŸ+r¾k¬¡žF9Ià;>k7xXf[þ¦èâRhž?=žØ ÝŠà Ú2Gb^z¾zJ„Ò~Rà Jz‡$öZ%ç¡ÞëÛøï*Qì•rº)̪@Ϭ= §\_ ¹ÑwÕé©Ó¦åsƒËœö)Y”oŽ_‡UÓô³¼¼ÎІAu-½‡zwŠšµ®#Kõ˜?%×/§‹hÌ1Ø=-2ëLÂär)ð°lùOŠG¢Ãöük'»ºTj÷êëyÂptVÕWLÀ;/ŠH3kÜlDÃ4 Ÿ¨]AÄr±Ü8,s1R왆»hdß(”%MCœóËá°Äú8¬f¥1òÞ‰*rF¸¼”m÷hÒoÖ>`7‰•&!Q›SæFÏÁüZ¦de´7™ ps*Q•²rÚGúm÷¹‚亶?Æ]ßû^&>(g‚ŸCÅÿó©¨Z%v^Ü-‹üu­˜ñåeVL•“göÙGc‚EóÈ¥èOœ¬ù²¢OŠ"mpªWNÇqP.fômÉʿŸ…v«“†± DýÐÊdûl<>U,†'ϲgÚ»°¿iÝEïö •e¥‘Ñ;—ÓÎ ×Æ÷5Ç*÷˜AfìOîÖên«9i¯ü }Ö &‚†Næê>?I­nЩ‘ÿDw¼Ø,è·ûaòê—`¡ç ÙêæØIÈ“깪Ýëá‹Þêz ÁRap¬`®|….Òº:ZýÚEÏ_áÉO>Uð$?«Vb½¢°Žw’”(Hƒ)ý»Áè¨ñòû'*ð¸ßÜÕ䶸èÉâlÞëÎ ÷BÚa¤Åd§™¼ÎÅö{<`¬ïéÔ6ÛÒ’Z$,iߤW•®ÑÝÅ8efq6&žgâgéu&ÛÀ¯ËæJ¸¹ØñÄÏÙ^éÃì©ð¾³ò‹ürÇníÅbÞÇRd5b¸±läD¢ðM•:LìN·ÒA¥=w9 ݧñù´FcÑéáö¦ž¾Œ"À1ìpñ]kæ÷‚–yà?ºY®>O(!@tÆ= Ö{¯Ô/)ÖïO9"cmÈø°^æ¼Q9tºÉòŒ~lˆH—ä½2Ï*˜Øc¯ÔøÜœ;za\0 D ø¢…zãs\îÝ|7=yõÜ[ß$§©6ýn«ñ3*²DP ‰Ú×_Ýjª¡µš¯ŸwûhEx½E ëT•-£v©G|©ÓC¹üåV „Æ¿ÿür€hñðõÓ2Tv tmì2Š|“²\puÜßñL9ýi¾ØýškôÈ•<-Ý7ï=©‹³wxÕX‹ŠüÞœÎYm† gÌÃìXù™Ø¾\¦ nqMB ýf¹–DC`ßký!‡®››!+Ë÷8„§šXF&uZ¶èØ¿…Ô–wÉ´¦;â•)fÆ4ÐÓ8÷|jòI~ØÖÎÞåVE6t??°<íUaÀy½·Ýá·ÞžÍY3¸©’ܺÞÓ·]®;­ÍµË‹ßvýʬÜ'ßÞ4é 5s®ÀRxNæy©¯¾¨þ¦Î'ÒÑžthÞGÞ¡sœ»û#ŠE;õ»VEXÔŽ¦<ÔDt-:›ç«Sä{5‰°ÀšßÚ)ÞäÇ•O‹…/ƒ7ä=±¨§½=ù—‹ð(TdHº¨>-"…±kö$…µ=5eµçÒÚâÜȾ¸°&Øo–US¢ÿ|?:Äpü|Iº|T¬çûa!øÅ˜›û¯#”PÈqíæùþÀ2Û‡ù<‘–ŸÙÜ5–ŽQJÒášk¬X‡ÜLDôÏWs\ ¡³I¦EÁ…£=™Û=ú@fB”1¹+¼ î»4,V—+å¤y:bQS«Ø›³ÊÑ{hâžÇ”øÑ< ’ÉJ‹¦?‡Z”¯Ð¼ )Âmîú¹ 2Zt\$1,sP­ONüBÀÕ:Ò¼o àÙ©~žWÒ&9cü‰›–8p¯·sõaîÌü½Y¾§3«D2ýÑ:Ée¿äÐg[¨å¿iÝRÌ…^©r½¤Ig^ÏYk†}›´hb2Èa`){ Ç'rË/ž”{7KL´.çÎ&y‘Hø`¢åƪ F'Ñá«QâËFî8§…ÕhÚB`²eyíµ×Ò³â°Ü:…-¦Jº¡< ¢"¹Óñ6Ÿµž‚ôf÷¯ ”Ú@åš7—EBÜÓ¿'0SLUüÆ 3 ÓÚM°äú£WEÒ"føõ>4wÍy_”a{"2©;¥Zh²ÒUÙYŸ@šfQ†«6èhê›¼Ò M$$ ò¸›Í”xN³DIU’º¯UO…浓sê“Ôf©âóÐ_˜›\B5/f¢ñC¥rb'¹,Þ .!Ë¢Œ$q«®GpÜ1:‰¬ÛtûÍ’¤FA¯eª`¤ø’;"Ù 6WÛܸºá»+©˜Øo1lU³fÝ3Ð4Ý™T;VIÍÿ·ÖgOxyr40!‡ác ‚ÄuŸæXûILgÿ6ZË,ƒOšä=êË«ù“wÙ–¯¢„f&ããóÀPu´òzЍ"nª‡àžléÄÒwÚ¸Ø%‹ìýhhx儊ìj˜x Ãr(R TÕÉôd5íñ‡@v¯@ßæzÁYþ[pn`‹XrÊ˜Õ G‘ý`!Î-~?ŽíÛ$o·‹à„ßžaô¹²ÅiJÒÌÀU*~]E˜©JåÏVs´²óiSPYeQåaÊwç-8wW»·œgb!ó/óEú½( Ì™»È›?,'ö=‘:ØÑª¤s‰}£I‚ÏZ¥ûÔ‹ßZ)él.ßÇKO\ô7¿ wk û(E/沄ãŒsbt7YüÒlÿjP…ì€VÁóßDÎF£›Ð Î38±I°"ö,f~ÄL}²Þk¢{ ”†ÙpÚƒíC–B ô¥€®c¥šA¥¤uN|Ÿµ h!N K=`Û#ïz²ŽpJ¾³lG›‚Ñ¥ÄíÁShJ€8£úübVõ«Á8ûJƒºÛ䕸×Ä aµ?(~œ|c¹e"áäô`ŽëÎòõR<%ÚÜsâo›±ç"©:¥ahåX/ 9}†&Ÿ&Ó‰}G̓æ¤Xì&âÄ^wüîµ¹½à•Y1WÞªLV1‡Më¤ ÝËï,é¿ÍQÌ`tV‡È;õ:ǪâÏv©)Ï£iå‚iž=l•M%‹eÙ†¹ß½¾%­èØœ˜O.*> u¢O`k¹]t_õ¶P}+dÉÃf[f-8Æ&ÐΫ Cïñ ܹt U' ¾ý‚Ê%É|]߃Öfj^x±)ÇŸêäÀDkÊÖ‡*YÜÍÜÜFIm¢\S!êˆ)ŒÈ92µö÷|è1ßÌš½ŠëÁmÏ~OñB3XIxï)Û$ñ縗:ä×Ìnþ$k-MÔ¡{BU¬¶§¯âàßµ¥³ºÖy?J*ç5#5·ŸÓa~€o1¯ýþd°5¡BˆÂ”É}bÓùër¿Æ“‰­^AÝac ã}Á¼=»ÔÛš®™®„ièÞò2Ä.ü}€^œ^ÚÛÏÐÚ mJ7áºÌÊ ¥oé)Âi:h<,¯8(¬UH, ¬8‚g¥ô7pIIWãÔ@æ„Ìú¬æ—RKtˆ5Ó÷¯ËXHm]nR|ÊçûNÒƒ›ª‹H­)íÕ»B™N‡ÆçÐg[Œþt$ñ#û{‡‘øó@ÂÅÄÅ€•‚7;ý 1Åò¯0\%ð54ƒ …ß ¤tö fÜÅRN%KPwxïFf íòÕpÏPçùMå’)º÷Ú¬Ý\º†Ñ7©Ñž¦ ²qeâ5ÄâsDÎѸêϹeDì*-§ª‡ù#׆òp1ôB‘2}M .ír£ ¶´2v–ã•«Þ(Ù»Í1»úЦ©NcŠg›ÉLðß3t›^îy.ˆê¹GYH+ûqQ‡xßnç>~¾¾hØ0É^LXcx™J·œ¹úrxCô§½¦Ý–<æHTð®ÕBU=UŸ{ׯ’ÍjÇHÿ¤µ½;¡óé¨ ×»ƒ!þQ;OHQ„JŒ™­ôYÚÞ5tvº;uò2’ÐÚ Ÿ ×W5f¸&¡Bk‘­Ëy 3…­ÉÇ|‡òᬠ’Só(z©¨ø H{²îÉ&çÎáO…ç^Þiؤ‹2½º‘Ä6dŒÿ¹É_?§ãÕü"$è÷Fº6ãñÍÊ(®M(–ý÷ûç8´5_φö•Ô¹’ ÍZž¯-o¥”šG·&Ë´+~'3ñ©qò¦KÆ%VÙÛ/¼díñt¼Œ.½rV¢'ýÞõ–ž›Ø:½â›è~¸ûä£es^ãõ.º|)‡”bÎyV8²´a›pÏœÓNûá=^ãÐo5·©ß»ù ±› Ã)¡ÀQ»ÝLÁ…=üã^~¯ð¸&žŽ@’|uM{•"–/¯™ üÛ) Ç «¢j€‡DÉÎ,^2éåËH¦†[4Љá­@ìÑÓñã˜;9RJ<­õ,â¹î—Ýæo›u䋆p¯Ò|ãå»lÓ­ %¶U+o;N—¸ ÃÂÞæTö³:|<6¼KˆF_É©÷hã§`¶u-t{hÚCŠqüÆæjò-üê>$mÁZbÃ@ ’Ñ6[ÕAžºy —ÞÁÄŠK{ôé¶C<Íõ\8£s.¢pJ2nÑ=0c÷„ú3YU­PjÙ—õG_c–"g[¥8߃nÛtÚ‚½Ã"@ðÛÊ#¥¸¤•Îw-š0³]ÉRÛü@õ  ñyó‘BðžÁFa©î—bæ²Cv·;WVßC~:ð•ãd䙿0»bÐMJ̱VÉJÙ…¢_†Ú'xúÂBÝõv{M¤ÙÆÏ¢g—´I:I´tžmQuØùŸi®üJ±:ÂjŽCu‘Å#K['ºžVad£íŸ=ûåwýË“r`ŸÎyâ³µdÛ«(•Æê!t~âN²"¡H =Ý„“X‹º’ëa{Y¹…óÌ´G*ÊæÅõŽ”t>nbà”ˆ¥­7nÖÒï`?t±‚¿†ëÅS9…â?–$Kc?ú(µ#Æ@½´£S¼=+׌éãªWUŒiW– ?8ê±ÅSçðÖVíl‘|M;bˆoŽ èNõ²-ã´*µxZy³òY+¬÷å]‘Ö"žÁO¡Ü¯¬±¥©B† £vÛZeƒ*·èeÄÊ)½K1G¸"ÚèŽW‡£x“îüPYŸiìBò9î¸{¾_ó^Wçéq'q…ð ž4.¦Þ¬T&Ó¬îh©_ÇÁJb©•o¾þ ž¯BüOö9h%H—ù0ø®æc½"Œû˜Y0qSh$²gÄü 42YH…IôI`nž7)ö³½H_ñ®ë“vwà5Сâs̑ƞkÉ]÷íÙŽ>5)J8Ï­U"Bsí®ßÜS³ÈäbLÎo*°äŒG‡ô5Y«cyMs˜>÷îI‘þm¥4A.8?‚÷5ó •Åö2=Ûª endstream endobj 253 0 obj << /Length1 1888 /Length2 21322 /Length3 0 /Length 22470 /Filter /FlateDecode >> stream xÚ´xstœûÚv’ÆNš4iÐLlÛ¶mgb;m6¶m7¶­Æ¶F_ºÏ{Þ³÷Yï¿ßš5óÌuóznüfÍCŒ/§HÍodc±±v¤¦§¡ãHI+ê[;ÐÓQ ØXhèè˜`‰‰íúŽf6ÖBúŽ@«£)@ÖÐñÃÏÀ@GÇK Zí?”F7€4ÐQ_ÉÍH Óÿ ÈÙ88Rè;|¨Ö&fÖ@òA[7{3SÇ?1©©ÿDúã-@Ð7´°qq°0è[$h¤i26.B3™5Àhªoi °1(ÕÊŠÂ ŠQYe9EršÀŠN¶¶6öÿÃEPQIY” Ä/£$ ªPD••þ|*­?ø›Pd”>ôò|þq—VâWR—¦§ýsz€3ÐÞÁìOÚÿâFòÁ ðj®Æö6V%™::ÚrÐÒº¸¸Ð˜898ÒØØ›ÐØZþÅOÉÔÌàbcoø¸Ú-ÆÉÚè£œŽ¦ÀøÓ€”™!ÐÚøÇIÄæ_J«R~8}Èÿ—ØG!ÿÄ´ü—9ÀüGS}‡¿|¥ää¤VúfÖŽ@k}kÃCG}G'€Þ_²7Јô_A'{û?9¤ÿ­²ÿß4ÿ¦.`óqgZ–îžú.ÿÝ1}k'‡ï«Í?oÛÐÆÚÁÌÁÑá_c3Kàözffý—Lš_F\DXQ‰Zêc𬩥m>ªcMãèêø—õŸxüBR6:=;€îcH…­m¬¬>X;Àþ)ŸÙGmìÝhÿ9ÔÖ6.Öîÿ%46³62þSs#'[Zek3;' ¸Ðÿ˜~ˆ`ÿ#3:è@;ÐÕДöO¢¿æä˜þø£žî¶6¶c}K §™1ðãëî ï 8Ú;=Ýÿ®ø'‚¥g™:~ŒøÇšÀþ]ÜÚØÀþ/ñ“«þ§ùd­(ùÇ~ÙX[ºŒ€Æ°´26Ž£@öÿgÃþ+—ˆ“¥¥Œ¾ìõüo#}+3K·˜ý—…*ðQ²ÿÃ×ÌAÄÌh$gæhhú¯šþK.î¨ÿ1ðüÖ&–À~ü%Rþ³C–Ãúqà˜ý9¯ÔôL,ÿ¥û˜CC k ƒ€ñ/ð£ÿE÷£ìÈhUd54(ÿ9+Ù[Ú™Y›˜Yúööún°tÀÀÌ p§ÿ˜b# ë_ ¥±¶qüpØ:9zŒmìaÿt‘…@ËÿGôbgÐêÿ±h þƒØ´†ÿ‹˜?t†6–·öo =€Öèo@ üdКþ ~ä5ûügù7ø‘Ëê?þ#òßÑD¶ùdÐÚþ ~$²ÿüHäð7È uüüHäòÈðÙí/øÏFÈý9}þZ/ºÿtæŽå¿°¢£½PÕÌèã'éo&ÒúŽöf®št»Aÿ!ÿxýû›ö?ÿg­ÿæ- `ãêNÍÄB føè =+ ýcF&Ïøþë„ük/?FèßøÏñ]†°K 6†œæIA%^ÂyS¥Äì4§å_xÔ$bÁ—R§Ú°1…²· €¼ù¾Í>i$ù6RbÚ^ ¾Ö…jÄè–oë?ã+&oäùvô½¤½°…ùG³Th”ýÒ¤}J;È$²rÕ‹˜fÒZb[¾”GÙÛ:Ÿ"&ÞQ® ´J[Vs \ æè›Ðì-Q]‘±Ú±§ÚAߟТ#ô{ø—(fõrƒ¾ŒJ@Úvw~Þ(àýM\7³ýÕ¶ûÂbŽ¿+³øäˆqæ  qÁQJ%¯0¡N‡ÌYy$™kÒ+û>$cžû·TǦÉÖTK˜ƒsÉôeâÄhÓz²ñw5h~‰ç’ŸˆNZÞ2Ö•K¦Ò#žÕc$a5±2ŽHBwlW‡üÀ,°Ð@à'Þç¶à~;ÞÝgV6#69+¸F ®æ-X×DÍ@rZïáÐáNÊ Ñf»€Ýbä÷hgÿ|'ó’þƒÈs’ݯބz*oÇÉ$w2hbØB6¸Þ¦(x¿#cYËð¢bÔ8“;«´ ÉÕÇúø§æ„m«‘ß^»–ó\-uØa:ÎöÃç•EMyÂUÍ!\Š›OúiÑð(/¿}üÓ —pö+äôyP[²QÔŒè˜UnNîš‚>ÉペÛ#Ã-ÁÕ›bvЄå((üÉÔ\~ë:e}X6•x “…Â7‹œ7ݪ›JäïRÛ ´f®ÝqE…U9CÃ0pÑÒh;lÕ´ÀDûvÄpÌw›£‹ò&‡ e'%¢—xøš2/…Õä"¡‚%ÇÝeiþòfA?CÌÆƒ¬ô:På ¢õ¸†b h¢”@pðÕ=ìòHöç|¤õ3!½§DT´ÍUg‚[ͬ2ý#I0ù$8c8cèñËë"w³Úw ¾O×}IµËwŽÃÌ?6£îŒ´%—ý—í¸9ûKà'ÜT©û`«]·ÉnBô¯ûñ´î Òû°Þ]@@ð†Øx5©µmÚ¾ý€Y*Ì ¯KϦ¨U§iýTˆ´â¦Áù:fâš°8þbâ}Óoˆ©bp¾ýù4ÈÏc ns±©]Èð¡@`¸ˆ•‹ƒ¯CÔüÙÔ_í*¡}ü¤Ì΀ê0T’ß2’èýVG]®k®ßl”ì~`Õ™2tt‡í«buLFn$µu©z;2eé[U ¶X5 ·½4$e9aO™ð®™ïŸ…µ¬þãRv‚¾êÆÓyôSz)LJq¢ÐM&/mÕ cV¬Þ09Þµ½·š4ɽ^Ý÷bb7–”Ú¼‹2×ÂÞ öæ©ÖH9´d]“ìa¨Æ±ú‚ï]% D¾Ø TA;ÆFt»o½é¢B†>–û¤ q WEˆsoq—·ÙÂûXK²ãV¬ ">’×8Z**Ÿó9ãŠ!OhcÊàv…ÁÙ7+ëÙ2úNGuU&ÆŸÖ"t5?ÙÔE4­—6‰?‚½¨-ì¤"{M„ñtxév/;h]fvЏN–MÎ>wú«Î­BölÐX²Q=*á=l –z¹c’9UaN¿‚Œ8w×!'Ûå–p–y0GXÑGÙ‚1io\–Gè$u§oî¤ rRiè ð)ÂÊšL¾}’Ã4{Y´UѰSÊçVs'åc&ðkExö $…oîšk”0IÊLÚâÊ.-ûjÆ'dér ±˜´$Düä °|Íy3ºš3žLôuGy…‹=Á&+Vº…Ê?~ˆZuA‰ÌJ‹Š:Êœ¨Nc´%aù6þNëu¾ÖNšÏ3I¤Ù+_Fíè~*Øc#' °ßÙg¬o JF†Fé SH) àk_ÀžÇTCàõ::xt IàÐ[?MÐkæ!£žSª¼ó—?éí'M2A£þLkp‚o‹+÷i(pÏåÆcÓb#÷fM8¸zÒŒ`Ø|aqª‚ö¶ÈÊ «"Éö³ßò,YW¨yÏ)æ-U½hRЗ­_Ü™ø1‘IMXqÑ . ž£ }#ñ7 ÝXøM²÷þW:¥òRŽ£d<ùååAp*ŽÆDˆêQôõ­E|#s¶‹-¿œ¡?[í àì×$pÄ @‹öóRרèà ëåwé¯1É ,^ßkýZ1uצ|9„Ÿb`.ÑYk”ÜA<íÐŒÉKý÷Ʀ|óe•ÓÙ áë‹FÍû¬9£ƒeAvQ‘a{ÚëÔ°¨"L¤îL”ˆÂR–ˆ› à§ôàã\OCq{F²ÚWÎnÈx»©éÁR†&ªtµ/L¡ÝpÝGL!«=hîI_ƒ•ãc °Õ¡6®2¥¸Ü öcØLÊD¡ZI¿dç(ãO¶Ý´6´›p®BU=[GÁnS5ßÍùGêTÕõµÔú ®ˆÏ‰Íp#òe@lšÚÞŠGßð FÖzº1f¬Ý+†ýp$j-Ð)×Ê9 ‚„§.š¯küzðO–“¡(S“µ¦tÞRÓýtŸ‹q"Õ‡v‘sÖTQÜ6‘Dö~Œ –MÒœΩ'1øCØ Ç]‹ a‹§SPùá_g¡Å}ZµþºëùŽEæ™'Ó.Ñï­ÜN4™¿h1}°¨‘<i×:â8+P$Mi%˜ÉsµÌNosçþ=ïw£jù…Ê»8aut‘ÔPƒhéõé-×r˜a&Nx>×ÿWîàH!<Ç—Ì'°[JšpVoÝúøíð9-Ö7¶¢*Ÿ#¦^£”hÇ:Zê=A‘:#¶ŸÒ`w&2pc<<ªDBì2"l¦ÿmÝDçÅ rmå]ϯÛÕöAWÔíà% § bž±løk—¨Êrg°ï~žëw“½HHWíV•ÈÃøõ¡Vàûرœ–ü^HoÛ"rÉ8RÄKÏZÐSÀRšó‚-„$NpÓWÙ€Cv¹& ,ˆúUˆÇô˜w­Ì‡peØä.sÌÙUÓ-fúci%¾AYzDQØÞÆbx6õOõüp±©È“dKµjT÷½Á {Vèu%øŒ™äÑu5'é¬ÖÁu"c`È«›:ô•€9n­¢Ì nqdzZèàÕKÛðÔÉ7UE$Qk…Ùð§–ÔÙ‘~NÕðŠ+E±ÉÓý]–=1Uôà_šß°[£~é?/éŒö¡Á;púÕeæ9çÛ¬I%©Q küŒ çtûŒÝ*pþSë˸ŷxغ#ìµ’¥0Öíå¯8ƒÍÆ ˜Ì­¨"c×l7ñíö¤i½Õ3‘½.^]ÃoñýÍI¢Íº¸È^Þ{o\ûCuÕåˆN•A"®’j›ë¡{{ùl-0¢–r2BÝå¯t;eËeÕþ÷—µÖaÈ7º1zh2¾äþ]¸ÔãÙ 3fjL!êfˆ±áx‚·MM©Cžx+êÅlJÆåIw·,¸¥Æ¦æ¡;}Ý;þ×w ë"¥=MQ_\7²rÎ^C&Ý ¤¼*{zq­T÷qÖ¯?H$ól¬>â6:V‘´3†>–_­î,¡_¾SømýÅ8kŸ8±…âo#k@ÛC¢ò[ó½–îW•y§á`3D[EGØ_T«éiàN·>øD>ÍTHÇjbV„ï@Qrãá§ì’ô²bÏ5S=®«žÂ¼¾,lÀ‘ v5L©k–'Û–¯!¾]Kþ`5_ò HhžG ¿@&ÀeÕq–¢ë5îÀþŠlÕz¸jó¢éŠÅ•º¤ Xé!€$I8éa üt}Í‘»ÕoÑqý£øpÿ;ƒ€&à ˜Ö€±–°ù=ŸZþ§1Ãeûuε PÍS#Èþ@6Í•£æ­tÓnj¼DÙCŽÖQn \"ˆrqTuŒ¢Ô GÈ7« G*XÂvøÁi¥|¬â$jïzÐXRÄŸœ/ødt@Qíökb©kPn‹ÆÆn±Ce'É!d U#8J}ˆÚ™áÄûÒr \t vá»Ð°ßt4XƒvØ_ÙS`aÑÒཽ5?ŠÛC̵«¥­ÚÞ—ï€È/,À¦ `†Bš”’dÛƒ=á:7Û`aöM É]§_ø³û¦æn³ÀúÙžCЉeånlC³Hê6n 6âÂ&0µöJq|hÇß‚Ñ$,z±8ºsmÔû¬±)–ö·åÄbV?M¸e“Þ5½n¼Š sBñØÊûüÜ,õ‹åÅœ½M[„ÍŒé6ÅHÑî÷Ÿ¨r£kºÚ•ËY¨#!DÆvîÔ€·pÓ_0#“æ¾–÷ô¡6tø×D—Í’(ÕNŒÆ| }eõJlîªáÕÕ—ˆ $ô§LÍ„œ^)üô|’GI˜*µÑ@EPQ¿B7û¹Ý××gð<ä3‰aN¼2A«‘ð“¾-3lƒWDÛïL9ðÚ×lÇ‘¬,ª}¨°ô:ËÍ;}‘•° o"›DBžÇ5‡Z]ݱ“$¦†«\æçù‡¨)xJà4‹ºÜ:©“À†9ƒÙ¬×£é|"Tm æñÉ@ûÞ¹íKB¸»‰í­$òw¯Ñv…À–CæÕò6.úó]> )¤ $Ñx邟h›BŠâîNœRŸ.¡DM3¢äó2ÓöŸ“/ü+Kƒ³.½ôY…¾ &¢çøÈgwu£i`@¾iXäÄÛ§Ì7²”ÔnPM6G®Îæ§ú‡XÕêAêp X¿û@ •'ÅâáôûJ¹Øböì=žÞ¦Œ\wƒFí#Fß8µ5qç\syɹ÷^Žä•ÑH˯ñä‹®Ú73p¢7F§ñ̵2Éœ[ôþøþŽR9`w,§¸Uß –}ªQ ‘U~¦F¾¼Â.³Üs¢›n³ò¼Õ¨ê̘ĭƒ!é#ñ 7Ä£ ÊÁ®°ÝÈ‘VH¢ü,%ø&šÉã]eM ¥ãÔÞrÛñ´û Öðxm‘ ÏÇ2 Õð”?mןî6tzç6Š ÞËñ¬±¿ëfÔ†ˆññ¤­&Á @Cì¹þÏÌߌҦţíû'«°3%uT»ònŸx½âUv†š MŽ(OÛ¹ nÑp. ØVs* îÞï/£s×´µÏ÷Õó¾r-ãö|èÙDº.Úéý±&o6åd¶WV PÉ©ˆRr¡èg¨Î /P¹æÁ”oµ²²ª¹þ\;:?öbK™\e¢eúbÒªÁí<5=7pN´ï1# ¨Þ¦|{îøK˜^ï¨&ªÄ,ÎöjÁµí î}Èì— ”­&Î[Xr~5(ƒÕ„i}†9L4íªâ×M˜T£ê ia£Ð‰'ª1ê=pù†t.NÅ—d,7ÑÊÚÃ5 ^s¡îÞóEáM Ò·y³¬ªYÅ÷¦Tȉw£Í‰Þ¥Ð4=߈.55s/„Ê' ë†7¿Ó¢”® ¶¾±7þ|ÔƒuËKï0›i¼‰9Fgê3ÕQs”«õ´‘ïîC¦£\Q醩/7[ˆ:«B:E“¸¯“AlƒÓ…ËøJr»Þšß^‚æE9xÄïo˜x$}¯'9±¼‚öÜ¢äAcØ¢ HÎP<‘ÐèÑ€V«Aèœ$Ey?~—0^¨§Ms¦}ŒÑ,Å6p¶¿S¦ö|[Gð6¡u=BÖËþuâ6¼|U¹º@˜îâòž´B1àám0äÍ[qõ)ˆ·Ð“sq“—?B¨8¡Ïõ—á[½éË÷ܵÛHÒÅX£ÊÅö+‡ÆË{랈楊ðßfÛ».I­ž¸ñý+ 6Ý1ðÈò94ÙU†sÚ>7ÝéfñŒÂeî˸ý¼Æ”<8¸ÄÙ&äMíòØ•bþ‚Ä­Ó, °’*høÇšŸ>C%¸Ð 7‚Œ²kd#õ?ª¤$¦CúòÙòQ=ØßVƇd†ñŒ3zà O”ËV£V…é*É–Q$`ÜZœûÀŠ JBiÓUs÷ýÄÅÁc}êÂìEôÖò·Ò¦d¾SÃÔ5Ë·Ò'Çf«ÐÌzŸå$ò–g9_»WÆq‚ß. ïùÅÉÛø”£(ŠÂsŒg„Õ?‹ø%³ÍÚ~OG‚FÇoúmuŠ}å^ƒéD¨·Åµ†Qó‚JiÞH”o¨-iBìãžWXW™ÄÖR±ç9CÏ—gˆ3½å5mUwû›bö#mìGg…Üžî“;ì8Ñ/¸Û˜£$[lããþÖ$K3ÙNËRÑWº¹J¶:n7³š:Þ;5 ÇÑ‹ Òßel DÀóÍLÔ>1r|± ;r7vs©bäB¹X퉨½–ô-[1ìun†SÏ¥°HÜtuæ›À$’üúa¿ˆërŸ&®mçpH%Ým#Ôä ÈâˬÍÙ£²¯AY&î^áÉX¥'rLËãÇûCS]£Uß:C¸g–åé XDd2åâüÆQ è+V´jTÍì%I÷¿ qžg'ø&WÂnn*.‹³¨µEw‚K‹¡z3´Ï t|1Þg›äümE„ÚÙàÊ]×u¿€ÈÔ¡. üe®OÐôu—¶O[n½åœèúx¨Wªíó©ÖÂe~?³m¤ÄCv„=Q& RtÖALY‘½ø‚ um ‹Ð9 V?QÉöaãûó1ÁšÊ‘£‘_}O‡øø¼¥9ãV-O» —uø±×É6ÿÁàò7~^ºŒ6# @U´n]ÿÀ-A› m5G#F^5UW‘Š'ÇÒÒJϦlî\ÍVåôã^÷º–â¬A•ìÈÎD.Ê.–ë-ÞÔ]“Í òËýò2;œÿµ3§etǬÐ(ݲ¡q(^kOÁˆgOóµ_•º~"[ ÏX¼]#TÄûbÕ”‡%Nïbñ^h_~?% WPòMˆ n<ê t®@­¼ѸãL!„uZhˆòÎã%ƒkÀì Èwôäbç3ÌFÅI€ *Á“ÒltûNÛLn6ŒÅLCZ»1*–¿“—ÆÂV¯oþ_Ý;Â7¸,„F˜$’÷ú«Ç«@¤×·¨Ó&k~—IìdSVC}±+Ÿèy ô8®2Øhîñ1N»cÇ †_t“0Ciø_§R¹l\1¨îVw6ñð+ôpáÊrì`¾Ü®&¥ðèeeÉÄ?/X{|S© “ï!Ÿ…ùÂn¢û’Ž,A…¿ŠÄÙ\׺2°˜Ñ‹lÞ2LÌå…d‰w”(^gOÊe£MòuA¹W‘÷Êc°ØýªùâדvÁ‡OujN™/z3±¯A|úYÎHŽÙãhãÎgPü`¾åœ°Âʼ֖XQSÛ/ax®u±‚{d˜ˆ?}øñ\J\û–‰sÆN+äÒ¡<Ô|ôµb q”~ÍØí“£ !òG•Ê5WYYWĈvIªxÞ€Dx€œib¬3gäû"®)ƒ:Œ‹Bf`"å¾F6Ö~GÒÀZ®ùUTÄ~µqä¢Û’#®¡Jú•ÊŽ‘òY˜Ü@g™›kw×_Ø1™çSù½ ­ÛJ@l펱rO­–·5ç^ѺŸ:tÞÖ)ÉžÍ0Ð@$‘™|p»°'¨ £ÌkÑVómÀ ¡¤°±®¹Ñ”`èH‚ΔLì³RòÄÐþ“¬Ý–GËD|(ÍŒ±8XÝ®€ÕUm“-à¥'Ú&ý¼›-—¢@ÓL»Ÿü«¹Û•ú$\˧ã]PåÆºþjÝZ6Gš'°:͉L€¾E„ æ·sK_m•ìÝsTk«I›b_>% ·Oê®ÒÚ<Éf~³áîѶî1ÝëÛ—jÑMÇ+Ý6TOBTm ɘ†º÷[ZU¤¢…•-{"Ø\}½pTÌ•ã|aû­€¤×†Ê¬Åf?CëòyÖ·e9o Ÿ°ØÈº´*¹—:M<3à\ôÍtä 9ÙU7Oo%a ÏMø¥÷r.ßø,8˜‹Õ>ïT¾¦øË—‰ÓÌ73­6§õÔ]Õ 8å퇰¨,Y+\«| Ùó¼”ÌÅ|÷ä ]S4Û 's;("ÖÑfÚQd>³8ª}þÒpâÎ )U¾ª¬ý˜Ãt¥Æ‰*CÝÅÂëoç|^R¶FKÓe³šßm±¹¥GŸŒµ¤AºA~È1 Ÿç-&Á¬ kÉœö‡õÙ9‘ží"ÅõrzÍÿ¶hLù®B¡ŒIxéã6ª ¿=QEx¼–Õª¼äd)£az·a÷¢—…R¥¤p°òK1 æëÑþ’++³…$ù\õ½GX …wZ¯/XçÔn°ÝÜ 2ÜékšNSúýæÌëñ«ØV¢,¤™ܤõ£õ'„×u¯H)bÿ¤q«"Q%­ýæ• †ü"SšBHá3p1[hý+âŠn#¡{^“K± F"™‰[>ݧV‡.Ÿ–€b©´>|ùcý;¶@¯s#”ŸÕy 1ärâ•= 0›™'!äÃ’Âè?èa&¹h(XMWG´²,úÂ$½·øØ¤ä?µˆbÎGïQ’X<#|* )XŽ{+CÇÀ¨KîqbÀ‚Bf[ÝÒѦÐÜ9‡+c¿(ÂBXÝ?Ð Á5µñ'÷.MUa.™W=9f « K’”'Ï·ýn.Ëx¢PÁñ q‹¦Ø÷¹ n•yŸÃ†Á·»ê&&©’.4åR¡6âþSTÝŠØQ;î /Ϫn³hÖðo"?ó²c¬üç1',OÃL†~³Ó+Të!#ºgÏó ©ŽÝUBC+ÿÇocd+Ê©4ⶆ”³7£ 4ÚNeއt?Ò/2Ÿ´úŹÓÄûàjMH*LðŒ‰éE4Œ<ÉŽøâ@½¤´tÁ¶Ç@2ZìÕ.G;»¸†Ü§ 8À<¾¤þ¸îVü ÌÖœ o:²AœKînጓTäâ1±ÝØ’ŸÆä˜´n®‹~^{š_x”ö:Š#µ\SÈÙeó«Z-/þ{Vô@Êœ:”…ÝÓñ[Óˆ ‚8ŒsÁ™ÄJk¶f{J¥Ò¶úIVï>¢†³W‰K5][C$7¿µÎ'–¥þ8ƦR‘›¼ç4?ºûùôCÆH…Òl ¾öÝÇÈ)Ê´8áe¯“@ÜêPíªTbá×AÉC’-×àW 1JàñÚ^ÓakFÙEŧvºúÜ3]{hnkª?.¨iqsê]¥0‰ØÆJ]•™o©4·mÏpzõTäVBW‚ßpzýº›Úœà00õ÷W¯Œ·LhŽ~ÒÇ ST³xf;¶w2¹zÐdiƒ{T­Aû¥8ußÍäbˆïvˆ”RYÍgI5Èãµìô…cƒ '‹§Þhò”šŠ&oËŠŸ‹†È;S·Í¯”ñÅbc²+ƒGú„¢ÿjQ ŒqÕbaEævuàÌmŸ‚4:%Œ(¹¦|c¢ãžÙ‡1²PÇXߥÛt»5 5õ´•ÍãG\4$¢ øtM"猊¢HçÈ7µÝ·‹s“Séfð›½mÝmf±õÇÀ•Û¢ò˜bY–Š))¥ŒäØÓ®!Ÿ²Âs_ñ{%‚º÷äo‚`STÆj¡fØqW±·(úyQç§÷:<æTºuc¨ÂS*` ¨˜wOc€ 4+\:ÆI«Êbš°êàWªqüb¶]©­²Çhê^\,§S46ÌÛÅdQÍiyD ÔYYÑßÝ,dÆ LDiÃŽÇ•‰äÕ¤·'JÎ=×êû‡Uý½ìßx~Rs]˶ Ô\Ý9Íÿ|ý«-B}V ô Q—gðÜÈ7Ÿ«GcÁÚ8Ž7p9Ð?G„¯öªHõcõ•³cZ$ó”,×D–àMýd*”ßõ0²’anØšJ{GKáóuÅfEØ_@ŽÃï}†íQS(kï@®ýªmûÂÜiŸùûR¨"òà÷À$¨Ô+uÑˇ¯§ôîÊrvr‹ÑLœZj—I7k‚¬—JQ‚4#™QGâ—囑£´1¤«\»2?AÆ#Ü£]Ëd°#>™b™D=H5wrëZ°¿Ô¼Öü,+ZBy|Î%ov’ú–œ@æ5’q-Þƒø• œ0g®©Öm'^*R[~[¹HÝ4NÑÆ´)›œ4µWb2»¦!ïúÚéžÆ<1ZJußôF]bö*XoÝ!:5›"è‚pþ:G±©³¨ã¦f<˜è¶B”!ž u“±ZGÙëÀ8l_?'âG™+g߯¼‚´Ü뀑£ æ ÊÛx”«ç.ìsnûËîö,Æø´û¨®üŽéÙ¸e!#ñàêT¯×Sà«cjB驼if/q1aq„—ž‘kÂÄxâˆmu Àtz˜À“G¨N"ÈØCf8[,òk0Ô}E0Š  È}é™ÅËr]‹B23)ÿ°‰²m>þç!ž_¤ ]0ϱÚCöüÏövjl¹¶ÑëƒŒÍØ¡ú—ÜòQ9¶Ÿ…BÉxoZæõÀzxÅGåjg°à4wA“óÃ|QjÙá(w¾ß Ï^ÞAÁ ±ê$@Ïø›þòàvdwÜ7$8ñÄá½-T¡¡èƒy,4ñž”–kOsõc.…m:Êßšï}[ºv ç…:LÂɵ`çHVÉTùÎXrƒ’<°x4íئ£/ÆÊaëH;s)¯a°‚¨•ÞÞñm«ë·±9¿þ¾:oæUhÅþ¦½ŽÄ¨Î<Þ X3›–V/bï{·R2­ð§$ãn:ÏÍ Ì/»Ì7¨HN:怟»#s8Ÿ'é]«2;‘cât!6ðÌë’ÐG6ÛQ€7 •fìšT·Ç—âÄr|[OV.!‘]ÛòO_‰• . >ÿàÅ‘¯¢*ÊKݱ”ÓÃE¿%@æIÖÇ #¾‚°ßëDUpzemŒ)´ƒJè$𤶽e[¥UÇ“¸Dp;Á8›/w.Yë2ª »–aDgáC5œA<§AL¼î‡¼U`LÞ4ï|ÆE¹4s‰î'È¥QN’Q]ˆS Ùá¦âË ³äoñqë¹ ýÝx©×ÃÑ »h º°%›—h"Â1 iÈ—Ÿ)Q qþ:Ím˜“Ç{4ªT¹5Œ[ÚªCøÎ»Šò”ZÕcç3 ¾eWýóYÎsq¯¡Û´¼g¡²Ïÿ>ž´ƒ$xâĉOù黋…~S`ÒLÑ…T·•êü*ö–/ì^EÈHßÄæÆ¡ÓHQ÷3-Sȱ_°)½ú*Hakw»e†CNp{¥áÏ鯀¹c⹟)á;MHD£¨mLãL½Ä˜Ÿ'P› ’7÷²8åûœÉ\“Z,v*ã ¯ä](q’íú zêo~»˜­8ŒsVÝ$¡0„ÑÖþ„&G¤²ò)¬wû†‚5È𤠣(’P™ÊŠFÁƒ6¡±¯AåêGHo?çá•å°;6¥úË”©ÀÍœð')—ü™YýqaÀ#úhÌcÊ%“;©“Ú Ç ¨õ³u Î[ÎÎ…@’ Üó9’ÖÓ“üCl´ÿÕF‚jb;ú"S?³³.F LÞ˘óÝ™xô>]Û¹GSÊRIi¸µK 9—¹;k]f\kA¾ß\[À°wá+õ^mÜ’ç'æÎ˜¶URU6XsvfQÚ„¢Ñxò E–ø¶D58ƒè‰—±;™À‚†¦´ƒÿ4Öÿñ©ŒÝÇ;쮽ßË*ö’ϽÂ÷[2wÃ}oýkŒËÌf\y Lëzµ¥ÝͪB´9½ç—„÷×/*ø§a5J*vØ$/f¥ŸÎè¢ÉryŠ6¼eög¬,½³Dë± ‡Ê©#‹L6îKëS?Õ$.¢ÿ'×OÁUŠEÑd#6Cê­ÍBŸœ•ýrZíC¾ÚÖߢÀ¼Š›ÅS8”ÊSºÂOÝfjˆƒËC|'"¼2'ewÁè¢PoËJÊ®*ÒA˜‘˜GD7¤¤,÷ ¡û0áÓ)mÜÚøß«ò×€z%Žaýäo€ÉÂp"ô^ö´AC/ê:tH¨,`c ¢`fFo¨u‘ehnìb¬èãl9v|åÌq²IM`C¿ûMÓ¢UÏõpãÑF ;GÃ^žèv– X⌳pZ¹pÃf<«mÆ—÷,ÿ]Ì@È#®°ÿྮ×Hka!ý|³íªþì€9GõFQdñˆƒ«x¿_7ÅÁ[]éâˆL(·¥¤wÈÔæÎW}Eÿ&‚5ÿå•Z•ýìi´×)ž_vˇî!íÄAê¡nŒ)QYW-:\Ži¶|]߸dœ±0ŠëhÆŒc1GBÒKÚŽÈ“³úÎÌ­“‡P`pHfxßZv<–gUîÛ ÎfÌÀzHnû‚ØÅP9“ûJï‹v^ñèmXN×;f7ÝXÜúšÈÇŒ'혹îÿkIRçŽ}|%“àÖÊÄc³l€?<´êÞ`|^ 1©Uò]HY óÝ8÷µd¦+kåP"aÐÄ&ÙէȺ¶¿–…Ì9róÇ?ÖùÒ¹ ©ø°Ò4çI'Q|.Ëó®]hBE.¯¼ÿJ³E›xb,m²Äßãe]îš±Ë}Úð#NdÃê“W`/a=Œ6Yt´Ëj×"isàW’ƒÜ¡_¶½D`ܧÙwH(3ó · uAë 8åñà/ë4`Ø ¿š§`òÇ/N‰ýX`\¼O(Öc´·g?ƒºß;ŒþÐC¿µR‰¯Ë/>G’âæh‹Bà@¦3±Í®Š«æSœÎ’.y4ÙÚgpaÍç ø>xu&xÑ”zúÅŠmâBRí:ÖÃÇ~¨Î`M¸yÒ’_ÜÈ4¨¬,ì¸Ç¶<êkÿ@‘…Áœ0M-öEWÔXÙ­m÷ò;v}>ÿm³[¤–Àñ:þ‘COt½MÆ(ü†ÁbÓï7ÞÀN2Pz<Ô7é 뇭(Ppˆ‘¼*åp¢Ã© yÛì‹ÁiŠ­ ˆ†TˆÁDUm¦‡D¹mËoÓH×Ý6ªç1ȶÙD éd4×YØ£³Bžv’ÇßF ­ÀÅðÀoê”*"¥u^±‚¹6* éÒ°åv›O#C‡wC1ý5-Ý&¹âª5Cn0¤Å¯'®ŸÀZÅúŸjÐK N²81¡C‰qÐ!‚qC‘Îõ“ÆM®kOÍN¹[ËPäÏ:¸~ši:ÜIWÚ/ùº¶äÒ „ÍwþU9vç×’µ©/d »n¯ÓùÙÎnÜn½Ò·Aùº*冮ª+¿(ª"äê6,¼| ]J´\™EQž°Tè5aéóQ°– ϦeIƒå]t VOÒýÉïÏÍVcô¨òݯƒüf›dŽï ‡Ãø0¶”G•ªHLXKF’`ËAW=tX9ÅÛ£k52³…÷(âÑß>y]!¯d“«Ïæ^õw¿¢ò«¿Ø»¿+I+`«!é2=Ù¶í)o'ëo§ŽÐ`',´’ƒ?‰ÀO%à+ €i ×í.kä¢&êÏOÛ²ŽÎI`¸C=ê ƒ2Ç“M‡@züÞ,cÈáàîû½¹##¦EÿL®°gÑ8ËÔâ¿Lh¾jÂØ;“w¦KÖ¥ðkÌãù*@î[T@'§ÜZ„U›k’°‡1ôFð:º8š^”¤ açOÞÄVV-JÙêÙ î[!žƒz„‘öÈDªb˜‹Û;tÛoò`M·<²·ŽžŸM+É•zÑ–°2”:~ª£oé5ž‹¡I&ÝÓ–ÓÒà‘_ÕçÛT¾Ov|1ôØ3$܈¤Ù:µÀÑÜQ1­Î“LÑQ{z;QÀ Ô”*yKaŸN²R¥8žÁE·Ï>nV´6t$Ãy°btôY¿#ç µ@.\¶Ë1•µÚ_kÚ‘‚¸÷‡³•JHÈóóÌz¯æ´:…¶ì¬åejqÀÉQc¦}¨(+u0à jÞU6N ¸NEMï =âl¤œÜ½îà%Êô=—’ØŽêQPyó¼¡ßo®”2>Ö tȫ׻"Í~ôÃgdæ®iR_mhé~,û‡v5-AkZ[9MdÇTïÙ ÿ=µ?.Yûy­žƒ$]Ãä¢` ¹ûF-JLxL ¸)·¡˜ÁçxNÀà;¦Êª§ãA%"¹É.Ìe‰ZÆ ñ;*U®ô5aþ÷2oF·:ïô°Ù=æÊž¦?kbªsá‚9Íw|Qì8Ýži‰g¢k'`³žå†ÀÎþBCÓ<énà03µÌCÊ<œ°×MèeÅã\ê;ŸËìþ9]N'þ”¼/;ñTv{NÖí+‰:­¶ä„ Û³7bã·ß/:TƃÄÑéjH…žCE·l;ó“9ÝÊk¿ò[;mRŸWε~íÐ ¡¦i+޽‡²ÇÕk´ïZdárµ »6RN$Ï»CÌÕªó œâ]ŽÔÆ8‘9·&†7—âÍöïHhòǵ§÷=u/(2,´|¡Œr¸Äq¤DAÞÈkU¸°ãþÀs+˜Æà¢–¢ÛO²OòTT@ÙïÂwÁFÒâ¹ ðòù'á0³åD/IÞJë­ M1Ì®Å\(™Û·YÇŸé­f~ß-”‚!ŠcP-‡DnrD ô\ìùAlÀg÷ö­9À¸•¦¡š]qN^´ÙÂ߬ªé† »²éƒ æNÌ›`¹l91ß ŸÝÌÞOVܨòb êGDÕfc[ª°€ùþNðŠœbÈ{„7„Ì1°qlòý6Ÿ ºocf*F¼ËË( -ΡA<“ŽÆÉlÅiOžœç‡.‰d¦Ã.Yi4÷ìe›PuÊF”7ë’'AU¶ ^³œ_ÒøwÞež¸4…k(6B£šŠCzAV=VÔÆÝ¾£¢†³\ý UÂÊ5'bGâ_ƒÄ¿;oÇòæ¥hJ Ÿ÷FÐG;h^ÜÔª\1:#³ÇõyUf±ê|[E‚tÖž™, {ÁÿõÝL_µœ\xd´²ýZ`~d›1›¸=þã5ÚýžlϹ+¸†1Ìc˜Ê«a½ýºû=s½r'z¤îàí$ÄÉä;¢à¢ÉæË×ÂýgÞ«Ò!—†9&üØ„U/skÎLLd;äo˜2{”Lºeêëâö„ºÇîüÌ¡/̘ÂDÛýßìаsk‡v6P7…ĉžõ v¨~x EX78› ïÎ'zõÙ(y`7¬*(„Œèñã  ÿt KSË1MÌ  iÙ¹åÞi&†{³Ú‘€N«… ŸrŒšÖÊbN1ÝÈV²›µ<$¡Ì/W}[ѨDVŽLËŠ E½¡PÃ;ù¯§P`‘,«lý# îÁ…5 ¤.õ¸°·—c½U)Á]­å³Äð÷•n“€¨úŦ҄RT®Î.¨²k`½Ý^kUᯇ^."•Éý³à–åæÀvÉKæ«Áú,5òÒÙs)n”!¦éX¨¯Š”à ”shWùõ?Ë`͆%ë´•Ï_ìG…,ÌÙ°Dü¯ÉÖJ1êñôRÜõqDœßâc™nƧ»*¥ÃÅr点!ä¹ÓÖ,Ø÷iïJ¹‘„3í»„LÛÔF­!uå/X˜ 9{eì™@IÜ{]«—NÞ:™`P2­æ“± A[z—ƒ…|'¹ºÝOS+3?™i; çì§”&À|b27è~ìCx¦³ïNPï'‘E(Œ-AíïÚX—’ý¢|ÝI´–Ú5>ëA™:´AT›&òàï—’›1¼ïhŠ"W6$F]%³´9ŽÄzìLÀ´^¼ƒ¬¾ÉE‹ãC슂•Ü«çZèŸÆ‚ø95|Ù¸z"½+‹Ê´Ÿsse1~ ˜æYÜWf¨Òó>ü\Üô´¸µ+50º/·ä˜yÈ óôù|1FðÀ¡/M{ Ìtü^<q{T1©‘¾a>Gü7½¾Z“êc1ßÙª«óô”O÷«þ\\+LSÆkÉð¶ø§›“^yÍ2Äéßß%8˨³NäÕÌà‘ÂóŸ¦ðmž²á(’Όኻ L&°»³Ø¿Aï9Õž»nJ鞬~s&¥g\9Öš.ê\ñˆtða3ù¡€ê2CC…zïÞ²4u4b®ì ~XU(L]´ëˆÞËš¹CWøª‹=ZyT|C‚B´ªæ¡}as{–TbU@†cÆû t“~ìoš J>ÄjWG…@‹°Óvž3¢¥wM u-A²æ7Ü”SX6lVÍoø²ƒG{¹Uå26½$ZìœG6PB%9îTxðˆàäE.fæ˜ô5Á¼UóêæÛäŒe¦ùóYˆ¡ùe6eÃB™L"âÄÂXì"Cf?W´ösnðã,V_9FHþA‹®jTšHÒ“¬zsqõ† ;]­íÏy«Ä|®QÍé|—̼d€ Ÿë{dgV3ßoªº¨!ÌÞä{DôJ#Íð;D“|ô#pü’·‡±Õ¯£[fmB‹(R!±ú$g W,þž8¿ýxV ‡fÐàei<¸FZ*¹)|üÝ'l+tû6£w»Tà9dËÉ$ç2&m¤¹”hýýpTêo%mÿ_ÛfõH‡Ã€a¦9ºcºÝݦ»ëè®1ÓÝÓyÄÑqts4ÓÛ0ÝmL3|WßÝï/x/ß‹çy8s¼+öJ`t @UÞ09ËØZð`0j6é¡!ޤô˜ú®^l¥éûj‰Ç=éEÍh™È¬–%Ê'étb®Ÿm¸ 8Ò¸Ó¬ƒpëÍò.­C* ï¦ŽSFÂ^ç*ÀÝ"¼.cK™«Ïðlgˆƒ‹ ‚Ä ÛâåY&Zãa ª¢Å©¿T÷w*fÞ³=‡ä)NººB [²Vò]ú×±º½ÒÉÞׂY^0¯4á}Ø3CÂ%˜‰¥¶û2Ɔ½:ü=ðÝî]w‹µRM2la‚óŒÀ5RÜ{ÖŒk}n%\;ÓŸ˜€³s€Ÿ’¶zé· Ñ  #£c†+oÛBpà “3‰ÓK¤"¾.Þ\T9ÒÛÎ<« 9iêrh4f—·y™¹‡SöŸp¥>įù<î6j ðÊ^ žÏ<ÊǘùðËð«ÞW|àž´×º­~ÓŒï)n÷Yã!ÐO À£ò-šà’ Aó’•ÙWÏ̈ÛýH@¶Ó¤bÇZ40ܾîDãsƒ;«×ük*´ÇW=Û¶ë¸5/5)ÖBéú6=wêêýæàKeËH÷¹€T^ #a}v%9[ùûQ÷DUâ>€þBdGö^¤mV-ïë&MõmtQ÷Hí;Ë®M°ÍÐz=³p¬Â” ösÚãg„A~ V$W.?Û%3~ ª[޲ìmÕóùCÿHå a׎gÖ‡x¶òmv“¿WèoŒºyy>Ó5+Ä nëäpQ8¼À«òPVÌB n¡P¶èă;ý6ØIf+Hî&¡)%"’™{X½9uÕÉ· O¤Õ9å¾ÐtïpgY7 >,“‘óþíœä¿H&ÇF¼âý9ñ1‹˜Ü·HÔäVŠŽE–P!I¾í‘úí{åµ]xx’æ~—öÚÏ`ù b\ü£†Xÿ~*¬=ÂÏÔØ²;z ºŠy½‘íÇ-¯#rÕš•~»ìª ZW×R 3T%½':²œP¨P|´÷:H+ oú1Üü*è+ì „ÓúÖµqzÐ9òn:ÏçƒÃaC­ªt«Y~gøœŠ­;ÞÏúÀ£¸‹Þ­£h½8ŰrÝõ Þ×Ta£ì¡J¶(󢫸BaáíMìerÛë¿Â ÞdXÏ ¥DÍÛ1ïâœ2™Í8ØÌ´Ë•Î4öØy$ggý*TF:Ç_ ˆºK‚PhH_øë;àÄo²iBÇøÿèoèÉvÒ~ÕŠ«.6T®¶"( Q¤N- ÜéV³Ýêîý`Êbçs¡o“N/ÃATE(õwÀ¤ µÊê~’‘IYk“|}9Æó–1Ý-øl@.SÎ bGØqOtlh{@™ÖNíbˆ=í1‚ƒ"uŽ%ŒäQL5·Äƒù€É?%M͈½Õ Ç$Âõl¹Š‹,ÈŸì !6 ¹M­+¹ú¢}-}U$û‘<½dËU3©œlï%ÃÆŒoÈ5²dù_!ŽyÍ·ô‚Lã€+`u¶º€©e¨ŠˆÊá×·T‚_;/£¤`Ú#/#€öÂü®eð- 2<Ò*ínΙëQ¨,,„còä:œ ¹‚ª”/ÉŸ®ÌžŒœò³žì‰*Ôl`v|¬#âÍÄ%@ר£oØøšdå1âÏÛ'lÅ3PF6Ÿ0R† ˆÖvì·D/«ÔÜà¢bGí„Ùø®Úë ¹tѦG…ç·uÉSáŒÌè©ÙwÙ÷Æ8PÀld…\ ¢Ý+9;¸â';}¬Õæ„d·œQçXÇñ:­UB¼P÷¦ƒ)'! UØ~ K¡ÄÊÌy!dI­9ËÁgd'ERɹ­;ÚÖƒ±“¸‚$ÀJÔÄàUXSØ÷¨-ð¦Y­Ã¤ÁÝÓ›xò.Ô¡>ùÓZáïQT”僀cÄP*fÜ•e—zé.”b:©ÕlƒÌÿÜïê ±Šª<èww6)ÏG šÀ\/ýcœ=…ŸåÍ´Ñ Ët=¾Ô ñ+­¤WéG’]ªvõ°%Àø›“äÂî¨Ùi»|%+u?û7°ßù^ÊÓòƒ÷ìÀJ·Îû[`ÀD´ú3+ºþªµ³U˜ä ©VÅà™ðRЗ0 Ìú]ˆ¿ÅV—õ-Ò©Ó¬´¨:ZV:‰Q’œ:ZÖÃè0ýü=GŽ‘iö3bn5?À—#§¹k•uÚÚ|A@‹0ÑŠŸ;°_ú¤0³g]ìý®Kho}Uk×ôS¡ï§_—4©ŽµûÎjÞ@#ÏìŽF®4-ŒQáqzj8‹ š;ÕÊÛl/zHrÎ:óÖpÇ`PƒÌˆºw6–ü”r‘à>m Òk¨'‚iöŸ< ¯™¼æ-ÉÕT£¢R¿´ñy7€zgK4ª,Tì%aKtt¿ŠOö#ñ¤ô®míef8~B ê…ï§‹÷—ðëá»âÅ>S–g˜O)Û}0à|ý9‰Æ¹‹ ùs5sFñlšCäÎ{¾éÎ"`l ŒûÞóPîÌ{Æ™ôÄ/œ­•E×­n(\/œêMv-ŸX¿> /Qßa‹Pv…¿|Iùpƒ«5ë)¤†±;<Ô¯³$ßßP¥l|ùůŒ\ÑŽ·n?îyM^7^Çǵù~Þ+'¯g:˜Q¨};ƒ7ªVZ"Báç^Öþ¼¹ ‹‡«oI£ÄM/ 8½Z­³÷A(>?<‘O¹¼ÅY[:KŸyzÚ™…w8«:&:g$Ì»{ åÓøê!»M<¡ˆÉ[oË×"› €äâ Úê&ÝNi‘ß «#"Wýà{[Nׯä¾ù¯Y~+T©ë:c ÀpeÃE™Thw3• p6+w µëF˜áÝ÷v>ãÂežh¾a‘Z,Úç{0Ï=CÝiþ'.AžITâVFỬåKæÃéeXA>PA KÜ˰¢z~À¡Â¹Ñ‹Ð"S³01ºÌ=dK&*Žƒ5vkØéSuóoýoå%;™D'Ø:VCÚMÈÉd®JíÿòsžÝ„ '»)ÞKKí›`d¦ u¹í?:`í­…ì1Àv´wºV¾—Э­~§Œ–3B§öøt»ørn¢|ßîûÂÑ=ÏjE™:¥S¥…Z@ø”cÔ ¢‘¾œ<4ü$-¬³šÒÝŽƒ;ì‹ÚFÔ7ošˆôý÷ï‹[ïA›Ü)˜?©>}VrqáJµŒ§›ûsvŸÿ‹¶çûñ›8žsOZè'\0ÀŒð2PWÐ'´ñµHF 8³2f="q.8NñŒôHÑËt—Š2Zÿ´‘ ÇS×IhF)]Ð' (ië$z̨›?äMi7Ñ:‚f£UÝwTø^‹x÷6ä9&—<ª¨XÊ&=U²ÑÙNš/N\‰¸Ð ÖkجAQœ¥Ô3…»ˆsœ9{è–â­Ög@¬ØãJ=u[’HÍ׈ƒÆg”Îv<%×ò·¡Pº!ïX³²SµOLUÂmTyM›!¦â$4⟬Åñ~>áÑúŠ‹˜ýK—â¾gDѳÂ9nQÊs½;bׯț8<7^L ù"Ñ”¡îÙneñÄóågc.¿ÖB³.ײS‹•³ðÌz†!ˆ™š3DôŸ3Êpcsn9yïµµ[g´ŽSÜ<)³xpb”$7ÿ-1 SºÆ ¦˜ŸÌ…(qÝ{å’„)a*± µï³G·F| }_Cíó´¿F—ùÁAT„Ò·Ô`ÅA2ž¤Û»×xѺ<ª¹&v¿ëÐ3OUÖ¶]4DôëÒŠçW7“膞®Þ,l —x§I¾=EÔ•ðq»¢¬`m9µÓö[þ]°‘Ý„»püþl¯òÿÛ¯ö¿˜W̾ Ô!Ò¤w¶/ý“Ûs•À›zdÛ|å®ñ5,\+‰ø|n1I9¤Ëåxǯ(?…&†Ê¶%¿ƒ&§ß›Í¡ÍøÆæ â®Ï òÔãö—¢F ú`ÑÄKÏV®^q¢zŸ8núõ¹K°ó²×ø_‡·šÖËÏ™Ìo–l‚»~lˆÍ;çDºê˜êR‡U™¯úeç'ˆš9-É’ÉŽ§îF\€1ð舚ì¬\pk€‚ÐÇÓ·Ëz5N˜ ÀÈ*.cŠG| ¤ÄzÇŠóÔ´ ìéRÇ'Þrèå öÝ»íR öZÀvÎI³kÂ2O¼ß>Y“~mtÕ” æ¾Ë’ la6ØPx‰Î,aï¬9Mó̤d³¤SÁ-€øVßçµÆ/I’Wpr&3ئ8ÞmêÍ3³V×®þ%4ê. ܦaþ¿cIØþ…ùǬ9=µ$£w/=1ÿŸu韖XNî¿f2“ÙÁ‡³»+®ÀEªDûaþÌŽ ާ·ÀGʽߊN†_3È ÷tÈ#('š8~w÷ÆþÛÞ24è㪶IÝ,å“~@€\kÿa‡õ›ƒñÖÚМÎX¯F97aji9 <\þ¦l;n[”[iX £ëìQ‡Mè|ãŒ3-–²[qî‘ Ë…lÊÚÌ8þD>Zš `Fç@©I!òWèÄÁu$±Ÿö-¥tƒùg®Lé!51¨$Ϧc›Zæ I=b7Ux…ˆOEá5—Vªºð²PæÔ‡ ᾡQ2+ßÕtj«ò€FýÊ8î’°à!‚S˜2´N¬¥?îö }*%ðpiQ>ÝÝ…%È9‰n~'0ùùïžDÛ¾Ÿè©uJ¶Ù©³ãü–³Üð#bŽä]ºÈ ‹6óçÜÚT]72Öj¯)Ð1™Z»jT‘ÿ]WÃþtFÖU¡pðVx~/ùˆ¤™  èŒÃ‘#*tEÞ Û €\ŠWü)"t0iCQ‚Ö"¥kø­f§À–?^ù Æ?’»Í= m¸­ŠgïÍqHæ% «ò9ŸÄð­^)*üNÙç§±h7 „ÒälD!|Ä\&,È‹öúø¬ÝZM¾ß5EƒùDfÈ32MMºtÑ^F¦3ýÅ{¼(R¦~ãºLç1¢sû%ˆÌ»Lxˆ`žÜn å%Áîæ{!êØ)&ùOsþ#D ÔÀM©¼ÙÉ8s½ ‡ãåmà$^™jõöaàX‚†REÜtÎ ]<¥p—ªF=ùÔö—Ü꺕=‹„’ŠœÂ$¦Ñ±‹µÑ—Mºº8ÒÕ¥]·™Ÿæ§Œ}|× (a¬»ĸET$­g fBõ“¸ôȘ‰øÉð/Ÿ¸czï¥EË6a.;°ñ¹» Ë~…d†úáÇ|-JN™‚„sxÚÉž™7_ÜÌâ¦"ïÞPsIƒjPØT”åp%rP~kß1oÍ Š|Ù3ÃŒƒt‚¹ï+ŠÇ¶ËQ}z¹!kFQÑïpks•~‚.q\L”]éÁ–íC ì“}Úݬ«fÃùð1ÜYƒøþM ÏÔ.ÙºtÜŽ’ä i&ì>sCéÞ·´¯%<Ñ®ó]aì?F“!uq5yú4c‹¬>Ø'ÄËp«Âá—I}ó5.ÄaåÓ`›RE2]=DµÀ÷¨×®¬Öz¤ºBùaÑ{Z¼ä_Œ¯5û•C!¸s‰‘ub¡~ÈQ¹>ºl×Nàñû3[†Wñ,£WÀ;·ßÙPr¬(69‹ÕupÇŸ&* nyƒh¬M±¼ÁÜšé)ä3cU&³3À¬›õ«€ðQ†\`@ýââÍ{»¤ªc–’ÆžœbžP"Ńmízy&¦ÿ;Z¼)ÛD0éàlÔ§--“aµ ÏÊ?DÈç¾ë:”$g¡Iy _ yÓío•‡ý$ÑJß÷)®PŒ0ijd\øìš>йë&Ë:XÈåD9!7I: :–*J—/Jnù…j·™›»™Æ@¢•ù®#N÷uKâ`x…eX»áyÕœ„/¡k[ò‘±`"ÖãÛ Ï3-}oâ&•æÜuÀóE !}·Òiå#"W]26~†×¡Íz-^;'EùµîÐÚ«kPOiòZtœ<|×Ôqz‡–q,9ñž$/¸¾áÖ>–ð^Ûô. v¨Ž{°”nHÖ$ÿ]±@H%vÒžn÷çÂ!!¿û{h n]ÒkEÅG/³Ær­1ðâ·þͯ™Öp]î8âÛ(:È´ÿ++~≘”9‡¯v`j1º½÷šeê{Ê8ü©Y÷dD]¯h<d晑‹¨‰(UH©Í.™yIJÀ«ªPPHÅÚŽˆ„g»§ÜÂà02á0øýJ@n¶…b®º#SEœL&ØÕÅžŠ¨€»dF¯ôø+0š˜gÆÎ–4T—àƒÇóïuO²ñ"Êý…ž‹üÀ½6¡õ}hÁ%g“*‡©¾ù·žl®Š“IÀ~ÝGG¹Grr;WÅòvyð³  é]»¾_§ªyl߉ã ËN_ïg‰Ã庣ÐNQE˜ëN»xÊb]Q§¾åhŽ=Ðäm)¥!‹Æ¼ý¦¡¥aŠ¥yŒ q”'­i’NÂCýÁ¯y-âÒÈ?+ªyEœÏ}8‰ÅbŸóŠðö,Ý=3¡%X[Êr¡eûz'ÔŸŒ–ÏiùiºÄ™–„XPÀµït ã„­­—SÆ8‹»ÃÏ8m9Ž'áÚßôF™¸+¾C‘E3øg¶ç¤l€÷"2™Ol£:&Ã]Ñb é˺Êõ%³ÅÔ«hN/“”ïtÿ/ÎV ªN°o&diºcAÂ…p,¸`ýLìD¤Ø¨\¥Í@\Ãá˜ûJë}Ñ^wðàÙpp›õ ‚(…ïI÷œ¿Ì øÿ¼oïTÈüa^ÿHã˜ÂUõ/ê|c¦YŒ”BøJÿ`ºïé>+ƶ KôX#Ûº†øÄá¥zzæ¥yÄ… a±‰ýé yüÇžÀ¡@m–„îš©ßø@¿a^FñÑÓÖcñØâ3¼é…¼7J\)‰ÊÌËwþ7NØÿ,“¶âóÚìt^„±Q1Mò&䩨¦Ð6õbˆ$Á¾2þãmj5bŠ1ÑÅâÄŽ°iŒ3Řsš¬¸ñ 6ËŸ?N·½…ÍVPÕ šg—³Ç·änj8N#Åç.ŠõbdùѲalÆÖi®J!¹N|–®bv–eÒýáÓ[-‘t[¶ïH¶÷—²²HÅÿå×lKê@nÈ> stream xÚ´ºuT›Û¶>Œ)îR w-îîîîÁ!Hp)V(îÅÝ)V ¸»»»Kq)üè>÷œ½ïùî¿ßÈHÞ<Ïô¹æZkdŒP(©2›L€ {0 #3@N^d’³03ˆ€lͬŒÌÌl¢N@c°È^Ì ä0s1²03²23s#P$ö@§7Ú `â‚Õ<€,jã¿€ÈÌ`bìü&Ú[XÙiÞLDANV–`À›O <ý±ațڀܜm¬ÆöfFyF€Èí´Pƒì&@Kc[sÈ Ô¨«Š«¨$UÕ•Tiß«º88€œþ'QU5uIz€˜°‚š8¨ATWUûó©´7:YÐÔÞäâ¼)þ1—WVÓVgaúS€à tr¶úö¿r£|Ë ðwjo¦æN »¿¨-Á`&&777F g0#ÈÉ‚ÑÁö¯üÔ,­œn 'ÀÛÓ h ü«1.öf@'Øø/V ge ´wþ1’ýKh÷ÖÊ7£7üŸÄÞþãÓö_êg ð…±4vþËVNII`gleÚÛ›¾)‚Á.Σ¿¸·7ÐŒê_ ¢.NNbÈÿ[äôŸ0ÿN]ôV™ž­—±Û¯˜±½‹³ç?zó¿Ë6Ù;[9ƒÿå0·²þÉÞùÏšYÙÿÅÉ +HKˆ«ª1Ƚœ=ƒ<è­;öŒ`wð_Úü ‹Éñ8¹Ø¬,æ·ñ·7ÙÙ½eíŒð§}bVo}ƒœ<˜þ{ mìAnö^ÿÚÜÊÞÌüOßÍ\˜Ôí­]€Òbÿ£üF!üÍYÁfÐt7µdúì¯YùC³ü¡ßšàãår˜Û:}¬Ìo/gcW ìäôñú§à#N€™•)ømÌß¶ Â_Þ¥íÍAîÑo™ü[ô?@ý×¥yÛf {[€ÐI~êÿvÙÅ’p±µU0¶RÿWGÿ[ÍØÎÊÖã¿ÿKGø'YêÿÃÚÊYÂÊh¦d6µü«‰ÿ¢¥ÁÆos/loa |[’¿(õ?[ÉömfßΫ?€…ãÓÉÞÆÑÔÆèì àbýK|kÂåûÖù?Ù˜ä´åU´Uéþ{`þÒ·7™YÙ[XÙ9ÆNNÆÌoSÀÊÎðbyg3 û_c`b´ßL.`€9È áÏRr~0Iÿ¡þ…¸LŠÿA\Ì&¥¿Ñ›¦ê߈ À¤õÄÍ `2þ½ÉLþFo>MÿƒØßd¦ Û·¦ü›aa~ cöÈ`þrüAŽ.ƶÿP`0™ÿíð¹8ýCþ–¨ÅßÞänà?UØL–ÿlìoÈÃÁøÏ¤Þ8«À·mþߪø;#Ž·lÿ,åßò·šíþ†,o ÿðÍòVèð-C‡ÿÀOo‘€N°ÿIã/Î ôw›ØÞŠt°uùGL–7Æñð­ÄTÌòVÏßÊìoBg+÷¿½½u¶5v¶ü‡Á[Lð?à›†Ëßkúæí¯ÃÙäü‡Ö[_\ÿßÚàö7d}«Ûã/ø¿]éÏ!ÿ× Æü÷äÿÏí÷V;l€šVf`˪ȃ¬Üu™ßŽ–7þíõïoúÿ+Åß'ç?¬ED@î^ lo­`øô¶žœŸØþŒ·Ïÿ25ý×=ô×É÷¶Cÿÿ\ Ðhа82å ²Nn.ñÏ›(…¡àf<)ÇÐ’‰}·˜6ÑJ€'–½E Ì÷oòK§ÌÉIñèû&úÛjQaÛ¾¬ýH¨¿6SÚ6ö•÷%@ÎÒ`TH—_ð+m#¥9”ÉÊÕ.b›JoŽm&¨‰r·¶?D²Ž½¢ÿJ"Õ+m^Éq+˜aiÄr²Åp_@ûð“`aâ'$øõ+:¸Kx‘vÚ(7gXÖ¡³M‡.9WM;m!Vû.¿¤SN¹zÇB/V4ùpãWûý’"Ô”‘‰³‡>ÉÏ«¶£ñ™²¤ç3ä[“¢{åVHjH2á%Â+éP•voÁ¿Ó±È¿ó´ðþ¨¬#`ª€ŽÏA§"qóY¼°Õ"굉FÍ2üÇ‘ö—¬j`˜%eÄb½ænµfŠQ'ÁÏ vÿ‰\Ì2ÈjòB›¯ú0κ>¾Ïô)I4wibpìÙúézmÅ$µ÷Ì-¬î×gŒ èŠfB³ï%‘ÏP¡U Ú:É”¹–»Éò¡æÁÜÁÐ]Žžaƒ0#><° Qˆ ćχÓm“ë—ÑWÍK¿†í3ýÎÂˉS–ˆÄãn¿¹·p%™}óžÈÌ­Â5™^ÇÈ#’ÝÙSy·:bw£ÙãPÑtÉ©VB¶{Øy¥K¥½Õ~%§Y/ÿ£/ãƒìIzZV0~á&J’m‡~_üç©›¨m]Q¹ ”fàTºê÷(ŒÒµû«¼Ïyúã~»ïÍoçk5óº2iàjoìù¹[â"¤‘™ ‹ä†…0Ã&ºxê9èòrWe˜ä°Y±Oíe ½w%žQ3SÅ:«“sR˜ËNž°V‘X‡¬­¡ñ°^ï?ÔÚabðbfíT¸e¡¨¸ ¼ð~ÞªsØqF Ж‹dê=f€G (¡%ØŽ’ hîæ,q©´7à@,ã)ã0¼>ûK[øŽ6£5Šœ Úôgt^ ø{˜¦óž‡ktEšúš­‹ŒqoŒî8íúÅmÖŸ®jLòÔ®­§Jw?h 1Ò±ñþ(AD ƒÞ‚òNÄÉMª¯sÀóšJXQ"ù}¡¤m;ú »I·\Ñ µ£?‚?×±ù“EEÈ3V¨ŸrÏï-¸ <«ßTþº}¥ì¥¹âRçA¼" ©½džøMŒ(Tt÷Ÿ`³»‹3Ó¦ p78pµò‰µZ)ÓË#ôNê¦Ó¹åuSgÌ ³‘Í,a¥îW®=S2ÈJà Üx,MœZ¦ôÒ;c-9lj‡˜¯ƒ—¦[J½Fˆûé.7È<Ú¢ùyóTÙÚ>…X’­v†ñް‰Z <í`ŠÚÀÍ©U‚‹îk²2K‡8ç’q‡G5ìz S•m˜Uo³^ëç9îõÝÓÕ•ÎûÇ á w¬á(J"«‚Ñ=?e²J+ëÔ ?]´òªzóiÆ+t+ßãi0˜Žç0…Xó¬)I,ßöû=@)ˆ“ô«OËJåŠÊ!O`”à…•”-fWSk§¨5Äe¥„íš«;È,½è¨n%Þ2Ž}Úz %ýÀV3Hk3v÷êp´¬Ï’#9Øé%»î{\;û4´ÅàÑ3Äýáj;Òuä{äWü¶SnhXbÒ`¶mk̶m2Ï¢.¯6”ÜÞê—‹RJˆºÒUTÞüfÏ-xcC}ˆå°ÓÖ€÷ÚÚVǬTNa‰½aÉkƒã£¾5버:æŽÜ|ÔÄë¾UÒäUÂB.›^ œö'ä³ë:—«Bž—‰ßÆy{TÂs_‹”31]ÛÕþP‘ü`|• icâ2}&Ó Shïíõyk€‚†Áœ}‰ÏѲõÑ¿‚ý ûѶ6ØÛW+RtCÒÂÞ,¿¹U@Ð\JA~7Í¿Õý ê‡uuo哱iv‡1ó}m>sD¹“ºe¹j:íd#µ}×Î œ6‹yø;«p¾¶hJ€h‹­ã©Xjœˆófþ§¬Ë–†$~Æ¥ß+ó‚ŒÔŸ÷xúî¾çÕ{æKš Áó†‡NH|ýÊ8`'hhºA8ð»lG†¯°\>¿c¿üÄ=xúÆÐN¼FaðrK·š¨øUéçþb¯UfügGº0m”_›•MÁ÷?/#NWîT£Êg uDõë\È[ê yaftvîOR².á»a^úŸ>cÔÔÎcîâIH€çcÚÑ„ üªø& Žäµ"d¡ŸÜ,uf(Wb%cÀb¿‚˜ RviãPœù¨Þ)×—Ä ¨ÁÉ×jQn¹nÊOôÅâöÍ!€íhçüóéÌŠ…­¯ˆ•ÍG˜ô³_˜¿±‰8[;w&-G)„$rw‚i¾+}O¿Mo„F·Á韔·4ñäµõ«¶Íyia¤qG­úkÀ‡,‡QGÆS•S‚d ØÂJ „¹bz^h†’u5Úº’¾Ï"ìr¹¶§Ê—Me1ÊõÖ4Úf1¼×޵s\ç'±ên‹«gÔëL¨Æà¶©!ü —|»Ù9iòÀ7Ü_ŒŠˆ¦ØüüÄsÙØ ‰Ö¢O`û\×¼k*úß­Àudq`yʽ³É_bÄÂT ˆ%ÃI ,Vê'­RaW¯!ª¾r÷.uÈÒF3nÜ‘çÌ„2ßyuR;N©¾:Ž5…2Å8H4úä¥èvgÈHÆÑh>)“ˆ·Ó¿tU±çZÞ»MM+ÈÄ~Ý[?äÒÑ,áø 'ùüNᇠ5¨e[i„»óaš¾d°à+Ç$š&æÙ¼Ñ´WÁ˜¸Ô² —§Wn8. ¾õ«³yÇçwS«ô?ªíXH‹8EUafû°ÒžN?ÓQ4 YìæG ¤Õú]{ &JHÔ=Îը¢ {H‰±üÚ¢(»uªÇ-þ&ô•Ÿ«×¹Ù!#Zq¡–»xõ®Ìêa¢Ìýh5ZnHûuv%ßtì&üKˆÆ÷1ã×|ymÒ-ßS>êÜK‘&ØoÙÍžÛ5n—ðæš$ø¶ƒ‡kÒ»­Ÿ…š4ÆÅbw…7–#žpù•£3”!¿Õ½L˜šâÑZËïùêU·ãÇ—ÕEÈ;©¬WmzmoWQû9)ÿúHÔ/É qŠ„YbJ’çÎLÚÓ&ñÎꕈ}ŠIU¦Pð‘ôÊ7úxfOã6Ã!ü½ÚP-/Fí ÔσŠ)ûŒ+¯×õ0Ö5`¶©ÌÁ¡™ÇФ PŒt~ íaXrBJ¨cûÇå]Öë%ˆ/©u%U4^wŠfu©ùŠ0x.¶a{\(+¿4djJ6qZëCÑÔêÄymÛp?òµÕ1´ ïË÷Žów_0_®á¯iòž Úuç=…ÂýMÁäXÙQ²ÈW_s¹g U|‹fó’CÎ&ú¾\—™¥ü^@‹']G‹ÞÒWá]€) I¯‘óQœêÙƒñÚ½éý@€r2Q{ sõ-|y/ÀÍ5öýŒfÉ]‚ ©QòŠ1tãÒrf’Fé÷xϵ÷0 vRѼ¤Ô÷>³7å£Iãc½¿@ôñFÂ죠Ôríe8üAgG¶8|«\·H°N«ÇKo^Û§’ljƒ›æS<ÉÁÀ)ªg¨<E¥(˜ƒAø›xáô4ËFUaVT‚>ìZ´ßÍÊÜ‘È6”ñÄü]æœhºüKǽcVddqãÕ4D§'Á¡%ÁŸ™é\ùùüůl4T8AÄÉ"\(ë”æ¬Íϳދx°&““‡ƒë„EÁÖnŒìk%Oùç8Í|ªý&÷ó_Z;(6{Ëã „nÊ Oè—~0"ÃW󠋸Lýv"Œþ5öñkòT¼è'…ŒZc'—º¶ZÍ>²HœßŒßΫ´ôòôèŵiÜù³Ë¯ÀÎü`I<ë†N¢ ¢›£4öÄ¥ÈE´y7˜ÀJP¿Y7=ÓØ;XÅéõà…æ5ÎOWaÌ;]ƒdeZoËÅó|¬šì™(ö•,–<{!Q5¦îµZ”á2öFޝ“-18rñ™£ˆ”üs¾I¬ªÿÌ/ZvoˆJƒÕÈñÒÏ'Èë6a·]Ä´¬_Ÿø,ªÀˆ‚9µŠæÌWD1Æ]AâŸA8|˜…ÊÔ©òà¡)bº¼@Y_Ó…ö“Ôq–>‡ò®_ÕjùâÙüíß§&Pú¼#Ô¤ʹN.qÃUÞi˜‹É½ä‚¢”?5Ø%&¥ÊÒ¢ÉNúŸ„R?7Öꎼ#‡HL3׃!Š7|v» "'ŸÓ /'NªÏVéöNýA¤ Cq}¦?÷‡Ñ€­Oã°Âª‹ØoÁ …—AP©!Ê–‚ï>^s‹Œ¦¤–}­¬‡>FsA=£ÅµéWa¸nP4 ½zz¡ŸÖ]䆿#0·lMó…m‹Ù|:†·?ŠcFìçÈwm:ˆ#rzú¾öaåQ3dübôDÔ9ƒ´Aº›ÔƒßÇ÷) ŒÄN=𚊟 ÄvÔ`–f…$¥Œ jÚW_úÝÕø@¡ÐÚt92[Ý•Bàýt¾©­tGºïŽ4ùÊc¡¿7^¼êÝÏø5îÝîjy$—Ý‘ÏÃÀ‘— Íà<˜–}ÒMÁ4ÃâÇCáKû·Ó!,çDÕ±®šÇàXé͹?ŽY+ÿB Á3ùÖ’Û¼Éñ“9õ#C@牨3âÄgSóSÿq1GA8¼"îÙ1yb›Ýº·#lHà¶8+Ó~/Ø@èØ"É>„¦¸újr@‡3¼=Yú(„¨Ö£c×RO×xÊd辕G[ùšýFÖîDº»€Kþ8YRvñc,oLy%g/æ=ÍNÊÔgƒÖ-Eè,RQ…‘[s¶5ýOÒ5çf%Aš×Ä9&¹\0ÓÁE-¸ô#§*¢4•´ÜåÉ€²`NÏH!‚ð9¬‹á²µdÈ9Õ }²ˆÀåúÏŽ#»ÁPœ²˜Ezv¢¨ŠÉodIV±”yýVA‘]b+ó£ôvÕy‡Ií?eiwGQ)9ÈÒŸ÷’m%¾Ît•u/Ñ»€]@ÙóLŒ„Q¹ÚýnTË{äXÛM˜¶ E[¡$kס ›/ílâ dŽ\?•õŒtù4Û-ø¡\¼®\@ƒ>€}hâ¹é§4áÂçÉ-¤r£f§¨íá'j«FÍjÖÐo“‹žŠ‘_ÈÝB+±Ø°åûϨÂl‡m+Ž2ÉZ´ªÄÓU­ftzB;ÅL×½ˆWÇ-× =ô¿<â ¹”—õ«t½îNQ’©'a²÷ÊÎ AÝÙñÑ#{3³ã7X[ô šx<Ñ9JÆB$=„ÞyHÈÕ¨­wuDG ¥´;âÛ¸éÉ|ÏBÛ œã¾K|&=éޏ¬œðçèÝbÓ)ô¼e^®ÅO‹ìˆ(õM¥ß¸,횃 x¡ ¢ÂWËΌУÿ•ò^N2S¦|úþ¶ÔwQ©³’`: e”KæuáUñlRý9u†± ÈJ¸CO,3rŸúüq°˜¦}Y¾Ópàdܸ‰÷¼Ûij*è"…ré^ÉÖ>•Þ§|ÊNçî|RÇnQ†‰u¬ð‹-¬—¼€â. †™] ¤âÇñ\uBâ¾`¡÷4Ïô=*?µa "ñ £w!—Ò¬*3EÔ?oÅhsó~Í’Lc`K /®rC™&?r7d?2+ýÚÝ/M*\¾'†šÖx½Ïxú<Œ¯Þ¿¡w²ÛPÈ ÁÝöî,n Öƒ%öéÅ k¯ËM_&{B6AE3ǦHD!)v¯Éh>þÙ^x¹W¡‹_¼3é C8Pþ›~[ „†¼ ÚX¢š}L1·²ð ;ßáÊÑd…/{V+VEU4××áß_0>CÅ,i‡)c¢’ X#ucùÆ/ FåméjYªkt:Á‰Sm)Ë¥ïi_/•O;Ï?e©³(0¯žºüt i¯úk+w´qªEÐ[í)aÖß¶ÿ+8èWÏÆ3²¼v‘áÁúÙ×ø¼uC˜,ÖÈã‘¿ÂeOžò*åºäk3ÓA¥cçã¦÷øª40*Ç­ŽRQJÿThltüê¶tà†ûjál:Ÿ+WéØ+ZØt£„©ï“å¸4ÍÊ€ ;÷­&ÿªîØpè2alàAÜrkÓ9Îû[Ò!6DóWPÛã§ò&Ä”oóø–¥êÅz–³¦5¹#'¹Y•ò»áCUáž`W6ú¾&Ì™²Lü‰’Ÿ;SUSÍÒêÒ$ [ä~Ø9³" ÛRúÔ. +Ž;†Õ ~P-F‰ ê”í3&ÁÅÄT?cìë5kÅÅö£ðd)íæ”‘ÐG²ØåìøiÜ‚5ìªʨkŒž€i§ÛN§à£RºÉ*m{ÈÖl’ŒGúVΑY”ü».õ<² GU2Ó4ÖéUEÖ{ Ùp½">H4Li8V ¬Ð.}ün‹¢$Âx'žÙ‰eíÍN¿žƒæ-Iª‚ÚÁ!P{F¶Œc`ø&$Öe†¦'R·ì¸ÄeeB_±8Ü’¼åc¸M€2MýÞeÍ‘GÎ §÷µÛ¾Õ,£;r¦öÄŸkê³ôS^ƒ4þZÕpJ Ö#Eñ¶²ÇìÀ†möËÞµëìèF ÛöϮӂ2YÔÅ«£—"â½i‡¤„Ý¥¹w—š,dóchð°6>âý !È5qÆkŽWíÀNóäŒxÍG~®Ù_Íqxœ ÔyílNjřñŒê—Š,\¼bï,J:=¿o¯”;¸Qøì–ÉØeËä8&†bmqJ.CèŸ×ðsaH;)Íg± ¯_xã·Ö†<£Õõ‘·¾,Ú[¦Â.˜µñ¯„'檥(ÀïÁQÆ÷ÏM6WœîHº;LÑúqæ ãœOÃXx¥Ir÷yŽ”v}@ãÅã/vÅa ©d½f¿zE„¼5Ì-80$'Œö7óŽ‚ëʧˆÂÓ¢Ìñ ”^޾æ¯ÅJ¢šR*„¶¹<±ðœùcÏ¿«?_Õ_Ä V¡JÛ6ÛÅý¹džöŠ–º=o§ë­I½ÛŒÑ‚—¼ï,çâ\ýÚöD,@cÉQ¿Ðß*f „„–[ó.!€÷€6ñ{w2$’³ ?n¬|»VOW@ñð{MuÜÇ}LjÇÉ¢šü.MJòààHEù=Å”}/ÐxIÀä‰È/Î9g?œçšßŽh#Ç·×æЄå-8ý½)ü}ô,rkhà õ<œ¶­`b‚ê…$=¢Ï‡*]bóáÞ1aå9gC{&‰ˆOÊþF&ªhUІþG%ˆ=”uçº Çʉi¦‘;±/;·‘CÊØµËg±æ[ø«ánÉ| ‘–‡&Ô[ß㮠'碫.«LòÃã²ÉNP—Â{¢ôtM˘WyëêÎWìæ´^ªöDn¯p–©®lo>Ȩ+r™Tû .V"©à|¦AëˆäŠs™‡œÍ®=Tðš@…N1¾Hm)¬-(\e‘’(0ÑM¯(ů$˜‘)îÐv”q-ï೑!˜E%y}åÝ(»‚Xm²gu»tÉé YòR¾V¾*•AŸŒx”µüä sÖËœ9A0ZˆI@:øÞ®uèxᦷñeÍ»]iEBŸ‚ï"ÛIèHòr×fE•ùŽˆ/Ð,<5’Y\´ÅÝø•Bã5ZÉ/À0Ã5cýJ´?~mí _§n}×ü+QZf$™7rbÓì+4'ù\kà½%O nJÎL¥~F>[ûYñW Å\¬n„TW»») Öq/iƒ„­-1uœ¹¡HooôÈ‹»²Ý²‹ÅWa;w¥;%“ni`ßfØÉÂE œ«ŽéF×Ý«ìMËõ†Ê+¼š‚l/ Ë×Ý HR§-–¾úC×åeÌ¢ßêGÉd õ*Pëb Ž›ÈÄOL‚“˜gË¢E‰;=?šÑ–áùRËÜ…Aö¥)€ìØÍp¿Ýü®±¡&°vvøe¼ë©|iÖg~²_^„ð¾PΤà®+ÖùÐOÊzþ«Î77«£Áó÷Oï0Ħ§MÒ1Xp,}1ƒbÆ™bàƒsÍKbœ4ÂêºjY|øüjŠKU]p +ÑÈp­6ŒöŽ]£B«]„#¡¼NzR—“K°•}/n A©í)±>_ ~„Ï,2”oÕÁ†8íREv’(j¤î_ùUæâCµÍcÕŠæD¯r ó´ŸÐ á¹hÁËgÌÀŸ^Ù”Ðy.*ísîm‹Ý>ã*OÃÇ"ôŸdW*‹ë%§ÿe?=J®)jRŒÏé:#©!Ãh΋ßÛ—c`¸!‡Üý|¼êHM;½‡=ÆOýTñuá‘þUÙ­Å)ÖN3‚ÞÞ)'lwc]é©Nñ¾Ëé+þ²$s™‘øÅÓ”¼ú½ý¥ùù"/'³Ê¨ãíÑjÕ*žTWÓtx"Ý&}zw ‡Z¿UZoûãý:¼U7Bt7cDDÈê|ð3j;[,PØ3òÎÑØ9íFEXB»Ñ>2ákÒù!I•KË?3e=ÚdTÓ$ÿ£õ7y9þ`Áæèh€¿†¬±L™Á²IwFInv†‹ÿÂá ¯eÄ-ã oxM_,2‹¦ÚþøžîkšªŽ5—MÇ&;fücÖQu©39ºFߘ×–ëTBV•žuh{G ,ýß AÕ Úa"Þ¡F{“ FöY¿…Cq%ºþ*.ß26A(ÑTŸK jR6²w8ERkÃáXK’¨]ôŠtº×`àµÏ&GžHñË®âr% 5":ãùê¶–=`+E*Rƒ´ÆIYGô·U¤Ö>’,Þðïv`± ãu*ÊcSQ”B†ÈÏ’_¨€vFÍ”êÔ寿U—UæJA*Ôü7Ó§â à ¬Õ’ÏËðï’á±…è·fQ%ˆ*Ö)R¬¥±`›k|(Ú'Äm %Þ¼jß [sÚ¼ÛÑW°©SšÏt£®1X×W;˜ux KÒ8)çŠ/éUioV{HDÃc¢^¸ÝZ¼“6ã£1´gU&öVil˜q©µÑóòÁX3%Þ\E”ØÄ;ô"ZÞ¬hÝw­9ÐÞðV ÁĦ¡EŒSW,ÖjÑßvã†@ìÚa× ƒ> ;k[þD•Œ¦“JGI§¤·‚ñ–.Î1ØŠÒt²°»ÿu }%ƸɈŸª4V7HþMñÒÜLÑ!NÿsóäM[mÎçæš»¹šKcÑ$#úæ€êpä™k3¼–£ŸÅn ØÊå˜×xø™ÁT ›³ùïšêtªLm;!?f{Ë¡7a…Møá£æsž½L«„e:eºæ Nøm»ÆŠe£Tî|¶×$Þ´ªÖÙ1*IyìGFEŽ.·èY ü!Γ‚,¤Ðä?V“rØ×ÈëˆàŽ“PŸl¸ìûgLo5±ÛS…~òªiÉ Îž¿ð¡¢ÆÍBšŒ„ß Ê„?ð 4¦gÀ±õæ‹Qi2ž1>´¤!æVúÖã鎟`ç¡ÑÜïèëW…*Q ©`LN±—˜Ì¿¤_üâˆÖÿÄ{ÿZ`ÆïYuxØ–&›¬_®$ã ßà{-µ¾§—gü!Ò«¼Ez®Úû©Š—Ùz ·€ö=,±æWa˜hÁÊÌ%Îg@y|‹CQy: wÓÖ/†>úÎöµyMîÜÌ¥Y|ƒŽî|Š{!÷C_YPžÿv¿¥µÒ*™Â>ߌՖlrfcÞˆ¦j]qëC°‡¤w*dÂúýQT;ªLJP× ±†tipË Z2¤Vü–ràÏ0 æXgâat±åH8 ”Ý׉ÞSº¦›——æ*öŠûú¥ùGK-š|¯½°Ò¯ìOYñ$p+ÎJl7,j963Ê7_LF#IoR˜e}݆Ë(¶Ã$÷ù&£çÒn¸5P¿Eʥݴ’UŸc÷C[êO3 ¦É–.!޶P“Ó˜}G° 3Ä­_#ˆÔf YÜ"i·°\Œj± ‚ôƒT¯äB>áq!@ʘg4uQñR¼BèàÊØ‹hÇÖ¬–ºÜ‘ðº§øñ=-’\ …–µí6~!Õ:;«Èñ$CñÅÓÔ’”×qÖåž•»n«0ÃïñŒhÜ ‰$÷È‚®ùC)¾h{7€ô†Ô(F=e”*O©ÉSyaè O]ÅGÓÓE¸`]Þ7e86ù«a#V”¦Rœ¹Ú,†m2Jt“'D¦ŸÍÍu àœ"Ü ;?(¡Š,ÙŽ=Âåe³[ñOe‹ ¸UERÂN|Ù t?çH¡ó²L|ŽÎ’AÛ¯ùÀâL¸Wg8Ù=GXG„ËLÔÁ_C‘о;‰x¯Šúì*-7ñÊŽüñ¼\5=Mí‘X ÁСL/ó™® ©6ö~›Í"((Ç’·”§¥\ý·$¡ãw(x[ @KÑw˜6*‹{«ï~ÊÒäv¯Z Af¹h3XxFÇÁK¶Ä›Ðšo,$ÏUH[Á”¸aràEç×àw:ÍVÕ Ì£r¹”:+iOO>r¬õã±¹C/œKëm«ÒÓ=› ÄR-V|’&5°‰jÔ:9=Àå ©+nl{Y“~-–*j(|8’gìZÇ1¡%óð9^~°pžº·«BýY2µÿPfΤgX×ýýA§¼­©]àWgß²ÆïsáJÈJgÏ1T¥ÞR¼'ǵýð—¤tM©x»‘™~$RPé=ò…wd`,”¨¦Î æcv¯vEä û;J ò3<¿oÎ!gÜŸ¡†ÏZgÖFnýÅQ¯q…{×è1-úÐ9NÎ;4î1Ðésw—c{Ì@‚wÇEkKñyj hWoÏVS£’sE+e<:FžÖ*gb %8j0Â%î'’gyª,ø ‹¤Ó×`ßeŠg[†ŸŠ'¹À7>ð®ÿ .³ØWl$P,ÖúE´Þ:X^»á™ížå-y~ªŒÃmãÚau¸ÄsÍvÌÙÈäW0µ¥?,VÿFíÅõþ#Ð÷Eµ›ñÛÕš22ÌAr‚Z5‚Ö}¿ïÎ.Áb)®¯í,ŒÞü Eht 8ïÞ  ;iq+”0 Ù^Ýqæë Úù7wõ„ÅkwW8™Û¥2HË<…™¢Z—ÊFZôSÜ@<â¢9Y× bæÁµËr[-̉uh4ÈW9yÇÞa+ï^+yù¸ Òñ‹L³MYµî»| fo*E ÓÇçôæóR<©€ë î……@†òAïS4VÁG¦E[ ¬¯¶žHí¾¸Œô%ʲA+ÖŒk UÄUׇ‘v´8.¯?SÇ—¾^GlS†`¸þh 1ÜÁƦ¯Cû e²E›1qk6o‹ðøyÒ‡ŽYoCïwÏza²¥Àð¼~˜$Ï~OÅéN}˜Q*oËðE"\ƒvd‚ñÆ{˜h-©~—mÑ><æuÓ«Ö!>{•%ݸInNF¤´ynVÔÅÒ£ÈòYM©›(é&–e²tl÷ÃÆ«ˆ7ŠtQ}s^ˆ/~·†¤ñ8“<.ÑĹ-L|‹8 àêÞ}¹˜κÔiž€¼nUV°•Ñ­ÍÝ}1âyr­×C±µ1A¼ EÃvô „ }‚ò§¹ÎþR‘9¡Ç#éü9Yñ@ö¤~³˜3¯ü©Bož–Ó©.UõAs·ì »ÞlŠCSïg&ßc›¯X_HR8ÝÌ‘8ÃŽ9€Ýem£ÃGÀz‰×7Öj+#_†«ásÖbiĬ’ÑyÚñˆšÔE+®«ßW„13©Ûßw*b+_”Îj 8ÍbnŒÛ¢Í¨!!º{›‰ Ÿí^~4Y%©ÖÄ¡·¶HÛýÄRC ˜¾æm3êñ…:h&ášPünE1Ã,ªƒÆZî\l¯€³Ò‹fß 5’<˜ßæ´sOu'Z‘ ®:fËyf\°×'›+ñ³:D¸v#6W¢&ò놡Sælé¾8o‘ÅV"ŸÎ~8ý¼É»›êrGófïAÂçÆjé6ýR¥GCíÃèð5"=œE¤¦ÃZýVhÌÙ•„˜–þ}²ßëád¯]dQ=þæGXøÜ„mBïu%ÞH HýÆy¾Æ7®QñíðfJTëÿ¬m¡–‹RÕÌ@L“áÜ¿ê( 5Š VCNË Ý‘ãáG1j‹3Å~÷M¯B úWô{Gù8h"©æP4wnnXФº(r‰*ô~~•XT¬¶ ‹_ê=bƒpã°LCÄò»E²r[&Ð6žó«ŽJ+"žr:²Ž¹À,Oƒ‰i¸÷l©½K eíÇ[‚¥t…”¤Í…¡Lœ•*…÷­Á¥\ú-¥ìÛ­•wF1b»ÖY°¦nSk,È1¯úËJYa™é¬Ð:ê'Im÷Ï}:·XðH2bôÙ•BÄX×- Ð𠪸ðM®{b²áÜ&ñœèËZ’ŠvÞ‰–äô^ÿ•j¦æ+ò©¹ñÉE­ 7ŠøÄqÓDI½BàD˜êÇ_X~P…ëøŸCC›øv«"ÉK¹ûP6U³%Œ~+nT\1iCã·é|(ë•ÿ¡OôÃgqÁ¥Q´×‚“ëž…$·ïgåÂýÅyN÷Ea të>Œ Ë}×:Òr‰ˆKÔš¹× á«Ó® bÛk{U¦JþÚõÃ<ÁgsóªÓ€Ô(4ØómqmÇÌdÑš>óK‘Ç®h{„íL®{üæg–\^ÈÅì}¢'"t)Í$¹69ñ8h}²w'Š1޶E16~R6õý #¥YÈ¿²ýôÒ±#ŽÅÀïDÊ¥baЂ8GÌ™ï’îÇtF¥5ì×9ϸ"Ñ̽Ò/¹+]YË’;6s)‘ÒÏj ¨¾a‹Û: ÎNä+RH°6ó§â=3“˽Õ§”÷Fô C„L¢Ù¢ÐåzôÁJ‡o-Öl"Ÿ”¼G5¿ˆôž**á`ŒZEG¥¼W°ô;="uÛ“É„ÏÓ‹oìÞÕu8È ÎjJ–¨ÖBø²›¾éz©‚þnõÓ|w‹®Rfy¢ÕKI燭2ÄY箆ž>ûÚ}­©î¡B÷'ÃÖwåS8˜¾§£%âÈ÷€}Üø f˜ž¹m(-SD~íG­òôt‡œP¼óÞ:]%†Éwå3+ÁÍLÑj£½Ð/KBé+Z ìr‡œ{‹Ój:ßWKq!Ïm0³5 *^qõˆ&*ND¿mÂôX\謗wEÔWIÝ'ø¤?þºùŒj+3ß—2c0ˆï͆S-¶_êc˜óÃ]uçY†g;¨?­ÙÌQ¤¶Éß î”QP ÿ€§à×ÊÂ)¸ìÞ@@l*ÉñWè½6ZƒÆtù|‰öüúCåË]“aÖТ'Òt+ºÛDùBì÷0ö3g#auÏîÒéOøÓÖVÞr­hß/¨™©ç´Ý A-žwa·~Òýp»ÏXÎûëqóG,¸¹ã±}ê¾[§ºrëe4®óé t8¥½»? &f Hêæd>×Ç*ÂÝ+>nIÃiòÑ{Z*ê~Š ^1>æ\ŒŒ—Â4µ@[‰‰cI>¸èŽÂÐïà#æÝWfQ˜#Sþ×¼Ôs4FŒfˆ„ÑNì†ñ"´4÷h=B®_’?±Cédí~›I%Æ~’~šº–ëQ*÷¼Ú¤Lä[ûÇ`ikÃÕeWû…–{Fm¨¸PTK]ŒR…ø¶¿Cñ—¾í·ùOÑÌœ§¨$I–;Æ:Ðà{1 +”äÛ84˜êõp“`¿&zÇ™ƒKjš—³D`Ð9SÔ° ˜z¤9Tø„WФ×T §ßù£d@ˆ((û ¢XDÁàc{cæå„Š|-¥…v‘Á‹<{~|Þ©—n¥ ?ó¼¤K§M‰šŠ”î³ëÚíÓE¾’¢˜“­S˜£¸#iá‡!9Ò÷%?¾3¢,éíÂãF]òûšU¶'­k})ïÍffs^xYzHè›jû€EŸ?‰bƒ²·Ç[|n›dú¨§ö«)vÚg›¾ÿ‚wEÈš8çñ¨ƒ(°&r»£Y%ØjÅ“MNóqö°G+,çGÛXM¤»á-¯bgZÿ:;ëœý÷J ¢eïþ|mÍV=ü8çh@0{øt˜Ê•4Ù~Ÿ@Æ­ ˜%g¾œPžpVÜ-J îxÿVßòb­n€E–K=ùe¶Ù¤$ËqvCœí(+Kz2}”4²ëLG:Ž+4¬«ÝoC¤-å‡õ5REѽžâp9v%ž_¦§]Øßý¸Y¼î¥ô×j3 vð«zno XQT³f;X­´bâ}6h<®’W¦S3x–*@f¿ñÏhÕ¡l•j¡¾›{õ’TøRßoC0‡C>\¸ŠÝw«këŸooÉêÅOñÝ>IJN´ÃÀýþ£-0¯– ÊÝC»ÿþG_¨öYz=ËE»_\A²zz]Á­ïdïUøÇþÌi³oTy¯Tô(ÿ(»#R‰­ÅWeŠ ½ýföï M²³³6öÝ^`r8ŒBwb›—ÂÛÁ¾¿97¬Ä¾ñî¾ü,»½]¬6”<¸ëQk9a>X ^„e-±PˆrŒòøÊT0aªÔÄšØ`í¤@öu’KBpFWh_dDïs3cpê:Pª˜š2NÇ \‘^j`ÆvØ÷A5§âÍY`«+e?¹ŒÆ$À r—ÝŸzœ­‚¦Œù¿èàÎA!S­0¯f˜.)G*ßi0ñ¦‚GÓ2`F¤W(p„ DËj6´É}©ì¶Õˆ§zÑî9f›»uöqõY?jzGf2øÿ¯sh΄plÛ¶=±í‰mÛ¶m¾±mÛ¶m›c÷²‡­úþBŸOµ; 6ìf1³ù¦¯QerlZée(…âˆwú–&*>€]1æ(ݳ{îÂ0!œ9IQåÆtš%ÕìÌÓT³•(Æ / b‹rØã௤n”+Ñÿã.›E-ûEvC$( IÞÎ,…SêÎ[ΆÓ*âðÝûð7Ƨi—ÃÀöEͽ0Ë(šß_>Ð X(z–„{1ÌNyÁ^—Çz'xö_Ïø•öƒrV†Z¸œÄ?4~ÙNk訒{o±ÒôCSø¡Õ «ÿZlãZv•ûmïYb-@¤ævm´»CKÆf%#LKhwÅ,43Ö,¬­rHÌô$‰¬õ^ÿPÓ7Üè­—¢< ìûÊ&]ްeú&—ådçQŠM…ÁÃñGÏÃ"©¿Ó„¥0îªß“µcm*à ÐÓhþ,s-àß 9y¢Êk6›<Ü-M'.kÃØÌ ü¦NëÙ%ù‘1 “ ·†1[›Ê)¿™U óå°¿#˜ÞZÑÀ:bƲPmµwôÛI+ääÝJ`Ñx Nô@ÈbÇßw#•´*jë5ëqÑ‘¯Ã€/DÄ 2´‘4×7>N=´sc€ Úo³gŠUQâü!–íaSö+Rd¡›A# ëçE¡§BÄ÷¢ÉÿvžTNÃ"ÿƒA…Ôê~œ™?ÖÓÇê½[AS5#0ïuí’QWY­wùlóáè@‰çùÅ:U?.Ñ„3¢º·ùDä“-Ó¿eÃ/ä›/ÜqÏÉy¥Ôèù´÷©h‰nÌ×ÚHøÏSrX¤~¥ÎBlµvä,¤05z¿êÕ¶i ÄK*õ`3ˆ8bÝ \¦L‹ÇZ§œž6U¼Á¼½› Ðß•rhu¡Gõ+›/Áø>zRZ%“b“œvË¿±uZà’Åíyݱæ5«>ú¼bÑcÝIC%'ukV¤þ¨05e·\'Z»ê£ßÁQÆe.ŸãŽ–0µÛÒÅ}@ Ñ$Q£\BEÊŠÇ(Ùs¯Å [ ÷ÀÝihaÿ•fžðÇ|%¿7|ƒHpiMß„B¬c뛀¬ÕÿX:tõ§ZkŸ ²›U+­œâ…^ÓegZ4ä Éé1¢«NŠ¥­OV½‰n”z±ƒ%M"qþ[gÎkÜı@3/¶íÏ[£PöB/F¡¯ð1¼Zô¸ÛÝbw(ÜñUxBï!b§›¶ø‚ïlɤPê²Õ`,BEE¬Òý¯b:PÞ‹EgQÜÇw™:œýfs@„ mšdxúDÙuÅ‹WQ¼ßâI‘@}Ø ôR*§ä( Ž <(¬§â»ð¢Ï¥L'ÜÓ…sõ÷‡ Øóö?f±ù[ä™ç5~‡Sh ´¦S&C e8OÙNÐ n|É_(/6¼ˆ—dÃür™úm¦­I€r¼ý=8p‰ Qmz‹ é13íîËÐÔ)B¯ÄÊÒæ¹ÌyrééG0wu§_„êà±f8ŒS;„ÓÌd õà,÷·ûö fc° XSÿ.ËÕE‘ßi {¡ýØOp0Íÿ,A¬qŽ‹P§HúC"Ý¢[ÁÚ—ðn’}Ä;#fýý'Ò7T¸È³¢~ô]‚H÷œ‘"ͰBktRíì þ•ÁQÞi¢úõ Í""¶ŽÆ Ø ŸÛâe~¼=FÇ ˜’˜qw`ºZØs§la0æŸ^ ™‚—eÎç€E‰ùÚºVc a9‡¶f(ý°õ,”ëîi™Û¥{ÃaðÀÈ9ÏÇ>«L7¿ZÚtS•c†vgýÆ~û^(ѰRÝ6 Yû§ó¨Ž[,Õ×i ºÙ³s¶)LÜÛ"çϪB}¡’™ëuµ9î«GÞ‘A%m °\ûñfZÖA”A½ÎVgÂN²;×NüIJ#N›´á‡}°Ø"Й/[5VbÃÜ¡$ˆz ¼­lcÐçÖtc¶‘$,ÅdŽ*ÞT Ê1-Ci!ŸzIÍŒ—áÿÃÁ!çø˜[HÛµœ£•‰}£2)7ß=DØØoUI(Ë3±»ÁŸ×R‹*}%y!;¯žèç™EµT>5ª"åñ¼N, Özy š¨ÆÝo®³gFI˜³‹¾íÊçž ðפ½Àiׇ&³ˆ^V¦_¾àoÝæ®^†ºÝ `È÷þ¶qùa9DožS)Á EèåÐÁäàB„»ùuæÄ«L  ´%{Š³Í»/òL>„ª«KÒ×3³0œdç9êoЩÇ`bÚ-`nè—=Kã#SRÃØD¥ ¦«D™¸«÷oÙQ,°-ôEË‘2±x¢lRÍC¨ÕùÈ÷šO¯ó_Ÿ›H6£} gBl"e-š¿^RQwϪá÷náž?t”¥Yn©æR–¸ÙQ¼Ýfƒ–i9*Ó•‹kª‡šºž4  ÆÔÓ§UâRlúof“Yò÷‚<Pƒw~ϖdŽ3<á Úå«Û¬¨ËÔKÞ6ZZ~öH†×šÇÀ±T¨@E«Ö´ŸêÐàÑì¥ïiVïóTZpƒµÉ˜mý9‚ƒ—ÿrä*\¤ÜoI}öÜë—z6h¨ÆÐoÑAÎò8ŸË~kÀY`œ¸¯eÙë+¼UÔ,Šaù‹&Ô\–Œ{³Ew¾°ß$ÏúØ8¦w/š4D&pŸ=-útEŽÃ+Ë Ì3,_zóå8·[-9 [ò³»Þ'Âu×7¤Ž‡òÈXém;?Œ#º°‚[©-'z!€®7Ì™\ Q2ÏÞÖh ù{ã™Ùìq´Ãó¹¯soi»Ù)_^T‹ çÑÀ·ïû£çë„úžI¬j¢äâì~õý®©™¸Šz?O ú6Œ0ì4ÖÈ/™ü¢î÷£!gó!OIõ$¥ê>w·;2ú'æ#ë¾('°ðúöLüg§á2ÙPëó{ 8õùØl L7!ÏØG ŠœIÁôrd¯ Š•¶§œ"5ž-‹P‹˜´F<ÔW”F½ƒ?¦íd—£–²T|ÙÐͪHÄág•x÷:ŠÖ¼»é œsc|½np8‹m&»v}%C¦4I2uˆªC·º7Ü£ïR¿?(stý$Õä³,ÛLòá,!¹‹Ìz–á‹x01\å½;€…œ…ÃRò{ð|Æ]¿á6á†L›s G§–œ¦LÁÞ£ˆU òÞ=XÝr,;Aô¡—+Š+f¹?+]'!$mâýð¦Êoï²Ôøª<¡K‡Ïîõ¸Ù¶½S¸ÃsŠâHÚx³Õ$t‘d‘HÔØf\'“ÂJ£çŒ‡wi«ÁÏ(•[À¾Ð —÷u Oê?X<ˆ1UIEƒ6Ó¡2Æ» °% _²ñ^‰ a°¬C;$Îô•R§ë}ûm[&Ôò¸æU[´D†§91G†nxšîüÇØ(ëó^ù}´ø! ¯N"Äp9û¹í·’õÔ1²”ï§+b—í4tÔß¹ÁÃöùÆG›ÆF1ýZqx, +L‚“ö -'¤ÃÒäËðV]ÕÜBLø(ï9Òôìî|¬óf–z¾â¥ÖøF™6:qžZ¦£€ÇÁaFÐ6…½2vCZÄÝRêðu¦0š£ñAˆg‰›gtíÒ”i@ò-Æòõ617óó£”}ó8à–c ]&ô݃6£ï¼Ó|¾Õà‚ zY'Åž¢æ9$ûEgZ)’Àâ2xY‰ÝˆåÁçÜÉ?¸×ì^hÆ¡7(,qdòä…ú"½Ø'³É_¤üòò$‡ê­6 ‚ªÙTPÛéhm ƒ;cò½˜×æ:ë{—Š;[l:r Åöõk(—Cëbþ[1|Ëè=¾ˆ1•G ‘'G‘ !䊟+]iÀz^2®Ïþ…íæ8€Ï§#6穦Ïå%óxáß vކ^w}Eì±´Éâ¬)¶öFé—(làââ·HY:YÃñ"ØÚ¶Ð|Ñ+Ë‚Ð8ÛËÆå‘¦RÑ–‚ÆÇù¸Û­16‚k¤ûógˆ.¸JnÂ}Û—CNç7v]Ÿ Šú!‚™ºÍžê¯9)nž¨œðƒOCЭ†æWˆÉ3"”µ7^e õ_Uܰ´ºŒ¡ÊgÍ›…Å #˜‹3ûÁEœL/P:iµ³ò÷Á3>O•ÂÖÝÃKtËË\´Ê1.wë ÇPºaت#Uµdq7ï(é/®Ôèp˜×ר\ÌÄÜ0 öýçVW<°gÂnù)À£¢?FmrIéþ¶óÖ3°½‰8Í:2¤B㳟ûlz§/ÒÕ2Y0 ´B¥óXY›ð82pß1s7Œš¤ü ~}7¿ž Á>~ÔÎE%¶dugî 8)LîjZñs Y‘GÁ¿® ;g›QÓ'VQÙaØl `­G°|…g~v`s)bñdéËédOƒ•Èû°™'uS‚º¬J^™ä"Í{Í#n{q‡GVƒaÓÿï?ððèñhq¯UMC!¹€ïüˆÙ¢îõh¢ù;µ* Ñ1uu»üãñûq4RJ ö×o,;¸wƒž.ɼ–‘¾E2ó£¶¶ËóX_áY]˜*ªÅ¬R:Ú}Ʊ‰¯ ‹jtû‰&_ZR~›“@½Èš$ µÈ¥Ï^Å‚üÀ´ñÓ­nìÜfŸÉKÿ«†Ò“ûVÍȦ ¤ÀI‘í¦IèaôzPêè»…J„G/A€€ÕÁÃR/ï5œøsï;ä~˜ÄzsÀƒL@›(2†|Hnƒù¡‰Ø î™uÑë#Ÿ´Ã‡#>–n…óz£¡ g0 g¿½}áÌïÏÐ(uÈTq^6–Å"Г\u›–š2vû -?à³°Ô'º¼õ[,ÆŠ­˜ƒ¾. Ê^GìÇRy!jaP­N-ÊÒ *‹“&ÌÿFdñÁ3Qún²WÀìkZj[! È m WìÙ\ˆ&Õø¨ôiæ½*F ÛòÔýlQ ÈJ¤˜r3;BŠÖDü÷eþZ6ÜͧæE{ ë…F>çÈWûÁ#«2|!ä)!éç¡‚_ü|ë=*“hÑ9`V„·ŸKøåűs(Åæ\«Ss ~Ìo]ãI§k‘®â>'M†¯¾ñm¹\¼’cIðóiV¡%N³ŽläBÎ|¯¯LÁ†4Å`õA1+fp–»JÊUù݆—ôu«Z¥°üË]5pàâ"M™éÁˆG7n„ $„°ù@#Š@¡lºd‘RžãC®1óŠÊiP’ðþVAQ§y¼ßÍ'0-ð·;˜“z0)±È›”#Ͻ’vƒpÊ¥ØE<1ümÂËCj8^Ýý¬c†ÛVŒñQ‚(òô:K1‡_E¸X¥UÊæÝ¿UbHœøšQäî€.{út¯ Q‡­"ÓYx¾Ó<¶ŽY®'üÃÈ®I±KýÅ þd@”$Þ‚t¥=&½ŠÀŽäVKc¬©¥Ø* ±°T_38‡·<¡}—èËõqÏ6›Ž2ÜÔ6fÐ =ô+£fY\->fYûOÑ|{Ôφ",á7V_¬ŠKŸu.j‰âMHÿ³y˜Ú­%²À‡¿f´ÓîHµÏ \{î˜%Ó¼c©çͬOj3Z/Wˆ?Õ$+„/;’ù†û~̽›v )ò1¸é­ð×£¶=/}¬z [í[²È€hÌ€Ú Gð¼ºCß‚÷N ݧÍ˰×~Z"w?¸·=FíNúúö¦º·© ”g4Z¥“Nø ž?ˆ*ëZÆæ4“ÏIê{oÒ!MÎNÚYE™«’ùŽª1o2¥ò´.˜ƒ/6EE¯Ž5 áâ6š«ÈÝÊʼ ª¡2*O>|4ȧÉcû$  [Æmì/îˆÂH<½ðWÕgþÃ:¼‚® ¾ÀxÃ"ïÖP!U Ú×ÏHÓzùDÉÚ¬›³~:Ír}©ûò:Ic7kÓˆ“÷9µ;¯\ix¨Ä†PßL(:$×ךªê𥎿œ©8•y­ËbGï(LLP¹~7¹{“Œ¹ü·1Ô>æ¸Z_q‰èŸ Hƒ½÷¦$?¶ô¼\¾vhh l4ðŒ-úvùÇS©#¿ùYˆù(æþ‡’4Ó–¥ƒãRf{¾å6¸7ÔV|@cüþÄVºštèC¹å‹÷[ŒM%“Õs“HÒÒBH·…¨ [§ÊÃð«.Nf„¨µÏtT6D•×jnîX>hhdqs ¸Þ«ÙÜn_R%?(ÌtÉa_Ö¶ÔÓ¬V‡øE‚“ÈsêbÖȯAWHÙµŠyA‘·îC½×; 5óˆåfJÈ“Ç ë' •¨“0×ì÷vÙéõÎÐè5êííëgi±yb¬t2@¨Çñ`Çz¥«4ˆ˜ +Öø›˜ø¼]"˜ R,–_MË·¼ùXì»&}U“*ЀÁýœ™réEBíÒÖÖ­TîáâTåz‚noÝKó‰FÆ‚£„–ü¶—÷x‘9’ÞŽðeai;‡J¬MÅXÝú>䄼ü ûÍ"ª’9éô Yü>´jhœþ†R$qEAóÁ"ƒ•¼ë ªL &ç ¢± NZh)Û,üÊr, + Ü"ï׺$Û×7´<‚mE–èÇzMŠ:vFþȯ©åTµ½Êd¬qFÕ”Fæ`È `|@Ä”cr´–©‚EßZò®å=Y+Õc¢î±êm½óôð†EÞ5R.œ/tÖ‚ÌUö'Þ[/¥ÉÙ_ªŒY)°²ÑõøìÝ‘ð4_h®zç¾#Åä‡ÌA¡jX¬ç­žøÔë˜8¨\Aóo´àËPOYr›:Mk(T㬠Æu)µåM³X7wìõíÐŽÊÚq9ƒ~;ó/ëœL€ƒA½ ”þækJW>³ˆ9a·µ^|å'&µ˜N@‘1*'9êVOȰ/‰A²ËhT;¤fI"Uí¾eº¼c&˜¸ÙÓªx§²($pøÎÏUo¶•¸R ŸêºÿTıžfžQ­zÜxë”Mtq_ Iölî {—Øèf |椵E/Ž"åò)iWPšC\û¸D Ŭë/‘.2wP ÍA_é~åJÀõM¢Ã\@Ź¥î¡hé¦ù‰ñ—VJy)œî<}¬Õr7`S+ñäQ”é¡ÃDäÝ¥/¦ 'ëšý²À‰~‡¿Õë# ;–•ŒúðˆÄ›žv¼'2€©¢&ÀøÑ JZî!£S­ÏŒVPÊ»îA·/-ò‘<Òóà ­õ‡SuÒKÒ÷ì–Ï‘O£wdâïŽ+¢ÐâN—8q &.»<ΰÓTPÏÀïnbÔ6,Ý*åŽ?“©N›Úàø†††WQ¼ü‹T<º^#®ÏPÍÂíºG¥™Ѓ½âf/é59]Byçõƒô¤‹¬*¥ Õ†r+›*žbÄŸ%@[Å­„\ì˜1¹Ô¸½qügáþ šl&Ñ5®X$IeÚw³œ|¦r¹”»ö ™%{…#CÜ×1¢F¬ Ë_T”E'߸Ù«'Ú/ûèxŽ‚ÕîÛCLÏBƒwšûÏÚ¿ À,¸œ+Ó~-¶—N’AºØOål×g ,dî páÐ8 ÃiNB£1/v´yÑ.t_ˆöu */{ºð]ù4¡+µd^´ËæmÆ×YþŸÄ7ÍÎWò –Ï›Š¨Š)“”!ÕŸ«++‚‰ÙÕ°ò÷1Xg§Ûc½‚êK'¾Ø}ÿ36Óüpg~‡2(ŒåS씋ñk1à&$ùTÓø×Î@UF¡“²kc_} PÜzZ#Ç—•VTû¡˜O êCkêÒËí8¼2 ä0oøÑmÜÿ,ŠûŒ±ëÉ‚ÉécÍmé~}*Zºú¯•¡®©¿©×ç]ïÁ˜´å&![˜pÄÐRÏ0›Z¡¿oñÿ"•“Cyé¿âGT •ldÅaÈÅÏÒ'韻eë„AKQ‘,Í™ù!0ä9Ñ0!Nà‚½Ë“E ¬Ÿì¨tîýC;ú¸¸ú·¥äoê`îcÀSÍMæ ‰Z!¸‰ÛtôÝq£f±~f± ¿½DÍRâQŸ6­u÷BæÇ‰ÿX©=[âW±ü¾²Mßò$êÌ!Ê·á«(ÔRrt`]ÉDHCÇҗЋØñyÿöÖ댣Ä›;W†[ÕàkuIߣ$è­á•jæ"õr1ÃsÙˆ²Dóli?<ÑÉaeÊ2 ëÀÝIqŠê¼ÌAÌ̱ޥÚ}ÐH>¹ýøj=½ØðÁ ‡u©Cégr¡AÛ 9XÔ?Jd_)_;¿œ<5 ï«ø)]y«.ý ÜHsª^BKÙDðó0­ß4Š¡^xÏSÔ|¡ô¢/ÙøۤǦÈSÌ•½¬;k‚t/‚¾¬Ìí³ÃöÅ­3ðdÉ7 åÄ+«OÏQ~M>|ˆäïñ}u2Áô³•Ç«2e¾^oˆ'| ¶`öAH[4|£Æÿ&L9P¹(ŒškiI£Üþ+ ­ö/ªï¹×žÝw7o5'äecÃ{Üå¨?ýK`¤ÅL¼šŠ§<°móK‘#ÂÙp‚z$/Ô½‰e/æáÃÓOõ•ø '"F:ö4.ƒu”±ÅÓ™4ñ!^%. î–©ð&N:g®¢Ln1—Ý»MOá'Þ©ÑÂ< ÑH‡ðxn÷¦¦{ŒpÅÀÊ®Ž††­¸K‰Vl(4 ’™‡÷˜h5àÒ5=íä§“ùÔTáyÕ&ƹŠÈYüqB¹L~JÚX ÚjJÖ_Mƒ¨Ù.êETM-wò&äe›‚”ˆ;’·]ñæ «x§MÈL‚׌%q¾€ë—˜ÆëÇ 2-ƒÞ’ÉäŒP~?«å’òfð{lIÈ*Ÿ\n:;dJÌü(žUõ+ר3– TÏ#’¢Ü—_ú¼À ¡‚z󃈴v"Å_gÃMö\wY€Ó7›^Þ:ÞPþ!ÝÅ̘ƙQ=°ƒ«éi,]5TºC×Ñfƒþ+l‹h‰âyéÉký…çf;´NŽÁ®”`œC[ïa' ²v BW¿ÊË6µpz üRâ¤`cŒÖ >µL!²[n_”±;¬=ÛÏÔÍUÄR#PsD&h¾N·Îý|ŸàŠqÅv­Ï2 #)í†j{ÜR|ôQ‚ŸqÚj×Búf½`ÙJC.Á‹é*k:cK£ÇŽ«‘,ˆ]ð ”evÈ*wPâýÒa.C˜í\òxÒ“7CËäI¢d®qjåô4‘[Ød“õ!Âýàn³Qéï|ùÇ‹:Á ¼”á§#ݳijsÂÀÙ×n>(æuøH^l½×ŷŘ%Æj¸ZŽfê«¾Ž”j $<圥W°|Q«VŸ Û]«GýͰeL”vÁ(‚9, t×­ Àâ1’–É"ÛUTzƉ3“…Ãy;7æxH/ ⳪oyæÒ D'š*ЈH¶¦Ny8jÝ´jï¼X×H¤N¼nî­®l!žS<¬\(Ê6X¥€¸béôÏÉ–¶äù¦ü²^²r1Ü/]h°28êÖ4 qÿ:sOѱ¢(ûI†00Cb9Ìâüá.t ‚'Fh,êø‚ÜÃ~³^ņoÕ×ÜîìtQà9™Ï9vöÆœ~È=<ÇY’¯Ó€3T3­¸µT×(å%œ5É"Ñ–(³CÉ({_ˆ58;ÝÕ‡µ<î O:ñyÀ¼Í8…®7Ü)xë¨P½nÌïÒËP hªÑÜXMp| DݜÈ)øT¾S°Ý°=a C/6e³JÖæ#îõ^\ŠäÖÈpøD-o»’0>׿5€ÀŽÆ‘c¨ám§žÕÆÑN±w#z|^–UÅ[‹2ÂàöÖ ¾Š}¦Íí!‘΀)¢È«?zˆØß³QÄ•×틞mÙú@jp©Kf¥¨ÂxicëÊÙˆ_ȬÂ\‘í;!½ÎêùL °ÓY¢"·:êF&Î=­EØFx®¤·fÙWOƨIZInÙ(x¤:àµcãƒu¼mý°ñÖmÖŒíw jß¼x¸ž²y˜ªÅyž'PkqcðÇkA¬øˆ%‰e¨ÒN‘ŽÚ†z4dü¡AuÔ~5â‚I8tô5µK—­]ˆ9Gçïq”˜5’Ì®*à ë±ÂAÞßNè›<çè#÷~3Éô%-=Lö ól1fùhop#™´M ;Ø249óÓ™Ç;Qˆ(ßÁY™ªb Ø–š)I ñPh-yª{’üIJH±`°âÝh棙ÂoŒ`p SCf™ •úò½míQY¢’)<hÒìú­áU§-jc+:¯Œ\WŒýaÃo PEÿüDŸEñøø(ܪYÆ·ðÂ#¥}ÈF¼H쑚åË¥ªÓÿ{¨­í¡£ç„ÏÌŸÿídiµ´4s’ÓˆÌAgIri¼rPÀ³´¿ÊFq¯ð‡…,e²‘G 3¬7V€E®Ðuá'Ù•ìæÓ}Tž™Rjz 3wJâüß|âÞH¡÷ k Ïœ&Yåî!¤fh6Š¡xÁ¡Ëæ)8›£®dç‡&f<Ú¿ecàõTÆ7p;JhA·o|_`{læä=—àÇP[‚½ö)0Û¨óLplWbŒ&USCzxºÎÓÝ[)¿Ñ›k|7Q‡03MÈu-Ù…;Í 7ªŽÚœ3u޽@Q«?ÿz/\…~ ÂDCfÜ·uH£ÖmMó«¹s䋰;Ì㺴ÌM ‘hXÐb¨CŒê¯rÿ¼[>r*$<4û6Ç 8“ý\ @·Ç†'dH…|xDÕ}‚0¸®ø’¡åÎo¬†ŠèÜdîôÇløân#ôª¢©µ¯j¶w§ß‰~@$VNTŠÀ`Çöƒ‘{í -5I[C`È)«×ÞãVýIhCõê¥Of§ÿí0e7EŠçbu1ªxÌÿ0ì¥"™xÕ;ÔšfêÄøþOP´ endstream endobj 257 0 obj << /Length1 2768 /Length2 28892 /Length3 0 /Length 30426 /Filter /FlateDecode >> stream xÚ´¹uX•ݺ=Lƒt— ‹înPº¥»{ѹèî”–î–îî.éi¤C:Dø–ï>gëÞç÷ïwqãÎ1Ǽç3€’TQ…QØÔÞ(aoçÌÈÊÄ•“³·³geaTš»ØlL,,ˆ””¢  ‘³¥½˜‘3ÀílP0q§‚#XXx)’@; ì4{ä€ÎFª@VÑ?@ÑÞÉ™ÑØÈ ìÚ™[ÚiÁ)¢ö Ks çß5ØWú-Â12±¶ws²¶Ù™d˜ä˜òön`£%€ÆÞ` ´0²1Ø›Tš5qe€¤²‚š¢ -¸°Š‹ƒƒ=踈ª¨ªI2Ä„åUÅ@u€¤šŠêﯪ@;0s€¼*Øÿ»8ðwºœ¸ª°ª–¢8+óï5X®@“åï¶ÿÅ Ì ð‡8Õ doûO…³³3³››“¹‹“3“=ÈœÉÁæ~ª–N7{5ü´þ#Œ‹)XNg à¿ üÞ€¬¥ ÐÎ ø;IÂþ_N[°”à$°ÝùßÄÀB8ÿ®ió¯p€øm,ŒœþÉ•UT”ØYÚ9íŒìLÀÎFÎ.NÃlàO )õ¿¢. Ðïrÿëý»ÍÿR±¯LׯËÇÈí¿wÌÈÎÅÉó/mþsÙ&övN–NÎNÿª˜YÚ³wú½g–vÿØä„å¥%ÄUTeÁƒgÇ(gVÇŽÉÙÝùŸèßõ„ÅdÁ£ÈÍ`cc°€‡TÜÎTÔÞÖÌÚ ñ·|b–`œíAÌÿg®­íìÝì¼þ¯ÝÌÒÎÔì·ò¦.Ìjv–Ž.@i±ÿ‰›ÿØÌÎÐt7±`þÝîŸiùmfýmËàãå`ï03²qúXšÁß½œŒ\g ÐÇëoÇ"DVn€©¥‰3xÐÁ‡ñŸêÒvföÞ™ÁLþ×õ?#@óÏA¥ŸRS{;€)Ð ‘YÞÞ<4ÿÿœ³ÿê%ábc#od ¤ùoIÿ;ÎÈÖÒÆã?"ÿ+Bø›+¼=ÈÖÈæ¿|–N–î@SEKg‹Tü—YÚÙ<úÂvæ6@ðžücRû}šlÀc ~ôXþ~rY¹¸ÿËžHk; “€‹÷¬ÂñKÿ›-€YSS[TF„þÿŒÌ?aâv&ö¦–væ6N.€däÈž6NN€+x¤Mîÿ €™ÉÎÞœppqö˜Ùƒo&'€Yø·é_ˆÀ,úñ˜Åÿ¸YÌ€Yêb0KÿA\fÙ?\Sîâ0ËÿAà ÿF<àŠ¸ƒòî òq˜Uÿ ðÔþ pÍ?ÜAë߈ÌÅèGÿ±²[ƒŒLÀE3ç¿Ìœÿcþ×$ÿ;™õ_fk óÄó²ÿÛþ_ `&&ÿFœàÞ&ö6àéø_ Ço‹­í~¬,`ALÿ‚à–À?À*ÿ£×o¿£‹‘Í_)`Íþ¤€¹™YºþUã·ÛÞôW8ÄüOE°ßü÷ ü;LÔâm°<@»¿"À6Ë¿ Xuë¿ xé(r×hóû üñƒ…²ýYÁjs‚kÙÐ_~ðªíÿÐ'Ûÿ‡¼‡?np1#ðõò{ÆÁú?ÖÿÜ1vp/ èŸ ïß¡\ÿØ,íÿì X2—¿VÀ ¶8þ)ÖËÑÅ|Ãÿµ3¬`ë_¢²‚%ûSó7ºþ¥)'8ÜÉÒýOS07'#'‹¿J€©ý!Ê ^“³ø×fƒ×îìfÿW¸†ËŸù÷üçMÀÉÄô·€àírý ‚vûët€‹ºÿÁ]=þ‚`ñ=ÿpWò‚þÅà?vŠ¿ïú®1–?O¿ÿy ú«8ƒì­–¦àÀ¿BäŒÀ§Ì]‡|±‚íàÿýIï?Pþ¹>ÿʱw÷bäKÅÈV›õ÷!ãòùT“½ŽüsýŸÒÿ‹¿ €@w  âÊ¢½ °UJSh©¯xÁt,%/Ói®€¦L<ÌJútÇ[|±Ü2 `a@‹U¡½¬ŸžoR€]±&e0ŽÍËFkbåÔ©’Ю‘¯œï[Tqá¯9êLjrËþe]d´G29ùZ_8f3ÚâÛÞÔ¾‹òvt?F³M¾b\%“é–µ}˃u+šgmÆÙ`º/£v¾]žî„t~}ÄŽ2ê^¡›3ÌÅý*çÐÛ®MŸ’¯ªyÜã•ÚrY>ún>bS›1“ý}QµP¶òùÛ"ãtâOÙ8Nù‘–6Ö©Ó†²ËUÐÌ£^e$*‰T«JÊĆ*ïPµEýô!Žš‚Ît­HmJ{ý­Ž­Ùu§ß‡}åÄУ©VîN2ðãHíSÊéÎ µòî)çâ}- "Ì©Æ'ræžeÕÉb$›\ò¯I¡éV|ž—Ïzª—”h)%1"ô$rÚËr0j ¨/A°å‚§2>nGÁÜ$äG5Ê1:ZÊÖº¿dšˆ#…^@,ÐM"éÙá][!ª•óca®@ØP¥3{»íº¤‰{%¼íßz–»Îèö´‚šýªY‹!‚‡:¶oN##:x(ý°6TLúÁ»vðD¼ï™ÕŽ¿ˆÿzüjþ¢TA6;æiïFp±Ý1ÂZ’7üa@ýPß‘ÀögaM¥¦üKH±u¶œ+)<dÃôž"{Tœ[±€:®`¡ö­)Š©¨Èfû+–Sldn‰zv¿0Ú'˜Æ"К¦Úh¹ÍzøçLÒéÕíCþ¢°³ ‰_Ã…[·“Xe£órDZQ¥zµm7(Tʆ¼lL|e"["q{|S¹³eN”bÜ“é?J]wi ¶é!Öׯ|Òçxr KßOóÅ,ªyÔZÃ{ø#¶!\ÉàMPé«÷1^3›»Š™+ú™¼YÀ­c˜Æh® cÜà Çíð ¯I”ZLï©í®¶D«û~O)Uxh…K;ƒNR(4xû ¥ÿKœ]„v35!z®ÃœøC¤jћ՛D¨o­ƒ¼ RWzZ&?|\ûføŠK¶h¶Å©·MÈ$]ŽÞ‚ª¢: ëžSyüúìÅË3¤Ôóš³õ*Ÿð¼MÊÈòcÙ f®×†£ó¯½ÑIÍj±dó()—Ç$Yu'LQ_¾µ¢y«óS:6!2¯::êU®s¿PUKgöÐÂ<µ3§Ö|DÒ1Åc‰«Å@ѨnF†Ë°£(Øñ”žŒ:úüJ ¸Aá)LI×F”É·'xàˆ"h K œ·ÞáË ú@§ì×›šTêëÙ‚üö)u¥czíב옃!l}ƒ?×¥¡$üzÙ06ëæÁ ­‡ðF,zßòÕég27  ü’À¬¬ïºˆÿ<\£è»3²úd[Ծ÷f¥¶OÉ©é3Á¾­hÁîâ¥ù\Wä××Ä'5ÝùÅ`9•÷2_Š8RJî3=K¼à(n=ÐN>gÀ’ÿìøì8³:á‡iÕ˜ÀÈú@fT–!èDk™4Ú¯¯Ö]S;ëfniå¸Ù¿tQpg;g* Ov7c˜+ß1ZcÅ$(ðüÒqéqª0ÙíÛÁÏRy‚_“>ŒÏªo8¶ñ‘Ÿ#^¢ ·• â’R¡íû^÷DÑB!ªÒS1òudf`'DýÚ=ˆ£G›~y_†÷SáEx/ö™úáÖíBªlÊ)+» ÙÝí‘>vÌìy¡ ‰/M§³M—Ó•_¦qxø¾âv×-!6ë JÑåfld ØÜî÷Òwþ¡n¥µIYIa&›D¬º»sš"è¼…¢½sN<ÎÒT=¹3¤F¹›Â$bÓòE¯v†º¡Ê)mK·ùWüçž’t²È™ÀÖ>Çÿ ©ÿP2±¬¬Â¬ð ȇµäèDwª¢˜Rƒë‘¬¤MƒaÓäòìaÃo7›h…Ðû™P0¿ÂN’¨#DÂñÇáÅ‚=tRЖšôó:ëe7Œäk\W%Ýl×Ñä0ožŸÒ•þ‡]?ŽDºÙ¦²‹ž¦™{ZV÷]¡ÜºÞ­IšËâ·–hHÛ°¹ZVøNE ~‡O¿l8£<Ý€0ïʶjìîMá37DË»0MêÏ/¡CùÖ{L2¸Ê¬©u[ú#ÎY$Êðƒ¤âÑÄüf{[ÛÆ” äÆ:h¤¶¶²M´HÄ+Í_¸•.óQ*Sï¡I’øVÒ.Ʋ¾G‰ºjó3¾¼””IÏÐŽ"Â6 0öæ2åî:>ûòâyâ‡do`ç\ÿðÒ:+âbØï€ÎKȧ@&[ûZFFõÔ._z‚ý¦±(ßý×®¬Š×•´•&³ÒV0”Îj-QËÚrUcs²AôÅ‘md†p£zKÛoÞ#yåZH¾Äªµ¬ñp‹j‘ÑkõkÏúœl¨X@/gÊò»Â)МpJ.õÂ6(±ƒ÷öÃÌ®3!¿ø-«‚idõ4ÊþÛ»x#åGžŒÆܾ7&Ø;‹½x|FwÈ`³5ª­‡û‹iñuG×7o@ƒµš…¹43̱ÁeäxŸ ÷bÖ¼t;ƒ¯ $DzuO?EP§ÛQ-%S²2g8²¦’jN)™=!Cg·oa8k{&¸? N£ÁJB½º6T¬šémjr6iº}WV÷£­/5ÉWt ™G?xå$C[Lþe  6>´È±röÞk:MNW"ãÕh¥äó*¤ÛX³WmЭx,½±?úů±>»¤ÞìÂb91Óa>¡N+§™ÍÓä–†(µÅéÖ‰JK´×b×›<_e.EHþPù€ÌC‚«yБÉÀ3¤Àé À»Œˆ!à,P¯ïà|F¾»Ù¦RÑ/Åœ(Ë{Ó Vˆõá}ž#Bm®ÏzÓíá5?Ç_b”–i^Ïå2#Öj´åŸd(߈Êöée˜¢79‰!Ç5"íÁ˜ç~Úôw½BN¥m?!²S¨IÓÉœ¬.åDïjé/1‘ Þt?s ofº HÈe}³4ñªo`gH`Êtª‡¿¢Œì8O¾HÕ-ªA| ¦ù”ÛÅè½õB>CPYÅyæÜ¸GPä¸ ð íbg™ Ô?×-væ]}|Þ80›Ž'Ã7 ¸šŽÓ™•¦Ñ|óÞôûã÷J”$Ù]á5/q}™Ï^pvqãF“7EòÆè>t«DB:™ ÃËv‹Ùô£0Ðòû-xœå,ûjÖÙ‡ œÙƒB"íüT& ¦ êû{/ª€êé¨Ô‚›8(@ù~në¶¸à˜Œ†2=œt°©ÜÌ­¯®,¡5=‘y2r×X˺’’þC²»;§'¿¨¾hjd¹A§í@¸’#!Ï ñ¦2-|7“–&Õñò¶Lƒ~dŸ9c—#‹¡_#7>ÅËÄ0ÁçF•L1g’\õn(_i@ﺓlÀ4JxÑBšÇÜŠwæÕÍ)#S”—Q€”=wÊÚHlØåÖŠêMýž”˜öná-Ú$Î ¾.¶ ?¥Tdd…Zûs‚{É™•Hß`]ôžhËY•§ù¢ý÷|QöŸ›œmp‡ˆÅ]ˆØ8×ä¶š>Nã)1áç¹c7JNñÁÍñkúT1dVRb’q_ÞÄ™šˆ°õnÎÒËŠH„Vt›£iD²Ó1† /EÜ íQûß“¦FÄ¿e¿YþºíšžÙ¹1j¦Ó=B¼ö³­Wõ©¨OI—ÌŒ¾M®;jDG½8÷x¹õ­÷®÷“ò¦_òvg­šÔز‡ iê\¡º¢Þ‰zoE /[,„õLaYÍoëuZÔ­ï¬VËCÛ¬éåi®‡ÔÌúΜ1Ôq&¾¢.ú…åGl‹J‘*Ž“gÝG”h½f û!ƒUÚ³Ÿ|³Wèx¥ >éf¨ÆU½«­Çu¸–¼žšU«µÓtÑÝÇÍ^„kS¤(ã®übj{›ýælQÅ\rz-ßæ¥È@}2ü ‰šB‘ØADôðcÇNÆfaXâ7jn>ÇG¼Åý¹Ñ]ÀZ¡A²÷Ùî«¶²#­¥Ô³±øú…í˜~LII¹Ë ´ª}üÂÏ/2,ÌL »–w“A¼®©oþ²¿]ÈQ_ŽØö˜²QlÜÌÁä#suˆ£KJ¾—Ù3ûh îy†ælTãm{oò‘#UðäõµÝÙB@ý²]ô¼Nùy™R-.jã:ÊRuxOÂÓÉØ”ÔÇ]3uÁB~Š9¶Ùs†”iowÐÂØÏ¥}å;¤ïæ­0uĉé#íÂÄsÅÝç  ~ÊÏÊÎ&‰0…Ά’ñ‡šÐˆXÐOÈŸQ›gßµºª•WJô.¸Í Sy]lç'ºx³™X¼M¹¢Ò¸R-Õƒ„ršÒO‡ÛïMÁžG’„-i÷G&ðm†5ëGm8ïz§7_ë)ÒZ# G°P9(¬üÒ†ÓÒ:Hé@ÍÍíQȸ+®Y2«ñºíŠ$ò†¥— !sä¢Y‚¯Ë¨ùü9¾C£ï¤ŒuÐÏ¿¯oÈYÍfÆTŸ’¥ÙFÒáÖÃÓTÕE’K-7@½:“}î2QÌ¡/¥V˜K$™cÏÕ<ÿæ[¢¼SNä€Ûþ8§jÓý‡À¹×~{‹¥³gô zž dl™ºŠôh^Z³ŠEÌ|ç>©×ì/4:ĸ…¬ÅJ[5%jVéiIqøôµa:VµyhXª(Áö˜Þ€Äø¥´”o¥N~«”%Žï•Ó½˜ûpþ]нqXÊó‡³T—ŠC¦dvÃË´‰ >óÅå|¾•ñI5ÉÙ®•Æîmtsõ= ?…¢6RÀêôÕkUzQ›õGPªÏy–l×Þ7rÛ ‡wã4kjEé ‹7fЦZï¬D-ÙÌÃ{X¥u¶OÌ]ôï>¸y“qlî;ï÷Š`jS©–àû=Q`Ë<3{¢¶à’)¾1“ÿð‰ÆE©*,«Ý¯‘™²¨h³P¯æ×c«Â›ýì.¸pi$> 0ðkï JëfÙË-Ïûå70hØÔmr”(³h£5yÆ©g8V,MÏäáJÃ&FüjI~Œ}+ÆÐFÓÔpTÿø~§À·ÎÆù¦ðQ ÄÁMë˜é®åÁE!WaÇäh醕Ǩa™®'„yU»ö~m"{¶*d)Þ;fA@¦}4) ±› ›!n£ð”Ëô_õQ㦡âÓÃÊž¼BÂzG¯ŠédC áìÆ¾šh j Ó.C¡8ö:ðrü€7…ÐòLÎ]|Å<‰‹J¼J_ 0lÂíû~âJ‹ý.Áx !¥%™„+üZhÓM–”¨¸ÚJsF®5Iú€þX{v›áËòפÑȳ 3*xNáT»Àc&MÖ}ãÝÇÑÙ79öK—V¢0\/h¯ÐD;oXúœŽõ\~d)½cÉŽ:…$ë˜xqÇHÊ«-&ƒ¹H oTi™É¸K²ÜÏËa6¾>.˜»Â­Fé«a¦åhõmÇ*éÊ·>¹€×Fð]G̳¨A{1™X㸽ñN´à–Ë•²1AAÅá¨WÑ,œd”Páî²ÊYeÅ„µO½íˆ·ï;»d̤ÍIvÞrÐðýóÎØ…;§o£pÃ[On凴ý”¨3©0†QCÚ?pó9YŒ #R¢bšhr‚“_¯^ôôfúŸý…¢] aŽ^Õ.¸3óQÒN™"ó$¸àe—û÷s´)É­îu«(ô8úï¸ ;¶È°À'­Ê†C¶UT©;±A)›·€LɸY–H Ö„Æ‚O¼Ç&'ßD 5[Ì­Uˆb7f¾‡¥×­D–%…0Z œÏ‚`ͪûį½ÂsAº6ý°q_¡ Qê2ÇŠP. o?t±«w‰†HôütÆ‚ÞCbÝb>—KŠy¶\0 BaoúðdÃÚ]»~_gœ½ÚLb)0ÂVfë÷XPIdXrR‚B…ñ•ßêì)¥~}àf”¦pB?t:àõ§¬õPÂR‚rìÿ2#6G¹PÞńճ³÷“E©ÞB^†ýýëÁ÷»„ÆœÎÄÚÁñy€ "ÒÆ ·‡ª‹ Gi®Â~¤¨W\‹›äåw±¦Ðœ,ˆÐmÁ(véhµŸgIPp¿Xq #ãdf?þ¼¬VpÚ³s?áU2ùÊ.;ÝèZ½’®KòÇ ‘Gï(°0ô¶ÄÉ#2M¼Glq ð¸+ƒ?²Gr³íÆFûùóëϽkûÞµS©p»“Û„©¼~tHÛ£[]|¶G ¨bc= „ʆ·ß;yé7 9-RâöJ.Éü´=­lü¸:ûË&1Ã\ y¸N„–¬ã:¾+3e×v¶zõùSΠ)º &Îl¡ÏÇÇzµï¾á¨éxè‘R3ÕÔheÅ»ýè Ô"¿FàK¢M‡$ˆ8ûX/ÛX—?­³bü‘Š·•€7«õC†º§Ï`?K§Ýçûæ×^Î_o[wÌ8Ò»Nt7)íÆ—ûO¥z{}š%,‘°“ñ÷_Ò]=AkH7)/ð"ºÊ!ÊçCAþµu°gó˜Éà²Dïœ{ZÖ´ºCÿYw¢hjå<½¸QÍ3î~`†—$ŸÚ$šc®^ŽB¬›,ùQaؘMÒ‡„÷‹ ÷„©LŸÒ!ƒ}t9¹2µ\÷ºÞÜgF]ˆ‰½_ós!w-÷­@ÄS³"P=vüc äŠ äÀÀݲ²rž´CƒÂí…n›qH»}7”&‰}pWdÙûƒR¸!gÙsµ—¤¥£ä¶ñZõЉ>¸¶ó»}QêŠG#'àÑ¥ðøûùþX¦—÷õoŸ°²jFyOÄ)ù…ÈÊÙµfOšE» ˆ:¸/Š ^ëçÝ/ØêBgœb {œ‡z#­ûõ®åh\æ÷ÜUÅÎÚV?ÛòöÐt™†¤µ¼}gdŽý¸í1&Œ×Øu[Ÿ¬¬˜…é¢xíÇ^ü n¤ÉUWc‡ÃXºÒ°ÞùÙ ˆŽÖèõn!AˆÛÐûÉ3³]ÏÂSóâ§Ä2S¢Êðþ¥Í'uøÆÂ¦@g<Ä]˜ÙDXµw>ÃNeöVNõ«CK©¶eþ–²ß¨Š_]«dˆÄkG 3‹Æ Ržç¤„?YA~÷ «K¸]"2ûº‰³\Q¯]E°gÛ2)oŠ%mº1FƒÛÝiÌ#!)R¸*N0so§¤¯0OÙk¿ —Ó|[P³®7µ±yä¬Çtݵvtýq{µlD©*G"‡a\'ÂW|éÙÒ7‹á>^+DZñpZ\™ty’gjÕ mÄŒF@ËãÈWsy¢v†¬Aû's²"ô ;Šä”¦#X+UìzB-XÑ“™«K{‰ÀÍá Ìç~ù©m˜ƒÜy°È¯éÁ¨>‘p¦íQeäå¶ZoG€ë<è(´~¨¹ø¤¯W90!a¹”›Jܿ˵TApê¢èø³ÊÃ2²®æ–¾:Œ#ÝÄOÍÆÈµ”6,´ªüí5*Ác¼Dn]îŽÆä(;KžôàŠ 5A®©|Eµû–Ø%„ h—«Í=:Þ ÈvÐöEô°æI(ŒÖŠýúPCÌÏ»¢“øã”zäS…„÷lƒ$™œà¯¤klzíowøȈñCÈSRã‡!x–ç—B—ª>~E/öé+£¶:Ì<̹‘´½×/GªãVò>N?Þ|³¼ЙG¹¹xÑÄ&mNúR'TÂEƒ•"SV>œf†Z*r. óæý iªê-1@~r$ûLÁWæeÅÆns½ Ûe¥¹„†T¨z×íâÎøãÓIV”èÍPÊ— ›«oí)ÜžoÈAH¼2·ÙfQϵŽhœY!]Õ]†'Ó8kÝ–ÀqÊ…¤ï Íý®†4k^Ë‘ê®ÍjÛ·,£ÒÙYˆa:47l°{Ø/›HG¢8®Óîí+j}×CM…¶föoFxÃ8yŠ&§žu§¤Æh#H‚[ÛÙŠ±D£•µl§[ò5jæía#²äÎ 5›«,0tÑ¥¨ÆÑÛ¥ +¡­µ÷¥,ž­Îii˜êÛú#æeÈ®Î6{ñÔ óÅög"9VÔÄJ5¾õ÷mújoÀ||¥!° áòŽ<lä$N^€ „t”¬ê9û!…H5l!=ÇåX“¸-œA ¶…«Ó…¹ôb«?Âç?sNXkxùøŠÏŸ8:‰MqhlÇ01sŸ‰{âY ì„ž/$ d§ûiõBëÖ£aU»¥¦°&[½Nœg²©Œq}4|†~~«úY†Ö ’r™$¤c¢æQ4ºÀÉÿð<Þù±F‡²ìk¯zEÓ¡¼yGÝ^‹^ˆùîÝÒ õ‹É}fMci|ZA•Ši<4•˰Ÿ(¡µ]±ÆOˆF"sÆõø€© [5‰QébËKö‡®Ù÷È.ޞϺ\Ô²OÁHcCž0+ÇG­°I3œ"÷¹ Ƕ£GåA‘/§ç õa•ÁZž}—Þ°?š>ôö¢B·ÎÉšS—M¡‹ŽJÞÑC"ƒ$zªœ“›üò”@­žÓ8à4ˆ>FS‡íŠõãdTV ]DÌs‡'OÜzר›Ñ¶¡Ñ£´óǼT- ò‘üÞ¤äú »b¡¿Šôpëû:U÷š[¨mU™ÊÌ2âd&˜ @JoNA fæ(ÿ‚\¸‚Ú-oŠ0M>­ÙÕwXáY?ƒ˜Ù¡Ä‡‡DD¡ïúã#ÔUޢЋ-™¢þpïFKTQÖƒŠS‰Ó^¨é€Ú~ 6)%µGF­u³8ÏͼËO ?4)ðùö./ÌpvE›²!¾|\ ŸwÌ èPe›×YçÇ*wŠ›ºâÈÌŸš$ø¼-i!çëysªÅKï+8ÇS†“E_¶ÔèG™"«–Ejì2æ¹¼“ ¯çÎÉ=Ûè}±Ã×69¬~;s¬—¯‰fšÓ^ÿCúEðµh¹'Ö¸ ‡3m-;¯b/c_;´xüÕâF3ÑÅX£Rg]µw³Oó!dÊŸMnE çªvÑc|jAÆ>ÝýT[[K±M0Vi%%ö¥©§¼°å2eYO¨dÛ=¾•Z…{Ö€uUÞ4MÄÛIxúHí’"“¦¢ LSwê{Œ†÷KÑ×î@Õí›^ñÉò÷ÛË¢&Åõ©hÕ÷ÚºQÛÐ|T´ll²½ âüÖyõ ©¢ñëù[ò<èŠêÝP¹Üåtò–?Ýøa[:ÑŠ‡/¬áKšI°°I{EŸNßp%Ž‘ŲÛcÿe9© ¯iyõjã =ªWß:¹“Ø÷$Âq›è¡ˆdÇ1(ámÊÔ7_ðy¶°±/Öx¤æê._­cçßkJ£jÂÿhÿ¨c2ŠT‹KwµÊ¨§ÀÇNÃKoðA{²¦=•Ù¥âšõÍC•熴êtí¶?õÏ S\öc£iÉ|¨ïÓ3¦E »n6`¢¿Ó ‚µBóhôÑK,Ìê\âW«KÑ PBã–O¹ƒüï0î |9ärê!½&Ö{T¿ò˜W#ùr òŒ£·Á±÷ÎJ[“;³ƒ,? tâäÜÃ* éʹÎäVaêÝ!¿Â‹ |ŒŸ(}+.3(Õ³‹|¶»l âŒUÜ&—=#^úð­<œûÄÒºâc¼î¨O”fY?‘¼ÜxèÜóÑ–eHûd\·ö¾Š²tEóm™AVåü"¤)S>¬”Û|Td 4£E~Ùr"Ióò ¦.ëª`n8’â;ã”’Á^'G98AªÑ¹/üó¬•%0ÐîBõ¥|¹Äæ†OºÀnÍüù€ Þᆪ΢™©×j»öÝï?Z<’çsé#v ?gâÐMa~õœõÿ‘–ÒΕ"HUu[QÞ× -eÊþñ«fò¢ÈA ¼™ëÏ!žš),|´)rç•ÆŒÈŒº"ø0äð{Á=8î”—s9ÀÃãwZÔóÊ _Ÿ\)GÉ*Iîk~é¢H¡rÌAœ+/žC…ÆÑޝÿº+²lÃà Y»iúü̲€y ¦ ï ê%)m9“c¡ _ñJcBUI½ÿ;™‡Ïw5×4AØrê!ÑÍXSî˜+˜™Hh/h í«^§º§›DwfÍþ ÈÞ¾]ó¦Ô‰¬r¨È¤OúZ œ{’iÖ§0÷¡…Uµý%kï’€@ÐX‘±q,Dc¾ô|õ¶”¯y5‚ªç˜Î ô‹‹ê{æâÂkBɺl¥²ê(ˆ¡±eþà˜€x—£ïŽ‘}ÒþdŽèU“$^9sõŠÎË:«éFzºl¢ÐyÝïÉ–~‹É å5Ò§§ø$ç:|­"°Æ³ãyq6ņ¿¦šP1"–Ú¦¢,}»ñ·×”ð*ØAIâµð±™±{ÔÊÚ§y"²ŠI „j¤·ÎmÀ ¹ÿ6­nc[]° "ÅÔNêáÛgj&yY$„Ÿ~g²÷·‚d†l±Lu¦/µ“1q].ž0Qgùä“MŸš&Ü ør©ŠL{Åa’¶Ú4n× Ã™–ú„j !·a!×û«aH X ðÙ°96&нàaõ ÀúH¤RåÏ_­–¢e$£0G~O¬±óÙ11lJOéúáÉ"6¯õ–À.•E³¢®ÉVyô‹øP_+JZXªÍ”öüÛ•ñT+ÅPi9NGÁ2 ŒÌ*—–zMrï¦ÒQ³õöâwÕ‡Hûå]æ·ä«cTîɱ]Qøø¨ ‚¨˜}ç!{$ú¼Üïö%vXbg©©)B"•é³%çÏ,:WŸQíz´ç„9M5•%Ô3& ÄgÛèÉœS}IßñÛÁ2á¤4Šð&ºžŒ­wó‰Â¯ªÔG^–µ¢§œxˆc“(Ú­Ä}ÂŽ”ðý¯þÙ6º&A9îöý`q¾µClG&hð¾ÁÃâ¿5$, R"©J`{Ò]¸ðƬB/¯1Ö lÈB¦ÒïSÂÄŒ’ÔóúÆ«ÕÏ–Õ?pT˜¢"ÊÓ£7ZüUðt;ÑZSë6{¶ç`çÜŠ'Çôz`Rëtó¸G†Çä;aß IK’É4¥pâ\@<=Îæèrt…$höP»¯ÓsnôQÛtà5x=:tÉê4t\_Ð\EœÄåŽè-‘ï2l˜#ãûe6cŠ›c–-FÙ–w¢ê‹õ\Ã>¦ðÜ=¹±ÃÍÃI5êÿñ?Š3m} lf¶bü}£mqqôÎ,k•Xº!Šïç2›R¶…~TÏ9?hÊêžÖöAw6×ñ–ûÐF‡jÊür¸IœýŸï¼,„æzÅ@‚ªÐâx¶Ñ¿Œ^œÏ39Ø ì;17b{\§; Äk4ŸäÌ¿gh­´M›ÌJºƒO¥ ’€V¶öô½¯BÝ´::þIÇìÙúS³ bîx“ÔŸQGjÛŒ‘•'¸ql’íXy¶ÓxÚï´%ÒÍøÂc£S,ƒ&ÏiŽC˜)(Ò’?º{¦×÷8éEPÏleºÑˆ"ßÇ›òE±¸tNÿüXfÇ õì£ýi"Ïx XÅâ™ÁÌ>·@W6$¹’¬ÊÏۀ뾶îÿñ÷¬ªÓÎŒïpÉK…!ÕØxF†°Û)3éÓ$fKÎ¦±6d„8PXå]Áû›}>½ü1"{Š«©ÌׯóG¢=À© TË0!™ö†¸yùÃ0yÕ ~5Éd7í7¥Zë1u«fiˆèÔz¬Û«ú×AÔ'{…Kèîáx¬=bÚ¿|óጣ}Åਘa²-Eí—}„GÆwõíôß"ìÊ_PK1O!\éîGÈÌ";x7Oš®œËqà­Ê—NT¦Ù–áÉAH€¿§`jšð”Q¬:£¡HEᇥ/>sŸHà?xÆZJ€I-P°br†nÇdÆòF|pÐc¡?hzØÿœBÆÃä'#MW²*ó­ÒF0Ò?ãf Ó»ØË*øõA ¦°™·ð³>ú%RY·AY™d±\5+Î?ÁÝ tîê4ø69=¶}÷U?,Žÿý+D×Ëǯ.E3ÝZ Á6æ^Ò<¶«â‹ñ¢`‘¶Á¢û8é œ ÇÃò61Uä1+­‡ÓÝ #„K‰€t%¯ºnMS^6ópUÖWl»å©¬š2ŒôÅí„O)-ìH*ChEBÕ:*í»äô¬‡E¢Ì‚=‹Ÿ|Ê+t`ÏÐEºß¿¿Yè½]£¡˜E/._ÑÂUe0Ì–àzX¹jQ¡‹§nؘ’5­w‚zZDn½%Î ùÚ0qº¯™ZóÌ¢š£–K'naÃyâgle@YŽå1MîA@a¼'‹†sÿ(o¯¹Õ/ÉÑúÈ'«Qžã©püšfÇØ+TÍQ”—3Œ—Õ0_å`™µCÃПE$Œ²çl?Ž ñòË<_Hœúý d™ï÷¥2Ùúa¦l/×”t£à$cÝN•r¥üi÷U²|ã3Îétû)ã¦4GÚ8ÑpÝîîËh{ã¡ï6 ëêfºš“0x|NNv‹eôÐ\ùÜ-¨åVÙUl!†…Ç_ÂVkE­È1X1^óˆ×n9&Í_, ‰¬ÉO–$3FÜg?%Ãàk“§9ZmĬruéËóK‚÷ÿtYï“g¬rƒÒÕŸ?øb Óƒ×Á,ݤ+ÜQ×2“Ð'5ã¼üCW–Nq\ؽ·=$rSÿæõ¸Ô|ˆ">¬þ2üŧüo¬›Åe冞4ç̓òq°ÎŽŒÔ5†ó<äv—±9ÈWì0@š”_D (Tü"‹÷´­u,¹“e…¡O†5\Ëì×>ðÌÉÕ‘Ô¸Ÿ¦êlàXÆ Dò0çaê 娲7¤*¼ûœ^fLP­DÂuá—àQôqi‚ÖUnf HÒ™ùåOc]¥U䇄¬3‰-y&[·l®òe^-VÅM·# )U†x\Š~_u¦â1Ðj!““ƒ}×}öÉ«&6’Á¯£šÇ«œJ± afmETaDº^/æC1—;ñ;Ц´Ú%ðÍS£}‹e¨M²–xûø¾ÏCïš-g7ˆUøÝ~–—¼P+:UG‰Dñálø *y·öŒ†€}þ^Bdð¡26b7náÎyc5±sø4C,XGFÞQê$—ÙÐÐÙÁ°N¾Ä}©Ã]@¤.‘ï‰i!vª2EFNªkº®µkí³æ\>{¶kÆ›ƒ»+2#âdÑrŒbž4½ïh{3œºqu­4t)Ó­ò£N±~™9ºñq ®§è Ê7SàXVÕÍølhnOfâQbbî3IA:¾ÌšÄ@v!܇›Ô´ê;ùƒY£*4°Ò½j—’í¸Œ¦Äöºó0‘ÓÝݦÊ9È)“?Lu¨¨eQôÄlØ·i|Ìòs£r†’«rÎáÛ­¹z:/D¥º¸>Vì(Ò.D”9-¿ß3¨iåú9¶bªÁ¶ =ý4ûóÄ—í:²”õ¾or”F¢A§·HW4|Š]ÅZ禊uØ)¢Ü†uYFbÁ¬V®üQ¨®”† *ÛKÓå‹^m_dÔÜK r«©øÂ3“$¾ ·A÷gÓk5¶5‘=:¬¢Rî‡',u¤ìêúÅWÈû{äÜ•ÞMN¥ZVî|VQý¹¬xSôIí«'Dë»_?0ktíÓpŒˆiÈnw‹o¾3ßq¶}^*j—ÛÿùÚ¶™=ONipðvøYvçlF ’ý0ó6‡÷ñ¡>åç²²qÂýö Ä öŠr8Ð4QŒ¹·1ÂÂ^Š¿j$\çºÝîkt¡:½8+o1޶TGT¥ƒžåJlrÌî¼~’!ºtàÓ,Èêø À7•8ˆ®ÚØþî. Ý”V%ÿµÿ4­WûÞ÷\4Ž¥a‹ô­õÂy~E¢ µ¬†7 œ{ },zÂ×@F,Y©ýyuÀ}®>è›Õ,ö­à¢wšè³£ë;ã#oâü Ës £<ŒÙ¼–Ý\-7çcÓ #öwîô™Y(ÆŒLD¨õ 2µôS‚ a6 »ù¸®Øñ†9zâ’'ÿz-B™EAHm ²LÌÂÖ*,%:wH¿™v7má‹J`‹÷¸5•¿Ÿ>Ÿ.`Í-*œÞÿÀ'ûâÃôƒå³HæþÞ†)š-­~D ƒ92}KJ£ˆÞ*fÂý4|»X’Àê—{[O4¼àÞ.F…»¹Ù)?‚rQÙW•æèÚ• Ø,_N$â""€P@`n÷ΉéÂâÏç÷è´Ì+b ì#6biê#¦œ¿ÂG/ôªËšðð(U~fç‘­ I˜cùppqýŽHÛ0–»¾/G}p–<ɆM†;è⃠y­Sè4ÊÇ6Ëá?Ô¸¦ZZ¶±9&î´<\J§â¬·©’¾{¸¸#üø npb¤²Í,Óÿ*†•1®âMôÿÈ Q‹½ëeCŽ‘ˆ…éOe$JŽïs«ßu‹·#Ü$œ ³†‘­U¶vÈCÕRd´âc? yPò%´9ÒZáoÉ|1˜ÔmU,ŠBЫgúVý|Æ\šgx^@òÑ1QOBôÊïS“n¬ìÁauW$NØ—Žä‘~ƒ“ý•èk6fKêüCÁÞŒ«Áé\VÄàgZžú}?_§ ï³4‰OÍN¿zu³oÊùÙ37—”S£IÕ±ö0ž±†Z§ã:Ü!¸¶žöœtuOÎ]Z°N|Ä!V…­3Ú1Ýa8äA ~­lOŸ«3}„S2^B”…#ö²ú™M¾q¤]³O>æ·Ä{L†‘&VnkTýë7©ÇÙâz’„§Çån,ºDˆY÷ê'(œF=fˆ0Ú‰²Mæé>ñC†BÚ~‰‡'‹>{+38M,ž³ý~­íyªž §™‘dŠ_°ü–ÔjáÇP1‘2@œ¬‡ÿDhùaêë(çik·b‘-/K2W<%í?¬Ë÷vºðÖ½‚Mä°MÔÛäuÚ›;‚÷suŸWÿ·¯oÓß[z÷!á¶eº5 þ¼û ×%3!·ç¢’Õ`ƒw¹†ÜšuðöMðŤÑÅvI~÷0?Çžqçÿ¯sêÍP”hm[»¶¹kÛ¶mÛÚµmÛ¶íö«mÛÖ=ÉÍy;?a2/k’Éâ+åu`"‚ÉA­¸ÎwäDÏ÷¹Â·¸›™´‰(“—¿JZÀ@åÚ+`Ä1:C}àwé®É:zE`=[˜*8fH‹„A¨ãdf§ÊŸSÏ j?”2JYy¦¹•Ħ‡UKˆn7P=>Ô'[Ô Ñ¢oX&`¯@ï9D¿Z×DãÍÇQL!4«=î¡+ÎÖ²i“ ”hå„釿 –Íÿà`âzn'ëgCˆf·(Øq5<]–~Œ_—¦;Ð_'O¢h̃£[RvLV^Úd-·¬³ÁW`ï™h° ¢PAÞm B8Ÿ#v§†öð±Œûò=o2á«9Óƒ•L·‹¿²«Ô‡¼Áù osVï2ýÆ“Yû\ão¦9B‡0]¦?OEŸ½Iå¤b¾—„ð¥Æ^~t¸µ Õ ò¡ƒYÍ€Ùö›Ð4f„!^ŠfJé @’‡À¼Hµß˜™0N–;Ù> ·üíOÕÙiøyüVÖýÐüƒŠncî9¬L­\|BÙÓÐÜÞ¯ï½e5ä²6»‹Rõ9WÞ ¥ 0?sïú=È‚VË4œyÉh1o¥K«ª“‘öÖ‰fÝé)“Ÿ}Â]VÏO¨3 Œ´;&þí>JË™.oR¾}õ´eð–¨e‹Çne¤xW./†*Šy—~#ä@9Ñ31‡qwQ‹È‡‹îϸ/æG›Àø 9·åeQ9|ÒmN[_Á‚«Ð®?s¯Í~m²¤ÇHø½~ðMRx?Ÿú[|‡*LÇiç¡ífä:ŸÓ[•Ï¥j]G4ü’Äì!–⊊¢™º Æ‚s”å4 ýÇ Ó›*åÂ`Eüë³,÷g—ý%¢`Ξ ¸ÿàd'ÆA½P ™¶ÜBû8­ÐaÖù¥µ\&8›M'Qš|GuŠUåºTÖ~W8ža¡ÆiJ–‘XæµqU~|m&d ²îʯì¨Rç-ñ­rÔ»IdªøI+ z'©¹ÉuúÇB%æa…t"MW/]+ÖýÅéÄÃÜ$[è2zS»¬( ®ãtz˜fÝ­Pc†Ú4/ÏPs«µËDV§ÑMèz-œêꙇˌ¾q d@Å͹âçJ9å;c––'ËŽÑ×”Œˆ§öüÍß!6Ú™ŽBä ÌPý¼o9‚¢ZΉ^U„šY†±7…²¸0Ý®÷“§:P+2+Ì:®:…›Îýw[ÕhŸõ:ªbçœ:wT£aØ»vk6 ëu¾à9Öé,s/R1PJÚ6øbu#p†è‹1$XIOW¨€LE`Ó=T€µ3üwxÆòeûz Ó@ä½Î«7‚oPµÏ÷šàçIª¢q!ÐLUú"É4Ö;ÓâˆjËïy‹JŽÚСÓ=y!u1!S† ›²°“r>í”s àÊÁ ¡oú)Û×tb •0?ž·³S%¶Õo>f擪`ÝJ3ÍæwÚâ ‰_u梜RŸEA¿T> 1O‡¿ôYñ/Dý?XÜ,Í¡Th–ià{õ` ‰=΀bÁîmùŠCo·"%Yb¹{BÌA`’AÎw?”ÆÊ;W¸ÂÑý+{ )£N¥yÿQ;ˆêInûŽ‚77£¥¦ïÔl¯¥ê†«ô«LKŒ50y¶z¦B‰XoT0£ÉQì—=Ù…;S‡a—úf4qna{…Tku<Õdoñ"õ{õ’L"®Õò¼dô6D‰‰Y¿Â²T"¥Ó=‘®!QØÐ¿a¹j, ÁÀXÊž¯÷¼Hý'º&4ϽuÞRöû|ÓãŸüÅ’'¨%ЇÓÍðæIÙÒ(¯í1 N`vKœ}&$£á4Jjïl!ż¿D1ü†S Š¥`ωN`vù]AÀ…·a è 0üÔi|g%2tOæZj ×Uöi^Èô¸†¶CæQ$s%ƒ¹«Õ¿Ý ‡c†AÝA¾Gë]Dw&Y•ò»Ì9$]l«…/–;ÛzZ"^2˜>J¹GXK·%¸G²’ ½a;ö‚Vy_z·? Ñ»+rÌÚã\û–¼ÌÍÐf¦“~•æ;ÅOw% Ôô¾? ¤œâÝö¹7·aþ³<_ÉÂÛß¹Òv;={/ý †Ôï®PÖülÐ{ íÿˆ‡ .´uËnÅv ð_È_œ­õA‚ŠSe쬛ÿ ÒD£<ðhØ ¨9h‚‰kí°9a¿ÒJ¬d` xÔiûùO‰/+¦ÍQ“T•9ïlŸ¸ óã±nrt·³{GH§Îjq‹^[©ªZPþ¥³†¥4[@A¶ÉJc® 7õÜ5mÌùáN^DbfQ 'Ð|æ$5ù´¯á“jpXý ÐøXÞSÆZ½ƒÀ,-ˆ¹ÉÇÄ™á”Z;`À¼ßwN"{ÕmòÑúW‘¢È¬\ƒ)öÿ™Nl/†Ñïc¿Hˆf`r}Ö›;Ú¦WgoÕ` ÁµËlduU½fXFï+([?4_ìø& ™5£.×¼„ô˜‘àéûÚ¶û%i†c+™%-r-ëÊ]é(¿P×OKt0õ¬`c¤Å;ôæ36¨í ¡áû‚1‡~‘ÃâMã…[Mñ"¿J½Ý†ç<—h(a6‘ßˉJûrœ³UŸíªÉÞeŽÏ/䇄©ý2jRσã‰Ça,ž™“å¾à1ÌN´ òí1Ìg3;²¶¦ #ž,üEã›nŠvïÄ'& »Ü‡Þ7â>ؽëlþi#3ºU&J}¡Üáµà9ë~rsH€$A®‘æ]T9½ìÿg·Îú—ÅK6[ˤBDÏRõì1¸Œ«K™Zžn‘é¦@–ö¬à£9¯°'ò,÷K^„·×‚Áæù•»ÿ6õøRB=]Ý G¡§ég8•Ò£U4U°¹AÑcfpS97¾ª¹TBý¤Iþ¯BrxÛ|5ãÑ^€>žXÉÒƒ¢ÞbŸ~íöytFçº÷@<Å¡«ÍÛù¬l´XØß¡‹þó´lÿ¾¥¨Ft…kèü«q‘œ‚Àƒ<ê³~ón]ê Í*µ€%†v@£Ž¬Ö?àùH¾çÔ±y&+ÿ·¹Pwy/mëõñÌà,Ø’ô~µA§ñœ5«Skc<Ñ” vuŒìH¤qÛ^Á™už+µIöP=É# T[6·y =£8Î%þkÄÓâBˆ…Ðî,|š…‹g¸¬ÅF©È ¤ ±@Æ÷õ€5?µwá.ñÖ/ÒÑc,Ë£²z{âþCrM1ÉX6Â1¢˜ŽNé݌ݓ&ý𲿨q¼„繈PÏÞ\/àùGÕ·Gì[Ÿ&¸TX\î–á~,18SÚ^ÁÞ®’Ä{&¹?ʾíXø0NS8›"¿1ËžK,ù±ÞïtþÎì–~ces¨¤øÔUù½ÿn:zÎS±ÂBÏQ¼N…Ì"gÚÎ²Ó è*k`Û:ƒz\é  ¿{’:Y½ OÕCºmè^¹;Im b»ÔlX”SÔR¿zƙ߻ÝwçјOÜWNó7Æ)`»½¬º9l×Ô.Œmˆ¿À&­ÈN/§ÆM$IÖñ„29ö[^w½ÅZ Ñ–¤ìø> Äϴ܉ƒyqTÄ×±µ#j€¾Wb<#ÞU© B3µªvTµàU=_¾F] ‰­´vPhoZ§Ú¯·.Õýyƒ*÷ˆ™™‰}‡,_ûÈY°êÁº{k­ÈèblðÞÿk¡¼kß§Üé~ñ™ÖÑGìí„Ð…·Ü “‡–±g7… Â#Na\¬>å׃=œSDRœßέr+!] à'Ê4]«Ó$¡tòk Õÿ‚ µþáMt­?˜Ø©DŒ˜ÑßÇŸ+ÐB{ó& jã§Ew†nEå|¯Á®×n;ܾ¦tmÚº¾D.Î"Qf3Ï#‘'ÜÕ‹Éz:iÍ›ÂùWÌ)a´km ïqÄIÎk!nOh4U›Á/¦%ƒ)lný)ëðƒ(¡É¡ƒ"I¨‰Â& ²ÍC³ù@šÅxéWž˜w¥¦]'!Ì ZÄl]HŒ#w=ÙËsüê²’¾kÌ7žÎ4É£r]p^À¡¼²=ÑÚÿC­£Hãò5íâ·»÷ý¤.榵Z_–fÇþ W8R¬þGåºlõ0 kT§À7St?X$«…–5"þN\ó²È¯8ÎgìcîõÔø Òæ/§­Œ+ÄHVãêug$R™q6hk‰ÛT¿ÀI«Ì}Cöº‡‘Þq,g'ÅDënAèuºfªæ_ñ#4P2dÍ@󟇡5gäÕf‹†Ð’Œ¬ÿˆö2ÕúéØår¢bj;ù`{{aÅknTLöÛXNƒÄ‘A6É{Q Ö3!júöµÎygÞÃrz¹©MÝ~Ô9{a Eýøñt’}!­ÿN:O°¢ ãÁ¨1«Í½jDúੵã õŠ–zro=Š’ù:ÕlÔ)òµ\WT®æ~§zg€žŒëj‡½`&SO.ß ÜS ¥lòB;Èõ©T¯ƒêó¾qêfÓ‹ò$fO«Ön ¤ ß@11éÍ% VP‰zFdŠƒ‡}[ˆÌ“/†2‹[AesiÍÖ=áEø‡a½µûLOz+8ƒØw ³Y{gð)cF2¯aÕ0Ýל`_qkËr^½¿ëpñýq0Ž"öJ&ÓüXL¤uˆ³±×lþ8s7³O Ôʰ¬Ì–N´ûâSØŠêØIP„½ö}‡JP–T˦À}ìÒÏsê—]X7x¯2׿³UæQ~Áõ©OsW‰5Y?ÆiÞ)Z¹s1„¸ÜÁ0s¢°ê’{Æ,îKd Õ›™ÕŠ~c…¹Ïï):î0Xc"È$íljÍöÏ­Øâ"Váv’•§úøSCŸ?yÑàÜì+ûl/„µ&×xzð§tXûîG(ÆÃø]êíÍ#€97/{´ÁÑ‘8fVUøP)¬íÚÒÁî˜"š~o—„˜Õ¦Ïë_îpöYJzgj?…A¡epÊ?ÊŠÇ£¬;Úx‡þ3ˆÂ®¹`²&(|¥4ÝØHÞE&:¬­z qx ÓM/J…׺)¢6é€õµŸ<§„KJôðÚWÿ¢ùQ9.ëªá-ŸBûºe’›-«?\#+Óxå m%z“ñóà‹7_FîhÀªµB°ç‡T¿ÕHáTA NÑÆà®rw=ÓQî¾­'W”¡Dô¿Ç³.U…ÑÑê!’¿n¸ #äKûò) )Èk4Ž-Å-A\AjY¹ÎnP#ÞÅ8úð« [ꤿÆ?Tœ¾‘›7ꔌàëla²4™ß²üTÍ 'ׇPÛ6±/Sp@Ye‡ãÿþÁ¤tåH yѾ̔Òh®%•¤ä&Џó¼nŸ«ÒÙeIºd]ÆÕÌuu ¶Glù4Á\|ïN'i²"ØÚI·ƒ‘¡Úk¾ÉFѱIŒ\$_êb©â÷dÅIåsìzjè xÄá¯ûûå´‡ÒÀKBSÒI^|U¸,莚ï Ç.èÕøGU9ÊfA¿xÅ—,D÷3Û™è9зÆ4KLüp®«þ–'‰µYÊSÖyeüiì+0—‡ƒBŠ[èmð³K9Âåi=']-7Ç||ˆèŠ=O½a'swŽSåDÕ zGŽ“þ!œQĆ]ÌŽPœ6ßñ:„=3vÔùˆ2sæ‘GQIèr©¾©/"ˆà1bôNþòúICÿÌ”Ó<ͪUø»/`Nk"êšc^ÎÞC•>ìYÆœ \› ádAî–gn6Ú+EKé繬¥î!’ómè<¸Yh)œ&( i³vú>Sæ .ê4ÇÅ¿ÕÿCNh±'ÜùA;59 åzh¡„ŸpWœVJêÁd^±Á^š’Ym¶ZûOàµAñ©÷'lÐY·>øœÓäNZu]ßTÙcZÚíÍË+úÌRç¦Îá°Îdi°I JZÝ¡92òŒaOl½‘é[Û ª~É*no†¾=5°¤ »31{r¸IòëÞSM TúÑKèŠjvÓ6 ú€Â7~½©Zœ¥dÕ=ñ±Fõqì׿T“¼§H7”µÃccl+Ï—Ôæ«%¹6YºÔ1¢]iìµð¥»@ã õ§¨ÍÀаêÜî4Ò_Uêmí+쾪 Qa©ãKLõ.ÏýžÀÖççºò6=T’^4W§¯UÀCMÀfb„Dù¢i,«òvU^‡Q—YüADW/î²I(ãq£SK49ºðÌ£·¸;cv¹1õ>ÁFî£Ú-̦”ü"d{½ÂI yÍ jßhó2‡aâ‚F†õ›| eð•ä|{ÍÄ×w¹ÞfAZbÍ=†ûä¾{$1;N>×G;Ì¥’ 'âIÚfÅì÷VVþc€áÁö´Ž¬ÒȯW{ûc­ÞûÎõae~ãÆÇ-rxÀ’$]íŽ5Æìí•倊™µ%)”k7âþ‹m3{Q®ÛB«Š,ïCS^oz¨tÊKŸÁ`Rå^Jÿ±é¡)9Ð×þtp—|,ÊeÃJ©x‡Íê‚ÖH«vc}u¶“3‹÷)y5ö6w´¶þ×ûwòÅÈ!£?f'Ã>‡;’ž¢B@¶ÊÍ•þ²ƒE› ­ƒ*Ýöõ)ˆäù,Zà›ykýæÑz™Ýáóâh¹{»7­}àOÊ.ðà@Gž¨ w)FsXõG¯+†#rË!ôeMÛìy÷$‘͆oVkãR)&¼kŠå<³Õ¦vf ÛÚïW÷[âEç"’• #ºn˜ÆMßmÿ púǬ{dðçTÊØ=W!ò'âsU¼.+ å_`?_ p´¾Çû­;Pò¢e¾s y‰~ÚÝ¥aªÐé‹I!ùÓisû“VßÍÆX3ªa¾¸¯ÿÀ¬çÛÖ7-?;øõ2ýø›ÂÖ2ÍÓêDŽúS4 ǪڨÌ>É;Nÿæ[gï ð–žr̺$3EÊ/Û¨¯§ØZ“,ÇÃ+ÓuYy€\Õ$vRd.êßÍT¢ŽØsë ~Aoh¿uºÜ•?¸eÎâÎ`Èá~SŽØòŠ\8  .O4QZA*;‡?9µ‘cT+‚»Äv×5Ú§ ýuðckS½Í9<1ÜvÇIN;Jµ!) üV‚'d£ætFÜ¢ašxžãX;† ü:fiýø´¥ ò‚JéˆÌ·ëôwÖÛ–ìO:¡9 Ôì f ëƒ1K¿¥Ø§(cQd ¶KóPÖ 0+GóþíÙÙ@£Û*à$O-%àg| ‹qyIÙŒ—%5ºGœ’í§ß˜¿KQš¤Y*ªŠy|2Ó êS7@=€¯Zˆ„â·FÊörsZlkÞKûµ%SÌÏ_‘,h"T0úúaLÆ”ap±häS̾WHïТÜÞ`O«2A^©>>.<=ws1UÖœÝ=é9Œ„­&LóX÷|Ù‡\5rÏzšáMLMF8nX®¬¨OË`8hîƒj‘Iƒ–š²‹Ž×V6LyxªŽ¶uÕ+wᑤª§ÙÉó–-DZزÞþò;ÞΛ›‡ïˆÍ»§®r§¸ešª‚Â}NÌ!ñ B U'ˆlù ß&RK¹ŠV0šÅë×¢”™K,y˜‰KAñ-à‹œ›(Ù›ä¿GZ¼3ŒbÅu tfÀ[FE–ù?û¹òéPÎÙ!…E«“Œ­×·Û¹ÓQÉbApÐÉØçÒø•í,G‡Hÿ@d¡´%òšÎb{³{ÿe‚„E4-Y6ûVž”åwŒ„D¶ðÛÂÆ/ˆ*Å­,°ŠÍYC¨§°øFŠZ=':#„—2›à‰‹té´P’PIv¦DÊÉ©ßß­ðª\“ÌÙÏ/^ÊBÒ72µõþôMO ú™ÈaLâL‡p-«ŸŽH\öö%{«®a4¸úƒä?ZkҠ늺fÉ-aDQ¥&MÛ¾…@=¥0Üœ“b>s¹,޶h/‡~êoÞ¤“ooÇ•\qÈey|hù[Ì›ÑK¼H"ûDÿÛ'`ÔŒ)Õ£á'Ô¢]0sG;~†^Pd·®f··ð°Ä)4É\ý)-IЗne¯4¿ùÂÄj+6(ÜIÐ Ü™ø ×QŽN­)Z|4vÛ#1ýÄå 68ô' O^D#c{“õ,ñ÷êžž¬ä|ÞïC>×ú33¼Áaø‹ªÍˆA¡ >uæn ´.Y£A¿²Ê0pÞÚ„³cÙ›ÜÀ$2ؼ›çÒµ¦y•ü¾zÌ,²RÜÂDx¶O$.ñüáK: •ÿŠ”*ØõÕ#°'AÛû{TöÅ´áÕCay»„#F¥úô˜P!Þ¯h×›u­¨ZÚJ÷c6?Ï@bLÍÆñâ4´,à€¡c2® ÊàgŸ• §(^æ¦â•;ß "m<Ñ"*Î'îÚéóK 3ß ½ÇqüÂMˆkXnj홡]ýé)u¸k™ê5žÖ÷²lOa}Õ‡ë¹ûk•œ‰uVÝŠdˆƒsÎh¶]þXf´É‘GLÄ)úHV„%—€@ð’Û¾»ƒ,Gw^>ûDzã…}U7ÖÁ²ÑCm¡ãýLbeN9•mŠ 49ê¢É—8]ú‚u²=nŸ2—ýÅ&ñ5T6ëy{K;+1&oÁÑϱ‰ §êdصµî„À%M> œW)%íoÛð¨7ÄRì=u¨¢ßO6rçE»_¸ª°†-gYF] €‡SŒWh—êºlh² âcu¼5gpF«a°Ÿà.1Dû˜”]±¤ q\†Á tþubñT$çy&ÆÇj¥î úLá$£—M^+ÕHXVl‡v'ëª&òeäI_jᆋÕ9æ»éþv¨vk˜å™/ßÕ¤æ˜YÀ{•L2Âø%_”Q˜RhüÌ+‹XÏ R̵ór{,ç¹kJH+Sf¤í<";¨6Ià;Ê3ú³_‡ÎQ[âd)8an²3„Ù¦´%!ê¶í@EÆdjÀ«UߘUIÍ,VJ=5Hu­7Ârâ§Y%u#/mÇßB‰à|å}ãž1|¿[ssʢη÷½Æúàìò0zM²û&Ƶ%#Ww&]ÊÛøÔÅ}4NT!‘e-€@Oœ«Îçw›Àšà¼1‹\áK6'Ùµ‡Îû ¾®:b÷ÅY×Ù_Œbßðën]m&Tl¬5o ‘éå?«›Ó‰h^…·:ÓˆÀŸŒÎ‡ù™žÒ\LȈÃVLgú¤i‡ <Úõ÷cÏÕ…pï<1麎¸£~GA²q¥î¿ÒÞØ(*Ð3¾fuX¬£ c„ô­S›µ=ú¹¶…žþÕ(æ¼ YY¾Û×ÒŸTt·æÐAÁ’é-1?5“ÉÃiŸÁä ³¾#MCÓ™\?ýuÅØÊì9&æ[4Ë0%fÓ§[ìö¶Q.ûˆzÀÆ0ÄJ>(L8Ûo÷»Õ?×Í ÖQ«»¹$Z•Kþê)ið\¥fnˆÖ÷ÉÞzûL½Ï1ÆC]ô¢2žÕù¶F£W}°¸ÃsÞù+ˆ³.}‚f݃¦¡òÐw5…ëq©“C*kÛKœÅ ùc¢Åß~PÄçðB§drYó9ŠÙ‰xfhË»¥ AxS1ª.„9©º´¹ˆÁèõøWVa…*Â’U%’ò`yáõ¦Æ>¶¨òdøëw¸ùÏâEÒÍ“&öÝåWËš¹¥£aÙ µ˜«í¬š„Š/„t‚³rA…1±" Éù­w¡§£˜tÓÜabj5÷íióe&ɺ‡DñæÛ+¡{©Y®&C…ôÁ©|†„˜yŸ¦˜sï`änk|ÐëC¡øn/¤o®Šh tÿ:hÛ­CÐ'ívÓbbÈù%cÆ-±C dc"¼Í’¼~!:g&›Ô‡x[;ùÀ·e~Á[´ïÑßý߯MVòíÉK¦†’Ncnð¨Õ‹Q¢ªr.! U„?ïÈÃßÌÆ±ûЃóÓ Æï þ‘I Í PA7÷ðP"§— *&F„]Âv>mMWE¶_NÇrúyeÅï6ƒ)ã7\ Á8⎅º’M/$ñ+®…§ÜÛ7âdEöùW-4·ƒÓ…æÛ~¥èFÃ%üªº™“”]€û~:3€Õ 3U¹ã¸)Ï“rìm[¡J̯Øö5ˆv¸ ¼·Âîù8æøÖÚÊÞÝùEþE(¿$saÀ¡ݶ LJ"! NÎ/'`ms¨êv±[Ÿ˜é¹ÓP½”£. -É'bÝúÑhÖrtaõ¤|èÅïM»to Á^•¡+\¸¹l¦™…aºi´ÙÁ.«álxÐ•Š­Ùé^ÇcaUÒÔ©xÏîÝ2ƒ¤l [¨Üø¬ÊZUjU¬Ö¿äC¡ BEÀ¡5ÝPv;»‚6ëù±$“mjÃiþDÆk’&\Krzæ¿G4V•ÓIØ eW¡W2¶!Á1ZtçXš£Ë÷ƒ$!Ђ#~cf&çpnh 'Ï„â©H±31,)¢EЬ!JY1š¼»M”sÑNq,òÇCÙ=^üäï¾`õd±³û>\* ‘LöÅi~¾m1N¿\®¿©ˆzº¢:X?ÆHà‚ûö ÖCéÐÛ¡•L¤´8sÿˆ&©&Šc¾—u­ G$Gn–xUšcš(‰¤0ùlg!ŽCÖ9ª–0f8 Ï!B©î°(@6ÙÆp¢`v͆SHªIe$2 AΔ ÙF|ß h?ŽÂ凧^Œõ·ªn Ña¹Ë½tØpuŸ¿ë–ÖhBƒOä‘¢:ÑY4:0 äôÔ§5X‚ÙÅY×»“‡’ÝD6¬ÍEByOá¸yV„Jò>Æükz~ÇYy#mᵂn1äÿµÑPCº¥!ßú‡ÁúžåC´'«¬Ï凯ƒ>§5é×3DÚKM\èà~¬ŸÉ0ë ØËš?ÿ€ .ÆÉoóz»ºé”r^ùÎŽÍOôLg6µºðÜô”`aøܧ£á½•‡TB>\JëáY†\À“xX|ª&SsëMå¹óˆ?,K¿§ŸŸ%V)êuÈ®UâÄ9éd7S°ßÎØöۺ͈è@\ã~(ˆÔ/8 K ä0 ‘<Ìà¦+ÃùƒpvÌäv ,\G»3(—ÙYo:Mÿý/Â3!ÆwR> ·šxô×Ô› AlX«ÖàÜáE0­¤çϰe}ir»!i(:!`a¿£‘ ÁÆ> W6¬øré¥HþóŠÇâÅG+%æ#M²n€GI©¢ÑÄ`?RUD…±÷“D¡¼ÿ‡îiýö_ö㌼êì*šRÔØ®$Fœ'>¬ ž ‚sñÁèv5G|ª*N²ïà £aÊäÝ5+·Ÿ¹HÉay!Žöú½Q5¹÷òƒEsfÀЇ—%Úù¤Œ%Œ…G YžmÏS\ý|áz¬º*Þg~3›¨—¼g1Å£çŽóòï»ö'%q­lÛ&„™¬ Ó  V!m~ÑèŽì bÂËÑØoÿE¯PZçZѽ»{” %M[Ï—ª´T\¬ ôs?}s(ÍZ¤î>4¸!N­u°˜ l57ñ;µéà çC^ í%˜Ó>  ‘K=YÉ\™iK“0‰W2’Œ*ÈTÓ‰ZÝÚƒ}Ü…9®­ŸDÜÄÿ6­8Œü[2z¨kõGí' ¯®9÷5=YZ¼ÛÇ%QNЇšý´¥U¼Çç_¡¢C1=N ¹R<Òê ëHË•SCð C<ëµß6dn_Fýü ëìé³ê9CBBâ¹”òœÛ`'WóªÍ® é“©yÞÊ×Ã÷‘ínÆvìœmh²üRÅÄÇ21/.puü²–GÄ/#dv™A5§†»«a© zgès ¤\ñ©ñ(˜RR2'H³8˜UR¥ùŸ¡`qVÆ]4­É€ ,J¦µøÍ ÑŽ¤—ßüíФ¬;ü¨v§ìFåK‹;;aE„á¶/vºƒÔƒîo;euYÝÝìâG}aÃÁGq«k&N¬fŒ¨[´ƒ20ö0Ù(¢Êªù6ÔÀg­ÑF? B¿½Â©Xº ë4¸7F’Ç|Þ/øBéÞç•ÏG·¡&}ï* ¡­˜Ü%!¯ n¦sjöêµü^a§tõAPr 9”¿­mÑ2ox>d¡È7(6¦›#œ÷ïÃ’­Ž‘ OUO„™âH‡YH ¥XmzÌýS1 tÇÉ‚û´‰î&¥uÃ(k>^e±\‘tx ü¾Ñtˆ£Ëž@ÝÂý"Êy"%l4Óå^¬Ÿï/ï+=§¾Ëa0f˺fTa.ö;ص¡t3éŒÉ/SÍ©÷ðœv#%´TVlkÕûáÃ+íÑ•Kê®DJø¸ZÎ*±œ‚-`œƒ" Ä¿AÀ·™Éé(a@X o%ò9‰`eõ0/–@2WvÌÐâ2š4e{–ã?ö-í`÷/©NËáÉWB…š\#y½Zv/–‰ª4•—ã…”-Aþ¿0íúR}à[Û6H:ã·ÏEüÿ‰ùP³MÓ«æwÞ7ðÙ2ÃŠŽ·‹½X†.8ÇŽû–Ùõ¯Aà †vC?û¯AÚÉÊ5ƒŸyà°b¢Fo­ÂÀò™±BuÕ5Ã*¨,ÿ@T·ú,òÍZÝÕð‰>ŸœiÍÈ[–l7#EÓ¤Æ4?ÿ¸M†õ:© ¢ÃM²9£=Uý¬’<Š&ý³å-ÇÈ'%€f‘ ªÃß”ˆÂíäƒÃ"2;I*'Œ qPý3!¸r?}Dg‡=Vñªâ…má[½ ô47©¿¸Ÿ È#§žv¹·:»^6¯bY=iMë«2BJS²÷+{Ó/€j¾V.“بú¡¬wºo” ?ÖìZDóe™Y% Ôæ…­–R²x“ì »Ð¼Æ,°ú#QáYÎ~Áh$;ÿt=_.Ûµ)Ùtƒ&ål%VJ¡í±nùWðœÓí±ètb3#Ê+º2ž3‚{#}™ŽÖc/Ľڬé=×'uåºqÝ Eôºá¹¾Ècý}HM(˜ÙÚ+ô@4 ?6Tsg"Ó(v€¿ôâVàxñkÿ\~ð]ÚýUåø»V¯ÔÖ4­&2õTóñO"](z87‚Fîa¾¾Ðôû²ißÛ ŽÎMxÄFb ‚WßÝÇQh“±J6“4¹±ï6~iX3âÁIŸGZïЖQÒ°tB‹ÒàÓyI{åâømcõxCˆVEØRŽœ$qq£g¸¡J’X@÷/.°6ÍpÒ.æà\ˆŸÙÓ»háj/g^>ãçÍ%jf%Ï\J¼“W.•Áh·wÚçº÷ç¦îr\7û?¯%ºcܳ¥E‘/¹E“é5ŸLIÏ¥kÂsÑgNЊn䄞° 6ìC´Nd¨’W“W‘dMær¢Ê޼hFUo—N· ž‘ ÷Æå6D¢ŽgßNF~Eüœl;Ãî¾ø}ö–r½ˆE“åûD¼/wÝ÷,hóŸf“ £?œ˜¿éš‡¸S¦w6K{šâyå?ƒê~ºW‰í`˜‰’b ­ªêË"-cÊkY“ù‚›{¡}:7™’ä¡uJÓÒJ¸Ö^Ž"´D¿¡¥’ ˆ‘†êz‹ÝR–çï"yk8–@Áˆ#YýÍ/ØþKõÞ'æÌ7ؤ†ÌäTDÑh‰1Îè fSõDf]¹&ý–º«XþaÒÕ`¸üà8¤:Ý9hÌ­mâ3UÐêÀ? ˆ‘…™vÕãØÇ ¦Š×nGR"‰":³B ¶söi‚ ã¬J«‰0\o˸pùÀ‚ÕÇ\ÆàðÌ,UG÷ž£K®ŒbMSw]Õ—[ÙQªÑ­p§¸mbVGS1Rˆ5úíHïXñångï^>?/SsHªc_™‰Cž=\•8íò,å[ü'»ŽŸ]2sY ”F”|ðeÛnQŒ›1ü‹& e"d×Zt?™ o ÚCü[×xé‹Î*úÛÍT.Ÿµã2²~û¸_¼þ¬°IÐm6_JU´yIVXs1F¨~H 5Hqõ‰­,S¼=xËx”/¾Jà«fQ´pâ[¬N¼‹ 7åá2ìW¯`ÕÎ:ÿºà÷ðV^ªÍ¼IR#޵ÀFW¨Çk’rª,¦Ç6Ê-.¨c„,ŽÎКÉH;Ù Uƒ<Ï\„ åB‹ßsÞ[dé\îrö«sß3Òüý–vôÂûþ|A4:¡ldB¯Ù°é÷cC €¬²‰`pæ­z€«Îꉊí7ì5+ä96¶“nJ¯ï}>ºúïœøÂ®b@ÓU×{rÌo‹æªÁçä«3ÌüÝ9ÁJÊ»<Þ™&Ô=s ´ëIù–¢w9©¼qîu#TŽ€Ñ@°AfÀ[.qàŠþEÑ*’$ø|#â‰$ âÚÈW¶Žê6œ?Nó•®F-í~Éá÷ UI÷Ì&æð;®záž3Ç:š²s—ûÇ?Ç·¤Å H tåd›’õ€#>rYµUŸÀƆý_‹ëé5ËÁn[¿Ç±¿¸é–í;uE¦Yq×üüc-d Ã׿vÏ õΕ ³ÛÂJ@?CáÙS-Úe3†zˆ|ŒÎ½&ÕÛUø¡¦­ÃÆËX÷EÔ{ÖÐ|Ù ¨h,Zs©zR1Ë@by¨:ùÆÄ%£¸¥ê˜ù¶Ìϱ &“ø?‰q¬ endstream endobj 259 0 obj << /Length1 2537 /Length2 18571 /Length3 0 /Length 20083 /Filter /FlateDecode >> stream xÚ´¸eX›ÛÖ5Œw·6¸w/îî®ÁIpw/ZÜÝ¡hq)P(î.Åݵ-RàM÷~ÎéÞçûý]\!™>æXs­u'Ôä*êL¢`3 äÊÄÆÌÊPPTƒÀl¬L²®¦ö6ævfVVNdjjqg ©« $aê äð¸Z”Í]!‘ÎvVV>dj€4t†-f^E «©†—# @gú— vqe23u˜ +"vôr¶±²výƒƒ‰éw¦ßÑbÌ9Ss;°‡‹ ÀdcVd(= J0Z›Ú[À–  @S]RM ­¦¬©¢NÏ I¬îæèvþ?,âêšÒo¢J’ Ö[€´¦ºÆïÿ@¿Õ[€’Äþ»Äñw¸¢¤†¨†®Š$Ëïlw ³‹Íï²ÿƒ‚ ð$ÔÒìðWµ««#? ‹‡‡³•›‹+3ØÙŠÙÑþ/|Ö6.°³òî ´þEŒÈB§«5ðï¿× `c¹Iÿ6:@¨„Aô®ÿ!ÂõwNû¿Ý.@à¿ÊX›ºü« ¢¢p0µ¹A¦ sˆ£«©«› Àä/ä´ ý  îæìü»†âLÎÿ-óèb`Hgö>~¦ÿ»b¦ 7ïpóï¶ÍÁ W—¿3–6öÀßè]~¯™ è/¢¨’¬”¤º“dð@LŠ`; fWO׿¼ç•P€Œ"/€À RI…8ØÁ‚Úù7}6ž\ÁÎ^,ÿ;Öv °Èçÿ£¶´YXþæÝÂÍ‘Edã䔕ø?gˆ ùÎ è `@Osk–ßÅþš•ßj¶ßj ~>Ž`G€¥©½ ÐÏÆyCöq1u\Ý€~>ÿ4ü[BfãXؘ»BƲUÿÊ. ²øþVCüÇô@÷×6¥‡ìQ 0ÈÞ `´DfQ»BÆîÿŸ]ö?µ¤Üìí•L€tÿÃèÿº™:ØØ{ýËñ<´¿¡Ò)LíÿÇfã"eã ´P±q5·þ‹Ä¿ÕWYÙLlœÌ¬Üì[4ï({ÈèBޛߧÄÎÍó?6ÈTšÛ€..n¾¿L@ÿ²¿AXtµÅ¥•Åÿwnþò’™ƒ-l@Vv.n€©³³©2+dع¸>l©¶zþ5-fØptsõX‚‘¯(7€Eô·êo‰À"þGâ°HþWâa°Hý‘¸, ÿ•xÙ,j$‹ú‰À¢ñG‚ÔÓü¯Ä©gúGâ°˜ý‘Ø ’3d,€®ö@K×?zŽÿêÿ°ÿ pÍÿ+qA’™ƒí!ìÿGÃÉù[ãàð§ +¤'‹ˆ’À? -ÿUû·ÝÉÍÔþ!Î-ÿ„@°YÚ¸ÿ#Ço3ØÍù«?!v«ß—ðŸ. Ö`C³ör´‚þáÑÙüC„ôúOL"þˆl&ÿÄrA(Að¿ H.›ƒÙï=mõlfÁP@r‚ÿÅÆAîøÇ ©áh 9¹ÿµTœlÿ§ý÷BqBˆu:Û€ÿPÏ aÅÑr'ü„'70äd6ûGglí?ˆbƒ@ÿÂõ[ºÿƒ'.ˆ»‹çŸ*Þ]ìM]¬ÿ‘‚å2.`Wkgà?Ò˜«ønfRó¯ÔÅìüOv +âþGd‡dñü‡)ãõÄ×èüw*¿oÁ¿ŽxÖ?gÂÿ=ü%«»:ƒí€Ú6G£¸(šBö†§>+ä|fƒè!ÿùdø¯Ô®–D‹‰=}˜8!‰Â/d- [ƒÛï_¡æ_Ô] ³ë?òï[zÍ‘—Àæ¡¶iÍáþ’ES•ðÔ|̧ñ…uäà–3§:I%ò·)€"ÅA­Y4Å`~Cÿ” P©u(žýóz[rõä­…ê»SEtIÑÑ<-fÍà,Å¥ÀÊÏôGry…ºeœ3Yí í¯š£Çâ|Ý÷±ì/Xש•íß à=JæØZpí±=—0‰»H–¦º ]_îqãcL¿ˆ.3Ìš†ãʽrìíÆÔcL+ÔÐ95ÌBÆå÷uÁ‰øèHÖ>4=‰‰Å[ %ˆ±/nérgìüÐÍ?]Ô ñy –îƒ~î|äüéÔK¢9¹Ö"åÆœ®þ ÙÒJï1šIS¦Üö“äyxüÚ¥wàQ)M‡øøSeÎgV¬õ—Ø$Æ×h Î  ‡*Py‡D6”ÕCæ“äm\§©mßmr¿ï·ü§ãìúMªø5"Lê¾÷i$™™(‹±I ÄziZV2ÄðâtQ²Æ2Ñ[ûó<~T_Úˆ©ã :¼”MW£i•ÏÛzl¦‡Fmhñ©'ÁìÇ>·UT†U×<ð›öbÄtx¨ÕOúD\ŽkÇ7üñæïÜhmlœîN?>f*!Í@qx  ªþ”ÌãÏt#ZÝëHÊœ]UH¡Wì—Û O[´GÕ¼šLÌemœ€Ñ“œÞRÔ㳘ɯ)Cu',Z-8Ÿ¿QVÚ¼EyÉX†©ÜÖ {oºsPûè2…G xã¡bžEPÎP :·*B1- ñÇÛ0Ô£½©Ú8çý*ÓVÀtHëì 4­—©¡rv#T4æ}ʦBx¦bÔ»fÁ*,×{V8ˆÔBÜ,ÝrFŇR”[L°´ØŽ³‰PG]Åñ3ßç‡)û¢…ÈTÀ‰Í,ü¢}ñ5ÛLL݉;þ±¹ñ #Y5Kp¤Hv¸‡¦+SéK÷¨ª´‹-ß\úE4 u\m\JÞeü“Li0ž9öóä«ËÎa=‡þJ k}±Ôû´Þ6T˜¸ŸH…òú5±À³ó´Ýû`¯_Ò‰õùuiZãšl\С^`jV…M¢ö)C\Nît£S×B6™¡F«— Æ6½^yK Kt-ÅGvZjçM†üsQzGh/.rQEÁ–(hˆT‘$•ÅŸØm}ÕZÏÅß@gÒÐe)VRâ”QE¦V¡]"UH\Úþr!'‡`ò]ý¤¬ƒ`Ì,çJêcŸÍ©lª˜8¸”¸ZX™®€û6¼É9²×'hvÅí }ÐDù„†F$»Ž¢û»’qP·Tè¹"òøÑØÅMˆöÐ #6}ô¦¹ÎfǼºQ1Mµ-]¶µ¡ž’ 19i§e°èsæ§7Oh‰´ÇŸMÕ>ˆ²;óëã?#Sê¤íùå•Þt‹Áã—Üb¯€‰X¨¢-MÚ] ûP#J¯¹F¦X¢ Xëö<'C™®½åÔ!Z×Zjì%žUõé~ß‚¬6jí`.¢ŠDbSel­–¥Õ…E¼Ç@^? µIä°aÞrhuØ̦òWqø> ¬à˜4òŠ£5 \â¢L¥9Ý~i<_s5kS¯¬µ eH®z_ÿ²èY£¤ù¤z6ã(!å!¸-Ysß2ûàcÌZï0ºæ6€ÿ1?>ÞŽ¿` fí9¡8¬\ïF¥ÆÉ;nŸÕ4Á*CQ'›q·6¦úg{¤•Ê·XÜí„îZó/‰LÌ`•û9Aá—·¬Ç¬q¶q'ºä·ICß[lHgA£(I}ª«Žúˆ€-¾yCk{ÿÔÍÒÒ[G6œ¦oÓ帛ID÷"¦m²/Bª^í©sýŒPæŸÞÞ¥ ³?ï¨2ZzF!• ¼¹d¨°ªg¨­â-*×&Ó8+[ÜÉú5Í"ºð“Á>Ž5ôg-N!>Ù þ’\Ξ°t ”§yá(/´.Sªþ8A+ P£Í‰?½24÷.ÙA8â£ó²5ùä‡ó _éÕsRï8ã |Šeem9®?2Œ[ÿAüÉΑÁE¥Ð]|5(xßµß|­Ãªéþb%kU;µÛ8Ìêcá“5¾l~ðAjW=ËÌ ®7„©wßÄf ô²lVQïÖzEï¼®¯¡¯çÝw$´(`c^…¾š²ä¹ÐrÅ!ÈÌ-(£'ô ö@ÕRôà-бóÃ’_lª-ÖXVkÊÞ4øú²Ñ–"sÌbñzyjÑÒ£Ê[eÊ3‘vÍãuª].;ò<Ùè xÃÁYY‚¢5eHß“ƒÇd6KÔ+¯)ªªÁ»uãЉ³E¨QÈoð C§îyr~|±s9u;%: ,$ؾµ´©éÂÕ´‡óczái°yxJuvGªÎ¹jßvÂ$uá?Œx:Éíÿt¯ÆvŠ $jÕ¹Q”ÓÝ1ŸE@d6—ãûŒ\Ʀô@Uð½pÑëK"ud¼j¤Œ²…Ôë÷÷|‰j‚‰dºƒå.,u¿tc4§¤F’v_0òO}Cÿ6ýí P3Л?.˜I*ܶ@¹(Í.Õ÷Ôƒï£÷ðò¼ÚÛsÕ$8jÞ*…È |<±ÊIŽ›iä´–Î@$öe1x5ÿ,æÒñ6›y3JÆQÒÔT2Ú>©À„ÁøÓHÖ>µiè… “éü ߌ³O+±o4@ϲ1æê«ÍF+ég‰Î™KT‰Þ ŒÚQ}ÁñƒÊÕIgŸ±\Z0/•[DSÛ';³bâÈÂÎepÏ­ÍËšãá9´’œ˜V©aÖ¢ªèJðTÁV‰z¾®gñ㋟.¶FÉN¡ÉÉ}[Gœ¼¦v‘»áa ¦üs§¡©*ŒŒ˜hù›ڱz~¼öšXÉ›jðBNîÁÁþ'l[¶x¼†×ã€%çùød,Xñ¯Ê‘ÎKÐÖRÓ©¸'Æ$ù–‚†·f†M¦°ÅÛº¥f†gÄ^©¤Qx¡4³WœËVùQÙ1Š¢z eŒ}÷¥"CÒߨ$Y;BV…lÒEäT(_|óÊ‚_h²àNt\x I4e —0íò3¸Ð Ä¶á®g¹âf«‰ÍŽR r—+ ñ,Ú1ãÌœú~wÙ¶úìˆÌѯýnKò:”u¨$}!ÝENµ©"QX“'ÛP9ËŸ V¬ƒ"´gú±l1Uð¬i‹Ël?†Œ:odÜñrìŠY&J„‚dÍØ‡hßÀû­-ûjNÐBÉÇ,’ÛF•Z”[°ÓìòñgÛ‘g½¾:ÑJ‡¹é¬>*ü~)*@5ŒcÅ㓬{ÇÆð ¬9=¾gÙ2àŠ.Ì``dYÀˆ¨šÌÈÀXÚCÏj 3P´Ac~|¸H$ò¡õ܆¢ufŠB²,~’˜úkÚ Je?¤ÏÊøáx׉ ?dÓïeàîí´”î9qs0/ŠÕ§ŽYVÇ+ËVLù*Xq”¶?©…ï‹üTØUH ‡áž`¡NG¦@>Ë‘°ë7ø[Ô\j‡®÷Ñ]e»K7±±C\D9¦¡ÿ>Ù CBÄ-y‹zlaòÉŽc;Iùªi5òFov¯«Æˆxµûx>†©ð. µKµK"é¾(]èãó·|”¥0€¸&ùú6Cáþ¼[$·C_(ó­÷¥ôÖ‘Þ½¼5?s›W=ØG\›¶^³R‘ÂÍÆy œÔ,˜7Ð œß=u:£hªæ[dtðy)´Ýž­aS =5¶Å¬Qö/Ÿð¥ªêoµ‰™Ý§“ãx‘ÂN4úþÊ~î•|ã%’ùi>¬²™Ð„HÄpçÚ8'¬,ž“кú€’WO3©ÉyñG_bH„•‡SÐ0z8¢WÔ 4iƒ™«¿8“;¤ªÒÈå|§Ô õòˆõ¾@‡¯ÐM—nKê¿xÇO«øð†ë—`ýDÖZE¶wv|ÍdÄë2—Y×üÜ[^¥¯«Jýˆ@k»À_ûíÛîk“ôëo5¼&>þ•¾§ˆ)~¯× ¾¾}®ÓÍ'j˰ÀkY¶/jíœ=° Ë‘ÿ,_4 ݽ-MŒÒœO‘¬3êðdh¨çÃ…¼º8úÌiÃø:ÝcOåm'VÐ~…>üWIY×dmÛV/³ÖÞÅ#‰PK° .0Uâí^C¯äÊv3vœ}‚`$ö°…tAÖ"BðˆTúß3¨‡î;kNNY#»,×­ëÙ¨òšSÕm¨Þ}Ê×®c̾ž2‘ gò­­Ùõ·oêyk„¢ÀK;,$”+#4ž©ÚñRŸß_ÙêÁ©D‚wwÂu.ìo8–#8òÄ S‰‰ThWaÓ¶c‹¿lËõóðÞ‰A¿m;ÓºR©Ö‚B£:ýå1Ý-#ßs¯_Äo;B:rCv—µå/ 6' ‰ìÎv&‡‘×üå`ØÔ9öÓ™æ nEÞBO·~[+A™åçž«ô$'Ùª_Ÿå€+‹½± ïYåôõ—9dRH¸DaîãÖa.#¯Ð¶âÃK Ýµ<„½=û[Ká€s4¯ùûÈ<új"Ù© ÁŽDM;{­º¤&)9+›ÚY1N%~ûjKÎúü–L„7e["à¦;6cÏíÆkõ&^ÞÛ¶$*}¢6zí¿ÐC㞆Zž³%tã¿Dt ÿˆVÈŒ´­ý9Q!…9·“'Ô›N¥£ákæ¾\â§*"ÅÒ‡WHäç~ jèØ¿®¥/×Åñ¬…Šú‰}D‡rËâþßèò“5¿e:BKXI>)[šIT|ûä3œI*.Ó‡™óÊ)>Cè×E%ýºŸ}¢Œ_¿'á0µfÓEëö"ÍÉ7ßI) ­L ”'}6¹„Lã3þeg ·dË;¯X”:%àå#;ŒÓ.e©ÇY˜¡3Z 1¸#Ÿ[‹ãìÝgöiY G4—·-wË­ž÷œ)p¡| Û{4s€nåSaWŠû¼ ç­ñ¹Ú|”´3–ºúÅ‘¨û(-Ÿ3Ã)(¿ìb¥Û.ßÚº~LÎÏ1ÙúðU†€‰™,žœ^G¦lËH—·^{Þop÷½ ViÃk•ŒZÈ~¯”úJ([EÊÚ?ßë¨AUxƒ'D?ÍÁ }¹„7?`DXâÜèRØG>ǙޫcA ƒˆSFpwJÑNØV‡w=¢ËÏ´” +U´Ï=ýÎ&<¥,jlj6{0@ðýÇx| {ƒ˜ ýó™°…AŒ¶*½‰¤pª–Œ¥Ê0徟5€fçbh¾D'¤ˆ7l'éßGcïärR îCJÂx'ñߣ¶UÓx/³È­2$1¦dü(·Ð;Õà3ÌPæ\”cÎhŒ"-ávñ¢­ï™–Øà3ˆÂBéOÌ~¨§Vì{«ê.‘ô‡[<#Ê‘Ùî0=`ùîß ‚oìRlOQ[žê6d=¯ÌdDò–àÃ+®‘W–%†÷‰Ž%½ïJÞ„å£ä5M2_Ö7åí¢qR{¾ “yæÃ{ÃæŠu»Ø÷Þ˜R8ºh4Ñc‹N»‚Wu—0uô廨þ,¢«Î„£žÉ8û‘//PM\Ì‹%¡Ö2–¹”ìñhm¦·ý0TÁêVÅÞh^¢Ð²×XÛ¶¦N? QâÇSîφš†ªPÕg)6.S7ËÅ`C)Y*ß×J¨öçû±Ìß[c¥Æ§0cÙ« ©2ö]@@–y#ˆŸç70+üä»Ä>ÜÐu°N°™À­Å®Å7zýxµT?ãýþ‚®c$bN¼%Y<„ø'ß´è¦Ûg&g¹ÛgF­ËiŸµº÷àt­j³{ ÿ*·öq ’?ºØd£KøåSße¬CIOÓrzšLßJ²ªîõgw{pÂz¶+ò¬(Ńc”q|Ú¦RÆ3Ûø;f`ê;©’®1ºT˜žŸ¢•b¦wò‹hÃê0u]½Ê»NL8Ä$†qÇÁ(Ѱ«L„øæ'œ–ýƒ‚ð`–m›Ü}•™oL“° I¿¡,ÞEË30@KñM³(5œ±¼"¥¤BAÆêiøžýÅi¬b">oëʨ›Öx—ûU¶Ã­‡Ë±‚‘öÜRqð¨”fA½ÇÃ}·WÿYÍÇ=ï ·mè´Bxá®xüÅÀJ—äƒJè´n™æøj¨7ÐÈht*öí1ž­9Øþ†ÍoÃÎ̦2§ÄK?”P¯Õ{çÄLmÍBHЇֺ=G€Ø¨3×7«¸šÜ>O;ýçWd{ÇÅ» ²×2ëíÎà .ü ŸÜ ·h¶·öRB ^ £QÅ<•G)è9鿟¹Jj,wr°´\4Mk~”¼}Oç®J•›[ø ì:ª@#L¿wÚ]BK£}S”±}vZ Í*žÅ«³’7¾÷Mîî|û§jkç–Üxÿ Ýc*ë^þ÷U-î‘Û?( >¥î~ç!#ôûüUc*'ËÂ¥žÔZûR@´eíøÇCz3ss¤†"WQ(нª¨Y´6ÇF{Âó’Ƚ_-ëTO=š~·òì€]-¯¨TG÷S€Útps fYãê»eÙáŸÝ5r*ñy°cˆYk¨£0Šíß=@!2%ªUÞ)¤­ªA¢™*Ü…Õ?j)œê5a‹8>"~ãa ¾íz8Tyjw¨å^P~›Ò@º(âõ˜i¶ÚÉÒS›Nrb¯„¼‚®úÚU®£&á'!Γ8Æy‹‡õ ©Ï¦kMÏÙi,ÚÈå7 ¨´*añqÎî*¥ùGu»hÖ Œ&XÛ.¯¢ø Êô±R’ä¥öÈoÒ_Ÿ±»Dòú¬Ÿ’ˆ¤`›‚É;gÞ-Úª²qçñ°¤àZF½=>@Æ–$ÍÄ]¿ @zŠ:Î:ôb.çɸA9¢fÇlÔï ¬tÝÚÞö §Õ [+À긕~¸<÷ß#Ùi«ç{i(`jqåP;‰Ùæä‰~é»h¹u[ìÙ_yo¢þ¢í5o<Œ¢òRG‹sÄöh¶@ò”ÈHWplË@ÆHu܇ý>ìö”M]¼É =YéÉÁ;&þ*ðæmÆCáA%ggd·Š»)¯0VA%fÛS:‚W­.ÜuýNvBù¹Áê ïõå‘jGŠðcîmY©ü·6~‡9nÛDØw"£g“UyL©Ù§;šzG§Òt½î;7Ù\2M…Ÿ©i€MŒ+Ô 'd&RO¬9Ô²g”$½ëÔãšÓÒƒ@ ±þeÎÊL F謜ñÔ¤3ÔhŠ—/ÄáÒÌ/<*Xr¶WçHvÜöô²Ëc(-«55Ýìëí‚cÇ)›öíÖ_¤KÍccâ9ßå¯Ì,q´;ãqh`QãûßѸ®»$|©X3ù¨xïñ^zZŒDµ· ë …r^¿$ŽÏÎnømíIºR„ž›¬×5ûðÌ‹MÏ‹f–téq– tüQFŸYå€=}gíÀÌ­üû‡OÝ{)40k0D©xÐ_*¼ÜÂ8åâ{“Ï_Œ†2ðR·ãm~ƒzxDø:QYU#Å“¶A®­½­¡ÇÕRÔ¦»3®Šq®8 $•âs™Ëy¹A*— ‹€_ÇM>é·R5Ç:»ÆÚX*«½™.5&ÚxŸ{øe\Ë:þq6Âà„fÉÖÁ]NoÆ#‚fùû]~$ªó{'êy"þ€½âYwôæ™Vœ=¡¦îÕkµf×qZpÖÏUÁ#N,ƒÜØœ´þ‹ÂbFÅ›clŸ„÷ɶžÈçô~"´Í®¸Ñ%m­¿„cå|8him÷ ÃB*VçwàÈ5Ö|aßeß·ÑÃH}›4îrŸDì•q]Z6_7²àš3—|QÈs÷åPe-{ɺϟA§V¨Õî.nÌ„jÐÔ:ÝYý6¸¿“Vîík ݱnÔ˜¡q!j+å ë»Ü¬åþ²]¡ÐÆÖL¸mœ¥™¸M‡‚5¡Š rŠÇ”¶íB6˜bªÒé7=fÖ8#OOê­}ò FP’Ì2ߤ¯¨¥I´’ÙNJ¶YÂ]ÔÇŽ°™¿Þ$‘èmW­Öĉ;€fg\•žUÝù÷JS5WÞh ' %ÞW½ˆu.hÄô‹,[ûçDé­‘]ÉÔš%œˆJS/‘:dÞ>ìµ!™½ÿ˜´óãë¯Q&RÍö (ºx®Ûœ¦Ð#/×è,ï˜Zö (â}í"–åKZÀNÀ[Ri Øž.Þ0S×_¬7tv¢³ ±í×.ŒÑ˜!­RïGŠW¯ˆÞ<­¿syJ\ÕåÖ/o\Kx«O/Ž[µ5v=.üT¡ˆì5iN5qð9›ÉãɰgjWV-Þ t£ …Cš­½)Hž36Èåp…þ%i›ƒcM ^uÍèùÚC´áAsîwÍ…6ÄÏ…'qâË}+W'½ØØCÛŸíœW´cÖ reå%„´¦FãmÖ;oÚù x`ì‚[û6×?`½ŽÚyçÆï±Åz‡m Vkæãê$-k/´K¯ôZ¦òL!ìžÕܹ8>¶—d|¸HHëè‰ÔДˆÐFæΠd‚»Ó…¡Y.!íŸeý/Y‹Jr:IׯÚ>§pŒ“þXx÷Ð>äp~¿„©Œ‰ñùÚ:¹Ê®*Eãð‰g§P[âòÞ"Åì½™çU¬¶XAÀ/\™Á]ü¬¡½§A-5¦—xë? Ö^GÛZµ:æ÷Tys0ž“mºñÂû ]A6¢B@₦öCY/h·SøöÚ’u³u.ÌöÍiº£[5ýŸTLG%ã¹b­8M"©ò-í/¬‰Í‰åÀçög.mRi¤ LÊ9Œ?¯–<·¹å38„Q!'ö4ÀgME‰ñáÆ¶ÊÙõ[Kõ~¥g^dÙ@¨/l'A»íK•ÄæKyô9ޱ¹îK¶ÍÂåî¯?_ùôi³÷9TAA: ˆðÇëT8ò€¦È/¶Ÿ\hċ޴wq¹ÿù•éç–OŒ|sàE]'©ÕØ Ÿž_‰k->vëH¦˜á·:Õl5Ò+õ@îåC§z1w%õŸVž÷_’ÛÉÃ<›EŠÞm¬þxÿÅQA‘ªÈÆNJ}µ°IåÔt C‹÷ie{ 2‘ Ûñ'ãíÍ ­žöb;§1_WŠÃ¼±?^O„Ó§ýè¥1ha惼Ã(IÍÕ‡pgÌ@3j ëœ,ÃÁîÎh†Êaû½¸Q§\úgØ~ž÷D²§:­û¤¬ªÝ9!²£Ã¤hoîÊæ=¥çF&«^’¾ ¾ð`ÛC¼èœnt[ÏkõycÞJG;5,ˆò.¨i¥VTIÞzT˜}r:/÷Ú÷Ç §%¦¶BÜD1‡ ]K¨ñ¤ë¹ÝÄÏn‹-›H"Å$R—dRÚ0RÕ£-&‘/fˆÂÑEÔ)½ø¡'¬'¯¤ûú‘…_múö¤˜æ\qå¾ã5Ǥ& *!é2tÊÏLdÖï};ê{€a{t¼˜æ×°ÏìaµgK¾·V˜ÇT?4uerß‹T˜ã˜f0s¦tì°3Dë‡5êî„ÔZðä°TÖÆy "jÛÐs½ÿIkûNk:Fïi¥;®u2Â/C0¾‰.J°š q­ö‚†‡'ê)#í'‘î±+ãÀíû¤VwÑ qÖRQ¹= ThÄ›ž„oøõAóCÍ“÷šŠ6*£ÓÖ±‡Ñ‡§%ä§'2žƒd2/<~’#å»V×JQtvéfu ÎÕVço¨ºÅʶ]ÎÔðìW‡ò§‡‚8ÒÀ>l`è†YhÔ3ôR™0Q£uàfÁÑ[>÷‹@è¹Æ‘x×K¼(Ïá8üÍuåC‰õ¨X ù¾ãdç^€•‡b ˜s’úa›¸d[Œ±×øána²öÈשJ‹¯ŽöM@Ë0² ‹“CC¶Æ=*lÊz‹ûOÌs˜­´“”×â×ñI¨ŽyQ]|YY»s¸ïx#ºæÆSÏ˃Oš\>žºä¦^¾½6ù9þÜŽqõ+ýÁiØ>C¢©½YýfsQ‹Súƒdx†ðm.Q—Xí*c©·e¦¶ Ó`Eàfõ8ž•ª&ÿ‚¨‘ýA·A‹æ±e»|›¯ª]Ûôðʱwbûˆ,¯óm*k¶œ3ž7q"1ÍI»)m³3>rNf ß;0Š0c”•–U¿ƒÆ­¾a½ФÞù'Ô5i¤sRîÛ« Ã,_aÏ}åâþP>%;Uñº§ÛÝÝ÷õâ²F%ìÑK#•¶þÔ'ñU8ß çÖbeƒ~¤jéK”plAÔP¹K¥ž›6Ó(7qûBÐÈÖ&ëaËN‹kôtÕD–é7Lݪ"¶J°JñÅKƧ•QîRwoÖTÁÕ¯[år‹[ú©Ñ𑚶§¿Þd÷PS8 ÄÆîä^8z†Þù 1}dË¢¾*ÝÔHC ¡0±€ô÷ÀnðúÔc£ëæ{ìŸ ïs(ûª]Ø[¾ ‰wìnJ*@—GÛú_¤"p/-%cáp~ÙMψŸâYækq^HÓ×a¥QJ2·ÇÉ@uÄõPßtoi4¡îJ}åïáÁ.[úß‘„y¡åòûðUùw÷.Û"§Ø½HG¶5aUµÅì,¨SÜ âaø?Pî¾3€Wý•Ûê±Eû%;&8¨ðë½¹”â•zleŽfΉ•àH¾už PÄ»™÷E«s±•èq Ä̽7¢iðôÐÍXËôrÅ/Ò/CÙ–gЭšœ;Yó_жñ?±K0½`äI :A'au•Uf‹<õå-"†¯Í–Šé}+v?ÛØ22gCŽÞMédaAÛÒA,x€QÃÖOç3§ëÏL:òã#sIðMù– OTfľáö瘣ƒÞ4®£ï÷y3¸Ãë¶Ú#Wçeφö’0.Ýñ5œRC›£7¼ö2Ã5 Rò$hãò•*w߃aç¨(؉éuÀÃŒò2ç)©Ås(9ø]Zí“£ü+¢YÂ2•Žù›²y»Ò»ö8dÕ3Pç4‰ŠõÈhÈÐÚ÷׌6’Á«=ä“[ä¾×ήÑmãîËtDïæ E²ø Œw3½&’³Ïšõ±Ã Ÿæ(ÒESH…Ӝ˙çb0Á“:8VÒ×C‰°)J†¤§¯ÄæX‚ÈV;î .œjÛ’ÕÅí8¤ÅˆÊ WÎVß~nãÌËNÝi7´ñ,µÿ‹5@.Ìeí1A»»rzãv¤„äs`hß l@4˧‹…oŠ2„p+Æ7”Èœ ÜŒ<¼>ª‡5<ºÁ4ˆ(ãÕ¯N¯ 8GÌÔÂÏ3ª1 Ë[ËþW˜ fÇXš¾i´f¦äÐlÞ¯)iE‹6´7"c»ƒ› áltGçlIôqê(Âg£+ñ+\Üawôp]…:IÐGùÌ~>^çe8FçÿeG¡QõˆçÇ¿è‰ôm †¿ˆ²ú.y]M\Ììý'eþs¬§Í×$p]}Ó5Üêûò@ãXÇõŽÅƒˆµÕ³”;»´­£%´Ü õ-g“=ò¾ï”å>gz/¶¡ÎsÀk^zm:V.«hËln‹S•H¶ ÆOU¨"Ôxáeñ=äÔ@‰°`° UbÃr{õ'a¦×t©õ²º´æFS7v9¬§õíw×çï]^U°0v‡i¥ófÛR³L“–9;bT¹¡‹¶x¥uh÷%rÏjœ]ÊGïôvó»JY¥JS4çÌ¥Á•Ñ|įWÃSÉpÑÉ Y­#€vîoÍ|—IM$¦«ÕŽ£Mm{HE.²(ä¥$½ª»úN.ê™!Vj¸Çöµó .ò"jWY¹•mȈ¾²ú)x@ÇQ>ôG-¥œ×J Y­Äòf숃™è"ÎNéÛ“ÝŸäŠý~ÚnJšì=ô¡Ò'“™Q@ÅaôЎ̲øIB½âÓE½ÎÚò—W‘7­²ª—¿ö„6]›î:²–JÅ•Ý=¸Á'ß÷{§ÈÌ«Ž+o*êV*: Ø¡ &ïD•œGÉ—Á#Èû¾’}OˆBÇŸ+Êô¼eH«[ÍŸ—„ ûFRñ D‚í¬ÑÆý y㯽n§rF Æó¡LKB–â—Ü4P+“jñM=v_{¦ò EÙ$Ê;ÝÅá§ û…zñYŠ4QtN\ò¥ÝúEsHðDte‹k””\h\“eYD[ë¿ËtŠ›-*»Œí{ú·~!ÿn±Ó&¸‹ Õ/.‚Ü`5 ^·žÔ¹BÅ9®›?Xv&”ÑéNí>~òZ†öáÙ‡µ [µïép*÷½Ý3j°- ¼¾Sö‰Íˆ½žm“ÖÖŽŸÊRϪÜ¢rw1{=‰•˜:bŠ‡íˆœôu g¡FÞ0¢#j7+kxKÅù faoþD–ÂühÚÅ_“Fìÿ^˜;:41É݆èô•Á\)ú<ó]L¤0{:3ô®sö.vú‘“Eï ÕgC­g£Ï‚¹gÆ~ˆÚþ¸”V­ ƒIý}·ô§´=ë®1U“jÔ{<4÷ÛÎyˆ°üè­;¦ *ß;9Â@3Y™lÉPy/†(ˆ#„_y¢Ù ¶i䓟…¶VQôëùLÄ ¾ø})©ì³cÜ%R³þ,‹š9¼£Úr‘–rt ¼;’p†–GÌ2u}–Mü<]È.T%iB”<`‹pÍ{P/ñCS ¥’âC"K† Mu?`À½Z×y_î>~B‹ußîdˆ‡º{GFÌžK¸¹úW¹y‰·ZŸ)kÒ»t÷Ž<°Ò5ä[ØÂaº\¡s=P¤5ˆº¢ò½gèë&Êë¨)Ö&*v Ÿð¾`ŸídûŽÜžµIŸRº;Ôš"ܘšÔŠwCµ·p ¯m—P‘‹Íɨà«F¸ \™n¨«âµP=‰—FÛ¤‰Ã|Þ` –L!ÌO™yÍ1Ðð5Æ1d°"ÈeúÈIMÉ8e1¯]ø‡Ú®]dêÇäàù÷ѧ(CRF3“IHÕ@ÎG|oû/F@®d?j0`efûŽ` 'ZG`+IÀã×ý´ýȪº(„–§.‚ Ú¢HZjÙøŽQ5›Ë5œW¯šDã³Çæ{ç ¼èrmûûšµ{¬ù°]º‘цgù±Ty™M5n\í€7Íb/^K™?œ“¸ûá¢Õä A_ây¦zZôw™‡$žÅ}&`‚ÛxAë ¨WPÍ®çõr´6\XÊd…êýÛ IðFï)¼ÃdЊ‰s^Áž`œ %¾!é弪øYÛËöµÊn²lV/ÌFW|­¨(C|5õæƒNê÷v_Ô†‹* º8œ¿ôØfWŸXíË“|Ôµoþн‚þpÇ {#rDµë¦Yö¥èaèZEü’Ü!z›ó·åàòÅZïÞdAifâÃm‘iyé|ÍDª_`D}òúÇ(¾æ¼EPd©KÒB 8úTyöÊVr„Ùç(qæ³ÄZö Ÿò± SÌbKé@xú¾l»˜O¯ó•Z„{ʘÍ&›ä,ûÁ˜RÜx¥âÅ©1Ï@ïrÝc–éÆ dî4úù!Öô›+ |¢†-6éÆk’=¸H\™÷V>l³ãã·˜h]Ãý%1ŒA§‡G–µvGQ:ÌY1渨aéçÛ‹ðrÍYuø/g†“‘Õ4fv S¼¹X†¿*$AÓ«Îch¾?ô+W멜¾cq¼ýÒVà sOæÞìDvGFÛ·¦¤÷œþ%[3¼ièCõ𑀉=Êâ• M;‡ËËÀ4¶;cíè/‘z݇p‚ÂX&ûIº'VVvרëÚe„Š/`¥;7åB#?ô¤†½ª´®, â»Vs²‹¶`MÖ¸!2|609´F„…¼æZá®mÑèO]‰L>fßa‰¢è—,ë%yLS~¢ÅA”OŠpüˆ‹Ã~l%»åÍÔé¢J “\nÅ8(AG¾ Y_ð ·‹äOôú£ë𑹨>4mÖøa+kJŸ+è³d¶t@9\g ŒÞÇeµbë@€‰ iŽêî^³”wu¼F±6nRÜ!7˜n¤!'óvR…Û¸CgÅü±r\ñóLF&cÇ}ÜÈl:ìRõÔ¨ŒMKÓ̬X¾>‰„¿£°çÍVm©0?ýw9kíʨ‡úxXD‰Èɦ`òðÜ.)»säÃSˆq@Ñhw !}°ãq‰²jü.xñé^Ÿ¢!û¡†hæ¨]Ã*dIo1<–¬I_9#ÿZ½Z´W(1£”·ÙcÁªn ³D”Ðxø¿ Ó°í¾—RHʰú&uv:ƒ-RuÁ1›£[F-³X‰›«óC ±‘n/Î?ïnIi¾.6ÆŠcñé; %›ÕBlÆfìù·hÙô¹ÐbG6>Õâ›áú um f}˜ÁžÃ1 «SÞUœCUëÔ ¼oÑ™èw Õû`IMßÈF¿©:>¬ˆ!4û_3s­·`ã_çjµL¢\>Ø÷#dì(£ßY-%eÕaâË!©‚o±YœdFòÎR¹mÞ˜Âi”<1•$üÛ€Ö‹® â‹P]Ú*!ªfꤑ¸dC;‘uÑAGµ»h[òøûœ²I!4­ ™_;áÔQu0_‡9þÐFËØ‚BCyT×…{»8Îɾ±¢Y&šD"N[ôBY(2nBíƒ<ÿµW§Ã㔳-z)Ubuom/a”FeãµÉ¶ž±‘yù`l êÀ"BæJe’Ÿ%u&n:ð=S.ñü¬ÏÇÕ‰#Ÿ4<û,ny —Oëoäx@šð: íià‰÷‘uKÂÔA:V„¥U‡£!ïbbØ->Xsk–Z'ÃÔo_qX›b]2—È0”ÃŽû~vN;«[àÇ·[Qì=ê? eé¢*vÈS–…œÌw&èdìn*ô"µ}NVCzý@}dÚ?A®[/rCÓ“Å×CŽ¡î ‚èüœJj–a`S½ÉOÒ€µ½xÂ>_5‹U+Ò{3ˆosûÅtÓ®bé0ßéx«5YAžç®vzÒ :64{K¡[o–.úW«¯ÊàÒΩýô],4FRn1Ý&­#}ü[rÆœŽ¶¯ë2iÇÒŽC"ŸvaãUðiÜ,zô9®U×Ì nÈîjõÐRª~LD¦ÐàéuOÍNJ¹—¼òrœ¡å¬£¥Ó{yë±¹ æWñ¯¯$X{ølª«êŠú¹õÑiå#•øs˜ÁŒ+ö³ú©âÕå`˜õÉ‹ŒÒõëV5=Dù()u…pAÚ­@ƒ§‘Kq™Áòêvl3ªC´TD”¡â*eçá-_¯…Êg–{C×G²¸’¬tÚþId‚.FõoJ‘ד ¤££Û•…%¶©„žØ¡Úò'ƒw¡,ûb “µ¡ÃmÌa­ÙðQÛ„ªø6¿‹ñ'l¾#ûÜÙ¹,%õ‚«¾XÆéó§"ݨDÒq\¨Î•k±Ž'Qõä_˜iŽìÀðZs” l.ýÀEj ^6d¢[ã;—C´0c£î%§2Ê•*nO£ÆØ|AÓšF–› n²—!Â>3âZÅŸ6:‡j}ÀÍþf0P X©pcÊ„“?Ì#)Ñq“ëéïÐóå‚¢¿ …p2²Ús'tc‡©ÌŠ‘['ÉÒO÷êÞfÝ”H–ëýÒ±é}^ óÙÀ<–øAÛÎLЛèxð΂wB&…áŽÛî9²2ë(ǶÏaÞø§‡€Û´U&Ý&âœ\Gã‡9¥Ã%uAúany./ÀçÝ|þ©Ù÷>Ä!5é ø_Û¿!–ÑˈŠp.:NÞ~3ÒÃüêsBN›Öqàùm• ʦó ok‡éø§Z|;/—õõŽ´¯–.ê}”‹…•@D.ßÄÌÝéÃc a ‚åíÕ—‹ÁÉ ùÃõpg€ìZ®-U(NŠÌ}JGÙ¾)½¼øVêÂò’}¥¬¢Ô ÂþnÙìuà`·”‚èìjM³vÀ¸–½ü)Æ‚R)Eˆ+ ^kާnê± ß.-¯®^<¢?jãûò¹!.”ö!Ÿþ0u²s4EüÌ•X¸I u†déÆ>O›ÆÐõ>*0üØôT¾ Lý|ïÛà/–æ1#ÿ Jù‡í$¬´hÜaJ²Òd*f ‰P¿ < „(ú #¾½}«‘Àè"~¸ÓþZ‰%'î¬éRŠ¡ü¦ÿ51–H{ùWu(È9Ö¸ —f<u2NgÕG“÷¦qÄÿ8‰îmèì¹|Ü4n&NeÇçsý´¦$¬…¾‰ÙÐê‹7 *ÃqRŒ¦UAËŒVn3¾!’—ëíI1“qSe¦ÔMØ.Nå'­ˆÀ˜‘oWQcƒ_骘úœYß^>Lmky-<÷o|~#´®¸dˆ‹0‡DÐ1¶ö¨§}E2àÐIrÌq¤>~[ü¦ £¿ccý•C"šðгí}!¥àБZlAfMâèˆvX%f¯4mùõü;Ä®Èû„wµ2rD?xñb¨+P "îÆ(„;GUY~Rôß} FCÃ’faRò¹y‹P2Ý:»-?D踵‰2ý\Àµ$„Û½Ñf÷.æS0ЈՋ³ÁªÛƳ¦ ¤˜]úæý1ŠÂ· xøcv°ÙšxJÕ±œBS'8Ñ ’û ¾sÚPC­‰f{l] Jcƒ+1ýýà *óËR÷ßW»JÞॠyöå=•Nìygt\\|³+¿ï5Æ{ÜÓÓ˜V÷Œë‘(ž;G'R>#¹àGœ*p›þى̳·+…¹P;³¤äÞ³GM&g´-±øðBòÜk…¼¸–Gœd÷ð×aáX).*8ywÌdQ¤ü‚¸.}Ö:ç¯ tc¹ ßÙÍ#h÷RCµ¥yÞ Òp¤?¯‰e‘„•«Ý)îÌ»Ì JÝcy².Ôa§I¦9«µfl>L’ZƒËÏí­Im…»¾7£ârR½^åè5=h‚eÓ:ÏÀýþÕéV<#^ ×€R9ñ/ÁÅEÿJíSÙïþÚºåúH[7Œ6mþ»ÖŸÇü«ÕOzyLäQ‹ºÒˆ‡«‡ô K¤<Ô:že!`}ØE!«yÑ™.ܾZÆ 7.äÍßP Ušªy84úa>^’Uƒh§yºç3åÔ^Ü œÇaÐUÕú«I=z®0XËJZð뀿€ïñÆÅü­ ,AxØ2jÉ#ÃÁ–°(„¹U?ø%l‘ l¦dï ,½¢y»Á Åÿ ¨ Wó'wý“»…<ã)p~0žô:pÙð”. ëæ½ÛËY;T%"Ó³ð£0Ì#UD½*»”ºõiLQp¾pþØ#B|T‰3·­Ú†£NcÿÐLö€•5?Å[I'©CĪÍm`„´2¨v xÚmÌæäcs¹›Ù°EÃ0æ©Î˜oÂA½yVË‹g´FyíA×±s¸T˜9a‡7rÉ1Sš±+û˜E’‰ýy·Zþ¡Ž£³áiÚ‚GsÞ­ðx² g„Ú‚†³%fHw‚|ör"Ò8€aç¥ÂH£Ë[Þ¿–¢_]ð1ŠulmåÕ}°¥ÎpìÁÜô!äq2Œì÷XϨróýs\ëk¥ Wo¨ÅËK‘‘öþa® d[ps倿8Ú´]—ÓÊ¬¬BäqWk\8/tkÅB¸éx§#éCÉ5ùðjrt=RX,ŽÝcüÆdø$h¾{pl9Á¦w 8DHl{‡È‚¤öâR  ¢(LÕÒ(K£Hì8“‡MgûVþÒ.1÷Sïaå½¼°ûÞ˨ÿ¥À´©Æœß]Ý>mãn~Xœõ¯iðí„d“A¸ŠéÎ æ9‡C±žá¦k²]Af8WÆã4Ü>:\¥T[€Æu½ïz6¹º ZÀCC¾jÆÌIÎÉáóéa·ÌæË121tFÚ}ÔZ±7hÛ|›CøÜ1›Ç³ýˆÆD×á“Gl§"MQºÌØÍÝñs^ËÍÀŠð%xOOpdß6 :ÚOc Æ/ï‚=14TL‰Ö ©/ÛK&þ–®7óŸÉK ÐÂÉÌl7¬C×Mág’j½ 7'< qYI›´èyÑO·[mÒæ"qÇëçD¥]e7uð)=É=´¬™Ô‘²Êö¿J×Ö§"¸ò[Þ•œÏ#•{h"ð¡P+:yõÃðPºsÐ!Þsq,Æ”yKbî†UŒáÐ˶X€Èßè_·æ„³¶Ãt°aê›Ë˜Ê)00lK×-2‚õ»Ê,0BòýÒ˾f<‹sâ¯útfƼ¦rHUA;XÃxJC’æ§¿×˪.Î\óß¶¾l\|["-áH>‘;_ƒTt¹9ÐÄX_^·©e ?dH’ñ91¿^*aBô ²¿núËåµYªB˺Œ5£¯p/µý³!îÍŽgí‘“VÝè‚T¼lj¸ÞBäLK$¤j^Ø4¨5r;”:S´ù0[·ÇäPèT·=î¨#‹È©æ'ÆH•ÊŒñü%dôB,vž(ï\ ”åŠjÞ¹rîC'ðŒé¾6øÕèÎÅý±ëË#WœÑuÈ¡rª´VÑQÔÖñ÷È7Š ãkE=·ÌÌ¿NÂ[.§ÚE›ÐiýÏYa/Çø5$+ÉŒZÀ÷Ï|z,i°ò¢ØÓ¨µ”S§²‡½ôÏʤ¾äšd„§ï¦ž@EGé«éåÒl›’É>ÆF¸sÔ=,@ 6ÿØMè9se®÷E÷x£”'ÀÑfZ?•XÜáÒúeî§ý·&ôayA.Á‘¡"’ð(B´\Û¹D‹ùí+Ь7l¯,H„¦^tѰ¬íƒ ;À!½;ìëq‹Iò´ËŽ™žã¹"ðSÓTOeÑ+ǮлµúpxV“ä U×<3Aðî;éúY æÊ¢q–2 fØ4¿-¬i^AèihÖ6â…‹ÌÎç•®”äšu«êƒUplˆå=UyÆJÏÚ ±.Ò~"ú™ÍÍÛ‹Ù?I‰‹\êÔkı¯~‚Àp±³§˜]CùÀ™ˆ×S#-‹E¾ ·mÓ…¼«7qt„Ýœ qà(Ó5¬M³Ø‡Ì¿Sj¦B‡Ð0¼\ˈk9ßzy:EåRÕǃæí¦»m CÌÍ? t¿#w¼á%­«™›ØÃ‘)A6äÜ•Ì@JWú”ÉÉzrËC„Ó’uç”SŒÕìèsèâòY¶CŸÇ$p/’ÛØfzEÁÈ·º!T·ÇNŽŒÔ÷?ú¯m¬úÞ­¸Ÿ ·™íøV\€¡õtE—;¡DWB¦ÀˆK¤hóa£“¾qšµÊÄ[+f<ÛÉÉô»9ÅÉ+k™({´æË€t Iô¿8=yØ < SŽä!¤\λ„l3%Ë:òXàz¸ÆnqEøÃY;LæÖ\¿R¢SbGš:}YoéŠÈ$Ÿßò²…;Ãêŵl¹%‚+'ëLQ„ÖúxeG«$þô¯|ާzø³ƒÀ¡í’& ôq¸Ç~0½À GËkLŸtTu±ã vÉ{ FmRн‹aËÆ«:í¡÷æ”ì@Ó1ê+=æ=æŠEƲKÑ89o6üµ¿E»ã<ß=ž˜âw}4ØUààpÅV=‹†›þyü¬M"Š£Ù£‡¶ 6BäPÑ;ö¹(®ÓQWp"½Wô÷q3m˜\ðJdêOµ×WHܱÂŒŸªçȘgÝT^B¡iyÒH|†¹0_·¤Ú~)Ý${¿°’GU2¼ÎºÞ+¿*Ÿ©SAcGÞžçó›„„ÿœ¯›e<{îŽ=k¹Î$&S)ZðjìÖÝyÅfh,‘ùã[üà|Ö³ƒEÌ=tVÐÞëH'ÿèÿEÿ„5ÎS)V¨dJ¯ ãv£y±rÙ‰–ieO•¨0’ùåxì0*\cõ”7¶·›êÜcú#IÕ½¡ òƒ”‰R~ö$¤[ø*žÐ÷¦ÃyFhÌE/ÄM4Ô {ì¾n»p£Ú·.ÑÙ~*Æ{e„æXÅÅÜL~GÝ.*¸“9” Ôò×B„ѱh•Á+yÒ.‡‚ªü>˜‚/õcÐ#“¦£¾ŒRHK0sˆZP7 ä"@YzD¬¼34¸N,ŒOã4 %u©…Kö9§>éL¶J§ð}UO»¸îéá§0ÚûrГ堨ut?,sâýÐÔýÌâ$æQîñòì ¢¼6ÜdÀ‚‡ǵ”1ü}ƒªÕø?¦n‰|ÎøFˆtÞÄâ<Òý•–[2¦¹’ËûLé]hãÇh1ÙYã7ÂÃâ0²Éþlêâ-¢PÞ^wRVé{Ž™¡ƒFoöþhÏO3wê—&~}CxÑ9úàÁrÄôÁÆjù˜×LWü‹×ÈLÒ f}lØŒ:/¬G#«²Éýtˆù™×_‘ªCÖŸ:…†þwÐÄ*z2Û¦=Ê0¸í®;Áî K«”Ô¥pnàßhFe›Aæ¹§`hµöqÑøeÇcØ8Ž¿ üS>¡ÒîrÈx[•âxñU8rU¼u0|ãTæ²,ä'x3ï$GAŽHup ‡Àf}Žuéæ^‹Úˆ°¬WÜ!µO¤³Üò(cL`b™H¸ÙóMöTŠœÿ5 (Q{.±ë±a[¹4Lä2€ åîšÇh.â:b{ÿ<ß`ÓÜÎl&kxØÔCÃ5ˆÑA€n¿.õÝÁUU ‘ï¼?(¤åÉ·±vIDë›O~Ë\²ä ¯rb^Ôöž®E銄}W2@R'—ÿ‰‘!Ï<‰‚=še¸Ì< 9èL¸,,¤S!§†jYø Ûjòp„‘? êxèÖþé)Œuwõö$¸£bì8/M¸ÇéÂèÝòÆ<˜@”K3­iëÊQh˜U›ß/OÕïçz™®1̃±²Ÿ%E//ÈP0åHï'Hñ,Õ˜øÛÓ©°Ãí¿ôZ¦ÙÃËGÁïîãl.ÕnO  òQ!ñ5´&\e Êü: 8cÂ¥ÎDf¥Å³í¯µ&#vEy)±ÊŽ‚´\ÜÑ?ÐÙ¨_!Ú!2› d•LOÕ-»l;m!—A©Ð@Šç铚iWÈ®u,þó] ". g{eÛé:¥–ÑëÒ~FE¹Ë ðA¥›è8>éi/Ýì<š3¾v=æDé#— áâ]ãҰ綨ñ}(!(rÇòÁU6ÐAâb|Â?) ÂïlG endstream endobj 261 0 obj << /Length1 839 /Length2 1219 /Length3 0 /Length 1797 /Filter /FlateDecode >> stream xÚ}RkTSg]:y©("ÃçŒÐ¤$!"Mx¿"Jy#-´!¹I.$7!¹±‰X (•†…X¥‘‚]<$ÈB `AP,j±AžC™ µí”vÍ¿ïìsÎ>ûìóÙn z³… Cˆ D ‰LAL”çI`.Bô †C\)Ÿ)&FRˆ2p$‘ lm}Å……ˆ…è ’'%Gð–r#™â(.t •Nu1 6ÌBAÄ…‡• »Ž`<«8[*ú5‰%!Àað£g ¾°!ŽC°…YÀáXxŒŸì B™R>…Y<¦«Ä†K6$(\ð±j„‘Öò0¤|~0S€1ý¾!ð o6‘LÙŸš˜˜/_Û†³¶0‚¹<àÞ°­MïB™˜.o„ˇù $aÀ2ˆ £,à0ùè|ÏÊ6|B…xÅf@¤½¿&ɃYI$‘ªój BØk•cv¯êvÜèjÿÿîºÚá°„lÁ®Hݘb1Sn@,¢‚ €±Ù2É0±$Dˆb-@$ESG(6X9¥³pñ¥’ôÀ8HøL où£ºP&Œ ‘rÑonD ba ³Q6ó· VKþ'Æ–Ã2°L"“)d2¬<Èzüu*î/,òñÊ@ i@£¾\v8§þ±Ž%‹!]ý³˜Ï¿Æ»%É –Á}åúYâW§Q•EÑw]~1MÏÇnñb¶ý»|üØH–Cp]çk(tƒ²­nÌ\v»ç@ÖÅT¯"–tf§˜¢œºšjñýzhÃRÜh¸gkÒà„é®A½B×ßK‘Ô¨õÚ$WõÃꞎYËk£›¼Ž¸§Þ; ¯ÛzçîcsÃ׿ëebUÚrNoÎ…qh=ªžKŠyV̳QOÈ$óévãÇ7`·[Uza¹ åsC·ëéö†èOš·¨j§ÎÑÈD{-—8­O.Û¬ó¹¿J °k½¦OZÎü°òáXyfšÉ¦/П¦’ŠouZ_”©—»5ù‚Úìöt¾íî¹ÙÒýÇfÎá[·ž:ònÛ[µÉpZ‹„ðƒHºâÎß2VFˆ_´†s’›d¯,ܾ5Éõ¬`Ž·À稒 Êœ ãF.Ì3ýa³=ä‘`(Õš.0.èóÍ«Ó)r«DûjzˆóðÇ^;¯ÇÙO„˜gd%ÒwžŒéÄàæeï7ANFúë§´/.ÞIï"µzÂ}¼êˆÖðÙŒü€í/¥|úÈÉz¼åË—©ÍxËÚ"í.ç›{¿¿š³Y3'‹bÇÞWÍëÆOU‹–_á% âþÌÀ¯ä.ù¾™’aáaé pUÕºÿœ–vº7úhHÜÙJ­¾ò½ƒ³-}ƒ-õÞîÊPÏÇ;þÕ›»rII$]wŒû5ôIk ù9¨ÇlZï8Ô~£ïÕ*`rß²›uÖΧ'²—+î76NÓŽ_l› +h7>6ÝÉw\Z(©÷ä·Eä—·¾8SnA°¼4ói Éü@·öíñuFK;íÔ¹gu9\>7Ô1ÍgbP;ÒaþÉ[3uš’›}‹/Ü sÚ›NñÒÊ£§mèó¼Ie ¾Gæ:)‚/”®ëòïŽW^y~¿måMB:·¥PþàÙ R8ú8$Êmñ„ÍÏ õ^ÝEÒójd|Û“uï\ô{‚ô\»WKˆ/;ç›®ÃLÔ_ïW—¦ÌqoSW»%Â-ÃÚ<Ÿ^·1¬( ü0×ÍŠïL“9]'«ÂÉN c?^½Dw¯.­b Õ²ŠF9?—–Ÿë)n j’ïLs¬j&ʽs—–Ý\+,ÐàœxùCg¾tKAàIÓ²`½#fV÷OÚòkãÃí…afn4¼ÃÍG©mŸßŒÂý§O¡{¡\”3ÆÛ5`æ¼™‡íé@û¸É£ÿÞ–³}¶ø¼þÆÛò ¢ÙñÈSœ¶eЙ‡Ùú~ Íprº×P?*çnîO–Š&ŽÎ¼Þ¼f¬u÷ÃNNŸ†›Ô¾ñQÏ öÈsÐàªØ³;¦<Þú½Œ8ëÏi‡Œ*Ô¶Ô·-H·mwÞv‹‡ðSÇDM{,1HvùÐÙÅ·íû¿a—” ?þrj®C/öUI˜˜S–©Cªj\8®PBÔj®½¹×}æ#›H\Ôi¦§°^1“š> stream xÚí[koܶ¶ý>¿BÀýÒ¢°ø¦È"ç‰Ó¤¤ ì4'Áx¬Ø“ŽGÓ9IûëÏZÔÃ#ÇNÆö49¸lŽ$Ф6÷cí½)J9“ÉL¹"SÖá2"Ž1ÓFãh3]øLù˜Ù p4™7¸.lVhëmè+])›ZÔ`DcñS ›S<áxWoK—ñ¡Þâiž#DÓ<:D\al-5Û‚ţʴŽè5H³¸…Ú‹i5zE‡>& »Scà¤0 .È ½9;•PˆíõH“+A7Æ2Îñ–ËŒlì34»™‰žÏ*2«$OBf5çÁCê¤Ì¬Ó´T™õ…aàZª1™“˜±FOð‚'>sƘœÌðÌ"—sF)œpJJgÎL@¡·¹J£¦Ð\F›¢¥E‘¹€ûàNgÌФu‘y¥ÈG™ñá¸ð–œU1óÞ.ðÁˆAƒÕ…Ôr¤ñˆBEI^g…ÁŒµ6YáH©¦ÌI!RDr2p>Š¢ÇIÁ[. |ŽB÷ ½)<"P§0N0ŽÑËPfÐŽb:¨Çðœ8 >:§y†ò¥ŽêB©‘6&‹ƒBðÓ‡rFYð$dÑÞŠY,Uü’2ð —Æª ΄¡-ÔO©Tg9íFš¡UÐzj³a_¨… ¨¦¦@oÀ°ÖаŒ¡Y‡+zЦœ/´§¥‘sÐ;ÚRáG·nÄã¿e&nÏçU=û§uº~0ÿ1wªåa¹|!a¤ò¥øQü$vq¡p1{å¤Î^ÄC>x¬É ÉÔ*÷*™nîƒA³ÛÙ­[™ØÏÄýêq•‰»Ù7“i]æ»{·ýþp\óz|0+¿ÍþýïþIÐÝì…rÜËÄÓgÏ¡»y"ÖåЛl~:›½¼´­Jm g£¦0Ûœš¶Þ6»Õ¬Zî/Æ“23M—Gãº.—s(Cºüá}}¿×%¹Š‘¸WÍë4×{Ô1]K ïAÂm;Ê=è«’±»EŒ]tWà#”¡½¢XUEõQºo¨8é ‹GËj²_B óî½L<.ß×Y?ñFÀÆGåóš×å¼^AÙ)Ô=ŠqU.'å*aªzXNÇwª÷Y<Å ƒƒ(—è :bÓ.éÌ O%0“s:úîèÚ£o SΑv]ÝsÊåd,=@VÀ{®,­Oå°êË•ïhZŸ|?™Ô¯+Þ ©qÉyLø“'Üm°·ÏLK(rÀyO  %'°|bàÞrB]G \Y.é…>EMˆ½Éb±»ûøùé‰1/(š–«Mnù[¢ç2TO€-r£éÿsŸÂ<Â1@¼ì瓦#nߺ•F·'õ´š‹}ñûÞO,ß×õbõ½“åxž/wËê Ï«å‘lýkÿ×| ‚¦'å·Clõq ©´ærl´õ©­U:—¨ß¤-—œÁÍuÛÞˆ7‡Þbx½Œ‹blˆã‡@6âèÏqZ Ž[Z™;pNU2¾•ð혹ý¤¹Lko·g»`6`Õô¤éaÉ×£„zâæqÆ mg™›ÍšZDD*¸I[ S`ò³I[„å¹–q»ñ˺m Íf`QC³9o#bdì?ÍhÏ‘n躎ÙQPíQ·Ç6Ê mtÚè&´ÑMh8Á,­9¶Æî1EkŽª=êöhÚ£m~›Æka®$ÙKÓ8š˜åòˆž‹|æ``Îü²£ÆI•[dT_†(oÎÔßE•Ç´jÌ’:ÜgM8#p gô C¸ôÅè± 4èèq‘vñir~ÞßOÔl5º–E¸Ž‹Ìït¢ )òç$$4ÑOG2j“æÓ”ôÚ¦¶ÐÎh ˆ¤Œú"´håóˆG#–öŒ­áí¸àå ŽñSë¯Ç«:ªÛ#báJQOÄ•ýŒô¨tÑ‹ÊÀpT‘ÙÅå2r.`Yä"ð®Ò“FòÉxÁÈ?·Û#F+0…‹‹ðŽ+`‘ODîsäö7¢åÓÉBÓ\ÈÀkñlX2×{cÁ$àêéÏ»wïò7Õá8%><Ù¡àÄ·×¦Ï ˜t>!Œ…ãwH %è$‡«“GuÊ÷.ÌÎÖ¿®Ol€×¤o‡S­P2„mE¶]Z{ÏrýœÑuZSyA‡bÉexÐêÜÕhí¤¾Bøºª^7”¾µRLe¸à¿lV®Ûx“¬|ØÖ·m%lz£¦.(hËfÃÚWv³¶€늷5 ÷<â}•+¸ÍMÚ›ñ5Î&M13VoÒ´à’˜ÛnÚ4ÈxÖ²š†ùÏ07®û^¾‚Á7cZÙ¥M:|6iÍ´‰ozRúÒfŽZµinÓݦ=ºM{tw¿Mt›þh÷‘ôçÓv\øœ/• .SqqØø\ "´3º­ "«þµ7 ªš×_¹„vHÎ×› õ)„Ûˆ_Olá»»°]éÓ¹`Ò7dJpƒ¹#LC¿%Ò]¯ÀãiK³š•`飯Žf¥à–8êbãÕéA[\Ü!&D² DzY[…¶E±Y[¨BPv£¶>¢­ÛŒ¸D7k[ ‘×›Ñë íRmÖÖp¡ÉoÖV»œÁÙVcÈõ¨q=ÄÆ—Ÿ øÎ~²L,Ž^/–GÙ‹žq·|;”{÷ï¼äP/“„ã©P¿¹O¥éšGèüF¥o1úâRÈb·Rp§JºV*mçâuê(eªg§R[Ô§~m»¾_{­íÇf}G‹õ±!Œ˜:B¥ÜŸ“¶“2ùüó$SÒý®΋¶O[^Ž^Àoã·02§âðÏòbs'ûZþ±'©sCȆ*kª°PÚ]±™§…vq¯”GŒpŽŠç6FéšÛù2k ‚âÀ=e2‚$šNG/¹8ö.õsQfÜhÈu&ç­ä2;i¶)MJúňs’Üþg¹–ÉM™Žºôœûß8 ·˜ °ku’KW8’B<É’zûUû¾€6:Êê‚b¬Le¨uÀ2mr . 9Ì\)ÇHMåîH`G?gkÐ&]±èKƒ‹*¸ šcÒVf8’ÚÈm˜ÍH’‰~Ô#®Û á±Õ:º¦Á€-Ú'Cë¸é•ç"´‘û9#îB2€¦¸ÔÇñ-@á}†]ƪ ‰Ë,ÜF ípºs<²AÖôv•÷HMç€ä%é¾ ý8¶°½U3”è|ʶœ[7κs#­3î|ÚG}ÆH÷”º¶oëèîéXóa‰okÇŽÏë>±kOþt÷ºbšà¶ï—è]çOçÛ¾Úööq¢:ûèâ‘›ÚGÚ¼ÞÊÞ87°êÔ×ào»ÁÚØ´ÛšÇF\üë(H"‘k$ô¾|º8/ÅTœl¹Ùо§½ ÒZmÚek. žDuOäHFé¿=èꈢµ­ëíø&uM½keû’¤ƹ’Èí%¸VÖ%¦[)w’?_HX±Þf]›Z ¸L=©ò-„¥r),/z Ù:Á3Yv¿Ã¿† ,Šy36Ý3œaúƒ¯zQØ7tpÍ=øÛ Lh2(5\‘…€ŠF@ȸ!H<NÛÚF Ž_Fx¾ô ùüŽÞ¶ÏŠM?¯BurØà³Oå’À”_z€Ë¼KA„Ñi®mâ¥ö @ÓËw~a‘‚öIa„¡³ÑIÕ’ðRΠE2(Á˜>¤Ùò™6m²’i&Ü»žh`Ø,׬ GÐôêŸ ÙDò&´F“„‘ösÉÔ•…ÑxêÕ tC{§—ö>4Xh0æ8\{xäŒ0{kij’‘êF’†vîíp–›l}¬·|ñÈÞ8oJÇ$ñ %K-H°V¨ë…ZÒiÀù’°–A-X+I R™_P ¦>Ö ñþ¿„x© -¸ãåêu-®èÁzרx0¨ŠápÖü†hsx¾iϹíì6&7Ã_©s°m\ZOìÊUw7Õ#ñÛŽàMÞnÖ‚‹¾oû»6Zs>-õmΕ4¡¿h~ÓK™,½P‡f¤£s=ÑÍÄRpǯRÒÆŸØž»ôc<ÏÉT«SoRmšBSë΋®gߺù5‰ sžP#×Ý]úY›Ù-H­zsµñn¹š,§‹ºZ6«¿ŽOpç§wŸüðà»Ýãñ².—wïÜ©f‡h0­2Û´¼“Þ ïð“ž~ï¦ø5YôiKÕjÂWÃ…S#±;^üXNŽkð© >÷v€Ì#ñS=žM'·çG³2“#±_—'OÚ#ñ´í„ZRÁåÍoÄ®ØÅs1b"E)^‹×ÕéRLÅLœˆ¹¨ÄB,ÅJ¬¦ïE-N¿m(½7ÅðüH’ï©ëþ—s`ÿÎßoÿ¶Æ½êd<¿Œªe?=Ç9dA°À_‚`.áÀmq\¸+~÷Äýô†âgñ‹x Š_Åoâø³ý.þ#žŠg‰SãÃi¹,WÓUâÙdRNg³±˜T³jŽß““qbdz–(OÇ«cruŠÿ·àï¬að‘8Ç-ŽË9xýFüÑò{>—`z…ß…XpCÀ¬|]7gË4â¢\r²^–¥¨ßUâT¼ïÄ{ñ—ø[ü].«¡ÜãUä~wïÇûû÷ÖäÞÈçbÁsD+xø¢äšàU>ÈàåPðJõ’¿L÷)éFÆ„ŸŠqkòW‹W¢Ìß©«ÌÿÉßžï=ÿîÁÃýñ|¥äG ß"‡ØIŸBüšZ{6{ ƒÙ󲟽âÕÅ–oüÙì­ CÍo¬¾ÑÎüø³¯¡ 'o®2ùÏî=ÛÇäVóêAýñé;›íÉð™;zL\›½½È^½5j(üFðO?`BùçéxÖÁà‘8Z–cèíºµÒVgåjÕsêœI.f§+Øe›«à)Nç‡år5©–e2¯sŒuWaìÓ§Ïw¾Ó2lÝ+NgãåeœœåSª¤ògœðu«ò–úx)KoG‰¢ÄÐñ“èIV,Ç“’ÒYI<ý£¬ûjœ77&—Áj'¤©›IêÊÐÚʱƒÔæd5%Còz¥Z íà³ó:ˆžø%xê®äGŸýg÷þok’ÿœ2uL‚ɤÖïâNÓåœê¡üw”½‚<è¥ÞIüŸîšÃœŸž€ÑÓ£ù'|&ØN¬Wcâ"¼’Küå÷_~xò軇ãú @õÎîï> stream xÚ­veT]Û’5îîäàîîàî~€ƒÜ=¸C‚ÜIpw'8îî®Á>î}Ýýz¼¯u¿{Œ½ªjÍšU³ÖÚ›š\EYÜÂÁ (ãvefga(ìÍÜ\ÔMÁ Ìv€w#75µ¤3ÐÔä–2u ´) 9€ƒÀÎÏÏD tpôrYY»è4Õ´é™þiù+`æõŸž÷. +0€æýÅhçàh»¾Cü¯7ªWk ÀdH*«èÊ)Éèd•4²@0ÐÙÔ âff2(€Ì` =ÀÒÁ`÷ÀÜlú«4–w,q€)ÀÅhzßô4:þåb8íA..ïï ÀÊÙìúÞWlnçfñw»¥Ãß„Þ#ìß}ï`*.®.æÎ GWÀ{V)™ðtµ6uý+· èÝ p°|´p0wû«¤¿}ï0ï^WSØà ôtý+—`rq´3õzÏýæè ú›†› lõOLg •©³…ÐÅåæû¯îü³NÀ«ÞÔÑÑÎëïÝGý« ÐÎ’‰ã=§¹ë{n+‰õ¯A‘[:ØÙþa·psüOŸ;ÐùïÑý53ôï$L-Àv^  %«’ƒë{JÝÿNe–ŸÈÿ‰ÿ-ÿ[äý¿‰û¯ý·Cü=Ïÿ -ãfg§djÿ>ÿ¸`ï7Œ @ð×óÿÅšÚƒì¼þ‡è Ôþƒáÿ"çjúÞq°Õ»l,lÿ0‚\d@ž@ «¹5ÀÒÔî½GÛ5Á@g;ø®åßm0³ssÿ‹OÃdn þ«é<ü»€`‹eþ.Ïß¼YõT¤$”%ÿõ6ý;Jå]uW /ÇwbÿQ‡¢ƒÅ-þÂpðø0³ór˜9Ùxß'€Ÿ‹ßïÈ÷7û?׊¦®Î O€þ{Ñlì—þÏ?W†ÿ# 6w°økNÔ]MÁï£õ_†¿ÜænÎÎïŠþ}ÚßKþÏõßCzÍ‘çÌClÒ2Ó]«ñsǤô{»Ù¡CKê4 ó+ºÒ"6ø¿›r|Ù‘gØêƳ£íJžåûQÒ÷äc®Ò´ñ2î~f5*AM?ÖŽñ9ŸUX‡ÑãaÓÚÝSU3*~†#™hãtF8¿§¤tÏÄ¡ºsDó7O­ÇmǨ‡Àª.8:¦ùzpGÛ?üsp ë¶gçcv<"µ )¾òy’«—‰óMù‹s¥@Ö×ÐqróÞ!8–Ç**än*˜]ñb$Ög†iœëQæKþ³’ûD‡ò$5†n‰Ø!ÃLõÀmƒFu Âï…\O¥f¬íŸyÉ3î“Dë­LíÃê©?pÃÉö ÅÞKDZجMB[ùÇ:#½MsQg'ùÛôs¤sR<#»#ZiêTÊ">·úä?Ø¿*f_p;jO‰"3£Ke™[˜<»!Íj,,bò(kÞJ{Û×±t,Ɔˆýt.¿º6‘ŒÿèëçRi/%æ‘Uÿ9+Ç6`(KTû-V³Š(9ïî6M<½);m…ÂÎS<àpÊóÇÐ]ø¨1ùéÈÕ3 g¸iéLi ¹zf’ aÔkQÆ­×À·ØŠ01[Éñµ%)CÜ Fò’‡üŠƒJÊXïæ£ÓÙ\²½€ð×6Ôì‡ù³«B(Ë0ÖóÈó°ÒŸ"#‡Èe]”!Œ×ZkÊ(€šÛ¾6¿5Hè•,ʤ¡Jt¸ÛöC¿Ãžå^A†2§Fd)D»¨ÖìãˆAáÌCJu™ ¨ Fi…º^øâù3:›ïàÝka®M”ýqL«Bõ/ž%x]Ñï=C­˜r‹Ä¬2DÙbMÃ0øV‹9’¿÷aQêvÞ ^áè„sŽÀ•z ›~–us4xÞÌG<ÒÃ÷XZHt!°íñ‡~‚kÆésÂn'xÞ®¥}zE¨›ÿŒ‹Æ*=lòaºˆ½”ŒOé ÍAÔ?×KÈþüØL¬Ú ;ýcÇì{DúÖ—ÔϤ«5qiá£þqK\cSQ|ýIøí»çŸŽïï”NGÂAS0Ӓ̧bM‰ìK¤c¦Á²lý•ã=ðqÛOUvÓnõ4m#Ì(Ç>ÈÄ:’üd_rF|GýÈ#'Û–=á³yæœè{¼ÏsJXKÔµW‹ðü…P—•¿X^Ÿƒz'2M[‰É~Ši$¥”»W5ƒ•W»¯É¾èGwwÌü0Ä“°wfB¥ýL/™ìÜ1Ÿ2ý±¦¢Õ¨'*å;"[§öylªCI²‹Ÿgù~nÃѯÄʾD€­Àî•‚ý©hó”ÌÀŠÔ£*=0yƒYÚàWç!q>ט2õ z?â…âº&¦¬V:D• ùP?Xå]ŠÛ,:4Å2ê‹™ÙŒÄR?¡>@ Þ,Æü8]ærˆsK"ÆŒ¬l ½¹`Éϵm÷ó|ú5¨ü ?aÕuŽ[ ®¸=58ÖxÐþ¿\Isd¶m¯i‘nÌÏÏ¡9ß' }›oë)ð'9…%‰ïYƒ2g¨Óñ&X¬<ÃtmzsͬùdKlù×JôvPFßaù(O—RžFŒgÒG¦*9Ç_[‚`iý»†‰¥yÎ÷¼ÿ€ð\SÆPYéý¦œt«‰ \Hµ#¼žðßd­îô­|P”HÐÏ!JgOÒ‘ôcqÄiÑÁßV„!Jºà£ / =D1µ 73b ~u¸;AwGÇlŠ›•§ÿ²z1X¾ìËÉSø®†Ì’xîM¯6Ì3üÙˆmû”å°Â+“¶‘™Up Á7óa¼®ü—VzÇ׺Ë2çneÌØŽlúÆŸéÇÔÛ‡á\¹#òAŠŸ•vFÔƒcì¤#("'Ô¾*7¹+sk·ÒQîBßÌ£´ &r îkºêÕKc¯çˆQƒƒ¨Ûqg“šÇOjÕóÙž’Qo_ˆ_®›«lrñ¢!Ë‹tE)zÀeÓkŽÍm_ÇÆħ[(ëKP|Ç^zú!vgæ‰ïÄò!ù7…iÿœÂ|ÈJ²êp|"Å¢õÜU¨0v¥~Ñ«S—ÈÐï¸^‡„Ôõv1î¯+Ði[vƒK­q7T±³'·†›el â”X¿tãÐýHP•c+;”@‘k‹ýÁ=]rb‹ò-¶åK‡á¢ñ J¬þÕþTëyÿDüp×ÇÇ.&qÓ˯Ù0ᘠ^j9Ñ®d[½]i9§?o€ÝJk(òìNM†Ä-÷ &R{9Dè§ñ¸N R³«èÒ˜‚ñ…Åèu+ØÅ“3Í4jÑJ½šà 5ü˜¼¼¶?éýЦ5Ä…œÊHöPºùý4M¯i™ ÚÖhIûèá.äåÏÂó Ÿúô1ÃPÙ†Õ€$$œ¦žY96ã­\Gt?dÔB °4U‡i‚-ì’­Ï¡Ât9þ¼¥{Á+e’áV^¶n)oiªS¥‹ØŒÙä]Üj©CúݧÊGŠçÜ}±_ìmA¼Œ 4ye?Ô!áŒ^­±ØÉ–`±¼®I¨¥žxàd·zÝž,’…æòÏÃwŽ»¹#½ Næ6³¬UˆÄDŽå)ä·‚§(9`Ý£‡k{Ò€²)NðZÓ¥Rä?·÷7JÐÇ~¶¯Rq–ôò7 ò>šç飅–ÎY[U¯°aãöö ³ßÂÙp²hó»vïb?U@Õ¹¼‰Vª«³V¡G\!|ÝNäª?ñ‘ÐkÅâ™Þ+(¾,7’¤)*ßÄXÉ·Ö á Ê81TÇ.‡¤Xw2¸ÂýÂ}VúþaKV¤A÷”û±Àî2E0zÂîŒRuâ¯mtL z…TÂ[.‡‘EL®a3`/E­ã‹UGM-z¶{/Ý8¡3-ÊýpÒýäÿ‰®ìÏ\•<ÑJ?s¨¡Ì5ó¦gÏç¸}ѯ†¢Ê/ÊâÁçŠbSÞ|áÖ~›|OByÃú|®°Ÿg°uvd`Ÿx¢jz»¦ÐC$„&á§T.òÔ-EÞ¢Ì!¼~Nm]ÇÊî£õÿ¼H¶ÑE1]é<Oµ‘ŒrdEíøD}aDú®$±öêaqÄP˺ZZE&+áF°PsíJ™ã )i·× =ñþé¦T2w¦í)羿†f¡Ê+±ˆdM$þ#ðådƒTšhI6&­·C$Yn|cà0”Öp"˜Eo=g!}hX™Ÿç­iõë9dC"S˜:ÁhÖzo¼žCx¤RßAˆA%´ -|}ªi½ëaýö÷¯Ô®½d¾´áµ0µc߉ÑR“|÷ N”ÑÕ1Eà–Æ™ÿ‘¢e+¨ñ¥›–JHb‰.³ýå×®Öµ`f×§T‚°AÔŠ «O!&ÇpsB²§¸bl>YAe}UþZ@ š³az‘>P²·êGë sVùEÕÝ*qÁhUÒ™›š‹ }]„áä j«Bÿ4^<ñûö»£äK}]R¬Õ|h›N1ê°~V:5M]lH‘*¹r Z†IiàˆšÝT_E‡ˆÛOåg£LVÇR?>2 åÞëOPwà.gorf ¡i¿1wœèq¦´Hy“šY,ó,žÃú.´€¸ŸÄ”§±›+×Ùì&iiGúóåG8³y¹#ôã®¶~­ |S4NÃA‡jØ+¡n¨‘Zåkª¢†.°"Ñ´É›³ÐûæWϺJté.årajû}ïÑ-‡¤Yo@º€’j€’ªº‘ÃÆQýmþϼ£j²A&û^çÁþÌYÄ,9·Â[u„6„x=³AÜK³SH=Tø¤ö2ªÑ=”c=ªÒK¹™˜n¿ëuRhRѼÀ,zsR¢¬ì₉/ßêéæqè7Ç¢Ûñ”ºicZ™\â7h—ÖÁ[7ÚÆZtá/ÜRÃÕ'®5éiR‰‹ŸQwvr.6#JD¨t6̳s±J±«Ë¬•¨.ÀisËKÏD«Fo˜Ë\,¶\Ïá§G<¯uâYyÚ¿Ñã`-`UU:]t¿¥Íx¸Z0µAæKˆÔÈ>êëMž“Yƒ cóµWæE¨Gßb~!)žÌ=9ÛØsüÁmr쀋׀ÿ-âÖ{ˆSÒº¨ àèGÇü13Û»9ïǾ–f°¾#wdßx\ûYT‹mضÇþ"Ã㉘Â!ä ìÝSÉk(4Ï^Ü>pp¡!öê°ŽÛ/Ÿ±†û?˜¦ÄÈ-úšGSš¨^»;@#ŒJì~˜°nðº2ލjh{lªäŽx଺ùéw š1Jæ‰ZÙ4jMÉâ'&“µÐü[]H‡¨(îòËpY™QJœ§1'ˆ—§™ ÄÅ×y°J–%PQ„ÁGTö­2`&oÚki×—ÌçôÐb8,æÊ€Ç"Ä¿¤‘Á½Ë|6æ0âäñFõ&ÛûpxÜd•]e~dQ"ÆÕáS×£póg˜Øˆ²®‘£¡à[Ä †Ò?;õÓJaÝ?šŸ–DÑ Vè½öw À]›ŸH'[Ê}rДìdl»o¹„½.Œ¾1“Áæ7Ü«œIúÝ}Dî%K‡&4*š„Š˜¬Ìâõë àe[¢‰¼(yÙÿ­û»<͘è‹(‘z)l iO[·AFöeû ÿ~R/»)R‹óƒ‹ú!vPœ*ùŸÎñèç¹€H2äJ>Ï$Dx«jƒVoñî% )O‡é[~œd°º²oãÇ÷ÈLÑ¢ûáËteÉv÷7œ¬­Õ±aúÔš¹ÒêbÚšŸÒ´ëzñ•ƒÀ8"©žö§-ƒØà€¹DCq¡wA½›ëv±÷”a&›l—6ÏQþO"3`\ëêΜ²Ü'^Ï!½gˆ\¾qàñî‰bžÈ' ŽØÉJ©Ä¡b„3ÙP‘­¤«¶yx÷›ë ïÄSÕóq©ù…œ–U{NYýèì'éa¥•QlñY º,°T8ç˜;Üyf²*¡²Î‹U-‹â§ü­-Ëü!NE-ø½å„÷n‡þúËÈœ^2XIÙBã %†lçgòѸ"ØÞQ#¶&ãg‚¬µ#^™g]bˆdÌ.ZK ØS¡åß-Qvã*‘j¿ }®˜Yñ|ApMT^ ¾,6¤#Ã<†Ô-qTmú‡I„ˆ´€Žý0¸è•>-y鱟.Fsf®·3¶óTŽxå5]&”ãªsb5f4-ÅÔ» wÔ>¶², ÆÂjnÀ¢º6?k™Ø·/6™ËØv:^î§=-îÛ6r*†j·ßOÈ–ÃniÛ"Q¨ð1ìÔH)Ñ,â븄?¹Ì‹µ8Å[z ê)b4¿ð8cÕ!hè"ÑtzÄÅÿ‡I‰Öc™~yUé ¸Ç¥„úM”Y o¡MñÛ—»–áb¹êåi© ,žš›–£ÖãÍ“W.šêáYùnP[*8ð²î~ûFu–§ë­@ ÓuDe¡8%žŠTS‘~´ÍÃHÄ8_YQTöä37¬F 6y²¾Ù‰©uæL»¹h`šÂ–W®³ä¢{1 É:¥z­!ó”Ê*ãªZ¶òlÿ —î ò¬æùWÎÇß»V ‹;L‰Q«¬® U9Э`i+Š á^KÁ¸R9VÎŽ_?Ò°FºǺ† 1å>„ââÅ—r N°6…í•\}ýM¥¡“¹F_ÿËò¹2Ë<0BÝK¨’÷'ßù‚Á2£ˆÒÉehû•±Ðò7»HbÏL2\¤‘«Ñ¾Hä’cíAM“ðyu ‡éíŸ^÷P¥AUÅ#)m©þ ,Ii¿ó¬·Þjˆ“ 8 ã]'1<Ù1¶I„öMš)8gúá6ÞHÍÏ@Ÿìx¦”»“f˜¸ð`º$Ç\©õ0de&· ¯K–›‰þ˜¡E³*\(ض&Îva–dñ/ ‰6@y‘.7ù0Óת›Ös¶9@ê¨gÛ&jY˜Ø[¤Óo\'ñE²Á€7@>¼öPܰÃþ¤˜DŒ7¸G9¬ …½úËñš.¶ƒ8ƒÚP%_‰þ'Ëbcﱫ‚¡;€X[7…ŽFS»„oÚ “h/Gv¢#š\X¡¢Åh}ĉ¡‡¡µ`dÀÊoŽ·½¸Ùí4ÄkX³_hé¬fJÏ;ìÑ€uùE”òûÜ©d]YŒû6s’oÎc&;6oÛã»èî_ÎuÙ–b4Vû|_;G Ôz³ßgíáe¹ÊH$¢\Ëß°[¾À‘Éaneö "vé.š_tjE§qÄÄ;¦™¸¢®öpÄ~„PÑŽ È(€§û—ªdÐ7…¡ô¸üO‚H/Å^zió2¾¥ù¾_ˆ™Ì6@±¹9%—FQÆkþÔxÀ&v»i,£úfX…^n;Z’P©MÄŠQRî ¥š>=-ý6»‚vÕ}KÞÀ­?]¤ŸpLöƒæK œ'íŒ(K6K³ aÈ …bgÍIå.éüÇÖøh“º:å\ÆÄïá) àzæå¸2< ž&(¾ïX$Åm£î<9‡ IñÃ’ãõÔ¯h-QaAWÛC.œ22:î-”N¼@C"dNæâ ˆyí0épÆbRkšÅê~Jd„uÅ44gÅMˆš?*çDÿœ?¥Åúv˜ÚÝ ê}mf˜¸°z¶7çºM秔džK´UV–¡)€“-ÌøÞŸ^æû–p]Ö…«.™}Ç´P›+Çe™¾I5ùs“ƒù„jÕ¥R”Æ‘–³P©¡Ž4¡iéWؾ•¤«~\ëJ ,E}{Ôw°¥üùÆ@öLžì“*…·^u¿Æ÷N“ýüÛ¼ÌK!­Å©w¡€×_¦N×Ç©T^¿yïUâågbA”+ãëÊm¢ÀâËd–zD»‰@O§ûÛKç8.ã â0î ŸÃ.¾´Ø¡·y͕૩bl'Gµò½ p¦b‚Y'ÉSEO‰ë)_uD³IØiÝÖo¾unh’ıeD2h‰iB…†÷t¹ëÉC°/_ysìÍá rj˜|Òá[ós T¼•üÁñÈyßAHXxDó'Ö„qpÚÑ%Z « )Ãn$"ÈÕ'tÐíÆBd¥éxF;¨§Æ`÷'øÎV=[û“ÔîvõÚž±"Õ7ŠÝ˜Xî¬C(×P_ëåØ ÞC9—OiÐz$ÉMBKÅpëüÈ#ñÙ¤ Ù×’¡Ý£:>ö@ldòÙppÒÈ%ô9rú.D«YÖ]ŠTbømüá„*É W}™ïVl8c2ŽÖA»?À“<4³&ñwš‘i[«á¹ýü¾º<“÷i…„?lBŽ(8?5½“ÿpš…&鮸ú¤¨—›3Íz¸}¸l_#ì!ýû÷Mhƒ³2Ô[­Ú:â)¦ó:HñiîÑ}ªA¤^i%q±4¬‹T'ÖƒeòHÖZi/2¼mj^_êywô/ËØužçk¡qëÖG°Hþ{˜¤ZŸˆ€‰á4XÖkZOðZ~­|KÚËlcFó©ºöµür¼h‡C8dÖ1‰àT]Ý:-- 1“ùëºãá÷ž'¨µà—‚â,YX›È  Nœ¦™8Š'jqs¸ը°ÄëW‘çz ”NÏFަ5ø/I”'lºMÅ"w¶õSBŸˆ±„ð¡:]pÅpÃW"•ÛÕk–•^‡ùr¨±ÑÁºudY¾î±Éj×ËH7Rñ͇Ý\œ¼~ íHþ{¤ìÛ ö´ÂC‡[ñ«à¾Zvôd%¾«“áÓµ?-ÆåNBï”è*ÐÙçiF—FÚK’…VÇ É¼fÃXí#AbsÓΕ±4ˆ®é]føâÜpEµ›&Ð ˜f¡Ã‘í l=Í;‡ûêpFл­h!B4›=H̲ÇòŠ (üMh5s7´×šs'FP:N æ³%³éí8—BÅaí.M(÷ÉÙiÙpÿébí´Ö“_5šD$çYÓ‰áie쀞KÀ½ö;¹:[´–Ç(Îwâ% âæ¾³ÐBñn\möþÚb…m%l.Æ%\eÇu’€N _ê !Áõì8¹X*¸¤§LŸE3“2I_ì ®:”]ÍuÎôFšib¦hÈ sÐmYt,1ذ¥c±Z_à¡‘|Ù’9pßVëo×wLÄÕHà±7 xa͘­>“Lô’ÜJÆcÙî%±/aÆ«‰ÔÇx±`4ÜИ¤d|QÐPorù7Â{6ƒ7ÌS³3Îû #êˆõõe2 ‹úÊJé__yR–(˜L»Ãëö¯Óñ ÷§"S$¹ÿÈ›óŽU¼˜cÚ-Þhk $ËM)1éRê‰õaý1eú’Ú-¥Çf`-ëÒã ÷c Î;Ãm:ázÐeøÕ_! «9´[Ù‹ cH—ˆJQ3øDfku çÛV-ÍìŸDë†]"’ƽô©Gøe­·yÚü¨jäPÃp7¿¤³¤ZàzMm_sJkkA _AúÒgв,3Ÿ÷Míæ,£×N•H{ûG,ÊIê¾þBŽKeÜ'a%Á÷P2×ñd ºË«—ÃËž#*á04*Æ=jÅesu ÝD£zí ‡Án†XJ zŽ5ì!Ÿ|ˆ¤SΰS$I¥D¬þ™7ð§RðIQh ç½ÅüǹÛqw°‰zêãù­e]È•áñdÆ›y-½7`]@´»íqðx‹ÕIÎÄ›(m…P/{-òü±÷VÜ¥ˆ-°¨õ£*VÞŸ«Šßì43³‡TaD§ŠžãGúSX/+Œ ¥§ÚæÙñ È u‡î£Œ ¥HÆÍ/ÃU‹)b’]¹ÐÊÖÉ¿\ÚÅA³?ϰª×ûl«²H}y9¼m‰ ̱LYiî^Ù†l¾>µÚ-UlúÆ\¿˜c¯~x³˜ý>¨P}vuÎàÍEß´­_߉s.óe½‘u–Ç ?Ô£üru·Šöäc+:xt“u„ÉCÃaTC"ΕK¿³Aš ÉéKXú.ììØM|¯Au_IÕ ¼.‡KÇl¶+ºföÊÇ‘L«+[K0^ÄqÝ \§B>o:¡òÞ¾Xæ¾Ìh1«ýòNZŽ*rˆ¥™Ô°§–ŠV'"Vý¸?ÔÇ—»¨êµ‹ˆ¢\ÓÊÉ=-uÞ=ØZó“~WC¶{ ²‡šTÔn’I vزyo܇![Å›k ­X_#nbQ-‡ò“É<ˆµ²ó¿EFÑ”» V[§Û·P®¡†ŽhÆ>z0¤ÎrðÙ†" º•DóAﬠȋK:ö>ôñ·^&i¾<ô{‰ÉŒ£ßõ1>'E^£XrÀÞo†ÍÁÛùÃHçš•K1Ÿf ¾¢Ö»°òîX_=F}]kCHmñ#¯8_]™ÍÛ¸“ùͱ¾œR’k½›·\?Ì‹wL­é¥RÑaƒaòÂ@ÅýcVª€Ý ó3é­€îÌù·E9ÕÜDÉñ,3ߨ±Z¼Œ üIßÎ’ÃÏI7õYóÇÐß’LZ¯eovû¤^òÓü‘$khV-ô¹Ï…QLçðC z’­«Õà€U_¢J®ÞnÍbÙÔ§YN–Æaê£>l*÷D ÈxÍ2ùQ²Ícá«iOÜåôÂtìÁ"wÙ ÁÅ`ª\%‰Ò [ñˆ_ w˱;Ù’ŠiâcVš ߪ5úªJVªÛ~GtAÝÜe5HæÃsqåhXÑÂ]Ñe´“Y®QÏŸ„L‰»Šé±¢Kó’Sèq5^fè5}¸Åƒb7尦̋7¤‹ü6µ<3º|A:%›«®¸Í†°;:K„ºŸÍÍñ@âñ›•» ÃãP‡Â&”=͸ô%“5¿*.R;¤e^Šj–1ŽíJ<’¡[Cî{‚úlû#˜ýªõ›H¬•KÏr¼>êèÓ7\â+VÞj{AŠÃÑš ›ë‰„À}£¤–kê9ÔÖŠý*:l«ox9†zR‚i "Äëa”#+,GFÙf{£$º<=J):Ý- ß„:9°,õün~'—ž,¡Ùúª²â)¾ÚüËæë<`‹ku&j –<\EêÍW(^¬´¢=zÛ ëÅLnPlÛÔ×Nµ4XSÌûF[Ï¥o»{åjjÓ–Tÿ[÷26k³¦Rw±QCo3 gíÕ¡dó¬§Yxš‚¼š QéWuI»UôÂ9HÕÇÅŸ†huwû ¶â†bÙ(fìί÷ö‘à"ÚÔîºóá üuKn‰|˜oÜó>Üë§Ÿ«~ñ®Í"1­DB-‘7ˆD‡]üÇžK”—^ÃiÙ†¨iÃÚýg\Klç±OQp7ƒ–V»#y›Qæ §q§«ƒb†·å˜…›ÙÙñβ.âÒ :»d„úS<üiÓó”ìT.k,ð©GfpªOÖãŽ'eˆLñNÅ`MÒ››zŰ!ÐÈæ~BزÙkˆÝRBÏôßz8Y Pë¼ñ¬¥íà(~Žíi|ÜБQ?@ }óÍ]¸Uß÷£wëÓ%º„Kš¬Pó<ݱ,´†ÏΛ˜µŸÜ‹üžòŒ~Ùø§¡97*~/<¯¹Ö|Xü]/Ràg”`õ;F:d¡åÃd·Ç$Ï×6cWìõH±?sn›18õ¹¸±Iðì$.6$ù [&qž}–ꛤ¯éé^U²-9BÒßÍø †û…ZN ¯*VqÂuáPS¿Ù!K¿K¶Zƒ7-–#\öáåöåžðIµâ WL(Q²BÙµ«µ°£ ?ßÇí0GK-XEuQ_ѧ˜_uV6ásõ^D‚môðܤÆäPël§ ÉX•â&© |…ÕˆL§KÜá¢ï/÷튕)šè(ˆ ;I{kCßìg¢˜6gTT„0|á3±Ç÷ÎEiΖ’V¿ÖÈ&Ìcsñ¹µÕ¤°ìú`¨¸¤ÉVZÃ*ÑÏÙaß6ç¯q‰$ñðØŒ®Í[u¦Z8U›ü‡Q=aeQ^R )…l»ÊWŠÌV¸½&ž¸âÑVb3nfzøžP3f®Å6¡1 úüIt›óh2ˆ!µ] ú£úHL£`Á½}ýéûæt ºòW]ÌPÇ ¶÷9ƒéÏ€0C*᪼!h ÀÏ•)ä,?•Èò{8§s57Lu9`Ð"ó胸œòm¤º²5‡{Û;9^¿,-¥Í=[¥ rK9)]/×%\˜»f†1)öν1=ΑeiÇ#_Èø”.ëýê£Ep ½s™/•È]9­žÚíÛlj¿…y³ Q… Êíù:[°Ù&{ßò¥KdHõ¥<Ùâ9ÁíV«‰RSÙ®~ K¸šœ»ª;7_@µÎæ34&Ö¸ãÔÞA׿ ü1ýE8`}…–YäT}E£W@ËWÔpÐî¸2¢a5ß¾}&SÓGv»¼ MÂëSI„ÃÒq Ô(GâµÄRa]ºÙ>ä–bE‘X°Ýò=Ʀoe7¡~¸Ö~¤µ":=’&ìTd]äÔ¡w‹¤s!¸J e Nðã_êDÍh…á£Ñï©ÏXÉ<¾-‡{õêiGßÐ\n`nÞ´ÈéýþGVäå¥Í,Ð<øš‚šÜBàÕìöRû`Œÿ¬Rzñ^Š&UÛ-[Ó4¡Ñ# ôƒT`†ùøW»S{ÌÇë£ “yzÛ¶+̽¹NsW–3ŸrUCï“´ó§¿ØèA Ð’•ãa>7C9ªÓÛ‘C@d•Šœ÷òJV2^¯d’áõuÁ×kz àÜóIéŠæG‹’ªÃÎ8hÉ ®R×.vD *ZV'>ã÷G§¿®XŠ«ÌÙ]XüZq™ÕÇ%†¬-þ¢*œ ]zׯ&5Ä‚'¶dP¾W)%GÏ|ö«=Ñ}eq”ŠóJùN®Ú‡zÅãyU˜ª*,óÖr ª)Ѽtöi{OZ±ÎÎ÷ÐcDEµÞös9᫼0‰{; :?oiÒ‡®!‘M°†ä¼Eê9’™mqÏ2ygG`z€Èqë‹ãA“>jÛ2y&ƒ-F÷îí‡6KƒÜÂÆž"˃ÌbõdûñŠ0Ó Ê”?uº;–¬:§|Lõ tü´ÂJ^ öPØ/ØÉAZ=ŒêgEƤ ÚΕÕD•œOíjîÉÚláÊL¨ÑÏ£ê™E =Þ,|¬ÆÓýÂòS_S`ÆÚWa°˜Ïäs> ›O¤ÓIñÐqS|ïã´`Ücó¨ÿ<ÙëFŠ‹š±ÈºB%zƒùâ ¿6ð±b˨û¶l BKÖ !§8€G*A„³«ŸZ ùêç v`°.QøùL°Õ´`‹€cÞ4T—# âþ°h }cC)HUž¿ÏêÌPÄb¥\ûÌêîÿÿã>b7 endstream endobj 266 0 obj << /Length1 1625 /Length2 7801 /Length3 0 /Length 8624 /Filter /FlateDecode >> stream xÚ­weX”m·6R*)Ý0HwJJwÝ1 Œ 3À ÝH*]Ò-ÝR"!ÝHIŠ„€4"}¾ç}÷ñ|û×Þïû>îkk+¯u7 #PŸGÎa QFÀQ<¼üm¨³­;R×ä‘GÀìÔP àx‚âà¡ ¸"‘CìŠ0@P ..ŽÃP@¸x»AQvC=c..îK~«l½ÿFî,‘P8€õîÃC¸8Cà¨;Šÿµ¡>@9BöP  4UÓV°«hT pˆÛ]@w[ Є‚!p$„`pÀþ:À¸ôwjHÞ;.9$@º@ÀÐ;3ˆâòâ¸@Üœ¡HäÝ7Š8¸à¨» ( s·ûÀÜñ' 7ĆóvGD QH°Ô¸ó TTþ+N”#õÛ7zöwšv°ûï”þ`w4w( …#(ˆê·/[ÀŠt¼ï|ß‘¹¸Aÿ„ᎄÂþ7À âr³ƒAÈ;š;îßÕùwž€ÿ–=ÈÅæýÇñGë_1@QHÌžG@ðÎ'uçÛ Çáû=,jp{@€ÿ/¹»ËߘÄíOØÏ Ç] ;æ °ƒØãði#Pw.ìÿ».óþçšühñ¤Áÿ‘öþßšûÏý·Kü½Ïÿ¤Vv‡Á´AÎwð×’Üm$@ð{Ï~/(øÿ39CaÞÿƒÑ?!ú›ëŸØ_Ôrp‡»Žðòòÿ%†"•¡^; v؃`wÅú#7„ÛAÜ`P8䮩êyg$ ðÌÀ v‚ÿ®¾ˆø·ûgìw}ú9Ÿ®‘1ÐØ”ëZ­4w#€2ðvþ_hÆZ»~óÈË#¼¾<¢¢!~q€€¿(@ü‰ÿÿàó‘À¿ÏZ ”Ô `ÎÏËÏ/¸{ÿýüûdù%8a÷{hôQ ¸ÝÝœýK𻻹ݵ÷ÏÕ¿Kûï󟉇@¼ `œ…YX2ôYZf:ª–"·TѼû½F˜KɃ¢‚ jDg`Zäªx…ÍuMoøÄÍ[ï».¿6Ô97ß“ÃØ:S!‡ù´þL]DˬïD¹6Cø¬JðÓ÷Œ£}f4W0ÍDø6×Fuõ¬Š¯±éÆß ¹=8:çbò("e>s!¿ª#k{Ô€F\[¸»Çš´}~ÆÖ;4Ðß×yŒÕµAÕ÷ED²Ë˜Œò¶q;}þåÉS-‘6ÆîÄæýYÃŒûžsSŽF–ÎñÐ2MJhå¸i1`Fá+õŽºà8]¥{IShûwÃà‹E“§¾<1žõÈ@âÃø¶Ž³]yåó&O¾Ê- CsÉÈ1Æ`ŧLÉZGìŽ_Á­ÑLÒ­ÙÈ5ØŸ^ÇO[´¨l)GgR´/5~A+œÀÒ7’3<ÿ²•KA=)Ý‚üˆNÆKÏKc!8ŸÅn}úp¤­éþ©žˆwÖ‡ŠíÅpá7òRîfбÝuÒ–Cª£å‘ {Ï6´ËD¤ïµ­4˜_Õ€P›7Á9kÙGph¢táÍŸóT¶«f´Ã_€@—$O¦–#³ªbCC~J.äð÷4’n笎1Ñ(N‡ž‘’^ôˆ$S]Måúð«\ª{ôö3“˜o6x½qN&ƒÀ÷[Ú|lzIÔ7“•bX¿5E1Â{5ì}ªýÙÙ¯+”žµÈ¢G¸GÒM®še‘<ö13ú„¬ËÓNë{,²h­°Ëu_d“å¨Tó2~-«Ò*è¦]Ö"Ÿé Öó×]bwd£l ²)||‘W¦4XöoaÉIÁRaå4çô4ËJ‘ë!Tù&ÛU&"*ÇOø]yjçE0L ¾³K',uWšã!#}°~Bòºù~ª0ItZHÐø ¿Û ^MQClm¹ÙfœèòøÈ—¡´þC>Û“Ýö,ˆÉ÷NBìG\N'Ù ‚®är÷†cÛ'?èöÏÕЯžeÕÆ4÷eG \»yœHùë±”ôÆÂ"Eöüu-Ë.A}M”X³ò%Ú§ªª’è½&ºìRI Hz6oæ­]¢—ƒeœÌp^»©Elsw‚4“‹LØZ‹Z#êˆü¤ÇÞ”Z¢™$‚Læ0^·ÝŒAdÌùôŸpßÇÊw{éºô[®Í‚>†…ò¥/á^‹Ë*nð¦3 ៼ë“=lP’‹ïº>™(éꎅ‡HÀ¦NŸ”ëÀ‰Y_‹fqäa1Ña4ÒIZ-D;£ ÓHGØ#<Û¶Û:xb‹Â>¶1/uNGV[_ïƒL¨54h{5š²gè6±F\¾è \°Fp|ÀlÒã›[ [lΣ•k:qŠ­fìÂ0ýL[ŠOÍ…Èô-ÙÍ7WÈ‹iK×MgׇÍRkw%éH„jÙ¯”ߪX¨á’mŽÐÌûØã&jõ¶€)‰ ÇÄé ‹`J2…À¬ìT™RSí¨ÆF6OÆŽÏrS›TúéKˆ²>ç0i&¡ìÃ|ߨ`ê þ0‹äë÷ÜÝõ´ØÏ«KcjÜÄ 05h ¶ÂÑ^̺±–U¼S£•“þºƒº™»[)Q¨šøÂ|I\·‰$õ¤ U!`äè| SŠDj’¿é¯õz©`&eV}ëï§&×\Ë, º&‰‹Þ©bXàNI‡œRë#OfÏ÷¦+DÉpÃ*OY¹Hüskôã"ÅsI÷¯dßQƈ6 8û´_cvëK® tKä°s)ç %o§(ä6×’ëÔ`TŽe—<—`”É}°Ò¨?°u {É`t¿§¨),åMó»àécU6§(fw¼ç _u—‚‘2¾“1±<9UßÁÌ[a0"T\ÃÄW¡ ¢ú&³ÃcšC¨ó ¥…¸Ûm½»`”‹”ãÀC%õŸú‰Ç Ãnýj0Væ³ó ‹ù°¾UÁÛ]?!ß ÒÕ¯bY?lpJ1œ”-O¡e©@˾]ó~%dqá&NZ ‰Òoî©îÒ'>DðB¤ö›…wQ²_p ™ÂNnë55êÓL8ÎË)ú+ºØ£æÖ¢u{£E5ÊPg+Úx/·iDz£\‚Hq ¢˜•÷?&.\4Œ“öG^¿•ƒeó©­âÚNx„5Ë’J´gmrßì…¶†Yc  tN›×›ýŒý¦³PÄŠM—Œ–kˆ¤8´˜š¥ RqßhxõJ³’(‹®x¢<]–'ÞïûÐWÕ¨ô†žßøÀÉLÒî1騴n<dµtQ&ºôÁ¹F=DAš$…»J^bý4#ÞÌàS¾B¢n­…Ò¸*&ìæMÕ\ÃùAÜÍ~ú¡g9„ð2š½?¥ðŽZa©¹D³Ö#7Äjõbeé¥fɘ6ô+Ní})Xâ)O¨à°ä€•f^×§w°_»Do#½øçÚ3nSKJVDj4a‹p î÷1ÄÒ°Ä©|½a«ìâYŽ óöÒ6þ¢˜÷g"SÀýMxn—ã®ÉîîëÄÓôGoyO¸¸Î9 /½E蟽¤\¥–²é<‰êxÕ “¥è2T¡ÐÂÂT0EÞða$ã‘®5‰œÆ¢Î™—îí8\ ÅKú/мš4mŠñ^×Ó!Q)Û1)un TÉŽi‹ÉiöžÏÄ9»=c'Òƒ!4v ̶Õ(õÍY¼éRÑ´È­Pÿóø+÷<¡þ8L¨¼SÛ€y®w@£H'kñf2\ ´ ç£îÙ#ýjÕª¨‰9=ý•Ï·ã£Óã_š€–/ß¹×ß‹kí‚ÌÏ\óÐ=ŽŠ#}.^íØ*5mø’|Gkv¤‡‹Ž\P$æaµc4ƒo8~åÍ2?uí“9Í;"Á[laÞÀ²½W½Ö>F¨˜˜/éQwjKäÙ­ŒîèµßS·JuÈè0]ÝAg§›*ޤ\ƒO5™Ïícú^õù^<÷ô™¬½ý8Ø¥)Ü޵é<ÀòŠLÂdýÞ¿¨ ]L´7ºä Yõ8x/(‡1DÙô™ò¬1NæÜ´ŽˆÝç²—¬ 5ðê ÛWÇŸ™¼¬îSõŸZ¿“tBnã‡Y[už½nÛWU¯:håThÁ!°•‘Ã{Û–j¦ë†ŒUÚÇøNÐMËmZÐí÷"ŠìF<<ð svvIéÓ˜“9Æã2f˜—ιꀺFö¯‘¼Väµs{‹®¯‹+³ŒHÛ ÜC<ÇûuÒNx#5G?ïE3ç¡E^8}u‹zÉ]ðIJ¹zàÊ­*Úh¡ÕtŽUÛÁ&«Oj¹±û9® `¤¹pŠŽP÷àäQ!¤4y4ºÆÀk&yôšÐ ­IÅÚ‰´÷ýg®é*çžt^KêCȺ< ïPjbJ6£14Fš ø&‚Â<†ðÑÊym¢ã?¼JQ¼‰nO|Ö¢eVsôDo㞤š†å–;ÄZ³¼O‡!IjfÌÍôÉß7ãZº­æƒ?XKÓðEìe&uÖ­Ôku[ÅÎ<¡—3?5GfLÓ–êù‡™Tζ¢¥õïÕUq?È{ºü½?ƒê Q›õ*æ‚G‡S¶¨÷lQŒ¬ûæië×6]£››§“Û7iÁ‚ÝàBrRú‰ïfІÝßì4š.a¾– ¦1ìŽR§Ÿ Ý7²œvîðàÔÖ"ÅÕ¥Ñüv ÞmgÈÓD1§¡²†4”ñdnÜ%¿±XñoÞøàY°´GFM˜Õ޶¾»e£L·ÐÚ—Ö½”/öù¢·¶âMH‚Lg6(£x´MjžgëÙ³g‘¶#ô®ÉˆsžüŨˆÜÎÊÂ’'÷¨òŒý :ÛHKpv¨«˜ÛŽõé=VÑÃà ¢‰§”:-j…Ïb(,¿’`Ù£i•ÝUdšy3©M_R3 Q?‰å¾þf¸—íÔ'DÀOdQœ§à'n:õ¹ï3…˜¶výñÉp`F¥c¥fäÀ™ë¦uC{XÙq26 ²×QIYñ¹Yx@Žˆ>rng…ê‰þ?íâWDÍ“ë2±ËGÙ¨æ_N#©±“Ê÷Ç÷+Æ;š èX†jÒù¶G ?ŒmYb°6Zû }ñ…c¹ §“Ì¡«Ò¤CcS»aƒ=‰yܬ"¤Õnb_w~¥Ê÷WÞÖw˜;ZÛÉgdÁ¸/òÜV*LƒyUL+‡ùÊÔŸŸì^/Õ~nTä¶ñp¬–ëv9Ãh¿Íìg°ðÊcxý[;6ož'‡ l«¡=äO$Êp\Q8Þo¡Ò«Íz—iî82, ½Z' è“k³à ,oîˆ$ €Ì·D³KìIÀ3qCQ1×ÜaæèŠ#í-cÎ"Ã-Ê~&ç]ÅÎI„êð&=!…ã½HqÁ’}½ÁUÏhÌæ»ä»Åö®Î¥ë>-z¦\6ˆYõ*r[C!}¦Ÿ'¬AÈà¶!â×Þ›ã>òýW«O¾çg,n;ÂV¿„‡o4¯@C7†éä-ó±‡óyrá›UU_%¼Ð kVó$Éo©Týw¬#˜¸V#oñÖjÃüÜ‚l¬–xn˜£tâË}ÊbúG€z³Åð*9…«x·îJ±glú$ /m"'á…VÕ‡ï¾K2œÃÛyZ5Œ^e–ƒÐÊ#ѹ©hú.޳ÊÐ-ØøêмÍ«–=káCÌ<ý ÷Ôí`Ür¥˜mØ3Z³&ó¬ì”J´iX?:|ú‚4Žõ?¦sðT~f­ã°X4ÿð3fwssȧ• 'Á•Ý$£ò"|2Ø\þ‰±wƒŸ˜Ñ°ê¼Ó9³QôÙš;Ô‹$v¡áHñó¾°!f\¯nÛ’ê'9õM 33Ÿ»¹À¡^æHŒLû]-îšbÓ‹0„ù÷Ãõx…j¢¤{ùžèÙEîì˜ßï·\Ýw¡7`ïë8ï²0* _/Ýud›Ü¦¶Ü±™èÔ Æ÷Lç í—f RÙv©9ÉÔ˜týµWzX^4zÑå&yßç´í$¨WSîýˆD?¸­Î¯¨Xíçh^4ë€8¿6¢ |ziçPømÍ‚-Ê[ç£è\eËätu¡ÒàfV|«[PŽ]ôí+yädô±¶m»Øõ φö148½4¥ôúÖþ­õà3¾µ/ašØ¼dhlp‚{/Õ®È3Ac’}±´™ÖlÞ‡PªoL$ÚMhDZ‡Á ƒ½ÊõÔCÛ¦ëä*¾øÇ`ž•®”Q–¦â{aTI,ÝvÔ¶ÈÖÿêvš¢HP¸gÿ"LÜ‚ý°ÀYõ3·–ö……S_žC\“NÉ[¢€¨¢%”Ì.­àþ+I~-Lѽ嘘«,ý@"7\!“ñÅ2WÌ„ð%[ä“\Y,Q“Ö. .Ù¨´ÜsFÚâÒö`%s¾ùV‘öîtäZ6 ¬Î{gÆâQ¢iiÞ(g]Žâ^©ŸÑv]¯×dÏóÐË6ÃRyûѪ”¼^ ñlÙ‘½ Ý©®bÅÖJ—‚1dƒþÒ×Vð¢u-Qsù¥Éf|+Œ†SëàKƵîÓ©Áý …µˆŸk&,?|µZXqpTŽ8¾¹7³bºÎ}IJ~0(Ü[ 1–(׺)ÎðÑ ¨Òuº ŽEb¶ØNFU Xü܉¥ÓSe®V3)øVp¨Õƒô_Ò?B \ÊØè‰„ _ Š’Í È÷R'|=¢ût>Sþn;ß§žz¸òQ%¯­(qa3fĪëÄXYÛŽ+Û[.Oë¯Í*«ةe‘cfûü•zì„Ë °æá©®ìóTóÈ=[ݼ­àº…„°P¨w1YmÑe\G iÆ—Ã…Š€nƒ~,cªvÅêÚ¬œŽLÒáÝ<õÜê[$åž§/¡ð¹²ï¥£wÊØ¬+É¿O;šr¬óHÑ(?ŠÖZb}èª"m‹‘åa°‡X¨¹Æ߀ßéÔ°Q†ÕMXŠIOñ¶Æ:¢{™ÚÎ’õäP«ÏM¢y$Óæ–GïIJéyk?èUz\ºmªšµp»Dù@Yôí£ç¬´º;* µ`ó,x=‡¾´auÖ[]BJ‡Ž~q‹GÏ%ØúK•¯$üqtÏOS0él™Û'°µÜ<öÔ¯vÉ›Xe6 Tˆ)¢±¡ù}¥P¹mœjR7¿9°‡vçq¦Ž^ã]i;Œ$´æ|óåãç²§Åõã/µ¨|Ç9v´à•oRtÛL£6úÃ]LŒŠ;ß塯Þg•8ÌŒXMÔìÑ´©E«S×Ù¾œ*ר ñ2[UáMþûÇœýqXÝâø2í÷­dê_ 'ZV¸!®®I2ø?1•(ž[”ãwK’ßµ×cvÏÞ¾b=8°èíúAG±ÓNžèÙ ý*3MûñÞ¤tÉgáíEkHgpo`¶½´º:¶ãÒ3«Î²Û© Ži\–àú›£#ûÈh”©³èÇX2é†Uâ€ã@[v?u ¤çÝQ,gƒ“"yùkîyØ(`RhèSìz›Ë ]¡ QÚéáüàÀþ^‘=Û€E_Óö8ÒLÒ¤ÑQïI—ó‚ $|=”ñÚäú‚'8uÁáLË+[7ñ@ðFÃhN}:ý6ºÛMUÉß Fë$‹V$pÏ Ž!7Â\m:dG,«Ã¢‚¾ *¦µð¬ë7 —dOS8¹*¯kY:õ“SC&Öý ¯V\vÁªìÑ-[Xqm?#kPŽ{쿬ðÚ®K1œöŽ3'™ð3/›Â¦HmŸ¬[ò /$S«¾\®~ nzIlçÅÖ† jã~:7vsœ‰xðJ³‘ÒGמô6/Û¿¹e.§!yÜð€bV¶‘ï¬?Qqí;x|Ü¥Uš^ËŒ|é›4ñÕ†”ªS¤läÝŠˆ°Ê®æS¹ µxi‘H³Ç×OÏ®°>Ë<ÝD nÃÐI<Ê"%ز¤$ÉEøÚáŸgI¬1y;TÉ›¾¹i×àÒÏ!¨$|\¸RÛÖ>œ8>:֣ʢXbeÇ ÊOaà#̽2ðÜ£TA-ïÉ`ÄႯEw]A¾^òŸÛ^WO‰ÞrQ‘D+WO|h)ÏW}ÿ¸†Müì¾ánñ|w]h°ªAGôÏRý‚X¢GáÜ^âDtœÙ•x²U’dt¸S²GùŸg‰½W›•7“OøÇ¹Ð[âØÏìh’>íx®‚}YÄ €k %×cÈ-­ÐK5Òy~8v+sç»°.õy‘P¬÷O>©yú~œð³Umˆv®yË×õZ{ J›ßMG3a-FνÒiíDî¦îr×KØÛÈF¥7ܸ¹þrµ²ùhÃu?o…É¥à Êdý¨›ÿ3–®4 cüJgSà³8œSû‡*[­‚è»ôŠZd…Õ„³¹DC¤²¸½6Ši„ˆLŸŠœýûé‚û¡ѽ؞%hâXÑ©‡ÕÕp‚`·yó1n\ñöÌs4{þÍo3r™­äN#Ù”ð%ûG×ô~é›ièT)‹XÂŽÓUÌóÄEîÄ ä|vþë#/'0²EÊÞ_–:D Êu¥ûyôŽÃš«|•똿¤w Ä€‘yA³Jp@y§j T¹²nùxž1JE©õãy…ñšrÚìQܼØî …%Jð¶^OJŒ@µõ‡ïRºi˜/&lõÚ¬fjÐÄÖ» 9m¹é«¯ò4Ûí‡Md·&ÚÁ®Pœ.©23µˆÌ#Ðõ‡0i™ xAÛÎÐ$FØÐÌXe>N1V?½àøË3N–¸W2 ­€ßìÏ™L•8d_ì«« …š’·±¡ËÂ"•4¯p9åèåèžú:¦^~Z«øun¯ %!š 8XøÀ“—&™!µEcdL4Zñàˆ´ÇõÔ ÿrÀwLã)=ß',öóôB#¶'+=E„Ñ+ß‘dc±Ê¯AŠX2Í)Íôh›Ð‹±‹O¹·Çˆœ|~Ä)5|T”ÎIeøÂEÜ1QŽè^‰ Ò¸d^?ŽNf¿ð áJµøqN·‘š™î„êö|ÌÜΘ¬0ŲÈÑðÆ”G/Á÷j¤4^2`ˆqSþ­Io†ìweàD0—íLA…a¸G®&»R8‰¶*ùî¸dM,ÿ"Á°PX\ª®6c}èa™"¦E#.é­ !4ÓjL]£ ]Ê#Å"žÉ¤üûvdÈ?5ˆZ¹Ú0à ºBóY-û…e²‘,„Ï“s]ÕÝ>¡¤¬Ì&B)ïð‰ªB2gYË‚–iƒŸÛ$S½öĨ²¢|Ö^yoÇYqB5wÂÇy;5›"sŠ“#æô}¸Uñ×¢`HÏî6þˆBº©„ÿåU-.õã‹lÓ+’ Áq“ž!+Æ%IãHú‘®±`iÒ=®¢™n) \Ä‚ú"ýö¿V #Éõî}*ÂÖ‚:®¶=›‰¯¨7ÒÆ)îÜ2{Ù­=ØW`™r1§åfî€Foà·X÷5 ÷,©ºÆÀ?°|'|ö£¬ÍÎ Ýp7ìBØ9úJ´;ØÎû¬Yþå€ãíéÏÆ¶ÏpŒ ûb ä–S¥áÄ# Uµ5ãÃxÅ®’­:ÛæÈ›Ÿø¿Pa…N{Êyj¬pôÞù·ºŽÓ´ 3\èwm•Šsõ;Öµêõ¯¼CÝR=µ~Ë+iüœˆ†‡^ÜylóyÈØIï ÄºyÙ[ËrÛØ¦(z'qá– Ü÷Ï+›Ýs_ñ¡)6óê]ôRYËŽÄviÒ¤ô?õ%x,ë@U";mÆ2ñ¦…êèÖFJ0Ò×­@Fƒ R&žÐƒ<ÞÀÒn.L)€Ïì‡FÉ9 yQö6…6FÏo\Û'Ó6†<¸Zѹ– ?Ïìh{IeNá­½äñ¡°µÑ¥’#Í%|Ælß|î"ãÜâ8”½çJ¢‰©eb³±xIZ%î{ÕQ¶hrÒCåØœðäñÁx[¸X§ý‰a¿‘7Ò=¢4úùù‰_ÛcÑÄÉ©xêHXå4“ò Çj?eÅîA1J¥†·,-Å_¤“Í$!Ì8Øv^X䵋^noHÝÓ|;¤Dgè&ÃJŸvx¿Ñß01))šì‹°¬kõHVHIá#ƒ8¾˜pM±u #¹ — ±D`W˜=Za6áodJ†/9=èqfP&‰3à„Ýö™oPªô Ha¾A­ºU¥—$°4An/»å Èp?TMhè^ä³N^x<,±2"%ø&cäó|±{Gü×F«È,OgÌ\ÅÓƒ:; 5€&ƒc'ÎãeèW¿g¿7%%›d“Ìoƒ PY«©óóÕe=ëŠÌ÷ÑTÑžxî!óêFK÷‡‹Ø 9M-B øµ¶+³ÝÌñ(ÞK4qdÓÆ’ •©$¾"Í-Þ²Ãe¡YÒMDy]Ph ˜\@_©2Ý­ p·WYîa³N+àÈ!ûù³½ÅoDb‘Ïg aû j:x¹í„”:{¸€W „^—p…c"„µN_3ML晄Gj5Ø(„¨!þ:Ö—\Wêj¹W©ZùKq Ë `N”ðé-­ÑKßv‚”’çÈ#IÒÔê± S]ú‡rC°·™ ³•qú@ †ÓIYË#%½kèHµ³h=^6ÆNúwk‡ÜR_w7Tþ §UD endstream endobj 268 0 obj << /Length1 1144 /Length2 10975 /Length3 0 /Length 11747 /Filter /FlateDecode >> stream xÚuvs|]ÝÚmlÛÙ±µÓØhÔÆhì;Ù16¶£±m[ml£qcëæ}Ï=çÜïœïþÖsÎ1žùh޹֢¡PRe3µ7IÙÛ¹°p°²ó,mÁΪFvŸYT@æ`À;Èe„DC£fébú/úp¹XÚÛI¹¼ój`€¼‘Èà`çgçåçâxŸ³sþÓÐÞ‰ ädikï P¹€œl,íÞ)I{°-ÈÎEìà`c 2U9ÛƒL@Îü³÷Ìþ;*@ÂÞÁÃÉÒÜÂ@¯®ò…‰‰ùßÀØãŸ @älin }Ÿ¸‚lìþŠôîBdrzOÚô/[%3£¦–.•  ·pqqàgcs03½c¬Îf¬v 6†÷D?Ú™JØÛþåÀ鯞IZ:LÞ‹ò`ûϾYÛÙ»ÙyýlfigúwI¦`6u;KG0HVòÿ¿CHÿÆÌA..v ;;r€ÜM,Øþ ©æáú›äø 6²3õñr°w˜Ù8ƒ|,Í@ï’—³‘+àâùxý¿Äÿ\!qpL-M\Æ ó÷cø·÷wdöµ¼‘‹“¥;@‡•Àþ×ó¯™ÞûšÚÛÙxüÛ\ÁÈ`ÓVÐTû,ÍôŸµÿËJ\ÜþÝ% Ï —ë])ïù¸8ÿÓ£’‘åÿ͈ýß›eíÌì|ÿHü½cÿLÞääü®Býß‚eüOO ö.–& ý¿E¢ËÎÅþ®÷ãÏÿàÿW ýg )°ÍßõÓÿ£pÀ{å΀π¿j·1rú/s#[KÿeÃ~ýCçÿ?².F6–&bvæ6ÿj“¥³”¥;ÈTÉÒÅÄâÂø®ngú÷)Ù;[þug,\ÿÁ©YXšXÛœßÕ÷7²3ýíLìM-í̪.ïú3r2ýðmvrzoÏßô¾÷Ÿk3Ë÷A w ÒÒ¼½‰@UmPû}µ±ËÞOÎ>nõÛ70ù¤(ÈV¨^ëâ¹7¼I™’Jc•:ÐòÐ!±Ä£xܬùÄ;Xá±°ƒ± dˆNXëøQÎè'/Øûˆâ" R²%<eÎ(Ênµh„%&°TCìqýHïµ÷áˆÉÊò+æøðþ(ÊØø*óÃÍŽtJ²[|KA–ëjœz “ÓFn<¹Ã®èÀ2œ›ïGåò› ‘Fr©=7&Ö*ááïœè>Zt|í„ìf.ϡۿbG~ÝaœE#Hˆ#]CA# øåÏõÙV`É8m.¯¿cŠ~…w‘EÌÎðظÊ2|ݳ$+‡Šü^zs{å¾y8¶Ð±hove®4„ÓÞÜÿ¦1o‹¿6­7öÛU¢·óÓÖÎ8D.„2‰Ÿ}UB€«}ã‘·¬ªAOþwné˜ÖV|b?Ïê ±-ý:+c3ãȲH÷©žé_êÓÂ2+•Ýö{-í‚Ì£ÅÆx< ̱¯úpÖÁKç_{Ü‹dw«CB î+¦ýsªëT*¨3ò RDkÊD97A²Ž .DöÖά‚žfCF÷Å4,êôJŽŒôáÜvÄýS˜êzhƒŸZÑÜš9àkNd(4JĪ‚û¯•½~Ü6e_ibBû‘¿ 2†E ‰Ô¤á~ºqŪæ4”»ö,6NRW€Ö «‰Ùè×ÝÙ s`^CéWõ·-b4¿E¨í'µ(å¶¡½%ø ·ö+9ø;N\ ¾áWs!´ð…c¬a¶J4´hxm}ŒªobDV9aõÅ“/ÞÝÕ(H…ûb“aÛaÂ×ûÀ 1p·¸¿¸9OÕ¼ 6s+åñ%þ<GÓ÷±f^xíx7ÖVv®Lܺ–šuhÏz7O¾?ñVÊg6-MBû¬YßRöƒ^V«¹Ú=`üg¬dœøQw[(ÞÚN™ÌÅàTl–xÜLá ¥vDSH,ÄŒ¯®n‹Q¦vÊï+©cšΦ¶w°bº¿hð‡ PwõƲ:ÏÛÇ'uŠ:µƒ´jõëÇq¨ ¢—iªyW,)ŠZ“Ø&](—ÄFîCÎV± ÐcEëÁqÒ~‘ß:¹fÅ|´§ó7˜àƒ¨Üø™Yœ0£ì8v ÄŸ¡„">¯u yˆtDPüò4ì1’ÒÒzf¼¬ÿëŠì"ßì¬Ó ãðò2WD5?îO_ÃÙ~O¹s£Å¿ÔW!ìÜÛ@ùÏ HÔ{´6$bô“èw—êjŒ­À¶ŒÕÄZæCk¼D)Ǫ`…²aHÑöaülZ< Ý`™Ó‘£÷\ÖäyõJé’ðIJi¸¶Jx Çiaçî*Uc)i/é’Q̶-ö‚6q¡†n¯Æ§fXsô­ÅLbÒzÄ'óü§!*!›YÁÖ’,­–J{ÿvîRû ™R¸ŠÃÈ\>± ‡òvQÝ‚¬*5DeÍa~•9&|„,ó·ÏòÉa¿Ø×h·`¾@˜Ëå‹oÂQžÇE`è…E¾‚1*R¾#ë¬÷:±O'3°.-%É' —¤®Û`t^®ªxgtÍ3Œ ÁJ¡ê#YEæÁóô}©4›ãÇx4&w〒ŸÉ´ç5ÞZÆõ›iמœ Èr‹ªYcR3¸nIˆb=„JŸÑŽª< ¾ÅQ‹<üB2°Â·½©ÛOÚE29êÅ=E;A´N-ÂqŠ‚° ëüÂ'ÞPãˆJï´ä­Ø1Í®qÂâúTƒ™>OBF7`·5AkH÷ˆ¹ øXè­ž»½Ó ¨¬BÜ•#Øúäv|Cª”?˜ÊË=í¶ë÷PX¿`¹ˆX÷¦gÎ~P° ;aè*7v‹EëŒLD ä­-ÓÎü¼ðÓY3u“áït8_PG/œ£b 0/âkÄKjŽåjÎ]ÙƒLÏ…ô(8É¿Ç5tN@¹àVUp3Ȱ&þ`$Ð þ60,/!Bž¥@ˆPÿšw Kñô€§­ÎC@wQ7¸œ‰*¤½[ÛÐ}ÔûQÉÓY#ÃZÆR¸QyTUKÓ™#‚ ¾Tû›ËžÊs溮,ç˜ê°ÕŒ0÷K>ØEláâÜâÖtÃÜ>ä£0v~[§ ȼ‰WQ­‘ú9,¬w^Ós–ÑÐZºædY:Ï4ßO E®M=ÃÝTì^>bLK²ôxá’›†%Œ v+ÕÑ»g»ý<Ã…Iå„ —^TõÛys¼Áú75ÞJh0˜Qqo Ëã{üLt«®¥9d {o n¥0© ÿO‰Ý¢g?ò‘ÝOALV¨‹°-œÌ6ÃÛ.¡¿›™† ´„¦éƯ¿sV%Þ£tþrœµÑªDÌqåÜ4€NG\ðò0(ÍHõæ'þÔ»·¨!¸0­Ü×aÄ}ÎMNÛÁñqH7Ыó«žÌƒÚÏøÓ a%ø¡K•¿¼ÙGŸ·I\NùNQˆf¨=Æä×ùÖ”]8,Y·1§ßÏôÙ_²ª¦uPÀsæÍ!¹åä>°Ó|{¢”wX‚¬,çeéŠ×§úú$¹¸øü:‰A‚½ICŠH¤„¤‡ç»Vóe5N,w 8§·X¶ÝüÄí…åkÃx˜t·ÐA˜‚h,´Px†-ZçЄlÒ)ï0ü úâ/¢C»ßaÖK¯;„‹‹O¥Ø ™-òœwÒŠ(•îTBÅŸy–ˆC¤ {’9»OwS'üÚË [èærûk ðbsDo‰«B:Sî—‹v5yõÊ8”gÁ_•cBæ¸CSÚ #ÏýzñÜŸ[+^©ÚgjVÌ6CÌE>y2¬ÙsÂ}=ò¡Ðá4–·^÷‘6¥ìV×umSΉÆpQtò‹N©é67L¯¬te²ô¡)¢‚>id±v;®4¾¢ß°žð^Ûr6¿ŽqýNßæ…J4ädWT ë§³¿`žË;l[\ÌV÷ã¡÷ß ©MaHèDmttj1âé£þª2 rîí€M©šŒë*ÎêjÌÐxËæ! x1Ësi t³3°kXºíù@¬VIìÃ\ìŸ$bM Z´Ñ\qñ¤V¯'ó®[”¶ŒStÛþ ÿÌŠjë ˆû†ÂE¿âtð%Ù8óuæ‚™=^ƒöÙ] »Ö}”ÓÝ×p6G«`Óÿw‰zí+2xg`Qñóª´m'»Ñ^cq˜ {ÂÊ8ô3‹’ÂuRaÃ\)¡ŽËÁ…‰ æ`¯ê€Ñ¥ƒH8F–U ~¹µí¢½M)‡PYÓO~ØO-¸}¶qœV›ìb2t[¦x ‰A¶ÏÚšÒÝ‹lh!&XK&›X¨‹ßS€0Ò!ZÌl—„{å¹è&îÀm¡°E¸ÆXÒô<¶Ræ =hXÒ±I³jçNåvJûÌí×Lû“8¿b™¬´”bÂ4].ÿ´–hp÷æh¤’ÈIoFDa Œe•˜(!=›<ý&,F ý«×N)ßßw&—9›½EX¶sc:¸¯¥qb"úÁЇ¥#¬¨Õ• Œx[o#æð#ÛÛ)§8§oK‰Sç— ì{¸•Èí¾˜eÄ‹_hÖ¯‰¿ÃÝóte=RŒ¥ñaäÒ«KØ“çt|g®¼&pgrKkñ…ÃóŽ|cÄísBÔ34+`Ë¡Çæ‚ä?°÷*âaæœxg \Ô²%Ó•QöjµÁ³ ¢WÝm¡-^(Õ|pèà:ënù¬Ù Xá\•ê0o¦¥oóD·;ûóü0%¾Åœ£D"||rŽ2œ!PÓ#àJx‡Lm'éyƦJY_‘׆³Û½"¦æ2xÑvTy/³^ýÜ|ª9­ø6l:VS{wÉ8ýñfÊ™B®ŸËZø§þ×kõü0Ÿ%Ë¥dÏŒ˜kÛ#}R½`eiiV”•ì¹”KÛ©­e÷Jƒw±‹„l:ÆÔ?˜µgÓNë;Œ’ûšäÊÅJŸ‘Åu”–){!Í Ô¤Zñ“£>Ds°V£˜ò’,ýÙdÿÍ>\Ÿè§PX†~m$d.¡•uûmƒMpš¡˜ëø°Ï[”ªgs¶æ`›XQÿ.=‰ù‚>»]䣺.tqü†©{ÿ²]›ÙM—Íœ½ ¾9¿&û(.Ç¢\‹Ñ‘œ²;È×XütºÃ|Ys:Â6‡çÓçÆzÒ?Ú}6::cE¿Î¢j™|ñ.¸ }YË Nø„ÕJ e–Vp+ÎÜ»ÖÒ¨˜üQ«­ÿ|•ü:‹µ©åHŠÖîe)¥…t»-QÄ\$FWë„<ýõ…‰…da -›øÕ¤Wø¢ÉC}‰çöOÀ§²;6”ú*Ý"ÒèIà#¦á.X‘47<œÓÀt%ÝP[aæ‰d‹47ßëZ!úLé_2œO<Ó]Ì}qn©Û«kÙ%𲡆e>ò a†ª`bÁÝi’Tó¹Ó'GÊKSÅ¥ìd•iS9ôëÉH⥌²ù±Ý½4™mÂÈ^²C3Ë]Ñ…·ÄE‘ÏV¢gfÃIïÑ&ŸF(*,b i§Sú¿ü`ž‘Ó<#}3nÆ;ÎTå¯Ô·Ë¦Ó ¦&-"0UÜ¥E¯­n¯^ÏÚ8Â%ßRbO9_?qeMãC7㦻ˆ¡ˆ iôi9©T¤(8žèî«9ßú•îk )ULÆþžé¥9r½=kÞPfAЄ\×Ì@1dáÛý«Ts‡™@s4}ƒØÄäò6S–ÿYÚ´-¯iÁæƒïÛŠvf'‚7á\=J–‚R+ýaéS†ÏWgtk>LözÞ¨,Þt„/ºíÙ‰|ô#L((önÁL¾¤Ä ÃÜúä{¼û3Gñ/rž y£¡½¥ÕÁ6Œ¬éÛ»y=p¯ÿ~ßIÜ|®FVÜ£R0Ò&øþOå|8tÁô¡Üµ;L>û¤(اAÛs}ùW*ëìS´¬#²P/+­a±Mu†ÖÔliv¢²­J¬¿ÊÏ /÷}ký§ +e®ï².g儨†I½ßt~÷4„ä­ü ´Ej݆§cŠ´Ã§¯3¢cG=v 7o7(Í‘õô§äN²î] †©dÝôç%ùÚçJÇäÓ9©àŒ;Ÿ}©ÌmôôVÌûÈœ9!ºNÃæÔqƒèJÒKFûþ<• ãft]‹J»År™a<e¥¡üôA™²{Foñù™x° …K åx¯ÛQ’ æ hsªù¥ˆ{­ú7¾6RT™P34oU%“´^/‡/=éZA±ÁüÄÑX·«ãIåºgøõ¦6Ô›ŽùÙû;GM¯ïÀµCȤ›;Xݨj+uݧ¨å^}þ¤Âó®4T  #{º£Ë~×uGQ, ¤2#së gÀÖ¾`ªV›ˆú<ã6‹Í·ÿ‘ùÞa„ëºèšU}@Ó-á¿ûk)]! rÂ(êéa{÷¤¨À·ÙŸfŸ¶2ÉX í® _Ö8¥ œµ+IŒÍ3õµWtuR]±X®eÄëU£oež’~ª$QnË-–袣ÅŠ¿p!ô›š“·©Z £€³¡dR®]ãC’£råYqotÔ>iÝõ"Öm* G£Oÿ\i·é:‹šdsï–g&0ê|Û©ôC´ÐÈ–æ£NÞÀ'&µU[uÈÄß§»•W鱜€…t¸²b ¤»³ü—©2œT$BJD×$Ì–¡¼¯ö)·妨½e±?ÄÑ›øÉ5®Šô„ƒVq_'0À4á$F7J§û܇Z–¢AymѦ@ ’°·Ã'G&þØþé’ÌžÃMœÔ;QfΡ“ó6Ç(•‚õ¾œ}]Èy¯ËŒjÅ>U¸·mŠI´ÍæmàÂ×üߪTXþku·”}+?ˆouP[‘ŒúúŸ<ÊëªY¿œÑ&e Âq^i‘–j«8>Ý+êHª2m,…o%ŠbO‰ª´¥…øêZÝO:K¶rß'î£Jn†#•.™MNݪ>J{À…Û[^Ûïóÿ†+ÍyÓdÚ¤÷«èû)Õ:¢ÃÚðÔBõQÆ+µÉöNRü»*še·‚6×cÒ™Ðï)Ôm(ß Ó/Å@ô¿ 5Ó|ž˜×èJC •:xZïÒ©=þ õžÛ¬–e, má=ïšHçÇÕÚxFVÛÆs|ñ¡hq[tSC"¦–±úÉý»²2m+X®—ü¾]¬Äá—H7áŽ`„»ëQi×CŸ‡©É¶Ž8ÂÚ¬£î±®¶•ܲf“±r­M‡1ͬ‚ÄÉÇ릓6åéj£Ø €3^kth¼;ýµµØ†Ï¼?t¡Ì.ãlƒØÀ¨ÖK„ÆÕ­Í'ÞÅ~*G]DÔS÷¬šþDâLÉõK<ˆçæüÎ)¥ãçgÒG³µy2¾ß×ÀK mÈÆ·¦ƒmÖœ}RYŸž¾°ÝÛ)òh¸ÂHy»K'òaÇJÚ„.,Éa Í Xz¯-Ì05p±²Õ–/óTw}¬ñ¯tΦ¢ Gó%V5P>â AäÈPßö\)(­.³Íüa€ýQ ½Å ®ÎA'JÊ!ƒ+~{ÈÝÌ6}1Éò:…%´ZÊòÀc½€TÑÛcªã’‘7JqrÔ/ZŒRŒéz™¦8ÝÃá[û.ŸÝ!õ ˆ—à%ÄE¢'Ëør»)Yõc@Æt7™º%<âÆK‰ý±6¦t¶f —²Z b_ëÙ„«³'ü¨Æ÷Ž‘JžD©sb¯D[º¸,Ç%ͪ€êPFš5 §-úm’Aãà—G"]+ªªž Ç}Œxøí5]÷Å{ƒ­æ"ñ\ÃR¤L3Aof\–å”Ô“sí!ª?jªÌ%F§×üÞkK6áp&ò*An®„É ggGÛ÷Ú¶ßîZ[eª{ÛQq¨Q«cc¼Ò{èžÔz›É7+L>G­èœ½Ô…»y#b²¡[qµçÏÎ×¢}([YõP²3û|+¥ËG›â9ˆc„O4=¯>wÊh¬ó¡µ=èþ»üíÐýµY¶?Œ(îÅÜ£7X¹àò 1Ž—ÙèV,¥†¿N6Fµxt=%*=ÈÐÔÇ–g˜ö‡ðde{”Ú uÊ•ê—q"ºolúÞßqilAé×N¼¶+Æ;†ñO½?Eå"ç5ð¥bd¶( ôì6‹²‘¶{ÇŽÊÐÆ–ŸàJCDuÔ3;ç¹ì:Ú+mÖû¹*™*"Cp*ŸñàðRÿðÌJl†ª—vÅ:Œæ÷®½õŠ4X’",sL¦]=†§TðÁónmÌSn4…«J´þžþªR¿7aªì¢Àìxkš´Í˜è¡¸‹i ¼o¶)-ø³N”.ñû”ÓÞ×½ûÍòBoÌ^Hw‹ßõ)ƒ)î`yš¥GzºÞ[W8 ú†×äCÝ·Ä8Lv3wÁ%âaô‰BÀ:¨9¹{¬Ò]jMÕ¶'aÄ'ÍsÄY$é1¸d1õ1–WœE¹Ó˜¸”ÊlÇhÞÄE‡½¤T—æoäjHÄì“9(zR*’€$¯]ááO‹ÇÚ’ÒNÁ-n<Þ=N~û2KicìwñEaQÝÅAÙ!¦;ÍÌuÅó!¹–ßlüMÓCK¬ƒ‡½ëØJ‰š½¿Y¸á± ëRlú™’>×â¡7 O½[ÖYé6/ÂvFœä{çåk:·^’QúÓy°ZkêfQµz²¡FxóþXf–B’j ײ‘¦RÂ×Äæ§É"ÕóŒFØoÂk€NÌÒÞÏ=<×Ú~œkm CíRóæŸ<)[Ü'§1ýv2’ŶڴÓÿäX(¶)A‘—-å† ü€I7Lø´â§žH™‘ÅråĹ¢Y zP ‰T«‘¼eG$Ù£‡öÉ‘ú9èŒ*½’ÐèGïÀõty$âÔD° ä5fÇù @õp¶Ú/&{nk O›;q¬ì¾‰¹@J³C޼гÞ;ÞØÖÍ2Ó•s†îB­ÝßÍŽGy:%f †Êï¤nÚeÇÜýëC7\ËJù¾ú'Åz'óÀ¯ô„sÜzÃ~8€.gÏ…¹w?:ùµeŸ_URá†/Ùƒ†.H~:ø‹F7êp² Fÿ‘ñpG7Õ餿­€ƒ²%2†|ì"B=¶ïÞ1…ŠLµÒ' Çý÷\½±›žèl:ÑÐõJZò5–’Zxc £ Lƒë;©\SäêgñF¿r~¸ÍmSrs-1uUV6ÚûBÔI䡈þ,tÿ”Úx èBÁ¦4œãùA“‰khæar+÷ÇrJðúB…@ŠªX£¹Ù«¾w¯–ñx03z€7â® iðk­³Í»¦Åp, !jRïOo…RNóóý ³+¤ðãýŸnÚþn|îÛ-Â6ÉHSÁƒ¾¿ž›/|‰ˆûZ°œ'”&ƒ|³•)nu Œ6zËéE#s>ÈÌ:ÆG={=ï2_“5tmôýÆ$aP(*Îo{ÌG&Ü•á7M†j°RôŸÝùB£oœß·v 1¹!-?z~äÉð[™» w7<™¥¦Äè£%1g¡Jžjû/.@…ÃÕ¤ÏÊȵ?.4¸Å](ˆV}t[Ó… Ë50¨ eCÏ~Û«¢ðÍÇg l< íæÉš¼Z!Ó¬u5µå½™pãZv{oŸÆ§5%±IûQ÷KH¢ÒV6©Rcm•¼µV—YùòSäècydBsz›¨2 %Ú,M+ºõø9à3«Xäj³ÙÄÜÊ|×F'*È6Þ¹dMXá ?äC#¦Ú‡³wÑì<ÚÉÇ#Þ¼ ¤é\|p a|‹ìO‡õSÍtXŧñ\Sɬ¬Ç\fͰë¯qéN!6eÂ…_¨¡Ô»ý/†z/§ˆ·}]5žD¡Ë0E¨Ä ÝÕÏè"°§õ.ó¶QV“áZAXûgd͵•gvâšj­Jmž¯X kqi§Þ?ÍËDxvP:Ðúéê/#|' ºH2äÙ4vÀxÝŽþùs1ÀÇ(a§†Ù“%E±hòš.r2qºôѰc®Èä4ZO‘lmˆ¶äab~!†a~OÕ¤ÂWrJÁ»€Ë Ù<-W½ÄÂÆ3 ß}m×O‹ì£ók.ca°zP†¢Q¿Xë”ÛÕ”\Š´ª"@àì£"Ëú æÕ†ÍGŠËŠY]E*ï„1­™?G2Ù©± A¦‰±ñ/ƒp§ìFeš6ûSíù*BKÍ"U w([y€îÔåyÜZ1Q„eˆž–Øêrõ$v«Ii”²‚$ågsø˜Jš,ˆf>b˜:_)ˆ§ÁÍ‘èœNµqò&;¥šEªaf/\qÍÀ± |¼ï^ |áìM·Ëü&¾å?ÅÆéMÕp*ãäh“›ÇBç+‚ŽúÐNSPø»í’›5˜¢±ˆZ|/6¶Mb%®u aöõë-MòöÆõ´&—ž¢<Ú1z…{5f?Êè$Y䨋8Å8= ï‰Àt×’©þªŠ1³m`ùÉžø^i(gmƒG `ÚužÙ}——//´åëz)ô?iñ|røý1Ò1~3ûЮíVe\lyÑÜ[Þ4œŒ[éäýuèòÂšÖ Gd\Ö^&*Ž©ì2gÈaάµû)'“ÝÙ “H£ØKÙ%RÂòÅ 8Ž\G¾zNG½Ê”®T¦âAÃ×ÏX-¯·v¹Ãl;Û÷Yé­“ Ž Îï0¶lS »›†<…ƒØ¢¦Û/<.¾óàÞqÊyóVKzq+ œñ•Å9È}U aðÓp¯µ5Dÿ0ò™•!ÿwWmžxzr;^w„V"޽Y‹BHÓ¬ÚèÇç?ùH™,ßw_Ïš&ˆ‚ž÷ž3 ãÖ„d“)2v½5±î, -ÙÃ’œñ@ 6¥ܪ6zÕ8-µ×„C£•sÏ$†"FJ”6*¼x·¹V:’tæh“R j/ŽîV¢××?ÍêõQžá;výh>ìíÓi3¾Mg±(¶‰8=)F kï½X-Œh‡õï; 6ûnÝ_Z /@ô7òµKßbœš~Œš œ0äã$\ÌËôNlø}×Iú8R_ ÅËÓäÂŽqI÷è*õþûª:RС µéÉ›pZT­’{èUé›Wü@|2áx–“[ÃÈÅ£ZU\CFû1 ßíxí¸oØÔF8¤O[b1Ã7ˆãÀåÕK­Hݾ÷ûiõͶ1³ÑsŽì›@~g킱›Ëb ÿ80"py»Ñ—Y!}•Ú 0&;¶nˆ#½K擄<öÞž¨fw¬ŽPÉ›éÏ6®fZ…Â^bוîSOÓ~wºëÈ«jk÷“ßqßèX`³ëûv…Õ‡€QQ° ‡÷EJræ%ìzìPy¤y)/æuÆyÍt¤ðQ`r úËPÁ¡ø •Z~(|nWû«KA?LC®4´XP…ÎdÓðî)þÍZáiCMH6’ŒžÖ’K·ížxíA¿“x´¡ju îøØì©}(¦y3È~#¥3òÉsY-”Uõ´¢'W§J­}@+m„çxœ> •ä%x †RDžÊÖ;ÊÉV}°`@X`ʘ¾º)•ûmƒa'­9œ8ÿ2ò—š>>cöšg<0L7iÂ[²6úIA̤oÜÄUaÁÞORx°6}¥ò⪱µ'årÕ[Û 2ë þ&ª ‡ žùŒíµ™ if™à¯t £ë£®¡ƒÏ½¿ScÄó3HÓëŽ!—¤ï{@5Ê:“XþKbÁyA¥lèk†å+\Þ~çñ~e™œÎávä£4*äש½¹Î Qг5í©41|Ê/qo*éãkªãBÄP¡¿š­‚Œµ0—ÓKÒ®%­cOøYQ ²G²#8å¶·Qâ˜= ÈVeËs†ÐŸÚ¢·&K„¾ä®©»óô}€ë6GÄyI0§¿0' € Œu‰õP‡M&ôGí¸Æ2\:zŒCn´>BLàD&U¢áršLI¡«ÙËïV¾á¾d…AP<ÒŒfè»Sí¯)((ÛgîÖZ_vûìpQÐ)öfѼµí]¥¤*¹5•¾ÍÖ5]Ý0¡@w%ºÇa"XðÈZ˪êP׬+Fª×…ʧŒ¶Š/ÿŽbIüVYÉÓ­ì~£€ï}8Ñ{ ó®Þ ÿRiÂP®êÜÑHútëüc‚'4”´kE œ÷3ÚÇCˆ‘2¼¹ãe]ð8¤V‡)|"ð¦Û¸Ä‰UšXCÛ[zÛœ_’Ø7`7î‚Ï!l¤¯wå±UÎëSU›ú6Çû3¤¨nçˆ3çÆ(a˜ãZÿ©[ï×™â·Ám3l~“^I8âÈJÌ„p‡ªÙ‘æïÉû¸Ÿo²¼òEެM”2·ük¶ ô擘væD®à½ ÈÒ,kôF2tAäOÍmÂÇÖG½_Ý­ dXIú ×¹:±›ð÷7É$ó²IñÃøšð¯Å"šÆŽÇaßt¨(^TÎ}ix"ÃZàM3öP¬–¦h$¬x‰Z㳊Ön¿9{N6sa›Ð¯ö ‚J¬_Hfë¢D¯.àØ—J£¼M›ˆpöÈ¿ðöº©CòÓ×ÿ™%=½ê¨iîÉS—ÖJÓ6ÊÏTù›'‘©½ûeõÞúÃêùÝcÌã ‘ï¯Zñ©Û}]€¨™ÛÛ´»:e´?Ê*XdÀØÎOzÆ#' {`®£ ’¦Ú±qÅ™„è“ýÁC®†jªšÛ]l¿©Èßùüöù35‹3ÆP"'}æÜ˜ÛlÒ²æk{Ö©ÌH©ŸÞ×3G OK,úÛžÒêÎkrµQžTWc”[Ý™\z¼LblÀ;[Ë¥MÙ·]1×Rp諃#]Šb›S_ Lá3O¿sörš=q‡Á» MEççâ.^⤮’±$¯ªÖ+‚Õz‚mÒ¹x&ó¶_2;½¿ ucÍZaèý†Ð±´Š›,.¤¾¾Lf¸KüìD‘Îï€â+²ÈËÂÅYfÌYØ<ˆÝŸýP°žÐäÂ&aB~9ðšìžŒÓˆËä”K¨ÜðLœ•ä^Å4 W’{Ùqï/ƒD§¨&°¤íè?ŠžÜZZ÷O4p¨ïÄ䳂٦ÏÔÆÈ¯}ÈŒKFaP*Kì8û?DMø endstream endobj 270 0 obj << /Length1 1177 /Length2 7929 /Length3 0 /Length 8706 /Filter /FlateDecode >> stream xÚmsu\”Ûö>Ò%%!0twww—0” 0À3834H#Štww7ˆ„„‚”t(!)ðåœsï=¿{çóþñµž½žµŸÍL¯gÈ-o³«À Hn~> €ÄÕÆa‚jq€ÜÕ‘ À Âaf6‚ ]Àÿ˜ò*ÂÁ $U!rŒÝÚ 8@€ÀÏ'Á'&!Ä÷°æüw" .ЃC\a>=0 w@ %˜­»+Š4twss€í À˜;ÜŒØ?tøÏ'anÞpˆƒ#Àfl`ÂÎÉÉõw„_\\`ãýo F@ –‡…ØæöÇiª`(þиݹzö e;òÙ6G$ÒM‚—×Í~ˆñ ìy `$/ûC³ÊP;E˜ëœ?槃m„yóþÓ ¡0O¨ï?Bö¨ÝŸòìÜÝx¡—î`u¥<„pþŽ9€‘a>>q>1ø%ìeëÈûÇÑFÞnà?Aþ? ¨¿¯Ì `rA€ý!öà‡Ž/ä áî`ßÿøï??Àb‹Ø€®äoö‡0Øþ¯½6 ‡xÌùxøøø||ÿYY>\® êâýwºÈ àÕÑ0S×—çü'ýÿÉTP€=Ðr󋊸Ąüü:Å…ÿ—UùWW|«Cíañ¿š˜Ú¿x€áˆWØþ41;à¿™t`Hˆ-Àö·a,ø„ù¼òðãÿG#ýþvúß3TÜ]\þœÛ_âê-Àú]žÈ3€ØþU Wˆ‹÷?Ôýo¢ ø/ëÿ‹îá¿Øå¡.`7¿À_ABâ¶Óƒ mÿrÉ_qc¨ÝŸO¬C@þxÌ%Âüÿƒ9Bl¡`âÁŠB`¨Ýÿª µ…ÙA CäƒAp»ÿþ€mÝáð‡9ýySµÿÞÛCZƒ½À¶8 _`¶’¡Nõ¡—µòԞܛ‚"Æç÷îtB8±.¨<úu(œË¨…ò~‰½ÍRÒs”©6GÓFC O VŽõtWèâÁ$& #~¤IuÀÓ ¥#÷‹mê˜o€*1†â]ή¢÷ÚúŠs ³Œâ8±a8Œ,€æÒl{ç¥.5mEA¶îÎvqòëà#]5—Wú3#ÝJ|NÁ¯ßájô4ºbÕ0Ãm>¸ ©ê"¶žý2¨€/0®Šƒ¬ÿiC ,•èï¸vìÒ”ëFíå*ŠÊeÝ>åýˆ{·:Â1ƒ‡A‘œH³ŒG@A1$¬å*¹`‹E>›?Øõ‰mOlž[j½oSãÉõͧ,;—‘Â] SuuýëeëG±¹®y˜ý©ƒeLèÒ:s»™3˜"5ZÃ:ƒržÂÍt.]ˆNƒí ž¾‹8¦Á7çl/©¾ç²öhƒÓ­·^žÁ\‹× ²I‰ÔRo;;G2àÑPáNЧ£(ïu!É+UüpÚí+.º”ë×rÁîC²‘™ìâòÔjÙc¾©ëKcÄ/¢¨qÕ¤%G¦'1yÝÎG€¢M-¹9˜€ñ¦¶—ú¡4éàdÞËf†KF‹”î¦%qµ9Žûaï|ÎIÖ2ðXZƒØxª?Ç’IëÒ’m?#®kCo\ÊÇN€üj†[¸’¶ ‰ú|ѧ¨E~ÞŠµhOÕ¾ÁD<Ãx#-[Ïë>ßW–`:Êâ9ÓÈÝn ¤9N[~ZEñö)j¾·ÝÇ_Ÿ]¸Ï\£–G¯\;aŽN¿åkEe8­*[üvT60øc–Ú»mäY»À‹ÒÈ|wŽDÂÖÁß ©ü¶?/¢”©EïØjoh:NøhÇ›ë©äÉÕ&§ ¤§è5“@¤0o…Ʊ\B ¥S:›átíìרq»t}3êO,<}Pf%ÔtÙsšù™ƒ€U›sº7úVµüÊ` ¿‰x,`—„±”;¦êÄøÕ‰D­ ¹ñ…!__GkǧœGçèÏé4—iR»t‘J}8]ëÕ;Ë !Fê“HÌw«@ìqIª:ñÖŵá5–ã«=Ÿ ÝÆ-H8«1—»ÎÐ5íñ+QkŠn`T.ãÁwMå¤6ãíd'eòdÿá!Õ—.E(­©1ç!æãßuâï9ÇsÖõy2¢_Pó¿rßÜÔ&Üç/ÉõÉGý°MU¯ÐOü!i‚éÓŽVÌ꯻êÅæú Ú'ï°¾i’µ¿‹YŒz}BS^¶¼f·Msâû²Ô‹êúús?æ¯6¦%“~ó8e¡úäVezûððF軟óä æ‹¸ ÙƒÉ<ÏjSƒâPQQDœf¡ØÙ{ÅPCpI¢"—‚éh 5|€lûž$+­Êºt:½GÚ Ê•§îQ^o¦Ù륲è¯2y¹9?öGÒ³&úSשd­b’ pÆ…pê–Π䵺ºRËà1*º\’~zŠG€½a:Àæf3 ^×RYÑ3º=¼|TÜÀãb:¼÷Î_„¶ßr¯dF?c˜’10ÜM|Ò,ñA$nÛ:ŠÓêBÝû‚ý8Ã÷åhM}ðþ9 w”÷´”u2òÈ“³¾z ÜP³„ýÇû*=‡U¥©YšPÛV|¥c¬"G#S1‘Hí Œ ­ÞWv³XÂÍ*7ZÆIŠ 9^,~Éùrdc3ŠÎ¸Y«hAÝ£P¼«u®èÁ9þíØ„Õ…kÓñê*‚íªl¸_@ÈWCÌàŒ»Â2þ¸²³´@€ä‘¿¨ný%0Ãðä÷ÂßE‘Á!+\†°PsÁ4é·èÔ™Ü{Odoy9GÂÒÊwµ§ç¬·o¬HX«ÄÌæšàsiglMÌ zD£k£-Ä‘2[+øJ½3“Ã^C3[לÀãÇaªrÝ6LÄ—P^¯ B`IçÙS¡¢u•UegIºÄ³-¢_ùÒûÊñn{qNæ«ãñ‡#`™éâ¤ÙÙÒY,ÀÏ#(wifg.7xòù +ŠûO(ægÙzcÕ¡Ê ÛIìƒé:ÛvjŸÆi3#õ-Íêðo†Ö¦6Óu™9D²cê%K;¹3bì§¿Û7®…˜ëHö²dDí eì`8CÆW'.ÍC'44Ùö§…˜ šsKÙÚæ šÀr¼q­ #ŽÐ XòóPø+ô®þ²p¹ÜĽNwçRÓõÑÞlýå[j ÇR Ô­­m©U‚Õ5Mœ¯D$4]íQßìS;¼íë À°nm蛨 Þ¤Þ¯eeõ`·!ßÁͶc®pgŠbd]q‹Õ[¡]Èç}”áºÖ•Ðv±ªn÷½é-¡¶åzcE¨Eêò´ ‹Ö©ÃÏäŒÅ0'¥§mÙñ»ó‘ÙcŽ j™0ú–ÖP^?vÆÞ‹>·þÜä°ÓT×î³ 1QfŒ5ÐSœ(Lõu…>ÔpxRÇãk™é~×™æ©Æ.rÓMû1uçÁ’?Þtý뮣(ð$^¶r¤Rå缈lj;f.¼[T¬$Õx¢„…8¿ª-ƒGÈH^ÒóXef*•f#²éÜÚà‘yQ Fƒ;î#øòUïiËÛ"ï{¹æ#·1[¢Ë±JþÔt‡Œ^»~§“‹ÝÍÕ t Îß¿k¡Ñ óoO\Ql‹1?Df²I³×mŽe—¶'nÌü†¿çžÙÆg¸šS$~.‡“w»ðÄldº[hlt”9îs=…'¦TAE|kÂ×,–ëyº·É#†l±\dâcßã‰Íbg'{=ÿ²^ÆUÏQòÕOH¯¿L«6Qv®K\APöbe5“§qT[åÌ[ügd±§±S“ÊþÑ#py&è#ˆ¨¾‰Ú¸.³T«úÉ´ê‡Òl¹÷“sôÖ6R/Û^a#Fd r _"ä“Å÷A½OißyÄzˆ“½Cà$è‘'‘¶[kïT­-&åL®sµE_uÖµB½CŸb·2~°ò¶7þá£dñj,öTÒ“Reê_kSä-'´dêJxøKÒú†f ¯.£‹]þ4€®0æ'Qah³ˆMìÒαö[•­©‰µ ɼ#wXšd\8Óâ|ó#äq¢SDo¾¿dùÆ0ˆ‡Öu‰Vz²OH!lãƒÛ«v€“ü‘ÈI5p´ì"¡#‘NZhÊш·¢4ùº–qÓ› ÇSin‰ïW^÷dÔçk2íE#€³8¼Ño/ºy—´6¤OÕ¤|)â&×Ú¥Ôžè÷Í¡ž²„°v‹@$ŠÈ#Ì\íÒYý•É9²s¸¦¯XŠ[ÒįazúbJaçNáÝ)Žªr§|,gŒL†¯Øß§æ¨íÔ–œ°'E›‘wD†B?\‚-¸âÍ`íÔï²máe±Ø¦”‰ñÆq?cñŒŸ{Wã}>;O¼Ñ!ÇSX®bfˆCÿ:GD¢ý%Kó{ƒDTËÖo{8¡´‘™o_†3UÌB¾—é00Õ+³Ä£X_/Œ¯ÆdRA<¹ãúOßÿÚEç\-¤†P`¯ûŽr̺ÒSˆ¯2b³cÖ¿˜ ç æðÁ² vkÒ'}t}b$¼Z=R.o>Þ"ЛY£v³.‡v ¦¬ëACî4-üVMòZÇÈÀ òÓÞêD>”•œVà„4Ž‚ªv¹º¾fþÒ (b ú•j­ZO_]Ú÷Qeð©txÑ+$É+/pü²È,®=»î„Ü}†ºðü³ýkmþ»0™ìØÛ §a™þ/qé?"éÉ®DŠv nòéQ9ü?æå¨œ[ÃMx)BN{s÷6zwkå'lc‡ùkŠ{íó‚ã ó²jÝì™EÅðTÒ”ðö‹ãc­v5‚o¾‰zWw^iìh-Ì=3e/šûªÃäÒ<¶Wú¢?`Ž‘KFcÒL(Z§RîþÎíÓµ¾Böw /2¸ ŸÉO¤T©¸õÈ^\ŒJèDa·Þ·§H ]™?ÇC°+¸??¼â+ò+qmÃÅð¡Åʦeþ*Š‚R^B"m¢Ù3ƒ–ïfx»påƒ7pRë¥pú,ÈãP¾¿¿gÝ¢‘#í9çÿœrДíÑàI?ùGÕHju‰£›å/3!J¸ào;ñÝ€ñ”ƒ2ŒOò¬m³P÷™A.½T‚n^%FßÞù U·–5euÑ®0¡¹ñ¤¬Æ^tI3‘€,Ûš-ã#í<ùS#¬yqeqO$\ I# ¦öo›„YuÝÕ¨ÁľrÏù¢«©xˆˆ7ÍŸO[;——ÂŒæØ퉇ž%±âJ$÷6xœÑ-¸4WsgRð刎¿v†øm£#Ë{`q77¼d}øPKƒ&”n±¢¶§›ÓàC‡¡Šª‹'c±¼<ïÿAð‰1œãSÊš­N™TªD6Õ¶n™eãoûÐ])ª!8 :¶X'#þz­XDôÝ7F™.¹×—u2²W›NÉ]¿rÝ`TÃ_\> K$ºø%Áî9’R­Y.>üí ñ”‹Ÿ0—ÍêîBO)HG&=Ýd6!ò; 1ÅB²ŠðÕ”N„Ѿô; ž­ÙaÑœæÁFpИûpŽy¹GR ëkÀRÙÀ¡gúv/(~îê8gòc:±½å~Nu‚Õ}ofK÷¡*]e»¥›:àtŽ‚þ•qôQ€‘eTÁa@PH;£YòËÚS*‡cÇ×2¨Ì¾GBúÛå"ÄèhD­sᣘægÆd}½RákÛ€gô„^Þh*³¤á0ËWÃs’ˆ|øQ\Œ¢$<¡Û!™wùq»’_5yEQâLÞÃé,§6³å¶r˵¡‹-ÅqÂÿÐŽ­MUjs•ûˆYe  ÎugQù†ó¶¼œ!'—õ:…ô`[oÍÚõÙÒ”€^IŸrË+…£åÜŸ*‘4´m•Ï‹ÛC! =œÜeöp•ùë$ ’oo‰¿¼oëØ•V¤_ïè&CÕ9h3Ž‘r3O‚eC;™ò†âmN’«“²XÕ –Fì^Ó˜V͸ØÏjcJ5¦~ûþ̘V—jnõ‰¢LôdC†ý'Ñ)º<>Ëêl3˜¸XéwâÇÈÔ‰×y’¥—/‹ýµï.ô'çY©›0šàËñ>³ˆÀÞ:Åh F½Ù½%ËYæ»/ßÊm8:õú‘(¸ØÌ88μ\$‡³ï,ª§ÉFóÔÁ–ñÌl’íCçqÖlx²-hÈåû¥N8»æ 3ÊL~ʹ:m¼¿k}w·;{Lgu<Éíuæ„´<84º¼¡~/ÓÍ"¸§ZWÿ²‚Ã:«b²Ž7òÂ,­ÏóT”í…AŸÆkSÏ“ö\»DtºpãëПä¨4ì¹vžlïö\±DÂ})Öƒ}ã_>1\“"M­X5JÐ@æÏ;×^T´Ón°°mè–bNxÅY±[®Qm%=‘·çÓˆìðO yð‚îþM1¶uߪäºû1ÚG¬Häì““´ìÉû™À%Y^9\vžqšlâYEùj¹èì«–$•nvúZC¡þg2e$È;J%D ®û¨ÙDÖžÒhìOLî±Jq®7:Ñ ¼_2hüRÜT¸(h+«Í@[÷»Œ*©ÙìÕ,õ…b?\PöµVjQù‰mj«ý5¡Ê2D1(þ€YˆôY<ƒnT¥½2;úÑцM{Cã›~›ÚRýŠîfÁß2NïúYí¬å>ºê%R¾»Xgš±!¨ßÌ3àx¢-nÊ ù}ïe>Yn£Ñ‹Ÿá&Pòˆ¢ë(“¿>rÉJÌ ‹I‰ŒÛçÐM÷W*^ë J×J'Ü)iYÂd[ÞCm[ã¶žÑÓRÛe·S3¼ xÌqd½ˆ›_0¦R‹•®'YaòŠ‹8¾W àþQèàÚ>J‰?%ä4ãØ¶åÏwúÅ[ªh8XeN¤ëô‘'z˜„*ŠÕX w¡½†J>ÉþÐDÁ³6¯MC2wÁë/ ͽ¸eEÏšÖÅh½¥¹œÒ¯°ÉŒvر,}5El”r 4A)ÀÍýq‰0ªÝÌÇ4ÒŸÅÇ£wŸçx„51FÎèïú.žöç¦[*íîÇ“íBñY¹V­sພXWEæCüX ÛB¸L(VЦNžÆó|bB Ä›”b¶)‰ܓմŮԻÞ`C§+#SÓ«å"i»°ôA£­b‰Úlâ–xoè¾ÈÞbò3ßÓ›|ÉA)i!éšîÒ°ìýÙ6$6â(*ôíèÙ€düðû›ŽPQ³6Òùï9+íŒÞ §0ưŸæÑŠ`¯øßSž{Ø?¼Aª0-cq¿¦툵â¥}¸ú®â7ѽmb>R»kå·G˜ê-Jy»¡n9$·û¸;Öq³Vc'Íîu뉹wøÀ÷•5hM #ŠSuü<[ìw/pF«ÅÀ‘³A?ZŽl¹H“%«²Ý‘øLï3©|ûb¹Y,®Ïôaþ€­å{J‡N„T¡õ†Ì›7ÎKÂÓÛ… DÛbo9Ç™e©ãý¦>)6={>.oAw´þSV&Ûsù`câ`¡p*œ*i^½W”¬Åiô”5·a@‚f©9ï ¿×3y)¢õ®voþd/‹M)ùæ)Å–‡¿Ûý.=8Œ …¤¥”(±Ã–Óa£x*Õ…kŠêWÃ¥ÔX#27ÃvÌT²×Ͻ[šeÝùÒW/ž³Ê–Ã_s!’NA–~ÅßÖ …¸+ YÂb€8™•¤¬C¶Apwû}S¥Í9¬”š'5'@(íǼ$#æø«Éw«k)WšuÈ›•km^s}ÑrëúÃ&B..$ ý;¿PÌ¡øûâÌ•òóïC²ŒÓ4G†§±×1à¶ :JìCID½Øg¯¬ÔvÿÁoǵór@јK¹<‡º˜G׫XÂ[ÎËCˆ~ ¾Ñƒ “˜bwÚOÁk¯ÜÓÕ3m}<Sä±hrÖ««V±«'á‘{å‹nƒ·`ë{Ÿ߀€Ìu—|:¿8I81aYUe€›@Oì²/>aÛÃç æŸñ¿ç2zGä»~Ö-r±JåmryÞ+Wþ¬ùÔ˜P”-&w¯”Æ«Žt삌k’Ôçè.ùcLÜ}º9–þ#Ü5ïiŸ;j®W‹Ä.ºi×ì‘ßÇ(ÜÓ¦Üõ{Ýî„R”pÖ±.’ðLѧ©@Qà ÇcJØQFs©²9–îȸû@««¹É¤–kSò$¢E>Þ¤vS#øòè©@ñê릮ž<ƒðÈzAÀ0#¾9ËPØœTº“¦„`»×}¿… ù€Äì›_ÚÈ;xaAùfd©¯”ì=±ayVÍý„ËöŒÅÞ¯û®Ù|òß$VÇ:ãaÊ/r0×Y}€ÖH:9bfûie1Þ"šþšôÌ|ÖÀµ²HÒgD/O Öu¿ÓhÄÂãùFÙ­JM8c\Ëgå¨êjíDì%bKý²yq÷üüsúXÿaÔ|J;ë÷(EféËÓ:Šß²µ‹ (1øp¥·ŸiÚº^ïWM¥Nï±{ðß¿7³à;7îS„ Fë —qq‡×¼ôŠJ©¿8Šå££hàUn< Pñ%¹>â(ÐRÏ:ƒZ»¿DJmZ&ÞeLÏ‹9rÃxÓµæ'­úºìN17GDIvN6qt]% {;úg~½?ëèK ùb»ëkÀºCm€t.‘Ir·àüã/ƒ «7$ÂøU°žt©wô³ü—u<ÇK­fÒÏZÍ1uò´Þt6SM0¦m]xÕE0Œ³f}Eg‰…–pßr^Ž%b8ŠÞ_1¤76Ÿ=ðw.¨çベ®Îêtõ ÷²EÂæ4™¢9JÂÞ¢4ZŽYU™ ëqIÒø×¿¾±Êõôˆùx}žKÙä'¿ú´R4Œ÷Ó¶Ó‘ÙeÞ(;¡KÚ>[î3‹o—Iü©ÜÜ4©¸\¶*œ{3ù­g6F¶„yž„“ÉñGÐbÅï1̹!ò¨m¾GÝieá]Îk料Þ0Pzë´rîPíÿP™v ½¨\Nï­Ôò¯æd…0FÅM„zå3÷s‘ß3t솽™Ö%»èP£ Ê~BÄSg9=ª”ëmMƒq˜gµK<Áa¼wJPûhL„à^Ó_­],Q*2‹þÂåù%ÆûnÊÆ£Xå}:ò•$…CªŸDaáµr¦ðĘäò:ºI•ú$ú«*šjŸŠÄGVÀªŒÅŬÄäM™¿›d§±ü$˜Ü³ÜO1jìõéyTÒ±ñ¬‰Ï,åó]Q±ËK7>llOÌ4ÙW¥ëÂušÅr-Ü)Ljüéž¹u&Júõ©Ê>×èø(ñæ[“hù^Ï‚Ðy‰nH13¦O¹^§(kQÒŸ> endobj 265 0 obj << /Type /ObjStm /N 63 /First 537 /Length 2706 /Filter /FlateDecode >> stream xÚ½Z[s›º~÷¯Ðc{:®„ìÙ³gré%inMÒ4Éž>[¶Ùƒ8múëÏ’X\L“ÓÌ™ÉXh}úÖU õ\ä ê ä×yGTD(¡ˆ20¸©ãÀ¦¤è0¨ëzˆ8ðʧ nDÁG„0Ä !>bÔwá†"æ2æ"Æ€wbBIˆ‡˜¯%rH`€ºã#—qQâ"—;ÁˆŽ\Ø ×§ €V@ pOT0Ä×G¾ƒ¸"'\=†”œ‚Š9 (Î<6pä+ȹ8‡ñäÈ9ü` Ü/¹®à†‚¹ˆÓæxÁ‚xÈSó€<æ€ï@Î|pCž “Y&BD Ïc`ÈQþƒ+xľPApU0¼…A@ ŒP¾“„N¡ÂGÂ÷”${©Š„ƒ|&RŸ Ÿ;!6Èç`õòQc\äûŽ?¢ÀÊ÷}5ÆC~Àa _ÀïŒþüs„/Wá÷iRìË|’E«"ÍFúù$\›۳ýÝÓ½7'Ñòn_„ÉÑx7§0"ç9rÍÐÝÝôú{LÀûcA'¸$pƒo#¼“OdR Aéï…«2š/ÊG5¡z7¦DŒðAÆÑd'™Ç9#|QÈå".áëR‰3…±³ Y Wxïá}ü¿Çð>ÄGøŸâ3|Ž/ð%þ‚opˆïðOÒ8Mà÷râ)–Xƒa™LÃ|gxÁσijtá9^àÅãj!áð¿8ÆKœà$J$Nq ¿Wxf2‰å¬0w™†[É,J§øg8ǹ|€<úóXMRàb‘I‰‹ï)^ãüÿÀø'þ)³ôµñàû̦:ýõדBóùêëÙ×›vh”·…G¨ð¨’…œý¯áº ß |R‡ r¾ö·òrT;7U>5îSÎ+Jƒš¾ñžã›Û“ëË£¶oÎå|½Í/. eBTókú…4ýBš~a[ÒÖ·BY3kw­¼ý¨3÷“ÎݽŸëü½Â_ñ5¾†ÓHf2rpæ]˜)‡Nä4Šãp8¹åý:ŒŸ“âÉzy'³<š'OÊöU¼Îñý:-äô.Öcª3ÌÔÂ22$‡«bLaæIšÉÁñŸ“'‡·ŸwÚI0T ¾Jµ”Áªô‰`ˆï?)ªvb5°+üM ÛÄwÖÊM9•kÇh +:'w'Xp:ΗLÒi”ÌÁÑlYšLdŽþ¦p°° VP{ò¾´‚}€¡kÒ¹´¬´ÃäŒâ¤íSd mí Þ:µt’/é”®r¯ÌBX½MYÀòüìZ¼Á·vªnkeZœéoÿ4:Ü}£¹iÃöËUõ MT ”lΜ²¢¥þ¦ÀfƒÔàÛ“âÂÜ»¡Ü¬“Ùuþϱ}Žež—ÝjžÉ’D‡¶JxöG*@°&©Á–h äÓ*BPg*@( ø. 'ÿÊB€V=+ÑCè†MmZ8©Ã!äæIã?1e%ä‘jo‹œÊòBµ{8JŒðQX>À¡k„¿FÓb\\³«©C®a½Kܯ£›ãó› àuœ&éQ±™×fÆÄVfô%˜]_ßîî–Ì€—Z€ã0ë¡æw¨¹ j|C c/@íæëÞ‡S‹šYÀ»Ì<çÌ,§± çÁÑþÕ»£7 êz÷rK4ÝŽË8µ‰©m{M§CL<ŸØ§/ŸÞ]½9‹•c¼÷± éø’Œ‰Óã>Úfé2‹¥k‘dîó)]ìîœZ¾:O—aÒ“_(Ú5 =Áò•û¾Ú?ÿøáâ½El[~ñ®ƒ¼F=ËCþKPÛz¦o‡®ÓÈùÅËg¼CÌy>±Ám›œ$§N°59òä¶)ÛÄ‚!bÍLc/Alð˜Ó"'H§™ÛÜÆ^Äm¿³ØÔÔCͬë7ÚevÎe®t < ˆÎÔŽ¨Ðµö§hªvU c\}s5+3d97WÖoS°mS_ë"êlJů°‚Z—]õ ´«sº.bØ•å¥×PYÊiêÓ¨~0€¤VŒ`kŒü2¶;H”éZR¯•³L>¨¯¢¶Wµ¦ðkMÞÐ,MÁz4ÝZ“h–´OäB}ÖíÂÔÔ½`;Lµ 30=l¼ÚŽòËR ãZ0žÛ£ÉkM6 I,^ÕÂ0Îv˜ª* LT0¼ß£ÙI^ÛÁY¯#ïì…³¦£3¬jÁ&ÃÆn ¾¶;½)¦áý&¼kÁ‹Ax·¶ÛMxÞ@$[KbL[ˆ^è6íº¦¯«‡±UeUDÒ@dA‘Ûˆ|Ñ©«­@…è5©H‡Ë „BlZÍVWŒ5bõ°±¶š5­¦ «+ÆÑD¬­¦M«iÃjf[Í­¦µÕ´ÙÅ(³©m5´šÖÝ6»md8µ­¦ƒVӺёf£#¢ÈlD6„HêžGšV“¦ÕŽè "ÖV“¦Õ¤a5±&"k«›F7l&¶ÍdÐæÚäfvSÑ0™Ø&“-&«¯Ê°$¿ÚO'ã‹öõ¯‘Ù$¼ W+™L£¯!h¬eQ±XÊ"š¼/•ÂITÈ·{ç;'œOV+5Úë{±·wy Z¦Ú/ï¢Âs_«3§Ù à£h-NñßÚlLÃ"|[„w±T³HØú3pG-¥bÚ!¯ï²”ªÉ~ûm&©Q%&…Ê—‡µñ¼%o ²¶‰ý¬û´û > Bêí¿ÆÌéTÉ%§–üìôâà^xê…§9Dv}÷ÇdRüTQª^¥Ë=Op³k{5['“"J“|&Óqº’Y¨ÕÚkà†åvåŽ}ÑrË%äµ0Ngãb!Ç…\®Ò,ŒÇjk®¦$e€£dµ. èºP·³4[†…2¦t€ŠÞtmæ1ã]ñ˜À‹€m^Da¬Æ¶Df\ÇØ§Q¶Q:V«wæ[¦šÖÛLk„fbw#.Ó±ÊäJ¤Ç‰’õ váo•Àq-UtL°ç¯ÆuHj9Sñv,@•„fïP 8¸°*ë±BYc |UBN›T5_5¦ŸNöj:™éø']çå4?u¶j&-/9çRgæ´«¼– ¼U%L-F\ôr*ö°ß\Þ¯Õðñ\&²ÎHîT­²*ùçëå2Ì•EeNë†ñv®ÔPªr 9Y$Ñ’l*‹0ŠLÀ«wíâm+z ¶;féÌû™&´L¶u.Çß¡»Œu‡›e0V—i£Mó²·<Ê0/á½(Ç<ª—•Áž¨O§ffœÔÓ5Ç;ý)æ*ÊkyˆÁÐÔξÜìÀõ?®˜+ÝšO ZžÝÕŸl¨ íËÆ«?þw>ìÏãt>2óÍ™¾:so¶&¤êÿkÊÆ\§S‰¿ärs@?…ÂŽÎrä×+þ ¥¤ endstream endobj 289 0 obj << /Type /XRef /Index [0 290] /Size 290 /W [1 3 1] /Root 287 0 R /Info 288 0 R /ID [<43D82A0577CA9670522F7DEDD28BBE82> <43D82A0577CA9670522F7DEDD28BBE82>] /Length 662 /Filter /FlateDecode >> stream xÚ%”¹RQEïéÇ“QDPTDdžAE@&Q™s##530µÊÀx'–`¨©¡‰þƒef¢¬m²jïîÇíÛ÷¬&¥”þf)i<K'ȧH“i:KQÜE Qo‘r €ÚIʃS`žk¤BPD½I*%Ô¤RPFm'g¨m¤rPAm%U‚*°Áµë¤³ šÚB:j¨×Hµà<µ™tÔQ¯’.‚zj©4R¯.ËœF9×Hyßh¢ú®Wi¦6’üȪ—òþZ©õ$¿Q;ÕÏõës$êàZÕÖIõN}Ä>önÐzAè` a0FÁà6¸î‚Ip,DJåžô÷´|ìE(À É#+¡Þ³TOkŽT …X^3€WÐ4à/4f÷‚uù°©ê­÷b ²”µx–ÁS°©þ—·ƒ'`l}°©í· vÀ.؇쀻* D˜qEteÀŽ‘z"ûðÊwq\EŸÅA•Uò‘æ—ü»2Àîuò2Õ¤yÀ,…ÏÂb¡…PEè#”šÉ¢žðT¸¡ÊHk¿ý ¯çî(/+B~a§øH„˜â‹NŠ/O8$œ^©.ÒÁg/oEùº…Žêbeo …Cšø'üþ ÿ„B=¡žPO ` Òs §qÖãìåIû`™´–©üCÑ ‰#ZŒ[Œ[Œ[Œ[-´ ¶"½øîå·#½÷ôµéÇÿáíFä:íEì68íG|ûêtÙdµÓadï’ÓQdŸŽÛH‘[|™";sÈþœ‰È-Œœ do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; #ifdef RCPP_USE_GLOBAL_ROSTREAM Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); #endif // duration_from_string_impl Rcpp::NumericVector duration_from_string_impl(Rcpp::CharacterVector str); RcppExport SEXP _nanotime_duration_from_string_impl(SEXP strSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type str(strSEXP); rcpp_result_gen = Rcpp::wrap(duration_from_string_impl(str)); return rcpp_result_gen; END_RCPP } // duration_to_string_impl Rcpp::CharacterVector duration_to_string_impl(Rcpp::NumericVector dur); RcppExport SEXP _nanotime_duration_to_string_impl(SEXP durSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type dur(durSEXP); rcpp_result_gen = Rcpp::wrap(duration_to_string_impl(dur)); return rcpp_result_gen; END_RCPP } // duration_is_na_impl Rcpp::LogicalVector duration_is_na_impl(Rcpp::NumericVector dur); RcppExport SEXP _nanotime_duration_is_na_impl(SEXP durSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type dur(durSEXP); rcpp_result_gen = Rcpp::wrap(duration_is_na_impl(dur)); return rcpp_result_gen; END_RCPP } // make_duration_impl Rcpp::NumericVector make_duration_impl(const Rcpp::NumericVector h_nv, const Rcpp::NumericVector m_nv, const Rcpp::NumericVector s_nv, const Rcpp::NumericVector n_nv); RcppExport SEXP _nanotime_make_duration_impl(SEXP h_nvSEXP, SEXP m_nvSEXP, SEXP s_nvSEXP, SEXP n_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type h_nv(h_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type m_nv(m_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type s_nv(s_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type n_nv(n_nvSEXP); rcpp_result_gen = Rcpp::wrap(make_duration_impl(h_nv, m_nv, s_nv, n_nv)); return rcpp_result_gen; END_RCPP } // nanoduration_subset_numeric_impl Rcpp::NumericVector nanoduration_subset_numeric_impl(const Rcpp::NumericVector& v, const Rcpp::NumericVector& idx); RcppExport SEXP _nanotime_nanoduration_subset_numeric_impl(SEXP vSEXP, SEXP idxSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type idx(idxSEXP); rcpp_result_gen = Rcpp::wrap(nanoduration_subset_numeric_impl(v, idx)); return rcpp_result_gen; END_RCPP } // nanoduration_subset_logical_impl Rcpp::NumericVector nanoduration_subset_logical_impl(const Rcpp::NumericVector& v, const Rcpp::LogicalVector& idx_p); RcppExport SEXP _nanotime_nanoduration_subset_logical_impl(SEXP vSEXP, SEXP idx_pSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector& >::type idx_p(idx_pSEXP); rcpp_result_gen = Rcpp::wrap(nanoduration_subset_logical_impl(v, idx_p)); return rcpp_result_gen; END_RCPP } // nanoival_intersect_idx_time_interval_impl Rcpp::List nanoival_intersect_idx_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_intersect_idx_time_interval_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_intersect_idx_time_interval_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_intersect_idx_time_interval_logical_impl Rcpp::LogicalVector nanoival_intersect_idx_time_interval_logical_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_intersect_idx_time_interval_logical_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_intersect_idx_time_interval_logical_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_intersect_time_interval_impl Rcpp::S4 nanoival_intersect_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_intersect_time_interval_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_intersect_time_interval_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_setdiff_time_interval_impl Rcpp::NumericVector nanoival_setdiff_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_setdiff_time_interval_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_setdiff_time_interval_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_union_impl Rcpp::ComplexVector nanoival_union_impl(const Rcpp::ComplexVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_union_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_union_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_intersect_impl Rcpp::ComplexVector nanoival_intersect_impl(const Rcpp::ComplexVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_intersect_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_intersect_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_setdiff_impl Rcpp::ComplexVector nanoival_setdiff_impl(const Rcpp::ComplexVector nv1, const Rcpp::ComplexVector nv2); RcppExport SEXP _nanotime_nanoival_setdiff_impl(SEXP nv1SEXP, SEXP nv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nv2(nv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_setdiff_impl(nv1, nv2)); return rcpp_result_gen; END_RCPP } // nanoival_is_unsorted_impl bool nanoival_is_unsorted_impl(const Rcpp::ComplexVector nvec, const Rcpp::LogicalVector strictlyvec); RcppExport SEXP _nanotime_nanoival_is_unsorted_impl(SEXP nvecSEXP, SEXP strictlyvecSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nvec(nvecSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector >::type strictlyvec(strictlyvecSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_is_unsorted_impl(nvec, strictlyvec)); return rcpp_result_gen; END_RCPP } // nanoival_sort_impl const Rcpp::ComplexVector nanoival_sort_impl(const Rcpp::ComplexVector nvec, const Rcpp::LogicalVector decreasingvec); RcppExport SEXP _nanotime_nanoival_sort_impl(SEXP nvecSEXP, SEXP decreasingvecSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nvec(nvecSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector >::type decreasingvec(decreasingvecSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_sort_impl(nvec, decreasingvec)); return rcpp_result_gen; END_RCPP } // nanoival_sort_impl2 const Rcpp::ComplexVector nanoival_sort_impl2(const Rcpp::ComplexVector nvec, bool decreasing); RcppExport SEXP _nanotime_nanoival_sort_impl2(SEXP nvecSEXP, SEXP decreasingSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type nvec(nvecSEXP); Rcpp::traits::input_parameter< bool >::type decreasing(decreasingSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_sort_impl2(nvec, decreasing)); return rcpp_result_gen; END_RCPP } // nanoival_lt_impl Rcpp::LogicalVector nanoival_lt_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2); RcppExport SEXP _nanotime_nanoival_lt_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_lt_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_le_impl Rcpp::LogicalVector nanoival_le_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2); RcppExport SEXP _nanotime_nanoival_le_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_le_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_gt_impl Rcpp::LogicalVector nanoival_gt_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2); RcppExport SEXP _nanotime_nanoival_gt_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_gt_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_ge_impl Rcpp::LogicalVector nanoival_ge_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2); RcppExport SEXP _nanotime_nanoival_ge_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_ge_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_eq_impl Rcpp::LogicalVector nanoival_eq_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2); RcppExport SEXP _nanotime_nanoival_eq_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_eq_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_ne_impl Rcpp::LogicalVector nanoival_ne_impl(Rcpp::ComplexVector n1, Rcpp::ComplexVector n2); RcppExport SEXP _nanotime_nanoival_ne_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< Rcpp::ComplexVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_ne_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_plus_impl Rcpp::ComplexVector nanoival_plus_impl(const Rcpp::ComplexVector n1, const Rcpp::NumericVector n2); RcppExport SEXP _nanotime_nanoival_plus_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_plus_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_minus_impl Rcpp::ComplexVector nanoival_minus_impl(const Rcpp::ComplexVector n1, const Rcpp::NumericVector n2); RcppExport SEXP _nanotime_nanoival_minus_impl(SEXP n1SEXP, SEXP n2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type n1(n1SEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type n2(n2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_minus_impl(n1, n2)); return rcpp_result_gen; END_RCPP } // nanoival_setdiff_idx_time_interval_impl Rcpp::NumericVector nanoival_setdiff_idx_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector cv2); RcppExport SEXP _nanotime_nanoival_setdiff_idx_time_interval_impl(SEXP nv1SEXP, SEXP cv2SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type nv1(nv1SEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv2(cv2SEXP); rcpp_result_gen = Rcpp::wrap(nanoival_setdiff_idx_time_interval_impl(nv1, cv2)); return rcpp_result_gen; END_RCPP } // nanoival_new_impl Rcpp::S4 nanoival_new_impl(const Rcpp::NumericVector sv, const Rcpp::NumericVector ev, const Rcpp::LogicalVector sopenv, const Rcpp::LogicalVector eopenv); RcppExport SEXP _nanotime_nanoival_new_impl(SEXP svSEXP, SEXP evSEXP, SEXP sopenvSEXP, SEXP eopenvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type sv(svSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type ev(evSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector >::type sopenv(sopenvSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector >::type eopenv(eopenvSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_new_impl(sv, ev, sopenv, eopenv)); return rcpp_result_gen; END_RCPP } // nanoival_get_start_impl Rcpp::NumericVector nanoival_get_start_impl(const Rcpp::ComplexVector cv); RcppExport SEXP _nanotime_nanoival_get_start_impl(SEXP cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv(cvSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_get_start_impl(cv)); return rcpp_result_gen; END_RCPP } // nanoival_get_end_impl Rcpp::NumericVector nanoival_get_end_impl(const Rcpp::ComplexVector cv); RcppExport SEXP _nanotime_nanoival_get_end_impl(SEXP cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv(cvSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_get_end_impl(cv)); return rcpp_result_gen; END_RCPP } // nanoival_get_sopen_impl Rcpp::LogicalVector nanoival_get_sopen_impl(const Rcpp::ComplexVector cv); RcppExport SEXP _nanotime_nanoival_get_sopen_impl(SEXP cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv(cvSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_get_sopen_impl(cv)); return rcpp_result_gen; END_RCPP } // nanoival_get_eopen_impl Rcpp::LogicalVector nanoival_get_eopen_impl(const Rcpp::ComplexVector cv); RcppExport SEXP _nanotime_nanoival_get_eopen_impl(SEXP cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv(cvSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_get_eopen_impl(cv)); return rcpp_result_gen; END_RCPP } // nanoival_isna_impl Rcpp::LogicalVector nanoival_isna_impl(const Rcpp::ComplexVector cv); RcppExport SEXP _nanotime_nanoival_isna_impl(SEXP cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv(cvSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_isna_impl(cv)); return rcpp_result_gen; END_RCPP } // nanoival_make_impl Rcpp::ComplexVector nanoival_make_impl(const Rcpp::CharacterVector nt_v, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_nanoival_make_impl(SEXP nt_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type nt_v(nt_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_make_impl(nt_v, tz_v)); return rcpp_result_gen; END_RCPP } // nanoival_subset_numeric_impl Rcpp::ComplexVector nanoival_subset_numeric_impl(const Rcpp::ComplexVector& v, const Rcpp::NumericVector& idx); RcppExport SEXP _nanotime_nanoival_subset_numeric_impl(SEXP vSEXP, SEXP idxSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type idx(idxSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_subset_numeric_impl(v, idx)); return rcpp_result_gen; END_RCPP } // nanoival_subset_logical_impl Rcpp::ComplexVector nanoival_subset_logical_impl(const Rcpp::ComplexVector& v, const Rcpp::LogicalVector& idx_p); RcppExport SEXP _nanotime_nanoival_subset_logical_impl(SEXP vSEXP, SEXP idx_pSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector& >::type idx_p(idx_pSEXP); rcpp_result_gen = Rcpp::wrap(nanoival_subset_logical_impl(v, idx_p)); return rcpp_result_gen; END_RCPP } // nanotime_wday_impl Rcpp::IntegerVector nanotime_wday_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_nanotime_wday_impl(SEXP tm_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type tm_v(tm_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_wday_impl(tm_v, tz_v)); return rcpp_result_gen; END_RCPP } // nanotime_mday_impl Rcpp::IntegerVector nanotime_mday_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_nanotime_mday_impl(SEXP tm_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type tm_v(tm_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_mday_impl(tm_v, tz_v)); return rcpp_result_gen; END_RCPP } // nanotime_month_impl Rcpp::IntegerVector nanotime_month_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_nanotime_month_impl(SEXP tm_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type tm_v(tm_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_month_impl(tm_v, tz_v)); return rcpp_result_gen; END_RCPP } // nanotime_year_impl Rcpp::IntegerVector nanotime_year_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_nanotime_year_impl(SEXP tm_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type tm_v(tm_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_year_impl(tm_v, tz_v)); return rcpp_result_gen; END_RCPP } // nanotime_make_impl Rcpp::NumericVector nanotime_make_impl(const Rcpp::CharacterVector nt_v, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_nanotime_make_impl(SEXP nt_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type nt_v(nt_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_make_impl(nt_v, tz_v)); return rcpp_result_gen; END_RCPP } // nanotime_subset_numeric_impl Rcpp::NumericVector nanotime_subset_numeric_impl(const Rcpp::NumericVector& v, const Rcpp::NumericVector& idx); RcppExport SEXP _nanotime_nanotime_subset_numeric_impl(SEXP vSEXP, SEXP idxSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type idx(idxSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_subset_numeric_impl(v, idx)); return rcpp_result_gen; END_RCPP } // nanotime_subset_logical_impl Rcpp::NumericVector nanotime_subset_logical_impl(const Rcpp::NumericVector& v, const Rcpp::LogicalVector& idx_p); RcppExport SEXP _nanotime_nanotime_subset_logical_impl(SEXP vSEXP, SEXP idx_pSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector& >::type idx_p(idx_pSEXP); rcpp_result_gen = Rcpp::wrap(nanotime_subset_logical_impl(v, idx_p)); return rcpp_result_gen; END_RCPP } // period_from_string_impl Rcpp::ComplexVector period_from_string_impl(Rcpp::CharacterVector str); RcppExport SEXP _nanotime_period_from_string_impl(SEXP strSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::CharacterVector >::type str(strSEXP); rcpp_result_gen = Rcpp::wrap(period_from_string_impl(str)); return rcpp_result_gen; END_RCPP } // period_from_parts_impl Rcpp::ComplexVector period_from_parts_impl(Rcpp::IntegerVector months_v, Rcpp::IntegerVector days_v, Rcpp::NumericVector dur_v); RcppExport SEXP _nanotime_period_from_parts_impl(SEXP months_vSEXP, SEXP days_vSEXP, SEXP dur_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type months_v(months_vSEXP); Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type days_v(days_vSEXP); Rcpp::traits::input_parameter< Rcpp::NumericVector >::type dur_v(dur_vSEXP); rcpp_result_gen = Rcpp::wrap(period_from_parts_impl(months_v, days_v, dur_v)); return rcpp_result_gen; END_RCPP } // period_to_string_impl Rcpp::CharacterVector period_to_string_impl(Rcpp::ComplexVector prd); RcppExport SEXP _nanotime_period_to_string_impl(SEXP prdSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::ComplexVector >::type prd(prdSEXP); rcpp_result_gen = Rcpp::wrap(period_to_string_impl(prd)); return rcpp_result_gen; END_RCPP } // period_from_integer64_impl Rcpp::ComplexVector period_from_integer64_impl(Rcpp::NumericVector i64); RcppExport SEXP _nanotime_period_from_integer64_impl(SEXP i64SEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type i64(i64SEXP); rcpp_result_gen = Rcpp::wrap(period_from_integer64_impl(i64)); return rcpp_result_gen; END_RCPP } // period_from_integer_impl Rcpp::ComplexVector period_from_integer_impl(Rcpp::IntegerVector iint); RcppExport SEXP _nanotime_period_from_integer_impl(SEXP iintSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::IntegerVector >::type iint(iintSEXP); rcpp_result_gen = Rcpp::wrap(period_from_integer_impl(iint)); return rcpp_result_gen; END_RCPP } // period_from_double_impl Rcpp::ComplexVector period_from_double_impl(Rcpp::NumericVector dbl); RcppExport SEXP _nanotime_period_from_double_impl(SEXP dblSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::NumericVector >::type dbl(dblSEXP); rcpp_result_gen = Rcpp::wrap(period_from_double_impl(dbl)); return rcpp_result_gen; END_RCPP } // plus_period_period_impl Rcpp::ComplexVector plus_period_period_impl(const Rcpp::ComplexVector e1_nv, const Rcpp::ComplexVector e2_nv); RcppExport SEXP _nanotime_plus_period_period_impl(SEXP e1_nvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_nv(e1_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(plus_period_period_impl(e1_nv, e2_nv)); return rcpp_result_gen; END_RCPP } // minus_period_impl Rcpp::ComplexVector minus_period_impl(const Rcpp::ComplexVector e1_cv); RcppExport SEXP _nanotime_minus_period_impl(SEXP e1_cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); rcpp_result_gen = Rcpp::wrap(minus_period_impl(e1_cv)); return rcpp_result_gen; END_RCPP } // minus_period_period_impl Rcpp::ComplexVector minus_period_period_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv); RcppExport SEXP _nanotime_minus_period_period_impl(SEXP e1_cvSEXP, SEXP e2_cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_cv(e2_cvSEXP); rcpp_result_gen = Rcpp::wrap(minus_period_period_impl(e1_cv, e2_cv)); return rcpp_result_gen; END_RCPP } // eq_period_period_impl Rcpp::LogicalVector eq_period_period_impl(const Rcpp::ComplexVector e1_p, const Rcpp::ComplexVector e2_p); RcppExport SEXP _nanotime_eq_period_period_impl(SEXP e1_pSEXP, SEXP e2_pSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_p(e1_pSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_p(e2_pSEXP); rcpp_result_gen = Rcpp::wrap(eq_period_period_impl(e1_p, e2_p)); return rcpp_result_gen; END_RCPP } // ne_period_period_impl Rcpp::LogicalVector ne_period_period_impl(const Rcpp::ComplexVector e1_p, const Rcpp::ComplexVector e2_p); RcppExport SEXP _nanotime_ne_period_period_impl(SEXP e1_pSEXP, SEXP e2_pSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_p(e1_pSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_p(e2_pSEXP); rcpp_result_gen = Rcpp::wrap(ne_period_period_impl(e1_p, e2_p)); return rcpp_result_gen; END_RCPP } // plus_period_integer64_impl Rcpp::ComplexVector plus_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv); RcppExport SEXP _nanotime_plus_period_integer64_impl(SEXP e1_cvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(plus_period_integer64_impl(e1_cv, e2_nv)); return rcpp_result_gen; END_RCPP } // minus_period_integer64_impl Rcpp::ComplexVector minus_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv); RcppExport SEXP _nanotime_minus_period_integer64_impl(SEXP e1_cvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(minus_period_integer64_impl(e1_cv, e2_nv)); return rcpp_result_gen; END_RCPP } // multiplies_period_integer64_impl Rcpp::ComplexVector multiplies_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv); RcppExport SEXP _nanotime_multiplies_period_integer64_impl(SEXP e1_cvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(multiplies_period_integer64_impl(e1_cv, e2_nv)); return rcpp_result_gen; END_RCPP } // divides_period_integer64_impl Rcpp::ComplexVector divides_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv); RcppExport SEXP _nanotime_divides_period_integer64_impl(SEXP e1_cvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(divides_period_integer64_impl(e1_cv, e2_nv)); return rcpp_result_gen; END_RCPP } // multiplies_period_double_impl Rcpp::ComplexVector multiplies_period_double_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv); RcppExport SEXP _nanotime_multiplies_period_double_impl(SEXP e1_cvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(multiplies_period_double_impl(e1_cv, e2_nv)); return rcpp_result_gen; END_RCPP } // divides_period_double_impl Rcpp::ComplexVector divides_period_double_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv); RcppExport SEXP _nanotime_divides_period_double_impl(SEXP e1_cvSEXP, SEXP e2_nvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e2_nv(e2_nvSEXP); rcpp_result_gen = Rcpp::wrap(divides_period_double_impl(e1_cv, e2_nv)); return rcpp_result_gen; END_RCPP } // minus_integer64_period_impl Rcpp::ComplexVector minus_integer64_period_impl(const Rcpp::NumericVector e1_nv, const Rcpp::ComplexVector e2_cv); RcppExport SEXP _nanotime_minus_integer64_period_impl(SEXP e1_nvSEXP, SEXP e2_cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e1_nv(e1_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_cv(e2_cvSEXP); rcpp_result_gen = Rcpp::wrap(minus_integer64_period_impl(e1_nv, e2_cv)); return rcpp_result_gen; END_RCPP } // plus_nanotime_period_impl Rcpp::NumericVector plus_nanotime_period_impl(const Rcpp::NumericVector e1_nv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_plus_nanotime_period_impl(SEXP e1_nvSEXP, SEXP e2_cvSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e1_nv(e1_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_cv(e2_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(plus_nanotime_period_impl(e1_nv, e2_cv, tz_v)); return rcpp_result_gen; END_RCPP } // minus_nanotime_period_impl Rcpp::NumericVector minus_nanotime_period_impl(const Rcpp::NumericVector e1_nv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_minus_nanotime_period_impl(SEXP e1_nvSEXP, SEXP e2_cvSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type e1_nv(e1_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_cv(e2_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(minus_nanotime_period_impl(e1_nv, e2_cv, tz_v)); return rcpp_result_gen; END_RCPP } // plus_nanoival_period_impl Rcpp::ComplexVector plus_nanoival_period_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_plus_nanoival_period_impl(SEXP e1_cvSEXP, SEXP e2_cvSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_cv(e2_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(plus_nanoival_period_impl(e1_cv, e2_cv, tz_v)); return rcpp_result_gen; END_RCPP } // minus_nanoival_period_impl Rcpp::ComplexVector minus_nanoival_period_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v); RcppExport SEXP _nanotime_minus_nanoival_period_impl(SEXP e1_cvSEXP, SEXP e2_cvSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e1_cv(e1_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e2_cv(e2_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(minus_nanoival_period_impl(e1_cv, e2_cv, tz_v)); return rcpp_result_gen; END_RCPP } // period_month_impl Rcpp::NumericVector period_month_impl(const Rcpp::ComplexVector e_n); RcppExport SEXP _nanotime_period_month_impl(SEXP e_nSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e_n(e_nSEXP); rcpp_result_gen = Rcpp::wrap(period_month_impl(e_n)); return rcpp_result_gen; END_RCPP } // period_day_impl Rcpp::NumericVector period_day_impl(const Rcpp::ComplexVector e_n); RcppExport SEXP _nanotime_period_day_impl(SEXP e_nSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e_n(e_nSEXP); rcpp_result_gen = Rcpp::wrap(period_day_impl(e_n)); return rcpp_result_gen; END_RCPP } // period_duration_impl Rcpp::S4 period_duration_impl(const Rcpp::ComplexVector e_n); RcppExport SEXP _nanotime_period_duration_impl(SEXP e_nSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type e_n(e_nSEXP); rcpp_result_gen = Rcpp::wrap(period_duration_impl(e_n)); return rcpp_result_gen; END_RCPP } // period_isna_impl Rcpp::LogicalVector period_isna_impl(const Rcpp::ComplexVector cv); RcppExport SEXP _nanotime_period_isna_impl(SEXP cvSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type cv(cvSEXP); rcpp_result_gen = Rcpp::wrap(period_isna_impl(cv)); return rcpp_result_gen; END_RCPP } // period_seq_from_to_impl Rcpp::NumericVector period_seq_from_to_impl(const Rcpp::NumericVector from_nv, const Rcpp::NumericVector to_nv, const Rcpp::ComplexVector by_cv, const std::string tz); RcppExport SEXP _nanotime_period_seq_from_to_impl(SEXP from_nvSEXP, SEXP to_nvSEXP, SEXP by_cvSEXP, SEXP tzSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type from_nv(from_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type to_nv(to_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type by_cv(by_cvSEXP); Rcpp::traits::input_parameter< const std::string >::type tz(tzSEXP); rcpp_result_gen = Rcpp::wrap(period_seq_from_to_impl(from_nv, to_nv, by_cv, tz)); return rcpp_result_gen; END_RCPP } // period_seq_from_length_impl Rcpp::NumericVector period_seq_from_length_impl(const Rcpp::NumericVector from_nv, const Rcpp::ComplexVector by_cv, const Rcpp::NumericVector n_nv, const std::string tz); RcppExport SEXP _nanotime_period_seq_from_length_impl(SEXP from_nvSEXP, SEXP by_cvSEXP, SEXP n_nvSEXP, SEXP tzSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type from_nv(from_nvSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector >::type by_cv(by_cvSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type n_nv(n_nvSEXP); Rcpp::traits::input_parameter< const std::string >::type tz(tzSEXP); rcpp_result_gen = Rcpp::wrap(period_seq_from_length_impl(from_nv, by_cv, n_nv, tz)); return rcpp_result_gen; END_RCPP } // period_subset_numeric_impl Rcpp::ComplexVector period_subset_numeric_impl(const Rcpp::ComplexVector& v, const Rcpp::NumericVector& idx); RcppExport SEXP _nanotime_period_subset_numeric_impl(SEXP vSEXP, SEXP idxSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type idx(idxSEXP); rcpp_result_gen = Rcpp::wrap(period_subset_numeric_impl(v, idx)); return rcpp_result_gen; END_RCPP } // period_subset_logical_impl Rcpp::ComplexVector period_subset_logical_impl(const Rcpp::ComplexVector& v, const Rcpp::LogicalVector& idx_p); RcppExport SEXP _nanotime_period_subset_logical_impl(SEXP vSEXP, SEXP idx_pSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::ComplexVector& >::type v(vSEXP); Rcpp::traits::input_parameter< const Rcpp::LogicalVector& >::type idx_p(idx_pSEXP); rcpp_result_gen = Rcpp::wrap(period_subset_logical_impl(v, idx_p)); return rcpp_result_gen; END_RCPP } // ceiling_tz_impl Rcpp::NumericVector ceiling_tz_impl(const Rcpp::NumericVector& nt_v, const Rcpp::ComplexVector& prd_v, const Rcpp::NumericVector& orig_v, const Rcpp::CharacterVector& tz_v); RcppExport SEXP _nanotime_ceiling_tz_impl(SEXP nt_vSEXP, SEXP prd_vSEXP, SEXP orig_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type nt_v(nt_vSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector& >::type prd_v(prd_vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type orig_v(orig_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector& >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(ceiling_tz_impl(nt_v, prd_v, orig_v, tz_v)); return rcpp_result_gen; END_RCPP } // ceiling_impl Rcpp::NumericVector ceiling_impl(const Rcpp::NumericVector& nt_v, const Rcpp::NumericVector& dur_v, const Rcpp::NumericVector& orig_v); RcppExport SEXP _nanotime_ceiling_impl(SEXP nt_vSEXP, SEXP dur_vSEXP, SEXP orig_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type nt_v(nt_vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type dur_v(dur_vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type orig_v(orig_vSEXP); rcpp_result_gen = Rcpp::wrap(ceiling_impl(nt_v, dur_v, orig_v)); return rcpp_result_gen; END_RCPP } // floor_tz_impl Rcpp::NumericVector floor_tz_impl(const Rcpp::NumericVector& nt_v, const Rcpp::ComplexVector& prd_v, const Rcpp::NumericVector& orig_v, const Rcpp::CharacterVector& tz_v); RcppExport SEXP _nanotime_floor_tz_impl(SEXP nt_vSEXP, SEXP prd_vSEXP, SEXP orig_vSEXP, SEXP tz_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type nt_v(nt_vSEXP); Rcpp::traits::input_parameter< const Rcpp::ComplexVector& >::type prd_v(prd_vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type orig_v(orig_vSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector& >::type tz_v(tz_vSEXP); rcpp_result_gen = Rcpp::wrap(floor_tz_impl(nt_v, prd_v, orig_v, tz_v)); return rcpp_result_gen; END_RCPP } // floor_impl Rcpp::NumericVector floor_impl(const Rcpp::NumericVector& nt_v, const Rcpp::NumericVector& dur_v, const Rcpp::NumericVector& orig_v); RcppExport SEXP _nanotime_floor_impl(SEXP nt_vSEXP, SEXP dur_vSEXP, SEXP orig_vSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type nt_v(nt_vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type dur_v(dur_vSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type orig_v(orig_vSEXP); rcpp_result_gen = Rcpp::wrap(floor_impl(nt_v, dur_v, orig_v)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_nanotime_duration_from_string_impl", (DL_FUNC) &_nanotime_duration_from_string_impl, 1}, {"_nanotime_duration_to_string_impl", (DL_FUNC) &_nanotime_duration_to_string_impl, 1}, {"_nanotime_duration_is_na_impl", (DL_FUNC) &_nanotime_duration_is_na_impl, 1}, {"_nanotime_make_duration_impl", (DL_FUNC) &_nanotime_make_duration_impl, 4}, {"_nanotime_nanoduration_subset_numeric_impl", (DL_FUNC) &_nanotime_nanoduration_subset_numeric_impl, 2}, {"_nanotime_nanoduration_subset_logical_impl", (DL_FUNC) &_nanotime_nanoduration_subset_logical_impl, 2}, {"_nanotime_nanoival_intersect_idx_time_interval_impl", (DL_FUNC) &_nanotime_nanoival_intersect_idx_time_interval_impl, 2}, {"_nanotime_nanoival_intersect_idx_time_interval_logical_impl", (DL_FUNC) &_nanotime_nanoival_intersect_idx_time_interval_logical_impl, 2}, {"_nanotime_nanoival_intersect_time_interval_impl", (DL_FUNC) &_nanotime_nanoival_intersect_time_interval_impl, 2}, {"_nanotime_nanoival_setdiff_time_interval_impl", (DL_FUNC) &_nanotime_nanoival_setdiff_time_interval_impl, 2}, {"_nanotime_nanoival_union_impl", (DL_FUNC) &_nanotime_nanoival_union_impl, 2}, {"_nanotime_nanoival_intersect_impl", (DL_FUNC) &_nanotime_nanoival_intersect_impl, 2}, {"_nanotime_nanoival_setdiff_impl", (DL_FUNC) &_nanotime_nanoival_setdiff_impl, 2}, {"_nanotime_nanoival_is_unsorted_impl", (DL_FUNC) &_nanotime_nanoival_is_unsorted_impl, 2}, {"_nanotime_nanoival_sort_impl", (DL_FUNC) &_nanotime_nanoival_sort_impl, 2}, {"_nanotime_nanoival_sort_impl2", (DL_FUNC) &_nanotime_nanoival_sort_impl2, 2}, {"_nanotime_nanoival_lt_impl", (DL_FUNC) &_nanotime_nanoival_lt_impl, 2}, {"_nanotime_nanoival_le_impl", (DL_FUNC) &_nanotime_nanoival_le_impl, 2}, {"_nanotime_nanoival_gt_impl", (DL_FUNC) &_nanotime_nanoival_gt_impl, 2}, {"_nanotime_nanoival_ge_impl", (DL_FUNC) &_nanotime_nanoival_ge_impl, 2}, {"_nanotime_nanoival_eq_impl", (DL_FUNC) &_nanotime_nanoival_eq_impl, 2}, {"_nanotime_nanoival_ne_impl", (DL_FUNC) &_nanotime_nanoival_ne_impl, 2}, {"_nanotime_nanoival_plus_impl", (DL_FUNC) &_nanotime_nanoival_plus_impl, 2}, {"_nanotime_nanoival_minus_impl", (DL_FUNC) &_nanotime_nanoival_minus_impl, 2}, {"_nanotime_nanoival_setdiff_idx_time_interval_impl", (DL_FUNC) &_nanotime_nanoival_setdiff_idx_time_interval_impl, 2}, {"_nanotime_nanoival_new_impl", (DL_FUNC) &_nanotime_nanoival_new_impl, 4}, {"_nanotime_nanoival_get_start_impl", (DL_FUNC) &_nanotime_nanoival_get_start_impl, 1}, {"_nanotime_nanoival_get_end_impl", (DL_FUNC) &_nanotime_nanoival_get_end_impl, 1}, {"_nanotime_nanoival_get_sopen_impl", (DL_FUNC) &_nanotime_nanoival_get_sopen_impl, 1}, {"_nanotime_nanoival_get_eopen_impl", (DL_FUNC) &_nanotime_nanoival_get_eopen_impl, 1}, {"_nanotime_nanoival_isna_impl", (DL_FUNC) &_nanotime_nanoival_isna_impl, 1}, {"_nanotime_nanoival_make_impl", (DL_FUNC) &_nanotime_nanoival_make_impl, 2}, {"_nanotime_nanoival_subset_numeric_impl", (DL_FUNC) &_nanotime_nanoival_subset_numeric_impl, 2}, {"_nanotime_nanoival_subset_logical_impl", (DL_FUNC) &_nanotime_nanoival_subset_logical_impl, 2}, {"_nanotime_nanotime_wday_impl", (DL_FUNC) &_nanotime_nanotime_wday_impl, 2}, {"_nanotime_nanotime_mday_impl", (DL_FUNC) &_nanotime_nanotime_mday_impl, 2}, {"_nanotime_nanotime_month_impl", (DL_FUNC) &_nanotime_nanotime_month_impl, 2}, {"_nanotime_nanotime_year_impl", (DL_FUNC) &_nanotime_nanotime_year_impl, 2}, {"_nanotime_nanotime_make_impl", (DL_FUNC) &_nanotime_nanotime_make_impl, 2}, {"_nanotime_nanotime_subset_numeric_impl", (DL_FUNC) &_nanotime_nanotime_subset_numeric_impl, 2}, {"_nanotime_nanotime_subset_logical_impl", (DL_FUNC) &_nanotime_nanotime_subset_logical_impl, 2}, {"_nanotime_period_from_string_impl", (DL_FUNC) &_nanotime_period_from_string_impl, 1}, {"_nanotime_period_from_parts_impl", (DL_FUNC) &_nanotime_period_from_parts_impl, 3}, {"_nanotime_period_to_string_impl", (DL_FUNC) &_nanotime_period_to_string_impl, 1}, {"_nanotime_period_from_integer64_impl", (DL_FUNC) &_nanotime_period_from_integer64_impl, 1}, {"_nanotime_period_from_integer_impl", (DL_FUNC) &_nanotime_period_from_integer_impl, 1}, {"_nanotime_period_from_double_impl", (DL_FUNC) &_nanotime_period_from_double_impl, 1}, {"_nanotime_plus_period_period_impl", (DL_FUNC) &_nanotime_plus_period_period_impl, 2}, {"_nanotime_minus_period_impl", (DL_FUNC) &_nanotime_minus_period_impl, 1}, {"_nanotime_minus_period_period_impl", (DL_FUNC) &_nanotime_minus_period_period_impl, 2}, {"_nanotime_eq_period_period_impl", (DL_FUNC) &_nanotime_eq_period_period_impl, 2}, {"_nanotime_ne_period_period_impl", (DL_FUNC) &_nanotime_ne_period_period_impl, 2}, {"_nanotime_plus_period_integer64_impl", (DL_FUNC) &_nanotime_plus_period_integer64_impl, 2}, {"_nanotime_minus_period_integer64_impl", (DL_FUNC) &_nanotime_minus_period_integer64_impl, 2}, {"_nanotime_multiplies_period_integer64_impl", (DL_FUNC) &_nanotime_multiplies_period_integer64_impl, 2}, {"_nanotime_divides_period_integer64_impl", (DL_FUNC) &_nanotime_divides_period_integer64_impl, 2}, {"_nanotime_multiplies_period_double_impl", (DL_FUNC) &_nanotime_multiplies_period_double_impl, 2}, {"_nanotime_divides_period_double_impl", (DL_FUNC) &_nanotime_divides_period_double_impl, 2}, {"_nanotime_minus_integer64_period_impl", (DL_FUNC) &_nanotime_minus_integer64_period_impl, 2}, {"_nanotime_plus_nanotime_period_impl", (DL_FUNC) &_nanotime_plus_nanotime_period_impl, 3}, {"_nanotime_minus_nanotime_period_impl", (DL_FUNC) &_nanotime_minus_nanotime_period_impl, 3}, {"_nanotime_plus_nanoival_period_impl", (DL_FUNC) &_nanotime_plus_nanoival_period_impl, 3}, {"_nanotime_minus_nanoival_period_impl", (DL_FUNC) &_nanotime_minus_nanoival_period_impl, 3}, {"_nanotime_period_month_impl", (DL_FUNC) &_nanotime_period_month_impl, 1}, {"_nanotime_period_day_impl", (DL_FUNC) &_nanotime_period_day_impl, 1}, {"_nanotime_period_duration_impl", (DL_FUNC) &_nanotime_period_duration_impl, 1}, {"_nanotime_period_isna_impl", (DL_FUNC) &_nanotime_period_isna_impl, 1}, {"_nanotime_period_seq_from_to_impl", (DL_FUNC) &_nanotime_period_seq_from_to_impl, 4}, {"_nanotime_period_seq_from_length_impl", (DL_FUNC) &_nanotime_period_seq_from_length_impl, 4}, {"_nanotime_period_subset_numeric_impl", (DL_FUNC) &_nanotime_period_subset_numeric_impl, 2}, {"_nanotime_period_subset_logical_impl", (DL_FUNC) &_nanotime_period_subset_logical_impl, 2}, {"_nanotime_ceiling_tz_impl", (DL_FUNC) &_nanotime_ceiling_tz_impl, 4}, {"_nanotime_ceiling_impl", (DL_FUNC) &_nanotime_ceiling_impl, 3}, {"_nanotime_floor_tz_impl", (DL_FUNC) &_nanotime_floor_tz_impl, 4}, {"_nanotime_floor_impl", (DL_FUNC) &_nanotime_floor_impl, 3}, {NULL, NULL, 0} }; RcppExport void R_init_nanotime(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } nanotime/src/rounding.cpp0000644000176200001440000003240714146544040015214 0ustar liggesusers#include #include #include "nanotime/period.hpp" #include "nanotime/utilities.hpp" using namespace nanotime; // C++-level floor and ceiling functions: // support for rounding 'dtime': enum class RoundingPrecision : uint64_t { NANO, MICRO, MILLI, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR }; static bool isMultipleOf(duration d1, duration d2) { if (d2.count() % d1.count() == 0) { // d1 strictly positive return true; } else { return false; } } static bool isMultipleOf(const period& p1, const period& p2) { // the multiple is considered at the month level, the day level and the duration level; // we know going in here that p2 was artifically generated to have only one of the three portions non-zero: if (p1.getMonths()) { if (p2.getMonths() && !p2.getDays() && p2.getDuration() == duration::zero()) { return p2.getMonths() % p1.getMonths() == 0; } } else if (p1.getDays()) { // for function completeness as we never execute this branch in this setting: #nocov start if (!p2.getMonths() && p2.getDays() && p2.getDuration() == duration::zero()) { return p2.getDays() % p1.getDays() == 0; } } else if (p1.getDuration() != duration::zero()) { // for function completeness as we never execute this branch in this setting if (!p2.getMonths() && !p2.getDays() && p2.getDuration() == duration::zero()) { return isMultipleOf(p1.getDuration(), p2.getDuration()); } } return false; // for function completeness as we never execute this branch in this setting #nocov end } static RoundingPrecision selectPrecision(const duration d) { if (d < std::chrono::microseconds{1}) return isMultipleOf(d, std::chrono::microseconds{1}) ? RoundingPrecision::MICRO : RoundingPrecision::NANO; else if (d < std::chrono::milliseconds{1}) return isMultipleOf(d, std::chrono::milliseconds{1}) ? RoundingPrecision::MILLI : RoundingPrecision::MICRO; else if (d < std::chrono::seconds{1}) return isMultipleOf(d, std::chrono::seconds{1}) ? RoundingPrecision::SECOND : RoundingPrecision::MILLI; else if (d < std::chrono::minutes{1}) return isMultipleOf(d, std::chrono::minutes{1}) ? RoundingPrecision::MINUTE : RoundingPrecision::SECOND; else if (d < std::chrono::hours{1}) return isMultipleOf(d, std::chrono::hours{1}) ? RoundingPrecision::HOUR : RoundingPrecision::MINUTE; else return RoundingPrecision::HOUR; } static RoundingPrecision selectPrecision(const period p) { const auto year = period(12, 0, duration::zero()); if (p.getMonths() >= 1) return isMultipleOf(p, year) ? RoundingPrecision::YEAR : RoundingPrecision::MONTH; else if (p.getDays() >= 1) return RoundingPrecision::DAY; else if (p.getDuration() >= std::chrono::hours{1}) return (isMultipleOf(p.getDuration(), std::chrono::hours{24})) ? RoundingPrecision::DAY : selectPrecision(p.getDuration()); else return selectPrecision(p.getDuration()); } static dtime floor(dtime t, RoundingPrecision p) { using namespace std::chrono; if (t.time_since_epoch().count() >= 0) { switch (p) { case RoundingPrecision::HOUR: // not reachable in this context #nocov return time_point_cast(time_point_cast(t)); // not reachable in this context #nocov case RoundingPrecision::MINUTE: return time_point_cast(time_point_cast(t)); case RoundingPrecision::SECOND: return time_point_cast(time_point_cast(t)); case RoundingPrecision::MILLI: return time_point_cast(time_point_cast(t)); case RoundingPrecision::MICRO: return time_point_cast(time_point_cast(t)); case RoundingPrecision::NANO: return time_point_cast(time_point_cast(t)); default: // not reachable in this context #nocov throw std::out_of_range("unknown rounding type"); // not reachable in this context #nocov } } else { switch (p) { case RoundingPrecision::HOUR: // not reachable in this context #nocov return time_point_cast(time_point_cast(t) - hours{1}); // not reachable in this context #nocov case RoundingPrecision::MINUTE: return time_point_cast(time_point_cast(t) - minutes{1}); case RoundingPrecision::SECOND: return time_point_cast(time_point_cast(t) - seconds{1}); case RoundingPrecision::MILLI: return time_point_cast(time_point_cast(t) - milliseconds{1}); case RoundingPrecision::MICRO: return time_point_cast(time_point_cast(t) - microseconds{1}); case RoundingPrecision::NANO: return time_point_cast(time_point_cast(t)); default: // not reachable in this context #nocov throw std::out_of_range("unknown rounding type"); // not reachable in this context #nocov } } } static dtime floor_tz(const dtime t, RoundingPrecision p, const std::string& z) { using namespace std::chrono; switch (p) { case RoundingPrecision::HOUR: { auto t_offset = t + getOffsetCnv(t, z.c_str()); auto t_hours = time_point_cast(time_point_cast(t_offset)); if (t.time_since_epoch() < nanotime::duration::zero() && t_hours > t_offset) { t_hours -= hours{1}; } return t_hours - getOffsetCnv(t_hours, z.c_str()); } case RoundingPrecision::DAY: { auto t_days = date::floor(t + getOffsetCnv(t, z.c_str())); return t_days - getOffsetCnv(t_days, z.c_str()); } case RoundingPrecision::MONTH: { auto t_days = date::floor(t + getOffsetCnv(t, z.c_str())); auto ymd = date::year_month_day(t_days); t_days = date::sys_days(ymd.year()/ymd.month()/date::day(1)); return t_days - getOffsetCnv(t_days, z.c_str()); } case RoundingPrecision::YEAR: { auto t_days = date::floor(t + getOffsetCnv(t, z.c_str())); auto ymd = date::year_month_day(t_days); t_days = date::sys_days(ymd.year()/date::month(1)/date::day(1)); return t_days - getOffsetCnv(t_days, z.c_str()); } default: return floor(t, p); } } static const std::vector makegrid(const dtime start, bool absolute_start, // is start absolute (e.g no rounding) const dtime end, const period p, const std::string& tz) { const auto precision = selectPrecision(p); const auto start_0 = absolute_start ? start : floor_tz(start, precision, tz); const auto end_0 = plus(end, p, tz); std::vector res; auto c = start_0; for (; c < start_0; c = plus(c, p, tz)) { } for(; c <= end_0; c = plus(c, p, tz)) { res.push_back(c); } return res; } static void ceilingtogrid(const dtime* dt, const uint64_t n_dt, const std::vector& grid, dtime* res) { if (grid.size() <= 1) { throw std::range_error("ceilingtogrid: invalid 'grid' argument"); // not reachable in this context #nocov } size_t iy = 0; for (size_t ix=0; ix < n_dt; ++ix) { while (dt[ix] > grid[iy]) ++iy; res[ix] = grid[iy]; // this is safe by grid construction } } // this is really the same as static void floortogrid(const dtime* dt, const uint64_t n_dt, const std::vector& grid, dtime* res) { if (grid.size() <= 1) { throw std::range_error("floortogrid: invalid 'grid' argument"); // not reachable in this context #nocov } size_t iy = 1; for (size_t ix=0; ix < n_dt; ++ix) { while (dt[ix] >= grid[iy]) ++iy; res[ix] = grid[iy-1]; // this is safe by grid construction } } // [[Rcpp::export]] Rcpp::NumericVector ceiling_tz_impl(const Rcpp::NumericVector& nt_v, // vector of 'nanotime' const Rcpp::ComplexVector& prd_v, // scalar period const Rcpp::NumericVector& orig_v, // origin const Rcpp::CharacterVector& tz_v) { // scalar timezone // check tz and orig are scalar: if (orig_v.size() > 1) { Rcpp::stop("'origin' must be scalar"); } if (tz_v.size() > 1) { Rcpp::stop("'tz' must be scalar"); } period prd; memcpy(&prd, reinterpret_cast(&prd_v[0]), sizeof(period)); const auto tz = Rcpp::as(tz_v[0]); // period must be strictly positive if ((prd.getMonths() < 0 || prd.getDays() < 0 || prd.getDuration() < duration::zero()) || prd == period{0, 0, duration::zero()}) { Rcpp::stop("'precision' must be strictly positive"); } const dtime* dt = reinterpret_cast(&nt_v[0]); dtime origin; if (orig_v.size()) { origin = *reinterpret_cast(&orig_v[0]); if (dt[0] > plus(origin, prd, tz)) { Rcpp::stop("when specifying 'origin', the first interval must contain at least one observation"); } } const auto grid = orig_v.size() ? makegrid(origin, true, dt[nt_v.size()-1], prd, tz) : makegrid(dt[0], false, dt[nt_v.size()-1], prd, tz); Rcpp::NumericVector res(nt_v.size()); auto res_dt = reinterpret_cast(&res[0]); ceilingtogrid(dt, nt_v.size(), grid, res_dt); return assignS4("nanotime", res, "integer64"); } // [[Rcpp::export]] Rcpp::NumericVector ceiling_impl(const Rcpp::NumericVector& nt_v, // vector of 'nanotime' const Rcpp::NumericVector& dur_v, // scalar duration const Rcpp::NumericVector& orig_v) { // scalar origin // check orig is scalar: if (orig_v.size() > 1) { Rcpp::stop("'origin' must be scalar"); } int64_t dur; memcpy(&dur, reinterpret_cast(&dur_v[0]), sizeof(int64_t)); // duration must be strictly positive if (dur < 0) { Rcpp::stop("'precision' must be strictly positive"); } const auto* dt = reinterpret_cast(&nt_v[0]); Rcpp::NumericVector res(nt_v.size()); auto res_dur = reinterpret_cast(&res[0]); const auto origin = orig_v.size() ? *reinterpret_cast(&orig_v[0]) : 0; for (R_xlen_t i=0; i < res.size(); ++i) { res_dur[i] = ((dt[i] - origin) / dur) * dur + origin; if (res_dur[i] > 0 && res_dur[i] < dt[i]) { // round up res_dur[i] += dur; } } return assignS4("nanotime", res, "integer64"); return res; } // [[Rcpp::export]] Rcpp::NumericVector floor_tz_impl(const Rcpp::NumericVector& nt_v, // vector of 'nanotime' const Rcpp::ComplexVector& prd_v, // scalar period const Rcpp::NumericVector& orig_v, // origin const Rcpp::CharacterVector& tz_v) { // scalar timezone // check tz and orig are scalar: if (orig_v.size() > 1) { Rcpp::stop("'origin' must be scalar"); } if (tz_v.size() > 1) { Rcpp::stop("'tz' must be scalar"); } const auto tz = Rcpp::as(tz_v[0]); period prd; memcpy(&prd, reinterpret_cast(&prd_v[0]), sizeof(period)); // period must be strictly positive if ((prd.getMonths() < 0 || prd.getDays() < 0 || prd.getDuration() < duration::zero()) || prd == period{0, 0, duration::zero()}) { Rcpp::stop("'precision' must be strictly positive"); } const auto dt = reinterpret_cast(&nt_v[0]); dtime origin; if (orig_v.size()) { origin = *reinterpret_cast(&orig_v[0]); if (dt[0] > plus(origin, prd, tz)) { Rcpp::stop("when specifying 'origin', the first interval must contain at least one observation"); } } // additionally if origin is supplied, verify it's not more than one interval before the first observation LLL const auto grid = orig_v.size() ? makegrid(origin, true, dt[nt_v.size()-1], prd, tz) : makegrid(dt[0], false, dt[nt_v.size()-1], prd, tz); Rcpp::NumericVector res(nt_v.size()); auto res_dt = reinterpret_cast(&res[0]); floortogrid(dt, nt_v.size(), grid, res_dt); return assignS4("nanotime", res, "integer64"); } // [[Rcpp::export]] Rcpp::NumericVector floor_impl(const Rcpp::NumericVector& nt_v, // vector of 'nanotime' const Rcpp::NumericVector& dur_v, // scalar duration const Rcpp::NumericVector& orig_v) { // origin // check orig are scalar: if (orig_v.size() > 1) Rcpp::stop("'origin' must be scalar"); int64_t dur; memcpy(&dur, reinterpret_cast(&dur_v[0]), sizeof(int64_t)); // duration must be strictly positive if (dur < 0) { Rcpp::stop("'precision' must be strictly positive"); } const auto* dt = reinterpret_cast(&nt_v[0]); Rcpp::NumericVector res(nt_v.size()); auto res_dur = reinterpret_cast(&res[0]); const auto origin = orig_v.size() ? *reinterpret_cast(&orig_v[0]) : 0; for (R_xlen_t i=0; i < res.size(); ++i) { res_dur[i] = ((dt[i] - origin) / dur) * dur + origin; if (res_dur[i] < 0 && res_dur[i] > dt[i]) { res_dur[i] -= dur; } } return assignS4("nanotime", res, "integer64"); } nanotime/src/duration.cpp0000644000176200001440000001443113703333711015210 0ustar liggesusers#include #include #include #include #include #include #include #include #include #include "nanotime/duration.hpp" #include "nanotime/pseudovector.hpp" #include "nanotime/utilities.hpp" using namespace nanotime; duration nanotime::from_string(const std::string& str) { duration d = std::chrono::seconds(0); const char* s = str.c_str(); const char* e = s + str.size(); auto sign = 1; if (s < e && *s == '-') { sign = -1; ++s; } int n; if (!readNumber(s, e, n, false)) throw std::range_error("cannot parse nanoduration"); if (s < e && *s == ':') { // we've got HHH:MM:SS format d += n * std::chrono::hours(1); ++s; if (s + 5 > e || !isdigit(s[0]) || !isdigit(s[1]) || s[2] != ':' || !isdigit(s[3]) || !isdigit(s[4])) { throw std::range_error("cannot parse nanoduration"); } d += ((s[0] - '0')*10 + (s[1] - '0'))*std::chrono::minutes(1); // treat seconds in the general way: n = (s[3] - '0')*10 + (s[4] - '0'); s += 5; } d += n * std::chrono::seconds(1); if (s == e) return sign*d; if (*s++ != '.') throw std::range_error("cannot parse nanoduration"); duration mul = std::chrono::milliseconds(100); unsigned i = 0; while (s < e) { if (mul < std::chrono::nanoseconds(1)) throw std::range_error("cannot parse nanoduration"); if ((i == 3 || i == 6) && *s == '_') { ++s; continue; } ++i; if (!isdigit(*s)) throw std::range_error("cannot parse nanoduration"); d += (*s - '0') * mul; mul /= 10; ++s; } return sign*d; } std::string nanotime::to_string(duration d) { std::stringstream ss; if (is_na(d)) { ss << ""; } else { // handle hh:mm:ss if (d < std::chrono::seconds(0)) { ss << '-'; d *= -1; } auto h = d / std::chrono::hours(1); d -= h * std::chrono::seconds(3600); auto min = d / std::chrono::minutes(1); d -= min * std::chrono::seconds(60); auto s = d / std::chrono::seconds(1); d -= s * std::chrono::seconds(1); ss << std::setfill ('0') << std::setw(2) << h << ':' << std::setw(2) << min << ':' << std::setw(2) << s; // now handle nanoseconds 000_000_000 auto ms = d / std::chrono::milliseconds(1); d -= ms * std::chrono::milliseconds(1); auto us = d / std::chrono::microseconds(1); d -= us * std::chrono::microseconds(1); auto ns = d / std::chrono::nanoseconds(1); d -= ns * std::chrono::nanoseconds(1); if (ms || us || ns) { ss << '.'; ss << std::setfill ('0') << std::setw(3) << ms; if (us || ns) { ss << '_' << std::setfill('0') << std::setw(3) << us; if (ns) { ss << '_' << std::setfill('0') << std::setw(3) << ns; } } } } return ss.str(); } bool nanotime::is_na(duration d) { return d == duration::min(); } // [[Rcpp::export]] Rcpp::NumericVector duration_from_string_impl(Rcpp::CharacterVector str) { Rcpp::NumericVector res(str.size()); for (R_xlen_t i=0; i(str[i])); double* ptr = reinterpret_cast(&dur); res[i] = *ptr; } if (str.hasAttribute("names")) { res.names() = str.names(); } return assignS4("nanoduration", res, "integer64"); } // [[Rcpp::export]] Rcpp::CharacterVector duration_to_string_impl(Rcpp::NumericVector dur) { Rcpp::CharacterVector res(dur.size()); for (R_xlen_t i=0; i(&dur[i]); res[i] = to_string(*dur_i); if (res[i].size() == 0) { res[i] = NA_STRING; } } if (dur.hasAttribute("names")) { res.names() = dur.names(); } return res; } // [[Rcpp::export]] Rcpp::LogicalVector duration_is_na_impl(Rcpp::NumericVector dur) { Rcpp::LogicalVector res(dur.size()); for (R_xlen_t i=0; i(&dur[i]); res[i] = is_na(*dur_i); } if (dur.hasAttribute("names")) { res.names() = dur.names(); } return res; } typedef ConstPseudoVector ConstPseudoVectorInt64; typedef ConstPseudoVector ConstPseudoVectorLgl; // [[Rcpp::export]] Rcpp::NumericVector make_duration_impl(const Rcpp::NumericVector h_nv, const Rcpp::NumericVector m_nv, const Rcpp::NumericVector s_nv, const Rcpp::NumericVector n_nv) { const ConstPseudoVectorInt64 h_i(h_nv); const ConstPseudoVectorInt64 m_i(m_nv); const ConstPseudoVectorInt64 s_i(s_nv); const ConstPseudoVectorInt64 n_i(n_nv); Rcpp::NumericVector res(std::max(std::max(h_i.size(), m_i.size()), std::max(s_i.size(), n_i.size()))); for (R_xlen_t i=0; i(&h_i[i]); auto m64 = *reinterpret_cast(&m_i[i]); auto s64 = *reinterpret_cast(&s_i[i]); auto n64 = *reinterpret_cast(&n_i[i]); auto dur = (h64*3600 + m64*60 + s64) * 1000000000L + n64; double *ptr = reinterpret_cast(&dur); res[i] = *ptr; } return assignS4("nanoduration", res, "integer64"); } static double getNA_nanoduration() { const int64_t i64 = std::numeric_limits::min(); double res; memcpy(&res, &i64, sizeof(res)); return res; } // [[Rcpp::export]] Rcpp::NumericVector nanoduration_subset_numeric_impl(const Rcpp::NumericVector& v, const Rcpp::NumericVector& idx) { Rcpp::NumericVector res(0); std::vector res_c; // by declaring it here we can make subset logical agnostic to double subset_numeric(v, idx, res, res_c, getNA_nanoduration); return assignS4("nanoduration", res, "integer64"); } // [[Rcpp::export]] Rcpp::NumericVector nanoduration_subset_logical_impl(const Rcpp::NumericVector& v, const Rcpp::LogicalVector& idx_p) { const ConstPseudoVectorLgl idx(idx_p); Rcpp::NumericVector res(0); std::vector res_c; // by declaring it here we can make subset logical agnostic to double subset_logical(v, idx, res, res_c, getNA_nanoduration); return assignS4("nanoduration", res, "integer64"); } nanotime/src/interval.cpp0000644000176200001440000006560414634012774015226 0ustar liggesusers#include #include #include #include #include "nanotime/interval.hpp" #include "nanotime/pseudovector.hpp" #include "nanotime/utilities.hpp" #include "cctz/civil_time.h" #include "cctz/time_zone.h" using namespace nanotime; struct double2 { double d1; double d2; }; union ival_union { struct ival_alias { bool sopen : 1; int64_t s : 63; bool eopen : 1; int64_t e : 63; } ival; double2 dbl2; }; typedef ConstPseudoVector ConstPseudoVectorIval; typedef ConstPseudoVector ConstPseudoVectorDur; typedef ConstPseudoVector ConstPseudoVectorNum; typedef ConstPseudoVector ConstPseudoVectorLgl; typedef ConstPseudoVector ConstPseudoVectorChar; // for debug reasons... // cf https://stackoverflow.com/a/16692519 template std::ostream &operator<<(std::ostream &stream, const std::chrono::time_point &time_point) { // updated with https://stackoverflow.com/a/71442312/23224962 and using C++17 return stream << std::chrono::duration_cast(time_point.time_since_epoch()).count(); } #if 0 static void print(const interval& i) { Rcpp::Rcout << (i.sopen() ? "-" : "+") << i.s() << "->" << i.e() << (i.eopen() ? "-" : "+") << std::endl; } #endif template static Rcpp::List intersect_idx(const T* v1, size_t v1_size, const U* v2, size_t v2_size) { // because 'push_back' on R structures is crazy expensive, we use STL vector and copy afterwards: std::vector res_first; std::vector res_second; size_t i1 = 0, i2 = 0; while (i1 < v1_size && i2 < v2_size) { if (v1[i1] < v2[i2]) { ++i1; } else if (v1[i1] > v2[i2]) { ++i2; } else { if (v1_size==0 || v1[i1] != v1[i1-1]) { res_first.push_back(i1+1); res_second.push_back(i2+1); } ++i1; //++i2; this is correct for T==U, but not for example when //T==time and U==interval } } // copy out result: Rcpp::NumericVector res_first_rcpp(res_first.size()); Rcpp::NumericVector res_second_rcpp(res_second.size()); if (res_first.size() > 0) memcpy(&res_first_rcpp[0], &res_first[0], sizeof(double)*res_first.size()); if (res_second.size() > 0) memcpy(&res_second_rcpp[0], &res_second[0], sizeof(double)*res_second.size()); return Rcpp::List::create(Rcpp::Named("x") = res_first_rcpp, Rcpp::Named("y") = res_second_rcpp); } // do a fast intersect without caring about the second index, and // return the result as boolean; this is useful for `data.table` // subsetting: template static std::vector intersect_idx_logical(const T* v1, size_t v1_size, const U* v2, size_t v2_size) { std::vector res(v1_size); size_t i1 = 0, i2 = 0; while (i1 < v1_size && i2 < v2_size) { if (v1[i1] < v2[i2]) { res[i1] = FALSE; ++i1; } else if (v1[i1] > v2[i2]) { ++i2; } else { if (v1_size==0 || v1[i1] != v1[i1-1]) { res[i1] = TRUE; } ++i1; } } return res; } /// intersect_idx T=dtime, U=dtime doesn't need specialization. /// intersect_idx T=dtime, U=tz::interval doesn't need specialization. /// intersect_idx interval/interval doesn't make sense. // RcppExport SEXP _intersect_idx_time_time(SEXP sv1, SEXP sv2) // { // const Rcpp::NumericVector nv1(sv1); // const Rcpp::NumericVector nv2(sv2); // const size_t v1_size = nv1.size(); // const size_t v2_size = nv2.size(); // const dtime* v1 = reinterpret_cast(&nv1[0]); // const dtime* v2 = reinterpret_cast(&nv2[0]); // return intersect_idx(v1, v1_size, v2, v2_size); // } // [[Rcpp::export]] Rcpp::List nanoival_intersect_idx_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2) { const dtime* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); return intersect_idx(v1, nv1.size(), v2, nv2.size()); } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_intersect_idx_time_interval_logical_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2) { const dtime* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); auto res_c = intersect_idx_logical(v1, nv1.size(), v2, nv2.size()); Rcpp::LogicalVector res(nv1.size()); if (nv1.size() > 0) memcpy(&res[0], &res_c[0], sizeof(int)*nv1.size()); return res; } // [[Rcpp::export]] Rcpp::S4 nanoival_intersect_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2) { std::vector res; const dtime* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); R_xlen_t i1 = 0, i2 = 0; while (i1 < nv1.size() && i2 < nv2.size()) { if (v1[i1] < v2[i2]) { ++i1; } else if (v1[i1] > v2[i2]) { ++i2; } else { if (res.size()==0 || v1[i1] != res.back()) { res.push_back(v1[i1]); } ++i1; } } if (res.size() > 0) { double* res_start = reinterpret_cast(&res[0]); double* res_end = res_start + res.size(); auto final_res = Rcpp::NumericVector(res_start, res_end); return assignS4("nanotime", final_res, "integer64"); } else { auto final_res = Rcpp::NumericVector(0); return assignS4("nanotime", final_res, "integer64"); } } // [[Rcpp::export]] Rcpp::NumericVector nanoival_setdiff_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector nv2) { std::vector res; const dtime* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); R_xlen_t i1 = 0, i2 = 0; while (i1 < nv1.size() && i2 < nv2.size()) { if (v1[i1] < v2[i2]) { res.push_back(v1[i1++]); } else if (v1[i1] > v2[i2]) { ++i2; } else { ++i1; } } // pick up elts left in v1: while (i1 < nv1.size()) { res.push_back(v1[i1++]); } double* res_start = reinterpret_cast(&res[0]); double* res_end = res_start + res.size(); return Rcpp::NumericVector(res_start, res_end); } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_union_impl(const Rcpp::ComplexVector nv1, const Rcpp::ComplexVector nv2) { // assume 'nanoival1/2' were sorted at the R level std::vector res; const interval* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); R_xlen_t i1 = 0, i2 = 0; if (nv1.size() > 0 && nv2.size() > 0) { auto v1_lt_v2 = start_lt(v1[i1], v2[i2]); auto start = v1_lt_v2 ? v1[i1].getStart() : v2[i2].getStart(); auto sopen = v1_lt_v2 ? v1[i1].sopen() : v2[i2].sopen(); for (;;) { if (union_end_ge_start(v1[i1], v2[i2]) && union_end_le(v1[i1], v2[i2])) { // v1 |------------| or |--------| // v2 |------------| |------------| if (i1 >= nv1.size() - 1) { // if equal ends, have to do the union of the eopens: auto eopen = union_end_le(v2[i2], v1[i1]) ? v1[i1].eopen() && v2[i2].eopen() : v2[i2].eopen(); // v2 interval done, as there's no more v1 elts to overlap res.push_back(interval(start, v2[i2].getEnd(), sopen, eopen)); ++i1; ++i2; break; } ++i1; } else if (union_end_ge_start(v2[i2], v1[i1]) && union_end_le(v2[i2], v1[i1])) { // v1 |------------| or |------------| // v2 |------------| |--------| if (i2 >= nv2.size() - 1) { // if equal ends, have to do the union of the eopens: auto eopen = union_end_le(v1[i1], v2[i2]) ? v1[i1].eopen() && v2[i2].eopen() : v1[i1].eopen(); // v1 interval done, as there's no more v2 elts to overlap res.push_back(interval(start, v1[i1].getEnd(), sopen, eopen)); ++i1; ++i2; break; } ++i2; } else { if (v1[i1].getEnd() == v2[i2].getEnd() && v1[i1].eopen() && v2[i2].eopen()) { // special case where the intervals are ends are equal and open: res.push_back(interval(start, v1[i1].getEnd(), sopen, v1[i1].eopen())); ++i1; ++i2; } else if (union_end_lt(v1[i1], v2[i2])) { // no interval overlap res.push_back(interval(start, v1[i1].getEnd(), sopen, v1[i1].eopen())); ++i1; } else { // no interval overlap res.push_back(interval(start, v2[i2].getEnd(), sopen, v2[i2].eopen())); ++i2; } // set the start of the next interval: if (i1 < nv1.size() && i2 < nv2.size()) { auto v1_lt_v2 = start_lt(v1[i1], v2[i2]); start = v1_lt_v2 ? v1[i1].getStart() : v2[i2].getStart(); sopen = v1_lt_v2 ? v1[i1].sopen() : v2[i2].sopen(); } else { break; } } } } // remaining non-overlapping intervals in v1: while (i1 < nv1.size()) { res.push_back(v1[i1++]); } while (i2 < nv2.size()) { res.push_back(v2[i2++]); } // build the ComplexVector that we will return to R: Rcpp::ComplexVector finalres(res.size()); memcpy(&finalres[0], &res[0], sizeof(Rcomplex)*res.size()); return finalres; } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_intersect_impl(const Rcpp::ComplexVector nv1, const Rcpp::ComplexVector nv2) { // assume 'nanoival1/2' were sorted at the R level std::vector res; const interval* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); R_xlen_t i1 = 0, i2 = 0; while (i1 < nv1.size() && i2 < nv2.size()) { if (v1[i1].getEnd() < v2[i2].getStart() || (v1[i1].getEnd() == v2[i2].getStart() && (v1[i1].eopen() || v2[i2].sopen()))) { ++i1; continue; } else if (v2[i2].getEnd() < v1[i1].getStart() || (v2[i2].getEnd() == v1[i1].getStart() && (v1[i1].sopen() || v2[i2].eopen()))) { ++i2; continue; } else { auto v1_gt_v2 = start_gt(v1[i1], v2[i2]); auto start = v1_gt_v2 ? v1[i1].getStart() : v2[i2].getStart(); auto sopen = v1_gt_v2 ? v1[i1].sopen() : v2[i2].sopen(); if (end_lt(v1[i1], v2[i2])) { res.push_back(interval(start, v1[i1].getEnd(), sopen, v1[i1].eopen())); ++i1; } else { res.push_back(interval(start, v2[i2].getEnd(), sopen, v2[i2].eopen())); ++i2; } } } // build the ComplexVector that we will return to R: Rcpp::ComplexVector finalres(res.size()); if (res.size() > 0) memcpy(&finalres[0], &res[0], sizeof(Rcomplex)*res.size()); return assignS4("nanoival", finalres); } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_setdiff_impl(const Rcpp::ComplexVector nv1, const Rcpp::ComplexVector nv2) { // assume 'nanoival1/2' were sorted at the R level std::vector res; const interval* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&nv2[0]); R_xlen_t i1 = 0, i2 = 0; auto start = v1[i1].getStart(); auto sopen = v1[i1].sopen(); while (i1 < nv1.size() && i2 < nv2.size()) { if (end_lt_start(v1[i1], v2[i2])) { // |-------------| // |------------| res.push_back(interval(start, v1[i1].getEnd(), sopen, v1[i1].eopen())); if (++i1 >= nv1.size()) break; start = v1[i1].getStart(); sopen = v1[i1].sopen(); } else if (start_lt(v2[i2].getEnd(), v2[i2].eopen(), start, sopen)) { // |------------| // |-------------| ++i2; } else if (start_lt(start, sopen, v2[i2].getStart(), v2[i2].sopen())) { // |-------------| or |-------------| // |------------| |-------| res.push_back(interval(start, v2[i2].getStart(), sopen, !v2[i2].sopen())); if (end_gt(v1[i1], v2[i2])) { // |-------------| // |-------| start = v2[i2].getEnd(); sopen = !v2[i2].eopen(); ++i2; } else { // |-------------| // |------------| if (++i1 >= nv1.size()) break; start = v1[i1].getStart(); sopen = v1[i1].sopen(); } } else if (start_ge(start, sopen, v2[i2].getStart(), v2[i2].sopen()) && end_ge(v2[i2], v1[i1])) { // |-------| // |-------------| if (++i1 >= nv1.size()) break; start = v1[i1].getStart(); sopen = v1[i1].sopen(); } else { // |------------| // |----------| start = v2[i2].getEnd(); sopen = !v2[i2].eopen(); ++i2; } } // remaining non-overlapping intervals in v1: if (i1 < nv1.size()) { res.push_back(interval(start, v1[i1].getEnd(), sopen, v1[i1].eopen())); ++i1; while (i1 < nv1.size()) { res.push_back(v1[i1++]); } } // build the ComplexVector that we will return to R: Rcpp::ComplexVector finalres(res.size()); if (res.size() > 0) memcpy(&finalres[0], &res[0], sizeof(Rcomplex)*res.size()); return finalres; } // [[Rcpp::export]] bool nanoival_is_unsorted_impl(const Rcpp::ComplexVector nvec, const Rcpp::LogicalVector strictlyvec) { if (strictlyvec.size() == 0) { Rcpp::stop("argument 'strictly' cannot have length 0"); } const bool strictlybool = strictlyvec[0]; const interval* ival_ptr = reinterpret_cast(&nvec[0]); const auto ival_len = nvec.size(); if (strictlybool) { for (R_xlen_t i=1; i= ival_ptr[i]) { return true; } } } else { for (R_xlen_t i=1; i ival_ptr[i]) { return true; } } } return false; } // [[Rcpp::export]] const Rcpp::ComplexVector nanoival_sort_impl(const Rcpp::ComplexVector nvec, const Rcpp::LogicalVector decreasingvec) { Rcpp::ComplexVector res = clone(nvec); interval* ival_ptr = reinterpret_cast(&res[0]); const auto ival_len = res.size(); interval* start = ival_ptr; interval* end = start + ival_len; if (decreasingvec.size() == 0) { Rcpp::stop("argument 'decreasing' cannot have length 0"); } else if (!decreasingvec[0]) { std::sort(start, end); } else { std::sort(start, end, std::greater()); } return res; } // [[Rcpp::export]] const Rcpp::ComplexVector nanoival_sort_impl2(const Rcpp::ComplexVector nvec, // #nocov start bool decreasing) { Rcpp::ComplexVector res = clone(nvec); interval* ival_ptr = reinterpret_cast(&res[0]); const auto ival_len = res.size(); interval* start = ival_ptr; interval* end = start + ival_len; if (!decreasing) { std::sort(start, end); } else { std::sort(start, end, std::greater()); } return res; } // #nocov end template Rcpp::LogicalVector nanoival_comp(const Rcpp::ComplexVector v1, const Rcpp::ComplexVector v2, COMP cmp) { checkVectorsLengths(v1, v2); Rcpp::LogicalVector res(getVectorLengths(v1, v2)); if (res.size()) { const ConstPseudoVectorIval cv1(v1); const ConstPseudoVectorIval cv2(v2); const interval* n1_ptr = reinterpret_cast(&cv1[0]); const interval* n2_ptr = reinterpret_cast(&cv2[0]); for (R_xlen_t i=0; i()); } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_le_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2) { return nanoival_comp(n1, n2, std::less_equal()); } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_gt_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2) { return nanoival_comp(n1, n2, std::greater()); } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_ge_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2) { return nanoival_comp(n1, n2, std::greater_equal()); } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_eq_impl(const Rcpp::ComplexVector n1, const Rcpp::ComplexVector n2) { return nanoival_comp(n1, n2, std::equal_to()); } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_ne_impl(Rcpp::ComplexVector n1, Rcpp::ComplexVector n2) { return nanoival_comp(n1, n2, std::not_equal_to()); } template Rcpp::ComplexVector nanoival_op(const Rcpp::ComplexVector cv1, const Rcpp::NumericVector nv2, OP op) { checkVectorsLengths(cv1, nv2); Rcpp::ComplexVector res(getVectorLengths(cv1, nv2)); if (res.size()) { const ConstPseudoVectorIval e1(cv1); const ConstPseudoVectorDur e2(nv2); for (R_xlen_t i=0; i(&e1[i]); const duration dur = *reinterpret_cast(&e2[i]); const auto ires = op(ival, dur); const Rcomplex *ptr = reinterpret_cast(&ires); res[i] = *ptr; } copyNames(cv1, nv2, res); } return res; } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_plus_impl(const Rcpp::ComplexVector n1, const Rcpp::NumericVector n2) { return nanoival_op(n1, n2, nanotime_ops::plus()); } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_minus_impl(const Rcpp::ComplexVector n1, const Rcpp::NumericVector n2) { return nanoival_op(n1, n2, nanotime_ops::minus()); } /// union_idx T=dtime, U=dtime doesn't need specialization. /// union_idx T=dtime, U=tz::interval doesn't make sense. /// union_idx interval/interval doesn't make sense. /// setdiff_idx T=dtime, U=dtime doesn't need specialization. /// setdiff_idx T=interval, U=interval doesn't make sense /// setdiff_idx T=dtime, U=interval: template static Rcpp::NumericVector setdiff_idx(const T* v1, size_t v1_size, const U* v2, size_t v2_size) { std::vector res_first; size_t i1 = 0, i2 = 0; while (i1 < v1_size && i2 < v2_size) { if (v1[i1] < v2[i2]) { res_first.push_back(i1+1); ++i1; } else if (v1[i1] > v2[i2]) { ++i2; } else { ++i1; } } // pick up elts left in v1: while (i1 < v1_size) { res_first.push_back(i1+1); ++i1; } // copy out result: Rcpp::NumericVector res_first_rcpp(res_first.size()); if (res_first.size() > 0) memcpy(&res_first_rcpp[0], &res_first[0], sizeof(double)*res_first.size()); return res_first_rcpp; } // [[Rcpp::export]] Rcpp::NumericVector nanoival_setdiff_idx_time_interval_impl(const Rcpp::NumericVector nv1, const Rcpp::ComplexVector cv2) { const dtime* v1 = reinterpret_cast(&nv1[0]); const interval* v2 = reinterpret_cast(&cv2[0]); return setdiff_idx(v1, nv1.size(), v2, cv2.size()); } // [[Rcpp::export]] Rcpp::S4 nanoival_new_impl(const Rcpp::NumericVector sv, const Rcpp::NumericVector ev, const Rcpp::LogicalVector sopenv, const Rcpp::LogicalVector eopenv) { // handle the special case where one of the operands has 0-length: Rcpp::ComplexVector res(getVectorLengths(sv, ev, sopenv, eopenv)); checkVectorsLengths(sv, ev, sopenv, eopenv); const ConstPseudoVectorNum nvs(sv); const ConstPseudoVectorNum nve(ev); const ConstPseudoVectorLgl lvs(sopenv); const ConstPseudoVectorLgl lve(eopenv); for (R_xlen_t i=0; i < res.size(); ++i) { const double d1 = nvs[i]; const double d2 = nve[i]; dtime i1, i2; memcpy(&i1, reinterpret_cast(&d1), sizeof(d1)); memcpy(&i2, reinterpret_cast(&d2), sizeof(d2)); const interval ival { i1, i2, lvs[i], lve[i] }; memcpy(&res[i], &ival, sizeof(ival)); } return assignS4("nanoival", res); } // R accessor functions: // [[Rcpp::export]] Rcpp::NumericVector nanoival_get_start_impl(const Rcpp::ComplexVector cv) { Rcpp::NumericVector res(cv.size()); for (R_xlen_t i=0; i(&c), sizeof(c)); if (ival.isNA()) { double d; memcpy(&d, reinterpret_cast(&NA_INTEGER64), sizeof(NA_INTEGER64)); res[i] = d; } else { std::int64_t start = ival.s(); double d; memcpy(&d, reinterpret_cast(&start), sizeof(start)); res[i] = d; } } assignS4("nanotime", res, "integer64"); res.names() = cv.names(); return res; } // [[Rcpp::export]] Rcpp::NumericVector nanoival_get_end_impl(const Rcpp::ComplexVector cv) { Rcpp::NumericVector res(cv.size()); for (R_xlen_t i=0; i(&c), sizeof(c)); if (ival.isNA()) { double d; memcpy(&d, reinterpret_cast(&NA_INTEGER64), sizeof(NA_INTEGER64)); res[i] = d; } else { std::int64_t end = ival.e(); double d; memcpy(&d, reinterpret_cast(&end), sizeof(end)); res[i] = d; } } assignS4("nanotime", res, "integer64"); res.names() = cv.names(); return res; } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_get_sopen_impl(const Rcpp::ComplexVector cv) { Rcpp::LogicalVector res(cv.size()); for (R_xlen_t i=0; i(&c), sizeof(c)); if (ival.isNA()) { res[i] = NA_LOGICAL; } else { res[i] = ival.sopen(); } } res.names() = cv.names(); return res; } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_get_eopen_impl(const Rcpp::ComplexVector cv) { Rcpp::LogicalVector res(cv.size()); for (R_xlen_t i=0; i(&c), sizeof(c)); if (ival.isNA()) { res[i] = NA_LOGICAL; } else { res[i] = ival.eopen(); } } res.names() = cv.names(); return res; } // [[Rcpp::export]] Rcpp::LogicalVector nanoival_isna_impl(const Rcpp::ComplexVector cv) { Rcpp::LogicalVector res(cv.size()); for (R_xlen_t i=0; i(&c), sizeof(c)); res[i] = ival.isNA(); } res.names() = cv.names(); return res; } static Rcomplex readNanoival(const char*& sp, const char* const se, const char* tzstr) { // read the +- at the beginning: if (sp >= se || (*sp != '+' && *sp != '-')) { throw std::range_error("Error parsing"); } auto sopen = *sp++ == '+' ? false : true; auto ss = readDtime(sp, se); if (ss.tzstr.size() && strnlen_(tzstr, MAX_TZ_STR_LENGTH)) { throw std::range_error("timezone is specified twice: in the string and as an argument"); } skipWhitespace(sp, se); // read the middle portion if (sp+2 >= se || (*sp != '-' && *(sp+1) != '>')) { throw std::range_error("Error parsing"); } sp += 2; skipWhitespace(sp, se); auto es = readDtime(sp, se-1); // -1 because we don't want to read the -+ as a timezone if (es.tzstr.size() && strnlen_(tzstr, MAX_TZ_STR_LENGTH)) { throw std::range_error("timezone is specified twice: in the string and as an argument"); // ## nocov } // read the +- at the end: if (sp >= se || (*sp != '+' && *sp != '-')) { throw std::range_error("Error parsing aa"); } auto eopen = *sp++ == '+' ? false : true; // check we read until the end if (sp != se) { throw std::range_error("Error parsing"); } const cctz::civil_second start_cvt(ss.y, ss.m, ss.d, ss.hh, ss.mm, ss.ss); cctz::time_point start_tp; const char* tzstr_start = ss.tzstr.size() ? ss.tzstr.c_str() : tzstr; int cvt_res = RcppCCTZ::convertToTimePoint(start_cvt, tzstr_start, start_tp); if (cvt_res < 0) { Rcpp::stop("Cannot retrieve timezone '%s'.", tzstr_start); // ## nocov } auto start = dtime{std::chrono::nanoseconds((start_tp.time_since_epoch().count() - ss.offset) * 1000000000ll + ss.ns)}; const cctz::civil_second end_cvt(es.y, es.m, es.d, es.hh, es.mm, es.ss); cctz::time_point end_tp; const char* tzstr_end = es.tzstr.size() ? es.tzstr.c_str() : tzstr; cvt_res = RcppCCTZ::convertToTimePoint(end_cvt, tzstr_end, end_tp); if (cvt_res < 0) { Rcpp::stop("Cannot retrieve timezone '%s'.", tzstr_end); } auto end = dtime{std::chrono::nanoseconds((end_tp.time_since_epoch().count() - es.offset) * 1000000000ll + es.ns)}; Rcomplex res; const interval ival { start, end, sopen, eopen }; memcpy(&res, &ival, sizeof(ival)); return res; } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_make_impl(const Rcpp::CharacterVector nt_v, const Rcpp::CharacterVector tz_v) { // handle the special case where one of the operands has 0-length: if (nt_v.size() == 0 || tz_v.size() == 0) { Rcpp::ComplexVector res(0); return assignS4("nanoival", res); } checkVectorsLengths(nt_v, tz_v); ConstPseudoVectorChar nt(nt_v); ConstPseudoVectorChar tz(tz_v); Rcpp::ComplexVector res(nt.size()); for (R_xlen_t i=0; i res_c; // by declaring it here we can make subset logical agnostic to 'Rcomplex' subset_numeric(v, idx, res, res_c, getNA_ival); return assignS4("nanoival", res); } // [[Rcpp::export]] Rcpp::ComplexVector nanoival_subset_logical_impl(const Rcpp::ComplexVector& v, const Rcpp::LogicalVector& idx_p) { const ConstPseudoVectorLgl idx(idx_p); Rcpp::ComplexVector res(0); std::vector res_c; subset_logical(v, idx, res, res_c, getNA_ival); return assignS4("nanoival", res); } nanotime/src/Makevars.win0000644000176200001440000000022714634012774015154 0ustar liggesusers## Compile as C++17 CXX_STD = CXX17 ## We need headers from our package, the directory is not automatically included PKG_CXXFLAGS = -I../inst/include nanotime/src/strnlen.cpp0000644000176200001440000000034113713656775015066 0ustar liggesusers // SunOS has no strnlen #include namespace nanotime { size_t strnlen_(const char *s, size_t maxlen) { size_t len; for (len = 0; len < maxlen; len++, s++) { if (!*s) break; } return (len); } } nanotime/src/nanotime.cpp0000644000176200001440000001447613723317114015207 0ustar liggesusers#include #include #include #include #include "nanotime/globals.hpp" #include "nanotime/utilities.hpp" #include "nanotime/pseudovector.hpp" using namespace nanotime; typedef ConstPseudoVector ConstPseudoVectorInt64; typedef ConstPseudoVector ConstPseudoVectorChar; typedef ConstPseudoVector ConstPseudoVectorLgl; static inline duration getOffsetCnv(const dtime& dt, const std::string& z) { int offset; int res = RcppCCTZ::getOffset(std::chrono::duration_cast(dt.time_since_epoch()).count(), z.c_str(), offset); if (res < 0) { Rcpp::stop("Cannot retrieve timezone '%s'.", z.c_str()); } return duration(offset).count() * std::chrono::seconds(1); } // [[Rcpp::export]] Rcpp::IntegerVector nanotime_wday_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(tm_v, tz_v); Rcpp::IntegerVector res(getVectorLengths(tm_v, tz_v)); if (res.size()) { ConstPseudoVectorInt64 tm(tm_v); ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(tz[i]); const auto tm_i = *reinterpret_cast(&tm[i]); const auto offset = getOffsetCnv(tm_i, tz_i.c_str()); date::sys_days t_days = date::floor(tm_i + offset); res[i] = unsigned(date::weekday(t_days).c_encoding()); } copyNames(tm_v, tz_v, res); } return res; } // [[Rcpp::export]] Rcpp::IntegerVector nanotime_mday_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(tm_v, tz_v); Rcpp::IntegerVector res(getVectorLengths(tm_v, tz_v)); if (res.size()) { ConstPseudoVectorInt64 tm(tm_v); ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(tz[i]); const auto tm_i = *reinterpret_cast(&tm[i]); const auto offset = getOffsetCnv(tm_i, tz_i.c_str()); date::sys_days t_days = date::floor(tm_i + offset); date::weekday wd(t_days); res[i] = unsigned(date::year_month_day(t_days).day()); } copyNames(tm_v, tz_v, res); } return res; } // [[Rcpp::export]] Rcpp::IntegerVector nanotime_month_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(tm_v, tz_v); Rcpp::IntegerVector res(getVectorLengths(tm_v, tz_v)); if (res.size()) { ConstPseudoVectorInt64 tm(tm_v); ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(tz[i]); const auto tm_i = *reinterpret_cast(&tm[i]); const auto offset = getOffsetCnv(tm_i, tz_i.c_str()); date::sys_days t_days = date::floor(tm_i + offset); date::weekday wd(t_days); res[i] = unsigned(date::year_month_day(t_days).month()); } copyNames(tm_v, tz_v, res); } return res; } // [[Rcpp::export]] Rcpp::IntegerVector nanotime_year_impl(const Rcpp::NumericVector tm_v, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(tm_v, tz_v); Rcpp::IntegerVector res(getVectorLengths(tm_v, tz_v)); if (res.size()) { ConstPseudoVectorInt64 tm(tm_v); ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(tz[i]); const auto tm_i = *reinterpret_cast(&tm[i]); const auto offset = getOffsetCnv(tm_i, tz_i.c_str()); date::sys_days t_days = date::floor(tm_i + offset); date::weekday wd(t_days); res[i] = int(date::year_month_day(t_days).year()); } copyNames(tm_v, tz_v, res); } return res; } static std::int64_t readNanotime(const char*& sp, const char* const se, const char* tzstr) { auto tt = readDtime(sp, se); // check we read until the end if (sp != se) Rcpp::stop("Error parsing"); if (tt.tzstr.size() && strnlen_(tzstr, MAX_TZ_STR_LENGTH)) Rcpp::stop("timezone is specified twice: in the string and as an argument"); const cctz::civil_second cvt(tt.y, tt.m, tt.d, tt.hh, tt.mm, tt.ss); const auto final_tzstr = tt.tzstr.size() ? tt.tzstr.c_str() : tzstr; if (final_tzstr[0] == 0) Rcpp::stop("Error parsing"); cctz::time_point tp; int res = RcppCCTZ::convertToTimePoint(cvt, final_tzstr, tp); if (res < 0) { Rcpp::stop("Cannot retrieve timezone '%s'.", final_tzstr); } return (tp.time_since_epoch().count() - tt.offset) * 1000000000ll + tt.ns; } // [[Rcpp::export]] Rcpp::NumericVector nanotime_make_impl(const Rcpp::CharacterVector nt_v, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(nt_v, tz_v); Rcpp::NumericVector res(getVectorLengths(nt_v, tz_v)); if (res.size()) { ConstPseudoVectorChar nt(nt_v); ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(&t); res[i] = *ptr; } copyNames(nt_v, tz_v, res); } return assignS4("nanotime", res, "integer64"); } static double getNA_nanotime() { const int64_t i64 = std::numeric_limits::min(); double res; memcpy(&res, &i64, sizeof(res)); return res; } // [[Rcpp::export]] Rcpp::NumericVector nanotime_subset_numeric_impl(const Rcpp::NumericVector& v, const Rcpp::NumericVector& idx) { Rcpp::NumericVector res(0); std::vector res_c; // by declaring it here we can make subset logical agnostic to double subset_numeric(v, idx, res, res_c, getNA_nanotime); return assignS4("nanotime", res, "integer64"); } // [[Rcpp::export]] Rcpp::NumericVector nanotime_subset_logical_impl(const Rcpp::NumericVector& v, const Rcpp::LogicalVector& idx_p) { const ConstPseudoVectorLgl idx(idx_p); Rcpp::NumericVector res(0); std::vector res_c; // by declaring it here we can make subset logical agnostic to double subset_logical(v, idx, res, res_c, getNA_nanotime); return assignS4("nanotime", res, "integer64"); } nanotime/src/Makevars0000644000176200001440000000022714634012774014360 0ustar liggesusers## Compile as C++17 CXX_STD = CXX17 ## We need headers from our package, the directory is not automatically included PKG_CXXFLAGS = -I../inst/include nanotime/src/period.cpp0000644000176200001440000006535314710675014014662 0ustar liggesusers#include #include #include #include "date.h" #include #include "nanotime/period.hpp" #include "nanotime/duration.hpp" #include "nanotime/pseudovector.hpp" #include "nanotime/utilities.hpp" // From R>=4.3.0 the typedef of Rcomplex changed. Some modern strict // compilers (e.g. 2024 clang -Wmissing-braces) get tripped up by // 'Rcomplex{re, im}' vs. 'Rcomplex{{re, im}}', the latter being technically // more correct for the new typedef, though for many compilers this will // "just work". See #134 and the comments in R_Ext/Complex.h. inline Rcomplex makeComplex(double re, double im) { Rcomplex ret; ret.r = re; ret.i = im; return ret; } using namespace nanotime; // for debug reasons... // cf https://stackoverflow.com/a/16692519 template std::ostream &operator<<(std::ostream &stream, const std::chrono::time_point &time_point) { // updated with https://stackoverflow.com/a/71442312/23224962 and using C++17 return stream << std::chrono::duration_cast(time_point.time_since_epoch()).count(); } period::period(const std::string& str) { const char* s = str.c_str(); const char* e = s + str.size(); months = 0; days = 0; dur = std::chrono::seconds(0); int n; if (s < e && (*s == '/' || (*s != '-' && s+2 < e && s[2] == ':'))) goto getduration; // test the case where we have only a negative duration: if (s < e && *s == '-' && ((s+3 < e && s[3] == ':') || (s+2 < e && s[2] == ':'))) { --s; // because getduration will increment it goto getduration; } if (!readNumber(s, e, n, true) || s == e) throw std::range_error("cannot parse nanoperiod"); if (*s == 'y') { months += 12*n; ++s; if (s < e) { if (*s == '/') goto getduration; if (!readNumber(s, e, n, true) || s == e) throw std::range_error("cannot parse nanoperiod"); } else { return; } } if (*s == 'm') { months += n; ++s; if (s < e) { if (*s == '/') goto getduration; if (!readNumber(s, e, n, true) || s == e) throw std::range_error("cannot parse nanoperiod"); } else { return; } } if (*s == 'w') { days += 7*n; ++s; if (s < e) { if (*s == '/') goto getduration; if (!readNumber(s, e, n, true) || s == e) throw std::range_error("cannot parse nanoperiod"); } else { return; } } if (*s == 'd') { days += n; ++s; if (s < e) { if (*s == '/') goto getduration; if (!readNumber(s, e, n, true) || s == e) throw std::range_error("cannot parse nanoperiod"); } else { return; } } // we've succeeded a readNumber, so this means we've // actually read into the duration; so backtrack and use the already // existing function to parse a duration: getduration: // # nocov try { dur = from_string(++s); } catch (...) { throw std::range_error("cannot parse nanoperiod"); } } std::string nanotime::to_string(const period& p) { std::stringstream ss; ss << p.getMonths() << "m" << p.getDays() << "d/" << to_string(p.getDuration()); return ss.str(); } template period nanotime::operator*(const period& p, T d) { return period(p.getMonths()*d, p.getDays()*d, duration(static_cast(d*p.getDuration().count())* duration(1))); } template period nanotime::operator/(const period& p, T d) { if (d == 0) { throw std::logic_error("divide by zero"); } return period(p.getMonths()/d, p.getDays()/d, duration(static_cast(p.getDuration().count()/d)* duration(1))); } // bool operator>(const period& p1, const period& p2) { // // this is actually a difficult proposition, so for this calculation // // we take into account the average lengths. This means that in // // certain specific applications p1 might be <= to p2. But at any // // rate this should work for all practical purposes: // const auto YEAR = 365.25 * 24h; // const auto MONTH = YEAR/12; // return p1.getMonths()*MONTH + p1.getDays()*24h < p2.getMonths()*MONTH + p2.getDays()*24h; // } bool nanotime::operator==(const period& p1, const period& p2) { return p1.getMonths() == p2.getMonths() && p1.getDays() == p2.getDays() && p1.getDuration() == p2.getDuration(); } bool nanotime::operator!=(const period& p1, const period& p2) { return !(p1 == p2); } struct double2 { double d1; double d2; }; union period_union { struct period_alias { int32_t i1; int32_t i2; int64_t i3; } prd; double2 dbl2; }; // const int PRDSZ = sizeof(period_union)/sizeof(double); // const int INT64SZ = 1; // const int NANOSZ = 1; // const int REALSZ = 1; // see Rcpp/inst/include/Rcpp/vector/instantiation.h where NumericVector and al. are defined typedef ConstPseudoVector ConstPseudoVectorInt64; typedef ConstPseudoVector ConstPseudoVectorNano; typedef ConstPseudoVector ConstPseudoVectorPrd; typedef ConstPseudoVector ConstPseudoVectorDbl; typedef ConstPseudoVector ConstPseudoVectorIval; typedef ConstPseudoVector ConstPseudoVectorChar; typedef ConstPseudoVector ConstPseudoVectorInt; typedef ConstPseudoVector ConstPseudoVectorBool; typedef PseudoVector PseudoVectorInt64; typedef PseudoVector PseudoVectorNano; typedef PseudoVector PseudoVectorPrd; // [[Rcpp::export]] Rcpp::ComplexVector period_from_string_impl(Rcpp::CharacterVector str) { Rcpp::ComplexVector res(str.size()); for (R_xlen_t i=0; i(str[i])); period_union pu = { { prd.getMonths(), prd.getDays(), prd.getDuration().count() } }; res[i] = makeComplex(pu.dbl2.d1, pu.dbl2.d2 ); } if (str.hasAttribute("names")) { res.names() = str.names(); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector period_from_parts_impl(Rcpp::IntegerVector months_v, Rcpp::IntegerVector days_v, Rcpp::NumericVector dur_v) { checkVectorsLengths(months_v, days_v, dur_v); Rcpp::ComplexVector res(getVectorLengths(months_v, days_v, dur_v)); if (res.size()) { const ConstPseudoVectorInt months(months_v); const ConstPseudoVectorInt days(days_v); const ConstPseudoVectorDbl dur(dur_v); for (R_xlen_t i=0; i(&dur[i]); period_union pu = { { months[i], days[i], dur_i } }; res[i] = makeComplex(pu.dbl2.d1, pu.dbl2.d2 ); } } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::CharacterVector period_to_string_impl(Rcpp::ComplexVector prd) { Rcpp::CharacterVector res(prd.size()); for (R_xlen_t i=0; i(&prd[i]), sizeof(period)); if (pu.isNA()) { res[i] = NA_STRING; } else { res[i] = to_string(*reinterpret_cast(&pu)); } } if (prd.hasAttribute("names")) { Rcpp::CharacterVector prdnm(prd.names()); Rcpp::CharacterVector nm(prdnm.size()); for (R_xlen_t i=0; i dbl; // [[Rcpp::export]] Rcpp::ComplexVector period_from_integer64_impl(Rcpp::NumericVector i64) { Rcpp::ComplexVector res(i64.size()); for (R_xlen_t i=0; i(&i64[i]); if (elt == NA_INTEGER64) { period_union pu = { { NA_INTEGER, NA_INTEGER, NA_INTEGER64 } }; res[i] = makeComplex(pu.dbl2.d1, pu.dbl2.d2 ); } else { period_union pu = { { 0, 0, elt } }; res[i] = makeComplex(pu.dbl2.d1, pu.dbl2.d2 ); } } if (i64.hasAttribute("names")) { res.names() = i64.names(); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector period_from_integer_impl(Rcpp::IntegerVector iint) { Rcpp::ComplexVector res(iint.size()); for (R_xlen_t i=0; i(iint[i]) } }; res[i] = makeComplex(pu.dbl2.d1, pu.dbl2.d2 ); } } if (iint.hasAttribute("names")) { res.names() = iint.names(); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector period_from_double_impl(Rcpp::NumericVector dbl) { Rcpp::ComplexVector res(dbl.size()); for (R_xlen_t i=0; i(dbl[i]) } }; res[i] = makeComplex(pu.dbl2.d1, pu.dbl2.d2 ); } } if (dbl.hasAttribute("names")) { res.names() = dbl.names(); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector plus_period_period_impl(const Rcpp::ComplexVector e1_nv, const Rcpp::ComplexVector e2_nv) { checkVectorsLengths(e1_nv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_nv, e2_nv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_nv); const ConstPseudoVectorPrd e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); period pu2; memcpy(&pu2, reinterpret_cast(&e2_n[i]), sizeof(period)); auto prd = pu1 + pu2; memcpy(&res[i], &prd, sizeof(prd)); } copyNames(e1_nv, e2_nv, res); } return assignS4("nanoperiod", res); } // unary '-' // [[Rcpp::export]] Rcpp::ComplexVector minus_period_impl(const Rcpp::ComplexVector e1_cv) { const ConstPseudoVectorPrd e1_n(e1_cv); Rcpp::ComplexVector res(e1_cv.size()); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); auto prd = -pu1; memcpy(&res[i], reinterpret_cast(&prd), sizeof(prd)); } copyNames(e1_cv, e1_cv, res); return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector minus_period_period_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv) { checkVectorsLengths(e1_cv, e2_cv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_cv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorPrd e2_n(e2_cv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); period pu2; memcpy(&pu2, reinterpret_cast(&e2_n[i]), sizeof(period)); auto prd = pu1 - pu2; memcpy(&res[i], reinterpret_cast(&prd), sizeof(prd)); } copyNames(e1_cv, e2_cv, res); } return assignS4("nanoperiod", res); } template Rcpp::LogicalVector compare_period_period(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv, const OP& op) { checkVectorsLengths(e1_cv, e2_cv); Rcpp::LogicalVector res(getVectorLengths(e1_cv, e2_cv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorPrd e2_n(e2_cv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); period pu2; memcpy(&pu2, reinterpret_cast(&e2_n[i]), sizeof(period)); res[i] = op(pu1, pu2); } copyNames(e1_cv, e2_cv, res); } return res; } // [[Rcpp::export]] Rcpp::LogicalVector eq_period_period_impl(const Rcpp::ComplexVector e1_p, const Rcpp::ComplexVector e2_p) { return compare_period_period(e1_p, e2_p, std::equal_to()); } // [[Rcpp::export]] Rcpp::LogicalVector ne_period_period_impl(const Rcpp::ComplexVector e1_p, const Rcpp::ComplexVector e2_p) { return compare_period_period(e1_p, e2_p, std::not_equal_to()); } // [[Rcpp::export]] Rcpp::ComplexVector plus_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv) { checkVectorsLengths(e1_cv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_nv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorInt64 e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); duration dur; memcpy(&dur, reinterpret_cast(&e2_n[i]), sizeof(dur)); pu1 = plus(pu1, dur); memcpy(&res[i], &pu1, sizeof(pu1)); } copyNames(e1_cv, e2_nv, res); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector minus_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv) { checkVectorsLengths(e1_cv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_nv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorInt64 e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); duration dur; memcpy(&dur, reinterpret_cast(&e2_n[i]), sizeof(dur)); pu1 = minus(pu1, dur); memcpy(&res[i], &pu1, sizeof(pu1)); } copyNames(e1_cv, e2_nv, res); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector multiplies_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv) { checkVectorsLengths(e1_cv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_nv)); const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorInt64 e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); uint64_t m; memcpy(&m, reinterpret_cast(&e2_n[i]), sizeof(m)); pu1 = pu1 * m; memcpy(&res[i], &pu1, sizeof(pu1)); } copyNames(e1_cv, e2_nv, res); return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector divides_period_integer64_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv) { checkVectorsLengths(e1_cv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_nv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorInt64 e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); uint64_t m; memcpy(&m, reinterpret_cast(&e2_n[i]), sizeof(m)); pu1 = pu1 / m; memcpy(&res[i], &pu1, sizeof(pu1)); } copyNames(e1_cv, e2_nv, res); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector multiplies_period_double_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv) { checkVectorsLengths(e1_cv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_nv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorDbl e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); double m; memcpy(&m, reinterpret_cast(&e2_n[i]), sizeof(m)); pu1 = pu1 * m; memcpy(&res[i], &pu1, sizeof(pu1)); } copyNames(e1_cv, e2_nv, res); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector divides_period_double_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::NumericVector e2_nv) { checkVectorsLengths(e1_cv, e2_nv); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_nv)); if (res.size()) { const ConstPseudoVectorPrd e1_n(e1_cv); const ConstPseudoVectorDbl e2_n(e2_nv); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(period)); double m; memcpy(&m, reinterpret_cast(&e2_n[i]), sizeof(m)); pu1 = pu1 / m; memcpy(&res[i], &pu1, sizeof(pu1)); } copyNames(e1_cv, e2_nv, res); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector minus_integer64_period_impl(const Rcpp::NumericVector e1_nv, const Rcpp::ComplexVector e2_cv) { checkVectorsLengths(e1_nv, e2_cv); Rcpp::ComplexVector res(getVectorLengths(e1_nv, e2_cv)); if (res.size()) { const ConstPseudoVectorInt64 e1_n(e1_nv); const ConstPseudoVectorPrd e2_n(e2_cv); for (R_xlen_t i=0; i(&e2_n[i]), sizeof(pu2)); duration dur; memcpy(&dur, reinterpret_cast(&e1_n[i]), sizeof(dur)); pu2 = minus(dur, pu2); memcpy(&res[i], &pu2, sizeof(pu2)); } copyNames(e1_nv, e2_cv, res); } return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::NumericVector plus_nanotime_period_impl(const Rcpp::NumericVector e1_nv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(e1_nv, e2_cv, tz_v); Rcpp::ComplexVector res(getVectorLengths(e1_nv, e2_cv, tz_v)); if (res.size()) { const ConstPseudoVectorNano e1_n(e1_nv); const ConstPseudoVectorPrd e2_n(e2_cv); const ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(nano)); period prd; memcpy(&prd, reinterpret_cast(&e2_n[i]), sizeof(prd)); auto dt = plus(nano, prd, Rcpp::as(tz[i])); memcpy(&res[i], &dt, sizeof(dt)); } copyNames(e1_nv, e2_cv, res); } return assignS4("nanotime", res, "integer64"); } // [[Rcpp::export]] Rcpp::NumericVector minus_nanotime_period_impl(const Rcpp::NumericVector e1_nv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(e1_nv, e2_cv, tz_v); Rcpp::ComplexVector res(getVectorLengths(e1_nv, e2_cv, tz_v)); if (res.size()) { const ConstPseudoVectorNano e1_n(e1_nv); const ConstPseudoVectorPrd e2_n(e2_cv); const ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(nano)); period prd; memcpy(&prd, reinterpret_cast(&e2_n[i]), sizeof(prd)); auto dt = minus(nano, prd, Rcpp::as(tz[i % tz.size()])); memcpy(&res[i], &dt, sizeof(dt)); } copyNames(e1_nv, e2_cv, res); } return assignS4("nanotime", res, "integer64"); } // [[Rcpp::export]] Rcpp::ComplexVector plus_nanoival_period_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(e1_cv, e2_cv, tz_v); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_cv, tz_v)); if (res.size()) { const ConstPseudoVectorIval e1_n (e1_cv); const ConstPseudoVectorPrd e2_n (e2_cv); const ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(ival)); period prd; memcpy(&prd, reinterpret_cast(&e2_n[i]), sizeof(prd)); auto res_ival = plus(ival, prd, Rcpp::as(tz[i % tz.size()])); memcpy(&res[i], &res_ival, sizeof(res_ival)); } copyNames(e1_cv, e2_cv, res); } return assignS4("nanoival", res); } // [[Rcpp::export]] Rcpp::ComplexVector minus_nanoival_period_impl(const Rcpp::ComplexVector e1_cv, const Rcpp::ComplexVector e2_cv, const Rcpp::CharacterVector tz_v) { checkVectorsLengths(e1_cv, e2_cv, tz_v); Rcpp::ComplexVector res(getVectorLengths(e1_cv, e2_cv, tz_v)); if (res.size()) { const ConstPseudoVectorIval e1_n (e1_cv); const ConstPseudoVectorPrd e2_n (e2_cv); const ConstPseudoVectorChar tz(tz_v); for (R_xlen_t i=0; i(&e1_n[i]), sizeof(ival)); period prd; memcpy(&prd, reinterpret_cast(&e2_n[i]), sizeof(prd)); auto res_ival = minus(ival, prd, Rcpp::as(tz[i % tz.size()])); memcpy(&res[i], &res_ival, sizeof(res_ival)); } copyNames(e1_cv, e2_cv, res); } return assignS4("nanoival", res); } // [[Rcpp::export]] Rcpp::NumericVector period_month_impl(const Rcpp::ComplexVector e_n) { Rcpp::NumericVector res(e_n.size()); for (R_xlen_t i=0; i(&e_n[i]), sizeof(period)); if (prd.isNA()) { res[i] = NA_REAL; } else { res[i] = prd.getMonths(); } } if (e_n.hasAttribute("names")) { res.names() = e_n.names(); } return res; } // [[Rcpp::export]] Rcpp::NumericVector period_day_impl(const Rcpp::ComplexVector e_n) { Rcpp::NumericVector res(e_n.size()); for (R_xlen_t i=0; i(&e_n[i]), sizeof(period)); if (prd.isNA()) { res[i] = NA_REAL; } else { res[i] = prd.getDays(); } } if (e_n.hasAttribute("names")) { res.names() = e_n.names(); } return res; } // [[Rcpp::export]] Rcpp::S4 period_duration_impl(const Rcpp::ComplexVector e_n) { Rcpp::NumericVector res(e_n.size()); for (R_xlen_t i=0; i(&e_n[i]), sizeof(period)); if (prd.isNA()) { auto dur = duration::min(); memcpy(&res[i], &dur, sizeof(dur)); } else { auto dur = prd.getDuration(); memcpy(&res[i], &dur, sizeof(dur)); } } if (e_n.hasAttribute("names")) { res.names() = e_n.names(); } return assignS4("nanoduration", res, "integer64"); } // [[Rcpp::export]] Rcpp::LogicalVector period_isna_impl(const Rcpp::ComplexVector cv) { Rcpp::LogicalVector res(cv.size()); for (R_xlen_t i=0; i(&c), sizeof(c)); res[i] = prd.isNA(); } res.names() = cv.names(); return res; } constexpr duration abs(duration d) { return d >= d.zero() ? d : -d; } // This gives back a `nanotime` sequence for a `by` that is a `period`: // [[Rcpp::export]] Rcpp::NumericVector period_seq_from_to_impl(const Rcpp::NumericVector from_nv, const Rcpp::NumericVector to_nv, const Rcpp::ComplexVector by_cv, const std::string tz) { const ConstPseudoVectorNano from_n(from_nv); const ConstPseudoVectorNano to_n(to_nv); const ConstPseudoVectorPrd by_n(by_cv); dtime from; memcpy(&from, reinterpret_cast(&from_n[0]), sizeof(from)); dtime to; memcpy(&to, reinterpret_cast(&to_n[0]), sizeof(to)); period by; memcpy(&by, reinterpret_cast(&by_n[0]), sizeof(by)); std::vector res{from}; auto diff = to - from; auto pos = diff >= std::chrono::seconds(0); auto dist = abs(diff); auto olddist = dist; for (;;) { auto next = plus(res.back(), by, tz); if (pos ? next > to : next < to) break; res.push_back(next); olddist = dist; dist = abs(to - next); if (dist >= olddist) { Rcpp::stop("incorrect specification for 'to'/'by'"); // # nocov } } Rcpp::NumericVector res_rcpp(res.size()); memcpy(&res_rcpp[0], &res[0], sizeof(dtime)*res.size()); return assignS4("nanotime", res_rcpp, "integer64"); } // This gives back a `nanotime` sequence for a `by` that is a `period`: // [[Rcpp::export]] Rcpp::NumericVector period_seq_from_length_impl(const Rcpp::NumericVector from_nv, const Rcpp::ComplexVector by_cv, const Rcpp::NumericVector n_nv, const std::string tz) { const ConstPseudoVectorNano from_n(from_nv); const ConstPseudoVectorPrd by_n(by_cv); const ConstPseudoVectorNano n_n(n_nv); dtime from; memcpy(&from, reinterpret_cast(&from_n[0]), sizeof(from)); period by; memcpy(&by, reinterpret_cast(&by_n[0]), sizeof(by)); size_t n; memcpy(&n, reinterpret_cast(&n_n[0]), sizeof(n)); std::vector res{from}; for (size_t i=1; i::min(), std::numeric_limits::min(), duration::zero()); Rcomplex c; memcpy(&c, &p, sizeof(p)); return c; } // [[Rcpp::export]] Rcpp::ComplexVector period_subset_numeric_impl(const Rcpp::ComplexVector& v, const Rcpp::NumericVector& idx) { Rcpp::ComplexVector res(0); std::vector res_c; // by declaring it here we can make subset logical agnostic to 'Rcomplex' subset_numeric(v, idx, res, res_c, getNA_complex); return assignS4("nanoperiod", res); } // [[Rcpp::export]] Rcpp::ComplexVector period_subset_logical_impl(const Rcpp::ComplexVector& v, const Rcpp::LogicalVector& idx_p) { const ConstPseudoVectorBool idx(idx_p); Rcpp::ComplexVector res(0); std::vector res_c; // by declaring it here we can make subset logical agnostic to 'Rcomplex' subset_logical(v, idx, res, res_c, getNA_complex); return assignS4("nanoperiod", res); } nanotime/ChangeLog0000644000176200001440000007546614740323573013670 0ustar liggesusers2025-01-10 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.11 2025-01-07 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Roll micro version and date * R/nanotime.R (format.nanotime): Index and override NA values prior to CCTZ call, flag after call avoiding a UBSAN warning in client code 2024-10-31 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date 2024-10-30 Michael Chirico * src/period.cpp: Create `Rcomplex` objects in a more robust way that appeases `Wmissing-braces` compiler warnings on `clang`. 2024-09-16 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.10 2024-09-15 Dirk Eddelbuettel * demo/ggplot2Example.R: Removed to local/ * demo/00Index: Removed entry for gpplot2Example 2024-09-09 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date * R/nanoival.R (setdiff): Under R 4.5.0, call setdiff for integer64 * R/nanotime.R (setMethod): Under R 4.5.0, define unique method * NAMESPACE: Conditionally export unique * man/nanotime.Rd: Alias unique 2024-08-31 Dirk Eddelbuettel * DESCRIPTION (Authors@R): Added 2024-06-22 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date * inst/tinytest/test_nanotime.R: Retire test for Solaris * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_zoo.R: Idem 2024-06-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.9 2024-06-20 Dirk Eddelbuettel * inst/tinytest/test_nanotime.R: Condition two tests to not run on arm64 * .github/workflows/ci.yaml (jobs): Add macOS-latest back to matrix 2024-06-19 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.8 * README.md: Use tinyverse.netlify.app for dependency badge 2024-06-18 Dirk Eddelbuettel * R/nanotime.R: Simplify one reference to RcppCCTZ * man/nanotime.Rd: Idem * inst/tinytest/test_nanoival.R: Condition some tests on being in an 'extended' run 2024-06-16 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date * inst/include/nanotime/interval.hpp: Add extra braces * src/interval.cpp: Updated output stream helper * src/period.cpp: Idem * src/Makevars (CXX_STD): Set C++17 * src/Makevars.win (CXX_STD): Idem * src/Makevars.ucrt: Removed 2024-06-14 Leonardo Silvestri * src/Makevars.win: Remove -mno-ms-bitfields 2024-06-13 Leonardo Silvestri * inst/include/nanotime/interval.hpp: NA behavior for bitfield 2024-06-11 Leonardo Silvestri * inst/include/nanotime/interval.hpp: Initial fix for bitfield * inst/include/nanotime/period.hppL Idem * src/interval.cpp: Idem 2024-06-09 Dirk Eddelbuettel * README.md: Use tinyverse.netlify.app for dependency badge 2024-05-24 Leonardo Silvestri * R/nanoduration.R: duration divided by duration returns double * inst/tinytest/test_nanoduration.R: additional test for the above * inst/include/nanotime/utilities.hpp: Use interface function Rf_asS4 instead of internal SET_S4_OBJECT * src/interval.cpp: Change setting of S4 bit before names assigment 2024-04-28 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date * R/nanoperiod.R: Add missing backslash in code call * man/nanoperiod.Rd: Idem 2024-02-16 Dirk Eddelbuettel * .github/workflows/ci.yaml (jobs): Update to actions/checkout@v4, add r-ci-setup actions 2023-09-26 Leonardo Silvestri * R/nanotime.R: Further refinement for default UTC timezone * inst/tinytest/test_nanotime.R: Idem 2023-09-22 Dirk Eddelbuettel * R/nanotime.R: Provide default UTC timezone in 'as.Date()' * tests/simpleTests.R: Adjist a test accordingly * inst/tinytest/test_nanotime.R: Idem 2023-09-21 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * R/nanotime.R: Fixed 'as.Date' to force use of timezone and to allow the timezone argument to be a vector 2023-07-11 Dirk Eddelbuettel * README.md: Add r-universe badge 2023-07-06 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * R/nanotime.R: added parameter 'accurate' to functions 'nanotime' and 'as.nanotime' when the argument is a 'POSIXct'. * inst/tinytest/test_nanotime.R: added tests for 'accurate' parameter. * man/nanotime.Rd: added documentation for 'accurate' parameter. 2023-03-12 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * src/Makevars: No longer set compilation standard * src/Makevars.win: Idem * src/Makevars.ucrt: Idem 2022-12-06 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * R/nanotime.R: Add example for additional format plus reference to \pkg{RcppCCTZ} documentation which has format details * man/nanotime.Rd: Idem 2022-11-08 Dirk Eddelbuettel * .github/workflows/ci.yaml (jobs): Update to actions/checkout@v3 2022-10-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.7 2022-10-16 Trevor L Davis * R/nanoduration.R: Add '+' / '-' methods for 'difftime()' and 'nanoduration()' / 'nanoival()' / 'nanotime()' objects * man/nanoduration.Rd: Updated * inst/tinytest/test_nanoduration.R: Add tests 2022-10-14 Trevor L Davis * R/nanoduration.R (as.nanoduration.difftime): Added * man/nanoduration.Rd: Updated * inst/tinytest/test_nanoduration.R: Add tests 2022-10-13 Trevor L Davis * R/nanoduration.R (nanoduration): Add default arguments equal to zero * R/nanotime.R: Use 'inherits()' instead of 'class() ==' 2022-10-04 Dirk Eddelbuettel * docs/mkdmt-src/: Updated for mkdocs-for-material 8.5.5 2022-03-06 Leonardo Silvestri * DESCRIPTION (Version, Date): Release 0.3.6 * R/nanoival.R: Fix incorrect subsetting with operator `%in%` * NAMESPACE: Added export * man/set_operations.Rd: Added file * src/period.cpp: Fix parse of negative period 2022-03-06 Dirk Eddelbuettel * R/nanoduration.R: Use 'inherits()' instead of 'class() ==' * R/nanoival.R: Idem * R/nanoperiod.R: Idem * R/nanotime.R: Idem 2021-12-14 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.5 2021-12-09 Dirk Eddelbuettel * src/Makevars.ucrt: Based on patch by Tomas Kalibera that is part of his changes for the Windows utf8-enhabced ucrt3 builds of R 4.2.0 2021-11-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.4 2021-11-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2021-11-21 Leonardo Silvestri * inst/include/nanotime/period.hpp: Regroup and expose nanoperiod interface for use by other packages * src/period.cpp: Moved code to period.hpp header * src/rounding.cpp: Idem 2021-11-17 Dirk Eddelbuettel * README.md: Remove Travis badge * .travis.yml: Remove Travis YAML config 2021-10-11 Dirk Eddelbuettel * R/nanoduration.R (all.equal.nanoduration): Remove as.character.nanotime as proper S4 method already defined * R/nanoperiod.R (all.equal.nanoperiod): Idem * NAMESPACE: Removed exports * man/nanoduration.Rd: Updated * man/nanoperiod.Rd: Idem * .codecov.yml (coverage): Ensure PRs will not get a red 'fail' just because coverage metrices dropped a miniscule amount 2021-10-10 Dirk Eddelbuettel * R/nanoival.R (as.character.nanoival): Added * NAMESPACE: Idem * man/nanoival.Rd: Aliases * R/nanoperiod.R (as.character.nanoperiod): Added * NAMESPACE: Idem * man/nanoperiod.Rd: Aliases * R/nanoduration.R (as.character.nanoduration): * NAMESPACE: Idem * man/nanoduration.Rd: Aliases * inst/tinytest/test_nanotime.R: Add tests * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_nanoperiod.R: Idem 2021-10-08 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * R/nanotime.R (as.character.nanotime): Added * NAMESPACE: Idem * man/nanotime.Rd: Aliases 2021-08-09 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.3 2021-08-08 Leonardo Silvestri * src/period.cpp: Fix for `plus` and `minus` adjustment * R/nanoperiod.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * man/nanoperiod.Rd: Idem 2021-04-06 Dirk Eddelbuettel * DESCRIPTION (URL, BugRreports): Added to DESCRIPTION file 2021-03-28 Dirk Eddelbuettel * docs/mkdmt-src/: Moved mkdocs-material input 2020-12-30 Dirk Eddelbuettel * .github/workflows/ci.yaml: Rename job from build to ci 2020-12-25 Dirk Eddelbuettel * .github/workflows/ci.yaml: Small tweaks to CI YAML file 2020-12-13 Dirk Eddelbuettel * README.md: Add CI badge 2020-12-06 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * .travis.yml: Switch to run.sh from r-ci for focal and bspm * .github/workflows/ci.yaml: Use run.sh from r-ci 2020-12-06 Colin Umansky * inst/tinytest/test_nanoduration.R: Added tests for comparison 2020-12-05 Colin Umansky * R/nanoduration.R: Support nanoduration to character comparison * man/nanoduration.Rd: Document new feature * inst/tinytest/test_nanoduration.R: Updated tests 2020-10-25 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * docker/r-devel/Dockerfile: Added for simpler r-devel checks 2020-10-24 Dirk Eddelbuettel * inst/tinytest/test_nanotime.R: Add explicit check.tzone=FALSE to equality test for POSIXct comparison * inst/tinytest/test_nanoival.R: Renable full tests, add bit64 * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanotime.R: Idem * inst/tinytest/test_ops.R: Idem 2020-09-11 Dirk Eddelbuettel * docs/: Added package website * README.md: Added badge and short paragraph linking to documentation 2020-09-07 Leonardo Silvestri * demo/ggplot2Example.R: Updated and extended demo 2020-09-04 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * demo/ggplot2Example.R: New demo based on Leonardo's example repo 2020-09-03 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.2 2020-09-01 Elliott Sales de Andrade * inst/include/nanotime/interval.hpp: Correct for big-endian 2020-08-31 Dirk Eddelbuettel * .travis.yml (install): Back to RcppCCTZ from CRAN 2020-08-30 Dirk Eddelbuettel * R/nanoival.R: De-activate two examples * R/nanotime.R: Idem * man/nanoival.Rd: Idem * man/nanotime.Rd: Idem * inst/tinytest/test_nanoduration.R: Make some test conditional * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanotime.R: Idem * inst/tinytest/test_ops.R: Idem 2020-08-28 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * src/interval.cpp: Use RcppCCTZ_API header and exported functions * src/nanotime.cpp: Idem * src/period.cpp: Idem * src/rounding.cpp: Idem * .travis.yml (install): Install RcppCCTZ from GitHub 2020-08-09 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.3.1 * R/nanoival.R: Add \dontrun{} because of Solaris * R/nanoperiod.R: Idem * R/nanotime.R: Idem * man/nano_year.Rd: Idem * man/nanoperiod.Rd: Idem * man/nanotime.Rd: Idem * man/rounding.Rd: Idem * man/seq-nanoival-method.Rd: Idem * man/seq.nanotime.Rd: Idem * inst/tinytest/test_nanoival.R: Skip some tests on Solaris * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanotime.R: Idem 2020-08-08 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version, small edit * src/interval.cpp: Add some tests for non-zero length vectors * inst/tinytest/test_nanotime.R: Skip one test upsetting SAN * tests/tinytest.R: Default back to serial tests * src/strnlen.cpp: Added strnlen_ to help Solaris * inst/include/nanotime/utilities.hpp: Declare it * src/interval.cpp: Use it * src/nanotime.cpp: Idem 2020-08-07 Leonardo Silvestri * src/period.cpp: Add extra braces to appease macOS compiler * src/inst/include/nanotime/globals.hpp: Use chrono duration; remove ambiguous time_point and seconds declarations 2020-08-05 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.3.0 2020-08-02 Leonardo Silvestri * src/interval.cpp: Use non-throwing RcppCCTZ function * src/nanotime.cpp: Idem * src/period.cpp: Idem * inst/include/nanotime/globals.hpp: More (u)int64_t * R/nanoival.R: Refine error message check * R/nanotime.R: Idem 2020-07-29 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2020-07-29 Leonardo Silvestri * src/Makevars.win: Add to set explicit '-mno-ms-bitfields' flag required for bitfield operations on Windows 2020-07-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * inst/NEWS.Rd: Additional entries added 2020-07-20 Leonardo Silvestri * vignettes/nanotime/rmd/nanotime-intro.Rmd: Additional edits 2020-07-19 Dirk Eddelbuettel * vignettes/nanotime/rmd/nanotime-intro.Rmd: Additional edits * vignettes/nanotime/rmd/nanotime-intro.bib: Updated bibliography 2020-07-11 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * inst/include/nanotime/duration.hpp: move headers to 'nanotime' and put 'interval' and 'period' in a namespace * directory inst/include/nanotime/globals.hpp: Idem * inst/include/nanotime/interval.hpp: Idem * inst/include/nanotime/period.hpp: Idem * inst/include/nanotime/pseudovector.hpp: Idem * inst/include/nanotime/utilities.hpp: Idem * src/duration.cpp: Idem * src/interval.cpp: Idem * src/nanotime.cpp: Idem * src/period.cpp: Idem * src/rounding.cpp: Idem * src/Makevars: Idem * inst/include/nanotime/pseudovector.hpp: let 'pseudovector' return a different type than the input which gives more flexibility 2020-05-17 Dirk Eddelbuettel * vignettes/nanotime-intro.pdf: Copy of prebuilt vignette from rmd/ * vignettes/nanotime-introduction.Rnw: Sweave shell for prebuilt vignette * .travis.yml: Switch to bionic, and testing via R 4.0.0 2020-05-16 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * R/nanoduration.R: correct NA and negative subsetting; implement 'rep' * R/nanoival.R: Idem * R/nanoperiod.R: Idem * R/nanotime.R: Idem * inst/include/globals.hpp: correct NA and negative subsetting * inst/include/interval.hpp: Idem * inst/include/utilities.hpp: Idem * inst/tinytest/test_nanoduration.R: Idem * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanotime.R: Idem * src/duration.cpp: Idem * src/interval.cpp: Idem * src/nanotime.cpp: Idem * src/period.cpp: Idem * man/rep-nanoduration-method.Rd: document 'rep' * man/rep-nanoival-method.Rd: document 'rep' * man/rep-nanoperiod-method.Rd: document 'rep' * man/rep-nanotime-method.Rd: document 'rep' 2020-05-10 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * R/nanoival.R: check param types before invoking C functions; use 'na.rm' in 'is.unsorted' * inst/tinytest/test_nanoival.R: Idem * R/nanoperiod.R: check param types before invoking C functions * R/nanotime.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * src/RcppExports.cpp: Idem * src/interval.cpp: Idem * man/nanotime.Rd: document 'tz' param behaviour in constructor 2020-04-25 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * NAMESPACE: Added rounding functions 'nano_floor' and 'nano_ceiling' * R/RcppExports.R: Idem * R/nanoduration.R: Idem * R/nanoperiod.R: Idem * R/nanotime.R: Idem * inst/include/period.hpp: Idem * inst/tinytest/test_nanoduration.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * man/rounding.Rd: Idem * src/RcppExports.cpp: Idem * src/rounding.cpp: Idem * vignettes/nanotime-introduction.Rnw: Wrapper as in anytime * vignettes/nanotime-intro.pdf: Pre-made pdf * vignettes/nanotime/rmd/nanotime-intro.Rmd: New draft vignette * vignettes/nanotime/rmd/nanotime-intro.bib: New bibliography 2020-04-09 Dirk Eddelbuettel * README.md: Add 'last commit' badge 2020-03-31 Leonardo Silvestri * DESCRIPTION (Version, Date): Roll minor version * R/nanoduration.R: Added all.equal * R/nanoival.R: Idem * R/nanoperiod.R: Idem * R/nanotime.R: Idem * inst/tinytest/test_nanoduration.R: Idem * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanotime.R: Idem * man/all.equal-nanoperiod-ANY-method.Rd: deleted * man/all.equal.nanotime.Rd: Idem * man/all.equal.nanoduration.Rd: Idem * man/all.equal.nanoival.Rd: Idem * man/all.equal.nanoperiod.Rd: Idem 2020-03-29 Leonardo Silvestri * DESCRIPTION: fixed 0-length-vector ops * R/RcppExports.R: Idem * R/nanoperiod.R: Idem * inst/include/utilities.hpp: Idem * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_nanoperiod.R: Idem * inst/tinytest/test_nanotime.R: Idem * src/RcppExports.cpp: Idem * src/interval.cpp: Idem * src/nanotime.cpp: Idem * src/period.cpp: Idem 2020-03-27 Leonardo Silvestri * DESCRIPTION: added %in%.nanotime * NAMESPACE: Idem * R/RcppExports.R: Idem * R/nanoival.R: Idem * R/nanoperiod.R: Idem * inst/tinytest/test_nanoival.R: Idem * man/nanoduration.Rd: Idem * man/nanoival.Rd: Idem * man/nanoperiod.Rd: Idem * man/nanotime.Rd: Idem * man/set_operations.Rd: Idem * src/RcppExports.cpp: Idem * src/interval.cpp: Idem 2020-03-25 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * DESCRIPTION (LinkingTo): Add RcppDate providing date.h * src/nanotime.cpp (nanotime_wday_impl): Update one accessor for newer version of date.h * inst/include/date.h: Deleted as no longer needed * .travis.yml (install): Install RcppDate * inst/include/globals.hpp: Add a single #nocov 2020-03-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2020-03-22 Leonardo Silvestri * README.md: updated information 2020-03-21 Leonardo Silvestri * inst/include/globals.hpp: parse format ending with 'Z' for data.table compatibility * src/period.cpp: fix vectorized 'plus'/'minus' ops for 'nanoperiod' * inst/tinytest/test_nanoperiod.R: Idem 2020-03-20 Dirk Eddelbuettel * src/duration.cpp: Slightly more idiomatic Rcpp * src/period.cpp: Idem * R/nanoduration.R: Idem * R/nanoperiod.R: Idem * R/nanotime.R: Idem 2020-03-19 Dirk Eddelbuettel * src/interval.cpp: Slightly more idiomatic Rcpp * R/nanoival.R: Idem 2020-03-18 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * DESCRIPTION (Imports): Updated versioned Depends: on RcppCCTZ * NAMESPACE: Turn on registration * src/nanotime.cpp: Slightly more idiomatic Rcpp * R/nanotime.R: Idem 2020-03-15 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * src/duration.cpp: Small fix to cast to plain old type * src/interval.cpp: Idem * src/nanotime.cpp: Idem * src/Makevars (PKG_CXXFLAGS): Minor edits * cleanup: Added minor helper 2020-03-14 Leonardo Silvestri [ The following reflects a fairly substantial set of changes made over a longer period and are just summarized here ] * DESCRIPTION: Add versioned Depends on RcppCCTZ * NAMESPACE: Load dynamic library * R/duration.R: Add new nanoival, duration, and period * R/nanoival.R: Idem * R/nanotime.R: Idem * R/period.R: Idem * inst/include/date.h: Idem * inst/include/duration.hpp: Idem * inst/include/globals.hpp: Idem * inst/include/interval.hpp: Idem * inst/include/period.hpp: Idem * inst/include/pseudovector.hpp: Idem * inst/include/utilities.hpp: Idem * inst/tinytest/test_data.frame.R: Idem * inst/tinytest/test_duration.R: Idem * inst/tinytest/test_nanoival.R: Idem * inst/tinytest/test_nanotime.R: Idem * inst/tinytest/test_ops.R: Idem * inst/tinytest/test_period.R: Idem * man/duration.Rd: Idem * man/nanoival.Rd: Idem * man/nanotime.Rd: Idem * man/period.Rd: Idem * src/Makevars: Idem * src/duration.cpp: Idem * src/interval.cpp: Idem * src/nanotime.cpp: Idem * src/period.cpp: Idem * .travis.yml: For now load development version of RcppCCTZ from GitHub 2019-11-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New minor version * inst/tinytest/test_*.R: Moved from ../unitTest, changed to tinytest * tests/tinytest.R: Add test runner for tinytest * DESCRIPTION (Suggests): Add tinytest, remove RUnit * .travis.yml (install): Add r-cran-tinytest, remove r-cran-runit * tests/runTests.R: Removed RUnit test runner 2019-11-20 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New minor version * R/nanotime.R (as.integer64.nanotime): Adding 'Compare' ops for character and nanotime * inst/unitTests/test_ops.R: Adjust one existing test, and add six new ones for character and nanotime comparisons * man/nanotime.Rd: Document new comparison operators 2019-05-25 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.2.4 2019-05-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * R/nanotime.R (as.integer64.nanotime): Define [[ accessor * inst/unitTests/test_nanotime.R (test_square_bracket): Add test * man/nanotime.Rd: Add alias 2019-04-03 Dirk Eddelbuettel * README.md: Add dependencies badge 2018-09-30 Dirk Eddelbuettel * DESCRIPTION (Date, Version): Release 0.2.3 2018-09-02 Dirk Eddelbuettel * .travis.yml: Switch Travis CI to R 3.5 repo 2018-08-31 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * inst/unitTests/test_nanotime.R: Skip some tests on Solaris * inst/unitTests/test_zoo.R: Idem 2018-07-18 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.2 * inst/unitTests/test_xts.R: Continue to disable xts tests even after 0.11.0 release 2018-07-01 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.1 2018-06-30 Dirk Eddelbuettel * R/nanotime.R (format.nanotime): Protect from empty argument 2018-06-23 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * R/nanotime.R: Two extras casts to integer64 in constructors 2018-04-19 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2018-04-18 Leonardo Silvestri * R/nanotime.R (Compare): Added attribute-preserving comparison * man/nanotime.Rd: Corresponding documentation 2017-06-22 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.0 2017-06-21 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * DESCRIPTION (Imports): Require RcppCCTZ (>= 0.2.3) * inst/unitTests/test_nanotime.R: No longer condition out Windows * inst/unitTests/test_nanotime.R: Ditto * inst/unitTests/test_xts.R: Ditto * .travis.yml (group): Added as required by Travis CI 2017-06-16 Dirk Eddelbuettel * R/nanotime.R (nanotime.matrix): Adding '#nocov' tags 2017-06-15 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New minor version * tests/runTests.R: Rewritten test runner * inst/unitTests/test_zoo.R (test_zoo): Condition on zoo present, and test not running under Windows * inst/unitTests/test_xts.R (.setUp): Condition on a 'future' xts version present as we really nedd xts to be nanotime aware for these tests * inst/unitTests/test_nanotime.R: Condition a number of tests on not running under Windows * DESCRIPTION (Suggests): Added 'xts' * .travis.yml (install): Ditto 2017-06-14 Leonardo Silvestri * R/nanotime.R: Error on ops not meaningful for type, also fix handling of NA, NAN, Inf, -Inf * man/nanotime.Rd: Corresponding documentation * inst/unitTests/test_nanotime.R: corresponding test 2017-06-05 Leonardo Silvestri * R/nanotime.R: Correct summary() by defining 'names<-'; fix 'c' * man/nanotime.Rd: Corresponding documentation * inst/unitTests/test_nanotime.R: corresponding test 2017-06-03 Leonardo Silvestri * R/nanotime.R: Prevent print from printing more than options()$max.print 2017-06-02 Leonardo Silvestri * R/nanotime.R: Ensure names are kept for nanotime vectors * inst/unitTests/test_nanotime.R: corresponding test 2017-05-02 Leonardo Silvestri * R/nanotime.R: Ensure 'tz=""' is treated as missing 2017-04-04 Leonardo Silvestri * R/nanotime.R: Remove spurious debug output 2017-03-29 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * man/nanotime.Rd: Minor update * nanotime.Rproj: Use devtools::document to work around a roxygen2 bug with S4 and setOldClass 2017-03-29 Leonardo Silvestri [ The following is summary of changes made over several weeks ] * DESCRIPTION: Convert to S4 class * NAMESPACE: Idem * R/nanotime.R: Idem * inst/unitTests/test_data.frame.R: Idem * inst/unitTests/test_nanotime.R: Idem * inst/unitTests/test_ops.R: Idem * inst/unitTests/test_xts.R: Idem * inst/unitTests/test_zoo.R: Idem * man/nanotime-class.Rd: Idem * man/nanotime-package.Rd: Idem * man/nanotime.Rd: Idem * tests/runTests.R: Idem * tests/simpleTests.R: Idem 2017-03-27 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.1.2 2017-02-08 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date * NAMESPACE: Also (re-)export as.integer64 * R/nanotime.R: Added roxygen2 snippet for as.integer64 * man/nanotime.Rd: Documentation 2017-02-04 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.1.1 2017-01-31 Dirk Eddelbuettel * R/nanotime.R: One more updated format string 2017-01-30 Dirk Eddelbuettel * R/nanotime.R (format.nanotime): Safer transformation to double (index2char.nanotime): Idem 2017-01-29 Dirk Eddelbuettel * R/nanotime.R: Additional documentation section on default output format string * .travis.yml (before_install): Use https for curl fetch 2017-01-25 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version and date * R/nanotime.R (nanotime.character): Display of nine dec digits (format.nanotime): Idem (print.nanotime): Dispatch to format.nanotime (thanks, Matt!) (as.integer64.nanotime): New converter to integer64 (Ops.nanotime): Explicit definition with some casts * NAMESPACE: Corresponding exports * man/nanotime.Rd: Corresponding documentation 2017-01-10 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.1.0 2017-01-09 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * DESCRIPTION (SystemRequirements, OS_type): Remove constraint on Unix as RcppCCTZ is now available on Windows too * demo/nanosecondDelayExample.R: Add missing library() calls; added save and reload example * README.md: Small edit showing save and reload 2016-12-22 Dirk Eddelbuettel * README.md: Updated to reflect CRAN status 2016-12-18 Dirk Eddelbuettel * demo/00Index: New file, demo now in package * demo/nanosecondDelayExample.R: Renamed demo 2016-12-17 Dirk Eddelbuettel * R/nanotime.R (as.data.frame.nanotime): Documented (nanotime.character): Support tz and fmt options (format.nanotime): Idem (index2char.nanotime): Idem (as.POSIXct.nanotime): Idem (as.POSIXlt.nanotime): Idem * man/nanotime.Rd: Idem * tests/data.frame.R: Added simple data.{frame,table} test * tests/simpleTests.R: Added simple format tests * demo/nanotimeEx.R: Extended somewhat * DESCRIPTION (Suggests): Added data.table * .travis.yml: Added r-cran-data.table 2016-12-16 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Rolled minor version * R/nanotime.R (as.data.frame.nanotime): New method (format.nanotime): Support additional arguments * man/nanotime.Rd: Updated for new method * NAMESPACE: Idem 2016-12-15 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.0.1 * R/nanotime.R (as.POSIXct.nanotime,as.POSIXlt.nanotime) (as.Date.nanotime): New converters (format.nanotime): Add 'justify' argument * man/nanotime.Rd: Document new and updated methods * NAMESPACE: Registered new converters * tests/simpleTests.R: Additional calls to new functions * inst/NEWS.Rd: Added * DESCRIPTION (SystemRequirements): State RcppCCTZ dependency 2016-12-11 Dirk Eddelbuettel * R/nanotime.R (index2char.nanotime): Added to have zoo() objects print a nanotime index correctly (nanotime.default): Switch class order with integer64 last (print.nanotime): Minor adjustment (format.nanotime): Added (showNanotime): Removed (format.nanotime): Support global option for format * NAMESPACE: Register S3 methods index2char.nanotime, format.nanotime; import two functions from RcppCCTZ (which are now exported) * DESCRIPTION: Now Imports: rather than Suggests: zoo * tests/zooTests.R: Small changes * .travis.yml: Added * .codecov.yml: Ditto * .Rbuildignore: Adjusted accordingly * tests/simpleTests.R: Two more conversions from integer and numeric 2016-12-10 Dirk Eddelbuettel * tests/zooTests.R: Simple tests for vectorised time operation * R/nanotime.R (print.nanotime): Do not default to character formating here, rather farm out to helper showNanotime (showNanotime): Simple pretty printer * tests/simpleTests.R: Added calls to snowNanotime() 2016-12-09 Dirk Eddelbuettel * DESCRIPTION (Version): Very initial pre-release 0.0.0 nanotime/NAMESPACE0000644000176200001440000000523114671560065013316 0ustar liggesusersuseDynLib(nanotime, .registration = TRUE) import("methods") import("bit64") importFrom("RcppCCTZ", "parseDouble", "formatDouble") importFrom("zoo", "index2char") importFrom("utils", "head", "tail") S3method(as.Date,nanotime) S3method(as.POSIXct,nanotime) S3method(as.POSIXlt,nanotime) S3method(as.data.frame,nanotime) S3method(as.integer64,nanotime) S3method(format,nanotime) S3method(as.character,nanotime) S3method(index2char,nanotime) S3method(c,nanotime) export(NA_nanotime_) export(NA_nanoduration_) export(NA_nanoival_) export(NA_nanoperiod_) export(as.nanotime) export(nanotime.matrix) exportClasses(nanotime) exportMethods("+") exportMethods("-") exportMethods("[[") exportMethods("[") exportMethods("[<-") exportMethods(Arith) exportMethods(Compare) exportMethods(Complex) exportMethods(Logic) exportMethods(Math) exportMethods(Math2) exportMethods(Summary) exportMethods(max) exportMethods(min) exportMethods(nanotime) exportMethods(as.nanotime) exportMethods(print) exportMethods(range) exportMethods(show) exportMethods("names<-") exportMethods(is.na) exportMethods(as.nanoduration) exportMethods(show) exportMethods(print) exportMethods(plus) exportMethods(minus) exportMethods(intersect.idx) exportMethods(intersect) exportMethods(union) exportMethods(setdiff.idx) exportMethods(setdiff) exportMethods(as.nanoival) exportClasses(nanoival) export(nanoival) exportMethods(nanoival.start) exportMethods(nanoival.end) exportMethods(nanoival.sopen) exportMethods(nanoival.eopen) exportMethods(print) exportMethods(show) exportMethods(names) exportMethods("names<-") exportMethods("<") exportMethods("<=") exportMethods(">") exportMethods(">=") exportMethods("[") exportMethods("[<-") exportMethods("is.na") exportMethods("is.na<-") S3method(c, nanoival) exportMethods(t) exportMethods(is.unsorted) exportMethods(sort) S3method(seq, nanotime) exportMethods(seq) exportMethods(all.equal) S3method(all.equal, nanotime) exportClasses(nanoperiod) export(nanoperiod) exportMethods(as.nanoperiod) exportMethods(nanoperiod.month) exportMethods(nanoperiod.day) exportMethods(nanoperiod.nanoduration) S3method(c, nanoperiod) exportClasses(nanoduration) export(nanoduration) S3method(as.integer64,nanoduration) exportMethods(as.nanoduration) S3method(c, nanoduration) S3method(as.data.frame,nanoduration) S3method(seq, nanoduration) S3method(format,nanoival) S3method(format,nanoduration) S3method(format,nanoperiod) S3method(as.character,nanoival) exportMethods(nano_wday) exportMethods(nano_mday) exportMethods(nano_month) exportMethods(nano_year) exportMethods(nano_ceiling) exportMethods(nano_floor) S3method("%in%", nanotime) exportMethods("%in%") if (getRversion() > "4.5.0") exportMethods(unique) nanotime/inst/0000755000176200001440000000000014740324202013037 5ustar liggesusersnanotime/inst/include/0000755000176200001440000000000013703333711014465 5ustar liggesusersnanotime/inst/include/nanotime/0000755000176200001440000000000014634012774016306 5ustar liggesusersnanotime/inst/include/nanotime/globals.hpp0000644000176200001440000002253413713656775020464 0ustar liggesusers#ifndef NANOTIME_GLOBALS_HPP #define NANOTIME_GLOBALS_HPP #include #include #include "date.h" #include "cctz/civil_time.h" #include "cctz/time_zone.h" namespace nanotime { using duration = std::chrono::nanoseconds; using dtime = std::chrono::time_point; inline bool readNumber(const char*& s, const char* e, int& n, bool dosign) { n = 1; auto sorig = s; int sign = 1; if (dosign && *s == '-') { sign = -1; ++s; } if (s == e || !isdigit(*s)) { s = sorig; return false; } else { n *= *s - '0'; s++; } while (s < e && *s >= '0' && *s <= '9') { n = 10*n + (*s - '0'); ++s; } n *= sign; return true; } /// Read an integer. This functions does not read beyond the end of /// 'sp' (i.e. 'se') and does not read more that expectmax /// characters. If the number of characters read is smaller than /// 'expectmin' the function raises an exception. inline uint64_t readInt(const char*& sp, const char* const se, const int expectmin, const int expectmax) { const char* s = sp; int res = 0; int i; for (i=0; i= '0' && *sp <= '9') { res = 10 * res + *sp++ - 0x30; } else { break; } } if (sp - s >= expectmin) { return res; } else { throw std::range_error("cannot parse datetime element"); } } inline const std::string readString(const char*& sp, const char* const se) { const char* const s = sp; while (sp < se) { if ((*sp >= 'A' && *sp <= 'Z') || (*sp >= 'a' && *sp <= 'z') || (*sp == '_') || (*sp >= '/' && *sp <= '9')) { ++sp; } else { break; } } if (sp > s) { return std::string(s, sp-s); } else { throw std::range_error("cannot parse datetime timezone"); // # nocov } } inline void skipWhitespace(const char*& sp, const char* const se) { while (sp < se) { if (*sp == ' ' || *sp == '\t') { ++sp; } else { break; } } } struct tmdet { unsigned y; unsigned m; unsigned d; unsigned hh; unsigned mm; unsigned ss; std::int64_t ns; std::string tzstr; std::int64_t offset; }; inline tmdet readDtime(const char*& sp, const char* const se) { try { const unsigned y = readInt(sp, se, 4, 4); if (*sp == ' ' || *sp == '-' || *sp == '/') ++sp; const unsigned m = readInt(sp, se, 2, 2); if (*sp == ' ' || *sp == '-' || *sp == '/') ++sp; const unsigned d = readInt(sp, se, 2, 2); skipWhitespace(sp, se); if (sp < se && *sp == 'T') ++sp; unsigned h, mn, s; if (isdigit(*sp) || *(sp-1) == 'T') { // the time is optional h = readInt(sp, se, 2, 2); if (*sp == ':') ++sp; mn = readInt(sp, se, 2, 2); if (*sp == ':') ++sp; s = readInt(sp, se, 2, 2); } else { h = mn = s = 0; } // optional fractional part std::int64_t mul = 100000000; std::int64_t ns = 0; if (*sp == '.') { ++sp; unsigned i = 0; while (sp < se && mul >= 1) { if ((i == 3 || i == 6) && *sp == '_') { ++sp; continue; } ++i; if (!isdigit(*sp)) break; ns += (*sp - '0') * mul; mul /= 10; ++sp; } } skipWhitespace(sp, se); // not as much as we could test, but good enough without too much of // a performance hit: if (m < 1 || m > 12) throw std::range_error("month must be >= 1 and <= 12"); if (d < 1 || d > 31) throw std::range_error("day must be >= 1 and <= 31"); if (h > 23) throw std::range_error("hour must be < 24"); if (mn > 59) throw std::range_error("minute must be < 60"); if (s > 59) throw std::range_error("second must be < 60"); // debatable // optional offset std::string tzstr_str; // need to persist this copy! std::int64_t offset = 0; if (*sp == '+' || *sp == '-') { int64_t sign = *sp == '-' ? -1 : 1; int64_t h_offset = readInt(++sp, se, 2, 2); if (*sp != ':' && *sp != ' ') { throw std::range_error("Error parsing offset"); } int64_t m_offset = readInt(++sp, se, 2, 2); offset = sign * h_offset * 3600 + m_offset * 60; tzstr_str = "UTC"; } else if (isalpha(*sp)) { // or timezone tzstr_str = readString(sp, se); } skipWhitespace(sp, se); if (tzstr_str == "Z") { // consider "Z" a shorhand for "UTC" tzstr_str = "UTC"; // #nocov } return tmdet{y, m, d, h, mn, s, ns, tzstr_str, offset}; } catch(std::exception &ex) { forward_exception_to_r(ex); } catch(...) { ::Rf_error("c++ exception (unknown reason)"); } // not reached: return tmdet{0, 0, 0, 0, 0, 0, 0, "", 0};; } template void subset_numeric(const Rcpp::Vector& v, const I& pindx, Rcpp::Vector& res, std::vector& res_c, getNA fna) { if (!v.hasAttribute("names")) { for (R_xlen_t i = 0; i < pindx.size(); i++) { auto ii = pindx[i]; if (ii < 0) { Rcpp::stop("only 0's may be mixed with negative subscripts"); // #nocov } if (0 < ii && ii <= v.length()) { ii--; res_c.push_back(v[ii]); } else if (ii != 0) { /* out of bounds or NA */ res_c.push_back(fna()); } } res = Rcpp::Vector(res_c.size()); for (uint64_t i = 0; i < res_c.size(); i++) { res[i] = res_c[i]; } } else { // repeat the code, but subsetting names at the same time: const auto& names = Rcpp::CharacterVector(v.names()); auto names_c = std::vector(); static const char* NA_STRING_LOCAL = "dummy"; // so we can keep track of NA for (R_xlen_t i = 0; i < pindx.size(); i++) { auto ii = pindx[i]; if (ii < 0) { Rcpp::stop("only 0's may be mixed with negative subscripts"); // #nocov } if (0 < ii && ii <= v.length()) { ii--; res_c.push_back(v[ii]); names_c.push_back(Rcpp::CharacterVector::is_na(names[ii]) ? NA_STRING_LOCAL : names[ii]); } else if (ii != 0) { /* out of bounds or NA */ res_c.push_back(fna()); names_c.push_back(NA_STRING_LOCAL); } } res = Rcpp::Vector(res_c.size()); auto res_names = Rcpp::CharacterVector(res.size()); for (uint32_t i = 0; i < res_c.size(); i++) { res[i] = res_c[i]; if (names_c[i] == NA_STRING_LOCAL) { res_names[i] = NA_STRING; } else { res_names[i] = names_c[i]; } } res.names() = res_names; } } template void subset_logical(const Rcpp::Vector& v, const I& pindx, Rcpp::Vector& res, std::vector& res_c, getNA fna) { if (!v.hasAttribute("names")) { for (R_xlen_t i = 0; i < v.size(); i++) { if (pindx[i] == NA_LOGICAL) { res_c.push_back(fna()); } else if (pindx[i]) { res_c.push_back(v[i]); } } res = Rcpp::Vector(res_c.size()); for (uint64_t i = 0; i < res_c.size(); i++) { res[i] = res_c[i]; } } else { // repeat the code, but also subsetting names: const auto& names = Rcpp::CharacterVector(v.names()); auto names_c = std::vector(); static const char* NA_STRING_LOCAL = "dummy"; // so we can keep track of NA for (R_xlen_t i = 0; i < v.size(); i++) { if (pindx[i] == NA_LOGICAL) { res_c.push_back(fna()); names_c.push_back(NA_STRING_LOCAL); } else if (pindx[i]) { res_c.push_back(v[i]); names_c.push_back(names[i]); } } res = Rcpp::Vector(res_c.size()); auto res_names = Rcpp::CharacterVector(res.size()); for (uint32_t i = 0; i < res_c.size(); i++) { res[i] = res_c[i]; if (names_c[i] == NA_STRING_LOCAL) { res_names[i] = NA_STRING; } else { res_names[i] = names_c[i]; } } res.names() = res_names; } } const int64_t NA_INTEGER64 = std::numeric_limits::min(); const int MAX_TZ_STR_LENGTH = 1000; } // end namespace nanotime namespace nanotime_ops { /// This set of functors, to the contrary of the stdlib, allow /// operations where the operands and the results are of different /// types. This is handy for example is adding duration to time /// points, etc. template struct plus { inline R operator()(const T& t, const U& u) const { return t + u; } }; template struct minus { inline R operator()(const T& t, const U& u) const { return t - u; } }; template struct multiplies { inline R operator()(const T& t, const U& u) const { return t * u; } }; template struct divides { inline R operator()(const T& t, const U& u) const { return t / u; } }; } #endif nanotime/inst/include/nanotime/interval.hpp0000644000176200001440000002725614634012774020657 0ustar liggesusers#ifndef NANOTIME_INTERVAL_HPP #define NANOTIME_INTERVAL_HPP #include #include #include #include "globals.hpp" namespace nanotime { struct interval { constexpr interval() : s_impl(0), e_impl(0) { } interval(dtime s_p, dtime e_p, int sopen_p, int eopen_p) : s_impl(s_p.time_since_epoch().count()), e_impl(e_p.time_since_epoch().count()) { if (sopen_p) { s_impl |= std::int64_t{1} << 63; } if (eopen_p) { e_impl |= std::int64_t{1} << 63; } // if any of the constructor parameters is NA, we construct an NA interval: if (s_p.time_since_epoch() == duration::min() || e_p.time_since_epoch() == duration::min() || sopen_p == NA_INTEGER || eopen_p == NA_INTEGER) { s_impl = IVAL_NA; e_impl = IVAL_NA; } else { if (s_p.time_since_epoch().count() < IVAL_MIN || e_p.time_since_epoch().count() < IVAL_MIN) { s_impl= IVAL_NA; e_impl = IVAL_NA; Rf_warning("NAs produced by time overflow (remember that interval times are coded with 63 bits)"); } if (s_p.time_since_epoch().count() > IVAL_MAX || e_p.time_since_epoch().count() > IVAL_MAX) { s_impl = IVAL_NA; e_impl = IVAL_NA; Rf_warning("NAs produced by time overflow (remember that interval times are coded with 63 bits)"); } if (e() < s()) { std::stringstream ss; ss << "interval end (" << e() << ") smaller than interval start (" << s() << ")"; throw std::range_error(ss.str()); } } } dtime getStart() const { return dtime(duration(s())); } dtime getEnd() const { return dtime(duration(e())); } // below we do some bit gynmastic to use the uppermost bit to store whether the // interval is opened or closed; bitfields would give us all that for free, // but we can't rely upon them because of Windows: bool sopen() const { return (s_impl & (std::int64_t{1} << 63)) != 0; } bool eopen() const { return (e_impl & (std::int64_t{1} << 63)) != 0; } static const std::int64_t bit64_compl = ~(std::int64_t{1} << 63); static const std::int64_t bit63 = std::int64_t{1} << 62; std::int64_t s() const { return s_impl & (bit64_compl | ((bit63 & s_impl) << 1)); } std::int64_t e() const { return e_impl & (bit64_compl | ((bit63 & e_impl) << 1)); } bool isNA() const { return s_impl == IVAL_NA; } static const std::int64_t IVAL_MAX = 4611686018427387903LL; static const std::int64_t IVAL_MIN = -4611686018427387903LL; static const std::int64_t IVAL_NA = -9223372036854775807LL; private: std::int64_t s_impl; // start of ival; last bit encodes if boundary is open (1) or closed (0) std::int64_t e_impl; // end of ival; last bit encodes if boundary is open (1) or closed (0) }; // operators: inline duration operator-(const interval& i1, const interval& i2) { return duration(i1.s() - i2.s()); } inline bool operator==(const interval& i1, const interval& i2) { return i1.s() == i2.s() && i1.e() == i2.e() && i1.sopen() == i2.sopen() && i1.eopen() == i2.eopen(); } inline bool operator!=(const interval& i1, const interval& i2) { return !(i1 == i2); } inline bool operator<=(const interval& i1, const interval& i2) { if (i1.s() < i2.s()) return true; if (i1.s() == i2.s()) { if (!i1.sopen() && i2.sopen()) return true; if (i1.sopen() && !i2.sopen()) return false; // here we know that s1.sopen() == s2.sopen() if (i1.e() < i2.e()) return true; if (i1.e() == i2.e()) { if (i1.eopen() == i2.eopen()) return true; if (i1.eopen() && !i2.eopen()) return true; } } return false; } inline bool operator<(const interval& i1, const interval& i2) { if (i1.s() < i2.s()) return true; if (i1.s() == i2.s()) { if (!i1.sopen() && i2.sopen()) return true; if (i1.sopen() && !i2.sopen()) return false; // here we know that s1.sopen() == s2.sopen() if (i1.e() < i2.e()) return true; if (i1.e() == i2.e()) { if (i1.eopen() == i2.eopen()) return false; if (i1.eopen() && !i2.eopen()) return true; } } return false; } inline bool operator>(const interval& i1, const interval& i2) { return !(i1 <= i2); } inline bool operator>=(const interval& i1, const interval& i2) { return !(i1 < i2); } inline bool operator<(const dtime& i1, const interval& i2) { if (i1.time_since_epoch().count() < i2.s()) return true; if (i1.time_since_epoch().count() == i2.s()) return i2.sopen(); return false; } inline bool operator>(const dtime& i1, const interval& i2) { if (i1.time_since_epoch().count() > i2.e()) return true; if (i1.time_since_epoch().count() == i2.e()) return i2.eopen(); return false; } inline interval operator+(const interval& i, const duration d) { // test duration is not > 63-bits, and after that the constructor can test for overflow: return interval(i.getStart() + d, i.getEnd() + d, i.sopen(), i.eopen()); } inline interval operator-(const interval& i, const duration d) { // test duration is not > 63-bits, and after that the constructor can test for underflow: return interval(i.getStart() - d, i.getEnd() - d, i.sopen(), i.eopen()); } inline interval operator+(const duration d, const interval& i) { // test duration is not > 63-bits, and after that the constructor can test for overflow: return interval(i.getStart() + d, i.getEnd() + d, i.sopen(), i.eopen()); } // interval components comparators: inline bool start_lt(dtime s1, bool sopen1, dtime s2, bool sopen2) { if (s1 < s2) return true; if (s1 > s2) return false; return !sopen1 && sopen2; } inline bool start_gt(dtime s1, bool sopen1, dtime s2, bool sopen2) { if (s1 > s2) return true; if (s1 < s2) return false; return sopen1 && !sopen2; } inline bool start_le(dtime s1, bool sopen1, dtime s2, bool sopen2) { return !start_gt(s1, sopen1, s2, sopen2); } inline bool start_ge(dtime s1, bool sopen1, dtime s2, bool sopen2) { return !start_lt(s1, sopen1, s2, sopen2); } inline bool end_lt(dtime e1, bool eopen1, dtime e2, bool eopen2) { if (e1 < e2) return true; if (e1 > e2) return false; return eopen1 && !eopen2; } inline bool end_gt(dtime e1, bool eopen1, dtime e2, bool eopen2) { if (e1 > e2) return true; if (e1 < e2) return false; return !eopen1 && eopen2; } inline bool end_le(dtime e1, bool eopen1, dtime e2, bool eopen2) { return !end_gt(e1, eopen1, e2, eopen2); } inline bool end_ge(dtime e1, bool eopen1, dtime e2, bool eopen2) { return !end_lt(e1, eopen1, e2, eopen2); } // interval comparators: inline bool start_lt(const interval& i1, const interval& i2) { return start_lt(i1.getStart(), i1.sopen(), i2.getStart(), i2.sopen()); } inline bool start_gt(const interval& i1, const interval& i2) { return start_gt(i1.getStart(), i1.sopen(), i2.getStart(), i2.sopen()); } inline bool start_le(const interval& i1, const interval& i2) { return !start_gt(i1,i2); } inline bool start_ge(const interval& i1, const interval& i2) { return !start_lt(i1,i2); } inline bool end_lt(const interval& i1, const interval& i2) { return end_lt(i1.getEnd(), i1.eopen(), i2.getEnd(), i2.eopen()); } inline bool end_gt(const interval& i1, const interval& i2) { return end_gt(i1.getEnd(), i1.eopen(), i2.getEnd(), i2.eopen()); } inline bool end_le(const interval& i1, const interval& i2) { return !end_gt(i1,i2); } inline bool end_ge(const interval& i1, const interval& i2) { return !end_lt(i1,i2); } /// True if the end of 'i1' is smaller than the start of 'i2'. This /// tests that 'i1' and 'i2' are disjoint and 'i2' is after 'i1'. inline bool end_lt_start(const interval& i1, const interval& i2) { return end_lt(i1.getEnd(), i1.eopen(), i2.getStart(), i2.sopen()); } inline bool end_gt_start(const interval& i1, const interval& i2) { return end_gt(i1.getEnd(), i1.eopen(), i2.getStart(), i2.sopen()); } /// True if the end of 'i1' is greater or equal than the start of /// 'i2'. This tests that 'i1' and 'i2' "touch" and that 'i2' is /// after 'i1'. inline bool end_ge_start(const interval& i1, const interval& i2) { return !end_lt_start(i1, i2); } inline bool end_le_start(const interval& i1, const interval& i2) { return !end_gt_start(i1, i2); } // Unions -------------------------------------------------------- /// In unions, we have the following rules: oo is disjoint, but oc, /// co, and cc touch // interval components comparators: inline bool union_start_lt(dtime s1, bool sopen1, dtime s2, bool sopen2) { if (s1 < s2) return true; if (s1 > s2) return false; return sopen1 || sopen2; } inline bool union_start_gt(dtime s1, bool sopen1, dtime s2, bool sopen2) { if (s1 > s2) return true; if (s1 < s2) return false; return sopen1 || sopen2; } inline bool union_start_le(dtime s1, bool sopen1, dtime s2, bool sopen2) { return !union_start_gt(s1, sopen1, s2, sopen2); } inline bool union_start_ge(dtime s1, bool sopen1, dtime s2, bool sopen2) { return !union_start_lt(s1, sopen1, s2, sopen2); } inline bool union_end_lt(dtime e1, bool eopen1, dtime e2, bool eopen2) { if (e1 < e2) return true; if (e1 > e2) return false; return eopen1 && eopen2; } inline bool union_end_gt(dtime e1, bool eopen1, dtime e2, bool eopen2) { if (e1 > e2) return true; if (e1 < e2) return false; return eopen1 && eopen2; } inline bool union_end_le(dtime e1, bool eopen1, dtime e2, bool eopen2) { return !union_end_gt(e1, eopen1, e2, eopen2); } inline bool union_end_ge(dtime e1, bool eopen1, dtime e2, bool eopen2) { return !union_end_lt(e1, eopen1, e2, eopen2); } // interval comparators: inline bool union_start_lt(const interval& i1, const interval& i2) { return union_start_lt(i1.getStart(), i1.sopen(), i2.getStart(), i2.sopen()); } inline bool union_start_gt(const interval& i1, const interval& i2) { return union_start_gt(i1.getStart(), i1.sopen(), i2.getStart(), i2.sopen()); } inline bool union_start_le(const interval& i1, const interval& i2) { return !union_start_gt(i1,i2); } inline bool union_start_ge(const interval& i1, const interval& i2) { return !union_start_lt(i1,i2); } inline bool union_end_lt(const interval& i1, const interval& i2) { return union_end_lt(i1.getEnd(), i1.eopen(), i2.getEnd(), i2.eopen()); } inline bool union_end_gt(const interval& i1, const interval& i2) { return union_end_gt(i1.getEnd(), i1.eopen(), i2.getEnd(), i2.eopen()); } inline bool union_end_le(const interval& i1, const interval& i2) { return !union_end_gt(i1,i2); } inline bool union_end_ge(const interval& i1, const interval& i2) { return !union_end_lt(i1,i2); } /// True if the end of 'i1' is smaller than the start of 'i2'. This /// tests that 'i1' and 'i2' are disjoint and 'i2' is after 'i1'. inline bool union_end_lt_start(const interval& i1, const interval& i2) { return union_end_lt(i1.getEnd(), i1.eopen(), i2.getStart(), i2.sopen()); } inline bool union_end_gt_start(const interval& i1, const interval& i2) { return union_end_gt(i1.getEnd(), i1.eopen(), i2.getStart(), i2.sopen()); } /// True if the end of 'i1' is greater or equal than the start of /// 'i2'. This tests that 'i1' and 'i2' "touch" and that 'i2' is /// after 'i1'. inline bool union_end_ge_start(const interval& i1, const interval& i2) { return !union_end_lt_start(i1, i2); } inline bool union_end_le_start(const interval& i1, const interval& i2) { return !union_end_gt_start(i1, i2); } } // end namespace nanotime #endif nanotime/inst/include/nanotime/period.hpp0000644000176200001440000001260314634012774020303 0ustar liggesusers#ifndef NANOTIME_PERIOD_HPP #define NANOTIME_PERIOD_HPP #include "globals.hpp" #include "interval.hpp" #include namespace nanotime { inline duration getOffsetCnv(const dtime& dt, const std::string& z) { int offset; int res = RcppCCTZ::getOffset(std::chrono::duration_cast(dt.time_since_epoch()).count(), z.c_str(), offset); if (res < 0) { Rcpp::stop("Cannot retrieve timezone '%s'.", z.c_str()); // ## nocov } return duration(offset).count() * std::chrono::seconds(1); } struct period { typedef int32_t month_t ; typedef int32_t day_t; period() : months(0), days(0), dur(std::chrono::seconds(0)) { } period(int32_t months_p, int32_t days_p, duration dur_p) : months(months_p), days(days_p), dur(dur_p) { // we have to ensure that NA is uniform across all construction // possibilities so that functions that compare equality do so // correctly: if (months == std::numeric_limits::min() || days == std::numeric_limits::min() || dur == duration::min()) { months = std::numeric_limits::min(); days = std::numeric_limits::min(); dur = duration::zero(); } } period(const std::string& s); inline month_t getMonths() const { return months; } inline day_t getDays() const { return days; } inline duration getDuration() const { return dur; } inline void setMonths(int64_t m) { months = m; } inline void setDays(int64_t d) { days = d; } inline void setDuration(duration d) { dur = d; } inline void addMonths(int64_t m) { months += m; } inline void addDays(int64_t d) { days += d; } inline void addDuration(duration d) { dur += d; } inline bool operator==(const period& p) { return months==p.months && days==p.days && dur==p.dur; } inline bool operator!=(const period& p) { return months!=p.months || days!=p.days || dur!=p.dur; } inline bool isNA() const { return months == std::numeric_limits::min() || dur == duration::min(); } private: month_t months; day_t days; duration dur; }; inline period operator-(const period& p) { return period(-p.getMonths(), -p.getDays(), -p.getDuration()); } inline period operator+(const period& p1, const period& p2) { return period(p1.getMonths()+p2.getMonths(), p1.getDays()+p2.getDays(), p1.getDuration()+p2.getDuration()); } inline period operator-(const period& p1, const period& p2) { return period(p1.getMonths()-p2.getMonths(), p1.getDays()-p2.getDays(), p1.getDuration()-p2.getDuration()); } inline period plus (const period& p, duration d) { return period(p.getMonths(), p.getDays(), p.getDuration() + d); } inline period plus (duration d, const period& p) { return plus(p, d); } inline period minus(const period& p, duration d) { return period(p.getMonths(), p.getDays(), p.getDuration() - d); } inline period minus(duration d, const period& p) { return period(-p.getMonths(), -p.getDays(), -p.getDuration() + d); } inline dtime plus(const dtime& dt, const period& p, const std::string& z) { auto res = dt; auto offset = getOffsetCnv(res, z); if (p.getMonths()) { auto dt_floor = date::floor(dt + offset); auto timeofday_offset = (dt + offset) - dt_floor; auto dt_ymd = date::year_month_day{dt_floor}; dt_ymd += date::months(p.getMonths()); res = date::sys_days(dt_ymd) - offset + timeofday_offset; } offset = getOffsetCnv(dt, z); res += p.getDays()*std::chrono::hours(24); res += p.getDuration(); auto new_offset = getOffsetCnv(res, z); // adjust for DST or any other event that changed the TZ, but only // if the adjustment does not put us back in the old offset: if (new_offset != offset) { auto res_potential = res + offset - new_offset; // adjust auto adjusted_offset = getOffsetCnv(res_potential, z); if (adjusted_offset == new_offset) { // are we still in the new offset? res = res_potential; // if so, then keep the adjustment } } return res; } inline dtime plus (const period& p, const dtime& dt, const std::string& z) { return plus(dt, p, z); } inline dtime minus(const dtime& dt, const period& p, const std::string& z) { return plus(dt, -p, z); } inline interval plus (const interval& i, const period& p, const std::string& z) { return interval(plus(dtime{duration{i.s()}}, p, z), plus(dtime{duration{i.e()}}, p, z), i.sopen(), i.eopen()); } inline interval plus (const period& p, const interval& i, const std::string& z) { return plus(i, p, z); } inline interval minus(const interval& i, const period& p, const std::string& z) { return plus(i, -p, z); } template period operator*(const period& p, T d); template period operator/(const period& p, T d); bool operator==(const period& p1, const period& p2); bool operator!=(const period& p1, const period& p2); /// This operator is meaningless, but needs to be defined because of /// the intended template usage. //inline bool operator<(const period& p1, const period& p2) { return false; } std::string to_string(const period& p); } // end namespace nanotime #endif nanotime/inst/include/nanotime/pseudovector.hpp0000644000176200001440000000320013703333711021525 0ustar liggesusers#ifndef NANOTIME_PSEUDOVECTOR_HPP #define NANOTIME_PSEUDOVECTOR_HPP #include namespace nanotime { // a thin wrapper that gives us the vector recycling behaviour of R: template struct PseudoVector { PseudoVector(Rcpp::Vector& v_p) : v(v_p), sz(v_p.size()) { } inline R& operator[](R_xlen_t i) { return i(&v[i]) : *reinterpret_cast(v[i%sz]); } inline R_xlen_t size() const { return sz; } inline bool isScalar() const { return v.size()==1; } private: Rcpp::Vector& v; const R_xlen_t sz; }; template struct ConstPseudoVector { ConstPseudoVector(const Rcpp::Vector& v_p) : v(v_p), sz(v_p.size()) { } inline const R& operator[](R_xlen_t i) const { return i(&v[i]) : *reinterpret_cast(&v[i%sz]); } inline R_xlen_t size() const { return sz; } inline bool isScalar() const { return v.size()==1; } private: const Rcpp::Vector& v; const R_xlen_t sz; }; // character is a special case that needs a bit of help: template <> struct ConstPseudoVector { ConstPseudoVector(const Rcpp::Vector& v_p) : v(v_p), sz(v_p.size()) { } inline const Rcpp::CharacterVector::const_Proxy operator[](R_xlen_t i) const { return i& v; const R_xlen_t sz; }; } // end namespace nanotime #endif nanotime/inst/include/nanotime/duration.hpp0000644000176200001440000000037013703333711020635 0ustar liggesusers#ifndef NANOTIME_DURATION_HPP #define NANOTIME_DURATION_HPP #include #include "globals.hpp" namespace nanotime { duration from_string(const std::string& str); std::string to_string(duration d); bool is_na(duration d); } #endif nanotime/inst/include/nanotime/utilities.hpp0000644000176200001440000000746314624352756021052 0ustar liggesusers#ifndef NANOTIME_UTILITIES_HPP #define NANOTIME_UTILITIES_HPP namespace nanotime { // helper functions to manage name copying in binary operations: inline Rcpp::CharacterVector copyNamesOut(const Rcpp::CharacterVector& nm) { if (nm.size() == 0) return nm; else { Rcpp::CharacterVector res = clone(nm); return res; } } inline Rcpp::CharacterVector getNames(const Rcpp::CharacterVector& nm1, bool scalar1, const Rcpp::CharacterVector& nm2, bool scalar2) { // these are the R rules for name handling in binary operations: if (nm1.size() == 0) return copyNamesOut(nm2); else if (nm2.size() == 0) return copyNamesOut(nm1); else if (scalar1 && !scalar2) return copyNamesOut(nm2); else if (scalar2 && !scalar1) return copyNamesOut(nm1); else return copyNamesOut(nm1); } template void copyNames(const Rcpp::Vector& e1_cv, const Rcpp::Vector& e2_cv, Rcpp::Vector& res) { auto nm1 = e1_cv.hasAttribute("names") ? Rcpp::CharacterVector(e1_cv.names()) : Rcpp::CharacterVector(0); auto nm2 = e2_cv.hasAttribute("names") ? Rcpp::CharacterVector(e2_cv.names()) : Rcpp::CharacterVector(0); auto resnames = getNames(nm1, e1_cv.size() == 1, nm2, e2_cv.size() == 1); if (resnames.size()) { res.names() = resnames; } } // helper functions to set the class and the S4 bit on R objects: template SEXP assignS4(const char* classname, Rcpp::Vector& res) { Rcpp::CharacterVector cl = Rcpp::CharacterVector::create(classname); cl.attr("package") = "nanotime"; res.attr("class") = cl; res = Rf_asS4(res, TRUE, FALSE); return Rcpp::S4(res); } // .S3Class is needed for S4 classes that are based on S3 classes: template SEXP assignS4(const char* classname, Rcpp::Vector& res, const char* oldClass) { Rcpp::CharacterVector cl = Rcpp::CharacterVector::create(classname); cl.attr("package") = "nanotime"; res.attr("class") = cl; // use 'install' here as in R source code attrib.c: LLL Rcpp::CharacterVector oc = Rcpp::CharacterVector::create(oldClass); res.attr(".S3Class") = oc; res = Rf_asS4(res, TRUE, FALSE); return Rcpp::S4(res); } inline void checkVectorsLengths(SEXP x, SEXP y) { auto nx = XLENGTH(x); auto ny = XLENGTH(y); // the following as in R source code: 'arithmetic.c' function 'R_binary': if (nx > 0 && ny > 0 && ((nx > ny) ? nx % ny : ny % nx) != 0) { Rf_warning("longer object length is not a multiple of shorter object length"); } } inline void checkVectorsLengths(SEXP x, SEXP y, SEXP z) { checkVectorsLengths(x, y); checkVectorsLengths(x, z); checkVectorsLengths(y, z); } inline void checkVectorsLengths(SEXP x, SEXP y, SEXP z, SEXP u) { checkVectorsLengths(x, y, z); checkVectorsLengths(x, y, u); checkVectorsLengths(y, z, u); } inline ssize_t getVectorLengths(SEXP x, SEXP y) { if (XLENGTH(x) == 0 || XLENGTH(y) == 0) { return 0; } else { return std::max(XLENGTH(x), XLENGTH(y)); } } inline ssize_t getVectorLengths(SEXP x, SEXP y, SEXP z) { if (XLENGTH(x) == 0 || XLENGTH(y) == 0 || XLENGTH(z) == 0) { return 0; } else { return std::max(XLENGTH(x), std::max(XLENGTH(y), XLENGTH(z))); } } inline ssize_t getVectorLengths(SEXP x, SEXP y, SEXP z, SEXP u) { if (XLENGTH(x) == 0 || XLENGTH(y) == 0 || XLENGTH(z) == 0 || XLENGTH(u)==0) { return 0; } else { return std::max(std::max(XLENGTH(x), XLENGTH(y)), std::max(XLENGTH(z), XLENGTH(u))); } } // SunOS has no strnlen_; definition in src/strnlen.cpp size_t strnlen_(const char *s, size_t maxlen); } // end namespace nanotime #endif nanotime/inst/doc/0000755000176200001440000000000014740324202013604 5ustar liggesusersnanotime/inst/doc/nanotime-introduction.Rnw0000644000176200001440000000052013705546565020644 0ustar liggesusers\documentclass{article} \usepackage{pdfpages} %\VignetteIndexEntry{Introduction to nanotime} %\VignetteKeywords{nanotime, nanoperiod, nanoival, nanoduration, date, datetime, time, nanoseconds} %\VignettePackage{nanotime} %\VignetteEncoding{UTF-8} \begin{document} \includepdf[pages=-, fitpaper=true]{nanotime-intro.pdf} \end{document} nanotime/inst/doc/nanotime-introduction.pdf0000644000176200001440000024304014740324203020634 0ustar liggesusers%PDF-1.5 %¿÷¢þ 1 0 obj << /Type /ObjStm /Length 3123 /Filter /FlateDecode /N 62 /First 511 >> stream xœÍ[[sÛ¶~?¿om'ã$nä™Nf|I즶ãÈNì¤ÓZ¢mžÊ¢+RmÒ_ß]€%JVÒ3 M‹Å^>,Ÿ0‰ôˆ ^âÃ_EgD ïâ1Ÿ‘x2À2ñ™§ˆç_+¸û„s•œ¦† B†ɘ$ÐTrý4‘üñ¢<¨ôB¢„€QÚ‡Q=¢}Ï>ÑÚÄç$` Þ p¡ 4 xƒ+X¯I臸%!GfB Î °JhÇ=jÏ>°ŒŒ@€,&™‡‰3ÓÐVa&Ç?Æ• '*,±Äƒ‚:ƒ‚–>HYCw”,e ­APðôBAñd”=‚)Ãô±”=%C´Æ5ð<À ì…%òå e ”AÜ S‰\'} ÌHDXæ%®† + Ì} ¦€2ç *”¹`‚€d<.ÿÏO?zçÑ$Ê#XP†¡Ñ}œ‘âáêËSLè!ÔOÓ{òò¥ér8£ÓlŠƒä4˜Ç1ÍÿJé‚þ †ý™~¡Ó¿ãyÚ°pÀ-……«†ï…¶± J¡iáŽÓ·Þgl+mV±´q¹ÖÆ%ŒŽ:}ws¼ÿW(çW{£ô1š¹6¶m¼(<¯eä>)¤KeÒbc $šÀOaÚ\•yƒä}cˆƒzàUSW€õ”F`¬€,¥F¦¿Ö9¬¬€hbŒ |l~[ìÕ ÇV¢ Ú^EsÁÉ@™« g!D/U`?"óõ‘:â;aœºèfê> ¾L èEr4wŒuèðø!âDn5Ò@ðP¨`c9 ìˬóC𼥿øú? aX,óLÍðð¾á™ßtb¼Ó/Æ?7<Ô5½/õ üT4Iâyœ%™õXcÀÓiD«{Ã…Um+_öØöeÓç»3œgíÖþX¤y<¹š†åƒmkžê÷ö¥uƒ‰å¼vˆƒ]!hérW†hjîà:4a #*gØç•†:CÀÔë@ôŽ3ÜÿtxqþÆõÁ£ø~á8CÅÈZÀãÙ-ÅVÎp–%eíTjÌ#±5ê)Û[*–²Á.p-Ã>ølè3Ûi þ1m T¶s1–Ct§&8ºèÏÎÉÅ+.oUÇ… ëñŽcºó°ò0µe/f‘˜¡X\è`7“¸#e©6êùm%w˶>ëPÛjßø®òŽŒl{ÇÛhÞð«À]üÇ"šnñf‹ÇÛxž%÷³AhïiºÈVyÆ>'¸ .fyœÎã•1(½¢hzEЄ ¶ñ\Ø19“Å]úá÷l+C¬¶„ЄK»‰ï¢(ÞÜarWí%]l„ªW(:åvÙî¹=Z¶$ŒY& ‡oª™ßV³žµ^©a¡W;S­†X:6ººøppPøpðàˆ[¦ …è ç·NÌÍ…{ß>T÷û&PX6ë³û¶ËçrÚ»‡"C¡I3³âóvÎw¸oèæSnŠœïí<ÛŒ„)Y0ŽÅßã¼z e[Ñ›!®võÖaâÙ8³Rà¡rß0 }·x}ÓZÝ` É\î“»hšÅe—úCzWßœ½½©í`#u\uT'êl²mo)wu–m\»‘¦©œM.úÚmc†F´æÛíâÉiCÊøñ5BÅŽ2M› ":¢Ê$…ݽ†o3«Ýø ;Ûc®½îybE€`뀧,uä›C[ÈDùÆÃ#S–­‘‡GšÊ²ÄãbEYãQ±¢â11[›ó˾ ~Ù×7GÂlÄP”»#W§wtÑ๧w¸± /âÕ–§wÞ~<¾>¹~qå RP³½Ã“2xï]y{ ²¡”w†·³º)Ó~I%Ý¥¦j+S5&`tÝÕc/¨ôXIü|ÙRe¬W°wAbMUî|5"²Ua(”Áz¥~žÑW6œ­ÓØ`G+]U[hì.áL¾wÂáŽ&¸ÿ'°ÝLX8Ù%"üo7áMÝt¯ ¼ B¹‚ÐÏrÎ'W£ËÑùª†*7b5† ;¾D´?…`›Á²”üUß ö@_7Ì3ÏqÁlù)›ùÒ†NÃñDR¯8î1q·÷œm¯:Z'bòi óÏuÿû¦Øu EìF(R¸B‘Ï2ËãóËWG£öGÑöwšR}WY¦ì$¨ñ«!ö„DyÊbùá3ÖøÛNTô¬`E[{FÁ=SÁzΔ֧I›’̉g)Ø3ORlÆ <zîä ?T™sçÓ¦ÙnÝ-9#PÃ)öií-ÙÒ³O›œuª¿êkÖMÈ$ÄJû£~ÐÙ‹­Òßæ~Œ¯È 0_——çá7î®GÁc‰åû^ò¬]˜õÛ„õÆ$W0Š~fÅŽë(¹»‹?dèWüö{—Ôÿk¤j¶ -XÚ»)²ˆ$ÑYÕªjöþ•ïh¼]ò¾KZß`êÕ5RZNùÀ\(endstream endobj 64 0 obj << /Subtype /XML /Type /Metadata /Length 1168 >> stream 2025-01-10T17:08:50-06:00 2025-01-10T17:08:50-06:00 TeX Untitled endstream endobj 65 0 obj << /Filter /FlateDecode /Length 5998 >> stream xœµ<ÛŽäÆu€Ÿ‚>¢¡¼°“m.ëÆ*ÊÈÃZ’d)ÖŽâ»FÀéæLÓb7[${Æ#ø/$?˜ɹTÉÞ¹¬fveÁ’U§Nû9uª^d©Xdø?ÿßõî,K³BKå¼TVSÀ¹3FÛEwuöó™  ÿŸõnñ»ó³—?Ø…i!Xœ_ž10±0"µª0 +Š4Wzq¾;{›ìË};,W°ŽÊ…Ó&©—ð·1B›ì¦ª/–+í\Zh—¼Z®Tž§E.’Mé§›\Z—T³'¦ À Àü0`Ò¢0I3ãÏs§“‹¥‚‡Ì¨¤+—J$Ý-αð*Onpœv…sr6'ìÄj!“­GÖÀ]ö³õ×í~³üËù7gR¡¤Zœ{vþOo“®Z:éªu3 #eæ’þ>µ{óõùٟΘ ð¥XXXMdò.¾äV¥BIæËWu÷Ór¨¦™L¾Þ,¬(”J6Us±N¸äX CÕÐú/)Å#ì\§E¦ÕB¥¨¯6g‰Xžÿõ“ºB¸Åj2îmRi`iV$ßVí¾ìxE]$›Ö#%Tò¦n®«~èê»p&•ÊŠ’€q:µN+ƒWÂä©–Åb%lÊh¸ µÈS‘g¶À¡@ãäb%S€(-#ûUuüV ,\ž »j?xìmž´—a'yòf(‡ºêu¿@§tò‚v“ü¸¯¯—D¼ëëáÖï0S“Ù6yÝ4õ¾­a®o ^anwQîËÕ—Ûrw(ë+ŒÂÁ›ì_„É&yýí‹ÀL›üøæÕoG’MH!³<µ@€Éþ"ÍÞ'˜‚9%~W6C½k»ŠQTÅ?~µÌ‘<¤ß¼šJíý;_w"±Fr‘ë E—%ö| Äñ;– Ðhœᨠ$~ût©o…IÊ0¨µnw‡º©6A¼D2αÉ7K ò/µHŽÍíJŠ e&3OVñLg™?Ô[£´zuÖ0½Î·`…¤ZaÈÖK„s"OváHÅ¡\Óò ñÉO%k¢N®–+ÒÂŒŒ™TÆæÉ»dB×´ïCŒBÄ6X€“¶ÈeãB°@_²’t°~3Ú+0¢s5}”ãwb#A¢ ³ 6 J ™ÏߨÓb@†¦ %ìj„þ«‘*ˆâ„tï–H…F"9tL9-“–,›ñ¹®7UÏTCu/Gž®ÛmÕ±UÁ`dúj?“‘ Y*ªÝ¡íÊÆ¯å\2Ü,>ŠÀfÓåq¿@7úµ›z؆u»-vU<倎 5*£Ç2H²&I¾dcë¤mš–• däfEü_ &Ù€ÉI*r-Xê=ȳÔà-]qÖ¨ˆyRvUø6ÒNê@;0'H» „J¢ÝÔÉ¡­‰\Ö{?Œ0X¨Š4§Ð@tT_#‰t0£;ŽòÁ:בEDMBEƒzÝlëõ§çyžñ‚P¥ŒÐ@hŒ\²-ÉJ€Wù· >.iUÄ ìM7Î[G` 0`ã?€Çít6d ¬L†—Õ~ónI»@îÀΫ®n'ãß‘ Ñ :Ùwå~|ì*àe‚Ul q“™eÂ1VMÈ¥¤œ’«?®É€Üòr(˜dQý.7L ¦ôviQ$¬žBصûaû‚„‚EÁ„¨Ö)íJ ÞI­Ê,qssìaòsB"ÝPµÄ ï/q a5‹¤JÕëcC~¡€”»Á,ᛜ¶MbÆŸ½†á—¨44 Yv "» ŽÀ€‘]é5‰Þeh ³¯6àR8Œ¶@wl)É;m)CDäO&¹©šf‚Hv—#ŒÝËr= Ó¶eÜ—ùmFxAåˆ0£€AûÀ ÕWˆ:rÙ1´ˆZF4]·èÿÐX pný7øs tj)±?ß{ÖýU_‘cXwÑàµ}ïçB༩//Ù·@tí­¯d@ýi÷U×z´=üQ$û*èÛ ““xb„Ȇ÷†QL.JÒ·0’¸FpLòCXsƒ°‹cÝ «šF‰9\å)ƒ"¥'H@îêò7ëzÜ#ЮÞšjt‘dÁ‘Ø”û‘l… €õP^ )²ìUã?a`ì-°ÉÙ¦å,Ç>!“è#@ƒá¸UŽ"@ Æ]VF±¤VezÙ•@þ¹Go§A5AôüPD“Å<0þÆX7…H7Ãk/þ b|¾¨,R 1ä¸éN ÁËéüÀ·$ãD `TÙô­'†$ I4¾b Óù/Y‘©·÷mÛz]U -&¦£N².2c ¿‹¼BÚÔíQÿ×ïß¼þwÐÛ;0©Ò2˜ï=t°v»m/l’5Hk?¢ƒBÜpÎë:{^ ˆKòÏËþäX²”áûªÚÿ1éRÂjõÆÙûÝr/“‹–B‹ˆÿÅ3ÙÑ pH}Û½3ò‹pÀbÛ¿ ñD †ßƒqœÚÛ)M¥©‘¦ßµCç²Á 8‘ðk^£1ÆÁ6é·í±ñ4AݽˆßØÇ}»îªˆµaöù±ÓÐï öÉcÂNy\İà 10l¨ïä6Ê(E…”:: *˜ø_|ŽvªÚ`¼†J;xÍýNBjˆBNáZå¦âÈ "¾kàmFıú~–û”h×·»ðdÉ]›À]¼¡3ÛíBâS+_ ´6íú¸›Ä)>#./Ú#m„ã'VBë#À3 =Í™H~`lSÓiÊô¤rW/R“ }WYÅ€Ï0™OR_Ïì| ”3} ÇLW|CNæÃ²g±€ä&wñB/”¸i¥äB` óœq{…‚tXâßð¤B1 wp½¥h;Œ›yëfŽP÷ÊWL–ŽI%î0·ÓeO ø½K)S§ÜcàòOåU•ÁC ò×ѧlÙ rªáÇ@0”-ÆÜ‘·¦2† ÏÏ‚¨:׫ ²~ž>L^U†%ÊjòÁ¯ú°f¯‡ Axâ¸o9úÅ 'B£Ló,ÖHÉ£žš(—·áùåý€‚“¾2"C`ìt™‡1ÅPf.uRÍ1쪦& ±Æ×M4‰õ(á拏¥Ê€‡ÉçxøÝäúD09P'xàÆ t8QÅÀmU$šxLRu¦R‘Íš?Š”† Ô‚Õ˜a5Š©å4ý)Ušû—Ì‹ÔÍý¾Ú6ýzÛüßUÕ|Pã^ØFªÔΙý„ºËà!psðTF{Òl¶ž}·¤Hƒ÷SE³8X1£~ ÆAræ´÷û|¤råóÔg0ï¥ÐNRrV^·uåB|HSþ¡…±q%C±‚1ëll9ë(û¾]×åW‰/&U2' n¶ÕyìyJÉ@#œ r7§‘W1ÂÄŒæ‘÷ªL~À0Á)2¸!Yið‘ZBð3óÌ×@!9mo(‚e'~É '«Õß(­¥GHÓÞ#vaÇ*yÁõޱbµšE“W ©ÐÆ…/ÑìBÐXHØ`@þVï‚ñ¥Õ€ååþ*<‚ /’Ûªì&…ry§)‹_ °Ð¾ò1Š£ÊQhu çk†XkÚ’{âxдLSvWÞk¡K©öíñjž'¡uÓtfZÜRS¯C” ¾JÐë×Ó!œùé‘=ø ,˜Áì¡ojV‰ï8Šc¼±Äƒz,Ø|ÒˆKcîìC„óz£)ÃѧÅNn:…E>¬‚,Ȩ@X#9^Î?ú S`S»ç“„‚´$æYø,½&YN燛ÀP-Êøˆw(V¾òJߒϺ‘×’%ÆqºûžæöäG >ím]?öiA‘u_ƬÁï· âì(¥“êb8SÁXæ¡êNÜ;EOÄ‘,•…6XáO•âœÀv9,*h‘È‚h^®;ª,I«0ð¸K¢òUÓ^T¤Ê ¢j,rã@ ?RÙƒ|Š Òo!m`ÀAæ•¿€^pT— .Èñ¯Ë¦ÚoÊnDiºÏEɱ%ñ"›ž|„JcÍtЦ¼etvþz»-}"Z\.¯Î(ªeÀêŠ\Š•ÄÖMu<Ù´[5ÙHæˆ LnÚu)9šSú:òIR•³ ¦zß|zÐV£Õ£bèÆ/>^g¬ë!«#Rù$ñ8¸¦ß/é¸_Êàa0I¸ ý|J`‚…Ð817xÈ/”wCÇüŽŠOOM}µÂ¼òzr˜°]Ÿ„±{1ºè«îº¢l[”íº“”hXªŸH¹)³‰Tay ÿ± ±Fà ³0'ˆÌ†PzSïjðO Þ‚™¸bà¸[#îÛºÚœåœb¤ð©1WF§ÂΩë=_{yÙWÑéd½EßÜ¿˜¸`e¢9ŠÖe´¯Žõ$Zâ8EÌŰcžÇ³Wœ`Oï!÷‡A¼Ü·#äùfr¿™°ˆíz}ìH¦}ÎÄR( ¡´L¥Á!˜jh›ø:'i J >¡ƒ.hê¤Ü]ÔWG<.:b\Á5örç´àòxvª¢±´òRûê:ÔQ1Lœ±\F+¹pÉQvÁ‰u9 ]}qÐ"†º~ûÛ€Š?§ŠõØ8ÅLk&?/h °•ÕgœËû™ÿñ9æ#IaI 4âÊ!h€¸Ïäó™1-$íá3£W´=*£k ë”K¥?ë®êÃ7–['¦<òUh‘|x.¼'ÙT]ˆ|tJ ûz¦Gx__4œ+TøŽÓØR .©ƒAƒŠÕìãýÇþP­ëÏÖáU.ÇUÞ©Ùã#žO"*ˆÞ´ #Kªüš"™ÛP®ž^l; ¥3©ÑœbðÁs—œAB/±«f:ãÃäL•æð4™9-?hÅÁe(Œõþö€!Ç'ö³ Âï™ï#À#vc †ç˜ŽÅŒû²O•)2á×oF!ål>ߌ?íf™§CÜkFS’Qy ÈÔÜû¸ÔãA\´*Àʪp™xÍáÏ#¸€ø¥Î¾Lô BÆHêÏ™Î~·Ä9œìÏÅCã<ÚÞÍ+29±aÀ??‚´½)¤š$¤=˜»QØcÀúÉ96Xš¡l‚ïá"\ ßæâÔ˜hû±ͱD_U;ÿý¯ÿÛûvz‚ÈÂüÝäÙÛ IîÃF°vLj@¨FøBÆ5ä®müŠç³Z~HÊМ½ÆiqCBÎ×ÃݸòÈ®\¤¹ô1ÏzÛö×0°€é¹£&4Ö:UJÅ£­oÚ 9lC®—SÓ -ò.z71ŸmŠ<JÿŸ[Þ »¼žpÓÝ$_¶Mu¦f_=©ÆAÃær5ƒüü²d.3‘J5‡þÁa÷• rª˜³–›\2v»R‹€¤9^t5Ö´®ãA^ .h¾ôèHN>NM:,¨¨Wìd³è€÷»#ŸÂ…,êꟗX Xÿ´-wOp¸Ó²¥fóòi¤C„ËO¥C16*’MÝšò6t aU¿ö1–9¹˜m¹»îý)[ì€[×pða&5qkï¯2¨bS ±¦±+ïiüˆ[“NCÆ(fÛî!¯è“„ÙŒC‡¢ÿðJJzá˜1^LúßxÈ.Î÷‰dR®×Õ!t€‚ÌÆ8YΨg§Ô£cø«c¸¥iB;¸¨ÓàC€S…¯Ø{ÚyÚQÑ)QÏùOPtjЩC,2–¿ð /žJ÷rV]UnJ_jǀܯ†™óÁÒïë}ÙÐÑš$aŠù‚? µdŽÜN[]±–;~–ƒÔc*Ê«<·Þ Ê/¥±kòH+óX .«.ŠëÄ$úK@w©Þ#¬Sž°9> î+U¹4ÇæOG »#à@Ô!ýñ»×ïꞘÖy&Íbýx^äû| îcç oxÎq[-À~|Ï÷Ãyõ“ãá9yz5=#üó«}¶Mññ6$ùÓ ¼ÿbE>§Ž¯s×R¸ïË­÷µ¸Ä–)ý•™¦¿Î{¥¼AæsÝñ;´Ôký÷Ý´™5§Ü'ÞNáÎËŽ ¯J¡½wÖÌŽ¨/"ÎÜÞ0tÇõ¤±&Oª›FìC´êÁ÷w{ ‹…N_ëy0RÆÄ4/âÚxž¬tçBšŠ'¡Ä¼Þ–x3¥êîZÈbé51ù"ÊÏÏgò=ƒ¬âÖe“Ñýž…q` sµèªÅŸ{µÉ’·â/þÌ&dqž™/² þýgúÿ)f_Š<_¢>L!*Ù! pÓ¥Þ&Ÿ”ôÔ…T¨/„b¦Aœ~3äE^í*ì¸zù]uóŸÿÑv?}þaÑÄ=¢?Ïí|÷ËÉî?pAV" å>L¸„;¥Äûbö!Ï}?BâÛÿR™yUÛáÿâåËu‡—òrü­žrŸv«å Â÷C×¢‹OÛîêe¸Ÿ&2¼ŸvUýK”Çgü,ŠÆÐn†ÑX/å> stream xœU{PTç½ë.÷^-CSÖ nï5ÉT“hR1‰¨ (ŽšXA‘‚å!ð~ÊÂòtwaYv÷wY–]–7"„‡q *ß™Ø$ÚLw†ÁÚÚ¨ØX2É´Éw™Ï‰½ëJ¦L;MïÌþs¿ß9¿ós®„-#$‰×Û{Ägçûox)8'3Éõfàø…ñ…=à)OÙ‚þ›7Zþ³›?½úázäAÙ9¹Gò•ªø„âĤwRÓ2³6ijÄ>"”#áÄA"’&¶‡ˆD±“ØMì!ö¿!V+ELBF”ŸIÖHº$ß,3K—Iõ2‰L)[ðÈðøœÌ ”?•HýƒA'½-ûËAâx!ZwGˆQIvö2`}Næ}ËÆ²Aô+¤ ²¡ì0Ny8ï«? FÐÓ¹ÝÐÌ:Èv€æÓ#Hê‹úÉÁu©VÕø]"›»¡—ÃJ”Ìà,Ò‰R[Î4 Û~w*cDwUsB¾âèè$]Rܦ+ѬÞb0WŒ¦*c¹z?héâé|`/—ŒBÐç‘w-zÞµký‹"·'Ò8‘Jr=-–3`6Z«Žë;Œu “©ªJS™[t~YÛuif©F8) æ6Þv«‘éV#@Ii’!%Å\®#×8ZZ/°m–Úá˜Ë…ò]úƪ$ï.¼%]H‚C_1dB4¨ å¿ÝŒÇ|_G«:u]1àWJ(WV”Åá T¼<9|µƒš† Ud‚!çÛ‡+}›bz è>rl- §»n;Äý.ð¼oÝþ3xcStCŠ¥h è?c`o´Ò^B§¸ïüuÉ(zºŒ•-Fà8…6âõ|TtTuÎ.¶°Bo èêÂøJ¾Ê¢·Š—`Ÿ±³S¿úRkz(—J¥â#^r%èÞà´ýÓqNåNÃ/`Å·ÌËëÁŸëþqÖ>þ‰µEôY'*P-uö ý8ô¨m‹Ê©Ç².š{nÑÜmÐüȹ¨óÐ*Z;퉵ML¬Ç²ø#Ý͵PMý]瀞‡_½)fÒ€ã?¦U‡°[*d Û™Þ\8Ê¥PeJƒ~3ÎÓï¢M¤~2áÁá/r>ÒµDG–¼j³®FÏ¡°‡¯V4­Ÿ:½$ö ¤ƒ²YcÕ›¼h}¥A]Y·Ó\ÍÕ«/[=“h…í]´IÈöµ4A X\1xpÏ1ÎC®…c¦h¨>gl¢ÍF»¶ÚZ-[RðÐÏÁüǶüõëOzK³\£æ?ÂP¯«-±ý®3Ë4~áå¼o¾ó&Z×û!?xƒëkáy°ÓK•ör+ýŸüŸBõ#Ì-JüŽöh*‡UTìX”5S8üP àƒè'ŸyÆÇÎÑÉÍÚÁÅrÁŠJ "[u¤TiT½>Ÿž†¿#Ù‰^ma§+Xc¿t)œÞˆ1!é—Hê#^ÈGM böÝÁ/°r ~u‹?^æ‘ÿðUËÉë\gƒÕ `5œ0ÙªL|T‹å¯Ñ†FîÓe-{€zÖð1ºÉ®nþ,‡¥VFŠ“Hyæ5sÇôÝU· %̼uiÝ»ø¡ñw,6þ¤«ñׯìÌ)gM¨—üï†ûÑÊD<2»<å} ­Å«]"_C"Ì÷K|Œ¿_R–ò Vá2sÌý—H÷=QÙ–¢1ö<ù~]{ÿÓö¨Üuñï·„êÐ"i€‹Ï37$®•·ºÒ…ñÇK»VÞž¾;…-ýâus<A<Ħg*Uº2úG¿{÷¯ ON4F¸Dø?D/ø› @>(ùHî")ÊFß13T‰Ïc·‘y&S·ÊãM=ì ÙÃó=¾%û_Ç^BlJë3ó¤sRü„]! Ïñ\~ñX]Ï›kù:3ïéIÿ™4JÂendstream endobj 67 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4060 >> stream xœWiT×¶®ºªDhE,TÐn4‚B4 bÂ(â*‚ÌÈ  (ƒb£D„DPDQM0"$QI¢&^£Q£AÉ®~»½ëž2Ü·Þ×kõêªê:gßþ¾½ŒÑÓad2Ùàù1qa7ø„®™g;'>6Bz62 ã5mšd91Ð%z'Fùz0‚Áƒn f¤Ï‡³×Ä/ÿh­Ë:×õnÜ6znš›š6/9Ü;%bå‚È…QÑ‹c|Vù®^§3Á6Óîý‰“>˜ŒãËŒc–0Kf3žñcæ0Ë™[ÆŸqaì˜Æ•qc&2îÌ$ƃñd&3s™)Œ3•™ÇLc¼™ùLcÈ(˜xf3˜1b†0ÆÌPF`L˜aÌpfcʘ1}f&›Ñcf1;™6æ,@V«#× Õ9¤sKt“tŸè™ëùëmÐËÖ»'Wȳåíì8Ö=ÀþÀ™q®\¯ËÇòEü‹AÎêÛê/Òo¨3Ðb ßÀ¼ T)Eõ· ~2@Ã-†y†EŠâü Å 2¨a°×à+ƒ2òƒ…&’¨ÁŒ W Ô2qX õh%;iâäèÄbÖ»89ز—>ÞF.f_@¥\!Q‹v0pzH ˜C0˜3®k+m½í⌻Zëjnß(^å¥ÄGôÉ¿9èy¹9þk„+¾åè ‡ß@.+£/s]h/ èh‰2tE·×È€8tƒ fƒ×¸?p†*åB×·Ñ–Ë\gÍôëìînè¼§RhÞ'j«Zù`£+ÚC›Å`9:³¨Â»h wå8…ÝZú¬l8x ÃPÙºBó¡¸IØÝ²­*¶ÚçΤj”Ãp(Za*nc´¢Ñy‚á[˜ž¡BK6ÍnáR;ú ïþ&ÃÔ¯~ý«µÉÑEªœÄ#I< רa €Ÿa€ì [ª›?Mš¿ÛOïËØs êãoL~8ÜÛx/êŠ*ªÁãÜ\âNÖÄ,àA?^øê’ÛXk77×€Û¯_×wtª$ÄÀHÜF².°Ï©ó]&PÉ‚.éÎ(Wý/O‹ú=ÇQO§s«š—{Ðå&ãQŽ3óg–û«ÊýÚcZÉmråÌÙf)lšýf"C]ucàîúWß§®Â"úu¤î~G]…dhàw0ÂßÁQ4#íÉwqb ýU± q­'SPõÕÓ0㊿j©Š3^ø ºúÁ±£û÷æ)a ·3}7ÙC¼ˆOhÜÞxb×[Œp©ßÔÉT‚dêkjêkúìßÔDÆ»8°¡f@Þ‚Ž¬žní+E{@Ôö;¹-h´£¦¹¡nTflÞ&U^Òñ´«)0}Ùð²Ô¬T²‘_‘87jÍá¬då–Ì]™»ÎзÙOPÿ_Þà@î’ÏsªJ«JO^!¤3ºÎåº6 ÈÚq„äóÅ¥êËíg7ø§+š¼ Ó¨¯ëhùÕHå Ž°À‰Ý¶cýÆuQÁ¾ëQ_ §ôP”'u½ã«¶¬9«:‘œ™’½’‡Ñl2Ø âºÐ·"ñ=|qŒÅ©°üå­²×U¹ãåOX'§×æ¸ð ;"¼6´KQÏcÅ6†iÛä´AÛäÚ6°ÑÄá&‡j»p¸Ø%Ç„þ:ÝKEÚ©7b°$B(‡,ª±]ŽrÑäxšƒ\h—ÿwÚÏü)ŸÖ&Tã(U²Øè¦…’† Ö8íçäÏ._¦ªXv+æi'— ËyÔ ût¾W<;~{Uß)e½1áó ý!OÀ&!=‹"‡IÓÎ+Û*£^NiîíQïO@=ôÄÙÏGƒ-¾ìè)Q¡’M ‰XïGÂÉêã‰ÅÛÔ»Oîkà<2”Uߤ™/MQÇg'~ºé`$ß'Eâ!*CU4K–Rï4Õ$ Ä>ÆÛc®k¤¡fPV1¶Í­ÅýÁª7ä yp¶åvKûùÒM€ü}n§W‡Sé§ãP}k… µ“%Ò¹cúkê”í÷¯ÁPEeˆÖô”g/ÞÊžHBt‹ ‘C#[”õÙ©¬œýû²”o¹u¢Ó“oì‘H{r}dIì© cAÄ,Xȃšë›ÓòiÓ$PBU/¡F€Yl[Ѻù»ÈŽýÛTû“H2I%îŸlÌ‹æaêi6!;í)Ý«÷µ«zPZÝL~"_$6F—¯:˜CÃÖšõ¥ì=º³'WKr÷änÉÝ’±žÄèñ)[6oMÜBø^IïSãí~ὃŒÔ›YMœ­s#zE‘JZ¬²:xš`¬®øFüD í[.DUù79¡e‚Y:â”î ãâU¿'¾Jªˆ' GÌ÷‰œh±¸öÛÝJ:^eàÄ?¦Á|šä… û˜ÂË-ºf§TÈæ›Ÿˆ=AG\»\Öõ¢1|ö!%uŒ0šZêY§äYdŸg¯ØØÔÔ¸´]éw(Q+Ú[¶OMø•—?ViZÿr¸#)(Ø.•¾ ¾ †N ÷éßë´¯ÿìX’Š4K›ÀCA|Np†®Üõ/AÀ498°¸~‚y"ÇÉlïhÙÛ¿¤b-‘6N—úW79(ÔÖ6¨æ±RLCzOó]n èZ÷˜<&]§ë/_Èÿ‚<àÅ´¿{h_¾%Ñí5Ë*þÇð¯±û¨PE]™Õ÷f\vããwû­òª—ά Q¢¶÷ÉÝ‹C¸·^7‘q ‡.庆%g¨JOô&á›}ùö¾‰ŠRö.y;äGº—dáW±îÿÂ?ž%Úøþÿ‹Ò46°”µÒÔ´‚¥€–örÄ}môÂí¼W}¨(óô‰ª’Ï*È·<Œ¢/?‚p0“A¼°Í PBÂßÈÄ&h´-ï‰-ì?¶„UÒž6h)Á%[i#Ð ö.–¢ LÛ×ì ÄLªï’dGH)>¥‰f’¹«C†ù&M$8Š ÑñÎ.©ñèXùt‘–’ 7ªšÔ?NÀdóã˜k¡·Ý*hEËõÊÉ™Ä㑟Å™AÛ¾óÎé;â7‡Æ%„“HŸ—R¾µxç]òœ<ß+uÄ8ø¹=(©÷Þ¼¡]ÉbÒ+¶"z{l˜ªÆÉábR › ÆÒ²(%ÄJMâ±NøøbZAò©È†¹Å’É䣈—P·g‚Aű™å‹«=ïDü@÷ýKØÁHûç¨X‘¬:x—O‹³[«*¯“:r297ˆ·F¡­ÆoÆÌ@_o¯àÆ»ß^hjSõ|_JAJñ졜êaC§¡ïí?v½]Ž—FþlHø†Ý‚ù~·¾€ùÇ| #O»(0¤¿½4µM„“Ù™‡3ž9}¼–\äAwü}†ÃÇ;¡ž{QHkŒÒ¸Û18f‰½)švÛ5Œë~¦?Ä49^PÿЦ°Q¸Y»ÒwIpÄ|ïàóךj+[TÆÝûðœÐQ8Û=8ÈÝ=¤®óë Û%ÿ7Pg†y´`‹hâ*ÁQ8ˆ²Ÿ§ƒ‚<%•5_W´äÿAGÒò`ucÐ=תi”;cl,p+R~îhN¾*;ãHFÁ)ÍVz8ûÇœ®Ù«|".n×,u˜¼ÌË+¼áþƒª«7{ °„$Êy:¨QÒçüMzñ¸Þ_ô¤Y®¦³Í ]–$”ÃÙ¨$hKЮ•@ïùWìh‹=VtËsÀö@ß¿’?èR®€ƒÙõ´‚À–€](‘ÞóVl†£'l´"hƒìh¤K Ä 5ÌP° ¯£ö10`˜ÿ¬)„Òendstream endobj 68 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5886 >> stream xœXX×Úžu™™µ¡î: hvíìÆBbW¥J¬HQP‘*Us0  H“"J^¥Øˆ5¢æ[PMÔýfsÖä?³`®ÉÍ}žŸáÙg9œ9ó÷¼ßû½ßˆ(>”H$¼ÌuË.§]K×éYxylñÆF|wÿ   Ñ1 ‘6bÄ )ÔÅ ÖÁ”ð³v‰§íR/»e;×/÷^±kåîU>†¾F{VïÝb¼oë?ǵû·™8™:›¹¸Z¸Yn_çnµÃÃæÙ€©Ï%zú›§ÏHœ9köœø¹ŸÏ›¿`Ḡq'QÔhÊ”šO¡Ì¨ÔXÊœZH£,¨ñ”%5ZGM¤¬¨I”55™²¡¦P¶ÔRj*eG-£ô¨õÔrJŸ²§VPÓ¨•Ôtj5ƒ2¤Œ¨YÔjj6eLÍ¡ÖPs©µ” 5ºByP©vʓҤQK¨!””:Dɨ¡GiQ{)mj¥CéRéCI(7ª/Õ £"(3¥A9#(:&ºßgBÔçñ q’†Xc‹F-=¥ÿ`¾`²žÌ:±ÅìïÉ­¾ú}#úÖ÷“öÛØ¯©?Ýß»ã€1Ѐ‡kŠ54´dÐùÁòÁ›W Ѳ|È}éx©¾´BÚ-}#Û(Û%‹“µ ’v!X+õ„"öû ³7Ûú8Ê›œXÙ ,q¡wÜ¿“™V‘´&ÿ•óOÊD¡üïâå,Α½F¸oÀgŒ‚HPnå¬á‘ˆ4˜ >0 ï 4 '£GÊÙU‰ØZÁ’®£ËðfG¶94>Ʊ6lKl=B—±šükT ¹•T%}ÿxÿlñJ[ök¡úA—"RiU»?ÐBØ}* _vÝé+Ã6Ü?Z!Û÷Ó©sõ÷t¡Ï¢ XO.Û7_âà›}âðq$>[L6ß‚‡¡è …ìW|SÒÙÒ˜Âçȿś§_»ëîñ>¼[¡É‡Vò3+E%Ý×-†L>˜ÃÃ'Ç“ðÄWã@t~aâ¤7x¸b³ÆwÍ_`k™¹`¡ù}à@ëRÇwdάu‰ƒÔ[h;öø ]YÿÀUÂ& .±þI4ø²° ·ïA¦-$>àt¬9Ç.©‘Qnà7ˆ*ßòZÅü£,fZ²¾Xìïïêå…tð܉ °ê%P0©´8t‰â¸_òtú"è3K³ŒÌoà rmÃÚױ佉¢Æ»9ð:jG7¯gI4ù:ìY «ªùù¾W¤ÝóT[ö]öä ¸˜1V3d![‘0›`6ñÕrÌ#çwã>{­ar{£êè!Œì;Їpž±g3 Ï É“–•˜ÅƒVLÚí›°]Ò9þV´šUíh‚?µeí-<­‰Mé>qœ†tF–¡¤z@oåCÁˆ•uX1~¸H›~0ßAWtŒP ¯FDHóï×bƒ‘#ó7Î öt/á›ú]®| ¿œñ0‚Èçmà0`üLÛ`ë™S°±Â€¤RŽ~ áÁp¨SÌoâ½8ëû#[’‹GŽÃ³ñè‡Ó¡oEuâÉz¶f÷ï_EÒ)¨˜µŽñK¥ùV;|òp©d¶3§êË:ðˆôA=ó0´®ß{›‘žG0¸ƒj °ŽÔ¬7«=yÑÿ‚¶ì·B->>·aöô§qÂ<&)àØ2ºv:0–Òx2JËʓ撓¯Úý·mkòR" ƒÏì¸I$A[vƒèAD1³B}˜¥ly]Qv!Ê@©aÇý%™=ñûbö"‰¬$ …¢°C.ž.î®.’îR +Q‹Ÿ¿µ°ð¢Z95¢ÆÝ¬6­I\¨±åÌòØý„Óñ0%á.%ázÿ'ÜðeŽ$O¥›`ºÊÇ‘¹ö×XdžVð³*¥uŽaÊ}ãsÚ²uð’wãÜ’·ÝDPgÖØÌ2¬rä¤å^÷(ö³Ñupq3÷ôŠKñ’?¢í±STVOøÙïÆ¥%y»O(¶ŸvJrM•ÈÖYžǫ̈ԭÎ;Ýpòdxà)yÜrú£©\ÜáåÐÖ ­| ø‹‹Ú2žŸßr[Ù[‘$<¼ÝêåIž?cÐ`†?½½²!Å’üöê,›ÅX}Ì„ÌòÆr<»`íkX”f-íU¾…dÚƒ, „±©IM±t9« OÖó}k§‹žvŠŸòó9|]žáÑYZ}4¹V^ÂúDú$œYTxO©0µO}çÌnÖ7ò¤wÞï!GP^ñe¼üAüZUήUI&¼Ä™dtm洞0Êב`‘ÁQŽìeáN‚_B½Ü#Ê×\µ*æµóSÓ¥/{ªÊ9-H¢ÄY(…ì„:ëÇç²*[å2K˜XÌ:Äú¥ÐüJ'¶wÊsVvnïV§Îà =ÎÜVÀ÷dã½ò(éi‘!Lo4W…hŽ8²Wÿ܇±@ŽP”Δˆ"ùxq$ïË9³m0Gµš¾ÈÀ2Þ°%Ž.Á+œÙƨ8<?Ä}áabJC ]B¶`\Ç?/%^„M?ˆá$&:4ÎuùÔÁÑ_Éï)m‰25þ•a„>zמ€‘ !œöZS™ØÄ!e’øÐÇ tH—΂ªAÂ×1¼áÅOâ‡ïã~¼”6a°®J:îÿXLx£C1ÁØ*iÅSØLÀ €'ÍÜqsF3ÖPɾÞT9KÙ˜ìŽ Ï’ßøž9p2–¨ðíôí w;ØOó@c$²ÂÅç¬Èeu¨!óJ%ùûŒ†çVÿíHbçQxîΕÓ0ª”Ú$”C•@!i£Ê™†„ÝeÁgÒ0¿œ]‹÷Âp†¯¯Ç¶9²#Žâ]ø$í'™^`¢þÆ7M¡~J‰(‘§õ@ºDZÇb+‹0ÚÌKX‹£‘‰o`Ü <)2lK8s+aMãðØÃ`ÙÅc:Cg¶.".h:ú9hÇ«9¢Æ«UóŸ5ÀÊü”tÑãN8DNS[éÃáA¤ìÜÿ0†’øî‚Å0básÜoÓÆ`{²VjðØÂcyGh¿\Z‰‡`¹© ֊܇¢w@RIýø—:‰Ž]ŸÖâwÃj"¼x€ ¼{øËLo†td¯ü¹×5Â^ðçmþI‰è+þ˜ø«|0P­ÜµÜÓn§§Î”³ûýCýÐ^í§}*®Õ5]+~³@Ž•½d‚¯âpõONX„·ðcÊD%]bþ‹ î»Åkk ¿1Fw`HÛ:§¦D†&+æ³É’#“‘äLfFA³UÙ<²Ç¢<›#S ššÊ÷½Y&jäcŸŠóµÀ¥œ1‰ó;Aó•,ìSýFW2p@©A«ÚØF‚.„•³kbƒÕ™˜˜tEØõö,¶PEb3þ+ú4v%¦/â8Á ŒõÛgF0p%àéÔ®¥P ùõÚ²Œj-^ &0²[&dnÑ<~}ÀŠZ6¡#‰Ðz-©ì8]Å‘%.‡^!3½ Vƒ•?…D’•¼L9ƒÃf쎣1^DW§ŽIjîÈïõ@ÔT—^^¯­·äFín• ‰Üh°²ÊUçìãì‚$3LoA_ró»×'ó"œ!lè…„jä?kçª!1UCr凨®Ñ×ù×LZZ«ÀygG¶54ÍVmgq7Ogc3A–Òz·o"l?8ô¸WÀ¨jQÉcy&æ×½ã,œìöÚ!ÉxÃ{0ôkƒbÐÁD' cè˜-¿‹EXwòX<Oèšî\K/k•Ï„£ögŽ<ºtñ*’´—lZ‰"P$‰ØË¿ïnUþ›7úUÌ÷Q.çæ Å¦æ†«]g ,"¿EÓ¿1j¶ìðx„@‚~i¾øÓ™æÔëè.‘ˆ×L›—äÍA+ àža l‚MfbZ°¬3I53³gдšp—8®üjE¿t À ²@”œ‚‘µXq‡Eßg^¨Lï2vêhò tRRàž½÷›;/8ˆ¢P”Ü8€v¿ª¢>„&"3.up_m"^üÅرÄF:A”vΫ'0¦Î¹€×)ð¾¿Y˜©ÜbÓ§¡2yhÛú‘¸‰f|íIR7{ÖÀÆon”‚smH©´ì¡ùc°}¼ë®¶lÅÓ¼#'›BprŽwŽû-Z5yq­YÇ~…»“ÿäücŽJdÏBV;Úë.¼¾Ø{7²*䥕¨ݵÉÇýÒ¦$û*á«8‹Rb’&AGÈW Y$ß¶?+ ÍÝ—«€>µ y>Â5—9,ZìhonîX÷mGYM³‚<ÀQµ€{éw3¨ YéXšÚÍœoUÓ\•_Ò”*×äÛî:×{Dí'¡ÂŠa” j›;T|—V·iêÂúO}œƒ0Á“OõÒÇ9>ÎFèã ™ø]T IÕÄd 'ðË?û„Ð^G¡lZtjt2êB¥Þ§çgǬ®Û’µ·0´e¡ì¯óŽHβ‘p-B-~µ_5yÕì-tËX¨“ÑcBrƒKx®|ú®ŽÁ­Nc&ZlÃ"üÔr …ê.5%ý=°ÒŸ@2’$û0ÐWÚrîÞ»¶»ŸÚUPp*» Àû”;. ïâ0K¸©nC­…ú «`1–¹l ѳóÒÖûõÜ€XçÜÖt®fïåàÛ„0³î„~U%ž¹Š ÕV)¶ÄN+µÏn×½S_÷¨(/<0[ž¼ŸÒ 01;a¿ŽÍ虘žÜì b{b4AäÐì7Ow…•ÝäNqÉžò Ô``i3FN`ÏZþIïNž‚d*ÙÉ3ñŸsªU,šæoë<¹eØ®à}ÈWâží[ÕXŸUQ*oj=|½•ð㇤–¬açÁŸûtç„ÝD¬¾«¥4Áê.XÝ$NZý&6éER2 úªËŒ_ ¡pxI¤óŽõ#²}ô‰ïNÒ'[Ÿt1Iê©%`ÖÃ-q¶úu@¾lfa8¶¦·Ãô³¬q,^ÑðŒ»*Ô& g¶:êh ÖËè}¼¯óW2 ¦ù2¿LDj­²Qœý X-‰]WêpvÃ]ÑènÞÙšÒÚØ‹èŽ„§Ø^]utõ„Å#lÖ`)j{FÈáw6­×vB*VÂþw§8G‹tUŒ…öŸ:ߌ™Ì÷Ÿ¼õØØ ›‹Ê¯ç 8Ÿ*§¬õh ²Ùc´Mòo4ÔIõñåˆì\fUIBáðÖœí+>y;âöIÚeœM$iw¹w‚ß'i×óúäg»G ŸM‹åš¿Í&NÊDè·Ybð×jg`__¨ªèo˜ÅhO"88WœˆªÜð<¾€^Áà9ª Ìñ[㒮đ >Äq)‰A/ÁA“¿Õ#ÑCÞ¬—þÒ îd§ßÁmå.71)eKò½3·Žš9Ï&•EÊýé ² ì*fm{Ý]=jÕ¿C¬?]½5ßIã­wôðÄùÒL‰l$̰ç<³|rs³²rs|²<=|}=åš¿€Ñ PˆKñÜë„o¿êQlç¶Ëw»_l`B°ü*#”"K7. ”[‰~†Mšü½Oª ì$mõ6¥?7Î>Š´jÛ΂Wüïà?­Fw-‡¢«Uï™^qØ[,È!ÊRB¢ÛàØ.ª_q-œæ Á·Œå‡‚Lô-ÈÄ €~œ«§—‹Kî΢¢œœ¢b¯W"Ox8)*¹`.7pÆ&î¦È\b™ïR[|2ûLBTBèq¹1s(Eq¨æô¹†‰ CuüËZQy7œýQ ùÊE£Gˆí½»± ÆÀ˜n7xëQ8h<<…+ÌØ_§E“š.‹ý郙F+§{>~§bÇ£˜Ñ¡HÇ}·¯§í3èúDf4²Í¨Ëø2Ç h;§ƒË5~4êM‡˜×P’ι[5—^ ßbÿðú¦ù¹ì—XÄáË u"´®\†5÷E¯/CÐsñkAJ;Ù̘ÜÃ%¤P(n8ŒÕ76Ôóõ‰‰óU8>>p8,:é¸íöÝacÃ[˜÷ö%pÀ̽uÝ]"C¶)ÀÎÝ'ëNP³%Waîò&ÜÕ¶‚6tIrѽØÁe÷.÷à˜àø ù5æp GaÈaçzks ÔútšÏÇiWÿ:MM+xÓ .Í¢ó/ Š´¦Ê>ä'âùÇK°á+,‚áðÙ¯ÿ&Ÿ²™]¸¿™ÙGy>¬|Ó ³Q´ú’àz|ƒ+Ï;—Ü„$ZŒÇŽ2]4OÏê{˜ueÎxçœÉ¿¿'½UëÀoÖ–™ÝÐYÈÊÕ2)]4´1øÁ‡tgƒGJ]õ‹ÿ ü«:iUÑÜÈóÇÚ2[¸ËÓ•ZW£ë’ë.ܸSg·ÐÚËÖÆM^áÇÝ--o#ã/ß",Þ»÷oÞ³ïëØ} öTxÖÁtbù«Š›ª½N;D…£¯Bm¬¦ Òjã˜Ê~ýÑ€¾õ}íÏendstream endobj 69 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4792 >> stream xœÍXiX×¶­¶©AEÚÓ­à€Ê  **¨‚APDeˆçDŽÆhD1¶3ÄD jGÔ @D¤ÁF¤%i•Äswõ=ͽïTãóæ¾ï¾ï{?ðuU®ª³ÏÚ{¯µʨ%‘HÎ]žºtÍêÐØ´‡„Ä5âØÐ58íïnºK‘±j‘eÕf0Ü´f %þÍL[èµrVz¤·OÆìÕ¾™~kæ¬õÏŠý8{i@N\`nüÜ„ eÁ‰ó’B–‡&Ï_–žºàÙ¸>ö¿9ìsŒq?a³‹«ÛÞ‰“&»ÛN™êñ•Ýв¡‚(wÊ– ¦FPó¨©ÔHjJ¦æSvT5† §ÆR ¨qÔBÊ‹²§"¨Y”IySŽÔ"ʇr¢fSã)_jåG9Ss(ÊŸr¥>¦Ü¨j"HM¢æR“©»”1•J  îS&ÔJÊ”šA ¤Ì(s*š’Qƒ(ž² ²(Kj0eE ¡Œ(kj(%§–S}©~T0Š M¡r©%>’|Éë>}2ú”ôi––N“ÉŒŒ6U=0úíB/£ƉcÊ™:Ö‚]Êîg+9Sn ·{Ów\ßô¾º~Kûëß·¿}ÿâþÆRcWãLã|ã3Œø xibfg²ÑÔÔt¤é$S?ÓHÓLÓ;¦/Lÿ10v ÚÌÄl¹ÙIsÞ|¦yµÌI¶WV"{"ÃÜ¥*„Ó&:'¤„E*a¼R"¤ÁJ¾ ¯¤»¼W—JccèI¥ÿ`ša% _©x¼Žch§M„j¤B“”æ ÍžOà‹6KÙ Â^öƒþÈ(ge»Þðô^y\€ÿ³MÆvø_å‘ê-—ý¨a ³ê|È”ÖB?òh,ep0.ÃAPFcšmð>}?ÈyÜ€Eø ,#>©†]jX§6oÑB‹v®ÖR&´X€š©G——•s²wÅ¥Ê+7† M\µc1'î>{õáTU‘p&álÄ7>ˆÃ•Œßçaø±WPÑ–Ù'³¾NEq(>/eUVFvÚ–ä&?ü”‡]Å^Dßm8ºš¼ùhæþ‰CPÒ§+Öd®Yºa1â™Í‚}³¤¸ª;¤pB(æñhgì½560Fw¾ƒ0ǵSìðäŸ_÷ÄØtž‡“cH3ÈÀü†J«0Ñ-ËT ]jÉ%­T7V@|¸:©°+ƒ¦¥„Í™•h‹p?„KFÔ{_Ÿ÷ ý‚ÙèÕË£Æc6Gl\¾.-5(p¹‰z¤pàA`aø­k9+¿SœÊ8˜²/L §)a–J«2¿*æír‡¥¬ë*NãŸÀIæBXåê:Äõ3ÀTðvƒ>X¡½óF!+â¹Orøßj¦`3Üî”ñ Y—˼V0Ó›­…‰H-ÜQK•.•×u½¿þí.\QëýYÁO¨¡É:{oz¦†j¥Ï,à @ƒ²`-69Tà3Œ¶ÇšîÀ F<‹çâ€écðEoî¿PCžZÒ©•ÂÇÐÎ ÃÕúá'ŒWëwö¤ JµÞ‹1§¤:³•Û”æõd•–²úz±4o‹¥y‚EM‡+Ï<|b÷Í\;++Ù™·eÇë0´tÅ"NVÿ‚—¢„Ú›^«ñk2Ï0µ>¯'U˘Ÿ÷¦½¢6uHÁ„Ïë{ )0™0Ö½<¦*TÙ7óŽ­E V‘‘É^‹]+_pëÁm%œ ³ ¨›È?©}­Š9o{B1õ°ï7iGQ‰Õ¥ó§ëî§Íß)7ÑÎTÃçj8¥–\Ð ëÕR]„Àóø†;dd1Øbœ¶šéwªb‰|Ñ•´ÔÉïèŽ m qPÊ_0«Àµã©ÈÍÊ ‰šä³Ó[r8>Âã!â–’–_äÇÆÒ·t§3…±u’ö6)ì!¨¹ÁˆÉx„·ï/úaLxqj­R¹óËBy»áóõùŸ .qcA‰ðSV̬³KJó6­ãs¡éË.á·ku©Ž¸Ž•½Ó÷‡:GFÖÕ“úÚY±u…H¥ymìj›Ñd)Ó k-d¯…#“q;,ÔÇuNì¹»r¬·c]kCßÈeÚfTyª²žóbI¤½òê¹ÂIÉ9—Ši1¤^¥-¡l§÷ÀÃr ú#´˜9•ÎF)9ôV‘ì>˵€Eó¶&çfä¬\ž» q>ñíŠ ûYÜO5Ì@ÖÒæráBï2Å÷ —-ÀÑð~[½ýÁžÉŒÖÛ#'N Ø“iž3¯§?õNtï*Ç7KÊ;à@›Tø¾’ß´ý3´ qiŸ<©€Û¬Ö· óÓÖÄ'ÉW§oLݾ€{Âìù¹´H…¸¦ò•Š5,JZ»nÎfÜo]Îg+ÖÏÍH‰B¾œý½ ?ïU»zK¾;üäê«è:°óÔ_­Üœ›‘¹XÃTª½¨˜ýŹB,ßyc*AvÀ¼©.Nsƒ ˜Ü~ü«ÂPÛb°4‚\#Õ !ïsÑk½™ ¥G‰ja€^C¿3¤µüêÀµY"Àzµn½´®lùÓ©WÆ™G9Œf࿇Ñ`ÜVÌ‚Qæì¨D?Ž_y!ë»-ßå_ávÖñ{ºnÝ}‚8õ]_·íh{þv…îD-,Õ µRÁJ—Ããlƒq6Îr„eš–SU·-÷+€FПƒO±p²ÜÝœß`c€½mÈÁ;Ù¿â~Ýäà¨0p†@¶n”hÁí#øºª™³ÊoK÷|òËëÙì]vä"Î3:f†ÂÙÇ·AÕ&Duô(WÃ^µäW-<ë’ÙºÃCs]MiÆ#äøª(‚µì…pöYõ¢©SÃ9+ úÛf†ê*ê€Êf©0ž„0½³°Èg5sØÓí˜ÏùEYÌõU×Ð=ôSaÅ=.EÞ›–¬M[“²$g!J@Ë 2¿Í>¸ùëm§¹‰Ì^»æ`0E*tÿÄ™òs—ÞC`Ê þ,Îä;«§cKl6Ýeü|ƒÝ¸®zö?!Ö­ÊçšëyŽ€µ":lŽxùý7ÌÔ|sö–ü+cáú0pIVòæd…Fü d'pê&Èû:dx…ÍUü·O«´¡ØDiƒ¡ýÛˆE â©S›Ö)åÇs 2Ð2®×(j®œ¹8óãH9|÷^U*DÃ'Ñj#û\ ¾m ÓV7A‘ïs Õ ècLÒñ-'·wåƒqvñ´3ês?\Fm˜O«Ç¶rüÌaFÄÍ­!†ï»ÍDzN¬=Œb8·˜x;¹ d0_¿3¿÷d2q²õ0–de²þH#k×¥M²y"úNÙk•¤A+HHUj…ý|>ØŽiÃÓHÞ\íÜñ`çŠÐ— ˜³è·ÕåËPˆŠ_—²&-+zC0š†Â'•§ÿéÙ‰òïð;SWåû$¤¨ý¢¬(®,;]‹î¢ÎÐ{v§ðÇ•ƒ]ޝ(D×¹‡µ•¿Wn¿CŒ§5ê Þ(¥¢ÙÖw± rs~ŽÐŽ\¹7[°ýËüˆ{^Yú‹B7€…X£É6mŒÁÌèXµ¾&„ù75›ÕúzwØÒc­íÕK±ço’v.ˆ˜œ%ÌãVðÁ%ô['ÃKâ&çÐÜ3hƒSÕÉ•’v-‘x©P)ªç^vŒwîsàD’<±0·]ㄽŽdÛýé3a:ôy£äÂ^Öµ8aÝ)Ø“‡'õ¤Ð}¿j»ÉÖÃŽÁ‹õ=8Yè¡G3plB Tú—-Gºøg);oØuœ­š•5=ºv»îÎÙ?9îÄËÛÅñsÄKá#öyØ•1>±kƒ#å)×cû"½jq';ÿ5ù»woºuH"°eðý3@>€\¾wO~u¯Þù4š«Û ˜4ÃcøòÿÌ’P÷¾mºHÛª0n·¤£›·­ÉaÑìõYQÛ¹¶áìŧ 0=NþQ #QnÁ½I ‡2yÂemª=`ÆtuÉ]üAWŸ0ÿI”mŠÝj£§²Žm:¿9Å{ðþ-ûwïÙ¹YÊË\•™’‘µûXŒbÓ®µKN?ºµ Y=ª(¾Qžv"bóV´=¨ÃSØò@òl’B ÔòxÓ,Ø$J8*Ü$#ú»³„»Ö$…P².[Üjì]%š°9éÉ¡K¼%K©‹ f)‡”8ÞØ³‘¾ÆÀFÝÆ÷å¢RIÎwBI§ uü”¶,2:0ÓÞàÊ7·bØÃX5¡ë<¯ù-êgù²ªàB"F/*ÆËí0Æ1êw‡ðŠ/ziVû5RØ/ìäõ;5ºˆyl –d­ÃCs¹ÒuÄh^ÕH_‘xþ1³æï3E÷:„r"àîRá‹^ß—Ù{óû’ŽË¯®þãêåFBL·V_‹--]𭚀üVÄe$lˆÙ>‹Ó0_\Ú]´ÿرó?¬F\kMÈôÐäE‰ §ØnÒ¿Íx¼•òÞý=l6³;-eí° Tü>¦d-«ïªŠ™èX,—½ì1[ü>†Á°ß;o‰»å^&Çì#6]Š™='2fæÌÈ ÷ë*/ž:n DKÊòê8$$óê;¾N®sÝ&†ßzÑYSûXœ.K ¡uàU'rt¼'“„ÒØŒ)†…ôt&Q¼à “‚½hÌø¾fp"ýˆ –HÃÀ¿^ô­³aNƒý'Ù ;ûò†û͘ïɈ\ ¾[}Á$÷ŒpÄÈÀ3¾“’ïV*GmpýÿÆ®AÚð¦ABøþO^Ÿí#d3#zbE®ê–\ÒÖS0\XÅw/bóo,<ó%WÊmKŽBÓ¸Q,ì²øãäi‘NKaá“ÑØ2û#<aç»Øÿ!±kŒ ØFÂ4®\*ÁC6ÜûÇ`Öc©'ñ¯Àò.ø#˜€À9üGƒ%7ŸÑ`ÛJb©0)g—Hìá‚Écõ_0•fendstream endobj 70 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3620 >> stream xœ•W TSY¶}x‰ŠŠ<CÛÞç者K-±K­r¨r@ËË -Ñ2‰ÌaH$2¹a!!`Â(!€"ÎÕåP¥¸TJ‚Z‚ú«ÕvèR»µï«é¿þMWwÿ¿ÖOV²Ö{¹ïÜs÷ÞgŸå8‚.ëÖ¯—…¯‹š;gÖçáa{m÷&B¬à~]í ³£ù·ãë]Ñã_»ìBÙ^SeÛÃå‘Ѝè51±b‰Jº×ß'`c`PðæÐ°}3f}øõl¯?,úàÓÅK(ʇZHm¤¾¤6Q›©-ÔVj5ò¥¶SŸSË©¯¨ÔJj5‡ò¦æR«©5Ô”µŽZOm œ©±Ô8jåB±”;5‘¢©I 8jIšr¤Òã›÷Flñƒƒ¿ÃwŽ^ŽqŽwœv;ݧ×Ó7…3„•"J$}?rê(§Q™£^ŒÎsžä,3fÌÎ1ê1Æ1—Çü÷Ø ±Ïǽ?î[—Í.FT7–7B+j²®´ºþ¹Ç¯'°çO=îL_ØÈ6†k• Éè¿mk]¸Y¥Tfu…&µhïÄ´2<30𨦘cnšqS¹Öô]ƒfÓLUÉQ­¹Q¦UrAh!ýäFCÛ)]ä6€ƒ÷ •2²²VS¡it1YÅÙ3àÅVŸN6ݧU=QÎ;àTBlÈMî:N¦ 3¤5Ü& 9\<^i¬àðZ©P%Ë ¨Ö”rÌ¡iC5É /áYßÝK—yû´÷KäZS­Ip·(8H¾pÏöÂŽ(fL/ ƒ"‰F¡àf •Z™¹°Ö§ÂÎdV’æûÏ3ýš:i ß÷ ®Û÷EîìX.Þ«QÄÍÖÉ1P´¶áP4š)4ÔÃ’ÊãðÌi7$zX¾Dh¯¸j¢ä»8ŽžzË¿««ûäÓ¾“¯²°+j'õëGª7/´°æ}Úxˆ®Ó攢½`˜ÈÌØfÎ,úL-óÖTWT,´³0¬¤Í8žÚÑÕh)0ÖÆO‘W¦)ØA—Vk‡ªEÙÚ_±ÓyñË!žðÑ¡j|Ù+ž>t…ŽZI / 5¯á×ç4˜¦VLÏÄ 3QƒS1=„=TÌå4:äo‚&èyVj‹Ñô“G¹}y_ôV+ÑàR«+3‡Ïãßc³bv¤£ådJ‰³Ðb¬QZ•7Ò  gŒû#ü1ë±i,´±Jk6GdEq䑘ð̠ಌZâu—pgŽ<'î$ô<só‹¯W<õ°àô±e=ô<s 9•—P§GmYN=7@Í)«ëibrÞ@X!^%KÌÎNH,üqë#ÎR-\¼s.Ø3Wh7%éOpÓœa.1¬íÏAMÈ‘.±)EnSŠ£…¾z>·ä$ ?E¦*C]Ÿ'¡Viü¹E‘bøÅì³eOñH€eCôŠcø!ÛŒÚ&- Íê|òœèû+éúy`&Š|Nÿܼn§->Vt¢Y–N´ºÓµêÇàîœîGŒ?º3(>Ÿwc+b6ªý4a»€JR¼Šf|¾ÔKr8ôp,w >%†Ã°Â¨‚DóB½j\£þ×Ûµ„··í,Êó¾Õ`žØ8ŠVÑ*“ž`HÖiJ!„ÙÚƒYyú”cûI“zfí|RR•PÉÎÓgë² "ÊSuPTV¥¯çðL±Û÷JýSDíô?~ú\SÓ©Ó±÷ÿ••¬œMF7õìæ–âüêgÔÀ›PÔýw¸´<»®‡ÀŽ·Hl Z d¦ö‹‘¯ÑÜ+þ—ðòÿw$:¹ˆœ\‘Ñ^$…ïùÝýÍe–­‹ÙöÄ€PIlÄFÞÜ„G ã²¹¯±0s0à ÙÚÈŠÐÐÈȰЊÈcÇ**Ž»Ô+­h³‰¬‚³woßÕß­¸ëÀËжžØHÒ,Ï[lXlðð×ÕÂ㢶“'Úß–xÉrANÄ¡Ôòþ)±ÂRMM "%1"HkvèĶiié"/ï6ï‡ 9Ê+Óï¨à§ž;¥Û–GîÉ1‚=ÕM±¦Lsd/™ ‚ôÖ>, Šª @sÄÅÄËÄ[GÝ~üdˆWVÁ»[¨ä–Ÿ×‚œÆ­FŽïœjí'5ïË"v:­”ªíc/)ûqNè®ÍÐ÷‚µC#Ts¯X:l š>ä»ÒôÍko°G˜&~pFÂÁ=¬Ñ‡ôË0:üá°Aut¯vÝ9hÈ.þØñêÖ«wæ _ÚÈÖ)sR d¢‘†û«Cd ®F~8 Ê ü@”JÄÜ7¦*µª‰av¾CJÓI·k*ÓCì²yHH{®‹Ï äÐ'BæÌOõ­–Ò‚øÍ‡ c4Êt*"”€Û}ëâúÖýÔÐÚX–ß·*vpU±mUÿy_Å õÐúX’?pàÐe¶EªMØ ¹ÓzM³D¢‘’+wì&L”j$’fžCnØNÔJ[Z´Íz€Ü‘›P߬m±EC%ÄR‚\¥‡ºJ,‚h’mC“ЃlKHuX,­“5¯ª¯·÷Ôy¶(xäÿÅ'æW}¬€þ°FU™""9.! `ë?¼RTšL˜êmˆ-¯,(9| ë¯^ùmÌó´“óØÊ3ä¼íDiihwÇÞègÚ’R(%š“ô̄h‰ßxH„ßÀh‘¿.Å PòÜmC›ü-1ôùs,çûøFõØÇÂâm49Û%'{ñ!/kešbu=÷¹uÃ7kÈ8âÅïCÛY$üè1vðóÛ*¥È¹§ã<õéyi™©0Q^u0÷jL¥ g.MÁ¿!ï1x7NFôò_8æK¢±Ä¶?ݰmOPÛw*J&g¨]ü®õfç™ Þ i4´ùîwÐÜøœã¿£`Q×…"»K— ¦£µãù8 Pþ{ÏÅÛÅ?]tbÓÙsÇ/ß(ú…yrL> stream xœ•UiPTÙ~Ýô{¼™ÑVh[iºQ\qÄÑÑ(:.ì.¬‚¨Tš%ÐÀ@hÙ‚—±‘ihÙÅÅušŽ`ǸŒJÊ¥LQ™š„D“óð¶S¹ˆK¥*Uy¿Þ»÷¾sÏùÎ÷O@‰„”@ ˜°v{ÂÖ´ÔèÄÕs<’Ô1«4Ñj~Ýá¤7ÎC 4c…ƈ ŸRc .6ãºÇSüóybRrJª&mUzFôÖÌ_gŬUÅÆmÛ¯N~áJQë¨@*ˆ ¡B©0JI¹PáÔzʃò¤"(/*’ò¦æR>”/åG­¢ü©ÕÔj-•@¥ÆQŽ$)JDŽ]HJÁOÂåÂba½ðšð­Õ%‘T)êaZIïfDLó£õlëPëëv2«cÛØ.8&æ¹… J4Úr©à2IÒ >\«[[ZipbnÁUZÒ×o0]éuø®)9rg±vwšÂÿß|¿”ÕêjPìqÐ÷óÝÃ’Âä’/kúiU"‘ œ¡œ­¸yÜEéT4osàב«Õ3ÐB‹Ÿ.; žŸ{rSÞÑÝò7ôŒ…ñ‹`GyIož‰òŠÐ*S£ê(u8b×Å´ÿ’¯_*HxœhrÅßÉ\>‰·ø¬¼ðm ŸÛ 8yhݹ¤;H É-n¿Ç“ýB£`¥‘vžØäƒ%î˜Z¨ÜÖ~lïð‰,#p؃‚À!9ô7¡–¬ì7\9ÛïP*KjŠŽÂ»‚Ò]h7 @Ñ=X‰Sý?Ií¦ÑÚmA³Àf:ã$É÷„JËjJ÷£ìËflûµ_ºj‹|‹*)m@!gc^$>J±“ vgTåkìã·hÖnSWüF®Õ(©g±#S”]RˆòѦæRÎh:òº Ëê‡ 7bÎ,nTÌ>²¾Z[‰Œ²–“‡LrÉMóñŒøÂ’ÝÅù 1<Ó¹€Á ̰âæsMÒeÌ1˜FÀÔxíÃd¸Ò}Œ7~Z¤-Ö¢²Ð6õ7ì©8"7þ¬-.(ÉE2Mveõ^¾Ì è‚úGf¤Çœ§Qð\¬¸ÓÁškåúâ²–„‡û#Ù†ß4]:H~©WÜÇüÖR˘Ýßg¢LÙÒká/îuîé”gûÒb8†ŒCÞF'JbÏ}›@ƒ ¹ÃDÚQdÀ?&B'~&ƒ×[ œ‚½G:#ª9½þÈ4/²ˆiNŒ§Zã¯,â]œ˜_låÛ8•%Üø½–ñ¶é2¡èrpö†)“$}\ƒAšm(¬BÕ¨¼tŸ®¢Lv’²]µÞ5gžÔÔÆ7E轞‡–'á‰,Lb æcÆÄ^©Û™®MËÈSdä"ä™”oY«U§)U;Ö¢uHU£jNmL?‘w]C—êot²’Á¢l´ëwö(OW¸7—…9  ÒL·È(_ÄF¦Žw´¿u@q¹âÛ=•º}¥e¥²º=¥ú}ì{…ÁR{!¯€¦:eðCs{|øê@ïhü úm¨‰hÙvj«9ã)úùÁ9°g±=£öÚ‘FÔŸx¢ÏTu½á;Å‘ë­Mft5æT¥WdërJcEhèZÀÝ%I[ܘTLÓ cðsÜË¿r¡LÐ4>ÌÀSè¥?†ïŸâ¬‰6˜K&8!j(Ök:£}‘l r‹ _á•8¹±Øö¶Û«^S£é¢<–³%nöƶî<€ÛÛïÂXàŸâ¡Ø2]åû1…Á‹‡rzú±§0`Å!Ôb¤a&3Š•ã|Jàê!íâ»ÉÝt©¾½ü:.fu$Škjð@ËÐRõƈ¿(Ù ¶l`ì`X™åXÎd¨6§D"6XÕjÞ*öQ@þ€'3û[*jª -mµmè$jΪJÚ—­ËEñ, D> ~z%à–‘±°˜Ñ›Ê›«6"Y%Ú[r¸¨îµ]´.«4ÍBÊè W­¿Ý ~X> stream xœMUyPWïa¦ûµŠalÀ#3AÁ[£±6Q0”rƒ€È) ‚ "xÈ%2 ‚ê¢ G¹DPÑDAwƒ¢Æ#k5!šäk|¤jßP»Uéï¿®¯Þwý #Óa$‰ží¶­±q¡±6‹l¢#C´¿fbý%²XWŠueå³øÓ øè±Þu}FûñÝ¿5(8$4Ì-Â#2jù †qf\SÆ•Y͸3Œ'ãÅØ0¶Ì:ÆŽ±g+Æ‘±f62NŒÀ1F´:#c˜ó}Iº¤CÇXç°Îé\i‰Œ‘9ÉZØYìnN‡sår¹¯‘ÊAï¡U.þ†ÛD‹¡Ï ^ƒ>l¹‘¢­Þp—\ÆÂt±¸¡à4æoÕF¬U‘4”œ˜ÉúCVòÊ;@*Hz–¸Ç‡¬SömFŠ»ÄÔ þ–¼¥©Þ™¬\|Ö%šuIAÉ ”‚FÌÈ233²˜,óÁrtÌÁÊâ²H•é% ¶¯#FÄ0À~­ÿ ÐvoP%38xK¸-i†yRñmµklQ,™š”´;}ïW x:±Xú8€Ý¿ÃÇ55©µªã å&ìXÍ­¯v(µÇsðŠÈ NŽá–Ø “i7‰ìýFÍÎ[‰Cø>¾WòM5/_èvXÓ bSø3ƒÿ€Âa–‘b¤ŠD PÁå´oÈK:ÎÂrt.³6ëæaÅ»÷°LV¾žíëä¢ê÷GŠ:2—Žw¼Žï™Á*FÀ ’xŽÎ–ÔVa~¤ÃÙ„èºØXíÝs$?N%_â>±ãº¤U̕޳ˆÝ RÿY^ÂÂ޼ïa=Ä\ð²EûÉÔÔd–qðNìf{\\…Ûà9L±l¢§Ó3RÜ­3„º6n]^½Jª/¯.Rã:\™RËwr¥ Œ/Ž/ˆÇÓã´ìÃÙA;ƒ#ÂCò~3ÞÌ)É<ÚòÐÄż´sOéM¯I®€L…ÉRQ%F Þ'|Žú`žèÙl°v¾¸íA˜j8¤;{ò‘ÑžQÑ…Çw)S‹Sž±NÄœ»™Ð“v…îGø×Àè[­e‹Ê¥.â¾Ì7ÖViªN¥§V*KRŽ­aû99|ȸ¿ô¿¯<}éSÑR ­{çì¸W•X›~7ãÎcý§ø+hoÆž¬Ý˜ÿ2¡fPGÀ¼Ÿ˜ƒþ´iÎÚ­l(]Ç›CÏ>o¥—ÎT¼ PþR» ¬Ô‚möf6ä6ÉEµºÿØÕYÕ|K©ˆó×6´I rÑa "ŸLä !…&u{tzìLû]ç‡Up‹>Ü|¨¨µ<;`F—¤ Œá øH ¯{…R7ì[9¯ü%¦ùiˆ 1¶vq‹Q§žU¾ú‰;™Wv¤ ówêvت¢ õ[¸ÄÑíù]wwUË€²Y²wGê.Ìo‰®k¿ÓU“k("dw‹ÒaXr©¶B2BG RX6¶W æ~lÈÐ_&”rYEXÓ¿Ã׎6ªßµ÷<ÃÀó0så+Âø%Ey*áúk­ > êüÊÜ“˜ÕåD8bäáD”‚sRh¡˜´‡âTäÌ’Š!m òòK Äüb§AÐîÆÐ½Â£ÙYÇT³ÑÉåéñ-uu—nl¼bJæÆ„,$f?ϳ'/ Ð×~¤{je×`am¼fÀNKÅéc&Y #sc(~Î6!ÖÄôñ|u\­ºÜ«rçVä—¬fÇ>¥w° PD÷Ç»…£Ó{¯ô¾ 2˜Ò7ô}euFj­SyhœºàãZcxƒ‘T<ú‚k˜ç~/Ì›oüP¦¡‚G.À…¸€ÓÏSM15ý„," Þ΋{÷*.}£$†P,w.÷yóÕ~Ì÷4®ÌÄ_áL•~Âí¢¬b4’ŸAOJ%±ª[ŸŸH¹5 3úÉŒ~„siÁJ;jjßX_,­8…kù–ð³®AÉÑaJ{ïí¶xc”qèmò+JNôÉ`åcVXÙ½PÖ+ù Á L¤õ”ô¾¨/CÌŽŸE‰‰.¬/\Ð §üD5 ñ¨€ÎGqM`ýBõæ"ÿÎàê}[p=>Ÿ{!Ÿ#gÒX£Êöô컚ÖÙ×Q¾¹ØÊ¾ëøÒÕýd‰ÒÜMhçÞtlYµÄ{«IÊAœs€Nyª?CÏõ, ~€yD¥e1¬Û&Eî 8Õt¹¡¾­9ªÁ_¥xYLöQ2ÑݙРO­”µ!w­äˆë(U~Åñf¯Ra¦T=!fw©˜©KYÐoæµ³ujc~‚š›A•8aÂÞ;ª½¸UüÒwbáU†PÙʹ$QXX ²€Òshü{”œìšÎÊ?èÓ¾¥a/&\ˆ*µ½¶ñ¥b–h#Ä´Wûà¼)Î!˜×:ÒÈDÏ·ÿïHæµõîÖPr¦ ó5ÛíT$%'iRZ‘¾6a+9SHíïNÍö5³¿ì¿Ûß–žÅJÅÒ0ì¿z u‘áÈ ðx(ήÀK˜$[%'ãVìg0@¶Á$ØìCŠֈL"J4ººá7áß £Bò5Õ˜ 0–Šcþ)É&Ÿ’`r”'®o ‹ÀâÏQ0ŲWd’»×þí>ÊÓ`ñä)»œiLšI»pîÄ?^¤NÓél1ÇÏÉñ3ßG`Y”S™sV%OT‹ Çá ug×5äS°î$†ù/è5Hendstream endobj 73 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5912 >> stream xœYX×Úž¥ÌŽXa)š™D£&±k4hÔQ5€¢¨`C*K[ÊÒû¡ƒôÞ‹"FìX±,ÑÄÕ¨‰I4‰bÔMnôÿ&9ÜçùÏ¹y..ìž™Ù9_y¿÷ý¾QBèQ‰ÄxµƒC€ÀœÙ3=app‚°ÒÁ|´r ¥þ±µöß°éýËe¶AÁ+CìBöËw¬ßé±kÇÚÝë<½÷89û¬÷õÛµvÔÁÑÍc^sÕxºñ“9&çÙ7Y¯±cÆ®[4VÅäærNœœkå^Ž‹wËtéfÞfwÍטf1Õ¢Þâ×ñÞãë'XOHŸðékÜk[^«‡ý£Ä¤ü])¾&i„µ?ÁZ}1©…CÅÉûbr’²BPÂ#Å*³øCŠ _ä"Q¼ÙWm¦@Á()-6))E3~ ¨œÿ®¨C-­aÈS¨ýÝе“ =ï_ª~£ËP‹€—ÀF›ÑŸÂg†š¡Gé¬4ùYÎ*Sö¸XеÊP$ïQô¯.^é¶G.çYU*ÝÉÛБ2r»T"Ç=îºÌ£KÈÝÕßÜa9Í6?¿}è̹’€µ<Û%Õ\ר¾n†æ:A³³¨Pš4‚¶p°&Ÿfƒƒ){KL$6¢(>˜Æo@B°a ]ª¾?9*L¢£dÈÏ·Õ Ëð”¥0Űªµ¶È´§É©T*ÔÒ0‡`s\nB³Õ‘AÄ‚zrœMý,57 BÁÂcØ`Ȧ>Ãäo|pHÿ5¿k6S™¤„/•’‹*¨W鋞àËñÌgØÌ| cöÇé z?þ&¼m7ÓÁÊÚÚáΓ®]»ùùUûÙü€—“¯gŠ_rdÏH¾ßT'LıŠ3‹À2®Ú¼®Fç„út*ªix _6Ä«dÒÁc0œ.­×X)È` Sá²aµæ˜ÚâX¥˜¯”VÁe²¥sûƒPl|0òOãß^´1³ç¿„wàí/{¯\غ¨DÈŠÈŒlAL;ª®@–¡z¿ðä¸Äd>-¥E˼›¶VmD æˆÛدòã€ù¾÷‘zC,SÂ,%\×¢è˜ ^'82£ÔÁ=÷—76»…ûîáÙgÍi%¯¨¯é¿hݹýh|b@òóÀ ¶ã¦-·_¾Äëá)þ–”5¹|éÜ'·/Ù¼Ëë¶¿­ñ¹–ø|;kÃì*ž§+QÍ/áÁïmÞÑàH¼0˜<³xÌÓw@ïú‰ŽÚjû¸‰íûÚ8â¹â8ÎÑuáBkûßP}}çøR;m:!D îšz1UWm!¾þ)¦wr½RíV¡a¼-®‚0•î@‘íPM%ÿ¤ÿ\䛂;ÍvBÚZŽB¨cN‹Ñþ6j¥ÿyE=Mt«³s_SÏnñɨFãoÑeõ¨Ux•û¹S¢¨!°<¤+ ú˜²>4HÐå¡¢‘RR›îÁ&}1U|SBc˜N§4DŸˆé ÿ$µÐ Å Ɔ¤&îÄ|J“N»ÀÃ.­H#¹0ðõj²ÉÜ›œu™FYÊú‡%Y5LãÒ‡e'ET "Բʲk®@¯YKµ6”šìÝTšœVA$!#¹XF2Gdd{\NV¾Ò›ë¿Åon›Œlüª#ëJ› :2x”Ÿ‘Q•Y’QŒ óÅYße^žŠGoBÓ6Ööûß:zòZOò¬•oÍ©ôC㛈2‘¾á_i8Bw…3lq„§Jï°ãÀÇ]ßwÀäìAb"zîŠÁõy[ ®¦ì—ƒb¾“Æca>E3øÕ°a@±†µmÃaŒð[x žo¸“fëÃ0mBC‘¯ð=ŒîÅ£ DœœSïÒ_Æ·•`¨”ÖÎ%˜û‹6ý¸/—C¡„³ªêùТ¡JÔj‰ ’Ô{¨5ŠÐ@X(Ñ„$QÑ-Õ¹½@‡¾Ž>ÅnÝJAP=–+×€‰»Rܬ4i€Mxå=°…M¦¬ÅÃù‡xOôî¤ðD_ót:¹2¾:±r&$šÕÿ=è[i˜ˆÿÈŽC©™#${/Zư‰þΞiQé Ê)(X«úð ÏݸýÀήçÇÁ¬0[€YâfÖ!ü¡æì[*êÕwƒ„kòGI‘qia‰|R´|‹5b|xã‡SM¤¤ÆWŒâ… ¯JEbêªË›oMBnØj-ž0x:L@8ðKy?š*¡Lir±{[÷×Ý0¼™²µb6AS(òáE…´M]ì|5Xx'¢0)ŠøÀ•ØÍ,Æ3Þ?ÉŸT[ÜÉyP”–W'C Ä8i"%°Í¤ÜÚø>…ÔG6G þžÖö3íÍ3¤…[¯bçìèüàbœÄÜ„¢Ä"TŒJòóK²r¿ƒÜ¢sLF_ ­¾…¶«Œ»7M!HºTÐI`ÐÉ]Òµ¸F × «º*# •›Ar?¡½¼…­ÒA!l€L)¾†»BÃÒSQ„ùžTÉ‹£éš\T…J™¢¿®†ôPÖŽÖ±¶˜û7¬=—önÞQ¶H£dé‚6 yôÎËî#ÍM<»Æ)óýgÂ{Ûîäf¹tÙÚ›½?ݸvãj—“³æOº!´[_Lèiß*Cé4^-¦ÆìÊÚ‹ÌW Ñ/µB ®^(1 ƒ†Õ}©Å^eé ȼ¥(ë æÖKu CW¾¸c•&ì^qW?ÈÂRå‰|ÈÆõñÈ YŽüž3tu%êzÕ/x>m*-°xÔ¯S€³“êùe0‘ÕtÉ­Ën ³¨GVð&3Ø7w« ‘dÍ .qp$´ ;`‡Ð½ø(>R½`uM#ám 8䀖Ůu ‹æ!YuÌé˜3躀zÐõÂÅ—[‹î¡;¨=¾Ô¹h ±l 3 0& ±Zõó}ÑN<Ï]yE¾¿të»ü†©º6áWÜ3eˆÖÕé4q ôÀ¨!Õ<ê$}÷3Ô§ìj¯ª-kêo*V+!UÃuiÄ•`ÑŠ{býKyüßLàt{øÁjÒsëÑBu¶ÙNã߀ԗôOGm7hH)ü X_¼p>¸âwŤù’\娂•ªÀK)ª.™²c(1W4ãjå­ëc]Ó÷låY#ª0Ò«rëøˬl+÷.• ¬„ŠŒñ³@^%²‚Â:c¬ÝЊX‹ù/ÖÀXû¢ç;žµ~u„ŸÞØ·½fb–Ó (%dF¡$S°ccKÒkÊÎ,ÉÞ—•v(¸ 1o}Þ+°s­PK|sDSuQ]vqFîÞÚÄ}ˆ)¯-jðJ¬Ï9º»»¬ß~òÏ^˹xìØÙóG¶là˜s·Ú6uªÕÑcmmU|}Yº…˜^0DóûËúú€ˆ8“Àþý  kþFKÿ0)ÿs²¶7!]¢j»ªŠ¨übå® v¤õKçÒvG ç>Aùñµ|Lspµ¢a_|ÚQ©ì´øþƒ{؈ÇËÿ·>Ñû.é][P[ÃþYŠB¶[ {äWéSî×y1ŸÔ}zˆLGð/ÎÕí£Ùü‡àý9Íö>>¶nó óÝ~n{žÛ+‰põkÿÄ.O‚lC܃GAá)mWÇÎÆÅ®)¤& $$  &¤©©¦FnM‘šœ½f¯:©AåqÍ”õ}a‡®z‰)ÞqxoÞ’ŠEfÛ‹<ÚÑIæLש›`T:Ã7—Ï )LªrÍ´ÓBr„_¿£}}‘¡D}«Å Vž°»$€t¯![Ú”t?ì] —më¸f7îä·7¦I¯H/O¯ðé°™fr¨É-i+àû)#¯’ùüa¯®ÃýLõ˜üÓ“‡LMãµto££ûs`Þ§p2…ZŸHWlöꌤ%’á„HÁf§n'MGÚh_¿ `4H Û‡ôÒ3‡t4^€§ ­9ö::îêS¸†Ìp®ßÐ_߆áx–öi’5Fƒ-8I ¡›;*ˆ%ž–‹wÕDúynÛà§ôëv..ìÏþO[¤ä«­-Ë^¹êG?˜õüùƒÇ0š‡g-Ò¿™<û‡$jÂÆØSôáY=§Üõ±ûÎ`?fÙþܼŒÌ<>ÊaKdLJ\jx2 c¢J#ÊÛ~;z¼Î~…J.lçþX¥Å1Y­éÿž„§YÛ ¶¼jó‰ú˜~“Ö™z“þ‹iÆúp·‡ëðkðñùúîn l;TßÚªy&ô¾ú.Øìï"îþc*WU’Äãûÿ¶MŒLG(Á<¼4¢ª&¯´8—‡ûØæ•e ”o>Ø"Aëc’u‹°f2˜b=l0UódlÍoØôÀà9X€=o[Èá·ì±Ñ’%ö`oÁÕ³Û·n¼§jƒ§Õ¯~L»pͲŒxOÈBQ+ó¥¨>µÓ¹åH}éþŒz†ªG‡³ò+=ÌlGLnUnBør,‰ž!¤'¡M(€™#Ež(Ê3Ò3jSz0b’Â’‚üêÒ÷ é IÍ\ÏàERä‡ÜÎú ¾x 1d (®QJ&dbËšþúš-–Ój–”'ÅÄ$ó \båi‘é¡id#YEriegî¡c|ߢÙRd©5B &g{ Šý‰¤Š¾\C,àq<ÍŽ¹|æ§;G3ì“OºO\ýÚFL¹ƒGa£Å ìnŠ-¯®-o*J.ŽÏãKOœl½€˜{_n·Üõ#;gâ5ñ IÉHaî[Êx6Ó,3¡¿„–¤©%(#ŽÊÀz™iÝ ¼/EMè¸Kóæ†ÕÙ^ˆ‰ X™B¨‚O#ñóf0 þÎRŸ£ÁN>i[P ƒm¥ÈyâÉiš’-ËüXõM©‘‹N£&æ‘”ä¬ô`ÙÁÒSuÚÜhY2¯‚«ÒäXïÚÞâ^0Rí$‘ðƒÁ†C7·\¶ké>ØtgnÛ|†¥xÄòͶÞõŠ*µß%IûR³øÖÖ›êñüúiO7¿(¯½!‚O ,Í3Í1% !F]8ü šÝ÷ìÌÊÖ8­ž½siáÉ@!'' L¼Jå3÷爘~÷øI¿pPJñ5’èÛÝ=¤yO€ÍÚ\/ôþÄü=|„’ӣðÿiÒHq{$¶òƒ)‡!=ÃJ9u·ÿ©©M+‡e4Èà7CmZ•0_)y¨‚t’ _pä~]ú 6òrO ÙÁƒ#$yhV£¥4\) GÁmÙ9ûòùƶΊK$õÇmìß_¶ö½€Uùˆ‹ùyÄÅæà²Ð(¿ø]–ß.0~öôµèõ€A™MÎÝ\ö¤|åBâ~RôõÐóz±ž‹KÄ7¾Þxzï!:€Êbs’ÉO g‚*Âê«Ê[º<Ï¿C*ÚÄn8 lžñì#üò-Œ =ñ|;Çíwu)Ãø¸ºÌ:TÂô\9ýÅ7çVZ«÷ß*^RJŽ©.jZïþáß§“ÊÂQbö ¹°½_ú+›x(§±5^½ïEXQ ïöòòÂf>:`Ø(/WUdf’úñ¤„­O*gõƒnõÿÖL×¢éŽýeëê¯w¡‹Ì½wñp<â½Å‹Olú*goZ…®ZgeñΓy` &þÌ[ÂaÎÑÁ݆g÷Û8ï>Û}ê«»7»%øcÎÖÎÉ’g-íºUÊKŸüðøâê5ZþNJDA¼ÊeÜ“äÈ?6˽»›eDe…6rÊ©È(g°%lûç+´Ž,ì’ÔÝ]vÓ”}A’sƒ$¬¯šŽõ§X’°Óç‚ÞÙ³åÇù8ç.ˆ‰‘7ë¬h).®ð#õ²¿O}t/9ÚxìXecQQå^wµq¢×ªŒÎÍÇÁΠȟ¼â|Ti^+/ŠŒOMWðøÞŸ€äæˆ\¹/¾Çf%ñYé„bÊ*‹j5Yv¹qg„hµïFäKÏhÅn"œûÕÂù']´Ÿ'žnÐî­Õ?éor®CÝd=£K:úEU­Ý¨8¡0.fŠ‚ÔŒxÄDÊc‚åäh¢‡±&¿±‰c‚+cÊ ²2 Jx¸; r5f«M±&õc·žC¥‰ÙáExÌ·[Áz~°ø¡¬0/•2ùÉUþx6Ãxø‰9í›øs6wœ 7äTåk<:Hºj“`øÖG^§7ܲêBŒ,),!ª01'UK,)ÅóÉŒ3u7ðøÙQq É(ŠIÈ «o†mZü¨ØBñÃBXR˜]H+TÃy#ç€Ã•åf¨rª²sGŒ ¨ÿ‹gêendstream endobj 74 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1956 >> stream xœm”{TSÙÆïår“ËÈdt˜´¤º’±èR*N™ªƒÓ:ã‹ä!yú@HHxD 9ÈK^ `MÑ€ "ŠX[Q;>Gg©£Ö¶Óå¾Y‡®Õ›Ú™é=îµÎ9{ÿ¾ïÛ$akC$¹`þˆd•,yýöO¶¨"±‘Öâ"¼+,Z‹ŠFö²·mXĈ>„ù f>¸6Ÿ°ž‚RT[¼"¢|e~Ñþ±Û¥ ¥+A|NøÛ )ñb±žØD¸›‰•„'ñ)áE|FüŽXEø¾Ä„ûš°%ö}¤„L$›É76‰6Ê“j·u´UÛ~Ko¤»é·¼Pž‘ïÇO€6;…Ìì33¹Æ²›ºdqÊøUY` ø(îÌP{åÓ2Øoæ{•çja/d¼Æ™ïŠf¾7WÄŽ0ÙÐø§2ÚŒ£düÑ‚ò,ì…# ‘:ÝWä Ø¢¼³ìÊ.²iªf)hg÷ =‘o|˜4$@é<ÌÜøê7ÇŒ—.ˆ‡ÆLwÑ=ÞßrÇIœ%¼v&h9vù“«ü¢‡^‚Û4%–—wšuí%¯N¼¹KÁq–ž9ÚØˆZ˜ÎcÀŠu›?4'ŽîŸ‹3ªŒÙ H®iÎ7\̬É.W#‘"m¿"h æ·o|;¶×à×' ?ЈN3]­-ÝÕU…š*±k.³vç_èÉž‡¬eï C–­£•üñ2)>‘ŸpD…2E¾FåhçÎtCÜÎÌŽÓ¨™ÖÔ]]¢+i ž—óx ¯x´&ß±VK=ý/ëê¬ç†2ÕÞV¢…VÌ9Ú·ìPÝäsúÙf2‚­¢ ý§+›ð¿ð’” ®H”‡rŠÕ%9µŽà—ã/Než=ÔDà‚Ft‚ß °8Öé&ß=Ö”w]ØEÖÏP¬+›&ÜŸªÐ)*h9ò^xÀ}Í`›a¯Ùþþ–ËÃbTˆŽ B&øxò9ãÙšæq+?1ÿÀ჈‰ÎжkKš+:$§a“îvmU£/vûáú½»£ReH´-¾û>¸?[°++E¨Œ“MŸ7Ê:u´¥RO6> Ø‹Jˆ?‰§øOr÷áðÄš¤²D$ZƒÜC¤«â‚3|'ƒyƒ^÷‡/µˆ‹4Hƒò™ÐÆÔ>ùJ½µ¥&õp6b”jmKíÑã¥M’·ìKûã^aÀ.\±+`gB4Åö܃µ¯€ü®âØ‘¢J‰À²î Ë!êÁ¨Nr¦ÿYˆ«µj_±P77L_ák©ÓMX-ý.!nsñø[JŸä¸~‘7OÁÖsÜP°ç6P)4Áû£×¯ ÆÔ¬RlÝè‡h$±BØ\óýšeÆ"»¶†zÅïúËW£Õ\F·¼˜šj_ào“&ìDŒwäÀƒºâº£Z®ã`ίúȳ/Ùͯ)ÖÙòáR´,ØóSßµrgäÄ`w ±-¸ýð×ÁïnНþ¥ãïlÑ“¨oë†3ŽàÜ‹óšà­ß˜O2¶ ™A~ž'ÙÏ©Gÿ'¹V4Z3‹ôE:ÎÕþ`$¸LÈF¶5JÂëC‹¥ˆ Ý%Ôk‹k¹m#Wâù_a§luq±š›¤[3ÈÎ7Ôè90£‚‚–íBeJŠRqBÕj:y¢Õ”|2^²' ñò8:‰ÿ ËN=råˆv7¦ž7÷[­ßÆW䦤#F‘Qk(/>v´Zr‹}°§8a^÷’¯faÇŠ=fY,”ê+ƒÝ°½ÇDÔ?¥’IyoòfÜ¿ÞæSu\&έ­>Ä“c÷ËŠñ¬)n¶Ï€z‚Ù .ç>Éê®°ãhš¹=9öÜdÊÏ6‰k^N÷ðì8çܧgÉóìu‹Cé^ûóz ‹yÏÝüßU’­ö& ¿æUgv¥/ñZÁ™X\^cï›Éi˹…ôÜo(1”·IþÌ?®hɰ|d¨Ò“÷)Øg¹‹’cû4wÅ\vŽO~R‹BN¤ ´õVåØ*sSò3“^צ-1ë–üEÅå¥MgDËåü=zv©)éʇ¬ý=ð™ù¥C%lᘃª˜ƒÿaæš9úï:<££×‡OvêS£Õ…ªü8‰î£gx“ð¼ïÒÑŒDu©ê#išxÉìS *Lç”v¨ÜÛœ~ÑØ]­ùªüôB5bâÒÚëʚʒSàvìTi j Ƕ‡…ù(}׋‹®*ÛCP8òVüÞ»á{G´À<Òó¨Yà åI‰r¹1©½ÃhèèH4Ê%‚Œz6­ ¶Öö—òºÞ{8ÙÛÄ¿ûåendstream endobj 75 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5550 >> stream xœ­XiXS×Ö>s<Ž­Ð(Ñög­smõv°b­u@q¨È aLHÈ@ÈÌ&3!#ó$œ@­ÚZªÑZ‡·½¶jŸÖÛáúõvØÇ»½Ï÷í+Ü¡ÿ¾À¯“½×z÷Zïû®Ã!"8ÎÓo­_/ȼ0ÎÚ¼øŒÔÄà³g*x8ïá›\0" Œ|øÙqÂaÁh8ô©‹OÁÏÒW3«²VçDåæå ã Þ'îKJNÙ¿9uKÌÖŒ»fÍÞ3gnܼù/,X¸hñ’¥Ë&-ŸüâÊ?Íxž &‰MÄ"š˜Fl!¦1ÄVb±xx›XEÌ!v¯«‰(b ñ±–XH¼I,"KˆõÄb1‚Iü‰EÌçÂ1¤A­“ã;VšÅ‡*Ë-õVºþo¥V£ØøM™@#0¨ßVÐh yÆq¡žÔæ+€ž`*ÊÍuVºúËR³ÑÌü&Ó†‘Òl#Ž¿–Äɸɤ4ëqFìÒœÀî¡pŒ!Ž,ü6Œý~Í»öºÿ5ñf½•–JkŒÔ¬4Mª¯,»QH7Š|úëòCš J$²ôTqJA‚>ÈA Ȫ6™\^à£¼ŠºÒýÅÛgÁgKüM—JýçéOT(žk¸AÄûzÃØâÇ,’«SŠU´pw\| ¤Bk“ÍæCXνªÖ 4+I?gv#nÁJ©[œ©Î*6ÐÉh&wnyF¾Z¹;ŽÅ}]‡£š€°po ô²< ­I7J¦÷:C'^…uf>À̯Ùåµ@m ÷¢W5y)hê+€Ÿªjln¶=‡2ÎV`.ê|rSâÜÄKªÉìòšißź&Ü6³F¡Ð)5&ibáV°‡Zv.¥»µÕÕ|ˆ.Õçu€£ ¾Ñ]_Ýî<¬ÔïQ†Ãu=š8»glÄ}ÖñÚÕGSÅâB³’6©Je@C‰Qû¤©ÿp«»«ã±É굸*ǽ“ܾcöv4â@0˜»­ÂB×~ÚîñÊmSKŠK ê&â`ò ñöÝã]Úû \q ÞꀅÉòè„T´®@ºE(QI­ÕnÄÌèîCÈį*tIDŠÂb=~8ÍŒaDÄD41³ÎF_í>yÂá`,ŠÚ„÷ÀP{Ìîªô»Ï;æH8éù%Å÷aÇ·ý7•­“Ë´tAô®ô@¥Ô¶ºÊ[ëÜ“öf“Óíå{½Õe^\¾.Y*/V‚¾¶,?jº|qO{Lb’(/‡Îò§9Ò5q â$Ñi4;Ýf¦úò™&? ü9隥AÃìE«äÛöÊÄ€/r»Î]å6Ö3UUX•“+ìÜÓºãZà ‡¿…ö'·i9ÁÁÌï±C.ñÙk0Wš6óþóÑÊÔdYn}¾Tj1Z5Ä ¶›\†¾T¥ó§¢¯cåàbÉeè “ Р¨Ò: ÷k8¸÷HCÒ¦Õ°2Ì3JÏhn†Ã1„HU™ZÜÇÂjŽbeÜˤ§á1Ó£%ýts0D@qý”ÄŽ$½˜ØB Š  TŒƒ¾m»66âöM9ïvÜÀÖÐäHutÁk™hD š¼ðwNT¶”µ·Üe N?¨¢ÞO8?kÓט,´çlc;&[—¹¨H©W)s˜äé²] –šw9½»Ó_c4ÓÂéQK¢@!PX5žj¨ÃÆ%"P_àÉ/Ž×oˆîÜwý FÜ«P³ÏõÀ4\. ·x¾‚ÊÂ"µF¯£Eâ4„Ëvø r~üåN…O's2j­Rr©¬*yusuýáww_…x(GLtubK},ñhmàli§ÛkéÅÄCýËÕ†_È ÿµ?à6vàM¿Ø{'™„æ„z…ÿÿÑ+ãK¤{ ºçX°v•–V2~²\*ëðý¹ÕvTSvt½†Fãì#ÐÔ誄ÆlºkOèø×Ü—C'ïõIŠÅô²í³§»ÕZ+ÉfB5¶àè§ëøÃ7aì5öïhªùùš]Å´:ÍR]M½Ñ_a›Ñg"4$kæ.ÀWm©Êh¶MÀC5ç:$™ÂìÌØNÁ•[Ç?;è ½']ö®Ëð‘wûuq%ii²3»¬ ß@™Kt:‘W!©m¨«n¥CaÁ—‚ ~­` ývñJ c·  ,±T&ÖÑéGl¹˜²† .š€èé7Ýô·»êZâêé+ð AKM¥&|A ÈÊËÏXwtÂi~<ç¢ð¼‰‹w1#NØurî`Í9ãÝ’8Â὞‹e€g–hi鶬tì™»«ÍLÄý²úS÷þ¸›»ÛÖoMÈ‘I0k¬øƒZê"Qø#0Ð#[k±Éê€3Þ ¨6k~îîXô”"‰°h µ²‚q;ýûO}Ž©èVÂÙq=•=Q×ÇFüÂvþœ%T29ÈUѪLy~! Š w…±Ü}Žq7•8—Òl0~Ú~ö¸J}²±{&ÞêË¢–ôþ‹‡ÃûïPÒçm¾$¯x2²eEût…Œ<ÈðØñò»EõtÄý›­w«™(6Œ·~õÚÙôª>_sƒüâP\ü@o}å=ÏOYyÿ ¢ÐÑ’M‰é°{ÚªlîÃöj¦åóº‹Þ£=ÿÜÞÃ[§nFCÓ‚\Toqx,tÝǾ*@U8•’b]q‰žY†´r½ˆøÛ:÷¿ûS7ÖBGLˆcò0ÿdåçä¸ó›ª+šûG¸ô#˜{5ŒõÂ]vòêLôú?·D–hqÝj‚¯ \4\ûÛŸ„ps/ÜŒýû6&Œ½/ðÚöƒ"Ebs>¾Ïœ›ù2ŸlÎ÷¡ù\4‹T¤‚ýûÛ@9Ç‘©hücÚ{$Uõö·ÓÖ\.œIbOÝÖ§.Ä£90 N ƒð4¯;©êÀž¬„ ¡'ý¨ÅJM´`{œ(S¥1hðè¯*˫킣¿øµ?ÝFœ-ìÜÆƒ¯?Üj´–Zp»…_;`ìšB¢¥ÿœÌE <[KVc/ik ?¬ëå@>;?Œ=þ$Ï›’¹ù$bŒ6F„Áï®óêÄÍIéû{SšÄGü‡Ûú”é¥^ûŠ î‚g¶¤bß.NÞ m¡]Ö Vˆ8'ÙÛaG<œÎóÉ*„bu‘FK?²þsC±\¯E} yËe6š5?|Ëæ°XA9¿ŸÈð6)Ù%<82úö"4ÍGùhï¤Ó3~„“á"xî§×èxh¢PÂäõY7¿€kàPõ·îÃÑ {Ëá®ä°Ûý¼ u¤—‘Ç:·‰Y_'jT ½fVŒN`(0`’S ka£û˜©í =åÑ ÜY!<û¨ÂÜçAƒÙ]e¸oŒ¸-¯Áe¼*‰]\ Ôˆµ´põÎø] ìwæÛVÕ)JSM§º/Ö¯€ÃÞcާþ¾ü:„ÌCvÈ첆r/¨¶á¢ò÷š£€ºÚ¸jÁÊxDof¢sbó6­Ý™ƒ=dß«‡r¨¶Óå-µ  ‡eÊ#…GäÇ01>}Nlí +•˜à|zžì±àè¾`óyŸ¬»‚O|á•Y»de²ú³Ãg¥k¯|]yP=)q[ßXH&‰”etLínæ(ùU妔)è™}«^-èt`6™J/¨ÁÖ§¨=°Wµ7ëÅ뻾…¸øœp}_«ÄCß=~â¸Øç¹÷~%â°å^ž[îkÕ½†«E:1 ä%¥&“³ Ï<ÖFçI`Ãûy„]aŒŒ–Fƒ2þ¥Úöât{\y‚¶–@w÷m8®>t<™\ª¥g>â  4ámÄEr§¸Òn6YìŒÏq4ƒØþ·+kµ-E•š$4/2ô„ : Ÿ»¼ÖJ…‹¬%Öà;~´ ÷Á_ €‹œ¯îà \-”òno¹55-NSOŸ„¸ô暴bµWxÕF†(€RZÅ “©ÌA{\]G¿Toõ¶øé“–=_¸Úô¾œq—áÉÎKÕxóS 3ÿt}Û˜ÆÁ0RØ~ .Çe?¨§/€:¨æIù…¯Ùr@( ÛÃ+9¿ßs¨­ZE±F¤”Êšq¸¥²±½5ÿÜìYó7½¾‘ž€Â5h>H¥óç]ŸÃ1ð<ƒ§£JxÏÏž?wyñç­eö“¥fºöòÍÓê[Ûry0‡½|•ópû ¯\ãË,ÐëåEtÒÞEy@ t¥…Õù‡$¾$ â´;r ÍÁ§y@¯)–¬@Ó#5ŠÐRÁâª1Yª\ôûßÝo9œÀbpIë3|…íÀ¬ÀeÜ».a}Ü o!^&ŒRN•ÊÕd­óšé^è àžËŸ›Í6;pP!<Œ¸'~ûº· zeØÕb`<|¸ãÄÖŠk=îQ7×}0 =‡MYý^Êq9½0gv˜A-¼µñïtD|Ž€#¾gd°·þÅ-/nÜvèÜ…/Ü£#®ÎØÆlA‡xZðÚœWvŸè¾yû“tÄà;‡·í "±:œÂÒ …‘]02 "¶›g´™ì¸fƒ/…Uû: ÅT}/ت1;±ƒZ˜È3;±Ñ¶ô­Ü§J‘éñʸ+kMÁ•¡,—_‚íøÖgõ@?&»+ì›<øÜ+§V 1ˆ#fkûT8º§»¥²ŽGC'Ϙ ø \6k™ ÔR5²Š¬ Qî¾Ep¨úînàæôßàh;œ :¨5Þ¢—WLš§þÂýÓƒ»÷o¹¢vϬÂ¥½pZ/\"â|ÅZÂØÃpgˆÊcÈóp÷½>*# übõ€RL–RŸ(W-*ÖÑo#>wú}±ôwIq2ï“1h7æwu(dzzq^ò\  ò}òŠ:[…ÓLŸ…|îƒÿþøvHÐ(¸–Ühz_p!}‚káèð Fí€c#zØ%ìH^KNÍäý©É™59þŽVý2ºÐ'_tDõ@ë»Üí½éå|ÏJÂØ?³áÁä iô€”'áH[ƒjøˆt‡'£Ù¼¶Ô T>"å}ixø€tu„DîS!«ÇLTTàSÚUVÔ“"e%ÐJ,‘Š$î"«Žj…¾Cësä ;°ìêb·Ýj²8h6&V8¬Nà ÊÞáC®8%nþ•[±SÚôÆìê—.8ÀÉ_Áõ0r> stream xœ½YoãÆùÝÈ œ‡Œ°ÖìÜÇ¢)°)vS‹É*(ŠMÒ-+‘H‡”½] ?¾ß ‡äPeŽtpæ»ïý‘Lâþ†×ùæâ ©ÖB%šh‚u" —X²„i-SI™%ÿJò ‚-,"6Y>½áâæâ‡‹×?2™,+€a&¬W3X/–4a†`AMƒ@`k¸Ég@¥¦¥É÷*. V,Ùì"_Ä`¦÷|ö¬/>9À2³ÆpàYàád–Y”K ’z¹$áe¾I¾› T&[¥™If7µÐh" ÖT™D3•ÉlsÒ çi^lW›l2ûíâÝÌáL†!3º2¥ HïCþu1§„HO»µNj­±‡˜@Å’Ǩ>¡KF™:ev2•ÌéD#ÊßPö„JÂ:%>_N~™ý㹜rF:îq:‰85J¡A. ±ÆsJü»C¬êƒú¢ [.jV¿žL)‘}¢¿V­Dû3jv¹~E|>ŽiꘖÊè˜0j@{Êl¨®éx?Qp0ŠŠr2å!¥‹E¶p-°ÍѼȲ|•åóì*|Kªn‹rÛ,è¦(7Uó@”Y÷,]WE¢êþî¶f‹77] P„1 ¯ck F)ØH0¼Ã‡‚.( ¶·1@Š(í˜pÉX®„4*FpðòhNAÄ4F5ààïîËâ.{ý¡ÈE~’W3©ÁêEŸ½‘½ZI‰­<Ò«½ ÿG¾<†õèùÖAÛz:TCé¢$…Í7½½)Wóôõ‡tYT§™“µX@IÑãwlsâ NL´æýẺwz kêmL-¦'l Ò[kO½ÝdÞ fÙò~¾Z¦ë»ô´ÚC*€Ûg|l«"û5*Ó á±a+÷–Å5“^?ÊHGïâlb°!ÔEäˆ6P¿KÊ wABuvµz˜8É0j nÀÏ(xˆ«2«0µ’ÇXÐ['ìAc! f{jªÒu½o/”êsT\ÿ–Í]™dÀ±‰B‹¬š—«ë¬ _Q…Ò¼yOÑ*ßf¥C6¸oÜ{ê+'ïráP_å¾Lƒ•Öjtý%<3m?^rƒF¨ „G»l6N}€MA$˜¦ÝÇf…'S®!!†þžù ÐóeÑö6"ü«²Ú6Ÿ *òf±5OUÄìs|f×p r"à䦈wÛj›úòÔ}œŽ1W¼úrWƒÌÍRˆSÎä ª2(wÛ‡,硘þʬ]à;îÛPôv±XmWEž®×_&”+¯ €ßkò)ý(;¹‰™Dëb qhÀ é€sBuÏûÒyHËUz½ö‚uÄSg< °Í*oùáhu±3 WZ/”á:i6Zzäß’caB ¯Efê S·ðÁµPæÍ#í2Á!é¸Ü!“v°ÑìÇŸÞ ˆ¦ÝÆÁb퓱·FkdݰÊÐ|]TÙ¢!Ð>I’Ú“öØEïß~øøMŒr¬tŸ•Ÿ'W!Dñh—… If‹ ´Â`m!S‰µäª^ô©Ö(ð¼O¸N¯Õupϳꫧ¸  jõÄ1ªNœA“Ò[Vößùú¾îýnó”è‡4eØŸÕ¦[ÔÎÒ÷k“EÚÛÎ;¢¸/Ÿ JB«(¥þÓú”TÀmÌIÏã}ä&ŠÖ×âöí²jÅ]§BðH–ôzð ñòéÜ›S&{ä¶…æ—¸ÔÖíŒR$Yg=sŸÈ¬ô!![eóP¢ë¬{¶Ú–÷ó­×‡Õ~÷gØÐ,QOÇG ¢ÑXÈ_+\(l”í³R{ÃmŽˆÍ I ðbÜñ9B- ÚbÎ6K±‚Üàxr¹©hÅv»mdbúò’g°ÍŽ}QP>«QÞ”ÅÆÙ÷¢N2kÖð'Úæ·i™²r?·-j—ö$×=Ô@ç*_úDéÜÍjKwŒÝgᣎ)¥Û@©Qè¾ò,< NÂýÖÿL¿©?¸xSk³yØã"&SS,,kâä+X*¥ÖÔk{,¹Ü Þܬý¦£§Z-ó† 7òÚVŒéw-WyX«·F$6a×Aa`}EÅE­XÕ6ëžúˆî·ÑG%ö—P²¤ÝÜ®!Ľo*ÿÁ§ç«…À)ʬº;]=d¾ qHjžÃÛ¿ýl°?L¬©¯ ‰ÿâ»/ XeÈMz¿Þ^u[½‘û§<Î4a¬x›63F(Óæ{ÚekÿY÷™ìq©# j‡làï›Ire ´—íð‚¨€¾çÀLrxÇÎL‚Év&I]‰¥ÔQ3ÉHÆšI ¨Ó…Tñ É'ÎbÈ#"TŸÐå”-¹æ·kúe{ê•ÂàŸÙç_ÿ]”¿7Ošþµi¤ªa±–FT¾q“> ëÕI –±¶/Á‘' |Y4ç6{G ‘XÛÓŒ0O€5Ò;ð~ÉÍ©V/u’lz!ëK-z°ÆÌÑ_¦ãŒÎ@&¾‹p£s ΄†ŽAöÀŽå0òÙ‘ÞåcÑGøË‰33 ÍÏÞÄ¡‚¤ò”RØâöYÚg2 K]3º‚9„]ÊÏ®àìØ îPµ ÞÄFWpÌsÃFHeRª}Ü=WkH‚F> _k®š`ãìØŠ¬ñŒ±™AI¡­éSðuƒÚúù`mCÝÕ|ÁPå*¡oß_eþuæI„U'4*µoYûÖÞpÿêäp–ä«Ö¹ohέôê~_ÊÔze°"*fªÖãÉÉÿ˜¿ÀctíHä¹glLaªt òêD¯@ͨ‚.4B”)*Ð a±a´#­çJÊ—ßbˆcyÐx`Ùa¸ÈÅëŸ{±… wìÈ};ŸgUU”í•îÆ Ý%”t½îúÌ›â¾ìzÂy±¹+ò,ßVQC{·{&ŠbndRÏgŒÕ„À’3“„yB˜ÿtè{7gîÊâaµ¸*Ø˖¢ëÿ(¼} -Þ±Ó–ÂB†iÔ–Rx…pL[zÉGä9¼»±Eš{$^²`ŽÂ¾Dy¡>WÏ«¸æ÷ Uáù¡ûòÛ×ó ôÓìo§>ÕÔÂâÓºÖæ¼'ƒq+>N¡U¼—üqÝ ž Kµ‘V=à?{ =<»CúærÌÀ±~_òê3Ó0,nåì:²¤F71è—‘²»XLõáËmR{Q)+‰¥;Öìš§[s ü…ä,9f³/ Æ© ,lÇpÏ%Òø ‰”Yì*a‘Öåû¨÷{¨u÷à»`°¸/Sw3%Ò½Ÿ»[Û1轟î\YpÕd ö=u™»0¡¸î×eÝ1Æ*ºÜ\fweVA…X9˜¶½nÎl£“‰jµ¹[gÑqHqŸ·`E¯°tÖ×Oª«î¸âóíj~ÛU¢›ôKWÅ^GçÄýKÖñ“<[¦îäfïÙ†‚¼¥ã3¨MÈÁëÖCvo[S°wi¢“ uÜÏ-†ŒuªAµ;´d¢gÈWä^wÆ€ÿ%…ˆ1ÝB;SE­[ •,y‡F„Ð^‰'ô ¥onœ†ŸjŽ @ˆmVùý6;›d˜»m†y&É0ÎÆåø’az 1çlrɃϞM.Å„U/ —0aÙ‰g–N3é>“tš6*4#—Î…µ]0,롺 í½<…+ܼ°ÇÂØÂ-„ÞCugÃØÈFÁ46Zeô±"Bu9=‡U4£üc›äKKÕ¡;/d„c+åXvAÛ."T—´>œÅ.b&F¶ ë~ MXZÖÆµ Ìp>V¼ˆ¡l1ª&‰8Ÿd"áW–=~Æþ“ÁDštîcò¸é´MÜ $ѶÿÓ?̨0 W ºú°…‘ï­'Xfè±R­Ó¦wÈù>ì:.÷Kñû't»ÝÞUo^¿ž—''#$Js\N'SCÝ)‘Và¢\¾¾Kçþ÷S”0ô{ºÌ¾mo¤w¶—"IÜ/¥{½[,²õõÄý¢Ú‰î³í6[û±…ÆVKôqµ~˜ÔWE$ʪméîã¸ØÂЪ#凋ÿ÷X8¼endstream endobj 77 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 166 >> stream xœcd`ab`dd”ñM,ÉpI-ÎLÏÓuöÐ JM/ÍI,Ò 1Ô54Ëwÿøiòsk7s7KǤïÚBw¯ó_`&m}fFF ‡_A|?s¾O;ÎøýÑqæï¾Oý½êø÷UßWÿ $ü¯ú½Ê%;ßžße¿Ë„üœ êÃöûî?ÖSl|r\Œ3ôy8Cß;Ýendstream endobj 78 0 obj << /Filter /FlateDecode /Length 3599 >> stream xœÅ[moãÆþnäGW¥j‹á¾ïšW i-’3Ú—  %Úf*‘IÙç"ÿ¢ýÁÙr©“dŸm^LS»3³3³³3ÏŽ~™e)™eø¿ÿ½Üœdif8ešÁK¦¨¤‚«YsuòË ±fþ×r3ûóùÉß›™NuFŸ_ž8bd&Hª˜3Eyªá÷ùæ$©òª¾)š²^¥óóŸO¾:?ùî$›&LÈ̤Bj…„³ÔhO›d<%Ñ~ƒ¿øžâ#Õ±0„ÐTs@7ó 3©RÉx<÷]R_ü\,»ù‚*•C’¦¸iж¨ºÖ¿Ó2é® üC§YÆ“e¾.ªUÞ„7$©í³„é<ùïŶ-«¢mÿHòä¶,îÂh“Ô—Ãsî OVÛ&ïʺÝ•ÝuAïÈPWËâ¦xÄT7õœÍŒ¨¤H°$¯VóÏ¿9Y¢S*gðœ"V ˆU~?' V¡L’Î &!«sÇ)$ÅûùíÉùÞ¹µhjåXmqº&ÎÙj÷œeð|W‡Ð3ó¶®Ú×Þ6 »Ïš¶¨\Ë|ÛJà¹'njç v¨L®ó6Ð¥ÉmÞ”ùÅÚNÄÝ"pð«îú _0TãÇ·¸ßj}ïǃNw8 g4;\%›òêº K2I{“WAæDtàë0Þd:ióÛ²ºØX5[UîD&©­¯Ø`°¼Î««ÂF¥hëK–*!Qs‚Ø‘_åËëc¡F‹T)>žóèPóTˆxjid攄6hzsS·ÖÙì&ì3ón€Ó@Ÿ7yÓY'ÎÍýxkáÖ C×q&ós@·m`l  m¥„‰ãq½°¹­'ã<•ü½î ? ¡®ó.þ«°`Yh·žÊFѽ“(¯—M~¶'ϼ-–VI}Z)»ðÕ–WU›Z¢ûÌ+XJ˜#ûõ\â$ÂÅgrRŒœ·EU?QBY®.¸âpvÒvÍvÙ ódÒÞW]þÿv¾˜¯×õ]þ_½)–åå½óWžÏ“û"oì e;6¹+Š·=s“\l»HrD.ÍX®Û¢qI8²±BàþÁ‰e3 î1¡÷“ã*«¬¥÷žäƒº‹¨m=ɩߞù¿œbR þ/t–¥ZÎDÆD*èL0p}ÊfM1û׬Bc).39ÂÃ3N.4lK1»j- •¢ÀB Ù LÀÝ5Ã8ÆmÅgwÀKMp¯¿<†×[L]RB!tc¶D ¸3fK‚jŽfKDì ‚§”9“”¤š¹ ”·é8r<˜0È~(M)är1í’`ÊH–Ù\OƒÚÎp/mŽ-ã+•rÐaÌê¹'rGV_däµýd?¹äÕ3F!‚«lgaóhaòÈ]a…Nm–Ù§c+SG ”o(„~7_LdÉ;òã|! AÄíEØFï_ë°¦pa 2}'ÎSý&“ ÁÝ‘ÛÇùr’J!+|líWI2øyN°dD@à¢ãí\BÌËDH| \DÉG%>Gx¼µ<>ÆñzgàÌWÖTE;¸ÁÓF"¢EbÖ/—UIÐ Óž*« '@Äjº¬Š1’ µ³°ù3Ãë© ²j$tøÃ3Lùº²1ù¬ëMø`# #F¾‰³Á aK¹«RÄëžSI¸ô>&þiÊ!;‘®+TO«O®á€q(A¬O|ìÍg(VñT`à¸|"Å*H½;¢Ø‡*™'Þ\Îþ;Î Îïž·…ÃaT¹Õsû„4‘>°áju1Ô±qˆµ…2yÒ= hvù6° 2¢š”UW4-âw{q¿^"¢`?AÒÏ=;z¡²™1¯må]ðŠu„öx5G8QXVÆÅh ¨gU^^>ÄÌžZt¬f—Y5“>3òº¦1Î,²^_^ý¨Ç¤3Ĥ›bÀ…›òªnêmK›äh¬=ìPl‹‰j®u$kM¾(XÝ›š]gGeÆ‹ßÝß­7Ý]À›ÕªD×È×kw‚ Ïð/iL÷!?ée"Í}È~°q c£)Gí×3£œ¤”×ïV ð#^»EÁv&D£^n«åû… ‘Âök!-WïŽS¨fˆúMpÎAj±O`YtJÅŽ:Íî/<(, íŠ|\ÉìÆ5ftÊYö/{·ÇbÛ N믢¬Ïꤲ÷€þ’>ndš¢Û6UÊ<"­¸^V«â}ë¯,3ŒCPHZævÖ×epf¬’³0ŽÄÄ…Šj©ÁÈàê\ÇëN>/«ÏŽ~DC±£­þâ ï o‹f]ç>pdöî±­…¹k*Šú{1DÉ}¸ ‘!Öqðw{Ao¦eÊ{ÐÛ{ép‡ ee{]7Ýuz»“r¹]çͺ¿ªI»-;of/ µ­HýÇd¸°uc/À8Þ1|ié.KýÝe¹)-$"E;\“¶]tÁIjcŸ¼ 3#[ï®ò.O\Çë]ÐÔz»ÁË·`ÆÀy²{'ü×b(E\ ƒûÖ›~åo†77ë¢Ý[ÃtŠx”¯A‰‚À þáÊøðŒÊB6iBe ã`Þ£ ã#,ž^ÛX¨| V•äÔÅx­Ñ3âœ,Ÿ‘¾†:;¦÷l¨øL ç£cÑ}I_â1þ|D÷à"^² wØÁÈò¯Ná¬f‹ŒÀÏ©ƒÃÀrI N!ÅãQ‹WˇœŠÔÚb¼êùsÑÔlÇYJÉ$¶‹(Om»•·pV9'Ô¢™±ímðŽåFŒ—?µ¤‡‚NaĈòÔFXy#ªGm@=íâUÏ]Ù¿`R‚Å´?`Ѳ+{FÐéψÞ΋ñ)Ì<žÚÊ='0òÂEY ?ö³\Ì:}#GkžReä:ìÃêòÉwÁÞz²ïÀj¬œ•1tKXTäŒÀUÔˆ”Is®Šì{n-‡ÆEbsà8ݾð0³u x=K±|8øÀÒûÖËÓi1LªHʹÃEOte°P1ÍßÈ#„I¹VG<"Ê«ëò!Z2z„ú8–úËé<Ë)vQ¡§–¾¬ˆ¨þF>AY*³c·Oð‰ýAåôÑQbqpÛ?É G|Øä¾÷ò(?‘:ͤÇw¾îQCßg­C¡k³þ„é@¦Û4@ýÉ›¦ì®7EW.Óùï?¶™ Íhðel-Ë4d+$%DF—,søtÛåØÑ¿Â7{.ÞßÀ)[ø7ç½0èh)Ž–æ$±ŒJVÅg•#â`r 9®Æö][À›eÔâ;’——‡ÓÝ2¹».ª0‹†ÎÛða/S`$­H¶ïŸcÓ#äac§-ª¶¼XÛžum,úø·jÔðkèÕ®«¾aÝ$˼-’|î@´\ë-l·]“/;ˆ}“x~qÄödMg„™”Ö¶qDƶkV$ž÷ÎKA-Üyœ+ƒìŽCÜ‹ÙÆ—‚GcK3£cƳ¤Ñ&ð ¼lêM¤´£2Y€êùX&LÞm;üQ™¸‚Õ˜§ê‚£30ñßP4æ‹·ô ¢þˆ1º+¥É?ªý}üx)MB—‘s+ßvœ¯Ûzhßl×]yÓc±Zïô(—Þ»6ÌÞI@@:ãÏõÃÝFhÈ_©ðƒŽx ç©`žXø@ó^D˜rÿ¥JË÷!¸¯“½=×’`¡9`˜BKéXÏõá;Àê0ÐõZkˆÑ`ÉÇ «aêfÀZ‰Q©¤³õ‰€ÿ`ƒíyf­'kÈ&PðèLÆõoØBO-¥|³kLyª˜`ì1+¨€)„óEéŒòI€Vö’Ÿ½¦:¼1É› øù2ÿâÛºýéMuU¬‹öY%ph+-;®_ ‡•as?S#§/ÔÃÊMÁiG´á@ž¶;ª]m›ƒ‰ì`ÌóÌ8b£ò5æt·«r‚ ¢ìVÎ'Ø 1å‰7HÄêÀÁº•{êqŸ± `ÁÈx}/¼($×J©ÓI'víG6W±™L‰Ì”ÙWÚ1™ÒЃýÕjU¬/æp¨Yë¶èºb}æ+;E’·åúvn7|Z´dš‹TE“Ä•šÐ” ©kÿ½ä–WÒ‚á„Ù6Š_ûÒ0+Ј"!úÆ Be²]Ï‘U‰Ï¤2FJΆšUäIŽ— ©™Âår¸_]ò6âªá¨ÓÆsM†ï™|wòÖ¸õNendstream endobj 79 0 obj << /Filter /FlateDecode /Length 3982 >> stream xœÍkoãÆñ»…à|Y5gÞ¾F.@š¦A‹´@sŠâZ´DÛJ$ÑGÒw¹ ?¾³/rW–hßI¼ p&¹;¯Ùyì¬ÞÎpAfØþþ]lÎÞž É ÅåL2f Jf3Q:#›‚³YSÍþ>ÛžáÂÀ(lf·Ï˜qvsö·³—?R1»m ZPÁíY( 8. „†F¼0š)>{È$5dö}L1® Ég›Gè×ðオ=oâ¬õÙk J,¸0ÄjøÕö¯æ%N:³ðÏb3ûý•eCÍLa¤¢zvusæE\ëB©gŠòB1»Úœ½A_|1¿ð‰–å‡õêö®‹oP[¾[moã#EÝjSÅ'Žº¦Ü¶«nUo/çÿºúóÙwWŽbBÖ ¥ƒHàA 5jŒ`"F &´0Œ[‚Ñýú¡_ýÍFd@öT„«yòŸhxBê5HYƒú¥¨Ê¶Ø–ÛÚÉñÓ™ œœÓÃL0Páh‡eÅÆ)1ÚŒêÌTªJ¤¨Þ sŠ)¾Àì«  Z!B/1»¤úKŒ/1>O4â£ù£ZÃK’ó71É*1Ì )÷-Ò}Õ¬êåËÄ-¤VŸc™˜Rv[J1“åù1Ä]h1¶§£ž^‘SÿÍÄ¿(_þP·ÿþf{[­«öv¬–rfvØI¸™bŸÅÖѰÏÎ/½!ÿŠ;¨@½é+BRó™v?• -Ö6QöåCSÚü˜]‰©‚‚¤Ð'Û•ü˜¢:§ü2l=Gð`ÀS«œ…TK4‰Z"A=à_ Zë˜áx™lƒ€æ£åB±((“l6­’K) lȈ’c}ùH§O ÇžÁ «“xÉ ÃLÐh¢&À'öä ¦“˜L¯Ï o¬’“‚H3¢s‘³Té°á”9Ï,œT¥O𙄍Ÿg„È‚ºô,‡cúÛzs_6«¶ÞÏ’&±Ò6>°€ Lã:‡|)ì78ÄÞŒ€6jŠltât¯ ï ß9¬G›ºíÖâxŽZÖmhS7ïËfTýº¨î;ÿloÊ×áÆ;DÁÊTÖ4VïʵÃa>9dTܦ@)ŸïïV‹»ÈG«và¨n–US-‡×âß­ºv˜ÕveÓRݯ†4éžê—¦¢"l÷•dæTÌ/$–6Dº:„pD]×Ý]|’ž*K¥pYcX.áƒçêíC¹~ÏÊ.(‹9DHHŠÖ ê¨ž9„aZ' Á¦ý#È`Qoªvøz]ÁBV(,k¹õßìß JÛ82Ï1œ½Ë%Æ!%º•0g´`4—pë0+…„ôW&ÞLRÝ]|€|´-7U/5m¿9N˜ËfíHK¢ÛYxal²­<üEo¹ó ªýä»òˆmã úÊx¨öjXm—öÁÊU ú&~=þƒ'‘6êMHÓÁ” !‡½6ãâEÀL$z¿²Šç¨ÕÂê’' 4æ®nºªñ/¬^¬¶ðhM5ÌeV.åÏQs¢hëâòfx®·U1® ŒœØ.ËC¦5´` $›[_ÿ\-:Wصl¡4øÎ še DBæou¬ò»*>9£s´©Ê-Háæa=|uû{chg8h¢¨7X,jªM¹Ú†g°É‡mØÃŠÁ+ Õ,.¨´%¦¾6E¸¶ ®fžáªYC‹[·ˆ“*±&ò¬"ÖŽ×e'v¡ehEoò©AX,Byª(‹IQ½Aç_úDC® &ãK[3ÁñA?]};ã.¾þî§ó¡Þ²wúÅQuŽAM4Íåtâô'äú)Н& Ûc¥OpVH*N©N!ÑM!Oœè&¨@.«ÿT'ê‚\N§ÖKHÉGRƒ«únÚòŠ ¦P˜=ò蟪n` e2°©ºÍŽ©À4˜K3à䨭¢9.rbO¼…ô{l‚ã«W“l"ÎÔÉÉWÔÆ ŠN´¢1œ¯=†X ñÓ‡Wt +Æ ¢ö?µb™­Òt¢"i ýtK¼E ü(c%£ŒØS3È|DŠâëiLYê²ô‰Ö•‚¨°™h]©€dšåëzŒIS¡ÀjGÖu“æ?ê±³?~óÃkoÒöˆ˜]ýpvõ»atÙuÍ?Ñ‹óâ5ûv]¶í9l‡§c2ˆç6»… UòóiË€œ‚‹t¼®Þ>TÛ…Ë!Ý5 }_mC±®x^8õ(V½±0–Ã5qo{„öuéëª Žî›úÝjY-ã ùt™Ã΢EŠø©bE¤™YË ÙL›8»IIQI!;PSL‘qlÜ‘k& P&(l¡H‚0(ººë¥ÅÑj»€L½ÚvîZ”½Ô8ªV6¯cmÍkèP±êurLbcÜAb!JÍ&ìnB#Õa ^,-™ Z ¶)à[GÂMÚÿùÁ L‚šbR(AsÔ T5z½ò h‰ ®b|A,öÏXx54Þ>Ûʵ¼«†á]>kªln¬'qæoõ6L²•TWcqbý؃`9ˆ¾d_Á÷ò—ªÄit¿.¶žH ˆNÄGöy2eá(h¹t-0Q5s¹s̰µì;ÈöÃE:üȃktª\óI—^´(”ô%¥ûfµíŽXÅxñ(…9QÜea,Cu\Ðè¤ÙñV¯§Ùàý™YŽo,T‰õª“Å*?"ÕáÕ:ÑQIT†èœlŽŠ)ÝÁÉiŸ*¦”ºÀù:>P‰Ñ\Šå˜@Å)rª' ä8)¨Î~ªH… ÛìœoZ§‹TBÈõ9t*†\ŸCh½S™DhÂ:¶³‰LÝQÅ Çš4žvçæ™î|´hB£ä9JòJž£$9JÛF<^”âãPŠC(?þt8¬ ìDƒ®RÊ ÊCïü_ëΖØ3X× _Ž_Œ Ø6I°ÆÓÚIHgçdøÝyŸÅN ZÔMS-ìY—î®IèS·OÆ ¦jïÃgK­ò‡îô˜Çó¿04œÿ¹q-ÊõâaíoÃØÓ;w[A¡ê;Ár”ïßÓý’û@Qã®xXÝÕ½7ãI”H×ßßÛ6ïÈ’?ét#“Ëð{ )±ÛsJ½X<4m<ÐR覩7ñD‹$mèéÐN˜}ìõÍM[%§„A–ák™œÝõ,…6ôåêæ˜- þỔzÿÇÀv €Ü•ë›9±ƒBF `¨Ù{dG°½`ÄûÓ1cø9³;ÄC;C¸=Ã{ΙÝŽ©íˆÖ…ê¤ B sÊ‹ Õi„Ï@|lfMQèB3ÚA&N˜i[7ͲÅv¿à€¥õ{$i§ô²wξü›vU¾ü¶^×›ëú¨Œš Û;’Krª ®_5%Azòéâ3Ÿ6£ó—ÈIFÀT»|Ë3Tç.˜8ö´ ´føìY‡ÏÀôMÙp8vcºckÌMW¦™Ï7†½¯ª_†Oà@G¯CP¯DʰË[ÿýÞâyâb1ïš‹\Xv[Ú%Ë3g–ðÐ ŒùŽz€kÀZûéÛmçñ&ª‚rYÛ\l/®Êžgk³Ÿ­”{Ç—A’ÑâÙr´è”0–&Ÿ"Œ7Èê1aÌ8eÔýdŒÞ¥,Ðb{˜½¨$YwTôÁZXgž"Ò_ ¸›GD:(ã4ºÔ£1æìÊ›t¤— Û•­;Œê*ìä”<Þá_ŸèÉâ¶/]Óœ,רŽÍü8gv°mªÍuÕ ¢sµŸð¤B›¸ý1‡ÝŸF¼°•ŠPÐØÙA(hìË:~×CÛêo‘Çþ7ºº‰-ÉV4I]€<Õnˆ«¾'$ÏÓí¥H`:›ôÝrY­¯KÕX ‡ªëªutÅJ ×«õ»¹ÏnªÚ—ØH‚Q´HùÛÙ²ž+Šendstream endobj 80 0 obj << /Filter /FlateDecode /Length 4152 >> stream xœÅkoãÆñ»Ñ!¸_hÄæíû´®mZ¤häÎiQ\Š‚–(›=™tHÊÎýù»}‘»:I¾Ew€Er9ï™å ”ã2ÿüßåýZÜžýp†íÝ…ÿ³¼_üöúìÕŒ:çBÉÅõú çI7jÁq.©æ IX®àïõýÙ»¬¯îË‹+"e®UöŸ¦ö«¬-ØVm¹2wÜaÙºiÃc–õwUÉlÙÜ?lû¢¿@¹ÖH(šUM_\Q¡á†ÊþÚôå8º¿ƒ‘p%«€«€êDzîám?^ðj%ÇÑélU|ðO4Éšõø ùT–ïá8sd›':+ ˆ·uïŸH­Ûæ~|ˆ<í$ë›@8ÎÄ¥½=UýÝx]üóúOgxWê˜äš2'õu±ÙTõ­ªAXŽ[eiz»­ [˜2à„d¹÷ÕõÙ· rŽu®@µ\p•«G”çœ,0•,'zÑ–‹¿/ê3Ðdi°’g_8[àWo_ÜvÌ ¹0^äÈG åÜŒ×9‘3DK¶xT`j¼øã' zkyØo¶Ä˜­’(k·Azð*Åb!4Î)s6 ŠÁˆ£ìWW£lÀ;ˆVŠ‚›€$øÁ‰&ˆ>â,|Vr%°Œ±fE—×EÝX¹þ·ÇyÄ ÷óƒ™Ê¡ äï³ ˆ!ni×ÚhÉ‚ ècL@Å)膧¢;'î “+Š/®8aÖ£ú™ÿç‘46gDМ³]v1ö9Ú9€ ì áQÿŸ_Ï"C¢t.BŒëü»ëßO0Šy®äŽ \L”Ô~;¼œ×ø¨AeŒø_O&ÀL°b¤C4ˆá~ny9!™3Àc;½íú¶ØTÅ«¿”››fÛÖå¥ aO¥ Å:áq)h fe¹Aö×1väQ¥`‹bç—¿ôíþ§÷KÍ3:Otà<žNn#ذ‰Ùùëû²­–Å«¿–OÿúGÓ¾ŸdçB‘„™¹íA¡¶2³=P \q"ƒˆà¾€EDØÎ_¯EUÛÜT“ ãœìiv‹€„Š+y,Bà™MÉ\(FÜ75¤ºSlB€¤¸3š%9,vlç_׫ª¨_½)·5¬1¦™„ÈÓ)33›×<B1‰™-‚+ -âCY´'1ÜùƒDŒíüuYÄ×íûmßM›3Ê%O9™Û$¬.?6g ‚b‹@–Ö$¨$ÜJU(nè:B„^À‚–Î,¡Á/l9#ýÂö ,¢WveK µe‚oʶ0Ëù.ÿ´åÅný‚Ý1àn ¾k³Ìû^e¶ÞÖK‹É":¬&³Ž'1gÉëMÓXS>LƒYäéÅïõʽth A`Å·ݲ¬l à(B ëE²ËtÑZ¦±-<´Ícµ2U#„EVÕþ)–YÓ®Êv”)^¸ßðbÙ®›ö>¼‡³vÔ…/j+U¸P»@Á¶Õ@ÛM‰ykÊ2Duå²ê|)ˆ+ éu}T?˜ñ\#ƒ6ª[`ëcQEä`ÈÝ­ Srn·÷¥­ëî*-kK™)wõÊã¦Â>K@fqà01Dƒû™°³,ꑎ›r £y0V[l6Âc‘u ¸_Øâ Bˆ¹Â“ùmÔº^µ"íåz»Ù„¦U÷mn`’5ã`ì+cP[ ²^–{kV+˜Ù|é`y×t¥-SiK/Ê9úr›¹ƒ!9‡7¦Ä"LhÄ PH„Àƒwömà\GN<߬½› OŠM*p€*Tã A7åø P¶]ß4«ðœ[¿p5º¡ˆè•?ö¡xÈ}!QXÿz,—}Óv¡|h³ÊÌ,fñ˜ÍÄÒa0]bé47ÿ º@Ìžîʶi8!£»NY¶*Q—Ý8¤n¬É޶جO6oÛÊNa ¢ñ´ÅÆø°*õ 33Ô+ ¦?c…O•µIˆ~F7Õò½¿ÂÊV]íOXt`û7›2 æ‘QÚ[Zqol[Pž½à`Õmm\ÜRgT”}]cж¯–Û $)ck3—¬6¢¬Gª¶+ÉZ®¥ÔÁÂ$"9†YsšU2ÄÔªYí £¼aöfRD¯ÚdÇ Ù ­ H“>zx®‘5‚DàÈV¼½Àmlú®´—ÚúCµö1uÒw?{Ñ®2®P<â~»é«« *TÙu<¤{kCŒÎW9muÒìëµduÍe ˜Æ©höq, „¬MÜ!ú@¡ä®­ŒáGí¥& æÒ A‰î [Bþ&ýÜÍ8– šýáB˜J©ÒÙó@¦u×`¥—£Ô­˜íãaB$hËÉÂî‰+FêïšmÛýTŒÏR ˜Þ, » sÛî…üÅaœˆÔÄl‘؈ðÓõÙ€ÛíÑÖƒ« nM³n»¼ ˜Ä€”€›» °èF€™½ !OÝ´ÙÀ^ÐÖÍkÌÍrŽjeáboxè”^ùÁ Gµ’w;&\É{-ƒ,ä¢Ì†ÙëÕYVåe¾/ÃÊ s?è]LO$I­ÅIRenüüe¦Ô•ßDcöÊís9ò­jÇKt†¿“ä~c8d6¹ôX2˜ŒÍ~³[bß™‘”Ò®œÄÀeêÕÖ›&7Çü.·ò㸱ˉƒ \q?E”?>lªeÕÛ¤EÙ´XçAŸµ1Õy"s¾Ò¹ß†e¿—¨œ4aªÙ–æa³¤B‚Û¶°B7 zôÅû@(â²(Ûð@yûkÇ9·/ue¿7cÔlÙ ·×Ñì]n˜E ÆkV}WˆNÃ.Êý’Ë/ó’Ú>Ìf°2Œl?$zxj·7¤h…18‚K#¸8H¹ u†øG·0ö¸¼7hëYXºÇ{÷GA2§tØ„$&¯fGöG¾`÷GÇ}Qª`a_”Hð©ú¤}ÑÃ(ÞÎT¬a–«˜ïYâN+ßÅp“ÝËÓ±`’5©i‚êD[°BçôƒLœ°Ü!•«D^v v×9åà AʸR™gÜæ¥v¿qÂÎ,å¢O¾˜º7ûŒÚLY'j[m]hŠê4häAŸKu|«Õ9òå&=šT) 2Íø÷s ©2››ì™b¡³ÌëØ ¿°LÏ[W6K7F÷—Ç>×Z d#’‚ž+Z’0¼Õ‰¢ÌvŠæá„orž ú+p ‚pÊð\Á*hM˜M^râ`å·bà3iŽ [RLP.V™Æ/–XÅ)„ßcÍûc{‘XE sÖ'Ϫ"°3'U¦ÓæT‡X8}J5bz&H…;zzh7cH&LΙ(Á9XÅEÆÏå²Lé ¨ rœŠ„‰s$B«áçs`ÊB³Óêá*A e"1ª¹Z ™i/Ö8‘ÖÄNCX£ÂüÆSAÍ·±é…8ÚÄ4Æm¬œ1¼HÌF¦qBÏ’_F çÎ/#T§Í/ñ0C~9¢z¹Ðí{n6çŠÝ¦CL’}ºš¼µñdýêb<MÙ8Møæ2ßqÈÙ·$¹â*Á5[üV*ç\¦òšÀ1Ë%Á;²š7‚möè5.«®Ã"ã%"8S*qò´;†;sÞ£:mâ}‰ÓgÞªOŽß·fO æ’ÚÒ@ÂóÌõLAK~Ò`î§ÞôÌSoŒêßOkv45–R?SÍø1®ÙNü¸ƒ ‰¤Ny°ÀexGn3‡tÙx®KÔx1Â׈½`H§4׈Α”Ç gNÊcT'MÊò0CdQýŸ‚º¢¹Ò©0ç®ûš¸¢=mP÷[T1ì™·¨bTS£º9ÒÀSâç êÔ4Ð¥ÔÏÔ[–*å´Q‘Qµ#¸™£:2päÙ¨ÎGõÏ<€ Oû`ÉÁ<|,ù®ÎáçäÝ©üUÑùº-îÇÒ¶Ù}qsa{ÐÉ6å´#@!£°¦Å\åÔâz—½v=E:êŒRÒ6³ÔåSx"l³¸íÔQ®KÊôX¯¶KÛ0§\/ÞÍÿ[»ÞFßh£cb†ôI€¼ELÉ3]ÂÃ`/aá¡X¾/nKO,Ö¾cZ¹o˜O3}å[l•û"‚ÑÄÑ6f)ÀXB`¤°£$2ÈqIh|î”ã¦a†|Œ®·­ÁGÑqHE%„ øÝ4äjAìècsÅAð0 ™Jü÷ÍÓ(Nצšæ>rªv§ø²·mUWEW|ÚÆâG§ †0°h1ìËi'à5(#n>0dLÌ\!c¨ïLŒô½"4ºÛ^;ãcÙo?„;ÓËøè[øŒ°ÃKÌo)WÏœâ€é^ЄŸgNq ¯ja— ÑËf³½4Hå›C£ý¬É6´öœ•E:%Á'í¹Ûˆ]‡¾ï$®­šÙï²\u0C•ol7ì~ãºnKwœÄöYÒ¤ÏRgÛîøÁ–Á6)Ëk*`››="a°ò§$ôÏvÛ›®ì{ÛLbì¼æ ,?ÿ!¨;q¸õîð;½wã@Û{'¨Ù™ŸÔ{^½î`ÂŒ•-6gœ›CÞxÏðÖf—K0‚ÜùrIµúqœžçþzI„9ëʦWÊb€3WÊbT§XPùo¡äà”Ÿ]Q`_*A5,¨ùbrýœ/Hê”—¹’tߨãºùðk"R ò\è"N¶ß¡\ù%ôæº$S#?Ç«I«˜Ç„/¢)·ÙžZø¦¬oû»¼ÙöѲʌÏFÏdø‡Ò4XßTHMÙ òì1À9÷‚ReÌ»´cK'Ù Ú±%ï ¦Ó0.®Ìù6C¸íá_õa¦³Í4{H@šÃòšé=YûçÆk ù(+ü½™=ç±°‹£{ħršPc‹¡ãˆ P l¿Ö÷ó§M_uŠQ|y*ò}™)†=ÉçÃÖA p¦éË¡#Ñ+92}…ùk9…=·ƒšîäRкɦ ®ë7ß}5©5Ý}ÆírNI½ûŽ[Œé¯ÿüv õùÈÔ´B³ê•Ù1Å9'¹‹“vÉ3N.L¡ "&…ä% âaÍ51µ!Ï•œûÔ6F5ÅS°0-»ø0é'ÌÊ}„P½Ëοòr¶5˜é5gΫߌ¿‡ÁÑ® þâ$‡sbÌôí/iR8º+üs$€çÀH×à²`ˆt!r,Ìz^¹20ঋ+Ês ‹këÁ_­VåææÖõZ*žm˾/7—¾Œ,qö¶Ú<^¸C<+»¾½nÍ)z’UÀ‡PrÐq•éëÓ4û[u[X0Ü|I ‘쿾¨¢c¢˜ù¼©Ä vòOŽ"²íæÂà!2óG¤ÅÁ—c{ø8Ï.£Œ™“èþ8' µ²H°B‚)•öX3>XÌ·gÿÂðüÿendstream endobj 81 0 obj << /Filter /FlateDecode /Length 3188 >> stream xœ½[ioãÆþZùÄÆŽšÕì܇Ñ|hÓM$(+HÚMÐm3¡Ž¥(;ú/ÚÜw†ÃË&¯%n²ØÅá{Í{>½‹¦qÿ‡«É»‰Tk¡"ŹŌF’p‰%‹(! åIôM´žla±Ñõž˜\M¾œ¼þŠÉèzçY0̤p(¬< – [V±Ø®Et̵4úkÍLsa°Ñêû ¾!3ÝóMõT6¹‰ÿnB½ ¢ðÏbýyîd¥‘ÅVif¢ùÕ¤´¨f°¦ÊDš l¬Œæ« ZoÓå/ÓùO“7sGJ¤Ð`U®%ð!ʇùPÙÇÇJÌ…²>géú¬áòÞ¢SFÁÆ´C2½³ï[’ƒ™‚äöÎÀPÀ: ˜õ¥(Ö Çî-úýtFÕ9ƒÍ$Hb­B·t:cÄ‹nÙôûù?&ÎÕÑüóÉüåsDDÏ›§adFÄŒÈ9!çþÏÇþïr-HŽDµÚ¢ÏþôùÅ›†4‘I³>Òj´ Í¿úº$Û¦ÅûhéAZªOÌ6=ÑC>V[2‰a³Íò~‚²àcek‚µU}Äk[S}Òý¦SSçÔR휌¸ÌML´‘ÿæî¶s´¯w ø”á°Ž¢Í•ûì¸3TÜø.Ê7ûõ2]_Wßtµ_/Št³Þ•_Y#Ñ*þ9 —„*”a¶›Ý.½ÌEkü¦¢ÅÑ6ɯ6ùªY__çÉu\Ó‰¨D›µ7ÀPØrÑÈT[=´Œ‹±ã ±{À61gl“®wE¼^ÔJÚû"ÍÒ]°„3Dh± ’[ŠÞ2û¬  *Â%deÊ"å²< ļ£ng—÷/áimØ,›¼WOÃ0÷©&š/'èò¾G#J°P*¬8¯ÓUSª ¥ÌDSxŒ ÒR5ü„/UM‰‚…kÙ”(#@[ú¤u€É…gòœÊ# Ü]Ê­lÒ¨Dœµ" SfóÌ,8£…’YfõókQ‹3Ú%ïŽ)Eƒ‰Šß¡V:ð”*¨û³¡x‡×ñzS¤«ä%4džÛa%8”Née‡TG¬/¦Lö`-`¤iwï_”¹–ψ >)æëù§/ž–Oû91p{mUW©é«Q¶¶‹¼N³5®­$Rˆ­á‚‚%v†’ÓíŒ`¾\œxg†â3ÖØ ãy]ÞRsw3¡X#BrÛ·Üç¾Ê±…Ì'}Ûa¤-d ƒ&¬Ãê…kZ(ô-/ŽÑZ»*L¿›:Š®ßx4«ÛÑ%xβhz£ÑÓ¹’Î1{Šç&D¡±r¥²Eø;W¢FrRŸY‡]üIK~7׆Qìý‰C”In:ÄéiG%¾k×miî’ò‹š|hñØs Í:ï¨všð[˜>´+®-v§«0Üuø­ê(3N“ 40L´Y½ ªœ©0‚Z¬Íƒ ?Ó‘àâ&²Óq0À[ú}×/vûË]RW3´Þ¯’<]¼@`¬pHëúéŒJíz§2 ¢¡ × ?B ð ‡€¥ÇèOIMõ#6ÔP,¡I O²4ITôÃ>%ÓOÄ’>"¡ b‡Ñ¦ú¨<ÆxJ*jãa}Tt?•‡V©©Ø®™¡]z`f3@Ðôd¼×ζ‡ %ƒ&bº6t1bã>çqͤÏÊÈßh<,|ÁIE' ñv°·À"ÔŽ¿¯·{:Á¸ä¬x½tÐSZŠþ¹/Z7úl“¯â"-62Ø8(hB¡, ÖSÖ RˆÕ†"ü ¢ŠU×å ÈRbV±æmãŒ{´--õàÌi¢Ôƒ3æÍ¾ z”×]•z„g-Z&Wñ>«ž†/ÐVÞ¤è¿gÿš‚ßz´nv¶š-çg;?ûâüìÍ·go~ý_E×¢»›$OšË¢–úñÛ—å…µí¶É"ýÈad•qõ˜@·qžúfÙYlÉÐhKCŸãr‹ës ã]&yCÐÜ;™@ËôÚÃk¥)¬Ó¶º •L%8è¶i—,6¥­Ü‡:æ®ôaðHêz/‹¾¹IÖ §õ¦y~s›äyZbœþ>L¢mKS¦»j=;´N–Цp®¼´Ú²f—¸ç{—fYÐ LŸ®Ù~Y-‡ ߬³ûæaG©V®ÙK“ð‚ O²ä6^öÚÔŽZ~ƒ¶9ìÌÎÕþ`¤¦´_y;د¼Pè6Yí›wiq³)Æzåóôú¦˜mãå2Y6ˆå¯I¾ÙU—઻†âîfsW³Ö tµLu9_m²lsWBªá~òK¼ÚfÉyh „ÉnY¶Þ1 ˜ƒ<0aôdªõŽ ‡X<ÀæqqâV¯ê,8LŒ—èFðÓçwG$¤BvˆŽ3VCu›Õ‰`Fè¹-1ÃJœf„] ‚vX•Xeð§.ˆàÌá¿î`¹tðúƒ= äx ,‡¢ç® lÞ•¶£ŒmµhDÖšG@‹èØÐbuâRb„h±êÊøÉ# ­ÞèÀÜ~Uæ“#ÀéýA¢ÀþܪÓFA›èÈQÐfuÚ(TâôQÐf5ä ¬9atÔ? 4Å‚ËgDèýaAZ,´8q ´ˆŽ-V'„!%F„«¡=a ´Õ?„†á€?/Zz!T'y˜³«Úô—¤ˆÓÌ`¼iÝi-ü!•0q1?Vs­[èŽý”#ü¢Ä‰ËU Gœ×À(¹¹MÃàÇýÔvy_ÝäqGL¡åf±_%뢦Æ^OÞ^_ ³_/“<»óGŸ~:ÿwC-K/ó8¿o–ßVáÖ¹®·Ê¡À0£tooe׊ßܤE%õÐK ]€³;¯hÐ0Õ'ù“\xH#07œù·¸¶·X¥¡1XHN;ä{%3bÔy_Cô-DÞtÆ õPÁÝMº¸)/ÝzØ„¸µ-“m¶¹wŽäï‚#œÉÝ7ݦq¸¥m „€(¶-Jƒ9<Ävä@_-¶[ïA=‡£ ˜µ¼«Á6^ü_'•Üu߸·þôC×fèÍr™d—û¤(’ì¨ Ñ ÁÈñW'ó!‹h­OëCbN@}àCx:Â8Œ> u~+X‰Ôyï¢]¤Ž0ÆÕHw3ïrnëÜ…¬‚= hPá0ácâ1C=¡pê‘z´qçÕQ?êq©oâßKî6«z­B¿K~I/Ó,-îýw|6ÄpìP £bL…QVdZÄë†áeõ½W)xÊLäc'쟖ËÔ=gÙý”ò=¬•]¶»Ôi.”ª÷=™ui¶m$ô²Œ¥n–˜qîzŸ(—tIº%L°°äeÿÌf{ ±ò‡ÛÓ²…ilÊìwɲ#¥Fc¢CŸêϘ–XhÐ>©ðHÞŒý"(.þHf aêPAKü“{×ì/*ÂæÉXf’Ò ®`[çd5Š›vŽëQùƒ8;a¢N dUÎÓ¢<¶ó4¬úÓÊ}ĉŽPë®~c»ÑØCrz•þ0.Ò1FþiSÙ…Z¬†\ˆñʉèñN¤9Gêj8²Ž 0{_'ªÞŒëDÚý0”àC-Â#»PÃi؃¸GÓª³FÇ'#N4¶¶£å´œYläN½mÝzhÔ%BF3è§Áà~¸Qa¸áí•î\¾;jXÎ?ÿyÿy¼K-È Ó1u¿å°)$”Á›¢ØîÎ_¿^äS§™ÆOœÏ¦3D·ùæ'(ð&¿~½Sæ€!‡u|R»ÇÓàÈ^‰$ÌåŒu*‘©;0eˆD%Äñ*ÆÒ]¤ÙíÔ7°+É®ÈÝF7)3”6¢|9ù?¿¤)¡endstream endobj 82 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 212 >> stream xœcd`ab`ddôñõÍÏË74Ð JM/ÍI, Jtw?þ“‰µ›‡¹›‡eýw+¡;‚7ù¯ €ä KóKR‹3óÒsRõJŠ ÕÛ˜Y¾¯áû±ðûDzï»Ê…¾ç>¶?+.œðýø›¢ +ç•ts´±•tUUu–pOèö™âÕçÝSÜž¶©›cyïºòSÙ…zôšp grÏÔîÉ| Ó~8Oûn;­Û ® Ür\,!ù<œgOì óû'òð00þéM~endstream endobj 83 0 obj << /Filter /FlateDecode /Length 3773 >> stream xœÍ\[oãÆ~7ò#÷!4vMÏý²Ò&m“‡ɺ- 'h‰¶™¥DE¢×ë"?·?¤çÌpÈY7ÛË¢ÙVÉs›oÎmóë„ätBðO÷ït~ò뉤67FO”å:gb" —¹dAiε¬ÊÉ?'‹’[-±“Û#ž8¹9ùþäâ&'·kÇBçÜJ|@äZ‚äîç¹Ñ4p¹5\‹ÉðR@ÓÒÉŸ{^š “+6™?á^ŸHø/tË/á©úä=<‘Bƒþ\b | ”¸O«[“:ãLº¦óÉ.Q =±¹Uš™Éå͉·H‘3NÕD3‘Ðír~r•ýîìœI²+úÓÙ¹„+ÖÊŒFΉ8'ü’²wŒ¿#`ƹTÚØ7„À÷³Ÿ.¿;ùæÒÉH™5†ƒhÌ0|Ì2«÷‰Hå^)ËÁò(bV¬óE±hÚj^ž]þÒñœìQžn£La¥µå å³`ÎÁ¬ÒÉn-‚ m­±{í¼ƒ•Î )bu•î°éÏ`ÔŸÁªh|™B³¿_þñ4²î³5Er%REÏ"EÇ@Á½Æ?¢öèLQg©`7Er(žkBÙˆVÅ¿.ÚòìœÁOÖÐl].‹UÑ6«u÷›Í¦Å?[Ðßd×¥ãñƒT±¦VçB*\.g@óË ‘þþT ™+k„¿={‹Vߤ(s·þŽ/ýéBÊ c»[ηaœ –RI$ѹ%L>Åb¶ s)ª ]ì”ÅÐC²pŒøpW®Ê"¬ƒáY{ʪa¡ºµ!Ö¦}(Ë~±t6ë–Öº ƒÊu—læÜDGŒÆK¬w-1c<§›¶|j„ÁÜ—[TŒÍä`„=¶1¥*'œžàʃ«wýnb¡4Æ@Œ M[ØÖFí …;p‘pˆ€p0§!j ^Jwsx?RØPC ÏÏ6bÊ#‡ˆU68xFDø¬2‡ϯ ܱ–©–#Ç %8º…ãb† ð÷‘{(Ns ™Ø Š( ¢U¢ ".zÈýÙ ë46dÀ±Àóÿˆ!&'£xðØxé9mOU»ô”~W#tnDb´±q#-D[y$p‚ÆOC¬`Ü!‡k&ý•‘(ìÉìÄä†P*Á`y]lU­³ qS} D*YsýK9m×w˲jí%µFfןœu—´ÍšÅ^¹8CðÈ'’…M¹[2®@2@Z"Y UìglTN¥}IxQAø6“tëEb‹°lÚÌ—Mg¼ «y3|¾nÚ»°®‡„î±(Yn8;ÂZ”„©œiÆãG¯²u[¬ZÌ¥ËÇ»ä\ºt¼ô_„[Ô ž¿(2_ÀS,{(ëºû¸ 0jµM ÍAͦ.‹E¸ EY{WxŠYµ˜UÓ®Lðüª›pŸ  «¹_ÌŠUU:"ÊYÑ=`û²Ä—{Õ¢-W¸Žx›kU¢4K_ŸàÎÊ|í‚ÂólZã2ù­Lñ¹ÁìB¢í «ÆŽR·=+'‡Æò47IY\䨎h¸(²þ)3(Þ_¶ÙõãPK-W埪Åm`#eã° jãëP9?T&¸!ªÓŒ¾€oΦwP³MÁBëíÕN€9ôJ+}LÁõÂ86·€èÅ9M8ï*ŠÃ# jmž+ì›]Âò£e•6Z¥ÐÈa?k(ãŒõNܯ޶›‰!"ÃV3¦|›ûÁ:ÒŽzWt—QšmK)±%Ϩ–Ï¿ÕÈ$¡­²Õ ‘N}4’ò¶$ì9“y_`pËOÅ|YûmlчÜ4uÝ<œQŒ§ðTL‡¢Y(žËö%ª”`q¥÷TÍ»ŸØ(›áFP1TÍØÜ5ÂU6ïa1VÝ,a_ jã 6ĬWf°1å‘S؈ä°o\JGü 5ÄÜuÈù˜}ýÜßœHç¯kÄ A]§69ÕV@\±{RÝÈ0›ERׂ¶;L³qûù¸E•0,¾Úû̘Œ)ŒÉˆ`òü©é)vÁÃ5/W½/þZ>üü¯fõ! ‘m_áWâÍ«`* "X–|t˜B(“\ïib+9Ø*…ªØa— ¨¾·ŒÜB"LûÔyv±´jùQ`MÂFøC #â]ýF-u!/ÔoX‡¡w õ~Ç´ë7󡀬ÉÅNE¶ÄçHP¨rëH²{ÇdLQ XÚÍç÷mq]—o!ZŸ¯¸äÅk9ì¬\´°ê ÍÚ&|îROj¬ûr×܇2•‹8£2 ò‡ x ×$õ–îºå ÙȼZÜ·]é“Pd𸾀亜6!ÙLIðHô%$qy²OÉ éVbÙ¬Üö©¡¯q¬s8Ûqd”`,bµ£¶13Ý~Í·N@T€Âv8w§Lq¬~w'Z»ŸØH´àF–³þ„î;.ÍÚÃ`¬4KG“¦Yñ{iXƒtQc¬‰¨Ö¸võ[Ìê44ÌN_£ìlfR ƒ¸…4{oªÔ7?GMt¸üÞê‘PS1«Óá”ÿ5¸ð‡ 4Õbl\((Œ¹:9RkTca#¢>66"V§ñȫР=£)ñÑÑ!°á·ox*ÖndtpˆXRŽ…ŽˆúØèˆX>zFˤí‰6cc„Ak÷Cm+gSÎÆÂJD}l¬D¬N·ÙñUh‘€“ª32X`Usª÷ÍAËç/h™R8öÖ×ËrU5³”³XÎ…Ó" ¹%4&~zÙ~,´¾Pá}AŠ•Ã’(ëâïèºóhé…b©xU?-¥R½ýf¿)8õDðn3ánUNO¹‡Y ãæºµî£Ææ–¤îÅ}'1û ½Ís&|?¶óÆÄ8ß‹7±ØGàmVguõ!Ð Ú·ªýï11<Ü^ÌŠºYì7÷!…Šd|Fûšc©64Ä¥QÚ9Âo pÜGn§¹B3¬Ë ’é¹ûâãxÐCF¦€Ø¿D™p¼ X(×w.Ý¥]„^«ZÌŠÎûu—½Gßz¢Ï¨qÛÁO- Ã&xv÷…Áß ÞðÞ4ŒÛøa|OBúÁž¼1ÑßW~Z‚³^dDBÏ`ýï½ý@J2½“ãgzÈÄP0aEö—rPHÇÚélÝÌ£w@ÂŒÀ»m³”C~*‡~°Ö*G°»E½û‰5ÜÙ\ߢÖÇøQ]ê=<ÆêRSt,©‡ú¥u"ýMhU'2 )MXÒG:§tvÎ_Ýzê¦X…F®ñD‹ª½•"Ÿ›TÇq› P·æŒÐq Ñ*«Ósöøª“ ÈÛäm‰øcCÁšò}'ˆæd@ÆÈ¨€p xTD´ÇFEÄêô³ùî@#ÑclxpæÙ7þNbplº¶—(ê²½½D1ªnúãòL¡ŽÒfåô s')yv·ð§ÿ¾ƒÂ²¯Ë¶¨êõËâ“™[,@ŒÌ‰PÝ~ùÊcA™-ʇeè¬}\–ý4.Î6«YWÂBý:ôlÚ»Ð&¼gYL?·aB—!!ÁÉìûªn‡kÃlí{Ñý µò´.Öë¡Ï?@ÎTT‹h,ÈöÃÁ:ûa˜ƒ\®ªy…%s7² J ]¡ò{ªC‹ÊTxzPt»QgÈçÚ0·|ht\cÓT=gТ¦Òš'Oö㸻Fª$ì›<²¿ü ÌÐ=*«â'¯üªpꇈ~tSÓ«rÚÖ°ñ÷þw ;ô΃\”@–H×Ü_ׇÞ8ðé]"ÚǪ@¾~ Ñ•Z^ëWsïÚ$ôB«E‰¯ ðHR¦¢Ü¬šù`¦¶/R©‰ àÓ ˜J˜_WíAÆZ€gIùö›È™vßêj[„¨“Å·#(„íäî [;*@À17\+œ0óï e+ïêõô®þÏmyÜÌáÎ1.¨ü%Oh§ëU¢Sbs!êîÑWIÌ11Ñ+RX’ºaDÚ¿Á½·Ó ˪i"Ùžwaâq2(c¥0É“|¾QdIÊlgÓ?f¥üÄZ¢©÷×”¸ÀÓyœRÃ@yðÍ# \'r`c¥.?èAÀ¾UD§‚8ƒ{ï:ñÔÏÇØ+]{)Ihƒâ5F³uÛ¬|ü 2ßuâf¸{Ó•ÑR@¦îÍšë>ÿ÷Ðp¡€\(:¦*O?$Œtqü›Ù¬¬¯‘ŽÕFf÷ح߆ F³÷UýñÌá®–ëgQ9Ͳ 2e(Ëù>ºÈij`ã¸Åy(ž6‚1~ëd³±hèEp)»Iºï¼ Le÷õòa: cN3Fƒd–ú ³M]Öýÿ«á7¿„ W@ª6aÊ0Óý¶ûþä¿‘ð`Áendstream endobj 84 0 obj << /Filter /FlateDecode /Length 4358 >> stream xœÍ\érÉ‘þϧ@(B1…¢T÷¡]ýeÙëÙ{LRáõŠrhJátC¤f½O±¿¢_ÙUÕÝÕx˜Æ+ý ÐGV_^uàÇ£|Àðú;ž±Áû£x¸:HÆóÁ/ÎŽžø¥^p&g—Gñ >ŒQ­á–°”;;8›½%gCë©·ÆâbÈe‚ 2+‡#aeLN‡#©$õÎ’WËùªXO«åïÃÞ‘åeúlDEÅbYOç@‰1ëÉqwÿ¢¨ÊôÍ r’á¤XL‚‚\U(ü÷Ù7G¯ÏŽ~ò=x_)|MªÁÈþë#Áœ¥‚,—†:>˜)$¬j¯ÌŽNoÕ—C c®§!®¨e@’ÁP&*¨.«„áRs².W³é¸¨§ËE× /RΊUUNÂ,Âc3xæÓP ÃÌ’L”–iÆ©2¦Ó•G3m<§š©ÈuQ á²÷J’Ì$È ‚pÿ@ãAN•LÁWwÔyXd«a´oÎþe;ÑwWÓúûˡDèhC–k$T™$ó4§˜sðΖ1­íÆ”T{ÖŽi0dýÓpd¸ôÛåñ=ÚÖñûäùþw§¿ùÏ1ZÔknRäÔx÷¼„Êm¤‡D.‡È: Ôê–â¡ñcœéŽ1NñîØ0Êø áë¨àOµA¾lð ÉtQ—ëËbŒÑ°þáÉÅç» Ò€\{0Aàòd¼ZÝ!Þ8“½€Ø—ò8sÏrâ¯'“rv±)뺜í¤Bn€9QޟɹÑT9ŸÑÞÙàÜ*Uf47V†˜ù›dïéâ=Üø`ðz‰€`ásô#ìåz9·È« (2Hp Ò0ðÙú…°/†– e’rv!žk+xóÚ´J£sE&ËEÙ O6Uä2Üó÷†.‡•¼Ë»1© K8™+kUŒ?ïËfT³ß¨¥ØÛæãõ`ÚÞ³Á¯ÖÅâoKPÒN±KkLµ7·á  !ij'©>¡˜óÅ EHÂB¢U2Šÿºf€z„éé›j_™½ ò)ëZŒ—uŒ˜ÐŠ}„Q^8X뮜—=Ù„‰Åà ›<&²´ÀÆö™Å¸Ò±Ë¼ VÃ2S`Óà Úk­ì]Ü{¸cqµ5Á€ê­I~ò},ú è5äøÑbé;/ãò1F¡¢CpÀ›tÐÄ.œA¬‰XÀ· †½ õè½­XS~sòñ8Hb £È^†¢v³§ ÐB1ÏdfüŒ ^ædµ^~šNÊ*]¤A°,/7³ô $vìüfÓMÕTU†W¦uCO¦è‹ýTL³jÙ< ÌW³r^B˜´D:¦¶óÕtÖÜdLÕI‰¹ÒÖ\gmÀÞ®EÍ0GôzÑ;Õ(n¢D@穿Т4غ”Á¤a¡Ó½'…`Ë¡±ËhvÍñÜpРÁðšsÓæ’ÈÌ*àlDÁ-u>2^߬/ŠEùñnžÑÕ;ñœì®Q)#và˜2ê,ÌnCÙê™ìëk\iD€xy=.gUúŽ0¯£Ið^ìÎêPh3y+‹²Œ›…lßÅ{ØXeOÆXtŽÕ¦în^bxªÈs J*˜9% lº œ‘²­’°FkpT¢#ÈK”Õ`„“ ˜ÖƒçäÍÙ+ðIHuúìr˜d<¸í¤¨ËØ;JË‹Êq N«”´_†ëAÖ*D€ø½ç¢\Œ?Ì‹õÇæÕW^‹-8~‘­>Òõª^ÃsU÷2gÇ,>Ë£wWé6Î}U–WíÓè»EF¬¾/¶€ú Ÿ‡¿Šº8³DÚi™­®Ì¾È?ȇ4müoÆu˜n m žÌ7ã±íÏ–U¹îºÎXX» Xä¸éÈ¡[¿l’W¢fÓ¼žoU¬3@Ëp mÿ]òJ¨d39Ó÷ÇÒVdHÙÔ(ÓyU¬3a‚ S.Іœ3‘‹&È|¹nx箲¸;Xêïñ~g6)Í©åúògÎy@ðqR?h´*[®49zƒÄ‚‹Y¹kPnr€bÔûÊC4°:ˆ±CÌ•£VôȽŘ҈Äɤ¬‹é¬Ê‹Ð”a ŠIåSX=ÝÌ!¤©fH¯Ÿw(€±¼sPD)ý –ignSv0ƒJg¼ž^”}?Ú’Ã ø»…î4ÆÔ;\]A@Àº;ÅÕ¬áó!;\}˜w pðÊËr]uJ/ºú¼üP®¡>jnzYÓ@'Ýøsè°?¯Êª“¡šÂ¾¶7wž7'\»PšªxOêÀr<ÅYÅh~L@*)Tõº(©¨ö¼U¬BôA».fB ±i £Uˆ°aèÞ‰B®°•²ùw)=g;¨\TŸ»Î i*+s]ôåd À\l¦³Iœ3}†\Ì–ãUó½‰Mñµðtü ,4Ñ)‚%lX_h§¿x3’&ÃüXYÕi<WSfVÇAE_x ä^#“dÓ6fZŒ¨õçz×2ÐÒñ ÖK] L^—×u†•Ëí‘TIjSŠ ¾ ul_B‡Ú>=‰ÆAŒŸ–Õa[9ˆª”ë°RB^®Våb2½Þm^3õlÒÆJ*®¬E„lq²ZE8R˜q3««ôTˆþEóÕDK…gý{È »¸bdÏÙ}LjÈ)Æ4$›žŠˆmš1l'tiÀacæWÒ!ycÓ–ˆNãÙf_Ôa⢜AàXO‚?7TLã':D´åä¢E|/ö¬Ÿ¦E÷ly]Ž7Í Gi³˜„ê"±qÒ±Ú,—ô| ú+ÑB€”rQ^hT4Þ¢Èz³X¤ÃŽ›!R ðæb³¨7«Yè·à“ßN›ë.ä,׋0;—œPSx$} —™ígf[ÛA¹vä,cÿÑÅùWßy`Æ“7YÿñHE-Td\JKqÆŠIM!Y‚ÝaøÁºüa°@@ÀC`þ÷÷¿pt™㢧Âç þbÉe‹F@I@¹k(£ ¥ +¿Ô-Pý¯0Æip.@?„‡úã‡^ø;ãTsÛJC¨8$k Y[Äôvaé!î³½à„h$q/§zÞ¦/h–ºXxQ¤ R˜}‹’Q='ë6üZð!pÉ} “Q=og`¢(ÐCr…ÎeØs `wýnµ¬¦×ãЇ *òo£<€ïOvœ¸…4‡qN¹P¶â6…ÄæVR,åûkcÐR‡4Œ9ç 0 A ¿‹÷Û†‚¸cy>Ô[òç†GLŽ8„4öP@pϵ~.䓇UøÛ‡¸Áô†Ëg“ð)ê8»§´¸…¶÷TâsÚ8õðx;HUŠÐ};DÐ ¨ds7ÎëwÝNÉÃÊÁQºbŸ¨Ë(uÝP÷ ÷i„ükÆž3¶ Ãì†3=I÷…B(B)®ä´wD¡wÔé¾YRäƒL ©÷V†:\ÿ<ÑÏ`µ¿WfÃn¨ãïÅ>âå:¦qñì·åÕ»?.×w¦‚ªKðré÷…M…R\öhï†M…aó¾­8½ + ·‚sÉyv2£ÔC›Ñþ'š¹=Io¬f=ÖŽÚBæR}9ÿIväÐYo[olRå>ì˜Ñþ`Ç\ÒüÈÂîvìÉyžÕ!Õá i ÔiÙôIïLFdA§ ƨoEêŸvÊÔ1Êõ‡ÝfcßÙØÎÆŠã‚ZÎ;l:ürž÷žÎÌâðf6Šºf%ö!fŽ;@v›Aá÷ÑöÇ~ÑYõg¶µìç]ÎÍžl¦üÀ\9å¦>Þ±º»¥¥aв¾q“Ý^¤kš²|¼'O磧“ÑÓ?ž=ý÷çO¿{þôµ?}úú§]ò€6†â,i7­³Dúβ?}¶Î‚‰ˆ§ÃQýc\³¼ÈƒíÐ]Ħçc¦ƒ@;$R§@ºGó0l5ÈðZ5ûf›y«,ŸtuÓ/5NúC&ˆË¹ã]Ä•6¬#fL¬ÍU‚*%zC=ÁC;Õ=©Mω†ý9û9Àw£-k.†0¸¿°/E:W¹‹ÍúáB‡ý#7ì‚îTBK<Ëo¸Â°7¹°ÿ8àmZÇ?)/ÃÉ`®n0—=ü!Ð¥*†»j¾ÂãžY›JåWËYy±Ü¤³£ÀÈ¢9(l=9MÄ­þ1þ—a!üq+Rüùf9)FgÝ 7Râ²s Uo nw8˜"oN¾}ÄN‹­¢rÇ bÔ}Q?ÔõªzþìÙÕÕÕРV$ôà•.×ïŸá‡ÑpNûp¶Ä<ÛEÛ¨7®LΡq Jµ‡bQ¿\9Î+ E®ºSà‚|לâvœœâŽ;¶#OxÌwñ¥WÑœ =¾ììw·Õp¦¶Ù)÷¶Ý.NUx©È¬|ŽС,œ¼¾®ËE:¼šÎ”wçÏùSxûráj5)æåŸšTÕ×T[½Åþí©t…ÛÀ†¸+CpNš]yq t¶ÛhÒž¥ §× §x†ë¸{rp’ã”à¶/ÃDN¯N^þ–ž$èà&ÕzöR#ª¢ A†[¼“;s–1•¦p{ø‹ç›¢Z$íQ³èß¿l”oh»ÕÕ%nG7ýš3ŸÏ;Ð}…×¾Jôο˜.&qÃwÁ’xhÍ›m¬¸(íx³a£ÐWHô«ßN/ÖCÔ›1žà¾9â¢$Ÿ·£L›0§ºo”Aœ£ö¸#±Oá‰M1°`N/Ì#1ÖÁÝXx*Áóœ“X¸]Ôè,ó@\–$™Ö~5T±ùˆ&uJt¶± u'}o~CÓ²˜Ïʪê‚Sfæì7.$yõõ× 2yØ–õ~Γ G0x,݆¸å“xzAáZØâLþ²ÕpÒC;ßàì›6“rkÉ"ÑOèΣåi ÃT5гÎ)N——õUÈBé°…o°=9ΛJÿ8fXßK°Ø¦¸f´bÛ’°¥NxÓ²}NÜù0Ú‡ð¿B\9HRÆÍú˜ †jí:„§œ¬}˜,¡?T ž ´ÐýI±gSævÊŇœËGŽˆFÕÊ ÃŠëòh¤!4++#tÿðK- B×j0{òœ‚¼ž´üçüdTŸZ£"éJ5v£lg1Á± kn[À1´Ó1UÝŽ4£‰CÉáÃáK¦“÷‰W“Óé,ÅO¨S Ã¢%Ô–‚L;V~ôw“¤Ìnendstream endobj 85 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4137 >> stream xœMWw\TǾ Üáš *›«,úÛë‹&1–Øb DEDP@iÒAzGÄCQ)R]PADiŠA) l‹%!EMÌÜͬï÷f—ø’ÝöÞ™sÎwÊ÷€RS¡Ág^~®¡ÁÖ.þ括Ü=CÍB\|ïgAìÿ×6¾¶~ }ã¼dé²åß®\­ûE}Nm¡æP–Ô\j+¥G}A}IYS_QÛ(Ê–šOÙQ ¨íÔ:jµžZDÙSFÔ7”eL-¦L¨ ÔRÊ”2£–S©o©”9µ’ÚL­¢,( J“šBRÓ(-JH}F±Ô JDͤj5 “R£t©4ÁA˜`LÅB%JåŽÊUuU÷¨©©Ù¨©]T¤¿¦wiÀ4ƒ‡êÓÕ“Õ¯©ÿÊX3 ̯“VL:øÉÌO¼?Uÿtþ§5T4Vj$kk\¼nrðäÓó&·j~¥¹I³jŠÑ”˜©ŸN­›Ú7õ=ªÔ”-†ä0Ì/‘øbÀ–áú-øRæGc _þÁþ )(€FåÃ,ŽÈ=£5ùv(á­û÷H´ø(é a-2ã‹Y¬*/¦Ÿ€TO ï!•S÷{_Ìl«Ý³ó@rÌ¡hο%‹?ð鹩Ça®è¡mëj³@[;±°6·›V82Š2FQ̨?0n5>CøúÑtôŒÂÎòö[ŒðMÃ¥’[Ý:°#ðœq#|ý¼®µLžO8³·Ì«Æ%ß2¸”á¶ ÅÐÈ<­ ´ôˆõâü|ÜbÍÈr~Æ^E4 Â7÷j},Ýã÷„úq¾nîQÖ!A… ñ ‡?HÑ€T•ÿŒ¯a¿ß¹l7ܵÉ«À• V2@jã놮‹›;«>‡íá—÷T{Uí*Ø ™8}v°ÁA×2jcàÎÝÄÆ“ødäÔöûem\mïõڻČÌ#d„ÿuD@NR•åð=|kßùˆj×ûFµ‹ žç;®YôýB{,†x4–˜×:6oí ƒï᫺†³×ªG˜¯Á^«h¿È`—-ßCfŽÉšü²â·Ë¹Ž ¯àØfŸ‰)EPØK‚ô•ñ¥ªÇ°ûÜFÕ•/õAÑ0|Ps¹óêÝêßá/ Ò0}0ÛÉ).ÈMìXôD[ ŸÍìƒF»6ʸ<6ìðÞ™u;Û~¸]Ø]q…«íi«¾£€ÁQþΨ@*ócå% ê;šŸäWä·#WÑ|;(¥åßÎß&Éöø{ï‚qÕ±éè@|Ù40Öû¸} Ñ48à7èXï^m[DLásÀéÃLMæïÐÈüÙe>g±Öp3çìô œ—( UÔNú(Š Lô”å9PD¬Ím(–æ—(M§¼˜T3/Q>MôŒÔp„ä DKØŽLÿ©ß›èt)Òìë@*‡DEOiaqZÜþÔ„™[á® ÍFŒ°ü]«uÿcý¦8ÿ6aSšˆ0ø#Ðä+ K«ãµ¯ÙJ7Íð9¼&{¤85 æ2÷M[æY„ív{î ¶ƒŽÐâœÿ»ÀÁíªÄüY ¤Ø%IԑѾÑq{Üãœ!c²»¬íhjVj6·  I‰‡ÑŒÞ}Ä ¯BŸvxŸ]^"68A ¬óü%¥:PrütQá©“Ù¹U²; &¥ìç4QeH?¿°Gðó3U^…€° T¢¹ô*à‹çÒF Ö”îßËAò¾”¸Od_íwMR™ž‘'.ðM:HŒŠBcs ÒS¤å†yUz (º¨Ÿw¤/UùðéH•/&§™ã¶L¯„"›=—2S³Ò²¹G¼:YZ!Ÿ§<=N´áŠë³á§®ßÇ[ÑÄ1(‘Kè-)§EÿÂR™5º0u‘³—|X®kÏëÒ‹Á ÉŸì'\Wå£É_±@žoçºWèåÏʦœÔœôã\Þ]zˆÝt(*9 ÆŠ s±Ku@yhõ¾Vˆ´á«Ár41|£¶¢\•Fùöé¨pÂèvùÂ~!ý9À[å #ȯ%à1?¿ò¸|%=ÄÒ!A· ¿På[/³‰É‡à!ÈÅgI2`zj:×…®-ƒf‹zMš>ÇÜJK¬!~²Êååå•”Ôç7@ævs Ç¡E²G&ºF$¬Kax—}ö¾vÞ~¶p+£wÕáŹúc¹5â³9ùÙk˜$õCê®å{[rÒáÑÓâ´Ô£äË` ™°q›—Û.‡Œ•Ï©úªUEÜ©üŠÌÖc?æf¦6æ3ÿ€ûIX‹²éùëámËÑ6ú€>ÁÙx?–п´9¾ÀŽÊ„LLM¤Oà9,UEî ÌÉz ‡s}³bócD¥Acaì«lºÔÓ׈|Ç 5ƒ'_ºíŠôG%Ä%øzßDåÚ/°„ £Æ*j“¿çºÁN1j68·=ºSÔ[ÞÂÕÝm?w[9©á¨Lø9úOmðöÊ”+JûÈXâO²¢«cå vò 襠W~ÚN7Ð%zŸíƒI©éÑkµ‹öO>ûàåê†A^M¦©ý±[¥èiŠô†MÍ'ߘ.‚U‘‚Ê|Ϻæ[Á¥P×ÝÖÄÑ àbèX`_¾§Ú¹)¢ ŽÂ{gš¯–VT\gV¿ï¶9­'ýêÔ:ÜUü°Š Ì[mé¬Ûcu€4a"§)œ¨uÞs:zοŬü-i%´XÁÂ3þõƒºžLÆìD¤d…åß‘=Š„õóSûüU©|ˆYO£K@ÎÉ5# iÞä÷Óøàgñ“é'ŠÐ›LL [¶àjŸn·R#(ºx*^†=ñ¤ƒßšóN]à*ŠróóÊ£ ´GžÍ»²ƒ;VZF[øÙq»Mí½, cèÜöìzaWÙeîü½–³]Jr›ˆDVOŽ_°PþNç¢çüßu-^ŠÒäRúýDé Ó~´dHðd‚so£86½0«åH=,¯~€©oW¹šî;š{`u¡ÍÉmuç¼£o@¤ß V"Š ìibëi ™ïwµ>-NÍÎÈçŠúÙÒWƒ]#ékrX»/%)9šSÞ¬Í"p× /§­¨°ŠŽÁ£0/9ÿžvdFBj4Ô‡Ö»¢ #–i+à}0_¾“ðÂÏüNú˜Lõ£(‹°×´qU”î°(tÂKM5m5áóÞüÖãk§Öc~&{ eÑÈ ×{™ï‰÷ñã¼]œ#6)‹û÷#¶Ÿ_0$$”ߢÖÄTíË -ðÉñ"­q·ßlkæŽi¸˜Á‚>ƒ··ÊÚÛć"üñ,›ÿ@Ñ·²&î¨zæ*õ”¸”ýð<$Ò¿¿ãÏG}§šÄm-eeHøšß¤7³]õk7GØsÞ–î[ cêÒöèva×™+\M÷õÚΉSO‰JMr_¡ÊЀÅf~dS%ɶ)ƒý;à ÈéO)¸‘ОÆÑ^dFc àìO+õ«‚`ÑT¢_m'6+lÞw[HqŠll¾——–—^À!ŸEØõ ùÞ$ï$#‚®'wœõ¿èq7l¢ï!b¬D_*vi+3 tãö¿ÝP¶šr,ΚÎ/$³pÀcò«ù„–þ$[”ssâ";¢¼†lüGÆÝG£äò° ÷NÏÌ֪ׄ”¸Ãqœ>þ0±V0|ïv?]:ãïa¢·ÿHVñ“ÒsÒ«`Ž–Æ—‡Ÿ =˜½n„VA–VÑ×w—™Á pgø¦-ÌÄ¥…I K2P¤¨„Ån 9ÓÆÀ ;ÓäA1ŒÝÈÃn2BÑnÅ(©_€~GÝ,ޯܱ(&©>¯wìE¹ýN^ìåƒÈ›,>ˆ-yG;‚œÛ’Òó™uÚ›99Fê†}¥=1Í ~‘¢!24VÊv°«¡‰›õwæ‹í±)Ä_@‹"Û³¾•~­‘-ð¼{þæ“®W-È¢9 Ò4À´8^Ÿí®sÔ]äºëqn+Ý Ùš»·<úé,šþ1W÷¸åÂÇY àUù4Sò4Z ÐÙz+°ÁTXžg®p>çëÉã q¦ø9+Ÿ [¯µ¾lBj7´‘¨§û1ü 6ÆÔVxw(Úñ7p¹þn¼†‘‚ãMÇ+ŠNW6¶¾ ™ûÍΛ69lYíÂͱÆ‹wÚ8á"Þ|ŒW«OŠ:¤N$Ù¯Qf‹Ó²a$·ÃÇ­^V˜ZcˆÕŒë:2SóÓ ¸´\z98ä— #‰üéµDÓ^<¬¸~YÜÜZÞ»áÐ*ër2Ož¶ÔÞÓ‘®¿‰UVûm³û{EºG¬'®e7fÊ—T\l9y2ݽmÜã<ÂB¸@_Ûèu9â4X€þ‹ôYO¬Oà©Aú„Ý ‡éÿ€_xÚ È¿•[‡/¦Ñ=rƒ¨uL°1êBVCZ¯¥¨MêLBúƒÿ“Ô/Ùð(3nrgö"½óÌÅ[—8bcrd0óÀ}òt ¶ÿšXÈ_l/íëÐygÔ;ÛÌ:ÐÊJ|­ýã < % NÆdÆõc„ñ‡0E¦Àä”d†ðûrVÈ÷6;mÄjzKç™Ø·ö½yú–›p§j… i JI‘ã¿P,?‰ýÜÁf ü‚ùbÄ i=é;Ûy],”7´œ¾sCÞ l´>›yäHzzÚÅÓÙ™FøWYuaK™N±ç‚K½Ï9n"ôe¼ÝÖÅ%dܲ#ê½dÒØ^‚¨œWx0àµ;ÚŽð[å•ÑÎ[Ï9s|™ʇÛ\Ìæë­ýÜp{CçÏ#Co”þõ‘ÖHø³ 5‚Ù¿ç-Yõ‘mgÉ‹°Ï*,Àóà~w펌ƖÂGÅ¿ikRÔÿ’…endstream endobj 86 0 obj << /Filter /FlateDecode /Length 2333 >> stream xœµYÛŽÛFöq¾B@^šˆEõý ¾f3qœµF¶ì…Aih‰6GTDÊŽƒüEùÂý­ê Iåu™À0d’}©®:uêTûç ÍÙ„âŸø»º:£“õÙÏg̿ğÕÕäÞâl6gbbr*©c“Å›3–SªÃ°‰b¹NM —¹…ßÅÕÙKòðò²¬—§äPv]YgSn`>#2írgœ#wÒ;IeRÁ?˜"û ¾:¥5)¶«¦jÓFæ~¼Î)Wän]Õ¾Œ©$ç™ ðE­ú¬Ý”`ΰä#¾W°¶$?Ä•œ%?d¾3ÃHsˆaù§a™Ú¶¬ë~ô“~qKî]ÙÆ5ÁcYbéÍdäþ¦¸Z–ûtxs>XñŠpÊé«,Ïþ½8k;v0wð 8xq v»o²©–!eq•QXE3æH]¶m4Ñ2L,¶—q;+Éý¯¿Üõý¶+׃£S°däó®j¶Ñžkç<7Z%{r°Åjòù–]±ÊF×(ò®Xâó>ã`Êwད€¤\Ýñ{²( €¢fb˜Ì7ˆ'òlþ8[¼={¸8{zFs@œÝÞÿiÄÆÅa[#5¯þ’lºn×~3›ÝŸß}’ϧÙÔ ÀB»}ó¶\uy³_ûßöG”Âñ[ŒŒ·>Øöç3(ÚÃ"Ÿ6dzN™97b2…í´Q6x¾O,ð¸GÙ} ªŽ0´>.ª:øŸAŒÊ¶ÛgSOœ[RřƑÇq ¡ÉÜç É(>a[l›®º*#8!,ä ¼jËU³½œÎ˶©] x°f£Óyãó–Iš}|IR'!ˆà7æ‚hº  «c|¼o€1:Âàa«Õ‡hÎs9rbmèÀ&)ƒØÉ‰¡°µrŸºìƒ-œ#@,ùø&0SÒäÚ ‰(“øA鄱!CÚäEî¡I#O½ì ¬Sì$™HB$ñ=å‚t½Ÿ­¤Â$" ‚h=Eü~îW J‘"¬%ÇA+x^-" Ò§C¶ðêË,PeäPë;§Ä¡Xšþ?h¡Jäš÷D©ƒKE Baõõ]פLgàäAYÔÕvw‡&f`Wÿ9¶ „Ï uáqÕuu9˜ ]•ûÓ€UúQqX7"8¿¬ë¼å°P]À†9§ÜÝI¶ëÛÀ늺…Nà';èN`6{ª­ÒJåŒG]2ªcØ `ðn‚s(¸Kûhç–_Ç9ôüLé`Èbƒ®·Ì÷°?íÊm|êhvøÈ=N}סÀ;á[Ð߇ÙVgÛë“ïm ó.våªúÇÊw½mäÈ÷m{è­aÄÜ ŸäBz^ôyÑllJœ1)1Åû§Ù/#ýÝÍžË׿,/_¯6Åz$T¿_uÅú5g¯)F ð‘¯! 7È!]'Š ¼îq’EMìLpê³ý²Ø–ï’šä¢oô‡,8 =­R=…P´ÝµnýQ&QLÛàÛ žuU]u‡­¶«q#Zw˜ãöþ_6(rªõ|Šþ‘¿«ú¶EÈOeÂIìAO!$›Ü¶Á»(þwÝhPb¢A2sþYRÿ‚ù$7½0€Â‘Iƒ(‘×ÉRƒòv¿ØT]ª”P6îõE§šüXÕu™pÁA„¤Êú%I âT_µãµ¥õX­«¥ÏY‹»bûËoÿoI³$˜H` ®c˜ ¼ý=†J#ô5¨¼Ã2 ·.\w¬›f]—³Õªûõ/unGhÝù>6#@ÚOÒPŽ©qG9á ’–Ssô_þ–ªo¸a½“èƒÅëT¯ Çש˜¥Ê¦J[ÆsÑ_Œ ú¼Zoq-ÎYò[Œ™›&̹éÉí<u¨CËoHº”Œp–,ˆ`^ 0¯)sc’†mãUÀh„ÍpAÜ•¸þ²ýéÙÿœm 9endstream endobj 87 0 obj << /Type /XRef /Length 114 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 88 /ID [<4017237e2ab7fd501b13ff292b94644c><81bec6397e13a59cb8bffda31fbd371d>] >> stream xœcb&F~0ù‰ $À8JÒ‰üÏÀ³â0ÍúòÛA${?ˆ4‘â RXDòÕHÎRÉ‘V_fÿ‘b ’§D2þ‘ü`½ü×Á¦5IFÞ½`Y]°8XÜL6ƒMNcÍÚ• endstream endobj startxref 83102 %%EOF nanotime/inst/tinytest/0000755000176200001440000000000014635571205014734 5ustar liggesusersnanotime/inst/tinytest/test_nanoival.R0000644000176200001440000016041414635571205017733 0ustar liggesuserslibrary(nanotime) suppressMessages(library(bit64)) extended_tests <- Sys.getenv("CI", "") != "" savedFormat <- NULL one_second <- 1e9 aa <- "+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-" bb <- "+2014-01-01 00:00:00 -> 2015-01-01 00:00:00+" cc <- "-2015-01-01 00:00:00 -> 2016-01-01 00:00:00-" dd <- "-2016-01-01 00:00:00 -> 2017-01-01 00:00:00+" savedFormat <- options()$nanotimeFormat options(nanotimeFormat="%Y-%m-%d %H:%M:%S") ## nanotime constructors/accessors ##test_as.nanoival <- function() { ni <- as.nanoival(aa) expect_identical(nanoival.start(ni), nanotime("2013-01-01 00:00:00")) & expect_identical(nanoival.end(ni), nanotime("2014-01-01 00:00:00")) & expect_identical(nanoival.sopen(ni), FALSE) & expect_identical(nanoival.eopen(ni), TRUE) ##test_as.nanoival_vector <- function() { ni <- as.nanoival(c(a=aa, b=bb, c=cc, d=dd)) expect_identical(nanoival.start(ni), c(a=nanotime("2013-01-01 00:00:00"), b=nanotime("2014-01-01 00:00:00"), c=nanotime("2015-01-01 00:00:00"), d=nanotime("2016-01-01 00:00:00"))) & expect_identical(nanoival.end(ni), c(a=nanotime("2014-01-01 00:00:00"), b=nanotime("2015-01-01 00:00:00"), c=nanotime("2016-01-01 00:00:00"), d=nanotime("2017-01-01 00:00:00"))) & expect_identical(nanoival.sopen(ni), c(a=FALSE, b=FALSE, c=TRUE, d=TRUE)) & expect_identical(nanoival.eopen(ni), c(a=TRUE, b=FALSE, c=TRUE, d=FALSE)) expect_identical(length(as.nanoival(vector("character", 0))), 0L) expect_identical(as.nanoival("-2013-01-01 00:00:00 America/New_York -> 2014-01-01 00:00:00 America/New_York+"), nanoival(nanotime("2013-01-01 00:00:00 America/New_York"), nanotime("2014-01-01 00:00:00 America/New_York"), TRUE, FALSE)) ## test warning when we double specify the timezone: expect_error(as.nanoival("-2013-01-01 00:00:00 America/New_York -> 2014-01-01 00:00:00+00:00+", tz="Europe/London"), "timezone is specified twice: in the string and as an argument") ##test_as.nanoival_vector_fail <- function() { expect_error(as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00"), "`nanoival` must end with '\\+' or '-'") expect_error(as.nanoival("2013-01-01 00:00:00 -> 2014-01-01 00:00:00-"), "`nanoival` must start with '\\+' or '-'") expect_error(as.nanoival("+2013-01-01 00:00:00 $$ 2014-01-01 00:00:00-"), "Parse error on 2013-01-01 00:00:00 \\$\\$ 2014-01-01 00:00:00") expect_error(as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00- "), "`nanoival` must end with '\\+' or '-'") expect_error(as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00a"), "`nanoival` must end with '\\+' or '-'") expect_error(as.nanoival("+2013-01-01 00:00:00 America/New_York -> 2014-01-01 00:00:00 America/New_York %%"), "`nanoival` must end with '\\+' or '-'") expect_error(as.nanoival("+2013-01-01 00:00:00 America/New_York -> 2014-01-01 00:00:00 America/New_York + "), "`nanoival` must end with '\\+' or '-'") expect_error(as.nanoival("-2013-01-01 00:00:00 America/New_York -> 2014-01-01 00:00:00 America/New_YYork+"), "Cannot retrieve timezone") expect_error(as.nanoival(aa, tz=list(1)), "argument 'tz' must be of type 'character'") ##test_nanoival <- function() { expect_identical(nanoival(nanotime("2013-01-01 00:00:00"), nanotime("2014-01-01 00:00:00"), TRUE, TRUE), as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-")) expect_error(nanoival(nanotime(2), nanotime(1)), "interval end \\(1\\) smaller than interval start \\(2\\)") expect_identical(nanoival(), as.nanoival(NULL)) expect_identical(length(nanoival()), 0L) expect_identical(nanoival(), as.nanoival()) expect_identical(length(as.nanoival()), 0L) ##test_nanoival_vector<- function() { starts <- c(nanotime("2013-01-01 00:00:00"), nanotime("2014-01-01 00:00:00"), nanotime("2015-01-01 00:00:00"), nanotime("2016-01-01 00:00:00")) ends <- c(nanotime("2014-01-01 00:00:00"), nanotime("2015-01-01 00:00:00"), nanotime("2016-01-01 00:00:00"), nanotime("2017-01-01 00:00:00")) sopens <- c(FALSE, FALSE, TRUE, TRUE) eopens <- c(TRUE, FALSE, TRUE, FALSE) expect_identical(nanoival(starts, ends, sopens, eopens), as.nanoival(c(aa, bb, cc, dd))) ## different vector lengths: starts <- nanotime(1:3) ends <- nanotime(4) sopens <- c(TRUE, TRUE, TRUE) eopens <- c(FALSE, FALSE, FALSE) expect_identical(nanoival(starts, ends, sopens, eopens), c(nanoival(nanotime(1), nanotime(4), TRUE, FALSE), nanoival(nanotime(2), nanotime(4), TRUE, FALSE), nanoival(nanotime(3), nanotime(4), TRUE, FALSE))) expect_identical(nanoival(starts, ends, sopens[1], eopens), c(nanoival(nanotime(1), nanotime(4), TRUE, FALSE), nanoival(nanotime(2), nanotime(4), TRUE, FALSE), nanoival(nanotime(3), nanotime(4), TRUE, FALSE))) expect_identical(nanoival(starts[1], ends, sopens, eopens[1]), c(nanoival(nanotime(1), nanotime(4), TRUE, FALSE), nanoival(nanotime(1), nanotime(4), TRUE, FALSE), nanoival(nanotime(1), nanotime(4), TRUE, FALSE))) ## show/print/format ##test_show <- function() { ival_str <- "+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-" ival <- as.nanoival(ival_str) expect_identical(format(ival), ival_str) expect_stdout(show(ival)) ival_str <- "-2013-01-01 00:00:00 -> 2014-01-01 00:00:00+" ival <- as.nanoival(ival_str) expect_identical(format(ival), ival_str) expect_stdout(show(ival)) ival_str <- c(a="+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") ival <- as.nanoival(ival_str) expect_identical(format(ival), ival_str) expect_stdout(show(ival)) expect_identical(format(as.nanoival(vector("character", 0))), "nanoival(0)") ##test_format <- function() { ival_str <- "+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-" ival <- as.nanoival(ival_str) expect_identical(format(ival), ival_str) expect_identical(as.character(ival), ival_str) ival_str <- "-2013-01-01 00:00:00 -> 2014-01-01 00:00:00+" ival <- as.nanoival(ival_str) expect_identical(format(ival), ival_str) expect_identical(as.character(ival), ival_str) ## as.data.frame ##test_as.data.frame <- function() { ni <- as.nanoival(c(aa, bb, cc, dd)) expect_identical(as.data.frame(ni), data.frame(ni=ni)) rownames <- c("aa","bb","cc","dd") names(ni) <- rownames as.data.frame(ni) expect_identical(as.data.frame(ni), data.frame(ni=ni, row.names=rownames)) ## equality and comparison operators ## eq/ne ##test_eq <- function() { x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_true(x==x) y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_true(!(x==y)) z <- as.nanoival("+2013-01-01 00:00:01 -> 2014-01-01 00:00:00-") expect_true(!(x==z)) ##test_ne <- function() { x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_true(!(x!=x)) y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_true(x!=y) z <- as.nanoival("+2013-01-01 00:00:01 -> 2014-01-01 00:00:00-") expect_true(x!=z) ## lt ##test_lt_non_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival(c(b="+2015-01-01 00:00:00 -> 2016-01-01 00:00:00-")) expect_identical(x < y, c(b=TRUE)) expect_identical(y < x, c(b=FALSE)) ##test_lt_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x < y, TRUE) expect_identical(y < x, FALSE) ##test_lt_same_end <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x < y, TRUE) expect_identical(y < x, FALSE) ##test_lt_included <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2013-07-01 00:00:00-") expect_identical(x < y, TRUE) expect_identical(y < x, FALSE) ##test_lt_same_start<- function() { ## x: c----------o ## y: c--------------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(x < y, TRUE) expect_identical(y < x, FALSE) ##test_lt_same_open_start <- function() { ## x: c----------o ## y: o----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x < y, TRUE) expect_identical(y < x, FALSE) ##test_lt_same_open_end <- function() { ## x: c----------o ## y: c----------c x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00+") expect_identical(x < y, TRUE) expect_identical(y < x, FALSE) ##test_lt_same <- function() { ## x: c----------o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x < y, FALSE) expect_identical(y < x, FALSE) ##test_lt_same <- function() { ## x: c----------o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x < y, FALSE) expect_identical(y < x, FALSE) ##test_lt_multiple <- function() { ## x: c----------o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2014-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(c(x, y) < c(y, x), c(TRUE, FALSE)) ## le ##test_le_non_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2015-01-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_same_end <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_included <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2013-07-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_same_start<- function() { ## x: c----------o ## y: c--------------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_same_open_start <- function() { ## x: c----------o ## y: o----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_same_open_end <- function() { ## x: c----------o ## y: c----------c x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00+") expect_identical(x <= y, TRUE) expect_identical(y <= x, FALSE) ##test_le_same <- function() { ## x: c----------o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x <= y, TRUE) expect_identical(y <= x, TRUE) ## gt ##test_gt_non_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2015-01-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_same_end <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_included <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2013-07-01 00:00:00-") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_same_start<- function() { ## x: c----------o ## y: c--------------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_same_open_start <- function() { ## x: c----------o ## y: o----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_same_open_end <- function() { ## x: c----------o ## y: c----------c x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00+") expect_identical(x > y, FALSE) expect_identical(y > x, TRUE) ##test_gt_same <- function() { ## x: c----------c ## y: c----------c x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00+") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00+") expect_identical(x > y, FALSE) expect_identical(y > x, FALSE) ## ge ##test_ge_non_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2015-01-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_same_end <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_included <- function() { ## x: c----------o ## y: c----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-06-01 00:00:00 -> 2013-07-01 00:00:00-") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_same_start<- function() { ## x: c----------o ## y: c--------------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_same_open_start <- function() { ## x: c----------o ## y: o----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_same_open_end <- function() { ## x: c----------o ## y: c----------c x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00+") expect_identical(x >= y, FALSE) expect_identical(y >= x, TRUE) ##test_ge_same <- function() { ## x: o----------o ## y: o----------o x <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("-2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") expect_identical(x >= y, TRUE) expect_identical(y >= x, TRUE) ## sorting/ordering ##test_is_unsorted_non_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2015-01-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(is.unsorted(c(x, y)), FALSE) expect_identical(is.unsorted(c(y, x)), TRUE) ##test_is_unsorted_overlapping <- function() { ## x: c----------o ## y: c--------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") y <- as.nanoival("+2014-01-01 00:00:00 -> 2016-01-01 00:00:00-") expect_identical(is.unsorted(c(x, y)), FALSE) expect_identical(is.unsorted(c(y, x)), TRUE) ##test_is_unsorted_same_end <- function() { ## x: c----------o ## y: c-----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") y <- as.nanoival("+2014-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(is.unsorted(c(x, y)), FALSE) expect_identical(is.unsorted(c(y, x)), TRUE) ##test_is_unsorted_included <- function() { ## x: c----------o ## y: c-----o x <- as.nanoival("+2013-01-01 00:00:00 -> 2016-01-01 00:00:00-") y <- as.nanoival("+2014-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(is.unsorted(c(x, y)), FALSE) expect_identical(is.unsorted(c(y, x)), TRUE) ##test_is_unsorted_same_start <- function() { ## x: c----o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(is.unsorted(c(x, y)), FALSE) expect_identical(is.unsorted(c(y, x)), TRUE) ##test_is_unsorted_not_strictly <- function() { ## x: c----o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(is.unsorted(c(x, x, y, y)), FALSE) expect_identical(is.unsorted(c(y, y, x, x)), TRUE) ##test_is_unsorted_strictly <- function() { ## x: c----o ## y: c----------o x <- as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-") y <- as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-") expect_identical(is.unsorted(c(x, x, y, y), strictly=TRUE), TRUE) expect_identical(is.unsorted(c(y, y, x, x), strictly=TRUE), TRUE) expect_error(is.unsorted(c(y, y, x, x), strictly="a"), "argument 'strictly' must be a logical") expect_error(is.unsorted(c(y, y, x, x), strictly=as.logical(NULL)), "argument 'strictly' cannot have length 0") ## test 'na.rm': expect_identical(is.unsorted(c(x, y, NA_nanoival_)), NA_nanoival_) expect_identical(is.unsorted(c(x, y, NA_nanoival_), na.rm=TRUE), FALSE) ##test_sort <- function() { v <- as.nanoival(c(aa, bb, cc, dd)) v_descending <- as.nanoival(c(dd, cc, bb, aa)) expect_identical(sort(v_descending), v) expect_identical(sort(v, decreasing=TRUE), v_descending) expect_error(sort(v, decreasing=as.logical(NULL)), "argument 'decreasing' cannot have length 0") expect_error(sort(v, decreasing="not a logical"), "argument 'decreasing' must be logical") ## c ##test_c <- function() { # LLL a <- c(nanotime(1), nanotime(2)) expect_identical(a, nanotime(1:2)) a <- c(nanotime(1:2), nanotime(3:4)) expect_identical(a, nanotime(1:4)) ##test_c_name <- function() { c_xy <- c(x=as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-"), y=as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-")) expect_identical(names(c_xy), c("x","y")) ##test_c_name_assign <- function() { c_xy <- c(x=as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-"), y=as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-")) names(c_xy) <- c("a","b") expect_identical(names(c_xy), c("a","b")) ##test_c_name_assign_null <- function() { c_xy <- c(x=as.nanoival("+2013-01-01 00:00:00 -> 2014-01-01 00:00:00-"), y=as.nanoival("+2013-01-01 00:00:00 -> 2015-01-01 00:00:00-")) names(c_xy) <- NULL expect_true(is.null(names(c_xy))) ## set operations ## naming convention for interval tests: ## cc : start closed, end closed ## co : start closed, end open ## oc : etc. ## oo ## intersection ## -------------------------------------------------------------------------- ## time - interval ## N=143 ## test_intersect_time_interval_null_interval <- function() { if (extended_tests) { i1 <- as.nanoival(NULL) s1 <- seq(nanotime("2015-01-01 12:00:00"), length.out=10, by=one_second) expect_identical(s1[i1], as.nanotime()) expect_identical(s1 %in% i1, rep(FALSE, 10)) } ##test_intersect.idx_unsorted <- function() { a <- c(nanotime("2013-12-12 12:12:12"), nanotime("2012-12-12 12:12:12")) idx <- as.nanoival("+2012-12-12 12:12:14 -> 2012-12-12 12:12:19+") expect_error(intersect.idx(a, idx), "x must be sorted") expect_error(a %in% idx, "x must be sorted") ##test_subset_unsorted <- function() { a <- c(nanotime("2013-12-12 12:12:12"), nanotime("2012-12-12 12:12:12")) idx <- as.nanoival("+2012-12-12 12:12:14 -> 2012-12-12 12:12:19+") expect_error(a[idx], "x must be sorted") expect_error(a %in% idx, "x must be sorted") ## test that nanotime %in% nanotime still works as it goes through the same S3 a <- nanotime(3:6) idx <- nanotime(1:10) expect_identical(a %in% idx, 3:6 %in% 1:10) ## time - interval ## 1: .............. ## 2: c----c ## r: ...... ##test_intersect_idx_time_interval_cc <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- as.nanoival("+2012-12-12 12:12:14 -> 2012-12-12 12:12:19+") r <- list(x=c(3,4,5,6,7,8), y=c(1,1,1,1,1,1)) expect_identical(intersect.idx(a, idx), r) expect_identical(a %in% idx, 1:10 %in% c(3,4,5,6,7,8)) ## 1: .............. ## 2: c----c ## r: ...... ##test_intersect_time_interval_cc <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- as.nanoival("+2012-12-12 12:12:14 -> 2012-12-12 12:12:19+") r <- seq(nanotime("2012-12-12 12:12:14"), nanotime("2012-12-12 12:12:19"), by=one_second) expect_identical(a[idx], r) expect_identical(intersect(a, idx), r) ## 1: .............. ## 2: o----o ## r: .... ##test_intersect_time_interval_oo <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- as.nanoival("-2012-12-12 12:12:14 -> 2012-12-12 12:12:19-") r <- seq(nanotime("2012-12-12 12:12:15"), nanotime("2012-12-12 12:12:18"), by=one_second) expect_identical(a[idx], r) ## 1: ...... ## 2: o---------o ## r: ...... ##test_intersect_time_interval_overlapping <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- as.nanoival("-2012-12-12 12:12:10 -> 2012-12-12 12:12:30-") expect_identical(a[idx], a) ## 1: ................. ## 2: o-----o c-----c ## r: ..... ....... ##test_intersect_time_interval_multiple <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- c(as.nanoival("-2012-12-12 12:12:10 -> 2012-12-12 12:12:14-"), as.nanoival("+2012-12-12 12:12:18 -> 2012-12-12 12:12:20+")) r <- c(seq(nanotime("2012-12-12 12:12:12"), nanotime("2012-12-12 12:12:13"), by=one_second), seq(nanotime("2012-12-12 12:12:18"), nanotime("2012-12-12 12:12:20"), by=one_second)) expect_identical(a[idx], r) ##test_intersect_time_interval_multiple_direct_call <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- c(as.nanoival("-2012-12-12 12:12:10 -> 2012-12-12 12:12:14-"), as.nanoival("+2012-12-12 12:12:18 -> 2012-12-12 12:12:20+")) r <- c(seq(nanotime("2012-12-12 12:12:12"), nanotime("2012-12-12 12:12:13"), by=one_second), seq(nanotime("2012-12-12 12:12:18"), nanotime("2012-12-12 12:12:20"), by=one_second)) expect_identical(intersect(a, idx), r) ## interval - interval: ## 1: c-----------c ## 2: c-----------c ## r: c-----------c ##test_intersect_interval_interval_cc_cc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- i2 expect_true(intersect(i1, i2) == r) ## 1: c-----------c ## 2: o-----------c ## r: o-----------c ##test_intersect_interval_interval_cc_oc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- i2 expect_true(intersect(i1, i2) == r & intersect(i2, i1) == r) ## 1: c-----------c ## 2: c-----------o ## r: c-----------o ##test_intersect_interval_interval_cc_co__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- i2 expect_true(intersect(i1, i2) == r & intersect(i2, i1) == r) ## 1: c-----------o ## 2: o-----------c ## r: o-----------o ##test_intersect_interval_interval_co_oc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") expect_true(intersect(i1, i2) == r & intersect(i2, i1) == r) ## 1: o-----------o ## 2: o-----------o ## r: o-----------o ##test_intersect_interval_interval_oo_oo__2_eq_1 <- function() { i1 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- i2 expect_true(intersect(i1, i2) == r) ## 1: c-----------c ## 2: o-----------o ## r: o-----------o ##test_intersect_interval_interval_cc_oo__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- i2 expect_true(intersect(i1, i2) == r) ## 1: c-----------o ## 2: o-----------c ## r: ##test_intersect_interval_interval_co_oc__2_lg_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") r <- new("nanoival", as.complex(NULL)) expect_identical(intersect(i2, i1), r) ## 1: c-----------o ## 2: c-----------c ## r: ##test_intersect_interval_interval_co_cc__2_lg_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") r <- as.nanoival(NULL) expect_identical(intersect(i2, i1), r) ## 1: c-----------c ## 2: o-----------c ## r: ##test_intersect_interval_interval_cc_oc__2_lg_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") r <- as.nanoival(NULL) expect_identical(intersect(i2, i1), r) ## 1: c-----------c ## 2: c-----------c ## r: cc ##test_intersect_interval_interval_cc_cc__2_lg_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") r <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:05+") expect_identical(intersect(i2, i1), r) expect_identical(intersect(i1, i2), r) ## 1: c-----------c c-----------c ## 2: c-----------c ## r: ##test_intersect_interval_interval_distinct_more <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:10 -> 2015-01-01 12:00:12+")) i2 <- as.nanoival("+2015-01-01 12:00:06 -> 2015-01-01 12:00:07+") r <- as.nanoival(NULL) expect_identical(intersect(i1, i2), r) expect_identical(intersect(i2, i1), r) ## time-time expect_identical(intersect(nanotime(1:10), nanotime(5:15)), nanotime(5:10)) ## union ## -------------------------------------------------------------------------- ## interval - interval: ## 1: c-----------c ## 2: c-----------c ## r: c-----------c ##test_union_interval_interval_cc_cc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- i2 expect_true(union(i1, i2) == r & union(i2, i1) == r) ## 1: c-----------c ## 2: o-----------c ## r: c-----------c ##test_union_interval_interval_cc_oc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- i1 expect_true(union(i1, i2) == r & union(i2, i1) == r) ## 1: c-----------c ## 2: c-----------o ## r: c-----------c ##test_union_interval_interval_cc_co__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- i1 expect_true(union(i1, i2) == r & union(i2, i1) == r) ## 1: c-----------o ## 2: o-----------c ## r: c-----------c ##test_union_interval_interval_co_oc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") expect_true(union(i1, i2) == r & union(i2, i1) == r) ## 1: o-----------o ## 2: o-----------o ## r: o-----------o ##test_union_interval_interval_oo_oo__2_eq_1 <- function() { i1 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- i2 expect_true(union(i1, i2) == r & union(i2, i1) == r) ## 1: c-----------c ## 2: o-----------o ## r: c-----------c ##test_union_interval_interval_cc_oo__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- i1 expect_true(union(i1, i2) == r & union(i2, i1) == r) ## 1: c-----------c ## 2: o-----------o ## 1: c-----------o ## 2: c-----------o ## r: c-----------------------o ##test_union_interval_interval_no_overlap_co_oc <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07-") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:07-") expect_identical(union(i1, i2), r) expect_identical(union(i2, i1), r) ## 1: c-----------o ## 2: o-----------o ## r: c-----------o-----------o ##test_union_interval_interval_no_overlap_oo <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07-") r <- c(i1, i2) expect_identical(union(i1, i2), r) expect_identical(union(i2, i1), r) ## 1: c-----------c ## 2: c-----------o ## r: c-----------------------o ##test_union_interval_interval_no_overlap_cc <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07-") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:07-") expect_identical(union(i1, i2), r) expect_identical(union(i2, i1), r) ## 1: c-----------c c----------o ## 2: c-----------o o----------c ## r: c-----------------------o ##test_union_interval_interval_no_overlap_cc_more <- function() { i1 <- as.nanoival(c("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+", "+2016-01-01 12:00:03 -> 2016-01-01 12:00:05-")) i2 <- as.nanoival(c("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07-", "-2016-01-01 12:00:04 -> 2016-01-01 12:00:08+")) r <- as.nanoival(c("+2015-01-01 12:00:03 -> 2015-01-01 12:00:07-", "+2016-01-01 12:00:03 -> 2016-01-01 12:00:08+")) expect_identical(union(i1, i2), r) expect_identical(union(i2, i1), r) ## time-time expect_identical(union(nanotime(1:2), nanotime(8:10)), c(nanotime(1:2), nanotime(8:10))) ## setdiff ## -------------------------------------------------------------------------- ## time - interval ## 1: .......... ## 2: c----c ## r: .. .. ##test_sediff_idx_time_interval_cc <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- as.nanoival("+2012-12-12 12:12:14 -> 2012-12-12 12:12:19+") r <- c(1, 2, 9, 10) expect_identical(setdiff.idx(a, idx), r) ## time - interval ## 1: .......... ## 2: o----o ## r: ... ... ##test_sediff_idx_time_interval_oo <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) idx <- as.nanoival("-2012-12-12 12:12:14 -> 2012-12-12 12:12:19-") r <- c(1, 2, 3, 8, 9, 10) expect_identical(setdiff.idx(a, idx), r) ##test_sediff_idx_time_interval_unsorted <- function() { a <- seq(nanotime("2012-12-12 12:12:12"), length.out=10, by=one_second) a[1] <- a[10] # make it unsorted idx <- as.nanoival("-2012-12-12 12:12:14 -> 2012-12-12 12:12:19-") expect_error(setdiff.idx(a, idx), "x must be sorted") ## time - interval: ## 1: as.nanoival("-----------") ## 2: as.nanoival("---") ## r: as.nanoival("--") as.nanoival("----") ##test_setdiff_time_interval_cc__2_subset_of_1 <- function() { s1 <- seq(nanotime("2015-01-01 12:00:00"), length.out=10, by=one_second) i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- c(seq(nanotime("2015-01-01 12:00:00"), length.out=3, by=one_second), seq(nanotime("2015-01-01 12:00:06"), length.out=4, by=one_second)) expect_identical(setdiff(s1, i2), r) ##test_setdiff_time_interval_oc__2_subset_of_1 <- function() { s1 <- seq(nanotime("2015-01-01 12:00:00"), length.out=10, by=one_second) i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- c(seq(nanotime("2015-01-01 12:00:00"), length.out=4, by=one_second), seq(nanotime("2015-01-01 12:00:06"), length.out=4, by=one_second)) expect_identical(setdiff(s1, i2), r) ##test_setdiff_time_interval_co__2_subset_of_1 <- function() { s1 <- seq(nanotime("2015-01-01 12:00:00"), length.out=10, by=one_second) i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- c(seq(nanotime("2015-01-01 12:00:00"), length.out=3, by=one_second), seq(nanotime("2015-01-01 12:00:05"), length.out=5, by=one_second)) expect_identical(setdiff(s1, i2), r) ##test_setdiff_time_interval_oo__2_subset_of_1 <- function() { s1 <- seq(nanotime("2015-01-01 12:00:00"), length.out=10, by=one_second) i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- c(seq(nanotime("2015-01-01 12:00:00"), length.out=4, by=one_second), seq(nanotime("2015-01-01 12:00:05"), length.out=5, by=one_second)) expect_identical(setdiff(s1, i2), r) ## interval - interval: ## 1: c-----------c ## 2: c-----------c ## r: ##test_setdiff_interval_interval_cc_cc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- new("nanoival", as.complex(NULL)) expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------c ## r: c ##test_setdiff_interval_interval_cc_oc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:03+") expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: c-----------o ## r: c ##test_setdiff_interval_interval_cc_co__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:05+") expect_identical(setdiff(i1, i2), r) ## 1: c-----------o ## 2: o-----------c ## r: c ##test_setdiff_interval_interval_co_oc__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:03+") expect_identical(setdiff(i1, i2), r) ## 1: o-----------o ## 2: o-----------o ## r: ##test_setdiff_interval_interval_oo_oo__2_eq_1 <- function() { i1 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- new("nanoival", as.complex(NULL)) expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------o ## r: c-----------c ##test_setdiff_interval_interval_cc_oo__2_eq_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:03+"), as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:05+")) expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: c-----------o ## r: c-----------o ##test_setdiff_interval_interval_cc_co__2_gt_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07-") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------o ## r: c-----------c ##test_setdiff_interval_interval_cc_oo__2_gt_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07-") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------c ## r: c-----------c ##test_setdiff_interval_interval_cc_oc__2_gt_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07-") r <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------c ## r: o-----------c ##test_setdiff_interval_interval_cc_oc__2_lt_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- as.nanoival("-2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------o ## r: c-----------c ##test_setdiff_interval_interval_cc_oo__2_lt_1 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+") expect_identical(setdiff(i1, i2), r) ## various tests where we add a third interval ## 1: c-----------c c--------c ## 2: o-----------o ## r: c-----------c c--------c ##test_setdiff_interval_interval_cc_oo__2_lt_1_3rd <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10+")) i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:05-") r <- c(as.nanoival("+2015-01-01 12:00:05 -> 2015-01-01 12:00:07+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10+")) expect_identical(setdiff(i1, i2), r) ## 1: c-----------c c--------o ## 2: o--------------------c ## r: o--------c ##test_setdiff_interval_interval_cc_co_oc_3rd <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:08+") r <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:03+"), as.nanoival("-2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_identical(setdiff(i1, i2), r) ## 1: c-----------c ## 2: o-----------o ## r: c-----------c ##test_setdiff_interval_interval_non_overlapping__1_gt_2 <- function() { i1 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") i2 <- as.nanoival("-2015-01-01 12:00:06 -> 2015-01-01 12:00:07-") r <- i1 expect_identical(setdiff(i1, i2), r) ## 1: o-----------o ## 2: c-----------c ## r: o-----------o ##test_setdiff_interval_interval_non_overlapping__2_gt_1 <- function() { i1 <- as.nanoival("-2015-01-01 12:00:06 -> 2015-01-01 12:00:07-") i2 <- as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+") r <- i1 expect_identical(setdiff(i1, i2), r) ## 1: c-----------c c--------c ## 2: o-----------o ## r: c-----------c ##test_setdiff_interval_interval_non_overlapping__1_gt_2_more <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:10 -> 2015-01-01 12:00:12+")) i2 <- as.nanoival("-2015-01-01 12:00:06 -> 2015-01-01 12:00:07-") r <- i1 expect_identical(setdiff(i1, i2), r) ## interval - interval: ## 1: c-----------c c-----------c ## 2: o---------o ## r: ##test_setdiff_interval_interval_2_inside_1__more <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:02 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:10 -> 2015-01-01 12:00:12+")) i2 <- as.nanoival("-2015-01-01 12:00:03 -> 2015-01-01 12:00:04-") r <- c(as.nanoival("+2015-01-01 12:00:02 -> 2015-01-01 12:00:03+"), as.nanoival("+2015-01-01 12:00:04 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:10 -> 2015-01-01 12:00:12+")) expect_identical(setdiff(i1, i2), r) ## interval - interval: ## 1: c------c c--------c ## 2: c---------c ## r: ##test_setdiff_interval_interval_1_inside_2__more <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:02 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:10 -> 2015-01-01 12:00:12+")) i2 <- as.nanoival("+2015-01-01 12:00:01 -> 2015-01-01 12:00:06+") r <- as.nanoival("+2015-01-01 12:00:10 -> 2015-01-01 12:00:12+") expect_identical(setdiff(i1, i2), r) ## time-time expect_identical(setdiff(nanotime(1:10), nanotime(2:9)), c(nanotime(1), nanotime(10))) ## ops +, - ##test_minus_nanoival_any <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_error(i1 - "a", "invalid operand types") ##test_minus_nanoival_integer64 <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:02 -> 2015-01-01 12:00:04+"), as.nanoival("+2015-01-01 12:00:07 -> 2015-01-01 12:00:09-")) expect_identical(i1 - as.integer64(one_second), expected) ##test_minus_nanoival_numeric <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:02 -> 2015-01-01 12:00:04+"), as.nanoival("+2015-01-01 12:00:07 -> 2015-01-01 12:00:09-")) expect_identical(i1 - one_second, expected) ##test_minus_nanoival_integer <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:02 -> 2015-01-01 12:00:04+"), as.nanoival("+2015-01-01 12:00:07 -> 2015-01-01 12:00:09-")) expect_identical(i1 - as.integer(one_second), expected) ##test_minus_any_nanoival <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_error(as.integer(one_second) - i1, "invalid operand types") ##test_minus_nanoival_nanoival <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_error(i1 - i1, "invalid operand types") ##test_plus_nanoival_any <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_error(i1 + "a", "invalid operand types") ##test_plus_nanoival_integer64 <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:04 -> 2015-01-01 12:00:06+"), as.nanoival("+2015-01-01 12:00:09 -> 2015-01-01 12:00:11-")) expect_identical(i1 + as.integer64(one_second), expected) ##test_plus_nanoival_numeric <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:04 -> 2015-01-01 12:00:06+"), as.nanoival("+2015-01-01 12:00:09 -> 2015-01-01 12:00:11-")) expect_identical(i1 + one_second, expected) ##test_plus_nanoival_integer <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:04 -> 2015-01-01 12:00:06+"), as.nanoival("+2015-01-01 12:00:09 -> 2015-01-01 12:00:11-")) expect_identical(i1 + as.integer(one_second), expected) ##test_plus_any_nanoival <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_error(as.character("a") + i1, "invalid operand types") ##test_plus_nanoival_nanoival <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expect_error(i1 + i1, "invalid operand types") ##test_plus_numeric_nanoival <- function() { i1 <- c(as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(as.nanoival("+2015-01-01 12:00:04 -> 2015-01-01 12:00:06+"), as.nanoival("+2015-01-01 12:00:09 -> 2015-01-01 12:00:11-")) expect_identical(one_second + i1, expected) ##test_plus_integer64_nanoival <- function() { i1 <- c(a=as.nanoival("+2015-01-01 12:00:03 -> 2015-01-01 12:00:05+"), b=as.nanoival("+2015-01-01 12:00:08 -> 2015-01-01 12:00:10-")) expected <- c(a=as.nanoival("+2015-01-01 12:00:04 -> 2015-01-01 12:00:06+"), b=as.nanoival("+2015-01-01 12:00:09 -> 2015-01-01 12:00:11-")) expect_identical(as.integer64(one_second) + i1, expected) ## Groups ##test_Arith_nanoival <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) expect_error(i1 ^ i2, "operation not defined for \"nanoival\" objects") ##test_Compare_nanoival <- function() { i1 <- as.nanoival(aa) expect_error(i1 < 2, "invalid operand types") ##test_Logic_nanoival <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) expect_error(i1 & i2, "operations are possible only for numeric, logical or complex types") expect_error(i1 & 2, "operations are possible only for numeric, logical or complex types") expect_error(1 | i2, "operations are possible only for numeric, logical or complex types") ##test_Math_nanoival <- function() { i1 <- as.nanoival(aa) expect_error(abs(i1), "non-numeric argument to mathematical function") ##test_Math2_nanoival <- function() { i1 <- as.nanoival(aa) expect_error(round(i1), "non-numeric argument to mathematical function") ##test_Summary_nanoival <- function() { i1 <- as.nanoival(aa) expect_error(prod(i1), "invalid 'type' \\(nanoival\\) of argument") ##test_Complex_nanoival <- function() { i1 <- as.nanoival(aa) expect_error(Arg(i1), "non-numeric argument to function") ## Subsetting ##test_subset_logical <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(i1, i2, i3) expect_identical(ii[c(T,F,T)], c(i1, i3)) expect_identical(ii[c(T,F,NA)], c(i1, NA_nanoival_)) expect_identical(ii[-1], c(i2, i3)) expect_warning(ii[c(T,F,T), 3], "unused indices or arguments in 'nanoival' subsetting") ##test_subset_logical_named <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(a=i1, b=i2, c=i3) expect_identical(ii[c(T,F,T)], c(a=i1, c=i3)) ##test_subset_numeric <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(i1, i2, i3) expect_identical(ii[c(1,3)], c(i1, i3)) expect_identical(ii[c(1,NA)], c(i1, NA_nanoival_)) expect_warning(ii[c(1,3), 3, 5], "unused indices or arguments in 'nanoival' subsetting") ##test_subset_numeric_named <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(a=i1, b=i2, c=i3) expect_identical(ii[c(1,3)], c(a=i1, c=i3)) ## test subset character i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(a=i1, b=i2, c=i3) expect_identical(ii[c("a","b")], ii[1:2]) res <- c(a=i1, NA_nanoival_) names(res)[2] <- NA_character_ expect_identical(ii[c("a","x")], res) expect_warning(ii["a", "b"], "unused indices or arguments in 'nanoival' subsetting") ## test subset error expect_error(as.nanoival(aa)[as.integer64(1)], "']' not defined for on 'nanoival' for index of type 'ANY'") ##test_subassign_logical <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(i1, i2, i3) ii[c(F,T,T)] <- i1 expect_identical(ii, c(i1, i1, i1)) ##test_subassign_logical_named <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(a=i1, b=i2, c=i3) ii[c(F,T,T)] <- i1 expect_identical(ii, c(a=i1, b=i1, c=i1)) ##test_subassign_numeric <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(i1, i2, i3) ii[2:3] <- i1 expect_identical(ii, c(i1, i1, i1)) ##test_subassign_numeric_named <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(a=i1, b=i2, c=i3) ii[2:3] <- i1 expect_identical(ii, c(a=i1, b=i1, c=i1)) ##test_square_bracket <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) nn <- c(a=i1, b=i2, c=i3) nn_nonames <- c(i1, i2, i3) expect_identical(nn_nonames[1], nn[[1]]) expect_identical(nn_nonames[2], nn[[2]]) expect_identical(nn_nonames[3], nn[[3]]) ## transposition, which is identity, as for 'POSIXct' for example: ##test_t_nanoival <- function() { i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) i3 <- as.nanoival(cc) ii <- c(a=i1, b=i2, c=i3) expect_identical(t(ii), ii) ## NA stuff expect_true(is.na(nanoival(NA_nanotime_, NA_nanotime_, NA, NA))) expect_true(is.na(nanoival(NA_nanotime_, nanotime(1), TRUE, TRUE))) expect_true(is.na(nanoival(nanotime(1), NA_nanotime_, TRUE, TRUE))) expect_true(is.na(nanoival(nanotime(1), nanotime(2), NA, TRUE))) expect_true(is.na(nanoival(nanotime(1), nanotime(2), TRUE, NA))) nn <- nanoival(nanotime(1:10), nanotime(2:11)) is.na(nn) <- 1:3 expect_true(all(is.na(nn[1:3]))) expect_true(!any(is.na(nn[4:10]))) expect_true(is.na(NA_nanoival_)) expect_true(is.na(nanoival.start(NA_nanoival_))) expect_true(is.na(nanoival.end(NA_nanoival_))) expect_true(is.na(nanoival.sopen(NA_nanoival_))) expect_true(is.na(nanoival.eopen(NA_nanoival_))) ## overflow n1 <- nanotime(1) n2 <- nanotime(2) ni <- nanoival(n1, n2) prd <- as.nanoperiod("200y") expect_warning(plus (ni, prd, "America/New_York"), "NAs produced by time overflow \\(remember that interval times are coded with 63 bits\\)") expect_warning(minus(ni, prd, "America/New_York"), "NAs produced by time overflow \\(remember that interval times are coded with 63 bits\\)") dur <- as.nanoduration(200*365*24*3600*1e9) expect_warning(ni + dur, "NAs produced by time overflow \\(remember that interval times are coded with 63 bits\\)") expect_warning(ni + dur, "NAs produced by time overflow \\(remember that interval times are coded with 63 bits\\)") ## test warnings for ops where the vectors have length mismatch: ##test_lt_size_mismatch <- function() { x <- nanoival(nanotime(1), nanotime(2)) expect_warning(c(x,x) < c(x,x,x), "longer object length is not a multiple of shorter object length") d <- as.nanoduration(1) expect_warning(c(x,x,x) + c(d,d), "longer object length is not a multiple of shorter object length") ## warnings should also happen on 'nanoival' construction: s <- nanotime(1) e <- nanotime(2) expect_warning(nanoival(c(s,s), c(e,e,e)), "longer object length is not a multiple of shorter object length") expect_warning(nanoival(c(s,s), c(e,e), c(T,T,T)), "longer object length is not a multiple of shorter object length") expect_warning(nanoival(c(s,s), c(e,e), c(T,T), c(F,F,F)), "longer object length is not a multiple of shorter object length") ## test that recycling is really correct, despite the warning: s <- nanotime(1e9) e <- nanotime(2e9) ni <- nanoival(s, e) + as.nanoduration(1:5*1e9) d <- as.nanoduration(1:2*1e9) expect_identical(ni + d, ni + c(d, d, d[1])) ## test S4 conversions: expect_identical(as.nanoival(aa), as(aa, "nanoival")) ## test seq: x <- as.nanoival("+2013-01-01 15:00:00 -> 2013-01-01 17:00:00-") expect_identical(seq(x, by=as.nanoperiod("1m"), length.out=4, tz="America/New_York"), nanoival(seq(nanoival.start(x), by=as.nanoperiod("1m"), length.out=4, tz="America/New_York"), seq(nanoival.end(x), by=as.nanoperiod("1m"), length.out=4, tz="America/New_York"), FALSE, TRUE)) y <- as.nanoival("+2013-01-04 15:00:00 -> 2013-01-04 17:00:00-") expect_identical(seq(x, y, by=as.nanoduration("24:00:00")), nanoival(seq(nanoival.start(x), by=as.nanoperiod("1d"), length.out=4, tz="UTC"), seq(nanoival.end(x), by=as.nanoperiod("1d"), length.out=4, tz="UTC"), FALSE, TRUE)) expect_identical(seq(x, y, length.out=4), nanoival(seq(nanoival.start(x), by=as.nanoperiod("1d"), length.out=4, tz="UTC"), seq(nanoival.end(x), by=as.nanoperiod("1d"), length.out=4, tz="UTC"), FALSE, TRUE)) ## 0-length ops: ## ------------ ## constructor: expect_identical(nanoival(nanotime(), nanotime(1)), nanoival()) expect_identical(nanoival(nanotime(), nanotime()), nanoival()) expect_identical(nanoival(nanotime(1), nanotime()), nanoival()) expect_identical(nanoival(nanotime(1), nanotime(2), logical()), nanoival()) expect_identical(nanoival(nanotime(1), nanotime(2), logical(), logical()), nanoival()) expect_identical(nanoival(nanotime(), nanotime(), logical(), logical()), nanoival()) expect_identical(as.nanoival(character()), nanoival()) ## Comp: expect_identical(nanoival(nanotime(1), nanotime(2)) > nanoival(), logical()) expect_identical(nanoival(nanotime(1), nanotime(2)) < nanoival(), logical()) expect_identical(nanoival() <= nanoival(nanotime(1), nanotime(2)) , logical()) expect_identical(nanoival() != nanoival(nanotime(1), nanotime(2)) , logical()) ## ops expect_identical(nanoival(nanotime(1), nanotime(2)) + integer(), as.nanoival()) expect_identical(nanoival(nanotime(1), nanotime(2)) - integer(), as.nanoival()) expect_identical(integer() + nanoival(), as.nanoival()) ## accessors expect_identical(nanoival.start(nanoival()), nanotime()) expect_identical(nanoival.end(nanoival()), nanotime()) expect_identical(nanoival.sopen(nanoival()), logical()) expect_identical(nanoival.eopen(nanoival()), logical()) ## set ops: if (extended_tests) { expect_identical(union(nanoival(nanotime(1), nanotime(2)), nanoival()), nanoival(nanotime(1), nanotime(2))) expect_identical(intersect(nanoival(nanotime(1), nanotime(2)), nanoival()), nanoival()) expect_identical(setdiff(nanoival(nanotime(1), nanotime(2)), nanoival()), nanoival(nanotime(1), nanotime(2))) expect_identical(setdiff.idx(nanotime(), nanoival()), numeric()) expect_identical(setdiff.idx(nanotime(1), nanoival()), 1) expect_identical(setdiff.idx(nanotime(), nanoival(nanotime(1), nanotime(2))), numeric()) expect_identical(intersect(nanotime(1), nanoival()), nanotime()) expect_identical(intersect(nanotime(), nanoival(nanotime(1), nanotime(2))), nanotime()) expect_identical(intersect.idx(nanotime(1), nanoival()), list(x=numeric(), y=numeric())) expect_identical(intersect.idx(nanotime(), nanoival(nanotime(1), nanotime(2))), list(x=numeric(), y=numeric())) expect_identical(nanotime() %in% nanoival(nanotime(1), nanotime(2)), logical(0)) expect_identical(nanotime(1:10) %in% nanoival(), rep(FALSE, 10)) expect_identical(is.na(as.nanoival()), logical()) } ## all.equal: expect_identical(all.equal(nanoival(nanotime(1), nanotime(2)), nanoival(nanotime(1), nanotime(2))), TRUE) expect_false(isTRUE(all.equal(nanoival(nanotime(1), nanotime(2)), "A"))) expect_identical(all.equal(nanoival(nanotime(1), nanotime(2)), NA_nanoival_), "'is.NA' value mismatch: 1 in current 0 in target") ## rep i1 <- as.nanoival(aa) i2 <- as.nanoival(bb) expect_identical(rep(i1, 2), c(i1, i1)) expect_identical(rep(c(i1,i2), each=2), c(i1, i1, i2, i2)) options(nanotimeFormat=savedFormat) nanotime/inst/tinytest/test_zoo.R0000644000176200001440000000201714635571205016725 0ustar liggesusers library(nanotime) #test_zoo <- function() { suppressMessages(library(zoo)) set.seed(42) x <- 100 + cumsum(rnorm(10)) y <- 100 + cumsum(rnorm(10)) mat <- cbind(x, y) now <- nanotime("2017-02-06T03:36:10.626159000+00:00") z <- zoo(mat, now + 11*(0:9)) # inc. by 11 to more visible, 1 works too oldOptions <- getOption("nanotimeFormat") options(nanotimeFormat = "%Y-%m-%dT%H:%M:%E9S%Ez") indexCharacter <- format(index(z)) options(nanotimeFormat = oldOptions) expect_equal(indexCharacter, c("2017-02-06T03:36:10.626159000+00:00", "2017-02-06T03:36:10.626159011+00:00", "2017-02-06T03:36:10.626159022+00:00", "2017-02-06T03:36:10.626159033+00:00", "2017-02-06T03:36:10.626159044+00:00", "2017-02-06T03:36:10.626159055+00:00", "2017-02-06T03:36:10.626159066+00:00", "2017-02-06T03:36:10.626159077+00:00", "2017-02-06T03:36:10.626159088+00:00", "2017-02-06T03:36:10.626159099+00:00")) nanotime/inst/tinytest/test_xts.R0000644000176200001440000000721213713520520016724 0ustar liggesusers## .parseISO8601 . . ## align.time . . . . ## apply.monthly . . ## as.environment.xts ## as.xts . . . . . . ## as.xts.methods . . ## axTicksByTime . . ## CLASS . . . . . . ## - coredata.xts . . . ## diff.xts ## dimnames.xts . . . ## endpoints . . . . ## first . . . . . . ## firstof . . . . . ## indexClass . . . . ## indexTZ ## - index ## isOrdered . . . . ## make.index.unique ## merge.xts . . . . ## na.locf.xts . . . ## ndays . . . . . . ## period.apply . . . ## period.max . . . . ## period.min . . . . ## period.prod . . . ## period.sum . . . . ## periodicity . . . ## plot.xts . . . . . ## - rbind.xts ## sample_matrix . . ## split.xts . . . . ## timeBased . . . . ## timeBasedSeq . . . ## to.period . . . . ## xts . . . . . . . ## xtsAPI . . . . . . ## xtsAttributes . . ## xtsInternals . . . ## [.xts . . . . . . exit_file("Skip xts tests for now") library(nanotime) ## check for hypothetical future version with nanotime support .runTheseTests <- requireNamespace("xts", quietly=TRUE) && packageVersion("xts") >= "0.12.0" if (!.runTheseTests) exit_file("Skip this xts version") suppressMessages(library(xts)) i1 <- nanotime(Sys.time()) + as.integer64(1:10) a1 <- matrix(1:30, 10, 3) x1 <- xts(a1, i1) expect_equal(coredata(x1), a1) #test_coredata.xts <- function() { i1 <- nanotime(Sys.time()) + as.integer64(1:10) a1 <- matrix(1:30, 10, 3) x1 <- xts(a1, i1) expect_equal(coredata(x1), a1) #test_index.xts <- function() { i1 <- nanotime(Sys.time()) + as.integer64(1:10) a1 <- matrix(1:30, 10, 3) x1 <- xts(a1, i1) ## don't check attributes, as xts adds 'tzone' and 'tclass' expect_equal(index(x1), i1, check.attributes = FALSE) #test_rbind.xts <- function() { i1 <- nanotime(Sys.time()) + as.integer64(1:10) i2 <- nanotime(Sys.time()) + as.integer64(11:20) x1 <- xts(matrix(1:30, 10, 3), i1) x2 <- xts(matrix(1:30, 10, 3), i2) exp <- xts(rbind(matrix(1:30, 10, 3), matrix(1:30, 10, 3)), nanotime(c(i1,i2))) expect_equal(rbind(x1, x2), exp) #test_c.xts <- function() { i1 <- nanotime(Sys.time())+ as.integer64(1:10) i2 <- nanotime(Sys.time())+ as.integer64(11:20) x1 <- xts(matrix(1:30, 10, 3), i1) x2 <- xts(matrix(1:30, 10, 3), i2) exp <- xts(rbind(matrix(1:30, 10, 3), matrix(1:30, 10, 3)), nanotime(c(i1,i2))) expect_equal(c(x1, x2), exp) #test_cbind.xts <- function() { i1 <- nanotime(Sys.time())+ as.integer64(1:10) i2 <- nanotime(Sys.time())+ as.integer64(11:20) dimnames1 <-list(NULL, c("a1","b1","c1")) dimnames2 <-list(NULL, c("a2","b2","c2")) a1 <- matrix(1:30, 10, 3, dimnames=dimnames1) a2 <- matrix(1:30, 10, 3, dimnames=dimnames2) x1 <- xts(a1, i1) x2 <- xts(a2, i2) exp <- xts(rbind(cbind(a1, matrix(NA, 10, 3, dimnames=dimnames2)), cbind(matrix(NA, 10, 3, dimnames=dimnames1), a2)), nanotime(c(i1,i2))) expect_equal(cbind(x1, x2), exp) ## test_plot.xts <- function() ## { ## ## plot doesn't work properly ## data(sample_matrix) ## sample.xts <- as.xts(sample_matrix) ## x <- xts(coredata(sample.xts), nanotime(index(sample.xts))) ## plot(x[,"Close"]) ## } #test_dimnames.xts <- function() { dimnames1 <-list(NULL, c("a1","b1","c1")) i1 <- nanotime(Sys.time())+ as.integer64(1:10) a1 <- matrix(1:30, 10, 3, dimnames=dimnames1) x1 <- xts(a1, i1) expect_equal(dimnames(x1), dimnames1) #test_align.time <- function() { i1 <- nanotime(Sys.time()) + as.integer64(1e9*1:200) a1 <- matrix(1:600, 200, 3) x1 <- xts(a1, i1) xx1 <- xts(a1, as.POSIXct(i1)) expect_equal(align.time(x1, n=as.integer64(60*1e9)), a1) #test_endpoints.xts <- function() { data(sample_matrix) sample.xts <- as.xts(sample_matrix) x <- xts(coredata(sample.xts), nanotime(index(sample.xts))) expect_equal(endpoints(x), c(0, 30, 58, 89, 119, 150, 180)) nanotime/inst/tinytest/test_nanotime.R0000644000176200001440000010021114635571205017723 0ustar liggesusers suppressMessages({ library(nanotime) library(bit64) }) options(digits=7) # needed for error message of 0.3333333 below expect_equal_numeric <- function(x,y,...) expect_equal(as.numeric(x), as.numeric(y), ...) isArm64 <- Sys.info()[["machine"]] == "arm64" ## nanotime constructors ##test_nanotime_generic <- function() { expect_identical(S3Part(nanotime(1), strict=TRUE), as.integer64(1)) expect_identical(nanotime(1), new("nanotime", as.integer64(1))) expect_identical(nanotime(as.integer64(1)), new("nanotime", as.integer64(1))) expect_identical(as.nanotime(1), new("nanotime", as.integer64(1))) expect_identical(as.nanotime(as.integer64(1)), new("nanotime", as.integer64(1))) ##test_nanotime_character_first_pass <- function() { ## we do a first pass parsing, which is faster than the parsing ## with the format string, and is also more forgiving expect_identical(nanotime("2018-01-01T05:00:00.99 Europe/London"), nanotime(as.integer64("1514782800990000000"))) expect_identical(nanotime("2018-01-01T05:00:00.999_999_999 America/New_York"), nanotime(as.integer64("1514800800999999999"))) expect_identical(nanotime("2018-01-01T05:00:00.999_999 America/New_York"), nanotime(as.integer64("1514800800999999000"))) expect_identical(nanotime("2018-01-01T05:00:00.999 America/New_York"), nanotime(as.integer64("1514800800999000000"))) expect_identical(nanotime("2018-01-01T05:00:00 America/New_York"), nanotime(as.integer64("1514800800000000000"))) expect_identical(nanotime("2018-01-01 05:00:00 America/New_York"), nanotime(as.integer64("1514800800000000000"))) expect_identical(nanotime("2018-01-01 05:00:00 America/New_York"), nanotime(as.integer64("1514800800000000000"))) expect_identical(nanotime("2018-01-01 America/New_York"), nanotime(as.integer64("1514782800000000000"))) expect_identical(nanotime("2018-01-01T05:00:00.99+00:00"), nanotime(as.integer64("1514782800990000000"))) expect_identical(nanotime("2018-01-01T05:00:00.99-00:00"), nanotime(as.integer64("1514782800990000000"))) expect_identical(nanotime("2018-01-01T05:00:00.999_999_999+05:00"), nanotime(as.integer64("1514764800999999999"))) expect_identical(nanotime("2018-01-01T05:00:00.999_999+05:00"), nanotime(as.integer64("1514764800999999000"))) expect_identical(nanotime("2018-01-01T05:00:00.999+05:00"), nanotime(as.integer64("1514764800999000000"))) expect_identical(nanotime("2018-01-01T05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(nanotime("2018-01-01 05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(nanotime("2018-01-01 05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(nanotime("2018-01-01 05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(nanotime("2018-01-01+05:00"), nanotime(as.integer64("1514746800000000000"))) expect_identical(nanotime("2018/01/01T05:00:00.99 Europe/London"), nanotime(as.integer64("1514782800990000000"))) expect_identical(nanotime("2018 01 01T05:00:00.99 Europe/London"), nanotime(as.integer64("1514782800990000000"))) ## test the alias 'as.nanotime': expect_identical(as.nanotime("2018-01-01T05:00:00.99 Europe/London"), nanotime(as.integer64("1514782800990000000"))) expect_identical(as.nanotime("2018-01-01T05:00:00.999_999_999 America/New_York"), nanotime(as.integer64("1514800800999999999"))) expect_identical(as.nanotime("2018-01-01T05:00:00.999_999 America/New_York"), nanotime(as.integer64("1514800800999999000"))) expect_identical(as.nanotime("2018-01-01T05:00:00.999 America/New_York"), nanotime(as.integer64("1514800800999000000"))) expect_identical(as.nanotime("2018-01-01T05:00:00 America/New_York"), nanotime(as.integer64("1514800800000000000"))) expect_identical(as.nanotime("2018-01-01 05:00:00 America/New_York"), nanotime(as.integer64("1514800800000000000"))) expect_identical(as.nanotime("2018-01-01 05:00:00 America/New_York"), nanotime(as.integer64("1514800800000000000"))) expect_identical(as.nanotime("2018-01-01 America/New_York"), nanotime(as.integer64("1514782800000000000"))) expect_identical(as.nanotime("2018-01-01T05:00:00.99+00:00"), nanotime(as.integer64("1514782800990000000"))) expect_identical(as.nanotime("2018-01-01T05:00:00.99-00:00"), nanotime(as.integer64("1514782800990000000"))) expect_identical(as.nanotime("2018-01-01T05:00:00.999_999_999+05:00"), nanotime(as.integer64("1514764800999999999"))) expect_identical(as.nanotime("2018-01-01T05:00:00.999_999+05:00"), nanotime(as.integer64("1514764800999999000"))) expect_identical(as.nanotime("2018-01-01T05:00:00.999+05:00"), nanotime(as.integer64("1514764800999000000"))) expect_identical(as.nanotime("2018-01-01T05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(as.nanotime("2018-01-01 05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(as.nanotime("2018-01-01 05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(as.nanotime("2018-01-01 05:00:00+05:00"), nanotime(as.integer64("1514764800000000000"))) expect_identical(as.nanotime("2018-01-01+05:00"), nanotime(as.integer64("1514746800000000000"))) expect_identical(as.nanotime("2018/01/01T05:00:00.99 Europe/London"), nanotime(as.integer64("1514782800990000000"))) expect_identical(as.nanotime("2018 01 01T05:00:00.99 Europe/London"), nanotime(as.integer64("1514782800990000000"))) expect_identical(as.nanotime(NULL), nanotime()) expect_identical(as.nanotime(NULL), as.nanotime()) ##test_nanotime_character_first_pass_fail <- function() { ## none of these should parse expect_error(nanotime("2018-01-01T05:00:00.99 America/New_dYork"), "Cannot retrieve timezone") expect_error(nanotime("2018--01-01T05:00:00.99 America/New_York"), "Parse error") expect_error(nanotime("2018-01-01T05:00:00.99 America/New_York s"), "Parse error") expect_error(nanotime("2018-01-01T05:00:s0.99 America/New_York"), "Parse error") expect_error(nanotime("2018-01-01T05:00:00.a99 America/New_York"), "Parse error") expect_error(nanotime("2018-01-01T05:00:00.0000000000 America/New_York"), "Parse error") expect_error(nanotime("201"), "Parse error") expect_error(nanotime("2018-13-01T05:00:00.99 Europe/London"), "Parse error") expect_error(nanotime("2018"), "Parse error") expect_error(nanotime("2018-1"), "Parse error") expect_error(nanotime("2018-01-32T05:00:00.99 Europe/London"), "Parse error") expect_error(nanotime("2018-01-01T25:00:00.99 Europe/London"), "Parse error") expect_error(nanotime("2018-01-01T05:61:00.99 Europe/London"), "Parse error") expect_error(nanotime("2018-01-01T05:00:61.99 Europe/London"), "Parse error") expect_error(nanotime("2018-01-01T05:00:00.99999999999 Europe/London"), "Parse error") expect_error(nanotime("2018-01-01T05:00:00.99 Europe/London%"), "Parse error") expect_error(nanotime("2018-01-01T05:00:00.99 %"), "Parse error") expect_error(as.nanotime("2013-01-01 00:00:00 America/New_York", tz="Europe/London"), "timezone is specified twice: in the string and as an argument") ##test_nanotime_character_second_pass <- function() { ## if the parsing above has failed, then we use a second parsing ## that is based on the format string that is provided oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") ## check that the format and time zone is picked up from the global options: options(nanotimeFormat="%Y|%m|%d %H:%M") options(nanotimeTz="America/New_York") expect_identical(nanotime("1970|01|01 00:00"), nanotime(18000000000000)) ## check they are overridden by the parameters: expect_identical(nanotime("1970|01|01 00:00:01", format="%Y|%m|%d %H:%M:%S", tz="Europe/Paris"), nanotime(-3599000000000)) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_nanotime_character_second_pass_fail <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") ## check that the format and time zone is picked up from the global options: options(nanotimeFormat="%Y|%m|%d %H:%M") options(nanotimeTz="America/New_York") expect_error(nanotime("1970-01-01 00:00"), "Parse error on 1970-01-01 00:00") ## check they are overridden by the parameters: expect_error(nanotime("1970-01-01 00:00", format="%Y|%m|%d %H:%M:%S", tz="Europe/Paris"), "Parse error") options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_nanotime_matrix <- function() { m <- matrix(c(10*24*3600+0:9, 987654321+0:9), 10, 2) expect_identical(nanotime.matrix(m), nanotime("1970-01-11T00:00:00.987654321+00:00") + seq(0, 9e9, by=1e9) + 0:9) ##test_nanotime_POSIXct <- function() { p <- as.POSIXct("1970-01-01 00:00:00", tz="America/New_York", accurate=FALSE) expect_identical(nanotime(p), nanotime("1970-01-01T00:00:00.000000000-05:00")) expect_identical(as.nanotime(p), nanotime("1970-01-01T00:00:00.000000000-05:00")) ## See: https://github.com/eddelbuettel/nanotime/issues/115 ## This one should break if multiplying the double by 1E9 directly ## without considering the integer and fraction parts separately. p <- as.POSIXct(as.numeric('0x1.91f18e4d0065p+30'), origin = '1970-01-01') if (!isArm64) expect_identical(p, as.POSIXct(as.nanotime(p))) ## This one is negative, making sure that negative doubles are also consistent. p <- as.POSIXct(as.numeric('-0x1.c6e8c4d077ae4p+30'), origin = '1970-01-01') if (!isArm64) expect_identical(p, as.POSIXct(as.nanotime(p))) ## with the 'accurate' parameter set to FALSE, the round trip should not be equal: p <- as.POSIXct(as.numeric('0x1.91f18e4d0065p+30'), origin = '1970-01-01') expect_false(p == as.POSIXct(as.nanotime(p, accurate=FALSE))) ##test_nanotime_POSIXlt <- function() { l <- as.POSIXlt("1970-01-01 00:00:00", tz="America/New_York") expect_identical(nanotime(l), nanotime("1970-01-01T00:00:00.000000000-05:00")) expect_identical(as.nanotime(l), nanotime("1970-01-01T00:00:00.000000000-05:00")) ##test_nanotime_Date <- function() { d <- as.Date(10, origin="1970-01-01") expect_identical(nanotime(d), nanotime("1970-01-11T00:00:00.000000000-00:00")) expect_identical(as.nanotime(d), nanotime("1970-01-11T00:00:00.000000000-00:00")) ##test_nanotime_numeric_keep_names <- function() { n <- nanotime(c(a=1, b=2)) expect_identical(names(n), c("a","b")) ##test_nanotime_character_keep_names <- function() { n <- nanotime(c(a="1970-01-01T00:00:00.000000001+00:00", b="1970-01-01T00:00:00.000000001+00:00")) expect_identical(names(n), c("a","b")) ##test_nanotime_POSIXct_keep_names <- function() { p <- as.POSIXct("1970-01-01 00:00:00", tz="America/New_York") n <- nanotime(c(a=p, b=p)) expect_identical(names(n), c("a","b")) ##test_nanotime_POSIXlt_keep_names <- function() { l <- as.POSIXlt("1970-01-01 00:00:00", tz="America/New_York") n <- nanotime(c(a=l, b=l)) expect_identical(names(n), c("a","b")) ## format, and as.character ##test_format_default <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat=NULL) options(nanotimeTz=NULL) expect_identical(format(nanotime("1970-01-01T00:00:00.000000000+00:00")), "1970-01-01T00:00:00+00:00") expect_identical(format(nanotime("1680-07-17T00:00:01.000000000+00:00")), "1680-07-17T00:00:01+00:00") expect_identical(format(nanotime("2120-01-01T00:00:59.987654321+00:00")), "2120-01-01T00:00:59.987654321+00:00") expect_identical(format(nanotime(NULL)), "nanotime(0)") expect_identical(as.character(nanotime("1970-01-01T00:00:00.000000000+00:00")), "1970-01-01T00:00:00+00:00") expect_identical(as.character(nanotime("1680-07-17T00:00:01.000000000+00:00")), "1680-07-17T00:00:01+00:00") expect_identical(as.character(nanotime("2120-01-01T00:00:59.987654321+00:00")), "2120-01-01T00:00:59.987654321+00:00") expect_identical(as.character(format(nanotime(NULL))), "nanotime(0)") options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_tz <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat=NULL) a_utc = "1970-01-01T00:00:00+00:00" nt <- nanotime(a_utc) a_ny <- "1969-12-31T19:00:00-05:00" options(nanotimeTz=NULL) expect_identical(format(nt, tz="America/New_York"), a_ny) options(nanotimeTz="UTC") expect_identical(format(nt, tz="America/New_York"), a_ny) attr(nt, "tzone") <- "UTC" expect_identical(format(nt, tz="America/New_York"), a_ny) expect_identical(format(nt, tz=""), a_utc) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_tzone <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat=NULL) a <- nanotime("1970-01-01T00:00:00.001000000+00:00") attr(a, "tzone") <- "America/New_York" a_ny <- "1969-12-31T19:00:00.001-05:00" expect_identical(format(a), a_ny) options(nanotimeTz="UTC") expect_identical(format(a), a_ny) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_tz_from_options <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat=NULL) options(nanotimeTz="America/New_York") a <- nanotime("1970-01-01T00:00:00.000001000+00:00") a_ny <- "1969-12-31T19:00:00.000001-05:00" expect_identical(format(a), a_ny) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_fmt_default <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat=NULL) options(nanotimeTz=NULL) a_str <- "1970-01-01T00:00:00+00:00" a <- nanotime(a_str) expect_identical(format(a), a_str) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_fmt_from_options <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat="%Y/%m/%dT%H:%M:%E9S%Ez") options(nanotimeTz="America/New_York") a <- nanotime("1970/01/01T00:00:00.000000000+00:00") a_ny <- "1969/12/31T19:00:00.000000000-05:00" expect_identical(format(a), a_ny) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_fmt_from_parameter <- function() { oldFormat <- getOption("nanotimeFormat") oldTz <- getOption("nanotimeTz") options(nanotimeFormat="%Y/%m/%dT%H:%M:%E9S%Ez") options(nanotimeTz="America/New_York") a <- nanotime("1970-01-01 00:00:00.000000000+00:00", format="%Y-%m-%d %H:%M:%E9S%Ez") # the result of format on a is taken from the global option: a_ny <- "1969/12/31T19:00:00.000000000-05:00" expect_identical(format(a), a_ny) options(nanotimeFormat=oldFormat) options(nanotimeTz=oldTz) ##test_format_na <- function() { if (FALSE) { f <- format(nanotime(c(1, NA, 2, NaN))) exp <- c("1970-01-01T00:00:00.000000001+00:00", as.character(NA), "1970-01-01T00:00:00.000000002+00:00", as.character(NA)) expect_identical(f, exp) } ## conversions ##test_as_POSIXct <- function() { a <- nanotime(0) attr(a, "tzone") <- "America/New_York" p <- as.POSIXct(a) expect_identical(p, as.POSIXct("1969-12-31 19:00:00", tz="America/New_York")) oldTz <- getOption("nanotimeTz") options(nanotimeTz="America/New_York") b <- nanotime(0) p <- as.POSIXct(b) ## LLL: not fully satisfactory here; nanotime will not have 'tz' set from the environment: expect_equal(p, as.POSIXct("1969-12-31 19:00:00", tz="America/New_York"), check.tzone=FALSE) options(nanotimeTz=NULL) c <- nanotime(0) p <- as.POSIXct(c) expect_equal(p, as.POSIXct("1970-01-01 00:00:00", tz="UTC"), check.tzone=FALSE) options(nanotimeTz=oldTz) ##test_as_Date <- function() { ## test scalar nanotime_scalar <- nanotime("2023-09-21T22:00:00 America/New_York") expect_identical(as.Date(nanotime_scalar, tz="UTC"), as.Date("2023-09-22")) ## test vector nanotime_vec <- rep(nanotime("2023-09-21T22:00:00 America/New_York"), 2) tz_vec <- c("UTC", "America/New_York") expect_identical(as.Date(nanotime_vec, tz=tz_vec), as.Date(c("2023-09-22", "2023-09-21"))) ## test missing argument 'tz': now UTC filled in expect_silent(as.Date(nanotime_vec)) expect_identical(as.Date(nanotime_vec), as.Date(nanotime_vec, tz="UTC")) ## test exception for extraneous argument: expect_error(as.Date(nanotime_vec, y=2, z=3), "'as.Date' called with arguments other than 'tz': 'y', 'z'") expect_silent(as.Date(x=nanotime_vec)) # check we can still name 'x' without an exception ## c, subset, subassign and binds ##test_c <- function() { a <- c(nanotime(1), nanotime(2)) expect_identical(a, nanotime(1:2)) a <- c(nanotime(1:2), nanotime(3:4)) expect_identical(a, nanotime(1:4)) ## subset ## subset integer a <- nanotime(1:10) expect_identical(a[3], nanotime(3)) expect_identical(a[1:10], a) expect_identical(a[c(1:3, NA)], c(nanotime(1:3), NA_nanotime_)) expect_identical(a[11], NA_nanotime_) expect_identical(a[c(0, 2)], as.nanotime(2)) expect_warning(a[1, 2], "unused indices or arguments in 'nanotime' subsetting") expect_error(a[c(1,-2)], "only 0's may be mixed with negative subscripts") expect_error(a[c(-1, 2)], "only 0's may be mixed with negative subscripts") names(a) <- paste0("a", 1:10) expect_identical(a[c(1,10)], c(a1=as.nanotime(1), a10=as.nanotime(10))) res <- c(a1=as.nanotime(1), a10=as.nanotime(10), NA) names(res)[3] <- NA_character_ expect_identical(a[c(1,10,NA)], res) expect_identical(a[11], res[3]) ## subset logical a <- nanotime(1:10) expect_identical(a[c(T,F)], nanotime(c(1,3,5,7,9))) expect_identical(a[c(T,F,F,F,NA)], nanotime(c(1, NA, 6, NA))) expect_identical(a[c(1:3, NA)], c(nanotime(1:3), NA_nanotime_)) expect_warning(a[T, F], "unused indices or arguments in 'nanotime' subsetting") names(a) <- paste0("a", 1:10) expect_identical(a[c(T,F,F,F,F)], a[c(1,6)]) res <- c(a1=as.nanotime(1), NA) names(res)[2] <- NA_character_ expect_identical(a[c(T,F,F,F,F,F,F,F,F,NA)], res) ## subset named character a <- nanotime(1:10) names(a) <- paste0("a", 1:10) expect_identical(a[c("a1", "a3", "a6")], a[c(1,3,6)]) expect_identical(a[c("a1", "a3", NA)], a[c(1,3,NA)]) expect_identical(a[c("a1", "a3", "a11")], a[c(1,3,NA)]) expect_warning(a["a", "b"], "unused indices or arguments in 'nanotime' subsetting") ## subset error a <- nanotime(1:10) expect_error(a[as.integer64(1)], "']' not defined on 'nanotime' for index of type 'ANY'") ##test_subsassign <- function() { a <- nanotime(1:10) a[3] <- nanotime(13) expect_identical(a[3], nanotime(13)) a[1:10] <- nanotime(10:1) expect_identical(a[1:10], nanotime(10:1)) ## summary ##test_summary <- function() { expected <- nanotime(c(1,2,2,2,3,4)) names(expected) <- c("Min.", "1st Qu.", "Median", "Mean", "3rd Qu.", "Max.") expect_identical(summary(nanotime(1:4)), expected) expected <- nanotime(c(1,2,3,3,4,5)) names(expected) <- c("Min.", "1st Qu.", "Median", "Mean", "3rd Qu.", "Max.") expect_identical(summary(nanotime(1:5)), expected) ## Arith ##test_unary_minus <- function() { expect_error(-nanotime(1), "unary '-' is not defined for \\\"nanotime\\\" objects") ##test_unary_plus <- function() { expect_error(+nanotime(1), "unary '\\+' is not defined for \\\"nanotime\\\" objects") ##test_ANY_minus_nano <- function() { expect_error(1 - nanotime(2), "invalid operand types") ##test_nano_minus_nanoperiod <- function() { msg <- paste0("binary '\\-' is not defined for 'nanotime' and 'nanoperiod' objects; instead use 'minus\\(e1, e2, tz\\)'") expect_error(nanotime(1) - as.nanoperiod("2m"), msg) ##test_nano_minus_ANY <- function() { expect_error(nanotime(1) - "a", "invalid operand types") ##test_nano_minus_nanoduration <- function() { nt <- nanotime(2000) expect_identical(nt - as.nanoduration(2000), nanotime(0)) ## + ##test_ANY_plus_nano <- function() { expect_error("a" + nanotime(2), "invalid operand types") ##test_nano_plus_ANY <- function() { expect_error(nanotime(1) + "a", "invalid operand types") ##test_nano_plus_nanoperiod <- function() { msg <- paste0("binary '\\+' is not defined for 'nanotime' and 'nanoperiod' objects; instead use 'plus\\(e1, e2, tz\\)'") expect_error(nanotime(1) + as.nanoperiod("2m"), msg) ##test_nano_plus_nanoduration <- function() { nt <- nanotime(2000) expect_identical(nt + as.nanoduration(2000), nanotime(4000)) ## * ##test_nano_mul_nano <- function() { expect_error(nanotime(1) * nanotime(1), "operation not defined for \"nanotime\" objects") ##test_nano_mul_nano <- function() { expect_error(nanotime(1) * nanotime(2), "operation not defined for \"nanotime\" objects") ##test_nano_mul_ANY <- function() { expect_error(nanotime(1) * 1, "operation not defined for \"nanotime\" objects") ##test_nano_div_ANY <- function() { ## div is in the same 'Arith' group as mul: expect_error(nanotime(1) / 1, "operation not defined for \"nanotime\" objects") ##test_nano_Logic_ANY <- function() { expect_error(nanotime(1) | 1, "operations are possible only for numeric, logical or complex types") ##test_ANY_Logic_nano <- function() { expect_error(1 | nanotime(1), "operations are possible only for numeric, logical or complex types") ##test_Math_nano <- function() { expect_error(sin(nanotime(1)), "non-numeric argument to mathematical function") ##test_Math2_nano <- function() { expect_error(round(nanotime(1)), "non-numeric argument to mathematical function") ## miscellaneous ##test_is.na <- function() { expect_true(is.na(nanotime(NA))) expect_true(is.na(nanotime(NaN))) nn <- nanotime(1:10) is.na(nn) <- 1:3 expect_true(all(is.na(nn[1:3]))) expect_true(!any(is.na(nn[4:10]))) expect_true(is.na(NA_nanotime_)) ## test square bracket (#44) ##test_square_bracket <- function() { times <- c(nanotime('2011-12-05 08:30:00.000',format ="%Y-%m-%d %H:%M:%E9S", tz ="GMT"), nanotime('2011-12-05 08:30:00.100',format ="%Y-%m-%d %H:%M:%E9S", tz ="GMT"), nanotime('2011-12-05 08:30:00.825',format ="%Y-%m-%d %H:%M:%E9S", tz ="GMT")) expect_identical(times[1], times[[1]]) expect_identical(times[2], times[[2]]) expect_identical(times[3], times[[3]]) ## test compare expect_true(nanotime(1) == nanotime(1)) expect_true(nanotime(1) != nanotime(2)) expect_true(nanotime(1) <= nanotime(1)) expect_true(nanotime(1) >= nanotime(1)) expect_true(nanotime(1) <= nanotime(2)) expect_false(nanotime(1) >= nanotime(2)) expect_true(nanotime(1) < nanotime(2)) expect_false(nanotime(1) > nanotime(2)) ## with character expect_true(nanotime(1) == nanotime("1970-01-01T00:00:00.000000001+00")) expect_true(nanotime("1970-01-01T00:00:00.000000001+00") != nanotime(2)) expect_true(nanotime("1970-01-01T00:00:00.000000001+00") <= nanotime(1)) expect_true(nanotime("1970-01-01T00:00:00.000000001+00") >= nanotime(1)) expect_true(nanotime(1) <= nanotime("1970-01-01T00:00:00.000000002+00")) expect_false(nanotime("1970-01-01T00:00:00.000000001+00") >= nanotime(2)) expect_true(nanotime(1) < nanotime("1970-01-01T00:00:00.000000002+00")) expect_false(nanotime("1970-01-01T00:00:00.000000001+00") > nanotime(2)) ## with POSIXt pt1 <- as.POSIXct(1, origin="1970-01-01", tz="UTC") pt2 <- as.POSIXct(2, origin="1970-01-01", tz="UTC") expect_true(pt1 == nanotime("1970-01-01T00:00:01+00")) expect_true(nanotime("1970-01-01T00:00:01+00") != pt2) expect_true(nanotime("1970-01-01T00:00:01+00") <= pt1) expect_true(nanotime("1970-01-01T00:00:01+00") >= pt1) expect_true(nanotime(1) <= nanotime("1970-01-01T00:00:02+00")) expect_false(nanotime("1970-01-01T00:00:01+00") >= pt2) expect_true(nanotime(1) < nanotime("1970-01-01T00:00:00.000000002+00")) expect_false(nanotime("1970-01-01T00:00:01+00") > pt2) ## all.equal ##test_all.equal_nanotime_any <- function() { expect_true(!isTRUE(all.equal(nanotime(1), "a"))) ##test_all.equal_any_nanotime <- function() { expect_true(!isTRUE(all.equal("a", nanotime(1)))) ##test_all.equal_nanotime_nanotime <- function() { expect_true(isTRUE(all.equal(nanotime(1), nanotime(1)))) expect_true(!isTRUE(all.equal(nanotime(1), nanotime(2)))) expect_identical(all.equal(nanotime(1), nanotime(2)), "Mean relative difference: 1") expect_identical(all.equal(nanotime(c(1L,NA)), nanotime(1:2)), "'is.NA' value mismatch: 0 in current 1 in target") expect_error(all.equal(nanotime(1), nanotime(1), tolerance="1"), "'tolerance' should be numeric") expect_error(all.equal(nanotime(1), nanotime(1), scale="1"), "'scale' should be numeric or NULL") expect_error(all.equal(nanotime(1), nanotime(1), check.attributes="1"), "'check.attributes' must be logical") expect_error(all.equal(nanotime(1), nanotime(2), scale=-1), "all\\(scale > 0\\) is not TRUE") expect_false(isTRUE(all.equal(nanotime(1), as.nanoperiod("1d")))) expect_identical(all.equal(nanotime(1), nanotime(1:2)), "Numeric: lengths (1, 2) differ") expect_identical(all.equal(nanotime(c(1,2,3)), nanotime(c(1,1,2)), countEQ=TRUE), "Mean relative difference: 0.3333333") expect_false(isTRUE(all.equal(nanotime(1), 1i))) expect_identical(all.equal(nanotime(1), nanotime(3), tolerance=1), "Mean absolute difference: 2") expect_identical(all.equal(nanotime(1), nanotime(2e9), scale=1e9), "Mean scaled difference: 2") expect_identical(all.equal(nanotime(1), nanotime(2e9), scale=1), "Mean absolute difference: 2e+09") ## test S4 conversions: ## to 'nanotime': expect_identical(as("2018-01-01T05:00:00.99 Europe/London", "nanotime"), nanotime(as.integer64("1514782800990000000"))) expect_identical(as(as.Date(10, origin="1970-01-01"), "nanotime"), nanotime("1970-01-11T00:00:00.000000000-00:00")) expect_identical(as(as.integer64("1514782800990000000"), "nanotime"), nanotime("2018-01-01T05:00:00.99 Europe/London")) expect_identical(as(as.POSIXct(1514782800, origin="1970-01-01", tz="UTC"), "nanotime"), nanotime("2018-01-01T05:00:00 Europe/London")) expect_identical(as(as.POSIXlt(as.POSIXct(1514782800, origin="1970-01-01", tz="UTC")), "nanotime"), nanotime("2018-01-01T05:00:00 Europe/London")) ## from 'nanotime': expect_identical(as(nanotime("1970-01-11T00:00:00.000000000-00:00"), "Date"), as.Date("1970-01-11")) ## don't run this one, it's only right when run in America/New_York timezone! ## expect_identical(as(nanotime("1970-01-11T00:00:00.000000000-00:00"), "POSIXct"), as.POSIXct("1970-01-10 19:00:00")) expect_identical(as(nanotime("1970-01-11T00:00:00.000000000-00:00"), "integer64"), as.integer64("864000000000000")) expect_identical(as(nanotime("1970-01-11T00:00:00.000000000-00:00"), "nanoduration"), as.nanoduration("240:00:00")) ## test nanotime sequences: ## straightforward with integer64 and nanoduration1 expect_identical(seq(as.nanotime(1), by=1e9, length.out=10), as.nanotime(seq(1, by=1e9, length.out=10))) expect_identical(seq(as.nanotime(1), by=1e9, along.with=1:10), as.nanotime(seq(1, by=1e9, length.out=10))) expect_identical(seq(from=as.nanotime(1), to=as.nanotime(10e9), by=1e9), as.nanotime(seq(1, 10e9, by=1e9))) expect_identical(seq(from=as.nanotime(1), to=as.nanotime(9e9+1), length.out=10), as.nanotime(seq(1, 10e9, by=1e9))) expect_identical(seq(as.nanotime(1), by=as.nanoduration(1e9), length.out=10), as.nanotime(seq(1, by=1e9, length.out=10))) expect_identical(seq(as.nanotime(1), as.nanotime(10e9), by=as.nanoduration(1e9)), as.nanotime(seq(1, 10e9, by=1e9))) ## increment with a period: expect_identical(seq(as.nanotime(0), by=as.nanoperiod("1m"), length.out=4, tz="UTC"), as.nanotime(c("1970-01-01T00:00:00+00:00", "1970-02-01T00:00:00+00:00", "1970-03-01T00:00:00+00:00", "1970-04-01T00:00:00+00:00"))) expect_identical(seq(as.nanotime(0), by=as.nanoperiod("1m"), length.out=0, tz="UTC"), nanotime()) expect_identical(seq(as.nanotime(0), to=as.nanotime("1970-04-01T00:00:00+00:00"), by=as.nanoperiod("1m"), tz="UTC"), as.nanotime(c("1970-01-01T00:00:00+00:00", "1970-02-01T00:00:00+00:00", "1970-03-01T00:00:00+00:00", "1970-04-01T00:00:00+00:00"))) ## other seq errors or warnings: expect_warning(seq(as.nanotime(1), by=1e9, length.out=10:12), "first element used of 'length.out' argument") expect_error(seq(as.nanotime(0), by=as.nanoperiod(c("1m","2m")), length.out=4, tz="UTC"), "'by' must be of length 1") expect_error(seq(as.nanotime(0), by=as.nanoperiod("1m"), length.out=-1, tz="UTC"), "'length.out' must be a non-negative number") expect_error(seq(from=as.nanotime(1)), "'seq.nanotime' cannot be called with only one argument") expect_error(seq(from=as.nanotime(1), to=as.nanotime(2), length.out=as.integer()), "argument 'length.out' must be of length 1") expect_error(seq(from=as.nanotime(1), length.out=1), "at least two of 'to', 'by', and 'length.out' or 'along.with' must be specified") expect_error(seq(from=as.nanotime(1), to=as.nanoduration(10e9), by=1e9), "'to' must be a 'nanotime'") expect_error(seq(from=as.nanotime(1:2), to=as.nanotime(1), by=1e9), "'from' must be of length 1") expect_error(seq(from=as.nanotime(1), to=as.nanotime(1:2), by=1e9), "'to' must be of length 1") expect_error(seq(from=as.nanotime(1), to=as.nanotime(2), by=1e9, length.out=1, too_much=2), "too many arguments") expect_error(seq(as.nanotime(1), by=c(1e9,2), length.out=10), "'by' must be of length 1") expect_error(seq(as.nanotime(1), to=as.nanotime(10), by=c(1e9,2)), "'by' must be of length 1") expect_error(seq(as.nanotime(1), by=as.nanoperiod("1d"), length.out=10), "'tz' is a mandatory argument for sequences with a 'period' step") expect_error(seq(as.nanotime(1), to=as.nanotime(10), by=as.nanoperiod("1d")), "'tz' is a mandatory argument for sequences with a 'period' step") ## test date time component access expect_identical(nano_wday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/New_York"), 6L) expect_identical(nano_wday(as.nanotime("2020-03-14 23:32:00 America/New_York"), "Europe/Paris"), 0L) expect_identical(nano_mday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/New_York"), 14L) expect_identical(nano_mday(as.nanotime("2020-03-14 23:32:00 America/New_York"), "Europe/Paris"), 15L) expect_identical(nano_month(as.nanotime("2020-12-31 23:32:00-04:00"), "America/New_York"), 12L) expect_identical(nano_month(as.nanotime("2020-12-31 23:32:00 America/New_York"), "Europe/Paris"), 1L) expect_identical(nano_year(as.nanotime("2020-12-31 23:32:00-04:00"), "America/New_York"), 2020L) expect_identical(nano_year(as.nanotime("2020-12-31 23:32:00 America/New_York"), "Europe/Paris"), 2021L) expect_identical(nano_year(nanotime(1:10), "America/New_York"), rep(1969L, 10)) expect_identical(nano_year(as.nanotime("1916-03-14 12:32:00-04:00"), "America/New_York"), 1916L) expect_error(nano_wday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/Nu_York"), "Cannot retrieve timezone") expect_error(nano_mday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/Nu_York"), "Cannot retrieve timezone") expect_error(nano_month(as.nanotime("2020-03-14 23:32:00-04:00"), "America/Nu_York"), "Cannot retrieve timezone") expect_error(nano_year(as.nanotime("2020-03-14 23:32:00-04:00"), "America/Nu_York"), "Cannot retrieve timezone") ## 0-length ops: ## ------------ ## constructor: expect_identical(nanotime(character(), character()), nanotime()) expect_identical(nanotime(character(), tz="America/New_York"), nanotime()) expect_identical(nanotime("2020-03-28 UTC", tz=character()), nanotime()) ## accessors/funcs expect_identical(nano_wday(nanotime(), tz=character()), integer()) expect_identical(nano_wday(nanotime(1), tz=character()), integer()) expect_identical(nano_wday(nanotime(), tz="America/New_York"), integer()) expect_identical(nano_mday(nanotime(), tz=character()), integer()) expect_identical(nano_mday(nanotime(1), tz=character()), integer()) expect_identical(nano_mday(nanotime(), tz="America/New_York"), integer()) expect_identical(nano_month(nanotime(), tz=character()), integer()) expect_identical(nano_month(nanotime(1), tz=character()), integer()) expect_identical(nano_month(nanotime(), tz="America/New_York"), integer()) expect_identical(nano_year(nanotime(), tz=character()), integer()) expect_identical(nano_year(nanotime(1), tz=character()), integer()) expect_identical(nano_year(nanotime(), tz="America/New_York"), integer()) ## rep expect_identical(rep(nanotime(1), 2), nanotime(rep(1,2))) expect_identical(rep(nanotime(1:2), each=2), nanotime(rep(1:2, each=2))) nanotime/inst/tinytest/test_ops.R0000644000176200001440000001073013745275661016730 0ustar liggesusers suppressMessages({ library(nanotime) library(bit64) }) ## ------------ `-` #"test_nanotime-nanotime" <- function() { expect_identical(nanotime(2) - nanotime(1), as.nanoduration(1)) expect_identical(nanotime(-1) - nanotime(-2), as.nanoduration(1)) #"test_nanotime-integer64" <- function() { expect_identical(nanotime(2) - as.integer64(1), nanotime(1)) expect_identical(nanotime(-1) - as.integer64(-2), nanotime(1)) #"test_nanotime-integer" <- function() { expect_identical(nanotime(2) - 1L, nanotime(1)) expect_identical(nanotime(-1) - -2L, nanotime(1)) #"test_nanotime-character" <- function() { expect_error(nanotime(0) - "A", "invalid operand types") #"test_character-nanotime" <- function() { expect_error("A" - nanotime(0), "invalid operand types") #"test_numeric-nanotime" <- function() { expect_error(1 - nanotime(0), "invalid operand types") ## ----------- `+` #"test_nanotime+numeric" <- function() { expect_identical(nanotime(0) + 1, nanotime(1)) expect_identical(nanotime(0) + -1, nanotime(-1)) #"test_nanotime+integer" <- function() { expect_identical(nanotime(0) + 1L, nanotime(1)) expect_identical(nanotime(0) + -1L, nanotime(-1)) #"test_nanotime+integer64" <- function() { expect_identical(nanotime(0) + as.integer64(1), nanotime(1)) expect_identical(nanotime(0) + as.integer64(-1), nanotime(-1)) #"test_nanotime+character" <- function() { expect_error(nanotime(0) + "A", "invalid operand types") #"test_character+nanotime" <- function() { expect_error("A" + nanotime(0), "invalid operand types") #"test_nanotime+nanotime" <- function() { expect_error(nanotime(1) + nanotime(0), "invalid operand types") #"test_nanotime+integer64" <- function() { expect_identical(nanotime(0) + as.integer64(1), nanotime(1)) expect_identical(nanotime(0) + as.integer64(-1), nanotime(-1)) #"test_numeric+nanotime" <- function() { expect_identical(nanotime(0) + 1, nanotime( 1)) expect_identical(nanotime(0) + -1, nanotime(-1)) #"test_integer+nanotime" <- function() { expect_identical( 1L + nanotime(0), nanotime(1)) expect_identical(-1L + nanotime(0), nanotime(-1)) ## ---------- other ops #test_compare_nanotime_ANY <- function() { expect_true(nanotime(1) == nanotime(1)) expect_true(nanotime(1) == as.integer64(1)) expect_true(nanotime(1) == 1L) expect_true(nanotime(1) == 1) expect_error(is.na(nanotime(1) == "a")) # now passes on and gets parse error expect_true(!(nanotime(1) < nanotime(1))) expect_true(!(nanotime(1) < as.integer64(1))) expect_true(!(nanotime(1) < 1L)) expect_true(!(nanotime(1) < 1)) #test_compare_ANY_nanotime <- function() { expect_true(as.integer64(1) == nanotime(1)) expect_true(1L == nanotime(1)) expect_true(1 == nanotime(1)) expect_true(!("a" == is.na(nanotime(1)))) expect_true(!(as.integer64(1) < nanotime(1))) expect_true(!(1L < nanotime(1))) expect_true(!(1 < nanotime(1))) #test_compare_character_nanotime <- function() { expect_true(isFALSE("2018-12-28T16:34:59.649943448+00:00" < nanotime("2018-12-28T16:34:59.000000000+00:00"))) expect_true("2018-12-28T16:34:59.649943448+00:00" > nanotime("2018-12-28T16:34:59.000000000+00:00")) expect_true("2018-12-28T16:34:59.649943448+00:00" == nanotime("2018-12-28T16:34:59.649943448+00:00")) #test_compare_nanotime_character <- function() { expect_true(isFALSE(nanotime("2018-12-28T16:34:59.649943448+00:00") < "2018-12-28T16:34:59.000000000+00:00")) expect_true(nanotime("2018-12-28T16:34:59.649943448+00:00") > "2018-12-28T16:34:59.000000000+00:00") expect_true(nanotime("2018-12-28T16:34:59.649943448+00:00") == "2018-12-28T16:34:59.649943448+00:00") #test_Logic <- function() { exc <- "operations are possible only for numeric, logical or complex types" #expect_error(nanotime(1) & nanotime(1), exc) expect_error(nanotime(1) & as.integer64(1), exc) expect_error(nanotime(1) & TRUE, exc) expect_error(as.integer64(1) & nanotime(1), exc) expect_error(1L & nanotime(1), exc) expect_error(FALSE & nanotime(1), exc) #test_Math <- function() { expect_error(abs(nanotime(1)), "non-numeric argument to mathematical function") #test_Math2 <- function() { expect_error(round(nanotime(1), 2), "non-numeric argument to mathematical function") #test_Summary <- function() { expect_error(sum(nanotime(1)))#, "invalid 'type' (nanotime) of argument") expect_identical(min(nanotime(c(1,8,4,2,0,3,10))), nanotime(0)) expect_identical(max(nanotime(c(1,8,4,2,0,3,10))), nanotime(10)) expect_identical(range(nanotime(c(1,8,4,2,0,3,10))), nanotime(c(0, 10))) #test_Complex <- function() { expect_error(Arg(nanotime(1)), "non-numeric argument to function") nanotime/inst/tinytest/test_nanoduration.R0000644000176200001440000007443714633656052020640 0ustar liggesusers suppressMessages({ library(nanotime) library(bit64) }) options(digits=7) # needed for error message below milli <- 1e6 sec <- 1e9 minute <- 60 * sec hour <- 60 * minute ## constructors ##test_nanoduration <- function() { expect_identical(nanoduration(1,1,1,1), as.nanoduration("01:01:01.000_000_001")) expect_identical(nanoduration(-1,0,0,1), as.nanoduration("-00:59:59.999_999_999")) ## R recycling: expect_identical(nanoduration(1:2,1,1,1), c(as.nanoduration("01:01:01.000_000_001"), as.nanoduration("02:01:01.000_000_001"))) expect_identical(nanoduration(), as.nanoduration(NULL)) expect_identical(length(nanoduration()), 0L) expect_identical(nanoduration(), as.nanoduration()) ##test_as.nanoduration_character_and_numeric <- function() { expect_identical(as.nanoduration("1:00:00"), as.nanoduration(hour)) expect_identical(as.nanoduration("-1:00:00"), -as.nanoduration(hour)) expect_identical(as.nanoduration("0:01:00"), as.nanoduration(minute)) expect_identical(as.nanoduration("0:00:01"), as.nanoduration(sec)) expect_identical(as.nanoduration("0:00:00.001"), as.nanoduration(milli)) expect_identical(c(as.nanoduration("1:00:00"), c(as.nanoduration("2:00:00"))), c(as.nanoduration(hour), as.nanoduration(2*hour))) expect_identical(as.nanoduration(NA_integer64_), as.nanoduration(as.integer64("-9223372036854775808"))) ## check name: n1 <- as.nanoduration(hour) names(n1) <- "a" expect_identical(as.nanoduration(c(a="1:00:00")), as.nanoduration(n1)) expect_error(as.nanoduration("10:aa"), "cannot parse nanoduration") expect_error(as.nanoduration("1000a"), "cannot parse nanoduration") expect_error(as.nanoduration("10:10:10.1000a"), "cannot parse nanoduration") expect_error(as.nanoduration("a"), "cannot parse nanoduration") expect_error(as.nanoduration(""), "cannot parse nanoduration") ##test_as.nanoduration_integer64 <- function() { expect_identical(as.nanoduration(as.integer64(hour)), as.nanoduration(hour)) expect_identical(as.nanoduration(c(a=as.integer64(hour), b=as.integer64(2*hour))), as.nanoduration(c(a=hour, b=2*hour))) ##test_as.nanoduration_integer <- function() { expect_identical(as.nanoduration(as.integer(sec)), as.nanoduration(sec)) expect_identical(as.nanoduration(c(a=as.integer(milli), b=as.integer(2*milli))), as.nanoduration(c(a=milli, b=2*milli))) ##test_as.integer64 <- function() { expect_identical(as.integer64(as.nanoduration(hour)), as.integer64(hour)) expect_identical(as.integer64(as.nanoduration(1:1000)), as.integer64(1:1000)) ## show/print/format ##test_show <- function() { d <- nanoduration(1,1,1,1) expect_identical(format(d), "01:01:01.000_000_001") expect_identical(format(-d), "-01:01:01.000_000_001") expect_true(is.na(format(as.nanoduration(as.integer64("-9223372036854775808"))))) expect_identical(as.character(d), "01:01:01.000_000_001") expect_identical(as.character(-d), "-01:01:01.000_000_001") expect_true(is.na(as.character(as.nanoduration(as.integer64("-9223372036854775808"))))) expect_stdout(show(d)) expect_stdout(show(-d)) expect_stdout(show(as.nanoduration(as.integer64("-9223372036854775808")))) ##test_print <- function() { d <- nanoduration(1,1,1,1) expect_stdout(print(d)) expect_stdout(print(nanoduration())) ##test_print_name <- function() { d <- nanoduration(1,1,1,1) names(d) <- "a" expect_identical(format(d), c(a="01:01:01.000_000_001")) expect_stdout(print(d)) ##test_format <- function() { d <- nanoduration(1,1,1,1) expect_identical(format(d), "01:01:01.000_000_001") ## subset: ##test_subset_int <- function() { dd <- as.nanoduration(1:10) expect_identical(dd[1:2], as.nanoduration(1:2)) expect_identical(dd[-1:-5], as.nanoduration(6:10)) expect_identical(dd[c(0,0,0,0,0,1,2,3,4,5)], as.nanoduration(1:5)) expect_warning(dd[1, 2], "unused indices or arguments in 'nanoduration' subsetting") ##test_subset_logical <- function() { dd <- as.nanoduration(1:4) expect_identical(dd[c(T,F,F,F)], dd[1]) expect_identical(dd[c(F,T,F,F)], dd[2]) expect_identical(dd[c(F,F,T,F)], dd[3]) expect_identical(dd[c(F,F,F,T)], dd[4]) expect_identical(dd[TRUE], dd) expect_identical(dd[c(F,T,T,F)], dd[2:3]) expect_warning(dd[T, F], "unused indices or arguments in 'nanoduration' subsetting") expect_identical(dd[c(F,F,F,NA)], NA_nanoduration_) ##test_subset_character <- function() { dd <- c(x=as.nanoduration(1), y=as.nanoduration(2)) expect_identical(dd["x"], c(x=as.nanoduration(1))) expect_identical(dd["y"], c(y=as.nanoduration(2))) expect_warning(dd["x", "y"], "unused indices or arguments in 'nanoduration' subsetting") ## also check out of bound subset res <- as.nanoduration(as.integer64(NA)) names(res) <- NA expect_identical(dd["a"], res) expect_warning(dd["a", "b"], "unused indices or arguments in 'nanoduration' subsetting") ## subset incorrect index type expect_error(dd[as.integer64(1)], "']' not defined on 'nanoduration' for index of type 'ANY'") ## subassign: ##test_subassign_logical <- function() { x <- as.nanoduration(1:10) x[c(T,T,T,F,F,F,F,F,F,F)] <- as.nanoduration(2:4) expect_identical(x, as.nanoduration(c(2:4, 4:10))) ##test_subassign_numeric <- function() { x <- as.nanoduration(1:10) x[1:3] <- as.nanoduration(2:4) x[4:10] <- as.nanoduration(5:11) expect_identical(x, as.nanoduration(2:11)) ##test_subsassign_character <- function() { dd <- c(a=as.nanoduration(1), b=as.nanoduration(2), c=as.nanoduration(3), d=as.nanoduration(4)) dd[c("b", "c")] <- as.nanoduration(20:21) expected <- c(a=as.nanoduration(1), b=as.nanoduration(20), c=as.nanoduration(21), d=as.nanoduration(4)) expect_identical(dd, expected) ##test_square_bracket <- function() { dd <- c(a=as.nanoduration(1), b=as.nanoduration(2), c=as.nanoduration(3), d=as.nanoduration(4)) dd_nonames <- as.nanoduration(1:4) expect_identical(dd_nonames[1], dd[[1]]) expect_identical(dd_nonames[2], dd[[2]]) expect_identical(dd_nonames[3], dd[[3]]) ## test names ##test_get_names <- function() { dd <- c(a=as.nanoduration(1), b=as.nanoduration(2), c=as.nanoduration(3), d=as.nanoduration(4)) expect_identical(names(dd), c("a","b","c","d")) ##test_set_names <- function() { names <- c("a","b","c","d") dd <- as.nanoduration(1:4) names(dd) <- names expect_identical(names(dd), names) names(dd)[1] <- "x" expect_identical(names(dd), c("x","b","c","d")) ## test scalar/vector mix LLL ## ops ## - ##test_nanoduration_minus_nanoduration <- function() { expect_identical(as.nanoduration("1:00:00") - as.nanoduration("00:01:00"), as.nanoduration("00:59:00")) expect_identical(as.nanoduration("-1:00:00") - as.nanoduration("00:01:00"), as.nanoduration("-01:01:00")) expect_identical(as.nanoduration("1:00:00.1") - as.nanoduration("1:00:00"), as.nanoduration("0.1")) expect_identical(as.nanoduration(1:10) - as.nanoduration(0:9), as.nanoduration(rep(1, 10))) expect_identical(as.nanoduration(1:10) - as.nanoduration(1), as.nanoduration(0:9)) expect_identical(c(a=as.nanoduration(1), b=as.nanoduration(1)) - as.nanoduration(1), as.nanoduration(c(a=0, b=0))) ##test_nanoduration_minus_numeric <- function() { expect_identical(as.nanoduration("1:00:00") - minute, as.nanoduration("00:59:00")) expect_identical(as.nanoduration(1:10) - 0.0:9, as.nanoduration(rep(1, 10))) expect_identical(as.nanoduration(1:10) - 1, as.nanoduration(0:9)) expect_identical(c(a=as.nanoduration(1), b=as.nanoduration(1)) - 1, as.nanoduration(c(a=0, b=0))) ##test_nanoduration_minus_integer <- function() { expect_identical(as.nanoduration("1:00:00") - as.integer(milli), as.nanoduration("00:59:59.999")) expect_identical(as.nanoduration(1:10) - 0:9, as.nanoduration(rep(1, 10))) expect_identical(as.nanoduration(1:10) - as.integer(1), as.nanoduration(0:9)) expect_identical(c(a=as.nanoduration(1), b=as.nanoduration(1)) - as.integer(1), as.nanoduration(c(a=0, b=0))) ##test_nanoduration_minus_integer64 <- function() { expect_identical(as.nanoduration("1:00:00") - as.integer64(minute), as.nanoduration("00:59:00")) expect_identical(as.nanoduration(1:10) - as.integer64(0:9), as.nanoduration(rep(1, 10))) expect_identical(as.nanoduration(1:10) - as.integer64(1), as.nanoduration(0:9)) expect_identical(c(a=as.nanoduration(1), b=as.nanoduration(1)) - c(c=as.integer64(1)), as.nanoduration(c(a=0, b=0))) ##test_integer64_minus_nanoduration <- function() { expect_identical(as.integer64(hour) - as.nanoduration("1:00:00"), as.nanoduration("0:00:00")) ##test_nanoduration_minus_integer64 <- function() { expect_identical(as.nanoduration("1:00:00") - as.integer64(hour), as.nanoduration("0:00:00")) ##test_numeric_minus_nanoduration <- function() { expect_identical(hour - as.nanoduration("1:00:00"), as.nanoduration("0:00:00")) ##test_integer_minus_nanoduration <- function() { expect_identical(as.integer(1e9) - as.nanoduration("1:00:00"), as.nanoduration("-00:59:59")) ## LLL name issue here due do to underlying issues with 'bit64' ## ##test_numeric_minus_nanoduration <- function() { ## expect_identical(2 - c(a=as.nanoduration(1), b=as.nanoduration(2)), ## c(a=as.nanoduration(1), b=as.nanoduration(0))) ## expect_identical(2 - c(a=as.integer64(1), b=as.integer64(2)), ## c(a=as.integer64(1), b=as.integer64(0))) ## ##test_any_minus_nanoduration <- function() { expect_error("a" - as.nanoduration("1:00:00"), "invalid operand types") ##test_nanoduration_minus_any <- function() { expect_error(as.nanoduration("1:00:00") - "a", "invalid operand types") ## + ##test_nanoduration_plus_nanoduration <- function() { expect_identical(as.nanoduration("1:00:00") + as.nanoduration("00:01:00"), as.nanoduration("01:01:00")) expect_identical(as.nanoduration("-1:00:00") + as.nanoduration("00:01:00"), as.nanoduration("-00:59:00")) expect_identical(as.nanoduration("-1:00:00.1") + as.nanoduration("1:00:00"), as.nanoduration("-0.1")) expect_identical(-as.nanoduration(1:10) + as.nanoduration(0:9), as.nanoduration(rep(-1, 10))) expect_identical(as.nanoduration(1:10) + as.nanoduration(1), as.nanoduration(2:11)) expect_identical(c(a=as.nanoduration(1), b=as.nanoduration(1)) + as.nanoduration(1), as.nanoduration(c(a=2, b=2))) ##test_integer64_plus_nanoduration <- function() { expect_identical(as.integer64(hour) + as.nanoduration("1:00:00"), as.nanoduration("2:00:00")) ##test_nanoduration_plus_integer64 <- function() { expect_identical(as.nanoduration("1:00:00") + as.integer64(hour), as.nanoduration("2:00:00")) ##test_nanoduration_plus_numeric <- function() { expect_identical(as.nanoduration("1:00:00") + hour, as.nanoduration("2:00:00")) ##test_numeric_plus_nanoduration <- function() { expect_identical(hour + as.nanoduration("1:00:00"), as.nanoduration("2:00:00")) ##test_character_plus_nanoduration <- function() { expect_error("hello" + as.nanoduration("1:00:00"), "invalid operand types") ##test_any_plus_nanoduration <- function() { expect_error("a" + as.nanoduration("1:00:00"), "invalid operand types") ##test_nanoduration_plus_any <- function() { expect_error(as.nanoduration("1:00:00") + "a", "invalid operand types") ## * ##test_nanoduration_times_numeric <- function() { expect_identical(as.nanoduration("00:01:00") * 3, as.nanoduration("00:03:00")) ##test_numeric_times_nanoduration <- function() { expect_identical(3 * as.nanoduration("00:01:00"), as.nanoduration("00:03:00")) ##test_nanoduration_times_integer64 <- function() { expect_identical(as.nanoduration("00:01:00") * as.integer64(3), as.nanoduration("00:03:00")) ##test_nanoduration_times_nanoduration <- function() { expect_error(as.nanoduration(1) * as.nanoduration(2), "invalid operand types") ## LLL have to fix this, dependent also on 'integer64' fixes... ## ##test_numeric_times_nanoduration <- function() { ## expect_identical(1.5 * as.nanoduration("00:01:00"), as.nanoduration("00:01:30")) ## ##test_numeric_times_nanoduration <- function() { expect_identical(3 * as.nanoduration("00:01:00"), as.nanoduration("00:03:00")) ##test_integer64_times_nanoduration <- function() { expect_identical(as.integer64(3) * as.nanoduration("00:01:00"), as.nanoduration("00:03:00")) ##test_any_times_nanoduration <- function() { expect_error("hello" * as.nanoduration("00:01:00"), "invalid operand types") ##test_nanoduration_times_character <- function() { expect_error(as.nanoduration("00:01:00") * "hello", "invalid operand types") ## / ##test_nanoduration_div_numeric <- function() { expect_identical(as.nanoduration("00:03:00") / 3, as.nanoduration("00:01:00")) ##test_nanoduration_div_integer64 <- function() { expect_identical(as.nanoduration("00:03:00") / as.integer64(3), as.nanoduration("00:01:00")) ##test_nanoduration_div_integer <- function() { expect_identical(as.nanoduration("00:03:00") / as.integer(3), as.nanoduration("00:01:00")) ##test_numeric_div_nanoduration <- function() { expect_error(1.5 / as.nanoduration("00:01:00"), "invalid operand types") ##test_nanoduration_div_any <- function() { expect_error(as.nanoduration("1:00:00") / "a", "invalid operand types") ##test_nanoduration_div_nanoduration <- function() { expect_identical(as.nanoduration(6) / as.nanoduration(2), 3.0) ##test_nanoduration_div_nanoduration <- function() { expect_identical(as.nanoduration(7) / as.nanoduration(2), 3.5) ## unary ##test_unary_minus <- function() { expect_identical(-as.nanoduration("00:01:00"), as.nanoduration("-00:01:00")) ##test_unary_plus <- function() { expect_identical(+as.nanoduration("00:01:00"), as.nanoduration("00:01:00")) ## Summary ##test_sum <- function() { ## error in underlying bit64: LLL ## expect_identical(sum(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3)), ## as.nanoduration(6)) expect_identical(sum(c(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3))), as.nanoduration(6)) ##test_min <- function() { ## error in underlying bit64: LLL ## expect_identical(min(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3)), ## as.nanoduration(1)) expect_identical(min(c(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3))), as.nanoduration(1)) ##test_max <- function() { ## error in underlying bit64: LLL ## expect_identical(max(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3)), ## as.nanoduration(3)) expect_identical(max(c(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3))), as.nanoduration(3)) ##test_range <- function() { ## error in underlying bit64: LLL ## expect_identical(range(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3)), ## c(as.nanoduration(1), as.nanoduration(3))) expect_identical(range(c(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3))), c(as.nanoduration(1), as.nanoduration(3))) ##test_prod <- function() { expect_error(prod(c(as.nanoduration(1), as.nanoduration(2), as.nanoduration(3))), "invalid 'type' \\(nanoduration\\) of argument") ## Complex ##test_Complex <- function() { expect_error(Arg(as.nanoduration(1)), "non-numeric argument to function") ## Logic ##test_Logic <- function() { expect_error(as.nanoduration(1) | as.nanoduration(1), "operations are possible only for numeric, logical or complex types") expect_error(as.nanoduration(1) | "a", "operations are possible only for numeric, logical or complex types") expect_error("a" & as.nanoduration(1), "operations are possible only for numeric, logical or complex types") ## Math ##test_abs <- function() { expect_identical(abs(as.nanoduration(-1)), as.nanoduration(1)) ##test_sign <- function() { expect_identical(sign(as.nanoduration(-1)), as.integer64(-1)) expect_identical(sign(as.nanoduration(1)), as.integer64(1)) ##test_Math <- function() { expect_error(sqrt(as.nanoduration(1)), "non-numeric argument to mathematical function") ## Math2 ##test_Math2 <- function() { expect_error(round(as.nanoduration(1)), "non-numeric argument to mathematical function") ## Compare ##test_Compare_nanoduration_ANY <- function() { expect_error(as.nanoduration(1) < "a", "cannot parse nanoduration") ## not quite clear in R: ## > 1 < list(1) ## [1] FALSE ## > 1 > list(1) ## [1] FALSE ## > 1 == list(1) ## [1] TRUE ##test_Compare_ANY_nanoduration <- function() { expect_error("a" < as.nanoduration(1), "cannot parse nanoduration") ##test_Compare_character_nanoduration <- function() { expect_true("12:13:14.151617" == as.nanoduration("12:13:14.151617")) expect_false("12:13:14.151617" == as.nanoduration("12:13:14.151617001")) expect_true("12:13:14.151617" != as.nanoduration("12:13:14.151617001")) expect_false("12:13:14.151617" != as.nanoduration("12:13:14.151617")) expect_true("12:13:14.151617" < as.nanoduration("12:13:14.151617001")) expect_false("12:13:14.151617001" < as.nanoduration("12:13:14.151617")) expect_true("12:13:14.151617" <= as.nanoduration("12:13:14.151617")) expect_false("12:13:14.151617001" <= as.nanoduration("12:13:14.151617")) expect_true("12:13:14.151617001" > as.nanoduration("12:13:14.151617")) expect_false("12:13:14.151617" > as.nanoduration("12:13:14.151617001")) expect_true("12:13:14.151617" >= as.nanoduration("12:13:14.151617")) expect_false("12:13:14.151617" >= as.nanoduration("12:13:14.151617001")) ##test_Compare_nanoduration_character <- function() { expect_true(as.nanoduration("12:13:14.151617") == "12:13:14.151617") expect_false(as.nanoduration("12:13:14.151617") == "12:13:14.151617001") expect_true(as.nanoduration("12:13:14.151617") != "12:13:14.151617001") expect_false(as.nanoduration("12:13:14.151617") != "12:13:14.151617") expect_true(as.nanoduration("12:13:14.151617") < "12:13:14.151617001") expect_false(as.nanoduration("12:13:14.151617001") < "12:13:14.151617") expect_true(as.nanoduration("12:13:14.151617") <= "12:13:14.151617") expect_false(as.nanoduration("12:13:14.151617001") <= "12:13:14.151617") expect_true(as.nanoduration("12:13:14.151617001") > "12:13:14.151617") expect_false(as.nanoduration("12:13:14.151617") > "12:13:14.151617001") expect_true(as.nanoduration("12:13:14.151617") >= "12:13:14.151617") expect_false(as.nanoduration("12:13:14.151617") >= "12:13:14.151617001") ## Arith ##test_Arith <- function() { expect_identical(as.nanoduration(4) %% 3, as.integer64(1)) ## NA stuff expect_true(is.na(as.nanoduration(as.integer(NA)))) expect_true(is.na(as.nanoduration(as.integer(NaN)))) d <- as.nanoduration(1:10) is.na(d) <- 1:3 expect_true(all(is.na(d[1:3]))) expect_true(!any(is.na(d[4:10]))) expect_true(is.na(NA_nanoduration_)) expect_identical(is.na(c(a=NA_nanoduration_)), c(a=TRUE)) ## test S4 conversions: expect_identical(nanoduration(1,1,1,1), as("01:01:01.000_000_001", "nanoduration")) expect_identical(as.nanoduration(as.integer64(hour)), as(hour, "nanoduration")) expect_identical(as.nanoduration(hour), as(hour, "nanoduration")) ## test seq: expect_identical(seq(as.nanoduration("00:00:00"), by=as.nanoduration("00:00:01"), length.out=10), as.nanoduration(seq(0, by=1e9, length.out=10))) expect_identical(seq(as.nanoduration("00:00:00"), to=as.nanoduration("00:00:09"), length.out=10), as.nanoduration(seq(0, by=1e9, length.out=10))) expect_identical(seq(as.nanoduration("00:00:00"), to=as.nanoduration("00:00:09"), along.with=1:10), as.nanoduration(seq(0, by=1e9, along.with=1:10))) ## all.equal ##test_all.equal_nanotime_any <- function() { expect_true(!isTRUE(all.equal(nanotime(1), "a"))) ##test_all.equal_any_nanotime <- function() { expect_true(!isTRUE(all.equal("a", nanotime(1)))) ## all.equal expect_true(isTRUE(all.equal(as.nanoduration(1), as.nanoduration(1)))) expect_true(!isTRUE(all.equal(as.nanoduration(1), as.nanoduration(2)))) expect_identical(all.equal(as.nanoduration(1), as.nanoduration(2)), "Mean relative difference: 1") expect_identical(all.equal(as.nanoduration(c(1L,NA)), as.nanoduration(1:2)), "'is.NA' value mismatch: 0 in current 1 in target") expect_error(all.equal(as.nanoduration(1), as.nanoduration(1), tolerance="1"), "'tolerance' should be numeric") expect_error(all.equal(as.nanoduration(1), as.nanoduration(1), scale="a"), "'scale' should be numeric or NULL") expect_error(all.equal(as.nanoduration(1), as.nanoduration(1), check.attributes="a"), "'check.attributes' must be logical") expect_error(all.equal(as.nanoduration(1), as.nanoduration(2), scale=-1), "all\\(scale > 0\\) is not TRUE") expect_false(isTRUE(all.equal(as.nanoduration(1), as.nanoperiod("1d")))) expect_identical(all.equal(as.nanoduration(1), as.nanoduration(1:2)), "Numeric: lengths (1, 2) differ") expect_identical(all.equal(as.nanoduration(c(1,2,3)), as.nanoduration(c(1,1,2)), countEQ=TRUE), "Mean relative difference: 0.3333333") expect_false(isTRUE(all.equal(as.nanoduration(1), 1i))) expect_identical(all.equal(as.nanoduration(1), as.nanoduration(3), tolerance=1), "Mean absolute difference: 2") expect_identical(all.equal(as.nanoduration(1), as.nanoduration(2e9), scale=1e9), "Mean scaled difference: 2") expect_identical(all.equal(as.nanoduration(1), as.nanoduration(2e9), scale=1), "Mean absolute difference: 2e+09") ## test rounding functions: ## nano_ceiling: ## hours: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 UTC"), as.nanoduration("06:00:00")), as.nanotime("2010-10-10T12:00:00+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 UTC"), as.nanoduration("01:00:00")), as.nanotime("2010-10-10T12:00:00+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("06:00:00")), as.nanotime("2010-10-10T18:00:00+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("07:00:00")), as.nanotime("2010-10-10T19:00:00+00:00")) expect_identical(nano_floor(as.nanotime("1940-12-12 00:12:23 UTC"), as.nanoduration("01:00:00")), as.nanotime("1940-12-12T00:00:00+00:00")) expect_identical(nano_ceiling(as.nanotime("1970-01-01 UTC"), as.nanoduration("06:00:00")), as.nanotime("1970-01-01T00:00:00+00:00")) expect_identical(nano_ceiling(as.nanotime("1970-01-01 UTC"), as.nanoduration("01:30:00")), as.nanotime("1970-01-01T00:00:00+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("07:00:00"), origin = as.nanotime("2010-10-10 10:23:12 UTC")), as.nanotime("2010-10-10T17:23:12+00:00")) expect_error(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("07:00:00"), origin = as.nanotime(1:10)), "'origin' must be scalar") expect_error(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("-06:00:00")), "'precision' must be strictly positive") expect_error(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("-06:00:00"), origin="wrong type"), "'origin' must be of class 'nanotime'") ## minutes: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:05:00")), as.nanotime("2010-10-10T12:25:00+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:01:00")), as.nanotime("2010-10-10T12:24:00+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:07:00"), origin = as.nanotime("2010-10-10 12:22:12 UTC")), as.nanotime("2010-10-10T12:29:12+00:00")) ## seconds: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:00:05")), as.nanotime("2010-10-10T12:23:25+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123 UTC"), as.nanoduration("00:00:01")), as.nanotime("2010-10-10T12:23:24+00:00")) ## milliseconds expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.001")), as.nanotime("2010-10-10T12:23:23.124+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.010")), as.nanotime("2010-10-10T12:23:23.13+00:00")) ## microseconds expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000001")), as.nanotime("2010-10-10T12:23:23.123457+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000010")), as.nanotime("2010-10-10T12:23:23.12346+00:00")) ## nanoseconds expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000000001")), as.nanotime("2010-10-10T12:23:23.123456789+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000000010")), as.nanotime("2010-10-10T12:23:23.123456790+00:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000000033")), as.nanotime("2010-10-10T12:23:23.123456814+00:00")) ## nano_floor ## hours: expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("06:00:00")), as.nanotime("2010-10-10T12:00:00+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("07:00:00")), as.nanotime("2010-10-10T12:00:00+00:00")) expect_identical(nano_floor(as.nanotime("1970-01-01 UTC"), as.nanoduration("06:00:00")), as.nanotime("1970-01-01T00:00:00+00:00")) expect_identical(nano_floor(as.nanotime("1970-01-01 UTC"), as.nanoduration("01:30:00")), as.nanotime("1970-01-01T00:00:00+00:00")) expect_identical(nano_floor(as.nanotime("1970-01-01 06:00:00 UTC"), as.nanoduration("06:00:00")), as.nanotime("1970-01-01T06:00:00+00:00")) expect_identical(nano_floor(as.nanotime("1970-01-01 07:00:00 UTC"), as.nanoduration("07:00:00")), as.nanotime("1970-01-01T07:00:00+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("07:00:00"), origin = as.nanotime("2010-10-10 10:23:12 UTC")), as.nanotime("2010-10-10T10:23:12+00:00")) expect_error(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("07:00:00"), origin = as.nanotime(1:10)), "'origin' must be scalar") expect_error(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("-06:00:00")), "'precision' must be strictly positive") expect_error(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("-06:00:00"), origin="wrong type"), "'origin' must be of class 'nanotime'") ## minutes: expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:05:00")), as.nanotime("2010-10-10T12:20:00+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:01:00")), as.nanotime("2010-10-10T12:23:00+00:00")) ## seconds: expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoduration("00:00:05")), as.nanotime("2010-10-10T12:23:20+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123 UTC"), as.nanoduration("00:00:01")), as.nanotime("2010-10-10T12:23:23+00:00")) ## milliseconds expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.001")), as.nanotime("2010-10-10T12:23:23.123+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.010")), as.nanotime("2010-10-10T12:23:23.12+00:00")) ## microseconds expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000001")), as.nanotime("2010-10-10T12:23:23.123456+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000010")), as.nanotime("2010-10-10T12:23:23.12345+00:00")) ## nanoseconds expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000000001")), as.nanotime("2010-10-10T12:23:23.123456789+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000000010")), as.nanotime("2010-10-10T12:23:23.12345678+00:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 UTC"), as.nanoduration("00:00:00.000000033")), as.nanotime("2010-10-10T12:23:23.123456781+00:00")) ## rep expect_identical(rep(as.nanoduration(1), 2), as.nanoduration(rep(1,2))) expect_identical(rep(as.nanoduration(1:2), each=2), as.nanoduration(rep(1:2, each=2))) ## difftime expect_identical(as.nanoduration(as.difftime(2, units = "secs")), nanoduration(seconds = 2)) expect_identical(as.nanoduration(as.difftime(2.5, units = "secs")), nanoduration(seconds = 2, nanoseconds = 5e8)) expect_identical(as.nanoduration(as.difftime(2, units = "hours")), nanoduration(hours = 2)) dt_1sec <- as.difftime(1, units = "secs") nd_1sec <- nanoduration(seconds = 1L) expect_identical(dt_1sec + nd_1sec, nanoduration(seconds = 2L)) expect_identical(nd_1sec + dt_1sec, nanoduration(seconds = 2L)) expect_identical(dt_1sec - nd_1sec, nanoduration(seconds = 0L)) expect_identical(nd_1sec - dt_1sec, nanoduration(seconds = 0L)) nt <- as.nanotime("2010-10-10 12:23:23.123456789 UTC") expect_identical(nt + dt_1sec, as.nanotime("2010-10-10 12:23:24.123456789 UTC")) expect_identical(dt_1sec + nt, as.nanotime("2010-10-10 12:23:24.123456789 UTC")) expect_identical(nt - dt_1sec, as.nanotime("2010-10-10 12:23:22.123456789 UTC")) expect_identical(nd_1sec + nt, as.nanotime("2010-10-10 12:23:24.123456789 UTC")) savedFormat <- options()$nanotimeFormat options(nanotimeFormat="%Y-%m-%d %H:%M:%S") ni <- as.nanoival("+2013-01-04 15:00:00 -> 2013-01-04 17:00:00-") expect_identical(ni + dt_1sec, as.nanoival("+2013-01-04 15:00:01 -> 2013-01-04 17:00:01-")) expect_identical(dt_1sec + ni, as.nanoival("+2013-01-04 15:00:01 -> 2013-01-04 17:00:01-")) expect_identical(nd_1sec + ni, as.nanoival("+2013-01-04 15:00:01 -> 2013-01-04 17:00:01-")) expect_identical(ni - dt_1sec, as.nanoival("+2013-01-04 14:59:59 -> 2013-01-04 16:59:59-")) expect_identical(ni - nd_1sec, as.nanoival("+2013-01-04 14:59:59 -> 2013-01-04 16:59:59-")) options(nanotimeFormat=savedFormat) nanotime/inst/tinytest/test_data.table.R0000644000176200001440000001033013713516255020112 0ustar liggesuserslibrary(nanotime) if (!requireNamespace("data.table", quietly=TRUE)) exit_file("Package 'data.table' missing") library(data.table) ## nanotime ##test_nanotime_data_table_constructor <- function() { ## simpler data.table, inserts 'formatted' set.seed(42) N <- 300 shine <- nanotime(Sys.time()) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- nanotime(Sys.time()) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) newdf <- data.table(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanotime_data_table_rbind <- function() { t1 <- nanotime(1:10) d1 <- 1:10 t2 <- nanotime(11:20) d2 <- 11:20 df1 <- data.table(t = t1, d = d1) df2 <- data.table(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.table(t = c(t1, t2), d = c(d1, d2))) ##test_nanotime_data_table_cbind <- function() { t1 <- nanotime(1:10) d1 <- 1:10 t2 <- nanotime(11:20) d2 <- 11:20 df1 <- data.table(t1 = t1, d1 = d1) df2 <- data.table(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.table(t1 = t1, d1 = d1, t2=t2, d2=d2)) ## nanoduration ##test_nanoduration_data_table_constructor <- function() { ## simpler data.table, inserts 'formatted' set.seed(42) N <- 300 shine <- as.nanoduration(1000) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- as.nanoduration(2000) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) newdf <- data.table(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanoduration_data_table_rbind <- function() { t1 <- as.nanoduration(1:10) d1 <- 1:10 t2 <- as.nanoduration(11:20) d2 <- 11:20 df1 <- data.table(t = t1, d = d1) df2 <- data.table(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.table(t = c(t1, t2), d = c(d1, d2))) ##test_nanoduration_data_table_cbind <- function() { t1 <- as.nanoduration(1:10) d1 <- 1:10 t2 <- as.nanoduration(11:20) d2 <- 11:20 df1 <- data.table(t1 = t1, d1 = d1) df2 <- data.table(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.table(t1 = t1, d1 = d1, t2=t2, d2=d2)) ## nanoperiod ##test_nanoperiod_data.table_constructor <- function() { ## simpler data.table, inserts 'formatted' set.seed(42) N <- 300 shine <- as.nanoperiod(1000) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- as.nanoperiod(2000) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) newdf <- data.table(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanoperiod_data_table_rbind <- function() { t1 <- as.nanoperiod(1:10) d1 <- 1:10 t2 <- as.nanoperiod(11:20) d2 <- 11:20 df1 <- data.table(t = t1, d = d1) df2 <- data.table(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.table(t = c(t1, t2), d = c(d1, d2))) ##test_nanoperiod_data_table_cbind <- function() { t1 <- as.nanoperiod(1:10) d1 <- 1:10 t2 <- as.nanoperiod(11:20) d2 <- 11:20 df1 <- data.table(t1 = t1, d1 = d1) df2 <- data.table(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.table(t1 = t1, d1 = d1, t2=t2, d2=d2)) ## nanoival ##test_nanoival_data.table_constructor <- function() { ## simpler data.table, inserts 'formatted' set.seed(42) N <- 300 shine_start <- nanotime(1000) + cumsum(10*rpois(n=N+1, lambda=4)) shine_end <- shine_start + as.nanoduration("01:00:00") rain_start <- nanotime(2000) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) rain_end <- shine_end + as.nanoduration("02:00:00") shine <- nanoival(shine_start, shine_end) rain <- nanoival(rain_start, rain_end) newdf <- data.table(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanoival_data_table_rbind <- function() { t1 <- nanoival(nanotime(1:10), nanotime(2:11)) d1 <- 1:10 t2 <- nanoival(nanotime(11:20), nanotime(12:21)) d2 <- 11:20 df1 <- data.table(t = t1, d = d1) df2 <- data.table(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.table(t = c(t1, t2), d = c(d1, d2))) ##test_nanoival_data_table_cbind <- function() { t1 <- nanoival(nanotime(1:10), nanotime(2:11)) d1 <- 1:10 t2 <- nanoival(nanotime(11:20), nanotime(12:21)) d2 <- 11:20 df1 <- data.table(t1 = t1, d1 = d1) df2 <- data.table(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.table(t1 = t1, d1 = d1, t2=t2, d2=d2)) nanotime/inst/tinytest/test_data.frame.R0000644000176200001440000001014213713516331020111 0ustar liggesuserslibrary(nanotime) ## nanotime ##test_nanotime_data_frame_constructor <- function() { ## simpler data.frame, inserts 'formatted' set.seed(42) N <- 300 shine <- nanotime(Sys.time()) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- nanotime(Sys.time()) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) newdf <- data.frame(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanotime_data_frame_rbind <- function() { t1 <- nanotime(1:10) d1 <- 1:10 t2 <- nanotime(11:20) d2 <- 11:20 df1 <- data.frame(t = t1, d = d1) df2 <- data.frame(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.frame(t = c(t1, t2), d = c(d1, d2))) ##test_nanotime_data_frame_cbind <- function() { t1 <- nanotime(1:10) d1 <- 1:10 t2 <- nanotime(11:20) d2 <- 11:20 df1 <- data.frame(t1 = t1, d1 = d1) df2 <- data.frame(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.frame(t1 = t1, d1 = d1, t2=t2, d2=d2)) ## nanoduration ##test_nanoduration_data_frame_constructor <- function() { ## simpler data.frame, inserts 'formatted' set.seed(42) N <- 300 shine <- as.nanoduration(1000) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- as.nanoduration(2000) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) newdf <- data.frame(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanoduration_data_frame_rbind <- function() { t1 <- as.nanoduration(1:10) d1 <- 1:10 t2 <- as.nanoduration(11:20) d2 <- 11:20 df1 <- data.frame(t = t1, d = d1) df2 <- data.frame(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.frame(t = c(t1, t2), d = c(d1, d2))) ##test_nanoduration_data_frame_cbind <- function() { t1 <- as.nanoduration(1:10) d1 <- 1:10 t2 <- as.nanoduration(11:20) d2 <- 11:20 df1 <- data.frame(t1 = t1, d1 = d1) df2 <- data.frame(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.frame(t1 = t1, d1 = d1, t2=t2, d2=d2)) ## nanoperiod ##test_nanoperiod_data.frame_constructor <- function() { ## simpler data.frame, inserts 'formatted' set.seed(42) N <- 300 shine <- as.nanoperiod(1000) + cumsum(10*rpois(n=N+1, lambda=4)) rain <- as.nanoperiod(2000) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) newdf <- data.frame(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanoperiod_data_frame_rbind <- function() { t1 <- as.nanoperiod(1:10) d1 <- 1:10 t2 <- as.nanoperiod(11:20) d2 <- 11:20 df1 <- data.frame(t = t1, d = d1) df2 <- data.frame(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.frame(t = c(t1, t2), d = c(d1, d2))) ##test_nanoperiod_data_frame_cbind <- function() { t1 <- as.nanoperiod(1:10) d1 <- 1:10 t2 <- as.nanoperiod(11:20) d2 <- 11:20 df1 <- data.frame(t1 = t1, d1 = d1) df2 <- data.frame(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.frame(t1 = t1, d1 = d1, t2=t2, d2=d2)) ## nanoival ##test_nanoival_data.frame_constructor <- function() { ## simpler data.frame, inserts 'formatted' set.seed(42) N <- 300 shine_start <- nanotime(1000) + cumsum(10*rpois(n=N+1, lambda=4)) shine_end <- shine_start + as.nanoduration("01:00:00") rain_start <- nanotime(2000) + cumsum(10*rpois(n=N+1, lambda=4) + round(runif(N+1)*25)) rain_end <- shine_end + as.nanoduration("02:00:00") shine <- nanoival(shine_start, shine_end) rain <- nanoival(rain_start, rain_end) newdf <- data.frame(rain=rain, shine=shine) expect_identical(newdf$rain, rain) expect_identical(newdf$shine, shine) ##test_nanoival_data_frame_rbind <- function() { t1 <- nanoival(nanotime(1:10), nanotime(2:11)) d1 <- 1:10 t2 <- nanoival(nanotime(11:20), nanotime(12:21)) d2 <- 11:20 df1 <- data.frame(t = t1, d = d1) df2 <- data.frame(t = t2, d = d2) df <- rbind(df1, df2) expect_identical(df, data.frame(t = c(t1, t2), d = c(d1, d2))) ##test_nanoival_data_frame_cbind <- function() { t1 <- nanoival(nanotime(1:10), nanotime(2:11)) d1 <- 1:10 t2 <- nanoival(nanotime(11:20), nanotime(12:21)) d2 <- 11:20 df1 <- data.frame(t1 = t1, d1 = d1) df2 <- data.frame(t2 = t2, d2 = d2) df <- cbind(df1, df2) expect_identical(df, data.frame(t1 = t1, d1 = d1, t2=t2, d2=d2)) nanotime/inst/tinytest/test_nanoperiod.R0000644000176200001440000013117114635571205020260 0ustar liggesusers suppressMessages({ library(nanotime) library(bit64) }) ## constructors ##test_as.nanoperiod_character <- function() { p1 <- as.nanoperiod("1m1d") expect_identical(nanoperiod.day(p1), 1) expect_identical(nanoperiod.month(p1), 1) expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(0)) expect_identical(as.nanoperiod("1y"), as.nanoperiod("12m")) expect_identical(as.nanoperiod("2y"), as.nanoperiod("24m")) expect_identical(as.nanoperiod("1w"), as.nanoperiod("7d")) expect_identical(as.nanoperiod("2w"), as.nanoperiod("14d")) p2 <- as.nanoperiod("2m1d/00:01:01.1") expect_identical(nanoperiod.month(p2), 2) expect_identical(nanoperiod.day(p2), 1) expect_identical(nanoperiod.nanoduration(p2), as.nanoduration("00:01:01.1")) p3 <- as.nanoperiod(c("1d","2d","3d")) expect_identical(nanoperiod.day(p3[1]), 1) expect_identical(nanoperiod.day(p3[2]), 2) expect_identical(nanoperiod.day(p3[3]), 3) expect_identical(nanoperiod(), as.nanoperiod(NULL)) expect_identical(nanoperiod(), as.nanoperiod()) expect_identical(length(nanoperiod()), 0L) expect_identical(length(as.nanoperiod(NULL)), 0L) ## check year and week expect_identical(as.character(as.nanoperiod("1y/00:01:01")), "12m0d/00:01:01") expect_identical(as.character(as.nanoperiod("1w/00:01:01")), "0m7d/00:01:01") expect_identical(names(as.nanoperiod(c(a="1m"))), "a") ## check negative duration expect_identical(as.nanoperiod("-00:00:01"), as.nanoperiod(as.nanoduration("-00:00:01"))) expect_identical(as.nanoperiod("-0:00:01"), as.nanoperiod(as.nanoduration("-00:00:01"))) ##test_as.nanoperiod_character_error <- function() { expect_error(as.nanoperiod("1wm00:01:01"), "cannot parse nanoperiod") expect_error(as.nanoperiod("1ym00:01:01"), "cannot parse nanoperiod") expect_error(as.nanoperiod("1dm00:01:01"), "cannot parse nanoperiod") ##test_as.nanoperiod_integer64 <- function() { p1 <- as.nanoperiod(as.integer64(1:10)) expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(1:10)) p1 <- as.nanoperiod(c(a=as.integer64(1))) expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(c(a=1))) ##test_as.nanoperiod_integer <- function() { p1 <- as.nanoperiod(1:10) expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(1:10)) p1 <- as.nanoperiod(c(a=1L)) expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(c(a=1))) ##test_as.nanoperiod_numeric <- function() { p1 <- as.nanoperiod(as.numeric(1:10)) expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(1:10)) p1 <- as.nanoperiod(c(a=1)) expect_identical(nanoperiod.nanoduration(p1), c(a=as.nanoduration(1))) ##test_as.nanoperiod_nanoduration <- function() { p1 <- as.nanoperiod(c(a=as.nanoduration(1))) expect_identical(p1, c(a=as.nanoperiod("00:00:00.000_000_001"))) ##test_nanoperiod <- function() { expect_identical(nanoperiod(0,0,1), as.nanoperiod(1)) expect_identical(nanoperiod(0,0,1:10), as.nanoperiod(1:10)) expect_identical(nanoperiod(1,1,0:9), as.nanoperiod(paste0("1m1d/00:00:00.000_000_00", 0:9))) expect_error(nanoperiod("a"), "argument 'months' must be numeric") expect_error(nanoperiod(1, "a"), "argument 'days' must be numeric") ## accessors: ##test_nanoperiod.day <- function() { p1 <- as.nanoperiod(paste0(1:10, "d")) names(p1) <- 1:10 expected <- as.numeric(1:10) names(expected) <- 1:10 expect_identical(nanoperiod.day(p1), expected) ##test_nanoperiod.month <- function() { p1 <- as.nanoperiod(paste0(1:10, "m")) names(p1) <- 1:10 expected <- as.numeric(1:10) names(expected) <- 1:10 expect_identical(nanoperiod.month(p1), expected) ##test_nanoperiod.nanoduration <- function() { p1 <- as.nanoperiod(1:10) names(p1) <- 1:10 expected <- as.numeric(1:10) names(expected) <- 1:10 expect_identical(nanoperiod.nanoduration(p1), as.nanoduration(expected)) ## show/print/as.character/format ##test_show <- function() { p1 <- format(as.nanoperiod("1m1d/1:00:00.1")) expect_identical(p1, "1m1d/01:00:00.100") expect_stdout(show(as.nanoperiod("1m1d/1:00:00.1"))) ##test_print <- function() { p1 <- format(as.nanoperiod("2m2d/2:02:02.2")) expect_identical(p1, "2m2d/02:02:02.200") expect_stdout(print(nanoperiod())) ##test_as.character <- function() { p1 <- as.character(as.nanoperiod("2m2d/2:02:02.20001")) expect_identical(p1, "2m2d/02:02:02.200_010") expect_identical(as.character(NA_nanoperiod_), NA_character_) ##test_as.character_named <- function() { p1 <- as.character(c(a=as.nanoperiod("2m2d/2:02:02.20001"), b=as.nanoperiod("2m2d/2:02:02.20002"))) expect_identical(p1, c(a="2m2d/02:02:02.200_010", b="2m2d/02:02:02.200_020")) ##test_format <- function() { p1 <- as.nanoperiod("2m2d/2:02:02.20001") expect_identical(format(p1), "2m2d/02:02:02.200_010") expect_identical(as.character(p1), "2m2d/02:02:02.200_010") ## subset: ##test_subset_int <- function() { p1 <- as.nanoperiod("1m1d/00:00:01") p2 <- as.nanoperiod("2m2d/00:00:02") p3 <- as.nanoperiod("3m3d/00:00:03") p4 <- as.nanoperiod("4m4d/00:00:04") pp <- c(p1, p2, p3, p4) expect_identical(pp[1], p1) expect_identical(pp[2], p2) expect_identical(pp[3], p3) expect_identical(pp[4], p4) expect_identical(pp[1:4], pp) expect_identical(pp[2:3], c(p2,p3)) expect_identical(pp[-1:-2], c(p3,p4)) expect_warning(pp[1, 2], "unused indices or arguments in 'nanoperiod' subsetting") ##test_subset_logical <- function() { p1 <- as.nanoperiod("1m1d/00:00:01") p2 <- as.nanoperiod("2m2d/00:00:02") p3 <- as.nanoperiod("3m3d/00:00:03") p4 <- as.nanoperiod("4m4d/00:00:04") pp <- c(p1, p2, p3, p4) expect_identical(pp[c(T,F,F,F)], p1) expect_identical(pp[c(F,T,F,F)], p2) expect_identical(pp[c(F,F,T,F)], p3) expect_identical(pp[c(F,F,F,T)], p4) expect_identical(pp[TRUE], pp) expect_identical(pp[c(F,T,T,F)], c(p2,p3)) expect_identical(pp[c(NA, F, F, F)], as.nanoperiod(NA_integer_)) expect_identical(pp[c(NA, F, F, F)], NA_nanoperiod_) expect_warning(pp[T, F], "unused indices or arguments in 'nanoperiod' subsetting") ##test_subset_character <- function() { pp <- c(x=as.nanoperiod(1), y=as.nanoperiod(2)) expect_identical(pp["x"], c(x=as.nanoperiod(1))) expect_identical(pp["y"], c(y=as.nanoperiod(2))) res <- NA_nanoperiod_ names(res) <- NA_character_ expect_identical(pp["a"], res) expect_warning(pp["a", "b"], "unused indices or arguments in 'nanoperiod' subsetting") ## test subset incorrect type expect_error(pp[as.integer64(1)], "']' not defined on 'nanoperiod' for index of type 'ANY'") ## subassign ##test_subassign_logical <- function() { x <- as.nanoperiod(1:10) x[c(T,T,T,F,F,F,F,F,F,F)] <- as.nanoperiod(2:4) expect_identical(x, as.nanoperiod(c(2:4, 4:10))) x <- as.nanoperiod(paste0(1:10, "d")) x[c(T,T,T,F,F,F,F,F,F,F)] <- as.nanoperiod(paste0(2:4, "d")) expect_identical(x, as.nanoperiod(paste0(c(2:4, 4:10), "d"))) ##test_subassign_numeric <- function() { x <- as.nanoperiod(1:10) x[1:3] <- as.nanoperiod(2:4) x[4:10] <- as.nanoperiod(5:11) expect_identical(x, as.nanoperiod(2:11)) x <- as.nanoperiod(paste0(1:10, "d")) x[1:3] <- as.nanoperiod(paste0(2:4, "d")) x[4:10] <- as.nanoperiod(paste0(5:11, "d")) expect_identical(x, as.nanoperiod(paste0(2:11, "d"))) ##test_subsassign_character <- function() { pp <- c(a=as.nanoperiod(1), b=as.nanoperiod(2), c=as.nanoperiod(3), d=as.nanoperiod(4)) pp[c("b", "c")] <- as.nanoperiod(20:21) expected <- c(a=as.nanoperiod(1), b=as.nanoperiod(20), c=as.nanoperiod(21), d=as.nanoperiod(4)) expect_identical(pp, expected) ##test_square_bracket <- function() { pp <- c(a=as.nanoperiod(1), b=as.nanoperiod(2), c=as.nanoperiod(3), d=as.nanoperiod(4)) pp_nonames <- as.nanoperiod(1:4) expect_identical(pp_nonames[1], pp[[1]]) expect_identical(pp_nonames[2], pp[[2]]) expect_identical(pp_nonames[3], pp[[3]]) ## ops ## - ##test_nanoperiod_minus_nanoperiod <- function() { expect_identical(-as.nanoperiod("2m2d/00:00:02"), as.nanoperiod("-2m-2d/-00:00:02")) expect_identical(as.nanoperiod("2m2d") - as.nanoperiod("1m1d"), as.nanoperiod("1m1d")) expect_identical(as.nanoperiod("-1m-1d/-00:00:01") - as.nanoperiod("1m1d/00:00:01"), as.nanoperiod("-2m-2d/-00:00:02")) ##test_nanoperiod_minus_nanoperiod_vector <- function() { expect_identical(as.nanoperiod("1d") - as.nanoperiod(paste0(1:10, "d")), as.nanoperiod(paste0(0:-9,"d"))) expect_identical(as.nanoperiod(paste0(1:10, "d")) - as.nanoperiod("1d"), as.nanoperiod(paste0(0:9,"d"))) expect_identical(as.nanoperiod(paste0(1:10, "d")) - as.nanoperiod(paste0(0:9, "d")), as.nanoperiod(paste0(rep(1,10),"d"))) ##test_nanoperiod_minus_numeric <- function() { expect_identical(as.nanoperiod("2m2d") - 1, as.nanoperiod("2m2d/-00:00:00.000_000_001")) expect_identical(as.nanoperiod(paste0(1:10,"m2d")) - 1, as.nanoperiod(paste0(1:10, "m2d/-00:00:00.000_000_001"))) expect_identical(as.nanoperiod("12m2d") - 1:9.0, as.nanoperiod(paste0("12m2d/-00:00:00.000_000_00", 1:9))) ##test_nanoperiod_minus_nanoduration <- function() { expect_identical(as.nanoperiod("2m2d") - as.nanoduration(1), as.nanoperiod("2m2d/-00:00:00.000_000_001")) expect_identical(as.nanoperiod(paste0(1:10,"m2d")) - as.nanoduration(1), as.nanoperiod(paste0(1:10, "m2d/-00:00:00.000_000_001"))) expect_identical(as.nanoperiod("12m2d") - as.nanoduration(1:9), as.nanoperiod(paste0("12m2d/-00:00:00.000_000_00", 1:9))) ##test_nanoperiod_minus_integer <- function() { expect_identical(as.nanoperiod("2m2d") - as.integer(1), as.nanoperiod("2m2d/-00:00:00.000_000_001")) expect_identical(as.nanoperiod(paste0(1:10,"m2d")) - as.integer(1), as.nanoperiod(paste0(1:10, "m2d/-00:00:00.000_000_001"))) expect_identical(as.nanoperiod("12m2d") - as.integer(1:9), as.nanoperiod(paste0("12m2d/-00:00:00.000_000_00", 1:9))) ##test_nanoperiod_minus_integer64 <- function() { expect_identical(as.nanoperiod("2m2d") - as.integer64(1), as.nanoperiod("2m2d/-00:00:00.000_000_001")) expect_identical(as.nanoperiod(paste0(1:10,"m2d")) - as.integer64(1), as.nanoperiod(paste0(1:10, "m2d/-00:00:00.000_000_001"))) expect_identical(as.nanoperiod("12m2d") - as.integer64(1:9), as.nanoperiod(paste0("12m2d/-00:00:00.000_000_00", 1:9))) ##test_numeric_minus_nanoperiod <- function() { expect_identical(1 - as.nanoperiod("1m1d"), as.nanoperiod("-1m-1d/00:00:00.000_000_001")) expect_identical(1:10 - as.nanoperiod("1m1d"), nanoperiod(-1,-1,1:10)) expect_identical(1 - nanoperiod(1:10,1,1), nanoperiod(-1:-10, -1, 0)) ##test_integer64_minus_nanoperiod <- function() { expect_identical(as.integer64(1) - as.nanoperiod("1m1d"), as.nanoperiod("-1m-1d/00:00:00.000_000_001")) expect_identical(as.integer64(1:10) - as.nanoperiod("1m1d"), nanoperiod(-1,-1,1:10)) expect_identical(as.integer64(1) - nanoperiod(1:10,1,1), nanoperiod(-1:-10, -1, 0)) ##test_nanoduration_minus_nanoperiod <- function() { expect_identical(as.nanoduration(1) - as.nanoperiod("1m1d"), as.nanoperiod("-1m-1d/00:00:00.000_000_001")) expect_identical(as.nanoduration(1:10) - as.nanoperiod("1m1d"), nanoperiod(-1,-1,1:10)) expect_identical(as.nanoduration(1) - nanoperiod(1:10,1,1), nanoperiod(-1:-10, -1, 0)) ##test_nanoperiod_minus_any <- function() { expect_error(as.nanoperiod(1) - "a", "invalid operand types") ##test_any_minus_nanoperiod <- function() { expect_error("a" - as.nanoperiod(1), "invalid operand types") expect_error(as.nanoperiod(1) - nanotime(1), "invalid operand types") ## + ##test_nanoperiod_plus_nanoperiod <- function() { expect_identical(+as.nanoperiod("2m"), as.nanoperiod("2m")) expect_identical(as.nanoperiod("2m2d") + as.nanoperiod("1m1d"), as.nanoperiod("3m3d")) expect_identical(as.nanoperiod("-1m-1d/00:00:01") + as.nanoperiod("1m1d/00:00:01"), as.nanoperiod("0m0d/00:00:02")) expect_identical(nanoperiod(1,1,1:10) + nanoperiod(1,1,0), nanoperiod(2,2,1:10)) expect_identical(nanoperiod(1,1,0) + nanoperiod(1,1,1:10), nanoperiod(2,2,1:10)) ##test_nanoperiod_plus_nanoperiod_names <- function() { non_scalar <- as.nanoperiod(c(a="2m2d", b="3m3d")) scalar <- as.nanoperiod(c(c="1m1d")) expected <- as.nanoperiod(c(a="3m3d", b="4m4d")) expect_identical(non_scalar + scalar, expected) expect_identical(scalar + non_scalar, expected) ##test_integer64_plus_nanoperiod <- function() { expect_identical(as.integer64(1) + as.nanoperiod(1), as.nanoperiod(2)) expect_identical(as.integer64(0:9) + as.nanoperiod(1), as.nanoperiod(1:10)) expect_identical(as.integer64(1) + nanoperiod(1:10,1,0), nanoperiod(1:10,1,1)) ##test_nanoperiod_plus_integer64 <- function() { expect_identical(as.nanoperiod(1) + as.integer64(1), as.nanoperiod(2)) expect_identical(as.nanoperiod("2m2d") + as.integer64(1), as.nanoperiod("2m2d/00:00:00.000_000_001")) expect_identical(as.nanoperiod(1) + as.integer64(0:9), as.nanoperiod(1:10)) expect_identical(nanoperiod(1:10,1,0) + as.integer64(1), nanoperiod(1:10,1,1)) ##test_nanoperiod_plus_nanoduration <- function() { expect_identical(as.nanoperiod(1) + as.nanoduration(1), as.nanoperiod(2)) expect_identical(as.nanoperiod("2m2d") + as.nanoduration(1), as.nanoperiod("2m2d/00:00:00.000_000_001")) expect_identical(as.nanoperiod(1) + as.nanoduration(0:9), as.nanoperiod(1:10)) expect_identical(nanoperiod(1:10,1,0) + as.nanoduration(1), nanoperiod(1:10,1,1)) ##test_nanoduration_plus_nanoperiod <- function() { expect_identical(as.nanoduration(1) + as.nanoperiod(1), as.nanoperiod(2)) expect_identical(as.nanoduration(1) + as.nanoperiod("2m2d"), as.nanoperiod("2m2d/00:00:00.000_000_001")) expect_identical(as.nanoduration(0:9) + as.nanoperiod(1), as.nanoperiod(1:10)) expect_identical(as.nanoduration(1) + nanoperiod(1:10,1,0), nanoperiod(1:10,1,1)) ##test_numeric_plus_nanoperiod <- function() { expect_identical(as.nanoperiod(1) + 1, as.nanoperiod(2)) expect_identical(as.nanoperiod("2m2d") + 1, as.nanoperiod("2m2d/00:00:00.000_000_001")) expect_identical(0.0:9.0 + as.nanoperiod(1), as.nanoperiod(1:10)) expect_identical(1.0 + nanoperiod(1:10,1,0), nanoperiod(1:10,1,1)) ##test_any_plus_nanoperiod <- function() { expect_error("a" + as.nanoperiod(1), "invalid operand types") ##test_nanoperiod_plus_any <- function() { expect_error(as.nanoperiod(1) + any, "invalid operand types") ## * ##test_nanoperiod_times_numeric <- function() { expect_identical(as.nanoperiod(1) * 3, as.nanoperiod(3)) expect_identical(as.nanoperiod("1m1d") * 3, as.nanoperiod("3m3d")) expect_identical(nanoperiod(1,1,1) * 1:10, nanoperiod(1:10,1:10,1:10)) expect_identical(nanoperiod(1:10,1,1) * 3, nanoperiod(1:10 * 3, 3, 3)) ##test_nanoperiod_times_integer64 <- function() { expect_identical(as.nanoperiod(1) * as.integer64(3), as.nanoperiod(3)) expect_identical(nanoperiod(1,1,1) * as.integer64(1:10), nanoperiod(1:10,1:10,1:10)) expect_identical(nanoperiod(1:10,1,1) * as.integer64(3), nanoperiod(1:10 * 3, 3, 3)) ##test_numeric_times_nanoperiod <- function() { expect_identical(3 * as.nanoperiod(1), as.nanoperiod(3)) expect_identical(4.5 * as.nanoperiod("10d"), as.nanoperiod("45d")) expect_identical(1:10.0 * as.nanoperiod(1), as.nanoperiod(1:10)) expect_identical(1 * as.nanoperiod(1:10), as.nanoperiod(1:10)) ##test_integer64_times_nanoperiod <- function() { expect_identical(as.integer64(3) * as.nanoperiod(1), as.nanoperiod(3)) expect_identical(as.integer64(3) * as.nanoperiod("1m1d"), as.nanoperiod("3m3d")) expect_identical(as.integer64(1:10) * as.nanoperiod(1), as.nanoperiod(1:10)) expect_identical(as.integer64(1) * as.nanoperiod(1:10), as.nanoperiod(1:10)) ##test_character_times_nanoperiod <- function() { expect_error("a" * as.nanoperiod(1), "invalid operand types") expect_error("123" * as.nanoperiod(1), "invalid operand types") ##test_nanoperiod_times_character <- function() { expect_error(as.nanoperiod(1) * "a", "invalid operand types") expect_error(as.nanoperiod(1) * "123", "invalid operand types") ## / ##test_nanoperiod_div_numeric <- function() { expect_identical(as.nanoperiod(4) / 3, as.nanoperiod(1)) expect_identical(as.nanoperiod("5m5d") / 2.5, as.nanoperiod("2m2d")) expect_identical(as.nanoperiod(4) / c(4,2,1), as.nanoperiod(c(1,2,4))) expect_identical(as.nanoperiod(4:2) / c(4,2,1), as.nanoperiod(c(1,1,2))) expect_error(as.nanoperiod("2m") / 0, "divide by zero") ##test_nanoperiod_div_integer64 <- function() { expect_identical(as.nanoperiod(4) / as.integer64(3), as.nanoperiod(1)) expect_identical(as.nanoperiod("5m5d") / as.integer64(2), as.nanoperiod("2m2d")) expect_identical(as.nanoperiod(4) / as.integer64(c(4,2,1)), as.nanoperiod(c(1,2,4))) expect_identical(as.nanoperiod(4:2) / as.integer64(c(4,2,1)), as.nanoperiod(c(1,1,2))) ##test_nanoperiod_div_integer <- function() { expect_identical(as.nanoperiod(4) / as.integer(3), as.nanoperiod(1)) expect_identical(as.nanoperiod("5m5d") / as.integer(2), as.nanoperiod("2m2d")) expect_identical(as.nanoperiod(4) / as.integer(c(4,2,1)), as.nanoperiod(c(1,2,4))) expect_identical(as.nanoperiod(4:2) / as.integer(c(4,2,1)), as.nanoperiod(c(1,1,2))) ##test_nanoperiod_div_any <- function() { expect_error(as.nanoperiod(1) / "a", "invalid operand types") ##test_any_div_nanoperiod <- function() { expect_error("a" / as.nanoperiod(1), "invalid operand types") ##test_Logic_nanoperiod_any <- function() { expect_error(as.nanoperiod(1) | "a", "operation not defined for 'nanoperiod' objects") ##test_Logic_any_nanoperiod <- function() { expect_error("a" | as.nanoperiod(1), "operation not defined for 'nanoperiod' objects") ## Math/Math2/Summary/Complex ##test_nanoperiod_Math <- function() { ## is that right? LLL expect_error(abs(as.nanoperiod(1)), "operation not defined for 'nanoperiod' objects") ##test_nanoperiod_Math2 <- function() { expect_error(round(as.nanoperiod(1)), "operation not defined for 'nanoperiod' objects") ##test_nanoperiod_Summary <- function() { expect_error(min(as.nanoperiod(1)), "invalid 'type' \\(nanoperiod\\) of argument") expect_error(max(as.nanoperiod(1)), "invalid 'type' \\(nanoperiod\\) of argument") ##test_nanoperiod_Complex <- function() { expect_error(Arg(as.nanoperiod(1)), "operation not defined for 'nanoperiod' objects") ##test_binary_plus_nanoperiod_nanotime <- function() { expect_error(as.nanoperiod(1) + nanotime(1), "binary '\\+' is not defined for 'nanoperiod' and 'nanotime' objects; instead use 'plus\\(e1, e2, tz\\)'") ##test_binary_plus_nanotime_nanoperiod <- function() { expect_error(nanotime(1) + as.nanoperiod(1), "binary '\\+' is not defined for 'nanotime' and 'nanoperiod' objects; instead use 'plus\\(e1, e2, tz\\)'") ##test_binary_plus_nanoperiod_nanoival <- function() { expect_error(as.nanoperiod(1) + nanoival(nanotime(1), nanotime(2)), "binary '\\+' is not defined for 'nanoperiod' and 'nanoival' objects; instead use 'plus\\(e1, e2, tz\\)'") ##test_binary_plus_nanoival_nanoperiod <- function() { expect_error(nanoival(nanotime(1), nanotime(2)) + as.nanoperiod(1), "binary '\\+' is not defined for 'nanoival' and 'nanoperiod' objects; instead use 'plus\\(e1, e2, tz\\)'") ## Compare ## ---------- ##test_nanoperiod_eq_nanoperiod <- function() { expect_true(as.nanoperiod(1) == as.nanoperiod(1)) expect_true(as.nanoperiod("1d") == as.nanoperiod("1d")) expect_true(!(as.nanoperiod(1) == as.nanoperiod(2))) expect_identical(as.nanoperiod(1:10) == as.nanoperiod(1:10), rep(TRUE, 10)) ##test_nanoperiod_ne_nanoperiod <- function() { expect_true(as.nanoperiod(1) != as.nanoperiod(2)) expect_true(as.nanoperiod("1d") != as.nanoperiod("2d")) expect_true(!(as.nanoperiod(1) != as.nanoperiod(1))) expect_identical(as.nanoperiod(1:10) != as.nanoperiod(1:10), rep(FALSE, 10)) ##test_nanoperiod_eq_any <- function() { expect_error(as.nanoperiod(1) == "a", "operation not defined for 'nanoperiod' objects") ##test_any_eq_nanoperiod <- function() { expect_error("a" == as.nanoperiod(1), "operation not defined for 'nanoperiod' objects") ##test_all.equal <- function() { expect_true(all.equal(as.nanoperiod(1), as.nanoperiod(1))) expect_true(all.equal(as.nanoperiod(1:10), as.nanoperiod(1:10))) expect_true(all.equal(as.nanoperiod("1m1d"), as.nanoperiod("1d") + as.nanoperiod("1m"))) ## names (in general) ##test_nanoperiod_get_names <- function() { a <- as.nanoperiod(1:10) names(a) <- "b" expect_identical(names(a), c("b", rep(as.character(NA), 9))) ##test_nanoperiod_set_names <- function() { names <- c("a","b","c","d") pp <- as.nanoperiod(1:4) names(pp) <- names expect_identical(names(pp), names) names(pp)[1] <- "x" expect_identical(names(pp), c("x","b","c","d")) ##test_nanoperiod_c <- function() { pp <- c(x=as.nanoperiod(1), y=as.nanoperiod(2)) expect_identical(names(pp), c("x","y")) expect_identical(pp[1], c(x=as.nanoperiod(1))) expect_identical(pp[2], c(y=as.nanoperiod(2))) pp <- c(as.nanoperiod(1:10), as.nanoperiod(11:20)) expect_identical(pp, as.nanoperiod(1:20)) ## plus/minus with 'nanotime': ##test_plus_nanotime_nanoperiod <- function() { nt <- nanotime("2018-01-01T05:00:00.000000000+00") p <- c(p=as.nanoperiod("4m")) tz <- "America/New_York" expected <- c(p=nanotime("2018-05-01T00:00:00.000000000-04:00")) expect_identical(plus(nt, p, tz), expected) ##test_plus_nanotime_nanoperiod_vector1 <- function() { nt <- nanotime("2018-01-01T05:00:00.000000000+00") + 1:10 p <- as.nanoperiod("4m") tz <- "America/New_York" expected <- nanotime("2018-05-01T00:00:00.000000000-04:00") + 1:10 expect_identical(plus(nt, p, tz), expected) ##test_plus_nanotime_nanoperiod_vector2 <- function() { nt <- nanotime("2018-01-01T05:00:00.000000000+00") p <- as.nanoperiod("4m") + 1:10 tz <- "America/New_York" expected <- nanotime("2018-05-01T00:00:00.000000000-04:00") + 1:10 expect_identical(plus(nt, p, tz), expected) ##test_plus_nanotime_nanoperiod_vector3 <- function() { nt <- nanotime("2018-01-01T05:00:00.000000000+00") p <- as.nanoperiod("4m") + 1:10 tz <- rep("America/New_York", 10) expected <- nanotime("2018-05-01T00:00:00.000000000-04:00") + 1:10 expect_identical(plus(nt, p, tz), expected) ##test_plus_nanoperiod_nanotime <- function() { nt <- nanotime("2018-01-01T05:00:00.000000000+00") p <- c(p=as.nanoperiod("4m")) tz <- "America/New_York" expected <- c(p=nanotime("2018-05-01T00:00:00.000000000-04:00")) expect_identical(plus(p, nt, tz), expected) ##test_minus_nanotime_nanoperiod <- function() { nt <- c(p1=nanotime("2018-05-01T00:00:00.000000000-04:00")) p <- c(p2=as.nanoperiod("4m")) tz <- "America/New_York" expected <- c(p1=nanotime("2018-01-01T00:00:00.000000000-05:00")) expect_identical(minus(nt, p, tz), expected) ##test_minus_nanoperiod_nanotime <- function() { nt <- nanotime("2018-05-01T00:00:00.000000000-04:00") p <- as.nanoperiod("4m") tz <- "America/New_York" expect_error(minus(p, nt, tz), "operation not defined for 'nanoperiod' objects") ## test the crossing of daylight saving time in both directions: ## adding/subtracting a nanoperiod should not realign if doing so ## crosses again a DST boundary: ## look at cases over the Spring boundary in America: nt <- as.nanotime("2020-03-08 01:45:30 America/New_York") p <- as.nanoperiod("00:30:00") tz <- "America/New_York" expected <- as.nanotime("2020-03-08 03:15:30 America/New_York") expect_identical(plus(nt, p, tz), expected) nt <- as.nanotime("2020-03-08 01:00:00 America/New_York") p <- as.nanoperiod("01:00:00") tz <- "America/New_York" expected <- as.nanotime("2020-03-08 03:00:00 America/New_York") expect_identical(plus(nt, p, tz), expected) nt <- as.nanotime("2020-03-08 03:15:30 America/New_York") p <- as.nanoperiod("00:30:00") tz <- "America/New_York" expected <- as.nanotime("2020-03-08 01:45:30 America/New_York") expect_identical(minus(nt, p, tz), expected) nt <- as.nanotime("2020-03-08 03:00:00 America/New_York") p <- as.nanoperiod("01:00:00") tz <- "America/New_York" expected <- as.nanotime("2020-03-08 01:00:00 America/New_York") expect_identical(minus(nt, p, tz), expected) ## look at the cases over the Autumn boundary in America: nt <- as.nanotime("2020-11-01 01:45:30 America/New_York") p <- as.nanoperiod("00:30:00") tz <- "America/New_York" expected <- as.nanotime("2020-11-01 02:15:30 America/New_York") expect_identical(plus(nt, p, tz), expected) nt <- as.nanotime("2020-11-01 01:00:00 America/New_York") p <- as.nanoperiod("01:00:00") tz <- "America/New_York" expected <- as.nanotime("2020-11-01 02:00:00 America/New_York") expect_identical(plus(nt, p, tz), expected) nt <- as.nanotime("2020-11-01 02:15:30 America/New_York") p <- as.nanoperiod("00:30:00") tz <- "America/New_York" ##expected <- as.nanotime("2020-11-01 01:45:30 America/New_York") # ambiguous expected <- as.nanotime("2020-11-01 06:45:30+00:00") expect_identical(minus(nt, p, tz), expected) nt <- as.nanotime("2020-11-01 02:00:00 America/New_York") p <- as.nanoperiod("01:00:00") tz <- "America/New_York" ## expected <- as.nanotime("2020-11-01 01:00:00 America/New_York") # ambiguous expected <- as.nanotime("2020-11-01 06:00:00+00:00") expect_identical(minus(nt, p, tz), expected) ## adding/subtracting a nanoperiod should realign if doing so does ## not cross again a DST boundary: ## look at cases over the Spring boundary in America: nt <- as.nanotime("2020-03-08 01:00:00 America/New_York") p <- as.nanoperiod("02:00:01") tz <- "America/New_York" expected <- as.nanotime("2020-03-08 03:00:01 America/New_York") expect_identical(plus(nt, p, tz), expected) nt <- as.nanotime("2020-03-08 03:00:00 America/New_York") p <- as.nanoperiod("02:00:01") tz <- "America/New_York" expected <- as.nanotime("2020-03-08 00:59:59 America/New_York") expect_identical(minus(nt, p, tz), expected) ## look at the cases over the Autumn boundary in America: nt <- as.nanotime("2020-11-01 01:00:00 America/New_York") p <- as.nanoperiod("02:00:01") tz <- "America/New_York" expected <- as.nanotime("2020-11-01 03:00:01 America/New_York") expect_identical(plus(nt, p, tz), expected) nt <- as.nanotime("2020-11-01 03:00:00 America/New_York") p <- as.nanoperiod("02:00:01") tz <- "America/New_York" expected <- as.nanotime("2020-11-01 00:59:59 America/New_York") expect_identical(minus(nt, p, tz), expected) ## plus/minus with 'nanoival': ##test_plus_nanoival_nanoperiod <- function() { start <- nanotime("2018-01-01T05:00:00.000000000+00") end <- nanotime("2018-01-01T23:00:00.000000000+00") ni <- nanoival(start, end) p <- as.nanoperiod("4m") tz <- "America/New_York" expected <- as.nanoival("+2018-05-01T00:00:00.000000000-04:00 -> 2018-05-01T18:00:00.000000000-04:00-") expect_identical(plus(ni, p, tz), expected) ##test_plus_nanoival_nanoperiod_pre_1970 <- function() { start <- nanotime("1969-01-01T05:00:00.000000000+00") end <- nanotime("1969-01-01T23:00:00.000000000+00") ni <- nanoival(start, end) p <- as.nanoperiod("4m") tz <- "America/New_York" expected <- as.nanoival("+1969-05-01T00:00:00.000000000-04:00 -> 1969-05-01T18:00:00.000000000-04:00-") expect_identical(plus(ni, p, tz), expected) ##test_plus_nanoperiod_nanoival <- function() { start <- nanotime("2018-01-01T05:00:00.000000000+00") end <- nanotime("2018-01-01T23:00:00.000000000+00") ni <- nanoival(start, end) p <- c(a=as.nanoperiod("4m")) tz <- "America/New_York" expected <- c(a=as.nanoival("+2018-05-01T00:00:00.000000000-04:00 -> 2018-05-01T18:00:00.000000000-04:00-")) expect_identical(plus(p, ni, tz), expected) ##test_minus_nanoival_nanoperiod <- function() { start <- nanotime("2018-05-01T05:00:00.000000000-04") end <- nanotime("2018-05-01T23:00:00.000000000-04") ni <- c(a=nanoival(start, end)) p <- as.nanoperiod("4m") tz <- "America/New_York" expected <- c(a=as.nanoival("+2018-01-01T05:00:00.000000000-05:00 -> 2018-01-01T23:00:00.000000000-05:00-")) expect_identical(minus(ni, p, tz), expected) ##test_minus_nanoperiod_nanoival <- function() { start <- nanotime("2018-05-01T05:00:00.000000000-04") end <- nanotime("2018-05-01T23:00:00.000000000-04") ni <- nanoival(start, end) p <- as.nanoperiod("4m") tz <- "America/New_York" expect_error(minus(p, ni, tz), "operation not defined for 'nanoperiod' objects") ## NA stuff expect_true(is.na(as.nanoperiod(NA_integer_))) expect_true(is.na(as.nanoperiod(NA_integer64_))) expect_true(is.na(as.nanoperiod(NA_real_))) expect_true(is.na(as.nanoperiod(as.integer(NaN)))) p <- as.nanoperiod(1:10) is.na(p) <- 1:3 expect_true(all(is.na(p[1:3]))) expect_true(!any(is.na(p[4:10]))) expect_true(is.na(NA_nanoperiod_)) expect_true(is.na(nanoperiod.nanoduration(NA_nanoperiod_))) expect_true(is.na(nanoperiod.month(NA_nanoperiod_))) expect_true(is.na(nanoperiod.day(NA_nanoperiod_))) ## test S4 conversions: expect_identical(nanoperiod(1,1,1), as("1m1d/00:00:00.000_000_001", "nanoperiod")) hour <- 3600*1e9 expect_identical(as.nanoperiod(as.integer64(hour)), as(hour, "nanoperiod")) expect_identical(as.nanoperiod(hour), as(hour, "nanoperiod")) expect_identical(as.nanoperiod(hour), as(as.nanoduration(hour), "nanoperiod")) ## 0-length ops: ## ------------ ## constructor: expect_identical(nanoperiod(integer(), integer(), nanoduration()), nanoperiod()) expect_identical(nanoperiod(1, 1, nanoduration()), nanoperiod()) expect_identical(nanoperiod(1,integer(), as.nanoduration(1)), nanoperiod()) expect_identical(nanoperiod(numeric(), integer(), as.nanoduration(1)), nanoperiod()) ## Comp: expect_identical(as.nanoperiod() == as.nanoperiod(), logical()) expect_identical(as.nanoperiod(1) == as.nanoperiod(), logical()) expect_identical(as.nanoperiod(1) != as.nanoperiod(), logical()) ## ops expect_identical(as.nanoperiod() + as.nanoperiod(), as.nanoperiod()) expect_identical(nanoperiod(1) + as.nanoperiod(), as.nanoperiod()) expect_identical(nanoperiod() + as.nanoperiod(1:10), as.nanoperiod()) expect_identical(nanoperiod() + as.nanoduration(1:10), as.nanoperiod()) expect_identical(nanoperiod() + as.integer64(1:10), as.nanoperiod()) expect_identical(nanoperiod(1) + as.integer(), as.nanoperiod()) expect_identical(as.nanoperiod() - as.nanoperiod(), as.nanoperiod()) expect_identical(nanoperiod(1) - as.nanoperiod(), as.nanoperiod()) expect_identical(nanoperiod() - as.nanoperiod(1:10), as.nanoperiod()) expect_identical(nanoperiod() * 3, as.nanoperiod()) expect_identical(nanoperiod(1) * integer(), as.nanoperiod()) ## accessors expect_identical(nanoperiod.month(nanoperiod()), numeric()) expect_identical(nanoperiod.day(nanoperiod()), numeric()) expect_identical(nanoperiod.nanoduration(nanoperiod()), as.nanoduration()) ## all.equal: expect_identical(all.equal(as.nanoperiod("1m"), as.nanoperiod("1m")), TRUE) expect_false(isTRUE(all.equal(as.nanoperiod("1d"), "A"))) expect_identical(all.equal(as.nanoperiod("1d"), NA_nanoperiod_), "'is.NA' value mismatch: 1 in current 0 in target") ## test rounding functions: ## nano_ceiling: ## years: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), tz="America/New_York"), as.nanotime("2011-01-01T00:00:00-05:00")) expect_identical(nano_ceiling(as.nanotime("1970-01-01 America/New_York"), as.nanoperiod("12m"), tz="America/New_York"), as.nanotime("1970-01-01 America/New_York")) expect_identical(nano_ceiling(as.nanotime("1970-01-01 06:00:00 America/New_York"), as.nanoperiod("12m"), tz="America/New_York"), as.nanotime("1971-01-01 America/New_York")) expect_error(nano_ceiling(c(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanotime("2010-10-10 11:00:00 America/New_York")), as.nanoperiod("12m"), tz="America/New_York"), "'x' must be sorted") expect_error(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), tz=c("America/New_York", "UTC")), "'tz' must be scalar") expect_identical(nano_ceiling(as.nanotime("1940-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), tz="America/New_York"), as.nanotime("1941-01-01T00:00:00-05:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime("2010-10-10 00:00:01 America/New_York"), tz="America/New_York"), as.nanotime("2011-10-10T04:00:01+00:00")) expect_error(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime(1:10), tz="America/New_York"), "'origin' must be scalar") expect_identical(nano_ceiling(as.nanotime("1904-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime("1904-10-10 00:00:01 America/New_York"), tz="America/New_York"), as.nanotime("1905-10-10T05:00:01+00:00")) expect_error(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime("2004-10-10 00:00:01 America/New_York"), tz="America/New_York"), "when specifying 'origin', the first interval must contain at least one observation") expect_error(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoperiod("-12m"), tz="America/New_York"), "'precision' must be strictly positive") expect_error(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoperiod("-12m"), tz="America/New_York", origin="wrong type"), "'origin' must be of class 'nanotime'") expect_error(nano_ceiling(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoperiod("-12m"), tz=12), "'tz' must be of type 'character'") ## months: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("13m"), tz="America/New_York"), as.nanotime("2011-11-01T00:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-08-10 12:00:00 America/New_York"), as.nanoperiod("3m"), tz="America/New_York"), as.nanotime("2010-10-01T00:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-08-10 12:00:00 America/New_York"), as.nanoperiod("1m"), tz="America/New_York"), as.nanotime("2010-09-01T00:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("1940-08-10 12:00:00 America/New_York"), as.nanoperiod("1m"), tz="America/New_York"), as.nanotime("1940-09-01T00:00:00-04:00")) ## days: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("1d"), tz="America/New_York"), as.nanotime("2010-10-11T00:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("2d"), tz="America/New_York"), as.nanotime("2010-10-12T00:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("1940-10-10 12:00:00 America/New_York"), as.nanoperiod("2d"), tz="America/New_York"), as.nanotime("1940-10-12T00:00:00-05:00")) ## hours: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("06:00:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("1927-10-10 12:00:00 America/New_York"), as.nanoperiod("06:00:00"), tz="America/New_York"), as.nanotime("1927-10-10T12:00:00-05:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("01:00:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("06:00:00"), tz="America/New_York"), as.nanotime("2010-10-10T18:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("07:00:00"), tz="America/New_York"), as.nanotime("2010-10-10T19:00:00-04:00")) expect_identical(nano_ceiling(as.nanotime("1899-10-10 12:23:23 America/New_York"), as.nanoperiod("07:00:00"), tz="America/New_York"), as.nanotime("1899-10-10T19:00:00-05:00")) ## minutes: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("00:05:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:25:00-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:25:00 America/New_York"), as.nanoperiod("00:05:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:25:00-04:00")) expect_identical(nano_ceiling(as.nanotime("1922-10-10 12:23:23 America/New_York"), as.nanoperiod("00:05:00"), tz="America/New_York"), as.nanotime("1922-10-10T12:25:00-05:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("00:01:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:24:00-04:00")) expect_identical(nano_ceiling(as.nanotime("1922-10-10 12:25:00 America/New_York"), as.nanoperiod("00:05:00"), tz="America/New_York"), as.nanotime("1922-10-10T12:25:00-05:00")) ## seconds: expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("00:00:05"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:25-04:00")) expect_identical(nano_ceiling(as.nanotime("1969-10-10 12:23:23 America/New_York"), as.nanoperiod("00:00:05"), tz="America/New_York"), as.nanotime("1969-10-10T12:23:25-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123 America/New_York"), as.nanoperiod("00:00:01"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:24-04:00")) expect_identical(nano_ceiling(as.nanotime("1888-10-10 12:23:23.123 America/New_York"), as.nanoperiod("00:00:11"), tz="America/New_York"), as.nanotime("1888-10-10T12:23:34-05:00")) ## milliseconds expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.001"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.124-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.010"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.13-04:00")) ## microseconds expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000001"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123457-04:00")) expect_identical(nano_ceiling(as.nanotime("1933-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000001"), tz="America/New_York"), as.nanotime("1933-10-10T12:23:23.123457-05:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000010"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.12346-04:00")) ## nanoseconds expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000001"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123456789-04:00")) expect_identical(nano_ceiling(as.nanotime("1931-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000001"), tz="America/New_York"), as.nanotime("1931-10-10T12:23:23.123456789-05:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000010"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123456790-04:00")) expect_identical(nano_ceiling(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000033"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123456789-04:00")) ## nano_floor ## years: expect_identical(nano_floor(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), tz="America/New_York"), as.nanotime("2010-01-01T05:00:00-00:00")) expect_identical(nano_floor(as.nanotime("1970-01-01 06:00:00 America/New_York"), as.nanoperiod("12m"), tz="America/New_York"), as.nanotime("1970-01-01 America/New_York")) expect_error(nano_floor(c(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanotime("2010-10-10 11:00:00 America/New_York")), as.nanoperiod("12m"), tz="America/New_York"), "'x' must be sorted") expect_error(nano_floor(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), tz=c("America/New_York", "UTC")), "'tz' must be scalar") expect_identical(nano_floor(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime("2010-10-10 00:00:01 America/New_York"), tz="America/New_York"), as.nanotime("2010-10-10T04:00:01+00:00")) expect_error(nano_floor(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime("2004-10-10 00:00:01 America/New_York"), tz="America/New_York"), "when specifying 'origin', the first interval must contain at least one observation") expect_error(nano_floor(as.nanotime("2010-10-10 12:00:00 America/New_York"), as.nanoperiod("12m"), origin=as.nanotime(1:10), tz="America/New_York"), "'origin' must be scalar") expect_error(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoperiod("-12m"), tz="America/New_York"), "'precision' must be strictly positive") expect_error(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoperiod("-12m"), tz="America/New_York", origin="wrong type"), "'origin' must be of class 'nanotime'") expect_error(nano_floor(as.nanotime("2010-10-10 12:23:23 UTC"), as.nanoperiod("-12m"), tz=12), "'tz' must be of type 'character'") ## hours: expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("06:00:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:00:00-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("07:00:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:00:00-04:00")) ## minutes: expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("00:05:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:20:00-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:20:00 America/New_York"), as.nanoperiod("00:05:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:20:00-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("00:01:00"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:00-04:00")) expect_identical(nano_floor(as.nanotime("1911-10-10 12:20:00 America/New_York"), as.nanoperiod("00:01:00"), tz="America/New_York"), as.nanotime("1911-10-10T12:20:00-05:00")) ## seconds: expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23 America/New_York"), as.nanoperiod("00:00:05"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:20-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123 America/New_York"), as.nanoperiod("00:00:01"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23-04:00")) ## milliseconds expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.001"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.010"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.12-04:00")) ## microseconds expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000001"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123456-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000010"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.12345-04:00")) ## nanoseconds expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000001"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123456789-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000010"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.12345678-04:00")) expect_identical(nano_floor(as.nanotime("2010-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000033"), tz="America/New_York"), as.nanotime("2010-10-10T12:23:23.123456789-04:00")) expect_identical(nano_floor(as.nanotime("1965-10-10 12:23:23.123456789 America/New_York"), as.nanoperiod("00:00:00.000000033"), tz="America/New_York"), as.nanotime("1965-10-10T12:23:23.123456789-04:00")) ## rep expect_identical(rep(as.nanoperiod(1), 2), as.nanoperiod(rep(1,2))) expect_identical(rep(as.nanoperiod(1:2), each=2), as.nanoperiod(rep(1:2, each=2))) nanotime/inst/NEWS.Rd0000644000176200001440000002114014740324147014110 0ustar liggesusers\name{NEWS} \title{News for Package \pkg{nanotime}} \newcommand{\ghpr}{\href{https://github.com/eddelbuettel/nanotime/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/eddelbuettel/nanotime/issues/#1}{##1}} \section{Changes in version 0.3.11 (2025-01-10)}{ \itemize{ \item Explicit \code{Rcomplex} assignment accommodates pickier compilers over newer R struct (Michael Chirico in \ghpr{135} fixing \ghit{134}) \item When formatting, \code{NA} are flagged before \code{CCTZ} call to to not trigger santizier, and set to NA after call (Dirk in \ghpr{136}) } } \section{Changes in version 0.3.10 (2024-09-16)}{ \itemize{ \item Retire several checks for Solaris in test suite (Dirk in \ghpr{130}) \item Switch to Authors@R in DESCRIPTION as now required by CRAN \item Accommodate R-devel change for setdiff (Dirk in \ghpr{133} fixing \ghit{132}) \item No longer ship defunction ggplot2 demo (Dirk fixing \ghit{131}) } } \section{Changes in version 0.3.9 (2024-06-21)}{ \itemize{ \item Condition two tests to not run on arm64 (Dirk in \ghpr{129} fixing \ghit{128}) } } \section{Changes in version 0.3.8 (2024-06-19)}{ \itemize{ \item Time format documentation now has a reference to \pkg{RcppCCTZ} \item The package no longer sets a default C++ compilation standard of C++11 (Dirk initially in \ghpr{114}, and later switched to C++17) \item New \code{accurate} parameter for conversion from \code{POSIXct} to \code{nanotime} (Davor Josipovic and Leonardo in \ghpr{116} closing \ghit{115}) \item The \code{as.Date()} function is now vectorized and can take a TZ argument (Leonardo and Dirk in \ghpr{119} closing \ghit{118}) \item Use of internal function \code{SET_S4_OBJECT} has been replaced by API function \code{Rf_asS4} (Leonardo in \ghpr{121} closing \ghit{120}) \item An \code{nanoduration} / \code{nanoduration} expression now returns a double (Leonardo in \ghpr{122} closing \ghit{117}) \item Bitfield calculations no longer require an Windows-only compiler switch (Leonardo in \ghpr{124}) \item A simple manual page format nag involving has been addressed (Dirk in \ghpr{126} fixing \ghit{125}) \item An set of tests tickling an UBSAN issue via \pkg{Rcpp} code no longer run unless \code{CI} is set (Dirk in \ghpr{127} fixing \ghit{123}) } } \section{Changes in version 0.3.7 (2022-10-23)}{ \itemize{ \item Update mkdocs for material docs generator (Dirk in \ghpr{102}) \item Use \code{inherits()} instead comparing to \code{class()} (Trevor Davis in \ghpr{104}) \item Set default arguments in \code{nanoduration()} (Trevor Davis in \ghpr{105}) \item Add \code{as.nanoduration.difftime()} support (Trevor Davis in \ghpr{106}) \item Add +/- methods for \code{nanotime} and \code{difftime} objects (Trevor Davis in \ghpr{110} closing \ghit{108}, \ghit{107}) } } \section{Changes in version 0.3.6 (2022-03-06)}{ \itemize{ \item Fix incorrect subsetting with operator \code{\%in\%} (Leonardo in \ghpr{100} fixing \ghit{99}). \item Fix incorrect parsing for negative nanoperiod (Leonardo in \ghpr{100} fixing \ghit{96}). \item Test for \code{class} via \code{inherits()} (Dirk). } } \section{Changes in version 0.3.5 (2021-12-14)}{ \itemize{ \item Applied patch by Tomas Kalibera for Windows UCRT under the upcoming R 4.2.0 expected for April. } } \section{Changes in version 0.3.4 (2021-11-24)}{ \itemize{ \item Added a few more \code{as.character} conversion function (Dirk) \item Expose \code{nanoperiod} functionality via header file for use by other packages (Leonardo in \ghpr{95} fixing \ghit{94}). } } \section{Changes in version 0.3.3 (2021-08-09)}{ \itemize{ \item New demo \code{ggplot2Example.R} (Leonardo and Dirk). \item New documentation website using mkdocs-material (Dirk). \item Updated unit test to account for r-devel POSIXct changes, and re-enable full testing under r-devel (Dirk). \item Additional \code{nanoduration} and \code{character} ops plus tests (Colin Umansky in \ghpr{88} addressing \ghit{87}). \item New \code{plus} and \code{minus} functions for periods (Leonardo in \ghpr{91}). } } \section{Changes in version 0.3.2 (2020-09-03)}{ \itemize{ \item Correct for big endian (Elliott Sales de Andrade in \ghpr{81}). \item Use the \code{RcppCCTZ_API.h} header (Dirk in \ghpr{82}). \item Conditionally reduce test coverage (Dirk in \ghpr{83}). } } \section{Changes in version 0.3.1 (2020-08-09)}{ \itemize{ \item Several small cleanups to ensure a more robust compilation (Leonardo and Dirk in \ghpr{75} fixing \ghit{74}). \item Show Solaris some extra love by skipping tests and examples with a timezone (Dirk in \ghpr{76}). } } \section{Changes in version 0.3.0 (2020-08-06)}{ \itemize{ \item Use \code{tzstr=} instead of \code{tz=} in call to \pkg{RcppCCTZ::parseDouble()}) (Matt Dowle in \ghpr{49}). \item Add new comparison operators for \code{nanotime} and \code{charcters} (Dirk in \ghpr{54} fixing \ghit{52}). \item Switch from \pkg{RUnit} to \pkg{tinytest} (Dirk in \ghpr{55}) \item Substantial functionality extension in with new types \code{nanoduration}, \code{nanoival} and \code{nanoperiod} (Leonardo in \ghpr{58}, \ghpr{60}, \ghpr{62}, \ghpr{63}, \ghpr{65}, \ghpr{67}, \ghpr{70} fixing \ghit{47}, \ghit{51}, \ghit{57}, \ghit{61}, \ghit{64} with assistance from Dirk). \item A new (yet still draft-ish) vignette was added describing the four core types (Leonardo and Dirk in \ghpr{71}). \item A required compilation flag for Windows was added (Leonardo in \ghpr{72}). \item \pkg{RcppCCTZ} function are called in new 'non-throwing' variants to not trigger exeception errors (Leonardo in \ghpr{73}). } } \section{Changes in version 0.2.4 (2019-05-25)}{ \itemize{ \item Define [[ method (Dirk in \ghpr{45} fixing \ghit{44}). } } \section{Changes in version 0.2.3 (2018-09-30)}{ \itemize{ \item Skip some tests on Solaris which seems borked with timezones. As we have no real access, no real fix possible (Dirk in \ghpr{42}). \item Update Travis setup } } \section{Changes in version 0.2.2 (2018-07-18)}{ \itemize{ \item Unit tests depending on future \CRANpkg{xts} behaviour remain disabled (Dirk in \ghpr{41}). } } \section{Changes in version 0.2.1 (2018-07-01)}{ \itemize{ \item Added attribute-preserving comparison (Leonardo in \ghpr{33}). \item Added two \code{integer64} casts in constructors (Dirk in \ghpr{36}). \item Added two checks for empty arguments (Dirk in \ghpr{37}). } } \section{Changes in version 0.2.0 (2017-06-22)}{ \itemize{ \item Rewritten in S4 to provide more robust operations (\ghpr{17} by Leonardo) \item Ensure \code{tz=""} is treated as unset (Leonardo in \ghpr{20}) \item Added \code{format} and \code{tz} arguments to \code{nanotime}, \code{format}, \code{print} (\ghpr{22} by Leonardo and Dirk) \item Ensure printing respect \code{options()$max.print}, ensure names are kept with vector (\ghpr{23} by Leonardo) \item Correct \code{summary()} by defining \code{names<-} (Leonardo in \ghpr{25} fixing \ghit{24}) \item Report error on operations that are meaningful for type; handled NA, NaN, Inf, -Inf correctly (Leonardo in \ghpr{27} fixing \ghit{26}) } } \section{Changes in version 0.1.2 (2017-03-27)}{ \itemize{ \item The \code{as.integer64} function is now exported as well. } } \section{Changes in version 0.1.1 (2017-02-04)}{ \itemize{ \item The default display format now always shows nine digits (\ghpr{10} closing \ghpr{9}) \item The default print method was updated to use formated output, and a new new converter \code{as.integer64} was added \item Several 'Ops' method are now explicitly defined allowing casting of results (rather than falling back on bit64 behaviour) \item The format routine is now more careful about not loosing precision (\ghit{13} closing \ghit{12}) } } \section{Changes in version 0.1.0 (2017-01-10)}{ \itemize{ \item Added Windows support thanks to expanded \CRANpkg{RcppCCTZ} (closes \ghit{6}) \item Added "mocked up" demo with nanosecond delay networking analysis \item Added 'fmt' and 'tz' options to output functions, expanded \code{format.nanotime} (closing \ghit{2} and \ghit{3}) \item Added data.frame support \item Expanded tests } } \section{Changes in version 0.0.1 (2016-12-15)}{ \itemize{ \item Initial CRAN upload. \item Package is functional and provides examples. } } nanotime/README.md0000644000176200001440000002125114634624322013352 0ustar liggesusers## nanotime: Nanosecond-Resolution Time Objects for R [![CI](https://github.com/eddelbuettel/nanotime/workflows/ci/badge.svg)](https://github.com/eddelbuettel/nanotime/actions?query=workflow%3Aci) [![License](https://eddelbuettel.github.io/badges/GPL2+.svg)](https://www.gnu.org/licenses/gpl-2.0.html) [![CRAN](https://www.r-pkg.org/badges/version/nanotime)](https://cran.r-project.org/package=nanotime) [![r-universe](https://eddelbuettel.r-universe.dev/badges/nanotime)](https://eddelbuettel.r-universe.dev/nanotime) [![Dependencies](https://tinyverse.netlify.app/badge/nanotime)](https://cran.r-project.org/package=nanotime) [![Downloads](https://cranlogs.r-pkg.org/badges/nanotime?color=brightgreen)](https://www.r-pkg.org/pkg/nanotime) [![Code Coverage](https://codecov.io/gh/eddelbuettel/nanotime/graph/badge.svg)](https://app.codecov.io/gh/eddelbuettel/nanotime) [![Last Commit](https://img.shields.io/github/last-commit/eddelbuettel/nanotime)](https://github.com/eddelbuettel/nanotime) [![Documentation](https://img.shields.io/badge/documentation-is_here-blue)](https://eddelbuettel.github.io/nanotime/) ### Motivation R has excellent tools for dates and times. The `Date` and `POSIXct` classes (as well as the 'wide' representation in `POSIXlt`) are versatile, and a lot of useful tooling has been built around them. However, `POSIXct` is implemented as a `double` with fractional seconds since the epoch. Given the 53 bits accuracy, it leaves just a bit less than _microsecond_ resolution. Furthermore, using floating-point arithmetic for an integer concept opens the door to painful issues of error accumulation. More and more performance measurements, latency statistics, etc., are now measured more finely, and we need _nanosecond_ resolution for which commonly an `integer64` is used to represent nanoseconds since the epoch. And while R does not have a _native_ type for this, the [bit64](https://cran.r-project.org/package=bit64) package by [Jens Oehlschlägel](https://github.com/joehl) offers a performant one implemented as a lightweight S3 class. So this package uses the `integer64` class, along with multiple helper functions for parsing and formatting at nano-second resolution from the [RcppCCTZ](https://dirk.eddelbuettel.com/code/rcpp.cctz.html) package which wraps the [CCTZ library](https://github.com/google/cctz) from Google. CCTZ is a modern C++11 library extending the (C++11-native) `chrono` type. In addition to the point-in-time type `nanotime`, this package also provides an interval type `nanoival` which may have open or closed start/end, a period type `nanoperiod` that is a human representation of time, such as day, month, etc., and a duration type `nanoduration`. These types are similar to what the [lubridate](https://github.com/tidyverse/lubridate) package proposes. Set and arithmetic operations on these types are available. All functionality is designed to correctly handle instances across different time zones. Because these temporal types are based on R built-in types, most functions have an efficient implementation and the types are suitable for use in `data.frame` and `data.table`. `nanotime` is also a better choice than the native `POSIXct` in most of the cases where fractional seconds are needed because it avoids floating point issues. ### Documentation Package documentation, help pages, a vignette, and more is available [here](https://eddelbuettel.github.io/nanotime/). ### Demo See the included demo script [nanosecondDelayExample.R](https://github.com/eddelbuettel/nanotime/blob/master/demo/nanosecondDelayExample.R) for a (completely simulated and hence made-up) study of network latency measured in nanoseconds resulting in the figure below ![](https://eddelbuettel.github.io/nanotime/assets/nanotimeDelayDemo.png) ### Examples #### Simple Parsing and Arithmetic ```r R> x <- as.nanotime("1970-01-01T00:00:00.000000001+00:00") R> x [1] "1970-01-01T00:00:00.000000001+00:00" R> x + 1e9 [1] "1970-01-01T00:00:01.000000001+00:00" R> as.nanotime("2020-03-21 Europe/London") [1] 2020-03-21T00:00:00+00:00 ``` #### Vectorised ```r R> options("width"=60) R> v <- nanotime(Sys.time()) + 1:5 R> v [1] 2020-03-22T03:09:20.732122001+00:00 [2] 2020-03-22T03:09:20.732122002+00:00 [3] 2020-03-22T03:09:20.732122003+00:00 [4] 2020-03-22T03:09:20.732122004+00:00 [5] 2020-03-22T03:09:20.732122005+00:00 R> ``` #### Use with `zoo` ```r R> library(zoo) R> z <- zoo(cbind(A=1:5, B=5:1), v) R> options(nanotimeFormat="%H:%M:%E*S") ## override default format R> z R> options(nanotimeFormat=NULL) ## go back to default format R> z ``` #### Use with data.table ```r R> library(data.table) R> dt <- data.table(v, cbind(A=1:5, B=5:1)) R> fwrite(dt, file="datatableTest.csv") # write out R> dtcheck <- fread("datatableTest.csv") # read back R> dtcheck R> dtcheck[, v:=nanotime(v)] # read as a string, need to re-class as nanotime R> fread("../datatableTest.csv", colClasses=c("nanotime", "integer", "integer")) ``` #### Use with data.frame This requires version 0.0.2 or later. ```r R> data.frame(cbind(A=1:5, B=5:1), v=v) ``` #### Intervals ```r R> ival <- as.nanoival("+2009-01-01 13:12:00 America/New_York -> 2009-02-01 15:11:03 America/New_York-") R> ival [1] +2009-01-01T18:12:00+00:00 -> 2009-02-01T20:11:03+00:00- R> start <- nanotime("2009-01-01 13:12:00 America/New_York") R> end <- nanotime("2009-02-01 15:11:00 America/New_York") R> nanoival(start, end) # by default sopen=F,eopen=T [1] +2009-01-01T18:12:00+00:00 -> 2009-02-01T20:11:00+00:00- R> nanoival(start, end, sopen=FALSE, eopen=TRUE) [1] +2009-01-01T18:12:00+00:00 -> 2009-02-01T20:11:00+00:00- R> intersect(as.nanoival("+2019-03-01 UTC -> 2020-03-01 UTC-"), as.nanoival("+2020-01-01 UTC -> 2020-06-01 UTC-")) [1] +2020-01-01T00:00:00+00:00 -> 2020-03-01T00:00:00+00:00- R> union(as.nanoival("+2019-03-01 UTC -> 2020-03-01 UTC-"), as.nanoival("+2020-01-01 UTC -> 2020-06-01 UTC-")) [1] +2019-03-01T00:00:00+00:00 -> 2020-06-01T00:00:00+00:00- R> setdiff(as.nanoival("+2019-03-01 UTC -> 2020-03-01 UTC-"), as.nanoival("+2020-01-01 UTC -> 2020-06-01 UTC-")) [1] +2019-03-01T00:00:00+00:00 -> 2020-01-01T00:00:00+00:00- ``` #### Periods ```r R> as.nanoperiod("1y1m1w1d/01:01:01.000_000_001") [1] 13m8d/01:01:01.000_000_001 R> nanoperiod(months=13, days=-1, duration="01:00:00") [1] 13m-1d/01:00:00 R> ones <- as.nanoperiod("1y1m1w1d/01:01:01.000_000_001") R> nanoperiod.month(ones); nanoperiod.day(ones); nanoperiod.nanoduration(ones) [1] 13 [1] 8 [1] 01:01:01.000_000_001 R> plus(v, as.nanoperiod("1y1m"), tz="UTC") [1] 2021-04-22T03:09:20.732122001+00:00 [2] 2021-04-22T03:09:20.732122002+00:00 [3] 2021-04-22T03:09:20.732122003+00:00 [4] 2021-04-22T03:09:20.732122004+00:00 [5] 2021-04-22T03:09:20.732122005+00:00 ``` #### Durations ```{r} R> nanoduration(hours=1, minutes=1, seconds=1, nanoseconds=1) R> as.nanoduration("00:00:01") R> as.nanoduration("-00:00:01") R> as.nanoduration("100:00:00") R> as.nanoduration("00:00:00.000_000_001") ``` #### Sequences ``` {r} R> from <- as.nanotime("2018-09-14T12:44:00+00:00") R> seq(from, by=as.nanoperiod("1y"), length.out=4, tz="Europe/London") [1] 2018-09-14T12:44:00+00:00 [2] 2019-09-14T12:44:00+00:00 [3] 2020-09-14T12:44:00+00:00 [4] 2021-09-14T12:44:00+00:00 ``` ### Technical Details The [bit64](https://cran.r-project.org/package=bit64) package (by [Jens Oehlschlägel](https://github.com/joehl)) supplies the `integer64` type used to store the nanosecond resolution time as (positive or negative) offsets to the epoch of January 1, 1970. The [RcppCCTZ](https://dirk.eddelbuettel.com/code/rcpp.cctz.html) package supplies the formatting and parsing routines based on the (modern C++) library [CCTZ](https://github.com/google/cctz) from Google, when the parsing cannot be done using a fast built-in parser. `integer64` is also used for the type `nanoduration`, whereas `nanoival` and `nanoperiod` are stored in a `complex`, i.e. over 128 bits. ### Status The package is by now fairly mature, has been rewritten once (to go from S3 to S4) and has recently received a sizeable feature extension. There may still be changes, though there should generally never be breaking ones. The package also has an extensive test suite, and very good code coverage. See the [issue tickets](https://github.com/eddelbuettel/nanotime/issues) for an up to date list of potentially desirable, possibly planned, or at least discussed items. ### Installation The package is on [CRAN](https://cran.r-project.org) and can be installed via a standard ```r install.packages("nanotime") ``` whereas in order to install development versions a ```r remotes::install_github("eddelbuettel/nanotime") # dev version ``` should suffice. ### Authors Dirk Eddelbuettel and Leonardo Silvestri ### License GPL (>= 2) nanotime/build/0000755000176200001440000000000014740324202013161 5ustar liggesusersnanotime/build/vignette.rds0000644000176200001440000000040314740324202015515 0ustar liggesusers‹QA Â0LÛ¨µ*^ôæì+D/"¼†&B &%o¾\Ý­Öx1tg3;L¦‡„JCFPF8º°Ç°BI¾3Å”¶ò$RY£ù9³R«t§*8]·îçVÏÝà‚?zD47©ñ« œ~î;ŠDé õ–¢ŠcûîÍÇ %~{áq!ŒÔ¼Í–7xˆ˜Ÿ C§MrfBŒuK‘¶êΖ"Óµ)|@ðð<Çq­´q¦¿8]'¹’¹“ìì¥}ƒh»\5e°óCøÑÿ °ot•ºG÷ Ž,?é,g¥ŸtféѰúߟ5$ LMnanotime/man/0000755000176200001440000000000014671560065012651 5ustar liggesusersnanotime/man/rounding.Rd0000644000176200001440000001152013723471745014767 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanotime.R, R/nanoduration.R, R/nanoperiod.R \name{nano_ceiling} \alias{nano_ceiling} \alias{nano_floor} \alias{nano_ceiling,nanotime,nanoduration-method} \alias{nano_floor,nanotime,nanoduration-method} \alias{nano_ceiling,nanotime,nanoperiod-method} \alias{nano_floor,nanotime,nanoperiod-method} \title{Rounding down or up a \code{nanotime} type} \usage{ nano_ceiling(x, precision, ...) nano_floor(x, precision, ...) \S4method{nano_ceiling}{nanotime,nanoduration}(x, precision, origin = nanotime()) \S4method{nano_floor}{nanotime,nanoduration}(x, precision, origin = nanotime()) \S4method{nano_ceiling}{nanotime,nanoperiod}(x, precision, origin = nanotime(), tz) \S4method{nano_floor}{nanotime,nanoperiod}(x, precision, origin = nanotime(), tz) } \arguments{ \item{x}{a \code{nanotime} object which must be sorted} \item{precision}{a \code{nanoduration} or \code{nanoperiod} object indicating the rounding precision} \item{...}{for future additional arguments} \item{origin}{a \code{nanotime} scalar indicating the origin at which the rounding is considered} \item{tz}{a \code{character} scalar indicating the time zone in which to conduct the rounding} } \description{ The functions \code{nano_floor} and \code{nano_ceiling} round down or up, respectively. Although the underlying implementation of \code{nanotime} has negative numbers for values before 1970-01-01 UTC, the rounding is always done backward in time for \code{nano_floor} and forward in time for \code{nano_ceiling}. The functions take a \code{nanotime} argument \code{x} which is the instance to round, together with a second argument \code{precision} which indicates an arbitrary precision to which the rounding should be performed. This argument can be either a \code{nanoduration} or or a \code{nanoperiod}. In the latter case, the argument \code{tz} must also be specified in order to give the \code{nanoperiod} a meaning. Finally, the \code{nanotime} argument \code{origin} can be optionally specified to fix the rounding to a specific point in time. } \details{ This flexible rounding must be understood in the context of a vector. The rounding precision can then be considered as an interval that defines a grid over which the elements are either assigned to the starting value of the interval to which they belong (\code{nano_floor}) or the ending value of the interval to which they belong (\code{nano_ceiling}). This allows for a grouping of a \code{nanotime} vector on which a statistic may then be run. In the examples below, such a use case is shown in the context of a \code{data.table} object. If "business" concepts such as month or days are needed, the \code{argument} precision must be of type \code{period}. It is then mandatory to specify the timezone argument \code{tz} as this ensures timezone correctness of the intervals including for example for the rare hourly transitions of some countries going from a timezone with a whole hour difference with UTC to one with a fractional hour difference. In the case of a \code{period}, the functions align the rounding if the precision is an integer divisor of a larger quantity. For instance, if one specifies a rounding of 6 hours, a divisor of a day, the hours are aligned on days and the rounding is made to a grid at hours 0, 6, 12 and 18 in the specified timezone. If the precision is not a divisor, the grid is aligned to the nearest hour before the first element of the vector to round. The argument \code{origin} controls the reference point of the rounding, allowing arbitrary specification of the reference point of the rounding. } \examples{ \dontrun{ ## "classic" rounding: nano_floor(as.nanotime("2010-10-10 11:12:15 UTC"), as.nanoduration("01:00:00")) ## rounding with arbitrary precision: nano_floor(as.nanotime("2010-10-10 11:12:15 UTC"), as.nanoduration("06:00:00")) nano_floor(as.nanotime("2010-10-10 11:23:15 UTC"), as.nanoduration("00:15:00")) nano_ceiling(as.nanotime("2010-10-10 11:23:15 UTC"), as.nanoduration("01:15:23")) ## controlling the reference point via the 'origin' argument: nano_ceiling(as.nanotime("2010-10-10 11:23:15 UTC"), as.nanoduration("01:15:23"), origin=as.nanotime("2010-10-10 11:23:15 UTC")) ## using business concepts and rounding across a daylight saving change: v <- seq(as.nanotime("2020-03-08 America/New_York"), by=as.nanoperiod("06:00:00"), length.out=8, tz="America/New_York") print(nano_floor(v, as.nanoperiod("1d"), tz="America/New_York"), tz="America/New_York") ## using the concept in a 'data.table': library(data.table) n <- 3 * 24 idx <- seq(as.nanotime("2020-03-07 America/New_York"), by=as.nanoperiod("01:00:00"), length.out=n, tz="America/New_York") dt <- data.table(idx, a=1:n, b=2:(n+1)) dt_mean <- dt[, list(mean = mean(a)), by=nano_ceiling(idx, as.nanoperiod("1d"), tz="America/New_York")] } } nanotime/man/rep-nanoduration-method.Rd0000644000176200001440000000230413660243672017701 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoduration.R \name{rep,nanoduration-method} \alias{rep,nanoduration-method} \title{Replicate Elements} \usage{ \S4method{rep}{nanoduration}(x, ...) } \arguments{ \item{x}{a vector of \code{nanoduration}} \item{...}{further arguments: 'times' an integer-valued vector giving the (non-negative) number of times to repeat each element if of length 'length(x)', or to repeat the whole vector if of length 1. Negative or 'NA' values are an error. A 'double' vector is accepted, other inputs being coerced to an integer or double vector. 'length.out' non-negative integer. The desired length of the output vector. Other inputs will be coerced to a double vector and the first element taken. Ignored if 'NA' or invalid. 'each' non-negative integer. Each element of 'x' is repeated 'each' times. Other inputs will be coerced to an integer or double vector and the first element taken. Treated as '1' if 'NA' or invalid.} } \description{ Replicates the values in 'x' similarly to the default method. } nanotime/man/all.equal.nanoduration.Rd0000644000176200001440000000431013643724064017513 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoduration.R \name{all.equal.nanoduration} \alias{all.equal.nanoduration} \alias{all.equal,nanoduration-method} \title{Test if Two Objects are (Nearly) Equal} \usage{ \method{all.equal}{nanoduration}( target, current, tolerance = sqrt(.Machine$double.eps), scale = NULL, countEQ = FALSE, formatFUN = function(err, what) format(err), ..., check.attributes = TRUE ) \S4method{all.equal}{nanoduration}( target, current, tolerance = sqrt(.Machine$double.eps), scale = NULL, countEQ = FALSE, formatFUN = function(err, what) format(err), ..., check.attributes = TRUE ) } \arguments{ \item{target, current}{\code{nanoduration} arguments to be compared} \item{tolerance}{numeric >= 0. Differences smaller than \code{tolerance} are not reported. The default value is close to \code{1.5e-8}.} \item{scale}{\code{NULL} or numeric > 0, typically of length 1 or \code{length(target)}. See \sQuote{Details}.} \item{countEQ}{logical indicating if the \code{target == current} cases should be counted when computing the mean (absolute or relative) differences. The default, \code{FALSE} may seem misleading in cases where \code{target} and \code{current} only differ in a few places; see the extensive example.} \item{formatFUN}{a \code{function} of two arguments, \code{err}, the relative, absolute or scaled error, and \code{what}, a character string indicating the _kind_ of error; maybe used, e.g., to format relative and absolute errors differently.} \item{...}{further arguments for different methods} \item{check.attributes}{logical indicating if the \code{attributes} of \code{target} and \code{current} (other than the names) should be compared.} } \description{ Compare \code{target} and \code{current} testing \sQuote{near equality}. If they are different, comparison is still made to some extent, and a report of the differences is returned. Do not use \code{all.equal} directly in \code{if} expressions---either use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if appropriate. } \seealso{ \code{\link{identical}}, \code{\link{isTRUE}}, \code{\link{==}}, and \code{\link{all}} for exact equality testing. } nanotime/man/nano_year.Rd0000644000176200001440000000324413714017251015105 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanotime.R \name{nano_wday} \alias{nano_wday} \alias{nano_wday,nanotime-method} \alias{nano_mday,nanotime-method} \alias{nano_month,nanotime-method} \alias{nano_year,nanotime-method} \alias{nano_mday} \alias{nano_month} \alias{nano_year} \title{Get a component of a date time} \usage{ nano_wday(x, tz) nano_mday(x, tz) nano_month(x, tz) nano_year(x, tz) } \arguments{ \item{x}{a \code{nanotime} object} \item{tz}{\code{character} a string representing a timezone} } \description{ Get a component of a date time. \code{nano_wday} returns the numeric position in a week, with Sunday == 0. \code{nano_mday} returns the numeric day (i.e. a value from 1 to 31). \code{nano_month} returns the month (i.e. a value from 1 to 12). \code{nano_year} returns the year. } \details{ Note that the \code{tz} parameter is mandatory because the day boundary is different depending on the time zone and \code{nanotime} does not store the timezone as it is just an offset in nanoseconds from the epoch. } \examples{ \dontrun{ nano_wday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/New_York") nano_wday(as.nanotime("2020-03-14 23:32:00 America/New_York"), "Europe/Paris") nano_mday(as.nanotime("2020-03-14 23:32:00-04:00"), "America/New_York") nano_mday(as.nanotime("2020-03-14 23:32:00 America/New_York"), "Europe/Paris") nano_month(as.nanotime("2020-12-31 23:32:00-04:00"), "America/New_York") nano_month(as.nanotime("2020-12-31 23:32:00 America/New_York"), "Europe/Paris") nano_year(as.nanotime("2020-12-31 23:32:00-04:00"), "America/New_York") nano_year(as.nanotime("2020-12-31 23:32:00 America/New_York"), "Europe/Paris") } } nanotime/man/nanoduration.Rd0000644000176200001440000002135214323545236015641 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoduration.R \docType{class} \name{nanoduration-class} \alias{nanoduration-class} \alias{nanoduration} \alias{*,ANY,nanoduration-method} \alias{*,nanoduration,ANY-method} \alias{*,nanoduration,nanoduration-method} \alias{+,ANY,nanoduration-method} \alias{/,ANY,nanoduration-method} \alias{/,nanoduration,ANY-method} \alias{Complex,nanoduration-method} \alias{Logic,ANY,nanoduration-method} \alias{Logic,nanoduration,ANY-method} \alias{Logic,nanoduration,nanoduration-method} \alias{Math2,nanoduration-method} \alias{Math,nanoduration-method} \alias{Summary,nanoduration-method} \alias{as.nanoduration,character-method} \alias{as.nanoduration} \alias{as.nanoduration,integer64-method} \alias{as.nanoduration,numeric-method} \alias{as.nanoduration,integer-method} \alias{as.nanoduration,difftime-method} \alias{as.nanoduration,NULL-method} \alias{as.nanoduration,missing-method} \alias{show,nanoduration-method} \alias{print,nanoduration-method} \alias{format.nanoduration} \alias{as.integer64.nanoduration} \alias{as.character,nanoduration-method} \alias{is.na,nanoduration-method} \alias{-,nanoduration,nanoduration-method} \alias{-,nanoduration,integer64-method} \alias{-,nanoduration,integer-method} \alias{-,nanoduration,numeric-method} \alias{-,nanoduration,difftime-method} \alias{-,nanoduration,ANY-method} \alias{-,nanotime,nanoduration-method} \alias{-,nanotime,difftime-method} \alias{-,integer64,nanoduration-method} \alias{-,integer,nanoduration-method} \alias{-,numeric,nanoduration-method} \alias{-,difftime,nanoduration-method} \alias{-,ANY,nanoduration-method} \alias{+,nanoduration,ANY-method} \alias{+,nanoduration,nanoduration-method} \alias{+,nanoduration,integer64-method} \alias{+,nanoduration,numeric-method} \alias{+,nanoduration,difftime-method} \alias{+,nanotime,nanoduration-method} \alias{+,nanotime,difftime-method} \alias{+,nanoduration,nanotime-method} \alias{+,difftime,nanotime-method} \alias{+,nanoival,nanoduration-method} \alias{-,nanoival,nanoduration-method} \alias{+,nanoduration,nanoival-method} \alias{+,nanoival,difftime-method} \alias{-,nanoival,difftime-method} \alias{+,difftime,nanoival-method} \alias{+,integer64,nanoduration-method} \alias{+,numeric,nanoduration-method} \alias{+,difftime,nanoduration-method} \alias{*,nanoduration,numeric-method} \alias{*,nanoduration,integer64-method} \alias{*,numeric,nanoduration-method} \alias{*,integer64,nanoduration-method} \alias{/,nanoduration,nanoduration-method} \alias{/,nanoduration,integer64-method} \alias{/,nanoduration,numeric-method} \alias{Arith,nanoduration,ANY-method} \alias{Compare,nanoduration,character-method} \alias{Compare,character,nanoduration-method} \alias{Compare,nanoduration,ANY-method} \alias{abs,nanoduration-method} \alias{sign,nanoduration-method} \alias{sum,nanoduration-method} \alias{min,nanoduration-method} \alias{max,nanoduration-method} \alias{range,nanoduration-method} \alias{[[,nanoduration-method} \alias{[,nanoduration,numeric-method} \alias{[,nanoduration,logical-method} \alias{[,nanoduration,character-method} \alias{[,nanoduration,ANY-method} \alias{[<-,nanoduration,ANY,ANY,ANY-method} \alias{c.nanoduration} \alias{NA_nanoduration_} \title{Duration type with nanosecond precision} \format{ An object of class \code{nanoduration} of length 1. } \usage{ nanoduration(hours = 0L, minutes = 0L, seconds = 0L, nanoseconds = 0L) \S4method{as.nanoduration}{character}(x) \S4method{as.nanoduration}{integer64}(x) \S4method{as.nanoduration}{numeric}(x) \S4method{as.nanoduration}{integer}(x) \S4method{as.nanoduration}{difftime}(x) \S4method{as.nanoduration}{`NULL`}(x) \S4method{as.nanoduration}{missing}(x) \S4method{show}{nanoduration}(object) \S4method{print}{nanoduration}(x, quote = FALSE, ...) \method{format}{nanoduration}(x, ...) \method{as.integer64}{nanoduration}(x, ...) \S4method{as.character}{nanoduration}(x) \S4method{is.na}{nanoduration}(x) \S4method{-}{nanoduration,nanoduration}(e1, e2) \S4method{-}{nanoduration,integer64}(e1, e2) \S4method{-}{nanoduration,integer}(e1, e2) \S4method{-}{nanoduration,numeric}(e1, e2) \S4method{-}{nanoduration,difftime}(e1, e2) \S4method{-}{nanoduration,ANY}(e1, e2) \S4method{-}{nanotime,nanoduration}(e1, e2) \S4method{-}{nanotime,difftime}(e1, e2) \S4method{-}{integer64,nanoduration}(e1, e2) \S4method{-}{integer,nanoduration}(e1, e2) \S4method{-}{numeric,nanoduration}(e1, e2) \S4method{-}{difftime,nanoduration}(e1, e2) \S4method{-}{ANY,nanoduration}(e1, e2) \S4method{+}{nanoduration,ANY}(e1, e2) \S4method{+}{nanoduration,nanoduration}(e1, e2) \S4method{+}{nanoduration,integer64}(e1, e2) \S4method{+}{nanoduration,numeric}(e1, e2) \S4method{+}{nanoduration,difftime}(e1, e2) \S4method{+}{nanotime,nanoduration}(e1, e2) \S4method{+}{nanotime,difftime}(e1, e2) \S4method{+}{nanoduration,nanotime}(e1, e2) \S4method{+}{difftime,nanotime}(e1, e2) \S4method{+}{nanoival,nanoduration}(e1, e2) \S4method{-}{nanoival,nanoduration}(e1, e2) \S4method{+}{nanoduration,nanoival}(e1, e2) \S4method{+}{nanoival,difftime}(e1, e2) \S4method{-}{nanoival,difftime}(e1, e2) \S4method{+}{difftime,nanoival}(e1, e2) \S4method{+}{integer64,nanoduration}(e1, e2) \S4method{+}{numeric,nanoduration}(e1, e2) \S4method{+}{difftime,nanoduration}(e1, e2) \S4method{*}{nanoduration,numeric}(e1, e2) \S4method{*}{nanoduration,integer64}(e1, e2) \S4method{*}{numeric,nanoduration}(e1, e2) \S4method{*}{integer64,nanoduration}(e1, e2) \S4method{/}{nanoduration,nanoduration}(e1, e2) \S4method{/}{nanoduration,integer64}(e1, e2) \S4method{/}{nanoduration,numeric}(e1, e2) \S4method{Arith}{nanoduration,ANY}(e1, e2) \S4method{Compare}{nanoduration,character}(e1, e2) \S4method{Compare}{character,nanoduration}(e1, e2) \S4method{Compare}{nanoduration,ANY}(e1, e2) \S4method{abs}{nanoduration}(x) \S4method{sign}{nanoduration}(x) \S4method{sum}{nanoduration}(x, ..., na.rm = FALSE) \S4method{min}{nanoduration}(x, ..., na.rm = FALSE) \S4method{max}{nanoduration}(x, ..., na.rm = FALSE) \S4method{range}{nanoduration}(x, ..., na.rm = FALSE) \S4method{[[}{nanoduration}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoduration,numeric}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoduration,logical}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoduration,character}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoduration,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoduration,ANY,ANY,ANY}(x, i, j, ...) <- value \method{c}{nanoduration}(...) NA_nanoduration_ } \arguments{ \item{hours}{number of hours} \item{minutes}{number of minutes} \item{seconds}{number of seconds} \item{nanoseconds}{number of nanoseconds} \item{x}{a \code{nanoduration} object} \item{object}{argument for method \code{show}} \item{quote}{indicates if the output of \code{print} should be quoted} \item{...}{further arguments passed to or from methods.} \item{e1}{Operand of class \code{nanoival}} \item{e2}{Operand of class \code{nanoival}} \item{na.rm}{if \code{TRUE} NA values are removed for the computation} \item{i}{index specifying elements to extract or replace.} \item{j}{Required for \code{[} signature but ignored here} \item{drop}{Required for \code{[} signature but ignored here} \item{value}{argument for \code{nanoduration-class}} } \value{ A nanoduration object } \description{ The type \code{nanoduration} is a length of time (implemented as an S4 class) with nanosecond precision. It is a count of nanoseconds and may be negative. The expected arithmetic operations are provided, including sequence generation. } \details{ A \code{nanoduration} can be constructed with the function \code{as.nanoduration} which can take the types \code{integer64}, \code{integer} and \code{numeric} (all indicating the count in nanosecond units) or the type \code{character}. It can also be constructed by specifying with individual arguments the hours, minutes, seconds and nanoseconds with a call to \code{nanoduration}. A \code{nanoduration} is displayed as hours, minutes, seconds and nanoseconds like this: \code{110:12:34.123_453_001}. The nanosecond precision displayed is adjusted as necessary, so e.g. 1 second is displayed as \code{00:00:01}. } \examples{ ## constructors: nanoduration(hours=10, minutes=3, seconds=2, nanoseconds=999999999) as.nanoduration("10:03:02.999_999_999") as.nanoduration(36182999999999) ## arithmetic: as.nanoduration(10e9) - as.nanoduration(9e9) as.nanoduration(10e9) + as.nanoduration(-9e9) as.nanoduration("24:00:00") / 2 as.nanoduration("24:00:00") / as.nanoduration("12:00:00") ## comparison: as.nanoduration("10:03:02.999_999_999") == 36182999999999 as.nanoduration("10:03:02.999_999_999") > as.nanoduration("10:03:02.999_999_998") as.nanoduration("10:03:02.999_999_998") < "10:03:02.999_999_999" } \seealso{ \code{\link{nanotime}} } \author{ Dirk Eddelbuettel Leonardo Silvestri } \keyword{datasets} nanotime/man/seq.nanotime.Rd0000644000176200001440000000244313714017251015533 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanotime.R \name{seq.nanotime} \alias{seq.nanotime} \alias{seq,nanotime-method} \title{Sequence Generation} \usage{ \method{seq}{nanotime}(from, to = NULL, by = NULL, length.out = NULL, along.with = NULL, ...) \S4method{seq}{nanotime}(from, to = NULL, by = NULL, length.out = NULL, along.with = NULL, ...) } \arguments{ \item{from, to}{the starting and (maximal) end values of the sequence} \item{by}{\code{nanoduration} or \code{nanoperiod} increment of the sequence; note that if the class is \code{nanoperiod} the additional argument \code{tz} must be speficied and is of \code{character} type indicating a timezone} \item{length.out}{integer indicating the desired length of the sequence} \item{along.with}{take the length from the length of this argument.} \item{...}{arguments passed to or from methods; the only interesting additional argument is \code{tz} where the \code{to} argument is of type \code{nanoperiod}} } \description{ Generate a sequence of \code{nanotime} } \examples{ \dontrun{ from <- as.nanotime("2018-01-14T12:44:00+00:00") to <- as.nanotime("2019-01-14T12:44:00+00:00") seq(from, to, by=as.nanoperiod("1m"), tz="America/New_York") seq(from, by=as.nanoperiod("1y"), length.out=4, tz="Europe/London") } } nanotime/man/set_operations.Rd0000644000176200001440000000743014211166045016170 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \name{intersect,nanoival,nanoival-method} \alias{intersect,nanoival,nanoival-method} \alias{union,nanoival,nanoival-method} \alias{setdiff,nanoival,nanoival-method} \alias{intersect.idx,nanotime,nanoival-method} \alias{intersect.idx} \alias{\%in\%.nanotime} \alias{\%in\%,nanotime,nanoival-method} \alias{intersect,nanotime,nanoival-method} \alias{setdiff,nanotime,nanoival-method} \alias{setdiff.idx,nanotime,nanoival-method} \alias{setdiff.idx} \alias{intersect,nanotime,nanotime-method} \alias{union,nanotime,nanotime-method} \alias{setdiff,nanotime,nanotime-method} \title{Set operations} \usage{ \S4method{intersect}{nanoival,nanoival}(x, y) \S4method{union}{nanoival,nanoival}(x, y) \S4method{setdiff}{nanoival,nanoival}(x, y) \S4method{intersect.idx}{nanotime,nanoival}(x, y) \method{\%in\%}{nanotime}(x, table) \S4method{\%in\%}{nanotime,nanoival}(x, table) \S4method{intersect}{nanotime,nanoival}(x, y) \S4method{setdiff}{nanotime,nanoival}(x, y) \S4method{setdiff.idx}{nanotime,nanoival}(x, y) \S4method{intersect}{nanotime,nanotime}(x, y) \S4method{union}{nanotime,nanotime}(x, y) \S4method{setdiff}{nanotime,nanotime}(x, y) } \arguments{ \item{x, y}{a temporal type} \item{table}{\code{nanoival}: used in \code{\%in\%}} } \value{ \code{intersect}, \code{union}, \code{setdiff} return temporal types that are the result of the intersection. For instance, set operations on two \code{nanoival} return a \code{nanoival}, whereas intersection between a \code{nanoival} and a \code{nanotime} returns a \code{nanotime}. \code{intersect.idx} return a list of vectors representing the element indices that intersect and \code{setdiff.idx} returns a vector representing the element indices to be removed. } \description{ Performs set intersection, union and difference between vectors of temporal types from the \code{nanotime} package. } \details{ Set operations between \code{nanoival} operands allow the construction of complex interval vectors (i.e. a \code{nanoival} vector can specify any number of inclusions and exclusions of time). Set operations between \code{nanotime} and \code{nanoival} allow to subset time vectors with interval vectors. In addition to the generic set functions, the function \code{intersect.idx} is defined which returns the indices of the intersection, and the operator \code{\%in\%} is overloaded for \code{nanotime-nanoival} which returns a logical vector that indicates which elements belong to the interval vector. } \examples{ \dontrun{ ## a vector of 'nanotime' can be subsetted by a 'nanoival' which is equivalent to 'intersect': one_second <- 1e9 a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) idx <- c(as.nanoival("-2012-12-12 12:12:10+00:00 -> 2012-12-12 12:12:14+00:00-"), as.nanoival("+2012-12-12 12:12:18+00:00 -> 2012-12-12 12:12:20+00:00+")) a[idx] intersect(a, idx) ## 'nanoival' also has the set operations 'union', 'intersect', 'setdiff': a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) i <- as.nanoival("-2012-12-12 12:12:14+00:00 -> 2012-12-12 12:12:18+00:00-") setdiff(a, i) i1 <- as.nanoival("+2012-12-12 12:12:14+00:00 -> 2012-12-12 12:12:17+00:00-") i2 <- as.nanoival("+2012-12-12 12:12:16+00:00 -> 2012-12-12 12:12:18+00:00-") union(i1, i2) ## 'intersect.idx' returns the indices of the intersection: a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) idx <- as.nanoival("+2012-12-12 12:12:14+00:00 -> 2012-12-12 12:12:19+00:00+") idx_intersect <- intersect.idx(a, idx) ## Intersection can be performed using these indices: a[idx_intersect$x] ## which is equivalent to: a[idx] ## The logical vector indicating intersection can be obtained like this: a \%in\% idx } } nanotime/man/all.equal.nanotime.Rd0000644000176200001440000000425413643724064016633 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanotime.R \name{all.equal.nanotime} \alias{all.equal.nanotime} \alias{all.equal,nanotime-method} \title{Test if Two Objects are (Nearly) Equal} \usage{ \method{all.equal}{nanotime}( target, current, tolerance = sqrt(.Machine$double.eps), scale = NULL, countEQ = FALSE, formatFUN = function(err, what) format(err), ..., check.attributes = TRUE ) \S4method{all.equal}{nanotime}( target, current, tolerance = sqrt(.Machine$double.eps), scale = NULL, countEQ = FALSE, formatFUN = function(err, what) format(err), ..., check.attributes = TRUE ) } \arguments{ \item{target, current}{\code{nanotime} arguments to be compared} \item{tolerance}{numeric >= 0. Differences smaller than \code{tolerance} are not reported. The default value is close to \code{1.5e-8}.} \item{scale}{\code{NULL} or numeric > 0, typically of length 1 or \code{length(target)}. See \sQuote{Details}.} \item{countEQ}{logical indicating if the \code{target == current} cases should be counted when computing the mean (absolute or relative) differences. The default, \code{FALSE} may seem misleading in cases where \code{target} and \code{current} only differ in a few places; see the extensive example.} \item{formatFUN}{a \code{function} of two arguments, \code{err}, the relative, absolute or scaled error, and \code{what}, a character string indicating the _kind_ of error; maybe used, e.g., to format relative and absolute errors differently.} \item{...}{further arguments for different methods} \item{check.attributes}{logical indicating if the \code{attributes} of \code{target} and \code{current} (other than the names) should be compared.} } \description{ Compare \code{target} and \code{current} testing \sQuote{near equality}. If they are different, comparison is still made to some extent, and a report of the differences is returned. Do not use \code{all.equal} directly in \code{if} expressions---either use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if appropriate. } \seealso{ \code{\link{identical}}, \code{\link{isTRUE}}, \code{\link{==}}, and \code{\link{all}} for exact equality testing. } nanotime/man/nanoival.Rd0000644000176200001440000001772614131560240014746 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \docType{class} \name{nanoival-class} \alias{nanoival-class} \alias{nanoival} \alias{+,ANY,nanoival-method} \alias{+,nanoival,ANY-method} \alias{+,nanoival,nanoival-method} \alias{-,ANY,nanoival-method} \alias{-,nanoival,ANY-method} \alias{-,nanoival,nanoival-method} \alias{Arith,nanoival,ANY-method} \alias{Compare,nanoival,ANY-method} \alias{Complex,nanoival-method} \alias{Logic,ANY,nanoival-method} \alias{Logic,nanoival,ANY-method} \alias{Logic,nanoival,nanoival-method} \alias{Math2,nanoival-method} \alias{Math,nanoival-method} \alias{Summary,nanoival-method} \alias{nanoival.start,nanoival-method} \alias{nanoival.start} \alias{nanoival.end,nanoival-method} \alias{nanoival.end} \alias{nanoival.sopen,nanoival-method} \alias{nanoival.sopen} \alias{nanoival.eopen,nanoival-method} \alias{nanoival.eopen} \alias{format.nanoival} \alias{print,nanoival-method} \alias{show,nanoival-method} \alias{as.nanoival,character-method} \alias{as.nanoival} \alias{as.nanoival,NULL-method} \alias{as.nanoival,missing-method} \alias{is.na,nanoival-method} \alias{is.na<-,nanoival-method} \alias{<,nanoival,nanoival-method} \alias{<=,nanoival,nanoival-method} \alias{>,nanoival,nanoival-method} \alias{>=,nanoival,nanoival-method} \alias{==,nanoival,nanoival-method} \alias{!=,nanoival,nanoival-method} \alias{-,nanoival,integer64-method} \alias{-,nanoival,numeric-method} \alias{+,nanoival,integer64-method} \alias{+,nanoival,numeric-method} \alias{+,integer64,nanoival-method} \alias{+,numeric,nanoival-method} \alias{[[,nanoival-method} \alias{[,nanoival,logical-method} \alias{[,nanoival,numeric-method} \alias{[,nanoival,character-method} \alias{[,nanoival,ANY-method} \alias{[<-,nanoival,logical,ANY,nanoival-method} \alias{c.nanoival} \alias{t,nanoival-method} \alias{[,nanotime,nanoival-method} \alias{NA_nanoival_} \alias{as.character.nanoival} \title{Interval type with nanosecond precision} \format{ An object of class \code{nanoival} of length 1. } \usage{ nanoival(start, end, sopen = FALSE, eopen = TRUE) \S4method{nanoival.start}{nanoival}(x) \S4method{nanoival.end}{nanoival}(x) \S4method{nanoival.sopen}{nanoival}(x) \S4method{nanoival.eopen}{nanoival}(x) \method{format}{nanoival}(x, ...) \S4method{print}{nanoival}(x, quote = FALSE, ...) \S4method{show}{nanoival}(object) \S4method{as.nanoival}{character}(from, format = "", tz = "") \S4method{as.nanoival}{`NULL`}(from, format = "", tz = "") \S4method{as.nanoival}{missing}(from, format = "", tz = "") \S4method{is.na}{nanoival}(x) \S4method{is.na}{nanoival}(x) <- value \S4method{<}{nanoival,nanoival}(e1, e2) \S4method{<=}{nanoival,nanoival}(e1, e2) \S4method{>}{nanoival,nanoival}(e1, e2) \S4method{>=}{nanoival,nanoival}(e1, e2) \S4method{==}{nanoival,nanoival}(e1, e2) \S4method{!=}{nanoival,nanoival}(e1, e2) \S4method{-}{nanoival,integer64}(e1, e2) \S4method{-}{nanoival,numeric}(e1, e2) \S4method{+}{nanoival,integer64}(e1, e2) \S4method{+}{nanoival,numeric}(e1, e2) \S4method{+}{integer64,nanoival}(e1, e2) \S4method{+}{numeric,nanoival}(e1, e2) \S4method{[[}{nanoival}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoival,logical}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoival,numeric}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoival,character}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoival,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoival,logical,ANY,nanoival}(x, i, j, ...) <- value \method{c}{nanoival}(...) \S4method{t}{nanoival}(x) \S4method{[}{nanotime,nanoival}(x, i, j, ..., drop = TRUE) NA_nanoival_ \method{as.character}{nanoival}(x, ...) } \arguments{ \item{start}{\code{nanotime} start of interval} \item{end}{\code{nanotime} end of interval} \item{sopen}{logical indicating if the start of the interval is open} \item{eopen}{logical indicating if the end of the interval is open} \item{x, from}{a \code{nanoival} object} \item{...}{further arguments passed to or from methods.} \item{quote}{indicates if the output of \code{print} should be quoted} \item{object}{argument for method \code{show}} \item{format}{A character string. Can also be set via \code{options("nanotimeFormat")} and uses \sQuote{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez} as a default and fallback} \item{tz}{\code{character} indicating a timezone} \item{value}{argument for \code{nanoival-class}} \item{e1}{Operand of class \code{nanoival}} \item{e2}{Operand of class \code{nanoival}} \item{i}{index specifying elements to extract or replace.} \item{j}{Required for \code{[} signature but ignored here} \item{drop}{Required for \code{[} signature but ignored here} } \value{ A nanoival object } \description{ \code{nanoival} is a time interval type (an S4 class) with nanosecond precision. One of its purposes is to allow quick subsetting of a \code{nanotime} vector. \code{nanoival} is composed of a \code{nanotime} pair which defines the start and end of the time interval. Additionally, it has a pair of logical values which determine if the start and end of the time interval are open (true) or closed (false). } \details{ An interval object can be constructed with the constructor \code{nanoival} which takes as arguments two \code{nanotime} objects that define the start and the end of the interval, together with two \code{logical} arguments that define if the start and the end of the interval are open (true) or closed (false) (note that these objects can all be vector, and therefore the interval object is not necessarily scalar). Alternatively, an interval can be constructed with a \code{character}: the format follows that of \code{nanotime}; the start time is preceeded by either \code{-} or \code{+} indicating if the interval start is open (-) or closed (+); the start and end times are separated by an arrow \code{->}; the end is folloed by either \code{-} or \code{+} which have the same semantics as the start time. The most important set of methods defined for \code{interval} are set functions \code{intersect}, \code{union} and \code{setdiff}. Additionally, \code{interval} allows the subsetting into a \code{nanotime} vector. Note that subsetting is allowed only if the \code{nanotime} vector is sorted. Finally, accessors are provided to get the interval start (\code{start}), the end (\code{end}), the open/close status of the start (\code{sopen}) and the open/close status of the end (\code{eopen}). The former return a \code{nanotime} while the latter return a \code{logical}. } \section{Output Format}{ Formatting and character conversion for \code{nanoival} objects is identical to \code{nanotime} objects. The default format is ISO3339 compliant: \code{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez}. It specifies a standard ISO 8601 part for date and time --- as well as nine digits of precision for fractional seconds (down to nanoseconds) and on offset (typically zero as we default to UTC). It can be overriden by using \code{options()} with the key of \code{nanotimeFormat} and a suitable value. Similarly, \code{nanotimeTz} can be used to select a different timezone. } \examples{ \dontrun{ ## creating a \code{nanoival}, with the start time included ('+') and the end ## time excluded ('-') as.nanoival("+2012-03-01T21:21:00.000000001+00:00->2015-01-01T21:22:00.000000999+04:00-") ## a \code{nanoival} can also be created with a pair of \code{nanotime} objects, a start ## and an end, and optionally two logicals determining if the interval start(end) are open ## or closed; by default the start is closed and end is open: start <- nanotime("2012-03-01T21:21:00.000000001+00:00") end <- nanotime("2013-03-01T21:21:00.000000001+00:00") nanoival(start, end) ## a vector of 'nanotime' can be subsetted by a 'nanoival': one_second <- 1e9 a <- seq(nanotime("2012-12-12 12:12:12+00:00"), length.out=10, by=one_second) idx <- c(as.nanoival("-2012-12-12 12:12:10+00:00 -> 2012-12-12 12:12:14+00:00-"), as.nanoival("+2012-12-12 12:12:18+00:00 -> 2012-12-12 12:12:20+00:00+")) a[idx] } } \seealso{ \code{\link{intersect.idx}}, \code{\link{setdiff.idx}}, } \author{ Dirk Eddelbuettel Leonardo Silvestri } \keyword{datasets} nanotime/man/nanotime.Rd0000644000176200001440000002363314671560065014761 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanotime.R, R/nanoduration.R \docType{class} \name{nanotime-class} \alias{nanotime-class} \alias{nanotime} \alias{as.nanotime} \alias{nanotime,character-method} \alias{as.nanotime,character-method} \alias{nanotime.matrix} \alias{nanotime,POSIXct-method} \alias{as.nanotime,POSIXct-method} \alias{nanotime,POSIXlt-method} \alias{as.nanotime,POSIXlt-method} \alias{nanotime,Date-method} \alias{as.nanotime,Date-method} \alias{print,nanotime-method} \alias{show,nanotime-method} \alias{unique,nanotime-method} \alias{format.nanotime} \alias{index2char.nanotime} \alias{as.POSIXct.nanotime} \alias{as.POSIXlt.nanotime} \alias{as.Date.nanotime} \alias{as.data.frame.nanotime} \alias{as.integer64.nanotime} \alias{-,nanotime,character-method} \alias{-,nanotime,nanotime-method} \alias{-,nanotime,integer64-method} \alias{-,nanotime,numeric-method} \alias{-,ANY,nanotime-method} \alias{-,nanotime,ANY-method} \alias{+,nanotime,ANY-method} \alias{+,nanotime,integer64-method} \alias{+,nanotime,numeric-method} \alias{+,ANY,nanotime-method} \alias{+,integer64,nanotime-method} \alias{+,numeric,nanotime-method} \alias{+,nanotime,nanotime-method} \alias{Arith,nanotime,nanotime-method} \alias{Arith,nanotime,ANY-method} \alias{Arith,ANY,nanotime-method} \alias{Compare,nanotime,character-method} \alias{Compare,character,nanotime-method} \alias{Compare,nanotime,POSIXt-method} \alias{Compare,POSIXt,nanotime-method} \alias{Compare,nanotime,ANY-method} \alias{Logic,nanotime,ANY-method} \alias{Logic,ANY,nanotime-method} \alias{Math,nanotime-method} \alias{Math2,nanotime-method} \alias{Summary,nanotime-method} \alias{min,nanotime-method} \alias{max,nanotime-method} \alias{range,nanotime-method} \alias{Complex,nanotime-method} \alias{[[,nanotime-method} \alias{[,nanotime,numeric-method} \alias{[,nanotime,logical-method} \alias{[,nanotime,character-method} \alias{[,nanotime,ANY-method} \alias{[<-,nanotime,ANY,ANY,ANY-method} \alias{c.nanotime} \alias{nanotime-package} \alias{names<-,nanotime-method} \alias{is.na,nanotime-method} \alias{NA_nanotime_} \alias{as.character.nanotime} \alias{as.data.frame.nanoduration} \title{Nanosecond resolution datetime functionality} \format{ An object of class \code{nanotime} of length 1. } \usage{ nanotime(from, ...) as.nanotime(from, ...) \S4method{nanotime}{character}(from, format = "", tz = "") \S4method{as.nanotime}{character}(from, format = "", tz = "") nanotime.matrix(x) \S4method{nanotime}{POSIXct}(from, accurate = TRUE) \S4method{as.nanotime}{POSIXct}(from, accurate = TRUE) \S4method{nanotime}{POSIXlt}(from) \S4method{as.nanotime}{POSIXlt}(from) \S4method{nanotime}{Date}(from) \S4method{as.nanotime}{Date}(from) \S4method{print}{nanotime}(x, format = "", tz = "", quote = FALSE, ...) \S4method{show}{nanotime}(object) \method{format}{nanotime}(x, format = "", tz = "", ...) \method{index2char}{nanotime}(x, ...) \method{as.POSIXct}{nanotime}(x, tz = "", ...) \method{as.POSIXlt}{nanotime}(x, tz = "", ...) \method{as.Date}{nanotime}(x, ...) \method{as.data.frame}{nanotime}(x, ...) \method{as.integer64}{nanotime}(x, ...) \S4method{-}{nanotime,character}(e1, e2) \S4method{-}{nanotime,nanotime}(e1, e2) \S4method{-}{nanotime,integer64}(e1, e2) \S4method{-}{nanotime,numeric}(e1, e2) \S4method{-}{ANY,nanotime}(e1, e2) \S4method{-}{nanotime,ANY}(e1, e2) \S4method{+}{nanotime,ANY}(e1, e2) \S4method{+}{nanotime,integer64}(e1, e2) \S4method{+}{nanotime,numeric}(e1, e2) \S4method{+}{ANY,nanotime}(e1, e2) \S4method{+}{integer64,nanotime}(e1, e2) \S4method{+}{numeric,nanotime}(e1, e2) \S4method{+}{nanotime,nanotime}(e1, e2) \S4method{Arith}{nanotime,nanotime}(e1, e2) \S4method{Arith}{nanotime,ANY}(e1, e2) \S4method{Arith}{ANY,nanotime}(e1, e2) \S4method{Compare}{nanotime,character}(e1, e2) \S4method{Compare}{character,nanotime}(e1, e2) \S4method{Compare}{nanotime,POSIXt}(e1, e2) \S4method{Compare}{POSIXt,nanotime}(e1, e2) \S4method{Compare}{nanotime,ANY}(e1, e2) \S4method{Logic}{nanotime,ANY}(e1, e2) \S4method{Logic}{ANY,nanotime}(e1, e2) \S4method{Math}{nanotime}(x) \S4method{Math2}{nanotime}(x, digits) \S4method{Summary}{nanotime}(x, ..., na.rm = FALSE) \S4method{min}{nanotime}(x, ..., na.rm = FALSE) \S4method{max}{nanotime}(x, ..., na.rm = FALSE) \S4method{range}{nanotime}(x, ..., na.rm = FALSE) \S4method{Complex}{nanotime}(z) \S4method{[[}{nanotime}(x, i, j, ..., drop = FALSE) \S4method{[}{nanotime,numeric}(x, i, j, ..., drop = FALSE) \S4method{[}{nanotime,logical}(x, i, j, ..., drop = FALSE) \S4method{[}{nanotime,character}(x, i, j, ..., drop = FALSE) \S4method{[}{nanotime,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{nanotime,ANY,ANY,ANY}(x, i, j, ...) <- value \method{c}{nanotime}(...) \S4method{names}{nanotime}(x) <- value \S4method{is.na}{nanotime}(x) NA_nanotime_ \method{as.character}{nanotime}(x, ...) \method{as.data.frame}{nanoduration}(x, ...) } \arguments{ \item{...}{further arguments passed to or from methods.} \item{format}{A character string. Can also be set via \code{options("nanotimeFormat")} and uses \sQuote{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez} as a default and fallback} \item{tz}{character specifying a timezone which is required for \code{as.POSIXct}, \code{as.POSIXlt} and can be specified for \code{as.nanotime}, \code{format} and \code{print}; it can also be set via \code{options("nanotimeTz")} and uses \sQuote{UTC} as a default and fallback} \item{x, from}{\code{nanotime} objects} \item{accurate}{in the conversion from \code{POSIXct} to \code{nanotime}, indicates if one wants to preserve the maximum precision possible; the default is \code{TRUE}, but in most situations the loss of precision is negligible, and setting this parameter to \code{TRUE} will make the conversion nearly an order of magnitude faster} \item{quote}{indicates if the output of \code{print} should be quoted} \item{object}{argument for method \code{show}} \item{e1}{Operand of class \code{nanotime}} \item{e2}{Operand of class \code{nanotime}} \item{digits}{Required for \code{Math2} signature but ignored here} \item{na.rm}{a logical indicating whether missing values should be removed.} \item{z}{Required for \code{Complex} signature but ignored here} \item{i}{index specifying elements to extract or replace.} \item{j}{Required for \code{[} signature but ignored here} \item{drop}{Required for \code{[} signature but ignored here} \item{value}{argument for \code{nanotime-class}} } \value{ A nanotime object } \description{ Functions to operate on nanosecond time resolution using integer64 bit representation. Conversion functions for several standard R types are provided, and more will be added as needed. } \details{ Notice that the conversion from POSIXct explicitly sets the last three digits to zero. Nanosecond time stored in a 64-bit integer has nineteen digits precision where doubles (which are used internally for POSIXct as well) only have sixteen digits. So rather than showing three more (essentially \emph{random}) digits it is constructed such that these three additional digits are zeros. } \section{Caveats}{ Working with dates and times is \emph{difficult}. One needs a representation of both \emph{time points} and \emph{time duration}. In R, think of \code{Date} or \code{POSIXct} objects for the former, and \code{difftime} for the later. Here we have time points \code{nanotime}, an interval type \code{nanoival} and two flavors of duration which are a simple count of nanoseconds \code{nanoduration} and a calendar duration that is able to track concepts such as months and days \code{nanoperiod}. Point in time and intervals are all based on durations relative to the epoch of January 1, 1970. } \section{Input and Output Format}{ Formatting and character conversion for \code{nanotime} objects is done by functions from the \pkg{RcppCCTZ} package relying on code from its embedded \code{CCTZ} library. The default format is ISO3339 compliant: \code{\%Y-\%m-\%dT\%H:\%M:\%E9S\%Ez}. It specifies a standard ISO 8601 part for date and time --- as well as nine digits of precision for fractional seconds (down to nanoseconds) and on offset (typically zero as we default to UTC). It can be overriden by using \code{options()} with the key of \code{nanotimeFormat} and a suitable value. Similarly, \code{nanotimeTz} can be used to select a different timezone. For input, some slack it cut, and various shortened formats are accepted by default such as \code{2020-03-10} or \code{2020-03-10 18:16:00}, or \code{2020-03-10 18:16:00.001} (and the \sQuote{T} separator is optional. } \section{\code{tz} parameter usage in constructors}{ The \code{tz} parameter is allowed only when constructing a \code{nanotime} from a \code{character}. This is because any \code{numeric}, \code{Date} and \code{POSIXct} is de facto considered an offset since the epoch. On the contrary, a \code{character} is considered interpretable and hence if it does not contain a timezone in its representation, it is possible to specify the \code{tz} argument to specify in which timezone it should be interpreted. This is useful in particular if one wants to convert a \code{Date} to be aligned to the beginning of the day in a specific timezone; in this case one should convert the \code{Date} to a \code{character} before calling the \code{nanotime} constructor with the desired timezone. } \examples{ \dontrun{ x <- nanotime(1) print(x) as.nanotime("1970-01-01T00:00:00.000000001+00:00") as.nanotime("2020-03-10 Europe/Berlin") as.nanotime("2020-03-10 18:31:23.001", tz="America/New_York") as.nanotime("2020-03-10T040947190301440", format="\%Y-\%m-\%dT\%H\%M\%S\%E*f") x <- x + 1 print(x) format(x) x <- x + 10 print(x) format(x) nanotime(Sys.time()) + 1:3 # three elements each 1 ns apart seq(x, by=as.nanoperiod("1d"), length.out=5, tz="Asia/Tokyo") } } \seealso{ \code{\link{nanoival}}, \code{\link{nanoduration}}, \code{\link{nanoperiod}}, \code{\link{seq.nanotime}} as well as the documentation in package \pkg{RcppCCTZ}. } \author{ Dirk Eddelbuettel Leonardo Silvestri } \keyword{datasets} nanotime/man/rep-nanoival-method.Rd0000644000176200001440000000226013705574141017006 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \name{rep,nanoival-method} \alias{rep,nanoival-method} \title{Replicate Elements} \usage{ \S4method{rep}{nanoival}(x, ...) } \arguments{ \item{x}{a vector of \code{nanoival}} \item{...}{further arguments: 'times' an integer-valued vector giving the (non-negative) number of times to repeat each element if of length 'length(x)', or to repeat the whole vector if of length 1. Negative or 'NA' values are an error. A 'double' vector is accepted, other inputs being coerced to an integer or double vector. 'length.out' non-negative integer. The desired length of the output vector. Other inputs will be coerced to a double vector and the first element taken. Ignored if 'NA' or invalid. 'each' non-negative integer. Each element of 'x' is repeated 'each' times. Other inputs will be coerced to an integer or double vector and the first element taken. Treated as '1' if 'NA' or invalid.} } \description{ Replicates the values in 'x' similarly to the default method. } nanotime/man/all.equal.nanoperiod.Rd0000644000176200001440000000221713643724064017154 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoperiod.R \name{all.equal.nanoperiod} \alias{all.equal.nanoperiod} \alias{all.equal,nanoperiod-method} \title{Test if Two Objects are (Nearly) Equal} \usage{ \method{all.equal}{nanoperiod}(target, current, ..., check.attributes = TRUE) \S4method{all.equal}{nanoperiod}(target, current, ..., check.attributes = TRUE) } \arguments{ \item{target, current}{\code{nanoperiod} arguments to be compared} \item{...}{further arguments for different methods} \item{check.attributes}{logical indicating if the \code{attributes} of \code{target} and \code{current} (other than the names) should be compared.} } \description{ Compare \code{target} and \code{current} testing \sQuote{near equality}. If they are different, comparison is still made to some extent, and a report of the differences is returned. Do not use \code{all.equal} directly in \code{if} expressions---either use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if appropriate. } \seealso{ \code{\link{identical}}, \code{\link{isTRUE}}, \code{\link{==}}, and \code{\link{all}} for exact equality testing. } nanotime/man/rep-nanoperiod-method.Rd0000644000176200001440000000227213660243672017342 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoperiod.R \name{rep,nanoperiod-method} \alias{rep,nanoperiod-method} \title{Replicate Elements} \usage{ \S4method{rep}{nanoperiod}(x, ...) } \arguments{ \item{x}{a vector of \code{nanoperiod}} \item{...}{further arguments: 'times' an integer-valued vector giving the (non-negative) number of times to repeat each element if of length 'length(x)', or to repeat the whole vector if of length 1. Negative or 'NA' values are an error. A 'double' vector is accepted, other inputs being coerced to an integer or double vector. 'length.out' non-negative integer. The desired length of the output vector. Other inputs will be coerced to a double vector and the first element taken. Ignored if 'NA' or invalid. 'each' non-negative integer. Each element of 'x' is repeated 'each' times. Other inputs will be coerced to an integer or double vector and the first element taken. Treated as '1' if 'NA' or invalid.} } \description{ Replicates the values in 'x' similarly to the default method. } nanotime/man/seq-nanoival-method.Rd0000644000176200001440000000213613714017251017004 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \name{seq,nanoival-method} \alias{seq,nanoival-method} \title{Sequence Generation} \usage{ \S4method{seq}{nanoival}(from, to = NULL, by = NULL, length.out = NULL, along.with = NULL, ...) } \arguments{ \item{from, to}{the starting and (maximal) end values of the sequence} \item{by}{\code{nanoduration} or \code{nanoperiod} increment of the sequence; note that if the class is \code{nanoperiod} the additional argument \code{tz} must be speficied and is of \code{character} type indicating a timezone} \item{length.out}{an integer desired length of the sequence} \item{along.with}{take the length from the length of this argument.} \item{...}{arguments passed to or from methods; the only interesting additional argument is \code{tz} where the \code{to} argument is of type \code{nanoperiod}} } \description{ Generate a sequence of \code{nanoival} } \examples{ \dontrun{ from <- as.nanoival("-2018-01-14T13:00:00+00:00 -> 2018-01-14T15:00:00+00:00+") seq(from, by=as.nanoperiod("1m"), length.out=5, tz="America/New_York") } } nanotime/man/nanoperiod.Rd0000644000176200001440000002074014634012774015277 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoperiod.R \docType{class} \name{nanoperiod-class} \alias{nanoperiod-class} \alias{nanoperiod} \alias{Compare,ANY,nanoperiod-method} \alias{Compare,nanoperiod,ANY-method} \alias{-,ANY,nanoperiod-method} \alias{-,nanoperiod,nanotime-method} \alias{-,nanotime,nanoperiod-method} \alias{/,ANY,nanoperiod-method} \alias{/,nanoperiod,ANY-method} \alias{Complex,nanoperiod-method} \alias{Math,nanoperiod-method} \alias{Math2,nanoperiod-method} \alias{Summary,nanoperiod-method} \alias{minus,nanoperiod,nanoival,character-method} \alias{as.nanoperiod,character-method} \alias{as.nanoperiod} \alias{as.nanoperiod,integer64-method} \alias{as.nanoperiod,numeric-method} \alias{as.nanoperiod,integer-method} \alias{as.nanoperiod,nanoduration-method} \alias{as.nanoperiod,NULL-method} \alias{as.nanoperiod,missing-method} \alias{show,nanoperiod-method} \alias{print,nanoperiod-method} \alias{format.nanoperiod} \alias{as.character,nanoperiod-method} \alias{is.na,nanoperiod-method} \alias{is.na<-,nanoperiod-method} \alias{[[,nanoperiod-method} \alias{[,nanoperiod,numeric-method} \alias{[,nanoperiod,logical-method} \alias{[,nanoperiod,character-method} \alias{[,nanoperiod,ANY-method} \alias{[<-,nanoperiod,ANY,ANY,ANY-method} \alias{c.nanoperiod} \alias{names,nanoperiod-method} \alias{names<-,nanoperiod-method} \alias{-,nanoperiod,ANY-method} \alias{-,nanoperiod,nanoperiod-method} \alias{-,nanoperiod,nanoduration-method} \alias{-,nanoperiod,integer64-method} \alias{-,nanoperiod,numeric-method} \alias{-,nanoduration,nanoperiod-method} \alias{-,integer64,nanoperiod-method} \alias{-,numeric,nanoperiod-method} \alias{+,nanoperiod,ANY-method} \alias{+,ANY,nanoperiod-method} \alias{+,nanoperiod,nanoperiod-method} \alias{+,nanoperiod,nanoduration-method} \alias{+,nanoperiod,integer64-method} \alias{+,nanoperiod,nanotime-method} \alias{+,nanoival,nanoperiod-method} \alias{+,nanoperiod,nanoival-method} \alias{+,nanotime,nanoperiod-method} \alias{+,nanoperiod,numeric-method} \alias{+,nanoduration,nanoperiod-method} \alias{+,integer64,nanoperiod-method} \alias{+,numeric,nanoperiod-method} \alias{*,nanoperiod,integer64-method} \alias{*,nanoperiod,ANY-method} \alias{*,ANY,nanoperiod-method} \alias{*,nanoperiod,numeric-method} \alias{*,integer64,nanoperiod-method} \alias{*,numeric,nanoperiod-method} \alias{/,nanoperiod,integer64-method} \alias{/,nanoperiod,numeric-method} \alias{==,nanoperiod,nanoperiod-method} \alias{!=,nanoperiod,nanoperiod-method} \alias{plus,nanotime,nanoperiod,character-method} \alias{plus} \alias{plus,nanoperiod,nanotime,character-method} \alias{minus,nanotime,nanoperiod,character-method} \alias{minus} \alias{minus,nanoperiod,nanotime,character-method} \alias{plus,nanoival,nanoperiod,character-method} \alias{plus,nanoperiod,nanoival,character-method} \alias{minus,nanoival,nanoperiod,character-method} \alias{NA_nanoperiod_} \title{Period type with nanosecond precision} \format{ An object of class \code{nanoperiod} of length 1. } \usage{ nanoperiod(months = 0, days = 0, duration = as.nanoduration(0)) \S4method{as.nanoperiod}{character}(x) \S4method{as.nanoperiod}{integer64}(x) \S4method{as.nanoperiod}{numeric}(x) \S4method{as.nanoperiod}{integer}(x) \S4method{as.nanoperiod}{nanoduration}(x) \S4method{as.nanoperiod}{`NULL`}(x) \S4method{as.nanoperiod}{missing}(x) \S4method{show}{nanoperiod}(object) \S4method{print}{nanoperiod}(x, quote = FALSE, ...) \method{format}{nanoperiod}(x, ...) \S4method{as.character}{nanoperiod}(x) \S4method{is.na}{nanoperiod}(x) \S4method{is.na}{nanoperiod}(x) <- value \S4method{[[}{nanoperiod}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoperiod,numeric}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoperiod,logical}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoperiod,character}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoperiod,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{nanoperiod,ANY,ANY,ANY}(x, i, j, ...) <- value \method{c}{nanoperiod}(...) \S4method{names}{nanoperiod}(x) \S4method{names}{nanoperiod}(x) <- value \S4method{-}{nanoperiod,ANY}(e1, e2) \S4method{-}{nanoperiod,nanoperiod}(e1, e2) \S4method{-}{nanoperiod,nanoduration}(e1, e2) \S4method{-}{nanoperiod,integer64}(e1, e2) \S4method{-}{nanoperiod,numeric}(e1, e2) \S4method{-}{nanoduration,nanoperiod}(e1, e2) \S4method{-}{integer64,nanoperiod}(e1, e2) \S4method{-}{numeric,nanoperiod}(e1, e2) \S4method{+}{nanoperiod,ANY}(e1, e2) \S4method{+}{nanoperiod,nanoperiod}(e1, e2) \S4method{+}{nanoperiod,nanoduration}(e1, e2) \S4method{+}{nanoperiod,integer64}(e1, e2) \S4method{+}{nanoperiod,nanotime}(e1, e2) \S4method{+}{nanoival,nanoperiod}(e1, e2) \S4method{+}{nanoperiod,nanoival}(e1, e2) \S4method{+}{nanotime,nanoperiod}(e1, e2) \S4method{+}{nanoperiod,numeric}(e1, e2) \S4method{+}{nanoduration,nanoperiod}(e1, e2) \S4method{+}{integer64,nanoperiod}(e1, e2) \S4method{+}{numeric,nanoperiod}(e1, e2) \S4method{*}{nanoperiod,integer64}(e1, e2) \S4method{*}{nanoperiod,numeric}(e1, e2) \S4method{*}{integer64,nanoperiod}(e1, e2) \S4method{*}{numeric,nanoperiod}(e1, e2) \S4method{/}{nanoperiod,integer64}(e1, e2) \S4method{/}{nanoperiod,numeric}(e1, e2) \S4method{==}{nanoperiod,nanoperiod}(e1, e2) \S4method{!=}{nanoperiod,nanoperiod}(e1, e2) \S4method{plus}{nanotime,nanoperiod,character}(e1, e2, tz) \S4method{plus}{nanoperiod,nanotime,character}(e1, e2, tz) \S4method{minus}{nanotime,nanoperiod,character}(e1, e2, tz) \S4method{minus}{nanoperiod,nanotime,character}(e1, e2, tz) \S4method{plus}{nanoival,nanoperiod,character}(e1, e2, tz) \S4method{plus}{nanoperiod,nanoival,character}(e1, e2, tz) \S4method{minus}{nanoival,nanoperiod,character}(e1, e2, tz) NA_nanoperiod_ } \arguments{ \item{months}{Used in the constructor to indicate the number of months of the \code{nanoperiod}} \item{days}{Used in the constructor to indicate the number of days of the \code{nanoperiod}} \item{duration}{Used in the constructor to indicate the duration component of the \code{nanoperiod}} \item{x, value}{An object of class \code{nanoperiod}} \item{object}{argument for method \code{show}} \item{quote}{indicates if the output of \code{print} should be quoted} \item{...}{further arguments} \item{i}{index specifying elements to extract or replace.} \item{j}{Required for \code{[} signature but ignored here} \item{drop}{Required for \code{[} signature but ignored here} \item{e1}{Operand of class \code{nanoperiod}} \item{e2}{Operand of class \code{nanoperiod}} \item{tz}{\code{character} indicating a timezone} } \description{ \code{nanoperiod} is a length of time type (implemented as an S4 class) with nanosecond precision. It differs from \code{nanoduration} because it is capable of representing calendar months and days. It can thus represent years (12 months) and weeks (7 days). A period is a somewhat abstract representation of time: it is only when anchored to a point in time and in a specific time zone that it is possible to convert it to a specific duration. This means that many of the operations involving periods need the additional argument \code{tz}. } \section{Constructors}{ The true constructor is } \section{Output Format}{ A \code{nanoperiod} is displayed as months, days, and \code{nanoduration} like this: \code{10m2d/10:12:34.123_453_000}. } \section{Details}{ Adding or subtracting \code{nanoperiod} and \code{nanotime} require a timezone as third argument. For this reason it is not possible to use the binary operator `\code{+}`. Instead the functions `\code{plus}` and `\code{minus}` are defined. These functions attempt to keep the same offset within a day in the specified timezone: this means for instance that adding a day when that day crosses a time zone adjustment such as a daylight saving time, results in a true time increment of less or more than 24 hours to preserve the offset. Preserving the offset works for increments that are smaller than a day too, provided the increment results in a datetime where the timezone adjustment is valid. When this is not the case, adding a `nanoperiod` behaves in the same way as adding a `nanoduration`. } \examples{ \dontrun{ p <- nanoperiod(months=12, days=7, duration="01:00:00") print(p) # when adding a \code{nanoperiod} to a \code{nanotime} or to a # \code{nanoival}, a time zone must be specified: y <- nanotime("1970-01-01T00:00:00+00:00") plus(y, p, tz="America/Chicago") } } \seealso{ \code{\link{nanotime}}, \code{\link{nanoduration}}, \code{\link{nanoival}}, \code{\link{nanoperiod.month,nanoperiod-method}} } \author{ Dirk Eddelbuettel Leonardo Silvestri } \keyword{datasets} nanotime/man/seq.nanoduration.Rd0000644000176200001440000000135213636243601016423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoduration.R \name{seq.nanoduration} \alias{seq.nanoduration} \title{Sequence Generation} \usage{ \method{seq}{nanoduration}(from, to = NULL, by = NULL, length.out = NULL, along.with = NULL, ...) } \arguments{ \item{from, to}{the starting and (maximal) end values of the sequence} \item{by}{the increment of the sequence} \item{length.out}{integer indicating the desired length of the sequence} \item{along.with}{take the length from the length of this argument.} \item{...}{arguments passed to or from methods} } \description{ Generate a sequence of \code{nanoduration} } \examples{ seq(from=as.nanoduration(0), by=as.nanoduration("01:00:00"), length.out=10) } nanotime/man/all.equal.nanoival.Rd0000644000176200001440000000220113643724064016616 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \name{all.equal.nanoival} \alias{all.equal.nanoival} \alias{all.equal,nanoival-method} \title{Test if Two Objects are (Nearly) Equal} \usage{ \method{all.equal}{nanoival}(target, current, ..., check.attributes = TRUE) \S4method{all.equal}{nanoival}(target, current, ..., check.attributes = TRUE) } \arguments{ \item{target, current}{\code{nanoival} arguments to be compared} \item{...}{further arguments for different methods} \item{check.attributes}{logical indicating if the \code{attributes} of \code{target} and \code{current} (other than the names) should be compared.} } \description{ Compare \code{target} and \code{current} testing \sQuote{near equality}. If they are different, comparison is still made to some extent, and a report of the differences is returned. Do not use \code{all.equal} directly in \code{if} expressions---either use \code{isTRUE(all.equal(....))} or \code{\link{identical}} if appropriate. } \seealso{ \code{\link{identical}}, \code{\link{isTRUE}}, \code{\link{==}}, and \code{\link{all}} for exact equality testing. } nanotime/man/is.unsorted-nanoival-method.Rd0000644000176200001440000000120613636243601020471 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \name{is.unsorted,nanoival-method} \alias{is.unsorted,nanoival-method} \title{Test if a \code{nanoival} vector is Not Sorted} \usage{ \S4method{is.unsorted}{nanoival}(x, na.rm = FALSE, strictly = FALSE) } \arguments{ \item{x}{a \code{nanoival} vector} \item{na.rm}{logical. Should missing values be removed before checking?} \item{strictly}{logical indicating if the check should be for _strictly_ increasing values.} } \description{ Test if an object is not sorted (in increasing order), without the cost of sorting it. } \seealso{ \code{\link{sort}} } nanotime/man/sort-nanoival-method.Rd0000644000176200001440000000076713636243601017216 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoival.R \name{sort,nanoival-method} \alias{sort,nanoival-method} \title{Sorting or Ordering Vectors} \usage{ \S4method{sort}{nanoival}(x, decreasing = FALSE) } \arguments{ \item{x}{a vector of \code{nanoival}} \item{decreasing}{logical. Should the sort be increasing or decreasing?} } \description{ Sort (or _order_) a vector of \code{nanoival} into ascending or descending order } \seealso{ \code{\link{is.unsorted}} } nanotime/man/nanoperiod.month.Rd0000644000176200001440000000177413636243601016425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanoperiod.R \name{nanoperiod.month,nanoperiod-method} \alias{nanoperiod.month,nanoperiod-method} \alias{nanoperiod.month} \alias{nanoperiod.day} \alias{nanoperiod.nanoduration} \alias{nanoperiod.day,nanoperiod-method} \alias{nanoperiod.nanoduration,nanoperiod-method} \title{Nanoperiod accessors} \usage{ \S4method{nanoperiod.month}{nanoperiod}(x) \S4method{nanoperiod.day}{nanoperiod}(x) \S4method{nanoperiod.nanoduration}{nanoperiod}(x) } \arguments{ \item{x}{A \code{nanoperiod}} } \value{ \code{nanoperiod.month} and \code{nanoperiod.day} return an \code{integer64} whereas \code{nanoperiod.nanoduration} returns a \code{nanoduration} } \description{ These functions allow access to the components of a \code{nanoperiod} } \examples{ p <- as.nanoperiod("2y1m1d/12:00:00") nanoperiod.month(p) nanoperiod.day(p) nanoperiod.nanoduration(p) } \seealso{ \code{\link{nanoduration}} } \author{ Dirk Eddelbuettel Leonardo Silvestri } nanotime/man/rep-nanotime-method.Rd0000644000176200001440000000226013660243672017013 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nanotime.R \name{rep,nanotime-method} \alias{rep,nanotime-method} \title{Replicate Elements} \usage{ \S4method{rep}{nanotime}(x, ...) } \arguments{ \item{x}{a vector of \code{nanotime}} \item{...}{further arguments: 'times' an integer-valued vector giving the (non-negative) number of times to repeat each element if of length 'length(x)', or to repeat the whole vector if of length 1. Negative or 'NA' values are an error. A 'double' vector is accepted, other inputs being coerced to an integer or double vector. 'length.out' non-negative integer. The desired length of the output vector. Other inputs will be coerced to a double vector and the first element taken. Ignored if 'NA' or invalid. 'each' non-negative integer. Each element of 'x' is repeated 'each' times. Other inputs will be coerced to an integer or double vector and the first element taken. Treated as '1' if 'NA' or invalid.} } \description{ Replicates the values in 'x' similarly to the default method. } nanotime/DESCRIPTION0000644000176200001440000000253314740327722013605 0ustar liggesusersPackage: nanotime Type: Package Title: Nanosecond-Resolution Time Support for R Version: 0.3.11 Date: 2025-01-10 Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", comment = c(ORCID = "0000-0001-6419-907X")), person("Leonardo", "Silvestri", role = "aut")) Description: Full 64-bit resolution date and time functionality with nanosecond granularity is provided, with easy transition to and from the standard 'POSIXct' type. Three additional classes offer interval, period and duration functionality for nanosecond-resolution timestamps. Imports: methods, bit64, RcppCCTZ (>= 0.2.9), zoo Suggests: tinytest, data.table, xts LinkingTo: Rcpp, RcppCCTZ, RcppDate License: GPL (>= 2) URL: https://github.com/eddelbuettel/nanotime, https://eddelbuettel.github.io/nanotime/, https://dirk.eddelbuettel.com/code/nanotime.html BugReports: https://github.com/eddelbuettel/nanotime/issues RoxygenNote: 7.3.2 Collate: 'nanotime.R' 'nanoival.R' 'nanoduration.R' 'nanoperiod.R' 'RcppExports.R' Encoding: UTF-8 NeedsCompilation: yes Packaged: 2025-01-10 23:08:51 UTC; edd Author: Dirk Eddelbuettel [aut, cre] (), Leonardo Silvestri [aut] Maintainer: Dirk Eddelbuettel Repository: CRAN Date/Publication: 2025-01-10 23:40:02 UTC