SeuratObject/0000755000176200001440000000000015117034671012651 5ustar liggesusersSeuratObject/tests/0000755000176200001440000000000015114353666014020 5ustar liggesusersSeuratObject/tests/testthat/0000755000176200001440000000000015117034671015653 5ustar liggesusersSeuratObject/tests/testthat/test_objects.R0000644000176200001440000004110115116566601020465 0ustar liggesusers# Tests for functions in objects.R # Tests for interacting with the meta.data slot # ------------------------------------------------------------------------------ context("Metadata") data("pbmc_small") pbmc_small <- suppressWarnings(suppressMessages(UpdateSeuratObject(pbmc_small))) cluster_letters <- LETTERS[Idents(object = pbmc_small)] names(cluster_letters) <- colnames(x = pbmc_small) cluster_letters_shuffled <- sample(x = cluster_letters) test_that("AddMetaData adds in cell-level vector properly ", { pbmc_small <- AddMetaData(object = pbmc_small, metadata = cluster_letters, col.name = 'letter.idents') expect_equal(pbmc_small$letter.idents, cluster_letters) pbmc_small <- AddMetaData(object = pbmc_small, metadata = cluster_letters_shuffled, col.name = 'letter.idents.shuffled') expect_equal(pbmc_small$letter.idents, pbmc_small$letter.idents.shuffled) }) cluster_letters_df <- data.frame(A = cluster_letters, B = cluster_letters_shuffled) test_that("AddMetaData adds in data frame properly for cell-level metadata", { pbmc_small <- AddMetaData(object = pbmc_small, metadata = cluster_letters_df) expect_equal(pbmc_small[[c("A", "B")]], cluster_letters_df) }) feature_letters <- sample(x = LETTERS, size = nrow(x = pbmc_small[["RNA"]]), replace = TRUE) names(feature_letters) <- rownames(x = pbmc_small[["RNA"]]) feature_letters_shuffled <- sample(x = feature_letters) test_that("AddMetaData adds feature level metadata", { pbmc_small[["RNA"]] <- AddMetaData(object = pbmc_small[["RNA"]], metadata = feature_letters, col.name = 'feature_letters') expect_equal(pbmc_small[["RNA"]][["feature_letters", drop = TRUE]], feature_letters) pbmc_small[["RNA"]] <- AddMetaData(object = pbmc_small[["RNA"]], metadata = feature_letters_shuffled, col.name = 'feature_letters_shuffled') expect_equal(pbmc_small[["RNA"]][["feature_letters", drop = TRUE]], pbmc_small[["RNA"]][["feature_letters_shuffled", drop = TRUE]]) }) feature_letters_df <- data.frame(A = feature_letters, B = feature_letters_shuffled) test_that("AddMetaData adds in data frame properly for Assays", { pbmc_small[["RNA"]] <- AddMetaData(object = pbmc_small[["RNA"]], metadata = feature_letters_df) expect_equal(pbmc_small[["RNA"]][[c("A", "B")]], feature_letters_df) }) test_that("AddMetaData errors", { expect_error(AddMetaData(object = pbmc_small, metadata = cluster_letters, col.name = "RNA")) # expect_error(AddMetaData(object = pbmc_small, metadata = c(unname(cluster_letters), "A"), col.name = "letter.idents")) expect_error(AddMetaData(object = pbmc_small, metadata = feature_letters, col.name = "letter.idents")) expect_error(AddMetaData(object = pbmc_small[["RNA"]], metadata = cluster_letters, col.name = "letter.idents")) }) # Tests for creating an Assay object # ------------------------------------------------------------------------------ context("CreateAssayObject") pbmc.raw <- GetAssayData(object = pbmc_small[["RNA"]], layer = "counts") rna.assay <- CreateAssayObject(counts = pbmc.raw) rna.assay2 <- CreateAssayObject(data = pbmc.raw) test_that("CreateAssayObject works as expected", { expect_equal(dim(x = rna.assay), c(230, 80)) expect_equal(rownames(x = rna.assay), rownames(x = pbmc.raw)) expect_equal(colnames(x = rna.assay), colnames(x = pbmc.raw)) expect_equal(GetAssayData(object = rna.assay, layer = "counts"), pbmc.raw) expect_equal(GetAssayData(object = rna.assay, layer = "data"), pbmc.raw) expect_equal(GetAssayData(object = rna.assay, layer = "scale.data"), new(Class = "matrix")) expect_equal(dim(rna.assay[[]]), c(230, 0)) expect_equal(rownames(x = rna.assay[[]]), rownames(x = rna.assay)) expect_equal(VariableFeatures(object = rna.assay), vector()) expect_equal(rna.assay@misc, list(calcN = TRUE)) expect_equal(GetAssayData(object = rna.assay2, layer = "counts"), new(Class = "matrix")) }) rna.assay2 <- CreateAssayObject(counts = pbmc.raw, min.cells = 10, min.features = 30) test_that("CreateAssayObject filtering works", { expect_equal(dim(x = rna.assay2), c(163, 77)) expect_true(all(rowSums(GetAssayData(object = rna.assay2, layer = "counts")) >= 10)) expect_true(all(colSums(GetAssayData(object = rna.assay2, layer = "counts")) >= 30)) }) test_that("CreateAssayObject catches improper input", { expect_error(CreateAssayObject()) expect_error(CreateAssayObject(counts = pbmc.raw, data = pbmc.raw)) pbmc.raw2 <- cbind(pbmc.raw[, 1:10], pbmc.raw[, 1:10]) expect_warning(CreateAssayObject(counts = pbmc.raw2)) expect_warning(CreateAssayObject(data = pbmc.raw2)) pbmc.raw2 <- rbind(pbmc.raw[1:10, ], pbmc.raw[1:10, ]) expect_warning(CreateAssayObject(counts = pbmc.raw2)) expect_warning(CreateAssayObject(data = pbmc.raw2)) pbmc.raw2 <- pbmc.raw colnames(x = pbmc.raw2) <- c() expect_error(CreateAssayObject(counts = pbmc.raw2)) expect_error(CreateAssayObject(data = pbmc.raw2)) pbmc.raw2 <- pbmc.raw rownames(x = pbmc.raw2) <- c() expect_error(CreateAssayObject(counts = pbmc.raw2)) expect_error(CreateAssayObject(data = pbmc.raw2)) pbmc.raw.mat <- as.matrix(x = pbmc.raw) pbmc.raw.df <- as.data.frame(x = pbmc.raw.mat) rna.assay3 <- CreateAssayObject(counts = pbmc.raw.df) rna.assay4 <- CreateAssayObject(counts = pbmc.raw.mat) expect_is(object = GetAssayData(object = rna.assay3, layer = "counts"), class = "dgCMatrix") expect_is(object = GetAssayData(object = rna.assay4, layer = "counts"), class = "dgCMatrix") pbmc.raw.underscores <- pbmc.raw rownames(pbmc.raw.underscores) <- gsub(pattern = "-", replacement = "_", x = rownames(pbmc.raw.underscores)) expect_warning(CreateAssayObject(counts = pbmc.raw.underscores)) }) # Tests for creating an DimReduc object # ------------------------------------------------------------------------------ context("CreateDimReducObject") pca <- pbmc_small[["pca"]] Key(object = pca) <- 'PC_' test_that("CreateDimReducObject works", { pca.dr <- CreateDimReducObject( embeddings = Embeddings(object = pca), loadings = Loadings(object = pca), projected = Loadings(object = pca, projected = TRUE), assay = "RNA" ) expect_equal(Embeddings(object = pca.dr), Embeddings(object = pca)) expect_equal(Loadings(object = pca.dr), Loadings(object = pca)) expect_equal(Loadings(object = pca.dr, projected = TRUE), Loadings(object = pca, projected = TRUE)) expect_equal(Key(object = pca.dr), "PC_") expect_equal(pca.dr@assay.used, "RNA") }) test_that("CreateDimReducObject catches improper input", { bad.embeddings <- Embeddings(object = pca) colnames(x = bad.embeddings) <- paste0("PCA", 1:ncol(x = bad.embeddings)) expect_warning(CreateDimReducObject(embeddings = bad.embeddings, key = "PC")) colnames(x = bad.embeddings) <- paste0("PC", 1:ncol(x = bad.embeddings), "X") suppressWarnings(expect_error(CreateDimReducObject(embeddings = bad.embeddings, key = "PC"))) suppressWarnings(expect_error(CreateDimReducObject(embeddings = bad.embeddings))) }) # Tests for creating a Seurat object # ------------------------------------------------------------------------------ context("CreateSeuratObject") colnames(x = pbmc.raw) <- paste0(colnames(x = pbmc.raw), "-", pbmc_small$groups) metadata.test <- pbmc_small[[]][, 5:7] rownames(x = metadata.test) <- colnames(x = pbmc.raw) test_that("CreateSeuratObject works", { seurat.object <- CreateSeuratObject( counts = pbmc.raw, project = "TESTING", assay = "RNA.TEST", names.field = 2, names.delim = "-", meta.data = metadata.test ) # expect_equal(seurat.object[[]][, 4:6], metadata.test) expect_equal(seurat.object[[names(x = metadata.test)]], metadata.test) expect_equal(seurat.object@project.name, "TESTING") expect_equal(names(x = seurat.object), "RNA.TEST") expect_equal(as.vector(x = unname(obj = Idents(object = seurat.object))), unname(pbmc_small$groups)) }) test_that("CreateSeuratObject handles bad names.field/names.delim", { expect_warning(seurat.object <- CreateSeuratObject( counts = pbmc.raw[1:5,1:5], names.field = 3, names.delim = ":", meta.data = metadata.test )) }) # Tests for creating a Seurat object # ------------------------------------------------------------------------------ context("Merging") pbmc.assay <- pbmc_small[["RNA"]] x <- merge(x = pbmc.assay, y = pbmc.assay) test_that("Merging Assays works properly", { expect_equal(dim(GetAssayData(object = x, layer = "counts")), c(230, 160)) expect_equal(dim(GetAssayData(object = x, layer = "data")), c(230, 160)) expect_equal(GetAssayData(object = x, layer = "scale.data"), new(Class = "matrix")) expect_equal(Key(object = x), "rna_") expect_equal(VariableFeatures(object = x), vector()) expect_equal(x[[]], data.frame(row.names = rownames(x = pbmc.assay))) }) pbmc.assay2 <- pbmc.assay pbmc.assay2@counts <- new("dgCMatrix") test_that("Merging Assays handles case when counts not present", { y <- merge(x = pbmc.assay2, y = pbmc.assay) expect_equal(unname(colSums(x = GetAssayData(object = y, layer = "counts"))[1:80]), rep.int(x = 0, times = 80)) z <- merge(x = pbmc.assay2, pbmc.assay2) expect_equal(Matrix::nnzero(x = GetAssayData(object = z, layer = "counts")), 0) }) pbmc.assay2 <- pbmc.assay pbmc.assay2@data <- new("dgCMatrix") test_that("Merging Assays handles case when data not present", { y <- merge(x = pbmc.assay2, y = pbmc.assay, merge.data = TRUE) expect_equal(unname(colSums(x = GetAssayData(object = y, layer = "data"))[1:80]), rep.int(x = 0, times = 80)) z <- merge(x = pbmc.assay2, y = pbmc.assay2, merge.data = TRUE) expect_equal(Matrix::nnzero(x = GetAssayData(object = z, layer = "data")), 0) }) # # Tests for Neighbor object # # ------------------------------------------------------------------------------ # context("Neighbor") # # # converting to Graph and back # # n.rann.ob <- NNHelper( # data = Embeddings(object = pbmc_small[["pca"]]), # query = Embeddings(object = pbmc_small[["pca"]]), # k = 10, # method = "rann") # # test_that("Neighbor object methods work", { # expect_equal(dim(x = Indices(object = n.rann.ob)), c(80, 10)) # expect_equal(dim(x = n.rann.ob), c(80, 10)) # expect_equal(as.numeric(Indices(object = n.rann.ob)[1, 7]), 45, ) # expect_equal(dim(x = Distances(object = n.rann.ob)), c(80, 10)) # expect_equal(as.numeric(Distances(object = n.rann.ob)[2, 2]), 2.643759, tolerance = 1e-6) # expect_equal(length(x = Cells(x = n.rann.ob)), 80) # expect_equal(Cells(x = n.rann.ob)[c(1, 20, 80)], c("ATGCCAGAACGACT", "TACATCACGCTAAC", "CTTGATTGATCTTC")) # pbmc_small[["n.ob"]] <- n.rann.ob # pbmc_small <- RenameCells(object = pbmc_small, add.cell.id = "test") # expect_equal(Cells(x = pbmc_small[['n.ob']])[1], c("test_ATGCCAGAACGACT")) # expect_equal(TopNeighbors(object = n.rann.ob, cell = "ATGCCAGAACGACT", n = 5)[5], "GATATAACACGCAT") # expect_equal(length(TopNeighbors(object = n.rann.ob, cell = "ATGCCAGAACGACT", n = 7)), 7) # nrg <- as.Graph(x = n.rann.ob) # expect_true(inherits(x = nrg, what = "Graph")) # expect_equal(as.numeric(Distances(object = n.rann.ob)[2, 3]), nrg[2, Indices(object = n.rann.ob)[2, 3]]) # nro2 <- as.Neighbor(x = nrg) # expect_true(inherits(x = nro2, what = "Neighbor")) # expect_equal(Distances(object = n.rann.ob)[2, 3], Distances(object = nro2)[2, 3]) # expect_equal(Indices(object = n.rann.ob)[1, 6], Indices(object = nro2)[1, 6]) # }) # # n.annoy.ob <- NNHelper( # data = Embeddings(object = pbmc_small[["pca"]]), # query = Embeddings(object = pbmc_small[["pca"]]), # k = 10, # method = "annoy", # cache.index = TRUE) # idx.file <- tempfile() # SaveAnnoyIndex(object = n.annoy.ob, file = idx.file) # nao2 <- LoadAnnoyIndex(object = n.annoy.ob, file = idx.file) # # test_that("Saving/Loading annoy index", { # expect_error(SaveAnnoyIndex(object = n.rann.ob, file = idx.file)) # expect_equal(head(Indices(n.annoy.ob)), head(Indices(nao2))) # expect_equal(head(Distances(n.annoy.ob)), head(Distances(nao2))) # expect_false(is.null(x = Index(nao2))) # }) # Tests for FetchData # ------------------------------------------------------------------------------ context("FetchData") # Features to test: # able to pull cell embeddings, data, metadata # subset of cells test_that("Fetching a subset of cells works", { x <- FetchData(object = pbmc_small, cells = colnames(x = pbmc_small)[1:10], vars = rownames(x = pbmc_small)[1]) expect_equal(rownames(x = x), colnames(x = pbmc_small)[1:10]) random.cells <- sample(x = colnames(x = pbmc_small), size = 10) x <- FetchData(object = pbmc_small, cells = random.cells, vars = rownames(x = pbmc_small)[1]) expect_equal(rownames(x = x), random.cells) x <- FetchData(object = pbmc_small, cells = 1:10, vars = rownames(x = pbmc_small)[1]) expect_equal(rownames(x = x), colnames(x = pbmc_small)[1:10]) }) suppressWarnings(pbmc_small[["RNA2"]] <- pbmc_small[["RNA"]]) Key(pbmc_small[["RNA2"]]) <- "rna2_" test_that("Fetching keyed variables works", { x <- FetchData(object = pbmc_small, vars = c(paste0("rna_", rownames(x = pbmc_small)[1:5]), paste0("rna2_", rownames(x = pbmc_small)[1:5]))) expect_equal(colnames(x = x), c(paste0("rna_", rownames(x = pbmc_small)[1:5]), paste0("rna2_", rownames(x = pbmc_small)[1:5]))) x <- FetchData(object = pbmc_small, vars = c(paste0("rna_", rownames(x = pbmc_small)[1:5]), paste0("PC_", 1:5))) expect_equal(colnames(x = x), c(paste0("rna_", rownames(x = pbmc_small)[1:5]), paste0("PC_", 1:5))) }) test_that("Fetching embeddings/loadings not present returns warning or errors", { expect_warning(FetchData(object = pbmc_small, vars = c("PC_1", "PC_100"))) expect_error(FetchData(object = pbmc_small, vars = "PC_100")) }) # bad.gene <- GetAssayData(object = pbmc_small[["RNA"]], slot = "data") # rownames(x = bad.gene)[1] <- paste0("rna_", rownames(x = bad.gene)[1]) # pbmc_small[["RNA"]]@data <- bad.gene # Tests for WhichCells # ------------------------------------------------------------------------------ test_that("Specifying cells works", { test.cells <- Cells(x = pbmc_small)[1:10] expect_equal(WhichCells(object = pbmc_small, cells = test.cells), test.cells) expect_equal(WhichCells(object = pbmc_small, cells = test.cells, invert = TRUE), setdiff(Cells(x = pbmc_small), test.cells)) }) test_that("Specifying idents works", { c12 <- WhichCells(object = pbmc_small, idents = c(1, 2)) expect_equal(length(x = c12), 44) expect_equal(c12[44], "CTTGATTGATCTTC") expect_equal(c12, WhichCells(object = pbmc_small, idents = 0, invert = TRUE)) }) test_that("downsample works", { expect_equal(length(x = WhichCells(object = pbmc_small, downsample = 5)), 15) expect_equal(length(x = WhichCells(object = pbmc_small, downsample = 100)), 80) expect_equal(dim(LayerData(subset(pbmc_small, cells = 1))), c(230L, 1L)) }) test_that("passing an expression works", { lyz.pos <- WhichCells(object = pbmc_small, expression = LYZ > 1) expect_true(all(GetAssayData(object = pbmc_small, layer = "data")["LYZ", lyz.pos] > 1)) # multiple values in expression lyz.pos <- WhichCells(object = pbmc_small, expression = LYZ > 1 & groups == "g1") expect_equal(length(x = lyz.pos), 30) expect_equal(lyz.pos[30], "CTTGATTGATCTTC") }) # Tests for small other functions # ------------------------------------------------------------------------------ test_that("Top works", { dat <- Embeddings(object = pbmc_small[['pca']])[, 1, drop = FALSE] expect_warning(Top(data = dat, num = 1000, balanced = FALSE)) tpc1 <- Top(data = dat, num = 20, balanced = FALSE) expect_equal(length(x = tpc1), 20) expect_equal(tpc1[1], "ACGTGATGCCATGA") expect_equal(tpc1[20], "GTCATACTTCGCCT") tpc1b <- Top(data = dat, num = 20, balanced = TRUE) expect_equal(length(x = tpc1b), 2) expect_equal(names(tpc1b), c("positive", "negative")) expect_equal(length(tpc1b[[1]]), 10) expect_equal(length(tpc1b[[2]]), 10) expect_equal(tpc1b[[1]][1], "GTCATACTTCGCCT") expect_equal(tpc1b[[1]][10], "CTTGATTGATCTTC") expect_equal(tpc1b[[2]][1], "ACGTGATGCCATGA") expect_equal(tpc1b[[2]][10], "ATTGTAGATTCCCG") tpc1.sub <- Top(data = dat[1:79, , drop = FALSE], num = 79, balanced = TRUE) expect_equal(length(tpc1.sub[[1]]), 40) expect_equal(length(tpc1.sub[[2]]), 39) }) # Tests for UpdateSeuratObject # ---------------------------------------------------------------------------- context("UpdateSeuratObject") pbmc_small_no_key <- pbmc_small slot(slot(pbmc_small_no_key, "assays")$RNA, "key") <- character(0) slot(slot(pbmc_small_no_key, "assays")$RNA2, "key") <- character(0) slot(slot(pbmc_small_no_key, "reductions")$pca, "key") <- character(0) test_that("Update keys works", { pbmc_small_no_key <- suppressWarnings(UpdateSeuratObject(pbmc_small_no_key)) expect_equal(Key(pbmc_small_no_key[["RNA"]]), "RNA_") expect_equal(Key(pbmc_small_no_key[["RNA2"]]), "RNA2_") expect_equal(Key(pbmc_small_no_key[["pca"]]), "pca_") expect_equal(Key(pbmc_small_no_key[["tsne"]]), "tSNE_") }) SeuratObject/tests/testthat/test_seurat.R0000644000176200001440000001570515114353666020355 0ustar liggesusers#' Returns a random counts matrix. get_random_counts <- function(ncells, nfeatures) { # Instantiate an empty nfeatures by ncells matrix. counts <- matrix(NA, ncol = ncells, nrow = nfeatures) # Populate the matrix one row at a time by generating a negative # binomial distribution using a random `mu` between 0.1 and 10. for (i in 1:nfeatures) { mu <- runif(1, min = 0.1, max = 10) counts[i, ] <- values <- rnbinom(ncells, mu = mu, size = 1) } # Assign column and row names to the matrix to label cells and genes. colnames(counts) <- paste0("cell", seq(ncol(counts))) row.names(counts) <- paste0("gene", seq(nrow(counts))) # Convert `counts` to a `dgCMatrix`. counts_sparse <- as.sparse(counts) return(counts_sparse) } context("merge") test_that("`merge` works with multi-assay inputs", { # Run checks against `Assay` and `Assay5` instances. for (assay_version in c("v5")) { create_assay <- switch(assay_version, v3 = CreateAssayObject, v5 = CreateAssay5Object, stop("`assay_version` should be one of 'v3', 'v5'") ) # Populate a `Seurat` instance with two assays, "LEFT" and "RIGHT". counts_LEFT_A <- get_random_counts(ncells = 10, nfeatures = 10) input_A <- CreateSeuratObject( create_assay(counts_LEFT_A), assay = "LEFT", project = "A" ) counts_RIGHT_A <- get_random_counts(ncells = 10, nfeatures = 10) input_A[["RIGHT"]] <- create_assay(counts_RIGHT_A) # Populate a second `Seurat` instance with a single assay, "LEFT". counts_LEFT_B <- get_random_counts(ncells = 5, nfeatures = 5) input_B <- CreateSeuratObject( create_assay(counts_LEFT_B), assay = "LEFT", project = "B" ) # Populate a third `Seurat` instance with two assays, "LEFT" and "RIGHT". counts_LEFT_C <- get_random_counts(ncells = 5, nfeatures = 5) input_C <- CreateSeuratObject( create_assay(counts_LEFT_C), assay = "LEFT", project = "C" ) counts_RIGHT_C <- get_random_counts(ncells = 5, nfeatures = 5) input_C[["RIGHT"]] <- create_assay(counts_RIGHT_C) # Merge the three `Seurat` instances. result <- expect_warning( merge(input_A, c(input_B, input_C)), paste( "Some cell names are duplicated across objects provided.", "Renaming to enforce unique cell names." ) ) # If we have an `Assay` input, split it into multiple layers if (assay_version == "v3") { result <- expect_warning(split(result, f = Idents(result))) } # Check that the result layers are named according to their project values. expected_layers <- c("counts.A", "counts.B", "counts.C") expect_identical(Layers(result[["LEFT"]]), expected_layers) expected_layers <- c("counts.A", "counts.C") expect_identical(Layers(result[["RIGHT"]]), expected_layers) # Check that the "LEFT" assay contains the expected cell names. expected_cells <- c( paste0("cell", seq(10), "_1"), paste0("cell", seq(5), "_2"), paste0("cell", seq(5), "_3") ) expect_identical(Cells(result[["LEFT"]]), expected_cells) # Check that the "RIGHT" assay contains the expected cell names. expected_cells <- c( paste0("cell", seq(10), "_1"), paste0("cell", seq(5), "_3") ) expect_identical(Cells(result[["RIGHT"]]), expected_cells) # Check that the values for "counts.A" in the "LEFT" assay are preserved. expected_counts <- counts_LEFT_A colnames(expected_counts) <- paste0("cell", seq(10), "_1") expect_identical( LayerData(result, assay = "LEFT", layer = "counts.A"), expected_counts ) # Check that the values for "counts.B" in the "LEFT" assay are preserved. expected_counts <- counts_LEFT_B colnames(expected_counts) <- paste0("cell", seq(5), "_2") observed_counts <- LayerData(result, assay = "LEFT", layer = "counts.B") expect_identical( observed_counts, expected_counts, info = dim(expected_counts) ) # Check that the values for "counts.C" in the "LEFT" assay are preserved. expected_counts <- counts_LEFT_C colnames(expected_counts) <- paste0("cell", seq(5), "_3") expect_identical( LayerData(result, assay = "LEFT", layer = "counts.C"), expected_counts, info = assay_version ) # Check that the values for "counts.A" in the "RIGHT" assay are preserved. expected_counts <- counts_RIGHT_A colnames(expected_counts) <- paste0("cell", seq(10), "_1") expect_identical( LayerData(result, assay = "RIGHT", layer = "counts.A"), expected_counts ) # Check that the values for "counts.C" in the "RIGHT" assay are preserved. expected_counts <- counts_RIGHT_C colnames(expected_counts) <- paste0("cell", seq(5), "_3") expect_identical( LayerData(result, assay = "RIGHT", layer = "counts.C"), expected_counts, info = assay_version ) } }) context("RenameCells") test_that("`RenameCells` works with multi-assay inputs", { counts <- get_random_counts(ncells = 10, nfeatures = 10) # Run checks against `Assay` and `Assay5` instances. for (assay_version in c("v3", "v5")) { create_assay <- switch(assay_version, v3 = CreateAssayObject, v5 = CreateAssay5Object, stop("`assay_version` should be one of 'v3', 'v5'") ) counts_left <- counts[, 1:5] assay_left <- create_assay(counts_left) left <- CreateSeuratObject(assay_left) counts_right <- counts[, 6:10] assay_right <- create_assay(counts_right) right <- CreateSeuratObject(assay_right, assay = "right") test_case <- merge(left, right) old_names <- colnames(test_case) # Rename all the cells in the input using `add.cell.id`. new_names <- paste0("new_cell", 1:10) result <- RenameCells(test_case, add.cell.id = "new") expect_identical(colnames(result), new_names) # Rename all the cells in the input using `new.names`. new_names <- paste0("new-cell", 1:10) result <- RenameCells(test_case, new.names = new_names) expect_identical(colnames(result), new_names) # Rename just the cells in the input's default assay. new_names <- paste0("new-cell", 1:5) expected_names <- c(new_names, tail(old_names, n = 5)) result <- RenameCells(test_case, new.names = new_names) expect_identical(colnames(result), expected_names) # Rename a subset of cells across both assays. new_names <- paste0("new-cell", 2:9) expected_names <- c(head(old_names, n = 1), new_names, tail(old_names, n = 1)) # Requires a named vector to be passed to `new.names`. expect_error(RenameCells(test_case, new.names = new_names)) names(new_names) <- old_names[2:9] result <- RenameCells(test_case, new.names = new_names) expect_identical(colnames(result), expected_names) # All cells provided in a named vector mapping must exist. new_names <- paste0("new-cell", 1:10) names(new_names) <- c("not-a-cell", tail(old_names, n = 1)) expect_error(RenameCells(test_case, new.names = new_names)) } }) SeuratObject/tests/testthat/test_matrix.R0000644000176200001440000000141015116566601020337 0ustar liggesusers# Tests for matrix checks data("pbmc_small") pbmc_small <- suppressWarnings(suppressMessages(UpdateSeuratObject(pbmc_small))) counts <- GetAssayData(pbmc_small, assay = "RNA", layer = "counts") test_that("CheckMatrix works for valid matrix", { expect_null(CheckMatrix(counts)) }) test_that("CheckMatrix warns for non-integer counts", { counts[1,1] <- 1/2 expect_warning(CheckMatrix(counts)) }) test_that("CheckMatrix warns for NA values", { counts[1,1] <- NA expect_warning(CheckMatrix(counts)) }) test_that("CheckMatrix warns for NaN values", { counts[1,1] <- NaN expect_warning(CheckMatrix(counts)) }) test_that("CheckMatrix warns for logical values", { counts <- as(object = counts, Class = "lsparseMatrix") expect_warning(CheckMatrix(counts)) }) SeuratObject/tests/testthat/test_assay5.R0000644000176200001440000003764315114353666020264 0ustar liggesusers#' Returns a random counts matrix. get_test_assay <- function(ncells, nfeatures, assay_version) { # Use the `assay_version` param to choose the correct assay builder. create_assay <- switch(assay_version, v3 = CreateAssayObject, v5 = CreateAssay5Object, stop("`assay_version` should be one of 'v3', 'v5'") ) # Populate a `nfeatures` x `ncells` matrix with zeros. counts <- matrix(0, ncol = ncells, nrow = nfeatures) # Assign column and row names to the matrix to label cells and genes. colnames(counts) <- paste0("cell", seq(ncol(counts))) row.names(counts) <- paste0("gene", seq(nrow(counts))) # Convert `counts` to a `dgCMatrix`. counts_sparse <- as.sparse(counts) # Build an assay of the specified type. assay <- create_assay(counts_sparse) return(assay) } #' Mocks "highly variable feature" annotations and adds them to the #' feature-level metadata of `assay`. add_hvf_info <- function( assay, nfeatures = NULL, features = NULL, method_name, layer_name ) { if (is.null(nfeatures) & is.null(features)) { # Ensure that one of `nfeatures` or `features` is set. stop("One of `nfeatures` or `features` must be provided.") } else if (!is.null(nfeatures) & !is.null(features)) { # Ensure that only one of `nfeatures` or `features` is set. stop("Only one of `nfeatures` or `feature` may be provided.") } else if (!is.null(nfeatures)) { # If `nfeatures` is provided, randomly sample from the `assay`'s features. variable_features <- sample( rownames(assay), size = nfeatures, replace = FALSE ) } else { # If `features` was provided, use it. variable_features <- features } all_features <- rownames(assay) constant_features <- setdiff(all_features, variable_features) # Add a column to the assay's feature-level metadata indicating which # features are variable. is_variable <- all_features %in% variable_features names(is_variable) <- all_features variable_column <- paste("vf", method_name, layer_name, "variable", sep = "_") assay[[variable_column]] <- is_variable # Add a column to the assay's feature-level metadata indicating the order # (i.e. "rank") that each variable feature was selected in. variable_rank <- seq_along(variable_features) names(variable_rank) <- variable_features constant_rank <- seq_along(constant_features) + length(variable_features) names(constant_rank) <- constant_features feature_rank <- c(variable_rank, constant_rank) rank_column <- paste("vf", method_name, layer_name, "rank", sep = "_") assay[[rank_column]] <- feature_rank # Add a column to the assay's feature-level metadata containing a random # values in reverse order from `variable_rank` (i.e. the lowest rank # has the highest value). feature_values <- runif(length(all_features)) feature_values <- sort(feature_values, decreasing = TRUE) names(feature_values) <- names(feature_rank) value_column <- paste("vf", method_name, layer_name, "value", sep = "_") assay[[value_column]] <- feature_values return(assay) } context("HVFInfo") test_that("`HVFInfo.Assay5` works with a single set of metadata", { # Populate an assay with random values for testing. assay <- get_test_assay( ncells = 10, nfeatures = 10, assay_version = "v5" ) # Add similarly random HVF metadata to `assay`. assay <- add_hvf_info( assay, nfeatures = 10, method_name = "vst", layer_name = "counts" ) # Extract the expected HVFInfo and rename the columns. info_columns <- c( "vf_vst_counts_variable", "vf_vst_counts_rank", "vf_vst_counts_value" ) expected_info <- assay[[]][, info_columns] colnames(expected_info) <- c("variable", "rank", "value") # Check the base case where `method` and `layer` are both set and valid. result <- HVFInfo(assay, method = "vst", layer = "counts") expect_identical(result, expected_info["value"]) # Check the same case with all relevant HVF columns returned. result <- HVFInfo(assay, method = "vst", layer = "counts", status = TRUE) expect_identical(result, expected_info) # Check that `layer` can be omitted. result <- HVFInfo(assay, method = "vst") expect_identical(result, expected_info["value"]) # Check that `layer` can be `NULL`. result <- HVFInfo(assay, method = "vst", layer = NULL) expect_identical(result, expected_info["value"]) # Check that `layer` can be `NA`. result <- HVFInfo(assay, method = "vst", layer = NA) expect_identical(result, expected_info["value"]) # Check that the `method` parameter can be omitted. result <- HVFInfo(assay) expect_identical(result, expected_info["value"]) # Check that `NULL` is returned if `method` does not point HVF metadata. result <- expect_warning( HVFInfo(assay, method = "not-a-method"), paste( "Unable to find highly variable feature information for", "method='not-a-method' and layer='NA'." ) ) expect_null(result) result <- expect_warning( HVFInfo(assay, method = "not-a-method", layer = "counts"), paste( "Unable to find highly variable feature information for", "method='not-a-method' and layer='counts'." ) ) expect_null(result) }) test_that("`HVFInfo.Assay5` works with multiple methods run on different layers", { # Populate an assay with random values for testing. assay <- get_test_assay( ncells = 10, nfeatures = 10, assay_version = "v5" ) # Add similarly random HVF metadata to `assay`. assay <- add_hvf_info( assay, nfeatures = 5, method_name = "vst", layer_name = "counts" ) # Add a second "data" layer to the assay by duplicating "count". LayerData(assay, layer = "data") <- LayerData(assay, layer = "counts") # Add a second set of HVF columns to `assay`. assay <- add_hvf_info( assay, nfeatures = 5, method_name = "mvp", layer_name = "data" ) # Extract the first set of HVF info and rename the columns. vst_columns <- c( "vf_vst_counts_variable", "vf_vst_counts_rank", "vf_vst_counts_value" ) vst_info <- assay[[]][, vst_columns] colnames(vst_info) <- c("variable", "rank", "value") # Extract the first set of HVF info and rename the columns. mvp_columns <- c( "vf_mvp_data_variable", "vf_mvp_data_rank", "vf_mvp_data_value" ) mvp_info <- assay[[]][, mvp_columns] colnames(mvp_info) <- c("variable", "rank", "value") # Check the base case where `method` and `layer` are both set and valid. result <- HVFInfo(assay, method = "vst", layer = "counts") expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp", layer = "data") expect_identical(result, mvp_info["value"]) # Check that `layer` can be omitted. In this case, `layer` will default to # `NA` which will be in turn be interpreted as `Layers(assay)` (i.e. all layers). result <- HVFInfo(assay, method = "vst") expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp") expect_identical(result, mvp_info["value"]) # Check that `layer` can be `NULL`. In this case, `layer` will be interpreted # as `DefaultLayer(assay)`. Thus, we are expected `layer` to resolve to "counts". result <- HVFInfo(assay, method = "vst", layer = NULL) expect_identical(result, vst_info["value"]) result <- expect_warning( HVFInfo(assay, method = "mvp", layer = NULL), paste( "Unable to find highly variable feature information for", "method='mvp' and layer='NULL'." ) ) expect_null(result) # Check that `layer` can be `NA`. In this case, `layer` will be interpreted # as `Layers(assay)` (i.e. all layers). result <- HVFInfo(assay, method = "vst", layer = NA) expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp", layer = NA) expect_identical(result, mvp_info["value"]) }) test_that("`HVFInfo.Assay5` works with a single method run on multiple layers", { # Populate an assay with random values for testing. assay <- get_test_assay( ncells = 10, nfeatures = 10, assay_version = "v5" ) # Split the "counts" layer in half across it's columns and drop the original layer. LayerData(assay, layer = "counts.1") <- LayerData(assay, layer = "counts")[, 1:5] LayerData(assay, layer = "counts.2") <- LayerData(assay, layer = "counts")[, 5:10] # Since it's first, "counts.1" would be chosen as the default layer when # "counts" is dropped but we'll do it explicitly (also avoids a warning). DefaultLayer(assay) <- "counts.1" LayerData(assay, layer = "counts") <- NULL # Add random HVF metadata for each layer. By adding "counts.2" before "counts.1" # we introduce discrepancy between the behavior of `layer = NULL` and `layer = NA`. assay <- add_hvf_info( assay, nfeatures = 5, method_name = "vst", layer_name = "counts.2" ) assay <- add_hvf_info( assay, nfeatures = 5, method_name = "vst", layer_name = "counts.1" ) # Extract the first set of HVF info and rename the columns. vst.1_columns <- c( "vf_vst_counts.1_variable", "vf_vst_counts.1_rank", "vf_vst_counts.1_value" ) vst.1_info <- assay[[]][, vst.1_columns] colnames(vst.1_info) <- c("variable", "rank", "value") # Extract the second set of HVF info and rename the columns. vst.2_columns <- c( "vf_vst_counts.2_variable", "vf_vst_counts.2_rank", "vf_vst_counts.2_value" ) vst.2_info <- assay[[]][, vst.2_columns] colnames(vst.2_info) <- c("variable", "rank", "value") # Check the base case where `method` and `layer` are both set and valid. result <- HVFInfo(assay, method = "vst", layer = "counts.1") expect_identical(result, vst.1_info["value"]) result <- HVFInfo(assay, method = "vst", layer = "counts.2") expect_identical(result, vst.2_info["value"]) # Check that `layer` can be omitted. In this case, `layer` will default to # `NULL` which will be in turn be interpreted as `Layers(assay)` # (i.e. all layers). Thus, we are expected `layer` to resolve to "counts.2". result <- HVFInfo(assay, method = "vst") expect_identical(result, vst.2_info["value"]) # Check that `layer` can be `NULL`. In this case, `layer` will be interpreted # as `DefaultLayer(assay)`. Thus, we are expected `layer` to resolve to "counts". result <- HVFInfo(assay, method = "vst", layer = NULL) expect_identical(result, vst.1_info["value"]) # Check that `layer` can be `NA`. In this case, `layer` will be interpreted # as `Layers(assay)` (i.e. all layers) and the first one associated with # `method` will be returned. result <- HVFInfo(assay, method = "vst", layer = NA) expect_identical(result, vst.2_info["value"]) }) test_that("`HVFInfo.Assay5` works with multiple methods run on the same layer", { # Populate an assay with random values for testing. assay <- get_test_assay( ncells = 10, nfeatures = 10, assay_version = "v5" ) # Add similarly random HVF metadata to `assay`. assay <- add_hvf_info( assay, nfeatures = 5, method_name = "vst", layer_name = "counts" ) # Add a second set of HVF columns to `assay`. assay <- add_hvf_info( assay, nfeatures = 5, method_name = "mvp", layer_name = "counts" ) # Extract the first set of HVF info and rename the columns. vst_columns <- c( "vf_vst_counts_variable", "vf_vst_counts_rank", "vf_vst_counts_value" ) vst_info <- assay[[]][, vst_columns] colnames(vst_info) <- c("variable", "rank", "value") # Extract the first set of HVF info and rename the columns. mvp_columns <- c( "vf_mvp_counts_variable", "vf_mvp_counts_rank", "vf_mvp_counts_value" ) mvp_info <- assay[[]][, mvp_columns] colnames(mvp_info) <- c("variable", "rank", "value") # Check the base case where `method` and `layer` are both set and valid. result <- HVFInfo(assay, method = "vst", layer = "counts") expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp", layer = "counts") expect_identical(result, mvp_info["value"]) # Check the same case with all relevant HVF columns returned. result <- HVFInfo(assay, method = "vst", layer = "counts", status = TRUE) expect_identical(result, vst_info) result <- HVFInfo(assay, method = "mvp", layer = "counts", status = TRUE) expect_identical(result, mvp_info) # Check that `layer` can be omitted. In this case, `layer` will default to # `NULL` which will be in turn be interpreted as `DefaultLayer(assay)`. # Thus, we are expected `layer` to resolve to "counts". result <- HVFInfo(assay, method = "vst") expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp") expect_identical(result, mvp_info["value"]) # Check that `layer` can be `NULL`. In this case, `layer` will be interpreted # as `DefaultLayer(assay)`. Thus, we are expected `layer` to resolve to "counts". result <- HVFInfo(assay, method = "vst", layer = NULL) expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp", layer = NULL) expect_identical(result, mvp_info["value"]) # Check that `layer` can be `NA`. In this case, `layer` will be interpreted # as `Layers(assay)` (i.e. all layers). result <- HVFInfo(assay, method = "vst", layer = NA) expect_identical(result, vst_info["value"]) result <- HVFInfo(assay, method = "mvp", layer = NA) expect_identical(result, mvp_info["value"]) }) context("VariableFeatures") test_that("`VariableFeatures.Assay5` getter/setter works as expected", { # Populate an assay with random values for testing. assay <- get_test_assay( ncells = 10, nfeatures = 10, assay_version = "v5" ) # Set initial variable features (including some missing values). test_features <- c(gene1 = "gene1", gene3 = "gene3", gene5 = "gene5") assay[["var.features"]] <- test_features expected_features <- c("gene1", "gene3", "gene5") expect_identical(VariableFeatures(assay), expected_features) expect_identical(VariableFeatures(assay, nfeatures = 2), expected_features[1:2]) # Set the ranking for the variable features. test_rank <- c(gene1 = 3, gene3 = 1, gene5 = 2) assay[["var.features.rank"]] <- test_rank expected_features <- c("gene3", "gene5", "gene1") expect_identical(VariableFeatures(assay), expected_features) expect_identical(VariableFeatures(assay, nfeatures = 2), expected_features[1:2]) # Use the VariableFeatures setter to overwrite the current variable features. expected_features <- c("gene10", "gene2", "gene8") VariableFeatures(assay) <- expected_features expect_identical(VariableFeatures(assay), expected_features) }) test_that("`VariableFeatures` works with multi-layer assays", { # Populate an assay with random values for testing. assay <- get_test_assay( ncells = 9, nfeatures = 10, assay_version = "v5" ) # Split the "counts" layer in thirds across it's columns and drop the original layer. LayerData(assay, layer = "counts.1") <- LayerData(assay, layer = "counts")[, 1:3] # Leave "gene10" out of "counts.2" so that it cannot be called variable. LayerData(assay, layer = "counts.2") <- LayerData(assay, layer = "counts")[1:9, 4:6] LayerData(assay, layer = "counts.3") <- LayerData(assay, layer = "counts")[, 7:9] # Since it's first, "counts.1" would be chosen as the default layer when # "counts" is dropped but we'll do it explicitly (also avoids a warning). DefaultLayer(assay) <- "counts.1" LayerData(assay, layer = "counts") <- NULL # Add HVF metadata to each layer. assay <- add_hvf_info( assay, features = c("gene1", "gene2", "gene3"), method_name = "vst", layer_name = "counts.1" ) assay <- add_hvf_info( assay, features = c("gene3", "gene2", "gene4"), method_name = "vst", layer_name = "counts.2" ) assay <- add_hvf_info( assay, features = c("gene1", "gene2", "gene10"), method_name = "vst", layer_name = "counts.3" ) # Expect the consensus (aggregated) variable features from the # multi-layer assay. expected_features <- c("gene2", "gene1", "gene3", "gene4") expect_identical(VariableFeatures(assay), expected_features) expect_identical(VariableFeatures(assay, nfeatures = 2), expected_features[1:2]) }) SeuratObject/tests/testthat/test_logmap.R0000644000176200001440000000467215114353666020332 0ustar liggesusers# Tests for the LogMap class test_that("`labels` generic works as expected for `LogMap` instances", { # Instantiate and populate a LogMap instance for testing. map <- LogMap(paste0("value_", 1:6)) map[["label_a"]] <- c(1, 3) map[["label_b"]] <- c(2, 4) map[["label_c"]] <- c(2, 4, 6) map[["label_d"]] <- c(2, 4, 6) map[["label_e"]] <- 2 map[["label_f"]] <- 4 # Labels can be fetched for specified values. values <- c("value_1", "value_3") result_key <- c(value_1 = "label_a", value_3 = "label_a") expect_identical(result_key, labels(map, values = values)) # For values with multiple labels, the first label is returned by default. values <- c("value_2", "value_4") result_key <- c(value_2 = "label_b", value_4 = "label_b") result <- labels(map, values = values) expect_identical(result_key, result) # The last value for each label can also be fetched. values <- c("value_1", "value_2", "value_4") result_key <- c(value_1 = "label_a", value_2 = "label_e", value_4 = "label_f") result <- labels(map, values = values, select = "last") expect_identical(result_key, result) # It is also possible to fetch the label that is shared by the most values # in the requested set. If multiple labels are equally common, the first # is returned. values <- c("value_2", "value_4", "value_6") result_key <- c(value_2 = "label_c", value_4 = "label_c", value_6 = "label_c") result <- labels(map, values = values, select = "common") expect_identical(result_key, result) # Label resolution is based on the column order of the underlying matrix label_order <- c( "label_a", "label_e", "label_b", "label_c", "label_e", "label_f" ) map <- map[, label_order, drop = FALSE] values <- c("value_2", "value_4") result_key <- c(value_2 = "label_e", value_4 = "label_b") result <- labels(map, values = values) expect_identical(result_key, result) # The output order is taken from the `values` parameter. values <- c("value_3", "value_1") result_key <- c(value_3 = "label_a", value_1 = "label_a") result <- labels(map, values = values) expect_identical(result_key, result) # Values without labels are excluded in the return. values <- c("value_1", "value_5", "value_6") result_key <- c(value_1 = "label_a", value_6 = "label_c") result <- labels(map, values = values) expect_identical(result_key, result) # If no labels are found, an error is raised. expect_error(labels(map, "value_5")) }) SeuratObject/tests/testthat.R0000644000176200001440000000010415114353666015776 0ustar liggesuserslibrary(testthat) library(SeuratObject) test_check("SeuratObject") SeuratObject/MD50000644000176200001440000004104015117034671013160 0ustar liggesusersd9b760d605aa3f7f9e31f5da5dcadda8 *DESCRIPTION 51a445d321e29ebb29fee2b069584f4b *LICENSE 17ad51d0f4368f283fcc9a78ea1e04c3 *NAMESPACE 59d3309047326f6092d38c7677a13433 *NEWS.md 34df10962de6a9e289b4adad0cf5eaef *R/RcppExports.R 66d0d765beb1a972daef4131088ac166 *R/assay.R c6a63258cdcbf4046b10c5e854f17d1b *R/assay5.R cc2128015347765a925fca71769a8798 *R/centroids.R 2c03d1c86e1284ed38bb114fea2faa21 *R/command.R fb8ad1532db9bd7eca87452ed678c606 *R/compliance.R 6781cef8ac1b25be2ad906c322e5ddda *R/data.R da55d8b58e7466bc4e4481e56bf484ab *R/default.R 52c048078a1e511ea7ec878743004893 *R/dimreduc.R 49ed41bfad630cf370946b7b18b6d6cc *R/fov.R 2e658143c837e541c16c326f993f3d0f *R/generics.R f71882fa33101484a69c20ef89040b6e *R/graph.R 58b8af27bef1b9d90d5709917ee214c4 *R/jackstraw.R 9d9d49145f89bf5d63e4a4002fea1666 *R/keymixin.R 1157c919d0115653ff067468bed0cd89 *R/layers.R 12da7f571f29632c9f5a26b1dbe5122c *R/logmap.R d525e66963ea78c0c5ba6696f4e51b67 *R/molecules.R 0f139db2cbaa3f733eeedc81534786a2 *R/neighbor.R 119e201daf76013ff1d2d062390c244c *R/segmentation.R d5428f7b87b404a9d22cff6205c4e34a *R/seurat.R be58ca9eef077e177e46994d21be2065 *R/sparse.R 146047742c95f51380758d91fee30619 *R/spatial.R 81cabdef8f6539ba02acbfc862c69413 *R/utils.R 4d8bfa12d175e4906562b132971d50e3 *R/zzz.R 1c07e7cebcba5f42abc787bd2912fc3d *build/SeuratObject.pdf e018a90b41532513da300eb8c1620b41 *build/partial.rdb 9037cac5a7562d0efc6a0bd40ed6abf3 *build/stage23.rdb 674c3364ad5d96d39b25c4cd5b40af1d *data/pbmc_small.rda f9ed0d71ce9f608edf31cc596e158c0c *man/AddMetaData-StdAssay.Rd f010121c9383289cdc4505f3f7c58eaa *man/AddMetaData.Rd 616d3e66ec85872667b668056d0c4378 *man/Assay-class.Rd 2b40f84c0d9ddb44368db0e38d915b9b *man/Assay-validity.Rd 6a7f2e21971ec5013223f7224498329e *man/Assay5-class.Rd 03aee82cbdc82eaa3894496be4783ba7 *man/Assay5-validity.Rd a3b8624fc2eb59997a2b8b606b387521 *man/Assay5T-class.Rd d36c30ccbb0c33e073f94905e56b2ca6 *man/AssayData-StdAssay.Rd 06de3eba0589f9cd88cacd81f679f940 *man/AssayData.Rd 70c614c9e5a38193c1464f01c7e260ac *man/AttachDeps.Rd ee65335c0b739ea9812006076a1d1f1d *man/Boundaries.Rd 7fe1b8b5e4bc9e5f986fabd9b2571465 *man/CastAssay-StdAssay.Rd dca50051ef7bd80d6190958c86e1b378 *man/CastAssay.Rd e8ce966ddbb660b3808dff4bb27f0490 *man/Cells-StdAssay.Rd add1c6d2fda097c1915714722087717a *man/Cells.Rd 3c6674d8cc1ffd49fdd68ea7054dc8b0 *man/CellsByIdentities.Rd 62f8158d220be99ebf294149a990869d *man/CellsByImage.Rd 718a7751f85178f6e354ab97e2ec1d86 *man/Centroids-class.Rd c39777496fed3c50360b54a444024097 *man/Centroids-methods.Rd b397cd0c29e6f69bf7ed25db340db929 *man/CheckDots.Rd aa780001dc7540239a4c5696163676a0 *man/CheckFeaturesNames.Rd da8078655056e8130c36c9cb7ba29bd1 *man/CheckGC.Rd 6dd14944650da89abd266e80f2ba4359 *man/CheckLayersName.Rd 75c9a6b2472f5fe44852c20e25c57bfb *man/CheckMatrix.Rd ed97979931f325e7d354148937f658b2 *man/ClassKey.Rd 07575870555b49149ac81395bb3bb397 *man/Command.Rd fd47e3d81c1a12c02576753bdc8fb8dc *man/CreateAssay5Object.Rd ac5923f61c65ffd9f9e88b75a7351e97 *man/CreateAssayObject.Rd 056dc3ab9a4117dbcdfc6ccc798066c1 *man/CreateCentroids.Rd c71553f2101a5b05f97ac6b6f249d5d0 *man/CreateDimReducObject.Rd a3912a3bb32892c7848ee0537277fe8e *man/CreateFOV.Rd b02fdbbeec7fa4c3bbe58b5a0ce147aa *man/CreateMolecules.Rd 121ba8fcaa44cc2d3de1c7d9fd051bf5 *man/CreateSegmentation.Rd a9186d1a9e9ac0c8f122f33ca510cb21 *man/CreateSeuratObject.Rd c21445135a11a1232e04b19268a13d86 *man/Crop.Rd e287a29557ef3c1fb37d0b50a7b6ce50 *man/DefaultAssay-StdAssay.Rd d68695d6866bd6c4b10db544e2131ca3 *man/DefaultAssay.Rd be193086f8b6b08418051b4b139d12aa *man/DefaultDimReduc.Rd 4030ae62870bab574a9e2021fb85a008 *man/DefaultFOV.Rd 0af832dbabbd34508e6d8dacca8d6254 *man/DefaultLayer-StdAssay.Rd b789aa4ae023bda9750f3c5accd59f7d *man/DefaultLayer.Rd aa35a63f7b32d31f9c5d3ceaa9949c3d *man/DimReduc-class.Rd 8d6989c456d8c080b684d70e044f7f76 *man/DimReduc-validity.Rd 3fbbf118376bc55e71b62459f214a0cb *man/Distances.Rd 2eec1b225da7d23d2ab12169c6da56b5 *man/Embeddings.Rd e5fbe83d0d833d15c572606cdc35d37b *man/EmptyDF.Rd 0d8b22181b0eb318976e8652f2a99f0f *man/EmptyMatrix.Rd 67b1189672717126cf9b551ddfd59223 *man/ExtractField.Rd f5a0157c94613ec5d251841e30d99281 *man/FOV-class.Rd 5b57d2433f9b974cfe2259ba4f2ab1be *man/FOV-methods.Rd 557c7ee742562e24c62ccd2893016794 *man/FOV-validity.Rd b492ee39d81ad910010e8ad89d0bd323 *man/FetchData.Rd df3c84658c30c964b7edc302adb710e9 *man/FilterObjects.Rd f5813c66d90e0e41471779f502142a99 *man/GetImage.Rd 888ced5bd65296a09c375f99eb156806 *man/GetTissueCoordinates.Rd 64e8bc99510d410cdfa662a7c8ec2f14 *man/Graph-class.Rd fb44cc961ea130ee6f5780cbc528e53e *man/Idents.Rd 8ce644523c9b724668641ec87c8b3ac9 *man/Images.Rd a14301c861b6be050b298a156565f698 *man/Indices.Rd f65a308c6130160a7b0cc71a3e03d6f1 *man/IsGlobal.Rd 923c288efca879ba84d91cd9ae011792 *man/IsMatrixEmpty.Rd 5a95da24e68c27ac6884a73d0140f28a *man/IsNamedList.Rd dc2e97055aa38878e7a3382bac8a67b8 *man/IsSparse.Rd 539bbb8c43d038c789aba294961c08e7 *man/JS.Rd bd0aa85cedf8142d552e748e12beb97f *man/JackStrawData-class.Rd 285b669f3370dcfc2bd9385887084b7a *man/JackStrawData-methods.Rd fb2b231fdcab84fde759dc5c884ad044 *man/Key-validity.Rd 8ba6fdea976cb582ae80631848e268c3 *man/Key.Rd 5a02ce35b6f915853174a0b1cc15786a *man/KeyMixin-class.Rd 12bbf02149ac2c7cb965ec42b5ddf639 *man/Layers-StdAssay.Rd 8038d4b773d9f261320e8ca747e68d04 *man/Layers.Rd 00fb4ca6f4bc7cfaaf16a70687cac27e *man/Loadings.Rd b1046ef8bd6f076f33af796bdf64acf6 *man/LogMap-class.Rd 7f2b9c14ec35d5381db2f6a1dfaff5d4 *man/LogMap-validity.Rd fd6485e90fe15663fa9a4fbab94064aa *man/LogSeuratCommand.Rd 6d87559fa98e7ce67c72077b552c1c53 *man/MatchCells.Rd 493b3581a90f3ba5564a576377971905 *man/Misc-StdAssay.Rd 107fd64783bda998708c1ba49f0a8d10 *man/Misc.Rd 0f148b18a5f85416b57bcbf7ed05164f *man/Molecules-class.Rd 0fe46170e96859f3d611b9730ca70c93 *man/Molecules-methods.Rd c573ddfb5d75ed2ecebf11e60b4e7ac0 *man/NNIndex.Rd b69ec370a967359b606c97a746a06136 *man/Neighbor-class.Rd d5d1da2125ae172295b4c596442e728c *man/Neighbor-methods.Rd 77241986bd6e5ca989b2ef8c8499365e *man/ObjectAccess.Rd e8d1ea2158db9906c7c51c9c16d1ef3f *man/Overlay.Rd 1599d0125758ea03d42d2b189c2bca12 *man/PackageCheck.Rd 140c538697acba8fcc0fe6922ffeb239 *man/PolyVtx.Rd 2e2aa4b4d568fed8fd2dc69b08877408 *man/Project.Rd 5b92ad192943e81a993753a9767caba0 *man/Radius.Rd c303c8310c7fa9c675157bfb38bc6d95 *man/RandomName.Rd 4a470abb721f3b5a881d7164f97411ad *man/RegisterSparseMatrix.Rd 8b21888ce66474589a1b5df6aa89e2f1 *man/RenameAssays.Rd ef685e9a797bab755448f1a9ca14e927 *man/RenameCells-StdAssay.Rd 9fbe83085937d7ce30a05341aae7f8a1 *man/RenameCells.Rd 3cccbc7351846becfa577101424b2551 *man/RowMergeSparseMatrices.Rd 15a7e1daadea7b1e972108235ae7465d *man/SaveSeuratRds.Rd c78c30789b1c22939943c8d92844c681 *man/Segmentation-class.Rd def673bd844a470e8939b5a2d9ece484 *man/Segmentation-methods.Rd 299fa025a475d90d8ac6877b8a178e31 *man/Segmentation-validity.Rd 4991f1cc91a80669c62dcc020053541a *man/Seurat-class.Rd 5b98388c60ff4ce098d4c4b1fcb3a7e3 *man/Seurat-validity.Rd 2f9f2aab7b8e18af0d49273ab9ae3ef6 *man/SeuratCommand-class.Rd 668237c345344d6bf0bc122117a7e51d *man/SeuratObject-options.Rd b1d291efa06a5f456f9204930fd6b637 *man/SeuratObject-package.Rd ec4884e558a673afcd11b4de8081fea4 *man/Simplify.Rd 549d0dfd91fccdfbb07935c645c4c595 *man/SparseEmptyMatrix.Rd 3c579ce646ee2b52c2d7d404bc41037c *man/SpatialImage-class.Rd a1e69d43c378ffa2926c415258ac88d9 *man/SpatialImage-methods.Rd da2e9b7ebbdb5350fc81511755750523 *man/SplitLayers.Rd b539da26d03e26fac6da93c138b1eeed *man/StdAssay-class.Rd 307f7d441820bcdcd045fbbfb5a7ba23 *man/StdAssay-validity.Rd 36d940b4f7071a8c84f5c9c5868a7eb7 *man/Stdev.Rd 40a8e43e919b49981034125ab04ee41f *man/StitchMatrix.Rd 53168ebb6c392d96cc16711313f62a93 *man/Theta.Rd ae755af60f7f03f074fd930b6505dc86 *man/Tool.Rd 2fca52f2ce5f3d6f20522c0ffe259462 *man/UpdateSeuratObject.Rd ef2a5ebda0c98dc158c2c55b98da3348 *man/UpdateSlots.Rd 763880892539492b322e9eaff7eaa43b *man/VariableFeatures-StdAssay.Rd 2e17261c3a566ebe3bda0095e55750cc *man/VariableFeatures.Rd 3ba1e2ae496857d51b279a466818b94e *man/Version.Rd 166350b457da176818d2e6a24d9352e5 *man/WhichCells.Rd 75784c4034a6c1360b044bd16a4bad02 *man/aggregate.Rd 407940b34bdc1c5653d793b1ae8dba30 *man/angles.Rd 933a4f7cbb83a4975bd64ed502c91355 *man/as.Centroids.Rd 18ebaaaf29f17b0b62ee0494cabfb0a8 *man/as.Graph.Rd 764355bf04b972b2cc848e22836ddb49 *man/as.Neighbor.Rd a9b6c9eacfbf9b0f9daef9ee280a0716 *man/as.Seurat.Rd c88b9218ac568bed06e3aaf7e593a0a5 *man/as.list.SeuratCommand.Rd 04eeaa4b9f3add0bd56aa373a458ebbb *man/as.matrix.LogMap.Rd 060d10cdca1afd48541066dc38c90368 *man/as.sparse.Rd 441d5b687d3d5e36c49c9a68bd4cabf6 *man/cash-.Assay.Rd 2c86cea8dd94aef26ecedbd8b34142a5 *man/cash-.Assay5.Rd 2e70185d65169d6bcf30a2281a85cb63 *man/cash-.Seurat.Rd 0b582389d325c009a7b1342ef7038f45 *man/cash-.SeuratCommand.Rd 85fdda36b4fc72762498957da37f7943 *man/cash-.StdAssay.Rd 5b9e319f90cf8477a16783b225440ebe *man/colMeans-Assay-method.Rd fd6dd58ec58f373e3f9107215d969174 *man/colMeans-Seurat-method.Rd 76a93b933e50e3fcdaaf4085a2a078fe *man/dim.Assay.Rd 0dd27e8b9af778181951587c60092b93 *man/dim.Assay5.Rd 61b93e58d2eb90a04b19aea1501b5430 *man/dim.DimReduc.Rd ed6cd4457ee1df08eff3f65b282cc84d *man/dim.Seurat.Rd edf104f32e5346ad6cd66ed5241196d1 *man/dim.StdAssay.Rd ea06feef772b4f8d54fadc40147e89ef *man/dimnames.Assay.Rd abe8607dd72d43d40e8bf456b96ea4d6 *man/dimnames.Assay5.Rd d1b119e3b23237dccd51a223d35000fa *man/dimnames.Seurat.Rd 2f123a04259af7a0a11c866f3d8e17e7 *man/dimnames.StdAssay.Rd 979af8e581327f11d3327bb00f8a51ff *man/dot-AssayClass.Rd 59dbfdd330fe37c358f4fb8bfd8a69fb *man/dot-BPMatrixMode.Rd 82986e08688df33e48833cd820edc1b9 *man/dot-CalcN.Rd 81a9cd78a67f899e434aa1e0a1879ed0 *man/dot-CheckFmargin.Rd c2cd9ec42f5ced7b709a906ad7ec0f6d *man/dot-ClassPkg.Rd e9433bd26caaff53dbf128bc379cd27f *man/dot-Collections.Rd 55f6ca223340aae1e82f1da1c315d652 *man/dot-Contains.Rd 10e6da96166a77f331faf9cbeaf1268a *man/dot-CreateStdAssay.Rd 0b3a18a4dc4cca432b8eba84db8b3b3a *man/dot-DefaultFOV.Rd 280c7b2edff3c4e44c46dafd8938be8d *man/dot-Deprecate.Rd ec08ddf520e35603d88f52b500dd7dc7 *man/dot-DiskLoad.Rd 454b7cc84209edc6c18f257e31152db3 *man/dot-DollarNames.Assay.Rd a8bdfbd37fa2e4899140f2e3d17170fa *man/dot-DollarNames.Assay5.Rd 28e60dd90bbd2cbd409add8a8cb4355e *man/dot-DollarNames.Seurat.Rd b50119132bccbc83385fcbe0ae1e6d35 *man/dot-DollarNames.SeuratCommand.Rd e1e95c5cf1badf20f3710b2c30938e3e *man/dot-DollarNames.StdAssay.Rd 179a72f565ab967f0af409fe7fc7a363 *man/dot-FileMove.Rd 774133c2529873d49b4cfeaa14309263 *man/dot-FilePath.Rd 5a53290427b7d4f1b40a815bd5df9930 *man/dot-FilterObjects.Rd d76a803f1a36d6593ea1d934130b4e39 *man/dot-FindObject.Rd 92ff49b5f62850a09acabec2fb8f96ef *man/dot-GetConsensusFeatures.Rd fe071100b7662afbbed2e67c6d30bb2b *man/dot-GetMethod.Rd 25be26d80dee6c201ca92be7a85e36a4 *man/dot-GetVariableFeatures.Rd 0ad6bf6483cbbf1d657b2c4b392138fb *man/dot-IsFutureSeurat.Rd d0cea3ab20c3d95e25e108dc12b68cbb *man/dot-KeyPattern.Rd 86e943e5db8af1862b22c88961bfd7fc *man/dot-MARGIN.Rd 28b9b58c10823c25567e61474eeb2dd7 *man/dot-PropagateList.Rd 076af451d3492abb6a10af41afb6d13a *man/dot-RandomKey.Rd aafcbb1daaa1d99fbcbf28fe7a289a94 *man/dot-SparseSlots.Rd c38ea05d4003aa5474867d0a46b8006c *man/dot-Subobjects.Rd a27fd5bd3fd9aa071dfa5320c4c97580 *man/droplevels.LogMap.Rd cb1e46f469cfbbbde29c8b5113e1d789 *man/figures/lifecycle-archived.svg c0d2e5a54f1fa4ff02bf9533079dd1f7 *man/figures/lifecycle-defunct.svg a1b8c987c676c16af790f563f96cbb1f *man/figures/lifecycle-deprecated.svg c3978703d8f40f2679795335715e98f4 *man/figures/lifecycle-experimental.svg 952b59dc07b171b97d5d982924244f61 *man/figures/lifecycle-maturing.svg 27b879bf3677ea76e3991d56ab324081 *man/figures/lifecycle-questioning.svg 53b3f893324260b737b3c46ed2a0e643 *man/figures/lifecycle-stable.svg 1c1fe7a759b86dc6dbcbe7797ab8246c *man/figures/lifecycle-superseded.svg 94e5233d9c4a52192385c7f3cdb6fcbe *man/intersect.LogMap.Rd 78079400a21db10eb1ecaaf656843272 *man/labels.LogMap.Rd 43343e5c36062085e258077a5f8a6294 *man/merge.Assay.Rd debf4b7094b712dc2cf790a6cc84ed17 *man/merge.Assay5.Rd 40a4085fa032570bbf7b134c884c6de9 *man/merge.DimReduc.Rd c0d9b267f370dc837b3bc3a9477f425e *man/merge.Seurat.Rd 31aa7c7ec61a601360ad15da400f495e *man/merge.StdAssay.Rd a0ed961a1431b3d7ff732a803b471249 *man/names.Seurat.Rd 1804e7cce177bff73333318c8f29cefb *man/old-assign.Rd 4846f0d21ea2a28c6096147d3ee517cc *man/oldseurat-class.Rd a0bf1fbe36866d20495c034663c13724 *man/pbmc_small.Rd 67e73eb537b9589f7db75d64b9d61e23 *man/print.DimReduc.Rd 174a22404b1c8b6e52c1fef014fc3cb7 *man/reexports.Rd 52b7b8b1fdf300fcfc3358933816899d *man/roxygen/meta.R 9948a98b4cf02f0023d963a6822ebc69 *man/roxygen/templates/desc-validity.R f8f8b7c72db894997c4c699a02891178 *man/roxygen/templates/lifecycle-deprecated.R ef3b2dc2cab64559e290df00aa7aece5 *man/roxygen/templates/lifecycle-experimental.R d72b4995266f56f576e728db07329ada *man/roxygen/templates/lifecycle-superseded.R dc7c0b2012073d518fb7e29829542006 *man/roxygen/templates/method-cells.R 861b2bdb816340853477cc9183549537 *man/roxygen/templates/method-features.R 926283891c3040d113feb2ba4e0166e8 *man/roxygen/templates/method-lengths.R f5501d158cc0717e81b9eef208fbd262 *man/roxygen/templates/method-show.R 7af52116e9baf2f1b960769e5c696545 *man/roxygen/templates/method-stdassay.R 8afd9aa06afa62ae7bf043e3a97915f6 *man/roxygen/templates/name-oldv.R 24034598a79b8f1461b1647f2ce82b3b *man/roxygen/templates/note-reqdpkg.R 47d96c85155d705c5782b78087dafe8e *man/roxygen/templates/param-dots-ignored.R 3b09153b5a6e4c24dcfa2d28a8da93dd *man/roxygen/templates/param-dots-method.R 674e3ec32a1eb9c0f84994fd6a7af746 *man/roxygen/templates/param-verbose.R 6e16a5460e9e990875eea028d2ef7bba *man/roxygen/templates/return-null.R f4e31c6d34d49a994f13999c1b301f51 *man/roxygen/templates/return-show.R 84d7260dd254c3dbeff57c77049aa163 *man/roxygen/templates/section-future.R 63706c0d94ca152a0f9c6c88cd5c5da6 *man/roxygen/templates/section-progressr.R c734e303b87cac72c78065f539f8c63c *man/roxygen/templates/seealso-methods.R 8b421a0430da79f3617d77d3d4206e40 *man/roxygen/templates/slot-key.R ce42fd10066a88edebd9b93b6c226731 *man/roxygen/templates/slot-misc.R 83845165946a2ec8a088516bd33f1fc9 *man/roxygen/templates/slot-stdassay.R f0281c9d04013fce7ee88878f720c794 *man/s4list.Rd 9725945b96056d0d581f1d7a6dc100b5 *man/set-if-na.Rd 2ba6c2705198b2a2e8b2175a473033e2 *man/set-if-null.Rd e619be82b82abdc58fa8f42b85aa4cd2 *man/show-Assay-method.Rd 6b3ba95b250573707792bec371446831 *man/show-DimReduc-method.Rd 61ff7a13e1a83819ce0f69e25ff9b547 *man/show-Graph-method.Rd a904dbf6ea73840de5eee2837a7c62c7 *man/show-LogMap-method.Rd b0834ed09fc9de9b75285cd798ab855e *man/show-Seurat-method.Rd afbdde96a15e97e09c1c3703ff9384bd *man/show-SeuratCommand-method.Rd 3150b8db98758cf2d96539ce21bbd216 *man/show-StdAssay-method.Rd 51dc3936ecc37d5b1ad56a6312a3b3df *man/show-oldseurat-method.Rd 9cbac366b52fc6f958ba8a8a994e33f7 *man/split.Assay.Rd 9e17f07672a66c882db037859a6c4667 *man/split.Assay5.Rd 4d2c392e487de8b7360e69320a9dcd50 *man/split.Seurat.Rd cdf3447828685edadad37bc2d1a0f0e3 *man/split.StdAssay.Rd 222260b09d633356c6822bf8f8273699 *man/sub-.Assay.Rd c8b569caae955d33492cb6405bed2c37 *man/sub-.Assay5.Rd dc17cea39248d99937dcbe74907d7d69 *man/sub-.DimReduc.Rd 40e9951309f5db2e4a8c58434ced37bf *man/sub-.SeuratCommand.Rd 2fd1adc5f70b7c9c182f5c41ec106f3f *man/sub-.StdAssay.Rd 14396e99fb2f9ad403b1913bc17c6af4 *man/sub-LogMap-method.Rd c1a82d4f5b7dce092c9a8eb6c484dc2d *man/sub-sub-.Assay.Rd 2e5e72c9692d8f987e0f103a77d2f86f *man/sub-sub-.Assay5.Rd c6dfd01f80348d992ead171e20294599 *man/sub-sub-.DimReduc.Rd 46f5758eafbece2ae8e4fd6dd6e18521 *man/sub-sub-.Seurat.Rd a33628bca5963c4d47dbf8be2762db11 *man/sub-sub-.StdAssay.Rd b66ee93ac46276cac312d6f69425058a *man/sub-sub-LogMap-internal-method.Rd 0e5a77399588f5c63db91f016bbe8571 *man/sub-subset-Seurat-NULL.Rd 6478f71545eb0ebb3c7d3be0ad572dd7 *man/sub-subset-Seurat-character-missing-StdAssay-method.Rd edb7cc5ba86e313828f37b9a5603e2e1 *man/sub-subset-Seurat.Rd 37c1fbb29b83b45b1ee2fcce83d01c2e *man/subset.Assay.Rd cfadfd6154a2169d43a6c04bd104b15f *man/subset.Assay5.Rd b5a3a276793423cab4d4c459d9d125ed *man/subset.DimReduc.Rd 5c65f232502c6fe10da8590037916f39 *man/subset.Seurat.Rd 496af400c5f7a40d274319734a320322 *man/subset.StdAssay.Rd b0d3db52c8ee7dcd38760763a5f6dcf0 *man/v5-assay-summaries.Rd 48564b53bdf7cadfa2a1cf088e08fa1a *src/RcppExports.cpp 288fcd4e7664587a425de78708c7f251 *src/data_manipulation.cpp f99ccc0ef8d6bb241950e293d697668f *src/data_manipulation.h f33c09d14c160d9f29a89251fd91a036 *src/valid_pointer.c 494c907b41d89dfef58d04099af65f7f *tests/testthat.R 390a02ba171811127c8237b5bd374f0f *tests/testthat/test_assay5.R ed2a7dbab182c31ff32e680ff7b75da0 *tests/testthat/test_logmap.R 019c233b2d99d0b6692ccdd305b97dbc *tests/testthat/test_matrix.R de4e7e0ddfdf71f5af61afe8aca63eed *tests/testthat/test_objects.R 4dd67a45850b81d9f77528e2e94a0638 *tests/testthat/test_seurat.R SeuratObject/R/0000755000176200001440000000000015116566601013054 5ustar liggesusersSeuratObject/R/seurat.R0000644000176200001440000053574515116566601014525 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @include assay.R #' @include command.R #' @include dimreduc.R #' @include graph.R #' @include spatial.R #' @importFrom methods setClass #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The Seurat Class #' #' The Seurat object is a representation of single-cell expression data for R; #' each Seurat object revolves around a set of cells and consists of one or more #' \code{\link{Assay}} objects, or individual representations of #' expression data (eg. RNA-seq, ATAC-seq, etc). These assays can be reduced #' from their high-dimensional state to a lower-dimension state and stored as #' \code{\link{DimReduc}} objects. Seurat objects also #' store additional metadata, both at the cell and feature level (contained #' within individual assays). The object was designed to be as self-contained as #' possible, and easily extendable to new methods. #' #' @slot assays A list of assays for this project #' @slot meta.data Contains meta-information about each cell, starting with #' number of features detected (nFeature) and the original identity class #' (orig.ident); more information is added using \code{\link{AddMetaData}} #' @slot active.assay Name of the active, or default, assay; settable using #' \code{\link{DefaultAssay}} #' @slot active.ident The active cluster identity for this Seurat object; #' settable using \code{\link{Idents}} #' @slot graphs A list of \code{\link{Graph}} objects #' @slot neighbors ... #' @slot reductions A list of dimensional reduction objects for this object #' @slot images A list of spatial image objects #' @slot project.name Name of the project #' @slot misc A list of miscellaneous information #' @slot version Version of Seurat this object was built under #' @slot commands A list of logged commands run on this \code{Seurat} object #' @slot tools A list of miscellaneous data generated by other tools, should be #' filled by developers only using \code{\link{Tool}<-} #' #' @name Seurat-class #' @rdname Seurat-class #' @exportClass Seurat #' #' @family seurat #' #' @aliases Seurat #' setClass( Class = 'Seurat', slots = c( assays = 'list', meta.data = 'data.frame', active.assay = 'character', active.ident = 'factor', graphs = 'list', neighbors = 'list', reductions = 'list', images = 'list', project.name = 'character', misc = 'list', version = 'package_version', commands = 'list', tools = 'list' ) ) #' The Seurat Class #' #' The Seurat object is the center of each single cell analysis. It stores all #' information associated with the dataset, including data, annotations, #' analyses, etc. All that is needed to construct a Seurat object is an #' expression matrix (rows are genes, columns are cells), which should #' be log-scale #' #' Each Seurat object has a number of slots which store information. Key slots #' to access are listed below. #' #' @slot raw.data The raw project data #' @slot data The normalized expression matrix (log-scale) #' @slot scale.data scaled (default is z-scoring each gene) expression matrix; #' used for dimensional reduction and heatmap visualization #' @slot var.genes Vector of genes exhibiting high variance across single cells #' @slot is.expr Expression threshold to determine if a gene is expressed #' (0 by default) #' @slot ident THe 'identity class' for each cell #' @slot meta.data Contains meta-information about each cell, starting with #' number of genes detected (nFeature) and the original identity class #' (orig.ident); more information is added using \code{AddMetaData} #' @slot project.name Name of the project (for record keeping) #' @slot dr List of stored dimensional reductions; named by technique #' @slot assay List of additional assays for multimodal analysis; named by #' technique #' @slot hvg.info The output of the mean/variability analysis for all genes #' @slot imputed Matrix of imputed gene scores #' @slot cell.names Names of all single cells #' (column names of the expression matrix) #' @slot cluster.tree List where the first element is a phylo object containing #' the phylogenetic tree relating different identity classes #' @slot snn Spare matrix object representation of the SNN graph #' @slot calc.params Named list to store all calculation-related #' parameter choices #' @slot kmeans Stores output of gene-based clustering from \code{DoKMeans} #' @slot spatial Stores internal data and calculations for spatial mapping of #' single cells #' @slot misc Miscellaneous spot to store any data alongside the object #' (for example, gene lists) #' @slot version Version of package used in object creation #' #' @name seurat-class #' @rdname oldseurat-class #' @aliases seurat-class oldseurat #' #' @concept unsorted #' @concept v2 #' #' @keywords internal #' setClass( Class = "seurat", slots = c( raw.data = "ANY", data = "ANY", scale.data = "ANY", var.genes = "vector", is.expr = "numeric", ident = "factor", meta.data = "data.frame", project.name = "character", dr = "list", assay = "list", hvg.info = "data.frame", imputed = "data.frame", cell.names = "vector", cluster.tree = "list", snn = "dgCMatrix", calc.params = "list", kmeans = "ANY", spatial = "ANY", misc = "ANY", version = "ANY" ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Get cell names grouped by identity class #' #' @param object A Seurat object #' @param idents A vector of identity class levels to limit resulting list to; #' defaults to all identity class levels #' @param cells A vector of cells to grouping to #' @param return.null If no cells are requested, return a \code{NULL}; #' by default, throws an error #' #' @return A named list where names are identity classes and values are vectors #' of cells belonging to that class #' #' @export #' #' @concept data-access #' #' @examples #' CellsByIdentities(object = pbmc_small) #' CellsByIdentities <- function( object, idents = NULL, cells = NULL, return.null = FALSE ) { cells <- cells %||% colnames(x = object) cells <- intersect(x = cells, y = colnames(x = object)) if (length(x = cells) == 0) { if (isTRUE(x = return.null)) { return(NULL) } stop("Cannot find cells provided") } idents <- idents %||% levels(x = object) idents <- intersect(x = idents, y = levels(x = object)) if (length(x = idents) == 0) { stop("None of the provided identity class levels were found", call. = FALSE) } cells.idents <- sapply( X = idents, FUN = function(i) { return(cells[as.vector(x = Idents(object = object)[cells]) == i]) }, simplify = FALSE, USE.NAMES = TRUE ) if (any(is.na(x = Idents(object = object)[cells]))) { cells.idents[["NA"]] <- names(x = which(x = is.na(x = Idents(object = object)[cells]))) } return(cells.idents) } #' Get a vector of cell names associated with an image (or set of images) #' #' @param object Seurat object #' @param images Vector of image names #' @param unlist Return as a single vector of cell names as opposed to a list, #' named by image name. #' #' @return A vector of cell names #' #' @concept data-access #' #' @examples #' \dontrun{ #' CellsByImage(object = object, images = "slice1") #' } #' CellsByImage <- function(object, images = NULL, unlist = FALSE) { images <- images %||% Images(object = object) cells <- sapply( X = images, FUN = function(x) { Cells(x = object[[x]]) }, simplify = FALSE, USE.NAMES = TRUE ) if (unlist) { cells <- unname(obj = unlist(x = cells)) } return(cells) } #' Find Sub-objects of a Certain Class #' #' Get the names of objects within a \code{Seurat} object that are of a #' certain class #' #' @param object A \code{\link{Seurat}} object #' @param classes.keep A vector of names of classes to get #' #' @return A vector with the names of objects within the \code{Seurat} object #' that are of class \code{classes.keep} #' #' @export #' #' @concept utils #' #' @templateVar fxn FilterObjects #' @templateVar ver 5.0.0 #' @templateVar repl .FilterObjects #' @template lifecycle-deprecated #' #' FilterObjects <- function( object, classes.keep = c('Assay', 'StdAssay', 'DimReduc') ) { .Deprecate(when = '5.0.0', what = 'FilterObjects()', with = '.FilterObjects()') object <- UpdateSlots(object = object) slots <- na.omit(object = Filter( f = function(x) { sobj <- slot(object = object, name = x) return(is.list(x = sobj) && !is.data.frame(x = sobj) && !is.package_version(x = sobj)) }, x = slotNames(x = object) )) slots <- grep(pattern = 'tools', x = slots, value = TRUE, invert = TRUE) slots <- grep(pattern = 'misc', x = slots, value = TRUE, invert = TRUE) slots.objects <- unlist( x = lapply( X = slots, FUN = function(x) { return(names(x = slot(object = object, name = x))) } ), use.names = FALSE ) object.classes <- sapply( X = slots.objects, FUN = function(i) { return(inherits(x = object[[i]], what = classes.keep)) } ) object.classes <- which(x = object.classes, useNames = TRUE) return(names(x = object.classes)) } #' @rdname ObjectAccess #' @export #' #' @examples #' Graphs(pbmc_small) #' Graphs <- function(object, slot = NULL) { graphs <- .FilterObjects(object = object, classes.keep = "Graph") if (is.null(x = slot)) { return(graphs) } if (!slot %in% graphs) { warning( "Cannot find a Graph object of name ", slot, " in this Seurat object", call. = FALSE, immediate. = TRUE ) } return(slot(object = object, name = 'graphs')[[slot]]) } #' Pull spatial image names #' #' List the names of \code{SpatialImage} objects present in a \code{Seurat} #' object. If \code{assay} is provided, limits search to images associated with #' that assay #' #' @param object A \code{Seurat} object #' @param assay Name of assay to limit search to #' #' @return A list of image names #' #' @export #' #' @concept data-access #' #' @examples #' \dontrun{ #' Images(object) #' } #' Images <- function(object, assay = NULL) { images <- names(x = slot(object = object, name = 'images')) if (!is.null(x = assay)) { assays <- c(assay, DefaultAssay(object = object[[assay]])) images <- Filter( f = function(x) { return(DefaultAssay(object = object[[x]]) %in% assays) }, x = images ) } return(images) } #' @inheritDotParams base::readRDS #' #' @rdname SaveSeuratRds #' @export #' LoadSeuratRds <- function(file, ...) { object <- readRDS(file = file, ...) cache <- Tool(object = object, slot = 'SaveSeuratRds') reqd.cols <- c('layer', 'path', 'class', 'pkg', 'fxn', 'assay') emit <- ifelse( test = isTRUE(x = getOption(x = 'Seurat.io.rds.strict', default = FALSE)), yes = abort, no = warn ) if (!is.null(x = cache)) { if (interactive()) { check_installed(pkg = 'fs', reason = 'for finding file paths') } else if (!requireNamespace('fs', quietly = TRUE)) { abort(message = "Loading layers from disk requires `fs`") } # Check the format of the cache if (!is.data.frame(x = cache)) { emit(message = "Malformed layer cache: not a data frame") return(object) } if (!all(reqd.cols %in% names(x = cache))) { emit(message = "Malformed layer cache: missing required columns") return(object) } # Check the assays specified assays <- .FilterObjects(object = object, classes.keep = 'StdAssay') cache <- cache[cache$assay %in% assays, , drop = FALSE] if (!nrow(x = cache)) { emit(message = "Incorrect layer cache: none of the assays listed present") return(object) } # Check the files exists <- vapply( X = cache$path, FUN = function(x) { x <- unlist(x = strsplit(x = x, split = ',')) res <- vector(mode = 'logical', length = length(x = x)) for (i in seq_along(along.with = x)) { res[i] <- fs::is_file(path = x[i]) || fs::dir_exists(path = x[i]) } return(all(res)) }, FUN.VALUE = logical(length = 1L), USE.NAMES = FALSE ) exists[is.na(exists)] <- FALSE cache <- cache[exists, , drop = FALSE] if (!nrow(x = cache)) { emit(message = "Cannot find any of the layer files specified") return(object) } # Check the packages missing.pkgs <- pkgs <- unique(x = cache$pkg) for (pkg in pkgs) { if (interactive()) { check_installed(pkg = pkg) } if (requireNamespace(pkg, quietly = TRUE)) { missing.pkgs <- setdiff(x = missing.pkgs, y = pkg) } else { emit(message = paste("Cannot find required package:", sQuote(x = pkg))) } } pkgs <- setdiff(x = pkgs, y = missing.pkgs) if (!length(x = pkgs)) { emit(message = "None of the required layer packages found") return(object) } p <- progressor(steps = nrow(x = cache)) # Load the layers for (i in seq_len(length.out = nrow(x = cache))) { lyr <- cache$layer[i] pth <- cache$path[i] fxn <- eval(expr = str2lang(s = cache$fxn[i])) assay <- cache$assay[i] p( message = paste( "Adding layer", sQuote(x = lyr), "to assay", sQuote(x = assay) ), class = 'sticky', amount = 0 ) LayerData(object = object, assay = assay, layer = lyr) <- fxn(pth) p() } } return(object) } #' @rdname ObjectAccess #' @export #' Neighbors <- function(object, slot = NULL) { neighbors <- .FilterObjects(object = object, classes.keep = "Neighbor") if (is.null(x = slot)) { return(neighbors) } if (!slot %in% neighbors) { warning( "Cannot find a Neighbor object of name ", slot, " in this Seurat object", call. = FALSE, immediate. = TRUE ) } return(slot(object = object, name = 'neighbors')[[slot]]) } #' @rdname ObjectAccess #' @export #' #' @examples #' Reductions(object = pbmc_small) #' Reductions <- function(object, slot = NULL) { reductions <- .FilterObjects(object = object, classes.keep = 'DimReduc') if (is.null(x = slot)) { return(reductions) } if (!slot %in% reductions) { warn( message = paste( 'Cannot find a DimReduc of name', slot, 'in this Seurat object') ) return(NULL) } return(slot(object = object, name = 'reductions')[[slot]]) } #' Rename assays in a \code{Seurat} object #' #' @param object A \code{Seurat} object #' @param assay.name original name of assay #' @param new.assay.name new name of assay #' @param verbose Whether to print messages #' @param ... Named arguments as \code{old.assay = new.assay} #' #' @return \code{object} with assays renamed #' #' @export #' #' @concept seurat #' #' @examples #' RenameAssays(object = pbmc_small, RNA = 'rna') #' RenameAssays <- function( object, assay.name = NULL, new.assay.name = NULL, verbose = TRUE, ...) { op <- options(Seurat.object.assay.calcn = FALSE) on.exit(expr = options(op), add = TRUE) if ((!is.null(x = assay.name) & is.null(x = new.assay.name)) | (is.null(x = assay.name) & !is.null(x = new.assay.name))) { stop("Must provide both assay.name and new.assasy.name if using parameters. Otherwise, ", "you can set arguments without parameters by doing ", "{old.assay = new.assay} with your own assay names.", call. = FALSE) } if (!is.null(x = assay.name) & !is.null(x = new.assay.name)) { assay.pairs <- new.assay.name names(x = assay.pairs) <- assay.name old.assays <- names(x = assay.pairs) } else { assay.pairs <- tryCatch( expr = as.list(x = ...), error = function(e) { return(list(...)) } ) old.assays <- names(x = assay.pairs) names(x = assay.pairs) <- old.assays } # Handle missing assays missing.assays <- setdiff(x = old.assays, y = Assays(object = object)) if (length(x = missing.assays) == length(x = old.assays)) { stop("None of the assays provided are present in this object", call. = FALSE) } else if (length(x = missing.assays)) { warning( "The following assays could not be found: ", paste(missing.assays, collapse = ', '), call. = FALSE, immediate. = TRUE ) } old.assays <- setdiff(x = old.assays, missing.assays) assay.pairs <- assay.pairs[old.assays] # Check to see that all old assays are named if (is.null(x = names(x = assay.pairs)) || any(sapply(X = old.assays, FUN = nchar) < 1)) { stop("All arguments must be named with the old assay name", call. = FALSE) } # Ensure each old assay is going to one new assay if (!all(sapply(X = assay.pairs, FUN = length) == 1) || length(x = old.assays) != length(x = unique(x = old.assays))) { stop("Can only rename assays to one new name", call. = FALSE) } # Ensure each new assay is coming from one old assay if (length(x = assay.pairs) != length(x = unique(x = assay.pairs))) { stop( "One or more assays are set to be lost due to duplicate new assay names", call. = FALSE ) } # Rename assays for (old in names(x = assay.pairs)) { new <- assay.pairs[[old]] # If we aren't actually renaming any if (old == new) { next } old.key <- Key(object = object[[old]]) suppressWarnings(expr = object[[new]] <- object[[old]]) if (old == DefaultAssay(object = object)) { if (verbose) { message("Renaming default assay from ", old, " to ", new) } DefaultAssay(object = object) <- new } Key(object = object[[new]]) <- old.key # change assay used in any dimreduc object for (i in Reductions(object = object)) { if (DefaultAssay(object = object[[i]]) == old) { DefaultAssay(object = object[[i]]) <- new } } # Add new metadata if it exists if (isTRUE(paste0("nCount_", old) %in% colnames(object[[]]))) { slot( object = object, name = 'meta.data' )[paste0("nCount_", new)] <- object[[]][,paste0("nCount_",old)] } if (isTRUE(paste0("nFeature_", old) %in% colnames(object[[]]))) { slot( object = object, name = 'meta.data' )[paste0("nFeature_", new)] <- object[[]][,paste0("nFeature_", old)] } object[[old]] <- NULL } return(object) } #' Save and Load \code{Seurat} Objects from Rds files #' #' @param object A \code{\link{Seurat}} object #' @param file Path to save \code{object} to; defaults to #' \code{file.path(getwd(), paste0(Project(object), ".Rds"))} #' @param move Move on-disk layers into \code{dirname(file)} #' @param destdir \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} #' @param relative Save relative paths instead of absolute ones #' @inheritDotParams base::saveRDS #' #' @return Invisibly returns \code{file} #' #' @export #' #' @template section-progressr #' #' @templateVar pkg fs #' @template note-reqdpkg #' #' @concept utils #' #' @seealso \code{\link{saveRDS}()} \code{\link{readRDS}()} #' #' @order 1 #' #' @examples #' \dontrun{ #' if (requireNamespace("fs", quietly = TRUE)) { #' # Write out with DelayedArray #' if (requireNamespace("HDF5Array", quietly = TRUE)) { #' pbmc <- pbmc_small #' #' pbmc[["disk"]] <- CreateAssay5Object(list( #' mem = LayerData(pbmc, "counts"), #' disk = as(LayerData(pbmc, "counts"), "HDF5Array") #' )) #' #' # Save `pbmc` to an Rds file #' out <- tempfile(fileext = ".Rds") #' SaveSeuratRds(pbmc, file = out) #' #' # Object cache #' obj <- readRDS(out) #' Tool(obj, "SaveSeuratRds") #' #' # Load the saved object with on-disk layers back into memory #' pbmc2 <- LoadSeuratRds(out) #' pbmc2 #' pbmc2[["disk"]] #' } #' #' # Write out with BPCells #' if (requireNamespace("BPCells", quietly = TRUE)) { #' pbmc <- pbmc_small #' #' bpm <- BPCells::write_matrix_dir(LayerData(pbmc, "counts"), dir = tempfile()) #' bph <- BPCells::write_matrix_hdf5( #' LayerData(pbmc, "counts"), #' path = tempfile(fileext = ".h5"), #' group = "counts" #' ) #' pbmc[["disk"]] <- CreateAssay5Object(list(dir = bpm, h5 = bph)) #' #' # Save `pbmc` to an Rds file #' out <- tempfile(fileext = ".Rds") #' SaveSeuratRds(pbmc, file = out) #' #' # Object cache #' obj <- readRDS(out) #' Tool(obj, "SaveSeuratRds") #' #' # Load the saved object with on-disk layers back into memory #' pbmc2 <- LoadSeuratRds(out) #' pbmc2 #' pbmc2[["disk"]] #' } #' } #' } #' SaveSeuratRds <- function( object, file = NULL, move = TRUE, destdir = deprecated(), relative = FALSE, ... ) { file <- file %||% file.path(getwd(), paste0(Project(object = object), '.Rds')) file <- normalizePath(path = file, winslash = '/', mustWork = FALSE) if (is_present(arg = destdir)) { .Deprecate( when = '5.0.1', what = 'SaveSeuratRds(destdir = )', with = 'SaveSeuratRds(move = )', details = paste( "Specifying a directory to move on-disk layers stored in", sQuote(x = normalizePath(path = tempdir(), winslash = '/', mustWork = FALSE)), "is deprecated; now, specify `move = TRUE` either move all on-disk layers to", sQuote(x = dirname(path = file)), "or `move = FALSE` leave them as-is" ) ) move <- is_bare_character(x = destdir, n = 1L) || is.null(x = destdir) } # Cache v5 assays assays <- .FilterObjects(object = object, classes.keep = 'StdAssay') p <- progressor(along = assays, auto_finish = TRUE) on.exit(expr = p(type = 'finish'), add = TRUE) p( message = paste( "Looking for on-disk matrices in", length(x = assays), "assays" ), class = 'sticky', amount = 0 ) cache <- vector(mode = 'list', length = length(x = assays)) names(x = cache) <- assays destdir <- dirname(path = file) if (isTRUE(x = move)) { check_installed(pkg = 'fs', reason = 'for moving on-disk matrices') } for (assay in assays) { p( message = paste("Searching through assay", assay), class = 'sticky', amount = 0 ) df <- lapply( X = Layers(object = object[[assay]]), FUN = function(lyr) { ldat <- LayerData(object = object[[assay]], layer = lyr) path <- .FilePath(x = ldat) path <- Filter(f = nzchar, x = path) if (!length(x = path)) { path <- NULL } if (is.null(x = path)) { return(NULL) } return(data.frame( layer = lyr, path = path, class = paste(class(x = ldat), collapse = ','), pkg = .ClassPkg(object = ldat), fxn = .DiskLoad(x = ldat) %||% identity )) } ) df <- do.call(what = 'rbind', args = df) if (is.null(x = df) || !nrow(x = df)) { p(message = "No on-disk layers found", class = 'sticky', amount = 0) next } if (isTRUE(x = move)) { for (i in seq_len(length.out = nrow(x = df))) { pth <- df$path[i] p( message = paste( "Moving layer", sQuote(x = df$layer[i]), "to", sQuote(x = destdir) ), class = 'sticky', amount = 0 ) df[i, 'path'] <- as.character(x = .FileMove( path = pth, new_path = destdir )) } } if (isTRUE(x = relative)) { p( message = paste( "Adjusting paths to be relative to", sQuote(x = dirname(path = file), q = FALSE) ), class = 'sticky', amount = 0 ) df$path <- as.character(x = fs::path_rel( path = df$path, start = dirname(path = file) )) } df$assay <- assay cache[[assay]] <- df if (nrow(x = df) == length(x = Layers(object = object[[assay]]))) { p( message = paste("Clearing layers from", assay), class = 'sticky', amount = 0 ) adata <- S4ToList(object = object[[assay]]) adata$layers <- list() adata$default <- 0L adata$cells <- LogMap(y = colnames(x = object[[assay]])) adata$features <- LogMap(y = rownames(x = object[[assay]])) object[[assay]] <- ListToS4(x = adata) } else { p( message = paste("Clearing", nrow(x = df), "layers from", assay), class = 'sticky', amount = 0 ) for (layer in df$layer) { LayerData(object = object[[assay]], layer = layer) <- NULL } } p() } cache <- do.call(what = 'rbind', args = cache) if (!is.null(x = cache) && nrow(x = cache)) { p(message = "Saving on-disk cache to object", class = 'sticky', amount = 0) row.names(x = cache) <- NULL Tool(object = object) <- cache } saveRDS(object = object, file = file, ...) return(invisible(x = file)) } #' Update old Seurat object to accommodate new features #' #' Updates Seurat objects to new structure for storing data/calculations. #' For Seurat v3 objects, will validate object structure ensuring all keys #' and feature names are formed properly. #' #' @param object Seurat object #' #' @return Returns a Seurat object compatible with latest changes #' #' @importFrom methods .hasSlot new slot #' #' @export #' #' @concept seurat #' #' @examples #' \dontrun{ #' updated_seurat_object = UpdateSeuratObject(object = old_seurat_object) #' } #' UpdateSeuratObject <- function(object) { op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op), add = TRUE) if (.hasSlot(object, "version")) { if (slot(object = object, name = 'version') >= package_version(x = "2.0.0") && slot(object = object, name = 'version') < package_version(x = '3.0.0')) { # Run update message("Updating from v2.X to v3.X") # seurat.version <- packageVersion(pkg = "SeuratObject") seurat.version <- package_version(x = '3.0.0') new.assay <- UpdateAssay(old.assay = object, assay = "RNA") assay.list <- list(new.assay) names(x = assay.list) <- "RNA" for (i in names(x = object@assay)) { assay.list[[i]] <- UpdateAssay(old.assay = object@assay[[i]], assay = i) } new.dr <- UpdateDimReduction(old.dr = object@dr, assay = "RNA") object <- new( Class = "Seurat", version = seurat.version, assays = assay.list, active.assay = "RNA", project.name = object@project.name, misc = object@misc %||% list(), active.ident = object@ident, reductions = new.dr, meta.data = droplevels(object@meta.data), tools = list() ) # Run CalcN for (assay in Assays(object = object)) { n.calc <- CalcN(object = object[[assay]]) if (!is.null(x = n.calc)) { names(x = n.calc) <- paste(names(x = n.calc), assay, sep = '_') object[[names(x = n.calc)]] <- n.calc } to.remove <- c("nGene", "nUMI") for (i in to.remove) { if (i %in% colnames(x = object[[]])) { object[[i]] <- NULL } } } } if (package_version(x = slot(object = object, name = 'version')) >= package_version(x = "3.0.0")) { # Run validation message("Validating object structure") # Update object slots message("Updating object slots") object <- UpdateSlots(object = object) # Validate object keys message("Ensuring keys are in the proper structure") for (ko in .FilterObjects(object = object)) { key <- Key(object = object[[ko]]) if (!length(x = key) || !nzchar(x = key)) { key <- Key(object = ko, quiet = TRUE) } slot( object = slot(object = object, name = FindObject(object, ko))[[ko]], name = 'key' ) <- UpdateKey(key) if (inherits(x = slot(object = object, name = FindObject(object, ko))[[ko]], what = 'DimReduc')) { message("Updating matrix keys for DimReduc ", sQuote(ko)) for (m in c('cell.embeddings', 'feature.loadings', 'feature.loadings.projected')) { mat <- slot( object = slot(object = object, name = FindObject(object, ko))[[ko]], name = m ) if (IsMatrixEmpty(mat)) { next } colnames(x = mat) <- paste0(key, seq_len(ncol(mat))) slot( object = slot(object = object, name = FindObject(object, ko))[[ko]], name = m ) <- mat } } } # Rename assays assays <- make.names(names = Assays(object = object)) names(x = assays) <- Assays(object = object) object <- do.call(what = RenameAssays, args = c('object' = object, assays)) for (obj in .FilterObjects(object = object, classes.keep = c('Assay', 'DimReduc', 'Graph'))) { suppressWarnings( expr = object[[obj]] <- UpdateSlots(object = object[[obj]]), classes = 'validationWarning' ) } for (cmd in Command(object = object)) { slot(object = object, name = 'commands')[[cmd]] <- UpdateSlots( object = Command(object = object, command = cmd) ) } # Validate object keys message("Ensuring keys are in the proper structure") for (ko in .FilterObjects(object = object)) { suppressWarnings( expr = Key(object = object[[ko]]) <- UpdateKey(key = Key(object = object[[ko]])), classes = 'validationWarning' ) } # Check feature names message("Ensuring feature names don't have underscores or pipes") for (assay.name in .FilterObjects(object = object, classes.keep = 'Assay')) { assay <- object[[assay.name]] for (slot in c('counts', 'data', 'scale.data')) { if (!IsMatrixEmpty(x = slot(object = assay, name = slot))) { rownames(x = slot(object = assay, name = slot)) <- gsub( pattern = '_', replacement = '-', x = rownames(x = slot(object = assay, name = slot)) ) rownames(x = slot(object = assay, name = slot)) <- gsub( pattern = '|', replacement = '-', x = rownames(x = slot(object = assay, name = slot)), fixed = TRUE ) } } VariableFeatures(object = assay) <- gsub( pattern = '_', replacement = '-', x = VariableFeatures(object = assay) ) VariableFeatures(object = assay) <- gsub( pattern = '|', replacement = '-', x = VariableFeatures(object = assay), fixed = TRUE ) rownames(x = slot(object = assay, name = "meta.features")) <- gsub( pattern = '_', replacement = '-', x = rownames(x = assay[[]]) ) rownames(x = slot(object = assay, name = "meta.features")) <- gsub( pattern = '|', replacement = '-', x = rownames(x = assay[[]]), fixed = TRUE ) # reorder features in scale.data and meta.features to match counts sd.features <- rownames(x = slot(object = assay, name = "scale.data")) data.features <- rownames(x = slot(object = assay, name = "data")) md.features <- rownames(x = slot(object = assay, name = "meta.features")) if (!identical(md.features, data.features)) { slot(object = assay, name = "meta.features") <- slot(object = assay, name = "meta.features")[data.features, ] } sd.order <- sd.features[order(match(x = sd.features, table = data.features))] slot(object = assay, name = "scale.data") <- slot(object = assay, name = "scale.data")[sd.order, ] suppressWarnings( expr = object[[assay.name]] <- assay, classes = 'validationWarning' ) } for (reduc.name in .FilterObjects(object = object, classes.keep = 'DimReduc')) { reduc <- object[[reduc.name]] for (slot in c('feature.loadings', 'feature.loadings.projected')) { if (!IsMatrixEmpty(x = slot(object = reduc, name = slot))) { rownames(x = slot(object = reduc, name = slot)) <- gsub( pattern = '_', replacement = '-', x = rownames(x = slot(object = reduc, name = slot)) ) rownames(x = slot(object = reduc, name = slot)) <- gsub( pattern = '_', replacement = '-', x = rownames(x = slot(object = reduc, name = slot)), fixed = TRUE ) } } suppressWarnings( expr = object[[reduc.name]] <- reduc, classes = 'validationWarning' ) } # Update Assays, DimReducs, and Graphs for (x in names(x = object)) { message("Updating slots in ", x) xobj <- object[[x]] if (inherits(x = xobj, what = 'FOV')) { fov_name <- x # Needs coord system update if # object doesn't have coords_x_orientation slot or # was saved prior to correction old_axis_orientation <- (!.hasSlot(xobj, "coords_x_orientation")) || (.hasSlot(xobj, "coords_x_orientation") && (slot(xobj, "coords_x_orientation") != 'horizontal')) is_visium <- inherits(xobj, "VisiumV1") || inherits(xobj, "VisiumV2") if (is_visium && old_axis_orientation) { tryCatch( expr = { boundaries <- slot(object = xobj, name = 'boundaries') # Find all centroid objects in boundaries centroids_indices <- which(sapply(X = boundaries, FUN = inherits, what = 'Centroids')) if (length(centroids_indices) > 0) { centroids_names <- names(boundaries)[centroids_indices] # Process each centroids object for (i in seq_along(centroids_indices)) { cent_name <- centroids_names[i] cent <- boundaries[[cent_name]] new_coords <- GetTissueCoordinates(object = cent) old_x_coords <- new_coords$x new_coords$x <- new_coords$y new_coords$y <- old_x_coords updated_cent <- CreateCentroids(new_coords, radius = Radius(cent)) boundaries[[cent_name]] <- updated_cent message("Updated Centroids object ", sQuote(cent_name), " in FOV ", sQuote(fov_name)) } # Update the FOV object if any boundaries were modified message("Updated boundaries in FOV ", sQuote(fov_name)) slot(object = xobj, name = 'boundaries') <- boundaries slot(object = xobj, name = 'coords_x_orientation') <- 'horizontal' # Update flag } }, error = function(e) { message("Error updating objects in boundaries in FOV ", sQuote(fov_name)) } ) } } xobj <- suppressWarnings( expr = UpdateSlots(object = xobj), classes = 'validationWarning' ) if (inherits(x = xobj, what = "SCTAssay")){ sctmodels <- names(x = slot(object = xobj, name = "SCTModel.list")) for (sctmodel in sctmodels){ median_umi <- tryCatch( expr = slot(object = xobj@SCTModel.list[[sctmodel]], name = "median_umi"), error = function(...) { return(0) } ) xobj@SCTModel.list[[sctmodel]]@median_umi <- median_umi } } if (inherits(x = xobj, what = 'DimReduc')) { if (any(sapply(X = c('tsne', 'umap'), FUN = grepl, x = tolower(x = x)))) { message("Setting ", x, " DimReduc to global") slot(object = xobj, name = 'global') <- TRUE } } else if (inherits(x = xobj, what = 'Graph')) { graph.assay <- unlist(x = strsplit(x = x, split = '_'))[1] if (graph.assay %in% Assays(object = object)) { message("Setting default assay of ", x, " to ", graph.assay) suppressWarnings( expr = DefaultAssay(object = xobj) <- graph.assay, classes = 'validationWarning' ) } else { message( "Cannot find ", graph.assay, " in the object, setting default assay of ", x, " to ", DefaultAssay(object = object) ) suppressWarnings( expr = DefaultAssay(object = xobj) <- DefaultAssay(object = object), classes = 'validationWarning' ) } } suppressWarnings( expr = object[[x]] <- xobj, classes = 'validationWarning' ) } # Update SeuratCommands for (cmd in Command(object = object)) { cobj <- Command(object = object, command = cmd) cobj <- UpdateSlots(object = cobj) cmd.assay <- unlist(x = strsplit(x = cmd, split = '\\.')) cmd.assay <- cmd.assay[length(x = cmd.assay)] cmd.assay <- if (cmd.assay %in% Assays(object = object)) { cmd.assay } else if (cmd.assay %in% Reductions(object = object)) { DefaultAssay(object = object[[cmd.assay]]) } else { NULL } if (is.null(x = cmd.assay)) { message("No assay information could be found for ", cmd) } else { message("Setting assay used for ", cmd, " to ", cmd.assay) } slot(object = cobj, name = 'assay.used') <- cmd.assay suppressWarnings( expr = object[[cmd]] <- cobj, classes = 'validationWarning' ) } # Update object version slot(object = object, name = 'version') <- packageVersion(pkg = 'SeuratObject') } object <- suppressWarnings( expr = UpdateSlots(object = object), classes = 'validationWarning' ) if (package_version(x = slot(object = object, name = 'version')) <= package_version(x = '4.0.0')) { # Transfer the object to the SeuratObject namespace object <- suppressWarnings( expr = UpdateClassPkg( object = object, from = 'Seurat', to = 'SeuratObject' ), classes = 'validationWarning' ) } slot(object = object, name = 'version') <- packageVersion(pkg = 'SeuratObject') options(op) validObject(object = object, complete = TRUE) for (i in names(x = object)) { message( "Validating object structure for ", paste(class(x = object[[i]])[1L], sQuote(x = i)) ) validObject(object = object[[i]]) } message("Object representation is consistent with the most current Seurat version") return(object) } stop( "We are unable to convert Seurat objects less than version 2.X to version 3.X\n", 'Please use devtools::install_version to install Seurat v2.3.4 and update your object to a 2.X object', call. = FALSE ) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname AddMetaData #' @export #' @method AddMetaData Seurat #' AddMetaData.Seurat <- .AddMetaData #' @rdname ObjectAccess #' @method Assays Seurat #' @export #' Assays.Seurat <- function(object, slot = deprecated(), ...) { if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'Assays(slot = )', with = 'LayerData()' ) return(methods::slot(object = object, name = 'assays')[[slot]]) } return(names(x = methods::slot(object = object, name = 'assays'))) } #' @method CastAssay Seurat #' @export #' CastAssay.Seurat <- function(object, to, assay = NULL, layers = NA, ...) { assay <- assay[1L] %||% DefaultAssay(object = object) assay <- arg_match0(arg = assay, values = Assays(object = object)) to <- enquo(arg = to) object[[assay]] <- CastAssay( object = object[[assay]], to = to, layers = layers, ... ) validObject(object = object) return(object) } #' @method Cells Seurat #' @export #' Cells.Seurat <- function(x, assay = NULL, ...) { assay <- assay[1L] %||% DefaultAssay(object = x) if (is.na(x = assay)) { return(colnames(x = x)) } assay <- tryCatch( expr = match.arg(arg = assay, choices = Assays(object = x)), error = function(e) { return(NULL) } ) return(Cells(x = x[[assay]], ...)) } #' @param command Name of the command to pull, pass \code{NULL} to get the #' names of all commands run #' @param value Name of the parameter to pull the value for #' #' @rdname Command #' @export #' @method Command Seurat #' Command.Seurat <- function(object, command = NULL, value = NULL, ...) { CheckDots(...) object <- UpdateSlots(object = object) commands <- slot(object = object, name = "commands") if (is.null(x = command)) { return(names(x = commands)) } if (is.null(x = commands[[command]])) { stop(command, " has not been run or is not a valid command.") } command <- commands[[command]] if (is.null(x = value)) { return(command) } params <- slot(object = command, name = "params") if (!value %in% names(x = params)) { stop(value, " is not a valid parameter for ", slot(object = command, name = "name")) } return(params[[value]]) } # @param row.names When \code{counts} is a \code{data.frame} or # \code{data.frame}-derived object: an optional vector of feature names to be # used # #' @rdname CreateSeuratObject #' @method CreateSeuratObject default #' @export #' CreateSeuratObject.default <- function( counts, assay = 'RNA', names.field = 1L, names.delim = '_', meta.data = NULL, project = 'SeuratProject', min.cells = 0, min.features = 0, ... ) { assay.version <- getOption(x = 'Seurat.object.assay.version', default = 'v5') if (.GetSeuratCompat() < '5.0.0') { assay.version <- 'v3' } else if (!inherits(counts, what = c('matrix', 'dgCMatrix')) && assay.version == 'v3') { message( "Counts matrix provided is not sparse; vreating v5 assay in Seurat object" ) assay.version <- 'v5' } assay.data <- if (tolower(x = assay.version) == 'v3') { assay.data <- CreateAssayObject( counts = counts, min.cells = min.cells, min.features = min.features, ... ) } else { CreateAssay5Object( counts = counts, min.cells = min.cells, min.features = min.features, ... ) } return(CreateSeuratObject( counts = assay.data, assay = assay, names.field = names.field, names.delim = names.delim, meta.data = meta.data, project = project )) } #' @rdname CreateSeuratObject #' @method CreateSeuratObject Assay #' @export #' CreateSeuratObject.Assay <- function( counts, assay = 'RNA', names.field = 1L, names.delim = '_', meta.data = NULL, project = 'SeuratProject', ... ) { # Check the assay key if (!isTRUE(x = nzchar(x = Key(object = counts)))) { Key(object = counts) <- Key(object = tolower(x = assay), quiet = TRUE) } # Assemble the assay list assay.list <- list(counts) names(x = assay.list) <- assay # Create identity classes idents <- factor(x = unlist(x = lapply( X = colnames(x = counts), FUN = ExtractField, field = names.field, delim = names.delim ))) if (any(is.na(x = idents))) { warn( "Input parameters result in NA values for initial cell identities. Setting all initial idents to the project name", call. = FALSE, immediate. = TRUE ) idents <- factor(x = rep_len(x = project, length.out = ncol(x = counts))) } nidents <- length(x = levels(x = idents)) if (nidents > 100L || nidents == 0L || nidents == length(x = idents)) { idents <- factor(x = rep_len(x = project, length.out = ncol(x = counts))) } names(x = idents) <- colnames(x = counts) # Initialize meta data meta.init <- EmptyDF(n = ncol(x = counts)) row.names(x = meta.init) <- colnames(x = counts) # Create the object op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op), add = TRUE) object <- suppressWarnings(expr = new( Class = 'Seurat', assays = assay.list, meta.data = meta.init, active.assay = assay, active.ident = idents, graphs = list(), neighbors = list(), reductions = list(), images = list(), project.name = project, misc = list(), version = packageVersion(pkg = 'SeuratObject'), commands = list(), tools = list() )) options(op) object[['orig.ident']] <- idents # Calculate nCount and nFeature calcN_option <- getOption( x = 'Seurat.object.assay.calcn', default = Seurat.options$Seurat.object.assay.calcn ) calcN_option <- calcN_option %||% TRUE if (isTRUE(x = calcN_option)) { ncalc <- CalcN(object = counts) if (!is.null(x = ncalc)) { names(x = ncalc) <- paste(names(x = ncalc), assay, sep = '_') object[[]] <- ncalc } } # Add provided meta data if (!is.null(x = meta.data)) { tryCatch( expr = object[[]] <- meta.data, error = function(e) { warning(e$message, call. = FALSE, immediate. = TRUE) } ) } # Validate and return validObject(object = object) return(object) } #' @method CreateSeuratObject StdAssay #' @export #' CreateSeuratObject.StdAssay <- CreateSeuratObject.Assay #' @rdname CreateSeuratObject #' @method CreateSeuratObject Assay5 #' @export #' CreateSeuratObject.Assay5 <- CreateSeuratObject.StdAssay #' @rdname DefaultAssay #' @export #' @method DefaultAssay Seurat #' #' @examples #' # Get current default assay #' DefaultAssay(object = pbmc_small) #' DefaultAssay.Seurat <- function(object, ...) { CheckDots(...) default <- slot(object = object, name = 'active.assay') if (!length(x = default)) { default <- NULL } return(default) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay<- Seurat #' #' @examples #' # Create dummy new assay to demo switching default assays #' new.assay <- pbmc_small[["RNA"]] #' Key(object = new.assay) <- "RNA2_" #' pbmc_small[["RNA2"]] <- new.assay #' # switch default assay to RNA2 #' DefaultAssay(object = pbmc_small) <- "RNA2" #' DefaultAssay(object = pbmc_small) #' "DefaultAssay<-.Seurat" <- function(object, ..., value) { CheckDots(...) value <- value[1L] value <- match.arg(arg = value, choices = Assays(object = object)) slot(object = object, name = 'active.assay') <- value return(object) } #' @param assay Name of assay to get or set default \code{\link{FOV}} for; #' pass \code{NA} to get or set the global default \code{\link{FOV}} #' #' @rdname DefaultFOV #' @method DefaultFOV Seurat #' @export #' DefaultFOV.Seurat <- function(object, assay = NULL, ...) { assay <- assay[1L] %||% DefaultAssay(object = object) fovs <- .FilterObjects(object = object, classes.keep = 'FOV') if (is.na(x = assay)) { return(fovs[1L]) } assay <- match.arg(arg = assay, choices = Assays(object = object)) assay.fovs <- Filter( f = function(x) { return(DefaultAssay(object = object[[x]]) == assay) }, x = fovs ) if (!length(x = assay.fovs)) { warning( "No FOV associated with assay '", assay, "', using global default FOV", call. = FALSE, immediate. = TRUE ) assay.fovs <- fovs[1L] } return(assay.fovs[1L]) } #' @rdname DefaultFOV #' @method DefaultFOV<- Seurat #' @export #' "DefaultFOV<-.Seurat" <- function(object, assay = NA, ..., value) { assay <- assay[1L] %||% DefaultAssay(object = object) fovs <- .FilterObjects(object = object, classes.keep = 'FOV') value <- match.arg(arg = value, choices = fovs) if (!is.na(x = assay)) { assay <- match.arg(arg = assay, choices = Assays(object = object)) if (DefaultAssay(object = object[[value]]) != assay) { warning( "FOV '", value, "' currently associated with assay '", DefaultAssay(object = object[[value]]), "', changing to '", assay, "'", call. = FALSE, immediate. = TRUE ) DefaultAssay(object = object[[value]]) <- assay } fovs <- Filter( f = function(x) { return(DefaultAssay(object = object[[x]]) == assay) }, x = fovs ) } fidx <- which(x = fovs == value) forder <- c(fidx, setdiff(x = seq_along(along.with = fovs), y = fidx)) fovs <- fovs[forder] iidx <- seq_along(along.with = Images(object = object)) midx <- MatchCells(new = Images(object = object), orig = fovs, ordered = TRUE) iidx[sort(x = midx)] <- midx slot(object = object, name = 'images') <- slot( object = object, name = 'images' )[iidx] return(object) } #' @param reduction Name of reduction to pull cell embeddings for #' #' @rdname Embeddings #' @export #' @method Embeddings Seurat #' #' @examples #' # Get the embeddings from a specific DimReduc in a Seurat object #' Embeddings(object = pbmc_small, reduction = "pca")[1:5, 1:5] #' Embeddings.Seurat <- function(object, reduction = 'pca', ...) { return(Embeddings(object = object[[reduction]], ...)) } #' @method Features Seurat #' @export #' Features.Seurat <- function(x, assay = NULL, ...) { assay <- assay[1L] %||% DefaultAssay(object = x) assay <- match.arg(arg = assay, choices = Assays(object = x)) return(Features(x = x[[assay]], ...)) } #' @param vars List of all variables to fetch, use keyword \dQuote{ident} to #' pull identity classes #' @param cells Cells to collect data for (default is all cells) #' @param layer Layer to pull feature data for #' @param clean Remove cells that are missing data; choose from: #' \itemize{ #' \item \dQuote{\code{all}}: consider all columns for cleaning #' \item \dQuote{\code{ident}}: consider all columns except the identity #' class for cleaning #' \item \dQuote{\code{project}}: consider all columns except the identity #' class for cleaning; fill missing identity values with the object's project #' \item \dQuote{\code{none}}: do not clean #' } #' Passing \code{TRUE} is a shortcut for \dQuote{\code{ident}}; passing #' \code{FALSE} is a shortcut for \dQuote{\code{none}} #' @param slot Deprecated in favor of \code{layer} #' #' @return A data frame with cells as rows and cellular data as columns #' #' @rdname FetchData #' @method FetchData Seurat #' @export #' #' @concept data-access #' #' @examples #' pc1 <- FetchData(object = pbmc_small, vars = 'PC_1') #' head(x = pc1) #' head(x = FetchData(object = pbmc_small, vars = c('groups', 'ident'))) #' FetchData.Seurat <- function( object, vars, cells = NULL, layer = NULL, clean = TRUE, slot = deprecated(), ... ) { if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'FetchData(slot = )', with = 'FetchData(layer = )' ) layer <- layer %||% slot } object <- UpdateSlots(object = object) if (isTRUE(x = clean)) { clean <- 'ident' } else if (isFALSE(x = clean)) { clean <- 'none' } clean <- arg_match0(arg = clean, values = c('all', 'ident', 'none', 'project')) # Find cells to use cells <- cells %||% colnames(x = object) if (is.numeric(x = cells)) { cells <- colnames(x = object)[cells] } if (is.null(x = vars)) { return(data.frame(row.names = cells)) } data.fetched <- EmptyDF(n = length(x = cells)) row.names(x = data.fetched) <- cells # Pull vars from object metadata meta.vars <- intersect(x = vars, y = names(x = object[[]])) meta.vars <- setdiff(x = meta.vars, y = names(x = data.fetched)) if (length(x = meta.vars)) { meta.default <- intersect(x = meta.vars, y = rownames(x = object)) if (length(x = meta.default)) { warn(message = paste0( "The following variables were found in both object meta data and the default assay: ", paste0(meta.default, collapse = ', '), "\nReturning meta data; if you want the feature, please use the assay's key (eg. ", paste0(Key(object = object)[DefaultAssay(object = object)], meta.default[1L]), ")" )) } meta.pull <- object[[meta.vars]] cells.meta <- row.names(x = meta.pull) cells.order <- MatchCells(new = cells.meta, orig = cells, ordered = TRUE) cells.meta <- cells.meta[cells.order] data.fetched[cells.meta, meta.vars] <- meta.pull[cells.meta, , drop = FALSE] } # Find all vars that are keyed keyed.vars <- sapply( X = Keys(object = object), FUN = function(key) { if (!length(x = key) || !nzchar(x = key)) { return(character(length = 0L)) } return(grep(pattern = paste0('^', key), x = setdiff(vars, meta.vars), value = TRUE)) }, simplify = FALSE, USE.NAMES = TRUE ) keyed.vars <- Filter(f = length, x = keyed.vars) # Check spatial keyed vars ret.spatial2 <- vapply( X = names(x = keyed.vars), FUN = function(x) { return(inherits(x = object[[x]], what = 'FOV')) }, FUN.VALUE = logical(length = 1L), USE.NAMES = FALSE ) if (any(ret.spatial2)) { abort(message = "Spatial coordinates are no longer fetchable with FetchData") } # Find all keyed.vars data.keyed <- lapply( X = names(x = keyed.vars), FUN = function(x) { data.return <- switch( EXPR = x, meta.data = { md <- gsub(pattern = '^md', replacement = '', x = keyed.vars[[x]]) df <- object[[md]][cells, , drop = FALSE] names(x = df) <- paste0('md_', names(x = df)) df }, tryCatch( expr = FetchData( object = object[[x]], vars = keyed.vars[[x]], cells = cells, layer = layer, ... ), varsNotFoundError = function(...) { warn(message = paste0( 'The following keyed vars could not be found in object ', sQuote(x = x), ':', paste(keyed.vars[[x]], collapse = ', '), '\nAttempting to pull from other locations' )) return(NULL) } ) ) return(data.return) } ) for (i in seq_along(along.with = data.keyed)) { df <- data.keyed[[i]] data.fetched[row.names(x = df), names(x = df)] <- df } # Pull vars from the default assay default.vars <- intersect(x = vars, y = rownames(x = object)) default.vars <- setdiff(x = default.vars, y = names(x = data.fetched)) if (length(x = default.vars)) { df <- FetchData( object = object[[DefaultAssay(object = object)]], vars = default.vars, cells = cells, layer = layer, ... ) data.fetched[row.names(x = df), names(x = df)] <- df } # Pull identities if ('ident' %in% vars && !'ident' %in% names(x = object[[]])) { data.fetched[cells, 'ident'] <- Idents(object = object)[cells] } # Try to find ambiguous vars vars.missing <- setdiff(x = vars, y = names(x = data.fetched)) if (length(x = vars.missing)) { # Search for vars in alternate assays # Create a list to hold vars and the alternate assays they're found in vars.alt <- vector(mode = 'list', length = length(x = vars.missing)) names(x = vars.alt) <- vars.missing # Search through features in alternate assays to see if # they contain our missing vars for (assay in Assays(object = object)) { vars.assay <- Filter( f = function(x) { return(x %in% Features(x = object, assay = assay, layer = layer)) }, x = vars.missing ) # Add the alternate assay to our holding list for our found vars for (var in vars.assay) { vars.alt[[var]] <- append(x = vars.alt[[var]], values = assay) } } # Vars found in multiple alternative assays are truly ambiguous, will not pull vars.many <- names(x = Filter( f = function(x) { return(length(x = x) > 1) }, x = vars.alt )) if (length(x = vars.many)) { warn(message = paste( "Found the following features in more than one assay, excluding the default.", "We will not include these in the final data frame:", paste(vars.many, collapse = ', ') )) } # Missing vars are either ambiguous or not found in exactly one assay vars.missing <- names(x = Filter( f = function(x) { return(length(x = x) != 1) }, x = vars.alt )) # Pull vars found in only one alternative assay # Key this var to highlight that it was found in an alternate assay vars.alt <- Filter( f = function(x) { return(length(x = x) == 1) }, x = vars.alt ) for (var in names(x = vars.alt)) { assay <- vars.alt[[var]] warn(message = paste( 'Could not find', var, 'in the default search locations, found in', sQuote(x = assay), 'assay instead' )) keyed.var <- paste0(Key(object = object[[assay]]), var) vars[vars == var] <- keyed.var df <- FetchData( object = object[[assay]], vars = keyed.var, cells = cells, layer = layer ) data.fetched[row.names(x = df), names(x = df)] <- df } } # Name the vars not found in a warning (or error if no vars found) # `m2` is an additional message if we're missing more than 10 vars m2 <- if (length(x = vars.missing) > 10) { paste(' (10 out of', length(x = vars.missing), 'shown)') } else { '' } if (length(x = vars.missing) == length(x = vars)) { abort( message = paste0( "None of the requested variables were found", m2, ': ', paste(head(x = vars.missing, n = 10L), collapse = ', ') ), class = 'varsNotFoundError' ) } else if (length(x = vars.missing)) { warn(message = paste0( "The following requested variables were not found", m2, ': ', paste(head(x = vars.missing, n = 10L), collapse = ', ') )) } .FilterData <- function(df) { return(which(x = apply(X = df, MARGIN = 1L, FUN = \(x) all(is.na(x = x))))) } # Clean the fetched data data.fetched <- switch( EXPR = clean, all = { # Clean all vars no.data <- .FilterData(df = data.fetched) if (length(x = no.data)) { warn(message = paste( "Removing", length(x = no.data), "cells missing data for vars requested" )) data.fetched[-no.data, , drop = FALSE] } else { data.fetched } }, ident = { # Clean all vars except ident cols.clean <- names(x = data.fetched) if (ncol(x = data.fetched) > 2L && !'ident' %in% names(x = object[[]])) { cols.clean <- setdiff(x = cols.clean, y = 'ident') } no.data <- .FilterData(df = data.fetched[, cols.clean, drop = FALSE]) if (length(x = no.data)) { warn(message = paste( "Removing", length(x = no.data), "cells missing data for vars requested" )) data.fetched[-no.data, , drop = FALSE] } else { data.fetched } }, project = { # Clean all vars except ident cols.clean <- names(x = data.fetched) if (ncol(x = data.fetched) > 2L && !'ident' %in% names(x = object[[]])) { cols.clean <- setdiff(x = cols.clean, y = 'ident') } no.data <- .FilterData(df = data.fetched[, cols.clean, drop = FALSE]) if (length(x = no.data)) { warn(message = paste( "Removing", length(x = no.data), "cells missing data for vars requested" )) data.fetched <- data.fetched[-no.data, , drop = FALSE] } # When all idents are `NA`, set to Project(object) if ('ident' %in% names(x = data.fetched) && !'ident' %in% names(x = object[[]])) { if (all(is.na(x = data.fetched$ident))) { warn(message = paste( "None of the cells requested have an identity class, returning", sQuote(x = Project(object = object)), "instead" )) data.fetched$ident <- Project(object = object) } } data.fetched }, # Don't clean vars data.fetched ) vars.return <- intersect(x = vars, y = names(x = data.fetched)) data.fetched <- data.fetched[, vars.return, drop = FALSE] # data.order <- na.omit(object = pmatch( # x = vars, # table = names(x = data.fetched) # )) # if (length(x = data.order) > 1) { # data.fetched <- data.fetched[, data.order] # } # colnames(x = data.fetched) <- vars[vars %in% fetched] return(data.fetched) } #' @param assay Specific assay to get data from or set data for; #' defaults to the \link[=DefaultAssay]{default assay} #' #' @rdname AssayData #' @export #' @method GetAssayData Seurat #' #' @order 3 #' #' @examples #' # Get assay data from the default assay in a Seurat object #' GetAssayData(object = pbmc_small, layer = "data")[1:5,1:5] #' GetAssayData.Seurat <- function( object, assay = NULL, layer = NULL, slot = deprecated(), ... ) { CheckDots(...) if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'GetAssayData(slot = )', with = 'GetAssayData(layer = )' ) layer <- slot } object <- UpdateSlots(object = object) assay <- assay %||% DefaultAssay(object = object) assay <- arg_match(arg = assay, values = Assays(object = object)) return(GetAssayData(object = object[[assay]], layer = layer)) } #' @param image Name of \code{SpatialImage} object to pull image data for; if #' \code{NULL}, will attempt to select an image automatically #' #' @rdname GetImage #' @method GetImage Seurat #' @export #' GetImage.Seurat <- function( object, mode = c('grob', 'raster', 'plotly', 'raw'), image = NULL, ... ) { mode <- match.arg(arg = mode) image <- image %||% DefaultImage(object = object) if (is.null(x = image)) { stop("No images present in this Seurat object", call. = FALSE) } return(GetImage(object = object[[image]], mode = mode, ...)) } #' @param image Name of \code{SpatialImage} object to get coordinates for; if #' \code{NULL}, will retrieve coordinates for the default image #' #' @rdname GetTissueCoordinates #' @method GetTissueCoordinates Seurat #' @export #' GetTissueCoordinates.Seurat <- function(object, image = NULL, ...) { image <- image %||% DefaultImage(object = object) if (is.null(x = image)) { stop("No images present in this Seurat object", call. = FALSE) } return(GetTissueCoordinates(object = object[[image]], ...)) } #' @param assay Name of assay to pull highly variable feature information for #' #' @importFrom tools file_path_sans_ext #' #' @rdname VariableFeatures #' @export #' @method HVFInfo Seurat #' #' @order 6 #' #' @examples #' # Get the HVF info from a specific Assay in a Seurat object #' HVFInfo(object = pbmc_small, assay = "RNA")[1:5, ] #' HVFInfo.Seurat <- function( object, method = NULL, status = FALSE, assay = NULL, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = '5.0.0', what = 'HVFInfo(selection.method = )', with = 'HVFInfo(method = )' ) method <- selection.method } object <- UpdateSlots(object = object) assay <- assay %||% DefaultAssay(object = object) if (is.null(x = method)) { cmds <- apply( X = expand.grid( c('FindVariableFeatures', 'SCTransform'), .FilterObjects(object = object, classes.keep = c('Assay', 'Assay5')) ), MARGIN = 1, FUN = paste, collapse = '.' ) find.command <- Command(object = object)[Command(object = object) %in% cmds] if (length(x = find.command) < 1) { abort(message = "Please run either 'FindVariableFeatures' or 'SCTransform'") } find.command <- find.command[length(x = find.command)] test.command <- paste(file_path_sans_ext(x = find.command), assay, sep = '.') find.command <- ifelse( test = test.command %in% Command(object = object), yes = test.command, no = find.command ) method <- switch( EXPR = file_path_sans_ext(x = find.command), 'FindVariableFeatures' = Command( object = object, command = find.command, value = 'selection.method' ), 'SCTransform' = 'sct', stop("Unknown command for finding variable features: '", find.command, "'", call. = FALSE) ) } return(HVFInfo( object = object[[assay]], method = method, status = status )) } #' @rdname Idents #' @export #' @method Idents Seurat #' Idents.Seurat <- function(object, ...) { CheckDots(...) # object <- UpdateSlots(object = object) return(slot(object = object, name = 'active.ident')) } #' @param cells Set cell identities for specific cells #' @param drop Drop unused levels #' @param replace Replace identities for unset cells with \code{NA} #' #' @rdname Idents #' @export #' @method Idents<- Seurat #' "Idents<-.Seurat" <- function( object, cells = NULL, drop = FALSE, replace = FALSE, ..., value ) { CheckDots(...) object <- UpdateSlots(object = object) if (!(is.factor(x = value) || is.atomic(x = value))) { abort(message = "'value' must be a factor or vector") } cells <- cells %||% names(x = value) %||% colnames(x = object) if (is.numeric(x = cells)) { cells <- colnames(x = object)[cells] } cells <- intersect(x = cells, y = colnames(x = object)) # cells <- match(x = cells, table = colnames(x = object)) if (!length(x = cells)) { warn(message = 'Cannot find cells provided') return(object) } idents.new <- if (length(x = value) == 1 && value %in% names(x = object[[]])) { # unlist(x = object[[value]], use.names = FALSE)[cells] object[[value, drop = TRUE]][cells] } else { if (is.list(x = value)) { value <- unlist(x = value, use.names = FALSE) } rep_len(x = value, length.out = length(x = cells)) } new.levels <- if (is.factor(x = idents.new)) { levels(x = idents.new) } else { unique(x = idents.new) } levels <- union(x = new.levels, y = levels(x = object)) idents.new <- as.vector(x = idents.new) idents <- if (isTRUE(x = replace)) { rep_len(x = NA_character_, length.out = ncol(x = object)) } else { as.vector(x = Idents(object = object)) } names(x = idents) <- colnames(x = object) idents[cells] <- idents.new idents[is.na(x = idents)] <- 'NA' levels <- intersect(x = levels, y = unique(x = idents)) names(x = idents) <- colnames(x = object) missing.cells <- which(x = is.na(x = names(x = idents))) if (length(x = missing.cells) > 0) { idents <- idents[-missing.cells] } idents <- factor(x = idents, levels = levels) slot(object = object, name = 'active.ident') <- idents if (isTRUE(x = drop)) { object <- droplevels(x = object) } return(object) } #' @param assay Name of assay to split layers #' #' @rdname SplitLayers #' @method JoinLayers Seurat #' @export #' JoinLayers.Seurat <- function( object, assay = NULL, layers = NULL, new = NULL, ... ) { assay <- assay %||% DefaultAssay(object) object[[assay]] <- JoinLayers( object = object[[assay]], layers = layers, new = new, ... ) return(object) } #' @rdname Key #' @export #' @method Key Seurat #' #' @examples #' # Show all keys associated with a Seurat object #' Key(object = pbmc_small) #' Keys(object = pbmc_small) #' Key.Seurat <- function(object, ...) { CheckDots(...) object <- UpdateSlots(object = object) return(c( meta.data = .MetaKey, vapply( X = .FilterObjects( object = object, classes.keep = c('SpatialImage', 'KeyMixin') ), FUN = \(x) Key(object = object[[x]]), FUN.VALUE = character(length = 1L), USE.NAMES = TRUE ) )) } #' @rdname Key #' @export #' @method Keys Seurat #' Keys.Seurat <- Key.Seurat #' @param assay Name of assay to fetch layer data from or assign layer data to #' #' @rdname Layers #' @method LayerData Seurat #' @export #' LayerData.Seurat <- function( object, layer = NULL, assay = NULL, slot = deprecated(), ... ) { if (is_present(arg = slot)) { deprecate_stop( when = "5.0.0", what = "LayerData(slot = )", with = "LayerData(layer = )" ) } assay <- assay %||% DefaultAssay(object = object) assay <- arg_match(arg = assay, values = Assays(object = object)) return(LayerData(object = object[[assay]], layer = layer, ...)) } #' @rdname Layers #' @method LayerData<- Seurat #' @export #' "LayerData<-.Seurat" <- function(object, layer, assay = NULL, ..., value) { assay <- assay %||% DefaultAssay(object = object) assay <- arg_match(arg = assay, values = Assays(object = object)) LayerData(object = object[[assay]], layer = layer, ...) <- value return(object) } #' @rdname Layers #' @method Layers Seurat #' @export #' Layers.Seurat <- function(object, search = NA, assay = NULL, ...) { assay <- assay %||% DefaultAssay(object = object) assay <- arg_match(arg = assay, values = Assays(object = object)) return(Layers(object = object[[assay]], search = search, ...)) } #' @param reduction Name of reduction to pull feature loadings for #' #' @rdname Loadings #' @export #' @method Loadings Seurat #' #' @examples #' # Get the feature loadings for a specified DimReduc in a Seurat object #' Loadings(object = pbmc_small, reduction = "pca")[1:5,1:5] #' Loadings.Seurat <- function(object, reduction = 'pca', projected = FALSE, ...) { object <- UpdateSlots(object = object) return(Loadings(object = object[[reduction]], projected = projected, ...)) } #' @rdname Misc #' @export #' @method Misc Seurat #' #' @examples #' # Get the misc info #' Misc(object = pbmc_small, slot = "example") #' Misc.Seurat <- .Misc #' @rdname Misc #' @export #' @method Misc<- Seurat #' #' @examples #'# Add misc info #' Misc(object = pbmc_small, slot = "example") <- "testing_misc" #' "Misc<-.Seurat" <- `.Misc<-` #' @rdname Project #' @export #' @method Project Seurat #' Project.Seurat <- function(object, ...) { CheckDots(...) object <- UpdateSlots(object = object) return(slot(object = object, name = 'project.name')) } #' @rdname Project #' @export #' @method Project<- Seurat #' "Project<-.Seurat" <- function(object, ..., value) { CheckDots(...) object <- UpdateSlots(object = object) slot(object = object, name = 'project.name') <- as.character(x = value) return(object) } #' @param reverse Reverse ordering #' @param afxn Function to evaluate each identity class based on; default is #' \code{\link[base]{mean}} #' @param reorder.numeric Rename all identity classes to be increasing numbers #' starting from 1 (default is FALSE) #' #' @rdname Idents #' @export #' @method ReorderIdent Seurat #' ReorderIdent.Seurat <- function( object, var, reverse = FALSE, afxn = mean, reorder.numeric = FALSE, ... ) { object <- UpdateSlots(object = object) data.use <- FetchData(object = object, vars = var, ...)[, 1] rfxn <- ifelse( test = reverse, yes = function(x) { return(max(x) + 1 - x) }, no = identity ) new.levels <- names(x = rfxn(x = sort(x = tapply( X = data.use, INDEX = Idents(object = object), FUN = afxn )))) new.idents <- factor( x = Idents(object = object), levels = new.levels, ordered = TRUE ) if (reorder.numeric) { new.idents <- rfxn(x = rank(x = tapply( X = data.use, INDEX = as.numeric(x = new.idents), FUN = mean )))[as.numeric(x = new.idents)] new.idents <- factor( x = new.idents, levels = 1:length(x = new.idents), ordered = TRUE ) } Idents(object = object) <- new.idents return(object) } #' @param add.cell.id prefix to add cell names #' @param for.merge Deprecated #' #' @details #' If \code{add.cell.id} is set a prefix is added to existing cell names. If #' \code{new.names} is set these will be used to replace existing names. #' #' @rdname RenameCells #' @export #' @method RenameCells Seurat #' #' @examples #' # Rename cells in a Seurat object #' head(x = colnames(x = pbmc_small)) #' pbmc_small <- RenameCells(object = pbmc_small, add.cell.id = "A") #' head(x = colnames(x = pbmc_small)) #' RenameCells.Seurat <- function( object, add.cell.id = missing_arg(), new.names = missing_arg(), for.merge = deprecated(), ... ) { CheckDots(...) object <- UpdateSlots(object = object) all.cells <- colnames(object) default.cells <- Cells(object) if (is_present(arg = for.merge)) { .Deprecate(when = "5.0.0", what = "RenameCells(for.merge = )") } if (is_missing(x = add.cell.id) && is_missing(x = new.names)) { abort(message = "One of 'add.cell.id' and 'new.names' must be set") } if (!is_missing(x = add.cell.id) && !is_missing(x = new.names)) { abort(message = "Only one of 'add.cell.id' and 'new.names' may be set") } if (!missing(x = add.cell.id)) { new.names <- paste(add.cell.id, all.cells, sep = "_") cells.to.rename <- all.cells } else { # Determine which set of cells names `new.names` is intended to replace. # If `new.names` is a named vector, assume it should provide the mapping # we need. if (!is.null(names(new.names))) { cells.to.rename <- names(new.names) } else { # If `new.names` contains a value for every cell in the object, we'll # assume that `new.names` and `all.cells` are co-indexed. if (length(new.names) == length(all.cells)) { cells.to.rename <- all.cells # If `new.names` contains a value for every cell in the default assay, # we'll assume that `new.names` and `default.cells` are co-indexed. } else if (length(new.names) == length(default.cells)) { cells.to.rename <- default.cells # If the length of `new.names` doesn't match either option, we don't # know what cells to rename, so we'll throw an error. } else { stop( sprintf( paste( "`new.names` should be a named list or else be the same length", "as `colnames(object)` (%i) or `Cells(object)` (%i).", "`length(new.names)` was %i." ), length(all.cells), length(default.cells), length(new.names) ) ) } } } # Validate that `cells.to.rename` only contains valid cell names. missing.cells <- setdiff(cells.to.rename, all.cells) if (length(missing.cells) > 0) { stop("The following cells are not present in `object`: ...") } # Create a global mapping for all cell names in `object`. new.cell.names <- setNames(all.cells, all.cells) new.cell.names[cells.to.rename] <- new.names # rename the cell-level metadata first to rename colname() old.meta.data <- object[[]] row.names(x = old.meta.data) <- new.cell.names slot(object = object, name = "meta.data") <- old.meta.data # rename the active.idents old.ids <- Idents(object) names(old.ids) <- new.cell.names Idents(object) <- old.ids # rename in the assay objects assays <- .FilterObjects(object = object, classes.keep = "Assay") for (i in assays) { slot(object = object, name = "assays")[[i]] <- RenameCells( object = object[[i]], new.names = new.cell.names[colnames(x = object[[i]])] ) } # rename in the assay5 objects assays5 <- .FilterObjects(object = object, classes.keep = "Assay5") for (i in assays5) { slot(object = object, name = "assays")[[i]] <- RenameCells( object = object[[i]], new.names = new.cell.names[colnames(x = object[[i]])] ) } # rename in the DimReduc objects dimreducs <- .FilterObjects(object = object, classes.keep = "DimReduc") for (i in dimreducs) { slot(object = object, name = "reductions")[[i]] <- RenameCells( object = object[[i]], new.names = new.cell.names[Cells(x = object[[i]])] ) } # rename the graphs graphs <- .FilterObjects(object = object, classes.keep = "Graph") for (g in graphs) { graph.g <- object[[g]] rownames(graph.g) <- colnames(graph.g) <- new.cell.names[colnames(x = graph.g)] slot(object = object, name = "graphs")[[g]] <- graph.g } # Rename the images for (i in Images(object = object)) { slot(object = object, name = "images")[[i]] <- RenameCells( object = object[[i]], new.names = unname( obj = new.cell.names[Cells(x = object[[i]], boundary = NA)] ) ) } # Rename the Neighbor for (i in Neighbors(object = object)) { slot(object = object, name = "neighbors")[[i]] <- RenameCells( object = object[[i]], old.names = Cells(x = object[[i]]), new.names = new.cell.names[Cells(x = object[[i]])] ) } validObject(object) return(object) } #' @rdname Idents #' @export #' @method RenameIdents Seurat #' RenameIdents.Seurat <- function(object, ...) { ident.pairs <- tryCatch( expr = as.list(x = ...), error = function(e) { return(list(...)) } ) if (is.null(x = names(x = ident.pairs))) { stop("All arguments must be named with the old identity class") } if (!all(sapply(X = ident.pairs, FUN = length) == 1)) { stop("Can only rename identity classes to one value") } if (!any(names(x = ident.pairs) %in% levels(x = object))) { stop("Cannot find any of the provided identities") } cells.idents <- CellsByIdentities(object = object) for (i in rev(x = names(x = ident.pairs))) { if (!i %in% names(x = cells.idents)) { warning("Cannot find identity ", i, call. = FALSE, immediate. = TRUE) next } Idents(object = object, cells = cells.idents[[i]]) <- ident.pairs[[i]] } return(object) } #' @rdname AssayData #' @export #' @method SetAssayData Seurat #' #' @order 4 #' #' @examples #' # Set an Assay layer through the Seurat object #' count.data <- GetAssayData(object = pbmc_small[["RNA"]], layer = "counts") #' count.data <- as.matrix(x = count.data + 1) #' new.seurat.object <- SetAssayData( #' object = pbmc_small, #' layer = "counts", #' new.data = count.data, #' assay = "RNA" #' ) #' SetAssayData.Seurat <- function( object, layer = 'data', new.data, slot = deprecated(), assay = NULL, ... ) { CheckDots(...) if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'SetAssayData(slot = )', with = 'SetAssayData(layer = )' ) layer <- slot } object <- UpdateSlots(object = object) assay <- assay %||% DefaultAssay(object = object) object[[assay]] <- SetAssayData( object = object[[assay]], layer = layer, new.data = new.data, ... ) return(object) } #' @rdname Idents #' @export #' @method SetIdent Seurat #' SetIdent.Seurat <- function(object, cells = NULL, value, ...) { #message( # 'With Seurat 3.X, setting identity classes can be done as follows:\n', # 'Idents(object = ', # deparse(expr = substitute(expr = object)), # if (!is.null(x = cells)) { # paste0(', cells = ', deparse(expr = substitute(expr = cells))) # }, # ') <- ', # deparse(expr = substitute(expr = value)) #) CheckDots(...) object <- UpdateSlots(object = object) Idents(object = object, cells = cells) <- value return(object) } #' @rdname VariableFeatures #' @export #' @method SpatiallyVariableFeatures Seurat #' #' @order 10 #' SpatiallyVariableFeatures.Seurat <- function( object, method = "moransi", assay = NULL, decreasing = TRUE, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = '5.0.0', what = 'SpatiallyVariableFeatures(selection.method = )', with = 'SpatiallyVariableFeatures(method = )' ) method <- selection.method } assay <- assay %||% DefaultAssay(object = object) return(SpatiallyVariableFeatures( object = object[[assay]], method = method, decreasing = decreasing )) } #' @param save.name Store current identity information under this name #' #' @rdname Idents #' @export #' @method StashIdent Seurat #' StashIdent.Seurat <- function(object, save.name = 'orig.ident', ...) { deprecate_soft( when = '3.0.0', what = 'StashIdent()', details = paste0( "Please use ", deparse(expr = substitute(expr = object)), '[[', deparse(expr = substitute(expr = save.name)), ']] <- Idents(', deparse(expr = substitute(expr = object)), ')' ) ) CheckDots(...) object <- UpdateSlots(object = object) object[[save.name]] <- Idents(object = object) return(object) } #' @param reduction Name of reduction to use #' #' @rdname Stdev #' @export #' @method Stdev Seurat #' #' @examples #' # Get the standard deviations for each PC from the Seurat object #' Stdev(object = pbmc_small, reduction = "pca") #' Stdev.Seurat <- function(object, reduction = 'pca', ...) { CheckDots(...) return(Stdev(object = object[[reduction]])) } #' @importFrom tools file_path_sans_ext #' #' @rdname VariableFeatures #' @export #' @method SVFInfo Seurat #' #' @order 9 #' SVFInfo.Seurat <- function( object, method = c("markvariogram", "moransi"), status = FALSE, assay = NULL, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = '5.0.0', what = 'SVFInfo(selection.method = )', with = 'SVFInfo(method = )' ) method <- selection.method } assay <- assay %||% DefaultAssay(object = object) return(SVFInfo(object = object[[assay]], method = method, status = status)) } #' @param slot Name of tool to pull #' #' @rdname Tool #' @export #' @method Tool Seurat #' Tool.Seurat <- function(object, slot = NULL, ...) { CheckDots(...) object <- UpdateSlots(object = object) if (is.null(x = slot)) { return(names(x = slot(object = object, name = 'tools'))) } return(slot(object = object, name = 'tools')[[slot]]) } #' @rdname Tool #' @export #' @method Tool<- Seurat #' "Tool<-.Seurat" <- function(object, ..., value) { CheckDots(...) object <- UpdateSlots(object = object) calls <- as.character(x = sys.calls()) calls <- lapply( X = strsplit(x = calls, split = '(', fixed = TRUE), FUN = '[', 1 ) tool.call <- min(grep(pattern = 'Tool<-', x = calls)) if (tool.call <= 1) { stop("'Tool<-' cannot be called at the top level", call. = FALSE) } tool.call <- calls[[tool.call - 1]] class.call <- unlist(x = strsplit( x = as.character(x = sys.call())[1], split = '.', fixed = TRUE )) class.call <- class.call[length(x = class.call)] tool.call <- sub( pattern = paste0('\\.', class.call, '$'), replacement = '', x = tool.call, perl = TRUE ) slot(object = object, name = 'tools')[[tool.call]] <- value return(object) } #' @rdname VariableFeatures #' @export #' @method VariableFeatures Seurat #' #' @order 7 #' VariableFeatures.Seurat <- function( object, method = NULL, assay = NULL, nfeatures = NULL, layer = NA, simplify = TRUE, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = '5.0.0', what = 'VariableFeatures(selection.method = )', with = 'VariableFeatures(method = )' ) method <- selection.method } assay <- assay %||% DefaultAssay(object = object) return(VariableFeatures( object = object[[assay]], method = method, nfeatures = nfeatures, layer = layer, simplify = simplify, ... )) } #' @rdname VariableFeatures #' @export #' @method VariableFeatures<- Seurat #' #' @order 8 #' "VariableFeatures<-.Seurat" <- function(object, assay = NULL, ..., value) { CheckDots(...) object <- UpdateSlots(object = object) assay <- assay %||% DefaultAssay(object = object) VariableFeatures(object = object[[assay]]) <- value return(object) } #' @param idents A vector of identity classes to keep #' @param slot Slot to pull feature data for #' @param downsample Maximum number of cells per identity class, default is #' \code{Inf}; downsampling will happen after all other operations, including #' inverting the cell selection #' @param seed Random seed for downsampling. If NULL, does not set a seed #' @inheritDotParams CellsByIdentities #' #' @importFrom stats na.omit #' @importFrom rlang is_quosure enquo eval_tidy #' #' @rdname WhichCells #' @export #' @method WhichCells Seurat #' WhichCells.Seurat <- function( object, cells = NULL, idents = NULL, expression, slot = 'data', invert = FALSE, downsample = Inf, seed = 1, ... ) { CheckDots(..., fxns = CellsByIdentities) if (!is.null(x = seed)) { set.seed(seed = seed) } object <- UpdateSlots(object = object) cells <- cells %||% colnames(x = object) if (is.numeric(x = cells)) { cells <- colnames(x = object)[cells] } cell.order <- cells if (!is.null(x = idents)) { if (any(!idents %in% levels(x = Idents(object = object)))) { stop( "Cannot find the following identities in the object: ", paste( idents[!idents %in% levels(x = Idents(object = object))], sep = ', ' ) ) } cells.idents <- unlist(x = lapply( X = idents, FUN = function(i) { cells.use <- which(x = as.vector(x = Idents(object = object)) == i) cells.use <- names(x = Idents(object = object)[cells.use]) return(cells.use) } )) cells <- intersect(x = cells, y = cells.idents) } if (!missing(x = expression)) { objects.use <- .FilterObjects( object = object, classes.keep = c('Assay', 'StdAssay', 'DimReduc', 'SpatialImage') ) object.keys <- sapply( X = objects.use, FUN = function(i) { return(Key(object = object[[i]])) } ) key.pattern <- paste0('^', object.keys, collapse = '|') expr <- if (tryCatch(expr = is_quosure(x = expression), error = function(...) FALSE)) { expression } else if (is.call(x = enquo(arg = expression))) { enquo(arg = expression) } else { parse(text = expression) } expr.char <- all.vars(expr) vars.use <- which( x = expr.char %in% rownames(x = object) | expr.char %in% colnames(x = object[[]]) | grepl(pattern = key.pattern, x = expr.char, perl = TRUE) ) data.subset <- FetchData( object = object, vars = unique(x = expr.char[vars.use]), cells = cells, layer = slot ) cells <- rownames(x = data.subset)[eval_tidy(expr = expr, data = data.subset)] } if (isTRUE(x = invert)) { cell.order <- colnames(x = object) cells <- colnames(x = object)[!colnames(x = object) %in% cells] } # only perform downsampling when "downsample" is smaller than the number of cells if(downsample <= length(cells)){ cells <- CellsByIdentities(object = object, cells = cells, ...) cells <- lapply( X = cells, FUN = function(x) { if (length(x = x) > downsample) { x <- sample(x = x, size = downsample, replace = FALSE) } return(x) } ) cells <- as.character(x = na.omit(object = unlist(x = cells, use.names = FALSE))) } cells <- cells[na.omit(object = match(x = cell.order, table = cells))] return(cells) } #' @rdname Version #' @method Version Seurat #' @export #' Version.Seurat <- function(object, ...) { CheckDots(...) return(slot(object = object, name = 'version')) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Dollar-sign Autocompletion #' #' Autocompletion for \code{$} access on a \code{\link{Seurat}} object #' #' @inheritParams utils::.DollarNames #' @param x A \code{\link{Seurat}} object #' #' @return The meta data matches for \code{pattern} #' #' @importFrom utils .DollarNames #' #' @keywords internal #' #' @method .DollarNames Seurat #' @export #' #' @concept seurat #' #' @inherit .DollarNames.Assay5 seealso #' ".DollarNames.Seurat" <- function(x, pattern = '') { meta.data <- as.list(x = colnames(x = x[[]])) names(x = meta.data) <- unlist(x = meta.data) return(.DollarNames(x = meta.data, pattern = pattern)) } #' Cell-Level Meta Data #' #' Get and set cell-level meta data #' #' @inheritParams .DollarNames.Seurat #' @param i Name of cell-level meta data #' @param j Ignored #' @template param-dots-ignored #' #' @return {$}: Metadata column \code{i} for object \code{x}; #' \strong{note}: unlike \code{[[}, \code{$} drops the shape of the metadata #' to return a vector instead of a data frame #' #' @method $ Seurat #' @export #' #' @family seurat #' #' @examples #' # Get metadata using `$' #' head(pbmc_small$groups) #' "$.Seurat" <- function(x, i) { return(x[[i, drop = TRUE]]) } #' @param value A vector to add as cell-level meta data #' #' @return \code{$<-}: \code{x} with metadata \code{value} saved as \code{i} #' #' @rdname cash-.Seurat #' #' @method $<- Seurat #' @export #' #' @examples #' # Add metadata using the `$' operator #' set.seed(42) #' pbmc_small$value <- sample(1:3, size = ncol(pbmc_small), replace = TRUE) #' head(pbmc_small[["value"]]) #' "$<-.Seurat" <- function(x, i, ..., value) { x[[i]] <- value return(x) } #' @return \code{[}: object \code{x} with features \code{i} and cells \code{j} #' #' @rdname subset.Seurat #' #' @method [ Seurat #' @export #' #' @order 2 #' #' @examples #' # `[` examples #' pbmc_small[VariableFeatures(object = pbmc_small), ] #' pbmc_small[, 1:10] #' "[.Seurat" <- function(x, i, j, ...) { x <- UpdateSlots(object = x) if (missing(x = i) && missing(x = j)) { return(x) } if (missing(x = i)) { i <- NULL } else if (missing(x = j)) { j <- colnames(x = x) } if (is.logical(x = i)) { if (length(i) != nrow(x = x)) { stop("Incorrect number of logical values provided to subset features") } i <- rownames(x = x)[i] } if (is.logical(x = j)) { if (length(j) != ncol(x = x)) { stop("Incorrect number of logical values provided to subset cells") } j <- colnames(x = x)[j] } if (is.numeric(x = i)) { i <- rownames(x = x)[i] } if (is.numeric(x = j)) { j <- colnames(x = x)[j] } return(subset.Seurat(x = x, features = i, cells = j, ...)) } #' Subobjects and Cell-Level Meta Data #' #' The \code{[[} operator pulls either subobjects #' (eg. \link[=Assay]{v3} or \link[=Assay5]{v5} assays, #' \link[=DimReduc]{dimensional reduction} information, #' or \link[=Graph]{nearest-neighbor graphs}) or cell-level #' meta data from a \code{\link{Seurat}} object #' #' @inheritParams $.Seurat #' @param drop See \code{\link[base]{drop}} #' @param na.rm Remove cells where meta data is all \code{NA} #' #' @return Varies based on the value of \code{i}: #' \itemize{ #' \item If \code{i} is missing, a data frame with cell-level meta data #' \item If \code{i} is a vector with cell-level meta data names, a data frame #' (or vector of \code{drop = TRUE}) with cell-level meta data requested #' \item If \code{i} is a one-length character with the #' \link[=names.Seurat]{name of a subobject}, the #' subobject specified by \code{i} #' } #' #' @method [[ Seurat #' @export #' #' @family seurat #' #' @seealso See \link[=$.Seurat]{here} for adding meta data with \code{[[<-}, #' \link[=[[<-,Seurat]{here} for adding subobjects with \code{[[<-}, and #' \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta #' data with \code{[[<-} #' #' @examples #' # Get the cell-level metadata data frame #' head(pbmc_small[[]]) #' #' # Pull specific metadata information #' head(pbmc_small[[c("letter.idents", "groups")]]) #' head(pbmc_small[["groups", drop = TRUE]]) #' #' # Get a sub-object (eg. an `Assay` or `DimReduc`) #' pbmc_small[["RNA"]] #' pbmc_small[["pca"]] #' "[[.Seurat" <- function(x, i = missing_arg(), ..., drop = FALSE, na.rm = FALSE) { md <- slot(object = x, name = 'meta.data') if (is_missing(x = i)) { return(md) } else if (is.null(x = i)) { return(NULL) } else if (!length(x = i)) { return(data.frame(row.names = row.names(x = md))) } # Correct invalid `i` meta.cols <- names(x = md) if (is_bare_integerish(x = i)) { if (all(i > length(x = meta.cols))) { abort(message = paste( "Invalid integer indexing:", "all integers greater than the number of meta columns" )) } i <- meta.cols[as.integer(x = i[i <= length(x = meta.cols)])] } if (!is.character(x = i)) { abort(message = "'i' must be a character vector") } # Determine if we're pulling cell-level meta data # or a sub-object slot.use <- if (length(x = i) == 1L) { .FindObject(object = x, name = i) } else { NULL } # Pull cell-level meta data if (is.null(x = slot.use)) { i <- tryCatch( expr = arg_match(arg = i, values = meta.cols, multiple = TRUE), error = function(e) { #error message that indicates which colnames not found abort( message = paste( paste(sQuote(x = setdiff(x = i, y = meta.cols)), collapse = ', '), "not found in this Seurat object\n", e$body ), call = rlang::caller_env(n = 4L) ) } ) # Pull the cell-level meta data data.return <- md[, i, drop = FALSE, ...] # If requested, remove NAs if (isTRUE(x = na.rm)) { idx.na <- apply(X = is.na(x = data.return), MARGIN = 1L, FUN = all) data.return <- data.return[!idx.na, , drop = FALSE] } else { idx.na <- rep_len(x = FALSE, length.out = ncol(x = x)) } # If requested, coerce to a vector if (isTRUE(x = drop)) { data.return <- unlist(x = data.return, use.names = FALSE) names(x = data.return) <- rep.int( x = colnames(x = x)[!idx.na], times = length(x = i) ) } return(data.return) } # Pull a sub-object return(slot(object = x, name = slot.use)[[i]]) } #' @inherit dim.Assay5 return title description details #' #' @inheritParams .DollarNames.Seurat #' #' @method dim Seurat #' @export #' #' @family seurat #' #' @examples #' # Get the number of features in an object #' nrow(pbmc_small) #' #' # Get the number of cells in an object #' ncol(pbmc_small) #' dim.Seurat <- function(x) { return(c( nrow(x = x[[DefaultAssay(object = x)]]) %||% 0L, length(x = colnames(x = x)) %||% 0L )) } #' Feature and Cell Names #' #' Get and set feature and cell inames in \code{\link{Seurat}} objects #' #' @inheritParams .DollarNames.Seurat #' @inheritParams dimnames.Assay5 #' #' @return \code{dimnames}: A two-length list with the following values: #' \itemize{ #' \item A character vector with all features in the #' \link[=DefaultAssay]{default assay} #' \item A character vector with all cells in \code{x} #' } #' #' @method dimnames Seurat #' @export #' #' @family seurat #' @family dimnames #' #' @examples #' # Get the feature names of an object #' head(rownames(pbmc_small)) #' #' # Get the cell names of an object #' head(colnames(pbmc_small)) #' dimnames.Seurat <- function(x) { return(list( rownames(x = x[[DefaultAssay(object = x)]]), row.names(x = slot(object = x, name = 'meta.data')) )) } #' @return \code{dimnames<-}: \code{x} with the feature and/or cell #' names updated to \code{value} #' #' @rdname dimnames.Seurat #' #' @method dimnames<- Seurat #' @export #' #' @examples #' colnames(pbmc_small)[1] <- "newcell" #' head(colnames(pbmc_small)) #' "dimnames<-.Seurat" <- function(x, value) { op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op), add = TRUE) # Check the provided dimnames msg <- "Invalid 'dimnames' given for a Seurat object" if (!is_bare_list(x = value, n = 2L)) { abort(message = msg) } else if (!all(sapply(X = value, FUN = length) == dim(x = x))) { abort(message = msg) } value <- lapply(X = value, FUN = as.character) onames <- dimnames(x = x) # Rename cells at the Seurat level names(x = slot(object = x, name = 'active.ident')) <- row.names(x = slot(object = x, name = 'meta.data')) <- value[[2L]] # Rename features/cells at the Assay level v3warn <- FALSE for (assay in Assays(object = x)) { anames <- dimnames(x = x[[assay]]) if (inherits(x = x[[assay]], what = 'StdAssay')) { afeatures <- MatchCells( new = onames[[1L]], orig = anames[[1L]], ordered = TRUE ) if (length(x = afeatures)) { idx <- MatchCells(new = anames[[1L]], orig = onames[[1L]]) anames[[1L]][idx] <- value[[1L]][afeatures] } } else if (isFALSE(x = v3warn) && any(onames[[1L]] != value[[1L]])) { warning( "Renaming features in v3/v4 assays is not supported", call. = FALSE, immediate. = TRUE ) v3warn <- TRUE } acells <- MatchCells(new = onames[[2L]], orig = anames[[2L]]) anames[[2L]] <- value[[2L]][acells] suppressWarnings(expr = dimnames(x = x[[assay]]) <- anames) } # Rename features/cells at the DimReduc level for (reduc in Reductions(object = x)) { rnames <- Cells(x = x[[reduc]]) rcells <- MatchCells(new = onames[[2L]], orig = rnames) suppressWarnings( expr = x[[reduc]] <- RenameCells( object = x[[reduc]], old.names = rnames, new.names = value[[2L]][rcells] ) ) if (!is.null(x = Features(x = x[[reduc]]))) { rfnames <- Features(x = x[[reduc]]) rfeatures <- MatchCells( new = onames[[1L]], orig = rfnames, ordered = TRUE ) if (length(x = rfeatures)) { suppressWarnings( expr = x[[reduc]] <- .RenameFeatures( object = x[[reduc]], old.names = rfnames, new.names = value[[1L]][rfeatures] ) ) } } } # TODO: Rename features/cells at the image level for (img in Images(object = x)) { inames <- Cells(x = x[[img]]) icells <- MatchCells(new = onames[[2L]], orig = inames) suppressWarnings( # TODO: replace with `x[[img]] <-` expr = slot(object = x, name = 'images')[[img]] <- RenameCells( object = x[[img]], old.names = inames, new.names = value[[2L]][icells] ) ) # TODO: rename features } # Rename cells at the Graph level for (graph in Graphs(object = x)) { gnames <- dimnames(x = x[[graph]]) for (i in seq_along(along.with = gnames)) { gcells <- MatchCells(new = onames[[2L]], orig = gnames[[i]]) gnames[[i]] <- value[[2L]][gcells] } suppressWarnings(expr = dimnames(x = x[[graph]]) <- gnames) } # Rename cells at the Neighbor level for (nn in Neighbors(object = x)) { nnames <- Cells(x = x[[nn]]) ncells <- MatchCells(new = onames[[2L]], orig = nnames) suppressWarnings( # TODO: replace with `x[[nn]] <-` expr = slot(object = x, name = 'neighbors')[[nn]] <- RenameCells( object = x[[nn]], old.names = nnames, new.names = value[[2L]][ncells] ) ) } # Validate and return options(op) validObject(object = x) return(x) } #' @rdname Idents #' @export #' @method droplevels Seurat #' droplevels.Seurat <- function(x, ...) { x <- UpdateSlots(object = x) slot(object = x, name = 'active.ident') <- droplevels(x = Idents(object = x), ...) return(x) } #' @param n Number of meta data rows to show #' #' @return \code{head}: The first \code{n} rows of cell-level metadata #' #' @rdname sub-sub-.Seurat #' #' @method head Seurat #' @export #' #' @examples #' # Get the first 10 rows of cell-level metadata #' head(pbmc_small) #' head.Seurat <- .head #' @rdname Idents #' @export #' @method levels Seurat #' #' @examples #' # Get the levels of identity classes of a Seurat object #' levels(x = pbmc_small) #' levels.Seurat <- function(x) { x <- UpdateSlots(object = x) return(levels(x = Idents(object = x))) } #' @rdname Idents #' @export #' @method levels<- Seurat #' #' @examples #' # Reorder identity classes #' levels(x = pbmc_small) #' levels(x = pbmc_small) <- c('C', 'A', 'B') #' levels(x = pbmc_small) #' "levels<-.Seurat" <- function(x, value) { x <- UpdateSlots(object = x) idents <- Idents(object = x) if (!all(levels(x = idents) %in% value)) { stop("NA's generated by missing levels", call. = FALSE) } idents <- factor(x = idents, levels = value) Idents(object = x) <- idents return(x) } #' Merge Seurat Objects #' #' @inheritParams CreateSeuratObject #' @inheritParams merge.Assay5 #' @param x A \code{\link{Seurat}} object #' @param y A single \code{Seurat} object or a list of \code{Seurat} objects #' @param add.cell.ids A character vector of \code{length(x = c(x, y))}; #' appends the corresponding values to the start of each objects' cell names #' @param merge.data Merge the data slots instead of just merging the counts #' (which requires renormalization); this is recommended if the same #' normalization approach was applied to all objects #' @param merge.dr Choose how to handle merging dimensional reductions: #' \itemize{ #' \item \dQuote{\code{TRUE}}: merge dimensional reductions with the same name #' across objects; dimensional reductions with different names are added as-is #' \item \dQuote{\code{NA}}: keep dimensional reductions from separate objects #' separate; will append the project name for duplicate reduction names #' \item \dQuote{\code{FALSE}}: do not add dimensional reductions #' } #' #' @return \code{merge}: Merged object #' #' @section Merge Details: #' When merging Seurat objects, the merge procedure will merge the Assay level #' counts and potentially the data slots (depending on the merge.data parameter). #' It will also merge the cell-level meta data that was stored with each object #' and preserve the cell identities that were active in the objects pre-merge. #' The merge will optionally merge reductions depending on the values passed to #' \code{merge.dr} if they have the same name across objects. Here the #' embeddings slots will be merged and if there are differing numbers of #' dimensions across objects, only the first N shared dimensions will be merged. #' The feature loadings slots will be filled by the values present in the first #' object.The merge will not preserve graphs, logged commands, or feature-level #' metadata that were present in the original objects. If add.cell.ids isn't #' specified and any cell names are duplicated, cell names will be appended #' with _X, where X is the numeric index of the object in c(x, y). #' #' @method merge Seurat #' @export #' #' @family seurat #' #' @aliases merge MergeSeurat AddSamples #' #' @examples #' # `merge' examples #' # merge two objects #' merge(pbmc_small, y = pbmc_small) #' # to merge more than two objects, pass one to x and a list of objects to y #' merge(pbmc_small, y = c(pbmc_small, pbmc_small)) #' merge.Seurat <- function( x = NULL, y = NULL, add.cell.ids = NULL, collapse = FALSE, merge.data = TRUE, merge.dr = FALSE, project = getOption(x = 'Seurat.object.project', default = 'SeuratProject'), ... ) { CheckDots(...) objects <- c(x, y) projects <- vapply( X = objects, FUN = Project, FUN.VALUE = character(length = 1L) ) if (anyDuplicated(x = projects)) { projects <- as.character(x = seq_along(along.with = objects)) } # Check cell names if (is_na(x = add.cell.ids)) { add.cell.ids <- as.character(x = seq_along(along.with = objects)) } else if (isTRUE(x = add.cell.ids)) { add.cell.ids <- projects } if (!is.null(x = add.cell.ids)) { if (length(x = add.cell.ids) != length(x = objects)) { abort( message = "Please provide a cell identifier for each object provided to merge" ) } for (i in 1:length(x = objects)) { objects[[i]] <- RenameCells(object = objects[[i]], add.cell.id = add.cell.ids[i]) } } objects <- CheckDuplicateCellNames(object.list = objects) # Merge assays assays <- Reduce(f = union, x = lapply(X = objects, FUN = Assays)) assay.classes <- sapply( X = assays, FUN = function(a) { cls <- vector(mode = 'character', length = length(x = objects)) for (i in seq_along(along.with = cls)) { cls[i] <- if (a %in% Assays(object = objects[[i]])) { class(x = objects[[i]][[a]])[1L] } else { NA_character_ } } return(unique(x = cls[!is.na(x = cls)])) }, simplify = FALSE, USE.NAMES = TRUE ) assays.all <- vector(mode = 'list', length = length(x = assays)) names(x = assays.all) <- assays for (assay in assays) { assay.objs <- which(x = vapply( X = lapply(X = objects, FUN = names), FUN = '%in%', FUN.VALUE = logical(length = 1L), x = assay )) if (length(x = assay.objs) == 1L) { assays.all[[assay]] <- objects[[assay.objs]][[assay]] next } idx.x <- assay.objs[[1L]] idx.y <- setdiff(x = assay.objs, y = idx.x) assays.all[[assay]] <- merge( x = objects[[idx.x]][[assay]], y = lapply(X = objects[idx.y], FUN = '[[', assay), labels = projects[assay.objs], add.cell.ids = NULL, collapse = collapse, merge.data = merge.data ) } names(objects) <- NULL all.cells <- Reduce(f = union, x = lapply(X = objects, FUN = colnames)) idents.all <- unlist(x = lapply(X = objects, FUN = Idents)) idents.all <- idents.all[all.cells] md.all <- EmptyDF(n = length(x = all.cells)) row.names(x = md.all) <- all.cells obj.combined <- new( Class = 'Seurat', assays = assays.all, reductions = list(), images = list(), meta.data = md.all, active.assay = DefaultAssay(object = x), active.ident = idents.all, project.name = project ) # Merge cell-level meta data, images for (i in seq_along(along.with = objects)) { df <- data.frame( lapply(objects[[i]][[]], FUN = function(x) { if (is.factor(x)) as.character(x) else x }), stringsAsFactors=FALSE ) rownames(df) <- rownames(objects[[i]][[]]) obj.combined[[]] <- df for (img in Images(object = objects[[i]])) { dest <- ifelse( test = img %in% Images(object = obj.combined), yes = paste(img, projects[i], sep = '.'), no = img ) obj.combined[[dest]] <- objects[[i]][[img]] } } # Merge dimensional reductions reducs.combined <- list() if (is.character(x = merge.dr)) { warn(message = "'merge.Seurat' no longer supports filtering dimensional reductions; merging all dimensional reductions") merge.dr <- TRUE } if (isTRUE(x = merge.dr)) { for (i in seq_along(along.with = objects)) { for (reduc in Reductions(object = objects[[i]])) { reducs.combined[[reduc]] <- if (reduc %in% names(x = reducs.combined)) { inform(message = paste("Merging reduction", sQuote(x = reduc))) merge(x = reducs.combined[[reduc]], y = objects[[i]][[reduc]]) } else { objects[[i]][[reduc]] } } } } else if (is_na(x = merge.dr)) { reducs.all <- unlist( x = lapply(X = objects, FUN = Reductions), use.names = FALSE ) reducs.dup <- unique(x = reducs.all[duplicated(x = reducs.all)]) for (i in seq_along(along.with = objects)) { for (reduc in Reductions(object = objects[[i]])) { rname <- ifelse( test = reduc %in% reducs.dup, yes = paste(reduc, projects[i], sep = '.'), no = reduc ) reducs.combined[[rname]] <- objects[[i]][[reduc]] if (rname != reduc) { inform(message = paste( "Changing", reduc, "in object", projects[i], "to", rname )) new.key <- Key(object = rname, quiet = TRUE) inform(message = paste("Updating key to", new.key)) Key(object = reducs.combined[[rname]]) <- new.key } } } } for (reduc in names(x = reducs.combined)) { obj.combined[[reduc]] <- reducs.combined[[reduc]] } # Validate and return validObject(object = obj.combined) return(obj.combined) # Merge DimReducs combined.reductions <- list() if (!is.null(x = merge.dr)) { for (dr in merge.dr) { drs.to.merge <- list() for (i in 1:length(x = objects)) { if (!dr %in% Reductions(object = objects[[i]])) { warning("The DimReduc ", dr, " is not present in all objects being ", "merged. Skipping and continuing.", call. = FALSE, immediate. = TRUE) break } drs.to.merge[[i]] <- objects[[i]][[dr]] } if (length(x = drs.to.merge) == length(x = objects)) { combined.reductions[[dr]] <- merge( x = drs.to.merge[[1]], y = drs.to.merge[2:length(x = drs.to.merge)] ) } } } } #' Subobject Names #' #' Get the names of subobjects within a \code{\link{Seurat}} object #' #' @inheritParams .DollarNames.Seurat #' #' @return The names of all of the following subobjects within \code{x}: #' \itemize{ #' \item \link[=Assay]{v3} and \link[=Assay5]{v5} assays #' \item \link[=DimReduc]{dimensional reductions} #' \item \link[=SpatialImage]{images} and \link[=FOV]{FOVs} #' \item \link[=Graph]{nearest-neighbor graphs} #' } #' #' @method names Seurat #' @export #' #' @family seurat #' #' @examples #' names(pbmc_small) #' names.Seurat <- function(x) { return(.FilterObjects( object = x, classes.keep = c('Assay', 'StdAssay', 'DimReduc', 'Graph', 'SpatialImage') )) } #' @inherit split.Assay5 params return title description details sections #' #' @keywords internal #' @method split Seurat #' @export #' #' @family Seurat #' split.Seurat <- function( x, f, drop = FALSE, assay = NULL, layers = NA, ... ){ assay <- assay %||% DefaultAssay(x) x[[assay]] <- split( x = x[[assay]], f = f, drop = drop, layers = layers, ret = 'assay', ... ) return(x) } #' Subset \code{Seurat} Objects #' #' @inheritParams .DollarNames.Seurat #' @inheritParams CellsByIdentities #' @param subset Logical expression indicating features/variables to keep #' @param cells,j A vector of cell names or indices to keep #' @param features,i A vector of feature names or indices to keep #' @param idents A vector of identity classes to keep #' @param ... Arguments passed to \code{\link{WhichCells}} #' #' @return \code{subset}: A subsetted \code{Seurat} object #' #' @importFrom rlang enquo #' #' @export #' @method subset Seurat #' #' @family seurat # #' @seealso \code{\link{WhichCells}} #' #' @aliases subset #' #' @order 1 #' #' @examples #' # `subset` examples #' subset(pbmc_small, subset = MS4A1 > 4) #' subset(pbmc_small, subset = `DLGAP1-AS1` > 2) #' subset(pbmc_small, idents = '0', invert = TRUE) #' subset(pbmc_small, subset = MS4A1 > 3, slot = 'counts') #' subset(pbmc_small, features = VariableFeatures(object = pbmc_small)) #' subset.Seurat <- function( x, subset, cells = NULL, features = NULL, idents = NULL, return.null = FALSE, ... ) { # var.features <- VariableFeatures(object = x) if (!missing(x = subset)) { subset <- enquo(arg = subset) } cells <- WhichCells( object = x, cells = cells, idents = idents, expression = subset, return.null = TRUE, ... ) if (length(x = cells) == 0) { if (isTRUE(x = return.null)) { return(NULL) } abort(message = "No cells found") } if (all(cells %in% Cells(x = x)) && length(x = cells) == length(x = colnames(x = x)) && is.null(x = features) ) { return(x) } op <- options(Seurat.object.validate = FALSE, Seurat.object.assay.calcn = FALSE) on.exit(expr = options(op), add = TRUE) # Remove metadata for cells not present orig.cells <- colnames(x = x) cells <- intersect(x = orig.cells, y = cells) slot(object = x, name = 'meta.data') <- x[[]][cells, , drop = FALSE] if (!all(orig.cells %in% cells)) { # Remove neighbors slot(object = x, name = 'neighbors') <- list() # Filter Graphs for (g in names(slot(object = x, name = 'graphs'))) { cells.g <- intersect(colnames(x[[g]]), cells) suppressWarnings( expr = x[[g]] <- as.Graph(x = x[[g]][cells.g, cells.g, drop = FALSE]) ) } } Idents(object = x, drop = TRUE) <- Idents(object = x)[cells] # Filter Assay objects for (assay in Assays(object = x)) { if (length(x = intersect(colnames(x = x[[assay]]), cells)) == 0) { message(assay, " assay doesn't leave any cells, so it is removed") if (DefaultAssay(x) == assay) { stop('No cells left in the default assay, please change the default assay') } slot(object = x, name = 'assays')[[assay]] <- NULL } else { assay.features <- features %||% rownames(x = x[[assay]]) suppressWarnings( expr = slot(object = x, name = 'assays')[[assay]] <- tryCatch( # because subset is also an argument, we need to explictly use the base::subset function expr = suppressWarnings( expr = base::subset( x = x[[assay]], cells = cells, features = assay.features ), classes = 'validationWarning' ), error = function(e) { if (e$message == "Cannot find features provided") { return(NULL) } else { stop(e) } } ) ) } } slot(object = x, name = 'assays') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'assays') ) if (length(x = .FilterObjects(object = x, classes.keep = c('Assay', 'StdAssay'))) == 0 || is.null(x = x[[DefaultAssay(object = x)]])) { abort(message = "Under current subsetting parameters, the default assay will be removed. Please adjust subsetting parameters or change default assay") } # Filter DimReduc objects for (dimreduc in .FilterObjects(object = x, classes.keep = 'DimReduc')) { suppressWarnings( x[[dimreduc]] <- tryCatch( expr = subset.DimReduc(x = x[[dimreduc]], cells = cells, features = features), error = function(e) { if (e$message %in% c("Cannot find cell provided", "Cannot find features provided")) { return(NULL) } else { stop(e) } } ) ) } # Recalculate nCount and nFeature if (!is.null(features)) { for (assay in .FilterObjects(object = x, classes.keep = 'Assay')) { n.calc <- CalcN(object = x[[assay]]) if (!is.null(x = n.calc)) { names(x = n.calc) <- paste(names(x = n.calc), assay, sep = '_') suppressWarnings( expr = x[[names(x = n.calc)]] <- n.calc, classes = 'validationWarning' ) } } } # # set variable features # if (!is.null(var.features)) { # suppressWarnings( # expr = VariableFeatures(object = x) <- var.features, # classes = 'validationWarning' # ) # } # subset images for (image in Images(object = x)) { cells.from.image <- cells[cells %in% Cells(x[[image]])] if (length(cells.from.image) == 0) { image.subset <- NULL } else { image.subset <- base::subset(x = x[[image]], cells = cells.from.image) } x[[image]] <- image.subset } return(x) } #' @return \code{tail}: The last \code{n} rows of cell-level metadata #' #' @rdname sub-sub-.Seurat #' #' @method tail Seurat #' @export #' #' @examples #' # Get the last 10 rows of cell-level metadata #' tail(pbmc_small) #' tail.Seurat <- .tail #' @method upgrade seurat #' @export #' upgrade.seurat <- function(object, ...) { # Run update message("Updating from v2.X to v3.X") seurat.version <- packageVersion(pkg = "SeuratObject") new.assay <- UpdateAssay(old.assay = object, assay = "RNA") assay.list <- list(RNA = new.assay) for (i in names(x = object@assay)) { assay.list[[i]] <- UpdateAssay(old.assay = object@assay[[i]], assay = i) } new.dr <- UpdateDimReduction(old.dr = object@dr, assay = "RNA") object <- new( Class = "Seurat", version = seurat.version, assays = assay.list, active.assay = "RNA", project.name = object@project.name, misc = object@misc %||% list(), active.ident = object@ident, reductions = new.dr, meta.data = object@meta.data, tools = list() ) # Run CalcN for (assay in Assays(object = object)) { n.calc <- CalcN(object = object[[assay]]) if (!is.null(x = n.calc)) { names(x = n.calc) <- paste(names(x = n.calc), assay, sep = '_') object[[names(x = n.calc)]] <- n.calc } for (i in c('nGene', 'nUMI')) { if (i %in% colnames(x = object[[]])) { object[[i]] <- NULL } } } } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Original double-bracket assign #' #' This function has been replaced with value-specific double-bracket #' assign methods and should generally not be called #' #' @param x A \code{\link{Seurat}} object #' @param i The name to store a subobject or various cell-level meta data as #' @param value New subobject or cell-level meta data #' #' @return \code{x} with \code{value} stored as \code{i} #' #' @name old-assign #' @rdname old-assign #' #' @keywords internal #' #' @seealso See \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and #' \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta #' data with \code{[[<-} #' NULL #' @rdname old-assign #' setMethod( # because R doesn't allow S3-style [[<- for S4 classes f = '[[<-', signature = c('x' = 'Seurat', i = 'character', value = 'ANY'), definition = function(x, i, ..., value) { x <- UpdateSlots(object = x) # Require names, no index setting if (!is.character(x = i)) { stop("'i' must be a character", call. = FALSE) } # Allow removing of other object if (is.null(x = value)) { slot.use <- if (i %in% colnames(x = x[[]])) { 'meta.data' } else { FindObject(object = x, name = i) } if (is.null(x = slot.use)) { stop("Cannot find object ", i, call. = FALSE) } if (i == DefaultAssay(object = x)) { stop("Cannot delete the default assay", call. = FALSE) } } # remove disallowed characters from object name newi <- if (is.null(x = value)) { i } else { make.names(names = i) } if (any(i != newi)) { warning( "Invalid name supplied, making object name syntactically valid. New object name is ", newi, "; see ?make.names for more details on syntax validity", call. = FALSE, immediate. = TRUE ) i <- newi } # Figure out where to store data slot.use <- if (inherits(x = value, what = 'Assay')) { # Ensure we have the same number of cells if (ncol(x = value) != ncol(x = x)) { stop( "Cannot add a different number of cells than already present", call. = FALSE ) } # Ensure cell order stays the same if (all(Cells(x = value) %in% Cells(x = x)) && !all(Cells(x = value) == Cells(x = x))) { for (slot in c('counts', 'data', 'scale.data')) { assay.data <- GetAssayData(object = value, layer = slot) if (!IsMatrixEmpty(x = assay.data)) { assay.data <- assay.data[, Cells(x = x), drop = FALSE] } # Use slot because SetAssayData is being weird slot(object = value, name = slot) <- assay.data } } 'assays' } else if (inherits(x = value, what = 'SpatialImage')) { # Ensure that all cells for this image are present if (!all(Cells(x = value) %in% Cells(x = x))) { stop("All cells in the image must be present in assay.", call. = FALSE) } # Ensure Assay that SpatialImage is associated with is present in Seurat object if (!DefaultAssay(object = value) %in% Assays(object = x)) { warning( "Adding image data that isn't associated with any assay present", call. = FALSE, immediate. = TRUE ) } 'images' } else if (inherits(x = value, what = 'Graph')) { # Ensure Assay that Graph is associated with is present in the Seurat object if (is.null(x = DefaultAssay(object = value))) { warning( "Adding a Graph without an assay associated with it", call. = FALSE, immediate. = TRUE ) } else if (!any(DefaultAssay(object = value) %in% Assays(object = x))) { stop("Cannot find assay '", DefaultAssay(object = value), "' in this Seurat object", call. = FALSE) } # Ensure Graph object is in order if (all(Cells(x = value) %in% Cells(x = x)) && !all(Cells(x = value) == Cells(x = x))) { value <- value[Cells(x = x), Cells(x = x)] } 'graphs' } else if (inherits(x = value, what = 'DimReduc')) { # All DimReducs must be associated with an Assay if (is.null(x = DefaultAssay(object = value))) { stop("Cannot add a DimReduc without an assay associated with it", call. = FALSE) } # Ensure Assay that DimReduc is associated with is present in the Seurat object if (!IsGlobal(object = value) && !any(DefaultAssay(object = value) %in% Assays(object = x))) { stop("Cannot find assay '", DefaultAssay(object = value), "' in this Seurat object", call. = FALSE) } # Ensure DimReduc object is in order if (all(Cells(x = value) %in% Cells(x = x)) && !all(Cells(x = value) == Cells(x = x))) { slot(object = value, name = 'cell.embeddings') <- value[[Cells(x = x), ]] } 'reductions' } else if (inherits(x = value, what = "Neighbor")) { # Ensure all cells are present in the Seurat object if (length(x = Cells(x = value)) > length(x = Cells(x = x))) { stop( "Cannot have more cells in the Neighbor object than are present in the Seurat object.", call. = FALSE ) } if (!all(Cells(x = value) %in% Cells(x = x))) { stop( "Cannot add cells in the Neighbor object that aren't present in the Seurat object.", call. = FALSE ) } 'neighbors' } else if (inherits(x = value, what = 'SeuratCommand')) { # Ensure Assay that SeuratCommand is associated with is present in the Seurat object if (is.null(x = DefaultAssay(object = value))) { warning( "Adding a command log without an assay associated with it", call. = FALSE, immediate. = TRUE ) } else if (!any(DefaultAssay(object = value) %in% Assays(object = x))) { stop("Cannot find assay '", DefaultAssay(object = value), "' in this Seurat object", call. = FALSE) } 'commands' } else if (is.null(x = value)) { slot.use } else { 'meta.data' } if (slot.use == 'meta.data') { # Add data to object metadata meta.data <- x[[]] cell.names <- rownames(x = meta.data) # If we have metadata with names, ensure they match our order if (is.data.frame(x = value) && !is.null(x = rownames(x = value))) { meta.order <- match(x = rownames(x = meta.data), table = rownames(x = value)) value <- value[meta.order, , drop = FALSE] } if (length(x = i) > 1) { # Add multiple pieces of metadata value <- rep_len(x = value, length.out = length(x = i)) for (index in 1:length(x = i)) { meta.data[i[index]] <- value[index] } } else { # Add a single column to metadata if (length(x = intersect(x = names(x = value), y = cell.names)) > 0) { meta.data[, i] <- value[cell.names] } else if (length(x = value) %in% c(nrow(x = meta.data), 1) || is.null(x = value)) { meta.data[, i] <- value } else { stop("Cannot add more or fewer cell meta.data information without values being named with cell names", call. = FALSE) } } # Check to ensure that we aren't adding duplicate names if (any(colnames(x = meta.data) %in% FilterObjects(object = x))) { bad.cols <- colnames(x = meta.data)[which(colnames(x = meta.data) %in% FilterObjects(object = x))] stop( paste0( "Cannot add a metadata column with the same name as an Assay or DimReduc - ", paste(bad.cols, collapse = ", ")), call. = FALSE ) } # Store the revised metadata slot(object = x, name = 'meta.data') <- meta.data } else { # Add other object to Seurat object # Ensure cells match in value and order if (!inherits(x = value, what = c('SeuratCommand', 'NULL', 'SpatialImage', 'Neighbor')) && !all(Cells(x = value) == colnames(x = x))) { stop("All cells in the object being added must match the cells in this object", call. = FALSE) } # Ensure we're not duplicating object names duplicate <- !is.null(x = FindObject(object = x, name = i)) && !inherits(x = value, what = c(class(x = x[[i]]), 'NULL')) && !inherits(x = x[[i]], what = class(x = value)) if (isTRUE(x = duplicate)) { stop( "This object already contains ", i, " as a", ifelse( test = tolower(x = substring(text = class(x = x[[i]]), first = 1, last = 1)) %in% c('a', 'e', 'i', 'o', 'u'), yes = 'n ', no = ' ' ), class(x = x[[i]]), ", so ", i, " cannot be used for a ", class(x = value), call. = FALSE ) } # Check keyed objects if (inherits(x = value, what = c('Assay', 'DimReduc', 'SpatialImage'))) { if (length(x = Key(object = value)) == 0 || nchar(x = Key(object = value)) == 0) { Key(object = value) <- paste0(tolower(x = i), '_') } Key(object = value) <- UpdateKey(key = Key(object = value)) # Check for duplicate keys object.keys <- Key(object = x) vkey <- Key(object = value) if (vkey %in% object.keys && !isTRUE(x = object.keys[i] == vkey)) { new.key <- if (is.na(x = object.keys[i])) { # Attempt to create a duplicate key based off the name of the object being added new.keys <- paste0( paste0(tolower(x = i), c('', RandomName(length = 2L))), '_' ) # Select new key to use key.use <- min(which(x = !new.keys %in% object.keys)) new.key <- if (is.infinite(x = key.use)) { RandomName(length = 17L) } else { new.keys[key.use] } warning( "Cannot add objects with duplicate keys (offending key: ", Key(object = value), "), setting key to '", new.key, "'", call. = FALSE ) new.key } else { # Use existing key warning( "Cannot add objects with duplicate keys (offending key: ", Key(object = value), ") setting key to original value '", object.keys[i], "'", call. = FALSE ) object.keys[i] } # Set new key Key(object = value) <- new.key } } # For Assays, run CalcN if (inherits(x = value, what = 'Assay')) { if ((!i %in% Assays(object = x)) | (i %in% Assays(object = x) && !identical( x = GetAssayData(object = x, assay = i, layer = "counts"), y = GetAssayData(object = value, layer = "counts")) )) { n.calc <- CalcN(object = value) if (!is.null(x = n.calc)) { names(x = n.calc) <- paste(names(x = n.calc), i, sep = '_') x[[names(x = n.calc)]] <- n.calc } } } # When removing an Assay, clear out associated DimReducs, Graphs, and SeuratCommands if (is.null(x = value) && inherits(x = x[[i]], what = 'Assay')) { objs.assay <- FilterObjects( object = x, classes.keep = c('DimReduc', 'SeuratCommand', 'Graph') ) objs.assay <- Filter( f = function(o) { return(all(DefaultAssay(object = x[[o]]) == i) && !IsGlobal(object = x[[o]])) }, x = objs.assay ) for (o in objs.assay) { x[[o]] <- NULL } } # If adding a command, ensure it gets put at the end of the command list if (inherits(x = value, what = 'SeuratCommand')) { slot(object = x, name = slot.use)[[i]] <- NULL slot(object = x, name = slot.use) <- Filter( f = Negate(f = is.null), x = slot(object = x, name = slot.use) ) } slot(object = x, name = slot.use)[[i]] <- value slot(object = x, name = slot.use) <- Filter( f = Negate(f = is.null), x = slot(object = x, name = slot.use) ) } CheckGC() return(x) } ) #' Add Subobjects #' #' Add subobjects containing expression, dimensional reduction, or other #' containerized data to a \code{\link{Seurat}} object. Subobjects can be #' accessed with \code{\link[=[[.Seurat]{[[}} and manipulated directly within #' the \code{Seurat} object or used independently #' #' @inheritParams .DollarNames.Seurat #' @inheritParams [[.Assay5 #' @param i Name to add subobject as #' @param value A valid subobject (eg. a \link[=Assay]{v3} or \link[=Assay5]{v5} #' assay, or a \link[=DimReduc]{dimensional reduction}) #' #' @return \code{x} with \code{value} added as \code{i} #' #' @name [[<-,Seurat #' @rdname sub-subset-Seurat #' #' @family seurat #' #' @seealso See \link[=[[.Seurat]{here} for pulling subobjects using \code{[[}, #' \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and #' \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta #' data with \code{[[<-} #' #' @aliases [[<-.Seurat \S4method{[[<-}{Seurat,character,missing,Assay} #' NULL #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'Assay' ), definition = function(x, i, ..., value) { if (.GetSeuratCompat() < '5.0.0') { return(callNextMethod(x = x, i = i, value = value)) } validObject(object = value) i <- make.names(names = i) # Checks for if the assay or name already exists if (i %in% names(x = x)) { if (!inherits(x = x[[i]], what = c('Assay', 'StdAssay'))) { abort( message = paste( sQuote(i), "already exists as an object of class", class(x = x[[i]])[1L] ), class = 'duplicateError' ) } if (!identical(x = class(x = value), y = class(x = x[[i]]))) { warning( "Assay ", i, " changing from ", class(x = x[[i]]), " to ", class(x = value), call. = FALSE, immediate. = TRUE ) } if (!all(dim(x = value) == dim(x = x[[i]]))) { warn( message = paste0("Different cells and/or features from existing assay ", i), class = 'dimWarning' ) } } # Check for cells if (!all(colnames(x = value) %in% colnames(x = x))) { abort(message = "Cannot add new cells with [[<-") } cell.order <- MatchCells( new = colnames(x = value), orig = colnames(x = x), ordered = TRUE ) # TODO: enable reordering cells in assay if (is.unsorted(x = cell.order)) { if (inherits(x = value, what = 'Assay')) { for (s in c('counts', 'data', 'scale.data')) { if (!IsMatrixEmpty(x = slot(object = value, name = s))) { slot(object = value, name = s) <- slot(object = value, name = s)[, cell.order] } } } else { abort(message = "Cannot add assays with unordered cells") } validObject(object = value) } # Check keys Key(object = value) <- .CheckKey( key = Key(object = value), existing = Key(object = x), name = i ) # Run CalcN do.calcn <- Misc(object = value, slot = 'calcN') %||% FALSE suppressWarnings(Misc(object = value, slot = 'calcN') <- NULL) if (isTRUE(x = do.calcn)) { n.calc <- suppressWarnings( expr = .CalcN(object = value, layer = 'counts', simplify = TRUE), classes = 'missingLayerWarning' ) if (!is.null(x = n.calc)) { names(x = n.calc) <- paste(names(x = n.calc), i, sep = '_') x[[]] <- n.calc } } # Add the assay slot(object = x, name = 'assays')[[i]] <- value slot(object = x, name = 'assays') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'assays') ) # Validate and return validObject(object = x) return(x) } ) #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'Assay5' ), definition = function(x, i, ..., value) { return(callNextMethod(x = x, i = i, ..., value = value)) } ) #' @rdname cash-.Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'data.frame' ), definition = function(x, i, ..., value) { # Because R is stupid sometimes if (!length(x = i) && !ncol(x = value)) { return(x) } # Check the names provided if (length(x = i) == ncol(x = value)) { # Add the names to the meta data if (is.null(x = names(x = value))) { names(x = value) <- i } if (ncol(x = value) == 1) { v <- value[,1] names(x = v) <- rownames(x = value) x[[i]] <- v return(x) } idx <- match(x = i, table = names(x = value)) # If there are any mismatches in `i` and `names(value)` # rename `value` to match `i` # if (all(is.na(x = idx))) { # warn(message = paste( # "None of the column names are found in meta data names;", # "replacing to provided meta data names" # )) # } if (any(is.na(x = idx))) { meta.missing <- setdiff( x = seq_len(length.out = ncol(x = value)), y = idx[!is.na(x = idx)] ) names(x = meta.missing) <- i[is.na(x = idx)] # for (j in seq_along(along.with = meta.missing)) { # warn(message = paste( # "Column", # sQuote(x = names(x = value)[meta.missing[j]]), # "not found in meta data names, changing to", # sQuote(x = names(x = meta.missing)[j]) # )) # } names(x = value)[meta.missing] <- names(x = meta.missing) } } else if (is.null(x = names(x = value))) { # Cannot add meta data without names abort(message = paste( "Cannot assign", length(x = i), ifelse(test = length(x = i) == 1L, yes = 'name', no = 'names'), "to", ncol(x = value), ifelse(test = ncol(x = value) == 1L, yes = 'bit', no = 'bits'), "of meta data" )) } else { # Find matching `i` in `names(value)` # Cannot rename as `length(i) != ncol(value)` i.orig <- i i <- intersect(x = i, y = names(x = value)) # If no matching, abort if (!length(x = i)) { abort( message = "None of the meta data requested was found in the data frame" ) } # Alert user to `i` not found in `names(value)` i.missing <- setdiff(x = i.orig, y = i) if (length(x = i.missing)) { warn(message = paste( "The following bits of meta data in the data frame will not be added:", paste(sQuote(x = i.missing), collapse = ', ') )) } } # Handle meta data for different cells names.intersect <- intersect(x = row.names(x = value), y = colnames(x = x)) if (length(x = names.intersect)) { value <- value[names.intersect, , drop = FALSE] if (!nrow(x = value)) { abort(message = "None of the cells provided are in this Seurat object") } } else if (nrow(x = value) == ncol(x = x)) { # When no cell names are provided in value, assume it's in cell order row.names(x = value) <- colnames(x = x) } else { # Throw an error when no cell names provided and cannot assume cell order abort( message = "Cannot add more or less meta data without cell names" ) } # Add the cell-level meta data using the `value = vector` method for (n in i) { v <- value[[n]] names(x = v) <- row.names(x = value) x[[n]] <- v } return(x) } ) #' @rdname cash-.Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'missing', j = 'missing', value = 'data.frame' ), definition = function(x, i, ..., value) { # Allow removing all meta data if (IsMatrixEmpty(x = value)) { x[[names(x = x[[]])]] <- NULL } else { # If no `i` provided, use the column names from value x[[names(x = value)]] <- value } return(x) } ) #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'DimReduc' ), definition = function(x, i, ..., value) { validObject(object = value) i <- make.names(names = i) # Checks for if the DimReduc or name already exists if (i %in% .Subobjects(object = x)) { if (!inherits(x = x[[i]], what = 'DimReduc')) { abort( message = paste( sQuote(i), "already exists as an object of class", class(x = x[[i]])[1L] ), class = 'duplicateError' ) } if (!identical(x = class(x = value), y = class(x = x[[i]]))) { warning( "DimReduc ", i, " changing from ", class(x = x[[i]]), " to ", class(x = value), call. = FALSE, immediate. = TRUE ) } if (length(x = value) != length(x = x[[i]])) { warning( "Number of dimensions changing from ", length(x = x[[i]]), " to ", length(x = value), call. = FALSE, immediate. = TRUE ) } if (length(x = Cells(x = value)) != length(x = Cells(x = x[[i]]))) { warning( "Number of cells changing from ", length(x = Cells(x = x[[i]])), " to ", length(x = Cells(x = value)), call. = FALSE, immediate. = TRUE ) } } # Check default assay if (is.null(x = DefaultAssay(object = value))) { stop("Cannot add a DimReduc without an associated assay", call. = FALSE) } else if (!any(DefaultAssay(object = value) %in% Assays(object = x))) { warning( "Adding a dimensional reduction (", i, ") without the associated assay being present", call. = FALSE, immediate. = TRUE ) } # Check for cells if (!all(Cells(x = value) %in% colnames(x = x))) { stop("Cannot add new cells with [[<-", call. = FALSE) } cell.order <- MatchCells( new = Cells(x = value), orig = colnames(x = x), ordered = TRUE ) # TODO: enable reordering cells in DimReducs if (is.unsorted(x = cell.order)) { ordered.cells <- intersect(colnames(x = x), Cells(x = value)) slot(object = value, name = 'cell.embeddings') <- Embeddings(object = value)[ordered.cells,] } # Check keys Key(object = value) <- .CheckKey( key = Key(object = value), existing = Key(object = x), name = i ) # Check loadings and embeddings column name emb.names <- paste0(sapply( X = strsplit( x = colnames(Embeddings(object = value)), split = '_'), FUN = '[', 1)[1], '_') if (emb.names != Key(object = value)){ colnames( slot(object = value, name = 'cell.embeddings') ) <- gsub(pattern = emb.names, replacement = Key(object = value), colnames(Embeddings(object = value)) ) } if (!is.null(colnames(Loadings(object = value)))) { loadings.names <- paste0(sapply( X = strsplit( x = colnames(Loadings(object = value)), split = '_'), FUN = '[', 1)[1], '_') if (loadings.names != Key(object = value)) { colnames( slot(object = value, name = 'feature.loadings') ) <- gsub(pattern = loadings.names, replacement = Key(object = value), colnames(Loadings(object = value)) ) } } slot(object = x, name = 'reductions')[[i]] <- value slot(object = x, name = 'reductions') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'reductions') ) # check column names # Validate and return validObject(object = x) return(x) } ) #' @rdname cash-.Seurat #' #' @importFrom methods selectMethod #' setMethod( f = '[[<-', signature = c(x = 'Seurat', i = 'character', j = 'missing', value = 'factor'), definition = function(x, i, ..., value) { # Add multiple objects if (length(x = i) > 1L) { value <- rep_len(x = value, length.out = length(x = i)) for (idx in seq_along(along.with = i)) { x[[i[idx]]] <- value[[idx]] } return(x) } objs <- .FilterObjects( object = x, classes.keep = c( 'Assay', 'StdAssay', 'DimReduc', 'Graph', 'Neighbor', 'SeuratCommand', 'SpatialImage' ) ) if (i %in% objs) { cls <- class(x = x[[i]])[1L] abort(message = paste( sQuote(x = i, q = FALSE), "already exists as", ifelse( test = tolower(x = substr(x = cls, start = 1, stop = 1)) %in% .Vowels(), yes = 'an', no = 'a' ), class(x = x[[i]])[1L] )) } # fast way to add column if (length(x = value) == ncol(x = x) && all(names(x = value) == colnames(x = x))) { slot(object = x, name = 'meta.data')[,i] <- value return(x) } # Add a column of cell-level meta data if (is.null(x = names(x = value))) { # Handle cases where new meta data is unnamed value <- rep_len(x = value, length.out = ncol(x = x)) names(x = value) <- colnames(x = x) } else { # Check cell names for new objects names.intersect <- intersect(x = names(x = value), y = colnames(x = x)) if (!length(x = names.intersect)) { stop( "No cell overlap between new meta data and Seurat object", call. = FALSE ) } value <- value[names.intersect] } df <- EmptyDF(n = ncol(x = x)) row.names(x = df) <- colnames(x = x) df[[i]] <- factor(x = NA, levels = levels(x = value)) # df[[i]] <- if (i %in% names(x = x[[]])) { # x[[i, na.rm = FALSE]] # } else { # factor(x = NA, levels = levels(x = value)) # } df[names(x = value), i] <- value slot(object = x, name = 'meta.data')[, i] <- df[[i]] validObject(object = x) return(x) } ) #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c(x = 'Seurat', i = 'character', j = 'missing', value = 'Graph'), definition = function(x, i, ..., value) { validObject(object = value) i <- make.names(names = i) # Checks for if the Graph or name already exists if (i %in% names(x = x)) { if (!inherits(x = x[[i]], what = 'Graph')) { abort( message = paste( sQuote(i), "already exists as an object of class", class(x = x[[i]])[1L] ), class = 'duplicateError' ) } if (!identical(x = class(x = value), y = class(x = x[[i]]))) { warning( "Graph ", i, " changing from ", class(x = x[[i]]), " to ", class(x = value), call. = FALSE, immediate. = TRUE ) } if (!all(dim(x = value) == dim(x = x[[i]]))) { warning( "Different cells from existing graph ", i, call. = FALSE, immediate. = TRUE ) } } # Check cells gcells <- Cells(x = value, margin = NA_integer_) if (!all(gcells %in% colnames(x = x))) { stop("Cannot add cells with [[<-", call. = FALSE) } cell.order <- MatchCells( new = gcells, orig = colnames(x = x), ordered = TRUE ) # TODO: enable reordering cells in graph if (is.unsorted(x = cell.order)) { stop("Cannot add graphs with unordered cells", call. = FALSE) validObject(object = value) } # Add the graph slot(object = x, name = 'graphs')[[i]] <- value slot(object = x, name = 'graphs') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'graphs') ) # Validate and return validObject(object = x) return(x) } ) #' @rdname cash-.Seurat #' setMethod( f = '[[<-', signature = c(x = 'Seurat', i = 'character', j = 'missing', value = 'list'), definition = function(x, i, ..., value) { # Because R is stupid sometimes if (!length(x = i) && !length(x = value)) { return(x) } # Check that the `i` we're adding are present in the list if (!is.null(x = names(x = value))) { i <- arg_match(arg = i, values = names(x = value), multiple = TRUE) } else if (length(x = i) != length(x = value)) { abort(message = paste( "Cannot assing", length(x = i), "names to", length(x = value), "bits of meta data" )) } else { names(x = value) <- i } # Add the meta data for (n in i) { x[[n]] <- value[[n]] } return(x) } ) #' @rdname cash-.Seurat #' setMethod( f = '[[<-', signature = c(x = 'Seurat', i = 'missing', j = 'missing', value = 'list'), definition = function(x, i, ..., value) { stopifnot(IsNamedList(x = value)) for (y in names(x = value)) { x[[y]] <- value[[y]] } return(x) } ) #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'Neighbor' ), definition = function(x, i, ..., value) { validObject(object = value) i <- make.names(names = i) # Checks for if the Neighbor or name already exists if (i %in% .Subobjects(object = x)) { if (!inherits(x = x[[i]], what = 'Neighbor')) { abort( message = paste( sQuote(i), "already exists as an object of class", class(x = x[[i]])[1L] ), class = 'duplicateError' ) } if (!identical(x = class(x = value), y = class(x = x[[i]]))) { warn(message = paste( "Graph", i, "changing from", class(x = x[[i]])[1L], "to", class(x = value)[1L] )) } if (length(x = Cells(x = value)) != length(x = Cells(x = x[[i]]))) { warn(message = paste( "Number of cells changing from", length(x = Cells(x = x[[i]])), "to", length(x = Cells(x = value)) )) } } # Check for cells if (!all(Cells(x = value) %in% colnames(x = x))) { abort(message = "Cannot add new cells with [[<-") } cell.order <- MatchCells( new = Cells(x = value), orig = colnames(x = x), ordered = TRUE ) # TODO: enable reordering cells in Neighbors if (is.unsorted(x = cell.order)) { abort(message = "Cannot add Neighbors with unordered cells") validObject(object = value) } slot(object = x, name = 'neighbors')[[i]] <- value slot(object = x, name = 'neighbors') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'neighbors') ) # Validate and return validObject(object = x) return(x) } ) #' Remove Subobjects and Cell-Level Meta Data #' #' @inheritParams [[<-,Seurat #' @param i Name(s) of subobject(s) or cell-level meta data to remove #' @param value NULL #' #' @return \code{x} with \code{i} removed from the object #' #' @name [[<-,Seurat,NULL #' @rdname sub-subset-Seurat-NULL #' #' @family seurat #' #' @seealso See \link[=[[.Seurat]{here} for pulling subobjects using \code{[[}, #' \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and #' \link[=[[<-,Seurat]{here} for adding subobjects with \code{[[<-} #' #' @aliases remove-object remove-objects \S4method{[[<-}{Seurat,character,missing,NULL} #' NULL #' @rdname sub-subset-Seurat-NULL #' setMethod( f = '[[<-', signature = c(x = 'Seurat', i = 'character', j = 'missing', value = 'NULL'), definition = function(x, i, ..., value) { # Allow removing multiple objects or bits of cell-level meta data at once for (name in i) { # Determine the slot to use # If no subobject found, check cell-level meta data slot.use <- .FindObject(object = x, name = name) %||% 'meta.data' switch( EXPR = slot.use, 'meta.data' = { # If we can't find the cell-level meta data, throw a warning and move # to the next name if (!name %in% names(x = x[[]])) { warn(message = paste( "Cannot find cell-level meta data named ", name )) next } # Remove the column of meta data slot(object = x, name = 'meta.data')[, name] <- value }, 'assays' = { # Cannot remove the default assay if (isTRUE(x = name == DefaultAssay(object = x))) { stop("Cannot delete default assay", call. = FALSE) } # Remove the assay slot(object = x, name = slot.use)[[i]] <- value }, # Remove other subobjects slot(object = x, name = slot.use)[[name]] <- value ) } # Validate and return validObject(object = x) return(x) } ) #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'SeuratCommand' ), definition = function(x, i, ..., value) { validObject(object = value) i <- make.names(names = i) # Checks for if the SeuratCommand or name already exists if (i %in% .Subobjects(object = x)) { if (!inherits(x = x[[i]], what = 'SeuratCommand')) { abort( message = paste( sQuote(i), "already exists as an object of class", class(x = x[[i]])[1L] ), class = 'duplicateError' ) } if (!identical(x = class(x = value), y = class(x = x[[i]]))) { warn(message = paste( "Command", i, "changing from", class(x = x[[i]])[1L], "to", class(x = value)[1L] )) } } if (is.null(x = DefaultAssay(object = value))) { warn(message = "Adding a command log without an assay associated with it") } # Ensure the command gets put at the end of the list # slot(object = x, name = 'commands')[[i]] <- NULL suppressWarnings(expr = x[[i]] <- NULL) slot(object = x, name = 'commands')[[i]] <- value slot(object = x, name = 'commands') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'commands') ) # Validate and return validObject(object = x) return(x) } ) #' @rdname sub-subset-Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'SpatialImage' ), definition = function(x, i, ..., value) { validObject(object = value) i <- make.names(names = i) # Checks for if the image or name already exists if (i %in% .Subobjects(object = x)) { if (!inherits(x = x[[i]], what = 'SpatialImage')) { abort( message = paste( sQuote(i), "already exists as an object of class", class(x = x[[i]])[1L] ), class = 'duplicateError' ) } if (!identical(x = class(x = value), y = class(x = x[[i]]))) { warn(message = paste( "Image", i, "changing from", class(x = x[[i]])[1L], "to", class(x = value)[1L] )) } } # Check cells if (!all(Cells(x = value) %in% colnames(x = x))) { abort(message = "Cannot add new cells with [[<-") } cell.order <- MatchCells( new = Cells(x = value), orig = colnames(x = x), ordered = TRUE ) if (is.unsorted(x = cell.order)) { warn(message = "Adding image with unordered cells") } # Check assay if (!DefaultAssay(object = value) %in% Assays(object = x)) { warn(message = "Adding image data that isn't associated with any assays") } # Check keys Key(object = value) <- .CheckKey( key = Key(object = value), existing = Key(object = x), name = i ) slot(object = x, name = 'images')[[i]] <- value slot(object = x, name = 'images') <- Filter( f = Negate(f = is.null), x = slot(object = x, name = 'images') ) # Validate and return validObject(object = x) return(x) } ) #' @inherit [[<-,Seurat #' #' @keywords internal #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'StdAssay' ), definition = function(x, i, ..., value) { # Reuse the `value = Assay` method fn <- slot( object = selectMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'Assay' ) ), name = '.Data' ) cell.order <- MatchCells( new = colnames(x = value), orig = colnames(x = x), ordered = TRUE ) if (is.unsorted(cell.order)) { value.order <- new( Class = 'Assay5', layers = list(), default = 0L, features = value@features, cells = LogMap(colnames(value)[cell.order]), meta.data = value@meta.data, misc = value@misc ) for (l in Layers(object = value)) { LayerData(object = value.order, layer = l) <- LayerData(object = value, layer = l) } value <- value.order } return(fn(x = x, i = i, value = value)) } ) #' @rdname cash-.Seurat #' setMethod( f = '[[<-', signature = c( x = 'Seurat', i = 'character', j = 'missing', value = 'vector' ), definition = function(x, i, ..., value) { # Add multiple objects if (length(x = i) > 1L) { value <- rep_len(x = value, length.out = length(x = i)) for (idx in seq_along(along.with = i)) { x[[i[idx]]] <- value[[idx]] } return(x) } objs <- .FilterObjects( object = x, classes.keep = c( 'Assay', 'StdAssay', 'DimReduc', 'Graph', 'Neighbor', 'SeuratCommand', 'SpatialImage' ) ) if (i %in% objs) { cls <- class(x = x[[i]])[1L] abort(message = paste( sQuote(x = i, q = FALSE), "already exists as", ifelse( test = tolower(x = substr(x = cls, start = 1, stop = 1)) %in% .Vowels(), yes = 'an', no = 'a' ), class(x = x[[i]])[1L] )) } # fast way to add column if (length(x = value) == ncol(x = x) && all(names(x = value) == colnames(x = x))) { slot(object = x, name = 'meta.data')[,i] <- value return(x) } # Add a column of cell-level meta data if (is.null(x = names(x = value))) { # Handle cases where new meta data is unnamed value <- rep_len(x = value, length.out = ncol(x = x)) names(x = value) <- colnames(x = x) } else { # Check cell names for new objects names.intersect <- intersect(x = names(x = value), y = colnames(x = x)) if (!length(x = names.intersect)) { stop( "No cell overlap between new meta data and Seurat object", call. = FALSE ) } value <- value[names.intersect] } df <- EmptyDF(n = ncol(x = x)) row.names(x = df) <- colnames(x = x) df[[i]] <- if (i %in% names(x = x[[]])) { if (is.character(x = value)) { as.character(x = x[[i, drop = TRUE, na.rm = FALSE]]) } else { as.vector(x = x[[i, drop = TRUE, na.rm = FALSE]]) } } else { NA } df[names(x = value), i] <- value slot(object = x, name = 'meta.data')[, i] <- df[[i]] validObject(object = x) return(x) } ) #' Row and Column Sums and Means #' #' Calculate \code{\link{rowSums}}, \code{\link{colSums}}, #' \code{\link{rowMeans}}, and \code{\link{colMeans}} on #' \code{\link{Seurat}} objects #' #' @inheritParams .DollarNames.Seurat #' @inheritParams Matrix::colMeans #' @param slot Name of assay expression matrix to calculate column/row #' means/sums on #' #' @return \code{colMeans}: the column (cell-wise) means of \code{slot} #' #' @importFrom Matrix colMeans #' #' @keywords internal #' #' @export #' #' @concept seurat #' #' @seealso \code{\link{Seurat}} #' #' @examples #' head(colMeans(pbmc_small)) #' setMethod( f = 'colMeans', signature = c('x' = 'Seurat'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(colMeans( x = LayerData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' @return \code{colSums}: the column (cell-wise) sums of \code{slot} #' #' @rdname colMeans-Seurat-method #' #' @importFrom Matrix colSums #' #' @export #' #' @examples #' head(colSums(pbmc_small)) #' setMethod( f = 'colSums', signature = c('x' = 'Seurat'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::colSums( x = LayerData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' @importFrom methods initialize #' setMethod( f = 'initialize', signature = 'Seurat', definition = function( .Object, assays = list(), meta.data = NULL, active.assay = character(length = 0L), active.ident = NULL, graphs = list(), neighbors = list(), reductions = list(), images = list(), project.name = getOption( x = 'Seurat.object.project', default = Seurat.options$Seurat.object.project ), misc = list(), version = packageVersion(pkg = 'SeuratObject'), commands = list(), tools = list(), ... ) { # Initialize the object .Object <- callNextMethod(.Object, ...) # Set defaults for meta data and idents cells <- Reduce(f = union, x = lapply(X = assays, FUN = Cells)) if (is.null(x = meta.data)) { meta.data <- EmptyDF(n = length(x = cells)) row.names(x = meta.data) <- cells } if (is.null(x = active.ident)) { active.ident <- factor(x = cells) } # Add slots slot(object = .Object, name = 'assays') <- assays slot(object = .Object, name = 'meta.data') <- meta.data slot(object = .Object, name = 'active.assay') <- active.assay slot(object = .Object, name = 'active.ident') <- active.ident slot(object = .Object, name = 'graphs') <- graphs slot(object = .Object, name = 'neighbors') <- neighbors slot(object = .Object, name = 'reductions') <- reductions slot(object = .Object, name = 'images') <- images slot(object = .Object, name = 'project.name') <- project.name slot(object = .Object, name = 'misc') <- misc slot(object = .Object, name = 'version') <- version slot(object = .Object, name = 'commands') <- commands slot(object = .Object, name = 'tools') <- tools # Validate the object validObject(object = .Object) # Return return(.Object) } ) #' @return \code{rowMeans}: the row (feature-wise) means of \code{slot} #' #' @rdname colMeans-Seurat-method #' #' @importFrom Matrix colSums #' #' @export #' #' @examples #' head(rowMeans(pbmc_small)) #' setMethod( f = 'rowMeans', signature = c('x' = 'Seurat'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::rowMeans( x = LayerData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' @return \code{rowSums}: the row (feature-wise) sums of \code{slot} #' #' @rdname colMeans-Seurat-method #' #' @importFrom Matrix rowSums #' #' @export #' #' @examples #' head(rowSums(pbmc_small)) #' setMethod( f = 'rowSums', signature = c('x' = 'Seurat'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::rowSums( x = LayerData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' Seurat Object Overview #' #' Overview of a \code{\link{Seurat}} object #' #' @template return-show #' #' @keywords internal #' #' @concept seurat #' #' @examples #' pbmc_small #' setMethod( f = "show", signature = "Seurat", definition = function(object) { #object <- UpdateSlots(object = object) x <- tryCatch( expr = slot(object = object, name = 'images'), error = function(...) {stop("Please run UpdateSeuratObject on your object", call. = FALSE)}) assays <- .FilterObjects(object = object, classes.keep = c('Assay', 'StdAssay')) nfeatures <- sum(vapply( X = assays, FUN = function(x) { return(nrow(x = object[[x]])) }, FUN.VALUE = numeric(length = 1L) )) num.assays <- length(x = assays) cat("An object of class", class(x = object), "\n") cat( nfeatures, 'features across', ncol(x = object), 'samples within', num.assays, ifelse(test = num.assays == 1, yes = 'assay', no = 'assays'), "\n" ) cat( "Active assay:", DefaultAssay(object = object), paste0( '(', nrow(x = object), ' features, ', length(x = suppressWarnings(expr = VariableFeatures(object = object))), ' variable features)' ) ) cat( '\n', length(x = Layers(object = object)), ifelse( test = length(x = Layers(object = object)) == 1L, yes = 'layer', no = 'layers' ), 'present:', strwrap(x = paste(Layers(object = object), collapse = ', ')) ) other.assays <- assays[assays != DefaultAssay(object = object)] if (length(x = other.assays) > 0) { cat( '\n', length(x = other.assays), 'other', ifelse(test = length(x = other.assays) == 1, yes = 'assay', no = 'assays'), 'present:', strwrap(x = paste(other.assays, collapse = ', ')) ) } reductions <- .FilterObjects(object = object, classes.keep = 'DimReduc') if (length(x = reductions) > 0) { cat( '\n', length(x = reductions), 'dimensional', ifelse(test = length(x = reductions) == 1, yes = 'reduction', no = 'reductions'), 'calculated:', strwrap(x = paste(reductions, collapse = ', ')) ) } fovs <- .FilterObjects(object = object, classes.keep = 'FOV') if (length(x = fovs)) { cat( '\n', length(x = fovs), 'spatial', ifelse(test = length(x = fovs) == 1L, yes = 'field', no = 'fields'), 'of view present:', strwrap(x = paste(fovs, sep = ', ')) ) } images <- .FilterObjects(object = object, classes.keep = 'SpatialImage') images <- setdiff(x = images, y = fovs) if (length(x = images)) { cat( '\n', length(x = images), ifelse(test = length(x = images) == 1L, yes = 'image', no = 'images'), 'present:', strwrap(x = paste(images, collapse = ', ')) ) } cat('\n') } ) #' Old Seurat Object Overview #' #' Overview of a \code{\link[=oldseurat]{seurat}} object overview #' #' @param object An old seurat object #' #' @template return-show #' #' @rdname show-oldseurat-method #' #' @keywords internal #' #' @concept oldseurat #' setMethod( f = 'show', signature = 'seurat', definition = function(object) { cat( "An old seurat object\n", nrow(x = object@data), 'genes across', ncol(x = object@data), 'samples\n' ) } ) #' Seurat Object Validity #' #' @templateVar cls Seurat #' @template desc-validity #' #' @name Seurat-validity #' #' @family seurat #' #' @seealso \code{\link[methods]{validObject}} #' setValidity( Class = 'Seurat', method = function(object) { if (.GetSeuratCompat() < '5.0.0') { return(TRUE) } if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # TODO: Check meta data md <- slot(object = object, name = 'meta.data') # if (length(x = class(x = md)) != 1L || class(x = md) != 'data.frame') { if (!.IsDataFrame(x = md)) { valid <- c(valid, "'meta.data' must be a base-R data.frame") } if (ncol(x = md)) { if (is.null(x = names(x = md)) || any(!nzchar(x = names(x = md)))) { valid <- c(valid, "all columns in 'meta.data' must be named") } } # TODO: Check cells ocells <- colnames(x = object) if (anyDuplicated(x = ocells)) { valid <- c(valid, "cell names may not be duplicated") } # TODO: Check assays if (!IsNamedList(x = slot(object = object, name = 'assays'))) { valid <- c(valid, "'assays' must be a named list") } else { for (assay in Assays(object = object)) { if (!inherits(x = object[[assay]], what = c('Assay', 'StdAssay'))) { valid <- c(valid, "'assays' must be a list of 'Assay' objects") break } acells <- colnames(x = object[[assay]]) if (!all(acells %in% ocells)) { valid <- c(valid, "all cells in assays must be present in the Seurat object") } else if (is.unsorted(x = MatchCells(new = acells, orig = ocells, ordered = TRUE))) { valid <- c( valid, "all cells in assays must be in the same order as the Seurat object" ) } if (!isTRUE(x = nzchar(x = Key(object = object[[assay]])))) { valid <- c(valid, "all assays must have a key") } } } # TODO: Check reductions if (!IsNamedList(x = slot(object = object, name = 'reductions'), pass.zero = TRUE)) { valid <- c(valid, "'reductions' must be a named list") } else { for (reduc in Reductions(object = object)) { # Check cells rcells <- Cells(x = object[[reduc]]) if (!all(rcells %in% ocells)) { valid <- c(valid, "All cells in reductions must be present in the Seurat object") } else if (is.unsorted(x = MatchCells(new = rcells, orig = ocells, ordered = TRUE))) { valid <- c(valid, "all cells in reductions must be in the same order as the Seurat object") } # TODO: Check features # TODO: Check default assay } } # Check graphs if (!IsNamedList(x = slot(object = object, name = 'graphs'), pass.zero = TRUE)) { valid <- c(valid, "'graphs' must be a named list") } else { for (graph in Graphs(object = object)) { gnames <- Cells(x = object[[graph]], margin = NA_integer_) # if (!DefaultAssay(object = object[[graph]]) %in% Assays(object = object)) { # valid <- c( # valid, # "the default assay for graphs must be present in the Seurat object" # ) # } if (!all(gnames %in% colnames(x = object))) { valid <- c(valid, "all cells in graphs must be present in the Seurat object") } else if (is.unsorted(x = MatchCells(new = gnames, orig = ocells, ordered = TRUE))) { valid <- c( valid, paste0( "all cells in graphs must be in the same order as the Seurat object (offending: ", graph, ")" ) ) } } } # Check neighbors if (!IsNamedList(x = slot(object = object, name = 'neighbors'), pass.zero = TRUE)) { valid <- c(valid, "'neighbors' must be a named list") } else { for (nn in Neighbors(object = object)) { ncells <- Cells(x = object[[nn]]) if (!all(ncells %in% ocells)) { valid <- c(valid, "All cells in neighbor objects must be present in the Seurat object") } else if (is.unsorted(x = MatchCells(new = ncells, orig = ocells, ordered = TRUE))) { valid <- c(valid, "All cells in neighbor objects must be in the same order as the Seurat object") } } } # Check images if (!IsNamedList(x = slot(object = object, name = 'images'), pass.zero = TRUE)) { valid <- c(valid, "'images' must be a named list") } else { for (img in Images(object = object)) { icells <- Cells(x = object[[img]]) if (!all(icells %in% ocells)) { valid <- c(valid, "All cells in images must be present in the Seurat object") } # else if (is.unsorted(x = MatchCells(new = icells, orig = ocells, ordered = TRUE))) { # valid <- c(valid, "All cells in images must be in the same order as the Seurat object") # } } } # TODO: Check project proj <- Project(object = object) if (length(x = proj) != 1L) { valid <- c(valid, "'project' must be a 1-length character vector") } else if (is.na(x = proj)) { valid <- c(valid, "'project' cannot be NA") } else if (!nzchar(x = proj)) { valid <- c(valid, "'project' cannot be an empty character") } # TODO: Check idents idents <- Idents(object = object) if (length(x = idents) != ncol(x = object)) { valid <- c( valid, "'active.idents' must be as long as the number of cells present" ) } else if (!all(names(x = idents) == colnames(x = object))) { valid <- c(valid, "'active.idents' must be named with cell names") } # TODO: Check version if (length(x = slot(object = object, name = 'version')) > 1) { valid <- c(valid, "Only one version is allowed") } return(valid %||% TRUE) } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .FilterCells <- function(object, validate = TRUE) { objs <- .FilterObjects( object = object, classes.keep = c( 'Assay', # assays 'StdAssay', # assays 'Graph', # graphs 'Neighbor', # neighbors 'DimReduc', # reductions 'SpatialImage' # images ) ) '' } .SubobjectAssign <- function() { classes <- slot( object = methods::findMethods(f = '[[<-', classes = 'Seurat'), name = 'signatures' ) classes <- Filter(f = function(x) x[1] == 'Seurat', x = classes) classes <- vapply( X = classes, FUN = function(x) { return(x[length(x = x)]) }, FUN.VALUE = character(length = 1L) ) classes <- unique(x = classes) classes <- setdiff( x = classes, y = c('Seurat', 'ANY', 'NULL', 'vector', 'list', 'StdAssay') ) classes <- Filter( f = function(x) { cdef <- methods::getClass(Class = x) return(!'oldClass' %in% names(x = slot(object = cdef, name = 'contains'))) }, x = classes ) } #' Object Collections #' #' Find the names of collections in an object #' #' @param object An S4 object #' #' @return A vector with the names of slots that are a list #' #' @keywords internal #' #' @noRd #' #' @examples #' \donttest{ #' SeuratObject:::Collections(pbmc_small) #' } #' Collections <- function(object) { if (!isS4(object)) { return(NULL) } collections <- vapply( X = slotNames(x = object), FUN = function(x) { return(inherits(x = slot(object = object, name = x), what = 'list')) }, FUN.VALUE = logical(length = 1L) ) collections <- Filter(f = isTRUE, x = collections) return(names(x = collections)) } #' Get the default image of an object #' #' Attempts to find all images associated with the default assay of the object. #' If none present, finds all images present in the object. Returns the name of #' the first image #' #' @param object A \code{\link{Seurat}} object #' #' @return The name of the default image #' #' @keywords internal #' #' @noRd #' DefaultImage <- function(object) { object <- UpdateSlots(object = object) images <- Images(object = object, assay = DefaultAssay(object = object)) if (length(x = images) < 1) { images <- Images(object = object) } return(images[[1]]) } #' Find the collection of an object within a Seurat object #' #' @param object A \code{\link{Seurat}} object #' @param name Name of object to find #' #' @return The collection (slot) of the object #' #' @keywords internal #' #' @noRd #' #' @examples #' \donttest{ #' SeuratObject:::FindObject(pbmc_small, name = "RNA") #' } #' FindObject <- function(object, name) { collections <- c( 'assays', 'graphs', 'neighbors', 'reductions', 'commands', 'images' ) object.names <- lapply( X = collections, FUN = function(x) { return(names(x = slot(object = object, name = x))) } ) names(x = object.names) <- collections object.names <- Filter(f = Negate(f = is.null), x = object.names) for (i in names(x = object.names)) { if (name %in% names(x = slot(object = object, name = i))) { return(i) } } return(NULL) } #' Update Seurat v2 Internal Objects #' #' Helper functions to update old Seurat v2 objects to v3/v4 objects #' #' @param old.assay,old.dr,old.jackstraw Seurat v2 assay, dimensional #' reduction, or jackstraw object #' @param assay Name to store for assay in new object #' #' @return A v3/v4 \code{\link{Assay}}, \code{\link{DimReduc}}, or #' \code{\link{JackStrawData}} object #' #' @name V2Update #' @rdname V2Update #' #' @keywords internal #' #' @noRd #' UpdateAssay <- function(old.assay, assay) { if (!is.null(x = old.assay@data)) { cells <- colnames(x = old.assay@data) } else { cells <- colnames(x = old.assay@raw.data) } counts <- old.assay@raw.data data <- old.assay@data if (!inherits(x = counts, what = 'dgCMatrix')) { counts <- as.sparse(x = as.matrix(x = counts)) } if (!is.null(x = data)) { if (!inherits(x = data, what = 'dgCMatrix')) { data <- as.sparse(x = as.matrix(x = data)) } } else { data <- as.sparse( x = Matrix( data = 0, nrow = nrow(x = counts), ncol = ncol(x = counts), dimnames = dimnames(x = counts) ), ) } if (!inherits(x = old.assay@scale.data, what = 'matrix')) { scale.data <- new(Class = 'matrix') } else { scale.data <- old.assay@scale.data } new.assay <- new( Class = 'Assay', counts = counts[, cells], data = data, scale.data = scale.data, meta.features = data.frame(row.names = rownames(x = counts)), var.features = old.assay@var.genes, key = paste0(assay, "_") ) return(new.assay) } #' @param assay.used Name of assay used to compute dimension reduction #' #' @importFrom methods new #' #' @rdname V2Update #' #' @noRd #' UpdateDimReduction <- function(old.dr, assay) { new.dr <- list() for (i in names(x = old.dr)) { cell.embeddings <- old.dr[[i]]@cell.embeddings %||% new(Class = 'matrix') feature.loadings <- old.dr[[i]]@gene.loadings %||% new(Class = 'matrix') stdev <- old.dr[[i]]@sdev %||% numeric() misc <- old.dr[[i]]@misc %||% list() new.jackstraw <- UpdateJackstraw(old.jackstraw = old.dr[[i]]@jackstraw) old.key <- old.dr[[i]]@key if (length(x = old.key) == 0) { old.key <- gsub(pattern = "(.+?)(([0-9]+).*)", replacement = "\\1", x = colnames(cell.embeddings)[[1]]) if (length(x = old.key) == 0) { old.key <- i } } new.key <- suppressWarnings(expr = UpdateKey(key = old.key)) colnames(x = cell.embeddings) <- gsub( pattern = old.key, replacement = new.key, x = colnames(x = cell.embeddings) ) colnames(x = feature.loadings) <- gsub( pattern = old.key, replacement = new.key, x = colnames(x = feature.loadings) ) new.dr[[i]] <- new( Class = 'DimReduc', cell.embeddings = as(object = cell.embeddings, Class = 'matrix'), feature.loadings = as(object = feature.loadings, Class = 'matrix'), assay.used = assay, global = FALSE, stdev = as(object = stdev, Class = 'numeric'), key = as(object = new.key, Class = 'character'), jackstraw = new.jackstraw, misc = as(object = misc, Class = 'list') ) } return(new.dr) } #' @importFrom methods .hasSlot new #' #' @rdname V2Update #' #' @keywords internal #' #' @noRd #' UpdateJackstraw <- function(old.jackstraw) { if (is.null(x = old.jackstraw)) { new.jackstraw <- new( Class = 'JackStrawData', empirical.p.values = new(Class = 'matrix'), fake.reduction.scores = new(Class = 'matrix'), empirical.p.values.full = new(Class = 'matrix'), overall.p.values = new(Class = 'matrix') ) } else { if (.hasSlot(object = old.jackstraw, name = 'overall.p.values')) { overall.p <- old.jackstraw@overall.p.values %||% new(Class = 'matrix') } else { overall.p <- new(Class = 'matrix') } new.jackstraw <- new( Class = 'JackStrawData', empirical.p.values = old.jackstraw@emperical.p.value %||% new(Class = 'matrix'), fake.reduction.scores = old.jackstraw@fake.pc.scores %||% new(Class = 'matrix'), empirical.p.values.full = old.jackstraw@emperical.p.value.full %||% new(Class = 'matrix'), overall.p.values = overall.p ) } return(new.jackstraw) } SeuratObject/R/layers.R0000644000176200001440000002344315075522101014473 0ustar liggesusers#' @include zzz.R #' @importFrom methods as callNextMethod #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setGeneric( name = '.GetLayerData', def = function(x, ...) { standardGeneric(f = '.GetLayerData') }, signature = c('x') ) setGeneric( name = '.PrepLayerData', def = function(x, target, transpose = NULL, ...) { standardGeneric(f = '.PrepLayerData') }, signature = c('x', 'target') ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .CheckDimnames <- function(dnames, dims) { if (is.null(x = dnames)) { return(NULL) } if (!is.numeric(x = dims)) { stop("'dims' must be a numeric vector", call. = FALSE) } else if (!is.list(x = dnames) || length(x = dnames) != length(x = dims)) { stop("'dnames' must be a list of length ", length(x = dims), call. = FALSE) } dims <- dims %/% 1L didx <- match( x = vapply( X = dnames, FUN = length, FUN.VALUE = numeric(length = 1L), USE.NAMES = FALSE ), table = dims ) didx[duplicated(x = didx)] <- NA didx[is.na(x = didx)] <- setdiff( x = seq_along(along.with = dims), y = didx ) return(dnames[didx]) } #' Check Feature Margin #' #' @param fmargin Either \code{1} or \code{2} #' #' @return \code{fmargin} #' #' @keywords internal #' #' @export #' #' @examples #' .CheckFmargin(1L) #' .CheckFmargin(2.3) #' #' # Error if `fmargin` is outside of [1:2] #' if (FALSE) { #' .CheckFmargin(3L) #' } #' .CheckFmargin <- function(fmargin) { fmargin <- fmargin %/% 1L if (!fmargin %in% seq.int(from = 1L, to = 2L)) { abort(message = paste(sQuote(x = fmargin), "must be either 1 or 2")) } return(fmargin) } .Cmargin <- function(fmargin) { fmargin <- .CheckFmargin(fmargin = fmargin) return(setdiff(x = seq.int(from = 1L, to = 2L), y = fmargin)) } #' Get and Prepare Layer Data #' #' Assemble layer data pulled from and prepare layer data for addition to #' v5 assays; v5 assays allow layers to be in multiple formats and support #' both regular and transposed orientations #' #' When transposition is required, \code{.GetLayerData2} and #' \code{.PrepLayerData2} will attempt to #' \link[.GetMethod]{determine the optimal method} of \code{\link[base:t]{t()}} #' to use; if no optimal method is found, \code{base::t.default} will be used #' for transposition, which may be slow #' #' @param x A matrix-like object #' @param dnames An optional list with feature and cell names #' (in order for \code{.GetLayerData2}) #' @param fmargin Margin for features (1 or 2); for \code{.GetLayerData2}, if #' \code{fmargin} is 2, \code{x} will be transposed (see details) #' #' @return \code{.GetLayerData2}: \code{x}, potentially transposed and #' potentially with \code{dnames} set as the \code{\link{dimnames}} #' #' @keywords internal #' #' @noRd #' .GetLayerData2 <- function(x, dnames = NULL, fmargin = 1L) { # Check dimnames if (!is.null(x = dnames)) { ndims <- length(x = dim(x = x)) if (!is_bare_list(x = dnames, n = ndims)) { abort(message = paste("'dnames' must be a list of length", ndims)) } didx <- match( x = sapply(X = dnames, FUN = length, USE.NAMES = FALSE), table = dim(x = x) ) didx[duplicated(x = didx)] <- NA didx[is.na(x = didx)] <- setdiff(x = seq_len(length.out = ndims), y = didx) dnames <- dnames[didx] } # Check fmargin fmargin <- fmargin %/% 1L if (!fmargin %in% c(1L, 2L)) { abort(message = "'fmargin' must be either 1 or 2") } # Do we transpose if (fmargin == 2L) { tf <- .GetMethod(fxn = 't', cls = class(x = x)) x <- tf(x) dnames <- rev(x = dnames) } suppressWarnings(expr = suppressMessages(expr = dimnames(x = x) <- dnames)) return(x) } #' @param target An optional two-length integer vector with dimensions of #' the v5 assay that \code{x} will be added to; used only if #' \code{transpose} is \code{NULL} #' @param transpose Transpose \code{x} before returning it; if \code{NULL} and #' \code{target} is provided, will attempt to determine if transposition is #' necessary (see details) #' #' @return \code{.PrepLayerData2}: \code{x} with \code{\link{dimnames}} removed #' and \code{dnames} added as attributes \dQuote{\code{features}} and #' \dQuote{\code{cells}} and potentially transposed #' #' @rdname dot-GetLayerData2 #' #' @keywords internal #' #' @noRd #' .PrepLayerData2 <- function( x, target = NULL, transpose = FALSE, dnames = NULL, fmargin = 1L ) { if (is.null(x = x)) { return(x) } # Check fmargin fmargin <- fmargin %/% 1L if (!fmargin %in% c(1L, 2L)) { abort(message = "'fmargin' must be either 1 or 2") } cmargin <- c(2L, 1L)[fmargin] # Auto-check transposition if (!is.null(x = target) && is.null(x = transpose)) { if (!is_bare_integerish(x = target, n = 2L, finite = TRUE)) { abort(message = "'target' must be a two-length integer vector") } xdim <- dim(x)[c(fmargin, cmargin)] if (all(rev(xdim) == target)) { transpose <- TRUE } } # Check dimnames if (is.null(x = dnames)) { dnames <- dimnames(x = x) } else if (!is_bare_list(x = dnames, n = 2L)) { abort(message = "'dnames' must be a two-length list") } # Handle transposition if (isTRUE(x = transpose)) { tf <- .GetMethod(fxn = 't', cls = class(x = x)) x <- tf(x) dnames <- rev(x = dnames) } x <- suppressMessages(expr = unname(x)) attr(x = x, which = 'features') <- dnames[[fmargin]] attr(x = x, which = 'cells') <- dnames[[cmargin]] return(x) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setMethod( f = '.GetLayerData', signature = c(x = 'ANY'), definition = function(x, dnames = NULL, fmargin = 1L, ...) { dnames <- .CheckDimnames(dnames = dnames, dims = dim(x = x)) fmargin <- .CheckFmargin(fmargin = fmargin) if (fmargin == 2L) { x <- base::t(x = x) dnames <- rev(x = dnames) } dimnames(x = x) <- dnames return(x) } ) setMethod( f = '.GetLayerData', signature = c(x = 'data.frame'), definition = function(x, dnames = NULL, fmargin = 1L, ...) { x <- callNextMethod() return(as.data.frame(x = x)) } ) #' @importClassesFrom Matrix Matrix #' setMethod( f = '.GetLayerData', signature = c(x = 'Matrix'), definition = function(x, dnames = NULL, fmargin = 1L, ...) { dnames <- .CheckDimnames(dnames = dnames, dims = dim(x = x)) fmargin <- .CheckFmargin(fmargin = fmargin) if (fmargin == 2L) { x <- Matrix::t(x = x) dnames <- rev(x = dnames) } dimnames(x = x) <- dnames return(x) } ) #' @importClassesFrom spam spam #' setMethod( f = '.GetLayerData', signature = c(x = 'spam'), definition = function(x, fmargin = 1L, ...) { fmargin <- .CheckFmargin(fmargin = fmargin) if (fmargin == 2L) { x <- spam::t(x = x) } return(x) } ) setMethod( f = '.PrepLayerData', signature = c(x = 'ANY', target = 'numeric'), definition = function( x, target, transpose = NULL, dnames = NULL, fmargin = 1L, ... ) { # Check the value of target # target should be c(nfeatures, ncells) if (length(x = target) != 2L) { stop("'target' must be a two-length numeric vector", call. = FALSE) } # If transpose is NULL, try to determine if we should transpose if (is.null(x = transpose)) { fmargin <- .CheckFmargin(fmargin = fmargin) cmargin <- .Cmargin(fmargin = fmargin) xdim <- dim(x = x)[c(fmargin, cmargin)] if (all(rev(x = xdim) == target)) { transpose <- TRUE } } return(.PrepLayerData( x = x, target = NULL, transpose = transpose, dnames = dnames, fmargin = fmargin, ... )) } ) setMethod( f = '.PrepLayerData', signature = c(x = 'ANY', target = 'NULL'), definition = function( x, target, transpose = NULL, dnames = NULL, fmargin = 1L, tf = base::t, ... ) { fmargin <- .CheckFmargin(fmargin = fmargin) cmargin <- .Cmargin(fmargin = fmargin) if (isTRUE(x = transpose)) { x <- tf(x) dnames <- rev(x = dnames) } x <- suppressMessages(expr = unname(x)) attr(x = x, which = 'features') <- dnames[[fmargin]] attr(x = x, which = 'cells') <- dnames[[cmargin]] return(x) } ) #' @importClassesFrom Matrix Matrix #' setMethod( f = '.PrepLayerData', signature = c(x = 'Matrix', target = 'NULL'), definition = function(x, target, transpose = NULL, ...) { return(callNextMethod( x = x, target = target, transpose = transpose, tf = Matrix::t, ... )) } ) setMethod( f = '.PrepLayerData', signature = c(x = 'NULL', target = 'ANY'), definition = function(x, target, transpose = NULL, ...) { return(x) } ) #' @importClassesFrom spam spam #' setMethod( f = '.PrepLayerData', signature = c(x = 'spam', target = 'NULL'), definition = function(x, target, transpose = NULL, ...) { return(callNextMethod( x = x, target = target, transpose = transpose, tf = spam::t, ... )) } ) SeuratObject/R/assay.R0000644000176200001440000015050015116320014014302 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @include default.R #' @include graph.R #' @include keymixin.R #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setClassUnion(name = 'AnyMatrix', members = c("matrix", "dgCMatrix")) #' The Assay Class #' #' The Assay object is the basic unit of Seurat; each Assay stores raw, #' normalized, and scaled data as well as cluster information, variable #' features, and any other assay-specific metadata. Assays should contain single #' cell expression data such as RNA-seq, protein, or imputed expression data. #' #' @slot counts Unnormalized data such as raw counts or TPMs #' @slot data Normalized expression data #' @slot scale.data Scaled expression data # @slot key Key for the Assay #' @slot assay.orig Original assay that this assay is based off of. Used to #' track assay provenance #' @slot var.features Vector of features exhibiting high variance across #' single cells #' @slot meta.features Feature-level metadata # @slot misc Utility slot for storing additional data associated with the assay #' @template slot-misc #' @template slot-key #' #' @name Assay-class #' @rdname Assay-class #' @exportClass Assay #' #' @family assay #' #' @aliases Assay #' setClass( Class = 'Assay', contains = 'KeyMixin', slots = c( counts = 'AnyMatrix', data = 'AnyMatrix', scale.data = 'matrix', # key = 'character', assay.orig = 'OptionalCharacter', var.features = 'vector', meta.features = 'data.frame', misc = 'OptionalList' ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Create an Assay object #' #' Create an Assay object from a feature (e.g. gene) expression matrix. The #' expected format of the input matrix is features x cells. #' #' Non-unique cell or feature names are not allowed. Please make unique before #' calling this function. #' #' @param counts Unnormalized data such as raw counts or TPMs #' @param data Prenormalized data; if provided, do not pass \code{counts} #' @param min.cells Include features detected in at least this many cells. Will #' subset the counts matrix as well. To reintroduce excluded features, create a #' new object with a lower cutoff #' @param min.features Include cells where at least this many features are #' detected #' @param key Optional key to initialize assay with #' @param check.matrix Check counts matrix for NA, NaN, Inf, and #' non-integer values #' @param ... Arguments passed to \code{\link{as.sparse}} #' #' @return A \code{\link{Assay}} object #' #' @importFrom methods as #' @importFrom Matrix colSums rowSums #' #' @export #' #' @family assay #' #' @examples #' \dontrun{ #' pbmc_raw <- read.table( #' file = system.file('extdata', 'pbmc_raw.txt', package = 'Seurat'), #' as.is = TRUE #' ) #' pbmc_rna <- CreateAssayObject(counts = pbmc_raw) #' pbmc_rna #' } #' CreateAssayObject <- function( counts, data, min.cells = 0, min.features = 0, key = NULL, check.matrix = FALSE, ... ) { if (missing(x = counts) && missing(x = data)) { abort(message = "Must provide either 'counts' or 'data'") } else if (!missing(x = counts) && !missing(x = data)) { abort(message = "Either 'counts' or 'data' must be missing; both cannot be provided") } else if (!missing(x = counts)) { # check that dimnames of input counts are unique if (anyDuplicated(x = rownames(x = counts))) { warn( message = "Non-unique features (rownames) present in the input matrix, making unique" ) rownames(x = counts) <- make.unique(names = rownames(x = counts)) } if (anyDuplicated(x = colnames(x = counts))) { warn( message = "Non-unique cell names (colnames) present in the input matrix, making unique" ) colnames(x = counts) <- make.unique(names = colnames(x = counts)) } if (is.null(x = colnames(x = counts))) { abort(message = "No cell names (colnames) names present in the input matrix") } if (any(rownames(x = counts) == '')) { abort(message = "Feature names of counts matrix cannot be empty") } if (nrow(x = counts) > 0 && is.null(x = rownames(x = counts))) { abort(message = "No feature names (rownames) names present in the input matrix") } if (!inherits(x = counts, what = 'dgCMatrix')) { if (inherits(x = counts, what = "data.frame")) { counts <- as.sparse(x = counts, ...) } else { counts <- as.sparse(x = counts) } } if (isTRUE(x = check.matrix)) { CheckMatrix(object = counts) } # Filter based on min.features if (min.features > 0) { nfeatures <- Matrix::colSums(x = counts > 0) counts <- counts[, which(x = nfeatures >= min.features)] } # filter genes on the number of cells expressing if (min.cells > 0) { num.cells <- Matrix::rowSums(x = counts > 0) counts <- counts[which(x = num.cells >= min.cells), ] } data <- counts } else if (!missing(x = data)) { # check that dimnames of input data are unique if (anyDuplicated(x = rownames(x = data))) { warn( message = "Non-unique features (rownames) present in the input matrix, making unique" ) rownames(x = data) <- make.unique(names = rownames(x = data)) } if (anyDuplicated(x = colnames(x = data))) { warn( message = "Non-unique cell names (colnames) present in the input matrix, making unique" ) colnames(x = data) <- make.unique(names = colnames(x = data)) } if (is.null(x = colnames(x = data))) { abort(message = "No cell names (colnames) names present in the input matrix") } if (any(rownames(x = data) == '')) { abort(message = "Feature names of data matrix cannot be empty", call. = FALSE) } if (nrow(x = data) > 0 && is.null(x = rownames(x = data))) { abort(message = "No feature names (rownames) names present in the input matrix") } if (min.cells != 0 | min.features != 0) { warn( message = "No filtering performed if passing to data rather than counts" ) } counts <- new(Class = 'matrix') } # Ensure row- and column-names are vectors, not arrays if (!is.vector(x = rownames(x = counts))) { rownames(x = counts) <- as.vector(x = rownames(x = counts)) } if (!is.vector(x = colnames(x = counts))) { colnames(x = counts) <- as.vector(x = colnames(x = counts)) } if (!is.vector(x = rownames(x = data))) { rownames(x = data) <- as.vector(x = rownames(x = data)) } if (!is.vector(x = colnames(x = data))) { colnames(x = data) <- as.vector(x = colnames(x = data)) } counts <- CheckFeaturesNames(data = counts) data <- CheckFeaturesNames(data = data) # Initialize meta.features init.meta.features <- data.frame(row.names = rownames(x = data)) misc <- if (.GetSeuratCompat() < '5.0.0') { list() } else { calcN_option <- getOption( x = 'Seurat.object.assay.calcn', default = Seurat.options$Seurat.object.assay.calcn ) list(calcN = calcN_option %||% TRUE) } assay <- new( Class = 'Assay', counts = counts, data = data, scale.data = new(Class = 'matrix'), key = Key(object = key)[1L] %||% '', meta.features = init.meta.features, misc = misc ) return(assay) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @importFrom Matrix colSums #' #' @method .CalcN Assay #' @export #' .CalcN.Assay <- function(object, layer = 'counts', ...) { layer <- tryCatch( expr = Layers(object = object, search = layer), error = function(...) NULL ) if (is.null(x = layer)) { return(NULL) } ldat <- LayerData(object = object, layer = layer) if (IsMatrixEmpty(x = ldat) || !inherits(x = ldat, what = 'Matrix')) { return(NULL) } cells_stat <- .CalcN.default(object = ldat) return(cells_stat) } #' @rdname AddMetaData #' # @templateVar fname AddMetaData # @templateVar version 4 # @template name-oldv #' #' @export #' @method AddMetaData Assay #' AddMetaData.Assay <- function(object, metadata, col.name = NULL) { if (is.null(x = col.name) && (is.atomic(x = metadata) && !is.matrix(x = metadata))) { abort(message = "'col.name' must be provided for atomic meta data") } if (inherits(x = metadata, what = c('matrix', 'Matrix'))) { metadata <- as.data.frame(x = metadata) } col.name <- col.name %||% names(x = metadata) %||% colnames(x = metadata) if (is.null(x = col.name)) { abort(message = "No metadata name provided and could not infer it from metadata object") } object[[col.name]] <- metadata return(object) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay Assay #' DefaultAssay.Assay <- function(object, ...) { object <- UpdateSlots(object = object) return(slot(object = object, name = 'assay.orig')) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay<- Assay #' "DefaultAssay<-.Assay" <- function(object, ..., value) { object <- UpdateSlots(object = object) slot(object = object, name = 'assay.orig') <- value return(object) } #' @rdname DefaultLayer #' @method DefaultLayer Assay #' @export #' DefaultLayer.Assay <- function(object, ...) { return('data') } #' @method Features Assay #' @export #' Features.Assay <- function( x, layer = c('data', 'scale.data', 'counts'), slot = deprecated(), ... ) { if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'Features(slot = )', with = 'Features(layer = )' ) layer <- slot } layer <- layer[1L] %||% 'data' layer <- match.arg(arg = layer) features <- rownames(x = GetAssayData(object = x, layer = layer)) if (!length(x = features)) { features <- NULL } return(features) } #' @method FetchData Assay #' @export #' FetchData.Assay <- function( object, vars, cells = NULL, layer = NULL, slot = deprecated(), ... ) { if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'FetchData(slot = )', with = 'FetchData(layer = )' ) layer <- layer %||% slot } # Identify slot to use layer <- layer %||% 'data' layer <- match.arg(arg = layer, choices = c('counts', 'data', 'scale.data')) # Identify cells to use cells <- cells %||% colnames(x = object) if (is.numeric(x = cells)) { cells <- colnames(x = object)[cells] } cells.orig <- cells cells <- intersect(x = cells, y = colnames(x = object)) if (length(x = cells) != length(x = cells.orig)) { warn(message = paste( "Removing", length(x = cells.orig) - length(x = cells), "cells not present in the assay" )) } # Check vars orig <- vars vars <- gsub( pattern = paste0('^', Key(object = object)), replacement = '', x = vars ) # Pull expression information mat <- GetAssayData(object = object, layer = layer) if (IsMatrixEmpty(x = mat)) { abort(message = paste("Layer", sQuote(x = layer), "is empty in this assay")) } vars <- intersect(x = vars, y = rownames(x = mat)) tf <- .GetMethod(fxn = 't', cls = class(x = mat)) data.fetched <- as.data.frame(x = as.matrix( x = tf(x = mat[vars, cells, drop = FALSE]) )) # Add keys to keyed vars keyed.features <- paste0(Key(object = object), names(x = data.fetched)) keyed.idx <- which(x = keyed.features %in% orig) if (length(x = keyed.idx)) { names(x = data.fetched)[keyed.idx] <- keyed.features[keyed.idx] } # Check the final list of features missing <- setdiff(x = orig, y = names(x = data.fetched)) if (length(x = missing) == length(x = orig)) { abort(message = "None of the requested features found") } else if (length(x = missing)) { warn(message = paste( "The following features could not be found", paste(missing, collapse = ', ') )) } return(data.fetched) } #' @rdname AssayData #' @export #' @method GetAssayData Assay #' #' @examples #' # Get the data directly from an Assay object #' GetAssayData(pbmc_small[["RNA"]], layer = "data")[1:5,1:5] #' GetAssayData.Assay <- function( object, layer = c('data', 'scale.data', 'counts'), slot = deprecated(), ... ) { CheckDots(...) if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'GetAssayData(slot = )', with = 'GetAssayData(layer = )' ) layer <- slot } layer <- layer[1L] %||% 'data' layer <- match.arg(arg = layer) return(methods::slot(object = object, name = layer)) } #' @rdname VariableFeatures #' @export #' @method HVFInfo Assay #' #' @examples #' # Get the HVF info directly from an Assay object #' HVFInfo(pbmc_small[["RNA"]], method = 'vst')[1:5, ] #' HVFInfo.Assay <- function( object, method, status = FALSE, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = '5.0.0', what = 'HVFInfo(selection.method = )', with = 'HVFInfo(method = )' ) method <- selection.method } disp.methods <- c('mean.var.plot', 'dispersion', 'disp') if (tolower(x = method) %in% disp.methods) { method <- 'mvp' } method <- switch( EXPR = tolower(x = method), sctransform = 'sct', method ) vars <- switch( EXPR = method, vst = c('mean', 'variance', 'variance.standardized'), mvp = c('mean', 'dispersion', 'dispersion.scaled'), sct = c('gmean', 'variance', 'residual_variance'), abort(message = paste("Unknown method:", sQuote(x = method))) ) tryCatch( expr = hvf.info <- object[[paste(method, vars, sep = '.')]], error = function(e) { stop( "Unable to find highly variable feature information for method '", method, "'", call. = FALSE ) } ) colnames(x = hvf.info) <- vars if (status) { hvf.info$variable <- object[[paste0(method, '.variable')]] } return(hvf.info) } #' @rdname Key #' @export #' @method Key Assay #' #' @examples #' # Get an Assay key #' Key(pbmc_small[["RNA"]]) #' Key.Assay <- function(object, ...) { CheckDots(...) return(slot(object = object, name = 'key')) } #' @rdname Key #' @export #' @method Key<- Assay #' #' @examples #' # Set the key for an Assay #' Key(pbmc_small[["RNA"]]) <- "newkey_" #' Key(pbmc_small[["RNA"]]) #' "Key<-.Assay" <- function(object, ..., value) { CheckDots(...) slot(object = object, name = 'key') <- value return(object) } #' @rdname Layers #' @method LayerData Assay #' @export #' LayerData.Assay <- function( object, layer = NULL, cells = NULL, features = NULL, slot = deprecated(), ... ) { if (is_present(arg = slot)) { deprecate_stop( when = "5.0.0", what = "LayerData(slot = )", with = "LayerData(layer = )" ) } # Figure out which matrix we're pulling layer <- layer[1L] %||% "data" # layer <- match.arg( # arg = layer, # choices = Layers(object = object, search = FALSE) # ) # Handle empty layers if (IsMatrixEmpty(x = methods::slot(object = object, name = layer))) { msg <- paste("Layer", sQuote(x = layer), "is empty") opt <- getOption( x = 'Seurat.object.assay.v3.missing_layer', default = Seurat.options$Seurat.object.assay.v3.missing_layer ) opt <- tryCatch( expr = arg_match0(arg = opt, values = c('matrix', 'null', 'error')), error = function(...) { return(Seurat.options$Seurat.object.assay.v3.missing_layer) } ) if (opt == 'error') { abort(message = msg) } warn(message = msg) return(switch( EXPR = opt, matrix = switch( EXPR = layer, scale.data = new(Class = 'matrix'), new(Class = 'dgCMatrix') ), NULL )) } # Allow cell/feature subsets cells <- cells %||% colnames(x = object) features <- features %||% Features(x = object, layer = layer) if (is_bare_integerish(x = cells, finite = TRUE)) { cells <- colnames(x = object)[cells] } cells <- arg_match( arg = cells, values = colnames(x = object), multiple = TRUE ) if (is_bare_integerish(x = features, finite = TRUE)) { features <- Features(x = object, layer = layer)[features] } features <- arg_match( arg = features, values = Features(x = object, layer = layer), multiple = TRUE ) if (length(x = features) == 0) { stop('features are not found') } # Pull the matrix for the cells/features requested return(methods::slot(object = object, name = layer)[features, cells, drop = FALSE]) } #' @rdname Layers #' @method LayerData<- Assay #' @export #' "LayerData<-.Assay" <- function(object, layer, ..., value) { # Check the layer name layer <- layer[1L] layer <- match.arg( arg = layer, choices = Layers(object = object, search = FALSE) ) # Allow short-hand switch if (rlang::is_scalar_character(x = value)) { value <- arg_match0(arg = value, values = Layers(object = object)) value <- LayerData(object = object, layer = value) } # Prepare an empty matrix if value is NULL value <- value %||% switch( EXPR = layer, scale.data = new(Class = 'matrix'), counts = new(Class = 'dgCMatrix'), data = { if (IsMatrixEmpty(x = suppressWarnings(expr = LayerData(object = object, layer = 'counts')))) { abort(message = "Cannot remove the data layer") } warn(message = "Resetting the data matrix to the raw counts") LayerData(object = object, layer = 'counts') } ) # Check the class of the matrix if (!inherits(x = value, what = c('matrix', 'dgCMatrix'))) { abort(message = paste( "'value' must be a 'matrix' or 'dgCMatrix' in v3 Assays, not a", sQuote(x = class(x = value)[1L]) )) } if (!IsMatrixEmpty(x = value)) { vnames <- dimnames(x = value) # Check presence of cell- and feature-names if (is.null(x = vnames)) { if (!all(dim(x = value) == dim(x = object))) { abort(message = "New data must have feature and cell names") } dimnames(x = value) <- dimnames(x = object) } else if (any(.IsNull(x = vnames)) || !all(unlist(x = lapply(X = vnames, FUN = nzchar)))) { abort(message = "New data must have feature and cell names") } # Remove underscores from feature names if (any(grepl(pattern = '_', x = rownames(x = value)))) { warn( message = "Feature names cannot have underscores ('_'), replacing with dashes ('-')" ) rownames(x = value) <- gsub( pattern = '_', replacement = '-', x = rownames(x = value) ) } # Check the the cells if (ncol(x = value) != ncol(x = object)) { abort(message = "The new data must have the same number of cells as the current data") } else if (!all(colnames(x = value) %in% colnames(x = object))) { abort(message = "The new data must have the same cells as the current data") } value <- value[, colnames(x = object), drop = FALSE] # Check the features if (!any(rownames(x = value) %in% rownames(x = object))) { abort(message = "None of the features provided are present in the existing data") } else if (!all(rownames(x = value) %in% rownames(x = object))) { warn(message = "Extra features present in the the new data compared to the existing data") } features <- intersect(x = rownames(x = object), y = rownames(x = value)) value <- value[features, , drop = FALSE] if (layer %in% c('counts', 'data') && nrow(x = value) != nrow(x = object)) { abort(message = "The new data must have the same number of features as the current data") } } slot(object = object, name = layer) <- value validObject(object = object) return(object) } #' @rdname Layers #' @method Layers Assay #' @export #' Layers.Assay <- function(object, search = NA, ...) { layers <- c('counts', 'data', 'scale.data') if (isFALSE(x = search)) { return(layers) } layers <- Filter( f = function(x) { return(!IsMatrixEmpty(x = slot(object = object, name = x))) }, x = layers ) if (!length(x = layers)) { abort(message = "All matrices are empty in this Assay") } if (is.null(x = search)) { return(DefaultLayer(object = object)) } if (!is_na(x = search)) { layers <- intersect(x = search, y = layers) if (length(x = layers) == 0) { warning( "Layer ", search, " isn't present in the assay ", deparse(expr = substitute(expr = object)), "; returning NULL", call. = FALSE, immediate. = TRUE ) return(NULL) } } return(layers) } #' @param slot Name of specific bit of meta data to pull #' #' @rdname Misc #' @export #' @method Misc Assay #' Misc.Assay <- .Misc #' @rdname Misc #' @export #' @method Misc<- Assay #' "Misc<-.Assay" <- `.Misc<-` #' @param new.names vector of new cell names #' #' @rdname RenameCells #' @export #' @method RenameCells Assay #' #' @examples #' # Rename cells in an Assay #' head(x = colnames(x = pbmc_small[["RNA"]])) #' renamed.assay <- RenameCells( #' pbmc_small[["RNA"]], #' new.names = paste0("A_", colnames(x = pbmc_small[["RNA"]])) #' ) #' head(x = colnames(x = renamed.assay)) #' RenameCells.Assay <- function(object, new.names = NULL, ...) { CheckDots(...) names(new.names) <- NULL for (data.slot in c("counts", "data", "scale.data")) { old.data <- GetAssayData(object = object, layer = data.slot) if (ncol(x = old.data) <= 1) { next } colnames(x = slot(object = object, name = data.slot)) <- new.names } return(object) } #' @importFrom stats na.omit #' #' @rdname AssayData #' @export #' @method SetAssayData Assay #' #' @examples #' # Set an Assay layer directly #' count.data <- GetAssayData(pbmc_small[["RNA"]], layer = "counts") #' count.data <- as.matrix(x = count.data + 1) #' new.assay <- SetAssayData(pbmc_small[["RNA"]], layer = "counts", new.data = count.data) #' SetAssayData.Assay <- function( object, layer = c('data', 'scale.data', 'counts'), new.data, slot = deprecated(), ... ) { if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'SetAssayData(slot = )', with = 'SetAssayData(layer = )' ) layer <- slot } CheckDots(...) layer <- layer[1] layer <- match.arg(arg = layer) if (!IsMatrixEmpty(x = new.data)) { if (any(grepl(pattern = '_', x = rownames(x = new.data)))) { warning( "Feature names cannot have underscores ('_'), replacing with dashes ('-')", call. = FALSE, immediate. = TRUE ) rownames(x = new.data) <- gsub( pattern = '_', replacement = '-', x = rownames(x = new.data) ) } if (ncol(x = new.data) != ncol(x = object)) { stop( "The new data doesn't have the same number of cells as the current data", call. = FALSE ) } num.counts <- nrow(x = object) counts.names <- rownames(x = object) if (layer == 'scale.data' && nrow(x = new.data) > num.counts) { warning( "Adding more features than present in current data", call. = FALSE, immediate. = TRUE ) } else if (layer %in% c('counts', 'data') && nrow(x = new.data) != num.counts) { warning( "The new data doesn't have the same number of features as the current data", call. = FALSE, immediate. = TRUE ) } if (!all(rownames(x = new.data) %in% counts.names)) { warning( "Adding features not currently present in the object", call. = FALSE, immediate. = TRUE ) } new.features <- na.omit(object = match( x = counts.names, table = rownames(x = new.data) )) new.cells <- colnames(x = new.data) if (!all(new.cells %in% colnames(x = object))) { stop( "All cell names must match current cell names", call. = FALSE ) } new.data <- new.data[new.features, colnames(x = object), drop = FALSE] if (layer %in% c('counts', 'data') && !all(dim(x = new.data) == dim(x = object))) { stop( "Attempting to add a different number of cells and/or features", call. = FALSE ) } } if (!is.vector(x = rownames(x = new.data))) { rownames(x = new.data) <- as.vector(x = rownames(x = new.data)) } if (!is.vector(x = colnames(x = new.data))) { colnames(x = new.data) <- as.vector(x = colnames(x = new.data)) } slot(object = object, name = layer) <- new.data return(object) } #' @param decreasing Return features in decreasing order (most spatially #' variable first). #' #' @rdname VariableFeatures #' @export #' @method SpatiallyVariableFeatures Assay #' SpatiallyVariableFeatures.Assay <- function( object, method = "moransi", decreasing = TRUE, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = "5.0.0", what = "SpatiallyVariableFeatures(selection.method = )", with = "SpatiallyVariableFeatures(method = )" ) method <- selection.method } vf <- SVFInfo(object = object, method = method, status = TRUE) vf <- vf[rownames(vf)[which(vf[, "variable"][, 1])], ] if (!is.null(x = decreasing)) { vf <- vf[order(vf[, "rank"][, 1], decreasing = !decreasing), ] } return(rownames(vf)) } #' @rdname VariableFeatures #' @export #' @method SVFInfo Assay #' SVFInfo.Assay <- function( object, method = c("markvariogram", "moransi"), status = FALSE, selection.method = deprecated(), ... ) { CheckDots(...) if (is_present(arg = selection.method)) { .Deprecate( when = "5.0.0", what = "SVFInfo(selection.method = )", with = "SVFInfo(method = )" ) method <- selection.method } method <- match.arg(method) vars <- switch( EXPR = method, markvariogram = grep( pattern = "r.metric", x = colnames(object[[]]), value = TRUE ), moransi = grep( pattern = "MoransI", x = colnames(object[[]]), value = TRUE ), abort(message = paste("Unknown method:", sQuote(x = method))) ) tryCatch( expr = svf.info <- object[[vars]], error = function(e) { stop( "Unable to find spatially variable feature information for method '", method, "'", call. = FALSE ) } ) colnames(x = svf.info) <- vars if (status) { svf.info$variable <- object[[paste0(method, ".spatially.variable")]] svf.info$rank <- object[[paste0(method, ".spatially.variable.rank")]] } return(svf.info) } #' @rdname VariableFeatures #' @export #' @method VariableFeatures Assay #' VariableFeatures.Assay <- function( object, method = NULL, selection.method = deprecated(), ... ) { suppressWarnings(CheckDots(...)) if (is_present(arg = selection.method)) { .Deprecate( when = '5.0.0', what = 'VariableFeatures(selection.method = )', with = 'VariableFeatures(method = )' ) method <- selection.method } if (!is.null(x = method)) { vf <- HVFInfo( object = object, method = method, status = TRUE ) return(rownames(x = vf)[which(x = vf[, "variable"][, 1])]) } return(slot(object = object, name = 'var.features')) } #' @rdname VariableFeatures #' @export #' @method VariableFeatures<- Assay #' "VariableFeatures<-.Assay" <- function(object, ..., value) { CheckDots(...) if (!length(x = value)) { slot(object = object, name = 'var.features') <- character(length = 0) return(object) } if (any(grepl(pattern = '_', x = value))) { warning( "Feature names cannot have underscores '_', replacing with dashes '-'", call. = FALSE, immediate = TRUE ) value <- gsub(pattern = '_', replacement = '-', x = value) } value <- split(x = value, f = value %in% rownames(x = object)) if (length(x = value[['FALSE']]) > 0) { if (length(x = value[['TRUE']]) == 0) { abort(message = "None of the features provided are in this Assay object") } else { warning( "Not all features provided are in this Assay object, removing the following feature(s): ", paste(value[['FALSE']], collapse = ', '), call. = FALSE, immediate. = TRUE ) } } slot(object = object, name = 'var.features') <- value[['TRUE']] return(object) } #' @param cells Subset of cell names #' @param expression A predicate expression for feature/variable expression, #' can evaluate anything that can be pulled by \code{FetchData}; please note, #' you may need to wrap feature names in backticks (\code{``}) if dashes #' between numbers are present in the feature name #' @param invert Invert the selection of cells #' #' @importFrom stats na.omit #' #' @rdname WhichCells #' @export #' @method WhichCells Assay #' WhichCells.Assay <- function( object, cells = NULL, expression, invert = FALSE, ... ) { CheckDots(...) cells <- cells %||% colnames(x = object) if (!missing(x = expression) && !is.null(x = substitute(expr = expression))) { key.pattern <- paste0('^', Key(object = object)) expr <- if (tryCatch(expr = is_quosure(x = expression), error = function(...) FALSE)) { expression } else if (is.call(x = enquo(arg = expression))) { enquo(arg = expression) } else { parse(text = expression) } expr.char <- suppressWarnings(expr = as.character(x = expr)) expr.char <- unlist(x = lapply(X = expr.char, FUN = strsplit, split = ' ')) expr.char <- gsub( pattern = key.pattern, replacement = '', x = expr.char, perl = TRUE ) expr.char <- gsub( pattern = '(', replacement = '', x = expr.char, fixed = TRUE ) expr.char <- gsub( pattern = '`', replacement = '', x = expr.char ) vars.use <- which(x = expr.char %in% rownames(x = object)) expr.char <- expr.char[vars.use] data.subset <- FetchData(object = object, vars = expr.char) cells <- rownames(x = data.subset)[eval_tidy(expr = expr, data = data.subset)] } if (invert) { cells <- colnames(x = object)[!colnames(x = object) %in% cells] } cells <- na.omit(object = unlist(x = cells, use.names = FALSE)) return(as.character(x = cells)) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @inherit .DollarNames.Assay5 return title details sections seealso #' #' @description Autocompletion for \code{$} access on an #' \code{\link{Assay}} object #' #' @inheritParams utils::.DollarNames #' @param x An \code{\link{Assay}} object #' #' @importFrom utils .DollarNames #' #' @keywords internal #' #' @method .DollarNames Assay #' @export #' #' @concept assay #' .DollarNames.Assay <- function(x, pattern = '') { slots.avial <- Layers(x) slots.avial <- as.list(slots.avial) names(slots.avial) <- unlist(slots.avial) return(.DollarNames(x = slots.avial, pattern = pattern)) } #' @inherit $.Assay5 return title description details sections params #' #' @param x An \code{\link{Assay}} object #' #' @method $ Assay #' @export #' #' @family assay #' #' @examples #' rna <- pbmc_small[["RNA"]] #' #' # Fetch a layer with `$` #' rna$data[1:10, 1:4] #' "$.Assay" <- function(x, i) { return(LayerData(object = x, layer = i)) } #' @rdname cash-.Assay #' #' @method $<- Assay #' @export #' #' @examples #' # Add a layer with `$` #' rna$data <- rna$counts #' rna$data[1:10, 1:4] #' "$<-.Assay" <- function(x, i, value) { LayerData(object = x, layer = i) <- value return(x) } #' @inherit [.Assay5 return title description details sections #' #' @inheritParams [.Assay5 #' @param x An \code{\link{Assay}} object #' @param j Ignored #' #' @method [ Assay #' @export #' #' @order 1 #' #' @seealso \code{\link{LayerData}} #' #' @family assay #' #' @examples #' rna <- pbmc_small[["RNA"]] #' #' # Get a vector of layer names in this assay #' rna[] #' #' # Fetch layer data #' rna["data"][1:10, 1:4] #' "[.Assay" <- function(x, i = missing_arg(), j = missing_arg(), ...) { if (getOption(x = 'Seurat.object.assay.brackets', default = 'v5') == 'v3') { if (is_missing(x = i)) { i <- seq_len(length.out = nrow(x = x)) } if (is_missing(x = j)) { j <- seq_len(length.out = ncol(x = x)) } return(LayerData( object = x, layer = DefaultLayer(object = x)[1L], cells = j, features = i )) } if (is_missing(x = i)) { return(Layers(object = x)) } return(LayerData(object = x, layer = i, ...)) } #' @inherit [[.Assay5 return title description details sections #' #' @inheritParams [[.Assay5 #' @param x An \code{\link{Assay}} object #' #' @method [[ Assay #' @export #' #' @family assay #' #' @order 1 #' #' @examples #' rna <- pbmc_small[["RNA"]] #' #' # Pull the entire feature-level meta data data frame #' head(rna[[]]) #' #' # Pull a specific column of feature-level meta data #' head(rna[["vst.mean"]]) #' head(rna[["vst.mean", drop = TRUE]]) #' "[[.Assay" <- function(x, i, ..., drop = FALSE) { if (missing(x = i)) { i <- colnames(x = slot(object = x, name = 'meta.features')) } data.return <- slot(object = x, name = 'meta.features')[, i, drop = FALSE, ...] if (drop) { data.return <- unlist(x = data.return, use.names = FALSE) names(x = data.return) <- rep.int(x = rownames(x = x), times = length(x = i)) } return(data.return) } #' @inherit dim.Assay5 return title description details sections #' #' @inheritParams [.Assay #' #' @method dim Assay #' @export #' #' @family assay #' #' @examples #' rna <- pbmc_small[["RNA"]] #' dim(rna) #' dim.Assay <- function(x) { return(dim(x = GetAssayData(object = x))) } #' @inherit dimnames.Assay5 title description details sections #' #' @inheritParams [.Assay #' #' @return \code{dimnames}: A two-length list with the following values: #' \itemize{ #' \item A character vector will all features in \code{x} #' \item A character vector will all cells in \code{x} #' } #' #' @method dimnames Assay #' @export #' #' @family assay #' @family dimnames #' #' @examples #' rna <- pbmc_small[["RNA"]] #' #' # Feature and cell names can be acquired with `rownames` and `colnames` #' head(rownames(rna)) #' head(colnames(rna)) #' dimnames.Assay <- function(x) { return(dimnames(x = GetAssayData(object = x))) } #' @param value A two-length list where the first entry is the existing feature #' names for \code{x} and the second entry is the \emph{updated} cell names #' for \code{x} #' #' @return \code{dimnames<-}: \code{x} with the cell names updated to those #' in \code{value[[2L]]} #' #' @rdname dimnames.Assay #' #' @method dimnames<- Assay #' @export #' #' @examples #' # Cell names can be updated with `colnames<-` #' colnames(rna)[1] <- "newcell" #' head(colnames(rna)) #' "dimnames<-.Assay" <- function(x, value) { op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op), add = TRUE) # Check the provided dimnames msg <- "Invalid 'dimnames' given for a Seurat object" if (!is_bare_list(x = value, n = 2L)) { abort(message = msg) } else if (!all(sapply(X = value, FUN = length) == dim(x = x))) { abort(message = msg) } value <- lapply(X = value, FUN = as.character) # Warn about changing features if (!all(value[[1L]] == rownames(x = slot(object = x, name = 'data')))) { warn(message = "Changing feature names in v3 Assays is not supported") } # Set cell names for (lyr in c('counts', 'data', 'scale.data')) { if (!IsMatrixEmpty(x = slot(object = x, name = lyr))) { suppressWarnings(expr = colnames(x = slot(object = x, name = lyr)) <- value[[2L]]) } } # Validate and return the Seurat object options(op) validObject(object = x) return(x) } #' @rdname sub-sub-.Assay #' #' @method head Assay #' @export #' #' @examples #' # `head` and `tail` can be used to quickly view feature-level meta data #' head(rna) #' head.Assay <- function(x, n = 10L, ...) { return(head(x[[]], n = 10L, ...)) } #' Merge Assays #' #' Merge one or more v3 assays together #' #' @inheritParams [[.Assay #' @param y One or more \code{\link{Assay}} objects #' @param add.cell.ids A character vector of \code{length(x = c(x, y))}; #' appends the corresponding values to the start of each objects' cell names #' @param merge.data Merge the data slots instead of just merging the counts #' (which requires renormalization); this is recommended if the same #' normalization approach was applied to all objects #' @param labels,collapse Currently unused #' #' @return A new assay with data merged from \code{c(x, y)} #' #' @method merge Assay #' @export #' #' @family assay #' merge.Assay <- function( x = NULL, y = NULL, add.cell.ids = NULL, merge.data = TRUE, labels = NULL, collapse = TRUE, ... ) { CheckDots(...) assays <- c(x, y) if (any(sapply( X = assays, FUN = function(assay.i) inherits(x = assay.i, what = "Assay5") ))) { return(merge(x = as(x, "Assay5"), y, ...)) } if (!is.null(x = add.cell.ids)) { for (i in seq_along(along.with = assays)) { assays[[i]] <- RenameCells( object = assays[[i]], new.names = add.cell.ids[i] ) } } # Merge the counts (if present) counts.mats <- lapply(X = assays, FUN = ValidateDataForMerge, slot = "counts") keys <- unlist(sapply(X = assays, FUN = Key)) merged.counts <- RowMergeSparseMatrices( mat1 = counts.mats[[1]], mat2 = counts.mats[2:length(x = counts.mats)] ) combined.assay <- CreateAssayObject( counts = merged.counts, min.cells = -1, min.features = -1 ) Key(object = combined.assay) <- keys[1] if (merge.data) { data.mats <- lapply(X = assays, FUN = ValidateDataForMerge, slot = "data") merged.data <- RowMergeSparseMatrices( mat1 = data.mats[[1]], mat2 = data.mats[2:length(x = data.mats)] ) # only keep cells that made it through counts filtering params if (!all.equal(target = colnames(x = combined.assay), current = colnames(x = merged.data))) { merged.data <- merged.data[, colnames(x = combined.assay)] } combined.assay <- SetAssayData( object = combined.assay, layer = "data", new.data = merged.data ) } return(combined.assay) } #' @inherit split.Assay5 title description details #' #' @inheritParams split.Assay5 #' @param x An \code{\link{Assay}} object #' #' @return Returns a v5 assay with splitted layers #' #' @method split Assay #' @export #' #' @family assay #' split.Assay <- function( x, f, drop = FALSE, layers = NA, ... ) { warn(message = paste( strwrap(x = paste( "Input is a v3 assay and `split()` only works for v5 assays;", "converting to a v5 assay" )) )) x <- as(object = x, Class = 'Assay5') split.x <- split( x = x, f = f, drop = drop, layers = layers, ... ) return(split.x) } #' @inherit subset.Assay5 title description details sections #' #' @inheritParams subset.Assay5 #' @param x An \code{\link{Assay}} object #' #' @return \code{x} with just the cells and features specified by #' \code{cells} and \code{features} #' #' @importFrom stats na.omit #' #' @method subset Assay #' @export #' #' @family assay #' #' @examples #' rna <- pbmc_small[["RNA"]] #' rna2 <- subset(rna, features = VariableFeatures(rna)) #' rna2 #' subset.Assay <- function(x, cells = NULL, features = NULL, ...) { CheckDots(...) cells <- cells %||% colnames(x = x) if (all(is.na(x = cells))) { cells <- colnames(x = x) } else if (any(is.na(x = cells))) { warn(message = "NAs passed in cells vector, removing NAs") cells <- na.omit(object = cells) } cells <- intersect(x = colnames(x), y = cells) features <- features %||% rownames(x = x) if (all(is.na(x = features))) { features <- rownames(x = x) } else if (any(is.na(x = features))) { warn(message = "NAs passed in the features vector, removing NAs") features <- na.omit(object = features) } if (all(sapply(X = list(features, cells), FUN = length) == dim(x = x))) { return(x) } if (is.numeric(x = features)) { features <- rownames(x = x)[features] } features <- gsub( pattern = paste0('^', Key(object = x)), replacement = '', x = features ) features <- intersect(x = features, y = rownames(x = x)) if (length(x = features) == 0) { abort(message = "Cannot find features provided") } if (ncol(x = GetAssayData(object = x, layer = 'counts')) == ncol(x = x)) { slot(object = x, name = "counts") <- GetAssayData(object = x, layer = "counts")[features, cells, drop = FALSE] } slot(object = x, name = "data") <- GetAssayData(object = x, layer = "data")[features, cells, drop = FALSE] cells.scaled <- colnames(x = GetAssayData(object = x, layer = "scale.data")) cells.scaled <- cells.scaled[cells.scaled %in% cells] cells.scaled <- cells.scaled[na.omit(object = match(x = colnames(x = x), table = cells.scaled))] features.scaled <- rownames(x = GetAssayData(object = x, layer = 'scale.data')) features.scaled <- intersect(x = features, y = features.scaled) slot(object = x, name = "scale.data") <- if (length(x = cells.scaled) > 0 && length(x = features.scaled) > 0) { GetAssayData(object = x, layer = "scale.data")[features.scaled, cells.scaled, drop = FALSE] } else { new(Class = 'matrix') } VariableFeatures(object = x) <- VariableFeatures(object = x)[VariableFeatures(object = x) %in% features] slot(object = x, name = 'meta.features') <- x[[]][features, , drop = FALSE] validObject(object = x) return(x) } #' @rdname sub-sub-.Assay #' #' @method tail Assay #' @export #' #' @examples #' tail(rna) #' tail.Assay <- function(x, n = 10L, ...) { return(tail(x[[]], n = n, ...)) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname sub-.Assay #' #' @examples #' # Set layer data #' rna["data"] <- rna["counts"] #' rna["data"][1:10, 1:4] #' setMethod( f = '[<-', signature = c(x = 'Assay', i = 'character'), definition = function(x, i, ..., value) { LayerData(object = x, layer = i, ...) <- value return(x) } ) #' @rdname sub-sub-.Assay #' #' @order 2 #' setMethod( f = '[[<-', signature = c(x = 'Assay'), definition = function(x, i, ..., value) { meta.data <- x[[]] feature.names <- rownames(x = meta.data) if (is.data.frame(x = value)) { value <- lapply( X = 1:ncol(x = value), FUN = function(index) { v <- value[[index]] names(x = v) <- rownames(x = value) return(v) } ) } err.msg <- "Cannot add more or fewer meta.features information without values being named with feature names" if (length(x = i) > 1) { # Add multiple bits of feature-level metadata value <- rep_len(x = value, length.out = length(x = i)) for (index in 1:length(x = i)) { names.intersect <- intersect(x = names(x = value[[index]]), feature.names) if (length(x = names.intersect) > 0) { meta.data[names.intersect, i[index]] <- value[[index]][names.intersect] } else if (length(x = value) %in% c(nrow(x = meta.data), 1) %||% is.null(x = value)) { meta.data[i[index]] <- value[index] } else { stop(err.msg, call. = FALSE) } } } else { # Add a single column to feature-level metadata value <- unlist(x = value) if (length(x = intersect(x = names(x = value), y = feature.names)) > 0) { meta.data[, i] <- value[feature.names] } else if (length(x = value) %in% c(nrow(x = meta.data), 1) || is.null(x = value)) { meta.data[, i] <- value } else { stop(err.msg, call. = FALSE) } } slot(object = x, name = 'meta.features') <- meta.data return(x) } ) #' @rdname sub-sub-.Assay #' setMethod( f = '[[<-', signature = c( x = 'Assay', i = 'missing', j = 'missing', value = 'data.frame' ), definition = function(x, ..., value) { # Allow removing all meta data if (IsMatrixEmpty(x = value)) { x[[names(x = x[[]])]] <- NULL return(x) } if (is.null(names(x = value))) { warn(message = 'colnames of input cannot be NULL') } else { # If no `i` provided, use the column names from value x[[names(x = value)]] <- value } return(x) } ) #' Row and Column Sums and Means #' #' Calculate \code{\link{rowSums}}, \code{\link{colSums}}, #' \code{\link{rowMeans}}, and \code{\link{colMeans}} on \code{Assay} objects #' #' @inheritParams [[.Assay #' @inheritParams Matrix::colMeans #' @param slot Name of assay expression matrix to calculate column/row #' means/sums on #' #' @return \code{colMeans}: The column (cell-wise) means of \code{slot} #' #' @importFrom Matrix colMeans #' #' @keywords internal #' #' @export #' #' @concept assay #' #' @seealso \code{\link{Assay}} #' #' @examples #' rna <- pbmc_small[["RNA"]] #' #' colMeans(rna) #' setMethod( f = 'colMeans', signature = c(x = 'Assay'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::colMeans( x = GetAssayData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' @return \code{colSums}: The column (cell-wise) sums of \code{slot} #' #' @rdname colMeans-Assay-method #' #' @importFrom Matrix colSums #' #' @export #' #' @examples #' colSums(rna) #' setMethod( f = 'colSums', signature = c(x = 'Assay'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::colSums( x = GetAssayData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' @return \code{rowMeans}: The row (feature-wise) means of \code{slot} #' #' @rdname colMeans-Assay-method #' #' @importFrom Matrix rowMeans #' #' @export #' #' @examples #' rowMeans(rna) #' setMethod( f = 'rowMeans', signature = c(x = 'Assay'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::rowMeans( x = GetAssayData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' @return \code{rowSums}: The row (feature-wise) sums of \code{slot} #' #' @rdname colMeans-Assay-method #' #' @importFrom Matrix rowSums #' #' @export #' #' @examples #' rowSums(rna) #' setMethod( f = 'rowSums', signature = c(x = 'Assay'), definition = function(x, na.rm = FALSE, dims = 1, ..., slot = 'data') { return(Matrix::rowSums( x = GetAssayData(object = x, layer = slot), na.rm = na.rm, dims = dims, ... )) } ) #' V3 Assay Overview #' #' Overview of an \code{\link{Assay}} object #' #' @template return-show #' #' @keywords internal #' #' @concept assay #' #' @seealso \code{\link{Assay}} #' #' @examples #' rna <- pbmc_small[["RNA"]] #' rna #' setMethod( f = 'show', signature = 'Assay', definition = function(object) { cat( class(x = object)[1], 'data with', nrow(x = object), 'features for', ncol(x = object), 'cells\n' ) if (length(x = VariableFeatures(object = object)) > 0) { top.ten <- head(x = VariableFeatures(object = object), n = 10L) top <- 'Top' variable <- 'variable' } else { top.ten <- head(x = rownames(x = object), n = 10L) top <- 'First' variable <- '' } features <- paste0( variable, ' feature', if (length(x = top.ten) != 1) { 's' }, ":\n" ) features <- gsub(pattern = '^\\s+', replacement = '', x = features) cat( top, length(x = top.ten), features, paste(strwrap(x = paste(top.ten, collapse = ', ')), collapse = '\n'), '\n' ) return(invisible(x = NULL)) } ) #' V3 Assay Validity #' #' @templateVar cls Assay #' @template desc-validity #' #' @section \code{data} Validation: #' blah #' #' @section \code{counts} Validation: #' blah #' #' @section \code{scale.data} Validation: #' blah #' #' @section Feature-Level Meta Data Validation: #' blah #' #' @section Variable Feature Validation: #' blah #' #' @inheritSection Key-validity Key Validation #' #' @name Assay-validity #' #' @family assay #' @seealso \code{\link[methods]{validObject}} #' #' @examples #' rna <- pbmc_small[["RNA"]] #' validObject(rna) #' setValidity( Class = 'Assay', method = function(object) { if (.GetSeuratCompat() < '5.0.0') { return(TRUE) } if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Check matrices features <- rownames(x = slot(object = object, name = 'data')) if (anyDuplicated(x = features)) { valid <- c(valid, "duplicate feature names are not allowed") } cells <- colnames(x = slot(object = object, name = 'data')) if (anyDuplicated(x = cells)) { valid <- c(valid, "duplicate cell names are not allowed") } for (lyr in c('counts', 'scale.data')) { ldat <- slot(object = object, name = lyr) if (IsMatrixEmpty(x = ldat)) { next } if (!all(colnames(x = ldat) == cells)) { valid <- c( valid, paste0("'", lyr, "' must have the same cells as 'data'") ) } if (lyr == 'counts' && !all(rownames(x = ldat) == features)) { valid <- c( valid, paste0("'", lyr, "' must have the same features as 'data'") ) } else if (lyr == 'scale.data') { scaled <- rownames(x = ldat) if (!all(scaled %in% features)) { valid <- c( valid, "all features in 'scale.data' must be present in 'data'" ) } else if (is.unsorted(x = MatchCells(new = scaled, orig = features, ordered = TRUE))) { valid <- c( valid, "features in 'scale.data' must be in the same order as in 'data'" ) } } } # Check meta.features mf <- slot(object = object, name = 'meta.features') if (nrow(x = mf) != length(x = features)) { valid <- c( valid, "'meta.features' must have the same number of rows as 'data'" ) } else if (!all(row.names(x = mf) == features)) { valid <- c(valid, "meta.features' must have the same features as 'data'") } # Check variable features vf <- slot(object = object, name = 'var.features') if (length(x = vf) && !all(vf %in% features)) { valid <- c(valid, "all 'var.features' must be present in") } # TODO: Check assay.orig return(valid %||% TRUE) } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Calculate nCount and nFeature #' #' @param object An \code{\link{Assay}} object #' #' @return A named list with nCount and nFeature #' #' @keywords internal #' #' @noRd #' #' @examples #' \donttest{ #' calcn <- SeuratObject:::CalcN(pbmc_small[["RNA"]]) #' head(as.data.frame(calcn)) #' } #' CalcN <- .CalcN #' Subset cells in vst data #' #' @param sct.info A vst.out list #' @param cells vector of cells to retain #' @param features vector of features to retain #' #' @keywords internal #' #' @noRd #' SubsetVST <- function(sct.info, cells, features) { cells.keep <- intersect(x = cells, y = rownames(x = sct.info$cell_attr)) sct.info$cell_attr <- sct.info$cell_attr[cells.keep, ] # find which subset of features are in the SCT assay feat.keep <- intersect(x = features, y = rownames(x = sct.info$gene_attr)) sct.info$gene_attr <- sct.info$gene_attr[feat.keep, ] return(sct.info) } #' Validate Assay Data for Merge #' #' Pulls the proper data matrix for merging assay data. If the slot is empty, #' will return an empty matrix with the proper dimensions from one of the #' remaining data slots. #' #' @param assay Assay to pull data from #' @param slot Slot to pull from #' #' @return Returns the data matrix if present (i.e.) not 0x0. Otherwise, #' returns an appropriately sized empty sparse matrix #' #' @importFrom methods as #' @importFrom Matrix Matrix #' #' @keywords internal #' #' @noRd #' ValidateDataForMerge <- function(assay, slot) { mat <- GetAssayData(object = assay, layer = slot) if (any(dim(x = mat) == c(0, 0))) { slots.to.check <- setdiff(x = c("counts", "data", "scale.data"), y = slot) for (ss in slots.to.check) { data.dims <- dim(x = GetAssayData(object = assay, layer = ss)) data.slot <- ss if (!any(data.dims == c(0, 0))) { break } } if (any(data.dims == c(0, 0))) { stop("The counts, data, and scale.data slots are all empty for the provided assay.") } mat <- Matrix( data = 0, nrow = data.dims[1], ncol = data.dims[2], dimnames = dimnames(x = GetAssayData(object = assay, layer = data.slot)) ) mat <- as.sparse(x = mat) } return(mat) } SeuratObject/R/RcppExports.R0000644000176200001440000000066715116402676015502 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 GraphToNeighborHelper <- function(mat) { .Call('_SeuratObject_GraphToNeighborHelper', PACKAGE = 'SeuratObject', mat) } RowMergeMatricesList <- function(mat_list, mat_rownames, all_rownames) { .Call('_SeuratObject_RowMergeMatricesList', PACKAGE = 'SeuratObject', mat_list, mat_rownames, all_rownames) } SeuratObject/R/centroids.R0000644000176200001440000003311515116356172015174 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importFrom methods as callNextMethod #' @importClassesFrom sp SpatialPoints #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The \code{Centroids} Class #' #' @slot cells (\code{\link[base:character]{character [n]}}) A vector of cell #' names; there should be as many cell names as there are points and no #' duplicate names #' @slot nsides (\code{\link[base:integer]{integer [1L]}}) The number of sides #' to draw when plotting centroids; must be either \code{0L} for circles or #' greater than 3 #' @slot radius (\code{\link[base:numeric]{numeric [1L]}}) The radius of the #' shape when plotting the centroids #' @slot theta (\code{\link[base:numeric]{numeric [1L]}}) The angle in degrees #' to adjust the shape when plotting the centroids #' #' @family segmentation #' @templateVar cls Centroids #' @template seealso-methods #' setClass( Class = 'Centroids', contains = 'SpatialPoints', slots = list( cells = 'character', nsides = 'integer', radius = 'numeric', theta = 'numeric' ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{Centroids} Methods #' #' Methods for \code{\link[SeuratObject:Centroids-class]{Centroids}} objects #' #' @param x,object A \code{\link[SeuratObject:Centroids-class]{Centroids}} #' object #' @param i,cells A vector of cells to keep; if \code{NULL}, defaults #' to all cells #' @param j,drop Ignored #' @param ... Arguments passed to other methods #' #' @name Centroids-methods #' @rdname Centroids-methods #' #' @seealso \code{\link{Centroids-class}} #' #' @family segmentation #' NULL #' #' @rdname Centroids-methods #' @method Cells Centroids #' @export #' Cells.Centroids <- function(x, ...) { return(slot(object = x, name = 'cells')) } #' @importFrom sp SpatialPoints #' #' @method CreateCentroids default #' @export #' CreateCentroids.default <- function( coords, nsides = Inf, radius = NULL, theta = 0L ) { if (inherits(x = coords, what = 'sf')) { # Set the attribute-geometry relationship to constant # See https://r-spatial.github.io/sf/reference/sf.html#details sf::st_agr(coords) <- "constant" # Extract centroids from sf object centroids <- sf::st_centroid(coords) # Convert to data frame and format centroid_coords <- sf::st_coordinates(centroids) centroids_df <- data.frame( x = centroid_coords[, "X"], y = centroid_coords[, "Y"], row.names = coords$barcodes, stringsAsFactors = FALSE ) coords <- centroids_df } cnames <- c('x', 'y') if (ncol(x = coords) >= 3) { cnames <- append(x = cnames, values = 'cell') } idx <- NameIndex(x = coords, names = cnames, MARGIN = 2L) cells <- if ('cell' %in% names(x = idx)) { as.character(x = coords[, idx[['cell']], drop = TRUE]) } else { rownames(x = coords) } coords <- as.matrix(x = coords[, idx[c('x', 'y'), drop = FALSE]]) colnames(x = coords) <- c('x', 'y') rownames(x = coords) <- NULL if (is.infinite(x = nsides)) { nsides <- 0L } radius <- radius %||% .AutoRadius(coords = coords) obj <- as(object = SpatialPoints(coords = coords), Class = 'Centroids') slot(object = obj, name = 'cells') <- cells slot(object = obj, name = 'nsides') <- as.integer(x = nsides) slot(object = obj, name = 'radius') <- as.numeric(x = radius) slot(object = obj, name = 'theta') <- as.numeric(x = theta) validObject(object = obj) return(obj) } #' @method CreateCentroids Centroids #' @export #' CreateCentroids.Centroids <- function( coords, nsides = NULL, radius = NULL, theta = NULL ) { return(CreateCentroids( coords = GetTissueCoordinates(object = coords), nsides = nsides %||% length(x = coords), radius = radius %||% Radius(object = coords), theta = theta %||% Theta(object = coords) )) } #' @method Crop Centroids #' @export #' Crop.Centroids <- .Crop #' @details \code{GetTissueCoordinates}: Get cell spatial coordinates #' #' @param full Expand the coordinates to the full polygon #' #' @return \code{GetTissueCoordinates}: A data frame with three columns: #' \itemize{ #' \item \dQuote{\code{x}}: the x-coordinate #' \item \dQuote{\code{y}}: the y-coordinate #' \item \dQuote{\code{cell}}: the cell name #' } #' If \code{full} is \code{TRUE}, then each coordinate will indicate a vertex #' for the cell polygon (created based on nsides, radius, and theta); #' otherwise, each coordinate will indicate a centroid for the cell. #' #' @importFrom sp coordinates #' #' @rdname Centroids-methods #' @method GetTissueCoordinates Centroids #' @export #' GetTissueCoordinates.Centroids <- function(object, full = TRUE, ...) { coords <- as.data.frame(x = coordinates(obj = object)) colnames(x = coords) <- c('x', 'y') coords$cell <- Cells(x = object) if (isTRUE(x = full) && is.finite(x = object)) { ct <- mapply( FUN = PolyVtx, xc = coords$x, yc = coords$y, MoreArgs = list( n = length(x = object), r = Radius(object = object), t1 = Theta(object = object) ) ) xt <- vector(mode = 'list', length = length(x = ct) / 2L) xi <- 1L for (i in seq.int(from = 1L, to = length(x = ct), by = 2L)) { xt[[xi]] <- data.frame( x = ct[[i]], y = ct[[i + 1L]], cell = coords$cell[xi], stringsAsFactors = FALSE ) xi <- xi + 1L } coords <- do.call(what = 'rbind', args = xt) } return(coords) } #' @details \code{Radius}: Get the centroid radius #' #' @return \code{Radius} The radius of the centroids #' #' @rdname Centroids-methods #' @method Radius Centroids #' @export #' Radius.Centroids <- function(object, ...) { return(slot(object = object, name = 'radius')) } #' @details \code{RenameCells}: Update cell names #' #' @inheritParams RenameCells #' #' @return \code{RenameCells}: \code{object} with the cells renamed to #' \code{new.names} #' #' @rdname Centroids-methods #' @method RenameCells Centroids #' @export #' RenameCells.Centroids <- function(object, new.names = NULL, ...) { if (is.null(x = new.names)) { return(object) } new.names <- make.unique(names = new.names) if (length(x = new.names) != length(x = Cells(x = object))) { stop("Cannot partially rename centroid cells", call. = FALSE) } slot(object = object, name = 'cells') <- new.names return(object) } #' @details \code{Theta}: Get the offset angle #' #' @return \code{Theta}: The offset angle in degrees #' #' @rdname Centroids-methods #' @method Theta Centroids #' @export #' Theta.Centroids <- function(object) { return(slot(object = object, name = 'theta')) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @details \code{is.finite}, \code{is.infinite}: Test to see if the centroids #' are circular or polygonal #' #' @return \code{is.finite}: \code{TRUE} if the centroids are polygonal, #' \code{FALSE} if circular #' #' @rdname Centroids-methods #' @method is.finite Centroids #' @export #' is.finite.Centroids <- .FiniteCentroids #' @return \code{is.infinite}: The opposite of \code{is.finite} #' #' @rdname Centroids-methods #' @method is.infinite Centroids #' @export #' is.infinite.Centroids <- Negate(f = .FiniteCentroids) #' @details \code{length}: Get the number of sides for the polygonal centroid #' #' @return \code{length}: \code{0} if the centroids are circular, otherwise the #' number of sides of the polygonal centroid #' #' @rdname Centroids-methods #' @method length Centroids #' @export #' length.Centroids <- function(x) { return(slot(object = x, name = 'nsides')) } #' @template method-lengths #' #' @rdname Centroids-methods #' @method lengths Centroids #' @export #' lengths.Centroids <- function(x, use.names = TRUE) { return(rle(x = Cells(x = x))) } #' @details \code{subset}, \code{[}: Subset a \code{Centroids} object to #' certain cells #' #' @return \code{subset}, \code{[}: \code{x} subsetted to the cells specified #' by \code{cells}/\code{i} #' #' @rdname Centroids-methods #' @method subset Centroids #' @export #' subset.Centroids <- function(x, cells = NULL, ...) { args <- list(...) if (is.null(x = cells)) { return(x) } if (is.numeric(x = cells)) { cells <- Cells(x = x)[cells] cells <- cells[!is.na(x = cells)] } cells <- MatchCells(new = Cells(x = x), orig = cells, ordered = TRUE) if (!length(x = cells)) { stop("None of the requested cells found") } return(CreateCentroids( coords = GetTissueCoordinates(object = x)[cells, ], nsides = args$nsides %||% length(x = x), radius = args$radius %||% Radius(object = x), theta = args$theta %||% Theta(object = x) )) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname Centroids-methods #' setMethod( f = '[', signature = c(x = 'Centroids', i = 'character'), definition = function(x, i, j, ..., drop = TRUE) { i <- MatchCells(new = Cells(x = x), orig = i, ordered = TRUE) return(x[i, drop = drop, ...]) } ) #' @rdname Centroids-methods #' setMethod( f = '[', signature = c(x = 'Centroids', i = 'numeric'), definition = function(x, i, j, ..., drop = TRUE) { info <- list( nsides = length(x = x), radius = Radius(object = x), theta = Theta(object = x) ) cells <- Cells(x = x)[i] cells <- cells[!is.na(x = cells)] x <- callNextMethod() for (n in names(x = info)) { slot(object = x, name = n) <- info[[n]] } slot(object = x, name = 'cells') <- cells validObject(object = x) return(x) } ) setMethod( f = 'over', signature = c(x = 'Centroids', y = 'SpatialPolygons'), definition = function(x, y, returnList = FALSE, fn = NULL, ...) { deprecate_stop( when = '5.0.0', what = 'over()', details = "Future integration with `sf` is on the roadmap with no current ETA" ) check_installed(pkg = 'sf') return(over( x = as(object = x, Class = 'sf'), y = as(object = y, Class = 'sf'), returnList = returnList, fn = fn, ... )) } ) #' @rdname Overlay #' @export #' setMethod( f = 'Overlay', signature = c(x = 'Centroids', y = 'SpatialPolygons'), definition = function(x, y, invert = FALSE, ...) { check_installed(pkg = 'sf', reason = 'to overlay spatial information') idx <- sf::st_intersects( x = as(object = x, Class = 'sf'), y = as(object = y, Class = 'sf'), sparse = FALSE ) idx <- which(idx) names_in_sf_object1 <- if (!is.null(x = row.names(x = x))) { row.names(x = x)[idx] } else { x$id[idx] } idx <- setNames( object = rep(x = TRUE, length(x = idx)), nm = names_in_sf_object1 ) if (!length(x = idx)) { warn(message = "The selected region does not contain any cell centroids") return(NULL) } idx <- sort(x = as.integer(x = names(x = idx))) if (isTRUE(x = invert)) { idx <- -idx } return(x[idx]) } ) #' @template method-show #' #' @rdname Centroids-methods #' setMethod( f = 'show', signature = c(object = 'Centroids'), definition = function(object) { cat("Spatial centroids for", length(x = Cells(x = object)), "cells\n") cat( "", ifelse( test = length(x = object) == 0L, yes = "Circular", no = paste0(length(x = object), '-sided') ), "spots\n" ) cat(" Radius:", Radius(object = object), '\n') cat(" Offset angle:", Theta(object = object), "degrees\n") return(invisible(x = NULL)) } ) setValidity( Class = 'Centroids', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Check cell names cells <- Cells(x = object) ucells <- Filter(f = nchar, x = unique(x = cells)) if (length(x = ucells) != length(x = cells)) { valid <- c( valid, "'cells' must be a vector of unique cell names with one name for every coordinate" ) } if (length(x = cells) != nrow(x = slot(object = object, name = 'coords'))) { valid <- c( valid, "the length of 'cells' must equal the number of rows in 'coords'" ) } if (!is.null(x = rownames(x = slot(object = object, name = 'coords')))) { valid <- c(valid, "'coords' must not have any rownames") } # Check nsides nsides <- length(x = object) if (nsides < 0L || nsides %in% seq.int(from = 1L, to = 2L)) { valid <- c( valid, "'nsides' must be either 0 or greater than or equal to 3" ) } # Check radius if (Radius(object = object) <= 0) { valid <- c(valid, "'radius' must be greater than 0") } # Check theta theta <- Theta(object = object) if (theta < 0 || theta > 360) { valid <- c(valid, "'theta must be between 0 and 360") } return(valid %||% TRUE) } ) SeuratObject/R/default.R0000644000176200001440000001637315116320014014617 0ustar liggesusers#' @include zzz.R #' @include generics.R #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname dot-AssayClass #' @method .AssayClass StdAssay #' @export #' .AssayClass.StdAssay <- function(object) { cls <- gsub( pattern = '5$|v5$', replacement = '', x = class(x = object)[1L], ignore.case = TRUE ) return(paste(cls, '(v5)')) } #' @method .MARGIN default #' @export #' .MARGIN.default <- function(x, type = c('features', 'cells'), ...) { type <- arg_match(arg = type) return(unname(obj = c(features = 1L, cells = 2L)[type])) } #' @rdname Cells #' @method Cells default #' @export #' Cells.default <- function(x, ...) { return(colnames(x = x)) } #' @rdname IsGlobal #' @method IsGlobal default #' @export #' IsGlobal.default <- function(object, ...) { return(FALSE) } #' @importFrom stats na.omit #' #' @rdname MatchCells #' @method MatchCells character #' @export #' MatchCells.character <- function(new, orig, ordered = FALSE) { cmatch <- as.vector(x = na.omit(object = match(x = orig, table = new))) if (!length(x = cmatch)) { return(NULL) } if (!isTRUE(x = ordered)) { cmatch <- sort(x = cmatch) } return(cmatch) } #' @rdname MatchCells #' @method MatchCells NULL #' @export #' MatchCells.NULL <- function(new, orig, ordered = FALSE) { return(NULL) } #' @rdname MatchCells #' @method MatchCells numeric #' @export #' MatchCells.numeric <- function(new, orig, ordered = FALSE) { new <- unique(x = new[new <= length(x = orig)]) if (!length(x = new)) { return(NULL) } if (isTRUE(x = ordered)) { new <- sort(x = new) } return(new) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Add Object Metadata #' #' Internal \code{\link{AddMetaData}} definition #' #' @param object An object #' @param metadata A vector, list, or data.frame with metadata to add #' @param col.name A name for meta data if not a named list or data.frame #' #' @return object with metadata added #' #' @keywords internal #' #' @noRd #' .AddMetaData <- function(object, metadata, col.name = NULL) { if (is.null(x = col.name) && (is.atomic(x = metadata) && !is.matrix(x = metadata))) { abort(message = "'col.name' must be provided for atomic meta data") } if (inherits(x = metadata, what = c('matrix', 'Matrix'))) { metadata <- as.data.frame(x = metadata) } col.name <- col.name %||% names(x = metadata) %||% colnames(x = metadata) if (is.null(x = col.name)) { abort(message = "No metadata name provided and could not infer it from metadata object") } object[[col.name]] <- metadata return(object) } #' Internal Cropping Function #' #' @inheritParams Crop #' #' @return ... #' #' @keywords internal #' #' @noRd #' .Crop <- function(object, x = NULL, y = NULL, coords = c('plot','tissue'), ...) { if (is.null(x = x) && is.null(x = y)) { return(object) } compact <- .hasSlot(object = object, name = 'compact') && slot(object = object, name = 'compact') coords <- coords[1L] coords <- match.arg(arg = coords) switch( EXPR = coords, 'plot' = { cx <- 'y' cy <- 'x' }, 'tissue' = { cx <- 'x' cy <- 'y' } ) x <- range(x %||% bbox(obj = object)[cx, , drop = TRUE]) y <- range(y %||% bbox(obj = object)[cy, , drop = TRUE]) idx <- c(max = 1L, min = 2L)[[getOption( x = 'Seurat.coords.short_range', default = Seurat.options$Seurat.coords.short_range )]] if (x[1L] == x[2L]) { x[idx] <- bbox(obj = object)[cx, idx] } if (y[1L] == y[2L]) { y[idx] <- bbox(obj = object)[cy, idx] } args <- list(x, y) names(x = args) <- switch( EXPR = coords, 'plot' = c('y', 'x'), 'tissue' = c('x', 'y') ) args <- args[c('x', 'y')] df <- do.call(what = expand.grid, args = args) df <- df[c(1, 3, 4, 2), ] df$cell <- 'cell' return(Overlay(x = object, y = CreateSegmentation(coords = df, compact = compact))) } #' Test Finiteness of Centroids #' #' Determines if a \code{\link{Centroids}} object should be finite; for #' \code{Centroids}, this means if their \code{nsides} slot is an integer >= 3 #' #' @param x A \code{\link{Centroids}} object #' #' @return \code{TRUE} if the \code{Centroids} are finite; otherwise #' \code{FALSE} #' #' @keywords internal #' #' @noRd #' .FiniteCentroids <- function(x) { return(as.logical(x = length(x = x))) } #' Head and Tail Object Metadata #' #' Internal \code{\link[utils]{head}} and \code{\link[utils]{tail}} definitions #' #' @param x An object #' @param n Number of rows to return #' @inheritDotParams utils::head #' #' @return The first or last \code{n} rows of object metadata #' #' @keywords internal #' #' @noRd #' .head <- function(x, n = 10L, ...) { return(head(x = x[[]], n = n, ...)) } .tail <- function(x, n = 10L, ...) { return(tail(x = x[[]], n = n, ...)) } #' Miscellaneous Data #' #' Internal functions for getting and setting miscellaneous data #' #' @param object An object #' @param slot Name of miscellaneous data to get or set #' @param ... Arguments passed to other methods #' #' @return \code{.Misc}: If \code{slot} is \code{NULL}, all miscellaneous #' data, otherwise the miscellaneous data for \code{slot} #' #' @keywords internal #' #' @noRd #' .Misc <- function(object, slot = NULL, ...) { CheckDots(...) if (is.null(x = slot)) { return(slot(object = object, name = 'misc')) } return(slot(object = object, name = 'misc')[[slot]]) } #' @param value Data to add #' #' @return \code{.Misc<-}: \code{object} with \code{value} added to the #' miscellaneous data slot \code{slot} #' #' @rdname dot-Misc #' #' @noRd #' ".Misc<-" <- function(object, slot, ..., value) { CheckDots(...) if (slot %in% names(x = Misc(object = object))) { warning( "Overwriting miscellanous data for ", slot, call. = FALSE, immediate. = TRUE ) } if (is.list(x = value)) { slot(object = object, name = 'misc')[[slot]] <- c(value) } else { slot(object = object, name = 'misc')[[slot]] <- value } return(object) } .OverBbox <- function(x, y, invert = FALSE, ...) { df <- .BboxDF(x = bbox(obj = y)) df$cell <- 'cell' return(Overlay( x = x, y = CreateSegmentation(coords = df), invert = invert, ... )) } #' Internal Overlay Method #' #' @param x Query spatial object #' @param y Target spatial object #' @param ... Ignored #' #' @return \code{x} with only the components that fall within #' the bounds of \code{y} #' #' @keywords internal #' #' @noRd #' .Overlay <- function(x, y, ...) { idx <- over(x = x, y = y) idx <- idx[!is.na(x = idx)] names(x = idx) <- vapply( X = strsplit(x = names(x = idx), split = '\\.'), FUN = '[[', FUN.VALUE = character(length = 1L), 1L, USE.NAMES = FALSE ) return(x[names(x = idx)]) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SeuratObject/R/command.R0000644000176200001440000002124715075522101014612 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importFrom methods new slot slot<- #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The \code{SeuratCommand} Class #' #' The \code{SeuratCommand} is used for logging commands that are run #' on a \code{Seurat} object; it stores parameters and timestamps #' #' @slot name Command name #' @slot time.stamp Timestamp of when command was tun #' @slot assay.used Optional name of assay used to generate #' \code{SeuratCommand} object #' @slot call.string String of the command call #' @slot params List of parameters used in the command call #' #' @name SeuratCommand-class #' @rdname SeuratCommand-class #' @exportClass SeuratCommand #' #' @family command #' #' @aliases SeuratCommand #' setClass( Class = 'SeuratCommand', slots = c( name = 'character', time.stamp = 'POSIXct', assay.used = 'OptionalCharacter', call.string = 'character', params = 'ANY' ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Log a command #' #' Logs command run, storing the name, timestamp, and argument list. Stores in #' the Seurat object #' #' @param object Name of Seurat object #' @param return.command Return a \code{\link{SeuratCommand}} object instead #' #' @return If \code{return.command}, returns a \code{\link{SeuratCommand}} #' object; otherwise, returns the Seurat object with command stored #' #' @export #' #' @family command #' #' @seealso \code{\link{Command}} #' LogSeuratCommand <- function(object, return.command = FALSE) { time.stamp <- Sys.time() object <- UpdateSlots(object = object) #capture function name which.frame <- sys.nframe() - 1 if (which.frame < 1) { stop("'LogSeuratCommand' cannot be called at the top level", call. = FALSE) } if (as.character(x = sys.calls()[[1]])[1] == "do.call") { call.string <- deparse(expr = sys.calls()[[1]]) command.name <- as.character(x = sys.calls()[[1]])[2] } else { command.name <- as.character(x = deparse(expr = sys.calls()[[which.frame]])) command.name <- gsub( pattern = "\\.Seurat", replacement = "", x = command.name ) call.string <- command.name command.name <- ExtractField( string = command.name, field = 1, delim = "\\(" ) } #capture function arguments argnames <- names(x = formals(fun = sys.function(which = sys.parent(n = 1)))) argnames <- grep( pattern = "object", x = argnames, invert = TRUE, value = TRUE ) argnames <- grep( pattern = "anchorset", x = argnames, invert = TRUE, value = TRUE ) argnames <- grep( pattern = "\\.\\.\\.", x = argnames, invert = TRUE, value = TRUE ) params <- list() p.env <- parent.frame(n = 1) argnames <- intersect(x = argnames, y = ls(name = p.env)) # fill in params list for (arg in argnames) { param_value <- get(x = arg, envir = p.env) if (inherits(x = param_value, what = 'Seurat')) { next } #TODO Institute some check of object size? params[[arg]] <- param_value } # check if function works on the Assay and/or the DimReduc Level assay <- params[["assay"]] reduction <- params[["reduction"]] # Get assay used for command cmd.assay <- assay %||% (reduction %iff% if (inherits(x = reduction, what = 'DimReduc')) { DefaultAssay(object = reduction) } else if (reduction %in% Reductions(object = object)) { DefaultAssay(object = object[[reduction]]) }) if (inherits(x = reduction, what = 'DimReduc')) { reduction <- 'DimReduc' } # rename function name to include Assay/DimReduc info if (length(x = assay) == 1) { command.name <- paste(command.name, assay, reduction, sep = '.') } command.name <- sub( pattern = "[\\.]+$", replacement = "", x = command.name, perl = TRUE ) command.name <- sub(pattern = "\\.\\.", replacement = "\\.", x = command.name, perl = TRUE) # store results seurat.command <- new( Class = 'SeuratCommand', name = command.name, params = params, time.stamp = time.stamp, call.string = call.string, assay.used = cmd.assay ) if (isTRUE(x = return.command)) { return(seurat.command) } object[[command.name]] <- seurat.command return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname DefaultAssay #' @export #' @method DefaultAssay SeuratCommand #' DefaultAssay.SeuratCommand <- function(object, ...) { object <- UpdateSlots(object = object) return(slot(object = object, name = 'assay.used')) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @inherit .DollarNames.Seurat title #' #' @description Autocompletion for \code{$} access on a #' \code{\link{SeuratCommand}} object #' #' @inheritParams utils::.DollarNames #' @param x A \code{\link{SeuratCommand}} object #' #' @return The parameter name matches for \code{pattern} #' #' @importFrom utils .DollarNames #' #' @method .DollarNames SeuratCommand #' @export #' #' @family command #' ".DollarNames.SeuratCommand" <- function(x, pattern = '') { return(.DollarNames(x = slot(object = x, name = "params"), pattern = pattern)) } #' Command Log Parameter Access #' #' Pull parameter values from a \code{\link{SeuratCommand}} object #' #' @inheritParams .DollarNames.SeuratCommand #' @param i A parameter name #' #' @return The value for parameter \code{i} #' #' @method $ SeuratCommand #' @export #' #' @family command #' #' @examples #' cmd <- pbmc_small[["NormalizeData.RNA"]] #' cmd$normalization.method #' "$.SeuratCommand" <- function(x, i) { params <- slot(object = x, name = "params") return(params[[i]]) } #' Command Log Data Access #' #' Access data from a \code{SeuratCommand} object #' #' @inheritParams .DollarNames.SeuratCommand #' @param i The name of a command log slot #' @template param-dots-ignored #' #' @return \code{[}: Slot \code{i} from \code{x} #' #' @method [ SeuratCommand #' @export #' #' @family command #' #' @examples #' cmd <- pbmc_small[["NormalizeData.RNA"]] #' cmd["call.string"] #' "[.SeuratCommand" <- function(x, i, ...) { i <- arg_match(arg = i, values = slotNames(x = x)) return(slot(object = x, name = i)) } #' Coerce a \code{SeuratCommand} to a list #' #' @inheritParams .DollarNames.SeuratCommand #' @param complete Include slots besides just parameters #' (eg. call string, name, timestamp) #' @template param-dots-ignored #' #' @return A list with the parameters and, if \code{complete = TRUE}, #' the call string, name, and timestamp #' #' @method as.list SeuratCommand #' @export #' #' @family command #' #' @examples #' cmd <- pbmc_small[["NormalizeData.RNA"]] #' as.list(cmd) #' as.list(cmd, complete = TRUE) #' as.list.SeuratCommand <- function(x, complete = FALSE, ...) { CheckDots(...) cmd <- slot(object = x, name = 'params') if (isTRUE(x = complete)) { cmd <- append( x = cmd, values = sapply( X = setdiff(x = slotNames(x = x), y = 'params'), FUN = slot, object = x, simplify = FALSE, USE.NAMES = TRUE ), after = 0 ) } for (i in seq_along(along.with = cmd)) { if (is.character(x = cmd[[i]])) { cmd[[i]] <- paste(trimws(x = cmd[[i]]), collapse = ' ') } } return(cmd) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Command Log Overview #' #' Overview of a \code{\link{SeuratCommand}} object #' #' @template return-show #' #' @keywords internal #' #' @concept command #' #' @examples #' cmd <- pbmc_small[["NormalizeData.RNA"]] #' cmd #' setMethod( f = 'show', signature = 'SeuratCommand', definition = function(object) { params <- slot(object = object, name = "params") params <- params[sapply(X = params, FUN = class) != "function"] cat( "Command: ", slot(object = object, name = "call.string"), '\n', "Time: ", as.character(slot(object = object, name = "time.stamp")), '\n', sep = "" ) for (p in seq_len(length.out = length(x = params))) { cat( names(params[p]), ":", params[[p]], "\n" ) } } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SeuratObject/R/molecules.R0000644000176200001440000002567715075522101015177 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @include keymixin.R #' @importFrom future.apply future_lapply #' @importClassesFrom sp CRS SpatialPoints NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The Spatial Molecules Class #' #' @slot .Data A list of \code{\link[sp]{SpatialPoints}} objects #' @slot key The key for the \code{Molecules} #' #' @family segmentation #' @templateVar cls Molecules #' @template seealso-methods #' setClass( Class = 'Molecules', contains = c('KeyMixin', 'list') ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{Molecules} Methods #' #' Methods for \code{\link{Molecules}} objects #' #' @inheritParams Centroids-methods #' @param x,object A \code{\link{Molecules}} object #' @param features A vector of molecule names to keep; if \code{NULL}, defaults #' to all molecules #' #' @name Molecules-methods #' @rdname Molecules-methods #' #' @seealso \code{\link{Molecules-class}} #' #' @family segmentation #' NULL #' @param key A key to set for the molecules #' #' @importFrom sp SpatialPoints #' #' @rdname CreateMolecules #' @method CreateMolecules data.frame #' @export #' CreateMolecules.data.frame <- function(coords, key = '', ...) { idx <- NameIndex(x = coords, names = c('x', 'y', 'gene'), MARGIN = 2L) xy <- idx[c('x', 'y')] coords <- split(x = coords, f = coords[[idx[['gene']]]]) p <- progressor(steps = length(x = coords)) coords <- sapply( X = coords, FUN = function(x) { p() mat <- as.matrix(x = x[, xy]) rownames(x = mat) <- NULL return(SpatialPoints(coords = mat)) }, simplify = FALSE, USE.NAMES = TRUE ) obj <- new( Class = 'Molecules', .Data = coords, key = ifelse(test = nchar(x = key), yes = Key(object = key), no = key) ) validObject(object = obj) return(obj) } #' @rdname CreateMolecules #' @method CreateMolecules Molecules #' @export #' CreateMolecules.Molecules <- function(coords, ...) { return(coords) } #' @rdname CreateMolecules #' @method CreateMolecules NULL #' @export #' CreateMolecules.NULL <- function(coords, ...) { return(NULL) } #' @method Crop Molecules #' @export #' Crop.Molecules <- function( object, x = NULL, y = NULL, coords = c('plot',' tissue'), ... ) { object <- .Crop(object = object, x = x, y = y, coords = coords, ...) for (i in names(x = object)) { if (!nrow(x = slot(object = object[[i]], name = 'coords'))) { object[[i]] <- NULL } } if (!length(x = object)) { return(NULL) } return(object) } #' @template method-features #' #' @rdname Molecules-methods #' @method Features Molecules #' @export #' Features.Molecules <- function(x, ...) { return(names(x = x)) } #' @method FetchData Molecules #' @export #' FetchData.Molecules <- function( object, vars, nmols = NULL, seed = NA_integer_, ... ) { vars <- gsub( pattern = paste0('^', Key(object = object)), replacement = '', x = vars ) coords <- GetTissueCoordinates(object = object, features = vars) if (!is.null(x = nmols)) { if (!is.na(x = seed)) { set.seed(seed = seed) } coords <- lapply( X = unique(x = coords$molecule), FUN = function(m) { df <- coords[coords$molecule == m, , drop = FALSE] if (nrow(x = df) > nmols) { idx <- sample(x = seq_len(length.out = nrow(x = df)), size = nmols) df <- df[idx, , drop = FALSE] } return(df) } ) coords <- do.call(what = 'rbind', args = coords) } return(coords) # return(fortify(model = object, data = vars, ...)) } #' @details \code{GetTissueCoordinates}: Get spatially-resolved #' molecule coordinates #' #' @return \code{GetTissueCoordinates}: A data frame with three columns: #' \itemize{ #' \item \dQuote{\code{x}}: the x-coordinate of a molecule #' \item \dQuote{\code{y}}: the y-coordinate of a molecule #' \item \dQuote{\code{molecule}}: the molecule name #' } #' #' @importFrom sp coordinates #' #' @rdname Molecules-methods #' @method GetTissueCoordinates Molecules #' @export #' GetTissueCoordinates.Molecules <- function(object, features = NULL, ...) { features <- features %||% Features(x = object) coords <- lapply( X = features, FUN = function(f) { fcoords <- object[[f]] if (is.null(x = fcoords)) { return(NULL) } fcoords <- as.data.frame(x = coordinates(obj = fcoords)) rownames(x = fcoords) <- NULL fcoords$molecule <- f return(fcoords) } ) return(do.call(what = 'rbind', args = coords)) } #' @method Simplify Molecules #' @export #' Simplify.Molecules <- function(coords, tol, topologyPreserve = TRUE) { .NotYetImplemented() } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @importFrom stats aggregate #' @rdname aggregate #' @method aggregate Molecules #' @export #' aggregate.Molecules <- function(x, by, drop = TRUE, ...) { if (!inherits(x = by, what = 'SpatialPolygons')) { stop( "Aggregation of molecules works only with spatial polygons", call. = FALSE ) } oob <- 'boundless' cells <- unname(obj = names(x = by)) if (isFALSE(x = drop)) { if (oob %in% cells) { oob <- RandomName(length = 7L) warning( "'boundless' already present in cell names, changing to '", oob, "'", call. = FALSE, immediate. = TRUE ) } cells <- c(cells, oob) } idx <- over(x = x, y = by) m <- Matrix( data = 0, nrow = length(x = idx), ncol = length(x = cells), dimnames = list(Features(x = x), cells), sparse = TRUE ) p <- progressor(along = idx) p(message = "Creating expression matrix", class = 'sticky', amount = 0) for (i in seq_along(along.with = idx)) { x <- idx[[i]] f <- names(x = idx)[i] if (isFALSE(x = drop)) { m[f, oob] <- sum(is.na(x = x)) } x <- sort(x = unname(obj = x[!is.na(x = x)])) x <- rle(x = x) m[f, x$values] <- x$lengths p() } return(m) } #' @details \code{subset}: Subset a \code{Molecules} object to certain molecules #' #' @return \code{subset}: \code{x} subsetted to the features specified #' by \code{features} #' #' @rdname Molecules-methods #' @method subset Molecules #' @export #' subset.Molecules <- function(x, features = NULL, ...) { features <- Features(x = x) %iff% features if (is.null(x = features)) { return(x) } else if (length(x = features) == 1L && is.na(x = features)) { return(CreateMolecules(coords = NULL)) } if (is.numeric(x = features)) { features <- names(x = x)[features] features <- features[!is.na(x = features)] } features <- MatchCells(new = Features(x = x), orig = features, ordered = TRUE) if (!length(x = features)) { warning("None of the requested features found", immediate. = TRUE) return(CreateMolecules(coords = NULL)) } x <- x[features] return(as(object = x, Class = 'Molecules')) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setMethod( f = 'bbox', signature = 'Molecules', definition = function(obj) { bounds <- lapply(X = obj, FUN = bbox) bounds <- do.call(what = 'cbind', args = bounds) bounds <- apply(X = bounds, MARGIN = 1L, FUN = range) rownames(x = bounds) <- c('min', 'max') return(t(x = bounds)) } ) setMethod( f = 'over', signature = c(x = 'Molecules', y = 'SpatialPolygons'), definition = function(x, y, returnList = FALSE, fn = NULL, ...) { f <- Features(x = x) p <- progressor(steps = length(x = f)) out <- future_lapply( X = seq_along(along.with = f), FUN = function(i) { fi <- f[[i]] p() return(over(x = x[[fi]], y = y, returnList = returnList, fn = fn, ...)) } ) names(x = out) <- f return(out) } ) #' @rdname Overlay #' @export #' setMethod( f = 'Overlay', signature = c(x = 'Molecules', y = 'SpatialPolygons'), definition = function(x, y, invert = FALSE, ...) { idx <- over(x = x, y = y) for (f in names(x = idx)) { select <- idx[[f]] select <- select[!is.na(x = select)] cells <- as.integer(x = names(x = select)) if (isTRUE(x = invert)) { cells <- -cells } x[[f]] <- x[[f]][cells] } for (i in names(x = x)) { if (!nrow(x = slot(object = x[[i]], name = 'coords'))) { x[[i]] <- NULL } } if (!length(x = x)) { return(NULL) } validObject(object = x) return(x) } ) #' @template method-show #' #' @rdname Molecules-methods #' setMethod( f = 'show', signature = c(object = 'Molecules'), definition = function(object) { nmols <- length(x = object) molword <- ifelse(test = nmols == 1L, yes = 'molecule', no = 'molecules') cat("Coordinates for", nmols, molword, "\n") hmols <- min(nmols, 10) cat( "First", hmols, paste0(molword, ':'), paste( strwrap(x = paste( head(x = names(x = object), n = hmols), collapse = ', ' )), collapse = '\n ' ), '\n' ) } ) setValidity( Class = 'Molecules', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } else if (!length(x = object)) { return(TRUE) } valid <- NULL # Check names unnamed <- is.null(x = names(x = object)) || length(x = Filter(f = nchar, x = names(x = object))) != length(x = object) if (isTRUE(x = unnamed)) { valid <- c(valid, 'All entries must be named') } # Check SpatialPoints points <- vapply( X = object, FUN = inherits, FUN.VALUE = logical(length = 1L), what = 'SpatialPoints' ) if (!all(points)) { valid <- c(valid, 'All entries must inherit from sp::SpatialPoints') } # Check that coordinates have no rownames rnames <- vapply( X = object, FUN = function(x) { return(is.null(x = rownames(x = slot(object = x, name = 'coords')))) }, FUN.VALUE = logical(length = 1L) ) if (!all(rnames)) { valid <- c(valid, 'All entries must have unnamed coordinates') } return(valid %||% TRUE) } ) SeuratObject/R/generics.R0000644000176200001440000012017015116356172014777 0ustar liggesusers#' @include zzz.R #' NULL #' Assay Class Label #' #' @param object A \code{\link{StdAssay}} object #' #' @return The assay class label for \code{object} #' #' @keywords internal #' #' @export .AssayClass #' .AssayClass <- function(object) { UseMethod(generic = '.AssayClass', object = object) } #' Calculate nCount and nFeature #' #' @template param-dots-method #' @param object An assay-like object #' #' @return A named list with ... #' #' @keywords internal #' #' @export .CalcN #' #' @examples #' calcn <- .CalcN(pbmc_small[["RNA"]]) #' head(as.data.frame(calcn)) #' .CalcN <- function(object, ...) { UseMethod(generic = '.CalcN', object = object) } #' Get the Package that Defines a Class #' #' @param object An object #' #' @return The package that defines the class of \code{object} #' #' @keywords internal #' #' @export .ClassPkg #' #' @examples #' .ClassPkg(pbmc_small) #' .ClassPkg <- function(object) { UseMethod(generic = '.ClassPkg', object = object) } #' Generic Assay Creation #' #' Create an assay object; runs a standardized filtering scheme that #' works regardless of the direction of the data (eg. cells as columns #' and features as rows or vice versa) and creates an assay object based #' on the initialization scheme defined for \code{\link{StdAssay}}-derived #' class \code{type} #' #' @param counts A two-dimensional expression matrix #' @param min.cells Include features detected in at least this many cells; #' will subset the counts matrix as well. To reintroduce excluded features, #' create a new object with a lower cutoff #' @param min.features Include cells where at least this many features #' are detected #' @param cells Vector of cell names #' @param features Vector of feature names #' @param type Type of assay object to create; must be the name of a class #' that's derived from \code{\link{StdAssay}} #' @param ... Extra parameters passed to \code{\link[methods]{new}} for #' assay creation; used to set slots not defined by \code{\link{StdAssay}} #' #' @return An object of class \code{type} with a layer named \code{layer} #' containing the data found in \code{counts} #' #' @keywords internal #' #' @export .CreateStdAssay #' #' @concept assay #' .CreateStdAssay <- function( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = 'Assay5', ... ) { UseMethod(generic = '.CreateStdAssay', object = counts) } #' Disk Loading Function #' #' Generate a function to load a matrix from an on-disk file #' #' @inheritParams .FilePath #' #' @return A one-length character that defines a function to load a matrix from #' a file #' #' @keywords internal #' #' @export .DiskLoad #' .DiskLoad <- function(x) { UseMethod(generic = '.DiskLoad', object = x) } #' Find a File Path #' #' @param x A file-backed object #' #' @return The path to the file that backs \code{x}; if \code{x} is not a #' file-backed object, returns \code{NULL} #' #' @keywords internal #' #' @export .FilePath #' .FilePath <- function(x) { UseMethod(generic = '.FilePath', object = x) } #' Get the Margin of an Object #' #' @param x An object #' #' @return The margin, eg. \code{1} for rows or \code{2} for columns #' #' @keywords internal #' #' @export .MARGIN #' .MARGIN <- function(x, ...) { UseMethod(generic = '.MARGIN', object = x) } #' Add in metadata associated with either cells or features. #' #' Adds additional data to the object. Can be any piece of information #' associated with a cell (examples include read depth, alignment rate, #' experimental batch, or subpopulation identity) or feature (ENSG name, #' variance). To add cell level information, add to the Seurat object. If adding #' feature-level metadata, add to the Assay object (e.g. \code{object[["RNA"]]}) #' #' @param object An object #' @param metadata A vector, list, or data.frame with metadata to add #' @param col.name A name for meta data if not a named list or data.frame #' #' @return \code{object} with metadata added #' #' @rdname AddMetaData #' @export AddMetaData #' #' @aliases SeuratAccess #' #' @concept seurat #' #' @examples #' cluster_letters <- LETTERS[Idents(object = pbmc_small)] #' names(cluster_letters) <- colnames(x = pbmc_small) #' pbmc_small <- AddMetaData( #' object = pbmc_small, #' metadata = cluster_letters, #' col.name = 'letter.idents' #' ) #' head(x = pbmc_small[[]]) #' AddMetaData <- function(object, metadata, col.name = NULL) { UseMethod(generic = 'AddMetaData', object = object) } #' Coerce to a \code{Graph} Object #' #' Convert a \code{\link[base]{matrix}} (or \code{\link[Matrix]{Matrix}}) to #' a \code{\link{Graph}} object #' #' @template param-dots-ignored #' @param x The matrix to convert #' #' @return A \code{\link{Graph}} object #' #' @rdname as.Graph #' @export as.Graph #' #' @family graph #' as.Graph <- function(x, ...) { UseMethod(generic = "as.Graph", object = x) } #' Convert Segmentation Layers #' #' @inheritParams CreateCentroids #' @template param-dots-method #' @param x An object #' #' @return \code{as.Centroids}: A #' \code{\link[SeuratObject:Centroids-class]{Centroids}} object #' #' @export #' #' @concept spatial #' as.Centroids <- function(x, nsides = NULL, radius = NULL, theta = NULL, ...) { UseMethod(generic = "as.Centroids", object = x) } #' Coerce to a \code{Neighbor} Object #' #' Convert objects to \code{\link{Neighbor}} objects #' #' @template param-dots-method #' @param x An object to convert to \code{\link{Neighbor}} #' #' @return A \code{\link{Neighbor}} object #' #' @rdname as.Neighbor #' @export as.Neighbor #' #' @concept neighbor #' as.Neighbor <- function(x, ...) { UseMethod(generic = 'as.Neighbor', object = x) } #' @return \code{as.Segmentation}: A #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object #' #' @rdname as.Centroids #' @export #' as.Segmentation <- function(x, ...) { UseMethod(generic = 'as.Segmentation', object = x) } #' Coerce to a \code{Seurat} Object #' #' Convert objects to Seurat objects #' #' @template param-dots-method #' @param x An object to convert to class \code{Seurat} #' #' @return A \code{\link{Seurat}} object generated from \code{x} #' #' @rdname as.Seurat #' @export as.Seurat #' #' @concept seurat #' as.Seurat <- function(x, ...) { UseMethod(generic = 'as.Seurat', object = x) } #' Cast to Sparse #' #' Convert dense objects to sparse representations #' #' @template param-dots-method #' @param x An object #' #' @return A sparse representation of the input data #' #' @rdname as.sparse #' @export as.sparse #' #' @concept utils #' as.sparse <- function(x, ...) { UseMethod(generic = 'as.sparse', object = x) } #' Query Specific Object Types #' #' List the names of \code{\link{Assay}}, \code{\link{DimReduc}}, #' \code{\link{Graph}}, \code{\link{Neighbor}} objects #' #' @template param-dots-ignored #' @param object A \code{\link{Seurat}} object #' @param slot Name of component object to return #' #' @return If \code{slot} is \code{NULL}, the names of all component objects #' in this \code{Seurat} object. Otherwise, the specific object specified #' #' @rdname ObjectAccess #' #' @export #' #' @concept data-access #' #' @examples #' Assays(pbmc_small) #' Assays <- function(object, ...) { UseMethod(generic = "Assays", object = object) } #' Get, Set, and Query Segmentation Boundaries #' #' @template param-dots-method #' @param object An object #' #' @name Boundaries #' @return \code{Boundaries}: The names of all segmentation boundaries present #' within \code{object} #' #' @rdname Boundaries #' @export #' #' @concept spatial #' Boundaries <- function(object, ...) { UseMethod(generic = 'Boundaries', object = object) } #' Cast Assay Layers #' #' Cast layers in v5 assays to other classes #' #' @param object An object #' @param to Either a class name or a function that takes a layer and returns #' the same layer as a new class #' @param ... If \code{to} is a function, arguments passed to \code{to} #' #' @return \code{object} with the layers cast to class specified by \code{to} #' #' @export #' #' @concept assay5 #' CastAssay <- function(object, to, ...) { UseMethod(generic = 'CastAssay', object = object) } #' Cell and Feature Names #' #' Get the cell and feature names of an object #' #' @template param-dots-method #' @param x An object #' #' @return \code{Cell}: A vector of cell names #' #' @rdname Cells #' @export Cells #' #' @concept data-access #' @family dimnames #' #' @examples #' Cells(x = pbmc_small) #' Cells <- function(x, ...) { UseMethod(generic = 'Cells', object = x) } #' Check Matrix Validity #' #' @template param-dots-method #' @param object A matrix #' @param checks Type of checks to perform, choose one or more from: #' \itemize{ #' \item \dQuote{\code{infinite}}: Emit a warning if any value is infinite #' \item \dQuote{\code{logical}}: Emit a warning if any value is a logical #' \item \dQuote{\code{integer}}: Emit a warning if any value is \emph{not} #' an integer #' \item \dQuote{\code{na}}: Emit a warning if any value is an \code{NA} #' or \code{NaN} #' } #' #' @return Emits warnings for each test and invisibly returns \code{NULL} #' #' @name CheckMatrix #' @rdname CheckMatrix #' #' @keywords internal #' #' @export #' #' @concept utils #' CheckMatrix <- function(object, checks, ...) { UseMethod(generic = 'CheckMatrix', object = object) } #' Get SeuratCommands #' #' Pull information on previously run commands in the Seurat object. #' #' @template param-dots-method #' @param object An object #' #' @return Either a SeuratCommand object or the requested parameter value #' #' @rdname Command #' @export Command #' #' @concept data-access #' Command <- function(object, ...) { UseMethod(generic = 'Command', object = object) } #' Create a \code{\link[SeuratObject:Centroids-class]{Centroids}} Objects #' #' @param coords The coordinates of cell/spot centroids #' @param nsides The number of sides to represent cells/spots; pass #' \code{\link[base]{Inf}} to plot as circles #' @param radius Radius of shapes when plotting #' @param theta Angle to adjust shapes when plotting #' #' @return A \code{\link[SeuratObject:Centroids-class]{Centroids}} object #' #' @export #' #' @concept spatial #' CreateCentroids <- function(coords, nsides, radius, theta) { UseMethod(generic = 'CreateCentroids', object = coords) } #' Create Spatial Coordinates #' #' @template param-dots-method #' @param coords Spatial coordinates #' #' @return A \code{\link{FOV}} object #' #' @export #' #' @concept spatial #' #' @seealso \code{\link{FOV-class}} #' CreateFOV <- function(coords, ...) { UseMethod(generic = 'CreateFOV', object = coords) } #' Create a \code{\link{Molecules}} Object #' #' @template param-dots-method #' @param coords Spatial coordinates for molecules; should be a data frame #' with three columns: #' \itemize{ #' \item \dQuote{\code{x}}: x-coordinates for each molecule #' \item \dQuote{\code{y}}: y-coordinates for each molecule #' \item \dQuote{\code{gene}}: gene name for each molecule #' } #' #' @return A \code{\link{Molecules}} object #' #' @export #' #' @concept spatial #' CreateMolecules <- function(coords, ...) { UseMethod(generic = 'CreateMolecules', object = coords) } #' Create a \code{\link[SeuratObject:Segmentation-class]{Segmentation}} Objects #' #' @param coords The coordinates of cell segmentations #' @param compact Logical indicating whether or not the object should only store segmentation data #' in the \code{sf.data} slot; see \link{Segmentation-class} for details. #' #' @return A \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object #' #' @export #' #' @concept spatial #' CreateSegmentation <- function(coords, compact = FALSE) { UseMethod(generic = 'CreateSegmentation', object = coords) } #' Create a \code{Seurat} object #' #' Create a \code{Seurat} object from raw data #' #' @inheritParams CreateAssayObject #' @template param-dots-method #' @param counts Either a \code{\link[base]{matrix}}-like object with #' unnormalized data with cells as columns and features as rows or an #' \code{\link{Assay}}-derived object #' @param project \link{Project} name for the \code{Seurat} object #' @param assay Name of the initial assay #' @param names.field For the initial identity class for each cell, choose this #' field from the cell's name. E.g. If your cells are named as #' BARCODE_CLUSTER_CELLTYPE in the input matrix, set \code{names.field} to 3 to #' set the initial identities to CELLTYPE. #' @param names.delim For the initial identity class for each cell, choose this #' delimiter from the cell's column name. E.g. If your cells are named as #' BARCODE-CLUSTER-CELLTYPE, set this to \dQuote{-} to separate the cell name #' into its component parts for picking the relevant field. #' @param meta.data Additional cell-level metadata to add to the Seurat object. #' Should be a \code{\link[base]{data.frame}} where the rows are cell names and #' the columns are additional metadata fields. Row names in the metadata need #' to match the column names of the counts matrix. #' #' @note In previous versions (<3.0), this function also accepted a parameter to #' set the expression threshold for a \sQuote{detected} feature (gene). This #' functionality has been removed to simplify the initialization #' process/assumptions. If you would still like to impose this threshold for #' your particular dataset, simply filter the input expression matrix before #' calling this function. #' #' @return A \code{\link{Seurat}} object #' #' @rdname CreateSeuratObject #' @export #' #' @concept seurat #' #' @examples #' \dontrun{ #' pbmc_raw <- read.table( #' file = system.file('extdata', 'pbmc_raw.txt', package = 'Seurat'), #' as.is = TRUE #' ) #' pbmc_small <- CreateSeuratObject(counts = pbmc_raw) #' pbmc_small #' } #' CreateSeuratObject <- function( counts, assay = 'RNA', names.field = 1, names.delim = '_', meta.data = NULL, project = 'CreateSeuratObject', ... ) { UseMethod(generic = 'CreateSeuratObject', object = counts) } #' Crop Coordinates #' #' @template param-dots-method #' @param object An object #' @param x,y Range to crop x/y limits to; if \code{NULL}, uses full range of #' \code{x}/\code{y} #' @param coords Coordinate system to execute crop; choose from: #' \itemize{ #' \item \dQuote{\code{plot}}: Coordinates as shown when plotting #' \item \dQuote{\code{tissue}}: Coordinates from #' \code{\link{GetTissueCoordinates}} #' } #' #' @return \code{object} cropped to the region specified by \code{x} #' and \code{y} #' #' @export #' #' @concept spatial #' Crop <- function(object, x = NULL, y = NULL, coords = c('plot', 'tissue'), ...) { UseMethod(generic = 'Crop', object = object) } #' Default Assay #' #' Get and set the default assay #' #' @template param-dots-method #' @param object An object #' #' @return \code{DefaultAssay}: The name of the default assay #' #' @rdname DefaultAssay #' @export DefaultAssay #' #' @concept data-access #' DefaultAssay <- function(object, ...) { UseMethod(generic = 'DefaultAssay', object = object) } #' @param value Name of assay to set as default #' #' @return \code{DefaultAssay<-}: An object with the default assay updated #' #' @rdname DefaultAssay #' @export DefaultAssay<- #' "DefaultAssay<-" <- function(object, ..., value) { UseMethod(generic = 'DefaultAssay<-', object = object) } #' @return \code{DefaultBoundary}: The name of the default #' segmentation boundary #' #' @rdname Boundaries #' #' @export #' DefaultBoundary <- function(object) { UseMethod(generic = 'DefaultBoundary', object = object) } #' @param value The name of a segmentation boundary to set as default #' #' @return \code{DefaultBoundary<-}: \code{object} with the default #' segmentation boundary set to \code{value} #' #' @rdname Boundaries #' #' @export #' "DefaultBoundary<-" <- function(object, ..., value) { UseMethod(generic = 'DefaultBoundary<-', object = object) } #' Get and Set the Default FOV #' #' @template param-dots-method #' @param object A \code{\link{Seurat}} Object #' #' @return \code{DefaultFOV}: The name of the default \code{\link{FOV}} #' #' @name DefaultFOV #' @rdname DefaultFOV #' #' @export #' #' @concept spatial #' DefaultFOV <- function(object, ...) { UseMethod(generic = 'DefaultFOV', object = object) } #' @param value The name of the \code{\link{FOV}} to set as the default #' #' @return \code{DefaultFOV<-}: \code{object} with the default FOV set #' to \code{value} #' #' @rdname DefaultFOV #' #' @export #' "DefaultFOV<-" <- function(object, ..., value) { UseMethod(generic = 'DefaultFOV<-', object = object) } #' Default Layer #' #' Get and set the default layer #' #' @template param-dots-method #' @param object An object #' #' @return \code{DefaultLayer}: The name of the default layer #' #' @rdname DefaultLayer #' @export DefaultLayer #' #' @concept assay5 #' DefaultLayer <- function(object, ...) { UseMethod(generic = 'DefaultLayer', object = object) } #' @param value Name of layer to set as default #' #' @return \code{DefaultLayer<-}: An object with the default layer updated #' #' @rdname DefaultLayer #' @export DefaultLayer<- #' "DefaultLayer<-" <- function(object, ..., value) { UseMethod(generic = 'DefaultLayer<-', object = object) } #' Get the Neighbor nearest neighbors distance matrix #' #' @template param-dots-method #' @param object An object #' #' @return The distance matrix #' #' @rdname Distances #' @export Distances #' #' @concept data-access #' Distances <- function(object, ...) { UseMethod(generic = 'Distances', object = object) } #' Get Cell Embeddings #' #' @template param-dots-method #' @param object An object #' #' @return The embeddings matrix #' #' @rdname Embeddings #' @export Embeddings #' #' @concept data-access #' Embeddings <- function(object, ...) { UseMethod(generic = 'Embeddings', object = object) } #' Access cellular data #' #' Retrieves data (feature expression, PCA scores, metrics, etc.) for a set #' of cells in a Seurat object #' #' @template param-dots-method #' @param object An object #' #' @export FetchData #' #' @concept data-access #' FetchData <- function(object, ...) { UseMethod(generic = 'FetchData', object = object) } #' @return \code{Features}: A vector of feature names #' #' @rdname Cells #' @export Features #' Features <- function(x, ...) { UseMethod(generic = 'Features', object = x) } #' Get and Set Assay Data #' #' General accessor and setter functions for \code{\link{Assay}} objects. #' \code{GetAssayData} can be used to pull information from any of the #' expression matrices (eg. \dQuote{counts}, \dQuote{data}, or #' \dQuote{scale.data}). \code{SetAssayData} can be used to replace one of these #' expression matrices #' #' @template param-dots-method #' @param object An object #' @param layer Name of layer to get or set #' @param slot \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} Specific assay data to get or set #' #' @return \code{GetAssayData}: returns the specified assay data #' #' @template lifecycle-superseded #' #' @section Lifecycle: #' #' \code{GetAssayData} and \code{SetAssayData} have been superseded. To fetch #' expression matrices, use \code{\link{LayerData}}; to set expression data, #' use \code{\link{LayerData<-}} #' #' @name AssayData #' @rdname AssayData #' @export GetAssayData #' #' @order 1 #' #' @concept data-access #' GetAssayData <- function(object, ...) { UseMethod(generic = 'GetAssayData', object = object) } #' Get image data #' #' @template param-dots-method #' @param object An object #' @param mode How to return the image; should accept one of \dQuote{grob}, #' \dQuote{raster}, \dQuote{plotly}, or \dQuote{raw} #' #' @return Image data, varying depending on the value of \code{mode}: #' \describe{ #' \item{\dQuote{grob}}{ #' An object representing image data inheriting from \code{grob} objects #' (eg. \code{rastergrob}) #' } #' \item{\dQuote{raster}}{An object of class \code{raster}} #' \item{\dQuote{plotly}}{ #' A list with image data suitable for Plotly rendering, see #' \code{\link[plotly:layout]{plotly::layout}} for more details #' } #' \item{\dQuote{raw}}{The raw image data as stored in the object} #' } #' #' @seealso \code{\link[plotly]{layout}} #' #' @rdname GetImage #' @export GetImage #' #' @concept data-access #' GetImage <- function(object, mode = c('grob', 'raster', 'plotly', 'raw'), ...) { mode <- mode[1] mode <- match.arg(arg = mode) UseMethod(generic = 'GetImage', object = object) } #' Get tissue coordinates #' #' Retrieve tissue coordinates from spatial objects. #' #' Spatial classes may have specific implementations; #' refer to those documentation pages for more details. #' #' @template param-dots-method #' @param object An object #' #' @return A data frame with tissue coordinates #' #' @rdname GetTissueCoordinates #' @export GetTissueCoordinates #' #' @concept data-access #' GetTissueCoordinates <- function(object, ...) { UseMethod(generic = 'GetTissueCoordinates', object = object) } #' Highly Variable Features #' #' Get and set variable feature information for an \code{\link{Assay}} object. #' \code{HVFInfo} and \code{VariableFeatures} utilize generally variable #' features, while \code{SVFInfo} and \code{SpatiallyVariableFeatures} are #' restricted to spatially variable features #' #' @template param-dots-method #' @param object An object #' @param method Which method to pull. For \code{HVFInfo} and #' \code{VariableFeatures}, choose one from one of the #' following: #' \itemize{ #' \item \dQuote{vst} #' \item \dQuote{sctransform} or \dQuote{sct} #' \item \dQuote{mean.var.plot}, \dQuote{dispersion}, \dQuote{mvp}, or #' \dQuote{disp} #' } #' For \code{SVFInfo} and \code{SpatiallyVariableFeatures}, choose from: #' \itemize{ #' \item \dQuote{markvariogram} #' \item \dQuote{moransi} #' } #' @param status Add variable status to the resulting data frame #' @param selection.method \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} #' #' @return \code{HVFInfo}: A data frame with feature means, dispersion, and #' scaled dispersion #' #' @rdname VariableFeatures #' @export HVFInfo #' #' @order 1 #' #' @concept data-access #' HVFInfo <- function(object, method, status = FALSE, ...) { UseMethod(generic = 'HVFInfo', object = object) } #' Get, set, and manipulate an object's identity classes #' #' @param x,object An object #' @param ... Arguments passed to other methods; for \code{RenameIdents}: named #' arguments as \code{old.ident = new.ident}; for \code{ReorderIdent}: arguments #' passed on to \code{\link{FetchData}} #' #' @return \code{Idents}: The cell identities #' #' @rdname Idents #' @export Idents #' #' @concept seurat #' #' @examples #' # Get cell identity classes #' Idents(pbmc_small) #' Idents <- function(object, ... ) { UseMethod(generic = 'Idents', object = object) } #' @param value The name of the identities to pull from object metadata or the #' identities themselves #' #' @return \code{Idents<-}: \code{object} with the cell identities changed #' #' @rdname Idents #' @export Idents<- #' #' @examples #' # Set cell identity classes #' # Can be used to set identities for specific cells to a new level #' Idents(pbmc_small, cells = 1:4) <- 'a' #' head(Idents(pbmc_small)) #' #' # Can also set idents from a value in object metadata #' colnames(pbmc_small[[]]) #' Idents(pbmc_small) <- 'RNA_snn_res.1' #' levels(pbmc_small) #' "Idents<-" <- function(object, ..., value) { UseMethod(generic = 'Idents<-', object = object) } #' Get Neighbor algorithm index #' #' @template param-dots-method #' @param object An object #' #' @return Returns the value in the alg.idx slot of the Neighbor object #' #' @rdname NNIndex #' @export Index #' #' @concept data-access #' Index <- function(object, ...) { UseMethod(generic = "Index", object = object) } #' @param value The index to store #' #' @return \code{Idents<-}: A Neighbor object with the index stored #' #' @rdname NNIndex #' @export Index<- #' "Index<-" <- function(object, ..., value) { UseMethod(generic = 'Index<-', object = object) } #' Get Neighbor nearest neighbor index matrices #' #' @template param-dots-method #' @param object An object #' #' @return A matrix with the nearest neighbor indices #' #' @rdname Indices #' @export Indices #' #' @concept data-access #' Indices <- function(object, ...) { UseMethod(generic = "Indices", object = object) } #' Is an object global/persistent? #' #' Typically, when removing \code{Assay} objects from an \code{Seurat} object, #' all associated objects (eg. \code{DimReduc}, \code{Graph}, and #' \code{SeuratCommand} objects) #' are removed as well. If an associated object is marked as global/persistent, #' the associated object will remain even if its original assay was deleted #' #' @template param-dots-method #' @param object An object #' #' @return \code{TRUE} if the object is global/persistent otherwise \code{FALSE} #' #' @rdname IsGlobal #' @export IsGlobal #' #' @concept data-access #' #' @examples #' IsGlobal(pbmc_small[['pca']]) #' IsGlobal <- function(object, ...) { UseMethod(generic = 'IsGlobal', object = object) } #' Check if a matrix is empty #' #' Takes a matrix and asks if it's empty (either 0x0 or 1x1 with a value of NA) #' #' @param x A matrix #' #' @return Whether or not \code{x} is empty #' #' @rdname IsMatrixEmpty #' @export IsMatrixEmpty #' #' @concept utils #' #' @seealso \code{\link{EmptyMatrix}()} #' #' @examples #' IsMatrixEmpty(new("matrix")) #' IsMatrixEmpty(matrix()) #' IsMatrixEmpty(matrix(1:3)) #' IsMatrixEmpty <- function(x) { UseMethod(generic = 'IsMatrixEmpty', object = x) } #' Split and Join Layers Together #' #' @param object An object #' @template param-dots-method #' #' @return \code{object} with the layers specified joined #' #' @rdname SplitLayers #' @export JoinLayers #' #' @concept assay5 #' JoinLayers <- function(object, ...) { UseMethod(generic = 'JoinLayers', object = object) } #' Get and set JackStraw information #' #' @template param-dots-method #' @param object An object #' #' @return \code{JS}: either a \code{\link{JackStrawData}} object or the #' specified jackstraw data #' #' @rdname JS #' @export JS #' #' @concept jackstraw #' JS <- function(object, ...) { UseMethod(generic = 'JS', object = object) } #' @param value JackStraw information #' #' @return \code{JS<-}: \code{object} with the update jackstraw information #' #' @rdname JS #' @export JS<- #' "JS<-" <- function(object, ..., value) { UseMethod(generic = 'JS<-', object = object) } #' Get and set object keys #' #' @template param-dots-method #' @param object An object #' #' @return \code{Key}: the object key #' #' @rdname Key #' @export Key #' #' @concept data-access #' Key <- function(object, ...) { UseMethod(generic = 'Key', object = object) } #' @return \code{Keys}: a named vector of keys of sub-objects #' #' @rdname Key #' @export #' Keys <- function(object, ...) { UseMethod(generic = 'Keys', object = object) } #' @param value Key value #' #' @return \code{Key<-}: \code{object} with an updated key #' #' @rdname Key #' @export Key<- #' #' @concept data-access #' "Key<-" <- function(object, ..., value) { UseMethod(generic = 'Key<-', object = object) } #' Query and Manipulate Assay Layers #' #' @template param-dots-method #' @param object An object #' @param layer Name of layer to fetch or set #' @param slot \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} #' #' @return \code{LayerData}: the layer data for \code{layer} from \code{object} #' #' @rdname Layers #' @export LayerData #' LayerData <- function(object, layer, ...) { UseMethod(generic = 'LayerData', object = object) } #' @param value New two-dimensional data to be added as a layer #' #' @return \code{Layer<-}: \code{object} with \code{value} added as a layer #' named \code{layer} #' #' @rdname Layers #' @export LayerData<- #' "LayerData<-" <- function(object, layer, ..., value) { UseMethod(generic = 'LayerData<-', object = object) } #' @return \code{Layers}: the names of the layers present in \code{object} #' #' @rdname Layers #' @export Layers #' #' @concept data-access #' Layers <- function(object, ...) { UseMethod(generic = 'Layers', object = object) } #' Get and set feature loadings #' #' @template param-dots-method #' @param object An object #' #' @return \code{Loadings}: the feature loadings for \code{object} #' #' @rdname Loadings #' @export Loadings #' #' @concept data-access #' Loadings <- function(object, ...) { UseMethod(generic = 'Loadings', object = object) } #' @param value Feature loadings to add #' #' @return \code{Loadings<-}: \code{object} with the updated loadings #' #' @rdname Loadings #' @export Loadings<- #' "Loadings<-" <- function(object, ..., value) { UseMethod(generic = 'Loadings<-', object = object) } #' Match Cells #' #' @param new A vector of new cells #' @param orig A vector of existing cells #' @param ordered Sort the result to the same order as \code{orig} #' #' @return A numeric vector with new cells in order of the original cells; if #' no match can be found, returns \code{NULL} #' #' @keywords internal #' #' @export #' #' @concept utils #' MatchCells <- function(new, orig, ordered = FALSE) { if (!is.character(x = orig)) { stop("'orig' must be a character vector") } UseMethod(generic = 'MatchCells', object = new) } #' Get and set miscellaneous data #' #' @param object An object #' @param ... Arguments passed to other methods #' #' @return Miscellaneous data #' #' @rdname Misc #' @export Misc #' #' @concept data-access #' Misc <- function(object, ...) { UseMethod(generic = 'Misc', object = object) } #' @param value Data to add #' #' @return An object with miscellaneous data added #' #' @rdname Misc #' @export Misc<- #' "Misc<-" <- function(object, ..., value) { UseMethod(generic = 'Misc<-', object = object) } #' @return \code{Molecules}: The names of all molecule sets present within #' \code{object} #' #' @rdname Boundaries #' @export #' Molecules <- function(object, ...) { UseMethod(generic = 'Molecules', object = object) } #' Overlay \code{Spatial} Objects Over One Another #' #' Create an overlay of some query spatial object (\code{x}) against some #' target object (\code{y}). Basically, find all components of a query that #' fall within the bounds of a target spatial region #' #' @template param-dots-ignored #' @param x Query \code{Spatial} object #' @param y Target \code{Spatial} object #' @param invert Invert the overlay and return only the components of \code{x} #' that fall \emph{outside} the bounds of \code{y} #' #' @return \code{x} with only the components that fall within the #' bounds of \code{y} #' #' @templateVar pkg sf #' @template note-reqdpkg #' #' @export #' #' @concept spatial #' setGeneric( name = 'Overlay', def = function(x, y, invert = FALSE, ...) { standardGeneric(f = 'Overlay') }, signature = c('x', 'y') ) #' Get and set project information #' #' @template param-dots-method #' @param object An object #' #' @return Project information #' #' @rdname Project #' @export Project #' #' @concept seurat #' Project <- function(object, ...) { UseMethod(generic = 'Project', object = object) } #' @param value Project information to set #' #' @return An object with project information added #' #' @rdname Project #' @export Project<- #' "Project<-" <- function(object, ..., value) { UseMethod(generic = 'Project<-', object = object) } #' Get the spot radius from an image #' #' @param object An image object #' @param ... Arguments passed to other methods #' #' @return The radius size #' #' @rdname Radius #' @export Radius #' #' @concept spatialimage #' Radius <- function(object, ...) { UseMethod(generic = 'Radius', object = object) } #' Rename cells #' #' Change the cell names in all the different parts of an object. Can be useful #' before combining multiple objects. #' #' @template param-dots-method #' @param object An object #' #' @return An object with new cell names #' #' @rdname RenameCells #' @export RenameCells #' #' @concept seurat #' RenameCells <- function(object, ...) { UseMethod(generic = 'RenameCells', object = object) } #' @return \code{RenameIdents}: An object with selected identity classes renamed #' #' @rdname Idents #' @export RenameIdents #' @aliases RenameIdent #' #' @examples #' # Rename cell identity classes #' # Can provide an arbitrary amount of idents to rename #' levels(pbmc_small) #' pbmc_small <- RenameIdents(pbmc_small, '0' = 'A', '2' = 'C') #' levels(pbmc_small) #' RenameIdents <- function(object, ...) { UseMethod(generic = 'RenameIdents', object = object) } #' @param var Feature or variable to order on #' #' @return \code{ReorderIdent}: An object with #' #' @rdname Idents #' @export ReorderIdent #' @aliases ReorderIdent #' #' @examples #' \dontrun{ #' head(Idents(pbmc_small)) #' pbmc_small <- ReorderIdent(pbmc_small, var = 'PC_1') #' head(Idents(pbmc_small)) #' } #' ReorderIdent <- function(object, var, ...) { UseMethod(generic = 'ReorderIdent', object = object) } #' S4/List Conversion #' #' Convert S4 objects to lists and vice versa. Useful for declassing an S4 #' object while keeping track of it's class using attributes (see section #' \strong{S4 Class Definition Attributes} below for more details). Both #' \code{ListToS4} and \code{S4ToList} are recursive functions, affecting #' all lists/S4 objects contained as sub-lists/sub-objects #' #' @param object An S4 object #' @param x A list with an S4 class definition #' (\dQuote{\code{classDef}}) attribute #' #' @return \code{S4ToList}: A list with an S4 class definition attribute #' #' @section S4 Class Definition Attributes: #' S4 classes are scoped to the package and class name. In order to properly #' track which class a list is generated from in order to build a new one, #' these function use an \code{\link[base:attr]{attribute}} to denote the #' class name and package of origin. This attribute is stored as 1-length #' character vector named \dQuote{\code{classDef}} and takes the form #' of \dQuote{\code{package:class}} #' #' @name s4list #' @rdname s4list #' #' @keywords internal #' #' @export #' #' @concept utils #' @family s4list #' #' @examples #' # Turn an S4 object into a list #' pbmc.list <- S4ToList(pbmc_small) #' class(pbmc.list) #' attributes(pbmc.list) #' #' str(pbmc.list$reductions) #' S4ToList <- function(object) { if (!(isS4(object) || is_bare_list(x = object))) { return(object) } UseMethod(generic = 'S4ToList', object = object) } #' @param new.data New assay data to add #' #' @return \code{SetAssayData}: \code{object} with the assay data set #' #' @rdname AssayData #' @export SetAssayData #' #' @order 2 #' SetAssayData <- function(object, layer, new.data, slot = deprecated(), ...) { UseMethod(generic = 'SetAssayData', object = object) } #' @return \code{SetIdent}: An object with new identity classes set #' #' @rdname Idents #' @export SetIdent #' #' @examples #' # Set cell identity classes using SetIdent #' cells.use <- WhichCells(pbmc_small, idents = '1') #' pbmc_small <- SetIdent(pbmc_small, cells = cells.use, value = 'B') #' SetIdent <- function(object, ...) { UseMethod(generic = 'SetIdent', object = object) } #' Simplify Geometry #' #' @param coords ... #' #' @return A simplified version of \code{coords} #' #' @export #' #' @concept spatial #' Simplify <- function(coords, tol, topologyPreserve = TRUE) { UseMethod(generic = 'Simplify', object = coords) } #' @return \code{SpatiallyVariableFeatures}: a character vector of the spatially #' variable features #' #' @rdname VariableFeatures #' @export SpatiallyVariableFeatures #' #' @order 5 #' SpatiallyVariableFeatures <- function(object, method, ...) { UseMethod(generic = 'SpatiallyVariableFeatures', object = object) } # @rdname SplitLayers # @export SplitLayers # # @order 1 # SplitLayers <- function(object, ...) { UseMethod(generic = 'SplitLayers', object = object) } #' @return \code{StashIdent}: An object with the identities stashed #' #' @rdname Idents #' @export StashIdent #' #' @examples #' head(pbmc_small[[]]) #' pbmc_small <- StashIdent(pbmc_small, save.name = 'idents') #' head(pbmc_small[[]]) #' StashIdent <- function(object, save.name, ...) { UseMethod(generic = 'StashIdent', object = object) } #' Get the standard deviations for an object #' #' @template param-dots-method #' @param object An object #' #' @return The standard deviations #' #' @rdname Stdev #' @export Stdev #' #' @concept data-access #' Stdev <- function(object, ...) { UseMethod(generic = 'Stdev', object = object) } #' Stitch Matrices Together #' #' @template param-dots-method #' @param x A matrix #' @param y One or more matrices of the same class or coercible to the #' same class as \code{x} #' @param rowmap,colmap \code{\link{LogMap}s} describing the row and cell #' membership of each matrix; the \code{LogMap} entries are assumed to be in #' the order of \code{c(x, y)} #' #' @return A single matrix of type \code{class(x)} consisting of all values #' in component matrices #' #' @export #' #' @concept utils #' StitchMatrix <- function(x, y, rowmap, colmap, ...) { if (!inherits(x = rowmap, what = 'LogMap')) { abort(message = "'rowmap' must be a 'LogMap'") } else if (!inherits(x = colmap, what = 'LogMap')) { abort(message = "'colmap' must be a 'LogMap'") } UseMethod(generic = 'StitchMatrix', object = x) } #' @return \code{SVFInfo}: a data frame with the spatially variable features #' #' @rdname VariableFeatures #' @export SVFInfo #' #' @order 4 #' SVFInfo <- function(object, method, status, ...) { UseMethod(generic = 'SVFInfo', object = object) } #' Get the offset angle #' #' @param object An object #' #' @rdname Theta #' @export #' #' @concept spatial #' Theta <- function(object) { UseMethod(generic = 'Theta', object = object) } #' Get and Set Additional Tool Data #' #' Use \code{Tool} to get tool data. If no additional arguments are provided, #' will return a vector with the names of tools in the object. #' #' @template param-dots-method #' @param object An object #' #' @return If no additional arguments, returns the names of the tools in the #' object; otherwise returns the data placed by the tool requested #' #'@note For developers: set tool data using \code{Tool<-}. \code{Tool<-} will #'automatically set the name of the tool to the function that called #'\code{Tool<-}, so each function gets one entry in the tools list and cannot #'overwrite another function's entry. The automatic naming will also remove any #'method identifiers (eg. \code{RunPCA.Seurat} will become \code{RunPCA}); #'please plan accordingly #' #' @rdname Tool #' @export Tool #' #' @aliases Tools #' #' @concept data-access #' #' @examples #' # Example function that adds unstructured data to tools #' MyTool <- function(object) { #' sample.tool.output <- matrix(rnorm(n = 16), nrow = 4) #' # Note: `Tool<-` must be called from within a function #' # and the name of the tool will be generated from the function name #' Tool(object) <- sample.tool.output #' return(object) #' } #' #' # Run our tool #' set.seed(42L) #' pbmc_small <- MyTool(pbmc_small) #' #' # Get a list of tools run #' Tool(pbmc_small) #' #' # Access specific tool data #' Tool(pbmc_small, slot = "MyTool") #' Tool <- function(object, ...) { UseMethod(generic = 'Tool', object = object) } #' @param value Information to be added to tool list #' #' @rdname Tool #' @export Tool<- #' "Tool<-" <- function(object, ..., value) { UseMethod(generic = 'Tool<-', object = object) } #' @return \code{VariableFeatures}: a vector of the variable features #' #' @rdname VariableFeatures #' @export VariableFeatures #' #' @order 2 #' VariableFeatures <- function(object, method = NULL, ...) { UseMethod(generic = 'VariableFeatures', object = object) } #' @param value A character vector of variable features #' #' @order 3 #' #' @rdname VariableFeatures #' @export VariableFeatures<- #' "VariableFeatures<-" <- function(object, ..., value) { UseMethod(generic = 'VariableFeatures<-', object = object) } #' Get Version Information #' #' @template param-dots-method #' @param object An object #' #' @rdname Version #' @export Version #' #' @concept data-access #' #' @examples #' Version(pbmc_small) #' Version <- function(object, ...) { UseMethod(generic = "Version", object = object) } #' Identify cells matching certain criteria #' #' Returns a list of cells that match a particular set of criteria such as #' identity class, high/low values for particular PCs, etc. #' #' @template param-dots-method #' @param object An object #' #' @return A vector of cell names #' #' @rdname WhichCells #' @export WhichCells #' #' @concept data-access #' #' @seealso \code{\link{FetchData}} #' #' @examples #' WhichCells(pbmc_small, idents = 2) #' WhichCells(pbmc_small, expression = MS4A1 > 3) #' levels(pbmc_small) #' WhichCells(pbmc_small, idents = c(1, 2), invert = TRUE) #' WhichCells <- function(object, ...) { UseMethod(generic = 'WhichCells', object = object) } SeuratObject/R/logmap.R0000644000176200001440000004134415114353666014467 0ustar liggesusers#' @include zzz.R #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' A Logical Map #' #' A simple container for storing mappings of values using logical matrices. #' Keeps track of which values (rows) are present in which observations #' (columns). \code{LogMap} objects can be created with \code{LogMap()}; #' queries can be performed with \code{[[} and observations can be added #' or removed with \code{[[<-} #' #' @slot .Data A logical matrix with at least one row #' #' @exportClass LogMap #' #' @family logmap #' setClass( Class = 'LogMap', contains = 'matrix' ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname LogMap-class #' #' @param y A character vector #' #' @return \code{LogMap}: A new \code{LogMap} object with zero columns and #' \code{length(x = x)} rows; rownames are set to \code{x} #' #' @export #' #' @order 1 #' #' @examples #' # Create a LogMap #' map <- LogMap(letters[1:10]) #' map #' #' # Get the names of values in the LogMap #' map[[NULL]] #' rownames(map) #' #' # Add an observation to the LogMap #' map[['obs']] <- c(1, 3, 7) #' map[['entry']] <- c(2, 7, 10) #' map #' #' # Get the names of observations in the LogMap #' colnames(map) #' #' # Fetch an observation from the LogMap #' map[['obs']] #' #' # Get the full logical matrix #' map[[]] #' #' # Remove an observation from the LogMap #' map[['obs']] <- NULL #' map[['entry']] <- NULL #' map #' LogMap <- function(y) { if (!is.character(x = y)) { y <- as.character(x = y) } return(new( Class = 'LogMap', .Data = matrix(nrow = length(x = y), ncol = 0, dimnames = list(y, NULL)) )) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Coerce Logical Maps to Matrices #' #' Coerce a logical map to a matrix; this removes all #' \link[=LogMap]{logical map} class capabilities from #' the object and returns a base-R matrix object #' #' @param x A \code{\link{LogMap}} object #' @template param-dots-ignored #' #' @return A base-R matrix created from \code{x} #' #' @method as.matrix LogMap #' @export #' #' @family logmap #' #' @examples #' map <- LogMap(letters[1:10]) #' map[['obs']] <- c(1, 3, 7) #' mat <- as.matrix(map) #' mat #' class(mat) #' as.matrix.LogMap <- function(x, ...) { return(as(object = x, Class = 'matrix')) } #' Drop Unused Logical Map Values #' #' Remove any unused values from a \link[=LogMap]{logical map} #' #' @template param-dots-ignored #' @param x A \code{LogMap} object #' #' @return \code{x} with values not present in any #' observation removed #' #' @method droplevels LogMap #' @export #' #' @family logmap #' #' @examples #' map <- LogMap(letters[1:10]) #' map[['obs']] <- c(1, 3, 7) #' map[['entry']] <- c(2, 7, 10) #' #' # Remove unused values #' map <- droplevels(map) #' map #' map[[]] #' droplevels.LogMap <- function(x, ...) { fidx <- which(x = apply( X = x, MARGIN = 1L, FUN = function(row) { return(all(vapply( X = row, FUN = isFALSE, FUN.VALUE = logical(length = 1L) ))) } )) if (length(x = fidx)) { x <- as(object = x[-fidx, , drop = FALSE], Class = 'LogMap') } validObject(object = x) return(x) } #' Find Common Logical Map Values #' #' Identify values in a \link[=LogMap]{logical map} that are #' common to every observation #' #' @inheritParams droplevels.LogMap #' @param y Ignored #' #' @return The values of \code{x} that are present in \strong{every} observation #' #' @method intersect LogMap #' @export #' #' @family logmap #' #' @examples #' map <- LogMap(letters[1:10]) #' map[['obs']] <- c(1, 3, 7) #' map[['entry']] <- c(2, 7, 10) #' #' # Identify values that are present in every observation #' intersect(map) #' intersect.LogMap <- function(x, y = missing_arg(), ...) { if (!is_missing(x = y)) { abort(message = "'y' must not be provided") } idx <- which(x = apply(X = x, MARGIN = 1L, FUN = all)) return(rownames(x = x)[idx]) } #' Find Observations by Value #' #' Identify the observations that contain a specific #' value in a \link[=LogMap]{logical map} #' #' @template param-dots-ignored #' @param object A \code{\link{LogMap}} object #' @param values A vector of values to find observations for #' @param select Observation selection method; choose from: #' \itemize{ #' \item \dQuote{\code{first}}: the first observation the value is found in #' \item \dQuote{\code{last}}: the last observation the value is found in #' \item \dQuote{\code{common}}: the first most-common observation the value #' is found in; most-common is determined by the observation that contains #' the most of the values requested #' \item \dQuote{\code{all}}: all observations the value is found in #' } #' @param simplify Simplify the resulting list to a vector #' #' @return \code{labels}: A list, or vector if \code{simplify} is \code{TRUE}, #' of all values and the observations they're found in, according #' to the value of \code{select} #' #' @method labels LogMap #' @export #' #' @family logmap #' #' @examples #' map <- LogMap(letters[1:10]) #' map[['obs']] <- c(1, 3, 7) #' map[['entry']] <- c(2, 7, 10) #' #' # Find observations for a set of values #' labels(map, c('a', 'b', 'g')) #' labels.LogMap <- function( object, values, select = c('first', 'last', 'common', 'all'), simplify = TRUE, ... ) { select <- select[1L] select <- match.arg(arg = select) values <- intersect(x = values, y = rownames(x = object)) mat <- as.matrix(object) cols <- colnames(object) idx <- match(values, rownames(object)) obs <- vector("list", length(values)) names(obs) <- values for (i in seq_along(idx)) { id <- idx[i] vals <- cols[mat[id, , drop = FALSE]] if (length(vals) > 0) { obs[[i]] <- vals } } obs <- Filter(f = length, x = obs) obs <- switch( EXPR = select, 'first' = lapply(X = obs, FUN = '[[', 1L), 'last' = lapply( X = obs, FUN = function(x) { return(x[[length(x = x)]]) } ), common = { counts <- table(unlist(x = obs)) tmp <- obs obs <- vector(mode = 'character', length = length(x = tmp)) names(x = obs) <- names(x = tmp) for (i in seq_along(along.with = obs)) { obs[i] <- names(x = which.max( x = counts[names(x = counts) %in% tmp[[i]]] )) } obs }, obs ) if (isTRUE(x = simplify)) { tmp <- obs obs <- unlist(x = tmp) names(x = obs) <- make.unique(names = rep.int( x = names(x = tmp), times = vapply(X = tmp, FUN = length, FUN.VALUE = numeric(length = 1L)) )) } return(obs) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Matrix-like Subsetting for \link[=LogMap]{Logical Maps} #' #' @inheritParams base::`[` #' @inheritParams LogMap-class #' @param i,j Vectors of values (\code{i}) and observations (\code{j}) to pull #' from \code{x} #' @template param-dots-method #' #' @note \code{i} is not reordable; passing a different order for \code{i} #' will return a subset with rows in the same order as \code{x} #' #' @name [,LogMap #' @rdname sub-LogMap-method #' #' @keywords internal #' #' @examples #' map <- LogMap(letters[1:10]) #' map[['obs']] <- c(1, 3, 7) #' map[['entry']] <- c(2, 7, 10) #' #' map[] #' map[1:5, 2L] #' map[c("b", "c", "f"), "obs"] #' #' # Pass `drop = TRUE` to cast to `matrix` #' map[1:3, , drop = TRUE] #' #' # Note that `i` is non-reordable #' rownames(map)[1:3] #' map[c("b", "c", "a"), , drop = TRUE] #' NULL #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'missing', j = 'missing'), definition = function(x, i, j, ..., drop = FALSE) { return(x) } ) #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'character', j = 'character'), definition = function(x, i, j, ..., drop = FALSE) { i <- i[MatchCells(new = i, orig = rownames(x = x), ordered = TRUE)] x <- as.matrix(x = x)[i, j, drop = drop] if (!isTRUE(x = drop)) { x <- as(object = x, Class = 'LogMap') } return(x) } ) #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'character', j = 'missing'), definition = function(x, i, j, ..., drop = FALSE) { i <- i[MatchCells(new = i, orig = rownames(x = x), ordered = TRUE)] x <- as.matrix(x = x)[i, , drop = drop] if (!isTRUE(x = drop)) { x <- as(object = x, Class = 'LogMap') } return(x) } ) #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'missing', j = 'character'), definition = function(x, i, j, ..., drop = FALSE) { x <- as.matrix(x = x)[, j, drop = drop] if (!isTRUE(x = drop)) { x <- as(object = x, Class = 'LogMap') } return(x) } ) #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'numeric', j = 'missing'), definition = function(x, i, j, ..., drop = FALSE) { stopifnot(is_bare_integerish(x = i)) if (is.unsorted(x = i)) { i <- sort(x = i) } i <- rownames(x = x)[i] return(callNextMethod(x, i, ..., drop = drop)) } ) #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'missing', j = 'numeric'), definition = function(x, i, j, ..., drop = FALSE) { stopifnot(is_bare_integerish(x = j)) j <- colnames(x = x)[j] return(callNextMethod(x, , j, ..., drop = drop)) } ) #' @rdname sub-LogMap-method #' setMethod( f = '[', signature = c(x = 'LogMap', i = 'numeric', j = 'numeric'), definition = function(x, i, j, ..., drop = FALSE) { stopifnot(is_bare_integerish(x = i), is_bare_integerish(x = j)) if (is.unsorted(x = i)) { i <- sort(x = i) } i <- rownames(x = x)[i] j <- colnames(x = x)[j] return(callNextMethod(x, i, j, ..., drop = drop)) } ) #' @rdname LogMap-class #' #' @param x A \code{LogMap} object #' @param i A character vector of length 1, or \code{NULL} #' @param j Not used #' @param ... Ignored #' #' @return \code{[[}: if \code{i} is a character vector, the rownames that are #' mapped to \code{i}; otherwise the rownames of \code{x} #' #' @export #' #' @order 2 #' setMethod( f = '[[', signature = c(x = 'LogMap', i = 'character', j = 'missing'), definition = function(x, i, ...) { i <- i[1] i <- match.arg(arg = i, choices = colnames(x = x)) return(rownames(x = x)[x[, i, drop = TRUE]]) } ) #' \code{\link{LogMap}} Interaction Methods #' #' Additional methods for using \code{[[} with \code{\link{LogMap}} objects #' #' @inheritParams LogMap #' @param i An integer or numeric vector of length 1 #' #' @return The rownames that are mapped to \code{i} #' #' @rdname sub-sub-LogMap-internal-method #' #' @keywords internal #' setMethod( f = '[[', signature = c(x = 'LogMap', i = 'integer', j = 'missing'), definition = function(x, i, ...) { return(x[[colnames(x = x)[i]]]) } ) #' @rdname LogMap-class #' #' @export #' #' @order 3 #' setMethod( f = '[[', signature = c(x = 'LogMap', i = 'missing', j = 'missing'), definition = function(x, ...) { return(slot(object = x, name = '.Data')) } ) #' @rdname sub-sub-LogMap-internal-method #' setMethod( f = '[[', signature = c(x = 'LogMap', i = 'numeric', j = 'missing'), definition = function(x, i, ...) { return(x[[as.integer(x = i)]]) } ) #' @rdname LogMap-class #' #' @export #' #' @order 4 #' setMethod( f = '[[', signature = c(x = 'LogMap', i = 'NULL', j = 'missing'), definition = function(x, i, ...) { return(rownames(x = x)) } ) #' @rdname LogMap-class #' #' @param value A character or integer vector of values to record in the map #' for \code{i}, or \code{NULL} to remove the record for \code{i} #' #' @return \code{[[<-}: If \code{value} is \code{NULL}, then \code{x} without #' the observations for \code{i}; otherwise, \code{x} with a new column for #' \code{i} recording a \code{TRUE} for all values present in \code{value} #' #' @export #' #' @order 5 #' setMethod( f = '[[<-', signature = c( x = 'LogMap', i = 'character', j = 'missing', value = 'character' ), definition = function(x, i, ..., value) { value <- MatchCells(new = rownames(x = x), orig = value) x[[i]] <- value return(x) } ) #' @rdname LogMap-class #' #' @export #' #' @order 6 #' setMethod( f = '[[<-', signature = c( x = 'LogMap', i = 'character', j = 'missing', value = 'integer' ), definition = function(x, i, ..., value) { if (i %in% colnames(x = x)) { x[[i]] <- NULL } value <- MatchCells(new = value, rownames(x = x)) mat <- slot(object = x, name = '.Data') if (length(x = value)) { mat <- cbind( mat, matrix(data = FALSE, nrow = nrow(x = x), dimnames = list(NULL, i)) ) mat[value, i] <- TRUE } slot(object = x, name = '.Data') <- mat validObject(object = x) return(x) } ) #' @rdname LogMap-class #' #' @export #' #' @order 7 #' setMethod( f = '[[<-', signature = c(x = 'LogMap', i = 'character', j = 'missing', value = 'NULL'), definition = function(x, i, ..., value) { mat <- slot(object = x, name = '.Data') for (name in i) { idx <- which(x = colnames(x = mat) == name) if (length(x = idx)) { mat <- mat[, -idx, drop = FALSE] } } slot(object = x, name = '.Data') <- mat validObject(object = x) return(x) } ) #' @rdname LogMap-class #' #' @export #' #' @order 8 #' setMethod( f = '[[<-', signature = c( x = 'LogMap', i = 'character', j = 'missing', value = 'numeric' ), definition = function(x, i, ..., value) { value <- as.integer(x = value) x[[i]] <- value return(x) } ) #' \code{\link{LogMap}} Object Overview #' #' Overview of a \code{\link{LogMap}} object #' #' @param object A \code{\link{LogMap}} object #' #' @template return-show #' #' @concept logmap #' setMethod( f = 'show', signature = 'LogMap', definition = function(object) { cat( "A logical map for", nrow(x = object), "values across", ncol(x = object), "observations" ) return(invisible(x = NULL)) } ) #' Logical Map Validity #' #' @templateVar cls LogMap #' @template desc-validity #' #' @section Data Validation: #' Logical maps must be a logical matrix containing only TRUE or FALSE values #' #' @section Value Validation: #' All values must be named within the rownames of the object. Duplicate or #' empty (\code{""}) values are not allowed #' #' @section Observation Validation: #' All observations must be named within the column names of the object. #' Duplicate or empty (\code{""}) observations are not allowed #' #' @name LogMap-validity #' #' @family logmap #' @seealso \code{\link[methods]{validObject}} #' #' @examples #' map <- LogMap(letters[1:10]) #' map[['obs']] <- c(1, 3, 7) #' map[['entry']] <- c(2, 7, 10) #' validObject(map) #' setValidity( Class = 'LogMap', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Ensure we have a logical matrix if (!is.logical(x = object)) { valid <- c(valid, "The map must be a logical matrix") } if (any(is.na(x = object))) { valid <- c(valid, "The may may not contain NAs") } # Check rownames if (is.null(x = rownames(x = object))) { valid <- c(valid, "Rownames must be supplied") } if (any(!nzchar(x = rownames(x = object)))) { valid <- c(valid, "Rownames cannot be empty strings") } if (anyDuplicated(x = rownames(x = object))) { valid <- c(valid, "Duplicate rownames not allowed") } # Check colnames if (!is.null(x = colnames(x = object))) { if (any(!nzchar(x = colnames(x = object)))) { valid <- c(valid, "Columnn names cannot be empty strings") } if (anyDuplicated(x = colnames(x = object))) { valid <- c(valid, "Duplicate colnames not allowed") } } else if (ncol(x = object)) { valid <- c(valid, "Colnames must be supplied") } return(valid %||% TRUE) } ) SeuratObject/R/compliance.R0000644000176200001440000000342715075522101015306 0ustar liggesusers.SetSeuratCompat <- local({ seurat.version <- NULL function(pkgname, pkgpath) { current <- .RoundVersion(current = packageVersion(pkg = pkgname)) if (pkgname == 'Signac') { if (is.null(x = seurat.version)) { seurat.version <<- ifelse( test = paste(current, collapse = '.') >= '1.12.9000', yes = '5.0.0', no = '4.4.0' ) } return(invisible(x = NULL)) } seurat.version <<- paste(current, collapse = '.') if (!is.null(x = seurat.version) && seurat.version < '5.0.0') { options( Seurat.object.assay.brackets = 'v3', Seurat.object.assay.version = 'v3' ) } return(invisible(x = NULL)) } }) .GetSeuratCompat <- local( envir = environment(fun = .SetSeuratCompat), function() { if (is.null(x = seurat.version) && isNamespaceLoaded(name = 'Seurat')) { .SetSeuratCompat() } return(seurat.version %||% '5.0.0') } ) .SeuratCompatMessage <- local( envir = environment(fun = .SetSeuratCompat), function(pkgname, pkgpath) { seurat <- .GetSeuratCompat() if (!is.null(x = seurat) && seurat < '5.0.0') { options( Seurat.object.assay.brackets = 'v3', Seurat.object.assay.version = 'v3' ) version <- paste0('v', substr(x = seurat, start = 1L, stop = 1L)) packageStartupMessage(paste( strwrap(x = paste( pkgname, switch( EXPR = pkgname, Seurat = version, "built for for SeuratObject v4" ), "was just loaded with SeuratObject v5;", "disabling v5 assays and validation routines,", "and ensuring assays work in strict v3/v4 compatibility mode" )), collapse = '\n' )) } return(invisible(x = NULL)) } ) SeuratObject/R/graph.R0000644000176200001440000001356015075522101014274 0ustar liggesusers#' @include zzz.R #' @include generics.R #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The Graph Class #' #' The Graph class inherits from \code{\link[Matrix:sparseMatrix]{dgCMatrix}}. #' We do this to enable future expandability of graphs. #' #' @slot assay.used Optional name of assay used to generate \code{Graph} object #' #' @name Graph-class #' @rdname Graph-class #' #' @exportClass Graph #' #' @seealso \code{\link[Matrix]{dgCMatrix-class}} #' #' @family graph #' Graph <- setClass( Class = 'Graph', contains = "dgCMatrix", slots = list( assay.used = 'character' ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @importFrom methods as #' #' @rdname as.Graph #' @export #' @method as.Graph Matrix #' #' @examples #' # converting sparse matrix #' mat <- Matrix::rsparsematrix(nrow = 10, ncol = 10, density = 0.1) #' rownames(x = mat) <- paste0("feature_", 1:10) #' colnames(x = mat) <- paste0("cell_", 1:10) #' g <- as.Graph(x = mat) #' as.Graph.Matrix <- function(x, ...) { CheckDots(...) x <- as.sparse(x = x) if (is.null(x = rownames(x = x))) { abort(message = "Please provide rownames to the matrix before converting to a Graph") } if (is.null(x = colnames(x = x))) { abort(message = "Please provide colnames to the matrix before converting to a Graph") } return(as(object = x, Class = "Graph")) } #' @rdname as.Graph #' @export #' @method as.Graph matrix #' #' @examples #' # converting dense matrix #' mat <- matrix(data = 1:16, nrow = 4) #' rownames(x = mat) <- paste0("feature_", 1:4) #' colnames(x = mat) <- paste0("cell_", 1:4) #' g <- as.Graph(x = mat) #' as.Graph.matrix <- as.Graph.Matrix #' @param weighted If TRUE, fill entries in Graph matrix with value from the #' nn.dist slot of the Neighbor object #' #' @rdname as.Graph #' @export #' @method as.Graph Neighbor #' as.Graph.Neighbor <- function(x, weighted = TRUE, ...) { CheckDots(...) j <- as.integer(x = Indices(object = x) - 1) i <- as.integer(x = rep(x = (1:nrow(x = x)) - 1, times = ncol(x = x))) vals <- if (weighted) { as.vector(x = Distances(object = x)) } else { 1 } graph <- new( Class = "dgTMatrix", i = i, j = j, x = vals, Dim = as.integer(x = c(nrow(x = x), nrow(x = x))) ) colnames(x = graph) <- rownames(x = graph) <- Cells(x = x) graph <- as.Graph.Matrix(x = graph) return(graph) } #' @method Cells Graph #' @export #' Cells.Graph <- function(x, margin = 1L, ...) { margin <- as.integer(x = margin) if (is_na(x = margin)) { return(Reduce(f = union, x = dimnames(x = x))) } if (!isTRUE(margin %in% c(1L, 2L))) { stop("'margin' must be either 1 or 2", call. = FALSE) } return(dimnames(x = x)[[margin]]) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay Graph #' DefaultAssay.Graph <- function(object, ...) { # object <- UpdateSlots(object = object) assay <- slot(object = object, name = 'assay.used') if (!length(x = assay)) { assay <- NULL } return(assay) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay<- Graph #' "DefaultAssay<-.Graph" <- function(object, ..., value) { op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op)) object <- suppressWarnings(expr = UpdateSlots(object = object)) if (!length(x = value) || !isTRUE(x = nzchar(x = value))) { value <- character(length = 0L) } slot(object = object, name = 'assay.used') <- value options(op) validObject(object = object) return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setValidity( Class = 'Graph', method = function(object) { if (.GetSeuratCompat() < '5.0.0') { return(TRUE) } if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Check dimnames dnames <- dimnames(x = object) for (i in seq_along(along.with = dnames)) { type <- c('row', 'column')[i] if (is.null(x = dnames[[i]])) { valid <- c(valid, paste(type, "names must be provided")) } else if (any(!nzchar(x = dnames[[i]]))) { valid <- c(valid, paste(type, "names must not be empty strings")) } else if (anyDuplicated(x = dnames[[i]])) { valid <- c(valid, paste(type, "names may not contain duplicates")) } } # Check default assay assay <- DefaultAssay(object = object) if (length(x = assay) && !nzchar(x = assay)) { valid <- c(valid, "'assay.used' may not be an empty character ('')") } return(valid %||% TRUE) } ) #' Graph Object Overview #' #' Overview of a \code{\link{Graph}} Object #' #' @template return-show #' #' @keywords internal #' #' @concept graph #' #' @examples #' pbmc_small[["RNA_snn"]] #' setMethod( f = 'show', signature = 'Graph', definition = function(object) { cat( "A Graph object containing", nrow(x = object), "cells" ) } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SeuratObject/R/segmentation.R0000644000176200001440000004674115116356172015710 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importFrom sp coordinates #' @importFrom methods as callNextMethod #' @importClassesFrom sp SpatialPolygons NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The \code{Segmentation} Class #' #' A container for cell segmentation boundaries. #' Inherits from \code{\link[sp:SpatialPolygons-class]{SpatialPolygons}}. #' Supports storing boundaries in objects of class \code{\link[sf]{sf}}. #' #' @slot sf.data Segmentation boundaries in \code{\link[sf]{sf}} format #' @slot compact Logical indicating whether or not the object only stores #' segmentation information in the \code{sf.data} slot, rather than also in the #' standard \code{SpatialPolygons} slots, to save memory and processing time. #' Currently only relevant for Visium data. #' #' @family segmentation #' @templateVar cls Segmentation #' @template seealso-methods #' setClass( Class = 'Segmentation', contains = 'SpatialPolygons', slots = list( sf.data = 'ANY', compact = 'OptionalLogical' ), prototype = list( compact = FALSE ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{Segmentation} Methods #' #' Methods for \code{\link[SeuratObject:Segmentation-class]{Segmentation}} #' objects #' #' @inheritParams Centroids-methods #' @param x,object,obj A #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object #' #' @name Segmentation-methods #' @rdname Segmentation-methods #' #' @section Progress Updates with \pkg{progressr}: #' The following methods use #' \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to #' render status updates and progress bars: #' \itemize{ #' \item \code{RenameCells} #' } #' To enable progress updates, wrap #' the function call in \code{\link[progressr]{with_progress}} or run #' \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running #' this function. For more details about \pkg{progressr}, please read #' \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} #' #' @section Parallelization with \pkg{future}: #' The following methods use #' \href{https://cran.r-project.org/package=future}{\pkg{future}} to enable #' parallelization: #' \itemize{ #' \item \code{RenameCells} #' } #' Parallelization strategies can be set using #' \code{\link[future]{plan}}. Common plans include \dQuote{\code{sequential}} #' for non-parallelized processing or \dQuote{\code{multisession}} for parallel #' evaluation using multiple \R sessions; for other plans, see the #' \dQuote{Implemented evaluation strategies} section of #' \code{\link[future:plan]{?future::plan}}. For a more thorough introduction #' to \pkg{future}, see #' \href{https://future.futureverse.org/articles/future-1-overview.html}{\code{vignette("future-1-overview")}} #' #' @concept future #' #' @seealso \code{\link{Segmentation-class}} #' #' @family segmentation #' NULL #' @template method-cells #' #' @rdname Segmentation-methods #' @method Cells Segmentation #' @export #' Cells.Segmentation <- function(x, ...) { compact <- .hasSlot(object = x, name = 'compact') && slot(object = x, name = 'compact') if (compact) { sf_data <- slot(object = x, name = 'sf.data') return(unique(sf_data$cell)) } return(unname(obj = names(x = x))) } #' @importFrom sp Polygon Polygons SpatialPolygons CRS #' @param compact Logical indicating whether or not the object should only store segmentation data #' in the \code{sf.data} slot; see \link{Segmentation-class} for details. #' #' @rdname CreateSegmentation #' @method CreateSegmentation data.frame #' @export #' CreateSegmentation.data.frame <- function(coords, compact = FALSE) { if (compact) { # Create minimal valid SpatialPolygons structure to satisfy inheritance minimal_coords <- matrix(c(0, 1, 1, 1, 1, 0, 0, 0, 0, 1), ncol = 2, byrow = TRUE) minimal_polygon <- Polygons( srl = list(Polygon(coords = minimal_coords)), ID = "placeholder" ) sp_base <- SpatialPolygons(list(minimal_polygon)) # Now create Segmentation object with valid SpatialPolygons inheritance obj <- new( Class = 'Segmentation', sp_base, sf.data = coords ) # Override with empty polygons for compact mode slot(obj, 'polygons') <- list() slot(obj, 'plotOrder') <- integer(0) slot(obj, 'proj4string') <- CRS(as.character(NA)) # Get bbox from coordinate ranges in the dataframe x_range <- range(coords$x, na.rm = TRUE) y_range <- range(coords$y, na.rm = TRUE) slot(obj, 'bbox') <- matrix(c(x_range[1], y_range[1], x_range[2], y_range[2]), nrow = 2, ncol = 2, dimnames = list(c("x", "y"), c("min", "max"))) slot(obj, 'compact') <- TRUE return(obj) } idx <- NameIndex(x = coords, names = c('cell', 'x', 'y'), MARGIN = 2L) xy <- idx[c('x', 'y')] cell.idx <- idx[['cell']] coords <- split(x = coords, f = coords[[cell.idx]]) coords <- sapply( X = coords, FUN = function(x) { cx <- as.matrix(x = x[, xy]) colnames(x = cx) <- c('x', 'y') return(Polygons( srl = list(Polygon(coords = cx)), ID = unique(x = as.character(x = x[[cell.idx]])) )) } ) coords <- SpatialPolygons(Srl = coords) CheckGC() return(as(object = coords, Class = 'Segmentation')) } #' @rdname CreateSegmentation #' @method CreateSegmentation Segmentation #' @export #' CreateSegmentation.Segmentation <- function(coords, compact = FALSE) { return(coords) } #' @rdname CreateSegmentation #' @method CreateSegmentation sf #' #' @param compact Logical indicating whether or not the object should only store segmentation data #' in the \code{sf.data} slot; see \link{Segmentation-class} for details. #' #' @export #' CreateSegmentation.sf <- function(coords, compact = TRUE) { # Method is called when creating Segmentation from an sf object # Set the attribute-geometry relationship to constant # See https://r-spatial.github.io/sf/reference/sf.html#details sf::st_agr(coords) <- "constant" # Extract coordinates as a dataframe from sf object coords_mat <- sf::st_coordinates(coords) l2_indices <- coords_mat[, "L2"] # L2 column corresponds to polygon (cell) index coords_df <- data.frame(x = coords_mat[, 1], y = coords_mat[, 2], cell = coords$barcodes[l2_indices], stringsAsFactors = FALSE) obj <- CreateSegmentation.data.frame(coords = coords_df, compact = compact) if (!compact) { # When compact = FALSE, make sure to store the sf dataframe slot(object = obj, name = 'sf.data') <- coords_df } return(obj) } #' @method Crop Segmentation #' @export #' Crop.Segmentation <- function(object, ...) { return(.Crop(object, ...)) } #' @details \code{GetTissueCoordinates}, \code{coordinates}: Get #' tissue coordinates #' #' @inheritParams Centroids-methods #' #' @return \code{GetTissueCoordinates}, \code{coordinates}: A data frame with #' three columns: #' \itemize{ #' \item \dQuote{\code{x}}: the x-coordinate #' \item \dQuote{\code{y}}: the y-coordinate #' \item \dQuote{\code{cell}} or \dQuote{\code{ID}}: the cell name #' } #' If \code{full} is \code{TRUE}, then each coordinate will indicate a vertex #' for the cell polygon; otherwise, each coordinate will indicate a centroid #' for the cell. Note: to compute centroids for segmentations stored in compact mode, #' call \code{GetTissueCoordinates} on the associated \code{Centroids} object instead. #' #' @rdname Segmentation-methods #' @method GetTissueCoordinates Segmentation #' @export #' GetTissueCoordinates.Segmentation <- function(object, full = TRUE, ...) { coords <- coordinates(obj = object, full = full, ...) colnames(x = coords) <- c('x', 'y', 'cell') rownames(x = coords) <- NULL return(coords) } #' @details \code{RenameCells}: Update cell names #' #' @inheritParams RenameCells #' #' @return \code{RenameCells}: \code{object} with the cells renamed to #' \code{new.names} #' #' @importFrom future.apply future_mapply #' #' @rdname Segmentation-methods #' @method RenameCells Segmentation #' @export #' RenameCells.Segmentation <- function(object, new.names = NULL, ...) { if (is.null(x = new.names)) { return(object) } new.names <- make.unique(names = new.names) compact <- .hasSlot(object = object, name = 'compact') && slot(object = object, name = 'compact') if (length(x = new.names) != length(x = Cells(x = object))) { stop("Cannot partially rename segmentation cells", call. = FALSE) } sf_data <- if (.hasSlot(object = object, name = 'sf.data')) slot(object = object, name = 'sf.data') else NULL id_map <- setNames(new.names, Cells(x = object)) if (!compact) { names(x = slot(object = object, name = 'polygons')) <- new.names p <- progressor(along = slot(object = object, name = 'polygons')) slot(object = object, name = 'polygons') <- future_mapply( FUN = function(polygon, name) { slot(object = polygon, name = 'ID') <- name p() return(polygon) }, polygon = slot(object = object, name = 'polygons'), name = new.names, SIMPLIFY = FALSE, USE.NAMES = TRUE ) } if (!is.null(x = sf_data)) { sf_data$cell <- id_map[ sf_data$cell ] } slot(object = object, name = 'sf.data') <- sf_data return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @template method-lengths #' #' @rdname Segmentation-methods #' @method lengths Segmentation #' @export #' lengths.Segmentation <- function(x, use.names = TRUE) { return(rle(x = GetTissueCoordinates(object = x, full = TRUE)$cell)) } #' @details \code{subset}, \code{[}: Subset a \code{Segmentation} object to #' certain cells #' #' @return \code{subset}, \code{[}: \code{x} subsetted to the cells specified #' by \code{cells}/\code{i} #' #' @rdname Segmentation-methods #' @method subset Segmentation #' @export #' subset.Segmentation <- function(x, cells = NULL, ...) { if (is.null(x = cells)) { return(x) } if (is.numeric(x = cells)) { # Account for the case when cells to subset are given as indices and not IDs cells <- Cells(x = x)[cells] cells <- MatchCells(new = Cells(x = x), orig = cells, ordered = TRUE) } else { cells <- intersect(Cells(x), cells) } if (!length(x = cells)) { stop("None of the requested cells found") } compact <- .hasSlot(object = x, name = 'compact') && slot(object = x, name = 'compact') sf_data <- if (.hasSlot(object = x, name = 'sf.data')) slot(object = x, name = 'sf.data') else NULL sf_data_subset <- NULL if (!is.null(sf_data)) { # Maintain original order of cells in subsetted object # Order is important when plotting polygons to avoid the sides (lines between vertices) being drawn incorrectly matching_indices <- which(sf_data$cell %in% cells) sf_data_subset <- sf_data[matching_indices, ] } if (!compact) { x <- x[cells] x <- as(object = x, Class = 'Segmentation') } slot(object = x, name = 'sf.data') <- sf_data_subset return(x) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @details \code{[[<-}: Attach or remove \code{sf}-derived data to/from a \code{Segmentation} object #' #' @return \code{[[<-}: #' \itemize{ #' \item If \code{value} is an \code{data.frame} object, #' returns \code{x} with \code{value} stored in \code{sf.data}; #' requires that \code{i} is \dQuote{sf.data}. #' \item If \code{value} is \code{NULL}, returns \code{x} with \code{sf.data} removed. #' } #' @param value The value to assign to the slot specified by \code{i} in the \code{Segmentation} object. #' @rdname Segmentation-methods #' setMethod( f = '[[<-', signature = c( x = 'Segmentation', i = 'character', j = 'missing', value = 'ANY' ), definition = function(x, i, ..., value) { if (i == "sf.data") { if (!is.null(x = value) && !inherits(x = value, what = 'data.frame')) { stop("Value assigned to 'sf.data' must inherit from the data.frame class", call. = FALSE) } # Update sf.data slot slot(object = x, name = 'sf.data') <- value validObject(x) return(x) } else { stop("Cannot assign value to slot '", i, "' in Segmentation object", call. = FALSE) } } ) #' @importFrom methods as #' #' @param value The value to assign to the slot specified by \code{i} in the \code{Segmentation} object. #' @rdname Segmentation-methods #' setMethod( f = '[[<-', signature = c( x = 'Segmentation', i = 'character', j = 'missing', value = 'NULL' ), definition = function(x, i, ..., value) { if (i == "sf.data") { if (is.null(x = slot(object = x, name = 'sf.data'))) { warning("The 'sf.data' slot is already NULL", call. = FALSE) return(x) } else { slot(object = x, name = 'sf.data') <- NULL } } validObject(object = x) return(x) } ) #' @rdname Segmentation-methods #' setMethod( f = '[', signature = c(x = 'Segmentation'), definition = function(x, i, j, ..., drop = TRUE) { compact <- .hasSlot(object = x, name = 'compact') && slot(object = x, name = 'compact') sf_data <- if (.hasSlot(object = x, name = 'sf.data')) slot(object = x, name = 'sf.data') else NULL if (is.numeric(i)) { # Handle numeric indexing cells <- Cells(x = x)[i] } else { cells <- intersect(Cells(x), i) } sf_data_subset <- NULL if (!is.null(sf_data)) { matching_indices <- which(sf_data$cell %in% cells) sf_data_subset <- sf_data[matching_indices, ] } if (!compact) { x <- callNextMethod() x <- as(object = x, Class = 'Segmentation') } slot(object = x, name = 'sf.data') <- sf_data_subset return(x) } ) #' @rdname Segmentation-methods #' setMethod( f = 'coordinates', signature = c(obj = 'Segmentation'), definition = function(obj, full = TRUE, ...) { compact <- .hasSlot(object = obj, name = 'compact') && slot(object = obj, name = 'compact') if (compact) { coords <- slot(object = obj, name = 'sf.data') if (isTRUE(x = full)) { return(coords) } message("Centroids cannot be computed for compact Segmentation objects; returning full coordinates.") return(coords) } else { if (!isTRUE(x = full)) { coords <- as.data.frame(x = callNextMethod(obj = obj)) coords$cell <- Cells(x = obj) return(coords) } coords <- lapply( X = slot(object = obj, name = 'polygons'), FUN = function(x) { polys <- lapply( X = slot(object = x, name = 'Polygons'), FUN = slot, name = 'coords' ) polys <- as.data.frame(x = do.call(what = 'rbind', args = polys)) colnames(x = polys) <- c('x', 'y') polys$ID <- slot(object = x, name = 'ID') return(polys) } ) coords <- do.call(what = 'rbind', args = coords) rownames(x = coords) <- NULL return(coords) } } ) setMethod( f = 'over', signature = c(x = 'Segmentation', y = 'SpatialPolygons'), definition = function(x, y, returnList = FALSE, fn = NULL, ...) { deprecate_stop( when = '5.0.0', what = 'over()', details = "Future integration with `sf` is on the roadmap with no current ETA" ) check_installed(pkg = 'sf') return(over( x = as(object = x, Class = 'sf'), y = as(object = y, Class = 'sf'), sparse = FALSE, returnList = returnList, fn = fn, ... )) } ) #' @rdname Overlay #' @export #' setMethod( f = 'Overlay', signature = c(x = 'Segmentation', y = 'SpatialPolygons'), definition = function(x, y, invert = FALSE, ...) { check_installed(pkg = 'sf', reason = 'to overlay spatial information') compact <- .hasSlot(object = x, name = 'compact') && slot(object = x, name = 'compact') sf_data <- if (.hasSlot(object = x, name = 'sf.data')) slot(object = x, name = 'sf.data') else NULL if (compact) { message("Overlaying compact Segmentation objects is currently not supported.") return(NULL) } idx <- sf::st_intersects( x = as(object = x, Class = 'sf'), y = as(object = y, Class = 'sf'), sparse = FALSE ) idx <- which(x = idx) names_in_sf_object1 <- if (!is.null(x = row.names(x = x))) { row.names(x = x)[idx] } else { x$id[idx] } idx <- setNames( object = rep.int(x = TRUE, times = length(x = idx)), nm = names_in_sf_object1 ) if (!length(x = idx)) { warn("The selected region does not contain any cell segmentations") return(NULL) } names(x = idx) <- vapply( X = strsplit(x = names(x = idx), split = '\\.'), FUN = '[[', FUN.VALUE = character(length = 1L), 1L, USE.NAMES = FALSE ) cells <- if (isTRUE(x = invert)) { setdiff(x = Cells(x = x), y = names(x = idx)) } else { names(x = idx) } x <- x[cells] sf_data <- if (!is.null(x = sf_data)) { matching_indices <- which(sf_data$cell %in% cells) sf_data[matching_indices, ] } else { NULL } slot(object = x, name = 'sf.data') <- sf_data return(x) } ) #' @template method-show #' #' @rdname Segmentation-methods #' setMethod( f = 'show', signature = c(object = 'Segmentation'), definition = function(object) { compact <- .hasSlot(object = object, name = 'compact') && slot(object = object, name = 'compact') sf_data <- if (.hasSlot(object = object, name = 'sf.data')) slot(object = object, name = 'sf.data') else NULL if (compact && !is.null(x = sf_data)) { cat("A spatial segmentation for", length(unique(sf_data$cell)), "cells\n") } else { cat("A spatial segmentation for", length(x = object), "cells\n") } cat("Is compact:", compact, "\n") } ) #' Segmentation Validity #' #' @templateVar cls Segmentation #' @template desc-validity #' #' @section sf.data Validation: #' Validates that the sf.data slot contains an object of class \code{sf}. #' #' @name Segmentation-validity #' #' @family segmentation #' #' @seealso \code{\link[methods]{validObject}} #' setValidity( Class = 'Segmentation', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Check sf.data slot sf_data <- slot(object = object, name = 'sf.data') if (!is.null(x = sf_data)) { # If sf.data is populated, it should inherit from 'data.frame' if (!inherits(x = sf_data, 'data.frame')) { valid <- c( valid, "'sf.data' slot must inherit from 'data.frame' class" ) } } return(valid %||% TRUE) } )SeuratObject/R/zzz.R0000644000176200001440000004075515116320014014031 0ustar liggesusers#' @importFrom sp bbox over #' @importFrom Rcpp evalCpp #' @importFrom Matrix nnzero #' @importFrom progressr progressor #' @importFrom lifecycle deprecated is_present #' @importFrom utils head packageVersion tail upgrade #' @importFrom methods new setClass setClassUnion setGeneric setMethod #' setOldClass setValidity show slot slot<- validObject #' @importFrom rlang abort arg_match arg_match0 caller_env check_installed #' enquo eval_tidy have_name inform is_bare_character is_bare_integerish #' is_bare_list is_bare_numeric is_missing is_na is_named is_quosure #' missing_arg warn #' @importClassesFrom Matrix dgCMatrix CsparseMatrix dsparseMatrix generalMatrix #' dMatrix sparseMatrix compMatrix Matrix #' @useDynLib SeuratObject #' NULL #' @docType package #' @name SeuratObject-package #' @rdname SeuratObject-package #' "_PACKAGE" #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Options #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \pkg{Seurat} Options #' #' Various options used in \pkg{Seurat} #' #' @section Package Options: #' \subsection{Seurat.coords.short_range}{ #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.coords.short_range}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.coords.short_range")}} #' } #' \subsection{Seurat.input.sparse_ratio}{ #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.input.sparse_ratio}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.input.sparse_ratio")}} #' } #' \subsection{Seurat.io.rds.strict}{ #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.io.rds.strict}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.io.rds.strict")}} #' } #' \subsection{Seurat.object.assay.calcn}{ #' Run \code{CalcN} when adding assay data to a \code{Seurat} object\cr #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.assay.calcn}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.assay.calcn")}} #' } #' \subsection{Seurat.object.assay.version}{ #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.assay.version}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.assay.version")}} #' } #' \subsection{Seurat.object.assay.v3.missing_layer}{ #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.assay.v3.missing_layer}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.assay.v3.missing_layer")}} #' } #' \subsection{Seurat.object.project}{ #' Default project for new \code{\link{Seurat}} objects\cr #' Defaults to #' \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.project}}\cr #' Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.project")}} #' } #' #' @name SeuratObject-options #' #' @keywords internal #' NULL Seurat.options <- list( Seurat.coords.short_range = 'max', Seurat.input.sparse_ratio = 0.4, Seurat.io.rds.strict = FALSE, Seurat.object.assay.brackets = 'v5', Seurat.object.assay.calcn = NULL, Seurat.object.assay.version = 'v5', Seurat.object.assay.v3.missing_layer = 'matrix', Seurat.object.project = 'SeuratProject', progressr.clear = FALSE ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Built With #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .BuiltWith <- c( R = format(x = getRversion()), Matrix = format(x = packageVersion(pkg = "Matrix")) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Reexports #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @importFrom future plan #' @export #' future::plan #' @importFrom generics intersect #' @export #' generics::intersect # #' @importFrom Matrix colMeans # #' @export # #' # Matrix::colMeans #' @importFrom Matrix t #' @export #' #' @noRd #' Matrix::t #' @importFrom progressr handlers #' @export #' progressr::handlers #' @importFrom progressr with_progress #' @export #' progressr::with_progress #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Environments #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sparse.classes <- new.env() #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setClassUnion(name = 'OptionalCharacter', members = c('NULL', 'character')) setClassUnion(name = 'OptionalList', members = c('NULL', 'list')) setClassUnion(name = 'OptionalLogical', members = c('NULL', 'logical')) setOldClass(Classes = 'package_version') #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @keywords internal #' #' @noRd #' .AutoRadius <- function(coords) { return(0.01 * mean(x = apply( X = apply(X = coords, MARGIN = 2L, FUN = range), MARGIN = 2L, FUN = diff ))) } #' @keywords internal #' #' @noRd #' .BboxDF <- function(x) { df <- expand.grid(x = x['x', ], y = x['y', ]) df <- df[c(1, 3, 4, 2), ] return(df) } #' Test Intersections of Bounding Boxes #' #' @param i,j \link[sp:bbox]{Bounding boxes} #' @param constraint Type of intersection to perform; choose from: #' \itemize{ #' \item \dQuote{\code{intersect}}: \code{i} must fall at least #' partially within the bounds of \code{j} for the dimensions #' specified by \code{MARGIN} #' \item \dQuote{\code{contained}}: \code{i} must fall completely #' within the bounds of \code{j} for the dimensions specified #' by \code{MARIGN} #' \item \dQuote{\code{overlap}}: \code{i} must fall at least partially #' within \code{j}, or \code{j} must fall at least partially within #' \code{i}, for the dimensions specified by \code{MARGIN}; essentially #' \code{.BboxIntersect(i, j, 'intersect', MARGIN) || .BboxIntersect(j, i, 'intersect', MARGIN)} #' } #' @param MARGIN Direction of intersection; choose from: #' \itemize{ #' \item \code{1L}: intersect along the x-dimension #' \item \code{2L}: intersect along the y-dimension #' \item \code{3L}: intersect along both the x- and y-dimensions #' } #' #' @return \code{TRUE} if \code{i} intersects with \code{j}; #' otherwise \code{FALSE} #' #' @keywords internal #' #' @noRd #' .BboxIntersect <- function( i, j, constraint = c('intersect', 'contained', 'overlap'), MARGIN = 3L ) { constraint <- constraint[1L] constraint <- match.arg(arg = constraint) if (!MARGIN %in% seq.int(from = 1L, to = 3L)) { stop(".MARGIN must be 1, 2, or 3") } else if (MARGIN == 3L) { MARGIN <- seq.int(from = 1L, to = 2L) } check <- vector(mode = 'logical', length = length(x = MARGIN)) names(x = check) <- c('x', 'y')[MARGIN] for (x in names(x = check)) { check[[x]] <- switch( EXPR = constraint, 'intersect' = { (i[x, 'min'] >= j[x, 'min'] && i[x, 'min'] <= j[x, 'max']) || (i[x, 'max'] >= j[x, 'min'] && i[x, 'max'] <= j[x, 'max']) }, 'contained' = i[x, 'min'] >= j[x, 'min'] && i[x, 'max'] <= j[x, 'max'], 'overlap' = { .margin <- c(x = 1L, y = 2L)[x] .BboxIntersect(i = i, j = j, constraint = 'i', MARGIN = .margin) || .BboxIntersect(i = j, j = i, constraint = 'i', MARGIN = .margin) }, stop("Constraint '", constraint, "' not yet implemented") ) } return(all(check)) } .IsDataFrame <- function(x) { return(length(x = class(x = x)) == 1L && inherits(x = x, what = 'data.frame')) } #' Test Future Compatibility with \pkg{Seurat} #' #' Check to see if \pkg{SeuratObject} and/or \pkg{Seurat} are at least a #' specific version or if they're configured to act as if they're a #' specific version (see details below). This allows testing compatibility with #' future requirements for both \pkg{SeuratObject} and \pkg{Seurat} #' #' Blah blah blah #' #' @inheritParams utils::packageVersion #' @param version A version string or object of class #' \code{\link{package_version}} #' #' @return \code{TRUE} if \pkg{SeuratObject} and/or \pkg{Seurat} #' #' @keywords internal #' #' @export #' #' @aliases IsFutureSeurat #' .IsFutureSeurat <- function(version, lib.loc = NULL) { version <- package_version(x = version) opt <- paste0( 'Seurat.future.v', gsub(pattern = '\\.', replacement = '_', x = as.character(x = version)) ) future <- isTRUE(x = getOption(x = opt, default = FALSE)) || packageVersion(pkg = 'SeuratObject', lib.loc = lib.loc) >= version # If `Seurat` is installed, check against it's version. # This is a (probably bad/hacky) workaround to avoid calling `requireNamespace` # and forcing us to list `Seurat` as a dependency. if (nzchar(system.file(package = "Seurat"))) { future <- future || packageVersion("Seurat", lib.loc = lib.loc) >= version } return(future) } .IsNull <- function(x) { return(vapply(X = x, FUN = is.null, FUN.VALUE = logical(length = 1L))) } .MakeNames <- function(x, strict = FALSE, type = c('layers')) { if (isTRUE(x = strict)) { return(make.names(names = x, unique = TRUE)) } type <- type[[1L]] type <- match.arg(arg = type) x <- switch( EXPR = type, layers = { # Remove white spaces x <- gsub(pattern = '[[:space:]]+', replacement = '_', x = x) # Remove illegal characters x <- gsub( pattern = '[\\;\\:\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\{\\}\\[]', replacement = '', x = x ) x <- gsub(pattern = '\\]', replacement = '', x = x) x } ) return(x) } #' Create a List with a Serial Comma #' #' @param ... A character vector to join #' @param cnj Conjunction to use for final entry #' @param quote Quote the entries of \code{...}; choose from: #' \itemize{ #' \item \dQuote{\code{single}}: regular single quotes #' \item \dQuote{\code{fancysingle}}: fancy single quotes #' \item \dQuote{\code{double}}: regular double quotes #' \item \dQuote{\code{fancydouble}}: fancy double quotes #' \item \dQuote{\code{none}}: no extra quoting #' } #' #' @return \code{...} arranged into an English list with a serial comma #' when needed #' #' @keywords internal #' #' @seealso \code{\link[base]{sQuote}} #' #' @examples #' .Oxford('cell') #' .Oxford('cell', 'ident') #' .Oxford('cell', 'ident', 'gene') #' #' @noRd #' .Oxford <- function( ..., cnj = c('or', 'and'), quote = c('single', 'fancysingle', 'double', 'fancydouble', 'none') ) { x <- as.character(x = c(...)) cnj <- arg_match(arg = cnj) quote <- arg_match(arg = quote) x <- switch( EXPR = quote, single = sQuote(x = x, q = FALSE), fancysingle = sQuote(x = x, q = TRUE), double = dQuote(x = x, q = FALSE), fancydouble = dQuote(x = x, q = TRUE), x ) if (length(x = x) <= 1L) { return(x) } else if (length(x = x) == 2L) { return(paste(x, collapse = paste0(' ', cnj, ' '))) } return(paste( paste0(paste(x[1:(length(x = x) - 1L)], collapse = ', '), ','), cnj, x[length(x = x)] )) } #' Indexes from Run Length Encodings #' #' Generate an index for subsetting from a \link[base:rle]{run length encoding} #' #' @inheritParams base::lengths #' @param x An \code{\link[base:rle]{rle}} object #' #' @return A list where each entry is the indices a particular value #' #' @keywords internal #' #' @noRd #' .RleIndex <- function(x, use.names = TRUE) { idx <- lapply( X = seq_len(length.out = length(x = x$values)), FUN = function(i) { from <- (x$lengths[i] * i) - (x$lengths[i] - 1L) return(seq.int(from = from, to = from + x$lengths[i] - 1L)) } ) if (isTRUE(x = use.names)) { names(x = idx) <- x$values } return(idx) } #' Round Version Information #' #' @param current A package version #' #' @return ... #' #' @keywords internal #' #' @noRd #' .RoundVersion <- function(current) { current <- as.character(x = numeric_version(x = current, strict = TRUE)) current <- unlist(x = strsplit(x = current, split = '\\.')) if (length(x = current) > 4L) { if (length(x = current) > 4L) { current[4L] <- paste( current[seq.int(from = 4L, to = length(x = current))], collapse = '.' ) current <- current[1:4] } } names(x = current) <- c('major', 'minor', 'patch', 'devel')[seq_along(along.with = current)] if (!is_na(x = current['devel'])) { if (all(current[c('minor', 'patch')] == '9')) { current['major'] <- as.character(x = as.integer(x = current['major']) + 1L) current[c('minor', 'patch')] <- '0' } else if (current['patch'] == '0') { current['minor'] <- as.character(x = as.integer(x = current['minor']) + 1L) current['patch'] <- '0' } else { current['patch'] <- as.character(x = as.integer(x = current['patch']) + 1L) } current <- current[c('major', 'minor', 'patch')] } current <- vapply( X = current, FUN = as.integer, FUN.VALUE = integer(length = 1L), USE.NAMES = TRUE ) if (!is_na(x = current['devel'])) { if (all(current[c('minor', 'patch')] == '9')) { current['major'] <- as.character(x = as.integer(x = current['major']) + 1L) current[c('minor', 'patch')] <- '0' } else if (current['patch'] == '0') { current['minor'] <- as.character(x = as.integer(x = current['minor']) + 1L) current['patch'] <- '0' } else { current['patch'] <- as.character(x = as.integer(x = current['patch']) + 1L) } current <- current[c('major', 'minor', 'patch')] } return(current) } #' Index of Names #' #' Get the index of row- or column-names #' #' @param x A two-dimensional object #' @param names A vector of names to index #' @param MARGIN Either \code{1L} for row-names or \code{2L} for column-names #' #' @return A named integer vector of length \code{length(names)}; the names are #' \code{names} and the values are the index of \code{names} in the row- or #' column-names. If no name is found, uses the lowest available index #' #' @importFrom stats na.omit #' #' @keywords internal #' #' @noRd #' NameIndex <- function(x, names, MARGIN) { if (!MARGIN %in% c(1L, 2L)) { stop("MARGIN must be either 1 or 2", call. = FALSE) } if (!length(x = dim(x = x)) == 2L) { stop("'x' must be a two-dimensional object", call. = FALSE) } nfunc <- list(rownames, colnames)[[MARGIN]] xnames <- nfunc(x = x) if (length(x = names) > length(x = xnames)) { stop( "Too many names requested (", length(x = names), " requested, ", length(x = xnames), " provided)", call. = FALSE ) } idx <- vector(mode = 'integer', length = length(x = names)) names(x = idx) <- names for (i in names) { idx[[i]] <- ifelse( test = i %in% xnames, yes = which(x = xnames == i)[1], no = NA_integer_ ) } idx.na <- which(x = is.na(x = idx)) xind <- setdiff( x = seq_len(length.out = ncol(x = x)), y = na.omit(object = idx) ) for (i in idx.na) { idx[[i]] <- xind[[i]] } return(idx) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Hooks #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .onAttach <- function(libname, pkgname) { for (i in names(x = .BuiltWith)) { current <- switch(EXPR = i, R = getRversion(), packageVersion(pkg = i)) if (current > .BuiltWith[i]) { msg <- paste( sQuote(x = pkgname), "was built", switch( EXPR = i, R = "under R", paste("with package", sQuote(x = i)) ), .BuiltWith[i], "but the current version is", paste0(current, ';'), "it is recomended that you reinstall ", sQuote(x = pkgname), " as the ABI for", switch(EXPR = i, R = i, sQuote(x = i)), "may have changed" ) packageStartupMessage(paste(strwrap(x = msg), collapse = '\n')) } } } .onLoad <- function(libname, pkgname) { toset <- setdiff(x = names(x = Seurat.options), y = names(x = options())) if (length(x = toset)) { options(Seurat.options[toset]) } setHook( hookName = packageEvent(pkgname = 'Seurat', event = 'onLoad'), value = .SetSeuratCompat ) setHook( hookName = packageEvent(pkgname = 'Signac', event = 'onLoad'), value = .SetSeuratCompat ) setHook( hookName = packageEvent(pkgname = 'Seurat', event = 'attach'), value = .SeuratCompatMessage ) setHook( hookName = packageEvent(pkgname = 'Signac', event = 'attach'), value = .SeuratCompatMessage ) return(invisible(x = NULL)) } SeuratObject/R/sparse.R0000644000176200001440000000735715075522101014477 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importClassesFrom spam spam #' @importClassesFrom Matrix CsparseMatrix RsparseMatrix #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Identify Sparse Slots #' #' @param x A sparse matrix #' @param type ... #' #' @return ... #' #' @keywords internal #' #' @export #' #' @family sparse #' .SparseSlots <- function(x, type = c('pointers', 'indices', 'entries')) { UseMethod(generic = '.SparseSlots', object = x) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Is a Matrix Sparse #' #' @param x A matrix #' #' @return ... #' #' @keywords internal #' #' @export #' #' @family sparse #' #' @examples #' IsSparse(matrix()) #' IsSparse(LayerData(pbmc_small, "counts")) #' IsSparse <- function(x) { if (!isS4(x)) { return(FALSE) } classkey <- unlist(x = strsplit( x = ClassKey(class = class(x = x)), split = ':' )) cls <- classkey[[2L]] pkg <- classkey[[1L]] sparse <- cls %in% sparse.classes[[pkg]] if (!sparse) { sparse <- any(sparse.classes[[pkg]] %in% .Contains(object = x)) } return(sparse) } #' Register Sparse Matrix Classes #' #' @inheritParams ClassKey #' #' @return Invisibly returns \code{NULL} #' #' @keywords internal #' #' @export #' #' @family sparse #' RegisterSparseMatrix <- function(class, package = NULL) { classkey <- unlist(x = strsplit( x = ClassKey(class = class, package = package), split = ':' )) sparse.classes[[classkey[[1L]]]] <- unique(c( sparse.classes[[classkey[[1L]]]], classkey[[2L]] )) return(invisible(x = NULL)) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @method .MARGIN CsparseMatrix #' @export #' .MARGIN.CsparseMatrix <- function(x, ...) { return(2L) } #' @method .MARGIN RsparseMatrix #' @export #' .MARGIN.RsparseMatrix <- function(x, ...) { return(1L) } #' @method .MARGIN spam #' @export #' .MARGIN.spam <- .MARGIN.RsparseMatrix #' @rdname dot-SparseSlots #' @method .SparseSlots CsparseMatrix #' @export #' .SparseSlots.CsparseMatrix <- function( x, type = c('pointers', 'entries', 'indices') ) { type <- arg_match(arg = type) return(switch( EXPR = type, 'pointers' = 'p', 'indices' = 'i', 'entries' = 'x' )) } #' @rdname dot-SparseSlots #' @method .SparseSlots RsparseMatrix #' @export #' .SparseSlots.RsparseMatrix <- function( x, type = c('pointers', 'indices', 'entries') ) { type <- arg_match(arg = type) return(switch( EXPR = type, 'pointers' = 'p', 'indices' = 'j', 'entries' = 'x' )) } #' @rdname dot-SparseSlots #' @method .SparseSlots spam #' @export #' .SparseSlots.spam <- function(x, type = c('pointers', 'indices', 'entries')) { check_installed(pkg = 'spam') type <- arg_match(arg = type) return(switch( EXPR = type, 'pointers' = 'rowpointers', 'indices' = 'colindices', 'entries' = 'entries' )) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 Methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SeuratObject/R/dimreduc.R0000644000176200001440000010154315116566601014777 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @include jackstraw.R #' @include keymixin.R #' @importFrom methods new slot slot<- slotNames #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The Dimensional Reduction Class #' #' The DimReduc object stores a dimensionality reduction taken out in Seurat; #' each DimReduc consists of a cell embeddings matrix, a feature loadings #' matrix, and a projected feature loadings matrix. #' #' @slot cell.embeddings Cell embeddings matrix (required) #' @slot feature.loadings Feature loadings matrix (optional) #' @slot feature.loadings.projected Projected feature loadings matrix (optional) #' @slot assay.used Name of assay used to generate \code{DimReduc} object #' @slot global Is this \code{DimReduc} global/persistent? If so, it will not be #' removed when removing its associated assay #' @slot stdev A vector of standard deviations #' @slot jackstraw A \code{\link{JackStrawData-class}} object associated with #' this \code{DimReduc} #' @template slot-misc #' @template slot-key #' #' @exportClass DimReduc #' #' @aliases DimReduc #' #' @family dimreduc #' setClass( Class = 'DimReduc', contains = 'KeyMixin', slots = c( cell.embeddings = 'matrix', feature.loadings = 'matrix', feature.loadings.projected = 'matrix', assay.used = 'character', global = 'logical', stdev = 'numeric', # key = 'character', jackstraw = 'JackStrawData', misc = 'list' ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Create a DimReduc object #' #' @param embeddings A matrix with the cell embeddings #' @param loadings A matrix with the feature loadings #' @param projected A matrix with the projected feature loadings #' @param assay Assay used to calculate this dimensional reduction #' @param stdev Standard deviation (if applicable) for the dimensional reduction #' @param key A character string to facilitate looking up features from a #' specific DimReduc #' @param global Specify this as a global reduction (useful for visualizations) #' @param jackstraw Results from the JackStraw function #' @param misc list for the user to store any additional information associated #' with the dimensional reduction #' #' @return A \code{\link{DimReduc}} object #' #' @aliases SetDimReduction #' #' @export #' #' @family dimreduc #' #' @examples #' data <- GetAssayData(pbmc_small[["RNA"]], layer = "scale.data") #' pcs <- prcomp(x = data) #' pca.dr <- CreateDimReducObject( #' embeddings = pcs$rotation, #' loadings = pcs$x, #' stdev = pcs$sdev, #' key = "PC", #' assay = "RNA" #' ) #' CreateDimReducObject <- function( embeddings = new(Class = 'matrix'), loadings = new(Class = 'matrix'), projected = new(Class = 'matrix'), assay = NULL, stdev = numeric(), key = NULL, global = FALSE, jackstraw = NULL, misc = list() ) { if (is.null(x = assay)) { warn(message = "No assay specified, setting assay as RNA by default.") assay <- 'RNA' } # Try to infer key from column names if (is.null(x = key) && is.null(x = colnames(x = embeddings))) { abort(message = "Please specify a key for the DimReduc object") } else if (is.null(x = key)) { key <- regmatches( x = colnames(x = embeddings), m = regexec(pattern = '^[[:alnum:]]+_', text = colnames(x = embeddings)) ) key <- unique(x = unlist(x = key, use.names = FALSE)) } if (length(x = key) != 1) { abort(message = "Please specify a key for the DimReduc object") } else if (!grepl(pattern = .KeyPattern(), x = key)) { old.key <- key key <- Key(object = key) colnames(x = embeddings) <- gsub( x = colnames(x = embeddings), pattern = old.key, replacement = key ) } # ensure colnames of the embeddings are the key followed by a numeric if (is.null(x = colnames(x = embeddings))) { warn(message = paste0( "No columnames present in cell embeddings, setting to '", key, "1:", ncol(x = embeddings), "'" )) colnames(x = embeddings) <- paste0(key, 1:ncol(x = embeddings)) } else if (!all(grepl(pattern = paste0('^', key, "[[:digit:]]+$"), x = colnames(x = embeddings)))) { digits <- unlist(x = regmatches( x = colnames(x = embeddings), m = regexec(pattern = '[[:digit:]]+$', text = colnames(x = embeddings)) )) if (length(x = digits) != ncol(x = embeddings)) { stop("Please ensure all column names in the embeddings matrix are the key plus a digit representing a dimension number") } colnames(x = embeddings) <- paste0(key, digits) } if (!IsMatrixEmpty(x = loadings)) { if (any(rownames(x = loadings) == '')) { abort(message = "Feature names of loadings matrix cannot be empty") } colnames(x = loadings) <- colnames(x = embeddings) } if (!IsMatrixEmpty(x = projected)) { if (any(rownames(x = loadings) == '')) { abort(message = "Feature names of projected loadings matrix cannot be empty") } colnames(x = projected) <- colnames(x = embeddings) } jackstraw <- jackstraw %||% new(Class = 'JackStrawData') dim.reduc <- new( Class = 'DimReduc', cell.embeddings = embeddings, feature.loadings = loadings, feature.loadings.projected = projected, assay.used = assay, global = global, stdev = stdev, key = key, jackstraw = jackstraw, misc = misc ) return(dim.reduc) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname Cells #' @export #' @method Cells DimReduc #' Cells.DimReduc <- function(x, ...) { return(rownames(x = x)) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay DimReduc #' DefaultAssay.DimReduc <- function(object, ...) { CheckDots(...) return(slot(object = object, name = 'assay.used')) } #' @rdname DefaultAssay #' @export #' @method DefaultAssay<- DimReduc #' "DefaultAssay<-.DimReduc" <- function(object, ..., value) { CheckDots(...) slot(object = object, name = 'assay.used') <- value return(object) } #' @method Features DimReduc #' @export #' Features.DimReduc <- function(x, projected = NULL, ...) { projected <- isTRUE(x = projected %||% Projected(object = x)) features <- rownames(x = Loadings(object = x, projected = projected)) if (!length(x = features)) { features <- NULL } return(features) } #' @rdname FetchData #' @export #' @method FetchData DimReduc #' FetchData.DimReduc <- function( object, vars, cells = NULL, slot = c('embeddings', 'loadings', 'projected'), ... ) { slot <- slot[1L] slot <- match.arg(arg = slot) cells <- cells %||% Cells(x = object) if (is.numeric(x = cells)) { cells <- Cells(x = object)[cells] } pattern <- paste0('^(', Key(object = object), ')?[[:digit:]]+$') vars <- grep(pattern = pattern, x = vars, value = TRUE) if (!length(x = 'vars')) { stop("invalid vars") } vars <- gsub(pattern = Key(object = object), replacement = '', x = vars) vars <- as.integer(x = vars) vars <- paste0(Key(object = object), vars) data <- switch( EXPR = slot, 'embeddings' = Embeddings(object = object), Loadings(object = object, projected = slot == 'projected') ) missing <- setdiff(x = vars, y = colnames(x = data)) if (length(x = missing) == length(x = vars)) { stop("Cannot find any of the requested dimensions") } else if (length(x = missing)) { warning( "Cannot find the following dimensions: ", paste0(missing, collapse = ', '), call. = FALSE, immediate. = TRUE ) vars <- setdiff(x = vars, y = missing) } return(as.data.frame(x = data)[cells, vars, drop = FALSE]) } #' @rdname Embeddings #' @export #' @method Embeddings DimReduc #' #' @examples #' # Get the embeddings directly from a DimReduc object #' Embeddings(object = pbmc_small[["pca"]])[1:5, 1:5] #' Embeddings.DimReduc <- function(object, ...) { CheckDots(...) return(slot(object = object, name = 'cell.embeddings')) } #' @method FetchData DimReduc #' @export #' FetchData.DimReduc <- function( object, vars, cells = NULL, # layer = c('embeddings', 'loadings', 'projected'), # layer = 'embeddings', ... ) { layer <- 'embeddings' layer <- arg_match0(arg = layer, values = 'embeddings') cells <- cells %||% Cells(x = object) if (is.numeric(x = cells)) { cells <- Cells(x = object)[cells] } cells <- intersect(x = cells, y = Cells(x = object)) if (!length(x = cells)) { abort(message = "None of the cells requested found in this dimensional reduction") } key <- Key(object = object) ovars <- vars vars <- grep( pattern = paste0('^(', key, ')?[[:digit:]]+$'), x = vars, value = TRUE ) if (!length(x = vars)) { abort(message = "None of the vars provided are valid for reduced dimensions") } else if (length(x = vars) != length(x = ovars)) { warn(message = paste( "The following requested vars are not valid:", paste(setdiff(x = ovars, y = vars), collapse = ', '), )) } vars <- paste0( key, as.integer(x = gsub(pattern = key, replacement = '', x = vars)) ) data <- switch( EXPR = layer, 'embeddings' = Embeddings(object = object), Loadings(object = object, projected = layer == 'projected') ) missing <- setdiff(x = vars, y = colnames(x = data)) if (length(x = missing) == length(x = vars)) { abort(message = "Cannot find any of the requested dimensions") } else if (length(x = missing)) { warn(message = paste( "Cannot find the following dimensions:", paste0(missing, collapse = ', ') )) vars <- setdiff(x = vars, y = missing) } return(as.data.frame(x = data)[cells, vars, drop = FALSE]) } #' @rdname IsGlobal #' @export #' @method IsGlobal DimReduc #' IsGlobal.DimReduc <- function(object, ...) { object <- UpdateSlots(object = object) return(slot(object = object, name = 'global')) } #' @param slot Name of slot to store JackStraw scores to #' Can shorten to 'empirical', 'fake', 'full', or 'overall' #' #' @rdname JS #' @export #' @method JS DimReduc #' JS.DimReduc <- function(object, slot = NULL, ...) { CheckDots(...) jackstraw <- slot(object = object, name = 'jackstraw') if (!is.null(x = slot)) { jackstraw <- JS(object = jackstraw, slot = slot) } return(jackstraw) } #' @rdname JS #' @export #' @method JS<- DimReduc #' "JS<-.DimReduc" <- function(object, slot = NULL, ..., value) { CheckDots(...) if (inherits(x = value, what = 'JackStrawData')) { slot(object = object, name = 'jackstraw') <- value } else if (is.null(x = NULL)) { stop("A slot must be specified") } else { JS(object = JS(object = object), slot = slot) <- value } return(object) } #' @rdname Key #' @export #' @method Key DimReduc #' #' @examples #' # Get a DimReduc key #' Key(object = pbmc_small[["pca"]]) #' Key.DimReduc <- .Key #' @rdname Key #' @export #' @method Key<- DimReduc #' #' @examples #' # Set the key for DimReduc #' Key(object = pbmc_small[["pca"]]) <- "newkey2_" #' Key(object = pbmc_small[["pca"]]) #' "Key<-.DimReduc" <- function(object, ..., value) { op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op), add = TRUE) old <- Key(object = object) suppressWarnings(expr = object <- NextMethod(), classes = 'validationWarning') for (i in c("cell.embeddings", "feature.loadings", "feature.loadings.projected")) { mat <- slot(object = object, name = i) if (IsMatrixEmpty(x = mat)) { next } colnames(x = mat) <- gsub( pattern = paste0('^', old), replacement = Key(object = object), x = colnames(x = mat) ) slot(object = object, name = i) <- mat } options(op) validObject(object = object) return(object) } #' @param projected Pull the projected feature loadings? #' #' @rdname Loadings #' @export #' @method Loadings DimReduc #' #' @examples #' # Get the feature loadings for a given DimReduc #' Loadings(object = pbmc_small[["pca"]])[1:5,1:5] #' Loadings.DimReduc <- function(object, projected = FALSE, ...) { CheckDots(...) projected <- projected %||% Projected(object = object) slot <- ifelse( test = projected, yes = 'feature.loadings.projected', no = 'feature.loadings' ) return(slot(object = object, name = slot)) } #' @rdname Loadings #' @export #' @method Loadings<- DimReduc #' #' @examples #' # Set the feature loadings for a given DimReduc #' new.loadings <- Loadings(object = pbmc_small[["pca"]]) #' new.loadings <- new.loadings + 0.01 #' Loadings(object = pbmc_small[["pca"]]) <- new.loadings #' "Loadings<-.DimReduc" <- function(object, projected = TRUE, ..., value) { CheckDots(...) slot.use <- ifelse( test = projected, yes = 'feature.loadings.projected', no = 'feature.loadings' ) if (ncol(x = value) != length(x = object)) { stop("New feature loadings must have the dimensions as currently calculated") } slot(object = object, name = slot.use) <- value return(object) } #' @rdname Misc #' @export #' @method Misc DimReduc #' Misc.DimReduc <- .Misc #' @rdname Misc #' @export #' @method Misc<- DimReduc #' "Misc<-.DimReduc" <- `.Misc<-` #' @rdname RenameCells #' @export #' @method RenameCells DimReduc #' #' @examples #' # Rename cells in a DimReduc #' head(x = Cells(x = pbmc_small[["pca"]])) #' renamed.dimreduc <- RenameCells( #' object = pbmc_small[["pca"]], #' new.names = paste0("A_", Cells(x = pbmc_small[["pca"]])) #' ) #' head(x = Cells(x = renamed.dimreduc)) #' RenameCells.DimReduc <- function(object, new.names = NULL, ...) { CheckDots(...) old.data <- Embeddings(object = object) rownames(x = old.data) <- new.names slot(object = object, name = "cell.embeddings") <- old.data validObject(object = object) return(object) } #' @rdname Stdev #' @export #' @method Stdev DimReduc #' #' @examples #' # Get the standard deviations for each PC from the DimReduc object #' Stdev(object = pbmc_small[["pca"]]) #' Stdev.DimReduc <- function(object, ...) { CheckDots(...) return(slot(object = object, name = 'stdev')) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Get Feature Loadings #' #' Pull feature loadings from a \link[=DimReduc]{dimensional reduction} #' #' \code{[} does not distinguish between projected and unprojected feature #' loadings; to select whether projected or unprojected loadings should be #' pulled, please use \code{\link{Loadings}} #' #' @param x A \code{\link{DimReduc}} object #' @param i Feature identifiers or indices #' @param j Dimension identifiers or indices #' @param drop Coerce the result to the lowest possible dimension; see #' \code{\link{drop}} for further details #' @template param-dots-method #' #' @return Feature loadings for features \code{i} and dimensions \code{j} #' #' @method [ DimReduc #' @export #' #' @family dimreduc #' #' @seealso \code{\link{Loadings}} #' #' @examples #' pca <- pbmc_small[["pca"]] #' pca[1:10, 1:5] #' "[.DimReduc" <- function(x, i, j, drop = FALSE, ...) { loadings <- Loadings(object = x) if (missing(x = i)) { i <- 1:nrow(x = loadings) } if (missing(x = j)) { j <- names(x = x) } else if (is.numeric(x = j)) { j <- names(x = x)[j] } bad.j <- j[!j %in% colnames(x = loadings)] j <- j[!j %in% bad.j] if (length(x = j) == 0) { stop("None of the requested loadings are present.") } if (length(x = bad.j) > 0) { warning( "The following loadings are not present: ", paste(bad.j, collapse = ", ") ) } return(Loadings(object = x)[i, j, drop = drop, ...]) } #' Get Cell Embeddings #' #' Pull cell embeddings from a \link[=DimReduc]{dimensional reduction} #' #' @inheritParams [.DimReduc #' @param i Cell names or indices #' #' @return Cell embeddings for cells \code{i} and dimensions \code{j} #' #' @method [[ DimReduc #' @export #' #' @family dimreduc #' #' @seealso \code{\link{Embeddings}} #' #' @examples #' pca <- pbmc_small[["pca"]] #' pca[[1:10, 1:5]] #' "[[.DimReduc" <- function(x, i, j, drop = FALSE, ...) { if (missing(x = i)) { i <- 1:nrow(x = x) } if (missing(x = j)) { j <- names(x = x) } else if (is.numeric(x = j)) { j <- names(x = x)[j] } embeddings <- Embeddings(object = x) bad.j <- j[!j %in% colnames(x = embeddings)] j <- j[!j %in% bad.j] if (length(x = j) == 0) { stop("None of the requested embeddings are present.") } if (length(x = bad.j) > 0) { warning( "The following embeddings are not present: ", paste(bad.j, collapse = ", ") ) } return(embeddings[i, j, drop = drop, ...]) } #' Dimensional Reduction Meta-Information #' #' Pull meta-information about cells and dimensions for a given #' \link[=DimReduc]{dimensional reduction}; cell meta-information is stored #' as row meta-information (eg. \code{nrow}, \code{rownames}) and dimension #' meta-information is stored as column meta-information (eg. \code{ncol}, #' \code{colnames}) #' #' @inheritParams [.DimReduc #' #' @return \code{dim}: The number of cells (\code{nrow}) and dimensions #' (\code{ncol}) #' #' @method dim DimReduc #' @export #' #' @family dimreduc #' #' @examples #' pca <- pbmc_small[["pca"]] #' pca #' dim(pca) #' #' # nrow is number of cells #' nrow(pca) #' #' # rownames pulls cell names #' head(rownames(pca)) #' #' # ncol and length are number of dimensions #' ncol(pca) #' length(pca) #' #' # colnames and names pull dimension identifiers #' head(colnames(pca)) #' head(names(pca)) #' dim.DimReduc <- function(x) { return(dim(x = Embeddings(object = x))) } #' @return \code{dimnames}: The cell (row) and dimension (column) names #' #' @rdname dim.DimReduc #' #' @method dimnames DimReduc #' @export #' #' @seealso \code{Cells} #' dimnames.DimReduc <- function(x) { return(dimnames(x = Embeddings(object = x))) } #' @return \code{length}: The number of dimensions #' #' @rdname dim.DimReduc #' #' @export #' @method length DimReduc #' length.DimReduc <- function(x) { return(ncol(x = x)) } #' Merge Dimensional Reductions #' #' Merge two or more \link[=DimReduc]{dimensional reduction} together #' #' @inheritParams [.DimReduc #' @inheritParams merge.Assay5 #' @param y One or more \code{\link{DimReduc}} objects #' @template param-dots-ignored #' #' @return A new \code{DimReduc} object with data merged from \code{c(x, y)} #' #' @method merge DimReduc #' @export #' #' @family dimreduc #' merge.DimReduc <- function( x = NULL, y = NULL, add.cell.ids = NULL, ... ) { CheckDots(...) drs <- c(x, y) if (!is.null(x = add.cell.ids)) { add.cell.ids <- unique(x = add.cell.ids) if (!is_bare_character(x = add.cell.ids, n = length(x = drs))) { abort( message = "'add.cell.ids' must be unique for every dimensional reduction" ) } for (i in seq_along(along.with = drs)) { drs[[i]] <- RenameCells(object = drs[[i]], new.names = add.cell.ids[i]) } } all.cells <- unlist(x = lapply(X = drs, FUN = Cells)) if (anyDuplicated(x = all.cells)) { abort(message = "Duplicate cells in provided dimensional reductions") } embeddings.mat <- lapply(X = drs, FUN = Embeddings) min.dim <- vapply( X = embeddings.mat, FUN = ncol, FUN.VALUE = integer(length = 1L), USE.NAMES = FALSE ) # embeddings.mat <- list() # min.dim <- c() # for (i in 1:length(x = drs)) { # embeddings.mat[[i]] <- Embeddings(object = drs[[i]]) # min.dim <- c(min.dim, ncol(x = embeddings.mat[[i]])) # } if (length(x = unique(x = min.dim)) > 1) { min.dim <- min(min.dim) warn(message = paste( "Reductions contain differing numbers of dimensions, merging first", min.dim )) # warning( # "Reductions contain differing numbers of dimensions, merging first ", # min.dim, # call. = FALSE, # immediate. = TRUE # ) embeddings.mat <- lapply( X = embeddings.mat, FUN = function(x) { return(x[, 1:min.dim]) } ) } embeddings.mat <- do.call(what = rbind, args = embeddings.mat) merged.dr <- CreateDimReducObject( embeddings = embeddings.mat, loadings = Loadings(object = drs[[1]], projected = FALSE), projected = Loadings(object = drs[[1]], projected = TRUE), assay = DefaultAssay(object = drs[[1]]), key = Key(object = drs[[1]]), global = IsGlobal(object = drs[[1]]) ) return(merged.dr) } #' @return \code{names}: The dimension identifiers #' #' @rdname dim.DimReduc #' #' @method names DimReduc #' @export #' names.DimReduc <- function(x) { # return(colnames(x = Embeddings(object = x))) return(colnames(x = x)) } #' Print Top Feature Loadings #' #' Prints a set of features that most strongly define a set of components; #' \strong{note}: requires feature loadings to be present in order to work #' #' @inheritParams [.DimReduc #' @param dims Number of dimensions to display #' @param nfeatures Number of genes to display #' @param projected Use projected slot #' @template param-dots-ignored #' #' @return Displays set of features defining the components and #' invisibly returns \code{x} #' #' @method print DimReduc #' @export #' #' @aliases print #' #' @family dimreduc #' #' @seealso \code{\link[base]{cat}} #' #' @examples #' pca <- pbmc_small[["pca"]] #' print(pca) #' print.DimReduc <- function( x, dims = 1:5, nfeatures = 20, projected = FALSE, ... ) { CheckDots(...) loadings <- Loadings(object = x, projected = projected) if (!IsMatrixEmpty(x = loadings)) { nfeatures <- min(nfeatures, nrow(x = loadings)) if (ncol(x = loadings) == 0) { warning("Dimensions have not been projected. Setting projected = FALSE") projected <- FALSE loadings <- Loadings(object = x, projected = projected) } if (min(dims) > ncol(x = loadings)) { stop("Cannot print dimensions greater than computed") } if (max(dims) > ncol(x = loadings)) { warning("Only ", ncol(x = loadings), " dimensions have been computed.") dims <- intersect(x = dims, y = seq_len(length.out = ncol(x = loadings))) } for (dim in dims) { features <- Top( data = loadings[, dim, drop = FALSE], num = nfeatures * 2, balanced = TRUE ) cat(Key(object = x), dim, '\n') pos.features <- split( x = features$positive, f = ceiling(x = seq_along(along.with = features$positive) / 10) ) cat("Positive: ", paste(pos.features[[1]], collapse = ", "), '\n') pos.features[[1]] <- NULL if (length(x = pos.features) > 0) { for (i in pos.features) { cat("\t ", paste(i, collapse = ", "), '\n') } } neg.features <- split( x = features$negative, f = ceiling(x = seq_along(along.with = features$negative) / 10) ) cat("Negative: ", paste(neg.features[[1]], collapse = ", "), '\n') neg.features[[1]] <- NULL if (length(x = neg.features) > 0) { for (i in neg.features) { cat("\t ", paste(i, collapse = ", "), '\n') } } } } return(invisible(x = x)) } #' Subset a Dimensional Reduction #' #' Subset a \code{\link{DimReduc}} object #' #' @inheritParams [.DimReduc #' @param cells,features Cells and features to keep during the subset #' @template param-dots-ignored #' #' @return \code{x} for cells \code{cells} and features \code{features} #' #' @method subset DimReduc #' @export #' #' @family dimreduc #' subset.DimReduc <- function(x, cells = NULL, features = NULL, ...) { CheckDots(...) cells <- Cells(x = x) %iff% cells %||% Cells(x = x) if (all(is.na(x = cells))) { cells <- Cells(x = x) } else if (any(is.na(x = cells))) { warn(message = "NAs passed in cells vector, removing NAs") cells <- na.omit(object = cells) } # features <- rownames(x = x) %iff% features %||% rownames(x = x) features <- rownames(x = Loadings(object = x)) %iff% features %||% rownames(x = Loadings(object = x)) if (all(sapply(X = list(features, cells), FUN = length) == dim(x = x))) { return(x) } slot(object = x, name = 'cell.embeddings') <- if (is.null(x = cells)) { new(Class = 'matrix') } else { if (is.numeric(x = cells)) { cells <- Cells(x = x)[cells] } cells <- intersect(x = Cells(x = x), y = cells) if (length(x = cells) == 0) { stop("Cannot find cell provided", call. = FALSE) } x[[cells, , drop = FALSE]] } slot(object = x, name = 'feature.loadings') <- if (is.null(x = features)) { new(Class = 'matrix') } else { if (is.numeric(x = features)) { features <- rownames(x = x)[features] } features.loadings <- intersect( x = rownames(x = Loadings(object = x, projected = FALSE)), y = features ) if (length(x = features.loadings) == 0) { stop("Cannot find features provided", call. = FALSE) } Loadings(object = x, projected = FALSE)[features.loadings, , drop = FALSE] } slot(object = x, name = 'feature.loadings.projected') <- if (is.null(x = features) || !Projected(object = x)) { new(Class = 'matrix') } else { features.projected <- intersect( x = rownames(x = Loadings(object = x, projected = TRUE)), y = features ) if (length(x = features.projected) == 0) { stop("Cannot find features provided", call. = FALSE) } Loadings(object = x, projected = TRUE)[features.projected, , drop = FALSE] } slot(object = x, name = 'jackstraw') <- new(Class = 'JackStrawData') return(x) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .RenameFeatures <- function(object, old.names = NULL, new.names = NULL) { if (is.null(x = old.names) && is.null(x = new.names)) { return(object) } # Checks op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op)) stopifnot(length(x = old.names) == length(x = new.names)) stopifnot(all(nzchar(x = old.names))) stopifnot(all(nzchar(x = new.names))) if (is.null(x = Features(x = object)) && length(x = new.names)) { warning("No features present in this DimReduc", call. = FALSE, immediate. = TRUE) } # Rename features names(x = new.names) <- old.names features <- Features(x = object, projected = FALSE) ldat <- Loadings(object = object, projected = FALSE) rownames(x = ldat) <- unname(obj = new.names[features]) Loadings(object = object, projected = FALSE) <- ldat if (isTRUE(x = Projected(object = object))) { pdat <- Loadings(object = object, projected = TRUE) pfeatures <- Features(x = object, projected = TRUE) rownames(x = pdat) <- unname(obj = new.names[pfeatures]) Loadings(object = object, projected = TRUE) <- pdat } # Validate and return options(op) validObject(object = object) return(object) } #' Check to see if projected loadings have been set #' #' @param object a DimReduc object #' #' @return TRUE if projected loadings have been set, else FALSE #' #' @keywords internal #' #' @noRd #' Projected <- function(object) { return(!IsMatrixEmpty(x = Loadings(object = object, projected = TRUE))) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Dimensional Reduction Overview #' #' Overview of a \code{\link{DimReduc}} object #' #' @param object A dimensional reduction #' #' @template return-show #' #' @keywords internal #' #' @seealso \code{\link{DimReduc}} #' #' @examples #' pca <- pbmc_small[["pca"]] #' pca #' setMethod( f = 'show', signature = 'DimReduc', definition = function(object) { cat( "A dimensional reduction object with key", Key(object = object), '\n', 'Number of dimensions:', length(x = object), '\n', 'Number of cells:', length(x = Cells(x = object)), '\n', 'Projected dimensional reduction calculated: ', Projected(object = object), '\n', 'Jackstraw run:', as.logical(x = JS(object = object)), '\n', 'Computed using assay:', DefaultAssay(object = object), '\n' ) return(invisible(x = NULL)) } ) #' Dimensional Reduction Validity #' #' @templateVar cls DimReduc #' @template desc-validity #' #' @section Cell Embeddings Validation: #' The cell embeddings matrix must be a numeric matrix of dimensions #' \eqn{n_{cells}} by \eqn{d_{dimensions}}; row names must be the cell names #' and column names must be the dimension identifier. The dimension identifier #' must be \dQuote{\code{key_dimension}} (eg. \dQuote{\code{PC_1}}). Dimension #' identifiers must be in order and cannot be skipped #' #' @section Feature and Projected Feature Loadings Validation: #' blah #' #' @inheritSection Key-validity Key Validation #' #' @section Standard Deviations Validation: #' blah #' #' @name DimReduc-validity #' #' @family dimreduc #' setValidity( Class = 'DimReduc', method = function(object) { if (.GetSeuratCompat() < '5.0.0') { return(TRUE) } if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL ValidColnames <- function( mat, ref = NULL, type = c('embeddings', 'loadings', 'projected') ) { ret <- NULL if (IsMatrixEmpty(x = mat)) { return(ret) } type <- match.arg(arg = type) type <- switch( EXPR = type, embeddings = 'cell.embeddings', loadings = 'feature.loadings', projected = 'feature.loadings.projected' ) mat.names <- colnames(x = mat) key <- paste0('^', Key(object = object)) if (is.null(x = mat.names)) { ret <- c(ret, paste("colnames must be present in", sQuote(x = type))) } else if (!all(grepl(pattern = key, x = mat.names))) { ret <- c( ret, paste( "colnames for", sQuote(x = type), "must start with reduction key", paste0("(", Key(object = object), ")") ) ) } else { dims <- as.numeric(x = gsub(pattern = key, replacement = '', x = mat.names)) if (!is_bare_integerish(x = dims, n = ncol(x = mat), finite = TRUE) || any(dims < 1L)) { ret <- c( ret, paste( "dimension names for", sQuote(x = type), "must be positive integers" ) ) } else if (is.unsorted(x = dims)) { ret <- c( ret, paste("dimensions for", sQuote(x = type), "must be in order") ) } } if (!is.null(x = ref)) { if (length(x = mat.names) != length(x = ref)) { ret <- c( ret, paste(sQuote(x = type), "must have", length(x = ref), "dimensions") ) } else if (!all(mat.names == ref)) { ret <- c( ret, paste( "dimensions in", sQuote(x = type), "do not match dimensions in reduction" ) ) } } return(ret) } # Validate cell embeddings emb <- Embeddings(object = object) if (!is.numeric(x = emb)) { valid <- c(valid, "'cell.embeddings' must be a numeric matrix") } if (is.null(x = rownames(x = emb)) || !all(nzchar(x = rownames(x = emb)))) { valid <- c(valid, "rownames must be present in 'cell.embeddings'") } valid <- c(valid, ValidColnames(mat = emb, type = 'embeddings')) if (!is.null(x = valid)) { return(valid) } dims <- colnames(x = emb) # if (is.null(x = colnames(x = emb))) { # valid <- c(valid, "colnames must be present in 'cell.embeddings'") # } else { # emb.names <- colnames(x = emb) # if (!all(grepl(pattern = paste0('^', Key(object = object)), x = emb.names))) { # valid <- c( # valid, # paste0( # "colnames for 'cell.embeddings' must start with reduction key (", # Key(object = object), # ")" # ) # ) # } # } # if (!is.null(x = valid)) { # return(valid) # } # TODO: Validate feature loadings lds <- Loadings(object = object, projected = FALSE) valid <- c(valid, ValidColnames(mat = lds, type = 'loadings')) # TODO: Validate projected loadings prj <- Loadings(object = object, projected = TRUE) valid <- c(valid, ValidColnames(mat = prj, type = 'projected')) # TODO: Validate assay used if (!rlang::is_scalar_character(x = DefaultAssay(object = object))) { valid <- c(valid, "'assay.orig' must be a 1-length character") } # Validate globalness if (!rlang::is_scalar_logical(x = IsGlobal(object = object))) { valid <- c(valid, "'global' must be a 1-length logical") } else if (is_na(x = IsGlobal(object = object))) { valid <- c(valid, "'global' must be TRUE or FALSE") } # TODO: Validate standard deviations # TODO: Validate JackStraw data # TODO: Validate misc return(valid %||% TRUE) } ) SeuratObject/R/utils.R0000644000176200001440000021457115116566601014351 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @include centroids.R #' @include segmentation.R #' @importFrom Rcpp evalCpp #' @importFrom methods as setAs #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Set If or If Not \code{NULL} #' #' Set a default value depending on if an object is \code{NULL} #' #' @usage x \%||\% y #' #' @param x An object to test #' @param y A default value #' #' @return For \code{\%||\%}: \code{y} if \code{x} is \code{NULL}; #' otherwise \code{x} #' #' @name set-if-null #' @rdname set-if-null #' #' @author For \code{\%||\%}: \pkg{rlang} developers #' #' @seealso \code{\link[rlang:op-null-default]{rlang::\%||\%}} #' #' @aliases %||% #' #' @concept utils #' #' @examples #' # Set if NULL #' 1 %||% 2 #' NULL %||% 2 #' NULL #' @importFrom rlang %||% #' @export #' #' @noRd #' rlang::`%||%` #' @rdname set-if-null #' #' @return For \code{\%iff\%}: \code{y} if \code{x} is \strong{not} #' \code{NULL}; otherwise \code{x} #' #' @importFrom rlang is_null #' #' @export #' #' @examples #' # Set if *not* NULL #' 1 %iff% 2 #' NULL %iff% 2 #' `%iff%` <- function(x, y) { if (!is_null(x = x)) { return(y) } return(x) } #' Set If or If Not \code{NA} #' #' Set a default value depending on if an object is \code{\link[base]{NA}} #' #' @inheritParams set-if-null #' #' @return For \code{\%NA\%}: \code{y} if \code{x} is \code{\link[base]{NA}}; #' otherwise \code{x} #' #' @name set-if-na #' @rdname set-if-na #' #' @importFrom rlang is_na #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' # Set if NA #' 1 %NA% 2 #' NA %NA% 2 #' `%NA%` <- function(x, y) { if (is_na(x = x)) { return(y) } return(x) } #' @rdname set-if-na #' #' @export #' `%na%` <- `%NA%` #' @return For \code{\%!NA\%}: \code{y} if \code{x} is \strong{not} #' \code{\link[base]{NA}}; otherwise \code{x} #' #' @rdname set-if-na #' #' @importFrom rlang is_na #' #' @export #' #' @examples #' # Set if *not* NA #' 1 %!NA% 2 #' NA %!NA% 2 #' `%!NA%` <- function(x, y) { if (is_na(x = x)) { return(x) } return(y) } #' @rdname set-if-na #' #' @export #' `%!na%` <- `%!NA%` #' \pkg{BPCells} Matrix Mode #' #' Get the mode (on-disk, in-memory) of an \code{IterableMatrix} object #' from \pkg{BPCells} #' #' @param object An \code{IterableMatrix} #' @param simplify Return \dQuote{\code{disk}} for on-disk matrices #' #' @return One of the following, depending on the mode of \code{object}: #' \itemize{ #' \item \dQuote{\code{memory}} #' \item \dQuote{\code{file}} #' \item \dQuote{\code{directory}} #' } #' If \code{simplify} is \code{TRUE}, returns \dQuote{\code{disk}} instead of #' \dQuote{\code{file}} or \dQuote{\code{directory}} #' #' @keywords internal #' #' @export #' .BPMatrixMode <- function(object, simplify = FALSE) { check_installed(pkg = 'BPCells', reason = 'for working with BPCells') if (!inherits(x = object, what = 'IterableMatrix')) { return(NULL) } stopifnot(rlang::is_bare_logical(x = simplify, n = 1L)) # Get a vector of all the slots in all sub-matrices slots <- Reduce( f = union, x = lapply( X = BPCells::all_matrix_inputs(object), FUN = \(x) methods::slotNames(x = methods::getClass(Class = class(x = x))) ) ) # Figure out if any sub-matrix points to a directory or a file path type <- c(path = FALSE, dir = FALSE) for (s in slots) { if (s %in% names(x = type)) { type[s] <- TRUE } } # If no matrix points to a directory or file, it's an in-memory one if (!any(type)) { return('memory') } # If any matrix points to a directory or file, it's an on-disk matrix if (isTRUE(x = simplify) && any(type)) { return("disk") } # Get the exact type; there should only be one return(c(path = 'file', dir = 'directory')[[names(x = type)[type]]]) } #' Identify Object Collections #' #' Find all collection (named lists) slots in an S4 object #' #' @inheritParams .Contains #' @param exclude A character vector of slot names to exclude #' @param ... Arguments passed to \code{\link{IsNamedList}} #' #' @return A character vector of names of collection slots #' #' @importFrom methods slotNames #' #' @keywords internal #' #' @export #' #' @family subobjects #' @concept utils #' #' @examples #' .Collections(pbmc_small) #' .Collections <- function(object, exclude = character(length = 0L), ...) { if (!isS4(object)) { abort(message = "'object' is not an S4 object") } collections <- slotNames(x = object) collections <- Filter( f = function(s) { return(IsNamedList(x = slot(object = object, name = s), ...)) }, x = collections ) if (is.character(x = exclude) && length(x = exclude)) { collections <- setdiff(x = collections, y = exclude) } return(collections) } #' Get Parent S4 Classes #' #' @param object An \link[methods:Classes_Details]{S4} object #' #' @return A vector of class names that \code{object} inherits from #' #' @importFrom methods getClass slot #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' .Contains(pbmc_small) #' .Contains <- function(object) { if (!isS4(object)) { abort(message = "'object' not an S4 object") } return(names(x = slot( object = getClass(Class = class(x = object)), name = 'contains' ))) } #' Find the Default FOV #' #' Attempts to find the \dQuote{default} FOV using the revamped #' spatial framework #' #' @param object A \code{{Seurat}} object #' #' @return ... #' #' @keywords internal #' #' @export #' #' @concept utils #' .DefaultFOV <- function(object, assay = NULL) { images <- .FilterObjects(object = object, classes.keep = 'FOV') if (!is.null(x = assay)) { assays <- c(assay, DefaultAssay(object = object[[assay]])) images <- Filter( f = function(x) { return(DefaultAssay(object = object[[x]]) %in% assays) }, x = images ) } if (!length(x = images)) { return(NULL) } return(images) } #' Deprecate Functions and Arguments #' #' Provides automatic deprecation and defunctation of functions and arguments; #' #' @inheritParams lifecycle::deprecate_soft #' @inheritDotParams lifecycle::deprecate_soft #' @param pkg Name of package to use for comparison #' @param env,user_env Managed internally by \code{.Deprecate()} #' #' @return Run for its side effect and invisibly returns \code{NULL} #' #' @importFrom rlang ns_env_name #' @importFrom utils packageVersion #' @importFrom lifecycle deprecate_soft deprecate_stop deprecate_warn #' #' @keywords internal #' #' @export #' #' @seealso \code{\link[lifecycle:deprecate_soft]{lifecycle::deprecate_soft}()} #' \code{\link[lifecycle:deprecate_warn]{lifecycle::deprecate_warn}()} #' \code{\link[lifecycle:deprecate_stop]{lifecycle::deprecate_stop}()} #' .Deprecate <- function( when, what, with = NULL, ..., pkg = NULL, env = missing_arg(), user_env = missing_arg() ) { # Figure out current version, rounding up development versions caller <- caller_env() current <- .RoundVersion(current = packageVersion( pkg = ns_env_name(x = caller) )) cv <- paste(current, collapse = '.') # Ensure our 'when' is a valid version wv <- when <- as.character(x = numeric_version(x = when, strict = TRUE)) # If we haven't reached deprecation, exit out silently if (cv < wv) { return(invisible(x = NULL)) } # Figure out if this is a soft deprecation, a warning deprecation, or a defunct when <- unlist(x = strsplit(x = when, split = '\\.')) if (length(x = when) > 4L) { when[4L] <- paste( when[seq.int(from = 4L, to = length(x = when))], collapse = '.' ) when <- when[1:4] } names(x = when) <- c('major', 'minor', 'patch', 'devel')[seq_along(along.with = when)] when <- vapply( X = when, FUN = as.integer, FUN.VALUE = integer(length = 1L), USE.NAMES = TRUE ) diffs <- abs(current - when) if (diffs['major'] >= 1L || diffs['minor'] >= 3L) { deprecate_stop( when = wv, what = what, with = with, env = caller, ... ) } fn <- if (diffs['minor'] >= 1L) { deprecate_warn } else { deprecate_soft } fn( when = wv, what = what, with = with, env = caller, user_env = caller_env(n = 2L), ... ) return(invisible(x = NULL)) } #' Find Subobjects Of A Certain Class #' #' @inheritParams .Collections #' @param classes.keep A vector of classes to keep #' #' @return A vector of object names that are of class \code{classes.keep} #' #' @keywords internal #' #' @export #' #' @family subobjects #' @concept utils #' #' @examples #' .FilterObjects(pbmc_small) #' .FilterObjects(pbmc_small, "Graph") #' .FilterObjects <- function( object, classes.keep = c('Assay', 'StdAssay', 'DimReduc') ) { collections <- .Collections(object = object, exclude = c('misc', 'tools')) subobjects <- unlist(x = lapply( X = collections, FUN = function(x) { return(Filter( f = function(i) { return(inherits( x = slot(object = object, name = x)[[i]], what = classes.keep )) }, x = names(x = slot(object = object, name = x)) )) } )) if (!length(x = subobjects)) { subobjects <- NULL } return(subobjects) } #' Find A Subobject #' #' Determine the slot that a subobject is contained in #' #' @inheritParams .Collections #' @param name Name of subobject to find #' #' @return The name of the slot that contains \code{name}; returns \code{NULL} #' if a subobject named \code{name} cannot be found #' #' @keywords internal #' #' @export #' #' @family subobjects #' @concept utils #' #' @examples #' .FindObject(pbmc_small, "tsne") #' .FindObject <- function(object, name, exclude = c('misc', 'tools')) { collections <- .Collections(object = object, exclude = exclude) object.names <- sapply( X = collections, FUN = function(x) { return(names(x = slot(object = object, name = x))) }, simplify = FALSE, USE.NAMES = TRUE ) object.names <- Filter(f = Negate(f = is.null), x = object.names) for (i in names(x = object.names)) { if (name %in% names(x = slot(object = object, name = i))) { return(i) } } return(NULL) } #' Get a Method #' #' @param fxn Name of a function as a character #' @param cls The class to find a method of \code{fxn} for #' #' @return The method of \code{fxn} for class \code{cls}; if no method found, #' returns the default method. If no default method found; returns \code{NULL} #' #' @importFrom utils getS3method isS3stdGeneric #' @importFrom methods isClass isGeneric selectMethod #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' .GetMethod('t', 'Matrix') #' .GetMethod('t', 'data.frame') #' .GetMethod <- function(fxn, cls) { if (is.function(x = fxn)) { fxn <- as.character(x = substitute(expr = fxn)) } if (!(isS3stdGeneric(f = fxn) || isGeneric(f = fxn))) { abort(message = paste0("'", fxn, "' is not a generic function")) } default <- NULL if (isGeneric(f = fxn) && isClass(Class = cls[1L])) { method <- selectMethod(f = fxn, signature = cls) if (!inherits(x = method, what = 'derivedDefaultMethod')) { return(slot(object = method, name = '.Data')) } default <- slot(object = method, name = '.Data') } method <- NULL for (i in c(cls, 'default')) { method <- getS3method(f = fxn, class = i, optional = TRUE) if (!is.null(x = method)) { break } } method <- method %||% default if (is.null(x = method)) { abort(message = paste0( "Unable to find a method for '", fxn, "' for '", cls[1L], "' objects" )) } return(method) } #' Propagate a List #' #' @param x A list or character vector #' @param names A vector of names to keep from \code{x} #' @param default A default value for unassigned values of \code{x} #' #' @return A named list where the names are present in both \code{x} and #' \code{names} and the values are either the values from \code{x} or #' \code{default} #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' .PropagateList("counts", c("RNA", "ADT", "SCT")) #' .PropagateList(c("counts", "data"), c("RNA", "ADT", "SCT")) #' .PropagateList("ADT", c("RNA", "ADT", "SCT")) #' .PropagateList(c("RNA", "SCT"), c("RNA", "ADT", "SCT")) #' .PropagateList(c("RNA", ADT = "counts"), c("RNA", "ADT", "SCT")) #' .PropagateList(list(SCT = c("counts", "data"), ADT = "counts"), c("RNA", "ADT", "SCT")) #' .PropagateList(list(SCT = c("counts", "data"), "ADT"), c("RNA", "ADT", "SCT")) #' .PropagateList <- function(x, names, default = NA) { # `names` must be a character vector if (!is_bare_character(x = names)) { abort(message = "'names' must be a character vector") } # `x` must be a list or character vector if (!(is_bare_list(x = x) || is_bare_character(x = x))) { abort(message = "'x' must be either a list or character vector") } # `x` cannot be empty if (!length(x = x)) { abort(message = "'x' cannot be empty") } # `x` is a character vector if (is_bare_character(x = x)) { if (!all(nzchar(x = x))) { abort(message = "'x' cannot be empty") } # Handle cases where `x` is unnamed if (!any(have_name(x = x))) { # `x` is a vector with values in `names` # Return a list for every value in `x` that's present in `names` # with a value of `default` if (any(x %in% names)) { x <- intersect(x = x, y = names) ret <- vector(mode = 'list', length = length(x = x)) names(x = ret) <- x for (i in seq_along(along.with = ret)) { ret[[i]] <- default } return(ret) } # `x` is a vector of default values # Return a list for every value in `names` with a value of `x` ret <- vector(mode = 'list', length = length(x = names)) names(x = ret) <- names for (i in seq_along(along.with = ret)) { ret[[i]] <- unique(x = x) } return(ret) } # `x` is named # Turn `x` into a list and continue on x <- as.list(x = x) } # `x` is a list # Find entries of `x` that correspond to a value in `names` # Assign new value of `default` for (i in seq_along(along.with = x)) { if (is_scalar_character(x = x[[i]]) && x[[i]] %in% names) { names(x = x)[i] <- x[[i]] x[[i]] <- default } } # Identify values of `x` in `names` x.use <- intersect(x = names(x = x), y = names) if (!length(x = x.use) && is_named(x = x)) { abort(message = "None of the values of 'x' match with 'names") } #`Return only values of `x` that are in `names`` return(x[x.use]) } #' Get the Subobject Names #' #' @inheritParams .Collections #' @param collapse Collapse the list into a vector #' #' @return If \code{collapse = TRUE}, then a vector with the names of all #' subobjects; otherwise, a named list where the names are the names of the #' collections and the values are the names of subobjects within the collection #' #' @keywords internal #' #' @export #' #' @family subobjects #' @keywords utils #' #' @examples #' .Subobjects(pbmc_small) #' .Subobjects <- function( object, exclude = c('misc', 'tools'), collapse = TRUE, ... ) { subobjects <- sapply( X = .Collections(object = object, exclude = exclude, ...), FUN = function(x) { return(names(x = slot(object = object, name = x))) }, simplify = FALSE, USE.NAMES = TRUE ) if (isTRUE(x = collapse)) { subobjects <- unlist(x = subobjects, use.names = FALSE) } return(subobjects) } #' Attach Required Packages #' #' Helper function to attach required packages. Detects if a package is already #' attached and if so, skips it. Should be called in \code{\link[base]{.onAttach}} #' #' @param deps A character vector of packages to attach #' #' @template return-null #' #' @export #' #' @concept utils #' #' @template lifecycle-superseded #' @section Lifecycle: #' \code{AttachDeps} has been superseded as of \pkg{SeuratObject} v5.0.0; #' as an alternative, list dependencies in the \code{Depends} section of #' \code{DESCRIPTION} #' #' @examples #' # Use in your .onAttach hook #' if (FALSE) { #' .onAttach <- function(libname, pkgname) { #' AttachDeps(c("SeuratObject", "rlang")) #' } #' } #' AttachDeps <- function(deps) { for (d in deps) { if (!paste0('package:', d) %in% search()) { packageStartupMessage("Attaching ", d) attachNamespace(ns = d) } } return(invisible(x = NULL)) } #' Check the Use of Dots #' #' Function to check the use of unused arguments passed to \code{...}; this #' function is designed to be called from another function to see if an #' argument passed to \code{...} remains unused and alert the user if so. Also #' accepts a vector of function or function names to see if \code{...} can be #' used in a downstream function #' #' Behavior of \code{CheckDots} can be controlled by the following option(s): #' \describe{ #' \item{\dQuote{\code{Seurat.checkdots}}}{Control how to alert the presence #' of unused arguments in \code{...}; choose from #' \itemize{ #' \item \dQuote{\code{warn}}: emit a warning (default) #' \item \dQuote{\code{error}}: throw an error #' \item \dQuote{\code{silent}}: no not alert the presence of unused #' arguments in \code{...} #' } #' } #' } #' #' @param ... Arguments passed to a function that fall under \code{...} #' @param fxns A list/vector of functions or function names #' #' @return Emits either an error or warning if an argument passed is unused; #' invisibly returns \code{NULL} #' #' @importFrom utils isS3stdGeneric methods argsAnywhere isS3method #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' \dontrun{ #' f <- function(x, ...) { #' CheckDots(...) #' return(x ^ 2) #' } #' f(x = 3, y = 9) #' } #' CheckDots <- function(..., fxns = NULL) { args.names <- names(x = list(...)) if (length(x = list(...)) == 0) { return(invisible(x = NULL)) } if (is.null(x = args.names)) { abort(message = "No named arguments passed") } if (length(x = fxns) == 1) { fxns <- list(fxns) } for (f in fxns) { if (!(is.character(x = f) || is.function(x = f))) { abort(message = paste( "CheckDots only works on characters or functions, not", class(x = f)[1L] )) } } fxn.args <- suppressWarnings(expr = sapply( X = fxns, FUN = function(x) { x <- tryCatch( expr = if (isS3stdGeneric(f = x)) { as.character(x = methods(generic.function = x)) } else { x }, error = function(...) { return(x) } ) x <- if (is.character(x = x)) { sapply(X = x, FUN = argsAnywhere, simplify = FALSE, USE.NAMES = TRUE) } else if (length(x = x) <= 1) { list(x) } return(sapply( X = x, FUN = function(f) { return(names(x = formals(fun = f))) }, simplify = FALSE, USE.NAMES = TRUE )) }, simplify = FALSE, USE.NAMES = TRUE )) fxn.args <- unlist(x = fxn.args, recursive = FALSE) fxn.null <- vapply( X = fxn.args, FUN = is.null, FUN.VALUE = logical(length = 1L) ) if (all(fxn.null) && !is.null(x = fxns)) { stop("None of the functions passed could be found", call. = FALSE) } else if (any(fxn.null)) { warning( "The following functions passed could not be found: ", paste(names(x = which(x = fxn.null)), collapse = ', '), call. = FALSE, immediate. = TRUE ) fxn.args <- Filter(f = Negate(f = is.null), x = fxn.args) } dfxns <- vector(mode = 'logical', length = length(x = fxn.args)) names(x = dfxns) <- names(x = fxn.args) for (i in 1:length(x = fxn.args)) { dfxns[i] <- any(grepl(pattern = '...', x = fxn.args[[i]], fixed = TRUE)) } if (any(dfxns)) { dfxns <- names(x = which(x = dfxns)) if (any(nchar(x = dfxns) > 0)) { fx <- vapply( X = Filter(f = nchar, x = dfxns), FUN = function(x) { if (isS3method(method = x)) { x <- unlist(x = strsplit(x = x, split = '\\.')) x <- x[length(x = x) - 1L] } return(x) }, FUN.VALUE = character(length = 1L) ) message( "The following functions and any applicable methods accept the dots: ", paste(unique(x = fx), collapse = ', ') ) if (any(nchar(x = dfxns) < 1)) { message( "In addition, there is/are ", length(x = Filter(f = Negate(f = nchar), x = dfxns)), " other function(s) that accept(s) the dots" ) } } else { message("There is/are ", length(x = dfxns), 'function(s) that accept(s) the dots') } } else { unused <- Filter( f = function(x) { return(!x %in% unlist(x = fxn.args)) }, x = args.names ) if (length(x = unused) > 0) { msg <- paste0( "The following arguments are not used: ", paste(unused, collapse = ', ') ) switch( EXPR = getOption(x = "Seurat.checkdots", default = 'warn'), "warn" = warning(msg, call. = FALSE, immediate. = TRUE), "stop" = stop(msg), "silent" = NULL, stop("Invalid Seurat.checkdots option. Please choose one of warn, stop, silent") ) # unused.hints <- sapply(X = unused, FUN = OldParamHints) # names(x = unused.hints) <- unused # unused.hints <- na.omit(object = unused.hints) # if (length(x = unused.hints) > 0) { # message( # "Suggested parameter: ", # paste(unused.hints, "instead of", names(x = unused.hints), collapse = '; '), # "\n" # ) # } } } return(invisible(x = NULL)) } #' Check features names format #' #' @param data a matrix input, rownames(data) are feature names #' #' @return \code{data} with update feature names #' #' @keywords internal #' #' @export #' CheckFeaturesNames <- function(data) { if (any(grepl(pattern = "_", x = rownames(x = data)))) { warning( "Feature names cannot have underscores ('_'), replacing with dashes ('-')", call. = FALSE, immediate. = TRUE ) rownames(x = data) <- gsub( pattern = "_", replacement = "-", x = rownames(x = data) ) } if (any(grepl(pattern = "|", x = rownames(x = data), fixed = TRUE))) { warning( "Feature names cannot have pipe characters ('|'), replacing with dashes ('-')", call. = FALSE, immediate. = TRUE ) rownames(x = data) <- gsub( pattern = "|", replacement = "-", x = rownames(x = data), fixed = TRUE ) } return(data) } #' Conditional Garbage Collection #' #' Call \code{gc} only when desired #' #' @param option ... #' #' @template return-null #' #' @export #' #' @concept utils #' CheckGC <- function(option = 'SeuratObject.memsafe') { if (isTRUE(x = getOption(x = option, default = FALSE))) { gc(verbose = FALSE) } return(invisible(x = NULL)) } #' Check layers names for the input list #' #' #' @param matrix.list A list of matrices #' @param layers.type layers type, such as counts or data #' #' #' @export #' #' @concept utils #' CheckLayersName <- function( matrix.list, layers.type = c('counts', 'data') ) { layers.type <- match.arg(arg = layers.type) if (is.null(x = matrix.list)) { return(matrix.list) } if (!inherits(x = matrix.list, what = 'list')) { matrix.list <- list(matrix.list) } if (length(x = matrix.list) == 1) { names(x = matrix.list) <- layers.type } else { endings <- seq_along(along.with = matrix.list) for (i in 1:length(x = matrix.list)) { name <- names(x = matrix.list)[i] if (!is.null(name) && nzchar(x = name)) { if (grepl(pattern = paste0('^', layers.type, '[._\\0-9-]+'), x = name)) { name <- gsub( pattern = paste0(layers.type, '[._\\0-9-]+'), replacement = "", x = name ) # If replacement leaves empty string if (!nzchar(x = name)) { name <- i } } endings[i] <- name } } names(x = matrix.list) <- paste0(paste0(layers.type, '.'), endings) names(x = matrix.list) <- make.unique(names = names(x = matrix.list), sep = '') } return(matrix.list) } #' Generate a Class Key #' #' Generate class keys for S4 classes. A class key follows the following #' structure: \dQuote{\code{package:class}} #' #' @param class Class name #' @param package Optional name of package; by default, will search namespaces #' of loaded packages to determine the providing package #' #' @return The class key (\dQuote{\code{package:class}}) #' #' @importFrom methods getClass slot #' #' @keywords internal #' #' @export #' #' @concept utils #' @family s4list #' #' @examples #' ClassKey("Seurat") #' ClassKey <- function(class, package = NULL) { class <- class[1L] package <- package %||% slot( object = getClass(Class = class), name = 'package' ) return(paste(package, class, sep = ':')) } #' Find the default \code{\link{DimReduc}} #' #' Searches for \code{\link{DimReduc}s} matching \dQuote{umap}, \dQuote{tsne}, #' or \dQuote{pca}, case-insensitive, and in that order. Priority given to #' \code{\link{DimReduc}s} matching the \code{DefaultAssay} or assay specified #' (eg. \dQuote{pca} for the default assay weights higher than \dQuote{umap} #' for a non-default assay) #' #' @param object A \code{\link{Seurat}} object #' @param assay Name of assay to use; defaults to the default assay of the object #' #' @return The default \code{\link{DimReduc}}, if possible #' #' @export #' #' @concept utils #' #' @examples #' DefaultDimReduc(pbmc_small) #' DefaultDimReduc <- function(object, assay = NULL) { object <- UpdateSlots(object = object) assay <- assay %||% DefaultAssay(object = object) drs.use <- c('umap', 'tsne', 'pca') dim.reducs <- .FilterObjects(object = object, classes.keep = 'DimReduc') drs.assay <- Filter( f = function(x) { return(DefaultAssay(object = object[[x]]) == assay) }, x = dim.reducs ) if (length(x = drs.assay)) { index <- lapply( X = drs.use, FUN = grep, x = drs.assay, ignore.case = TRUE ) index <- Filter(f = length, x = index) if (length(x = index)) { return(drs.assay[min(index[[1]])]) } } index <- lapply( X = drs.use, FUN = grep, x = dim.reducs, ignore.case = TRUE ) index <- Filter(f = length, x = index) if (!length(x = index)) { abort(message = paste0( "Unable to find a DimReduc matching one of ", .Oxford(drs.use), "; please specify a dimensional reduction to use" )) } return(dim.reducs[min(index[[1]])]) } #' Radian/Degree Conversions #' #' Convert degrees to radians and vice versa #' #' @param rad Angle in radians #' #' @return \code{Degrees}: \code{rad} in degrees #' #' @name Angles #' @rdname angles #' #' @keywords internal #' #' @export #' #' @concept utils #' @family angles #' #' @examples #' Degrees(pi) #' Degrees <- function(rad) { return(rad * (180 / pi)) } #' Empty Data Frames #' #' Create an empty \link[base:data.frame]{data frame} with no row names and #' zero columns #' #' @param n Number of rows for the data frame #' #' @return A \link[base:data.frame]{data frame} with \code{n} rows and #' zero columns #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' EmptyDF(4L) #' EmptyDF <- function(n) { return(as.data.frame(x = matrix(nrow = n, ncol = 0L))) } #' Empty Matrices #' #' Create empty 0x0 matrices of varying types #' #' @param repr Representation of empty matrix; choose from: #' \itemize{ #' \item \dQuote{\code{C}} for a #' \code{\link[Matrix:CsparseMatrix-class]{CsparseMatrix}} #' \item \dQuote{\code{T}} for a #' \code{\link[Matrix:TsparseMatrix-class]{TsparseMatrix}} #' \item \dQuote{\code{R}} for an #' \code{\link[Matrix:RsparseMatrix-class]{RsparseMatrix}} #' \item \dQuote{\code{e}} for an #' \code{\link[Matrix:unpackedMatrix-class]{unpackedMatrix}} #' \item \dQuote{\code{d}} for a dense S3 \code{\link[base]{matrix}} #' \item \dQuote{\code{spam}} for a \code{\link[spam]{spam}} matrix #' } #' @param type Type of resulting matrix to return, choose from: #' \itemize{ #' \item \dQuote{\code{d}} for numeric matrices #' \item \dQuote{\code{l}} for logical matrices #' \item \dQuote{\code{n}} for pattern matrices #' } #' Note, when \code{repr} is \dQuote{\code{spam}}, \code{type} must be #' \dQuote{\code{d}}; when \code{repr} is \dQuote{\code{d}}, setting \code{type} #' to \dQuote{\code{n}} returns a logical matrix #' #' @return A 0x0 matrix of the specified representation and type #' #' @export #' #' @concept utils #' #' @seealso \code{\link{IsMatrixEmpty}()} #' #' @examples #' EmptyMatrix() #' EmptyMatrix("spam") #' EmptyMatrix <- function(repr = 'C', type = 'd' ) { repr <- arg_match(arg = repr, values = c('C', 'T', 'R', 'e', 'd', 'spam')) type <- arg_match( arg = type, values = switch( EXPR = repr, spam = 'd', c('d', 'l', 'n') ) ) return(switch( EXPR = repr, spam = spam::spam(x = 0L, nrow = 0L, ncol = 0L), d = matrix( data = vector( mode = switch(EXPR = type, d = 'numeric', 'logical'), length = 0L ), nrow = 0L, ncol = 0L ), new(Class = paste0(type, 'g', repr, 'Matrix')) )) } #' Extract delimiter information from a string. #' #' Parses a string (usually a cell name) and extracts fields based #' on a delimiter #' #' @param string String to parse. #' @param field Integer(s) indicating which field(s) to extract. Can be a #' vector multiple numbers. #' @param delim Delimiter to use, set to underscore by default. #' #' @return A new string, that parses out the requested fields, and #' (if multiple), rejoins them with the same delimiter #' #' @keywords internal #' #' @export #' #' @concept utils #' #' @examples #' ExtractField('Hello World', field = 1, delim = '_') #' ExtractField <- function(string, field = 1, delim = "_") { fields <- as.numeric(x = unlist(x = strsplit( x = as.character(x = field), split = "," ))) if (length(x = fields) == 1) { return(strsplit(x = string, split = delim)[[1]][field]) } return(paste( strsplit(x = string, split = delim)[[1]][fields], collapse = delim )) } #' Check List Names #' #' Check to see if a list has names; also check to enforce that all names are #' present and unique #' #' @param x A list #' @param all.unique Require that all names are unique from one another #' @param allow.empty Allow empty (\code{nchar = 0}) names #' @param pass.zero Pass on zero-length lists #' #' @return \code{TRUE} if ..., otherwise \code{FALSE} #' #' @importFrom rlang is_bare_list #' #' @export #' #' @concept utils #' #' @examples #' IsNamedList(list()) #' IsNamedList(list(), pass.zero = TRUE) #' IsNamedList(list(1, 2, 3)) #' IsNamedList(list(a = 1, b = 2, c = 3)) #' IsNamedList(list(a = 1, 2, c = 3)) #' IsNamedList(list(a = 1, 2, c = 3), allow.empty = TRUE) #' IsNamedList(list(a = 1, a = 2, a = 3)) #' IsNamedList(list(a = 1, a = 2, a = 3), all.unique = FALSE) #' IsNamedList <- function( x, all.unique = TRUE, allow.empty = FALSE, pass.zero = FALSE ) { if (!is_bare_list(x = x)) { return(FALSE) } if (isTRUE(x = pass.zero) && !length(x = x)) { return(TRUE) } n <- names(x = x) named <- !is.null(x = n) if (!isTRUE(x = allow.empty)) { named <- named && all(vapply( X = n, FUN = nchar, FUN.VALUE = integer(length = 1L) )) } if (isTRUE(x = all.unique)) { named <- named && (length(x = n) == length(x = unique(x = n))) } return(named) } #' @name s4list #' @rdname s4list #' #' @return \code{IsS4List}: \code{TRUE} if \code{x} is a list with an S4 class #' definition attribute #' #' @export #' #' @examples #' IsS4List(pbmc.list) #' IsS4List <- function(x) { return( is_bare_list(x = x) && isTRUE(x = grepl( pattern = '^[[:alnum:]]+:[[:alnum:]]+$', x = attr(x = x, which = 'classDef') )) ) } #' @name s4list #' @rdname s4list #' #' @return \code{ListToS4}: An S4 object as defined by the S4 class definition #' attribute #' #' @importFrom methods getClassDef new #' #' @export #' #' @examples #' pbmc2 <- ListToS4(pbmc.list) #' pbmc2 #' class(pbmc2) #' Reductions(pbmc2) #' validObject(pbmc2) #' ListToS4 <- function(x) { if (!is_bare_list(x = x)) { return(x) } for (i in seq_along(along.with = x)) { if (!is.null(x = x[[i]])) { x[[i]] <- ListToS4(x = x[[i]]) } } classdef <- attr(x = x, which = 'classDef') x <- Filter(f = Negate(f = is.function), x = x) attr(x = x, which = 'classDef') <- classdef if (!IsS4List(x = x)) { return(x) } classdef <- unlist(x = strsplit( x = attr(x = x, which = 'classDef'), split = ':' )) pkg <- classdef[1L] cls <- classdef[2L] formal <- getClassDef(Class = cls, package = pkg, inherits = FALSE) return(do.call(what = new, args = c(list(Class = formal), x))) } #' Check the existence of a package #' #' @param ... Package names #' @param error If true, throw an error if the package doesn't exist #' #' @return Invisibly returns boolean denoting if the package is installed #' #' @export #' #' @concept utils #' #' @section Lifecycle: #' #' \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} #' #' \code{PackageCheck} was deprecated in version 5.0.0; please use #' \code{\link[rlang:check_installed]{rlang::check_installed}()} instead #' #' PackageCheck <- function(..., error = TRUE) { .Deprecate( when = '5.0.0', what = 'PackageCheck()', with = 'rlang::check_installed()' ) pkgs <- unlist(x = c(...), use.names = FALSE) package.installed <- vapply( X = pkgs, FUN = requireNamespace, FUN.VALUE = logical(length = 1L), quietly = TRUE ) if (error && any(!package.installed)) { stop( "Cannot find the following packages: ", paste(pkgs[!package.installed], collapse = ', '), ". Please install" ) } invisible(x = package.installed) } #' Polygon Vertices #' #' Calculate the vertices of a regular polygon given the number of sides and #' its radius (distance from center to vertex). Also permits transforming the #' resulting coordinates by moving the origin and altering the initial angle #' #' @param n Number of sides of the polygon #' @param r Radius of the polygon #' @param xc,yc X/Y coordinates for the center of the polygon #' @param t1 Angle of the first vertex in degrees #' #' @return A \code{\link[base]{data.frame}} with \code{n} rows and two columns: #' \describe{ #' \item{\code{x}}{X positions of each coordinate} #' \item{\code{y}}{Y positions of each coordinate} #' } #' #' @keywords internal #' #' @export #' #' @concept utils #' @family angles #' #' @references \url{https://stackoverflow.com/questions/3436453/calculate-coordinates-of-a-regular-polygons-vertices} #' #' @examples #' (coords <- PolyVtx(5, t1 = 90)) #' if (requireNamespace("ggplot2", quietly = TRUE)) { #' ggplot2::ggplot(coords, ggplot2::aes(x = x, y = y)) + ggplot2::geom_polygon() #' } #' PolyVtx <- function(n, r = 1L, xc = 0L, yc = 0L, t1 = 0) { if (!is_bare_integerish(x = n, n = 1L, finite = TRUE)) { abort(message = "'n' must be a single integer") } else if (n < 3L) { abort(message = "'n' must be greater than or equal to 3") } stopifnot( "'r' must be a single, finite number" = is_bare_numeric(x = r, n = 1L) && is.finite(x = r), "'xc' must be a single, finite number" = is_bare_numeric(x = xc, n = 1L) && is.finite(x = xc), "'yc' must be a single, finite number" = is_bare_numeric(x = yc, n = 1L) && is.finite(x = yc), "'t1' must be a single, finite number" = is_bare_numeric(x = t1, n = 1L) && is.finite(x = t1) ) t1 <- Radians(deg = t1) coords <- matrix(data = 0, nrow = n, ncol = 2) colnames(x = coords) <- c('x', 'y') for (i in seq_len(length.out = n)) { theta <- 2 * pi * (i - 1) / n + t1 coords[i, ] <- c( xc + r * cos(x = theta), yc + r * sin(x = theta) ) } return(as.data.frame(x = coords)) } #' @param deg Angle in degrees #' #' @return \code{Radians}: \code{deg} in radians #' #' @rdname angles #' #' @keywords internal #' #' @export #' #' @examples #' Radians(180) #' Radians <- function(deg) { return(deg * (pi / 180)) } #' Generate a random name #' #' Make a name from randomly sampled characters, pasted together with no spaces #' #' @param length How long should the name be #' @param chars A vector of 1-length characters to use to generate the name #' @param ... Extra parameters passed to \code{\link[base]{sample}} #' #' @return A character with \code{nchar == length} of randomly sampled letters #' #' @seealso \code{\link[base]{sample}} #' #' @export #' #' @concept utils #' #' @examples #' set.seed(42L) #' RandomName() #' RandomName(7L, replace = TRUE) #' RandomName <- function(length = 5L, chars = letters, ...) { CheckDots(..., fxns = 'sample') chars <- unique(x = unlist(x = strsplit( x = as.character(x = chars), split = '' ))) return(paste(sample(x = chars, size = length, ...), collapse = '')) } #' Merge Sparse Matrices by Row #' #' Merge two or more sparse matrices by rowname. #' #' @details #' Shared matrix rows (with the same row name) will be merged, and unshared #' rows (with different names) will be filled with zeros in the matrix not #' containing the row. #' #' @param mat1 First matrix #' @param mat2 Second matrix or list of matrices #' #' @return Returns a sparse matrix #' #' @importFrom methods as # #' @export #' #' @concept utils #' RowMergeSparseMatrices <- function(mat1, mat2) { all.mat <- c(list(mat1), mat2) all.colnames <- all.rownames <- vector( mode = 'list', length = length(x = all.mat) ) for (i in seq_along(along.with = all.mat)) { if (is.data.frame(x = all.mat[[1]])) { all.mat[[i]] <- as.matrix(x = all.mat[[i]]) } all.rownames[[i]] <- rownames(x = all.mat[[i]]) all.colnames[[i]] <- colnames(x = all.mat[[i]]) } use.cbind <- all(duplicated(x = all.rownames)[2:length(x = all.rownames)]) if (isTRUE(x = use.cbind)) { new.mat <- do.call(what = cbind, args = all.mat) } else { all.mat <- lapply(X = all.mat, FUN = as, Class = "RsparseMatrix") all.names <- unique(x = unlist(x = all.rownames)) new.mat <- RowMergeMatricesList( mat_list = all.mat, mat_rownames = all.rownames, all_rownames = all.names ) rownames(x = new.mat) <- make.unique(names = all.names) } colnames(x = new.mat) <- make.unique(names = unlist(x = all.colnames)) return(new.mat) } #' Improve S4 validity error messages #' #' Catch errors from validObject to allow for more informative error messages. #' #' (R's internal validation checking--including making sure the object has all slots in the class definition-- #' occurs before the custom validity method for a class is run. Errors originating from an internal check may be #' confusing to users, hence they can be modified here to provide more helpful messages.) #' #' @keywords internal #' @noRd #' safeValidityCheck <- function(object) { tryCatch( expr = { validObject(object = object) }, error = function(e) { if (grepl(pattern = "slots in class definition but not in object", x = e$message)) { e <- simpleError(message = paste0("Consider running UpdateSeuratObject; ", conditionMessage(e)), call = conditionCall(e)) } stop(e) } ) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname dot-AssayClass #' @method .AssayClass default #' @export #' .AssayClass.default <- function(object) { return(class(x = object)[1L]) } #' @importFrom methods getClass #' #' @rdname dot-ClassPkg #' #' @method .ClassPkg default #' @export #' .ClassPkg.default <- function(object) { if (!isS4(object)) { return(NA_character_) } return(slot(object = getClass(Class = class(x = object)), name = 'package')) } #' @rdname dot-ClassPkg #' @method .ClassPkg DelayedArray #' @export #' .ClassPkg.DelayedArray <- function(object) { check_installed( pkg = 'DelayedArray', reason = 'for working with delayed arrays' ) return(.ClassPkg(object = DelayedArray::seed(x = object))) } #' @rdname dot-ClassPkg #' @method .ClassPkg R6 #' @export #' .ClassPkg.R6 <- function(object) { for (cls in class(x = object)) { x <- eval(expr = as.symbol(x = cls)) if (inherits(x = x, what = 'R6ClassGenerator')) { return(.ClassPkg(object = x)) } } warn(message = "No r6") return('R6') } #' @rdname dot-ClassPkg #' @method .ClassPkg R6ClassGenerator #' @export #' .ClassPkg.R6ClassGenerator <- function(object) { return(environmentName(env = object$parent_env)) } #' @rdname dot-DiskLoad #' @method .DiskLoad default #' @export #' .DiskLoad.default <- function(x) { return(NULL) } #' @rdname dot-DiskLoad #' @method .DiskLoad 10xMatrixH5 #' @export #' .DiskLoad.10xMatrixH5 <- function(x) { abort(message = "Unable to determine the feature type of 10x-based BPCells matrices") check_installed( pkg = 'BPCells', reason = 'for working with BPCells matrices' ) f <- paste( 'function(x)', 'BPCells::open_matrix_10x_hdf5(path = x, feature_type =', sQuote(x = '', q = FALSE), ')' ) return(f) } #' @rdname dot-DiskLoad #' @method .DiskLoad AnnDataMatrixH5 #' @export #' .DiskLoad.AnnDataMatrixH5 <- function(x) { check_installed( pkg = 'BPCells', reason = 'for working with BPCells matrices' ) f <- paste( 'function(x)', 'BPCells::open_matrix_anndata_hdf5(path = x, group =', sQuote(x = slot(object = x, name = 'group'), q = FALSE), ')' ) return(f) } #' @rdname dot-DiskLoad #' @method .DiskLoad DelayedMatrix #' @export #' .DiskLoad.DelayedMatrix <- function(x) { check_installed( pkg = 'DelayedArray', reason = 'for working with delayed matrices' ) seed <- DelayedArray::seed(x = x) return(.DiskLoad(x = DelayedArray::DelayedArray(seed = seed))) } #' @rdname dot-DiskLoad #' @method .DiskLoad H5ADMatrix #' @export #' .DiskLoad.H5ADMatrix <- function(x) { check_installed( pkg = 'HDF5Array', reason = 'for working with H5AD matrices' ) sparse <- DelayedArray::is_sparse(x = x) layer <- if (isTRUE(x = sparse)) { slot(object = DelayedArray::seed(x = x), name = 'group') } else { slot(object = DelayedArray::seed(x = x), name = 'name') } layer <- if (layer == '/X') { NULL } else { basename(path = layer) } f <- paste( "function(x)", "HDF5Array::H5ADMatrix(filepath = x", if (!is.null(x = layer)) { paste(", layer =", sQuote(x = layer, q = FALSE)) }, ")" ) return(f) } #' @rdname dot-DiskLoad #' @method .DiskLoad HDF5Matrix #' @export #' .DiskLoad.HDF5Matrix <- function(x) { check_installed( pkg = 'HDF5Array', reason = 'for working with HDF5 matrices' ) sparse <- DelayedArray::is_sparse(x = x) name <- slot(object = DelayedArray::seed(x = x), name = 'name') f <- paste( "function(x)", "HDF5Array::HDF5Array(filepath = x, name =", sQuote(x = name, q = FALSE), ", as.sparse =", sparse, ")" ) return(f) } #' @rdname dot-DiskLoad #' @method .DiskLoad IterableMatrix #' @export #' .DiskLoad.IterableMatrix <- function(x) { check_installed( pkg = 'BPCells', reason = 'for working with BPCells matrices' ) fxns <- lapply( X = BPCells::all_matrix_inputs(x = x), FUN = .DiskLoad ) fxns <- Filter(f = Negate(f = is.null), x = fxns) if (!length(x = fxns)) { return(NULL) } fn <- if (length(x = fxns) > 1L) { # fxns <- paste('list(', paste(sQuote(x = fxns, q = FALSE), collapse = ', '), ')') fn <- paste( "function(x) {", "paths <- unlist(x = strsplit(x = x, split = ','));", "fxns <- list(", paste(sQuote(x = fxns, q = FALSE), collapse = ', '), ");", "mats <- vector(mode = 'list', length = length(x = paths));", "for (i in seq_along(paths)) {", "fn <- eval(str2lang(fxns[[i]]));", "mats[[i]] <- fn(paths[i]);", "};", "return(Reduce(cbind, mats));", "}" ) fn # abort(message = "too many matrices") } else { fxns[[1L]] } return(fn) } #' @rdname dot-DiskLoad #' @method .DiskLoad MatrixDir #' @export #' .DiskLoad.MatrixDir <- function(x) { check_installed( pkg = 'BPCells', reason = 'for working with BPCells matrices' ) f <- paste( 'function(x)', 'BPCells::open_matrix_dir(dir = x)' ) return(f) } #' @rdname dot-DiskLoad #' @method .DiskLoad MatrixH5 #' @export #' .DiskLoad.MatrixH5 <- function(x) { check_installed( pkg = 'BPCells', reason = 'for working with BPCells matrices' ) f <- paste( 'function(x)', 'BPCells::open_matrix_hdf5(path = x, group =', sQuote(x = slot(object = x, name = 'group'), q = FALSE), ')' ) return(f) } #' @rdname dot-DiskLoad #' @method .DiskLoad TileDBMatrix #' @export #' .DiskLoad.TileDBMatrix <- function(x) { check_installed( pkg = 'TileDBArray', reason = 'for working with TileDB matrices' ) tdb.attr <- slot(object = DelayedArray::seed(x = x), name = 'attr') f <- paste( 'function(x)', 'TileDBArray::TileDBArray(x = x, attr =', sQuote(x = tdb.attr, q = FALSE), ')' ) return(f) } #' @rdname dot-FilePath #' @method .FilePath default #' @export #' .FilePath.default <- function(x) { return(NULL) } #' @rdname dot-FilePath #' @method .FilePath DelayedMatrix #' @export #' .FilePath.DelayedMatrix <- function(x) { check_installed( pkg = 'DelayedArray', reason = 'for working with delayed matrices' ) path <- tryCatch( expr = normalizePath(path = DelayedArray::path(object = x)), error = \(...) NULL ) if (is.null(x = path)) { warn(message = "The matrix provided does not exist on-disk") } return(path) } #' @rdname dot-FilePath #' @method .FilePath IterableMatrix #' @export #' .FilePath.IterableMatrix <- function(x) { check_installed(pkg = "BPCells", reason = "for working with BPCells matrices") matrices <- BPCells::all_matrix_inputs(x = x) paths <- vector(mode = 'character', length = length(x = matrices)) for (i in seq_along(along.with = matrices)) { mode <- .BPMatrixMode(object = matrices[[i]]) paths[i] <- switch( EXPR = mode, memory = '', file = slot(object = matrices[[i]], name = "path"), directory = slot(object = matrices[[i]], name = 'dir'), abort(message = paste("Unknown BPCells matrix mode:", sQuote(x = mode))) ) } if (length(paths) > 1){ paths <- paste(paths, collapse = ",") } return(paths) } #' @rdname as.Centroids #' @method as.Centroids Segmentation #' @export #' as.Centroids.Segmentation <- function( x, nsides = NULL, radius = NULL, theta = NULL, ... ) { coords <- as(object = x, Class = 'Centroids') if (!is.null(x = nsides)) { slot(object = coords, name = 'nsides') <- nsides } if (!is.null(x = theta)) { slot(object = coords, name = 'theta') <- theta } if (is.null(x = radius)) { radius <- vapply( X = Cells(x = x), FUN = function(i) { area <- slot( object = slot(object = x, name = 'polygons')[[i]], name = 'area' ) return(sqrt(x = area / pi)) }, FUN.VALUE = numeric(length = 1L), USE.NAMES = FALSE ) } slot(object = coords, name = 'radius') <- radius validObject(object = coords) return(coords) # x <- c() # y <- c() # radius <- c() # nsides <- 0 # for (cell in Cells(x)) { # a <- x@polygons[[cell]]@area # radius <- c(radius, sqrt(a / pi)) # x <- c(x, x@polygons[[cell]]@labpt[1]) # y <- c(y, x@polygons[[cell]]@labpt[2]) # } # coords <- data.frame(x, y) # rownames(x = coords) = Cells(x) # return( # CreateCentroids( # coords, # radius = radius, # theta = rep(0, length(radius)), # nsides = rep(0, length(radius)) # ) # ) } #' @rdname as.Centroids #' @method as.Segmentation Centroids #' @export #' as.Segmentation.Centroids <- function(x, ...) { return(as(object = x, Class = 'Segmentation')) } #' @param row.names \code{NULL} or a character vector giving the row names for #' the data; missing values are not allowed #' #' @rdname as.sparse #' @export #' @method as.sparse data.frame #' as.sparse.data.frame <- function(x, row.names = NULL, ...) { CheckDots(...) dnames <- list(row.names %||% rownames(x = x), colnames(x = x)) if (length(x = dnames[[1]]) != nrow(x = x)) { stop("Differing numbers of rownames and rows", call. = FALSE) } x <- as.data.frame(x = x) dimnames(x = x) <- dnames return(as.sparse(x = as.matrix(x = x))) } #' @importFrom methods as #' #' @rdname as.sparse #' @export #' @method as.sparse Matrix #' as.sparse.Matrix <- function(x, ...) { CheckDots(...) return(as(object = as(object = as(object = x, Class = "dMatrix"), Class = "generalMatrix"), Class = "CsparseMatrix")) } #' @rdname as.sparse #' @export #' @method as.sparse matrix #' as.sparse.matrix <- function(x, ...) { if (is.character(x = x)) { dnames <- dimnames(x = x) nc <- ncol(x = x) x <- matrix(data = as.numeric(x = x), ncol = nc) dimnames(x = x) <- dnames } x <- as(object = x, Class = "Matrix") return(as.sparse.Matrix(x, ...)) } #' @rdname as.sparse #' @export #' @method as.sparse ngCMatrix #' as.sparse.ngCMatrix <- function(x, ...) { return(as(object = x, Class = "dMatrix")) } #' @rdname CheckMatrix #' @method CheckMatrix default #' @export #' CheckMatrix.default <- function(object, checks, ...) { return(invisible(x = NULL)) } #' @rdname CheckMatrix #' @method CheckMatrix dMatrix #' @export #' CheckMatrix.dMatrix <- function( object, checks = c('infinite', 'logical', 'integer', 'na'), ... ) { checks <- arg_match(arg = checks, multiple = TRUE) x <- slot(object = object, name = 'x') for (i in checks) { switch( EXPR = i, 'infinite' = if (any(is.infinite(x = x))) { warn(message = "Input matrix contains infinite values") }, 'logical' = if (any(is.logical(x = x))) { warn(message = "Input matrix contains logical values") }, 'integer' = if (!all(round(x = x) == x, na.rm = TRUE)) { warn(message = "Input matrix contains non-integer values") }, 'na' = if (anyNA(x = x)) { warn(message = "Input matrix contains NA/NaN values") }, ) } return(invisible(x = NULL)) } #' @rdname CheckMatrix #' @method CheckMatrix lMatrix #' @export #' CheckMatrix.lMatrix <- function( object, checks = c('infinite', 'logical', 'integer', 'na'), ... ) { warn(message = "Input matrix contains logical values") return(invisible(x = NULL)) } #' @rdname IsMatrixEmpty #' @export #' @method IsMatrixEmpty default #' IsMatrixEmpty.default <- function(x) { matrix.dims <- dim(x = x) if (is.null(x = matrix.dims)) { return(FALSE) } matrix.na <- all(matrix.dims == 1) && all(is.na(x = x)) return(all(matrix.dims == 0) || matrix.na) } #' @importFrom methods slotNames #' #' @rdname s4list #' @export #' @method S4ToList default #' S4ToList.default <- function(object) { obj.list <- sapply( X = slotNames(x = object), FUN = function(x) { return(S4ToList(object = slot(object = object, name = x))) }, simplify = FALSE, USE.NAMES = TRUE ) attr(x = obj.list, which = 'classDef') <- paste( c( attr(x = class(x = object), which = 'package'), class(x = object) ), collapse = ':' ) return(obj.list) } #' @rdname s4list #' @export #' @method S4ToList list #' S4ToList.list <- function(object) { if (length(x = object)) { for (i in seq_along(along.with = object)) { if (!is.null(x = object[[i]])) { object[[i]] <- S4ToList(object = object[[i]]) } } } return(object) } #' Simplify segmentations by reducing the number of vertices #' #' @param coords A `Segmentation` object #' @param tol Numerical tolerance value to be used by the Douglas-Peuker algorithm #' @param topologyPreserve Logical determining if the algorithm should attempt to preserve the topology of the original geometry #' #' @return A `Segmentation` object with simplified segmentation vertices #' #' @rdname Simplify #' @method Simplify Spatial #' @export #' Simplify.Spatial <- function(coords, tol, topologyPreserve = TRUE) { check_installed(pkg = 'sf', reason = 'to simplify spatial data') class.orig <- class(x = coords) coords.orig <- coords dest <- ifelse( test = grepl(pattern = "^Spatial", x = class.orig), yes = class.orig, no = grep(pattern = "^Spatial", x = .Contains(object = coords), value = TRUE)[1L] ) x <- sf::st_as_sfc(as(object = coords, Class = dest)) coords <- sf::st_simplify( x = x, dTolerance = as.numeric(x = tol), preserveTopology = isTRUE(x = topologyPreserve)) coords <- sf::st_sf(geometry = coords) coords <- as(coords, Class = "Spatial") coords <- as(coords, Class = "Segmentation") slot(object = coords, name = "polygons") <- mapply( FUN = function(x, y) { slot(object = x, name = "ID") <- y return(x) }, slot(object = coords, name = "polygons"), Cells(coords.orig)) return(coords) } #' Generate empty dgC sparse matrix #' #' @param ncol,nrow Number of columns and rows in matrix #' @param rownames,colnames Optional row- and column names for the matrix #' #' @keywords internal #' #' @export #' SparseEmptyMatrix <- function(nrow, ncol, rownames = NULL, colnames = NULL) { return(new( Class = 'dgCMatrix', p = integer(length = ncol + 1L), Dim = c(as.integer(x = nrow), as.integer(x = ncol)), Dimnames = list(rownames, colnames) )) } #' @method StitchMatrix default #' @export #' StitchMatrix.default <- function(x, y, rowmap, colmap, ...) { abort(message = paste( "Stitching matrices of class", dQuote(x = class(x = x)[1L]), "is not yet supported" )) } #' @method StitchMatrix dgCMatrix #' @export #' StitchMatrix.dgCMatrix <- function(x, y, rowmap, colmap, ...) { on.exit(expr = CheckGC()) if (!is_bare_list(x = y)) { y <- list(y) } rowmap <- droplevels(x = rowmap) colmap <- droplevels(x = colmap) stopifnot(ncol(rowmap) == length(y) + 1L) stopifnot(ncol(colmap) == length(y) + 1L) stopifnot(identical(x = colnames(x = rowmap), y = colnames(x = colmap))) dimnames(x = x) <- list(rowmap[[1L]], colmap[[1L]]) for (i in seq_along(along.with = y)) { j <- i + 1L y[[i]] <- as(object = y[[i]], Class = 'dgCMatrix') dimnames(x = y[[i]]) <- list(rowmap[[j]], colmap[[j]]) } return(RowMergeSparseMatrices(mat1 = x, mat2 = y)) } #' @method StitchMatrix IterableMatrix #' @export #' StitchMatrix.IterableMatrix <- function(x, y, rowmap, colmap, ...) { on.exit(expr = CheckGC()) if (!is_bare_list(x = y)) { y <- list(y) } rowmap <- droplevels(x = rowmap) colmap <- droplevels(x = colmap) stopifnot(ncol(rowmap) == length(y) + 1L) stopifnot(ncol(colmap) == length(y) + 1L) stopifnot(identical(x = colnames(x = rowmap), y = colnames(x = colmap))) y <- c(x, y) for (i in seq_along(along.with = y)) { #expand matrix to the same size missing_row <- setdiff(x = rownames(x = rowmap), y = rowmap[[i]]) if (length(x = missing_row) > 0) { zero_i <- SparseEmptyMatrix( nrow = length(x = missing_row), ncol = ncol(x = y[[i]]), colnames = colmap[[i]], rownames = missing_row ) zero_i <- as(object = zero_i, Class = 'IterableMatrix') y[[i]] <- rbind(y[[i]], zero_i)[rownames(rowmap),] } } m <- Reduce(f = cbind, x = y) return(m) } #' @method StitchMatrix matrix #' @export #' StitchMatrix.matrix <- function(x, y, rowmap, colmap, ...) { on.exit(expr = CheckGC()) if (!is_bare_list(x = y)) { y <- list(y) } rowmap <- droplevels(x = rowmap) colmap <- droplevels(x = colmap) stopifnot(ncol(rowmap) == length(y) + 1L) stopifnot(ncol(colmap) == length(y) + 1L) stopifnot(identical(x = colnames(x = rowmap), y = colnames(x = colmap))) m <- matrix( data = 0, nrow = nrow(x = rowmap), ncol = nrow(x = colmap), dimnames = list(rownames(x = rowmap), rownames(x = colmap)) ) m[rowmap[[1L]], colmap[[1L]]] <- x for (i in seq_along(along.with = y)) { j <- i + 1L m[rowmap[[j]], colmap[[j]]] <- as.matrix(x = y[[i]]) } return(m) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @method t spam #' @export #' t.spam <- spam::t #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .CheckNames <- function(x, n) { stopifnot(length(x = x) == length(x = n)) if (is.null(x = names(x = x))) { names(x = x) <- n } if (any(!nzchar(x = names(x = x)))) { idx <- which(x = !nzchar(x = names(x = x))) n2 <- setdiff(x = n, y = names(x = x)) if (length(x = idx) != length(x = n2)) { stop("Not all provided names fit with the values provided", call. = FALSE) } names(x = x)[idx] <- n2 } return(x) } #' @importFrom stats median #' .FeatureRank <- function(features, flist, ranks = FALSE) { franks <- vapply( X = features, FUN = function(x) { return(median(x = unlist(x = lapply( X = flist, FUN = function(fl) { if (x %in% fl) { return(which(x = x == fl)) } return(NULL) } )))) }, FUN.VALUE = numeric(length = 1L) ) franks <- sort(x = franks) if (!isTRUE(x = ranks)) { franks <- names(x = franks) } return(franks) } #' Move Files and Directories #' #' Move files and directories with \pkg{fs}; includes a handler for when #' \code{path} is a directory on a different filesystem than \code{new_path} #' by explicitly copying and deleting \code{path} #' #' @inherit fs::file_move params return #' @inheritParams rlang::caller_env #' #' @keywords internal #' #' @export #' #' @templateVar pkg fs #' @template note-reqdpkg #' #' @seealso \code{\link[fs:file_move]{fs::file_move}()} #' .FileMove <- function(path, new_path, overwrite = FALSE, n = 1L) { check_installed(pkg = "fs", reason = "for moving on-disk files") stopifnot( is_scalar_character(x = path), is_scalar_character(x = new_path), rlang::is_bare_logical(x = overwrite, n = 1L), is_bare_integerish(x = n, n = 1L, finite = TRUE) && n > 0 ) eexist <- function(err) { warn( message = paste( strwrap(x = paste( "Trying to move", sQuote(x = path), "to itself, skipping" )), collapse = '\n' ), class = c('WEXIST', 'EEXIST') ) return(fs::as_fs_path(x = path)) } hndlr <- function(err) { abort( message = err$message, class = class(x = err), call = caller_env(n = 4L + n) ) } if (fs::is_dir(path = path)) { path <- fs::path_expand(path = path) new_path <- fs::path_expand(path = new_path) new_path <- fs::dir_create(path = new_path) dest <- tryCatch( expr = fs::dir_copy( path = path, new_path = new_path, overwrite = overwrite ), EEXIST = eexist, error = hndlr ) } else if (fs::is_file(path = path)) { dest <- tryCatch( expr = fs::file_copy( path = path, new_path = new_path, overwrite = overwrite ), EEXIST = eexist, error = hndlr ) } else { abort( message = paste( strwrap(x = paste0( "Can't find path: ", sQuote(x = path), "; if path is relative, change working directory" )), sep = '\n' ), call = caller_env(n = 1L + n) ) } return(invisible(x = dest)) } #' @param pkg Name of package #' @param external Include packages imported, but not defined, by \code{pkg} #' @param old Includes S3 classes registered by #' \code{\link[methods]{setOldClass}} #' @param unions Include class unions #' #' @importFrom methods getClass getClasses isClassUnion isXS3Class #' #' @noRd #' .PkgClasses <- function( pkg = 'SeuratObject', external = FALSE, old = FALSE, unions = FALSE, virtual = NA, collapse = TRUE, include = NULL, exclude = NULL ) { classes <- getClasses(where = getNamespace(name = pkg)) include <- intersect(x = include, y = classes) # Filter out classes imported, but not defined by pkg if (!isTRUE(x = external)) { classes <- Filter( f = function(x) { return(slot(object = getClass(Class = x), name = 'package') == pkg) }, x = classes ) } # Filter out S3 classes if (!isTRUE(x = old)) { classes <- Filter( f = function(x) { return(!isXS3Class(classDef = getClass(Class = x))) }, x = classes ) } # Filter out class unions if (!isTRUE(x = unions)) { classes <- Filter(f = Negate(f = isClassUnion), x = classes) } # TODO: Remove virtual classes if (isFALSE(x = virtual)) { '' } # TODO: Collapse classes if (isTRUE(x = collapse)) { '' } # Add classes back classes <- union(x = classes, y = include) # Remove excluded classes classes <- setdiff(x = classes, y = exclude) return(classes) } #' Get English Vowels #' #' @return A vector with English vowels in lower case #' #' @keywords internal #' #' @examples #' .Vowels() #' #' @noRd #' .Vowels <- function() { return(c('a', 'e', 'i', 'o', 'u')) } #' Check a list of objects for duplicate cell names #' #' @param object.list List of Seurat objects #' @param verbose Print message about renaming #' @param stop Error out if any duplicate names exist #' #' @return Returns list of objects with duplicate cells renamed to be unique #' #' @keywords internal #' #' @noRd #' CheckDuplicateCellNames <- function(object.list, verbose = TRUE, stop = FALSE) { cell.names <- unlist(x = lapply(X = object.list, FUN = colnames)) if (anyDuplicated(x = cell.names)) { if (isTRUE(x = stop)) { stop("Duplicate cell names present across objects provided.", call. = FALSE) } if (verbose) { warning( "Some cell names are duplicated across objects provided. Renaming to enforce unique cell names.", call. = FALSE, immediate. = TRUE ) } for (i in seq_along(along.with = object.list)) { object.list[[i]] <- RenameCells( object = object.list[[i]], new.names = paste( colnames(x = object.list[[i]]), i, sep = '_' )) } } return(object.list) } #' Check List Names #' #' Check to see if a list has names; also check to enforce that all names are #' present and unique #' #' @param x A list #' @param all.unique Require that all names are unique from one another #' @param allow.empty Allow empty (\code{nchar = 0}) names #' @param pass.zero Pass on zero-length lists #' #' @return \code{TRUE} if ..., otherwise \code{FALSE} #' #' @importFrom rlang is_bare_list #' #' @keywords internal #' #' @noRd #' IsNamedList <- function( x, all.unique = TRUE, allow.empty = FALSE, pass.zero = FALSE ) { if (!is_bare_list(x = x)) { return(FALSE) } if (isTRUE(x = pass.zero) && !length(x = x)) { return(TRUE) } n <- names(x = x) named <- !is.null(x = n) if (!isTRUE(x = allow.empty)) { named <- named && all(vapply( X = n, FUN = nchar, FUN.VALUE = integer(length = 1L) )) } if (isTRUE(x = all.unique)) { named <- named && (length(x = n) == length(x = unique(x = n))) } return(named) } #' Test Null Pointers #' #' Check to see if a C++ pointer is a null pointer on the compiled side #' #' @param x An \link[methods:externalptr-class]{external pointer} object #' #' @return \code{TRUE} if \code{x} is a null pointer, otherwise \code{FALSE} #' #' @importFrom methods is #' #' @references \url{https://stackoverflow.com/questions/26666614/how-do-i-check-if-an-externalptr-is-null-from-within-r} #' #' @keywords internal #' #' @noRd #' IsNullPtr <- function(x) { stopifnot(is(object = x, class2 = 'externalptr')) return(.Call('isnull', x)) } #' Test Empty Characters #' #' Check to see if a \code{\link[base]{character}} vector is empty. A character #' is empty if it has no length or an \code{nzchar == FALSE} #' #' @param x A \code{\link[base]{character}} vector #' @param mode Stringency of emptiness test: #' \describe{ #' \item{\dQuote{each}}{Return a single value for each member of \code{x}} #' \item{\dQuote{any}}{Return \code{TRUE} if any member of \code{x} is empty} #' \item{\dQuote{all}}{Return \code{TRUE} if \emph{every} member of \code{x} is #' empty} #' } #' @param na Control how \code{\link[base]{NA}} values are treated: #' \describe{ #' \item{\dQuote{empty}}{Treat \code{NA}s as empty values} #' \item{\dQuote{keep}}{Keep \code{NA} values and treat them as \code{NA}} #' \item{\dQuote{remove}}{Remove \code{NA} values before testing emptiness} #' } #' #' @return If \code{mode} is \dQuote{each}, a vector of logical values denoting #' the emptiness of of each member of \code{x}; otherwise, a singular #' \code{\link[base]{logical}} denoting the overall emptiness of \code{x} #' #' @keywords internal #' #' @noRd #' IsCharEmpty <- function( x, mode = c('each', 'any', 'all'), na = c('empty', 'keep', 'remove') ) { if (!is.character(x = x)) { return(FALSE) } mode <- arg_match(arg = mode) na <- arg_match(arg = na) x <- switch( EXPR = na, empty = x[is.na(x = x)] <- '', remove = x <- x[!is.na(x = x)], x ) if (!length(x = x)) { return(TRUE) } empty <- vapply( X = x, FUN = Negate(f = nzchar), FUN.VALUE = logical(length = 1L), USE.NAMES = FALSE ) empty <- switch( EXPR = mode, any = any(empty), all = all(empty), empty ) return(empty) } #' Update a Class's Package #' #' Swap packages for an object's class definition. As classes move between #' packages, these functions rescope the namespace of the S4 class. This allows #' objects to depend only on the new package for class definitions rather than #' both the new and old packages #' #' @inheritParams s4list #' @param from A vector of one or more packages to limit conversion from #' @param to A character naming the package to search for new class definitions; #' defaults to the package of the function calling this function #' #' @return \code{SwapClassPkg}: \code{x} with an updated S4 class #' definition attribute #' #' @inheritSection s4list S4 Class Definition Attributes #' #' @name classpkg #' @rdname classpkg #' #' @keywords internal #' #' @seealso \code{\link{s4list}} #' #' @noRd #' SwapClassPkg <- function(x, from = NULL, to = NULL) { if (!is_bare_list(x = x)) { return(x) } to <- to[1] %||% environmentName(env = environment( fun = sys.function(which = 1L) )) if (!nchar(x = to) || !paste0('package:', to) %in% search()) { to <- environmentName(env = environment(fun = sys.function(which = 0L))) } for (i in seq_along(along.with = x)) { if (!is.null(x = x[[i]])) { x[[i]] <- SwapClassPkg(x = x[[i]], from = from, to = to) } } if (!IsS4List(x = x)) { return(x) } classdef <- unlist(x = strsplit( x = attr(x = x, which = 'classDef'), split = ':' )) pkg <- classdef[1] cls <- classdef[2] if (is.null(x = from) || pkg %in% from) { pkg <- ifelse( test = is.null(x = getClassDef( Class = cls, package = to, inherits = FALSE )), yes = pkg, no = to ) } attr(x = x, which = 'classDef') <- paste(pkg, cls, sep = ':') return(x) } #' Get the top #' #' @param data Data to pull the top from #' @param num Pull top \code{num} #' @param balanced Pull even amounts of from positive and negative values #' #' @return The top \code{num} #' #' @importFrom utils head tail #' #' @keywords internal #' #' @noRd #' Top <- function(data, num = 20, balanced = FALSE) { nr <- nrow(x = data) if (num > nr) { warning( "Requested number is larger than the number of available items (", nr, "). Setting to ", nr , ".", call. = FALSE ) num <- nr } balanced <- ifelse(test = nr == 1, yes = FALSE, no = balanced) top <- if (isTRUE(x = balanced)) { num <- round(x = num / 2) data <- data[order(data, decreasing = TRUE), , drop = FALSE] positive <- head(x = rownames(x = data), n = num) negative <- rev(x = tail(x = rownames(x = data), n = num)) # remove duplicates if (positive[num] == negative[num]) { negative <- negative[-num] } list(positive = positive, negative = negative) } else { data <- data[rev(x = order(abs(x = data))), , drop = FALSE] top <- head(x = rownames(x = data), n = num) top[order(data[top, ])] } return(top) } #' @rdname classpkg #' #' @return \code{UpdateClassPkg}: \code{object} with the updated #' class definition #' #' @keywords internal #' #' @noRd #' UpdateClassPkg <- function(object, from = NULL, to = NULL) { if (!isS4(object)) { return(object) } obj.list <- S4ToList(object = object) obj.list <- SwapClassPkg(x = obj.list, from = from, to = to) return(ListToS4(x = obj.list)) } #' Update slots in an object #' #' @param object An object to update #' #' @return \code{object} with the latest slot definitions #' #' @importFrom methods slotNames slot #' #' @concept utils #' #' @export #' UpdateSlots <- function(object) { if (!isS4(object)) { return(object) } object.list <- sapply( X = slotNames(x = object), FUN = function(x) { return(tryCatch( expr = slot(object = object, name = x), error = function(...) { return(NULL) } )) }, simplify = FALSE, USE.NAMES = TRUE ) object.list <- Filter(f = Negate(f = is.null), x = object.list) object.list <- c('Class' = class(x = object)[1], object.list) op <- options(Seurat.object.validate = FALSE) on.exit(expr = options(op), add = TRUE) object <- suppressWarnings(expr = do.call(what = 'new', args = object.list)) for (x in setdiff(x = slotNames(x = object), y = names(x = object.list))) { xobj <- slot(object = object, name = x) if (is.vector(x = xobj) && !is.list(x = xobj) && length(x = xobj) == 0) { slot(object = object, name = x) <- vector( mode = class(x = xobj), length = 1L ) } } return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setAs( from = 'Centroids', to = 'Segmentation', def = function(from) { if (is.infinite(x = from)) { stop("Cannot convert shapeless Centroids", call. = FALSE) } return(CreateSegmentation(coords = GetTissueCoordinates( object = from, full = TRUE ))) } ) setAs( from = 'Segmentation', to = 'Centroids', def = function(from) { return(CreateCentroids(coords = GetTissueCoordinates( object = from, full = FALSE ))) } ) SeuratObject/R/jackstraw.R0000644000176200001440000001131215075522101015155 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importFrom methods slot slot<- slotNames #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The JackStrawData Class #' #' The JackStrawData is used to store the results of a JackStraw computation. #' #' @slot empirical.p.values Empirical p-values #' @slot fake.reduction.scores Fake reduction scores #' @slot empirical.p.values.full Empirical p-values on full #' @slot overall.p.values Overall p-values from ScoreJackStraw #' #' @name JackStrawData-class #' @rdname JackStrawData-class #' @exportClass JackStrawData #' JackStrawData <- setClass( Class = "JackStrawData", slots = list( empirical.p.values = "matrix", fake.reduction.scores = "matrix", empirical.p.values.full = "matrix", overall.p.values = "matrix" ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname JS #' @export #' @method JS JackStrawData #' JS.JackStrawData <- function(object, slot, ...) { CheckDots(...) slot <- switch( EXPR = slot, 'empirical' = 'empirical.p.values', 'fake' = 'fake.reduction.scores', 'full' = 'empirical.p.values.full', 'overall' = 'overall.p.values', slot ) return(slot(object = object, name = slot)) } #' @rdname JS #' @export #' @method JS<- JackStrawData #' "JS<-.JackStrawData" <- function(object, slot, ..., value) { CheckDots(...) slot <- switch( EXPR = slot, 'empirical' = 'empirical.p.values', 'fake' = 'fake.reduction.scores', 'full' = 'empirical.p.values.full', 'overall' = 'overall.p.values', slot ) slot(object = object, name = slot) <- value return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{JackStrawData} Methods #' #' Methods for \code{\link{JackStrawData}} objects for generics defined in #' other packages #' #' @param x,object A \code{\link{JackStrawData}} object #' @param ... Ignored #' #' @name JackStrawData-methods #' @rdname JackStrawData-methods #' #' @concept jackstraw #' NULL #' @describeIn JackStrawData-methods Autocompletion for \code{$} access on a #' \code{JackStrawData} object #' #' @inheritParams utils::.DollarNames #' #' @importFrom utils .DollarNames #' @export #' @method .DollarNames JackStrawData #' ".DollarNames.JackStrawData" <- function(x, pattern = '') { slotnames <- as.list(x = slotNames(x = x)) names(x = slotnames) <- unlist(x = slotnames) return(.DollarNames(x = slotnames, pattern = pattern)) } #' @describeIn JackStrawData-methods Access data from a \code{JackStrawData} #' object #' #' @param i A \code{JackStrawData} slot name #' #' @return \code{$}: Slot \code{i} from \code{x} #' @export #' "$.JackStrawData" <- function(x, i, ...) { return(slot(object = x, name = i)) } #' @describeIn JackStrawData-methods Have empirical p-values for a #' \code{JackStrawData} object been calculated #' #' @return \code{as.logical}: \code{TRUE} if empirical p-values have been #' calculated otherwise \code{FALSE} #' #' @export #' @method as.logical JackStrawData #' as.logical.JackStrawData <- function(x, ...) { CheckDots(...) empP <- JS(object = x, slot = 'empirical') return(!(all(dim(x = empP) == 0) || all(is.na(x = empP)))) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @describeIn JackStrawData-methods Overview of a \code{JackStrawData} object #' #' @return \code{show}: Prints summary to \code{\link[base]{stdout}} and #' invisibly returns \code{NULL} #' #' @importFrom utils head #' @importFrom methods show #' #' @export #' setMethod( f = 'show', signature = 'JackStrawData', definition = function(object) { empp <- object$empirical.p.values scored <- object$overall.p.values cat( "A JackStrawData object simulated on", nrow(x = empp), "features for", ncol(x = empp), "dimensions.\n", "Scored for:", nrow(x = scored), "dimensions.\n" ) return(invisible(x = NULL)) } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SeuratObject/R/spatial.R0000644000176200001440000002652615114353666014652 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importFrom methods setClass slot slot<- new #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The SpatialImage class #' #' The \code{SpatialImage} class is a virtual class representing spatial #' information for Seurat. All spatial image information must inherit from this #' class for use with \code{Seurat} objects #' #' @slot assay Name of assay to associate image data with; will give this image #' priority for visualization when the assay is set as the active/default assay #' in a \code{Seurat} object #' @template slot-key #' @template slot-misc #' #' @name SpatialImage-class #' @rdname SpatialImage-class #' @exportClass SpatialImage #' #' @seealso \code{\link{SpatialImage-methods}} for a list of required and #' provided methods #' #' @aliases SpatialImage #' setClass( Class = 'SpatialImage', contains = 'VIRTUAL', slots = list( 'assay' = 'character', 'key' = 'character', 'misc' = 'OptionalList' ), prototype = list( 'misc' = list() ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{SpatialImage} methods #' #' Methods defined on the \code{\link{SpatialImage}} class. Some of these #' methods must be overridden in order to ensure proper functionality of the #' derived classes (see \strong{Required methods} below). Other methods are #' designed to work across all \code{SpatialImage}-derived subclasses, and #' should only be overridden if necessary #' #' @param x,object A \code{SpatialImage}-derived object #' @param ... Arguments passed to other methods #' @param value Depends on the method: #' \describe{ #' \item{\code{DefaultAssay<-}}{Assay that the image should be #' associated with} #' \item{\code{Key<-}}{New key for the image} #' } #' @inheritParams RenameCells #' #' @section Provided methods: #' These methods are defined on the \code{SpatialImage} object and should not #' be overridden without careful thought #' \itemize{ #' \item \code{\link{DefaultAssay}} and \code{\link{DefaultAssay<-}} #' \item \code{\link{Key}} and \code{\link{Key<-}} #' \item \code{\link{GetImage}}; this method \emph{can} be overridden to #' provide image data, normally returns empty image data. If overridden, #' should default to returning a \code{\link[grid]{grob}} object #' \item \code{\link{IsGlobal}} #' \item \code{\link{Radius}}; this method \emph{can} be overridden to #' provide a spot radius for image objects #' \item \code{\link[base:Extract]{[}}; this method \emph{can} be overridden #' to change default subset behavior, normally returns #' \code{subset(x = x, cells = i)}. If overridden, should only accept \code{i} #' } #' #' @section Required methods: #' All subclasses of the \code{SpatialImage} class must define the following #' methods; simply relying on the \code{SpatialImage} method will result in #' errors. For required parameters and their values, see the \code{Usage} and #' \code{Arguments} sections #' \describe{ #' \item{\code{\link{Cells}}}{ #' Return the cell/spot barcodes associated with each position #' } #' \item{\code{\link{dim}}}{ #' Return the dimensions of the image for plotting in \code{(Y, X)} format #' } #' \item{\code{\link{GetTissueCoordinates}}}{ #' Return tissue coordinates; by default, must return a two-column #' \code{data.frame} with x-coordinates in the first column and #' y-coordinates in the second #' } #' \item{\code{\link{Radius}}}{ #' Return the spot radius; returns \code{NULL} by default for use with #' non-spot image technologies #' } #' \item{\code{\link{RenameCells}}}{ #' Rename the cell/spot barcodes for this image #' } #' \item{\code{\link{subset}}}{ #' Subset the image data by cells/spots #' } #' } #' These methods are used throughout Seurat, so defining them and setting the #' proper defaults will allow subclasses of \code{SpatialImage} to work #' seamlessly #' #' @name SpatialImage-methods #' @rdname SpatialImage-methods #' #' @concept spatialimage #' NULL #' @describeIn SpatialImage-methods Get the cell names from an image #' (\strong{[Override]}) #' #' @return \strong{[Override]} \code{Cells}: should return cell names #' #' @method Cells SpatialImage #' @export #' Cells.SpatialImage <- function(x, ...) { stop( "'Cells' must be implemented for all subclasses of 'SpatialImage'", call. = FALSE ) } #' @describeIn SpatialImage-methods Get the associated assay of a #' \code{SpatialImage}-derived object #' #' @return \code{DefaultAssay}: The associated assay of a #' \code{SpatialImage}-derived object #' #' @method DefaultAssay SpatialImage #' @export #' #' @seealso \code{\link{DefaultAssay}} #' DefaultAssay.SpatialImage <- function(object, ...) { CheckDots(...) return(slot(object = object, name = 'assay')) } #' @describeIn SpatialImage-methods Set the associated assay of a #' \code{SpatialImage}-derived object #' #' @return \code{DefaultAssay<-}: \code{object} with the associated assay #' updated #' #' @method DefaultAssay<- SpatialImage #' @export #' "DefaultAssay<-.SpatialImage" <- function(object, ..., value) { CheckDots(...) slot(object = object, name = 'assay') <- value return(object) } #' @describeIn SpatialImage-methods Get the image data from a #' \code{SpatialImage}-derived object #' #' @inheritParams GetImage #' #' @return \strong{[Override]} \code{GetImage}: The image data from a #' \code{SpatialImage}-derived object #' #' @method GetImage SpatialImage #' @export #' #' @seealso \code{\link{GetImage}} #' GetImage.SpatialImage <- function( object, mode = c('grob', 'raster', 'plotly', 'raw'), ... ) { return(NullImage(mode = mode)) } #' @describeIn SpatialImage-methods Get tissue coordinates for a #' \code{SpatialImage}-derived object (\strong{[Override]}) #' #' @return \strong{[Override]} \code{GetTissueCoordinates}: ... #' #' @method GetTissueCoordinates SpatialImage #' @export #' #' @seealso \code{\link{GetTissueCoordinates}} #' GetTissueCoordinates.SpatialImage <- function(object, ...) { stop( "'GetTissueCoordinates' must be implemented for all subclasses of 'SpatialImage'", call. = FALSE ) } #' @describeIn SpatialImage-methods Globality test for #' \code{SpatialImage}-derived object #' #' @return \code{IsGlobal}: returns \code{TRUE} as images are, by default, #' global #' #' @method IsGlobal SpatialImage #' @export #' #' @seealso \code{\link{IsGlobal}} #' IsGlobal.SpatialImage <- function(object, ...) { return(TRUE) } #' @describeIn SpatialImage-methods Get the key for a #' \code{SpatialImage}-derived object #' #' @return \code{Key}: The key for a \code{SpatialImage}-derived object #' #' @method Key SpatialImage #' @export #' #' @seealso \code{\link{Key}} #' Key.SpatialImage <- function(object, ...) { CheckDots(...) # object <- UpdateSlots(object = object) return(slot(object = object, name = 'key')) } #' @describeIn SpatialImage-methods Set the key for a #' \code{SpatialImage}-derived object #' #' @return \code{Key<-}: \code{object} with the key set to \code{value} #' #' @method Key<- SpatialImage #' @export #' "Key<-.SpatialImage" <- function(object, ..., value) { CheckDots(...) object <- UpdateSlots(object = object) value <- UpdateKey(key = value) slot(object = object, name = 'key') <- value return(object) } #' @describeIn SpatialImage-methods Get the spot radius size #' #' @return \code{Radius}: The spot radius size; by default, returns \code{NULL} #' #' @method Radius SpatialImage #' @export #' Radius.SpatialImage <- function(object, ...) { return(NULL) } #' @describeIn SpatialImage-methods Rename cells in a #' \code{SpatialImage}-derived object (\strong{[Override]}) #' #' @return \strong{[Override]} \code{RenameCells}: \code{object} with the new #' cell names #' #' @method RenameCells SpatialImage #' @export #' #' @seealso \code{\link{RenameCells}} #' RenameCells.SpatialImage <- function(object, new.names = NULL, ...) { stop( "'RenameCells' must be implemented for all subclasses of 'SpatialImage'", call. = FALSE ) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @describeIn SpatialImage-methods Subset a \code{SpatialImage}-derived object #' #' @param i,cells A vector of cells to keep #' #' @return \code{[}, \code{subset}: \code{x}/\code{object} for only the cells #' requested #' #' @method [ SpatialImage #' @export #' "[.SpatialImage" <- function(x, i, ...) { return(subset(x = x, cells = i)) } #' @describeIn SpatialImage-methods Get the plotting dimensions of an image #' (\strong{[Override]}) #' #' @return \strong{[Override]} \code{dim}: The dimensions of the image data in #' (Y, X) format #' #' @method dim SpatialImage #' @export #' dim.SpatialImage <- function(x) { stop( "'dim' must be implemented for all subclasses of 'SpatialImage'", call. = FALSE ) } #' @describeIn SpatialImage-methods Subset a \code{SpatialImage}-derived object #' (\strong{[Override]}) #' #' @method subset SpatialImage #' @export #' subset.SpatialImage <- function(x, cells, ...) { stop("'subset' must be implemented for all subclasses of 'SpatialImage'") } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @describeIn SpatialImage-methods Overview of a \code{SpatialImage}-derived #' object #' #' @return \code{show}: Prints summary to \code{\link[base]{stdout}} and #' invisibly returns \code{NULL} #' #' @importFrom methods show #' #' @export #' setMethod( f = 'show', signature = 'SpatialImage', definition = function(object) { object <- UpdateSlots(object = object) cat( "Spatial data from the", class(x = object), "technology for", length(x = Cells(x = object)), "samples\n" ) cat("Associated assay:", DefaultAssay(object = object), "\n") cat("Image key:", Key(object = object), "\n") return(invisible(x = NULL)) } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Return a null image #' #' @inheritParams GetImage #' #' @return Varies by value of \code{mode}: #' \describe{ #' \item{\dQuote{grob}}{a \code{\link[grid]{nullGrob}}} #' \item{\dQuote{raster}}{an empty \code{\link[grDevices:as.raster]{raster}}} #' \item{\dQuote{plotly}}{a list with one named item: \code{value = FALSE}} #' \item{\dQuote{raw}}{returns \code{NULL}} #' } #' #' @importFrom grid nullGrob #' @importFrom grDevices as.raster #' #' @keywords internal #' #' @noRd #' NullImage <- function(mode = c('grob', 'raster', 'plotly', 'raw')) { mode <- mode[1] mode <- match.arg(arg = mode) image <- switch( EXPR = mode, 'grob' = nullGrob(), 'raster' = as.raster(x = new(Class = 'matrix')), 'plotly' = list('visible' = FALSE), 'raw' = NULL, stop("Unknown image mode: ", mode, call. = FALSE) ) return(image) } SeuratObject/R/data.R0000644000176200001440000000210115116320014014064 0ustar liggesusers#' A small example version of the PBMC dataset #' #' A subsetted version of 10X Genomics' 3k PBMC dataset #' #' @format A Seurat object with the following slots filled #' \describe{ #' \item{assays}{ #' \itemize{Currently only contains one assay ("RNA" - scRNA-seq expression data) #' \item{counts - Raw expression data} #' \item{data - Normalized expression data} #' \item{scale.data - Scaled expression data} #' \item{var.features - names of the current features selected as variable} #' \item{meta.features - Assay level metadata such as mean and variance} #' }} #' \item{meta.data}{Cell level metadata} #' \item{active.assay}{Current default assay} #' \item{active.ident}{Current default idents} #' \item{graphs}{Neighbor graphs computed, currently stores the SNN} #' \item{reductions}{Dimensional reductions: currently PCA and tSNE} #' \item{version}{Seurat version used to create the object} #' \item{commands}{Command history} #' } #' @source \url{https://www.10xgenomics.com/datasets/3-k-pbm-cs-from-a-healthy-donor-1-standard-1-1-0} #' "pbmc_small" SeuratObject/R/fov.R0000644000176200001440000007132315116356172013777 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @include centroids.R #' @include spatial.R #' @include molecules.R #' @include segmentation.R #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The Field of View Object #' #' A modern container for storing coordinates of spatially-resolved single #' cells. Capable of storing multiple cell segmentation boundary masks. #' Supports coordinates for spatially-resolved molecule (FISH) data. #' Compatible with \code{\link{SpatialImage}} #' #' @slot molecules A named list of #' \code{\link[SeuratObject:Molecules-class]{Molecules}} objects defining #' spatially-resolved molecular coordinates #' @slot boundaries A named list of #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}} and #' \code{\link[SeuratObject:Centroids-class]{Centroids}} objects defining #' spatially-resolved boundaries #' @slot coords_x_orientation A character indicating which axis #' \code{x} coordinates are associated with in spatial plots. #' Currently only applies to Visium objects. Ensures consistency in #' plotting spatial data across versions, as objects prior to the #' addition of this slot had \code{x} coordinates mapped to the vertical axis. #' @slot assay A character naming the associated assay #' of the spatial coordinates #' @template slot-key #' #' @exportClass FOV #' #' @aliases FOV #' #' @concept fov #' #' @seealso \code{\link{FOV-methods}} #' setClass( Class = 'FOV', contains = 'SpatialImage', slots = list( molecules = 'list', boundaries = 'list', coords_x_orientation = 'character' ), prototype = list( coords_x_orientation = character(0) ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{FOV} Methods #' #' Methods for \code{\link{FOV}} objects #' #' @details The following methods are defined for interacting with a #' \code{FOV} object: #' #' @param x,object A \code{\link{FOV}} object #' @param boundary,set Name of segmentation boundary or molecule set to #' extract cell or feature names for; pass \code{NA} to return all #' cells or feature names #' @param i,cells For \code{[[} and \code{[[<-}, the name of a segmentation or #' \dQuote{molecules}; for \code{FetchData}, \code{subset}. and \code{[}, a #' vector of cells to keep #' @param j,features For \code{subset} and \code{[}, a vector of features to #' keep; for \code{[[<-}, not used #' @param value For \code{[[<-}, a replacement #' \code{\link[SeuratObject:Molecules-class]{Molecules}}, #' \code{\link[SeuratObject:Centroids-class]{Centroids}}, or #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object; #' otherwise \code{NULL} to remove the boundary stored at \code{i} #' @param ... Arguments passed to other methods #' #' @name FOV-methods #' @rdname FOV-methods #' #' @concept fov #' #' @seealso \code{\link{FOV-class}} #' NULL #' @rdname Boundaries #' @method Boundaries FOV #' @export #' Boundaries.FOV <- function(object, ...) { return(names(x = slot(object = object, name = 'boundaries'))) } #' @template method-cells #' #' @rdname FOV-methods #' @method Cells FOV #' @export #' Cells.FOV <- function(x, boundary = NULL, ...) { boundary <- boundary[1L] %||% DefaultBoundary(object = x) if (is.na(x = boundary)) { return(Reduce( f = union, x = lapply(X = slot(object = x, name = 'boundaries'), FUN = Cells) )) } boundary <- match.arg(arg = boundary, choices = Boundaries(object = x)) return(Cells(x = x[[boundary]])) } #' @rdname CreateFOV #' @method CreateFOV Centroids #' @export #' CreateFOV.Centroids <- function( coords, molecules = NULL, assay = 'Spatial', key = NULL, misc = NULL, name = NULL, ... ) { name <- name %||% as.character(x = tolower(x = class(x = coords)[1L])) coords <- list(coords) names(x = coords) <- name return(CreateFOV( coords = coords, molecules = molecules, assay = assay, key = key, misc = misc %||% list() )) } #' @inheritParams CreateCentroids #' @param type When providing a \code{\link[base]{data.frame}}, specify if #' the coordinates represent a cell segmentation or voxel centroids #' @param molecules A \code{\link[base]{data.frame}} with spatially-resolved #' molecule information or a #' \code{\link[SeuratObject:Molecules-class]{Molecules}} object #' @param assay Name of associated assay #' @param key Key for these spatial coordinates #' @param name When \code{coords} is a \code{\link[base]{data.frame}}, #' \code{\link[SeuratObject:Centroids-class]{Centroids}}, or #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}}, name #' to store coordinates as #' @param misc A list of miscellaneous information to store with the object #' #' @rdname CreateFOV #' @method CreateFOV data.frame #' @export #' CreateFOV.data.frame <- function( coords, type = c('segmentation', 'centroids'), nsides = Inf, radius = NULL, theta = 0L, molecules = NULL, assay = 'Spatial', key = NULL, misc = NULL, name = NULL, ... ) { type <- match.arg(arg = type) name <- name %||% type coords <- switch( EXPR = type, 'segmentation' = CreateSegmentation(coords = coords), 'centroids' = CreateCentroids( coords = coords, nsides = nsides, radius = radius, theta = theta ) ) return(CreateFOV( coords = coords, molecules = molecules, assay = assay, key = key, misc = misc %||% list() )) } #' #' @rdname CreateFOV #' @method CreateFOV list #' @export #' CreateFOV.list <- function( coords, molecules = NULL, assay = 'Spatial', key = NULL, misc = NULL, ... ) { # Create a list of Molecules objects if provided; otherwise use an empty list molecules <- molecules %iff% list(molecules = CreateMolecules( coords = molecules, key = 'mols_' )) %||% list() # Create and validate the FOV object obj <- new( Class = 'FOV', boundaries = coords, molecules = molecules, assay = assay, key = key %||% Key(object = assay, quiet = TRUE), misc = misc %||% list() ) return(obj) } #' @rdname CreateFOV #' @method CreateFOV Segmentation #' @export #' CreateFOV.Segmentation <- CreateFOV.Centroids #' @rdname Crop #' @method Crop FOV #' @export #' Crop.FOV <- function( object, x = NULL, y = NULL, coords = c("plot", "tissue"), ... ) { if (is.null(x = x) && is.null(x = y)) { return(object) } for (s in names(x = object)) { object[[s]] <- Crop(object = object[[s]], x = x, y = y, coords = coords) } return(object) } #' @rdname Boundaries #' @method DefaultBoundary FOV #' @export #' DefaultBoundary.FOV <- function(object) { return(Boundaries(object = object)[1]) } #' @rdname Boundaries #' @method DefaultBoundary<- FOV #' @export #' "DefaultBoundary<-.FOV" <- function(object, ..., value) { value <- match.arg(arg = value, choices = Boundaries(object = object)) idx <- which(x = Boundaries(object = object) == value) norder <- c( idx, setdiff(x = seq_len(length.out = length(x = object)), y = idx) ) slot(object = object, name = 'boundaries') <- slot( object = object, name = 'boundaries' )[norder] return(object) } #' @template method-features #' #' @rdname FOV-methods #' @method Features FOV #' @export #' Features.FOV <- function(x, set = NULL, ...) { if (!length(x = Molecules(object = x))) { return(NULL) } set <- set[1L] %||% Molecules(object = x)[1L] if (is.na(x = set)) { return(Reduce( f = union, x = lapply(X = slot(object = x, name = 'molecules'), FUN = Features) )) } set <- match.arg(arg = set, choices = Molecules(object = x)) return(Features(x = x[[set]])) } #' @param vars A vector of variables to fetch; can be the name of a #' segmentation boundary, to get tissue coordinates, or molecule names, #' to get molecule coordinates #' @param simplify If only returning either boundary or molecule coordinates, #' return a single data frame instead of a list #' #' @details \code{FetchData}: Fetch boundary and/or molecule coordinates from #' a \code{FOV} object #' #' @return \code{FetchData}: If both molecule and boundary coordinates are #' requested, then a two-length list: #' \itemize{ #' \item \dQuote{\code{molecules}}: A data frame with the molecule coordinates #' requested. If molecules requested are keyed, the keys are preserved in the #' data frame #' \item \dQuote{\code{coordinates}}: A data frame with coordinates from the #' segmentation boundaries requested #' } #' If \code{simplify} is \code{TRUE} and only one data frame is generated, then #' only the data frame is returned. Otherwise, a one-length list is returned #' with the single data frame generated #' #' @rdname FOV-methods #' @method FetchData FOV #' @export #' FetchData.FOV <- function( object, vars, cells = NULL, simplify = TRUE, ... ) { vars.orig <- vars if (is.numeric(x = cells)) { cells <- Cells(x = object)[cells] } else if (is.null(cells)) { cells <- Cells(x = object) } # Find keyed molecules object.keys <- Keys(object = object) keyed.mols <- sapply( X = object.keys, FUN = function(key) { return(grep(pattern = paste0('^', key), x = vars, value = TRUE)) }, simplify = FALSE, USE.NAMES = TRUE ) keyed.mols <- Filter(f = length, x = keyed.mols) mols.fetched <- sapply( X = names(x = keyed.mols), FUN = function(x) { df <- FetchData(object = object[[x]], vars = keyed.mols[[x]], ...) df$molecule <- paste0(Key(object = object[[x]]), df$molecule) return(df) }, simplify = FALSE, USE.NAMES = TRUE ) vars <- setdiff( x = vars, y = unique(x = lapply( X = mols.fetched, FUN = function(df) { return(unique(x = df$molecule)) } )) ) # Find all other molecules unkeyed.mols <- Filter( f = function(x) { return(x %in% Features(x = object, set = NA)) }, x = vars ) if (length(x = unkeyed.mols)) { mols.default <- Molecules(object = object)[1L] unkeyed.fetched <- FetchData( object = object[[mols.default]], vars = unkeyed.mols, ... ) if (mols.default %in% names(x = mols.fetched)) { unkeyed.fetched$molecule <- paste0( Key(object = object[[mols.default]]), unkeyed.fetched$molecule ) vars <- setdiff(x = vars, y = unique(x = unkeyed.mols)) } mols.fetched <- append(x = mols.fetched, values = list(unkeyed.fetched)) } # Assembled the molecules data frame mols.fetched <- do.call(what = 'rbind', args = mols.fetched) rownames(x = mols.fetched) <- NULL vars <- setdiff(x = vars, y = unique(x = mols.fetched$molecule)) # Find all coordinates for the cells requested coords <- Filter( f = function(x) { return(x %in% Boundaries(object = object)) }, x = vars ) coords.fetched <- sapply( X = coords, FUN = function(x) { if (!is.null(x = cells) && !any(cells %in% Cells(x = object, boundary = coords))) { return(NULL) } df <- GetTissueCoordinates(object = subset(x = object[[x]], cells = cells)) df$boundary <- x return(df) }, simplify = FALSE, USE.NAMES = TRUE ) coords.fetched <- do.call(what = 'rbind', args = coords.fetched) rownames(x = coords.fetched) <- NULL vars <- setdiff(x = vars, y = unique(x = coords.fetched$boundary)) # Warn/error about missing vars if (identical(x = vars, y = vars.orig)) { stop("Unable to find any of the provided vars", call. = FALSE) } else if (length(x = vars)) { warning( "The following vars were not found: ", paste(vars, collapse = ', '), call. = FALSE, immediate. = TRUE ) } # Return fetched data data.fetched <- list(molecules = mols.fetched, coordinates = coords.fetched) data.fetched <- Filter(f = Negate(f = is.null), x = data.fetched) if (length(x = data.fetched) == 1L && isTRUE(x = simplify)) { return(data.fetched[[1L]]) } return(data.fetched) } #' @param which Name of segmentation boundary or molecule set to retrieve coordinates for; #' if NULL, will retrieve coordinates for the default boundary #' #' @examples #' \dontrun{ #' GetTissueCoordinates(object, which = "centroids") #' } #' @rdname GetTissueCoordinates #' @method GetTissueCoordinates FOV #' @export #' GetTissueCoordinates.FOV <- function(object, which = NULL, ...) { which <- which %||% DefaultBoundary(object = object) which <- match.arg(arg = which, choices = names(x = object)) return(GetTissueCoordinates(object = object[[which]], ...)) } #' @details \code{Keys}: Get the keys of molecule sets contained within a #' \code{FOV} object #' #' @return \code{Keys}: A named vector of molecule set keys; names are the #' names of the molecule sets and values are the keys for the respective #' molecule set #' #' @rdname FOV-methods #' @method Keys FOV #' @export #' Keys.FOV <- function(object, ...) { return(sapply(X = slot(object = object, name = 'molecules'), FUN = Key)) } #' @rdname Boundaries #' @method Molecules FOV #' @export #' Molecules.FOV <- function(object, ...) { return(names(x = slot(object = object, name = 'molecules'))) } #' @details \code{RenameCells}: Update cell names #' #' @inheritParams RenameCells #' #' @return \code{RenameCells}: \code{object} with the cells renamed to #' \code{new.names} #' #' @rdname FOV-methods #' @method RenameCells FOV #' @export #' RenameCells.FOV <- function(object, new.names = NULL, ...) { if (is.null(x = new.names)) { return(object) } new.names <- make.unique(names = new.names) all.cells <- Cells(x = object, boundary = NA) if (length(x = new.names) != length(x = all.cells)) { stop("Cannot partially rename cells", call. = FALSE) } for (boundary in Boundaries(object = object)) { idx <- MatchCells( new = all.cells, orig = Cells(x = object[[boundary]]), ordered = TRUE ) if (!length(x = idx)) { next } object[[boundary]] <- RenameCells( object = object[[boundary]], new.names = new.names[idx] ) } return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @importFrom utils .DollarNames #' #' @method .DollarNames FOV #' @export #' .DollarNames.FOV <- function(x, pattern = '') { layers <- as.list(x = names(x = x)) names(x = layers) <- unlist(x = layers) return(.DollarNames(x = layers, pattern = pattern)) } #' @rdname FOV-methods #' @method $ FOV #' @export #' "$.FOV" <- function(x, i, ...) { return(x[[i]]) } #' @rdname FOV-methods #' @method [ FOV #' @export #' "[.FOV" <- function(x, i, j, ...) { if (missing(x = i)) { i <- NULL } if (missing(x = j)) { j <- NULL } return(subset(x = x, cells = i, features = j, ...)) } #' @details \code{$}, \code{[[}: Extract a segmentation boundary #' #' @return \code{$}, \code{[[}: The segmentation boundary or spatially-resolved #' molecule information stored at \code{i} #' #' @rdname FOV-methods #' @method [[ FOV #' @export #' "[[.FOV" <- function(x, i, ...) { i <- match.arg(arg = i, choices = names(x = x)) slot.use <- ifelse( test = i %in% Molecules(object = x), yes = 'molecules', no = 'boundaries' ) return(slot(object = x, name = slot.use)[[i]]) } #' Aggregate Molecules into an Expression Matrix #' #' @param x An object with spatially-resolved molecule information #' @param by Name of a #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}} within #' \code{object} or a #' \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object #' @param set Name of molecule set to aggregate #' @param drop Drop molecules not present in a segmentation; if \code{FALSE}, #' adds a column called \dQuote{\code{boundless}} consisting of molecule counts #' not in a segmentation #' @param ... Arguments passed to other methods #' #' @return An expression matrix #' #' @importFrom stats aggregate #' #' @name aggregate #' @rdname aggregate #' #' @keywords internal #' #' @method aggregate FOV #' @export #' #' @template section-progressr #' @template section-future #' #' @order 1 #' aggregate.FOV <- function(x, by = NULL, set = NULL, drop = TRUE, ...) { # Check molecules set <- set[1L] %||% Molecules(object = x)[1L] if (is.null(x = set)) { stop("No molecules present in this FOV", call. = FALSE) } set <- match.arg(arg = set, choices = Molecules(object = x)) # Check segmentation boundaries by <- by[1L] %||% Filter( f = function(b) { return(inherits(x = x[[b]], what = 'Segmentation')) }, x = Boundaries(object = x) )[1L] if (is.character(x = by)) { by <- x[[by]] } if (!inherits(x = by, what = 'SpatialPolygons')) { stop("'by' is not a segmentation boundary", call. = FALSE) } # TODO: Check bbox intersect # Aggregate return(aggregate(x = x[[set]], by = by, drop = drop, ...)) } #' @method dim FOV #' @export #' dim.FOV <- function(x) { return(c(0, 0)) } #' @details \code{length}: Get the number of segmentation layers in a #' \code{FOV} object #' #' @return \code{length}: The number of segmentation layers #' (\code{\link[SeuratObject:Segmentation-class]{Segmentation}} or #' \code{\link[SeuratObject:Centroids-class]{Centroids}} objects) #' #' @rdname FOV-methods #' @method length FOV #' @export #' length.FOV <- function(x) { return(length(x = slot(object = x, name = 'boundaries'))) } #' @details \code{names}: Get the names of segmentation layers and molecule sets #' #' @return \code{names}: A vector of segmentation boundary and molecule set names #' #' @rdname FOV-methods #' @method names FOV #' @export #' names.FOV <- function(x) { return(c(Boundaries(object = x), Molecules(object = x))) } #' @details \code{subset}, \code{[}: Subset a \code{FOV} object #' #' @return \code{subset}: \code{x} with just the cells and features specified #' #' @rdname FOV-methods #' @method subset FOV #' @export #' subset.FOV <- function(x, cells = NULL, features = NULL, ...) { features <- Features(x = x) %iff% features if (is.null(x = cells) && is.null(x = features)) { return(x) } for (i in Molecules(object = x)) { x[[i]] <- subset(x = x[[i]], features = features) } if (is.numeric(x = cells)) { cells <- Cells(x = x, boundary = NA)[cells] } for (i in Boundaries(object = x)) { x[[i]] <- subset(x = x[[i]], cells = cells) } safeValidityCheck(object = x) return(x) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Add a Segmentation Boundary #' #' @param x A \code{\link{FOV}} object #' @param i Name to store segmentation boundary as #' @param ... Ignored #' @param value A \code{\link[SeuratObject:Segmentation-class]{Segmentation}} #' or [SeuratObject:Centroids-class]\code{\link{Centroids}} object #' to add #' #' @return \code{x} with \code{value} saved as \code{i} #' #' @importFrom methods as #' #' @keywords internal #' #' @noRd #' .AddSegmentation <- function(x, i, ..., value) { if (i %in% Molecules(object = x)) { stop("'", i, "' already present as molecules", call. = FALSE) } # Check bounding box if (!.BboxIntersect(i = bbox(obj = value), j = bbox(obj = x), constraint = 'overlap')) { stop( "New segmentation boundary does not overlap with existing bounds", call. = FALSE ) } # # Reorder cells # vcells <- MatchCells( # new = Cells(x = value), # orig = Cells(x = x, boundary = NA), # ordered = TRUE # ) # vcells <- c( # vcells, # setdiff( # x = seq.int(from = 1L, to = length(x = Cells(x = value))), # y = vcells # ) # ) # value <- value[vcells] # Check class if (i %in% Boundaries(object = x)) { same.class <- vapply( X = list(x[[i]], value), FUN = inherits, FUN.VALUE = logical(length = 1L), what = 'Segmentation' ) if (length(x = unique(x = same.class)) != 1L) { warning( "Replacement value for ", i, " not of class ", class(x = x[[i]]), call. = FALSE, immediate. = TRUE ) } } # Add segmentation boundary slot(object = x, name = 'boundaries')[[i]] <- value # Reorder cells x <- .OrderCells(object = x) # Validate and return safeValidityCheck(object = x) return(x) } #' Order cells in an FOV #' #' @param object An \code{\link[SeuratObject:FOV-class]{FOV}} object #' #' @return \code{object} with the cells in each boundary ordered #' #' @keywords internal #' #' @noRd #' .OrderCells <- function(object) { all.cells <- Cells(x = object, boundary = NA) for (b in Boundaries(object = object)) { bcells <- MatchCells( new = Cells(x = object[[b]]), orig = all.cells, ordered = TRUE ) bcells <- c( bcells, setdiff(x = seq_along(along.with = Cells(x = object[[b]])), y = bcells) ) slot(object = object, name = 'boundaries')[[b]] <- object[[b]][bcells] } return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @details \code{[[<-}: Add or remove segmentation layers and molecule #' information to/from a \code{FOV} object #' #' @return \code{[[<-}: Varies depending on the class of \code{value}: #' \itemize{ #' \item If \code{value} is \code{NULL}, returns \code{x} with the boundary #' \code{i} removed; also allows removing \code{molecules}; does not allow #' removing the default segmentation #' \item If \code{value} is a \code{Molecules}, returns \code{x} with #' \code{value} stored in \code{molecules}; requires that \code{i} is #' \dQuote{molecules} #' \item Otherwise, stores \code{value} as a segmentation boundary named \code{i} #' } #' #' @rdname FOV-methods #' setMethod( f = '[[<-', signature = c( x = 'FOV', i = 'character', j = 'missing', value = 'Centroids' ), definition = .AddSegmentation ) #' @rdname FOV-methods #' setMethod( f = '[[<-', signature = c( x = 'FOV', i = 'character', j = 'missing', value = 'Molecules' ), definition = function(x, i, ..., value) { if (i %in% Boundaries(object = x)) { stop("'", i, "' already present as a segmentation boundary") } check.key <- TRUE # Check bounding box for incoming molecules if (!.BboxIntersect(i = bbox(obj = value), j = bbox(obj = x), constraint = 'overlap')) { stop("New molecules do not overlap with existing bounds") } # TODO: Check replacement molecules if (i %in% Molecules(object = x)) { check.key <- Key(object = value) != Key(object = x[[i]]) } if (isTRUE(x = check.key)) { if (Key(object = value) %in% Keys(object = x)) { key <- Key(object = i, quiet = TRUE) while (key %in% Keys(object = x)) { key <- Key(object = RandomName(), quiet = TRUE) } warning( "Duplicate moleculecular keys, changing to '", key, "'", call. = FALSE, immediate. = TRUE ) Key(object = value) <- key } } # Add incoming molecules slot(object = x, name = 'molecules')[[i]] <- value # Validate and return safeValidityCheck(object = x) return(x) } ) #' @importFrom methods as #' #' @rdname FOV-methods #' setMethod( f = '[[<-', signature = c( x = 'FOV', i = 'character', j = 'missing', value = 'NULL' ), definition = function(x, i, ..., value) { i <- match.arg(arg = i, choices = names(x = x)) if (inherits(x = x[[i]], what = 'Molecules')) { slot(object = x, name = 'molecules')[[i]] <- NULL } else if (i == DefaultBoundary(object = x)) { stop("Cannot remove default boundary", call. = FALSE) } else { slot(object = x, name = 'boundaries')[[i]] <- NULL } safeValidityCheck(object = x) return(x) } ) #' @rdname FOV-methods #' setMethod( f = '[[<-', signature = c( x = 'FOV', i = 'character', j = 'missing', value = 'Segmentation' ), definition = .AddSegmentation ) setMethod( f = 'bbox', signature = 'FOV', definition = function(obj) { boxes <- lapply(X = slot(object = obj, name = 'boundaries'), FUN = bbox) boxes <- do.call(what = 'cbind', args = boxes) return(bbox(obj = t(x = boxes))) } ) #' @importFrom methods initialize #' setMethod( f = 'initialize', signature = 'FOV', definition = function(.Object, ...) { .Object <- callNextMethod(.Object, ...) .Object <- .OrderCells(object = .Object) safeValidityCheck(object = .Object) return(.Object) } ) #' @importClassesFrom sp Spatial #' @rdname Overlay #' setMethod( f = 'Overlay', signature = c(x = 'FOV', y = 'Spatial'), definition = .OverBbox ) #' @rdname Overlay #' setMethod( f = 'Overlay', signature = c(x = 'FOV', y = 'SpatialPolygons'), definition = function(x, y, invert = FALSE, ...) { for (i in names(x = x)) { x[[i]] <- Overlay(x = x[[i]], y = y, invert = invert, ...) } return(x) } ) #' @rdname Overlay #' setMethod( f = 'Overlay', signature = c(x = 'FOV', y = 'FOV'), definition = .OverBbox ) #' @template method-show #' #' @rdname FOV-methods #' setMethod( f = 'show', signature = c(object = 'FOV'), definition = function(object) { # Show cell information cat( "Spatial coordinates for", length(x = Cells(x = object, boundary = NA)), "cells" ) # Show molecule information if (length(x = Features(x = object, boundary = NA))) { cat(" and", length(x = Features(x = object, boundary = NA)), "molecules\n") cat( " First 10 molecules:", strwrap(x = paste( head(x = Features(x = object, boundary = NA)), collapse = ', ' )) ) } cat("\n") # Show segmentation information cat( "Default segmentation boundary:", DefaultBoundary(object = object), "\n" ) if (length(x = Boundaries(object = object)) > 1L) { segs <- setdiff( x = Boundaries(object = object), y = DefaultBoundary(object = object) ) cat( character(), length(x = segs), "other segmentation boundaries present:", strwrap(x = paste(segs, collapse = ', ')), "\n" ) } # Show associated assay cat("Associated assay:", DefaultAssay(object = object), "\n") # Show key cat("Key:", Key(object = object), "\n") return(invisible(x = NULL)) } ) #' FOV Validity #' #' @templateVar cls FOV #' @template desc-validity #' #' @section Boundary Validation: #' blah #' #' @section Molecule Validation: #' blah #' #' @name FOV-validity #' #' @family fov #' #' @seealso \code{\link[methods]{validObject}} #' setValidity( Class = 'FOV', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Check boundaries nlist <- IsNamedList( x = slot(object = object, name = 'boundaries'), pass.zero = TRUE ) if (!isTRUE(x = nlist)) { valid <- c(valid, "'boundaries' must be a named list") } else { all.cells <- Cells(x = object, boundary = NA) for (s in Boundaries(object = object)) { if (!inherits(x = object[[s]], what = c('Segmentation', 'Centroids'))) { valid <- c( valid, "All segmentation boundaries must be either either a 'Segmentation' or 'Centroids' object" ) break } else { cells <- Cells(x = object[[s]]) if (!is.null(cells)) { matched.cells <- MatchCells( new = all.cells, orig = cells, ordered = TRUE ) if (length(x = matched.cells) != length(x = Cells(x = object[[s]]))) { valid <- c( valid, "All segmentation boundaries must have cells" ) break } } else { valid <- c( valid, paste(s, "contains 0 cells") ) break } } } } # Check molecules nlist <- IsNamedList( x = slot(object = object, name = 'molecules'), pass.zero = TRUE ) if (!isTRUE(x = nlist)) { valid <- c(valid, "'molecules' must be a named list") } else { for (m in Molecules(object = object)) { if (!inherits(x = object[[m]], what = 'Molecules')) { valid <- c(valid, "All molecules must inherit from 'Molecules'") break } } } return(valid %||% TRUE) } ) SeuratObject/R/neighbor.R0000644000176200001440000001153415075522101014767 0ustar liggesusers#' @include zzz.R #' @include generics.R #' @importFrom methods new slot slot<- #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' The Neighbor class #' #' The Neighbor class is used to store the results of neighbor finding #' algorithms #' #' @slot nn.idx Matrix containing the nearest neighbor indices #' @slot nn.dist Matrix containing the nearest neighbor distances #' @slot alg.idx The neighbor finding index (if applicable). E.g. the annoy #' index #' @slot alg.info Any information associated with the algorithm that may be #' needed downstream (e.g. distance metric used with annoy is needed when #' reading in from stored file). #' @slot cell.names Names of the cells for which the neighbors have been #' computed. #' #' @name Neighbor-class #' @rdname Neighbor-class #' @exportClass Neighbor #' Neighbor <- setClass( Class = 'Neighbor', slots = c( nn.idx = 'matrix', nn.dist = 'matrix', alg.idx = 'ANY', alg.info = 'list', cell.names = 'character' ) ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @rdname as.Neighbor #' @export #' @method as.Neighbor Graph #' as.Neighbor.Graph <- function(x, ...) { nn.mats <- GraphToNeighborHelper(mat = x) return(Neighbor( nn.idx = nn.mats[[1]], nn.dist = nn.mats[[2]], cell.names = rownames(x = x) )) } #' @rdname Cells #' @method Cells Neighbor #' @export #' Cells.Neighbor <- function(x, ...) { return(slot(object = x, name = "cell.names")) } #' @rdname Distances #' @export #' @method Distances Neighbor #' Distances.Neighbor <- function(object, ...) { object <- UpdateSlots(object = object) distances <- slot(object = object, name = "nn.dist") rownames(x = distances) <- slot(object = object, name = "cell.names") return(distances) } #' @rdname NNIndex #' @export #' @method Index Neighbor #' Index.Neighbor <- function(object, ...) { object <- UpdateSlots(object = object) index <- slot(object = object, name = "alg.idx") if (is.null(x = index)) { return(NULL) } else if (IsNullPtr(x = index$.pointer)) { return(NULL) } return(index) } #' @rdname NNIndex #' @export #' @method Index<- Neighbor #' "Index<-.Neighbor" <- function(object, ..., value) { CheckDots(...) slot(object = object, name = "alg.idx") <- value return(object) } #' @rdname Indices #' @export #' @method Indices Neighbor #' Indices.Neighbor <- function(object, ...) { object <- UpdateSlots(object = object) indices <- slot(object = object, name = "nn.idx") rownames(x = indices) <- slot(object = object, name = "cell.names") return(indices) } #' @param old.names vector of old cell names #' @rdname RenameCells #' @export #' @method RenameCells Neighbor #' RenameCells.Neighbor <- function( object, old.names = NULL, new.names = NULL, ... ) { CheckDots(...) neighbor.names <- Cells(x = object) names(x = new.names) <- old.names slot(object = object, name = "cell.names") <- unname(obj = new.names[neighbor.names]) return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' \code{Neighbor} Methods #' #' Methods for \code{\link{Neighbor}} objects for generics defined in #' other packages #' #' @param x,object A \code{\link{Neighbor}} object #' #' @name Neighbor-methods #' @rdname Neighbor-methods #' #' @concept neighbor #' NULL #' @describeIn Neighbor-methods Dimensions of the neighbor indices #' #' @return \code{dim} Dimensions of the indices matrix #' #' @export #' @method dim Neighbor #' dim.Neighbor <- function(x) { return(dim(x = Indices(object = x))) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @describeIn Neighbor-methods Overview of a \code{Neighbor} object #' #' @return \code{show}: Prints summary to \code{\link[base]{stdout}} and #' invisibly returns \code{NULL} #' #' @importFrom methods show #' #' @export #' setMethod( f = 'show', signature = 'Neighbor', definition = function(object) { cat( "A Neighbor object containing the", ncol(x = object), "nearest neighbors for", nrow(x = object), "cells" ) } ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SeuratObject/R/keymixin.R0000644000176200001440000002025015075522101015022 0ustar liggesusers#' @include zzz.R #' @include generics.R #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' A Mixin for Keyed objects #' #' A mixin (virtual class) for enabling keyed objects; provides consistent #' behavior for getting, setting, and validating keys #' #' @template slot-key #' #' @keywords internal #' #' @exportClass KeyMixin #' #' @aliases KeyMixin #' #' @family key #' setClass( Class = 'KeyMixin', contains = 'VIRTUAL', slots = list(key = 'character') ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Regex Pattern for Keys #' #' @return Returns the regex pattern for keys #' (\dQuote{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}) #' #' @keywords internal #' #' @export #' #' @family key #' .KeyPattern <- \() '^[a-zA-Z][a-zA-Z0-9]*_$' #' Generate a Random Key #' #' @inheritParams RandomName #' #' @return Returns a valid key #' #' @keywords internal #' #' @export #' #' @family key #' #' @examples #' set.seed(42L) #' .RandomKey() #' .RandomKey <- \(length = 7L, ...) Key( object = RandomName( length = length, chars = c(letters, LETTERS, seq.int(from = 0L, to = 9L)), ... ), quiet = TRUE ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @param object An object #' @param ... Ignored #' @param quiet Suppress warnings when updating characters to keys #' @param value A key to set #' #' @details \code{Key.character}: Update a character to a key #' #' @return \code{Key.character}: \code{object} but as a syntactically-valid key #' #' @rdname KeyMixin-class #' @method Key character #' @export #' Key.character <- \(object, ..., quiet = FALSE) withCallingHandlers( expr = UpdateKey(key = object), updatedKeyWarning = \(cnd) tryInvokeRestart(r = ifelse( test = isTRUE(x = quiet), yes = 'muffleWarning', no = RandomName() )) ) #' @details \code{Key.KeyMixin}: Get the key of a keyed object #' #' @return \code{Key.KeyMixin}: The key from \code{object}; if no key set, #' returns \code{NULL} #' #' @rdname KeyMixin-class #' @method Key KeyMixin #' @export #' Key.KeyMixin <- function(object, ...) { key <- slot(object = object, name = 'key') if (!length(x = key)) { key <- NULL } return(key) } #' @details \code{Key<-}: Set the key of a keyed object #' #' @return \code{Key<-}: \code{object} with the key set to \code{value} #' #' @rdname KeyMixin-class #' @method Key<- KeyMixin #' @export #' "Key<-.KeyMixin" <- function(object, ..., value) { slot(object = object, name = 'key') <- Key(object = value, ...) validObject(object = object) return(object) } #' @method Key NULL #' @export #' Key.NULL <- \(object, ...) NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Check Usage of Existing Keys #' #' Check key usage against existing keys to ensure key uniqueness #' #' @param key Existing key to check usage of; if missing, creates a #' key from \code{name} #' @param existing A vector of existing keys to match against \code{key} #' @param name Name of object that \code{key} is used for; if provided and #' \code{existing} is named, the entry of \code{existing} for \code{name} is #' removed from the check #' #' @return A key guaranteed to be unique in the context of \code{existing} #' #' @keywords internal #' #' @noRd #' .CheckKey <- function(key, existing = NULL, name = NULL) { if (rlang::is_missing(x = key) || !length(x = key) || !nzchar(x = key)) { key <- Key(object = tolower(name) %||% RandomName(), quiet = TRUE) } key <- Key(object = key, quiet = TRUE) if (!is.null(x = names(x = existing)) && !is.null(x = name)) { existing <- existing[setdiff(x = names(x = existing), y = name)] } if (key %in% existing) { old <- key key <- Key(object = tolower(x = name %||% RandomName()), quiet = TRUE) i <- 1L n <- 5L while (key %in% existing) { key <- Key(object = RandomName(length = n), quiet = TRUE) i <- i + 1L if (!i %% 7L) { n <- n + 2L } } warn( message = paste( "Key", sQuote(x = old), "taken, using", sQuote(x = key), "instead" ), class = 'existingKeyWarning' ) } return(key) } #' Internal Key Methods #' #' Internal key methods for classes that inherit from \code{\link{KeyMixin}}; #' these functions are designed to be used as the body for methods for #' \code{Key()} and \code{Key<-()} when an immediate public method is required. #' Generally speaking, classes that inherit from \code{KeyMixin} should use the #' \code{KeyMixin} methods for \code{Key()} and \code{Key<-()} #' #' @inheritParams Key #' #' @inherit Key return #' #' @keywords internal #' #' @noRd #' .Key <- function(object, ...) { CheckDots(...) return(NextMethod()) } #' @rdname dot-Key #' #' @noRd #' ".Key<-" <- function(object, ..., value) { CheckDots(...) object <- UpdateSlots(object = object) object <- NextMethod() return(object) } #' Update a Key #' #' @param key A character to become a Seurat Key #' #' @return An updated Key that's valid for Seurat #' #' @keywords internal #' #' @family key #' #' @noRd #' UpdateKey <- function(key) { key.msg <- 'Keys should be one or more alphanumeric characters followed by an underscore' if (isTRUE(x = grepl(pattern = .KeyPattern(), x = key))) { return(key) } new.key <- regmatches( x = key, m = gregexpr(pattern = '[[:alnum:]]+', text = key) ) new.key <- paste0(paste(unlist(x = new.key), collapse = ''), '_') if (new.key == '_') { new.key <- paste0(RandomName(length = 3), '_') } warn( message = paste0( key.msg, ", setting key from ", key, " to ", new.key ), class = 'updatedKeyWarning' ) return(new.key) } .MetaKey <- Key(object = 'md', quiet = TRUE) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Key Validity #' #' Validation of \code{\link{KeyMixin}} objects is handled by #' \code{\link[methods]{validObject}} #' #' @section Key Validation: #' Keys must be a one-length character vector; a key must be composed of one #' of the following: #' \itemize{ #' \item An empty string (eg. \dQuote{\code{''}}) where \code{nchar() == 0} #' \item An string composed of one or more alphanumeric values #' (both lower- and upper-case) that ends with an underscore #' (\dQuote{\code{_}}); the first character must be a letter #' } #' Keys that are not empty strings are validated with the regex #' \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}} #' #' @importFrom rlang is_scalar_character #' #' @keywords internal #' #' @name Key-validity #' #' @family key #' setValidity( Class = 'KeyMixin', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL key <- Key(object = object) # Ensure key has length of 1 if (!is.null(x = key) && .GetSeuratCompat() >= '5.0.0') { if (!is_scalar_character(x = key)) { valid <- c(valid, "Keys must be a one-length character vector") } else if (is_na(x = key)) { valid <- c(valid, "Keys may not be 'NA'") } else if (nzchar(x = key) && !grepl(pattern = .KeyPattern(), x = key)) { # Ensure proper key composition valid <- c( valid, paste("Keys must match the pattern", sQuote(x = .KeyPattern())) ) } } return(valid %||% TRUE) } ) SeuratObject/R/assay5.R0000644000176200001440000027157515116320014014407 0ustar liggesusers#' @include zzz.R #' @include assay.R #' @include layers.R #' @include logmap.R #' @include keymixin.R #' @importFrom methods callNextMethod setAs #' NULL #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Class definitions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Core Assay Infrastructure #' #' The \code{StdAssay} class is a virtual class that provides core #' infrastructure for assay data in \pkg{Seurat}. Assays contain expression #' data (layers) and associated feature-level meta data. Derived classes #' (eg. \link[=Assay5]{the v5 Assay}) may optionally #' define additional functionality #' #' @template slot-stdassay #' @template slot-misc #' @template slot-key #' #' @keywords internal #' #' @exportClass StdAssay #' #' @aliases StdAssay #' #' @family stdassay #' #' @seealso \code{\link{Assay5-class}} \code{\link{Assay5T-class}} #' setClass( Class = 'StdAssay', contains = c('VIRTUAL', 'KeyMixin'), slots = c( layers = 'list', cells = 'LogMap', features = 'LogMap', default = 'integer', assay.orig = 'character', meta.data = 'data.frame', misc = 'list' ) ) #' The v5 \code{Assay} Object #' #' The v5 \code{Assay} is the typical \code{Assay} class used in \pkg{Seurat} #' v5; ... #' #' @template slot-stdassay #' @template slot-misc #' @template slot-key #' #' @exportClass Assay5 #' #' @aliases Assay5 #' #' @family assay5 #' setClass( Class = 'Assay5', contains = 'StdAssay' ) #' The Transposed v5 \code{Assay} Object #' #' @template slot-stdassay #' @template slot-misc #' @template slot-key #' #' @template lifecycle-experimental #' #' @keywords internal #' #' @aliases Assay5T #' setClass( Class = 'Assay5T', contains = 'StdAssay' ) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Functions #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' Create a v5 Assay object #' #' Create an \code{\link{Assay5}} object from a feature expression matrix; #' the expected format of the matrix is features x cells #' #' @inheritParams .CreateStdAssay #' @param data Optional prenormalized data matrix #' @template param-dots-method # @param transpose Create a transposed assay # @param ... Extra parameters passed to \code{\link{.CreateStdAssay}} #' #' @return An \code{\link{Assay5}} object #' #' @export #' #' @concept assay #' CreateAssay5Object <- function( counts = NULL, data = NULL, min.cells = 0, min.features = 0, csum = NULL, fsum = NULL, ... ) { transpose <- FALSE colsums <- Matrix::colSums rowsums <- Matrix::rowSums type <- 'Assay5' csum <- csum %||% colsums fsum <- fsum %||% rowsums counts <- CheckLayersName(matrix.list = counts, layers.type = 'counts') data <- CheckLayersName(matrix.list = data, layers.type = 'data') if (!is.null(x = counts) & !is.null(data)) { counts.cells <- unlist( x = lapply( X = counts, FUN = function(x) colnames(x = x) ) ) data.cells <- unlist( x = lapply( X = data, FUN = function(x) colnames(x) ) ) if (!all(counts.cells == data.cells)) { abort(message = 'counts and data input should have the same cells') } } counts <- c(counts, data) data <- NULL CheckGC() return(.CreateStdAssay( counts = counts, min.cells = min.cells, min.features = min.features, transpose = transpose, type = type, csum = csum, fsum = fsum, ... )) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for Seurat-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @method .AssayClass Assay5T #' @export #' .AssayClass.Assay5T <- function(object) { return('Transposed Assay (v5)') } #' @method .CalcN StdAssay #' @export #' .CalcN.StdAssay <- function(object, layer = 'counts', simplify = TRUE, ...) { layer <- tryCatch( expr = Layers(object = object, search = layer), error = \(...) NULL ) # %||% DefaultLayer(object = object) if (is.null(x = layer)) { warn( message = "Cannot find the layer(s) specified", class = 'missingLayerWarning' ) return(NULL) } calcn <- vector(mode = 'list', length = length(x = layer)) names(x = calcn) <- layer for (lyr in layer) { ldat <- LayerData(object = object, layer = lyr) if (IsMatrixEmpty(x = ldat)) { next } calcn[[lyr]] <- .CalcN(object = ldat) } calcn <- Filter(f = length, x = calcn) # If every layer is empty, return `NULL` if (!length(x = calcn)) { return(NULL) } else if (isFALSE(x = simplify)) { # If we're not simplifying, return the list as-is return(calcn) } else if (length(x = calcn) == 1L) { # If we're only calculating N for one layer, return those results return(calcn[[1L]]) } # Simplify the calcn list for all cells all.cells <- Cells(x = object, layer = layer, simplify = TRUE) ncells <- length(x = all.cells) ncalc <- list( nCount = vector(mode = 'numeric', length = ncells), nFeature = vector(mode = 'numeric', length = ncells) ) names(x = ncalc$nCount) <- names(x = ncalc$nFeature) <- all.cells # For every layer, add the nCount and nFeature counts to existing cells for (i in seq_along(along.with = calcn)) { lcells <- names(x = calcn[[i]][['nCount']]) ncalc[['nCount']][lcells] <- calcn[[i]][['nCount']] + ncalc[['nCount']][lcells] ncalc[['nFeature']][lcells] <- calcn[[i]][['nFeature']] + ncalc[['nFeature']][lcells] } return(ncalc) } #' @method .CalcN default #' @export #' .CalcN.default <- function(object, ...) { return(list( nCount = Matrix::colSums(x = object), nFeature = Matrix::colSums(x = object > 0) )) } #' @param layer Name of layer to store \code{counts} as #' #' @rdname dot-CreateStdAssay #' @method .CreateStdAssay default #' @export #' .CreateStdAssay.default <- function( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = 'Assay5', layer = 'counts', ... ) { if (!is_bare_integerish(x = dim(x = counts), n = 2L, finite = TRUE)) { abort(message = "'counts' must be a two-dimensional object") } dnames <- dimnames(x = counts) cls <- class(x = counts) if (isTRUE(x = transpose)) { csum <- .GetMethod(fxn = 'rowSums', cls = cls) cells <- cells %||% dnames[[1L]] fsum <- .GetMethod(fxn = 'colSums', cls = cls) features <- features %||% dnames[[2L]] } else { csum <- .GetMethod(fxn = 'colSums', cls = cls) cells <- cells %||% dnames[[2L]] fsum <- .GetMethod(fxn = 'rowSums', cls = cls) features <- features %||% dnames[[1L]] } counts <- list(counts) names(x = counts) <- layer return(.CreateStdAssay( counts = counts, min.cells = min.cells, layer = layer, min.features = min.features, cells = cells, features = features, transpose = transpose, type = type, fsum = fsum, csum = csum, ... )) } #' @param csum Function for calculating cell sums #' @param fsum Function for calculating feature sums #' #' @importFrom methods getClass #' @importFrom utils getS3method methods #' #' @rdname dot-CreateStdAssay #' @method .CreateStdAssay list #' @export #' .CreateStdAssay.list <- function( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = 'Assay5', csum = Matrix::colSums, fsum = Matrix::rowSums, ... ) { # Figure out feature/cell MARGINs cdef <- getClass(Class = type) contains <- names(x = slot(object = cdef, name = 'contains')) if (!'StdAssay' %in% contains) { stop("Class '", type, "' does not inherit from StdAssay") } for (i in c(type, contains, 'default')) { fmargin <- getS3method(f = '.MARGIN', class = i, optional = TRUE) if (is.function(x = fmargin)) { break } } cdim <- fmargin(object = type, type = 'cells') fdim <- fmargin(object = type, type = 'features') counts <- lapply(X = counts, FUN = function(x) { x <- CheckFeaturesNames(data = x) return(x) }) # Check cell/feature names for all layers if (is.atomic(x = cells) || is.null(x = cells)) { cells <- rep_len(x = list(cells), length.out = length(x = counts)) } if (!is_bare_list(x = cells) || length(x = cells) != length(x = counts)) { stop("Not enough cells for the counts matrices provided", call. = FALSE) } cells <- .CheckNames(x = cells, n = names(x = counts)) if (is.atomic(x = features) || is.null(x = features)) { features <- rep_len(x = list(features), length.out = length(x = counts)) } if (!is_bare_list(x = features) || length(x = features) != length(x = counts)) { stop("Not enough features for the counts matrices provided", call. = FALSE) } features <- .CheckNames(x = features, n = names(x = counts)) for (layer in names(x = counts)) { cells[[layer]] <- cells[[layer]] %||% dimnames(x = counts[[layer]])[[cdim]] %||% paste0('Cell_', seq_len(length.out = dim(x = counts[[layer]])[cdim])) features[[layer]] <- features[[layer]] %||% dimnames(x = counts[[layer]])[[fdim]] %||% paste0('Feature', seq_len(length.out = dim(x = counts[[layer]])[fdim])) } # Filter based on min.features if (min.features > 0) { for (layer in names(x = counts)) { if (inherits(x = counts[[layer]], what = "IterableMatrix")) { check_installed(pkg = 'BPCells', reason = 'for working with BPCells') col_stat <- BPCells::matrix_stats(matrix = counts[[layer]], col_stats = 'nonzero')$col_stats cells.use <- which(x = col_stat >= min.features) } else { cells.use <- which(x = csum(counts[[layer]] > 0) >= min.features) } counts[[layer]] <- if (cdim == 1L) { counts[[layer]][cells.use, ] } else { counts[[layer]][, cells.use] } cells[[layer]] <- cells[[layer]][cells.use] } } # For now, coerce to dgCMatrix if not dgCMatrix, IterableMatrix, or DelayedArray if (!inherits(x = counts[[layer]], what = c('dgCMatrix', 'IterableMatrix', 'DelayedArray'))) { warning('Data is of class ', class(counts[[layer]])[1], ". Coercing to dgCMatrix.", call. = FALSE, immediate. = TRUE) if (inherits(x = counts[[layer]], what = "data.frame")) { counts[[layer]] <- as.sparse(x = counts[[layer]], ...) } else { counts[[layer]] <- as.sparse(x = counts[[layer]]) } } # Filter based on min.cells if (min.cells > 0) { for (layer in names(x = counts)) { if (inherits(x = counts[[layer]], what = "IterableMatrix")) { check_installed(pkg = 'BPCells', reason = 'for working with BPCells') row_stat <- BPCells::matrix_stats(matrix = counts[[layer]], row_stats = 'nonzero')$row_stats features.use <- which(x = row_stat >= min.cells) } else { features.use <- which(x = fsum(counts[[layer]] > 0) >= min.cells) } counts[[layer]] <- if (fdim == 1L) { counts[[layer]][features.use, ] } else { counts[[layer]][, features.use] } features[[layer]] <- features[[layer]][features.use] } } features.all <- Reduce(f = union, x = features) cells.all <- Reduce(f = union, x = cells) calcN_option <- getOption( x = 'Seurat.object.assay.calcn', default = Seurat.options$Seurat.object.assay.calcn ) # Create the object object <- new( Class = type, layers = list(), default = 0L, features = LogMap(y = features.all), cells = LogMap(y = cells.all), meta.data = EmptyDF(n = length(x = features.all)), misc = list(calcN = calcN_option %||% TRUE), ... ) for (layer in names(x = counts)) { LayerData( object = object, layer = layer, features = features[[layer]], cells = cells[[layer]], transpose = transpose ) <- counts[[layer]] } DefaultLayer(object = object) <- Layers(object = object)[1L] validObject(object = object) return(object) } #' @rdname dot-CreateStdAssay #' @method .CreateStdAssay Matrix #' @export #' .CreateStdAssay.Matrix <- function( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = 'Assay5', layer = 'counts', ... ) { counts <- list(counts) names(x = counts) <- layer if (isTRUE(x = transpose)) { csum <- Matrix::rowSums fsum <- Matrix::colSums } else { csum <- Matrix::colSums fsum <- Matrix::rowSums } return(.CreateStdAssay( counts = counts, layer = layer, min.cells = min.cells, min.features = min.features, cells = cells, features = features, transpose = transpose, type = type, csum = csum, fsum = fsum, ... )) } #' @rdname dot-CreateStdAssay #' @method .CreateStdAssay matrix #' @export #' .CreateStdAssay.matrix <- .CreateStdAssay.Matrix #' @method .MARGIN Assay5T #' @export #' .MARGIN.Assay5T <- function(x, type = c('features', 'cells'), ...) { type <- type[1] type <- match.arg(arg = type) return(unname(obj = c(features = 2L, cells = 1L)[type])) } #' @templateVar fxn AddMetaData #' @template method-stdassay #' #' @method AddMetaData StdAssay #' @export #' AddMetaData.StdAssay <- AddMetaData.Assay #' @rdname AddMetaData #' @method AddMetaData Assay5 #' @export #' AddMetaData.Assay5 <- AddMetaData.StdAssay #' @templateVar fxn CastAssay #' @template method-stdassay #' #' @importFrom methods as #' @importFrom rlang quo_get_env quo_get_expr #' #' @method CastAssay StdAssay #' @export #' CastAssay.StdAssay <- function(object, to, layers = NA, verbose = TRUE, ...) { layers <- Layers(object = object, search = layers) if (is_quosure(x = to)) { to <- eval( expr = quo_get_expr(quo = to), envir = quo_get_env(quo = to) ) } stopifnot(is.character(x = to) || is.function(x = to)) for (lyr in layers) { if (isTRUE(x = verbose)) { msg <- paste("Attempting to cast layer", lyr) if (is.character(x = to)) { msg <- paste(msg, "to", to) } message(msg) } clyr <- Cells(x = object, layer = lyr) flyr <- Features(x = object, layer = lyr) w <- function(e) { warn(message = paste0( "Unable to cast layer ", sQuote(x = lyr), ": ", e$message )) return(invisible(x = NULL)) } if (is.function(x = to)) { tryCatch( expr = LayerData( object = object, layer = lyr, cells = clyr, features = flyr ) <- to(LayerData(object = object, layer = lyr, fast = TRUE), ...), error = w ) } else { check <- is( object = LayerData(object = object, layer = lyr, fast = TRUE), class2 = to ) if (isTRUE(x = check)) { next } tryCatch( expr = LayerData( object = object, layer = lyr, cells = clyr, features = flyr ) <- as( object = LayerData(object = object, layer = lyr, fast = TRUE), Class = to ), error = w ) } } return(object) } #' @template param-verbose #' @param layers A vector of layers to cast; defaults to all layers #' #' @rdname CastAssay #' @method CastAssay Assay5 #' @export #' CastAssay.Assay5 <- CastAssay.StdAssay #' @templateVar fxn Cells #' @template method-stdassay #' #' @method Cells StdAssay #' @export #' Cells.StdAssay <- function(x, layer = NULL, simplify = TRUE, ...) { if (any(is.na(x = layer)) || is.null(x = layer)) { return(rownames(x = slot(object = x, name = 'cells'))) } layer <- Layers(object = x, search = layer) cells <- sapply( X = layer, FUN = function(lyr) { return(slot(object = x, name = 'cells')[[lyr]]) }, simplify = FALSE, USE.NAMES = TRUE ) if (isFALSE(x = simplify)) { return(cells) } return(Reduce(f = union, x = cells)) } #' @param layer Layer to pull cells/features for; defaults to default layer; #' if \code{NA}, returns all cells for the assay #' @param simplify Simplify the cell/feature names into a single vector; if #' \code{FALSE}, separates each cell/feature names by layer #' #' @rdname Cells #' @method Cells Assay5 #' @export #' Cells.Assay5 <- Cells.StdAssay #' @templateVar fxn DefaultAssay #' @template method-stdassay #' #' @method DefaultAssay StdAssay #' @export #' DefaultAssay.StdAssay <- function(object, ...) { return(slot(object = object, name = 'assay.orig')) } #' @rdname DefaultAssay #' @method DefaultAssay Assay5 #' @export #' DefaultAssay.Assay5 <- DefaultAssay.StdAssay #' @rdname DefaultAssay-StdAssay #' @method DefaultAssay<- StdAssay #' @export #' "DefaultAssay<-.StdAssay" <- function(object, ..., value) { slot(object = object, name = 'assay.orig') <- value return(object) } #' @rdname DefaultAssay #' @method DefaultAssay<- Assay5 #' @export #' "DefaultAssay<-.Assay5" <- `DefaultAssay<-.StdAssay` #' @templateVar fxn DefaultLayer #' @template method-stdassay #' #' @method DefaultLayer StdAssay #' @export #' DefaultLayer.StdAssay <- function(object, ...) { idx <- slot(object = object, name = 'default') if (!length(x = idx) || idx == 0L) { idx <- 1L } return(Layers(object = object)[seq_len(length.out = idx)]) } #' @rdname DefaultLayer #' @method DefaultLayer Assay5 #' @export #' DefaultLayer.Assay5 <- DefaultLayer.StdAssay #' @rdname DefaultLayer-StdAssay #' @method DefaultLayer<- StdAssay #' @export #' "DefaultLayer<-.StdAssay" <- function(object, ..., value) { layers <- Layers(object = object) value <- Layers(object = object, search = value) idx <- MatchCells(new = layers, orig = value, ordered = TRUE) slot(object = object, name = 'layers') <- c( slot(object = object, name = 'layers')[idx], slot(object = object, name = 'layers')[-idx] ) slot(object = object, name = 'default') <- length(x = value) validObject(object = object) return(object) } #' @rdname DefaultLayer #' @method DefaultLayer<- Assay5 #' @export #' "DefaultLayer<-.Assay5" <- `DefaultLayer<-.StdAssay` #' @rdname Cells-StdAssay #' @method Features StdAssay #' @export #' Features.StdAssay <- function(x, layer = NULL, simplify = TRUE, ...) { if (any(is.na(x = layer)) || is.null(x = layer)) { return(rownames(x = slot(object = x, name = 'features'))) } layer <- Layers(object = x, search = layer) features <- sapply( X = layer, FUN = function(lyr) { return(slot(object = x, name = 'features')[[lyr]]) }, simplify = FALSE, USE.NAMES = TRUE ) if (isFALSE(x = simplify)) { return(features) } return(Reduce(f = union, x = features)) } #' @rdname Cells #' @method Features Assay5 #' @export #' Features.Assay5 <- Features.StdAssay #' @method FetchData StdAssay #' @export #' FetchData.StdAssay <- function( object, vars, cells = NULL, layer = NULL, clean = TRUE, ... ) { # Identify layer(s) to use layer.set <- rev(x = Layers( object = object, search = layer %||% 'data' )) if (is.null(layer) && length(layer.set) == 1 && layer.set == 'scale.data'){ warning('Default search for "data" layer yielded no results; utilizing "scale.data" layer instead.') } if (is.null(layer.set) & is.null(layer) ) { warning('data layer is not found and counts layer is used') layer.set <- rev(x = Layers( object = object, search = 'counts' )) } if (is.null(layer.set)) { stop('layer "', layer,'" is not found in the object') } else { layer <- layer.set } # Identify cells to use cells <- cells %||% colnames(x = object) if (is.numeric(x = cells)) { cells <- colnames(x = object)[cells] } cells <- intersect(x = cells, y = colnames(x = object)) if (!length(x = cells)) { abort(message = "None of the cells requested found in this assay") } # Check vars orig <- vars vars <- gsub( pattern = paste0('^', Key(object = object)), replacement = '', x = vars ) # Pull expression information features <- sapply( X = layer, FUN = Features, x = object, simplify = FALSE, USE.NAMES = TRUE ) vars <- intersect(x = vars, y = Reduce(f = union, x = features)) data.fetched <- as.data.frame(x = matrix( data = NA_real_, nrow = length(x = cells), ncol = length(x = vars), dimnames = list(cells, vars) )) for (lyr in layer) { lcells <- intersect(x = cells, y = Cells(x = object, layer = lyr)) lvars <- intersect(x = vars, y = Features(x = object, layer = lyr)) if (!length(x = lcells) || !length(x = lvars)) { next } data.fetched[lcells, lvars] <- as(t(x = LayerData( object = object, layer = lyr, cells = lcells, features = lvars )[lvars, lcells, drop = FALSE]), "matrix") } # Clean out missing cells from the expression matrix if (isTRUE(x = clean)) { no.data <- which(x = apply( X = data.fetched, MARGIN = 1L, FUN = function(x) { return(all(is.na(x = x))) } )) if (length(x = no.data)) { warn(message = paste( "Removing", length(x = no.data), "cells missing data for features requested" )) data.fetched <- data.fetched[-no.data, , drop = FALSE] } } # Add keys to keyed vars keyed.features <- paste0(Key(object = object), colnames(x = data.fetched)) keyed.idx <- which(x = keyed.features %in% orig) if (length(x = keyed.idx)) { colnames(x = data.fetched)[keyed.idx] <- keyed.features[keyed.idx] } # Check final list of features fetched <- setdiff(x = unlist(x = dimnames(x = data.fetched)), y = cells) missing <- setdiff(x = orig, y = fetched) if (length(x = missing) == length(x = orig)) { abort(message = "None of the requested variables found", class = 'varsNotFoundError') } else if (length(x = missing)) { warn(message = paste( "The following variables could not be found:", paste(missing, collapse = ', ') )) } return(data.fetched) # # Pull feature-level metadata # meta.fetch <- c( # grep(pattern = '^md_', x = vars, value = TRUE), # vars[vars %in% colnames(x = object[[]])] # ) # meta.fetch <- setdiff(x = meta.fetch, y = colnames(x = data.fetched)) # meta.keyed <- which(x = grepl(pattern = '^md', x = meta.fetch)) # meta.fetch <- gsub(pattern = '^md_', replacement = '', x = meta.fetch) # meta.data <- lapply( # X = meta.fetch, # FUN = function(x, f) { # df <- as.data.frame(x = matrix( # data = NA, # nrow = 1L, # ncol = length(x = f), # dimnames = list(x, f) # )) # df[x, ] <- object[[x]][f, , drop = TRUE] # return(df) # }, # f = colnames(x = data.fetched) # ) # meta.data <- do.call(what = 'rbind', args = meta.data) # if (length(x = meta.keyed)) { # rownames(x = meta.data)[meta.keyed] <- paste0( # 'md_', # rownames(x = meta.data)[meta.keyed] # ) # } # keyed.meta <- paste0(Key(object = object), rownames(x = meta.data)) # keyed.meta.idx <- which(x = keyed.meta %in% orig) # if (length(x = keyed.meta.idx)) { # rownames(x = meta.data)[keyed.meta.idx] <- keyed.meta[keyed.meta.idx] # } # if (nrow(x = data.fetched) && (nrow(x = meta.data) %||% 0)) { # warning( # "Returning both expression and meta data; data types might be different than expected", # call. = FALSE, # immediate. = TRUE # ) # } # data.fetched <- rbind(data.fetched, meta.data) # # Add keys to keyed vars # keyed.features <- paste0(Key(object = object), colnames(x = data.fetched)) # keyed.idx <- which(x = keyed.features %in% orig) # if (length(x = keyed.idx)) { # colnames(x = data.fetched)[keyed.idx] <- keyed.features[keyed.idx] # } # # Check final list of features # fetched <- setdiff(x = unlist(x = dimnames(x = data.fetched)), y = cells) # missing <- setdiff(x = orig, y = fetched) # if (length(x = missing) == length(x = orig)) { # stop("None of the requested variables found", call. = FALSE) # } else if (length(x = missing)) { # warning( # "The following variables could not be found: ", # paste(missing, collapse = ', '), # call. = FALSE, # immediate. = TRUE # ) # } # return(data.fetched) } #' @method FetchData Assay5 #' @export #' FetchData.Assay5 <- FetchData.StdAssay #' @templateVar fxn AssayData #' @template method-stdassay #' #' @method GetAssayData StdAssay #' @export #' GetAssayData.StdAssay <- function( object, layer = NULL, slot = deprecated(), ... ) { CheckDots(..., fxns = LayerData) if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'GetAssayData(slot = )', with = 'GetAssayData(layer = )' ) layer <- slot } layer_name <- layer[1L] %||% DefaultLayer(object = object)[1L] layer.set <- suppressWarnings(expr = Layers( object = object, search = layer %||% 'data' )) if (is.null(layer.set) & is.null(layer)) { warning('data layer is not found and counts layer is used') layer <- rev(x = Layers( object = object, search = 'counts' )) } else { layer <- layer.set } if (length(x = layer) > 1) { abort("GetAssayData doesn't work for multiple layers in v5 assay.", " You can run 'object <- JoinLayers(object = object, layers = layer)'.") } if (is.null(x = layer)) { msg <- paste("Layer", sQuote(x = layer_name), "is empty") opt <- getOption(x = "Seurat.object.assay.v3.missing_layer", default = Seurat.options$Seurat.object.assay.v3.missing_layer) opt <- tryCatch(expr = arg_match0( arg = opt, values = c("matrix","null", "error")), error = function(...) { return(Seurat.options$Seurat.object.assay.v3.missing_layer) } ) if (opt == "error") { abort(message = msg) } warn(message = msg) return(switch( EXPR = opt, matrix = switch( EXPR = layer_name, scale.data = new(Class = "matrix"), new(Class = "dgCMatrix") ), NULL)) } return(LayerData(object = object, layer = layer, ...)) } #' @templateVar fxn VariableFeatures #' @template method-stdassay #' #' @importFrom utils adist #' #' @method HVFInfo StdAssay #' @export #' HVFInfo.StdAssay <- function( object, method = NULL, status = FALSE, layer = NA, strip = TRUE, ... ) { # Create a named list mapping HVF methods to the layers they're available for. layers_by_method <- .VFMethodsLayers(object, layers = layer, type = "hvf") if (length(layers_by_method) < 1) { # If no HVF metadata is present for the specified `assay`, return `NULL`. return(NULL) } # If `method` is not provided, use the last one from `layer_by_method`. if (is.null(method)) { available_methods <- names(layers_by_method) method <- available_methods[length(available_methods)] } # Normalize "mean.var.plot" to "mvp" and "dispersion" to "disp". method <- switch( EXPR = tolower(method), mean.var.plot = "mvp", dispersion = "disp", method ) # Check `method` against the list of method names parsed via # `.VFMethodsLayers` and throw an warning error if no match is found # and return `NULL`. if (!method %in% names(layers_by_method)) { # `sprintf` cannot handle `NULL` values. pretty_layer <- ifelse(is.null(layer), "NULL", layer) warning( sprintf( paste( "Unable to find highly variable feature information for", "method='%s' and layer='%s'." ), method, pretty_layer ) ) return(NULL) } # Choose the appropriate layer for the specified `method`. method_layers <- layers_by_method[[method]] query_layers <- Layers(object, search = layer) # If there are more than one, return the first. layer <- method_layers[method_layers %in% query_layers][1L] # Find the columns for the specified method and layer cols <- grep( pattern = paste0(paste("^vf", method, layer, sep = "_"), "_"), x = colnames(x = object[[]]), value = TRUE ) if (!isTRUE(x = status)) { cols <- setdiff( x = cols, y = paste("vf", method, layer, c("variable", "rank"), sep = "_") ) } hvf.info <- object[[cols]] colnames(x = hvf.info) <- gsub( pattern = "^vf_", replacement = "", x = colnames(x = hvf.info) ) if (isTRUE(x = strip)) { colnames(x = hvf.info) <- gsub( pattern = paste0(paste(method, layer, sep = "_"), "_"), replacement = "", x = colnames(x = hvf.info) ) } return(hvf.info) } #' @param layer Layer to pull variable features for #' @param strip Remove method/layer identifiers from highly variable data frame #' #' @rdname VariableFeatures #' @method HVFInfo Assay5 #' @export #' HVFInfo.Assay5 <- HVFInfo.StdAssay #' @method JoinLayers StdAssay #' @export #' JoinLayers.StdAssay <- function( object, layers = NULL, new = NULL, ... ) { layers <- layers %||% c('counts', 'data', 'scale.data') new <- new %||% layers if (length(x = layers) != length(x = new)) { stop('Number of layers and new should be the same') } var.features <- VariableFeatures(object = object) for (i in seq_along(layers)) { num.layers <- suppressWarnings( expr = length(x = Layers(object = object, search = layers[i])) ) if (num.layers > 0L) { object <- JoinSingleLayers( object = object, layers = layers[i], new = new[i], default = TRUE, ... ) } } VariableFeatures(object = object) <- var.features return(object) } #' @param layers Names of layers to split or join #' @param new Name of new layers #' #' @rdname SplitLayers #' #' @method JoinLayers Assay5 #' @export #' JoinLayers.Assay5 <- JoinLayers.StdAssay #' @rdname Key #' @method Key Assay5 #' @export #' Key.Assay5 <- .Key #' @rdname Key #' @method Key<- Assay5 #' @export #' "Key<-.Assay5" <- `.Key<-` #' @templateVar fxn Layers #' @template method-stdassay #' #' @method LayerData StdAssay #' @export #' LayerData.StdAssay <- function( object, layer = NULL, cells = NULL, features = NULL, fast = FALSE, slot = deprecated(), ... ) { if (is_present(arg = slot)) { deprecate_stop( when = '5.0.0', what = 'LayerData(slot = )', with = 'LayerData(layer = )"' ) } layer_name <- layer[1L] %||% DefaultLayer(object = object)[1L] # Identify layer(s) to use layer.set <- suppressWarnings(expr = Layers( object = object, search = layer %||% 'data' )) # If layer.set doesnt return anything and layer is not defined if (is.null(layer.set) & is.null(layer) ) { warning( 'data layer is not found and counts layer is used', call. = F, immediate. = T ) layer <- Layers( object = object, search = 'counts' ) } else { layer <- layer.set } if (length(x = layer) > 1) { warning("multiple layers are identified by ", paste0(layer, collapse = ' '), "\n only the first layer is used") layer <- layer[1L] } # layer <- match.arg(arg = layer, choices = Layers(object = object)) if (is.null(x = layer) || any(is.na(x = layer))) { msg <- paste("Layer", sQuote(x = layer_name), "is empty") opt <- getOption(x = "Seurat.object.assay.v3.missing_layer", default = Seurat.options$Seurat.object.assay.v3.missing_layer) opt <- tryCatch(expr = arg_match0( arg = opt, values = c("matrix","null", "error")), error = function(...) { return(Seurat.options$Seurat.object.assay.v3.missing_layer) } ) if (opt == "error") { abort(message = msg) } warn(message = msg) return(switch( EXPR = opt, matrix = switch( EXPR = layer_name, scale.data = new(Class = "matrix"), new(Class = "dgCMatrix") ), NULL)) } # Allow cell/feature subsets dnames <- list( Features(x = object, layer = layer), Cells(x = object, layer = layer) ) cells <- cells %||% dnames[[2L]] if (is.numeric(x = cells)) { cells <- dnames[[2L]][cells] } cells <- sort(x = MatchCells( new = dnames[[2L]], orig = cells, ordered = TRUE )) dnames[[2L]] <- dnames[[2L]][cells] features <- features %||% dnames[[1L]] if (is.numeric(x = features)) { features <- dnames[[1L]][features] } features <- sort(x = MatchCells( new = dnames[[1L]], orig = features, ordered = TRUE )) dnames[[1L]] <- dnames[[1L]][features] if(length(x = dnames[[1L]]) == 0) { stop('features are not found') } # Pull the layer data ldat <- if (.MARGIN(x = object) == 1L) { methods::slot(object = object, name = 'layers')[[layer]][features, cells, drop = FALSE] } else { methods::slot(object = object, name = 'layers')[[layer]][cells, features, drop = FALSE] } # Add dimnames and transpose if requested ldat <- if (isTRUE(x = fast)) { ldat } else if (is_na(x = fast)) { .GetLayerData2(x = ldat, dnames = dnames, fmargin = 1L) # .GetLayerData( # x = ldat, # dnames = dnames, # fmargin = 1L, # ... # ) } else { .GetLayerData2( x = ldat, dnames = dnames, fmargin = .MARGIN(x = object, type = 'features') ) # .GetLayerData( # x = ldat, # dnames = dnames, # fmargin = .MARGIN(x = object, type = 'features'), # ... # ) } return(ldat) } #' @param features,cells Vectors of features/cells to include #' @param fast Determine how to return the layer data; choose from: #' \describe{ #' \item{\code{FALSE}}{Apply any transpositions and attempt to add #' feature/cell names (if supported) back to the layer data} #' \item{\code{NA}}{Attempt to add feature/cell names back to the layer data, #' skip any transpositions} #' \item{\code{TRUE}}{Do not apply any transpositions or add feature/cell #' names to the layer data} #' } #' #' @rdname Layers #' @method LayerData Assay5 #' @export #' LayerData.Assay5 <- LayerData.StdAssay #' #' @rdname Layers-StdAssay #' @method LayerData<- StdAssay #' @export #' "LayerData<-.StdAssay" <- function( object, layer, features = NULL, cells = NULL, ..., value ) { if (!is_scalar_character(x = layer) || !nzchar(x = layer)) { abort(message = "'layer' must be a single non-empty string") } # Remove a layer if (is.null(x = value)) { if (length(x = Layers(object = object)) == 1L) { stop("Cannot remove only layer") } else if (layer %in% DefaultLayer(object = object)) { msg <- 'Removing default layer' if (length(x = DefaultLayer(object = object)) == 1L) { DefaultLayer(object = object) <- Layers(object = object)[2] msg <- paste0( msg, ', setting default to ', DefaultLayer(object = object) ) } else { didx <- slot(object = object, name = 'default') - 1L slot(object = object, name = 'default') <- didx } warning(msg, call. = FALSE, immediate. = TRUE) } slot(object = object, name = 'layers')[[layer]] <- NULL if (slot(object = object, name = 'default') > length(x = Layers(object = object)) || !length(x = slot(object = object, name = 'default'))) { slot(object = object, name = 'default') <- length(x = Layers(object = object)) } maps <- c( 'cells', 'features' ) for (i in maps) { slot(object = object, name = i)[[layer]] <- NULL } validObject(object = object) return(object) } # Add a layer fdim <- .MARGIN(x = object, type = 'features') cdim <- .MARGIN(x = object, type = 'cells') # Assume input matrix is features x cells dnames <- list( features %||% dimnames(x = value)[[1L]], cells %||% dimnames(x = value)[[2L]] ) if (length(x = unique(x = dim(x = value))) > 1L) { didx <- match( x = vapply( X = dnames, FUN = length, FUN.VALUE = numeric(length = 1L), USE.NAMES = FALSE ), table = dim(x = value) ) dnames <- dnames[didx] } value <- .PrepLayerData2( x = value, target = dim(x = object), dnames = dnames, fmargin = fdim, ... ) # value <- .PrepLayerData( # x = value, # target = dim(x = object), # dnames = dnames, # fmargin = fdim, # ... # ) # Check features and cells features <- attr(x = value, which = 'features') %||% seq_len(length.out = dim(x = value)[fdim]) cells <- attr(x = value, which = 'cells') %||% seq_len(length.out = dim(x = value)[cdim]) fmatch <- MatchCells( new = features, orig = rownames(x = slot(object = object, name = 'features')), ordered = TRUE ) cmatch <- MatchCells( new = cells, orig = rownames(x = slot(object = object, name = 'cells')), ordered = TRUE ) if (is.null(x = fmatch)) { stop( "No feature overlap between existing object and new layer data", call. = FALSE ) } else if (is.null(x = cmatch)) { stop( "No cell overlap between existing object and new layer data", call. = FALSE ) } features <- features[fmatch] cells <- cells[cmatch] # Check for existing layer data if (layer %in% Layers(object = object)) { fcheck <- if (is.numeric(x = features)) { Features(x = object, layer = layer)[features] } else { features } ccheck <- if (is.numeric(x = cells)) { Cells(x = object, layer = layer)[cells] } else { cells } if (!identical(x = fcheck, y = Features(x = object, layer = layer))) { warning( "Different features in new layer data than already exists for ", layer, call. = FALSE, immediate. = TRUE ) } if (!identical(x = ccheck, y = Cells(x = object, layer = layer))) { warning( "Different cells in new layer data than already exists for ", layer, call. = FALSE, immediate. = TRUE ) } } # Reorder the layer data value <- if (fdim == 1L) { value[fmatch, cmatch] } else { value[cmatch, fmatch] } # Add the layer slot(object = object, name = 'layers')[[layer]] <- value # Update the maps slot(object = object, name = 'features')[[layer]] <- features slot(object = object, name = 'cells')[[layer]] <- cells validObject(object = object) return(object) } #' @rdname Layers #' @method LayerData<- Assay5 #' @export #' "LayerData<-.Assay5" <- `LayerData<-.StdAssay` #' @rdname Layers-StdAssay #' @method Layers StdAssay #' @export #' Layers.StdAssay <- function(object, search = NA, ...) { if (is.null(x = search)) { return(DefaultLayer(object = object)) } layers <- names(x = slot(object = object, name = 'layers')) if (!is_na(x = search)) { layers <- unique(x = unlist(x = lapply( X = search, FUN = function(lyr) { if (lyr %in% layers) { return(lyr) } patterns <- c(paste0('^', lyr), paste0(lyr, '$'), lyr) res <- vector(mode = 'character') for (p in patterns) { res <- grep(pattern = p, x = layers, value = TRUE, ...) if (length(x = res)) { break } } return(res) } ))) if (!length(x = layers)) { warning(message = "No layers found matching search pattern provided", call. = FALSE, immediate. = TRUE) return(NULL) } } return(layers) } #' @param search A pattern to search layer names for; pass one of: #' \itemize{ #' \item \dQuote{\code{NA}} to pull all layers #' \item \dQuote{\code{NULL}} to pull the default layer(s) #' \item a \link[base:grep]{regular expression} that matches layer names #' } #' #' @rdname Layers #' @method Layers Assay5 #' @export #' Layers.Assay5 <- Layers.StdAssay #' @templateVar fxn Misc #' @template method-stdassay #' #' @method Misc StdAssay #' @export #' Misc.StdAssay <- .Misc #' @rdname Misc #' @method Misc Assay5 #' @export #' Misc.Assay5 <- .Misc #' @templateVar fxn Misc #' @template method-stdassay #' #' @method Misc<- StdAssay #' @export #' "Misc<-.StdAssay" <- `.Misc<-` #' @rdname Misc #' @method Misc<- Assay5 #' @export #' "Misc<-.Assay5" <- `.Misc<-` #' @templateVar fxn RenameCells #' @template method-stdassay #' #' @method RenameCells StdAssay #' @export #' RenameCells.StdAssay <- function(object, new.names = NULL, ...) { CheckDots(...) colnames(object) <- new.names[colnames(object)] return(object) } #' @rdname RenameCells #' @method RenameCells Assay5 #' @export #' RenameCells.Assay5 <- RenameCells.StdAssay #' @rdname AssayData-StdAssay #' @method SetAssayData StdAssay #' @export #' SetAssayData.StdAssay <- function( object, layer, new.data, slot = deprecated(), ... ) { if (is_present(arg = slot)) { .Deprecate( when = '5.0.0', what = 'SetAssayData(slot = )', with = 'SetAssayData(layer = )' ) layer <- slot } LayerData(object = object, layer = layer) <- new.data return(object) } #' @rdname VariableFeatures-StdAssay #' @method VariableFeatures StdAssay #' @export #' VariableFeatures.StdAssay <- function( object, method = NULL, layer = NA, simplify = TRUE, nfeatures = NULL, selection.method = deprecated(), ... ) { if (is_present(arg = selection.method)) { .Deprecate( when = "5.0.0", what = "VariableFeatures(selection.method = )", with = "VariableFeatures(method = )" ) method <- selection.method } label_column <- "var.features" rank_column <- "var.features.rank" feature_metadata <- object[[]] # If `method` is not provided, and the assay's metadata contains at least # one of the default variable feature columns, with a request for a flat # (`simplify=TRUE`) and assay-wide output (`layer = NA`), then return # variable features directly from the assay's feature-level metadata. if ( is.null(method) & ( (label_column %in% colnames(feature_metadata)) || (rank_column %in% colnames(feature_metadata)) ) & isTRUE(simplify) & is.na(layer) ) { variable_features <- .GetVariableFeatures( hvf_info = feature_metadata, label_column = "var.features", rank_column = "var.features.rank", nfeatures = nfeatures ) return(variable_features) } # Otherwise, we will aggregate variable features layer by layer. # First things first, determine the relevant layer(s) to use. query_layers <- Layers(object, search = layer) # If `method` is specified, only consider layers that have the corresponding # feature-level metadata. if (!is.null(method)) { layers_by_method <- .VFMethodsLayers(object, layers = layer, type = "hvf") method_layers <- layers_by_method[[method]] query_layers <- method_layers[method_layers %in% query_layers] } # For each layer, extract the relevant metadata using `HVFInfo` and then # parse the variable feature names. variable_features <- sapply( query_layers, function(.layer) { hvf.info <- HVFInfo( object, method = method, layer = .layer, status = TRUE, strip = TRUE ) .variable_features <- .GetVariableFeatures( hvf_info = hvf.info, label_column = "variable", rank_column = "rank", nfeatures = nfeatures ) return(.variable_features) }, simplify = FALSE, USE.NAMES = TRUE ) # If no variable features are found across layers, return NULL. if (is.null(unlist(variable_features))) { return(NULL) # If all extracted features are missing (NA), halt execution with an error. } else if (all(is.na(unlist(variable_features)))) { stop("No variable features found.") } # If simplified output is requested, aggregate the variable features from all # layers by taking the most common `nfeatures`. Ties are resolved using each # feature's median rank across all layers. If `nfeatures` is not provided, # the union of variable features for across all layers will be returned. if (isTRUE(simplify)) { variable_features <- .GetConsensusFeatures( variable_features, common_features = intersect(slot(object, "features")[, query_layers]), nfeatures = nfeatures ) } return(variable_features) } #' @param simplify When pulling for multiple layers, combine into a single #' vector and select a common set of variable features for all layers #' @param nfeatures Maximum number of features to select when simplifying #' #' @rdname VariableFeatures #' @method VariableFeatures Assay5 #' @export #' VariableFeatures.Assay5 <- VariableFeatures.StdAssay #' @rdname VariableFeatures-StdAssay #' @method VariableFeatures<- StdAssay #' @export #' "VariableFeatures<-.StdAssay" <- function( object, method = 'custom', layer = NULL, ..., value ) { if (!length(x = value)) { return(object) } value <- intersect(x = value, y = rownames(x = object)) if (!length(x = value)) { stop("None of the features specified are present in this assay", call. = FALSE) } object[['var.features']] <- value # add rank row_names <- row.names(object[[]]) selected_rows <- row_names %in% value matching_rows <- row_names[selected_rows] rank_values <- rep(NA, length(row_names)) rank_values[selected_rows] <- match(matching_rows, value) names(rank_values) <- row_names object[["var.features.rank"]] <- rank_values return(object) } #' @rdname VariableFeatures-StdAssay #' @method VariableFeatures<- Assay5 #' @export #' "VariableFeatures<-.Assay5" <- `VariableFeatures<-.StdAssay` #' @rdname VariableFeatures #' @export #' @method SVFInfo StdAssay #' SVFInfo.StdAssay <- SVFInfo.Assay #' @rdname VariableFeatures-StdAssay #' @method SpatiallyVariableFeatures StdAssay #' @export #' SpatiallyVariableFeatures.StdAssay <- SpatiallyVariableFeatures.Assay #' @rdname VariableFeatures #' @method SVFInfo Assay5 #' @export #' SVFInfo.Assay5 <- SVFInfo.StdAssay #' @rdname VariableFeatures #' @method SpatiallyVariableFeatures Assay5 #' @export #' SpatiallyVariableFeatures.Assay5 <- SpatiallyVariableFeatures.StdAssay #' @method WhichCells StdAssay #' @export #' WhichCells.StdAssay <- WhichCells.Assay # WhichCells.StdAssay <- function( # object, # cells = NULL, # expression = missing_arg(), # invert = FALSE, # ... # ) { # cells <- cells %||% colnames(x = object) # if (!is_missing(x = expression) && !is.null(x = substitute(expr = expression))) { # key.pattern <- paste0('^', Key(object = object)) # expr <- if (tryCatch(expr = is_quosure(x = expression), error = \(...) FALSE)) { # expression # } else if (is.call(x = enquo(arg = expression))) { # enquo(arg = expression) # } else { # parse(text = expression) # } # expr.char <- suppressWarnings(expr = as.character(x = expr)) # expr.char <- unlist(x = lapply(X = expr.char, FUN = strsplit, split = ' ')) # expr.char <- gsub( # pattern = key.pattern, # replacement = '', # x = expr.char, # perl = TRUE # ) # expr.char <- gsub( # pattern = '(', # replacement = '', # x = expr.char, # fixed = TRUE # ) # expr.char <- gsub( # pattern = '`', # replacement = '', # x = expr.char # ) # } # if (isTRUE(x = invert)) { # cells <- setdiff(x = colnames(x = object), y = cells) # } # cells <- '' # return(as.character(x = cells)) # } #' @method WhichCells Assay5 #' @export #' WhichCells.Assay5 <- WhichCells.StdAssay #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Methods for R-defined generics #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #' @inherit .DollarNames.Assay5 params return title description details sections #' #' @importFrom utils .DollarNames #' #' @keywords internal #' @method .DollarNames StdAssay #' @export #' #' @family stdassay #' .DollarNames.StdAssay <- function(x, pattern = '') { layers <- as.list(x = Layers(object = x)) names(x = layers) <- unlist(x = layers) return(.DollarNames(x = layers, pattern = pattern)) } #' Dollar-sign Autocompletion #' #' Autocompletion for \code{$} access on an \code{\link{Assay5}} object #' #' @inheritParams [.Assay5 #' @inheritParams utils::.DollarNames #' #' @return The layer name matches for \code{pattern} #' #' @importFrom utils .DollarNames #' #' @keywords internal #' #' @method .DollarNames Assay5 #' @export #' #' @concept assay5 #' #' @seealso \code{\link[utils:.DollarNames]{utils::.DollarNames}} #' .DollarNames.Assay5 <- .DollarNames.StdAssay #' @inherit $.Assay5 params return title description details sections #' #' @keywords internal #' @method $ StdAssay #' @export #' #' @family stdassay #' "$.StdAssay" <- function(x, i) { return(LayerData(object = x, layer = i)) } #' Layer Data #' #' Get and set layer data #' #' @inheritParams [.Assay5 #' #' @return {$}: Layer data for layer \code{i} #' #' @method $ Assay5 #' @export #' #' @family assay5 #' "$.Assay5" <- `$.StdAssay` #' @rdname cash-.StdAssay #' #' @method $<- StdAssay #' @export #' "$<-.StdAssay" <- `$<-.Assay` #' @return \code{$<-}: \code{x} with layer data \code{value} saved as \code{i} #' #' @rdname cash-.Assay5 #' #' @method $<- Assay5 #' @export #' "$<-.Assay5" <- `$<-.StdAssay` #' @inherit [.Assay5 params return title description details sections #' #' @keywords internal #' @method [ StdAssay #' @export #' #' @family stdassay #' "[.StdAssay" <- `[.Assay` #' Layer Data #' #' Get and set layer data #' #' @inheritParams [[.Assay5 #' @param i Name of layer data to get or set #' @param ... Arguments passed to \code{\link{LayerData}} #' #' @return \code{[}: The layer data for layer \code{i} #' #' @method [ Assay5 #' @export #' #' @family assay5 #' #' @seealso \code{\link{LayerData}} #' #' @order 1 #' "[.Assay5" <- `[.StdAssay` #' @inherit [[.Assay5 params return title description details sections #' #' @keywords internal #' @method [[ StdAssay #' @export #' #' @family stdassay #' "[[.StdAssay" <- function(x, i, j, ..., drop = FALSE) { if (missing(x = i)) { i <- colnames(x = slot(object = x, name = 'meta.data')) } data.return <- slot(object = x, name = 'meta.data')[, i, drop = FALSE, ...] if (nrow(x = data.return) == 0) { return(data.return) } row.names(x = data.return) <- rownames(x = x) if (isTRUE(x = drop)) { data.return <- unlist(x = data.return, use.names = FALSE) names(x = data.return) <- rep.int( x = rownames(x = x), times = length(x = i) ) } return(data.return) } #' Feature-Level Meta Data #' #' Get and set feature-level meta data #' #' @param x An \code{\link{Assay5}} object #' @param i Name of feature-level meta data to fetch or add #' @param j Ignored #' @param drop See \code{\link{drop}} #' @template param-dots-ignored #' #' @return \code{[[}: The feature-level meta data for \code{i} #' #' @method [[ Assay5 #' @export #' #' @family assay5 #' #' @order 1 #' "[[.Assay5" <- `[[.StdAssay` #' @inherit dim.Assay5 params return title description details sections #' #' @keywords internal #' @method dim StdAssay #' @export #' #' @family stdassay #' dim.StdAssay <- function(x) { return(vapply( X = c('features', 'cells'), FUN = function(s) { return(nrow(x = slot(object = x, name = s))) }, FUN.VALUE = numeric(length = 1L), USE.NAMES = FALSE )) } #' Feature and Cell Numbers #' #' @inheritParams [[.Assay5 #' #' @return A two-length numeric vector with the total number of #' features and cells in \code{x} #' #' @method dim Assay5 #' @export #' #' @family assay5 #' dim.Assay5 <- dim.StdAssay #' @inherit dimnames.Assay5 params return title description details sections #' #' @keywords internal #' @method dimnames StdAssay #' @export #' #' @seealso \code{\link{Cells}} \code{\link{Features}} #' @family stdassay #' dimnames.StdAssay <- function(x) { return(list(Features(x = x, layer = NA), Cells(x = x, layer = NA))) } #' Assay-Level Feature and Cell Names #' #' Get and set feature and cell names in v5 Assays #' #' @inheritParams [[.Assay5 #' #' @return \code{dimnames}: A two-length list with the following values: #' \itemize{ #' \item A character vector with all features in \code{x} #' \item A character vector with all cells in \code{x} #' } #' #' @method dimnames Assay5 #' @export #' #' @family assay5 #' @family dimnames #' dimnames.Assay5 <- dimnames.StdAssay #' @rdname dimnames.StdAssay #' #' @method dimnames<- StdAssay #' @export #' "dimnames<-.StdAssay" <- function(x, value) { msg <- "Invalid 'dimnames' given for an assay" if (!is_bare_list(x = value, n = 2L)) { stop(msg, call. = FALSE) } else if (!all(sapply(X = value, FUN = length) == dim(x = x))) { stop(msg, call. = FALSE) } value <- lapply(X = value, FUN = as.character) rownames(x = slot(object = x, name = 'features')) <- value[[1L]] rownames(x = slot(object = x, name = 'cells')) <- value[[2L]] validObject(object = x) return(x) } #' @param value A two-length list with updated feature and/or cells names #' #' @return \code{dimnames<-}: \code{x} with the feature and/or cell #' names updated to \code{value} #' #' @rdname dimnames.Assay5 #' #' @method dimnames<- Assay5 #' @export #' "dimnames<-.Assay5" <- `dimnames<-.StdAssay` #' @rdname sub-sub-.StdAssay #' #' @method head StdAssay #' @export #' head.StdAssay <- head.Assay #' @param n Number of meta data rows to show #' #' @return \code{head}: The first \code{n} rows of feature-level meta data #' #' @rdname sub-sub-.Assay5 #' #' @method head Assay5 #' @export #' head.Assay5 <- head.StdAssay #' @inherit merge.Assay5 params return title description details sections #' #' @note All assays must be of the same type; merging different v5 assays (eg. #' \code{\link{Assay5}} and \code{\link{Assay5T}}) is currently unsupported #' #' @keywords internal #' @method merge StdAssay #' @export #' merge.StdAssay <- function( x, y, labels = NULL, add.cell.ids = NULL, collapse = FALSE, ... ) { assays <- c(x, y) for (i in seq_along(assays)) { if (inherits(x = assays[[i]], what = 'Assay')) { assays[[i]] <- as(object = assays[[i]], Class = "Assay5") # TODO: support Assay5T } } labels <- labels %||% as.character(x = seq_along(along.with = assays)) # add.cell.ids <- add.cell.ids %||% labels # TODO: Support collapsing layers if (isTRUE(x = collapse)) { abort(message = "Collapsing layers is not yet supported") } for (i in seq_along(along.with = assays)) { if (is_na(x = labels[i])) { labels[i] <- as.character(x = i) } if (is_na(x = add.cell.ids[i])) { add.cell.ids[i] <- as.character(x = i) } if (!is.null(x = add.cell.ids[i])) { colnames(x = assays[[i]]) <- paste( colnames(x = assays[[i]]), add.cell.ids[i], sep = '.' ) } } features.all <- LogMap(y = Reduce( f = union, x = lapply(X = assays, FUN = rownames) )) combined <- new( Class = class(x = x), layers = list(), cells = LogMap(y = Reduce( f = union, x = lapply(X = assays, FUN = colnames) )), features = features.all, meta.data = EmptyDF(n = nrow(x = features.all)), misc = list(), key = Key(object = x) %||% character(length = 0L) ) # Add layers # TODO: Support collapsing layers if (isTRUE(x = collapse)) { abort(message = "Collapsing layers is not yet supported") } else { # Get default layer as default of first assay default <- DefaultLayer(assays[[1]]) for (i in seq_along(along.with = assays)) { for (lyr in Layers(object = assays[[i]])) { LayerData( object = combined, layer = paste(lyr, labels[i], sep = '.'), features = Features(x = assays[[i]], layer = lyr), cells = Cells(x = assays[[i]], layer = lyr) ) <- LayerData(object = assays[[i]], layer = lyr, fast = TRUE) } } } # Add feature-level metadata for (i in seq_along(along.with = assays)) { # Rename HVF columns mf <- assays[[i]][[]] if (!ncol(x = mf)) { next } for (type in c('vf')) { vf.idx <- grep(pattern = paste0('^', type, '_'), x = names(x = mf)) if (length(x = vf.idx)) { names(x = mf)[vf.idx] <- vapply( X = names(x = mf)[vf.idx], FUN = function(vf) { vf <- unlist(x = strsplit(x = vf, split = '_')) vf <- paste( paste(vf[1:2], collapse = '_'), paste( paste(vf[3:(length(x = vf) - 1L)], collapse = '_'), labels[i], sep = '.' ), vf[length(x = vf)], sep = '_' ) }, FUN.VALUE = character(length = 1L) ) } } combined[[]] <- mf } # TODO: Add misc DefaultLayer(combined) <- Layers(object = combined, search = default) validObject(object = combined) return(combined) } #' Merge Assays #' #' Merge one or more v5 assays together #' #' \strong{Note}: collapsing layers is currently not supported #' #' @inheritParams [.Assay5 #' @template param-dots-ignored #' @param y One or more \code{\link{Assay5}} objects #' @param labels A character vector equal to the number of objects; defaults to #' \code{as.character(seq_along(c(x, y)))} #' @param add.cell.ids A character vector equal to the number of objects #' provided to append to all cell names; if \code{TRUE}, uses \code{labels} as #' \code{add.cell.ids} #' @param collapse If \code{TRUE}, merge layers of the same name together; if #' \code{FALSE}, appends \code{labels} to the layer name #' #' @return A new v5 assay with data merged from \code{c(x, y)} #' #' @method merge Assay5 #' @export #' #' @family assay5 #' merge.Assay5 <- merge.StdAssay #' @inherit split.Assay5 params return title description details sections #' #' @keywords internal #' @method split StdAssay #' @export #' #' @family stdassay #' split.StdAssay <- function( x, f, drop = FALSE, layers = c("counts", "data"), ret = c('assay', 'multiassays', 'layers'), ... ) { op <- options(Seurat.object.assay.brackets = 'v5') on.exit(expr = options(op)) ret <- ret[1L] ret <- match.arg(arg = ret) layers.to.split <- Layers(object = x, search = layers) if (!identical(Layers(object = x), layers.to.split)) { message( 'Splitting ', paste(sQuote(x = layers.to.split), collapse = ', '), ' layers. Not splitting ', paste( sQuote(x = setdiff(Layers(object = x), layers.to.split)), collapse = ', ' ), '. If you would like to split other layers, set in `layers` argument.' ) } layers <- Layers(object = x, search = layers) layers.split <- list() for (i in seq_along(along.with = layers)) { if (length(x = colnames(x = x[layers[i]])) != length(x = colnames(x = x))) { layers.split[[i]] <- layers[i] } } layers.split <- unlist(x = layers.split) if (length(x = layers.split)) { abort(message = paste( strwrap(x = paste( "The following layers are already split:", paste(sQuote(x = layers.split), collapse = ', '), "\nPlease join before splitting" )) )) } default <- ifelse( test = DefaultLayer(object = x) %in% layers, yes = DefaultLayer(object = x), no = layers[1L] ) cells <- Cells(x = x, layer = layers) if (is_named(x = f)) { f <- f[cells] } if (length(x = f) != length(x = cells)) { abort(message = "Not enough splits for this assay") } if (any(is.na(x = f))) { f <- factor(x = f, levels = c(unique(as.character(f)), 'na')) f[is.na(x = f)] <- 'na' } else { f <- factor(x = f, levels = unique(x = as.character(x = f))) } splits <- split(x = cells, f = f, drop = drop) names(x = splits) <- .MakeNames(x = names(x = splits)) return(switch( EXPR = ret, assay = { for (lyr in layers) { p <- progressor(steps = length(x = splits)) p( message = paste( 'Splitting layer', sQuote(x = lyr), 'into', length(x = splits), 'splits' ), class = 'sticky', amount = 0 ) lcells <- Cells(x = x, layer = lyr) for (i in seq_along(along.with = splits)) { p( message = paste( 'Creating split for', sQuote(x = names(x = splits)[i]) ), class = 'sticky', amount = 0 ) group <- paste(lyr, names(x = splits)[i], sep = '.') xcells <- intersect(x = splits[[i]], y = lcells) LayerData(object = x, layer = group, cells = xcells) <- LayerData( object = x, layer = lyr, cells = xcells ) p() } p(type = 'finish') suppressWarnings(expr = LayerData(object = x, layer = lyr) <- NULL) DefaultLayer(object = x) <- default } x }, multiassays = { value <- vector(mode = 'list', length = length(x = splits)) names(x = value) <- names(x = splits) for (group in names(x = splits)) { value[[group]] <- subset( x = x, cells = splits[[group]], layers = layers ) Key(object = value[[group]]) <- Key(object = group, quiet = TRUE) } value }, layers = { groups <- apply( X = expand.grid(layers, names(x = splits)), MARGIN = 1L, FUN = paste, collapse = '.' ) value <- vector(mode = 'list', length = length(x = groups)) names(x = value) <- groups for (lyr in layers) { lcells <- Cells(x = x, layer = lyr) for (i in seq_along(along.with = splits)) { group <- paste(lyr, names(x = splits)[i], sep = '.') xcells <- intersect(x = splits[[i]], y = lcells) value[[group]] <- LayerData(object = x, layer = lyr, cells = xcells) } } value }, abort(message = paste("Unknown split return type", sQuote(x = ret))) )) } #' Split an Assay #' #' @inheritParams [.Assay5 #' @inheritParams base::split #' @param layers Names of layers to include in the split; pass \code{NA} for #' all layers; pass \code{NULL} for the \link[=DefaultLayer]{default layer} #' @param ret Type of return value; choose from: #' \itemize{ #' \item \dQuote{\code{assay}}: a single \code{\link{Assay5}} object #' \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects #' \item \dQuote{\code{layers}}: a list of layer matrices #' } #' @template param-dots-ignored #' #' @return Depends on the value of \code{ret}: #' \itemize{ #' \item \dQuote{\code{assay}}: \code{x} with the layers requested in #' \code{layers} split based on \code{f}; all other layers are left as-is #' \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects; #' the list contains one value per split and each assay contains only the #' layers requested in \code{layers} with the \link[=Key]{key} set to the split #' \item \dQuote{\code{layers}}: a list of matrices of length #' \code{length(assays) * length(unique(f))}; the list is named as #' \dQuote{\code{layer.split}} #' } #' #' @method split Assay5 #' @export #' #' @family assay5 #' #' @template section-progressr #' split.Assay5 <- split.StdAssay #' @inherit subset.Assay5 params return title description details sections #' #' @keywords internal #' @method subset StdAssay #' @export #' #' @family stdassay #' subset.StdAssay <- function( x, cells = NULL, features = NULL, layers = NULL, ... ) { # define an inner function to validate the `cells` and `features` params .validate_param <- function(name, values, allowed) { # if `values` is null or contains only null values, keep all allowed values if (all(is.na(values))) { values <- allowed } else if (any(is.na(x = values))) { # if any values are NA, issue a warning and remove NAs warning( paste0("NAs passed in ", name, " vector, removing NAs"), call. = FALSE, immediate. = TRUE ) # and drop null values from `values` values <- values[!is.na(x = values)] } # if `values` is numeric, treat them as indices if (is.numeric(values)) { values <- allowed[values] } # ensure `values` are in the allowed set values <- intersect(values, allowed) # if no valid values remain, stop execution with an error if (!length(values)) { stop(paste0("None of the ", name, " provided found in this assay"), call. = FALSE) } return(values) } # if no subsetting is specified, return the original object if (is.null(cells) && is.null(features) && is.null(layers)) { return(x) } # validate and filter cells all_cells <- Cells(x) cells <- .validate_param("cells", cells, all_cells) # validate and filter features all_features <- Features(x = x, layer = NA) features <- .validate_param("features", features, all_features) # validate and filter layers all_layers <- Layers(object = x) layers <- layers %||% all_layers layers <- match.arg( arg = layers, choices = all_layers, several.ok = TRUE ) # subset cells and features layer by layer for (layer_name in all_layers) { # maybe drop the layer if (!layer_name %in% layers) { LayerData(x, layer = layer_name) <- NULL next } # otherwise, filter the the layer's cells and features # `MatchCells` is a bit of a misnomer - assuming that `new` is a # subset of `old`, the function returns a list of indices mapping # the values of `new` to their order in `orig` layer_cells <- MatchCells( new = Cells(x = x, layer = layer_name), orig = cells, ordered = TRUE ) layer_features <- MatchCells( new = Features(x = x, layer = layer_name), orig = features, ordered = TRUE ) # if no valid cells or features, drop the layer data if (is.null(layer_cells) || is.null(layer_features)) { LayerData(object = x, layer = layer_name) <- NULL next } # otherwise, apply the subset LayerData(object = x, layer = layer_name) <- LayerData( object = x, layer = layer_name, cells = layer_cells, features = layer_features ) } # clean up the cells and features slots slot(x, name = "cells") <- droplevels(slot(x, name = "cells")) slot(x, name = "features") <- droplevels(slot(x, name = "features")) # in case any features were found in a only one layer and it was dropped # in the previous loop, we need to make sure our feature list is updated features <- intersect(features, Features(x = x, layer = NA)) # update the features to match the valid list - see note above on `MatchCells` mfeatures <- MatchCells( new = all_features, orig = features, ordered = TRUE ) # subset the meta.data slot accordingly slot(x, name = "meta.data") <- slot(x, name = "meta.data")[mfeatures, , drop = FALSE] # ensure the object is valid validObject(x) return(x) } #' Subset an Assay #' #' @inheritParams [[.Assay5 #' @param cells Cell names #' @param features Feature names #' @param layers Layer to keep; defaults to all layers #' #' @return \code{x} with just the cells and features specified by #' \code{cells} and \code{features} for the layers specified by \code{layers} #' #' @method subset Assay5 #' @export #' #' @family assay5 #' subset.Assay5 <- subset.StdAssay #' @rdname sub-sub-.StdAssay #' #' @method tail StdAssay #' @export #' tail.StdAssay <- tail.Assay #' @return \code{tail}: the last \code{n} rows of feature-level meta data #' #' @rdname sub-sub-.Assay5 #' #' @method tail Assay5 #' @export #' tail.Assay5 <- tail.StdAssay #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Internal #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% .VFLayers <- function( object, type = c('hvf', 'svf'), layers = NA, missing = FALSE ) { type <- type[1L] type <- match.arg(arg = type) pattern <- switch( EXPR = type, 'hvf' = '^vf_', stop("Unknown type: '", type, "'", call. = FALSE) ) vf.cols <- grep( pattern = paste0(pattern, '[[:alnum:]]+_'), x = colnames(x = object[[]]), value = TRUE ) vf.layers <- unique(x = unlist(x = lapply( X = strsplit(x = vf.cols, split = '_'), FUN = function(x) { return(paste(x[3L:(length(x = x) - 1L)], collapse = '_')) } ))) if (!isTRUE(x = missing)) { vf.layers <- intersect( x = vf.layers, y = Layers(object = object, search = layers) ) } if (!length(x = vf.layers)) { vf.layers <- NULL } return(vf.layers) } #' @param object A \code{\link{StdAssay}} object #' @param type Type of variable feature method to pull; choose from: #' \itemize{ #' \item \dQuote{\code{hvf}}: highly variable features #' \item \dQuote{\code{svf}}: spatially variable features #' } #' @param layers Vector of layers to restrict methods for, or a search pattern #' for multiple layers #' #' @return A vector of variable feature methods found in \code{object} #' #' @noRd #' .VFMethods <- function( object, type = c('hvf', 'svf'), layers = NA, missing = FALSE ) { type <- type[1L] type <- match.arg(arg = type) pattern <- switch( EXPR = type, 'hvf' = '^vf_', abort(message = paste("Unknown type:", sQuote(x = type))) ) vf.cols <- grep( pattern = paste0(pattern, '[[:alnum:]]+_'), x = colnames(x = object[[]]), value = TRUE ) # layers <- Layers(object = object, search = layers) layers <- .VFLayers( object = object, type = type, layers = layers, missing = missing ) vf.cols <- Filter( f = function(x) { x <- unlist(x = strsplit(x = x, split = '_')) x <- paste(x[3:(length(x = x) - 1L)], collapse = '_') return(x %in% layers) }, x = vf.cols ) vf.methods <- unique(x = unlist(x = lapply( X = strsplit(x = vf.cols, split = '_'), FUN = '[[', 2L ))) if (!length(x = vf.methods)) { vf.methods <- NULL } return(vf.methods) } #' @param object A \code{\link{StdAssay}} object #' @param type Type of variable feature method to pull; choose from: #' \itemize{ #' \item \dQuote{\code{hvf}}: highly variable features #' \item \dQuote{\code{svf}}: spatially variable features #' } #' @param layers Vector of layers to restrict methods for, or a search pattern #' for multiple layers #' #' @return A vector of variable feature methods and corresponding layers found in \code{object} #' #' @importFrom stats setNames #' @importFrom utils modifyList #' #' @noRd #' .VFMethodsLayers <- function( object, type = c('hvf', 'svf'), layers = NA, missing = FALSE ) { type <- type[1L] type <- match.arg(arg = type) pattern <- switch( EXPR = type, 'hvf' = '^vf_', abort(message = paste("Unknown type:", sQuote(x = type))) ) vf.cols <- grep( pattern = paste0(pattern, '[[:alnum:]]+_'), x = colnames(x = object[[]]), value = TRUE ) # layers <- Layers(object = object, search = layers) layers <- .VFLayers( object = object, type = type, layers = layers, missing = missing ) vf.cols <- Filter( f = function(x) { x <- unlist(x = strsplit(x = x, split = '_')) x <- paste(x[3:(length(x = x) - 1L)], collapse = '_') return(x %in% layers) }, x = vf.cols ) # Extract methods and layers vf.methods.layers <- lapply(vf.cols, function(col) { components <- strsplit(col, split = "_")[[1]] method <- components[2] layer <- paste(components[3:(length(components) - 1)], collapse = "_") return(c(method = method, layer = layer)) }) # Combine into a list vf.list <- lapply(unique(unlist(lapply(vf.methods.layers, `[[`, "method"))), function(method) { layers <- unique(unlist(lapply(vf.methods.layers, function(x) { if (x['method'] == method) return(x['layer']) }))) return(setNames(list(layers), method)) }) vf.list <- Reduce(modifyList, vf.list) if (!length(x = vf.list)) { vf.list <- NULL } return(vf.list) } #' Returns the top variable features from a data frame of highly variable #' feature annotations. Features are marked as variable if their value in #' `label_column` is neither `NA` nor `FALSE`. When a ranking is provided via #' `rank_column`, features are ordered accordingly. #' #' @param hvf_info A `data.frame` containing highly variable feature #' annotations. #' @param label_column A column in `hvf_info` indicating which features #' are variable. A feature is considered variable if it's corresponding #' value is not `NA` or `FALSE`. #' @param rank_column A column in `hvf_info` indicating the rank of #' each feature. #' @param nfeatures The number of variable features to return. #' #' @keywords internal #' .GetVariableFeatures <- function(hvf_info, label_column, rank_column, nfeatures) { # If neither `label_column` nor `rank_column` are present in `hvf_info`, # just return `NULL`. if ( (!label_column %in% colnames(hvf_info)) & (!rank_column %in% colnames(hvf_info)) ) { return(NULL) } # Create a boolean vector indicating which rows in `hvf_info` contain # non-missing values in the `label_column` if it exists. label_mask <- NULL if (label_column %in% colnames(hvf_info)) { feature_labels <- hvf_info[[label_column]] # If a feature label is `NA` or `FALSE` then set it's value to false. # Otherwise, treat the label as truthy. label_mask <- ifelse( is.na(feature_labels) | feature_labels == FALSE, FALSE, TRUE ) } # If a `rank_column` exists, filter out missing values and compute an # ascending rank order. rank_order <- NULL rank_mask <- NULL if (rank_column %in% colnames(hvf_info)) { feature_rank <- hvf_info[[rank_column]] rank_mask <- !is.na(feature_rank) feature_rank <- feature_rank[rank_mask] rank_order <- order(feature_rank) } # Warn if `label_mask` and `ranked_mask` are discordant (i.e some features # have a label but no rank). if (!is.null(label_mask) & !is.null(rank_mask)) { # Identify the features labelled as variable but missing a corresponding rank. missing_rank <- rownames(hvf_info)[label_mask & !rank_mask] if (length(missing_rank) > 0) { warning( sprintf( paste( "The following features were labelled as variable in", "'%s' but had no corresponding rank in `%s` and will", "therefore be ignored: %s" ), label_column, rank_column, paste(sprintf("'%s'", missing_rank), collapse = ", ") ) ) } } # If `nfeatures` is not specified `label_column` doesn't exist we're left # with `rank_column` and so we'll return all features with a non-empty rank. if (is.null(nfeatures) & is.null(label_mask)) { warning( sprintf( paste( "`nfeatures` is not specified and '%s' column is missing; returning", "all features with a non-empty '%s'." ), label_column, rank_column ) ) } # Set `nfeatures` to the count of labeled features if not explicitly provided. nfeatures <- nfeatures %||% sum(label_mask) # If a ranking is available use it to determine which features are variable. feature_mask <- rank_mask %||% label_mask # Apply `feature_mask` to feature names from `hvf_info` to get variable # feature names. variable_features <- rownames(hvf_info)[feature_mask] # If a ranking is available, use it to sort the variable features. if (!is.null(rank_order)) { variable_features <- variable_features[rank_order] } # Select the top `nfeatures`. variable_features <- variable_features[1:nfeatures] return(variable_features) } #' Returns the most frequently observed features in `features_by_layer`. If #' two features are observed at the same frequency their median index will be #' used to break the tie. If `nfeatures` is not specified, all features in #' `common_features` are returned. #' #' @param features_by_layer A 2D named vector containing mapping each layer #' to it's corresponding variable features. #' @param common_features The intersection of features across all layers. #' @param nfeatures The number of variable features to return. #' #' @keywords internal #' .GetConsensusFeatures <- function(features_by_layer, common_features, nfeatures = NULL) { # Create a data frame indicating the position that each feature # appears in the layer-specific vectors given by `features_by_layer`. position_df <- do.call( rbind, lapply( features_by_layer, function(.features) { data.frame( feature = .features, index = seq_along(.features), stringsAsFactors = FALSE ) } ) ) # Only consider features in `common_features`. position_df <- position_df[position_df$feature %in% common_features, ] # Count the number of times each feature appears. feature_counts <- table(position_df$feature) # Calculate the median position of each feature. median_feature_positions <- tapply(position_df$index, position_df$feature, median) # Combine the feature-metada into a data frame. feature_df <- data.frame( feature = names(feature_counts), frequency = as.numeric(feature_counts), median_position = as.numeric(median_feature_positions), stringsAsFactors = FALSE ) # Order the data frame by descending frequency and ascending position. feature_df <- feature_df[order(-feature_df$frequency, feature_df$median_position), ] # Take the first `nfeatures` if provided. if (is.null(nfeatures)) { consensus_features <- feature_df$feature } else { consensus_features <- head(feature_df$feature, nfeatures) } return(consensus_features) } CalcN5 <- function(object) { if (IsMatrixEmpty(x = LayerData(object = object))) { return(NULL) } return(list( nCount = colSums(x = object), nFeature = colSums(x = LayerData(object = object) > 0) )) } # Join single layers # JoinSingleLayers <- function( object, layers = NULL, new = NULL, default = TRUE, nfeatures = Inf, ... ) { if (is.null(x = layers)) { stop('Layers cannot be NULL') } if (length(x = layers) > 1L) { stop('The length of input layers should be 1') } layers <- Layers(object = object, search = layers) new <- new %||% 'newlayer' if (length(x = layers) == 1L) { LayerData(object = object, layer = new) <- LayerData(object = object, layer = layers) return(object) } if (length(x = layers) == 0L) { return(object) } # Stitch the layers together ldat <- StitchMatrix( x = LayerData(object = object, layer = layers[1L]), y = lapply(X = layers[2:length(x = layers)], FUN = LayerData, object = object), rowmap = slot(object = object, name = 'features')[, layers], colmap = slot(object = object, name = 'cells')[, layers] ) LayerData(object = object, layer = new) <- ldat # Set the new layer as default if (isTRUE(x = default)) { DefaultLayer(object = object) <- new } # Remove the old layers for (lyr in layers) { object[lyr] <- NULL } return(object) } #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # S4 methods #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% setAs( from = 'Assay', to = 'Assay5', def = function(from) { # Initialize the new object to <- new( Class = 'Assay5', cells = LogMap(y = colnames(x = from)), features = LogMap(y = rownames(x = from)), assay.orig = DefaultAssay(object = from) %||% character(length = 0L), meta.data = EmptyDF(n = nrow(x = from)), key = Key(object = from) ) # browser() # Add the expression matrices for (i in c('counts', 'data', 'scale.data')) { adata <- GetAssayData(object = from, layer = i) if (IsMatrixEmpty(x = adata)) { next } LayerData(object = to, layer = i) <- adata } # Set the default layer DefaultLayer(object = to) <- ifelse( test = 'counts' %in% Layers(object = to) && !'scale.data' %in% Layers(object = to), yes = 'counts', no = 'data' ) # Add feature-level meta data to[[]] <- from[[]] # Set Variable features VariableFeatures(object = to) <- VariableFeatures(object = from) # Add miscellaneous data mdata <- Misc(object = from) for (i in names(x = mdata)) { Misc(object = to, slot = i) <- mdata[[i]] } return(to) } ) setAs( from = 'Assay5', to = 'Assay', def = function(from) { data.list <- c() original.layers <- Layers(object = from) layers.saved <- c() for (i in c('counts', 'data', 'scale.data')) { layers.saved <- c(layers.saved, Layers(object = from, search = i)) if (length(Layers(object = from, search = i)) > 1) { warning("Joining '", i, "' layers. If you have the same cells in multiple layers, ", "the expression value for the cell in the '", i, "' slot will be the value from the '", Layers(object = from, search = i)[1], "' layer.", call. = FALSE, immediate. = TRUE) from <- JoinLayers(object = from, layers = i, new = i) } if (i == "data") { if (isTRUE(Layers(object = from, search = i) == "scale.data")) { warning("No counts or data slot in object. Setting 'data' slot using", " data from 'scale.data' slot. To recreate 'data' slot, you", " must set and normalize data from a 'counts' slot.", call. = FALSE) } } adata <- LayerData(object = from, layer = i) if(inherits(x = adata, what = "IterableMatrix")) { warning("Converting IterableMatrix to sparse dgCMatrix", call. = FALSE) adata <- as(object = adata, Class = "dgCMatrix") } data.list[[i]] <- adata } if (IsMatrixEmpty(x = data.list[["data"]])){ data.list[["data"]] <- data.list[["counts"]] } if (any(!(original.layers %in% layers.saved))){ layers.remove <- original.layers[!(original.layers %in% layers.saved)] warning("Layers ", paste0(layers.remove, collapse = ', '), " will be removed from the object as v3 assays only support", " 'counts', 'data', or 'scale.data' slots.", call. = FALSE, immediate. = TRUE) } to <- new( Class = 'Assay', counts = data.list[["counts"]], data = data.list[["data"]], scale.data = data.list[["scale.data"]], assay.orig = DefaultAssay(object = from) %||% character(length = 0L), meta.features = data.frame(row.names = rownames(x = data.list[["data"]])), key = Key(object = from) ) # Add feature-level meta data suppressWarnings(to[[]] <- from[[]]) # set variable features VariableFeatures(object = to) <- VariableFeatures(object = from) mdata <- Misc(object = from) for (i in names(x = mdata)) { Misc(object = to, slot = i) <- mdata[[i]] } return(to) } ) #' @rdname sub-.StdAssay #' setMethod( f = '[<-', signature = c(x = 'StdAssay', i = 'character'), definition = function(x, i, ..., value) { LayerData(object = x, layer = i, ...) <- value return(x) } ) #' @param value A matrix-like object to add as a new layer #' #' @return \code{[<-}: \code{x} with layer data \code{value} saved as \code{i} #' #' @rdname sub-.Assay5 #' setMethod( f = '[<-', signature = c(x = 'Assay5', i = 'character'), definition = function(x, i, ..., value) { return(callNextMethod(x = x, i = i, ..., value = value)) } ) #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c( x = 'StdAssay', i = 'character', j = 'missing', value = 'data.frame' ), definition = function(x, i, ..., value) { if (!length(x = i) && !ncol(x = value)) { return(x) } i <- match.arg(arg = i, choices = colnames(x = value), several.ok = TRUE) names.intersect <- intersect( x = row.names(x = value), y = Features(x = x, layer = NA) ) if (length(x = names.intersect)) { value <- value[names.intersect, , drop = FALSE] } else if (nrow(x = value) == nrow(x = x)) { row.names(x = value) <- Features(x = x, layer = NA) } else { abort(message = "Cannot add more or less meta data without feature names") } for (n in i) { v <- value[[n]] names(x = v) <- row.names(value) x[[n]] <- v } return(x) } ) #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c( x = 'StdAssay', i = 'missing', j = 'missing', value = 'data.frame' ), definition = function(x, ..., value) { # Allow removing all meta data if (IsMatrixEmpty(x = value)) { x[[names(x = x[[]])]] <- NULL return(x) } if (is.null(names(x = value))) { warn(message = 'colnames of input cannot be NULL') } else { # If no `i` provided, use the column names from value x[[names(x = value)]] <- value } return(x) } ) #' @importFrom methods selectMethod #' #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c(x = 'StdAssay', i = 'character', j = 'missing', value = 'factor'), definition = function(x, i, ..., value) { f <- slot( object = selectMethod( f = '[[<-', signature = c( x = 'StdAssay', i = 'character', j = 'missing', value = 'vector' ) ), name = '.Data' ) return(f(x = x, i = i, value = value)) } ) #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c(x = 'StdAssay', i = 'character', j = 'missing', value = 'NULL'), definition = function(x, i, ..., value) { for (name in i) { slot(object = x, name = 'meta.data')[[name]] <- NULL } return(x) } ) #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c(x = 'StdAssay', i = 'character', j = 'missing', value = 'vector'), definition = function(x, i, ..., value) { # Add multiple bits of metadata if (length(x = i) > 1L) { value <- rep_len(x = value, length.out = length(x = i)) for (idx in seq_along(along.with = i)) { x[[i[idx]]] <- value[[idx]] } } else { # Add a single column of metadata if (is.null(x = names(x = value))) { if (length(x = unique(x = value)) == 1) { value <- rep_len(x = value, length.out = nrow(x = x)) names(x = value) <- Features(x = x, layer = NA) } else { names(x = value) <- value } } names.intersect <- intersect( x = names(x = value), y = Features(x = x, layer = NA) ) if (!length(x = names.intersect)) { abort(message = "No feature overlap between new meta data and assay") } value <- value[names.intersect] df <- EmptyDF(n = nrow(x = x)) rownames(x = df) <- Features(x = x, layer = NA) # df[[i]] <- if (i %in% names(x = x[[]])) { # x[[i]] # } else { # NA # } df[names(x = value), i] <- value if (nrow(x = slot(object = x, name = 'meta.data')) == 0) { slot(object = x, name = 'meta.data') <- EmptyDF(n = nrow(x = x)) } slot(object = x, name = 'meta.data')[, i] <- df[[i]] } validObject(object = x) return(x) } ) #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c(x = 'StdAssay', i = 'numeric', j = 'missing', value = 'ANY'), definition = function(x, i, ..., value) { if (ncol(x = x[[]])) { i <- colnames(x = x[[]])[as.integer(x = i)] i <- i[!is.na(x = i)] if (length(x = i)) { x[[i]] <- value } } return(x) } ) #' @rdname sub-sub-.StdAssay #' setMethod( f = '[[<-', signature = c(x = 'StdAssay', i = 'missing', j = 'missing', value = 'NULL'), definition = function(x, ..., value) { slot(object = x, name = 'meta.data') <- EmptyDF(n = nrow(x = x)) return(x) } ) #' @param value Feature-level meta data to add #' #' @return \code{[[<-}: \code{x} with \code{value} added as \code{i} #' in feature-level meta data #' #' @rdname sub-sub-.Assay5 #' #' @order 2 #' setMethod( f = '[[<-', signature = c(x = 'Assay5'), definition = function(x, i, ..., value) { return(callNextMethod(x = x, i = i, ..., value = value)) } ) #' V5 Assay Summaries #' #' Summary maths for \code{\link{StdAssay}} Objects #' #' @inheritParams base::colSums #' @param layer Name of layer to run function on #' @template param-dots-ignored #' #' @return The results of the summary math function for the layer specified #' #' @name v5-assay-summaries #' @rdname v5-assay-summaries #' #' @keywords internal #' NULL #' @rdname v5-assay-summaries #' setMethod( f = 'colMeans', signature = c(x = 'StdAssay'), definition = function(x, na.rm = FALSE, dims = 1, layer = NULL, ...) { return(Matrix::colMeans( x = LayerData(object = x, layer = layer), na.rm = na.rm, dims = dims )) } ) #' @rdname v5-assay-summaries #' setMethod( f = 'colSums', signature = c(x = 'StdAssay'), definition = function(x, na.rm = FALSE, dims = 1, layer = NULL, ...) { return(Matrix::colSums( x = LayerData(object = x, layer = layer), na.rm = na.rm, dims = dims )) } ) #' @rdname v5-assay-summaries #' setMethod( f = 'rowMeans', signature = c(x = 'StdAssay'), definition = function(x, na.rm = FALSE, dims = 1, layer = NULL, ...) { return(Matrix::rowMeans( x = LayerData(object = x, layer = layer), na.rm = na.rm, dims = dims )) } ) #' @rdname v5-assay-summaries #' setMethod( f = 'rowSums', signature = c(x = 'StdAssay'), definition = function(x, na.rm = FALSE, dims = 1, layer = NULL, ...) { return(Matrix::rowSums( x = LayerData(object = x, layer = layer), na.rm = na.rm, dims = dims )) } ) #' V5 Assay Overview #' #' Overview of a \code{\link{StdAssay}} object #' #' @param object A v5 Assay #' #' @template return-show #' #' @keywords internal #' #' @family stdassay #' setMethod( f = 'show', signature = 'StdAssay', definition = function(object) { # Basic assay info cat( .AssayClass(object = object), 'data with', nrow(x = object), 'features for', ncol(x = object), 'cells\n' ) # Feature information if (length(x = VariableFeatures(object = object))) { top.ten <- head(x = VariableFeatures(object = object), n = 10L) top <- 'Top' variable <- 'variable' } else { top.ten <- head(x = Features(x = object), n = 10L) top <- 'First' variable <- '' } features <- paste( variable, paste0( ifelse(test = length(x = top.ten) == 1L, yes = 'feature', no = 'features'), ":\n" ) ) features <- gsub(pattern = '^\\s+', replacement = '', x = features) cat( top, length(x = top.ten), features, paste(strwrap(x = paste(top.ten, collapse = ', ')), collapse = '\n'), '\n' ) cat( "Layers:\n", paste(strwrap(x = paste(Layers(object = object), collapse = ', ')), collapse = '\n'), "\n" ) return(invisible(x = NULL)) } ) #' @rdname split.StdAssay #' setMethod( # Because R is stupid f = 'split', signature = c(x = 'StdAssay'), definition = split.StdAssay ) #' V5 Assay Validity #' #' @templateVar cls StdAssay #' @template desc-validity #' #' @section Layer Validation: #' blah #' #' @inheritSection Key-validity Key Validation #' #' @keywords internal #' #' @name StdAssay-validity #' #' @family stdassay #' #' @seealso \code{\link[methods]{validObject}} #' setValidity( Class = 'StdAssay', method = function(object) { if (isFALSE(x = getOption(x = "Seurat.object.validate", default = TRUE))) { warn( message = paste("Not validating", class(x = object)[1L], "objects"), class = 'validationWarning' ) return(TRUE) } valid <- NULL # Check layers dorder <- c( features = .MARGIN(x = object, type = 'features'), cells = .MARGIN(x = object, type = 'cells') ) adims <- dim(x = object) # c(features, cells) if (!IsNamedList(x = slot(object = object, name = 'layers'), pass.zero = TRUE)) { valid <- c(valid, "'layers' must be a named list") } for (layer in Layers(object = object)) { # Reorder dimensions of layer to c(features, cells) ldims <- dim(x = slot(object = object, name = 'layers')[[layer]])[dorder] if (length(x = ldims) != 2L) { valid <- c(valid, "Layers must be two-dimensional objects") break } # Check that we have the correct features and cells for (i in seq.int(from = 1L, to = 2L)) { if (ldims[i] > adims[i]) { valid <- c( valid, paste0( "Layers may not have more ", names(x = dorder)[i], " than present in the assay (offending layer", layer, ")" ) ) } } # Check that we've recorded the cells and features in the maps for (i in c('cells', 'features')) { didx <- c(features = 1L, cells = 2L)[i] if (!layer %in% colnames(x = slot(object = object, name = i))) { valid <- c( valid, paste0( "All layers must have a record in the ", i, " map (offending layer: ", layer, ")" ) ) } else { nmap <- length(x = slot(object = object, name = i)[[layer]]) if (nmap != ldims[didx]) { valid <- c( valid, paste0( "Layers must have the same ", i, " as present in the map (offending layer: ", layer, ")" ) ) } } } } didx <- slot(object = object, name = 'default') if (length(x = didx)) { if (didx < 0 || didx > length(x = Layers(object = object))) { valid <- c( valid, "'default' must be between 0 and the number of layers present" ) } } # TODO: Check variable features # TODO: Check meta features # TODO: Check key # TODO: Check misc return(valid %||% TRUE) } ) #' @inherit StdAssay-validity title details sections #' #' @templateVar cls Assay5 #' @template desc-validity #' #' @name Assay5-validity #' #' @family assay5 #' #' @seealso \code{\link[methods]{validObject}} #' NULL SeuratObject/data/0000755000176200001440000000000015075522101013553 5ustar liggesusersSeuratObject/data/pbmc_small.rda0000644000176200001440000016720015075522101016362 0ustar liggesusersBZh91AY&SY£ØÓNèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàØÈ H@€·É ¥h¡ }îx™¾ð=z‚¨¾Fð½÷Ü5æ×X«®ºj:j[j[`Ó/l§­R€(P)^˜Õ›R¶jÖEJ’Í¥¬Ýº“¶ùåîͰ;»˜¯]vaJÛVi2i’T]¥)&†…€¦€(hèB…B… (ª€æjí{Àb¥ëÜ÷=îñÛÛžíÛj×¹­`… Ow 6ï6öú s9·HP\‘/Ñ€(£õ–k ²%’Ú-SzîÁ{ Qnð º`!ljDÆÛ5³,’_wDÙ¸ÚTÝÒÔÐÔ¬V–™i•„+튪JT ©U’'fÐÊ›[kùš:Š•$'}¹SÛRÞc¥IQrm†”M¨bÙ«LªŠ” kb¦Û6À¢›ÝÄ©vÙ$¬®â—[3 µKÂÍR¦HÛÜi\oq×LZÑVÕ™´ÈU°˜Íг(B-dP«b@ÊD@š14ÐР˜4 4 <ÐÓF£CM4M4Ó&2hɦ!¦š4a¦†ŒCMF”H€ “&2i¦&F˜L&šhÄÓ!‰„bi  4ÐÓA € y£@ƒL‚ˆ@˜€£CL“6ˆÉ=i¨zLSôSÑå=Qúše6š6šji¦ÒjzbM16’<ÔÍF)±¤Õ='µM<“OCIâz˜I“=Ié¦@Ó)§§©)"B Lšh§èm5MÖ»LJ\‡%Ê‹0Éhöß;5û¹‘×CªG"EƒÍC`úWõô¾úÖ·/¿VŸ)…œãÞEõ ëØÇÌ^Ýà€9Öd:ȪýæEœŸÿ [=Ù€—úÍǽ Å?¹.¤n,ŠÔ9C%k1v”Ȩ)Ì È ÌÊ¡(J ’ÚùvÆÆ4ÄUQ˜[ýLá´ÌVùdĈˆœ Y¿ß¶¾~ÛÌN[ Ö¢3AFƒZ59te/dØ ­³©ÖµAiÈ¡#X…šÓš’ÌRŒŒ¢ýÛhÂÛ2¢Ôdk[í¶©“Jq° œ‰3V5RÆcPNA™‘,Ž1‘ÉÑaSŒŸOZ†Ö$b~Öh©ŽiŽ¢O Üe5'†Ì•oŸ·Ì¶Ž(¥>ÒÛˆÇiN—cz©>âåNÐðá«O*Ë'ÉI´o.A½Ý%×_¼ÓÎCß'#{î'!*&­ÌË ÈxêÃ15j lu!Öf2xà8[f\þ&W9ÃM'%±\08FÐïmÃG6 ¨¡­IÂ᫞Ðj^)8kµ¬y—*ÞSh2LßÉë Û*!y'ZÍãiá;Æö×9m ´S<ÈwÖ'i7¶ÛæA©xIÇpƒ‡+8Obmq^F2æA¾ømj¡ªÕ©5DhbaÊP“FÝ ¼aíPœLN/d_]ŒD금4BY9×_sœÛ%lB“¾¨×R5Õœ^Q…¸HE¶q¶£lN¸XA´-°@± x¦§¹f:ÐW64f¢²F8­$ë Ùº¥‡¡’ØÑ |Ú2¨ÙÚB‰Ø²u·¶A“Ó嵑bARVÆ”à¿%ÙfÒègaöÝi©ðyÌ–ÚùmÔ`Ð|·yÆ{Sm“H å²ã)ÙvN…nÖŽ† iè­ºEÈÒÎðuNæ!ˆ Aµ{qÐftqc•(7KC¨y|Ë-æÍ9Ým'6Á ò/­IO£ýÁºÝ÷{<ÆßíÆíöܢࣣë2ùTQZÎT;\Íg'(sz‚G4<ü«Ðæ´ñm¾õjg²£”²"ä6[31S¬€ñ¦ï—«_d9ÁšCm(mË-¤§GéçƒQGh²ÏbÇžÒ„ÍûÔíô\ù—?QIAè¶ëž ±©#·¾ëmËrÛ_-9}[Ý9l·{>>pÏI¯·óóÌô{ïEî·ùòc¥­—çöÛyæù=Ý,—I÷*¼üØô'ª‡üœ½I1²$L}F°¦[`@˜“ÞôÓïu˜ý°!Žçš÷D?Ûç°Ã¹‘„usæX—ĸ÷‰E܉@Œ1ŸÖ–D•DƘM+ˆÖdSTÏšüÁ£jªióëzØcì^óngõUø‹&9ûB‘2L^¿$‚¦bb " •Š š—úx…)KÈX°¥*–ŨeE<ß™N]”ÊÅ"©R«Ð¤Æb˜dêðqóÏb/§ÓÉ®ïkÛlð|Æ4áä*Lq1e+Õ £ÙÌNe ýh+ÌD£ËðÂ:-TU*ª'¡L;°îê‡XI=Ú‚,’FÊêÖÕ}lDl©QÁQÑLTΓ˜å$ŠŸšŽŠ.÷â6îz]tGzº6ô´à¬rvuriÉêtiéx¼dCêb#¢‰ŸÊ«OqüÙ¨€% AA^sÓ5P\¨Šn@Ч²Æ?„ǡުê©=—g»ÌŸá]•‡­Xã‰$óÈÿ>–ú~Õý}ýGS£ P¬'Í)¦‚Š! ¯ûv’ª«–õ¨²ÎÍP¦·%id;zÃÞ{LýÝ÷þÇÍù^ÓÔ‘>G‰àô<Ñ9;—oÒˆÝ÷>ßÛ¡áÑ7AÇÒqÐíчg¶øŠ=»îÔ8±ßcЄ{.7ùßiÿؾWuwÙÓ¿ò®üÛŸj>(GyâÆ£üD#ÖÓNzÕµ-–¿H’}ògÐñäŸFµiàÓtwº¡½·G¸ñy[|8u‹Ú¥²y\°öÝÍœ6w«Nh§,+l}½÷{;?ÆB:*:¾•Ë£†4ðüXG™ÕŠž*á¦*±æc—õÈGW,M§Æw¾­·go±áûM}†•î~”ˆðgÖˆ}O._ÙVÕð>Ûìà7l´³ÁÜó+³W¥ì¸b¼êÚº;Øp厞˜©ÃÛzÝ\«N«ìåÑì’$~ƒòÉ!‰]•ÃL}¦mÃôÁ©ŽFÛM[+ƒêó¼Ãù÷¯ûÄ#²žv1=ÇWG?i",ªª{¶Çƒß~ƒ«àø`ÜUÃÛ{ 4î=‡Ø{q!ر\>r$1ZWsÓáö±$Ý•dmŽZ:;ÝN\>sÈùZúø’[jG¼î1àì÷^ÃÐñx\º4å§Û|$ˆó«…w»1­:1¤­¼ï&Þ·²òº6ò:>WWλ>G½õá•#Åóï;ÌÚ;˜z\¶ŸzÞ¾ÿi"8<þ¯gâpmì±â¦Þ/í¾yÂR»9:´õ¶Åw9hô©ŠrÆz[x½§'s¡éùÿŽ$mGÔSªåËÊžÿºù¯†!ÂÏÔöÕÞî{Úw!:6Ã~¯‰òHŽsû¿èô1ò¾WOç$n¡lIe‘‹‹Ù¦kEua¶)Æ›=çg™¦ß>ìê­¼êcVœ+«äùRHÒ£Éãí*x»˜šNNÏšy4ÅqöFÚbb¶Æ˜¬x:´pÛ·™$6Ûm&4ìÑæmâˆi\«­º<­±·Ê»•ì~E"e"õV'r´÷õÁyerÒ©ZuaäiŒ?#éD:/U“©\*c«£«N1J¬mäö¿E椑Ñ[ó|ƒK vdœ4ÅJ§VØi¦&+Úhñ<õ˜ò°•µVØùµ“+Ôñü쒩« Æ;1†ŸRìõòö@é`èQ]­i¥b±4×™‰èö¡HŽT:,Æ+Ž¢&¬–ÄUE*WFÚUb«LcOìß«óïløŽªøê~Tˆâ“†,¢»òHad¥Um1æx½NuW*c«ouÁ¶aÕÙ^w-½æÈGê?P!–UR©·G{O®ü{)M±Tw=–>ôð‡rO}X©VDGEëCDèÿjA¤ZˆÃDɦ?ô>“ú8C’÷«³X¯£Ó꾓ÍêIUçx»:ª¸pÃÞ{ŽZráZy¢C£‡­©Â§¡^§,r®Œ8WsLp¸i^ó ï¨î¡–-FélLW-±UŽT¤Î!8B(Ë>†)H9þ"ñ,`˜šºv®¦) *»Ûl¯sÎÛjö4{©Œuí´ý#ñOÕ}S««—Ãwº¹lÇϴ妘Ùäcã¹màÓÌìïw9píýGşªì®ŒyïÔ¦Õõlr®ŠÙ§“nçE}»Jòº1õÕ§rŸŽ|ãÎÓÈúvÛm¶>˜(uVÞ,6ò9aé}ˆœ**Š®ti…R¶Ç¦%yŠêÓéº>Ä“üt•TªªUUU*¦*w?ÈI…J©UT•]N¶8pÓG›rûÕ!ð•ETªª*Š­«ÌöÞW{ƒ½\žex»ÿÐ4¢+–1JTò Å&*«éØÛ«hì®\4Ç™§ «ëI©Ê±Xª® ó´ÇЪ~¬œ?Ãå•UU+l+‰·gæÉ¥*¸QÃF;œ±¥U*«la¥VšiSM˜úÒOôIù¦1Œbª˜Ã9w8i[~x˜¥rÛ£ûôp®¬0å£ ÑSõˆ›|oô›pÅTà§,V:*pû)Á¦1R•ZbpÛ‡ÈI·,1J£¹Ëë[a*±õÉ¥+JÆ4Ã*±§f˜èù Rp£'W{£õ®ª8QUUö ¦šhøêÒ•Œ*SÒ¸Jù)•_éåN…<.ç.çW.‰äz\´ž·´ñt|'sÌðyݯC«ýDb¥}zb“˜£†Ÿ$=§ú£ªàÃÄSÛcU‰UIÙ^*ÿ Ôp§©þ±ŠJ¢´§GÜ!ŠÚª˜ªÂ˜Æ)Tª§sýq4¤ÚŽUÊcl?ØDè¨mË )ʱշ¸lÛÐõ¿û‚LWû*”ì®Í=†Ÿí)UUÜÛLyUŠùïöɧëŽX§²êƘÆ6ᦜ4÷¸:¹z[U6èV•þâ6¡Šïx±6¦ÕŠ=õ>•Ãê1þ誅Jw«î©ämÞôlÿxÒ“ tWêÍ«jÆÔÇ ?ßiÃM?ài«N§áÁXÛm´ªïa·V&8V–9}ÊmR4¤Ã³O×›Tª’ŠUM¿á1¦ Œ4ìÇV•¶Ï#£Á¤úg‹þ$áR©ÞQ†0ÅWÝÆ1Ziʧ¾ò¾èOªN‰=†‘ÿœ±Š¨v8i¤ÅyU&•ù%yÚ?äNŒNŠÙI¥M«Å¦pÅx?åHÑNXÒ•T¥SþaU1ŒUaŒcªªÆ+ŽŠÆŒTó´úÛ9V6ïióÎöÕËéßó¤:*´ìÑ¥~À)EU)UOúÅUŒ1Œ~Á Ó´á¦1NÅlý‰8+õʦ)ŠÆšM4ª1ÑXÚ˜+–Útx¹i¥urû´M*IT®åaU:«gý"bŸõ ª¢°ÓF•RiŒN0­¥S¶ÆÛbméuc³½Þÿ­ŠO¼*•J•JQ_˜þ×ï•UØcF1Zc_²Ь+¢´Ójÿµ&ŒiZmQÃlmäcO9hå]ŠÓo+GŽZaS²¿î"¨¯ûÆ ªáLF•ÿ)U÷¬R”¬1¥m¦•´4ûáµaŒ1¦šU1Xî­?fp¬pøM6¦•·™Ž¯Ú'{LUrÚW{m´Æßø±Ã®ÛÛ³‘Ãò:9}Ûµ#³jÆÛSN®¸WslrlÇs— ¶¬TêÛN®Z{¿¹QÁCÿ$+öha÷$hÆß€‘ÿ™úûb8~Ü`÷ŸÂ{OG ¹QZTcÅÕÙ]Zrùˆp¬mއ­æ•øNªŽõ=–ÌmaÃðŽ+èÏá¶x+Jìì÷i£««¢|ÅVXš|W¶Ùµw9{/ºvrêÑ·{Ò•*¾i^u1JšcU‰ÕŒ~ÜÅw4¬-º^øÖ7°ä°ùÉñÒtdmfñåžëæ—A4N›]ðùõ“N\ý9*-<3ç âÌ¥`­¼ŠèÒì*@†qs_ÍÓ9}( u_0õ±–4S$¡Xƒô.tTAP=¢œ"Õ×c=ƒ'‚¢|E¯µ¶hk£r®¯üK4ñSÝ @nd{hSä ™ƒùÞ3úÚi$d‡ãpþþ´C†¯ª0 Ç `Æ5ûœ‚‚hQ ܆rŸò>'ÅÎáÞ4,€KêOªÖ.Í ãˆ IÑ…ÿÇU_Í{ÕõØçò<_uè¶8½Ç{ãäÛfCc¢<áÛå»!d^;î$‚î†Áþ€­''# ˆpÄ ó q.ûˆÃÒ”GbgL zD !çœ?rb³E1@T (|¤{9Õš™ÃHB›¹ÈÉ ¹ ­î‘ý‹¿õ)KéAE2Ð¥£Ý$‰â—lh²˜ *6â88öN×Fiw’ Š¹Ÿ´’ð§§­ïJ"Á£2Oó-ÖúøB”á…>ˆ@û!D8æØõï 5çùŸ€íPLTE1SRDLO›œ‰¤ ýw•ðŽˆJÈ>ütëOzqÖ“wžÎïr¡ô0ë !a¤,4†°Ô5 †á¸n…†¡¨j†¡¨Xi †!a¨d‰Ô,2 †¡aaa¨jBÃ!¨j ‘5 C!PÔ,,)'›·otïçâæ«Ø¾Þ÷óUrºîÕµËî—•š"Ìð¨ ØÂ(§ T’ÈEH©RRaOë€ôЋìÀ ˆtpŠ[ ûš û˜J„M(„û±DSùHyXŸ¢L"ŠvÐ =Lï²`TI@*žJ«ÂB(‹àÿmŽ.pˆíòÿF'ÏÀÐT[ª6@(<´ €wd"$¨9‹ÖB‚Q³ØIPRP ÕÀ"›<\…T³À¢}Ð Ê$ú—ˆŒ©¹ÀŸ”㛨î©Ñq›ã`ö ø0 ‡¹ˆ–Gìe‚¸¤„Ÿg߈'ÿ4!áH“Ïø¤ágHLð@"šXýà@_Î|„_®@Í}r?¶Â@”5˜)L¤@ ›Ù‚<ãg¢àD /óæt÷©ât>¾4*¿løÓH<t0(U†ç¯ˆ+¡ƒñ:y€ᬆ"w_M.{«œÎL&R$¹ê2fødJ?Zn¿§¥ÀÑVxDÁ ~?ÄŠøý÷ò·à?Rrnt²ãòsáGð`7̤†[ðPêüÿý½µä·yèÜ:[rîé&™w(_Ú)yyAÒS°òœÂÁ4¤¨¸*Ÿ3¼&å|ÄuÐ_ÄŸDÁFÇùæ¢a6.‘JáKÛœ™Zû;„f-éïæb5L Âg¹°ZõE‘ |Ÿbý3ÕæÛ'X»,ø ê5¿?Õ¨EƼúßSî},½µã€öW¾Þ¬;»Ì‹†Ÿ2ˆ}‘X è8®+ܦ4‘žŠOŽNŽcÂú¾rùjÉêø­ä¥!…@`c‰P g‰'ñUÚv”Þ£G#šü>î½Ù|›í u¸Z¿D7é9¶ö¸âw¡OÇæ(dÅÒbt›fÑù:ÊmðÉ ìùšH¢ƒ kjLTÃ4FÙ‰5-QF¤Â¦"Û†Ûkl‚·Œ ˆb¥‚R†—[F&ÖÁ5RÁAÄUQAEK0ÍQÔÝ»ëk‹‹iž6SA5’Ii5¦ †T’ý¤–B@ß8Øpúà Ù5W«V´5h}\›D’ËWJ°‹Á¤#^@Œ(FÙùq|qá8ÜæÌ>ÉÎOn'>‹iªÀ¹ v¶SØx0íŠC<žÄC­:ËòðX²¯î¤¢y|w<%_›ËYj"T  l`¨ FT=˜AðOáÈÅ|=D*ãaþlr‹·žhêsÿd¯v~ϯÎä?uN¢õž˜P U*4`ê˜T6p„aÀ“äñò}AlUúQŠPÈÄ‘ï½Ù9* ¥¤”QsÛ®ƒô~Äø¶ÊV†®—ÝTXù–|Uqï"M!ÚOðfæã¡5jÃÂ'üÅëþç ;–™E!âþ…€zÛ!))C!ui!Xz­´Ž º‹R rzîóÜwÛËß7ñsÃïäNÊt”áœ_ð1ËaW€þ”¬K`2¼¼•¯î ®WZôÀ®¡ 6w(í&¯ýÅßòSJ;œ·‘…Rç~7ÈNÞ(‚,/ƒ=|Ûª´£ˆ‚z2ýÄü CåáBm5©9*G@'¾hXGæAˆö²IÀûŸUÉè/Ððå×F'óP×ÏÌ›~`4á]-hBñöÍê%pnJúN’Ë~|~èdÖ¹% €)èpóƒe.¢‘"0Œ5ä>ù[I \µDÈÍRm”@iÑŒþÓZ3þÄS®kï£Ò`2ýæ§öu„@²–V¨š«U„@ÿèDè KÔ"=\ùuÐ(â¼éN‡kÉÌ>U±¢š@ƒ»aô'ØR ¡6WáTRc ‚!©š¶è=÷óGÅe$®ñIZŽÎ-±\sy”¶Öýèô²íÒ(ä#ýv4ó(IvÙà§_ƒ¡ÎøS‚ö~½Gk †“tÎçÍ´KàA_¡¨Î:™˜Pé²õö¡ÍÇX´WÇGŠŒ! JûIL†C±œ÷Ý»Bjö°È&‘ œúC¢ {¥|ÿ“P³0—ÍZÉe‚þt‰…3c¨ÁØ×Šö[ɦéE.mTÇ©ý@ñK² ^G0ª‚΋z\ ¨Dã³ýW²õ‘bMl‚@ =¤-1«RÑd .J!•dO6éùNC…*Ei•ìàCž,²|˜ò |(jàBK[òmgš#7ëÃ',ƒ£Þ$Ø#PC’¹R¤1z¿ |ùK„4ÁbM.s¦Ù.<éµ{›ý]-ÿôÌÙÊ{L´õWUˆä{­-ÞÍP¢ÚóÙ°'ŠÂ›”.om¶òT7`¡‹·SXv¦çù`€B}Ç‹L5ÆÍ?ÞÃì>ÜÇvìü'm¿‰æü?H{Iσ¤Ñæð×ÎÙÑk25ÇÜþœ"KÉ’hlª†úIérWìIB{ÝAr†o˜áw‚tN“hÒ s£³—CüVûÿ'´kÉ\y«ÝüJè ríyÔ3Jì|•¤Cô"ˆ$­ ÷©}×ï–Œ°Ñ);Ÿ¼É´~R¶•`€€}s{ZD~×¼LÑgcc­cP]êj””®ùŸñö„²ÒrPÅñ” àëu ZW’ ‚Î^7©sœã'ä@ÓCÓkÔ~ÐC’ð <|éä{*ÚÐ zžüÃ:)˜Ý*–(Æ­»ßÀ‚[T0?Ô‚ºåx‚ Äy˜†­Áàµy‹mHƒQ¦»ø<©½(„d@¥™£oËLµ¡ìuÎ1ɦ £ÐÃGu lG)ë°ç²8fûU³Ö ?E#Zåj ‘˜“®½¨ ý9–†±Þ‘^þÝÔ×;yì~Ò RÏå„’mÔÊ0—X­‰k7¿›l³=M1{€º*Á€8éÿnk2¿Ò‹éÎÐÏCþ§S×PÇémŠßB:° òÉÞã!#ȤrëQ(O¯ßºüGÛh¥H˜½ÀŠâH{>oà |…·á1^7KÝÚÆºó¸då¾Ë®Í_K}ÜôÞó[§ÖwbTÁDDyZ*;ƺïöî~À¿.aNµÞ⌣yi<±‹MÙAjDÿ&Ù•_¢qï©PAHOŠº°ƒª2"$¡&¹usl<A8a8m¨|/ç ²)g箇š½Xz|>]°èyJ-æÛ¬WŠ.+Í/Ýï æPsŠk1ýÞËÖrÖŽve¥K½—ôŸ¢Í’xb[Ô*Ëʦ…(QµDvïêÖÌdR@!"õæµG8ÿ{Ä“EF[Héá.§¤§T¸Z>[®zk7C5ñ¡{ GH }XA5DC1¢ñl¶»^·ÕÛÿVJ´ úñ·ì2rsòk­T~ZYÚ\i=ॠ³$%¿‹åȰBY®é¹÷¦g‚ü7 ÿ¥ãl>ír‰2”¢Q¦š[;9ûuÖ6Tœ¯YÁkØ+¶y÷>>•1|H{øid¿–þ;8¡£*Xj¿ºÒ IW’ÇK \,Љ‘@7n,|E&-f=±`=¦ºß×}ûÂ: @ƒ+z§ËôåoÖ\}óÍvÓ׿eÕn˜f}”åFVXÖÁG›&H_bQŠE KTŸÝó9ýK¼]ìC×VuÚösVàzëWeêö6YßÔ®á‰Ê Ó¢é(‰é@ 7Ò1POE ãœï£ôgÎÉÈ£`‡_¤9Ϲ¼Î>«µIŒ¤ð#·÷¯À‡¥æÏ)C¯ùñs”t¾'ï[:±ÍJØ  ˆAÀ}€ýÈ=¾ùkg–wúëtsr§(ˆºøçõ([Z¥gú\ÃÓ¨6¤¤H@*|f³ƒCŽê{þ[æçi‡æ©’?MŸåökÑ]äm~sè°Íà¿‘\§ëõry$ù²r%Îð?à©,ýÌ I¶3Ÿ¦¨L–®îƒ©½\û¬úa–ÙH$2_*Ê>•ŽŠÿ=/Ý›d¶kå0¨¾kÓ;UÉA<¸:;T×-P}9Ï+3ا°H2x{Þáp«”é>J©ÅÆŠ-ë¬Û̽,~=Œ Aç‹(x_œõg‰?/cð~Í­Gò¸a«!‹QPG§™ ßúÔ Ïž P¿M欂G»âï%¡¤Ö‰¸K4]zÐ ܵæ/ÎúÿÏ·j$À$œ¤šÕ¤ª'ð½t³‹=M8 ¨^9m•Vc=OH b¤HŸ‡;S:íÀÎò-Ò@5I=úå±—õ¹»ØÖ£PA÷ ƒúnH‚Oöóµ¨!«•ieQþæc¸ôº àZ&C‘ ü:K'“Þk¨*ÿ”!?Íð2üü%A0•<dz;¯0)ÍãíÓ%¦œÃ@ŠwýßžHF‡Asü6{oiÚ™¦ø6µDhµ¶Û{ôüòýß8×úÿš~Ö}©HªoC où Oá¼ã±Ý^?œÊå€gÂw;„Ý«Ò+F­vÈ”‡§GЍ…+ˆ@(|ò¤ßú¤Å B÷â´?hf(‚û>t®p€ä«º|Tü?1Ïr>;K¢„ßµÒðÆ®p¶ÍŽ`*~¤´Sèu^áàRŸÐ€~Þ3œ˜ ¤ ä¹I^`7+v³íó›­À)cê¾ *cÂßÙ.¦^Ǻý& œbd2õÅ2õ·ƒºß:°râ£~ð’p¼K_Á€‚â¶à™7î²@‘1Ö„oêñ–!˜ãx~‡%YjÞ4õ`_w´ ÍÎpÿxUšü[$ƒ“Ýöúù"‡Lý4ÈKG¢©7éWáä*-Aq ¦ëƒ Áû¹áÈ^áPôqRç‚ZOG‡ö”˜ÀÌ,Ú$æpÜwîÿ[(A ,>¾ð$àhk‹ž¡\Ú¼ aa=¸ r^!!” !Tß#=EÉÂ=üJ€,ûÿmãP@?æûš·†ÇÇ((|»îõŽD»Ïgï|„ÉÛÙþ›\àÕDº•‘ß®û롯L06ÄÎõyñˆåjDo=Ùðuìï!@7L‚I±„>ý¢ À7,,—¯ö¤²؇ŽûÃÄœ”@Ûg6IêžvAŠ€ ¿ë…÷' ÀÀ7ù"¯êS¼›+Ê]0Œ|í6÷Ýn%ŽF¡+¨Yæ-g›%ü¢Û‡dla­„7Èü³ˆ!¹P (a-OÓã­î5t›ùd‚¥hªvd{˜DûÿÕgqoãæÿ”Cƒší$TB‘ÈalÕ3À÷!0š¿ç»œ)±¶ÞÅÜ?ÛÙ®:ãßù *µPÞ¡|IJ @Ÿ{›»NP±ßH×þ6Âihe‡Ñˆš\uü•ìô²ê¡ïaj(ûS&ß“¯—éÉnÓr©<Ïe:Ý®”ÔF»Ê¤Áv(Ûq²Î@ãožBUÖr·Ê ›´P–˜Ûùhÿ¾"éFýl¬FAÜúÒºøÁ¿ÛI ”`?ÕÓ 0q©…Æ\WÅž´‡qª’õý¤s\€¼ Û|ýßÜ¿½ rsèBC4å8`vÁ±»Mó-Í$ƒos˜JÛ§<∣ãaÏæ$æ3å—ÅVLMoø’e¸™ÇY gƒ–›Ùè$8ZEó)_úNCd¡îö_f—_CÔ¶]P“ýõôT;h¼¨d À`d­úÉŠ\¤¡Ÿ@½gfy[/ÚÎ ÷ã· D¡Ø…lÐod——t¹mæ }fÎIŒ¾ðxé߇ÿ]|”·j)¹úa¯™GE|§] 9"QMÊ@‰$ˆÔôGæ’Î Í ß-’à`þSHºïò­ÖÈ,Ÿ¤”/Û.Neºæd(à°ˆgfñrÚ9Ç£âøŸà;ºIî-D‡wãPa Ôôé˜m:‰÷e$ÎÝÕLÿŒ¯Ý0ÔXÀ(ï“|=Ð?Ô”:ÙÑ ¡„(Ã…ÁË™ƒeÇÛ¥¬ü(Y¢•Ó†™ð’Ÿ(ö ?nlœ@ D3ªêõ¡hH$7èW†á¦p<$hfvÐ%¦ 䨀µï»¤ÉØV\m„ýË”©šÜ§#x€é`ÌGøáñÝß_Z¤Î‹ÏãË6i¨õnIvЇ ÿä„bÐZ©¸:z1q ’õ$9')Õuó-oyH‡¬ŸÑuÒ*â#xä­šü7%@ÑG¤8øXüÊ€ ÖË^jb¤ ^a‚5!”w=4¦é˜ƒ”µyãz‡y…TÖÈ뺫çSõfèyÖ™xèÆã<—mÊþÈ;‚ÖPÓç†Eû#*ô§ÓÚi-Z]ßmÞ&EvÄ ¼IA7Á´3ÖŒ]hè%¿ÒÿbTnh6dI R`~ÉDš$QÊÕò9j­3pѹäG½`±RzÉ)û"’"ÅñähTŠ´ê@Ü#ý¤z¯P+QÂoñÑ(Í3i±g50¼ÏÎL¼X=IœzðHDRWuT ¼’K¤xíÝûšå9›Üp¢•£X@>•Þ´=×Pÿ÷Áï;Ü>'¨$éaZ#ó@øË)S‡¡Á†€ý@"ó Gïo Ýtެ0ÊM^H™…uzÀª§ã Ñ[5'j«€~mµÞ|ô(„yºOòÎ^ ÐÆè>Tl ÂÒ«VŒË×&Õû]ü38˜‡Ty\tú¿ÿ7gšÇÌ€˜áDå hÒÅL||o)ôk¾Ú{¾Â—›êe»óÞôÜ®êTè ¢ü DµÀê~Ob›xƒÃï†×xU[doâ˜$¬ï:xV&.P\¢xHš)ü‰L¢nаKDÿ¿Iÿšúžÿ’5·ô˦k³^O*œ³0ù¨øµ$nfoéÛg/'æKˆ‹ÿ,Ô_€ ‹îWX¬ÚѱEÆ]©?Õé*TOFdÿí¢›áöPk¸3Ó^ñw@¥  h2ƒŒ p8`9މÒÊ`µÑx›otÛ÷Öçà‘N,Y—›HbùÈ's¯ÒgÕSÖuÔ©}ó¹FŽ0ÐÁ_"p~LˆuUsÔa”±&¼Ì4…<@|Â6lΗè5z¶%+â"÷DPûaH$c\„WwxWI=!€¸èTáÍÃ5–Õµ€õ€·(4­†S•rû±È TóˆA%ãÙ2´Óø´pÆÍcd{Ý5ϘµÏô+;¤ ×J¶JÚò=2+_ŽàçºÑú>^‹w¯ßÐ3ô¿ˆ $¾^p÷ZUwnª'ù6D÷ÅaÆ·J@G¯ªîݾÔ$ƒ ¤>@¸5 v‡*úø¶(l—`˜ó©ã"œ‡I‘ÖNúUÕ1QÐKߟYúwÖÛ³ä×M×lo/§â¹´Z‰oI½ÍBCÞθ©ä¥áÛN§eI¤x§ÓÕ´Á@ Š0oÜxæ¹ÜNìo¡Ú=v+ÕðŽaÂ`þX˜ž{"ï>üq{®ß«a±Ëj{o_lûćóèÌHzÐþ@${œ±RdkÈäÔp19ËBóq.,’VXUðBóF^Öñ¡“oŒƒLd°£¬u«ÄÑÿ; y?Å%)¦€ƒ:>`lÄ-%'ûªQÁ°Úჳf@“…L(L•³ˆ’GÓÜÕÜ笪ژ<òäþ‘#v`ÿM8/@0i-ïàSæ Ea•€wöå&µÍ!¸þ‚F~´7<’t4ÚV¬Ð)ΣÅyòf¸û06¼_žŸÛØ–m±â¶;˜ƒ}o¦T·Ûj yX`Ô«H*¤”MMì¹âë)_ê­ËÛÔþ`@?èžÔÆáä)yн®ímç9Õß¾Ss±iµÞ DȲT¼úL°†ƒáÃi:Z{µ?#ôr”•a¤?¾Š“ó½•MšÑM= Ì’O× ’O_Æ$P’I$”¤þ¯n:–÷ ›msïõç1J OèÊ€„½lzE6<\ŽVA³µkÏà;Î`üù3FÈ‘«îíëßܧgÃnŒƒ‘™ùXó(˜òRç7¿µÍny5¢Ö¯ô+½h4C}ñgA“P.T„FßXµdZüùéΞZ[ôÂrž½.|ÇÖ2;×øk;—¯/Â…} AI×é;G`ÁËÙs2uW`Ibx_ ;&×:M– ™±“±žŒ©O‚i³˜ýØb3ÝÀ’Æ»øìÌ_Ç:jÑ­Ì^0õ*0'=nð6¿V³·@ªßû›O·˜¬Ë®hÔî8þ–Š£¢´íJ.@…‰‡ÌĤNP€ãÌ<ÇÔ:Y±]9ª ]uª‡¤³UÛŸ€¯UU„üõA‡È·nd6w*Ôøt$“õ|ÉkA—zDe¿ðMÃV½À«º;çþ-J?îœ>Ãê½”¤§wÌ”å…ù6m-ïó?'8¨Ïý[]UªÍh¥ÕUÖØe¸¯Î…¼üT[v î{}ö7eÚwFy³¨?üxŽÏ>å#?뇹¾ó­>GÆrßÜ5n‹®9ûÆÙ:û^?Aì£ "5’W¶˜lñuÛj»jc~ö@ ôXv‹àŸN»ÚëÔl5’„I¦Ø&>,À5€DC@à NY“ wÙf/Iãnc'Ï)(’MJ¤ŠAJE$â2úëÐÉå'Ákó™ý>ð{4ú ŠdYp+—½ý©%ÏGÝ›åÁ±šê:"­zºr!‹©l’¶ÈC‚âÁtfûÃ{øÔe½¥£9Š?IŽk//MI% Bn¡Zy¯xî×m2ÑH`f'ôi#ÒÉ"­ZÄÓ)¨b’ÌãZ— ¦ñã-W/åòûžýQ!J#äÒÚ*H€É…!5óêøDNr!«rÝôu7—×0ǧ‚¡hó|5Wë²þZ„€1°”’þL¼;zdKgorN°ñù5ZÊqã,÷`ËYûÉÿï-ñ‹øàBóÇ¿ûâ[“©r@F+RA÷¾Š ð ˆ!õȆ0Íäæäc@º³èÔ=ÐH€€§TRªÅë&­÷Ü¥(Ñû{o&LHI$‚W«?„’øÿ#ß“Àþ^ãÀó.ε·{P=¥7kµýWfô¾®üæ=ÖmúR3'Z´‚_±@îµl·½ö[Ñ$yÇw¡¸PÜÑbDˆÈãâS@då"2ˆ¬Ï›ÝDˆW5X·¡ÞÇ ¢¤ÿ)½Å;DO±ô'°Ôû·3!ßÞâc½5è2/×V6€n§™ˆ€#JnúÀ õ¤ÉúÇ×káÔ߀èí¼ßGGm§ÄY1Ý=ÿÃE¨P…JïVH­ D%MD•4‘Qí󆂔 ¡¡Hf:˜•—Òàˆ@¬„?ĤûöžpÛÜòù6/ˆ ¡v¡¼ ›H$ Û’V—A}™ÿ>/ìQÜŽèF¸¦@õ«“ÏúûDT?ÎQ~~ÊÔ¨«r•â"zl›…³ ·¾¤‰‹‹Ã™Á“k.Ì9tåú¬Rx öy{ëÓ>ƒ >£Ç¨Üÿ|-+ø|²–«Ê®º¢‰“3A¾+ÊÓon9R Ø45LÌ)ay7+÷AwÖ£ñ¼ÔÝö°2 uÿR¥_+å…Q ±xIzËB{Êù1y~ïÍZøúª¾.ÛÀÞxÄ=Š(Éo¼n2 (–÷ƒ6ƒxw–Á›Ûx’‹ö³Ù›´uìš-ös­nôM+3AòÆ•ž5Œ›cEþÉ&¹¥kšF‘­dÓ4­DšÆsDi™k-uC=œÎiZv¤g©3{´sç›úØÏîzܽ³1g©¼¥ +ki íx,ñü-ÍÅ ,›k‡h³6¶Ôæ‡ëa™†ÖÛ™30ÃWÒ¨‡g×øž¿åVÿ“ÈóÝj8NNwœÖ°Àýì¯çôBþûâüëYPZÎ9¤‘&°‘Fïn)›yNÒè\Šñ‰`—þÿè[Ž7K·då©öüoˆ@o²HϱHǃîi @ÙÏg7š—nK nI Ÿ¯«sãˆä®hdf¨æ|~ƒìÉÞõ¨‚I8Mè2@†=Ä7¨;À33X‹r õßÝ3h·çàY4]­G¹Yrš½ÆÑýyŸ«¤É‡¸µdžîA‚E„¸ó`6a*JE#¹>Eþ$}SsÞ]?žÛWžzÄ×mЗc¨¿k4_î~Ús]»Þ.ù´†[—¿h!¥ ŒöﺌML¥=bØúÃÃ)q«¾þºõ£_éêÕêŸß•³Ò¹eºTT> Û1Èëµô#ýrÔá‚ÌB/„ V2½FGãüCÑð²{å/!}¦$²ª„"u—r‰†q­õÈ2fgôVŠeIÄA¸Cæ7t”L[¿\E­,þ«ÛØžºÜ-LÇü[L•€Ìϱ Á¹>=ÇiÛ.D½ùpâlŸÖú;!ðò•Z\Ýi%MR~þJœ4'I ‹ÌŒ/y]1ÖÌjeÑܨkzÇûŠÃ©2È/îg XOv+€œPó*¾xb^0«¸Ç~ Õqȱæ¾>eN]]Ý×Ú rª—ôUuÌþÙáÍ}\wK ³k:£âãôÈWÌvòø¾*9@y5¼c“/3x,Ïïã—qìÌÉ—dÏh?'ÖiýýošôtµšŒš^ÕÔrLRÚ">¨8Ö¾bZñ­ËíŒ$½&| 2h«&¸,±Ï¿yOÊN$^ü¥o#LÇÊÉ”º fute~˜îH.I™~÷SÉ¡k°;½Û’´k‚–qÔ0}¢»lmµ0«íýY]Ží}Âm D‚žÀ!€)«(#DTIe³¶Lq.=æ~’2Ÿ¿…„Ë4}vSƒÕÐp®QæÍ`€*×v=bèy÷0ß±uöc”Wލïo`TÍ\9vº¯\V1J1J²U\Âxª¦ „øZpoKöx]žcé§[óôý­êk`Öïß|¾ù'ö«}f¼ Ü›9F?³¥Ë!£”ùþ×mšiëVóI§€""}Í©Kœy|:⃠YL®{´àñf®þ.UJi€²ôæñ¬Ä0º}5LÌ,lêñçÄué²Ã1é¦ðÿùäÇPß‹6IxÚmÉ0ðºêõ¢ÂGņtp $½èýïG!K¶BïA0ÿ»Õjò+N]?ËãÿóJÓ8z(\ íµÚDÜux ~²šŸF×”ø%ÐÑbA`ëZ\«kqñ þjjܳ¬$ÂI'¯¦3‘àÝ›Ý0âÙ8'(âZö‹è´9^Ç)[ù:Êäæy95Óß™øÄÄú…© T‰\–1D^ƒ‡gáU}£èE¶<óQ^²T÷)÷µDÍùôPmGAAÕpRŒÕ0¬rÉgë; Û{ÌmüÌíBOŠ(ûf-;)ÜzkñÜÎ|¼‡1‹{DkúT5©Þ/M[þž¾ËÚΔþ=¶óëNŠGÖåéöønµÌä1þrys“7¼PmD ìµ_œü‹öÿž[×ýRýμlxÓžÛž2rà_ö•v§ìüÞg¥Ê‰s„bUÍÀ*Êöá4ûI)ºÀêþñm]ç‹nœÉ=™lê­vž´æs¾„ß'ë “½Y>¾:𔢝À-§sçÖ @3H†Wû³„[Õ gÁÈyú¹+׭ʲëèãßÇEòú<Î_ðŸø=—•©œ-á2¢ †eÒpR|ר> Åà\³3@¥r;èd¶¯Ï ~¨ýg×ê¿ÏOp­y2#È5M6×€0ÆÒ©`ïžjϑфf§s¶ÃБ$ÊU)§J|ðŸä«®÷† ©Ö¼àˆJx{î>ï]Šë8ïQ#Z»S˜æ!êÈ·@Ú=üu­ÂFúM5Š–IºIËèa.š&l7G딦ÎîMäHÿX¤û±5›*ùº'âHe©Ñ²Sð®êóÛæÿÍBh*–Ém+‡ØÝ¨]öO`›A#œ¾žœq ÚáŸÏ}ñlŒnt[?ö•vã±ÒXÒæ øþBaý3Ê›¤R°ªuž[ˆµÝ€@ vò?»?ºòÓÆz×t\Ç¿¦W?ÖòˆxÈÌ¡Âê2»u4[.fÆÛ¿Rä—$ºbüò›ö¯–ŽÇðâråDƒ“ÈÈzWÊar[“öâ õ §‚ØíÂnú‡úÉ‘ÒÄaFŒËF ¼×|îžÒK‰´^¹¢Ó­ …¦° B¿lWí\Ÿ‡¼‚þÒ¡¦C²Ä:¾Ðe®Ÿk V‡¤ÅÚŽ…ÊÂAÏÚ|€ÿî[‹´•»‹àÁtµA–5Î}´ÿ®˜k/ÊMáÆŽÁ…c @»œÌ\æ 1<º0Z3 ŸMìø(}.̉¨÷\9HFå†"†k•€VÊý[9ŠóíZÉìþTüœOËŠî0,4Vý´G„º;ÊWŒ¶w>à íA}×rÏËïHÆY÷rÆtQß3é–*Ÿf[@d@žÓrÝÛ¥Å{Àï'L‚Éû¢~Ýð öºMä™Ùˆ‚€FwŒoŒ€¹r_>>O,æñÀ‰[7÷ƒïæuŽÔDÑàˆ+.ã¢ß†ÁXòÞ[*ûªï\@ÈO§ï·y¾ÁÀô6«| µº¬Ý敺VÙ ‹—ƒÆð•·ÓÒ.\]BB'Ò" ' ˆ†î5Ëà¬þ-Œ<"\+cpZ~õ\q¶è8[žö ½Ÿ¿7AìÂ,õBê ¯[Äzíµ£‰´¥×½Vaüœm|&õ&Ú¿udõØ©Òä¬Ú§LÜê9wú¯Gëåv©I•ɇ®ÿ± ÃÞþ…µèóE×»dw¥<±@Ö­Ú ÏT1=ÿʨ9åLò|ÊV‰oy]=nûOïÍ£{aÜR¦ó*È€õÉVâpXvïuµºÖéçmé|ˆwP÷r9|äo°Wl:d%,|V»”C5œ¤©Ûë>‚wª=0Ûüòõù€ÐýòŸÉO J^‘}Î-âßß¡ŒªúZ1ó»çX[ÒÓáµ]5T› 7ïÙ4·×{¶Ù%¾í1{ÚŸ§ùãªÙ5µv•zèëYjuÊjî½÷K-ªfP¯Ü¿ÛTSšðÐBvë½ZX®ÆWße Ï?&©!79ÄãèW1«‰PNÐ~ŒDOe]k:ïº~¾wšA½™é7Wd:ÜHe8¼o÷y»^jm+K·¾E-g·WT†5ûš¡·‹‰ŒöEK¼µTét˜œM¦Ÿ„ýâßçõXú¤hûo>ÞÏo¤ßF;þ³Û…—Ö/ÏÅü\+XëÌÌ2%I31ÝÇÃ'ÚøalÐjTmpõÝRâ²)R˜R…*fY‘-=kÚ]¬TÆêàâf‰T—õ(«ÝÒ˜`â69C°Oê\¾ÝÆdàÞe#ŽŒÅ2B¹Ü?ç6w[Îz©Zß/Üã.Ú¯`ïï{ÕkÞöŒ]Χ´ù=i×y¯µF”¸—yÛø_åúoÂýÿÈùßïüÿÙðý‡¦ú_gþŠwI„.›c‰ê ¢Ôâ»_ï“Â?êSagñÃ=wÈASÍ„¾¬pÔfÙc œqŒ ¿J4 [€ã‘Ôâë*˜¹z€ìÆñ15~LàEñ–Þ×w “䄞ÏÄÓÎôgªþÞGÅý?ýÜ5]C~‰þšSú›^¾çüÂÑ`PJDºk\¾¬Ø³Ž³dÃDïÏó6ùÿk³6h\\ÌNFT0C‡;ÆÝ Ç€áñ‡kNV³,¯,'qOY<ŠbX‚ni¹…N@ZÓ8¾bësgàP–úžG†œšôlwYj9¦c,»ômM ¦7‘K›ÃëÚeÚá¶Ù$›ük§ ¿õ±åæb°õÜ—Œ<º;+>¯š·¿ãuut2q7„ =°ð°hB"x0y$!›§ÈpÝ]ÄK!‹ÎP¨d( YÇŒ2CÙ3"ær¡TV¦”Ä8Ò¬èˆZNBð;o¹úŸ«ØužåTN{˜S¾˜k¶¹ÏÄ5dd[ ŸüçúÞ& Ttók›7;?3M3£‡ëslò;ÝèÓ¦ç8ÃàØIƒÂáÞõƒÃÕ®"YóÚd@(UE„D‡„ZñÄ!ê5X[˜;¸pSÔ#€öpLS‡¾qΤ‚¹«ºHF~d;âq0;I[^‡b£†a²Ö§7ø¾†þÛéò»¯cÝn¿ÖúîïÕï»nÙü¢Óöã­AD¿È×o—œa[¿¹ÍÔ"(䯭óµ·êòJ ]R*^µÎÇͪY^y`ðf{£ç=§¾å›¬ÞîßvÖèaýE¹{d°Â€Îì´Äøç¼g씈BD'a*‹ßj5 á‡DL[sVÊ&àÙï㳊&0ªôàÈ›ìå¤Á ]ò|!Ýð [IÐÚÖ³dIþï°íüŸšëüÇí½NŸ×ôzßúq->z)eK‰nâvÍ«”ƒö)÷“t -PX{Öf¤RmLMá¸äm蛈-¼É…±"ÿjÜ8‹Q".YžaàºÔ^'È¿.˜ õaͯ$Ä«9éÆ&Ö±‚ñ+àЉ.õbÚe!óSXԜċÛ6Ìf_+Kæôê…-—¼ÉÎÐ5禖Î0&¤^”2a"²x:è+I†¸Õ°˜ÎlF#5y34€Œæ Ù]à’(ƒÏ2QÇ!J:Þ! #/çfŸèyÒWö*xÔ¼‡Ì½¢Š4GžñÍËÅâ˜fá?N ù2Ël%¢ãxÏØ4Ï|ÞU¹¹yÐæŒ纺`;º¥„)Ig‡T¤aiàaØgÈŸ*ÚdÛ@ZÚ+žRƒsÁS°ô kVe!”D aÊÁ¡À‰Ö1}tÊrv¸jyrQ# é”…C:ÅN•/д ºœ\* …8QO˜±ˆ"Î#\39"0óOÊ")f\º«Â€rNÕOÏÀ{³ÃŲNY=î5<ʾ·ÏbïMÙ{ƒ¶ù~óÀê{>÷Ïòtò÷/´æy³úSÚo²Ä~/1ã¾§ ¶ÚòSŸËdí|EÏ”©ß[èzCk;óÑŠŒ Qâ'¤ ¦W{ÞØ7éH¬]åõŠ! EÊi Ql”:Í B¼ƒY Ù® ÈZ†ÿ4ùÙ|ÝÄ”2)›#™›kw,26ªy0_\…`UðjH0]ˤAywPÅBwzæd1ÕPâS¼Z†D Ntð#­ bXìï~W7;Ý<½Âjn<½_oã Õ”äµó*]]3fŒ[)*4c¬ó}Ëž¡PÁµ¼'‘5. ¶jà]«È.–b`Tº&8&P¡É¦áLiil-NSå“‹0»ºÕª8yXØ2 ¡6¼Ã`ÝÕ t¨°g)¥šüCamZžÄÊÒ®–¥ˆ.òð#ˆ1ZY‘/ªDd–ls£š.Icgye$VK^LFɳ‘€àeaggËK"VC02ªdù‡¹;oËäÑËu— µ™« ,Mc[Z-k’Ô¥Ù$–xêŶ-f¸HÁÐÖ5à z>‚ÏD ‚X°$JKVQžMµì,B£ /öýÏÞvþJ>†óÇø—‰lgüª¿›é*Í~/[¨Š”}¸çmcæØÜ-É3Æpô:õ>W Ä(œÜÐ:ŽŒŽ?í^ ³ 0â\mÙÙ\Œe\|î3„‘v¹Ð89„Eô¸ÇÆO&2€YÌ¥ƒÈ ^ "Üê j¹ÓH£ ÀÎA3¬WS&ò4³ßS†|†((",Yfõ£T²ÄB!:ˆ×«'«£A®1Ù»IÆÅ,\æ–zŸ<°=;`d-ªúžÂÖ´€‘j€Qªà_%V¦1h¦©€[œ ¡ÂŽÔŒËˆËU¥õsj؜鬛]jÓCEñze|V@„„,áN½UžÎ±]°`<;D5eÔ#“qíü_‹Úÿ‡ôkoØùþcÐõ=ÿùy¿,¡‚¾yše²›ò¯^§*©ÿyjl)^~0X½öëšáÒT®àÝ@VxuwrE[Î7# ýN]HäêÁÓåź„J€Úô› [+ÍÅÏUëUÛ]›Êœ¢ÇŒ»ëµ< …¤Bu8ŠˆšL“aÕ .h ›\e“‚î˜ä@²Lç`’#EY‰ \aÅ=@C*ówIà LÛ4ì6žvÛm Á0·ÁÎnèÛ5:¶Ç~9-%‘öª ö­-kM4Xg±±´’(RÁYS¥¯”´\Ћ@´,*”ŽËÖq2E¤è@¢ÙNýVrä ÈÉA ûȽgÐQä~ÁÕMxU=ä]u¼ïWSFßÔf¿?jøœš‹àa¤Ç÷%·»=«Õ‘nÚ-{¨DGé¸<cÔb'€áqlÏ™¬¨Ž,3ñlÈRÅôh|–¸ È`eaÇÀVšj±1/6è 2á8 „ ë̪…{&¹¢ëdž‹ë³¹L^BB ,[Ch" ÷q‚&/V“”S™2–2… %µÚ˜ÝÕ‰°‘ké” NNOysG9ÅÆWq˜:h¥ŠÉ5óÓärD‰ 4)E‹î–ÅqÖ†/•Ÿ#Ïj㨰[N ©ïß1ºùùæ^F·;ÂÈb—5ô?›Ûôÿ©;ÏÚv‰ý½'„.¦êu4N%yaÁ´Ç Ôn9ü léäVbJ ³Í„b©‚\Mbm"‘é<`53¨ Sáíu­¼±hÑgFˆÔu ì.ٌ㠭q®FvXÎ$g¯I›!a ÒùKå8¾(MC´À¬TVf±WË%b.ñ‘Ñј C8‹MZlEYÅtBEݱ ê/fr×£ìeä=ÏØòß[ß~.>1Ü—¹\ú ĵˆ÷o´m>,=– ±MP¥M¶îɾ>øÛÚ÷Øxž“­å-æôÊø]jÞÃŽd†[_XóÍ0³Ž¾“>+*)‘âMšnàk«M5ÌZÍ5®y‡¯]{Þ&gv‘BÂìÅ‚B¸‚Ù 1(a¡ÛªÉÀ¬ž, §ÛDÝ6mi¥Õ›ÇÞôt‘¤é£(.h‡s°Ö#&—,p¥ÅõkkÅ …ÆÆAö}œÚá¦u‡Ë(p˜!:ô²Ô¤äø?ÝöæÇwõÿñàü-߯úíÿè~çߨï{“| fÞ£b¢èŸïôèÖ"¹Ì"+1åÅxó › .l{âöãÊ)ÎbptDêDƒŒ HsÁ‰0ÖäK´hÕ‚ü˜²P¤^X‚k© .ET?*È,ª¬ç8‹Xg2íyOO6T4©­NÂa•°êøtDÂ63‡,Й„\Ž©dÑ‘š|92”•Pª0 ¸tÚí.qB'D£ÉÉY€Fr3qào.³t“äóbáªPcñÛ§Ÿ_z€ÅkÔçú¯WºµtýǧÚùŸ’¦ý]×£õG¦®]EÐtŽ(n”ÅÃ9h M3ïúkŠu ö!Ü—~œ8‰é‹Ûdç=ËZo’½²°‡–¨nY«'Êr#€®®pù’åû,Ðkè•Ø[2º[)fÆPZEŸIÒDKKˆ"Ni‘0DqÀäô¤ÄVZe¶ßsúc>«œešÙÚíà–ðUýI¼¦Êû51UëªÝ,[ú¡fõßÀ#ò|‡Aþ•=7˜ß.Fœqãˆ-Ç·˜X*·Œj!#÷‹©7ry*1'3,]ù<’ ¶¼® „AЇAÄ`F9S­íB¬5Yf 3аeUK#²f½­:F”,Yð0@ …ÉÁWÌà Hd],†»Ã3Ó¸»2kÊ– N´/2&¦ê3³‡± A3Ö\X<;ìLœR[ƒ)Ì5šÑ’Å=›@RQ©»‰ ú¯5ñ=WÇq÷›o‚PiZïCÂüŸžx}d´£%Æ]â¸]?~~-ß7âW}¢€RzËVú:9fÿ·¬ì·gÅõúøÝz꺞ª!º‡TúÇUSã&ÄT#Œ¯Áˆƒ2÷Å• bn ÅÅúü+ Ô8¢÷]vt^Ìá¥6Џ°ÄDS²$ŪÂÏWPE +C” Œ]X9qh`Hw (ÌŒÃH—rºïöŸCôºß‘Çü±Ààªúgª&ÉDÛ*æik«–é}ê¥ýÚl»¾—&½y•·ä2Ò, ®íêbúór'„z „u–Rʲ±ž:·;‚/f®5eç-]M"ø$Èh¤äŦkœ°hí.ãB,Ã^¤‹lHU¢D`ZÏj*‰:“a«+Ã0–²‡_"€ ›6­1gÝ}Sý>ëÚöÞ7ä|Ø÷ŸWö_Ýùퟥ€êú¬5þ×>—ž"m‡S@Jm7SîÝôN)ÀÀàâvU½Á@xu—âÔ=ˆ¡~.V2¥ TqÃñˆÌ!,3шÊ/ŠlÖ&pÔ Âq†l™XQœ€écJâÈ9<¸ÎêÆDØ…EÝêÀ¹VêTÔÌмá­zšÞßøyÿCÇç½wc«šç;_áê·~·}äþ,—Ç~§žRüsõj¸×9‡o_©Ý`ÐpÛ´6‰jƒ§ül@NFrV8öð„ô(\ ð8Žóe=ykEš†8¼YhÆŽZß-µÙ©¼µ”C`¾²#Aå5ìÕåŠ Ag»]H“Û%F {'"Ar® ¾ðdsœún¸üO«î=ŸÉéþ¿Ûý\VëeKªÔ¦¦¾e°»)ŒÂvkW@´QK¨O Æï6ÍþªæÆ°–)e¬ä6_p‰¼Æ=AŽcÂ\âòDðøîDrÃXñ Ø?'ã™ÉxØÁGBˆƒ2ƒUøïcs °W "ŒZƒZé$çrÖ†y²qC¬ú£²ê¿½ïÍç¾W+²ñwZñû\ûû^žCêÓQíÆoBdŽ£Á£¼‰¥KÏà?ÇVùøé””è4ì°-™9t¶ã0€c‡7.`·5ÖàpoC† u΂ìEáív‘'£Dˆ‰1;EÖM>­ža³]ÁìôÜ’šÓAêF`kMÍð——Õ³©s=®ßÝn~ûÓóþ;ëmkåˆ'§å÷‰DoH%°WC¾o°ÓÑïÝÏHæâf q~ï¿ìþûyí¯¼ë|/M¾õ±‡ÚÝo7ú-âƒýý3³ßøŸÙð;ßt½çM_Ë¿}“7Ÿç¡·@õ¼·D£1nœ\yWÉÚý&l.D–¹‚’<ÎÃ÷78Š3È„Áv >…™ôœ¢Ë‹Yqsºç7 ~¿aÄè:â“ø‰X𒆕 ¥j†ŠJR„ª¢‘ ()i ¨¦!”(¥iZ(H†‚ŠBšR©((( ¢B–’𢀡&¥(hJ  ¦©(bZªªhˆ  (‚¢h(’•¤™š*–• :¼Æ•ªª˜*¢B¨j ¢€)¥()B„‰h (+×FA5AE$IAO›…Éh™iuITUPA@…-Q’ä… 4¤AJR @U%4´„ACIPKPRT‘RÑ@ AIML“!^ ÉJ(*d" ("‰(ª(J(5d…4´4Ì SEJA LBPÓQÒ”¥#Q44…d†CES@STdCUE APf`PEE9NC’dQQ4Ò´4´æaME4ÑM!IIHöƒ°ö=Gžñ&£¡úÕ+€»´óçÕ6³ бWõî¶ÃM+ÇVt•™_ö)ÿÎî>Cû†«ÚKm¯ô>uK¶ÙvÜ£w¢4r®)3hPŒfõ²QW ÎÊZJ>z¡¾»w…>46v²U¡Ï…¥ÌĨ»ÅŒ¤?—V¹€ÔÃuå&2ýˆÚ8?…ŠÖ‚?à½GøvEUòø`7CúµŸn;ÞˆìäVýÉÿ¦²Ù˜öKNëµSæ.0&Mœ’œîj²ÖÏiW¶ýÕ÷R«Ù·iøËe:¦4Vt? .Fiži‰‰mu±ðl%&–Õ`´ù Ÿ%aðecÏ—ÔÍçNÁìñ/ Ví6é¨5ÚîIOw´£Æ+#µÞé’ü®5cm´Œ©ß°"u_Ïó¼\¿“Fæ'ë¡K?wE‚çaõêøä¹´s”ɺ›8ɹMƒ?¯téÛ8Ó´JTõØU^0ÓîÞ¤*|hoBü¢7PUÚ ¯P€Dc7Ž£yþ§_W‹ŽþZáé÷ÓŸIknµéz½ù8ÇX§ªå\"!(~#sÒõÙ±°z5{ ZIBhJ)¦¨ˆšª©*e¤ (hi –š )J¤*! ìóªF‘ ˆ£3ˆªH¨ bJ)( ZJ`¤‰ Š©Œ‡*X’†fª (j`¤(j"’‚%Š€¢&” b(h œ¢(h*–¡BH!4ø ‚ =7|ûKŒÿ2‡SÂfW–¿zÜq¾‡u*ðKúÊYÛÖYnÙ„ûåGù}æì¶3‘ì:%•·Q®ŸIrÈbñ³× ^=Wú¥)PH1ÔÞçfÝœ}™ (OÄÀ⹺{ñíÝì 8' 8(¡KĘ4&ƒêAH(ȺàÔ¬R©R…‹XM³´kB4Ù¾rSõE^öiŽ?Xš0 ¦8£ŠÜß”Jf@ì‚ r¯ïÌl}´tQº~üy®/é—$‚·Á.[óŸð"=o·áþß½è;…Þ¸ñHðP  ÑÝ»+Ÿz:6•³Cw–¸Ë5én‘Õÿ¿êòI  âP¨H¡¨÷׈?™n‡Ñô܃3Ê÷;ljæø>Ÿ¹Ýì|½×ïìü¬sÞ‘Áåû”Ð`f]¤MF->ÓèõÛ©¿èë¼Îž~‹\!ÅÁáÁ÷Ax9“%”$@Ä MPT™9± HD”4$Td AAKJM1$M4Ò…D’ÒáY˜´±R4µY9Ãç{ï¿ëN§àhÿÌê=Tp¨üí´Ûñ³|ä:ÏÊøÞÂuþ«á÷žèJ©dû9ÿøøĸ¾Ë2ñnåâ»öµŸO3YÓYV³ ø^C§òÿæ÷”R~Tý#]e¯o­£;\Àö‰y4ß^êÙ:üþßKù½ÔyŸ. ï¾üÿcë9¯þtÄc—í ìÏ·ùŸÄãËWÒñq½'øÈ_…õÞàGžçè ý_Îå_—ì´ì=?`¶Ooýä|nðsm¨³û÷sý”C}áZ¿—®Üߨ“y·AüÊýœËìíþ/OÝÃÖÞö|û¯;ÕzÈôÞ¦ù·=0vR]ngàFsý¶¿'wüà·œ! ‰îùnÅùŠ_‚U:EÃù¯œ}7XGÛ˜ô>ùÇÈóÏcãðɳ™dÕ|Ìò¶æç=þ¯Öúß}à_ò³éIì5”m;¦Ä×ì﬎ýzÿ¤ø¨ð°ù¡v_m›²þŒrTaéßà÷~qfô½Z2½Év2«¾þO£äòï±oºIzþ˜ã ?ŸBŒ`ƒ¯]{²›ÈÅj‰• `Ä~¢¡ Ç,Ř;ü~”Á½†Hó–~Ëéö¤ýn{r]„é0:_Qø_uÄA:õþïñA^Åâ>Ÿ<= Õ¡4ð×úìuð ‡m·M§¾˜1`–¦úscOWÃÞ@Ñø²Tú]G¾ÕQk,»]|­SÏúEïôk»ù?FÛ™‰ï_gcl3äå§m{ÏyÛfuyù‘åOUîþדּåß—ðxgáæß™ŸVÊ9|\7šI‰aø´öØŒ,®0Ѷ{Ú_‹ÖëYDDÒé¦"m¯59>Ý^KÅ?ðIÜu5ù¸r Q¿3Ãò1Ï[ì½Oés¿2#§‰îÝ9ùå—t`Äyß9Íû®#u„ð»wà}4$tÞ×Î~ïÙžÒ¸_Ž>A®ß.÷¡`óŠ÷fFøz™ì³–Ý #b1Š˜ÇP` {Ý+iÇ™¶/×!ÜFÜYh}V,=Äae·ŸœCžVU!-+*6œ…4*™¸>—|@F¸ ð¦”B™Ù¦›Œ4j¿úóÕĒͨš`ÜBkBd¸>‚9k‡y¸òž™’h?kÁqhÛ0É«»ÊŠªJ+ •ÉX… )  ¡¡¤j )(¥))¢Š (h”Èc3./2G‡,®Ìo.ÎzÌoÁÝÄ!Úf1½t6³$pßšŸ¼c”Å<3õé° Ù“­!ÓüÒ¨ÅÃ(RD‘#ëØîðŸMÕ–·¬-É¢GÍo?û'Ø?Ýø?qÇöˆ¢Áå{f“ÏBÙAŽj̱Á#;Î#ÄS»Ì)Ä`aDw NÜÁjç·úF¹5·íøtövyžé£Sݯ½½ÔqC¼Vó¼:"Ë6½±æ«­ükÑz[]ôþ·³ì}î|ŸPø<züÿ­ü¬ŽíÑ,I'ûßÇ_qÎyN½$E9=M“êæÛåëõ‘šÌ·Ÿ;^®:›y¨ò£/Úšå+‡+ý…P¡åÃUÃ6Çú76Y~†µð{æYF—7K^>9Ó€Tèýµ~Úg{ÛnÓ±ýßw~ËÈù›·žó[÷£~©e‡O«õ-²<ñÃxòÇIºòw#3dMnlµ-]N_ÑU¾A™ãʆÚH-cmQ÷žûo(»fX#Ùõ+×|?µ¯Åöƒñ>[f@ø~‡¾xýN¬Cƒåÿkß¶'š¡_ Ž Ø¼Þ[]ooÿÎù±ì¢n²¹î‚Lüâÿø ãŽ3aÇ QËF=©ÆÁ~ŽKŠÉ^ëàg-ßûÆI¾iJ¹”ø&$‰A±êvø›ß§ü^'ÑYS´joc‡MÔz?¹ìõ~’t~ÞÃÖ_kßΧ.ºÂ!.ö³8ÿ3{lŠ"ÚÞ+Trÿ?ðþß©ãUsÆQ,ãŒDcàÑió8qX1›³PïLúØã£Ü5õZÁ,ÖÿVyŒ úþlõV^c Ç*s·ƒ'4`…“uBçM=ƒ7 óÏPÙ5ó,ž~PfÌFýœN/TBš%®Ô/vGÇc£@tCZdÏ›$·¯¦›d3žÃÉä='¤½MÎöW2_Þýœ¤¥³¿ædž+o½Öö¢#xÔêîv×KÒùÏqÜ;xyø±Ÿƒñ´xÏQì>? 3ùÏìQR4LPAT DIÓ1v™ !TÖfvîþóµìŽùá0åÝcˆIÅë¡Ðu¡Xèóáƒu¡\TÞG ñŒ K§``kŽuNì bUÜ#Ž¥<ó u ú»Ö}Ñr`—̾°¥]a û›”ödóèÝÅO»&)ŒEí1!@qàÌvZèVmf¾R‚¥³ise¸[Û®<‡ýü½,Õò²AÑxÖb,Üq7'Ïb5S œ®]šiþšíVÓ|÷O*ÑÇqäÞUcÒ8QݨÅŵòñ‰ô8^Ñö“èNB€69àm×Ý燮õ3€'Lh†üÚ -ffîJʃB±—Ééîå@~@TfhÏIk¬ Cw}-hRlÇ.Fš´iºì¼9·ÜéÔÕ™™ß.÷c'ç)lÌÃÀÞaÉFšÛ %C ²¿ ½¾wY¿ßp rÑ®¹¼j-«•òäe¾·MÊÊØN»úŒè(­.…NŽˆ?hÆw¯6ÛoÌ£ 7ìú -*¦3)_,÷’lÙ° \–o&~bÝ¿c‚30\z†ŸÍøyû„¶ÉÈ+®Hì¨öìUG;m…y´’;ŒÒ’&[E“hˆ¤ðþÈÌ€ª)i)(¡ˆZB&¨hh¡¤ oÍûï¹ôŸV×Qóºžõöž«ñç}ö]ãÇw¯²ë¤&Jiei\a E±Ù×EÂÕo¡S·]¼|×þM…žÄàÝçÖ_Þ‹¹ûÖн-e'¬µŸÂîs¦©0”J“±ˆhoÏ-O³äµ˜LúôMª–±éú/½¬¿¥_½0¹Fc úæÒ ÿÝ›æ"é_bãÌ1›šúÕ<|­¦ßŒÏW¹`Y6K÷΋‘é¬\á[µý¼÷§0ûÆãXaff™OP£¹Ä9¹Òc€œÐ;Yã'Ì4^%ã´qY.í2\N·Ô6dc‡>Y^uw! Ü$–†: ÓÍpR¼è¼0·tÐd§6Qµy>_ç–Ëá¶Úžî©ªm¾GëI?OB~ ÇY«‹zíØ­ìš—Ó Ÿ–u©y–ÞdÜôQ”8÷ݽKûF=‡<¸ÐÚñ›cŽOÇq–(]ÓV*RfåÝVÜ7pµYd¬R¶ Ž ¿š³¥ëⱩx“&ǸP2®Ü‚YJÿÞÑ‚G¦È¬+Ìášü[6TÊOjKª^ó#̽bs8nŒ¼ƒ¶åÝ×qéˆZ§õèÙ3n=Ú÷뢤ֽ(4»1Àìéé¾Â²²w}ôñÅbØSªøíjõm‹ÿ·º¹© ­¬z&{µÚmõù„mˆI$Ëue´ãóuÛ{Aã[dÙüßœnÞÑ+õéz ;Go×fw;+ôÕÑÆSsW z Hb‚!H‚ |]®S éy½wÄì>€÷ž/âó¯6))*„(ˆny;ÿ®ý^/5øŸØúÿø¹‡2¢›™fFEI‘á¾Wã}—UïµûÿÁÊå-QJÿ“´ß¯ì¾ }ÊäUIMAƒÔõ¿/__Ûû^›ãþÇ]T”Ò×iÞ8½ÒñÜâ€ízÏOô}§àý¯]$Ê%"׳ïó÷×»ç)ª)¥Töžµïãq´i!Šé1 &<Ê|ì ƒ«sƬ+aj-OÊT¡!| ÿ>ëÛÿÜõìÄAýx.¯$P³Ç™åñ8^ÞÜbØê6ã÷ªóf!!ƒÏ³¼K‚²$2=~­áH^@9&¿? ¢¨{§Öý~·}øáðpÞêú¯²p:©š?Â~޽x”UrP`H0˜^†Ó~ÿ”²7áÏ<è‡(qýÌ‹ BÃpÈXn …!Ö‡ÚÍÃ!¸p†¡Ä,‰¸n…CP°Ô‰¢ †¡¨XXb†¡¤*†C!Âq"jCp°Ä8†Èj †CpÔ2†CP¨Xbo>¢78Ÿ²•Hs ……†BÂÃ!Pë°É܉Ô2 ……†ChXd,‰aˆXj ÃPþbCpÔ6…†Cˆn Wû71Å©PÒ?#Dº½Eõ:†¹çZæ‘§n­k3vt홤fgµm:ÎS±jöŠèW¡`„ÂY¤=Pâ! ¡¸T5 ‡pâ†äN!¨d,‰´7 B¡abE†¡¨d7 ÃpÈXn…†Ô5 ÃPÈd2…CHXj áÿYýæVÈfí(~1d ¦"¤0ÁÏ9Â$ v Þ Õ   åúâ´@´JºGòÉ–+¥cxš©…úêí¶“—)•<ªD×pÂd¶„&PLû-ý7ku¤ºå ;i Pª²WVðËdò.º8&µIîþîν_y~žùõÿÇ#ùÙ½Cî²5Nòü/ž£Ä’C$ó¥#q¨‡£³êpÕuõžOÚÌD¿#NãHa’2i„©$Ü‹Y!ÑkÝÍ žIÍœÑZ8Ãy°‘¬(#­(.%VpwÛ”›­®ª‡Ø½'!{Ä=I³ÃïqãzòGæ¹Û^ ‚xêý@vÇI]ã|ò»DRwƳ"/G*/Öt""𗤍®bàî¾Å‚¬Eþ­í´¹6ŽE˜o¬Ì‰ÂˆtÂ;C!¤*†¤K !a¨Xv­ÊtuGÓW—ßö<±Òfe8f¼$=ì¦z·ÈdÙ™ÙG4ÚZbt!hRîØ³»är²¸°?Òò¾eîïr„©¹!X!: ‡’A#r&ÐÜ8†!ˆjCR&¡²&!©!Ô2†Hš†¡¨j37"mí!ˆn‡Ü7 C!a¨d,‰a¸n“õ“Ô7ÒØd,:CpÔ5 †C!Ò †¡¨Xd?/,8†¡ˆq †¡ù8n‡0ɰ°°ÔôÊ“É1212dæ~NyïÎéÂXu……‡0°°°°¨Xb‡hXj !°Ô2 ……†BÃ!aaPî…CªXq!Ü,2C±w‡À¤r ÕµmC»W»b­Ï;‹tkÚQÝýJ¦©«lϦy'íri8†C„=¨Xj¤5 †á¨XXXj CpÚ †ÈXd1 * †¡aˆYPÈR†Ü2†á’&áÄ5 …†¡aÜ8„BBHL„ä$!Õyµ.ê‹Cå{( €n-¦j^jê錯ÓNÚ¤ÑAlÿÜ/€ÅeqfÞmêÇ&£÷Ѐ^ïwF~ý€nt×ï³w¿Aþ`Ãs¬“R7€ºª£GÞ÷ÄäYo“5HöÙ÷Ÿë¹†œj-™ÿè×+¡ä’8‹±³ýv=¹ØÜ¬¾ŠÙÐËúûR~»Ëúÿžëj@rý0w-È/~‘©€©¦ „¥*‚šB¨"Zª¥¡f„¶[Ñ"ص"Z‰-IlB"!"ˆÈr_ßGÂÑôÛÍüÅîܦ@N ›]¦¾vWڈ鶽geªàé8'’foíK¡y5&gµêCçOh4Zµ‰ Z*?,)‚€Ô %Œ(hàNq‘: )Çà†#eÄo^Ý5þ½ÿ®=³½pÖL9qÌ6,ÃÞÚÁ® ᳪ;Ò°®'p™qÍ9*µ¼ÒÙμrw‰-h¤ìv3^ûÓ%–±%¿Sýybš¹f»åN“ÓWtÃáãµÖõÓq'a_ó{mEíÙ^·ûéî7ÐDà á®aß½!‡˜„!_Є BHI !2„’{¡÷p¶ÎcØ»Xª÷øÓx'–«Ùº&ÑçRñ{^­BךÌMîÍîzvüéáÛáó°øpödLš†¡a¨je ÃPÜ1 ……!Èb BÃ!aaaÜ7 ðÜ4†¡¨i CÔ‰©!PÜ?LMK8†á¹pÔ,5"Xq ‘5 !a¨j BÃ!ˆd*"d5 ÃpÜ2†!´2 †C!¸d5 †ÐÈXXd7 †C!Ô ™ €B5í¾®ÅžèÞ-¶º*t'¡RŸHdúuãÅ4›šþ*|€ Ä©JƒAGñeñZ¯Uqý}‡ÒÎpæXáÏžX—I2ä »z*!p©.«¦«)=v©í¥öy² Œƒž/ioçk™ýYÕç» £ã°­ïv©ANC hµö#hòS ½KZ…ÞÕfÎÛÏ p÷…‰ €P˜ cgÅÁ©HÄÁ<ƒ= p\µÛ–‡ÔÙqÿýÓë8ÞW}µÿÚáéÊ…ƒ}áÅßUe쵔̃y AÝáÙ•ÂìÎ˃KöˆW÷YëôÈ:kE„À¶-{L¤å&S8]ã¦xÉù7•šs!X¸³š†zŸŠ“5LöÙ€w!ÔÜÚ–#RИK•xÿvz“Ùí•K›±|ë5ÖwFM¦°i››äx»¯êa:_†Ã)àdÆf8.}® ñ—ÿçó½u¬ŽÇI8·a—ý2°Äñ¾“¯9µ[\¤G 7K€Œ)¼ð½¾[ÎÔ8Nî0,o‹2A-Às²Éû5ñ‡A”´éDã”;¹1¹ž/kQÛ¼ëö,kkËŽs¯µ ´ Ìé&äL~m«³#móÓ%GíÄ?obë«¿M\²Þ=Þ|s³T|1©ª±s cšÁ'"n‰Z¡kYMˆótþî{›úøÀ¦Ë¢ãq]@R ó›è`u¥êP é½GV .‹-hßDzÃÛxyjšöbÊZŒ1ÜâBÛõ%QÓ”=$èúö.åËžùz'š¤)^Ó%½íßþ¹µ¯ZÝ;׼Àg ¬y†fÚäÚVOoËv*Ol‘ä7µÇ–÷5;«?+Ò¯Š €¾^¢‰æ>]3V…/dΡžÇ\× ‹¸µ®Ã„ FQJ*c2Ήvm…’ã’uzî0LÌÍ—‡Õц[dû¯rñ__}¿9‡bôÞÙÃs4Ÿùí&uÙZ×ÕGÈNFèÁIhU ëÔ¹ñÙò^ÿîS¬!ó-§EÞv Ç:h¾œ9ÔbhÚ Àêð½Í~G èï9›ï~ü¾^ðã[sxg)à ös’m¬Ï ô(Nfz§#ª\L ®2¤ÕTü7K.sROjܳ&ËÄ Ï•ï4è÷q´»l›E€K³PÓºà“™Ä´¬ÏXÃHÑdÞžºLÍ;XêÚ‘ÞÛ‹E¢ì;}VëcÄuBí8NÕ Z¡áAºZ^Pdé®v/Cgø¬ü–Ðää&’+Ÿ£û©K?æþ,“MLâgZÄ 0F“i=(ÓnܦÒÉ…¸1Lø=©ãÈ"Òþv|X~:W CêÐÔ5 †!%’!$9."ÆqˆÎr…½47ªʹÑÁ5®1Á3 œ;&ÔW÷YÊKr·sÜ—7'A¿KOêÐÿI ¬¥{ûmM_—ùÏ»øÐ¿ŒCà¡a¨Xd2‡ÖBÃPÈXd*†¡¨n………CP¨j‡å¥‡jDþ¦q"n‡0âDü¤Ü7 B¡°á ‡Á–j†Chhš†BÃR&¡¨XjC!aÈi B¡Ì,7 C¬°Èj†!ˆd,:ÏÊÍ¡¨n†!a¤,,9…‡Hi …†áÔ>zXd7 †BÈ›†B¡Ä1 †CPÈj †CpÔ,5 †¡aaÒ !adL…BÙa´7 ¡¤5!¸nBÃ!¸Xj †’^)·´£“–{ÆLã STÑSªújGÅh³Í 4‰æ‡žCP²&CË8†¡¨XY¡¸bC!aâ…†CÈj†C ™Fd$„ž¥KE¨w &ˆÔmÓGùç{®ß'ô_Bñ«òu_{ׇ±wÀöø0ÎÚ¸·º­ -æø½dk`ÝÝF³Å_4L®lÅ1Cy—r±¿ìpM†Òeï€@!ÓÆ¦îw+öÌÙ—,5¶Îˆ°ïùì”ÿå‚6i‰…hajŸÚˆozßÛ;n¼?ÀëVfûçcÊÜÑGÅÃ;.}òŠu`öoµô?’Ï~NÛÄP”0…”¥B‰%$°´ŠDSLÂ4„%4UACCKUUD…1DÒEDSP@M4T11444‘DÄ‘$E5IÑEPPÉ cc M™…×éú.ïð¿;£ßæ 4ÚÝ÷=úç=(?ˆ6ícAé³ã²­¹\Š’ö@¬bâáWÕ<Ц»ÖÜúF^Kø»@ÌRóê6˜üÝŸ\Îãç1óï_ª]>H :ß’1d·ÏRÄ좌Fõ†SvlÊl=[ žMØÉÀØu[^;¹½ZësŽÔ÷ mªdí›ñ † Ïpë'%Áÿ¬#0Ým «õbƒýÚ)ª&FOÅ]dìzœ•ÎzÌf³ýKx&îçÉ´[Œö¼wãÁ->M­i±{›)î:÷¹+„Ò¢%Ÿ_ñòir‰v>×ì ÞOþ+V,Ås9Ž.Z $wjóÐ-zjf…¿C¢æ¶xlðcaݶÑÉÙ©l«-UÏ .?Þ³¹åãZþùr}¿åŠ"õ“|ÙOßr<ºÞW+H&Ü.’»”¯¤ƒÜg^¤äOIõFÃcÒ³ÓÑEš¶5ÄiËà8Bã‘RÌÅjùä;ÚWåKVÔÁ<ÕÃ1ܸ¸cÙÓÑ,„å/Éøquk®˜Ìͪÿò²ÙVš‹LùèïœENb“ÁÏèÑ¥CQºÏû˜ÞÁ$³h šp,ŽTîþQ`IwÇñ¿®=’Kå“O›µ41¬™Xp&¸É!zôÇœTßt¤¤©„ÃÉãä¬ìµ÷‚L&×ÑËâ8fa¡¡Ã™»†¯'dæû³¡Ô¸çºæ 79nk|5–P¢¾PûÎçÑß 5oñÄk‰’ûþzº_]vuÍR“çqÉs ˆ·/n|†â~Be³lõÁÌrr-Þ¬oÑÒ•Ê/\ãgv«©]{Þi:üÆŠ|úZ!YOK‘<™@—÷YL!9ìÝî½· v>–mô> ¾‡ûÏYí/gß|ìÒü÷?Ýœz‰ >²8¬NïPù$ƒ„~búÁ³9ÙRÿp^ä„Oa‡©›€õù²µžJÁ€×fѶ-óç¤Û(p+i5='—L3˜6‘*C÷éǧwkmÔïö¹Üdrþµvû’ a„H„#h®¯Æ‡th¦â¼Þ h yà¢p YÆJ`@cO—rE¹˜êbzÎØ°6¾½3I|ÌÎrÆ«[œÌ E©·Œz‚ß …Ôrˆj«V.þh$@wÏvO•$„ŒVº^«ý9áƒúþÝõ,MVŸŒáÑæXNvÈâ4ö§¬z1Z¹ÃÈ×f²ÂZ÷‚}Æ'±9æ‰Ü˜˜¡“ºëçwm[,ÏÞöIgõ¸Äö=.ô…O[£þ ÷·cn€) œ' üãÏ`¸Âc±êì¬OF^[$ÉÕ )_Oè–>%@"!üÜ^Àê¯æ›€€œ…l{Í&ck­•ÒTR€pÛë?Dejéœz ƒb3#Ï« ÓÕWª#¸‰¯-7÷5d’âqE–Ã"ׂx%¸^ÚðÞ® Ãû§šÄç¥ç;ÐøžÅ··¥¡‡-G+Ì @R¼ï¶6JØûÞÍí,?ƒ¹¹ÍÆMéã¾9éXn€ŸûI9,t;rÚ0Dè` !ñÏN" ³0:H~{ªß¯=£b†Uñûú_7©Ë Ïæ¢pHÚø¾µK•å·éo?J]:–æ›ë5wê\ÒB¨öG˜@¹ò‚#>C¬ÐŦÀ89áYñc›äýÙ.÷*þ£n}œ³ Pƒð@7ByAÂC1Yöw&xìo®€¿õQÐÞüîo9nʘdX¨ìG‰$éÁéÚHSº¦õ‡U“µ}ÿÍS=9Úé YZµ9ʦ˜€ëc²*ã)­ÑdøÓ|òwùºÒÙlr¨eôœq¿y{ÀôÁÇ’ š+Réµ_’ŽŽË¿±·–t°ÆÄæé« ¾³¸|oÚ‘ÛêE1P>(»èÏãŽækjîƒý$e0Zç'LàŸ·Ýv¹ºéÄáñù“z÷ÑS4ê´y.¿ öÕ ÈX¸ûîÞ Ù q®$Uí³@y½ç4 ²8!É$‰Î:RÛ%1ܘÜv £|ô §<0 [þ@"•”c¥Ùh”<œ9’DÌt¨1ÿr;Ñíê²¼ƒèSd¿Aײn ãú-¤ ñƒã=y\éÔUurìvdÞQPôæÑ 5”‚ºJ»ˆ,­(“çÊ>¢p²óÆÕ,lü•ÑxGMR+Ls$@Á^ëî¡X‰¾k©²qí.ßãªÛñ[0óԑSLø§›ÿ43œfÛþ fÔàÃQohï¾ÉÁÅt(ä,‡_èèÍ€AœdN¿b§Þ˜æê”8Q CB Ä,Êù»Õ.,-¡·[MûC,â­[/ÊÁìËìjæ¹S}ÿ›¼®e†ø e™ûŒfsËŒ2ôïfßÈÐèët°_|¯Hз±»æ$"úEìÈý^å¶qK»o"ؼÇnÛ®¤[Åý¯¡ƒbÚ%ö8<¬ëLcjm®Q‚á—lá¥Câ7þ|j$Ë®x$TßnÈ’‹­Ú~=¨S¸‰_cS~<°Î³žt¢biˆÓÁ99¤Ë’†Ø%©ìÐÂ(á½3Y¨³Í®‡Uêfý b–ýŒO윇Þ> å±a¯ú»Ò>xÜ0§ˆÀcοo~v¥îG­ªÞnºó:£š/\ã(p0`%fi<>êëüa»gâÔT4ÛÚç» …w]KI)«ÉO’eIJí~fˆH!ïYÌîb“»õõ€“ßÕn/ž^Û›Jà a(q &n«Lï¢è§·ë-ÜV—2é¸H  rÖòhkH³Zr Ú4Ó q…24–¯#gÌÏ7’ó›7¼µyz‚†jZ¯n½)ÁµY¦fdDÔ"Û ™hB’ƒƒ‡6OÓQúwµ´gî3• Vߌ3×DhÔnn[5Tª_÷F›qNø³Õ ¥V'#·;¦žž,'ßúxc¾Zu™@Aæ‹Ù¼Ý*‡£iáöö¿Öeá¼À"þy%ÜÔ±‚«èÝ5ö~Ôê.åÌ:”µVh“÷òÌ`>–ÆyÆxŽÑ¸rÜ Á ~ßoýR­ÿŸeøÛß»õ“fò²>›ømì“}uª"çÙÕ¾Ï*Ó/UíüçMêmº/þF"Ö¥Þ5Æê/›ž&Ï„-†4b%s0kuŽVI-çéÄ3bú<ŠŠW•hÉó›èß2×zk C…ê2{âØïôu:+‡#2Gˆû´¶“ÉÏ(ù„ÀUz‹]‡˜Û Àl‚{ŒDÆùÈí¦¸ÖØééA¸˜•\\¶ÀB©d)è*d1‰ŽèêEh;ÏtJSVÙüwS³¼»Œsã’ WÊÇ†í§ KÚ.¯€@ˆ !]΢¹fÀð^ûEÎÕ^E©hžéȲ’ò€ L¾¹ïïÔûqñn»¿ ·Æi¡Ï8Az@ì'—qCÇ»ñudkk ö˜~¹‚K0!!ÎZÍq©›;à=]pí¢€ w·àNË2·g¡ždkÅ:éôD‚IúÌ$(úp%_ˆˆ¢¢íÈû±ðù»­çùïQÒýoÚÝ`/øË?|°&pP "N‹;G éÏõÏ5˜-”]ÊÎk^Æ›OYÂáõ3yÝ£Z~* ñfÝ ü6S¯wuÖ°¶0ÿóøô¦Y4çc@"Ù"È®¯×¢@?•-!Ä"Mà‹½’¶ÿÀ¥Š«ÓºÇÙ2÷§‚†JäÀ!5!ˆ! ¥(×Wö¼ÏEÑÜ5›Mw§´‰®‡|p­¤œZÜ;n=Gyò‚ å8©¦„2Eã­º)A LiJ1 …"RÑ?*5äJ(JHhs}ÏË+€ÉØöÆûì/} #*Å?Ó€YÜÂi_S{ÁŸM¤ûe[sÊØ½Ì© D^Å$+žó‡uÊY³W8T¾\ÈG ªâÍ;™‘ôwÌ$&Â}ÚçÛ‚&zw‹n’øÈåùÁH1¶eÔ¬´Ä3u0³iŒKí±¿w!½(­=Tíîµß§`;×:¹Z tÖ¯ò¸¦‡ÿËÔ ]õ®ÈLÍäpšSh]­Üœ%†ü*hHoä±\XØ-·CÓv¥dÀTQá>»²bZè”${ø#F‚FÕoñH3 pê:å:sš*á›ÎF>í%"pÜå¯P^ä9`ìÑ® ê2¦Ò~V¹¸f*Ì›wN` £-ãßùÀîÿóñà²íA uæëäøq‰Ó] $ó¼3ø¼”7Ÿ~¥¾Šú ^–›°×qâÁyÑKÛiÈ{PI`Çpö`ì>’ï5}¸8ï˜âíbá[*Ëï!õ% Á¨"÷1÷wúE¼0λKÊ|p»(Øé½YÛ+µzÐf†Ðlæ¸úi‰ÌC¼ N ¶›¡OϽìù÷FC=¢{Eèáî•ÿ¼¼ãœO:#-Bîâ5Mu·˜‚wSĬçYM¨±g+‚‰¨ÀB }ô~ Ëaý»Óân€¶‹î–£è×›Ì\Áä¤wCl$[ƒôË­Ë p\ú@†¡Ž$Œ"ÚÄ&¤aËç\2΀-B€YqyÊ32œ3òÒG ô6ÿ5r«ª×ç÷{ºuëvñÇ5 5ÂÍüí-Q> 7»i{í¶s—ñnŽóðÓ²¸ Ýüî+ð_>fïûåys¿ßEìÉæÞˆŠê¿ÝÊvÜÜwH1È=Üÿ·ñ§¸»Ø"XŸÃVùÝì€-`©!àh-ëP¢)tA¥‰=¤èÀ‰O­/ᢡáÛч÷ä~±ð‹xÀÄ@‰,Oíé¡"«¤›Ý^Ý`:szVìGqÏw)ç¡ÓûÅùÿ>,z`§æí-‘âÐð¢‰$!£âk½ôá´ IwUÙ{íï¯KàsÀpnˆ¬üô°‡5Oqß9Ï]§Ï®s„ÔõÔÜDÂï_:9² 8Oüǧî*µ½Ê#ÿGôȹ5¶Å~¶²zVžn ]ð W…ØòóÝð!—ú³naØÐ‚ÏÐüœY–€'f ¡4&Ï2Üþiö=mZru1¢²YÁ^«ì¥sFÌYq@q¨’5òVýVMûüù™š‹OEß5¥x1^Í *n¶’ž@Fƒ@œ¹m¼ {0“ã#zïy4ØE©‚.ªç0º8ü%¥Ï¤[º.%/h|Ž÷š@ë‘C¤Ûh·§TD ËŠC¿Îž÷‚ºq´i¸9Dã€„Ô $š‘oÁ富ýç2Ûòè_#ü€xîé‚¥ MA³éÓíåƒØÇ¯þ;#Tˆ}3KŸ”Ã4?Ö†“Õ·pöKí=›¬ êâÅF&,ZQιnC'ýò±7›Ç#D@A6˜Ì_=+EeÕ(ò‚n€ Š…A@b”Â$PH­Ñ EňغMpïný&88Úl­¾~¾}oÉòD>iç.ÆçÛÕ:>ŸaOPÅ0¿j9¢ÚO „Y\1@…‘E©´-ê ê ‰Rãõ›D@“ÙòãžX+'5~6¯_»Ì3,[@y±§ü¶NkûH·[ûÎ †Ð$^v§ž62Ø$«´ÓÓ)ÃZŸ¡P#w˜½W“¢0Ôâu(âr©MCF“¼úSÊ0j i©éŠ`¬9ÜvÕ¾ÝJò¼Úmž7=Ï%\‹s‰w÷9Ç´°¸Œy2‡É翯ö#·ÜúžûÙáâg àxºzÜû?‹NNuùÒÊ^ïD8f,Nn@rÚ;äul?FEwµÃ½c²¸ýf}üLÂåò-ßçA¨tï(ð¥Ìì}t³ 7]ÿ¹æ‘œ>Þœo4Ó,b³Ò+ÀôÙ"n¸‘æySv£-è+¾¢R7ª{úGfÃÊØpzíyZŒo”÷â(–®/ów€ïj€pÏßðä\Ëæ¸´í1%Ô¸évóC‹YÖ÷ŸÃþÂè59¥@…„v# ˜ÞxxZ­T×ý oàÃ$©wœ zç­cç ‚ÙÏœZIC€Bc]íak^¶d€p€tGi æˆ ŒÏÀ #R%B‡¢p´S !Ÿg7 Ê¹ú/l|ÍžX@OBýKÈø ƒ'à‘ïUJ –ojþvzZ)Ëï{ _Ð |ºcMê(¼J%z#vôn3|!D‘K&‹š#ƒÁƒC™íòËÉy>L—‹{ôž}³fïi; ¨¤†ƒ ûC»j—»[3¼[÷£ >0×Ê\ݼAûç×öW·°;Õ¨Q þ]~j<‡Žé=Ø$îx¸ŠÆêm¿¸ s.ö‘tóý»ZNóJÏËç¡ÝÉôýö†ZF\–04à2_‚+Û ¯…˜¾Ø2Ѐd8³ Ò#yù¨ÞKø27³ ¯jÎóÝ`kÍS͔Ÿ‡eú²ô%Òy&ÞfÎYØ]A6‚wyœ§5~ô?Åì*Ÿ7Žò»•^sßÏ;mÕÖs:@O &¿ÑÖ ê>O¶ •ÊfE ÉéäȆöH6ˈœgYáݸc€1€ä È-“Ã}”5âW¦·vzöûh»›|J®^÷++9«¦×¡:YD1/eøobxn˜wL¶Fõè|½¶×ícÀ TNh†gižÎxþD7úh_–ѧçw-ßJ‡m¥Š¯ùëýÎ0¸m£&ã[ÝÂôvùNªDa??t¥:O ­œ0}À9ü¦Š™ÂÒõyðkd+v€Åì}šìIµ9Òú00î™þåÈ€6¨¢ëâ°»zy$#_ÓQvf¥H¿#ÍÛ¨ëÜ [~i‘ª­íOúZ÷ÜVî,ÓÏ^§Eo’>Ëþ¦ I=ÉûŸþ›¢þDúûŒ{Sþ‚§ì‘éþÓ}Å‚A¹,)é½÷±ná]±à@ FÓø|¢2(6{ ‘d¢ªx¨ÜT eà+<ÆÊH‹mæ‹;ícþæ<¥5 Áßsi·m€“«Èšˆ¬º®\âý_ò 1ìHîøC®^ž³3¶ZwâØöbóÛB¦ã0± ˆI€…G]Ê@Óƒ7$–d@ ˜@çè9îÒî N­€%%„G ç“`GÝŠd m˜JÞ×·õn죚òRÙ‰ ~·‰¼ÍàƒÚ¨wvjăcíéßû8*K-•›ø7èOž¤ân1Rðì“÷E;f9‹ß}Àr¸b@F±äûŸs7ý”O}ú&#?ö¯MŸØ~´ÍÌŽ4ì ïñï‘ ÇÖ&O—³Æ8ÑÁ³5feÝQ—Ç s—ñîx+w”½üûÄK λ+ UáÞBqn’¢]{…+]/k~ߌ†I§«…¶øI G¨ÿV ’1¶ÎBgÆÿ6ÖÑΉï@JüûÙ÷þû®#TÉÅÿ¤5ž=ãVþ‰€%$°2çJÔï‘’{%]¦OAJruéê ‰½ä—Cd²ÏÐRw}ÚIk탂¸–?ýüxÎ+7â ¿²ª¸òÇ¿-ÔRðãY!„~î£GÔ€oýL÷Ýfùµ›É=¨:EU>Ýkønª[ýŠf¨aiÂ}@µ§Œ‚íïŸxmeÚiH€E•¬x^‚EÿhñýoÜb.Œmì¥ß`à;•¸ÿÞ,e­zŽmÓÒ¯•=y‘Yiý1 “Žé§æ2ynøýúP»Aºúð…ÆÝo›?+úy ƒCzK$Ĥ„ÞÇv6áY€Z¡ðÞì<úfºQìÎox¤¡»‘ÜrõÅ&TNíè_ß\ʼŠÃnÖ×å÷*ýž/oå;ñ:!Œì™ð€/‰ÇÖÇ\A¡ÜEò³oÀ<lÖšÙö†º}-TâÛj< Êâ Â+?jˆu²¨Äñ‰Í«ûswjt/¸î´ƒ¢›Ø‰‘ëÈ0­@ˆ/‰\¨>ñ‚ýR,©ÚŸÈ»Þ¦Ž;˜¸OlG÷Xö$jx¾±5¬ýJy-ˆãj4zm¬ZéÿœRø¢­ó¾Y ÄùuÚêÈËH^—ùCŸ§Évîa³µüo 1d@Rëë–_®ó8,ªÿI“ÕôzÅÿ-•ôë¤Ç±±jª/ jÉDpæée?·=g¦]š–Édê^7{ìÏ±Ï ã6 ÿ˜ÿ±\UœL=nû2*¸_ì1ÅV¹ü6;lEÀé1­¹ÚæÆ½%»iÚßÉ9hI&Ó>Ïžü̇ñïLü¹wY"Óß½(Üäûû@$Xh—$ko“fì62”ÍåG|¤P„‘[•dÕËLæÎ*׳šGe–ï=d4šSû6&VCjÕ³¶±|·23©Ö`ä±VIö_otÐWÊèÞ^çu­‚–Îe¸ù ÿ´@î"IëÉÅLKGøù? q™N£'ðl±v›ý÷6åKMÊÜ–Hp5ÐØoÊT¾H|¹›ëº4˜ÿ*×.wýóA³sÐ1vb òv–°¤…ïÃLŒpœ~ý/ü¼°ÞŒÝë©ÕuèBf_dz¡-Y°EÞ€n)ýR©ùG=잆€oü¹\æÇ—3îJÌb0V y·Ñï´{ˆ1¼®oãܶß*O“·S€8ÃLjö;—tkêÿ%Ô·•1±K§‹P$sIû¶g ù#ÚWÄÆ  'k éï%讯ù®œ]Ó[Ù¤ Ñ€Jô"?ÁÄöEcÂhÈÑ‘¦j`Ÿ@C“XÍc¢:æiBƒÍ}éƒC£fßçˆjZDÇa 0è®/þEÃ];˜{^CÞ @1\ùæYV|¼%ŒÚãÜ?}I—+f ÉŸ*¯¯‡¡ö<›>Ùœîû¼ýjÄsç}$߃u elûÎQ ‡ÞÙ( 6×›œÕý(p¿]ž¹ ÅÄ5=ýŽK}ŽÏ=I à ‹p„C•rrˆPë¶©ž«µÕµÏÆ^l°ZŒ/ NG_]ˆëü)}ð,g/ýwEDe–Ý¥þB*…AAßõò {d³'D 6"ªÕʩڿ•a`€ 0$lÏð2ŠæûSLíòX¿#£ktãÃçÙÊN'\$—íìȾÞ,öÍïIž¨ïò\?‹‡ÄÉI—øЀ›Ý^ãœêõ^&µ6f,/Ä-RºU”å6‹ùaV¹Þ"7@³d Öçaî@ ü Ñ@Á~ð`y”=ÆŠ'‚}Ü’l³ÍbSOóÊ\uN/«š HÖ^Ž‹–Ý’ñîcÀ»>ÞÉ ú ï Ç~ÙÐZ_ÓàÓçä"3L‘½ˆ}Üü¬‡¿מ¹ƒÞ‚K=;o[ç³û(œgØ®ÛÝGQ_zNÆwîÄñïZ±Þé~ùñ €$ýhSªä-qìnIîö%ƒj_H1Ønè×Ù^å`ÛAÁˆÓ?lYõêÇr]ðòsÿ„3à—@çôSMö]éÂ?¢ˆæÓ‚Ô»Uæ]\¬0 üÖËÖ€ˆ¸”æß" ½V™CõµÝ]ü=¦¼ˆ€ Æòk\O³÷£§§à â!&]Ṻ2OŠSékŒ¯ާnÛcª#·ómÃøäöU0þ‹¯ÑP4e‹=5QiW’óü"ƒ.J÷C!þjÉÒh˜Ç¨²Ú5ÔNíW´¥ÿæE_{бäÚð¬AŒ!@6è0\娫,*Zݨº .øàs<´ÖWÑi#ïœ9•9ÝÅhÌp1ÌA±u€PßRþnj%3¿„_¶öÂA}âŸ'WÍzm~5 B<“_`s°UyWÀ`ln- ßoô>»oÇúûVà]³Å~æ¹Ô#mçâþ.ÝgÐH_Èw 雈³OH\£éz˜´~üv21]ý MÁ1ÇìRå…–eÖ@(3å#hBH  ã`qÇ,œð ¬¾ïÐAëO"?# Åô&Á¢g¶õ̉ñX„oµÙï.!1³/Þ¨š"ïÇs|Ù_Âôé¼f`ú±þƯHFóX‹høÜ™ã“ÁÞl¢…œkß…ž·£°éNc|¬¼Ö­ŽÓ°Ë^·#%™D1^D˜øe(úR€€êåÁb Hü?x‹ör ú7'`Ñ[*¦XaÆïf¡Ò «•Wp‰ÖÑw´›@ÜAòg{Ð?;ÃQΛGt£Å9±'µââ*GÔæÅàhð•­1oÛ;€@­Bžñ`¤^¼Ýør~¤÷üÁ˜ ’«ý|!cBuÖ¥Ð+88W¶„²ÃYÞÙXp•Ò2Ó¼&áçÜíTâ¡Éßwüä_ÅeÓ÷tôÔxm¬D y~äí °ø†‰ =¬¨!‘CÂömdÛ`—ÿ(?.]þF{™l§©Vÿž—Pª@†¸ZÃí™ì 6…¿Á5KtG¯8½tl·Ì¶®þG+–eŸùŠˆ*¥ÙöwÊZÌ;¤‘a~%´|‘ êD7¹¬ö©)(ÜÚ~—û4‚²¯É›à(b6ù|¯kÛ9>Î8”Õbß8­ç?[ÒôbØXb@"ió‚=âKkÆ¢¹ÿiaúü*µÙõqIK¨Š‚jÅÙÙ8½Ô­!Wɯ÷úìà¹Yd¦œò.ôOx wŠÛÝÍ÷4Q–÷±hØBé¬ì‡ gáýy°0"™Ï%‡²ÅUU‘[‹¼W’#íþiðµÛ®Öó£vý]ÈC~\ºÉÄ ÷“Îþ1€It4ÎkÿVÐ*†½ä â¹`°xU>¤®»è>97!¶N—êÖYåeñçè|ÕL°ç7°c‘‡7™Ô5› šõ‹õ2 ÿ3³|2ÿ©†ÀâþI\$«èÒ߀T’¿ß…vˆ6˜½%º øRk¸aÕàg ´-ix|iúrÏ{ü›Ç[ù¨h,µ:`ì`®ø¸: ÿz0:ˆÍs6{šn~ÔÆm,/ í`ë’ÖSü?îìþ_Û¡û-‡ÏÑ×v¨­;æé¨—`@8€;?–Ù$sÖSî·›jª6öw€Y%<Þr¹ÅäWœ;)ÖXȲ[¹Õ5f@ë:'‡ùÄ$63óîsþ0…_æØ,- Ú†n0p¦¾4¤C-ϽjÕ'ñø ’øŸlPØ*a uÛŠ«ü¥Ov¯ÌXmZœÆçô¿gŽîLúöú÷¿™ÀD1œ½®ý>ä„E\ôÄ6až‰ßi"ÎÇíº«ÐñæµÈš¿ó²Â¡5šDÐ;w¾4Íþà…¡SQ"ø—@«—W®„ -1€.L`n‘QÚV4·¢a†ŸûyQ°u:¼Ëø*} ì?jÏŸì°ÕLÕÌ÷_Ø5ò^æ [×ôœ·Å²ÀÛE60(šÚGÇ|›Äüº™KµùúÄø¿7ÛŒëýÆÊlB A•yrðƒP«™ÊÁáäþ~ŸÇ¸äæçÜwnÍk8_a˜lˆãÁ‚iÜdÔ•l餎:ÉfU=n¬—ä zMZ)}~wûMÔ+ÝDQø1&º°„;~öÊ@y´à*½§¶|y°"D"?µ¹Þ$­>Û[ýŸ ~€AWo¡â©"·Ïjuú-7‘hó­@ ª¶IBK»ì;ä?‡ך¤Èð ˆÂI{Êê³ï?çx¡…©lÖ”Ïeú±âœ>ak’è•"øUë:Äò ’TãûoßÚ ÆãÈE«£ÕÇÛ¹ÐCäý´5 ÒÍŸÝlz±(Šã¨Ý#§ ?5ôÞ­¿@ø¬úWûåpÜC¡–Û(kf#€A*ÜèÔµœ4§©3ÚGÓè“Î7 =Å#eÙƒ£4$^×µ_×,5ªú]Ïv ë_ÞÞàrŠ¸ê’¿»âÀ4šqé3aù9û§&“ç4±?ËC¬üË&ÜxT0É(ïëº[ߊÇ,ƒ÷Ì6ჩ™ÕÕu÷q Ÿ —Z®EΛ¿ž»Pe°+6z˜>™¯ï†AR1(Ú 9‡8OOƒ±ˆÿ£¸«[ÿn%œûâHp=ŽªyFRº»BÖ§Ij›Â€ek•Ðë+u=³ª­G‹qº©DL"ÊVÃY Æ ^g:…µ;jQA[Å_í à“V´ÞD™ ö/ç9×?^3`6JÝ^žžx0€%IWQ‘³åñ\/’95Óyì…Ui·v†äð°Ý”’„ØÖÝïï2Ÿhïµs¾^ ôZѯç-wÐF_Ç~f’ýwÏ=*ƒ/·¸‡Èêë5ÛßçqY:PÚÌ£æˆógp±¨Û3z¼Al’w*“­¨Äx|¼géQB:×iµð¢?îï‡g$Ÿì€[ž4^}CáÞ«mü JMÀ5ÒÄ>j]öZü̧úÓËòû÷nŸ».Û]>ð õ•mžÏ0/ [^…<ÈçØFËOe‡›æÝoõ^MæWKõAf´9e†.*âìÄ$|uñP_ ­l@z.ó`z9XfŸä3ͳ]yI–WAM}Y!üµ^¬^Ý»¥Ç“g¦òõ£¶§Ÿé‘ç »ØL’H/”¥›­¤ÍÙ =]K–1_íà@ ¬ö]œ;ž…?4«‹Ê} 5“¸ŠÅ° d“-v‹Àí€Æ*"Û.<Û,S6,ˆ½W·³ZÌż5#•4%,žñkM:•°ìKFé&³\9$-اR ù>ö÷¸ÿ‹ÜÃ.DåÞÿ  #9µ½ó9'E+ªÎüýÓ¬B+ž~ÎìHã2í@+Kðn\8}æ2‹²™èHÇ @žw$räÏû£:Å  p%î¦ï¾ÁüsUv»\LÕxŽ.¨ØÑŒ^ÚƒÀEumpk‰ÎȽe—#WÚ—2Ÿ›`µ/ä{|ÿ²šo¬/׌ð µÓâ´é¸ß<5}ÈÒ>ý1i–ÐÖC¨Û£gí‚Ióãö´™º-'WF4#:®šîà.˜Kãe“šÓ˜ÍÂÝXÛ²s®ÜíËh¿mUA}xcLÑ€óÌ›Œºðíõ(?EñyÊMéd–R·¿ÞAßùÆÎ¿Â4Ç[—l.v'[òç‹{Î:ê^úæeõmñÄøožÍ%`Å;è‚—V¾ýr÷X`žAtz¬l“§ã"D-õ¯Œú2­8éÐãY î´ˆÝVºÜ囵NE)§ŠÇÎÜÞ@ ®»—ï&×£óß­ybzþ–~nòîgŠL@ŸÍú¥Goöy‡….çûÔ8v¸ê XsµùWN7/Y­Rÿ}êcIùÄï„@¸¾5äV~†„ëí2=BÊ gy°–ήÔÚÆÖJã¹2 î¿ÎŽc÷Z4"híÖ5ž[BhÙ ´œ}$ìÄÄ åÓ¿ /ò·~ƒ÷{Eä~‡SËs>«÷}ÝýMÙvö޵Ég·±ê¾fH„bæ{ì·t©¿¡w‹OkcÞ 1,Ñ}8e<÷-Q5§š \Êl ¹»«7a·½¯¸QvHàžÇ=õgßNÑP•Ùdl‡c P€sóé.Öm0ïK_ öØd¶9%UÎ\®•‘Úœ…4Zjtw]pu½EŠl*S1"E›¨6ŠÞ‹ž1o¬ëî±wywÑô<ôF'‰—àÄfù À,®þâì\Önu–šÌ]µèNrí>Hšà¨F!JôûÓüE¿eÈ$.ùŸ}¹û^Ô?9"¬T½ç´´Å;b2ïê+RjU­¸¦^ÕE–ƒ/vGkv?¬5–€wŒAÀn“5ħ€?Çë8)uôþ½J ScÌÝöI"þ×b ³’µ(mqÉä —ÙÙ‰L%fÞ×Q]]H7°KùiÓæèÐãþÙd1rŸ­óúd¹kgø~1 8,psdð”GçúÆ©cçýöAÙû ædÿfÕ|ƒíyá/6ØNúy”.hõŽQ^Åç­s+ž ª|¡P·”Â.ÀQù¦¤¢ö užß…Ÿì |^/˜l6;:c’p»Eá?,9;Ømƒåcó{^§þݮɳxÌå- ÒkÊ,- ".#Bn°§áu–dø¹9Ì™ÆV€Šl•óo4Òú ïþišËæÄ¡,ip]MÐýÝ™¦9¼D@~â“Pa Ó›p”Ü-˜wJj]•{ë¬ùnÝj5D›Fë?3šúÔKÇZ.Ê×në¸eº]§Ð=Ûõ=¶Ù èøìغŽ33ì‡ËĆ«-hΪ»¡ }€” ¬‘ " ¡¨ ‘¤‚’ˆ‘ *„Ne’ªP Ò>sdMw?Cýöüc/[6Œ|ûÕ{¶H[ˆí& zû®dÊ.ø”Ìy-â+‰ŠÙ>¯˜µ$ñÙµ†•?¸‘˜_|dñØ 0 @÷ ½KÉ1‚4JÜ7ÚDv0Uwît ˜0‘O-PDÔV»Ñ{k ¦Î‡=„àapËŸŸÃ«–«¶×‡;-ªgŒ®ïÿ7T{AXvãnñ2·0=¼×ö}+ñ͘øjxÕÀ´¤Ì`Ïv©àñ—˜7·p õÜÝ]px=t»<ç#,÷«%ëÓ+¯Žm‹7]ü{óÍ/ÓÜ°Ú âA kÇ—í™´r/[§@½º»{HuŒ‹IÙY­#àáÛÊÃc!Ž  |d’gcgÅ”Ÿ×êðN—\Í+· ÒËz²’¤TPCù³¤NKîMÙÆ@ÎÙ_‹ Æ§ké’\SÞ}Ê<Ëïxà“ "Ìå=.«6/«ºþgv—dðøIK[ë•ʵ2î¯3MQ^¤¼šê –Â69‹ÈÔ’ž³M*„hˆ¿.ŠOûG·òlÔô¹U÷=|o$qH–´ÙÝ?‹˜lÒèN¯ìèÌ×\¯%ìß‹)\ææð…ü1 ƒÿvê_­Ñ7;CçùÚN³ÖÌã%^½çÍK↧µñ‹¤÷ÏjCg©€C`œ ø¨B„‡õIÐ,$#ÐO~üÂún'õí²KYÒK¬#Å›»wäk9]ùzËnÖäÔqK”LïηØ8¦®E˳éÄC,g¹ð‚‡€CrX‹}i™+V æ¢ÆÅ- n·mYceá¹@Cfªp{úQ¨°’Ö¼àóÖiÂ6ü÷8 NÙjóÌxS¹¤Ë%(LuLï…]¼#ëï ‹Z‘Ê©¤‚pÜlƒl[ŸÉ4ÿ¬¿b-ýFy>Z{ž+6¡}‘lË»NÖ¬íYó¬ZÒ/,òu¾Àè)}8µƒÂKè@:éTf¹n\0= eªýíkëë†á>KŒ“m &ž2ó—ûdè÷ÈïïðnŠ:¬©¦1PŠ$8Ï9t(ÝuxW¯ç*ÃB³ºçŒô9jÚäFçè&J-}º <ƒ×)-RbØãòÏcÐtY£{Sš\Wf{ãœdAÈܱy˜t»1H±PÕx¾ºªu1 ›ýàí§òÏÏe¤QîKºTÁkä5ùHó†²,—Ÿ PÌw]î¡VÕ…zÎ|Cl[÷yº€!` ©˜­áºÛ6v„¡>˜P(˜Q71î†`%œÒ'e,°û™´+ùFÖ^oO¨Ùûæ»c¬úÑoׯÁ|ÔõÔgÿ·öØÆ€Ì’«ÆìÖá}Ì­—oŸ:&+eÃ|yïáàôðû¢y]†Ð—¬”ý@€™FÐ:äÒ|’ýfÅ€E/¯½IU% Fè™4ß7ã£Wž©x¥ZÇUm+m·/«ïszð €þ‘ÔæíËcùHT0p~yÞSšÂÏÐv’¦ÝCþ§”ü(ëStîÏ“˜ÿs'"ñacÑ£¢Á•úµÿdd3µ«k<éM'¥ú@Û² Õß΢Ÿq½Áíg;€fWÙ:/õ´8HƒÒþ#™–Ö…´¾%9{_†­Î–VÆKBæÊßjO«úÿvâ”’=yÕû»O²¾T žQa4…ÎÅÇxS&Á¢Ïtñ*Å3éó“ž]ñ_€ 6†ÅQýÖô»tõ¼ÜNâ^ô TÙg³¥çJ¥|d¹Ó_[/c¼T=Ízè† ‡w-ò8 ½Ï=¾ñ‹«Ÿòq6îû9ƒ¥¬‚O9—«¸ýÅp÷€ÂÁ?e†À…ùN‹¿±éËþù,sÕ×%ä  ¤§è狦«?„üp$±‚ÆèUÒ67– €ƒ·¹å´mñ7U8§5NFÈ™”ûšX%ä ¸ÞH'•&m¥ß· ¾6ku ùRü¤»ÅV÷/¡Éæù}õ~|o·GÙ„Hz]<ܦ׺u¯æssÙςʳlá’ ^nC#¹$S¤†åI¼¦ÄåÁgxê«¢òò›Ô^›ïGvX€@ÓeØfnw;eÿ÷qòÒ/îçUí&yUêþ­~¼³•õÛðù‚ŒòÎÿërÖÈá † WömׯLÒ„=´=Ý\pCðÅÞ'%/ÉÄËáÛŽBͧJœ!`£xÙ¹¼Ua‡àKç\| )¶nëè,G­9 î°DîR°­¿· [{´—º¡¥jGØ~  2Ή@Žißñg×­}ÙîóåâQL»ÚZ&ˆÙ5? .¼.& „µBVŽ…‘²0Û·÷°kÙ}aqO奴ý@¸C‰‹VÍùæWrãb¡i‹ë R©ÉŒKMâ( 4  "o+Ãü—‘Ú13¥Fá\È'q“· %X¯ËbAáþ…Å¡*¿)JCï© Z©ÎíågÈ ¯"¢ç°|ÁÏöíÿˆ42o2roÏ7{Ì‘kzÞ_r™ô¨1n° Ø ýöÿÑèlqßýØq€® ” ²…woç²™|Ëã°üߦ7~bIÂBÑ_cHêL¤n{5ÚÏ¥gWëÞà)¿6|—S¡‡ÅV>`*—dv7H^û‹>ùeàDöùôv4”‰²ì.Ù¯|–qk™k5œÉ÷ïÔ©Ü”q¹zn_¾³y¶wGq­lùdõ¾C·{1œrŽé¾o"ü6¾¿_/1ŠÞZëkõMmwaíå°ØÜ/Òƒéaæ©“L¾†M™æ]|oh§Xzjß¶¦Y¤ý××-óÇÅîó_y/vE¬Ð—|nK '÷âÌèƒÉãÁ9¯¢@È,‚í:4qKsQí_î×Ç)30—_Ñ´gàjRú˜­‹CøÐ=û¶«0N|¶ }×ã:Àÿ{fŸmÖg·Ãú!ÎÓRm÷4‹ÞæO- >œŠ=ۧͨ‡ü-Maý^cøIŸŽ££–ìºË”²¿7ç£êè2ðÉ:”ž>,¾aO…MŽ•Á·±ÙqåöÕ<×͉ќ9ÿ£;¿%¦;ŸuËåúþØ™du‚wdvßš„ +p=.¿_½_»€znqÔ­ká©{_Dq ¶-Ó¼ßfµ.·OÀoÑé!å뻪².Fâ :Ôñk}¯…R?¨j¯Gç&ÓPþ£ÛëoóY¦*æÙ|ÎQ=˜N„¿Ño†ÆýM©]ñ±Öyi“°¬÷™÷þUÚa {’¢\·5ž#TE¥_Äî°—|ü´¹5Aï¡€~·uŠyÜ’¶»¨üz* ž-_â–ñLË%¥¿¦èÚœ² f\†¶¥?ÎÓÍkJ_ŸRQ 7è̉ϤsÿW*zR75¿‡õ’$=”‹ª 9é ‘ù®.M†y—HÔ}m}î‰Ø5É$.h_GϳôTy8„¼ÊÂDÍ’É|SUwMì9üåé#—ÖW`Þ€;$òŒÂ#µhƒ»¯P¦ŽÝÔØ¼8vZz Î!‰B(olU?)½^'¥4ãùÉ`:æÔ¶WÙþýv)Ûß ÀõÌBîBÍCÕø¤¦Ãý3"e‡Ã„ªÌñcýh Ÿ+…„¦Ç4 •쌂Et!Ò6ç›QÔT•Å ôÄó>€· IJsh]áŽ;zŒM¯ÚP´Œ tÆeLR‡IpF…ßæÁ]´¯ŽÑ›°òÚÄCæ†ø‡i¨†ÓþÕ{¶¾…vþÔ¢ñ(°ÉÔúõR<£Ø»þåyx»¯]Á/ýa€ †G¾ñW¹ü޲³ù~¸8ì:_¿Î3+¨à¥sÌ“ÃKk1- ì£öÅ’µ J“›¦­EH[¤—2D¨©îM+6°³M Ó¥ð½^407Ä굊t°5S“ýâK Òr­ +{^m’*-iCÛ“b, O°{)€B_œ)°@áwš¯<Òµ«¬‡"‘C§2‚@“ô¦zÊš$RÞãǶrV/xpzkAÑëI>…«zú$­'sjæÈ¤Ï¯O:ëåžwÉ㉣D󸤳ÕÞ"HކäGt$É@YãœÈv _ÀIÊ=„Ëô¹Ólî{–Ô ¿ï½|Û^•š6<ÜêbS½n‘gݶõ‘yÂy~[%çø¿I unÉ~ˆ(aXÈvJ~[H0¬Ihgî-uùëGÂÿêùrcû_nsj…Hç½Þ¤ýR¬ª=ªŠ-U  ¥Þd²O'•µ×Á~ö°‰‚°vEÉ~þÐH&™•=é¾ÚÑ — ª¶˜»~ÒÎÈÁ±´ƒ€}Sta†ëVe*¸W*¡“™ÃH³Å6òX4„uéi)ý²®^Â;Òìcöíœ _9i5YN+Ò€ $†üùO´ñ õ$ÞüîO®=Û[ÇÿÏÙ¡¾Þ¦lTyà­5ß1:ñGÊ›‡cŸ½þ—IòPÙ~@(ã„;– ¯éÄçéìS¨y z]éz¦ø—ÿ¯Òht½$%$>&“JóE•{½t_SÊ*ÖÝ,\Ö+OÛdæl¤V½êBlŽà<~6…kºd›°Nø¢ï+ÏŒI›0ªN›}OË'Ʋ{ÒÓe`ÏGEWûͨ¬œwÈ+þBÂmΗ«Åê6¿a¢\â?ˆEŽ7Ê?±_.3«¡ãrsË$Îó´Õù™º ?ÀB$@fQ©¤ýïg]ãþ ð #I©›ßì"•H¶ØJb? áø‚OkïlûZ+ZEÿ­O-åVµcÃh¹¤•M×v,lÐŽ B¿u‘J‚ú¿÷ÊE†Ïmë8ß$³gùÊO¿§VæÆØüŽ`G[£ñOÿMqb™_4´Gxy[¿30r¥Ëmnác&Æ *Ä1Vk ~䀹` @­J÷Ås,Àéyg`h‚اFÑq½õëà…"V4Ë›Z¹Áù*ãtÉyJÚ£¢0ä°ô,þ©Ç j²=¾»£–«3 ©WG`õö“–±ˆå"§Ÿp=çŒ-ÕGU/Ǭ[ë½VS¶÷,RäW‘Clßq<Èoˆ6«ÓëŒ#5`z {o >¶ñ5Ì‚å]ià‚@¶P“BXŸõqûl äÒ…C«šG–PÙ¦¸{ok>ùK#ç÷ØðäÁ™´Y;Ê“UåêÕ¿@xy(˜:ƒˆ½¬@U<ÊúÖ¾;ì„Ð zô dëÞ×k«û Ìs²‹ÙD“âøá¾´;œ.‚Jפþnz{ŒöÞ¬»GîÖÕ£e$a>7¢œÏ#õ`… ¼à‰ì %ÖÇa™ìü]=“ ½›î2½e]O·q²á‡G©•7×Ùþ¿¦«Õ³|NVLg@±’…”T&’h‹²\©õlÜ;W63´ágpJJq÷Š»õœº¹L©Ž@À¡¥ ל²µ 8D´Ï¹=uºiµ°wÖb໢î $/RVz}Ù-jj/2ˆUDzNª _øžó+ÒÉ[Š™À½àúíÓIô½gïúoÜ è¿­ð¾‡¿`ÌÞS¾ö_ÅîTq@%àå-††ýÏqWêŸYípr¼E/³Óœ#rè¢h¡~Qã;â\D‘¹ó=—/:òìN}ÇQºõþGà¢O=ÇÍßBP€Å"ív}p+@:4š:™)39{já¥R²Iâ3~ ôù'fV…Q †- njqtXÍk¥ŽòÓnŸ]ÆëI·Ám$€wUgšŸT¨ÒãH %Ø‹Ò~{VPH«x«E*uà\=ý¼ÉƱ²/nwt¤NÐuC®íÌ» ê SPðZ¼¬rýEx>ë>#ÀÅSg5˜¶€5™ôŽí’×Ú·êG–Ycƒf]=ûüÇ¿ŠA"4X;KT»§UMjß@ÐÜG%©õHÕL8eBM×x+þ,U°)¬XÂÛ-ÕÙ<óÎð“ñÑB& EWµÏ êòx|{µ4…@g|ŒH|(ð¶NðÂå¼Åm÷`­šsà`+_›­*ÁHR’ý¯¬‡gŠÔ%Aè|Á­ûƒõ‡nÞúÍÇÞ@k§'Ý lð±+‰®jÀ­v;SþPÉA0b©×÷í-Òÿ5ržÃM»d¥IˆÞå‚×Jº‚(#ËcŽñì²ßÊìÛ/-ó®OtÜIµT=œOª^å Ѐáéÿtž¨S„X(×´µc•†q/+ó)Gâ­ (̓“Ξ]dxù\nÔB0°–ñ›9ÂÞ{Z=—ÉDàá´"ñŸÐ$s1JÀ;”ïçGìè­‡>:ÀÀ€$ §£Éèg!ŽIÇçÀx»ã à¸j¸ÿUö[ñÛ åÚ 1“ŒÝÜÙvYk,â#mºëªÏ ºwÕ{àmX6Ö¶äþh›ðíÓÖ°²X¥6væneÏCd„ɾ¦«˜”ˆR€ÚøÉËdóKˆ$•ÝþêgÔ+­à%¾í)ü‚>^/V~§éF’àDôò`÷”VªËF%€õºïÚ/};¿á…ä'p3)>h—3Òæ1"Î9P“ð¹P¸QS³ä@‡ÓDpWSŽË€ &yôÇlúâ !|Kªµ"H LI±é·Ð­è»¥¼ÊTÊ®?"0zkDx1Tœ>Ø$>­cTì20’ϵ1—ŸMõ€ƒàò6¼ÌÚŽÚEI²°Q l€”¿^ú\­ÆSÈÝK¬ØŠG€¾s´Ïc³ïèz— P€ E w0õ/éÙt¯˜@~PîÊmg›ã`Š«.pÈ÷|«IPP½µ8G¯ž?l¿3B¯™‹šKˆ —­Üeÿ‰É×P³–Ž:c­Žòš\Ž3wGß[FÇå¡ ˜tP pv¨!Š" c1½œÖÄÄäõU¯‡ž‘ v¦úeœ;ÅGòT•DÞ°¡0ƒ‹Žøì ”ë0?öoï‘Ñ ‡ %,"qºf ^ZuãO” o3úÔPúlxc0”,iPCóî, %;¯¡ æålOÔH.’ÕëB„›%7Aû¶^¼}»t$KË»£îýL‚ µ ù¦¡ƒÚmr,»®ƒöc#zD =ÔcÖÿÔ8£ÛZ³ó×S›ºPÀÓÂ*ÏeÀJ”‚ptòÊ^@à ‡ÓuQÚÅxWøžåc}H’‡ˆ7ÉÍ_1ר²‘ÓRod ڇꉪÕ0kä9‘œxËaX`A"æŽr>Rõ>¼m þÇQô`7_¶: U~`µ‚騨T ·Á,hTÁßã9Oƒüy¬^û.V:Ð"è¯k8™m¦— ‰üwÓY~Vj7¤–n–[9ò8e@ïtë²šËøû¿Å4÷Aó!ûè'O$¯óËîcYŽ¢I “ÜÝÃù²ÐUª8ÿ_U@o¹Un$y §ƒá¯Ò IçÐÛî7t¹ža< ×sº¡ÍÂÜ¢‹@ðŒŠ¼ {yV âꘋ³Mõ™¬WÑ ÝÜïÙ°¦Î˜\ôЭï;òzº,΃´c©°‡_M6m¾Øx4a,u¿nN Ê9#?8`Ddõ{}†#oñ.^U .tÄžû¦DT ßxßð”ƒëÑ”sÝ5óÿn(ù¿¦äiŒ¦sCS:!¤“¸µª¨§ßŒ®À¹ê樧ËÄbÙQi^ä¡ç¬{¨]ˆa GÙ´çeƯª´)l:ðnòšïjÜíjø©Pn!…çQ F"·oX’Ÿ‘-ÉJعaƒÏËÛöL•@áÂ7—ðÆ„@wü¾>EªpjŠîòî=¤õzÿëÏêvªc$žZÉ8¹¾$ö®üö? K€æõ<=co ÛZß,ÎG]ŠÊ‘Ulyä'™ ‚ìZªÒÚà>áÅ ÅÚ ˆvD§Ï«wq‚zQ:„L ZöÓ‘yØ…L³êà%ñÒ}ã§è™•4—LrÖBUyÞ€mϰk‹ù Ì/êûz•Ù‹í»ç覎Íת}“UkžlTô–Î4aœ&§ñlùÎÒ?«²aó€æö ¤CÍ?ˆŸ´gèሰ›‹÷äШ™Q¨röPÑyqÖhŸhº ›‹—e`jÞ¥´yÓ¤™dS#;¨L…Ïn昮ê•åÂD@}‰•¨"ƒ—’¨0°â²¨·šƒV©Ûò†£És'~£ ·íLØAìò0>$ÅÀ¸"þïM§tÅ­º¹õ¹Ï|á”Õ ·°ã9?RüYŽ ›‡ÿÒÈ€tu\ã¬Ps(ÎÓNÌâáuÓ»Löÿ¢äí[è5#H>þšnŒmõþø–¯æJƒ“W­„5gÜf’Yi¤ÿIú öÀí>#’ Ö{÷þÚã?°©²€(L¡ë£!ifŒ„¼=Û;™ñ¡©õÞr l@¯G¤é©ä*†¬½¥é¨Ü?˜’<ˆcÈ£o&öïÐÜ`olt)’úþtŽ˜wn§ùWÄÞÂöAUéæ5x%_N’~ßY?À(øg•ðo!€)ó\[°¸Äc·%¥VÀ–åeSÎú‘m•Ä€nŸ¦†…†q Á'úrD2éÇrèf]\í{´L©IT€ðH CJgNï}tÞo¿ˆ!@jÛW‹#æ¦aóÐw‹É£@¬q~N øðýËŸÌ®}ÏÀCe6€ˆ0wˆ$Ä>’;\ðÀI%q¿¤Ñ€•—hóM£Ï)›í°T/$ÂÄÅ •ïÌ€F1¾¶Á”[‹ˆKàƒ —è&ÕµˆìÒ]}jÛ>˜@£AŠ™|J„@)LI÷œ_×Üf¾‹€¡:SÀÍWëà«ÖÇïÁ‚•¥< N?{$¹.[÷zcjÁ\ðÞŒü@ÔÒ9”ýJÑÒÿ=t²Rw„Ð v ‚˜uÓÎÖr‚.W‹››Muù:Ué×€Û°Gú#¡ëù§¨D ßºŸ&LXý 3û®:ÈLW´]Ðûj@pë²:ø§ç`º-Ð)}QCažìÿÉ[ÒCÈŒ ãUÒé¾ Û)(²ÒÙì<¯dø"{[j €3:NcvÈ™~>Ý„Œýµ‡¬Íö×§¦®ý-3Ž‘Œ ÑVm8þ _†áx” Nˆ‚¸§UR¨ïÌÕ×# ctDpé~VdÄlLrÙ0PÜqÈüxO æ³ê]0¬X£Ò%è+FÛÚ›tŠœ ŒÛÖ3DÁ¡T´¦ Çg€$Ux•ŸóêÅ‹-÷W—ápÔkjîã¸Úfš”nŸâá³uŠ/ÀrÖǃ~Ýþ¨AX.à†-8AZî‚‹1ãD0fI é=Ï4:‚Aëè«amÑðM±g®L»UðOTð wdN‰ ‡i$¹HJi/~ýá}ÿPêLJ5âé]ê’uHf$®ðå+P( S<›ÈÃK´ =ú„ê}ÇrDg{ç)<ûý7‘8U•£¡“t sœ~c¾\Ó ´—m¸á(^b€+©-´œ¥'˯”Éë!/ºcÅì§tó½Ë 3µ‚ù]lñguÑîv5˜qCcÞÙ/šÈa8àþ;€uÖ$Íòùv`DX/P×+eÓ 4qÒ£ûëÔù‰¯êöa˜ãÝžÖz×ÏÁQÞù÷Û1oe=ßîúMÓø~óëeØm ÚŽR··|?c6¨•B³KîMAnÈ„ (ÉóRÚ£­E8´¡‘*T @Ý ›í.<Åõº‚„ÅE¾×´†þ  ô¥SEúP€HȦ@BWD•³K0ço[·ÙêK4çU¬O»®rñIsž»Ð £•š Ãݯܧ$'[ïÒñ5²¤Áyš.X²íúÿΕýŸ~U‰àŒ]âÍÈÛp`¨ºN e9’Ë*n„jÙòÙKºù ™úîÊ=Fª)K…E~ü4?dyXµ ¹DµwA9Ê"ùgæڷ=|RÁnìGf•4èKª$QÇÏcá÷2ÿËU [DÂA €‚¹ñ H=[ž :«ÄÕPŸ ‰?MΜf¯ùÛ‚¾ŽÕÜ'¬–/0-ZMºßu ³kBS<‘) E&nGå›gñ>%÷+:üúw<•7ØŠñYýAçWȈFÑEz©k-\ ­-³ÏòQÙäþü4Ü]ò]ävµüK1¹‚ÅÒBÅ1rÚõ2Ÿþï£Àhuýf“®)—žËÔ|| OÎÙ@±¡š/g˜µàªž9ŒŠ$öÕ'”›»¯DèÒÇ¢{€ ëOÆ•õ¬º°–-s¤€je?yôt*NrºÓ¶­ÎuIiþ°5Æôe›ñraiáá: üäÊͨ2>›wEXpuÍ:Å¥:ä’Òà“fÉ)b$§d8´€Q¼H¹§ëMÊo{ùàýü^ÒCÚ$Ì”S6²Qô¼®’ß<õ0þ¬Ú¶ŽÙ&ÙÄÜôAHr3û[§Ý¿<ŒßGîµ®ÀAF°ü•~í¾†Æ)¨•‹^µÍ„{ÞGÔ±f6æ3D  ªýòé§Ýa°DÇ›ò­± gSËÃ3Õÿ'•kú ®Ò{2 kQí¥¨ûRÜì3ãA¯øf_­Œc„Ä•Z2éwh¨2m•è3»úÿо˜ ×Ât?ù·çq?“ã²›†€Í‘ÈXÿòyWé—çjš“ì@º cd5ßŬÓ²(ÅùýrÐ_*ýJõØôô ùlÊûÖö·cÞë±Ù<ôvüE³ö¹¤BE^ £÷mù)Ù ý‡y:bí¯5òoó3“V,€ü2t@@!P~‰…:Q¿¹Kíîù¸OiEFhªCŠ€ déV¤®©#hžH-#  ™M´lé›[”Ìôí©­tÑ Ÿi?W[¨§ Gî”<8¯)c£ÑG©MX6Ÿ.ÙóUÓ]†DÝwñO©IÔª‘®(µvÅè1¤o¾‹¨[r0sÄ*Æ,Dä2vªJ+IìºSc÷`½%>„“B©0”¸,g¬Ÿ…ê€?Çy¾}¶Íï¼%ÖýBeãÓk¹ÚFhÒŒ¬¨ * ìÇT+üµs”ÕGs·•&ωšÙ’é*¯ùéPßèçmÓµx#m8Õ–vZç¡“¼D‰Èô€¢]š’xþçP^å8É”‡èMŠø¡×oÓèÅc›¥“%A@'4ƒÌ‰½–¼€*Ÿ.Z6?^uí8á|’N4C¶Úqè6ÐO¤Ó9—E¨Ij¶Ú‚ ³S¡äæhî¢ou¢±O¹Fɾ¤'–ábwÛ%7ãŽò|.ã”ÕR]sôÅãÔüÅ{YÎ{¥6Q¥´!;ŠFÞ9-±¼ôÒ¯Q»n‚Zjáð”Û/×Ò+@î×@S¥æÖµdzáщCK¸IË—”A•ŸÆé®íUédõq¤zév_¶tò¶õ"X ônët‹&ÆwMeK™MG\ìA LW8&X ° {¢h³Áµ;Þ¢Hìe#$Ä{B»S f!Hc†9Ù DMl©“”¯ÏÞUmç™sóÔE²Æ TW÷{ƒú¹ûzì3Ïf¹.ÉHöRGkH’¸p ÊŽWïͲ÷6vQ/^:çµ?x7Þû­)§X¼ùç¬ÕÖ?¥OÅ>³.dŠ%TåÒ\u¯UÁ c§™‘±ï8mÝ}–õxLZÅ®ÊÀ Zr©È6žÂ8[X ¼ö{Yeš_Ǩ– ±ÇKD!7dc¨‘‡túßeÆõa ‘J0[4¼‹”úå@Ës½õ*ù‰p×êÔûqʵh±8}mË™wzPn¸F²MqceM™ëjf7”íÏÉ—ƒÇï·ŸC Hø\-ÿo:ðÇ©³ºýžZ¯Ü³R]Póè’a!‰D¡!‰}ÊÎÙ×r vE‰'àCÍ—N¦‘Lóœ,.–žÑý\ú£sH¯}± ˆn±Ê"ºñQÏØ[„—õ£žý1’‹ ‘iPI>ÿ@E’9Óü¤X¶4ZtÆêQK§™š)n?šŽvùD^„ŽÈ»ß Þ"²—ö¸ì$v[”Q?G~6„I!P°ºªpÄZú`vmõEgÃ'8¤B0NÒ5}Þ»ø,gŵ’`0.‹âfû±–ÂXöÔMמí]ëÞÔÏ>o»l^‘ÜÆÅé'ÅhþZƒ;dø=ú:yüÔ×ëuþ£ù½÷ŸIÀp<…¦#=ˆUˆHaˆR4~&ÌPP5à…LÓUoòsn+ÙÎú0oè"ĵä¥Á%da6z¡‘› nñéôÈÞ=gCÚý}:¼éú¾ß’Ôñ9`zp»}ÿCcB•Ó ¶ùž}"AP—jùÊq‘é" <&;.…p#voÒPþ˜¹s¨ä”/¡i °$-ðì©—”|áîÍ;½ý »“ ÿètŠELÒx¤Ô«''TÚ3ê;é(öS§¬P‘¿ ­ èp YUTÒËåÔxUroRÖè³4t ÖÓI;úÈÌý£àì³-³y¡Ód;O†Š 9¢cÁ7`w²§M:‚ëNñ¡à(?H¹ÙÀ”OÚÛ€>4è?IxøŒÙÙzöTiAâ› “""ÚMé"OújÏ‘P×"ÊÜ º„UÑJÅ$!RŠ…+ÇCï¦6בì`3ÊgÕ6f¸•žh“›Jm¸áf©ÁÄ‹½ÒXÀB>Ô<ÊOÏ:Òâhl~—iÓèÂjŽ)åÎõÌßéGˆc®¯0§ ‹‡™ ª^'ã¦è L}^Ìì}Rš‹Œô<âw/x•ß‚×UVOÂ,3s²–žOó"±Žï'绂 š¾Õž7qª-fªöý¤Ì:sCÿ‘ézgpÿV1*´ - £2s˜!óD;i*´F |‘Ï@U:a’ä(izzuÙGÉKÍJB}$}º©Ë¾©®áõ)é+~©: ì¼ÛT¶n}O´„¦®õ"à3¯–F¹,ãÉR.Z¤a“NÅ SÔ]ÐÞÍð#ÞÈöÓФ h 7 >—°îžûh:f¦X…ƸçA¶TR5˜á}|rÏm4ô¾–?Õ¤•Ek׳çÄ$ñªø‰ ±Ýú 57‡²™[dÞWF„C¯6S㫜tÃó¹©o9ø®ÁÛªg´ß§%ÆÊœÆi¥£¨=g ªSêmˆû ã ¡së9>ò#õ{Ò™Ù&$; g¸ÛLGÃ.®er=X|f›û±¥I0Mò{…óUÐòà €g~ڞ™WØîÈ]˜G±//{¬¨*ë!É2ɲHb`.CRÐö hµ+ù)A!ÑÖt=ËHhˆ7¼Ô=¹mO²V§Üé}¿ѱŸ¥j½Å6²°z4×k•Ë,sÜBALPÓ\í›S4©„{;»A4„]¼`§5"¤Ma0õÊŠû LÙ£}àÞi:ܰIÀÄF4É€¢Çx,ü ßõZгbíÛZ€‡/:™,‚gËûˆ!ÈcU öà˜[xÃjÇ-Lt¶1>1€‰–G·¦*=ð®_ù@í q×3ÓY-õ]¢À-‰ï›#=\¤¿ô|ˆØ¶å|†€þÑm÷ÄtVÉy$‹7”€ï@¥ãê)1!ï}›Ü<Û>´³™ÅÕý>鄸¼Ò¼UYê'™§˜øS:k”Hl#Ü!Äð’i)}˜9H{JÝèÃ1Å)Ë!“‘`Ù(N¼s>/'Ûù ñÚ6àIùF'*zÄCÙñÛmWú·eê‰ö%…ÿ×Ú®Þ?Ò¸;›P§¹~‰¯Ï¶jÐ3^wæëZš ö¼£S„mD(ŸH «Ù¼áìʦ@¬f³.舘ˆ1„8 yɰœyžb¾KÖþ—Ë–õÀ[†ŽUʪZ>£ï˜nØìòœœíjÙÜÆ«:4^Æ÷{'»éÅÄ,møc¶¡vלTãÍ4N“~Ò, ߑƭÒ6ÌêeEÿîŸL!¿BN c梊VXüþ8У:»H$/#¥`q >0µæ FoE»¢À«(º•MÉ}5ì}·%GÒÄûilwLbJhˆ =µéjªãú(ì™6‘:d¼2úßàáA²°Ñ#PzXij øhö –Q¯ÀC€îßQ¸Q‹0 [úC47Ö`ô†^7/‹ûh÷V}Ð@:.QM¥þˆ{•[¥mfµ9ÎDQú?ƒ_°¥ëbÛêm&ï˜Ñ_ƒÝå•2•‡Ó÷ô½qÜO!ÖPK4]ð´6½Ëz,à—E³Uc$”ì~9$2N¤FÕQɇòâÎB,ÁÙÑ 9¬3 _-²úI uyU,í¶Þ]g5îú¶7ŒãšIˆ¤U¯³ðÎýN¹¡(Üâ› ê%Âfÿ7 ¯7í-}…¥kÞý®BàçÁïÖŽ¢7 h[$6;\ýŽM‘°¦-F3€zCn—ës>€þ/ñÖÎ G*æ­ tèjö>.}s&™¥e§®ËíÓ²›Eð§ƒjÔi%ÕLg[žYáç,êGìê®iñ+D‘qá(šM}ÿ ]ÛÝ#m¼Ë 8DhÈaQëç'nY/įn›k³X$ÇܬR±jØø¨ÓÑkU3~¬þ}=*„Ï’)Öfsš_OHAwIS“\ö ˜ÞÐåÜÑT£3Á£z’¿†9´‡ŸzŸsO¡¿»X~NaDåiL Ÿ¼ªç$¯ýSv盫§ûÒ¶×LhúÚ1Nl<ÙÐ~$÷2|µ›H Gfœ(ÐpÍ«0,±±èxó<$'b«!e@g»SHžD×!D°»d‘ÀÙÞ©ôQ²’š­ow8ûòxÆ%¹»¬.Ë ÚÆ Oy¯ŽO_IÐlOf´MFåo"*2õ*jbèù€Eÿ'¥ÏÉd¹¶ôuiَܰ\ #include #include #include #include #include using namespace Rcpp; Eigen::SparseMatrix RowMergeMatricesList( List mat_list, List mat_rownames, std::vector all_rownames ); template std::vector sort_indexes(const std::vector &v); List GraphToNeighborHelper(Eigen::SparseMatrix mat); SeuratObject/src/RcppExports.cpp0000644000176200001440000000357615116403603016442 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include #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 // GraphToNeighborHelper List GraphToNeighborHelper(Eigen::SparseMatrix mat); RcppExport SEXP _SeuratObject_GraphToNeighborHelper(SEXP matSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::traits::input_parameter< Eigen::SparseMatrix >::type mat(matSEXP); rcpp_result_gen = Rcpp::wrap(GraphToNeighborHelper(mat)); return rcpp_result_gen; END_RCPP } // RowMergeMatricesList Eigen::SparseMatrix RowMergeMatricesList(List mat_list, List mat_rownames, std::vector all_rownames); RcppExport SEXP _SeuratObject_RowMergeMatricesList(SEXP mat_listSEXP, SEXP mat_rownamesSEXP, SEXP all_rownamesSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::traits::input_parameter< List >::type mat_list(mat_listSEXP); Rcpp::traits::input_parameter< List >::type mat_rownames(mat_rownamesSEXP); Rcpp::traits::input_parameter< std::vector >::type all_rownames(all_rownamesSEXP); rcpp_result_gen = Rcpp::wrap(RowMergeMatricesList(mat_list, mat_rownames, all_rownames)); return rcpp_result_gen; END_RCPP } RcppExport SEXP isnull(SEXP); static const R_CallMethodDef CallEntries[] = { {"_SeuratObject_GraphToNeighborHelper", (DL_FUNC) &_SeuratObject_GraphToNeighborHelper, 1}, {"_SeuratObject_RowMergeMatricesList", (DL_FUNC) &_SeuratObject_RowMergeMatricesList, 3}, {"isnull", (DL_FUNC) &isnull, 1}, {NULL, NULL, 0} }; RcppExport void R_init_SeuratObject(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } SeuratObject/src/valid_pointer.c0000644000176200001440000000024715075522101016437 0ustar liggesusers#include // helper to determine if external c++ pointer is valid SEXP isnull(SEXP pointer) { return Rf_ScalarLogical(!R_ExternalPtrAddr(pointer)); } SeuratObject/src/data_manipulation.cpp0000644000176200001440000000726315075522101017636 0ustar liggesusers#include #include #include #include #include #include using namespace Rcpp; // [[Rcpp::depends(RcppEigen)]] typedef Eigen::Triplet T; template std::vector sort_indexes(const std::vector &v) { // initialize original index locations std::vector idx(v.size()); std::iota(idx.begin(), idx.end(), 0); std::stable_sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) {return v[i1] < v[i2];}); return idx; } // [[Rcpp::export(rng = false) // [[Rcpp::export(rng = false)]] List GraphToNeighborHelper(Eigen::SparseMatrix mat) { mat = mat.transpose(); //determine the number of neighbors int n = 0; for(Eigen::SparseMatrix::InnerIterator it(mat, 0); it; ++it) { n += 1; } Eigen::MatrixXd nn_idx(mat.rows(), n); Eigen::MatrixXd nn_dist(mat.rows(), n); for (int k=0; k row_idx; std::vector row_dist; row_idx.reserve(n); row_dist.reserve(n); for (Eigen::SparseMatrix::InnerIterator it(mat,k); it; ++it) { if (n_k > (n-1)) { Rcpp::stop("Not all cells have an equal number of neighbors."); } row_idx.push_back(it.row() + 1); row_dist.push_back(it.value()); n_k += 1; } if (n_k != n) { Rcpp::Rcout << n << ":::" << n_k << std::endl; Rcpp::stop("Not all cells have an equal number of neighbors."); } //order the idx based on dist std::vector idx_order = sort_indexes(row_dist); for(int i = 0; i < n; ++i) { nn_idx(k, i) = row_idx[idx_order[i]]; nn_dist(k, i) = row_dist[idx_order[i]]; } } List neighbors = List::create(nn_idx, nn_dist); return(neighbors); } // [[Rcpp::export(rng = false)]] Eigen::SparseMatrix RowMergeMatricesList( List mat_list, List mat_rownames, std::vector all_rownames ) { // Convert Rcpp lists to c++ vectors std::vector> mat_vec; mat_vec.reserve(mat_list.size()); std::vector> rownames_vec; rownames_vec.reserve(mat_rownames.size()); std::vector> map_vec; map_vec.reserve(mat_list.size()); int num_cols = 0; int num_nZero = 0; // offsets keep track of which column to add in to std::vector offsets; for (unsigned int i = 0; i < mat_list.size(); i++) { mat_vec.emplace_back(Rcpp::as>(mat_list.at(i))); rownames_vec.push_back(mat_rownames[i]); // Set up hash maps for rowname based lookup std::unordered_map mat_map; for (unsigned int j = 0; j < rownames_vec[i].size(); j++) { mat_map[rownames_vec[i][j]] = j; } map_vec.emplace_back(mat_map); offsets.push_back(num_cols); num_cols += mat_vec[i].cols(); num_nZero += mat_vec[i].nonZeros(); } // set up tripletList for new matrix creation std::vector tripletList; int num_rows = all_rownames.size(); tripletList.reserve(num_nZero); // loop over all rows and add nonzero entries to tripletList for(int i = 0; i < num_rows; i++) { std::string key = all_rownames[i]; for(int j = 0; j < mat_vec.size(); j++) { if (map_vec[j].count(key)) { for(Eigen::SparseMatrix::InnerIterator it1(mat_vec[j], map_vec[j][key]); it1; ++it1){ tripletList.emplace_back(i, it1.col() + offsets[j], it1.value()); } } } } Eigen::SparseMatrix combined_mat(num_rows, num_cols); combined_mat.setFromTriplets(tripletList.begin(), tripletList.end()); return combined_mat; } SeuratObject/NAMESPACE0000644000176200001440000004114115116320014014055 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("$",Assay) S3method("$",Assay5) S3method("$",FOV) S3method("$",JackStrawData) S3method("$",Seurat) S3method("$",SeuratCommand) S3method("$",StdAssay) S3method("$<-",Assay) S3method("$<-",Assay5) S3method("$<-",Seurat) S3method("$<-",StdAssay) S3method("DefaultAssay<-",Assay) S3method("DefaultAssay<-",Assay5) S3method("DefaultAssay<-",DimReduc) S3method("DefaultAssay<-",Graph) S3method("DefaultAssay<-",Seurat) S3method("DefaultAssay<-",SpatialImage) S3method("DefaultAssay<-",StdAssay) S3method("DefaultBoundary<-",FOV) S3method("DefaultFOV<-",Seurat) S3method("DefaultLayer<-",Assay5) S3method("DefaultLayer<-",StdAssay) S3method("Idents<-",Seurat) S3method("Index<-",Neighbor) S3method("JS<-",DimReduc) S3method("JS<-",JackStrawData) S3method("Key<-",Assay) S3method("Key<-",Assay5) S3method("Key<-",DimReduc) S3method("Key<-",KeyMixin) S3method("Key<-",SpatialImage) S3method("LayerData<-",Assay) S3method("LayerData<-",Assay5) S3method("LayerData<-",Seurat) S3method("LayerData<-",StdAssay) S3method("Loadings<-",DimReduc) S3method("Misc<-",Assay) S3method("Misc<-",Assay5) S3method("Misc<-",DimReduc) S3method("Misc<-",Seurat) S3method("Misc<-",StdAssay) S3method("Project<-",Seurat) S3method("Tool<-",Seurat) S3method("VariableFeatures<-",Assay) S3method("VariableFeatures<-",Assay5) S3method("VariableFeatures<-",Seurat) S3method("VariableFeatures<-",StdAssay) S3method("[",Assay) S3method("[",Assay5) S3method("[",DimReduc) S3method("[",FOV) S3method("[",Seurat) S3method("[",SeuratCommand) S3method("[",SpatialImage) S3method("[",StdAssay) S3method("[[",Assay) S3method("[[",Assay5) S3method("[[",DimReduc) S3method("[[",FOV) S3method("[[",Seurat) S3method("[[",StdAssay) S3method("dimnames<-",Assay) S3method("dimnames<-",Assay5) S3method("dimnames<-",Seurat) S3method("dimnames<-",StdAssay) S3method("levels<-",Seurat) S3method(.AssayClass,Assay5T) S3method(.AssayClass,StdAssay) S3method(.AssayClass,default) S3method(.CalcN,Assay) S3method(.CalcN,StdAssay) S3method(.CalcN,default) S3method(.ClassPkg,DelayedArray) S3method(.ClassPkg,R6) S3method(.ClassPkg,R6ClassGenerator) S3method(.ClassPkg,default) S3method(.CreateStdAssay,Matrix) S3method(.CreateStdAssay,default) S3method(.CreateStdAssay,list) S3method(.CreateStdAssay,matrix) S3method(.DiskLoad,"10xMatrixH5") S3method(.DiskLoad,AnnDataMatrixH5) S3method(.DiskLoad,DelayedMatrix) S3method(.DiskLoad,H5ADMatrix) S3method(.DiskLoad,HDF5Matrix) S3method(.DiskLoad,IterableMatrix) S3method(.DiskLoad,MatrixDir) S3method(.DiskLoad,MatrixH5) S3method(.DiskLoad,TileDBMatrix) S3method(.DiskLoad,default) S3method(.DollarNames,Assay) S3method(.DollarNames,Assay5) S3method(.DollarNames,FOV) S3method(.DollarNames,JackStrawData) S3method(.DollarNames,Seurat) S3method(.DollarNames,SeuratCommand) S3method(.DollarNames,StdAssay) S3method(.FilePath,DelayedMatrix) S3method(.FilePath,IterableMatrix) S3method(.FilePath,default) S3method(.MARGIN,Assay5T) S3method(.MARGIN,CsparseMatrix) S3method(.MARGIN,RsparseMatrix) S3method(.MARGIN,default) S3method(.MARGIN,spam) S3method(.SparseSlots,CsparseMatrix) S3method(.SparseSlots,RsparseMatrix) S3method(.SparseSlots,spam) S3method(AddMetaData,Assay) S3method(AddMetaData,Assay5) S3method(AddMetaData,Seurat) S3method(AddMetaData,StdAssay) S3method(Assays,Seurat) S3method(Boundaries,FOV) S3method(CastAssay,Assay5) S3method(CastAssay,Seurat) S3method(CastAssay,StdAssay) S3method(Cells,Assay5) S3method(Cells,Centroids) S3method(Cells,DimReduc) S3method(Cells,FOV) S3method(Cells,Graph) S3method(Cells,Neighbor) S3method(Cells,Segmentation) S3method(Cells,Seurat) S3method(Cells,SpatialImage) S3method(Cells,StdAssay) S3method(Cells,default) S3method(CheckMatrix,dMatrix) S3method(CheckMatrix,default) S3method(CheckMatrix,lMatrix) S3method(Command,Seurat) S3method(CreateCentroids,Centroids) S3method(CreateCentroids,default) S3method(CreateFOV,Centroids) S3method(CreateFOV,Segmentation) S3method(CreateFOV,data.frame) S3method(CreateFOV,list) S3method(CreateMolecules,"NULL") S3method(CreateMolecules,Molecules) S3method(CreateMolecules,data.frame) S3method(CreateSegmentation,Segmentation) S3method(CreateSegmentation,data.frame) S3method(CreateSegmentation,sf) S3method(CreateSeuratObject,Assay) S3method(CreateSeuratObject,Assay5) S3method(CreateSeuratObject,StdAssay) S3method(CreateSeuratObject,default) S3method(Crop,Centroids) S3method(Crop,FOV) S3method(Crop,Molecules) S3method(Crop,Segmentation) S3method(DefaultAssay,Assay) S3method(DefaultAssay,Assay5) S3method(DefaultAssay,DimReduc) S3method(DefaultAssay,Graph) S3method(DefaultAssay,Seurat) S3method(DefaultAssay,SeuratCommand) S3method(DefaultAssay,SpatialImage) S3method(DefaultAssay,StdAssay) S3method(DefaultBoundary,FOV) S3method(DefaultFOV,Seurat) S3method(DefaultLayer,Assay) S3method(DefaultLayer,Assay5) S3method(DefaultLayer,StdAssay) S3method(Distances,Neighbor) S3method(Embeddings,DimReduc) S3method(Embeddings,Seurat) S3method(Features,Assay) S3method(Features,Assay5) S3method(Features,DimReduc) S3method(Features,FOV) S3method(Features,Molecules) S3method(Features,Seurat) S3method(Features,StdAssay) S3method(FetchData,Assay) S3method(FetchData,Assay5) S3method(FetchData,DimReduc) S3method(FetchData,FOV) S3method(FetchData,Molecules) S3method(FetchData,Seurat) S3method(FetchData,StdAssay) S3method(GetAssayData,Assay) S3method(GetAssayData,Seurat) S3method(GetAssayData,StdAssay) S3method(GetImage,Seurat) S3method(GetImage,SpatialImage) S3method(GetTissueCoordinates,Centroids) S3method(GetTissueCoordinates,FOV) S3method(GetTissueCoordinates,Molecules) S3method(GetTissueCoordinates,Segmentation) S3method(GetTissueCoordinates,Seurat) S3method(GetTissueCoordinates,SpatialImage) S3method(HVFInfo,Assay) S3method(HVFInfo,Assay5) S3method(HVFInfo,Seurat) S3method(HVFInfo,StdAssay) S3method(Idents,Seurat) S3method(Index,Neighbor) S3method(Indices,Neighbor) S3method(IsGlobal,DimReduc) S3method(IsGlobal,SpatialImage) S3method(IsGlobal,default) S3method(IsMatrixEmpty,default) S3method(JS,DimReduc) S3method(JS,JackStrawData) S3method(JoinLayers,Assay5) S3method(JoinLayers,Seurat) S3method(JoinLayers,StdAssay) S3method(Key,"NULL") S3method(Key,Assay) S3method(Key,Assay5) S3method(Key,DimReduc) S3method(Key,KeyMixin) S3method(Key,Seurat) S3method(Key,SpatialImage) S3method(Key,character) S3method(Keys,FOV) S3method(Keys,Seurat) S3method(LayerData,Assay) S3method(LayerData,Assay5) S3method(LayerData,Seurat) S3method(LayerData,StdAssay) S3method(Layers,Assay) S3method(Layers,Assay5) S3method(Layers,Seurat) S3method(Layers,StdAssay) S3method(Loadings,DimReduc) S3method(Loadings,Seurat) S3method(MatchCells,"NULL") S3method(MatchCells,character) S3method(MatchCells,numeric) S3method(Misc,Assay) S3method(Misc,Assay5) S3method(Misc,DimReduc) S3method(Misc,Seurat) S3method(Misc,StdAssay) S3method(Molecules,FOV) S3method(Project,Seurat) S3method(Radius,Centroids) S3method(Radius,SpatialImage) S3method(RenameCells,Assay) S3method(RenameCells,Assay5) S3method(RenameCells,Centroids) S3method(RenameCells,DimReduc) S3method(RenameCells,FOV) S3method(RenameCells,Neighbor) S3method(RenameCells,Segmentation) S3method(RenameCells,Seurat) S3method(RenameCells,SpatialImage) S3method(RenameCells,StdAssay) S3method(RenameIdents,Seurat) S3method(ReorderIdent,Seurat) S3method(S4ToList,default) S3method(S4ToList,list) S3method(SVFInfo,Assay) S3method(SVFInfo,Assay5) S3method(SVFInfo,Seurat) S3method(SVFInfo,StdAssay) S3method(SetAssayData,Assay) S3method(SetAssayData,Seurat) S3method(SetAssayData,StdAssay) S3method(SetIdent,Seurat) S3method(Simplify,Molecules) S3method(Simplify,Spatial) S3method(SpatiallyVariableFeatures,Assay) S3method(SpatiallyVariableFeatures,Assay5) S3method(SpatiallyVariableFeatures,Seurat) S3method(SpatiallyVariableFeatures,StdAssay) S3method(StashIdent,Seurat) S3method(Stdev,DimReduc) S3method(Stdev,Seurat) S3method(StitchMatrix,IterableMatrix) S3method(StitchMatrix,default) S3method(StitchMatrix,dgCMatrix) S3method(StitchMatrix,matrix) S3method(Theta,Centroids) S3method(Tool,Seurat) S3method(VariableFeatures,Assay) S3method(VariableFeatures,Assay5) S3method(VariableFeatures,Seurat) S3method(VariableFeatures,StdAssay) S3method(Version,Seurat) S3method(WhichCells,Assay) S3method(WhichCells,Assay5) S3method(WhichCells,Seurat) S3method(WhichCells,StdAssay) S3method(aggregate,FOV) S3method(aggregate,Molecules) S3method(as.Centroids,Segmentation) S3method(as.Graph,Matrix) S3method(as.Graph,Neighbor) S3method(as.Graph,matrix) S3method(as.Neighbor,Graph) S3method(as.Segmentation,Centroids) S3method(as.list,SeuratCommand) S3method(as.logical,JackStrawData) S3method(as.matrix,LogMap) S3method(as.sparse,Matrix) S3method(as.sparse,data.frame) S3method(as.sparse,matrix) S3method(as.sparse,ngCMatrix) S3method(dim,Assay) S3method(dim,Assay5) S3method(dim,DimReduc) S3method(dim,FOV) S3method(dim,Neighbor) S3method(dim,Seurat) S3method(dim,SpatialImage) S3method(dim,StdAssay) S3method(dimnames,Assay) S3method(dimnames,Assay5) S3method(dimnames,DimReduc) S3method(dimnames,Seurat) S3method(dimnames,StdAssay) S3method(droplevels,LogMap) S3method(droplevels,Seurat) S3method(head,Assay) S3method(head,Assay5) S3method(head,Seurat) S3method(head,StdAssay) S3method(intersect,LogMap) S3method(is.finite,Centroids) S3method(is.infinite,Centroids) S3method(labels,LogMap) S3method(length,Centroids) S3method(length,DimReduc) S3method(length,FOV) S3method(lengths,Centroids) S3method(lengths,Segmentation) S3method(levels,Seurat) S3method(merge,Assay) S3method(merge,Assay5) S3method(merge,DimReduc) S3method(merge,Seurat) S3method(merge,StdAssay) S3method(names,DimReduc) S3method(names,FOV) S3method(names,Seurat) S3method(print,DimReduc) S3method(split,Assay) S3method(split,Assay5) S3method(split,Seurat) S3method(split,StdAssay) S3method(subset,Assay) S3method(subset,Assay5) S3method(subset,Centroids) S3method(subset,DimReduc) S3method(subset,FOV) S3method(subset,Molecules) S3method(subset,Segmentation) S3method(subset,Seurat) S3method(subset,SpatialImage) S3method(subset,StdAssay) S3method(tail,Assay) S3method(tail,Assay5) S3method(tail,Seurat) S3method(tail,StdAssay) S3method(upgrade,seurat) export("%!NA%") export("%!na%") export("%NA%") export("%iff%") export("%na%") export("%||%") export("DefaultAssay<-") export("DefaultBoundary<-") export("DefaultFOV<-") export("DefaultLayer<-") export("Idents<-") export("Index<-") export("JS<-") export("Key<-") export("LayerData<-") export("Loadings<-") export("Misc<-") export("Project<-") export("Tool<-") export("VariableFeatures<-") export(.AssayClass) export(.BPMatrixMode) export(.CalcN) export(.CheckFmargin) export(.ClassPkg) export(.Collections) export(.Contains) export(.CreateStdAssay) export(.DefaultFOV) export(.Deprecate) export(.DiskLoad) export(.FileMove) export(.FilePath) export(.FilterObjects) export(.FindObject) export(.GetMethod) export(.IsFutureSeurat) export(.KeyPattern) export(.MARGIN) export(.PropagateList) export(.RandomKey) export(.SparseSlots) export(.Subobjects) export(AddMetaData) export(Assays) export(AttachDeps) export(Boundaries) export(CastAssay) export(Cells) export(CellsByIdentities) export(CheckDots) export(CheckFeaturesNames) export(CheckGC) export(CheckLayersName) export(CheckMatrix) export(ClassKey) export(Command) export(CreateAssay5Object) export(CreateAssayObject) export(CreateCentroids) export(CreateDimReducObject) export(CreateFOV) export(CreateMolecules) export(CreateSegmentation) export(CreateSeuratObject) export(Crop) export(DefaultAssay) export(DefaultBoundary) export(DefaultDimReduc) export(DefaultFOV) export(DefaultLayer) export(Degrees) export(Distances) export(Embeddings) export(EmptyDF) export(EmptyMatrix) export(ExtractField) export(Features) export(FetchData) export(FilterObjects) export(GetAssayData) export(GetImage) export(GetTissueCoordinates) export(Graphs) export(HVFInfo) export(Idents) export(Images) export(Index) export(Indices) export(IsGlobal) export(IsMatrixEmpty) export(IsNamedList) export(IsS4List) export(IsSparse) export(JS) export(JoinLayers) export(Key) export(Keys) export(LayerData) export(Layers) export(ListToS4) export(LoadSeuratRds) export(Loadings) export(LogMap) export(LogSeuratCommand) export(MatchCells) export(Misc) export(Molecules) export(Neighbors) export(Overlay) export(PackageCheck) export(PolyVtx) export(Project) export(Radians) export(Radius) export(RandomName) export(Reductions) export(RegisterSparseMatrix) export(RenameAssays) export(RenameCells) export(RenameIdents) export(ReorderIdent) export(RowMergeSparseMatrices) export(S4ToList) export(SVFInfo) export(SaveSeuratRds) export(SetAssayData) export(SetIdent) export(Simplify) export(SparseEmptyMatrix) export(SpatiallyVariableFeatures) export(StashIdent) export(Stdev) export(StitchMatrix) export(Theta) export(Tool) export(UpdateSeuratObject) export(UpdateSlots) export(VariableFeatures) export(Version) export(WhichCells) export(as.Centroids) export(as.Graph) export(as.Neighbor) export(as.Segmentation) export(as.Seurat) export(as.sparse) export(handlers) export(intersect) export(plan) export(t) export(with_progress) exportClasses(Assay) exportClasses(Assay5) exportClasses(DimReduc) exportClasses(FOV) exportClasses(Graph) exportClasses(JackStrawData) exportClasses(KeyMixin) exportClasses(LogMap) exportClasses(Neighbor) exportClasses(Seurat) exportClasses(SeuratCommand) exportClasses(SpatialImage) exportClasses(StdAssay) exportMethods("[[") exportMethods("[[<-") exportMethods(Overlay) exportMethods(colMeans) exportMethods(colSums) exportMethods(rowMeans) exportMethods(rowSums) exportMethods(show) importClassesFrom(Matrix,CsparseMatrix) importClassesFrom(Matrix,Matrix) importClassesFrom(Matrix,RsparseMatrix) importClassesFrom(Matrix,compMatrix) importClassesFrom(Matrix,dMatrix) importClassesFrom(Matrix,dgCMatrix) importClassesFrom(Matrix,dsparseMatrix) importClassesFrom(Matrix,generalMatrix) importClassesFrom(Matrix,sparseMatrix) importClassesFrom(sp,CRS) importClassesFrom(sp,Spatial) importClassesFrom(sp,SpatialPoints) importClassesFrom(sp,SpatialPolygons) importClassesFrom(spam,spam) importFrom(Matrix,Matrix) importFrom(Matrix,colMeans) importFrom(Matrix,colSums) importFrom(Matrix,nnzero) importFrom(Matrix,rowMeans) importFrom(Matrix,rowSums) importFrom(Matrix,t) importFrom(Rcpp,evalCpp) importFrom(future,plan) importFrom(future.apply,future_lapply) importFrom(future.apply,future_mapply) importFrom(generics,intersect) importFrom(grDevices,as.raster) importFrom(grid,nullGrob) importFrom(lifecycle,deprecate_soft) importFrom(lifecycle,deprecate_stop) importFrom(lifecycle,deprecate_warn) importFrom(lifecycle,deprecated) importFrom(lifecycle,is_present) importFrom(methods,"slot<-") importFrom(methods,.hasSlot) importFrom(methods,as) importFrom(methods,callNextMethod) importFrom(methods,getClass) importFrom(methods,getClassDef) importFrom(methods,getClasses) importFrom(methods,initialize) importFrom(methods,is) importFrom(methods,isClass) importFrom(methods,isClassUnion) importFrom(methods,isGeneric) importFrom(methods,isXS3Class) importFrom(methods,new) importFrom(methods,selectMethod) importFrom(methods,setAs) importFrom(methods,setClass) importFrom(methods,setClassUnion) importFrom(methods,setGeneric) importFrom(methods,setMethod) importFrom(methods,setOldClass) importFrom(methods,setValidity) importFrom(methods,show) importFrom(methods,slot) importFrom(methods,slotNames) importFrom(methods,validObject) importFrom(progressr,handlers) importFrom(progressr,progressor) importFrom(progressr,with_progress) importFrom(rlang,"%||%") importFrom(rlang,abort) importFrom(rlang,arg_match) importFrom(rlang,arg_match0) importFrom(rlang,caller_env) importFrom(rlang,check_installed) importFrom(rlang,enquo) importFrom(rlang,eval_tidy) importFrom(rlang,have_name) importFrom(rlang,inform) importFrom(rlang,is_bare_character) importFrom(rlang,is_bare_integerish) importFrom(rlang,is_bare_list) importFrom(rlang,is_bare_numeric) importFrom(rlang,is_missing) importFrom(rlang,is_na) importFrom(rlang,is_named) importFrom(rlang,is_null) importFrom(rlang,is_quosure) importFrom(rlang,is_scalar_character) importFrom(rlang,missing_arg) importFrom(rlang,ns_env_name) importFrom(rlang,quo_get_env) importFrom(rlang,quo_get_expr) importFrom(rlang,warn) importFrom(sp,CRS) importFrom(sp,Polygon) importFrom(sp,Polygons) importFrom(sp,SpatialPoints) importFrom(sp,SpatialPolygons) importFrom(sp,bbox) importFrom(sp,coordinates) importFrom(sp,over) importFrom(stats,aggregate) importFrom(stats,median) importFrom(stats,na.omit) importFrom(stats,setNames) importFrom(tools,file_path_sans_ext) importFrom(utils,.DollarNames) importFrom(utils,adist) importFrom(utils,argsAnywhere) importFrom(utils,getS3method) importFrom(utils,head) importFrom(utils,isS3method) importFrom(utils,isS3stdGeneric) importFrom(utils,methods) importFrom(utils,modifyList) importFrom(utils,packageVersion) importFrom(utils,tail) importFrom(utils,upgrade) useDynLib(SeuratObject) SeuratObject/LICENSE0000644000176200001440000000006215075522101013645 0ustar liggesusersYEAR: 2021 COPYRIGHT HOLDER: SeuratObject authors SeuratObject/NEWS.md0000644000176200001440000002042715116566601013756 0ustar liggesusers# SeuratObject 5.3.0 ## Changes: - Update `subset.Seurat` to no longer call `droplevels` on the input's cell-level `meta.data` slot; update `subset.Assay` to no longer call `droplevels` on the input's feature-level `meta.features` slot; update `subset.StdAssay` to no longer call `droplevels` on the input's feature-level `meta.data` slot (reverting #251, see discussion in #247) - Add `drop = FALSE` when retrieving data in `LayerData.Assay` to preserve dimensions when subsetting to the requested cells (#261) - Update `sf.data` slot in the `Segmentation` class to store a `data.frame` in accordance with changes in loading Visium segmentations (#267) - Add `compact` slot to the `Segmentation` class to denote whether the object only stores segmentation information in the `sf.data` slot, or also the `sp`-inherited slots (#267) - Update `CreateSegmentation`, `CreateSegmentation.data.frame`, `CreateSegmentation.sf`, and methods interacting with `Segmentation` objects (`Cells.Segmentation`, `RenameCells.Segmentation`, `Crop.Segmentation`, `subset.Segmentation`, `[[<-`, `coordinates`, `Overlay`, `show`, `setValidity`) to account for the addition of `compact` and the update to `sf.data` - For a detailed description of changes, see [#267](https://github.com/satijalab/seurat-object/pull/267) - Add `coords_x_orientation` slot to the `FOV` class to hold the orientation of the x-axis for spatial data (to mark whether the coordinate system of a spatial object has been updated) - Update `UpdateSeuratObject` to check whether an object requires an update to the coordinate system based on the existence and value of the `coords_x_orientation` slot (currently only relevant for Visium objects) - Add method `safeValidityCheck` to show an improved error message suggesting to run `UpdateSeuratObject` when a "slots in class definition but not in object" error is thrown by R's internal object validation; use in `FOV`-interacting methods # SeuratObject 5.2.0 ## Changes: - Add `sf.data` slot to the `Segmentation` class to store an [`sf`](https://r-spatial.github.io/sf/articles/sf1.html) object (#258) - `sf.data` will represent segmentation boundaries for a given image inside the `images` slot of a Seurat object - Add `CreateSegmentation.sf`, `[[<-`, `setValidity` for interacting with `Segmentation` objects - Update `RenameCells.Segmentation`, `subset.Segmentation`, `[`, `UpdateSeuratObject` - Add optional `misc` slot to `SpatialImage` to store additional info associated with an object in a list (#258) # SeuratObject 5.1.0 ## Changes: - Update `subset.Seurat` to call `droplevels` on the input's cell-level `meta.data` slot; update `subset.Assay` to call `droplevels` on the input's feature-level `meta.features` slot; update `subset.StdAssay` to call `droplevels` on the input's feature-level `meta.data` slot (#251) - Update `UpdateSeuratObject` to call `droplevels` on the input's cell-level `meta.data` slot (@samuel-marsh, #247) - Drop `Seurat` from `Enhances`; update `.IsFutureSeurat` to avoid calling `requireNamespace('Seurat', ...)` (#250) - Update the `VariableFeatures.StdAssay` setter to apply a speedup (#240) - Add `SVFInfo.Assay5` & `SpatiallyVariableFeatures.Assay5` (#242) - Fix bug in `UpdateSeuratObject` (@neanderthalensis, #210) - Fix bug in `WhichCells.Seurat` (@maxim-h, #219) - Fix bug in `SpatiallyVariableFeatures.Assay` (#242) - Fix bug in `merge.Seurat` (#246) - Fix bug in `VariableFeatures.StdAssay` (#245) - Fix bug in `HVFInfo.StdAssay` (#244) - Fix bug in `RenameCells.Seurat` (#237) - Fix bug in `subset.StdAssay` (#214) # SeuratObject 5.0.2 ## Changes: - Properly re-export `%||%` from rlang (#178) - Class key-based warnings (#180) - Require R 4.1 (#180) - Fix errors in `UpdateSeuratObject` (@ddiez, #182) - Add `...` to call signature for `Radius` generic (#190) - Fix bug in `PolyVtx` (#194) - Fix bug in feature-level subsetting (#200) - Update `UpdateSeuratObject` to run without `Seurat` installed (#199) - Add warning in `Layers.Assay()` when the search returns no results (@maxim-h, #189) - Fix bug in `subset` to allow empty images to be dropped (#204) # SeuratObject 5.0.1 ## Changes: - Update internal calls to `GetAssayData()` to use `layer` instead of `slot` (#160) - Update Matrix version to 1.6-2 (#164) - Change layer-saving in `SaveSeuratRds()` to move all layers instead of just those in `tempdir()` (#169) - Update internal calls to `SetAssayData()` to use `layer` instead of `slot` (#171) - Replace internal calls of `FilterObjects()` to `.FilterObjects()` (#171) # SeuratObject 5.0.0 ## Added - New `Assay5` class with support for layers; layers provide support for: - arbitrary expression matrix names and number - arbitrary expression matrix shape - disk-backed expression matrices - New `$` method for `Assay` and `Assay5` objects to pull expression matrices, replacing informal usage of `@` - New `LayerData()` and `LayerData()<-` functions to replace `GetAssayData()` and `SetAssayData()`, respectively - Support for renaming cells and features with `dimnames()<-` (changing feature names does not apply to v3 `Assay` objects) - New `SaveSeuratRds()` and `LoadSeuratRds()` to save and load `Seurat` objects with disk-backed layers - New `droplevels.LogMap()` to drop unused entries from a `LogMap` - New ability to split (`split()`) and rejoin layers (`JoinLayers()`) within `Assay` and `Assay5` objects based on grouping factor ## Changes - `slot` argument deprecated in all contexts; where applicable, replaced with `layer` argument - `[` for `Assay` and `Assay5` objects take a layer name to pull an expression matrix - option `Seurat.object.assay.brackets` allows restoring v3/v4 behavior of subsetting the main expression matrix (eg. `data`) - Stricter object validation routines at all levels - `PackageCheck()` deprecated in favor of `rlang::check_installed()` - `AttachDeps()` deprecated in favor of using the `Depends` field of `DESCRIPTION` - Subobjects within a `Seurat` object may have subsets of cells present at the object level - Begun replacement of `stop()` and `warning()` with `rlang::abort()` and `rlang::warn()` for easier debugging - Expanded validation and utility of `KeyMixin` objects ## Removed - Unused object constructors (eg. `Assay()`, `Seurat()`) # SeuratObject 4.1.4 ## Changes - Fixes for `CellsByIdentities` (#80) - Remove {rgeos} from Suggests and replace with {sf} due to {rgeos} package retirement - New check for potential binary breaks between dependencies and SeuratObject # SeuratObject 4.1.3 ## Changes - Move {rgeos} to Suggests; segmentation simplification now requires {rgeos} to be installed manually - Move {sp} to Depends ## Added - Add keys to `Assays` and `DimReducs` in `UpdateSeuratObject` when missing # SeuratObject 4.1.2 ## Changed - Bump required Matrix version to >= 1.5.0 # SeuratObject 4.1.1 ## Changed - Update sparse matrix coersions due to Matrix deprecations # SeuratObject 4.1.0 ## Changed - Allow `UpdateSeuratObject` to work when `data` is `NULL` (#38) - Fix superclass issue with R-devel 4.3.x (#42) ## Added - New `FOV`, `Segmentations`, `Centroids`, and `Molecules` classes for imaging-based spatial datasets # SeuratObject 4.0.4 ## Changed - `CreateSeuratObject.Assay` sets Assay key when not present (#29) - Ignore warnings when creating an `Assay` from a data frame (#32) ## Added - New `CheckMatrix` generic for validating expression matrices # SeuratObject 4.0.3 ## Changed - Export utility functions (#22) - Bug fix in names with `Key.Seurat` (#26) - Improved duplicate key checking and resolution # SeuratObject 4.0.2 ## Changed - Provide default option for `Seurat.checkdots` option if option is not set (#16) # SeuratObject 4.0.1 ## Added - `head` and `tail` methods for `Seurat` and `Assay` objects (#5) - New utility functions (#6): - `AttachDeps` to attach required imported dependencies on package attachment - `IsMatrixEmpty` to test if a matrix is empty or not ## Changed - Allow super classes to replace child classes (#1). For example, allows `Assay` objects to replace `Seurat::SCTAssay` or `Signac::ChromatinAssay` objects of the same name - Better support for creating sparse matrices from `data.table`/`tibble` objects (#4) - Improved error messages for clashing object names (#7) - Allow returning a `NULL` if a subset results in zero cells (#9) ## Removed - SCT-specific code (#2) # SeuratObject 4.0.0 - Initial release of SeuratObject SeuratObject/build/0000755000176200001440000000000015116571033013745 5ustar liggesusersSeuratObject/build/SeuratObject.pdf0000644000176200001440000154542615116571033017053 0ustar liggesusers%PDF-1.7 %ÐÔÅØ 2 0 obj << /Type /ObjStm /N 100 /First 826 /Length 1368 /Filter /FlateDecode >> stream xÚµXßo›<}Ï_áÇMÚRü#U“ºD«&¥Ôn{Ù^¼à/a…™Öÿþ;¦3ª˜Ú=äBÀ>÷Ü{.×J""‰äDªI£1¡áRÊ O¡‚Ž11'TɆ©è„1¢ðc’(ÌfŠÄ2",!±–„GDsE8':f„œiÂc’(\^ÄG¥'n(`…ÄQi"@‡aŠHpÔœ•òX8¢T€—8*F$ÈÊGàI©ˆžLÔ·¨Â$<•Ä`þ÷§á'žN"âJ_"üqäüqÄxM)ðc "R„q-ˆFÂ(&´&¸Å\zàI¸fŠ*’O! 4`LÕ„‚4‹µ»H È2‡ÔÓ ‰t™€’J8RhÁ©Â¨Áiân!§p‰4Qœh9¡ Ã¹›U8Wˆ¸+ 7\¸q§0R¨Ãe«5à‘fœ¸üC#®CˆÄcÎP‰k7 2qíp0Ž'Ü]r‚€¡‘K7¤Ð'‘QŒX`á®@`æ* ‚#½z Á"'Nœº€2rWœ¸º€f¢%Ñ„BÆ)2"œª² Í\9qQ@8‘ @¡6ŠÇeÒIa &HWë(”2²N%[>Or$€B?Ù=”B»*AÝKíʤ­|99?'g·äì²ü\’³9yuóßfzkw•i>ýøi—Íô&5õzº5Ë;³²Súš¼{7yõÇ ¿ø;ªíÖëÌΙÊãLãÌ'g~8óÓ[ú»oÙúí;ÿwÕÎx}ãt^湩®MaëG³²(Ì&=ÄqêÌܙҙÜã)_û¿…'Zû¹ýAÎ_©OÚ2äá¨|ßþ©Ç„§ÆQ9ž¡ÉQ^D™?Ò ð&„}þØZÞ ñqî»Å›ñöæúËbñB.ý¶…|qfÑš@çºIË|®¹ï‘c*îo\9¸§æÑÃZuÐOÕ§ƒÞÓ:Ý .ÒôÊ6fnsÈý…lZså 4}Þeaû1õtf7MUfi}È‘é®>3ïhã‘+_æ ÕAo—•Ù®xºìf²]š×AÔ<«›ã¢=q‘{εæ_é Ž…iªì÷tQ®®Ìv½¢ë¶òlû! OeåËà!]A×6[­”Õ×> ™w±ö»¨Ömô~>ÍÐ M»Þšª¶°ëî®®ò×{¹‡VøÐŸ—¹©ëà³w¨a½õ;Ǽ˥>îí—ɳ4kîOwøË_Ë»Ï`æKç¾Ç¿®³|NÐò¥"ïí­‡<ë¨-öi™ åªiÌr=·Û0ZÓíùKÿˆÎýSµíñð¾ÜmRSeö ‡÷þ1ßíÛ[÷aÊöo(‡=ÌLÝ7³nÉ4'î3f6Ïë ®í¾_Õ=ïï?¦X³&ˆƒx>C­„}rž¬ŽY÷ÌàRÞo‡Ò(½·î—ý# `ðš?¦˜]÷Zoæoíª€ø¦ÉÊÍéö{áU·mºëü~=iùnúýõ õŒNû¦bTnû9”o/ÿÀFc! endstream endobj 203 0 obj << /Type /ObjStm /N 100 /First 878 /Length 1378 /Filter /FlateDecode >> stream xÚµXËnÛ:Ýû+¸l7¡ø( (P4Mš6i€¸èªÚbµz–’&ÏÈ¢ühº0EIä93s†Ò‚ Æ™à1“). ‹"ÜâikÄ„4¸*&«fRƸ&»û”)…{!˜2b&„dšÆ‹˜iz/ÓxÉYL÷2b —Š%F⪙Qªã0†Þ§,ñ^ qnfBItRŒÀ¬("(‰OhØ(b­#IÜ ­X¤8u4:)k?$ NÑ1°,r,aj äDÐ '1Èc X. ›˜\r ÛEäÎ0r‚{b(hÔùl(^†Ï9&ÈTC‘1˜nrw)'Tú)šÞù–â}ªÉआÌÅ]š’)†æ3Él"zBèpYB0aà©$ÕR‘¢Cèð@B3É1C’hQ–¤Ohp7N0 O0.žIAãRz‚×$‹„t²»ƒÿÐKsŠ1ÔöJh¦)E%ÔQBOR¦)sÔ"IfïÞ±ã9;>«¿×ìø„½¹¾©ŽNܽ/ÚMcŸŽ¢·ìýûÙ›Ÿ2‰ñK~rÎO¨qÔÜPc©¹§¦ ¦¥æ5oº!Oo§ØNòòÚe÷Ë »!95%5×~Fæ/'ùO¯~H}JÍ5?&.ì“[ÈqÑGÑ^³eyy”.†éhO­<¶þ+pjt˜a*Æ8×žØæî~mÛ]¹æ¼Ã]{§Ú CeK×ì,IåKOÕ¨Õ3fýo¨§•Üðïàiþ}#ï³è:³ÍÝѲ°M\}[²‡šÿ|¯ðÔ›pìÄÿ`‹<ËÛ§¿6áÁ³~ZÈvêK›7­­–nKc½*Ë^€ÚëzU¸W4Gõí¥]õî„«©Yy'œwÌùg½ò~Æ-5—Þ´Õ¸-ŸÊ…˲¼ºuô“óbç>ˆ•çjB «öéÒ¶ëüqšbÕk24½õ¡èÇyN]»¼;±­c9õæ·^¢;/eÏbØyѺõÕâ—[¶M?Ö!ç;òüå_,ý¸@ܨÈnYŽÏªé!«®g(]{Wg;s”ÃhÞùœËvb›ZÞct‡¯â3מ—öÖ1 8÷ŽYŸÑ.ˆú=oš{÷±®×X;¶ÿL¼`ø>üj4þ{Õ ùèƒXû¼y±Êì0µq>[ÛÕݶÌ9–…•—qßúüãô¼º©Ç8>{O}€+¿s«ÇñÎ3W/±s瑦ÖO'|é¥ÔSHUæƒ@ÕÐ®Ç F¾œ0§ê½µ†ä>H >G%$Æ©ÿ5#_¡ƒªÇysVÔ [Ýj|²zÑ/çê¦\t•c:\$‚µ%Äù °ìešñÛÈÆ+ó±{¶)çùb—¿çíÚþé*Õ–UúÅsu:ýö[»v¸|ÿŒU²CVó˜uµáuì;¨š|©óª;$† «‡k`ôX8Å0"ÏÇg|u£ÙúÕÓr¯°‹é½`/Þâµö}]ìB»¥`¨vÛ-]Ô6¸£ìí´{î#ÃáÙÛ÷ ÒöÍHøö&°bsÚûX—¥­² ë†;ˆrXà6µeÜŠÒ­±= ¸Ë¡þ}©Ü÷„ýŒG¿ÑÄyzÃ6õßÈ4ßáÿ’l˜ÃÇøiÞ}Ïí—y3êÝå°ÁÖÿcp endstream endobj 584 0 obj << /Length 1178 /Filter /FlateDecode >> stream xÚ¥—aoÛ6†¿çWèÛ$Ì¢I‰’¬b+ÐÔi–"Ù Û0´ÃÆHŒÍD– ’2–¿£H'U,'ÎEñŽÏ½äiì-=ìŸàÏÓÅÉøM¼£4oq㑜"J3/É&(ÉroQz_ý/AŒ}„Ä/Lë.HrŸ-yÆ õÿ™óV2ýÛuB÷-/ôÁ_‹Ïà8õAy’DÆq#J/ŒR„sbýNyÁ×A”ù` ÿ¹Qêb¦Ù—G‰ñ÷ Ž©—£åªb£r>åßpLë]˜sjŸEŔڋ]u±‡ˆo#§þ’×ÍZf+tï僄¬.]C©tâ‚i^(/¢(Ç€w;‚‹fZ3>²–ª-°[Y×Ìñ”bÍk£«„6ßïm¿ä%¬™ »{ím¥²våÜÖœÁÂê°æb¹za4ܧZJ¶Yí,]L Å8Ye„¸¥ÙŸFÕTÛ ›ÎÉhãn$Ì¡+d»¿ÈÆ`oE¹“x§Y-¹RöuÍõªéèJ×c0g!Ì ¶Æ¯Û+Cem›;g¬§M­`oÛ¶^¹†M\;°1é›ték? çá†u«] &û.ð#msf­Úé"»ÚMǘþ­Û:3'÷§`šKùgŸGvÒs^×\:´©ÍÝ;sƒ¿áG˜$ð$Öì'›(ƒÉ±'!/\sv~e#ÞŒ˜àx2®»­¡QLò¨—I0ôý¨ƒK½+V4êάåÌñž2ÕÚžv?\ÚIåô?C|d “t|‹ P{NÆ/EâVã!yçºeÒA-ûi ÕTöãé‹Owàùÿ^Çž#“ãÀaNú?˜ë€Êýì6‰ÈÛ$ŽÂþ&{˜•ã\>¸¢øÕt€7ÃáE &œã’Nè íŠüߺٕ‰’k&*(aϾeý»óèRPnŽ8}¯.vªw¡ÇÔµÔ¿¼€>š*rö+´æ]ë…CÑ\câÌBü>»ì–|d{X+­7êÝx¬ºŒ­Ø5Z ½j¯‘hƪ+™!ÔJ %ÓTËñ³qú£gïÉìCZîXAѬ±`ú!¿°f\nžÓv9ãsã‚ÃK«·Jw$îX(Õru õ“åý)œñº»ü-wìJÀñçàoŽáºÞÈ;…¤nk±… G%ßÉÛ¿£Y@^—êåĘ=–‚÷?Û| ˆt%Ý”…ÑÁ•Úì[Õ´«&¯Mä‹õ1}Óšëóa6û±Í¦º¬äp³äRjð¤]Ê)ßBaQæR”ƒ*qËû¢âƒ_¯˜–âß!ÉR#6}ûi•t·´ ÜÒq7²Y•SÉAóY±\(Œ˜ÖV~âšÊŠÕË}[Œ(X¢ì 1Ü_×Ã4ÓjÔ?$üø£™ù±–˜ÙìÅÉ@é€Ý endstream endobj 600 0 obj << /Length 782 /Filter /FlateDecode >> stream xÚÕ—Ks›0ÇïþÜ 3AH¼íLÇétҴ㸧¤dBÌk¨cúJim‡ø1ÐÎôbÐþvõ×j%C-Ö v58Ÿ†cli\ÛÕ¦3Í‚ ìjžeÚ4ÒîtÛø1ý<»þÆ@äÙ p°À¬‡\¹aû:§ªaÒb7;>L„}±§™¶':‘"ðÂ0…i‘²3i, MCà8êsÍ“ôoRm ( – ÛVV·uS¶?œ;ÓP?ÿvAÓß¿Q2W¡F4%rnKùC£U%^=}ÙíŒ&BH¿‡üð^>cݰE‡ÕjÁfmÀ7-â¸L n·~û4;*Bÿ«ŒTó¨ùöˆfÂ\Ç ?Yôë$Ÿ'y<5W/+? ËòLM^>^&±H¢=>á¶7‘y÷áxxCiĆ Ù:}` §‡]—óøE‚c<6™z^'iô…äÒSMÒÃnxUÓft™‡b/x$T›þ øk²ZŽ'ýÅÝè2)¤"ÏK±~7Å1ò{tÒR§)yvWàwª`m»TÙõ\ª2Sq&M]Û(ãíÐì™vìjµÚK‚Ç@„f´JBvÉÝGš¯ëÓ2Kž“¼‡¸*R>vÇDtFê”wÆš*ì#½;.-⌔ÝEß<*Öã49“«"‰z-,²ŒäQ/ 2MHÒòKÔ³î«øDB©Ôœqur. ÓÒaé­dñ픓¬¢QvŸ+£qÖ,)áIÑÃ&ÏŠ”†uJ{ÈVŠ˜HÚ4[ŸË?»/jN“øQ²šÂßÇ ÔὈU±²}7Þ‡½žfay³··®mì»®ðHú"ß©L|ñf57ùÈ>ÅØjþ#Ü®5ù*Dv\ý‰†Ü,›Ýdˆ d`ËÝ´> ÿnƒƒàß8jó·y9â_«ä«zœ\ déÀ–§»;cU»^r ˆ•°`$o=Õ ÉÄþT*_¨l˜¾åþGÊ´6ÇÊåê^«\»íåtð ˜(vÊ endstream endobj 404 0 obj << /Type /ObjStm /N 100 /First 879 /Length 2006 /Filter /FlateDecode >> stream xÚµY]oÛ¸}÷¯àc l)~‹ºȦ轚¶°ÓÝ{o›ÅVl5¶eHršüû=£¸t•J®cg›¤(jæpÎp8¢ŒÐL0#bf<*Ϥ6ÌHɤ§Z1åq[Z¦e‚Ú1Ð5Ú(Á¬ÄsJ3ëâQ†9K×1s‰BíY¬q­%‹cŒ×ŠyÒ£-óžd8–X:aI}F0)b‹†fRŠd`ŒAÃROŒ†Ç³x^*…‡-@*çÐP@ •ã¤nz“ @› A$[#Ñ€d›ˆqKêäØR’=ɉiú1tÅœÄÐJ½‰SF‚FBfLi‰¯Ñpz``9e¡Ñˆ1/àVÖF"ÑH0ÖQŽ$'Ã>&dO˜Höx HN`& Ž´Pf`…AX,øÒ˜<žiÌ3ÑÄ•gZC%Ò†%ÖHmÚ‚_ Þ´èq€,˜Ó.¥cȰàNǘ“8íz0íêäDS¶*@ °¡5䘅%É’Á Q Ùr¥( &£k°gñ7št5LC³µ ¯l‰iPdÁ È#Gƒdo³`T5®G aî`ÐxX‚AðÇÁ h€Ò˜ŒkYð«A õ*Cc`GCxà¢Ð;Ç4Ž”‚!Ð…+XÖI’ì%s [¯˜#'²˜’s´¼Cƒž‚tרSr±E8uÞ™ÁÉ ‹F,úwqQ°è5{1¼^òóbž×ó¬âÃIZÍøxžV—/Ùï¿^|ѱÃ?þ"„8§¢ bNEFŘŠu»¯¢âU¸ÛÜHÃêå^(Y=+&Ï„cúj*fAÀd¢eºšQ¶.Óº Æ2ÌkÑVÉ©…¾U×ÝÚÞgùtvU”¿"á}›S1 ó¹ “*±ÿ#ý;Ìÿ$YþÃmVÎÓû.娸 BËöï»å}LÇ7é4;›eã›.¡ƒ€Æ`7árô[w»éÖ¶ºZŒùp=çÕ"Ï»ô­‚µAØD­ÀÑ" hæ6ïQTæËš¿ÎÃl²÷**UËÀC㢯ÃFß0ÌnÜvÜcвøšë^[–æ¯m“õ8ÿ0äëNgKLÚõצËI±x¥»[Ú2ˆ,‚Þ?ZÐ=2 §U•Þ÷#ÎúÄévn½v×|mgÙ|~€²³Ðš‡¢OOñí<+§Ùh•–UvžÖe>ÎúU6Fû‚ñv-nWÌ(8`îVáîù6¶}t¼¥ÝHGémö”‡ÝñiDß¶ÁtFã0¥]i”MÙ²Në¼Xþ*@oUMÛllWßVsŒ¹<$hwàÚ¸FvP0ïÀx›ÎóI^ßÿ# oÛ±3oÇŽzÇ6Qeõ`~½i,×ݼj[âU.—íŒdÞg&½ØÛ§ºÜ÷é^óƒÎý¸èU{¸µPœ‹Böq8kÇñEG”ªªYñí·wÅô<]µV¯3ÌÚañ7*Þ…¾i;æ­öXR=VË«y~ÝO×v?_µY¹ÞÅÅ Ë3¿] KÚ‹ŠUÇ:ÜzÁÛ6 Û=áÉžú3®_Å·cß*ðQó&èuŽGTlS°Îtà—zì3)¢ÂöX¾žd·½F®ƒQkÝöÉÈëñ¬É%îv‹Ú‚Ã÷fw=öY_QßMÄ:dÞ"ø“ÙøA›}Nu;8ÙèÜ•ðï¡õ𬣿ÿxíO}-¾˜euÚ¥ë¢ýBöôÈ(Šy¯ˆb{˜Ðýô§Õ$­7燫¾×žOaõMÚ~»Gúù!Xl¿·¥ ¢yQWB™‡I×;"ÛŸYYQÒÖ¡ãÏvÖ_=Jƺåý5ËdzÞW™¿¡y;ìù“/'Ù? ~Ûβîò™Nè²èM^_’““Atq¿ÊXôÛÏ :+–5ÙŠYohä fU±.ñžÔœ´5]çÙ$Oÿ(îØgÁèÈN±8Q—ˆ(ñ,æ=Œ;].AûÜœ’Z:|¨Ý¦Ž7µßÔÉCíŦ–›Z5õå ¹‘?ˆþ(ÊIV6XÄeôŸèmt† Éä%¡×ì³Vš :ìÜБ³t\Pí7š†ÖW5DFïòåMtzrÒ(ˆNÇ”ÏG£èÓð-ý_ÌêzUý+Š&E΋rIÁ¥Ð>Z^Õ\ËD½¼Ê„Óq¬öœÎ‹AMgÙ bw$B颯| ŸäJHË~â¬*Ñ<¦wåxs¬é¹/ŸlÒ€Õò°VqM–•†;©™ö’kúFÑ€NË*É…ÁÏNµhËG á±R=ìâ¸Xlq·ÑÖn,)cNߘŒ„c!kX\&öŸåUµÎª#ÖÓw·ÄÂ+,Ó±à¾ùŽÆ­=À®–«ò¦âå«õ2¿Åqdê?Àûq+ûïÿþÏ’‹Ú±<ÛÄ0:Ѹì+‘¥Ñ`‡0ætrÄà7Ø,m±oª­÷›­íO¾_ì‡âû…Ä…ü~AŸ¬ö5È‹>–Åx”Á–ØŠ_¿aÑEvW?ÞðíÑNˆŸöèĺG'›=:±Û½öoõ{ì endstream endobj 658 0 obj << /Length 1011 /Filter /FlateDecode >> stream xÚíœKoÛ8…÷ùZt!•Ê7E`63 Z$)ÐzfÌ‚µY[;2$e0ý÷CÙrÇNs%+À ºÓFô>ž{)…³€'§ã“wç* LbSÁø[@ I¸P¦4QÜãipŽòÛˆ¥aå6CÓ°Œþ|w.èƒsQ‰VÜ_y}¯9!Í­‚˜«41T1Óþ¾9è&y_–¶¾ì(æR‡IKBöaÌ“{‰á{¿‡P‰ÿ$IõÏÍ×ÏõMLU¡~tl3$ˆ)K¨Þ›ÅŠK„Ýú†þ,[~vÓ»‰OS”~'Ô†ú‹»+l5Ê—K{;õFˆœŒAPgJ êŽy§‡Ì¤5zúkôtŸ½üõʉS„¯CÊ€º¿7n.^çZ×u€ YoœÛ__š¡^¹ ÷ßâ·[ò-Ëa¸ ÜPdKØo¯ÿ¸¼ô®BÑ@ž²­”o†CÙÀk˜~ЃJË7;E¼úW0pô) ýÖ»•hÝÇ•™k#7m°ÿ,3uʧh°”¨Ê|_Ètzå*{f+ë×F¦±´l%^ÑBXÛ25MÞ"ϦeíÚX×tJ~ŒÒ‰'~QØÕ<Š™2Fz0ú"+«ÇvÝX Ƽ†%²\ÚªÈþM.óÙ•]ù”Í öVŸ„*€P¯]6›×^üÕ›CæE½=£1.w‚.з±Ù˜I\—+[”Î[¯Vˆøå¹7±ãgaO¶ô9ÏŠÕy'à VÈ=ï")C»È¦YÕô¤„ÀVHKæi+ær+rAVŽ€›–À÷U®iŠkç‹Ðnº"à>zÊ!蜴‚îÝDvTô ìÜ/á°~ɺXUvRó3·ò¡¤@éwÒ<¨¾?Íïn§¶È\o1q€»î0Ô#[Vv+…â¸Ms tP«eä‹ÚÎ¥Â%³wÙKð œþø0mö²jm6šLæÏVm/íÌù[hŠFÒŽ²…“½³mÑ© Ç<ÒæC”—®šçëy½]©6ÁŸÆ j›Œæn®ÿ¾EqÊ9®†G ¤òË&ù1º¢¼¶KïÖ©æƒógpÕä»Ýß•ßQ8JΠ§HF…³•»ï~úêo¤ÂïnRùåPÓá¸Fo`éA²;`EŸ9ãµ% ÁàÂ}ô%L`÷_ç»}wf­^¹µ)±ž«A 8ÈóZ¦Ÿê°ð§¨4v?;—pâWùÂMîëNèÎ:†=ýƒéL·XÕ¾¸Ù²q^[eù­O¾Ják/ûzÕp½nžfº ­ÿ{ƒÑÚ/‹Vùª¾´À:¢oaËõÜãñ÷ñɵñ endstream endobj 749 0 obj << /Length 1068 /Filter /FlateDecode >> stream xÚí›Ms›0†ïþáÕ’àØ&µë4mfO/™T£8´`2@úñï+’Ø©/ nš¢ ÊA™Ç;ïî¾Z³p3½š^ŒCìÄAÌ wfçF( !wƧ±3Kœ37ô>ÍŽ^Œy´v#$ˆY¨³ºå Xz$rkÕ,•ù‹j·¹³‡O) 0bŽO„þ!mžp¨ÎåUV¿¬*iñÓóE¹ç3„~_Â8þãïz]þÚF÷ì·Îé+ "§4ß6_~˜Œœ3?ÆÂeøÎ½Íª/>&¤ÓüƒJ®æžþð¿ÍfÑr—‘hÇ&‚O<"ÜúŸ'ôÙFÞÓ"§·ª¡/ªôü(¦†^i‡ÚIškÍH8€ˆí¼_oÐñêLG7Â6ºÄ›Aƒü6;Šˆ <¸áõ‡â=UW¥¬=_×›áÀóáæ~pÖÈz)sU­‹vŒ„͆»„"z]-Îáð>Êp¼14ï5|¯å‚ãÁêColÛ²¹Íoþ<“Uåù´ÉrC”Ü®YŽ£N€¿yŒ»2K“´6¡16öP¾ý7ÒÀaFZÕr9W:r£Ovog» s#)‹ËL}[µØY‹wòRk²^a ‡ ò0^çêgÏ7h“$].t\‡”Ø’8Þs| ý²^Õlïd]¦?t #2pÄIƒ<£±QWÕsûâPÖRï Ö â[Áƒ|ŒqšÕª<Ѻ¢+/j®…Þ´Ü®Á‰5¥»Õ%ë7οox7Å5£‘ ðÇ”(¢+û\™`¿(V)51Ùì3Yoº øÎÐ7:•Õ±Ð:Ô¨ *^&ªžær¡´’³¡w:ê75ïYZUWê ‘”¢ÔUº¬Mÿ)"nµúV«¨—œ”òòâÚ{âŒÚ„ø Ö:ÉÌ7ÇÓå¹]ÊìqKQŸ&7ãP¾°OŸ"ªMVÒÔ~XØÚ¯¿„ ;»™.õcuÀË-îÞàG ³Í>ÛÈï>¨TLÛIزRóúÆ%g!²ª¾CÕa|§Õ$+>ËL?^È=„5ao|òÛ\×í$¸‰g +«÷2WÉqZÕºËä¶Ú ë¶@9’«‰¯§u)õÝM¬™¶üž×¬Ñ #ŸílsÍV­›²Œ1;ó`"tœsT¤Ë1w3¶C‰Í}!:Õ9:õüˆpÛ«?é§ðV™áUBÿgÛúiì¬d§d²P¹þÑr®;›øyrˆU Ì:Ùùv`‚àÚì| òMŽ Ù_Q‚¬°÷€À°·“„[è=@§pè[¦“c*,â]ˆqóâÂA‘çr™x¾ÀÔ¦ÅÎ4Û´˜«r¡Ö_d¢{˜.yÎøáÀAõöÞÌ4xcÙ™´€“¾}å”cf%xÙíoèÝ]_ÏF¿ ì(/ endstream endobj 606 0 obj << /Type /ObjStm /N 100 /First 918 /Length 1973 /Filter /FlateDecode >> stream xÚÍš]‹7†ïûWèr÷F­ó¥# $1Þ]Øû"»f.¼ÎBÂL!ûï÷UÍqw9à"Fã3ªî®zõèë©^[×T’uK$”j¡ÄUPj’âø¾%1NÕ<©u|®©Û¸ß•6艘p(¨*Q"õŠo8Ñø½’$r÷h¢æ† K\JÃEML òÄ슋–XQu¥žØ´¤ÊLe\+PfNÜÊ,Ê ^.PfK"e®I´B‡Mèãf´ÅG#¹'i£•R’ôn‡Šo•pcNÊ•Š$•>îQ´bU,iET©I½£RA§tTXQŸC¥`2ê¨Ü&¬‡Š¶™¢÷*ÚoÖ¡¬’Ì^U“5ƒ²Úèh(ëÒkPÖÁmPÖ!ÚðGñ³¡*z¿Vƒ²áƒ7_§ÚÑIÕ$yÁüœœÄ€‹G+.Ðd‡ ë訣ãÑžZO”’ž:8&AŒƒNMQIÍÚ¸GSsŒêI­Å1­·Q³§NOǸv¯cì»4KÁ¬!;8æFmrÌî˜?޹Ñ; ^ÌRÐpÇä B ÚP£"¸eTIEuh5\™'0õʨßÑxÌFiGQéŽgÑ4"B F_1†Ï1Kˆ¤¢~Œ‘¡¡Ž¡5FÙ1þDŽ)ã˜)D½ •1½ &ƒc®`¢WtzƒÔG×¢VüuÜAlu@‰¸bÝ8j$FGŽžÇŽ+Ô!ÄꆪcÒ< β†z=<{v8¾þ߯×éøõÍÍíýáøêÃï—ÏÿüéæçÃñ›Û»®ïÞ,ÝruüûñÇoßÐòápüîúÝ}zc¥f 9wL#É¥-«<‹ã¶¯Ó³géø*ÿvûú6Ÿ§¿üúöÇë\ÿš¾úꀈ@%WLƒõ\ª}žÁ× Ï!„¾.é»tüþßÿÁlÉX×c,³!vÝ|øå—«ÏÝ‹ µÜLU³Èïn~q{s¿Ôÿb¬ÑN½À쨘5Æíåã/XXñ k`|€ÞñåÝí»W×ht:¾|þ"__ÿvŸ®>íÇ—hÛáø-ª½¾¹ØÆã£·Þß~¸{wý~Y¦ËWÿºþá§·ßÜþ––þ‘köòíž“<Ü· Í{Ô:ó`y”#î.%•()JŽR¢Ô(-ÊeèP‹2ô8ô8ô8ô8ô8ô8ô8ô8ô8ô8ô$ô$ô$ô$ô$ô$ô$ô$ô$ô$ô4ô4ô4ô4ô4ô4ô4ô4ô4ô4ô,ô,ô,ô,ôìAïêq— – –ÌiÅÔNX1úWÌ#!xÉhô Á[n]>Ð& XÃò=#ÔšÌ?Ð2‚ò˜™j?3ÂŽm0P™!’{_A(gi[4‚)7^AHÉL[<¢ô<65'j¹è„<>blÖ¶‚(–›ó„N€h–ÇÎî#RBÆ~mÂ&@¸ qç8e2¶½uD-{É3DÅ¡nAøEx,+óL} ¢M€š—³ÈGµ\˜6 &DLÃÆLW¹ ó!7Û€à Óˆ3c+t‚à±Ý‚˜1 »Ïq¨3Ý}6âRûÌlö™ÕØgæ;°Ï¬íÀ>³¾ûl Ä¥öY-;°Ï*íÀ>«¼û¬Êì³ÛgUw`ŸUûÂöY­_Þ>«þåí³) Úg^¾¼}æôåí3çØg.;°Ï¦@\jŸ¹ïÀ>ó¾û¬•Øgv`ŸM¸Ô>k¼û¬Éì³)—ÚgMw`Ÿ5Û}Öêì³)—ÚgÍw`Ÿµ¾û¬—Øgw`ŸõS°ú?é¼0 endstream endobj 841 0 obj << /Length 1045 /Filter /FlateDecode >> stream xÚí›]o›H†ïó+¸©æû²›6UW›¶²½íEµZ{bÓcζÿ~Ïì’6­D³i™KàQž¿ç¼ç#oí!ïÅÙo‹³óK.=)soqãa„"B¹'0Ž8QÞbå½÷/ŠmK¿ÖÍ%±_-~?¿¤¸ó,E<œÀ'žbæ–3Ô.å…„ËHaê…±€GHsS®ËµŽæz_&ð¹’P? B†ÐÃ\¨Rs½.9¯(’^iÞ6΀çûPaî+ùŽ-mä…8Ž„b æ«´Z!§?Å?ÿ(Ö³Ú ;ß»-(2½Ügº —YRUA(è8ŽÄ÷dœëzS 5þ Ps$'€s0ÜØ î6Éuu’jãé°üÞz–œp&Vœ_ét½1öίô‹ò(°QSgÞ6û¨ò RŠÉ…Åñ óòë[CX—Yb®ŸLž']"2†r3«CþÆ`O–æõŸ€1?Yë‹nßÃ'=b?‹¸p+î»ë|ùw•'Y„„0wÖ‡‰L€}KÞeÚ8ÔèYšÏôjž‡`—e[ˉ°““â#ãþ½4µ„ÅäÜá¡ogågÉ*ÝCfBIìbèÿ@»*òW`…@Zu'¾'eeGY³ù´ªš„Ñäኸ¬Ð2FVYyùBgðUNMúæ%Ø®î7+Ìþ÷ʺ绤¬ôUR—éR› œºìb»ÚÓü `#…¯!lŠP3Óˆ8˜tÊ\6m{jíŠPs½ÎÛvOR§ÅöXƒâ„M.æõ8ÍlÜ»5'†b—4t©òaToµŽ,ÁX¥µÑŽOèX<×®]Þ[é:LoÂÞ½©gH…œë{ðM¨;É/¢Žó0ÜÊ*)nq·ÒÊ‘v¤£i¿¸äØ"͈QÓ}Qä9øêSc\`×eé²´k~W›Æi<ù£X_%»nRL'áŸGg:Oó]–ÞÀ—Ÿcײã0ƒ¤Æ–žoi\’½Ì“µ>JƒdÂU×¾ㆀ½;(#b沆.Q;·\HÔÑ©^ 8w Ú×ëõÐg><ƒõ8äÁ!Ñ®û7¯Wú’a¡à…FÚÙ“:­s›Cù£Ùî÷<èvM¨j]é;ªŽ&N\¶QrL\ðì§"õýyH†*>Õ²R¸¸ÜÓœ4fŸÁøQ ]'¦ù‡œ&‰ãY’øo,2ã•ó;£Q-÷âÏ]SåKjݨÎëkX‹µóyœR×~¹GdìF×»l³¢6sw5lðËyb×k¤E—UZlÁÞ(é¤d )±cÿn“6ö² “„9ÒÀß_À:¿¤´ó“éˆHRå…1‰n7áåv¥?¶Oß»Q4b<>þГû‹ÇëóÅÙÄçú endstream endobj 894 0 obj << /Length 1688 /Filter /FlateDecode >> stream xÚÕYÛnÛ8}÷WèQ"YÔÝA±hš´éf´kgºi‰–ëâŠRƒì×ï I'¶+»u‘»@`2ä> stream xÚÕVmoÓ0þÞ_a1$iñâ—ĉ ƒI Á *2©—å¥$)lÿžsœ„vda Uؾ{‡ä¡“ÙÓÅìèE¢ˆD ÐâQÏ#\HRJ¡Å -19.³LU§*×59Ó›J5ÏÊß4¥ã²Ç?­p9çø¢¬º;`Öކ†YQq¬ëÚH@Å…ªüHˆªõÓ·'³Q SîQ[~wø‹Ž›Ú6o®1šÁ»5ù]­=ÊÕwr‚»ƒÐêyøŒÛ1×Íe¹²sC_;‰3„´ ä.p³úhŒc<’†»gGÏy€ŽB ¿¦ÃGÏ÷®- µj]öå‰<€t‚º0êÈ›WÉ&×…ÃnêIo#OXAWÓ^•ŒIH¸¿6†?„ÍmÐ ±’ˆ¾8ôNŠ‹ªÒɶÙÝ–ÊU½O\š³'î#ÀgÒs+wSýp/eBâWeòO´õõÆï½´¥ÓÊÞ­)²Ÿa&d–ÿŠÅö&«I–ÖIл«¿üYÄ Øßm…˜ô‰v¿$óºV×S}”ØPxø•i`Ôu›ÌÐâ«FMp"BÿÏt1Œ…Ðxù¤‹9Ñ­8m ›ZT÷_2erùÚ<úеêŒüßÛ„ÁÇ÷i®–éN §u 7Í'U%}Dw ×;î#„œ½Fã$¢7Ìv¬ô:S±†&¢™àÃtÝ ®6}NãKej·®ç§Ìo–ü¥ž…m+ÛÙc׎ßn½Q!‰~›ã@ô endstream endobj 786 0 obj << /Type /ObjStm /N 100 /First 916 /Length 2692 /Filter /FlateDecode >> stream xÚÅZß·~¿¿‚ñƒ¸œ$‡…ÀIà6@ v´5üp>_K/§à$éßoVp¥¥f¿ýf83œaU )Tå@"%p)5HksÈ¡æJÉø\CM-˜â7×Z±à  ØYm”~Ò$Pü¦i Z ¬å@-á)­N‚Ÿ·˜*áÂKòÉ-° žRà\¸¦zfʸÜjÆP’ÃÁ/?ÃE "f©Éä“-HQŸÜî`2%¼a2nkRH&J†ÉøV…0™4¨ªOÎA³ùä´$ãO-ûd ÚÌ'·€Gá§Ùo16Ó3c9c¢±„\Æ[rõ_1¨mã­JÊŒ‹ YÁ……"fܰk0ÿÙð¡P*Ó™A+ÅÆ[J3È+áÉú*A[T†ŠL*áæ:­ Ö\1VðP(„b²Œ/6ÄüÞÝ)ÎŽ¹bNu¨Î¬9Âj¡¥ Z0¯±?ÔRhâ0ÀcËsŒC«xo}Í0,!¥ìB` ‰AK£$ͧU\å’ü¸ªì® öb-¢3275b¼m’‰››i)g0:õÞüÞˆ¶ETðÒ-¹ 7†[ÂdšÛ+Uà&A ßß W0P¼, ”Võ·uK§rÖ’Û<ž…ïð .°ž+#®ãw@Ì Š' 7ÁP±L|ÄZj°&\ae4òï*k0#\™œ=~|6üøßß.Ãðäæf½=^¼{½?ÿpuóŸ³á›õí›ËÛ— 7½þ6|?|û’ÆgÃóË‹mx™E_Ï”[ È$19ç¥F¬YÌ{?Ë0üuýã: ß…¯~;{[~¾þú ÿOBk¤6‘sÌõ¡AHމ' T¢¦9eÌÑò„PdÉ3 ê (ÅbÔb*s l â»ð²ªAòó0üãŸÿ ?3ìùæÝõõ«»¹O×7ÛQæS¸m8»Ý¯žb‰,@ÿ€‰Ã³ÛõÅ‹K óáÇËß·áÕû/ý @Άo!ïòf» 6F­çþj›õ»Û‹ËÍèõƯþ~ùæêü›õïa$ÃW'bÞîÙù-~ ²›7ò¸ÁS=ˆ9–ÚzÛÒGícîãÝüÚGëãˆ` ]»‘úÈ}”>jsKk­]uyÔåQ—G]uyÔåQ—G]uyÔåq—Ç]wyÜåq—Ç]wyÜåq—Ç]žtyÒåI—';y¯Nk¿°]ØïÞ|K#˜¯Þ×|à­DÂ.¥Ea{Õ"û4„½PäS;€(9j•9´ÕÈmBE†zê,¼ xRm.Ä4Ë…,€‚,V¬î= †‚l– ]EʱMí‚\CòÀ(àg#R²Šäšå"/€ÂR:p‘Í54ËEYÒ®Ì.ru ÙC£È+O¸(®!žCQ@¡›L¸È®¡:‡bž¹!˜L¸×?4 *Hžä€‚]C³\´P$‰YÛ'hhŽ Z ˜iK{Ô= xsh¨>4ŠZ±ý8p¡æšåbh¦ˆäT&\T×Ð, D3E$—I¦¥Å5Ds(ðàŠHîu = u •9 øNåkp!®¡Y.ðЧ·ÉÖMÙ5T…'âV(’kh–‹¼– ’ˤª Í54Ç/à/‘<·b®¡9.x\ GßeîQT×Pyhˆä)M¸È®¡Y.ð‚HÎ4áB]Cù¡Q ’+M¸hhÃþ[Ç‹W¢ï0°ëg–‰<'7‹^AØ£H®Ÿ9 $Œ0îõÜ;Ü\=³T,à8aÜ›%{æ š±€ßdDqÕ Åõ“¢xÑ Ù4BpÞ,½“³¡®C±€Ûdñ”'T$í¡Q ˆs™pA® Y.pY„ÉïE‚†´=4 ñrðÝÔ\A³T,P?¡š¢wàö(*”g©X û&Äðd“þ‘ëGB8Oª­”¡Ÿ2KÅIR:"ïÆI¦G¾Lg+òaßÄ»æ²o2i•|ÐDQŇtTe××x¯‰²k}|AÅ[ÌcÑÿ® "½y ½y ½y ½yPûýÚï×~¿ÞÝïr¬7¬7¬7¬7+¬?׺<ëò¬Ë³.Ϻ¼Î™u"?Þœø˜U¤8XE®È l,íQ¢Ii¯ugÑ m´³áÉãÇã†'Û«õÍðbøéù÷þ÷ÕÏÛío›¿ ÛõU\ß¾(ymÚ†›×[¯\ò£OØñç!\¸x [U?§[šŒˆÓXˆý¿#ÏE °;ˆj-j¥A¤2ü/.¯¯#'ÊÐ ²ß#Àzâ$§‘%PÃNÏ0wìrJ¬mÄŠ(´êwýe$6%ŠvèvJ^ᢓÚ1F€•ãíŠÖ½~iv°@;%8Gß’Ó#°*Ä (¶ý•}û/Ð`·H–jþóP×·WoF° ÿVø£USµÜ›‰­ÂÁ)à ­”ñÞA³Fa;N^U8“•µ\ÀÉ‚õ:ÙÆ^‘W x©b£:–µNA'²úU5>b512EzùÍÆÍ½EÄÊ9Zʧ¡“Œpe|Œ;à¡â'÷F|^BhR¢˜¿ÄC}ŒÎÊÕ€5“,jxÐ k„'õtNvEšÇ§¡Ó Û*c_uŒubµøB§‰˜ä6ö˜½Æ—NSVˆ€¶JZŽYìÉvô!¾çá7ý0Œ`c_Ç Ã è”¤ ëlÇ,öLcyÐËPB®þy,ŒñiÖ:¯rÉ~‰Ó1(á{îBñ1efì=üx)Œ6%=Í"Ê<úÏ£\<|‘æ¸zãÚVXÁXéjåNcź*z”Ö‹ F”gøv/U#\7x=ÑZOYêª`ÅC'"e/ ‡Ÿ´ê.s*­žFí¥¯JÕcÔnÀé…öÌYàÛ³úáiÐ*'Ê@Š”¼2ÎG$J$^N²qëîÇg}Y5Œ~öSóàÜœo¯~9¿>ß^m~÷:^­‡Íå»Ûóíjýú‡ê‡õÛ…õŠ6v<{a»ôZå~Zg盟ãÅõùfsB{ò\Ôø­!iiúYh/3)Ä$o¤ÝRò(ÏŸt¾‰×W›í§aÁ·6ºœyoî!tÀ¾—˜‹—¦*÷›œ3ö¼v¿¹^ó3ôûÉÿM К endstream endobj 948 0 obj << /Length 1103 /Filter /FlateDecode >> stream xÚ½Wëo£Fÿî¿å*u‘ á±¼¢öƒÛ»D­N©zq+UÔ:m`c“bì²Ø±ÿûÎ>pcjŸî¢ÈÚÍ2;ó›÷¬¥Í5K»ý4]ßb[‹ÌÈw|mú¤Ù–eºØ×Û6}7Ò¦©£PŸM½¾õáxf„`#HbsÂÑí=N=²”à׌úžápèÊÛ“r¾YÒBwT±Öõî ì‚&ÜP3ìÐtÃP2Úue7u‹Àq4)ü™¡VrZ¹ýtÄ?6\×E\µý0g×Åhõ¨ž‡žiRu‰›<-€ŒÍ°Ö=;ò=YR]@Y=É5[hÏ NKy”’ŠÈ]µÒ 9­Ô-EÂèYȰDö|²_æÅª¤é\MÓæë '©ˆý "„6kÂHª5¼Ð‡Éž–﹉ú«ë”-É7t¦'`J8KR•ÙÎȳ„Cô£ph¹…¤J ÂÔ*—‚¾H‚\&’r®È½vñ°w<+´ꑎÿ_Ê*s•€–vèF70ÆhºPÊ了BÂÒF+ *O«pìûÂö Œå(@?' õ±á(w}ôÆKV-^&l¢Çý)h‡èá ‰$¸m¹Aè«3Õ<åCGÙÊMBµÉÙêD <#Ú»±?î;Ju<°uuÃq$K:÷¹ø·Ðc8ÁÀã—¥Y%­ ðÅ'ò"•·²‚³¨hI’*ƒYür†V Hø–²›‹²9ŒÐwæqMà[ž?»7~Æ—áÚ F’CÝ,—rÆŠóVZnÿÕ˜s7ÚfäyÒ?—”TTÈúíñ¨+}esaÇoá”4[~{1˜‹) é²·µ¤åœ¾…íØ:Ϫo+¨A_† Û<ÂÌq–ÈÁâøaG–ëœφ­†3>r¨Š˜ndK^e=˳,}F¬ëÇeò™-IžÇñÕ§ûÉÕlV÷%t±U%}'©ïøPÅ7ŠË‹ÏW|ϧ3¾æ¼èÊ­ˆ"¹…J(Öj‘©RÛEØÍ»EŒñˆ[Z%‹#YuCëãvÅ?^ÍbûƶƒܾÁmAKÆC­èeÚ¶’Õ¦¨ØÕì °>LGÿŽlqöáuâiƒ?“å(žYZ 1¸8Ô^éRÆ H––k£ßO‹|µ:(Àó!ß2m?l¾oŽÞ6~Ô‰]l¡º³’0™ë…èÐ{û5Á¡i— 4‘ˆqÏ£Í/– ßS–”ÙºÊVÅ©±Ð ïê·ƒhä|\bõÉÑ(å6G©¡AõFæôü>î]£®\Å0‘ÊýS‡Î}}tfwøú}߸†^½Ü½Ô{¡Sîvq&Eÿ¨`eŒeÅü3)çuµSñý|&¼–^sÔ5ëvЫ4£ëœ$^LÕ€AX6/Hµ)éeœ,âh9žÜÿÅ›É;˜©6CSÍVáØž|Ï@ý¹qõ+ endstream endobj 987 0 obj << /Length 1231 /Filter /FlateDecode >> stream xÚ½W[o£F~÷¯@ÚJ)`†Û¶}H›õj«hµÝ¸}aó@ÌÄžƒË@œüûž¹˜` Ĩ[˲fg¾3ç2ß±µ•fkg¿.f—s?Ô"+ò]_[³Ä€ùà uRÊ©4©9ª CZ‘J}¥D™‚ìñdŸVyQ’t‚V˲ÆõúÂK*$À> aÍ6a vÚ[8щ7É )¯ùõÅWÒ“ Ÿ’¬&ã0=SÂÙ$UIŸÍŒþ-b…Ã[’TY‘0õ”œì¤wnØ8WfÜAñ¸‡²±J ¿ŒÈ× Ÿ˜4qONÇú{ÃÄ답²&3},æ .½¡r؆c¯ˆàïFHü³9©O GùÜ'/`ìhµ~͘°KôCКèÑ ™$´=ñ!¯Þ5sЉÊì[Â:„z“±b  žî]÷ö~ǨŽž<Ãt]WT>ésñÚŠè ˜Á€Ç¦´’§ ðÅDyžÊ¯hÎUT¤L–…)r>ICª5d¬¥ìý¤t#ý«§*òo¶gÃßé  ‹)»póäæ2ƒÒ3Z ¦ªÆ{ÕOòð^¾›vîIÇŠ(ÇŽÛG;[éáG‡Œa[ÿ(ÈŽês#€¢lxp_UuÉŸD.Üðq!R𝨰™(õ¶;ÅLiîaÒÈ,„T>^¶,é¶¢E>tW;#ÅüKeê¾%Ü:Å ³BY$®µ‡²Øì‰Åpx¨« 2Šä à$JqÉÏûß[ äO–¬È(u‹(Ÿ¿{wŒmë·H>Å-‘Êñç±|ÐäËyÐae°úcß=¬v0‡Ÿõ~Ò©¤Ï1½»?ªgZ[9úE>æW7·Ô"ÐÜ»S¨Ûï}Ü ½ÏTÖ<gm~æœT´£¦ª1 ßl„IÉÚM¾‘Ò%¢Á¾s¯s½O•¸éµ$Œ)D<÷Àø“&Nb—ü<¢H¯GBH]Vg•š,#¨ìNð_¦„¶BSÁ½Ï”XS~‚ñC4yåÿ)±Ã5½i—9-u XE« ¾…îaþ¥¤Jh6zžfóÝÿÐoÊeϧèkôõ”D¿îÁbj÷vh¦‹€©XÈü5/*9H)«àB¨)[ˉ{)W½ÆÉåʶÀâyær?sÖŽ€ÔÃ0ç¾O¥XKA™âDÍ6·ÙßB9®Š3ãÓŒd¢æãÝšð€ä]â¾ñk¹¸J;£öüB÷l]Ô™ZQ6Ë—-Üœ$½P/I˜Z¨Ù´È@7E‹@ •k ÿœ× endstream endobj 1025 0 obj << /Length 973 /Filter /FlateDecode >> stream xÚ½V[oÛ6~÷¯ Ò£€Š!EêìÅkš¡C¢±·Í‰QUH–'É]º_¿CQÖ|‘{Hó`ùðvø}‡ä9E)¢è—ÉÏóÉå`($¡çxhþˆ¥„ ùŒ‡hž 3j-æ¿^ÞxÁÖÌÈæŽà!ŽÈL­+Ù¼+‹B.=sB;ÿà\l-¡Èv|hqãöw+ô°Ì×jgÍÖÚ`²Y@x˜Å7VÀ±’ͺR–Í9Çy)“l™Ö¦õXVaæÔ†ðwp³n„íp¬Ù´F’jYgåò˜Ž¿t#ÛtmÙq!ŽÌ`ž)pOóº$MáKI€*Ý4æ} $·æ{¡g»¡g‰g–\oÉÜP¬T²Žè0ÍòÁ²]QqóÖô|µ -ó,ÉË ð7þn¨S¶ÔCªä–«B5ŸK '„'p4Q}WÁé){¯á}|ÐxvX•?¨KádžŽž¼£Ž#¡û_„ÚMí8—õhhÏÚ%²\ïü«‰è·õ/p‘Íß+\†¼ŒWÚ©PUª¾û^›KàšK°ª²eó õ]¯×µ:y³Ñ<óþI«\ÕGRÌAžõQÎ<Ñ'Ÿð°óµŠ%¤JñO¶ù_=ñŸu!ó<Š.`ôb±Ðû´¡£º°_±+FßšUìÊm§MÞÏ'MX ÖWRâsŽâb-(J`ˆýÝN-€sñ;G³É§£tLIÛI—˃Ó>'>íàW-/Ü=ž@P¼™is7À·–Ëp©?©é¸–Ô–§º7î?ªKü=¨²ŒÃÛð%[pA]úRu\e«6 ÿê:Õ‰<Ž5xS =(—UYtiÿh1<í`ymkŒ‡79ý¹Ký[-Suú>ÎíÍs%gÜü·*1v+´Ñgý˺ýqˆúíݵƒëöRÎS”uO†²8%0Ó*]C5·¸ƒ›ñ'ÿL`žF«í;޾Ýg¦µQqÈÔØ–ðØŸìÈðog' Ÿî„âRU>š;-M3î_x+'ScÔyy8µq0žó!]– ¹N9ÞgUòØ‘Fƒµéʲ…xÖ1;S·àØÓ¥äœªƒ¥'ß8ès±ã8椴±PÚŽ~Ê0Õaœ)LõÚFÊÇËJábr]湬îàÞÖ¯³ï^Nº-ÓW¢{1^\~·•«&y•áæ¬xŽ^ê—]q‘Œˆ®»²+ûGiÑAîï¦G$x‰.bXCê„lz±ÄÊä_%cØ@ endstream endobj 1057 0 obj << /Length 1063 /Filter /FlateDecode >> stream xÚÍWmoÛ6þî_A JKJÔ[Ñ~p׸X‘uØâ Ô|P,ÚV K™(;É¿ßQ”Y–U;HÓÂ0x6É»ç¹;-EŸF¦£7×G \ËEÓ9b”›»ÈcŒ¸v€¦1 q’±”‘aùøÁ¸š~~3ᬵ‡SF<ßÕjÆÔš­mœOGÿˆ±­z×óˆÍ4[Â+Šb˜üŒ`*ðÑ]µt…8 ð¸Òš¢ËÑŸ[}ݱâÀ½6F‰ ]—+pw8<ì`òAkchz6§xbx.†ÃpT® 5 ó¢6Â`85LÛññ´ô1I©í§Ê}ÂO!ª ñž ¸ÅbšÐG!gEr[&y¶Ãé‘ÛN˜LæÛ÷õöO¢ô¶£,VDzùg.oa¦b£B.Rý÷J)® w`šÊ†å‡ÚÚÆß2Zˆ^p=`½°¯^¦C)¾´õP–y¬åy^ha–FRjXÛ‰ªš}]n› ñ6%º{z×S@ÅHà8Õ}&gÚ6!¤–â"¿ÕÒ{=LÆ—çWWJR`Ù$`V\…¸M£™X‰¬ )“EVÅç)TÏÆ_þm¾Ï@ûæ‘>0¬Äw¦7Qº;¤ÙÏË¥ˆâ¯Ô¡÷5£l'†Œ^<2…el(š?¯2JÒ§òúiºJ¤L²ÅvT‡Ì‹h%^(k–6K«‹5xÀ°-\ÊÁ÷Òvß¹ø®£<Ëòð¸©ðð!>*¨ÿÚÓVºïªëhV%?¿Ú¾³²»¸ëJ‡P›kÈÉ¿¨PUPòyÏ­âáæ&‹¥’ʼÙUÎÔòe­¬¨/­8>0z²« ÿ¶ÈòBœ¢·ªõƒŠ_ qjüö47cÂͱ8X}X¶Ç`€™Ò<1|Õ-´‚ÊOŒ^vLº­WÊ8¤³‚P´3ò R­FÃ[hŠ\m¹“56Ãd¸N:¹ÔSÇ‚ŒÀÅ{î:òð‡aO;â·†É9ÇӥИáè… ¡ò´:9õ!p¶ªÄ=¶R˜4uüÌ}¯U°NŸ…ð¾o}eá.)—ÌÛ;U–íÍBvˆ¸>ær˜Bïþ$;ªU©Ðx5:p´¼£„£‚õ·åAòÙAàí„äýuóÝø~Õ á/ü©òŠT^ù1_ª”š6q*ó§<{6ÐY–…ß³ðÓn_„ÐXÜÁÃQç:‰“R¯£Õ×/&¥2 a)ŠhV&à5x‰UÚª†DÇòíI¥ßð/=ïT®š¸¦CÛ‹áÙ)F»Ê„¹íFV×S5óZóF{îáÙ”wº¹_ È(QÙúãz¯}yfwq¾DLâdõýÍpe&ƒæL¾„­•(â%|'oÓ¤ü¾†:(××Rar¯@OGÿqú¢P endstream endobj 933 0 obj << /Type /ObjStm /N 100 /First 919 /Length 2250 /Filter /FlateDecode >> stream xÚÍZMs¹½óWà˜\@|t£*×Vyír’ªM²%û°‰ÊZb%é"©Ôúßç5P’×ÔŒœ¡]¦GlÝî JpÆ™¼!Æ#˜âŒ÷ÆG}‹Ægý‘LúÎ&¤bŠ&z2…ÄPÄÓ;“ˆgíDõëÿ ‡>¼cÐgÑÿz¦!OE…b|" KW:„ыς .…Y¡ˆñêHÄ[JÎÊ ¡˜ÀÊŒÿ°D =e4O ­ÍÅadÀü\ÝH`Æ2.œ dLØB‰øON&:tZ`–ô'Ì<ìTęȌ1Å›˜tƒd̤@,YfEȪÆ‚¨N2D^X“ö“ ‰dÌ“Á0•ŒVÙöÊ9 ÍÑp,4KhÉÑzÌ¢­Šá7¸ŽSB‡:â`bü"°C)èFiA7uÆ… è´ ÆŒg%«ÜÞÁßÉBTŸ9WàbÌÎ;u¶ŽÉ›$° ¤`’Ƥh>S‰Œ§ÝÁî)Ï %#pÄHªñO þT*FJP Ýg—u4Ø;øR0FÖÁMæXq&H¢Ð*§Àº9Á1&Ê‚aÄC©R19;U‡ƒ1w]µŠÓÙDt«î‡„j1H°‹utXÕe•²Ÿ±h@@‚³¶U/¦¬ch”çXE0ª³!åj¬*îaë(¬Ã“¨cÕgг/fó׿¼ÀžÎœ™ù/û»zÁêâ¡Pl‚÷W·××ïg?üð¨r”bÕÇ£”ú¡t eŽ6»±0ÈY„ß(]¤ `áÊoÖ«yñÂÌߤŒPûfoYÑ×^/ýDqÆòh¿`i×^4”¢ú‚Îç?oÖo—;snæ?¿~cæï–¿îÌaÜwŸ?-ñÃâãr6 ËÕn‹©Ígó³åv}»¹Xnkš©ÿúóòòjñãúWs®ã%¬#¬€÷f±A[ZÓ{¹Z­ÑÕy͵ŠEsm}"D÷OnÏÔžÒž¹=ËþI­=µöÚ3¶ç¾¿/¦TÇŸÍßÞ~ØÕ÷Ÿ®VÿžÍ\o.—› ݽŸÿqþ§ù«s__t²°RðÎ&,4,Z5ÛF±Œô›$ZO z/«ŸÞšùÖïÖnþÝÙ?Vöåv»øü{µø40rÁp‹dÓÙjÒN!…ñÓâóróz±[LÅ|Å_‡àDí³Iœ½¾?+’“Í”KH>ÑjF…-–ëQ(öìr}m§vQÌ@ƒt4D±FΚ ÛÚ‹ëÅv;$"…tg öˆ–ò4HÿY\_]^í>O@$Á2Jn¿¤ù9§ù÷uiþ×”9“#UÖB ã”õ,™hzݘ½ e¤.ØJã8eÝ=¤4RÙ#Êcþ†³áçâø^n¾ ùõcÃ7²ü¼gíõ{Í^hçÅõkMBbz+Ï]H].ä.ôžCï9ôžC˜’ë7Z’ôÔàJPë‘mþI«õMHHˆ+õà6"XÁ®-•ã¶žE§>që‡ÈÅÕD¦{Y‡WrXtðÈç4ìÖ=l ;ª HŠØ»?Õôü6è¹Òµb,͟㿾  ȋrCžõÜŒ2ÜÔd,¦îLsî4{J9=žר:Š~DmqÍx¡£p>m®V»“§hõ#~Ç£­_Éà4Ry:2=2‘ŸÑ;ÛÈ|<%¾]Þn»Wë››ÅêrÂPö ÎWBçôºèùX¿HdICþ¡"Œ²t@f6ä‡Q½^__/6©[·akáí‘¼Þ (úD¡=¼y¤¤}< €"æÕ… Qtšó ¢pNSM" åÐ(` ¥ïÐ[{}µÝw!¸b½á2–»?T"ïG´Ù[¥oã´[i½>2N›»K §ÑÆnÑq« ‚äÆ0j×iì$5ÕaK1V;`¥±“ôµoù?þP/Ñýf—Àßú- Þ\Ú3vêÌŸ:ó§Îü©3êÌŸ:óçÎü¹3î{ î=óIî‘D$¬p¸G“Ø\â³Ý#ñzp[jˆýâ¤wcЂü\Çí ÝÇvÈÔîmxÂŽ„Òwº·ÑÑô{ChžáÞF‡Ôïm<ÒÉNÙ=ê˜nm ²YŸù{ÞÚh€€8šþÎV°Þ3®(”RjæBqŠ ¨©²Áž¿°Œò•ëÿ6#Ú endstream endobj 1072 0 obj << /Length 937 /Filter /FlateDecode >> stream xÚÍV[oÓ0~ﯰƉDŒ87 ŠXhL°•*ÈR·ÍÈ¥$i·ý{ŽcgKÒ´´ˆ4M>Ïå;6AKDлћéèå„Qäcß14] J¶˜ƒ\J±cùh:GFM}6ýðrâx-M˵0umðSë—e¨›žö` õQA kÙ¡aºðÑ’æç÷aºNxٱܷ‚Gy`ì°³‡ êbf+¸Eê†MˆöÊëú&¾—i˜$Apvu9>›ÍDðe˜û`_Û=“ÚŸ6I"¥jÅ¥À³*.”¼àaµ)¸‘ð-Wz)¯TÄy¸+-Š0åMï=¨’_Ü6¿j‡¹6ö=·Ã;¼áø-ËÀp> stream xÚÅWYoã6~÷¯v ”"F”¨+Ý>¤9XØíÆí‹6(d‰IH–+Ê9þ}‡‡\Ë–yëºÓ&9óÍpŽolãÞ°“_¦“Ók?4"ùŽoLï bÛØ¥¾‚}72¦™£8Æ—yù•eËÔ¼~:½¦dí µ BÊÃÄg&¶V‡éÚa«=m9üèª;˜‘’bÉ:W×DëCÃ"!vðE×*Fg¦E)EÓfZ®KÑKšeͬÂ$ˆ=™N€X!v\T²&Q«,iWwU­¥®«Ž¥¤\ì2‹xØv‚ÅkŽ>9ÚKßy©á9ov¨wÑS먞«.J²Œeʆ„›Ð{?Ÿk´î¾ ·|E•¯¶åo¸å%Ù¨çùf»´æÍN«ç;וøÌ•œên~w$þ&É‹!üM‹¿H ®Aÿ $)âx˜Ø¾²â† ”¡‹Î ^íÊ12cOži9ŽƒÎ9OD꼪¯ÕÌ´<=²´9_¨‡žLOdržå€üj‚R¹EQ2ÏÔ-1Ѱ:I›¼VÍÅïÒ®‡ –Êø™F 84jR-¿nÕð`¡°Àöêu¬äßlφÒûˆ'ûhæ)VZ$œo–¹%š¶¢Ÿ”ó^&]4Á‘çé:u?AqÈË£¼è™'%ãG1ªdõ=;Š&¾(òæ(äËgcTM®¦“¿&D $+šàQ‡1ÒrßÚF›Ð±…Ƴ/D¢xzêëU93á3=eY.ÊöüžØIìc¥²†ö0+¹˜xº½\2žÖù¢É«ù÷”å/ËB÷„”µ+VŠÂ …Yt °MØ¥ºI]•ª¿$Q¢$›s€•h±µðøηÏï<¹ï'u{’¼÷ïáùlݸêSöŠL­W“‹UY>½º=VìþØ×—Q—Øv¯õ^Ù¨§/qœŸ(õú3««…Zý¬>®Ï½¹Ò›ãÛÛÁž­Cã¼¾_˜®ƒ>èÂ]®Ó‚^[‰8ÐpÏ÷j·;r°‡Ë®q„ÍÛn¥˜ª@ç#@_¬b^öµ± î<ËSAõùZGh½l3CéË3x#Hµ& –Õ-…«õ¶€±=ƒ0¼@_© ¯SAí¢H3Ñ(„LåË¢Ñ?VÍŠhJ:Éõ¡…”TqžÏ }l•þ?Íu5±eÂ{Šô¦9â”La¹XÖ€UÎ^Fàã(tºé–1ÁÈýi­î­yÒn…/Ó@çœxOý ()í@%½)bLBl¹øƒz‰ŒaâoNºCåþbD‘oã?¯Uß3J¢Þi|çHóx˜ñcT@mºšxkûÀÓn t—»›zÛÎH#çm¾o4Oå*fÔHÓŠZŸgö­¯5Ì~¬­²Ÿg[åó€Lp££µJ>åP;üGøÁç!?B;ØáAy³°C 8ÇѤ¦ŽÿZ×F ,ê|ÞÁ@êz©l°Ð\½$å¢`|<ã A˜OWÕ%Rïh¤‰bl,õ¹˜•韼LŠ"ŽßÁî;Åã¤ëlp]´ºÇäŒØšð‘3OÜ“Æß%ò$v endstream endobj 1138 0 obj << /Length 1522 /Filter /FlateDecode >> stream xÚÍX[o›H~÷¯@êJ R \f¯¶ÙmZµÊVÚÄé‹­&fŒ©0¤€ôßï93ƒ ˆíF•3—ó}ç>ØZ¬ÙÚûɳÉëwÄѦÖÔw}m¶ÔÛ¶<âkãX¾7Õf‘6×bÜÎ>¾~燕^@-gJá±f>·®ù¦`.ØJÀÅlòmâÀÐÖœÝÙ~0µl/ÔëÉüÖÖ"˜ü¨ÁÔ4ÔÄÒµF@|@<§ÚõäïÝyݧ$4 8¶å%ßw-Û!cà€Ð´±snú!±õkÃtôÍA]=¿ûÊ ê苪4L†:Ë"9ø“§† 3©y‰ øÿ{4Ðÿâ“KÞ2¡¸~ìø§è@r%=Æò]j¹®âú–—‹"¹¯’ÝããAŸò W¯@® ¡îÉ'Ð_å‘/QO8X¤àVÐ†Ž³¿öIƒxwSï†Ú#| ëq>O¤ì7 WR–IÿÊcmy&g,ËR£¨ÀÐklzw~y}¡&3fëÃÙÛÛÚ!]²ÐÏ©&+Î"$ÿXSjÑqì˽F„¯ÿüÄ”µ+–¤' Wy^ÄHN†çêU9(C¢ŠÀãxì.äóÿ'+™è.+ aFuË ”Ÿ$G@þÄÖ\%ÃåP2$úÚ€‚^gÁ¨®âÇ¡cãðLJ8Ë¡jœp®ˆòуi_s~ªUNÞ™KÆ1 ¹+¾ÎQ[,Q|¯fÐj)uú½* ¦ Áì¡”ÿ*ìs9.Wrê˜0ýlL}`·áÏéÏ>!Tä"á Ä+y¤Àg ׊Kà[ƒ*A5¹>}BŸ)£§«'ý·n»L[6ä²@€sTJûâ:ö íÉ0NáÕ%ñL¹H×w–Å.Ġ甫hÌž8oûÞÕŽwý'šÔöhÀ†4ñÉäCâ]ˆ–ÿKN8ê&.|' áH*GèºZ“Àuæ`Ri ‡X‰j)2r÷Róa&²û@¾•çvŸ]Ý\ôz×¾5=ÕT2ù· ´Ãi´e9³ô£ÌçCæs§0Ÿ;æÃGžq`’ÅÈÿ/ÓŠlQaÂÁW 0®ç«¿à¢LØL¿lH àb…ùH] ÚuóF€¡w(‘$䶃û˜<¶¼GñEòÅö&|{'.J=ºé1½Pä>x¥ÒX)°«H9&!DÜB…åQtQVƒ… ÌÍ\MF ¾,Bu è)ÃÔ²i¸ïÙŽ‚ÕŽ•h…>Zv°90=¨çi™?§ôŒwˆÝ÷uQÛ»ax/:mϧ:‹"Ô ú}bN…7ŒTxÃHä„^ÕÁä|þ»Ùk‡§îïyÀo&Æ/®BKÇÐ DøUézí\”–õ¿Ø5`MàH-tÇoøâ»æ_ëk7Ãö þ §àaÁäëND©KéºnS» —ˆìÁ”DI…ˆ¾!ÑÅ,•¨qc’!_È©L~‡/Å5OðÊSšbÜûKßçBY²ìÆeìxß;”ì¤ swõ,H§M룷,EÅ}ÿa§w|m|vĽîtÝ4N>ûtsyù#w=üˆ÷"&9¢{ak^Äü$Qý%8u\ ’WÉ«#dTµ‹Ùä_õÂò endstream endobj 1165 0 obj << /Length 972 /Filter /FlateDecode >> stream xÚåVKÛ6¾ûWΡ2`)¤õ4¶Íf‚t×9©FKK´Ì€z”’²›þúv¥]míŠ h )r8o†ß£at3ûi3{ý.JÐÚ[G«möˆ`ìùA„bB¼È_£MŽR'M߸Ë;ÖKÚ-¶›_^¿ ÈàH€‰'>(ÔÂ$T23lM€p0vÒî*†Eßœ¹~ e#X;:ùÜc”Àá(Ð'È%±„‘Ñõjá†;7¬3“îÀÌ$cB¸‚}fÂü—¬£9í¨ùûg¶—´dʰæì­C ÃÑü7âfWf¿·%"M·[X!GéñÖàÏн°öÚ†e|ϳ)ë¼Úײ¤¯«K-gja.X×1éñœU];_móBÖ}ÓΕkcÏ)=ž´ŠrY7fö£6·¯'Bާ¡·ÁµýέwŸXf—•QVxV¦2%‡ƒœ¦zë[lÃl§ÎUÛÒ/Sg¦åµ¦Z¾ÐÈ[^Þ²¼Ï.·ã<óÞÛ÷Wóíö¬X“ÑØDU=­î=—­]#ØŒ²¾oͬޟ¹•Ç™Jê“ ÿ­KåbÚ¥ÙõföçŒÀŒÈ‰Ä‚{+”•³t‹Q[ Ñó× º×‚% €åâ@Q—@w³_Ÿ¥Í“ïO‚_Ð`ø V“<9`¬h=8 …—عZ„ÄÉó…뇉s×ïÔ¯º&j̺ö_Âò‰‡Áëf&ˆ^ñq‚m&ß²6“¼9ÒÐõ™_SoÔkiüj±JLD1Üú…Kˆ ˆ‚äFŽ¢€Öìf`„!£¯ ³ÆÉÚŒýø Ð/Y¥þ©0RÝÉÎ Äku¯õz %'Šc¥xAœŠIþÓgTUP¾ah«ª6Ö¨ >/A²@ÇéíÍãì§p€8“™”jÅ:úPG¯H/‰t¶]°Ó'2àC­ÜÇÌÍ ˜ °Ñ±ÀÂ=ï/sCužw•VÖ@I|*… Ǧ´;ÚιÅã°ò„W“¸؉(Gv|ßyö1¡¶ƒ!. -¯ ½AVx•³FƒÈ”§ÐÿtÚ…m ãG‡*ÔUäáØ6ª--Øå‰Š·7þ•å¾»ÀòkÍ”mw¢³C[ŠVQè†È‹Šv½´øÄc”ÄSÈYÔ–ÙJšAÛ_–®KU,‡=q¤lRÑ£<=¤)·ýþ“=σö£§o\3~¦¢?½ŠV>°?ùö ¿6ß-ßi!ÜHÚ¾ë:xÏxqØÞ¼—ƒý@0?×e©zÚ×)‡'ÝžoÜôò endstream endobj 1067 0 obj << /Type /ObjStm /N 100 /First 975 /Length 2292 /Filter /FlateDecode >> stream xÚÕZmoÇþ®_±[4XîÎ̾F`Ç®ÓnkØÐV2PJ¼Øl$R )Ãé¯Ï3K®,YbîäİÍ9rnö¹Ùyßó.qÆ»ÀÆsQB ¥lbd#>›¢ŸøGÉWÏ&„ D1ÑyÑ™(I obá#dR†SVæ(&se&§ÊM!V9‹(sÒßs½-O>*…KÄ^r„ð„›B•å<@˜^Ä*+a­¸†»“×¥uµ•å³ÓÅX²>²Ë‘K½T‘pä½ÃãV—½!ÖÛ\&CTS¿Æ¨R2T•}¥‚¡²• »BJ±>DΆ¹>4žŽƒÏxŠâ ǨòŠ7œŠ®Û¸Ô; ”®%FÈés”`„«æK4œ(•°9A%C€¤R©b¤pÖçpØ3åM Pc0UAл âE©ªBaÝ[\rÐ=®7bÛƒ‚v¢Tþª8,à±@RÀøª.åÉ„ kÁJény†”R”ÂŽD*•/Âj¨Þ›L ºAÞ«ÝÕÕ<Œ+3lÉCç±Ú,Â$… öE\¿ƒqÖ{IL ¤øðœ)¦ú]„ù©axJEê)›ìësS1™¢` v&qŠÔ›\7Ò3™¢{ŠÕRõüW8U F %ªÇí Eí[ÏT‰%UE‰7%WE Äæª(ØBú°`.¥ŠÝ^§fæEw¿Ú€¯&¡Š…Òt×IÙ|5i®újopÏ£GŽ&o~¾ìÌäÉb±ÜM^_nêõ‹ùâ§£ÉwËÕ¬[;¸¼{;ùË䯓§Ç¾^M^ugs,ž¬jz·j\ÙuDö®'æÑ#3ym&ß/ß,Íä™ùëö¢[½ëì“õzúóÍ·ßáïP2Yõ¢-”ÀÙfUR”õåù|36بeݨC°e©X5Qü³Äû¡\®»{°<ƒ@"Vxe&ÿü׿±û–±ß‰Ä8üâêüüí^fXEåŽ)YÄ’Ãp TýÝq3Û€Ð?Œ;äb#B÷0n.øLC5H!ZÊCqûlAì¹Åý|¹ØT»zŽ|mo{ŽXŠoYÛ/ˆ’¹Äö‹à·»@4,Ø|½€ðÉËÕòìu»6“—Ïž›É›îãÆ¼½í*/§ïº£ÉS`蛵æÇºŒzÄzyµ:ëÖÛœY¿û[7›O¿[~4Õ‰"BU*¿x9]án„ϸå«þ·Æº5Ç+œšâ•x;ާ’w6"K’›‘'öƒŒgÈý~_­NÆ‹„8ê4E‰¯ŸË,Øz¼E²Û‹c¶Z^Þ‰É? VÜd¾ö‹‚§ÿܾör£|°$ñ0Ü!Ø,å·À-Ѧ2˜Û‘¥r’ Ñ}þ|Ë…o;÷M¯½åܩֲrŸ«àÝÞÉïöŽy7ª5¾ãÞÙïÜ;S#¸҈Ј؈ԈrÙ;­ÔzyG4É¥I.Mri’K“\šäÒ$—d-“w„31G›Q1¢B¶HHIIŽ›öûj¶<·£Ç#.¾úÆF8ìG³…LÓõ{{v>]¯G¬ï"Q€7HAs7"åƒ }˜žÏgóÍø¥b4ÀÁçJ=XHdy?¨ãÑ7Ìë‚ñBÀGGÛd6¿?—1T‚Æ¥Aa/VçýPÓ‹n=¾-S²¤†Óðd”å¥Ï&eD0š4Ô70‘è¹Ì6eL0¨òk?¿„m±ÌFeL»AíÅÁI@ƒŒÅYÚL»Hi/œgó‹WÝìêlD$.X0ôáͨW,ÚvXÂ`毈D´DNdv6¨n"C/^ýkpM8J€#|DE8˜Á©J*{Aüùâ´›Íæ‹wë1“R¶‰Šu²uˆòI±xÖbk/–§«nºéÚæüãô¿6~³~/èÐ]b\)ýV{˜d‰d‹Ž·v¨(ãµÌQŸ/) £¾ÆH$©Øñœ‹š.[î°ìH·=P4gÀÓ }²£kãîA³MSããif:4èÈxgÖõóW‚Ïåj¾Ø$$³õœ¯ñP*V zàìRÕ}x´ÓÙýàVùso«|?·KV':øƒ€›üa¸5ÅÁ̆q „xß8ð~nQã å¦"–âP}SpmÑ0f€°Ìå æd{ûêÑ;iÎw;iŽ_ÜIë‘ɶ=õ±©¹­—¥ÖË’o5‚!h’©I¦&™šdj’¹Iæ&™›dn’¹Iæ0j'íA5‚ÕòedÄ×ìzFz#&у‡|´èÑÕc6?hv gCrÄeî…q€|±r"u2Ë%jkÊi Löç·ïWÓË÷cö_é5^ÃЛK?Œ×ÝÕjº¿ÅòhNë¹±uF¤ûõõpìÏ:o*ˆÂmðÌH¬’ÓWj2ÚГWìè vÆê¤”tœökc;0['ˆG–õЫG}¹ Ç£ñòÉY ¥o76ø© »Ù’ÂaB™ªÛ=pŽíÊøoƆ$…¶v*gÏ>Ò7ÿáÅ‹1G=d5##ÙÔcŽbëË‚è+ñ«ï\B“Œ¼×à›\?œ-ŽQEUt )xì âЃ lŒº=»÷I¬¾ÒwvÿÉšNN®ïO—Oœ¸““Ëùìôñîâ§nµØRÿ{¼ý<{?])õŸ““ËÕrƒõ·ßߺ8了ËY÷xþcý¼-îO:ÅKÝÅÉɪ;ŸÖµFC)m«Øª …N~Ÿ:ùM@7ÒPDÞ¤ö¶ ë䀹wwtt0z!­šï’Eòi’Ã$OñÑæ|ýFc…4ð ñӔεs{%%x(ýXTT|öNPFŒøFÐ](µãåô€ÙÅMæO/ùèêé0Ü,¥q£Vö© äÙ#éÕ‰±R†"©GŽr{TMEä ŽùüÚØ‚ö4ÿßl"†»³‰È_>›ˆmĭßs®UÇ\Ï´ Rß“ýÕsÑ#1ú„zX³ÃÁ‘†Ð‡ãøø3(¿³$˜ endstream endobj 1202 0 obj << /Length 1145 /Filter /FlateDecode >> stream xÚíXKÛ6¾ûWHR€¥H"%Ê@.Û¦)Rltíä¢ì±¸^-ôØJ²“üû9Ô®-K~ ©›C±Ê"9O3ß̬g­,Ïú}òËbòò ó­™;‹‚ÈZÜY¾ç¹”E÷}7¢3k‘Z ñ#ûvñÇË7Q¼u2qh”$‰í“W¶ãg Os¹®E;}÷þúZ]šxFèáÛzbË 8ü¤¨âÅ Û =Ì®µ|ÌÅR²lñE!Ûû*Å绪Ƈ&[•¢]×íãþŽ}êÄϸ³£;éŒ\Þ‹Z,[YO‹¬i²r5?Š6ùÛB¬eÊó,К…!ºò%I²)Ú÷`V×uooññ•ƒëFäk£‚±-aŽF&tcXµ¸«zµl¶Ù´¿@ìÇ. /ýﱋN®Ìøsc«VGññfO<|J ’‡%SÊHõ ÜɃ\¶‡ÂBAº<ŠÐäì“߉BÚÚ–¶ÂU¤©­•6kÐÄ;ÊñDsŠx8Áˆ·«²ªez†k‡åFgÊ5Ö>Åո俴Fbc0"ÏRü9‚#½Ð“Þ+×vƒ+ńƆî˜aÞBê¹ÉÈ&º)šFØ`ÛW;¦djwÒpï¸Ð4+À~Y6YUнh×Ë6«`£ì«ô•Ïþ)úÁžEdös²r e(ùœµ÷Cì…mÑÇþUÈ™n‡ú`îf§87—*»ñ«¼©Æô‡äÏœ "÷²–{ߢT3½:ð¸Îs hüѨj£#•c¤F:RÜ]+&všùª\  ñtÄF~ÜF@Ý˜È‰ŽµV¤¢øbükÂÍ$²0lìÇD”é·a¯ŸÊ”! Z•J§ ÚÜOþgHU•&š–2Ï\nÔE™ã;¨ÌÓÉx{8v阷HdqH»¸Ñ•Å ‚`Û"@$`¬ã-@9K³Ö7Ñ»!Ú«.f¥²*¼Pi^âKÝJhOÓæœz§îþäT<°Vñã_œ\ûZÀ;Ôá,s༃\~®è°½QœŸµ_¿›ô^”$J…Òô@Ëù-â¡·…šq7@O mLse…¬WòšBr ŸzqÖÈö“ß“¿'¾–ì?=tB劬e1In=+…M N—Îbë³>ZX ÔqFá9·æ“¿F»qœ­vJ¿ï¹xJ9”Çnð9ÁѬ_ú=rc‡P\Šj£*s“9ð6¼©>=Hµ"k‡Ü°6øUQ5ìäε¾ºÑÔ "uÃÙ׊ºÇa‰"7ˆØ9° ûl`´¤”»ÜcèþkÙ,ëìQ“ó9Í…éNnº"¦ V¡yWÆ 8ŒU2˜À6³kUÌøS13ˆÀS‡Èhƒdú›÷™G#áÄNð» üôýoF_~Þè«8­Ñ¤†ÑÝöè»Ó÷OÖc-ëº×~W× ØõsÖAæœ1ô~çQšÿK£ttÞ(ýœ1?Þœ˜^«w¨Óô÷wµ­søñÛ{óÏ•.ŠÕ¾¢Î^0w+”ÊÓ¶ endstream endobj 1237 0 obj << /Length 1151 /Filter /FlateDecode >> stream xÚÍXQoã6 ~ϯ0îLjײ$Ëö’í®‡vÍö⛫©7;Él§Mÿý(ÉqlÇI´ †¢"Qä'Š"?Ö1f†c\~š .¯<ßìÀs=cro`DZ õ ޱí‘À˜ÄFˆ†ö¸("Óõѳy;ùryEqc u°Í} •0æRfàT&@˜6„­´år˜$zϦE|‚Æi±hmo¨iÚľaaߦÛízüؾ‘Ë=zøýz`„q=ô rÑR­æ9º_ä¦X®Ò4™Ïô—´0ZÝ™-àƒyèo1- ½º*¤ voÀ£0ìñRˆ.^ÂÈ_ÆÅq‘£ÌÄH”Q•‘žxJʇ~P°3 ´öÀ‚uEóøu>„i˜² nÆô½Ôh A…r¦ßu&¬ì‡ ‹{`KC Õñ³Ê£ô»nÓÍ¥=šŒ¡(w%qRš€÷Ùô)R«L\mLæ2ÂK‘GÓ2YÌõd&ʇ…ü³ƒ]îÚ®¶ÇÐsàŸ%»VàtÚ†5M£¢è¾¼W©fÕQ*÷üfÚ;a†gq” ¥‹C¯÷Sœdg9Ø™G™(Îb,ùLœÁCç8S'ä ¢<Âæàódðï+͸®ŽÌ'6èfƒðÖ1bXƒÜg“À7ž”dfP°Æ©,Š©q3øu§ž9Í ÜBбc{pPæy¶Kš¸û½ åJîS}5Fѳõ‚ùè“,ûÁ¨ >å/ía Ìe6v\ ø“(¦y²Tyôär~-J]Tj&„¢b3“V,þ¨#ÂT\±K4¤N€¸\ký­ˆf¢L8¾ÜÇP^Ýý© D¬ÇªLËAŒ/¯x+dÕê}ÕÕ7ÜÝÓ+߉çõ0Ù`—ØÆý`s±L£©Èļü¿¡Wº¡Ö«O¨8+qÌ¥ŽóÙ Nc•ÅÁË=x©ëƒÁâ.p†ñü”¼&#³ïÍv4ËàV„…)ÂÒæû)OräoXõ#YÜoßïy?jT.ôk›m^Û¢‘ÏïxdõåíGÇ”Cµò,*ódm¥É? •¹ã“6 ”Un¨Øc…}.ž´@;CB¿›ðê.ä£ÕpdZJå×MÞãUÍÝ%2  -÷ïã¼õSV^ÝØÚCßG½j$ªuŸ¼B¢w>¥Í|º ­ù0ñΪî•¶×tð˜/ÝÎ+;ÃG¢iü¶…¯¤^U=‚ŒÝ H90Yµ­o¸LÝ#ºGàÐ#ŒNJ~ “Ä»°w­ùÍÉ»f‡?ç"*…2ñËÝNêz?âö0¡7%¤„ËþVd×p3š`ŸÁ–îÞÝ‹Šeš”ïk¨¿c8ÆäÁ„öyeËTÇ3Q”y´ÎmܦN•ÝòyÔæMË»lúg‘Ei†¾¸½­i!œW*Vx%ÊéƒVzRÝ9Èáö¿2œ5 høWÔ+hØ'ß++}ë€oƒúCYvB<ÂÎ…¶G´ÝoaÇñyïÜ tRÿ+bÿ) endstream endobj 1258 0 obj << /Length 833 /Filter /FlateDecode >> stream xÚÍV[o›0~ϯ°ÔH3Ò ø†!ÚK§®•¦iÒÖl/¬4”K¤MÿýŽ1I!6©¶hŠ;ø\¾ó‹±ÑÙèrô~::½ày–çPMçˆØ¶Å¸ƒ$!–Ã<4 ‘‰k\O?ž^8nK’IfIê‚Zfl•e`P? %=²à@"Ô®ÔL&D­gR ™Ö.²`U`˜Â¶ñ;S¯êé,_fU©,‚5“Ø–'¼®ŽO&Ä~«5È„_×Þ?LG¿GTlD6A ϳ¨h–Žük…pV-æ¹è¡M‡¸%g°OÐÕèË&ŠíU3'ÛÌ6¸®vÖb¥Çˆãµ}S2nãO† 8xŒ (rñ¹bcw$ŽkQp@$1ȵ V¡ŸG嬈ïª8Ï: [éìÔ‹J$±<ƵúeT~Æp…jÃq¹~’èêP?uð(l‚Üf*«Ì±l›h«ßÊ` €'Ÿwr¢ëäŠé5ªÛ<Ôûy^èÍ, ÊRÃ’¤“(uú¦Üvãã§4o+ *¨RX¢!}5Ž×N™å2Œ¶ˆî’`¥QVýwð;{$ËhŸÄž‹%„c0Šu“¿6±«í™Ó\R*ñÙº¢ác¹¨X õökϾ_×ç`ón™V5žß@ÜÿŒfUöuió,)¨ÆïùsFºWòùSÉ6ªwU®›n±nº¼Q]¸²&-›üíF'jFµñ4¨Šxe&ñ¯•Ñ㤃-ÃfD”ͪ—,zÐÝA±G}7<÷ ¿4±šâO “sŽ?­½Ê^çšGÀfÀn'` ›jMC·yCƒh…nMÍ(T«!ùÉC\Ý=XûÐÚÝIz§ú¿¯yxJÔ³a¾”Ÿ«HÕ„ ý””ùkn•{a˜”R¼yÅPY»Äàþ§\l¡*!ãJËÓúˆë I‰3[Á¬Š!pÑÕÖêa [‰ÃrrФp½fR˜›Ù»³qΦULé{Öã_µÎ±?ô††~ØÂ†/¬×¼l]þ¿ö§£ ãô~„ò“Á„.T‹è(žÊ»$®ŽB`¹¼«iW½‘ïŶãúå endstream endobj 1178 0 obj << /Type /ObjStm /N 100 /First 974 /Length 2233 /Filter /FlateDecode >> stream xÚíZmo¹þ®_Á=ô@‘3¾Æ!¹n ¤×ƒ“×ÚªØ{÷l+ä ×_ßg¨¥b'qv¬|)Ð/Òh5>’3ópc2Îx£ ‚oñ¦xØxNú™UȆ¨¨P %ÕLÎ0y¼aÕó‰Lð<ƒÀ0¦Ê)qUYŒHUŽFJUN&†j™MÌP&çM&}’ðËm–XÛe|pŒ0žÉxq¤Ï ƒ¢ÏÁÀ`V ÍJ…•£!—Ô^NÀî£JÇ †!^¥â EQ{8»˜ÐG!ŒÍ)̆yûo0Jm!0«½ 'Œ-Â=\¼×Q A‘¨R0Á)P‚ ‚ –‚+a\¥ÐÉÁñŠÕk¸êgH:rsA蔼ƒ”´º A‡CÖBÔ^=îj 艄üË1UÀ ÓàÔQ%ñ¬HJ1BêU‚$¶õ:K©>Ã4%¯³âÑ6Ç*e«ý)kä0‹:ip°‰¢Ë€ˆLL éÔm‹!ÄRg™Ä$_GDÑ$ª#¢dœ R6IbµWLB‡3)³lWB*:¥ê¦ì«˜±jª¿9˜Ì˜‘´YtùFš ¦`5f@Æàñ­>!Æ“Dö1 9EµðoöêÏûYÔÖh.Nû °_êh°Sr)‘˜â‚z ÊE—9þ¦ðVÂ3ñ^ûȦD©m‹)Ùë¨Å™RtUî çê"Ð¥æÔ5Ñ©ã:ħ" »ˆÏ¨®s 3ZtC¹xvp0›?5ÇðLÀ®>2óŸþñOüm9¨¯ƒ¬ß«ë‹‹—³ï¾û´2pTíXÄFø{œvˆøÆŠÚ‹6‘ÍØAÿ×þ*µ=Û„ ;N›ƒX¦´—Wsp`æ‡Q# m›bW "rÿ1 ºÿTššn4—ú¾uë#ôi.Ëõºšÿ¸Zž>ï6æØÌ|zhæ/ºw³Cñâ·7þXüÒÍæO€¨»Ú¬5œÖ~fó£n½¼^vëmˆ­ÏþÚ/¾_¾3Çú "p¤B/ÑÑb…Öˆ±Ø°UññÕÕÖŽ·¹MñÔÔÖ ¾ ÔnBh‚4!6!5!7¡Y.Íri–K³\šåÒ,—f¹÷Úþ¨Ègóçׯ6õ÷³ó«_góï—«³nUGí^Îÿ<ÿËüɱ¯?ÔQ§p1Ržõš4è``ÄÉj.ŒŒzë”?7ó?-_, –ÌŽ~¾²Ï»ëÕbóÎ×$8ر՜ 9Ë”=ÂR$²ÅË8¯×‹ß&„AÅzñŒà-cšGÁ qo Iºá¹X‡m2„ãéùåQwv}:ÏÁjA[¯%¢ˆE2Û\îr|<ù¡­f}´Z= A±GgË ;9œ’ÕJ¥Á %Ù¢eà g€h±~m¿ÝBúö‡¿?{6åÖ%\á¤uo ü(E%Z—ÓC» e·-L;8‹MnÎGï©Ó‹Åz=áÔuÑ’ø‚™¤ûAz»¸8?;ßL{s,ÊÔÀˆ„Z©bÞ´N ë‰âCî4P´mÍÐC!Aô #´•}rr}õúÕò݉ îääíòüìÕ£þǯÝêj+ýçÑöûôõb¥Ò¿NNÞ¬– Ø>¿õã¢[¼íÞ^.ϺGç?×ïÛæþhÁŒSwyr²ê.µ¯­W¾ (ÓîpŠdÆà~z¥]½šŸ³óËé·7i½ð~Õäñ*:ËÕâ²[O–‘²æ«(eeÐe·ú¥› òxÖ$Ñ£a«Ç*Chöã›aÈ£ÖÇ͈0€ˆw½õõ«u·™>™÷u'aºÖK«;Á¨Ajò=êNå0z$5šFßRÞÑhI6K©-âàÁ8VÛE‘~¤6ƒÐ·}OmÉÉïO; CK«µdìÌlSá‘Ú>hìõwã[\ø6K¾Å…ßÞ(ó ^üÅT˜ÓÇT˜åË©pi¶4 [z «G’½ MˆMHMÈMh­È5Á7šÀMh–©Y¦f™šej–©Yæf™›en–¹Yæ0%nü(")³ž“oùQTVÀá÷àG IãGCPö̜Ɔ=ó?šžEÌY`ÙQ£¨Dà3ÙxÏÔ¨ÁiÔhÎP£©Q£{AÚ5«çð=3Š ¬1ų̈G‚X‚µÌ#|…ÌhÂÈÃêÚy%ëCôÊ^øˆC´©¯½*N`®u‹ BÙOÉÍ…¬¾jìñÔÿ% ãÙ‰ ³#”±×‡Á알DïlÒ—š•ŒDPçʃ³€ÐWu 8ƒ.hAÉ .?Üé3ƒü°vŸè‹jFðõ¨PÁ×’ÿ<Šý¤.Ѝ 1[‰÷4}2ÉÛ”&©DB1=Yu‹MW‘ýíÕ¿ahò•ŒBœ^OȃÕ7þ¨JŠîÎ S¯Ù‰Jhzº¨ƒ^ŸÀ19Ôî¶ ~ßÑ yˆ¦ƒ©‘ähõu]CÂ`ù gÉ6æM½¿“–Ây'èÛ&]9Ÿ‡³McÑ(Ñ;B=Q‚+qËúÍÅùfò•Ûo —l½„¤ Ž húX†’ÁG`*yçx¡›Êƒ+>©-™møä ÅÚ(¾õ>ËHm=I §PŸ$«ì\}I”‘üñ¡ŒÄ/>”ÑËKÛãŒÐNCB; í4DÚiˆ´Ói§!ÒNC¤³ˆLz¯ UT(i’Þë¯Ö“:ëËp%#Óóý…êý„²«e&Ä¢[Hïd5, ¹à¶q –Õ̤{K¹mz¨(¹t£ž‘)w•’Û÷h”¬?ŒæFE3%šLz—`‡FÊ,½ê:„æFM#5’îQÔÜTÞhÒ íÿç§g endstream endobj 1279 0 obj << /Length 883 /Filter /FlateDecode >> stream xÚåW]OÛ0}ﯰD¥9RcâÆùÚöÂÆ@CÛ¤n/Yâ¶aùè’´ðówm‡’¦¦-< $Ô߯××ç\Ûך! >LÇg®¸cM¦ˆZ±™‹þÊ›HY§X"’žóˆg{a§X0Í"¸Ô'ôH§¼Ž«tѤe±AäžÐÆÂP™0œA¦åðsÞ~ÛÆQ‘ƒáúîK̳Ì̸AñÊ{XR†Ï¹¢ VÒRîÁ4Åc—XUÎñ³Žf\ NÖÛöèVÁ²ð¥­Z€2/eOËJqÕµ‚åÑ¥½oZÀÝiBÜÕñæ í `Q8Ž‚u;L…“ø<¶I@©mÅYóœÍKƒ?RsB”ñÞTí*Ê–|ƒ[{ µ:Q³¬ø“èâyTEqëQžÖuZÌFB€dZE92÷0¼#}Ÿ„««}ixÎ<ܱþ,¼(1Lá/EBØÎA–ÖÍ+A'<ý—%€ÿ›`ß½RÍ–Ãã¦Þyÿï¹÷o{%ÛÌ“7†òä¤õñQ5Cwæ­ð¡¬^´Å_/²¨‡Êß@ÛÁ×Ù¾s?• ‚¶¸L€üMÙK9Ý(¹ ÞòÛz‹á °¶äbë’ë@âB߉Ã8>ÏŠ²âÉ!qÛÊ-‡#;jQ$-U?Æ@DˆSiʶìL’Ö¨U‡ðÒea«ê<0×,D'û4ýË\¼ÅþÀb{øÖ0™Çä«AÒ0mæã¸Ì–y¡ÛçÐ(%m+ÊcDR¢îZ¢š0¾ÚCý0ø]{TX›þ¬(±ÚQ’†ƒ—E–þ‘‹ôà¬a¨ 0Ò€§ÕðA¶IU.„F %Íœ+âõ> stream xÚ½W]oÛ6}÷¯Z£€HI}݃·¤† hg/Z°1ck,O’»t¿~—v)GÎìÔ1 Ûuyyîååá¡gÍ,Ïú8úy:z÷ÁÇVâ&! ­éƒ…=Ï¥~hE»!M¬in¥ˆxöÝô×wÂØ°LJŽÐؽ᫆u¿ÔUʰyÚ?8÷!žåž¨r{ùíИ¢IÙÖ½qÆø¸Ørp쯈‰m‡‚ê{Û BôϺ3èñ}ôÅÄJ£"/:›Dè«ûH¾…U,6‰QÇ–uE½Pïæ54c”·|ÜØj0Õ¼–ø¢^JÄX…ÊÉJÖ¶ÛÙ0£IÊ!®!$íú +EH_ê=@iª—²ç<ýî|±ª‚—Oëe•Z¾4}ïœ Ìøýy2<Ÿ]Ý^^Ó=¡(/ªWΔ æY°Š·'™¬âÍŒŸ`¦"¦­RkW÷-ïö›Ód,GP ]êiʹxdÕ²äí ] ÐWdÅà,ô7ô}iPo±<}äjé°œuL=­Úb1S¢Àð’Ê·j°¦ÿµ=îõþ0`+òãA~4ÃÏ9ËE–÷UöG[±²Ïšzµl×y‘Ü …Lì“<ß]6»9µ ”—z ÜÝÕͦ—Xô–s›OÌ`L+#j ÖWÈß;ê¿•+.<àé™î+þÕV?©¿EV—ýŠÉ´u×%Ëú¦×·OðÄ»V#MßHdoîîÖƒFÓÑß#,÷ÞœÛ~œ¸$ÁVVÒ;ÏÊá%¸wi[ÿHÓÊòacD>…viÝŒ>ï¬^%ÌM…d{Òˆ‹uîž?þä¯bßCkK‡1º´Œjñ3SŸX#žXç6‡SYõND_¶ùáúdNAè¹^BI ÕÐA>õÜ’ c=çmÖK)^ W>­Ê¡-Y¨¢ƒG­TV@+òù¡©+Õb‡p+¥k…°C‹á-sªTS UÓ>ìwÛ²ߟúv§â­æº¡y­©ä¶²ll”$ºxûÌ#âIüÛcÇmãbŸlLšÙªâ ›Ô= üO6Ÿ_¨ˆ€vV ô°Jð·+at‘©¶—¯{!ªy!öIòovʽñ’7ó­¦7XÝlƒ(&i±W%|÷MfÉâQÖ³'wÕñz—÷¼.KÖ\Òl¨tŽ®/ëÙIf[ïðм9ê9~Uu“ž*‹ò˜hݲh¡H0:hÚÁ¢>¾Ðͪ¼/©zÂæªn ‚êô£{}5‘3¤ÒÀËx¡m™¨zWŸCAüxpn endstream endobj 1312 0 obj << /Length 1140 /Filter /FlateDecode >> stream xÚÕWK›H¾ûW ä° „GCƒ´{ðn&Q¢ÉH;{ñZQÚ6/àÉ̿ߪ®6qœC´ÚS¿êñ}U]EãÃ5ÞN~ŸO^½‰b#q’ÈŒùÚð\× XdpÏs¢ 1æ™±0§–›YöA¶âµh…µœ¿õ†y=5æz0ª|e&®vs;Ÿü3ñ`ê^ç!âÃyd¤»Ébé¾7à(‰¯Jtg0ÁZ-ŒÙäÏÎÞù¨h0Þ§á¹N£0r<jC :„ éé.ì0f.= mÙA›yIãô3ÔW+Ñ4•úfš[¶gŠÖòL©´èøkÞni&a&kœs3E YX6 ECçUMãZ©‹öP+¡ÆQ8ÇÃǘãrþ#á£0±‘lG®˜ël¿–MZçû6¯ÊA˜Ná¤Þ‹ ÛKyƒËÌXÀM‘e9Z®#“‚‡³¶" ˆ mT+ˆId~‘iëX6óQ’ œ€Q-›°x¢“}.Ó£þšÆ¼\WõN(ü„Ó„RHP.Z™Ñ>åG™D¢@Άˆ%aDDRY h™»¡+Ån_Ȇvò2-™¤E-EF³LîÛí Ú MQä›r'ØV ‚ouÊLù¸'Nu~”ÚÛJ´©åss«Eñrà~sX‘Nµ?☞µ¾äy¦Íå­ `÷@‹ÊŽk‰LÒ©ÝÞÏÞÒª;èGžù`A.D‹2•hÃ!s+K$-°:|æëHáV!ЫÔË^*´Y­¨ô£®J?nÌäâ3Fét1 -–‚aÌ|$/74×ìì’‚¸ÃÚ¤Ú½¡…5‰ N¦M#0O´TîCó :–`&mÉ€ºÎÆÑíZ«Vx—‹ï§/–Ë‘¶¹0Uzè _˜6V•C ŠÁ§Fläh9Ž”'+OÿYD„Bºn×Ýô2­ o­~£áþÓÝÝ4&ÊœDWþË—$2 :sÛ*£ùoŸ2Z@9cî ».œþ2L•§1Qù³2þߘqøÿlʧòÿ¯)¯§õæ€=;€æÕ\,Éï”"¡<{Š ûƒÍ84¢iÙëDô…<×: wÜ„‘›îÍrÑQ ‘Ÿì~Ôm«Z·Ë"oÚ £¦:ëZÅ×ú½3ì¶´qì±Øt¯@®³Ú¥êjäefM(™¢ÂK³\8ÊJ÷rqR×_äۧˈ.[ã‡X«×Þ÷å/+/iqßzM]wGžó†?MýC¨evŸ¾·Ç—ÍÕ_PŽ"ÖÁî1cÅ¡ieý¹- ׯ6w·óùíÇÙâ> stream xÚÍVKsÓ0¾ûWh¦äìJ¶ü‚áP íÐ 0´)—Ѓk+‰;N,‡¶ÿž•¥;qœš¡3\â¤]}ß¾´ÍAçÆû±q|Æ(ŠìÈw|4ž"Jˆí2”Ú¾¡qŠ&ØqÌ›ñÅñ™6Nºc»Ä;õ™XØçe¼šË“Ñö?ŽŸ‘ º1íƒ" |”,ŒÉ A)l^ ØŠBt_] ·LÚÎÑ•ñmcoû«ðMü”Ø>0ò=f3æl°òeUY*Zø€RÔPžXžË>-–¦Eñ/“b^J©2-× ð7=Šg 0W™<äz!ÉÅø‘—Êt7e¾>(+j¬#4>ñì(¤ŠÚ.’2[ÕpšÌþ0l‡7D–Cl"Y«KªNT¸Jž® <%G¹¾á «£X®<ª“B%D Ÿ%»ÔvRú²v›ycZŒ1|2,eÞ7ºt$n]ëÞ¦Öû½¾ÕÓþ)æmÃ`wÏP4 a¢£/;6ÒØŒ=#íÎȨ‘QNwð›Ô¢뤄Ñ1îz–,æzxsÃŽa©ÿõö†N÷:ÆaþÍpI¡"æ¿ÜpíØ‹¸*³‡ÃI$ßd˜&êçÃÖqý¼·ÛáP]y´Ãí¶Ã!þ¿ªuC endstream endobj 1354 0 obj << /Length 920 /Filter /FlateDecode >> stream xÚÍWYÛ6~÷¯ ’‡J@Ä"EQFú°M7A 4E³N_œ PdÚ«B‡+qüû ;–Vvwiá\ß ‡c‚6ˆ ×³_³ç¯„DÎD,Ðb(!˜qRJ±`Z¬Ð2È{\•½ÆêªËõ˶®óf~\üöü§Ìˈ‘˜ˆ f†8#^ œâ§ŠâVÌ ßç58l9é¡©ETb°`gäë.ß^~ ¹}F !Æ–ÔH·jÎüé§O݉ æÆZéËvåæë¶s“¢ÊûÞù™ý4ÔŸ<‡6-ƒßsÝ•·SL“ ` %ÉåDý8'ÄåÄ[Un.?ƒ„ï‹#S+oÞÏnX¼{~×ÍQÖG&]ã䛸³nsU«&dq û“ù:ïoÇwmˆOÇi°¸TaÄÛæ<ЭÛ+Ú&Œepm>ªÓcqc„ÀÁjðö´ra”¿Ù4m§V»Gù¤p–ákp‚'ƒV6fù0^Un®¬{à·ê͆ÊÆltÝt oJíw¯ÃDyu¥aݵµ#h‹'Lš¯ 2:z_µÚm·k›è©À™Œ‡Y¥w¡°éi,ûFð5™n¶[X‚Ö¿U¡§²(ãNäa&ýfÞÌ©,á6Êž3Ï?,QgXÜôÝ -­}´Óä²n$GÝ_† eP‘,8«úönü°z7ÆÀùCÜâ»\ˆöeæØÛuÇðóÛ¼ÞVª¿ÿ&A˜ItïC >ø´÷…îã5Üòٸu¿Í»^ùâ¸/ÌöÎ0D:f ¸#/"7º‡h>ï¿ã4µ¬éÚ›Aý¢ÄW¯¦h«iÊJ5}©¿ ˆÓÃ’nñ hhòZõ¶t˜À Ë40u›÷ZsøÉZåúªSŸžxÅtNÉ1-`í#µªªî¥b31x&5îÞ7¸ñTž «ôxT³#QýÆU®óa°æTì91ÿ?"Åÿó@ñï§ÙùböÏŒÚÒ@÷/•s)QQÏ– Z´a–ItcÖˆC=O9ƒy….f½î¶»>Ý`³€šEE†yÿKw}P7D6¨X’“àe&ló-ìê_"ƒ|ªŠ8Ôä‰ö}$×ðÛ¶ÀÊ! Œi'ÐJ2L¡ï{Z>ñŸƒ2‚‰ô·æWÕ]¹Õ%t'œÈ¶3…m§Q1”{ü©S®YâXîQ›(};˜;Ú endstream endobj 1265 0 obj << /Type /ObjStm /N 100 /First 961 /Length 1937 /Filter /FlateDecode >> stream xÚíY[o·~ׯàc@‘œ^£H› m´(’hk8нI„êHrž_¾¡´¶KÑÚ^)p^¤ÙÝ!ùÍ…s!EŒ3>H1ñ)Aÿ½ñT_à)×7dBÈJ° ‰uL4tpʆY‰HÄäM,`ñâL¢b0{ʆìL&¯„79éü˜»„ú†L‰õ :__aˆ“ú?x9•@U¨`|› ~H±· $ðá‘~èïR¨R9W!b1ÁÅ–œ >2ÖüÀ¬3§`€")ñK©ò›¯lVƒ*¸Î @$UŽB†’ShPeÑE ;—±F‰†½èXLÊätæ¢zèËrtj§”ŠKŽ@Õ¸¤…Hœ 5|bÃYmCóC®(Ì_|Ñw˜¿DQ*©š%ÀWå* ¼ÓYðA%¬NFˆt€W 6ƒâ¤ŠÁA¥€¼ÀÖ^õjux(ðE¯JljRG`1¼úŠ$Ö0¸$u ÁHæ:_³ÚY­‹X#‰>é×À·Â„­"³ @Qª‚¢®ÂB 1 X`¥XÔ1ˆ‚IŽØÀªÉeŒA¨¯“‚ƒ¼)Tqàö)Tq ŒDU¨;QÞœ¸ŠÔ‰!¼ qQ@•Dý¾*«kÅꇌµ¢ú<Ì‘‚Î!øš¹R˜­TQáY-1qU_¢T]²b•@a‰““Áð‰9ÅvLØÉÏÍð÷?þĶq–à6RŠe¨b~1¾|ûín‰V÷pGnJ–:òr*–àƒÝ¸)‘pÑnÜØ|Öøݸ}É–ó'yº˜¯Íɉ>… ¥øÍ°§ˆ¦Þ<0|»´ˆ;xû{gó n¤˜|øërqö¢Y›S3üõÉS3|Ù|\›Ëu_þý¾Á‡ñÛf0| Í|½ÒhRtü`ø¼Y-.–gÍjÏ껟›óÉøûÅGsª+FG+á/1Z7´ß0~7Ÿ/0Ûé&,+žO–­ ƒá‹‹×ëúül2ÿk0ü~±Ìçͣɛú}º[cjf£Ñ²™ŽëZ½k%¥Mðܪm™EqÿÔÊWå—ßž=ëÏ™õ¾Ðó`Ï^í vdÑÊtÁ2ÏšUï€ØG›Ñp]B’ŽrЬY¾múGS¼Õ–¸E#B¨)£yÝ´ÑŽ´nAc…¨ËÙ¦BY]¼^5ëÞ±N6êÙClA÷Œ–Þ2}öÅæÄGrÓãÅl6žŸ÷gÛMK–ëÑ ‡j„|†áäKÃQm$`Áyü£qe´ÄÈÜH—(gË>YL§ãå/;îÓ;6F6 m¸¶Ø„½uz.uÛ³ÅÛB´õkŸ‹EqKÎÀ‡=GM÷0X€÷8=¶Ü"+°*JÓcÈNÌ­\¶½Ó{±,á(žñÊN'«õaTÚôègçúóe¯VГïÊ6¾7Cb~fˆ¦¡#7„½Ô•™D¤ŽÜ![¤ëܰ7žtäöÈ¢zúxûãªÝõZ'›ôT}ÛÔ}Ò½î4¹wî^}¸Ñ½êê­º×]­x ïÞe¾:òAXJò0Ü„À"ôÏãFÓœ©«”¢u‹tÕ7eìK¹lZ>uðÃÜâ­úg9wÞtóøFOüïz|£— õÜDï@¶„´Dl‰Ô½ž­hžrÈèÅêM “6@b}ªÐáŠã§ù›‹ d'øBÐÊÍV@ÕShS(J8\¯>†B—è:{­*œuØ™'éÕ Öªz®ÍEüܱÎÛЌדżG½D¬ª5j‹z =mî9õ|X1³ñz9ùاVKô~q‹#0"ËQ?÷#9ËWêHøzùx ÆËñûw7j*ºMMEûª¤lÜ›GzàÆ6ô{cýçFP(vä–Ñjv•RÒ ]õàýû«Ò}Üz ùA˜îçó×Àͨdœÿšo:Iøf®”p÷\)Ûû ½Dï1úųaTMY؋豬fÃâ¥{d¹ïáp¶z+£É7I©„ÓrK‹³Ïƒ8ÔdWߺE¨Ûe>Þ>îã¸åÞFl3CÓÐú÷ÿe¿Í endstream endobj 1378 0 obj << /Length 1047 /Filter /FlateDecode >> stream xÚÍWëoÛ6ÿî¿BhŒ"Vê…­¼%:¤»ûâ#3Š =X€÷‘ƒ8CªºJ8ÁVrhYï‘zóéÂÞØM@+o£ò°?ÄÙæöxE;§`5ZA‘q­º—àµÎ/ CRw%&à x³±a©Z"°ãE_u-nšÊfBu®ž“Šúîwôp2ÂûtToÕœ}”Ÿ£ŒÅ„žwuÍå5À®^GïºêZ¸¡½’¹OÊœ·i5SõùfE]4N6éh8_¬¸Î2uzûÍ@˜.¸6²Sj.Ûiôð»¸kŠ?Uy8›½¹î$PÕ?âœ÷œÞ\ßÜÞjÆ]>¸+Ò$AàÚŠã\Çš©®›òz1ý5 ÄÁfÄáFæÍhvë;s8}4Ê3ç‹am¨F4eе3ývœ£vz+¼:—G,¥,|ý±Q)É÷Û¡EáHý¿0$¡8#Wš6geeö¹.zqJ@¬B–¾ÃïGÞC¿‘:t4kH¬Ó‡A‰bú,HÐt60BF~ ÅÏš~.T!«…)d/ªØže¡íOcÂõ'Ñe´*Œé°hQsh,‡ ¾Þטÿ‹<…>Q)Ü–¢ét…ýÛ5ß^æq81Íaµºs«x7Í6V$ù‚ßU5Ü©új­ë^v Rºy­£}kp|ì pÑÎ"›æ%E¿”íº¯âáW»Á-´éí&sBmøú¹<ýÆsùcþ¼p Gt¶GòW¸“o8qÿ ûêQûÿ<ƒ>Æ=#z¸çšrä w )x/lê˜Äš>õájðP,ÿˆ«½ endstream endobj 1395 0 obj << /Length 812 /Filter /FlateDecode >> stream xÚµVßo›0~Ï_ai5RãÚ`c¨ö’um¥i?´5Û Ë7¡"!š¥ÿýÎ6Í #YRµŠ;Æwþîî»ÏP4C]ÞgW~€Bú®Æ·ˆQJ<î#Éñ½Sá¸"ŸU6›;n€§Î~‹Ò™Œ?œ]qÖ²å”xàÙX¹BïÐæ,ØÌ[›‡»‡®„EÏÚÜ(å ½Àã¼*:æ-7í3Y $·>³,‰séºx¯ì¤ÔÂÇw*©«SXâ¯Xˆó,ÍjÇ•øÁ 86Ž—©5Ë–:âZ•qRgŲqªêya’Vç Dø•¡~3@e ha…Þ'õ$/í€"@q„SŠu:\Ûh^Ø{Z«\­U^‘ôàñ'¾¬‡GGÑH a+™-!ñTì•…ÂxÎãéÁvh¬ è ¸M¯\nâä«ê%o™% À™Ï·d”RZ_†¿‚RüvhG OÃÉU­Ó±sF'ØL )¤0ÜÚG‘-Y뜟4¡ÈÎj1­ŽØ=™tÁ%;µ¼f”»±Õ]sX+³v³0Qî4ìYNò¸ª¬iýh:¸~ ˜)>ÛJ—>áÌCÉbM(Já!x#^ ßfëq ¢äZÉrt3øº³~F?;lb€É2r!‰`²«ŸS+›­òûa‡‰"à_Ž`X•ú71SD:TèQâx[¶)÷nòoíâËôN9ÂÅI½'=\@z‚cÒcÓÀ{®N]"E#îïU•”ÙÊHé3¤ý¢0r¼Ör­J`î[£ìÂ*»^á:MGöþŽÚt%åïiÍ=rˆ|¯â™:\ vÇÞbæø¦é.BH»M\„̼ycwÜxv4·Vjç·ªíXÝ3ÛŽïžžôñ _—ñjÞgÓ»ÿ‰¦ÿ?Œ]m(4*g÷ µt<×û%vWBG›ýÅ–.l´tžVÝ.˜N„1écä ño{ýè†Ä-\í‡îèMžôëKÓ+¨µJ»õtÆLÛ¯5‡Pû‡ê÷§{õœV½V‹ò¶ ô"ÍûÀš—F endstream endobj 1413 0 obj << /Length 696 /Filter /FlateDecode >> stream xÚÍU]OÛ0}ϯ°ÄÃi1v;ñÃX7&!Æ´µì¥ã!4n‘¤sÂàçï:NKBÓj uC•â›Ø÷úœs?JÑQôÉ{?ñ#†Q2”h2GŒRÂ#‰bƈä M24Å¡ô/&'‡Ç2éœä1'\*ˆÓœI+R-SSi{Ô£í'ÞOI[Ç–à)y‚f¹7½ (ƒÍ[*A÷ÍÑEp}q°oÑØûºŽ÷tuâ.F‰JR¢[ƒë;“Ö=p@Hu<§L"ŠG¥/ÖÆ>gé\$¸.íãÔiÑ»tD\àÇ+6"Û_.o´/B7e¾Eý¨Íþ`»óD˜´û„0¤ •Ñ®1½e¦c†k7÷ÜüKðxi‡â:Ä0/!!˜ü;cŒ‡œD<ÜßËtQé§Ýç7Ä®ú¥ÝŠ×ØF/®l;€:©…ôÏ盃³e¾ÙíV‚îĘ»µiÍÌÙóÒ8£3Hâ~ØÝ7CE޳´NÉܤ¹rt²Ó‡%ä&¦¼'­Üë;·œŸžþ?ªŸÓÚ\?<›¦x] Ë_ÆB¾.Åb´ßtlô#̺ߗ¨ô endstream endobj 1439 0 obj << /Length 1483 /Filter /FlateDecode >> stream xÚ½WKsÛ6¾ëWð™RáûќܴéL&MÚXΡ²›(HBC‘ Êq~}w± LÉŠc¥MFK`¿}ï"p–Nàü6úy2zò<+œÒ/³(s& ' ?N2'C?‹Kg2w¦î™RlîWÕL©ñÕäÅ“çI8¸–¡Ÿ105¢ÏŒ ‡“Áa¯?íE9c "—Ýš7ã8rµÚ»~øìò¡È0 ü $>¡‡rN½<Šr÷¬{q»íl쥙û¯ôá­!Bàxaîg…•Ô÷ýû12ƒaõ»>—¸0Ÿ´n­zÅ%-×\¯€ æê!â$$Žl¯ý†­ùþ#F1^]¼|yÄaS/‰K·dügð—n…®˜d•æöËI`žþäRlE³¤5HN÷d‹§®‰J¢˜å¢¿E'aʇ€ºº_<…%è.”BÆ ©“g~YD dè—iJJnÇà'VwÜš’INFkZM V×V ”xnuÞ‹»2!Æqà§aFŒßŽKb|4ä¬vjg„¬6L*NrI¾‘\Y·3-Ú>ÒÖí++·h6¦;s¦™Aÿu2ú0 8pÂ]&¦X†±S­GÓ«À™ÃÇ|* çÚ]; X*O0ûjç|ôçgǤû~ŠiƒVÅmºR}`Œ¬Ü ¡´çOŒFiA×hùlw÷¨JI *E§hD’'G U’¦~š[‡üÂU%ÅÆ˜ýtwM’²°õ.wohkªDJU¥+}Ðý…S¢¢e×{ ]Ž”sÞI¦!ÎÓ"t9£$Tº ÒŒ[ÞÒ|¸~ ×ÀÈM+׬Ÿø ˜±‰pS i¢*Vc…IV°J]¦ˆB©Q×ûÔªîå;¤dƒ¹¹@Ä>Q‘Ú6D±ME)جæÄaÁ™î@r{e3tÖôÊg[è }×Orß@ÍË¡ÈˆË NªcjAed¨ŽÊG·þÁbE®Zµ]u5‹Ýªµ¹'"`YAAñ`e”G*ÿˆyª(?á ËœïzáŽYˆ7¯Î<Å?€†q¸Ùj.»ƒ*wDf±†ï«ýìïÖAÿXÁÂ5Å*'žçuûu½1°¼j»F«û»WîEsqVb2Pl ”ÅÖ@ðoã•*ÂÜ6¾ØôüŸüñû)mWï•õÕ¤wl}„Ë=Ýݤÿ0ès›nÿÖêŠ9qã·R,¿ ûN‰†Õ½vEm¯WL÷½F¨á‘œŽÄnO†²ÕKßBîÅÄ ]øØÖ÷âΰ¢%3¾yCs k*~‚Ù·Lú}ù²ÞŽ‹¸K†íuÇÁºd%fB›\‰¥Ú] C!I—J¶Ê»’t,§Ä,–ªyn1§½š“éêÝ8ÈNŒ]˜¢ª/cÚ±5ëßZ(Ý;Ÿ(]£´ì*”ËžAÞ` Öð¶S_âïù̓„‹2¨© Ú£YêíFS$mǦk˜Àýµè›¾l¸ôó=ØJÿ Bô¢•ožâ¨àØÜ(º±ÆoZw33óHva×­´VoVØìr·óL/ˆ `íÝob‡„(ŠöµQD[´·lެ¡Îl~áÌטöJIÓ@+lÏFè¾—AØ^’ïYíݱ—ÞÁ¡Ð£/ƒ4|É?« ÓÚ  ˆ¿ýßSæ}:óþº²ÿW^ýøîÑgA.<Ööâ’¬7œÓÏ9&$€œÕªýŠán“üƒÙ·ƒÙºy”¤ýKCÌaŽ3¶Ló)¡Áo ãkð8f#2Xÿ‚Ëá÷“~~áÈ¥Ó/ßÜÉxª¥ûȧ zÿg|20Ô¾Ÿ‚ÚÑl¿%ýîOÇS™'î3 •Œˆ×³;êÿQ—ƒQkú­-ç¡;ý.(s±þN0æþ=° î-ù·‚gÀ¦úÛ>·º™â€¼S«àYü/îÒu endstream endobj 1458 0 obj << /Length 1159 /Filter /FlateDecode >> stream xÚ½W[oÛ6~÷¯ Š•†J%%êÖ®ÞÚènXäa®Ð2ckÓÅå¤é¯ï9$-[Ž“ÅCøä¡Îå;7S² ”¼ýt:zqÂÉü,brzA¥~Èc’0æÇaFNçdâ©;=}ÿâ$Nw¾ #ê'19ú›±R RçÚ»t£Èe1/:M@޵ߞŽ>l)a½²8‰ý I^&SJæpùžÀU–’+ýiE8Ø“ðö%ù8ú³—·¿DÉ."Fý0ÆQæ#ec,jŒ(³î‰ÇCN3×cNèza”fܦ@N„Š·½¤ÃyⳘÑ@ႳÌgAh°¼‘*o‹UW4õÈÐ0À)ñXê‡ijØÏÜ4ÔÑZ‚†¡Ó\˜xüž`Ì‚7·lp«g®ÅÎ?2ï”UØu)êy)çæ0sƒ¤Ï øù)id³ýðntCuÈG‡ë E<Ä "? "ƒ °k#Ьgnïþ.›•byÀA[3l–åͺ?<€!Éq†¨\”Ò<¯ðƒÆØàœ &)ºu+½_奎,]mÄo,Ô»7Âìø#f4µ…˜•ÒX±cª»ñRdq™óÀöü"¯Ýïu@_®°ôÖª3'(WèÐÒ„YšZz¥¬Ýϱ“c_ŠVälÍ'—H‚2lÚW(€ÖØùWÓ¯ÿSSÞT+}n¶­õ¢×ndmÝÒ2]4eÙ ‚«¢^¼ÜïÙÑ ãûY”€2? m©| ÝãÙë_¥ÎØ6@Y­ìÛGæê¨\ø®Ç9‡C@M(“¡0HÜgϵIda; †áWK éu¨ß¢º:ףΠCè¼~mVz—(Àü( ކO³-^ØïÅ I½b¬ô¦5kÕ²C}‘BÒ® ñëD¨d[ä†j„µT† á™üh0éd#­ó©õ ^³Y¯ŒEp“ %µg›†Ã7†ßÖP·„J5!­çÊ:¼ÐZ€&l¸×õ\¶*ot™ÛoC»íù­‘E[^!:q´·Êš‘£3¶Õ„¤ Q®7ô…¢ 4—àVÙ!Âô¨+ó{PáF¯Ì¡—Y1uÓݑז¯ÿºŸßD·y°·.ëQµr!¿lÞ'Âû:öþšÚ•zÙô‡ó§·—Æ=ãGiÛñ¸TÍÁvx¯©b¿IÞ6_ìÙi*+áöm½„©0‚íü‹G; EzzŽM3Šc1ÐWÜd6 )t­@ != :d(­’ݲmâÌÕË£æ¦4sžúýж™&NßT…âù1JÂXaÙãT—B©;{ÍñÒná–Æ¡ðû¡Ãö1yh×… s&¢e^T¤¦•T¡ ž”…|xE£VeÑ=¬¢½ÄSë™’÷SÉïšüß~Õª”ê–.ycˆLH Âà_ý¦?&ð•Ym ÏŽ ?zf]ͪü\U¢,'“'~?™Nõ…X(`ÉnôU4Äl¬¿aüuþ–þ© endstream endobj 1362 0 obj << /Type /ObjStm /N 100 /First 966 /Length 2030 /Filter /FlateDecode >> stream xÚÕZKo7¾Ï¯àqsáE‹ŒŽ gäÛ‡ì >Œ¬^GÙÑŒ13 ’¿_qš²d=º%t;Ùƒ­jv5ù±XäøÀÙ8ã“)L!#-ÿ^娯ÉPP=X… CB4IX6™xe¯-b¼§¤z£cú޵MÐ '¯ñ”Šh^JÔ^3^JV úU "ãEÎ#ä`|©(º"dÐBÎW}†”ª~2佂͉«~6DNGÀ¨DQ¿(“S„A¼!f]RÊ:-AÏ9T zlja¾á8±âL úmñ&DWÛ6Šj+ÕJ2è²¾D›aˆ’ &— Àª.Å ŽÝ7x"•’Ž.@*õ HxF›Ç[JUr&Â’‹$ÙDöQ›"$,10ÆäX[{•$µ~ôb¢Ä ¾”¬+åá:ûý¬‹ Ý]çHè­Hm#ÃÎk¿·pEþŽE é8–‡TÇ‚{qðrôæ£$†WÿÀÛ슎Q  ÷K®¨!|¦zc„¦£G…`0ÅWI‰uÖ€¤ÔÿL*A;©R]½G²(+‹ ã‹Çt „¤Àá‰R)@b‰u•àê@Ð Q×/âd2’Dl${5â (jb0«Ú –bÕ+ðÝ¢c ¬2“¾…­rªw°ºêq0¹ÔÕÇÜŠ«‹ƒN ±xöl±|iN¦ÁüÚ,ù׿wÎŒ £[„›ËõúÝâë¯ÖFðÚ+ÓöÚYæÑŽdì~CûÕvs0Ïž™å+Ä\BDÔÏ^a16ìàxËþ>Uš»øÜ?Àm2ÂRÐùòçÝöý›î`NÌòç—¯Ìòm÷ÇÁ\ûöÏ^¬>t‹å `è6‡½æÚÙbùºÛo/wï»ý1¯Ô¶º³óÕ7Û?̉bI^Ó*½Ã@«¾F:<^,Ÿo6[ôvrLªŠ§&Õ^à&¤&HrJ/ÈqÖŸ¡®ý/–o.OõùûóÍËo¶»³nW±¹wË.¿[¾8ñõA§ó† ÇÖ#²“þuÈ›âm† “g›KÞóºoÌòÛíÛ­ÁRþãõ6öMw¹[^l/.V›³¯Ô¸“À >ZÑl˜É&D:‚ÆFü%XdÄ{áØ×gÛµ 2²e¡†ŠC²NÓ쪗ÛõzµûquÑíçÂæ½XäÀ(Î&Í]¥  ª·®{¡}¿ý0 òžä¯W¬  !ºë¹Úÿj߯Wûý”ÞlF¹‚VœåȃÐNfs÷¶Á8r´Nñ°%¥'%ÚœüC‹÷Ãêã„KÖ'4[À6(ˆ­t$;+9<GMô"Ÿ=ÜQó¼"dævU¸®ÜªB‚ÀHíÑw© 2j}Û7{t©Án3Nù¿zã,ÚÈ Ìcí Ji1Ó±ÚYOÆÚD+2‚„`Oé‹å͵ZÓ`DpТœ} Œ¾ü¾ZŸŸþœ°²£`»y…Š9áoBu¶Û~\w¿wëýävêëyŠ0nëúzŽreÃ|ìμۣ‡é‹C_Ï"’b±g´^ÎaìÿQ²I·×¶h2BÕÓìùÁ2ä^8?vç~=Ýî&thMpØõaãgHtL‹g|Àw¦Gâ)ÛzP,éi†Vq=¡â˜mTf3€êÅ®[ºŠí§ÓßÐÕäô܉ÎÙs´wôj/ç8AšxÁÀ4Ñé yÓ”a “#!äüBññVôcÉÙùÅäPàÅ^/{(ʹŠÞ CÙÔ3Ú©£JPjëuÎõê=x.ºÝ‡nj01+yÃZô>kÌþãúü0¹ûöa„$Hz+Š=¥^Ëyì19òýX.O÷Ý`já ù¬ëºòà¶åNm.¢‡£cµÉc†óhëñµs2V;fP©ôh<ðHm_®Ë”‘)ö|ûOorŸL-B£‘›pÕÒÈFld#6²Álp#ÜÈ7²Álð´dCOM‚TŸÍN¹m@ÎN®ßoµ¤ÏTB û6/&†i²þ²X #§·ÖtÅ£„¿ˆ…54š² ÖôlÉœ¬‡Ò(Ø(óR°O£`Cxæ¥`=˜FÁ†ÀÌJÁ2Ò®þ´¯Q°,qzûfM³ endstream endobj 1486 0 obj << /Length 1859 /Filter /FlateDecode >> stream xÚ½XëoÛ6ÿž¿B L*Uõ\?e(†[ƒ|XšŒLÇjeÉå¤Ù_¿{P²ìÈ^ú Ĥx¼ãÝýîxÇÀ¹vçåÉÏg'Ï^$™“ûy&ÎÙÂAàË(qR!üDæÎÙܹpOQ³0sïb¯¨”1³Ë³WÏ^Db´/ „Ÿf¸ÒŽ0Gš“ÀÊùíìäŸÃÀƒˆ$})§X\\Î_9°”gÎ-‘®œN‘FȵrÞžü1ðÛÿ%=¢t¬‡üN˜Ä™†#=Æ: ûÁùhó…Ë(pÏ–zæÉ8sob«qºCå’Yòê ÜøæêƒžÅÂ-:7m†(ñ…ü+°¶Ñ„בø x´ýU›¢-×]ÙÔ;Ên•Þñ ÈOd~$¼µ—òöRFcíwx]ÐÆÒ0ƒ®çÔÍÂÔ½[—…š ·úB®ì=nŒžó¨¬™> îq{«7­ê²»‰Ÿ3 ß÷-ÑØ²š%LüP 6ËÛªé̤=GvMصRwºÝ‡ßÞÁâ pOg^†n­V¨$«Òt<*À¥*ë²¾ÆoÒÕ`ÓO3O¸ëVƒN'Ò•êڲд ãÜÕªÀËÑâ'›e³©¬¤+øÉ€#MÿónqsãÍË•®Q†"/:¡ðsÒ~ã˜õl€Iœ¸tƒsKÝ;7~3Í á!¤k6WF[ÊfÁß ]U†‡ªžóÚB«nJòlŽŠ¿ d„º×8±d€ Ú×á@pnƒˆI|X©Ó;G¹¿9Ø5†AÔø3/±û‹®þžÌ« ,/ž¬ô ídÝКe¹æ )ømuÑ´sm÷’¦ðÛÒÖŽhiqhç-™€”{:ó¢ ‚ƒy„ˆ^ z³fUŠ®¼AÍtu·cÁިĒ”y ü_Ü0 üù™Ó^;ýðÏ—'˜´EâVÍuŸƒh¾Rë5âqÌÛ’"ñ…ã(¦€4ü‘œG ùz$ÍZËó¾ !£8/•fË<û¸@¤â¹Êº—PÙ#Z×NFÛ¶ ¿ª@I<„ »¥êúQi¿)ƒ’ì¥nw¨Ú¶1 €#ᾆé[\ÝÓÔr[afØ+eIìeÞŽì¤r ¥ N;†M¯ÀN÷¦Ád^£š‡VÈÜhƃ)cÎcPž¤-ž0¢…8&¤ã¤Žb]„=žp¨X;›Á;Ý IV˜àÈàˆ¬”…;Ð00)òÞ2HÃÁÈ©½¬êpêæ ;ÉYéYÙ8ù&é®lWêÒõŒ8îÁ•öàÊî+u_3²2“âX_ß)Š,¸RW:WÚ_@i‘5#²;etvи$§QªWJK‚¸ýpÍõBmªîAw¼Œ tkíUº¾î–‚!Zn1ö—!m6ðÅ«6CM‹Ÿ‡{ ·Ñ‚r5(ž>Qàmvò+/@h‚rK½µ)C™ƒ`›¼s¦Ñ¶*Mñ°ô|m‹@@-£Ä‚¤6]»)P°¥AÞpáªZ7 ´)ŸNáÀžî£¾{Xÿ’;¹ çÜ~(j‡¶ÅOì“¢k윳ŽÈCÄ›‰Øý€P@§ÝW@‘|‡íMá XÝÞµ½;p¶mjøXv`…®šÖ~QÕz ÷Ö4ÞA§¯4tU¶kdøÛ¢©*†hh«8©«²ýÙs+ÕÒ½‰íŸšºwALâ)“îû©‚wpjÃ(Z¸C>1«µêc©#aÔ.ñŽIùûByÿžz]ÚßÀË/|ÿä l*¦úh™³©—¶­´Æô 2N+Ó|ÉÅMÌç?Ýæ9Ô´ @ º’0Ša1ÖÒå¼ì˜„ÒRÄw 2)ÉåàBð#¦n %&–eC¹`n~:’Õî‡|–»O|~sÚ¿NÑ7#KíšñéçHAõì»Ö kx<6?—{ä^|göZÅ‹‹G°YäÎËÕ£øäP…ÿ(JAVºÖ"ɬ«²{rYÿQÓÏ«¡”~Gß÷•9„Û1ꫤãѸÿJœE{޹8Æ ;µŸôz|>KSÌZÔöœ¦• "Z oóˆ,ÒÈÏCñM‘Ï1Ó¢!qàRv1ýš ïÖÉ“oµÛ'ÅÎìVÊpaÏ«¾À¹âRúsR54¢ä/|°/î5nG„W3¨ïðõ ðù,OFZÝ®*µœÜîÿ¬aQO endstream endobj 1507 0 obj << /Length 1356 /Filter /FlateDecode >> stream xÚÝWÛnÛF}×WN¯ “Yrymài ¤A‹ÖNª¸ÁšZKjyQ¹”÷ë;³³¢D‹–íöC_´÷Î9³³GÜ™9Ü9ýp>zó>ôÌËâ vίŸsO„±“ø¾‹Ì9Ÿ:&øøâüÛ÷qºµSÄ‘Ç}vÌž­å8HÙí;ÙJÜ>âÖ x·Î¹ëƒnÀ¤ ã?©Û±+RÁ~g1“Åb*ÛE]õ mì}rê¸~ê‰4íLé±D+ÇAÂVº¥Ñ%4)S4ÔÔ•r UÍÚ9Žc–csÙȼU m¹Æ)•·uó øt4f›ùÛ=åu¹4ãZ«©õzÕy'[ë‰vn]ÕEQ£ƒ›E5ûþœq´½ïeQÀ”ߥ`±‰qÎN*@\¦Êek˜ÃaÈtÛ€OZúÌ#®fÞØ Ã̓¤o, Ùá!­ôÝàlødíf®e÷%= ¸Zå€;:Ü8>¦–ï€Cì‘—É“cçÙ&Xèß! §Ó"Q¦ÓP[Ö™I!U—sYúKÕ,rš½cŽ+¥i?ÆEYQcªá”å×dQãÒœ¬¬ãÕ’>Vr©•‚2qø0’QÀí\¶–Èjª‰Ã›…ñsÒ’¼ª¦ªÑ9}¶evCè:€Ð/{ù|KFLº’56Ú~FŽ`lîN•åj½¡»æé‹ 5öY‹0L7€Í½ÞÊjº×ä—B™\ÇSÕížl¶çºÝ–,2†jLβ.ªFÍÔW2s?T‚ý9‘î¿'î¶ånvñÝ—×÷hz5c "/MmŸ)Eåð¤Ðõ`äð˽ÔipHÝßL²'{Jã5ÆüËå_PÎöÝ{¥„­Í× +ñ8„ê<Œhìfâ ƒ¨T}†³áv )e7™Çó¸j.°¹‚ÕÞ¸)U;¯¡›0LgŸ­Ëß#â…J’e쵇_zõB4àÛâ2ÄÌÑS¼`äÃÍ ©õÞ‚ótÓ“g€÷+Èdòü€¯ÓEù~"ôSÉRé jþL½ˆ'½,틨W—Z=ÆÕèÇóÑ?#ßô;éf‘‘“—£Éw¦°øü‰,unÌÖÒ !ý’µcáœ~(nÛú´WÑ|îÅ`˜¤^ÈýöÒqÖ‹-NCÎN>QjßZ蜭gŒì&¬36a{‚‹§DH‘„J;‰'¢"y§tÞ,–ß*}OUµ´½–@€y®´FÅ&VZà4PkÞeœ¼ZU¦ðjZºª›§ä Z Ìöê-´lފؼÚ~HSÃMÊAS9Jt}iÞEƒ•Ñl¸Þš÷òn[®ŠŸr΄YÒ¿ WBƒ¯L]ÒµœUœô´Vp¦¾.•ÎÂì€æ3*/ȶå²0’!¯WôÂi|øè .€ð[SFVÚ%ËByë xÕ†»ÞÙCÈaFb0Ü g”!F¯½Ù¸ Zù³,dnw‘ÆÎ•Ý5WÚNõAP!t>i9S÷œÔOö¦þ䡾´Âå¾çy„äªr¸c…¼UíWêÆb‡º@Á‰½cj¦ @ÈQO®+䃾_½¢g‚Z#|¦ÔÇ«h:¾ØùÛ…«‡Cw ‚Z5²:4x`Kñ#”T#·ÿùÓÇÛxÝ·øD,N¢î¯šèï[#9PŸv¡;Àl;èo¶ mrqÀÒ£p8w³[ ú›6ãsÏM]÷} s§ÏÁ\Ž–Öô—›¢ÞMáÛÐꃎ‚Òã?9ÐÍ endstream endobj 1524 0 obj << /Length 1070 /Filter /FlateDecode >> stream xÚ•V[Ú:~çWDô¡A‡¸ ¹ôò@µíJGÕ>t^(:Ê&f¡ %¡»üûz<ØÁá"„â8ž™o¾¹x\ëÅr­ÇÞ×YïÃ÷ ²b£Àš--Ïu õ+ô<ÐØšeÖÜžTU2Eöá!©“Áböï‡ï¾§ù®Gˆr•â8õàLÏ•FøáP9ìÐ’hd9£ïQ©ò¢8c×µ¿à#c»’¥IͲ_îØåoJ¹B‡#‹Çc”#„ˆm'º´o ÔÈŒ(‰=Ü~÷-L)>7¬^®—E‰‹4Oª = UOçâë{Éê²t0ÉÏ7ŽˆjÊj! ƒÇ¸Á©âù7Kk#yr`¥Fb šúWÙâN¿J“œm+-öÛºêwr¼e¯BÀøñîÀ·Ž3櫉ãEÄCë…Õˆ¹*Vߩɴ˰(D≽¢…Dô&À#^…¸†)ɲ›c$²Y?º:'`|þpLò…¡Î…ÝéN…¥ë_.õSm„h}ÚƒÏ.qy‰IÓ†®ö ŸOC•MxT>,0¬–e±ÁCkØ© ‡Šò_ÅЖÉ>‡”Võò,–HùDV €qùó±UêPT´‹0 1Üj»8qÚrZk±’jùov’ï™±yt5…•ŽmJû#÷Ñ÷í’Õûr+kÆÂÐØoÊ[K™Ì櫃{ÄçWGÃu%°Ÿ!…}ûu]¯dz6¸;X&鵞ýc½dé!Í»(×Ê­Mù|º—´•¼#žŠÏ@Nx[Œìd›¢w•\¡`%(ù…4q±g„Éà¾à*;lp~{Pמ "ÞUQ`ÉꔬP€½ñSUëB*Ø$u¹NY5„×ÈÞW—ê¦cÒåòÿõ.kRûô ÞdkÒÀÉ4âò.`Ø'OxÏþì\,âv6}{K6»œ]¾üµzޏ²À?&WHèq.Äùå‘Éyû(Î4E׃•¨x°=µ…Ö[¹%ÇM¶/yêTv"8.N|ž¯0?ɓꀵ{Þ¤ÿW›$Ïåw>÷áÈcÔÜû8òÿâ8óLð"ÍãéÑc‰xrrBÑ]¯Êbÿ²jy›[bÄ$'y˜²oww>ïÿ|šô‹n¿•QöIED½†7}„n‰üƒ¯ËŒ0•à„¨Î4–Œc>ϘR]Ï•À,wÓ¡Z³–Ù[£ %»äM^4,Õâ·Yï/1 endstream endobj 1541 0 obj << /Length 989 /Filter /FlateDecode >> stream xÚ­W[OÜ8~Ÿ_aч:ZâÆqœKÕ}`E‹Z!ªÂ´/ÓQ2fÈ*—Ù8#àßïqìd¦E|f|Îçsýl´F:›ý3Ÿ½ûäQ‘Èw}4¿AÔqó|PJ|¡ù -0s­åüË»O~ØÓd¡K8ˆŽÖ9‘2¶Ü?H¥;sÌ  Œ|OÙÌ÷+Û àK¦mßX6w|&j-Ô·B «¸Ž”V"©³ýé¦*s-Å…^Õñf³¼þT•àMqÐèìO‡;›ë<ù%ó8Ë‹£Ë‹“£åòXcdñƒ¨´ø·^Ž”/G`Eô=?†ße{„KIDÃA(Wm(þõ°£ê;k’r[Ô¤ËÀû1K¿D*›0¦ôÔ™±$y\Wé½:ð~¹kò—^èSGâŽÄ]2Ú®^!*£ Nèü¹Ù:6û8Ÿý7£àŸƒècßó $žÇQ’ÏK­`B , Ñ]£š#F#ðȺš}{lõÝUWÐ.H„ãÆ}J<—vƒ3?ê™-ìyþfÙoE™c<ÀW‹S,ÔŸ$ýé0/Q߇ø+´óe­õæVàã£L±Ü»æ²Cb×1zÂ](:õtŒ§B&Uº©Ó²Úc‰ …Ð3!a¡…óTª`ÓÌÀ˜‡‹8‡`„ÔŸÊ ?$DÕµâåÙn6aæq‡©ú>,ðñ!˜Ê¹Ó4¿«mòʰgU¼¹}eÌ ‘®o¯Ëj/¬Ní5 ÇŠR¥¾å¶U­\N‚È´ów¯Åd‘'Šì)ºž ÅšÐÍtBúÔâ2ÒžÜäil ³²PÁÅ÷óó„Áhóò»0¥éÕìó¦½L˜^sQß–+s–†“ ØT&VOí¾5%tí¶Šë)£IÅàpÅqoaF‘­Än·¸+¥«b—ð¹n:©ÖÛ\sq-÷vÕSÝh îQðt»{à“CG©Kæ‹iüB&àpí7äj?´ï‚ÓŸ×EY‰Õ¸Mµös•‹8šyb›5)óeÃC¯, .°ÖÖ(> stream xÚµVYoã6~÷¯ Ò XqI‹Ôö%ÛÍ"Ø#ööÅÍ#1¶jYòêHkýï’c¯¤ÅLRÃÎ7óÍ-EדwóÉÛ«0F IÂiˆæˆQJ¢ˆ1 šghϽiŒÛV¦z\]¨mãÝÏß¿½âì™&§ŒDqvNè=êNºœO¾NL)bÃ!aNJ7“Å=Eß#%1úÃlÝ ~D\[-Ðlòy°w<$ç)oò‡bg©µJ{ÒéY]öò˜(þðåööE5nóG•îÒ┋}ÁÅÅ¬ë »Q™ÊîGÜÑAKíßä.H(¤KÇ&®nTi—Íáaöc¿²hìøkíÍTWËö#XƒÌþ™?yò“ ”С‚YwªÞÙkxfÞ8K¸ZÙ? âã£Æñ‡‚px\~—ç  Âä»> stream xÚíZAs[¹ ¾ëWðؽP$@ÄŒgg²ëɶ3ÙvÇÉ¡­7‡[IÜ:RF’;›ß”ž£ØVôì·˜Ñ!W2Û|\])Ù¦gWÔR`Á¢IÍG!4œ‰] Éôa†ª­8ªÑ|6„Tà±’Š«DmD…TÚu•Í`aHÙÃk 'Þ&;yÁ?uc˜¿få@µr€%j)“““ÉôÔ#Ð ÂùÌMÿþÂ/=C¡ä~6¿¹¾~=ùñLJ•cM–õGÑæè"u˜¶ÔìÇŒ…p3øÙ Gõül”9Bi5¾3¶z`‹GÙk9ŒçÃlùn6:˜ŠÇÔƒ±xÒxÌêãõÕz|0•¼1Þ-0[äžrÌÍ›Õl|4²·BÌÙÛUÌ™=[鉨¤½pZzùÛ›a’]0RUy—ÞUþÌŽÅ[mtm.°7Õ&Üò݇´¥ÂËQSÓææ••‰‘u…¢Q0Tç@mdšÈºɇw™ò@rl Ž¿‰K(÷ø°ÕÐOæÃÚs]í¹®ö\W{®«=×Õ-×µ>ÃVˆ½@½À½F%½››•1H/®FÐ+ëGI¾æøØ`þÖ zëepò õ>×àƒu>’x¸ç÷çTÈkùMB=I¢ù‚R]\w«Õˆ•ÖÚb 0køÀt4B%DÞÚt=£Üáú•;àˆŒª‡ÒSªCPŽI©z,=§€å¸œêЖTt\RÕ£éYÕ!4ÇeU=šžVDsnn…Ü }Úà:j¥¦ÅÛ—MT‹pÑ…âY"N¡>‚ |c> stream xÚÍV]o›0}çWXêÃ@®ÁƆi{H·vÒ´mMû’õ&ÎÇDB‡I«üû]c“BB²¤«´>aŒ¯ï9÷LÐôÑ9ë;§,@ NxÈQŒB0e‰ Àœ&¨?B—2ï¦ÿéô‚Ç•”sÌDûTkÞ§ªì)•zaì®ôr‡Ø$5âü:ÐLR~¥Ò‰l…ízÂv¢ 8F~cÇf£³|¹¥ÅLªŸ$"ùí/9,_{~Dˆ‹1†¹@güâ$0Aä8]f¥]=F»~#SõòÖ7Ïû4[ÊÖfv·/y&‡Ëì(Ä''fÅ%5Ϲ,§ùÈŒÇyaÃ,UÊ´N4›<¨¾¾2_Zո߮»":W$IEÿPúE„?M› y—¥C9—‹òåtçy5ûõwÐ9Út#ía„©°þÑ+&KhœGC·T{ é/Fdl:a» L„Âí-<ŸR –»]Q›¤Ìj¨íÏÁCòsV޹wÐ92©ËÜB(§²0ꡞ#uœµ`vŠ4 þTš<‹tnGùØKÍ«’“qZÎr[¤Û ’Õp<ƒ€ÒL¤Ê´è‰=mí>黂[uC좮Q?RßR§æ¢ w‡f‹XÅA4¥Ù$htWZÛ$¹¶³çPÕÜnV(k RÉ'‰Æ9ï;¿P¬ï!g8N4œ;ƒ‚FðˆašÄè¡Z:G <[I‚2té|ß靿rÚ:xÁê2cÁÛÏÍK'OÚ63¢×ꃢ©F`ŠU c÷³nº’…ÚCFXq 5CuܯC’`žˆZÎjXÌî*)íðŸ ËÄcLó²Twr¥•©©Ts3{Äî#k¯õ%]íð~fþÛkÝugòÌ÷öu·~Þeþÿ.‘¢è©’8eFtÕøy|íÙo÷²¸Í•l}ìÿ¸:ß.ÇV±AÀ Ýv± endstream endobj 1586 0 obj << /Length 1008 /Filter /FlateDecode >> stream xÚÍWÍs›8¿û¯`¦‡ÂL­ @vgî&îl'“™6N/id›./ÂMóß÷IO¸@°ã줳{’Ä{z_ú½\ke¹Ö»ÉÛÅälFVLâÐ ­ÅÒ¢®Kü ´8¥$ôck‘Y·öŸ¢(¤óeñþlÐsàRÂ#Di6Ÿ)ž‰k„sÐaž¶ÜSÃGïÌêÕn#JÇ÷ìFö®WÇ»†FÖ”FÄ"TÝ}i34 kíí4à·g¥3õ}.8SÚc·ºz\PÃó8ªiªã*B¥â"oÖ¢5.·µDvêP»H¤ÄS™l’«.·—»2mòªD¶f4ø½Iþv¼È²'´HÔÇMiå”ÒjÑìêÒðƒ9¸‘J18`ñÄ‘¾Q³}Šó;‘¬—RÜã&Õ¾ Ût¯ žaÐ@G_,î—ª4ªÍ¾ÛœÍy?¿õõXöÙ3)“6viôÂS.èÛ?p¹º¹¼4D™o¶E¾|èÑo.NñÿÌý1œ¼x~uÎóÍG‘íÒÃÀðŒW"_­ï@Â/ðá` _j47cß÷ãÃ÷þýT=g°œ ‡À@m+o{~e†wØêwÄIæ93¦ÊQƒ˜2è²C¸žB•Rê¡°nwºÁØ›ªW<3}H"`¥&Aw'A‘5=k‹¶:ôæs-³ý(¶¯fcÔý…ýü³€ƒ8ýOði³M­êA¯…À'ûÙé¢`Œødh†› endstream endobj 1604 0 obj << /Length 1075 /Filter /FlateDecode >> stream xÚ½VKÛ6¾ûWè(+-%R¯=8ín`Q µ“Ë6(d›¶UÈ’#Ê»ÙßeK»²ì¢E¶øÎããð›aÖÆbÖÇɇùäö^øVê¥QYóµå3æqY±ï{O­ùÊz´yä|›¾½’Ž$ç±—¤)èÑ2?Ë¢P^>­dé‰ÝäM.›0c¬ý‚Ÿ£Çå~ª¹A ‹œÔ©|·/òõKOÃ+_]±=kE]Á»ÙJ,Á¡ÛµÌšCmVÊl'ßV4ËÁÏØn*šeôQy¹)@ÆœxB¹lªú=,ðÈÎׄD/‚GW$̾Ÿ>ÌîÌnÏKû•]¹Ïê¬!T¬8òÒ$°\À9 C ZfKÄn븜óWà  p(ì ¾Ðr‘Ñ}ßkã„肜 2³È's_4²³â ¯¹&?_/NãÓ}Fû¢ž’ŸOèšF|­Ö§àºA½E•½Èã‰qöž€PÿÂfKfª“åXk¨™ÄC ·§…ªÁbðϼĪqJÃß/B¸Êw:xoªTÖÏtØýƒ… ~þ™”"é+¬>êØû¶ÂÿŘãBÒ{3y€¬¿`pþ»¼ð3l2˜¶ (‹Äs *th ÿpÜ1û'úì»åŸj—EëÔän>ù>ñu¬þ‘E̽4ö­ånòøY+Øü Pð4±žµèÎð¢cÁa\X³Éog%îíå‡Ï¼°aäÅAò†W889íÁ$‚Ùeù&öÒ Ëà¡Á§ ¥–CÂØÞÔ¸]öZ ÿV$³x!op…œRâì›e‘)5‚’^¤ÿ%BC T"á qƒÆ/R-ë|ßäUyŽ´ü‘GÀ Ðeáp°w\dÔÕ[ÂÍOEî¸*N \Êç/*ÛÈë“y œs¹‰]-þ¼FOÕKõ_¿<<˜]Dáìf-,K¯< R]ç.>]rpZo;ÀŠC]¾"¥ Æ›ÍÀ”nÈŽ¾—jއö‚‘zc»Ê¢iŽEçXtÊÝœè\ÑÃBR—Q´­ ?6%E¾ƒSz•ïP4д;Êl4•nMbx§ë DT»lúªÒƒíÆXSc!)ªBçuwà£ÔE/ N÷e-€ÀTmÑëŒ?=T - 6Õ5×Jnu“zÔ¹ûd\(+ v†Æagm[VË啕ºiçh„ÆÙ`¿ˆÇñ© –Û÷t²K8ænþÙi[W(ðl ÉŒ=Y×U} ]lþü‘爷Fš;uÉMBââóVj`̾¢ý¬]H:XÕIG²àU¹¢Á“’í) ;}¹Q¯“õ˜ëá‚è»¨Ê ¥ ¬Qªèœè¼ƒf›µeáZ ÿOZÿ"‹_êQ^[‚jü7F1h endstream endobj 1621 0 obj << /Length 1216 /Filter /FlateDecode >> stream xÚÍV[oÛ6~÷¯Ú ˜TR¤$jÅÒ,)VÖ¸}qó HŒ­B–ZFAœ$ÆúOj7¸žZw#v†q°jûn¿¿@ˆbm2ôofùóÓÕ•=ÝÖU©ºÉéåÙÕõÅÑ7ÄFõY»Ü®eí±ÐíÔÁ·yƒ±y'Õ&Î_ø<O]Ëm›õ¸ß‚ɱ»s¬‹€ª(à}y²ˆWõÙl_8ÂÁÄÓ ºí3-ÞÇu”ݶÅü¦çÊ®fQe½¬¤¡ÇߺÊP¬2P€0èqÓýXT³Ù@Ü ·Qõ¸Ó5%h&Ä®Ùí¥[T÷]W¨È©m1‰GÈ>ì‹ ”¾q}öÒØÍª­ü‘"pf‰‹%´÷2ýOÈÍ‹²õ¦’êôô ,æƒ ”Gjd½~mÓ®±‰Önë_5†àKåñ$9¥ö+U•¹¤¯úüE!xˆŠ©-uÆ&îašê zÑŠ0à4îѨ»¶) åçÖêƒ]˜ èÂóU?n$Ó„ÏÒÌ]öH¸çƒ–ý$a@ßÓCÎ%?¥>õhöøÑ;uS伂ŒÉt#<)/®«æ¿ÕyÌÅ#µãƒÓÞ‚_ œvéôäÇGJ@ì*k³¼“¶R/ꛃ:\ì~˜,¸˜òaj~cíÀÕÔ¤tíx ò ‡ L¶Òl«U³­ CßêšjU\×0Eèª _ô¡0"Ç·©•Œ™kÓv2­e­-¯¶z—Zt§ì¸²õ,i™º1k±Ý@UÀIò´žåªG]³Ve!_ÀseÝÉåà7zušã -aàkBc°]ã¿u@k´6ÌBà [Øåp-Ú ïß›¯ûŒ0úê⻃þjösiðÕ9ôEp§Ö†3Þ¸ÕÓ£5D–è½=ٸϕäꉤdî]ßÀò<Úæ•´î‘e+³!Ö»U?¦²Ój³±ÍŠrûN­a(lËüyNÅj§"“µl2wuæCÎe›xü6þÓy1øoÄÀ¦Ž|ƨºìO("ó@dfD²4Yd!!2t¨Ã‡u¼Z|5áŠ{†Ÿ»ºâPÄC›@²`̤QL4Šž.2¶i<êÐ@ÿ Ièž endstream endobj 1644 0 obj << /Length 733 /Filter /FlateDecode >> stream xÚÕ–ÑNÛ0†ïû–¸X*5ÆŽÇ™´ Ö¤•p1u\„ÄmƒÒ„Å逷ǎi˜VÆ$ªª›Ä>ÿçsΟ 0¾Fƒý#ŠACæ1ÍFÊ@€1d$Q ¦áëèdÿˆñÎS—x(ô±(†wêªÌRé.E½(‡®:‘J=i€ÚP*íÌFÀõõ˜B ]‰sËÒš×™turàb÷ÌJ…Q`”ZLJ)!NWÙç6„ú@*Á '¦.¥t½¼ÜdÃ6fÐóƒ'¶ù²Ý£¸ÎÊbèú;y¬Ï<èQ™SIK)¶ÇI¸¸©3Úf}Ÿ#ç¬ÌE²Ê…t…ÿmõ÷V¯ó€aèûÝ<˜¼;‰®0+Àû§‚j‡øçYšÕVŒÃhðk€›…ðs73D!BH–ƒé©ºx¢âƒ»æÖ% j«JÔ8ƒïý‡,˰Z#ȘÏä~ѽ¡hepfP¾ ™TÙmÓº¯8îs¦ÖÚÎºŽØÔɬ¬¶--ËÞ^­§¦DÊkå&¾s#’úÉ »ˆ®Öç1Ö9/e<½`kÁ-èÞž ŒsAÌÑ$ÞŒ5r3xî»ý£ÀÖ®¯~j[ðÒÛíy½s^tþXä¹ü‰|t?2* „ê/Ö3›'!þ°m‹:ʤ\‰qYViVĵh˜Êkêl¶Ês3úbÑäòp¡ÛÌMâ4[mbîbþ&¢ˆ—â¹-žBÜA}UZ¹;¿<=ÝáÜE QÇkÔKX&á,+²Z4αsÛ¯ägÅ`[&ż^ìæöíÖSg%EO—k‡Þ ûðxru-EÝ¥K´³ýƒÑ? Êl®žw«J¼s”,â*NjQÎèï[Áï§YËt³fkGiUÞnäöª÷ÝJ½Ã>ësÏ endstream endobj 1573 0 obj << /Type /ObjStm /N 100 /First 963 /Length 1645 /Filter /FlateDecode >> stream xÚíYKo7¾ëWðØ^¸ä 9$#hp[  ;‡¶¶мµ…ØR Güû~Ci]+–‘µ"µ=ä`kvõ‘üf8å‰3>Æd‚èg6…ô³Ï‚àÛTð†X¡B†’b… “7ž’a©/‚ Þ D0#1ѱ ÉÄPTÈ&–¨B10:&g$+8y“XÁ‘MJ NÑä\ަ”„‰p.(Ár.+CEzVŠô¼þceEJ)W~: “¾×k°è€„Á«RY)±HÆ(¡ ÃZ’”.“¼Êø— güe¯ô‹¨*[ðXª¶jÂRÕ-x,Uß ¹ ÖÁ#¹ªqC¾ª\¤ªsɆˆtÌN£xÁ¤Ä¥®V E¥'Î’Õ·Ø™ìcµ"•Xx ;ôKJØ&WT=— {µ"¹Î‰Ôˆs0©ê1«Å$µ¢xìyðY—À» VˆX™ø`8yµè€p+êuføcRÁŠ!ªñ„R,0üÏé ¤RÐî$¥®JA9NH«=Âl™iµ[!«?¼*THIÀe£[)D`±èE툕 64Æj1†ÏŠn¨0œ6»*©×JîwÓYà·$j<¸±Ò À—x…'ØK ¬D¢zPÉéà)Ià zB*•“º¹FœD 9ÑEcN"AÒ  G:s&'ypt4h^™3„M@(Ÿ˜æ÷?þDl8˺tb«Þ0YÞÜ\ ž=û š¼ а¹Ájnè‰öÎæÜ—Ioc´'KðŠ~hfؤ¯’¾DŽÑfDûwôÎèÀ–é <žNæèÈ4LjMM)uØ1bTôú]ºoà iqýM0šÑWH Å­Æ`òæ·ÙttÚ.Ì™i~{ulš·í§…¹[÷íç-¾^µƒæ%8´“Å\KLyМ´óér6j竲Sß½i/ÇÃÓOæLWÔ,‹\p…†3ŒÖ‚Tß°JâJ©fH¬–—‡F»¾‹qø¨`â~èÀb™¿š…mð}™Dë¶nöÐTl)Òí­fÖ~hŸ2™<ævž¶éƒ÷kÃQ= jчÜÙíò·Ëßàvù)n—ŸävÛÐ8èÙ Ôí±Ù)r´È>ßÑ÷ÑIlH½ÑL–Sß½ÄYÚ:¦rú£Áµ‘àïEÚ®Á%.<®5©þÁÕ<ŸL¦˜ílu¨W>õL¿VZ}A¤4§Ëw‹úüz(Ãtó>Y=ßâ¼&ÚEäb#œÙ­O°çÕ¸§¦ùyúvj°9?œü5±—ãÛÉð¶Ûçóùðój¯½Ð!ÇV›ËŽ¥bá O£÷ȧ°-8æw|8á“úó9m—³áâ>õnmÚz§Ì ð]ÊŒ¨½>öDc^„™ôE‡l£Ï=Ñh¾` 4ETê¾6ጞƒûÚ„9XJ©'Í¶Õ ~h46º´Ã)à~nÚÈZ{(üèàæ&_úå&y˜›´¥_¥$;A:!í5IE„›^ ¤Œ3d6äÅê5 ¬ü£A8ºΆ£E;;?_N®ßM?»àÎÏ?NÇ—ï~Z?,'ó÷ãU®Ïã«ÉtÖÎ? a}s6¹Ø_2ñZ§·>PÇ¡7Y«!„3GzT1öïê۔𡛪UæN ŽèÉùQ%&ËÛv6ý”X{”ËÖ#âÈ{KzGÈ!!ü‹zÔ$Bî õà>øŸ»±É•à=¢N¸'¬åm½Øv4ã“ûjÐÔN=Ѭ–Üv¸ÜŠ& …ËaÐö½™èUHººØ¹z„-'Û@ßP=òºVpW=¸«œ:áÓƒCw {=“CÅÖWa›5«d5bD áüùxy õfÿ¹=¹ίím»¸ž^Î÷x I‰6£¹Ð ʌڡÀXâGŒƒVß|G, ‘p嫼ÞLoÚÑò¦íxn†ó=² Z”à©+½YfÿtZ{7׺ÏÝ>l§ú›sÈ­Ù’¯›§íÕ-vr¸O'‡±yt\è);fìƒEÒÜØþ] …'ãÙQÓv@¯wàöqx3¾/öØ©úÄV‹¨Óh#‡@¤?Ù(=ƃ3@xJOø ×hÛÑý£ƒ £dë8Gïý7–rj‰ endstream endobj 1671 0 obj << /Length 1299 /Filter /FlateDecode >> stream xÚÍX[oÛ6~ϯЇI@¤JÖÕö¥IÑ!èCâ ’>0m3“)ƒ”jçßä¡I–d{†¡hÅ0ä9ß¹¬k¬ ×ørñûââãm”sgÍ"c±4<×uü 2bÏs"n,2ãɼÆÔš%fÉ ’q{ƒËuaÙb#ãÖ÷Åo¯%áÉögî<4ý¹üå…«U‰Sq[ObؾøQ|•Š,;t]ó!€¯R’ÁzY0Xp²¢¨¬µqW­<ñ‹ÔV¥ðöKZm0#éåÕ·¿äß!9ƒ2\Ù‡! Ý?‘K€ôª¿ŽãèUÆŠ-¬~ƒÏâþñæ»”)¥Ì|aóiòÙ&F€Ž¯‹Ý³ºÅË+NK±òô uÇ–aœ…Nâùp늭„‡©åÏÌ’wâßÿ䃗8~¢óa?”Yæå­¶ïû&Àìg\//#/2¯ôñÇI &Âòþ“”t=9!\A Í!$}O‡N\{Z¤Î´èh6‹ÏÊ:ä–B¶EœãÌRªË¾E¹Æ –ý:=βÊóié¸Òe""4ÅT °HqfP䌊ã“a|]Ñ‚‰h.œYÒŽ#HOU€òC×/~ãÓJªÀü[ÅÛ_a›,1áæ·Ç»»Øêj†—¨ÊËž|T`Є ½žé"Õ›§=${D+V£ /Ÿq‰H>ÜêÆZ\ W¿àrA8¯ðuñ^0Cö|²ì äy]eØòLpY`ò-* ªýWןe{fFı¶ÔCG&n·÷(#ÕiÚ›*N[¬vX[Ê6Í'šë:Øc*¡;d„ÑJ6k±á9ϪâÙõ}Û¾‰è*ÇÇõî, %%>3Å=B'n*”¡¹°’Àļì¶SŽqSÝþª"k¾¦ aõïK«ÕEÏû0Êœcº*×çyVeKµ‘ÿ¾(u¸ÓyD*“Lf¶žË[# ò0 O„}$Ï)fMÆ!ÀÂ*jk“Õ6¦©ž¬„®ºí³„¦næ:$Ç1òêE¦ßy‰ô4•> Q4&¢ÇÇèMô¦C:RÌD¤½>Ý$¿œŠÃg·9’±}ÓCBË?@Á«Í±·.$^fEUžBYÿ´æ‘˜@>«‡'ÿ®‡ëÙ+ZÒTˆ‰N˩ӫ\³º¶Ó"¯6”êM­(lƒ’´=ÀæNèÇÅóÌs°8ñvxvgî`B$þ7]S†…Ь~z·ð/^N¢$å _ø—¾OÑÕ Ò„Fý›ðÜH”H¾ˆ%æðæÚŽõÁwÛåéTÈÔ‰Ö˜/õ‚ùò„J»ÚrÁ‰Á `&XÓI çþ5Êö””Eýœ“æ l•ôs­ÿ:h¥~ƒ¹'ãÔ¼ð@îy8™RûþV‚A÷ay6›l§I¤ð]Y/É#­Ñú)´]žÿ,¹wØX±*@d:ŽmÎtÊ å—£Þ»½º{¸M«ZeÃ@‡æíÍââ¯h)m endstream endobj 1686 0 obj << /Length 1128 /Filter /FlateDecode >> stream xÚ½WKoã6¾ûW9Q@ĈõZ ‡4í[d·hãíÅ»Y¦m6²äŠÔfýï;|8‘E±Qoa@¢ÉἿ™‘ï¬ß¹ü<\½§ÄÉp±3]:Ä÷qHc'!ÇaæLÎ Qßý:ýíê}œv(g^„~†nÖ¬pƒ=ÜåêµSÖˆOù†©[ßÊAIWPêxAC#ƒ Ì«%¯¸dFXO­zçz”R4]3× CŠêíÖ¨ê†ÙZÚ›IOMJˆâþÌÔñH„ƒ€Ñ%«VrýŠÔ!Ž ‰‘?DïÑÄG| ªÆ’JUµ(X¥œ"›š/„«iòfÆ›¢-óæÒõ"?D5\j¹`]@¯´õœƒÙÊÆ¢¶Â_0Ë»>”¿Õ7êr·ª«¼|òÁYt5°xﯨë/1¦ëÊÆ~8u•fùç‹L˜éà5å‹t!Dà0>ŠÐ߬&ä˺qõ‰4y‚)e)Fl°1í\09hÂå`ÌïÙ 9Bi„¾æˆâdÄK¶°Ú×=+(XᤠÑÿ„‰ Ú+ø?¤æ…\ЈÔ—&=_ôu¾ºƒx6Úb]?Ž…ú¤N‚¾qÁç%(¸3š5L¶M%^uå§Ïwwöv=]@zé÷Ly$ Ñu)ê^‚<¿È1Å–¤8LSÃö†UŽ^QæBŒeÞAâܳկ¢%—¼® 2A€Ê}íK42Õ–fÌÄ»“€f§¨fsõXîDëc]2(8ìGsß0¹®çåYçÇŸÙ€ƒŠØ“t~cz"¾å%_p¹ëÉøu:ùgB4#òÔ™#’aJb§ØLf_}g‡€Yf©ó¨I7t<œÐÖ¥s?ùc2Ýößà ñq †E~mkVþáöæÀü8ë÷Ä”úèFá 0„ëVã…Q‚nófîFå+å(*8 ¨øð,4ŠïAsiæã £§˜kÌ¢S )N2bÌú…‰¢áÛ'ñ‡Þ9œŒö%$±^ÉËòÕò¶*^-ýuUÚù¸†B¢÷ wó†-F ¢ûY(?Âú–@Õ/~äׯ 0øè'óº¸gm“Ëßçª×â Ûˆ|É.€˜Sµ¯›U«ªd )F•}CÉúexf.¨ºãcûËÍb”—-;)âV™ºì›N·3kTº«¾,[µ:¦ã §9¤8NáÖE5$N÷LÇÿ.ß Ïêè5º×°Æ¥¾kÖpîf$ƒ=3ÌÀ‚WÛVÚ;\È'ÄN`î8 Ö …#ÿÖ;XÑß8&êªÛ'O_:foïXÚ¡”>¥{¨»Öoeêyqþg…÷M.þ+U. ÜM,±ÜmY¯ Šü¢¨ÛJŠ K{±Èe®KÁÿ^:Š×ÀtÝñ¸)½Kͦ`bìûTÍG¾ýî:èmÉÝqŠCcçx©wí0éÚ/YkC‘µ%VN×c¦Íª}R)ïú õ/BìÙ² endstream endobj 1701 0 obj << /Length 969 /Filter /FlateDecode >> stream xÚ½VKÓ0¾÷WXâ@"¯;/!ËSBhyláR8˜Ô-EMSòX–ÏØã´I›V»Ò‚z°ëÌŒ¿y}cF–„‘7“çÓÉÅë8%Íâ0&ÓáŒQ!c’pNc‘‘éœÌ¼eQ¨ÍÜÿ6}{ñZòž¸dœ&©cVPr#3aÎü«éäׄÖ¾³'•<#y1™}cdßø”¥ä·-ˆ„Ëi¬®ÉõäãÎÞájáˤŸ3Â8J©ˆã#ø;Up;ëéÍ‚$•Ì{£?Qê]ë¶ò#î©Æ)×V{Ü!™R–ÜÇÄ-GÂ󔦉@Ü/uW«m³*7ì{¹à) @]ÊÕ?´ë5x#„·Ú,ʪPÖ=ÀUzÛJ߬ʶ^ÿÁóªuyçµÓGñæ‡ÆÕ8[ßý нŸ:o¨«¾gÆ”Éa}®ÕRú3â_2柤õ+‹XùÝ\ÿ€0æQJáÌV"˜ BA3ޡĵÀµÐÍrŽ{ˆnòµªkt$áƒ1_;ûÀf]õ±„“ qÝ}Y-ÛBo|zM}61§â Á´™ÆP&aâ]nŽJçPë0\Í2‡\;Gš;œWaj¼Âj‡Äê9^Ý”Ôt…[[ ~ óúpòQv9tÛ@ºRä+™W.pµ ŠtŸj{Z⺅†t†ÀGÛ]M+Ï*›´pól`li¨­wgæmN×wx”a ³É{¬G’˜fi8¬YÃgbìtz‘‚=§h'›…ËIa›.e]·;ªÛIÞøPYØ!æÜ´÷È鋟9­û®#¤W«}1)G”~À=ísÆ ìì³yQÂΥܠµa' çÕåVúW«ë¦«ßƒ@€·Ñ÷蘒ÑÒ÷Oç®¶XGЕV¾¬kõ'z?Æ #8ˆ dæ®Æá«q+\n"³Bk‹xd(Lj:Ó㎃W’ɇÐaÒ¦ýC hŒ4¸­: ð£)©–¤Û~:j®™ÕÀ¸žo'Ë5=’µŠ‹ª,\»»€ÑVˆ¾…GA]Û§‚ùφjuûþ$Üq‡‘‚ò½5…¼5<°m Ó³/ Ü[ZuG9h¬›Ì}>Y¹§†ÃâûÖ½Fôz]ÿß·ÅQéšél%1Ÿ—íÆ ™£Q<âè\5ên’ÅjCÑó¾8;)»Ýiq÷"Î붸ˆÅ%ÝX&ÁH€º§ÈQ aÿr4“ endstream endobj 1715 0 obj << /Length 1301 /Filter /FlateDecode >> stream xÚÝWKoã6¾ûWèHWJ¢°èÁM7Åi²í:í!»F¦mmdÉÕcôחálÉQœ¸P Räœç7Ÿ]ki¹ÖÏ“g“w̳šD~dÍ–çº4`‘{‚Ěͭ[Â|ûëì—wïIÞ:—øœœWR4rZ×ÂV_¶ã‘ë;Û CòM¦ œ¸æ9õëÝàZŽ«¯_™VËv- ;ðISΎꞸ¯3·Ó€s¼(-Ûâà†+oû1™ÚN¤±Õ| ڗΙËFÅ4ƒ½¬ÀQ48æRÔ 6«¬ÆÅµ(L~À—Ö὚óˆl³<ÇÕº½«¥¹¤Y™—Se¢ (ăjÅM¸¯ óh†Æ0 ‹ã‡5Ž:¤ê!j;Ì‹ÉÌæ)q«’™V§©`“y›JÜ‘hµGÀºÐË;wƒÎ@«˜¤:ëÍ{8r‹“²—þ¨HÖ¬´æîPi‘ÍKPe Ê —Ò¶)¿¸Ap,´ÎÎ`¾ð.VGcìÅýëGubèév%+³ Q…¬3QÕ££ŠÕÐEDöI¢v7ì²åõyšÖíúEs!m‹´Ù•ç¢ì<(ò´ÍE“˽u8Sw×'è²x{]Œ£Œ::µNR‰Rz\£ ¸TÈó#´uÝJSâXªR3Š®e³2Q#äÛ¤õCª õøÃN""òVŽÂõak9€éiaN©?Ê­ áô÷'ößjõ É<†/@—²²<è?f“¿&ž¾ÞÛu8–¨1æVºžÜ~u­¹ÚTJƒ„[[-º¶˜*Ö˜jž[Ÿ'¿=Û°Z’çÒHiÆâ€]¹ï;åãõÝHsŒ’%>g®:c(Á?7Aȉ(pÔ7Á4VÓ2G Ž<ê‡Ñ)£al„° ¤ÜаŸdV™n`ÿ&Î –¾‡¶ù.A>kdQŸ:¢‘T[Tå·„YØ•”úøâ†®¤K~åÃ¥,¤ZñP~ÐЕ,v#:[™””®Óæààr3†ãå¢ÃE‰em¹€²Þ´Í€6èyž}¸dä¡Âô5ÅwS‹¥<Ê“^É—žä%¸OÛ™hv6°ÉÕÙ˜€¡ 7¢CÖá„®K~ÀÁ½dÐÀ^¿—©«›ËËQÁt%Ó{Ú…¡wâbzùùÃ胲–3âOÇ‚ÄßŠÔÆ'’Ú›â9æ/…¢Z™mò°È?t¦škuCuÓfŸ~}U‡â'±ÞOã<÷½)SWÍu5KúžÍåüÌHšV”¦È »™ ÄOšÂˆß„3îö*™ÅIðcGÁhx"‚Å=‚/ƒçŒü©Ù1¬vìæ€4ÏQá~ówÐÃRcXëQã8v3 Æ°5Ná°¡Æs”ëlVÁ`ßbØ(¯˜ôv4;H·uÛÒ1ÒDsó ©qüÿ Æ|x/s¿áÏÉ{íÀÇ!ïËŠ¬Étåup°û ¿‹Å Œ½¯/{÷\‰Ãc÷u?òžtL乚šÚ¿Wfö±X˜™(æ ŽIb¹”æèw;D®ú_퉮¨i½U}¼½+–÷ãéu§ endstream endobj 1738 0 obj << /Length 1135 /Filter /FlateDecode >> stream xÚÍWYoã6~÷¯°J‘"‰”%mÛ‡t›,Ú‡n›xûâ. Z¢míêðŠTŽßá![vGZ4AaØ–È9¿g˜?…z€C8Bø gÝõ«½Ã7M.i"ñ³CÙÙÁpBOƈŽ)_šŸ¡ A¶ ’T– ~7ºÆà¦ñ!Gšz %&Á~×kó´É7²×ü–®Kãk«ÆŽí$ŸBéH7ùaׯñ!Uø#—ç|p ~ÎÁ­¥ú0ÕMÆMI©xž±î¥¡YÞv/b cÌÐ[ã¢Yµ%LV8@âôÕñŒ½Ú¸Ó€’ØÙÚ„-• m óQ–Wà*׫õÒìÂuÎ7šDtk#àSÆÉ’‰KŒm«1¶©6¼-¥¶…2AÎ^r“†±P U¢Ö[$ÛÈ M=™YÍ×âÄÎ1¾óŒÿ —7»ÆypÿZ-ŸËàm›¢ƒ‘«Ó¼I 6HS›už òZö"J_ÓK¹^¸[C<µó`›³épST–Ÿ¶$ @ÙEµ*X?Jàö¹U¡1xÃbÔ…ó¸aÿ¯ixD ;˜ˆ™•ÿ_»°7Œ endstream endobj 1760 0 obj << /Length 1117 /Filter /FlateDecode >> stream xÚ½WKoÛ8¾ûW=I@¤êA½=¸M³@ìbcw/n´DÛlôðŠR\ï¯ß¡HÙ’#+q"¾fæ›Ç7¤-´Fúcòy>ùxƒm™‘ïøh¾B¶e™.öQ`Û¦ïFhž …†±þc~ûñÆ;'†…^ }))©¨nk×,»§IÿµÔ Ï×~Ò¸bKû:Ÿü;±ah!û`ǰiEгÉ⇅ؼE°…h×Í(vaœ¢Ùäӯt&è:c[¦îùžozQ ‘x`Ÿà?£žŸ¶‹-Ó=[£âŸp×p½P#ò#t©MGrµÍbUiöcƒ«x/½Ä)ómÇ´[zyMy\²mÅŠ¼çÜÑÉ~ÚCdØ‘éø~7Hàˆë6^§˜˜að’ì’|Éúœñ¤¾oœ¬é `Á0ï|ö¾[ž%t7b.œ·ÍÈSçi¶¤IÂò5¼–¥}’Ÿœî„Ô—”ðþƇŒT%ûõví«F©¥ªÈ¤yu ß¶,„ 4y#} @ö=‘?¿ÝÝ åUBûf댖,¦Ïx /T¿N‹%I{go¦w³¯ƒQýIâ^•d÷2ÝãqïdÊxÕÂnŒZh7Ÿ+Öi¹†@äºëh-ÚgеS|ýÓã4ÒÀ ´©¤™L°$ÙŽA[­tÃÖ6r³Ú(NÆ4MåˆfºjÀFøÆX¢¤o†!>©æQ|îÅøVÀÒºT“sF†p¹§´æ\ n'qi%RàÕxq—v£X½+œùÚK³5§‰X¨Ä’4®ÓCï­6ŒËQ $9´s¢_Šø¤¿Ã””æ¬"yBJ… di,5 ÏØJÝ ÛmÊb²LiC.™û¢< úïawg¹ßCˆµX‡ñ†”²\Ê%h/T1öd´amEb–²J†æiÑð¨x8œ¬·ê¤,.WWe‘Éu"8‹4fß-Çrn)£iFoF¡ÓoFò.qß8Hu¨šêh°`ël+;BÌVûÓR"\&R]ìm£î'¦™ŠTC®ê´—Z¬=2^“”ýe$*r.¸Öö×ã±ç?Ïñ{Êë´RøUôÆ¡ÂnI,hõ0}b°S´®óKˬ¹ZÆ"â+.°Y*&0``k— ùåUQªM’‹ÒÜ« 4ìªåÌYÚ²–kâçESY10°é°¸cÕæhò\“îôŒ°ÔнÿÑ#_#iM_ó‚œ*!ø3CT®Q;¼’Eÿ}9^ ¼=UÍhÃnW›¦ÌW¸rݤã8]–ˆiqüÁs+è¡{"r ²+³ ¢Ùò ÿ‰”b¹(ThO¤£*£ÕFö „_@!ÛЈ›gãXµ«‹”ƒGåÒ­ý›é?yÚ-ÌÁBÏ7«ó„ûM‡ïcÈ<|'—àñ¾¦ïdk —iõNäõ’Ó—{BmøÙý?'ê1à endstream endobj 1667 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2022 /Filter /FlateDecode >> stream xÚÝZMo9½ûWð¸{¡H‹@0@&AvØN»kä ±{2ÂÊR ɋɿß÷(·#ÇÒ¨e·f€½HÕ­"ùX¬b½"哪qÆ'M&&~gS¿‹ñR(TãK„œ BÕäMÈÔÁH rv&F ©Mþo‚ÉŽÊYLŽJ!š\=5E2•«)E üî%vëKS‡†xªe ˆ©I€’|A÷]çÄÇ‚.k`¿%˜à2Û¢Ó@¨©raS|„(„X $ö‰‰ œY©2ѲAò #jH‰ `ŽMQÑoV´€MBiÓ«R3\Ew¥™®&j³ì*§H[ˆ«­EÑ\½à"4Mv°£´ÅH”ÄW”0#Hш†BI!ÁŒ’‘h—!¥ÖýfßV‚ÂJÙU#űÇðEÛð|WÙÀGo’7ÑǦLÄÌ '£¯|Lj©ý˜MTôTa–¨ +e4LŽ(}‰"Íâ3Æ‰Ò ¤Â¡°ð±TZk¦ÍÃ2\Hº‚$F£o¿Fƒ†j”ø!%£¥,d£µY†I¾Y"T“Bb[®|tMò&ilR0‰ËI \¥½‹˜§VŒ! oÅ”¹Â¹9y– ‰ÞÄ 9áE‰ž˜áìy 46ÿ¦¡Ð‡ºÖž®Úð]Í.’SC3¤Âyc¡3A )+t¬®Í«U<½;£«"Í4˜sLLI úcÉš/^½º˜¼5Wž£8si&ÿü׿VV0¶¦bŒ½¸›Ï?^|÷Ýÿ©¶|û¡Ú>Ø Ÿz¤ýn¹Ø˜W¯ÌäúQ„hköûý|û€õUDëý]±ÿ…;bkû® > óÉO«åõûnc®Ìä§·ïÌäC÷ÛÆ<ŒûáËç?L?u“7ÀÐ-6k†rp1¹ìÖË»Õu·Þn›íÝÝÍlúýò7sE,ˆì¯á#š®Ðš›É}ã׋Ž]m÷gâùfئp1y÷ó¦=ÿc¶øÏÅäûåê¦[µÎÝÇÉß'?LÞ\ùö@<טIpj=£7'›± õ¶Ò²%[Õ ½×Í–ïÍäoËKƒµøËå/ ûøVËÙÍú¯´Ìî:e÷ujmË„­À*ö“§‹º«Ü/jòÎ:Dç0혽Äì0má·/‡æ±ìzÏ#Ùq‹o\)):—9LIOÛÞ³&o½¹åã{¡ôB½Šëß ¡dLÃfg™A’ αA#ñ[Œ«õrÐÝVón×Ñ^ˆÁg‹t¡)YÇ=¹FëC ZäÑã.o/o¦ë_íõ|º^‡*H²È¦ÈžÕ:Ò /60sjµ¹ÊŸK|²îVë G`ý¸œw×wóî\°jÂê¬XYædT·Ýæ×å͈¸bI6À¯{\š³e>9ì}÷é 9ÝÌ–‹óX¬÷zÉØ]A¥}±5(6zñ§Ýh`úˆ@yÀ&¡Ú”âs°ýw:ŸÝÌ6_ž¤¥¢'¤¥]å®QÆ…¡ÚSðzíÈ\ 3 Ô· ÅÂÂF_†jGìæ:Ô‚¡j[Þ³hk°>Å\Á^;7¸§-ú ’¹ËÓ„¯$ó¹4!»=¼²¾€WÖQy%Š|AÙCr¶°hGÚT„(m ‡÷Á×ëõô‹~½¬½Gï#åR Þ‘öùõÚRmÙGXhÃ"ahߊ|"2Xl¾–¡H¢óØ^ë@m‰n¬ @Áxr2Pi‚'/#ñ ½GÑ9BÕ—½>‰N¡<7:y¾Óè8wÆ S$ë©MitвÏ`IË aúB€´CVé±1óÈEŽœ±m 1ª¤ƒ8¦k»þ<]­»';†'ì»ÊqŠüÕ¦­Ñc2P;Vgu_¶C¤)§¡¸õ—סÚ̲EõLç-Ï6)OƒMÒ°`˱< ¶Ð[½ ½{A{!õBî…Ò ÷å53ï…¾gé{–¾gé{5ÂCcb)Rãu^ɪ`‡lA‚~?¾G¬ÖPÛ‘) ˜Dxgl;¬Š2kÜÃá R¿œÛÑÑ §–vͱEžby‡r Mƒqžâ,FBúj î¿ZOƒ´¯ô§dTgy/ ÑÄ‚ÒÕbº{½ÀÊmjgà GðüªÇqŒ$ Ôv­±.Ëíã›ÙíèHàÂDï‰h¶•gGÇ‘,¦·ÝzôˆÊù¡ôpbàaž…sÛ­>ucca4+6¶X”©KÓQ,ëÏóÙftÏíÏ\ÀjÚíìâûázËÝÏënt0!‰åÍ“ Ž…W˜ˆ#áÕ$8Ÿ/å´£þÚþšAïBM–WÑŽÄŒ§óÙÆ?GôȆ¼È b%X‡ÌN@¹êA(?,~ÑÛ íy ×îr±É$5A”]:ý†Çëéï®òqê»Wå/o]‡i#«ñ”}¨v@]²·ß§-0ªœGËQJ¨ ê7´ï€â¡†Êž']Õ?£ú=ÈÁÝgAÈ“{Jȵ<ŸÇžHkO¤µ'ÒÚi퉴öDZ{Š®=E×|jMz"íï#vûG‘ÊŠê`ܾÝ^v7w×cÞ…xËÿg³‰ØåÛ/ëqgâ³)YGÛbB”YÇÿŸœ†él„¶?eà’yMí”áwÎ$¯Î°f oVÂ× ¤ñ(”s`aUø×žþðÅGëô(ÒÚoÁü«î57 endstream endobj 1770 0 obj << /Length 756 /Filter /FlateDecode >> stream xÚÕU[o›0~çWXtÒ@*®Íi{èzÓ¦ªÝÚ´/Y4QpR6 “­ù÷;Æd©³vš´i/ÌwŽÏåûŽ Z ‚ÎŒ7ãà4ŒQ‚“Ð ÑdŽ(!ØóCQŠC/A“M­£–¥;µÝغ´ÝȺµg“w§>ú„â(öÀmoâcá û#°³A;n›ž´9yH«¦d\±Üµ‚ÇÅ`ú}Ü1rh„#êJ_yÚ¥¶b½räzƺCÎÓõ1üùHÒÜUÙ'^¥e9šW‡æl¶/‘eºf­|}-“giɰpj‚-B%8 †"5WlÚ¬®qÔƒâ,—ìp’â¼UýÈêÕËWÙåÝg–uÂko/*©>XuÇò¼X.¸r,Ä÷¢­»´+êå¾îì²NõVZ8ïröí–æþ…­Õ’¾?2U`,©h’ Ý顎&ÝM)“‰ñÕ àŽ ú“Ççc†(«ŒéŒ ~‰ØKbô½‡VȪG¾`n‰®;׋H7 Ä‚ `u©"–ËÛ-„ÉÈrꄱ/ZkÔbâ6¶ã±uÝÈÏ"-åÆQm®U÷PhíH0µø/Ò&&®û;iËô|Í,ð#Ä:¤wÌxÖ`‘V§[c¡×eŒ#¢ŒHÌó ÓM–ðY:0_êRFŒ25„37Ä1 ¥³ž.Øó§ÅSQAÏ„®²‚àÃ,Àµêz8 ±·'מ\+ÖÝ×¹|Ÿ×ƒ†³è,S‰¨Òñ÷åä84†-»¶.r­ÖF(ˆ‚"M6}äI?d%h¨Ý&ËGöU]²l%ñX…7ççZ¸F°CgM-~{ìt\<{r™Vì ä6ôSN’qIu’ü­F‹‹Ï[û?êt·nÔºe‘ÉÙ¢öW…9ÁÌ6´ìo@}x‘o±æír®…¶p׬žI°îžm.óJÎÿˆ¸áÿDÜ@!î£Éãÿ[r`l endstream endobj 1790 0 obj << /Length 1019 /Filter /FlateDecode >> stream xÚÍWßœ6~¿¿%5RàƒU}¸F¹(išH¹Íåá’Þ]RVØ›tÿûÎØæ· jÔT'½öŒçÇ÷ÍØxÖÆò¬—¿¯..¯CßJÝ”ÌZ­-ßó\2+ö}—ÑÔZÖ ™ýyõúòš%=IÊ|7Žœ£dž·<“üÚòÿݢʅg •¸§ëÐ*e'ˆa‘ê#>y‘Z áÔM}½üô©íDžGn¨w\n›BÏ×M«'y• ¡½ŒûñÜ©Ý_ôÎÀ‡;R•BN©LŠƒO’4Šá¾»§=åtªåMÓâY“Úbzk×T¹Ùg²Ìª'“òñ㼃w¥ÈçIº®«–~ ìç wÃ7;^KH@SÿçFËdÿëlÇÿÖÑkÈnØ/i?ì#—vrWíæ Ù4 R šÁxá„ù‰K“¤Á¸ ©ÆALL>m‡R Z¶mTËp§ÚFº, Ñ?n`­‹Œ@|`3${™Ú¾lôØÈ-oõTÑ_yUÌrÇí¤ST9edàÏM¬Eõôý+wN0Rd2s×-2ãäé(û½”[[Í„ÎtutZ.šê&ǽÎ]ý«¬¡ÐwºPÕ–=ŽÙROÿœ“†˜¹i Û|¶3ò•Û>ÉåÉké^½Ç]¸'“aêߪêR¯õšî¼÷‹™ âÇ À^pž`Ç@ªµ"zÂø$~Pm¨ns:±â¡2¤nØ^NB¥Ï«  ÈjÞLá XÒ¯!›ÖD ÙgÂ2‡"² {ÖQõY²«>ny=uù8AôzÒÃJíâÂqÉAaf9’g‹f>y×eÛ”gú(œ ÒéBÇÇ7òYú2BUÄG5^;SUü€³¦šæ×³)&yÜφÞ©Œì¡š|Ò`ûV‚õ^^„-*ÌÇÖ¡‘«æy¹>j‹%ÖPþÃÂDN`µå{èÊæfÒ™‘ÇÊ{,ÁB!¨”z…صÕâUþæ]1Ò“´:ÛVkQ|έ¾êª½Æ¶yØ¡Í/:5ÐEŒ{]ËÕ‡öZHé1!ÎD7QÇÉ.”ª—&ã¿êå½y™ÎFt^Õë3÷tÏ·}ÕÈ{"kOÊ6¯ø’çA›åaN"ßkÁA;Û ƒŽ 7ø»¦=¾IdûüΠĔٌ«òªÞT|Øè³âëAAcòaKHç´cç¡·v •Zøätüí;zx^-Å>&ÎaTîu/’\Î â†c²J®*xPL¿¤gø8¼uî?¾}œ¿X]üOvíÛ endstream endobj 1805 0 obj << /Length 840 /Filter /FlateDecode >> stream xÚÍW]OÛ0}ﯰàaŽ´;¶c‡iìƒIˆmÚ({)H ©i mÃ’TÀ¿ßuœvM i™ÚiªT;±¯ï9Ǿ×7 EŸ:ﺃãP£ˆDa¢î5b”.B¤#!P·zø}fâÂ|NÇ&™Mî]vOŽ[2”¥9,Zeçthåæc·ó«Ã K[x'(™tz—õaðÁP¤Ñ}9u‚€P®:Fgo‹õVÛ’†PË4%! ¥$"TÏÒX,2DKö=ŸkAÁ“ û–žÏ¥Æqe?¢Q6@óî÷O«(z¾àoêÖþzuS:KŠrn³n‚¶/ÐÍé#¶9¤šhUmó“'Ù讥ÓÔ?k{Î4òYDTÄ–å‘8™HÖà9‘jíT"y¾”øÆ8•V˜ùVÖyL#Ÿ~j-¿Ð *i’¦Y? x(Å„xǬ+XÎ8™[îï»gܵS Ó¾ë_§™ë$ã8¯BKÕIÛÑWÕšr¸1¹Îâ‰i2l4dp:")7#uk]ç­kööZØîšîJÚ>Û±…J×Pÿldúåüô´múN©¯‹¨£l0›˜©Ç\ä­‘µ&¢€öˆ*Pøì..FñØ"Õ8ñN=?ЬGS`•»jžÌY¾çHâ|˜ÎÆ}7vUZ÷;CFÕe,•c÷£bè^ÃÌ”†TH"Ô…MÒñl2ÍW³»\¢¡IZîŠQ%Û‹€ÑvævW.h@›ˆ¯9~h¸‡{Ö‚z¾?ø‰ÕI-ëdh©“Mº&N<cèžæªµ±‡JEÙ¶H<®#ñ¸;Á¶H ÌÔ¬ãQÎ)!NË#f{p€ÞH£æÚ×’/wª´ãQÜN% @ÊyƒË¢’ó2—é;4EêÚ´š `™îÊÈy¯«Ig ޽=6€ã|Üzз×Í2†Ü5­D£©ouÞš³¸CòËBgæo*›£V3i½ši®ùX$‰æb·µ2SšPY«•ÏÌÎI?) ŸT¯ßV¹¼¹ÏzÅœ·ÈJÈ×z;%3ã >)þƒ’¹E¨öª¹ùÎå~‰G^§ endstream endobj 1824 0 obj << /Length 855 /Filter /FlateDecode >> stream xÚÕVmo›0þί@ë‡4\ŒyÝ´Ýú"MQ§5é¾dÕäI˜wà¨ê¿ßÙ&-$$i§©R)€}w¾{îž;»æÂtÍ ãÓÌ8>÷±™ $ôBs–›ØuñC3Â…$1g™9·üؾ™}9>ãžäÜ!8$ØúÜ0*Ø”­*¾þ² ´~³TH ÃíÎCüžªk:^_D›¿né‚ äw=ÁNÔw66#ÇÚÐÚ•EÅjAEÁënজ7Yûhs-[7^ø¡Øl$VúõêÂPò>w+NZÂZÇ‹ˆ;yÅå6´([4V”‰¯îæw; -Z®Æ‡Áæ¤ZcÔUõž@FaÚìI»+EÕO²>› ¬ÁSÓ—S'fZó×Ì`Z"IlÞ)ÑJ‰D>÷ÒœßvROæû°‹BðŒtA²Ñõô¼€m?ø.(Ù¶˜üeÈU[t´œ|•~i¼» ­IE§JKûp!±‡ü$z.:~äjB‚ÂŽ"§¬M›âv+…‡jfpaÐÅJwò©ÀÊPò9”?¶8¤Òdm¨ Mï®Çå'téÿ~+z,9QT×IÔ%lÐtR¾ªLšnXö·€îô~0uÞ\]ž¼•­ábÓ¢¼`e6ÐÀ{¤3VÕÐþÏqë0§©îq}éËëÉd(Þ‘ä¶á:;}ÓÛ°ŒŸ…ê_б¶Á:p­8e9]•bìŽñ~ì¨'f*|™LMþ)U[Õ á/ƒ@[ endstream endobj 1840 0 obj << /Length 1263 /Filter /FlateDecode >> stream xÚÝXKoÛF¾ûWÉ!K d–oòЃíÊE Á dåPØ…±Wö6|$ÇýõÙYJ¤L Ñ¥- Þáì¼væÛÙ¸õ`që—³‹åÙ‡«8µ27‹ýØZ®-s7c+ñ<72k™[·ì²‘¢“7rÓˆîãÛ‰bö§\uöËß>\…Þ@ýÖ ¼8ðX˜áæ7~@*Hù å˜Uû(e'Ü\tÌsÎ~¢åúó|þMBÊ¢ˆÄŸšZ‡0~C~¢­7“z¥ªÜ•,Šv¤ÉÊ®áä›Fþˆ¸ëºšídt:½ÓÞ¼^ÇÜÌ#öÛ·dð& ’ðXçD¯ë†ˆU!Ú–rŒs»ïL†ù½eçm+^¦t&å÷2.7æÂç:üáÑŒôªÞT];Έ9µÐQŒJ´¸>Ÿ.L%JÙºk%‹|¤á͈ç²PåØÁýºÿ3ðúÏa ú÷@‚ø‚h H~8H¾ã¥ºÆP-wÞFþÜÔjPÈÅ+Ðñ¹ÇJÑ5êûQ/Ì)ÔWÛO™$5>$=$šñ ØÚÚ¦ªê¦…úKæÄ¡¢¥L×ñ¶†U›²Ò§µ’ØÍR‹Ú ¶këø¥Õƒ55Æ÷l¸x÷+ª“²šÛî{$¹lÔ7R=~XÕ×Ùž+vcîïØÑG>Ôø.Œñ¶¦jN§T•ê”(ú„´c{9 71x¯ïîÑH|ŒäÊNû G}ñ0ˆˆ©ðAtª³Aã…¸Ô µôº×—b…‚ÄF\¼7¤f×¶KÝÊÞ›2îxêVƒìuS—Ä6áDÚÒ»Ãh»¶r¸<~…Ä !\ˆ¹Þ4ôe°Š¤h$¨žžÙ»8_ ÚåÇŸg÷—óÏ7ËÙâþr6ŸÛiÈ–¿šMõLUA°°OQ§XɧMGd)lí±Fõ)LM³VvS¯†VÛ+åëÝÕä"À% '5Ñhz?¤¾®ø±««Ò7¬M4R:z îþø¥ð^¿'2òMà‘ìGîx94×Éu¯¿¤– @F‰÷äM,Ô©T4–4*P‡FiT 3p…À6HŸ¤©—¦>× E½H{+-‘¤½znxÆÁ8Øáԙ¤Á®3, â.ä¡×_C¤jZï¸Ïøç?ܲ[ù$àÉ•½š$C-±*êj@)ªQTôîí£jU—OT€ÊÔ“šxéLë_÷½ÿIéŠ}UÕè_¬‘…üfÃ&†6LG9¬»Ñä(T„ê9:Ìs@f]éKg:F„/Šá¡Móp—Π¬"dž—ð-ƒŽ6Do_#(öªsñ©öÙÍc½Ñí¾èÍæ…)cîºÁ2¿¨)gÏ0¤`Rî'k¨ù˜··¨É&™A ²t;0»8ì,¡8j…–ZR½±ËõÖYŽB ´y+òÇ3¶ àP$êAiÝ»£þÆÐHJ=Dæ.æ¬íS7Ô£ÁçàŒ|àÍÇÙPƒ×Ðw:xûAy<¦ÃÞ艀†izzö1óTµ[ÌŤ3L>_°8ÖOž8ð E?lEl"jZg˳¿¹ŠN¶ endstream endobj 1849 0 obj << /Length 1320 /Filter /FlateDecode >> stream xÚÍWKsÛ6¾ëWpœC¨™æûÑI©kwÒÉ$ÓDIN¦…IÈbÇB€¶Ü_ß}€ eË®ÝSG.»ØoŸ€<çÒñœ_f?-gÇg‘ïä"O‚ÄY®ßóD%Nêû" sgY:çnìÍ¿,=>K²‰d˜{Âc8‡dNúnƒR3Ïž=~Á@:Q[„i@z‹ fÈÚBˆ=å[¨ÎI¤î«þrhT;2×èù" #w#µV%Ò¡k:þvf­z&eÖÀ…Rß60Eå9 ?^ì3œ¦jE¡êZ? *DP¯Û¢J5_D™ç®”4C¯\”æn©Œ* Âýªå¯4ü­•Ô†ͺÒÌl$¹wÃ+ æ‹,‹Üß«ºf®.´²‡€«ˆÑI‘gxá‹<ŽÙ‹¢v±Š¢Î6}µEÚw¥å]£X#iê¹Ë9Xêx«W«÷6‚C¡XYmÉå’åFŸ_À2ÉÜ¢‡µâ-Éòà8(Í}°†X½}˜ÝÅ|'î_(PNëueÖœAÉŸºC(€6uÇ܃é>{aøP^»¸ÜÊî.Q&ØO§ &£TD^C•Y®´°mJ©)¥Tƒ»”¢È÷ !Åñ„]©P£EÑÔ?ƒ®ñE”[üŸæyâÊzP÷õÛ^Cƒr=¬üÊ*ÁOdN:L¾¿¼sBöA =ø÷p#€c”ÆÒX˜Ç8ñ¶3ÿ ÿk(¦0ÉÝM¯®ªnмº¢2îuÕµ–óÙ‹½—¡ðàëCe†i6¦6WC[啬ug©¢PjXZYK²— §˸ç cµ¨‰±VL¨-ÀÓˆæPÁ›5l®»šÌ¤îªë™üùkzA•Ï­ /гKÕ*ô Ú6Žbwi=KwžÉº2cÕ{-íþµ²Âó[æôª¡Þº¢Þ²˜ØµÄÕU³©«ÕÍa7PêÃ`«Lÿ–6¦ÀÛØ¡Q€!ˆÄ1ŒiŒÞÐÀzƒ”©€¢lù.zC£­X÷át/¨å»‚Kmh "YÃÕWBÍ x°€ZzÜàðõ=ô°ÄÐðÌ€´ÐSC-íº”FBÊ¡¨‚8‚ Ò nFœ0ª-dP”P­j7ƒarR´3Ò6A€Ìê²®«ö’ì Rc¢Åcšít+â­iwß—¦@‡%ÑØ€~ ˜ðYÏžA¶<˜‰~hØEу(ÚWÃæ¢)þèå5K½\Xi%KaäEõKï ²•î뮪Z±üüÑ7Ú¨F Ô;>Ký Îs÷¹ EºÇU[ƒ{‚Æ‹C²„â°üè¨0[ó$3tæF_ååÎÛ§™þ>œi”ÇálI-°´&!_¾ÿxJ’‹ ÂsöŽÉ&I×Ä&¦ý„^ ÷Ý^˜F|¡˜}«c0ïÈï°»t®Ÿíçi[âùÓœ.gßf>Ý{þî½d‰H¼Ô)šÙùÏ)aaž9×$Ú8Œˆ4 ®³ßîí~TO/RHàV ’LÄAvσÞ×ùÞ­š‡nà„‰Æ™{ÒÑŠxeÕBHõ>ʼnˆ‚ü)>1öèÀ‚f@Zì?+]ôÕÆØ î©w8¹N‹¾%º~âÌ¿ ³ÛåÑ“ìaX%Õ£mÇí^5¾ýøæÝ¸¹o£èþ~xìѦîÌ‘:2•Öƒ:²ÏdÁži‘¡=«øCÈ_úS2M¯²Qã:vþ´nöÇÅdÇ={÷éÆAé[wâÿ'XwÒ ÅÿGݵ– endstream endobj 1859 0 obj << /Length 876 /Filter /FlateDecode >> stream xÚÝVßoÓ0~ï_a‰‰xvìüÚx&!„+¼l0ÖÖA˜ÀCf|NÛÙª Ÿ…ž’îÛ+„K†˜SÐG7šëo¢PÛ†h/ž„‰wºðÆ8øA{.¯á9މ1©9æÖAÃ¥÷Â>M6ŽÓ§ÜFS{ŸòÅLhPÜSW´ÍÒìnî̦*ë(êöÊ¨×øÔ;1nåÔ €Sê}øüþýÌ]¨•6ètUUf×ÞjöGvSqä²ß¢¡'54¤MÓNäoÔî è^ër‘+aÐÊ;©Dm‰i lq+  gÕ%î9=±[ÝÑsLÚ÷Ó¶©·@ÄÑDaø¿ÑW!%‡qG„xW$$NSæ-«F9‰'zìœG&í¤O[šs[7 ‰@7¶¯oæba thU.f‡rÒ•à˜DéßÊG•R®ÄÃ2Ò°§Ã§¨Õ ÌöÓÎÍ4ì\¨qwäYsÍ¥#(ÖÏvÆø4Ô’aE XVê2—RL†MŠ¢æ¢5ÛZ(Û^¦¯·µP«WcžX±ýâg±—W†¸‡Kßüuß/;,›€Amæ¶õ[1+Û?ÒÚåa|ír=œ[Uà‰[ :Ç|1Ù#ŽÜªÂ›ñèûˆv…¦ý(ŠH†KPQ.¿4—ï X–¢›Î´F A8ázúTèbôqïàèæÝ&”à°ò,Ä!a;ón[´ãló 0N¼×FY¨7Õí DEÐ+½¿3/žL ÿ“¼ ~î˜×<‚•ò5~Y´åRéBîi"z ‰àù}ÁºêÈõ“¾M&†"k×}$}S8ûÛÊÊg™ÏÄÁéþ«VwéŠDÄ´>Œ2-Kp™áY÷¢u-d8£ôüº?/³þX߯>”‰ôì™yÁÌÚÝô‰ÙO›ÖlŠ Ø1¼$»òùÜ9"ÏÛ|9wù8íµnSœEÑyq'ÓŠe•´NýÙŦzýµ’Õ{Xv¬zÑÓ._ô„ëw!Vm®Îšºî?7þ]wf úŸnÃn endstream endobj 1767 0 obj << /Type /ObjStm /N 100 /First 973 /Length 1875 /Filter /FlateDecode >> stream xÚÕZÝoÇ×_±ÍËrçk?#€cCi€5d£hkø‘ήZ‰ H pþûþfI*R$J'‰@àÍÝÍÎÌÎ÷쉊YHŠå@*”ÀÕBn”[ $´(Þ´`쨙‚åì‡L쀄lÕ %é Å:r¥92ÞWíÈ-4m`` ®O jþ®à‡”*D¡ê\ 'åBpÉ ^°T¸/iÉκ€’R_[Í9 Kνb'™Â6¨’³­@iÖßRàÔ|måÀ,¾HÀâÌ Ä`딡ÎÖŸåÀþújä4 ’ @„:ß&€Ì%y¡æxµašðL¬¯À³µ¤­ÉŠ Ö”‚8s@ Ü|¿5qÐ-gèT9u4‡\×Ëþ(;‡ ¨ºBS Ї¾ùÈ7_‰‚šk¥’ríWlT³ï§ ŸÁ‹°1-Ô€Ww× h8 àjÕ¾,jëƒ\S_Á,A2@ þC.1Ã$» ”`Ö ³²þ2û°a@x›µ€W@P%̬ˆ[®inx èVñø±ê~P…ƒ5°þ-÷ðÖÔùƒ@&é4É•À·YÉw&ÎÜõ)%äÜR Ùå!wá\»¢à¦¹Þ7_;=Ø­ºyðˆ»«R¹Á†.Rœ¢¬™Á™Š"ŽfGÀ85C ™¹¡’S_€(Êê 0ˆ ß-ª¸ñÌcLÒÁ«W“¿ý:„ÉëÙl¾:˜¼¿øeÕïÿv:ûßÁä‡ùâdX|Løôiò×ÉO“7©ßLކãUø(\"»C¤ 6#­Æ†Œ@Ô" Ð^‡W¯Âä}˜ü8ÿ0“·á/GŸgñ|X|âÛÓó£áäâø»ðý÷ø{º8J©'¡µ8Z%zÐÝ-ͯ‹ÓÙê9¤i%&w´4ðD\å>q–¿,‡Ûåy>"16p9 “þëß¡µ(nMÖh¤ÙÅÙÙ§È”RÇÎE#RÐó`‹EA˜Ä†Ü î3ÛJŽ’ÇÒÖÔ"ÙXpâè9{6èÆúGÚ‡óÙªôÑoÖËQS2²ðúш<³}ÓBEúݼQ¼Iýô&ïóã÷œ(LÞ½= “Ã×UøtÝ/ßM¿ “7`;ÌVK/U}½»ßr~±8–ë’ÖŸý<œœN˜ Ýc½ £êÀßMX D]#^Ýz~ˆ§åÛìÛ,f¡‘Ø& MùY°µåèéòO‡]s,2z—JHÇ´Ë/¯»âU'½â}w9)/¯`OrÒv‹“Ö:é:%/Á¸÷g.OoÏ6mÞ²t ØÈ[ tàÓ~r?'d6k1X)„Í¢W`É%ŠíÌý'ÓÕ4~^Lχ=–¡œ#£ÍÜŠb$1aÿ÷ˆòóül8¾8–û“„ ܽæ…èí0$A÷&4¢­zQ­ç¨(Ê—² 83œý>YÞÀóÓ“=ªEj‰hV·’¨¶èýà}’¼¾œC˜éêt>Û§Pd1¢ª§(\#r Ƙ[å—u\28*!›ÏÂÑÛfV‰Mu§,?Í>ïOr ¹†>Ô›w…L>2”1î”áðïÿØ£ ä‘üb>¤d…Mp¦|—ñèdºüO<>›.—7úÈúê^o«6ÞÇR‰McM›Ô zb‡u¥^í¥ÃªÉn/Ÿ]]¼ZÝTŸ¶©b>ÄoÚ¼×”%*jf64¼p*!(Yj»yZyjû ¯M¹³\cõ¯ÃîHþU¶´˜K»£Ü],¦7m¨õ6¼Š|Yè0)B¤‘؆Q—oû&u+¶"sX)#±³«Ql[mc±ºÉHl‚åª=ñxewǺZd·D„=%"ò^[SɱXÿt€­w‚d?O¹ãÈàÇaõát¹¼ÞÌÁãt6]ý~zðTTL endstream endobj 1884 0 obj << /Length 1064 /Filter /FlateDecode >> stream xÚÍWßoœ8~ß¿%5ÒAm0¿ªö!wm*õ¤ê.YÝË&ª\pN »¦¹ü÷7f¼Xv“HQtO6¶gæ›oÆãZk‹ZŸ¿.o/9³7 ½ÐZÞYŒR×ç¡1æ†~b-3kEϾ]~y{ƃ“+Ç÷xÌÉGy'ÚúX”W2kS}rA~P •Ç–ãÃ'ŒÞósÛ (%×>Ž¥Tù6ÃùݶÆIºMƒö#6²¯wßàÎÈÌŠ ÁLÅfE¨å€ÃI 0ãÓEÓˆ‡Ðí÷¿eª~A@®ëÂÓZ´œçƒCóþÔr·©,e¥þ/†Ïp°ûxïàøClZùŸ_ÌÅkÙÖB½Z_=„¯àß|A1(vô­ô"7¡&7.êu þÚ¾GT3ºÎÓqæz³Ä¥ GEˆiZÆüðÈ‹ÈEe;¾ïƒ@ ɜԔŠÐ SÀÛÓ6BOÛ0^y±ö Ìq²ƒ É M«­ rYã´‹´í€@Ö<'B0=ËÇáÎWQJcñG#lØyj¤B´¢Á… #2’&Iþ²“z,z3fŒ³ôípÎÉ2—°:pIårŒyâè|–B;Äy|¦Ç 0…:k÷…Êqëšiç¤ÝAÄ#’ ™ñ„Ëòé_Qî6òô=1ƒ²÷ŒÇÀøþ9Ä‹úYšR“¶uÝ×´þû t„Q( É©²€BpØ}/ÓoM)6›Q dƒgþVK`ÁXoËò§•¼‚è¦:Ydif ðžæEµ>†¾Á7–A·;P»/]?!¯VgW_/Înoçœÿ]ó¹×{Xµ>ïÛÙœ¾©YOÛ ÿÄ;#~>dâhGüi#/ÖCÏ^,_Ÿ–‹ tQ‹õ£Ç7ñc+-«[je° æ\²û¾;ZZ^°ˆû0ßX׋?ÞlKGÅ @‡póY»?nbŽtža2nVcNÉ¥í0RTºæ‘)A<,© ”º±U¯­ýôê V»ødÖð,7,]îGÏá9à3­9 ¸ÆÞžƒ&­‹*¶Õ±"ÏN<Ñ×RÔ©.9”0‡Ç¬ëižÃˆÌòÊ›¹‚ÝI”B¡Õ®@è•êѶ;™îbXÜ-©¦’ýRDt¿µ?½ëžæT $RÑH§¨Y5…*~h Òl ›‘JG?Ó($jR9ö`Óþj[g²vá èø£.¶u¡Ì+áÅYkåv¢û„ëû Ê<ýÓÔQ¦ñ<•6-…´E†6½¢´Š\Î5˜hç‘G¼ƒ¯YÕã ÑŸ >…2-n¨Ï5Z½ª«„\f¦q˜c²k’Ý?ñþÂsÝñZ@´Ö¹ž*ÓõäźoÌ fæµ×öáh«Y(a‚ùØ Wz»Â´'ÛÊAËp°ï©Œñ¾´Mï\çÿÁ?Ï' endstream endobj 1898 0 obj << /Length 923 /Filter /FlateDecode >> stream xÚÝW[o›0~çW õa °1°ËC¦4•ªªÑš4/Y5‘ङ d´ë¿ß± )·\·=lʃM8>þ¾ããïLu®šê•òy¨\ô¨§úȧ6U‡3Õ2M„ U]ËBûê0TÇZ—Í‚u”õtÛÓúºíj#ýax}Ñ#Vi%1-äzüŠ5æ6Š™ïƤdlÖ†íŸX®¹Oƒ9«,Û6‚;·ŒÚS ËCØó*€»‹øŽ…ëéWÓ1“Éw6ÍÎuÃ1M-HÓàUN?Éáöþæ̬œX+÷n;Èvé½³š¯cö¤c[ËÒp÷À”˜êq*ulâÝÉmà‡{d•׭Ί=6Æ‚ÝÛz¬T²é>Õ‚hÝž5†õ£Öy`EªîŒªv.òș.und’¦‹IÄ¡xù3ˆ—K¿c8£dÃØEØ··Þ±å$ž~Kã ŠŠ«¤\•Š%è[q!ž¨ç¨ÓX?˜j/¯!:Ø÷Ôa«ôÇ%\M"u |Ù R(Xõ’Y&¢7¸8ˆÒ*Ø^T 0õ+GA11µ+ÆÌñ´à)”“AñO¦[š8i˜w7¹ ”k£#µq oj"ÄîÞ’iQh‚d¹´à—NW‹e¶HžNÉ^ɘ_)ÁRlÀ€i–ßÂ"·»åÛ׬;Sï÷µÝ­eCÖBEâqɲ1ò-ëàUâá£!ÇçB6ޤŸ³3ù~€å³ì1 å|–¬äd4É ¸5Y„·ïòpUD ¤ØõE­ ¸"[È/JÒzíµnÄêLWlS…/û‡©w:ô}Éüuý“:ßn×”×ÿ"L EE_™°°Zý˜•œŠœU-L€óÜ(Ûí ɦJ?Õ:)rG†¸YMñ}#™²\MƒtKOó·ú/ÛµK>–Z&þÈÁñqÎÁ »s´üÚ¾loh¸ˆt}¶EV´Iƒ0»í´|mŒÛðã¿ý†_DY˜DÉ$ˆ„йùž]U‘Û¶žáð‰Üê¨>ó€/›|ßFƒø^¦T#ÏI³;þCŒEn;³QhAUÛ!¶4!¤$†­Jõ²Èw}ôxb÷¹ØŒ*WNÜÁ¶=¹Óç­Ü/ücL endstream endobj 1914 0 obj << /Length 763 /Filter /FlateDecode >> stream xÚÍVÉnÛ0½û+äP ¨Rܤ¢—´©A€"n/n²E'.䥒ÜÔß¡(Ù–-«5’9q$nïÍ ß Eˆ¢«Þ§Aï¼/ŠH¤…Ä(%\(¤#ŠGh !–»\Ÿ÷U¸³’+MhÂ9åšd:#y{Aˆ×vyV—|ô~õ˜±ÍùJKB©@ãYoxOQ“צ¢=•KgH-8Ø)ºë}Ýœ·?:z—£D-%5 ™p/Í$^¥ÅM¼6YðŠv6}ÉÅ—žÏ°ñžXÃîô|.5¾ñ$|Ög´s’h&Oáæ8ˆ–@(&‰d5…|œM—Åt1o0Ø2iÆ2D> ‰Šª0^ËsÏkœ×ŠGãŒÄyÉ}¤U4ß=Œ¾½!PD‡Àoyü`Z¡µ@Õ‡Põa¨~PI£Ÿf\¼÷|I)&„À?fo“ü€“ˆ°­üøè»ñwœ®LËIggnþŽ»qfŠÇEâìÉ"sÆ8óÜyE³fÁì»Ê_»,‡Ø¾uÛžÖõ ò$’êYny]2òd6òEÙdf™Æc33óâmÐSÏNÆ£¯Ì|‘=¬€®Ç\ä­ó‘9@{J(šÎžþÅÜ©Áb8nÛµïE]…¨vß¡{GÅ ä8•Ú´„ˆ™¤’§Et*sffχ I~œ“’Ðm<«q1ÙŠ¡¶bâC «’Q㼩¢ÿ!™ß½HáPÝÜ(ú~MÛç‚?x¾œ¼ > stream xÚåV]oÓ0}﯈6$‰dNlÇ â¥Œ‰‡!¶ÂK˜Pšz]P>Fœnë¿çÚN»¦ëʾZÐÔÙq®ï½çúÆç`kbaëcïý°w0B+r£À¬á¹åaìXÜóÜ€DÖplÅhœn_ÊÄöC4cöÙðÓÁ€zK»(ö\ð©í™¶éá6 Ó%cgníø‰ÙÓ¯'ÓB”6ñQ#;ÛWGpÇ—3-Ç‹\ 1´£›ÕØË‰Æ÷}ŽúeknhÕÊÖLOîøBRðg›=BQ5²ÆÐO‘6m™:ÈU®~èF˜™\¿ÙQ€’|*Ö^‰° ´oëÌ]«£©œ\”“æÂ¬—j JZg©Y¸R†ÂöPÚTµ­Ó½ÎæÖÍ…h'U“ä <(? þ‹Ú¼¨ÎÍx.’fZ iž’rl¼¦"‡(¹4OYÙVânQoR£S¡2 árY=¥NW’÷}d:˜£™y\:ª7°Bˆ©ÓÈÆY£;݆ ú5ØÔ®L¥u’6 ¬JµNP!š‹ ¦åÛG5W¡WîÝö‚Ä¿c†áç­ùàbHìA:ÂIóDÊ}üXÏ´õ|e*7{1çŽÑs#ÖöÁa Ý&t¬Ï£ù¶­rQïâLâD¡êú.“BÈ]Ä‚ûf"vQ:y™gÍv­4 œŽ¤xXÈÚÑMR\æb3ÉuÈ6]Üm!Üm¡ñU— Üb£wŽ/GEúCIžÇñÞÉqïìLÅÑX0`¹et•2lŸgÝ;ö~õ<]o!(¡nà+-zñ¶Æð|¹$ ­kmZXjÄ©âþÜ:í}¹‰Ö]憌8êqû~WkÌV5Duz £Í 4æ!EDjT\ÁxËE,D‡ÀE¬çæñxZŒ´Y-7€ÆÌõ|þÐ]#¤‡Џ÷AÈ´Î.›¬*ŸÂdÅH†s;”KÌ–´asMØ|óOùU&ñðv¼?Áý}Ó…§ÄŒšÇf~®D‡š,(è`À» J½}½N- ÛŽXÝ´vÃÊ—ÛvûÍC¿ÐA‹²—£ô9b”ýb”>WŒ¶uºbËb44b”ü…b”í@²íÉQ¶u=ï Nt¡·|]‰Èv¦·iI$n¹€Ëâpc¨;Hßc› endstream endobj 1877 0 obj << /Type /ObjStm /N 100 /First 965 /Length 1846 /Filter /FlateDecode >> stream xÚíZMo7 ½ï¯Ð±½hE‘ÔÈÜh‘À жF{Úºu¼…w]$ÿ¾šÍÚ±³ãvl´@. gç‰z¢H‘Ô8+¹à¨¤àDír•)GGœ] ‚Ù^Dc5]Ì *Ž#™ ŽS6!9!žAÈÐÖÀÅihàêT œƒÓjàL.‰iÎÑ¥bàÌ.³³¸\X]‰ÖìðšKÉÞGÔ+ÀàXlöPvYA_Õ¸(Ôjê F¥¶È•©¶PbsÆ`B!›Á°mÒ{RTŒp­&V¤dóc|ä`,Š˜º #inoÍJÁ´Tq±ôo1OÅ*²²cj‹1&³K R›'ìj «ÐÎÑøÔ€l< ?qi`~‰mì/¹ HŽ•ê R†„T°;ÔF`²¤6‚0Yme‘¥Øo˜Âö+Ãl\m‰‚åH ¶býHÅìDµß±ß°ÛTm.*N¢Ø\T!™k„g»IÉ6«F(–¨®Â‡Dà ÑPJ Ï’Íñ2…6ðImÁ\9·¹®ON¶ ¬19e &e§ÒÌá‚Iš̶‹•Í 9`†sÞ O±Ù d›Uøh?B]Jl³qr)g›ñ‘Œ$˜-˜ÃW®.ÇÆ[žYæ€A`âÆ>ºœØÆbsÎ6Vàì•ðÖWz#ê…̵*ÖR¨mœ¤àIAaà)%–4{ôh6æŽ&Á|èæ?þô³«Õcz°¯w~yvözöÕW7ƒ¡«¡SUŸ`“qhÍ䋎խ¡z…õî òüýýItŠ>"DSöT¯ùàÁò|í=ró– QÚ† ȵÒð xÃŽ¢:Àp$'¼›Ä9Ô÷Ù2oO3Í_\,_vkwäæ/ž¸ù«îÝÚmI¼zÿg‡‹_»Ùü)uçë•e'±ñ³ùa·Z^^w«>‹µß¾ïNNO–ïÜ‘K8·r¯1Ñâ£îÏÏ—ÐvÔçXãÓRl/”~U׈´!³ùËË7ëöüÝéù³ù“åÅIwѦ ¯çßÌ¿?=¢ö` ±¶X“WË’vì´W|ËÆÉseÀ7K¿tó¯—¯–;õÅá/çþÙéÛÃîäòøK³Ô$D(«Ï8ω£·D±óðÔ^$= ‘ÉÛ)Opœ­–ÚÁ+Ôz'"Í­ ß!#ì‚·ç0'©ŽD‹ª‡ÃsžÆ‚QƒÀ0å^Ð(èõÊmq~%´¯ýnhïðµ`'Îÿqh×òqh÷:ÿYhÚDô†e+c7B4üƒÂPwQÁŽÚ™³Áê0äþoõö—ÝåÅb=eô“gSšŽ!D1¢OZ}õ/Éë>|®z+‹ƒç?LGE=ZK>^áÀŒ£[GƒÁò0$b̾X9Ÿ³ËL">÷²G+ó@$ Šë.˜a~lr+KH°ØïïnD+ùZÊH4z2oôH´¹ŽDKG£ »4²ž5Œÿ´ b½;‚è–Ñ»“øÆ2¡¤>ÆIK牫ekº¯§Tkçï”RwÌ`7(£cë x-¨BíÆí^ÐÈ$v½ñ¿Cã–¤#ÑZ켋– ¾Ö2Í1ùšòHtD$rà{A¼+§±¼I·åßV·W¢ïJNŠòqu[edu[µ\¯nír°¬v7¸Ò äA(ƒ°iníZp# Ã9‚  ™Í²oyp¨>dÞÏcr"ÑȇMbÏ5§½LNNßž/Þv«©ùHÈíÊjà#àQ[èšÏÛîâ×nr2è×ì Û@FÑ:ÙuÆ>2«?ÏN×S“¢I‚·›Êhߨ}õ”ooßV—oVÝäd†¼Áƪ™ˆ&Ò¾³D°ÉZ>}àèô™ÐQÛ<çâSÎöÙÖ‡4*1Lɦ’/ö1sÃF™ö²éiÜSfP(¦-%saEAqJ÷–ì>šÑ?‘ÚU÷WŸ¸Ÿ>š|Ç(o®ƒ6L"‰}+ßÇdz*Ñ($ÚRrÂ>*WOb>5l $KÚOhç(ž4¶p—lD‹¯ºŸÍÎY¬Sfûè [6ÊÅÛœìe³sëõk5û³„ñ­¿ÜåZíf4ÚÅxÓw–ÑZKËÄ#ÑhsS‹_v?¿þ 8O endstream endobj 1971 0 obj << /Length 1035 /Filter /FlateDecode >> stream xÚÕW[oÛ6~÷¯ Ú‡Q@¤Š"%QÛ^²¦-Z`Ø–x{QƒA‘Gƒ.™$'é¿ß¡HÙ´B;Î+ ˜÷sÎ÷ñ\(­>,~Z.Þ¼g%^Z^#âûeŠ ñ"š eRFÎåòÓ›÷7vÂ.1rÆ=EY{ge}.Šu.w/|­ãÝrñ÷‚@×Gd#>ŠC†åõ"½ôQ‹Ÿ,%Ý[kÄÀ‚˜QèWèbñÛFÞ¼Ubñ½PE!÷‚˜?aÀJŒÃ©Ræã3Ç%¸¬…Cp#»}Ù6Yå¸4Œñ¹,äÈ`ANsü³2÷csÝvu6ÎJ-vô@áϯ@2ËEE$òx@È3Ñç]y»Ñ>çj~Ù¹„{Œëã¿®+ 1‰q-±”–q6»rÜ€ãv=È1ǹ¤§ªz5ÊšBmªE# ëÕ¤èj¼*ï#&áçqÔ­ÐÔ=ÿ°€{'Š4hi#ý0׉‰v"˜ÿƒã² «,Á´ 4&a¨ÐÙ0%¸ÔÖ÷C ‚Õ\Ö«¶k¥÷j`;Îñg?ôÅÊSñ±ã…© >ˆ›®½×‹&ó)>±a$­÷MV‹Þz ômd£­-vÜzŠ™#àSªàC»O™‚sy[­k½Ï~úzÆn@Ä3ÐKåpâ ôjÁŒW:r1i¬¿÷ÙJX#ÀñˆxýÚqCßÇTµ@ÃM[¨þèÖ²“WY¯íÉn*ÕïlP±™ŠæÇ¬Gf· —.ɘ‘ëõòµ;ÚØ=^ï·e¼&½Íj¸ù&yLúÞbêÄi·ZCæuh€‡þ`,=C³r»Ón1>=P ,i‚â=¥|&[&”ŠVâ¿D>“:þp’gÕZì+ ‡ ‚w[óÖ÷Θ—7BeØFÖ•u-ÿUIJ¨íµN½B•Uc­.±·´è!3ùX#@ÈNI>(t_Æ6Üfîf‘ç3ºÞG±C­ã‹Ò"]o'û©Åþíæ¼•(P[¸¦êFª0~™‹2ˆÝ¯70bð(µÒ€qYˆÑ–¡üìS&ºþ_¾R§ø´êÛãÏoG7|lñŒÐ³Ò|¢+Û'š"k‚'jæÎqV•E9HT_0òdvç¥,ºÌ5&T¸ xeöÏÍo;‘ bÊ¿\M)Á|CJÏ2\Ýòj9Nã¬rLJÝMîß›´ž£E~¬ls¡{§ýò¢òNíN/Ȗ‘~-EµèVâ?×5sÛ®l†¯p|ͯ¯zq´²ƒ9äÝCVßV¢?þ5ÍA˜|DètC:‰5y¦^@?ºª½½ªó?û:«ª4}«¯./7Ÿ.>PÇ·çÌédç «˜GÁç÷?…™'Õ endstream endobj 1994 0 obj << /Length 956 /Filter /FlateDecode >> stream xÚ½W[oÓ0~ﯰŽ´dql'ŽÄËB“`…—€Pšº]P.#IÙø÷_RÒ,-š¦>ØuÎý|߉ã£5òѻٛùìô2(öâ0Ñ|…ˆï{”…("Ä iŒæK”àe^z×rÓ¤ómþþô’‘ó‰ ö´,”ÌÌ·@8B„C¦„]*¨–vƒ©Ñyá¸Ü÷qÕÔwf—·ödS.dcöõʬ™,ŠVùû.ñ½˜Û(•úWŸû·Y éEâÅDì8Á*-¥ur»Q·¶­gý|èÅš¸‘éRyém <þÃk•ÕÖxZ-ͦպ»±‡ÜŸ4t@Vm^WÓ™ƒå‰Ì‡"ÆÓaåkƒòlƒ•l˜mÜRV]¾Êe3h_¼ÞÞâM©ì“Ÿ]Ìg?gÔ|D¶ðå_ ðÍÊYòÍGKx–= t§EKÄ@$b ·ºž}Ü"v¼jŽˆøBà‹™GI8Å‘þÃx š¸!e>¾t¢K‡œv›F­Ð{Ê#SlÊ>—ªÀæï`B‹™ºN'Íó|àÙI›äØÄ`œ{$$&¹·²Íšü¶S}f7`ùp$ž\"<*,®.A±T©ª4)µiÂæ\Ní C'ˆðÂÉЧ9 ÍUvî‰ÈÚýܦk9ÐD€Ñ#¾°È¿¦f-ewS[دjËŬH[VDvzªž¾²Ý$x85w•&öœo1¥ßc}o=,WΚõèèÐwí£uÙWȺÏðÝ|£ztfeàç Ô¬Q¿ýôÀ|¢;<ÉŽ‘eJ®œã2ëIú‹‡8-6òyfÀ×)èÝ9ÀµÛÏdu^©#(i“gæà—”ÁY§`¡Â½Ë{éîÆÂ»«»´ØZˆ°‚¶ÐÐX6æšìj]^´;Ä`êM^ŠÖüË«)tiûCˆr-Ud@³¢­ÿ§N¶wn¦?¡îÏ œ0U~¥*à|™ëZþvÃú)79)Å\—³“MšéI¢5Õte–í1ˆRº/§&.D«H3àÌ.ïNŽòÙî–þ{Ñ{¬iÞ›þ•ªp¿ŸÌúhŽ$ɳ*I^»'°üø: ,Ÿ\}þðá)ÍŽ`ÎêëųT ¦ÉZ>ƒ'ŽŸ#§ÒÚÍ¢•Ýa>ê÷iy[Èöð·ûß =¼"¸÷;×Úw²3=§÷Ý´ÿÎc}Ÿ­úK°•Zô¯¥ñwÁöëcQfßÛ2-Šܲ Ç|íËø{àA,JÉ?í¿gü endstream endobj 2017 0 obj << /Length 1247 /Filter /FlateDecode >> stream xÚÍXëoÛ6ÿî¿BHŒ*UêUìK–5Š¢Ão_”`SdÆÖ ‡+Éü÷»#)E²éÄZc`ŸIÞûwwd,m®YÚÇɯÓÉ»kjk‘ùޝM4Û²L—úZ`Û¦ïFÚt¦ÅÄ õ»é§w×~88éº@ÛÈágfYQ&kÌ˦It'$È3±¤¦ÓÉ·‰ ¤¥Ù½?LêP--&ñ¥Í`ó“[Q¨møÑB£`G@] sífòG/o÷[x =±-Óß|ß2©ÂƱ}à\4`Ž êR‹\ê†Mð¬ñY÷lÂt›¬Y®®’k=`–“vU‹m¾‘”3A\áQXç ù‚Â’d°†ëVÇ„†¦k9§ÄDøNYôÈ"•Yü5i-Û¬*G®?…`Œ„P3l°% ûGÖ‚®+ýs)iº•†!`£m—¤,ÏŃ.x2p¿äÚ»=`²‘'šáx&•VüÙ$s¦4_áN r'‚Þ¼ÜX¹qÅwÁÚE5ôCU "Í“FZØ#xàîÏÒÞ¡š˜ôØÚåQž·À*ÛŒ<ŒÐ[˳¶ða# r\(6µå5[æIÊ V¶ÿ W¼C®pM¿â{ä+vDÂ/ëù \Ó]‡´Í³‰?”p)h»Sït…ÀqrÙUü™¡VϵŽüº'?îÁûø¼dÄzu^{ä_–¶»‡wCHÍ(t„É}Œ ÷¸ÙPHP@-VÑ?*#gå¼]ˆõGNâ3h¡Ø*Ρ¦`õœ#jÍ2ÏÚ«h{Íêž> stream xÚÍWßoÛ6~÷_A FCФ({ɺ¥@1ØâíÅíƒj1ŽÙÊ$ÙIÿûEQ¶d:sÐÖD4ï»ûîŽGÑ Qônöó|vu'(%iÅh~‡¥„‹)ÆHÌS4ÏÑçÅz“­uC®›& ¢‘Á§ùû«ÁŽ.BÅÅ25‹3Úßñë|öÏŒÁ"6ˆ'‚¦h¹ž->Q”Ãâ{Ki‚»­k$@%8ŒKt;û}7ýv„:ÄÀ(‰AµXJ'±ƒÕ6HÇ@Añu2l6‡¿’a0¼Óer™à›@)˜é¬ÝÖv¹[È6¹¼5[a¾; ð#,[ƒ ÝtwûÍ"8‘Iò³XøÂ㘦DÀÉþ/ºYÖÅC[T›ô½ F¾d YJâžït 08ïáq7s§ôh™ã¥.K;êŒnÏ€~c‡;iWB5=¡„F‹´ ‘UãÏ&[i¯ú8Ê'éñ¼z¾¡ßrû]ëö¾Êíø®ªí`YfM¯–óܬþØ+|xÍïÉ5=ä=@A-FR)ÇýH%}‚Ì1›"NRæW½Öe¶Ôk½iÿçXº«~ íw—•[}ŽÏ¯ëÕÀ<Âmó¬ïOø¼wùÓ$â'©KE‘Â×.6à$¨^!7üãHübàïQ2™fEà{õ`Kü·^¶ÓÍS*Ây´ƒ‘N —Þ6˜ÚÆ&œª°Ô›U{oçË¢éƒõ±psÛ‡ „yÖêü(… ä+ÃËÍa0Ÿáµ¿‚4ÆGÚŸŽ:¾ƒß¡ÂBrrdØ{ßg©»ª,«î`±YÙ©]Þ1ú6o¦•AŽ* \Ôˆ¨ˆ[m?FŒþ‡(u.Zškï³:[¶ºîS¡™^8sï}”¹ڻƥÑ/\»OÏ)ïÈ•^LïæœTZX¥ûäál™YÃÏŸLC'ÿûnÛ«¹çä„õÌ€ʵ#:îÃïÞ ÇñÓV'Ýrv²»ÕF‹òJÙT/©Ó.tL]¢h_WÍO~˜~^ÃŒ†ð&@‹¼hí>¸´[¶ˆ!à3H(àpðº©Ýðtè¤u† çC¸œ—1“ÿà{€:Bp%ïÈѯ_r‹gw’ä/-œè5Þ—o&ÝÕÏþ½º¸€^,.âˆã‹ÀYëz¥/rSóPíEl×l?ÃcûŒ«N>*ÞvIù»©lòݸ׺Ð]·z[gí³òö\,…V”³ïÛŠ2%‰¢ÓvÚ£²¿…v3ö´›êD»™àîýts,‰€bûMúLÆá±úª>3ùúF³:M÷Ú8ŸF{]qô|UR7öþØ<ô endstream endobj 1959 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2279 /Filter /FlateDecode >> stream xÚÕZmo¹þ®_Á- PäÌð 0É%H[ íœhk¨bï]Ô“¥@²ƒ\}Ÿ¡DÉNbï:]×Âή†äÃápæá ‘g| l$êSL!}ã9«€¯¹~I†H¿@’@HÎpQA‚ UˆÎ$¦ orT刢ÎW‰÷1©U&m5¢‰UB3Ñy• ’P#$Ë9› äXkâ)¥‰"!O¬(R,*1z- xDQkKÁ;m5¡µzÂE1%Ô"Rû‚Š¥(’ì ŽÚ | µï5'§Rö†Š×šñ;Ñš3öYd1̬vÌÁ°dÅ’£áX‘æ{mkÉFPm ˜ˆš¦ q˜BKo$¡æ“KF)ïU*°á' Z0º#Å^"¤¤ØK2ÁW  {ÁGJ16ƒÝœƒT-€!TÔ–eÅ«㇈a‡„à@b ¬6뜘èRÕ &U)šÈ)L %ƒ¯zÙÄ(õßbbBGц3±Ô0\R¤È$Â+$†Ïˆ¶ëÅ$ƒ0摃QÿH1» Á¦)‘º|)%sÔ){m¾”2¼ (^ 4PªãÀöYûDj­¬C†²’Žªx* šp„o’j‰ï­Ý¡drªFÃåâ´zR\ÐÖØ™â‹v‚½)Ìnë¦Ej™ÑZ cR¥ hC;•‹"P/qZbÒ9¢žêtÊ9)ÀŸœ„ª¥ž0>À©Rí°ŠÛ.À \dµ„γLNN&Óçæ s3a~ŸšéßÿñO­Ê2¦¯°Ø »/o‹7“ï¾{X›3[µ9Øo¦M)Ø¡5cF‡¨íSº«ýbµ¼6''fú±Eÿ­Å^À†q÷"xqíª45ăŒ¹¶}Iq8Ÿ¾ òéëÕÅ«îÚœ™éÏ_˜éëîãµÙ·ûú×÷þ˜ýÜM¦Ï€¡[^o4èÔ6'ÓÓn³ºY_tú Ôoé.ç³ïWÍ™bQ?J…Þ ¡Ù¥5ç­âÓår…ÚζqXñÔ8¼|¨ Üi¾TlBj¶ƒŸô£¶8™¾ºy{]ß_Η¿L¦ß¯Ö—ݺ¢uo¦šþyúìÌ×íàLÃ…­ÎùP‚§ÍÛ4°D‹H½§up^™éW¯Wƒû»ÓŸ–öùüê´»¼¹ø½Zz$ä‚õˆÌ@€yÏ“[‘oˆYÈ&Öé\¬G ê¼´|±Hb÷"y¶îf×]ÃóÃÛ£¶ñPyŸ€BýÓÖŒŸ‹uš÷\²És¯yìéålóÎ^,f›Íˆ à4»4_QQö6‹<Õ‡Ùb~9¿þuD_ÊÉö{`Ìe7¦;;†?…`5ç6,âɆšXz°Œ"0ühïÜ=`®ºõÏÝð4·ÎÁ¨bsku,0Ž{á¼_Ï—×G‰Al+ÅÞá¡Tl%ŒÃÙܼÝt_ÆSsar‡\XJM…‰Ä*?ÿéØå2b²Y7Q0ju)p&)åù±GÌcÄjdÚA!¬-=–¾ýPNvÖ9?¿Y¾{»úxîÄŸXÍ/ß>Ù½üÒ­—[é?O¶Ï‹w³µJÿ:?¿^]Âöû—E7ûÐ}¸Z]vOæ?ÕçÝêþ&Swu~¾î³ÚÖØfÑéÌB{³0üF×üÿ—fùM@ùëß^¾7ìéÎÐ~|êJ¬|.çWËÙU·}‰÷ /iH»cê´eË££É««š àò¾?ÀÇ6-Ú‘·Þ+sGˆ4§"}Dùs,•.~M¾­¼§„¯Àå(Ú:‡jÕÁh†)sŒÈ_Cè,áHµ)eëÊPغçQ|ùŠ ºoENÉùô)9­[Ç_INë»â©[ì;› MMˆMHMÈM(;Á»&´š}«Ù·š½ŒÊ[½³zL Ju‰.A¼ÂB0ÞÏ[Ÿn6³ 3‹¡‚©¢Ç..áì@ Sèã­c£Ñp mhaRÔ‡¦Â8mUH¯+ÇÇA:oÕ=z"$VÏ]H7=|ß~g…6öf'‘×™)RÈ½ÎÆö!BÐWB²ÃÁN·…úpŒDƒ>Éa8‰ž…ö 5^)¿‡¢ëA=‰ëƒ²%E#ƒ‘@ð”²\¶ºƒÐfó~1¿L›Hzb‘ôļ€1(6¶)”>Rt$0!ÕcE¥2épÌ–8×yÖ-cž„lÙÅ= â`õ¸ÆžÒW«„g´è>Ø…i»;?йk=³Ê]ï*6m“Õ+ GÑ,¬¤ Õfþâiñ—µCÞ­ Ó,éœä¡Ú„ð+C{Éì¬ÄÊ$zâ¿Å6,Ô*àö^Hò¿‘`¡ÏI°¸¯'ÁÔ.5‚KàR#¸Ô.7‚Ëàr#¸Ü.7êÌ­fn5s«™óQH°À 4IÃé•à-õ‘àp½MpÖKz½)χH·Yð˜pŠžÉ–= ˜Ý¾ÎÇ‘xp€‰ôæÐS@ÄÑ•ø£0#EÔ”¿õ24•ÔÇ:Øû·ºÄ? Ñ«z™­ÉøPt³‰õì¡AÑ}ž{¡ì‰ç˜X°lb½RµÃÂ:@®Ë-æ9æÄ Q: Ñ \NúÑÜ¢žaÌ¥%ò™?  ž­^êEs‹|†£œ…ˆÞKmìSÏm·gŸ;† é§Æ]ö9&ù„‹Ùãar6+¾¡xF?ÉXh½ß˜­ÞïÝžˆàOäÎGxV¢%þ$ø¶òÖ*õÌÇÑÖùIC•É[ > stream xÚÍXmoÛ6þî_!´&‘"‰Ô[×/Y׊KÜ~qƒ‘h[›^9rÍoi~ÓulÆ«k±~b+- ‚v6šíNÓ `àþO5[ðÞ¶±/ˆ º‡šé„%½~m˜žmë·¿9o–e‚íyYacgäåuÐ…?“³?ãLOÍL¿åëŠ5C›7Ø`–cEž‡f%i^°œ×_lÏÞÂ#¶ˆE.±"gØôН2óœÍÿ‹TõÖÄïËÖ\Ié9^¸Êõ-ÛU®ºªkgWo꓾ó¹"Ïöoýs\7ЯÔø³B­K±ys$~fB:g4.™ª—÷ÛÓÿæñÑâÃ3ô¬H]©ÝËöÐjiKc@{c¸¡^š/Ídz´n°µIÛ±õÊ0aažàÈœ³f]qCšËŠäRPGLÄ<ËjlJ‡žã´ÏFäëG֟騖9JQŸyo “RŠ©€žÖ.¹BZfY)7¦Å‡ pް·~spÞ¾×µTð;¨öê×±¿â# »rQ,Ô.YÅâ†WhÖƒZ´Ç½÷˲žkjÜÊÝK~‚­ŠŸ Ÿ³u¦ÎByñJkŸŠ/€²Ã3€8¤ y‹U¤9ðDË1ÃÌ’)È´Z/µíÍܳgOHçžP@íèÁPyS ¯\v|Ûšr!9#2ª{rË…!ѯ²º»hΉ,¨‚—éº.(_¨ ¡´½€"MÒyR]Îz9n_4p4x;- ”91×O ©bïOÖ@P„DÒæÄ#ç^> stream xÚ½XÝoÛ6÷_¡‡£†J•Dê }º¦ [×}Xš´EÛjô‘JrÒì¯ßIÉ’,»öÖ,R$ï‹w¿»“c¬ ÇøuöËÕìùy±^`\- ×qlÊ#t]; ±q•×ä,Í߉d³°L? ßqÈ+8`Z”R"rÓ‹ÈÜ´à¿=.rÞTég3òÁñJ|Ú¤•H`¼£Z8TÍ mŸ2%ÚRðfS ;+ù‘²›ˆ%O)Iº£#¹¨”«¼oÒ²àÙ±rÑi¹ìûªü(H¾,áÛª4-ð½_вüvkKòºæOö¦>FÂßy®E)—ꉧ•ÏÊ©$#GM©îx%L—¢âÐnÝö´0í÷È É÷¥aN¸‹UVÎyöe­Þ A=yÖÓ2Ââaaƒâöü^¹|U§u# ‚ægÓbÌ%o–ŠM]>ÃO ÚáÉÈc &’“¢lÔ6Œ5©LË%hɼDk?˜2¬ÔÚãø¨]—#òN¢Þ¤*þ ϵcÜðôýîâK)ì"å¿©ûŒí³³Õ‘ëùQÝ$âáËÆ~©ø<˜R9—,š²RžÒºTÝð"ᕈ‚xàØõ 7ÿ‘/îê¦âÇÈ£¶ÀÏŽŒ wªá»&Ê/€ö%Ò>ã ·Xì0©[Ï[;ïÿ1mÖ:zöºâ(\:¶ã°ÎÓzqôm×Z† üvx›L¹Y é=Hž¢Üh0JÀ'\Ðx:J8/pHY+Å mƒóúçšWP²R¯”7)W¹2$ŽšµÐTæ[¥ÏýXã[—ÜÉ@zzWÁpdžjuBf° Zg:•u"éf˜—•~óû5/ÐÆÚz¹¨Òì÷¼¡6µz·,³Lò£(Qoç*.å8Èç¦HZdÀàŒ”,fÏ™ô"È„·S@†'\¸PÇ×¹y%>+R÷¼i$d¢™"ÿ÷5·þyiýu£ŸŽßütûÃ^¦mÒ4•õ¨c»®®›.¢"0y™AM•7#£²âGµÌ•Êy+Œ&Äsœmžµhó¶@ÃKæz‰:(Röo²#•‹f]J OêSæU¹_´ÁþÇ|'ûIÓùNÏtC»>;ž£3ôÏmeª”>¬§0‚ÈÕ®íi ûz !F®¿#€¿4ÿNœ:Vâ›óùÃ}•ÍwPP¦ÿͼÇ1›½¾š}š¹’¤ÛõX4òl'ŽE>»¾qŒ/€##ãQnÍ Ê…ŒÂ83.gîmd#7ì\Ç@E0Û ããÂ%ˆZBªqÈ)‘)áÔ%ù!ygúˆéð·Å%?"ïÍ0$}Óêûž €w‚öJK6Ñ®RÈÙ´ÓRÔ‹*•MÆÝ÷ˆ™(<ïír2}€|G¶ªWÒ%HªŸ~“¬-Uæ]C}´2¨¯QÐ Äg§.3EJIÝÿ‚¦¯s“bʆ*¼×ÿÂÂ{3zv8Å®brµ–MA,ÛsE{ºmØÒõˆ8îêœõÚ‹˜põl£‹uÄ%@Aº* 5!YÂ3ió¨.U©?jŠ¢ZaF`Ç!p…:±í‡ ”²Y̺/ ¦ùWOÜ9èÇÔè˜w]Ê$ãd‚±ÁpÈw¬Â€)ól¤{Û_ÈŠŠ(CŒ¬tÅU`( êZ ûedØ/#ö8 eÕ&/stVrC™mòb´ ípH;ܡݩ¨¦i¢»ÒôƒC™¨lhN¡–C§BÝFÀß;LÛ9¬Þö f†89T"Bp»¥¿¿e ¢¾X¡¬ap€(#o_ݺ‹LM㬯ÕŠ…bõ>ÍоvJ[D«¡ÛYÞ"»F¢/ToOiÏF˜ðîÒ{ýÕ ™*Ç sŽÒ}ŠÚ•ÇÊÍ€m¿!Á:ðñ¬ê3Œü¶ý”ôU@ižñõ1Â_n›{à{¶mîÿ¯C1vŽAªü‹a\ endstream endobj 2109 0 obj << /Length 1134 /Filter /FlateDecode >> stream xÚ½WëoÛ6ÿî¿B@„"•õ\ÑÞ²è€k¼}˜›²ÄØÚ,Éå¦Ý_¿;e[~å4Rä=w¼;sknqëíèÇÉèå›À³R7üÈšÜZç®"+ö<7©5)¬)‹|ûfòîå›(Ù¡1wýÄh’«RuYK…”#näƒð`‡Å1<ŽÙ Î_äWÛ‰`ØiIJeYd]ÙÔ9;òÆ& Š»©·¥lÇCVÙ~ÌÖª£¯, “ô‘ÑÒÔÒYÊzÞ-ð;b¹ $‹¬ÍòN¶DòdÞ5í+àkÄþÑç_ïÕ”7ÕJ7JFëíF;É꺅aºm–ËÜ•õü‡=4£p×{ÏMC3tEè}ïG`±©rÎÆ5 .“ÕªCU0Õµ “®>ò˹k;AÀ‡Ï)â¡°$`t3Tƒ,ÈðHÚÝB¶ÒÐÅ x[ç€;*Ü2¼~M+?·/q£0x´ï<Ý: û½@áÆE¯(½ii­šVŸ$ª«EVëðW²-s:ýlcŽ-×ð4=úEYÑ`ªá‘‰¯Î¢Ö¡³¬6Š×+2nòLI 8¥ýðÀa zDw‹¬3¬ E1¼+µ8ËL×u![•“Ù&²Û€î…úél<_‘®$M­2fäÆö áQ…^®{‚ÍóÐ’ÅKi{¬CtÓñÁAý®w²šÞ5é%—–õþÔMw&› ߆ڄ‹Œ5&ç²W­œË/$æ4T‚ý5ÍœÿÆÎŸ7fåNzóý§ïNh.%}Âå¦Ô^KIÕp¼TÍSjàUYÉZAÍ–½/Å:×U6€ào¨k—{”>Ð~ÙçÁ¨¬ñ ‚”툪d·h ¢1+ú²nbµh)m?hƒßüO­„€±м_ghÏÀ] ™) Çð¼|¸FnžM¸AH+uòe¦ÔÙŠñ-SLJR9u{ñßÊÔ²éó( XQVϤ Šè\>|+¨ Ý7×ŇõZ­gJ>LëèçÉèß‘§e{›¡,aM<+¯FÓnpùT‹4±î4ie 0ì—Öõè·ƒêÁ“_<'¸¯ð]νóc]” ’€³· q˜˜2 ›÷²œ/fvèQ÷ cݾ²ÿKeèë2EGéÕdÄYePÏ¿œÁƃ¸x 6„ApdúS’¯¤ÊÛrõÔ¡”`Ùv—€½‡†‡.c·œéú©á›ZB£ê›eM4‰éš„ œlL«ÚârOgù]esyÔ#ÅÇò÷r¶™™N‚³•뺛yrßÀdéÅ "¹´êÞQÐþÝÇͦ  šx{q¬ ›kÚclGYºÁ¼¹Úq;‡°¶…Ï:uâSК\iûàÁÄ0ãÝn±c\ñéI<;¯#òQ‡ñ ¿™.WŸ~lêcäu;3Ü›ùÁ·–OyV“~V;õBÙøV€£‹ endstream endobj 2125 0 obj << /Length 966 /Filter /FlateDecode >> stream xÚµWKoÛ8¾ûWèa)`Í’”DJÅ^²Û4Ø"=lãæâú XŒ«BW’]çßwø°*9²tS0I“œ™ï›ÇmEW³¿³×ïD„b .Ðâ1J‰$#ÂÑ"EKœÖÕ6W{GXå ¹®6’­·Z¼ý.`½Ë˹Ï °ðõæŒ:-—‹Ù·ƒ)E¬S d@x Ѻ˜-W¥°ùÁV¡ïæh°A>Ìst3û¯“w: ª‡‚Q"À4 Q€bˆ <Ä(< (~ëÍ®½ãjëÍý0ŸÊ]£¼áÔ®¯õ¼Ò_›l­‡$×kæÄ­'%üºSQ8ÎFIÃç°aQ#¾Œõ[Õ¬ëlÛfU9Àû÷À…,Bs&œë?ª¢Ò~·Î@~€“R/ôÂÇ;³Øiž€K œÙ{¡p Í±ûZŸ¨à@á„8kàC"ToÐqúñj¦ îäPjè„EñÈ_ìsm8ãÌþ©I6jñr‚W¯¼yH)¾ñíX¨öK•Úù}UÛÉ:OšÆf„f„ÞýÃåJ_Í÷Óhxiô³‰CqÍŸiHZ;!°dîú8AöþE½Ùªô|ŽÛf’§3üH+çpê•!|ɹÄcøW§J Iu°BüU­ÛS5§Ô"#kp0m“Ð6ý»)«Z¥“L¹PºõbËçh*|gÀùø{Ö~O–²jíÆ¶V&© Ç$nífVÚ±—…š¨FÕVŒÉts¤œ¾®SXº~â¥S=òñEÞTÏ).(®™Ë97™k&Æ›Âx³xåA‡æ*¹{yu²Wv¾Óí—{}÷]SÕáŠÎøløZÆ}ç9K 9ÛÀ±˜ˆÉßÚÍ2h™ãؽÿ—ÅJÓ¬Ü4Óm¬ð¡½R­íEÿQP”¡IÍí„è–Ué„é÷â(p¥à$L/Ò¦2jA _¤Mµ¡„@×0^úE'¾Ç˜êý;ùûñr endstream endobj 2143 0 obj << /Length 927 /Filter /FlateDecode >> stream xÚÍW[o›0~çWXíÃ@ÔÆ\;í¡K/Ò¤MZší%&NÊ ²5ÿ~ÇØÐÛÖ®S|ˆ}|¾ÏþÎ9.FS„Ñòn œ][ù†ï˜LÁØ –ƒ\B ‡úh¡¡êXÚhðþìÚñVVRÛ4¨ãÃ>Õš«4+5ÓS—‚2¸ƒ‚eˆa­x굫nºð#|.‚)k¹ma;w²‡tâÔój$cEñlZÜaÏÇßXX¾ÖtcÕ0 øð(°“nRÃ'ÂéôT¬¸¥bLYy?„=™ç“ (ÄQ¸«‡6¬f_‰™¶¡z§}-Â.·NÀgïÛöÿÈæ–-ò <š‹³—KÎϨŒç3ñùV 'Yœl²]×W€i®/õz‘O)›iÔTËb§¤öHI@\×rû°,×tÕ ÀM)ë¨]^ëçxMK„j»c8&!YA’+g©Ü ‹Dèr.!”÷,fuíšQqœÇ»Ø ŠrPƒ”ɸ1®Ü$‡XÃÊI"¬ÕK9™q…P CLppÏ_4ßQƒdÑ]6Ö+ÛÚÝîÙiSɶ© ÎCf +/^låX *× Mæ ±ß°R%GÉ ÖäŽøŽâD–,eRçóTXš²S}=긺k )éoOÉV fã4üZ¤A’ ‡U:ŽF< ‡äÜ–‰ Ö¨©AíÄ;’Êø"ca<‰Ã.*ñ¬µT¤§c¹¿m¡¯\ ” Б¦RË5&(L•á£&Ü·‡~UKSdA‰t- v‚n•O[•#šu«\GDN)6°ë>6âî& ·Uå= ‹Õ wÛS+ŸP³‰*¥ÜMÔê»þ1„p«ã•az¾a›¦~ÉŠ0³Â³/Ÿ%ï^΂²Iiù5?à•ŒYÑ®X?5ÛVƒ| ú¥´òÍDE(ö€'|º4wÇ…š³,oë¯WwÃr™±öTtòÏÛc…og°ysìÃ2VÈÎÔ­¡>«}[uÙ}#›…TMÌUç¼`œ¯‹Û^ ìÙ|·šÚIð¬pŠwØÄ]Ý£jON´Ÿ=àA4Ý"®xXqÌŒ |Šj³¿q¢ÃÊ¡WdA^°Ž¤Ý—7jxõûüï¹ žÛà¹=Ùµõ¦6;–[ÿ¥¹±ç㶘eAøE/(ÊèpQVCÄfu…€|Žä›nçYÐ-k¨ð endstream endobj 2051 0 obj << /Type /ObjStm /N 100 /First 974 /Length 2254 /Filter /FlateDecode >> stream xÚÕZmo¹þ®_Á- P’ÃÀ8$#}Ar=Ø)ÐÖе½IÔÈR Éi®¿¾ÏpEŪ­îÆ·º¶ì] ɇó>ܵÆe”5>*ÏrM*EÄI‘ Êz¯(Yù!+k{ôòÄ(gel±„Ë*ä4UÉ ç„ÀLï FÄ Ët!ƒ*P"ž9+‹a¼sA@E«\%:PÁLÈ`ûŽÈ :2Få2À+ºµð,d‘C•¬"²ò¦£‚òËHÉ âÖûd°‹˜•E†É(e{&‘òÙÈXÈM‘@rŠ)e¡¼b WÂË>¶¤˜‹hÁÁ ){TK6–m"G#Ûν Ș-fÙEfÅÉ$Ba+–LRÁXÁ„-¦,–¡b'ʆ0T`c' H…àIžY¢˜ À¬Ê«hDÈdXEK‚N@½‘¡Ð`ô²YŸ±8";h›È0P˜-¸2³…X€/Š´‰ òMc-P‰d@`‹eý ’ÌnÅ“í˰Ôä°ÔXŒ–°å P°cÑ(–T)ãyL’ $caZYÌ\x$âAyÙ)ËZ6« óÅ #l’Ø@vNü ûÉNÌjË^¬’ Ýì‹À¼‡© À¯ÊxÄ*Ƀ/Z¡«œMNN&ÓSu×$8õ™šþù/«Õ°h˜kh`q7Ÿ¿|÷]³Ióc¶9à:tjÊN‹Âͬ¼` ·wZÁ÷Ëåb£NNÔôe(æß {‰ñœ©ÞÀ»rýæÓ¨¿À¡àhÝ ÂK†¥mÙ³¹rƒ•¦?®–×çíF]¨é§/ÕôMûe£v Þüô©ÅÍûv2}@íb³–PS&›LÏÚõònuÝ®»ðSž½nofÍ÷Ë/êB–âDÙ¾ÅBÍ £!GÞ~¾X,1ÛE¯O‰×[ÂUÂW‚+*+‘*Qç ¦T‰:s¨3‡:sèfþ·Mx“éùÝզܿš->N¦ß/W7íªlͼþnúûé‹ *7"먘µø+bœ6p!ë¢6P'£“I»YÎõø²‰Qgèf‹Æ»¬£éGÓÁ¦fýA_Ï›õzžRŒ‡øµϹ$˜h½f¬ô°r¿Ï\+÷ &òhWð(·AÊv7KE€öq·Ôžì@nõJE=Œ«É…›¢×½Ã@îÀ:Çx¨SÚkŽöÛ¦ûýÐ^Ût¨9Úk¨žÜ)¥ø°SJ<¨S²&‡R¬]P¬]P¬]P¬]P¬]Pª]Pª]Pª]Pª]Pòc6?R¦e´lŒŽ6R”:-aÆÕ¤ƒŽú‡æúãùfÕüã´Ù4Ç)°]FºCó> ÑÔ>ŽÃQûÖUÛlÚÓÙíY{swýÇ«¿c¶Ñƒ½G9YN¸ç¬äfÖÖ…ÃMÚÎÑ*qb9íÚ“tÈÛìbmD,bTR¨l±¸r ýXŽÆq—z*Ä\ͱ_cRÑÆÛ„>ñ«ý쌺MWÓ§š3ÊÞˆèE 툜#;§íaïÿ´š-6Ç0ä[riÇ¢\H܇f[ÖÁt(hiØŒ`Ci,²”3¨:ÃáT¼ûaà)I2…o¨`î3÷W0q¾ör»dµÍé8Ü»uCw)š—ë0n9ëõÙåF®cãžpz{°&Ù;ʕӳû©¼ÍÊ?ïü–L~P•È‹Š'W%¹–y[zÈ[ˆ-A•°•p•ð•õ¶&z?@ «1‘ÜÌøÿn¢gIåÝb¥í5ÞMô#×D”Ååv º.+ô‚:J’GfQòW,Ž€E*É>,GIò`lø &%s?˜#%ycåœj‡ÆË!R޽hŽ•ä½$!¬U<øCzͽxŽ•æ«k™®2#¤WyÝÃDp±ø”<Z à4<µî1÷¦ÖG¹9àJCçö(C9Ñq¸ååÜ1$‡¡¸ƒ';ÛzyârSD}åÂÏ<Ø;Ø;8”¢Ÿœ†-?LÃÖ=9 Ëw]BÝB._t„­ùØÖ|lí¨o=‘,bÔò…ŠÐùä!I‚jÜA|µ|ÿºù4fwÆZ¾rqÑêÀr ‹PU8*:~9ƒd³ŠÃ‡ sÌq­«÷Ñ”wÂ3é”l/¬f­o›ÍjöetAí»ŽˆÜpw8£‹˜‡u‘FÚÕãG‡c £¼#)x¶ýbœysÕÎ×`)‘ÊúoH#÷™wi$zQÎq¸$˜<›å%, 榤åó´aÜž‘µÊm‚Ž4”Ûù¨åC¦aÜR—ÃÍ(ÝR:··¨Ü/ñÑ“3žw3^÷EÔÓ2žÛ‡Ë'¢["V¢æÀíÇEc%:–‘Ê·N¾Û”/4¤¡ƒß¥üºËõ§1ëu £5Hü \›|) endstream endobj 2160 0 obj << /Length 1066 /Filter /FlateDecode >> stream xÚµWIsÛ6¾ëWp’CÈ™pK¦·¶;í¤™Ö–{±s@(Èf‡‹J@‰üïû°P!eÐVd<6@ò-ßÛ>ÀÈ»õ÷ëâçåâÍyš{ET¤qê-×F("4õ2Œ£”Þrå]ûçAN|.Ë Îý»S&Yðqùû›sŠGŠá(Ë ˜Õ*i¢dÈ:V𖌔¸È#Ll2xIŒîMŒÑDûÀÕu˜ äß YÙä#`Ö80^+%„gþºëƒâ3ë ~¢Üë•G³½Ðާ¶•Â`|!Ôo˜ì«Ý¡ÜØZ˜'d#Äi„°‰\Þoø‘gqæ/U!î7A 7Qtë@»í¹ØÖ²joÍk‹BïegÖžËmß¾6ò¦¦6Õ klÝwÍÛ“º=Dþí5[[°VAÞ6¼¯JC`â BìW°-¹x ;Ü$*òø{¯^w·UÉêQeŽ„úÝæ¢=ê†IÉûö!TèÚ(Æ×þC'9´±ÿ厷Nç©ÆÛô.ð‘ú•´Ð³ÇúµÛ/€¦Êé·ÑÝ$d Ÿ>Á dj¦ÔÃóºõ(“Bezq.ô±d›Œç"°µ\j"x¨¯ú GE’LYÇÁc_Yc }¢­RË8ÂL+›†µBÇYP=ªa í–eïßA‘ú¬Þò™#f‚«^Í#šØ!:1ÑÉCqG¯ÈcgÞ:…èï,% ˶euƒå«J7@¸\3’d²êZckä„©ñ)xãØ.¹rå=©EçŒï¨“ê0êßÄ:ÅgÍFÞOÌêB%~ñ£ørcèlÇšM}@[s«•ƒ±”îAe*µ¶ƒk A·'‚ö,œb/ ¼„gËÅ¿ ¬S÷· ú I¼²Y\DÞ >‚Ùˆ¹÷E‹6 ÷ªî+µw¹øk6}EšæŒ§Ðc¤ Íl,çp=Ú_Æ|^L†%Í)‚Là”ÚÿáBMF’Û' XêmÍzóz5Xu† ½Åñÿ Õ„D·>’¨ãÆ–ú”‹²¯6º«Ÿ1h*Æ?«à*@ŠM$z§ ¹æ h›|§&I€/u1¡±ÿç/'æ‹(;ø¢ßQ(£¥°2óH7BHÓáð ëøÏlô0Su1€¯k ¦j'Ò—|Û ý7¢Ç…$õÿá%¨Ëc†øJ°[~ü„ÌçpßU*_Ý'€ !tuÊGQ4ž—êfOã—/Ä%1+¤ì®[™½N‘Ú”5„’=¼B¼r½Z5|µ-]jN•ƒ<Îó™õÂnK® ¤¶?™åÃÕû÷ý££þÚß³Æ]èÿsÌäÂÑ{&3Žsy‹ZjªÙ=֜µÑåÅÕ™STÔœH®ÔYX2ÉW™;õ †æéHÄžÔǘï?ÝU†B endstream endobj 2174 0 obj << /Length 1445 /Filter /FlateDecode >> stream xÚ½XYoÛ8~÷¯òRˆTQ'Ýî>ds(l7q÷%- F¢mµ’åÕ‘ãßï Y’ØmPhŠÃù曃C9ÆÜpŒ£¿¦£·W>1&ö$tCc:3ˆãØž!vèMŒibÜ™a8þ:ýøö*¤•^àٓȇ}Äš«4«yù÷ýØ Bó;ÇĬ+9Jhò;ò–ÞÀr#˜ôä6gå¼Éùrì¹Cñá¶‹ºÀ©aj{”ÊŠ{QtM½³üÈ̳åØò<4ô ©®Ô¶ë*5¶mï׺¨CYåR´ ÔùæŠUO¤êºPê/å0çõfA ©£<õÀÊj?žm¾N«Z©œI8,‡erü0X™²ûŒW]„¾9ãuŒV,Nå|Sq9ø1†m9ìñ<¶ˆùˆkŠR™÷Åq4QæÃ2¶|µV¯š,“£vQZãvÏr6ΪcXˆy–½Dºå\¬ë¹ .² #@üHXÍ”ÝE©m œ„ÏX“©5©Ú€eнY€}a%9"2ö ¾ó5C†ž5Ý¥TºÉ匳º)ù6CŽ 2ãly¨žëAÂ’L¹P…{½`Š0¦AåiU¥Ëùá{E 0ü…ޝYYäïH ƒ„6üîQúÅ%Î àGD§,o=&î,**_õäP†¼ƒ(ö˜eq»vÓ€Pjò¥ 6€¥hö[Ð žLÜײ«~%KøSÌWÊ—P¯º™ÉÌ¥½ÌíÙï£ý á÷S°* ]Úw’@BM€u£P2€ƒ–ü¡À±`À"3«¬}hÞ€ ±ƒä‡‚ 9'cá=¢’ˆÀlbO‚@™íx¾vB/]ÚJ‰Qu·`BýdAo¸J¿Ç´^ \Ö9ïÞ('G0˜ßµGaÏG–FüªŽZKþR¨&ªÜ-‹º“U‚E‹ÚaHûeìRÅ$}Û´úgNo>_nSkùEŸ ³Ze7µœîÄéŸÏ@¨|þ„ˆž`7F×¼:»¾ÝrÒI±ð,£"!@°#kÄh  s†!÷“®Ùw¬XQhO¨Û÷J•õ½Ê_•‡Ýò é<Û8nK–«|[§`¼n;˜zBâ1zv™¬W6+ûÛj1¿-KØuùÄòUÆ÷÷Ô=÷QØ,ô[3#ÛÓI¾Š¡…Ã<þÃ’Ï+h Û#Õy‹ÊÇê>¿U9”ÓS9!úTµB€HGŸ,oZgvÞ˜ŸÎ¿‘m";–ë.L„¹a®‚oÁY‚`Ÿú8c²!@÷ ü’áâ£äÍË¢YUGœIp§R̰þÁu9ý7"ÀŸcö> Q ‡1â|t÷Õ1x CHQãQ,Í HS;ò=gÆíèŸÁ)/­½»8*„ÄôHh!í_HÑ'ÃË@8éêƒ+ÅQ*2/ˆÌÛæÞBŽ<1Ý*/K¨°¸æœ—5åæÎÅù¾Û~Ç·}P{„ýÒNËåú Û%*±/x—éªN‹åQ%+’âx¿—óÍ%Ëá¨Ðƒ¼ vÚ…±&Dµº³­µßÜò¦d[¿‹·B2¸+¬Q0]5óm—¹¯*S?Wlί»9ë…Ö:óUŠ«ûªýƒóÕfªŸœU{>QkOnë¤?q‘æ7Uéë‰4HýíCOéï½ ÷œ×¿£«p©ju€q{€ß²¡À‘¼„À@¡Æ!¢v)íòY­å0w´ä¶´Åw{ÒV(覭܋©‘HÛ5ˆ¨—¢›Šv:O?¡¢þ|ú‚ endstream endobj 2192 0 obj << /Length 1453 /Filter /FlateDecode >> stream xÚµWKsÛ6¾ëWðЙB’ßÔää:q›L2žÖ긘„-Ô|¨[ýõÝÅ‚2%ÑŠ4m‡ `Ÿß.Üyp¸óóä§ËÉ›³$sfÞ, çòÞñ9÷Â(qRß÷’pæ\Î5;›;Ÿ)»ró©ÏJ¡õôæò㛳Èœ¸ï¥YœÍ©$Å=neÁæh°Ùíw»A ÄÎ|R÷2_å¥Ü8úÂ"åC]38Ì=–ÑáëwrÑÊ\t²¸±ê¥ƒíÜqýÔ˲Ô¥ÊN¶çwʼ³æÚ Ã=¡ÕBOͤX󧹪éÿý#[­CˆXìqƒ£ÞÒt©{{àó2§Eshø›qLº#×ÛQoèÈ]=U­;) ³ñýå䯉oDøë€Æ³Ì¸9¯&×7Ü)`ñ#h‚óžÌÖʉ æi„ñ+‹É¯;îçCÔlèìûÜK@«8ã@K¬ƒÏ-=TÚ'³ í“,âìr.ÁUqQ‘eAÃæžþWJ>á(eèiì³¼Ûcg’y@ú;Éžh$ â0ðÒÔÂëÔy«FyqY£Ó&ÑÉÔ‚„UÍPjk"äÀàÓM]Ÿ ÀŒªeK+÷è®iUýÐïà¶P5@Qµ“÷v÷BtJ”åÊm¥nʯˆ` Ë…]N_ÄK–¥ö¦nìT,Ä]¿¾MÊøÞ,ŽÉ„=Î*ÔzYvja¹ÑHˇJ’YÂøËPïHñe]ˆve™ýˆ dAÌ.–‹…5­Ó–ã®­@%¿ ˜µ¥cÚöÖCjÚ|­šRæKTg_xÌÏ>\üŸò´e¢(b§M…ÌïúÍOª››Ã¤Þ‡J<Ƚ¥¡ú#Òü¢l¶r~ké¬õ†~£pÄœ#,C?fµ¨Œ—`X*Ýá¨GÁÁ&ÏBöù0Á(¦8Ä1£úf(…üÂè6Cñ}x»+ÌÂ3ÌÒV]k«hi:€ ¡"H †Ð 0m©8´Æ]ŸÂô;‚®:Э$•u+É­8:Ò­ÀíÂä“Í¥½²‘¿¨‹cAÈN{Û¨B›ûfÜ2Œ2‰ 5±L•}ø^‹Î°N¨câdoö¼èëÛç[¨V‡y­Xš² Æ\´"ï°iÆ(]£öŽàþ'Kaåi®h?ÏJ4×fñy´Ç0"wªœa^3BDï‘zgƒCý¡òöFµ&mM*]ì›> þ,d·cEO`‡ÅcÓsµòA>+ˆ½©- ±Â÷±ÿãZ¸Ÿ¸¿ßØ?wg7?Ü~÷ªPÓÚÑâFÃÎÈ{M—DD‚“`<Þ|pŸn?JñTÉnÞlÝ­£–xA<ûi~šyAìWfg™ó+râÖË ŸdŸñ,¾Éìùq³’Ô< ÿ“7™AËÒäß½ÉlpH{LÁÂÖ`|[ÙæŸ‘{ö½Ï£Í®iLSpÜ?Lªa¾ endstream endobj 2221 0 obj << /Length 514 /Filter /FlateDecode >> stream xÚåW]o›0}ϯ°ÔI)¸æ;HÛ˺fÒÖ­RKúÂòàÀ ñQagMÿý †Ô4Ò¶j Û“ ¶Ï½çÜ{} ôaòΟœÏ-yØs ùk¤‚MËA®®cÇô¡@qfêÒÿx>wf½¦M°ElÓ왫ÆL¹V W¹ÓT]É'¥ª‰w«OHkRسz(Z£®xiJ°£1 Ž=7 8·ïþL˜8çìLÕlB”[SŽW‘œ¯ËJNÂŒ2& º})‚fõµ\Xl¯ï8¸› MˆéÙ­Oeì+±Én*í¯ÊmÑêQ>½•×ÅÕU»Ž1Ûõ¹Æ2Lìé'HÏnó(ßV0`È€œœÓ‘ãaòžrZ³+WyËã­X; ë?Ç—¥ù}–®‡Áöo—£ ö'xdO¤WHo  9ü(Ê“p½ÊþÒܽJ÷~$<» óy³÷}9Áƒ §ør9Í3(bž4øˆ²»)ÔÃNŸ°×l»ݱß,¶uÛ]ãB²äXÁ}FCÈ¡àGÔ`i\4^‘i˜ÐІªiž2–ñôB«Ê4b/PP›Aa5Ó7Z׋³-M€¿¨Áç2ƒp›Á×àt$¨óõ?΀[ˆk{”§eqIðÒ¤ù2LʇýGXw‘=ùç»ô'ß§žÃ endstream endobj 2229 0 obj << /Length 1773 /Filter /FlateDecode >> stream xÚ½XM“Û6 ½ï¯ð¡y&ÒêÛvÒË6‰3mÒd&Ùä²éAkѶR[rE:ÿû(K²dÙLggÖ”D‚ø<ЭFîèÍÍo÷7·óx:š9³ØG÷Ë‘çºNÆ£‰ç9q0ݧ£k>ö§Ö‡±?±¾Ø[1ö,µÛžUŒmx•Êñ_÷ÜÎC¯&&t=g2 `- žáœ—·…Éam²mfƒ8xК»rµßŠ|ø–’åí_7©›0ÙÞÔ ' úѡ߃õŒßÖW>ØAXÅã7±Pm…½æ¼Ø‹­;žÎtTâT~<Ñ %‡Öü×±zû±EV—u‰.;.;ë±ØçiR®4UŠ;=´ó}‡n.œø]X·Â£T¨DeEN_5Œ&´ ¤Ûb#û0Ë}V½?T™,øåBlb›¦€¥HÔ¾¨íh;³©ö{Î,ŠÈ9è(ÇÚ¨eQ¾ Ñ.‘²ÇöÐz×å,½N«¿¥€=Ñ8˜ž¥` ⓤ'­"îË*êÒçÌùÙ•ÇStçüqÄ>8ØzŸU@CE:n(_¨µ`ͶB­1X§¬˜ò9ì¿'¥<¯O4A}`/´¾£BZí/"¬è÷Ql%e–ÎZ}¾`²V:% $óS‹¤Å 9§ßšSmªbˆµ±!­Ø_b`#ŽUoYÛŸtêƒæ¿‡ËÎCðS!9ÈfÝF{±±Éس(iŒçÖ%«À¸Îòó6†Ã6F—ÙøQ áýyG$÷^{à¿\I7ºy'éY¯«»ƒcÙïèO°8äŽÈWV®:t½å~‹ÿ¹wmñ6P Ž¿Efu;’ࢃMÉ:úŸïúÁ]jêñÂÅ0ª.¯‡–šÖ™xÀ&»&Ò/ÒþýìJÚÈ`úDÿ'·÷R4öú¢$åd`RfL 1èÆ{¦ØóíÌ›åPh·µµª¸ί?/÷Èuñtί2¹Cs&ÖÁ h|ânn(¶[.5Ç»0©Òb¯º¨’—íù2žÅÖ ¿ð¢y0uÞÑt7uW$Òà2¢0 ñŽÚŽª>ˆ¶Œ¸ Šþ}ˆÚ5,bj#¡aŠ1g±à¼8N†™ ï[ÇYý†‹¹ó¬asur%iõµÌ%šEúæ+tg¦D ÄÇFzÂ:|j ¯ Ýéɵ ¯(}.Å?ûʳ—IÁÎí]ƒÝ´€¦+tùº¢°¥¨í0¼ÅzÞj\⨎Qœ<Œ»Žç†´è«ï¹ ¦ëêk•N_OÉ£zx~€1¿0ŽùvG|;BoG¬_ꢂ¯ŽI _¯ Ñ[š ²_á#ºSH%RîÓ ÖDhÕ´Z^ÓeÕBN$å‘°Æ)[¦Ï WõQ¶Öh¼–Ïi³hWKÛ7“]‰åõýÍ¿H™ãE endstream endobj 2241 0 obj << /Length 1443 /Filter /FlateDecode >> stream xÚ½XKsÛ6¾ëWðÐ82 ¾š^œ4î¤Iê©­ø"ç@‹Í„"‚²£ß]”Iåé´ã"°ïo`àÜ8óÇìí|öú”Q'÷ó$LœùÊ¡AàG,qRJý$Êyé,H¸_ç¾>M²ÑÉ(f~–¥ÀGž9uÃŒœ¹aJ.=—’{7ŽIQWeÕãÆÌ-vxÇxÄÑ‹Bæç‘ã…)¼‹ß«â=…^ä*µŽ,lfY¶mWVMÑs¡Lè‘–þêziš’×cyNÊ¢/\ÉwÕk®^>Tý­z¹l]lzä*÷W]»Vûý­&üfÍ´¿/úªmÔöµ¢Þ4eÑUJ'©uA¨Ž|XmŽ£€ˆj}WW«­ÉbÅ”TÂHËâÌÏ¿¼·Ð…¤hJW.Ú¦Þ+´x*¿á«Áo°¬„zÞð†wà®òüÎ(z©Ùç¤< §AeÁžŸúM×ðÒ‡CŒ‘3àÑ=T‚ƒ˜(b¤ÀG„:z5on0†ø»®D¯V¨>>ŠLEßKp!ªæ¦Ök¥®V®G è˜çŠtg¨ÁÁ¨{âÓ0Sºä[3&, ‹H.@½XyØá˾íÔV»Rï×mÍ—©ü¼W‹ï˜tÛ¢šâ ¾M$?¡è‹N“(3a1Ú˜ïöžH¸4¥)4º€ø ŠG=„ŽJÇ÷¼û]¶Õû+ißx¿ãâN&_)/¨‘N$°Üîv]ÏÎ9ùŽ×µÍûÆÔtµ×ß@¾19,¨YJ)Ú„!x 5 A. ðUŸŽ ó‹QãWfY,¬c1™ïÀý¤TáÛq©ÚêDêT„Äœ+ ¢u½õ 8m}/±Vš¢R5Ðõˆ±G‹Þê‰jâ=ÆV«Ø`x Ú¬ñ¿2…kXId[Ìf¤.TÏ’:xWA<ô!øó3§Ãv¤–ç²+MÔ'’³æz°¡Dðêñ¼¥>ï€y×V¥xŽ9 ¶Ç Aä 0ƒ>_—vè³yøD9jRžu+† £‰©nbÎb¹+r ¡Åæú1ñÍåŸG¤ñ·ÍÐ&ž&4ö ƒÊ¦Xñz׈ÙÕ«ê*ˆØ1í`±øÍ;äõK7Ê] J®E40‰Ü n¢/#K¬¿…Ð*·æ‘QÙŠzÃí>´Mm²à§ÓÁ両Í2¾D°eÕÅ ÃÐ6»àÖ__>}²TH¹¯º¼>²€)(p%]‹‹iy4²ŒUÄŒ,;¾n1Itå„îÆ94LÑ*þE]ËýáNÏc´mâ†L2çïÛ¸Yª¡v€VÓjÜïtPø™¨0MŒ’¯ŠM­ÉÄÐðU!H‰±NÇÿA«QFü+ 1Ðäf9ûáŒb"ÍϽ‰3fn0°…K ¾PÒO«._6²Cf$ÝMj¬LžCØ’ÈkG¥jpîomÝEò«fxQÛé7¯£‘¿Ó[€ž7„uH:à^,ó:'Š675íÙdªÙÆ3•OqÛ>êdFÝW¢º®Õl¯RÓ^ÚPà¨4²±“å­2ñ£œ*é:Í "Ó½ý¨1ÙÒ̇‹üéÙ¥·¬±Y¾ŸÏ~̨dCw"F}šgÎr=[| œ6a  3çA];аü”E°®‹ÙßÇ_8&zÑÀOÀ¯ø±!Èè£r÷êsÅv‘ùÞåšø±#Æ ´d|4!cz³]ì,|‰]JføBf¡Q˜ß¹XvÕÝ“kI’]l4¹,@ýш~`RoY’e:lN/Ø·0ìÕÃÐÞ¾hèe)‘!:ÛÝÁÆæ™!­í{û˜—`襛'#k_â/å뺸=˜JZîçÇ©öÿ‘ûߦ°ÍýûOÿ?? N endstream endobj 2153 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1797 /Filter /FlateDecode >> stream xÚíYÝo7 ÷_¡ÇíE'‰%A~,[ ’`ØVäÁMnmVÇlgèþûý(ÇY\ç’KzÞÃP Hé;R¤(þø¡ žÄ8<%ã™”È&dQ¢&g’°‰¢˜x¯D4“b’S!N&qQ"›Tâ(H6™êƒbrV–èL ú$zSë+o¼ ª<ã}¬ 9ãCV%Q ò ýÑøU@ K Æ ÌE Š ÀNŸ°ð2U*š«RlÀçT°n U ƒÝGÄžW‰T¨H` X éÞÙ©€Ê3«+’>+A)ÈGõT‚ʰS_JÕšðGê^³S»t¯º9¬ òÙ×E”R#¼î¤Ôí`¤{ņÈéÛ q¬«ˆ¡˜UGN†U‰l(§úG缌vǾL!PE]Tð ‚F á‘à¨I-Sª–DÃàS oYê"^€IÅc%§N,P*zˆÁaaÁOPÞpÒs .€Ò g=§à°J Žà ¬FGpPVR•H&º{NªD1ÑëAï@E•@HF]TUXb(*ŠT»@‚ÔeXÆÄè* XƒJ@‡`[x½yµ2¨RW†GÄé)‡¨(1B¢²À‹DEDÀ‰Hd]~•X:ˆŒˆz>„JQ¦!©T ¬\Vˆ:W”àL¡úCpW>@,V`d‡šÂ€±·7jŽÿ¾lMó|:-GÍÑÕûeýýóùôÓ¨y1›Ÿµówˆw'ÍOÍëæå;_ŒšÃötiÞ!–­‡¿Wa9ùb52=ë"ƒï¹ÙÛ3Í‘i~œÏLóÊ|wøÇÔ/.ÇóEûf¼œŸþÞ<{6¿!ÌÉV4OXÞ(DKˆ"$ Øvšs¸csB€W‚ÂÒ’¦"üßmÎÕôr|ú©=ÜžÂÖ#þ½Çi]»G³‡Ç©E’N{.¶ìx…Å<ÂÈ™CÓüúÛï¦KšÞce6Ó«É䤓Ù;W¹¥D+ˆü~Ü1›€ÔžÜŽ­CfêÇÍq[úZB'Ú¯ó–{Û"‚ºôeö Ô/ ÙŸM—õÀ÷¤±ø•Ø>…¸ë5öQÅcqëȱeý¯ Ñ]Ë nYÿ@ªƒ.ýMÍÁ|vzÔ"þLsðjß4Çíç¥9Ù éƒñ‡vÔ¼„Aít¹Ðj[ujä.fWóÓv±ª»õÙ›öì|üböÙÔ`äñT¢÷`<‡4jóÊ’Ñ ( (®‚ÚS%N‚”d$:¤ìŒ„§ÝN.…-Õÿo.†Ãµ÷ˆ±ˆ'[H;À厑ór§ ¯«ôòÃÅåòï-l£TöÇömæüÁ!âzsSZûr£öÛȽ¹‘í톛ۂ¼nAvfêËíŠå˜»¾‰é ´ÿ Ö/¾ý €ß‚þ“ŽÓÞx OxòƒâÚE‹²F&ÙÚei€º:) <ºQuÔ^ÍÇË-8%zœn3?\*ïâFcmµ ôäÞêtӛм¤² fÍ=¹{,}­ÆhaµïÇ ßYÌCVË ˜u•Î'ƒ©„m0×LÈ'[`Êt]-3¯‰¸&dM¤5‘×D‚Ä(cz‡!Èlì‘Ñÿah´Ì¥‚vÿ|²lçoßÿ‰eÃUYeX9#ðtÜ$?­§înþèr¼<O^_àÐìå)£¡Ã”LlY‡bý‚9‘‹º;7³I{z5iCšRtœ1Œ–‡UÛX½Òc¢{rå‡ D ¼3›xLf$ܲFDÃåAk^”ùìül1x_ØÛ¤÷S(ÿzq0,3uðþÛ_ìáÙxñÑ^´Ë³A-J„¢ƒùÜ¡Œq4HÚ§>8¤­š¶Î€½jÚmæ‡kÚ]Ü:ô"o'ÜÔSìÍÄ”ˆzr³Àµ©'sHÑ:îë_d»çŠÓeŽþ÷7îÿ'7“Í?/m´xÉ™âüýÞ×wuè̶º:½n~TWwËz‘Ý;co0ß›±»EzºŸÊ¶ŸBzr÷®í©·÷×D\²‹)S$Xý…õ­CŠ”i'Ô·eÃ䨎FŒö$@9¡=qyµÏu÷ôÙ;è$)¢™rc ëÔ–ýƒ¦ì wcŸë}cJ*˜>´¤«§]A*?ùÓÜ=¢¨/w ‡î”¾2!vͼOÆ6ß‘©<Û´†4­!M²&Қȃα<Ü#AW %AåÑïÞ²„ÿz> stream xÚ­WKsÛ6¾ëW`œCÁAðåLî´I“ÉdÚJéEÉa™>TŒÆÿ¾‹i’¢»íø€°‹Ýýv¿MÑQônõÓfõúm£„$! Ñæy”Ÿ‡(ò<ú Údh‹ß ù¾L÷Âùºùðú-÷Fúœz$Š}¸MkFžÒYQ{ÿ/›Õß+Dмáê0òI@´+WÛ¯epøÁQ££V-ïW·h½ú}¸o¾êøy4Žß£$„à 1; 0…¼“‘ÝÖ|N•ªãúAŒsm Å,•©6]Άû$bì%Ù˜¨ùê!MH…&ìŸE»kòƒÌëjùS“Jx1r½„„,²†ø}HÄ>•™{WÙ²„pÆíçv×¹uÿiú/4 õÝ_b'¯7 —u&Œô£YvJåjßÔwWVåªI[)šá硨eñ8:=^gBÔ/4æ2Ÿ$ž‰áÕ+£±ö­k!êÌÈ÷ucÝiÛh"oÒêô Ú8Õ-^‹®Iå’Ñ¢DÁ)4:j¥é[Û=d6©±ùÿ àÂõ¶iF÷úüñã¢* ¯·Ýqö¬/ÉÙ†³z·Í¾+Eåø Ëöbãk¸ b3¦óiEyÄ"|[JÔw^ˆ—¬æÅ‹‹Øý‹Nåä×Úa1>‚§˜cY«5À]SÙ½a÷Çå4ÁíCÝ™ÙOw;qF®+an¨ïÍÆʨ*8¬Š~é-Söa3Ô›¦øfSU+ IrR-E…‰¹D‡® .áâ÷ŒÐ±qœ© Øšƒ¨98æø$™ BÃ¥ Ù¸4s ²öÅʆÿ¼Z* Oi ³)€ïªb}HežçÞí±5•ÞPɨõÐ…‘,Á”¨§²–`½Qù…8?"â’g|m.9æ½TJQäÙz÷·¢Ð‘*9­L)òÒñ°}8  ;Y—øNmÅã§n<Œyý§í—ø7/ØûéÃumÄoNà´yÌ«½=ݢʆ½Ú²Ûðk°R˜óexᥨ}ïͼ…ø´å#A÷sßé<h2‹Û6 öFÑZŽ ÉÍt³YMò'%nêr¹@A…·ØÀÓ©ïÙ©±'ËÈqˆVÏs÷oÁǬN²ÿ¢ž–p0zâà0®^ßÓP}F|ªI).òV̈́؞Ê#õ³D; @j»\¦w…Ý×*JøM»4r-E¯öŠù ˜ˆžgðGbÔìQ/þq2$·ú “ÁÍM‘>ÖÝwÞÍIeÝhgˆÁ@ÑÌ –LÈ4/ÚKhºƒÝIÍÕWÀñy nz~ÛçjF>"HÚÚa'!ò¬'ÑÆÄ¸yžñ¼úEöñmÑÖg>[žQŠùà[(Æ|…ÿEþaÌY; endstream endobj 2266 0 obj << /Length 965 /Filter /FlateDecode >> stream xÚÅVKsÛ6¾ëW`’CÈ™_ ÙLNkg’ɸÓJÉÅÉ&!‰RT °®ÿ}w±CZ´-µ‡^pì~ß¾Î6Œ³‹÷«Å›«Ðc©› _°Õšyœ»A(Xìy®R¶*Øûö÷Õ§7W"í¼q.„°>H½*•êäÏíø‰Õ´E¹Ë´TxfÁ{K—«ÅŸ ¦œyƒû®ˆ"–׋›ïœ°ø‰ÁRš°;³µf!àˆÃæ[.~ô=‰I9^¾¤Ë€ÆZêmSÐ| 16“¼Ê”"V±7É\}Õó£¼±®~ý:wbv7@‚HÏ¢t·-ó-MßÑpýåóçÿïRvm¦Ï¦A¹¬1gž§ü\î]´›®–;;ð-­žÌÁgrÐ=è%áÔca Et±;*“‡§:'v“Ð'3@íiÂG=+¨hÝëÂ(‹¾¼›‚ÞÊ–¦&ö¦ê8} Qæ= (B@×Y­$ëaM£’›ÂÌ4.¦Ö-õ™nWdí=‰0ñ@ÝT2ï*Û3M ”iʰbèÀØNûHò™+‰ÅÂMšsîoÉåšÆ>Ðuw%­*úišå‘#5dœ½í÷ØQ%¨Zg]¥IÛÀ׊ [œÝ?g 0 ÕéðÓ1S»N{Ö’ÚùǃÎ#Uæü(ÀãFö‚cÇ ´w5ÑÕ!@ïÏY¶^“’»ã³I<ŽÂÛçÉ!’£Ø”#ú“’†dÁô‘ðp묬Կ¹~—Ãå‰ l·`”Zu†´îie ?±5$HÔÞ°’yùaN²ÞWrRY Ý >måÚT;(6ƒÏ™m£$‰ rQÞÕXa;´5&ì܃/zTè¶þ2—PÝ´ƒ/Nºû¿Ú©°²ª“gy®ëEo/ÓÙáEB}&À ÑÛ™î±Z=âåßúTþBI@™ˆ½ÔõÄôƽn4MÚn÷ÓàL°¥ÿéÚ‘Ën›²P/&w>„ L \î T8Fr8rD ^³ÿûõ& endstream endobj 2280 0 obj << /Length 992 /Filter /FlateDecode >> stream xÚµVMÛ6½ûWÈ¡1¤DJTѶi¼I°MÐÚÙÜ´m«­­$'Ùþú̈´+yeÅ ¤0 ÉápÞã|ˆ“5áäzòË|òbi’°$ "2_Á9 eDb!X&dž‘½®Òû¿,Òºö>Îß¾˜JÑ9"¹`±Á`«‡¨3áîŠWóÉ?"'âh=Š 4Yn'‹œd°÷–ÀN¢ÉçVsK$ÜK4ZÙä÷£¹Ó±E ã.ÁYFJ3¡Å ‚ãq@ŸtÎ.|¥%§óñüPi8æ)Aᨾ<žF%#ÆuðXÖ}9𑈘’Úºÿ«©—U~ßäå®çþ0z/"4ñ…f*pï×⑲4XÑrbDsOÐ, j@ªòÆ­¯ªr뮃Ó¤Z“ƒøÇõ)ï‹Öl¶~ù[ÚTù—š{þ-(óü8àôOO‡Ôù–•vl6yí$·bvé]á´Vûf_9Ù|¹G§St…,½C(EÞxAL¬R¹BOÀ ¨O”²Œ¬‘ˆš¹hîòï#yAÄ‚DZÕYQ6õ ëtñûÀsúÀöµÉF9ñçô}ûÆiñ†t—n•Œ²µåÁárk´Ý@®pemv¦Jãõl<Îb»[Þy¾ŠèßfÙŒr:n úoxUÔåŽ.SÆŽA4˜±=·ñ]!ë’Àž|ßlLå˜@ ?>)~¥‚Ù‘¡ã`ø/®8üÅùì—RC|Éÿ·¨ÉP0}â×·Ó7»U9^Ðb,h¯1=òõ¦À¸Q1½õ∦Unó W¦¸bÚj †£©tR$,Vñ÷©taÂYߥÒ]›ÆóÁMw™j»ÒOžê`Æ­•Im1ÁILVÛ´½Øî–ÕÁÔS‚¯ºÂŒOv4Ü&›j“ æ«äºûȃFèÐYÜ»up§èPó>©‹û&/ò1&âÄÕ’¢ ˜ „ëâFsäæ ÆÞðVN?oòâL C³H¸Þ7»‡'BŸ.Àæ¬UNeü¡VPC¡Y6¶Ž†®ŽJZÛ{°<Ø•~ü îªõhùP§k3ÚE¾ÕMt/鱕w:@9vŽ­i6eæ&užÕVþÙÓ«›Ù+·Í;Ô2d#Y"܇Ò)­gîé™~÷áæfÄò…†GÛÉO¾?¥ÅÞ X›]η1Ÿ©qóç±>{f5fácÎÚ²‚Bçs:~ü!ðÃP@¿ÝCs:4xà$Ò;¡Ó:Ša_倶›'‘Ý:ûðƒ9u.þ”Ûï£ íš܃ͼÉÌ}e–ð퓚õóÁ„ƒŽö5X endstream endobj 2311 0 obj << /Length 480 /Filter /FlateDecode >> stream xÚÕVKOƒ@¾÷WlêÁšÈºÈ«$z¨Iñ‘ƃE/Õà CEhjÒï²K+DšÔjl=ͲóÍì|ó MA— ¿sâ™:r±kŸÚÈN6L9ºŽmÃE~ˆ&=ÇPÓgÐbÎ!Ñ}™­°Ùó+Åñ’\ÝM͹·÷£Q+VP¤‹Í iT…µœÑð&tÐVLò8™±8jFáßÝ[ÝæÀï8Kq ÍfZ@X¦®,~«_è3FH -ö£…ìõ-´lù躂ˣHŒä/?Î4%ß)›Ãÿ¢±Ú#­³cm3;A骛Pþö.’›M9MºU¾ºIÆišÇݯ­¶lîBÔ¡91Þ`4þtÿ| ö¼è3ZÄ”±ÅF+t«6XÕzëÒU-BÀæq:ýWï×*=©Úr¿]}Nwc­©èªõC§ÔßMhc7î}¦v>»ïóÕäRýÎ?³ñ endstream endobj 2315 0 obj << /Length 474 /Filter /FlateDecode >> stream xÚíV[OÂ0~çW4ø $¬vŒv,ÑL˜—dø‚>TÖétÒMþ½];p %x‰Oíz¾söÀYãÔk¹¤è.^L„ Õ#À6MH,x>˜¶ÎoÜ‹$HÛwÞå‘Û3+ð2¡Ý·D0 ´qi 2¼Û°aõ-‰6º¶8´”Ï-Âfá%<Œ®S´ ŒPkl©5fùcê«}rµ™E4Ë-»Jk*­‡%á*‡iket©óÑâ)¡„ƒ±b5VJÎHrvd5HzÿÄfyg•’4eªæpRfP„jÆ”?/(ÓNãfG™šqÊi’…ÍB¡z¼òUYNó—¬ÏŒÆC=˜E‚W˜&PCÃgsÎf4g~Ágë !„òØÐä½QÇ]È¡6½˜Ë„„œeEÚ«ÊmÐ,EºšŒF¥ug1¥AÈ÷ÎnçlÑ‹Y’ÿ*ÕVʇcC­ ½°ý·þh–çoù.-±õc”ûˆ.¯ûÖž<œ×LÞõd¸sÏüõt=²1+ÉöY‰·ÎJ%¶«×V7Ãx…ÁR#¶e ïcñ©K>0`¿¸ ƹÿWþ¥»ï¹’ø;+Iö[Éõ?ïjzW‰ܧ endstream endobj 2319 0 obj << /Length 1250 /Filter /FlateDecode >> stream xÚµWKsã6 ¾çWhv•f"EoÉ;ÓC:Ý´Ýi{HÜôì±èX­JNê_€ Ò‘ü8äà!M ÀGàÃC¾õlùÖ/?Í/®nâÀšy³4L­ùÒ |ß‹âÔÊ‚ÀK£™5/¬;KïóoW7i®½e‘Äè‘ïüzó[³lñÅ _©Ý™&áFI"E܃œ?vÜÄ÷í»ˆÖš÷«¶ ý²´YT¬ëD¦Ã}O '†±ûºëØ6ð-îú?Dÿßr€ÒŒá*Õ©þ­A#DÁwSDͪSîdKG—M×G?ŠkIàC¨^”ëè~Ëk9m¾á.ÙÅ•ÁUÈ ÕSJĆþÖZÙ0à¾Æ÷ñŒõ(°èžð!tïÌ@É~Ÿ9öñ3{÷9ýnRúó)P÷z™Ü¾–ýj¤¢ã¨)“åh¬ÌÔX©N)1ã V }woøxÖbyÒÀ§®Á÷S5‘ćrì(ž»ãÞd'ys‡æ”D8ßY“²‰øÝlMøRûdë{gÍ,Ãúu~ñ?ï endstream endobj 2325 0 obj << /Length 793 /Filter /FlateDecode >> stream xÚÕVÉnÛ0½û+ˆæˆÒÚ‹ö¢Iš"ÐØéE5 F¢Z\Qvã¿ïˆ¤lÉ–»§æÄ9o8Ë›¡zB]>MçW®¸#Mfˆ‚-ÛE¥Øµ4‰QhÜÄ<Ž|£Ãéäëù•M[›PìùØ“ºžWë ˆ¾”í–²Ùh›#6-…¹|aÙ<境ܷ‚Eùvmé°Lêa‡xÊÖÉÐt1®y¥„ê™+áË÷+%$ù¬PÒ¬,2%1µˆ9’Y©¯ !تÁtôÆ|Q2}Añø‹GUí:¸gR‚G§ n¼»~‡h% ø¨–ùcýKÓ3m{sVywwñà4¤ï­5mnQ@ðG'%¸’®vRïD}Ph›8ÂP:Á£Q€¢lN Šá‚ÃVà£?R5C6Pß³kB§h<ø¶—ˆ²yÀ‘Vó@Š\hǵ0µ­MóTb«)Ü  Mß²eõÀËñ ±–X+!cy2_¤¬âõ·'«Uï×%:ÔˆªS¡v’ú¾¤Z)½(ZéÎêOˆC1±c¢·{¦†¤t‰&åg.¢2™WI‘÷6öÖ‘ìC#Û ®ÓaYM:@Ré°ìn:äZ‹G`€km‡Ô€f @jJš1–Tõ²RV†¶‡UíÒȾèR>öÄR=±u8± š·ãšÉë· ÃéAùñÁTë’¥ Þ1¢lÜóœeüˆ»XQƼ”¸Ø’•¯;?æU?zÿ¥ãЉç~`KŽëH^5r¢çâØÚH³¢T‚¬ÿzÖ´»²;Z'Íüïõêá ÓÚqþµúÛ”|ž²ˆg`ç-Dñ4—íîáöVÆe1ïœ]]ÜŽ/Ï:î=?ŠÿÿÜþþ’žò﨓Ü&¥ÍsÜ:’]س_ò%/Eoúz´Ùì%ï¨fœå{ìJ—q¾ÈxÙü.í·¯…bÉm³'¸·ÕÁ‡NÒwžà¿À!Õé endstream endobj 2248 0 obj << /Type /ObjStm /N 100 /First 971 /Length 1327 /Filter /FlateDecode >> stream xÚíXÍO[G¿û¯Øc{Ù·³³³»¡H„ˆ´R#EÀ¡-âà‚› Z6²þûþfƒA}v•˜÷ü›ï}1&vÁÅZ]Ê.Æ”œFû/ޏ‘ÕdDq‘Œ¬.ÃJt¬IDÃHp9×AÉêj01’\5FȬÊöBœš€(Ùi#Š£ÀdTµ”¬Ž(š€@åbïÈQ$àÙŽRðcŠÀVpQ*0öD3L$Ù¤eÈÍÔ¤›ÅÜ2ÖÌæ¹EŒ£DPš¡¡°9mIµG¥Ü8`£²¹/\áæ˜9j£`vŽv’E zb yÀÆT@" OUÓPñ£&“[¡ZÕäVvؼ@8à†ÕL±1¨Ò²ãØÜ®T6'`5¢dNÀææ6drjn+jn#7œZ‘!–æ¶B‡4·:rsεq@G‰¦vs):*U«計(èP FY© å Ø¥`µa~À”Æ! ´…eHÉ8À–ýA4R³žƒº” ïÀ›Ô*’²K¢}‚ä¼ä…”b63B’*›¶H ,#ˆ“K›”*+t z…`•ù"-£¢µ F ¥Å+T'ÌM†QÕd üÄjÙ –u@N AAœä ÌN2 “,Cœ”Ð8 ¬H〲ÒèÌ=û 3ךñQ›â¼Uœ/jÓœ7Û‡ÚVmº…,[”Ü:ø¾ˆ¢¯²'4JŽaô^Ð1øÔ-±‰}íN){ ÔóÞ+Ö³~hì®^£öE£ú+×íOžÿ±¤kØ,éRû•4‡¼qòdþvòYyE”]žE¸,ød ” ÒrÔØ½!Áð~ú_}>ú8\Ì®¿îüJÊ>c##¬>!cɃEZè¿-ñ'WÃù9Îç;´ªTo—–T`][¤ƒ'ÛnkõTåY³†sÿa6¼ù²;K°ã€Q»)øb‹ä2N\Ô‹<ŸÃù|x·qLÝbf®ƒï§ øTt?h.ð0öEã,E‘ôDK!_¢ôEÇìµ·lÜ›<ÉžÐXçWô+ú½_4®gTJO4ãÖ”Rú‘n&ÚØNìƒÏVÛÉZìR¯Ãcë%m'Îʦ³Ä/p6mëlÏœïÄY}ÂÙògkÿµàxý’¡Az¢I³"»«šÇ•Ö¿=•à4ÐËâŸ(®ø‚âŠi‹x¯ƒ¿/?ØÛóSßžDKÅ…1Öý SôöõýŠþaÐÿr½.ˆ endstream endobj 2350 0 obj << /Length 1169 /Filter /FlateDecode >> stream xÚÕWK›H¾Ï¯@ÉaA „—o²‡Y%^e5ÊaìÝËdmhÛ¬0XMãLþýVu5ÛØf”ˬ,¹ úõÕWO\cm¸Æw¿/îÞÏBϘ:ÓÈŒÅÊð\× ÂȈ=ω‚©±ÈŒ'3N¬¾ŸEIoeLÏáµæKÆKËOLYãÚ;WßÇǽMvÅj—ÀK/¡½oßZöÄuÍy@ã–ËM•‘¼ª iÁêšpÄ}ÄOjöš9ºìÉœóF09´ipƒkØ öt2!Xs.Q+ù͸Õò_žÊw /ŠšÄßhøú×Þܳ¢áZv6{xî óëT9Ò*KVo†•®Ùž;%Ûò#ÅßT"_;9îxó¿SZÛ9Õ®à{^Ô¨ôó5^·=F@ð]ÁR¾ë½jMÔEí^€é3Â~ntbû ¤}ʽX7 šø§YétðsC ™H|<3͸L7Ÿ˜dƒbØ_‘èötxÙ#&è‹ $ËJ›(U+e;•·u3—9¯õdEã®) ’V¢Úê–ÀîÄÄÄL/À‰X†øiZ\?ÿÌtâ‡õÛš{\ʯ—ð#F¼–1"BfV˜œÉFpr'…ƽ*1‘³e¡gjEÆõ"0öXÕê*¬aÍeÕJ!/ ^ôèÃá‡~[‚so™ÌÑ1 š²ƒ)7yMÒÐõW SWqÛ« -Ñ`¹r>JËöÌÜòLíK€lÕr\ïT¦áiþÍ ÂôpDýŒX*o@Œâ'\¦.h™ŠX|†Ì®\ìE·ê2uýâ¹yÔ+Om§éZ:ÐbuŸG=ý=—›Á¤…“_ÜsQCI$àjFyy^®_À [=—#,¡B®)ÓÖU‘Å)芆IÍg)ÂÚ x~Üz>õJ\²ÎªUùÉøŠ5: =çõøÄL$o9+‡S1:7iéV¬9%‘§×¸è2– Og,*¦€Òƒ*£â„h÷tÿ£}0.)šô¾2œÕhAõ¬i¶ø¯× ½½–LÈnNë y4`Ë“q»mÝú‰m“’¶ÀÌò<ϼ˜nû½qI[»Ðó`å}wÑÿésàFB¼È¼×Y±_«Fôk[ÓÈ<+­·z´Ãççå®( C]ŒU î©3gˆ‡GÊø]…¼ytÕGûÂeƒ-OöØ;' €¨Ì£ ¿˜ß{™,EÌV®!obÓ:"È!Ë£š‚. L%x¡D‚Ö%E´jMGÀ½ÝÞ†{óšöÿ'nøZ³ÐcÙ“#pu_á?‰¬s¥!ªñ²ÆY°}^Üý⛎­ endstream endobj 2357 0 obj << /Length 997 /Filter /FlateDecode >> stream xÚµX[oÓ0~ﯰÄ©´fqî™à•@hV‰‡0Mnê­F¹”$í¶Ïñ%Yº9[Sº—ÆqŽÏå;ÇÇþj¡d¡Ï£ÓÙèø“¢ÈŒ|ÛG³k„-Ët\›¾¡ÙÅÆ—ŒÜÐj|9ûzüÉÅi×Âf: KÈ—YJ;»áI#=±˜täš³;’­R©½]Ù÷ a±ï gC4ÁéDXêz3žx–e|¦µ$4Måˆ-h^³ú^ͧ¤ª¤IP;Á–yM¨\°úmyÖjž%WUFÒÞp#kc3³]sÿaN©˜’\æT>×]ÈQ]ÈgÕXQº(ï×E©$V4a×,yp¦ÚVAä#§·rÒ Mwáè‰Ú÷òO\xy7‘UàNšbñé­ªŸncðI#¯•}äã’’÷°/a/$­Eœ¤•áݲȶÐÛt­’Ä”Šbþ‡&jmFk² 5Ù‚U™NŠ4'}äl_^vÝ©÷ûçù‡«*ϯJZ™x_àEÕ Û!?)û`›dUX¬ÒÒ䱜³º$¥RG²b«œ×OóÚì‰Rº¦±úRœ]Ù‰63ÀõÛiXê¬Ó«Í9Lÿ‡ÝõC}·_Ù÷éßû28¨ªUAžªÀÊu~¢ÛðCzÔnåT” Z uÚî¼!åx/¿O¯ðPÜ»)+DÏr±¼ ì¡_u¬²ü¦](¼Ô…!9Îàmø-Y²œòoZð»íe(þ‡¿¯jšHw<ÏÛàžxC£:Ý3*‘ç`»¤v;0{1¨IµìG¡"j>œQCãT™?ÜþéV³Úën½¤‹]¥9üô»¢!M½¬KRo]mžm˜w[å3àR šÙÀ»À0³{¬Ü*›„‹ÈëôOÑ×<¡Oÿ§vá™ÍFGX·ŒG¾é…%Ù(¾´Ð>‚ w!º¢r”.§›)ºý襉‚Ö‚ÛZ žú@]q™^ãñ­íL?ê,‹'¡ãZÆ÷5o'¶¿ŽÑ{Ø 5#b"4W$‡â‚ÿL~`ºP‘‚”Á¸ŽŽ]Û´lÅ}?Ò*)ÙªfE®¥Ò˜» Î¡é„ ‹o¬‚-ïø¡ì"ލPÄ:DS ]p\×7.V¥æ‚X®Ÿ~¾Á{‰Ò¸B󱵜àdŠ›'ZK\Bõ%½PÚð„ Fn`|éóÚ3 ¿û^U¬u²àr²±8jkZ™ç©šg9ÐGR&c;4–üÝ ƒÏ3Yeb fadFjÎðùä-«—rT/yßU‚„›¾×æJëéS‰ endstream endobj 2364 0 obj << /Length 824 /Filter /FlateDecode >> stream xÚÕVMoœ0½ó+,õP#Ç&j©šD­¢Hm6½¤9ÅÙ¥âc l²ù÷c³B¶›T•Ú 6x<~oüfŠˆ¢SëýÌ:8á E$ ÜÍn£”x<@!c$ð"4KÐÔ¾ž}:8 DÏÒ!ñ¢ü´6‹Dn”™EsðÌ{öN·ÁqCøèém—u¼ƒmOà.ìÈa‚xB˜óspT£>-o¾ËyóÆv|Jq\×ñƒž¾ÓÃùåÙ˜1MiQ9u}B#ƒî¨Z¬sYØž‹›z'Êß Ó˜ÆáéþÊá¡â#+,yž‡/亊³ÌFËNz>ž:¦ï‹.N¨à—ÏNX¾ °Îã\Ú-ŒòVj§ +úµ)õ˜¥yÚèi-ãj®L–[“=BþÕŽgëiQŒÕ: óQ¢núh9N•:ô§¨Ô;‘˜Øoâ|•Ézu pð-0%w¦}½zeÄW6zR­‹C帽J"?š–q§Teç211tx\$ʸï·ÛbϬƒ±mbó€&\4Ï­«kŠXç€T ûÖ4Gr?äÌ3ta}~’³®Ù•nˆs°-¥‰ÊD Á)>•êÒ|ÏeºXÞØ>Ãe¥¿ÄÙ¢¬Òf™«×§…í0Üy¦é1Bƒç°ÔløD-ä4 ™²žWéªIËâ%ÕA…-GÛÒž-Q•U=¢J¶6ÃE¢ÈJ˜möQíŸÔ°wmê)!d I$ÉöÙо¼uôx×%øÖÇPÕžsÙ,ËDÏoUŒÔdžAíÑ¡G¥ V_OP#)ð0±mr‹JKH7ßa0ÆL*¹Ê⹄fÒüWÔ¦¯íì›…)øª ÏmƒÀv÷j‚+ÈW`Õ&è îK&ÃX6KiÒ¹½ä6Á“úpîõ¿é®<[šž–¶%¶EÔ¡¨›²’½á~‘ͺ*j ‡ã;Û7. :­ƒ UޤɯÍÊføk±õÒ†²§êdØÕIx¯ì©ž‰ˆIæ‘'x5èxâ÷ Úç\ÿ<¨CáŒôס¡)ÎÃ[ ÷P©GÔ¶7an ™Œ*´¬ŸòËÁ” endstream endobj 2385 0 obj << /Length 850 /Filter /FlateDecode >> stream xÚµUÛNÛ@}ÏW¬ÄCm©Yv½7û¡ôµ•ZR^(ªL²8®›Ú’¿ïì%‰“¸PP${cÏÎÎ9s映 tÒ{?èË%8‘‘DƒD ÁŒK¤(Å’%h0B—Ái1ʇº¯g‡Çœ¶Â9¡XÅ ’ÙÀ˜š˜ñé? zz–Ñef©8ŽGÃiïòŠ ¼B«+`cžø:\E*8*\óK…A×®MÈ3å!´ÝgÈÈœáQì•Uã-´GÜÑMéKhÆÚ«ÒöÔêtô$9^„‰ ÒÉ~εä?så=ä! `ph0ö5ŽõÖL±3µt³NGa*Â’È×5X&fÒ7*/]ÕÐ\ü¹Ì¾¤·»( Á±Pœ~(§Ó²p¶ùÙÚ©¹dÎ=Ó‰ 2‰mÄE¨”é‡I¡Ê]\p†#)_Æ]bñîºp¦‘—l~3wª¸…SY½è³»§>=üpŒª -–ßOzŽÍ`Rª> stream xÚ½WÛnÛF}×WÈC–@Hs¹Ë›Q pë ¤µ•¾¨F±"W2SRd¹”ý}g/dH•r¬4- {/œ93;sfíYk˳îf?Íg·[‰›„~hÍWö<—ÐЊ0vC’XóÌZ Ø·Ÿæï/nÃx I¢À%=Jæ^ÜÕ’Rræý œŽ8ÝÇ`“蓜Û‰ º*D5:>P3Â[Ž]ÇZÁ‡j§`Ùñ}•¬Ö“ji;Aˆ>ñ´ï`‹R´³aƒy–·¶¡ƒS¤>ˆm2},ߨ~ŒZÞ°´Í«QÊÛç ¦1ÊÄ¥?nl5¡ž>( ÑèÜJ$¼_ÔQ\†-ÅJ¥+Z©³ÓÞ¾³v&Ü’µMþÙ ÷~±N‹o·æÁEb7 }‘YSÕßñBüÇvábA[¾ÚÔ(eú'&ƒo>³€‹ÉäHæÈŠAYHûdŽ\’`­KåoàyèGž„SðòR,ð%öž:l*†Ä0éÏ/t„vè­q%íVKq†ôÓÓ\*qáwzAÌ}/l|Ó6‡‹ÎïP™{Cx>¤6<òF Üg`7_ô *l 7«æí3kõŒ5\Oê† × à5B 7æ8„—7;¦¨d""ùFÞ(P”DZªkVÐf7óÙ_3¬R÷¤`êú^d¥ålñäY|;±µW¢¥E¡ž"J`^X³_Of¡fþaM`ÀBIÑ$tƒ(x‘ÕÃdTL¡6 b`R=VËOÜ0J[¹ŽÐÉ5+.j9‚ß¹h!v?žv˜ÆÄM|rŽÃÚ1:ÑÒh@Ý„j¿®¹H›¼î®åÜŽ3—=âPË®S@!²‹€ ´æÒ{JPÃËJ íòͺÏÕAˆ®„`‡).S*† L+]5U)gTyR)=òmiú ­4ø Õ3!t“KsÖòÌ>B¦*_»Žèü:/x¶MO³õ„ºkXý|â `Õ«'“ÄxÿsU–_¤ð?¤¾8ecù‰‘P•§>ªÚ–“þåùUèq¯6‹Âµúè~e>o:±ãXvfËž ñÊ¥ê(šlþìMš™ýµ*Å‹ZéíÊG½Vd`âø‰w':ëà_ö—©7ö¹º|˜³Lò—œsí±Yå+3¶GÕäë|ÊÞSå0å’Š’E/—h^ÑT? ¶æ¯ï¨§‹µã0™·’”TâKnv]wÔ €kL~cZÁ5_±maØý‘èQ=³Ë)wÏ2udk¬^ÏWUc:Yaî;á0å×·SåpT~ãc“G¾Á™¯]âU³Þ–HÄGíËÏ£¯\¢ðâ3ס<ê¯TŽxëøÔ±ÏAßÀ³—M„¾4aœ’•gR»†ëÑUNP[PŽžÿxMØ~³ÉË[~ª9½ªùÃÇ›ÌGt1`M]œ‚ޤ„qiÀ6Ñ€m"ÔÜÛ炟àb‚n¯><ÞüßïçaÖÖË2ýC”ÐàÎzvÖ);ëÑÙ?ÚŽ¡Â›æozMÅí endstream endobj 2412 0 obj << /Length 791 /Filter /FlateDecode >> stream xÚ½VKsÚ0¾ó+4É¡òLq$K~¥ÓmI§™$3 ¤=Ð< À?¨e é¯ïÊ&¤™´ÃaWÖ¾¾ÝÕ.ÍAŸ;†“3/@¡zއ†SD ±÷O©í± 'h„¿È˨,âu?]”–à{ëvx~rÆé–"'Ôöf+•€)™1ŽúÃÎÏ– Zûð|fûÌCã´3º%h—ç®Â­*ÑqÃçÊj‚¯µ½]Záþ6Jl"ô\Ϧ{ ä¾ ¤!ÜÒuyÀ þ8–KñøÎê27ÀñTÓH§•-s%5µåvÈœÛÄáYCã-5ò¢Ï¨†öIÈq/Ê8ÏÀ6ÊEÔ¥¡ÍO«­€áèNUW((ŒU(Ô(ÇQ61wòÎHU9«¸|c¾ˆºKªãâ—sQè3[}ÈÍGº¦šY¤ñ¥?ü²\GÉRãîªv©éÃíät2'„,›šßÈh&ZSÒ’"OŠÍ£P­7!€v×avHM-Ž­®KÔd-“RLÓT”ó|rºÑƒj‡®{ÈÃ!½b¶LEf1—r/Ø ×;¯¢Ñ4£®ï8>î5c_t\ýf…¦†/èÌïsñÐ<º_8ÎòÒ8öñ)™uËtÒ7q£CýzŽíMí@¨Öƒ×ÑKdþDjág¨˜¡ {}0ÑU/ëÖÆàJUþ¹…ﯣt‘ùüÀ˜Ç뛇Ot_&VŠéB©¶;¦Oè>¥«u6H^ FOÙ¶fû8u8$›9ÿvƒ8ð´È•‰ø*JÅä"–åþýá¶ìJ«â”¹uT•^gMP?´aվʚ@c5Ûø¸Ì5•ê(&¶(žj6Ò$©0+nIÍdä¤Úï Äá +S«‡ÙæÅÃ"›æÅØx*瑱%É®Ýêsa$…0ÁÞFAm1Å,³ø§Jÿq‰ÔýS ø·z)ÛDSßk2¼¾é?Hä+[ÿ½Ø9ë] 62‹HJû·(òÇõ;Úúïc¾i, endstream endobj 2426 0 obj << /Length 846 /Filter /FlateDecode >> stream xÚÅVKSÛ0¾çWøhÏÔ²üŽÞÏFG1Š70fK;"^`„£€ÄÆlaÌÍȳ.ggG“ jÝœÛÏ7Ïhb¹‘y=­Kj¹¡¹=¥5µ“ÌÂ&­*.8r”:ÐåµÃvCø"RËIyÕälm׬»rû+à„mÎaäFžºÛWŠ;´CXžX6!ÄÌÒªÞ¿v)â9¾+‘i–¡fÞ4lX…‚Š vÓ¤%“Šê­ùÎãòhMsVÉ-Õ׸Ø/Ë"—"ÅZÑuQ¯Xyc²c\lË7õý3”…Wà6æVªãb<¤÷òó§ã;2:çæ:YÑRÞ9–‹¾×ÑÁ°´HÚ~¸H%ô›•Ű„ñ•[ÀSOùN2âÂvÆÖWõê!ô•¢ÙÎJ›§ñö"©û‡àǽ˜˜‹³‹ïã>_ éRrDðVz§óoÓŠõ¹ZˆMNΧãAæ¡T>¾£ù&cécH`·3ÄC”>UŸ!f‹sðσL­<¤"¬ BÍA±?+¶úŽÓ «ø<– ÷Ù 15 «Vò ^´CB#þêœjü¤sú÷´ýG|õ§]0ž Jô ´×¡ô|°¶óu…o_ONg£›^Žw“øahI>š_:Æ~uDâÈØŠ«¹áAS =ûÌ˜Ž¾=ùe[î”p@„ù¡êFÐyE×Õ÷q» âNñÀ‘\ñfâGZÜò¡Q yüa‡Óo¦ë"ââ—˜)Íñz¦ 7Â(±4ç”UI™nêJö•UÚ•j’»Ä²±)†’ÈÔöñ¢«znS±…¬¸u!Oªºxh×jS²ªÉjÝK–ª ï)Ò“µõ%¼â?ˆFì· endstream endobj 2437 0 obj << /Length 1070 /Filter /FlateDecode >> stream xÚÕXÛŽÛ6}÷WÉ¥€ˆ!%êV .v7­±MÒØÛ—Ý<Ð2-«ÑÅ•äµû÷!EjWR%_ZE ¢Er4gæÌ™Áb ÞM~^LÞÞº>PàZ.X¬ÁÙÔ!ȵ°X8c¡aùð˼*˜aypÍ*f¦Ü °Úä†)öV¥ñy1{{KIËØƒi®ãAß‘›¬¿z³˜ü5!b‰yþ ëQD Âtòðƒ•Øœ±ø`_M>yÔëÌ'¿?Ûë?kTÔk£"¹Â5á Âþ3¨PF Q žíÿ}ŠáÌ0 lVHÝ ƒÔ8“F ‡èhŒ¥.òü‹€*@t M.qդ隗ao«8Ï:8šg/;Ä& ¦ê¶r^çÒ´m®óBÛÿŠ4ËOïú!~¨¯Ìúqû¸N•Z<Ú MP?øa[È6'[º(±ŠÅ*ÏaRêÀYò·:˜²ªž6q©7™%ÑLMÛ¤R.wÝS®eo€±ý¦LòêÅësœÓdÒ’2îž+Ýû5ÊòB4¨3úÎF šT²ãcúH¯¹dö2UÎ%Äá(QãAÒ­‹< î¡ v¾^kÄ!kÒÃŧû›Ñ ÅkMÈtµqÕÚͧº«‹€i®m˜¤á“üO“nY/œëÁ@Ü Á«f`¨…}\òQ˜·Ó»ùÍT©dÇbþ±ÓˆÈ3Ä”»4e…®˜*¿tˆ*«U¾«NOO,{™…d,â2^6uª*Pr9Š÷ýýÝÝ9’|+¹ºËB9Xž’d×iY²ÄÒñº²üh|¬ðT[ê,ònµ’tÞUj•Ócžn^ÄuÌôL;XW£¬daÈKM¼ÆµsžåK³æš|Oºs@ú;q5›;-Žž×£Ò1•,j!]I÷_Ô¡^±ÿ¨ÀãÍ­ƒÿpÝêlÊø–騉#Þ´Hþì |£†,±‰Ü9yª’!BŒKÛ7aI3¹]Pu~x’È‹§˜ïµâ®¿-gZOø ”“ endstream endobj 2345 0 obj << /Type /ObjStm /N 100 /First 969 /Length 1629 /Filter /FlateDecode >> stream xÚÍYËn[7Ýë+¸l7‡9€ º$@agÑÖÈB±ÕĈ#²’&ß3”íH‘USŠta‹—÷ g8oòÆÄɳcÁoLN£=«‹Ôâ7Dq\0›29i¯rt’‹ ’+!¦ºÂ:ÀŒ¸Š¿R°\fƒT§Ú¨ÕQàì–  „) Ž(µ…2FÕV’ä(aÍR؇ÃKfÁê"51¥8ÊT*F Rp¨à˜”Œ©%Ú"…0#(à_É $ÕlÂ3 ,@FšVQm,À1°QTl‰¤ÑâE¬r‚“Á*ôÈÀ¦µåPm ó¹é¡â1«©¨‚¡°I§ÀIÓ„ý+Øv Š‚í¤ªM8ÛpmÛQpV[=)Þª´9¨4-bT!°€Ô‰lõTªK©1ƒ a¦† j6-âi‚Bl¶qÚa5&Û‡€‘íÂìÁ1„AŠs#‘a5N©À©š®8dÇœ‚°0—F‡Ê±Q`•,Æ_ñVÈ(°.‰x ª¹tÍj{'Ø3‡d{Š4°d¦Æä™Ê Œ\!Gã`&ÊiÁ¡b$H]6Á"6…ü:%°Ü¦3¬”³6€Ij`QØ„Ãj•ɦÀ¡6'€v²¦0`VÓp€M$ Ê,¨$ÀW£éEˆÌ’…–Ø"ؘDs¨#lsâÄ‚sÉ ›OBÑN„Ãàèh0|æÎ¢ùKp'nøÇŸ!¾‚·Î)yÈë&¯®^ =úo4×ê+œp}<ÌÝÑ‘C‹ØÀ‚ìÎpÚ›(ê¹y€ô†¨S¨{ñ€=WØÙ°øð÷ÙôütÁ¨Ìì5Gô„¼ó0 p›ROÝðçéË©ƒQ~8ù{âÇóó·ÏFóѦ¢½ˆÂ¹xó"ÍÞ22R¹gh Êð…óFIÞG“e!š× 8ÜyjsšÙgd£u[ß9$~)õ¢c„ŒÄ›rÅW½s£.¹êî>XÖ}¬Ï¥ ¼²õ,[hu|«'mÞÖ‡&…VëÐ9yE þ?§áuóIÜÝ|’¶0ß2øaóÝ‹F AÍèCŸk7:#K…Ô‰fÁo¥Ã ùÒ/É!ÑT=:ƒN4ÚG¤×ðˆ!¯Ü«öÖhmŸ 7ÆÖR8­ÚαUózlÕ´]l-—ç²×ªŒ&Þ‡`sðjXξ¨ÕBòE6–ÂçÓ7/FÖŠaå-â¾ÞÓo‰9KN‡A'ñJ½`DD…úйÑN4›jr¯J8ô½kã(çkȇAÃ”Ò Æ‰Í×^mÇý‘t¢‰£GÆÚ¡¢n ô•|°R^q¼Ò@ß—´®§•ïHõ¦C/z3¨áv@·ƒ¸Ï4fÎØŠDoNñpx<—䉷Éß)ÒT”r' bZè“ß\Œ®ßúO£«Ë‹Ëù—=( zøúU=Ö5TXà!±F×þýh>»ü¼wEH‚Î(xv-Éãt.h8jÝ|À¹˜M?\?¯®÷.ODÏL# *ãXèjôú~aZnвEµY?ÜeÞ‹Nࡹ‰½Ý£ͨ{åÞº·´Xáë•$U;2k':"LÊ··)›Ñ|¦^Ir£yÜg+¸ïcS\«v}¶k°ÛÀ}^Ð,RFÊÕ{*ìí&: ¹òÆýéý‡ù—-‹}¡vqÙ¡+à¯Ï)ÐΔnIbôR¥My¥t¢¹*Ú°Ø‹f¡'u¢“Fo—çhƪ['v…îËŸ{@“’·/hF¡%=PK¸sÀGYøÈ;ß«Ø {<-ƒ¬x÷¢sM>p7:$ŽNpB‡d_Ï‚&s4íD#”¼FéE§êYónvv´´~ÿÊ©óþ•o?,U–¸¸lißTn¼×ZƒLµ}B?ß¾€yûÞ Ö©æ²±Øü6:w:ŸþÙïp¼‰í úøh úw”;n(m)οÃwí endstream endobj 2453 0 obj << /Length 817 /Filter /FlateDecode >> stream xÚÅVßOÛ0~ï_a‰‡9ÒbìØ±i{`b UÒ”°—ÂChC)¤ KÂ*þûíôGÚ´¥l/õ¥öù¾ïüù|ME—½oqïôB0’PzÅ÷ˆQJ¸H1F$QfM?Òkz´Ùù{ÜûÕÓ“±å¦Rù$ÐhÖÞR4†¹>‚™0@s³r†„U‚ƒ¡¨÷c¹Ýæh«uàŒ T¤À— ¨bš’×´¬Zà€I¸æ:t%GŽËðs6­—û 'ùXÙÄZÇgØng¾cG)\è?'iý–&H7s!‰ò¢n)ŠŽ³‘, ž×œÍyZÊés=-òÇ×öùÈwÇ`Ü£†0ç a.4a‡áÜ~ Ç ð«þ±¼aeì+Î8]ă£fž r]%“´]ZµíêÄ|—6Â> Cõ.m„e¾ÞDT‹úÉHùST—FÍZò…Dؘÿ®‹ˆŽèö,6_\;þ^\¤¥ÿG¿¼X“ÔùyR'ýoÓ«²¢#-[Iþ…óê endstream endobj 2472 0 obj << /Length 856 /Filter /FlateDecode >> stream xÚÍV[OÛ0~﯈ÄC‰˜8vnÓöÀÆ@êÒhÙKáÁ¤.š¦‹SªþûÛiIÚ´Ð Ø”;ö9>ßw.öq­;˵ÎZ_{­£Ó ²b^`õ†q]LY`…„à€ÆVo`õѱ°oz£SF*¢Ì%8Œ(¤…¢PÉ´Üòh+¨–v¼©Ñ98°ßuQ—š1Ó1OD*&…YHEqŸ Ì|˜åf’Œ¹”PXÔ×»íjÕzuxòØ-r>?áoÒmÔs-üû¾Ûé^»¾›Ý>ˆ¤84Xä8[N1ưMÌÏgÇŒO|<êdu–GqLš™¿Ñ“Qz)³ä9šÙ3\\Ÿ¯‘®2$ÜĹ9Ð`ŠUŸDà–3cÇùÝ |`S²V2ëãhu‰°Fæ ƒw½èê>c¡¢ã‰íPJA ¨IkÝ9&¬t°Ým#ð”’•)V`Ž¡)R Œé"+!÷"7S}Û…ÜÎÊÏÛù ¼£‹Þ†ÿ¹±:š@¦¥¼e“=ŒêlØmS9ú‚§ÂŸ3” Õè—i¤V”Ô(‹,f³1RµN²®õOÊÍû,/Ĥºë£¶° J§£|”ðqûPcà8òÊ> stream xÚÍU]oÚ0}çWDôaŽ´¤IœÏi{`Z[i“öPÐ^ªL0…‘„:þýl_H3Xé¶';ޝÏ9÷\_[Ú£fiwƒÎõ­kk‘ùޝ ¦šmY&v}-°mÓÇ‘6˜hC†úhðùúÖ+;qäšØÆü¹ç ÝŠMKÍÏ *» ør»á|CÐÕ•nx–…úÆ5]%$¦)]æ°Ò|–M`>ÍÖ0‰Â0 ªÜ‡òïøSC¢cdë55XšÁy^)î»åYÙøó·ÀÂ4M¾fÃÇ{Æ I *Î'8ØŒìf¡ÓõižÞÓI¿†²ª ûoöšÂþ­e}Z¬I~¶.ÿ<ÃþO{sX› íV›‡rU¡éºÄ÷Ö¯9;(gµ¶s8ðÙ‘é„ê pظêIp'@½¥n`Œy'룦¨C½¾YÊ.­Ãw†Rå„B‡sÑŠ;C'gŠB>£k˜J;už4a§ÐQªË’ž'‰ž.q6ºç¡]ÐïÌù¦G>:B8ÑõŒòAïtÃu]Ä¥Cb¤ø ).tN¸ nñBÔ^€%I©n£ |m„)+S‰Ï¦5TV_eÅØ¨ ;‰ïGͬ®Ÿ$º¯Ý#÷å§y>:DÕn±‚R!ù®¤RÖöWo~’t•ÐöÛV39ä‡ùnirÈMV=L5¥;ª APŒò‘†éXÉqˆ‡î eϤ †ò•> stream xÚ­WÝs›8÷_Á¤3JB|¥s¹¹¤ÓNo:mܾ$} €]nÀ¤ˆø.ÿýiµ€Á–»Íð€´»úiûµ–µÞÍþœÏÞ\‘»qÀk¾°¥®'+dÌ ¼ØšgÖ-)“{ÛáÉKé~¬—'ö÷ù‡7ׂ$enyJ¯–‰bØ3£¥«ùì猩!µØ`$¹ë…±•V³ÛïÔÊÔâK-Å‘õ¯ÞZYB# µ´nfŸ}ÛoD„c$Œº:aà ×cÞ€d bP î!Iß:"”\Û#Å*³Ïɧ{™7ë¤-ê•„™ˆÜ?áû›†$)s­Ó Vp—3q X% î ¨ï,@På2mŠ8ÖÒÚÄQ,²®ÔðÅßgùÊVÞm‹ ñiä0ðH­Û~@Ðz9iq=­Q2)V8‘àK> _ÒâŽz"ÅI¥ÇÇ;ÒŸ<³zÜÈj–V?üòn¦Ü[ÊzY¤I‰û«ÇMnÈxsï\þU&ËÜx/†{ ÜÓ«W¶ãSJn<|Wyû£Îp¼¨¤e"%FGÈ&|‚Õ×]ÜŒÍÜ’qHM…ŒTadnìûcJßQŸÂ^½Ï›î¨ïÿÉÓö\/÷ÂuÖà9]ê¤d^*)DõG¬œ-ŠF¶gç8u¦ðn>ÒºªêÕð™”å™afýEõPjÊ,Ì¿|½2îv]WO;|`¢»§ƒL¸l–•âºÇI+2â&à…n³pênò\àö6 4¹‰iK3„`­²Š&Ó1¶©¹”O¼}Ô¹»ˆUã<µißÚðbÌjEkÄ´PㄼΘ£âˆ§£åˆSO‰øü©?Mu©HKŸ:hurÊÞv9 2X7WË.9-šººØ®þÈd¤ò¯?½Ý;ÎèáSÃï(§¦,àDÊ*D–¡´Å9»°!üMr†{†ý¦‹ÆÉaëvêüðØ;ªXB n¿PHGãÔ›©8ùUûw±²—‹Iñ\?bCõP· ÊIUËÖéèÕ­ŠŒ»Ù‘Ÿá°Ã»Ã[‹ÕÛ¡LðiØòa¯„7#YÞæMU¬ò çï!bžp¬MÃ`Ç7 ‰,:¹‘4$z8EçíÅV7‚°û„ã‘&ÿ©Æ­:Öw:=Ò—ä¯*lÏѶìí¡k¢;ÀÆ”);9“cÈFCy=\K oÞ •xO F#RÇV[¬–x¶²èÝÔ§ýdR3Ú“R|WÝ÷Ÿ3àJëûåªnÐÛ{K½@…ßì8Øôã'–w쨌VÎ |õQx¡¾Õëˆ@Õŧֶî{Ûþ»X9ä3â¡Ý‚æEÀ“,¨…>ÉxÀs4 ±oÍBÐ5޽ ‚ZÀÜ";<í–Ÿ^7ÆHÐóiAšÖM6¥§Ç¾ZT›/Hý ÿsÝMÚT`^–²þ• ýç\ÿaèî²Ýe©ÙáBô÷XdE D²#Aô’W b¦º¼IºÆC+Ý4ò⤶0Ši Éù)J *uÖˆæé…µ'Ò­’¶)þ3ýlcÓNGû/[Û"eÖÔe¾Þó“ÿ‚vo;â+7KÅ#¬ípòj>ûTzF/ endstream endobj 2512 0 obj << /Length 746 /Filter /FlateDecode >> stream xÚÕUÏo›0¾óWXÚa ׯØÀ´:µ™4¥“¢¦'–ƒCœ4 “nùïgc§ƒ”VÉÖjÝ=c¿_Ÿß{ŸX>9'ÎÙ0Ä ˜,F’cÈH&sº ò¦“ÏgC·4 c±PùitFÜ bwç‘+<ìV¼æÚÊA6– ¶Ìý½½Dj“/—?ùºÌ…ìX>&•ÇÄÊXyÑ©ÇÀǤ46¾Ö¼ô|ŠûÞ7rT,¯xùQ”‹º•Lñ;Œ¦jëxʧLhroŸ¦x„[qR÷­ÙíDOÝb&OОN»Ée:/<0?ÄÊè¹r›ºÚýmvÁ>++1j§`˜`{õoŒÂpµ™›•ºQÝñzUl¤ÙY•Yp#¤¨­êÂÈ;žoM#‚ÏùLäRg¤®aÐJð€üÝAŸnµ_ö‚¾—'øÖÕÙWȹœ8߬®|?å”Å0¢dk'"0W‡ê¶!Ibð£Q]ƒPAµÎÁµ3~t •Dm*Q5cŠ\(ÕTïib'ú¸%-ËÔgqˆÜ±çcw+Tãú„F.×ÍDhì^ñÍªÜæ¼æÿ\J¾3Ë‘GW‡O€& Tß)  ¸°‡')R{pBfÕªÔ]ÞK`‡\« +V„EùØb%Äb%a«:ÐX Ñ6¿mÖ­,ýtiV $ÌÏäKq<½ödTRO^1û&²ÚÎb®OìBØ! ¢Hÿ‰ƒ5ÜÐñÙr)øëK•eªkbäZÔ·Åü€¡²œËßÔÞnÓNlOöØôêk‚SôIYÏÍ4Y'Íi”l·ìî ²uÔÜŸÉýƒ_nF£^ÕLä¹9†Rð*»í¶Ïù?Qú,Õ|0£ì¿˜Ñ—Ýž®/½¯ƒzJ [ñf endstream endobj 2529 0 obj << /Length 1278 /Filter /FlateDecode >> stream xÚÕWKoã6¾çWØCe Vô~¤íÁE6 Aï^œ=p-:vW–Qnšß!g$‹¶dËm·Ea’H9ß7OÚÆ‹a®~™_Ý܇±‘XIè†Æ|e8¶my~hDŽc…^bÌSca>°‰›o72ùÄ1«;V³É—ù¯7÷¾Ó‘õmÇŠbvVR‰#×\Ùt,Ž:‹§^äY±kLÝÆ<YQO¦m›?ã#åeÅ—¬æé³Øðw®å¦°áL‚å,ËRÃÓDí¥ÍI¡FÆõ¬ÄÁáwïð„'Ÿ/3¶ä[ž“[^¯‹ßWE…/ËŒ У.ô…šýHéâ\˜3!Ø[Ð'Ô+Ð@ î߸"\P|ý/ëkÔ%“3ô¾â¬ÞU\hä=~zx ù%ϲÁI`O‘¤>~šâów–íøÞþkš‚Mâˆ#ÁYµ\ëÀg°»¿7È'¾«Xý·@ûÂ}™dvhrTÈ òõoÇÒwåo ]#cåàG—Ë(Rð`¿›å ¬ÀŽðèYõ²¿˜x®Y ­>> ÈœØòâ7BÍ+ŒÎŸAÅšå“©çy ʆfŸÔ!UeûDÖÉSNyd[Nç¬ð™1Y/ßd唡)‡êŸ+^/åäš$hZðQš…ZÍÖ+”z5|ƒÀ7ã›%Ø’§ºFE½n”T>:™‚@*. ªsDñW:Zêô*i(¦ét›"gN¦²ÃÐ4üªT"ŽYš6¡b{Öã–õñl¶ô¸­Y˜×}1¨ŽÃºzÚ Nh~žÄž ŽWTBw’æØ*ÐHÌÔ1 õ&_f»”_`•Ïõå‘­›AFÅâ®Mó_. ‰RĈ¨CýKV×¼ÊÑD)Õ&ÒBë›Em¤äNDäɛͻÈÛ`»=P& :ÊÄß?Ï®cŸqSÈh϶k÷ìø8ëu²à;Q‹³ÜeäάyÑ’‚8¥º$Þƒ¼éücjC¾¾XqH ÈxÊWl—Aó_ã·g²’ˆ¦œt FKàgÅF%WâëÇW€ÙeŒ¼†ÿ>-}Ä17 j‘kG( ðÂ5«)Ó±ݰqµž”ŽxêÓõ±&™0q¦2©¼ãÛMãËuUFÔb¥ârͽzÊ„Ia‚˜0…‚DVfÇÜÞž‚…V"oeݹŸ=<½?o­YYfÐ"xI`²½>B³®X.JRgSC–ͪ”^ IlËš–4˜Ò,åH•"q¤5 tVÏ}ÏÞPz»’®°Ÿu¨˜0U¿é%Fã÷ !¥tåtƒF“NÌb¢8CšªÌß·¾o|9 Ã—S”å¤K reC"EI жù®oŠo›øEŽKXí3âH:pƒùÇO#|èN!€°+PÖÑ©ä# ÕG¯Sɉ¢"AäÏ;âÏÛóçchúäzGÉðœ3$WO ØAÿ•NRJôã.’ª¨¬ç¾‹ò!ü‹­Þl¦›—üd>iÑמ@èµ€#{ùö^Ö[ŸnÁD¾¿/E§Õ`³ÖöòGÄc†ІD÷· êˆüÄëèÁ~Íûö“`öûõè⛯›z=¨KÛi÷ÂÛ«ˆˆ|Xß–¿§¬¶e/npJÓº­N%[*IJŒÓ¥¥éƒUì¹6Ï÷ó«?’ê'Ó endstream endobj 2449 0 obj << /Type /ObjStm /N 100 /First 969 /Length 1488 /Filter /FlateDecode >> stream xÚíY[oSG~÷¯ØÇöeÏÎÌÎ^¤ ˆÒ‹@ŠÚRÜÄ¥©Ù ÿ¾ß¬cpb,ŽƒTŠ)sö|³3gî»æ(Ñ—su$Éq”⨓s¶…ê8 ˆœP5¯“Á.!.ªÁ¥A Ôilàä´6pv)XÔ¥b`eW²Kp•Š-DW“@6tÁ¸UA©±krD°5ŶpTM7…úlšÆ@ãH„Oè 9$Ù¨ÈÆ1ScˆŽ”„i2 ÂRh–´q@XªM)lœ£qdP¥™[Q-ƒO¤f83e6ÊlÙ¾0Ë)ŸÃBÁ–Œ²ÇØT Á°±1˜À þ+±Fã0ZŒ£œÄ8 „¥Æ%8sÄW˜rnjQR“54Žê$°QÖ"6\ePÙÜû ¾c¡†@œq'ê€ál¸«í '‹–¦nr’Ù¬R³“’Ú.à¨-`ÂH]‚‹Œ­@‘C ¬ÇH°t„fp— …?ª¡ÔÁâjTeû*œË$£ÀPàjPPjÛÛÕ& a l†qJæ%PÌaPFÊp¹ T, •Œ2§XdÀêm ‘láL MÕl…µìT¥á°‰6Ï G4™Á­)# ”!>S[cPMuÄ¡.TgH+ÚÖ ­Àjؼy…µâRHJ.‘ù\%¸$bkð$¹ Ý‹wW#×='óAwzýǼ=?»¿tO&ÓóÑôe@²‡WÝÝOÝÓ—ÔÝÉèlî^2W_îðdI’È3| ¾Rî±;8pÝ©ë~˜¼˜¸îÐ}wòçØÏæç“ëù÷îÑ£þLCla•àN\÷˯¿¹Z½ÀrKrãëËËWÁHý†N9ú¤„–Œo’ÿš³'¤Q?4ÂË[ìöC#+½ÕÚ~hT/ÒÍøJÔ¬»è£ÉxÞ"ê(Yˆó‚íMB+-`uùÁXjZ¾AÒÔpû€Je-䆃ºdÔO'g§#¸ëŽ\÷bt3wï•XäÌñðõhÐ=…B£ñ|f5¾ñ[jÌ&×Ó³ÑlQ÷ÛÚóÑùÅðÉ䯵lJÄ.WFz§à^Tn®Ey‹lXˆïäºÁƒ ¥øšèШ&¥ïW¢ úÚ†ˆ•žhIì‹”¾è ¾ úfã3ׯ­¨lxÑMâó}ô‡ q§(Ü-[Wˆ‹Bæõ¢ÃvEaÑžg܆FÓçžØ]û7¦S_!3ŠGŽ¢æâ?Æ T>rÝØ¿ž½9O‡ÿçõ6ži‹Âµ ^MiÉú¡1ÌyLü}Ñ|®ùAÐ’Ä×Z¿¡¿´ZÄ–¾èP½ÞoB[+wF’;¥h¥Hí\ŠjX/E¥ì>Ÿ”ºEš¯‚ß§9!¹2÷DGL¨=Ñ‹ÏT?³7lrÈ®>Ð×| wo˜ëMŸv€¾%ò’(Kbažvx¾%hŸMD2Úp´“){Áa 2ª·ØŽxŠicy6yý|xµÚ=>ó0‡PvRñ?åv€vœÇzÕüÅô€ <Ù…o—ÐÂn„|¬ôå´¨H»ŠjZDŒaµ]ØõÑŸœgù·ÃË‹ó‹ù»ý)eÓ7•¥iTɗŸTj8óçÓ‹›½‰ìDj÷…(v;pœeµBϲQŸóéäêrôvt9Û SñÁL²Ô…5çô).P`¦3ìð…¬DêíÙ¶W­¾þp:do·l‚†4SO´&õ…{‚­iH‘žh†•÷Eò¼RúÏ\P(­ŸEìÎp×À.Hû}djJ¨ÔI¨'ZSñ»ÇÚˆê7ðÿÌè;šz¢cFëÙa’\MæÍcåF{庞ٜûe¶ý4qo¬´_ ö8 2ìÍ ƒÓl¿Ù¡ºÝ³5»]m:z}}9œþbÝ\MG³ÙÅd¼ÖÚ¸lQ…VÁïŒÙ¨”•pø°‘ endstream endobj 2538 0 obj << /Length 872 /Filter /FlateDecode >> stream xÚÍW[o›0~ϯ°Ú‡V\›[µiê´´RUM[“î%‹& NÂi÷ógc @ÈUÕÔ‡È6¶Ïù¾su˜nŸÇƒËŠS7Áx0BPXC“8`색âèêt|wycÚ“ÄÒ¡ .§8s»~°œgâä•ò‡ãÁŸæSp-Ú´lH-xÑ`2EÀç›w€o96x)ŽF€rí%|‚Ñà{-¯;JüV?FÐäŒLCj˜;°q:NãâD³EÊ-ËU¶â.}9ÉäK™©V˜j芛¯RÕ‹âD‹ECE?mê@.æÚ’íq©èض¤÷…e^$y/[ ×LÛ.¶†mHªë’2!%eBKÊüËŒ ªL.†;°4!S7 n)ó1sç¬L8k¸Êu?‘â§ßÌË/TÍ@HòoXèàr4a|à•bñA“ã³®X”ós¹?"rŒX¾ˆ}9ŸÅ©œx¡›•ö°p+˜Äî»ÒRM~Ü[AôÀü•×w­÷ ÇÅãÂéó½$ÅŠ• ?Êáæú~4Ük³.Û”%¡ë±ˆ-ó·Bß8‰þøáqø¦Ü?b«ÔÍ_Ýù©°iQšìÏÏ=;%<¶æ·.q\§ó•èJžíÌó=ù-It 3m“Zº¥\/eŠŸ8XSé»Õµå€J5œÚn¦.t”¬t[°*JaÂ=Ì|©:Kù‚¥rZ„…ªñ ~vœ:ê¶2 Õ&Jo nr}ÿåë@Ø €ßVaXêZ”’TôA®Ù0”* ¶öŠOGàZ‡ð~\_ݨÔÏäØHá·Ê4IM`¶ÝŽ"¡hj?TÇT6 Šy'Oa¾ÿU°ÙÅÿÅühä endstream endobj 2550 0 obj << /Length 971 /Filter /FlateDecode >> stream xÚåWKÛ6¾ûWÈ¡4°VD=H íe‹6EÓm€"ÎIÙƒ*Ó²¶Ö#”¼›üûÎpè—VZ8@àèÅ| ?~óqÆyNáxÎo³Ÿ—³×oDì$n"|á,×÷<7…#9wE8Ë•“²»¦ø3kç÷Ë·¯ß„üÄ:ô¸+ã°Œ] Í̳è¿.gŸfºžÃÀBnœp'¯fé½ç¬`ñ­KIì<ÓÊ ál"êÖy?ûë€7l ûPž²çž+€¡ˆ„øÏØv‚ÓÉɶt¡Çnç‹ ŠÙÝ<â¬ÁŸ¢Ì±É¶´°G÷+ ]?ø·ˆ~8"¾Ë€‡DÿÕåºlû²©Ï|8úrv%…žÏº²j·Šú9ù1ë³²V§¶n´µë]Ö ª¬maÐѨYSû8"d§ìü®;lØ6 ªE»{]æªsç "þ¡Tkwô:Ë‘Á?t8ƒ_àËÜN¢ˆˆ?mJc´A#98U²^äé ž:èsœY¦-·ZuŠÜ¤‰²&‹lów§4a£À'ày³ÝUµÁvmä˳BL'FjÑç‹H°•÷9ÏjêÀ °PcžçZe½ZAÌÅ’=•ýfôø Þl#4ØpÙ§Ò%j‡Û ß“0ƒ’) ±P]pºdi:ê8žÕ๾Ó²Õ Î=D œA0­*sãs$º¢Éiа˜¦?-ìâiž-0Iü²Ñfɇ.+Ôhvd›œÎ¶ã…|Ùß:ãnÂ9™¼z1áyì}Hm¥úM³¢¾ICìteQgýN+"/ÏF‹Æ|¶çßä› R¬Wú¦*;“ž#0£ƒPüœ¦å Qz°­ëº÷÷gŽ]Ï/ëÍU¼º¢[ï>ÜÝ}ǛҪÝf¹ªTÝ_1$3ßÜeÓ…Ä7í#>—Üìw’¡¬{U\_„ÿ”˜ÿï(¨w<Ðù•D˜z-Ú­.€N= Të^|_~ ¿ jîA¡ }xÆoé§šlÿ‡S!¾òPäPa†BH×ãÒ qÑ‘Så å22å\dʹK(ÅD©üV*¬Â±Ýªº€ÂÇØð»¦'=ÛgØÇP¸‡ X¾kz:h×Q¡v¡Š/£ Dÿ½¨}®å|ˆçiäȪë'ÑP]?¦²Ä¥’>̱™ “dÇ1ÊNóÇÏ÷ µZå^(~j˜µ¢|GQg=qCf×hùŽ7ëMÞ,bÿ;϶Já&±þ/dŸ×Ñ4gÈÒ"y‚ýõdD…ƒ°>ùäÿñ}Õ endstream endobj 2570 0 obj << /Length 1039 /Filter /FlateDecode >> stream xÚÕVKoã6¾çWè¡iE½•¶‡´M-²{H½½¨906m«Eƒbl§¿¾3$•JŽäQlð#zß¼8+'pÞ_|?»xwS§ð‹4LÙÒ¡AàGqêd”úiT8³…S’"vf?¿»Móg”%~AcУyîÄêÛ"ßE`µƒê¸'àu^˜Áedä~u‹”°ú‰D{*²>º„`š=r£$W®‡”\»^˜§¤á{ËÕWWzQœP¢EÅ£ë% ùϕѵ¯ÔÚPp) 5õÓ¦iÍk£ÆÂ<#5oVjý[׋¢ˆ|gŽ\ÑI `&Ìɾý˜ƒ°ûl؆w&%wµþ–+ÔÁó ƒEb¥Ä¸ûhù…?÷ƒ.°e9T©–ãÚòœT£>D”’  âÉðÈÜ 3²f.%Òõàv”âÒðìÐ?¸—x‘µææŸ¡ëx£ÖLY͒ݶÝb8_Xž ÷w0Á@Óœ°+÷UË;Sc(úáNMøÄx€b÷·ÞTÀÓ4#?ëKÂìºÞyô8N0è£@௟îîFmBÈã8Fg›IáÄÅXw‡xR®fÓÃ[ñØb–9¦{çB;1U ìäZ 9a(žNOû’žËqù,ú PcŸ™ÃΈãÖ1­mºt )þ7QùQL$Ÿ ¹¨š•QÂ&UÌî?ÝLh1¶µ:V×FÒŒÎÖ|oeãRí¥Ì}ÕLZìWÏ`V㤨Ÿ„vüR ÕŽŽè7ŽjÿG¦Øñzz‰)½6k±ªæÌú¹aJVãü¾Â9±¶‘°Öœµ– 7¶hFöoò£L‘ëºSkˆž^Cm ÃÇzq¤zq´ÐS!ÔœÍXµ¨¢{vó˜è¿½4´d f ŒB6DZJ9t•i‹öÊB„ŸŸ;òþUp&vÁy;cøùdÈå9ÚÑ'Öú&AþÈâ®›ZnçX;jË…ÛšïxÝ~a»¶»ÈH ©üG¬Õì‘c/¿Õ¹“å}s`ÕéîtqÊÒ¸«tZ@¥[]_™ÁûƒäLqC3sü…Sg*€LYÝÈ;®ÇŠ.Ô\aXKzEƒ‡ÎŸ1y{B¤>”÷ðàÑ„Þ5HØ·^Ksîì”DúkÈyYâž|xû[ ó@O6Ú!:š €^/6`ìD.wÌ4¹F$ÎCf’ŸÑ^¾Jòõˬïßâþ};7¸;HØ=¤—æ#²gv"_gaã’Ï]Ø¡²' ¾`9õ2w~QÁ{âdÕ ñÜr5_¦n–Rlþ;•3ݯc»|· R/ ?ìŸBdd°{¾;þ¿ŠØ š»gù¿ÝU'pŒ.’›ÙÅŸ_Ù endstream endobj 2584 0 obj << /Length 1143 /Filter /FlateDecode >> stream xÚµWKoÛ8¾ûW½,T*)Q"Uì²›¤@‘¢ØÆÍÅ›c1Žzx%9iþýÎŒ"9Ž‘çÅ|ˆÎ7ß¼L½•G½/³?ç³OÇ©ô²0K£Ô›_zŒÒ0æ©' Ó8óæ¹· 'Íê›Z×~’UyÑû‘ ·þùüë§cÎF×9e¡17³Į̈{îh>ûoÆ`J=6¼”Š$Œhæ-«Ùâœz9|üêÁ§Lz7æhåqPFp”Zz§³¿yÛ£ÃÅ£a ¦‰ ©L§p,”Û‰Š`ŽltÄ’Srâ'Œ4ø³*–8¨ÒâDc'g¾d,p7Vž„™”ÏÁj1ñ¥, #i!ênÙë¾hê œ{Xš˜ô&ÃDÄöú™/c£½2‚8ŽIséø{€~΀;è_Ø›~žò¯^ö•U¸ñJÕy©s»¸œh†Ði(½våÝM|™=x;æ‚Ö¾_ ð-â&F b”†œ9>T½‚w癟¥#°/0à/–ÆF¥Ö]åG’lü€‘®¿ƒÀ–¶ e‡rz¹o‹_v¾eàt¯Šº¨W¸ÇIS—·öëü~üyäÈií÷cŸ'§nß…èFw޽6q–Øè·2ÌA ¸8Ð:Òì­iÐ,¸B³4 .jU¡Gàô¦è¯Šç)é¯Ü÷¶Á»7xÌ Ï4£;’Ž.ôqr¸Y—`åÞÉ@sáA]­]ê2ËhBw99ùða—sãy†À„i–$6 M0%0b#1ªu¬×óU–‰o°3’ï£(²’¿_tº½öSè"óu‘êÜ^+lºÒ­ZZß4BuÕgÉ»ÏÏÊí2Õ•Çð,@‹gE(ª m– wˆwŽsد-o›u©¯uÙ½ós[)¨¨ˆCè½Qš¦.žŒpotýRØ«{$0$5áI–ò!$„„°²Œ?'”’ß;ZõPR÷hžûÌèù$‹S0a6Ü_,¬Ò‚ÞY߆Ä2Þ…¼ñŒÓççSå–¨ûh±ÅÝäËtÓußÞ¾V»èN+72ú˜éFÙ/VÆêìñ>8â”"ñ¾=e!¥|È|§zÓªþ¯¦ª0…íoúãiÓo{|eó¤@1P5Ö¿|PȾMߦágR„,{›Žìa €2m bí¦þˆ3 -lÓº6ÔuZ8Á:îô”ôÂ×­ª]m*m‹ƒÝ)‹Î”v(±§ V»—‹zKºehW‡u_¢°×xJfùÙ©•~zZÙk©‰ç ƒ7ÆÕ]X´ºß´u8Ø÷þ°Ã1væC(l? ó?l=Å? endstream endobj 2605 0 obj << /Length 1187 /Filter /FlateDecode >> stream xÚ½WYoÛ8~÷¯ÐJ#ê}ȶ͢E4qö%ÛÖ¢m²ä’rŽýõ;äH†¤ÈŽ\ìAÀ15œ›3]ke¹ÖŸ³?æ³óË€Y)M#/²æK‹¹.õƒÈŠ£‘ŸZó̺%id¿?¿Œ’§Æ4 cx6B®½PŠÛ^Bõ™Û¨Aç¤Óu¼6}p!W»(mß#µê® .îšœXK¨Ÿ$(¨úö],ê¡]'o öbò‰o„íø¾Oª%®×b'y­éÄØN’1Y]í.(hÂ*—¢ÞÉ’.ªÍ†—Ùq#´ W†µó†þhbI} É«'Zo‰hîë)ºŒ—Ìù¼Tµà&·Ÿ"T/¤£_ÙiDx±£™Ñ #ï–Š¾ A”ŽÄkh:9³ÀN–§ìÄP¥ÞI¡ù&T‘ Õï ÞsIU¯…¼Ï•3¾Ù5ö@† Z§)FÓ0ĸÜçõSßúo~¨º’bRV®…Ö›øä¢PÕ;3!DÃ|M“ö$¤~õO8žç‘¢Z!щ"nìYòRw‰ZH¾¨óªÄͨ× ÉÔ)ùÕg£‡3 öýí†.ü³vв $ôMU\êþ¡~ÞAáôt:‹‚+u´¦OsQ×àí¯Š§i|йí0¨üéjgoç³3f„³ýÜ ]F]Y‹Íìö«keð®õÓĺ7¬+€HÆta]Ͼ38{÷„¹4gƒÄ§iš ßpèEiÏÓ0 \òQH;dd¥ïm˜sLv'ˆMÒôwÐì`d¦AH£æÂ¾j!ó­¹|?ÑÑ?j§›ÙY¶„Ä©²î…;w~3ØZT £®VB·Ó)-îFñ•8 žƒ / ¹.¹öq5Ý&Cz©m×Äþ*_Æý© ¿¾cdŸúá™Qþö&GêÑemæCjàPïª? a¯pùtóáÃÙØ(yœÆÆ³Œ.DQÐZì¤XÞ¯y~uóv”¿àßDñœìÆù…n£[%¦I¦”šmg$J^t´šþ3ùð´lwQžÚǺÈ ÷³Ðôq‚ÉŸG/óÿá…?ÀGjŠ'ÞHÕÃ4Æ¾ÄæÇda½æ9´>è>°›;ݘ •D®j«†,"…(WõZ_Ö Ò«¼™­3üñ¨KñàhÔ`2u ßn Î¥¾†Z­AÆÊJJ¡ðsUfy¹2EG4M¼~ÑßÙ!bò}[E ÉeûšŸ—H og£©—?Z¤JpŽ%ÆÙÛÕIO§eMާ“ÓN’Äk컦TQÕ Éö±b~˜¬ßwªFJ+ÕÁêKZT;Dš©ûu¾lIñc—Kts4ÌR”•Üð"ÿ‡ëq©s iô¢Ôä ×óiW)4’‡´Š¬ù°ÄÕX¤ ešêIÅ-¨ Yµé{0è/\5Su»-r‘õsÏÛÔíó ‰_Ô“èNè÷ñƒønôæïú‘¼w”¥aS1¯wPô˜¨â¼í”Ȧ×ë ŠÃ…éV÷nU¶Ï¬'ͰؿÔ{+¡ endstream endobj 2636 0 obj << /Length 1277 /Filter /FlateDecode >> stream xÚÍXmoÛF þî_! &³¢—;½´ØoM†i‹6ξxÅ XgGƒ,9:Ù©ÿýÈãÙ‘Yp¶Ú‚@ô½‘|HytŒ¹á¿~.®‚Ȉí8ðc<3\DZ}¡ëÚãÔ˜˜ QÍ…=’2±¼ÈÜpëÛøÃÅsû˜ãÚaäéjG⚣ùÀbÖX<Ü®z! ú´ç+Ì$_‰ÖÖÆM~nd ÝÈfžG›GÖÐ÷}³D$Òº¦˜†³úž¨4©¤hf¹f…Kç@ˆ”FgU¹Ð:† žµyú§Ãï?ÓIøáê¥- Q>Ûq¬å»vD¾9Êeù"5:kßzžg’BT –wÖsóo1­A$qsmq„1K³š”¦jŠ™I‘Ò®¬À#jQ%Ó:ÅËÇ}€£¾/ ÍT¾ÑRŸ IäW%ë0Ql¾V²i)‚#\ ”š:N@°0Aí‹á4O¤Ü÷°ÿt2Ó'¯ ¹Í;Ü3ºvÌ9™ñ·J$µP¼>ß¡ÕN 3'ç°Éä \˜™f‹3±)’…çN.ó¬>-£=÷“«;)Ž`9¸®:ØÝ%6÷¸1] &ß#…ÉÀ×#ãQ-] ¸… ó@nÜ ¾<»åœfæiI꺎€¢œÅ6‹¼ýÌCY§’AÜ“ûÌ1?ŠÊâp—ã]Ë# iÙ£Ú~Ä^¢ÉÍ:2&w"Û 4ÎVÙ²ÎàfýÙì#ªM¦,¶D¥SVYé‘5ßæ:ç$­¨Ë9ÜãÅyéV&óî„Û!rØ#ò«WˆǼñé«RIJô eGbwo_\…nÛ|0ûSWÎ5ŸŒ¿¿©sÞÃ+Úfld²Ñß<¹¹$úú|º½¾Ö³IšÚS‘çv–\3-óœBøpHÁ‡ª Fø"_dnAøpe>YV%._g©z,4NM–K:£xšx†N µÍsòfTY¿\°èxKt6ë4 ä"süõöò@M ¶®Ô»_5òÀ †5œ´ÓûyðísÐJÝFÝÝý‡}?;À´_eûtÅ™ë÷ž2¥¤1 œé  HUì¨mÊÄ ãC@iÔß'Nú$A˜ +–”‡úä·>©nÕ|rŸ¾{ªm}[A‚ê7M€WïûywmzL{'ê$Ëå’'tzê‡Oe-:a}c ÔåÚ—²bþ„2uH¦Vq£¿ÓUU u7Öù†ÒEQÖ4'WÚ>eU§ÔíK¬1<÷ë¶v‚íúÚ·S¢íJ°st%ôX‚>u%"êJøÿî?C[‚Ÿ®/ÁOטÐ)irœØ®UpbsìzüœÍ‚3kt N _³KÐËêÙuÏìNŽPM endstream endobj 2535 0 obj << /Type /ObjStm /N 100 /First 969 /Length 2009 /Filter /FlateDecode >> stream xÚíZ][¹ }Ÿ_¡ÇöE–HJ¢€`l‚´ö IÚòàdÜ]o=ãÀö,²ÿ¾‡Ëó‘qïMr¶@f†¾¦¨#Фu‡“ Ž'¹¸Xª+*Ž äÔ1‘ã¬íÕIÄ·I†ØX‰.,äR¢3ìR5e—¥)'—kSήpS.˜…Ì`vJM¹º*Ч óB/²VH5:.äbä Ó)BÒõ„gÜRa“£b5 F8'“`IbIj#ÔÅÚLa3SÂZbª sdÌ‘ÅFNÌj#2ô44 óÖlÈ3 ÄØ$¬‘’-¦”`KζÊdk.0•«Í†u¨bƒÛ¼œ ~)7=ŒÕbÃÌӕ̲²ã@ _ÁN{fiöðLš‹íO4Ø>.Y0‡ǵ­“G¬E"¶&⣂èBP›Žfó™â7/Ûi^V…Ô¼ eI±bl©Ø’+JŽ˜O-*’­û&¥á­I ›šT±à ImqǤx#‰KÔö§&‡@k3dÄTÃT‹ƒ_š¤.iÛŸZhP†½à2eRt™ª¹“g![µºl»ŠGÙeû©@²hÍñœa³bÇrA¸2ö%sIÕeeŒÅeU›Í•š †ÔvKh“" צǮ ¿0VWr1{1YÔ7 ¸ªíxŽÅi #Û?%ißV§ Ø”)8µ,…æÒ$rª0‰V©gOžœÍž»s$²"Ÿ_ºÙ_ÿöwË^Ï–HJ+tW׫՛³o¾iÚ/ÖW;÷䉛½@°™«Ú°–ÌXÇþ\^û7XgÚ¿ÁVa‘ûo‚«¡A4˜_ìfšý´Y¿{µØ¹s7ûéù 7{½ø°s¯¿ÀóŸg³g´¸Úm­$´iÎf/ÛõõæÝb{S&Ú³ïËù·ëîܦoî®ôÍ7mŠmò>Cs ªÚÁ)µ6ŸowÏ')w"¼màI´E|DpþÏisòdœ6âÈ£Ô–X|D §Í1yKàqÚ¨¤^®ò6î%ÀýÔ¸› H'­ùÑl¸Í“ÏN€>NÑÏOÔ”ñ pWù6¤Å‡ze_Uþ¯ýµ´‰=å±»ƒSÚcmƒùø€SôËšÓ¦Vy$µò'¦ÖìéÕÕÖÎoè áilp/HRnVóZ3r6{uýv×>·¼úçÙìÛõæb±i›ٟg™=;íƒa~‡ÕrJ>‚ï‰Þd°pôFÉjò¬ jO›»_¹ÙŸÖ¯×Ûõ‡—ÿ¸òß­þ~þÞ¿¼˜oñ¿ÍWË‹åî÷?š#'A%8øXG•böÜnÖ|ë/ç»ÍòÃàtˆ"ð2)`?èZ( *>+ûH|ÐÅfý~µøm±ÚNŽˆ¢úÐ8ðjq1þ=i‰èÝlabrDÙ+¢º#÷¥ ZÍß>î Vò§7ù±"… ÉGj£ÁòEFkÇêgœ¶ ÙêCn1Š-Ü-\LjôgW1•«˜ÒT±²/U%wáðD»P÷‚†.ÄIëZÈ>Á1dÚ°Ì ŒÖN$Zz4[-ûñí¯02yñ@ÿܪZ¥‰`“"ªÙ×…Òë=CAkÍZ|Hø¬ð‹”‚?!ŽÀʇ í*ˆôŽÓUxÁ̽qGd…À.i†°Ä÷¸É$ÑE”¿`W ¬Kó Â*|’Žˆ Ê_ôï ¼ò'ø»Ê·-Bòô4Ú¤ž8ÔÆCO¶±j3l§8R[Õ"Œµ-ð § 5ÅöRŒ}òxv(Ú‹¯ÑÔéžò`oü¸6|f·ã´ÑÑTŒÖF3Dt eIÅÛ»²‘Úv‰Ac=B ÂùÞ—5ô÷ØÈ¤¿ëºK@XÆ,é!1¥â¹ Ò…Ô…Ü…ÒíBg"Ô™u&BÝ2uËÔ-S·LÝ2uËÔ-S·ÌÝ2wË<)ÇaLö«óÕ:D´?¹Þô ¹–¡ãsâŠÂj¯ ô€Fp\Z¡BÓ`œæL1H·J8£Œ¦~ ¤é/•÷g¸ÝUœOý ÁŠ>Þ¼>Û,æ»Eƒ6õe Ù›Iõ$B»Œ‚t>ù©” ºÜ`Í…‡qL„ Üng ÉuÉÅòrú¼2(ñE8_¡1P®`¢ÜnR"àÞ£íûÕr75–N‡Á5c»Ð§ŠÖe ÈM<Žåúív19˜Îì¬FûW!oÿáÁ5ûªMšžÚq بêHAñì_Ý4€aŽ„ñ/íaÕ endstream endobj 2659 0 obj << /Length 1030 /Filter /FlateDecode >> stream xÚÝW[s›8~÷¯ÐLVÌ!0;ûà¶I§t3;ûâ탲Cƒ‹pRÿû=BØŠ/Ù¦}ØÉL,t®ß¹IrÐ9èýèÍtôúÊ£("w9šÎuÂ<ŽJ gš&h†£Ðú<ýøúЇ-Næ{„G ôÔ³=æ9ø“,-Ÿâ…´læ‡$e®Ò"™Ù¸ÕT©ÿ¾ ªV: ×ã„FÏ‚k`y©á”“SëTq™®´ý¦=¶nzCdÓxA`Ä?鍯pe¹!~²Üf£(Íï²(e£þHˆÊÚ.oß ^š+éÄ6JÙÄ¥ãWÍí᪳W–­ƒHqi*¬ØÖÞº9¯ñöN‰…„9;8ûÕ+ËöO˜ù]Êê¡HÌz®qëEœ ¥Œ[íÔ‡¦þÖ8Ü63Ãíúê‹ Š8à%‘ï·ªôÇw¾þ0?Þ]__˜åæA$ ‰e–‘4Q‡x! œžëq¹XCF-æâJù‰Xëõš×eàBÅÔW?Æuqèãžn]iÅ=@÷ñW}æ~8q7NoÎpú&—íFñN5Êa×@tã¨g€éTÆQ;4¨“a3âXσQЏ’ ð£Þ‚@Ö€E~]×ݤª0[Õƒ4¹ž$륖ǵ\£¤˜ÎVb”ÙY•…fL™tµŠÕÊèÈ÷‚N¢ÐmZh‹6k†lV¹XJõ»Y§ó¡ÆµaüâéíÝeCì6î…]«í´Rƒ:t dâ^fjHK­B’d‡³„ìÌVR¡•ç’ëý°È¡(“sþo+â¼µü/çȸ ´|Æç½Ñx¢SkmO©>4)•h#= ³ž—Åò`8ãzŠ^ùÍÉ©×Du"uù† 3U<+as>÷]l@6UõhÁ·ÈÒ$­Oà֒Ȥi®IЇ¢¥ª>´ -¼+˜³ÇÎÛRŠJnSrsÿÝx(:€­¸õ[âl‹½#nkÔÞ¯kø9Vf¶ëy{å&¢›ÕïãÙð ò£epÌ~•!¸¶ýK>L÷4¯~º­^±©õ½’çY¾¹»#Žü܇Р¯¡(ä'Rß=SügŠ–Óߢ2ߺµõwëÒ0Œ“3†Á˼P\æ×ï/öBibR¯ov·¡Jý?žûŒÿÐá¾i6Ö½ =(4kOÏæ<¶‰¸È2±R²Ã}5¾ž\^ ¦ªô_•Ÿò; endstream endobj 2684 0 obj << /Length 1946 /Filter /FlateDecode >> stream xÚ½XÝoÛ6Ï_aì¥2©ú²>Zô!ÛÚ­ÃÖm¶h†±èX"y¤Ü4ûëwÇ;Ê”-;Á0 ~ð‘<òŽ¿û¤ÂÙÍ,œ}wöõåÙÓWY1+ƒ2‹³Ùåj…a¤Ù,¢ KÊÙe5ûèÝJu#ƒ÷r«D?ÿýò‡§¯ÒÈÙ“†Q œh¸ËyÎB–̹Ãì'yñÌs˜K\•èÅÜ_„¡÷‚þ.ßýòòƒƒ|P¨\,FüjÄýêâÇ÷ÓìÕ}’Ë~Ä}#ûŸ7}ݵWá"ü2ZúŠnt׸+àÝ_Ój%WbÛôS;Þ2'M*™öKs÷ÑnbpS¯¨Ì¢ ( â»P7Û[ÙΓØëõéýÿ=äñ 8 Ò2¢ƒ¾ì›ÉµéG?ãÜ»`øÅL!+‘ïŽÿè'IâíœäøÉI’zÝ5 ·ðŒYNx âW1)|ÿ(…ºnoÉpžÒòAå §æfAа©µ]XMÊH£è´Œ„ddF†~!MTU°”MÔ•> G”i’{Ë9Ðk¡Äry½T8[xŸçqáüNבË,¢Ìkd{Ó¯9TPýô·4Sç4¸GvÜx¤÷„”¡'6›¹r[¸€Û¯%kÙ)%5-wm&4Á’gA‰ à –ÏsÀN4[©É0}G*˜³ŒôBõ´ÖÁWDJ_ÏLð„ïÐÕŠ[yÒ0þ —cže×4b£å€¦y½:âž‘É{“Ðñ"¡ôGd#ðB÷Æ’JÓØþS'4Ü…¨v ú2àZ*0Kœ—^}\“WO©32éÔ)¤èµlôÄ1Sæ=0'^3·×ÜèÑö9(3'í£}~"“"f5€  …”nº^Y·º—¢¢bÿŸ¶&E…BÑ•Ç'-»m‹·±‡`Ý­ëÁ=aJÉ¿¶µ"'œDIɶS·¢©ÿ\È"´f¶15úÏþ+¹ìn¡lT²â…ý““ÁNÔèTš«Î[Ø2RåW„&ËsS£72… ¬]Ôa.Òÿ΄êöͺ£T¢Ù‰` û±^kÑV 3ìLƒª¸4 Xq%«í!ÑÏö¤g Gz±`<Ê WqžV›ˆ«0'çHŽgØ=ýÂÌf…$Ìî€n KÅ·€¥Ý-h×]ݯ‰"ß‚<©–©Ü3•Cuæ@ÞÙ]ûÆŒ:cÏ4)õùƒ8Ò˜5›TõU˜$üÚ„†›ˆÉ‡ ª õ/¡ýZŸ²‡oõ[a^üWysqÊñ¢ðþ4ÉJnh4B!^Œí€ +ÕÝ¥å*u/iäô"z¼Ž±^ |YGìàd潄 á<?'ŸjÕqŠ­¶ÈK£ BmTÆ Ýy-LÕÊÿÁÇ “ ô)Žó¶ëßyØ1O%%'ÀÇÏ‹q/~¤e_1Åžõ­k ÷n',ƒvœ®×é£ÏGwÞ6…ñË帱2Ó}óÛÄ6Ðf#´–ÖûØ66åöœ¦‡Þaúõ““¿ÎKjü&_>¼x(CN9 8Kš¦Tó«ƒîð1ϲ¡]H¼oe/êFÓ0šÒùm-1¤R·¥ÃsÅÐnÓŠ}wjw:ô…HšøT—Xª-F¬â%“0öù‡3.´æ–Ò ù;/É;Fm Œ¡xNµÜÃ÷ì 5ÿ{DØ6û 4µR8Å­NbTÉ!gMjoŠî\ÀŒ®$6AÁÜÏ‹Ô{Ý/ݹD£;gÿÔ $„ óðo@¦è¯‚XxˆÝWïÛ ˜Z +t(³hênØ=Cp4zmâ‚jˆ tRÑ3ÍŠ²ê¡fæ^0¨+ t_s¿xp-£â¢¤NM¢/¤PKä»á|X­[š'901.?8JùÿÜ/âл\óYìMH2ä¸ß|caû»LåT9™ÔýÀ!¢’„“ž@¸BÛ´c˜ºéG:,¹íäarŽÌ»È º'jmÂcÍU‚'ÜF)çĺ&VÊ3˜ºê÷’:ûPBÞ¢¤kB B4-Ø7À×ЀYip;$´˜Ü ‰z5Ȱ⸳‚TaAwñעgo]]°´Ý lìøÐ¡ªê©Ä`ÑÀGŠ‹Æ9½B»ý„^0Øÿd)ê‘’œž&Þƒ^ YH;2͘Ü™0pšÀй-ή¤è·ŠM'b#Ã@ƒ¶I£Ì|K¡#c¼|S NŒ¡IŒü<†½6%†n¾Ñøº%'œc':e=êŸàÃÇãgPªéóɾþ£Ïc~9¡Ö퓞H“1—K|j¤æª˜8Lh@W.Zk4˜Úið„}† ·  †þ¸ÂJœÅöó±c†Ö4b³À–¿àA»ö\VÓ~Öó·ª?>œS?u·"›ÂôW뽟C‚xÉ æËðÝrÌìv;Ì|ð…/¥/|Ádcóòòì~ÖAö endstream endobj 2691 0 obj << /Length 835 /Filter /FlateDecode >> stream xÚåVíOœ0ÿÎ_ÑdKV’£Rh¡$/Éâ–LÏOÌlUYà¸QN½ÿ~NnÓé.n‹1ôÚçí÷¼üZ] ï¦ÆÖ>£( çxhzލm—yȧ”xn€¦ 1lš§Ó÷[ûžè‰º%, `¨úª¸–2ìÖ8Xf=q«“·6]­u,¥i¹ÂÅ;™*ê=3ƒ²¨ ®EU¦å8.ÎL‹{ø›Œ« ì0†¯LÎq”™§IZ™Ž—¦`¸9…ƒY¢Ó™é\É2Š«´˜éÍ\V—,NTüÊ:0½Ô¶^i‡>ïÉ„·müµ ¥¯!•²Õ¡ƒ“7cò%Ù‹·IŠ I :ÿˆ6Û,«ëB/гšDGµñ:eó³<þ¢ò(Ë&Zi©?oõçî¸ËíÿUq/޼(»ˆ.£Ùxl­ÓyÍ}z&‡oô§aùf¡?YªªVã|ˆv ½| øxTf˜’.-ÆÞÔønЦ™éíÌ©Gá¡87ÂS%pÑ@ót݈æˆA‡ûÌ…u†ŽOkÛPßòý頀ɃábA@ÏY{{Á`x—Ùø@Bö\.t^ë…Ò;>ÎSÈ!űÉ,3ÀLqV—bYo ¥’¨ŠÖ#g" 6¥A®²‘w ó(±EûØØ•*.ÓysÅÿÆSC#wݹËZä°Èc™X O Ž;œkI¥e§éÁ~£¬°.aÝyº¡Û®#„ô'ÐqIG@?o~l[ú Xè8¬âc·bx4µóv^”í4t”†¸úUŸÞ‘WŸëw”Š–c:£ò+t? LeE5Òú¾þeŽV–ržE±Ìå¬ú+¿Àªòÿ¯¬ü¯ënšÉdÿW•ýc _VmïÍ›®ì½ëÞ ?p^  endstream endobj 2717 0 obj << /Length 925 /Filter /FlateDecode >> stream xÚÅVßoÔ8~ß¿Â*çH$8±ó Ý=ôZ@BÁíê^ BiânÙMØxþ÷Œ=Þ\’fC—CBÕ6ŽcÏ|ßÌø3²&Œ¼Xü½Z¿dÕ^ZÛ¢ ?(¤žÇhý|·Þe‡Tµƒ ŽŸ#”ÚŸz¡@;ˆnœ…a„DÄô|븜sØH#:µkŒà&èÈÎûˆíÃ’ M Ü Ú@Úd®Um!¨[¹Ã¡Éµã†¢}[©]˜ 5 ËLe}ß‚fEqmî¸Ñ±}m¤¥vƒÏ¶1¤d^¾c\ä8y]*qXì-¼b”Ófï¸>­ý{@=ý뤽•#°G5¤+]VU¶•õ¾íáKãÀOU‘™øZª[Kêˆ53‚ðËb–O„Žž}Ë6 HÑìÑ$1c‘èè%@Ïò³‚óBZò³JPqTnoêŽ/H§D×þ…æz“h7YUõ´a°âL"‰3£Özã'`çEñð tëLÉV•Ûõ áÌýÙjñyáFü®_ð(ð<óÍâê=#|ŒOòÕ,Ý" Ý#*²\¼=š4Ó”†ÒL#(T.„iÇšR/ïQ:8<Œ®tzy˜Ðeã„>ÍT™U8¡mé)cOOÅô¢3:Í—^ÌÂSø"/1Ñlƒ4õdu)Û|W6ª¬·?q`‘!§es`/]¤ðõ¢×Ãg¥c uòZwiÅbF%u•#¬ªlU§•¸ þ¼„ìÖä0üçžKhb~p û¦.·ª÷؉ThDª=Aô?É»³éRðÉ A¦ïPÛÍÅù­œº•ŒRõüHí*áô¼jëcÕ2“Ÿ±³ûêwá§'%EˆÞÅ‹ÛlbF¡^Êõá¾™³à†^¦gîô?}OÐSæìËÓÀ%<¥p«ÜÕe1­ÃPÐǧXÖ³þê?aÿ¤Ðždt×Å<`~y¤ŒPõüú`YúÆôŸ¸$–E©îf¥ Tÿ;‚/3 endstream endobj 2646 0 obj << /Type /ObjStm /N 100 /First 981 /Length 2162 /Filter /FlateDecode >> stream xÚíZmo7þî_Áw(@q8Ã7À(’&ÈÝéa§@{V€“ím£«,’$÷ëû Wë—ÄŠÖîªÈ {–’g†œg¸ë£ãŒ>V!_H…dD¼ Ù„”U(&þÙ™‚ dJÑ?±7DœMÊÅÏîMÉûª•!%2äcJ†3š$ê|ŒÁHâ ÕaºÑ) (I%tEñˆJœu •² -`¼BªÇ”tµ~ªˆâj_LDôG©&ʬTJ]|`ÃĺŒ †}ªmÁ°Ž¢aEšÐŸcÁ Æäd ˆœê¸M™I$]±öŒ^5ÔbX<—$˜‹§P E ^¢ªSÅ)ÔhóN—á_ñÇ ©Ô)ÐèþÊYM‘ÙHp S$g`m5-V"©.'cäât䌑KPg ›”¢¦€ƒ‚íÜðµÖ TÝÐÆ­Ä&!CLˆYû¦`BkÐM(©Î› bLW„PŠºHÅÄ\W”‰¥º9“I02ü|õ#,šàLQÐÆÕËE Á„âœIRçÀRÃI¡†OI긛BÑ5byI£Î'í«f€„Y1ò$L†چɲg•0Y޵‡úœªU0J_½îˆìJ’oûêàRH[%ÕQŠÉÉÃተ}2L ûÇyÎ.¤!’ˆMaÖÄÁBÑ” üSÕ ¤ £Ý¤1UÔ¾t%y>8<<½ùxÕ˜Ñóù|±>\Ÿ­ëóëéü׃Ñw‹åE³›¬VÃa’!>;LÙª…éýd6½˜®?‹(YltòÁ6ŽK{â`cÜ êtp—Qò–ã-O¢Éaá‘xV$t‹$‹Å¦Ù…äbz9<”çh6Ü@Aưش»‘Ì'—Íjøm•“õÞßÀɶìtÑêj6]ŽE¢‡Wn±,8w¹>[5¡y kkÆsæØŒ~üéßà)–‰Á‹ 8Tç׳ÙÛ­Ê`*UIÅê!ÛS;õ8–úi‡-ÐìGÛ;x¶/nIÁf$¯žÚØÉÂ}WéqùÞÊ$V‰e?mJΊ|²ÈW‹ùºFÊ+p£ˆl^»½‚Z(Ô=€©×=$oÜÊï‘È;TñÉì0Ëçì0û§³ÃÔ1¿DÃ’¹–B…ìl€<'%,j@˜°õà8i®—“! †0±]`°ÞëA!éd;øæS¦RÃ&ó#®»Ê7‡ liî©Í‘ úŽ ®oõ2õñ¥ÎÝø½²à-Ññï ÙvšOB¶üŽíJ“Ô•&©+MRW𤨠]Ñ“º¢'uEOîB?ú¬‡6éõµGêDîŒbS$$!¶$q×­èÐ;€Sµò7p„‹Õ›ì]pZ{º5Ñ ¤@¥é‚´·KQÃVô}R½aŠÑ!'„/1ÒÁÏ,x¬½(R ž5ün ‡ËŒÇ×ówg‹c'n<~¿˜^œ=Û<üÚ,ç­ô¿gíïów“¥Jÿ¯–‹5´í÷fÍä}óþrqÑ<›þ\ßî½*MÍåx¼lf“:×ÐFÑÂâ7FaDŒCúi”¯Ê?xýzÀCgžCVÛxû8£ZØå­ ?î² Ú -Ÿˆû i/χ†#)bbÙÀ œ­^¨í‚³,Ýù¦ $ÒÂÅD½Íç]…ÜçP* éhB/6tWy÷ÍùƒÚZ<=xMüvw’ö¢-™¬¾ªýSû«ÔÆùã8÷ÕÖwHžPõm}A ¯T݆”~ò†àNuøTB(}F¨…'jý"¡aý a#äNØeýa#P'øNà!é3eœ˜úÜâ0™lƒ~‚c+»íWN'W“õt2;ZLa¤!ß°8-‘Iê§C%ZL§o®‹ÛÎU¿_ÌšóëŽñ–\6ëw‹‹!éª~íP/äQÑz$]}5ºëBa°çXí‡Ú3#ÑQ¸¥—«®<Õàæ˜§~¶Á»ŸvÛ»»O1ê…/ÂÜ雨ŸÙ}ñÂ÷¤ùå6CÌ/æûñ¤'Tc`R2&Ô±þ)À·“ÞÐÊ 4ñA'OÁöP©©B?ØêÍmî)ß¾ç+¥ôÔAß5¦žÚ’3‚Æ÷ÔÖË®(á©Ú¿—Qâ endstream endobj 2730 0 obj << /Length 1058 /Filter /FlateDecode >> stream xÚÕW]oÛ6}÷¯ ЇÉ@¥’IIú6M°¢°ÅÝKÒÙ¢mm²ä‰Tÿû]Šô‡IsZlh‘]Y$ï9÷ã\£Âèzòv6yuE н˜ûÍ–ˆ`씣1š¥èÎ!ØŸ~ž}xuÅ£“¥wn@õ›2‹:Òݵ.§®9©Ô&Øúy?›ü=!`bD.xȼ(ŠÑb3¹ûŒQ ? øGè¡YºAP„4;G·“ßçuŸ†Gxʃ`3Î"/âÜðè í€B~D±s3u‰³_iyÇmÞ,tn®Œì©öS¤‘Çø³(*´'%ÜÇf¾¡r)ä¢Ê¶*+‹‰ý³›Ö¹$ò‚(²‘8Í”³,+{üyªVhoþ~Ýî]³åæ4HCžõRê”ó©Ë˜ó§X(ÒEWãó¡ˆ÷I&+ÑË«‡g8ÂóÅ ð‹±s˜§É»±5ãÆX䉴¨Â6týõ'‹·Å¿Í½»¯wdÄ‹3È®D¢êJÈ{ÌðãKÄógXëåðËLnóD÷ï΢·>ž ‘õf“T»6,©Ò²VçHðÓ˜CÝ×â¿(Þˆjuٱ훞g¶çÙW”4kw§ù¡©jvf.ÊãbX™X¿YÃr“ìoÅÝ9¶6V7­RÀSmr°Žö¢ó­ÝtaRž&*±7ï ó!Sk›ëu%­“×›B¾î¨0g­w€eÀb/ ,°{ŸàqåÖW†{ìã^ÎQ00xai¸0@i1>ºûßg8ÍÀ‚`˜›ê¶“ éįÎ@úvJ»³)í~J§NÏböthôí¶JêMîÖPðÂKíqª{q9=Þ§Íôth™Éîq@Í&êÌŒöv- [W˜çÊô/…Ö¥/™Ìæväi‡•€ÏЉ'rû~6ùT endstream endobj 2766 0 obj << /Length 979 /Filter /FlateDecode >> stream xÚ½WÙnÛ8}÷Wh¡€ˆ!ERK1/i§)PtÁLܾ¨E¡ÈŒ­BKF”³ü}/Iّٵ[§0`Éïvxïá1qæqÞL^N'§çAäÄ8üÀ™^9”Ìxà„”â€ÅÎtæ$¨JK©ð…\6ië~¾==ç´gÃâG„G³š¦MHVóÞjoµÜóCxȬх”®Ç"†Î UÌ®ðÁ‘ÓèŸöö?ã<ì§9qÄ„uû¾.d¶,¤ò²"Uj3¯~,CÌãp•м”•ëG¨MÛ¼®\Ï÷}T¤úɽë‡H6ö‘q,Õ‹Î÷I&PhŒ^ɪmê|¶Gj :9Ä»ÏyÏ{)ÛE=;¶ÿ€=Ø»èÀ·À9€ÞfŠc!úÛÜE:>TŒ±aˆ›´Ègy{?ˆñz:ùB#ºž@SLBádå$ùJœ¼| qX9·fiép¨$äzð çbòïÈÈôÆ|8'”à !Ã~ÈÇǼ‡AÊŒtáz-/]á£úò»tEY C,"ôA{2.ÆK (¦‡•fKà#L%ü j+øGª¬É¯Í¼ŽqÈÆf®Ù"°æo¤Î¶¬]h6b\CâRµ˜_õ•}­ jx †‹è»ÌÚnÅmÞ.òÊ®Jo”ä‡ÝgÖ™° Û±ñ€_uUŒ`B;öþ¤Ò¹ÜB©à wÀóìÄ%°ñÌ^í¸Øû«º±7ëi==‡©ë·u ŠGý“eh4j°1¦m¿Aîà‹îBÄ·gÍ|©¹ù¨U;ùÉér·{¯Bމ³§éÞo¾=jþìÆJ‹¥ü•¹˜Úq`j{kgƒÏ¢ÿ`=; Z¢(j}\ÞæÕÜ.^ ÕCw»ÙióúnDy$èÅ&Q‰ËA—„ 4&¬;׿ø”l`°ekwïÍPØt‰¥ÕlÇw»u#FM•²‚Bí*c¥L‚߯`–Cã+ Ç´ÛµFΖ™æKµ¥1F39–y ¬¤~O†Îµû¨±ûì‚j<(û#àXÉ´‘ªõ*™Ï:‹®¯‹ê¼I¯j§ öcÛ›½ý¹Þ6§k1c¨ÃÈÒÞ!qâÉvã]À¾S¤ˆÆïÞ82o…AÝæVôÊ&Ít¯¡zSâZí'æÀöù˜¤Ðøe÷û7©ñDjÔ¸•nG”¢IòG€J’¿½“=™Ãqêy>ùðéÝ»cº‡>îú#Aœ­JøÈÁ V3—OiÕgïÁ!¬d»_ÌÂòõ]Z^Rí¯-#pð5uE8âîú²Ì¾©TÅ*‹Gžà/Å•í* endstream endobj 2780 0 obj << /Length 1190 /Filter /FlateDecode >> stream xÚ½WËrÛ6Ýë+8“EÉ™ŠHðÕ;‰;“Iœ¶Vºq²€HHBK‚.IYòß÷âE‘2%ËIÛxœsÏ}9k9¿Ì~^Ì®nv2?‹ƒØY¬Œ’ØI0öã0s…sïbD¼¯‹÷W7q:Øz?q„î-ãë¤îÒ›Ãߺ™W¬ÛÔð#q‹Vœ!óÞ»Åìï†)rpÿTœÄ>Ž'¯f÷_‘SÀÇ÷|ÊRg§¶V4 a^:w³ßúûŽGÍ'òÁÈae>¶|â%ÍKÚŽÇlÄ‘„¹‹ óæa”š“^„¦^9\1MŽ$>"¯á¦9 MbœúiioY›7ü¡ãµ8ëš:s8¦©>®…êéeM ¦Äå­^Ú¶¬Ð³®ÖcÛÕ Ó›:{_ÃÚmÙ™#õJB?’¨Góq¿ ˆ‚‹µÞEËuÝðnSµÚÛFF˜KAä'Ö îʺk'©Lœ1>/öGêŒv?r?Ò®á{c°6X©£\Øê‚Q`ß(Û•ßœûÜ'˜‘ã ‡Yp¸õ›pzsìR»ß W¾LÅ…€C d¼Ì°‹’Éǵ{H (Xü`A¶·"ċч‡’çtY2Xž7'„¸ïüµ™uyy QËçžzMØþŠ(‚bU¿ÌðZØgäÊ#MEUĪˆ°ZÎ9íTlÁâŽK¨r¦…ÂÙ!.ì:íô¬¢ƒëµí˜þ!+ì…âºm×0ZIÐN€ýL…ŒQ¬YIc²Þ^Vxm!Hè ÏmЖÄn¡1ˆíJ”j&‡ôx`×nÄÍôý\è­«¦®é¥8ø‚•öŒRóžÙ@¯œ•¥/hõÜ‹Ÿ+v«¶’×Èuä]Z+못 ˜˜C¨¸;éÝæþRïÑ3ªÁu:;2f,‘ƒ!°û°•—uÊàþéBC"â#ÿ·U”„±ŸeáQUåþ¨ÒËî@VÎ[e;½ÑôãúF‰ûQõ PT‹3•”@òGÀæ_)¥aD¬|g)ýhºTÂWÊ®4×™D…üÔiÖŽþþÌeïexÙŸ;á¡Ò+jð’(rÿdy7xN}Z3ÁdœöþY0•Cmqw5¤ã¸4—uù//Š]ºfUÞÏ-ì<[y/¬ÀoÞx*èîB=jGÒsEJNúëê&y¯?À#‹Ž¬y|lò2¹Ð4W¯d:ÜË|£&|Bð˜#Üä î–¯í¶ û¿°›<Þnê_/¥‹X/izݬ·$ž0p¿¯«Ú›×Ƹœ¢ª}QÁ|Áíc»×¯ )rqH…úÄVxK¹e§²Å9û€kMYHáxËA‚ÒШ Z6Û=ꢬû½i‡¸ÉÀ!&EùI—ú_È l:i·UE›§¾Õe&k»¢Þv/ç1*YIÖAÞòeùd!KG{Òqn?øpV-“Ýo¤Z[‘wÊ®ç=;Ž70’±z_ŒÎõ:°Mú°8ˆÁI^”ýUÿKŒ8u®—Á·äRüŸ¥û°æ‘³Ý¸u¢§Õe¹óenR4èþ£m, endstream endobj 2795 0 obj << /Length 1004 /Filter /FlateDecode >> stream xÚåWM“Ó8½çW¸ŠrÕØH–-Ù‡= ,³µ0Ë&p <‰â˜uä[&ÿžÖǘÄ8ɰµÅBq˜RÕju¿~Šž°WxØûcòt6yrÁR/ 31o¶òÆ!™Ç ͼÙÒ›£Ë[?J‘hªÜ8Úúf/Ÿ\ÄdgÍX˜b AÍ‚í4ÁnŸç³ÉÍ„€‰=ÒoÁx’„y‹Ídþ{K˜|éÁT–zŸŒëÆ‹! ë°•7¼éã GSGÌwë 8d"KÒv_‡®a»—ÔŸí¬›<1ºô‚n}‚úƒøó Ž9š^çªÌ+;?ˆCŽ.¯> ?!h¡Z>¤&gIáŸs?J¬ÕftbãXÅI˜‘ô[°²˜Ä#½e„…8¥“ßE»hÊkUÖr—/øì5rH2ì }Öˆ\A%'(—v¬5Kv(“eìÄJjë[rÓ‰ÆM¶Këyå CÅBÙïq‚ÇÚ€îFØ8×îÄ%Uä¥lÕpc•7…P;›%ýfÑáͶ7 ý Ž(zš·å"¯ª­ŸRt¦½Ä:“%‰ì=¦±\Bë)EàhE½¹†­STK!5`†/46ˆO;8¸ôŒZçÊ~\õa>•j]JkŸ¬qewryh½²¦ {†¶û6èQ8^ ¨hD,LHdËzÛæ…%Сø¡’½3ª[pw}ÁmÝXJ˜SÖþÍçNŸ»é0 MÛè…cc>zd=¦±7B­ë¥µWuc¶,d®ºFØrù^ÇãQN<R5u¹lÏܯÁ_uµ-jÙŽÅ1`È‹À÷€`*Š  ë‘…﫺‹®¿0..ßí]‰¿@Ûwjþ× g?qíð÷¿öúÔÅtÞü8ù4Ò—ê± êÄÅt7û" àˆž7æ~S‹t¨ËÍż£C{ Qd!á±Íkû€¼fZŽØK~49¸ê'G÷ÙÓs}<šaÌ!ÃFöÜjå(@Ÿ4Z+«”­’I²q]©'r#¨Àh°X:oY¹é>€“YÜÉ,ne–ö]K|ÊÆõ¥ kXF¿ v§Úr)FÂpfi´&É6z0GBð‚>ðN'àÈoÓDyQȺˇ¬w~Æ@Ávâгáäaå™Ö°N§ÊÊ'¨—»â¨T¦½ Žu;`aeÿyˆ&> î)0^×J|ÓóÉá0[—.ƒU'æf²nÄMW6ú$´_ê7ñCnÞ{ „wæßzŽ¿B²]o¸ö¹ÎúüãÃÑÖÞÂTï¢ä>êGÐÜrã«2áÑúžT" endstream endobj 2811 0 obj << /Length 1102 /Filter /FlateDecode >> stream xÚµVÛnÛ8}÷W}©T,)‰ºt±iÚ-ºE6u 8AAËŒ«­,¹¢”Ë~ý5”-_›dQè8çœΈ‘9aäÝèõxôò,ä$¥iäGd|M8c4#sN£ %ã™8œEîÕøÃ˳(˜"¦`ÉÐf9]d_õB…11ëáíxôcÄaÊ_ÅeQJ²ÅhrÅÈ ^~ ð*MÈmgº !øÃæù<úsuÞöˆ â!Îhœ"‘R Dw.³ïr®N¿©ìû>à”>žx"™v®àØzHœ–ÝDÝåºQeæ ß±[Õ5އ¥y…Î:?ûù‡Mô#ø#ÏpO¤"žßy¾Q:«óe“WåÍ5ÝÍh'ăσÄ~nôqýÄ1¼ƒÀi\;wXôÜí²ã £Äa)í‡B8–û^Ï8óc}ѽH‡‚;@ïCï÷’ F)}áz‚1GÕuUãôwÆ_Þ‚ À“zÞ.Té¾Óè£@´² ­¤ÛˆÂÄ‹|?v΀[2vÚ–r¡ôöC Ü îõQ‡Â8|oCØÔ­za¦!dz]·6¸¥=êh,òþ£>/–û Ï*׃M¥ËçÍ }¢ú_n9²hÕ£ئÂûÒ`¹Éu>-îÑqm’X¹ÜiZ3«KûÓ¡Á;U¡jèÌŒiY5y9 áÜžš—º¨f¡ú1¿VÙ}V¢³#I5y£–µÊd£fWÖÙnN$ûËßN>„ÜÄÜäð0‹Ùêp\ç%Ž7ÆHÕÚ˜nCPFÙo0˜³µÂýV÷¬àõœôÓ‹Fu!Ëù«W™AùuCÈ•&ÀÅÜðÁ Þå‘—žy×)Ài*l €â%g‡kr À6å¿¶'A>Á^|´cît¤Èt¤l/Æ wо!ɍދ›>.ЙW}iÕ»Î_ÿqНf²05G´ð}š<®?îO~R¥ÿ¯?YÉNð’év ø»Ü47t#'‡½‰³¿Ñâ^êEžéç¸ØgU1%k­Ê¯ï\ɾ8è–£õ™©ŒU½ÍSz»Õî³jkÙ Ô@(bÿ¨ÌéÛ¼ùÖ7[Ø®«¢À–`+"È_T-w—,w.év"ÀÿIXb§V@©µ4mõ^ÿ¤MAÇ>mëZue½Á’¸M4M1/`b÷² mdÞøª´:oPåï{Ì‚=»øtò —ž%•Á–§Õ'²ªE°Ç^ÈA;Ý<4ìݾûb˜fÊÁO@f¯À¥ÏÙÞð“‰Qkçõ^M;Çkö¡óɤˆYäÿö·Ê\™;#ò®Ç0³ŸÀÝ‹Gg²Pt äªÙž=M»'á¸qü{ÔôZɦw¡Äß°co dß:IíµœÉ¥ ¸c=©ûºÕyËåôÀçÿ£N· endstream endobj 2725 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2155 /Filter /FlateDecode >> stream xÚåZmoGþî_1[7;oäÌn7{Ò^a§‡k­·‘6¶.²dè%Hï×ßÑVgÇR¼NWÅ÷Á%qÈgH‡äÊEg•Q.:§Ë«WÙáÕ’²>ÉY9ÂåSaaEŽT ¤˜ƒ²Ì^E“UÀ_$:rÑ[•Œ«w`‹Bx•²"¨ì³¤r"!XYã w {RÖ:Á^k¹ÁgΈgÁVÄ:¬à$|Á(›Š”`•ÍëÏðÏzÑ Úm!( Àw”ƒP²+*k!4¥!)oœ Yy[,@FyWV€Ù/:È)OQøÈ+è ±T«)ŸSù–U°E\²Ð¡!XÁB°gÑÁF‘µ¢ƒ­˜¹PN‘ÏÂKaƒ ‰“ˆã¨H\‚ETt¢GQ²I,•@q‘/³L2 Îh›â'¬bS,Š­°)žÂ2¶ÅR1+†­…‚ËÅÍ X1±Æœ¨8¾qƉeÇø([§¬,â\¬×DcS’¸ "-‰ ‚a¬B ª¸A‡°H)‚ŠeAR.ÙDBÐù(+²QQ4‚‚”À²"‚ `ø [’M ¾£X7ÁÇx“¡"CEŽú±ãÄL9‚b‰ ø%!…Ê dÉ•œlBâ<9D(»ƒ$Pˆv/ºX’OpE2b!_V°¨.+ ƒ\Ñ$&NðQ*a” ô&0QÊePdãÄN„ì:ÁÙÙÚxt||T=W8§Œ}¦ªüúŽ“Ñ±â­Õ>Ÿ®&“×Gß}÷inÇNËéÆm3k»Ã}:›.Õñ±ªN‚ Ë”e§ð,¢°}ƒÈÍí7ØK¶©ý&à³yòûµ^¯~žÏ†çÍR]¨êç秪zÕ|Xª­ÞW¿ß4ø¢¾lŽªgÀÐL— É"EØQuÖ,f«ù°Y¬óIùìÇf4®¿Ÿ}PÂÄ01‚â5Õs¬†1( ãÉt:ƒ´‹u.<% ñ‘þÂyT¯Þ,Ëû—ã黣êûÙ|ÔÌ‹óºúkõ¢zvaË6Ä–lôšnøÓ’D3:89›Y“P'Ũçªúaöj¦à”¯ÎÞNõ³I3\MšÅ×b¢^ 8CZ2°ÏFËñtdu†·ƒ±šbx”;Ùmìä\B'º %ß´ÛÌm qdmpðÂd›þËãöN¤‘nÜ”¢N&wäðrU7f’öܶ#Ö€¾/gÜIwÈíœq+3|”3îd” ŒŒü‡óý¡[‰1ÜK (\Ö $˜–°-áZ·D›mÖ™h]±lˆ­œÔyCP+™ZÉÔJ¦V2µ’©•L­dj%S+™ZÉÜJæV2·’Ù÷šmÔ^ªL§£TuȆÑjŸ;dC}6ªWz8©}fFû·.¯ƒE!h½v¸“QigöÃz†`˜ÏÆ£Áò–µÔ-¬`¼¶Ru=Öu³¼šz kø–¼Æq|×½k‡§E…ÊYK2yÖysy ‹ÕËñlzdmÐ{«N£³Ig rÛÇëÝ•ÎÁu8â-6tCZZÀÏÀö¾žŒGãåï=‚KAK7E|ɦr *v²(2ü§<ºš×ËCTN¸šÑ&9qE£-3N£)úÓp wÓ—§·Y£5V\@W#NËŸ¨àN‹ºG·Øè´Å•½…!nB›× À–Æ1+ͯ·hvbÜ‹ãùøú¬­†ý#‘€E¼Úh4Ë€×[NŸ8D78?õäÅ5j“Ád\¦~ Æ!ù”¡È`Nÿö÷„QŠò@:”©IÄ+íñü¾¹êñuNKÕè8®ÏAK‰ã\DÄä½0ÑfÝûùõØ}–Ó:rÍÃpÖ8tk1ÑáL³Œé©ÿÌ¿¹1 :%H"”#Þ[BK’ö¢º¸è?çÂg¥¿Ù@qPdtõ ”ãuƒÕôêÍìÃÀ3¼GaöæéæÍ»f>]Sÿ~º~^Õs¡þ9ÜÌgK@X~çͤ©ß7ï¯g£æéømy½+îm™cs=Ì›I]tõ~%z1‹ÛšEîãùË4Ëÿ”Ÿ~yù²ßÌW†Ý­¢×Iÿøg4¾î?í¥XîåK`”sÖwÁ2­¯Ñ.ô (D^Ÿå òI3= 躙_6ýg˜u®³Ý.©¦ÄVÒÄø½P«7‹f¹KÐ0=b0w›y;„ʤÑtä&T.Òa¸á›À]¹C‚'»Â޵<èÆí49t5  Wiçðl·\2òxâñ÷Û#²ý“´Þ‡giÇô=¦ÏžÅvXÛaUŒ‡ÃûHšJ¹ƒzT:ÊÄÚ§ýäOÍø7üÿ^Ò¡ö ò\6 ¬X\í’ÿ3‘H»–‚/k’g´lÑÍ¢{ÉJÞß>-–£Ùê~Ήy÷Œ÷=»Ãp{yÜ;slGfBqìÊdeé0ÜÒé¥pn“] Xú,—:r»è´<×îÈí’t&¹-§Rk|1%2ÝϬÙ~fÝìawÝ•$Œ²ÊÞªó¥VCRÀ]ähYf>¨ÿI#¿É;%íT'ÇÇECu2”É`u^ýröBþ¾ºZ.oOªj8¯§zþTËÿ‚=›_V7õðÌðíâí×唑Sn3ÿ7K ¢#> 7L@;çÿ17§ñ©#7ESî¾nÜÞTé]¹åž5;KÁ]Ü–òýâîÑ¿xè˜&¢QÙØ?”&’µ÷Ò„<þÜ4!¿Lé±Ü’2K7ú”µóò€(–‘d€¹Û?ƒœOêéå“'ëføNŸ­&z<],ëɤ}\nÈj:§†;Ì· ·ëÖ郄Ü[îÿ¯KŸ endstream endobj 2837 0 obj << /Length 1342 /Filter /FlateDecode >> stream xÚ½WKoã6¾ûWØC% –E=­=¤y],ÒtííÅÙƒ"1¶º²ä%©$þ÷r(Û’ßmº0`’"‡óþfèSÃ1~ëý:î î¡Ûqè†ÆøÙ Žc{~hD„Ø¡ã̘˜ –—–;4…}“Ï?Ó¬N­¯ãƒ;ŸlPzqhîU4ĉ䡞£Y5#ð 6¨úž?´]}7‚?ºÄiQwxMúã˜s*û™&¢f”[}ÏóÌ>Wœ'–™K\ôEŠO \Jº, ®8hGg¸Jxs&)õ—2“ß|±‚ÐLXž”)í ç·Trì`}ÚN 5R²*¦GÕº¦EqXîÌ6Û$ù‹å¹&µi˜-O fŒ¢Ç‘sFŸ“ºhuì-ÿyWÃLüW9ÔErŸ"ˆ‚LY²˜ñã¬ïi>ÉÛŸ¬>üW ÐäjžVóE-hvâ¤1A^«OL ÓR•(trQ­bTÌ(RŒîïÏ0!“y'òªrcÏ,+aIÓowp„2"±í{¯äÔRK•øÄŽƒ/*í³² ÀkhYÀ=¡?äº ¨XFÙ&¡o¾Zª0|;¾ðdº¶w >|°>=«éfU†ógY¥ä$- Fk£n£ÚOZàM6³ÝÙµÉv’tŒ«ÒïÑ œ· "Ëçg¿à@.½U®Ckcßuôö‚UÒiÖÚ¾»ú4ºÕ'lÛVä åµÁ®Ø´žëŽƒôÀ>Ëk¾®‘ As¥ÏÀÏ*Œ×ÓmŒŸ¨XÚW»Ôºh»£œp¸ÎE ÷}=_÷:MœËŒ•œ³rP÷?5¹“å|Qìn£ýxíþÃZ»Ç$›Jp(黵ºãB}á+¸žð*hÂUµzE%Îà ¡|˜c(9þ>…úŒ² ø¿¬ž)EMϪ :ÈoÖ¶ÓVU¾6ºg¶\ôVµftÝKDÖ8©rÓê.± ½ä<jZPFáê’ï(EòvŠFTŠ0„W`Á«=B‚v‘7M¾X:nÝßkk®Óù¢i‚ay– Œ]Ðàb§ÉeÉÆUª(S¯zÚ“ñçZµÕ ýñ´/ò1 ¾¶íÊpq:ÇNÁh˜öWÕjoœÃxÞ¬.A‹.ßõþÀœìn4ßÑZ¨ÇäG1‚BñC8®lJÿw^`ãõÙI\·Ðºûç0­1 endstream endobj 2848 0 obj << /Length 772 /Filter /FlateDecode >> stream xÚÍVMoÛ0 ½çWía60«ú°> ìÒamº5Û% ×vRvìÙκŸ_ÊR²8MÒ놬H$ÅG>ñ… 9"èjô~<:» )Šp$™D㢄`J¤(Å’Ghœ¢‰G‰ö§ãg—Ro˜r &2‚@½Ñç8Í—­±b‡ÁÊ#` 6¹õ»ø—u‘ =÷}!¢BœeØg«Q@æµ±ê$öAˆ÷.°ßú¶L¾·e\“É œžL§æˆP‚#áÖM¾è¾AÀ>´Ïåb<ú1¢`J]×EÒ‹ˆ¡¤M¦¥pÑ zÓ…P:rXèfôi/[|µY|ÈIB;D¤°.·ë¦ºÏ’n«°púÛo(ï*ëü€ íÅ‹Ô.Z»£¼Ú¨×ø‚yÕ½Yff™8ó|1«š2îòj±¸ÐC²/Àmñ…;È%„Ä’¸þÈÚ¤Éëõí;Z> ¨i¹Æ\kënAsî@óІº©€ÂëË×­‘úÔ³×mSÔ„gkÅlø/m<ÏŽ§æþ<] ɪ[³zkŠ1^1ΰ’qQzœË€é?ãb™ ¢Ø §§öü†Ûo™uwUj×P »HЏmm9Ëœ¾q…Ú„7ñn²ew»œv:˜Gáʼn——c7&«‹8ÉÊlÑýÈäŸtí9ž7ó%@õ9óºÃ£òÚœ¶Çô°4¡bÊ;_ØWTÝBªÒÛåµ]È7r¯Ð¾C2s‡CÅ´AÕ?Ñú•¥öê®r)twYc—}“ýÒöé¬ë¼?!aºîG†\ >Žƒ¤Ì˜9¢q_ýHzOn?r¸Ng%dÞˆr4ÙÑ´~ã!ïî6§âAˆqšB öJã s*ÿ®2€Å"và¿Å–j¾)À'µ/`Ø;l̬?õU¹ÒMk•‰,A#b³˜ûF/÷WƒpL£ðu”‘ªs&_Wm-Œ2Âß yåÔ°YlfM_„^G+J§|ÿL"m—I“ˆÐ‘G*&”÷ endstream endobj 2864 0 obj << /Length 767 /Filter /FlateDecode >> stream xÚ­UMSÛ0½çWè¨Ì`!Ùò×C: tÚ™Bè%å lá¤õGj9…ö×WòÊ„ÆËÒj÷íîÛgŠ2DÑÅèÃltzD(&qàhö€¥Äã #£YŠæøZ”iU|…ßÍ.OÏ9ëÝðâ€DÔÓþZ[Fcc4¢6„¶æ=k§3wÜPozpiRgëB–cÏÅ\ß~kwan¤Qâ2Žªû2i¶ôáκ!ž”cÇó<¼,D&aYÝ?ÀûôCRä0 Úˆ„Ãáׄ³ º‘IP‡ãx%”’)„n* ¡YÈ–…lzW_H•­ú Ž&s[߯q€E¾–{Ë·…j»l³…­A-ÒåÚTË¿c†Áßt6ú5bÚEì?G|Ÿù()Fó;ŠR}x‰ôQ¡ÇÖ´@\Ó(ä†9º}}¶­-‡e”´ïÆ:ÛGÄ^vA<¬¹Ç)¾¥.¦Ï°hLv~„¼`Óx2ß!.;û³d±.Ô«²„løž±â‘GhÈ!›R%õrÕ,«ò-Mû,~>ÙÎ hZ›K»ñP·ùµM5¹æàK‰b•ñ8NŒ‡…¨EÒÈZ€…ff³af&7¤|\6 Ç2V­D""è­2“vh¶_šqw›ß©OsYf”O)>ƒ—u‹Dg¦G¹ll¢æKÏ®vÁŽAÿn eñ¾¬PŸ*Ó›G(w®'±*3;˜‹jwýé&wÓøûV5ä+4 êt’ߪø=Ök™hHMU¤êŽ˜ÓõÃ| Ù–Ô­•j_fÆFu“ß çáT^#ÆÓ§¦ÕkíƒnK”Á—~H„ê uËëóÞhüý½«lOö”òhh½ ³4ý†«ggðÞ°r§dýö>«$^7YÇÌÒ4½<<ÉUõÌ,Qóm]xCõ§Oíu¼,EÚYÀ»ðö×áeC””©%î^uÂÒ”’Ø÷©×qVa'hµ\åZo’6»¾vnv0ë?Ú?•a« endstream endobj 2878 0 obj << /Length 834 /Filter /FlateDecode >> stream xÚµV[oÚ0~çWømŽÔ¸vì8ÉCX×NªªJ£t{ ÕÀ@ª\XÖõßÏ·@B¢Z÷dÇçöÏÇ'ƒ%Ààëàóxp~͈PÄ=Æ @0F”q‚8Àx&ì‹Y£ÓNÉUx¼yØ7xªx)zéI,èIÌ[ Ø×¯µ©T#(jôÔåÍê3-Æ]‘.dèñ1†f¹{¸½íÕÏÅ :ÙÆÖñoQN‹ª«<=\õ@éc·'™#9…ßa¹Üd"w¨ëê(Ïøm Ç·÷ööîŸ^‡T9‡€)’DÂèÍ­Åæ)lE™,“‹ÚMËêÿcz˜!îùÿw¦ !GQyÞŽaÏH1Óß²“ÈÅ:èÍ‹ÒÓ‡LDŽ$¤ÿ4 Ø¢»\ŹüóºžÏ¡l f3ŽÌ&5*×ÊlÕT ÖØÈüÅ> stream xÚåWÝo›0Ï_Ú‡T\ÀÒö­í´©êC›î%­*œ„ B„Éšý÷;$…„д۴M{²±}w¿ûÝÏ8ÆÔpŒ½÷ÃÞé…Š|Ï7†Ãu„‰o®‹|ÃÄ™×lNsöe·î‡ŸO/ˆ[Á‘BƒByØu]q¨çhpšÔNÛëã¶À"VB·œNYClßê‚:ÞаÝ‘ ¿õÎé;Åø+‹«Ëî;މ‚5‰TÙF‘«¤ŽÕ‰¬ÆœU³"QóIQªIœQ®ýêþäîÍLÜÈpN¿·É´žP@{Ô?À—9{Db—«Ïwj¸º½¼üÃÎö_ì­ÿoz{–æ×,YÆÿKt¯X:AÃoˆo‘%Ýþþ„ܰeI«_~ <’bãØš&íW}‹& ŠA¥Iƒ•<år0iø¼ß†ï Ú+/^9b. 5Y¢LW…†PÍX©¦2Ÿ-þ8OÑï…¨ox[” Q1Q¦A‡šˆ4ÔKm*;`eªƒ ¤–Ø*åÜHêKs 3Á­åš èšÈ² » 6Òý0 Pbœ©éc V[î±±¬;¦‚½ÜªRb–l‘D3õ]seè«î‹5Ù’½&~m·–\xL«Ùž:& ßÐÕ•[ç+š/2ƾ‡ Ë'°€ u³VmD5GÝšåo‡œ¦s5R=n^×2.ÄEÿ°Ì• hÕhNq‘IÎwwã<~à9ͲÑèèújpt/ÚPýEQW_Jx ¢Ò¾ÔðÖ®#o¶up0¸©¢ÅâI+çÃÞŸ> stream xÚ­VÛnã6}÷Wî ¬¹¼é´i·)P` Ôvûâ ´ÄuTèâŠ2¼é×w(ÒŽäUœl5œ9gæp(Švˆ¢ßf?¯gïo%C)I#¡õÄ(%BF(fŒD"Eëm0c<¸[ÿþþ6J¦›O"*ñ² x‚u»Ó«½jþ¨º¶È´±›fÔÇ‚@1J`w$ín’T´à1, §ÖGR« 6.BJñOnØ+Óiú‰†t~óyþÎ-fMÙ[Úå¯cóm•}6•*ËÍf¾üãf~wFÌ>Z°ØEf”¤¡gxþJÇë÷Zå߆x:x«í‡œ(cÔÃ(,8挤,vŽpöËÞÞ{Õe陵•>ÕRç‡ìå±¾žÉÍ>S—¹¹ð}b“UÛÇïü¸b?GêLå¶Ùþ£³î9ï¦|‡ ^Éø ÔðDäËäMª!y…VúÐ*ŸOŸÛ7Pîc¢&á>Z]ÕÂÕ’û‚©<'–$)ò‘áüfþV§qšÓì×õìßç±sÓ‘$qÈPVÍ6wåðâ‘&èØ›VHBOŒ¥€y‰V³?Ïírt]5vU`AŸ•2&\:2Ëæ-3JG^8I91äÎ øB†w Æx,Þ!ÇàÕÎýºóo-íaa‚·îËÒ.6Ç+™áœ°ô{ã '®‘ÄDR_ÎÚdm±ïЦÑÜ£«)æ)I¢ð̼g-îú(à1nÜBÓº±jZobú4۹ĕKvÀ°q [»ÿÁ¶õsìO"ÃÄ]|#2 ‹DP¨/å_F’) ”â+”¦5a… ™?80å'-?‡ì¦Ý*]‚ãÎ\Eø 2ÿò:g£Ÿ0†´Ý­é|ê-ú¯ßþ<î¡}÷ yrÁ_b¥³¦ÎG1%—¸,Nš/+¶žL˜8i²SEi^£ÇÕ½‚F!Ó°Ô ÔiÜ›-æ±èîÝ[w¯ÝÄô`î^¬ ûZ÷oÇÂö];Ûðó…ýŽª? çö¼ƒH$±ª=’Cm¸¼¸/±œz-\I¡g“Ÿ¨n1 ÇgôÔg™KµÇ#†x„u+dYj_#Ofÿé¶1nj¯4ëÁñ¿¨dÝøpPè>¸*ê¢Þ]ìðyzÑý;H#¬Êƒ~M]—º;´µ®ŠÇn2)ôÓýôS(ãr endstream endobj 2823 0 obj << /Type /ObjStm /N 100 /First 970 /Length 1692 /Filter /FlateDecode >> stream xÚÝY]o[7 }ϯÐcû`]I)i ôÙ lX‘tÀ¶ ®}ÛfMìÂvÖößïP¶Ó¤u¹µamy¯È#’"©Û}4΄ìÙDÑÅ” ÿ&ã)«ÏÑD"BÑø+EÁ º6xC¢‹]1чƒI GÖŸ¢I\ÁlŠèò Æ{—T‚‰@õ]VcU*Æ3©.rÆK®’ƒ@*ã‹TxôÎë;h1˜Ì BY*ï¨ë]"&{äPñ0ÕmÄñúNaÂÊ ŠBr ‘t›Ê)ÂB*U1¯–åp»Ìػ˺C`É+]@>Á¡ÐK¡Zeõ•¨]@^-p€ÄjÉPtª¾¢ÈuC*u…b¥“A‘8g(Æ¢;Ïœ!e¥M”Bݤ¤n(Î5žâLt5Zâ$VêÁÄPÔ–°ÆW—Šú*× f‚ÚBPc ¸à‰—:ðN„…½âuA‚^aM™ÅÉéŠD¸®ÐwEM$(.ŽŒîš]a*À:ÖW•/¶ÄÈ XÈRõ0xq Õ– I†˜ª‹zd”ÃK½ú+×4Tg¼ãêa¸¹z Ç\L“êa¸ƒ¥f"²†S x1 $˜(\qøµÝ,B$NS$ãQ\Qz¥ñêÏ⤬¡À®$ÀŸx 7l©çª8•RVWáP_1$©x1"8¦`KIH°•\µ[‰ýÁááA÷Ìœâ|:ècÓýþÇŸ8ÎËYlÉÉÕÅÅÙÁ£G÷ c°È¢FtÌÁFäM#š²%׊&õf`'–Q”ÚÐA‚%iFûl×{<šNæðÐtG¨ Œ<«ËŽD“&¬PU¸¬pÆ4ÍV¿ ÍËÊÔÎ\q× '8MúKÝ‹ÙttÒ/Ì©é^<;2ÝËþãÂ\“xùé}†oúƒî)õ“Å\ëZÒõÝq?Ÿ^ÍFý|Yëê»_úñùðÉô£9UózÔS g04œa5*cŠKàãÉd m§Ëª¯|jÕ_ ²ÒZÈk¡¬rkÁ¯…°h-,5±¡jú {2ûYåéκŸºçÝS< {œéÖFpŠ÷Ébc8a¶ÿ˜m‚¦h£€\½Z@e÷óùä]÷øð°èçÓIwÒývü\ÿ|°Þ}|ÓO¦—磹M/»ñp1œ÷‹yGƒwƒ÷¯.£ùàõlz9ÞöËÅÛOƒñt2 ü`¾NÆÃÙ¢¸‡ØÓ¦m­8™Jjó.}}Xï28¶> »8œc­¦QlAž íX—5xk&ž˜îÇéË©A&?8~=±ÏÎ/ûñÕè¡Ù“•¿=;Ëh9~FeÅs¶¨Õw »ã@Eƒ¬ãL°‚2ÎzJ•L$ÔÄ»I<õÃE¿öɯ¯þ‚¶Ý{&8 j¹ 0HTòÖg¾7@öx<œ¿µ£‹á|¾CJEÓeE)¤\sfKJ/ÎÇç‹O»c…a=jÌ’Ù’ïeuº‡\¦˜¬Çà°$ˆP“}P‰HÍ‘Êé~&ãóË}PAÒ¸u³M y|ÙÏÞô{,7¹á‘­Ãàé}±îd3¿z…z½‘Nmñ$Ÿ[|)µÃ§-—MÒMðõ<Å î­íÜ53‰¸Á¤ÑÚ¢cheB¸CRhõ``LZ¾•wÀ½4yÙ¾G7ÿo>òiCóM²Ý‘¿¹õ´MóM›d"«Ÿ>ö‚zÙ+h†ný ß†ŽLvã'¾M`9¶ABÙTZ‰mq/h/¨x.ÿßÑÌVÿhoŸ2wЪˆV]·ŸÛ²M÷)[uŸ²±.\´r#:$®ŸCÑ>[q­hŸôãJÞe]ÞA|ËòVv+¾«[×7Å·¬÷Ðß[àëú&ÑnªAßÖ\ iå¡Ã5ëFµGÿO­hò¶P#Ø'gÝÍŠÿïþ4 endstream endobj 2921 0 obj << /Length 1510 /Filter /FlateDecode >> stream xÚXKsÛ6¾ëWp|¢fL†ð¡tzp›¤ãŒ›¤–Ó‹“E‚ŠTÊ®ó뻋iŠ"«ã± ‹ÅâÛo°c¬ ÇøcöÛÝìÕ»06ö"ôBã.7\DZ}‘ëÚ¡¿0î2ãÞ\&s/6æ^dò¹k.ç–«{£F n39ÿz÷þÕ;æö4ú‹ÐŽöSº\×G¡™£Mx{7ûgæÂÐ1Ün÷0òíEàévvÿÕ12˜|oÀÔ"6•èÖ```ÄPmi,guú†OuDõè:v&†Ahƒ–öˆ|É÷"iô):Т·úÞb1sX3·ü 2“*ÃAlÞÌ׬ñO’i,¢ÃÅ!à§ö¡énÔñq€~#ŒÏLIºs¡”oéí_2Iûq|Vr²{PÆlß= PŽp#Éž ¸7\¦¢Ø5E]Àö ßÜØ°Ü…íÞµ,ß÷5–0¸©'0ÄÉ>†ÐôG„o5·‚ÀüÆ Aøš …žÏUÕ§rƒÓZhª+ª(S?ËdÍGÏ8ræhìÌc\ûâ*Uò>ºÀ|m½Bã/Õ´£§šÊ‹ð Çü•>ßÜŒJnë‡CÉ»ÛÏoG%3.›¬Âß ž& ÏÐPøuG— ^&M1ØèÝÕÍr°“>˜mÛê³Õ?´V…{´k‰mÀ!YóLÞðˆ½CÚ]ØÀ« ”i©Ô!dXÝ2êÅÕÏü³&¸º²²B~§—R¡ù¤Ð’’SQáë ¸‚´J¶¼‚cƒ>oûÐÚÈ9$«&Þ¿éâýë¤êÂÿ4iㄯ¡´›ÎÏEþL2¦Îu‰XɺÜ7ž\¾ÄÖè ÷L›"mž@Gh·µ$ÏÚ=éIN:'ºW‰ä¯_K(·o–' 1/ÏÓÍ´nx uwÌ8`²ö^"Ó¢ø •!Ë&päha–õºH“Ò†ä»æu>Þæ@S‚uf¼@ƒ–ZŒ³¦>\­2/iû¤¢çÕò÷kH±yMï‰+µÇÕŽ¨ï…¤ç£(š†Wp˜ù©ÙX*¸Pˆ‹ÇB"· ÍÃÓÉ©M2ÌSHÀ䪨ñDc !\³€¬&i¸ºL, §k…ÍFÒzÛç|)*ZÖ‰lx¹«žy-Îeòí4ÙìS!dµ01NCV<@¾6}£¼¡óÌ|Ä ¯Åw¹KRý ޲…Z§Æ: ’ë ²Ap© ÀÑeKàĪïg¬”;EžØçqíTÝÚ”î…Ðn˜âƒö?ú$ !>r=CwEÞ €¥âFˆdí½Éý­B$° 68•ÑÔÃ<ͤÜk Šºðôíâ–AgÑ7°ÅUpD‹#ÜNöË®Íl‡Ò\[wÎZïÛíœM!ˆ Zù¢ÜÃà.¤s¾¸=çæOEµ&‰Ç ˜½èV¥›DBáJ­ khFCºÐaG)’ö~#ìëEc±þQì.F1bN`¦s¼½Ñ-Ju®ež¯¸ÀFi…뉼{'¶¡Šq¼6¸XÁ"oÊ86•Ñ”‹L¯S PQe¶ c—â-VKêuàð\—u@"§aˈ¢W`©l’¯é¥M¬Œ™×ëª\÷Åh®Ûµ½£ì-t³‘Ð#­« úE°áåŒî¡|S×ß_VLa«M­ÎUën0ßW©.]¾JŽZ îÄ¥b1õK9‡œ•¶í^B¼´ÿ‡‘öØMhÁ¨ò«ÛYû÷|¡óÍÿ¸¹_W\²X©D Þš°•œl_® ½ÿýïæŠ³ endstream endobj 2937 0 obj << /Length 1150 /Filter /FlateDecode >> stream xÚÅWKoã6¾çWÞ‹D^IÖËAsÈn’‹Åv{у¤”E[ÊÊ’KÒy èï I'¢"ÛI.…¤Èy|óÍC²g--ÏúõèÓôèãeè[ãá8bkº°|ÏŽÂØJ|ÆÖ4·f¶ï‡ÎõôËÇË8m‰ŽÂdèE ’Bâ©}ç‰MߞР#âÊq};ç¨}äi§à1l™q·vÜ Ã‘²ö5KF9wÜQ:²¬a 윪OîKQ(L‰×26“—k­Ì ¿-ÿFÄ©åúé0Ž´çiQ‚ ŽìŦž‹²©ñ)¶7œê8†³g10§·Whµ-ôé˜Ió¢QN­sÊÔž "6\» €ZMž:w /ê8#À>CÞùÐqÃÀ·§p¢ÍÓšdíè8æBÊÇQ¤XîRåî(SûžLCØ¢ ¸ñ[ áÓœT•(k0ü†©dJo%Sab¦ t1Ÿ7m@»ÙBñ†)GlófOðVQÆÿô"oY5AÌ£Ð>ÅedO¯~\À•C&¢‹†QƒÁX1Ðê²^‚P€ŒÉ¢‚Ý–2Ì—Ú—NÊh‚`d¯Ð””Ê© e¥UˆòÔ@^7˜WÑ[ø(iÔ[´ y ÂÐ^W”pí‡Q’ï-ê¨sW.k*EOݲ¬ôQgt;¶[C»)–¾5‚¾¿K1a­„,2ú÷¦dTßa¡¾¡e¥¹CÕ2k2Ç1÷Ó‰  —TûjÔªËB=”5ôpUÑ\'dJÕl;«xÓËÉ«ª¼Ë'wôê|b„cÌ^+Y}†u´X# ˆìâ¬ êøŽ ^$>±R°‡Oá$`*U¶>|pÜÈó°pÔúìä©ÿ<è?-X.Ô=âÔUñ¬(‡ä©Ò]ðÁ±K*ªGõpª–í!Ê“¤D–hOúõ¨ýÁJ¨e¹m6œ|MÉÝ9­È#ÍÏ#Üñ+áþv~Ií÷¢ŽM‡ël5W"¿¸jÅ“¾Â)®0ÏüôY~6ä%ÿ9¸¾65?CzÆ9yŒ~Ïné\ äªärÝ…`EWø¯@;'‚ ºÓæÍ¦\Ζã>î“a‰Èéþ:{êè™ÝmM[nä'nÛ%FL ßô€ŽZu<“—éniW¸NEJ¿¸4„ÓFFZ«õ >²äfQV´£§’ÜæLÐÕ…‘\éƒ08 Áæ lÛF©?ñrÞáWBh›ß/HK ÒTѨýœÌ‹þ²[3=™Ð}ÇE[mÚ4•Én·Ù6Ð`ûÚÀ;RQVè¸p¦ê³¦…ü¹Û›Ú}.Jl|¦Ó“‘¹>…÷¥Î!ôAÃz‡’˜1#ƒø=‘+õžÙ(/Zͼ«ÜÿÝCËþq÷éûgZUü]“NëþOs.[¯Lq çää#¾YÁʇ›¼doœ1 aÄÐnÀî\i­‹×*òE´oÚ¾}ºn‹…l“zúÚÉQD»‡õ’5øç¢-¯캻êû}¯¤n. 階"ê\íܼøZ¹˜ýà—ìÈ endstream endobj 2960 0 obj << /Length 1108 /Filter /FlateDecode >> stream xÚµVI“£6¾ó+(çUHl©ä0éY*©ÉÖvåâtUdm:€ wLJü÷<-vÆžqjR>HèmßÛØ;°?Xß-¬×ï“ÌÎý<‰{±¶Ã ðNì4 ýåö¢´—ΜnÚºQæt¤«Xë5Â}Xüðú={ÒK…q8aKª;À–Ú°%X²¡ØÏ²½(…'¤m|åzq8sòDµâ4îI,ñc²¯kéìVM1%2Í®uL[#­>ïK¡/ëªVæµ~›°}§¾ñôÙÑf'™â@žôoÃð­>f>èœ5œR'½œÓ='pIÒ‡W=}U`»¯' ý¹ÐÞDs¸ÇŠÓþ[%ª}£et';å:cýî¤2drÞÈh^˜È׺ó|ÝL4FÊT–â뛦*ÆÃ ©4•WGë¨ÇΧBEðOH¾d&UçÀ“Z¾ô6|(Ë;ÇYUŠÉõ=š˜¯nÑ÷/Ú?Ãõÿ ÿGVÓb_Óÿ}ÜÓþ¥ÑšîÖ"¹Ñ4úcå=‘º*«îpu±Á«[Í6 endstream endobj 2970 0 obj << /Length 820 /Filter /FlateDecode >> stream xÚÕ—]o›0†ïó+,õb óa@Ú.º®­Vu•ÖЋ)Ë%PœaÒ¦ÿ~6†$JÛTE‘à÷9/–:ˆ€._ýÁñ¹…€=l`àÏÒuhZ8AlzÀŸ‚±‚V'þåñ9v·ºŽ5Ãs]C)Ñœdªá(EP$4Óæâ^¡jH‰©ªñûS&fèÕÂgþàÏñPh½&vlha„óÁx¢ƒ)x ø#Ïe×9°¸,Ç2yœ‚Ñàçz¾v+Áœm0¤CÌQ±íB>AÉ5"BöZrÓ–LΈLKWF‚d«s• ¯‘ Óv”bÕF5o7§…¡mÚoá”yó†¼/f¸s`íyZ/‹éãæ¤ª)ž­Æ,9ê$–¢ð7 ¥`½UÙ ÕØªZ­©{Ø…[™RæÛõ¤ÈÖ±rò‘¯) ^, Þò ©Õ¿íÈ5–)â/WÿìØàßYµ#¼†/ÊÞRü°$SYÏT¶´ˆI.ÃùvÑÿ 9Ž”Sîƒ^=¶Ãõœ­AV/©(”ß„ë&ïÖÚªnfµÕD´(õÑô)ÚMqÆM¥Õo‹H܃H§h.ÕЙ\šÏ!qÔW·º¦ì‘±©‚^–ñ=ÊhÎÝêÚKücò/FYåp endstream endobj 2992 0 obj << /Length 1654 /Filter /FlateDecode >> stream xÚ½X[oÛ6~ϯ0úD•¢»ìn{ÈzCŠ¢Zw/é0Èm³“%”âøßï’’eY”í5(ò`Š!yîßùHg´9£÷7¿ÏnnßE“ÑÔžF^4š-G®ãØ~b×µ#:š¥£ò…®64{R&%+rkCËu1¶`"ã¿fnßnëË›N&.qÝÿ{ãhqõ/,Û2'#Ë‹áÓWâXߑ䥞ù¾O4ËÄ‘ }×ÈÝ–ä ¡‹²àc¹½XŽ[ÇÈaY¨¥ÿÈ¥tû‹šfË^àpòéëǵåÖ”.“*+;ç'Y66›Ð–âŒ,7²(P.ú~¥‹R^lÏx(ݯò‚ÓôEt¬“¬¢Ã'‡ž“Ùš‚¥Î¼FDn’ŸÒð›ÁVy{’­Þ#²¢Ô£­Ì:º`c—|sü”•ÿ˜c¤öýö{~Jɬº¦ý»A•ÿ*÷ó±¦}‡Ì²õ¢ µÈ’YÙž§÷†– ëÄ| >܉:Úç¯ëd9I€Wc+òž–*¿ܤr, y²ÁOÑcf'»`ÿŒ QÑ×EÁS–'%×Öä™RÓ°Ö*BÊÓÅ  ¥{À€ÂŸ)wÖ/_Uö¤pè¡ìÔ÷ Ò®Ïh¾*×gœŸSÞHH”ïy•[j¯š¦¹6L\ÃÊúc<Úr*€cRžw†¨æ‚–WÆëa(J_Ô‰Ú Óç«­ Ѝ6›„ï#$Ê´¨Ê  íÏñTCü5àæ]ntñËJú§ƒÝÝq¦ødÉ’åpÇjh€¸dÍi†YµÉÅ«N¶]{ÆÇvcTß<×9Ó—Z¨çôš5ñÉS¯-°ÃÕö4HõdÕ ý…£þ)ögpŽéê|ýq­÷k½ÿq­ƒçÒZf­IqÐÛà:æþÍõœÖ½­·Mí<Òõxoâ¼YVýJéaÂP.™}þúÖÌ•C]ÈU$>E„"‚Ç ÁÃ.=PKvL™‚ó”-šùDý(´à%}RßKåͨöGÔø#$Š$Ù~Uä’øƒïaß1A%Èð£«"å"Ú4/vOÕÃI¥Žêy±ƒêÉ=º¹ó‚¥jF*ˆ© Z“!™³!¼€|*JŠ í*|V‚7Ûª¤­'êDÑ9RÈÎc™*ST;BÖ1ñðåeƾ¢É0‡BÙ&àc£9 ÅÀMn&MBt¢'\гòäB‹SáÜ0+¤©dÁ`sjäA ɵݧÇwì=t>ð­&Í,%MRû9hgoé@+æ­–Þ-ž Ý zØ —bÓ¦;÷×~º³›&ø?˜ì]®A þìɈ#¶©áç“6®$òìÌ]°aaÃ6‚ºOŒý¹L·?TaÔ, Å—­H´­hn_B}É«kŒW×æÞ ³C÷Ö >rı·}{Ô=÷ š|)©ð®it†–÷×ÃsÁéûƒ'{ü†ÈK{£K<ÙŠ7õŸ¶ÙìKLä LYññC6…EÊb4m6¨FP\ÉÌF‰¥-Ia_Œ €Ùœþ[1®Kÿïv€{”Æ”gF aâ@*´Hì¡Ä°jñW3 {óû™ÙÒa´møá-б7ï7—·1Í!ë^/ñŽØ×LzéÖ¹;ܽ$ L°9ÒýeF¶œÔqs•ô?x±‚$ªçãs‰ïÉç=spIìœ4ø­ÞÌM×>wàÚ7«¡Yd™ôÜN¿ŒD>[)R¨úª!µºÝرlMØ¡ôPv¨®’¾IÉÞÖxínûÄ UºfªÃk’¨ïÓéøHŠÆø„?Ïý->©¨aÒ›a³1Ä ýèyvÏ3ªÆñ«mT’©·ãÉVý³&èòcYå ù†!¿$”#v{À˜]7j Æ—K: ¿¼ºZÒ:‘Ý Í(ßœÐYeÅ<Éúño* xe…îy­æê8 mÔËe*KÏ­™t°ß¸ ù¼“w2*Ú¢M³9Õ¯Äò#Qg70ôn‘› ¹Íh"jí€éÖЉ÷ ‰³U޼=÷¢‘h1dÝ/N¼Ôý};»ùÅ}¤Å endstream endobj 3018 0 obj << /Length 1252 /Filter /FlateDecode >> stream xÚíX[oÛ6~÷¯  €Š%Q—ìaزeèе]âæ%éƒbQ6ZrM*Y†þø^K¶âÖXڧ¦¨Ãs¾sáwH…ÞÜ ½?&¿N'/Ïâ¸H£Ô›Ö C'©—‚Ó¸ð¦•w…ÉýÓ?_ž¥yO4ÎBœ% ÇÈH¦^å¨BËOBgl$½…[DÌÅvý;?ŽP¹.…`‚ÿW*Þ6~ç1ºãja­gaOÉ•yYwª[³±žÑc¹ÓÄš›.¨AC+D«Aßñf®§´d>AÊZ´>€D•´/:éLá L„Þ,¹á¹6¸ 0¸ÌÊ©ÖÂaMy#˜5·*ÇZã(Œ¶9ÙÑ—Ò¾£4ƒà†8¢‘õö:"á.†l€†!:ãKvÊ„6àœÁ˜âw:rûYKTëR±9gÒ>ÏJ÷â"š#椘²ƒNêè[„ðù‰­žà‹­(=Y„ý€):m—Ë 0½ÈaâÍLt•ƒrF¡ózh ªL²Óyh/ÅHl®ôrâIšAA­µ²£6RMÛ«‡H± ¬&­Ö­‰ÇŒIië&AùÔh'—zUÛºk«/EƼ-$;Án}šBqu›ÄÑnƒ#EK»—_ æv`1LÈŸY7o]0 Yþ¤7Vb±EÚgµ`fè2ôÆ©Ž<³“jÁ¬ Ê«¥FD`£ÝdHéhj!ííù£ç¶…h#ƒO’Ͷm}TÝE1úÙnê““¯)À‘œùPS&)°áKû·l׎Ԣ5{¾»ùÂR7¼ª\µTÃï˜c”ä³ì…]¬ã{ˆÑv½(·|Þ0¥ØuHÃgÖB@‚ö–­o9»{Óä ùk"ŽRëG Æ,Ñÿ"d;Êä_•š~¿`s¨e !˜‰RÊC‰Ò J1 ‹MÄ7•EH”zæ^Wœ)U˜2Š™<9ª‚ò´uË+ùeh:UGh×½Õ¾dPMÕSëÿ«lÖ ö-ÐÓžö§F¿³ +‘#=Ñ›k`à¶¼âê~`ã÷éäã„Eäáè•ä ŽÓÔ›-'WB¯‚—@!:žwgD—^~dI cá]LþÙ1ýóÝ`›§àt*¥d$£@áŒQì´ ]hšb>Ðv9leš£K?Ë€‡¹xÐ5î,¥˜¤Ñ1ÎZ§’‘CkQLsw üÉÙš¯”kGž/5GëH”[¦µb/Õ€oÁñ†¨×ÃÙúí?Ð}¤ÕÈÝÿ¢l*aÎðp£æþ¨bK2dÒööF+?Š~eÁÇÒRð¥_¤=¯ÿWؘÜô³RmF®ÅmmB?‘¢uïg­ã\Þ¸µæÐ2&rÔDî!æÅLgÜÎíV²mØÍ~Ïδ¹MÈÔžô£'}Çž4æÌ(KG4ÃY–}Û–%ðŸ‘áç„ýO ;ˆn;‘æš¡WµmBæ„ ÿö9CoZ5Îß4FoÞ¿~ýx“Š"ؾYü4MŠ9.Šä)šÔS½KD‚*})ªK¸²ÙçÍõÎÑnÅVöòÝTî[©cX®WÚa¹iwíÊ~1b1í6„_bÕ÷²œ³GØtÏù'ü}óÑâù§OÏíè~s׊b\¡¯ë¾Ôž)HûgÌæ¬i endstream endobj 2910 0 obj << /Type /ObjStm /N 100 /First 989 /Length 2438 /Filter /FlateDecode >> stream xÚíZÝSÉ×_1öƒg§§çÓÅ]â³ãäªrøª’¬A±¬¥$á³ÿûüz¤‘Á `1—«<€zw{f~ÓÓß»6RFÙl"A)ëY«8%!Xyr*DVÉ{• ¯µ¸°ÊÜÈÂjYeç œÊ¹Ìë1/¡¨d…JŠÈ–©3¨è@…Ø”{á …{ÁËSŠŠ’)÷Àb¢ÅŒ©l ¸®¬Á`öQÖ`<ˆ& …±Ìâ(Aå0Ur2Â9å2Â/‡eŸŸ±†‹Š­—Y\RìŒÈÅá©/ÌÞ(Aá ²²òâà\v!:²å©SÎÆByå\‘¥ÊùäIˆØbŠgV.Éör Ped€˜EÞ 0o.ûöIyC²FxZ`ŠÊÛ HÌ1Vá“<¨„ÙqŠ>þH Š´!6ˆNÖ’§1Ê؈O$ûšB”/Z’ÌcAÈ)&L‘NÌ œŒHT–˜>ˆ<ãø%‘{bìbk£ì'ƒ‹%hšò4yBöXÃB eæ¨âbß”M².45ú¢·™UŒAv ráó*&9þœ¨‚êE‰Ø@»’ñ¢SMb.³$¨¶)cq/0Á@uRĶ@e,%Ý—Så—SåN©PAa@E•(ؘË40CIHKd[H íb '!YLµ¬!Ée)1›b_Éóâ0ØÙ4¯»É\íì¨æ5çcßÅ…ÐNα^@ BZ>ÁùCNrñãƒæÍ´;ÚkçêjÞ¼z­š·íç¹:à‘,õöËY‹ÓvмIJíd>k/kšÝvÖOÚÙÂî˽_ÚãÑð§î³z'‹l2f{€…†SŒ†ebï…ñÅdÒa¶w %xŠƒZ\‰Âý-¢2vÐìÎËõßG“ƒæ§nzÜN˺æ ù[ósóò• z„MZã5Yñ‚^èµå¨å¼9í"Ø^Áî©æ¯ÝÛN5¯Ô“Ý÷½×žO‡ó§"°^`°±ZLȦ¤‡¬‹qf˜×Â8ÎÚçÏgÃOíÑDÖ N½¢qÎh_üÝ&p¦íð¸W8Ö&ma[ÖeÄyƒ3“(tta-‘ËE¯0•ÄÀ¢öÿü׿½4#@Dë´‡ ™œÇk™aÅ…;D§ àA¸Úß±!·eذ!·ÜyCnGY‹oÆMNÔ×_æþê•.;¢‹.j#¯Ô¼ŽF-r˜r!nNò^‹ãU‡…Xyw‡å«{ •ˆ•HK‚«/ãêËø&_va l(Ze\eVK3-±4ZÒÁÊÒŠ¡5/vvÊüÍ‹£ù¨›4{ͯ»?Ëß“Óùülö¼iŽ¦Ã‰ž>;›vÿÁôº›ž4gãݸw2mg³éÓÞŒ: ƒF c†ä™ƒ–€6aýZ£þm4?Õ»çc]!õèöàt‘‘¬ ¹9"û¸ Òépr©ø—tŽÛëÓJiôûóùù´ýµE­†ÓùèhÜξ²<3ôl4™O;}:ÿ8~zç=Xfá·àUtŠ3¬’‡Æ/õjïg½Y $ ó.êÔä ÛJ"¯7F¸^C-J1 »b‘—0j–Û€\óK°à°E´½È¼ŠqyÓ¦ÜYüífܨz4ѦHPêD´.ÆÝy¯d—¢_”"zYîÖ‚¹Ö|Ú,¬åp5¬¹Ä\ b./ o*Qsu_㛯ñÍ»JÔðèCŸÙ;§ˆŒPªvd†(/]€nIölti}ö~6œ†ã7ÝøËI7é1‚Xh””¥Œ*"—V¼*E†´>qž½ïƒ¿É,*ÁP sÒ.äïƒ6î Ù „´Ža—$…n6:ú›Êª“ÐÅ¡øb½{<œêíü´;îóŒhx)¯¡$ˆxЉµ•V„7Èë•æe+áit<[;{M>®‹Ý –CÀ"él «wy94简%Ö(ÂnÃõK7nÎãF\.m9¯Pyä¼ÒØVïâZFr‚Å;¸"KÈ`„Š¢ãq5õ¢ ¼ÂÆù.œþ°}ŽGÇ£ù—+ßç-þEæUá‰Ì#ä‡`f¨Ìµ•øµÌrŒ–6ä¶0Þðmm½uý{1x€]¼&7÷È |Í Bì3¦Sd¨KÂ~Cq€yävðCy#íÑb–ÝA‚w ˆ6T„k §Ã[ƒ)ú¶±¯k)!%†@„¥sþ?÷îÝцÌ>yDõMUPìB:òÛ×BöûHÕ¶ÙÝÝb™Ëî.›»»»Tk™Tk™T[}©zÂ\‰”úu‰^Çòv Iâe¸#y3… eÜz§8·÷hÉ«yŸ‹øROˆ†H†•ØÿÎÛ‹ìX³¤Ï‡rìòÊŒQezŒæ¢ƒíz”Á @(@´"Ý裵xç$ÙÈ üz Ù@÷(kÏáßhE:!Õrû¿!¤ ÛŒFkqöÕko”œ\dþ¢à4Ò¦ÜNr¼˜6ä¦ì´|r¿,ûR  "}¾Ú›»cÔaCéÛ¨ƒ{áQ§¶ÛrmÀåÅò¥Â’ JØJp%\%|%B%b%R%êÌTg¦:3Õ™©ÎLuæå›¯ƒûEy…eÍ"Ã&„8„7 dýöë‹qôbŒÓF^YBºhr‰X[}CP>{¬P✗/ƒrÔ1ÉB°Êŧø¸ÅŸÂxþüF8·Ÿô,ùcbù¸ ¿6—ê éêöç·ÀµÞ‘-<£g~µ¿ÝøÂèî/bމèf-&ƒè$-“mZ$=7¼jÛÒÃ'8ŠÚ¶”×ÁûÇn[VXµm¹-¬k[®€-Ú–·áúNmËŠª¶-·…õPmKOÀ#M—ª÷itv©÷$ E+dpn:ÊõöÈ®kZÞSûa”P4h½Óˆ•œ5Ë'¡X×gõÈ?%@õ~‚Œµ}’– IÍX4¿/–ꬬ| ýÊY±¨Uí¬*¬ê¬¶…õ`Îjlá¬nÃõœUEUÕ¶°ÊYYà“¯‹—¾ ù³Næ÷à«–ÀÄËwê[ãºFb¯$á\~Svcyö_¦éŸ endstream endobj 3041 0 obj << /Length 1387 /Filter /FlateDecode >> stream xÚÍWKoã6¾ûW(+­(Q¯ìÉM6ŠíMÜ^Ò=(m³¥D¤ãØßíXŽì8ÛC‹!E΋3ß<:s't~ý<}¼Ls§Š4JÉÌaaÄ€¶âY«l*ù «UYùçeŒ0†Ø‘0H0 öbß6&@EÌÏÏxä^}û ‹õ=v/0'8oåÜ` £üs ¸·WBO±'Yn€—$ò£Äè<)úž– ©ƒ±~Dµš Fœ¹³®]ÒFÙÑv!ç ¿’0ÝâKÀæTÁ‹…¥mi-i©= :è[ˆtϼ/8 æ âk÷¥zS ãB.¯ðÇbý ¶°àÏ”Û,‹>4ð\Œ ÒÜ“íaUIm}ƒWK¡KŒ5Æ+L÷sœò,µ®–’Œ?ðh&J½"ñÌ­)ç!}Úƒ`‚4"ÊýÈÃÈ]K½ íw€ ßl)Iib+/Þö~WàÁiKEz Qr¾U†ÀõÖNV *QÏü )Òû¡¡á¥…¼¹­ÅšñÈ1°¥’õ“Ý?jÑT%PyfþÙüúiÄš6‡Ek¤UÝSæ ºýÁ_oÖvôë“:^s°AÛ_S5T>;ÄÎè ˜Ü¤0ž›âm·öè®kmx Ó“~çYë—)B¯xþ- "O ³/0h¹éG0‘–Ü+MT;½nÙ˜YŒYßihZtØ$£fµÄÿ;]˜" ¤6*v¶ê᥀j01“ ½‰ÏLïæÆ`ˆG%ž´œK“µø%+[Ê¥6©A§4¶lE#K°¥ÄL@ØXÓ„šÉêù tšß$Ch‡Ú!,¶WØÔßRûb}¢ª~ƒÈ\ìGu…™éåd? endstream endobj 3075 0 obj << /Length 1105 /Filter /FlateDecode >> stream xÚíWKÛ6¾ûWèÐ ¬R¢^H.[¤ )Úu{qr -®­B­HmßáC²d{7R¼ÙK‚…W3óÍ g>bgç`çíâ×ÕâÅJœÔK#?rV·ÁØ häÄ„xQ:«ÌY#âãå§Õ»o¢d°4 ±—` ‚ô¢Þ6Lº÷Ë0DlIP‘g¹\ú1ú¢ö.°UÙ=Ao<æ~ª¥¹~ ƒ‘ɶ2¿ç‚¥Y½vCŒÑVò¥ªoÍSîõ5‚–~‚ø•]јgÆoY[H;ªi“_šoÁ¥d›ÂJmE^í¬ðç%N£¬1¯@Z»à!ôÚ(¸>Ð=áŸKRÏ÷“æ<ã•ü:æÕÞw@ho‹VHnQ*ajNªˆ$½ä¶s‚Üç¼™ Zm–n¡ùV>;~W°Ä$Gìv·_wÁµ1§È…ì£?Ã*J|ôV©z\Sï‘P{äÄ®¡Ð# ÏwûMÝLÀâyÞ Á ÏZ{]}£—tdyÉ+BXa&z©GigZá~(ué2B^²¿Ä|qÇdÞ™®¥›vO —­vwM­@x•*'—ÔçË —”¹Ø^ൠf¯[°¼‚•L‡uº)÷¼gvœZóÏ2 ]>â€jżŸídcè¦uõËM­t|â¥$À3 êªørAZG‘¯\&:b$©QP/"AGrÈõëBÔñšŸ€‚‚%– }˜à=ŸRdÈ“rÓ<%éY˜¨2³17Í"eë´,¹Ü› ôé?É)jï/Þ![‡ŽùˆC ?r.‹Áª9Z]Ç™¦†º¹ÒC´^gxœ‡ëõ+÷êŒÆËý4|õáï÷ïŸR¼¨†ÿ,á=ª…ŠgQVòfÇŸASˆžÓQª‰vÔ{‚ÎÅo«Å ¢%“þ.P(@AèlËÅúv2˜|Šƒ4q>륥CA]Lx/œ›ÅŸ'U .ŒCS Á^Hß÷â(ßÏŸô(Wå„bt£zìZ†>Üá]5®0Fl€x†ŠyªïˆF Da ö> stream xÚ½WÛnÛ8}÷W襚%Eê†>eÛmÂÛìnÜ}ñö±Y….©(ÇèßïðbWV+Ú 8¡HΜ™3—P”!Š>L~_L^¿”’4 "´¸AŒRÂE„bÆHÄS´X£%¾RÛF¶oë²”Õz¶*¤ÖÓ/‹¯ß Ö¹ºœqÊB†YÀÌ× õJþXL¾Mˆ±ÃûQ,£1Z•“åŠÖðñ#‚Oi‚vöh‰˜ r®&Þ믄ˆ» %Ø…‰X|ÄápDz„†%‚âÅFy¨ñÑGÁùñ‹îTï &øíAÓ°#DDxpŽ^1´ˆq’>hï”^5ùm›×ÕÎx¢Ç4c) ÂÈ]x²!à=&˜S¹žÚu«ÕÚI7uㄢβ¼ÊÜ«)Ãî)¡ÝÈÖI²QNh¶•j¿Êã´ª¾žÎÂU«öÍâô{}V86tà°D! Cçœ[ÙÈRµª‹90Á¸[óX©t+ËÛ}Žt#53n£}ju«ãÓ‰S|"NÒãquH)ÞÇÊZ;t¥«Â€H §¡ÍKE,¢q=‹Üƒwšê·î6ªrZu ÙMƒKïÃv[=Æ(œ’߉¥Ö¨Q—6 dÑAß±NØ·Œ%ßݶã«fív2U)àÔpBðáJÐ/Fßêáþ•, pcòeê•;w¯Ýx¼G¾7ÏžáoËx=nÀ<79ÔUïrÅä˜Oqð0Çyåƒ?`£06½âQy¤Ì Ç…®ŸRï©ONè†ÌnŽ€å@À$W¶ÄÚM¨ à |Xï}?$AM†öâ?÷\½´w#÷Xt°ìû†~ٻ𫳔‰“wuQÈæDF?Þ^×Ù3Á5¬Z’gT&5)LïÆ?^íðpô&)Œ¿tJâa@Bš¸¸èM½{ÁùSÞÎ,›×½drƒ!‡ain»§¹{z²âaŒ/¯¿ª)L‹&±Ì˜ty§š»\íN8CP"húsF%NBYòSF¥Ë;S ¼ù¶píûž<—;ó!ï·’±êøYËLœ29m¼x1u}F¸ÕSÄÊvº3‚γJ¶ÛÆ÷Ëø~—x9ÔI;àû—/ô*Ša®É¨úÚx¥“ÎÞñ¡¿h²m à ðç0ÿï…S{:r"b|ñk8!'ÂqNxäÿNÓËb«žBù¿ßÿ|G×[¨p Úú\ˆº]×Ûvœö‡ÉÀi¿Ëu~]x­ÊUúMàOŸçóA¨Plþ¬·¥Ž endstream endobj 3104 0 obj << /Length 1417 /Filter /FlateDecode >> stream xÚµWmœ6þ¾¿)•ÂV…³yGQ?\•¤jTEivÓ½\^–†—»^~}g<†… ¹»¼T+­±ÇóÌ<ó3rƒ¿®~ٮΞz܈í8pc»38c¶ëFȹ¸±±ÍŒ “;ÎúrûììiM¶^X.cÇÜ’®HÊߪ$VZ&m‹›WLßñd»ú°â0eÅalóÀ3ÒjuqÉŒ ^>3àU×jkex Aè¹0/ÍêQÞéHÂ)ÎìPcs lŠêP»›™j(ž ]™›µÅÍa»åú¡ù«XûÜl*ÑI°ŒÉg6óœ/ÁDº{ ößö™KÊ?m*‹CW4õLÿ#޹#Ãâ‘íFá vËu]s§-îÛ Ï}º³y%êµ™]‚w·¸ì™ïpEo‘"ëÓ¢Îé©Û Ú¢õþ¿[[ð/$íhv4^­»"]sS´Ä®™!,DFàLëöª~-Â_0G¸dŽhò5óYÚ42kZ[>cf×”ãìДM~óBŠVÈ+A«?Ó°}ùê œåƒ׎9‰~ð€¶l\ÁÐû&£ù®‘4CäìiÈgô÷µ-¦.†[:µxýÊíØ÷¿?ä»üt.óiã:f×Þê¯;üDŠž¬7·˜ΉSo7'|}«9ôó‘v§ÂNMæÙœkW‚en¿:pàêçU)x† )…LêT ,÷}3){1¼¥Q‡=ô­È†ex3‹$×|Üô9ðÅz°Dÿ~=“’óFݾº ¤r/`¸ùŒa`Ç‘ç`’6ËïMNp/63ÑÛaºÄ‰¬ŠZ¥|UìhT@prT#³ÅSû¦/á`¦wt¨>×Ðx =×d°™D€¢ Ù”Ö˜Ë&œÓœãm zäE=ø,ŸäÃSnÇY`Êï?×q@NýŠT¬©Úªx|Í\op¾Nˆ-¦øAë…D`A™ÆÉmC6Ÿ_vŸ¸P ×àžeý2Úž™YÒ%t õh˜–%½Î Êqô4˜|"C²/°FŒW³Á È´ˆF‰Þ"(¬Hm¬âãÄé×{QŸt¤3H.ñXµ¸Ýðþ¤ð&iWPn;ËÄ.éKÍšDU®¹0}YòMäðïìP¬ø¤Oy/îáb¨Nþ­…UŠ:Ç4Ï)‚Ø'°bOK䣴kô3ÕœQÝE)3*?lq•›Ô™ÜTâÓØþh•ôD_X5R¯$åaŸ¨zÓÞïªý‚ýŽ3GÓÒÚ®)Ëׯ•B­_08‡ÔØ×ÙØÈ(ã— éâ¸ækæ°EïF®ùfɯx‚-˜obÓ-E.þ%Qìsð¼D_~›ø¿/ëã¹õ×¥™_þøæ‡Ï^:ôé_Ä¢ªhÓ{ÑéZCÂÐmKY´:€†/»¾n;Ù§]/‡=([”eR‹¦×Q¦RÅ}R Àh#œ—z–S!üìȹ1L_Þý8mèíŽïŒIAðTñ›`?~ÕJñ¡/äÐ2%µ6ÀA* ^Ùh¼S…A¶œá¡Áø6êtT endstream endobj 3031 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2255 /Filter /FlateDecode >> stream xÚåZmo¹þî_Á= 8äðí`’‹‘k€äz°SàZ;@×Ö&VO/†$¹â~|Ÿ¡DÙJ,k“[½öCœÙÕpøp8¯ä:CYåŒ5Šƒ¢‚ÊVqŒŠ\’÷¤(±VYW8²1×xˉ” …×+&>û,o¢ò¦ŒNÊ{MAù,£Ù¨È„³*%avN‘Y½bEE¤óÀ1 âˆ}„p¶Š¼±"< c€Ï2c@`™©,'áyðE'Hñc„\"Œ¢dˬ4Å2ï2Lá0Y2EdeMÊeÙ r•õeÁÐ Öf~EÊæHBáÌ$eƒ lDGÞ‹ÖÊXhËä26*¶+)I±[ýš¡Ë‚4ÈAk1" 9s¡T ÅÊ[›0¦ô.–±P»'ÑmÀ–Ä,ø°„`M‘—Up,¸üŠ%„àdD´*ÄèU€I¦Àþ‡ÌtË*ala,K6°h²èªŽÄ2t ²h¢-«MbIø`A1sÃ’c,™0"»ŒUÀü’)6ˆå%[0a_“ b5)Â8Š. *&üÁ¿üö𬇳]edÊFf‚•§ìe'ðc6¦`cPEÙƒGÒ¼òXm^¹‚¼[ùV™WÎ3¦³²ü$”˜Æ@L0˜[0D±,䜌ø~Kb!5æA 0CÙVÖœeCÈÀ(ŒÊ™Š}Á? a·'êáЧjðóßÿ!\Z66d¯ƒ#5½ß}÷ÝãÜ>²vXn7nN¬=,í Ü.jíwãvÙêkíÈÍQËtã¶>jìÜa¸­ÑððC0“Ñ™sGnD-~·Åý|6]ªãc5x×ò°Ä2ì¹D¾Õ\ÜïW!ÙlØ<Ø\eƒµç:&fÄI+_†7†ò€y?ÍgWgíR«ÁO'ÏÕàuûa©6^ÿzÓâ‡æ]{4xxít¹ø]&=œ¶‹Ùíüª•w.¯Þ½j‡£æûÙu.0!Ìdû5sŒÍÂøt:AÚù*1 ž’˜ÖWÂâ#DeìÑàìörYž_ަ¿ ¾ŸÍ‡í¼ÌkÞ þ2x1xvNåA ^a‘ÈuȵD\‚û‘+™Sgb°=-p¦?Ì^Ï6ðO§o§z>n¦ï¾ýVŸÞ\a ú·ß*õè°d.“N€f½Ó±¤÷¤#´`¼˜ÂNhO‹æ×þ`p$Ø< ›uBB&Ó’ ,Ìn'£Éi;¼½ê a" qYGÅöp¢Œ@õˆB†ÃWí²9i–Í}0ÅÙܹbÎÅ£…~óC^~ŸytÛ!º»Ø‘ÛG¨š]Wn‹¸g»âæd»r;†{p: 7¶3ø®«´Ø%8iGnÔ™Ú}¬“»¨ºHï‡Ø­¨º;·Bl¡3úOCgt¿#t†(c%Òšð¦T‰g}³¾ÆYï+Qú*Ðoæ5ªäP%‡*9TÉ¡JUr¨’C•ªäP%Ç*9VÉÑö™˜HCE*$£¥)bq:)À~½ÛNÚ·ÍíxÙw´ pK´…!`vZ奈füH¬}1[ê3Ò’Ž(·[mQä[¤ž€H 7…nÒN?Ì››ëa$äfégcÐÕ¢5©ˆ»¢¶y7Œ×³Ù¸Ç4-ˆu­éÚ'ÿùÕC9†‹ü'ª÷™7'“˜>&Û‘Û1éàüA¸m­õÚGþ‚œûÇ‹[}/ænfR·›‡¥}r¼˜êy\ªçq©žô¥zÒ—êI_ª'}©žô¥zÒ—RŸ§xŽXGƒj-—Qry„ö Ñ(¹Ž%Ö³ÙdÒL‡=:»á'Þ òN aÚêd67óïù|ïØ6§$^ËîHa,Ÿr0‰ïŽC/gïÈ"iÉe}Ed“\8¹½ˆÎ¥!‡Ì•â“ÑrÞ¶N³ÐãÑby(PÖZäS”í>Jo“I¢PðíÛ«æ¦Ï³Yô46y䳬,¡§ÉN®$t üÕpXìYé­Õ-+ë¤ü°«ÆüWÄ!=|0ˆE’TIÇüH¾În?ÍŸùsn$óCwŒò‰ ‡á†v-Å®ÜȈ)uÅíC(§ݸٓ¦Ô·CcI9†›²ÎÑuä¶r•óàW!rëbèÊM¾À_rÛy¿¹Wt|üu ÉWX¿«!ß”#´õEå­¯bûý„Ð2ȬÜ{e9±h!ÂîS£³›f9jÆ/&Xíºá´ËëÙpñ±{Sý §‹{o1ß9,FwnFn³¹+7‚|jÚÛ#@gו›¡Ÿº2#°íºHÇòMÀ= ÿwÅ­ endstream endobj 3120 0 obj << /Length 867 /Filter /FlateDecode >> stream xÚÝWËnÛ8Ýû+ˆt12P±¤)K2ÐY´iÐô…ÆîÊÍ‚¶hG3”è’RÜü}/r-Ç™IÑM\÷Á{ι¤m‚Öˆ óÁËÙàÙë4GÔqy>Æ4ÐqÐ$Å É~¨”Ñ&¥&“±ô—0K]nšRÕ=Ýx ÍQLsœd#þ>¨™ÛòcFAUñ…°¤…]¦¤uÛ͵ùáçH¯Q7½Ï)z+~ÃéØþç!:é.yQ¶¿Íͺ5¯Äî¿©[l­¦÷¾~øüî݉߾oóò‚«S“¬(+÷嬣þÎwOø¹ú`{Ý endstream endobj 3140 0 obj << /Length 1366 /Filter /FlateDecode >> stream xÚ½XMsÛ6½ûWp&‡R3&ÍoJi/n»i3iÇV:íØ9@",3¥H…í¸¿¾ ,H‘ I‰›ñA Hoßî¾]Ø1V†c\žüÎ=»ˆ¦­Oo,ßqÀ¼Þž’ì횬&®I­5å÷ÅÄò¦fÂIJGGÅí£¦†åÃ#üÊS^¼˜X¡ã˜×>þÊ}ß%–a ÁÄnŒxû¾ésÓH‡–.s (˜…!‚cÕ‚Q~ë„ΗS…„fScÛ¶á•+¶ =¬êhŒbé*'¼*é÷4,R†Ý¬bñ‰.ym¬ Zk,á+/´ãPEÄy¹ªÖ4ŸøžÉ»Nîÿ8ÝÚþT9ý‹:­‹ûtÈ\Ë÷}aöêK˜¹‘y>²E0ÀZït+¡Èà×Lað0ñb“‚Ïð|pYd~_ìâèóByh(„ˆuäÁ15¯<À«„»€¯Oç…BÁïi‰ÃC³­çdÕ  ×t#7§yÂÔÙ¹ÂrOàZpÑ€x©Gölêu‘¼¦w¤Êø9cäé'k$Hñ¡àç Oç÷„wùf*=+‡ÝU¦È[ !ø¤"àeJxMïcÊï÷qèÛñ,@ä¿Ñƒ¿§¸ý?6U¸eòÀÖo Ñ·.’}~ŒÁ¿âpd`MC³¤ :¹š“0` aü8±g¶¥æÉrI7ÇENq‡â'nÏY•Å~]ÐDË©’0NËf2’“›¬àÙN Ál¬jÉmMn"¡‹G³“ÓG;'kÊö(†õéž%dz´ 0äµÿ„â«©¡-5Ù–©r²¶è!®9‰´‹Üoã6-åT BRkD^U†?'ఙ؊!]qñÍïª,Ó„~ÕâWµ¡;伄 ‚N7áÚõ…Ði¤\2è‰xíªîÜy­nJ(âŽP&méЖsòMu§/8K¡²Çˆê4`âDaõ¶ºî¦X õ±+Zƒ:Jº]m$‰üÛgÀ€ã"ç’òq&»NìT@AptWkåãÑD<ÌgxÇa\clt¬±ó”±Š¾*Š2I¡Y¤Ú¬Q͆>R޲ˬXL·¦6¿úðf$\0KöÕ˜”ô´.Ç*y ZõfÕ†¥1êïA)ܪ»þ¶î~k¢ê¾÷wÈÌN·w—¦ŒÅzÓöñ^‘$­ØAT3Lõ‚ãc‰+±Kÿm…r}#èz©m ©§m¥g£Pßx÷îْ늊r®«D_å×)¶—ÐÍÍ‘-^X2(¹ ^>÷ßäY‘gO=–âÆ Z¡1Ÿ+Êôµá8&éú ²ßÑœ¥EÎÚ5<¼IlëFš×½ièü­ö/yq®û59@ÄÅ[‡ò‚\âuþTë5)ŸÚi ÍüÙS£=¯vzQ<)ª}gQ ó¤1¨~HYº¨X7`ÐúšÚæòB4—U¾ä’}ý?¢°µ‘Ã0îþáÖs]7Ž÷0™áÂim}oýÃcÐ —p ³ë¸ègo§Ÿ€Ò’÷Â'Á2ß#!Ý…Rc£¤wÙ8ŒvŸx )±ë!)AoIÛV²[uƒA4mwƒâ3‘dòóa‚ÇÕ_Q°ÄK·wƒÜé›Çè³êÕÏÏ¡Œ¨õxK«ëë­¡ç˜×2ÖbWé v»kœlºkx”¢%¦‡S2öàsŒÄ}}ÎóSZ·õ_™§û´»•£ÿû=mGÉÞÌOþ‚Ñã endstream endobj 3164 0 obj << /Length 1842 /Filter /FlateDecode >> stream xÚÕYÛrÛ6}÷W葚 ^uiÒ‡4i2i3m'qfÚqò‹°„†"T€´­~}w±àM&%Ñv<ÓÁvqöà`åV#oôîì§ó³ço§óÑb²˜ÓÑùÕÈ÷¼IMG3ߟLÃÅè<]8Ÿ¶,,}¿a+înx¾–c7˜9‰=ÿåùÛÈo¸pCÏ÷"Çb|{æÙ©Êÿ0_Ü@3žÀt…4Ý—À÷Zß³ֱç9ïx~.´.øk)U"2–sýÅ‹½æbáÙïZ£óÃØÎçhcìFqäÀ?ßcßÑØ£Ô½DGçNe{cçJ*j0k»½8|Ó\Dç\ì5=þÈ…X/☜O¸×c˜”'c7 CG^ŽÝxêüÍ—9u “dsæµl^üN*Uz“𯳗qéÛ·\X¹/p¶T@îuÈy`öQÂÜûÂfRQ L{?ã8öñ êJ‘8ôjÌã`‰p·UbûsIÿ·ŠFEP‡0«6WÓ„åì472©6,Mw4Fñ¼P™î4|³m^²ð–HFñ Nˆ;ß[¦¼»ÆgVa–)‡1Áߦ ´r”ä½ïÀz°™á\t|ÛÓkNV Øå(O1'i³€*o½OŒcºGE1ñ¢°BéŠ ¥@qä7PÜ6JWE Â…=‡]dªëo[Ð5Žý­1 ÚÇTIZÛRRèÏF½¬;Þ0æP¼ÃEdâ=31ƒÁe¼›'eèÏ(ÞÆ¼Z³Ì„ úëä„]*HhÛ]\3"©0³¿Á'8ªÁ'{aé`—ZÖÞÒöýHÛukI£¼ú•o€ÒzEœ!¢øÍ8QCŽe©­ž°å’oó^µ'ºÔZmÔVMµö‘ÿSõXJíUŠrÅ_`¼Ì&,S¦5×ÔiDjЯÇpÌq=ŒU²¹ÁÀ¦ /J Hïè†+Œ¤Ä8¦FŽÝÐmËoëIôÈÑb³%Œ,#éÇvÉ4Ôq³ârz‚3h É[¦ãF`ñ{ŵ8ö ;€D* Bçíx¥«è¥ªvŸ¶L1°Î•¦gR­Sa¿¸c½CSpý¬åèÔBŸóºVÕ‡·Ïºw¿ðPÌ’Þ/_©U7Þ¼§æŽy\hîÃùͳB8 OLçX—U!$ˆV.ÂDG=ßcöK¦lM=á–¢Ô³,/úÉgÄgö,!kZ §÷r´y$bó@7± A(à{$}[ˆª›fU¾¥Ìjœií’†Èzwõ/Ëwö1fYݰüÁ¡éúuex¬0÷rcÛö÷”Yý{Ê ,Îá ‚Î ·§JÛhÚ -|§f™µnx GIw)ÓbÓÃÀ'Boý΂R÷ ¿7¡jÞºû+¯Õs¶W¦BfUå/vIÕåÈ ÝõYËö -«Õ€½t+‡;Ú!OÃ;l­&g”ÎðHB „88 .Ìàß>øÐkxyYÞI ] x \F¡Íâr[ +“™Û$è*³ Æåœ˜ƒª]Èd*W‚ëÇŠp]f[on<ʤ¨³â‘ZÝ‹;÷Úûd¿U‰';Q×%ÜØì˜oÖ‘êúiõ`í©.Öf]¦,kEá^Y {¨¬ €GB­|­°dêCøü‰Š!¡S iIVî¥øÆZ̬]Ý_«_‡i´MvwÊ®J»»ºK ‘`1T¦FÎÞ4lA"¿V‚tˆtþÂìû'ÀÆŒR}#«š³MŠŽi3qj~MëÚëŸÏÏþÓ€ n endstream endobj 3191 0 obj << /Length 1468 /Filter /FlateDecode >> stream xÚ½X[oÛ6~÷¯Ð¥±ZÕ]Ô†=xY¤+2¬q÷â˜"ÑŽ6ZÊD)i^öÛwÈC9’LÇNÐ~àý\¿ó‘²c­-Ç:›ü¼˜¼}¸Vb'‘Y‹•å:Ží‘»®ù‰µÈ­%q½húeñþí»ˆö¶úQ`S7Aj“¸áEcÏ…H§%÷òÀÄÑz@IÐ;9ëŽÎ¼&}pÉØtæSŸÌ¹¨ÇZøÙԪ廕ð¸ïµf.µ}JQì/l•¶¼‘†Ý¤š¤Aoæ†Ê:uüŒ5ç›tÍžwtQѲ“ªªó¢L&ž!æ\œñê*åÏ8ú+{ŽËY™nØ ã|hîébòÏÄU'Ý-PÂ0¶cˆy¶™,¿8V‹ïA°ŸPëNmÝX`)|èsërò»!­}4ré:vø h“p ´1È¢¤wv9 iàËéÌ%ò`+ŒIZÊ–’‡ãf¯®Çš/µ+¾®@;ÒÅ^Ù«MÊðB;îd|»x6·JëÕ«é œ#—>¶Ö\W9öWUŒ§B Y±;̬¾Ö÷Õ,²3>cÜ/áëÚIØÇÇg't¾¾Ñ¦è6¯«ìý„Í»ù‡ËS½ÈÓ{V‹ÁòÅ\¯Ù¶ òÜcb;¯×톕Sß#x4ÆbûuL ÃØÅž“y¡#hq©±²[5#ɾê É_,kƛǡ0µÉ«#LN³I@þ\¥YSÕ¯qT”Ø6×òH|"X)X7—6OòΤÂFùƒÀB‰ŠU/•îÎÑœ}vü ¢î[u]µ7E¹DNB$¸•&løÔ%…PvZqd'ÔB²ZÁ>—ÑfSÂ5ŽÐF7!w×E&+YïÉRXSŠz»v4¬’GpRà¾V°\ËWVâQœé¼°Á ?!ç«ÃÕôÕ*`V¥¤ÈÀ0OÝ[Õp}¼16,»de–’2Ei !•/Õ BÀ˜žÖò«z#Ðò-Pá…ô³ÛaÔ5ð/Òæz¯cÖ-:®MÀ E®[-2Ñ£@ÝNȤu‘^qfÖS³RòF¢ÈAPÁ¦MU3ì­Y I–èâRy¬]…t5¦Ç¹êbûýTU7ÐYo Ë›C!ÕT¨¥ t¯$‚ï¬0„bŸ‰´Üƒ)ËåD?`Âè‚ܵv÷…Ì‹]ޏQŒMÔÌГÛÍž¢0JÕlk¤0š©¦ÒnÃEÞÂÓ.D"ÚFB…Ó]%U%{3·§ì`¥PÀ©̵€5WVåL4i™§uŽ3ÒÈD²€¹ºgìǸ}¶å1Éð1º£nÐGI>Œ¼Z™2(H 9 4:ÚXaËÁ.@ ã÷5ò#É^ò w•UƒJA–µ5ŽÅuÕòû’$(’D¢l¼Á ½,Y¿XC€Ì=|j† %ïìžмÎöÃ¥cÌœªoùpäq¸1ä]ôô4è·Ê£‰d".bÒª‰ƒR8‹õ+ãSë5UåTÞ+os†“ º´»<¨æ€áæpcr³}Ó± '.ææÐîJ‚=)çØáúÝŠöOÉŧ Œ éB®‰jßæ'—d@¶êƒQ'©oÞ¾ûþ„é—‘dÜG³É·ÑùºæÏyfþ1Mï°ç|C|dM[—bÆÛP·ßïjú®€p4×8Ph˜¦•aâŽ1úðþÃoá;Ãó<òð' ýþkU2yÐq6/r¸´Ô>Pª–àÅVæ(D^RqwI—êžiê#F‘M.~xÒËÐüá»T¿;÷=;ñº:V‰ôN©˜m¿«ö¢ê©’-ù#wÿÍ„ž'5ƒûRéúíjçã‡+ Ë—ÈÉò´À×I±y!5ò ñÛ°zÍþ_EãÿÚ+ÁšÃ*wØét1ù³e· endstream endobj 3208 0 obj << /Length 1674 /Filter /FlateDecode >> stream xÚ½XKÛ6¾ûW›Cdt­ˆzR zØ"I‘ ЮÓË&@¹åU#K®(5ÙK{‡Ò–eÚë ÒÀñ13œçÇ¡}gåøÎ¯³_–³g¯êd^–‰³,âû^%NJˆ—„™³,œWlêª÷®„`ó€º÷ñüÓòí³×ñ…YâQ?©Šƒ©$šùú WËÙß3Cß!Û3’4ñ:ùzvóÉw Ø|ëÀVF/ŠtíD FI±µs=ûm+oúU†DéØâ{ ¨˜Ä™Ø6lÙÁ Ùˆ÷f‡‘ï^ÏÄ•,óE§.kä—ºŠ_±Û­ŠR/ÊÈc¬Bí#K’y4ŽPý—\ä]µé«¶ÙÓ~gÅ^Hu„z!¥È~­M C4¾WBš¨Ãª£:Vc!e±—>¶âÖÃ-ʤ'”yòd¾ˆ}ðqˆß5ïïÚÇeÛá ¯™¨VJöã»OµÂãcnÜ]t§LVÔ"^Ç£ ùèǾ$Ud¡&Hàë¥Ú™°•ÖÕ¢k7hÈÏøy}õîú••´f÷¼{ĹTã"o‡¦—¸vQ°ž]À±JéxoÁ¤G¶ÖCÝWji'O?.×ó<µ¼°8D2“9WÝjXófn/NfЙóuR¹Ñ~f¤AºW¦@àçQ§[9føûü] P˜ˆÃÈmoÁg±ûÏû)ñ4­bÐ9Õùq†Î J2‹Ü?K–÷m÷gUƒßþŽËAè ÞnÖXÿ(3‡ åï)„aôËQ,ÉkÁ?úaÔp±§Q䮺vØTÍ ’)ò3WÖ®: ?õœ¸•Pz:÷ öS«-ŽPW ùœp‡3ÔQàDù€dî—»*—@¥ir¦ JÕmi¢ç0‰‹éÁ -_i‰¬¸b¬ðÀŠ0sß”cÅW»«àâP‚é˜Ê¢ÅQÙ±5¿´ál·´KI¹BlÀjÑâÆõ²–ßvk逡f¨r/l †Âz>Á¿x+¬ŽÖë³…¹J2PCÝÛS,ðñÏN!;êvUåJ¡(0éQé`£Äo zA–ðZ ]/›4 öjV´HÕ´=Zy>t8wíP8– A$2¥ãô¶Dýª´º:™Gð(ÖKÜ9äµÁüîÒ±FNÕ·ìK1h5Üò.z|tu2‘ Ä{H1iÕÀA)ðbýJÿtzOU9•÷J^ÇE•ºÔ\TcÀ ¸9Hên¶-ë4wãý•ÝÔ\I@ÃêµnËQŸ‡ÅS÷ý‡wï,Xb\®êH¡ãSÈ ä¶%ƒöQi¬Þ±÷ȃ“-ëÉh%²7Zª£6Ûd–)S¢ `ètíÌá/pÛ¬Vpƒ.íúùôõΤ²kÝ×òc@üªÛ—ÕøÖØPÈlóh<€Xà"Ï!¸QŒé= BÍÿŸ6Ä6±u°{^pz <¡¾“v3Ý Q`ëG8^×ßâ ñC½±ªÇzWLñ¥²øÔÒšõ]•sq3-¹­wTà›U½Wqò¥§¡åy†Uø-R¼äºÊ›Bh“›É•¾­òqrX³@ƒË‡O–¿Bɴʼ0 ~TýÛØâ4:Öíd©û¥êåK(3oF÷²ÀºSîÌuÇÿ¸èÕÅŸ©w’õQBŽe¦Ú6ý. o>¨@|{\žµ‰påuúú²ªŒè&V˜{Öd_iþ‘!“¿NxiþÕ‹êd/ ûw…öó€-&*焚r†~ü‘Àˆp°IÉú sq¾ÉK‘Æ:[€d§FÞⳄUЊ5šÈtÈzª‹³Ã™É…Dþ9Zà€3ýH?.fþEÖWôþѪÞÕ‹n\ñò™7mÎd«>Êi˜ËiÕ«ÏiàÔ¥tn7ôYØýä/¼º¹ÎEÕ8†Ñîyƒ¾²!â«åì?ÿ´£ endstream endobj 3116 0 obj << /Type /ObjStm /N 100 /First 971 /Length 2144 /Filter /FlateDecode >> stream xÚíZMs¹½ëWà˜\@|t£Uª­òÊeÇ•MeKö!‰ÊJ;JhqK¤RëŸ× AÑ–(QöH¾ì…ÓÃi4ÆkÌp`\JQ—cL®&»f³š@.*AÉ¥ìŸê27ÁÚT§%»Ûì ó‡ê$Dü‘¢’“šMÈNs5œ*›À®æ¦\\•¦,½5m…Tšzuör†‹5@«˜‚µÈ [‹ Ü©Z‹ à™¬‡ÌjkQ\¤ÜÆ Ë¤6R ¹¦‡~%ú XV±!,×ö”`¹¶~‰\ «~Rë>HQÍ2ºLÔ‡&{ $i#"´P¶qPuj–›3³=e4KÅ,3 QhOñ€Éì1¦¡ˆaf<Ð`½1~j›(ÆlmmÕQJ }pu®µ(숪µ(ÅÑÊ:"n- B¥!¨Á‘”¦‡6y4Gµ>Ð9çdÑ€a1‰õ!ä¸4o; ·éÃMWB4˸-mXQª+©EƒW(Û(5"tÚ|à§HnâJEÐPVV2b®ËælI =~„Zh¤p I4`jˆfx®b´¢ƒ‚ÑìÕ¤jƒ¨dñi€1#R[ÀÃ[šÙ*ÄZ(l[0g‹;Md0mJ" ‡¹µ9Dôk2¤„8OõB¿–¦814=‚ãµØ*€ßc°‡Íå³ ­ê*£yNXf•mø •-|’-ÙBñàðð`òÒ`¥f,éc7ùÇ?ÿeö|¶ÁRò‹èòz6{ðÓOhõ-ûjOXÆûi'"oë|?mÌ5®_á~5¿\ºÃC7y…8f¬ìÖìUA„ÁÝ«D.×~c!ᬟ `æ«‘ ìÆ'¿^ÍÏÞKwâ&¿¾|å&ï†ß—nÓï»Ï¿ x0ý8LŽ€a¸\.,75c“ãa1¿¾:«üÒþûÛp~1ýyþ»;1¥-¦÷èhz…Ö–V×_\^Îaíd•W ÏWÝ6…ƒÉÛëÓe»ÿåâò¿“ŸçWçÃU3ÞOþ2y39:‰íÆðœa$ȾVó{Eœ'%X.¡xҵ͕oÝäõüÝÜa*þtüáÒ¿ýmº¼˜ÎÞ|Âhÿl¾Ùž)l›™ªµM”$ò ó·§u[¹Okö ß?‰vVoyöí?´˜vª>ðžÊLêYã®÷eZÛNxûæ8l!Ž˜ð莄—¿#áå‘^õL ¥ì 6çT¢Wx'eBÆ«;3Þby>¿^ÞÊuù1¹.ß 1øpçfz—6òrÐ=µ±ù{MòÛãVLÜ:à(e½Gsè€˜Ý ’¾=tˆžF¶×‚tA»Pׇ.Ä.¤.ä.Pºeî–¹[æn™ë˜‹ö ³ÊîÕ …}ÈâñßÎÀ}9|˜^Ï–/‹éçíðýÞe½ ŽÙ ©Ù“ @sèϧ‹ûñPm|”‚ïÇäx£Ó(¸<¸òNPFô Ê0©Ú1€Ø{” û`xBòŢѣPv(H<‰îózXÞ¢v߇„bñÑjÒš¼Õo„ 3 V$¸‡SÞ‰äãÕüt|dÁžŠ%Üý‘U|Ê»ýñfñz6?ΞI ^P$G‰@d\¹ðN$ÇÓó‹ëÅà@Ý%(‘)}+\¤Zw¯ã“!DñÙŽE .†€€2£¬»#ãh˜Íã£ÈØ:QEÐ;?HðOˆ´Åùŧñ1DÂ%Ù‘‘¯FM@UBæûV뻋Åâz8𣋋Ëérß1QÁ!ßŽäŠøXvÇéñp9ý4> stream xÚ½W[oÛ6~÷¯Ò£†ZuW‡>dkR`C—8{q‚‚¶hG….®(;Í¿ß9<´cÙ²sAø¤u®ß¹ðеæ–k}ü1|8¸•:iäEÖhfq×uü ²bÎÈO­Qf÷ûfôׇó(Ù"õ“Øá<Ašè²Íä É®‘¾^/Üâú!0Fž5ôbøÓ'ök»îÃÆÃÐuÙµë¹dJw>&>+Ľl”ùÚaE6þÑ^Ä„=ôÒ˜¹Í™jéPÏpX)Ú&ŸJÕý·Õ¼½íÕª%éÏ×nè ¥Ä½‚·‡¾ï³ßhy XVù¥ÄÝ ©4eŸ¹¿£›²öV òµ¥¹öOsk1JÃð«D)3R(­‡Á ,G-м=ˆ˜ùtb{ž@èB'H8©þÚÔóF*Ô a¸ZÀê±L´Òüs—¯á‹ÝŽøqa˜›©ÓÍNÐÌÇOÒ<ºÍ1XQÈfËjÚæu…§ˆ-•T$ωAŽk5 Îl/PêŽ!(¡ß½,DñmMJYe²¡½jE»TF=@àÅkðQevG &öCFrÖàF9˜¢œlÀŨ•˜r‡SÀí†_«LHå{€=JØ]#0‘G‰äG| %-Tý’š]…äÊ)tKªäžŽ5€†ì»œ¶Úï­ì §È3hQç=V…„ÊÉÓ‰ "ZÙà­FF¶·5¡úø¬ŒKRö‹ƒ¶Ý‡ïtO ݃=ûýs´ {¤c8-Ä#ô\ÑÁZôŠÀ»5é;3~œ6¿I8²¼|w@^ÕêM”•²™Ë7O-'J¶OP58 ~ ¸È7ãf莟rkZÆ7®•ÁGhÐðWbÝiÒÒ õâÀ‡}a]þÙk;ng¦Ý¶s׉ÀÁи«0¦¦Ý1) \öEÂè凉¹Da7}•‰Æ9Ã+„#W¹ {nqúo¦¯< ­õä»Dži{† ¬x änÐ3ÂQâDÜ´íÏRM›|¡|AÓ&àº%àú5(˜‘sƒ€=É{œE+"ßjï}cåî-s¥Ä\öÚcx|ÄpfÌ?„__-øŒpgØÔ<†Z¢÷Ž(.}ZõE’Ñ^;…›MφK}ÿòkßÌÍ>çå…Ì–Ó>¶^–fûtGþoO.å²íëúÑ 4TAxüDËÉb*Nö=},yN›ù²”• ¯VM¢G’‡L<>Y1 §e»ÎòˆõqíB8ipí¸ŽÈCÆ+…ZEEµ€à­}ø&Ñ&@…šÚ[Að,PÏ0ç!ÇGj4êo¸ÊŒÞ­[‘D×fÁ‹ì)¡û×Nqæ[Ê—½-Û½)ØîMO°àì§(aâVOo> ‹‚A±¾È¨)uuóÄnž¸y0OÛͳSRLoi÷õOó©©ËY›Æ¢O)«ÃêB᥽…×)´Å¤œ~S%¼Çc]t77¶Âõ£ÿí|2-æU> stream xÚÍVMÛ6½ûWÈ¡1¢$’Š6i·h°iѮӋ›ƒV¦½*,Éålüï;ü-+\¯·H‹À0HŠä̼™73ŒÐEè§Ù›ùìÕ5ÏPNrs4_!E$I9”žäh¾D |ÛW}ľ_ô]õ9ø8÷ê:¥£{IÎI% ÕÜ q®Í"§èÇùìï…i„èA)a,Ge=[|ŒÐ6ß!ØÊ3ô`ŽÖ(3DªÅnÐíì·ƒ¼éh€¤b „F„ƒ‰œ Ç## ‡ëà„|tw²$ðmRl S|„ ˰¹[Œb©ì—y nõ—µìïegäúᦌИ>®…•zâÃiB²ÄáúAª²«¶}Õ6'°ŽðNbE3ÒŒä‚Oà ’Ä4“f)nà&…ZZ,iT±–^3`ÑvÙ©±Bý¯üÅ Û–o;š<[ÚùJwÓÀMË0f‰I‰…Ýï|Ô?†fzÇ{>:-†–㇅.ÌÊN_Ûá—77ns%‹~×ÉG÷¿Ù7Ç@_Çó_Â|QL x@ý‡jñ—,ûg> stream xÚÍWm£6þž_î*ÕH ØÓ—éõRµZ]ÕKî¾äV Þ,WHr˜ìíþûޱ!@MzMT­V8¶ç}<3c¬ ÇøeôÓlt3!®Ú¡ïùÆìÞpÇÆÄ7×µ}³Ø˜#;æÝì·›‰ÏW1umÂ0*/‰ÝBð ™CÏT’Œ- Ä­U[^›X±ø`†>ŠÒo‘6XMM™a¹Ì¦L?)[ÖÌ-Œ1ú’&¬ú´…Yî\-–ñeñ vE&•±Jâ¤P†ƒÐòˆ(?Jªd-Y<–EþÚ¬å>F/6° P,¾ÓZŸ͌\*©–ï"î`!ú¦L±ç–q øG‡:ðïs1(v†i])ÂZ¦‘Ý4þ*ÎDs~Tž{þϘ;F×)Ua|CÒðRÖï µKº‹ ù5b2¿‚‚â$»’˜u”qq Çe<_ñË ê¤ŸØ¦Iq’ÄÁjöæ)ʶ)G ÙÑöÀ€™OêÂ@a ¯|A sôƒ¥¾ÛE¶üSdQšÎç/Þ½¿¸»“rJS0%¬é¼6¡jtÒ8{¥öê]þúQ}>Dy-R>чšDZ_y –ÆÒ¤µof£Ï#·ô¸[7eÂØXf£ùcÄpl2ãKy53„! Ö©1ýÑë-Õù[ýôð!HàØ5Mý ¡ûa+Ó ›;h*»eImˆÐ ä—¡}*7Œ2Û…ï†)ȑхx (uø~æb™'Û"Þó/Úá´²¥ìѪÑ×Î))ü^D+~zþökòò¥Jª)Vß²‡Æ:û6¹ZÔ ëf´‡ yúí±ícÛ%:JÐ}éõcxÒOATwðöýííÐ;iœ§Ñ3Ï{OmÛ>µtŒóÕ.ãk{¨®§Œ•½-Ú <˜bÆë³†È¥£ê`.$͹«{¹ßvuLêQ³Ÿ7•j¿†{*µËVtº€æD: 2&r.T×ÏEôÖ1(‰HI·úQÂRŽë¹z¬ÅF‰ýKr¾ý^ýŒù}´K ѾUþH+^@“ŸáHÐaM}é÷_WëMÎãSÒøˆÈ+Dä³ ÁžBD°U!"ØSˆööïVn×h€àÎbxq/qthNYÿ$mCØ `GkH©x…ìâº7 Û?À¹}Zö†0üZHæiHF›Œ)H†ÿ‡Œ^“ÑË2zqT6¿‚ŸH“.Ž(Ñk"¥ k@¥ »¯‘%T  ÿo«í endstream endobj 3297 0 obj << /Length 884 /Filter /FlateDecode >> stream xÚ½WMs›0½ûWh&‡Š£ $@zpó5ídšiìôâæ@ŒâÐbœN“ßaˆðGëd2)HÚÝ÷vµz±ÐYè¢÷iÔ;>wò‰ïÚ.Ý#jY„qy”—ùh¢1Îw™ÌÉi4»–ábbÜŽ¾ŸsZ;66™m[>¦Œ«=«rp6êýîQ˜Zˆ®l»žC<‡£É¬7¾µP‹_,ùý)·Î÷g0Ѱ÷me¯=–¸W@-âBl®#ˆÇh'€• Ào"ÜÂCä¸ñàd ïTf“4z\¹o³ÔJȤ‚0Q.q28•ø!¥S´œ^_´™¦Çœ¶«LÏï ÓqðO9É« ª3‹¨l‡®‚ºÉ‚©Ô¢Ñ ótèÕ¶p‘FÉ´Úô ÕDUÉ.ðªz‡:Øe‘•ÏÓdžÊp—jùnø.â…ìê-[+DÛÊ»WÀž¬SòºÅt&¬Îr3G[“¸ ôPü †q6ÿ—¦Ú|)À{*—/D»öÕ—'þâ(ŒrÃøÅï}£‰1JŠ¥\¦AÍTÙÑ ²fû^¶“H‘Ë+wu÷ê.”¢EÕZ‹æÎìæqÙÿœC¥SsÕ|;kv/cÓæëgÉ|RŒ¾Ô¾ƒÇz1q@¶Žñ{9 £Ù»xr \Ó©|s_­b{„ÖšïäT/Þ˜íœo«YŒå Í:”‹4È7+VÞR¬ºÈ¯m½½ e‹Û_(ÙI% ´Dؾ ðÎFÅÚ.|cü*¶«ù×±k¤ÄÕºïô>ü¿<o,Oë€÷§N[œ{Ë}¬¹ã¹¼ŒúsÚ¥.u[ßZI´ ZWc8 e’ï¸7•`8!É"ŽÎ—Ã3퉶žªýkû\Á V endstream endobj 3214 0 obj << /Type /ObjStm /N 100 /First 983 /Length 2277 /Filter /FlateDecode >> stream xÚÅZMs7½ëWàhŒÁWãcKI­b¯wS•Ô¦d§*YIŠšH\S9ôÚÿ~_ƒJŠÈÌÈ&—{fÀëF£Ñ¯)k”JXc’ÐÖBÐ$¬ç7Ú ²Ž… |Ô,D‘ȰeíSB›˜XÒB;ëY2BSôG¬ÐÁðㄎyZCB§”Gxa´Ë_ƒ0&=^9ËZ ɳš5£2ÀgÈkAXËxÅ+ ñÄà,AJŒ Lpl‹Å¼!£³Q˜hó$ R6Ç)a’Ɉñ5FBX[ÃN|Í*¼C´f'ÍKF‘7@’½Åú„÷ž‡ÂcPl+aéàx6=$#’ÇÇ4‡Ûæ‡E6YÖÇŒ6…¬o…SÙsÄ2øàtÌØðÎ…,9á¼f  {Â&î°tïAŠÙ+É‹²`JÔYŠ^DÀ†1ˆèòŽÂÕ‘²/B1dË`GÞ`“´ˆ)û‡·UgTÉŠÄ@r"9Ã1“pfàA­ï¾V°"@ÈÆ&¨ÅH›d-' ‡¤E–04¢Öˆ£”p"á‰ÕóË.âC£ámˆ0ãøø¨zÛ,Zq|,ª·¼E˜B‰S<` {÷€Iå  ÆäËl?ŒÝ<`Þ„CÑ©åpÈß~{Tý´l¦ïêVœ‰ê§7oEõ¾þÔŠ‹#|bï?ßÕø0¹®ª×T/ÚÂ<óQuZ¯šõrZ¯6‡0¿û±¾šM¾k>‰3Vòû›Ìš,1š³Ý(ž, f;Û$-Æ““V'„"Ä"¤N0ªº¦¶®efSf6›™gbsT}×,¯êeF®.ªUßW¯ñ€m¹`c§p“NQ½7N&`B’ aê-ÉÀjïÖ—-¦¬~˜->T'ÇÇyêdÚΚEõ®úùô{þ÷â¦mïV«ªér²ËWwËæ¿˜_6Ëëên2ýƒw×ËzµZ¾Ô]h»¥D^k7x xÉ»"“ç õ2!н±2Aï$‡Ü;Qý³y߈êxqúÛBþoÖÞÈÓõ\H/ÅX¬O’OS䢑œ·ú ÝLWóz¹:q=o.'óóóõâæ²ùt®œ:?ÿØÌ®.ÿÞ=¬«³»,ççÙõ¢ps½â7ß|ÅØ÷§?ÿãüå^wôÇ“SA&⮥RHîÎIN›^kŸNÛ˜‘¿­Ûõ²þÕ9ª&Ëv6׫{•WJ¿š-Úe#oÚÛùhAÆA‘•‘{%'ì¥HT†Z½wCåéU3—òdµš|¦ã+Á|inÐ8²’¯Ê>4À4YÝÈé|2fÈ;‚ƒ:H¸%¡¬y¤“ùìjÖ~•ÖA¢Â"GR#ŸiJRãB$"lß^Pg£o*N‰Jl ‰ÿ§^ ã#Aé $úItR{߇äjv;>”„Íá²³ƒ‚²T¢¬êG²˜ÜÖ«ñU ’oÝǹˆ{¤Îm½¼®GÇâ¼Á®Üc!,¨:zÀ¬Ö—«ºÝæ Ìc:•«¥_~ýê4i‘.|Ba·XÏç{•Q¿emOLJj£T“µÏ@íŒäÊ.&©à»Ãh+I~¨ ¢’éà0mT‡R Ö¯’f(£¬ÄòXû¾6TŽ?*ÔÔÙ¿+Ô׿`Jï*áTí_\¨=-ÔÉ~y¡îJÉíÌTÑÏÏùÉ!½é|;æÿÆ£È6àÆ^³ÿÿÐ\ÿ8¹1Íj…b”/¿(ÁË…±A9¡Q¤‚[ÿñÕü$‰{Fy¨¼M"Èò É‡Ñ6à+1 Ô¦8;T§Oi ¶CåÏí”aÚø‡P9Œv¾eýPR(ã†î¥N(& íË#crü/Î!<;"[:î w…Ž»BÇ]!ú®}Wˆ>¢O%ëP!ú¾LèË„¾LèË„¾LèË„¡LÊ„¡Lì˜ù¬P 0 ©¹iÀ::”øf³XޝŒs6'¹0ÅcD÷î!‘Ÿ…è`üÇ+”‘ÁáÞG…óê5ÊHJ{A½^Ö“¶ÎÐþ}É-œ1o#¸‡[!qÑ{!A8SÒØ-«P÷áÀôâJ4É9d‹÷²â¾u’-%óT1½…Â¥ ÿ1ÊN6& âfÂý&‘žþ=zÀÉÆo%$+¹‰8R[ŽcTwÊí§dwóY;zìv%Åyî~Ÿ’Ä¿seÇ„žnˈñÒ] ÚFÉ¿:u]1íÁî¯jŠu`JS¬ÌŸÑ땞ØsìJÐÌFÒ}KLc+CHAO¬ )=±^$‡kŠm¡tM±>(‡ìŠ,]Wl”öŠž®-Ö‡ç°}±¦»úÀT޲΄¬kõPm0,?P—¢æ‹n ¶ÃNQ0‡ÑvøŸ†zÄÂ#ÖØ¡ÚHÖ†ÚÆD\¸CµuÐ2˜/èt=â¡ûéê 5í`¨é+j(<2ú }Œ…>ÆBS¡©ÐÇTèc*L7¹Qûbd„?£t\+àÈù\â% v»÷¿™ÝžÖWë鈉–‹J$6$ ô]&þFEéÏDb àØª×pìòßbD¼º‡¥8cµ®N°Þgʨ¹/΢¼$•z½s˜ŠŠNÜzè@œ¼eÏ5~Qe@œ6ÜmÌ¢ÔK±×Ù!‚É3ñ_ŸuPœâ+r–C€qÌö`Á~ÅЅ몀Að¨ûˆ&æ6 ¢7•ÌøpÊ#'¹S·=`üóí§wËÙ¢Ý '_‚é9ÕLÚUŸ’‰ìa´-nãÁÚÄÊÎß´vjcnë†Î툤‹ƒµµ–ü÷•ô-wüvÖ3_¯ûZúÁ{ùDûÿ:,•y endstream endobj 3322 0 obj << /Length 1077 /Filter /FlateDecode >> stream xÚ½X[o£F~ϯ@ÚJ;H6a¸{{‘Ü6YµJ«jíÝ>ШÅfl“bp{³ÿ¾gæ 6 ÆM£<Ìà9·ï;sÎÌDWÖŠ®¼¿ú~~u}kQe¢MÃQæ+…êºfZŽâRª9æD™‡ŠO¨i¨÷óŸ¯o¯"jÚ¦fë&Bù~‘³B›±}\üJ—^À…[Ñ›¦-dž ?š¨þ‡nS®cÃÔ&~óFÛºNf&Ž[VlÒç«4ÃÉ2ò#t«`|±úWj1øägS©U¢F&¶a=úÑ}?ÈQÓ´{©gUÁRÖÏCÍi¶ÞoY¢š)òMͱ7dP† ¡Éq¹k.™JøÓ<%ã¢8ýðļQš¤={´!g‘t¨mòÀ–½©æ¬yZ wH¿qË…°ïÒu´ bU„ÄwËó(Mð;JBX,¢dß+{¸>¨QEÁ"f9®)Ž«`•1•’ÝáºrÛ/YËmU’ŒÚ¶”ðôð ÆÇË\gõ5m—¦ẢûòbÖ·Bߢ|ÿ›ñ茛Úpž*–GåIðRæa…ÑöU?âbñ Îl(¬lÍþgO}6\ïÁuólw1ë†ÔÎ1Œ9Ö±ÝéÐîùP“O)»"ƒï¯¿Ží¹²R;÷êJí «,HÑ”Iõ åðw‹íòÏ|ı|›I_bþ-¿Ì¬)Åéw8XÕèE†‡ðãÝûéot<Ñ$Èx â•7âZ¼ô‰ƒ·­ñêmò²¥»äÀ²:ïóoþ3Ñ4Ká8-.øL÷òÅp&Ð  o=U0Ÿä»õV.rÍt!nXU±“1î¸ö/hÔ½¬ý¬ÂS„þE˜$I÷ÏØ–bôÕï[»×Íüê_‘Àp endstream endobj 3331 0 obj << /Length 894 /Filter /FlateDecode >> stream xÚÕVßOÛ0~ï_a‰‡91v;‰¶=01!M”½¡qK¦4$í¿ßùGÓ¦„®hLÚžìœ}¾ï¾û|E3DÑÉèËxtp,c”D§ˆQJx(QÄ‘ò¿ø3õGKÅ.…õ‹KyÇÞËÊSÐWå™M3Í”žhBÓ¡?3 ƒx¾ŸÂ}šZké¼R tI§>-uÂ…@¸Î¤ìÞ‡ºò‚?å™ÊöÁPüœ.L­ÚE]:kzÒ»A‡U­Á >›Ç×sÞÞoÜ÷2BÕ¸Û?uË:hrEc¿ó²çÖ“<Ùv9Å{÷(˪5#‚RLY6 qÀIÂvØn>>ùv|J‹…8aoÏ®_r;ÎU{_ev>–ÍdR¤MciˆújÑ«†D·lQ§íÓ ÃF%kŠªµ³Ïv¸¸:?ßÂÑ+)Öê¡H' $Ùþû9o/æÿóf¼GS ˆ¤®cA¶ÛcÈ@ÇX6”Ø4}± X*[]nnsm§¦ÂæÊgÍ.p\ÖϯÐi ²™§¦O÷ Ü™˜®§@_´Ãn½ëCö³È›·°eîÃvtº$é|ÙÕ¦ƒa- qQ»¨ê»—Hü‚šÉN †À¼z\-Ì·.®nÙîÁØ·fû4öõé@wwål67¶Zë÷øÀõø5g#Qa$úÑY´bžóFõc¼4ÝC¡ŸBÇ^¨¡¯¸ßiyþÜxV6ˆ¯ÕãB5-¸  ÿ¿qÙ ß endstream endobj 3347 0 obj << /Length 1351 /Filter /FlateDecode >> stream xÚWÝ“›6÷_Á¤…™@ °Óö!m“Ìtú™øúrÉ´2–mZ@çÜtú¿wW+|pÇ].}b¥]ýöS«%öö^ì½^|»^<{Åo­ò4÷Ö;/‰ãˆñÜ+’$ÊÙÊ[o½K?aÇ$-nêWt#Û­&ªoµéúÒôÜÒõ+¯†/çŲè:êO×xqH®ÏD%fNm°mbЈ÷AŠ)¶6G¨(R½9öf ݤ«>"dת®AÂùô }’µ<¥EÛ©Ó„Ë­ 3¸˜a·~Nù*²Qˆ/-÷Ïs¥Œ8“–1=4€üèµólã2d{“‹ü®ƒ{g©Se•óPÜJåýnØA‰vèÔZ‘ÂÖ:a™sæèvŒÚËVÂ}ºk×ùô´°¬š»0Fsu0¤u&íc”%¡tªóv=¡\8SIÿ)t›d9‰\lŒ¾aÆpx_#-å•òôÇûÊç¸iÊ?t#ê[w€î¾‘cÌØöZšIºí+0Íœ½…–ìúö¡p?Z鋲”Úaê£,«vüiuØv0“•»ÊÜíÓµ2“Û÷„Âñd0fñr½ø°H0ö’ó¨Æx%Ü+›ÅåûØÛTFlµôNV²ñ8< g@×ÞÛÅo÷öIÇ}=Ãshå,]Eyî¢uqÄYÏ z›™ùÇOCÊxì_às ²”Åeøro‰@¬ Ç×…åŠëÒû)~a„€Yªg¾7h­<±“(% aº7b>tIeÅ焎BÄg&æt™El(“ï¥.»ê8´ÏfG#5>çsc5Ò)DÊ#·ƒµãÚøÀ·Å åDôùu¢åÎÎÆv_uv&ÁÖè3è¤e_ 4VGÍpšæþpâF7ó¯}Õ&œ›N¬MPÎi1ŒµižÁh抺¢\áŽýØ‘µiÃb«{²™‚€¸ÿ·×ÀÇk¬&M›4ÞØNŠì¬Úö tÂÇnø7¸áj‹kǺG Zìå㧇r}û6ÝmØŸ2æE·ïYꛇG¢O£æ®ó­¹„sM06®ÇÇû{°Âjèÿ×oÞû¤¹ÿØ¿kËPXÈ„õ¥ØßQJ²$Ž t¨Æ{æè'E´û{fKè#ÿtúé· endstream endobj 3357 0 obj << /Length 757 /Filter /FlateDecode >> stream xÚÕVMoÛ0 ½ûWèa20«’e}xÀÖÛaô—´(ÜØm3øk±ƒîç’œÔv’6ú;I°HŠO4E÷ˆ¢sïÃÔ;>“Å$–¡DÓ;Ä(%<’H1F$Ñ4E3|QûA¨qš´Ù$¯ÚÆ¿ž~>>‹XÏÇ’hÊ!ªõ`\#vuÔ³ÖæA¨à#wN§?“¢Î³fà¹o…ˆ ip–‘Í[£€)Âcæbù ©Z·Y®Êw&08Œ’XtØVµ•Þ4Ùj™´7Õí÷lÞ¹¼wË…µ˜Øó¯öøŠ ºÃ°ÊGaÀŽ­ï ‰!ÉAr§ejBõs\»x§Sï‡ÇÀ“"¶aERNBÍмðf×¥pÁµFÖ´@§"CDŽ&Þ·½õ³ÔC {ÔCY$*´$¡Pkê¬÷Ê/ãžï,:‚Rùõ/BÛ+~À…ÆõµÛEéÖÄ® ›*ù‚a¨ã^ÈBE„Y¿ÙA‹vtµˆb¤tÐ>fÍ|¹¨ÛEUîì¸Q‡ÛÓ„k½% @Ãù(l-PáÄg¸ÛV·À±À¶iœ|‚0ÑCA˜î’»h’ûìp!<—æ†À§¶]wÙKYœ,ïWEVú<Äíó²|!‹N-£' :(R¡Â'¥« -—tå²ÚÊ­«^Ù@péÇ'ù*ÛGñάÕ8ë­dM*‹öÁ‘Û>t=CZMûÔn—fW”Gå´Z³¿Õ¹¦DCÅþªº¹äDKÑU'[6ãößR¶2Ê>ÏZ§ÝK_) nFéÆÕ ùSyW-‹d#¥Ýðäâ{%óP¥øŸ)¹£Ùaž.}ÍqWûa„량¶ãåI°oÝ€ „ f ‡™2xîÖ"kªÔí„ÛÌó¤é¦·ö³9}Óaìg6ÃnðírÚé`Æ+Œ:!Fò> stream xÚµWYoÛF~ׯ ’‡R@Dó\’(úà.¸Ek;èƒ kre±¡H…\Æñ¿ïKY”Wr ´0àîÎÎÎ|sÊwnßùuöújvrNîå"ÎÕÒ |ß‹bá¤Aà‰(w®JçÚ "1ÿtõáäLd;¬‘½89Äóת*æaæ®Þ¨ºî‘}æ›WÞ];Î }'Ø> Rá%YìëÙõ'ß)áðƒGyæÜëÚ‰A‡4Ž€®ËÙŸ[yû+[‘îZøž»D’{‰4´hVå;W¯"Š}÷}©]-ç‹À½Ÿ/¢$u‹y¸ªž/`°—¹k©‹UÕÜòp„®ê´¬³ÑUZu•¤÷ì(Ä©‹ð9(°µ±Åg"ȽԸì­êáõ®ÚfbíƒÕS·gÎ"ȼ(Ëøú…ÒC×€•až»’—ºê5Sí’ׂÀ$R¯¤9DL(&—7²ÓU1Ô²ãï^í˱âãd¤[æ‘ œ‚¢u¥q¹77kÙ÷¯q_¸«êvuR·xz‡vƒ­ À/O¶ëÛöòVYQ·x!=â…‡ˆýÛOüöæUhÐ%ñ}×ó<Ø FÃÈËÍë/_2ÇeÄëZéU[2MF"A˜±-i0‰~<ýÉX¹«Ûµ{Ú÷òÞvÇÊ¿üSL!ù /¿ ÁÃ+a»g0#¬ÞB!<0aùU+ÙÙM«Õ«9ݽGÛ÷×rœp‰j\˜ä˜†´s×É­ÌðpÊW‰¤‰4õ%Íf_4ë_ÌñØy e?¶B“∌JÙ¯ÆÇ¼ ¦%žÂGHA£Ušaÿ _g®ÉQoô²"ÿé­ö–¤WŠCúÁhø@£&Ò¤à“õtE~Oê¢âbk«N¯j(ÔÕX99á"{²Úr,œôêè,Ÿ•*@+Í©oŸ~<7SÀQ‡|ÆõÖ/È ÔæÅ€&ãEÕ¼¤áá­˜òÊâAœ#Ìöñš¸ØÎàðtQúM~¯Ö&!£[\òý@uü±䆫ƒa˜ ›rÎ;VWþa¦ùØÌÞ^@àƜåú ÷üeP{s±ŽªrwBÆ‘»’£vÃr©É$G¦‚Øìµ£‘C™Ì$JQ%WN`ªÆt@¸ôv›R ÄŒ)“ ñãžñdzÒŒ÷t„]Ȧl×cò³óÃn‹dмù"ŽcžàØüèÀ+e˶›y¨wÛDåÎ#¶©~ëÿ ¿íTâ endstream endobj 3382 0 obj << /Length 348 /Filter /FlateDecode >> stream xÚQMOƒ0¾ó+z,ÉèZ ý8h‚º™˜xÙPj ²Î-)°.ûù¶«Øæb¼´oÛçë}‹ÁÀàÖ»J½ñ” ‘d!éŒà„ F%Hà>­Ö¹ ¸ºVZ7þkz7žF¤Ç¢’!©ÑÜã åäáoƒŽzè ƒ!7—Ô‘}É`¦?Õ€Ú“è"‘? ”­r¨|ó¶ªíU«¥{ÊMtW•Y¡º&±¬h#!C':WÊ0…‰nª“©°Y1 ¶GWÎöYù™¬SÕæ«›¬ÍÎÎè0Ìd—킟Èq4-„cÑOŽh§eÿÓýå Žñæ½Èßš"Ózä1Æp½PeÛ¸úÂm¡kmä‚‘ŒåŸ¤ÔnS«¦YWå@î~%Ä•—n£¿hµU‡âÿ s¢¯Üɨ×d‡-·ªnØtö0éœ&>I½/‚£ÏÛ endstream endobj 3460 0 obj << /Length 872 /Filter /FlateDecode >> stream xÚÅ™ÉnÛ0†ï~ zp€Zá¢õØØ±ët#=¤EAKŒÃBK ÒAýö•mÅ¢Õ •>HR‡œùg8&ÎÊ!Îl@Nž‹ÁùÔãóÜ0 ©³¸w(!.÷'`2g‘:wÃy‘Ê_gßW‡‰çS9±×£¶“ˆ3òb7¢|?þ!|;¼þ¶×u7✅Ö⌳áÆo†„­!´~­ßF”¹Ìk¾v羫§†Óö‡o›eÕ?7rªíêö¯×³AŒNV~$',[eÚ[Ä´=j”dõ`,†ŸD¦Re6/Ëlï\ãF®+aÆGxY­îI H²{a2Sh7SÚôDæòÇrÕ 4†TžGD»ŒEí7> stream xÚÕZ]o[7}÷¯àã. ø1ÃÀ(Ò$ðnì¢H²hw­«Ø·µP[ d9Húë÷ ­Q­X²¯œ«¢}‘æ^ g†Ã!©gbtl(™*›ð¼ ^— Å*B1œY„j²Á;S˜Dð¦Ö,B0ÞAŠÆ $2žb‰Ï Ô'A/"eBjR1|Ó«&0KÛMH5‰D&dò"1¤’ÑGJiÈ(% ËàL¨AÚF ËaL%Cð$<#úö¥&(„Ø´Ð<Át I~Èñc$yi Bj À†}k]f!Á?¹özI  ½¦*ï„uåHè?!Lø(¡Ê Т4»J³ “•ì ¹ÚÔŠIÄ: @¾Ev†Ç!dé‹Ñ 1,HÍœò+Ú¢¸ˆˆÅ86±“¾@›Rã A }å$jÐ¥g1Ã÷%Ixàƒjk™ÐWeWBS¸=¤hØÉ0vH%†ûæX}óMJ†Cë+A#䌨’p€3 &úG r2°c]@™eF_¹6_¡iÁYz(¥9 Ý×(ä`Q®Í8øH.´wRGäb’o±['ÏÒ‚ …û ›¨¹¾JL¦OÜ|‚ŽRj3¢9µ~‹3)K¿bçTZüÁ ™[È”b`X1bþ—qWgrm£EŒ×f :/¡Í tTÄÒÈjÕÈH->«ø­¹“®”ƹS]à£ãã£ÑKsаJ˜×¯ÍèÇÿü×x笄ÝBßÌn./ß}óÍ#Ú1ÛŠÚ'óÙÒ›Ñ <»Þ6;AŒ3²z€w«þ·E?!ñ[=Àô“^>ú~1?{Ó-Í©}ÿòÄŒÞvŸ–fÝïÛÏ:ü0ù¹;½‡n¶¼–hÝ^w×ó›ÅYw}›Ú»vçÓÉóù's*/O®á:š,ÐÓÐ¿Íæ@;½Ív§e»•PW‚w*x‚ QRUH*(²Wd‹üÅ™£Ñ››÷Ëöüj:ûåhô|¾8ïm îÝè£ïF/N}{±ŸÁjÁ±õ0ìk|#ÞsðO‚7 è}ÛüöÆŒþ>;7ðû_^ÿ4³oº›ÅdùWqÁ0^ÍÏ»gÓŸÚ÷&Ü߬O)wWãñ¢»œ´¾O8QÌÖfA^µNª´?£YþTþõïW¯†Í|…üÚ?9Ú"Uï#þ9Ÿ^ ŸöŠ,Š~Í…R´ÙÇ>\f“«îzpB²J)ëW„8›øqBWÝâçnø ³Êu(%²Kجa½D•‚jÆÖ²{½Üe©,e#¹®,km û ˨iï•¡ÊZ†b›b ö~ÚÄ0\ =µQÖÛèbOíPPÒ|©ý[A¼QoVÇw â;eï—1öÇ.Ó×UÄÑo©ˆk¿Š8Rë|ÃÑíá¿»Êkÿ!Äe#wíˆâ6ÆžÚ ÿÉiBOm”#̵§6!’Ðâ0ÚT-ÿé”á××Ö2%÷ÓD(^¹§¶çhå$༥|Ò?}ÒRÚcÒÒ–½ªlRIOmlØš¢·ic´VÊ¡j“ØW¥cé«ì«kufOmd9Ý­¸[› Çåa# Ÿv¼%ìø+ÂŽ÷ ;Þ+ì¶j»h©B™“·>ôåÁ(›®ê§MYòQì«®¯õbñV_¢MR¨öUF›Cí©àtÏÜWŨ\?ôÓö( Å'$ÿÓpc%"ùçxf¿ß,¼{†™ÝçŠÑÿ^ò6ËiC©Ø¡ÀÇxÏa÷¥Ÿ=ÿüÝ9xN—ÓîúÞÎ ‡=²Å]廵b.ÒFýóA”# IÜS›3Â|Om9+ûRyï J¯RÅø²:rì—-ç÷Å}Eìz¦¾Ú'_m a}ö—B±œvFþI·<»x9YNîE|Ùg/\ü>ëãVmöVî{j»Œ}¶.U>5((¹{A!g#OŠ¢W/E¯^Š^êT½Ô©z©SõR§ê¥NÕKª—:U/uª"WE®+drN¯BP!ª@*° I…¬BQA‘õ"Šô"Šô"Šô"Šô"Šô"Šô"Šô"Šô"м"EŠ9(rPä ÈA‘ƒ"EŠ9*rTä¨ÈQ‘£"GEŽŠ9*2)2)2)2)2)2)2)2)2)2)2+2+2+2+2+2+òª *%¶rO)©\0û¬/Œe;.Ï[sÐÌ'[†¼wpÖc0öÿT$ë‡vÃÇ\¥ÝÍÁ‡I¨!°e $$Érp RÙ>ÈaHCªˆ@Ü®V=6›‰ƒ#Ã0y7‰P¼î@ºvX6{îÌUþGcf j1†~ëì~~ /çqX"Òðî@LbÏOkw–V¸g7 ’ê3© ä ßÉ-ˆË ¤,óÀe>&Úuf¨Æe’ÓHÔXU‡üÁjm‰$dÈTé!Q]Ý™¡rt™Â$j>‰€Îe†b§$…V1†Ê—kÿ¦#WŸ endstream endobj 3562 0 obj << /Length 1294 /Filter /FlateDecode >> stream xÚåZ[Oã8~çWäaŠÔdâ¸IšÑJ+†AµÑŒºû`ÓfÈ¥Jþý:—vÒnéøØ)/+TàœÏß¹;¦¶ÐLíêäÓìäÃ¥3Ô<Ãs,G›=jÈ4 ¨åôY#)— χ̗éK¿Á­[:«[¨ÓˆKh¸X–IêáTç?ÓL8øÆå“›àqÐßK¹&šƒnkb^ìRuÑÓÞ9¯ñY¹ZÙ€Æè¤¢ ñPô.¨_DT‘'2‘ ¦²¯š­ÆM,‚Tîã6Œ¢„US)BÃN“ZN‹Œ0±XœÏi{9|ó€þa>ÿSï+ÂÙRpýñ—Û[iLà’¨êÓ'xw”‘²a–.C€Ü«ž7 aç%ŒÖx÷?xÿ'‹:¤ì Œ9Ú.-!1UU« i4¯ž·äGE»˜f ªHÍØ® U"ÐIÎR¿D&€Ü„–ôÎòœ¼*T8à(5â9¢c®Kji8ÕîÁ*Wok›äîï=X6°éh¶‹ Ï6RñS¦ê»X$—{v ùet”_Ÿ*cŒøË]½SZ\Rÿéê\:jM(Ö-y¥Y>æýä»`6< ã _:Š-@_Ä+özWÝÈHߊ /ÈѬîÜäï–!Nz×ô*¦Ò—"„XºLpæì¸x ?ÿ‰7u•ËʧcˆN'$ ÒX%0éAðÒ—»r,ŸV¹­²§OÆ-H1˜’çfÞ˜¨œÒBˆUzø¨'Euw8{ȃ¦,dþR- bÑfŽ‹Rù,€ðÁbo¡5Fi‘l\¹l]Ý×»p¼­×vŒ¡¸>òÚ›)¦îÉvÀæ:r¬Cïl ®Ä ã¼$ ovýíÚ™ÏÓ8æQ,}¢¶µ‡ß<³K¿É»4Ä7±Gà gu'pŸåÿûÆÒ~qÏs:ˆŸŠï÷ µ‚¼wd<2Ò¤n#»ÁÆÂùWý–×Ç«ˆ$Ýà æÝ†ü¼#P 2KÍû›“…¾¿$ñ¹ôÏÆßËï­Ô²á—×fÂ÷Ú{ý½M>)bʉÿõöÙÇšuÇÌß¾Úîüî÷îï‹ÙÉ¿v±!Ð endstream endobj 3463 0 obj << /Type /ObjStm /N 100 /First 1016 /Length 2711 /Filter /FlateDecode >> stream xÚ½[A· ¾ï¯Ð±½è‰)‰€ ‰á¶@ ±i \gQ v{ ¤ÿ¾5ÃYç°z9h²z½OßP$ER|¥¨† §¨° (äZmƒ=Ä )dµŽ9š6Ô e|½JµØ¨"­7) ³!À¹fQ Q±QÔ¶§%P¯¶q U[$dʶÕ³tµ‹Žy=dÉŒ5HÁVl^N!·nxo ÙV³ÿ%1¼ jÔÇ<|,4æ óð¾ÒÇSÙƒŒ%;Û{Imö ¼*ÞÀæA@²÷-9pi&°RK2¦$W6¹ ÜÚ˜WkóZTŒKéA¨%¬Q2NÆ_O™‚H³÷å¤mO±½ØÌA´–Pi{ZCÍÛw[¨¥î¡b9¬ÁŠí+ã¥S¨­ŠP¨šÒ&ˆ–Š1• €è°Eöæ‚·WŨ†&xÚ6|UªbÀ‚°M­Ù ¶³í¸ S»±ƒêt%cW%h{ ¥n«ÖUÚžö ¼=Õ 2žâUû‚5 ílÜñòªÝäS"²EÀŠRfÃi‚aé„ý¡$4æM[× ª©½ÃöRÒ±yøAœ„µNDÍp¡D%.a-60¼‘4“iÇjØKVÇjÔÇP9XÃX¢cµLÛ¬–3›8«aËìÍ 8Ê›)VËu,¡X-·Á–AY˜Ø S¬ÁÙj°I*Ðxv³ç¡)jv(¦*2¬¼%¹yñâæòö¿Þ†Ë·ww÷7—7_þý0>ÿýç»ÿÞ\¾»ÿôÓí§w ¾!½¿üõò·Ë÷ïh|¸¹üpûñ!¼#M¯ƒàØÍHS‹ J³Š%æ}^¼—7áò—û·÷áò2üé×ÿ¹àýçðÍ77øo‹šb6ç60ë@µÅ [€?+yšE[ÉAb†+­Çd»ÜZöÓ{”V&’ 2¾5’™]«Ì„ÃJAt¨„9c)±âø SøÊL{šD^IB‹ŽS"Ñ]/±;B OHôu$2ILvªdÅ.Û Vã8BŠB2ã`ZI"ÅU(T£yëœ)ªÛ¹A2}B"/ÜŽ°#=q¬f :a ¯× „Vù¨)C2yB¢¯·ŽlÍBwë€G8Ÿ&¡õð“:L’P‹œ ˜‰…â4ZIÛQ,†“X‡‰æ˜Úˆ;!ž±Ð…æ!8¸šÅ”íŒÏÕØÀqÔ™y,tVÇTBh‘©GD?óÆ„-ÃoðÌ:(@"ÕXÍ:œá›YG^Iolá‹r´€Ö6A´ã,‡`&ÊJ9Ài×2\Tr¼‚ó6C­3ãPY)l†eSò0Û(89÷Ányn´ÞiÃMÅQïN›`°M',–†vX,[˜[F`³EvØ.Qdr„–•§— ªª­§¨ÚU¨²JÜÌÄ4Ь?Ç)õØÌ6ösÑ7$3á°Ðe#­#ålfŠøARŒdö:s–e¡·,[oÙ3ùó ‘'W+DRרWˆÜ@¯–ˆêÂS” lCì29§ÙÛ­_)ìÒÌ6* ‰½LuH^CgyöHìuªá%ŠŽ:U›Ÿm½¯òB3D‘éz¡ ¾fñ‡ÅZB~—ÿù¯ È ¸†–nÃÝ—_~yÿädjc¶ éëU?ûÕýÝÃàðjÜŒWÚ¾÷jÜQ×¼m É?4|8ž «ÖíK@¼¼þtÿñÍ-^=\^¿|.oo{ï/Í×xÛË÷Xøöîá³µ% 0Úçû/Ÿ>ÞŽKÛ¿ýãö§Ÿ?|wÿ[r¶¬¡© îõ‡Oø¶MämâØ£ÏXx47ŸÑÛ°ÄÕÇœîÝ-ù€|}P|àÈÍ‘›#7GnŽÜ¹;rwäîÈÝ‘»#wGîŽÜ¹;rwdudududududududududÝ‘­9a²ŠØâƒêƒæƒîG&G&G&G&G&G&G&G&G&G&GÎŽœ9;rväìÈÙ‘³#gGÎŽœ¹8rqäâÈÅ‘‹#G.Ž\¹8rqdvdvdvdvdvdvdvdvdÞ߯½s¨8Æ—ãΡ*Åœ'μžÐÁPëHI;ÚÚ4&y6Ûõh•­ùn»£%‚Wí³2ÖÒû8„U0úZò¸Û.ä@‚s„ ÌšZêúÖššfؽËÞZSÉÂŒYGI^¯¢ÈÆä±­¥&«t¶ç©mî÷£Ò` p^~?*bÕI}µ/L ÉB81XœÌ3"-´ÀXê$Èèuý--œžŽ[ZxªH}"‰Ìë¯äàí£9h¿’ƒk62ÏsýqHdJýJˆ;Ëó”y6@ä©'µõrä€SNqFB—_Û]ƒõ´ì7Å:,_Ÿ¤e}7ØÜÑC Ù€¡-Ó’kÝ÷ÎéD±õ‰¼fF²c¿½ñx"wµKÔ ‰"~«ô+$âÆ_æ =a;„íÂü±U×ÈM;"OhÂËȸ*N1WÌ Ï¡³´ce«®»«\¬¸ÜŽFöÌÉ®#&e÷¥&jǸŒ;l¿ßéÍ®cA¦ÇVg1íœ.YJõ«.ÙEŸé6È{"¾©Ô#Òµ;Îí„ò!õlµå 3’4KÀ´Ÿ@©§h=ZÈ ¾Kg ¥²þG7v b?"Üœ}™©¥3DÁ¦ò( èŠÌZ¯è±‰üÿ°6~ endstream endobj 3706 0 obj << /Length 1162 /Filter /FlateDecode >> stream xÚí[Mo›@½ûWpèJ@÷ƒ]X)—´i¢Vi*5nÕÊíÚÄA v¸Uÿ}ÁÆŽ±7ŽÙR¤Ä‚aÞμÙáyC×ÝΫsœp£{c`„êrÃÃØáTÝÑ3±‹^þè¾uÎý¥K©ç;>¹¡éEï®ÎÞ~-.ë ÒznÚ[ºÞžß`/ÿÎnë9§iüÙ¯¸Ò3­Ò\þãøFRXýùé¢côlJ©éUžøÄ=9±ü€©ŒWÞÞ ‰A×ĨAj’Z ‹›˜oØ —d Ú II*ŸaÃÎi%+iE8ð `Š63pîq(2%búz Ì-`ÐÌ"ØÄ ‰{HD]ºž¹ M/` SÀ…l–± yIA%œEñ§p0é«nZBÓ¢À¥Îu¡‹1tmãXaäØ ½­bÔð&CñÖ¾hÉÎ?~)¾u‡¿#VvƒC=sbæ7Úq˜ÝŽ©Ì@q3Ve ÷6A«$½'I©ÁH'?Ó0Û`B È!A+Á˜yñfÇÁhPû™Rð)·H[ÍæšA÷ÉÐ5L€÷g×Ëáû ‹‚»wq0 Õ2yÙBÌ”·µ´vÅ9±­ijõoƒ$ègab^}+~K§%>Ëž½q-*¯š€|öê·s¼ì93pÄ~í÷` fuøÓ³.ÇÃÁ½uõùòÒŠ£4FCÀõY_]QŸ? ¤éÔF¸ë‘-QÖDË÷ ­¢F&¥¯¿÷cí½ÿ¨‘5²=ÐÈh•€ †BŸDŸÐ¹__#ËHÑÎF@¿T4MDe ‘ì™DŸ4T›4G•ìÙU2iŽ#<DZ¦Ð™¬ª“)ÊÕײ¹BÊÂ7¸1bÐr.=Ã[¤ onàSRŸø'¶¥Éšz2ÆâyS!Cù¡¼†êü È•²´4Õ”‡±B³²»"'Xƒ œ›$ˆC@ea7±³†# ¯Bb5êæ›ïºLf½ GY2Ž) ôÿ·Í?k9úã»°?¹ [ˆþéÐEõ £~ã<íƒ,ëÛ..Àcòøjð–žPñžpê`æÌËWCø{¡#³­bñI«¾1àÛ@FY8lðí‚>šÄaõ[òå 'ÛéHÊiÚ@ÇÕrà‰¥¨± ò¬ÅômJ’E§ Úü®¼+B¢gŠ”Ø„µüv‘ŸËÕü‹$¸¿=ÔØ¿ÈÈà°Á¿ £áíÏqr¨ñ¯LX‚ =û´ë“‚—È}/›#ÀðoòA«À.@ߪÞEiÖ2ÜÛ…üwx!×ö÷9ì«à[˜íK!×:ùñÿ¶+Tß‹™ù?3-Ÿ=Î|îÍÌg1Àhc³ÍsŸ¼ÂAˆ±O¢5ö)µ§stnB÷ð¶Êا =öI\è£ÑÐcŸ„B¦ÍfõF?lZû;·àüû ÿë:K‚?gyÑU 6Òg áRc’XèáØg ”·Çá?àá¿êìo»Ø7’Œ endstream endobj 3565 0 obj << /Type /ObjStm /N 100 /First 1023 /Length 2881 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹pX,’€`À¶ $@¶Ny1v }οÏ+ÎÔ´|éÞwa—£æ<¾&ë«ÈZ©…RIR 'ö†$6õ~Œæšª7,™Uo´ÔÆðFOãü­‘¨ÌgTÑèwh ç àjÞ$QOš¨±y«&êÕáÈ1ûµÄį'æóÓ‘X† Å%qeÁL`[…9qëÝ[xƒÁ>.c R}4‡¢>ûá‡ã1^N«Æþµî£1´ùT0+½úþ c>Å«*‘wIÊó»¢Ie"KMêÔв¤V©´¤­;éIù|ÊH˜Sï§%áý| %ŸcGQNUÏO%ÕÚ} ÕT9ÅZtuµTG÷·ÄG#ò1´'ãùÔ$™Ì§V’)Û4¬£ÕówÖ¯û¨ù•Rgõ1ðZ]š¿%^¡û‚¢¥©›úÕšzkÎÓÞG™ýZE ïQaÔœ –lÈ|j–†êä‚~µ9Š¡_+Žbè×Åg¼•4Fs. –SÈ °â3g/RÁk`Œ@ÅMÍê–wîó)­9ßÖÐÅÅ›¾7Á`¥Dæ}»›©ï‹iÂô‰ƒa¶‰œ0šl2Ö«>ífë>wÀh\¦ :Fc>#`4–) ŽÑX§„Fcs“ª£q›b€¥÷ás³ ê ˜‚ƒáDyî€ÑDy‚a´9Óhb4±á¯ "$Ý-ÞðV$ÃUa˜Òâ²0W¸²ëÂ0qxáªw/^ÜÞüï·ûtúöááñóÝéÇ/ÿþXáä’‹ŸåÂdw8¬Ì:á¶®+¤]Š ûÃÊ+,ýôïJñ.Lá˜ÄÊÃ"1Î~’Ï$ALë·0?9œ99‚*«>5}7'·¶>õa¤~~-0ÔæËA¶Ÿ”¯Ï|?=%Ÿ±¥9%õ4ïF[‡ˆ ¢ÕDpž“KõÓšV‘ì±à•þß\P58)Ïþà´ý²Á|cÛ‰j¤? *ô+ª~´y#­åá79ØÒ žó¼}Ñ<ò‘=«øƒ£x‰¥­æØ?¤ÓOÿüWØÔÖ:ûÍË×_}_=>|ž¨¯¬'¿?™ßz5Ï )>´äžüüA`(~Ïyy¤É/~Îl¤ŽMß?ýôúãã‡ïñbéôúå«tzsÿûçôîsõüïN߃ÄýÃçOðÏe~ß§äÓã—îçÿéùÿþqÿó/ï¿{ü=ÍY4ììm¸™¾~ÿßö{¶KǹŸ0ð¼t>óðÒ hp4$ ‹F‹FF [ô±ècÑÇ¢O‹Ñ[ŒÞbô£·½Åè-[ ·@nܹräÈ={ ÷@îܹòäÈ#G @<yòäqAöË»Kƒ¢ÁÑhh4j4,-=LLLLLLLLLLÌÌÌÌÌÌÌÌÌÌ,,,,,,,,,,¬¬¬¬¬¬¬¬¬j²P“…š,Ôd¡& 5Y¨ÉBMj²P“…šÌÙÙÙÙÙ94h¡A ZhÐBƒ´Ð …-4h¡A ZhÐBƒ´Ð …-4h¡A ZhÐBƒ´Ð …-4h¡A ZhÐBƒ´Ð …-4h¡Ál ¾[tO=ãI»^Ï’6Dvãøzva„G•æõÛ•v÷YArxE¼0Ô%k~»‘h#w8šc+g¢ BˆƒŸîÃ9p[[5Ðà ƒ#óèÅ1‰…±•÷[]I "¸¬C+/E7ë¦ ÖŠTø˜C]n³ŽìuiWæÁþÊ'êÊÕ0¤\}({ä[Ÿ бR~Œ çç%^T7ì#^ÂA{W?´òЬd¯à˜‰Îõ $deq Ñ+Ú̧;1”ŒÃYA5ºsˆØW:mÃ̶fDæòpXy¦Kávh#Ñ¿ëH¬œ‰ŽÌWê•„;PpIðÒZ/¯7Û8PÃjè1‡•fÉL³\âJþÓ’Xê0¥a5ÆFÔs‰c+WÃO´ÇWËá¡î!‰•“Íï™úF¢{ùßf‚VîäW·­`¡›×® Ç©·r˜^îço<ý&ܲ@/yC&³³+7Ë‚|õÊ¡Ákx¬wÄa©¿ìœýPáJbhn®Ð#ºð|FÏÉf`¢\f’¨¶2À¬~t»‘`ä=ÃŽI­ôU”Ç×$Tsy ^aúñåÆŽ×Škci€éûvßHtÊí)¥ò¦½!È»ú*AÌ'ãF¥Ê.öij` ƒÝ6ÍÃ\z‚I¬¼š gUá¯ýxfæcn¨^.mv£2~êcþy‹+#ÿ'VÝ‹¸í£I¡$vÍZ,R Qʳ"iÍn“ {mWÒáåþ‡W-ûõйFxïf¶®\ ÍÃKaaŽìî4—ÂfÉ0íýÁg  bpÝH¸•¶vc^«ñ¢~¹EÆq)íNžJÚ¹4VtÜìˆF­nüŠžú1‡¥çê )ñF¢{I=D[{DÓ¶ÅðšQë1‡í\ýÿð‡‹À endstream endobj 3708 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2278 /Filter /FlateDecode >> stream xÚ½›Ao$·…ïú<&«XÅ"…'‹µä`x÷àdáCâ†C22üû¼Gi¦•Ëô¨ «g§›üšU|¬*rj+–Jª­x’ª¼hI›ó"R=y^ŒÔšáBJŠù•Hó+Ñ$¥U^Õ$2Ú®ŒMþ·ÆÖ¥%ñÁæ%’„¯z’Þ!#ɼOKRÑÆ+IªÎVT“ÖçokR׊>ÔH;ïó¤Ñç}xƒ¡ó>4_œ½)h¥™@UÙ[ÅÿÌIÏWðÎ'8!|¢âeºú¨Æ˜Ox2¾emÉÔØod5Ørí ÍÍVF²6¿µ’,æ³&ÉÆ|Ö4yyþ¶&—èÃŒcÌgÍ“›‘·¸GÈ"y¾›ÁÝf{#ù>á%Á"´ ^cÃg]ù¬×„{Ù‡Ì7­…!i1Œ¡k}šÒ#Eyþ¶§ig {è`+0O¬5IáÓÒ0h´iK|Œ®}à±­ ù^[i-u–P¯Ó–­§nÓ–m¤N㶤N–Ôû`oxÁQ¦-£¦!nè#, íl/< ›¶Œ–†;©0`£uŽ.Œ2º°·iŒii˜BJéÄê‚Kö×é½ÕÙM‡ûëìwÁ§…u8p gOhZJŸÎ‘"³1ø°ˆÍ{áÄ¢Á~ñ øÇiÖÞ€O.¼¶H›N18YºÐ“1T˜7Ï7 7-Ó§zS•y/zÓj³1ô¦|ÝÞ”³·FAoðG\¢7 Qá%«¥T^rBâåîÞ½»;}úïo÷éôõÃÃãÓÝéãïÿ|šŸÿúËÿïNzüò¯û/Ÿ ”¡üxúöô—ÓŸ?Ëüpwúþþ§§ôY‹g˜ ï–;l®9à_¦5W¸íëôî]:}L§o?=¦Óûô‡ßþñó}ÖþÇôÕWwøoƒJîö ¢Z¦¯ìBX]Q{øÈÂKV{Â}!„[®Ý7ˆÖÐþ¸b¥9¢dªÍ¢ã/¦ý.ĈuRGVx¿•’S¼eƒA¶³êL¢…­d(ë"#á7@Ô²‚žu­½gEä©qcäÒìŠ=V„d£¦¾ÉÚe]á·Q7ˆ>2—¢}ˆ…³CFÍÁè‚:EìBèBs`!_Ê¡šƒñÂÄJ¿Tm¹oÖ@H— £—=†¥‚i5†=g÷¬qÃÜð•Öð‘ÿl!Ùoˆ·ÐË-3˜>ëeí-ók´/×Ë Ä‹^îC,ÕK@è € “Ιd+¤²qMµWB`|C€g£Ú]„ºR©n-è\eÂláÜ(=wÙFBK)³»=o+•Êós®ðQ#+”=ˆ&+¥ Qn¯b½âq„®”*D¹¾Í Æz•3tbô7Ð*W”›T5År~mzÆz¥zA8 ÕB]é¥fáÚ…á08‚ŠgÎG¨%WÜ!Þ ´ÔÈ3Æû+³t&Cíš`ÛJS´\¥m±70¬ ô;lÁÁ?3 Äýˆ•Ö@ÀP)S/Š4Ã)S{º2ªƒ²êtPN¶á±2—<^1¤’%¨=†¶r õmnhsLÓ ¤¬¤h‹xß(JuV÷)ê(6œ#´m’ Ø5ÁÔ²^³ÏgÑÞ…¨úÑeaÜft)œ´R±¼_Ñmñ•r…¥¢ö¤Cbä*0AEŃ4sXî£Í"•*3a¸¦1ýáĹ!oèj˜msŒ8 bä}VOYk§p#Òà ‚ÔcŠ#ZÀ€HfÀ-ƒq¶äu–'ªöc‰34«Œ |󳋀£sìÌÁ ?xêøÜõza¨ÈCÃŽa0ä]ÈÀ[/ˆ1“)ÿhjH åš)F]àŽÉáC£l÷cO°^va°š]ìX†‚¤ÓÚÆ ÇA X+GpÏQÑ®&ƒl‘ä”Ï~­tºrŸP å~Ü…Y¨ÇQ¡>·d«e,âÉÌ¡V#¹as?f¿@@*Fï„r“c! Ñ·eφh¢i;¢Iæ–ò‚; WÏ•pÈÂ-¯Š8 Q„Á! –C0®Foà˜Üw{m 5DþõXk°”mȇ/¥äÚúÁÍÆÈ‚eeXé jÕ™è°J…lûsy&êµîx¤<ºA „_ ÁdC<6Ö¯ä`†Æð~æ1ü`Sv}ƒpËÖ þ•ºAðïÕÚåJˆY£œÉEçi‘­nuæ?½Ä1æy\ ADa…„Ç^¶9¼^Q‰…•ìY6÷¹xbbaeòYYð~0LË"rÄÒt# Õ¾A ¸Õ¹;¾¡+!´æñ¢b½¸ b¡K˜abù¾@̆؇Xy˜ÉXŸ3Ù îæÆÊ½y,X9^1ô™jÜÀ°Òˆc˜qœ!¼p Ó}ˆ•{óÜUrßCòUx~%RÌ‘Q¨h=è,Sí5÷Ö.Æ¡¨·P¬ÜœG™y^”5¢àÑÜp¤~Ü!/XÎú!‡™8þÞúÆ » +wçëðydç A§Ow!VN‘üj ( \ÏwVže2í¹ò0îÂf•—a¥WšAÿ]X.ÔØ‡Xª—­ ÓòÙÇ ÆXy”Ébu‡>Ctža’¦çÊu| ‚q»@¸ ùäO v§ÆÊ…ü¢Ú n ŸU VÆQ‡?M¹†>´yþ¹±Q/û€´UCÏm——ºÎж—+ih÷µ+‡³Œ^òñwð† x1Ô¬ÇU¨Œašn Üw«mŸae™ë6¼qf0n> stream xÚí\KoÛ8¾çWè°\ RER¤¤¢—6i‚I $ÁbîX‹v´•ã@Rº›¿’_±ÅÖ G­[ì¥mb“ÃÎó›a}gìøÎÉÁûëƒ×Ç*rb/V\9×#‡ù¾'儌yJÄÎuâ|œ^}øãå_×_líË"V^ä‹j«Ù×XÀê/ø‹ÝýêOß‹œ¼þqþÏË“š`¼¶‡+¤òbÉ—‡Õ/Åb+îolÕ üyðjñq Ÿ]!Ä€ ÞÜ1Ü8FìE’9.ãžï³ù)~ó®Ì}®ËÃéd¢o“ R3f!©ÙÁ !lÌ)x@ÌV¬¨åÄÙ6ðWÏWÿÖõÞ…~˜_zË~úÒ_hD¸ñ!S¼Òœg× X•–L„]x` ¤’ž‹xs3Ärñüj;.b/ÒÑèŽÂ”n:roﳌž‡WÁ¹ŠpÎÄ»$97¥>Ò¥Æl!Ê» ž­Î|¥'w™)pÒŸ˜|lúR¡bºðÍm™OÓ¤@‹ŸDWéa9Íiã r÷õ*U«B˜ŒNr}wC$T|°ófiQþy†ËIƒmêRm!¬/Œ0ÓX%‘¬Jiå2•eàijV‹é8êÌû¨‡_¯Ê\ÿóèuw’ÜêÐ66t'¦¼™&¹g‹dw¦ma¢Ë<ý×;›ŽÏõÚ†k•P‚Ôx‚Aĉ­1Š©óíáœc óu&ß|A”åÕJXøº2ãI2u™NoqáÿiÐ%3’ªîzÉ&ÁõD!?“_q§óÂQÃheÏZÉem^ÔÁ“;FÞ5à"¨]^@í”j*%õ†ÔzŠ^szІÅä0¢6Eƒ< hi¶Ôfº ÏÚ@µÖ“ƒ|zßt–&iù€&AÀƒ5üË:Á"Wdj=¦v6C¤”ß{§Lžz‡ä)ì·¤}š,ì¬îl€èùÚ¾|^ v–N/†:=iïõÀ4m@ÞíêÑ&R´0¨@(K=¼92wxr—Ñ…yó&7:¹<º"ÂP™ˆv~€B3ßû ¿ŸÞß&:OÍ÷ø¡.J\¸¤˜"êðgUHWïÐd^œÒº$oÔ$3ï»ÂeÚI”Oá ÈÓLdÛqWðh{Z-ï3åñ@DP5ðŽ?ýŽ ©ÕÂÞ°_‚ïfP¹×÷ëOÆ8 Z°{WLg§=6$ì®í×»\€ëÜ»ïN“ê2ÒÒ&Øc‰¬±Góï?œ OøÊ‘au q´ÉÏãÅ!Xé`,\†4tÇ·½ãF]]‰Qã‰xï¡Aj KQãµ*F>ô»¨žj¨ž]¹ÓMÝŸÐÜðbªÄÈnÌðëÉ!–V’jMëL?˜¼¸ÐÓ/Í%ȹŽÓ±Ç¾EDÃé4OÒ[]šâUK ß0ÕO˜<ªGU.–f^õúò·–D·¶C+É"©þßFkC´»¹eYÏÁ6ƒKmæ³ÿ½¬`SòöUw ´aŠÖ“~€ˆÍ£tri’û!¥`ôsü6chKáØIò Ö-i«uv“;pŸÜhCšØ ;A—×ù43Ãû _!8ž?EUú"n’­g”,³—Äí=-(A‰ô| ê|6¦Hã Õ.È™K/â úIÝ”q¥ïF9¦xhOYb€êx„ÄÉ í (NbFú>+ç"Õtãc‚Qˆ–np•Õ¥f_ŠBþ" Cø–a·7«K>š‹Ãª1$ ž­ð¾› ]а-Ëí(<l­~Bغ•ë·.®ÃòTí™’ à6¹ùå›Í[\4¡‘ãvÍ6!OBÀ/qÉ V+8;›w³,9ÑvÀá"´Èû%‚ÅŠœ¥ y¦Ékç@ºw†J%–¸èf-…·vhJñ|l|HY1„%LÒ ÕëMHÍ[‘õ¨žcð€Gæ’GæÔ8rµ!Gö­päÖSØôU[HK¨­Þ‚úúãžÇc÷G^™à¾Î¯‹}Ÿ_瘻°Ó, †ôöxF½Ýd¢i2kQ ‘îEû1éØë«ýl–Â<ÙçvG«’ûäÿ'¢ùQ+ùæ;lhf½\Ý_±ï['õ>\üv)u endstream endobj 3906 0 obj << /Type /ObjStm /N 100 /First 1034 /Length 2829 /Filter /FlateDecode >> stream xÚ½[M$· ½Ï¯Ð1¹Ôˆ_, ØH€Àöm±ÇF€c½’ŸGu³z/©êƒ¦/¶vºúñ•¨GR”ZF•R‹ôÊ…z·I¡QGŒF᪌ÕÂÔ%FTXj‹V‰çH [§iá^5FVØÅŸ0j…GÔ‹P(^„e¢@æ§ŒÿØü”Õ¤Ç(Œ_>Å£Æ?Y‹Öù]¶¢Ô+lp+*—O{Q•xö¢Ö&Ê(Úk H-ê6„ŠŽ(ÂÅêðI1–@-&-Pe:â=`ÒšÄ[‚šõo)^ÌGØÀD´Ê1ZK£Ï)•Æ#¬a›rXS)Íl>§¥µÖÔJsVØÐVÚ°°«½ôê¬^0#ó£€O [-øûQé†qé…‘”î=¾kZ¼Ö9²â$6¬çv­×éKóâ¦1C æ­Ç»µZÜçwñ2>æ§Ë¨ó»MÊàéiLÄé-LØÐéLìhÓ—pÀèÓ[ÍËðïÿP­õê[ª4ý…D•ç°@U/`5V»< ¶éQ,Tªx3˜ê Ã1}ŠW¦x"†Ž!M¯vX#™nuX#`òˆl>à°F}zÖa|:ÞaÆåXc‚5‡5æé{8‡X.ÀÛָͬqŸ«cÀVB<|±4€:‚΀5pŒ—°&ÚÖðæfÀÐ\Óšø\aÖdàË‚É(¤°CXSŽEæ!kˆ”bkj¡#‡ß0 Xš‚õÓ»wOÏ?ü÷×—òüÿõòôüíëÇÏ/?ÿ²S„ˆïžž¿{ùíõ÷O?½üv‘âüÛß_~þåÇo^ÿSÞ× ‹pð‡'€|·¡èvýò×?¾íý%ÖàO—PsŒë€j(ù0åä9°´ôx™™™™™™™™™™YYYYYYYYYYYYYYYYYYYYÙÙÙÙÙÙÙÙÙÙ¹%rKä–È-‘["·Dn‰Ü¹%rKäžÈ=‘{"÷Dî‰Ü¹'rOäžÈ=‘=‘=‘=‘=‘=‘=‘=‘=‘=‘=‘G"D‰<y$òHä‘È#‘G"+rèý: p$šËAËAÏç ‘SƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒžôÔ §=5è©AO zjÐSƒ~Õà‡§¯¾ú"ÝÍÄôôüýïÿü<ÿý·_>þûéù›×O?¿|šI­~xþËó_Ÿ¿}Oó‘ú\Þ#ñn ñ5¯[„c²¶EmÑmµ)žûº¼{Wž¿/Ï~ýáµ<ÿ©üáW¤Ö¸þ±€Â­nX;‰Þ·PÎ9 á…$`°[ó-Ryß ãÖ1CÜþ?‰¾^XDw \e3ĶS´Ð\ûeïN‚ÆfPî)‰•+‚Y6hzç ¶ù=Î`]ÈÚˆÿ; ã­"ó’m! ÅüD—MkÏ—ÓÊ…é#9¶É¦cM@+ˆ§ÁŠŽÚW®KØB¤mªà€9×Nâ$ü HWo$‚”¹c¼7¸‡B ^¸’; ±r*"h3*}‹-&õË”4L‘ºhtåÂìmcäáÄ@ÄŒöÄ Zéf¬ Ô©æ¶)¬³Ö­"•+G‘b©? S+Å!Fì¿‘E ©Ü\1îX™C kqÁm±£§Ö7‹>Ö¶ªGѪ­\X‰ö ›ò],V&s…?PÈ™"DÃÄf=aöþ ´((ìÆ¡GA1ÎItY¨$‹ŠM…Ih”¢ ‹™Ž‰F»=¤²b&L,ß8ˆ„2Ï9,­¬`\a|'¯´fç$–VV&[4:vÑŸ:'±rI´±Å6~'áPê+bee•[cpˆfíuëcÒ6±GUVlXØ)[¥Í°çáN¨¾Á‚Pçõƒ°í¶rëcQBPj4 ‘·j,Ôû2~P¹ˆº.I —ÁãœD[« Q¸c'Áp÷sÎ+ã„Džº‘@&ñV§$VÖ43eÜ84äÔ¦çÆÊ%ÑÚÖ¿àÐ඾̅A¢íe®ºoGQ‚mmÌ®ˆÕƳuNR8‚„<¶¶SÓ-ŽÏ+"Rª‚ŒŒ#í H(öâqØ–$°7—A"e)Øí$°4tœsЕ޺‰jœo5Î"£¶˜çÆøû8+ \š«q§€UÚ°ñ8£@+÷(ªã bç€Âb*ãŒÃÊB¿Cæ7Ž=©ð)YÙAEˆ”Ë‚É+oçžXÙ>åÚ6·Éä[ŸJ=æ +³7ó‡;±­Ê¹(t¬í’ÜTÁ†-X=÷…-Ͷ}á‰Ø„÷sMØÊ>Y”±í¦ vÙâÌéŒÃÊ}gøŠ•H¤ˆOðD‡'áZµËW„ ’Dô DÏI,mPE›,w!kÈ,–æÍá³{œ,¢o‰¤y‹7èžjE1ecïe+J££ÍN__U AD·ª²*¢h{‰Žm_\—s§yà}‘ü€ÃÊ"!Zx^ÙÛ¨zÜùÙÿ¯¨gö¿+W„"uÍ‹ZWæ[ëýœ-mÕ!0Ìû‡W¨*FÜ„;%±Ò} aމA³§|JB—6a»û‰8s©w‘XYÎ41/^I°bÝÓ9‰¥yQúMq®`:î ±´ [S½‘0äºG¡+û·ˆ—ƒnVÝ'Ѿ¾¢°©cïJóãm8I])Šü5|?‚l…ÌŽ¶Àcýa“ò×í¬Ib­ˆ>ˆÃõ† ê'`’«Ø ò ׆„D¡}oH¼¢­?h÷wM¢–Î˰óTTâ´Ùc6€Qéì~I/G\œÚÖŽ*+KþØ„r“-.…GI£Qãul?ŽZ3DoÁ»ÉÉ¢Ñæ>ÅâêÄ,kÓé ñ(\ÕzÛÁ¶«ƒ¹mÃÊ\YØE&HQºµu·E«¬i)TX~xö××7ì"Jµ&³Ð…6æ/::Ÿ[[éÆEú„EÛÎI˜¯=”žÆ“DˆSú9‰¶2d"cÅov(:éwÐÒÆþ¼éˆ¬áײÆÇ6ëVµÄ+YÙ«‰íx\xŒË\(y9z6óÚDÜb9Wmeggœ*è,(.Ç 6K,ª‡÷xÚˆ’jÈE\¬ÒÃ#aYÛË%ŠŸÅ•?›½ÜyàB¨>¦BÚÚnnt;FB ¹œp •$$ŽØ0y/XkÜZ¡y/˜KŠ… SâÊL¿\E¿ÄsÛâ'(q³–Û¼r&´UvK‚ú9‰•qòæ$7ü. ëmE±?ˆn$¢ÅïvNbå9ƒF¿‰è,›ÜAb¡:4:Ëê7(ðó9‰•arÜâ—k;‰èóß!޶rIÌ0qã×Úz]© ÄÇ&ó2²D/¾¡mó£ M+#•Æ•¡øÙR(jÛ‚1ð±@"« Lì¼â”q¹ÎÔÚ¬0Ê];º{©oá d«øùÐîŽYƒÛ=$þû˜ëš endstream endobj 4074 0 obj << /Length 1504 /Filter /FlateDecode >> stream xÚí[KoÛF¾ûWðH³îƒ@.­m¹v툅 €Ó-®e6itRÿûRoJbhíîБÜÂ9»ßì<¾™!gä çüè·ÁÑ»¾À 8áÎàÞÁyÔçŽÀØã4p‘sëbŸÿ5¸|×ç²ö(Ò“8¨Mºøpzöçä±#4—^‰µç{‹zDT_ÒÙkQ<önÔS–³%Övsëþ2—XýyÒÉ'‚gÿ~šÈçAýᥴÚëælò5Õ·¸UÈä5&\,€÷A¹À©ßebŠþ.8‚V/‚“HO2ìô*Û ›Û.¢Ð;&à: ¤Ýq¸ˆ‡PÝoÃ2“‹q8Rs}I_CsGkûÀœ¸uy½±*²¨h;•‚µÝu©>jV¥Eœ¥arÜc¹¹Šž†eõLÐÀÔ,ft»lV„wã¬|vÎ4(¡ V{E[ÛIñ*¼_‹"|†Ù„¶ lð¹N+QM½GºZO” ôi§©Ž1K†@]&­ ΜVÚÆ OÈ$ÚÕ ;ˆì {hÏ&&6JѾÇ›°K|‘öñ%Ø· ć†+f¨ð7BÅi<þ4áDML~*½µ&˜Ôm,jŠNc—›°«ÿ;w =…ònãËëû‚kUÜf@ùI1 ²‰1Oyo·m1õà÷½z…d”¶ª,à°$ ÂÒkFE¤* ‹ ¾²¦z°5Æôc!¯€iž×ó˜•ù K› ¦ÍÕ·ÝÓr‡¾¼CFty¸Ï]Fa1 +ЦD·Mr _bíÜ`GTo÷†IXÀ·­9ÒžM{y­%¿…IÅå³ñªXkÕ¢ Ó¡2ÇH4âw”g{ÚòÀúÔWu¯“’+ø‰ú¦’»ÊF×!.ˆ}ÛSK í»’‰„>ãÀ7hÌì€Û8×K‘ð"RiY€³bQ±bñB<Áç—9gã;Eq:‚ºˆ¡ÐvÚ~gãÇòù:,óøãèæ[—–’j¨¼¯Âò)W…™Ýœ¨$OœTǼþÇÏf ª;ººö]¾ƒ4¢¹Î5|JFû–~)¬»+z¤_Ø÷U9|8 ËÐØW˜µ¯ Ý…¡Bƒž,UðF¬7NJ•¼û[ Ks~§ÓÞ]ªÍú¢üfúJ‹C7{y`¢hû쨾zû·,­tW[sÊ®ÖóWëÙVqé|µa™)]™§¹sUN[«´¡k­¯ÛѤqbÚžÁiaû+ ʓ†©†;YÀüï VˆqQ<©“,Ë«Z&,§0l]Íb]u›XزšÍÏ ÍB=ЏÃDeü±f½“ªpͳ8áÉKaYÝ}\û-°ßpy€Y î5W‡®y-ÃHM^wè1‡9õ7D—èóðñ¨WILC¡¯Ò)éþn¾! /}i¥O]¾4}µ#/vi®­Ù„‡×_¯° ™d¢±ÿQžÝQtÂ^¦èdzuTÙLjÜÞv2£Ñ4ÄÞ¢½ fƒuPuqØ\ T8ºÄhœ¢k‰`*W‡2¼·S%4ñ÷Ïý‹ô>ë,ìÕÝ·~d°”(K‘†jfÛ}ßÛ£{¯--¼€`¾Ìh,›-eñ#§%È4RÆwbR‡êLW2¶‡Õ6ÍA"=MÅÓk­uß ÉÞ«ß=ÍÚ>×ñ“´Ty¡†åÞLM47ðÛ•´Ã ù¶Á¼ñ¹‰å Þ}œÆ¥Ú½ÄµTaS]´Û.»(Γì.LŒ(ÙëÆú&L­ž?äžÐE1›¬™ÙÀDdn?Ç&µXPñ!«è*.JcóÔáò—áðëM™‡ß¦,šc=t“:\¹îÏ ÖDtÑ×"+}SLvý-‹u-o«%Ó è—Yœ^…ÏÅ2^N'T^Þ¼Ò2¦UÇbƒ%×(ã¡)"[~UÏP­PÑzy68ú‘÷Ðy endstream endobj 3907 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2790 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹ô°>I‚@I€lœ:(ò"0bh YœŸWœ©ûàé9P Îv÷ãëbÕcÉ‘^½Ô"½¶B"Ñè…Ý£1ŠÖ¸DµØ¼DTÜgƒK )ƒ-Z¨ÚlY!êþ€–’Š®:¢Õ YçhBâ ®…ú¼ÊThôè¹0ÍgY óùª–ù,ºd#Cì`«=þÖ ·NÑ zŒÇª6´/Bóªà?™ý  T£x;kчà±FчÄ-}n-úV”꼯e ëÌ$-žÀWµ:£¢uå¢Íã •¢}Ì–«2Ÿ°bäÑhètMÏW{1ó‰7Šù¼j‹I¼óªqñ:‘MŠóùª`P\GCæ1|ÁÙZñæó¾^¼‰2J«}x-‰OŒ§6ýuD°öixi @gð)ô::mëEìÅ £Æ½¦þðâÅÃéõÿ~z,§Ïß¿úøpúæ—œßÿþÃûÿ>œ¾xúðýã‡ï*”¡¾9ýõô·Ó—ßÑüòpúúñÝÇò¸lNáxmóAc[øªSßÈîû¼¼xQNß”Ó_ž^?•ÓWåO?½ýÏã¦ôçòÙgø·€D›Ãowƒ¶ˆåCÃב€¯l¡Pµm`tè6(‚ŸÆLò¶^žU¬Ñ&ð=•º Lc&qzžñP’M¡ÍfcƒîqݬNåŠÑùc }!ÖÍ«$ñ­A ÐJ#hÝBÔ.L¶2H¡-¤`mƒd\ g‰oG x%ƒ&ÛÀÌx¡Ð&–;(¬t…Q7Žˆ˜¬2$á˜òByrFÄtÞ6YnpΞÑB+ÿ˜„ÙJ숻’€YFä‡$Ž… CÈNJµEFpHb¬ôI‚4bÊÚIp߬ÝA‚x¥P oò,t RüR²¨Pjdr&ägJ†™ ¼ӏɸ•bÝ7AJhÌ[dB¡œ^"sØ S¬´„"(‘Íï$Ì·¨oŽI¬´„#(«_I4|Æì}DBu¥f;¹’è®ßŽIØÊð²1ÊÀ$zjƒz“púÂMÔ|»p3mlí þÂ$R¸HŒO!ܨ#6©ý˜ª¥•ÊíHnùÊÎà¨/YÈÒjC0_@±&ª0He„G[í7BÔÖËv$T†‚'eõ}Èø m}©¡ˆŠùy)5´k„ì3“@¨²Ð•”³ÑiTWF‡vøaUŸ­Æ¢dÜ9Ö~@¦ÝÊ­êÊ…[ÆÔ‹ ½ôÏИ[o †ëZ©2ó©õœb68)$¼µU8õdŒ-’Ãë-Ÿô•#`Ý9hÅ„:ú$ÆjwÞ6mwf)ߘ>W ¥B›÷+ Èôˆ¥±#¾<,æ²TDdÚÂÉö<.¹›!90Dz®£ß永ܠ¹D¶“€. Ö;H,kéN G§“ͼª¶Õ†-õJE¦êW‹…w ^Yn°msÇ$Y¨la™c+ÓÔž±O³“pdyýŸ`ÝT¤OÍuSÁdêtkÝ”WV^±^[=Œ³Gf…ú£ŸY©ø3¹fš¢"»6ºš‚Ù¶>—)ÜÑ»ÆÔI‘çbJ¤XÁ rpcîµE¨PlåµóÜ éˆ=Ô¢Ãè™8\²lƒ„!.Yvp¢[Ãa¼>¡aSÄÜÈ™«éìð[£a+-a„7/¬øð{šH*a‹u~~9y0#«Rß'ŽÕ¢vk4t½L0µØ·Ùe"HÕ[;M¦ë PF2£Cfû¥ ÿí†K´•à Ëc;ùÕÜÜ¥+c’­Wz¦,L¡±?Ûi››£ð8( d;ü<[M‚rþ·SŽÁèÇ–î5!šIrˆú Úp‡Å‹3Cx瀈 êÇ–n7Å‚"!9¨ÍBì˜ÃÊý&…>ñ•ƒ£®rÌAOáq!9Ä$zÇP,UJtÇR’R’;"Ó–nýuô½‡f, ÝÁaånS®!“#zT¢¨1m>­>Wù'˜§âLN²ÐJ±(z‹•»M™Ëµí|\Õx8…·˜Èn ÈJKÀþ¢;‡°Ä<sÄaé>Oøä+‰8¨ÒüKÏHp¤Ô;ÑM#XŽ8,]äM¿á€<“ïá°tÔ 9]¿’@燷ŽH¬ÜžŸ‰eœ9KX³;BÃVŽF,ÔÙob#0ùŽØø$‚‰É»"§Ù3†éöªDÿ‚ya± æ!‹¥‚y©yHx‹CŽ‘çyÔ(Àè™vÆ«n-2ý$‰žÓ$–ž -Îï$$ö‡Ç1‰¥;ãÒ6‰|2I Õ‹ž‡$–îŒ[ì€Ó•„7;&áKWªbmèÊ¡ó\@<æÀ+ÕÊ‘4ÿ&8í9ÝK7ÆS­å/ÓU­$f2~¦ñ]­.,vµ:d±t¿ivœ]§Šl&Ž`@bO6X! ¿e‹ßéW±kƒ’©–¯ËéÛþ«`õÒ•öÐòþ—|“7¿|zÿq¢¾ô^9Õ|ê¥ÆÁ[º|‰ãæÃóJÕóm€8½úðôî›G°/§W_½,§×¿~,o~oW ùpú==¾ÿøsœZÓx>Þûç§_>¼{œãóßþñøýo¿xúµLSùü‰DŒÀ«·ðtóËÃÓÌ?£ãyü;øÌÃß—†fòáÙhÙèÙçF÷¾4(=yå=”÷gC²¡Ù°lx6Z6™™™™™™™™™™™YYYYYYYYYYYYYYYYYYYYÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙ¹%rKä–È-‘["·Dn‰Ü¹%rKäžÈ=‘{"÷Dî‰Ü¹'rOäžÈ=‘G"DÎhM#£id4Œ¦‘Ñ42šÆ%škÕlP68’ ͆eóѲѳ‘ȔȔȔȔȔȔȔȔȔȔȜȜȜȜȜȜȜȜȜȜȒȒȒȒȒȒȒȒȒȒȚȚȚȚȚȚȚȚȚȚȖȖȖȖȖȖȖȖȖȖȞȞȞȞȞȞȞȞȞȞȗ|³fNŽzÃì½nñ³¥YÉaü}`ªæÅhaÚL¨m£ŠÙI [‰*æ˜Ä´™PJ õÇö”â˜ÄÂ<ãìDm'R êyÈaåÉF66 ˜"}†V’°•†ÔPÓ„Æ:ЖXy4(¶/!¥;Ô4 á:öˆº jÈ?¨í¨²c U tÂ[ìŸÜd±°¼&³+‰Ö¶øqí1‰•žËô‘Mî,F,Vë,„Wz…nŽ´ÇUgqÏP/Çìîæq×!Œÿ`X¯¶ endstream endobj 4076 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2274 /Filter /FlateDecode >> stream xÚ½›ÍŠd¹…÷õZÚ•"’ Û`¼òÌ®ñbl7ƺ‡¡½ðÛûeÝ{k3©\¨ºº”T¦ô])þYG©¤:¤$©Ê$ 瀯:5yï±Q9ðÔFpiÜþÔ’”Žzõ£Á)9•brs~@%‰wΪš¤)?«5I÷9²$£s|Leh$U›£–´¶9êI½p  ­\Ú¢q„'蓜T*ç«À–0ŽðŸŽù>|Ì&}šÏ'«øCÌG«˜ ëÀuàep]+ÉÊà,&ÉT9 ЬÎ'·šÌYÌ’…’Àk†ØÈÐJv›¢kn0»Kß!ud…΄‚âî’k£˜ NEïˆe߸â ˆ@é¹ÃÆ)vDa%BF®^ïGÙ(˜Ò<ãN"@Ó€óPº€Ò@ñë7v‹|!Œž¢±BÙxEsÀª *–Ûð5CÛ)„q!@ Õs ;ªçxÏ` ¿ëša§^@Žœ a™1犡î´RÑá3âbè%¯OÂê~åÝ2c‰7 åóޱ îÜáƉ-#˜]#ì4 M²#{8zÍZŒÆ©Ã/Z k‚(;M“aOí$ÈmªÇ}„±Ó,hÉ 3ˆG—¢;UÒà˜äTø¨Œ”iÍPËNa@ԆݛæÁˆ¹·¬<F”ωfeÀ 9=´Ôìa– [£YÂ@vqB diÈÁÖ;ý„ÖÌœô„¨1s%„îL.¬äxáˆ(Ø)–ê‘Y~8!b@?ë[û ‡uéòÊ\»¬!¶º¬ÃkFÉ,‡œn~D›>Éi~ó€8çb|Ïy@¼¹ÎCl5—-7z®ƒaŒ[d·‚Øê»à>Y$9 X¨ò„l j2!zQÀ›-æ’b«¡èfÂd7ÚàKõ&$Õú“’ïÉÂ^³2‰„ :‹\Ãês*!‚¸ÞÔOEîc¬vLÁ|Ï©0l ìEz1˜äˆ¶dÐBiž[ÈÅà-³è¾b¨ß  ä …—Û@:\ï¹®¶ÓkÚz"DäàÀ a«Ï(¹Ùµ 6jØs:²›Þ„Óx/¤lM¸ÞØÅp˜î%CÝ«˜ÎhêÁ°- 3W [Ó‘õEœ m©0TÝé±` š( c`ðX!ÊíljçtÚÚ¬U;“ÿÊ[CƘLµ?©q0Xïð\í‚SíORNXj¥FÞyå&Hv”—˜ˆó,ô9ù/r…6ž ÊÊ‹¯ƒl-šãäÝ.ˆnÙu¬!vª+S6â„`iŠ©èÂlotµ_™ÏK×½7|U/™à ßÜ™%ÄÖ¾6oÓN·YBìŒ)Y^y'Øê†­÷ZËdïD‹—GDBJÛÑYø¼x¥Ý°àÎÀ{Ý ¯e§µBbåqAL#î@Ôw[ Ç] ™0×ÜÖ¬ 0H+›þ¤ZÀÛ=£!Ã(³tÊNC¨íEž1 Ï7¢+Š$oýJcgÓ vBvz°’¡#É„z¦³=N v‡a§ï`®ìû€`² ¤B4Øz$ˆuŸUÉF¾Gz XÏMl [ÏBà®ÞíCÔÌŽŸ5„í—Ê:jfÏ¥RÛzàÆúýTßéÈqT¿ q•­bkÒà ß/†Šà¢Œ5D×½:m¶°½A0 ‚Œ½:cöÛ½A 6 ® ÆÎØ®ÉL:Oˆ^gf ±S.Ëhdå ¼1¬‚¦ÎžDeµì×!ZÛ[ÑgÛŸ÷ ™|+è[ªA“5ž•s° ?.œ†ñtV;5”ñŒ²SÖbþf"„ä‡m±€¸“ŽÇN{‰ÀRÕžL„¼®!úÎÀö+»Œa³Ø-¼‡¦ŒÀfõ¸×¦ò-”CJf‡ö©ìk»jÇÖž!Äûlµîˆ÷7ó‘ÙY«£ên›îªq¦¿ «x 9úóˆ×³Yä„hLÑ× mk7Îv‘“aŒÜÚ6÷»P¨‡Ùô¢Eç…S¿h·½ål\[YÏz¶Ð…„À¹Þ³˜;o´Ìkp)†ÌHÛÝgy‘ç*Mì µƒ2p@ ÖîZ×; $¬òk'“â¡kˆ­2ÁÖXÌ¢ ¡¶^³ôÙè«ó¢‹ñ?˨ԙޟ¥‡½d¦Ã¯;ö™áˆñ¬Ó¸…:#J=à ^ŽˆgAÀsKM쬲6f‘FX&)0qǵ²?!—ƶ6û”•e8×O»uª™ßNa± ?‰íÀ¥Å,²KÏéfâ-¿ã$fØb,î³ÉŽ1xÑ;ÚÑvÖ‚]v~1´[ÀBvæä3ÆÔ‹â­ùôˆÓwüº¶ªô endstream endobj 4246 0 obj << /Length 1514 /Filter /FlateDecode >> stream xÚí\Ýo›HÏ_Á£#º°@Õ—kÒT¹KÒ(ÉNÊN³%\ù°Gõ`°g{—!²Óª®*ØùžùÍÌR¤ùÒ>}¼;zwÆÍ5\F˜v÷UÃÔdš±Á¨«ÝyÚýèüêôÓŸÇßýúîÌć©Ë Ñâ¨ÅcؤåCG¨>½xÚn<­/׉]ü#­^úMÌÛ)ÏžGÜæ¶ÈŽ…5½`ɵ¬êµ¿…jŽš4îuÌȨyž‰ü1ñ²Žs§à¹îGãZâáhi)Oõ×›ÏGJé“mÒ>sí°•°ô.N'n”©x\ÇÞ$ªy·¼ÿP¦Ê×R™qöå5ö‹3Û&!†i™•!af\$þ%ŸJSìœXëô{ÈèÆu,¤CÔy\á¶ŽPÌ5eŽ(_²œ‘kíâ¥u€]ð¹HOyÎaLë¨ð ì ÷6‹$}¥BÕ¢²fÀHßMަ+d-BÈçÉ,‡qeKø@(b?4NDœ§Ià)jqõú©¿ PGº ׂžÑðf59½ ÚxB‡1GÖ11yÓf¥~išì-;¡Õ–ôVøQÁm]“x f»ÀàÆyÃÁ`Ì~*AØ­˜¥«¯Û4³€hx$Ó©]ÙDyŠ$%Õ½Ó3—+\$s?è2 Åd  m¡Éª™ ž7À„Ù`ÔŽÐõß5£B Š˜fÙ…é\§Ót²Î÷1™ÅO¿ö¤[‡ÒÄ@xÝ›Óu·ÇJD[7)TÈ’íQ×!Ù˜G¢ÚÊ%_«_^ýd³‡äá_1 ³lÐEÉT¶¿—¦º0w—4¬)Í^˜za•ò;Ý ù c:o<\Gµ†c›ñ/x*²\Eà?>$i•_ý”O³}£ã¢D25ój)Ü~~ò@ 8\2•µ#[–oÿÿ²¿'<7%ªY3ƒÑ\S_h¤BUÍ.ö Yt÷åI¤!Ÿ«ëË’ÐWMl¼º=®¿“»N¹ŸÄKd ñ^K0ÐX°¤óûRÁššÓ #WuQRɘ¥Pµ÷L°nÐÐÏ|oÜa×l»j9°@m~·ð†E_\1zÍ'߸/NÅä›:]™®wúMþÉ"†Ó«M1 ¡naìHÑMòpþþýë~K×TtÄŠòÅ«ÃMI:öo›ÙÁÌ¡-„åûˆŸëàoÄ8àó»ÿ|a×up#\¯ÓnªjB_rûÞW);c™ôY«Cu_ÕÒ&hêrvi³êêzý`–AÑR›tY%£â÷­~ùÚð®Zзýÿ¿´ {ItUît”Ñ•ˆÞTpïæô wÉÌ¡(¡Dð6ži«ÏŸ…¼‹ïÓTdÙêÛìÞ©Kq%OBonüdzÿAWÛ¡ñÕïƒÌ0ØÆõ§»£ÿaÜ!b endstream endobj 4077 0 obj << /Type /ObjStm /N 100 /First 1024 /Length 2898 /Filter /FlateDecode >> stream xÚ½[Ï‹¤·½Ï_¡crQ«Jª’‹Á?Ø$€‰}HböàØC01;f½ç¿Ï{ê®ÞõÁ_ÏAÓ°ì¨g¾~z-Õ+U•ª[)3•ÔŠ”$µq IÝ9ÐTçà &«ÂAKîëK}v<ÍóŸz’âÆÑH"s>`4¹þªo^9’$6ùœj’®Äךdøz®%¼u=gIE9—zRµõ\OZçzn$5UÌ¡lï¨%iDÆ”:…ô*>Bi|o­©ÊàŇ)åÈRmm½ÃSµ¾ÞÑSí²ž©ŽÖ0GXˆõ׆? #ÐPþW j'ƒ†ÿ¬¯¸×õ¼ìx k:Ëz®'ã”ÔLœkÕ&Ö¸ÏJ²VùœI2[[ašÌ'çÅGµQÉÞZ²¹VÜ,y9ÿÕ“ëù½=y]+Ž¥ó6 sØÄö)YyIÞm$ù|¯kêÜŒjêb\{l6¶h=‡oÊÏBÝÖŠ{OÝùùH}ÈÀ>aF~øÐ£¬¿vKC…stň¤X—Q×®vIs.¼Ë)eM×a:°·Mlé Ö¬cž¡´7!À€ù`2°Ÿ2ÆzÖ`†eYHˆˆ-0˜©è ¿A;m²žÅløÀä:1›x'.,Mdˆ`¶©´iîjuŠ–e ³©.cE‹V@™˜M[_`˜M}Ù „$Úi+Ü)PÀ¢À”(:*CÌVÁçCÌV•&…NU–õ,f«F£¼–ê}#f«£¬g1[u=‹ÙÖ®,k*­C(qX–rˆÙZs{xõêáôõÿ~zL§Oß¾}zÿpúê—¿_¯ÿúÃÛÿ>œ>{z÷ýã»o |Dysúóé/§Ï¿‘õâáô÷ÇïÞ§oÔZvl,V% ÖA»d_ 5KëxîÓôêU:}•Nzúú)¾HøéÛÿEØè½88Î)¦kÁ?@ßäà;ýƒ@ëq˜5ÏgPè;—'ófh²cîÚ-Û iÜÝÉE!cÌΊBS¸ÉÄsÔ˜íÁ0«}ç:tæ;ãÊaJž+ó¿Áaï¡%ðÕ0‡ çÌ,_᫹7à¤âwZˆØ A䀜õº:ña,b¾‰‚p)=­r0Äeþ×õ(À~ ²"¤í½­sËËªÒ †8óGÙ~3šÔâq€““ؼ‡p´f~á$迎2¿!;Ï p@¢GÓè0j0 ÇOŸ¹ù"|dÀ“‹\ŠÎ›ÚN£„cVd6W8,XнÉag·ܮ5phçlƒ>«vÕ Ïr\o窤Q F—Ão“ðÑu+Èuä ÓÚÞ$±S “±x~%SPºî›$æÎ:@]Uˆ+‰\§ßæ07Ætm–\>â`ÈDõ9lm ^–Ù®ªZÛqáô% TÈ|á,>TɪDw"Q}àäªIY“p¬È@$Ѥ°íèøÜé²+¥WÇKìDpPf]z›ÃÆ|‡…Á‰­…5˜±j1¼f$§£zÈØynÁTÞ\"ë켄¬–+ª<¿\îD¢‚„I’ÎMAöÙ@‚7•8Tëc;-¢vœHÅ;2 „4˜ÜxÙÙÇq…lì,ËP”¼‚EŠÑy”ÃQ¸a{Üs1»‰[X×¼5c5=†».Rrh˜¾?éâ-p·¹’.çµäÒï$P&]Ü…+$@“·í·Hl=™êº~Ä‚+ãY,^b?.W°,œ²/ãöìo6ä ºÞ^ý÷túÇ?ÿ•æ„¿ñÔ‘RbÖ·¿üøã›xøõÓÛ÷ õu㎜ßõn›µó ö¾Ìxá3±VÀ8}ùî黯A>¾üâu:}ýøëûôæ·ëñ%H>œ>ÇLoßÿÌF’õ~~쟟~y÷Ýãú];ÿîoßÿðígO¿¦µR¬KôɒЗ߾ûa£~yp­òϘxµ£ÏêF¹ æe0J ♡1¨1h1°x z yò äÈ3g Ï@ž<yò äyAf‡Ée 1ÐÔ´X <=#,,,,,,,,,,¬¬¬¬¬¬¬¬¬¬\¹r äÈ5k ×@®\¹r äÈ-[ ·@nܹr äÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈ=CMÒ¹räÈ={ ‡%4(¡A JhPBƒ”Р„%4(¡A JhPBƒ”Р„%4(¡A JhPBƒÔР†54¨¡A jhPCƒÔР†54¨¡A jhPCƒÔР†54¨¡A jhPCƒÔР†54¨¡A jhPCƒÔР†54¨¡A jhPCƒÔ‹ßìêf:7¸E#Q4¸Ýl$Úš C¿¹B{«s¨1Î-¹Ê<³*zŸëºUñK±Ú›änKÁ$¨­v¦ÊæaGþQû¹©û–Bm¯æ%Î dž{竃òÄF 4º$ž{vÅÏ VSïT\NŽsãJbòB®ß&á[»?u]q 8½U¼»Ibg^t¥Wõrß&1wöZf«ù•;gžÁagq]Mòø˜ƒ·\žÃa§YZY-¨Ö[n¬UXÏ•›1xC{´9¸œƒƒÏ̆û›æN7Å6®à0à+uÞæPe§˜¹±ÇòBPFrþŒ…({åɠܸ+“(O&U†GÕÜ$J®ÂÚ„ ‚c±(I£âÀV,"f³:rã7à#Wƒ;"ÑwÚDåÕ£ðû/˜œ•̄ƴa%Ú}.ž‘¿ðÄë?~©‰žjú¹ÍnúÁu‹ùί TÆGiÝIòûLtáTo †Þ)–¸lGãU¿?pÙvwM×{mÇ9¼d3á/~/Gײ[ûÔ/‘{«˜Gd·HÝ«ÉìjtZ½_mb‘ª÷á ͲŽqn­jp†ð²Ë¹µê(ÆÝy|K¸þŽP¶ Ü¢ eﺾ»p„êsHÌÁe¡!œ;ÌXP~Ûj}л»¶’ÀQê¹ÁL/ÎRÏ fý¨¦,;“?ö£¯Žª²þ¤kÆ"œ;ÌŽXhÛiží…1Ö…èM ;S™ºnDƒ„–¶nDo’ØÙO¤íúÊì…„²7\žAb§`ÆÎý~c]CÂOÕs¿ŸÕgôJâÿ«œw endstream endobj 4248 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2308 /Filter /FlateDecode >> stream xÚ½›K‹$¹…÷õ+´´7JÝ—®ÍÀØÛà•gvƒ~4ƺ‡¡½ð¿÷9‘•‘½q*ꄦZUúBºs%¥‹hiÅE¬ˆ^´w6¢Øœlô¦ldé=Ø%ç`c–i‚†¶"í¸¦Rðçù†–ò‘ü âá~½êEb&[Q$•Ï×^dôã¾,øèqß(ÊhÍ¢z\µVÔŽ«èRCúÀãAKÀkNg o0•}^¡û°^Læq_@÷bÇ}³X Þç­X*{s)6"Ї+bÅíúªháüÕdƒOqŒZ(ûpüÚ¯Wñ±dv<~ Ÿ­D Þ‡!ÃÑG(ÆXø|,<ØGx‰|JD‰¼^Å\ŒëÕ,1Ic”ÎÙBk–®ìRz+ÝïÃàôCÄÞ )ÝJÏäûv/} ûÀôd»^íW³¤ ûè˜qç«JŸ%#ÙG¶’)|”’ÃÙG*,#ù”´2DH^†C—Q†%ß·Œ¸^Í2:‡SðБ׫³ŒÙH€W˜ÍÙÇ2ñPô—ž˜VþÍÊÄà³åeFòyì‰a«—9®W³Ìy½:`§Òƒù–¦‡}NZ¯ ‘æ“¶5•6}˜÷„·ì|*LLÚ8L¶ˆ74>w†…ãŠ&ŒV{< ½Á|Ž{Ñæï¤ ½a•M:ËÐþ†¦Òo®7 7m×Л*|Mô¦F{Õ†ÞÔiÎÚÐÜ㸽iÂÐDo:Ž'`á9ð14Ñ›ÁHÞ>|x»üøßŸ?–Ë÷Ÿ>}þòvùá?ûrüþ§}ú÷Ûå7ŸùÇÇ_~jˆ í/—?\þxùíOrüòvùóÇ¿)?Áµª¡Wó^,&_}Ҳ±pß÷åÇrù¡\~ÿùÇÏåò»ò«ŸÿúÏUý×å»ïÞðoDheD9!ºW} "6BôQ öqBŒV޳„è¶bxežðŽ™ß lÃ+e˜ :u&¼d<Œ˜›&“æ "!ÿY-!¶Ì„´Î8F(-©ö û©·Z¯Yœ ™ë~2°ó.ã ˆš¦eMHÊB sG_CøÎÅ …ÌwƒÊ'f#úÎX…ÂÇç"娭!úÎuT®ÊøW#±§ªO@ì\áO«vl/¼C ˆ FíÄü“«]ï±JfCEôÐCs{¬:!ÞcÕÂd¿¸ãTw=(¸- ÑíÅÎÔ>äÛ#ž€Ø)¶'RùW*HåOA쬇‘¨‚âž<û°‚غ¦lí}3ôÂQ”sW{;G­+Nˆ€Ïö5Cß9Á*ü΀Äní çø&Á AªÓ3oÁªc€Z> V¶?XÝ nÁj ±Ó0'¸:tRL.Ôø¦{·fËt\#ð¨Í®Y¥Ø‹¬â}Mo‰Eå˜7ZË#«h›O.0wq34yrÙ\*±WAD;$„ 4æZ¢tˆ+7ž…©úÂûÞ}†Æ‚ãÆèÛuͰSO nçaF ‘%Cߺ/;ãdP‘ÊcbK†­ç7¢Ž´;ü•ûÕ+iƒ„Û5JwîØÏâ>ŽãöþÂ6Æl‡¦vÔƒ—¦‡ºªM0Ñ8EÄF…é ¤ŠŽðÈbС.Œ;Ù䫿U  ô cHÈ383"ˆ{ÌõÌ/F‚kv<:¸äe‰×”¢î\@§ ¹“§LÓsEzMˆ0®ÝÂb&’xo¨&¬îÚZ¼h*š×y‡E'O@ìœ z| AÛ| "w*(9ž¾A ›6kˆÂιv‹2ç„èj&×;+O†G½C …çõ5ÄΒäm?‚{´ žK“Ø©¨ ,k Î È9ãA¾p£Çöú˜Áv† «a~c`”ÈùÃV³äBÓA‘¼‘¹– ;« (Ùj†Dp‡Fu—™óEáÅw ½Cd?ή!¶št OEdŒY Ú*!º#•eàkk^™'ŠNx*O-!¶ECº¾„ ÇšAÚV£€’<-ç`)èW¦6ìE 6DZrÈb¹ü ˜5 ·%^Eá<}êèEùñ¥ç(‡ƒ{ O(o¥àö'D¸>ÁoñL앪Y¾Æ2­sŸ ÚvBÕE?|4œ‰ ë×%boÍÁ#ÉÔ<¤Íšƒ_†òD}x¾j+r¹ò[PT7’G2WŽ ¨/ÜÅþ\óÔü{2÷ã ðSÿÄ„¯› endstream endobj 4411 0 obj << /Length 1494 /Filter /FlateDecode >> stream xÚí\mOãFþίð—JF¾}±×ö©_(WNÀU„¢J´ª{IÜsâÈv üû:qN²I¼ëñ5´è>ÜéÈÎì³ó²ÏÎL@Fß@ÆçƒŸn>œ9Øì€fÜ<!›:Ìð0¶ Œ›È¸3±ãþqóåÃók¥žoû8(Í>t~uúé·éÇÐ\z)Ú«}ÞzY`¯üOZ-ËÄ0}Vzÿ—‹|®&¨-»³(¥æïÈEÕ—dÞY˜óîîGë¨'&/Ž®~½¸I™JÀs xéGóM—lßȦ{¯þyýù`¦Ý1ñ!6Ù6lȰ0±±G*P×bćâ8Ïùs®§“š£&i]ã‰H0…;VIÍ„‰«"cºÊõËUê‡;ƒjŸˆQ‘¥q$sؾ‹ËµØ\·Z»Õ¬¡(©Th?¢&õ·Èˎ况ϾÞêH¹°#LNØô4Í×ýay輈ÓÑ. ²¬Ëë̈³æV”—ûãÉù÷„ÛÖåušPM×=J‹è¹íl)<OÝ]7ïdÏQ,L‘f‘ÈöÞ«§Ÿ%|Ôÿøñ‡Fa(È\p8á·?ãQ^ð$‘2 ù%ˆT®³,0j5¾ÐVr±ôéRd}Q¦£,—¼ÈâP´ #D%HóW¥Ü&svè'®í¹~¥?çÃ1”1 çüJ/¦Šz¯O{PªG땪+²µð/´ë<¥-dB€ƒÕa+ÄÛÂeb^ÐqùQ˜Ž¼ æA 4|*d*Z§¡aÂó(÷°Öˆ«é÷ËÔœ6o;ÂGžÄQ\<ë«öUR›(¬øÁM’¤c… ¬Å¬TpÊ ®Gζ.o÷bEJîRœÆÃkMB¨ÝI&x!^¤~U‰ÀA:Žòƒ®„úV6 ¯›^¡@¸³š¤w_=ëé Õ&sÿ·½£°@ }é»Ð÷œKâBóWȪ) úÔ´£tl ΈÀ%R¢‘†_“˜j®ÖÖùh‘0PÎÅšTQMãÒÁµgV)Ã<C‘kÖÒŽ£èR¼ªã˜ä›XùOÒá€*GÐÉ#à­vFA^v{Õm­£}í–¾…nëêß+["„Ú1ÃõJÃ~ æ—Òu{EÆŸ¦·iCÃ6éGÊäÂ×w›—x¸†ú"í_òñÜŽrà²ÞË4á$9àI¯Êì€Æ"¢wÌW"îîÓ íŠÈ.À:z`%eRÆþžM3¬€^;áØ³iâÍoýx8Nâ‡/%¢’2Æ|ÔÇtÔ®¦ì]?h‡évR¦Ÿuì¢VPM*yǦ=uí•›c<åš“ç[žÅü>g‚“Ll(#»Q¾=;=¤°–$éi`ú%½€öï}¬³ä¹ŸŽòïøº¨å¹$.ìYû F½^æ„®ÄB'Dâi4È ô99ÐÕ`×…YÆä¯}ož°öØÛ¶r:÷„.Là­è(„ö¢3¦BÑÞ ´%[…‰¼êý+AÓ+x>x›#5 ‘xÔ'p¾ÊE_DéhÚÀwÁÛ$t~!üÝã(Y6.Âæ<ìBc bàÉ}. ÆIˆ«©Y5 «µöæ6r»2ÅÊ8ÞÉð;þ_“á Ðë@×bò¿s㎸ñwŠ!€ñqçeCÛ¾ªÛà¦î²],kR4o¯}V†*éí{¾p Gx\èqJ†5#݆789C(Šu½~¿›.ë>íæß‹¦ºœ.{òÒú‡N‡þåÕÓüÛ÷o»_½þÊþÆ€@¦ó‹3ÀßOhßçÿÁ‡÷1B&úFïÛX©}¦ÿ¯ÿþŠ×"Úæ.ñî{ “ó´ÀK·Nÿ}º9øŽn¸ endstream endobj 4249 0 obj << /Type /ObjStm /N 100 /First 1024 /Length 2929 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹pX¬â °-( ‚¥CbAE^FŒ]CZοÏ{œ©ÙøàîB·!X\MÏãk²^}‘kYrHÁ²h5,äÚ9(ÁRæ †¢•ƒj›÷ÐÓ|x„¡ ƒœ‚¤&Iœô£ ȉ™n•Ù‚”1¿Q‚´<8ªAzßmAÆPŽz³ùÜx‚Ÿj Yç§*!—l˜C3Ø>§ró9¼Á‡ÿ4Í Y¢s´'¨Â4Ƶ0Ê\ÓÖèsÅ §ÍÇ bqipX&I©r’ÓI2¸ ¶“t~½Ãxv ótXv–Ôz¥ée2ê°ŸÔ 'íÃÑ'‚ÿ8Å€™ ·CÌ&Ú9öV¤ÙÀ¼Dê\~°i­a6¼†ÈùµJóžë3hb>‹Ù`•óÌCÁš0v±qHU4.¥BS‚W11`æ˜MEðn°X iWVJ‹Š!fӒ泘M+LC̦ÛÁÙEÇ|óˆ%ãl·„Æ!Uȉ0ÄlàXï^¼¸;½ýÏÏ÷áôõÃÃãÓÝéÍ—>ÍŸÿúãÿïNß<~úáþÓ»‘ÞŸþ|úËéÛw2¸;}wÿñ)¼ƒ "Eo©Æ¹š¢À°MzÄËṯËáô&œþôøö1œ^†?üüá_÷û÷ÇðÕWwø³Ž64æT®,tþîG³(=Òù\Y4üÝb¡½ÇϬZb§=¤ îÎ.ÂÖ·XÔ…,XÀ™iÖØ 0ø‚h¬,Â9ÅÂz¬pmDl°N­%„ Ͱ“*,¤/d1:ÞAkŒØË$Å 7ÍÆlå·Y4YhœZ#ƒ0¼dœ¡°hD\›¤d‹¼ëï°­Dº­ËJÀ‹GDÇ-+ej>Õ)äò’} ºr3$&„$ç`:÷d—ƒÙBÖ"£§s(ö±O¡,”§U…“xÞ þÅ„oC]©‹ž¢ÂI;‡‘caú¹Ë!/ä0*ðÔ9”Ôá3Û>‡±ÒIU¼8ÂrG¸J8§{@fŒì.¦q˜è°fð––â*+×BacÐcAØ@Ôà¶P)X"ävò+èˆÈbÌ2Q){ÆJ 0KA¥ráÀô&õ¼ÏIøBmd 3k?øHæ´ˆ \ ’ÃX0¥«¬;¥b)tšDAm…škÑŽb›¨¥?³Œ]z‹\Ö{ ArMw­Ð&¢G@Ù¼I›…®4‹Öâ@A)¹6 3XøÀ#ßZ ]ŸåJ©Èµë5Ë•Š [,ÒXï® ‡Èˆb :ÊJ)e'×[/T¯‘ÍSˆè“•´ ×­+#)ÊN£mæ/ÕhacùÖf¦=–fÛm°qδËÁ<9m{¬_¥V/¹¤Vý]8ýýß$ê¨áBËÙ­zøòÓOïýáWOô´PS>ë•I`—äòCÃþ »<£Îqzýéñã›{§×/_…ÓÛû_žÂû_¯Çkp¼;}‹™îž>³ 6‘ùÚŸ¿|úxÏKãüo»ÿáÇß<þæJÑ:Û¬=_ø„o£D†óœÎUþŒ‰g/|f+í<(Éâ¦\Ÿ1T4tŒË :ruäêÈÕ‘«#WG®Ž\¹:ruäæÈÍ‘›#7GnŽÜ¹9rsäæÈÍ‘»#wGîŽÜ¹;rwäîÈÝ‘»#wGŽ<y8òpäáÈч#GŽ<.Èl‚]âƒìõù ø ú ù ûÀ‘őőőőőőőőőő³#gGÎŽœ9;rväìÈÙ‘³#gGVGVGVGVGVGVGVGVGVGVG6G6Gv5©«I͑͑͑͑͑͑]ƒêT× ºÕ5¨®Au ªkP]ƒêT× ºÕ5¨®Au ªkP]ƒêT× ºÕ5¨®Au ªkP]ƒêT× ºÕ5¨®Au ªkP]ƒêT× ºÕ5¨®Au ªkP]ƒêT× ºÕ5¨®Au ªkP]ƒê4× ¹Í5h®As škÐ\ƒvÑàû5Ñ®3žw Iv#ˆ»¢ÀÓ[ƒãÿÇA*#8‰Šä±4&œœ'/=öÍ´meJ*RU8‚Šä‘»&Hiö^+’É®G±èH É+ d+%ë ,VÖ³v°g¹’É-k‘Úk̯J/6Ö˜<Ü«†»SØd몬2b1–¹Ð\ )ÙØàPvaS/#]D9ÃuhX8†šZÔ­2s¥H¯$093'Qº"—ÏUxÓ0aû \ )ÉI¥•h+wƒuP1TûfS(²@‰ÞêhŠ»r%R-—cHˆAœ4cS|V€‰I•²e²°Ü¦ $d{ER¤«b½‹˜]PÿZ-l±˜dÂâ²Ïá<[é%íS>[;´ÆÊ« N¢(*iÛ'%­ßÖÝI3b*2 ²B<Ý$±°ñ <ãå6ý2¥`bjÝ Ú-¿m+÷£D$†Òxy À(Æ<Ú‘qP3 iAdÏóÆ¢¼scåý 8Š^6³]é) Ä»Y^Hi3ÓC]È~PKìj’yFA‹œ×šÚ[‹K¶Ë³”„ú—y& ¾n¸«œ×&™<ö½R:Ï}w(ØJ‡9¨Êó*0 Í‹G;V¦v<@agÔ)@*ó–Ó6…¥™]¦g~fÀ€Zm—ÁÊè ?þ‡ïÊì3h £ϯظRà©JÖ= K“[Af-‰­ú»)¬±E6y?Bs?Ê%²gr%‘1yÊû$D––~ß—#µ ‘G ¨BÎ¥µ!›ŸPoñ,ÅfZçù’6¤4ÛÅx_ßPžl(zK€Gn©ØA,2ÓkBµGÈIEâtIÛI¶¦õÅŸ Ò)–•7$°=ØËÝAÈŽ<^€&"%нá(å­uXZñ\2º<ò$S Ö Å&”Ÿi+Y¹ Üx^G¹p€-6ètŸÃÒŽ²GÞ^»p€ËNv…•‰m‡*æåò3xpžJìrÈKÃÆˆlÞ^8ÐJsÃÊ#V–[ÓO_8d²Ï¡¬t,ñx9éÂGÌÈp÷9èÚF]NWYäz.È÷9¬Lç*ÝãU¹ÁKÞ²+e¡È(otv6‚Pi!tñze§D7.Ô•ˆRÇŽgµ¡°ÖH¬g“Ø´=“è:¯¤ì’cmÌJ©^I0»âIô. IK»¦c6æ®,2[37XY÷fM˜ÜžI x6’wY,u——ÆiæÕsÞddÑÇ»…¼ÀtXÏÒ{Ì«´_¼è?úfÏrmåïC@ ÆßÒ`m,‘L¡ÂÜlè/ ¼ÅÈâ¡”· é­ös)¬[ýYßÊ‚àÉnacù×ÎØV·°­íÉðXüÊah,´‰=KOõ•ýFç¯ îqXj¢óúJÎjÞsÝ%ak•М„±I!û$F]˙۲úâµÆ™ò&ãíã-…ÊJ™æúÓ@ —K’ñ”w ·o¹®dAÿ,m^0íŒê®rÌû¥­o4ÓëúΛ×ü¥Û,X­3»i)ÂAíó·ËìŽð”©V›7K[³£:D—cùyæEoq9–'•›Îåÿ 'ù–N endstream endobj 4449 0 obj << /Length 521 /Filter /FlateDecode >> stream xÚíV]oÓ0}ϯð£+‘̱“H¼ÀXÇ Â†”!ä5ÞMe»þ=éXÛeöÌÊC£ôÞ{î9¾Fà p<̓½)OAeœpŸŒPDcŒ#N3— €G¯ž¼Ÿ|È_ìMc¼fL3¥ˆv¡®ÌpÌVF¢wÖÉšuøÓ<$I÷‘öNFÔMôDkñ½àÙšKRJá)bh@O6þÄœÀ¢¸Ý{å‰Gò.à£!Ñî‰R Vùö¯oƒã]d;…2ƶY°ûÑ`þy[oåR ãÌãv÷ûñˆ-xä•4‰R[¨h_ÎjëRËFÒݲýr¿HSµãaÜå#¤éïpâ§¶m¬F‹´û§Ï£ËýqèV½×¼}®uúúßÍ^/„Òò¥0ªþæ§‚ø]}O:|œöøËùBÌ>ËòAXàÝ¢Fö#ðõÙ'93îÂ;à6­Ñî€ÌBéKêi@Äîóa< ÷0†ÙtÀ%û¯Ë¨.¢©KÇŽåC6ÚÕ˜#lg™CŠ> stream xÚ½›ÁŽ·†ïû<Æ«XU$Á€mAI€,’:Èò"0bìÒ pÞ>±›=냺gaÅÙí.~M«þbs$“†$“ÊìØÔ5äּтö?q fæ 5ù]Ì¡eñF”¬xKqJwh)LfòßÁ¸XöV ¤­_W•å¯-Pí]樵ê- Lì½£gæ~oÎsë×I`åŠ>²‚ÖÜJ¶À¥9KÆ4ö>2!i·ÒžÃBRȉ…,ê× ‡¬Í­H¹°÷!rÕ‚>D1Õ­ž¸[Ám¬ý:Ç­þCp‰²[QŒ©÷¡øXª÷¡¸­-ÍAS¿—(UïÕÇ- *êÏ 4ÕåÞ´,÷b.j¿×RÐ… oÄ~‡q0îO„³…Ê$˜RCb3ʘD+µßQ‚5êöj(Iú½-*n¹¤€)ò; …"âO^8-~/~”’üÞ"æ} ¥™÷[,TêNRJ¨œû5ÔÜ=æ«tïª)TëîUáU¥ûAåPk÷@¶´üUB#ó>ª†ÆË_-4é>„ajj²LE³îaœV»µZë^‚ITwx%î~ÒÜ{órÜ7IË讟^.€§²\Nµ»&œBD˜'<3Áu“7щO$ôFŠÉE½‘- 7ª,wh¢7j‹ó%ä]HBo ÿG“`órzc·#÷CÓŸW’7ùo vs‚ã¢é«ŠßÖ×x¦t÷âÅÝéí»§ïŸîNo¾üôÔ?ÿí—‡ÿܾüôóý§w ‘!½?ýåô×Ó器;ýxÿñ)¼c©ÑŸ#ÕèËŠµEŒµcGÁeß…/ÂéM8ýùñíc8½ úíÿo·ßÞáßÿÏ •cÂ0«ƒå%±a”¬¢–¯CTA5ú,™ZTê‹5z´1+1%þ:1M¤°ŒéÀJÏ ¢ž̇¯mÉÑÚD≠Ÿ@ä²T0ø0X¢F-ŠÉ…L¤(%6¸»Ö¹¯ K…—Ô ²+P`aô 4( ÅD»n‘çQ ¨GEpS)±'¹ªQLÔgªìALt dȈ%Šü¦è9×R¬€A–‹ˆÇ;±bâ2EZ€O"y2G,”°,0.Ù}äVá*It)°"àg‚&8D˜êÒ(2Ò˜&Ääjíñ*„)6®7òˆ3¥!p{B[c¦Óá[Qp®u‹¢¹ÌrL®Ò,J¡͈&Šäâ¨äHÐoJˆä¶@ÁðuŠ23N´Ñ¥Q× ”b×aˆU-ï…í™,åØKi‘ 'J¢ FPÓ½FSÃ"w¡;¡û(\x{­;ë£Îœ ĉE’wÈÁX]è1ÐÌ逴¥BX îé•Å!Ä̈ÉñÏB¢káž !‚@Mg=vÍQgê»ó³(Å‹˜#™™; îRR.H©ÅøBgÊí†äéUÔ B:ö:èˆaæ5Žêé‹¡éP¡üV{uŽäºÑ&º%jéXÁ7ÈÛ’ê1±ÍŒU-VÏ™+…ª+Pä4_Ü¡D†b+},¬SyNÝÉämîHX³Aˆ¢‹Š#š¹B JÆ÷`€Â!èªcˆ™¡*sì»=ñ³‹½#n3ƒ6Ê®ç6| ÄL·sAIgÔ„Ò—ìÄÔ€Y)ª×†@êÉ@ÌœŽVbõm‰B¡.P_°@ËÂvre‰b¸@MøêÀJMûUG™­0e£èÿ·K(¦º&ê=õ1¨˜˜¾Yš»köx¾WtÌ ÍѤa,ú»†’¥É¢íîÍVYk´ì›z¢uŠš´çô¼WüÌÜCôÎ*|`ƒ€È!“cˆ©gu¯WãƒBP‰*ç (¦îdBA•3EÆØ¸[SÈ|E‘•à¾a¤QP‰x !Þí ΉºÇßÔä¢ð Y|•îîPÌÌ Úbè•¡ÿ=s`ÝúûŽœ+ŠÝ‹Xt…!øë¦ñ2#ÉÒ óEâ „UâÌ-Ë…·!¬ ï¡ÌxÃ*ðŽæ勾ÛV}wÈPçË»a•wG SkòUÝm «º;b˜[’/ân0 qwÈp…’<'îKr­È3RµÛäÙ4É!ÁÔjܵ$A[®£?fh³·’¹A̹ªM.êà ê¶æ›TâþžÅJ=3![ò1ÃÔRœSlbglº„aj%^"“œ4ýxÄ!ÄÔJ\Ñà„¹Ú¿bj¹UÏ‘DeÈ9;†˜[‰C?)!†+™Cˆ6?P2¢•‰l‘’!¯Ú^ÕuP¹A,±òajå7‚å€Ñò˜bêÖ嘵èÇÁ|>D[`?ȱ³<êüwo,¨nüT¦ù):e¯?öêϙҶE?¸AdB¨@Ì Ûúksƒèë’!dæ tÆVÏð?{w¡3µ„ñ3•¢¦Xè˜ÁfV;ÕÏÞ÷ß•åw¿ÿù—ß?þú@¿4÷‚×>án?JË…}?£ãþ- çéß±X:6e4¶‹ÛÚà44<y4†e–yXæa™‡e–󰜇å<,ça9ËyXÎÃr–󰜇e–eX–aY†e–eX–Åòû9îÊî§H#ýËZî¦x>óW¥’oóö… xôñ…WÂþ]¢Ã/œ_ÂÏ!Ö3Cgº‘â"tê_3‘X=’IAŽ70!íîÇÑ-züO£Ã€ endstream endobj 4454 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ3·Ô30W0P0bsC#…C®B.3 ˜’JÎåròäÒW03çÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(ü‡‚ä1˜ÿÿÿÁ£ŒQÆ(c”AW…Å—«'W Ê  endstream endobj 4455 0 obj << /Length 361 /Filter /FlateDecode >> stream xÚ핱N…0†KHºðôªDãÔäzMd0ÑÉÁ8©£ƒFgx4…G`d {N[  !Ä\'/Ëé×6çü”óy–Ê+‘‰Kq"…”¹ù¹x•üƒËìBÏgz"7«/ï|WðôQèžÞâO‹;ñõùýÆÓÝýµ<Ý‹')²g^ìŸ¸Æ @;‡?&yxÄ|*t¤‰ŒTT#…Ôcްãú‘ôFGºßšjK Œ©ÆR¶FgIA£óö–°cƒ!„ 1 î'ŠtåÉU1¦Ä@”¸ª©IoIe3óC õŒÀqG`¤,Rh„-Rdd.R¼B‰y¡ ¤6SiŽå ÿŠsfê—ßo{O¬uÖZG®uò²|¯„ž|Çùä{Ó÷­ïéf~ûAHZØÛSãïŒ`*¡¼€p·@eI+¬b`–(ö#)ºÏÅéÁÀ&Š0Ðð›‚?ð&Ϭ endstream endobj 4456 0 obj << /Length 360 /Filter /FlateDecode >> stream xÚ½“½N„@Ç—l±É6<ûÊaDŠä<)L´²¸X©¥…Fkx4…G ¤ Œ3;;äâÇ¡“Üå—ù^ö¿Åùq^¸•;sG™+N\qê3ûb×9:W®È9òðl7•MïÜ:·éºmZ]»·×÷'›nn.\fÓ­Ûenuo«­Sh¬h™ ŒŒ%"0q†hjè9uT1''Ðad⪖ò¹Ê·n”Š|̇´¯ l@ ÄÔÍÿ±Ã‡|s,èT¨¨ýx?ƒÑ·jŽôkÂÌ(lý±Úð¦Ÿ0ž± §¢ùÉöåALÁú;–Qì78ßú?`ý'Ë%L~ÀI0>ŒÑ`DÛ{¨=c/ŠÚGÓ+y)¦ BÄ®„oÐÑ"6tϼxƒ“ùœu6Ú¤äÍD£ÕêA‰¬MÏj¤^_49Z9Gä³4-d¦ðáG5k­‡–ÇKCæ‘H\^ª²—•½µ/„@ endstream endobj 4457 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚíÔ½jAð‘Â4>‚óÙ]C6 ¯LeR%)SD’.p,ìôÄçHaqrpåÁqvÏ%ˆX$Mp`?~ÿb¦ÓÒ—¦MšnäsMí+z2øŠF»D;»Ïã F1ª1IŽj 1ªxHo“÷gTÑè– ªÝÒ÷ ÐeðÅÌ.˜óD æÍºþrwTcy‹ zMþj¤ÒgÔ´Pg?QÚÙÉ(ûn¾!¡•v5æ|ø™W”ye¥¦©o¾ÓÌP^jûšW´rJ‚–­K¥¾**Ž(?YÙ¯(=ë¬-ö%ëůŸ¿öc¼Ã-Ê?[ endstream endobj 4458 0 obj << /Length 415 /Filter /FlateDecode >> stream xÚµ”±NÃ0†eˆä%?‰ L•J‘È€bFÌÉ›ôUò(}„Ž"¾óÙ9ŒMU9_bÙŸþ;ÇÚ« {m:³ñk/ÍÍÆ¼[ý¥­í þ<ã«·O½ëuûìçtº½÷uÛ?˜ŸïßÝîoÕíÞ¼XÓ½ê~oÀK©‡é¤À¢ü5„ÀáP ‰Jz¥¶@O«™¨‘N‘üZªTjŽ*,x³"á¤a$*™T€‹‡ÍY­p‰\Ra5Va5Vaµú¸ÒUXUXUX†Uˆf7'µ¤BjI…d’ $RK*$sȦDX‘1Q PÆýG—P¦&Õ2kÆ‚ÊԤ̔Ñj *SSYjræ’­’“Ëv‡ÌLÈ I©9©V8©V.R­š ¡VŸdj¾@‚šI¦æ{Eää{e»Ê@–š“©‹Ì©\Rãó ZÕð̬jØ+«Z3­g’OPR£¶MjÀ±!YÐb‘ mÕBÛFµp|£Z83Qm˜EwÕ¼-©á‡d¡‰xsÒw½~Ò¡¾¾I endstream endobj 4462 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚeϱ Â@ à+B–>Bó^k­¸ª‚ÄIÛGë£ô:vž÷7HO„».!¹$‰'ó˜C^Ø›L9Yð%¢;Í ñDâ|£,'}àYLzc£¤ó-?¯+él·äˆôЇ'ÊWlŒ)•²¶½]¯ ÁJû¬aÐ@¿…£7ôÄ*Ñ8ºÙn¨•>ÒSúË_øWføÎÓ9sÖèä7p,"®Fâz"ª¾§K˜ŠýŽA=è7ƒcÙ×ÝÚ™üwߦÕ`PÓ:§=}Ù—š¦ endstream endobj 4468 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ-ɱA…á“($§ñ ç Ì\v³T’µSH¨¢B© $:óÈ@\#Qþß_‡õTQUE&ªMGã…Ö-nÿu8³M [Yð,ÎVº]ï'†v=WéN;SÜ3uzÀ3üãéxîý:côÁEâ†_Ïìœ endstream endobj 4472 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ3¶Ô32V0P°P06S02U01SH1ä*ä24 (Be’s¹œ<¹ôà ͸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  ÿþøÿãÿ¿úÿüÿ™ÿ3Ô3ðq¹zrrJi` endstream endobj 4452 0 obj << /Type /ObjStm /N 100 /First 990 /Length 1717 /Filter /FlateDecode >> stream xÚíY[oT7~ß_áÇö¡>ž±Ç)B"дH´B€ÔK”‡-,²(Y$úïû}>ÙÝ@ ÒC*ÚØsì™o®Ÿ“’\JRÄÈAsš  rÄY4Ôå\9ˆ®Ž’k}—š“0nËN4È £B–J˜§ÜY4'ÖF18)‘¢£8©™\°XZ#0UѾ.9ÕLaÀ ±õuÙ©i‚ŒX€Ö2iÕi©}4hJ¹)¸,q$.J%礠(7E“‘_J.ÚøÔ\,Ji)»XÍ ÃÀ¥uÎ KEi0ƒ@­(¬„¬$c‰i4”ƒðDZ-PU ¤Q-…½µe×gÁ8šHK¤Á‘V: *hë4À4X ö"œ#Õoä¡‘Ö‚½0´’K¬Qi(3)M"Xg1îQjÙM¢± z(AgÒ=à p1è1:Ũ‡ 0õè60ê!tŠQ1 °Òiàl­ÓÀ%ƒ½”†§z`+ddè!™¨²‘ÆàbÌaÄÐC¬pÔR †=\@Zf‘/Ð#Ò¬ÓÀ¹”NªR; r+ôŽ´2þ;Ò =$PßJ=@Ø*1¬9C¸c”ƒ3U®ËÌ’1ôŠ3¦hÑY¦ª)'ŒzÃÓVã Þ‡.Ì $ŽU¢¯¢µ¾£¹,J³#²DJ+‚QEâ„’\ÖF÷äÔÝH=ˆ‘aTËloo6<ýçí wON–«ÙðäÝ_«>x|ò÷lØ_ž>_œT€p4ü<<îJŸÌ†Ç‹g+w¨¥ø 0¿€¤µùRù¨ŠuwÝÞžž¸á§åÓ¥î»ïÞÎ_.|¬ß»;wføÿßAˆ„+5ö ¶’¤>wPâ“]…hB){–† Š}FDïFã„(r…á«CòxÆ¡TóÌD¢BEº5Ñ3«¬eo!EðPù¶@”à¥!±` 8:*c´”yTóÏ£ÈiJŽ|C©óRi‰â#SÁ‘Û-ah4ê‰Wœ89=)Ë⋤«Ü1%ŠŒˆ¬‚Í+j‘ të^Bɰz ›…˜‡L¡؉oÀbø›ËU9¥!Pxfm@¤è+ÚŽÝ ò”Õªø†Cc"£N0Fv‚qroüBöÆ ¢’Þ²7Ö ÖÞØ âkxc bí &õÆy†¢oòìo¥(ÐUºÏƒÐ:m½ä‰±ÁPu'†8åIÞPÙEžcPÊN»íe: Š£ò‚Ç7ºâÊ„fPEÚCÌíïN mÂr­) $”-+cvîÀ 2aL¢êÙ¹QÚ˜»@LÙ^âèCåUí%¯µÉpˆãfÑÔ×+‰§ô0ðÖƒ&³U…7€ýŽÉn„ $"/WÞÞð×þŽ)d»­6šój ‡‡öJ‰ZÍk§r²VfŸCÛ¢@|ZÒë ÈÓ·ÙI#ÊOé›7\:A¿êÆ1é1Žšm¼‹Ÿ£`ýä¥ý(Ê„ ‚κᎾAa–¯(>y÷úõÑzñÁòdÕ¹d^±tÜuP š¬'¼‹­Ÿàž^[î°.Ÿ=Y½Ý?pÃÓÅû•ëÜqM9ßs¼:ú6ý6ýŸMRw›õL¤ IObœ ¿ÎßðYŠc¦ý2_¿w‡'_Â…¾Wƒíøh\µ¿¿Ä§îá{CÞ*\¯gËw§Ïg=_?N¼oP öÝQÏʃãÓ³Õ½WóSW ùáü|‚žb6üvü|õêl|ÑufÃ'Ï–ÏO^Žo;‰«)àl|÷H3­K(#è/üɨa®áÔmŸ{ø‰]‚ÊWÝE3¯Á¢Ì¿x±8]œÐ ‡%s¸§¤Á£ø>_¼pÂ0?ÿƒnŸ‰Bö²%*‰6…‘ì`£4„œ8µÍ”¯[-¯§ÒŸ–õ´°º6Ü5£¤´KQN›(Y?Œ 1¾Ø½qˆT½"œl"$ÇË’>!¶‰‹>Çë8¬ê0¯ºµví‡n zw;Éó…7ôC§&ý7ò;‘Çá’W¾˜ÇŠHhµ#\-8?] ùæ¬Á8•¿8WqéšÆ÷HLb¥hàÙ7þâĵ½1%>0®CïÞ*öÖ“2pÿu[oàX†TpÊW=7vmË\ËÉÖµ—“¿|"ùË6ùѾ#w¯áÚ–‡yË[×¶þ-ã‹“Á.ÛŒ¢Ö6;œ ýëúLV.gCùD6”m60ÈâMV6Ùð/v4 endstream endobj 4479 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö32U0P0UÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ!àÀ …`ÀåêÉÈÓŽ¤Ô endstream endobj 4480 0 obj << /Length 98 /Filter /FlateDecode >> stream xÚ͉=@@ ÝwŠï¼}+6j?‰-$T Q¡TÎàfºG6¡¡2´JMé,'Å uw5Lão 2é¨RÝâkîÛ1C²&§B öJ3À<‚ßú‚Ò£ÅÀ|kø endstream endobj 4481 0 obj << /Length 97 /Filter /FlateDecode >> stream xÚ32×3³P0P0T04U02Q02VH1ä*ä22 (X@$’s¹œ<¹ôÃŒŒ¸ô=,¸ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿƒq¹zrrP) endstream endobj 4482 0 obj << /Length 188 /Filter /FlateDecode >> stream xڵб Â0€áŠƒp/Ñ{“(‰8 µ‚ÄÉ::(:×GóQúJc.½¡Yt²P>z !ùÍtl JœøWÏQϰPpM3IŸôãt̂أ6 Ö~ Ânð~{œAdÛ%*9Ê#Øê$!óê i¸&¶‘ Ý“ÐRZÆT²,˜wDHcÚ/¸ÿÑþ&:'>¾ß¶¬z ¸ Wâf\Ð÷äºýÖ]y¿¬,ìàLiÙ“ endstream endobj 4483 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚ}Ò±NÃ@ `Ÿ2Dò’7 ~.AE—T©‰ H01TLб$˜Þ¬}“ ^àCoˆbœl$8ƒ}¶GÛÇEAH9G§Žs|B7“>ëÚnñ°ÁE‰öŽÜ í•LÑ–×ôòüºF»¸¹ í’V9e÷X.‰Ù@̼c¢Dp#JÿêЊÎÿê‡Eïš¾¹êB‘—0ŸmkˆöªæâUi€Ä ”4p¤+nál¨ˆáM—áÊëÞ×#m¿všª ¥ #%í”âF• …^òQ0Ü_ß?Ô½ð²Ä[üPü¼ endstream endobj 4484 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ]Ñ1N„@ÆñG(H^Ãx'p@–$ëšHa¢•…±r--ܬ5{´=ŠGÀX¸a|óæ#2a~a†üLS_”µ”r©Ws%õµì*þঔ0ô6l¼¾ó¦c÷$MÉîNWÙu÷rؾ±Û<ÜHÅn+Ï•”/ÜmÅûH'ïÏp\H~"JlˆìÙãÂ_2üÌo8„p°—¶S´ð³G3‡™†ƒ©†£ƒ™@Ò°©Áèm¡†M “™A ›„çøÊ³ým'ˆO*`³•)LVÒlÛ•Ìa6دÚ9¥0ô/ßvüÈ×IÕ endstream endobj 4485 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚµ‘½jÃ0…¯ñ¸‹Á÷×¥ÎÈÔC!2„LIÇ É,?šÅàQC°z®¥[¬OÝ‹tŽfÓÉ´12ÎżŠ)ä”ó7›"äy¿süâeÉÙNLÎÙdÎÊw¹œ¯Ÿœ-·+º–=z\®…(éH?ëḵ÷ŽT jÚFX4ä+TÔ:t !R´¨G•£ª“ÛíÅŸÞˆFþ ‹€j€Ó#+Pÿ Ðüþ:Ö† ÖO×푪?8êqw›hZT«±ÆãDÈÖ¶ˆ®ÑAÖÅvÚi}÷Hþþý«ð¦äþ6n» endstream endobj 4486 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚÏ; Â@Ð,¯q yЙ(‰é„¨` A+ µ´P´Žî,àF\”!ãüR,‚3ÅùÞû> stream xÚMбNÃ0à‹2DºÅà{HBS S¤R$2 ÁÔ1#æøÑnã5òdôPzü&%êòÙº³Ï¿ÜœŸÖ ©¤‘“Zš3Y^ÈsÍo¼X¡XÉòrê<½òºãr+‹—7(sÙÝÊÇûç —ë»+©¹ÜÈC-Õ#w!3¥ÞrÍ̾47ûV©2S¯dÚê­ö¼öDnˆŠcåtf "‹ GĶ­¡"y³93û# dÁu;œ±Æt‰id›ð(º™âˆøÏ¸›Ùã܈Ìn@?à)¯ÛÛ“Ña‰=RUüC ¾îøžLÄŸµ endstream endobj 4488 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚm̽ Â0ð@†Â-y„Ü˜ÔŠŽ…ZÁ ‚N⤎ŠŽÒ>Z¥à tÌP<ï*Ýò ÷ñ¿™Ÿdsô8å7ó˜-ðœÂ ø÷8”28]¡àö\ƒ[† >îÏ ¸b»Ä\‰‡ýB‰*Ji"¥ Q£l—wŒ‰Ü7=“|F4ý°cZF׌¤G䌈Ñôæ=’D?f+ÉV’¥æ‰LÙ3ë,Õ6¾(ŠÄ7Ú*ªªÎ#¬ìà WGiÒ endstream endobj 4489 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ó34V0CcS …C®B.#° ¢’s¹œ<¹ôÃLŒ¸ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ€à?’L2Ódþ"åÿƒÈúÿ€äù@òÿ y€ýl`þR%ÁˆJ6`(&ÑÍDA 74°ÿƒ» ìο?ìnþvÿ°_°ÿ``àrõä äE‰c endstream endobj 4490 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚÎ1 1Б-ÓäfN`\‚Š .¬+¸… •…X©¥…¢«íQr„”)ÂÆ hoñŠùÃðÇLGó’Æd² ™]J¼£ÉÙ8yq¾aÝ¢>)Qo8EÝnéùx]Q×»qÚБONØ6¢¨R)ù¢—ADdPQe^ÅêË:¬ÞºA—À¿ìçÃLX²…ŒðæúP¤ÂsLj¸nq‹ÏV endstream endobj 4491 0 obj << /Length 182 /Filter /FlateDecode >> stream xڵα Â0àH‡À-}„Þ˜¦Æâ¨Ì èä Nêè èÜGÓGé#tÌ wBQÔM„䃻„»ßä}=Àùš‡#Üj8€É¨N¹ä‡Í j‰&5¥.(7ÃÓñ¼UÌǨA•¸Ò˜®Á•(„ˆ&|WTퟔžµ 6FA’òÖ#c/ÈÄs†¤áÿ¯§ªß ?û9ÓÖÏIgÕeãœ^D­ áJù/¤m-7$L,à¶Î—‰ endstream endobj 4492 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ]Ž1‚@E?Ùb“i8{ƒ bâ&ZY+µ´Ðh ÞŒ£p„-)ë@,“™—ü?ÉÌ׋t¥Bµä‰Ó¡o=)NXΰ¸>(7¤O*NHïØ%möêýúÜI燊Hê©ðB¦P=€ÌÕ€sžó[ˆNt­×ƒ…C`™EY(›)j× ›‚kІ¯ÏPÎ`‡¢þ5ÿ••ìàW¢GÆ©¾œ²t-pHW¶†Žô<ÑcË endstream endobj 4493 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ32Õ36W0P0bcS …C®B.cC ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. õ˜ÿ`ÿÿƒÁþñ†ÿÇÿ0þïÿÇøŸÿ3³ÿaö?Ìøý>üÿÿLH=-0º¸\=¹¹ÍÈj2 endstream endobj 4494 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ±J1†G®L“7¸Ì ènÎ[´rá<Á-­,ÄJ--­7¶’GØä ÞøgµÑJ¾ 3?þYû£n%­¬äПÈÚËñ©šÏŠ’ÇhöôTñ7` V‰`ɪN´T%Zº àw:û~F¨¨b.H5#À@'ÄúJu– ÓHd3|MÞ㢿˜˜4Äé'rqúÉ– 8*U$²ˆ/¾á/© endstream endobj 4495 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bsS …C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]þ3Á$;˜d¦%ùD²ÿ?$ùÿ’vü?€dÿ ùL>`ÿ'€É ’aÉÿÿÿÔÿÿIr¹zrr7 Šå endstream endobj 4496 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ32Ö30W0P0acSK…C®B.#rAɹ\Nž\úá F\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.Oæ ü?äÿ€ý?ÊÕàŒÿþ#!þ ìÔFÿÿ€#.WO®@.ücQZ endstream endobj 4497 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚ32Õ36W0PÐ5SÐ54S02T0µTH1ä*ä22 (˜›Âä’s¹œ<¹ôÌ̸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 Œÿ˜ÿ7€1ûÿ&RRO°?À`ÿ31ÃàÀò@lßðÿ@ýÿþ?ã†ÿÁ˜„ëÿc¨oÿtöþÿ€Þg`àrõä ä—‹¥ endstream endobj 4498 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aS …C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Œÿþ#!þ ìƒ ýÿÿޏ\=¹¹õ'Xr endstream endobj 4499 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚÕ̱ Â@ àˆÃA–{„æ ¼V¡­‹C­à ‚NâTÁ>Z¥pc‡z1í䢻Càû“ŸÄÓјBŠd’& "> stream xÚ31Ó34V0P0bscs…C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]þ1üg`øÿýÿ Éÿÿ´ãÿ$+øÿ0°ÿû$™ÿ?`ÿ'€É ’aÉÿÿÿÔÿÿIr¹zrr¿_u¬ endstream endobj 4501 0 obj << /Length 169 /Filter /FlateDecode >> stream xÚ•Ž1 ÂP †ÿâPÈâšøÞÓŠc¡Vð ‚N⤎ŠÎõh=JбCé3ƒàæ/„ü_ê&ó)[*µ<[ðÙѤ[ÖqXœ®”{2{™É¬•~ÃûóB&ß.Ù‘)øàØÉŒQ B‹(ÄF]Ô#n0nP¾A¥Èjdµ¢4_Aû~|>KF­Aš«ê¢Vê‡L®Õ™Vžvô›kó endstream endobj 4502 0 obj << /Length 183 /Filter /FlateDecode >> stream xڭϱ Â0€áH†Â-}„Þ hë(Ô ftr'utPt¶ÖGé#tÌP<Ó¦7%Ç7\ üÑÉH*ŒÝʵB5Å£„ èq»¨îêp†Ô€Ø¢ƒXº=³ÂÛõ~‘®ç(Ad¸“ïÁdȈ׌EÔø Âi£ÊY†–q*ÂÚ™O'ó¾OÞ;è,~6ÿxÙO@}ƒïñmeÔtÚYålúyûNmdìÕ_…… ¼óàa endstream endobj 4503 0 obj << /Length 192 /Filter /FlateDecode >> stream xڭϽ Â@ ð‡B–{ózý8«[¡VðA'qRGEç>˜n¾†oàJcÛëPpT¿! á'yÒÀHEŽiïã UÝõh¶£ÝrM*@9¯ú(õ‚.çëe²œ’2¥OÞuJàæ`âÒ©d¾pØ}pKçm@Àúykf ¶6•u}ÕòÏÚ;ÝËݲl›Í-z•½Rp“ÿÞüRm‚0µR0?¾Å™Æ~hà“D endstream endobj 4504 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ36Õ35R0Cccs…C®B.ccˆˆ9˜JÎåròäÒW06æÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0ücÀðÿŸü aÿHTüÿ7°ÿø¿ùÿAT¢á?¨ ‚H0МøÿÿÁåêÉÈN9V  endstream endobj 4505 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ=Í= Â@à'Â49B殉;üSZYˆ•ZZ(Ú‰Içµö(ÁR!8¾ˆûÁüì¾í¦í~O;Ú­ñôu›ÈAÒŒý·­›½ sqKM3qSNÅå3=Ï;qÃùHqc]%ÚYK>VØ M3DäKÃWĸP…èëýcìN, …=á­¢7b[feƒ¸ ¼ð‡'¢?f–5¾â®Ì¬ð²îE€LrYÈŽR® endstream endobj 4506 0 obj << /Length 143 /Filter /FlateDecode >> stream xÚ36Ò31T0Pa# Sc…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ä0°®ƒâÌÄÌ@ÌÄòÿÿ3üGÂìPqÊ1óB˜ù?{3þïg`øÔdÿ¨ñ—«'W S™Ov endstream endobj 4507 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚÅÊ!Â@ÐÙTl2¦G蜀í¦[*IJIXA AP€D@@··ã(\¡ªŸY ñ_òg~˜Ï|%¥xMh¤jäìùÆ¡Ö^¦š§+·‘Ý^BÍn­Wvq#ûó®Ý.ųëä Ë#ÇNd& ~iAùDÈþÕüËb"Z$‡D€‘z¼Õ/5ƒÅÈ«È;þ.qmz endstream endobj 4508 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ]ɱ ‚Pà# ÂY|ƒ> stream xÚ]Î?nÂP pG Oò’4¾@û’<þ4RÕH¤f¨ÔN ˆ @ e@Jz³ .’#dÌPâú¡Ñ.¿ÁŸìÏ}óô’O!=Cê‡dF´ p‹&’©OÓFË ŽÔ32êw™£N>h¿;¬Q?ß(@=¡y@þ“ 1WYóÕ€* =!¿âpîBKápñÐQ¾då‹åWiG]xuÕâ^Ê÷ô8oqîæ/ÇéÚ"±%ûø$|¾"×+eqåzêÙuùâ°Ÿ ®„€Ó¿ð1|m endstream endobj 4513 0 obj << /Length 204 /Filter /FlateDecode >> stream xڕб Â0à+ ‡Ø(z/ I• E¡*ØAÐÉAœÔÑAQp(â£õQ|„Ž^m‚E\$|Kîî¿¥Úý.Iòj’:Šzm}< ’Tœ00µÍãÅ’”D1åŠdF§ãy‡"žÈG1¦•Orɘ Æ<²ÀºØ€spùªÁ"–²G¥…9¦5¡4ÐÒʳò’ëQ3ÎܬŒxÇ:n¨™Ø«–~y~VýåòCTáé(Ô™£ÙüF++ÃI‚ |Û A¨ endstream endobj 4514 0 obj << /Length 194 /Filter /FlateDecode >> stream xڕн Â0ð+…Côï4_( Å¡V0ƒ “ƒ8©£ƒ¢àСÖGé#ttp0!‰Šƒ á·ärÿ$§T< N‚z’“’4”´xBÅÉ®‘ô¥ÝSlMŠ#››}dzA—óõ€,]NI Ëh#ˆoQgЀ–‰J£rÀª½Û—ÜHþÿððîNÔN#¨œ80om[…ÓµÀ™xáŠ"mTé#lûG[âX»)¼ŽúiuÞe0Û€3+|RA endstream endobj 4515 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ32Õ31S0P0´P06V06R0µPH1ä*ä24Š(™B¥’s¹œ<¹ôà ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒØ?ðàÿ!†ü?Ø70aCÆŒ˜Øød,€‚@!.WO®@.õœ"m endstream endobj 4516 0 obj << /Length 136 /Filter /FlateDecode >> stream xÚ32Õ31S0P0SÐ54S02P°TH1ä*ä24 (™Be’s¹œ<¹ôà ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÌØ?ðÿ ÿ ?°o`0`(`H 0703°3ð1È0X…B \®ž\\Ë—!Ð endstream endobj 4517 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Õ31S0P°bCK •bÈUÈâÄ@tr.—“'—~¸‚%—¾ˆðôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàc°o¨oø u 6 \®ž\\TtÓ endstream endobj 4518 0 obj << /Length 164 /Filter /FlateDecode >> stream xÚ31Ò31Q0P0TÐ52T05T03RH1ä*ä2±Š(XC¥’s¹œ<¹ôÃL,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÀØ€L1C)0ÉÀ¡ø „’PÊB@¨õB€˜|‹P“ÙðX5Ù€X °:Õ¬NÇcV§† ² \®ž\\Á-› endstream endobj 4519 0 obj << /Length 117 /Filter /FlateDecode >> stream xÚ32Õ31S0P°b#3c3…C®B.C˜ˆ ’HÎåròäÒW04ãÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0Ø0Ô1üg„ÀŒ ˆ| ö õ ÿ!h€ —«'W %– â endstream endobj 4520 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ3²Ô37T0P0W04S0²T02TH1ä*ä2 (˜B$’s¹œ<¹ôÃÒ\ú ¦\úž¾ %E¥©\úNÎ @A…h ŽX.O…úÿ?€è?}àrõä ä¿Iz endstream endobj 4521 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ%‰»@@ûóç ÜÝ»¶öHl!¡Rˆ ¥‚ð÷„)¦˜ñšxOÃŒjéSªãl±Á…7ê?¦y„ôtRS!±á±Ÿ $o ZHÉÁÒŒˆ%ï—몈 û¢ endstream endobj 4522 0 obj << /Length 288 /Filter /FlateDecode >> stream xÚÐÁJÃ@à„=æ²/ î¼@MbÛ”BI V0AOŠ'õèAQÈ!¤y´}”øñ¶B0Îl&‘.?|C›Ì¿ðÏV3ôqzŽÓ`‰á +| àÂ9=öqvïža“€w‡á¼+z^ro¯ïOàmn.0o‹»ý{H¶èÐiQ¢)eMJ]©S2vÒH’¹k²˜Ì„©÷d-Œ!]#¾~šœu?ÌÚá»Úëþ8é,yl-”šÇVÝW6|tOGœ¾qÁáµ8ãîmhm›q¿m¨›QÝNcG«PtV<Wcù_õý:RÓ‰…â-•Ô\GIñ¶‘Ò»>˜)Í¿iRéòçÒJNøÚ¸ o/‹¶¸Là~¥Ÿ§£ endstream endobj 4523 0 obj << /Length 281 /Filter /FlateDecode >> stream xÚuѽJÄ@à )Óì ;/pæ“Sç ¦ÎÊB¬ÔÒBQ¸BâÂv>‚Ïß$peŠ8;»çå¢n±»³ 3³Ù~vˆNœÄSLcLð.†GHºŽpšmb·0+ ¼Â4ðœøüôrálqŠ1„s¼Ž1ºbŽ‚VÞšÝë{MuPJ{µ oM”Â7´"Øâ5?ÐKŠûZØgcGý?ÒQýFö´vè¸>*jˆ¹Ìµh¹è]> stream xÚ…1jÃPDç£âÃùÑž _BÄ`8D…Á®\„T±Ë€Pr³A¥ #g\¸óÂ[ØÙa&Ïîó\M ®¼Ð"Ñ]*’Íx'Óùÿy{—E%~«ÙLü3eñÕJ¿>¿÷âëGMÅ/õ%ÕäUª¥GÀž€8 ˜›5p›€&êÐXâ€æ†Ü‘[2ÀÐÀ 5ùAÔ°Ä…q7¢íŽ81„ÙÑpó{ ì€0#åéEÙR¶–ßgΰØÙ ê,µôz¯ 툙U’öÖ–ü1 òTÉFþÈEŒ endstream endobj 4525 0 obj << /Length 219 /Filter /FlateDecode >> stream xÚUнŠÂ@à]¶X˜"yp7Oà&B¼tþ€)­,ÄJ-…xœ`—¼¯äÜ+ä ÎÒBX³3wf>f¦˜Q6øbйËG)î38Aîf©kÝbw„q fù̼›‚)øûs>€/'˜™â&Ãt åEòæªPš‰>{Zâ; f,óOÈž?B]}tì1LÂU|÷hµ‡¼ª§!´ð‰’€‚©­õ°L+ôƒ^¤Þ¨†Ð=‚ˆ™ˆI æÂTÌB?…KkÙÝ Y +xir§ endstream endobj 4526 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚUÐ;NÃ@à±RDšÆGðœ kK,¤‹”‡HPQ *BIAµs4ÅGp™"Êòÿ»Á6…õÍ®w»~¹¸óV¿ûÊüƒ*ýRÏuÉ%ƒ÷O]×ê^Ì{u{쪫íûøó¡ný´±JÝÖ^++ß´ÞšÌC‰„S¢É{)zÐÉü™\"i%»¬4á”6Íò‰Uj‰HSÑK&eo©ÂTF€çg³K´±³ðÿ5Ѥ²¨r#ïãŒØk¤ÁDV#¸ Ĉó7èÿ¯—'Šîïp*ÃSó¥±AÎ ×]­Ïú >à™ endstream endobj 4527 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ…ÐÍJÄ0ð顃}ƒí¼€öƒÍ² º‚=îɃxR‚ŠÂÄæÑú(y„{(3itáG&Édfôêd^QAeEÇ-–¤Wt_ªg¥5G Z”áèîQmj•_“Ö*¿à¸ÊëKz}y{PùæêŒx¿¥›’Š[Uo @<âˆ9ufÆ8g׋:&í°ç£ëh€¬FŽ÷ˆOÂ^|I‡ÌòÓNî{Œ§‘?,œ''Oìi%ÉÉõ‘”_ùàMÀü à–?ØK¯ÀÓ´ L Áz¢@;uÙúž3Áå2<ÛŒ+ãÙ¦Œ ÕJfWÄ-ƽ<Ï%5¾Þß’“É uöP›:¯ÕN}°m» endstream endobj 4528 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚ]ѱNÃ0à‹Ù®ž¤f»–·Zªwn×BÆ{ÿG4êûèQ ù@ÅdNAÂÄBí¢Í^=•IÝ T‹d¬%sµ™÷˜Ú]KsýÄbr¦h6ó@Î^^43{2è±¹˜îƒzD!;‰(dý«­`ïÑ!´m¢X“Ú¯¡m㺠ZÆèB$B¤¹ŠÆRm7ó˜WúKPËÄ›–_ø †×Šæ endstream endobj 4529 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚ]ÐÁJ„PÆñO\gã DsŸ « ×ZÄÓ¹jÕ"ZUË`Š‚Cúhó(>‚KÃØù®Žf‚þ¸ žû¿.;™ÏMbœÞÙ©qgæ%•wq™®.ùáùM–¹Øã2±7úVl~k>?¾^Å.ï®L*veS“> stream xÚeÐ1nÂ0à?Ê`é-¹¼Ô ÂС*R R3T¢CÅŒHµR¤äh…#ddˆ’úA vkÉþü{ño›áÀc6vŽ6c^'´##9–(›Õ–ÒŒô‚!ýjOIgoüµÿÞNçSNHÏø#áxIÙŒ¡;ê? *¡„Ðrú–§Ž£Ëħ¸óä>h Kur— FäP¡wåÙVÒ á¥¬Pu¨3ZB‰ŸŽÈç„Ïû®Òá(MnL| —Ü.G}Yƒk²ýzÉè~ƒm endstream endobj 4531 0 obj << /Length 270 /Filter /FlateDecode >> stream xÚmѽJÄ@ðÿ±ÅÂÞ˜yÍ— pppž` A+ ±RK EÁBÈ>Z:_#oà–)BÖ™½wáGf6󱩧ł2Ê :)¨:£òœžrójÊ’£UyL=¾˜umÒ;*K“^qܤõ5½¿}<›t}sAü¾¡ûœ²So€qĬ¼=f¼ï–›9fîðùÅ©Ëh€¤FŽ÷PC@s€>ítü©“óh¤G˜[†€ ´Rd‡ÔúÃJÉ " h"ö|š÷<zØŽÙtÄí! Í#ݲsi‘DÚ0$§'x,.$cq/õcÁ÷¢¿­,±Òág J z·ß\ÖæÖü­U endstream endobj 4532 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÍб Â0à”…[úÞ˜V´…ZÁ ‚N⤎ŠÎí£ù(}„ŽJÏK‹ÑÀ@È—„ûá.‰Çé#œòfÌR<Åp…$å{d®æãxLÜa’‚\ñ+HµÆûíq™mƒÌqct•£ð‰tHTý€´#>EP3žßs‹Ò raJ !úÒ!L½Ñv(]p†gÑt.8÷Э xYÔ4}k]FhaZ7¥C|¦¢Ý©üÛxÞS)¨õºÞ‰ZX*ØÂ ¬Sšd endstream endobj 4533 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚµÎ?AAð•Wl2#˜ØdKÉó$¶P)D…RA¨9š£8‚òbìóÆóË|3ÍüÐz´8*ãqqïà!ælK,Ýêf!‚™ç+˜´ÀËùzS/§èÀ4¸qh·TQûƒÒy”~1}áÉ „3îÌMP u|˜žðf*¡e´ðz”7"êÈ…`–`_ÂâSt endstream endobj 4534 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚuϱ Â0€á”…[úz/ imŠu*Ô vtr'uªè\ÍGé#tìPŒÉE#.ßp—?"Æ 0ÁÁãã1îC8j ÚÑfw„¬¾F!€ÏÕx±ÀËùzž-§Ïqb°…"GÆ<)›o™×)˜Û~ôŒ­o¬mûÆ»mj¼ÙVFf+ɇ­cìlÝŸð¯üöO¾2¥ðê¥Î—”üVgvdMi5…”L?X:úpâêc=_ÿЧn3˜°‚'ä¯VO endstream endobj 4535 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚMα Â0€á+…Cè ½'0©ØÚAª‚ÄI7ûh}”>BG‡bÌE1 䃻døÓA_æ$)å; tD‡/8ÌÌ,yä‡ý …bCà ÅÂlQ¨%Ý®÷#Šb5¥ÅŒ¶ ɪA¨u ÎD DµfcßÊ9ñ-O_pjÏ·3ðmß—3ômœÑß® ïýäð±5·áŸ~¶66¼fƒšÃ;_+­QÅáqÉšo&V—&9Ô ùx¾ç ×øûdœ endstream endobj 4536 0 obj << /Length 300 /Filter /FlateDecode >> stream xÚ]Ð?JÄ@ð¦˜"{¸3'0 ®› ë ¦ÖÊB¬ÔRˆ¢°U’›x ËÜÀ#˜8åÁøÞäŸIñ¿oŠóE«ÓÕZŠ&>Sç‘z Å‹ˆ( Ïb›ÿVEká_á«ð“kõöúþ$üíþB…Âß©»P÷"Ù)àÍ·é´$› £•NºšH’òA?%®“A^ à|‘6¤ï^ì£@Å(.§: \= )ʛɠâ¼Wš‘ªQY;àXývrÊšTfÀŠ©Š;£è¬ÈÀ‰£<Ö+fT ‡QR«‰÷ª8ä‚vÊ™– Y±eKÍa¦ hd'ÚÒþI~¶:t'mi «¹ ËÙª ñ#‰JkšRBÞÔVËAn+q™ˆñé¥™Ê endstream endobj 4537 0 obj << /Length 291 /Filter /FlateDecode >> stream xÚ]ÑÁJ„Pà#..œÅøÃÌ}‚Ô(u1 Lä"¨U‹hU-ƒ) \úhΛ½€ÐÆ…x;ç\G-PüëÿŸ(<‰Ou Ïè%œÇú)ÄWŒbZ¼äƒÇÜfèßé(FÿŠvÑÏ®õûÛÇ3úÛ› ¢¿Ó÷¡0ÛipM `L=GgŠ hTà6GÐ xŒŠa, B9Ǫ(A R}a9¡²Ø¬+ð,jX0ï?r¯•@5°dì'´ÛÂÆ¢ƒ„Qp,œÚé!@{F5Á(IÍ”’å€T@‘ÒÀõ£S’ _Ò =ß#¤ÂÏ% HÊŒVè–¿ HΈ^Z™ùƒGöÉ¿Ü (xš\Œ5™/3¼Å_Ë||Á endstream endobj 4538 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚmбN„@à!$Óð;/ ÀHlÜä<)L´²0VjyÅ팷ƣð”äpþ9L0@¾e†ef§./ëZr)6r±]VWòVð«R£¹ÔÅœzÝó¶áìIª’³;sÖÜËçÇ×;gÛ‡Ñ÷<’¿p³"ŠO„ËO-“±.”4Ð7RD×Ê‘S4áEúYÚRÒzcéf‚ÒcÅ=¶T‰‡h\KΕÿHg:Ãd@ůq è¸_eÂÑ\·‚oÿŒã Ó™“ÍŒšEc†¶¼@[ÆÑµWðK›‡·†Y6' ÌPÇ¢ÕѶ’·‘›plЬ>ß6üÈ¿ƒmyä endstream endobj 4539 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚeÎ;Â0 ÐT¼ôõ H«*0V* Ñ &ÄŒ ˜Û£õ(=BGÔ`‡O1$ÏN;f2Î2LÐК¤h¦xLá†ó„Sg(JÐ[4ô’NA—+¼]ï'ÐÅz†)è9îRLöPÎQ¬µå°j¥¢Nå-ÑrÄ„TÿžD#ɉ~ –T?Bª¬”„frOMPÕ¨sÐÈ`à;¤vôî)Gÿ/¤O7ºr$òi%±O#É}jIå£$Ö£w{ðÆÚç?°(a/5ÿsR endstream endobj 4540 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚmÑÁJÄ0à)=réu=%/ m-­+ÈÖìAГõ(¬¢7±é›|‘À¾@ËÆ™d -´—¯dštæO™Ÿ”¥HEv*޳Rà{q.^2öΊ—SqV µç7¶®Xr/Šœ%×X`Iu#>?¾^Y²¾½K6â!é#«6Â=Ð#mKôQGk:0HÜÂ7•Vȧ/AçÊ‘'Ö‘ÞzP·5×ý%4A?&4cüŸâšN1|‚lg¨uÜÍbi4®gí娕ˤvMƒõìÁÞÏe†ñjˆ•VjlYÂö ÃJ§oÚÃàZ`†ñ¯ZàøÑŽpÄp4TðçR«¤ë£éa;¬!»„%-_@êÙz:…«Ð!#=ºMiÕÓþÂy¶±«ŠÝ±üv’Ö endstream endobj 4541 0 obj << /Length 261 /Filter /FlateDecode >> stream xÚMÐAJÅ0Ð)]fa/ð¡sm+¶"ïìBЕ qõuéBQp×­Gɲü iœ™hMIyM:™ÌdhOúsj錎Oièˆ'Ͼa?ðbKýEú³ÅíˆÍõ67¼ŒÍxKïŸ/ØlﮨÃfGµO8îÊceID``g&@òY”â›ñ95³ü3çØ•’#­Ë™œœ¥ð “fW<@Ô ‚€E¿Çs>‰(Rµ §’:$ÓV.Á»¹bãAû*3ÂJêËü´€ î«Ê˜sìJ´¯Ú›?&¡JI_B”´›)J—rí&| eàýüD¯X‡×#ÞãdŒ? endstream endobj 4542 0 obj << /Length 255 /Filter /FlateDecode >> stream xÚeбJÄ@à?¤Lqy1óš;ÉåÄÀy‚)­,ÄJ--í‚É£í£äR®\g& wÚ|°ó'ìü[”‡å1Ϲäƒ#^¼<áǽP±’¡ŒSòðLëšò[.V”_ʘòúŠß^ߟ(__Ÿ³œ7|·àù=ÕP¹…aHÂ(fîãTÆÈ AêÄ#{Ľš8=N¦Ý¯™Ø#Ã_+ÑíÚAïžtjÖ›£4HÃ`~AWÓQ‚~,¨‚·@Ekÿ¥flF[bÛ³î[ªúÏ µ~”ö“-´½(½ÛN[¶N£ÏA/ñ£¼†V—í­‹³è¢¦ú?Fj¤ endstream endobj 4543 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚUϱjÃ@ `ZîB­'¨ã«S0Òâ¡ÐNB§¤c )-t³ÍâGðè!øz²3HôñKh{~\.hN™ í)'—Ó)Ã+º,ä9Çqs<ã¦Äôƒ\†é>Œ1-_éçû÷ ÓÍÛ …é–áæË-ÏÕÞ±wzð´¶L“Ô 73ˆnb¤. fV÷ c†éF ÓI, —m%‰¦‘¬5µ¤Ò€Ä+I¤¹IbM/1šNb5Ó'ë1UÞó…Wà®Äwüݦpt endstream endobj 4544 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚUÐAJ1à˜ÅÀ[4ç]@3SH[A¨œ… +âJ] Uº›£ÍQz„Yº(/É(™EøÂ !ÿŸY}:ŸrÅõŒO¦,[3ççšÞÈ™VlΆ£§WZ¶¤ïÙÒ×2'ÝÞðÇûç éåí%פWüPsõHíŠç¬r‡1ØZøµÐ p8áüŸƒ°ø#ól"kdû”ÜÓGvÈR !èPô)JÈ,Ô.¥Š ìRAE&‚Mñ½Ž#G±×˜¡ÞbToYè’=Ð$-¾C0dðLâÊÿ¡´øŠÈm¨.—ÛÒÖçFæüÃ’bðͺjéŽ~)kB endstream endobj 4545 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚUÎÁjÂ@à 9sÐ;/ ›UÖ¤*X æ èɃxRBZÚs·ôà­OP|–3ÿj˜€WòÄÄLĤ¹Å«ÈÀ3+¾®C ,¦Ít"‡”Éïå²y®¦\6´*ÀÒvè211©E[&:·|Ud–oÝäM~˜3óË\š<ü9äLæ ì…^|Ip…ÿù` endstream endobj 4546 0 obj << /Length 212 /Filter /FlateDecode >> stream xÚMÎ?ŠÂ@ðoH1ðš\@È»€Nbj£àº°)´²+µ´P´ $`‘No°g‰7ñ)S„dgFA›ï/ê÷¢ˆ}q7`Âo:PhŠ>‡Ãgg³§iLjÉaDêG—IÅ¿|:žw¤¦ó/HÍx°¿¦xÆ@@6/ïcGÇÄP‰Âà”¨!×Rˆ^!ª'“ÌâTH3=™â,ÑšÅæ×R˜;÷â…g¹X²Kž%Hs$h%Æ¢uõg·+> stream xÚMÏ¿ŠÂ@Çñ‘-¦Ù70óÞ&a…ÀÀ‚VWˆÕ¥…rWšGË£lgé–[„è¬QsŧùMó¾yK)¦!õêúJp©á1¦Á°¹|îpœ£þ Ô žóŒ:_Ð÷ág‹z¼œP‚zJë„â æS‚ º¶àÄŽÿÔ¬jußkÉÀzçäEª’¥òÌ «¬°Q)Ü]ÑÈx’îÄŽ/ÊÕ¬eQPú»¬xÏÑžc=þrÔ_ÇÁ»°0’%t£ÿÀà,ÇÞ!_‰ endstream endobj 4548 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ]ο ‚PðOîœÅGð¼@]ÿ éb`955DS5¡öfö&>‚ã$»)5üÎð}œÃñü‘Ë6+X8!Cо¡ %j¡•P¦f•¢¶J`Rôò¢Ûþjµ×Ÿæ—­ùZzê FB”!Ì‚ž¥_©ºC4KhEoçM> endstream endobj 4549 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚUαN„@àÙPLÃ#0/  ¼æHÎ3‘ÂD+ c¥–íH ± Ó7ðY0¾ˆ@IAXÿÝcCl¾bvæß?;9Î2Id#G©d¹¬Oå!åg^å&²Þ^îŸxW²¾‘UÎúcÖ奼¾¼=²Þ]IÊz/·©$w\î…ˆÔÌGï ~=ÑBç‰Oá \N nk¢m`ˆª`Â\MèðÕd³G :5"ìÀ€šÕ»>ƒfÆâ®g¢ä|w3±ãÇòÞŒT8Ú¦¢º¥ŠLH[e"4ûü 8 ¿Ð6IõÔŸ—|ͬÁkÞ endstream endobj 4550 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmÎ=‚@à!$¯á¼ èòS $Љ&ZY+µ´Ðh²…‘åfx“=%-l,¾f&™LCö9áQÀQÂÑ„)LLès›ý‰¦‰ ‡ ‰…‰IK¾^nGÓÕŒ9oöwTä ”€Ý×pŸ< ÑAZ-¤Ý@:ÒÔh½M¦,ÃÑ™òTYõ(ûÖPà zãõG÷ãߨ IaévíÁU.R8Uk®èÏÍ ZÓ¢ B endstream endobj 4551 0 obj << /Length 216 /Filter /FlateDecode >> stream xڕб Â@ Ð!‹? 4? ×Zµ¤­`A'qRGE¡C©~Z?ÅO¨[©&‡á\îA.ärI»ÛêôÐÄf›–ƒ¶ƒÝ>n,؃íÒµ‰N¯Ì­w0 A.ÐvAN(2œâñpÚ‚ÎFh pi¡¹‚0@!D-%ŒŒð\"ùƒ¸ŨÞr"Ë®R\uêŠTÇP\(z>Sa¼¡Ø§#|¡sf’ÌC§¢ÈuªŠLç¯1>|Sþ¶Á$^IÁk,b&â…rŸˆñÕs\ ãæð;ø]ª endstream endobj 4552 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚEοJ1ðY¶L“2/ Ù¸{ºÀy‚[Z]!Vz¥…¢ ({ûh_$°¹"¬Î,»ÚüŠI曯^ŸSE º5Žê=:|ÆzÉÓŠÍôôð„›íŽê%Ú+ž£m¯éõåmvssAí–îU÷Øn @ð‰ÉëE2 ÊȨ èž1½JàAE8èƒA‡b„räÈßg|¯FÆí‰Ã„äÌ d¾]¥ 2÷ÑG€d˜÷Æ3úKê–‚ú'Îè‘'BÇ¥„žx`:!s\ÁIŸ²`~zNx /[¼Å_¨TdW endstream endobj 4553 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚUϱJÄ@Ð7¤^“ò~@gãfa„ÅuSne!Vj)¬¢`•̧åS"þ@Ê-ÂÆûFaæ0Üa.wª³Óª’™,䤜NžJ~å¹Cˆøü÷æñ…W5Û;™;¶×ˆÙÖ7òþöñÌvu{)%۵ܗ2{àz-” DfJ £HŸGº„"|„Z¥ÑÖ¦ÁçÑԠÛ)ä€ò`ötfTvhÌ"Ã?|@‘×QZ×計VШó@0ã1ØE–Îã×¶-eý¶ƒÒƒ¯nOæ;`ëDŽhI|Uó†´éd" endstream endobj 4554 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ…Í1 Â@ÐR,Lá^@ܹ€nŒ¦¢‚)­,ÄJ-m5âÅâMö)Sq79€3¯øÌ?ŠÃ<æ~ÈQÂq̇.ì6µŸý‰ÒŒô†£€ôžIgK¾]ïGÒéjÊ!éoCv”Í^a JH˸ìçø;%ü¢‡ŽB·‘Xœ[O”ë ÔŽgUð[¥kM•4FF~ŒúêÕxçÊÏ•€ÓìBTð hžÑš~; 9õ endstream endobj 4555 0 obj << /Length 215 /Filter /FlateDecode >> stream xÚ•Î;jÃ@à_¨0La]ÀDsyõˆ¬Á?À* I•"¤Š]¦ˆI Eu4ÅGXw[á‘× Æ¾f†™Ò|ø8☣Œ£¤à,æ<çuBß”¥Ò޹HÝìó‹¦%©7ÎRRK*Wü³ýÝš¾Ì8!5ç÷„ã*ç  /&bw¥ÜUa-« pÐð ¿6èu<ƒ@ôŃøÏâÉ×gè9{+p+tjkâܼ]]´GËsŒåw´¼¡QI\§•˜6¨Ñ†€ÿrYÛtZ”ôJ'L{JÓ endstream endobj 4556 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚUαJÄ@àY¶X˜âòr™ÐM.ÞA\8O0… •…X©¥ ¢íeå _ë|“XÙFlR,‰3…m¾â˜ÿ/ʽe4§Ýœög4/é6ÇG,r|ð{¹¹Çe…ö’ŠÚSŽÑVgôüôr‡vy~L9Ú]å”]cµ"Ð-€"ÀŒ4ÉÈ6"ñn"ja ‰g\ô ôê½… ßÃ}abZvL£ºRÈ´WÝ€î¸Wq‘þæÏz=Aè…æ³ã=AF­…Zp2Ǥ>}Ýþ±áÄm¼§ÿ1¾fxÔ‘0Sè!9„¦ƒTxRáþé^ñ endstream endobj 4557 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ}Ì1 Â@…á‹ÀæbæºÙ…è ‚#˜BÐÊB¬ÔRPQH!š£å(9‚eŠÝÙµ¾êð”(E!¨/I )ÒtxA©M )»eÂ8E±!©Q,LF‘.év½QÄ«I m%…;L¿ð>?9›:À^ÖÓj¬šµœŠµ7óœ’ùNÁ‚ÿ÷Ö=¨»Öj •‘Av†G ¹Êç)®ñ ®E‡ endstream endobj 4558 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚUÏAJÄ0à?dQÈÂ^`0¹€v:B[¡LaÁ.]¹WêR¨¢ÐU'GËQ2x€‹É¢t|MUÆÕG^Âÿ¿dùéyªæ*W'©Êçê,WO©xÙ‚†t,¦›Ç±ªEr§²…H®h,’úZ½¿}<‹dus¡R‘¬Õ==ˆz­˜Å€È!ò|¯e£2ŽL»Äñ²ä[+1“-ÿ2R•c;“–íë¶2l ›IÓTšõAp©ÝfÒvàî@tc[¥§Ö èÙÿư`æ)ôÏaTzÄCY?›ô£´‰/C ÷EåîPÚÌ5¡„Û&„së~´¡„o eŸôs*ÁP%Äe-nÅ7ã7x` endstream endobj 4559 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚUϱjÂPà?ÜáÂâ ˆ9/Pc0$Bj¡;u(ÚŽ…V2H¼à‹åQî#dtí¹É`]¾á¿çÿáÆÉ8ÉxÂ)?DÏxšògD¿GNxšõ/ß4/)|å8¢ðYb Ëo7»/ çëKºä7é¼S¹dÏâ蓺øù@7=æÊbTªEV´žÓŠUш?âI4›öà´õMÔÐâÚç;žØ@ê½A¯êmQSuj#Síêõ}7µ÷ÝÈ~Ô9ìÌÜ`^¹©ÀBË× è©¤ú’tUž endstream endobj 4560 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ=ο ‚PðO„³ÜGð¼@]ÿAµ(˜AAM ÑT Em¢B/foâ#ÜÑA´«BÃßóÀ›;¼â™ËÇþ‚¯.=È÷tè°¿œ6—;Å)É#ûÉ­ŽI¦;~=ß7’ñ~Í.É„O.;gJ Àì+ˆ¯‚92´È =™ ¡¥Y5"¡ÙÕ$*GE1À_ßkÐMŒAÛŽÌfb)­n!ê ¢Êa—!"„ºt¨5¾}€6)è•GÏ endstream endobj 4561 0 obj << /Length 238 /Filter /FlateDecode >> stream xÚ]Ï¿NÃ0ð/Êé!÷Òš?"R)èÄ€˜ZF¤‚@ê€j?šyó=D ç¤$¶ôî|§Ïjr¢ŸÊ=.ÏYMxzÁ«’ÞH•]õlºo-_iVSñȪ¤âNêTÔ÷üñþùBÅìᆥ:ç'z¦zÎÈLfÜU¸ò›/à2¸k`£­¸Ö&[ˆ~‡ÜÀõ6bòÓùÝ‘Tƒ~4óЃ{ÚÎh{“FRýD“öJÎÊÈ*+o£Ft:‡^˶ñCØÆf\8ØŒ&‡†Ñôи%F–Ó¶öŸt[Ó‚~JlÓ endstream endobj 4562 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚEÎ?NÃ0ðgy°ô-9‚¿ €“˜¿K+•"‘ &ÄÔ22€`«šl‹%GðèÁ²± U†ßòÞðž½:m¹æk>i.ø¬e{ÉÛ†ÞÉ–´æsû_mÞhÕ‘ybÛ’¹Ë9™îž??¾^ɬn¸!³æç†ëêÖ x ô·ÆBþ`'#¼ˆ"“QMU1"èQ~9üéé{Hw” \„šfÕP3] ˃ú,a!ÒaZW}¾²‡p{EÌÂL~& ‡< ‘ÒxD·=Ò/´8bª endstream endobj 4563 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚUÍ1 Â0à_:ÿ`/PìMC”v(j3:9ˆ“: U:ˆÍÑz”¡£ƒˆIÄ!Ë7¼ï‰é8âQL#NN"¦#Ç ¡ÃˆDòkgÌ%²- l©cdrE·ëý„,_ω#+h§‡ö( ò¯¿ ß0¬R‚GéC:k3•d¦V™ª4PÖ`  {@û1¼ÿ€¡gy9x–Ρoi|KãZ”Cf1.$nð ñÿ> stream xÚ=ͱjÂ`à2î’7hî èŸäÇ6]ˆ fìÔ¡tÒŽ…*:H|±é(V;Qû¬›X¶’¤\FjÓÛeý%E)æM“TÌ‚k1åRvûO1Åjª±˜™¾Ç}H9S Ü Á¹B†4øÅ7Z4^ë7^󝿬üð;r<×ÿŽÌȇ0È)¤ Êèz§»!ËB–e,; eá£__ß=Fʼ”W¹|/Hd endstream endobj 4565 0 obj << /Length 178 /Filter /FlateDecode >> stream xÚ]Ì1 Â@Ð )Óì„Ìt“MBÄ…Á-­,ÄJ-+³GËQr„”Bt ñóªÿá«|(¢œú1%Š2EûϨR.#Ê’ï²;baP®I¥(ç\£4 º^n”ÅrJ1Ê’61E[4%o!¨Aü™u4§x@ÕuŒ/øòØÓñYë¬qDówßûk;Ôp×pÒÐjh´WOü: ¬ðm 83¸Â7Ä¡B endstream endobj 4566 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚ5É1JÄ@†áo˜"ð;ÉMB¢™……uS,he!Vj)¬¢°•›x¥9ÊaÊ)Bp’ÍS¼oÓ\^]sÉ-_TÜ´\·üZÑÕëK®õù¼¼Ó¶£â‘ë5w1SÑíùëóûŠíý WTìø©âò™º##„M~!ÝJõ‰Ë&Ò ­zåt9FìaÆô¹õ¹u‘Þ"øYa€áÌ b&ÄõÏ9ã1¬ÄM¤‘J·°‘^-}´ð‰?Ÿ°9:o,”U ÛŽè;¢VF endstream endobj 4567 0 obj << /Length 205 /Filter /FlateDecode >> stream xÚUÍ1jÃ@Ð/¶L!]ÀXsxµ^ƒ¶¬"W.B*'¥Á v+éh:ÊaKÆxl%4þ†oÝlÎ9üdxaØüa苬•2gëÆËþ@ËšôŽ­%½‘štý§ïó'éåë3Ò+~3œ¿S½b$PTˆ§h»$&wÊ;.CÕ¹ Yw¬þÐ ¡A ß †¿ ¸HD†‘)Ô€ TøC‰8À!ö#Çÿø_¢^P=”W¼ÉDC)´ƒö­kÚÒ V²Aš endstream endobj 4568 0 obj << /Length 238 /Filter /FlateDecode >> stream xÚUϱJÄ@à?l±0Åí ·óš,GHŠ`à<Á‚Vb¥–Â) r—GÛGÙGØ2ENÜS8¦ø`vfv¦,Ï]ÅW|測y]ñ³£7* žc]§—§WÚt”ßsYP~-iÊ»þxÿ|¡|s{ÉŽò-?8.©Û2" 5Bõ¶×+hßú……–‰&Q[Xo}ÝÂöÆïfô?´BÜÏôAqaú#ÐGØÏ L0P3 ¨(E§È>QZ–ÐAj4‰ú„¯ÄNq1 ‚2!šQydqõ-«`l.ŒÜÝvL¿@WÝÑaÔ endstream endobj 4569 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚEͱJÄ@…áR Ü"y¹/ Iv"f!XW0… Õb¥–B…KœG›G™G¸eŠŒ,Ææ+þSS_l8ç’Ï .K6—üRÐ;™ís6Õiy~£]KÙÍ–²Û%SÖÞñçÇ×+e»ûk.(ÛócÁùµ{†òÊAzD¬jÈUW>õsèô‚ÕnVÐnŠ¡í-t‹ ¬ß+Ãʼ2ýü3¢;Ž_| üJà%Ár,¡cQvŽ$FŸŒ)úêX£‘F \ì@7-=ÐsºJÅ endstream endobj 4570 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/l˜Â¼€¸óšÄäHŠƒƒóSge!Vj)DÑN.>Z:_ca;S„à·Q9m~ ³ó)³“âT3­ô8¯´,´¨ô>—')Œfº(¾îeÝHz­ÅBÒ Æ%m.õåùõAÒõöLsI7z“kv+ÍFá˜QÁ¸‹Ø–Ú"qõ Ißîé`{¿ƒ}w3ÁˆÕ ¢™á›fÀÆÿaBì™»=ÑÌð3ã ÓKˆ·žM;tŸÄ~®è±='sŸ.ìC˜Ë±ä |G ew´†UuÌ‚%s‘LáárÞÈ•|–ob3 endstream endobj 4571 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚ]бJAà?l±0Í>ÂÎ èÞ%w'6 Ä^!he!Vji¡hw˜_leáÊ+Bô¿\&Ìò±ÌÂìÌÓó¢ÐL/õlªE¥e©/¹¼Ë¬b2Óòb|y~“e-áAg•„¦%Ô·úùñõ*ayw¥¹„•>æš=I½RÀôü–4žt®…I6ÂFáZ“à˜€˜Ãt#ÍÀæÀ¤?ÀjvOG,I#¬“Ü1>ÂÇ-í k`#¾ØŽ°õ ™ìèyßñ¯½Dø}ÑçÛÃqç ž†÷à~`[ u¹®å^þš#g endstream endobj 4572 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚmÎ1 Â@Ð iô™¸ILÀTÁ-­,ÄJ-mMŽ–x…ÁÒB\'î6æÿæO“„BÊØ(£4¥]„'Œ»v±;¶,4ªÅª·¨ôœ.çëU±˜P„ª¤uDáuI0vŽìà±ó[€>Ë™iÁ7 äw40`ÔV.Àªœ›óv^–'žVOȬh/|5V þÌW5cjSKü.[HG endstream endobj 4573 0 obj << /Length 277 /Filter /FlateDecode >> stream xÚ-±JÄ@„gI±°…y¹ü/ Iî/Åaà<Á‚V"¨¥E!Åá­øbkåkì#l™â¸ÜÿG‹ýŠfvþbzZ”ÑœN¦TœQYÒSn^ͬb1£rþç<¾˜ecÒ;šU&½bÙ¤Í5½¿}<›tysA¹IWtŸSö`šQì›ØA;(yD– Cõ˜Ž‹5£jÕ]ÆhAàG´ÑNùuÔ+7 œîÕÓA}Ù8¨o{õ‹Ä©=j‡5ÿ‹-?È nÿ_¥½L³s'æ¨;†ŒÅ¹è‡›ãt†¡-"s—=âŒHfÁ…¨{.Üî]=ð1#衇WC€Çà `.skR@eÝ endstream endobj 4574 0 obj << /Length 247 /Filter /FlateDecode >> stream xÚmÏÁJÃ@à?ì!0—¼A;/ IÛ„æPjsôäA„‚zª(ô 5¶²¾Á‚—Bë?Ôƒ‡ùv‡™ËéqYj¡µMµœkUéýDždVó²Ðj>¼Ü=ʲ‘üZgµäç¼–¼¹Ð—ç×É——§:‘|¥7-n¥Y)àzãyK=]€óIDÚ’ è02F ôØz² Æ:é×I‡ðKp>¼‹ølÉ;ÒÀ'Œ[rÂÂŽÅ^¸C4¼a p7é¬ï›þ‡ý¿ììy0Ï_ø·Þv„4’,ž0ÊÆ¢l-ÊÂöŒØÔ¢$¶Kι’/ÕRcë endstream endobj 4575 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚmÏÍŠÂ0ð„ sñ„Î ¬mm­—e?`{XГõèAQ؃­à‹ôr,XÌ΄Z4ÐMÂ?3·[qŒFø&Øéà:„D Ø ÿ¯V[¤àÏ0JÀÿ¦sðÓ<ìð“!Ò~„óƒ¤#´ úUÃ55†ÜâΖžAX²:•E––§Š¦DniÜßô8õuçÄ”M†öReeòŒ£7ŽVœª8@|Jâ—«)B„“;¥poT×Ó%zúªÄIjÕçÿb)\M͸úuÜw3¿ü険…q SødšY endstream endobj 4576 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚeÏÁjÂ@àÉ!0—¼@ÑyvMˆ…¢`ÌA°'ÒSÛc¡-<ˆúby”ÜzMo9„lgÌÁJö[˜]fç7qÌ!ßòõ€ã”“„Ÿ#z§a*Å“´»yz¥iFvÍÔìBÊd³%~l_ÈNW÷‘ñ&âð‘²ÃFðsÔð+¿‚ï\©äœƒÐ*µR½+ºÿp§Œ.Ù)ogŽÂ6øþ*ÖTÿjÈ)”h` ìarAÖá’ö?æDƒžrìð8xuG+iN‘ iJ!Pú…’£ÂÂAm€½‘|cy‹¾ÎHníÐ<£úÔÐZˆ endstream endobj 4577 0 obj << /Length 250 /Filter /FlateDecode >> stream xÚMÐ1NÃ@Ðo¹°4à¹ØNì¤ÃR. ¢ˆ¨€2Etˆ,7sÇ-%.°¥ +æÏ*‚ûŠÙÝ?³[ÍΫJ - =›iµÔºÖ§Rv2_°Zh½> stream xÚ]ϽjÃ0ð·èB|/ÐÊvlJ 4¨‡@;uÚŽZZÈ¿A_ÉoA =+'7rIAüþÜ Ý¡,½Ì2Š)Ié"¥œONO ¾âhÌݘò«ÓÕã Î 4÷4£¹á>šbEïoÏhf·sJÐ,hPü€Å‚Ànaß- ÄO ±w°‘îD-V5JZU˯JW•ºWFšß1×À9Î p2[¨Ó4Œàâiª 莒‰> stream xÚM±JÄ@†ÿ°E`š¼™Ð$w‰±ºÀy‚)¯²+µ´P,Âm-²r‹3ñ_õäXøXfvþùØrqV–šë…ž.´<תҧB^eY³˜kUÿv_dÝJv§ËZ²k–%koôýíãY²õí¥’mô¾ÐüAÚÆHf¢™{`Š¢Ñ8ˆ"éá‘â€Õ"Ÿ`~à`ÁÛ'ìÀië8ØŒœiü'~aãÄa£ 73»PcãÄR¨K÷\ìO´0’!š‘ö˜ƒ… –ËРûgVÔ:Â.  ðP4IJìS¯áaòüŸ ‡ÈU+[ù§Œf9 endstream endobj 4580 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚEÐ=NÃ0ðgyˆô!ï¤MD¤R$2 щ1QF$@ u@oFŽâ#xÌ¥üí1ø7ØïÓåâ¼,%— 9[H¹’ª’]ÁLq™KUÏ/ϯ¼n9{eÍÙ-®9kïäóãë…³õýµœmä±ü‰ÛéˆÌš£%šLOjHi¯%N{2½ò”ZÐèðN‡Àô‡gôŒŽ '> stream xÚÍ“?N…@ÆgC±É6½€QãÚ¸Éó™Ha¢•…±RK vF8Þä%^€’‚0Îì ‘¼Z ø-;;3|óqvrX”ºÐ§ú ÔÆhs¤ŸJõªL¡ù6Ç~çñEm*•ßiS¨üŠ^«¼ºÖïoÏ*ßÜ\èRå[}O‰TµÕ@W‚€dªR‰ˆ;Ȉ,Q–ˆG¨9ÛCi ì7rXKËä0—Aà@$ˆs;’²º:ñ>GOÔ11PV¨GG’ª à{ ré(µëÜ‘  J}1*7S(»$;SheIÙLõ>âoúCø¨^¥f­i0Ó¤ÚÙIñ™Î§ÉÌô¬ð§ Cœ4ôqú¢ŽHºèG®¹‹nJÛè°¬‰®³œcÔC +{ç7ZÛÎÛ¶>»ƒ Úà¿¢‹*E!¼Õe¥nÕ/ÙÏíã endstream endobj 4585 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚ…¿J1‡gÙ"0M!óº·`D«Ày‚[ZYˆ•ZZ(Úºy´}”<•aÇ™¹ãôP1|ðå—?üâéáIO :¢ƒžâ1ÅH=>cT¹Pc;÷O¸°»¡Øcw!»á’^_Þ±[^‘ØÝÊ™;Và8ƒŒ‘?dm˜gPÇj·\R…q :“dÄ„*Á |…Vbn¶;ƒg³Eó çd˜ö1Öo( Ø÷aãhDBÿcü³!ýD[Áo˜¬1¿En¥ ¹±¦ä%iêÝînª6N:ó\ÒZÛ` æ]H›_ÙI<ð?yë­œ endstream endobj 4586 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚíѱ‚@ à& &]xúÞÜHLtr0Nêè ÑUy´{ጃ „zwÀ¡Í×6ÿÔd4”’™JBG´ñ„qlfiG{Ø1+P¬)ŽQÌÍE± Ëùz@‘-§¢Èi’Üb‘¤‚˜µ©ÒÁc®|æÚ!P÷Æái à±®!`{èø.ÿT¼ÊV6ß¡ýAÓõ_°yÍÀ4Õ8+p…o âøš endstream endobj 4587 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚµ‘±‚0†kHná¼Ђ±0’ &2˜èä`œÔÑA£3<šÂ#02Î^KL%!_sý{½þ¬æI‚!.qa¼@¥ðÁCT±Ý9ß +@P% 7º ²Øâóñº‚Ìv+Œ@æxŒ0> stream xÚ]Ð1NÃ@Ð¥°4¾;ÛŠBƒ¥$\ ‘ŠQ%Ú¬æ£ì\¦°v˜Y)¢yÒî·çÝT—ëk.¹æ‹Šë57 ¿UôIõJ/Kn®æäõƒ6O\¯¨¸×k*ºþþúy§bóxË[~®¸|¡nËXÊp8™ÎÙë…HDÑFä#ò°Ô々Ú~Àþ¨¨7ö'ÉQÈ”´^;LKZ+45qj@.dêtÜÇv“ù!¤¸Ç"iíÐÄÌôehÖ”ôÁjÛ]ˆÿdVçµ³½ÍSuž‡è ±ýõ?h©›ÓêgåcfKxýºëhG¿Á•¡Z endstream endobj 4589 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ35Ô34S0P0RÐ5T01Q07SH1ä*ä21 (˜›Cd’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.O†ÀOþÁN2bÌH$;É&åÁ¤=˜¬“ÿA$3˜äÿÿÿÿ?†ÿ8H¨úANò7PJÊÃç‚”ÿÇ`$ÿƒHþÿ ÀØ`ÿð(Èþßÿ ýß E` q¹zrr:é“p endstream endobj 4593 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ5É;@@Eáþ®@yWàŸ!^‰j˜BB¥J¡µu&ÁWž„¾J¨˜0ȨcFg ©kŠá7¦ÆBz¦ÚUˆmxìç1mA )9hª¶äu¿®_þóT€µ # endstream endobj 4594 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ31Ô35R0P0Bc3cs…C®B.c46K$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä00üÿÃÀøÿûÿÿ üÿÿÿÿÿýÿÿ@¸þÿÿ0üÿÿÿ?Ä`d=0s@f‚ÌÙ² d'Èn.WO®@.Æsud endstream endobj 4598 0 obj << /Length 142 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P04PÐ5R03U01QH1ä*ä25Š(˜˜A¥’s¹œ<¹ôÃLM¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ` ¡*À$ó0ÅߦlÀ$ã0Å~LÉ‘¥üŠrâ”3|@VÓÆ|`°Hò1p¹zrrµs*¯ endstream endobj 4599 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ32Ö30W0P0QÐ52T06R03RH1ä*ä2‰(XC¥’s¹œ<¹ôÌ̹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ìÿ@ð>ÀÀÀ 700Ècà öX°×aÁ5@ü þÁÀÀˆ ```ƆaÎEÇàüÿ ˜ËÕ“+ ¯ÆOÓ endstream endobj 4600 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0QÐ5´T05R¦ )†\…\¦ ` ˆTr.—“'—~¸‚©—¾‡‚ —¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Býh“ÿ@)¨ —«'W )+« endstream endobj 4601 0 obj << /Length 128 /Filter /FlateDecode >> stream xÚ32Ö30W0P0SÐ54S0´P°TH1ä*ä24 (™Be’s¹œ<¹ôà ¹ô=€â\úž¾ %E¥©\úNÎ @Q…h ¦X.Oöùö?0`<ÀØÀØÀÜÀÎÀÆÀÇ Ã`ÁPfàrõä äÏÇ!ï endstream endobj 4602 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC K…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O9†z†ÿ PÈðÁ†ËÕ“+ ]› endstream endobj 4603 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:ÆÔ„–Ò”³bƒÙ‹ŽþÓŠ<@zšAjzHhxìçÉÛ‚ )9(݈Pò¾¯¨:<Ól ” endstream endobj 4604 0 obj << /Length 279 /Filter /FlateDecode >> stream xÚMпJAðïØb`‹Ë ¹}½»ü»!Á+­,DÔRˆ¢`¼³²ó™ö1,|¯óŠuÆK‚ͯ˜Ùý˜Av8ì™Ôäæ`hC3ê™ÛL?è~ÎÃÔŒò6¹¹×óB'¦Ÿëä„Ç:)NÍÓãóNægG&ÓÉÂ\f&½ÒŪÂbÇ”k 𠟸Bç]YÄ8L 5V„%šiPo+ £jÈEšì‘c”eøÍzÌ4ÂZØ0Ê7Bû-×ðÞ 50“$–„ø ó-| Îï)yÙÎZºBùÇÛ¯ªiËFøTÕVU+8ášÐ0A¥ðBÊaBdÑ%9ÁÇë¶@ ¥PÊ©BìˆvèãBŸë_«“u endstream endobj 4605 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÐÁjÂ@à ƒ4׊ÁSµ`B{êAA{,ØÒž“GË£ôrô ngvÜ]vù˜]Øaþb:™Î•QOt ·O9~ᬠڕüpüÄe‰ú]Í ÔºE]nÕÏ÷ïêåëJå¨×j—+³Çr­€Ö€Ç(àYXU€õ‰zj&®|’€aOÃd pèùcš1uÔŽ¸Æ-1H[7c(< ¤bÆgá Xk;®>É÷èN`$ŸŽ³„Ö:¢‹ -åomc)¾ŠZ¶ç†/%¾á?OFi° endstream endobj 4606 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚ}бNÃ@ `W"yé#ÄOÀ% í©‰ Htb@LÀÈ@ÕÎÍ£åQînìåøí‹ e@Ê铳å³_^-¯¥’¿+ï5±÷ˆ+ õÇÛ'¯[vÏâ=»dÙµ²ß>Ø­Ÿî¤f·‘—ZªWn7BÇ”R$c̤Ž(õÔ„•Ñ(NHN͇ÌxÎì‡ÙÄø—ù%ƒ•ƒõCke2Mo胵ŭB/ç©•ð›Äpè·8Yi¹RN„L4pʉ`Eÿ¡ËÀMôÓ¢s‚Ñd޽~Fgû:5ЗêTúŒŽšHºi¬Ù só}Ë[þL[œæ endstream endobj 4607 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚÐÁJÃ@àYh`Í ”f^@“[ …ZÁ zò ‚ …* =É£åQò9î!tÝ™¤‡âAO;»³Ìü¶8-Î)£‚NÎhaÉô’›wcm(f´È‡›ç7³*MzOÖšô&”MZnèóãëÕ¤«Û+ ç5=ä”=šrM¢“@åë) ¼oç\SÝ%´Ø}‡«³ØqÝKK䄸´ã‡PËFïF왎»m4â„øˆ¤cž´ÂRÀ1Uó'~¤þú@õ›h`"[bzÄ ÉOv˜ÙJ:Y³åœ ¨°»®‡8!áÎy¥»@ì4÷h? î%<$ü¹.ÍùD‰pj endstream endobj 4608 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚѽnƒ0àC"ÝÂ#pOƒ(TLH ‘ÂP©:D™ÚŒZ53<Â#02 ßÙ$i¤(Aœ>l#ÝÓxñSHiLÉ+}GøƒIfÖ!/ùàë€ËÕ'%ªÙEU¾Ñßïqjù¾¢UAۈ–A¥µîÄÑ©kó¡~ÍF AkóæpÖ³Þ`…Ñ9EåÌkð&Çkkpk ³Éá9ç“\SþX¿·ù}iúžõÙÀõ,3ÐðO®ùZ®)g{I!9ÅÎê·VÓ®ÈQ5’Fb´)e¬<îþR‚gJàëàÛ‘)›gpò-áºÄ<[?—Ò endstream endobj 4609 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚmпJÄ@ð „´bæ ÜD؈ œ'˜B8+ µT´5y´> stream xڅн Â@ àÁB]ó^«=ì þ€ÄI¡}´>ŠàØ¡´&ZÚŠã#¹§N—,êñÑ.é>íl<¢v8·$•‹íGªiÕŒ«¨¼9O—=ªÑbL6ª ­m²6èMü”#Îi ÆÀx7.2>´Ê12¦VFS¨0•ªBÌ@‘ú3–ù`F²[ˆ…×cs4"#p}ãþ¢ýK¸—_†á_üŒà'Fújá¾À©‡K|ÒÐqj endstream endobj 4611 0 obj << /Length 270 /Filter /FlateDecode >> stream xÚ…Ð?JÄPð/¤ b.°ìÎ4‰°‚XW0Å‚Vb¥–ŠÂ²ÉÑr”=BÊ!Ï™I\ˆ ¾æG&óþÌ—¥§IÆ1/ù䌳”Ós~NèR-Æœ%ß§WZÝsšQt#eŠŠ ¼¾P´º½bù^óCÂñ#kôð…ÜUà9·µæµs`Ñàâ(+Ìw€z;#h¿GØÈž‹½œÐ!¯ éW¤øñze«»e0Òá¹TV<%× ä‘Êú_ÜHõ'Ëèo@Ûííeõ7®²)Àˆ%pÀb9 czCr™&!j.Ç; w¶³‘¶uØùÍLÚœ«ô$ – ]tGßPÄ< endstream endobj 4612 0 obj << /Length 217 /Filter /FlateDecode >> stream xڅѱ Â@ à YúÍx­ÒªSA+ØAÐÉAœÔÑAѹúf}ÁÑAŒI…C¹á~¾ä²Ü%ïvºJ¨''RÖ§mŠÌ3©-õb³ÇQ…vIy†v*]´ÕŒNÇóíh>¦mI«”’5V%AÍÜ0óåpFµ„6¦;˜—Â8HO?BEà >üˆ¡ƒDtWÈ£ød&VDñÍB;Hµ¢ph>?ìÃg_;ù# tXžymWú Ã,?‹“ øgÔ¬! endstream endobj 4613 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0bc Ss…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿÿ!êAC=3Ø€õ`¢ñL0`'ÁÄ?3˜øƒƒ`?pü`âBL<ÀAØ£úA€=ÿÿÿñDp¹zrr¾aZ¡ endstream endobj 4614 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚmÐ1 Â0à'„·ôBÞ4­¤ÖN…ZÁ ‚N"ê(¨èÜ­Gé::cÒ‚Ìò  üïÓÉ,¦€§$Šb:‡xG!tP”ô/§+fùŽ„@¾Ò1r¹¦çãuAžm"ÏiRp@™@ªTcYk5à¿ÿlÜ2ÛÚmj[¹-lK·Êœl?n½Ÿ¬ôZSÀXÔ¶C}´ªzͪ4çÝAG`ºæ R]d®3€˜/}Ï,åu3ömp)q‹_ûoaî endstream endobj 4615 0 obj << /Length 274 /Filter /FlateDecode >> stream xÚ]ѽJÄ@à [¦0/p}“ — XÎL!he!Vj)Ä¿:y´õMâ\g„uf3›ãR óM–ag3ùùéºÐ©>£Ø¤z½ÑϾažSíJ>xzÅm…ɽÎsL®é+&Õþ|ÿzÁd{{©3Lvú!Óé#V; µ8í@Ê*bãAøxå@QxÔ@AÈ9 œ8ŒÒÍ(> stream xڅн Â0Àñ ‚…Côï LC[T?À ‚N⤎Š‚›>šÒGèØAŒEl ù‘Ëø'ªÙ¡"ÞIDI‹Ö wÛYh¯öaµÅ¾F9§¸ƒrÌS”zB‡ýqƒ²?B9¤…¢p‰zHp6&øÌÕžp¾|b¿-j8 endstream endobj 4617 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚmÑ¿KÃ@ðxT³r¹X4íT¨Ì èä B :Š?Ð9'þ[·uô_ˆ®f’Áó½k›Úá¾|ÞÝÁ»Éá^¼/•ìÓôåA"¯c|ÀdHµâ’¦·8N1ºÉ£šÅ(=•OÏ7ÏŽdŒÑD^ÆR]a:‘[ Âþ’LK> "@ÎÚª(î ŠÖw­wVÞÒ¬¤˜nÐŒä5z+WñJ¥ð×ÕiÄ µì:yNÅR½ RN@WP!Ége¬Ë„¦­<½.#Òv­.©#ÍéFÝZ½ÊI»åÔ[Ê6È,,iÁ‡vR|Ÿ¶­¯•üŸZx¬ûZøsà!‰¥J¥“G*œh;‰¿ÜÚBamÅòi'> stream xÚeÑAK„@Àñ' Èk‡Àù©Úv¶ ò°P§KTÇ`‹:;}³‰û ó òèÁvzÏ]Å=èüFaü;“ON&S™ÈSºòs™ÉÇ_0Ïhžð”_<<ã¬ÄøVæÆWôãr!ß^ߟ0ž]_Èã¹\¦2¹Ãr.¡²„µjÀÊ5ƒn¡rh„߯á‡à3¾Û1¾ÖÒè}Z‡ÂCÑG¨tc‚P…ÙG¢zŒ°é1Ž Ú>#é ÖcxÖ,¬ ‹³ŠA•ºwÐÅÆ!2´EÕ *kíÐ8;´âAqÂ2¨À³jØGÅXmÁ Á'ñÎmA?N¼i¿ƒÞ/K¼Á¨‡xƒ endstream endobj 4619 0 obj << /Length 262 /Filter /FlateDecode >> stream xÚ…‘1NÅ0 †]e¨ä%Gˆ/m©xS¤ÇC¢L ˆ ßð¬´GëQz„ŒªÛdè"Jò)ËþÓ^žû+ªiGgÔzò;zmð„Þ³XSÛüܼqßaõHÞcuË2VÝ}¼¾aµ¿¿&>è©¡ú»€]@ƺ¼›ÙN¢ff¹üÒYÌ*˜à('‰’ ü‚Q‚ BФùŠ Id“!Ù‹¥T$·pÓa“¨èÿ‡6U.ÃοÀÅ~‹I2FE?h+(¸QÊ©š[/¹UöB–€éÃÄ oÄ\öLrƒD’Š5éßÑð¦ÃüÖ¼ˆ„ endstream endobj 4620 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚнNÃ0`G,Ý@¡÷à8UÚ2E*E"L ¨tìPsüh~”> stream xÚuнNÃ0ðä¡Ò-YÙz/IÀTt!R)`b@LÀˆ&PãGó£øÌV¤¨æÎa¨øÈðS|gûîlg{Í×lywŸíœç|×ÐY+Ášg͘¹} EGÕ[KÕ™„©êÎùåùõžªÅÅ ËzÉ× ×7Ô-0j`šÜ#ЧQ æ#ÀD¼LÚ€Òc0u(e ‹+9í1ü´ _¬E—ÿÿrùŠ4ê²A)'RòÐvd/Ú”F½¶™¢”NI/ÏJB7™,ú|z’5[%°m_‰«¾}תŒ¦£G9Ð;}ŒÞ£tøŒúBq)[m0”:˜Ï}ÐiG—ôy?x endstream endobj 4622 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ…ÐÍ ‚@àÂyõ 5OÐ*h&‚ä!¨S‡‚êØ¡¨³>šâ#tô°d»µDFäÀð1?00~8r(9ôÈhïâ }OÔŽ,å`wÄ8E¶"ßC6]déœ.çëY¼˜‹,¡µKÎÓ„ŒZÿ¢‚¬Ô¹Y@T7sɸ z‚l»õbô¤ãÔ x³ýÄR I´;Èø‡®à­ŠªSqk¥¯([‰Å²µ\ÑŧÅy£NS\âwpmõ endstream endobj 4623 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ}ÐÁJÃ@à ¸0HsõPè¼€nHLO…ZÁ=yBA= * ÞÌ£åQò9öP:Îvô 9}à 3Uœ5gœ|Zp5çòœsz¥²ÒnÆå<ŽžiÙ»ã²"w¥}rÍ5¿¿}<‘[Þ\pNnÅ÷9gkjV,"­ùVöFZે˜áÀ&²WŽG˜"‰ì”“jØÈVÉFxA”Í=f‘^éþÇtXD:¥ýƒ$‚ߨÀQ`¢uþõÓ@ ¤ºú3 çØF«d@âma5_³óÙjέ ñ"btÙÐ-}”^p endstream endobj 4624 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ]ÐÍJÃ@Àñ †@¯½9/ » ÄF„ZÁ„zò …Bõ(¨èMÌ>Ú>J¡Ç$ë~LµÙÃòcfØóê¬jHRYÒiE Iõ‚žJ|ÃÚmíxÁ§Ý .[T7(níE{GïŸÏ(–ëk*Q¬è±$¹ÁvEƌѱ©Q³y‰]CªÃœ*Ö>gY8U°³Î#å±`k½²ö¬&•³÷98ù7‹,¼ûàlïsÇJﯬËB>ø¬S}òŸƒ>éŸÙÔ±˜˜Œs¶aeÐø¬ý˜-«#ÕÔ¦~G~±—lÆÞ´x¿+%eÒ endstream endobj 4625 0 obj << /Length 318 /Filter /FlateDecode >> stream xÚmÑAK„@ð'‚ ëU(p¾@©™äÒAØ6ÈCP§Õ1¨¨³³ßl– Sb?‚ÑEXqz㨛ëžüñÈûó&ŽÃcêÓ  GtÒè„>ä•Ħ>¦íèá™ÌRâÝÐ8 ÞæÄK/éûÛÇñfWgÓ9½ÅŸîH:§BTºÁ†4‘Ò ÜÀ-AÇ]˜+ÅÉ@kS]Ñ”„žÆNZC E$«ž6ÒÑEfŠ{œ"92gÖ=ƒ4¦x? vl¸ìÈ% É„k‹0QÔq£µá¾¢t6Œ®,¤¬ ®${Qtpc6¢äÛ,2Ȳ.Þ¹lÉ!ÿ„ŽIËÉ׈¿Øã[qÝÓÄÓ$eO·e%7ŽXÊJÛÔqèòžvKÚl'A‘8Q”ÒÈyJ®Éj㬠endstream endobj 4626 0 obj << /Length 276 /Filter /FlateDecode >> stream xÚ]ѽJÄ@ð [†3iÏ*ûæã0^eà<Á‚VWÂZ §høf_$•¥¤LnœÝ™æ,–_f–ìþ™-‹³bi3[ð*K{~aŸr|ÅrÁuæJ·ñø‚«Ó-˜ÞpÓúÖ¾¿}o¨F`¦Î5@¦î5@/òÌ|ž™×øI¸ãÄÈOàRm\ŸÿáoC= þ‰þ‹×5Þãa“|Ú endstream endobj 4627 0 obj << /Length 212 /Filter /FlateDecode >> stream xÚmνŠÂPà„1­ÅBæ4¹a·ºà˜BÐÊB¬ÔRØ]VØ"xï£åQ|Ë!×1‚XØ|3p椪?pÂ)÷§)?y¯è‡†_²LXFsÙiœQ¼–ÅóÆlÁ¿§Åãå„ÅSÞ(N¶”Mpw"¯þ‘%Î@ ¯FÔ`_¨|ßÁ;Bgá9!¬4`Š&E£U ÁáEˆ ù¡­`ßàAíKª]Ã{ÒªÚAÞ5èä]m?ÎIT”ú*•%Ã!´4ËhE7U}Jì endstream endobj 4628 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚuÐ=N1 à7JÉÍ!¾d¢Ù?FZ‰) ÚQ%$(`r´%G)V ž °ÍWØ–åçÉlßµÜð‚÷Of<]ðµ£;jçRlxzðÕ¹º¥eOvÍíœì‰”Éö§üpÿxCvyvÄŽìŠ/7—Ô¯ó1²ý¡Á/6;¨ yª &C†z‹‡PïÞ@oQ{½:CG ¢Ž2U¨…\Yô•MÁÿ‹Î:|…º$³ñB7¦0x¼âÅKœçP%¤ñ†ø${By‡œ:îéœ>ðLe endstream endobj 4629 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚ}Í1 Â@Ð/)S˜ ™ è&YIc@#˜BÐÊB¬ÔRPÑNÌ-Gñ)SHÖQ ±±xÅütæTÎ+ZS‘3P8¶†W]‘¡‹+|4(; ¬SúwXOøZ‘dx)ñeEûÇã÷îÝ>’ ÄÁ7¸{¦S¹•kœz(ƒ ÏhRЂž]«<ø endstream endobj 4630 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚuÐÍ ‚@ð Á\öœ([2)Š„> A:D§êØ¡¨[¤æ£ØØÍCh3.FP-òCgwÿîŽë5u›ZäQC“Û¥N—vèj.¶¨Ó33ÛŽtVäjtf\F'˜ÓùtÙ£3ZŒ‰«Zóž ~ĨÂoÁ~yûcþáó·µO3I­âΪøÁúÐg¯`g²@¥`¥P?‰|ªXÞmc$EßbX©¹›KöoíJ>G}›—í¹Urì°Ô/ÛcCM~Yܼz¬Â'XÉ€…" 3Éå-8 p‰/¥fl endstream endobj 4631 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚuŽ1 Â@D'¤ü´BþtE…Á‚Vb¥–‚Šv¢ñf%GHi!ê˜B´pgù3c[N¤¡6µ©í¨më2’­XK1|+åÏb-q*fªÖŠR“Žt¿;¬ÄÄã¾FbÑh.i¢À€ûÌÿR]Ü#¯sãìèÁ+ÀË ÿŠ JdDïz|ãɃšÿÇý÷y*Ô˜Œ*CѦ#6 wrÖp38UœßÛ{Ë •‰¼ÆÀAê endstream endobj 4632 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚuÎ= Â@à )¦É2'póƒ‘TÁ-­,ÄJ--m£×Š7Ù#¤L\w… lñ>˜÷šIÆ£tB%:iNãœö1ž0Íô™Ó »#–ùšÒ ù\·ÈÅ‚.çëy¹œRŒ¼¢MLÑEEpÓñTÀž |´E © ý¯ ¤†5àëæf‘Kó)%@h†ðî °€ó;Ô.^†ÞgéþñÍ T;gWø*S™ endstream endobj 4633 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚu¿NÃ0Æ/Êé–<‚ï 1$Щ‘J‘È€S„„Œ : Æ/Æ£xcõèÕ|gÊF=üìûãû>»³‡ý‘´båÀΤ;•ã™ M_ íä·@¡§ýô™!3%Ÿ©×RJP™!ƒLjŸª ÒeTé"féSÊø‹_e鵟´!}Ñ ®©v–¡ŠYW}Çç#_ózGq endstream endobj 4634 0 obj << /Length 211 /Filter /FlateDecode >> stream xÚ}ϱ Â0à+Â-}ï L«­8YÐ vtr'utPtõ±#>€/àPßÀ±Ci¼4‡ùÈå.„ßë4Ý69Ôâíùäwiåâ=];ºÔ‡åûŠy-#¾Ei¿;¬Qô'rQ„4wÉY`X)ð:“ŸõÜZÙ÷?ëÆøŸ¶Q©UüξKþÁ~À ñ„{Í}C!`eá ¸èn!T˜Ëò2­V§ÏrS°’j9·eLtʲÜâÜJ½”’_oJ]pá?Rémì endstream endobj 4635 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aS3…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØ?0ðÑ0‚°0070àü˜ÿCƒýùdD (¨ž¡ýc`øƒ‚è1ÿ`øÿÿq¹zrrxæ<÷ endstream endobj 4636 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚÏ= ÂP ð”…,½€Ð\ ¾~ÐM¨ì èä Nê(¨è&¶GëQzÇ¥5Å>ñ9ø ÉHâc?"‡ìl7"/¢ ¤½‹gô=;ù2Û1ÉP¬É÷PÌ9@‘-èz¹P$Ë)¹(RÚ¸äl1K bÖh½n û†³ü]Z Ð}1˜þTR¥2¥ReI…j"*<~ð;Ð|ŒX®õjèz|Z§WÐ%ÜÍb‹·4ïKq–á _êãMt endstream endobj 4637 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ}бjÃ0Ð3·äâû‚ÊnâM¦P…vê:5IHVË[ËŸ¢­«Ç &ªî ­!œtèNgfå#åÄÛ,h^Ò¦ÀãœC¾øÚá²BýAÆ ~‰§¨«W:Ï[ÔË·'*P¯h]Pþ‰ÕŠ é!.7xùW‰é­Ý=Õ ¿çd°«B7ÒCÖ¦ k¸fÔ‹ «€FmS²°g~Ôr X%NXg¹@íÄÎqßÜ¢“vkùÒ5a{DƒW±-ðØK¬,¶#=¤=d„àCø³âs…ïø C„j­ endstream endobj 4638 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚUÎ= Â@à‹Àk<‚s÷G‚vBŒà‚Vbe,-mGËQrËâ:Ó¨ ßÀ¼W=?Ù [öz9çS®Îðš­F}'fËÞÃ,¥… +¾^nG˜b=gSòαÝ#”Lô¢Zt*ë¨ÿõLd¢M D“ŠGb&(QÝSoð¯'ºÙcc#°Øàþ÷G> endstream endobj 4639 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚÌ1NÃ0àe°ô/½AûŸ'T e!R[$2T¢SÄT‘ÁV¥A\ª£QÀ ¡p¾¹EÔ´1r§a?‰]c{þ&ʶQÕÇ7P ‘_‘Hõ_"Ÿ" ë‚f´צ†8 endstream endobj 4640 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚmÏ-Â@ài*šŒáÌ ØþŽ&¥$¬ … (@" àôXÈ%€ à++š.;¤rÅ|™·ó̦ƒ^”PH±´Oɶ0åräe³Ç\¢XR£˜ÚWrF§ãy‡"Ÿ)BQÐ*¢p² è¨Lo”ј§ª¬/¸do¸tï5Œ¬Ȭªõf;%_[Áa\kþ±vëÕ\`kð*·~Ŷ_;´§@ƒ1_c?Òú0¦Ä‰Äþà†[— endstream endobj 4641 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚuÎ= Â@àR¦ñ™ èf݈ÚðL!he!Vji¡h4GËQr„-·u²¢ìòov™—êN¯Ë ÷¸­95l¼×t"Ó—0a3üLvGç¤Ölú¤æ“Ê|9_¤ÆË kRSÞhN¶”OÈ* x9 ª –ƒ­N‚À a°Ž<+£ÀÆ‚ódørÿqB÷üƒ"ûøR -Oõl¿qÙ€äfM©ä¤’o#Eüf¼ä9b Ð,§½ ]Lß endstream endobj 4642 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚ}οjÃ0ðÏh0Ü¢GȽ@+ 'îR0¤ ÔC¡:„NMÇB[’5ö£éQü1VOIó‡ÐD?„îôqÃâÖæœñ•Sð°àüŽç–¾I®™ìQ¾¯½Ò¸"ó*Md¥@¦zâÅÏòƒÌøù-™ Ï,goTM‰×-Pû²‚_—âÆéi€vP=ÒªƒZCù­ûK⑊]l¸¢Þé.*á3ÍŸ{P¾ï,›Øm¢ñ8Ôˆöb+ã þ’¹°º—T¬t€(‰"âêOìþ79ÕUÛ—Ú3iZÑ ýw'mË endstream endobj 4643 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ36Ò35R0Pac3cs…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]äj˜ÿ7þg`ÿßÞßÀþ¿O¾Á~Ž}ƒ¼ˆ( ò òX€Ä{0Ñ'PˆzQ‡‹ø"þà ÁÄL‚$ñÿÿd‚ËÕ“+ ºæ;W endstream endobj 4644 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ=ÊAjÂPà?¼E`²uç\ ¾—>‹Šµ`‚]¹WÖ¥ E¡‹Psæ%Þ Ðmètb© ÃÿÏøÇþð‰{~HÙØgüžÒ¼ãvüèï²ÝÓ$'»bïÈε&›/øt<ïÈN–SNÉÎx²ÛP>c˜ŸùÂ8jP£‰*&àYeqy×mwn\\q£¤‚‘F Râ"=-ÑJÚ¯ÚÁ¨è.SˆªL(—ŸJÐ÷¦«Ô/%è5§7ú9G, endstream endobj 4645 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚUÉ= Â@à`Ú}ÐÍnT1‚[ZYˆ•Z *Ú‰ìÑÖ›ä–)„¸þ€føš™‰eW(¢uÅ’RA”‰#JåçYï0WÈ$ä;#WS:Ï[äùlDyAKAÑ UAЂŸö›¾ .€ œ Ü Xý­Î½ÁµÊß2 ÌxLÿ 3d°—>ÓÓ{ß”îÍ8µ†+àXáŸ?y<Œ endstream endobj 4646 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚeÎ1 Â0àW:Þ’ØwMC«u+Ô ftr'utPÜš£õ(9BÆ ÒZ)¾þyùb&3J© ©¤|NYA‰w ™†Ë–Ãr¾a¥PÂŽbjjKÏÇ늢ڭH¢¨é()=¡ª)rÛÆ·ÞE?˜nc ÌŒá†õà혤å=-$zL©“ %üÑ ”|(  D$q@3\O¼cæ=üi¡ÑÀµÂ=~] X€ endstream endobj 4647 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ=Ë1 Â@Ð[»Ìt7&˜tBŒ` A+ µ´P´ÕÀxœ%G°´ÆÝDÃÀãó?øƒhÈŠCî{DìxïщÅæü°YvGŠS’+É™®I¦s¾œ¯’ñbÂɄ׫ ¥ ߫ܭª*ûá”pÞâ QˆDnRfi ±[:°J Jô ‘Al[CþÇÊ€±¨Æ1؆‡Æ­y¶¼4ݚ·è85øAÓ”–ôœF< endstream endobj 4648 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚUϱJAàY²0¯M¼yÝ=’»3BLÀ+„XY„À¦´P´Mö |„¼Ê‰àkhee‘òŠÀ:»kÀTüSüÿä£ÓQI†J:ɨÒ  û 1/844(ãåîÇê[Ê ÔW£®®éùée‰z<»¤ õ„æ™VrîÕmSwHÒ‚Õª-¬@~Eé–9ù: ZXïéz>÷ô±ñìÄÆ€L#‰­™Nä(± Ó ¬úÉ›ez‘3õŒ‰ÔêƒY×꛹hÔO@¬lÿáǤ‘c~$ <}M„ pZá þ„å]" endstream endobj 4649 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚ5Í=jÃ@à·,nS4'ÈJ¶6 ŽQHªÁU’2…C ®,MGÑTn!´™“b>˜Þ”ËûÕ‚s.¤Ê/+þ,èHe%}®­.>¾iW“ã²"ÿ$Sòõ3ÿþœ¾Èï^¸ ¿çw¹> stream xÚMαJÃPà?Z8„fí x^@oÒD“É@­Ð ‚¤ ¨c¡Š‚SÍ£åQ|„Ž­¹Ô†sù†sá?šœç3º9‹3MsM.õ9–WI3n/’߯§ÌK1÷šfb–Ý^Ly«ïo/bæw׋YèC¬ÑZÊ…âp¨ ëý‰Â"lî1î^M+ ø{Œhðoƒ)à5ÈiD;['ZÔG½Êé;w>œ£ó‹SšÓˆ~;O{ë. a¯“Á@F‚‘`$ûõ^±ßŽZ¶´ìgÇΖaÛúylÓ_•›RVò§GS endstream endobj 4651 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚuϱJAà± ¢­•7/ {›Üy¸Dð A+ „ÄRPQ°òÖ7[ð|ûW¦8¼Ì$Ml¾…ÙÝf w\9ç>rQpYòÜÑ3*)æ\V››Ù#k²7<ªÈ^H™l}ɯ/odÇWvd§|ë8¿£zÊØKdiÐ"ëû¤D%(€ï;¥œ”Û<)÷ÿ‘”Ø_ŒïOIY Ó~0-Î`> stream xÚ1 Â@E°L¡70sÝì ’@°ˆÜBÐÊB„€ZZ( 9ZŽ’#XZ:IV›t«þ 3ïOÌØÄrÄ#²‰xjø¨éBºN%7nt8SjImYǤ–’“²+¾]ï'RézΚTÆ;ÍážlÆ@TðJô ø@ ðhxÁ«jze/¨ š]aöåÙáýÝ;¿íÇÎAdDÉ/ak+ÚÎ?i¶¥”T“‚RSÊ"§…¥ }G«@ endstream endobj 4658 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ1 Â@E¿¤L/ :ÐÍ®A"ˆEŒà‚Vb¥–‚Š‚…EŽ–£äÁÍ$±ÐNxÕÌgæý¡˜1‡qß„l">hº.§!Ǧ^íO”XRÖcR 7'e—|»Þ¤’ÕŒ5©”·šÃÙ”s Î@ t€h~//i¹ÝKxO`L®Ð“tIVãçßxÅ?üÞù¼¨>ö‡©(=C±uÚ•¿/ñ@ªÅRÓr•iniMoEËBs endstream endobj 4659 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5R²LLR ¹ ¹L @ÐÄ "“œËåäÉ¥®`jÀ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQ`Æ`нLÉI†`’ù˜â‡ˆÙ@¨©˜RŒ)öÈ&U@¤c Œ‚ B•@5@µÃ ƒ µj-\ò²ÑÍ;@¶e¸\=¹¹³+ endstream endobj 4660 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5R²LLR ¹ ¹L @ÐÄ "“œËåäÉ¥®`jÀ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQxÀJB±SŒ \Å¡˜!’ Ø%¡æý@5¯bÙ–A)~d%P PírÈFC-‚Z+‡ì$¨QL‚z…DK ¾árõä äµd*… endstream endobj 4661 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 4662 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚÍŽ;@PÕggÜwAí“x…„J!*” Âî%>‰EÈt3ÍØ00 •¾UjÌØrR¬Ð豆iø¥qAæ 5‚T‡¸šûv̬ɩ‚½Ò p¯ó:½_ó¢thq_þh endstream endobj 4663 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 4664 0 obj << /Length 130 /Filter /FlateDecode >> stream xÚ-ɱ Â0…á gð 2œ'0¹-¥™k3:9ˆ TGAEçæÑòfÚ¢|Ûÿ—ÕÒ7ôlXUÔÀ:ð¢x@='eý;ý m„;P=ÜfÌpqË×ó}…kw+*\Ç£ÒŸ;Zä“Fy2d›åÏd“L*R!s™ÉB¬¹ËY°ŽØã ,P#Œ endstream endobj 4665 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 4666 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ-É1 Â@EÑ?^á ¦xЙ‰‰mŒà‚V"ÑRPÑ:³´Ù™&Nwo¾\ø’ž%红V\ó¦xA=y1žö:À¨n×w¸°ççý½ÃÕ‡ ®áYé/ ­tò‹½4è’M22ÉD³˜ÉT&2+•<å*ØñBÛ#´ endstream endobj 4667 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsK…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O†z†ÿ 0XÏ ÃÀåêÉÈ[\w endstream endobj 4668 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽AÅñ ɉ¨ŠóÌ—eëµSH¨"‘ ” ôÍ£xw³ÓN¦ø5çæþgvZ8œ8K¿àÜñbñ€·²–>žÎ7TzOo¡×²C‡ _Ï÷ºÚ.)k̓<j*¥zÑP ¢±‰R˜è.NÑO|[ƧÕmÈÜÏdSéL6•Îeé\6•NdV;üxÔ*Æ endstream endobj 4669 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsc3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7À`=ƒ 1S—«'W fp"¸ endstream endobj 4670 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ54S0´P06SH1ä*ä24PAS#¨Tr.—“'—~¸‚¡—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEA†¡žá Ö3È0຀`ý™ PÈx€±±¹™¨Ò‚¡€!ËÕ“+ &,• endstream endobj 4671 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 4672 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ32Ö30W0P0S06V04W0µPH1ä*ä24PA#SˆLr.—“'—~¸‚¡—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓE±¹A†A‚Á‚Á€¡€!0€Âs ÿþÁz ´oàcàrõä ä-#ª endstream endobj 4673 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚUÌA ‚@à7 ÿÂu ÁÿŽXÓJ0ƒfÔªEBµ ,jímŽâ¼AiÒ"ßæ=xj1›kŽû¤)«%gš/ ÝI¥ÊÆå|£Â<°Ò$7}MÒlùùx]I»'$K>&ŸÈ”ÂGƒÈ½mÞ~¹¼ûi\Ô…ÎáðG8Ô¢x­8ÂM lÏŸj„¨0­ íéb+12 endstream endobj 4674 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 4675 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ32×3³P0PÐ5T06V0²P0µPH1ä*ä2‰(™B¥’s¹œ<¹ôÃj¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ Ì Øð107È0°3H0°1X0ð10ð00È0$E@øPôPŸc0nøß`ÿàÿû0\@Œíø€Ìärõä ä;g0÷ endstream endobj 4676 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31Ô35R0P°T0²T06V0µTH1ä*ä22 (Ce’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 5ÿþýg„" Õ1ü*Êl*,,0‘ƒ—«'W /¨67 endstream endobj 4677 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚUÏAJÃPà‘Y13Ð4i»j³tåBA] * ]”vB.{b yÐ ÜdÞsJDìâÛüÃ{ÿÌqt”ô¹Ç &yÐ燈^(Ž4ìñ`ØMîŸhœSxÍqDá¹ÆæüöúþHáøò”5ð¾¹¥|€ü`aaÇ9Áïeå­ ã—R(£L¥(û3”]µ7EÉÛ`±¥EiÕÔêN-6Vj-pâW©|gÁÓíªÀ9£Ãpã«\ª²,~‰UsퟻNöŸívI ÊìN=k¿jF(uŠE}€¥ññ£òÖŸÚg\ غ]ÑYNWô_Z endstream endobj 4678 0 obj << /Length 351 /Filter /FlateDecode >> stream xÚ5‘ÁJÄ0Eo Xb·6? í ¶Vf`T° AW.DÔ¥ ¢àbÀúeü‘|B—]Æw“6‹Hšóî{-Oæ&7…9,Lylʹyšé7]Tr˜›ò$Ü<¾èu­³[ST:»”cÕWæãýóYgëë33ÓÙ¹¹›™ü^×çÈz@´%[Ä µH~, „p@ìp€/ ±Xb¤VöðÝÈó}§äí“íöòÕ$í—@‡)…»@?° ½§éc˜ŒlSŸT¤_2øz>:)zÉSQ/w9õ’÷•zæ§žýPÏþ¨g¿ÔS@=×Ê "mÃÍ¢"{tSøí_¶‘Û‡£\L:eÍR@5Rl#² L7‘¥^ Zê7û] gOª‘.P²y&#›àMYYê¬.IÅŸ«gÂØÏž¹ýp¤?éËGúTl]úfbÖÒµ¾Ñÿ&¨† endstream endobj 4679 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ø0Aý? Áøƒ½ýãù† ö@CÿùA2þ€’@5@’±D‚!™dþÀðPI¸ùÌCdþÃÀþƒ¡þÿƒÿÿ “\®ž\\^åˆÓ endstream endobj 4680 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bScSK…C®B.SßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.Oþ êÿ³ÿg``üÁ~¿ùûÆÿüäØÿÉ?`°gàÿ¤êàÔ õN}`o`üÁÀþ¤›™ÚÔøFÑ¢¢˜ÿ0°ÿÿƒÿÿ? Q\®ž\\à  endstream endobj 4681 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚÌ1 Â@…á· LàœÀMŒÀBŒà‚Vb¥–‚Šv¢9ZŽ’#¤L!êÄ‚ºËWÌü0aÔíìs_„D¼hO¡Ïõ—±«-%–ôœCŸôX¶¤í„‡Ó†t2r@:å…œY’M¦€zÜáæ&óÐÎc¸¥§ÜÁ©ÎPÕêöøp±t¼¸e£] 0.â,$+IJ’“‹¬áâ­õ§_ÏFn_óoõ^:,Íè Àv;r endstream endobj 4682 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚmÐÁj1à é^=;OÐd-‘õ$¨…îAhO=”‚ÐöX¨ÒÞ„Í£í£ø{ô°˜N"¸Q6>fB&?™Nî'izàmf4Õô™ãáZûÒ||ã¢DõJÆ zâ.ªrM¿»¿/T‹ç%å¨Vô–“~ÇrEP@X×ìû8õ \²²IU{ó˜»ùÁ3ÌbÆYã¥1Ezôè$æ'i=SË©†LÂB„p6Pu Ž–8ç:R†£ ²Ž÷›[4ß9Þ²áéí…ÃŽ&ÎÈ&üZÚú'­ãXήÁÇ_ð%°m¼ endstream endobj 4683 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ•±‚0†0Üâ#pO`Amd3ALd0ÑÉÁ8©£ƒFgúh< ÀÈ@¨…«Ú´_®íÝýýe4fÐÜ,¹ ¹¤kˆ”µÓ„íÅåŽqŠâH2@±5§(Ò½žïŠx¿¦EB§‚3¦ i3 €5C8ZA–›À/:LÊ^ÕÁ­ûpšôXpžÛôkÚF¶­±bIF°Ü2ÕéqžËUœNÐC¨™E>ª_…ñ÷c‹ð+v·d¯ó¯åínÔâ&Å~VŸP endstream endobj 4684 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJÄ@à? LaZ áæ4‰Üª[-œ'˜BÐÊB¬ÔRPÑÖÌ›ø*¾‰yË+Äuv²g!–Bà#“ÍÌî¿ÎïúnÙñÎ;ÇÎóMG4÷Zly¿›¾\ßÑ¢§æ‚çžš-SÓŸòÓãó-5‹³#Ö÷%_vÜ^Q¿d ˆRPDZT†¸R´öR ÊOÔµ þ@ù*˜(ÞAWEÁ],øR‚º˜IµRê5ú7P­Ñ&?”2oÆ(~#FLØàgÈü5=dF#ïzv¢L;mf–Ä&,—mXJ[°Ìa Þ#å }Rº:%e-vÁvS½•Ô=U:î霾šes– endstream endobj 4685 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚ33Ö31V0PaS Ss…C®B.S ßÄI$çr9yré‡+˜špé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁõBýc``üßD@.ƒý0ÅÿL1ÿSŒÀÃ?UBÙ7@¨`JJ=SüPêŠýê (<ö¡9ÅñP¯@=ómrüC%h˜ACž  !@ y`> stream xÚuб Â0Ð  ·ô¼/0­ µ‚Dª£ƒ¢³ý4?Å/iLsqˆð’»INÍÆª œ&vª)©9 ¼¢‹åý¶O4¬4Ê©åÊFQê5Ýo3Êj³ ­ioK¨k2ýè D˜ÒÀ€§dFLƤ1’(­C8^Qˆ€„ÉÆDð¹ïɰ|pÃ1ÆÛ½Ó.þ"bøÿyÒ€Œ)™gëºk¸×¿àRã?UŸ’~ endstream endobj 4687 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ35Ñ3R0P0bSCSs…C®B.s ßÄI$çr9yré‡+˜˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÀd’ñƒü†ÿ Œ`’ᘬ“6`R‰äÁAòI68ÉØ€L2`%™‘Hv0)"ÿÿG'!âP5Ⱥ‰ A€J$ãÿ `G@%¹\=¹¹Mÿx× endstream endobj 4688 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJÄ@à?l˜&yM"&`µpž` A+ ±:--­7`ákMgé+ä ¼òŠãÖÙÍ& XšæKf’Íì¿]{Üt\ó)p×p{Æ =SŠu¨ÄÎæ‰V=U·ÜvT]j™ªþŠ__Þ©Z]Ÿ³>¯ù®áúžú5ð(ü6S¬ßü`À쑊-Ì— oÕ¶¸áÖë¥d‡ˆ¾¯ I¾Sòý03a‘™LlB".€¿Ñ!1ÍúOx½&ÂpcÄJÂ&ÆHù‹¸£…¸Û…˜„rI)¥ÌÜ” _ò,v0Ÿšõù{lØtéT–‰é¢§úî”Û endstream endobj 4689 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ33Ò3²P0P0bSKSs…C®B.SS ßÄI$çr9yré‡+˜šré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÏøÿÿ?TŠñó bü78) À¤¯s‘)hèb y.WO®@.!»¥7 endstream endobj 4690 0 obj << /Length 106 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0aKSs…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿ†€ˆ¡¾aècWüÅåêÉÈ3v\‚ endstream endobj 4691 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ31Ò33W0P0VÐ5R0¶T05WH1ä*ä26 (˜ZBd’s¹œ<¹ôÃŒM¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. öÿÿ?@"äÿ000°ÿâ„=ˆ¨oÿ`#ø?0üoõ ü ä0X0È`a°o`àŠ2°7Ãñÿ qõ \®ž\\ŸÎ`¬ endstream endobj 4692 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ]ÑÍJÃ@ðYrÌ¡¾@ û&A[sjsìɃxj= QôjöÑò(y„=HÇíÌÿДeöDzÌÌ~,¯/•/üUŒeé7~_òG‹8"ÇÝ;¯Οãšó›GÿõùýÆùúéΗœoüKé‹Wn6^DÈÅ8×I êF"!¢:˜+2oa[8˜®7“`¦dÎ`+ØÂÁÔôhLM‹fp ˜&byiguf0«­~5Õ¿jŸþ©RrÀyd* îÕõSkÜ_ Ÿ¨ NÔÇ÷9LÕxoéá ÿádÔÿ™‹„sù¾á-ÿ5Š•P endstream endobj 4693 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ35Ô³T0P0bKSs…C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ€™dü€þ3 eR/i& 0È ò‚d“Ì`’LÊ?`üßÀðÿÁ@!¹\=¹¹Afl÷ endstream endobj 4694 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚuÑ?kÂPð{<0p² Þ'ð%œÿ€ ur(Ávt°ÔÙ€«ê•]ÝÌGÈè|½¨X#yîøÝ=8. [~›< 8¢€:½û¸Ä°ËµW”ÅÇ|ýÕ”Â.ª1wQÅÏôõ¹ú@ÕjH¯>yoÉà瘣1 ýƒ¸ 8hFãx‡]Ê*ñ›1æ•øá8§¾yºØTBŸ¤,a P³ —À“M õ2Ü< œ fepÒˆ\$ÀIÂÖ5+zÛG4÷V¸Y5D NZ@fWðí¤'c´ÔÒÇýoÊÀQŒü¦Â! endstream endobj 4695 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/.0…ûfŸÀMNÖ?óSge!Vji¡hkRù\AKÁTÖ©$EØuwöŠM1üøf`Šï`¹·<’…Üw£¥>”w%=’Ö.>úÃí­jRWRkRçnKª¾ÏO/÷¤V›SY’ZËëR7T¯¥µ@fµm óÀ¦‡í¼ÅÏ0 à{d¾¦˜üۘÎ=õ4]LÕ3ùȦ€aÒ@b·´liº@ÏT|`Ä“MLjbËÀ¾Å4ŸLõ“ÿ1ÂÄdtFÀœW$®Gœ á*Ã.|ר™±ÕtIÿ6D†c endstream endobj 4696 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­‘±‚0†Ï8˜ÜÂ#ô^@D'ÔDŒ“::htGáxWÚœmš~éÝßöú_LÂyÒxJsNgoô(ò»ÌéŠIŠîžÂÝ5‡ÑM7ô¸?/è&Ûñ~IŸ¼#¦K¶ Cµ¥ Ô¼*x1F%¨À)dBœÃè ñ‘Š…¬ªA«ÑŸ8çEÅjGîU…Ò(ßNk¼ûÈ4ª,— ~ÐjÔ…}Á<ÛC¿2[|Žþfa?­-ÈÖžÆ3ë ñ“­oŒ×œÈ¾}°]Ñ=ÂUŠ;ü”K‰É endstream endobj 4697 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ35Ó35T0P0bS#Ss…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚ ê„úÏÀÀø¿,ÊÀ ÿLñSÌ? Ô0Åø™adªT Y;ªÑPû ¶CÝuP7ÈÙÿÀÔˆ ƒ™….ĵ˜—«'W ŽK€¿ endstream endobj 4698 0 obj << /Length 309 /Filter /FlateDecode >> stream xÚ­‘±JÄ@†ÿba æ3/ I ‰ Bà<ÁZYˆÕii¡(6‡Y±õ¡ò>D|I™"Ü:³$EÀÒò…Ù™Ù™ÿ/²Ãü˜Êé -¨àŸºKõ£Î3Ž&t”G›½¬t|My¦ã Žë¸ZÓóÓË½Ž——g”êxE7)%·ºZà[ÈÙV°óþz=ÞªEd€°‘¥ê€šKzNä¬.{7Aâ|®Œ$sQèЄÒ>j"‡vDÉmvsÔý#ƒL°ÿb~ÃüöùdóáGŒûñ¶[ÞVužeø½ÿajÖEyȳv¾Y©:À†%*?ñʵÑJî¤~D`q£ìû€@\qðíBìcáÌšpê`¶èŽÐþ ™j‚óÚ·²<§Øq}^é+ý 6²¥É endstream endobj 4699 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ Â0ð–‚ì#x/ i*Uœ ~€ÄIí£ù(}„ŽJãÙK Í"&…äHrÿt¢F*ÄÇ8 q¢0šâYÁ È€f4ãÊé óäžê ×´ 2Ùàãþ¼€œo¨@.ñ 08B²D­uåÐ uf,HW§‚ ô¥lüfëç¬(ºz¥eõ§Ö~ûüæÞ¦Øô§¹_Qš@™ñÍëõ6Ò+L®6ŸñeålóZ¹šÿ«›v,X¿ÕKéP~ï‡ÞEÔºe¯Ö©úN=â’¹«vð™<›Â endstream endobj 4700 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚUϱNÄ0 à¿Ê)K¡~h{=îÄB¤ãè€Ó ˆ @°!ZÞ̉èF%Psw ²|Jì8¶ç‹Ãª¦’æt0£ùŒŽŽé®r®^j°¤EµËÜ>¸U㊠ÕKWœkØÍ=?½Ü»buyJz_ÓuEåkÖ?€ÆŒ!òÎf°l#>Ù3ZÎ;@Î'€ç7Àîx ïÉ&Œ&È–Nm9ƒR0—!¡G/aEïFD+E$½ÑŒµ²MX‰¿„^É>a‡-úÆü‘Mˆÿèû=¦×:upÇ´–¤-µiÞ}õèGŒˆA§Š^{s¦ywÖ¸+÷=Ÿ†# endstream endobj 4701 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ3µÔ³4W0P0bSsJ1ä*ä2ñÁ" Fr.—“'—~¸‚©1—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÁþ?<@£0ÿg`ÇÀøùA ˆbüP¢>€©T*L`¥€)‹`J+ŦF Åþ¿Hʃ‚ârõä äWÎr° endstream endobj 4702 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚåÐ= Â@àÑÖBÈ\@7‰¬ÆJðL!he!Vj)¨h«9šGÉ,SˆëlÅ3X,ßòf˜âu¢VsÀmnFlzlº¼ é@ÆH¸¤˜¬w4HH/ØÒ‰I'S>Ï[ÒƒÙCÒ#^†¬(±µÊ>ñl \3X~ZPCAù©J'BEH?4€þ—ºôuâ7{©-'¿ROrï%ËxºVÝ™‹Ã·¹CÙ ï qBszØxaº endstream endobj 4703 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÐ1jÃ0Æñg1> stream xÚuÑ1KÄ0àW „ãºv8ÈûÚôÎb ç vtrá@ÿ…?'â)ΤC¹ø’£âMHøH^ÂK^Yì/Pá÷æX.°8ÄÛ\<ˆR¡ëÅÑvçæ^,k‘]b©DvJË"«ÏðéñùNdËócÌE¶Â«Õµ¨WhíÀ­í"kÿ·ä@öŒæ¤àmDâ$f~¤#; Hl ¿¥½8@£ÁŠwdFUšì¨%[pù¤^q(é`J7)¯Iˆ’›ÑMk¯T¢äRÙñRI JN%}¤½Ö<=“Dt2l¥IÜ©yÑÑ&ôFš:Uï; ôAš9ÉOŠ} ô5*¡¿­ºÿÄÿ‰°­ ÄœŒE'"'íEÑ<´¾¦®_g'µ¸ßÑÆ©Ñ endstream endobj 4705 0 obj << /Length 279 /Filter /FlateDecode >> stream xÚ]ÑAJÄ0àC»…МÀ¦Ç.„Â8‚]ãÊ…êÒ…¢ëöÁ«ô&æuW°ôù’<3‹ôãÑ¿ù».OËÊXSÒZ[svnž ýªIkÂè_<¾èM£ó;šu~žÍyûxÖùfwi oÍ}aìƒn¶¦E„'8p…@ë@Òµ1Ù±=™Ž h¨ $«3,ØÄ+N¼€ÝŠ­‚moƒµÛ³.˜ }0ý颿Q…£’x(`ÜO‡b<¾£âkˆç|ŽÑ4ºPS0á€%»â€ ¢–ƒöàØÞW¾œÌÈCeàË  »ä›PIÂ{Á7™½]øоiՈݱúªÑ·úR}Ý endstream endobj 4706 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚÍαJAàYÈÁL›"y÷.p1©b¯L•BAS¦P´Î=’p²2EÈ8»n@ô,†ofgÙ§“ËÉŒK®´¦×WüRÑ+ÕsË8ÆÅó– ¹5×sr·zJ®¹ã÷· ¹Åý5Wä–ü 7©Y²È ð~k%…öÒvìT²Z^{ÓcÝÙ³ ÷ÃâôU«o²CÕ0Ë–*¤ÅSTB¶‹ú`ζÑñÞ&‡í%‹ãE¶Ÿ´§QÒÈ0›b4è3¾Ýe}÷¿Íÿô"Ý_馡}Èl® endstream endobj 4707 0 obj << /Length 232 /Filter /FlateDecode >> stream xÚUÐ1JÄ@Æñ/¤¼&GØw“@B,ÄuSZYˆ ¨¥ ¢`—-GÙ#liv|ß‹ÜÀü`fÈŸ™iÊ“¶ÖRu«M«Ï•¼K]Ù¼ä”O¯²î¤¸Óº’âÊV¥è®õóãëEŠõÍ…ÚêFïí—é6¢}8rB²G‘š² ç g@þãîp ¬vøÂoûÑðDšD,ZŒN€Çà±E‹Ñ- ®Å-FIâ2vpŽeDZdøÓbt¤½k±Ùt`ÌÜÓÔel6óXÆË"÷ó­üdÁí=yÙ<"ú»ýW.;¹•_µštó endstream endobj 4708 0 obj << /Length 204 /Filter /FlateDecode >> stream xÚmÌ; Â@à . ´Vf. ›´1àL!he!Vji¡(X›£å({„”Á8ë£—åø‡ùÝéÅQ—Úš’˜º}Úi<"ÏÈŃ÷f{ÀQ†jÅ{T3ŽQes:Ÿ.{T£Å˜4ª ­5EÌ&¡€º6äü¥…°%/_x÷/PAP02gøýÁ0Ò¦–yp&îî¬dBw›:Œ+0ðÁüâ}¨AT¾yóMÞ6Ó¢5lö–¢.Ë5²Ài†K|¤øT£ endstream endobj 4709 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01V0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃT‚D0S$ê00|`ÇÀü¹A¾ù;ÿæ ì˜ÿå˜00þ* àÄ?8Q"êI&êPMÊøbÛ½`Ëßœq ä ã ò Ìê˜þÿ:]þ—«'W ÈckA endstream endobj 4710 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚÎA ‚`à'?( ‘œ ”ýüºÌ A­ZD«jXÔ.Ì£yàÒ…Tcu€ßæ 7f: 5ÙðP³™° ø éL¦ %¿—ý‰â”ü MþBbòÓ%_/·#ùñjÆ’&¼•ÎŽÒ„¡ZÀ{ÈUe5ÈTÆ©¬Ö-Õ‡W¨6êÀj@-ÐÉÅóOù¯Ó‰;*`{ú^‰ž[bàTd7“ý w§”§ÍSZÓ»= endstream endobj 4711 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0VÐ5T01Q0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿó‚ÁþT‚zó !ÿHÔ±÷`øÁøþó†ú쀶¤ „|P±=˜i«‡u âÉDª)öph‘<„ÚkrF=ÈAï?0þ`<ÿŸ¡†½ÿ?ƒü?þÿ ì@‡s¹zrroXhI endstream endobj 4712 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ]Î1 Â@Ð\˜B/ 8ÐM²(ÚЦ´²+µT´“èÑr”!åbI qáÁ23ü;èö9änÀ¶ÏvÈû€ÎdC)úlGUgw¤IBfÍ6$3—2™dÁ×Ëí@f²œr@&æm)‰Ú¸·2Ï©\^¡sϵ2¸Î÷¯HÅøQ‰RñþQÖOþø—Ö5ÉQÑJrµìhè M£íÂá„TårL¼@³„Vô½£@ endstream endobj 4713 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Õ36W0P0bcSK…C®B.# ÌI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ê˜ÿ70ð|À ßþ€ÁžÿCÿ`ÆÌ00ŠÿÿÿÇäè§3ÿa`¨ÿÿ޹\=¹¹¢&[ endstream endobj 4714 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ¿J1Æ¿00…ñ v^@³9ïäŠÃ…ó·´²+µT´[¸}´> stream xÚ31Ó34V0P0bS …C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ì€à?É&™iN‚ìaþ`ÿD~°’È700nà?ÀÀüDþ“ØÀÈä‡$Ù€‚ëÿÿƒÿÿ7 “\®ž\\y endstream endobj 4716 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS3…C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜ø0È@A@ 8~Àüá? ±q©ŽØ0üÿ‚¸\=¹¹(CE` endstream endobj 4717 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ32Õ36W0PÐ5QÐ54W0´P05SH1ä*ä22 (˜Ãä’s¹œ<¹ôÃŒ ¹ô=€\úž¾ %E¥©\úNÎ @Q…h ®X.OÆ ìø   P?`üÁð†Ø€¸ôE6Œ?êügüðŸ‚üc?PÃ~À†Ÿÿó.WO®@.ÿ§Wõ endstream endobj 4718 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚµÍ1 Â@Еir3'p.#˜BÐÊB¬ÔRPQ°ÍÑr±0EÈ:? êdÙ³3ó7èuÂ.{Œô¸òʧãH‰ÆrCqJzÆGz$¯¤Ó1öÇ5éx2`ŸtÂsŸ½¥ […RÊüâë?´LõºæÝ3Ø‚ærÁÊkm‚¨„;xÔÂ3êH†Kv¤Ø@%¯â.êýoÔ nn—**ŒÉù@Ô¦ôDr endstream endobj 4719 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS …C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?0ü‡!þ ̃±ÿ`øÿÿq¹zrrÆ‚Q. endstream endobj 4720 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ3³Ô3R0Pa3scs…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?ð`Àðÿƒý†ú@úƒ=ãƒ:†ÿÈ77Ø3ðnà?Î ßÀüÿˆþÇÀDÿa`ÿÁÀNÿ``ÿ€þÀÀþ`Ð O€âÿÿƒÿÿ7ÿÿNs¹zrr#߈ endstream endobj 4721 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bcs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ìø?00üÿ`ÿD~°’È70ðnà?ÀÀüDþ“ØÀÈä‡$Ù0½ñÿÿÁÿÿI.WO®@.‡e% endstream endobj 4722 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚŽ1‚@E¿¡ ™†#0Ðeƒ6 &na¢•…±RK v9Gá”Tâd)H¬ÌN^fþîþù‘žÌ¦ð”Çš£€Ã9Ÿ5Ý(ŒE”qÑßœ®”R{cRk‘I™ ?îÏ ©l»dM*çƒæàH&g8^W‰S­œQƒdHàVðá•R¾ ò!J*¨- Ài~ nNû/†ooñkg»Íîõ$AéÖHåŠ> éáwlzZÚÑIKÚ endstream endobj 4723 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚα Â@ àH†B¡y½ž­uj;:9ˆ“::(ºÚ>Z¥p"ØŠç]qÐQ |CB’?Šû2ä€Ü“1G!‡#ÞI:R°«aøm”d$V$f¶O"›óùtÙ“H–$R^K6”¥ŒÊ¯À¨\ƒ¹UW0÷Â/¼º%>Á«°T¨5*è´4hy~“ÿÌ÷ö²¥ý¦Ýß> stream xÚ31Ö³0R0P0VÐ54S01Q06WH1ä*ä21PASc¨Tr.—“'—~¸‚‰—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃùŒêØ0üa<|€ùÃãìÊð?`0?À€Áþ€> stream xÚ36Ò35R0PacCcs…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ØÈ3üPàÿÃÇþ?nÿÀÿœýó3 ~Äo˜0ÿah`þÁÀ€‚?P³Íüÿÿs¹zrrjÙF„ endstream endobj 4726 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚ=αJÄ@à¶X˜fßÀÌ x{›`TñSwÕ‡•Z * Wî£í£ÄÊ6`“"8Î%GŠ™ùÿfŠ|q~ÆK.ø4p¡ó‚½R^j¨çåÔ<> stream xÚ36Ò3²T0P0TÐ5T0²P05TH1ä*ä22 (˜Ad’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Ø W á Œ@Ì Äì@,ÿÿ?Ã(f„ÊQ „þ0‚pC sC3ƒ=;ÿ?°f.WO®@.uH– endstream endobj 4728 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01Q06WH1ä*ä21 ([@d’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ ìþ`üJò`À‘p’ƒºBþ`°ÀÀðƒ¡üÆçÿì™Iùÿí@’ùÐ.WO®@.1c endstream endobj 4729 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚU̱ ‚PÆñ#‘k[çêªWJ'Á rjjˆ ¨Æ†¢¶ˆûh>Š`›Ph—º—jù ÿ¾@ BŸ\ò©ïQà“ÒÎÃ#ŠHE—Äè³l˜dÈ—$"äS•‘g3:Ÿ.{äÉ|Lò”V¹kÌRj×_œ œÒ.Á.X ,g0i)à <¡¥©¡pƒ¶&†®A†=éjœ|c(v‘kØ]þb=ÀÐ(Ô¿áúO¨ÁI† |F£?ê endstream endobj 4730 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÎ=KÃPÅñs Xx³v(æùzËíËb ­`A' ÖQ|A7©‘|±€Ð~Lïx‡`¼7UÓN?8gù«áá°Ï!ñAÄjÀÝÏ"z$¥ìr·¿~nîh”¼d¥HžÚ™drÆÏO/·$GçcŽHNø*âðš’ WUPñ÷6¾Aß´4æðŠ5¹§q ‘þ" bxØ%âtÇq¿Á_ù®cùGˆÅ²h;²š÷L€ Ëtè5Â<þfúOk…2·|âµÁ+ñ–ZlECÝdÑ ±ï(°ç˜ÂÑIBô¥Y_™ endstream endobj 4731 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚMν Â@ ð)(¡«ƒÐ> stream xÚUÎÁjÂ@àYi® Î èn²Zõ$¨sÚSE¨GÁ½‰æÑöQ|„x ‰³²Iéå;üÃüü=ÝF¤(¢N8 ^DúÖ!þ qª¨¯ÝiµÅIŒò‹ôåœs”ñ‚ö¿‡ ÊÉÇ”B”3úI-1žQY¦ãâàAægà//7ˆœŽ4gËZŽvª*Ì 0‰Ã¿˜Š+ã]S‡¸CEÉ@QsüϰFÕì,IqSn/¼'¶’gCþbŸ^m‘mjg`ç1øã'>ÚŸKø endstream endobj 4733 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ%Î1 Â@„á‘@„‡$|'0‰+AA¢‚)­,D¨¥ ¢æQ<‚eŠ`œÅ_ìì·°&î# µÇL_M¬‡H.bìÚ£½ØŸ$I%ب‰$Xp• ]êíz?J¬¦Êu¦[>ÙI:ÓIU•uO§Ã)Fh~ðß!;£ó:còÌÛዬQÖ‘‚ôŸÿ)HÿåpIëH]R·YÀ#õH[¤mé(œ²âl2Oe-?uàC endstream endobj 4734 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚµ1 Â@EH!L“#d. ›ÍºˆBŒ` A+ ±RK EÁBb޶GÉR¦R×l´6¯˜˜ÿþPtÌ+îǬƬ5$Ii;ŒXÜf¢$#±a¥I,ì˜D¶äëåv$‘¬f,I¤¼•í(K~ |[äj¿„W¢‚opGÏà ÀÄ!´—S‹¢E¦ /‹òèzù´ÌO¾6x+Ó¸YÛ~åÕÎÜuдñí…æ­éÂÕ`ú endstream endobj 4735 0 obj << /Length 121 /Filter /FlateDecode >> stream xÚ31Ô35R0P0bc3SS…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]0001;Ëñÿ ÿaX*6T°ý†úÿÿ?À0—«'W ¾NÚ endstream endobj 4736 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚmαJÄ@ÆñoÙ"0M^ป'p÷WóSZYˆ ¨¥ ¢`eòh>JáÊ+ŽŒóé5‚E~°;ÿY²¬šc­té_^iÓèC-/’³Ÿ+9¸’u'éZs–tî·’º }{}”´¾<ÕZÒFoj­n¥Û(Ê-€~‚Ù€8¶#J^ÎQì0CÜc…0áùîÈDÌ_úŸžÓÁïø:ßsöNüaçü™r$_΂[-> ³À,°ˆ, %‡s„'äƒlÏ"³ÈÌñ¥™aAZÒ›M°¿ÈY'Wò TŸc| endstream endobj 4737 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÐ1NÄ0ЉRXšß`3', ZiY$R AE¨€ ´ØGóQr„”[¬0¼„‰"OÊŒóÇ“ãîÈ/¥•^—ÒŸ‰÷òØñ+÷ÅVüɾóðÌëÝ­ôžÝ%Êì†+yûxb·¾>—ŽÝFî:iïyØ™-­2È9QµµÕ EëPõE6‚f¤LÍôV»&‘ÆàðÌÔb&e6‚€§Ñf“õÕŽó‘òY (yâ/ifU ý°Å_ cBüÔ¨M>Õ‹ý‚¸Ÿ™°y¥ÿ€‚޵¸2_ |ÃßÇ›jh endstream endobj 4738 0 obj << /Length 188 /Filter /FlateDecode >> stream xڕν Â@ ð+ At-(˜'ð®¶µkotr¡P?ÁQðÅ_ÄÇè èý‹­³ù‘äIàõÃ+FŠÃ!¯=Ú“™º,ñ‘o)Ñ$ìG$'¦KROùt8oH&³{$S^z¬V¤SBĢ⊠ØÀ©iƒèA«äf°1ë€h‚.p;»Áö`¯Z  \2ðoóŠß›ÿÂy™³54Ö4§òý`ö endstream endobj 4739 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ•Ï¿jAðïnaÜ ˆÎ ˜½s=b!j W¦J!‚`R ìnÍG¹G°´8ÜÌœEH:›_1;ödÏyŸSp¯ÏnÈyΟíÉ9)¦œ¿Ü_6[šd?Ø9²oR&[Ìùð}ü";YL9#;ãeÆéŠŠÇÀŒÇæÒºÂ„ÐpQ*Å+j .+xsº7á”xÄ•‘Íç–Üð‘\ƒ }µrÓþ† ”¿ø´•R þ/:tK­¬uéîNTc¨'Û¼‰Ä'ò¡jìiT”2ƒ®D¥×‚Þé+XÑ endstream endobj 4740 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚm½JÄ@…OØ"p›¼ÁÎ}d³ƒÚXW0… •… j)¨hëäÑò(ó)S„ÏD…m>†{çüÜuuìVZj­G+­ÏÔ9}ªäMjÇa©îägóø"›VìÖNìÇbÛkýxÿ|»¹¹ÐJìVï+-¤Ý*Ðô@ P„sŽºø‚&¾³¾[ D>#E@ƒ¢Ç†r˜Iõ~2û> stream xڕα Â@ àHÁB}Ѽ€Þ]õ¤“…ª`A'uª(¸ÙGóQî|ƒšTZèàà‘û†?$w#3°i²ÔhdÈŽéhð‚CË!Çá·s8cœ ÚÐТZpŒ*YÒíz?¡ŠWS2¨f´5¤w˜ÌHŸP˜Qžç®ÎëY’ 4aÐ:B@à ¸Ç8 ‚—1¾ìn -¡SQ¼üRá-8­ð d“_Ñ®Ó+ÈJ¢_<ÿ!’¯tùâ<Á5~lúQ- endstream endobj 4742 0 obj << /Length 265 /Filter /FlateDecode >> stream xÚMÁJÃ@Eo˜ÅÀ[8мÐ$A„ÒB­`B]¹WêÒ…¢ÐEÁù´ù” ;#Ç›*ÖÍyóî{wæÎquÔLµÔZ§ZŸjÓè}%OR7KmN~&w²l¥¸Öº‘₲í¥¾<¿>H±\Ÿi%ÅJo*-o¥])L OÄ[ À`;d1ëa¶°3X`LpÀM6{ä{xÖSÏœ˜°Hpžî|tO¥0£1l¹6Ì ùi4ÈþÓ,ìÀe3zŸÓáw™gRÒô¦SÅß@v伕+ùÿcå endstream endobj 4743 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚuÏ1NÄ0бRDšÆ@ò\œlÖBT––E"Tˆ ¶¤AKr®â›ì!eŠ3³ ˆšgiÿ_×'aE5t¼¢æŒB ÇŸ± 2¬(œÎ_žpÓ¢¿¥& ¿”1úöŠ^_Þvè7×çT£ßÒ]MÕ=¶[‚b—….'0SÉ2*(ÙŒ`&p ÞÁõBì!Ît ç¼àÒð_èÝ_èR¥c§Ø™%Éž 6{6Cñ!I¬cˆ“Ä)A×ô?€Ö«ÌÁ“ôXZ1IÁØËN+éOVë”ùÀäqY‰-Þàú m9 endstream endobj 4747 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ•; ÂPEo°L“ ™ èË{? bSZYˆ•ZZ(ÚÆ,-KÉR¦uò)ÔN8Õ ÌœãúzÀO¸g4û†‡†šÎdŒL=ûíj¢0&µacH-dN*^òõr;’ W3Ö¤"ÞjövG t)PÂ*ÐÉaçp2¸)\ à <` %:5vQá9܆ Á÷ô‹×ÿü\ø<.¿š§òÝ)Z™FL ÅSl+ç¤ö— i‘"é’:i”Òª·Kó˜Öôï*c¸ endstream endobj 4748 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ•= Â@F¿`˜&GÈ\@7»þ¥RðÜBÐÊB¬ÔÒBÑ.ÄÍ£ìR¦⸠j)¼jfÞk÷[ºÃ w¹i4›”{†wšŽdŒLNÛïÕö@#KjÅÆšÉœ”óùtÙ“-ƬIMx­9Ù°J @,ˆnB‰ BPÂÈ«gXxnˆ÷$ÊaõKý?¿¾GîýT¾‹ÃKæ%–{Ïúé,æâ/Ò"EÒûÆÌ÷J5M--é7Z£ endstream endobj 4749 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ37Ñ32W0P°PÐ52S03R† )†\…\¦ aS¨Tr.—“'—~¸‚©9—¾‡‚)—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Bý0`€PÿÐi˜<—«'W ¦5° endstream endobj 4750 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 4751 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ31×37U0P0UÐ52T01V03RH1ä*ä26Š(XC¥’s¹œ<¹ôÌ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. @ ",@Dˆ(€@Ä f€3˜h€ì`¤ŒDð9!'l°˜7§éƒqšŽ0x`LGŒÓt„Á8MÇä‚ËÕ“+ :Ì6Ù endstream endobj 4752 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚM1 Â@EH!L“ÖBt. ›5*$BŒ` A+ µT,s“£ä)-ëÊÀ›Ïûãõ:ºÇ.·5w‡ì ¸ïó^Ó™$º2"«jw¤0&µ’R31¤â9_/·©p1aM*âµfwCqÄN‚ã &yæ–IK˜·m² …mòž…õŸ€É‚À # ‡d¸Ãʤ²R©ìT„ˆ¨%’Yh¢|Þ’å¼lAÓ˜–ô!K endstream endobj 4753 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ}É+€0DQ?«˜ðúÚ4TóI¨ … (@" àÙy!Á#®9×i •êisZÇE±Ãú Ã7æ E„ ´Ò0@bËó¸VHÑ•THÅQi&ÄŠ)¥û/Ô=–Þ-˜ endstream endobj 4754 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚM; Â@Eo˜"ð7 ú6 “‘‚ L!he!‚ –‚Š‚]²·2K™ÎvÊÂ8~@›s/ç>xq§v8àVÄQã„“”·!)î:¼ägÚìi˜“\pÜ%9q†d>åóé²#9œ8$™ñ2ä`EyÆXÃ+= ¿µÒWhºŽj@ß®¨×aÚ w~€§þ` ”›D‰»7X#¬²•°úƒ‡°æ‡âá}1¨`õMƒB½ŸÓ8§9=1hM& endstream endobj 4755 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÕ1 A Eÿ²]¯8;êÀvë N!he!Vji¡h«{´9ŠG°´ãd±QÄÞ<~~ „¸~·p\p/•³ìJ^[ÚÑ L}¡­V[ª™9J2ãä’ >ì2ÕtÈ–LÍ ËÅ’BÍ@.ÀY®*åtÀßà“}4˜I“½¨™kÆ\Ðê7B <µÄ/z‰¢ñ…íž¿aúš×³?I£@3zóպà endstream endobj 4756 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚ}бNÃ0€á‹ó[ñòŽ«í#•Ú[wж¾£¯Ïï7´«ûkÊÑ®é)§ìë5€Ú‚,ÝÇH‡Y˜1Fu˜EÃ1˜Û$Ì`„Ú³$ª] ½ciÕÝiÇ’˜¶MÓ6Òj T§Ä%˜0Òú©`t‰è)ßšô »µýÚ£Éî§ûì0„R7¡ ŒÇ’A¢«Ó\—þt‚‡dèC@ëf;„wÛ€75>à/G°ž% endstream endobj 4757 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÑ= Â0àJ‡Â[rß LK©¥S¡V0ƒ “ƒ8©£ƒ¢s{4Ò#tìP“ö¥qj |ä‡÷Ã[Æ‹$Dõ^†Åx àQ¢Î¾>ê‡ó 2ü€Q|£n‹->¯+ðl·ÂxŽÇýˆ¥^oÇémIiTEí¸²êud=X4ƒi;87v¶LNó7މoò™üTÏŒêd²T}Xö÷_õ§—QOË^Wþo5Q;ŽG2Ê7öOõ×Ò<êq.ÖœÔWX ØÃuRÖä endstream endobj 4758 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ½‘=NÄ@ …¥ÉÍ!¾L"±ËnC¤e‘H¢J ´$GóQr„-·­ñŒ7qF}#[ãŸ÷–«Óõ9Õ´ “†–g´XÑsƒo¨¬Sxm™§WÜtî5áZúúxÿ|Á°¹½¤Öª±Û´ (E¸TV";§‘èYäepšÒ{ðJý¥9†~P(eÔRÂé™XföìdH-Ø ÌXq*óKÏíÄ8§ãþ/÷ü§~ÖbyœoƃÑöq?´}Ý`ôƒéáÁô©ÀôºÓïëØ0fW Ø';´¬jœô÷#˜©†úcŠÍªþyÄ< ^ux‡ß³ = endstream endobj 4759 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ37Ö32V0Pa3 Ss…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ@˜þ¥ÿÃè õ?ØÿÓp,ÿBóÿ‡ÐÌ@@4#P2Íðÿ„®ÿ€JÛÿ@£ÿ@hytúú?iBöÿAu?œ†ú«þª¿aá¥aá ?öÿ¨á[ÿþ°ø@‰Ÿ?P\®ž\\2oÉ™ endstream endobj 4760 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ}б Â0à+Â-}½'0­Út µ‚ÄI‡‚¯ì˜¡Û¤…¦VÇÇår~>ÅS hR(Šéâ#^ô¦-Ç &ÙŽ"ŽlUÜ"“kºßgdÉfA!²”ö!”)isÞÀKT •¡oéY<py~# ³ˆ?@Iæz­S=©Z¿ˆ¿‹Ah1s–Ì!oâ9)ù–¹ÁÓʦ«:#Ç¥Ä-~·Ê endstream endobj 4761 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ33Ð3°T0P0bS3Ss…C®B.S# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁ¬CýfÅPÿLÉC(~ÅŽB1£PŒX© ª‚Å€Dý@¦!;˜úÿ7UÓ€j š ø(ÚP °ÅEq¹zrrco©· endstream endobj 4762 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ36Ó32T0P0aSs…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…h 1±\ž. ÿÿÿÿƒŒê0 uŒî'.WO®@.•õy9 endstream endobj 4763 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ}ѱNÃ0`W"Ý’GˆŸ'‚6Ý"•"‘ &ÄT¨`mòhåM"ñÙ"Ê‘³ÿƒ­ƒ¥Ï¶ìÿ|./ÎÖK—»óy”…[–î© WZ•ó<—©lì^hS“¿w«’üõ¼J¾¾qoû÷gò›ÛKWߺ‡ÂåTo3Æ2OÀ4ƒ1&ë Е&`1¶’H@ÕŒ@8-§iHd€D#` Ñ•t2*Æ= ð-¯ü|qÌâOŽéü¡h96Ž¥ŽbÔ£ˆR3· <9QXF7Ü+´chFm”vµb S„ŒÐ^¹:¿cÿÑ›ðƒ swtUÓýQ~Ö( endstream endobj 4764 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ35×31V0PaScSs…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þVŠ¡þÃ0¤ØRüPŠ %BÙ£Põê?˜b„PÌŠÿ˜ªÿÝÿ8(.WO®@.‹† endstream endobj 4765 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}Ò±jÃ0à·è ì{‚ʦIëBÀ¦P…vÊP:µ;´´ÒÁ~°~?‚Æ &×S !HÁßIËwWÅÙÅœ :—[U4¿¤—ß±šI_„6|<¿á²A·¦j†îV^Ñ5wôùñõŠnyM%º=–T> stream xÚeѽJÄ@ÀñYR¦É#džÀMü¸\·pž` A+ ±RK EA±ˆ¾™¾I|ƒ³Sˆgwv/'W,üfþÅn³¿ÓìQEþ4»tÐÐuw8›Ë\ùÑ/®nqÑ¢=§Ùí±Ü¢mOèáþñíâôj´Kº¨©ºÄvIÌ@ƼÚÀ˜À èøU´Á;€é=zÅ‹¬ž'|+ž|1 #G”R (¤ø¹¤2))€RT¸58BÒ )*¤¨¢BŠ ˜0Dtc„㈒ß(rþTd¾†À¿á±<\B¹…"!OÈL¬ÑmÁ%”‚Á£è!ü)ä Y‚Ùµx†n«Äº endstream endobj 4767 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚµ‘1NÃ@EQ Mã#ì\Ì*Š •¥$\D‚*J(SAíÍGñ\º°2üñÈ "JË»Ïþ£ïÿÍã]>‘{™Êm”,—éƒ|DÞr!B~ôÊzó’Ó¥d‘ÓÈœ– ùþúùätöú$Pçòϊ˹‘vdW¢º3Vª-p¥uèÁµ›/ˆ «Æ—=›:Ô`Nzº¸wÏèʼn¬8røöØ,œÍVÃpÚž£¯Ý¥xèçóœðdnÿ¿&8둉ç°;æb9©•ßÞ³µ0ÔrEÓªõUXîЂyjóÖA‡^ªýŸó:œŸŸ'?—üÆ¿°ÛÈI endstream endobj 4768 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ33Õ3²P0P0b3Ss…C®B.S3 ÌI$çr9yré‡+˜šqé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ˜ú¡þA¨ÿ õ?øÿQŒÿ€( Ä Êþ2%ÿ…úO&…b ª Pk!Ž€: ì@ˆ'@Ôõ¬q%vŠËÕ“+ 0¾ª( endstream endobj 4769 0 obj << /Length 233 /Filter /FlateDecode >> stream xڥѽ Â0ð‡Â->Bï4bÛ­àØAÐÉAAëækù(>BG‡Ð3͇‚uP=¤òAYý‡Ú¯K]¹k̵ÚpÍ&ŽËœÛÈ…MšÊgd ŸÎoç°Úk|x–¯pÿ +‡Â@Zä/0ƒ´d73(Mº\5|¢³3¿WU =e0ƒ>¬ß endstream endobj 4770 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚeϱNÃ@ à?êÉyƒÆ/iJ"•¥‘J‘È€D'ÄŒ X{÷hy”^åc¡¯êŠ™D5‡=îþÙü:þé§“ÎÇ|ñ_.þ(Ø_’ IŸ˜4B±±ÌCjÑz8½–nZ:Ð7¡6 endstream endobj 4771 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ33Ó31V0Pa3cS3…C®B.SK ßÄI$çr9yré‡+˜Zré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿƒANúÃÿÌÿêi†úõ Zþ@ˆæ‡Ó5`šNW€ifœôýà˜fÄI3€i0™4?(pÓ\®ž\\wG³æ endstream endobj 4772 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚíÑ1‚P Ð’.^@?'ILtr0Nêè ÑÍGã(ÑP[ˆ‰““£Cû_Û´Ë‚Á0$êûy4Šhïã CmJ9î&»#&š5…!š¹´Ñd ºœ¯4ÉrJ>š”6>y[ÌRbæ\æò €[B§øãgpq ‰¸þD¬…b¢ ¤û7 ›%é¸ÇXzÂ’¯²+pîC‘7 M=$¿©¯¬qÓ˜«ŽÀY†+|œ¼T endstream endobj 4773 0 obj << /Length 271 /Filter /FlateDecode >> stream xÚ}нNÃ0ÀqG"Ý’GȽ8‰DÃÔH¥Hd@‚‰uFlU›GË£¸o©‹‡¨ÇÝÅ|4RâülK§¿\•ç%æXâYUŽ>ð³Šy{9Þ<½Â¢û€³ ì ƒmnñãýóìâî °K|,0_A³D"êMLäþá¿1 /äΘ­¢c Œô/jEË802F¦x©åZ0WðýFf ÖÇàa2+x…3‘ ô .Hbìþ‰‚[¥TS'J &f N”@MüA­àÖy@»Qpâ: œèÜ7v#"Úõû†ö.€¶ÔBMíúŠGH'‘ SÄ~ }J× ÜÃ2ÿš` endstream endobj 4774 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚuν Â0ð+„[ò¹'0­~€ÄIí›™Gé#tì =猪‹!ùAþ¹—úù€RÊÉG4Ó!Ã3vYªW}ØŸpR ßP>@¿}±¤ëåvD?YM)C?£mFé‹AhÀ0W–¹pµ•(Ô†Å&áRŽ_ïÕGW«¶RM©Êú1|šŠw5áFò—ú«ýö ]Ÿ÷æ·ñ¯¬5IW¦†º'C»§{p´Ü:ކ«ƒV†#Î \ã 8.y endstream endobj 4775 0 obj << /Length 191 /Filter /FlateDecode >> stream xڵϱ Â0ÐH†Â-ýï L«–ºj3:9ˆ“::(:·ŸÖOÉ'dìP{^ŠCEœÄ<¸Ü%¹$“Q”`„c^ Ïc¸À4å¸ }âp†Ì€Úâ4µä]Pf…·ëý*[Ï1•ã.Æh&GA‚}1è”t@%’c55lË)É1•’¬(*ÉÚúzí¼Ãºgã û¶?øqÛÛ[®ë„­Da_½=@ÖMÐ é4ÕBÚ3²ò'`a`Otí„€ endstream endobj 4776 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ•Î; Â@à )ÓäBænbÄ*#¸… •…X©¥…¢­Ù£å(9BÊKÆY#X[Ìó‚?›M³ŒbJ]-(Ó9Á¦¹ô±kÝâtÅR£ÚSš£ZË•ÞÐãþ¼ *·KJPUtH(>¢®> stream xÚµ= Â@FR¦É2'p³$!vÁ-­,ÄJ--­o–£è ´‹dœ±ò¯æÁ·3ì<6{AŒ†\±Æ¸+ [ˆÎDi,7P3ŒP#¾eƸßÖ ²É5¨çƒ˜->E) ït´ÿD›ŽL®Ì”Z&U¼×!˧Òm,—J¯¿–yÿ"LŸXœÞI?ðåµ]ìÀ&^-Vìæ±gÇž·Zêø¿n$ù̴ɦ†¦p h¥Á endstream endobj 4778 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ]ν Â0àS:wÉ#ä>m©Ð± ì èä Nêè (¸¥à‹õQò3ã­ þ\È'›3ʇEÁ)çrFçï2:RÞߥ}ì¶×”¬$S2{ZÏù|ºì)/&œQRñ:ãtCuňCèà:DávG|‡iÊFy”­öÐV;¡tPo¼0ðáƒÌ7ÀæÙ÷âª{äKxÕNÄ. P¡5­ô €’’ÒÒ‚¦5-éQle€ endstream endobj 4779 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ3²Ô3´P0P0a S …C®B.c ßÄI$çr9yré‡+›pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä?000þÿÃÀÀþÿ?÷£¾ÁþÁÿ†ÿÿŒÿ¡óFÁð¿FØ1 bˆÿ ÓÑbõÒøÿÿÁåêÉÈŽXo5 endstream endobj 4780 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚ…½NÄ0 Ç]1Dòropõ @ZµU™ˆt`b81#æô x¥lŒ¼B$€Ž7œbì´Bb"Š~±ì¿?â¶?é;ª¨¡ãº§¶§æ”j|ƶoE]·„îŸp3 ½¥¶A{)~´Ã½¾¼=¢Ý\ŸSvK»šª;¶rJ“€xþâP0ów4Éð{\í .c9ØNø]ÿ”"ÿßY¹pÒ&Zm­¬m¥1¬˜÷BÏ`­XëX Ï2ÝÌ1Ï2s–Pª)£Ö—àH˜²r”Á€—L¥5ø1ýÒýáU¥—Wôš[$ÜtUòÝ’ŒáYņ'¼ðr˜Ô endstream endobj 4781 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#S …C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3Á$;˜d¦%YH2ÿÿ$ùÿÿ’ò@Aæÿ6Œÿ˜ÿW€É òÃÿÌÿ ‘ H$Ã’ÿÿÿ±ÿÿ“ärõä ä WžH endstream endobj 4782 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#SSK…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØÿ0ðÿ!ùÿ("”ªÁþ3Ô#!öÿ ÌÔFÿÿÿ€#.WO®@.Nq endstream endobj 4783 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚÍÎ1Â0 PwõÒ#Ô(i‚ í©‰ H01 &`dÁœJ\,Gér„I+: F,=þ°*G² ŒÒ ¥rBjLyI‰gTÝ9£i>dûVņTbfI×Ë툢ZÍH¢¨i+)Û¡© ë¸íEì¿ Yßëú¿Lì!æO`ý’@7Ú[§=·Û¾9nÙ…ÝØû4?ú×#nç×ø`9yÚ endstream endobj 4784 0 obj << /Length 198 /Filter /FlateDecode >> stream xڵб Â0àJ†Â-}„Þ˜TZèV¨ì èä Nêè èj}´¾¯ÐGè˜!ỗƒ:Èw÷'„dfœ¢Á‰ßiŽYŽûNf¾6\ò`w„²½Æ4=÷]Ðõ/çët¹œbºÂM‚f u…~ÑCQýÓˆº¯*ÇSÕK¦cã;[È©›èXeÙ°c£–ÅF:Ô‹’!÷ö1HÞ¿B !ù›%ލõÔ‰=Ûˆ…ec'lô’ü_Ù‚ì§0«aOP‡Œ± endstream endobj 4785 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#3S …C®B.## ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3üGBìÿ˜úÿÿq¹zrrÊWù endstream endobj 4786 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚÝÍ= Â` àˆC!‹GhNà×"Ú ‚ ì èä Nêè (¸µÒÁkyo =Â7:”¾¦ÅÉÁ8„<ù! úín(žt4BMl}>pÐÓº.«ÁfÏ£˜ÍR‚›©vÙÄ39Ï;6£ùX|6‘¬|ñÖGB%%9µ "” 4Dªrr•{Ef‡V5 ÜR×’S^r_Ô,µÿ¬¥»IQiâNÉë[)%ö[ôyü/ Èû[<‰yÁo¨Rµ€ endstream endobj 4787 0 obj << /Length 151 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ1Ô`øÿùÿ Éÿÿ”gþ$mÿ7°ÿ«’Ìÿ>0Éÿþ`þ‰l@"üÿÿýÿÿ˜$—«'W Žá‰ endstream endobj 4788 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ31×37U0P0bScs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Œÿ000ðÿÿ$ëÿÿ’ÿþ700ÿc°ÀÀþ‡Aþÿ2 \ i$Á €Êêäò?ˆl •Ä4b>Ä.dÛ!îp!îdræ~ùÿ€$Ø_\®ž\\-in« endstream endobj 4789 0 obj << /Length 193 /Filter /FlateDecode >> stream xڭп‚0ðš$·ðÞ h[I;˜èä`œÔÑA£3>Â#02Î+šhÔM‡þ†ûúçK£`¨#Ô8Âc¤1ˆqgàaÌSQðˆ¶H-¨†1¨ÏAÙ9žO—=¨t1A*õA½›¡ ]‘O›Pö±’JA…äy)Iˆ¼r&õÓ~ó®ßþàÇmý—·’ªkÂ]Ÿ{77”Ôx­Ü¿f}N$¹nýCâù&L-,á‹ endstream endobj 4790 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ­Î1 ÂP à‡B–¡¹€¾>ÚÚÍ‚V°ƒ “ƒ8©£ƒ¢›ðr4½I ›ƒ#Uuù†„?ùÓ¨•PD15m›RKqF ‹kL2F”ƯÕ|…ÝÍ„’ Í@çhÊ!m7»%šî¨GMASKÑ Ë‚Àð©†\.!ƒö97„;9ûwWð…ÃÚ è*¯=išÝ§ÕSùA÷uSyïÚA­û<»‰öÔÖìÉá& NÎj(GÕMÀ¿trÿû%Žñ¢‰› endstream endobj 4791 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ3¶Ô36V0P0bcsJ1ä*ä26òÁ" ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Ã?æ ÿÿñÿöÿDM}Ãÿ?þ`ÿ÷áÿæÿ@Ä8ÑPß$쀈` 4'þÿÿ‡Ap¹zrr8WÖ endstream endobj 4792 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ%Œ= ÂP„7¤¶ñÙ˜„‡Æ.à˜BÐÊB¬ÔÒBQ°“£y”á•[„ŒûHñÁÎÌθb2+$˜Š+ä’ó]n: 2ç/*NârN7ærZmåùx]9]ì–bîJŽV9qµ*ý> stream xÚ36×34Q0P0bc#Sc…C®B.#K ßÄI$çr9yré‡+Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ø0°<¶‡âz þÁŒ@ÌÄòÿÿ?ø„™bTÂðÆÿ ÿ7~`øøƒýÿ@Ç400ÿcàrõä äÎpR endstream endobj 4794 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ30ØøÿŸÁþ?’ý?ãÿÌ@5J2"‘Ì0’ñ?;ˆlàÿÿ¨Ìèâúÿ€¤üÿÿA*þÿçrõä äðŒ endstream endobj 4795 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚe̱ŠÂ@Ð7¤¼&`Þ8Éš …(¨ ›BX+ ±RK EÁBÐɧ䦜"8ÞqaZÜ÷=¸yÒÎ$‘/$ëI§+ë”wœå良þ±Úò¨`=—,gýƒ+ëb*‡ýqÃzô;–”õD©$K.&âœQÎ~8¢˜¼-x¥)؇%‰à Vd‰.hUAëmPþ[‡0ªÃ+|D0|D] ×zy‡ÊÝ^Öœ}÷b‡Uc\6úù?ù»à?#Zh endstream endobj 4796 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚuαJÄ@à9R,L³opÙ'p=…póSZYˆÕ¥…¢pE ûhû(û{]Ä#ãÌZ˜F˜ácfø«Ë³«Ú朻ªÍEmö%¾aµâ¹Q»WÜthMµB{Ë[´Ýùxÿ|A»¹¿6%Ú­y*MñŒÝÖ‰\Kÿ©&Ð#d!#P¬OIÇ*¿ —M «D // R2h‚``ÝRÌ“m\®ùÕ‹ãzð=@>6m8ˆ}F}:ä1Μ¢>²Šý ,EýÍfù¹œ‘]ˆîO Î sSq0€iî ›TxÓáþ¦‹j endstream endobj 4797 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeͱjÃ@ `-~„ÓôìÆ&lpˆ‡B2e™ÚŒZš-?šó&†¾ÀA–Œé– î㤻_*³—‚2z•S¼ÑbI_9þ`QJi©ŸßØthwT”h×ÒEÛ}Ðßï鈶ټS޶¥}NÙ»–˜a÷lÌ}ì!â!xHĢ µK{Ñ0S%¦ÓYLæIŒÙ±„4¬^½vA:ÓCžõÿ5ûÏ2?¹j,TÓkØ„pÂgÙ àe3D^63ÔìŸÅU‡[¼}l* endstream endobj 4798 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚeϱJÄ@€áYR¦ÉÜÎ è&^¢‡óSZYˆ•ZZ( Wœ$/%ñEò[nnœYäÚ|Å,ü3[åû%åt@{Å!•Ç4?¢ûŸ°¬dšS5ÿ}º{ÄeƒîšÊ ݹÌÑ5ôòüú€nyyJºÝ”ßb³"fo8ü7a êLìàŒ¸{؈kq€ÐàEoÄÚ›A ª I¿sLÅlL;q›‰é6‘­˜ð,ú)þˆŽ"pøkë'ëaÒö“šß “6ª«jùTº…vûMtÕ%ü¥yþÖpû®É7«±šc%^–Æ ð¬Á+üš~oì endstream endobj 4799 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚMÎ? Â0Çñ_ÉPxKŽÐwÓÚ‚bÁ?`A'qRGE¡ƒÐ-Gñ;ˆñ¥.ù@^ø’W EÁ)çáŒ9ñ)£+åa–†kx8^hV‘Ùq^YÉ”Lµæûíq&3ÛÌ9#³à}Æéª—Þ{÷G«¼-m,@{L¡?˜ y㉲§C¦|Ï uäj%@ª* éy RM§œT—rR)§~ØØI;Ýó¶Ri+&¶éPÚ¦¼•õþ¡eE[ú´åfN endstream endobj 4800 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31×37U0P0bCS…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€ÀDübvQ$þÿG%úAüȨÿÿÿÁåêÉÈB•\ endstream endobj 4801 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿbaš> stream xڅϱNÃ@ `G"yh_éüp’([+•"5:T #Ö^í%pcó»He``ùÛ÷û\·wm# iä¶”º’¦–ç’߸jQD¹ùéœ^yݱßKղߢ̾{”÷Ïöë§{)ÙoäPÊâÈÝFnˆ(ºžŠèF Ñ©j…Àd|ÉŒL@Àä6ììmБÜT /åˆõ¤sg`À|¸®Œ¿8c†Â¨Ò’5 MñÃÙâ—”i\Qn+ ¥yrŠevœEs¬á‡Žwü Ô4„s endstream endobj 4803 0 obj << /Length 252 /Filter /FlateDecode >> stream xÚEÐ;N1 `G)Fr“#Œ/³£Ñj«HË"1Tˆ ()@PgŽ–£ä)S„{Aló)Çù“iw¹›iC]Œ4M4Oô2â;n÷²¸¡yþÝy~ÃÂÃm÷8ÜÈ2Ë-}~|½âp¸»¢‡#=Ž´yÂåH`xpœv ú$¸ä"¸,t¹?“”¬¥JIÏRÜsTR/´°vÌ „ –å6£#`f€ÀÁ3G&û-Û]\\ò\´Eõ«åV>R®ô­tŠUÌ?p¦²"ÅFÏ ¶ø¿Ìò¢!ÚS‚S¯`% ^/x?}Ï“… endstream endobj 4807 0 obj << /Length 136 /Filter /FlateDecode >> stream xÚ32×3°P0P°PÐ5´T02P04PH1ä*ä24Š(YB¥’s¹œ<¹ôà ¹ô=€â\úž¾ %E¥©\úNÎ @Q…h ¦X.O9†ú†ÿ ÿᬠ—Àƒ€ ãÆæfv6> † $—«'W ÷ '® endstream endobj 4808 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚ½Ò=‚0à’$ßÂüN`!!U'ÄDŒ“::ht†£qŽÀÈ@Z©mIjüÙlBÚ-ïË$ÇCŒû‡ÏOñÁ¸š‡jª^gHs`[ä1°e¿ ,_áíz?K×sŒ€e¸‹0ÜCž¡ì‡ „(eml ñdE|µQ”ýb©M*mÐhýVK;-Fi,ŒI©U®Aml´¾µu¥Öø¡ü“ΧâûýéË÷Úl.CNµ›ŸÍÕZ¸=x¦Úº½%õÐë³gizïÜÿ@Õ‹6ð ·¯7 endstream endobj 4809 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚÅѱ Â0à; ·ø½Ð4X-‚P¨ vtr'uTt•7)7´&/¡Â“²‰Ž hÀ4³“"¯rM¾ò¨Ó˜îzd‡Ú endstream endobj 4810 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚ½ Â0…Oé¸KßÀÞд¤v øvtrAPGAEÁA0–Gé#8:õÆÜòANȹß-LÇÎØp;ç"ã¢ËëœödJ åZ¾_V[êU¤glJÒ#‰IWc>NÒ½IŸsÒžçœ-¨0pu@ÜÜ€Ä_‹x vёÒZÕ°uú/¬{#õÒ¡^EÈAó^Uö‹ÌzÌÅN4° ¨E A2ò¢;Wa…Äé ¨°V4¥'VhLr endstream endobj 4811 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuÏ1jÃ0àg<þÅ7ˆÿ 4²‘ã1'…z(¤S‡$ MH×XGÓQ|„ŒJÝW\(TˆôúŸ 7uN3uúk‘i1Ó}.Gq%CËáf÷&u#öU])ö‰±ØæYϧƒØzµÐ\ìR×¹fi–Šè €éÆWà‚Op_ÝPIÓ!õ I@Ò*¤#f %×#ý¸~á,üK{ÇT#ç¼³¶,„ΰq`É(°nìYÜsLøâ¾Þ–ÇF^䃷V2 endstream endobj 4812 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚåÐ=ªÂ@ðH˜Â\@ÈœÀMü BÀ0… •…X©¥ ¢­ÉÑö({Ë«ãî+¾¼b†ßü§˜aÖé8åž«|Äý>2ºPî³Ô~±?Ѥ$µá|@jáRRå’o×û‘Ôd5åŒÔŒ·§;*gX@l$Æu¯8lSyÕEÈžñn!Ñ­Á£X#xiTCÄÆ©F•þHjODO' 0¿ôvÒÊÝö§þ³B÷J#n Ò$"¡ˆù&š—´¦ݤ› endstream endobj 4813 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ36׳4R0P0a3…C®B.c˜ˆ ’HÎåròäÒW06âÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0ÿ`þðÿ‡üŸÿ?lìþÿ(¨gÿñà?óÏÿ6ügü  u@lÃøŸñþC{Ì ´÷ÿÿpÌåêÉÈÈöPê endstream endobj 4814 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚ½½ ÂP F¿Ò¡¥Ð¼€ÞVn«“‚?`A'qRGE7Áúf}”>BÇÅšÞ‚Šè*3$|9º×î†ì³æV‡uÈQÄÛ€¤}®+ê5“Íž†1©%kŸÔTڤ⟎ç©á|Ä©1¯öר8Ux·èã”À*à%V7±38©“ÂÎ \Aî&°rOP ådeyÜ¿¡>Xý ?c\%éý#øë£æË'q¶(I£©fÔ‰µNšÄ´ ƒ…) endstream endobj 4815 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ3±Ð37U0P°bC33…C®B.c# ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<] >00013Ëñÿ ÿAø9³ùà óÿúóCýÿÿÿa˜ËÕ“+ Ìt^@ endstream endobj 4816 0 obj << /Length 259 /Filter /FlateDecode >> stream xÚ]ÐÁJ…@ÆñOf!"·."ç åÚÍE0p»A.‚Zµˆ ¨vµ ôÑ|Á¥‹ËÎgH0?˜ñ?p´¬NÎNmn¹ÊÒ®×ö¹wYUºÏ¹å‹§7ÙÔâîìªw¥§âêkûùñõ"nssa q[{_ØüAê­…ÙÈB´aD4%;˜>Ú#îp¨§Ýà{%*eÌdl”鈧W”]èHÿ‹ùOË·ž¦…dfä 3Âױt¢KÒ‡óF¼oæû¼³MØfl=³oÂ,"†EÌ"pLΉ~WІh–Fš¥F³*Ö4×€& !Œ3ž´DWþËZnåÎvj endstream endobj 4817 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 4821 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚMÎ= Â@àR,LãvNànB¢ þ€)­,ÄJ--íDs4o¢GH™"8nÂW ïÍÀä¶?ÌÙr’ó`À™RËû„N”f>¶œg¿nw¤qAfÍiFfîs2Å‚/çëÌx9á„Ì”7 Û-SŽ(–§“·“êѪEšÎ§#ÀZ^JtÔhàŸF{pš FÄUK½ÑóžÐ%\ÙÞùÝü3q UA‡R•ˆš´¢/Û W endstream endobj 4822 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚMÎ1nÂ@б\Xú Gð?»kǸ‹%p¤¸@"UŠˆ ()@¡‹bmÂ\.’åÏzEaéU3SL¡—eÁšMΫç%›LóÑÐ…²ÜÇš‹·Ww8Óº!õÍYNêÓ礚-ÿ^o'Rë݆ ©š ë=55#ê[$w,z¤w¤U‡‘CÜO|?Mì$í ÞƒàofÜ\‹‡X‘^ÄC0¶3UÊà-Ä%âbé#±þ }4ôEO·€[h endstream endobj 4823 0 obj << /Length 438 /Filter /FlateDecode >> stream xÚå•;NÄ0†mÉMŽ_‰-#-‹D $¨(KI‚:9ZŽ’#¤Leð{fc–Z:,%ÖçÇØ3öüësqÉ . ~VrQ®åWð`oLèÙU–¶ûù•mj–?pÙÅòÕÃòú–¼¾°|swÅË·üQðâ‰Õ[éRAaI€ $<% g•Bœ­Fâ蕲“ÂäíŽQ{Ûôò߸ɭügvrlÖHÔmi"•±„¶2mIÙj©7¶¶­n”[?Õ+ň£^`vnNþïÛÝnìîRD [·®T;çmä·hѯ`Cë¶;剟èwe_φœUb^œ¯¦*ãç)Õxèi[>|ø,²ëšÝ³/ ñ]î endstream endobj 4824 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚ342Ñ37S0P0bCCS ¶PH1ä*ä24° €@’ɹ\Nž\úá @ .}8—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ÂxÀpÞÿÞÞTÞÞ9öÿÿIöÿ` Êc¨ÿÿ‰Ç±Êcã1@œãÕƒ …ñìÁ®ñäÁ4ŒÇ¶Æc»;l=ï‚LjŸ÷ì{²x?-,á %|¡‹+ ¸cóÎxGM¨é5-¡¤3Ô4ȶkÚe‡d 9ïØ#g8æ$…04àà!8Êå :¢Ä§ËÕ“+ é|0 endstream endobj 4825 0 obj << /Length 484 /Filter /FlateDecode >> stream xÚ…ÔÍjÜ0p ºø¬hvm($'Cš@öhO=”žšIHÏö£¹§¼†ß :ú`4ý4²ÖY‡vù¡Ñx,©Þ×g_ÍÞÔ{ó¥1©›½¹«õ“>¯ÑŒŽ¦‘Î?úò w?Íy­w7Ü¡w‡[óòü÷^ï.¿3h¾2¿0í·>\¥TA#þñSDÿÖ7š3f N*·¾ŸG03&õ…å¡3ÆŒ%XÒ€[-Gj§ìf°tLâ(9uÃxU„a¼xæÔ+¿¤EXÏÊ“…èa< ° Ì™³g¶f¨Þq D°Ýdµ"²\s>a±¦Û$0gö‰CâÙùJ†‰I0]"E¶qž§$„ÂÆÈž1{¢8º _[Énæ@*ïŸAÅír œ% ~Ž8Èr®LóŠ4O»$ùH™×¯³EÆw)‡f›ÞdZJ™§ ר TP:®íÂ*•¹L,óÄ,qùÀóx‹í&«è–|>'-T°ßdÜ8nÅñ”³ŠG0VG0–˜é– Dé ’|ÜÌÓ†¢J¾_ôæ$1E¯~ß ôÏæÛ/J35œP&$èd!ú,ÛH1U܇SØ«6܉™l¸Qî<úú èÿïï¶ endstream endobj 4826 0 obj << /Length 356 /Filter /FlateDecode >> stream xÚµ“±NÄ0 †Suˆ”%¿´UÜM‘ŽC¢L è&`dÁJ»ñZÝx¼7v¨0±“ö‚ÝDë«“Øþÿ(Ëê°>‚Žá ‚e 'K¸«Ô£ZÔ>YÂ"®Ü>¨U£ŠkXÔª8÷iU4ðüôr¯ŠÕå)TªXÃMåF5kBìEørÄψqJ{Âí´Ž82jtþÑøL6[GåaÛÑ&>GQâÀ8P*‘Q̸ÇŒ«åœ@츕I±ÿ-µÛ‹¡‘¡I9ÆcÆ«‹H‹YrTAâr ÈÎEñdm´§]ùιsGóí%e8ÚÝ„mŠÑIéÄ»?ÑîÃööÁ‹©[DºþsF]¾ã {CÚôa°Ìë6½$^½mçC—Þ#$£œùRœàcø±X:-qwH•%Û!Ã@B¨³F]©/À¾jé endstream endobj 4827 0 obj << /Length 332 /Filter /FlateDecode >> stream xÚí“ÍJÄ0ÇSr(ä’Gè¼€6YX¡§Âº‚=zò ž\=ï¾à«ôMì#ôX±dÌ$C·+=èâAÁ’_“ÎG2ÿ±ÆÎÁÀ,G`gVVݫ½vfãÞÍZT*¿„¨ü”ÖU^ÁãÃÓ­ÊçÇà¿—peÁ\«j Bb'øAüëg#Öÿü«8Ávà q`_̆Yzgd.»±Žìç,h|sB¤Á«ÆwLcoHKè"7A"‘7~*iÔÑuIN™³È.†lhàTÚá,éwËî'9!דŒßbAÇØŸë?È{Ÿ÷kw;]¹ÃÓ5k`̬™~¤%5Ö|Öë0hòu³ÕêK½ÕðsK©Em§‡Ú%=‡ºH¦uäu+¹wB«q"­7Œ½!tCw~º¦ÜЫi\V'•ºPÖÏ endstream endobj 4828 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚÍ’±NÄ0 †Se¨ä¥P¿ôÊлN•ŽC¢L ˆ @07ÖGÉ#tÌPÕØN{¸+^ú9±ÿ4ñ¿+/¯pƒ^”¸­p[ãk PÕ¼¸ÁݼóòûŠG¬j(nyŠö¿>¿ß Øß_c ÅŸJÜ> stream xÚ’=NÄ0…¹ˆäÆGÈ\ò#ABeiY$R AE¶J ´ë=Ú%GH¹EäÁ3v¼ˆR„¥$Ÿ=ãycçuÍù%Tpg5´´WðR«wÕ6~±‚.FžßÔªWå#´*oý²*û;øüøzUåêþjU®á©†j£ú5!2œqÏ€ˆúæ\Œ î몛^=¨oaf+š endstream endobj 4830 0 obj << /Length 443 /Filter /FlateDecode >> stream xÚ½“½JÄ@Çw¹"°MÞàn_@sá<¼1pžà‚Vb¥–ŠvBâ›åQîR¦;ÎÇf7bD°p “_f?gþ“u~¸XÚ¹]Ú|¯ÖöxmrólV ŒÎmžù±û'³Ù™ìÆ®&» “í.íëËÛ£É6Wg67ÙÖÞæv~gv[«¼%-ùj¥ ‡¤9Ô @…Cˆ ~ã,pº¢Eœ@ƒåìU‚Ï :¯ç'ÐhŽ(œ´',9Z::¥%ÆNáfè¹²Ò‚NMq#]æ ÒKÂÄcõ¦ëÿÆ_o6Èb<ÍP)Œw¡f´X*IèëKè«.²’5ëÌzTmx>Ú”Õd7JÜgL]é;“"^7îJ9Ž7*è[º’:U•šÊYG9ýMƒÞº×UfóLs¾3׿.vÞ‘ endstream endobj 4831 0 obj << /Length 250 /Filter /FlateDecode >> stream xÚíÓ±nÂ0P#H·är?Ž!–`²Tj†JeêP1µŒ ˜É§åSøF†(×»#)b£[œÈo°}gKw! 'cÌp0ÅÁ8Ç|„~äñÛÃB†òùºÕ¯ Ì p2p¯²®xÃýî°7{Ÿ£·ÀOÙ ŠÉIf/ʱV¨‘¹G$X¢òFŸ¨ú÷ÇÛ˜m†._›½½Ëÿ©¼(!zyt¥¯½r|òäAìYIj%m”HBÉ?—T‡×/æF{L©«”–.¡Og†[ôdbÃåZ™´6‘ã%¤­É½Ëû¥~y£Ô¯Þ+^»Ö’ô)¼°„i endstream endobj 4832 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚíÓ±JÄ@à„+Ûì#dŸÀ$Þ!¹*pž` A+ ±RK Eë|±_ä:Û”'„ü&3;;'Vr… /›ðÏì„,OŽs—»Åx-ç®8ÎÝ}ažLYŽ9ÝOîͪ6Ùµ+K“OÛ&«/ÜËóëƒÉV—§®0ÙÚÝ.¿5õÚE1v/àPF2UÚþ“ñët1ªFyZ„IhwiXmÑ c„Îfƒ6ÙR“²˜Õ6°i…œEä,"g9‹ÈYDÎ"6›@„™Í¨[b‚ð‚U¦ 4f£”ÿÁâvðƒRNå;à‰7på‘1àçÐGcëðƒêä÷›X)SôÊAh• °ÇÖs¦Œ¹ Ï­§¯Llö¹Vè…é>¡„‰’+ 7ž±’/ì„Tù§ió +Èú=ÍYm®ÌÏØ: endstream endobj 4833 0 obj << /Length 201 /Filter /FlateDecode >> stream xÚíÒ? ÂP ðH!‹GhNàkQZÿ€ÄI]mæQz„'v(ý|¯UÐMÁÑáã—’)a«ÙêŠ'm“ +aGÖ>ï8°½g[[¬¶ÜXÍ%h³›)«h"‡ýqê?ˆÏj( _¼%GC!š\M€1.Jk@b­©µabuÓ8³öäCŸj(ȅέ èÌŒýî5}x~÷–<­öoT "s¿4ÎŒ‘›V:TI¯æ_šýý@ù9Ë£ˆg|(4 endstream endobj 4834 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚíÒ± Â0€á”…[ú½ÐäZœ UÁ‚N⤎Š®ÚGóQ|Ç¥±IEEP\¼åƒ þˆš*D…-l¶ IupA°†0ª¶ ‰øl¾‚$9Á090{é·›Ýd2ê"ìá”PÍ í¡¢õ|¨ó¦î ½úÆìÕ÷:¬ËzlÀƬ®õµ™Bè7½¾÷÷ ƒì7ÆYÝElú(ŸÝ›~ôÍÒ†’Ùä:srëÑÍmH'ïlÃÊý“ý˜ÖGž¹a/–\^ÎeVÇÐOa 0«   endstream endobj 4835 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚíÓ½ Â0ð„ [ú½Ð6ƒÖN?À‚N⤎ŠN ¾˜à‹¾€àâ ž×3â âj w?.$dù»Ø•+cKÓ&5;˜Aêxc’>NFS¨çõ1uµy QÞÁÅ|9¨Þm O›8à;CÈ›¨ ]/ºñ¦Âýjµ–7Cq(¶â@lþþûKÛ/|pøf+Î>x%6tåz~Y?¬ ›£7W»'’4q ¶D; ÃFe†óq(ž>é›wÈíêm¹¼5·w(õ´æIZ¡•Cî‡o| endstream endobj 4839 0 obj << /Length1 3011 /Length2 21311 /Length3 0 /Length 22805 /Filter /FlateDecode >> stream xÚœ·tÝÛú.»±¹bÛ¶m·ÑŠm6vƒÆh¬ÆFcÛ¶š¤±Ú¨Ñ]ÝûœÝžs¿ÿ½ß¸#c$¿ç/žùbÎJRuFQ3 ”ƒ½+#+ @ÖÞÔÁÞÅÁÖØÕØÛŠƒQ háfkì ­±r"PRjX¹Úÿ'-J- ³‹•ƒ=ß?úâÎ@cWDÂØd¦á({X9¬Ü|l\| 6VÞ+:8ó­L-¶uKcgG ¥¸ƒ£—³•…¥+àŸO)-È…‹dÍÆP3v´(Ý­€öÿa@cnåìâjold²5þûCÄÂÎØÊ–ÉÔÁŽ–ásÈÊú·ÃÿŒê¢f Òøë/“ƒ³Åÿ—%;ã/S®Óÿo@cçòׇˆ›©‹ÐÌ–é?Ô¬Lö.@3€›½Ð .«0Õ`û·¤ ÚA©4˜x~M Dø+>7 7; €ÆÒÕÕ‘™ù—ù¯%&s&{ +3-(Å’öfâvv@{WV€™•©+ÀhaeÀüË•†ˆ#+À hþ7V4vu¶òè³0±°°X~ýüóeJ…™ƒ½­×ou%PrÌÚ2’êJzôÿCý£,&æà ða0²rs8Yx<윿ÿtªblõ/R,¿ eíÍÿ&oææøï ¸ÿÝxš¿🮔\A9Ðü®š '‹)èëÿÐF)üŸºç—íŸmð§Ã·Ñ¿[篵ºçÿhù_môïÖù¥óßÝóË„ÉçÿÖ7¿tþ+#”ÿ¿féÿy~þßfæÿ8'ÿ÷é`–r³µý« iþh?¨ÿœÿjÀÿî )c;+[¯ÿÍdòßšÚÀ¿‰ÿOŽÔÿlTYWc+Q{ ÛDV.RVž@3+WSK€¹±­ ðo¹æ¯ÍØZÙU\¬~” ‘àdù¯5 K+S{ ‹ à_K@{³ÿ" bofeo`ãä;;{!°€†™“àà °yò=A±™™ì\A&G7W?P~M'€Yô—èoÄ`û¸Ìâ¿€Yâ7â0Kþƒ¸YÌR¿+€Yú7b0ËüFìfÙ߈À,÷¸ÈÿF . ¿ˆ‹âoâ¢ô¸(ÿƒx@\T~#Ptµß]ý7E×ø@Ñ5#Pt­ß]û7E×ù@ÑuÿA¼ èz¿ÈÎø7Å3v1µ²2µr6u³ûGÎÊÆõ¯W+[3à?r¶_bW ³•‹ÍïÄÿrâúÛ'ˆ‹Éž@«& óö·´cgcS -ÐÜõ1ç¿Äå?ÞXÿÛ]ÿCŸ—ýù€6oúâ‘1u°õò?[àø%±³ûVP†Ìþì ­›9ØÚþÉtÕ0ÿÎ×/ää:T~+€cþ;*ˆœ¹•ûo Î_Ënz©XüöZ·øõêþ©bjù›7(?–^Ž–@û?4@2«? ˆ¹õTj›? (¿sölûkŒ¯ƒ÷G€.6æß¡8A¾ìAãÿ;K Ðönv&¿î:‹?(±‚rãð›4ȧÃV¬¬ :þ^Åp4vÚÿGi9Xÿ%ýϲƒ(8A'ìª\ɬ~—”XG[·?6Æ ’8ýÞø/ätùë€ûÇ7Ç/¡è1còGQA/Bæ?êÁ Úòo·œ¿Ðýrp‚Ô]@¯”˜€»€î*Ë?\€øþfºf™]-ô (!®€|¸ýîmPÌ¿®Sç?³ *­û”u?& äÔóŠêõUÄû7g'o óß þãX7us•Äõ¯ÇèÌÿ76·],@ 'ÐaeÑÁ”?ĺ.¤ý¾F”Àƒq’Ëþ»Ÿ ùw÷œ÷ mX«±‰GÄ!s6EE5|R Z ghÃOîÝ5õXþViž»gËÉhc;Ð'bÏî,Y¥Äç‡ïðÏÒfA¡høØñýUT<ÝFø~í1Œ¢£”³†ŠË TÁ £K©‚qxˆFßï²è×wh±Íº¡]ñ“ázpä0î\‘P™˜5‡bÉ–=‘v>túð#âÙoD"H®ˆaœ3• QFÒrq@‘yuH@¶ÜòQŸwÕå "þZPM6yfZ©>ôW‰Éçï¬ÁЭC]*@—¬¤ý྾û–×È?DÛÓèßÈ#'ö‚ßf¦b©® `NëöS˜˜R&ØŠ‹w²†«á%œ‘D)ï÷¢zéŠõ‘âDñQe’íØf>OúàÊf™egb‘r &¥I]ÎIÉ…É&[•à艗·µûié öW-—©ÕS þ4Dõ4O¶å.‚î`H©ŸŸ§×²™ cz†hJ70ÆÁ/Å N [EÚ‡Ô±÷ª4U‚2šû ÈjýÓØ^’4~;pç8§§ ~~œ.oA–°[¾kZü ëD…ì‘o­^và*Ý›}n~Øí+æyøå€ÏÓ‰ùI(ªh3L¨PyMö»8ïqM¸^Äh%ÞJ_Ø7` –pd®8'¼ß“S†&30Úrޏ+®ïw¢(Òü)dŒ@àOSãrï&¿CG{›˜äÔ”¶VSÄ··ùl|ÉðÝ Õ#ÊO¤Yò½Ë±ïÛŒ³÷éNòÖn$Sôd‰·¹È+€¬ž™©ÊÈg$d=ð·×P¶ÒŽ æÍJ¢àW?Hr¶Çyó#KL¿Ëðœìò÷Ø0÷X¦òñ:}Sg_Âá"Âl´^~2#*læ¯é~÷Ïåÿf¾¦ÈÏY¿{4±ê¤Ø{œ"R/9SMß5IC1‡ÏzißtÔ~‹™(Ðã&Ý»˜¾Ž›è€AúˆûMËò}¾nIE£n¬:.ŽÀÙ·÷gSª8õÙ#j[)ð¸ªlh¬ŒR9íÓ7éè¢xræˆzåbºî×êaa­´ìáÙ•ôÙsµj—<7'èlóBŒUbßVܳH`ñÐÂ;b°aIý˜Ðz)ŠÈ–¢—c¶‹¯5YYüsû&>îFÅ$£øÞ¶%¿ähŒçžÃ¿´ô†ÆÅñXi](^§…Ü~K§×=næª}½UzÐmäȃã2ãÌmá¬Pƒ.t~Nž§Îd8#«¸Óþì2r§sbtFzìý~¨Jœc™ë…*"ýõ2œ TÞo ý.'%z?>‘ÈÎæ)M#Ç…NÈ¥Îñ!óÖ€ã½ô©&ו֋u/ºü»çúÌÍ7ý·Í‡ùº$Jþæ$vP‡53í=)O(ÇWsDIŽÛ kS§ì¾_gôÂgй|«òÆi×ó¦„uÌvvë?CÐëÀú5Ù‹t }äÖ,Ckƒœ |ÌE¸B–Åï©A-ºéSæ8œËaÙFC:îÝ +OO¸>o²-öPÇ^¡½síôjDôf´uEŽ=¸#Io;Jq޼֫ï avYYÇ ag{~}áaAj_¹D %ñ„ Â] 9ë³\³< ?`®>}ñ%™éøÆ6À54Öô1 ‘ •vúІŒO⓹š¹ue;ó»"eéû:héü’Þmm$]ìëãôÜYc(~ÀÎ*Nsz´¤¦;'ÆtÖåèvHâÆ­ˆ¬µ¡ŸÜQfQòpЧÚVVz|Ý‚˜åÎì7sá妇È{1ˆ¦ ÓBz4TO<œÝ;3ÖJ7è5::_ßx•rêà/vèzŒÝbHßÀH+9–4¨iÖ-©„Yy6V\'øg2YÞ¤Jº¾GÔš¼° {¡qQÒó^­ÅZ²®Ò]QÙÿ4æq4?ø¡Ûв|iášä–.ŠÔé{ŠNî>Ö'Ì0ë ú2cÿýèg s22ár΂Ep.ž„Í©Ó/O³’\/m8`°d©ß8/«Ieç2R,.Á_§ãáyGg&NÞ­Xïmkô!¤Ùµ}æÕï}½î5¢Ûï_WÆ4}ïtB[ÇŒÈDü™y§9Dð:Aóí´…žp:¥ðJµ ‘c¨6oékñ[íWEºzç tæ×!‰Ê ¨2¥2Oåi'[’]¡[¤ôFða]7ý})zì}]Å`]möPÎßÃÃçN±ê*³˜d^38ˆ&"epô8²{â¹`_}=±¡nÚáøtõaÌf°‰ T‚á=ú$õ‰P[ä)Üúnl'¯}½"vdgÚñ©‹ÿyÉÂê£<Ìr#ªmZŸŠ.Šmç‘Û¿4’}"Â|²< ^Y,."Y‘›Ïì(qY¡.Ôò,™³c;ÃüÕ±øàzÛ_2ñY Ow<Ö¿¡kñ€«‚üÈ›¡”ê_À©‰:ý#ƒ¬×*m‰w¬&«iBœz‡o„öFÔmë¶¿öa‡!y TJɸb@ÙšÃ77…´¤=÷VÈ/çÔ †g—ÝUÃÎæ†þ8-6 6&ÝV4SÃm"Æ£ˆ©»\ú0| ¯ÍïiQD ¢ãÆÛNéÕ º¾ ØCcØ3¬E:Øñ·i¹¦ÐB$‹¾í«Ø-l®6°£Ë|¼Öa ï‹_[j"múá B]•èHë^ñ9­0È•<…/ó!˜‰ÿÙ}|"ÂÙŒ§¼‡5Ú@<×Ý{½ëœïXÑŸ«Iò8lû©¤R ¾+òÇ <]Ь{‚ëRëWÑi…6 †ø°9M™ôƒÕÛT϶'ÌŽÁ¦ÖŠzó¤9V¶š-®Ï˜~sû ÕÛ}HbyÖâ`Àk?>ÎMwGp×ò@„kç¡J3 Ô¥PM1m›]4ÝŠ¬ëèúôö­{QwcŽ€pHâ.‘ÝÐ{*ÙÐÄá¶s¢š>O‰:9 >ÙÀOf·UlÅxwˆ3ð)°£þ—§Œ]Ìú‹þã¤`±J?_j*d<Î{%íÝ£†Ùk‹gF¶r/VÞïû« n·îk|É}2š‚ý±%/0E,×%jLzþÈE¢Q»œ#»cÌ>Î¬ÌØp—хqWÚo û`~¦5~¯y:¶xOœï©Ü"ü!ã+æ¥;ÊTŠlú“*ÜLq³üW+”x|‡wÆvŽ¥r»[ò|ÛhiàéЛúc.C52ãqQGv"'æúÔ”föW_èËN%:Ë[h•9µŽOZiÈw&Yi`ÒÝa]‘DÆÑl>\í¹ýxgÇÑh‚[¡CÑÃ_}%vÛ36ú^ fYyòí†.zÞ;ÛyDø ^æ¯xŠLZœ­áÇŒ8€v51þÇÜÓˆz glÎÊ©s Û|‘Ltú…¬þ(À:C‡(³ßÔÛñàp—‹ËaÏÓ&7SÙ§…É•2 çvìMdûBÜ Õ|lD¾&Ž4ué*Ùkdï­êÌÕ‹/wcúÌ5½òµhaÝv}Úg´¹‘DWޝ3=ëÑ2‡¯\¸gzlBðrÖÙV±ÂNæ_¹Óª¹t0ž0™ù6¹ßIÔìïìÒm“?ÉÁ¹ÏÎÖõ1È*«L¶*ÆÕ*å ‘yú§ÖÏ=-ã í)pXK¿Q Š8c:Ÿëô­¼f<CÁ WR" ³P“ ¬ÃG}%Ñ(SÛ܃}W—®hÏyY‚“¡Õý`÷¶ 7Ÿê G# µílòʪ<‘ ½S÷°ÿX^º +Ëå8åå:hÀ ÔZW‘zU{h§è¦Îa8Å6ôÜRI%ݾý¯#÷FK ¡ä—¿c¤ÉÙ «>ï7¸¿)‡TÚòÚ¸Â{FW^šH-×¢Mnˆ4ÛýQFd…No»ÏøtÏŒ¿QZÎs­ná±Ý™KeœMÜæ´ˆ­zE ñ´Ëþ™1á9®sãíðG·7ŽŸ¨$à µæzrãÃÙ-—BëÜbfjºÎ®û×o‰ñÍw ÷ —öÕTèêCÓEl[W„ãýXB† Åd,PÛopÇòŽáÌndØ;ëy,’èqôá²e-V'o¶óIýŸâ0ÝããMFy_Ñ‹{½<Õïe ©‹Â!8¾Znö·,l¹hÝM/³ÏbÈ¿DÏÔ™Ó5ê9vªÕ°Sà‰»å|8 Îß ¬eà¯óšâÆOÊi¶ Ã$QO®üT6ÜÔíÛr …Ij\∖p«£öd¸Z«ˆ7Þ-NFÌÉ|ˆ]ûØadÇtT½›uºÙP¶¶T<¿ ofºó½é­×+>îdª½ ¿Ï§+¡ðî9ÔÇzl.ò¬}w­=(®åÀDZkHÉùé,ÿ$5·19©^a­Ÿb7·e­·N5 aÃ"!ª®º¶ö$ÙÞB´•‰ÅÊ„ÂGY_.ߦ_à$à’Zà*n |¡š'œÒÿb@¬"ƨ®62@¬h^­»º°(+éÃä¶1 YK/§w7oQ§å~¼ÿtû³¡™ð¢=pž¯¹) >-ÑŸÖ·Å”†¶Ê¥Gm *\°XüƒÕÀ§¼ð Ðùf}ß { -Zƒ¿Å±¸&ßWx;™!„kùûcαÅôJˆX·{û] ×Q*?J4ÃÅÁ5ã>& œÉl“òÓ™P @(¼­×ÙÔʱjû f/ëi»Ëš%þb޼4 •ÂÈÕøoü’wQ=“úESûÒ…¸·Wdy‹Ê ”T}jîtPó­X…òµÏyÙ·žRñÂÒ@åÊ Ä8 â—¥³‚ÎW ênŽ)pš-éÏõÎʸaIÂ,4s ïò¿ãE[ü€ED¼ë–½q±;nØ4ê jäödŠá® † qÿ¬š09Ùã—>%q_µÕ„Ëø¾ò–—Þ—âëá©™ù7×ýñržû-îµrÃqm¦ôÇ{é¯ðl§‘KU¬=jîºíR´Û”5àC9—?bpÙy¤éâð“Jñ£•¹îEù“œNH…Ûhp[s K2[<4¼U<3LyïæìªwLƒdRÖü¾]l?4&…R)«›™säqe½Mv|(ðSaS!Ìz†;¶÷Ù*´K fˆ9›‚`ÂÄ7Ü—uиðS+²éõ Ä &É™ÀÀ‡k@àk݉ªÞ!)–ÎêfɈŠàNÅÕ”‰mÔÈS bËI.—…ËOá¿«!z‡kC‹0¬Å4\ü=œ÷Ôþk,ö›Qæi±{Òñ©y"â~ù}Û¶åÅšŸâ¨£*W-ï´-l·³Ÿ”Ȳ¤8eÊ%" BlIn<ãôðèV ž—I¼™{Ä5ÞBðè/î`—+¨.G7À(UÝ.ì"\¨ëÖ­¶xyç^ 1å”gŒ…7o£èo6y£8¶/hôòi¦Ä¶É›ˆW G¾HAS¸ÁŸZ±[¥‘ãnb12GKECm­’ÛÅ(ùÈ` 뮂ïY{U–'ù¹“ð¬Ld›Æµ™½STºeê²Ýšq½ô8Ÿ÷ïèäha¢í2‡q•ôvü¢×J`÷ŽpŠ™—¥²JM¶~atO Ò—Z>åA\ëí­Oô£º3µ·Õ©P€J©3Ï}õ··Ìªì9•Úîc÷êfßT•%Î-0ýCмdú?;-ÓQÜ‚«Šà,biÛvÙ¦u@¼ãd¥XN£ìŽåGúfI‚üáè51[ßh.—VãÅ.«—¬láà÷Söž ¸Žôgëµå…š5‘þ÷Žé ÉÂ}ifíÔcy´d®³É`X×Çã%‰ß">P; y~ŸÈyÚXÒ™7OÌ _*ñ:Äúx6ŸO¿˜luÔ†yÚù×ͳC}ŒÞ®1þ<¾TÜCÙÃs3„óTÃ^.ãÄð•©‚ÍK_2h\3±„1ûÜGç¨{¸‚ |¾µ€§³BO誀Ï-¶ ã "¬s{À0ËñX’éX‡¯ûy²Súg°ˆ&#ºé¤ÆR^õÍsÀ¼VD“Ý¥0LÜö%1lŠÇ†Òí`ƒF¼¸Ì§‡ôÍ9UêUª©¾ª»›§Þ¨…ä€dBó';ŠÜ%úÚ’[ç7=Ø´`WzNPï²Àï/ÊÒž·GéXj|w„xº5 ®“«j"×ÈÆòggC.Ó¨VïU<®ÖÕÄh[,²ƒV2oY&R]¢Âß2}‚vò ’¤Û3íÙ†âØ0„Ï·‡ú·E¬_X ‘NBUvþPÚz@i/kNÈÉ¥ûþ¢N°O ž€áá‚2•ûÚ¾hf…¦Ž,œD£¦ÙuŒ$ñžÏŸÐq L©*R“³Ùý¶è£)Àèå’k$`1C} :³Áq޵†ê#±Q¹šÈ|wg ÖFÂ¥¥muºðú6šAFºÂ±g²‚±$_½½=›ÞYEVÐ?vÚWX¾VÛŒ÷§žQ;7PHí­ì«ƒGLtÅž)Åa ,NɾlȆÑW@3Cñ6e(8ãÀ(‹"y^Ç ãà0®tY4Mæ,¤J ÞäÔxÞ\ÏôK”rµz×Ã3{@>£C XMU¨²ýÂgAúŠÄ Äö#q,wÈ®À{[ΊY–À÷ÞÜ»:hu¯á>3Òãæa‡Ç©Ü]YáA”Œ9tQå·‡´éd†ÈÎelY]—Ã#ªvº¿´ÉÜÚL^wgcv±’žYDdÅØ¸¹ýKÆ—?SGŽV܇¬è„(k¨ šâÒ=dÉE ï¶³% ¹‘íî)Ñg3Ü»zÚ=>Ìát®Ã/ô¶Y; é®ÞˆÊ7é*PüÔfÖi¨§#o>¢Zòø0ÿÂÚis*l­Û·ỷ¬™ìè»çÈÍÛ«½Ã5’ŒóilþÍüèî±±–žQvhäÄM¾«jÓFŒ1f1d´œUyqªœš® uü{'†ûáP¢d8ÆIƒqÜÙÓœeß›ŽÒ Ô×ó š«Rm_rÑHa!Š+]Ô&ìþyŒuýÎ7å“'¶³ZrÑD["•»Øúβ÷ùÙ /¬«Ã\õ‰L¢ø¡],Ö»½,iÜ¢,ôÂzç¡–HàÀeÝl£ËúTq8Ãþ*zEm=˜mÁx÷.^Gcž:µÍfÊ;¦Ï·póä–æ<ºü,ý¾Örmáw¢1¥{ºƒäe·¬Y“שX Ú’cwå¯rÖýY&‘>ÔQ]u%&{bêw( °÷âŒqì W&ÝÀ'Í@Ö¡¤¤ ¿õ§ÐèÁgµ|ÞÉtzÒ¦Êþ„ìÃhÚ‚I´wè',ÛžËËAÜ>…#¿pGÌÔyUm\µ†\X¸™ýBîƒð ë·áÄ¡û„rFo÷Rñ¼›`¬ÁˆÊÍ·¡Jô“e7Ù3D-\BóáZ/ýOûï7Žë,efLØìwëP^ßrÄX[áwU¨å­ƒã¹7Pbÿ¨ÜCL,E1þfñNÐ}8ôõÜ"ë›…ë6I"ö6à°±ji€1ï=GâÈñÃ|º—’éçHAã\ˆ€¯ö‚¾è³u)J.}kÅcüf­¥Hz‰*ÁÞ÷ë@v ª1e·Åá:¦Ú~jY¾ƒà ¬-ÅÀй—êk8%jâš±všõ"KáAÏ„Ôþ25Có¶m'8¹Òv"$1 cˆüx7dÚ׬Iª”Òu¯0º·0½GŸ;t=‚ªj¹ý5VªÍø½ú°Y¯ÈžÑÏ zÓ6?®5vö ¾2s²Ý»Â–ò4[jÁÀÞºÝq+6-!Æ¿"ࣧ&×tGÝçUøöx ŸŒs/^Oã%‹Úˆ"}yÏeŒÍÃ,7éÐ8R›äúÔ0i„ÿ nFÄJËV.”w#EY|Ô‰6ëè| a=ÿo®Ø'þ¥G™ÃPcþ­óš¥ò@껈£ò;ËSü£ðSƒ½±$Ži²6—®¥vx äâù™O‹7µ¶hˉŸî<õŸ)MHç;Z¶|>¤©”¶$ÜO©aWŽ‘~–½öM—Ú¸h‚KΑÍ>›ºö˜Îô9^ý)`¢Õä¾6“ÙWþ_㺬+ ¢P0s·îÓíco)¯[ºz ÆH»•ÙoM++¢s°×Éè‚ÆC)=K¾¼É˜î@0!­ب5•Dì”p䡹«HÈédNâp2÷Ž1¦®ØÙX•š„y\  ÖbëTˆ†~üë!_9çH³@wƧGæLá9?Ž®fß‚R,è[§ÏçØÄP2ÓwÕ‘‹æ¬õE{‘‡Þí\ÅåÜÐc¯–»Lr V £2%z&™ª;{Óh ,¥Å]ù¸°@?RbÖÎo’Ïô0£ç=¨MJ4+©šg‰`vƒEl,8üîù>;T}3«hÜW}§ÃW™Ï†Ž®i³ÌÃzÌÌøVm]ðØóó©YS]Ù¯ûÔKJX’ÂB<~NŠbXŠFÑÍ/t¾ÿË ©\Tþò b~¿„6ì(QÙ+¬mæ´‡zæ÷P×2‘ù³¯bÞrI|ã¶}ÚL=TÒ®Œ6dI¯àíI´c•a×뾺¿¸Þ÷¡*š¦°1p1òmbY Ég'ì‚ÕøBl+ŒyáÌû®UšK6ǬÌ•*|—5=Э1Ì`=Õ7lª.$%[áH ›$^°tÝóÞÏæ‘}0Qö#a€‘Qä;É4›^‰½2ŠþÄÍÝnyã&†-ßBE Iý·± &íÑIîK«'y2ø¥Àüc–u}‰™=RŸ!‡ïÖ~HhÕ?žqâEÚN®oMÑè&F>Ÿ¥ël±'>ÐëD ¯…§v[ ¦íþ`VAP+OÅò•F)àY®öódëZ±®&~L«–|žX˜ãQæ_ûÀ–•Õ¸Úáùb5Q‚ ¬ÞG× á~ò÷ŒC¯emsÒ”´_  J“zõÄ$ÁžÞ%ŽNªùHF8‘„ˆ0)Gˆ® £¼{Ïvw¾wÑ·P®Mús=º'[q䊥‡úH°ÎcX¹~ÖÿÃë` gFX•p˘Ôqô–tbË“fGwà:ÔLD¸”#Úýr1u´‡§;]Œ™KxBbæ÷–æþ¡â»Ô+¡ïÐYÁÚSÁ±¡ðÅ/(ô”`*ü‹ËðïOE®c‹\å¸!è^lB®^ï…5À¢»Oc2ãŒE>pSœ|ö}>c×ÐR†W츺¶N¦¦8œ`²Q¤‚k©z÷‚m†x¨d”Œ$I2HxÒC-õªœ6åî"‘°Þ ø0…[w…E<­ÆÅ”§ÖG±V¾¶¸6í7!Т :˃Hrj‚ýðº\=_“8&3{Ó¬ "ã¸GÔðEÌѹÍ*,J»1Xše'[j~xðü…»ŒD¿'s¬cyA•‚ØA™ZHZô¼Ä­Ùés®®5›‡çŦzñsúeÞAGÀ£îWˆiV7eû³hðG赪ÒºoD)Y |I‡5ÂFp³HŸY’Xh•dø†Ç"ˆsÛŽ/yvBpŒæ´²ßnëµMë:cváµ*7šþhÂé¢=9€ÓòKWÞý¸¿‹ú*?2êå½PèliÏýaWýÊ\ÙJ’uh‡¼†š4£Ó­Ó8Püi¾ù)Bá[æG-Z —k”ó1"XPþ‰ŒâÖ©Eé²`6df4;}Ê^¦œ:õS­Ù5&ôCÜ~ëìngB–b ÏO˜ÉÀÝää1ªý$uÔ€•u×v6»-/*ÙQ4/Ušº;™œúDÔ­Å#²ù/ËשqO}ð†§m3ù:9Ü6*;Í“ˆš†äI9µû0ýp–¤‚ñµç¯ ``×ß1 ·á‘%4ë™ÁXñ-× ïZ–®³?)øÉé´ÍǾzÓñækSkY—}I}r¥õ¥àÀ^.@ÜÖã2ƒ½eûÚp‘ëÙ¶„ZÝo8˜è?{å¶Çs1&0íù©‡ÚoxñEgO.b“0$ìrN{„f=z‰=ëU;bìæ W³%TB<ÔO˜ÿÌum3€)Ž/ Š*†¨ ìׯô{ÜɶÒèJoìóçõNA§ÀV.„)WÅ r/ÕЃÑï}møI­¶],ÝÛú¨„3ô%àTw¤É¬Î³ eqÔÐqäl!8W‡AC`q·~ö³-bMÞáôMèÓå_ÐØQ Í1D¹ß{Ëz!Á_†òq˜ò*g`–°¥ Èïåp¼>8O‹”p gPÐ7 ž(‡Ž`òÍ…&B­’Ÿ™æK"œíq?HŒipëAR¶%4ÞÙbŠ_˜wcï‘/ŽË¥G WîÒÉ|6ÀZ޾¼ŠêœKDÇËm…³ye|ѳw7¶WÜ‘­£&I:“¶äÆô˜1˜RõéவEÈÐ\T0u3œ#äÞ#a¡íuþ2£â;êÒ}ûR<“NßÞÝê Qˆ ›9(1§¡ð®ë®ëD8‹¢"Þy{ÐJIJoCÕ¯™T>&+ó'7‰ÇM \úi˜ÒÍWíàvCϨ¡kçç»ìkXYÓÇGÓ'$†*ž—^÷lm÷Ù-ìÛ¬y˜¬ ƒá½;öÊfuZÒ©—¹¦ba‹J߀òV¥ŠÍéqÇœú+á&?Y k’¹ˆÃµä™#)Ê?)¿[%9¸¡W…õÆÕÒÕ%qaª‚òCÛ±…–N÷ W«úœG1§’ß/Í ¶ùU}§7Bà•†SüÖƒó›.{蓇)Ø×²àÓZŒ3r„ô>¥kF@Òôqó*A3ÔFx׊悘 µ:Q Ñl-N|<ÃåKŸ˜p%… ·(r2—A¯ßåZžä-¯£NãÕÍ]@:y4·ÿ»“)~lðQëšÚ!º5ѹζ¥²1ü¨ª®5$ÎÖuÆÓ”é Ì‘#lE&êÎÆc¦°Ry§+ š9™çgµh%FJ!¿~)Eã +=Wo[M¦½å$X¸®Í4aøù©\ëܸqå$7^8)ƒäM*«gœ†ø¶d‰YNÉ&o.ÒCEÑ*c!ØÖßîWÙ ñ×V]8}aj‰…¢„†ª¡_ ïY7&jõVV»â'ƒ½Ï»I]…>ª°AúrÝ:\™«¢â¥¡2¡n¤"üTÖ,:6Ua¬1EŽx>–Fá§(v>¦Ù´oln‚ úöþö˜A­Îª¬Ö›®x#yÊ m;è[µ“&¦ä\jªüµaÑ}òµ©0~ìT®N’k¥`ïGaè3œàÆÛž™Ë~¹P†HÜ÷ ñFX9]?l8®IxŸñURR¶›ÐQXë+xœ_Á…ÚêÎ+Õp¹m,’QEÇlù…y©¡‰•ë…_ëõ–°ÚÞL´1r6â°Œ}Y2¿ÉeŸlE´÷<ä!n…vHŒ ããw'Û/aÖ­»¨£@õ™´9²œ?¡§ÔÇôo.“}ö¶‹%ÀF› ,Ääâ6^†,•LÓâØéi à÷ñú‚C¿ñ]Eû}Ü@ªÏ? NÆrŠ‘O¥Z'ÔÌø„ñ‡4)YR WŽ˜i¦†%܄זìAZ‹ŽÙÌóùꔚjãÄ@Lº¸7>+¼Ú(Fxb%½v^¿>”·ºµpk•4ÎRMѯ…ž—‰Bµ´Ç{!Û!›ï×  yoIœ‘¾Ýy†¦—}•šÔ{ÎCùºRbaë³µË3`8÷3Öf9«9]Ý!Ñ¡†5Òa†¦”Ãß5¨ýô%½ÌølvjvæJN@¡ÁÿCy3Z¥¬}0‚}9§n@Ö >º³¬íµà¶Š´±ºýXÎË/ŠZúòNCþ£W„6D>̳WëqÁ”~àʧ9ELæKÂ5Ú•±THÁ¸ °½`wA[ž¹œ`½œ1Ù‚CëÀ°–•ÞUá%Lhäbü‡JeF¯bô¤tàoËÃЩm«çæì7µÈGœ8æ:T¹Ä9H™êÙCU?p/¤+f(U,óñ¬\4Wü‰úàŒ>{¿˜aZ­{t5N6ë ÚÑâžEö-‚Çcûì‹éŸ<é@#G¥·P¶{½®~Än8;cnqŠ—˜ª¡ë"ƒ…¤~þñÐâá5Þ¡޾%¿#’€¼ –qÃOä õW¥¢¬#ï¬[üõêíYèþð|ŒàãˆPB)3¾¿‚~E®ù ‘rà°ûê¦ö‚ü=|ÄAYY¯Wä£Oé ¯œ3Ió·,²Ò3!#ת|qµ8bÇËj1Ñ%U¥ªe•¢/dlº–ü5"$ƒîCóÉL„Šœø¥÷‘]Ç…?–L/¼X0„.Ù }Zuàš‘o°õg£ˆI²ÏÛ»ª‘:ÜØN6£21eª/‘Y!ð±äïjì˜íiB¬Žmc‚v¶ ²VEg?oð?Â.åÁ’j}—¼Ùì½6YlSrøÔ&ÚYvN¢šQ,ìïîîg'?šêÑØ…¹Î»h¦À¡àWJB[Ø9-[ý~r@?©iër[¬žkÛŸúH<ûò+!Ê®%ò'Çqaq¢‡,ºQDŠxçÏïÉã!^7¦ïºß‹Ùgmæ}>Z~Hßv2œ~W]¹Ù&jr"²/SkŠ,3þ…áCì 1´§î2¿Ï·.òk*BƒòÖóÝS«­uk0€B²²ÃKòÕÕæÈ¥/MXd)HòãÆò¸‡ßÒ¥\.ÉF8€Â>n/|N˜YÐ<³NÞå=Âx.P¦C«Jx¡ª 0u€˜ÍÖ9œ–¬žÏûZ5ù©y³NwŸý¼ /aüâ&‰¨'´1 ô ÷«uÁà‡^3Îöò™ìp°d¼áM>.¢îÝ'H°YûsgŒ"õȬ;åkÙ½„B8KA×{EíR>&ô Á…CйñÝšPû!ÄSÖ„©$'ƒ+¶ Ú.£xÄ;ŒŒ·ë[¢4µhd>Ôªïò-^´WžIE¤«¸ö“v;²ÅÙ–õ¬Z \ü¾¾–¤ ùÆ#’UZö`}ápsË×/vâõ(õ}ÀÍÚa>˜;  ”Ì@Ò”ðÞD¡J‰fT†•ìÁYeï…|úåPËF®ÞWœ¬ªfêÅ%çbªÎ«ic¾}‚•à÷Æ3k ¦«W©”âè­øêO-FŒü<]^Í\çNœÃê¹Ò è «ÅI_ìëdýBÓž¸SEÇýñéØ8ªè½ÊLÇAþGF|&õ¹+.8OY”0µ`6ÿŒä'†0E«ºÄKÖ)+ý øQš™ýž`7A¥4ÿhù~–Wù†Èó¸ëìWZÚLÏÊçþÛb±d®ÞvMC§¥/-œ‚%ÕŸ7šÅåˆxfAY’ío“ñ% YdõcÿœnìJä»ë!1ÖÑ´Ü%ÞqõÐA€¬ÛDùS …löÔÞÉt)¦ …מÛ/hšƒ¥Ê³"uûÜEY‚FJR>?:›ãÄlº¦À°ZI‚¦B»ËÑìDæ‡ðeŽ¿Ã£¨³°ªC€9W®7Û;Qü2˜µº'»Ìð®ºÅêȧ˜¸Fûn±Ó“ û[³O‡<ûhŠ™ìטíâM"yð™dŸŽõ^ƒï%xž—nÚT™Õ&—è S ‰Áö¡ƒ|½5}i•fsìüíNEWüiº èV•«sYÆs×£ U}_wà"·i¬àö:qíg5ÏÓ×ÇVOHÈOèqÁ3g½¼CºŠõì®øéùêåË~¾ù`…|«jó³4³ð¶¯2ª³vZ!øƒ@°ðW¢ÕpË<¹äV©›û U•ßrÔkÄÄÀJœO5 ™¤€®ÿé°«íKŸ  »»""þ3k†h¼vànz^ç~ƒf'âË;e;TtÃÛ%F¶$åSKòwæD0è˃m°Í/¨%´#öÃR!O”î0 ã8ÄôhÆFûBT–ÓŠw¼‹è‘LJ“Ãr±Ìüˆœ«˜\ææf uV³x+S©ù{ÔÇ÷föA`¸6ïLD`¹v´ xp¥¸ù¨4\ƒrê#£”¾#‘2xwB_7za¸ ï$0ë½]?¬x}J417Ùù˜zÛ¬ÛØ™‚Ùö£¬ä=™œÆ}ý²‰àûƒœ=†µxV­¸ªÊÄÚZgäªgÄò·`,#¹‚ñw~¾o0~JP„Ù2÷ƒ}þò-üYÃ…ãZ°ýfáSGP,AjîKU´Œ œÙêkÐå zpU`Ÿ´ëËp›*|t·÷eüdÒ ¼C@CSÙýDÐØècT`CíÁ¬éVÃÒäz½•^…¿p«§ ª·"‰ÙÞžÙl— ¸ŽæR¦þĦ­?Q¸±½-χhNvÕ}B/ƒáé”ÈM¨GÖ¥-D™ âqÏ` Rÿc*!¼±´tP³.rôΰ6ïùlÓW„^]™Â­‰€+jÚW/dø˜COëeÖ¨‘©—|þX)^£M#»\n¼9¿i3iûü™ê.¿~k¾çÒüéf‘€Vj’p’'ÍǶʲB·¸Ä‹DéPK?´—¨O¥Ë;­ÜãpwÖõQ¯Ñ´…‹ |åo1?Ô\:2HkR.ëÙ¢Yd0í¸£ZWº-å ¯°Ô•½S”“;D¸5ïhš¥¨¹Ñ³lM] â ¥ÏøŒïzÐá0¾Áñ¬}!]Sà§¶¯¢Cytèl¬l53¶`Å…­¶i Û¥EéµÐ µŸù²€t?|Ðå˜8±¸ 4º?F­b ²Áh·„Á:3kñ¢X_HîͳTb/ž¾ `Æ {|ºx#øáƒk™RϺŒ.1»¼Ôî'û™Ì—é îÀc¹ÝE#æV Écäs>w­¦DñKQ•ùðóÇjq|­Í›F_æ©wiÅ]ï‡ ­p®¶B (ÀÖƒP~8ëë@’Î3ÅÚ{B0ù+íº¢hÅøFHpL8˜ÌfBßt|¨hå òèá†JJˆ)‚ê´j„ª¥RfÒRϯ‘÷©™ÐÎdÑA}?o‹´³qjܬ÷ û7a ¥ô`½q‘±íÏËáŒ#ž4-a;éÀW;‡ûgÕ²Ÿcä-9YŒ¹yš—r+sâ¾ï{Ë4–7Ø’y ËûZº}N¬‘òT"›Ä’c‡ûžwG&Æ”l©Ù7xb‘n5üékÍÍap溋ÿ¨v«‚œC@ïГ„2¡k 8ꦎ5ßêŸè`4Ûø>DÔV'Fq²¤Éw9-ÇÈ|Àéé%»õF\4\BU\,‡~N:5§K§”÷cÄó?vvÇ ³ sr4ÌøP mNÜŠê~8™¿”»átŸ–”=’ÂÀÖ‹øÎ¡¶º]Q§{Îàø ¿5G[88tã:_³ÔÝ ¸Y*w„iïŽâfø&ž3{÷-RU¶nÇ æÕY194†òH’úðÖÑQ)5ù9œÁt;¿‡$M›ä±›Dãݦ̧ˆÇl_|%ѽE‚&Õd‚ˆ-f9pÓ÷”ôX”¶|Ì=Q2oL•ù+Õ*Þõk=#Qw.Awª#Ökšò8^eÃ9Ås “žf¤µ!À« (Ød³‹÷Y¯|Ú¿ òdœÆÉ•"çº0ñ’6!̆ä, PZlªZV~ð*ò ½„ÛÉéµ,ï¿°‹¿ ´Vo¬Û*Ì¥·Ù§u*«²¶a¬= ú4¶v,‰Ú8âh=ŒöþVc›FNÒDS^±Só}lã9b´@ti;z›yÝ:\àlZs?Ms[¹Éý ,.|{(éñFXÜð".j¹mq[•è± "’nÞ¿f”$M)µv+`2ÊZìÞ\â{Q«ø{ˆžžTË;qƒ’Mw¼h§`8€¬ìÀ9¸š< ßËÑ÷‚÷ó ø(ÿ­“Ø{[:Ãsñþ½€OÌJK_tpy6U-Le¡mæûDêߨ`ÄÉÐ’ Ï~]F©kE^»¾½áßßz˜c(’Ö®~–ñ¦ØD_/­þ!È¥ö\ì¶µgnûñ¦a›3«_5Šzçú§tSšò½É›ùíÅÉÁ/CVä–a…N‹ß;² E…fƒ¥â\?¬~ŠôÿqQ1Ù³²ÞLÏSR>ÓgèŒãˆ+žäyôö¶tl!°ç]Ä>î':M02DáDõ×-ÊçS–ç*BÙhÕvºB%-ëC®½³¨½}…t‰lS n³Ž3è¶÷]+Ú׸T©ÏÖªôd…退ڟD‰{úõ¤qÅ8Ê|R<¥X^[!šÞù>–ó¥ñà/âªyž½tîïÈú&IåûëeЛމ¾;ô y 3 ·AX`ËTS§ïrB6¨µB§~?Uÿ$Åñà}ï‘:áBÛÖûÞäZ MÞ@ºÂGØjõ@1¿gô\A]ÚoÇúû•…Ÿû›…ÂFvyìSIQr~ÖäOŠ[(Ú#‹B¹yÌ ñÒ§é¿­z5sÄ™µØŒºf‰Kó¢9/rê=á =3ÆLi?Œx©5XYpií}OÎ%F}Ìv·Á3¬à-U´»â¼ãžM<¿ÕÖO„ª[Jb½5<ÏŠØöÈýsÞ„ƽ’]GW,ñஞ@³)7ž+V Ï}2S­Û‚w ´µ7ï»í£©™Ñm-•'?½Á~†tK„ÀýÂ06D4ü5¹Rº- LÉ+=&rjÖ „Í"d‰o…űE«u¸f!"MGïo•oßKwØÙZó«’õ²±J a{œ¯zÒlÄ"ß&äw¥ö‡#{µã™ÌO$ÅÏ)ì¼ö¬ ï­äiW+}DÐH–ÜþŽÿV‚F[¥pØ{˜©C—„dàÊ©r*JU/‘Œkܵ…š5ÐÞ®cÈÊ¥Ìc‚]2̈/H½öB\ÄzNó~–Å_ˆG.¯»(‘àüƒQ¬!äq”á”°B°ŒÂW®.9•Üaœ“7µ=µgÝœKPñÔR‚Ó¾ë†ÆçÛÊ'æîè³ -ç|=·›‚ í5`$oëÍ'ÑÊww¶¼7ƒl0N±`­¶ÓÐÓÜ®3¿ïŠ[—âªÈ“gI¾ËhýBC´ûþ–î!{xu´— j)2‘pW¯)?Ü¿ùòód ×-ùv d“×Ù0;Õ<4ü þ T˜Ùeu+S÷Ë$Ù#“$7œ§ôˆâo¸pc JT6x.Æ-¼3Fà*qˆˆ‰|È«½rÝ´”^äm÷”Æ2ék=æ3„¡Õ‚®îU&¤" ’Ö*„ÍÛ\ÂTQJ¥rFÀ£\±ð8„l‘ުÙzϬ#«0då»Ý ­¤zÛY5\÷Ð?(ŒÊÑxÁ2ù4žDû!?ÉÖǽ®¶‘²Ÿxõ{?«µ~[Æ‘¿eúhu5ÊvBÊ7)=[—eÓX7è«SïÞŒÒH¬f° /lú«ÆÇ$8,ÈÍ¡'fϲ>»ÓínId@š?È{È×+$L°¹IÙ3½£!&T|+z…¿îMG&£j :«ÑJŽÝ´‚ ýê¼=H˜r†:üzÁ3ÅšuÃEKØýt‹›èjKþ¥©‚‡5‰gÚåm½Î޵n ´Ê:„Òå¾R˼ ™²Hº¦øÄΪˆªŠÏ~ÕsÐÙ¨-0…S©?ª 1?Fõ›UÆW™¶¥lÜö“GQ°¥utaꣽZDÜ=!ÞÝ´ñÉ8à¨{‚™0“äö®S‹Ò¶«ñ,Qb¢!¹ó’Š¥›wVø¨s#ƒîpÊ×åQ2ߺ÷y»t:ð.ôÅVõ'?͆éäF9&h€ÅbÍòuæâ÷…U݉˜–Kkì™3¨/½ tBÇFŪ­’Ù3ÀˆÞ ³ ú”Èy̘ƘYÚŠ &ÂHI:vBöyÊ­íë;•Ìä ëŸ|×ög¸òÕrÆ93ßµÓ6ÄŒ&)‘ÎÅBœ¤Í›ç™¦¦T‚q¸³Gzâ¡_yá˜m;½¿vp 忹$c¸úZ8÷·ñøÉ¿ :xµš×RŸ±ÜJD7:œþÙú ËN¤Êž Ò®â(-M«1¢2Á‹'ßÌY6ê… ‰#;ó‘¦vÖRÈèû$â–]‘¥I2]ð‡F®)â|.$‹ÍîYmIâL1 Õ[QÎd:éÖ;5«^š+%Iç{ðØ zøæo<ÄPßô³{V/&Òܲçmëôñ¸?þWåè|ŽnÉh½ºLf¾ÅfFƒPh±y¤RÙÖ¯"qÖ”‚˜Ó:Æ2¹?7NË?,U%æüêæcX "Ê(8¸—Ká³7ÖOÜÆûœúèŒiñ0¬Âw”]´‡ íË©å ¨ ùìxfŒ ž"[Îî©Ó½£ ÚNj³%,T‰DñZ%ñù~oÉÙ/5¯ÜjHТ&Áqö^µä±,¸vØz4ôK鄱v ˆ•â^ïÈo_"3›·Šn-(ÐÔ`D¦ƒŸ*¸448°lrvcŽ%ôñ{;ÔdŠL‡r ÏˆLF¦<1`Z¡ j;ÙZ‹–íoKó¬"Üý¡z¹½.Ÿ-Ô\Ö:O~÷Fí2ñ.¾5ʘ>†Ë~$åek ¾)…ið ­BÚË L/²F²ÿ4S\‰Ã§ùOèkê¯ ®R‘iFM­|ÅHt·dİ]!ÕãðlMq\—Û³~µÞTšŠè|Ü{a&øy¸?øzxÂ;;õór£œf5§¢¹\¬®Ý¹Ãª4"Íà!“F&•é§æÓU#Þ'¾4ãvÿc½HuPC«_Îã¥Î(w5¬ÅçO€þŸ9û0p×:tÅÊþ ЍÙ?ɹQâ ÊiOVNv}Ür'÷c–ÝÛÂoÊÈŸR¦øIÔŸ´¡Tâ¬`q°vÂ`IÿŽÅݧ”»Xæzk ”Ðý)›)±Ö{o$‘ª#Xàs{â¤ä£jJ¼×ê(·¸¥Âµ Žë*MnÍÛ@ª:²'dˆèg§–k’¸çlpWÍJj«Ï“ˆ¬‘# Ó&¸¬·PÙÌÓJñ«ÓÄÏJ]ÔÄ]6pr5/lö añ=ød0÷Ú6žñªc¯qlA½3Îw^–¦€ŸI=•HÑb•uàÕxnDF.Ó‹œ{nvݮؕå8ðžˆLE<è)‚èÌÄÄ< «å®Ô›1{Xó†ºs‚pP t$P"?6y<²^‰ü°Ù¥l: ;xã²¢‰VÿZú‰ÐñT-ùwcCÀ{*ä!0Aª@fg¿¤<+ö{[¡ ¹¯¶/E×$˜ŠŠ7ò@Ú†ch¡•E®õ’Bë×ô¤ ÍØéÀ¤¬Ì‚¹”Ã!‹Ïg`Õç4ëûcîàãM²È½aÛI~*™4Í« ÐÊCØ‚dóÓ 21VPÎsÎ{rp ‹~Ö*/,߯%ª;ÙriË‘Hݘ,œå[zñ$²!-ªæ`ÚŒt l½ÓBZ#tË;R½"ñA6ª 6xÄ`ôúW<]¦Òò ›kp« Sáè*WuÒ:÷Is­ 3*AHõdN(Ðd¿ 1üÜ,úbÆ¥ÅìÉ.n:g´*Š[Ÿ„ÚKg²ÇywÝÁ_!v›4ó=Æeññu ôYìæ§*»y×õk(²öî¢WÿgÜwO&â9„ª5îÑ»á³à_Á÷gxcÈýƒf>¼ß;’¯XÐbrêä”D-Ï÷4/‹y4`$àÄßI¸8š%¾Ööàþ÷71Lµl0Õ¤H/Ýk°`¹ãy±Æ$¾iÑ ˆÞËŽ"õB38®˜ý#i8…ó¥ø ,†¥iŸ|ÊM9ê@ßÄubT¨â“®ÑÓÙÍá~ƒc„ >°ý2´j;Á@‚_;Ι³C9H‘W#rjè$©k4CÜxxýúÖQxòv.ˆ÷i>uÌ1ZNYm -ÊdÄöqа°å U¤­(qWT©14=Œ ŚɮЙ¿€–t?·E1º›‚ÇÚŽÃ:4 †TS!Ê’É&02€EG€šÊ3j XF!yè?â£ê_GÊß÷ ‘ü ì·]²œùýxòêz¨\ç}¤Ï=ünƒY™ jßg&¨ýw~d†Å5ß ÕÂz_ð’œ}ã™É¤ÿÙŠhÿprÎg5^‘„Ô´¡Á*ÉÙ™õl5;ÙmÍçWì§Îpjh…»‚suR—KÄŸb /!S‹j4Ã¥ÐZ‰÷ÞÎçðö”&Ó/­™{Í½ÌÆQAêî_|Ùýt6¨q\¿‚l6cõç½ Ÿ]*´ß`Ÿ‹¹ž1†¸–­ŠmÕÛrYuõG’>yèǺaf}ô¨˜ÊZª3β=aÓÄš¤k¦Ñp&PúÉò)/4ÓQzHpönYÕu¥î³¼ÎWeþ-Òû]¼º÷¾p;Çòú&Ü”®~@h•yØæÓ&R¢5/Uü2 -e£w2¬Ê÷¤ÇÑœ S~fåÔÚ—E©tÈØ_n±Í婳Æy ÂÒ“Íúvº¾xÂ4®]C¸Øò­ ¤K[Q8¶àqS3?tk™š¿g©ý’°!@®Pj(‰³™•K)Z8OâÖwÒ_²Š>,¿æªéÄ[˜ôf’í@«œ+Çc]¥ ³¹zÕRÕsQ^Y_ku‘`K—3IŽi7Eø×ç^˜zÀý4”3¼»à;Î+¹z ׬§çZ©y¯‹ø§˜Ù½V£¼z._¿_4㳇¬»JŒ¤¬zBW©¿îŽœG ûa•™ÓëØS1^9J2ʹ.ú1ù]CÑ)¸¶`LNÑUÖáêAI'ÅŒ E0rM÷,7ÛH̢ĹûÖMïYÒ.­Y@ l—‹Áq³Ò8j§T3hÚ·qßë’*’6øý^üÄöõ¨:·¯ôâú¼|®¸Œ‘k>É÷>«Ë« | 5Æšùëëo©%V8~<é^ÞÝcŸÚxò«³^߉óï'þã2®»î)=Ï›-jo:í—/˜˜nªAìŠÆ#Éø¹lbÔÆpÈðPA&Þl`1…²ÌÁd[ÕSÿ*¹~ÕœˆaY!žè7멞(ÜOvA“ñ’˜Òç K·¤(€ë0x—^RÿL‚£À£ËÈÙ/¯» ¥B+}Ly)ŸÊíàÊf ‹ æ!B| –E¾Ú°ž ÖÿȺ Üáoå…øsm¬}¹å´ƒç©>\·³åÓú³cèÖüQÊo¥ôž e–xÞÛT#ƒ:¾~ õ´¤ à†¸Ñ=²$áÔ] Ö¡!~4ž¥~Ú*‚¸sA§»óس¸Žôv$q“Ò¿E@–§í¬ÑgSUÃ6ÎBë‰òᔳщMN[ ƒJ W¿{¿û¤pzM}ÛmÿkÿI‘Š“*Vv M³ K¼êu—5úÁ*QíÉ2…l+Öõ"·a1ÕÓu„c´ð°Èf°Ó{Ô{3M0Th8[ÕËp›‡„™þ]tNÍÊšµh!)¶Ìs%¾ ¡¤Å7½n²ö$ÿëä:ºl׌´¡*£ù3Ôhðí¥àÏ õz—À1Ì#a¨™øS©Hãõœ×+~F$¢F;fî‡A'7´Œ^æ ƒ¦éndPHUEJ: Õ¡á”4ùÅޯżü‘뵊‘¾ôlè<=‘0vr*Ëä¬ÒzÊf™Nj“p¿(l(;]Ï™ÜRWQ·ÞmblƾxD7S ³S_ØÏR)/\Åq#eÐÜ—5^è«Qº%øÐ”# Óˆõ¸k$¼IˆnsdRÊ;‰ÈQ-:™üûÁ½ê ÂÛñ?+f‡Keä.)ò’C$¬?Â, 8k©%žÉ˜XßNÜÑ{þs[v Éè™w^yÆ%Ê(öÍG€\ïÀ¹"DÔ$'/â¬ëÌyˆo8.µÀæ€BŠ@ßNU‘üµè-s¨J·ëf‰ Û³±u:3Ó~Þ©|öÎ9éøl3ËTýË…áþ[ôYE]U}:ÇUI8:hàထXÄãü¬o:;ìL­uÙê¾@0ö¿÷Dé‘û~[ÃÒEwÅ\®dg½sªã8–6˜Œ6ÆX=è¹Ø$mÊF(Úµ0Ô(c[‰Î–ubÊ›`4¯šdËQÌ¡×'L¾B 3"h˜&êpŸéÚÔ?öÓShëöSŠDß;š›t©Kõ_ife ꞟ§«‘¹ò×ö MZŒi.'¢th÷"<r“$G¬*îwDE-^Á˜URN!Ñä0¨­âÝu¬¥·öV~NFHÀù_„0?b‡½˜}pi2;ÐÆpÀÚšf ¡`[ç’»>,XØÈl(y3ÙóËu„Sá6jçHϪ¯@‹›ùOY¸îå5gy“0TÌSq˜Ëð¬£!Œyz½²#5MƒN\Ö‹9•Œ¬s¼ÎÑÛ¤Á÷p}è¿SOÀ!àÝ&ú3LEùÖëã±ö²ªE©À€ï×Ïl­u|Ç úád×JE)ÞœÀýboO· [?CÇA >Ô—œd’•¬‡žšñ[¨G=æ=å {=&K§¾Åtj¬T ßJ|òÜ”H#ž>ÕØa/e'L<‡8¾øÈ7%u÷"û‚¹F JX’MÅâûøCYP;`yi xòâ”g¯x4-ZÒ…‘¼hGV$É&rÑÅ¡ÿíK3”ëÃ75Œãå üãOÀ½¨úÜóÖým—Z;2íÀÏaòTº+ÎŽÂV„ð¤~U]óècuú JÙ7³Å.n½_ETsWRêc nܵÏyFl|´¼°¸Ùx@xg(©ß&°_L}~ WI¦=ëÁb¯ìS–ö)‘Õ¯Ò‡‚[uÜr+Þˆ¼9wG‹à^yÜ~à•pÊ‘Ì}…šÝþö&ŠšÞ’ég !a3pNïÉ öIéöÚßW"(¿á(îáÅàå?Qw#lènâó ƒÄÓüøKt-AÇ»®5PÛë—qO9üé¼ÔV¶MpöŠ€ÆêévcõB©¨Â#-ƒò,¬ã÷9å‰5“Æ›„¿ZcËGÁ‘)¡.Iy(•ñª^ŠB®-§1ϨDò:ˆB³• \®’zIí¹%/`šÏ&1+(±U?ä‚}EK}@¶¦4ˆ/޲F¤Ñ3ûR¢æºÆOv¿ðˆ}¨…Ýá/~×Ýgæ¤Ñ‘O”†k4žm±ÓÉ(¸y¦oâå Ë=´Èm±y芎õÌžºsÛr–×È=¡’µ*pw„éRÿ«ªÅ»CɈFªçGp8Ü*[£Ó²5´Èʼnµ­x½f;:V]&–ËùaW{;€WÏjVg¿<Ë/Kô«v¼Qƒj_6œzxñ‘Lˆ3ämKò¹„e™ÿ£ºáäâ…pSÿiÇšd™Ù¢êÖ+ìÖ%yë›è[[£=Ö@S€Ñ¢e¶'ÖWï¨^aF£SðÊ­ÏcBÙðnÞ*pM¸G*F«¶½Ê–Å™#‚êZiUòKýó©F[B¥÷ÕØ!„¾äíC#+Ç˵Tƒ&c´@Ws? ÆüátÈ×*åøR_måC/ã`DÖÛ»"}J+ú_±ÙØ^ÉëIƒHu3†6æ´ÑA÷݇¾·´NTpv¶Q0¯îOö_K]—ËTŒQq6Ý”õ ìˆÞug¤é“ŽÀù ÔÝÔ˜»fÅÁ)߆¤ò…¾8i ÔÿERÄro'ƒîë•¥(„¿“vûòøt„kD›Aª®¡s"ÚÃm~êÏ­‰•0ȸŽC\á%--xP/Ø{W p÷gáІáýÔ“%Ñš+?C”ì¯ìW+ØêÜ6àR®¾㳘™ßè …Ñ„{€¦aã¸z½w) aŸK6Ã)š§Ìæ“*ÜÓâ™ÓÁU£á´M ÞSsæ­2ÔØÇ5·-Àª¤lw‘[¯ p¶N7ð Të¡äc&…òãQtTqÇ//ßMïOµ¥Œø8NIتí]hî!Z­¶m`²eSÆ–*uÜÕ´š ûÞQa.;:›øú˜:©¦k/P·¬3<ÿþEsÁãk}Ut/ŠQ̆6ÞËÓÖyz;Y b³Ã¿L‰o㣲ž@Åü=C¸ý!‚U-ÅÊÇA‘$’ꨨoL度]êCÈÀãyÖÏ¢58X!ù믜tÜXHœ¿†'%Ìž°yÝÔÐòt›®1Òjü¤—뺸¾ÑºÏ¢£)ÚÅ!Òã|†9ÆŽ–p ¦àA²y°ÓEêÑtد¼5^ÅænÓ Øã8!é9#N;M`oŒÛ ãØcN5¦áŒ§Ìò"†‚¤!5×Ûšõúªþ C8o¦œäékò¸ŠyÕåÚqÁ ^œ…YÞòu±µæ¹íÿ»zjc‰ zQß×R—F2C}[­Ik…Cõxxïz¹kÌ{†²ª÷îaCm'ÒhO„@°ÉÚo”–â:¾p.IíOS¯§™Ó@˜L½·Ù»¡ÃoÜ~jWÐ~FNÙj˜ÀøÐi`m/bü[ó;U‡°Þíryéu~bÆ9Þ“]1óZ;l‡ÖŽ%çù‚Æ_ìájjV 7ýq[/«%óÙ¸`¢“¨QŸaI« »_ɳŒyâ@eðF-ÂN Ū=còšÝì×f°u°k¾Wtg‹£mZŽÏ AbŸÇ>ˆJÌy˳* íÚÞëƒ"LfÖâ§×âZKûlh½ŠN!tä3“{>z³qÆrOâíùJ %…Äb”Öåžå`Çøã®Oà&€K¿7"wljg<\¬CLç00Eà§ZØN]îѯIŸí´ÑWr$”¸wEÉ^Ëúð‘àȲ<]*£¡§nó­â³ï¬ Æçˆ=@BÂÊÛT ð¼zXÏ”P¹àÛxÆ?]¨Ý¯R=«u½Éà*¹³‘ÈN>x/ÃêÔ+A—”#%aÕTéÕíO¯Ø'E²&m#üãˆgÖO³T‡¤Rmék13›ñø™> 1(M°.–¿–“‡/’Už|0"2Z\©ÇVkü¯Ñ›^|¾Ùõ‡å0øRZ—„D”,Íc¾•F;¯Â¬nÛ×D Åþ“]&=  ?do!– 4¸D€2'Ùd†Ð§ÏŸ¯ûo¢“à«ÏïKÞ ¬9†d¥£ÖŠ¥R¹ihÀ.29 w€V(Þ ÞÎ:¸wQ§T¯ycĶ¯Þ£º9­_Ù—–vPóMÇO& (Ÿ8¨:N] endstream endobj 4841 0 obj << /Length1 1409 /Length2 6329 /Length3 0 /Length 7292 /Filter /FlateDecode >> stream xÚwT”]×6R"!"Í(ñ3tww‡RÃ0À3ÃÌHƒ„4(Ý%­t‡¤¤€(!*„” t|ƒú¼ïû¼ÿ¿Ö÷­Ykæì½¯½ÏÞç\×½îa¿«gÈ+o‡°…ª à^P ¨­­€@A> P€„݆qþí'a7¢Ð0\â?Š((ƒõ)1X 6Ðxä @" Q  Šÿ D $J`w˜@› €CÑ$스 æàˆÁîó÷À á€ÄÅEïÿJÈ»BQ0Ðc¡®Ø!`€!ƒb¼þQ‚SʃAJðó{xxð]Ñ|”ƒ ×}€ ã0€¢¡(w¨àjd€Øúg4>v€‘# ý;`ˆ°Çx€QPÖáƒ@áhlÊ#¸Àî0T×è"¡ðß`­ß€û€?‡ñþUîOöU!üW2A¸"Áp/Ü`stU´ø0ž˜û0Üî vA#°ù`w0Ìl‹üj P‘×€±þ™ AÁ4ær5#ÿUì1+Ãí®®P8MrÕŸ …`ÏÝ‹ÿÏå:ÃpŸ¿-{ÜÎþj »GH~c8ÌíT]éë"ù·ÏŠÅDÅ„P7Ôâȵ‘ú+ºrcgðóA"{ìP?˜=ûC⃻CÔ#¨ŸÏþi‘€@;°…:Àà$ÿ®ŽuCíÛØûGÁ<XúÀ«Ï¿V–X†Ù!à.^ÿ†ÿºb~sE5CCMž?#ÿ+¨ €ðøð x„PH Š]øý³Žö§ÿÈU‡Û#WÅ®úÅÔß=»ÿ!ç…pþYL¥.Àùo¦[…ìèÿÌ÷_)ÿ?š_Uù_™þß©FÐXnþÑXÉa~]ä• ÅŠêŸ}(Ã!»+õ ‹À(Ø‹{ùXKàÂÊÔêù‹Ý~>8ƒM`göØ#P$W}տݕ﷉%?ü—ùm P(l¿øíáoû—â¡PO(„äó$"ùÄ©æIëq•<ƒïʈÁNê±™ïH¦WyÌz1Þ0+sJó¥Ê犕S‡Ž‚ÛqöÜÇ=ŸåZ–:/¡C^•5ÛØÉËÃk >GŒ÷&É›pž›&+0K£zqô˜¢(:‰eíz ÙÉ}ÿªéþ”àÁA]¢"ªÒªÓÞYU’©EÃ(n²õÅÓl;`´"¼OûWÎ×gÁKÑ):é÷4¥ÚOHâ=*)úf({˜º¢5܃V¾³…b(•%•„®WšÌäÝü™Sì¾™Nåc«zKnÓ®·tž+ù¸Fg×qywÓò.gb§¨£M¢}4hËû„‰9C­ŠÊÍ_´›ÎcÁkì—I8B›t§ÁÔ^Ï•arÖ Ñôššè]øùH3EýỾ'œ÷µã¥/Ê–·üêÙÛbÜíCq[þªJ¦\Væ¡ÉäÚð³ÎëcsÉš9ä ™0x(–êØj$S4#þ¤%ÀŒRPÌ–Za|“¿þkÿõBóCo¡‹¼½övŽ)·Ê(x U´÷BíŒozÁóÓÿ›:HZu´¢·‡ëâ¡o¥ç¢¥V¿+¢Ð¯Ü»ÕUøÛÂGʧÑ Kö‹ŽÈ'1´|-÷ʧ—z˜ËpcípJtrKO÷iÞö!ZqIÜK£O7½Ï7qÓ:$È:o‚—z·%MÆ:DúózIqe>ß¿ü!Ó’¢ !ä*>7l˜læ¦ðiçÉ£iY¦§\ =Zy§¸¬+GîèÇ{kšó)Yµþ@ðzü³èVù…ýæœ(®ñj†‰o7ZK¤‰øÄ_|ÍÜÜt` ßË”¾Éò°ÝšåÒöa}û»£IÁüi_ÐÐõ†]Ó{,ßèp—²2^/€w×Tкq\O Øwìv›=¢u^•«É(ù|'šÎŠë5OºÙú­®äô "Ø¡ä&aȶ½9Sã%Ø×¦Ý1¦Øö1W—‡yðä!Ð)ñ{ލױÉ­TG:ÃÆ<‚Ç~TÈ Þ± ûI+ølÒš¤—ÁEÈÛd}o n°·ÐÁd•«¬åÆõöMŽK2…ñ5Šs=íOËP5|:|÷ì™sî}«hÛøôïÞCÍD`Ò¡!kÂ¥[T3g}#§ žÑ)Êñkä[¦õ5ƒHD¦ÒYfi^»§Ì ýGµÚÓ‡,–Fʇ]Né‘þüïoÑSÃs#ž~ÈV™ò±5jnµ' ýò-·Ü'Bkl“#¼³“dÐ,K|i°háôh»~^F6ðÖÔrQî§ĶGúø¢Is´y‡„—8¢e‰±‹–Æëì[ÓM¿'¹a˜Õ)³¼à–{¢»n˜' ö§~T«£‰\U¡bø†ãfI^w¨¤2ÑuNIºV­‹Á-ì7žgµ„,øÈLÄðç–U¾PtE̯GØËüž#§ïØ}õq¤’‰¤Š¼nå¡Tô]ª¿ow³o ³3µZ먗%BÞ€ J2Ö*ô6Ë3AÏΘû÷nàÞ+ׄ¬¯Z“ìËü|óÓ1*]ÀÍx«éÍЩWAÀgVä-B¶4ãFpQ@M@–°¾ÀA Ú¬F†)sÕQÐñ%ÄD® O„Ó¥}ï8b<ûRg3TÀ/ í]Jï0½E¥½r÷š®t´âîRÓü\ík±ÿÉ<ÂãV=½öf¾à}îúžHwa?¾—…âEwªr[ë(oBÍ×ÓýbñD^øi·­MªhF^E_Ÿæ/éôŠî:+ć÷]¸lËxÄÏ™mH}Q3©êÃ÷t§j»å°¬ÂË–q/Öú.g½·³’¾-F²¶ÿæºSASO–3é²Ý¡Pù8¡ÐIÚþ|íÌ¥“v¢‘Qžp® ¨¹kÖÛ©ÛÞpü¼?Î8¥ê0c  ærj¤Æ8»ðÊè÷õ]þD‡ÈãÏdF"BYF|-Y•–iË« Þͳ:Iô‰ªŒArõ¡|ü⸒ý£ê×6Þ©x'²µâ×ÄÅsùh/âé¶ËDìERãáW¤¦Æ_ËÍ~:m›äœPùÓ¼Ú áù¾Á©b;Å3¿Æ°-Ï«ž ~G¶%Ûd-H£Žù„‡e€Á’ûÆ{fØ>µ:€*壽:÷ìC{:i\m*Áq.öÖ/*(Ü^V4èrtXð>¸MÇœ½©ÑM¢ÆÅˆÒ?Œ­gÒ>ÌlDk«åÇ/3"ìLµE{$­ï‘§{!J#ü3œ•A"éãý)ª0—càÓüpÎbš©ÇŠD©<Ûo›??hº@²8~P€‹ÉëØ”_Æ«¨Å¸âpÍß™+$(Ã̬À2\Ø€ìžÎwÏÓ$Ä׿Zð¾òsöוûú­ì5ÙªtU©ã§ .çÊŒf±˜íxܱÚêα§ê%_\(ù&­îQhúƒ¨m§Ê%j£™Ö÷d÷ÙÀ;ÁôÓU§hûĺü‚O®g¢šgõ1QØðê<~@—òF˜íNÔ}Å ·½nŽÐs³[›êù}©ø¨6‹é†×Ao.¿œ@6îñ‹-(»;HÙ­w•™öGnV¿˜l6%8D†Nì9æ Èç²Pp~¶Ô^¦ûHINLA}8kX>úA7©ÚeöÝ{/iÆý+oaåè@:o¶‹ !È·9à³a$òY›üw\Çbš4¤-܆@ãmÂ…sTk󰪲ãÇšìíà@þ­… ›¤¬%9ñ¨»© 9­°QŠ¥†t‹Ü»£ò/zî®#cÉP^åQú•Ä+#Û/³ÂË•?ÛÛeJ·4=Ý» ÞXcŠ™Ê3ÖcßûŽš~dæK¯*ÇÉU¶$òíX- j %r8™ÔdÊ kSzóµ’•GŸú?>âçjš¹Îû£^{Q~Ämƒ¶õ‹ÍŽþ|Þn’£¶N@·òã¦d/©„wšˆÈɽõäÙÛ>¼¥­B1UvÊäHë›Í¾FíãI§ðó×lÀMá»/ã³[€I‘_¦äBî&7ø/+³ŠIÞxü|·îrÏ”cµQ%í ø=/®.pVödmó£÷uÉkË„V”?ö¯ŸZBe?æ'i÷Þšˆâ QU‡§Í©'o$ÈO¤ÅÙ®ÿèߤeËàn‰;8pD‘Ü &f–I® Ý 3íå+±ó?R½*§.ŽãÌÉ– cYÕdÈÈà¨åÙ‹ÈGY° ³=üÍï9‰lÇÙübnü¼Ì-˜ ž×&xq$OZž`,Ö×ß‹ˆåF¢o0ž)º8ÛÊÁõyö†% â¢áÙñ^ïB+iž|nðc~µ¦¹þIÓÄ(˜µTŒ~1:; ©,Ñî1˜•=J£ ¡"MÈé.ë–V?X(Öè·ùþ&ÑŒËÀsg.~=¯Ç“Xx”oʱ„•¨EIn#ç3pRïßÕL£Qxc)´i'°P Ÿ¦oÀÑKs¶îBERÊü2ç}ÈOÿnßÝÒÆyâ Ê[ûFü¨Žó"–ÊùÛÖþüº³e—2vï}`:Øý5AIOQGHÓ¢avwUV™õ‡|ì(éÞÆ¢3ëlÎ~¼œa)×徚>!µßýÄ1wcY%)®€¡äË‚Œó‚í¤Wßã˾̭«¾ï§ìJ ÀiL7b[S×>\ôŠÂI£â×fò­jì`Í‘¶¡ï#À%ˆÃÝsd†å­JÙž$eæ4_#YÊ¡ ça–”&ËÀW~üØ[ŒBÔ…ä­a‹p>X~+·DT_”Ö|‡šu°ê{–ºo[ù…9ôF+Ll´˜2îûn|£]—™kÞíý …J†8Y77_Ú³¦°¥— jŠìS‘õj¯ôeÅ9OJ嘮øJ¨¼ß0ís ÒE/+òûÒžÖÑ]¥Æ¯žuÎ?Ñ% sR˜Z“ ‘}òuE‰àU Nãçû^J‰Ÿ;®»šY³ÆÛF/“}=¸(ÕmÈË»a`°/¸ÝÆË§‘e„¼'8 /DZê%×öæËx?!ang2‚ÿðf”žÔ“4iï€g˜†[´aGíõ±¾Ô>-È­Ðlt­vÚùƒpŠú4Yíiu°³)RtÅÍË`LªŸyÑ“TzŸ7Ó=ÿ§ê;j¿*óæmoHÚÄ~å;^.îW“ÉyÎ2­ôä%S‡¨×.P#ÒüÕä #?eË­‚Ïç‹ Ù9´›¼bòÍ ‰mO–šŠbxˆå=nk擵Ëã2‰ó•E–™\LQaR„BÇÚƒÖô–Fáiþ¥ºW2Éê{‘8-„¼Ï.XL|ÜEšêË[Ñ¢À²_g„O™³íí?@I‰›yÉ uJ*:QX®Êó s(G!ºz>²cCº‰ˆ›c8ÐH´TÌÿqX,kêØB_‡KÒk1–Û ,5½mMŽgE]¹ŒyœN1—¶+Ü4Ò¾˜h†û± U/Ð¥q§ªî-Zʤŧ¬4–xôœ…›å™ ]ðn oI÷tí åco„pð@áLi­]…òㄳAŽnê O„}Åǵšùdu³¼–¦ moà‰ºAÒ hŠ¥l I‘HLMãÜXÆÈT×&”q컟®'›g¼çWÊOÍšèrˆÄ4U©­·µw'ûÞE¦Á߇‡`ý„¦­<»ø)šµ­?'ð=¾¾@»…•µ;‰ ¦6vµ8$LÍ#{ZÓâK/ êµìd¢#Âp5¯gÉ ~°Ø6Ô‘{žOó—þzÑ<‘±ì×ò„-ûèÙ"º1 uM&R„l©§ßŸ+•X7ž¤ôE¿™‡ð[þ{C‹¾Îi%œP:6~Ú9ÒvUÒ¦…æþƒ®lF ö‚Õ9j´ÎÞ³»r× —S¦{ä”x¬dk@@8ܱum§ÅWOøQ—¾^þÑd—Í)úúý ëœ?¯ %Ó&ÕZÏ= ¢Öž¯D„3 «rÛȾ5PÑ.![è¸ø0ì°ôtÙi?5 Ç»Àiî‘Û•4Ç}ÓìÙ¤z¨EâÕäF\§ÐÙÀÖ-÷]ø Èú]ÓÍ’‘ØSåÛ }êÍ;"Ç÷ÏÔºØÂb.F¼2>‡m'\SKFšW/M ŽÙ–´.ÓóÏUºg%š_S謳±DÝU’(Á‰¢Ä aç½N ¦]ÊÐöL8è¿g­•r*ËøÚŽŠûT"l¸#`)êɹÕ"„$­ÐkåfäÃwfÊFÙJ<­µÔÒîp7h~KúÈÓ('åãB¼¶v¡HWAGŽŸü¼/Àeb§oÔŸ΀ç6›{7"Y©0mÊ!tžèÂ+ðd#w ÌÈ$Š®éã¢|ß¾í ºÉ“_À×uþƒy íEÆq +M¿ $_«ôŒÁ©SR§*xmAQÁ—3¯óMå—Fõ¦q-¡òj`ÿi_+Ç Ã³ü jÛÕ=¥®ÖZJª¨Ç;FÙ‚õMô?×óq¤¤o(Õ9tøýk“-Uè¹,b]¯{·ÿVvHð•¥&ñ3©^‡õ©4ƒƒ=µz‚Y³w6ÙüY‰:Ó¸‡Íæó-¸/BUd‰? ~¬ýé¿Z©«ÿ <êæÐ‰wß·¿xZO[ÓtWîI±&ÓÔÔH†–ì÷»x8·iNZ[}3pdÆó]Çè1giYT–èÃ=„¬]Ÿ¼íÖË)dа‘´W!–Räð`'Å1 Ðu/ïž¾\yÛé<(¼=-¥&®áÑÙKãˆF?÷e¨r|Qe&…z¡ÌTéâqdRáô·þC—"7\Ÿ†!4t+ó[Åä+y…®„;@0"Õ˜²6žœ4JÂYt¼%ûê1DnÒ.^÷žÎ(ì÷€!"èÿå¯ÐÿÏïÍ‹üë¯ÇŽr<³öAŽ]çE&."×Þ}"¬“,©€›ßÒgþ¡;…K@L yøPŠ êÐ/MUv;hŸŒ–\‚’÷óÛ°»Þ9sÌÛþÆ2Ò‹ ²x¢ëºIÛÎ烮oÕÔ?òOÌß´Ç0ö†éÅ|!m©àëšt;/ ì,Žvk†gtu!žoWùhn)2Nñï2(¯´¨Ài¹ ÀÉíæó,½‘ÕuJoö&,ŸÌS¦ŒzJßp×f¤Ç,vRVš¤PTîãiV¡»äÛ"[õ.s$‰D×Tg|¬â§M²»ëT¨f‡_M˜3ŸYmåý˜ŸDbf¦·@S]¯CêßЯ(|ùZ|˜Ó.ì,d¥˜s9×TcZUÌü×M±àp^sÎÌ'~„o][Dt·£àÀ>®ÿQ• ³öÊ-<1hn{!\|Œñ2í}DJe›"=ÔeQÞÁÞlº=æ+Në8çž²„ÅhîÊšó‚B{%Ÿ«öÿáó'Ç endstream endobj 4843 0 obj << /Length1 1504 /Length2 7662 /Length3 0 /Length 8668 /Filter /FlateDecode >> stream xÚtTÔ[û.¥ Ò C ]CwƒHw(=3À3ÄÐ ˆ4H§ÒÝ%!Ý!Ò ()"Íõ|ÿsÎwïZ÷®Yë7ûyk¿ÏÞÏ»ôZº\²„T Gr¸yÅòêêO„¼¼üܼ¼|Ø@  éýËŒ 4€º¸Âp±È»@-‘w6Kä]œ:Pqs€ø !1°//€—Wô?1€‚¥; Pç¨ àPWl <ÂÉËfc‹¼Ûæ?K+˜ æüu„ºÀÀ–p€º%Òêx·#ØÒ ‹Ã H¯•`•°E"Äxx<<<¸-]¹.6RlœÒ u…º¸C!€_„–ŽÐ?̸±=[˜ë».ÂéaéÜ``(Üõ.à ºî6è>Qh:Aá‚Õþpþ:ˆô¿åþÊþUÿl #,á^0¸ Àæh*©q#=‘œK8äW ¥ƒ+â.ßÒÝæ`iuð»sK€’¬6ÀòŽà_ô\Á.0'¤+·+ÌáEž_eîNY‘G8:BáHWì_ý)À\ à»c÷âùs³öp„Üç/` ƒC¬‘€¸9ñèÃaÎnÐ' …Ü™°ÿ¶Ù@‘A^a~>ÔõÛòü*¯çåýíý2ß1ðóqB8¬ïH@ý`Öл?lWKw(éâõóù§ãß@``$À jƒcÿ]ýÎ µþƒï.ßæ xÆ{§=€÷×ïW¦wò‚ à^‡ÿ¾_m9yUuŽ?Œÿ×''‡ðøp\|‚¼H¾[øý»Š–%ì¯.xÿN}·F@¼º½;¦ÿtìþ—Xÿ6À¿‹i îT °þ-r^A^ðÝôÿ-õß)ÿ7…ÿªòÿù7¤äæàðÛÍúÛÿ¸-a^Ü‰Ö y7ꈻ1€ÿw¨!ôÏЪC!07Çÿö>AZÞ ‚,ÜæNÌ\ n^?v˜«Ì Ñ‚!Á¶$óÇ®ÿkÔ`p¨Âöëm¹Ëâåý/ßÝ|íïÞ×;]þqYºÞ ò÷5þÂлqúwŠp0òkîø…–..–^ØwW‡> »…@=+Àà G ïRwœýÖì_×,* àÿ2ýF¿:âü‚<Ð@AìPÀãðxWÊñox'&ø?à])Ä?à])×ßð_tÀn..w|«ðŽëðï7 õ„‚±ç¦`ñ »ê –³JY*®µQ‰{û)gF|\£¹fXÈÅ óoqº™óªÅJsÝ %3»v 9ç³7_fŽ}Vkèj½N¹è”¾ÛÐYÅNßž¢NÆûü¤f˜ÆoDÉ6L’£+péAÑ¢‰|ôá4ĦGˆïËRÝ5ïÁL\¨$¬Ü¢Ñö¡²0C”ZÔ`gYÙdÕ¯·&xBÎ’µìór%Ê$_4}éÌ`öÚpMjÞÐâ>ó®=$áYñóÈ.›øÏ•çyÉ6ÛOoô dÒµ~ìäárWöŸ ûRå‡ÀÁÃ\a²9êê³Í¹"÷Í_7ñˆŠjÝËÔi {èphý®Šëbˆ÷ ôz©LQ¿‡êºÛü#ÙsëÏt™Ûìv?‰ËÎ_ã¾ nÑÌjÿÚUæ;+VZ¬±rý÷¢º°6ŸÍ"©®“³…¹Y¢5_~Ž%k³$;sÍ¢ŽÕ…³”®¡;¿Ñ#y0©öCî50¸3 vhè@²ß*ÎÙ›«&Ñ­e ”Ä ­9Ã+ õí)úÞa$L§¥“+Æò©›h‡Db©37„‡p³tYÄ!DBGp_î¶ßš°I~#Œð-æ?RÀX6¸¬ìò`ZpÎÔÊr7tnnf†d Kl¨5}÷¼ù\>ÓhO¯~’ë_ؤLH¾‰»¥Y1!Œ¶1ÜŽR+ £<%_çK›G]¢—ý4Z }’„"¬ê!hK=Ä¡o¡±DyYt+Aëì3»Ú{pTýb—')Œš#6ˆ8Qõòz[¤Ûkpk–a¾W?ûæGz_â¼XYkÎ3bi”+‚ ßGq‰%užùiË×;û¸Û ìT1C÷áÚE†ÛÒj|6»”ì í–ÍWWE“uiÙôЦðHñÌY%-b!åjuÌWŽŸÝŠj»£Aœo6„åŸ ôg¼14eȱŠEd€5®"ž\ó¹öÞP/¡\JáÕ4¥3Ö·4g<‰¿DW+8C¯5ø@ߎ¯ÆÝ†§ø jž#ÿ¦ß|ü„ažQÐÉ!„ ¯eµ#”Ñðª‹4tûúd¦§<Ç€ˆ2Ì멲­iìùu˜zdŒ¹ÒÃñrµîi¹gj½fNݧ³Çƒøo@ØŒˆ·Åb‰¾–"ݯd}>¬vcܪ:ÆQ?Ú¯HÝBö›:Wò“á:£SÓ aÝjÐzÏíö©¬¬ ìG†tT­|Io>Ë/ù\¶†”t?TXà ýÌ™dÅ+¨(´çköc:¤&#ï$ÀF—'q&%1ûd2uÏ ÖÓœk1c)Ùɤg>ïöUôEðøµPÿ”}#þ'ŪW†ßæ·Ñ šA£ž;'ðsxê!ºQß;»péJ°ÜBé··)?š÷ÑÉ4<¢É[¾ #¸<4U}¹);U”“#©BÜv?ƒ•aÅ×ÙR6{Ì7s•ùûaÁ“¾!‚ò†Tl9QÉy/.ŽÂFf„RÝýNˆóøä¤ðÐz '†K‡ÏW$ÊÊúÔ™ôÎãE™;ú<ëj«I—Ѐê‹Z³WD¢gÐ@õ¶0Æ›¯1e„«“G[%Ž®ëbÅëAh¼iúúdè­}ÁÔÜMq¾ ²fÍpÒ`TAxÍë¡n× eË%ãÞXlOÞM Œ1Õ܉àžfU8ÑyÃàueÑ|ôj Y Mgƒän·#Æœn¦X£á=‰®I±|1ÄEè¾HÄ´zÊÛK‹ÜþV!äûìÈO_®ìÙ¥Ít­$ÑâHs–ó¾P彿±çdÉ!¤ûÔ78³Qëa.ßpB#FlbÝøy8@a‘;Å?}2¿–Aªy)´\~&:¬SùI:cgÊÝÙí!±¯lÃL“wsŸÆºB%± •qáåéÈ“¦@´ÇoÓ6æ¡äX]µ__Z$ṲŒ‘göÂn#ÅòhNZ¼…Ð#Û֣аFŠÇ$ŽÑìq³ftðûÄvßÇ·T±“lÍœ•'püHIVÖš¬w¿Ì7øy­½r(C-†Ùrv»^ìý¶1ãî×úfRØòTh• ñäcÀ¶šˆšá 1Éþï6Šê‘«(Un·ÚqN/H˜…Ÿ‰:/h#žì]_Õ$aĨó™ZvÇœ:XQèÊ®¾\ûVYÏñ,+ŸŸc%àë¸_½6;9Æ8(€z:ìÛ]Ä•à4ëùx÷z½ÿU&¦¿4 æF¤M»÷,©Cua|èÙÁçÛ5ªÑÆÆü´&Ùzy¥²Ô$cÇ7Áfwd¢¸‰òg]§›c÷¥¨¬éM©ggTÞN|’ôøºÒ¼ysJ›4zÂK>¦¥ÜÐuŽt·«r™9¼úÅ=*¥‘•Ý6èÐ1þ÷WÌ\ÕP&ƒ·cö@²êÝ‹¤»I,B‡é#kDÎâ#q•—Údg…Óß™VÂfÂø¡ÆXóžCëka<^Ö¦Ø[Rg¨ÎfkqG/.ª;QÖŸ³Ôdú¡[óß`tlM²®¯‚J¦èžwnzOêØÉzœ¹•[Š0"5+³÷ï}Ä+Ìez„ú%ñ%ñk]ÍŒqM’œ-™×eí‘uï©V½h|@»J=%ØI]/Ù"Ì”T_ø©pŸËÐ xã/̓ÚVø™Ðì)8_ðä“t¤×=±œÁÈ.¡ˆ8¯ ¦~â¤õYÛ¥N¾VšÚ?koê,÷œŽ9ï%qXùõ›“-=C?–fA¼Þ­G€¾yù,į̈Ä>kÓg’÷¨]ísr¿#1kEéƒÎf¥‰=ƒ>&/+Ö%Ô=*{ÖŽÚµ÷æ´QEŠù+C¸\àár]pÚLÄ í Ÿ¿ Â‹5Gý¤ÛÉMU:›}ïÁ,›Ö)‹ÇÀ¹}¯1åÜzIæÿMÇÜöÃ’mêá+û£äÐö–Å×4õ¡òuU€“¯–0 f{ÞÖý”ºäœ˜ýJwã0„½(óà,ÿi q¹ ߬QŸˆËÕˆÿ¦©Ðˆ]‘ - ý]¨‘}Îë…>È} .WÕÚ×›&‘,½7›C»­ôËJµSS­«Dä§­ç‚» XÙPj*R´_}Z}”!ïqæˆ3Ój’_u£+îöûФ%ö˜ãžÝËyev?K ùIó¬:$Þ@Oóc”êŒ|¬mõ%:öjγU WÉM9Îô—ió±-ïíaûµ% çû“êlH@›ÙéÖOÜjÕ˜¬WheHaFÓÕíœbBODY-;d¨vle ޜȤåAXÚ(n±¹âtSðš9¸üžNô£t>w Â^¥/éút,«^¾ëƒŠ(ïN‰æø©®hªŒ•o-:M\±#pÃ-'kÞ ¸mB¨¡¹ŸJRv¾&Nîj?é}œ¦)q¯ÜÄw×Ý¡”ÞJj)^À„“(µýs›rùÌ÷yd—ð{ä$ù­ªä§Œ[m%ç'ÓæíbDaxͪØî-ëŠô· >e,ª•µe«Ú’ ,7™&‹¤X7yÇ7Ÿ¤ëÞ|z¤RMÖÞŠXf¬¿ó¯Â¼¦}ÅÔ:õŠDKa€×ØË–upCüð™xRaJSåÇ«I‚ /Nů‡ç_§ .{ÆûUüÃñF~öc^¬jr-rÀ˜î#iaȦÙêÑ›àTäÙ¤“œa~ë‡Õ_/ž­2yÑôeÍqD²±ÆÝótæUý±úb³ûzñãL+²,ü-2=>6¿…á2ˆGýE|Ù4áÇûùçØÐaµ!ÝóœV¬Bc}aÒs`óQ»œ lÓ…Vƒ)[I®œ@Ö+ó>³â(:1 Ÿéü[¹výKÌLæìfÔûk‹'§“7æD•»õùŽÎ¹6Q@Éàü€ÈBýÃ\ ùµ:g‚îªëŠ0ƒ/ôçMµUâΉøq´øXëÈØ+M °¡wüqò®ÝóªÎ}}cç– µÝ˜hÝê¤Ú¥Ãb ë© ˜fËð®Tž‘j´Ú>C”hSx&Øçƒ2ñÿû©‹X{lEA\¥ÊTjr9;‡t_…3ÅnµmªóTû; ’W¨""Üüd×ï›Íf ¸·Æ’YdP¬'È{Ç=ÿ¾|Ÿ2bò¬t¿݇i€H¿ùùea*lmŠ[€q$d¿o´žY’Ò1öÁ˜^õÏÎ{Q%G: KÒå3IÍr–íp/׿*-ÛT6úž;ÔA§Ýy<–œzB|~Œn[Œ½÷{Ÿž"À_G§ÔQÝÅÏ:‰Á >ާzÂ0Z"õNÒò@f1¤Ò;¨Hí—þJ+\›]‡if\zÕ1?‡KÐù$t‡+¶;=`÷Xëã0Ã=$C‡ÄLV¢J“WâF/·™z ö¹ÅBÅɤL̘Un ¥óûHk{/¤ZùŽ•«Q~6o°y®2Éa?G4m,9Nja~D-ò‹ï­³ƒG^VÈ­8é‘'pd<멃6‚ígíéúÒÒ¼½w( p®•Ó¢‡šŽµÅÞ ¼¡!ÆùÎ;½× ð´¼¬*ÖƒÉ!yÅz2¶dôónImÿÊ,— LÁ!¿²Ûr&/ Æâ­Þ™.½‹unßcÂëªNèK÷ˆœšT”–>«ñ‰IgÿÜa„[™Oœœ°N ä\Ré<* ӼЩ-=~Õ×RÊ›O0.vDG~$†×ö`‘»yßÕ€%»ÞØñѱ)BÍb±Aµ@¶Xê*†M3"k«1(@¶[_¤1Bz@ÞlÖt>‹bˆ¡*`f{2¿'Wú6*Û‘U²ð™€€sƒ¿óSZ·Á5^-sž×sÛÒó nñM»Áõ­¹â2Qµ€ŠÑ©Ùõ¬ˆ¤p+!Vè[?ˆ3ì”ê%(XBüŽ“{mÃ?²pÈ a} æÏíßkŒxHmyÎYáìßðw(|{»ð€Ý\}Øö\(…sõ*Ÿ*œX¨çKž¶”õ‰AÁJ½Ž=µÝž‚y¼Z¢I,W<º´»ÖŽõ¢’x²z>àæ>oO 7Åk DF Û)ôÀ͆¨þ;iL¼Ë2Ù…}›DRP(½L?»(à"wŽ3ŸKðB³Â'ÈÛåCâ†9y+s¿-j€ÇèžÄ7ÙŽ¾²‘÷æÂñ¥¤ƒPö-ƓßZNeV\ÊñæQ/<†jÛnˆEÃ8ÓMŽ—Ï‚±C×%¹ð6Ê»ØøæwßÛlÄ5ƒ^¾û9"a¾àMnp]Ž ML»acÈü˜_%.N²vJïËS¬ÄmP»þä³wõä €à4Ú‰‘:,ÓZÐÄ0VK"0sª†–ç–Þß󜨕ñâEadgoÑ2æ{P¼œ™ZÞ0zêµl3«'UrrÆtö¬,‰Ð(ÞG´‰$9V-w¿T ùÜäÌ4OØ}ÉH½Ù$ eúÈoû Ûôk‘7Á¦Å õ²ÕÌ%и•5ô•RfãCǺ»Ãy5RÕ8xšW´‡vʜیˆg°«÷Ó=N>Ž˜n{t_k+˜’§w=—yΚÀpótâZ?“D°#M•uBPAïæ–œâFéBâ Äiw QáoD®mí)¿Ò’h$öð8øÉ! qà½óPãÜÍÇxö£xlª­¶ÆvË# H{·ÙØŽ3&~s£-ųžè”áD_¬ ÒÆh qÎ÷¹€oyÛ^8ÇšW}Dh£GV% Ý9tSQ¿w—¡÷ý†ð’N–ÄêÉ•½Ëk<ǡ̀{K«%ajK…à<}öAW}s¹Ýrïì\¤‡º‡Á>ÕF^m2ûÓì%CáXüÛÚ1bÆŒ­LQÒx¹u»V£ü·ø'Êæ+ûO·áŠÍþzÛ®…Ïêê‰Fæ³Æ©±ª5*–¦’¡vËÜ ß‡Ý pòijZRdØuS Œ…µçˆg¦» Û~qu/º^ßÛÞgß%%®óâÅÝn÷ÛKÙÞ½S¤`Êy—Ù²ò5ÙLQlWÝÑHW˜ºEŸ¹œšh-  }G¨Îvõ¬Óúeløy+¥ŒcOôYe^8ÈŸÛ¨Âf-LæàíÆ÷B{må "ƒ–í‹ö(K½A+Ô5õÆ2?''ÿ¾Gï·98¨óÈ`›º«íºv2¢Ó©&Ÿmˆ…’UÂ.ö¥¦ÉÒ¤¨ÐBžâ^Y*ĦìÏVÕMFËxÏb¤;OòÏžWE%µO&‹úü´ïà³à:¬¤Ä1”§ÿ¼;=³Ä‡+˜/Mâ¡sUrCÖÁ|YÁYÜî0|— TÛS­ŠuÜÄ5LõI9ï`K¯`Ò—&ò>˜±1jÁõùTƒòÚT‹k×¾©9SšàMÆݽÝcN ÁmüÊ÷1êjà6ik»eU^‡Z=ÔqFq}5ÎÓÄ 8S(bĸãøÑ(®lòd«|;8¾E ½7öœœy ‹O#Žo/ÓZ3¿J¸ÃõvŒâacc|GǘtûqÜú3&ç;:±÷Eü—¢h¾+CÏïOz„,r«|:è “‘ßJðAå \¼*Œ'G¯],çœzÜ¢ÿD$—3! Þ*yNÖ÷©X†ŽîÉÎ#_1}ÿ| “ýÉDW¡Î‚ddäãˆûÆ©æ<¡4N‘]ëÈT¹—Î4V‰Í¶ÒÌž.÷¨ûFPùß>¥N¹€©qÏ~tãJyhpî;©_“¼<<—&†™Ø{Sñ¤©ø^‘гµ%æ· öˆ}˜`³j+¤ýáKœÆÖÙv˱‡Î¡ÎÜJ씵Ë÷üž…€\zV·7³Öá0_%&êúo+,/B[¸,•fÑ‘g!Yx&Cªs-R6“àv°€r£†°V6éû¦oM*Mc/^Åh­þpÀ0]B øp¢ä@úPÔwÙ ÖR# ƒ÷åQ…ðfÇtyPT.aDezZ&Z¥±…®/Ï 6ƒýS”þqè™J4!žRE릂ó@JÒì-¶ó Ѷi”?ç0¬w–ûsÜõ>™«n˜ã3$¸§*¨–;øµèh7Á.>¼ÛÍ´¢œš³/Ñ7Ô6Ñæ!ídŸ&Ð]“5€¢ºh(2†Tâ­½+Ñ|P÷\æú9yé`ª=ß” ëÕc¡ýÃ(d6©Ö&nK¸ÚºZ;e3„íè¨øªZ§¦juŠ´²ok]ÐÝ+öYi™dÄ ;#]g‡O£Ó©J?G ðÕæøl«TK³“‰þíÇ‹ÏM|üÏTfÌԊᙋ̅¬|C$ò®¤–Vj†7naËF‚¢&BíäH°î?Ój‰¼Ë1¹ôýê?ž<:ô( œ)Ðã(z2ùÒyÌ*lbö>-Ã>”?¼Šs”b\·T—¢;0¡u¤Â~þix¶pèó$¿˜Ô{Ö¦Æ Œ6dõ”µƒ/XÎÛç‚\ðöSäú@VöáèrbÁò$dCV¯ñm¤ý ¦ôÅ£ñL˜‡Ftu àKE ¬_™Žú[’»–h”†ùTûýëº^#ÖÂîïé ˆª’Yžm‚¬‚烰³ÞÏ}Q×MaîàuàãtaXÌÒ¾Êg|Cº÷ب΀„‹!sÚpkЇsŽÛ¹½§ÄÆ@¤RxÅ…°NŒò; “2MîwH¬kp†%P#Õæêãeòo9‰†ží=ŸF»Þ Eßfd‘ ¯60\zX×û|åró$…äÑ ½|¶‡o^ønúšÚÊO£åþ 7oUJøƒÏ±Aü8½èµ+™'“”%—"Ó(ƒc4掤Ì[×!Z׬’ðï~$â3õÃüTÛgU6Kó¸öÄKtÞ/x4©rÞxâjDÊæ$¬Åe¶ž ª—vðauÝZ‰_—p7©VÓI›éº!*ꓦȣ¿LwWceRøÔØ?M®×‹ù¾•3–esnÿ+wLÕNiÔeíç¬ ±Í„›’ Èø FǤïmÇ,–CÜ»¥/žñ!ÝÝý™Áµún}¤à@¶úž¤ÍSZ®Â=Í—â!žõã“VL> J`îÛNsßÓ¿ôš½7 8$0·*L}Kù Ep4Ùk­·V3›—?YÆÆ"+E‰pHºm„eÍ (’*uŽŠäŸÃ\ÈU<Ù멜Ié|[£F‘ò&œqØU{ë1ñ5N•‡ Ä >$MLz™â>´»®Þز!É-–ðkÂê=emïŒú¦toz'à T}툋ç=@šÓýÀ V48¢è·‡¾üâÑó!ªà@á=KCµO©ôVÿ¥v‘§Ž³€˜3mté~•||²þuÿtXo´0¸ ÏpLZ§Ä9Uíà Ûs…o@zº¢¦ç¥ëÄŸ<&‡nQÉÕ‰õìœ)öAL’…äø¡áP6ìª0ÎL³ ç æ8X—BúácÇñ»`Å’>Lf WNŸš#ïÇË 3"Js2"=ÃRå†n§|W3¹z éKü(ìš÷Ã=gt‡ -,¶ä4ŸßØ1ôìåêšü*-Ü4 endstream endobj 4845 0 obj << /Length1 1386 /Length2 6039 /Length3 0 /Length 6990 /Filter /FlateDecode >> stream xÚxTSÛº5Ò¤#H7 ½& ½wÞAjHB‚$t^¥7éJé]©Ò¤(]zQA^ôxî½çþÿìõ}ókk͹÷ád30T‚¢`ê($F$”¨è[‚€ PT!áä4c°¿í$œf04…”þ„Š ŒÁÚTÁ,P…ÜóD@¢¸4HBˆRQÒU° ÐÜC!ahN”»¯ÜɃ­ó÷%€ IIIü(¹Á<à0  Æ8Ãܰ!`ÀÃ0¾ÿHÁ#ëŒÁ¸K {{{ ÝÐB('y^€7ã 0‚¡a^0(à×È=°ìÏhB$œg8ú/‡1Êã ö€°C¢±!žH(Ì€­0ÖÒè»Ãuþþl$úWº?Ñ¿Á‘¿ƒÁÊÍŒô…#Žp  ¯®#„ñÁÀHè/ FaãÁ^`8ì€ün PW2€±þ™ ñ€»cÐBh8â׌¿Ò`·Y UA¹¹Á4ɯþTá0vß}…ÿ®+åôÿ{åGBõt6EÂx´Tÿ`°&’Ûœ`€PJ\\ €=À| ο ˜øºÃ~;›±3ú»£ÜŽØ1`pGö‡Ä ö‚0ž°@ÿÿtüsE pàs‚#Iþk†9þµÆž¿Ü`ÄÒþúüëÊË0( ‰ðý7ü÷ ›ªiÝ·4çÿ3ò¿œÊÊ(€¿ ˆ@PJ@â 1@à?ó€áúøX-¤# õW»Ø}ú»e¯?àù#^À?sé¡°Ì…xþMtk ‚ýýŸéþ;äÿÇò_YþW¢ÿwGêžÄo?Ï_€ÿÇvƒ#|ÿ °ÌõÄ`U ‹ÂjùßPsØ_ÒÕ…AážnÿíÕ€±jPB:a-º+¼û—ŽV‡ûÀ p Äù/Öüe7ý¥7 3@¡á¿î0Ø( ð¿|X‘A\±w4–š¿]0¬†þYW AA‰MDLöðû’`Ï»øƒ°ª„Â|~“ ,„Da°!ìŒG”ɯƒƒÑØ™áhWì98ÿr’ü£ÄÓë¶ßLÀVÿ{ý[Ú0˜ B2?‹‚È„»¼ï8¯UbòüæPæ¬âœgîÕˆ" zñéXõ]ï¯t§Q¥eg–:¸ Mq„ÃDm¿LПÛÇg'ƒDlÒå’ƒŸž*‹ XÝGÍ.dÓ4Œœ4Zxzl.Ëž#w„NžöÃ+-n§"7Z^w ÷Dí£8¾²ÐN…$Ytfo÷m%7k‰¾¥2ãSÇÔi¿CuÛñ&æ'Näã´wiÈÜW”š›`O4¥(4¡zg¢³Ž“©Gl)¡ð†ô {x1¢²)Q¬MåãmŒ©ÕX§ã¸…È£çcÓñ7RÕ™ÌݵwÛF½=÷”UÔÜsR¢«ÕºÁ\Rþø¤ÑfAªd'’Ôdà‰ÆP‘Y¤޳cÉBA{®hÛŠãQK,Uýw ÷ýÓ^æ4muÌÂ÷ý gxÅ¡ê’?¼ D?|¶Ðí«„ê®ûúp{ÝÆü“j¨n+A´åݥңȪ"ËÄ™7Ejû:—"«v"­7ª[ËQšéþ$ [>S 7‡¶¸»;<ÚQdç§ßÍõn³e«¥–ìfµ&NãÿàJ[ÍDÜV¿¢³Ò¡Â5r=gUÏw8(©äB©œÛJŠß÷ð…3{9Î ÂøÇésu·woמ!˜!|‹Ñì_«mƒŒª¾ØT¸E®Q¾…—†kWèM%°i݈{1ýâÇ:ý‰ÕO;Ì´¹LV÷›ƒÌAOEž;¾7¥4Ó7LŸäú¬žœ‚E?«—!ðÒ»Ž$}𫘟MaR4Í•ÊzªWdêÙÌ'~’©´ ß 3CÕ?~ïÕ–¿“¢ÐSŸv[&-·Nn䃼@øÀjie—5{å·¦ôì[“F»×½ŒTÒçŠñs UIȧíòéFr):]©éâëJZ綸õYÞóÙ4%P­!M?WÈ™h˜Ï$ÖØ¡ãaS­zGí±òQ4cé×QËšŽÂ]á¯W‰ãV…­?æX[t8õ ·³4Ã"S©e ¸î=yä•<#0ÀÑÀîlZª«p\¿­°œêÎ7.áEþî–Ü{:pUƒ"Uñ™^Š˜í¾hzŒÉçzIǶH£¯aITX«>oxYPbúË'yq¸é³ï)F~OiŽŽ7ý£&l©T?Ë®ùge­(§lÍ~90ŸqäV9ò]\©µ|>ý\ÑÂ*™Z‡d”xÀÆðåšvôÅ]W}¹[»?+gM)e Pjo}qÅ}›ÅG.AôÏj`çì{óØÜÆ´5ª=ÔöG3WÜç£C*IDzâZ3º•+<ü•pÒÊŠ-o6›Éç¾`0ÙîrÕ×ù‰úeºNcöB™Äô O[ã%±Ã,qe9ª÷E^È÷Y&«DÕY‰uãì“gå46£‚AþÑ“CŠÓü˜³áä×.Ë!à1wäÐûÕ†éO3þdzå¡8{Μèo›ûùœÖwËzÏèB×>W™-¬ †uƒË³mŽ7fHqw0…ˆÔLgJñä+ýh¯»R£Í7õRIÆ[<ƒ]6C÷3âWILg­âg¯dŠëïglt¬yͱJ¹’úR%Ð5j¦øºË0ª½[¤º0ì‚r'¤÷Âmª>æ8øi¨(°s†À>{³mÔeŒŠÇlp|in•¾ê|Ë;Ô™ vgn£Ê]Õû¹›I°µ‰ôµŽ0S?€ó !0j¾›)nîÃ-R·‘ˆšûŒ}E:ä’ã/çã!#G㨛ó¸U±9:šÅoÛ´?5åófž>Èç÷bé›Þ?Ú^\s„ÆN÷MÜ¥½ b=!ÚŒà’‰û8w¼nâ´c\6ôŒªð±Î‚Ÿ†'Ì2,¢ïÌUϼÑòå®úœì†r`}Ʀkýû^Â%£]ž…™q[‘9NJ ®ÒÅåŽ[x;NÜÅ&"À- 5ýz§ü.ƒáç6ÚêðBß<š€ÔįÛÔ{ü“ž°ö¥©5BÞ¾˜ÇKÑØ~'\}ÊB·™‹À»Ð„eGΨ4lzé}]g×$-Ù!ûJXoÓ*Tº•ô2.?`½–g­Õlæ`)V£¬ !ªíÈd~ÓoÑ£ÀnW?wÅÝ‘H ]@ O7}oz]䃟ð‡ú¦y¿)Þûá­1ª×Xî R|[ªíº7Å2Þ7þÞr¤4¸UE]ÿz™a®Ei-­õU'ÑU7¦yYh…câƒÓ-b‰0ˆákxƒ•'–8–táx».Dѳžk‚x%ˆÊáìñ½{¡@–¹Ÿ! •½f ðnjê¿£uÉþ€îbyè•‹¯Iv|Ho£™Ûà—ÇË Jß8© 3$%ïͽl˾&åw½ý³I´Êbpæa[rfäõR ßîc©¸ñ­G…(—Ó]íS—Â6!b‚Ñs~Píì‹Ò^­„ªÎžá}<ѳ&A$ê¸ã°“[v²s‰&¸>'+‰ãS»óuð •áo£R!ÏñOØÏ‰m"šï)ª gúºKì[A½!»£Å£Õ¨CÉÄ~moC§ñî¹| [òP¡ÙØè¼±ží:R³˜‡Ç¯¯.ÎÝÈn"Àcd6œ7w„ØKì“ÚËíž6Ùƒ×Ü_žö'°¢SpÅ|…,Âñ˜§FŸó|a.2)ÜÅ)9…‚´ Š\++ßĺ| ª,"bBýnUhMïEëœÅ3Æ¢QŒ–/°¯ë©þô˜~«Ô;ÏXÂT悔 Mqw¯Qç«,;©[ÌôÚóП†Ž!%7žQMá9J…ñÕ0íXHŸt­ËvdKó.ê°8âŽÆÓöJ¥pS\døYüiÛQļ J)N½µÚ|[!Ú=¸ïÍš¸ýæï½QbYà%F~=¿Q?cÒ‘FÕ›•ô^gl‰üÞöÞ᦭*¼ìÒªd_-›÷¡E¤‡íàæ¢iÔ÷€œŒ;ßÄÌ·'Mc·„ž]LÈ]ÅecßgzÄô z 6ÐÙR¥¬ kŸSùHXøÜ•‚j^ɸTŠˆQ© …JäœÌ¦ìeÔ4>žc¦ ÚV/cbje`Œr—Ûbq…Ø™½a¤ÎŒ ÝäÁO`k³nî‡_ïE¡këV2B®ìö·”¦‚DKW i7»•YÍŽrìK©µÑ%¹È‘<²QTnäù{_¯±£=+Vÿê4Ý]7O9kc-gG©¬’z¹óÁ‹ñýŠÛK/'ï6ƲF=Kšø znàHÿ–¸êH`Ö¸¿@üxµã:óg¥VÉ_yÙ"íh¬ûë¸;ÈçLƒãª€)¼xk\(°°uìÆ›´æ²[Æ»ÔG³Ò µuÙÉ¡rôÕ¯Ùn]»Í7ÒY!D ¼îMÐc$ÙÆ£8?ÿ(Û Òҩثǥåö8ÿãSy ¶×né°ƒaÅ1¹ùû”™ŠæÆyžä[×[3É×e}Ïsõ<ÉÀi„[ÅeýB%{¸½†â¾h„È ÊW%-›(Þ[ºçAMÆE_®,3摌¡ñY‰3\e|¶ ,ƒÉÜEŠú ®æ¡Ù¥±þgϺX'wk©¯¶æ+øÓ äÕÁM²…}¹ÝvвY¦›!Rîlv]¸¥† 'kÜ%z9 {Ë×3åÉqûËF_ºØ4P#D-äïú)Ì«îËéG\ët@’±Äû?¸å`É#Ï>/É·ñ¨khÔµÌWôµ{Žó|£¹ÚC–¨ê½Òznó,˜´“)‰vúÄ_-…v¸¸÷‘wÈ<Ãr•­Ùòº3#&÷ÔÏ•ÃÕ•Ãæîv -þ>ı¥ð{ e» ¾y†âáÈÑѼÓÇî·†5OR ¿dÅà;,—Ñ »]kAˆÛáª\âÍ8]ÃvîÓn>ºËÁ&ׇY¦™8×Ca"…r7Þü‘qÇãÖšÝôå•¢sß;<«5öœ þL”¥l†¬¹Â@.ô’Oë±ãºr%Ռǣ=µ¥=+Ìä‚“¾6s¼áSŽï/än2~ }—«°U…ðRÚˆV0foÍ0Ïàpòéj2÷2fmç˨@Ÿ.g^òpïd¨Ýt¹,P§b¤ìކD Y0é»Üg+*Ömî¼øÕ¼§?síngSñÖÍð´~Ï)n¼¡«ÛFÒXNö`À‹«©føLe鳨N“Î}t½·‰§2º£m¼öÜ ÿ¿`^uy¡é£Çuê'¦çìíÚc‘‘ü•S–]0 `%Oú)ÊÄ”­Ó ãäJ(õŠšÇRK0)aÿü䫌ý íú¥ "Mé†çO–-5Y@©+횃þ-ÞaƒF¶–“Ù ä$O8ÔËÞfhªÎš1*¸úN>n½i°È©.×Ú38 Ep:Z¨¡=gà\ÿP¯Áª_kØn+:X…hß„ÎoqÊ‘xXv:#-î"äšý]ìSY 4{»ãrù#‡} 1E(áBuY0ÕŠžˆ«cøåyOB4/ˆr«áÐky«û8Hû½¹®îô¢¨Â»ÄørÝC›oÒæ 27©¼n'EPf^·X‘¹®|;…8¦Ô‚&QÈ`YKF¡€ÍäY4@èF3šnïÔÔfíyXŠÜ¤EìÏ—)b /cƒ=‚u1ò¾r5‘|«!*x]mÉ:1ýLJu…î¦óþ’ô‹£kÖÇgsCÌ:!¸Ûa…©\ î©§†ŸŒ¶ÓÝ…£ÉxV™fO^öÍz™ïŒÓ3z¼:Gö/NTÖ+tß kNQg7ªʯàóÐ6œ2°OWNÊm‡ 7wÃ|P÷l–ßU°½ñ¾×ÿ(ø(?³=$Fµ_d¶2R^Ï_EUÜ\Uýò‚E"¶Þšý|¶|Àwýóp_*¡IAœŠØ…†‡ÓŠ)A¥ØŽÄ¨Çq\µ‰Ý±DÓ?jT¬ÍIæ?Þ"+¬!Ðõú¼Äãr S¶º ;/BìæØŒÙôâ¾1§ÐŸKfŒv#Š{šP½OldÕuk"¥'ërç ÑOîÐõ¾P5ÍùK™ÀÛûÖºAyYé9XbÂiDä*Íý¬»¬ÚÑNQøåýÏzÊ×)hãrMªÒ3ÜàSvÎí{CíÀOE¯W=U#sScȸ‚/û$¥„.gKÛ×½”!üAjÝü ¤Cb%Ñ\©c‹Vù ¤Ó1±–úº´B&m.‰ÀØT 2@î"¢âfUü©R_B>ÄÕü»kqQy'îˆE wØ‹¯,%t¹´=²¦¥/Þé½—ÔAA]ޣߑ‹RFÉ“fÝab<ȘÄp[¤Ci¥øÕ$êöõÖˆ² q’þý6‡qn­yÂQ 7(óÛß%ÐC½YâFXfœþ¼ír§9ÞÌbËRë3È“PW@Ñ÷¹PH­V³ç¼rJUŽÍ‹ëŸ7øšp,£lk˜¨_ž*ú­›Où†h}˜'²£yIk€|ëªÀNŸöÓþ-ÉíLŽ—Kö¡‚R´†Â}ÅŸuëaÁù s¯‡¶¦j¯±Rî8¯áÙÄ–8ìw_n¶oUÚm‰ÈNžf ðãSî`˜{*j­Æsë¢îþ,×W|Æ©›¬º¸I†)iœó"‹œ±flvXì=Ô5S§Š]ñ»j}1—’wÌ,oPNœ÷5‹b¢š*¯Ú ]*"KzØK¾Mš%)²¢Ö‰u.ÀM°¤¦­çC‰I¸Ò.ýL½ÃD¨™b#På3pŒ®AûìkæËªkS­®EÍ]Ýu.½Ñz_|‚>ÇM`qÒÙXÐü>u"9ÞØ=zîæÚ³a¹²µÞzŸóêÁˆ éŽs}±%ƒµpï^»‰5`,›ö¢hÌÄ»íçÉoN~JëÕxdÜÙå~;BÞ å¸j wgTF¶CVc‰õ¿lÛS•º§dú·,•i‰ßRÉоTÁö®Ís»IXùaØø-Çsì“*:ÇEGÉ-t>™ÞÄŸºJX"Ô[s®s‘=d_SK• h’±Ç§è'õúÁy~{¡ÆÄj2K`³ Ãe×xlÊè¿TIî»ñò™‘ö„&ÓyÞ÷µ»ùÂÊžZñÔý•~¤Í¢Æç·¸÷᪸ŠÊnUmV}B†WQŽ9MÏDôÇ`ŒÏ¾ôq²„ìòn» ž/ο¬`§iô$ÉTƒ¥ˆó÷Í×¢Kïr3ݬk-=Éü´îmø‚ñx¿ÖA]àÒ Hb`ô#ôbÀ¡\ ^yÈ)D£íg­w³06|ýbõŒNm‹P`f&2E%§{ EÃ{S0ädÐìÓ3é)FÓy‘Éù!Pô»×©ì݆æmOÂô/O&“ïòéûýh‚´¹@Ò*-¹.–>ÌÍÓ$îlÉmKP§YÒg5œž¿ÞßPCk-©Ç¦ ç*\¼‰ÍZ&³£…ôøÖ_˜´Õ&¥’®F›äLX§?±o¸-X«œ®=ñ¨8ô‚~ÔóÁô­ñ8 ¨.æåÜì±+ëÙð"õ=`¦Yδçßœ7W@áCe‚+Ÿ37qåã¼®TÊÓêµw¥ª;?Fúzûä0| ëïëî‹/™|;‰ Á«õÍû™ùôܘú:Ãýo›) ƒDsþ =ìK-õaÞé´¨\ÅgWñ„Eá <ÕËÝÑo4Ž'ÑAuë@ ŸÌUw[¢¥Ž%R±Ó*ã·:Æñf a¦‡£€ܱ@4ÊùH«Ö¥öUöµ¨#–O³›Ùv5*©¥Î“?$ÎhÖt½*ú¢²üc‰¢¡¼Ò¦ø ˆÖ[îO[ñ“íMã¯;/:׈/ŽØŠ ýË+a´ê“F•ÑÊüm8’ë¼5w8àðdS¿iMfTöí]!×I¯çX6›œêÆJèÂÓx#ü»DúÊWGœjoL6Sssf#S"˜¸ ©Ž‘ R{:D¢qYõdü•_¢ÓÒ(Ûü0WëTìÔ6„åTÖv™A©¸êØa¸ì#I5ÖDöÐ1H¼¤_mÊŽ—AŒÆ‡à°Ÿkßwé„XÁDÃg]ô?ÇK‹ endstream endobj 4847 0 obj << /Length 696 /Filter /FlateDecode >> stream xÚmTMoâ0½çWx•ÚÅ$ !Ù ‘8l[•jµWHL7IP‡þûõ¬V=Mžß̼ñ s÷ëu;ÑU··õÈÙ›=w—¾´“ì÷îÝÝå]yil;<[[Ùj<=?±×¾+·v`÷Ù&ß´õðàÈ›¶<^*;²~&ûQ·‚>ìþÝþ”MS >Ù_êãP·ò{=éÇsæ@öd”ôÇöçºkŸ˜xäœ;`ÝVY×`Œs4½JaÓQÜ¡n«þª‡í¡.’Uu9\ßèY6î>¼ý<¶Ù´‡.Z.ÙôÍž‡þ“4>DÓ—¾²}Ý~°û¯ÒÜÑör:-d0­V¬²WÑÍÿ¼k,›þ8ãóþy²LÒ»ðºÊ®²çÓ®´ý®ý°Ñ’ó[Å*²mõíLrŸ²?ŒÜÔqù¥ã• â5F8@ šˆ=@Šð)&°  È8Ô¹€ÂÅRx u€Dº\j2H—†ª¡ÐVÁ¹0CzL]ø Âb°ct‘I ©g$`htÑ‹0œÆ\F„áŒ0ä†sê‡á jd< —Iê6œ»õñzgóñºË»þê W ¤qÈ’£+—Ÿ#ö•ñÌÇkÄÞ .‰bªsré…¤šáæÄç†bïmŽXú¾„Kß7ǵHß7Géû„û¾nb§>&jÊØµäuœ¯¼ú•ñ1ÜV™÷•âÜãâµÇ‰Ou$ÕŸqWèS/%1{\øxB!€§ÔK(hH©—TЖ枃»J©Ïϯv×ÜëÁ=küÒ2ø¥UðKÏ‚_:~é$ø¥Óà—ÖÁ/¿Œ ~™Eð+7¿èË¢/ ÿlì¡ÛÒ(/}ïö -+ZXukoûìÔE?Z„ãæÅÛKýqíƒÄ endstream endobj 4848 0 obj << /Length 695 /Filter /FlateDecode >> stream xÚmTMoâ0½çWx•ÚÅ$ !Ù ‘8l[•jµWHL7IP‡þûõ¬V=Mžß̼ñ s÷ëu;ÑU··õÈÙ›=w—¾´“ì÷îÝÝå]yil;<[[Ùj<=?±×¾+·v`÷Ù&ß´õðàÈ›¶<^*;²~&ûQ·‚>ìþÝþ”MS§“ý¥>u;áà¾×ÃÑq~:fc_0F)l®»ö‰‰GιÖm•u f8GÓ«6•ê¶ê¯bØÒ"!YU—Ãõžeã.ÉÛÏó`›M{è¢å’MßÜáyè?IáC4}é+Û×í»ÿ¢Ìl/§ÓÑBãÑjÅ*{pÝìϻƲéOÞ(ïŸ'Ë$½ ¯ªì*{>íJÛïÚ-9_±eQ¬"ÛVßÎ$÷)ûÃÈM—ÏñP:^9À ^`„ª‰Ø ¤Ÿbr š€Œ@ ‘{@(\,…RH¤Ë¡&€ti  mœ+3¤ÇÔ…Ï ,;F™$Б€‘zF†F½ÃiÌeDÎ(ó0œAº1a8§ÎyΠFÆÃp™ nù[¯w6¯»ü·ë¯Îpµ@‡ )9ºréñ9b_iaÏ|¼Fì-ÐÐà’(¦:×ù(—nQHªY^`nA|n(öÞæˆ¥ïK¸ô}s\‹ô}sÔ‘¾oA¸ïë&vqêcâ ¦Œ YK^ÇøÊ›!¡_Ãm•y_)Î=^ ^{œøTGRý÷w…¾1õR³Ç…'ÄxJ½„‚†”zImiî9¸«”êðøüj'pͽܳÁ/-ƒ_Z¿ô,ø¥ãà—N‚_: ~iüÒyðËÈà—Y¿2qó‹¾,ú’ðÏÆºíŒòÒ÷nЪ¢5Q·ö¶ÍNÝ Yô£58.]¼½Ñ»á‚ò endstream endobj 4849 0 obj << /Length 900 /Filter /FlateDecode >> stream xÚmUMoÛ:¼ëW°‡éÁ5?$R. ¤d9ôMðð®ŽÄä ˆeC¶ù÷³k›m‘CŒÕp¹;;†wŸ~>Î|¿Ž3óEŠ_ñ¸?O]œ5ß¶‡âî®Ýwç]Oßcìc]=~?§}÷Oâ¾yhÆáô9%?ŒÝ۹׬“B|Æœ‚>âþ)þ;ëvÇw%gÏçáí4Œ3‰ä§áô–’>\ ‚‚6ý§ã°¿ õEJ™€õØ7ûÆ8ó 1¿’{Æ~ºðÏ`W(-ú¡;]¾è·Û%=°ùñýxŠ»‡ñe_,—bþ+-OÓ;qü\ÌL}œ†ñUÜÿI--=ž‡·B«•èãKª˜æÿ¾ÝE1ÿpÆ[ÎÓû! Mߊyuû>Û.NÛñ5K)Wb¹Ù¬Š8ö­iÇ[ž_®¹uÊ•MúÑzQ­Š¥Ò)V†€Ú(TØ€àx¿àÞ¢ žjy‹°°!ÀÐÔ•µZÔÀ2àP="¦ZdÔ0\ÃG©R\¡·”).–2*ÎШa!„U¼Ä,†³ÔÛHð° `+jÐÃ.¸5Nα@èâ°èÐVK-àxŸ%ô˜Ü3š% A°YÓ€z¡ÎšÔ>kP#¬³¦õ™5m0W£oš¦Ã¾žj­®§Üý·.†ÐZ¡ŽT$X/©)n)æ#W—„o(æ“oÀRZÞ $K¢p4’ŽZ¶-bâ\­1¦Ü°Jä æP"Gñ‘XÔQ¬‚i/8ºkÉ^€ÂZqŒ:ZsŒ½š9”d š­Bù Ž)ßsLù-ï7½æx˜ÏJ›¡¾Ò`¯ažÉ½)f¥É$†µ’1™¸ dÑŠcªCZCù<£7Ã3JÊgózÌnøþHȰíáÌYÉšäTœ¯a…Šï¯Æ,_»œ-Ÿ—Oë87Ë}êÛKÔ´Ü—Ll¹oKñšò+Êg­JÌâ.¾GZyóº‹Vðc­48¸’ï¼äØWtù]Í:P~`áŒñ±–rZŽq.nÍ1]Ç ÇàSÿæ/©ßP•ýïuö¿7Ùÿ¾Ìþ÷Uö¿·ÙÿÞeÿû:û?Èìÿ ²ÿƒÎþ&û?”Ùÿ!dÿ‡&û¿1y–¦¼ÍH·œn5þ¹ã)º½ÝyšÒ“Bï½x#†1Þž´Ãþ€]ôGoáõñÅ×Mñ?®Xê endstream endobj 4850 0 obj << /Length 814 /Filter /FlateDecode >> stream xÚuUÁn›@½óÛC¤äàx ,‘ei#åÐ$J¢ªWÖ)R ¶é×wßÌ8•šæ`ëñx3óæÖßžf®_ü,¹ÖêÑÆÓÔúYõ}³..ê±=íüp¼ó¾óÝùîáF=Lcûä겺­o‡þxÄ·CûvêüYõQé_ûá¯sÔå³ÿ9;šÙï~1Íô¬_àBÏ4ôÏýñ-è¾’¨À«O¼¢Ò~:ôãp£ÌµÖ:ë¡«Æö9Dsñ¤æg—Û~è&1¦^`32±êúö(WôÝîB0(~z?ýîvØŽÑr©æáæá8½“Ó«h~?u~ê‡WuùÉ]¸ûtÚïß<œ(­VªóÛÐ4dq·Ùy5ÿjÙÙóûÞ«˜® »kÇÎö›ÖO›áÕGK­WjÙ4«ÈÝ?÷LÂ%/Û³v´º _±NŠU´4(61¦‘‚ȘH`ZpÚ0a‘A‘SgAQ@Q LE…)5÷8ZÖPÔ\RC±¦%4k(4m¸¤AÓ%MÅJš÷ëŸ÷´‹óÞí¯Í$é¸*C™6TQ.€cæ3à„pô‚4ctÊ| œ1vÀ9׿À–yÒ\Û;æ‘´.y.i*æÉOÍY£§I¸¼a%aÎ2A†{&˜c¯xÓï”sÌÊ4c̲´» «lcw3Æî6aŒÝí‚ñ˜v7äÍfŒ©gΘ4–½a®ŸÈÊ’O³€g[2†O[1†[3¦þôKš?¾mÃgÁþSÌ-Ø }Áþ3è öŸÂOÁþ3ªeÿv/ØNzöŸ‘ž}æð\°Ï™ì-!={3ôpó“ïàßI¶ØËI¶)°dKÉýd‹gÃI¶˜å$[dè$[ÒH¶Ø×I¶ðì$[ìå$[ìë$[då$[ê/Ù¿“lá³”l1·”l¡/%[èKÉ~JÉ–j%[ì^J¶¤—lIoùí$,çv)%sìRJæxöÊš³¥>üf—T+™cVÍýSìÞß°¦nä$ 7G"Žñ·=MS8‹é¬§ó'k?ø¿ƒý¸G}èäü†«û&ú馿r endstream endobj 4851 0 obj << /Length 550 /Filter /FlateDecode >> stream xÚmSËŽâ0¼ç+¼$æÁ1$#„”‘8ìÌh@«½Bܰ‘À‰œp`¿~ÝÝ +8Ä*—«ÜåŽ=ùñ¹óSÝÁŸ¿Jñ]s³øùÏCëM&ESÝ®`úw z\íÞħmªôbšo‹­©û'ÞšêrÓ0ªž‹28׿¿ëˆé~û}øëÐúuHX¢z_÷§z.ŽßXA¶_`»º1o"x•R:bctÞ\ñ$7ÒˆÙ˜ïTm‡H∽@ ]Wý0£±ºº– ywïz¸nÍ©ñV+1ûr‹]oï”òÅ›}X ¶6g1ý–Í­ínm{Ì!¤·^ '·¥ëÁûá böü˜ÑþÞ‚P48YÕhèÚCö`Îà­¤\‹UY®=0úÛZÄŽãiÆ¡“Æ 7(©äÚ[¥Êá4rƒ”;"A"e"qD†»gs"2´dK$Øâ°#Ð’±%#KŽDÁDN¹Æs5&ªþì]ªJï[/G endstream endobj 4478 0 obj << /Type /ObjStm /N 100 /First 1030 /Length 5653 /Filter /FlateDecode >> stream xÚí\[[7’~ï_qw1ðá½HÁ±“l¼g²q.“~»e[›v·#©3I~ýVï-µ¬VÇ;X`ÑÐiòV‘U¬úªHÉZï'9E©&˜¬SrÒÖPAMNsAOAã'¤tPx/Ê©@%=©<• ¾§âÒMÆÄxf]”“cñaT“ñ@¯F=™€AšÉD¯é–›¬–D)X«ˆfÄ.-7Ó‰ /ÞF*™É)ãϰd'ç,?… Œv‘ˆ‘ÚÚ ¢*¹ ßôT‚)H-'â-jÀ[AÚ):¼`ÉM1Ro¹QÒ*wæBœ”Ò|¬”õŠtøuìL©àÂä>×Rã(ƒ¡©Ò ©è±hߥ^Ñ]‹oéh q Óò ‹‹^dT™h ÍMÊ*p4#x§&-q"•|‹‹žfÖÝ–ˆ%'±i$¾öt:ëÌK8uÈ»¢›àˆ·Hrõ@ôpB” ž:1t7z2P¨Så‘5Šz ¨.øHâ"uVzâ [SöLk…=àÌhC3 4Dm€: Æ¡Þpg4õÚáœ(/QÎPlÊ#o“öÙñPÇ GG "©‰QDÝ»`ÏŒ¦y •34¡ÞÇ0Çm£¤YtH8HRª€J…EOÒw4¬PÛH4ùÁbdÍšâ<Pf4âȯC–TðK@-=Nž#y„@O¹Í;Ïz”¨ÿÎÑ”I$éHÜç~"mVQãªq¤.Ñ(uæ ½agè T \šôµvšÞ@QL´$±„Ìâ´cÉ{Z(ô²=9šú5Ò¤5’F‚Sƒ¥ Î~rR¾8ûè£3ñÍïï–“øìúj{&žß¼Ür•nš3ñåâ-=óòŒ<[l׫ߦŸäŒ³‰ÝIúkå©ÕãÇרfzÓ#TZÔzÂG_/7×7ëóåfúè£I|µ¾>¾Üb;ñÕ'ŸMâéÛÅëåãéÅô׿b/«õfûäÍb¶àLüm‘+J«3ñýêbûf“ —œ¾>Ÿ^__¬®^'Æ·¨5Ø$[B÷°ÛŸ´Ÿ!$¦ü3£loßõaFÙ€›Q»@Ï:”¶’–ïŒú8¶×fFKÕþÓŸ•3™*nm`FíÍå0{\!nF;bÕLFïã»´Êø¾Ì5ˆsyÜ7µfF3mÝ1šºÃ«UÃSfK½”©<Ÿ¬^½Z®—W$®Ÿ¬ \›Ä|u½½X¾š ˆN%ÄzÇ{±à>AÓd}´XðÇLÁÖ»Q‰:êvÇà3Å® öÇì3F±ÀEOEMCKG2â¾¾­d ›|¡—½¬èeE/+zYÑËŠ^V@O2ûm`¨txS«¤B4U<dàYÕh°¦sÍ“ ¦Ôø™-µH5—kø Ö Ô Õ|®‘6 /5~&K)„Rc µ%Qˆ¥%ÙH¬ªZ¥^£®Ub šZ%*ÑÖª¥ª«Us„Z%Ç}­1Ô*³Q˜RäÑÚÔ*ÁY¹"³LªT ÈÊ•"4!+WèX°Z¹R"dåJ.‘•+,²r¥™n,ÖàHÓñÓgØô¡P`úÈØÝaúŠòu¦¯h`oú²’é³hlg’œœI­à.ƒˆ†]”1stùÚîê8{•˩߇\S?…náÔLî4Ì– ÞŒn -«08‹†ðbsC4p¤Îfv$_§É{K§çÉŽ§—SäŒÞ7M@&Zòuß”$ÖÐ>ëtéêy¶ÚÝYwLìuÇ ºãvuöèŽo¡7¬òÿø_вÐÅ„¨©5å2„L§Wìß[üe8!jï«áôÌL|PxB ±?<â,šz@qz€³-<á‰ÝÉšPƃs6»ê³ûÆ®3)/ƒ:W48¨ŠˆûÑb €®-Ž,Kjˆ1 ùHŒ1|îíND´9+›´þ1FP%Ù’ûN-øÜŒh¡å…zÞK}ºfÈþpùpö'¥mf€$D}öGÇ!û“˜N壳@¤À¨¤ÆßL¶=áx€â´†öÑàMÝ ø?î6êߟaê±?~°5ùÏx(ë„mÑœEøPqÂDaBs1öþ!ç eö¡¦O8-WÓ%–[ê˜CÅq´9ájŽø½Rƒì!5ÈRƒì!5ÈRƒê!5¨Rƒê!5¨RC _<ñRØPƒØPÃØPÃØPCRe¨ah¨ah¨ah¨ah¨¡mmA 5hGj¨y?«æÚxû¬Ô0$ò{¡ß c¾ÁÈO€Q=ø£{ð ÆôàŒíÁ7׃o0Ѓo0C’̤3$éÀI:°C’쀶Áh쀶Áh쀶Áh쀶Áh\EÛ´i1ýÿçõsô&‘U§@û'dJÕEtƒ"¾heƒ"¾hfE|V϶It×V‘ œµ»µÉSÀHúÏN¹øýä|Óµøÿ]d“÷®¹Ï„ ˜J5È’ú€¨(½Ÿ)Ž27rFPPRùßÏÔFKy¿ìžˆ)?7±§í!¿/‹È§Ç´|gB]ø¡ìï1[D'ü99k‹ŸHp?ØôéyÛ}¸íP¶¶ 6ü`»(Ø!dô†ø×åvé¢ZcïW“£ìüj•Ò½PSž”î…š¥s3PÓ¨ŒùjÕp/¡K CMnQbjN·ykJÎõ@Í{±á‚>M 5¥ËÈú41@Ÿ&ötPšØWÌAib_!¥‰}E|€§B£¾â Jû 7(Mì+Úp|„Gwib_±¥‰¡fãh¼ì.Ôü!>‚šÜZì5™Héeh;¸4u—±pÝÁe,\“?Œ…kpMý0®™ÆÂ5ñÃX¸îÒ2®»´Œ…ë&-cáºGËX¸¦ ×ZÆÂuƒ–±pÝŸ¥d3ÔíYJ6CEþŒ“+Š%œì+Š%œìklA8Ù×h‚p²¯‘ád_cÂɾF4¤F‘4Dö;ÛP³¸¼Y“¸Œ¨k7ò оö²ßõö²ßõöjØõöjØõöjØõöjØõöjØõöjØõöjØõöÊ÷øÚ«Ðãk¯b¯½–=¾öZõøÚkÝãk¯MŸÜöÚöpÛk×Ãm¯¡‡Û^ûn{z¸í[ð¡xõÊnû|h^¿•+Í ØÜ3%eí©)) l÷ÁAîàÀ wq` ;ã¼§ëÞ,¶™¥»#Oh<¿ëÛ»FÍt`a‰vfÿp×ÿ¾4dÈõœ¶Ñ‚#ÞÌš€3á'À©‰$¬çíŒ+ØyÂwQÎ@g"g´=^Ña+ ÖpÆÓ`¨-öŠÞ€‰íp€‘ ‘‘-/¥ì\6”½GÔÈZGcH÷Ó¸Ó}„{6ßð‘±czµkÎM²¢êᢠN3Ù=Lãç"_§ƒ±pˆ1°ÚW®U¨/íIdÏèZRŠA©=cÐ(£#ÀJªm‚ö"¾õÄ@k/Øš‚zO¢lØ$ÿÐé°‡B+ßöÉй~ïÜ»~·ÜÛùšc àã]Ÿ2óuïÓrŸýŽx¨Î‘ÀM¨Î‘Öqh©6:/Z#0è…¯ ˜Bè…o…Œs)(|u•|u•|u•|„|}|}ž)ø&xè‡øøøTˆ]:µÝ¹í 2ÙmWhÌnÛÃà¶½ܶƒÛöqpÛAn;¨Ám=¸í`·ÝíçSm?Ýv·ŸG\uûyÄU·ŸG\…8¸ívüŽÝv;~Çn»¿cenÛ?¬ÍíøÐvüŽÝv;~Çn»¿c·ÝŽß±ÛŽ÷Ýe´°ë¶eç¶å>·m¦GÈÊNßg$¼ÐíQÛÎkpÕyí°z¯­eŸ½‘¡åjht×v÷Ð._:8ö€ýmKgµÐ2t*ÿû¿ ÚA`F ñ¸s¸6Ÿõin'ô‘=ùœ;0;gvÙ¤³YŸÈªÞ6gK.#ïŸßÞÎèÎÆò÷*|9ÕGŽAõ‘c¨ØšÍ©ê÷€öÀöƒÒç¡CûütHTuo»»á.]9²ÐÊ·lœaX¬4}ÿCýI»îÊw«¡„ÙÝj(±v¿rÄÒåïÓõûÿ)côu“i•  滩$¢šir¸%i?-=Óûé ·t„‘#ƒÐ['C8o€PU–>NÚƒ'@´™³ép;£tÌú0É/j7¡A">~{åð¡“v „:z®™Î…‡¶{E«¨Šü%ÝGÐA÷ÇÂ3òšÒƒ³ ݆uÛmXQ¿f\qmÃJqcÛ{¹“G;ëñ“åæ|½z·½^§…•Vã÷ŸúüËÿò…|µ¹¾\l¬ì£¯—¯o.Ôðrñµ¾_Š’§è ¢l.Ä7çË«í$q,Þ}¾\½~â—ï?Ý..Wç_½¾\Rõùvùö; ÎÄ?rsë|Ze´„ÿM|,‹'âñ©øLü‡ø\<ÿ)¾ÏÄ—âïâ+ñµx.¾ߊïÄ÷ââñ£XˆÅæ|µ:_­ÏoÞ¦òvuy±Äâv¹^m~‹­x)^.Öâåzq¾¼\¾Ú¦ÒšàâÏËm½åôà\œ__^_áõíÛ…¸×—81b)–¿Ü,.Å+ñjõëR¼BK$^‹×ëåɉ7âÍïïÞ,¯ÄJü·øY\ŠËåf#ÞŠ+qµºZŠ«›·/—ëÍêõ•¸×xãx·ÀuÅÔ¹”h¿[®iéÿêúB¼»¼Ùˆ_Ä/7ËÍv…,ýrs½]^¼¼L…ÍŠ¦wþ™[‹Ø,Eú›Õobs¹Ø¼[±}³^.ÅöŸ×âFÜ\] ç×ë¥øUüSü&~ˆ?–ëëO’þl…’BUŠ÷Q¥ž|þüùyòìÙS%÷ªÎ#TäGš¾¦%Ñwa\д¢íõ‚i„ ÈŽJôˆpÌ52ªW£ q5Ž'ç@Ï=þúÉÏx<~ÿpTBìþçŒ&¨;GsŽãY¢F]²"]‹Í­±™ûŒíÛOŸþøÃ÷8¶ç?Ü%+´P"ÐèÐÊ`\ÑF‡C=mtVÞ9º²Nß.¶on l=»Ë'Ù¶(ºE–×l^Nä²ö.·j*x¡¥Ÿ×q^i)Ñ:áeKk)­*^ÿl xÅÑÚ£´¯v¶t@‡@2ÅPÔµŒÖé=F² »v¯³[´3˜®Þ"¶Ï4…I^¡ÕzSÍTR¬whdÈ„lÑP4ëЙÍbD;2ll_'¤xÛ`½x/xDUy¼Ø,éÉ®”<}˜ýa—¹”r€}²Á>[Âõo®¿½Z!ìrþ(H;puËZì0eo3G(êzž`Oáþ<Ý^å;LÁm¦LÇ“é8* £xŽÞ7v8”;ñ¬†þ`$ìŒt»|;ù/á»7UêÜ–¬LcÛú= àö8¯¯0ÈÙ ½¾!§s†õ5[¸Pw_¬.pÉåošLùxÕ”74§œµ›2»SH “'‰)œbZ=þò ÆÛ\påNÊuFG©” ¤“> SÐ)ˆ“Ié4ÔIé”"è,å)± 2cÊ—Ù1þ!¤LÌc°)¾Æ‚ÉÄm—Ê_o¥_"€Ê_‚¢/ÈcÈ_1¡Ÿ+( ©|üñhRf • Ò¯dšyC™~« SðenóNቤ|цœñå_-È… y£Š~Žà!£ÊÀ˜~«!‹(¸Ryœ!fvòº8‘TYM*–y‹i‘N¨ë ×büé¤´Ì V«”ÂB^¹Z%ŸŠ…<·ZùŒJ«˜9ÖY?°ij[î¸LS§lûѤì@Jû̱Q²l)dš¦ŒÓ$Ÿv")“íŸ,"JÇY´ÍöC[ýQÙlß´-³d}é8+»ÎßóÆ‚R åŠdòwï°` (…¬õ:¤>‘T>l‹Ýä夡v³ô|Ñú¼í~"©¼…C¿…’Ç·&Š¢„2ÉMÊ ¤Bцà󆲄£ÌÒ‹eD ËòŒE21¯4#Sú yéí餌Ì1Å•6°`JÊ£ÔøDRZfÖµÎë쯌NH 1ŒV U¼º1¶ôçJ!mÉa!ä)µ.>€Tþ¶ådòÑ…y&­ÌxÍêüÒÏ8½wUO zRÖ&7uèm3pêô˜µ5ꌩTFzü G ˜¿š¿ó{"%•Oê§ßCÊ6ÓŠÅ$È,iþ¤Óiño'ek],§­–®X[­„}­àmY—¶¬š¬h:O&ÿºò7k–µeíÞ+E;0¹yƆÕEWKY¶ªÓ­.ÿ~³½\]Q¯äLÙ¾RŒ3•¯ðV‚º¾»Ú^.§úµø§ú]à6 rc½üu*_$_/A;½n¿ž¡ï—Ëß[·:3­3y°³RKí嬜6ÀÎÊ"¼«3;t¦÷uæZgúpg²ïÌ…}µ)·‡§¼¤rgvOg¶ À€àö À6ØÃ0ƒì>˜&sXf€Ý'Ó` À 0û`šôaèAfŸt€>,=Àì€nЇ è}PMê°Ô ½Oª @€ ö @5ÈÃÔ>È&yXr€Ú'Ù   þ TêLî@ýi¨§ú“Rwu6@Vü^Í ƒ endstream endobj 4859 0 obj << /Type /ObjStm /N 100 /First 883 /Length 1549 /Filter /FlateDecode >> stream xÚ}ØMn$Gà½N‘7pðñ'2À/0¾À,zaÀ˜…a ||¿»DQàpÑ­”*ê#¿(<©ì±k]ö¬kïËî¸Ä_qAå²}_ºn~µKoçW. ð_\®ÏûuH\æ÷¾Ÿ»Ï_×m̳¸0ÏpÉZ Ô›L5µKÄ©ë(3Á×ÖÅPp±r.¶`¬Ø‹¹ÂÅ! ^\Ý*{˥Ͼä6Îûè%œ?ÖÂûäXûá…\K¹W@õM·ž®Kƒ‹õÞ¼àb î7¸ØÉÎÅÁYÔ¹8&ïÍdãâ›ß)×ááT±“UÏ­c2ø°0CÏLྠUá܉êÍdábã+Ÿý«ónéò3¿ã9\0~Ÿ¹õ Ü ·´øÊ|ø§;4k/x‹×ÙåÁª€4¨ŸÁy¯…®qnú¹7Ü Ip8Ê1™$)“íØòaúàív&sƒö€ÉÜ /Ž nÐ×91Ü ‹3™t(“¹AçæÞÀ òÀ0™t &ó™îf‡èòà3„›ôxî£wùÞNÏûòÛq`/ø:ÂëàïàÅ­o²ßà9<ƒg:!^è92üièÃd’‡ñqaV8÷$<(ç q‚ˆ‡É<^±÷9ƒ\|;“y(y¨Ïñ¼¯½“y”÷â,Â{´yy„ãÚ8‡šwv“™§›‹©Â .æM<ÿÚ~Þ \˾ýøãÛ¿þöçïßx#o¾_Þ~øùÜÓ.ÿýŸ?¾ý÷Ïs³ïï?øãÛÿÞß ïßýëÛ_|ðù籟~*aòvßcß\ŸÃ¬ ã[á#Ìæ0”°Õ…i†­1lߟþÏYÃøF~…í˜Ã¬„¡ K€=ì°;€1DØ@$@ÌQv 3€€è<|ð€'€Ï^¼ð°À €w–6XðÀÀf-Öhè  À:M´h  €@;$f혤 @ :I™¤H °f€U¤X °t“Ö,¼Âôy¦°ó›Ü§°Õè÷þ{ó9LK˜ta–a2†Ýϧ°×œ_ÂÖGØ«Bÿ_˜—0mÂ^=}Âtû ðšóKXì`ïæMØN€=l-aÀN€=DØÀN€˜¢ì  f€(ÑDø à :OŸ¼Dà à3€ï<l°à€%€ÍV¬°Ð@ €uš:h°@@gí40 h€À €€ 3€t’2H@ 3À*ÒH¬`éVÌ%¬¥„_s~ ûÀ\Â(%üš³„!Ks £”°v%Œ,aÌ%ŒRÂèJY˜K¥„Ñ•0²„1—0J £+ad c.a”FWÂÈÆ\Â(%Œ®„‘%Œ¹„QJ] #Ks £”0ºF–0æF)at%Œ,aÌ%ŒRÂèJY˜K¥„Ñ•0²„1—0J £+ad c.a”FWÂÈÆ\Â(%Œ®„‘%Œ¹„QJ] #Ks £”0ºF–0æF)at%Œ,aÌ%ŒRÂèJY˜K¥„Ñ•0²„1—0J £+ad c.a”FWÂÈÆ\Â(%Œ®„‘%Œ¹„QJ] #K sØç¿ÑÑ•0ÖÇßèòŒ£ŸOÄ?‡5òì ³9 %luašaã‡$rþä5g »?>$‘;æ0+aèÂ<Ã0‡}xÍù%,ö °£„5’ÈN€=l”°`'Àž¢ì  f€(»ˆˆ @t‘>xˆÀÀg/Ñxø `À;K›¬x` `3€ë,tÐ`€&€ÎZ¬ÐÐ@;$fí˜PÐ d€@@f)è$dX@:€•kX@:€•s K)áל_Â>æ.üš²DeÏ\úW²ÿø1‘ endstream endobj 4860 0 obj << /Type /ObjStm /N 100 /First 980 /Length 4608 /Filter /FlateDecode >> stream xÚ•\ÛŽ·}×Wôc(róNFEŠ9’,hÁ"­^í$³3‹™Y%òñ)’})’EÎæÁp‹uªXuX¼sÖñ®ï¬íŒè¬ì˜Ôí;Î\gtÇï ï„V¶¶Ó²SŒuºï •î´2Ï DßI ª¢“²³ +ûÎIºë9Øàð§:n;ÆÀ‡º¸dï;&üpšgŒ{À£Ž)Ðñ‚þg5ƒ/åü ÀáK€£Êú/ ¥ð_P…vÌyÿc™ê™z_¶R…2ï„ ­é;a·b@©PU çq@‹Ô:|ÀõÞ£€4t§@ì¿L§ p_ÀR¯ƒ×iÁ=(¢¼ äy|yn¥§ÍŠÎ(Œ1áKy2½ -"zã¿LgU¨*›Ê—¹ÎõÁ„‹À„ï” _¼sVz]†õÌÇ`ÚËÞû Âzq¾¡l`Óh£ÞúŠœo.!‚ŸJ ÑX°ëzhΤòŸÐ0\DÔÆ5gþÓ7´…LOÚ:”úæ.`¡6È0þ >­Oßžh@2`P›¾ ¤dG¨8$Š 3¨MqëíúLRZx jS! Ÿ-F6ƒÚ´¾6µiÍC)Ô¦}„Òù„4 ’ >¡6#}:hfŒôQp¨Í8>¡6ËClj³Ê§›ãP´n(5!W%ÔæßIª€Úœö‰ Ÿ6~úÎÀ|C;H|ÞKé+ã½ö)á xï|×r²œ1Ÿ¯:ä¶ïwš‰3Ëܳï¿öÝ/Ûón„Œ€ÞýéÙw¯ Kâ×Çá8îÏОÀL,8Ž_ýþñaüϹƒTðÿøýï‘!ȳÉÕMCâ„!µâMC=24¹—b³!c[†ŒÆ†diºîlH6 ql¨' -d›&Ù“m²õB¶n’­1Ù† [/dë&Ù“­ ²õB¶j’­0Ùš [-d«&Ù “­ ²ÕB¶j’-1ÙŠ [.dË&Ù“­²åB¶l’-1Ù’ [.d‹&Ù“- ²ÅB¶h’-0Ù’ [,d‹&Ù“-²ùB6o’Í1Ù‚ ›/dó&Ù“Í ²ùB6k’Í0Ùœ ›-d³&Ù “Í ²ÙB6kÙÈ#¸^‘f6b+Ñ Ï¬b%‡XñÃp?žºëß¼9Üüöê<ÏÏaÔNt¿ùt»ùòÍa·Žöò§áæ_Wçãðï7ÃyxÌ WA^Çáüúp?ì7Ï;?Á?ø’=ï þ°ÝÇãÏŸÿ9ÞœOPgسO›ÃîåËW§Óð jPÁ•<ûîÝö~{ÎB*þ‘#¼/ŠÑÕ)¨Ï™Š,(ªBøÃÏ¿úzYH Vc¯N0‘¦ç~U×çqRžº­ˆ#$xî*u¯m{fâÍh‘c¾‡ÿ §»¥Á`ùéÚåAªZ8á1a+œ¬±5ŒTÈy¸þór{{;>‡A•'IËÿûß›ÿ°u>7wਊó~üáöñüx÷»‡Ý°÷Z5û«ÍæýxbFÀB\¢À´¡c'\'Ôɸ1dn-Á$íÂÒT÷qŒXÚIàî ˆ«áþa7úŽ­5Ö{´Éʦ6»Ù 'Pršì „ó tì9ÌsìíÉ×a·ÝlÏÞYÍÚo†õ"…Dç…YœÎ¶Ñ0™d,u3u>ToA‰¢f9+SB+Ö‚¨’gÂÉã%ÏK#ØUã.}N•ëÑžÖŒõ›ÄµÞÐߌÁ#¥)IðŠ#¥?÷›á¸ƒ’&%QÉ¢0m„­|-ÐÕ]J— óõp:Ï[YÔ‹ ¸$%Y:¼²X>îv!Dë²ÂhJ奫Göcäc©EG¯a¬;¶…3o¶÷ŸÆÍãM¨˜çÒy’.¼ý0n¿Ü}>ƒšÈ¥Wã—{¨v8o0’sgdxá°{{?|a¬gq!\ÄœGP³Ðˆ3Þ»¼.oŸ?~{»ãÛsLGÝÛ ¶›+1¦9§eAQ&$­M"¤®G¾øž©UÂÄép ~Y¢êbÈ”¦ŽºÏw‡)ƒôEX0‡—Š¯ïÆ›ýøÚ«[[G¸¢Y CÊ´i6¼øÝðm<ž|±¯;ÉÓT}Àm;¯î˜éyQàxìšË—Òà©íõqÎcìªqñ– 9÷»fŽºÀEW éÌì‹Ó¼! Ë8‰UqTW¹|w>zA§QÝPƒ–ýr¹_q~1†‚ b%IØ0$$¥)ÔÆÏû·Ç˜²ÆÈ:'e8uS VjÝig„g}ïO“Æàk L,âÓµU¾0pF@G Ü’óFæzUŸŒ{®IË9ÞÕ–ˆè &Ö‰Çx°édYŽø!žÛ4!CÛ'nâ‚6'€Š¡f„&a<ßÜMwnL'L‚2^¬œÑZQˆ9Þëy+Š”D%KŠ–ÙKÒw¥Í+Æh¦VØ2}Hüºã/£ï¹_AQL÷¶ÌÇÒP‚1©§½Ü',µÉЮ¥rÜuð.‰ÖxñSâ¶œFàø-y8£¨«×¨ÇŠ4¦¦xíåË–MœÍÊWVñÊ+´Rì³NY¢<$ ý–§îja‚ uÌ¢ð9M&VAN¹¾†¦ð e‘ãc`|RSæ",úC¦XÛN›œr¥¨˜Ë¼;…s¹>/]ã጖… ð«˜|XQøúåÝaØDɧ0Ò:.šá®Vèà2Ýõ8‘çò˜””õM…_-€52<£Ìb4‚(Éêò¤I.Ö.X¨0ðåýàïA…M¢ð¥!z¼àŠÓ¹Z%Ý#Щ¯Ä§ý$(V¦Tñ¼ÚÑÄh­ZÔÅ»lGòù\–㈖÷ãñ˸4¬ÆW=ï·'ßFŸöù2oYâMn(œû‹vªQá^®LƵÊU°®³zQ6i—y¿f¬ÆÏj½e«Æ¯[±l‰ÉäіÙ¡÷2‰÷UõjàTŸIžl% %Úä}~›¢ðæt}(2]ÞáÝÊ*ÌÞÛá[wÓCÕØ BjÚ¢¹ÉÀè ŸuÿÐêUâ8è½'Yž ¯(L¨Ïƒh]pú¸¿_ËÉ r"ŠxT…¶Ÿ¿ŽÇ]ì¸ëMÅ/–sÍÓ*æãa÷íËaŸ:´M© y÷"¿ÅXKc§:J<9ˆÖCša’OB«²Å£Æ¬·´ìemVjãC×Ëxa ¶;jÞ°¯‚egx—éuð‰–EE’æ§3BY%Iþx<Ìï¸ð&s*¾àÆ\¾ŒŸ°OR4à[Ūblqñ V §PJnã1šŒ-Êb *¯ »'(åŶ†aÈ~s¸ïjyòHh•Äzц`ŸN±ç“Gǫ˹ ḇÍ¿æàÖ$Õ­²à ~ª…Óo ¸Å{-$Šj†–Í3¶Å§—@Ù©ó5õFÜÄïTÅ4©'/c0fÚ’â;:,F¯Ö:SÜÔØnÎ|ú7•øjv.rTä2Ïý gõá|_’¢pN--Ã×IŽ›ñ¸š6´ «ÛKt[xÊMÉáßq¾¾œŒ'ðɃ#ú>˜ýT¼¿Dì\­×NøÇ0Wùõþ)ÁUq½äÈK- ÊIÃUqÃäJ×_^7«›¨U¯†¯cº½æa¤ ›N_+ |¯˜<=ÎÂ$WÔSÕ ÍD=wMïðBX=ŒâÇmz5> o@£Ù„ÉìÑÍ^#ôÒL…=òƒ¢]Á/’È–w…óp/ñ:~¸²ø¤dýY7ý²‰r+Vâ ?xN““)‘W[d’Ujn†OòIP4årÔ«èýáž™\†? MC¡Þ`c>cHY+úŠ'5®`oþau†M6âêÖÕS€á”·÷»íí7?Ò[èF€©šžI~û7‹`šÉ‚¸C$¬G -K=ÉO‚k¸èŒj—qML?.xA‘]2BSSÅGÿ\áßÇÃ6.A —„0nÂã 2¶Ý·_‡ãvø¼×wu> stream xÚÍ[k\·‘ý®_Ñ3Ù`rù&oàÀÞ,vá o,<¶5ÓšéuO÷ »G¶ùñ[uúźÅKidHGT±Èª:,Öƒ·å‹Ë³aæ‹fÁ˜™1#;3¡8¹™5l~fSÄl˜¹"âÌå’y”fÞÃ#ú«·éÊÌÇb‰xçydfÁYÐì,Ë»7 )bÖÏâp …YtCáQœEúÒ, ž· y–l$#”Y †×Æa–Rࣙ¥’yE´³ì ëÝ,‡Ì‘ œ-kJÆã0g¤7K‹iVbÁlž•b Ɉef“xqhè ï­! \ÃÁâ2C±z‚sȉ‡†–‘))ÒЖ Cb•S¦arž¤%’frae2I³Cà2I³€d’f]äed±ó3I³œ2I³Ù€—¤ÙÕIã ÀÍ$ÍÙ”Imœw¬²q!ó Æ%Ï"èü£Â"È!Œ`ýÝx;`Ió.²ˆBÒ|€f…¤ùXòÃGFÒÈ*r:Û0 $-8:p’´Ø3†/‘»Ðб’_ѤECÎFC’iFC’ IZL¼$-’¯½¢!IKÆ‘w †¤%çx_‚ÞŸ’´”,ïkHZ*–5#8M6 $ DC’–Iw’´œ «NStVf i´ÀЈ7³$­¸yÉÑ ¹?ëK^oÈØLKÒ _Òµ"MYu’n[°,Òn ùÑ0ÓÄ‘4Òß’sñd•¥óæetŽÖøÌËœ¥aL`à;œ‹ ;H^”ÀKÒ¬Mà%iÖ'AZ+IÈZ›cyõÙg¯þøÍüq±›}ÿ»7ïÖ×ßÿÙõ›»ùîáúÞíæ¿üáÏßü÷é¿ãÄãbÿ°¹»¢»8ȼ™µ>.w»åúþüçÝ|?¿~·%YzŸ2½Oèj@Ö¶VþåÛ¿ýáöa¾ßîÛ³_,Öûífy·mC¨ /ØæëÍjqû¼Z4¶1/Øæ›¿~õ•ÞÁò?¼úãWËÇåþåSeÿðêOê9C{Ÿï÷ê|¿Ü¬µ-®‰ÆW›û¯çO H  ñ¢Mν“ÙNËõ~qßÚ'¼lŸõóãb»¼Õû¤æ>5¤Ýô‰[NQ}§yñáýZ¥>äMØ¯å œèÚx=oçû+ζ¦Ã€=Áe?Äum®f>õ¸ðµG' ÑŸ°KÐÛäœïËáüU*}øt'6ûrùøfq÷|«-,/êß·ó§µK^¶K*Éâ 7Y,ïÞn¶Zó²_lçë;½›}ánOä óÕ<Îïz3÷A‡zÙ þj}²SM×6¿Ð!ÞÑ_õIR¹ý²mVËÝ^oòÂ|¿hëÒ‹‚/¨¹lö/Ù¨mRøT7šÔë“Õù8÷Aho"x}É#©‰ÌÍÍóšîùÏ7Ô¥Þܼ§2òíçÇ¿ü¸Ø®£ÿûüð'[Ì£ÿ¹¹yÚnöt”ºøËj1¿xÿ¸¹[|¾|‡?åvÿrmbL‹Ç››íb5‡¬*Ù…r%ÿ)T9'ý*¨ßÜ|ÇSþà8×oVoÉ9µ+¼ÙHç¹¥ý#?œ'üc$rÕE5zuùØãÿÁÊ4¯Þ|w}n·H]çªðWϱ~u¦su]ƒMœ`DÀt?h:6 ú×óývù3–5ëf©ysí”ŦSE ¯/HËë•%7§Ø¬œÚSgÞ^¿y^]ïç«w'uÖ—³‡WÍÊ1žVìÓn¨{œ§Õf¿úåõë*„T!óiKŽ¥´kÕßÊÆJVKLI§+)œÖ»*BTŸ5ùþyux^\üüD:íÑ%Ôpo›÷§ÇèÍÛÿ¥„G¶ÜeÙ§‰ØØ’é-š@léï_¿¾~ótKæúï?øXkß>2Þ>,n„G,×»=ùÄ‚ûÀlmÍÉ=^,b»ùãSm®Fn’Ñ>I;aÛ,ö; ‹ šÖî§×üå»ã`ýÌ^ï†:õO°Áêo4»w¬gaw›Ÿ&þA)-X)À¨Ÿ3;b"cvß~\œ´ô£¶mƒÇ‹ŽyW*ᆺ¡Ÿâ|eŒÀä\RhÀ:ñ”Ññ ôß,ʘ{ú¦3®§±ø˜mÛð>Í©O·âõîiµÜ_RyjÎ0®Á¸æÜ!•ûöÜaa½éþî²}h–økÖ¶%ÏoÉýð&R_P/Æäö”ªóI=y0'LLb©ðšÃ¬¬*›Õ÷Iåö²Ž•2‡X%»N"¡N"ÇùS…¡µ>_ ܯæÇ5lý úÌrªRÚM²2¡±¸gû¥Ò ^Ÿôøe§¶a?_®ª6Ô´fmhMU•WµêyMÀ‹»óKâñK܄ţOV£ÕM“ßÏWË»oO Û×îûÓ’ºN‰OÛÍ=ç}d¯ã‰Þ>ÌŸ¨Óü=P:}PY®ï?_D9Ýö'` 5Xblx¡Ï™[©~œ }òI£#‰÷O/G’e’”ï˜É3) R`’ºXÙ¾)#ï °‘ H™IF “lM2Œ™°•aÌÁMè¯*¾ ýxS›‹ÀÆ0\A h® ¹0MœÀŠ %#SÄA'¦ˆs& cÚê±ä3Û„v…××ÊtÎ â€ùzFq¾ìð1Õ„o[L÷ã ›BofLõ1ò½Œ©Æ‡o%ÿ{ŠÂø¤vô˜kœùŽÅÜŽ-ö qµc³DDãës ßFlíG|£ð~öï˜kÄønÅÜFì|ˆiB/†'×€ñ-Œ¹Œ/aÌ5`ðs ®â¸=ÿæ¤íb,õÄÔÖ‹/_,õðÕ‹¥ö0¾x±‘ŒŽH/ì˱ÔxñŠ¥—?×~ª ð‡…ŒO©1ôŒO©1ôŒO)I­}€ÍíÅŸ+€0UüÈGH°L"Sj€Ž©(¦Ôn"SbS±pÎûa*í‡ÄËk4BfJíQ¡0¥ö(vC|#Á“DÂlñD¾çt§²}dxD² È ‘á)<2<"µF†GäŽÈÇvôç$§r|ÌÜoY¡Ya’«­g¯j T£šØæ‰ÀÏÙ=M%÷ĉ¸Ÿ¸vt"M¥R HŠø*)ÔgŒDÀHßÚç™Î±,M%¥Ä>$ò _Cá1™! '3D"yg@TkŸauû8Ó9)婤”Ù‡DÂÉìC"ádö!‘p2ã“k¨3ããEèÉlr¶MÍò9+婬Ä9-ÖûÆG$œbð<\kV ‘ƒ $ºÂÂnRû,Ï•©ð_ ‘„ ªA,¨±pXI£ðµ‰'ÍøSêr³þ=zÖb'”ãÜTs* «É_мڞS¹ Z¬=*º=)º=+z]=¶KÍ䂞œÓÎßV+zbúÉO+zÆÏò4ÝŒéü‹;«@2O;¯ÔK.èa€ùÉw+:0×.`€yVga€yVga€yVga^‰Óf 5 zfó¢Åg|—W˜sQLt…¹eÌ•Ñ\”·Utºë‘®F :Fp]O½’ï@W˜sMte4ïDW˜s O}—r).䉦Í@‹-ôÌæ^an¹W˜“uūۋW˜£Þ÷^9¬xúWTR/¹ c„æA«Ìõ¥wÀ¢OX! ÔÍè2õ[¥E—©ßÓ,ºLýæcÑ.}íÑ.– Íz¡cF’Hê  +A›©[~‹6S·¥ýbQï(ýbÑ÷ýbIû-/FîV è2‹ÎÒè2‹ÎÒè2‹zæ°h‹ú*cÑ.6‚px{‘e Ò= t™Ew è2‹z¶°è2KQÆ¡],:Há{â ƒTÁ¿îíÝî"KÒ-A¸Ë´ƒ¾ÝÜeÚA_cî2í ¯1¾;êó/ã”ͨކλ&´üÓ8î2í Þ&w™Ôëiº=(º=*:B½›ºáðϬ§ß¡œü$麟$Ý€ƒPÈ 8ˆX‘4?B•ƨŒ§É@/ÙŽò,ºß$~’;¨Ç gº*4œèê ÇẃÊôÎtÕö:ôÊtêvò›¤ë¾3;ülw(Z]€®"‹ã6“Zl¥–èV‘°«Ãà†‘è¾c…¨]÷£¤ã¶ÐõQÒq+FtåéÜ/]y:×´ÖXÍA×ü ôÎÍ «ë~”tœ[h;å  «÷<ôtƒêœèú8€îÔY; ×ù*édÒsݯ’Îtv@×aÇtv@W…Œs]ÇôBçfȯ’îôUòÿíaQ@ endstream endobj 5040 0 obj << /Type /ObjStm /N 100 /First 1041 /Length 4135 /Filter /FlateDecode >> stream xÚ[ÛŽ\·|×WœÇlà¬/Ý$Ã@`ÂaÙ$Äy0ü0Zµ¯.ØYÑß§»4”—Sgˆ¼Q­CvWñÖÅž•5µe]dÍa ­z#.©o¤EZöF^J Þ¥5|¬K_—%¤ŠÏ뤊·ÚJÍOd•Õf“°ÄP}‰KLE½•–(Å{H^b)É[²ÄVÐC—´y«,))zÔ%‰¢G[ld>tµxÕ{hXrPÏþ™“x_MKñø4/¹ˆbä&ŽÌ â~Õ>I‚¾K2zØ%«ù(«Sáÿ[¢!ùȤ¦äßYà*ÉG.yÑ’|dƒ¥-ùȵ„äÈKYJJ¥.E¢óWÚRJ,森Ærô¾FS Ñ{u5EïQÓR%xš—Z‚û5²k ÎFÕ¥…€¾ei)86=MFiK+«ã°É³ ô6Ÿa «Ø¢5Óê}Z²fnÏf>Žª‰5kC7ŸxÿÌš6ó!6t³©+Ãú† µ=‘°®X$©yZBô(­iÞb4âÞC̆̚æ-ªQ`MókA7ó–œ@kú:‹˜·”}X$ÖT1h•/Äìãè×½iÞrŒî"˜·œ|v©³¯Õ`ô…¬«{ æ-g;½!׈oÍ›­XÍ›¯óf_›ïfeK(¸‹hÞÄÜyÓ¼Ù2òÐmNƒ€ÉÅ÷HBÓ¼IsRC4oŠ…kÀ­}ŸµÖÌ«m#ãÀš¶‚ZÛ›æM‹¯ò` ÍH×VŸíñq“y+¾Ë¬iÞJðÕlɆVóVRqoÉ÷l.íÉW_=ùò§Ý›ýqùõoÇýÍÃáÝÛ¿_§Ô®lÿÚ[—çË#{¾òµ“ɼâóHö{"{„½=Á^ÝþÛ“/ŸÞ8°±ÃoO¾þúŠœ}8Ûšçnv%»ÂÎaØÙ«ÛmŸÛÁ^ —axdc‡ qÒ™\é•í ½éÒMž€ôF, Økz…\}?áœÇÀÞsß±çvç<&ZRagÔ vGA^š€Qè „:å1“s °8°µš`§¨vZ€ òd2ÙØaœ »çRÉÎ…Ö¿‚s¥õ_À9±QÀž¶ ½:ë0AQ@zaï ½ÐÊ) ½Ðä^hå^Ø›ínlì0ƒÒy^9,'=­Vé´ÔêŠÏÙîì¥8CQ®Î:LPÔˆáEM°ÓJ¯NºßdØ“nGÙ ì“ýí‘f0*†£PA:¯ôÒ ]é< ¤o|ö>݇PÔ«³ ¤+¡h Wzé¼ÒHçû³t¾?Ø«“ëÛ#;Ì`€ôz~숶žÏ„g a%hyÅL4þ3ÑÙ1-N ˆw¸ Á²R Çaa&è.Î+f‚îâ¼b&Q±úLä 6*ìù" D6v˜ÁhŽÂ ½’yÅçJö{!{„Çqör˜¡'#ÌÒAÃ1 ÃUØ9\8\h’Ø›µˆlì0A:y‰ N`ó ;¡ˆ =ŠÒ#öÒÅpÐú÷3à< s¡ÒAï0A­™­(hÍÌG0´fæ#¢Q6ÂØÂ>‘ÃÕY‡Œ‚áh2 5e¥5­izþÜ. ¢…h”H¨!%ÊÅz‡ hM!õ–¡5…·=´¦ð¶‡jÞöPÂÛªQòe¡„ÈÆ3 78Ħð†UNŸC6 ïcÈF¡W– Ù(%NP é w˜ €ÚÞÇP›ÂûjS(íËþä{né¼ï!e¶ÁuLBtš„@mJ¥Q@:›A:gÂ!d£pFÙ(“Œ&( 6•7&Ô¦òÚÚÔ xv†ç¤k`x öÉõ]Æ$¤L“ ÒÉ;Ô¦&Bµ©‰P@6jâqœtÍ„²QóŸ1ê4 ØTzÎɛʧĦòiÕ¨¼¿¡•÷·«Æ&IH“éL@k*=fhM¥·× ­©ô:“!•³ˆFUš"ˆF­“£¶IH›&!КZiå@k*ïzhMåë¢QéºçûeÂlO´!‘Y"š…fR³PB!š…d„@3’ÍèõŠs»À~";Ì`(†c® ìD,¤fI ¯Á~~Ðy¢¼Nsn{©LPŒs¦“©YèÀHÍBŽ@jªH4cQ¤+öÊå½ÈÆ3 Þ2R³f¤ÓUïIOtÐ 4c©l{5MP Ù w˜ €Ô,´·R³ÐÞHÍBW·@4ºº¢±ÐÕ-uÀˆñê¬Ã FÅp´Á¡5+oðÒi. +eÕX)¨Æf(†KÏ;LP@lV*ÄÄf ŒB`çpv¤óñÕXãdg¤tuÖa¤GšsˆMº¢b³òyÕX)Ѩƚyx°—ãÅ ÊôA 6+¯ˆÍº¤g"ª± Ò…Ç{rYîÉX¡”i"›¤Æb³ -ˆÍJï ÕXIV TcUìéåd¬íÉ´B)К•zhÍÊG=´f¥ú“@4V>³!+ŸÙybD1½0 5+_š•JÕ©Y+ ÍXùf€f¬•ÇyõòS­ŒJ™V(R³ò‰©Y­(HÍÚè0‚f¬æš‘ê0ÍX[› “i…R 5¹V!š/ HÍÆ74c㛚±­ŒNaŸÀ+”2­P ¤f£7#Ôl‘a4Ø 4caóŠÏ 4cK3c2­P ¤fã“R³ñI©Ù8g‚hlÊ߃tåïÁÞä2V(eZ¡hÍÆZ³ñ†…Ö¤Ÿ´Tcã} ÕØèUT [›\c…R¦JØl¼]l¦•“›ieíãúÌìĆ«F³3öÉdŒJ™V(ÅŦ wήÕ(aòó/Ä5‘yÅ•ìÁí´þÔecZó Âè´B©®6ÓJ™†®˜ ºÓuÅLdF‡™ §R]1™áa&ÊåkOÇ ¥N+”ºb&hûµg¤ºÒ©r©¤Ó«‚N¯ À^ËãdL+”@:m ½1:ÞH§r±ºlLü@­.Óé uÆX¡Ôi…Òs #–Ž«ÍĆêj3z²Tg‰Ÿ Ôec TòP—)LÊÅ:´:­Pª‹Í£PØiŽ\l&ÖØÁyæhÁ9o­àœÕ Îùl obLB¦3Ñ@9© ”ó‘Ú@9© ”s2ј8™hL“¿&ѱB©Ó ¥Bk&zThMþ5¬Bk&–$‰n†â¢ñüãÑ8ynÖ±B9}*š©fr‚‰ ã·@j&úaG¨¢­RöSB[ÐæË©`Ë“Óé S£õZKÐ +¸íhœÇ´¾ N *Œì…ɯXÆSiz(UŸãóT1ÇT«`™Š`,S Ì£¨Âí§‘™/? ‡Ñô,òøró“(ð%æ‘™Ï—ŽŸCþ'~çæó9fm“‚ÑxÍx÷}nãŸséPHT÷óÇÌô5(¦7¨Šé ª®xyçŽgÏôèià˜þŽ)ßoà˜ÒŽ'Ï©ãIÒñùÃá•}™ëiƒY#öFêÜÒ”|ûîæ/v÷æçùïo¯ÿy<î>ÊõóW»ãíõÍÝîx¼NK°öF;5Nµ—Ü‹-¹òoæÈÑŸ»»Ã«ÃÃÇSßÜîoþxúÍ–çÒÁ•®tp§Ó>×Ò£+uË3F¶û¸¿?ú¬vŸ÷ïÞo:ìÀjV;°Ú¯=(N¾?ýÝÏ¿œ<}{xó|ÿêà ûªJíPj‡R;ѵÇÓÖ-_}ðÇ3xòûtÿðý›ÝëýÊÖ1µŽ©uL­Ýztüç‡Ãð/öîw}=}|z÷îåînÃe‡Ö:´“vȽ:cЛk¨~NÞ~Øüê„ü2ÍíôÞkÜÒÚ¥76×ÐcG/Þï»;€?Åñãáxói…oxï(CG:Ê“ð¶F0l.¨¿†—“Ãç»W‡Gv:°Ð…ìtÄæ~ùåcý¯¡?SübÿúÍþíÃÎO¤a‘‘ïØaÅ+vX±{|qsM]röW4Ÿ¸¿ûøËîþ°{y·ÿn¿{øp¿?vz8ªŽ?vü±ãO}BRrŸÉÜ#Ï=rN&ÿ¯06føÎ'»ãõÓûÝûÛëw÷‡ÿnىʨÜ'6÷‰•„%ààã§ýáõíËw÷'߯o&§ˆt.¤s! é³(=8)[Ž;ø¼¤ïöo_?ܯ¿1Zîß™³ סt„Úöt =óF•ó±—ÇüŸ8îþÜ?ÿö»íùDëùDÓŽ¯'­'ÿ¤cïN³|øýÔxûáîîäùÃÛ÷»›?ö¯.ÍuÏ-ZÏ-Zé({^Ðz^ÐÊæ‚D¦ñóËÿXJeNßã:|ü ³Ï®:²žL´Ò‘õŒ õŒ ñߟ®ÝGäÌ­×…s¯øZ£ÇÞÖÆZã¦î@ƃqÏZë÷û¾õû¾µ´éå´Zf=7h=7èåcktÞúõÞø'ŸÆÃÆdÈzʬz#öFêÜ—Um”÷øgžŸ]i¦ôFívj„Τ ÆŸÖ„Ç¥÷î+t¡ƒÄéÞ¶F'\»a¬Ç˜7|u¡£ˆEì¤ÆϤÇJWì/áÿL©É endstream endobj 5168 0 obj << /Producer (pdfTeX-1.40.27) /Author(\376\377\000P\000a\000u\000l\000\040\000H\000o\000f\000f\000m\000a\000n\000;\000\040\000R\000a\000h\000u\000l\000\040\000S\000a\000t\000i\000j\000a\000;\000\040\000D\000a\000v\000i\000d\000\040\000C\000o\000l\000l\000i\000n\000s\000;\000\040\000Y\000u\000h\000a\000n\000\040\000H\000a\000o\000;\000\040\000A\000u\000s\000t\000i\000n\000\040\000H\000a\000r\000t\000m\000a\000n\000;\000\040\000G\000e\000s\000m\000i\000r\000a\000\040\000M\000o\000l\000l\000a\000;\000\040\000A\000n\000d\000r\000e\000w\000\040\000B\000u\000t\000l\000e\000r\000;\000\040\000T\000i\000m\000\040\000S\000t\000u\000a\000r\000t)/Title(\376\377\000S\000e\000u\000r\000a\000t\000O\000b\000j\000e\000c\000t\000:\000\040\000D\000a\000t\000a\000\040\000S\000t\000r\000u\000c\000t\000u\000r\000e\000s\000\040\000f\000o\000r\000\040\000S\000i\000n\000g\000l\000e\000\040\000C\000e\000l\000l\000\040\000D\000a\000t\000a)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20251211163226Z) /ModDate (D:20251211163226Z) /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.27 (TeX Live 2025) kpathsea version 6.4.1) >> endobj 5141 0 obj << /Type /ObjStm /N 27 /First 258 /Length 828 /Filter /FlateDecode >> stream xÚ¥VÑn1|ÏWø‘"ÑxmïÚ–ªJU+!¥¨ñ€úpMŽ6&U/Eôï±/)§³¡os{gf×—1“ÓJ+&giŸU†8§¬±°r–2Å6fà•ärAyvDÄ$ÀZE¯' P.˜+r*M!—d«ÈÄ\3mJ̹(³J›úu’PÌÕØ+’˜™8( ÔÿE—¥ŠVFsæÊZC~g”1’%IÒo}–"N×+V†m¿N”ݯó ™09:šLß/æúÆÚ¸Ô‹K•€1ƒëÉôÃâ~±Iû_uíl³X¯^jï1\OŽTVïʤÎc¹Nõ>•5Tà‚ &lÜÎT¹¬1.vc.ñâzé ÃA† u.æWð.ˆg4“á‚ÑL†vu®0—£Â¼...Ídè]årƒ:.ŒK`B`B`BÐT‘:¹Ba\MõÐãëGÃ…Á¸Òç5æòpááÂÃ…GS=ôøúÑ`ò.W—‡‹.º 'ÔÆðr(Œ+ÀD€‰M ë'ƒÃ`\BvÌa"ÂD„‰ˆ¦Fè‰õ£!ä\®0®.âÎi @õ£!n0.ñãq‘¶¨ã@<@ýhÈàC.2ÁÁÁÕ= ÊÆBY‚‚‚‚‚8[ÏÞ\mšÇMâ¹ü¾:|×½]®ošeú ôè7bÌè`ï?¤Û×»Åìî´].»Ã“®kžÇ¬ÈCBò‡d ÌêëÉUûôØÀêÓê¡™ýlççÍæqñ{L|$ä#! ùHò¬”¨5ËÅüâæGàþ ÿQ„„$$$!!·¥ËíUilõÀ¤KÊ¿¢’„„$$$!!ÉA†‹/ÊÒÿ!!! IHHBBCó ÿK_ò‘„|$ä# Ôl£®ö%üÝ’˜ÿP‰D%q/R°_ã¬íÒÂþV™¶âíçç‡VMO›M³\ßN¦ŸšÛ¶S)û.L¦O›åbµ}¶¯>6÷m·½“öÏyËùzÞN¿t-–§íê¤W¡xÀ™ñ‹Ïè endstream endobj 5169 0 obj << /Type /XRef /Index [0 5170] /Size 5170 /W [1 3 1] /Root 5167 0 R /Info 5168 0 R /ID [ ] /Length 12523 /Filter /FlateDecode >> stream xÚ%Ýy|cí]ß}˲GÒÌhö}Ÿñlöìû¢Ù4û¾zvÏrŠB –mXLž@CMü4d ”E8@xPB!}AMÚðÜR §ZBZ” )­›Rn‡ô¼üó¹çº$Ï÷:ºÎ9¿sîL&“ùrG&Ó‘I2™RúŸì¢Û™E³Ëô%С量¥šYèLûjY}K4sÐ¥o¾ÅšÝ0Gß}‹4óPÐwWßBÍ"ÌíÈtöæô-Мóõ-ÓWÒ ,ÐwTß|ÍXÀ"}ôşŇ§kÕ9ë7W3V|™¾íúâ#—à }7õ4Wª´o&£/Vw5¬Ñ7Wß͵°Nß}ñU×Ã}Çõuin„Múâ3b3m†-úêëÔì­™ÜÝXçØÄÛ`»¾Øš;`§¾úBO/ôé;¨/£¹ vë³.o¿¥¹öê»£ïµæ>ØŸöMtè{¥yê[§ï¥æ!8¬o‹¾šGà¨>>ÞÐ<Çõ=Ð÷\óœìÈtõئo?Ó,Ã)}sô=Õ< gô­Ð÷Dó,œÓ·IßcÍ œ×wXß#Í pQßy}5/Áe}×ôõk^«úžê{ y ®§}ëõÝ×¼7õmÔwOóÜÖ·Sß]Í;pWß>}ÑŒ7ß×wRßmÍø ~}œ¿‹Š•L×¾«!÷oßÔŒ/øDßB}±±qžéÛ«ïºflØ}ÇôÅW)/õ]ÒwU3„¾Ö÷\_|}a˜J{îRÝ:½pYŸ4Muè[«Ïö›’Ä©N}»õ]Ô”â©.}.Û~ʘš£/œ×4z¦ÒaÕ=ây›2ò¦æê[¢ïœ¦Q;5_ß.}œOìS ô]ÔwFÓ`ŸZ¤ÏÎèmy™2اÒEÍÉÆ÷8¥i°O-Ó·^Ÿ¬MìS+ôí×wRÓ`ŸZ¥ï‚>92اÖè‹×4اÖé‹(ãSûT:Øç ôÕ4ا6é[®Ïø˜2ا¶è‹sXÓ`ŸÚªï>ckÊ`ŸÚ®ï„¾ƒšûTšµ9“‰>ãrÊ`ŸêÓggôö~Mƒ}j·¾ø\czÊ`ŸÚ«Ïïí½šñÂ~}á2Þ =¨ï¾¾Ýš±BéšæwÌ׋/sT_ Î>ÍØÇõõè‹U‹xR_Ÿ¾š!à”¾ñµBÞ}Wôm× ñçôùqx;6I„æ¼¾gú¶jFàÒXäGí,ߎÍa½¬/ÎMiŸºªo¥¾Pa¤L]×Ûe“¦Q6uS_d-4¡S·õÅÎrƒ¦Ñ=•®ZþïlDÀ`Ÿº¯o±¾ušûT¿¾ØAE| ö©GúNé[£i°O=Ñß7¢g°O¥_µÐ?Oß*Mƒ}j@ßf}[ƒ}꥾Ø­Ð4ا^뻬/"Ÿöä}é`_üùŒÞòÂ2} ¤ƒ½PËë[ª™…N}±7[¢™ƒ.}§õ-Öì†9úb°/ÒÌCA_l°…šE˜«ïµ¾šó ÍU±;6bI3°@_ˆš¯ X¤/¾D_x®f¬ø2}±'Œ\+ôÅú4WÂ*}ñk«»ÖèÐ7Gs-¤‹ñË_u=lлKs#lÒçW÷íØL›!^q:‚Ù©Ù[õÅòboƒíúVéëÐÜ;õ•õ…ž^èÓwCŸ)ÚûvÁn}iô¾ ¿{`¯¾çú^kîƒt°ÏíËè{¥yê+è{©yë»©ï…æ8ªï…¾Ícö¹#‹õ=×<'õmÔ÷L³ §ômÓ÷Tó4œÑwQßͳpNß}5+p^ß+}4/@úgs›«ô=Ô¼—õ­×ׯy®êÛ­ïæ5¸®ï¨¾ûš7াSúîiÞ‚Ûú®è»«yÒÍ{÷ }ÑŒ7ÇRbññ¹±B±¦ñâ»Å—Ž­›)¶ßë$Sü¹0›8¶}|ËM°â .ƒ=ìÈ@]Ð ‘«·’Ì‚÷ū޼æifý+Ÿd¶¼sù›0à…9‡a.ğ͇,€…°ÃX Ë`9¬€•° VÃX ë`=l€° 6Ãè­° ¶ÃØ ½Ð»`7ì½g?€ƒpŽÁÈ%™5Çc vÀ± öÃ Ç YX ¡ßq@6Ã5xmŽ^€^8 ×á¥It zÀüùî “Þ ¬˜?ß³¯žÅ°öAÌhMý†WÀv8 wLÕ²0vƒ77ùÇᜄ2œ‚ÓpÎÂ9¨Ày¸á\†+p®Áu¸7á܆;pîÁ}xýðbÕÃx Ïà9Dô^ÀKx¯á-ÁŒˆ&™Yph¹Èq㢈üÑ$³áM¼/gzsÖ°ŽÂ€9aL {á< ˜¯Å„ÏÌ({î™_uÂ"XæCC¯M€ °ÌÍ&ï˜tal†˜]‚‡¦ ”` ˜¦ŒšG0˜o,L2'+ÿ:7üþæa£/“G‹Š0æÁ|(ÁX‹`1,¥ Ï‹–à X «`5¬µ°ÖÈߛa ôÀVØÛaì„^èƒ]°öÀ^؆բpŽÁq8'át'™]ÃåAâ<˜ØÔºa7”á¼ôÿì~f»Á9xæW· ü†Ú ¥©8½ŽÃ5xêl\ƒç~XJ°ÎÂ#;ý°Á%;ýXû2œ‚ÓpÎÂ9¨Ày¸á\†+p®Áu¸àp’Ù÷îØ·ì®sþuîÂQˆŸ÷÷á!<‚ÇðžÂ3xn¿&Rµ8¹Ò­¯?É}G|Æ x¯-4¼~5¯Ö|FÍð«ÅIëRëò>vú¦Þn.kúfx¹»Iæñ{c\àš×¸&À5® pM€k\àš×„°&“µ9IæÒÑX”<×ä¹&Ï5y®ÉsM”k¢\[ïÃÍÂGoÛIÛïÞ½mG›Øž°3ãÕŠ½À+~‡ýtËxMîkr_“ûZôÉ}Mîkr_“ûšÜ×ä¾&÷Ò™­É}Íö3CÎÖd£&ÞµIæÚ§â+µƒ òµøí!´fTÔäªvÂê®·öoù×Zð³Ó»ÔŠ¿eÅ_s­ø€¿`÷•n«…ƒŽI!J&k2Y“ÉšLÖdÒ¤<[“ÉšLÖd²&“5™¬ÉdM&káRšjå$sû‹±ö¦ †_¶vîüÕĶÖ’X‹óv¥Ù80ÞgíXñÅV<¬a5‹—ÓšœÖ"§ “†x¶&˜²µ·,ÅpoAz’d,º æ@üD÷!Î"΃ùIæã/Bœ"\ ’Ìë©xa‰ÍùÒ¿–ƒ3½+Áù¿ÞÕà¬_/Q½ÎëõngózÖsx½=°¶ÁvØ;ÁÄ¡·vÁnØ{!¶Ú~8§a]’ùÊÇú‚Ãp ŽCÄû$”!¦°x¦yÎAÎø—à2\«`žÓkNÓ“"ƒ½÷[½wà.܃ûðb«I2_óW±¦á1<§+ôà…ŸÔö «íÛ}ýÊÆHÛæ…•p’ûÄÁ›ÒäLG6+R;¤)>×´¬WTÆJþõ*É|㱘¹ ÍX'ä@TÆDeLTÆDeLTÆâsEeLTÆÒ¨ü@+ *c¢2fb8ç—Bœ9–’±8_,%cR2&%cR2&\cÎÅÀ–—1y“—1~ÇL4ÇX#~,MâwNÄç Ò˜ Ò˜øŒ‰Ï˜øŒ‰Ï˜øŒ‰Ï˜øŒÙ~c²1vLMǤdLJƤdLJƤdìר’1)“’1)“’1)“’1)“’1)‹Éñþ$ó½ß«+/cR2{`)“’1)“’1){b1&cb1&cb1&c/€Õ±W¶&™ïìƒf³õjg¨éJ2?ÿÃñVgâ„=3qšžŠ™89OÅLœ’§b&Nĺ34Τ?;?{•9˜q¹aF¤f\d˜†a˜†a˜†a˜Ynä:gòÉ›!oÆ^`Æ^`†ÆgˆšY™dªŸFè ¡31 „aÆ^`FJfb¡R2ÃÌÌ‘$óãëâÏø¡v†Újg¨¡v†Újg¨¡v†ÐBg!t†ÐÃ~†Š™ Iæ§þk,Þ`†ÕVgXau†ÕVgX†jg¨¡væ©{®Ã5¸ ñ‘Lϼð;òž'™ŸýÅøÈpGY~ï:zº›€–ÉmIfò»£¯æ@ P„¹0æƒÒ»ë & `#¬†44‹å-€…°ÃX Ëa¬„U~pã}›`3l=°&É|$ «7Û ®ÙÄEš^ˆK3» ÎL²¼CökNîè5“¹`ŸxÆ[öÁYØ›d~íï¾þ8®ÀÜ=®»Ü=&wOBNÁiˆåUà<\€‹p .ø ×à:<‚~8—d&ÞkpnCÚ»÷á<†'ðžÁs€p˯à5ÄŒ'¼¥ãü7?GÌYè„tçœOp>ÁùDQ¤.'™æ—ãÏ8Ÿp>Aè¡DM:Aè¡Ë€Õ V'XXb1AÙļ$ó{ŸŽ… Í„ÐLÐ=áb«iÙ1nÓMì~'øàw‚ß Ü&ÄbÂe¶ .'â⃬NlO2Ÿzg|¡qIÐ .'âÊYÌ t‚Ð B' t‚Ë .'(›HEýç%±ÐX?j'8Ÿàw‚ß CòÍaßñé(y¬N°:óg³ú‰»ÀÛÄ$óçï‹…Ò=!A@&ˆŸ ~‚ø â'ˆŸ ~â•óáãe’ù‹ßŒ¥¼¥Ï½§œäèé„tA7ä¡E˜ óÀ‘ž, âb’tÿAFs ,J2Ÿ?Í%°–ÁrX «`5ôÁÚ$ó…OÄ_¬‡ °6Ãè­° œ§éÙ;¡œ¢éÙ{!®sîJ2oÏ%ï‡pÁp¶§ç‡×COC\= ®7ö¸Ù“ÎÑ¿< ­Àˆ+ž— ®s^¸ºérfò›#¶Õ8ñ·Î2õ¸jÙs\«ìy®Pö×%{\ˆìy.?ö¼{ÂyœìbzØŸ Ç!ÝÃtÓ=L÷° ý.UÔæ8z71t"¯8Ý‘$½‹¿•ƒa·ç$ÉüEŸX ‹Å°X ‹ÅðX‹À™¶aaa.‡KI²dY,J"†%bX|†×‚tÃÂ0, Û@†·ØtÎà ËÁ0—Ã[“dÅïÅ¢$bX†åjxˆÅ°X ‹Å° ËÁðaa’‡%Éš¿Œ¥ð0 —A†…a8>—·a½‡‰&~˜øa⇉&~øÄÅì—°oA\¸&oøl’lº®E`8.W‹Àp\¤ŽS“œs>ìçýMœŸä|˜óa·9æ|˜ó†…68opÞGÏ“dÛâxÁoÈUcðÛ ´QL’;CñgCó’äàªhì ~ýþv¹ÂÖÕ ¶AmƒÚµ vƒË— .\6¸lØ B 6V&É‘—ñü6 ö†€4¶2ídáÐa`ºÁoÈoÜ ¹A²Ky]íIrâcQt7œßmÐÝ » 8d¡qŸýû ›³AwÃØoØo8ÃÒÕ‹†±ïŒaWãt’œ¾‹†4D ! öì7Øo°ß`¿ÁyƒóFœRfºÁoãf’œûŸ±<â÷©=æp=¶±ß—Ô6ú“äò¾x³04¢0á)Ä—‰úah¼ôÃz^'É_ˆs´ D5Aœ·znˆ*<¨ xPæ:€%põÿÁBp¶vrY’|ÕOÄ’ã,É2Xa=,I’Ç»ã-+a¬†5°6ÁfØ=?ïÛ ~ 7$ÉóÄRvÀNp^ùAì‚=°öÁ~8á\Kp$I^½?–wNBNÁi8gá\€‹p®Áu¸ŒÜ‚ÛpîÂ=¸ Â#x Oà)<ƒçޱù=—“dðÏcM_@X}¯½…ÐqBdzà$ÛxN|Ž'É÷ì÷g㬎GÅ«ãQçÁêxTw°:5¬Žó1Þ$ï¸Ëê8«ã¬Ž;Å?Nã8ã4ŽÓ8¾6ñㄎ:Nè8¡ã„Ž:îÁ8ã4ŽÓ3¾>I¾égâ#w—ã\Žs9Îå8—ãÂ0ç´\d?ÇÆqÇi§qœÆqÇi§q<Î@ÆiŒt/ÿ>)ã—A@Æùçwœßq~ÇYguœÕqVÇYguœÕqVÇYguœÕqVÇYîà"ÆÛxú+þŸ‰çr<\¾åÕ $Ð9èJ’Ÿþh¼àrH¶sȧ,€…`pfC”Ḁ’â›å &›þ€¿ç=±Ð•%7«! mÖÂFP'“íW`²Û@MLv¨„ÉöBœÚG`s’¼÷Çâ÷€ª—lœ;(}oŽƒ®Ãš'y=Õ<Çᜄ2œ‚ÓpnÀ58š$?ô…ø´sPóp.Áe¸Wá&Ü‚ÛpîÂ+¸ž$?ú«±¼~xà1ÄùçCœ¹à6DòÉC«- ªl’!§Š‡¸Z›$ú¶XJÔP±?•S›A†¢@J†¢,Šø!⇸rQoˆî!º‡öGC;“ä#ßK!: L1=DòP|-’‡H"y(~÷YbuˆÕ!gÞ‡¨¢v(¾µCÔIÄsoâÄå 'ìÃG\jdz(ýÁø†X!¡ûð8âwèn’|ô·â}"0$C"0$CÆô ‰À ‰ÏdX}–$¿Ý+“þ5)“1gSrIò¹sñû“ìO28™îÿðñ‚0Lç“â3iœOJÓ$û“‹|Áã`KN²5IÞdú«û©ÙXû“ìO²?iˆO ͤ!>Éþ¤k®“$Oì“LOÚΓ“äOÇR¢âîɨs£{’éÉ(gcz2ŠØøŒÒ5{Ò|m’îIº'c%éž4°'9Ÿä|’óIÎ'9Ÿä|’óÉ e_PµÈ`,ŠóÉ Iòé ±jr0IüdúSù™}Â0Iíäµ$ùo?}×A']Þ*n'Is:^5ö'dR&E`’óIÎ'9Ÿä|R,&Ÿû“ìOÆytö'Ã~\¸~Ëg¸Ð¼#I:–¼/þÕ 9ÈC6I>ÿ™x¡ ºaŽoe~  $_üx¼e.̃’M•{`a’Ì~)Þ²–ÀRXËa%8e¶c5¬µ°ÖÃ&8®‹ïp>lG¬ÆØÓ1ôîø Öwl…m°vÀNØ.NîØ{!Š÷'q%)¿ãD‘bìôËßè4DâYˆºÃ ¨,Üñ.$ùb,EáŽk vpÇ µ·À5¹Q/pâ¼Þkx ýIÇÜoŠ¥¨ÿÛñTýíxðht€Ÿmÿ*éX°$š@è(¡£ Ž28:ø-€b…ѹ”N:ý¸­;ºæ'«ßŠåÑ=ª¨a”ÆQGi¥q”ÆÑ@ã(£4ŽÒ8Jã(£1ª*b4>cSÒ±î/bñ=@Ù(e£l²5§:û€·QÞFyåm”øÑý £²1JÙèá¤cÓ{cÉ2ªc”ÕQVG %t”ÐQBG %t”ÐÑ(÷<™tôÄÐU¿1¥¢W D©eaôFÒ±óƒñ>jGãB3«£¬ŽªêÚ.G¹årô)<VGY}åLoÔˆ¼L:v}6*£L7¢,ï G“ŽûBµ$Ž¤ãØ·F“iGÌyGÌyGÌyGÌùÓ¯ó QQ+”w¬›o,H:ÊãoYuœœwœœwœœwxo¡8©M­#æ¼#æ¼#æ¼ãä¼ãä¼ã¼ã¼ã¼Þ¼ãß|cCÒqöN|ÉŽ§ó ãÒqrÞqr¾õÔ*YÏ;&Î;&Î;&Î;¸Í7ÒŸÉ Ž¥°êp8¯–=ï˜8ï˜8ï˜8ß`Õ1qÞñoÞño¾Wõ S•îyÁyÁyÁyÁyÁùFÔàžK:®~[|P”æ°Úˆ‹è¬6¢t×`oDq.¡(É%Ôan^å|Þ±nÞ±nÞ±n¾j¹t°\èÚÚTÔöÇKu´ý9ˆ“]*\úÕÌö/ƒÐó0é¸õŽø[…³ýE˜%X aDÙåÙ¤ã±VÀJX.­ö¯µ°ÖÃØ K“Žç…XÀè­° ¶C/ôÁ.P•Ó¿öÃ8'à$¨Ùé?§á œ…sP£°/éxõ:><ÊÁa8÷áXÒ1t3ÞâšHÿE¸Wà*\ƒë%U7AÁPÿm¸wáôÃCxá <…(´~î4$Qµðö éøÚÏÄD FÔX¿òª>Å2Å2 $ï퉾¨Ž^ ŠjIÇ·üj¼åЬ֢zð«:¦ :¦ :¦ :¦ >± þ¥ þ¥ þ¥ þ¥P‹ æ¬*‚)(‚)(‚)¨)Ô6Â&Ø ¬ªk)¨k)¨k)¨k)¨k)¨k)¨k)¨k)¨k)¨M)Ô–$ovÆ:3­L² ¥ ¥ ¥ ¥àN®…oXUÈRPÈRPÿRPKR¨¥ò¾çV,E”¥jñf¨ÅE.BU¤T¤T¤T¤T¤TŸjá#Ý ¿ûR,ŠUw‹££££££²jÔ*7)(7)(2)v«¹« $ïyW,/\*ëÎ@…NP[ÖÝ 1GJ'õR¼¹saD{ ¢x}!DɺB´î(T_ JÇ» IGµ#–²¢}5DúZPvÞ­¤ypŸÒ©Ðÿ¿ñg›A%y·r‰nµoÝNœw«ïîµâÝ»`( ïvZ½û œôËüägcy‡áusÝ'à$¨öê>ߘÆòîBºª‹¥Tà\„Kp®ÀU¸7à&Ü‚ÛpžÀ½¤ã¿Ë» Â#xìA¼åiÒñÁ3ñ¯ç’£X𼆷’Ž?’Ä¢ê袚袲éâ@ØRá\Tá\Tá\Tÿ\HçÏYƾbé¢bé¢bé¢bé…ƒÖj –iº¤;h‹+‘.*‘.*‘.ª„.”’މ±<ÎULULULâèØé‰Á^Ø q%$n?XqÓÁFˆ[ D@ítQítQítQítQMtQ‰tq`mÒñ±žøH‰P@]T@½ðM\þÙñÂ¥P¸8°'éøøTü…KÅÒEÔűPO]Tx\Tx\Tx\Tx\Tx\Tx\Tx\Tx\Tn\Tn\Tn\Tn\Ti\TK\TZ\¨$Ÿ¸Ÿ&ª‹ª‹ª‹j“‹jŽ‹jŽ‹jŽ‹jŽ‹jŽ‹±í%BÍqq !>jŽ‹Q*jŽ‹jŽ‹jŽ‹jŽ‹jŽ‹ÓFíÀ­¤ã÷WZƒé€À´lLËÆ´±?Íþ4ûÓìO³?öãò@OÒñ¿Çãoýiiš–¦iiš¦lš²iʦ¹œNçÞv)þBJ¦¥dZJ¦ÅbZ,¦åez­ÅÇ $LOÇ¿˜žŽH¢J*n‰Bª¸Y„äé¸ED§ãÆc:n!y:Ê8ãâš½À4ÉÓ$O“c(7îÛa ôÀVØÛA‰[Ÿ:ä¾^èƒ]°öÀ^ØqkOÜ£s âžÍI¶ûB|îˆ;}âÚÓfp£É 5‰må^ž¾8aåž¾2¸o§î>wëô)‘îsN_Ü™ÓwÜÓw Ü…ÓwÜ{ÓwŽ$Ùùÿ6Vý7}·ÀÝ5}Qˆ{7Æ&采 »ï1„ý¨Þ~fucQ’ì’éø×Kx¯á-¡¹˜d;3wDFD`DFrÐ"0¢|$‘’‘$ÉnyW,OF„aDFä`DFä`DF¢ÐUFä`DFˆ!o„¼òFÈ!o„¼ŽF8Qv>Âàñ#i|v&ñá¶ÐˆHlÉ‘œy‰’Hy9Â0" #q›µ#qsµ#qKµ#q#–; FèéK²»÷ħÅÝXLÄ=XüŽð;Âï¿# éG!t„ÐBGîû#€ÕV›áãF’Ýÿ¡ø VGÂj”ãGqó à²é-ÍtÛ?»ÿb°É`“Á&ƒM› 6l2Ød°É`“Á¦AÜä­ÉQ3›dO2–Gc“Ʀ1Ýä²Ée3î%³M›Ë“ìùñfB›ÂÐ\¬6ùhBMRš¤4Ii’Ò4œ›q×›M×ä·¹#É^î‰åQÛ4¦›bÑ”ˆ¦D4%¢)M›½y0ÉÞøø ‰hRÛdµÉj“Õ&«MV›±k&´i¬6l2ØŒ;æˆj^H²wr±¼¸;ŽÁfܧ"¾wÂÑØ¤¬y;Éö:ÞÌj“Õ&«MV›q·„Ú4B›\6¹lrÙä²ÉeÓm¡Í°ú–*2@d¡rÐÝ0òP€"Ì…y0J°Â"X K`),ƒå°VÂ*X k`-¬ƒõ°6Â&Ø [ ¶Â6Ø;`'ôBì‚ݰöÂ>Øà ‚ÃpŽÂ18¡öa’}ôƒqúî®4íN²_=Ûï4œ³p*p.ÀEˆ[X.ø ×à:Ü€›p nÈÛïÁ}xýðÁcxOá<‡x/á¼öÛÖ¾Í~›ý6ûmöÛì·Ùo³ßf¿Í~›ý6ûmöÛì·Ùo³ßf¿Í~›ý6ûmöÛì·Ùo³ßf¿Í~›ý6ûmöÛì·Ùo³ßf¿Í~›ý6ûmöÛì·Ùo³ßf¿Í~›ý6ûmöÛì·Ùo³ß¦»Mw›î6ÝmºÛt·én‡pÊy)'Ù¯èŒ ¶—ýËIö[¯FS@Ú"ж´E -mh‹@[Ú"ж´E -mh‹@[Ú"ж´E -mh‹@[Ú"ж´E -mh‹@[Ú"ж´E F`þ·g ÈB'ä  ºaä¡E˜ ó`>”`,„E°–ÀRXËa¬„U°ÖÀZXëal„M°¶@l…m°vÀNè…>Ø»aì…}°ÀA8‡á…cpNÀI(Ã)8 gà,œƒ œ‡ p.Áe¸Wá\‡pnÁm¸wá܇Ðá<†'ðžÁs€ðRç¥s „äûû“ì7]Ødßõ·¯f¡rÐÝ0òP€"Ì…y0J°Â"X K`),ƒå°VÂ*X k`-¬ƒõ°6Â&Ø [ ¶Â6Ø;`'ôBì‚ݰöÂ>Øà ‚ÃpŽÂ18'à$”ᜆ3pÎAÎø—à2\«p ®Ã ¸ ·à6Ü»pîÃ臇ðÃx Ïà9 À x aÿ5¤âKî}-U„¡ÒœW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^á¼Ây…ó çÎ+œW8¯p^!¹Br…ä É’+$WH®\!¹Br%’I²?ø0L÷'Ù÷&mŽ¿?š"ඪRKZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D %-h‰@KZ"Ж´D eØ·Xmö-‰hIDK"ZÑ’ˆ–D´$¢%-‰hID‹ss½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%³´’™[©Í¹©_ÉÔ¯dêW2õ+™ú•LýJ¦~%S¿’©_ÉÔ¯dêW2›+µcØ?J²?ùVlÄSIößKGÔǾ3š"`®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®W2×+™ë•ÌõJæz%s½’¹^É\¯d®·àG2@d¡rÐÝ0òP€"Ì…y0J°Â"X K`),ƒå°VÂ*X k`-¬ƒõ°6Â&Ø [ ¶Â6Ø;`'ôBì‚ݰöÂ>Øà ‚ÃpŽÂ18'à$”ᜆ3pÎAÎø—à2\«p ®Ã ¸ ·à6Ü»pîÃ臇ðÃx Ïà9 À x ¯à5p^å¼Êy•ó*çUΫœW9¯r^å¼Êy•ó*çUΫœW9¯r^å¼Êy•ó*çUΫœW9¯r^å¼Êy•ó*çUΫœWI®’\±&Éþ«J¬éº$ûÉóéØúÓÏDSª"PªTE *U¨Š@Uª"PªTE *U¨Š@Uª"PªTE *U¨Š@Uª"PªTE *U¨Š@Uª"PªTE *U¨Š@Uª"PªTE *U¨Š@Uª"PªTE *U¨Š@Uª"PªTE *U¨Š@ÕYزSå\!/{Q¹”‰—=S¢Ü ®ª–óà9Te·õ•]^)»®Vž*ÏÊîó*{²QYñaYDÙ]ûå¥àIIe÷á–WÀJð¥²ëjå5àzJÙ³•Ê®ª–=@¡ìQUeçÂËΊ—ÝÚSî×vÊNß•]%+ï×äʮΕ]§+»Vvɯìâ_Ùñyy쇠æ¸ì¤{Y¥qÙó²z²ûËê'Ë(UV/ZVmXVe[v‘µ¬¨|Îk®e—íÊîß*{vVù\ª*»É¶ìÞ¾²"Ô²;¾ÊžãUv }ù6Üç‘ÊNº—ÝðQ~ýà’Kù<Ïâ*»Ý§ü ^B8ßd§=ü>O²­Mñ/¯*{¢H™ýÁ8aÅþ`ÔG°?Èþ ûƒì²?×ÔÙd0nꌋkqU•ýAöã.?ö£ô”ýÁxfûƒì²?Èþ ûƒìÆUUöãjZˆ‘dÿûoÇúѶ®$™ïˆæ$û…é^௧øâ'SüÍ÷¥xûãÕ¸Jaƒ >H²_šŠ>lдÁm°Á§Iöo?¯zþÚà¤ùå_‹>›iÐfŒKÒô&“t<œI:»&Åœ§)ò%øXŠÂ菱;'żJŠùïJQúå þ6Å¢bŠÅ°$ŸbéÂËÖ§ðлÎé.­såNø?)VýMŠÕN±æC)ÖþÓëFR¬ÿá~.ÅF‹ß¤oó×§Øò EÏ£(N‹‹ÅãÄ:“έߟ¾°m<Åö_O±ã‡Rì|GŠ^Þ·þ$Å.‹Ú}*ÅžzŠ}«Sì¿›âÀw¦8øñ‡{SygŠ£)Ž5Rœ¸”âäPŠrŠSÖåô¤8[HqÎßVþSŠó_Jqñ}).ýeŠ+'S\LqͺÞJqsQŠ[ÇRܾâÎ÷¦¸ëûÞû7)î9E¿mÿÐÖ}ôµ)ÿjŠ'ÿ"ų)ž{aà^Š6ØK¯¾ú¯?•â-ßò+ºR|eOŠ¿÷)¾êS ýaН™›âkç§øûßœâëüÙ×Ϧø†3)¾Ñ7úŸHñÍëbÇsvŒŠ7s’Îwúúÿh^Šoñáßú<Å·ÙÎßþ—ñæxhŸáòfnÒù¾ðæƒñ‚1ó&ju$ßi¿ë¤øn øžeðÙÃc)¾÷jŠwÙVÿO:³ìü¾C)¾4Å?¶ö?`íÿI_ŠkúƒIñÞŸO1ú›)þé¶ï+§xÿ¿NñÃ{RüÈ»STÿ ÅîNñÏ.¦ø±tuþøï¦øçÖà'ýíOý÷?³.EmkŠŸùqñùÀ·¦ø9oþùÿ•âþ8Žùÿ[›â—r)êÒô¡Û)>üU)~ùGSü ßòW~!ůþbŠpô/+ůeSüºð¯^ÄÆ±óxÅsvoìÑß,M:'~:}Ëoõeþµ¯úo|ÕIÓo®ÿâÿ7H~KßÇEêãVí·m«É÷¤ø·”}Â7úÄÛ)¦þGŠßù‰¿ËÛ'_§øw†Ëï‹Ù|uŠÿ5)þPøÿ ôG)>e‹ÿGùcÃà?Nñ'"õ§)þóªÿÅ8ÿ3CãÓSü¹­ö™¦øo0Øߕ⳿”¢™€5ýK;€¶Aò9áÿŸ¶ËÌ[)þ×¥ø¼Uûßÿ>Å_[_ø|Š/Ú|ñÓ)þfCŠ·Åñíÿ˜bÖ¾4âoߟâË?’Iré^4É%é†ÈuüdŠl:œs©ž\.û¹®jŠîtøåæü“ùÉ…t„ææ®L1oSŠù{!Ýt¹ûR,üº‹¾=Åb XòW)–¥™Ì-ÿ{á2žºaÿfe’[ñ³é +Sy¹UéFÌ­N7XnMºýrkϦX—îsrë;SlXžbcºƒÏmJÇjnsšØÜ–?KÑó…Û20“bûRìLàOSô¥Rr»†SìNr{ÒpåöyóþÇ)¤ûˆÜAÿ:ôk)§1w俦8š«ÜqŸ{"Ý'æÒŸù$W~–âÔµ§­Ë™tHæÎî†ÔQî\:’s+tþÏS\ð¥/•ÀZ]Nwú¹+‘âj:Hr×üëÆ–7¯§¸•ƒÜítäî|KŠ»ÿ2ŽÿÛÊï࿃oÖ&¹é¨Íõûð‡é>1g¯—{œîÑsOüíÓt”{öÁÏ}ÆÀO¥xñ×±”xÀ¦yÓ›IîÕ‘ô…×çR¼u'ÅWøú_ù+)¾*Ýç¾Z¾6Ínîï§?c¹¯OlîÒ@îÓ!”û¦4Þ¹oN‡}îïŽ%›}½1ûzÓ“äþá¯DßÖ$÷ûçã_Û’ÜçŽÅ¿¶'] Fâ_;’®¾ôç©kÏ‹ûÓ]A×átÏÐuì7âUS¡7ñ˜ƒ¸'n~GšÆÖn']wÓ}q×ãr<ØÝƒ’g=ÉxÖgg=†uÖÓ¿gãñõ=ëáç³ =»<|ÖCÈg=„wÖÓœg=™vv+lƒx´|<—Ýcbg{ÁSg=ÖzÖ#kgãiñã=ë »³žE={âÑí=ë™Á³ñÄüx̽§ÚÎÆå=zÖ”g=!vÖs„g=“wö œ…sP¾õXëYÏ4žõDðYOžõ¸åÙ«à9¸³×ÁÓegãõ· ÿï)¾³ñþ{àéг‰=Ûñäúxäþcxž¨>ë)ͳ“=둺³/ þׯÀc€gÓYÐât,t}Í/eü+ÈB'ä  ºaä¡E˜ ó`>”`,„E°–ÀRXËa¬„U°ÖÀZXëal„M°¶@l…m°vÀNè…>Ø»aì…}°ÀA8‡á…cpNÀI(Ã)8 gà,œƒ œ‡ p.Áe¸Wá\‡pnÁm¸wá܇Ðá<†'ðžÁs€ð^Ák >Ý­w}—âÍÅuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ׉¯_'¾N|ø:ñuâëÄ×SñKÒî÷KÆ¿è€,tBº æ@ P„¹0æC ÀBX‹a ,…e°VÀJX•t½7cvU·fþ/ž™Ê endstream endobj startxref 432422 %%EOF SeuratObject/build/stage23.rdb0000644000176200001440000000655315116571021015714 0ustar liggesusers‹Í]ýVÛFÆ!€IÚ4­’4Mƒ ýÛlC Ý“=M †$$Õ6•¥´‘%¯$'!œìÙ¿÷öúH»OÑÓhv®teFòÈ pÎð»Ø£™ßÜ{gî±,vÆAÈ ùý= â,ý5$À3ôïi÷ï¼0FñæUñ/Ä –ìU¬ˆ–ùæ`_¬ˆª)¦#Usà}ÙP!Ÿc®©ª/yJl‹£k¬?ÜW¶-Å"»”Æ$üåQj•›G¸j”^µ«é„ŠyÁûù=TexÝPB ·Xø&T¯H ÅT5c/¤nå‚!׉j¶¸ÞjAø#tÁ˜£Ñ ¹Þ ŒNëÿ»óëô/ÿ·[VtÙö[ÎùÃÜÜØº¿£8¾®Ü?N7EPp QûkÅ©7*UúË´ÍÇû_Tªµ¦¦«ß|½´¼øåíEuw©²EšÔʵ¿Å©Ôe#ð‚Ùp4Ó°ËÕ°‘s¯ÕP_åx}y£ðG2ö>ì.GŽªÒr¿¡€ý†Æ½Ë†Â—å·×wÐ sïC~·À ¨7Lëåß'¢qíª¸©Ù&ÞŒQM¥Y'†#ƒZEÍ«•·oß–«\ƒ“&@7‡T¯¡|-5ÝØZƒî?eK¸èœá9cÃ'ëÕï9 a­E<òù$ ¹½$oÚq»B¼€ò…ÞÛºÿˆA,dXÀ‹ˆPN¤(n¯#’¬k²ÑïâG('ÓL*A÷Ä’Ð@¹Cx†ŠÉ¦ Â$b åRf¦ÉK—{½gQžMm˜¢¸ÑÙ=;èà ┳tOGstÞúQ@—,ô×= è’>¦sÏ|Z:PN3ˆ%¥VÎ=‘-ÍlÚ"®`bÓ¦i/Î1٢ϡ|.³Å6Ù.#Σ<ßõ9 ½Í!^AùJコ¿Ê –ŒJR‰­Xšë4Î .P»š^+ºÏ1ˆ%y„xÞ9µ)+/å=’p™…÷ÆÏ¡œ|êL§Õ¼wA,½6Ý8zÉ=¨“éæ¼…¥¬˜¦¥Úe{ß´œ–l쑘t'/G˜À©6™tºå0î§ÓиΠ–”FFùq\γƒ õ€nš4åÝ=%ò;a†&Dð–+‚ãÄ”wz?]Ÿ1ˆ%%™µ¦eÃÑD›8ÔëĘ´N£‚gPžp¯®%Ä'(?Iâu§Þ3.VÊÂÊ@é)ƒX’%ztÐÕ„d7k6Ýfós lbJH)¢¥ÓPÊ1ØüÃbšÑh:e»![6¡AŒª+&Ýi?à1¨sÁþ1f éF[,/g¿œ”„£ U L ×3û± ûg HÄBÇf…®D¬®¸Ø,ªqV¸ˆ”ž28k›8# \ÄJ9»±ÎøË,»Û.ÇÒ”¸§;gqè€"Êbÿ‚ИgKƒÕŒ_d¬ ?¬þ¸µžýZò!2ÜDy³Ÿá ˆ1DY…ûµD׃EUvdXôå$ÖšA\@9ÙCñ?îëh®eÄÛ(ßî¹Êˆ+(¯¤6רhâÍb± ó'ÄU”WFˆ—*A§ß#ÞCù^ïS%è~A,}LÅ™»ºŠGY)E‚tIÄ¡y‚ØÇC#èþƒrhô1*0û,¼ þDKˆvb”ž28'F籉O„KÀRŽÁî$àx ø+bÙ-}˜°(´‹Ü{v'…4÷í¦>87ÄÒÇhu Ý0ûh•{õeöëÉe¤ ø娓6ËxDvŸ£ü¼÷ñ ºÿ‰A,ýŽWó¨`ÀìãUW< ¨–w„Ö§Wƒ±€Ò3'%YF,›¸" \ÄJ9»±®p#Ö­r]³mº¡ËÄŠÉœ91Q^ì_è·ÄÒÇÐu ý0ûÐ5R—KëÂ-?Ÿ"UÀ_Pþ¥Ÿá ˆÈˆ ÊJïÃt¯2ˆ¥ßáë:*0ûðÕ5/º%Dey0BPª1ˆ¥¿!ì*6ñ™0p! (åìN; a ËLp"yÇx åK‰©N¦Õи –”KÊ9ŒY"êHÜ5-Ñ ¯Å˜ì>G'Ìæk4Ù}æsœŸ£ö® 7ªÜ^ ’®/#ºý‘‘3ë6âTºšC¼‰òÍÔ~RÄSý¸ß ˆË(/'ö !^2~‰ø5Ê_÷>€î¿aK³Mæ ]È6'½Yºy’U7I:°€Œ¡œþ&ˆI'©"n£œþ—Ø~Ý?fK¿“Î2*0û¤³ÛάKˆU”«ƒ‘{¥-±ô7÷¼MT„Ë=RŽÁĹg,}¥heáõ‹ƒ§¬ETÉõT4–pL>&ÒPäâQÔ ‡X†¬Çdõ…à}¿påDKZ„Ǽ$¯MKèy±$´“^›ºŸeK2´ÕÊUyC÷ná°…$®À›,ð{ˆ¡X&<Õ)}„ñwdcVŽZ=Ò™äȵ£†NsêŒIªi8±¦b1LÅJ«Æ·©£§aµ*æC•Š´?eû A‚uX+0ÁpWÛkZlÕ3¡*^ÄŽ0<:÷Kö5¶™P¥‚d¸7Ì'TI%ÿ0‚L¸¤ƒQ©U}ö¨:çºÏUÌzÝ}Zë’;\2*™P§¸¬÷=‡ó+ ¶Ýþ¼¶k¨K/·é¼Æ4ôƒ çtl· ás¹ü &¸•j¦®¶WâhAÛ%ºÍ¶žEcÒÖr8û&ÛÞld{¶c™ÿîš×j Ê8ͺû<¦Ö4§±"ÝB i°s0¢ÐÊ §ç[Ëþ£T£æŸÊÞª0ÉilL² ³ak¡œ94†-ò¦Á*pŒÓÔ°ˆ´áx] ŠhìŸ@yée­ÓR0A#è.¡QT!Ç©Š.Q©pÇ‹üÅz³RÃ{Ô=6þåü.æ"¶…ÁÔ9èLtÍÐ ){Ñ=Oñ?YĆcë;–zÓvh×wÜgÎþíÐ1MÝ^YY©ª/Ô &*_¿<¿tù³wœ}áÇYwQÞ=Ú²û6x­ÐöI óÔà‘ð›‚÷z:„,chõ¿üöŸù¯·6›'}üïx¸ƒk•¦mUì}Ù"•ªjÅÛ…Vì›.­GùN„¯îÿ|93g³šÈ…”p•mpxïÅfõúü×-ü¯þ~‹ò·Gn¡žøˆ""Þþ(o“f ç’ô*n¨uºiyóîrªÃC¯‡wïÞzgŒ‹8.À”W2cQªi5/ÕÊœ¹ù%Îî mÀ9”ç’ ! –¹§Ëî#Â3àε݉¿qìÝÃù%0ýÍÞW8¤¯‚CMf¡vëxÛ‘îY‡™8Z''Ýï&éÛHy*IJÒEi­ºúÐݦgAý+÷ŒèpßqöJ¥m—« xFÙ´ö*ïPÇ:„ã×Ï8Ã-á ü £Y©MYlV¹ó¼9ôO:sDÞ¨Øïç/ ­e.ùÒÆ9¼@ o{;§,¬úçø9Ž»o‹Înد?GùyZ=œè0rÊ×Ï}CÕÜô4 ݯ!Íë?ZGþgŽ€?£üsfað(G^ßZ«Þßܾ¿ñ0]$ȈÑú`ïÊådÄ ÀÓ¾Vñ(/ |_ÞIbôè/áˆ%”¥LÖü¤šZ6ã^8AnK;‹åŽ ð.ÊwSÛ¸äÛø¬tÿnŒì¼ßÎõ…h-ø_ÒTQV3_C;è^—àÆ£ªâO÷þiL±a‘Ý”‚vÝ ðw¿ þr k÷ÃȦ…?þ{í—ÓhSeuratObject/build/partial.rdb0000644000176200001440000016505115116571021016077 0ustar liggesusers‹ìý[oÙ¶& NÓ¶n¶®–%˶¤ä‹dK”ä»%Ë–|KÛi;¶3×%µv®’X¦Hne§×:»Ná Ñhú4îFW£ÑhôËþ ç'œ×zéýª°±Ÿ µ:FÄ7ÉI2‚Ò¼DP‰\ Ìü†%ŠcÄ߼Ɯcü¾‡1–b'Nzÿ?NâïcŒ'õþ=àá1v‚u{8ÙúÆ)8e»âd­­¯V¹øË×§pcÅÊ­B±b9Ù\…~±k²ŒH Ûñ>ûsÅÞñ$ñ;Ÿ|÷æÍ³·?ì–3egÛ3£—þåÿ¦VækX÷WÞ_mçòŽ'ž`ÁÿÖð‘ãÏ ™Nþðñù½†Ïu9…L1›+ì4Ô@è‡Oì=ÇmøÚ®gÕo`ÿ½áº+9ï*ö^ɳ¨~±ñ/kÿ<ðçmüæLÞvù7§øc¾ûîÃËßg*¼®üVBÔtQem ¦m,VöJ‹ï½ÿÝâ»7ßoíçòÙ{w—o-ݾ¿”Ý^^üàì{^þnëß9™Êâž]XÜp]ûë‚oNú}£oS_² *Òr*ãùtÿ­‘%5ÇF}¤ÊþEun;ÖüÙ±Æ?;ññÙïA¾Ôßè¶ }î¸÷¹S2cö²õ.ïØ®4”l1³¿ç*v%W,X¹‚õ~ѦjN¿°¶¾µÔœ‚±„³gµ –®7R?' Š‚g‚‡¨o}hR&Q¯ÖìƒÜ§bR¨Ö®MÏ‹¿–œÍÇ€ýû“÷Éq|Ž#Š!Ÿœz†(Ã~|öþqˆaÔIw!óÌÉÍ ë U{ 8y(y·ú3¢´ß-'‰ÖÀ!ÈJõªµcÓÎçl7Bï1 I±B´üBê‡D1Õ…ù~‘ôH¼@xòé<ÂGBÂ^ȽÉ{„JŸ€(†<Òÿq×±|¯XO†—NøƒpòˆAßTr•|X/Ö ŽBMÞ7¤þœ€(о9©kNèÁQ*âoŸÕ(Rôç«Vε*Þ϶l7—±ö Þd®¸m3ÚU˱3»ø¸[)–×*Û_æe¥Nõ €üLÿQ Åòž×Þÿâdç-o•f¹;ï­æ²vŶl×úâäó„™ü¾[qÊÞ¬t›þ€f¨óÖg»œ³·òŽì£ôÀü£òvÛ±+û^õb<ïxN)[þ$zÁ-9™Ü¶çž=§bÓ㥟¸–»[ÜÏg­LÑ›z{³n×[¤É?Ó)<á[ÈoµŸéÛ Õ¿óKÉ{,—V¾_Ü}PžSÞ¿ÝXpœ·JåbÅÉy)zÚ+íÓz¼áÒ²tAø-äoud§7³Ž›)çJĤˆ†‹áE\ë'ݦDQìÎè¯C'òÅŠì@#¬]ôÖ1¾iÇukŠL%i‡ ë*MÞP­œÓ5‡>sJ@ü ãQG¦¸_ˆ$ÒÉ÷O¾{ú,ÄÈAœp²¹ þÉÍL16c–xþSu2Åù}h›šÿ¡PÚê»Moôµ‚š¢þòã»7²M,n@Þ0Xa¹Š³¡öð1äÇÉ71RÿD@”¤Í–êZúAMë1H¶aAc:ƒ?èeŠ;-r KhLzû(¡ ëüÛZ³j˜cHz¾}¸YiSU® { , 9<Iý¢€(I›1Œào3êñ—i•Æt ˆp²¹…udc:‹D8ʪëkCiäC°ÜÒkHdÛyà"d%*É5¤³  áä¥äLê—DIÚŒÔǘRðf¨XÎíÈ6¤Q4žÑd’Ðx 4¤TC}ÜûΫ‰\ÁΫ}«²kW¼ÿå\üÛ¶l×kiÅím¯¤­è•¢¬—GѼ¿‡ü½6ÙF*e;ó ¦z‹ùÏNÁ.dIÛÎuçêÙw70*¨mãÎã¹ð’´c¨Žñv§?Ûå4ß÷’툻½Às•jL®# uÀ1ÈcÆ:‚›?:™Š·¬+n[¼^¼Ñu7·•«ä ;Önng7Ø·ôÚ—egÊEוu1~ø²þVßé`ßÑ¢?ÙéPØ·‹»åŸÔ¶ñ}©ïÐÌ&¿´Qãmù½´­ÜôÇá±q´Á^Õ6(×ôI]'PèLM¦Ÿµ±w>;ùê>¿¤Ç…r£†q·¥q0†ð&ä›É“˜Ôß%i3&PcÞÜÙ˹Ù&4‰f3ÉÝÜ™D³!4¿¹³¸aÑ)™¬•Ϲþ;Ìý‚[)ïg¨Ye-ª&ot² NqßUY¨’ÑÃÀÇÇß¶&Á Â'Û°cIêŸ ˆ’´j€c¼mëø'ç«lÓšBs"ì‡ÜÓšBsšÂt2ÅíWDGCE<Ú°Š› ;•]+³k{K>z£þ9˜¯~Éy?¥3Á‰‚«®åUÜ*ýϵööÝŠ¬—§àÂï!ë/T7¶z zo²W,{è|i×.ìï9å\¦öL®µ]Ìç‹_‚SávÁëE²ÞO3Þ_È>Æ4J¸YéUKªIý,KÑP“c2%uÝÀÈJ UÛ¹™ý~¿X‰R| (¼‡Ò¤Ó€5[vvœ_¬’]ñxSeY3œ‚ }¢ú›SÙ¯ÞpžË<Ïû7-ø­C—ðç—˜F[¤Oœþ[³1õíqN’dÒcQÔÚE˜yrŽ)¡¦”'‡«)Ù&C&=PyªµÇz¶Âø3€ç¸Ì4&­thÇumºÞ~ò¨O°29u4|G&%é ä<G½ 䈮9WYpø‰#Šf­Üú|³îˆ'vÌç²¹Ê×àxa®à X¶O"ÚiØ-fÝYË…‹9þBûS]lóаá«óRºå!óãæÀ^Bá ƒ±N>Wø¡¶8 Yí¸½øÛÔlÔˆ9Ã#ÎGXõ½sÜ3¼9ð€ÐÜÛ””ôqcÒ8Yi‡°åÔª/¸–›–¤×@KBáeFܽZ^€|!~f\…½æÄ™AúÇ'Œ÷ZƒOÊŽ]q|~ðK¡Rf^!®³ºíî¸Éq„¸ŽÚéT®:/É÷_dÀ$ЂlÅÏÒë`&!Ÿ«-ÉôXJú§3gÌ­?)­óà#a‚cë<øHØÖ±• 8 Lpl´ul%ýç€úck7»~R#ç¹–ôª²DŽœ ä«;t—<9@ÊV;#¥Ä9r.€ ¬î$Oâä\) ù ¥IUKrvgs{JìLƒ‘iVw$4nv¦ÁÈ4ëɳ3 V¦YíÄU‡vÒ`dšÕqJœi°’ðd¥¹wKvöyìôƒ¸(Qt´\d‰.KAËE¦¹,Ñ¥(p8ÙäÌ;‚¢‹ %ád3oiŠ’þI Å4&Þ-)zjÏ)ï8Jü\' …ÃÀqós œ$®ˆ'ÏO2` ¨5ÂÉñs œ$ì%ÎOÒ¨Õ<[óÓ-ås%~.ƒ“ËÉòsœ\n7?—ÁÉådù¹ N.·™ŸËàär¬ü<íîo¹ŽAo€”7X<§#z¤¼Á4NëôˆyƒiNÂäz¤¼ÁLn€J¿oºÁꇎ«ò3T+½štì¼[ Ñ|Íχª¿xÓª€›A³ª"Šbml˜'m…IoÏz€}Ì|P·L±qJ•Íxo×Πn·ð9Ž(jÐô©ñX§“ÿwÍTèHŸh|SN?«}zÏ¿¥AÏøo°žØ”©}k­Î6+öVMñ¾Ïtof‹…JÅq+»MᑱªŸèýªZ°ÐêO4|Hˆ(~FôBõ³›Û¹ý²øÑá†ß̔런ñéªÇ2ªløÐÉÍ‚î§Ñž†e,Ô[jô©M€Å)‹êÇÏÔ>ò'çK¦¸·çG‹­þÉh‹?éÜ,–4œµz7 ÿÐÙúïŒþþ™Üv![÷§ÓMuK¬)ò_ë™Óò{On"~)ÿƒS¡Ú*æ³Í ©…ܶ“wÅïi²òíà˜B¸3¾Ï­”‹uüVö­uéñÚµëÈ5òeB?Ùp¼Öõ‹½WÊ;b3<ÙÔP?Ûù}Q]SŸàø‘£Œ>±YúòüõZfœB6'rc¦é[>Ûå¾…Ow¹ÓP3ÕYAËæÙ»Yv¢Qƒßì}Ïoe]Ó›û®½#Zv2‚›ù¬À¨e+ºª~®3âÂCEÚèU^®ÒŽBÆ€ýržÕõ!ý¿çMÑažð:À¦Gmli7£ZZC}xÃÒ~¾Ž Q-²gÓ.ïøÁEÕý¡ZܯÔ?hd/äy„‚¢Ùùúgnj(Ÿ¬8w·øå€ŠëÜ|Ÿý®TgO ÛNlf·EÏŸ @ •ò~¡…m½›%¯Û÷ãÕUœl‹RÇÓØbÂÚjípì„«Fjâß²8 ›®ôxMÅû˜[ß÷…ÕPǦ³gçòáÊÛ‹Sñ>ê6?QCÏK»nñHóQíïRT?ÐòeÝ›î×B±äææÌ ÏðŸŸèùªã›u#mãx}Ò«ˆÒî!êáÄæ§­V]Á)oÝv¼Q4ãTU^×5nY¨“0ïÌfÉÎ|ò†Ý§âø—â*Æ"–…õSçz2y}F®Ã@*þÑÓ â*;î~¾â®•³ónÅS½æÇæÿÓ_+ÅbÞ]YYyŸýFý,ŒÊ³Ó3ËÓsÿ².œŒõqòvm](®Ûèg'›6€„¤ ¿dÁÏ»H!Í2Žmüÿþû¿þßþÿyu±yØì= ®,î»åEw×.;‹ï9fƒUè¢ûÕõ:jʃSÝþD!-çÝ{% e?r­‰0u$¡ßýüîýìÌr(-ÄpA ?¨Ñ"{è-ŠˆñöµýÑù½ð çÔô2TÍ{‹–_þé¯4§úë_ ÿôOÿô×@yÆ%<á äcÏØµ¹•Û ¦Z&Ü™šYy„5˜M8yLåF‚R¹¸“·ý *lõ·ÿ¥ânÿuf™œäý?äñîà‘îÔ?ªš‡š½,GâóŽÐp z'µù2N£ïÃPB!úž¦Ñ]›OÞo¼õ—é&L¿ãïýu·R)¹+‹‹ôÝé÷ k©ŸNË;‹׬ ý{¯åXaO%F—ZbÕnN½k Ù¼@  VN&¼úP~Žã¯Û¢g7b¬?Bþ£n=j3²Ÿ×ÏËB6çOOMÔк| åýÑu$^UøÈÿ`l¬Í‘Ÿ}xòþå»/¿{k¦.fÄ‚ ÑõÁ_܆̈;À>^ØÊ3Qä« ØIŒ~ú)<1á&äM#ýá‰Íl1gæ¹1·õ”E?垌pòº¶‡¸ßØ9?=cÈÏOäý¼W5!ºÄ;âYÈYã½cà :éR¿ðxŸÅM|ã9õºJe§ä­E©Rýuï£eü?Ï$??㥆·È ù›ãDç˜;&”†ŒJëüÈÌŠM/䛓) u¹õ7ž*»’_k<ÊÛ±æEÜW;ýо¼ˆŠ›Î‹(a†Æ­ÚˆìbU rKìð¶…jLÃwÞ ¶Š’ö ©åHx†:Ô.àYÈJUª5:ïÛ ¸ã ,œ”kHý¨€(†\3ø#øð£Úmt1Oâ9Èç z'*ó›˜'1dK()ïúó¢(z§C×*}¢hÖJŸÏ` *n[’6‰9úú «Ùzp²ÕQæÈ³¼<·û²{"zûˆ³¼¤®ŸÕA÷+³Eüí(‚µ¸ï&µyâ«’Äß Z†¼¬å§Ðþ( ÛI%}´ [V;€^ýa··ägíê¯À#úÂ#ôC®ÀË=BÓ7ó,œS¬Ò1nFóŒu„Ó§“ï†IýŒ€(†žþ ´}|MÐÍê–‡IWý.% ŠbN±Z¨ùÐðÁ*élzðÁVË¥ÌÿóTåOîš:eÕÆEIW‘g“'U òkñ¸.sÈŒiQ’&°˜MÔ\;:¹•·wuò€ SMCDm‰§‰í5Z ¦s€&e†0aÔ¬ÃôiŠ©$ûñA³ͭP#{µ~°…p²þU£W#CFS•æ fz52ã’€(ISx´åØÆ^mê “íÕú¡mÈh%(¥ÏL ئ^M8’@¯¦‘~p$ƒœÀ:Y˜£ùëäfb¬Ñ³‘!€—!_n_ÏFfÌ ˆ’4ųmîÙ„ Ú„{¶ahã¡ÕÚÔ³‘ú”€mêÙÄóRæz¶Æmšç% zÓ¦65¦kíô¨¾ÉÓ­ Zª-ç­ŒÏk°ZñYÚ 4{ ƒ¾±8Å»„q­…pòtò-‡ÔϨ| CÏŒ{¨Žfú‘$2c߇µ„BG¬ØÖSm]13ö ZÊŠ‰VÓ²7©íjÝËÖMÿAœް¦ìqµm!ž^XöNÕç—ÎOCúÏÇXSöNSã DÒÀUpr•…æOŠ‹Ÿ«àä* ÍŸ-„Aƒ×ŸåiAúÏC’âê²´Ób?!ÇYSZì¸Èñ„ œ`Mi±“ë¼È€I Åš²óÅÅR1n#?d£4Òd)éŸΰ¦´Ø¦VµÌÃkà#a‚«ðr¤½+p˜àÀ*ìl¶u`%ýçX-ò¬ÞÀÅMÕ´ØAȇ,4-v\ä|B>d¡i±“#çCò! M‹9‚YhZìÄÈù¤$<Ïš’2"§rZìG`ä#š;.v>#±Ð´ØÉ±óXùˆ…¦ÅŽ‹ÀÈG¬½“ÏG`%a|“O½´Øë å: M‹E×AËuš;9Š’ã¬)¯i\]- ' ˜yKS”ôO-¦1ñŽ+-ö8I˜à²yœ$ÔZ6ëò“ jprü^þ|%ÏOÒ¨Õ<ãJ‹ýœ|œ,?ƒ“ÛÍÏÇàäãdùùœ|Üf~>'ÇÊO´ØO@Ê',4-v\}R>a¡i±“#èó Óœ„Éô Hù„…¦ÅNêeÓð’ã¸*?Cµ¶J‹}ýئ×åOƒfUEÅÚØ0•Òb{,õ_“ö±¦´ØÚ>‰N‹ý ~ ì‡ÜŸ¼OžásQÔ* éS­Ób?Çc3:Ò'ÂÒb÷ÒÏN_Úÿ7ØwÂá»Oc0jzåo,:æýhEþó^ –rÌûǪ޻ݿà·ñþµŽmîpïo놼Ÿƒ<§m±RÈûk¢(˜:<ª¼(§ =Àáñð&E ž?~-ì>dxLÊ'Çñ9Ž(†|rZì¢,kê¾8yȘk"“œ€/…ÐdIû…Ô ˆrü"¹?êᛠù%:äžÇ™R«-Çú³¢rLGàI—tÀ „½¬Y;v—ðѰ²Rï©è¿_@E—4Fµéü¸ëXŸo[’Fñøã<Ò—rÝ„vqDú×îRÕ"ý+Ò¤ÓR:ý$FöŸ‚% Šb¡¿íË>ä‹‘±û[åyèjm†„Σ¥kŠÌ%i‡ñíwŽê¼¡Z9§kN¸Ã±áZ±BûܼýÕ)G©eˆ^àäf-|‘ѧêdг~ö¼®.Ö7,Ú3ÊZù… )ú™)‚eQv\׿ífWÊ”}ÕrìÌnðÏ_,w·¸ŸÏÊzšžbøä´ùÿÒhRùR\ÈæöœYíMÄ‚{|âC¹Å=Ç ŽPd¢Œ“Ï»þå¾í ­t0¢´—•âúKÖÙ΂٠Í,%„!ƒLw6|KšjM¶ñ Âׄç!+-—åÏ >Hxòmÿœô9£à•‹@ ²eÌ+]œÁ*޹ LCN`ªOꦀ‹õ§úc–KS„´õÄã¨Ø°eÛ5™µ|ù…¶y{ÎÞ–7òìæJ´h,;™b9«Ü̇ø8y¢ÍÍœl¹ œƒ<?›HÝ$ðdµ—puêTš9™ÀCˆ-BV#¶ÑfNæÜ®A^KÆ1K@½Ås]-Í\ú¬!YñøòsmkN{î(QŒ£ÏN>j§å0y‚„ŒtÆÜ²_P+,’^…ú>Íl”*%Û9& Þbè Õ‡ZÇ*\~ò¥^¦¸n”k¿ÂÕ<½÷Õ~•t4TEjÃ’t•ðr2ì*©fïÚŸ/îø[¸{v©äI’6î ðä[}Ô*PÎÚëâλ¤`ñ8p²ÒÞsè7oC¾­¿0â«6Ñ*½Z#cîŸB~ª¿ø¤Y‚¿¥`Õæw|Ó›âyDâëOo¡éÙMó¼RÑ[WSê“`ýé}¤OË>ÎH@aÍ->ŸùG²¬Œ]à–§­·Î—à ‘.`×þì„/¦iÓÀ)TdE¸Ÿ-ž±Õ|”SþÄ:pƒ¤Abš+!kmÜóYA­Ö|@oD®9øˆ’´c¨ŽñÌÊskáÖgØú¸ÆfRÇO„\¡O|l>ÂðKL qÚ;6“QsÀ»ïé±™,µ€W _126Ÿʽê.ƒhPÜn! îŸBÖ˜ßø“Kyxæý?BË>’˜Îî ä7úƒ³o¶â­ºÉ-ܾ288ŸÁTÁR¤Ça ¡Ö±V¹Aú¼ ¶‡6ùÄ£ú¡M-3„­Çéά³mïç£LDŽÑ“,—'Yh ¦¸ÆhR× ‰Á$9FŸl¨ŒÅ 1g¨Üñz¹jlxÇZ™u~±‚ÄX²ž%£GÏXurnh@ï…'ƒnKÒ4‹UãÐúG˜âÁCùá¼wíi`økE»;Z/sC¿ùp²Ú12ñ·£A‰:WY[ÒL"£.W ¯hwƒFl zû%«RDœÖL~Ÿ.”ù–Û4I»§P‘„7 ß0ÖTû2²æ>ðäGñ÷e¤î&pòzü£í¤àƒ ÈÉs¤þ±€(I›1àïhÛãÏ4ÓÅr.j½IRêƒz#•vjåH*…<ª¢–ñpâ§–¾ój"GgK‚)xuëÿö„-;H{µí•UYï’Õç/!ëïèMø'_½î±R¶3Ÿ`j©\üììBÆ‘´ñXG¨õÚY®˜Ôò.a2ùöÇG1Ž(I›q5À1Þn {Ï©Øé¬]±e{Ú¸èeµ×"x…w/@ê:#¬)~Ÿæ´[~kŒì†ÄøÑœGôg¬írõî§”]7€«W º§Å4ºŸ:ʲ<­jùp‘iœ ýæ Àh·ðá`Y†-oÉöÙÉË6z²h øò;ýY45n‹±Š3ÁæÍž]Ï1VaŸvÍh Y.~¡‘N–ýoœâ¾kµ˜o´Ê ; | Y‰ärmk šcuaË’&5©* JÒf\C pŒ·mÿä|•mZ×ÑœûYõVGÜMë:šÓuüA'SlÑ©°¶ê6ƒk _?;™JQØnE\u-¯âVéÁ#Y/ólµ„ßCþ^›lt¾èê3¹Öv1O™šýPXZɘ…`Wš»K­H*ŸyÔäØŸ EI]7p²ECÕ¶È›º€º'„¬4ì4ÜÍžõäZ%›rdÙAÖ § OgÇI”{¸§¡O$(WϘúÆ7'éu2é1‹L”+×]W‘³ ž§ÌQž]®¦dÛ™ôT@åG¨Ön\~Þ ãOžc‘iÌ2Z9ÈH†ãÓ‚•)È©£á;2鸀(IÏ—ðLõf‹Ãºæ,³àŠ8GÍZ¹õùvì¹%o òoAV:}Þ:ÍrKFFóаî&è{“ÅsF2"ˆ6©ëj‘Ô ¢MŒCÒ Å5Ÿ» "†¤R}~é›W¤ hf<ôŒ("òÆ%iä-ð’ðd¥ËÂr½^^„|1~j}„x.qjþ à$äIóýÖOjýÖmð€0Á~ë6x@ØÖ~‹ aµ;< õ[·AHÂvö[¤ ¨ßoE‘³û'EvÞ#ï°x^¯F°óy‡i¾^Õeç°ò M;wXhz´ÄØy¬$ ÉÌaˆ=Õä}²ô¼ JÞeñœŠ ç]Pò.Ó<¤KÏ» å]¦y#FŽžwAÉ»¬vV]?4©<=ï‚–„!+MlZÒ³¿>{Ÿ,Gï—÷X¢“¾{àå=¦9éÓå(0œ€<?Gï—„“Õf}z%ýp ²úoGO éûd z¤$ I?A„c¬)ýTr%øý0­ANŽ ÷AJÂôS‰”ôµÚçùÑjùûd ºR®$KÐr¥Ý])W’%è H¹Òf‚®€”+±´WLà'ËÐU°rTéU¥ŠCWÁÊUVwY;y†®‚™«Ls"&ÇÐU°r•™Üa’ÞÒ_19N¨4Tk« ~Ëxè@õwZð hWUDQl¡-³ÃVi’k,x·BعߠS¢Sø­ÁkÕ¿Q<â çR?( ŠZ4}ªu ¿‡xl¦ÂGúį:…Ÿ±$p-ø4äï üb)'ð{¦î»¦ü‹¿µ~QëÙÚ˜ÃOÑbÓ9ü$ÌÐy+‘‹ÎetC^Þ¸ˆÉ[Dʸãpáä‘ä]CêGD9®¡Nµ 8Y©ŽBµF§(;œ`u‘Ó’ö ©?' Š!ß þÈÏÌü¨ö:ÿ$«åô;YɼïD%Å: ŽAKÞ;¤þ¼€(ŠÞéÐ5‡JŸ€(šµÒçs#‹ŠÛ–¤Mbú²>Èj6….ŒZîU*Ÿí¦ä7¹Åº˜Ïîä ÚþÅ7—®ÆÓÌ6ïÏ~eɃ·#>Þ€|CËQa;åJ øÐóûh±jlcNk^,îeÕ$h‘ä,núfž(rŠU“ÆM`!ùRX.¤º]R?# Š¡§?(_t³º%aÒ•àoAˆ¢Ø^S,ü2á€ɪ ’V ç{ý(o¥oÝqÝJ#õDIÚwB´[ƒ:¹•·weM"àŠ³*Cm©Õ¹ýhã{\mjG½`?Gõv¤e†07Ò¬V͹ï[ç«zcîgÕMdMÔÃtŠÝºUFfœP}ö­eƼÅÑ _}ËoZ~â­÷NW½_òüÊ?œ)Òîš!‰þLöyñ „¯ ¿Ò~ž¡ >"n•æ ;Ò—/†`ËP½¬È¾~]·ŸAàØp‹E•}–¤è Žzý‹œF\œ#µ) ßæëЮ…k£`9{¥ÊWË­”)Îଳ“V© ;ÿehE“ºzUvùI]ÎCžW1LnöNê. +í]‡ªmq•ŽÓÓÚ$éš³¾ì:eéœ^dÅ"ðä;Z´?uº@Ýó융¶f-©c øò‹dˆqøòËäRRÿJ@”¤{Tž‚cÂ=*©MÍõ¨w©GE_Ú0?ñÙÎï«eá›kk×´_µf·ŠÞćÂQ”üÛœû¥’'fl×™ "D:…¬àЊU!¼†ÏÖh>@Êš•´CLÖ’‚¬¾º»äcf=ƒ6©ˆ«‡"u§€C•æ~²C—ø^ ;j[xuõ>;Ä|ÞΕ)#pu>_›îç ¦!Ë^²r¸ Y‰½‹yê²r «'°«z‘¬M‹ùsh.SÊÍFüíš¿ó»Ûë'ý“$ÂäÔõú9XU{Ýj5 EöÆP{„Â9*Ã-?©x(´&ï®C^—}ú„‰x(ÂE°x(zÆè—Lz, ŠZË5V£Ï“¬(µèx*‹LJ h¦•K›!ælÑŸ(ŽêšC«ªÕ7$bz7Á‚y¡Å~ /ð&À\B³/ðè; ¾À›M §!O'ßrHýŒ€Ê/ðô̘D p43iI"k CÑÈ¿-0ˆf M…0$ ƒÁ†Þ¤íHïŸî]2`Ð!®Æ="†tP}~éÛJ¤ ÐÁÐ@tZU+Š-´±eªE¡¡Ã­=¬–ª! ¶S¢£Ðð¤׫ãcÒN!õƒj™’ŒBÃÔ0>Ò'~ÕQhLF2iˆæ\GþˆFà–r š'ÊîûØEè·†æPëÚÚ†FÑbÓah$Ì!Oª¼Œ¤#¥=À>È}*&E ž?~-¦rò>9ŽÏqD1ä“Þº.!Ê´Ñg:g Ÿ1æ›ÈÀ@bðá‚WÒŽ!õgD9 ŽÏ CVª¡P­ÑaÄÀ3ÂE‘¤=CêGD1ä™NxFÒ'ðadsY´Oø€HØÆn¬Ÿãˆ¢è“ÆPCwëcÙ.¸ÁÝÏ·-Iûx¼lŸùò˜1Μô9Õѵ Äc±Ú;f+@cýk‹@<|Ÿ†¿;»¬Í˜NKéX,9D8yÞ`³‰Š¡%Ffæ’I7RŸE‘–'tÍA§UEÍZÑo½Ýðÿm‡ÚÜzé—cÀqÈãÆ˜Ùzé— Q=™=¡í¢.´^•8<“@þŽóбJ8(Èă©4l<&ÕˆI}J@Ev¦Xxô’“òÅŠìòêÌ"ÔZ^…ËJ¡lØ LÊabØ=Þ„í)á9% Šþ„ndç)¨U‘"»»>H8Y© –ëîHž¨µåWXêêb}âEhÖÊçè*j±P±sº%îüR*;®ëßR°+å\ÆqW-ÇÎìÿüÅrw‹ûù¬Jœ£àÐæÿKÿÒlåKq!›Ûs dµÇý ñ¡Üâžc/éö{ÆÉç]ÿRƶcWöËòÞ…õ†:á«  ø8ýYg;Wp讈‘TÒ¨2ÀtDá›\Tk²g¾&<ù|üg@(j¨éŸ“>g¼rhA¶Œy¥‹3XÅ1WiÈJóoyÇL!/j;fÌriжžx¶JP¯%à È/´Í›Øsö¶¼‘g7W¢`­e'S,g•›ù`@' «ÍƒÍ5s²å2pò\ül"u“ÀkÕ¶õëÔ©4sñUï"d5bmædÎVˇr‡Õ…ˆÓ1KÀ‡X«ùÍ\úYñøòsmkN{î(Ñ=úÏN>j }˜ vœܘ["‚ õ jùÛýÞäW!C¬6›6·Ù¢Êz‹¡ƒVj«p%ͧo/S\7ʵ_RÇcè AVZó°°÷© KÒUdÇYàds/>úóÅ\Æ[9ìÙ¥’ÊAÚ¸+À[oôQ«k¯‹;oì’‚ÅãÀÈ3ª7}3Gtòmý…_µù‹VéÕsøòSýÅ'Íü-«6¿£OÞÏ#_z MÏnšç•ŠÞºz+ï`ýé¢O«D[à Hƒ‹Ïgþ!+c¸åië­ó%xB„¤Ýµ?;á‹iÚ4p Ò»¨#0ŸðägÚrÊŸXn4H À&„ëŽ{`ÔjÍôFDRß+ JÒf‚˜•çÖc¬zÒ<ìêx\c3©ã/sC®Ž'>6±êÅǰKí›É 9à]ÈwôØL–ZÀ+¬zyÍÀØLßÈï¸ßƒ|ODƒ€âv Yrø²þÀüÆŸ$XÊÃ3ïüZ%¢îã²7ßèξي#´ê&7Ghnp>ƒ©‚¥>H‹Ø„E\܃ô˜ ¶ÇóHýYÕçi™!\øI`îÌ:Ûö~>êMäM¤½,2”[\c4©ãqÞ„µ´â}²¡27ļXlÇëåªñG?ÚXÖùÅ ’/¨„i>ƒ¬ÖîCÏ“A·%iÚ$ Ö „Ó§“Î{מ†¿V´»¨} ¸é›… :š½Áh¨¸ÎUÖ–4“ȨKÀÈ+ÚÆÝ ƒÞ~ɪ_/“ß§;*¾åÅv AÒn Ixò c-@µ/#kîA~_Fên×!¯Ç?ÚòW[¤vòFòé, JÒfL¡8Æ;Úöø3Ít±œ‹ZoE’”zå^Vë{™âN­II±HrÀM5ÔÇÒw^MäèlI0¯nÝáßž°e©¶½²ª"ï<ð%dý½‰}2Éë+e;ó ¦–ÊÅÏNÁ.dIňmZ¯åºiA­0Ö%ÝþH½% JÒf\B pŒ·èÞs*v:kWlÙ^@ ·.®^@ 6šâÖiN»å·Æx\0~Ù;0†æ=äk»\½L&e× à*äUƒîi1î§Žr…,O«Z>\dç‡B¿™3{ùv –eØ‚ñ–lŸ¼J˜µ5à;ÈïôgÑÔ¸-rÄ*Ît›G4{v=ÇX…}Ú5£5d¹ø…F:Yö_ 8ë£ùY´ò¶=™s¸y=þ¾‰ÔÝn@VšÏÊŸQì^Û­TJîÊâbž³<]^Èç¶ÒÅò΢]®ä¼Ÿ¸‹nÅÞqÜ4=ÍŒóKÉ›RûÑý"-"ÌS²v¾úH ¢Íi÷sä ÐÄì?5^ôCt¸+Þ’¥²võ§g‚±ºÚ.S#&eÛ¹ýrØ ¯â“›»þ‡¢T£‹úêÒ®á·R.òS͉*öÚWÞ ô ·ñ§dŠ…B0izñ-~`cý!»ëUDIz¤º…úã¨7ËidvçïìrAþL<ÝËêöCîO‚Ò·Q·«¢º&þöÁе½_ðIeçs•¯_=d­]§ìÐá qñ‹•Ê´ÛT)Êú“,¾†üZû F2»vaÇñ÷êŠû ËHoiÝAŽ@Vzùml´„¿¿«ÃþxVAdRJ@”¤û‡{x&Žfû‡.?çp!zªaÕ},xîƒá=Ìä¥ã®ÍOÎ×/År6Bó1àdµe—–[HýQÔ* |ˆkÒÉÿ[Ác3S…~ö«‰Ýo.ø{ËÈýò÷Èý³”#÷¿PuÞS»b/|¨dýüfÃ÷ÿ{µÞ­áû-6¾_ÂŒ°ar¨™ƒ’ wÚBꞃ|NžˆõsD¼øãðáä±ä½CêÏ ˆrd¼C½kpŒ5EÀÖôNt€òpÉ š¦5)÷ú ¢rÏÙoœJÕCiE‰aý/B¾˜€‡Ä°þãÇ“÷©ŸÅ”‡>ðP«ùOÒC|Øìh¯‡:àŽf=4âµ![Âó”å{Çz*N ô?Y©ª"\t˜€òÕêFËEüz%GEu֜ȓ<]áEÑšù„Qç´ØýJÖX·P†k(oa¨e]õ4-¬N°êMdC4îÜÜs*»Å°x7¸ÛÍBo)òxy68x7+©kÖÛ^¿ž÷#zÿÈ:¥²“¡eçìܼ•N§ç¤‰F¿´€ï ¿‹¯ýEÚÁcÑGĤ7Eøê„?…Z:u¤ŠÕÂM%Jx!¾•AÂߪ'ü¼Up¾øwÈLrþxNøòƒcݾkï„u<ïBDüü¤ÆºÓh Q›Z¿®9½0…#Šá–ßQTI³C]<ŒþiÈJ¶…Ÿ/Ú(XÊfõG!#ð` …(kIó—Ô ˆ’´ý¨ŽñŒX'U °ê=¿“ëduq5i{á-]ð+ncNR)Z;*ªl¹Ž,‘àFÂYȳñyî"œƒ<—<ƒè3×TߘÔ2c5À1"Ÿ ñ[Ò²!V ìO ;T·Ìø‘=²¬ø ò+­–ÖªW¥ìÕfKQ±e“샫Ø«Y¬p\ϼÕâ§.4×{Z5Uú°ž1C#¦í‘‡õâUyX/:5-ïD—´«%Gx$ò\SÜŠ#êQLŸ0xToÚúPr2¹í\gü(:S zºoyÈyÕêÕ¿—3„?&܃¼§RéæO5‘IQ’žŽ aG%V049žN§% B1M+@CƒËÔFyÇõîZ%úAì¥be×@K{0Q¡*Z™{8y^•ø‡'ø0\F(WHšE¤>- JÒfˆÑöã#sß%“´n„U£‰[†}– ×÷âv6rÚÂÄA Ïu9~ÀW„W _Iž>¤þª€(†ž¾gÓæ}Nˆn>¶ð¤JÔg¤E[àˆ¢ØªºtÍ9|Iõ^Ö©¼¤k™e€‡ûbM©x´›O‹,8Oc[±ù̬Xe§²_.¸Aœ©`¦è”µNF%†ü0ð«&{Iº‹qßõ‡ •·^‘ ºÖ\H–Abøxs J­X’ž¹RòRgy¦õ[‰–>¹œ‚<•ŒOF€Ó¬)~¶¢OÆjQf„É‚·ÐSÉ80\…¼j¬V:6?Ûùý°já¯Bxb6½Ö#õ)õÅ]sèQŸ€(šµr-8hŸ·ìLÆqÝbÙ?ùä‘…‚ñ‹\é§lIÚ;Ïòàz§„C_稼ã'“îW!›#¶p³Ií2ðäÕ¶È~p¸yM›8=xÓê¦U<~ù›£1»›dµk ŽÍ“h„æÆæe?7Í–cñÀÓ¥ý|Þʼ¶¼\GØ.÷¼öþU13™; |ʪ ýt‡¯œ÷Ö¬³“¶$ͳP“„ÂüÙÔL#Sܯ®ó¤lš^…lnýÙ"Ð)<œ…¬ôb¸~ú7¯â”9à5ÈæîŽœPس!Knï@VZ±¨¸ä:ð.ä»Ú.99oË*iî@V™Â#c»;ï¨ì§Ñ\¼›Õ¢¾u3“ýq ßL᣹ùøœt'F GX5åîQXÈ’IãÀYÈ&ÏšD –¤n8yNÛ5—˲SÊÛÄÁô‡GWz€$¯ßB~«mêpÈ©’ââPxÁ`Èw§2®‰`gX[x¤>% ÞþÚhгK,8¤C8Äš‚žIš7¤[[dÆY‚ž%å4Ac›¸#¼ÃÐ3Ãø *1¨úCÈU,‹é•»_rÊ^'+}‚*ÙNPÕ,V8AeÞjñS'¨>TM•>AeÌЈ¹Vä ªxGž Š‡NÍ'¨—´«%Gx$òUÜŠ#OPQLŸ0x‚J)«Å#Q’¡Ätm(ç z®½f;Кfßt¤u'pˆ%¶é(ÆÜ7·Ä=é¿?t™0 <YíŒñE.™4 ¼Yi¿JÞ9c@AÖtŽä”Úrœ‚%Lj¬EkÛ©dvUÒ6Ì¿…ü­¶•aÀó´.—¥•˜ÍÀÌpøúŽní(Ü%³®ÓÓ©ñŠÔYÀEÈ‹ñ3šÔ.A^ÒæÊùUÚ«qŠ%ƿު’dbø ²Ò©ñúœm…CžLZc˜¶§ª´}° `à ðd¥6rÄ%u§€!› zÒ2_ÇIà8«F§IzCê'DQ{z#ñD/áïÓLcJe~V…”€(IûlÏÄÑì¤S5žè«%SdMñD5ÛQ«x¢K¨Â!ÈJ3]ýô glˆ'*Wá«È&ü¿e<6S¡BXc¡Ÿýjâ‰IÙ2¨èåšü=¨¨@/å ¢t<ø›%úÔz¶ÇÆÝ!Fç2núý¼÷/ׯ¢@¶ƒ–"Oäƒð1äÇÚ¢dô‰€( f„G 9(hÑ!b‹öCîW1+bzˆØ¢’w ©¥ÝN¡¾•‡€¬T;¡ZRt²Zuhy…Ô ˆbÈ+‡ŠiwˆH¢¸$δbsŒI4äxCRŽ!õglxe®ë˜ÃÄ^;DÑ$ÃÇÊŽö:¦ÎàhÖ1gêƒðúƒ²¤Äè¡ç!ŸOÀ?bôPáÆPÒþ!õD1åŸÚþÈ&éñ®«½þA¼á*šõÏP]ûQ‰Ü Ûü× ¬)Æxlîé†KºYhŒñ¤ÜÓ vplˆ1®ëžºîéKzvµîéK8šu™ðÕ§àÂqÖ¾ZÛEQá«Å(¨'’wÂÊEÑEÓ‡5'ò5ôi¸€cÃxÅj9/v´Õ@±J!`ùŽdo2M+ÒŽ>èæØ°å®hÇú‡°ŠŠ1¢n?L'\‡¼Þ†ê€nŽêÕÙ2Š´FØtZwwy !¥Ex”ÛÖ³Ã6/BVš…jmCZØ„ËÏ H›GUÆ÷ÉyÐô¸B¨“õÀMÈ›m ÿjcLäס~„?s„È„?“4ùÅ8gæÈŸš•æÍp–p²ÚäAüm…בG[" Cˆ s`Mƒ†¬j0Mãß´¼ab4/¡µivÚªÉÒ&À BWþ´¶I£Vhÿ(m5Z/kZ7`Õ÷ìÒf ÁË ¾žè°hü6f Œ±ºýFÝ~@~ƒ¥ §Ú0މ¡Žæ$ŽÆ‰n ùqL)Fˆ0tù7Êé²Ãzs±^N~#åãÀ ÈúKqaLÔ c µa,3‹Ìš®]Y§±¦:la#,zg›‡“IX4ÉL'Šý¶,Öæ~{ Ê ÛÙoOC7Ç£·þ ›ÓÝÀ#ÒoÏ€ÊXï·?OCÀü X^•­Y2»øòCmdm{?_qÉ`J9$iÕ]øønõó>*ú»ÑϽ°ÎRñ7™tÈ× 7 –µ0GŸÿÖh÷ÚÓÀp•7 dï(PxªfwÓ7oB¾ÿ‚íŽÀ¡Mºk"õ·D1ôô­sGò`÷˜F·ÏÀA&¥DQlÁÚ¹#ï_REõ›2Æ}®°`Ð bM>µ›OD³x›0$Чbó‰!w$8 ¼ÃšrG&ÕÎWQGõ¦ *Çm"ô¬y,ƒ e|îÈ aHîHMÏ(æŽ$c.§XSîÈ8}2œfM¹#}b,w$™5 É©}ð!*wä}Ðsé6^ñ·Ò}©O ¨7(èš#Ì÷ÃrG*ÖJ|¹#Ás„ü‹ÚžVFJç ɤ»ÀÜ‘WMj—!¹#ãêeHÝuàkÊ©|–P5wä#˜0$wd;gwë, ›×Ñ<ÍͱçŽ$s‡OYSîHÕáËTîÈ Ô$áä1s3 ¥Ü‘dË40$w¤öVqd2„Ƨ¬­ •Ü‘oAUÂO§­FîH2l’;2.â’ºSÀÜ‘q—Ô޳¦Ü‘IM`Hý„€(jOo$wä3üýwLcJe^e‘I)Q’öÙ;<G½IçÈa͉œÌ|VÃE³ZVg,?\}í¬‘ÿ^™ÎÕݦlg¶Ä£Åáé'xZ$Îøé>AH ukÍ*míe~v÷ì|~¾!JêÜOË+·ç½ò'é'ø«?}y.|„nŽfÖe‹3~Ê»€¬¸&¿[.îïGÒôüÿ,%\„¬4y©³ú[ÿ]¾ÿ‚Òz°`ĆŸ~š~ÿvcúOhÁ£TI?Ñx Ba‘ªùDóõOd»i&ýËì/j«ö»ëÖ²¼É¿ƒ™„!i2U#Ó%yd?D¥{–×í—¶ô÷°ŽPˆí¦»@±,H­¾—¶ï°‰Po…"þv„ìkd¦¼q„A„#Õ^=‹¿½@Æñxud”·ð'XEh.“ÒYÈc)û-]Ú°MC8yHÛ0…Øe‚rÂä'B‘vüts43Ú,3¦AlÊæÊ^›ÌåÛ0)Ž5?ÃNÂÈ †ç­ݹƟa5a;ç6ts4ãý‰Ð¹瀴‘[0Œp²Ò«ÎÈÇ-¦1Í(20žð1äÇG{F‘…™„æf¿§a&èÈg‡ªúùðqJþñ<¡0%I¼nC7Gåvª¶{ÓùÅÞ+å°ËßCÝŽÑ.@zENêSªo „î©=‚›’†í²à€á0ds²º63ÅBÆ)U"4 ¹<’ö ©E­Â_í6éäÿåðØL…”a;Xô³^úÙ‰àKûÿÆjGÆk¶&]È®¦Wã+{¥Å÷ÞÿŠnñ‡Ý‹ï·ösù콻˷–nß_Ên//‹öïüyÔâž]X¬åŽä[¡¯í£¯}ô¯ÕŠýï8ß4Ö8˜\¶‚{G'km}µÊÅ_¾î8…+V¶hŠËÉæ*ô‹]»uL¨óÉwoÞ<{Æ%¡ƒ N¸WØ¿?;ÙÔþðñù½à—k|Ã)ü²³©¡=+dŠÙªàõÝE–ù³ñ/kÿ<ðçm`UŠ?лï>¼ü}¦ÂIæÿ³Rû¢žFeë*Ž«TìÌîS§äV=wªñ{Órß[O¯¦ÆÒé5–í~Œüˆá®õ*¢p÷ÿOj=Úìeë]Þ±]' g¶˜ñoú7irëýâ~%—÷ªUž¯ÂÊL {­i°t½‘ú9Q̽P£^”]'Óètd'pò€Š]᳥͂½öâç8Zw±ÐUaR4é œ[ņU¡$M£‚)¥~?-`CŠyÖ†ß-ȶèó[d=G×°p®‡·,Ô¢Ù +³k—í ÅøìÍ,‹eºzUB×ç(ö™®`u/P™hlþòª„&Bâ%MnRG@COß:äU7›g„oSû>…fÀQ¯}ŸÐ5ç€Dðе2ô²ð9çæ¶ò_«A$íâ„z3«Ðþ†Ò’ÊL„cÀ‹/#oä™/Â3ÀqVݶIš·„¢–£ððÌC}¬­Í–Ô§Ôk¶'uÍé‡)Q4kåÍ '_bíÔF9¯còÏGÀ´õÔ©PÌ+·mÙüÇVεì|Ù±³‘/½¢iÎ%NKk>ÒÀ~Š#WÈ’©nqÞr?åJžÝ•´õa·¸ŸÏÒ]ëŒÏ{ŸÊ,I»…9ª˜ @£§ =Ù.6T&dÖ3àÈJÕÑkµˆ:zbËæ7«¤Ì}| ù±ª¹Mß|ŸÕN ßguàãê¾Imúäï’ï¿Hý;Q =ýA—ìûYuog'NêSêuâQ‹åKöôe=À!ÖtÉ^Ò¼ÝÚ¢/9+`Ã%û¤œ&„„h'w„בzf¿d?kB~¨bÙQ»dŸìƒ™ºdoÞjñS/Ù34Tk‹Köñ*޼d¤sÉ>nD^²[qä%{#Šéí¼dOÆ?%éJÈ’ÜÎRH¯ªi†Ú;ÂÈýÚ¯é0ó¯n#c¨Bs¯n/X»¶Ûx{Úò~Tܶ$F† ±ZbÚ!VwBEÓa§ëgH[v¸y͘ÇNl–>…u†¤mø²RgX¿*°>ßN/¥—¤ó¬€ß@þFÛœy*v&N¹`WrŸy+Ÿs+”µÝ)dB&縴¢ƒå% ŠbC§¿úÈ¥sWö²ÚU:­©¿™[’„ƒª_Zfô+Õyƒ÷ú—TN Øð2Jƒ?a<ê§N,]ëÄ¢VQ;àðß@ðè¾|AÅÚˆKÄËgúN"ù/3;YÝ­²Ã« m\SOB{vk–ß癓ô)}føò#ƒµqu€U§¦lòzò Œ>³! JÒfÇÈ ´óƒÖÕ4Te[Ö«Ýã¼Èª(ãnYC¬š¿Æß^ïduï™5[Öôóð©†5œÐ¶ó²M‹ì´€•È%×´†@ ÂÇ'ÏiRÿD@”¤ÍàG^8ÆÛ´Î76­tu*+ÛȆѰ¯@6·(ldÂÖž¿&ÅÚÔP#›wÐÌ^½¹‘Å×€?@þ!þæ&^gúòÉóœÔÿN@”¤Í8àV•áæÖã`MSZeÙæ5‚&5R/ÇݼFФG!+mV²°uÎä[{ÏÏ(¦åé¦wðÖ’t&yxò=egÊtÝ#àsÈÏ“qÝ}à7õw>:±¥àšÀ·ßÆßÙ ÛüÕÔ<ß%ßËúw¢$mÆt wv;ùâ–u™4²µÐµ^ 0q»µºNàÈgTÔò@xõ}ÇK×ªìæ¤£ÐœiÇ!+-!ÌöhdÎ%àuÈJGä}4œ‡¬v@üí5+ ê"Ýbʹ§Pyd½ uä*Ö—\>ïþÙrTn¢-„¬?ÕºVvöŠŸ½‘òË®S°üxóQÏT—†Ñb&ç_òGTI{ÇŽøx òµø;és‚Ú60«8ª0Ñ2C¼¼'}Ò­dϲí_Øž·ãnÿâõœ!Ö”Xs­7¹!ÄÙs+v!k—³–W;9ÿ •ì2ò,ð&ä›ñ7&ñ.Ñ-È·’g1©¿- JÒfð‹Cˆ 7¦îgg>¹•²ýE¶A³Z|µ³Í‰‰lP®¤¸ÒSlPAÅR–¤»ÈŽ1àyÈ給;an:óÊsÓrío}„©…¡W÷!ß7诈¬¯¤n ¸y%š\®B^ÕnÌçø©aÖò%W‘N¼MV=~€üAÛº“*Óõ‰€m> §ÍÚ=]'sNÏ@VZÛÈÑfBÀaVÝö‹{œÐƘ¤~D@”¤Í˜D pŒw<±—s¥ééµ2À³XÝKð¸éIê:ƒ¬é²·ælrqâÂÙ ¨7£Ü/x3ƒý ½CÈZTMN>oœâ¾ëçë“t«…6EøòãøÛ–>܆—d¤þ©€(I›1…àoÛ:þɉZз¼ñÚ ì‡ÜÓšFsšÆ4Dº‘¬˜Ž†Šx´a ÎBÞ)ìTv›£¤ÓÂL/®º–Wq«ô?×ÚÛw#s_Fyy~!üò÷ÚdÛØrè),Ïà½bÙ±ì|i×.ìï9å\¦öL®µ]Ìç‹_‚ûhvÁëE²ÞO3Þ_È>†xãx²ÚÑ‘V$=ö³,E/šû“¡(©ë@V¢h¨ÚÎÍì÷ûÅJ”âc@á&èDÕŽó‹U²+QG–dÍp ò”qvŒþÃOöÂ_6þø'àÒÂý?]ûùRkcå{%\‡¼.û4ô‰CG1iápñf»rË2¦¾ñÍIzLz, ŠZ#8t]EÎ.¦…šRž]®¦dÛ™ôT@åG¨ÖnœÇÞ ãO?žã Ó˜e´r‘P=½‚•)È©£á;2鸀(IÏÅú³Å!]sèÖL€(šµ².Þrª]K ¦bóÖg;ŸËæ*_ƒ‹¹‚7TÙÁ'öœÊn1+}½cI¸y]g :n ?);vÅáû/J±¯Ö„«®xÍs"¶ I]'p ²ÚÀ.þ655ÔDÎóÈ€ià 䙸çyÂ{Lqê¥ûüó²D%ý—W _1>Á¬^Ìå-MÒÌë`&¡ðR"n–^3 ' OÄOám³¸Q–89H¿œ‚¬>ûŽêÅz~Jt98¾y0p„™?|ÁŠy0Pëð¡nßEðC'cÇâ§§$F<8=IÿàEÈJ÷'ZÒóÔOÊü\'@”^U¢Èñsœäg|p~,y~.°ZÔ`­÷¦rü\'XݹƒÄù¹^ŽCV´Zòót6·§JÐ4H™fuã&h¤L³ºèãÉ4 b¦Á”óªL‘#h¤L³º£ ‰4 bN@VšÞ´$hßžSÞqT)ºZ.Â=½ÌlAÑEÐr‘ÕïJž¢‹àÈ"ÓìDä(ºZ.²ºã‰S”ôO-È–yŠ–ÊÞ¢_•¢K åR²]-—ÚMÑ%Ðr)YŠ.–Km¦èh¹+EûÝý-×Qæè2x¹Ìâ¹ÅÁÑeðr™iÞâ×åè2¸¹Ì4‡:9Ž.ƒ—ËÌäJ^zSuÔäh©R4T+í¿;vÞ-†hæÑboÕw—µ*àFвªˆ¢ØF›NÀñ8–’VÑùëV˃ÙÃLžWoÇø&\A8y(y·ú3¢¨U@Ó§ZÇ1æ§Ð™ #é¿ê8Æ£áVè»ûè»Cb_l Èßc ÔRŽeüŽ÷øüo6œñÿ^­wkk8cE›M‡3–0Cï=PD8PzGÞ Ùz?¼yÓ¸ˆè¹ÇáB!_ÒÎ!õc¢çPçÚ<Y©–BµFÇj=œ`uwE“ö©?/ Š!ïL„ÇiýQí}ªëø2äË]ªUŒu|ò•ä]Eê¯ ˆ¢èª]s¨ô ˆ¢Y+}>7ldó$mƒêöAV³Éè!2ç,«n$øòEcÄ\Ç“º~V»•ØÏ궸=4ŠH®•sý oÞŸ«žÞ‚|KËU¡ïAýQAéŒõ.#@ ²eÐiµÍ§ÏsöNàR°¸xòU‹›¾™Ê9øyè\ÂiÈÓÉw¼¤~F@COPü`¾6èfu+Ť+Áß›E±½¦XøM¯ó~ˆÓgµ§µá@Ò^á¦ï°U§ùvöéV©¿" JÒ^Ca›#ÓcНvÜ¿%dm9–mñ 9ø…7ºW#¯KUåÁ´ C~¬3z„²±»ðó_é±Ü’\Tˆ(Ì‘ õ'6 ë)ø¶a?ä~mçž -I÷ôâs|Yi$jéž¾ìÏ­QHÅGc¬[Ó—•Z¤´†WY5Ô¦¦fV­rñ‹IÖ­¶¸ o”þU¢ Ï_A~¥mèk:ªž)æ÷÷ !ÖViå²N¡’ÛÎ9å´õ1â7:Õ_C~­ýD]ü$­¨8Ï1<ÿíýä|ý¹Zy²ë²m8ÙÜÄ'rÚGêYí&ã «;f®©¶Åí2RØ ®½i2¤ÃšuvÒ*ü¸¼YmkµeŒwO~^V¡Å p òZ2´¸|ùaR´˜>‚üH›½séZ#•l ëÀ×õû²›µÎµÖ1ç V±œuÊþ-£Œ]Â÷Yî§\©ädU‚î ïs 9±Õ¥:ž¼fµuEêSª¯£´ÌB pT¯V˹eWŸ¸S ÿÍúš‡ÿV^åc W ¯¨ñ‡z|Z õ¨Þ¸éu\PÈžÞ®ÆMf\%iOŽÁ{ÛØ¸ÅðªÉ6nþ>›ß”iSã¾€¶À±Mû€Èœ†wß·ÎWõÆL/ z€£•Aø6vëVÙ8hËQý½·–ðG3<~õ-Ïì¼¶ˆð´êýú“çWþáL‘ÎOys´â6ý™N„¼Wõw†KÚ˜fµ0[!bâ¢hšÕÂl…ˆ‰‹i°0$ºUb̶¸ÂB~êÂÔ£W.²Zd«Ö½2.V,²Zd+­+´&"[ޱ¦è•qÑs”\d¡Ñ+£'é¿Àj¾¢W¢§FôÊ%V k½2.~.±ZX«è•Éñs ¼\b¡Ñ+ãâç8¹ÄB£W&ÆÏ%Ö2ª—!~êD¯\fµ˜V!Ñ+ã"è2«Å´cMÑ+“#è2ˆ¹ÌB£WÆEÐer™µw|_f-Cz"¨^ôÊ å –èÌïhyƒiÎüt)z¹Á4;9ŠÞ-o°ÐЀ‰Q”ôO-ÖÐEµ¢WÞ-o&KÑ› åÍvSô&hy3YŠŠØÚIÑ› åÍX)ª½òxy‹…F¯Œ‹£·X-¨‚ÞÉMŽÞ7ytå¡NŽ£¡ ÏÎIu@¬JmŽì»öNGøh̓Î4,“âHWàÙ*6,%9rRלn˜ÂÑ EfÞ;•ýrÁ­èä9åýžÅ›¼HŸqâa,x\;Ü6ÐuŸìóÉiö†O˜¶8Öy Ô#\…¼*ûaKÓæ´È.¢U?®A^3ØCø×4"Ú=²§äÛCÕ‰t3= qÔë5=²´ ’Ö' Šfc ŸƒèÄ;Â?¢ÏAaK¹ÛûuH¤O˜~„£aºtÍ¡ÏôØpÎ6©Z„C8êõÞ©ˆ^¼'ýÞ.d‹{y%íGXÓ)3í•gÄ«R× 9e¦è…W'dÀ9àk:e¦ýü¯N†@ÂSfªÏ/ýzô_†œ2S˜\„žâñx©šÚý «7 9ÅAÏ€”gXè)ž¸x!am'/΀ gbåÅ9yC{ŠJǦ‡Y-ÈkÈÉ„¸˜1 6 ³Ð“ q1CŒ4r¬*©ñŒÔ ˆbèé[½lÀCó8gmšæú”€zÓœÆqü“ôN£vð4äÓ=ýžu^àó†c&íRß' úÒ ôõ·[ª`ç%­"/…½þÖv‹G”/ÅrØ;`10ÏHÚ-¤þŒ€Ê»ú¡Ÿjýú›-cL¡[OÓÏ~5¯¿ ¾=mùî{´"¿Õwßoÿ×?¯ÿ·ÿÖ@-åwßO¼÷<—÷ÜüÀý;úþj=Ûܯ¾]¿Rt_|ÏAžÓ¶XéÅ÷5jJ˜6DöÖÑ/Ê´C¼ú]ò¦EL§ñê[˜Z'íRV@”£àñå÷0d¥ Õz¸—ßBLã¤=CêGD1ä™™ç¹BÖú°¿µÀS¼·-Ûzâ”+¶×åqÜô'Ç)YkVfvzÃuí¯ÓóÖô‡J¶*ó3ŽÓsz/Ñ_B~i^Š/Ñ“¢×/Ñ%éÕ¡kŽ¿«* Š:ÛCãwU"nô€%؈ðe%ÛBƒ‰§6,{úYímP€=yh]3gÛÆÓ¬ÓØì'b“oLð£ 醴ÕFìabÄÇK¬)Ýb[î´”iz™Õ‚ñ\fŠãVDDŽO•„¬b“êÏHý‚€f–R¦³$êÇN‹ã£¤…B&¾µTìÍšæˆNó¿ M›'À\«R´vY^“¡gw!ߟ×bžÈ{ï%O(R_@COß³i—wüݰ•K7›ï¶iªÒ‹–ÀQoªÒ©km’u hf"œ®6œjÇjóáK*ú·˜¢ßIÚÜï¦!§-þZOZ&ƒ»ÍjIán³º Lq Ú¤n¸ yUÛ]ð’Ê)£À'Ÿh[3TÊ{_YÆ €%„C•†‰ð‡À"yC^‚¬4ë’ã }è Ç彬í)¥s`WD1¶n:ÚÙDüJêñI}ŠE&Á“ä¥öáï!Ô GÍZ™þÆ©´lKÒNñÎ4d¥u™É€¾j˜†¬4*É5dR7\„¼¨í³øÈ»^[åœÒðägÚ¶õe°ëw»*GdøIÞ (q\÷èÖÖjŠ£úk -3H]˜”üôÆ9]3Ž‹·J¹sb·²'{¨g Ö>„üPŲªE­Ø½º[©”Ü•ÅŹ¹ë(!:5­ŠD—´«%GxÄ­”‹…6(öZVÞ ô‰¦óf§dŠ…B¢àaÄ·øçõô‡2þ‘€(IPÂÑ|ÍRùØFä*A8“ËšˆU‚‹Öàš+ÖÛµjƒÇúì”)Ñu;½”^Zµö]éí=²ñ,p²ÒNZëÛ éC¿iaã7À?tcÄ›AR·üòɰgø#äµÙÓíÑÅ­8vV¶}“¿þ ùgÕZ0’çe‘xøð½·ù›ÂdRJ@õ¥ž–ãx&Žfûä“û•\^¶ O°`eIØÙÜN@««¨Â~ÈýÉûdŸãˆ¢V’w&ñØL…a-…~ö«¹`îù߯øí€+»Çþ/+ ÌR¾ðHÅyßýÜ¢üÍÿÿ?*N1<þ¿]ü¬{öÿ ä+Úæ*ý¿* Š‚¡ã¢ÊÍ]ڒ놌‹‡7)b\ô|øñké cÿ!ãbR>9ŽÏqD1ä“îj_eV‹#ÿÀ~ÈJµ1ù¸‹!žø€¬VZN!õƒ¢´Û)â¹þÈJµª5ú†x®Ÿ¿ÄV«-¯ú!Q yå¸çIt°ÚÁþÈ= øƒ€„±ɤýAå´€ 'Ï5ýqîã®c=Ï9y?íù9ç‹¥”õ±Ž!œ„–—N>ß ¿ú6@~¡ý4Ï2N>玲'vÉÞÊû§!øƒìíç+¹’÷3úˆå:;µùéVq¿µË_­=Ûýä¦uB>ƒüLûQØ/•ŠåŠ[çß5Í>Ø+æÌ¾÷p³Ï_~x1geíŠ-ýâ1òÇk?ÇÀ“âLîðO™JZ%‰`:óš–oÁ>•úr¯zJÊÂqà,äYƒ¾ˆMfR7 œƒ°äøÕaxü"«Îç «q¹õÂNXéKZH®JïC¾ŸÌ6Y7„‰Ï 4Š ¤óâ^¦±ZjúfÌ‹üS`¬îX\Ô \íã*äU%òÔ©³ì‚ô1'2ápòºùyØåb.+ëúQ¸œ°­ó°ê(1x¬%4;zÆ$çaâ5‘£4#{îÍÍÃÆCæaާ‡¹Ú"X‹{òuVP;y"ùY©Ÿ%i3ÆPã| ûSu÷ç_~.z„i=œGNÄøæþ{¥^¦ø^I®¥“ºN ð>IqÖ˜ÓcfÃÊìÚe;SqÊV®Íe¼º)ìX_vs™]Ëþ%çZ*ó/ŸC~®5¢Õ1íY¿‰‡ñ;k%n¿‰‡ñù†o—vC»U÷>‡®ìzƒa1“óûù/HrþŠÇ*ÑÎkZÚdq7ðäÚ–?~²_.{m/ÿÕ*¼ÿÙ¥R>Øù1çæö÷øØ“¶žÜ}¯Ÿ§wŠ®·:p ™¯ôX*‡¢ùyíÇk?Ç:ÕªßFx5Óë2ËΔ‹®Ë/F¸óž_ªƒi©œ+–éAé~¼Î™êuÈëÚOqÞÎfsþëËâ¶g–×Ì]ﱬ];kIÚ'Œeaé2oîdÇ”€ÊïÝåšû á4äim7ÍÕ5÷=¯ÍxÍDò¨Vñºë¼ßK§¼6üò·ñO‚8AHíkȯ“Ÿ}ú7¢$mÆ$j€c¼“ “6Å •mN«ÎtÄ)q7'RÇ𠱦o’³žTã¾®8ë)Ø{Ô›S“ÆR¿²dJÖž>€¬?rž÷»h§:Þ¨ï;Od„Z}µ\«·µÂ´(éæFê/ ˆ’´Ó¨Žñ¶úÙl"Û< ½À~Èýñ·yR× €< \1Î6¼y§³w ;Þ,¹ÖüCØ“¶«.å«]õ“ÖZ{û®t4­‡ð{Èßk“mcË¡§°<ƒ÷Š4ùÏ—víÂþžSÎejÏD½òùâ—àþ]°ö Yï§ï/dãJ¸yCkv:ËûY–¢—AMŽýÉP”Ôu +Q4Tm‹Ì½—Q÷„ü5žþ ”k¶.O³,;Èš!àdõ3®Qì0œ9Ò¹WàPÂuÈë²OCŸ8ômã¿‚?¿¢Ó𢌩o|s’^'“ ˆ¢Ö]W‘³‹¡¦ž@~OMɶ2é©€(†º‹n3ÜŠ ýHÏq•iÌ2Z9ÈÈ•ú>ÁÊäÔÑð™t\@”¤g‹Âñ³Eí“^_áÆäˆb¸Ç?EµöœÊnQú…å5ð€PxëglbqœšÔuÏA>gPmÄu Œ ^©$MRR^@COß*#éšg½QoZ@êS¢h4 ñSÇ·‹Ÿ% ¢›ù<½AHFRmD‡½b„e$MÊ#¤¾O@µ {±€Çf*d Íèg¿š°f"'´ yq¶¿Õkÿ<ðçÿx¢UÊ!/+8NÌ*ÿ›zñRëÓ®õâ“óur³ë†¾É §h³Rè‹yrÂI˜z>Sä_”e‡Èz9Äš^1Þ²ˆ)Û!²^ çÀ“ö ©åø…zSžôGVÔ*(Tëá’^ gÓv ©?+`Cjޱ~<À1‡Èn‡c“ݲŽ9 gpÔsLãë ¥ }6Lpk¥Ïç†ÍO†HÚ$†^à[;j6µÚèò8ü††Eëø!°iÖtDC»ÃØàw(ø«­³¬.ÑŸ¶Úˆ­òñäKÚü­jʹþl:ïϸU‚c\®B^5N”Sþ¤¼„ú¶ ÙŠ…+MçÞ;Õ6¾ÈÒ^Ví•}Y¹wnúfÌ%äj\M†åIªÛ'õ3¢zúƒBðÕG7«-A%_ þž‡€(Ší5ÅÂCôU''*÷­„íèjbÕQe»u«ŒÔŸ°aO4)ÏÝSÑŒWßòsÖ–cÙ­NV¬z¿öÖ±ÕgŠ´ àøÁ¥¼?S‰Üq ø ò+íç«àÜD®°³¢L[aÉç$Ùׯëö>V  òžF•}–¤ý¨ Žêì£Za‘CHÄ«aR›ò͈íZ±6 –³Wª|µÜŠjÖÙI«T Ÿ£]„|Q¹j¢¦@©«QyRZ渼œ‡¬´c#7Ü“:~šg²Ò[¨Ú'-Há8«%gu)ÝIÒ5g}ÙuÊJiOw ßÑ¢…ø©Óêžg笵5kI…kÀ_$CŒ»À—_&?’úW¢$Ý£Ÿ©aÂ=*}(4×£Þ¥}iÃü ü¨£ŸñS:+ }‡J}òv¨iüª5»Uô&>t಼@wÀ­ýRÉ3¶ë̹B6H„©wS8ùvo]ñRÖ¬¤Â'ìØŽ¡±KþTèê†#JÜ=©;Åj±q!Ç?t‘2þúÇ{ ¼K˜[ &ù²7e¯ÍçkÓý¼CÇEUbô W!+±7Tk—ßeåþÒ*0ßÒ¦U´¸öMÕŠ¦kþZ¬šÂÕÝ-LNƒ[¢ŸƒU5¿$JîõOþêÍYƒ¬Ö……¿´Û \gM'~÷4ô '~y€Â¿zÆè—Lz, ŠZË5rp”GÍa-:žÊ"“Ršiå¦ÉJ¶ÔƸJq'z4´!a8î„üFfø‹‡´×'¿ îTH(F™9¿×K*1ÊDÈùUÕ™åìœìî<œs¾^Ž{ '܆ »¢¨úüó*Á3.Ç!çgOú½·L)î}y7°Ulˆ^àkŠE=Å!±è’£ç´  æ9Vwà:.zŠÁDB.î&FÏ B¹XCÃÓ¿>þ‚_)Ö×EÐ’7£^Õº’£¨°‡+Ò5nfˆAN9éqýTQŒ­í¢oðp^ãLwDתRŸP}Ö'y‹û0‰/Cnh{äp‰/Cn$åRß' Š!tå 4»³ó’VM„ƒÍmQumzDùR,‡ÝN˜„+‡ %ïRF@µ ¼˜aá±Sè#ÂV‹ô³_ÍÅ cçû[Þ͸Ú@¿ßÍ0q7㩚ï„YÔoövÆÿY­ckëí E›MßÎ0#4âT ‰IoRÄ©œ˜4)ŸÇç8¢òÉ!×V‡ÈN: yؘs•TØ&OÚ3¤~D@”#áñrÆYÈJUªõp)Jùf¼Zh¹†Ô ˆbÈ5Þ88DžÒ~ÈJ=ФSø¨ØQý Õ.DË)Tlx¯é”^Ï)éêÛiIψÉI‡!›ëÈ¢=#ÞicOÆs.p4Û“Ñ%³´b“éJÈ%³Ø#Þ6¹d–”cÐmW±á’™!æÁ‚ªkºaW7Kvˆé†;ºY[‡úݨ€f‡˜± Ë÷‰Ÿ£Õs€ nZIšÙêù°ýýÜ`2楨[šü<áä©ä½Dê§DQôR÷a͉|at .àˆ¢h­ÓB÷‡åßä•OønV—½ñð†…Ô}àÀܬ>àd¥Æ¾"ß .×E(æK„³šüŸ Zñ¼•N§ç­ÜÏ9kÍz¾ñúó9i2‘m瀷 ߊ¯EÚ!ìê³w.í#uˆÜ ©U/÷ ål ãçt|ƒFdhäì9-Oâ>40ÂK/µÄý¨ŽG†Ä îÀ‘"ñ\64‰à›£$­#±õ`!¸S Í¢0˜p²ÒæsÄtkß­¦”½×ɯ¨³÷P­¨Õ„”€(Šè´®9CÁ—TÅp›î(ª„ oꞆ¬d[ø„k£`)›Õ…¬4ï o7Q‰„ÐGbF¶¤ùKêÇDIÚ ñX}Œc‘×ÕI&&í†ÜmŒ´/w ŲõÚ·•Q§B‹›²âýÈ]Iqå,xÂ%i3„¡8FÊžôWL’¦‰99OA67ºña¿T*;®k}±Ëÿ†Í—]§`í—²A\‡¼®mVWÙ©ì— ®,a&Á\”ٚ„9ñö‡×¯eéB¦ô³Ú¥‰~–H{&uݬvI¢›µe«Ô ئ­ \àh¶¿?銑%q@ T½5˜1„“âëÄgo¤¿Ø¹¯Ý};s–ÕÒÛžeŠË@yŸô³ZzÛ~¦¸ì««ƒ³µH-èÝiI®à&žòv ò’¹–Ójó¢¥—îW!¯&ã¥eàÈ´½¤”„xM@COß±)¸$ôù4ÓíCµŸÔ§DQ$äq]shÖ' Šf­¼Ø°ü‹AÖìç\¹²O)»éDÿœ¶Ï)Ø[yÚ&þ$ò[µJåâç\Öq­L±àæÜŠSÎ9| ~%|ù…öÓÜÜrvíÏ9Ït2Ç©Ð&÷˜ä Ïö9_/ªœ.o¯Ø¹|Ø‹/žàzA›*ZŒ%õ)õFoúëPæ~È¥o„Ð6g°iܨ63ç&3DIÚa‹à G½.F»V–XЫpD1ÀÉxB‘ý-˜{ýûãïÿH]'p€Ux+VLGCE<Úh•»¤¶ôŠW]ê$Wý5ŽYÖËËð á÷¿×æþÆ–*]8d7 °hÅ!¿öB¸YíˆN+’ÊÇÿ¾ jrìO†¢¤®8Àª‡÷ ©m2XX+‹±á5é4`Íú±¡­RÁT–dÍp ò”qv$#úJ¸y]öiè&bDߟßÒixQÆÔ7¾9I¯“IDQk‡®«È#aËBM=ü$žš’mdÒSQ uÝØíÚ ãÏžã6Ó˜ô´r‘àÞiÁÊdé¹t<¾#“Ž ˆ’ôäõž‰£ÞäU;¸7½ÂéP}¯PËŒ{¨ Žzµ’Šx4‚{ß C‚{kÏO"BÓ’ºN`HpoÕ—Æòѓɀ1`Hpï¸æg÷ÁÂàÞªÏ/}Ú†ô_òS†ãÆù©Ü{”$aMÁ½ã¢ç (¹ÂBƒ{'GÏ´Ü;.z®€’+Ìäéuyz® y¬°ÐàÞ†æí§Å¢’®‚”«pN/SìÈäºÊj™ªÇXõîEܼ2|µóVÃ*¨ÀÑì­†V¡½ïâ¡0Ýñ\«H}J@v!~J!´7醄öÖöHthï5xa…†öNÊ#¤¾O@CQ íý® dM¡½µÝÚû!\A8y(y·ú3¢¨U@Ó§Z‡ö~„ÇfL¡[+ÒÏ~5¡½ †‡nÜû|EþÜ[ –rpïg Þ{muÊî‡JvÃuí¯¿ÙèÞÿ‹Zß6w`to›ªõ¶nlï9ÈsÚ+Åö¾& Š‚aƒd£Œ‹ˆ%Iûf@!Æ„¼qSêˆ@ÒÇáÂÈ#É»†Ô ØJ²½®¡Nµ 8Y©ŽBµF‡ù<œ`¡ø’ò ©?' Š!ß ù¾yjWì´¢{Ä@ßcÇpè;d5š”{HýV£šî®ºçÁ‚ªƒ:X-è·pÿ[CcÞŠ e,ÆoãŽÔ_Po7xXs"·Ç»Y-þwH0 I{hZÈ®ÚKVWLö‹/ª˜6ó §…UÃÀ Í-ÂfŠñ¸Í ©YiÚ㬖Œp<@MCz,œÉ‹|ÍÑ2$÷1 PKš XVž˜k­YtÑ\Þ,1õäfeœ|ÞU6KØæ5hÖËÚvìÊ~ÙQ·¬Ö†Ü¨P¯°mÛ­é–7«¦ô­°QËróE2+ë”ÊN†vÜfçä­,28é°(Œ®´1™EqúªÛGÉǤ‚rÂäT|#~¤bTÔ7^íbiðê!VˆL‘ì+Ü48Ä®U#SûãÉ|SGYß¡kƯ&ÛÇ€ü‡60_ ®ó;”Ö!# :aä¾¶Ó~ðd¥Åœ,í…S1ò¢&e.Tiï:v9³KüÞPL1@–Þ‚|ËàÂ1*({7«¨š$>TcjA5% Šb[:§kÏX±!(»©¦­ýœøËC©†e×lÚÊAÙÉœ~`HPví×#‡ˆ£”=)þŽ…—¤Ív¹c’Nú£¼¤i@U»Ț´kï9t'8XÐVŠÞ¤âõÈŲBH`2±x ²Ò.–•…s¾a –“⩟°!ÁrRfˆA_ã£r?Ÿ©bŠ*iä8ˆL¨õN8Ô¸K?úW:]â5·s1˜I{Ï2ù}~ SÊâs@~&u5~nÄüläƒäIEê×DIÚŒ ÔÇx¸}‚6…$-›‰ { +m42~Þ_üÔí§NÅ)ïå Žµ[üB$Ânú÷•ƒž;ë-ñW­Ìn±è:~×ÙÊ%Ó{7”+·G×× Æ;Ž ·äU)gIš1šq4G¹Ð‚¿)»"ÛúXín«;ªÝ7µ³×ÄÝ2µMÙPÎÏo”JyzÅøÕª”í‚[*º9:²åúoéNÖ^É“hg³*‘ùF€Õ¨.þv¥ºÑí6Lr­Ùܶåî—JÅrÅÉÎY[væY]ßr%íŸ …+%qFS`0©]…¬4ê| JÒ=%Ç1Þž!õvC¶[#öCî¿[ u]ÀÈƺ…•º–Ö⛘ô©X@øòkmšY–û)W é×$Í»ÊjmÍÉõ3à*©=¹ gÃHýÕφՙaIš!F³Œ¿8ññýÒ“2­8YéEŽ\/@꺀C•æ$¡½À­§Á;jŽP,7õ²#ËÏ_@~¡M1¯ý½”îà èF˜`û¿ ž’Ú6¶RA@åöªµe` •Í£Ñ)·y¹ŠŸÔ¦ §’¯xR\À†¨I™!Ægq'€ÎaHZ6Ç‚Õ?¡ÖNŽ#è\¸…»•=ÙË‹dY/ðäWÊ]ó±êpu·R)¹+‹‹ùܶ“ùšÉ;éòB>·•.–wír%çýÄ]t+öŽã¦éifj§^¢,âÈo²v®ú@ 5‹Óîç¶[-~êBÑ…í®Xv¾²võ§§USÿtµ]††jíÜÜÎíxcuâŠOnîúJˆN:-º¤]-9Â#n¥\,ì´A±×²ònlT O4Ý«=ý S,‚@U#¾Å¿—Ì¿A?pÙþ˜ð[Èߪ<ŒùàWdÒkQ’æ¯á™8Æ3Ì+$˦÷ŒÀnÖ”,[³ÓžÚàé?­’íºN–V Eo¹P¶‚£:²›dæi .­ônRŽàblïÈ É³ˆÔ§DIÚ 1¼wŒ‡ TÒ /€Â„æ,¾u¾X•/Å…lÎ#µëu°vÞ_ò­·Z©{÷³Wªœ £û€ +íË‘[ ´,%iV‘ú‡¢$mF5À1¦CÁAIÛÁhBý“_©›nlðè¹A"mÿDc°­ìôlË«~?DnÞ–~3Kv÷×!¯+×퀮«—X°²åˆ¢Ë8KÒŒe°Œ£ã˜ló_M—ñïT€í¨…NQÔ·L½}"ƒF€£MžklC~x²É£Ò‘ñšIapŒi\Ö¯¿¥N}Ji?Ÿ÷–ïù W‘N¹E.@60 “eê€WUL¸½’Ú°í•Ôw O{UJ€K&ÇXõÐÜ-ö>xÔ`Šod[,)ìjEo¨«ú‰j‹¥×;YgÛÞÏW‚–;ëFÞohE—‹Àû¬S6iÖÞ 8VÅ„Û.©M͵ÝãÞzC¡:Y- „ò²?„ü0·Ý>‚ü(ù–Dê×D1ôô›ÂÜ´#Sš-XëñI}J@EF¦tÍyˆFÁE³V¦Œ0,kç#xŒpò´1֜ƕ‘RD¢Ó‡Ð¸Þ^/õ¸ÓØ›©¦S¢9[p5¥SÒÞN§´WAnÃ…ÔŸPyŠú©Öé”ã±™ #é¿êtJ&ò´Ì§t­#ϧ$pK9ŸÒe÷ýfÓ(ý_Ôú´·¦QÚ!:ç2^ÍÎó¤J‚x;]¿æts-½…üVû±”r-}' Š‚J¯¥“e©Ÿ5½•:¼Y+‚CdY€<¼SHý €(ív u²<¿Òk …¡é”ÃåW„¬VZ^!õC¢òÊ)!¤_ÄÄJC¬)8Al~+á‘Äi^R~!õâòË—‘J©ro.¶hÃÞþ$å*ý¢rI-Y ©”bóÍ©”’òÍ©”4}3(æ!SñŽ˜:é\ c÷Ž˜:i òXòÞ!õçD1äÓX,¨8¦›Õ’(aMññbsL7œA8 Y­{×r ý(†3ÐХݖtNB8 Y©o‘tNBw;)çú1Q 9g¨©O“uÏ)¸ä ½M›{Ä„QBPð¤ÝCê/ØÞHÓ=½b§&ë™Óðá0d¥ÞEÒ3bÎ,!ƒHÒž!õ#¢˜ïÕ‚-&Iç3çD{5án;{5Â1cìÕ”ÜÓ—ô±d{5aaÓÎ^Ô‹9âéÕ”<Óo&Ù«õÄmìÕHýˆ€f{5ãÙbXu/-,[¬¶·¢²ÅÀC„sç’÷}暀(ŠÞZ:¬9-sûu ØpSC±Z&ªÝmc–4¥DQCðá䉸|§š÷OÑŽ«-+K/gÖÕ€—WÛPkäŒS´#ÈïV«L9Ù1`ËíH;„2Í*jE9¡$M »Y-]7S|'õH%­Þ9xì\½lhi‘VO˜"Ü:SHØLœ^€¬6#«‘°Y¨°„ÍŠi'l&Í_sj'l3_™3ËDÂf1 •¹7]¦2#Ã"Bs/3# “‘° ªü@6 å„)È©6 dtsÈJ¯ÁÍ‘zí‹ð,d¥­YRÏÀ7„Âä^“/&““e£ÀeÈËm`ô%ÔÇ#ÖS_‘yL³=uGë×'-lŽAVê1eY-¦ª1·¬°æ ./B¾¨mˆÆšã jƒð­9„í–£´æ3o˜3ËÄšcÖš[sxFù@=«üÜŒòf‰1ÌÍU˜©¥¢»íK!1Bv[—Bâñùv.…ÒÐÍñˆ °‹,T ÊK¶ `áBsìZãZ¨±›¬ïÎ5—Jdûàï ÿ® ¼_Býqà·¥OqÈsýwð(¡°ç“4É~‡fÇÅÐÓ÷lÚüÚEˆîûxìßëœ>aþüÌïÑb8¢(¶½]sþÀ‚ÙGõ$J·ÿ#'^dAÛ'ìgæçFL¼þWÿ±úŠË¯ºj8»Ò0[¡3:–¤§È¤A xÙ˜§ZÞlé¥yàä¥d¼t¸ yYÛKA߯à–À»ÕÂØÊ_8né—‡À'Ÿ$ã—{À§Ÿ&?òúg¢$mÆO?«¨7ËjdF§ßµFæXޤÆ& :SÂ^ȽñSc@عOÛ'©KÒ)¤¿8y ÝÍ•Œ^„¬{UÞ'ƒÀqÈãºÑ/¹Ê®Š_&€3gÌn­îY¶tË5`r:·\.B^ÔvËPÓÍMÙþŒìYn@ÖïÓA:YYºü)p²¬:=oëdˆléBN`¯Ôu‡ %?Ú‘ú3¢$mÆ?€ ͺ­Ãà È7Ú=,“1÷!?LÆm7 ?J¾%‘úuQ =}Ǧ0$7íHSÿÌt[°Öã“ú”€(ŠŒLéšc£QpDѬ•éS€ÊÚ¹NCž6ÆšÓxµàß\¨%Ò˜i/w2à G=î4öf§hiÁÎdWöµ7]RìC6æ.¯G+dœR%Bó1`3ê’úQÔ* üh“NþŸƒÇf*¤¤O4nFÓÏzég'‚/íÿ«½ú¯Ùšt!»šnÑ>X¬ì•ß{ÿ+ºÅvo,¾ßÚÏå³÷î.ßZº})»½¼Ä«üΫ÷ìÂ"RGóZ­Ðwú›þµZ«ž>?Âh5æ/[ß8§L·§­­¯V¹øË×§pcÅÊo¿l®B¿Øõz¿u>ùîÍ›goÈ$ô.b~îTîöoÁÏN6þ?||¾p/øeÇß×Â/;›ZÙ³‚7qÈÑík^Ù]d™_1ÿòöýóúûo ”Jñz÷݇—¿÷fB`˜ÿÏJí‹z•=VðÚ;;óÉÞqžì:™OUßjüæ´Ü7׳«©­tzme;GÙ¡#?b¸'!‡/ˆÂ ðUëÐf/[ïòŽí:=³ÅŒÿŽË¦ñަÕï÷+¹¼×$䛂±„B¶Mƒ¥ëÔÏ ˆ¢`FhÌ‘|Q–ED± —ñÀ…ôá-‹˜îÓŠ)Bí1 I\8'åR?, Êð u¥]À“Òš~騴ó9;ì%ò 8ã Í ”cHýYQ 9Æò=â/â_rnÅñ&pþ «xLÒÚ“páUÈW :«’«äÃZÑI8ˆ°½©ŸP¯w;ôª1r £.àØðz_±Z,±5ϦÓéyË)—‹”;YÊÇÒî„Ç-È–AÖDÅÒæy ]/&Åš®À×UlX/J²¦C׿ð!–¶<‰MrVwöð†…Ô V[› ¦žƒ|΃#Ïzõ€´„cÇ’'0©?/ JÒfœB pToÎ-Ï5ú}¤i¶عFMêÞz¹mUÊûμ7—‹_,»€9ìÏc,÷ÖŽ[¸Z †z…'èn@ÞˆŸá§áGÂÇ'O-RÿD@COßú4c7›oý´i”êE›à¨7Jzneñ¯K@3S›G/ Ÿsnn+ÿ·„]k«Xô–ä+늕\a§±Qå\oeîVì|Þ‘¾KÙw>‚üÈàÄ'ê%Kt ´—R Ç6SjUoø„½dQ¬•©ƒ–X²fÁa„S§Œ‘æ w,ƒÐÈ÷*ÚDq„6Bˆôe<”«¤yÂÛßO=Lq3ÉL<2㬀ê›Zfo~ÚɨÑ5Ãxf!ñ•˜AcšØŠÝ F`NöÁLE`6oµø)ƒ˜ªµEæxGF`އNM»Ö˜ãöHdæ¸GF`6¢˜>ÑôîX*³ÞÐ@Æ?%éJHŒ¦9Pª¾‰Ü«¥m¦Nà3ÿš,âTœ°»eð5Ù‚õÅv…¬¾ôŽõ³S¦PxÖíôRziÕ*ïc÷]éy:™: \‡¼®µº sæH9ovVV2äÌŸ«+QI[iÇîð>äû½Ú"’ßÙàôíïNAV^5}s'p…U39j/5;'ÛðÈ€UàÈâoxçÑØ× ¯i?·¿gâØÒ;&dÆCàsÈÏUkáБú»6Ý`ø‰X[Ñß_`}u”5zÙ”P}‘¬eÆE<G³£ÙIÿHŒ¤It<®ØYi«'‚.Ñ'!ÇQ„ýû“÷É8>ÇE­$OBNà±™ ÂZ ýìWsÒØ™º–ç!'ò÷ó&ÎC>QðÝû³üð}Öý͈ü¿«õksˆtýJÑ=9yNÛb¥‘×DQ0#ôTCý¢L;Ä‘È3Ϩ˜1å<đȓwI9†ÔŸ°aÓ¼ŽÏDCVª¡P­‡;r#)ÏúQLyæuÑΪzF<™¤gÄmôÌIxƒ£žgŽ7˜ÓGmÆ¿®F.²$më`µÃg!›kÏc¢úºV'4/§ OãK䪞¿#œ†<­M—Q+˜œ¸A(¯õX4 ‘]œQ™Þ‡|ß`Š:Ḑ1„!‘¡“jCTVDQäé©ÃšÓòtn—€ 'm«¥¿nü›•¶ŠŸÙ%ìgMëhE«z,+¸,ñ8Ò ná äýj²ü&d­Y”cIÞ*ñ„¨¹jò¬Ú+~vpà[Þ*ñ¤¦9«Î[VÖq+ÙD¯mêÏÎÉ(;v@5 ¶¬²“÷/~Õùé äMãû„æfÇ–•N§¥éƒ}¬®ûÔ4&%…@`QX„WÓ}w¤Ðͱa¯SÑŽ±º)é,õóä/ùzâÇ·Ç [£®Zð+CFëEzl=8¦”ir&øýSl§l¸j!iNŠE¤±mÿ¤Õ™±N`HÔšÃÛÆÂ¦ò© KÁž~àk ݦ0}—ŸÆ·²m8 Yi:1‹¯½>mR; œds{)‘þjm¥ÈõÊ#‚ÚUÈj['âo•N>°!ÉVRfpŠÐT¯L;’–±Ú!Bý^9Õ¸ZzC{ÅÂB6ç~âÁ s¯›V0½²ßö2ÅÎ0ü=C6W¦7`þrNºa“MóÀ{ïÅß°IÝà}È&û“ˆ†-,UÛ¹5KêWTßšÕ2C<“_ÃîÄfš¤qtجØËš"ŒË7ã·l.às„o ¿Qî}ŽP Þ²IöÁLݲ1oµø)ƒ·lŒªµÅ-›xGÞ²‰‡N&oÙÄí‘È[6q+޼ecD1}Bï– ýöЧ§#Gu~dšð-ä·*ÏÑéïDIz¤?àè´¡‘¾‹¿•’´Ž¶9;Yíu'«;E­ÙsÏû§=ª/Ìhìòkþú-·˜ß¯ÐL_úˆY<|Yi…&Gøq¸p òZò¬"õDIÚŒ ÔÇxÈ­hj\&ìfM¦$yÝ¥[OdÆiÕ߉¿³¬ u†¶\ÇkUK~•lÁu„Â:Mc•ºZÞ²]ge…6Zß?ý `â-à:äuƒÍ½Åõ¶Ó¾Ýe¯ÏR3û p™5%:“3»é›yÙ¨aÜ»¤æ<ð1äÇÚLNÍ«Pö ð)ä§qQVÝ÷??Aþôë ì÷ÀMÈ›Æ(û-09Ÿ eŸ÷ ï%?V’ú‚€(º-Dz$í˜ xîc rJ¹åôéV ™Ñ+ Šfµœ°,銙Fe Çä LfB/=Ún&—‹ârÔž1Ù6< Yé´\"u§Xí ñ)¦x(ܯ’跭|q'—±óiËz¹­â·1àUÈW•ýÖ´=Iç#UÜ”.CVöåÜ4 ¼ù†¶$Ÿë–,¸ ¼ùŽ1Ÿ¤Þn¨xd ø²Ò‚IÞ#w ?ÒöÈ©y ºñáÉË—²Ý-²|ù•¶A¯¨»-;H†»}®õ¥œ«TœÂªU¬ì:å/9×±fñ.Î{k+W°Ë_iõOŸÞ÷Ö/‘çW£žg& ‡¯ ë?ÏezžŽãÇüË÷‚%V®àÿ{×É—Tò?_‚y„—!뽋 í¯h}¥`Ù=à*d¥—bò3Õ4SU0÷ð6äÛFf¨ôóÀMn*Eô¤î p ²M%ÙMRÿP@åM¥ˆ§ØR£®è$Ô>‚¬ßGJODIýº€(m˜ˆ CÑN„K’QɺAà(äÑøÛ ©;<ùœŠÚЩèêà¿ËŸÜ’q¨—ß³+Õ€R•" Ri%‡^®CV£VhO÷ŠT¼÷ ðd¥qSÞ{Ào!›|['õ¯DÑ4ãµu·ädrÛ9Ç æûå2%TŬ§Ê¤Ù›siëã.½ùÈ ¦G–»_*ËùÔWRøøò í§™¢§ñÃOÓäìÆ¼ÿ<ü9üÛ¡’f^…i„Â&„b+`ÚS›ï#tóõá d¥sö w —Ó·ÒK ;îdÇ%àä…ë" \„¼¨]ÖÍ4ÜS¨ˆ%àÈJ E¹95|žáè.dµcÁâo¥û!RO@”6Ì9„”K Ì9º¼5-£^úF[dÞ ðd¥Ñ_nØ"u§€cÇ”'{¦w«û_=¾R’‚/»N0,ØŸéŸ^cû‰m²Áuâœtf_2þ"ð=ä÷Úd;Ed &F²œ›ÏæXÝ}bCÓ¢Žé¿äJÓ² #c†€£˜Ö’ºÓÀôCŠÎ9gñ†æM:æiöZŠÒ[¬sà=á䥣੻ÀX¬“ºeàdýÅz*òy+Ÿ<>‚ü¨-cǵÀ§>êMëÓé-7¤éAÖœBŒŸ¤î$pò·Èï7’g€#•^Ú„¯:§ù‹’OÆd+ŸŒ§ «­<ÄßÎÒ°—+dstðÕ_U¾–üÞUèt®¬‘•ÓÀ—_j[;F {Ë vÙ-ëåN¡X¦pÙÒcÁõ€ >ŽAVš …ӪŠÑHZ]g 'p‹šÔ^bÕÜšŽ¤å¶mÕŽòÊ.©„;Ôþöøe¦±=~ø%M+OBíÈj¯üÄßJ/©Hý]QÚ0, —Ê“ØÆõþd·X”Î@Ö ÜÆ%u§€úÛ¸•±h[TÖö~ÁoBþë:Š‹›§¥”÷÷N9Hâ;“madôàKÈJ=´\ ›G«"|Yÿ]§t #õß ˆ¢;–n_ hS hÊ™Bµv#‹ÚV{iqª×JܘžX¯GÑ"À¸ÇÅÐÓ·N¥É3‡¤J'Îéæ/œ¤ÁCŽ)U>¦ÂUH›³È‚ÐzÍýjN¯)i×êœp²ÚÉØü‘LÁ–†¿+6`ÜcàøL8Ϊ±î“nΤ~B@COÂtÎ_fMYÿñI}JÀ67Û,¸‰ÅE³VôâîÞ„wn²ºx†š¬bÜ]2æ,ðÂÇÇÞ IÛmàÈOâØ×À §Õ.Y×=¤Â;Q²àðdý#®¯ÊN!KG¬*veßµö1hÐ2™óÃÚ²ËnÚúX´œ‚½•wj¿À§ç­/e»$û<Q›„æ®-¥—ÐÕþ#ãÍSèÎ’¤i`¡Xcø ½YO#óϼ2L\Þ‡|ß`shq_I¹ã [§Â~5››¾ù"p²ÉH­!¤n¸ Y?’bt)ïdYñø²RÙ’µ£þ;D§ìÎîä‹[véSæ$]gÁ+$»•ÞQËów¨Êßþ, Æ÷' +o7}s'ð䢮Žö‘/“”z“úõ¢·ZÜ.–"s!WØ‘%4Y³| ù¥¶UW*â3m=÷ZÛY™u*v.ï}[ÅýŠ%iëjð ä+í_1‘9óÀ[ãß„!mW·!+mÂÔoàÏ[¥ jY!ç:Ùrø²zïµ,xÌ—U‡¥·÷+ûe‡n=9õÑR«YXZ^È*åbºU؈ÅÍÀ;/ +M [..|ÎíœJÅ™®™íÛ<ÕóG¾µ K¿~‚l2(PDGê¾Æz'bñ8¨M÷ ïi·éå:©/ˆbèé»6Ýà ^ˆféú °MÛoOÐj9¢$m†°†Ô¬ ©W­‘‘V‘§DQ´çæ¡«'¢7{΂ÍFŽ(š^Jç¶­Y¼zkï9þÍæÙémwzÞò~èTò_ù4vÎú«¬ÍßÀ„iÈJûƒu6[–5cý®œ£Ð ÞtÄßÅ}êP€ìF¹l•µR¸+;Ô´ò®e…×í‹§Ïoûv©â—0˜PxÕ¢iü(h-míe¬ >þìîÙù¼¬qÂæ…˜2$¶ž%ÂŒo¡š£™~v‘×ÑO?MS&Šé?ý‰jë‰7«8®k½¼¶ŸÍçÜJdÔ(£_ÃPÂEÈ‹ÚF_µüÿöœ=s¯)uÆS»bÏÒcÌ[Ó™â~¡âNG'ÔŒ2ö $nrk{/0ÖOó±fÙîl´Á–Ь"³&FYÿ oâ4­ï$Ûç¤ùò¬Šú¤ÛÌ;¨æh¦Íøaf,ÿ¼ÑŸÉ‡ö¯®ªgZdÍü¦NAžÒ_“™4¶xí¹âì•È2?‹óKÅc"’5ÉÚúöê-„Åß^ò£QÕ%[ò {!méXG(¦Jšƒ¡š£¡iƒ¾ÙÊØ™gb" ûÆê½H{ÎgÝÖ¿#Ö!:묊÷~„E„BŽ(Më&ɺÅbž’–yýmåäÃï`á$äÉä)ö{¨æh†bÅüÓ”ôÖ…¢®eqŸ$˜¯6d¯Ú²3Ÿ‚VÞÈ\,KOaÿÓ …ý6ý‰v0ùA”¬ÏQ¬BÌ?Â2B‹™šh÷T­”µç'Ø@ØYI5\µ§61”µlÖCÖ¶ì„eý“¬%‚vÂ$n•D˜ñPÍÑL;½²’|üÏGŸ­ˆ0ðgE¨wLRüíí¨E$¬4²„ü3Ì%ä'Âô÷¤ -!mDØÆ%äTs4ÿ÷þµëÒU<º²BqQŸ÷ìJ9÷ËÏÙ\¹ÕªÇûµçøêU~µ‘Á³ óS«Ì­Ònôsíf·oK/‰³0ÐÜ*s*Xeš[ ;0ÐÜšd60“Òäˆ.W%»·¬Ý†…„Bœ'­ß²vÊÅýنʔ5nímýþÊ\Ö–]èßÅ¿¨iËS¹]¤ Á{]Ƽµ{Û—vå}Öš;¹%ݧþ;¨æxD·>Á´OF›s<[ yØGx´·„~íÜb(@5Ç#³ÅP„1„Go‹¡‹ìÃ?Â0ÂIÈ“ÉS¬ Õ¥[ .L'<º[ XFhA¶´­Tßb؇ „Gk‹á3¬!lïÃh'4·Å’¶ãè&LAN©Øªµk3[,TÊûaAžCÛWf²‹?òðOÎ1¥ZšvüuÀQ¹>BÕvo:¿Ø{¥<Ï*ÚtêƒÔý5WD†ù+jŸ£º'ŒÜRþXÐ}qT?|Âoæ…F©RËþøO,8gLx²ÒT)œ¤Âé&µÀaÈúhjvN¶µg#G >Ä©ÁBë 4¸3g)xÿœ€(¦©©–.‘Œº "ï%AÍIà<äùvQs˜†œN†šcÀEÈ‹Éwâ¤~I@c ×qì¼[Œè¯©=þ{ÖÖQìß-ªŠz£Xc›<¹_Éåe/¨ü,½û ÷ôI¦XÈ8¥J„æcÀ~ÈýÉûäÄç8¢¨U@Ó§Rï³!:ùÿÍTèHŸhŒËF?륟¾´ÿo°Ѳ¸­I²Ëm|š'‹•½Òâ{ïE·øÃîÅ÷[û¹|öÞÝå[K·ï/e·—ƒÅo°o´¸gë¶@Ò¼r+{=ú×jåzjÓc60dþ²õSp¼¯p²ÖÖW«\üåëŽS¸±be‹V¡X±œl®B¿ +_dê|òÝ›7ÏÞ†ñIè^Ä ¦Ü·Ü3ìß‚ŸlêÄøø|§í:þÖØÄ…_v65¶g¯ÿÏvjuÞE–ù³ñ/kÿ<ðçÿx¢Y)þ@ï¾ûðò÷™ 'šÿÏJí‹z•½Rqžðƒ…¢©æÃSÒrêÉÖÔt:½¦D»‹üˆáŽ…¿ 'ÂÿC­»rÙz\mòiš-füèÈ"Y°Þ/þå/I¿—çm ¦†l•+š+]k¤þª€( f„ ‘ÃaŒ²0b[„—vÏC>¯baÄŽÒ–D¨= 9P‘”HýEQލƒí^€¬TQ¡Z;6í|ÎÛ)¶êüZ9¦\3Z"õã¢(:(jý×: a”mû¶—UÓ<øò1×DÝ1= ž|FÛ1]Öw­éÙ¢† ›¤g%Wɇõ'AÉ“í¥çIP’£=µˆRéE³VÎýh—sÅ}×Bæç‘Pˆ."Üw{­¨ÙÙªµa²e8yÆ£Ú0i^‚|)yö’úË¢zøƒ"†òYe«[f$] ¤>% Šúz?¾ÿ]K±›¥ßõÏAVo:ºuF¿» JÒ®^¹j2¨•ëÆ‚Ž%)ËÞ*ÝÝ-–+?—íÂŽlîrºbÜËj)Œ{U›[ ã¾^íñ¤†Q4xúi&ÖUˆôu><]/ ŽïÙ¿´6(²+ëÜÌ~¿d“oW ‡äl¦O„&% ç`FßÌ”# úø{È¿O¾mþA@M3ŸI•ó_-ש($ßíCBÔ¢XÕ®ì8• £ŸŽì=äˆÑç?@–æZ‹Éöç—(Õ<ê´[¡ÐŽAÔ<…JŸÎCžWµÛ|4µ¾¡µÔ¢+èßö¡Õ hƽÖH&ýN@5Ô™7Ò¢®Nmºû[ÑRxÞ×~¦1|G¤W_dRJÀx&…|f‘+”ö+i·d—]Çë¼ê’4wÏOxfô™YÛ?³ºú8fKé[ægC¬Ö‰™ú3Û8³ õðˆÌ,„cÜÉÎ,š{ù™©:ü5Í,ÈÞ) Ù™…‘15³8ƒ?=ÃŽÜÌ‚Lú€Gbf1€¯à'ŸÐÌ‚LJ ÏÌb˜÷ Å´¿ê¨”s٭ѳxtB ²Õ¾I™1# J'#/ÌO*N>ßxýá™ùi…p˜S Ô¾iò=ðäÉO+HýGQÚ=­^”Ä8­˜ ™Vˆ]‡üŒ‚ì=|Yšfm˜Q½S@³3 #5bjFqz n(À£0£ “Þ ˆÒÞφ0ÆŽÜŒ‚LJ ÏŒ‚ïUwÓ6Ý]Ogì|¦ iîyü²4ÏÚ°* {§€fWFjÄÔª ?M£Å 1…c—ñ¬ Ȥ¢´wUp _±ÈŽÜª€LJ ¨¼*ª/ŠXUYÝøû¥£WYK¨ ŽêK(-3–ñL•j(rÑ•+TœrÁÎKZuƒÑU!+ 6Œùä|ýR,g#4±jg’´[HýQÔ* éS­ãéÞÄc3*„5úÙ¯&ž®ñ¬-Ãêžm Êo5¬îëýÿòŸþóm ˜rXÝ*>,Ù•œ¹çMØ2yÛýíÕýªur× ªëu¬X—O®i›¬X÷º€( f„^–ðy'iÅíö±¦Øó‡7)b¬ôüøñké `ºýû“÷Éq|Ž#Š!Ÿ 5w Qöµ¥Û <Ǫq( 9(2Ô±p—§z}l,yïúó¢ïˆqmÇ +USÄö@T c1’,?¹ªV/Zîá×86„TÔtÏiÑ=’Žé€3q¼CœÇæ>@ò@ÃÉ;†ÊYQ 9fäã®c‰Î±T†žN¸…pò¸AEEa#úN@žHÞE¤~R@Ei_¢ÚïE³VNS$-áÛ.þgXuJ°S‰Ü öwØ€#G Ưóü_G!jûf1hµVεlës®\Ù·óøQÙ)•×›~ÓSÌ»UÂíž>‡ü\Ûè7¹Âv±¼, è=5öù­|ž[jåü>IüäÞ¾[ñ~°ë”½µÅv¹¸gUvs®NèÞ7ßh?Ò™ Îéaö½åŸ(WÒ0”Pée¨É(Þë%cÎ'!+upr…Ô -È–¶“ºù»o•€ÅSÀ9ÈsÆjá påÒÉÍ\ÅÙ‹hmœmÜF"õTßFÒ2C˜9ôeŽr¤ÇšËöû!÷ÇßTHR‰‹ãbÅt4TÄ£ «XpòNaÇ[ùdví²×ë:^7í5#¯·ö×CÔ ëªky·JÿsýeJ,Ó3Àï!¯M¶-‡žÂò Þ+–½#_Úµ û{Þ‚3S{&ZååóÅ/ÁëY»`íÓÑ.7ãý…JdÑcÀ ÈZ]yIý,KÑP“c2%u|Wf²ECÕ¶86‚º' 9Ù¨H§k¶ìì8¿X%»Bg`T¢¼§ OgÇè?üd/üecá.-ÜÿÓµŸ/µ6VÞ¹£¬¶÷µy]öièa‡}e.†¢UnxQÆÔ7¾9I¯“IDQk‡®«ÈÙÿAæ<ü$žšR‰›ûT@”¤gbœÜøg'örnF¶?CÕ±º%nÜý9©ã !+u«¡;E‹½÷ÎZùœ[¡åí~Á­”÷3•ý²÷Cª&'Ÿ· 央¤[Ç@þ1´Áa¦ÑßÞÆÀ 1ö¦Oê1´'ŽÊm+Tk7v<·ÂXÓϪkõöÔªó;t§Øê\q¯`e rêhô‹dÒqQ’¦UV¿_<¡kÅìÅðlj¸î4ÊžSÙ-few³ÇAB‹5¥?Ðîy"®9’:þ ²ÒtSn5§!Ok³õ¢¿IhWdž²óû9ìBV%ðä ð!ä‡Ú–ÊÅϹ, UKT"ðáØƒÞ¢%²ïsì¼[ŒhJ¤m’é¶lñ·¦CêÉU€ä y ÍT=¬Û§ŸýjNÈ>]Ýò|üXM~«çã×þyàÏÿÛÿÜ@/åóñOUiÏúQŽ„gÄ#ñg!+UQ¨ÖÉ6å“v ÎfVÅkº¸k$ÒÁjÇáû!+õ(’Nác¢ø²y y§P°áT•¦SÆžÐ?ß-ÖËÂvÙ®î%Jš)žˆ· [½t˜ñS§’÷©ŸEÑK§uÍ9àD¼b­Äp">æ>åP§á‡ ƒqgÖÄÃΊ~Yˆ> _ÙµýØh´åâZ*/ëýí=V}qéËëÚ&Oåê:›`Ûª– *'ÌK<߮ט ÜF¶\ÎCž7F²›¥O;Z§ õ×qÓÁ(A$ò–ožƒ(úãRŒt•»iàKÈ/µ-|î3gÖ¡êÎÑŽgíÀgÖÚvl"ÚBÞùìäiïÑö™–¶ž:åÜgï~{q”ÎÈ>‡ü\ûYNÎ:;iÙ& DB ;!©ÙNÓ9¦Ï·­–S¸–Z¬šáØXo[ÛÚo DÕ¹æ|@V‰P‹yª¡šÅMßÌq ²þ„epÎÚó:Ï ‡ÏKŸô%s¦7 ßÐ6ËÊ:Û¹‚ã§ ,³¶÷ ™@ÌU¤­ä;Çx7äËæˆtØ)}À†IÍ5I}J@ÅvNmìF ­Ïz€ZûNfn¤ƒª¯´Ì`ÕÕ£&o¨VÎéšCµpJÀ†)ü :²ì:Ý^V;â9î :©Â5ÿ©:™â…M^¯;»ƒ‰ÝS­Í¥,?5AÆqW-ÇÎìÿüÅrw‹ûyéW¸ô#À ÿ Íÿ—[^‡nU¾²¹=§àýzpÄY|(·¸çX~H?ÿ]4KrýiæbÒs-ñûKÈúóÆþ`ŒÊÒ¢£"¿À"%hnx‡ïþS­É6žaøšð<äóñ7~Æžg¾ íŸ“>g¼r‘UoÐú²eÌ+]œÁ*޹ LCN'ã˜)à"äEmÇŒY.MÒÖ£bÃV¹Ö°|ù…¶y{ÎÞ–7òìæJ´3Rv2ÅrV¹™‹w& O´¹™“-—sçâg©›^ƒ¬ö¾³NJ3'®!«Ûh3'sî× ¯%ã˜%àCȵÓ4óy•[>€Ï!ëöÜQrü«­yÙmáÕZXØxm·DœmÔ Ø¤W!¤¾O@3ï”®/Po1tÐêC­c=O²¦ûðqµ_!F^Ø}xÉÅGGCU¤6,IW‘g#GŒõ®ýùâN.ã­öìRÉ?ÿ%mÜà-È· ú¨åžâëâλ¤`ñ8¬Qµ¸é›G·!ßÖ_ñU›¿h•^­‘1w€O!?Õ6ê%Íü-«6¿[ ¢6xDâëOo¡éÙMó¼RÑ[Woå¬?ýb*”Æ ûhnñù,x镱 Üò´õÖù…¬?0¿ñ' –òðÌû„Ö¹ôòýÁÙ7[q„VÝäž„ù„æç3˜*XꃴcC5Æ5H j…½ö¤GGRVÀ†¨ÄI™!mJ`îDð0Ù1zšãò4«¾3J•ˆ1šÔñ˜ZëCãÉ-ÖÅú¡ü>;ŽâÇ)ÐÖrÖù…¿÷YÏ’Ñ£ÀgÕÚ}˜'{y8•lõ´XNCžNf8ï]CšÈ׊vwµ^æ†~ó1  kö£«>“ê\emI3‰ º\¼¢mÜ ±1èí—üpŠ>ã3ù}º½ç[XlWÐ$í¾„Š$¼ù†± Ú—‘5÷ ?Š¿/#u7ë×ãm§l@ÞH~˜#õDIڌ˨Žñ޶=þL3],ç¢Ö[‘$¥%K/¿fPÚ©•#)©ëŽBVº0ÄP?uõ±ôW9:[‚®|ë®îtËv¬7àn{eUÖ»dõyàKÈú;zûd’×=VÊvæL¥øNÁ.dd¯Õ\ëµ^;ËuWµÂ‚$éöGê-Q’6c5À1Þn ›§§[„nŠìh›¥x²¹ë‹‘½©ëŽ@Vê|B§Ýò[cdÇð,Ëêî|È6z²h øò;ýYtõæÉ*Ît›G4{v)^yaŸvÍüØ=Å/4Òɲ_ÈÃ,Zy۞̹\‡¼ßDên7 +ÍgåÆÏ9Á !·aþJꟈ’´×Qã?•BEÒõ¼^àk =I]'p5…Š”:k"æP‘dô0ð1k WÛÂ……ŠLŠÔ¤þ©€(I›±€àoÛR üžFs"ìgMßãjZi4§4þ !ð»dÅ4¾°M8ð{~!üž5~W$[âßAPB½Ý¥V$•ü¾jrìO†¢¤®8Y‰¢¡j[Ä_BÝBVvŒ~'k†€S¬)ð»!v$ø}%\gÕø rOCŸ0ø}N¨Üð¢ŒÑ üN&=E­è~O 5¥<»8\Mɶ2é©€Ê3ŽP­-ƒSóN‚/(•f­d$8u¿`e rêhøŽL:. Jҳśx&Žz³Å ºæÐ¹í‚SêñO ZG„‹°ð6ˆ@(Ü 063ˆJMê:c¬šN î ÉmP‚0$§–*K-…J¿ `CN-C´è hñQ™³À[ã¹}Фv(ÈIðâ"ðä;É÷^¤þ®€(I›q-ƒ£z'*þöÁçÛÖ‡Š]ÈÚå,ò‹Çyë³Ïes•¯ó8ráM®íLZ-†ú]XMø²Ú®;oú¦äRú öÑ9Ù^à3ÿ:;¢u‘ºN ÖëìúX³QSâÈõ(p8Æ4wË5ó{ ?¦l¦ûOIß%ý€!_4Nϳé§Å|Þ.SšXW•©÷ÁNÂ)ÈJkV9¦Þ; §YõÔcòL%fXí„ΞÅÍÔû`'¡pH'q¦’þ+À«¯Ÿ© Vƒó‘@ÒÌ0“pœUïÏÄÍÒ0“pòDüäX!'!O¶¤ßNAVßÏŠeRí»VÁÂGÙU0°­£,p˜à(» J¶s”%ý€ñ²§~RæçpòˆÒ«J9~>'°ºùÉóóxù€ižc’ã§° /æ&ÎÏà%á8d¥A«%?Ogs{ª])×X¢›Ck åÓÜÒ%船¦œWeŠA×@Ê5Vwi9q‚®˜„•¦7- :è´ ³Dyf>d‰Nþ‚™™æäO—¥dÀ$ЂlÅÏÒ‡`&ádµÙŸKIÿ4«¥ð›fªW•Z-Q†ÝÝâ—ùê:%Ø—’´ôÈùˆ…&€Œ‹¨@ÎG,4d\üxN‡òX™ç’w©å¨8‡ºÖ.à9ÈJµª5:?í xä« N›´wHýyQLyçGdœ³~T;úp’ÕR:Çᨼ´B¾vzç$<ÂQÏ;ºæPéE³Vú|nãQqÛ’´IÌ ÜYͦÐ%’j†Z˜å:¾|Ñq#÷SH]?«Åºígu[ŠÅYV?G-Ípóþ,X–>x‡äã-È·´\zdÁøOÊ@ê]FX5ûµ/[Ö*ð-Î+XÜ Õ(gqÓ7ó¬à!ïUâ"0OÒH8 y:ùŽ—ÔψbèéÊTÉݬni˜t%ø›¢(¶× s0àdž´jƒ€¤•ÂÍ#¨Ê[é[w\·ÒHýEQ’ö˜ØØ…Nnåí]YSHl¬Ù–ZÝ(ì6¾ÛÕ¦vÔ ösToGZf³#ÍÚhÕœû¾u¾ª7æ~VË@; Yi©ìÛØ­[edÆyÕçßZf À[ÍðøÕ·<ž…å§mcÕûõ'ϯüÙ"í±ù±éÏdŸgÏ@ø ò+íç "7#ÞE®°³"k×lb¡¯$Ùׯëö3hîת²Ï’4c5ÁQ¯ß`‘3ˆ+ý¤6ä›}Úµ0bm,g¯Tùj¹•2E@žuvÒ*Uƒ0åa¯ï ­hRW¯Ê.?É ë¬àé:«{¡×ìÔ].@VÚÁUÛ"B)gµÌ¬ã¬.3«"Iºæ¬/»NY)©ð"ðä;Z´?uº@Ýó융¶f-©cÕ’µ®±ºd­qã.ð%ä—ɤ¤þ•€(I÷¨g¯V1á•Ô¦€æzÔ»Ô£¢/m˜„‡¨úlç÷å¬ٛģôšÆ¯Z³[EoâC²Ê þEíýRÉ3¶ë̱«BÖ BƒiEÑà …ËDš²f%í3y¦ «¯î£Æ.ùh^dÏ €(q÷P¤îp²ÒÜOvè"…üÍ v Ô¶ðêê}v.ÈF±+{SöÚ|¾6ÝÏ;æK–½då0p²{#óÔeåþVO`WõUf›óçÐ\8¦”›øÛ5-æw3¶×Oú'J„É©ëÿôs°ªöºÕj€B?b›ì#Œ¡ö× «u¡G!R­É»ë×eŸ†>a"R›p#4,R›ž1zÄ%“ ˆ¢ÖrüâוZt<•E&¥4ÓÊM'õ”l©cºæÐªªG@õ ‰˜^àÑÅ Å~ /ð&À\B³/ðø›VÂ_àM€¦„Ó§“o9¤~F@åxzfL¢8š™´$lʂՄ!Á¦äß65Ūa{ÂÂ`lòMjÑ¢ôÎôé^Ü!ÎÇXSŒ¸šù¨@Cõù¥/—‘þ À0†èi$ØÔ4«¥ÕX7S§Y-­¦ 'ÏTRί0‡\U‹©Â l*1¦’þ+À`S†&O}õ·$mœ- CnêÆEÑVËôrS7.fÌ€ „!‘(cégµùÊ8«»{ijˆUŽäs L Lpˆ½&¶uˆ%Îb/’—X{‡XÒß«iê28y™…FšŠ‹Ÿ—ÁÉË,4ÒTrü¼ ^^f¡‘¦â⧘^5$ÒTbü¼ ^޳¦ð †ø©iê «åw ‰4A¯°Z~×1Öi*9‚^aµT­!‘¦â"èò kïø~Ä$Œo|׎4u̼ÊB#MÅÅÒ«`&Ï‘Ûi*9–òl¹<]í$3»yÁR1G°°ªNœ¥¤Ÿ¯MB"MZŸ˜ˆ45 rβÐHSquäœe‰n¨Šé‹…µlâü˜/µ–ï1FššcµÊ ®_çX-…²ÖúU· #.µ¦Br- …ýÿÄ)Jú'ÓèÁãŒ4u ¼¼ÆB#MÅÅÑkàå5¦{TU“£×ÀÍkLs6$ÇÑkàå5i*©B×@MŽ–*ECµ¶Š45އŽHã›T\ZVQ4¦u iŠÎH÷°Z&߆FÚn‰Ž4%æÃ‚<”¼[HýBéºE1ÒÔ\±“[¢#M-À íuË\ÁQÙ-¡Ÿji*ÇfL¡£ Oüª#M™UÔ2ØÔDK~«Á¦^ïÿ—ÿôŸÿk»”ƒM}§àÀírÎÞÊ;Ï›²¬» Ü£¿Ù SÿµŽ®A§-6tJÂŒ°s,’ŠQf"øÔ$äI3#¦Û‡>eA¶’w©Ÿå¨9‰º\„ÊbÕ$†œt¸ T!{Iy‰ÔO ˆbÈK/~|þ²°]†v´· u Ùp4Û„.4zéÁ‚ªŸxL!~$­KÕPI?‰q„ƒ?Iû‰háˆWkòüäI–ôR—P’lMbø§6¶&}Š£ÙÖ4ý¡äM„í|þ«©Î¯¶úSoÈJSbIwuÃE„ÂkÒî¢ß]ŻνÈíìæ)¨Mà,‹{KÒÊ8†p²¹™xt,K‰Ðbm›Š“ú)õ¦âã‡5'ò=Ä)¸€#Š¢=´ #O'&Ÿ’•ul&ì‡Ü¯b\¨QEµleÕp ²ÒT0|É¿)žhR| rR‘ÂßÌò[3bkÍzûÃë×ó–[ñ¸ëýóùÆëÏæ­¼¡ÎûíÆ¼!·äÉßÿàý&NÏI3žâІlÇ× #íà[³Þjƒœ$éú@Âs•–AF›BüF8 ÙÜ4¶ES胣ÍÍcS³Òì!./C¾¬mHů²IÔÚ ÆKì–¤ ›¬hÔËrs{¥|nû+ï"¥-‚5„<æÃmˆ-«°HÙ“‚9bT4MÓf¼JsòÁ-ùt•kY§Tv2ô hvNÞR1f›¹^¢Ã¢OÚ1Ü‘°]¢Ûeɼ#PN˜‚œjÃÀ+†Þ9º¯0Ø¡—,¹Ltà¶` 6©{ÍsÐé̾[)îM óNVJsMëÁB7KšsüáOj÷ÇPu&÷Å 2æ¹ßÑzO®…Müö„ÙJ‚ùbPs›r‰1ŸÌžþòÚÀ|áŽTŒÌ‹Ü\”¤ÛEÐþ"¼Þ­êu£Ý?YÃ/"^‡¬´Õ'ÛÄPoûl:ÿ»Ý\f—ó•¢UÚÏçÓÖóbÙR°³8 yV¹%ßáµ¼P¼¼ ù¶ÁæÕâBñðä;Ú¼>IåTîß®B^5æ—Ã.ò#$Þè¬49”sx£WØ ÔtÐø¼•Ù-]Ǹ¾].î¡×ý¤(*—}ÏoA¾¥mâ)õÔ,s¨'B!·•"“Æt;m:ìÒ#`C$TձÒ4ƒß勸Ó'Y+Lv ïòu@ÖŸ‰+ÕB§€(†z™ãŸ]ÙyÕu|Žpò±~¥EøiRØ<êi!“žÒðÌ3Q’æ…xµ² ­c-b¾½­c-‚£ÙÖqÊÍThof»XÞS0lx²Ò¡ÙV2–AxòmÇœ°äç­dßPœ„±X-Y•ÅTpÖ5•kÐ!%é6+^ÈkCÏEjSÀ6ö\¤¾S@³=WïžcÒŸírº”/ʶ“|ŽoݺhñµR؇<®íšÔ¼Šo&€“Íõ\=Ùœ[rÊ®|Q²g¸ y9)ÇXÀo´É17· «­ÜB‡”½Ï%ƒÖ€ ?JÊ#·ë×µ=rrÞçUÂ8lŸA~¦OK–éÀ¥>¦ §Œ‘ãµZ‹Nû ÷%ÁRxع?ù GŸãˆbèù[åÓâ÷u™îC«AEŽ)eJÖiSØD^B% £ 5ŽÎj›ÈKh„ƒ•NGL#ö(IÝIàä!ýÎÓÏJ¢à—3@ž$Om»ÔÈy™–žšÞ¬´ï.ï©sÀ»ïj{ª¿º›L;ÉÒÛµdÌ=àsÈÏ•}vJ·“¡™`€mÚ®½𯊠/ëHm ØÆe©ïÐô²Î.òVu¹âNÙ–Ý’ºÏ&º¬#…]@sË:évBê'DIš!7Ñ68&ÜNn¢mÜlo;¹‰¶ÁÑl;éÄ™:£€#ͽ2mÑBn¢UjEaÑk!¤þœ€( Ì×—Ñné6 ¹ÆpUP›‚¬??—®wR\@”¤Í¸àÓaತm4çìš?d¶¸‘ÍZŸyÜ®‘…ØÝÏWè(lÖ®ØÞŒ±LÊø~àäµøÙ}>$|ùaò´"õDIÚŒ»¨Žñ°û¤¹CÒ´{ 4á)ÈJç?BMšyíß7Á´Í«7F·‹*÷±Ú*¨/À¸ }n#ä#†Òþ·“Hý Q’6ã>j€cL„öcBHš¶¯ÄBèGï½âgg+ƒëT¹¬S¨ä¶sN٠·ímªtWî½W@pÂ×_ÇOö¸”ð ä7ɳŒÔ¿%i3VQã!ûñt:-iØЛ°r·1ªOm”wüಮU²]×ñO½iIÙRKÉMfžÎCV: Gf!¹²øþ?i‘ú´€(I›±†à™»x´ Ië‚Å„}•ÞZ1XW3öw»NÁŸ‰Ð”Ú›zX{4½.y=´ß‘»óV¦¸·•+8”à»hÙ]CËKò%ë/ ¿ÐvõãÏN¦âÙL;ýÁE4Ï@ÏÞ½bÁûw…$‡Î¯,Û›yÏ'ùÀÂÇÇß` jŸ@~’|K!õODIÚŒuÔÇxlw5ˆ‹¤yh¥„ýûA·ßØ¿äöö÷¬ÂþÞ–7ðx¯RÛk h_¨YóÇ‚/ýCÀç•Þ©ÈÑ|Î$üò7Éó‹Ô¿%i3„þ%Fš4Þà•´ò N8Â4.¶ð­c?OÅñkOìVöd3»ecÀ!ÿ¨Õ[Õçên¥RrW½–çd¾fòNº¼Ïm¥‹åE»\Éy?qÝŠ½ã¸izš™Ú}騋Ś샫>ÐBÍâ´û9²oIÌjñSŠ%â²»âñ•µ«?=­šú§«í24TkçævnÇëµW|rs×ÿPBtjtÐiÑ%íjÉq+å"+U쵬¼ènã'N?È … çñ-~Ò&þ )–ä‡waæÊ~ùw*fŠÞXK&ý^@”¤‡ü§x&Ž1m"úÁ$M£³¤@ó›ˆW7¬Ì®]¶3oJ‹U]ØêMÁè>à-ÈJ'”åˆþ ®#^ã%Í&RG@”¤ÍxŽà©{jQr$íûlþŸï ÐÐË­÷ŽÇÜBm‘–+ˆ}Šå¬ÇøÙ½¢[±\~©i¿Þ£J-È–¶—®¿ÂÚu“u%Ù8|Yù1¤Íô¨7B­á7TkǦ°Ò4©$]µ©­ÕÂH}JÀ6Oµ¾¤Š(šµ²ôSÁûÿJSßè­µ)XL Úï_°$­þþ#\‚¼¤ÕM…îȩħ&“Ö€•f½=S>Wø¡ö.ð1d¥ñC®C$uËÀ'õ@t#šidhàV•ÿø²Ò1D£ GÚUï&86ó N†”nð’ ýÀ3Õ’ŲÖ!³Îç Ï%ã aà5ÈúÉ3/Zû•\>÷ÇÚq N¹nz*۞ȲëÀç laò©Ã¼õe7ç ’Výdþ}õóŠ[˜F— ¶ì9.J%Õ„¬ôb'Tk׿'çë—b9¡ùPk!©çRF@µ ?ìѤ“ÿ·‰Çf*Œ¤O4¾J¢ŸõÒÏN_Úÿ7V{‰:^³5éBv5–ùn±²WZ|ïý¯èؽ±ø~k?—ÏÞ»»|kéöý¥ìöòâg¿lW¾óW‹{va±qìXàiˆÒ¼¢+¤ÆŸ/?ú×jE{&ø' 4°eþ²õ?Ë¢>oë«U.þòÕ›vÝX±²E«P¬XN6W¡_ìzãi±:Ÿ|÷æÍ³·aÜz›°œCÜKìß‚Ÿl‹~øø|á^ðËŽ¿5ŽÂ/;›Þ³‚7Œù¯íyýw‘e~ÅlüËëýÿòŸþóm`YŠ?лï>¼ü}¦ÂIçÿ³Rû¢žFeÏ 8²ê¿Sßž–ûözÒ55¡N¯ mç(ÏzäG w0ätá>/œÿ_µ~îíeë]Þ±]' h¶˜ñ_\»2¹‚õ~Ñ_>ä2^ÍÎ{ÿrý* d;h0Uñvú½<·Sx$·ßj?–tí’úïDQ0CaË ê+´î†ìÞ¨ˆj¡zóIí1`ÈŽAR.!õý¢´×%ÔÕvû +ÕM¨ÖŽM;Ÿ³ÃNèÄ×Iûä>ÇÅO­3Â9'áÂØ0±9ç$B’È()çú1Q 9g¨Ñ9$ÝÓ—tÀ¶.Uû$ÝÃGOB!‡iÒî¡rA@SýYëýª(Ÿt¸¹šXÖ ?àþ]»ú3'­"Š!ŸÈç`ð’púÍá ŒÝK]ð áä©ä½Dê§D1ä¥>ÌÒÁô_Ò5ݰ‹ð,ä³ ¸¦î <’¼kèw£¢rÍhÓòNÉG=ð áä‰|$dÁ“¼&í#Ro ˆbª“kž¨yé£0ü1»½•†1·h‚³IxÃßaÔ¡º6S üíÀnÈÝÒD$Âß(JƒP]økaÂ_9Öñ“cOªjÜ~D•1MeD¹YgO^Á`¦U¸FÃhÇÀz´» îÒBŽvwC9a˜ÑŽ=m'rïèiKëF ú®ÐvçÞ!:„-…š*ÞÐÆžâSã Aƒ¹ãº³ì®×ˆMQ¡§h> ùáÌÿ(JÒÈ'{Çà„ê“=!‡ *[€…&0ó:Ä1Tad¡$S6×#Û€Û!o3×»¥A¹\ï^"T—ë©IªîÂh'Uã`GzRuŽk!'UÞQ7ÞY3a%UÞÚFj¼ü„æÆ Âˆ$UD% 4©:Ê!T—T Ä"ЪUNWoÕD×±±ßJÄö0•OÅp9{HF¤†Ë™‡4•Ãå~•σaèA…Ýí>Ô âí9OfP9ÝFs®uæµJ§®QS9×@(º•uÀvÈíAD—‡QK„:d]ÚrÔ[ÓåOOÈo2ràæèa4Íÿ LþLtÌÿ LþLÐæµtF©ù¯Q´,ï l™pä=!ص’ñ0R°ga„êû ‹ç_©?§0й5gQ;„êæÖTÀVšóªXf&®NÇNM{Ãbí:=Eð4äÓ!Ø%éa4ÛõŒ?¥ù2…RȈË: ®8…2…j"ÜYhZ¶×L:€‘XPa¢4£´ b\›!7Kó’\0"„M›¤I©XBuË”,ô°@‡PÝB?F»G´Œ&œsZÈ£ ('ŒAŽ…v³Ðía¤†¨sša Õ§K®·ÕÚ<¬À6ÈBc´¼ñ6‡ú!dö¯ >ÞuÀõׇoó( ÂOÅ(õ4HFj”úQyT‹ú(uìC+E(j!ÇÊ ÃŒ+3Ðía¤âʬæÆBõqE¬7 ‡# t8cµCêR!"ÐŒÄR¡ó( ÂOET¹’„‘Š*Aæ¢õ¨ò؆Uǵ£Ê œ0̨òEèöП¨¢lšæ—47¶nÒ”¯ÉŠ3Äe °K pMΗP_„¡®É!Û‘X“óe”aäæi~„[ ·H“S3Oó«àCíyš_;ÂÐÃÊ ð„rXù:”J…•šjOÌ)³†Þ6èzR“ #ì·Üû8?‰Çö0&úø¥h¶E–ÎSš{à›‡¸×Ån+ÉÉíiÍ=²öiðjåV“SãpN¦®¬®Ó¶h²Ílµ7Cû‚[›e ¸å"µ1`ˆ-©o`Pm˵"k¹ÞY£Ð;ÉóúÉ ¸p=d¡)D¼~B —7h'5_;øÙ-R7íÕµ\KSVqÚ,­|N€W'pò@P£w@ÞRÅìBë¹Õ )ÙÙiBCÀƒU#»€‡ ’®‘EÝNœç +Dax;äÛåCç5ŽÝ*-a rL™q,$¯`´ ع)ë … €qÈñàŽqŸ‡¸=ÿ’R„·«UÏ¡þ_Òds ©x ¦èaLØ$¯Ñ&0ˆü2 p!ä…Êœã:sýêŽQ¾ § l†Ü¬Ì@êŽQ’ºEÀä„|ãIƒÈ"õ² Èœ2¯¨^¸gËÌ[S»! »ó×T+pdùÀñòh2$s×™[cZyëÁ:[&Ûȼ¢¹C´†4\û-×þÊp·ŽÔÆ€!vëH}ƒª»uìŒTj+vëHá ºn·Ÿú â ÚB.Ã7< ØO.Ã7.‡ë'—áªõ“Ì© µØYÝ+Óy<ä2¼‚p dù—¦ÜBê[Ä@¾þ áÛ²NÁç Ï0jcåósîr'õ Ä4ï <ôi²Ž»`“Û«šÛFªŸdÖ7œJé³H‘½vž&èN²<“±i*lʰ 'c4²¦ù8pòÿÖý*êðäÁ›©?È ® i|%à¡?Ö½ ··—“Øk0gÂFÈÊL{Ópaj&kæì¢>m‹fi.ZÞ1ìæ¦ñzâkð@ÂnÈBo‘øŒù5Taäžà­ˆÔ÷2ˆ+hßC xè1/*mÛÅIíu˜0á2ÈB“™jRÚ:ìtÝ‚‘´ž5“v¾@³ÀÊm÷¤Øj "Û„,ôbϨ_GÕî‚,4‰RΚHýnqMãû(}2jC`_‰7`ÈoøbÔCÇœœ‚ÌØ= “…õ´5•Î\œcÛº•£ )­ÑIàQš€wC¾ÛSJÈh´‘ú# â šÆPúcê+«×Jq²|–NØ¢IL!ö:é Ôa»0mg3 Û€' ŸòËùÊs_Ú¶§‹{ûú2Ö¤™¼˜Ì˜½…žŒu¶7_˜ê3 ¶å|RìsºSf±—žfseeZ½;qûøHèÖZ~ ž ãÞâìTè¬Ù»Öå§É–‹{u#cm=9Z¦zjkXDëŒôLZSNK¸âEéÒM™Su-g«$,O®S#E»ÏM… Øñ¬LÑ7S ;ŠÕw,ߟÌçrnË Î¯ÄÆS•_XNß®pk´Ä;¼¿‰?&dÎ%à˜ZTäb-Qúƒ¸‚ù?Ä3yèOÈoÌ ö€ÞÒÜøN‡WÖtï:j\°²3Y=7“=k–ºlåmt×ÍSôói3WÞÒÊÕ>óÁ ® iü %à¡Oé_ép NjïÁ×Õ§ÇÍl~ÖÄKÕ>wÓ}+eælkÒr"‰»iAõ¾ð”zˆ&àÈBãØ|Æþª”ð(ä£Á[©?Æ .EO¿tÂðÞ™×Ðýû} ÷g¤ã}¸Œ‡¸¯I–ÎÏ5w&›‡¸éÌ™ã'¸qÍUÍuý«(ý•yN™ìWQÑW5•'iìÜ«3ˆ~Þ²Óå÷„´ÔÉÐ+Ë »E¶¹!Âqà0äaiâ‰bÒȘ)†/¯_  Cx¿„jåÞœ7x²ë6>€…J½Âã³öP„êvÚ²×éÀU&}Ðì¼98Þú#†­À}Åvq’2£_¡„ÅØV~ˆ T×V’õT·•dCå~¼5ã8pòHðÖôkš‡j­Iݪ²`S„íÛý·¯P$„:d]º–n!ûª59íã­J⸠8Y¾¯¶ôߠܥÂoM­‹'˜©‡s’JÒõ[iÓ–ò0Rc0äTûwî”—d©ôßaÚ=µ¯; ͹Qçdý{Ôa?ä~©fªæ`ÈARDi8 Y(ë­Ó2e¬Ü¹:j÷G ž‘Ô C–@nÄÆ½uwÁž¯ðGG ‹MÒSÙqüXsa€ÉÐÇp BuÉÐbu¢®‚,¶Ÿ/}¢µØ¹+˜ Z ÜYþð„õúŒme¬ÇL}ÊÌ™…kÒS^"fÛcŒ×{©C·~>m9“Õ'0æOÊ÷ Ž×+íò›5À 7øoD¤®¸òÆp¼œ(´7C;ÁßÎÃ'ð7ÂÈÄJR·x²|¬tjªÀí×Dax'dù×æÛœº° –Ó‰)­SØ;þƒk%”:f¦¦Öå)³˜,X¥IÂurdÒøG-Ôž©1(×sh¸Q:uÝèOšû:ÌC\’Ų³Nêú:éV©¯à¾3ƒ2“Ö¤•ÔKy9½Ÿ6ôãæLÁ°‘/r?ŸQ›„û!ï—~„È;]Vú>}6›<]Ì:ÎÐ¥:CzÇø±áŽ®“{wu맸™ÿl wBÞéŸMÖåñWèöPo Ô0‚”Up ÓiM\kÈÁ kþoàJ¨nªÚ Wó• ?y²TѧNuWNnÚ:[´· WýßA—p²Ð’Cɪÿt{(\õ5Õ6N˜ŒìtÆ ïsšR÷O¥VÇÝ"“úƒr-ru³Œ†œ{ŒdÒ,òN'û—æîæD¸òjeU³ÄÉprIsÚ®£ù& ºÓ»¸k†Ô·0ˆK¬j/˜£Óû÷o<¶&b”tGõû}úl}¶ÐýÑøÿ´Êt’ ®A_ÄkÎ’±>;;Ý7îü—/æHïè?;ceR·îìßu[jr ÏÙ÷”‘ë«Nè{½òµé×KcÿS._hnð4·AsS) ô$3N„¥_p?mv?52Vʲ/V¾ˆ»'-VߟÀÇsÿ`¥ûÍýÕqséóQrVïðùÊ—ËË_V>[1lÛF2=jN³>j]°rsJ¨4_½XãaÝo˜Ÿ¾×Hž3¦ÌÃi3yŽawܘ5]+O1·¯a-£‹ö˜‚Fð®¬ó“sêÙ£3§üÊ_Ì}ÆõÕ–Wã¡VÕ´Ní¿ÿòF·è$O SeuratObject/man/0000755000176200001440000000000015116566601013426 5ustar liggesusersSeuratObject/man/dot-GetMethod.Rd0000644000176200001440000000110415075522101016344 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.GetMethod} \alias{.GetMethod} \title{Get a Method} \usage{ .GetMethod(fxn, cls) } \arguments{ \item{fxn}{Name of a function as a character} \item{cls}{The class to find a method of \code{fxn} for} } \value{ The method of \code{fxn} for class \code{cls}; if no method found, returns the default method. If no default method found; returns \code{NULL} } \description{ Get a Method } \examples{ .GetMethod('t', 'Matrix') .GetMethod('t', 'data.frame') } \concept{utils} \keyword{internal} SeuratObject/man/labels.LogMap.Rd0000644000176200001440000000315615075522101016331 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{labels.LogMap} \alias{labels.LogMap} \title{Find Observations by Value} \usage{ \method{labels}{LogMap}( object, values, select = c("first", "last", "common", "all"), simplify = TRUE, ... ) } \arguments{ \item{object}{A \code{\link{LogMap}} object} \item{values}{A vector of values to find observations for} \item{select}{Observation selection method; choose from: \itemize{ \item \dQuote{\code{first}}: the first observation the value is found in \item \dQuote{\code{last}}: the last observation the value is found in \item \dQuote{\code{common}}: the first most-common observation the value is found in; most-common is determined by the observation that contains the most of the values requested \item \dQuote{\code{all}}: all observations the value is found in }} \item{simplify}{Simplify the resulting list to a vector} \item{...}{Ignored} } \value{ \code{labels}: A list, or vector if \code{simplify} is \code{TRUE}, of all values and the observations they're found in, according to the value of \code{select} } \description{ Identify the observations that contain a specific value in a \link[=LogMap]{logical map} } \examples{ map <- LogMap(letters[1:10]) map[['obs']] <- c(1, 3, 7) map[['entry']] <- c(2, 7, 10) # Find observations for a set of values labels(map, c('a', 'b', 'g')) } \seealso{ Logical map objects, validity, and interaction methods: \code{\link{LogMap}}, \code{\link{LogMap-validity}}, \code{\link{as.matrix.LogMap}()}, \code{\link{droplevels.LogMap}()}, \code{\link{intersect.LogMap}()} } \concept{logmap} SeuratObject/man/Assay-validity.Rd0000644000176200001440000000267515075522101016621 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{Assay-validity} \alias{Assay-validity} \title{V3 Assay Validity} \description{ Validation of \code{Assay} objects is handled by \code{\link[methods]{validObject}} } \section{\code{data} Validation}{ blah } \section{\code{counts} Validation}{ blah } \section{\code{scale.data} Validation}{ blah } \section{Feature-Level Meta Data Validation}{ blah } \section{Variable Feature Validation}{ blah } \section{Key Validation}{ Keys must be a one-length character vector; a key must be composed of one of the following: \itemize{ \item An empty string (eg. \dQuote{\code{''}}) where \code{nchar() == 0} \item An string composed of one or more alphanumeric values (both lower- and upper-case) that ends with an underscore (\dQuote{\code{_}}); the first character must be a letter } Keys that are not empty strings are validated with the regex \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}} } \examples{ rna <- pbmc_small[["RNA"]] validObject(rna) } \seealso{ \code{\link[methods]{validObject}} v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/IsNamedList.Rd0000644000176200001440000000166015075522101016063 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{IsNamedList} \alias{IsNamedList} \title{Check List Names} \usage{ IsNamedList(x, all.unique = TRUE, allow.empty = FALSE, pass.zero = FALSE) } \arguments{ \item{x}{A list} \item{all.unique}{Require that all names are unique from one another} \item{allow.empty}{Allow empty (\code{nchar = 0}) names} \item{pass.zero}{Pass on zero-length lists} } \value{ \code{TRUE} if ..., otherwise \code{FALSE} } \description{ Check to see if a list has names; also check to enforce that all names are present and unique } \examples{ IsNamedList(list()) IsNamedList(list(), pass.zero = TRUE) IsNamedList(list(1, 2, 3)) IsNamedList(list(a = 1, b = 2, c = 3)) IsNamedList(list(a = 1, 2, c = 3)) IsNamedList(list(a = 1, 2, c = 3), allow.empty = TRUE) IsNamedList(list(a = 1, a = 2, a = 3)) IsNamedList(list(a = 1, a = 2, a = 3), all.unique = FALSE) } \concept{utils} SeuratObject/man/SplitLayers.Rd0000644000176200001440000000137015075522101016160 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay5.R, R/seurat.R \name{JoinLayers} \alias{JoinLayers} \alias{JoinLayers.Assay5} \alias{JoinLayers.Seurat} \title{Split and Join Layers Together} \usage{ JoinLayers(object, ...) \method{JoinLayers}{Assay5}(object, layers = NULL, new = NULL, ...) \method{JoinLayers}{Seurat}(object, assay = NULL, layers = NULL, new = NULL, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{layers}{Names of layers to split or join} \item{new}{Name of new layers} \item{assay}{Name of assay to split layers} } \value{ \code{object} with the layers specified joined } \description{ Split and Join Layers Together } \concept{assay5} SeuratObject/man/angles.Rd0000644000176200001440000000106515075522101015157 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{Angles} \alias{Angles} \alias{Degrees} \alias{Radians} \title{Radian/Degree Conversions} \usage{ Degrees(rad) Radians(deg) } \arguments{ \item{rad}{Angle in radians} \item{deg}{Angle in degrees} } \value{ \code{Degrees}: \code{rad} in degrees \code{Radians}: \code{deg} in radians } \description{ Convert degrees to radians and vice versa } \examples{ Degrees(pi) Radians(180) } \seealso{ \code{\link{PolyVtx}()} } \concept{angles} \concept{utils} \keyword{internal} SeuratObject/man/Command.Rd0000644000176200001440000000130015075522101015254 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{Command} \alias{Command} \alias{Command.Seurat} \title{Get SeuratCommands} \usage{ Command(object, ...) \method{Command}{Seurat}(object, command = NULL, value = NULL, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{command}{Name of the command to pull, pass \code{NULL} to get the names of all commands run} \item{value}{Name of the parameter to pull the value for} } \value{ Either a SeuratCommand object or the requested parameter value } \description{ Pull information on previously run commands in the Seurat object. } \concept{data-access} SeuratObject/man/dot-ClassPkg.Rd0000644000176200001440000000125715075522101016204 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{.ClassPkg} \alias{.ClassPkg} \alias{.ClassPkg.default} \alias{.ClassPkg.DelayedArray} \alias{.ClassPkg.R6} \alias{.ClassPkg.R6ClassGenerator} \title{Get the Package that Defines a Class} \usage{ .ClassPkg(object) \method{.ClassPkg}{default}(object) \method{.ClassPkg}{DelayedArray}(object) \method{.ClassPkg}{R6}(object) \method{.ClassPkg}{R6ClassGenerator}(object) } \arguments{ \item{object}{An object} } \value{ The package that defines the class of \code{object} } \description{ Get the Package that Defines a Class } \examples{ .ClassPkg(pbmc_small) } \keyword{internal} SeuratObject/man/SaveSeuratRds.Rd0000644000176200001440000000737015116566601016457 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{SaveSeuratRds} \alias{SaveSeuratRds} \alias{LoadSeuratRds} \title{Save and Load \code{Seurat} Objects from Rds files} \usage{ SaveSeuratRds( object, file = NULL, move = TRUE, destdir = deprecated(), relative = FALSE, ... ) LoadSeuratRds(file, ...) } \arguments{ \item{object}{A \code{\link{Seurat}} object} \item{file}{Path to save \code{object} to; defaults to \code{file.path(getwd(), paste0(Project(object), ".Rds"))}} \item{move}{Move on-disk layers into \code{dirname(file)}} \item{destdir}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")}} \item{relative}{Save relative paths instead of absolute ones} \item{...}{ Arguments passed on to \code{\link[base:readRDS]{base::saveRDS}}, \code{\link[base:readRDS]{base::readRDS}} \describe{ \item{\code{ascii}}{a logical. If \code{TRUE} or \code{NA}, an ASCII representation is written; otherwise (default), a binary one is used. See the comments in the help for \code{\link[base]{save}}.} \item{\code{version}}{the workspace format version to use. \code{NULL} specifies the current default version (3). The only other supported value is 2, the default from \R 1.4.0 to \R 3.5.0.} \item{\code{compress}}{a logical specifying whether saving to a named file is to use \code{"gzip"} compression, or one of \code{"gzip"}, \code{"bzip2"} or \code{"xz"} to indicate the type of compression to be used. Ignored if \code{file} is a connection.} \item{\code{refhook}}{a hook function for handling reference objects.} }} } \value{ Invisibly returns \code{file} } \description{ Save and Load \code{Seurat} Objects from Rds files } \note{ This function requires the \href{https://cran.r-project.org/package=fs}{\pkg{fs}} package to be installed } \section{Progress Updates with \pkg{progressr}}{ This function uses \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \examples{ \dontrun{ if (requireNamespace("fs", quietly = TRUE)) { # Write out with DelayedArray if (requireNamespace("HDF5Array", quietly = TRUE)) { pbmc <- pbmc_small pbmc[["disk"]] <- CreateAssay5Object(list( mem = LayerData(pbmc, "counts"), disk = as(LayerData(pbmc, "counts"), "HDF5Array") )) # Save `pbmc` to an Rds file out <- tempfile(fileext = ".Rds") SaveSeuratRds(pbmc, file = out) # Object cache obj <- readRDS(out) Tool(obj, "SaveSeuratRds") # Load the saved object with on-disk layers back into memory pbmc2 <- LoadSeuratRds(out) pbmc2 pbmc2[["disk"]] } # Write out with BPCells if (requireNamespace("BPCells", quietly = TRUE)) { pbmc <- pbmc_small bpm <- BPCells::write_matrix_dir(LayerData(pbmc, "counts"), dir = tempfile()) bph <- BPCells::write_matrix_hdf5( LayerData(pbmc, "counts"), path = tempfile(fileext = ".h5"), group = "counts" ) pbmc[["disk"]] <- CreateAssay5Object(list(dir = bpm, h5 = bph)) # Save `pbmc` to an Rds file out <- tempfile(fileext = ".Rds") SaveSeuratRds(pbmc, file = out) # Object cache obj <- readRDS(out) Tool(obj, "SaveSeuratRds") # Load the saved object with on-disk layers back into memory pbmc2 <- LoadSeuratRds(out) pbmc2 pbmc2[["disk"]] } } } } \seealso{ \code{\link{saveRDS}()} \code{\link{readRDS}()} } \concept{utils} SeuratObject/man/DefaultLayer-StdAssay.Rd0000644000176200001440000000123015075522101020012 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{DefaultLayer-StdAssay} \alias{DefaultLayer-StdAssay} \alias{DefaultLayer.StdAssay} \alias{DefaultLayer<-.StdAssay} \title{Default Layer} \usage{ \method{DefaultLayer}{StdAssay}(object, ...) \method{DefaultLayer}{StdAssay}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Name of layer to set as default} } \value{ \code{DefaultLayer}: The name of the default layer \code{DefaultLayer<-}: An object with the default layer updated } \description{ Get and set the default layer } \keyword{internal} SeuratObject/man/Tool.Rd0000644000176200001440000000336315075522101014626 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{Tool} \alias{Tool} \alias{Tools} \alias{Tool<-} \alias{Tool.Seurat} \alias{Tool<-.Seurat} \title{Get and Set Additional Tool Data} \usage{ Tool(object, ...) Tool(object, ...) <- value \method{Tool}{Seurat}(object, slot = NULL, ...) \method{Tool}{Seurat}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Information to be added to tool list} \item{slot}{Name of tool to pull} } \value{ If no additional arguments, returns the names of the tools in the object; otherwise returns the data placed by the tool requested } \description{ Use \code{Tool} to get tool data. If no additional arguments are provided, will return a vector with the names of tools in the object. } \note{ For developers: set tool data using \code{Tool<-}. \code{Tool<-} will automatically set the name of the tool to the function that called \code{Tool<-}, so each function gets one entry in the tools list and cannot overwrite another function's entry. The automatic naming will also remove any method identifiers (eg. \code{RunPCA.Seurat} will become \code{RunPCA}); please plan accordingly } \examples{ # Example function that adds unstructured data to tools MyTool <- function(object) { sample.tool.output <- matrix(rnorm(n = 16), nrow = 4) # Note: `Tool<-` must be called from within a function # and the name of the tool will be generated from the function name Tool(object) <- sample.tool.output return(object) } # Run our tool set.seed(42L) pbmc_small <- MyTool(pbmc_small) # Get a list of tools run Tool(pbmc_small) # Access specific tool data Tool(pbmc_small, slot = "MyTool") } \concept{data-access} SeuratObject/man/SparseEmptyMatrix.Rd0000644000176200001440000000072015075522101017344 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{SparseEmptyMatrix} \alias{SparseEmptyMatrix} \title{Generate empty dgC sparse matrix} \usage{ SparseEmptyMatrix(nrow, ncol, rownames = NULL, colnames = NULL) } \arguments{ \item{ncol, nrow}{Number of columns and rows in matrix} \item{rownames, colnames}{Optional row- and column names for the matrix} } \description{ Generate empty dgC sparse matrix } \keyword{internal} SeuratObject/man/SpatialImage-class.Rd0000644000176200001440000000202315114353666017360 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/spatial.R \docType{class} \name{SpatialImage-class} \alias{SpatialImage-class} \alias{SpatialImage} \title{The SpatialImage class} \description{ The \code{SpatialImage} class is a virtual class representing spatial information for Seurat. All spatial image information must inherit from this class for use with \code{Seurat} objects } \section{Slots}{ \describe{ \item{\code{assay}}{Name of assay to associate image data with; will give this image priority for visualization when the assay is set as the active/default assay in a \code{Seurat} object} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} \item{\code{misc}}{A named list of unstructured miscellaneous data} }} \seealso{ \code{\link{SpatialImage-methods}} for a list of required and provided methods } SeuratObject/man/dot-FilePath.Rd0000644000176200001440000000112115075522101016157 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{.FilePath} \alias{.FilePath} \alias{.FilePath.default} \alias{.FilePath.DelayedMatrix} \alias{.FilePath.IterableMatrix} \title{Find a File Path} \usage{ .FilePath(x) \method{.FilePath}{default}(x) \method{.FilePath}{DelayedMatrix}(x) \method{.FilePath}{IterableMatrix}(x) } \arguments{ \item{x}{A file-backed object} } \value{ The path to the file that backs \code{x}; if \code{x} is not a file-backed object, returns \code{NULL} } \description{ Find a File Path } \keyword{internal} SeuratObject/man/Assay5-validity.Rd0000644000176200001440000000224315075522101016675 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{Assay5-validity} \alias{Assay5-validity} \title{V5 Assay Validity} \description{ Validation of \code{Assay5} objects is handled by \code{\link[methods]{validObject}} } \section{Layer Validation}{ blah } \section{Key Validation}{ Keys must be a one-length character vector; a key must be composed of one of the following: \itemize{ \item An empty string (eg. \dQuote{\code{''}}) where \code{nchar() == 0} \item An string composed of one or more alphanumeric values (both lower- and upper-case) that ends with an underscore (\dQuote{\code{_}}); the first character must be a letter } Keys that are not empty strings are validated with the regex \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}} } \seealso{ \code{\link[methods]{validObject}} v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/Graph-class.Rd0000644000176200001440000000104515075522101016050 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/graph.R \docType{class} \name{Graph-class} \alias{Graph-class} \alias{Graph} \title{The Graph Class} \description{ The Graph class inherits from \code{\link[Matrix:sparseMatrix]{dgCMatrix}}. We do this to enable future expandability of graphs. } \section{Slots}{ \describe{ \item{\code{assay.used}}{Optional name of assay used to generate \code{Graph} object} }} \seealso{ \code{\link[Matrix]{dgCMatrix-class}} Other graph: \code{\link{as.Graph}()} } \concept{graph} SeuratObject/man/Key-validity.Rd0000644000176200001440000000161315075522101016260 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/keymixin.R \name{Key-validity} \alias{Key-validity} \title{Key Validity} \description{ Validation of \code{\link{KeyMixin}} objects is handled by \code{\link[methods]{validObject}} } \section{Key Validation}{ Keys must be a one-length character vector; a key must be composed of one of the following: \itemize{ \item An empty string (eg. \dQuote{\code{''}}) where \code{nchar() == 0} \item An string composed of one or more alphanumeric values (both lower- and upper-case) that ends with an underscore (\dQuote{\code{_}}); the first character must be a letter } Keys that are not empty strings are validated with the regex \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}} } \seealso{ \code{\link{.KeyPattern}()}, \code{\link{.RandomKey}()}, \code{\link{KeyMixin-class}} } \concept{key} \keyword{internal} SeuratObject/man/RegisterSparseMatrix.Rd0000644000176200001440000000112715075522101020034 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sparse.R \name{RegisterSparseMatrix} \alias{RegisterSparseMatrix} \title{Register Sparse Matrix Classes} \usage{ RegisterSparseMatrix(class, package = NULL) } \arguments{ \item{class}{Class name} \item{package}{Optional name of package; by default, will search namespaces of loaded packages to determine the providing package} } \value{ Invisibly returns \code{NULL} } \description{ Register Sparse Matrix Classes } \seealso{ \code{\link{.SparseSlots}()}, \code{\link{IsSparse}()} } \concept{sparse} \keyword{internal} SeuratObject/man/dimnames.Assay.Rd0000644000176200001440000000303115075522101016555 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{dimnames.Assay} \alias{dimnames.Assay} \alias{dimnames<-.Assay} \title{Assay-Level Feature and Cell Names} \usage{ \method{dimnames}{Assay}(x) \method{dimnames}{Assay}(x) <- value } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{value}{A two-length list where the first entry is the existing feature names for \code{x} and the second entry is the \emph{updated} cell names for \code{x}} } \value{ \code{dimnames}: A two-length list with the following values: \itemize{ \item A character vector will all features in \code{x} \item A character vector will all cells in \code{x} } \code{dimnames<-}: \code{x} with the cell names updated to those in \code{value[[2L]]} } \description{ Get and set feature and cell names in v5 Assays } \examples{ rna <- pbmc_small[["RNA"]] # Feature and cell names can be acquired with `rownames` and `colnames` head(rownames(rna)) head(colnames(rna)) # Cell names can be updated with `colnames<-` colnames(rna)[1] <- "newcell" head(colnames(rna)) } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} \code{\link{Cells}()}, \code{\link{dimnames.Assay5}()}, \code{\link{dimnames.Seurat}()} } \concept{assay} \concept{dimnames} SeuratObject/man/split.StdAssay.Rd0000644000176200001440000000624115116320014016567 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{split.StdAssay} \alias{split.StdAssay} \alias{split,StdAssay-method} \title{Split an Assay} \usage{ \method{split}{StdAssay}( x, f, drop = FALSE, layers = c("counts", "data"), ret = c("assay", "multiassays", "layers"), ... ) \S4method{split}{StdAssay}( x, f, drop = FALSE, layers = c("counts", "data"), ret = c("assay", "multiassays", "layers"), ... ) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{f}{a \sQuote{factor} in the sense that \code{\link[base]{as.factor}(f)} defines the grouping, or a list of such factors in which case their interaction is used for the grouping. If \code{x} is a data frame, \code{f} can also be a formula of the form \code{ ~ g} to split by the variable \code{g}, or more generally of the form \code{ ~ g1 + \dots + gk} to split by the interaction of the variables \code{g1}, \dots, \code{gk}, where these variables are evaluated in the data frame \code{x} using the usual non-standard evaluation rules.} \item{drop}{logical indicating if levels that do not occur should be dropped (if \code{f} is a \code{factor} or a list).} \item{layers}{Names of layers to include in the split; pass \code{NA} for all layers; pass \code{NULL} for the \link[=DefaultLayer]{default layer}} \item{ret}{Type of return value; choose from: \itemize{ \item \dQuote{\code{assay}}: a single \code{\link{Assay5}} object \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects \item \dQuote{\code{layers}}: a list of layer matrices }} \item{...}{Ignored} } \value{ Depends on the value of \code{ret}: \itemize{ \item \dQuote{\code{assay}}: \code{x} with the layers requested in \code{layers} split based on \code{f}; all other layers are left as-is \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects; the list contains one value per split and each assay contains only the layers requested in \code{layers} with the \link[=Key]{key} set to the split \item \dQuote{\code{layers}}: a list of matrices of length \code{length(assays) * length(unique(f))}; the list is named as \dQuote{\code{layer.split}} } } \description{ Split an Assay } \section{Progress Updates with \pkg{progressr}}{ This function uses \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/IsMatrixEmpty.Rd0000644000176200001440000000111615075522101016462 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{IsMatrixEmpty} \alias{IsMatrixEmpty} \alias{IsMatrixEmpty.default} \title{Check if a matrix is empty} \usage{ IsMatrixEmpty(x) \method{IsMatrixEmpty}{default}(x) } \arguments{ \item{x}{A matrix} } \value{ Whether or not \code{x} is empty } \description{ Takes a matrix and asks if it's empty (either 0x0 or 1x1 with a value of NA) } \examples{ IsMatrixEmpty(new("matrix")) IsMatrixEmpty(matrix()) IsMatrixEmpty(matrix(1:3)) } \seealso{ \code{\link{EmptyMatrix}()} } \concept{utils} SeuratObject/man/KeyMixin-class.Rd0000644000176200001440000000273415075522101016552 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/keymixin.R \docType{class} \name{KeyMixin-class} \alias{KeyMixin-class} \alias{KeyMixin} \alias{Key.character} \alias{Key.KeyMixin} \alias{Key<-.KeyMixin} \title{A Mixin for Keyed objects} \usage{ \method{Key}{character}(object, ..., quiet = FALSE) \method{Key}{KeyMixin}(object, ...) \method{Key}{KeyMixin}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Ignored} \item{quiet}{Suppress warnings when updating characters to keys} \item{value}{A key to set} } \value{ \code{Key.character}: \code{object} but as a syntactically-valid key \code{Key.KeyMixin}: The key from \code{object}; if no key set, returns \code{NULL} \code{Key<-}: \code{object} with the key set to \code{value} } \description{ A mixin (virtual class) for enabling keyed objects; provides consistent behavior for getting, setting, and validating keys } \details{ \code{Key.character}: Update a character to a key \code{Key.KeyMixin}: Get the key of a keyed object \code{Key<-}: Set the key of a keyed object } \section{Slots}{ \describe{ \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \seealso{ \code{\link{.KeyPattern}()}, \code{\link{.RandomKey}()}, \code{\link{Key-validity}} } \concept{key} \keyword{internal} SeuratObject/man/old-assign.Rd0000644000176200001440000000152215075522101015744 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{old-assign} \alias{old-assign} \alias{[[<-,Seurat,character,ANY,ANY-method} \title{Original double-bracket assign} \usage{ \S4method{[[}{Seurat,character,ANY,ANY}(x, i, j, ...) <- value } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{i}{The name to store a subobject or various cell-level meta data as} \item{value}{New subobject or cell-level meta data} } \value{ \code{x} with \code{value} stored as \code{i} } \description{ This function has been replaced with value-specific double-bracket assign methods and should generally not be called } \seealso{ See \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta data with \code{[[<-} } \keyword{internal} SeuratObject/man/sub-sub-.Assay.Rd0000644000176200001440000000345315075522101016425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{[[.Assay} \alias{[[.Assay} \alias{[[<-,Assay,ANY,ANY,ANY-method} \alias{head.Assay} \alias{tail.Assay} \alias{[[<-,Assay,missing,missing,data.frame-method} \title{Feature-Level Meta Data} \usage{ \method{[[}{Assay}(x, i, ..., drop = FALSE) \S4method{[[}{Assay,ANY,ANY,ANY}(x, i, j, ...) <- value \method{head}{Assay}(x, n = 10L, ...) \method{tail}{Assay}(x, n = 10L, ...) \S4method{[[}{Assay,missing,missing,data.frame}(x, i, j, ...) <- value } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{i}{Name of feature-level meta data to fetch or add} \item{...}{Ignored} \item{drop}{See \code{\link{drop}}} \item{j}{Ignored} \item{value}{Feature-level meta data to add} \item{n}{Number of meta data rows to show} } \value{ \code{[[}: The feature-level meta data for \code{i} \code{[[<-}: \code{x} with \code{value} added as \code{i} in feature-level meta data \code{head}: The first \code{n} rows of feature-level meta data \code{tail}: the last \code{n} rows of feature-level meta data } \description{ Get and set feature-level meta data } \examples{ rna <- pbmc_small[["RNA"]] # Pull the entire feature-level meta data data frame head(rna[[]]) # Pull a specific column of feature-level meta data head(rna[["vst.mean"]]) head(rna[["vst.mean", drop = TRUE]]) # `head` and `tail` can be used to quickly view feature-level meta data head(rna) tail(rna) } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/Centroids-methods.Rd0000644000176200001440000000673315116356172017321 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/centroids.R \name{Centroids-methods} \alias{Centroids-methods} \alias{Cells.Centroids} \alias{GetTissueCoordinates.Centroids} \alias{Radius.Centroids} \alias{RenameCells.Centroids} \alias{Theta.Centroids} \alias{is.finite.Centroids} \alias{is.infinite.Centroids} \alias{length.Centroids} \alias{lengths.Centroids} \alias{subset.Centroids} \alias{[,Centroids,character,ANY,ANY-method} \alias{[,Centroids,numeric,ANY,ANY-method} \alias{show,Centroids-method} \title{\code{Centroids} Methods} \usage{ \method{Cells}{Centroids}(x, ...) \method{GetTissueCoordinates}{Centroids}(object, full = TRUE, ...) \method{Radius}{Centroids}(object, ...) \method{RenameCells}{Centroids}(object, new.names = NULL, ...) \method{Theta}{Centroids}(object) \method{is.finite}{Centroids}(x) \method{is.infinite}{Centroids}(...) \method{length}{Centroids}(x) \method{lengths}{Centroids}(x, use.names = TRUE) \method{subset}{Centroids}(x, cells = NULL, ...) \S4method{[}{Centroids,character,ANY,ANY}(x, i, j, ..., drop = TRUE) \S4method{[}{Centroids,numeric,ANY,ANY}(x, i, j, ..., drop = TRUE) \S4method{show}{Centroids}(object) } \arguments{ \item{x, object}{A \code{\link[SeuratObject:Centroids-class]{Centroids}} object} \item{...}{Arguments passed to other methods} \item{full}{Expand the coordinates to the full polygon} \item{new.names}{vector of new cell names} \item{use.names}{Ignored} \item{i, cells}{A vector of cells to keep; if \code{NULL}, defaults to all cells} \item{j, drop}{Ignored} } \value{ \code{GetTissueCoordinates}: A data frame with three columns: \itemize{ \item \dQuote{\code{x}}: the x-coordinate \item \dQuote{\code{y}}: the y-coordinate \item \dQuote{\code{cell}}: the cell name } If \code{full} is \code{TRUE}, then each coordinate will indicate a vertex for the cell polygon (created based on nsides, radius, and theta); otherwise, each coordinate will indicate a centroid for the cell. \code{Radius} The radius of the centroids \code{RenameCells}: \code{object} with the cells renamed to \code{new.names} \code{Theta}: The offset angle in degrees \code{is.finite}: \code{TRUE} if the centroids are polygonal, \code{FALSE} if circular \code{is.infinite}: The opposite of \code{is.finite} \code{length}: \code{0} if the centroids are circular, otherwise the number of sides of the polygonal centroid \code{lengths}: An \code{\link[base:rle]{rle}} object for the cells \code{subset}, \code{[}: \code{x} subsetted to the cells specified by \code{cells}/\code{i} \code{show}: Invisibly returns \code{NULL} } \description{ Methods for \code{\link[SeuratObject:Centroids-class]{Centroids}} objects } \details{ \code{GetTissueCoordinates}: Get cell spatial coordinates \code{Radius}: Get the centroid radius \code{RenameCells}: Update cell names \code{Theta}: Get the offset angle \code{is.finite}, \code{is.infinite}: Test to see if the centroids are circular or polygonal \code{length}: Get the number of sides for the polygonal centroid \code{lengths}: Generate a run-length encoding of the cells present \code{subset}, \code{[}: Subset a \code{Centroids} object to certain cells \code{show}: Display an object summary to stdout } \seealso{ \code{\link{Centroids-class}} Segmentation layer classes: \code{\link{Centroids-class}}, \code{\link{Molecules-class}}, \code{\link{Molecules-methods}}, \code{\link{Segmentation-class}}, \code{\link{Segmentation-methods}}, \code{\link{Segmentation-validity}} } \concept{segmentation} SeuratObject/man/dot-Subobjects.Rd0000644000176200001440000000165715075522101016604 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.Subobjects} \alias{.Subobjects} \title{Get the Subobject Names} \usage{ .Subobjects(object, exclude = c("misc", "tools"), collapse = TRUE, ...) } \arguments{ \item{object}{An \link[methods:Classes_Details]{S4} object} \item{exclude}{A character vector of slot names to exclude} \item{collapse}{Collapse the list into a vector} \item{...}{Arguments passed to \code{\link{IsNamedList}}} } \value{ If \code{collapse = TRUE}, then a vector with the names of all subobjects; otherwise, a named list where the names are the names of the collections and the values are the names of subobjects within the collection } \description{ Get the Subobject Names } \examples{ .Subobjects(pbmc_small) } \seealso{ \code{\link{.Collections}()}, \code{\link{.FilterObjects}()}, \code{\link{.FindObject}()} } \concept{subobjects} \keyword{internal} \keyword{utils} SeuratObject/man/oldseurat-class.Rd0000644000176200001440000000475215075522101017021 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \docType{class} \name{seurat-class} \alias{seurat-class} \alias{oldseurat} \title{The Seurat Class} \description{ The Seurat object is the center of each single cell analysis. It stores all information associated with the dataset, including data, annotations, analyses, etc. All that is needed to construct a Seurat object is an expression matrix (rows are genes, columns are cells), which should be log-scale } \details{ Each Seurat object has a number of slots which store information. Key slots to access are listed below. } \section{Slots}{ \describe{ \item{\code{raw.data}}{The raw project data} \item{\code{data}}{The normalized expression matrix (log-scale)} \item{\code{scale.data}}{scaled (default is z-scoring each gene) expression matrix; used for dimensional reduction and heatmap visualization} \item{\code{var.genes}}{Vector of genes exhibiting high variance across single cells} \item{\code{is.expr}}{Expression threshold to determine if a gene is expressed (0 by default)} \item{\code{ident}}{THe 'identity class' for each cell} \item{\code{meta.data}}{Contains meta-information about each cell, starting with number of genes detected (nFeature) and the original identity class (orig.ident); more information is added using \code{AddMetaData}} \item{\code{project.name}}{Name of the project (for record keeping)} \item{\code{dr}}{List of stored dimensional reductions; named by technique} \item{\code{assay}}{List of additional assays for multimodal analysis; named by technique} \item{\code{hvg.info}}{The output of the mean/variability analysis for all genes} \item{\code{imputed}}{Matrix of imputed gene scores} \item{\code{cell.names}}{Names of all single cells (column names of the expression matrix)} \item{\code{cluster.tree}}{List where the first element is a phylo object containing the phylogenetic tree relating different identity classes} \item{\code{snn}}{Spare matrix object representation of the SNN graph} \item{\code{calc.params}}{Named list to store all calculation-related parameter choices} \item{\code{kmeans}}{Stores output of gene-based clustering from \code{DoKMeans}} \item{\code{spatial}}{Stores internal data and calculations for spatial mapping of single cells} \item{\code{misc}}{Miscellaneous spot to store any data alongside the object (for example, gene lists)} \item{\code{version}}{Version of package used in object creation} }} \concept{unsorted} \concept{v2} \keyword{internal} SeuratObject/man/Molecules-methods.Rd0000644000176200001440000000343615114353666017317 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/molecules.R \name{Molecules-methods} \alias{Molecules-methods} \alias{Features.Molecules} \alias{GetTissueCoordinates.Molecules} \alias{subset.Molecules} \alias{show,Molecules-method} \title{\code{Molecules} Methods} \usage{ \method{Features}{Molecules}(x, ...) \method{GetTissueCoordinates}{Molecules}(object, features = NULL, ...) \method{subset}{Molecules}(x, features = NULL, ...) \S4method{show}{Molecules}(object) } \arguments{ \item{x, object}{A \code{\link{Molecules}} object} \item{...}{Arguments passed to other methods} \item{features}{A vector of molecule names to keep; if \code{NULL}, defaults to all molecules} } \value{ \code{Features}: A vector of spatially-resolved molecule names; if no molecular information present, returns \code{NULL} \code{GetTissueCoordinates}: A data frame with three columns: \itemize{ \item \dQuote{\code{x}}: the x-coordinate of a molecule \item \dQuote{\code{y}}: the y-coordinate of a molecule \item \dQuote{\code{molecule}}: the molecule name } \code{subset}: \code{x} subsetted to the features specified by \code{features} \code{show}: Invisibly returns \code{NULL} } \description{ Methods for \code{\link{Molecules}} objects } \details{ \code{Features}: Get spatially-resolved molecule names \code{GetTissueCoordinates}: Get spatially-resolved molecule coordinates \code{subset}: Subset a \code{Molecules} object to certain molecules \code{show}: Display an object summary to stdout } \seealso{ \code{\link{Molecules-class}} Segmentation layer classes: \code{\link{Centroids-class}}, \code{\link{Centroids-methods}}, \code{\link{Molecules-class}}, \code{\link{Segmentation-class}}, \code{\link{Segmentation-methods}}, \code{\link{Segmentation-validity}} } \concept{segmentation} SeuratObject/man/NNIndex.Rd0000644000176200001440000000126415075522101015212 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/neighbor.R \name{Index} \alias{Index} \alias{Index<-} \alias{Index.Neighbor} \alias{Index<-.Neighbor} \title{Get Neighbor algorithm index} \usage{ Index(object, ...) Index(object, ...) <- value \method{Index}{Neighbor}(object, ...) \method{Index}{Neighbor}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{The index to store} } \value{ Returns the value in the alg.idx slot of the Neighbor object \code{Idents<-}: A Neighbor object with the index stored } \description{ Get Neighbor algorithm index } \concept{data-access} SeuratObject/man/dot-Contains.Rd0000644000176200001440000000065515075522101016254 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.Contains} \alias{.Contains} \title{Get Parent S4 Classes} \usage{ .Contains(object) } \arguments{ \item{object}{An \link[methods:Classes_Details]{S4} object} } \value{ A vector of class names that \code{object} inherits from } \description{ Get Parent S4 Classes } \examples{ .Contains(pbmc_small) } \concept{utils} \keyword{internal} SeuratObject/man/set-if-null.Rd0000644000176200001440000000141515075522101016044 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{set-if-null} \alias{set-if-null} \alias{\%||\%} \alias{\%iff\%} \title{Set If or If Not \code{NULL}} \usage{ x \%||\% y x \%iff\% y } \arguments{ \item{x}{An object to test} \item{y}{A default value} } \value{ For \code{\%||\%}: \code{y} if \code{x} is \code{NULL}; otherwise \code{x} For \code{\%iff\%}: \code{y} if \code{x} is \strong{not} \code{NULL}; otherwise \code{x} } \description{ Set a default value depending on if an object is \code{NULL} } \examples{ # Set if NULL 1 \%||\% 2 NULL \%||\% 2 # Set if *not* NULL 1 \%iff\% 2 NULL \%iff\% 2 } \seealso{ \code{\link[rlang:op-null-default]{rlang::\%||\%}} } \author{ For \code{\%||\%}: \pkg{rlang} developers } \concept{utils} SeuratObject/man/CreateDimReducObject.Rd0000644000176200001440000000336115116566601017667 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{CreateDimReducObject} \alias{CreateDimReducObject} \alias{SetDimReduction} \title{Create a DimReduc object} \usage{ CreateDimReducObject( embeddings = new(Class = "matrix"), loadings = new(Class = "matrix"), projected = new(Class = "matrix"), assay = NULL, stdev = numeric(), key = NULL, global = FALSE, jackstraw = NULL, misc = list() ) } \arguments{ \item{embeddings}{A matrix with the cell embeddings} \item{loadings}{A matrix with the feature loadings} \item{projected}{A matrix with the projected feature loadings} \item{assay}{Assay used to calculate this dimensional reduction} \item{stdev}{Standard deviation (if applicable) for the dimensional reduction} \item{key}{A character string to facilitate looking up features from a specific DimReduc} \item{global}{Specify this as a global reduction (useful for visualizations)} \item{jackstraw}{Results from the JackStraw function} \item{misc}{list for the user to store any additional information associated with the dimensional reduction} } \value{ A \code{\link{DimReduc}} object } \description{ Create a DimReduc object } \examples{ data <- GetAssayData(pbmc_small[["RNA"]], layer = "scale.data") pcs <- prcomp(x = data) pca.dr <- CreateDimReducObject( embeddings = pcs$rotation, loadings = pcs$x, stdev = pcs$sdev, key = "PC", assay = "RNA" ) } \seealso{ Dimensional reduction object, validity, and interaction methods \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/SeuratObject-options.Rd0000644000176200001440000000374415075522101017777 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/zzz.R \name{SeuratObject-options} \alias{SeuratObject-options} \title{\pkg{Seurat} Options} \description{ Various options used in \pkg{Seurat} } \section{Package Options}{ \subsection{Seurat.coords.short_range}{ Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.coords.short_range}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.coords.short_range")}} } \subsection{Seurat.input.sparse_ratio}{ Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.input.sparse_ratio}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.input.sparse_ratio")}} } \subsection{Seurat.io.rds.strict}{ Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.io.rds.strict}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.io.rds.strict")}} } \subsection{Seurat.object.assay.calcn}{ Run \code{CalcN} when adding assay data to a \code{Seurat} object\cr Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.assay.calcn}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.assay.calcn")}} } \subsection{Seurat.object.assay.version}{ Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.assay.version}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.assay.version")}} } \subsection{Seurat.object.assay.v3.missing_layer}{ Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.assay.v3.missing_layer}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.assay.v3.missing_layer")}} } \subsection{Seurat.object.project}{ Default project for new \code{\link{Seurat}} objects\cr Defaults to \dQuote{\Sexpr[stage=build]{SeuratObject:::Seurat.options$Seurat.object.project}}\cr Currently set to \dQuote{\Sexpr[stage=render]{getOption("Seurat.object.project")}} } } \keyword{internal} SeuratObject/man/LogMap-class.Rd0000644000176200001440000000551715075522101016176 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \docType{class} \name{LogMap} \alias{LogMap} \alias{[[,LogMap,character,missing-method} \alias{[[,LogMap,missing,missing-method} \alias{[[,LogMap,NULL,missing-method} \alias{[[<-,LogMap,character,missing,character-method} \alias{[[<-,LogMap,character,missing,integer-method} \alias{[[<-,LogMap,character,missing,NULL-method} \alias{[[<-,LogMap,character,missing,numeric-method} \alias{LogMap-class} \title{A Logical Map} \usage{ LogMap(y) \S4method{[[}{LogMap,character,missing}(x, i, j, ...) \S4method{[[}{LogMap,missing,missing}(x, i, j, ...) \S4method{[[}{LogMap,NULL,missing}(x, i, j, ...) \S4method{[[}{LogMap,character,missing,character}(x, i, j, ...) <- value \S4method{[[}{LogMap,character,missing,integer}(x, i, j, ...) <- value \S4method{[[}{LogMap,character,missing,NULL}(x, i, j, ...) <- value \S4method{[[}{LogMap,character,missing,numeric}(x, i, j, ...) <- value } \arguments{ \item{y}{A character vector} \item{x}{A \code{LogMap} object} \item{i}{A character vector of length 1, or \code{NULL}} \item{j}{Not used} \item{...}{Ignored} \item{value}{A character or integer vector of values to record in the map for \code{i}, or \code{NULL} to remove the record for \code{i}} } \value{ \code{LogMap}: A new \code{LogMap} object with zero columns and \code{length(x = x)} rows; rownames are set to \code{x} \code{[[}: if \code{i} is a character vector, the rownames that are mapped to \code{i}; otherwise the rownames of \code{x} \code{[[<-}: If \code{value} is \code{NULL}, then \code{x} without the observations for \code{i}; otherwise, \code{x} with a new column for \code{i} recording a \code{TRUE} for all values present in \code{value} } \description{ A simple container for storing mappings of values using logical matrices. Keeps track of which values (rows) are present in which observations (columns). \code{LogMap} objects can be created with \code{LogMap()}; queries can be performed with \code{[[} and observations can be added or removed with \code{[[<-} } \section{Slots}{ \describe{ \item{\code{.Data}}{A logical matrix with at least one row} }} \examples{ # Create a LogMap map <- LogMap(letters[1:10]) map # Get the names of values in the LogMap map[[NULL]] rownames(map) # Add an observation to the LogMap map[['obs']] <- c(1, 3, 7) map[['entry']] <- c(2, 7, 10) map # Get the names of observations in the LogMap colnames(map) # Fetch an observation from the LogMap map[['obs']] # Get the full logical matrix map[[]] # Remove an observation from the LogMap map[['obs']] <- NULL map[['entry']] <- NULL map } \seealso{ Logical map objects, validity, and interaction methods: \code{\link{LogMap-validity}}, \code{\link{as.matrix.LogMap}()}, \code{\link{droplevels.LogMap}()}, \code{\link{intersect.LogMap}()}, \code{\link{labels.LogMap}()} } \concept{logmap} SeuratObject/man/dot-CalcN.Rd0000644000176200001440000000071215075522101015450 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{.CalcN} \alias{.CalcN} \title{Calculate nCount and nFeature} \usage{ .CalcN(object, ...) } \arguments{ \item{object}{An assay-like object} \item{...}{Arguments passed to other methods} } \value{ A named list with ... } \description{ Calculate nCount and nFeature } \examples{ calcn <- .CalcN(pbmc_small[["RNA"]]) head(as.data.frame(calcn)) } \keyword{internal} SeuratObject/man/merge.Assay5.Rd0000644000176200001440000000245015075522101016150 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{merge.Assay5} \alias{merge.Assay5} \title{Merge Assays} \usage{ \method{merge}{Assay5}(x, y, labels = NULL, add.cell.ids = NULL, collapse = FALSE, ...) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{y}{One or more \code{\link{Assay5}} objects} \item{labels}{A character vector equal to the number of objects; defaults to \code{as.character(seq_along(c(x, y)))}} \item{add.cell.ids}{A character vector equal to the number of objects provided to append to all cell names; if \code{TRUE}, uses \code{labels} as \code{add.cell.ids}} \item{collapse}{If \code{TRUE}, merge layers of the same name together; if \code{FALSE}, appends \code{labels} to the layer name} \item{...}{Ignored} } \value{ A new v5 assay with data merged from \code{c(x, y)} } \description{ Merge one or more v5 assays together } \details{ \strong{Note}: collapsing layers is currently not supported } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/Molecules-class.Rd0000644000176200001440000000131315114353666016751 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/molecules.R \docType{class} \name{Molecules-class} \alias{Molecules-class} \title{The Spatial Molecules Class} \description{ The Spatial Molecules Class } \section{Slots}{ \describe{ \item{\code{.Data}}{A list of \code{\link[sp]{SpatialPoints}} objects} \item{\code{key}}{The key for the \code{Molecules}} }} \seealso{ \code{Molecules} methods: \code{\link{Molecules-methods}} Segmentation layer classes: \code{\link{Centroids-class}}, \code{\link{Centroids-methods}}, \code{\link{Molecules-methods}}, \code{\link{Segmentation-class}}, \code{\link{Segmentation-methods}}, \code{\link{Segmentation-validity}} } \concept{segmentation} SeuratObject/man/CreateSegmentation.Rd0000644000176200001440000000200015116320014017450 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/segmentation.R \name{CreateSegmentation} \alias{CreateSegmentation} \alias{CreateSegmentation.data.frame} \alias{CreateSegmentation.Segmentation} \alias{CreateSegmentation.sf} \title{Create a \code{\link[SeuratObject:Segmentation-class]{Segmentation}} Objects} \usage{ CreateSegmentation(coords, compact = FALSE) \method{CreateSegmentation}{data.frame}(coords, compact = FALSE) \method{CreateSegmentation}{Segmentation}(coords, compact = FALSE) \method{CreateSegmentation}{sf}(coords, compact = TRUE) } \arguments{ \item{coords}{The coordinates of cell segmentations} \item{compact}{Logical indicating whether or not the object should only store segmentation data in the \code{sf.data} slot; see \link{Segmentation-class} for details.} } \value{ A \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object } \description{ Create a \code{\link[SeuratObject:Segmentation-class]{Segmentation}} Objects } \concept{spatial} SeuratObject/man/sub-.SeuratCommand.Rd0000644000176200001440000000141415075522101017313 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \name{[.SeuratCommand} \alias{[.SeuratCommand} \title{Command Log Data Access} \usage{ \method{[}{SeuratCommand}(x, i, ...) } \arguments{ \item{x}{A \code{\link{SeuratCommand}} object} \item{i}{The name of a command log slot} \item{...}{Ignored} } \value{ \code{[}: Slot \code{i} from \code{x} } \description{ Access data from a \code{SeuratCommand} object } \examples{ cmd <- pbmc_small[["NormalizeData.RNA"]] cmd["call.string"] } \seealso{ Command log object and interaction methods \code{\link{$.SeuratCommand}()}, \code{\link{.DollarNames.SeuratCommand}()}, \code{\link{LogSeuratCommand}()}, \code{\link{SeuratCommand-class}}, \code{\link{as.list.SeuratCommand}()} } \concept{command} SeuratObject/man/SpatialImage-methods.Rd0000644000176200001440000001504315075522101017710 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/spatial.R \name{SpatialImage-methods} \alias{SpatialImage-methods} \alias{Cells.SpatialImage} \alias{DefaultAssay.SpatialImage} \alias{DefaultAssay<-.SpatialImage} \alias{GetImage.SpatialImage} \alias{GetTissueCoordinates.SpatialImage} \alias{IsGlobal.SpatialImage} \alias{Key.SpatialImage} \alias{Key<-.SpatialImage} \alias{Radius.SpatialImage} \alias{RenameCells.SpatialImage} \alias{[.SpatialImage} \alias{dim.SpatialImage} \alias{subset.SpatialImage} \alias{show,SpatialImage-method} \title{\code{SpatialImage} methods} \usage{ \method{Cells}{SpatialImage}(x, ...) \method{DefaultAssay}{SpatialImage}(object, ...) \method{DefaultAssay}{SpatialImage}(object, ...) <- value \method{GetImage}{SpatialImage}(object, mode = c("grob", "raster", "plotly", "raw"), ...) \method{GetTissueCoordinates}{SpatialImage}(object, ...) \method{IsGlobal}{SpatialImage}(object, ...) \method{Key}{SpatialImage}(object, ...) \method{Key}{SpatialImage}(object, ...) <- value \method{Radius}{SpatialImage}(object, ...) \method{RenameCells}{SpatialImage}(object, new.names = NULL, ...) \method{[}{SpatialImage}(x, i, ...) \method{dim}{SpatialImage}(x) \method{subset}{SpatialImage}(x, cells, ...) \S4method{show}{SpatialImage}(object) } \arguments{ \item{x, object}{A \code{SpatialImage}-derived object} \item{...}{Arguments passed to other methods} \item{value}{Depends on the method: \describe{ \item{\code{DefaultAssay<-}}{Assay that the image should be associated with} \item{\code{Key<-}}{New key for the image} }} \item{mode}{How to return the image; should accept one of \dQuote{grob}, \dQuote{raster}, \dQuote{plotly}, or \dQuote{raw}} \item{new.names}{vector of new cell names} \item{i, cells}{A vector of cells to keep} } \value{ \strong{[Override]} \code{Cells}: should return cell names \code{DefaultAssay}: The associated assay of a \code{SpatialImage}-derived object \code{DefaultAssay<-}: \code{object} with the associated assay updated \strong{[Override]} \code{GetImage}: The image data from a \code{SpatialImage}-derived object \strong{[Override]} \code{GetTissueCoordinates}: ... \code{IsGlobal}: returns \code{TRUE} as images are, by default, global \code{Key}: The key for a \code{SpatialImage}-derived object \code{Key<-}: \code{object} with the key set to \code{value} \code{Radius}: The spot radius size; by default, returns \code{NULL} \strong{[Override]} \code{RenameCells}: \code{object} with the new cell names \code{[}, \code{subset}: \code{x}/\code{object} for only the cells requested \strong{[Override]} \code{dim}: The dimensions of the image data in (Y, X) format \code{show}: Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Methods defined on the \code{\link{SpatialImage}} class. Some of these methods must be overridden in order to ensure proper functionality of the derived classes (see \strong{Required methods} below). Other methods are designed to work across all \code{SpatialImage}-derived subclasses, and should only be overridden if necessary } \section{Functions}{ \itemize{ \item \code{Cells(SpatialImage)}: Get the cell names from an image (\strong{[Override]}) \item \code{DefaultAssay(SpatialImage)}: Get the associated assay of a \code{SpatialImage}-derived object \item \code{DefaultAssay(SpatialImage) <- value}: Set the associated assay of a \code{SpatialImage}-derived object \item \code{GetImage(SpatialImage)}: Get the image data from a \code{SpatialImage}-derived object \item \code{GetTissueCoordinates(SpatialImage)}: Get tissue coordinates for a \code{SpatialImage}-derived object (\strong{[Override]}) \item \code{IsGlobal(SpatialImage)}: Globality test for \code{SpatialImage}-derived object \item \code{Key(SpatialImage)}: Get the key for a \code{SpatialImage}-derived object \item \code{Key(SpatialImage) <- value}: Set the key for a \code{SpatialImage}-derived object \item \code{Radius(SpatialImage)}: Get the spot radius size \item \code{RenameCells(SpatialImage)}: Rename cells in a \code{SpatialImage}-derived object (\strong{[Override]}) \item \code{[}: Subset a \code{SpatialImage}-derived object \item \code{dim(SpatialImage)}: Get the plotting dimensions of an image (\strong{[Override]}) \item \code{subset(SpatialImage)}: Subset a \code{SpatialImage}-derived object (\strong{[Override]}) \item \code{show(SpatialImage)}: Overview of a \code{SpatialImage}-derived object }} \section{Provided methods}{ These methods are defined on the \code{SpatialImage} object and should not be overridden without careful thought \itemize{ \item \code{\link{DefaultAssay}} and \code{\link{DefaultAssay<-}} \item \code{\link{Key}} and \code{\link{Key<-}} \item \code{\link{GetImage}}; this method \emph{can} be overridden to provide image data, normally returns empty image data. If overridden, should default to returning a \code{\link[grid]{grob}} object \item \code{\link{IsGlobal}} \item \code{\link{Radius}}; this method \emph{can} be overridden to provide a spot radius for image objects \item \code{\link[base:Extract]{[}}; this method \emph{can} be overridden to change default subset behavior, normally returns \code{subset(x = x, cells = i)}. If overridden, should only accept \code{i} } } \section{Required methods}{ All subclasses of the \code{SpatialImage} class must define the following methods; simply relying on the \code{SpatialImage} method will result in errors. For required parameters and their values, see the \code{Usage} and \code{Arguments} sections \describe{ \item{\code{\link{Cells}}}{ Return the cell/spot barcodes associated with each position } \item{\code{\link{dim}}}{ Return the dimensions of the image for plotting in \code{(Y, X)} format } \item{\code{\link{GetTissueCoordinates}}}{ Return tissue coordinates; by default, must return a two-column \code{data.frame} with x-coordinates in the first column and y-coordinates in the second } \item{\code{\link{Radius}}}{ Return the spot radius; returns \code{NULL} by default for use with non-spot image technologies } \item{\code{\link{RenameCells}}}{ Rename the cell/spot barcodes for this image } \item{\code{\link{subset}}}{ Subset the image data by cells/spots } } These methods are used throughout Seurat, so defining them and setting the proper defaults will allow subclasses of \code{SpatialImage} to work seamlessly } \seealso{ \code{\link{DefaultAssay}} \code{\link{GetImage}} \code{\link{GetTissueCoordinates}} \code{\link{IsGlobal}} \code{\link{Key}} \code{\link{RenameCells}} } \concept{spatialimage} SeuratObject/man/FOV-methods.Rd0000644000176200001440000001235115116356172016012 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fov.R \name{FOV-methods} \alias{FOV-methods} \alias{Cells.FOV} \alias{Features.FOV} \alias{FetchData.FOV} \alias{Keys.FOV} \alias{RenameCells.FOV} \alias{$.FOV} \alias{[.FOV} \alias{[[.FOV} \alias{length.FOV} \alias{names.FOV} \alias{subset.FOV} \alias{[[<-,FOV,character,missing,Centroids-method} \alias{[[<-,FOV,character,missing,Molecules-method} \alias{[[<-,FOV,character,missing,NULL-method} \alias{[[<-,FOV,character,missing,Segmentation-method} \alias{show,FOV-method} \title{\code{FOV} Methods} \usage{ \method{Cells}{FOV}(x, boundary = NULL, ...) \method{Features}{FOV}(x, set = NULL, ...) \method{FetchData}{FOV}(object, vars, cells = NULL, simplify = TRUE, ...) \method{Keys}{FOV}(object, ...) \method{RenameCells}{FOV}(object, new.names = NULL, ...) \method{$}{FOV}(x, i, ...) \method{[}{FOV}(x, i, j, ...) \method{[[}{FOV}(x, i, ...) \method{length}{FOV}(x) \method{names}{FOV}(x) \method{subset}{FOV}(x, cells = NULL, features = NULL, ...) \S4method{[[}{FOV,character,missing,Centroids}(x, i, j, ...) <- value \S4method{[[}{FOV,character,missing,Molecules}(x, i, j, ...) <- value \S4method{[[}{FOV,character,missing,NULL}(x, i, j, ...) <- value \S4method{[[}{FOV,character,missing,Segmentation}(x, i, j, ...) <- value \S4method{show}{FOV}(object) } \arguments{ \item{x, object}{A \code{\link{FOV}} object} \item{boundary, set}{Name of segmentation boundary or molecule set to extract cell or feature names for; pass \code{NA} to return all cells or feature names} \item{...}{Arguments passed to other methods} \item{vars}{A vector of variables to fetch; can be the name of a segmentation boundary, to get tissue coordinates, or molecule names, to get molecule coordinates} \item{simplify}{If only returning either boundary or molecule coordinates, return a single data frame instead of a list} \item{new.names}{vector of new cell names} \item{i, cells}{For \code{[[} and \code{[[<-}, the name of a segmentation or \dQuote{molecules}; for \code{FetchData}, \code{subset}. and \code{[}, a vector of cells to keep} \item{j, features}{For \code{subset} and \code{[}, a vector of features to keep; for \code{[[<-}, not used} \item{value}{For \code{[[<-}, a replacement \code{\link[SeuratObject:Molecules-class]{Molecules}}, \code{\link[SeuratObject:Centroids-class]{Centroids}}, or \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object; otherwise \code{NULL} to remove the boundary stored at \code{i}} } \value{ \code{Cells}: A vector of cell names \code{Features}: A vector of spatially-resolved molecule names; if no molecular information present, returns \code{NULL} \code{FetchData}: If both molecule and boundary coordinates are requested, then a two-length list: \itemize{ \item \dQuote{\code{molecules}}: A data frame with the molecule coordinates requested. If molecules requested are keyed, the keys are preserved in the data frame \item \dQuote{\code{coordinates}}: A data frame with coordinates from the segmentation boundaries requested } If \code{simplify} is \code{TRUE} and only one data frame is generated, then only the data frame is returned. Otherwise, a one-length list is returned with the single data frame generated \code{Keys}: A named vector of molecule set keys; names are the names of the molecule sets and values are the keys for the respective molecule set \code{RenameCells}: \code{object} with the cells renamed to \code{new.names} \code{$}, \code{[[}: The segmentation boundary or spatially-resolved molecule information stored at \code{i} \code{length}: The number of segmentation layers (\code{\link[SeuratObject:Segmentation-class]{Segmentation}} or \code{\link[SeuratObject:Centroids-class]{Centroids}} objects) \code{names}: A vector of segmentation boundary and molecule set names \code{subset}: \code{x} with just the cells and features specified \code{[[<-}: Varies depending on the class of \code{value}: \itemize{ \item If \code{value} is \code{NULL}, returns \code{x} with the boundary \code{i} removed; also allows removing \code{molecules}; does not allow removing the default segmentation \item If \code{value} is a \code{Molecules}, returns \code{x} with \code{value} stored in \code{molecules}; requires that \code{i} is \dQuote{molecules} \item Otherwise, stores \code{value} as a segmentation boundary named \code{i} } \code{show}: Invisibly returns \code{NULL} } \description{ Methods for \code{\link{FOV}} objects } \details{ The following methods are defined for interacting with a \code{FOV} object: \code{Cells}: Get cell names \code{Features}: Get spatially-resolved molecule names \code{FetchData}: Fetch boundary and/or molecule coordinates from a \code{FOV} object \code{Keys}: Get the keys of molecule sets contained within a \code{FOV} object \code{RenameCells}: Update cell names \code{$}, \code{[[}: Extract a segmentation boundary \code{length}: Get the number of segmentation layers in a \code{FOV} object \code{names}: Get the names of segmentation layers and molecule sets \code{subset}, \code{[}: Subset a \code{FOV} object \code{[[<-}: Add or remove segmentation layers and molecule information to/from a \code{FOV} object \code{show}: Display an object summary to stdout } \seealso{ \code{\link{FOV-class}} } \concept{fov} SeuratObject/man/Images.Rd0000644000176200001440000000106015075522101015106 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{Images} \alias{Images} \title{Pull spatial image names} \usage{ Images(object, assay = NULL) } \arguments{ \item{object}{A \code{Seurat} object} \item{assay}{Name of assay to limit search to} } \value{ A list of image names } \description{ List the names of \code{SpatialImage} objects present in a \code{Seurat} object. If \code{assay} is provided, limits search to images associated with that assay } \examples{ \dontrun{ Images(object) } } \concept{data-access} SeuratObject/man/as.Graph.Rd0000644000176200001440000000225415075522101015352 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/graph.R \name{as.Graph} \alias{as.Graph} \alias{as.Graph.Matrix} \alias{as.Graph.matrix} \alias{as.Graph.Neighbor} \title{Coerce to a \code{Graph} Object} \usage{ as.Graph(x, ...) \method{as.Graph}{Matrix}(x, ...) \method{as.Graph}{matrix}(x, ...) \method{as.Graph}{Neighbor}(x, weighted = TRUE, ...) } \arguments{ \item{x}{The matrix to convert} \item{...}{Ignored} \item{weighted}{If TRUE, fill entries in Graph matrix with value from the nn.dist slot of the Neighbor object} } \value{ A \code{\link{Graph}} object } \description{ Convert a \code{\link[base]{matrix}} (or \code{\link[Matrix]{Matrix}}) to a \code{\link{Graph}} object } \examples{ # converting sparse matrix mat <- Matrix::rsparsematrix(nrow = 10, ncol = 10, density = 0.1) rownames(x = mat) <- paste0("feature_", 1:10) colnames(x = mat) <- paste0("cell_", 1:10) g <- as.Graph(x = mat) # converting dense matrix mat <- matrix(data = 1:16, nrow = 4) rownames(x = mat) <- paste0("feature_", 1:4) colnames(x = mat) <- paste0("cell_", 1:4) g <- as.Graph(x = mat) } \seealso{ Other graph: \code{\link{Graph-class}} } \concept{graph} SeuratObject/man/CreateFOV.Rd0000644000176200001440000000377515114353666015512 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/fov.R \name{CreateFOV} \alias{CreateFOV} \alias{CreateFOV.Centroids} \alias{CreateFOV.data.frame} \alias{CreateFOV.list} \alias{CreateFOV.Segmentation} \title{Create Spatial Coordinates} \usage{ CreateFOV(coords, ...) \method{CreateFOV}{Centroids}( coords, molecules = NULL, assay = "Spatial", key = NULL, misc = NULL, name = NULL, ... ) \method{CreateFOV}{data.frame}( coords, type = c("segmentation", "centroids"), nsides = Inf, radius = NULL, theta = 0L, molecules = NULL, assay = "Spatial", key = NULL, misc = NULL, name = NULL, ... ) \method{CreateFOV}{list}( coords, molecules = NULL, assay = "Spatial", key = NULL, misc = NULL, ... ) \method{CreateFOV}{Segmentation}( coords, molecules = NULL, assay = "Spatial", key = NULL, misc = NULL, name = NULL, ... ) } \arguments{ \item{coords}{Spatial coordinates} \item{...}{Arguments passed to other methods} \item{molecules}{A \code{\link[base]{data.frame}} with spatially-resolved molecule information or a \code{\link[SeuratObject:Molecules-class]{Molecules}} object} \item{assay}{Name of associated assay} \item{key}{Key for these spatial coordinates} \item{misc}{A list of miscellaneous information to store with the object} \item{name}{When \code{coords} is a \code{\link[base]{data.frame}}, \code{\link[SeuratObject:Centroids-class]{Centroids}}, or \code{\link[SeuratObject:Segmentation-class]{Segmentation}}, name to store coordinates as} \item{type}{When providing a \code{\link[base]{data.frame}}, specify if the coordinates represent a cell segmentation or voxel centroids} \item{nsides}{The number of sides to represent cells/spots; pass \code{\link[base]{Inf}} to plot as circles} \item{radius}{Radius of shapes when plotting} \item{theta}{Angle to adjust shapes when plotting} } \value{ A \code{\link{FOV}} object } \description{ Create Spatial Coordinates } \seealso{ \code{\link{FOV-class}} } \concept{spatial} SeuratObject/man/LogSeuratCommand.Rd0000644000176200001440000000155115075522101017112 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \name{LogSeuratCommand} \alias{LogSeuratCommand} \title{Log a command} \usage{ LogSeuratCommand(object, return.command = FALSE) } \arguments{ \item{object}{Name of Seurat object} \item{return.command}{Return a \code{\link{SeuratCommand}} object instead} } \value{ If \code{return.command}, returns a \code{\link{SeuratCommand}} object; otherwise, returns the Seurat object with command stored } \description{ Logs command run, storing the name, timestamp, and argument list. Stores in the Seurat object } \seealso{ \code{\link{Command}} Command log object and interaction methods \code{\link{$.SeuratCommand}()}, \code{\link{.DollarNames.SeuratCommand}()}, \code{\link{SeuratCommand-class}}, \code{\link{[.SeuratCommand}()}, \code{\link{as.list.SeuratCommand}()} } \concept{command} SeuratObject/man/DefaultFOV.Rd0000644000176200001440000000170315075522101015644 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{DefaultFOV} \alias{DefaultFOV} \alias{DefaultFOV<-} \alias{DefaultFOV.Seurat} \alias{DefaultFOV<-.Seurat} \title{Get and Set the Default FOV} \usage{ DefaultFOV(object, ...) DefaultFOV(object, ...) <- value \method{DefaultFOV}{Seurat}(object, assay = NULL, ...) \method{DefaultFOV}{Seurat}(object, assay = NA, ...) <- value } \arguments{ \item{object}{A \code{\link{Seurat}} Object} \item{...}{Arguments passed to other methods} \item{value}{The name of the \code{\link{FOV}} to set as the default} \item{assay}{Name of assay to get or set default \code{\link{FOV}} for; pass \code{NA} to get or set the global default \code{\link{FOV}}} } \value{ \code{DefaultFOV}: The name of the default \code{\link{FOV}} \code{DefaultFOV<-}: \code{object} with the default FOV set to \code{value} } \description{ Get and Set the Default FOV } \concept{spatial} SeuratObject/man/ObjectAccess.Rd0000644000176200001440000000165215075522101016240 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{Assays} \alias{Assays} \alias{Graphs} \alias{Neighbors} \alias{Reductions} \alias{Assays.Seurat} \title{Query Specific Object Types} \usage{ Assays(object, ...) Graphs(object, slot = NULL) Neighbors(object, slot = NULL) Reductions(object, slot = NULL) \method{Assays}{Seurat}(object, slot = deprecated(), ...) } \arguments{ \item{object}{A \code{\link{Seurat}} object} \item{...}{Ignored} \item{slot}{Name of component object to return} } \value{ If \code{slot} is \code{NULL}, the names of all component objects in this \code{Seurat} object. Otherwise, the specific object specified } \description{ List the names of \code{\link{Assay}}, \code{\link{DimReduc}}, \code{\link{Graph}}, \code{\link{Neighbor}} objects } \examples{ Assays(pbmc_small) Graphs(pbmc_small) Reductions(object = pbmc_small) } \concept{data-access} SeuratObject/man/JackStrawData-methods.Rd0000644000176200001440000000270515075522101020034 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/jackstraw.R \name{JackStrawData-methods} \alias{JackStrawData-methods} \alias{.DollarNames.JackStrawData} \alias{$.JackStrawData} \alias{as.logical.JackStrawData} \alias{show,JackStrawData-method} \title{\code{JackStrawData} Methods} \usage{ \method{.DollarNames}{JackStrawData}(x, pattern = "") \method{$}{JackStrawData}(x, i, ...) \method{as.logical}{JackStrawData}(x, ...) \S4method{show}{JackStrawData}(object) } \arguments{ \item{x, object}{A \code{\link{JackStrawData}} object} \item{pattern}{ A regular expression. Only matching names are returned. } \item{i}{A \code{JackStrawData} slot name} \item{...}{Ignored} } \value{ \code{$}: Slot \code{i} from \code{x} \code{as.logical}: \code{TRUE} if empirical p-values have been calculated otherwise \code{FALSE} \code{show}: Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Methods for \code{\link{JackStrawData}} objects for generics defined in other packages } \section{Functions}{ \itemize{ \item \code{.DollarNames(JackStrawData)}: Autocompletion for \code{$} access on a \code{JackStrawData} object \item \code{$}: Access data from a \code{JackStrawData} object \item \code{as.logical(JackStrawData)}: Have empirical p-values for a \code{JackStrawData} object been calculated \item \code{show(JackStrawData)}: Overview of a \code{JackStrawData} object }} \concept{jackstraw} SeuratObject/man/Misc.Rd0000644000176200001440000000244215075522101014601 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/assay5.R, % R/dimreduc.R, R/seurat.R \name{Misc} \alias{Misc} \alias{Misc<-} \alias{Misc.Assay} \alias{Misc<-.Assay} \alias{Misc.Assay5} \alias{Misc<-.Assay5} \alias{Misc.DimReduc} \alias{Misc<-.DimReduc} \alias{Misc.Seurat} \alias{Misc<-.Seurat} \title{Get and set miscellaneous data} \usage{ Misc(object, ...) Misc(object, ...) <- value \method{Misc}{Assay}(object, slot = NULL, ...) \method{Misc}{Assay}(object, slot, ...) <- value \method{Misc}{Assay5}(object, slot = NULL, ...) \method{Misc}{Assay5}(object, slot, ...) <- value \method{Misc}{DimReduc}(object, slot = NULL, ...) \method{Misc}{DimReduc}(object, slot, ...) <- value \method{Misc}{Seurat}(object, slot = NULL, ...) \method{Misc}{Seurat}(object, slot, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Data to add} \item{slot}{Name of specific bit of meta data to pull} } \value{ Miscellaneous data An object with miscellaneous data added } \description{ Get and set miscellaneous data } \examples{ # Get the misc info Misc(object = pbmc_small, slot = "example") # Add misc info Misc(object = pbmc_small, slot = "example") <- "testing_misc" } \concept{data-access} SeuratObject/man/GetImage.Rd0000644000176200001440000000241015075522101015363 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{GetImage} \alias{GetImage} \alias{GetImage.Seurat} \title{Get image data} \usage{ GetImage(object, mode = c("grob", "raster", "plotly", "raw"), ...) \method{GetImage}{Seurat}( object, mode = c("grob", "raster", "plotly", "raw"), image = NULL, ... ) } \arguments{ \item{object}{An object} \item{mode}{How to return the image; should accept one of \dQuote{grob}, \dQuote{raster}, \dQuote{plotly}, or \dQuote{raw}} \item{...}{Arguments passed to other methods} \item{image}{Name of \code{SpatialImage} object to pull image data for; if \code{NULL}, will attempt to select an image automatically} } \value{ Image data, varying depending on the value of \code{mode}: \describe{ \item{\dQuote{grob}}{ An object representing image data inheriting from \code{grob} objects (eg. \code{rastergrob}) } \item{\dQuote{raster}}{An object of class \code{raster}} \item{\dQuote{plotly}}{ A list with image data suitable for Plotly rendering, see \code{\link[plotly:layout]{plotly::layout}} for more details } \item{\dQuote{raw}}{The raw image data as stored in the object} } } \description{ Get image data } \seealso{ \code{\link[plotly]{layout}} } \concept{data-access} SeuratObject/man/dim.Seurat.Rd0000644000176200001440000000156215075522101015723 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{dim.Seurat} \alias{dim.Seurat} \title{Feature and Cell Numbers} \usage{ \method{dim}{Seurat}(x) } \arguments{ \item{x}{A \code{\link{Seurat}} object} } \value{ A two-length numeric vector with the total number of features and cells in \code{x} } \description{ Feature and Cell Numbers } \examples{ # Get the number of features in an object nrow(pbmc_small) # Get the number of cells in an object ncol(pbmc_small) } \seealso{ Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/sub-sub-LogMap-internal-method.Rd0000644000176200001440000000124015075522101021526 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{[[,LogMap,integer,missing-method} \alias{[[,LogMap,integer,missing-method} \alias{[[,LogMap,numeric,missing-method} \title{\code{\link{LogMap}} Interaction Methods} \usage{ \S4method{[[}{LogMap,integer,missing}(x, i, j, ...) \S4method{[[}{LogMap,numeric,missing}(x, i, j, ...) } \arguments{ \item{x}{A \code{LogMap} object} \item{i}{An integer or numeric vector of length 1} \item{j}{Not used} \item{...}{Ignored} } \value{ The rownames that are mapped to \code{i} } \description{ Additional methods for using \code{[[} with \code{\link{LogMap}} objects } \keyword{internal} SeuratObject/man/DefaultAssay.Rd0000644000176200001440000000350215075522101016271 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/graph.R, R/assay.R, R/assay5.R, % R/command.R, R/dimreduc.R, R/seurat.R \name{DefaultAssay} \alias{DefaultAssay} \alias{DefaultAssay<-} \alias{DefaultAssay.Graph} \alias{DefaultAssay<-.Graph} \alias{DefaultAssay.Assay} \alias{DefaultAssay<-.Assay} \alias{DefaultAssay.Assay5} \alias{DefaultAssay<-.Assay5} \alias{DefaultAssay.SeuratCommand} \alias{DefaultAssay.DimReduc} \alias{DefaultAssay<-.DimReduc} \alias{DefaultAssay.Seurat} \alias{DefaultAssay<-.Seurat} \title{Default Assay} \usage{ DefaultAssay(object, ...) DefaultAssay(object, ...) <- value \method{DefaultAssay}{Graph}(object, ...) \method{DefaultAssay}{Graph}(object, ...) <- value \method{DefaultAssay}{Assay}(object, ...) \method{DefaultAssay}{Assay}(object, ...) <- value \method{DefaultAssay}{Assay5}(object, ...) \method{DefaultAssay}{Assay5}(object, ...) <- value \method{DefaultAssay}{SeuratCommand}(object, ...) \method{DefaultAssay}{DimReduc}(object, ...) \method{DefaultAssay}{DimReduc}(object, ...) <- value \method{DefaultAssay}{Seurat}(object, ...) \method{DefaultAssay}{Seurat}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Name of assay to set as default} } \value{ \code{DefaultAssay}: The name of the default assay \code{DefaultAssay<-}: An object with the default assay updated } \description{ Get and set the default assay } \examples{ # Get current default assay DefaultAssay(object = pbmc_small) # Create dummy new assay to demo switching default assays new.assay <- pbmc_small[["RNA"]] Key(object = new.assay) <- "RNA2_" pbmc_small[["RNA2"]] <- new.assay # switch default assay to RNA2 DefaultAssay(object = pbmc_small) <- "RNA2" DefaultAssay(object = pbmc_small) } \concept{data-access} SeuratObject/man/sub-sub-.Seurat.Rd0000644000176200001440000000465415075522101016614 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{[[.Seurat} \alias{[[.Seurat} \alias{head.Seurat} \alias{tail.Seurat} \title{Subobjects and Cell-Level Meta Data} \usage{ \method{[[}{Seurat}(x, i = missing_arg(), ..., drop = FALSE, na.rm = FALSE) \method{head}{Seurat}(x, n = 10L, ...) \method{tail}{Seurat}(x, n = 10L, ...) } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{i}{Name of cell-level meta data} \item{...}{Ignored} \item{drop}{See \code{\link[base]{drop}}} \item{na.rm}{Remove cells where meta data is all \code{NA}} \item{n}{Number of meta data rows to show} } \value{ Varies based on the value of \code{i}: \itemize{ \item If \code{i} is missing, a data frame with cell-level meta data \item If \code{i} is a vector with cell-level meta data names, a data frame (or vector of \code{drop = TRUE}) with cell-level meta data requested \item If \code{i} is a one-length character with the \link[=names.Seurat]{name of a subobject}, the subobject specified by \code{i} } \code{head}: The first \code{n} rows of cell-level metadata \code{tail}: The last \code{n} rows of cell-level metadata } \description{ The \code{[[} operator pulls either subobjects (eg. \link[=Assay]{v3} or \link[=Assay5]{v5} assays, \link[=DimReduc]{dimensional reduction} information, or \link[=Graph]{nearest-neighbor graphs}) or cell-level meta data from a \code{\link{Seurat}} object } \examples{ # Get the cell-level metadata data frame head(pbmc_small[[]]) # Pull specific metadata information head(pbmc_small[[c("letter.idents", "groups")]]) head(pbmc_small[["groups", drop = TRUE]]) # Get a sub-object (eg. an `Assay` or `DimReduc`) pbmc_small[["RNA"]] pbmc_small[["pca"]] # Get the first 10 rows of cell-level metadata head(pbmc_small) # Get the last 10 rows of cell-level metadata tail(pbmc_small) } \seealso{ See \link[=$.Seurat]{here} for adding meta data with \code{[[<-}, \link[=[[<-,Seurat]{here} for adding subobjects with \code{[[<-}, and \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta data with \code{[[<-} Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/Neighbor-methods.Rd0000644000176200001440000000142015075522101017077 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/neighbor.R \name{Neighbor-methods} \alias{Neighbor-methods} \alias{dim.Neighbor} \alias{show,Neighbor-method} \title{\code{Neighbor} Methods} \usage{ \method{dim}{Neighbor}(x) \S4method{show}{Neighbor}(object) } \arguments{ \item{x, object}{A \code{\link{Neighbor}} object} } \value{ \code{dim} Dimensions of the indices matrix \code{show}: Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Methods for \code{\link{Neighbor}} objects for generics defined in other packages } \section{Functions}{ \itemize{ \item \code{dim(Neighbor)}: Dimensions of the neighbor indices \item \code{show(Neighbor)}: Overview of a \code{Neighbor} object }} \concept{neighbor} SeuratObject/man/as.Neighbor.Rd0000644000176200001440000000101315075522101016036 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/neighbor.R \name{as.Neighbor} \alias{as.Neighbor} \alias{as.Neighbor.Graph} \title{Coerce to a \code{Neighbor} Object} \usage{ as.Neighbor(x, ...) \method{as.Neighbor}{Graph}(x, ...) } \arguments{ \item{x}{An object to convert to \code{\link{Neighbor}}} \item{...}{Arguments passed to other methods} } \value{ A \code{\link{Neighbor}} object } \description{ Convert objects to \code{\link{Neighbor}} objects } \concept{neighbor} SeuratObject/man/dot-SparseSlots.Rd0000644000176200001440000000143015075522101016750 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sparse.R \name{.SparseSlots} \alias{.SparseSlots} \alias{.SparseSlots.CsparseMatrix} \alias{.SparseSlots.RsparseMatrix} \alias{.SparseSlots.spam} \title{Identify Sparse Slots} \usage{ .SparseSlots(x, type = c("pointers", "indices", "entries")) \method{.SparseSlots}{CsparseMatrix}(x, type = c("pointers", "entries", "indices")) \method{.SparseSlots}{RsparseMatrix}(x, type = c("pointers", "indices", "entries")) \method{.SparseSlots}{spam}(x, type = c("pointers", "indices", "entries")) } \arguments{ \item{x}{A sparse matrix} \item{type}{...} } \value{ ... } \description{ Identify Sparse Slots } \seealso{ \code{\link{IsSparse}()}, \code{\link{RegisterSparseMatrix}()} } \concept{sparse} \keyword{internal} SeuratObject/man/VariableFeatures-StdAssay.Rd0000644000176200001440000000522015114353666020674 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{VariableFeatures-StdAssay} \alias{VariableFeatures-StdAssay} \alias{HVFInfo.StdAssay} \alias{VariableFeatures.StdAssay} \alias{VariableFeatures<-.StdAssay} \alias{VariableFeatures<-.Assay5} \alias{SpatiallyVariableFeatures.StdAssay} \title{Highly Variable Features} \usage{ \method{HVFInfo}{StdAssay}(object, method = NULL, status = FALSE, layer = NA, strip = TRUE, ...) \method{VariableFeatures}{StdAssay}( object, method = NULL, layer = NA, simplify = TRUE, nfeatures = NULL, selection.method = deprecated(), ... ) \method{VariableFeatures}{StdAssay}(object, method = "custom", layer = NULL, ...) <- value \method{VariableFeatures}{Assay5}(object, method = "custom", layer = NULL, ...) <- value \method{SpatiallyVariableFeatures}{StdAssay}( object, method = "moransi", decreasing = TRUE, selection.method = deprecated(), ... ) } \arguments{ \item{object}{An object} \item{method}{Which method to pull. For \code{HVFInfo} and \code{VariableFeatures}, choose one from one of the following: \itemize{ \item \dQuote{vst} \item \dQuote{sctransform} or \dQuote{sct} \item \dQuote{mean.var.plot}, \dQuote{dispersion}, \dQuote{mvp}, or \dQuote{disp} } For \code{SVFInfo} and \code{SpatiallyVariableFeatures}, choose from: \itemize{ \item \dQuote{markvariogram} \item \dQuote{moransi} }} \item{status}{Add variable status to the resulting data frame} \item{layer}{Layer to pull variable features for} \item{strip}{Remove method/layer identifiers from highly variable data frame} \item{...}{Arguments passed to other methods} \item{simplify}{When pulling for multiple layers, combine into a single vector and select a common set of variable features for all layers} \item{nfeatures}{Maximum number of features to select when simplifying} \item{selection.method}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")}} \item{value}{A character vector of variable features} \item{decreasing}{Return features in decreasing order (most spatially variable first).} } \value{ \code{HVFInfo}: A data frame with feature means, dispersion, and scaled dispersion \code{VariableFeatures}: a vector of the variable features \code{SVFInfo}: a data frame with the spatially variable features \code{SpatiallyVariableFeatures}: a character vector of the spatially variable features } \description{ Get and set variable feature information for an \code{\link{Assay}} object. \code{HVFInfo} and \code{VariableFeatures} utilize generally variable features, while \code{SVFInfo} and \code{SpatiallyVariableFeatures} are restricted to spatially variable features } \keyword{internal} SeuratObject/man/sub-.Assay5.Rd0000644000176200001440000000207515075522101015722 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{[.Assay5} \alias{[.Assay5} \alias{[<-,Assay5,character,ANY,ANY-method} \title{Layer Data} \usage{ \method{[}{Assay5}(x, i = missing_arg(), j = missing_arg(), ...) \S4method{[}{Assay5,character,ANY,ANY}(x, i, j, ...) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{i}{Name of layer data to get or set} \item{j}{Ignored} \item{...}{Arguments passed to \code{\link{LayerData}}} \item{value}{A matrix-like object to add as a new layer} } \value{ \code{[}: The layer data for layer \code{i} \code{[<-}: \code{x} with layer data \code{value} saved as \code{i} } \description{ Get and set layer data } \seealso{ \code{\link{LayerData}} v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/CreateSeuratObject.Rd0000644000176200001440000000604415075522101017426 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{CreateSeuratObject} \alias{CreateSeuratObject} \alias{CreateSeuratObject.default} \alias{CreateSeuratObject.Assay} \alias{CreateSeuratObject.Assay5} \title{Create a \code{Seurat} object} \usage{ CreateSeuratObject( counts, assay = "RNA", names.field = 1, names.delim = "_", meta.data = NULL, project = "CreateSeuratObject", ... ) \method{CreateSeuratObject}{default}( counts, assay = "RNA", names.field = 1L, names.delim = "_", meta.data = NULL, project = "SeuratProject", min.cells = 0, min.features = 0, ... ) \method{CreateSeuratObject}{Assay}( counts, assay = "RNA", names.field = 1L, names.delim = "_", meta.data = NULL, project = "SeuratProject", ... ) \method{CreateSeuratObject}{Assay5}( counts, assay = "RNA", names.field = 1L, names.delim = "_", meta.data = NULL, project = "SeuratProject", ... ) } \arguments{ \item{counts}{Either a \code{\link[base]{matrix}}-like object with unnormalized data with cells as columns and features as rows or an \code{\link{Assay}}-derived object} \item{assay}{Name of the initial assay} \item{names.field}{For the initial identity class for each cell, choose this field from the cell's name. E.g. If your cells are named as BARCODE_CLUSTER_CELLTYPE in the input matrix, set \code{names.field} to 3 to set the initial identities to CELLTYPE.} \item{names.delim}{For the initial identity class for each cell, choose this delimiter from the cell's column name. E.g. If your cells are named as BARCODE-CLUSTER-CELLTYPE, set this to \dQuote{-} to separate the cell name into its component parts for picking the relevant field.} \item{meta.data}{Additional cell-level metadata to add to the Seurat object. Should be a \code{\link[base]{data.frame}} where the rows are cell names and the columns are additional metadata fields. Row names in the metadata need to match the column names of the counts matrix.} \item{project}{\link{Project} name for the \code{Seurat} object} \item{...}{Arguments passed to other methods} \item{min.cells}{Include features detected in at least this many cells. Will subset the counts matrix as well. To reintroduce excluded features, create a new object with a lower cutoff} \item{min.features}{Include cells where at least this many features are detected} } \value{ A \code{\link{Seurat}} object } \description{ Create a \code{Seurat} object from raw data } \note{ In previous versions (<3.0), this function also accepted a parameter to set the expression threshold for a \sQuote{detected} feature (gene). This functionality has been removed to simplify the initialization process/assumptions. If you would still like to impose this threshold for your particular dataset, simply filter the input expression matrix before calling this function. } \examples{ \dontrun{ pbmc_raw <- read.table( file = system.file('extdata', 'pbmc_raw.txt', package = 'Seurat'), as.is = TRUE ) pbmc_small <- CreateSeuratObject(counts = pbmc_raw) pbmc_small } } \concept{seurat} SeuratObject/man/Idents.Rd0000644000176200001440000000705015075522101015134 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{Idents} \alias{Idents} \alias{Idents<-} \alias{RenameIdents} \alias{RenameIdent} \alias{ReorderIdent} \alias{SetIdent} \alias{StashIdent} \alias{Idents.Seurat} \alias{Idents<-.Seurat} \alias{ReorderIdent.Seurat} \alias{RenameIdents.Seurat} \alias{SetIdent.Seurat} \alias{StashIdent.Seurat} \alias{droplevels.Seurat} \alias{levels.Seurat} \alias{levels<-.Seurat} \title{Get, set, and manipulate an object's identity classes} \usage{ Idents(object, ...) Idents(object, ...) <- value RenameIdents(object, ...) ReorderIdent(object, var, ...) SetIdent(object, ...) StashIdent(object, save.name, ...) \method{Idents}{Seurat}(object, ...) \method{Idents}{Seurat}(object, cells = NULL, drop = FALSE, replace = FALSE, ...) <- value \method{ReorderIdent}{Seurat}( object, var, reverse = FALSE, afxn = mean, reorder.numeric = FALSE, ... ) \method{RenameIdents}{Seurat}(object, ...) \method{SetIdent}{Seurat}(object, cells = NULL, value, ...) \method{StashIdent}{Seurat}(object, save.name = "orig.ident", ...) \method{droplevels}{Seurat}(x, ...) \method{levels}{Seurat}(x) \method{levels}{Seurat}(x) <- value } \arguments{ \item{...}{Arguments passed to other methods; for \code{RenameIdents}: named arguments as \code{old.ident = new.ident}; for \code{ReorderIdent}: arguments passed on to \code{\link{FetchData}}} \item{value}{The name of the identities to pull from object metadata or the identities themselves} \item{var}{Feature or variable to order on} \item{save.name}{Store current identity information under this name} \item{cells}{Set cell identities for specific cells} \item{drop}{Drop unused levels} \item{replace}{Replace identities for unset cells with \code{NA}} \item{reverse}{Reverse ordering} \item{afxn}{Function to evaluate each identity class based on; default is \code{\link[base]{mean}}} \item{reorder.numeric}{Rename all identity classes to be increasing numbers starting from 1 (default is FALSE)} \item{x, object}{An object} } \value{ \code{Idents}: The cell identities \code{Idents<-}: \code{object} with the cell identities changed \code{RenameIdents}: An object with selected identity classes renamed \code{ReorderIdent}: An object with \code{SetIdent}: An object with new identity classes set \code{StashIdent}: An object with the identities stashed } \description{ Get, set, and manipulate an object's identity classes } \examples{ # Get cell identity classes Idents(pbmc_small) # Set cell identity classes # Can be used to set identities for specific cells to a new level Idents(pbmc_small, cells = 1:4) <- 'a' head(Idents(pbmc_small)) # Can also set idents from a value in object metadata colnames(pbmc_small[[]]) Idents(pbmc_small) <- 'RNA_snn_res.1' levels(pbmc_small) # Rename cell identity classes # Can provide an arbitrary amount of idents to rename levels(pbmc_small) pbmc_small <- RenameIdents(pbmc_small, '0' = 'A', '2' = 'C') levels(pbmc_small) \dontrun{ head(Idents(pbmc_small)) pbmc_small <- ReorderIdent(pbmc_small, var = 'PC_1') head(Idents(pbmc_small)) } # Set cell identity classes using SetIdent cells.use <- WhichCells(pbmc_small, idents = '1') pbmc_small <- SetIdent(pbmc_small, cells = cells.use, value = 'B') head(pbmc_small[[]]) pbmc_small <- StashIdent(pbmc_small, save.name = 'idents') head(pbmc_small[[]]) # Get the levels of identity classes of a Seurat object levels(x = pbmc_small) # Reorder identity classes levels(x = pbmc_small) levels(x = pbmc_small) <- c('C', 'A', 'B') levels(x = pbmc_small) } \concept{seurat} SeuratObject/man/CastAssay.Rd0000644000176200001440000000140515075522101015577 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay5.R \name{CastAssay} \alias{CastAssay} \alias{CastAssay.Assay5} \title{Cast Assay Layers} \usage{ CastAssay(object, to, ...) \method{CastAssay}{Assay5}(object, to, layers = NA, verbose = TRUE, ...) } \arguments{ \item{object}{An object} \item{to}{Either a class name or a function that takes a layer and returns the same layer as a new class} \item{...}{If \code{to} is a function, arguments passed to \code{to}} \item{layers}{A vector of layers to cast; defaults to all layers} \item{verbose}{Show progress updates} } \value{ \code{object} with the layers cast to class specified by \code{to} } \description{ Cast layers in v5 assays to other classes } \concept{assay5} SeuratObject/man/Layers.Rd0000644000176200001440000000513615075522101015150 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/assay5.R, R/seurat.R \name{LayerData} \alias{LayerData} \alias{LayerData<-} \alias{Layers} \alias{LayerData.Assay} \alias{LayerData<-.Assay} \alias{Layers.Assay} \alias{LayerData.Assay5} \alias{LayerData<-.Assay5} \alias{Layers.Assay5} \alias{LayerData.Seurat} \alias{LayerData<-.Seurat} \alias{Layers.Seurat} \title{Query and Manipulate Assay Layers} \usage{ LayerData(object, layer, ...) LayerData(object, layer, ...) <- value Layers(object, ...) \method{LayerData}{Assay}( object, layer = NULL, cells = NULL, features = NULL, slot = deprecated(), ... ) \method{LayerData}{Assay}(object, layer, ...) <- value \method{Layers}{Assay}(object, search = NA, ...) \method{LayerData}{Assay5}( object, layer = NULL, cells = NULL, features = NULL, fast = FALSE, slot = deprecated(), ... ) \method{LayerData}{Assay5}(object, layer, features = NULL, cells = NULL, ...) <- value \method{Layers}{Assay5}(object, search = NA, ...) \method{LayerData}{Seurat}(object, layer = NULL, assay = NULL, slot = deprecated(), ...) \method{LayerData}{Seurat}(object, layer, assay = NULL, ...) <- value \method{Layers}{Seurat}(object, search = NA, assay = NULL, ...) } \arguments{ \item{object}{An object} \item{layer}{Name of layer to fetch or set} \item{...}{Arguments passed to other methods} \item{value}{New two-dimensional data to be added as a layer} \item{features, cells}{Vectors of features/cells to include} \item{slot}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")}} \item{search}{A pattern to search layer names for; pass one of: \itemize{ \item \dQuote{\code{NA}} to pull all layers \item \dQuote{\code{NULL}} to pull the default layer(s) \item a \link[base:grep]{regular expression} that matches layer names }} \item{fast}{Determine how to return the layer data; choose from: \describe{ \item{\code{FALSE}}{Apply any transpositions and attempt to add feature/cell names (if supported) back to the layer data} \item{\code{NA}}{Attempt to add feature/cell names back to the layer data, skip any transpositions} \item{\code{TRUE}}{Do not apply any transpositions or add feature/cell names to the layer data} }} \item{assay}{Name of assay to fetch layer data from or assign layer data to} } \value{ \code{LayerData}: the layer data for \code{layer} from \code{object} \code{Layer<-}: \code{object} with \code{value} added as a layer named \code{layer} \code{Layers}: the names of the layers present in \code{object} } \description{ Query and Manipulate Assay Layers } \concept{data-access} SeuratObject/man/Cells-StdAssay.Rd0000644000176200001440000000153215075522101016500 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{Cells-StdAssay} \alias{Cells-StdAssay} \alias{Cells.StdAssay} \alias{Features.StdAssay} \title{Cell and Feature Names} \usage{ \method{Cells}{StdAssay}(x, layer = NULL, simplify = TRUE, ...) \method{Features}{StdAssay}(x, layer = NULL, simplify = TRUE, ...) } \arguments{ \item{x}{An object} \item{layer}{Layer to pull cells/features for; defaults to default layer; if \code{NA}, returns all cells for the assay} \item{simplify}{Simplify the cell/feature names into a single vector; if \code{FALSE}, separates each cell/feature names by layer} \item{...}{Arguments passed to other methods} } \value{ \code{Cell}: A vector of cell names \code{Features}: A vector of feature names } \description{ Get the cell and feature names of an object } \keyword{internal} SeuratObject/man/JackStrawData-class.Rd0000644000176200001440000000111515075522101017470 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/jackstraw.R \docType{class} \name{JackStrawData-class} \alias{JackStrawData-class} \alias{JackStrawData} \title{The JackStrawData Class} \description{ The JackStrawData is used to store the results of a JackStraw computation. } \section{Slots}{ \describe{ \item{\code{empirical.p.values}}{Empirical p-values} \item{\code{fake.reduction.scores}}{Fake reduction scores} \item{\code{empirical.p.values.full}}{Empirical p-values on full} \item{\code{overall.p.values}}{Overall p-values from ScoreJackStraw} }} SeuratObject/man/show-oldseurat-method.Rd0000644000176200001440000000073215075522101020144 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{show,seurat-method} \alias{show,seurat-method} \title{Old Seurat Object Overview} \usage{ \S4method{show}{seurat}(object) } \arguments{ \item{object}{An old seurat object} } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link[=oldseurat]{seurat}} object overview } \concept{oldseurat} \keyword{internal} SeuratObject/man/Segmentation-class.Rd0000644000176200001440000000213515116320014017440 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/segmentation.R \docType{class} \name{Segmentation-class} \alias{Segmentation-class} \title{The \code{Segmentation} Class} \description{ A container for cell segmentation boundaries. Inherits from \code{\link[sp:SpatialPolygons-class]{SpatialPolygons}}. Supports storing boundaries in objects of class \code{\link[sf]{sf}}. } \section{Slots}{ \describe{ \item{\code{sf.data}}{Segmentation boundaries in \code{\link[sf]{sf}} format} \item{\code{compact}}{Logical indicating whether or not the object only stores segmentation information in the \code{sf.data} slot, rather than also in the standard \code{SpatialPolygons} slots, to save memory and processing time. Currently only relevant for Visium data.} }} \seealso{ \code{Segmentation} methods: \code{\link{Segmentation-methods}} Segmentation layer classes: \code{\link{Centroids-class}}, \code{\link{Centroids-methods}}, \code{\link{Molecules-class}}, \code{\link{Molecules-methods}}, \code{\link{Segmentation-methods}}, \code{\link{Segmentation-validity}} } \concept{segmentation} SeuratObject/man/Version.Rd0000644000176200001440000000066715075522101015342 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{Version} \alias{Version} \alias{Version.Seurat} \title{Get Version Information} \usage{ Version(object, ...) \method{Version}{Seurat}(object, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} } \description{ Get Version Information } \examples{ Version(pbmc_small) } \concept{data-access} SeuratObject/man/IsGlobal.Rd0000644000176200001440000000163215075522101015402 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/default.R, R/dimreduc.R \name{IsGlobal} \alias{IsGlobal} \alias{IsGlobal.default} \alias{IsGlobal.DimReduc} \title{Is an object global/persistent?} \usage{ IsGlobal(object, ...) \method{IsGlobal}{default}(object, ...) \method{IsGlobal}{DimReduc}(object, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} } \value{ \code{TRUE} if the object is global/persistent otherwise \code{FALSE} } \description{ Typically, when removing \code{Assay} objects from an \code{Seurat} object, all associated objects (eg. \code{DimReduc}, \code{Graph}, and \code{SeuratCommand} objects) are removed as well. If an associated object is marked as global/persistent, the associated object will remain even if its original assay was deleted } \examples{ IsGlobal(pbmc_small[['pca']]) } \concept{data-access} SeuratObject/man/merge.DimReduc.Rd0000644000176200001440000000204115075522101016473 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{merge.DimReduc} \alias{merge.DimReduc} \title{Merge Dimensional Reductions} \usage{ \method{merge}{DimReduc}(x = NULL, y = NULL, add.cell.ids = NULL, ...) } \arguments{ \item{x}{A \code{\link{DimReduc}} object} \item{y}{One or more \code{\link{DimReduc}} objects} \item{add.cell.ids}{A character vector equal to the number of objects provided to append to all cell names; if \code{TRUE}, uses \code{labels} as \code{add.cell.ids}} \item{...}{Ignored} } \value{ A new \code{DimReduc} object with data merged from \code{c(x, y)} } \description{ Merge two or more \link[=DimReduc]{dimensional reduction} together } \seealso{ Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/Centroids-class.Rd0000644000176200001440000000224015114353666016753 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/centroids.R \docType{class} \name{Centroids-class} \alias{Centroids-class} \title{The \code{Centroids} Class} \description{ The \code{Centroids} Class } \section{Slots}{ \describe{ \item{\code{cells}}{(\code{\link[base:character]{character [n]}}) A vector of cell names; there should be as many cell names as there are points and no duplicate names} \item{\code{nsides}}{(\code{\link[base:integer]{integer [1L]}}) The number of sides to draw when plotting centroids; must be either \code{0L} for circles or greater than 3} \item{\code{radius}}{(\code{\link[base:numeric]{numeric [1L]}}) The radius of the shape when plotting the centroids} \item{\code{theta}}{(\code{\link[base:numeric]{numeric [1L]}}) The angle in degrees to adjust the shape when plotting the centroids} }} \seealso{ \code{Centroids} methods: \code{\link{Centroids-methods}} Segmentation layer classes: \code{\link{Centroids-methods}}, \code{\link{Molecules-class}}, \code{\link{Molecules-methods}}, \code{\link{Segmentation-class}}, \code{\link{Segmentation-methods}}, \code{\link{Segmentation-validity}} } \concept{segmentation} SeuratObject/man/dimnames.Seurat.Rd0000644000176200001440000000270215075522101016744 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{dimnames.Seurat} \alias{dimnames.Seurat} \alias{dimnames<-.Seurat} \title{Feature and Cell Names} \usage{ \method{dimnames}{Seurat}(x) \method{dimnames}{Seurat}(x) <- value } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{value}{A two-length list with updated feature and/or cells names} } \value{ \code{dimnames}: A two-length list with the following values: \itemize{ \item A character vector with all features in the \link[=DefaultAssay]{default assay} \item A character vector with all cells in \code{x} } \code{dimnames<-}: \code{x} with the feature and/or cell names updated to \code{value} } \description{ Get and set feature and cell inames in \code{\link{Seurat}} objects } \examples{ # Get the feature names of an object head(rownames(pbmc_small)) # Get the cell names of an object head(colnames(pbmc_small)) colnames(pbmc_small)[1] <- "newcell" head(colnames(pbmc_small)) } \seealso{ Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} \code{\link{Cells}()}, \code{\link{dimnames.Assay}()}, \code{\link{dimnames.Assay5}()} } \concept{dimnames} \concept{seurat} SeuratObject/man/JS.Rd0000644000176200001440000000177315075522101014230 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/jackstraw.R, R/dimreduc.R \name{JS} \alias{JS} \alias{JS<-} \alias{JS.JackStrawData} \alias{JS<-.JackStrawData} \alias{JS.DimReduc} \alias{JS<-.DimReduc} \title{Get and set JackStraw information} \usage{ JS(object, ...) JS(object, ...) <- value \method{JS}{JackStrawData}(object, slot, ...) \method{JS}{JackStrawData}(object, slot, ...) <- value \method{JS}{DimReduc}(object, slot = NULL, ...) \method{JS}{DimReduc}(object, slot = NULL, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{JackStraw information} \item{slot}{Name of slot to store JackStraw scores to Can shorten to 'empirical', 'fake', 'full', or 'overall'} } \value{ \code{JS}: either a \code{\link{JackStrawData}} object or the specified jackstraw data \code{JS<-}: \code{object} with the update jackstraw information } \description{ Get and set JackStraw information } \concept{jackstraw} SeuratObject/man/split.Assay5.Rd0000644000176200001440000000562715116320014016210 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{split.Assay5} \alias{split.Assay5} \title{Split an Assay} \usage{ \method{split}{Assay5}( x, f, drop = FALSE, layers = c("counts", "data"), ret = c("assay", "multiassays", "layers"), ... ) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{f}{a \sQuote{factor} in the sense that \code{\link[base]{as.factor}(f)} defines the grouping, or a list of such factors in which case their interaction is used for the grouping. If \code{x} is a data frame, \code{f} can also be a formula of the form \code{ ~ g} to split by the variable \code{g}, or more generally of the form \code{ ~ g1 + \dots + gk} to split by the interaction of the variables \code{g1}, \dots, \code{gk}, where these variables are evaluated in the data frame \code{x} using the usual non-standard evaluation rules.} \item{drop}{logical indicating if levels that do not occur should be dropped (if \code{f} is a \code{factor} or a list).} \item{layers}{Names of layers to include in the split; pass \code{NA} for all layers; pass \code{NULL} for the \link[=DefaultLayer]{default layer}} \item{ret}{Type of return value; choose from: \itemize{ \item \dQuote{\code{assay}}: a single \code{\link{Assay5}} object \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects \item \dQuote{\code{layers}}: a list of layer matrices }} \item{...}{Ignored} } \value{ Depends on the value of \code{ret}: \itemize{ \item \dQuote{\code{assay}}: \code{x} with the layers requested in \code{layers} split based on \code{f}; all other layers are left as-is \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects; the list contains one value per split and each assay contains only the layers requested in \code{layers} with the \link[=Key]{key} set to the split \item \dQuote{\code{layers}}: a list of matrices of length \code{length(assays) * length(unique(f))}; the list is named as \dQuote{\code{layer.split}} } } \description{ Split an Assay } \section{Progress Updates with \pkg{progressr}}{ This function uses \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/cash-.Assay5.Rd0000644000176200001440000000156215075522101016047 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{$.Assay5} \alias{$.Assay5} \alias{$<-.Assay5} \title{Layer Data} \usage{ \method{$}{Assay5}(x, i) \method{$}{Assay5}(x, i) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{i}{Name of layer data to get or set} \item{value}{A matrix-like object to add as a new layer} } \value{ {$}: Layer data for layer \code{i} \code{$<-}: \code{x} with layer data \code{value} saved as \code{i} } \description{ Get and set layer data } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/as.list.SeuratCommand.Rd0000644000176200001440000000166315075522101020030 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \name{as.list.SeuratCommand} \alias{as.list.SeuratCommand} \title{Coerce a \code{SeuratCommand} to a list} \usage{ \method{as.list}{SeuratCommand}(x, complete = FALSE, ...) } \arguments{ \item{x}{A \code{\link{SeuratCommand}} object} \item{complete}{Include slots besides just parameters (eg. call string, name, timestamp)} \item{...}{Ignored} } \value{ A list with the parameters and, if \code{complete = TRUE}, the call string, name, and timestamp } \description{ Coerce a \code{SeuratCommand} to a list } \examples{ cmd <- pbmc_small[["NormalizeData.RNA"]] as.list(cmd) as.list(cmd, complete = TRUE) } \seealso{ Command log object and interaction methods \code{\link{$.SeuratCommand}()}, \code{\link{.DollarNames.SeuratCommand}()}, \code{\link{LogSeuratCommand}()}, \code{\link{SeuratCommand-class}}, \code{\link{[.SeuratCommand}()} } \concept{command} SeuratObject/man/dot-IsFutureSeurat.Rd0000644000176200001440000000200715075522101017421 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/zzz.R \name{.IsFutureSeurat} \alias{.IsFutureSeurat} \alias{IsFutureSeurat} \title{Test Future Compatibility with \pkg{Seurat}} \usage{ .IsFutureSeurat(version, lib.loc = NULL) } \arguments{ \item{version}{A version string or object of class \code{\link{package_version}}} \item{lib.loc}{a character vector of directory names of \R libraries, or \code{NULL}. The default value of \code{NULL} corresponds to all libraries currently known. If the default is used, the loaded packages and namespaces are searched before the libraries.} } \value{ \code{TRUE} if \pkg{SeuratObject} and/or \pkg{Seurat} } \description{ Check to see if \pkg{SeuratObject} and/or \pkg{Seurat} are at least a specific version or if they're configured to act as if they're a specific version (see details below). This allows testing compatibility with future requirements for both \pkg{SeuratObject} and \pkg{Seurat} } \details{ Blah blah blah } \keyword{internal} SeuratObject/man/dot-Deprecate.Rd0000644000176200001440000000540615075522101016371 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.Deprecate} \alias{.Deprecate} \title{Deprecate Functions and Arguments} \usage{ .Deprecate( when, what, with = NULL, ..., pkg = NULL, env = missing_arg(), user_env = missing_arg() ) } \arguments{ \item{when}{A string giving the version when the behaviour was deprecated.} \item{what}{A string describing what is deprecated: \itemize{ \item Deprecate a whole function with \code{"foo()"}. \item Deprecate an argument with \code{"foo(arg)"}. \item Partially deprecate an argument with \code{"foo(arg = 'must be a scalar integer')"}. \item Deprecate anything else with a custom message by wrapping it in \code{I()}. } You can optionally supply the namespace: \code{"ns::foo()"}, but this is usually not needed as it will be inferred from the caller environment.} \item{with}{An optional string giving a recommended replacement for the deprecated behaviour. This takes the same form as \code{what}.} \item{...}{ Arguments passed on to \code{\link[lifecycle:deprecate_soft]{lifecycle::deprecate_soft}} \describe{ \item{\code{details}}{In most cases the deprecation message can be automatically generated from \code{with}. When it can't, use \code{details} to provide a hand-written message. \code{details} can either be a single string or a character vector, which will be converted to a \link[cli:cli_bullets]{bulleted list}. By default, info bullets are used. Provide a named vectors to override.} \item{\code{id}}{The id of the deprecation. A warning is issued only once for each \code{id}. Defaults to the generated message, but you should give a unique ID when the message in \code{details} is built programmatically and depends on inputs, or when you'd like to deprecate multiple functions but warn only once for all of them.} \item{\code{env,user_env}}{Pair of environments that define where \verb{deprecate_*()} was called (used to determine the package name) and where the function called the deprecating function was called (used to determine if \code{deprecate_soft()} should message). These are only needed if you're calling \verb{deprecate_*()} from an internal helper, in which case you should forward \code{env = caller_env()} and \code{user_env = caller_env(2)}.} }} \item{pkg}{Name of package to use for comparison} \item{env, user_env}{Managed internally by \code{.Deprecate()}} } \value{ Run for its side effect and invisibly returns \code{NULL} } \description{ Provides automatic deprecation and defunctation of functions and arguments; } \seealso{ \code{\link[lifecycle:deprecate_soft]{lifecycle::deprecate_soft}()} \code{\link[lifecycle:deprecate_warn]{lifecycle::deprecate_warn}()} \code{\link[lifecycle:deprecate_stop]{lifecycle::deprecate_stop}()} } \keyword{internal} SeuratObject/man/dim.Assay5.Rd0000644000176200001440000000132315075522101015620 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{dim.Assay5} \alias{dim.Assay5} \title{Feature and Cell Numbers} \usage{ \method{dim}{Assay5}(x) } \arguments{ \item{x}{An \code{\link{Assay5}} object} } \value{ A two-length numeric vector with the total number of features and cells in \code{x} } \description{ Feature and Cell Numbers } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/cash-.Assay.Rd0000644000176200001440000000203615075522101015757 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{$.Assay} \alias{$.Assay} \alias{$<-.Assay} \title{Layer Data} \usage{ \method{$}{Assay}(x, i) \method{$}{Assay}(x, i) <- value } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{i}{Name of layer data to get or set} \item{value}{A matrix-like object to add as a new layer} } \value{ {$}: Layer data for layer \code{i} \code{$<-}: \code{x} with layer data \code{value} saved as \code{i} } \description{ Get and set layer data } \examples{ rna <- pbmc_small[["RNA"]] # Fetch a layer with `$` rna$data[1:10, 1:4] # Add a layer with `$` rna$data <- rna$counts rna$data[1:10, 1:4] } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/dimnames.StdAssay.Rd0000644000176200001440000000232315075522101017233 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{dimnames.StdAssay} \alias{dimnames.StdAssay} \alias{dimnames<-.StdAssay} \title{Assay-Level Feature and Cell Names} \usage{ \method{dimnames}{StdAssay}(x) \method{dimnames}{StdAssay}(x) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{value}{A two-length list with updated feature and/or cells names} } \value{ \code{dimnames}: A two-length list with the following values: \itemize{ \item A character vector with all features in \code{x} \item A character vector with all cells in \code{x} } \code{dimnames<-}: \code{x} with the feature and/or cell names updated to \code{value} } \description{ Get and set feature and cell names in v5 Assays } \seealso{ \code{\link{Cells}} \code{\link{Features}} v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/Crop.Rd0000644000176200001440000000154115075522101014610 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/fov.R \name{Crop} \alias{Crop} \alias{Crop.FOV} \title{Crop Coordinates} \usage{ Crop(object, x = NULL, y = NULL, coords = c("plot", "tissue"), ...) \method{Crop}{FOV}(object, x = NULL, y = NULL, coords = c("plot", "tissue"), ...) } \arguments{ \item{object}{An object} \item{x, y}{Range to crop x/y limits to; if \code{NULL}, uses full range of \code{x}/\code{y}} \item{coords}{Coordinate system to execute crop; choose from: \itemize{ \item \dQuote{\code{plot}}: Coordinates as shown when plotting \item \dQuote{\code{tissue}}: Coordinates from \code{\link{GetTissueCoordinates}} }} \item{...}{Arguments passed to other methods} } \value{ \code{object} cropped to the region specified by \code{x} and \code{y} } \description{ Crop Coordinates } \concept{spatial} SeuratObject/man/sub-.Assay.Rd0000644000176200001440000000243415075522101015634 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{[.Assay} \alias{[.Assay} \alias{[<-,Assay,character,ANY,ANY-method} \title{Layer Data} \usage{ \method{[}{Assay}(x, i = missing_arg(), j = missing_arg(), ...) \S4method{[}{Assay,character,ANY,ANY}(x, i, j, ...) <- value } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{i}{Name of layer data to get or set} \item{j}{Ignored} \item{...}{Arguments passed to \code{\link{LayerData}}} \item{value}{A matrix-like object to add as a new layer} } \value{ \code{[}: The layer data for layer \code{i} \code{[<-}: \code{x} with layer data \code{value} saved as \code{i} } \description{ Get and set layer data } \examples{ rna <- pbmc_small[["RNA"]] # Get a vector of layer names in this assay rna[] # Fetch layer data rna["data"][1:10, 1:4] # Set layer data rna["data"] <- rna["counts"] rna["data"][1:10, 1:4] } \seealso{ \code{\link{LayerData}} v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/dot-DollarNames.Seurat.Rd0000644000176200001440000000113715075522101020135 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{.DollarNames.Seurat} \alias{.DollarNames.Seurat} \title{Dollar-sign Autocompletion} \usage{ \method{.DollarNames}{Seurat}(x, pattern = "") } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{pattern}{ A regular expression. Only matching names are returned. } } \value{ The meta data matches for \code{pattern} } \description{ Autocompletion for \code{$} access on a \code{\link{Seurat}} object } \seealso{ \code{\link[utils:.DollarNames]{utils::.DollarNames}} } \concept{seurat} \keyword{internal} SeuratObject/man/dot-MARGIN.Rd0000644000176200001440000000053315075522101015446 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{.MARGIN} \alias{.MARGIN} \title{Get the Margin of an Object} \usage{ .MARGIN(x, ...) } \arguments{ \item{x}{An object} } \value{ The margin, eg. \code{1} for rows or \code{2} for columns } \description{ Get the Margin of an Object } \keyword{internal} SeuratObject/man/cash-.SeuratCommand.Rd0000644000176200001440000000137315075522101017444 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \name{$.SeuratCommand} \alias{$.SeuratCommand} \title{Command Log Parameter Access} \usage{ \method{$}{SeuratCommand}(x, i) } \arguments{ \item{x}{A \code{\link{SeuratCommand}} object} \item{i}{A parameter name} } \value{ The value for parameter \code{i} } \description{ Pull parameter values from a \code{\link{SeuratCommand}} object } \examples{ cmd <- pbmc_small[["NormalizeData.RNA"]] cmd$normalization.method } \seealso{ Command log object and interaction methods \code{\link{.DollarNames.SeuratCommand}()}, \code{\link{LogSeuratCommand}()}, \code{\link{SeuratCommand-class}}, \code{\link{[.SeuratCommand}()}, \code{\link{as.list.SeuratCommand}()} } \concept{command} SeuratObject/man/names.Seurat.Rd0000644000176200001440000000177015075522101016256 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{names.Seurat} \alias{names.Seurat} \title{Subobject Names} \usage{ \method{names}{Seurat}(x) } \arguments{ \item{x}{A \code{\link{Seurat}} object} } \value{ The names of all of the following subobjects within \code{x}: \itemize{ \item \link[=Assay]{v3} and \link[=Assay5]{v5} assays \item \link[=DimReduc]{dimensional reductions} \item \link[=SpatialImage]{images} and \link[=FOV]{FOVs} \item \link[=Graph]{nearest-neighbor graphs} } } \description{ Get the names of subobjects within a \code{\link{Seurat}} object } \examples{ names(pbmc_small) } \seealso{ Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/PolyVtx.Rd0000644000176200001440000000227015075522101015332 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{PolyVtx} \alias{PolyVtx} \title{Polygon Vertices} \usage{ PolyVtx(n, r = 1L, xc = 0L, yc = 0L, t1 = 0) } \arguments{ \item{n}{Number of sides of the polygon} \item{r}{Radius of the polygon} \item{xc, yc}{X/Y coordinates for the center of the polygon} \item{t1}{Angle of the first vertex in degrees} } \value{ A \code{\link[base]{data.frame}} with \code{n} rows and two columns: \describe{ \item{\code{x}}{X positions of each coordinate} \item{\code{y}}{Y positions of each coordinate} } } \description{ Calculate the vertices of a regular polygon given the number of sides and its radius (distance from center to vertex). Also permits transforming the resulting coordinates by moving the origin and altering the initial angle } \examples{ (coords <- PolyVtx(5, t1 = 90)) if (requireNamespace("ggplot2", quietly = TRUE)) { ggplot2::ggplot(coords, ggplot2::aes(x = x, y = y)) + ggplot2::geom_polygon() } } \references{ \url{https://stackoverflow.com/questions/3436453/calculate-coordinates-of-a-regular-polygons-vertices} } \seealso{ \code{\link{Angles}} } \concept{angles} \concept{utils} \keyword{internal} SeuratObject/man/Overlay.Rd0000644000176200001440000000312015075522101015321 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/centroids.R, R/segmentation.R, % R/molecules.R, R/fov.R \name{Overlay} \alias{Overlay} \alias{Overlay,Centroids,SpatialPolygons-method} \alias{Overlay,Segmentation,SpatialPolygons-method} \alias{Overlay,Molecules,SpatialPolygons-method} \alias{Overlay,FOV,Spatial-method} \alias{Overlay,FOV,SpatialPolygons-method} \alias{Overlay,FOV,FOV-method} \title{Overlay \code{Spatial} Objects Over One Another} \usage{ Overlay(x, y, invert = FALSE, ...) \S4method{Overlay}{Centroids,SpatialPolygons}(x, y, invert = FALSE, ...) \S4method{Overlay}{Segmentation,SpatialPolygons}(x, y, invert = FALSE, ...) \S4method{Overlay}{Molecules,SpatialPolygons}(x, y, invert = FALSE, ...) \S4method{Overlay}{FOV,Spatial}(x, y, invert = FALSE, ...) \S4method{Overlay}{FOV,SpatialPolygons}(x, y, invert = FALSE, ...) \S4method{Overlay}{FOV,FOV}(x, y, invert = FALSE, ...) } \arguments{ \item{x}{Query \code{Spatial} object} \item{y}{Target \code{Spatial} object} \item{invert}{Invert the overlay and return only the components of \code{x} that fall \emph{outside} the bounds of \code{y}} \item{...}{Ignored} } \value{ \code{x} with only the components that fall within the bounds of \code{y} } \description{ Create an overlay of some query spatial object (\code{x}) against some target object (\code{y}). Basically, find all components of a query that fall within the bounds of a target spatial region } \note{ This function requires the \href{https://cran.r-project.org/package=sf}{\pkg{sf}} package to be installed } \concept{spatial} SeuratObject/man/dot-CreateStdAssay.Rd0000644000176200001440000000473115075522101017354 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay5.R \name{.CreateStdAssay} \alias{.CreateStdAssay} \alias{.CreateStdAssay.default} \alias{.CreateStdAssay.list} \alias{.CreateStdAssay.Matrix} \alias{.CreateStdAssay.matrix} \title{Generic Assay Creation} \usage{ .CreateStdAssay( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = "Assay5", ... ) \method{.CreateStdAssay}{default}( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = "Assay5", layer = "counts", ... ) \method{.CreateStdAssay}{list}( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = "Assay5", csum = Matrix::colSums, fsum = Matrix::rowSums, ... ) \method{.CreateStdAssay}{Matrix}( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = "Assay5", layer = "counts", ... ) \method{.CreateStdAssay}{matrix}( counts, min.cells = 0, min.features = 0, cells = NULL, features = NULL, transpose = FALSE, type = "Assay5", layer = "counts", ... ) } \arguments{ \item{counts}{A two-dimensional expression matrix} \item{min.cells}{Include features detected in at least this many cells; will subset the counts matrix as well. To reintroduce excluded features, create a new object with a lower cutoff} \item{min.features}{Include cells where at least this many features are detected} \item{cells}{Vector of cell names} \item{features}{Vector of feature names} \item{type}{Type of assay object to create; must be the name of a class that's derived from \code{\link{StdAssay}}} \item{...}{Extra parameters passed to \code{\link[methods]{new}} for assay creation; used to set slots not defined by \code{\link{StdAssay}}} \item{layer}{Name of layer to store \code{counts} as} \item{csum}{Function for calculating cell sums} \item{fsum}{Function for calculating feature sums} } \value{ An object of class \code{type} with a layer named \code{layer} containing the data found in \code{counts} } \description{ Create an assay object; runs a standardized filtering scheme that works regardless of the direction of the data (eg. cells as columns and features as rows or vice versa) and creates an assay object based on the initialization scheme defined for \code{\link{StdAssay}}-derived class \code{type} } \concept{assay} \keyword{internal} SeuratObject/man/v5-assay-summaries.Rd0000644000176200001440000000265115075522101017363 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{v5-assay-summaries} \alias{v5-assay-summaries} \alias{colMeans,StdAssay-method} \alias{colSums,StdAssay-method} \alias{rowMeans,StdAssay-method} \alias{rowSums,StdAssay-method} \title{V5 Assay Summaries} \usage{ \S4method{colMeans}{StdAssay}(x, na.rm = FALSE, dims = 1, layer = NULL, ...) \S4method{colSums}{StdAssay}(x, na.rm = FALSE, dims = 1, layer = NULL, ...) \S4method{rowMeans}{StdAssay}(x, na.rm = FALSE, dims = 1, layer = NULL, ...) \S4method{rowSums}{StdAssay}(x, na.rm = FALSE, dims = 1, layer = NULL, ...) } \arguments{ \item{x}{an array of two or more dimensions, containing numeric, complex, integer or logical values, or a numeric data frame. For \code{.colSums()} etc, a numeric, integer or logical matrix (or vector of length \code{m * n}).} \item{na.rm}{logical. Should missing values (including \code{NaN}) be omitted from the calculations?} \item{dims}{integer: Which dimensions are regarded as \sQuote{rows} or \sQuote{columns} to sum over. For \code{row*}, the sum or mean is over dimensions \code{dims+1, \dots}; for \code{col*} it is over dimensions \code{1:dims}.} \item{layer}{Name of layer to run function on} \item{...}{Ignored} } \value{ The results of the summary math function for the layer specified } \description{ Summary maths for \code{\link{StdAssay}} Objects } \keyword{internal} SeuratObject/man/RandomName.Rd0000644000176200001440000000130315075522101015722 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{RandomName} \alias{RandomName} \title{Generate a random name} \usage{ RandomName(length = 5L, chars = letters, ...) } \arguments{ \item{length}{How long should the name be} \item{chars}{A vector of 1-length characters to use to generate the name} \item{...}{Extra parameters passed to \code{\link[base]{sample}}} } \value{ A character with \code{nchar == length} of randomly sampled letters } \description{ Make a name from randomly sampled characters, pasted together with no spaces } \examples{ set.seed(42L) RandomName() RandomName(7L, replace = TRUE) } \seealso{ \code{\link[base]{sample}} } \concept{utils} SeuratObject/man/subset.Assay.Rd0000644000176200001440000000166615075522101016301 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{subset.Assay} \alias{subset.Assay} \title{Subset an Assay} \usage{ \method{subset}{Assay}(x, cells = NULL, features = NULL, ...) } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{cells}{Cell names} \item{features}{Feature names} \item{...}{Ignored} } \value{ \code{x} with just the cells and features specified by \code{cells} and \code{features} } \description{ Subset an Assay } \examples{ rna <- pbmc_small[["RNA"]] rna2 <- subset(rna, features = VariableFeatures(rna)) rna2 } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()} } \concept{assay} SeuratObject/man/subset.Assay5.Rd0000644000176200001440000000165515075522101016364 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{subset.Assay5} \alias{subset.Assay5} \title{Subset an Assay} \usage{ \method{subset}{Assay5}(x, cells = NULL, features = NULL, layers = NULL, ...) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{cells}{Cell names} \item{features}{Feature names} \item{layers}{Layer to keep; defaults to all layers} \item{...}{Ignored} } \value{ \code{x} with just the cells and features specified by \code{cells} and \code{features} for the layers specified by \code{layers} } \description{ Subset an Assay } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()} } \concept{assay5} SeuratObject/man/Project.Rd0000644000176200001440000000121415075522101015310 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R \name{Project} \alias{Project} \alias{Project<-} \alias{Project.Seurat} \alias{Project<-.Seurat} \title{Get and set project information} \usage{ Project(object, ...) Project(object, ...) <- value \method{Project}{Seurat}(object, ...) \method{Project}{Seurat}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Project information to set} } \value{ Project information An object with project information added } \description{ Get and set project information } \concept{seurat} SeuratObject/man/dot-DiskLoad.Rd0000644000176200001440000000206015075522101016160 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{.DiskLoad} \alias{.DiskLoad} \alias{.DiskLoad.default} \alias{.DiskLoad.10xMatrixH5} \alias{.DiskLoad.AnnDataMatrixH5} \alias{.DiskLoad.DelayedMatrix} \alias{.DiskLoad.H5ADMatrix} \alias{.DiskLoad.HDF5Matrix} \alias{.DiskLoad.IterableMatrix} \alias{.DiskLoad.MatrixDir} \alias{.DiskLoad.MatrixH5} \alias{.DiskLoad.TileDBMatrix} \title{Disk Loading Function} \usage{ .DiskLoad(x) \method{.DiskLoad}{default}(x) \method{.DiskLoad}{`10xMatrixH5`}(x) \method{.DiskLoad}{AnnDataMatrixH5}(x) \method{.DiskLoad}{DelayedMatrix}(x) \method{.DiskLoad}{H5ADMatrix}(x) \method{.DiskLoad}{HDF5Matrix}(x) \method{.DiskLoad}{IterableMatrix}(x) \method{.DiskLoad}{MatrixDir}(x) \method{.DiskLoad}{MatrixH5}(x) \method{.DiskLoad}{TileDBMatrix}(x) } \arguments{ \item{x}{A file-backed object} } \value{ A one-length character that defines a function to load a matrix from a file } \description{ Generate a function to load a matrix from an on-disk file } \keyword{internal} SeuratObject/man/show-Graph-method.Rd0000644000176200001440000000065315075522101017205 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/graph.R \name{show,Graph-method} \alias{show,Graph-method} \title{Graph Object Overview} \usage{ \S4method{show}{Graph}(object) } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link{Graph}} Object } \examples{ pbmc_small[["RNA_snn"]] } \concept{graph} \keyword{internal} SeuratObject/man/FilterObjects.Rd0000644000176200001440000000142515116566601016456 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{FilterObjects} \alias{FilterObjects} \title{Find Sub-objects of a Certain Class} \usage{ FilterObjects(object, classes.keep = c("Assay", "StdAssay", "DimReduc")) } \arguments{ \item{object}{A \code{\link{Seurat}} object} \item{classes.keep}{A vector of names of classes to get} } \value{ A vector with the names of objects within the \code{Seurat} object that are of class \code{classes.keep} } \description{ Get the names of objects within a \code{Seurat} object that are of a certain class } \section{Lifecycle}{ \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} \code{FilterObjects} was deprecated in version 5.0.0; use \code{\link{.FilterObjects}} instead } \concept{utils} SeuratObject/man/Seurat-validity.Rd0000644000176200001440000000123715075522101016775 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{Seurat-validity} \alias{Seurat-validity} \title{Seurat Object Validity} \description{ Validation of \code{Seurat} objects is handled by \code{\link[methods]{validObject}} } \seealso{ \code{\link[methods]{validObject}} Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/Assay-class.Rd0000644000176200001440000000312415075522101016067 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \docType{class} \name{Assay-class} \alias{Assay-class} \alias{Assay} \title{The Assay Class} \description{ The Assay object is the basic unit of Seurat; each Assay stores raw, normalized, and scaled data as well as cluster information, variable features, and any other assay-specific metadata. Assays should contain single cell expression data such as RNA-seq, protein, or imputed expression data. } \section{Slots}{ \describe{ \item{\code{counts}}{Unnormalized data such as raw counts or TPMs} \item{\code{data}}{Normalized expression data} \item{\code{scale.data}}{Scaled expression data} \item{\code{assay.orig}}{Original assay that this assay is based off of. Used to track assay provenance} \item{\code{var.features}}{Vector of features exhibiting high variance across single cells} \item{\code{meta.features}}{Feature-level metadata} \item{\code{misc}}{A named list of unstructured miscellaneous data} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/DefaultDimReduc.Rd0000644000176200001440000000147015075522101016707 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{DefaultDimReduc} \alias{DefaultDimReduc} \title{Find the default \code{\link{DimReduc}}} \usage{ DefaultDimReduc(object, assay = NULL) } \arguments{ \item{object}{A \code{\link{Seurat}} object} \item{assay}{Name of assay to use; defaults to the default assay of the object} } \value{ The default \code{\link{DimReduc}}, if possible } \description{ Searches for \code{\link{DimReduc}s} matching \dQuote{umap}, \dQuote{tsne}, or \dQuote{pca}, case-insensitive, and in that order. Priority given to \code{\link{DimReduc}s} matching the \code{DefaultAssay} or assay specified (eg. \dQuote{pca} for the default assay weights higher than \dQuote{umap} for a non-default assay) } \examples{ DefaultDimReduc(pbmc_small) } \concept{utils} SeuratObject/man/dot-DefaultFOV.Rd0000644000176200001440000000061415075522101016430 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.DefaultFOV} \alias{.DefaultFOV} \title{Find the Default FOV} \usage{ .DefaultFOV(object, assay = NULL) } \arguments{ \item{object}{A \code{{Seurat}} object} } \value{ ... } \description{ Attempts to find the \dQuote{default} FOV using the revamped spatial framework } \concept{utils} \keyword{internal} SeuratObject/man/split.Seurat.Rd0000644000176200001440000000445215116320014016301 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{split.Seurat} \alias{split.Seurat} \title{Split an Assay} \usage{ \method{split}{Seurat}(x, f, drop = FALSE, assay = NULL, layers = NA, ...) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{f}{a \sQuote{factor} in the sense that \code{\link[base]{as.factor}(f)} defines the grouping, or a list of such factors in which case their interaction is used for the grouping. If \code{x} is a data frame, \code{f} can also be a formula of the form \code{ ~ g} to split by the variable \code{g}, or more generally of the form \code{ ~ g1 + \dots + gk} to split by the interaction of the variables \code{g1}, \dots, \code{gk}, where these variables are evaluated in the data frame \code{x} using the usual non-standard evaluation rules.} \item{drop}{logical indicating if levels that do not occur should be dropped (if \code{f} is a \code{factor} or a list).} \item{layers}{Names of layers to include in the split; pass \code{NA} for all layers; pass \code{NULL} for the \link[=DefaultLayer]{default layer}} \item{...}{Ignored} } \value{ Depends on the value of \code{ret}: \itemize{ \item \dQuote{\code{assay}}: \code{x} with the layers requested in \code{layers} split based on \code{f}; all other layers are left as-is \item \dQuote{\code{multiassay}}: a list of \code{\link{Assay5}} objects; the list contains one value per split and each assay contains only the layers requested in \code{layers} with the \link[=Key]{key} set to the split \item \dQuote{\code{layers}}: a list of matrices of length \code{length(assays) * length(unique(f))}; the list is named as \dQuote{\code{layer.split}} } } \description{ Split an Assay } \section{Progress Updates with \pkg{progressr}}{ This function uses \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \concept{Seurat} \keyword{internal} SeuratObject/man/Layers-StdAssay.Rd0000644000176200001440000000345415075522101016702 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{Layers-StdAssay} \alias{Layers-StdAssay} \alias{LayerData.StdAssay} \alias{LayerData<-.StdAssay} \alias{Layers.StdAssay} \title{Query and Manipulate Assay Layers} \usage{ \method{LayerData}{StdAssay}( object, layer = NULL, cells = NULL, features = NULL, fast = FALSE, slot = deprecated(), ... ) \method{LayerData}{StdAssay}(object, layer, features = NULL, cells = NULL, ...) <- value \method{Layers}{StdAssay}(object, search = NA, ...) } \arguments{ \item{object}{An object} \item{layer}{Name of layer to fetch or set} \item{features, cells}{Vectors of features/cells to include} \item{fast}{Determine how to return the layer data; choose from: \describe{ \item{\code{FALSE}}{Apply any transpositions and attempt to add feature/cell names (if supported) back to the layer data} \item{\code{NA}}{Attempt to add feature/cell names back to the layer data, skip any transpositions} \item{\code{TRUE}}{Do not apply any transpositions or add feature/cell names to the layer data} }} \item{slot}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")}} \item{...}{Arguments passed to other methods} \item{value}{New two-dimensional data to be added as a layer} \item{search}{A pattern to search layer names for; pass one of: \itemize{ \item \dQuote{\code{NA}} to pull all layers \item \dQuote{\code{NULL}} to pull the default layer(s) \item a \link[base:grep]{regular expression} that matches layer names }} } \value{ \code{LayerData}: the layer data for \code{layer} from \code{object} \code{Layer<-}: \code{object} with \code{value} added as a layer named \code{layer} \code{Layers}: the names of the layers present in \code{object} } \description{ Query and Manipulate Assay Layers } \keyword{internal} SeuratObject/man/IsSparse.Rd0000644000176200001440000000067215075522101015442 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sparse.R \name{IsSparse} \alias{IsSparse} \title{Is a Matrix Sparse} \usage{ IsSparse(x) } \arguments{ \item{x}{A matrix} } \value{ ... } \description{ Is a Matrix Sparse } \examples{ IsSparse(matrix()) IsSparse(LayerData(pbmc_small, "counts")) } \seealso{ \code{\link{.SparseSlots}()}, \code{\link{RegisterSparseMatrix}()} } \concept{sparse} \keyword{internal} SeuratObject/man/PackageCheck.Rd0000644000176200001440000000125015116566601016204 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{PackageCheck} \alias{PackageCheck} \title{Check the existence of a package} \usage{ PackageCheck(..., error = TRUE) } \arguments{ \item{...}{Package names} \item{error}{If true, throw an error if the package doesn't exist} } \value{ Invisibly returns boolean denoting if the package is installed } \description{ Check the existence of a package } \section{Lifecycle}{ \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} \code{PackageCheck} was deprecated in version 5.0.0; please use \code{\link[rlang:check_installed]{rlang::check_installed}()} instead } \concept{utils} SeuratObject/man/Neighbor-class.Rd0000644000176200001440000000147315075522101016551 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/neighbor.R \docType{class} \name{Neighbor-class} \alias{Neighbor-class} \alias{Neighbor} \title{The Neighbor class} \description{ The Neighbor class is used to store the results of neighbor finding algorithms } \section{Slots}{ \describe{ \item{\code{nn.idx}}{Matrix containing the nearest neighbor indices} \item{\code{nn.dist}}{Matrix containing the nearest neighbor distances} \item{\code{alg.idx}}{The neighbor finding index (if applicable). E.g. the annoy index} \item{\code{alg.info}}{Any information associated with the algorithm that may be needed downstream (e.g. distance metric used with annoy is needed when reading in from stored file).} \item{\code{cell.names}}{Names of the cells for which the neighbors have been computed.} }} SeuratObject/man/dot-RandomKey.Rd0000644000176200001440000000106015075522101016356 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/keymixin.R \name{.RandomKey} \alias{.RandomKey} \title{Generate a Random Key} \usage{ .RandomKey(length = 7L, ...) } \arguments{ \item{length}{How long should the name be} \item{...}{Extra parameters passed to \code{\link[base]{sample}}} } \value{ Returns a valid key } \description{ Generate a Random Key } \examples{ set.seed(42L) .RandomKey() } \seealso{ \code{\link{.KeyPattern}()}, \code{\link{Key-validity}}, \code{\link{KeyMixin-class}} } \concept{key} \keyword{internal} SeuratObject/man/Loadings.Rd0000644000176200001440000000262515075522101015451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/dimreduc.R, R/seurat.R \name{Loadings} \alias{Loadings} \alias{Loadings<-} \alias{Loadings.DimReduc} \alias{Loadings<-.DimReduc} \alias{Loadings.Seurat} \title{Get and set feature loadings} \usage{ Loadings(object, ...) Loadings(object, ...) <- value \method{Loadings}{DimReduc}(object, projected = FALSE, ...) \method{Loadings}{DimReduc}(object, projected = TRUE, ...) <- value \method{Loadings}{Seurat}(object, reduction = "pca", projected = FALSE, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Feature loadings to add} \item{projected}{Pull the projected feature loadings?} \item{reduction}{Name of reduction to pull feature loadings for} } \value{ \code{Loadings}: the feature loadings for \code{object} \code{Loadings<-}: \code{object} with the updated loadings } \description{ Get and set feature loadings } \examples{ # Get the feature loadings for a given DimReduc Loadings(object = pbmc_small[["pca"]])[1:5,1:5] # Set the feature loadings for a given DimReduc new.loadings <- Loadings(object = pbmc_small[["pca"]]) new.loadings <- new.loadings + 0.01 Loadings(object = pbmc_small[["pca"]]) <- new.loadings # Get the feature loadings for a specified DimReduc in a Seurat object Loadings(object = pbmc_small, reduction = "pca")[1:5,1:5] } \concept{data-access} SeuratObject/man/DefaultLayer.Rd0000644000176200001440000000146115075522101016267 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/assay5.R \name{DefaultLayer} \alias{DefaultLayer} \alias{DefaultLayer<-} \alias{DefaultLayer.Assay} \alias{DefaultLayer.Assay5} \alias{DefaultLayer<-.Assay5} \title{Default Layer} \usage{ DefaultLayer(object, ...) DefaultLayer(object, ...) <- value \method{DefaultLayer}{Assay}(object, ...) \method{DefaultLayer}{Assay5}(object, ...) \method{DefaultLayer}{Assay5}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Name of layer to set as default} } \value{ \code{DefaultLayer}: The name of the default layer \code{DefaultLayer<-}: An object with the default layer updated } \description{ Get and set the default layer } \concept{assay5} SeuratObject/man/Segmentation-methods.Rd0000644000176200001440000001157615116356172020025 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/segmentation.R \name{Segmentation-methods} \alias{Segmentation-methods} \alias{Cells.Segmentation} \alias{GetTissueCoordinates.Segmentation} \alias{RenameCells.Segmentation} \alias{lengths.Segmentation} \alias{subset.Segmentation} \alias{[[<-,Segmentation,character,missing,ANY-method} \alias{[[<-,Segmentation,character,missing,NULL-method} \alias{[,Segmentation,ANY,ANY,ANY-method} \alias{coordinates,Segmentation-method} \alias{show,Segmentation-method} \title{\code{Segmentation} Methods} \usage{ \method{Cells}{Segmentation}(x, ...) \method{GetTissueCoordinates}{Segmentation}(object, full = TRUE, ...) \method{RenameCells}{Segmentation}(object, new.names = NULL, ...) \method{lengths}{Segmentation}(x, use.names = TRUE) \method{subset}{Segmentation}(x, cells = NULL, ...) \S4method{[[}{Segmentation,character,missing,ANY}(x, i, j, ...) <- value \S4method{[[}{Segmentation,character,missing,NULL}(x, i, j, ...) <- value \S4method{[}{Segmentation,ANY,ANY,ANY}(x, i, j, ..., drop = TRUE) \S4method{coordinates}{Segmentation}(obj, full = TRUE, ...) \S4method{show}{Segmentation}(object) } \arguments{ \item{x, object, obj}{A \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object} \item{...}{Arguments passed to other methods} \item{full}{Expand the coordinates to the full polygon} \item{new.names}{vector of new cell names} \item{use.names}{Ignored} \item{i, cells}{A vector of cells to keep; if \code{NULL}, defaults to all cells} \item{j, drop}{Ignored} \item{value}{The value to assign to the slot specified by \code{i} in the \code{Segmentation} object.} } \value{ \code{Cells}: A vector of cell names \code{GetTissueCoordinates}, \code{coordinates}: A data frame with three columns: \itemize{ \item \dQuote{\code{x}}: the x-coordinate \item \dQuote{\code{y}}: the y-coordinate \item \dQuote{\code{cell}} or \dQuote{\code{ID}}: the cell name } If \code{full} is \code{TRUE}, then each coordinate will indicate a vertex for the cell polygon; otherwise, each coordinate will indicate a centroid for the cell. Note: to compute centroids for segmentations stored in compact mode, call \code{GetTissueCoordinates} on the associated \code{Centroids} object instead. \code{RenameCells}: \code{object} with the cells renamed to \code{new.names} \code{lengths}: An \code{\link[base:rle]{rle}} object for the cells \code{subset}, \code{[}: \code{x} subsetted to the cells specified by \code{cells}/\code{i} \code{[[<-}: \itemize{ \item If \code{value} is an \code{data.frame} object, returns \code{x} with \code{value} stored in \code{sf.data}; requires that \code{i} is \dQuote{sf.data}. \item If \code{value} is \code{NULL}, returns \code{x} with \code{sf.data} removed. } \code{show}: Invisibly returns \code{NULL} } \description{ Methods for \code{\link[SeuratObject:Segmentation-class]{Segmentation}} objects } \details{ \code{Cells}: Get cell names \code{GetTissueCoordinates}, \code{coordinates}: Get tissue coordinates \code{RenameCells}: Update cell names \code{lengths}: Generate a run-length encoding of the cells present \code{subset}, \code{[}: Subset a \code{Segmentation} object to certain cells \code{[[<-}: Attach or remove \code{sf}-derived data to/from a \code{Segmentation} object \code{show}: Display an object summary to stdout } \section{Progress Updates with \pkg{progressr}}{ The following methods use \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to render status updates and progress bars: \itemize{ \item \code{RenameCells} } To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \section{Parallelization with \pkg{future}}{ The following methods use \href{https://cran.r-project.org/package=future}{\pkg{future}} to enable parallelization: \itemize{ \item \code{RenameCells} } Parallelization strategies can be set using \code{\link[future]{plan}}. Common plans include \dQuote{\code{sequential}} for non-parallelized processing or \dQuote{\code{multisession}} for parallel evaluation using multiple \R sessions; for other plans, see the \dQuote{Implemented evaluation strategies} section of \code{\link[future:plan]{?future::plan}}. For a more thorough introduction to \pkg{future}, see \href{https://future.futureverse.org/articles/future-1-overview.html}{\code{vignette("future-1-overview")}} } \seealso{ \code{\link{Segmentation-class}} Segmentation layer classes: \code{\link{Centroids-class}}, \code{\link{Centroids-methods}}, \code{\link{Molecules-class}}, \code{\link{Molecules-methods}}, \code{\link{Segmentation-class}}, \code{\link{Segmentation-validity}} } \concept{future} \concept{segmentation} SeuratObject/man/dot-CheckFmargin.Rd0000644000176200001440000000071315075522101017012 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/layers.R \name{.CheckFmargin} \alias{.CheckFmargin} \title{Check Feature Margin} \usage{ .CheckFmargin(fmargin) } \arguments{ \item{fmargin}{Either \code{1} or \code{2}} } \value{ \code{fmargin} } \description{ Check Feature Margin } \examples{ .CheckFmargin(1L) .CheckFmargin(2.3) # Error if `fmargin` is outside of [1:2] if (FALSE) { .CheckFmargin(3L) } } \keyword{internal} SeuratObject/man/GetTissueCoordinates.Rd0000644000176200001440000000216515116356172020030 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/fov.R, R/seurat.R \name{GetTissueCoordinates} \alias{GetTissueCoordinates} \alias{GetTissueCoordinates.FOV} \alias{GetTissueCoordinates.Seurat} \title{Get tissue coordinates} \usage{ GetTissueCoordinates(object, ...) \method{GetTissueCoordinates}{FOV}(object, which = NULL, ...) \method{GetTissueCoordinates}{Seurat}(object, image = NULL, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{which}{Name of segmentation boundary or molecule set to retrieve coordinates for; if NULL, will retrieve coordinates for the default boundary} \item{image}{Name of \code{SpatialImage} object to get coordinates for; if \code{NULL}, will retrieve coordinates for the default image} } \value{ A data frame with tissue coordinates } \description{ Retrieve tissue coordinates from spatial objects. } \details{ Spatial classes may have specific implementations; refer to those documentation pages for more details. } \examples{ \dontrun{ GetTissueCoordinates(object, which = "centroids") } } \concept{data-access} SeuratObject/man/sub-.DimReduc.Rd0000644000176200001440000000242315075522101016246 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{[.DimReduc} \alias{[.DimReduc} \title{Get Feature Loadings} \usage{ \method{[}{DimReduc}(x, i, j, drop = FALSE, ...) } \arguments{ \item{x}{A \code{\link{DimReduc}} object} \item{i}{Feature identifiers or indices} \item{j}{Dimension identifiers or indices} \item{drop}{Coerce the result to the lowest possible dimension; see \code{\link{drop}} for further details} \item{...}{Arguments passed to other methods} } \value{ Feature loadings for features \code{i} and dimensions \code{j} } \description{ Pull feature loadings from a \link[=DimReduc]{dimensional reduction} } \details{ \code{[} does not distinguish between projected and unprojected feature loadings; to select whether projected or unprojected loadings should be pulled, please use \code{\link{Loadings}} } \examples{ pca <- pbmc_small[["pca"]] pca[1:10, 1:5] } \seealso{ \code{\link{Loadings}} Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/dot-GetConsensusFeatures.Rd0000644000176200001440000000203115114353666020617 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{.GetConsensusFeatures} \alias{.GetConsensusFeatures} \title{Returns the most frequently observed features in `features_by_layer`. If two features are observed at the same frequency their median index will be used to break the tie. If `nfeatures` is not specified, all features in `common_features` are returned.} \usage{ .GetConsensusFeatures(features_by_layer, common_features, nfeatures = NULL) } \arguments{ \item{features_by_layer}{A 2D named vector containing mapping each layer to it's corresponding variable features.} \item{common_features}{The intersection of features across all layers.} \item{nfeatures}{The number of variable features to return.} } \description{ Returns the most frequently observed features in `features_by_layer`. If two features are observed at the same frequency their median index will be used to break the tie. If `nfeatures` is not specified, all features in `common_features` are returned. } \keyword{internal} SeuratObject/man/show-LogMap-method.Rd0000644000176200001440000000070215075522101017316 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{show,LogMap-method} \alias{show,LogMap-method} \title{\code{\link{LogMap}} Object Overview} \usage{ \S4method{show}{LogMap}(object) } \arguments{ \item{object}{A \code{\link{LogMap}} object} } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link{LogMap}} object } \concept{logmap} SeuratObject/man/StdAssay-class.Rd0000644000176200001440000000500415075522101016541 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \docType{class} \name{StdAssay-class} \alias{StdAssay-class} \alias{StdAssay} \title{Core Assay Infrastructure} \description{ The \code{StdAssay} class is a virtual class that provides core infrastructure for assay data in \pkg{Seurat}. Assays contain expression data (layers) and associated feature-level meta data. Derived classes (eg. \link[=Assay5]{the v5 Assay}) may optionally define additional functionality } \section{Slots}{ \describe{ \item{\code{layers}}{A named list containing expression matrices; each matrix should be a two-dimensional object containing some subset of cells and features defined in the \code{cells} and \code{features} slots. Cell and feature membership is recorded in the \code{cells} and \code{features} slots, respectively} \item{\code{cells}}{A \link[=LogMap]{logical mapping} of cell names and layer membership; this map contains all the possible cells that this assay can contain. New layers must have some subset of cells present in this map} \item{\code{features}}{A \link[=LogMap]{logical mapping} of feature names and layer membership; this map contains all the possible features that this assay can contain. New layers must have some subset of features present in this map} \item{\code{default}}{A one-length integer with the end index of the \link[=DefaultLayer]{default layer}; the default layer be all layers up to and including the layer at index \code{default}} \item{\code{assay.orig}}{Original assay that this assay is based off of; used to track assay provenance} \item{\code{meta.data}}{A \link[base:data.frame]{data frame} with feature-level meta data; should have the same number of rows as \code{features}} \item{\code{misc}}{A named list of unstructured miscellaneous data} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \seealso{ \code{\link{Assay5-class}} \code{\link{Assay5T-class}} v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/Boundaries.Rd0000644000176200001440000000231715075522101016002 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/fov.R \name{Boundaries} \alias{Boundaries} \alias{DefaultBoundary} \alias{DefaultBoundary<-} \alias{Molecules} \alias{Boundaries.FOV} \alias{DefaultBoundary.FOV} \alias{DefaultBoundary<-.FOV} \alias{Molecules.FOV} \title{Get, Set, and Query Segmentation Boundaries} \usage{ Boundaries(object, ...) DefaultBoundary(object) DefaultBoundary(object, ...) <- value Molecules(object, ...) \method{Boundaries}{FOV}(object, ...) \method{DefaultBoundary}{FOV}(object) \method{DefaultBoundary}{FOV}(object, ...) <- value \method{Molecules}{FOV}(object, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{The name of a segmentation boundary to set as default} } \value{ \code{Boundaries}: The names of all segmentation boundaries present within \code{object} \code{DefaultBoundary}: The name of the default segmentation boundary \code{DefaultBoundary<-}: \code{object} with the default segmentation boundary set to \code{value} \code{Molecules}: The names of all molecule sets present within \code{object} } \description{ Get, Set, and Query Segmentation Boundaries } \concept{spatial} SeuratObject/man/StdAssay-validity.Rd0000644000176200001440000000240315075522101017261 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{StdAssay-validity} \alias{StdAssay-validity} \title{V5 Assay Validity} \description{ Validation of \code{StdAssay} objects is handled by \code{\link[methods]{validObject}} } \section{Layer Validation}{ blah } \section{Key Validation}{ Keys must be a one-length character vector; a key must be composed of one of the following: \itemize{ \item An empty string (eg. \dQuote{\code{''}}) where \code{nchar() == 0} \item An string composed of one or more alphanumeric values (both lower- and upper-case) that ends with an underscore (\dQuote{\code{_}}); the first character must be a letter } Keys that are not empty strings are validated with the regex \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}} } \seealso{ \code{\link[methods]{validObject}} v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/CheckMatrix.Rd0000644000176200001440000000222315075522101016105 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{CheckMatrix} \alias{CheckMatrix} \alias{CheckMatrix.default} \alias{CheckMatrix.dMatrix} \alias{CheckMatrix.lMatrix} \title{Check Matrix Validity} \usage{ CheckMatrix(object, checks, ...) \method{CheckMatrix}{default}(object, checks, ...) \method{CheckMatrix}{dMatrix}(object, checks = c("infinite", "logical", "integer", "na"), ...) \method{CheckMatrix}{lMatrix}(object, checks = c("infinite", "logical", "integer", "na"), ...) } \arguments{ \item{object}{A matrix} \item{checks}{Type of checks to perform, choose one or more from: \itemize{ \item \dQuote{\code{infinite}}: Emit a warning if any value is infinite \item \dQuote{\code{logical}}: Emit a warning if any value is a logical \item \dQuote{\code{integer}}: Emit a warning if any value is \emph{not} an integer \item \dQuote{\code{na}}: Emit a warning if any value is an \code{NA} or \code{NaN} }} \item{...}{Arguments passed to other methods} } \value{ Emits warnings for each test and invisibly returns \code{NULL} } \description{ Check Matrix Validity } \concept{utils} \keyword{internal} SeuratObject/man/reexports.Rd0000644000176200001440000000112715075522101015740 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/zzz.R \docType{import} \name{reexports} \alias{reexports} \alias{plan} \alias{intersect} \alias{handlers} \alias{with_progress} \title{Objects exported from other packages} \keyword{internal} \description{ These objects are imported from other packages. Follow the links below to see their documentation. \describe{ \item{future}{\code{\link[future]{plan}}} \item{generics}{\code{\link[generics:setops]{intersect}}} \item{progressr}{\code{\link[progressr]{handlers}}, \code{\link[progressr]{with_progress}}} }} SeuratObject/man/CreateMolecules.Rd0000644000176200001440000000174215075522101016764 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/molecules.R \name{CreateMolecules} \alias{CreateMolecules} \alias{CreateMolecules.data.frame} \alias{CreateMolecules.Molecules} \alias{CreateMolecules.NULL} \title{Create a \code{\link{Molecules}} Object} \usage{ CreateMolecules(coords, ...) \method{CreateMolecules}{data.frame}(coords, key = "", ...) \method{CreateMolecules}{Molecules}(coords, ...) \method{CreateMolecules}{`NULL`}(coords, ...) } \arguments{ \item{coords}{Spatial coordinates for molecules; should be a data frame with three columns: \itemize{ \item \dQuote{\code{x}}: x-coordinates for each molecule \item \dQuote{\code{y}}: y-coordinates for each molecule \item \dQuote{\code{gene}}: gene name for each molecule }} \item{...}{Arguments passed to other methods} \item{key}{A key to set for the molecules} } \value{ A \code{\link{Molecules}} object } \description{ Create a \code{\link{Molecules}} Object } \concept{spatial} SeuratObject/man/VariableFeatures.Rd0000644000176200001440000001146215114353666017150 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R, R/assay.R, R/assay5.R \name{HVFInfo} \alias{HVFInfo} \alias{VariableFeatures} \alias{VariableFeatures<-} \alias{SVFInfo} \alias{SpatiallyVariableFeatures} \alias{HVFInfo.Seurat} \alias{VariableFeatures.Seurat} \alias{VariableFeatures<-.Seurat} \alias{SVFInfo.Seurat} \alias{SpatiallyVariableFeatures.Seurat} \alias{HVFInfo.Assay} \alias{SpatiallyVariableFeatures.Assay} \alias{SVFInfo.Assay} \alias{VariableFeatures.Assay} \alias{VariableFeatures<-.Assay} \alias{HVFInfo.Assay5} \alias{VariableFeatures.Assay5} \alias{SVFInfo.StdAssay} \alias{SVFInfo.Assay5} \alias{SpatiallyVariableFeatures.Assay5} \title{Highly Variable Features} \usage{ HVFInfo(object, method, status = FALSE, ...) VariableFeatures(object, method = NULL, ...) VariableFeatures(object, ...) <- value SVFInfo(object, method, status, ...) SpatiallyVariableFeatures(object, method, ...) \method{HVFInfo}{Seurat}( object, method = NULL, status = FALSE, assay = NULL, selection.method = deprecated(), ... ) \method{VariableFeatures}{Seurat}( object, method = NULL, assay = NULL, nfeatures = NULL, layer = NA, simplify = TRUE, selection.method = deprecated(), ... ) \method{VariableFeatures}{Seurat}(object, assay = NULL, ...) <- value \method{SVFInfo}{Seurat}( object, method = c("markvariogram", "moransi"), status = FALSE, assay = NULL, selection.method = deprecated(), ... ) \method{SpatiallyVariableFeatures}{Seurat}( object, method = "moransi", assay = NULL, decreasing = TRUE, selection.method = deprecated(), ... ) \method{HVFInfo}{Assay}(object, method, status = FALSE, selection.method = deprecated(), ...) \method{SpatiallyVariableFeatures}{Assay}( object, method = "moransi", decreasing = TRUE, selection.method = deprecated(), ... ) \method{SVFInfo}{Assay}( object, method = c("markvariogram", "moransi"), status = FALSE, selection.method = deprecated(), ... ) \method{VariableFeatures}{Assay}(object, method = NULL, selection.method = deprecated(), ...) \method{VariableFeatures}{Assay}(object, ...) <- value \method{HVFInfo}{Assay5}(object, method = NULL, status = FALSE, layer = NA, strip = TRUE, ...) \method{VariableFeatures}{Assay5}( object, method = NULL, layer = NA, simplify = TRUE, nfeatures = NULL, selection.method = deprecated(), ... ) \method{SVFInfo}{StdAssay}( object, method = c("markvariogram", "moransi"), status = FALSE, selection.method = deprecated(), ... ) \method{SVFInfo}{Assay5}( object, method = c("markvariogram", "moransi"), status = FALSE, selection.method = deprecated(), ... ) \method{SpatiallyVariableFeatures}{Assay5}( object, method = "moransi", decreasing = TRUE, selection.method = deprecated(), ... ) } \arguments{ \item{object}{An object} \item{method}{Which method to pull. For \code{HVFInfo} and \code{VariableFeatures}, choose one from one of the following: \itemize{ \item \dQuote{vst} \item \dQuote{sctransform} or \dQuote{sct} \item \dQuote{mean.var.plot}, \dQuote{dispersion}, \dQuote{mvp}, or \dQuote{disp} } For \code{SVFInfo} and \code{SpatiallyVariableFeatures}, choose from: \itemize{ \item \dQuote{markvariogram} \item \dQuote{moransi} }} \item{status}{Add variable status to the resulting data frame} \item{...}{Arguments passed to other methods} \item{value}{A character vector of variable features} \item{assay}{Name of assay to pull highly variable feature information for} \item{selection.method}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")}} \item{nfeatures}{Maximum number of features to select when simplifying} \item{layer}{Layer to pull variable features for} \item{simplify}{When pulling for multiple layers, combine into a single vector and select a common set of variable features for all layers} \item{decreasing}{Return features in decreasing order (most spatially variable first).} \item{strip}{Remove method/layer identifiers from highly variable data frame} } \value{ \code{HVFInfo}: A data frame with feature means, dispersion, and scaled dispersion \code{VariableFeatures}: a vector of the variable features \code{SVFInfo}: a data frame with the spatially variable features \code{SpatiallyVariableFeatures}: a character vector of the spatially variable features } \description{ Get and set variable feature information for an \code{\link{Assay}} object. \code{HVFInfo} and \code{VariableFeatures} utilize generally variable features, while \code{SVFInfo} and \code{SpatiallyVariableFeatures} are restricted to spatially variable features } \examples{ # Get the HVF info from a specific Assay in a Seurat object HVFInfo(object = pbmc_small, assay = "RNA")[1:5, ] # Get the HVF info directly from an Assay object HVFInfo(pbmc_small[["RNA"]], method = 'vst')[1:5, ] } \concept{data-access} SeuratObject/man/CellsByIdentities.Rd0000644000176200001440000000147015075522101017265 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{CellsByIdentities} \alias{CellsByIdentities} \title{Get cell names grouped by identity class} \usage{ CellsByIdentities(object, idents = NULL, cells = NULL, return.null = FALSE) } \arguments{ \item{object}{A Seurat object} \item{idents}{A vector of identity class levels to limit resulting list to; defaults to all identity class levels} \item{cells}{A vector of cells to grouping to} \item{return.null}{If no cells are requested, return a \code{NULL}; by default, throws an error} } \value{ A named list where names are identity classes and values are vectors of cells belonging to that class } \description{ Get cell names grouped by identity class } \examples{ CellsByIdentities(object = pbmc_small) } \concept{data-access} SeuratObject/man/intersect.LogMap.Rd0000644000176200001440000000162515075522101017066 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{intersect.LogMap} \alias{intersect.LogMap} \title{Find Common Logical Map Values} \usage{ \method{intersect}{LogMap}(x, y = missing_arg(), ...) } \arguments{ \item{x}{A \code{LogMap} object} \item{y}{Ignored} \item{...}{Ignored} } \value{ The values of \code{x} that are present in \strong{every} observation } \description{ Identify values in a \link[=LogMap]{logical map} that are common to every observation } \examples{ map <- LogMap(letters[1:10]) map[['obs']] <- c(1, 3, 7) map[['entry']] <- c(2, 7, 10) # Identify values that are present in every observation intersect(map) } \seealso{ Logical map objects, validity, and interaction methods: \code{\link{LogMap}}, \code{\link{LogMap-validity}}, \code{\link{as.matrix.LogMap}()}, \code{\link{droplevels.LogMap}()}, \code{\link{labels.LogMap}()} } \concept{logmap} SeuratObject/man/dim.StdAssay.Rd0000644000176200001440000000146315075522101016213 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{dim.StdAssay} \alias{dim.StdAssay} \title{Feature and Cell Numbers} \usage{ \method{dim}{StdAssay}(x) } \arguments{ \item{x}{An \code{\link{Assay5}} object} } \value{ A two-length numeric vector with the total number of features and cells in \code{x} } \description{ Feature and Cell Numbers } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/dot-GetVariableFeatures.Rd0000644000176200001440000000226615114353666020376 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{.GetVariableFeatures} \alias{.GetVariableFeatures} \title{Returns the top variable features from a data frame of highly variable feature annotations. Features are marked as variable if their value in `label_column` is neither `NA` nor `FALSE`. When a ranking is provided via `rank_column`, features are ordered accordingly.} \usage{ .GetVariableFeatures(hvf_info, label_column, rank_column, nfeatures) } \arguments{ \item{hvf_info}{A `data.frame` containing highly variable feature annotations.} \item{label_column}{A column in `hvf_info` indicating which features are variable. A feature is considered variable if it's corresponding value is not `NA` or `FALSE`.} \item{rank_column}{A column in `hvf_info` indicating the rank of each feature.} \item{nfeatures}{The number of variable features to return.} } \description{ Returns the top variable features from a data frame of highly variable feature annotations. Features are marked as variable if their value in `label_column` is neither `NA` nor `FALSE`. When a ranking is provided via `rank_column`, features are ordered accordingly. } \keyword{internal} SeuratObject/man/dot-DollarNames.SeuratCommand.Rd0000644000176200001440000000143015075522101021430 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \name{.DollarNames.SeuratCommand} \alias{.DollarNames.SeuratCommand} \title{Dollar-sign Autocompletion} \usage{ \method{.DollarNames}{SeuratCommand}(x, pattern = "") } \arguments{ \item{x}{A \code{\link{SeuratCommand}} object} \item{pattern}{ A regular expression. Only matching names are returned. } } \value{ The parameter name matches for \code{pattern} } \description{ Autocompletion for \code{$} access on a \code{\link{SeuratCommand}} object } \seealso{ Command log object and interaction methods \code{\link{$.SeuratCommand}()}, \code{\link{LogSeuratCommand}()}, \code{\link{SeuratCommand-class}}, \code{\link{[.SeuratCommand}()}, \code{\link{as.list.SeuratCommand}()} } \concept{command} SeuratObject/man/FetchData.Rd0000644000176200001440000000324515075522101015533 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/dimreduc.R, R/seurat.R \name{FetchData} \alias{FetchData} \alias{FetchData.DimReduc} \alias{FetchData.Seurat} \title{Access cellular data} \usage{ FetchData(object, ...) \method{FetchData}{DimReduc}(object, vars, cells = NULL, ...) \method{FetchData}{Seurat}( object, vars, cells = NULL, layer = NULL, clean = TRUE, slot = deprecated(), ... ) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{vars}{List of all variables to fetch, use keyword \dQuote{ident} to pull identity classes} \item{cells}{Cells to collect data for (default is all cells)} \item{layer}{Layer to pull feature data for} \item{clean}{Remove cells that are missing data; choose from: \itemize{ \item \dQuote{\code{all}}: consider all columns for cleaning \item \dQuote{\code{ident}}: consider all columns except the identity class for cleaning \item \dQuote{\code{project}}: consider all columns except the identity class for cleaning; fill missing identity values with the object's project \item \dQuote{\code{none}}: do not clean } Passing \code{TRUE} is a shortcut for \dQuote{\code{ident}}; passing \code{FALSE} is a shortcut for \dQuote{\code{none}}} \item{slot}{Deprecated in favor of \code{layer}} } \value{ A data frame with cells as rows and cellular data as columns } \description{ Retrieves data (feature expression, PCA scores, metrics, etc.) for a set of cells in a Seurat object } \examples{ pc1 <- FetchData(object = pbmc_small, vars = 'PC_1') head(x = pc1) head(x = FetchData(object = pbmc_small, vars = c('groups', 'ident'))) } \concept{data-access} SeuratObject/man/RenameCells.Rd0000644000176200001440000000376415075522101016110 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/assay5.R, % R/dimreduc.R, R/neighbor.R, R/seurat.R \name{RenameCells} \alias{RenameCells} \alias{RenameCells.Assay} \alias{RenameCells.Assay5} \alias{RenameCells.DimReduc} \alias{RenameCells.Neighbor} \alias{RenameCells.Seurat} \title{Rename cells} \usage{ RenameCells(object, ...) \method{RenameCells}{Assay}(object, new.names = NULL, ...) \method{RenameCells}{Assay5}(object, new.names = NULL, ...) \method{RenameCells}{DimReduc}(object, new.names = NULL, ...) \method{RenameCells}{Neighbor}(object, old.names = NULL, new.names = NULL, ...) \method{RenameCells}{Seurat}( object, add.cell.id = missing_arg(), new.names = missing_arg(), for.merge = deprecated(), ... ) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{new.names}{vector of new cell names} \item{old.names}{vector of old cell names} \item{add.cell.id}{prefix to add cell names} \item{for.merge}{Deprecated} } \value{ An object with new cell names } \description{ Change the cell names in all the different parts of an object. Can be useful before combining multiple objects. } \details{ If \code{add.cell.id} is set a prefix is added to existing cell names. If \code{new.names} is set these will be used to replace existing names. } \examples{ # Rename cells in an Assay head(x = colnames(x = pbmc_small[["RNA"]])) renamed.assay <- RenameCells( pbmc_small[["RNA"]], new.names = paste0("A_", colnames(x = pbmc_small[["RNA"]])) ) head(x = colnames(x = renamed.assay)) # Rename cells in a DimReduc head(x = Cells(x = pbmc_small[["pca"]])) renamed.dimreduc <- RenameCells( object = pbmc_small[["pca"]], new.names = paste0("A_", Cells(x = pbmc_small[["pca"]])) ) head(x = Cells(x = renamed.dimreduc)) # Rename cells in a Seurat object head(x = colnames(x = pbmc_small)) pbmc_small <- RenameCells(object = pbmc_small, add.cell.id = "A") head(x = colnames(x = pbmc_small)) } \concept{seurat} SeuratObject/man/sub-subset-Seurat-NULL.Rd0000644000176200001440000000240115075522101020006 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{[[<-,Seurat,NULL} \alias{[[<-,Seurat,NULL} \alias{remove-object} \alias{remove-objects} \alias{\S4method{[[<-}{Seurat,character,missing,NULL}} \alias{[[<-,Seurat,character,missing,NULL-method} \title{Remove Subobjects and Cell-Level Meta Data} \usage{ \S4method{[[}{Seurat,character,missing,NULL}(x, i, j, ...) <- value } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{i}{Name(s) of subobject(s) or cell-level meta data to remove} \item{j}{Ignored} \item{...}{Ignored} \item{value}{NULL} } \value{ \code{x} with \code{i} removed from the object } \description{ Remove Subobjects and Cell-Level Meta Data } \seealso{ See \link[=[[.Seurat]{here} for pulling subobjects using \code{[[}, \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and \link[=[[<-,Seurat]{here} for adding subobjects with \code{[[<-} Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/CheckLayersName.Rd0000644000176200001440000000066115075522101016705 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{CheckLayersName} \alias{CheckLayersName} \title{Check layers names for the input list} \usage{ CheckLayersName(matrix.list, layers.type = c("counts", "data")) } \arguments{ \item{matrix.list}{A list of matrices} \item{layers.type}{layers type, such as counts or data} } \description{ Check layers names for the input list } \concept{utils} SeuratObject/man/DefaultAssay-StdAssay.Rd0000644000176200001440000000123015075522101020016 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{DefaultAssay-StdAssay} \alias{DefaultAssay-StdAssay} \alias{DefaultAssay.StdAssay} \alias{DefaultAssay<-.StdAssay} \title{Default Assay} \usage{ \method{DefaultAssay}{StdAssay}(object, ...) \method{DefaultAssay}{StdAssay}(object, ...) <- value } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Name of assay to set as default} } \value{ \code{DefaultAssay}: The name of the default assay \code{DefaultAssay<-}: An object with the default assay updated } \description{ Get and set the default assay } \keyword{internal} SeuratObject/man/Stdev.Rd0000644000176200001440000000150115075522101014766 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/dimreduc.R, R/seurat.R \name{Stdev} \alias{Stdev} \alias{Stdev.DimReduc} \alias{Stdev.Seurat} \title{Get the standard deviations for an object} \usage{ Stdev(object, ...) \method{Stdev}{DimReduc}(object, ...) \method{Stdev}{Seurat}(object, reduction = "pca", ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{reduction}{Name of reduction to use} } \value{ The standard deviations } \description{ Get the standard deviations for an object } \examples{ # Get the standard deviations for each PC from the DimReduc object Stdev(object = pbmc_small[["pca"]]) # Get the standard deviations for each PC from the Seurat object Stdev(object = pbmc_small, reduction = "pca") } \concept{data-access} SeuratObject/man/AddMetaData.Rd0000644000176200001440000000266315075522101016004 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/assay5.R, R/seurat.R \name{AddMetaData} \alias{AddMetaData} \alias{SeuratAccess} \alias{AddMetaData.Assay} \alias{AddMetaData.Assay5} \alias{AddMetaData.Seurat} \title{Add in metadata associated with either cells or features.} \usage{ AddMetaData(object, metadata, col.name = NULL) \method{AddMetaData}{Assay}(object, metadata, col.name = NULL) \method{AddMetaData}{Assay5}(object, metadata, col.name = NULL) \method{AddMetaData}{Seurat}(object, metadata, col.name = NULL) } \arguments{ \item{object}{An object} \item{metadata}{A vector, list, or data.frame with metadata to add} \item{col.name}{A name for meta data if not a named list or data.frame} } \value{ \code{object} with metadata added } \description{ Adds additional data to the object. Can be any piece of information associated with a cell (examples include read depth, alignment rate, experimental batch, or subpopulation identity) or feature (ENSG name, variance). To add cell level information, add to the Seurat object. If adding feature-level metadata, add to the Assay object (e.g. \code{object[["RNA"]]}) } \examples{ cluster_letters <- LETTERS[Idents(object = pbmc_small)] names(cluster_letters) <- colnames(x = pbmc_small) pbmc_small <- AddMetaData( object = pbmc_small, metadata = cluster_letters, col.name = 'letter.idents' ) head(x = pbmc_small[[]]) } \concept{seurat} SeuratObject/man/show-Seurat-method.Rd0000644000176200001440000000064515075522101017410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{show,Seurat-method} \alias{show,Seurat-method} \title{Seurat Object Overview} \usage{ \S4method{show}{Seurat}(object) } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link{Seurat}} object } \examples{ pbmc_small } \concept{seurat} \keyword{internal} SeuratObject/man/RowMergeSparseMatrices.Rd0000644000176200001440000000113615075522101020302 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{RowMergeSparseMatrices} \alias{RowMergeSparseMatrices} \title{Merge Sparse Matrices by Row} \usage{ RowMergeSparseMatrices(mat1, mat2) } \arguments{ \item{mat1}{First matrix} \item{mat2}{Second matrix or list of matrices} } \value{ Returns a sparse matrix } \description{ Merge two or more sparse matrices by rowname. } \details{ Shared matrix rows (with the same row name) will be merged, and unshared rows (with different names) will be filled with zeros in the matrix not containing the row. } \concept{utils} SeuratObject/man/AssayData-StdAssay.Rd0000644000176200001440000000260415075522101017311 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{AssayData-StdAssay} \alias{AssayData-StdAssay} \alias{GetAssayData.StdAssay} \alias{SetAssayData.StdAssay} \title{Get and Set Assay Data} \usage{ \method{GetAssayData}{StdAssay}(object, layer = NULL, slot = deprecated(), ...) \method{SetAssayData}{StdAssay}(object, layer, new.data, slot = deprecated(), ...) } \arguments{ \item{object}{An object} \item{layer}{Name of layer to get or set} \item{slot}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} Specific assay data to get or set} \item{...}{Arguments passed to other methods} \item{new.data}{New assay data to add} } \value{ \code{GetAssayData}: returns the specified assay data \code{SetAssayData}: \code{object} with the assay data set } \description{ General accessor and setter functions for \code{\link{Assay}} objects. \code{GetAssayData} can be used to pull information from any of the expression matrices (eg. \dQuote{counts}, \dQuote{data}, or \dQuote{scale.data}). \code{SetAssayData} can be used to replace one of these expression matrices } \section{Lifecycle}{ \Sexpr[stage=build,results=rd]{lifecycle::badge("superseded")} \code{GetAssayData} and \code{SetAssayData} have been superseded. To fetch expression matrices, use \code{\link{LayerData}}; to set expression data, use \code{\link{LayerData<-}} } \keyword{internal} SeuratObject/man/sub-sub-.Assay5.Rd0000644000176200001440000000254615075522101016514 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{[[.Assay5} \alias{[[.Assay5} \alias{[[<-,Assay5,ANY,ANY,ANY-method} \alias{head.Assay5} \alias{tail.Assay5} \title{Feature-Level Meta Data} \usage{ \method{[[}{Assay5}(x, i, j, ..., drop = FALSE) \S4method{[[}{Assay5,ANY,ANY,ANY}(x, i, j, ...) <- value \method{head}{Assay5}(x, n = 10L, ...) \method{tail}{Assay5}(x, n = 10L, ...) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{i}{Name of feature-level meta data to fetch or add} \item{j}{Ignored} \item{...}{Ignored} \item{drop}{See \code{\link{drop}}} \item{value}{Feature-level meta data to add} \item{n}{Number of meta data rows to show} } \value{ \code{[[}: The feature-level meta data for \code{i} \code{[[<-}: \code{x} with \code{value} added as \code{i} in feature-level meta data \code{head}: The first \code{n} rows of feature-level meta data \code{tail}: the last \code{n} rows of feature-level meta data } \description{ Get and set feature-level meta data } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/AddMetaData-StdAssay.Rd0000644000176200001440000000165215075522101017532 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{AddMetaData-StdAssay} \alias{AddMetaData-StdAssay} \alias{AddMetaData.StdAssay} \title{Add in metadata associated with either cells or features.} \usage{ \method{AddMetaData}{StdAssay}(object, metadata, col.name = NULL) } \arguments{ \item{object}{An object} \item{metadata}{A vector, list, or data.frame with metadata to add} \item{col.name}{A name for meta data if not a named list or data.frame} } \value{ \code{object} with metadata added } \description{ Adds additional data to the object. Can be any piece of information associated with a cell (examples include read depth, alignment rate, experimental batch, or subpopulation identity) or feature (ENSG name, variance). To add cell level information, add to the Seurat object. If adding feature-level metadata, add to the Assay object (e.g. \code{object[["RNA"]]}) } \keyword{internal} SeuratObject/man/StitchMatrix.Rd0000644000176200001440000000131415075522101016326 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{StitchMatrix} \alias{StitchMatrix} \title{Stitch Matrices Together} \usage{ StitchMatrix(x, y, rowmap, colmap, ...) } \arguments{ \item{x}{A matrix} \item{y}{One or more matrices of the same class or coercible to the same class as \code{x}} \item{rowmap, colmap}{\code{\link{LogMap}s} describing the row and cell membership of each matrix; the \code{LogMap} entries are assumed to be in the order of \code{c(x, y)}} \item{...}{Arguments passed to other methods} } \value{ A single matrix of type \code{class(x)} consisting of all values in component matrices } \description{ Stitch Matrices Together } \concept{utils} SeuratObject/man/CastAssay-StdAssay.Rd0000644000176200001440000000136315075522101017333 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{CastAssay-StdAssay} \alias{CastAssay-StdAssay} \alias{CastAssay.StdAssay} \title{Cast Assay Layers} \usage{ \method{CastAssay}{StdAssay}(object, to, layers = NA, verbose = TRUE, ...) } \arguments{ \item{object}{An object} \item{to}{Either a class name or a function that takes a layer and returns the same layer as a new class} \item{layers}{A vector of layers to cast; defaults to all layers} \item{verbose}{Show progress updates} \item{...}{If \code{to} is a function, arguments passed to \code{to}} } \value{ \code{object} with the layers cast to class specified by \code{to} } \description{ Cast layers in v5 assays to other classes } \keyword{internal} SeuratObject/man/figures/0000755000176200001440000000000015075522101015061 5ustar liggesusersSeuratObject/man/figures/lifecycle-questioning.svg0000644000176200001440000000171415075522101022107 0ustar liggesuserslifecyclelifecyclequestioningquestioning SeuratObject/man/figures/lifecycle-stable.svg0000644000176200001440000000167415075522101021021 0ustar liggesuserslifecyclelifecyclestablestable SeuratObject/man/figures/lifecycle-experimental.svg0000644000176200001440000000171615075522101022241 0ustar liggesuserslifecyclelifecycleexperimentalexperimental SeuratObject/man/figures/lifecycle-deprecated.svg0000644000176200001440000000171215075522101021640 0ustar liggesuserslifecyclelifecycledeprecateddeprecated SeuratObject/man/figures/lifecycle-superseded.svg0000644000176200001440000000171315075522101021704 0ustar liggesusers lifecyclelifecyclesupersededsuperseded SeuratObject/man/figures/lifecycle-archived.svg0000644000176200001440000000170715075522101021331 0ustar liggesusers lifecyclelifecyclearchivedarchived SeuratObject/man/figures/lifecycle-defunct.svg0000644000176200001440000000170415075522101021171 0ustar liggesuserslifecyclelifecycledefunctdefunct SeuratObject/man/figures/lifecycle-maturing.svg0000644000176200001440000000170615075522101021371 0ustar liggesuserslifecyclelifecyclematuringmaturing SeuratObject/man/Cells.Rd0000644000176200001440000000237615075522101014756 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/default.R, R/assay5.R, % R/dimreduc.R, R/neighbor.R \name{Cells} \alias{Cells} \alias{Features} \alias{Cells.default} \alias{Cells.Assay5} \alias{Features.Assay5} \alias{Cells.DimReduc} \alias{Cells.Neighbor} \title{Cell and Feature Names} \usage{ Cells(x, ...) Features(x, ...) \method{Cells}{default}(x, ...) \method{Cells}{Assay5}(x, layer = NULL, simplify = TRUE, ...) \method{Features}{Assay5}(x, layer = NULL, simplify = TRUE, ...) \method{Cells}{DimReduc}(x, ...) \method{Cells}{Neighbor}(x, ...) } \arguments{ \item{x}{An object} \item{...}{Arguments passed to other methods} \item{layer}{Layer to pull cells/features for; defaults to default layer; if \code{NA}, returns all cells for the assay} \item{simplify}{Simplify the cell/feature names into a single vector; if \code{FALSE}, separates each cell/feature names by layer} } \value{ \code{Cell}: A vector of cell names \code{Features}: A vector of feature names } \description{ Get the cell and feature names of an object } \examples{ Cells(x = pbmc_small) } \seealso{ \code{\link{dimnames.Assay}()}, \code{\link{dimnames.Assay5}()}, \code{\link{dimnames.Seurat}()} } \concept{data-access} \concept{dimnames} SeuratObject/man/MatchCells.Rd0000644000176200001440000000144115075522101015723 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/default.R \name{MatchCells} \alias{MatchCells} \alias{MatchCells.character} \alias{MatchCells.NULL} \alias{MatchCells.numeric} \title{Match Cells} \usage{ MatchCells(new, orig, ordered = FALSE) \method{MatchCells}{character}(new, orig, ordered = FALSE) \method{MatchCells}{`NULL`}(new, orig, ordered = FALSE) \method{MatchCells}{numeric}(new, orig, ordered = FALSE) } \arguments{ \item{new}{A vector of new cells} \item{orig}{A vector of existing cells} \item{ordered}{Sort the result to the same order as \code{orig}} } \value{ A numeric vector with new cells in order of the original cells; if no match can be found, returns \code{NULL} } \description{ Match Cells } \concept{utils} \keyword{internal} SeuratObject/man/cash-.StdAssay.Rd0000644000176200001440000000172615075522101016437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{$.StdAssay} \alias{$.StdAssay} \alias{$<-.StdAssay} \title{Layer Data} \usage{ \method{$}{StdAssay}(x, i) \method{$}{StdAssay}(x, i) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{i}{Name of layer data to get or set} \item{value}{A matrix-like object to add as a new layer} } \value{ {$}: Layer data for layer \code{i} \code{$<-}: \code{x} with layer data \code{value} saved as \code{i} } \description{ Get and set layer data } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/CellsByImage.Rd0000644000176200001440000000123215075522101016202 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{CellsByImage} \alias{CellsByImage} \title{Get a vector of cell names associated with an image (or set of images)} \usage{ CellsByImage(object, images = NULL, unlist = FALSE) } \arguments{ \item{object}{Seurat object} \item{images}{Vector of image names} \item{unlist}{Return as a single vector of cell names as opposed to a list, named by image name.} } \value{ A vector of cell names } \description{ Get a vector of cell names associated with an image (or set of images) } \examples{ \dontrun{ CellsByImage(object = object, images = "slice1") } } \concept{data-access} SeuratObject/man/show-DimReduc-method.Rd0000644000176200001440000000102215075522101017627 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{show,DimReduc-method} \alias{show,DimReduc-method} \title{Dimensional Reduction Overview} \usage{ \S4method{show}{DimReduc}(object) } \arguments{ \item{object}{A dimensional reduction} } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link{DimReduc}} object } \examples{ pca <- pbmc_small[["pca"]] pca } \seealso{ \code{\link{DimReduc}} } \keyword{internal} SeuratObject/man/sub-sub-.DimReduc.Rd0000644000176200001440000000210415075522101017031 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{[[.DimReduc} \alias{[[.DimReduc} \title{Get Cell Embeddings} \usage{ \method{[[}{DimReduc}(x, i, j, drop = FALSE, ...) } \arguments{ \item{x}{A \code{\link{DimReduc}} object} \item{i}{Cell names or indices} \item{j}{Dimension identifiers or indices} \item{drop}{Coerce the result to the lowest possible dimension; see \code{\link{drop}} for further details} \item{...}{Arguments passed to other methods} } \value{ Cell embeddings for cells \code{i} and dimensions \code{j} } \description{ Pull cell embeddings from a \link[=DimReduc]{dimensional reduction} } \examples{ pca <- pbmc_small[["pca"]] pca[[1:10, 1:5]] } \seealso{ \code{\link{Embeddings}} Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/Assay5-class.Rd0000644000176200001440000000423715075522101016162 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \docType{class} \name{Assay5-class} \alias{Assay5-class} \alias{Assay5} \title{The v5 \code{Assay} Object} \description{ The v5 \code{Assay} is the typical \code{Assay} class used in \pkg{Seurat} v5; ... } \section{Slots}{ \describe{ \item{\code{layers}}{A named list containing expression matrices; each matrix should be a two-dimensional object containing some subset of cells and features defined in the \code{cells} and \code{features} slots. Cell and feature membership is recorded in the \code{cells} and \code{features} slots, respectively} \item{\code{cells}}{A \link[=LogMap]{logical mapping} of cell names and layer membership; this map contains all the possible cells that this assay can contain. New layers must have some subset of cells present in this map} \item{\code{features}}{A \link[=LogMap]{logical mapping} of feature names and layer membership; this map contains all the possible features that this assay can contain. New layers must have some subset of features present in this map} \item{\code{default}}{A one-length integer with the end index of the \link[=DefaultLayer]{default layer}; the default layer be all layers up to and including the layer at index \code{default}} \item{\code{assay.orig}}{Original assay that this assay is based off of; used to track assay provenance} \item{\code{meta.data}}{A \link[base:data.frame]{data frame} with feature-level meta data; should have the same number of rows as \code{features}} \item{\code{misc}}{A named list of unstructured miscellaneous data} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{dimnames.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} } \concept{assay5} SeuratObject/man/dot-FilterObjects.Rd0000644000176200001440000000134315075522101017230 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.FilterObjects} \alias{.FilterObjects} \title{Find Subobjects Of A Certain Class} \usage{ .FilterObjects(object, classes.keep = c("Assay", "StdAssay", "DimReduc")) } \arguments{ \item{object}{An \link[methods:Classes_Details]{S4} object} \item{classes.keep}{A vector of classes to keep} } \value{ A vector of object names that are of class \code{classes.keep} } \description{ Find Subobjects Of A Certain Class } \examples{ .FilterObjects(pbmc_small) .FilterObjects(pbmc_small, "Graph") } \seealso{ \code{\link{.Collections}()}, \code{\link{.FindObject}()}, \code{\link{.Subobjects}()} } \concept{subobjects} \concept{utils} \keyword{internal} SeuratObject/man/sub-sub-.StdAssay.Rd0000644000176200001440000000433415075522101017077 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{[[.StdAssay} \alias{[[.StdAssay} \alias{head.StdAssay} \alias{tail.StdAssay} \alias{[[<-,StdAssay,character,missing,data.frame-method} \alias{[[<-,StdAssay,missing,missing,data.frame-method} \alias{[[<-,StdAssay,character,missing,factor-method} \alias{[[<-,StdAssay,character,missing,NULL-method} \alias{[[<-,StdAssay,character,missing,vector-method} \alias{[[<-,StdAssay,numeric,missing,ANY-method} \alias{[[<-,StdAssay,missing,missing,NULL-method} \title{Feature-Level Meta Data} \usage{ \method{[[}{StdAssay}(x, i, j, ..., drop = FALSE) \method{head}{StdAssay}(x, n = 10L, ...) \method{tail}{StdAssay}(x, n = 10L, ...) \S4method{[[}{StdAssay,character,missing,data.frame}(x, i, j, ...) <- value \S4method{[[}{StdAssay,missing,missing,data.frame}(x, i, j, ...) <- value \S4method{[[}{StdAssay,character,missing,factor}(x, i, j, ...) <- value \S4method{[[}{StdAssay,character,missing,NULL}(x, i, j, ...) <- value \S4method{[[}{StdAssay,character,missing,vector}(x, i, j, ...) <- value \S4method{[[}{StdAssay,numeric,missing,ANY}(x, i, j, ...) <- value \S4method{[[}{StdAssay,missing,missing,NULL}(x, i, j, ...) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{i}{Name of feature-level meta data to fetch or add} \item{j}{Ignored} \item{...}{Ignored} \item{drop}{See \code{\link{drop}}} \item{n}{Number of meta data rows to show} \item{value}{Feature-level meta data to add} } \value{ \code{[[}: The feature-level meta data for \code{i} \code{[[<-}: \code{x} with \code{value} added as \code{i} in feature-level meta data \code{head}: The first \code{n} rows of feature-level meta data \code{tail}: the last \code{n} rows of feature-level meta data } \description{ Get and set feature-level meta data } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/colMeans-Seurat-method.Rd0000644000176200001440000000307215075522101020166 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{colMeans,Seurat-method} \alias{colMeans,Seurat-method} \alias{colSums,Seurat-method} \alias{rowMeans,Seurat-method} \alias{rowSums,Seurat-method} \title{Row and Column Sums and Means} \usage{ \S4method{colMeans}{Seurat}(x, na.rm = FALSE, dims = 1, ..., slot = "data") \S4method{colSums}{Seurat}(x, na.rm = FALSE, dims = 1, ..., slot = "data") \S4method{rowMeans}{Seurat}(x, na.rm = FALSE, dims = 1, ..., slot = "data") \S4method{rowSums}{Seurat}(x, na.rm = FALSE, dims = 1, ..., slot = "data") } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{na.rm}{logical. Should missing values (including \code{NaN}) be omitted from the calculations?} \item{dims}{completely ignored by the \code{Matrix} methods.} \item{...}{potentially further arguments, for method \code{<->} generic compatibility.} \item{slot}{Name of assay expression matrix to calculate column/row means/sums on} } \value{ \code{colMeans}: the column (cell-wise) means of \code{slot} \code{colSums}: the column (cell-wise) sums of \code{slot} \code{rowMeans}: the row (feature-wise) means of \code{slot} \code{rowSums}: the row (feature-wise) sums of \code{slot} } \description{ Calculate \code{\link{rowSums}}, \code{\link{colSums}}, \code{\link{rowMeans}}, and \code{\link{colMeans}} on \code{\link{Seurat}} objects } \examples{ head(colMeans(pbmc_small)) head(colSums(pbmc_small)) head(rowMeans(pbmc_small)) head(rowSums(pbmc_small)) } \seealso{ \code{\link{Seurat}} } \concept{seurat} \keyword{internal} SeuratObject/man/AssayData.Rd0000644000176200001440000000533115075522101015560 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/seurat.R, R/assay.R \name{AssayData} \alias{AssayData} \alias{GetAssayData} \alias{SetAssayData} \alias{GetAssayData.Seurat} \alias{SetAssayData.Seurat} \alias{GetAssayData.Assay} \alias{SetAssayData.Assay} \title{Get and Set Assay Data} \usage{ GetAssayData(object, ...) SetAssayData(object, layer, new.data, slot = deprecated(), ...) \method{GetAssayData}{Seurat}(object, assay = NULL, layer = NULL, slot = deprecated(), ...) \method{SetAssayData}{Seurat}( object, layer = "data", new.data, slot = deprecated(), assay = NULL, ... ) \method{GetAssayData}{Assay}( object, layer = c("data", "scale.data", "counts"), slot = deprecated(), ... ) \method{SetAssayData}{Assay}( object, layer = c("data", "scale.data", "counts"), new.data, slot = deprecated(), ... ) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{layer}{Name of layer to get or set} \item{new.data}{New assay data to add} \item{slot}{\Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} Specific assay data to get or set} \item{assay}{Specific assay to get data from or set data for; defaults to the \link[=DefaultAssay]{default assay}} } \value{ \code{GetAssayData}: returns the specified assay data \code{SetAssayData}: \code{object} with the assay data set } \description{ General accessor and setter functions for \code{\link{Assay}} objects. \code{GetAssayData} can be used to pull information from any of the expression matrices (eg. \dQuote{counts}, \dQuote{data}, or \dQuote{scale.data}). \code{SetAssayData} can be used to replace one of these expression matrices } \section{Lifecycle}{ \Sexpr[stage=build,results=rd]{lifecycle::badge("superseded")} \code{GetAssayData} and \code{SetAssayData} have been superseded. To fetch expression matrices, use \code{\link{LayerData}}; to set expression data, use \code{\link{LayerData<-}} } \examples{ # Get assay data from the default assay in a Seurat object GetAssayData(object = pbmc_small, layer = "data")[1:5,1:5] # Set an Assay layer through the Seurat object count.data <- GetAssayData(object = pbmc_small[["RNA"]], layer = "counts") count.data <- as.matrix(x = count.data + 1) new.seurat.object <- SetAssayData( object = pbmc_small, layer = "counts", new.data = count.data, assay = "RNA" ) # Get the data directly from an Assay object GetAssayData(pbmc_small[["RNA"]], layer = "data")[1:5,1:5] # Set an Assay layer directly count.data <- GetAssayData(pbmc_small[["RNA"]], layer = "counts") count.data <- as.matrix(x = count.data + 1) new.assay <- SetAssayData(pbmc_small[["RNA"]], layer = "counts", new.data = count.data) } \concept{data-access} SeuratObject/man/show-SeuratCommand-method.Rd0000644000176200001440000000074315075522101020706 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \name{show,SeuratCommand-method} \alias{show,SeuratCommand-method} \title{Command Log Overview} \usage{ \S4method{show}{SeuratCommand}(object) } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link{SeuratCommand}} object } \examples{ cmd <- pbmc_small[["NormalizeData.RNA"]] cmd } \concept{command} \keyword{internal} SeuratObject/man/dot-Collections.Rd0000644000176200001440000000136215075522101016750 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.Collections} \alias{.Collections} \title{Identify Object Collections} \usage{ .Collections(object, exclude = character(length = 0L), ...) } \arguments{ \item{object}{An \link[methods:Classes_Details]{S4} object} \item{exclude}{A character vector of slot names to exclude} \item{...}{Arguments passed to \code{\link{IsNamedList}}} } \value{ A character vector of names of collection slots } \description{ Find all collection (named lists) slots in an S4 object } \examples{ .Collections(pbmc_small) } \seealso{ \code{\link{.FilterObjects}()}, \code{\link{.FindObject}()}, \code{\link{.Subobjects}()} } \concept{subobjects} \concept{utils} \keyword{internal} SeuratObject/man/RenameCells-StdAssay.Rd0000644000176200001440000000134315075522101017630 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{RenameCells-StdAssay} \alias{RenameCells-StdAssay} \alias{RenameCells.StdAssay} \title{Rename cells} \usage{ \method{RenameCells}{StdAssay}(object, new.names = NULL, ...) } \arguments{ \item{object}{An object} \item{new.names}{vector of new cell names} \item{...}{Arguments passed to other methods} } \value{ An object with new cell names } \description{ Change the cell names in all the different parts of an object. Can be useful before combining multiple objects. } \details{ If \code{add.cell.id} is set a prefix is added to existing cell names. If \code{new.names} is set these will be used to replace existing names. } \keyword{internal} SeuratObject/man/CreateAssayObject.Rd0000644000176200001440000000333315075522101017241 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{CreateAssayObject} \alias{CreateAssayObject} \title{Create an Assay object} \usage{ CreateAssayObject( counts, data, min.cells = 0, min.features = 0, key = NULL, check.matrix = FALSE, ... ) } \arguments{ \item{counts}{Unnormalized data such as raw counts or TPMs} \item{data}{Prenormalized data; if provided, do not pass \code{counts}} \item{min.cells}{Include features detected in at least this many cells. Will subset the counts matrix as well. To reintroduce excluded features, create a new object with a lower cutoff} \item{min.features}{Include cells where at least this many features are detected} \item{key}{Optional key to initialize assay with} \item{check.matrix}{Check counts matrix for NA, NaN, Inf, and non-integer values} \item{...}{Arguments passed to \code{\link{as.sparse}}} } \value{ A \code{\link{Assay}} object } \description{ Create an Assay object from a feature (e.g. gene) expression matrix. The expected format of the input matrix is features x cells. } \details{ Non-unique cell or feature names are not allowed. Please make unique before calling this function. } \examples{ \dontrun{ pbmc_raw <- read.table( file = system.file('extdata', 'pbmc_raw.txt', package = 'Seurat'), as.is = TRUE ) pbmc_rna <- CreateAssayObject(counts = pbmc_raw) pbmc_rna } } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/as.Seurat.Rd0000644000176200001440000000066715075522101015562 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{as.Seurat} \alias{as.Seurat} \title{Coerce to a \code{Seurat} Object} \usage{ as.Seurat(x, ...) } \arguments{ \item{x}{An object to convert to class \code{Seurat}} \item{...}{Arguments passed to other methods} } \value{ A \code{\link{Seurat}} object generated from \code{x} } \description{ Convert objects to Seurat objects } \concept{seurat} SeuratObject/man/Radius.Rd0000644000176200001440000000057515075522101015142 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{Radius} \alias{Radius} \title{Get the spot radius from an image} \usage{ Radius(object, ...) } \arguments{ \item{object}{An image object} \item{...}{Arguments passed to other methods} } \value{ The radius size } \description{ Get the spot radius from an image } \concept{spatialimage} SeuratObject/man/dot-FileMove.Rd0000644000176200001440000000176215075522101016204 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.FileMove} \alias{.FileMove} \title{Move Files and Directories} \usage{ .FileMove(path, new_path, overwrite = FALSE, n = 1L) } \arguments{ \item{path}{A character vector of one or more paths.} \item{new_path}{New file path. If \code{new_path} is existing directory, the file will be moved into that directory; otherwise it will be moved/renamed to the full path. Should either be the same length as \code{path}, or a single directory.} \item{n}{The number of callers to go back.} } \value{ The new path (invisibly). } \description{ Move files and directories with \pkg{fs}; includes a handler for when \code{path} is a directory on a different filesystem than \code{new_path} by explicitly copying and deleting \code{path} } \note{ This function requires the \href{https://cran.r-project.org/package=fs}{\pkg{fs}} package to be installed } \seealso{ \code{\link[fs:file_move]{fs::file_move}()} } \keyword{internal} SeuratObject/man/dim.DimReduc.Rd0000644000176200001440000000313515075522101016152 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{dim.DimReduc} \alias{dim.DimReduc} \alias{dimnames.DimReduc} \alias{length.DimReduc} \alias{names.DimReduc} \title{Dimensional Reduction Meta-Information} \usage{ \method{dim}{DimReduc}(x) \method{dimnames}{DimReduc}(x) \method{length}{DimReduc}(x) \method{names}{DimReduc}(x) } \arguments{ \item{x}{A \code{\link{DimReduc}} object} } \value{ \code{dim}: The number of cells (\code{nrow}) and dimensions (\code{ncol}) \code{dimnames}: The cell (row) and dimension (column) names \code{length}: The number of dimensions \code{names}: The dimension identifiers } \description{ Pull meta-information about cells and dimensions for a given \link[=DimReduc]{dimensional reduction}; cell meta-information is stored as row meta-information (eg. \code{nrow}, \code{rownames}) and dimension meta-information is stored as column meta-information (eg. \code{ncol}, \code{colnames}) } \examples{ pca <- pbmc_small[["pca"]] pca dim(pca) # nrow is number of cells nrow(pca) # rownames pulls cell names head(rownames(pca)) # ncol and length are number of dimensions ncol(pca) length(pca) # colnames and names pull dimension identifiers head(colnames(pca)) head(names(pca)) } \seealso{ \code{Cells} Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/show-Assay-method.Rd0000644000176200001440000000071715075522101017225 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{show,Assay-method} \alias{show,Assay-method} \title{V3 Assay Overview} \usage{ \S4method{show}{Assay}(object) } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of an \code{\link{Assay}} object } \examples{ rna <- pbmc_small[["RNA"]] rna } \seealso{ \code{\link{Assay}} } \concept{assay} \keyword{internal} SeuratObject/man/set-if-na.Rd0000644000176200001440000000136715075522101015476 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{set-if-na} \alias{set-if-na} \alias{\%NA\%} \alias{\%na\%} \alias{\%!NA\%} \alias{\%!na\%} \title{Set If or If Not \code{NA}} \usage{ x \%NA\% y x \%na\% y x \%!NA\% y x \%!na\% y } \arguments{ \item{x}{An object to test} \item{y}{A default value} } \value{ For \code{\%NA\%}: \code{y} if \code{x} is \code{\link[base]{NA}}; otherwise \code{x} For \code{\%!NA\%}: \code{y} if \code{x} is \strong{not} \code{\link[base]{NA}}; otherwise \code{x} } \description{ Set a default value depending on if an object is \code{\link[base]{NA}} } \examples{ # Set if NA 1 \%NA\% 2 NA \%NA\% 2 # Set if *not* NA 1 \%!NA\% 2 NA \%!NA\% 2 } \concept{utils} \keyword{internal} SeuratObject/man/dot-PropagateList.Rd0000644000176200001440000000204115075522101017243 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.PropagateList} \alias{.PropagateList} \title{Propagate a List} \usage{ .PropagateList(x, names, default = NA) } \arguments{ \item{x}{A list or character vector} \item{names}{A vector of names to keep from \code{x}} \item{default}{A default value for unassigned values of \code{x}} } \value{ A named list where the names are present in both \code{x} and \code{names} and the values are either the values from \code{x} or \code{default} } \description{ Propagate a List } \examples{ .PropagateList("counts", c("RNA", "ADT", "SCT")) .PropagateList(c("counts", "data"), c("RNA", "ADT", "SCT")) .PropagateList("ADT", c("RNA", "ADT", "SCT")) .PropagateList(c("RNA", "SCT"), c("RNA", "ADT", "SCT")) .PropagateList(c("RNA", ADT = "counts"), c("RNA", "ADT", "SCT")) .PropagateList(list(SCT = c("counts", "data"), ADT = "counts"), c("RNA", "ADT", "SCT")) .PropagateList(list(SCT = c("counts", "data"), "ADT"), c("RNA", "ADT", "SCT")) } \concept{utils} \keyword{internal} SeuratObject/man/sub-subset-Seurat-character-missing-StdAssay-method.Rd0000644000176200001440000000273615075522101025661 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{[[<-,Seurat,character,missing,StdAssay-method} \alias{[[<-,Seurat,character,missing,StdAssay-method} \title{Add Subobjects} \usage{ \S4method{[[}{Seurat,character,missing,StdAssay}(x, i, j, ...) <- value } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{i}{Name to add subobject as} \item{j}{Ignored} \item{...}{Ignored} \item{value}{A valid subobject (eg. a \link[=Assay]{v3} or \link[=Assay5]{v5} assay, or a \link[=DimReduc]{dimensional reduction})} } \value{ \code{x} with \code{value} added as \code{i} } \description{ Add subobjects containing expression, dimensional reduction, or other containerized data to a \code{\link{Seurat}} object. Subobjects can be accessed with \code{\link[=[[.Seurat]{[[}} and manipulated directly within the \code{Seurat} object or used independently } \seealso{ See \link[=[[.Seurat]{here} for pulling subobjects using \code{[[}, \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta data with \code{[[<-} Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \keyword{internal} SeuratObject/man/cash-.Seurat.Rd0000644000176200001440000000400615075522101016141 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{$.Seurat} \alias{$.Seurat} \alias{$<-.Seurat} \alias{[[<-,Seurat,character,missing,data.frame-method} \alias{[[<-,Seurat,missing,missing,data.frame-method} \alias{[[<-,Seurat,character,missing,factor-method} \alias{[[<-,Seurat,character,missing,list-method} \alias{[[<-,Seurat,missing,missing,list-method} \alias{[[<-,Seurat,character,missing,vector-method} \title{Cell-Level Meta Data} \usage{ \method{$}{Seurat}(x, i) \method{$}{Seurat}(x, i, ...) <- value \S4method{[[}{Seurat,character,missing,data.frame}(x, i, j, ...) <- value \S4method{[[}{Seurat,missing,missing,data.frame}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,factor}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,list}(x, i, j, ...) <- value \S4method{[[}{Seurat,missing,missing,list}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,vector}(x, i, j, ...) <- value } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{i}{Name of cell-level meta data} \item{...}{Ignored} \item{value}{A vector to add as cell-level meta data} \item{j}{Ignored} } \value{ {$}: Metadata column \code{i} for object \code{x}; \strong{note}: unlike \code{[[}, \code{$} drops the shape of the metadata to return a vector instead of a data frame \code{$<-}: \code{x} with metadata \code{value} saved as \code{i} } \description{ Get and set cell-level meta data } \examples{ # Get metadata using `$' head(pbmc_small$groups) # Add metadata using the `$' operator set.seed(42) pbmc_small$value <- sample(1:3, size = ncol(pbmc_small), replace = TRUE) head(pbmc_small[["value"]]) } \seealso{ Seurat object, validity, and interaction methods \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/merge.StdAssay.Rd0000644000176200001440000000220515075522101016534 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{merge.StdAssay} \alias{merge.StdAssay} \title{Merge Assays} \usage{ \method{merge}{StdAssay}(x, y, labels = NULL, add.cell.ids = NULL, collapse = FALSE, ...) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{y}{One or more \code{\link{Assay5}} objects} \item{labels}{A character vector equal to the number of objects; defaults to \code{as.character(seq_along(c(x, y)))}} \item{add.cell.ids}{A character vector equal to the number of objects provided to append to all cell names; if \code{TRUE}, uses \code{labels} as \code{add.cell.ids}} \item{collapse}{If \code{TRUE}, merge layers of the same name together; if \code{FALSE}, appends \code{labels} to the layer name} \item{...}{Ignored} } \value{ A new v5 assay with data merged from \code{c(x, y)} } \description{ Merge one or more v5 assays together } \details{ \strong{Note}: collapsing layers is currently not supported } \note{ All assays must be of the same type; merging different v5 assays (eg. \code{\link{Assay5}} and \code{\link{Assay5T}}) is currently unsupported } \keyword{internal} SeuratObject/man/CheckGC.Rd0000644000176200001440000000053115075522101015132 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{CheckGC} \alias{CheckGC} \title{Conditional Garbage Collection} \usage{ CheckGC(option = "SeuratObject.memsafe") } \arguments{ \item{option}{...} } \value{ Invisibly returns \code{NULL} } \description{ Call \code{gc} only when desired } \concept{utils} SeuratObject/man/ExtractField.Rd0000644000176200001440000000136415075522101016266 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{ExtractField} \alias{ExtractField} \title{Extract delimiter information from a string.} \usage{ ExtractField(string, field = 1, delim = "_") } \arguments{ \item{string}{String to parse.} \item{field}{Integer(s) indicating which field(s) to extract. Can be a vector multiple numbers.} \item{delim}{Delimiter to use, set to underscore by default.} } \value{ A new string, that parses out the requested fields, and (if multiple), rejoins them with the same delimiter } \description{ Parses a string (usually a cell name) and extracts fields based on a delimiter } \examples{ ExtractField('Hello World', field = 1, delim = '_') } \concept{utils} \keyword{internal} SeuratObject/man/print.DimReduc.Rd0000644000176200001440000000220215075522101016527 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{print.DimReduc} \alias{print.DimReduc} \alias{print} \title{Print Top Feature Loadings} \usage{ \method{print}{DimReduc}(x, dims = 1:5, nfeatures = 20, projected = FALSE, ...) } \arguments{ \item{x}{A \code{\link{DimReduc}} object} \item{dims}{Number of dimensions to display} \item{nfeatures}{Number of genes to display} \item{projected}{Use projected slot} \item{...}{Ignored} } \value{ Displays set of features defining the components and invisibly returns \code{x} } \description{ Prints a set of features that most strongly define a set of components; \strong{note}: requires feature loadings to be present in order to work } \examples{ pca <- pbmc_small[["pca"]] print(pca) } \seealso{ \code{\link[base]{cat}} Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/WhichCells.Rd0000644000176200001440000000354215075522101015735 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/seurat.R \name{WhichCells} \alias{WhichCells} \alias{WhichCells.Assay} \alias{WhichCells.Seurat} \title{Identify cells matching certain criteria} \usage{ WhichCells(object, ...) \method{WhichCells}{Assay}(object, cells = NULL, expression, invert = FALSE, ...) \method{WhichCells}{Seurat}( object, cells = NULL, idents = NULL, expression, slot = "data", invert = FALSE, downsample = Inf, seed = 1, ... ) } \arguments{ \item{object}{An object} \item{...}{ Arguments passed on to \code{\link[=CellsByIdentities]{CellsByIdentities}} \describe{ \item{\code{return.null}}{If no cells are requested, return a \code{NULL}; by default, throws an error} }} \item{cells}{Subset of cell names} \item{expression}{A predicate expression for feature/variable expression, can evaluate anything that can be pulled by \code{FetchData}; please note, you may need to wrap feature names in backticks (\code{``}) if dashes between numbers are present in the feature name} \item{invert}{Invert the selection of cells} \item{idents}{A vector of identity classes to keep} \item{slot}{Slot to pull feature data for} \item{downsample}{Maximum number of cells per identity class, default is \code{Inf}; downsampling will happen after all other operations, including inverting the cell selection} \item{seed}{Random seed for downsampling. If NULL, does not set a seed} } \value{ A vector of cell names } \description{ Returns a list of cells that match a particular set of criteria such as identity class, high/low values for particular PCs, etc. } \examples{ WhichCells(pbmc_small, idents = 2) WhichCells(pbmc_small, expression = MS4A1 > 3) levels(pbmc_small) WhichCells(pbmc_small, idents = c(1, 2), invert = TRUE) } \seealso{ \code{\link{FetchData}} } \concept{data-access} SeuratObject/man/split.Assay.Rd0000644000176200001440000000307215075522101016120 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{split.Assay} \alias{split.Assay} \title{Split an Assay} \usage{ \method{split}{Assay}(x, f, drop = FALSE, layers = NA, ...) } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{f}{a \sQuote{factor} in the sense that \code{\link[base]{as.factor}(f)} defines the grouping, or a list of such factors in which case their interaction is used for the grouping. If \code{x} is a data frame, \code{f} can also be a formula of the form \code{ ~ g} to split by the variable \code{g}, or more generally of the form \code{ ~ g1 + \dots + gk} to split by the interaction of the variables \code{g1}, \dots, \code{gk}, where these variables are evaluated in the data frame \code{x} using the usual non-standard evaluation rules.} \item{drop}{logical indicating if levels that do not occur should be dropped (if \code{f} is a \code{factor} or a list).} \item{layers}{Names of layers to include in the split; pass \code{NA} for all layers; pass \code{NULL} for the \link[=DefaultLayer]{default layer}} \item{...}{Ignored} } \value{ Returns a v5 assay with splitted layers } \description{ Split an Assay } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/UpdateSeuratObject.Rd0000644000176200001440000000122215075522101017436 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{UpdateSeuratObject} \alias{UpdateSeuratObject} \title{Update old Seurat object to accommodate new features} \usage{ UpdateSeuratObject(object) } \arguments{ \item{object}{Seurat object} } \value{ Returns a Seurat object compatible with latest changes } \description{ Updates Seurat objects to new structure for storing data/calculations. For Seurat v3 objects, will validate object structure ensuring all keys and feature names are formed properly. } \examples{ \dontrun{ updated_seurat_object = UpdateSeuratObject(object = old_seurat_object) } } \concept{seurat} SeuratObject/man/sub-subset-Seurat.Rd0000644000176200001440000000442615075522101017247 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{[[<-,Seurat} \alias{[[<-,Seurat} \alias{[[<-.Seurat} \alias{\S4method{[[<-}{Seurat,character,missing,Assay}} \alias{[[<-,Seurat,character,missing,Assay-method} \alias{[[<-,Seurat,character,missing,Assay5-method} \alias{[[<-,Seurat,character,missing,DimReduc-method} \alias{[[<-,Seurat,character,missing,Graph-method} \alias{[[<-,Seurat,character,missing,Neighbor-method} \alias{[[<-,Seurat,character,missing,SeuratCommand-method} \alias{[[<-,Seurat,character,missing,SpatialImage-method} \title{Add Subobjects} \usage{ \S4method{[[}{Seurat,character,missing,Assay}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,Assay5}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,DimReduc}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,Graph}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,Neighbor}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,SeuratCommand}(x, i, j, ...) <- value \S4method{[[}{Seurat,character,missing,SpatialImage}(x, i, j, ...) <- value } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{i}{Name to add subobject as} \item{j}{Ignored} \item{...}{Ignored} \item{value}{A valid subobject (eg. a \link[=Assay]{v3} or \link[=Assay5]{v5} assay, or a \link[=DimReduc]{dimensional reduction})} } \value{ \code{x} with \code{value} added as \code{i} } \description{ Add subobjects containing expression, dimensional reduction, or other containerized data to a \code{\link{Seurat}} object. Subobjects can be accessed with \code{\link[=[[.Seurat]{[[}} and manipulated directly within the \code{Seurat} object or used independently } \seealso{ See \link[=[[.Seurat]{here} for pulling subobjects using \code{[[}, \link[=$.Seurat]{here} for adding metadata with \code{[[<-}, and \link[=[[<-,Seurat,NULL]{here} for removing subobjects and cell-level meta data with \code{[[<-} Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/subset.DimReduc.Rd0000644000176200001440000000154515075522101016711 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{subset.DimReduc} \alias{subset.DimReduc} \title{Subset a Dimensional Reduction} \usage{ \method{subset}{DimReduc}(x, cells = NULL, features = NULL, ...) } \arguments{ \item{x}{A \code{\link{DimReduc}} object} \item{cells, features}{Cells and features to keep during the subset} \item{...}{Ignored} } \value{ \code{x} for cells \code{cells} and features \code{features} } \description{ Subset a \code{\link{DimReduc}} object } \seealso{ Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()} } \concept{dimreduc} SeuratObject/man/Seurat-class.Rd0000644000176200001440000000447015075522101016257 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \docType{class} \name{Seurat-class} \alias{Seurat-class} \alias{Seurat} \title{The Seurat Class} \description{ The Seurat object is a representation of single-cell expression data for R; each Seurat object revolves around a set of cells and consists of one or more \code{\link{Assay}} objects, or individual representations of expression data (eg. RNA-seq, ATAC-seq, etc). These assays can be reduced from their high-dimensional state to a lower-dimension state and stored as \code{\link{DimReduc}} objects. Seurat objects also store additional metadata, both at the cell and feature level (contained within individual assays). The object was designed to be as self-contained as possible, and easily extendable to new methods. } \section{Slots}{ \describe{ \item{\code{assays}}{A list of assays for this project} \item{\code{meta.data}}{Contains meta-information about each cell, starting with number of features detected (nFeature) and the original identity class (orig.ident); more information is added using \code{\link{AddMetaData}}} \item{\code{active.assay}}{Name of the active, or default, assay; settable using \code{\link{DefaultAssay}}} \item{\code{active.ident}}{The active cluster identity for this Seurat object; settable using \code{\link{Idents}}} \item{\code{graphs}}{A list of \code{\link{Graph}} objects} \item{\code{neighbors}}{...} \item{\code{reductions}}{A list of dimensional reduction objects for this object} \item{\code{images}}{A list of spatial image objects} \item{\code{project.name}}{Name of the project} \item{\code{misc}}{A list of miscellaneous information} \item{\code{version}}{Version of Seurat this object was built under} \item{\code{commands}}{A list of logged commands run on this \code{Seurat} object} \item{\code{tools}}{A list of miscellaneous data generated by other tools, should be filled by developers only using \code{\link{Tool}<-}} }} \seealso{ Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/dot-DollarNames.Assay.Rd0000644000176200001440000000113315075522101017746 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{.DollarNames.Assay} \alias{.DollarNames.Assay} \title{Dollar-sign Autocompletion} \usage{ \method{.DollarNames}{Assay}(x, pattern = "") } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{pattern}{ A regular expression. Only matching names are returned. } } \value{ The layer name matches for \code{pattern} } \description{ Autocompletion for \code{$} access on an \code{\link{Assay}} object } \seealso{ \code{\link[utils:.DollarNames]{utils::.DollarNames}} } \concept{assay} \keyword{internal} SeuratObject/man/DimReduc-class.Rd0000644000176200001440000000325615075522101016511 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \docType{class} \name{DimReduc-class} \alias{DimReduc-class} \alias{DimReduc} \title{The Dimensional Reduction Class} \description{ The DimReduc object stores a dimensionality reduction taken out in Seurat; each DimReduc consists of a cell embeddings matrix, a feature loadings matrix, and a projected feature loadings matrix. } \section{Slots}{ \describe{ \item{\code{cell.embeddings}}{Cell embeddings matrix (required)} \item{\code{feature.loadings}}{Feature loadings matrix (optional)} \item{\code{feature.loadings.projected}}{Projected feature loadings matrix (optional)} \item{\code{assay.used}}{Name of assay used to generate \code{DimReduc} object} \item{\code{global}}{Is this \code{DimReduc} global/persistent? If so, it will not be removed when removing its associated assay} \item{\code{stdev}}{A vector of standard deviations} \item{\code{jackstraw}}{A \code{\link{JackStrawData-class}} object associated with this \code{DimReduc}} \item{\code{misc}}{A named list of unstructured miscellaneous data} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \seealso{ Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-validity}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/EmptyDF.Rd0000644000176200001440000000072415075522101015217 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{EmptyDF} \alias{EmptyDF} \title{Empty Data Frames} \usage{ EmptyDF(n) } \arguments{ \item{n}{Number of rows for the data frame} } \value{ A \link[base:data.frame]{data frame} with \code{n} rows and zero columns } \description{ Create an empty \link[base:data.frame]{data frame} with no row names and zero columns } \examples{ EmptyDF(4L) } \concept{utils} \keyword{internal} SeuratObject/man/FOV-class.Rd0000644000176200001440000000303715116320014015437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fov.R \docType{class} \name{FOV-class} \alias{FOV-class} \alias{FOV} \title{The Field of View Object} \description{ A modern container for storing coordinates of spatially-resolved single cells. Capable of storing multiple cell segmentation boundary masks. Supports coordinates for spatially-resolved molecule (FISH) data. Compatible with \code{\link{SpatialImage}} } \section{Slots}{ \describe{ \item{\code{molecules}}{A named list of \code{\link[SeuratObject:Molecules-class]{Molecules}} objects defining spatially-resolved molecular coordinates} \item{\code{boundaries}}{A named list of \code{\link[SeuratObject:Segmentation-class]{Segmentation}} and \code{\link[SeuratObject:Centroids-class]{Centroids}} objects defining spatially-resolved boundaries} \item{\code{coords_x_orientation}}{A character indicating which axis \code{x} coordinates are associated with in spatial plots. Currently only applies to Visium objects. Ensures consistency in plotting spatial data across versions, as objects prior to the addition of this slot had \code{x} coordinates mapped to the vertical axis.} \item{\code{assay}}{A character naming the associated assay of the spatial coordinates} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \seealso{ \code{\link{FOV-methods}} } \concept{fov} SeuratObject/man/pbmc_small.Rd0000644000176200001440000000227315116320014016014 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.R \docType{data} \name{pbmc_small} \alias{pbmc_small} \title{A small example version of the PBMC dataset} \format{ A Seurat object with the following slots filled \describe{ \item{assays}{ \itemize{Currently only contains one assay ("RNA" - scRNA-seq expression data) \item{counts - Raw expression data} \item{data - Normalized expression data} \item{scale.data - Scaled expression data} \item{var.features - names of the current features selected as variable} \item{meta.features - Assay level metadata such as mean and variance} }} \item{meta.data}{Cell level metadata} \item{active.assay}{Current default assay} \item{active.ident}{Current default idents} \item{graphs}{Neighbor graphs computed, currently stores the SNN} \item{reductions}{Dimensional reductions: currently PCA and tSNE} \item{version}{Seurat version used to create the object} \item{commands}{Command history} } } \source{ \url{https://www.10xgenomics.com/datasets/3-k-pbm-cs-from-a-healthy-donor-1-standard-1-1-0} } \usage{ pbmc_small } \description{ A subsetted version of 10X Genomics' 3k PBMC dataset } \keyword{datasets} SeuratObject/man/dot-DollarNames.Assay5.Rd0000644000176200001440000000114215075522101020033 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{.DollarNames.Assay5} \alias{.DollarNames.Assay5} \title{Dollar-sign Autocompletion} \usage{ \method{.DollarNames}{Assay5}(x, pattern = "") } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{pattern}{ A regular expression. Only matching names are returned. } } \value{ The layer name matches for \code{pattern} } \description{ Autocompletion for \code{$} access on an \code{\link{Assay5}} object } \seealso{ \code{\link[utils:.DollarNames]{utils::.DollarNames}} } \concept{assay5} \keyword{internal} SeuratObject/man/colMeans-Assay-method.Rd0000644000176200001440000000270615075522101020006 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{colMeans,Assay-method} \alias{colMeans,Assay-method} \alias{colSums,Assay-method} \alias{rowMeans,Assay-method} \alias{rowSums,Assay-method} \title{Row and Column Sums and Means} \usage{ \S4method{colMeans}{Assay}(x, na.rm = FALSE, dims = 1, ..., slot = "data") \S4method{colSums}{Assay}(x, na.rm = FALSE, dims = 1, ..., slot = "data") \S4method{rowMeans}{Assay}(x, na.rm = FALSE, dims = 1, ..., slot = "data") \S4method{rowSums}{Assay}(x, na.rm = FALSE, dims = 1, ..., slot = "data") } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{na.rm}{logical. Should missing values (including \code{NaN}) be omitted from the calculations?} \item{dims}{completely ignored by the \code{Matrix} methods.} \item{...}{Ignored} \item{slot}{Name of assay expression matrix to calculate column/row means/sums on} } \value{ \code{colMeans}: The column (cell-wise) means of \code{slot} \code{colSums}: The column (cell-wise) sums of \code{slot} \code{rowMeans}: The row (feature-wise) means of \code{slot} \code{rowSums}: The row (feature-wise) sums of \code{slot} } \description{ Calculate \code{\link{rowSums}}, \code{\link{colSums}}, \code{\link{rowMeans}}, and \code{\link{colMeans}} on \code{Assay} objects } \examples{ rna <- pbmc_small[["RNA"]] colMeans(rna) colSums(rna) rowMeans(rna) rowSums(rna) } \seealso{ \code{\link{Assay}} } \concept{assay} \keyword{internal} SeuratObject/man/Embeddings.Rd0000644000176200001440000000153315075522101015747 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/dimreduc.R, R/seurat.R \name{Embeddings} \alias{Embeddings} \alias{Embeddings.DimReduc} \alias{Embeddings.Seurat} \title{Get Cell Embeddings} \usage{ Embeddings(object, ...) \method{Embeddings}{DimReduc}(object, ...) \method{Embeddings}{Seurat}(object, reduction = "pca", ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{reduction}{Name of reduction to pull cell embeddings for} } \value{ The embeddings matrix } \description{ Get Cell Embeddings } \examples{ # Get the embeddings directly from a DimReduc object Embeddings(object = pbmc_small[["pca"]])[1:5, 1:5] # Get the embeddings from a specific DimReduc in a Seurat object Embeddings(object = pbmc_small, reduction = "pca")[1:5, 1:5] } \concept{data-access} SeuratObject/man/CreateAssay5Object.Rd0000644000176200001440000000202115075522101017317 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{CreateAssay5Object} \alias{CreateAssay5Object} \title{Create a v5 Assay object} \usage{ CreateAssay5Object( counts = NULL, data = NULL, min.cells = 0, min.features = 0, csum = NULL, fsum = NULL, ... ) } \arguments{ \item{counts}{A two-dimensional expression matrix} \item{data}{Optional prenormalized data matrix} \item{min.cells}{Include features detected in at least this many cells; will subset the counts matrix as well. To reintroduce excluded features, create a new object with a lower cutoff} \item{min.features}{Include cells where at least this many features are detected} \item{csum}{Function for calculating cell sums} \item{fsum}{Function for calculating feature sums} \item{...}{Arguments passed to other methods} } \value{ An \code{\link{Assay5}} object } \description{ Create an \code{\link{Assay5}} object from a feature expression matrix; the expected format of the matrix is features x cells } \concept{assay} SeuratObject/man/AttachDeps.Rd0000644000176200001440000000156015075522101015726 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{AttachDeps} \alias{AttachDeps} \title{Attach Required Packages} \usage{ AttachDeps(deps) } \arguments{ \item{deps}{A character vector of packages to attach} } \value{ Invisibly returns \code{NULL} } \description{ Helper function to attach required packages. Detects if a package is already attached and if so, skips it. Should be called in \code{\link[base]{.onAttach}} } \section{Lifecycle}{ \Sexpr[stage=build,results=rd]{lifecycle::badge("superseded")} \code{AttachDeps} has been superseded as of \pkg{SeuratObject} v5.0.0; as an alternative, list dependencies in the \code{Depends} section of \code{DESCRIPTION} } \examples{ # Use in your .onAttach hook if (FALSE) { .onAttach <- function(libname, pkgname) { AttachDeps(c("SeuratObject", "rlang")) } } } \concept{utils} SeuratObject/man/as.matrix.LogMap.Rd0000644000176200001440000000152515075522101016773 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{as.matrix.LogMap} \alias{as.matrix.LogMap} \title{Coerce Logical Maps to Matrices} \usage{ \method{as.matrix}{LogMap}(x, ...) } \arguments{ \item{x}{A \code{\link{LogMap}} object} \item{...}{Ignored} } \value{ A base-R matrix created from \code{x} } \description{ Coerce a logical map to a matrix; this removes all \link[=LogMap]{logical map} class capabilities from the object and returns a base-R matrix object } \examples{ map <- LogMap(letters[1:10]) map[['obs']] <- c(1, 3, 7) mat <- as.matrix(map) mat class(mat) } \seealso{ Logical map objects, validity, and interaction methods: \code{\link{LogMap}}, \code{\link{LogMap-validity}}, \code{\link{droplevels.LogMap}()}, \code{\link{intersect.LogMap}()}, \code{\link{labels.LogMap}()} } \concept{logmap} SeuratObject/man/droplevels.LogMap.Rd0000644000176200001440000000150015075522101017235 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{droplevels.LogMap} \alias{droplevels.LogMap} \title{Drop Unused Logical Map Values} \usage{ \method{droplevels}{LogMap}(x, ...) } \arguments{ \item{x}{A \code{LogMap} object} \item{...}{Ignored} } \value{ \code{x} with values not present in any observation removed } \description{ Remove any unused values from a \link[=LogMap]{logical map} } \examples{ map <- LogMap(letters[1:10]) map[['obs']] <- c(1, 3, 7) map[['entry']] <- c(2, 7, 10) # Remove unused values map <- droplevels(map) map map[[]] } \seealso{ Logical map objects, validity, and interaction methods: \code{\link{LogMap}}, \code{\link{LogMap-validity}}, \code{\link{as.matrix.LogMap}()}, \code{\link{intersect.LogMap}()}, \code{\link{labels.LogMap}()} } \concept{logmap} SeuratObject/man/merge.Seurat.Rd0000644000176200001440000000626415075522101016255 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{merge.Seurat} \alias{merge.Seurat} \alias{merge} \alias{MergeSeurat} \alias{AddSamples} \title{Merge Seurat Objects} \usage{ \method{merge}{Seurat}( x = NULL, y = NULL, add.cell.ids = NULL, collapse = FALSE, merge.data = TRUE, merge.dr = FALSE, project = getOption(x = "Seurat.object.project", default = "SeuratProject"), ... ) } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{y}{A single \code{Seurat} object or a list of \code{Seurat} objects} \item{add.cell.ids}{A character vector of \code{length(x = c(x, y))}; appends the corresponding values to the start of each objects' cell names} \item{collapse}{If \code{TRUE}, merge layers of the same name together; if \code{FALSE}, appends \code{labels} to the layer name} \item{merge.data}{Merge the data slots instead of just merging the counts (which requires renormalization); this is recommended if the same normalization approach was applied to all objects} \item{merge.dr}{Choose how to handle merging dimensional reductions: \itemize{ \item \dQuote{\code{TRUE}}: merge dimensional reductions with the same name across objects; dimensional reductions with different names are added as-is \item \dQuote{\code{NA}}: keep dimensional reductions from separate objects separate; will append the project name for duplicate reduction names \item \dQuote{\code{FALSE}}: do not add dimensional reductions }} \item{project}{\link{Project} name for the \code{Seurat} object} \item{...}{Arguments passed to other methods} } \value{ \code{merge}: Merged object } \description{ Merge Seurat Objects } \section{Merge Details}{ When merging Seurat objects, the merge procedure will merge the Assay level counts and potentially the data slots (depending on the merge.data parameter). It will also merge the cell-level meta data that was stored with each object and preserve the cell identities that were active in the objects pre-merge. The merge will optionally merge reductions depending on the values passed to \code{merge.dr} if they have the same name across objects. Here the embeddings slots will be merged and if there are differing numbers of dimensions across objects, only the first N shared dimensions will be merged. The feature loadings slots will be filled by the values present in the first object.The merge will not preserve graphs, logged commands, or feature-level metadata that were present in the original objects. If add.cell.ids isn't specified and any cell names are duplicated, cell names will be appended with _X, where X is the numeric index of the object in c(x, y). } \examples{ # `merge' examples # merge two objects merge(pbmc_small, y = pbmc_small) # to merge more than two objects, pass one to x and a list of objects to y merge(pbmc_small, y = c(pbmc_small, pbmc_small)) } \seealso{ Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{names.Seurat}()}, \code{\link{subset.Seurat}()} } \concept{seurat} SeuratObject/man/aggregate.Rd0000644000176200001440000000427515116320014015635 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fov.R, R/molecules.R \name{aggregate} \alias{aggregate} \alias{aggregate.FOV} \alias{aggregate.Molecules} \title{Aggregate Molecules into an Expression Matrix} \usage{ \method{aggregate}{FOV}(x, by = NULL, set = NULL, drop = TRUE, ...) \method{aggregate}{Molecules}(x, by, drop = TRUE, ...) } \arguments{ \item{x}{An object with spatially-resolved molecule information} \item{by}{Name of a \code{\link[SeuratObject:Segmentation-class]{Segmentation}} within \code{object} or a \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object} \item{set}{Name of molecule set to aggregate} \item{drop}{Drop molecules not present in a segmentation; if \code{FALSE}, adds a column called \dQuote{\code{boundless}} consisting of molecule counts not in a segmentation} \item{...}{Arguments passed to other methods} } \value{ An expression matrix } \description{ Aggregate Molecules into an Expression Matrix } \section{Progress Updates with \pkg{progressr}}{ This function uses \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \section{Parallelization with \pkg{future}}{ This function uses \href{https://cran.r-project.org/package=future}{\pkg{future}} to enable parallelization. Parallelization strategies can be set using \code{\link[future]{plan}}. Common plans include \dQuote{\code{sequential}} for non-parallelized processing or \dQuote{\code{multisession}} for parallel evaluation using multiple \R sessions; for other plans, see the \dQuote{Implemented evaluation strategies} section of \code{\link[future:plan]{?future::plan}}. For a more thorough introduction to \pkg{future}, see \href{https://future.futureverse.org/articles/future-1-overview.html}{\code{vignette("future-1-overview")}} } \concept{future} \keyword{internal} SeuratObject/man/Theta.Rd0000644000176200001440000000040715075522101014752 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{Theta} \alias{Theta} \title{Get the offset angle} \usage{ Theta(object) } \arguments{ \item{object}{An object} } \description{ Get the offset angle } \concept{spatial} SeuratObject/man/sub-.StdAssay.Rd0000644000176200001440000000221015075522101016277 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{[.StdAssay} \alias{[.StdAssay} \alias{[<-,StdAssay,character,ANY,ANY-method} \title{Layer Data} \usage{ \method{[}{StdAssay}(x, i = missing_arg(), j = missing_arg(), ...) \S4method{[}{StdAssay,character,ANY,ANY}(x, i, j, ...) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{i}{Name of layer data to get or set} \item{j}{Ignored} \item{...}{Arguments passed to \code{\link{LayerData}}} \item{value}{A matrix-like object to add as a new layer} } \value{ \code{[}: The layer data for layer \code{i} \code{[<-}: \code{x} with layer data \code{value} saved as \code{i} } \description{ Get and set layer data } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/CheckDots.Rd0000644000176200001440000000250415075522101015554 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{CheckDots} \alias{CheckDots} \title{Check the Use of Dots} \usage{ CheckDots(..., fxns = NULL) } \arguments{ \item{...}{Arguments passed to a function that fall under \code{...}} \item{fxns}{A list/vector of functions or function names} } \value{ Emits either an error or warning if an argument passed is unused; invisibly returns \code{NULL} } \description{ Function to check the use of unused arguments passed to \code{...}; this function is designed to be called from another function to see if an argument passed to \code{...} remains unused and alert the user if so. Also accepts a vector of function or function names to see if \code{...} can be used in a downstream function } \details{ Behavior of \code{CheckDots} can be controlled by the following option(s): \describe{ \item{\dQuote{\code{Seurat.checkdots}}}{Control how to alert the presence of unused arguments in \code{...}; choose from \itemize{ \item \dQuote{\code{warn}}: emit a warning (default) \item \dQuote{\code{error}}: throw an error \item \dQuote{\code{silent}}: no not alert the presence of unused arguments in \code{...} } } } } \examples{ \dontrun{ f <- function(x, ...) { CheckDots(...) return(x ^ 2) } f(x = 3, y = 9) } } \concept{utils} \keyword{internal} SeuratObject/man/Assay5T-class.Rd0000644000176200001440000000377315075522101016312 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \docType{class} \name{Assay5T-class} \alias{Assay5T-class} \alias{Assay5T} \title{The Transposed v5 \code{Assay} Object} \description{ The Transposed v5 \code{Assay} Object } \section{Slots}{ \describe{ \item{\code{layers}}{A named list containing expression matrices; each matrix should be a two-dimensional object containing some subset of cells and features defined in the \code{cells} and \code{features} slots. Cell and feature membership is recorded in the \code{cells} and \code{features} slots, respectively} \item{\code{cells}}{A \link[=LogMap]{logical mapping} of cell names and layer membership; this map contains all the possible cells that this assay can contain. New layers must have some subset of cells present in this map} \item{\code{features}}{A \link[=LogMap]{logical mapping} of feature names and layer membership; this map contains all the possible features that this assay can contain. New layers must have some subset of features present in this map} \item{\code{default}}{A one-length integer with the end index of the \link[=DefaultLayer]{default layer}; the default layer be all layers up to and including the layer at index \code{default}} \item{\code{assay.orig}}{Original assay that this assay is based off of; used to track assay provenance} \item{\code{meta.data}}{A \link[base:data.frame]{data frame} with feature-level meta data; should have the same number of rows as \code{features}} \item{\code{misc}}{A named list of unstructured miscellaneous data} \item{\code{key}}{A one-length character vector with the object's key; keys must be one or more alphanumeric characters followed by an underscore \dQuote{\code{_}} (regex pattern \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}})} }} \section{Lifecycle}{ \Sexpr[stage=build,results=rd]{lifecycle::badge("experimental")} \strong{Warning}: functionality described here is experimental and prone to change without notice } \keyword{internal} SeuratObject/man/merge.Assay.Rd0000644000176200001440000000237315075522101016067 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{merge.Assay} \alias{merge.Assay} \title{Merge Assays} \usage{ \method{merge}{Assay}( x = NULL, y = NULL, add.cell.ids = NULL, merge.data = TRUE, labels = NULL, collapse = TRUE, ... ) } \arguments{ \item{x}{An \code{\link{Assay}} object} \item{y}{One or more \code{\link{Assay}} objects} \item{add.cell.ids}{A character vector of \code{length(x = c(x, y))}; appends the corresponding values to the start of each objects' cell names} \item{merge.data}{Merge the data slots instead of just merging the counts (which requires renormalization); this is recommended if the same normalization approach was applied to all objects} \item{labels, collapse}{Currently unused} \item{...}{Ignored} } \value{ A new assay with data merged from \code{c(x, y)} } \description{ Merge one or more v3 assays together } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dim.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/dimnames.Assay5.Rd0000644000176200001440000000225715075522101016653 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{dimnames.Assay5} \alias{dimnames.Assay5} \alias{dimnames<-.Assay5} \title{Assay-Level Feature and Cell Names} \usage{ \method{dimnames}{Assay5}(x) \method{dimnames}{Assay5}(x) <- value } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{value}{A two-length list with updated feature and/or cells names} } \value{ \code{dimnames}: A two-length list with the following values: \itemize{ \item A character vector with all features in \code{x} \item A character vector with all cells in \code{x} } \code{dimnames<-}: \code{x} with the feature and/or cell names updated to \code{value} } \description{ Get and set feature and cell names in v5 Assays } \seealso{ v5 Assay object, validity, and interaction methods: \code{\link{$.Assay5}()}, \code{\link{Assay5-class}}, \code{\link{Assay5-validity}}, \code{\link{[.Assay5}()}, \code{\link{[[.Assay5}()}, \code{\link{dim.Assay5}()}, \code{\link{merge.Assay5}()}, \code{\link{split.Assay5}()}, \code{\link{subset.Assay5}()} \code{\link{Cells}()}, \code{\link{dimnames.Assay}()}, \code{\link{dimnames.Seurat}()} } \concept{assay5} \concept{dimnames} SeuratObject/man/RenameAssays.Rd0000644000176200001440000000127515075522101016304 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{RenameAssays} \alias{RenameAssays} \title{Rename assays in a \code{Seurat} object} \usage{ RenameAssays( object, assay.name = NULL, new.assay.name = NULL, verbose = TRUE, ... ) } \arguments{ \item{object}{A \code{Seurat} object} \item{assay.name}{original name of assay} \item{new.assay.name}{new name of assay} \item{verbose}{Whether to print messages} \item{...}{Named arguments as \code{old.assay = new.assay}} } \value{ \code{object} with assays renamed } \description{ Rename assays in a \code{Seurat} object } \examples{ RenameAssays(object = pbmc_small, RNA = 'rna') } \concept{seurat} SeuratObject/man/Indices.Rd0000644000176200001440000000077215075522101015270 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/neighbor.R \name{Indices} \alias{Indices} \alias{Indices.Neighbor} \title{Get Neighbor nearest neighbor index matrices} \usage{ Indices(object, ...) \method{Indices}{Neighbor}(object, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} } \value{ A matrix with the nearest neighbor indices } \description{ Get Neighbor nearest neighbor index matrices } \concept{data-access} SeuratObject/man/UpdateSlots.Rd0000644000176200001440000000054115075522101016153 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{UpdateSlots} \alias{UpdateSlots} \title{Update slots in an object} \usage{ UpdateSlots(object) } \arguments{ \item{object}{An object to update} } \value{ \code{object} with the latest slot definitions } \description{ Update slots in an object } \concept{utils} SeuratObject/man/subset.StdAssay.Rd0000644000176200001440000000201515075522101016741 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{subset.StdAssay} \alias{subset.StdAssay} \title{Subset an Assay} \usage{ \method{subset}{StdAssay}(x, cells = NULL, features = NULL, layers = NULL, ...) } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{cells}{Cell names} \item{features}{Feature names} \item{layers}{Layer to keep; defaults to all layers} \item{...}{Ignored} } \value{ \code{x} with just the cells and features specified by \code{cells} and \code{features} for the layers specified by \code{layers} } \description{ Subset an Assay } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/dim.Assay.Rd0000644000176200001440000000143115075522101015533 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay.R \name{dim.Assay} \alias{dim.Assay} \title{Feature and Cell Numbers} \usage{ \method{dim}{Assay}(x) } \arguments{ \item{x}{An \code{\link{Assay}} object} } \value{ A two-length numeric vector with the total number of features and cells in \code{x} } \description{ Feature and Cell Numbers } \examples{ rna <- pbmc_small[["RNA"]] dim(rna) } \seealso{ v3 Assay object, validity, and interaction methods: \code{\link{$.Assay}()}, \code{\link{Assay-class}}, \code{\link{Assay-validity}}, \code{\link{CreateAssayObject}()}, \code{\link{[.Assay}()}, \code{\link{[[.Assay}()}, \code{\link{dimnames.Assay}()}, \code{\link{merge.Assay}()}, \code{\link{split.Assay}()}, \code{\link{subset.Assay}()} } \concept{assay} SeuratObject/man/dot-KeyPattern.Rd0000644000176200001440000000071315075522101016557 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/keymixin.R \name{.KeyPattern} \alias{.KeyPattern} \title{Regex Pattern for Keys} \usage{ .KeyPattern() } \value{ Returns the regex pattern for keys (\dQuote{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}) } \description{ Regex Pattern for Keys } \seealso{ \code{\link{.RandomKey}()}, \code{\link{Key-validity}}, \code{\link{KeyMixin-class}} } \concept{key} \keyword{internal} SeuratObject/man/Misc-StdAssay.Rd0000644000176200001440000000117115075522101016330 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{Misc-StdAssay} \alias{Misc-StdAssay} \alias{Misc.StdAssay} \alias{Misc<-.StdAssay} \title{Get and set miscellaneous data} \usage{ \method{Misc}{StdAssay}(object, slot = NULL, ...) \method{Misc}{StdAssay}(object, slot, ...) <- value } \arguments{ \item{object}{An object} \item{slot}{Name of specific bit of meta data to pull} \item{...}{Arguments passed to other methods} \item{value}{Data to add} } \value{ Miscellaneous data An object with miscellaneous data added } \description{ Get and set miscellaneous data } \keyword{internal} SeuratObject/man/Distances.Rd0000644000176200001440000000077115075522101015626 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/neighbor.R \name{Distances} \alias{Distances} \alias{Distances.Neighbor} \title{Get the Neighbor nearest neighbors distance matrix} \usage{ Distances(object, ...) \method{Distances}{Neighbor}(object, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} } \value{ The distance matrix } \description{ Get the Neighbor nearest neighbors distance matrix } \concept{data-access} SeuratObject/man/EmptyMatrix.Rd0000644000176200001440000000257515075522101016200 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{EmptyMatrix} \alias{EmptyMatrix} \title{Empty Matrices} \usage{ EmptyMatrix(repr = "C", type = "d") } \arguments{ \item{repr}{Representation of empty matrix; choose from: \itemize{ \item \dQuote{\code{C}} for a \code{\link[Matrix:CsparseMatrix-class]{CsparseMatrix}} \item \dQuote{\code{T}} for a \code{\link[Matrix:TsparseMatrix-class]{TsparseMatrix}} \item \dQuote{\code{R}} for an \code{\link[Matrix:RsparseMatrix-class]{RsparseMatrix}} \item \dQuote{\code{e}} for an \code{\link[Matrix:unpackedMatrix-class]{unpackedMatrix}} \item \dQuote{\code{d}} for a dense S3 \code{\link[base]{matrix}} \item \dQuote{\code{spam}} for a \code{\link[spam]{spam}} matrix }} \item{type}{Type of resulting matrix to return, choose from: \itemize{ \item \dQuote{\code{d}} for numeric matrices \item \dQuote{\code{l}} for logical matrices \item \dQuote{\code{n}} for pattern matrices } Note, when \code{repr} is \dQuote{\code{spam}}, \code{type} must be \dQuote{\code{d}}; when \code{repr} is \dQuote{\code{d}}, setting \code{type} to \dQuote{\code{n}} returns a logical matrix} } \value{ A 0x0 matrix of the specified representation and type } \description{ Create empty 0x0 matrices of varying types } \examples{ EmptyMatrix() EmptyMatrix("spam") } \seealso{ \code{\link{IsMatrixEmpty}()} } \concept{utils} SeuratObject/man/Simplify.Rd0000644000176200001440000000143015075522101015476 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{Simplify} \alias{Simplify} \alias{Simplify.Spatial} \title{Simplify Geometry} \usage{ Simplify(coords, tol, topologyPreserve = TRUE) \method{Simplify}{Spatial}(coords, tol, topologyPreserve = TRUE) } \arguments{ \item{coords}{A `Segmentation` object} \item{tol}{Numerical tolerance value to be used by the Douglas-Peuker algorithm} \item{topologyPreserve}{Logical determining if the algorithm should attempt to preserve the topology of the original geometry} } \value{ A simplified version of \code{coords} A `Segmentation` object with simplified segmentation vertices } \description{ Simplify Geometry Simplify segmentations by reducing the number of vertices } \concept{spatial} SeuratObject/man/LogMap-validity.Rd0000644000176200001440000000206515075522101016711 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{LogMap-validity} \alias{LogMap-validity} \title{Logical Map Validity} \description{ Validation of \code{LogMap} objects is handled by \code{\link[methods]{validObject}} } \section{Data Validation}{ Logical maps must be a logical matrix containing only TRUE or FALSE values } \section{Value Validation}{ All values must be named within the rownames of the object. Duplicate or empty (\code{""}) values are not allowed } \section{Observation Validation}{ All observations must be named within the column names of the object. Duplicate or empty (\code{""}) observations are not allowed } \examples{ map <- LogMap(letters[1:10]) map[['obs']] <- c(1, 3, 7) map[['entry']] <- c(2, 7, 10) validObject(map) } \seealso{ \code{\link[methods]{validObject}} Logical map objects, validity, and interaction methods: \code{\link{LogMap}}, \code{\link{as.matrix.LogMap}()}, \code{\link{droplevels.LogMap}()}, \code{\link{intersect.LogMap}()}, \code{\link{labels.LogMap}()} } \concept{logmap} SeuratObject/man/roxygen/0000755000176200001440000000000015075522101015110 5ustar liggesusersSeuratObject/man/roxygen/templates/0000755000176200001440000000000015116320014017101 5ustar liggesusersSeuratObject/man/roxygen/templates/param-verbose.R0000644000176200001440000000005015075522101021767 0ustar liggesusers#' @param verbose Show progress updates SeuratObject/man/roxygen/templates/note-reqdpkg.R0000644000176200001440000000021115075522101021623 0ustar liggesusers#' @note This function requires the #' \href{https://cran.r-project.org/package=<%= pkg %>}{\pkg{<%= pkg %>}} package #' to be installed SeuratObject/man/roxygen/templates/method-cells.R0000644000176200001440000000013415075522101021607 0ustar liggesusers#' @details \code{Cells}: Get cell names #' #' @return \code{Cells}: A vector of cell names SeuratObject/man/roxygen/templates/section-future.R0000644000176200001440000000132715075522101022210 0ustar liggesusers#' @section Parallelization with \pkg{future}: #' This function uses #' \href{https://cran.r-project.org/package=future}{\pkg{future}} to enable #' parallelization. Parallelization strategies can be set using #' \code{\link[future]{plan}}. Common plans include \dQuote{\code{sequential}} #' for non-parallelized processing or \dQuote{\code{multisession}} for parallel #' evaluation using multiple \R sessions; for other plans, see the #' \dQuote{Implemented evaluation strategies} section of #' \code{\link[future:plan]{?future::plan}}. For a more thorough introduction #' to \pkg{future}, see #' \href{https://future.futureverse.org/articles/future-1-overview.html}{\code{vignette("future-1-overview")}} #' #' @concept future SeuratObject/man/roxygen/templates/method-lengths.R0000644000176200001440000000030115075522101022145 0ustar liggesusers#' @param use.names Ignored #' #' @details \code{lengths}: Generate a run-length encoding of the cells present #' #' @return \code{lengths}: An \code{\link[base:rle]{rle}} object for the cells SeuratObject/man/roxygen/templates/method-stdassay.R0000644000176200001440000000030715075522101022342 0ustar liggesusers#' @inherit <%= fxn %> params return title description details sections #' references author source #' @name <%= fxn %>-StdAssay #' @rdname <%= fxn %>-StdAssay #' #' @keywords internal #' #' @export SeuratObject/man/roxygen/templates/method-show.R0000644000176200001440000000016615075522101021472 0ustar liggesusers#' @details \code{show}: Display an object summary to stdout #' #' @return \code{show}: Invisibly returns \code{NULL} SeuratObject/man/roxygen/templates/return-null.R0000644000176200001440000000005115075522101021514 0ustar liggesusers#' @return Invisibly returns \code{NULL} SeuratObject/man/roxygen/templates/name-oldv.R0000644000176200001440000000047115075522101021115 0ustar liggesusers#' @name <%= fname %>-v<%= as.integer(version) %> #' @rdname <%= fname %>-v<%= as.integer(version) %> #' #' @note This is the documentation for \code{<%= fname %>} for #' v<%= as.integer(version) %>; for the latest documentation, please see #' \code{\link{<%= fname %>}} #' #' @seealso \code{\link{<%= fname %>}} SeuratObject/man/roxygen/templates/slot-key.R0000644000176200001440000000037215075522101021002 0ustar liggesusers#' @slot key A one-length character vector with the object's key; keys must #' be one or more alphanumeric characters followed by an underscore #' \dQuote{\code{_}} (regex pattern #' \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}}) SeuratObject/man/roxygen/templates/lifecycle-superseded.R0000644000176200001440000000013415075522101023327 0ustar liggesusers#' @section Lifecycle: #' #' \Sexpr[stage=build,results=rd]{lifecycle::badge("superseded")} SeuratObject/man/roxygen/templates/param-dots-ignored.R0000644000176200001440000000002615075522101022723 0ustar liggesusers#' @param ... Ignored SeuratObject/man/roxygen/templates/desc-validity.R0000644000176200001440000000015415075522101021772 0ustar liggesusers#' @description Validation of \code{<%= cls %>} objects is handled by #' \code{\link[methods]{validObject}} SeuratObject/man/roxygen/templates/section-progressr.R0000644000176200001440000000105215116320014022712 0ustar liggesusers#' @section Progress Updates with \pkg{progressr}: #' This function uses #' \href{https://cran.r-project.org/package=progressr}{\pkg{progressr}} to #' render status updates and progress bars. To enable progress updates, wrap #' the function call in \code{\link[progressr]{with_progress}} or run #' \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running #' this function. For more details about \pkg{progressr}, please read #' \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} SeuratObject/man/roxygen/templates/slot-misc.R0000644000176200001440000000007615075522101021146 0ustar liggesusers#' @slot misc A named list of unstructured miscellaneous data SeuratObject/man/roxygen/templates/lifecycle-deprecated.R0000644000176200001440000000043615075522101023271 0ustar liggesusers#' @section Lifecycle: #' #' \Sexpr[stage=build,results=rd]{lifecycle::badge("deprecated")} #' #' \code{<%= fxn %>} <%= if (exists("ver")) paste("was deprecated in version", ver) else "has been deprecated" %><%= if (exists("repl")) paste0("; use \\code{\\link{", repl, "}} instead") %> SeuratObject/man/roxygen/templates/param-dots-method.R0000644000176200001440000000006015075522101022552 0ustar liggesusers#' @param ... Arguments passed to other methods SeuratObject/man/roxygen/templates/return-show.R0000644000176200001440000000013515075522101021525 0ustar liggesusers#' @return Prints summary to \code{\link[base]{stdout}} and invisibly #' returns \code{NULL} SeuratObject/man/roxygen/templates/slot-stdassay.R0000644000176200001440000000230715075522101022045 0ustar liggesusers#' @slot layers A named list containing expression matrices; each matrix should #' be a two-dimensional object containing some subset of cells and features #' defined in the \code{cells} and \code{features} slots. Cell and feature #' membership is recorded in the \code{cells} and \code{features} slots, #' respectively #' @slot cells A \link[=LogMap]{logical mapping} of cell names #' and layer membership; this map contains all the possible cells that this #' assay can contain. New layers must have some subset of cells present #' in this map #' @slot features A \link[=LogMap]{logical mapping} of feature #' names and layer membership; this map contains all the possible features that #' this assay can contain. New layers must have some subset of features #' present in this map #' @slot default A one-length integer with the end index of the #' \link[=DefaultLayer]{default layer}; the default layer be #' all layers up to and including the layer at index \code{default} #' @slot assay.orig Original assay that this assay is based off of; #' used to track assay provenance #' @slot meta.data A \link[base:data.frame]{data frame} with feature-level #' meta data; should have the same number of rows as \code{features} SeuratObject/man/roxygen/templates/seealso-methods.R0000644000176200001440000000011015075522101022315 0ustar liggesusers#' @seealso \code{<%= cls %>} methods: \code{\link{<%= cls %>-methods}} SeuratObject/man/roxygen/templates/method-features.R0000644000176200001440000000031515075522101022324 0ustar liggesusers#' @details \code{Features}: Get spatially-resolved molecule names #' #' @return \code{Features}: A vector of spatially-resolved molecule names; #' if no molecular information present, returns \code{NULL} SeuratObject/man/roxygen/templates/lifecycle-experimental.R0000644000176200001440000000031115075522101023656 0ustar liggesusers#' @section Lifecycle: #' #' \Sexpr[stage=build,results=rd]{lifecycle::badge("experimental")} #' #' \strong{Warning}: functionality described here is experimental and prone to #' change without notice SeuratObject/man/roxygen/meta.R0000644000176200001440000000127215075522101016163 0ustar liggesuserslist( rd_family_title = list( angles = "", assay = "v3 Assay object, validity, and interaction methods:", assay5 = "v5 Assay object, validity, and interaction methods:", command = "Command log object and interaction methods", dimnames = "", dimreduc = "Dimensional reduction object, validity, and interaction methods", fov = "", key = "", logmap = "Logical map objects, validity, and interaction methods:", s4list = "", segmentation = "Segmentation layer classes:", seurat = "Seurat object, validity, and interaction methods", sparse = "", stdassay = "v5 Standard Assay object, validity, and interaction methods", subobjects = "" ) ) SeuratObject/man/dot-BPMatrixMode.Rd0000644000176200001440000000136515075522101016770 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.BPMatrixMode} \alias{.BPMatrixMode} \title{\pkg{BPCells} Matrix Mode} \usage{ .BPMatrixMode(object, simplify = FALSE) } \arguments{ \item{object}{An \code{IterableMatrix}} \item{simplify}{Return \dQuote{\code{disk}} for on-disk matrices} } \value{ One of the following, depending on the mode of \code{object}: \itemize{ \item \dQuote{\code{memory}} \item \dQuote{\code{file}} \item \dQuote{\code{directory}} } If \code{simplify} is \code{TRUE}, returns \dQuote{\code{disk}} instead of \dQuote{\code{file}} or \dQuote{\code{directory}} } \description{ Get the mode (on-disk, in-memory) of an \code{IterableMatrix} object from \pkg{BPCells} } \keyword{internal} SeuratObject/man/ClassKey.Rd0000644000176200001440000000122715075522101015424 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{ClassKey} \alias{ClassKey} \title{Generate a Class Key} \usage{ ClassKey(class, package = NULL) } \arguments{ \item{class}{Class name} \item{package}{Optional name of package; by default, will search namespaces of loaded packages to determine the providing package} } \value{ The class key (\dQuote{\code{package:class}}) } \description{ Generate class keys for S4 classes. A class key follows the following structure: \dQuote{\code{package:class}} } \examples{ ClassKey("Seurat") } \seealso{ \code{\link{s4list}} } \concept{s4list} \concept{utils} \keyword{internal} SeuratObject/man/CreateCentroids.Rd0000644000176200001440000000132715075522101016765 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R \name{CreateCentroids} \alias{CreateCentroids} \title{Create a \code{\link[SeuratObject:Centroids-class]{Centroids}} Objects} \usage{ CreateCentroids(coords, nsides, radius, theta) } \arguments{ \item{coords}{The coordinates of cell/spot centroids} \item{nsides}{The number of sides to represent cells/spots; pass \code{\link[base]{Inf}} to plot as circles} \item{radius}{Radius of shapes when plotting} \item{theta}{Angle to adjust shapes when plotting} } \value{ A \code{\link[SeuratObject:Centroids-class]{Centroids}} object } \description{ Create a \code{\link[SeuratObject:Centroids-class]{Centroids}} Objects } \concept{spatial} SeuratObject/man/sub-LogMap-method.Rd0000644000176200001440000000370515116320014017130 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logmap.R \name{[,LogMap} \alias{[,LogMap} \alias{[,LogMap,missing,missing,ANY-method} \alias{[,LogMap,character,character,ANY-method} \alias{[,LogMap,character,missing,ANY-method} \alias{[,LogMap,missing,character,ANY-method} \alias{[,LogMap,numeric,missing,ANY-method} \alias{[,LogMap,missing,numeric,ANY-method} \alias{[,LogMap,numeric,numeric,ANY-method} \title{Matrix-like Subsetting for \link[=LogMap]{Logical Maps}} \usage{ \S4method{[}{LogMap,missing,missing,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{LogMap,character,character,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{LogMap,character,missing,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{LogMap,missing,character,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{LogMap,numeric,missing,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{LogMap,missing,numeric,ANY}(x, i, j, ..., drop = FALSE) \S4method{[}{LogMap,numeric,numeric,ANY}(x, i, j, ..., drop = FALSE) } \arguments{ \item{x}{A \code{LogMap} object} \item{i, j}{Vectors of values (\code{i}) and observations (\code{j}) to pull from \code{x}} \item{...}{Arguments passed to other methods} \item{drop}{For matrices and arrays. If \code{TRUE} the result is coerced to the lowest possible dimension (see the examples). This only works for extracting elements, not for the replacement. See \code{\link[base]{drop}} for further details. } } \description{ Matrix-like Subsetting for \link[=LogMap]{Logical Maps} } \note{ \code{i} is not reordable; passing a different order for \code{i} will return a subset with rows in the same order as \code{x} } \examples{ map <- LogMap(letters[1:10]) map[['obs']] <- c(1, 3, 7) map[['entry']] <- c(2, 7, 10) map[] map[1:5, 2L] map[c("b", "c", "f"), "obs"] # Pass `drop = TRUE` to cast to `matrix` map[1:3, , drop = TRUE] # Note that `i` is non-reordable rownames(map)[1:3] map[c("b", "c", "a"), , drop = TRUE] } \keyword{internal} SeuratObject/man/SeuratCommand-class.Rd0000644000176200001440000000170515075522101017554 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/command.R \docType{class} \name{SeuratCommand-class} \alias{SeuratCommand-class} \alias{SeuratCommand} \title{The \code{SeuratCommand} Class} \description{ The \code{SeuratCommand} is used for logging commands that are run on a \code{Seurat} object; it stores parameters and timestamps } \section{Slots}{ \describe{ \item{\code{name}}{Command name} \item{\code{time.stamp}}{Timestamp of when command was tun} \item{\code{assay.used}}{Optional name of assay used to generate \code{SeuratCommand} object} \item{\code{call.string}}{String of the command call} \item{\code{params}}{List of parameters used in the command call} }} \seealso{ Command log object and interaction methods \code{\link{$.SeuratCommand}()}, \code{\link{.DollarNames.SeuratCommand}()}, \code{\link{LogSeuratCommand}()}, \code{\link{[.SeuratCommand}()}, \code{\link{as.list.SeuratCommand}()} } \concept{command} SeuratObject/man/dot-AssayClass.Rd0000644000176200001440000000077415075522101016546 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/default.R, R/utils.R \name{.AssayClass} \alias{.AssayClass} \alias{.AssayClass.StdAssay} \alias{.AssayClass.default} \title{Assay Class Label} \usage{ .AssayClass(object) \method{.AssayClass}{StdAssay}(object) \method{.AssayClass}{default}(object) } \arguments{ \item{object}{A \code{\link{StdAssay}} object} } \value{ The assay class label for \code{object} } \description{ Assay Class Label } \keyword{internal} SeuratObject/man/SeuratObject-package.Rd0000644000176200001440000000562415114353666017712 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/zzz.R \docType{package} \name{SeuratObject-package} \alias{SeuratObject} \alias{SeuratObject-package} \title{SeuratObject: Data Structures for Single Cell Data} \description{ Defines S4 classes for single-cell genomic data and associated information, such as dimensionality reduction embeddings, nearest-neighbor graphs, and spatially-resolved coordinates. Provides data access methods and R-native hooks to ensure the Seurat object is familiar to other R users. See Satija R, Farrell J, Gennert D, et al (2015) \doi{10.1038/nbt.3192}, Macosko E, Basu A, Satija R, et al (2015) \doi{10.1016/j.cell.2015.05.002}, and Stuart T, Butler A, et al (2019) \doi{10.1016/j.cell.2019.05.031}, Hao Y, Hao S, et al (2021) \doi{10.1016/j.cell.2021.04.048} and Hao Y, et al (2023) \doi{10.1101/2022.02.24.481684} for more details. } \seealso{ Useful links: \itemize{ \item \url{https://satijalab.github.io/seurat-object/} \item \url{https://github.com/satijalab/seurat-object} \item Report bugs at \url{https://github.com/satijalab/seurat-object/issues} } } \author{ \strong{Maintainer}: Rahul Satija \email{seurat@nygenome.org} (\href{https://orcid.org/0000-0001-9448-8833}{ORCID}) Authors: \itemize{ \item Paul Hoffman \email{hoff0792@alumni.umn.edu} (\href{https://orcid.org/0000-0002-7693-8957}{ORCID}) \item David Collins \email{dcollins@nygenome.org} (\href{https://orcid.org/0000-0001-9243-7821}{ORCID}) \item Yuhan Hao \email{yhao@nygenome.org} (\href{https://orcid.org/0000-0002-1810-0822}{ORCID}) \item Austin Hartman \email{ahartman@nygenome.org} (\href{https://orcid.org/0000-0001-7278-1852}{ORCID}) \item Gesmira Molla \email{gmolla@nygenome.org} (\href{https://orcid.org/0000-0002-8628-5056}{ORCID}) \item Andrew Butler \email{abutler@nygenome.org} (\href{https://orcid.org/0000-0003-3608-0463}{ORCID}) \item Tim Stuart \email{tstuart@nygenome.org} (\href{https://orcid.org/0000-0002-3044-0897}{ORCID}) } Other contributors: \itemize{ \item Madeline Kowalski \email{mkowalski@nygenome.org} (\href{https://orcid.org/0000-0002-5655-7620}{ORCID}) [contributor] \item Saket Choudhary \email{schoudhary@nygenome.org} (\href{https://orcid.org/0000-0001-5202-7633}{ORCID}) [contributor] \item Skylar Li \email{sli@nygenome.org} [contributor] \item Longda Jiang \email{ljiang@nygenome.org} (\href{https://orcid.org/0000-0003-4964-6497}{ORCID}) [contributor] \item Anagha Shenoy \email{ashenoy@nygenome.org} (\href{https://orcid.org/0000-0002-0537-6862}{ORCID}) [contributor] \item Jeff Farrell \email{jfarrell@g.harvard.edu} [contributor] \item Shiwei Zheng \email{szheng@nygenome.org} (\href{https://orcid.org/0000-0001-6682-6743}{ORCID}) [contributor] \item Christoph Hafemeister \email{chafemeister@nygenome.org} (\href{https://orcid.org/0000-0001-6365-8254}{ORCID}) [contributor] \item Patrick Roelli \email{proelli@nygenome.org} [contributor] } } SeuratObject/man/as.Centroids.Rd0000644000176200001440000000202315075522101016235 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{as.Centroids} \alias{as.Centroids} \alias{as.Segmentation} \alias{as.Centroids.Segmentation} \alias{as.Segmentation.Centroids} \title{Convert Segmentation Layers} \usage{ as.Centroids(x, nsides = NULL, radius = NULL, theta = NULL, ...) as.Segmentation(x, ...) \method{as.Centroids}{Segmentation}(x, nsides = NULL, radius = NULL, theta = NULL, ...) \method{as.Segmentation}{Centroids}(x, ...) } \arguments{ \item{x}{An object} \item{nsides}{The number of sides to represent cells/spots; pass \code{\link[base]{Inf}} to plot as circles} \item{radius}{Radius of shapes when plotting} \item{theta}{Angle to adjust shapes when plotting} \item{...}{Arguments passed to other methods} } \value{ \code{as.Centroids}: A \code{\link[SeuratObject:Centroids-class]{Centroids}} object \code{as.Segmentation}: A \code{\link[SeuratObject:Segmentation-class]{Segmentation}} object } \description{ Convert Segmentation Layers } \concept{spatial} SeuratObject/man/Key.Rd0000644000176200001440000000272615075522101014443 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/assay.R, R/assay5.R, % R/dimreduc.R, R/seurat.R \name{Key} \alias{Key} \alias{Keys} \alias{Key<-} \alias{Key.Assay} \alias{Key<-.Assay} \alias{Key.Assay5} \alias{Key<-.Assay5} \alias{Key.DimReduc} \alias{Key<-.DimReduc} \alias{Key.Seurat} \alias{Keys.Seurat} \title{Get and set object keys} \usage{ Key(object, ...) Keys(object, ...) Key(object, ...) <- value \method{Key}{Assay}(object, ...) \method{Key}{Assay}(object, ...) <- value \method{Key}{Assay5}(object, ...) \method{Key}{Assay5}(object, ...) <- value \method{Key}{DimReduc}(object, ...) \method{Key}{DimReduc}(object, ...) <- value \method{Key}{Seurat}(object, ...) \method{Keys}{Seurat}(object, ...) } \arguments{ \item{object}{An object} \item{...}{Arguments passed to other methods} \item{value}{Key value} } \value{ \code{Key}: the object key \code{Keys}: a named vector of keys of sub-objects \code{Key<-}: \code{object} with an updated key } \description{ Get and set object keys } \examples{ # Get an Assay key Key(pbmc_small[["RNA"]]) # Set the key for an Assay Key(pbmc_small[["RNA"]]) <- "newkey_" Key(pbmc_small[["RNA"]]) # Get a DimReduc key Key(object = pbmc_small[["pca"]]) # Set the key for DimReduc Key(object = pbmc_small[["pca"]]) <- "newkey2_" Key(object = pbmc_small[["pca"]]) # Show all keys associated with a Seurat object Key(object = pbmc_small) Keys(object = pbmc_small) } \concept{data-access} SeuratObject/man/s4list.Rd0000644000176200001440000000352315075522101015131 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{s4list} \alias{s4list} \alias{S4ToList} \alias{IsS4List} \alias{ListToS4} \alias{S4ToList.default} \alias{S4ToList.list} \title{S4/List Conversion} \usage{ S4ToList(object) IsS4List(x) ListToS4(x) \method{S4ToList}{default}(object) \method{S4ToList}{list}(object) } \arguments{ \item{object}{An S4 object} \item{x}{A list with an S4 class definition (\dQuote{\code{classDef}}) attribute} } \value{ \code{S4ToList}: A list with an S4 class definition attribute \code{IsS4List}: \code{TRUE} if \code{x} is a list with an S4 class definition attribute \code{ListToS4}: An S4 object as defined by the S4 class definition attribute } \description{ Convert S4 objects to lists and vice versa. Useful for declassing an S4 object while keeping track of it's class using attributes (see section \strong{S4 Class Definition Attributes} below for more details). Both \code{ListToS4} and \code{S4ToList} are recursive functions, affecting all lists/S4 objects contained as sub-lists/sub-objects } \section{S4 Class Definition Attributes}{ S4 classes are scoped to the package and class name. In order to properly track which class a list is generated from in order to build a new one, these function use an \code{\link[base:attr]{attribute}} to denote the class name and package of origin. This attribute is stored as 1-length character vector named \dQuote{\code{classDef}} and takes the form of \dQuote{\code{package:class}} } \examples{ # Turn an S4 object into a list pbmc.list <- S4ToList(pbmc_small) class(pbmc.list) attributes(pbmc.list) str(pbmc.list$reductions) IsS4List(pbmc.list) pbmc2 <- ListToS4(pbmc.list) pbmc2 class(pbmc2) Reductions(pbmc2) validObject(pbmc2) } \seealso{ \code{\link{ClassKey}()} } \concept{s4list} \concept{utils} \keyword{internal} SeuratObject/man/dot-DollarNames.StdAssay.Rd0000644000176200001440000000165115075522101020426 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{.DollarNames.StdAssay} \alias{.DollarNames.StdAssay} \title{Dollar-sign Autocompletion} \usage{ \method{.DollarNames}{StdAssay}(x, pattern = "") } \arguments{ \item{x}{An \code{\link{Assay5}} object} \item{pattern}{ A regular expression. Only matching names are returned. } } \value{ The layer name matches for \code{pattern} } \description{ Autocompletion for \code{$} access on an \code{\link{Assay5}} object } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{show,StdAssay-method}}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/FOV-validity.Rd0000644000176200001440000000060115075522101016156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/fov.R \name{FOV-validity} \alias{FOV-validity} \title{FOV Validity} \description{ Validation of \code{FOV} objects is handled by \code{\link[methods]{validObject}} } \section{Boundary Validation}{ blah } \section{Molecule Validation}{ blah } \seealso{ \code{\link[methods]{validObject}} } \concept{fov} SeuratObject/man/subset.Seurat.Rd0000644000176200001440000000335615075522101016462 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seurat.R \name{subset.Seurat} \alias{subset.Seurat} \alias{subset} \alias{[.Seurat} \title{Subset \code{Seurat} Objects} \usage{ \method{subset}{Seurat}( x, subset, cells = NULL, features = NULL, idents = NULL, return.null = FALSE, ... ) \method{[}{Seurat}(x, i, j, ...) } \arguments{ \item{x}{A \code{\link{Seurat}} object} \item{subset}{Logical expression indicating features/variables to keep} \item{cells, j}{A vector of cell names or indices to keep} \item{features, i}{A vector of feature names or indices to keep} \item{idents}{A vector of identity classes to keep} \item{return.null}{If no cells are requested, return a \code{NULL}; by default, throws an error} \item{...}{Arguments passed to \code{\link{WhichCells}}} } \value{ \code{subset}: A subsetted \code{Seurat} object \code{[}: object \code{x} with features \code{i} and cells \code{j} } \description{ Subset \code{Seurat} Objects } \examples{ # `subset` examples subset(pbmc_small, subset = MS4A1 > 4) subset(pbmc_small, subset = `DLGAP1-AS1` > 2) subset(pbmc_small, idents = '0', invert = TRUE) subset(pbmc_small, subset = MS4A1 > 3, slot = 'counts') subset(pbmc_small, features = VariableFeatures(object = pbmc_small)) # `[` examples pbmc_small[VariableFeatures(object = pbmc_small), ] pbmc_small[, 1:10] } \seealso{ \code{\link{WhichCells}} Seurat object, validity, and interaction methods \code{\link{$.Seurat}()}, \code{\link{Seurat-class}}, \code{\link{Seurat-validity}}, \code{\link{[[.Seurat}()}, \code{\link{[[<-,Seurat}}, \code{\link{[[<-,Seurat,NULL}}, \code{\link{dim.Seurat}()}, \code{\link{dimnames.Seurat}()}, \code{\link{merge.Seurat}()}, \code{\link{names.Seurat}()} } \concept{seurat} SeuratObject/man/dot-FindObject.Rd0000644000176200001440000000142715075522101016503 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{.FindObject} \alias{.FindObject} \title{Find A Subobject} \usage{ .FindObject(object, name, exclude = c("misc", "tools")) } \arguments{ \item{object}{An \link[methods:Classes_Details]{S4} object} \item{name}{Name of subobject to find} \item{exclude}{A character vector of slot names to exclude} } \value{ The name of the slot that contains \code{name}; returns \code{NULL} if a subobject named \code{name} cannot be found } \description{ Determine the slot that a subobject is contained in } \examples{ .FindObject(pbmc_small, "tsne") } \seealso{ \code{\link{.Collections}()}, \code{\link{.FilterObjects}()}, \code{\link{.Subobjects}()} } \concept{subobjects} \concept{utils} \keyword{internal} SeuratObject/man/as.sparse.Rd0000644000176200001440000000143215075522101015603 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/generics.R, R/utils.R \name{as.sparse} \alias{as.sparse} \alias{as.sparse.data.frame} \alias{as.sparse.Matrix} \alias{as.sparse.matrix} \alias{as.sparse.ngCMatrix} \title{Cast to Sparse} \usage{ as.sparse(x, ...) \method{as.sparse}{data.frame}(x, row.names = NULL, ...) \method{as.sparse}{Matrix}(x, ...) \method{as.sparse}{matrix}(x, ...) \method{as.sparse}{ngCMatrix}(x, ...) } \arguments{ \item{x}{An object} \item{...}{Arguments passed to other methods} \item{row.names}{\code{NULL} or a character vector giving the row names for the data; missing values are not allowed} } \value{ A sparse representation of the input data } \description{ Convert dense objects to sparse representations } \concept{utils} SeuratObject/man/Segmentation-validity.Rd0000644000176200001440000000126215114353666020201 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/segmentation.R \name{Segmentation-validity} \alias{Segmentation-validity} \title{Segmentation Validity} \description{ Validation of \code{Segmentation} objects is handled by \code{\link[methods]{validObject}} } \section{sf.data Validation}{ Validates that the sf.data slot contains an object of class \code{sf}. } \seealso{ \code{\link[methods]{validObject}} Segmentation layer classes: \code{\link{Centroids-class}}, \code{\link{Centroids-methods}}, \code{\link{Molecules-class}}, \code{\link{Molecules-methods}}, \code{\link{Segmentation-class}}, \code{\link{Segmentation-methods}} } \concept{segmentation} SeuratObject/man/DimReduc-validity.Rd0000644000176200001440000000316015075522101017223 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dimreduc.R \name{DimReduc-validity} \alias{DimReduc-validity} \title{Dimensional Reduction Validity} \description{ Validation of \code{DimReduc} objects is handled by \code{\link[methods]{validObject}} } \section{Cell Embeddings Validation}{ The cell embeddings matrix must be a numeric matrix of dimensions \eqn{n_{cells}} by \eqn{d_{dimensions}}; row names must be the cell names and column names must be the dimension identifier. The dimension identifier must be \dQuote{\code{key_dimension}} (eg. \dQuote{\code{PC_1}}). Dimension identifiers must be in order and cannot be skipped } \section{Feature and Projected Feature Loadings Validation}{ blah } \section{Standard Deviations Validation}{ blah } \section{Key Validation}{ Keys must be a one-length character vector; a key must be composed of one of the following: \itemize{ \item An empty string (eg. \dQuote{\code{''}}) where \code{nchar() == 0} \item An string composed of one or more alphanumeric values (both lower- and upper-case) that ends with an underscore (\dQuote{\code{_}}); the first character must be a letter } Keys that are not empty strings are validated with the regex \dQuote{\code{\Sexpr[stage=build]{SeuratObject:::.KeyPattern()}}} } \seealso{ Dimensional reduction object, validity, and interaction methods \code{\link{CreateDimReducObject}()}, \code{\link{DimReduc-class}}, \code{\link{[.DimReduc}()}, \code{\link{[[.DimReduc}()}, \code{\link{dim.DimReduc}()}, \code{\link{merge.DimReduc}()}, \code{\link{print.DimReduc}()}, \code{\link{subset.DimReduc}()} } \concept{dimreduc} SeuratObject/man/show-StdAssay-method.Rd0000644000176200001440000000147515075522101017702 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assay5.R \name{show,StdAssay-method} \alias{show,StdAssay-method} \title{V5 Assay Overview} \usage{ \S4method{show}{StdAssay}(object) } \arguments{ \item{object}{A v5 Assay} } \value{ Prints summary to \code{\link[base]{stdout}} and invisibly returns \code{NULL} } \description{ Overview of a \code{\link{StdAssay}} object } \seealso{ v5 Standard Assay object, validity, and interaction methods \code{\link{$.StdAssay}()}, \code{\link{.DollarNames.StdAssay}()}, \code{\link{StdAssay-class}}, \code{\link{StdAssay-validity}}, \code{\link{[.StdAssay}()}, \code{\link{[[.StdAssay}()}, \code{\link{dim.StdAssay}()}, \code{\link{dimnames.StdAssay}()}, \code{\link{split.StdAssay}()}, \code{\link{subset.StdAssay}()} } \concept{stdassay} \keyword{internal} SeuratObject/man/CheckFeaturesNames.Rd0000644000176200001440000000061515075522101017406 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{CheckFeaturesNames} \alias{CheckFeaturesNames} \title{Check features names format} \usage{ CheckFeaturesNames(data) } \arguments{ \item{data}{a matrix input, rownames(data) are feature names} } \value{ \code{data} with update feature names } \description{ Check features names format } \keyword{internal} SeuratObject/DESCRIPTION0000644000176200001440000001224615117034671014364 0ustar liggesusersPackage: SeuratObject Title: Data Structures for Single Cell Data Version: 5.3.0 Authors@R: c( person(given = 'Paul', family = 'Hoffman', email = 'hoff0792@alumni.umn.edu', role = 'aut', comment = c(ORCID = '0000-0002-7693-8957')), person(given = 'Rahul', family = 'Satija', email = 'seurat@nygenome.org', role = c('aut', 'cre'), comment = c(ORCID = '0000-0001-9448-8833')), person(given = 'David', family = 'Collins', email = 'dcollins@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0001-9243-7821')), person(given = "Yuhan", family = "Hao", email = 'yhao@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0002-1810-0822')), person(given = "Austin", family = "Hartman", email = 'ahartman@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0001-7278-1852')), person(given = "Gesmira", family = "Molla", email = 'gmolla@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0002-8628-5056')), person(given = 'Andrew', family = 'Butler', email = 'abutler@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0003-3608-0463')), person(given = 'Tim', family = 'Stuart', email = 'tstuart@nygenome.org', role = 'aut', comment = c(ORCID = '0000-0002-3044-0897')), person(given = "Madeline", family = "Kowalski", email = "mkowalski@nygenome.org", role = "ctb", comment = c(ORCID = "0000-0002-5655-7620")), person(given = "Saket", family = "Choudhary", email = "schoudhary@nygenome.org", role = "ctb", comment = c(ORCID = "0000-0001-5202-7633")), person(given = "Skylar", family = "Li", email = "sli@nygenome.org", role = "ctb"), person(given = "Longda", family = "Jiang", email = "ljiang@nygenome.org", role = "ctb", comment = c(ORCID = "0000-0003-4964-6497")), person(given = "Anagha", family = "Shenoy", email = "ashenoy@nygenome.org", role = "ctb", comment = c(ORCID = "0000-0002-0537-6862")), person(given = 'Jeff', family = 'Farrell', email = 'jfarrell@g.harvard.edu', role = 'ctb'), person(given = 'Shiwei', family = 'Zheng', email = 'szheng@nygenome.org', role = 'ctb', comment = c(ORCID = '0000-0001-6682-6743')), person(given = 'Christoph', family = 'Hafemeister', email = 'chafemeister@nygenome.org', role = 'ctb', comment = c(ORCID = '0000-0001-6365-8254')), person(given = 'Patrick', family = 'Roelli', email = 'proelli@nygenome.org', role = 'ctb') ) Description: Defines S4 classes for single-cell genomic data and associated information, such as dimensionality reduction embeddings, nearest-neighbor graphs, and spatially-resolved coordinates. Provides data access methods and R-native hooks to ensure the Seurat object is familiar to other R users. See Satija R, Farrell J, Gennert D, et al (2015) , Macosko E, Basu A, Satija R, et al (2015) , and Stuart T, Butler A, et al (2019) , Hao Y, Hao S, et al (2021) and Hao Y, et al (2023) for more details. License: MIT + file LICENSE URL: https://satijalab.github.io/seurat-object/, https://github.com/satijalab/seurat-object BugReports: https://github.com/satijalab/seurat-object/issues Additional_repositories: https://bnprks.r-universe.dev Depends: R (>= 4.1.0), sp (>= 1.5.0) Imports: future, future.apply, generics, grDevices, grid, lifecycle, Matrix (>= 1.6.4), methods, progressr, Rcpp (>= 1.0.5), rlang (>= 0.4.7), spam, stats, tools, utils Suggests: BPCells, DelayedArray, fs (>= 1.5.2), sf (>= 1.0.0), ggplot2, HDF5Array, rmarkdown, testthat LinkingTo: Rcpp, RcppEigen Config/Needs/website: pkgdown BuildManual: true Encoding: UTF-8 LazyData: true RoxygenNote: 7.3.3 Collate: 'RcppExports.R' 'zzz.R' 'generics.R' 'keymixin.R' 'graph.R' 'default.R' 'assay.R' 'logmap.R' 'layers.R' 'assay5.R' 'centroids.R' 'command.R' 'compliance.R' 'data.R' 'jackstraw.R' 'dimreduc.R' 'segmentation.R' 'molecules.R' 'spatial.R' 'fov.R' 'neighbor.R' 'seurat.R' 'sparse.R' 'utils.R' NeedsCompilation: yes Packaged: 2025-12-11 16:32:27 UTC; root Author: Paul Hoffman [aut] (ORCID: ), Rahul Satija [aut, cre] (ORCID: ), David Collins [aut] (ORCID: ), Yuhan Hao [aut] (ORCID: ), Austin Hartman [aut] (ORCID: ), Gesmira Molla [aut] (ORCID: ), Andrew Butler [aut] (ORCID: ), Tim Stuart [aut] (ORCID: ), Madeline Kowalski [ctb] (ORCID: ), Saket Choudhary [ctb] (ORCID: ), Skylar Li [ctb], Longda Jiang [ctb] (ORCID: ), Anagha Shenoy [ctb] (ORCID: ), Jeff Farrell [ctb], Shiwei Zheng [ctb] (ORCID: ), Christoph Hafemeister [ctb] (ORCID: ), Patrick Roelli [ctb] Maintainer: Rahul Satija Repository: CRAN Date/Publication: 2025-12-12 15:50:17 UTC