From 42d02039d511961eec9efa0ace8df30f14531bba Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 12:24:58 -0600 Subject: [PATCH 01/80] Initial commit of package docs. --- R/MicrobiomeR-package.R | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 R/MicrobiomeR-package.R diff --git a/R/MicrobiomeR-package.R b/R/MicrobiomeR-package.R new file mode 100644 index 0000000..2d4f808 --- /dev/null +++ b/R/MicrobiomeR-package.R @@ -0,0 +1,4 @@ +#' @author Rob Gilmore and Shaurita Hutchins +#' @name MicrobiomeR +#' @docType package +NULL From 995507a949896b7ce29d304870631ba8257da37f Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 12:30:18 -0600 Subject: [PATCH 02/80] Added initial description. --- R/MicrobiomeR-package.R | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/R/MicrobiomeR-package.R b/R/MicrobiomeR-package.R index 2d4f808..63dd271 100644 --- a/R/MicrobiomeR-package.R +++ b/R/MicrobiomeR-package.R @@ -1,3 +1,11 @@ +#' MicrobiomeR +#' +#' A microbiome workflow package using phyloseq for data import, metacoder for data analysis, +#' and ggplot2 for data visualization. +#' +#' +#' +#' #' @author Rob Gilmore and Shaurita Hutchins #' @name MicrobiomeR #' @docType package From d1efc7db8fafb321a79a6a6a0e9b100ffc49600e Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 14:03:23 -0600 Subject: [PATCH 03/80] Updated with details section. --- R/MicrobiomeR-package.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/MicrobiomeR-package.R b/R/MicrobiomeR-package.R index 63dd271..ae58b7d 100644 --- a/R/MicrobiomeR-package.R +++ b/R/MicrobiomeR-package.R @@ -3,6 +3,9 @@ #' A microbiome workflow package using phyloseq for data import, metacoder for data analysis, #' and ggplot2 for data visualization. #' +#' The goal of this package is to enhance the use of the \code{\link[metacoder:metacoder]{metacoder}} package by +#' providing tools that mimic the \code{\link[phyloseq:phyloseq-package]{phyloseq}} package. The only difference being that +#' the main data object is a \code{\link[taxa:taxmap]{taxmap object}} instead of a \code{\link[phyloseq:phyloseq-class]{phyloseq object}}. #' #' #' From 6ec1388eedd2834a4c94a6385d98315aa17e59b1 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:12:57 -0600 Subject: [PATCH 04/80] Updated bad NAMESPACE imports. --- R/palettes.R | 2 +- R/utils.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/palettes.R b/R/palettes.R index 39ec1bd..63217bd 100644 --- a/R/palettes.R +++ b/R/palettes.R @@ -159,7 +159,7 @@ viridis_palette <- function(viridis_palette="viridis", viridis_number=800, virid #' @seealso #' \code{\link[grDevices]{colorRamp}} #' @importFrom grDevices colorRampPalette -#' @importFrom crayon red green italics +#' @importFrom crayon red green italic #' @importFrom glue glue combination_palette <- function(...) { # Set up parameters and variables for the palette functions diff --git a/R/utils.R b/R/utils.R index 2b112d0..aacba32 100644 --- a/R/utils.R +++ b/R/utils.R @@ -289,7 +289,7 @@ transposer <- function(.data, ids = NULL, header_name, preserved_categories = TR #' \code{\link[purrr]{modify}} #' @importFrom dplyr select_if select #' @importFrom purrr modify_at -#' @importFrom red silver +#' @importFrom crayon red silver transformer <- function(.data, func, by = "column", ids = NULL, header_name = NULL, preserved_categories = TRUE, separated_categories = NULL, ...) { if (!(is.matrix(.data) | is.data.frame(.data) | tibble::is.tibble(.data))) { stop(crayon::red("Data not transformable.")) From d780a4cff81a48c96ec3d3541ae1354c9ce8c979 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:13:13 -0600 Subject: [PATCH 05/80] Added Other Documentation section to package docs. --- R/MicrobiomeR-package.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/R/MicrobiomeR-package.R b/R/MicrobiomeR-package.R index ae58b7d..1e90720 100644 --- a/R/MicrobiomeR-package.R +++ b/R/MicrobiomeR-package.R @@ -7,6 +7,18 @@ #' providing tools that mimic the \code{\link[phyloseq:phyloseq-package]{phyloseq}} package. The only difference being that #' the main data object is a \code{\link[taxa:taxmap]{taxmap object}} instead of a \code{\link[phyloseq:phyloseq-class]{phyloseq object}}. #' +#' @section Other Documentation: +#' Below are some links to helpful R package used, while developing this package. +#' +#' \describe{ +#' \item{metacoder}{\url{https://grunwaldlab.github.io/metacoder_documentation/}} +#' \item{taxa}{\url{https://github.com/ropensci/taxa}} +#' \item{phyloseq}{\url{http://joey711.github.io/phyloseq/}} +#' \item{microbiome}{\url{http://microbiome.github.io/microbiome/}} +#' \item{MicrobiomeR}{\url{https://github.com/vallenderlab/MicrobiomeR} +#' }} +#' The [MicrobiomeR_Workflows] and [MicrobiomeR_Formats] help sections are also useful for understanding the +#' package. #' #' #' @author Rob Gilmore and Shaurita Hutchins From df79e9650bd6fab453a21d254b93575a8da7cc52 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:14:23 -0600 Subject: [PATCH 06/80] updated NAMESPACE --- NAMESPACE | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index c73ff1b..4d7fced 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -56,7 +56,12 @@ importFrom(ape,read.tree) importFrom(ape,root) importFrom(ape,write.tree) importFrom(crayon,bgWhite) +importFrom(crayon,blue) +importFrom(crayon,green) +importFrom(crayon,italic) importFrom(crayon,red) +importFrom(crayon,silver) +importFrom(crayon,yellow) importFrom(data.table,data.table) importFrom(diptest,dip.test) importFrom(dplyr,arrange) From fbe4d309081ab8b2c11f3422c130945a09046b08 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:15:01 -0600 Subject: [PATCH 07/80] Started vignettes setup. --- DESCRIPTION | 4 ++- vignettes/.gitignore | 2 ++ vignettes/data-wrangling.Rmd | 65 ++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 vignettes/.gitignore create mode 100644 vignettes/data-wrangling.Rmd diff --git a/DESCRIPTION b/DESCRIPTION index 60b73c8..99ec965 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -51,7 +51,8 @@ Imports: vegan Suggests: knitr, - testthat + testthat, + rmarkdown Additional_repositories: http://bioconductor.org/packages/release/bioc/, http://bioconductor.org/packages/release/data/annotation, @@ -62,3 +63,4 @@ LazyData: true RoxygenNote: 6.1.1 URL: https://github.com/vallenderlab/MicrobiomeR BugReports: https://github.com/vallenderlab/MicrobiomeR/issues +VignetteBuilder: knitr diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd new file mode 100644 index 0000000..c52071d --- /dev/null +++ b/vignettes/data-wrangling.Rmd @@ -0,0 +1,65 @@ +--- +title: "Vignette Title" +author: "Vignette Author" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Vignette Title} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +Vignettes are long form documentation commonly included in packages. Because they are part of the distribution of the package, they need to be as compact as possible. The `html_vignette` output type provides a custom style sheet (and tweaks some options) to ensure that the resulting html is as small as possible. The `html_vignette` format: + +- Never uses retina figures +- Has a smaller default figure size +- Uses a custom CSS stylesheet instead of the default Twitter Bootstrap style + +## Vignette Info + +Note the various macros within the `vignette` section of the metadata block above. These are required in order to instruct R how to build the vignette. Note that you should change the `title` field and the `\VignetteIndexEntry` to match the title of your vignette. + +## Styles + +The `html_vignette` template includes a basic CSS theme. To override this theme you can specify your own CSS in the document metadata as follows: + + output: + rmarkdown::html_vignette: + css: mystyles.css + +## Figures + +The figure sizes have been customised so that you can easily put two images side-by-side. + +```{r, fig.show='hold'} +plot(1:10) +plot(10:1) +``` + +You can enable figure captions by `fig_caption: yes` in YAML: + + output: + rmarkdown::html_vignette: + fig_caption: yes + +Then you can use the chunk option `fig.cap = "Your figure caption."` in **knitr**. + +## More Examples + +You can write math expressions, e.g. $Y = X\beta + \epsilon$, footnotes^[A footnote here.], and tables, e.g. using `knitr::kable()`. + +```{r, echo=FALSE, results='asis'} +knitr::kable(head(mtcars, 10)) +``` + +Also a quote using `>`: + +> "He who gives up [code] safety for [code] speed deserves neither." +([via](https://twitter.com/hadleywickham/status/504368538874703872)) From a30a949701db1e1dbad7fd5cee0f7a81051f341b Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:15:14 -0600 Subject: [PATCH 08/80] Started vignettes setup. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f31f088..d792e5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +inst/doc .Rproj.user .Rhistory .RData From 66f4ec7465722dacfccb94f1252e4366e355088c Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:33:46 -0600 Subject: [PATCH 09/80] Initialized introduction vignette. --- vignettes/introduction.Rmd | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 vignettes/introduction.Rmd diff --git a/vignettes/introduction.Rmd b/vignettes/introduction.Rmd new file mode 100644 index 0000000..82b7fcf --- /dev/null +++ b/vignettes/introduction.Rmd @@ -0,0 +1,25 @@ +--- +title: "MicrobiomeR: Introduction" +author: "Vignette Author" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Introduction} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +# Introduction + +MicrobiomeR is a microbiome workflow package that uses phyloseq for data import, taxa for the primary R +object called a Taxmap, metacoder for data analysis, and a combination of packages for data visualization +including ggplot2. + + From 8e56c91a50e135c79a0f205fc86823c33bcae113 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 15:55:57 -0600 Subject: [PATCH 10/80] Added MicrobiomeR Formats section to the introduction vignette. --- vignettes/introduction.Rmd | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/vignettes/introduction.Rmd b/vignettes/introduction.Rmd index 82b7fcf..d2d44c6 100644 --- a/vignettes/introduction.Rmd +++ b/vignettes/introduction.Rmd @@ -22,4 +22,31 @@ MicrobiomeR is a microbiome workflow package that uses phyloseq for data import, object called a Taxmap, metacoder for data analysis, and a combination of packages for data visualization including ggplot2. +The goal of this package is to enhance the use of the [metacoder](https://grunwaldlab.github.io/metacoder_documentation/) +package by providing tools that mimic the functionality of the [phyloseq](http://joey711.github.io/phyloseq/) +package. The only difference being that the main data object is a [taxa::taxmap object](https://github.com/ropensci/taxa#the-taxmap-class) +instead of a [phyloseq::phyloseq object](http://joey711.github.io/phyloseq/import-data.html#import_biom). +# MicrobiomeR Formats +In order to make metacoder and phyloseq's data objects more understandable, MicrobiomeR uses it's +own "formatted" taxmap object. This is simply a taxmap object with observation data `{r} names(tmap$data)` +that contains a specific naming convention. MicrobiomeR's naming convention format is not only +intuitive, but it also gives the MicrobiomeR package the ability to validate data before it is +analyzed or visualized. + +The formats are listed in order from lowest to highest level. To get a taxmap object into the higher +formats they must be in one of the lower formats. It is also inherently important to understand the +MicrobiomeR_Workflow, which describes some of the important dependencies used to create the MicrobiomeR +formats listed below: + +## Phyloseq Format +**_Level 0._** - The "phyloseq_format" is the format given to a taxmap object that has just been converted from a phyloseq object using metacoder via get_phyloseq_obj. A taxmap object identified by MicrobiomeR to be in this format will contain "otu_table", "tax_data", "sample_data" and "phy_tree" data in the observation tables (metacoder_obj$data), which represents the matching phyloseq::otu_table, phyloseq::tax_table, phyloseq::sample_data, and phyloseq::phy_tree data in the original phyloseq object. + +## Raw Format +**_Level 1._** - The "raw_format" is the format given to a taxmap object that has been processed with as_raw_format. It contains the "otu_abundance" and "otu_annotations" data in the observation tables, which are just name conversions of the otu_table and tax_data table from the "phyloseq_format". + +## Basic Format +**_Level 2._** - The "basic_format" is the format given to a taxmap object that has been processed with as_basic_format. It contains the tables available in the "raw_format" along with "taxa_abundance", "otu_proportions", and "taxa_proportions" tables. + +## Analyzed Format +**_Level 3._** - The "analyzed_format" is the format given to a taxmap object that has been processed with as_analyzed_format. It contains the tables available in the "basic_format" along with "statistical_data" and "stats_tax_data" tables. From 090d7da019f447e01627ac9594b4f22967922a29 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 16:15:17 -0600 Subject: [PATCH 11/80] Added start to the data-wrangling vignette. --- vignettes/data-wrangling.Rmd | 62 +++++++----------------------------- 1 file changed, 11 insertions(+), 51 deletions(-) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index c52071d..6197043 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -1,65 +1,25 @@ --- -title: "Vignette Title" -author: "Vignette Author" +title: "MicrobiomeR: Data Wrangling" +author: "Robert Gilmore" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Vignette Title} + %\VignetteIndexEntry{Data Wrangling} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" + echo = TRUE, + collapse = TRUE, + comment = "#>" ) +library(MicrobiomeR) +pkg.var <- MicrobiomeR:::pkg.private +mc_obj <- as_analyzed_format(obj = raw_silva) +hts <- get_heat_tree_plots(mc_obj, rank_list = c("Class")) +hts$heat_trees$Class ``` -Vignettes are long form documentation commonly included in packages. Because they are part of the distribution of the package, they need to be as compact as possible. The `html_vignette` output type provides a custom style sheet (and tweaks some options) to ensure that the resulting html is as small as possible. The `html_vignette` format: -- Never uses retina figures -- Has a smaller default figure size -- Uses a custom CSS stylesheet instead of the default Twitter Bootstrap style - -## Vignette Info - -Note the various macros within the `vignette` section of the metadata block above. These are required in order to instruct R how to build the vignette. Note that you should change the `title` field and the `\VignetteIndexEntry` to match the title of your vignette. - -## Styles - -The `html_vignette` template includes a basic CSS theme. To override this theme you can specify your own CSS in the document metadata as follows: - - output: - rmarkdown::html_vignette: - css: mystyles.css - -## Figures - -The figure sizes have been customised so that you can easily put two images side-by-side. - -```{r, fig.show='hold'} -plot(1:10) -plot(10:1) -``` - -You can enable figure captions by `fig_caption: yes` in YAML: - - output: - rmarkdown::html_vignette: - fig_caption: yes - -Then you can use the chunk option `fig.cap = "Your figure caption."` in **knitr**. - -## More Examples - -You can write math expressions, e.g. $Y = X\beta + \epsilon$, footnotes^[A footnote here.], and tables, e.g. using `knitr::kable()`. - -```{r, echo=FALSE, results='asis'} -knitr::kable(head(mtcars, 10)) -``` - -Also a quote using `>`: - -> "He who gives up [code] safety for [code] speed deserves neither." -([via](https://twitter.com/hadleywickham/status/504368538874703872)) From 08dc65e66a57545ccc62f7072a02c2f3d777fcb1 Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 16:16:35 -0600 Subject: [PATCH 12/80] Updated the data-wrangling vignette. --- vignettes/data-wrangling.Rmd | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index 6197043..2cb1f75 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -11,15 +11,21 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set( - echo = TRUE, - collapse = TRUE, - comment = "#>" + collapse = TRUE, + comment = "#>" ) library(MicrobiomeR) pkg.var <- MicrobiomeR:::pkg.private + +``` + +# Import +Importing data is done via phyloseq. + +# Visualization +```{r message=FALSE, warning=FALSE} mc_obj <- as_analyzed_format(obj = raw_silva) hts <- get_heat_tree_plots(mc_obj, rank_list = c("Class")) hts$heat_trees$Class ``` - From ee69d3c42975f554758686c686037712221ba9be Mon Sep 17 00:00:00 2001 From: grabear Date: Fri, 28 Dec 2018 16:16:44 -0600 Subject: [PATCH 13/80] Updated docs. --- man/MicrobiomeR.Rd | 34 ++++++++++++++++++++++++++++++++++ man/as_raw_format.Rd | 1 + 2 files changed, 35 insertions(+) create mode 100644 man/MicrobiomeR.Rd diff --git a/man/MicrobiomeR.Rd b/man/MicrobiomeR.Rd new file mode 100644 index 0000000..1a2884a --- /dev/null +++ b/man/MicrobiomeR.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/MicrobiomeR-package.R +\docType{package} +\name{MicrobiomeR} +\alias{MicrobiomeR} +\alias{MicrobiomeR-package} +\title{MicrobiomeR} +\description{ +A microbiome workflow package using phyloseq for data import, metacoder for data analysis, +and ggplot2 for data visualization. +} +\details{ +The goal of this package is to enhance the use of the \code{\link[metacoder:metacoder]{metacoder}} package by +providing tools that mimic the \code{\link[phyloseq:phyloseq-package]{phyloseq}} package. The only difference being that +the main data object is a \code{\link[taxa:taxmap]{taxmap object}} instead of a \code{\link[phyloseq:phyloseq-class]{phyloseq object}}. +} +\section{Other Documentation}{ + +Below are some links to helpful R package used, while developing this package. + +\describe{ +\item{metacoder}{\url{https://grunwaldlab.github.io/metacoder_documentation/}} +\item{taxa}{\url{https://github.com/ropensci/taxa}} +\item{phyloseq}{\url{http://joey711.github.io/phyloseq/}} +\item{microbiome}{\url{http://microbiome.github.io/microbiome/}} +\item{MicrobiomeR}{\url{https://github.com/vallenderlab/MicrobiomeR} +}} +The \link{MicrobiomeR_Workflows} and \link{MicrobiomeR_Formats} help sections are also useful for understanding the +package. +} + +\author{ +Rob Gilmore and Shaurita Hutchins +} diff --git a/man/as_raw_format.Rd b/man/as_raw_format.Rd index 79055f3..c3e14b2 100644 --- a/man/as_raw_format.Rd +++ b/man/as_raw_format.Rd @@ -20,6 +20,7 @@ See the \link{MicrobiomeR_Formats} documentation. } \seealso{ \code{\link[MicrobiomeR]{is_phyloseq_format}}, \code{\link[MicrobiomeR]{is_raw_format}}, \code{\link[MicrobiomeR]{order_metacoder_data}} +@importFrom crayon silver red greem Other Formatting: \code{\link{as_MicrobiomeR_format}}, \code{\link{as_analyzed_format}}, From 7454fc33cca85bea23102476669122fb19eca734 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 14:29:30 -0600 Subject: [PATCH 14/80] Made a function for creating a rooted phylogenetic tree from a phyloseq object. --- R/phyloseq.R | 72 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/R/phyloseq.R b/R/phyloseq.R index abf88c0..16aeb52 100644 --- a/R/phyloseq.R +++ b/R/phyloseq.R @@ -47,50 +47,78 @@ #' @importFrom phyloseq import_biom sample_data phy_tree import_qiime_sample_data merge_phyloseq #' @importFrom ape is.rooted write.tree read.tree #' @importFrom tools file_path_as_absolute -get_phyloseq_obj <- function(biom_file = NULL, tree_file = NULL, metadata_file = NULL, treatment_group = NULL, parse_func = NULL, rdata_file = NULL, path = NULL) { +get_phyloseq_obj <- function(biom_file = NULL, tree_file = NULL, metadata_file = NULL, + treatment_group = NULL, parse_func = NULL, rdata_file = NULL, + save_rooted_tree = FALSE, recursive_save = FALSE) { if (!is.null(rdata_file)) { load(rdata_file) - phyloseq_obj <- get("phyloseq_obj") - return(phyloseq_obj) + phyloseq_object <- get("phyloseq_object") + return(phyloseq_object) } else { # Load the biom file data amd qiime metadata separately, and then merge them into a phyloseq object phyloseq_biom <- phyloseq::import_biom(BIOMfilename = biom_file, parseFunction = parse_func, treefilename = tree_file) phyloseq_metadata <- phyloseq::import_qiime_sample_data(metadata_file) - phyloseq_obj <- phyloseq::merge_phyloseq(phyloseq_biom, phyloseq_metadata) + phyloseq_object <- phyloseq::merge_phyloseq(phyloseq_biom, phyloseq_metadata) # Create the "X.TreatmentGroup" variable for the metadata # This step gives other functions a standard treatment group variable to work with if (!is.null(treatment_group)){ if (is.numeric(treatment_group) || is.character(treatment_group)){ - phyloseq::sample_data(phyloseq_obj)[["X.TreatmentGroup"]] <- phyloseq::sample_data(phyloseq_obj)[[treatment_group]] + phyloseq::sample_data(phyloseq_object)[["X.TreatmentGroup"]] <- phyloseq::sample_data(phyloseq_object)[[treatment_group]] } else { warning("The treatment_group parameter must be numeric or a character string.") warning("The data might not be appropriate for other MicrobiomeR functions. Please try again.") stop() } } - # Write to a tree file that subsets our data and update the phyloseq object - if (!is.null(tree_file) && !ape::is.rooted(ape::read.tree(tree_file))) { - # Root the tree - phyloseq_tree <- phyloseq::phy_tree(phyloseq_biom) - ape_tree <- root_by_longest_edge(phyloseq_tree) - # Write the tree file - tf <- basename(tree_file) - tp <- dirname(tools::file_path_as_absolute(tree_file)) - new_tree_file <- sprintf("%s/rooted_%s", tp, tf) - if (!file.exists(new_tree_file)) { - ape::write.tree(ape_tree, new_tree_file) + phyloseq_object <- root_phyloseq_tree(phyloseq_object = phyloseq_object, tree_path = tree_file, + save_rooted_tree = save_rooted_tree, + recursive = recursive_save) + return(phyloseq_object) + } +} + +root_phyloseq_tree <- function(phyloseq_object, tree_path, save_rooted_tree, recursive = TRUE) { + # Write to a tree file that subsets our data and update the phyloseq object + if (!is.null(tree_path) && !ape::is.rooted(ape::read.tree(tree_path))) { + # Root the tree + phyloseq_tree <- phyloseq::phy_tree(phyloseq_object) + ape_tree <- root_by_longest_edge(phyloseq_tree) + # Write the tree file + file_isdir <- file.info(tree_path)[1, "isdir"] + tp <- dirname(tools::file_path_as_absolute(tree_path)) + if (file_isdir == TRUE) { # Is existing directory + tf <- "rooted_tree.tre" + } else if (file_isdir == FALSE) { # Is existing file + tf <- basename(tree_path) + } else if (is.na(file_isdir)) { # Does not exist + if (tools::file_ext() == "") { # Is it a directory string? + if (!dir.create(tree_path, recursive = recursive) == TRUE) { + stop("Unable to create directory. Please check the path to your tree file.") + } } - # Update and return the phyloseq object - phyloseq::phy_tree(phyloseq_obj) <- ape_tree - return(phyloseq_obj) - } else { - return(phyloseq_obj) + } else { # It's a file string. + tf <- basename(tree_path) + if (!dir.exists(tp)) { + if (!dir.create(tree_path, recursive = recursive) == TRUE) { + stop("Unable to create directory. Please check the path to your tree file.") + } + } + } + new_tree_path <- sprintf("%s/rooted_%s", tp, tf) + if (!file.exists(new_tree_path)) { + if (save_rooted_tree == TRUE) { + ape::write.tree(ape_tree, new_tree_path) + } } + # Update and return the phyloseq object + phyloseq::phy_tree(phyloseq_object) <- ape_tree + return(phyloseq_object) + } else { + return(phyloseq_object) } } - #' @title Pick Outgroup for Tree #' @description Pick an outgroup for rooting a phylogenetic tree. #' @param unrooted_tree An unrooted tree object. From 7dd003170d5024042d787f610bd8fcf012f49164 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 14:42:43 -0600 Subject: [PATCH 15/80] Updated the roxygen documentation for the new function. --- R/phyloseq.R | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/R/phyloseq.R b/R/phyloseq.R index 16aeb52..6a7f558 100644 --- a/R/phyloseq.R +++ b/R/phyloseq.R @@ -78,6 +78,38 @@ get_phyloseq_obj <- function(biom_file = NULL, tree_file = NULL, metadata_file = } } +#' @title Root phyloseq tree. +#' @description A function for rooting and saving a phylogenetic tree. +#' @param phyloseq_object A phyloseq object that contains a phylogenetic tree. +#' @param tree_path The path to the existing or desired phylogenetic tree file. +#' @param save_rooted_tree A logical that determines weather or not the rooted tree +#' is saved. +#' @param recursive If the directory doesn't exists create the parent directories +#' that don't exist as well, Default: TRUE +#' @return Returns a phyloseq object with a rooted tree. +#' @pretty_print TRUE +#' @details This function is a helper function to get a proper phyloseq object for +#' downstream analysis. Some analysis requre a rooted tree. The function saves +#' the rooted tree in the phyloseq object. It can also save the tree as a file +#' if desired. +#' @examples +#' \dontrun{ +#' if(interactive()){ +#' #EXAMPLE1 +#' } +#' } +#' @export +#' @family Phylogenetic Tree Manipulators +#' @rdname root_phyloseq_tree +#' @seealso +#' \code{\link[ape]{root}}, \code{\link[ape]{read.tree}}, \code{\link[ape]{write.tree}} +#' +#' \code{\link[phyloseq]{phy_tree}} +#' +#' \code{\link[tools]{fileutils}} +#' @importFrom ape is.rooted read.tree write.tree +#' @importFrom phyloseq phy_tree +#' @importFrom tools file_path_as_absolute file_ext root_phyloseq_tree <- function(phyloseq_object, tree_path, save_rooted_tree, recursive = TRUE) { # Write to a tree file that subsets our data and update the phyloseq object if (!is.null(tree_path) && !ape::is.rooted(ape::read.tree(tree_path))) { From c63bfa5282f5c04113270f5f6bdbe3ceb3ebb08a Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 14:45:18 -0600 Subject: [PATCH 16/80] Updated the get_phyloseq_obj function. --- R/phyloseq.R | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/R/phyloseq.R b/R/phyloseq.R index 6a7f558..6801dc4 100644 --- a/R/phyloseq.R +++ b/R/phyloseq.R @@ -14,7 +14,10 @@ #' @param parse_func The parse function used to parse taxonomy strings from #' Greengenes or SILVA database. Default: NULL #' @param rdata_file A .Rdata file. Default: NULL -#' @param path A path for the output tree file. Default: NULL +#' @param save_rooted_tree A logical that determines weather or not the rooted tree +#' is saved. Default: FALSE +#' @param recursive_save If the directory doesn't exists create the parent directories +#' that don't exist as well. Default: FALSE #' @return A phyloseq object, and a phylogenetic tree file if one does not already exist. #' @pretty_print TRUE #' @details This function heavily relys on the phyloseq package to import data into R. From c891168575ae70787e922cebb6dacb15957a75d2 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 14:58:34 -0600 Subject: [PATCH 17/80] Added an import section to the data-wrangling vignette. --- vignettes/data-wrangling.Rmd | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index 2cb1f75..720de03 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -15,12 +15,39 @@ knitr::opts_chunk$set( comment = "#>" ) library(MicrobiomeR) -pkg.var <- MicrobiomeR:::pkg.private +pkg.data <- MicrobiomeR:::pkg.private ``` # Import -Importing data is done via phyloseq. +Importing data is done via the phyloseq package. MicrobiomeR was developed by testing data from [Nephele's +16S Qiime](https://nephele.niaid.nih.gov/user_guide_pipes/#amplicon_pipes) pipeline, so that will be our +frame of reference for these vignettes. While one can use any phyloseq object generated by phyloseq, the +function `MicrobiomeR::get_phyloseq_obj()` will be used to import the Nephele data, which includes a [biom +file](http://biom-format.org/), a phylogenetic tree file, and the metadata file ([Nephele mapping +file](https://nephele.niaid.nih.gov/user_guide/). +file. + + +(_**Note**_: *Test data can be found in a private environment variable called with MicrobiomeR:::pkg.private*) + +```{r message=FALSE, warning=FALSE} +# Get the data files from package +input_files <- pkg.data$input_files +biom_file <- input_files$biom_files$silva # Path to silva biom file +tree_file <- input_files$tree_files$silva # Path to silva tree file +metadata_file <- input_files$metadata # Path to Nephele metadata +parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations + +# Get the phyloseq object +phy_obj <- get_phyloseq_obj(biom_file = biom_file, + tree_file = tree_file, + metadata_file = metadata_file, + parse_func = parse_func) +``` + +# Formatting +MicrobiomeR provides an intuitive formatting system for taxmap objects. # Visualization ```{r message=FALSE, warning=FALSE} From 432298fe0b818772e08d5f10b22fb59ec0829f32 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 15:37:32 -0600 Subject: [PATCH 18/80] Added a Formatting section to the data-wrangling vignette. --- vignettes/data-wrangling.Rmd | 63 +++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index 720de03..336c930 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -20,12 +20,12 @@ pkg.data <- MicrobiomeR:::pkg.private ``` # Import -Importing data is done via the phyloseq package. MicrobiomeR was developed by testing data from [Nephele's +Importing data is done via the [phyloseq](https://github.com/joey711/phyloseq) package. [MicrobiomeR](https://github.com/vallenderlab/MicrobiomeR) was developed by testing data from [Nephele's 16S Qiime](https://nephele.niaid.nih.gov/user_guide_pipes/#amplicon_pipes) pipeline, so that will be our frame of reference for these vignettes. While one can use any phyloseq object generated by phyloseq, the function `MicrobiomeR::get_phyloseq_obj()` will be used to import the Nephele data, which includes a [biom file](http://biom-format.org/), a phylogenetic tree file, and the metadata file ([Nephele mapping -file](https://nephele.niaid.nih.gov/user_guide/). +file](https://nephele.niaid.nih.gov/user_guide/)). file. @@ -40,19 +40,60 @@ metadata_file <- input_files$metadata # Path to Nephele metadata parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations # Get the phyloseq object -phy_obj <- get_phyloseq_obj(biom_file = biom_file, - tree_file = tree_file, - metadata_file = metadata_file, - parse_func = parse_func) +phyloseq_object <- get_phyloseq_obj(biom_file = biom_file, + tree_file = tree_file, + metadata_file = metadata_file, + parse_func = parse_func) ``` # Formatting -MicrobiomeR provides an intuitive formatting system for taxmap objects. +After importing amplicon data with phyloseq, you will need to convert the phyloseq object to a +[taxa::taxmap](https://github.com/ropensci/taxa) object for use with the +[metacoder](https://github.com/grunwaldlab/metacoder) package. MicrobiomeR has added additional +"formatting" to the taxmap object in the form of specific tables names. For more information please +consult the Formatting help page in your R console via `?MicrobiomeR::MicrobiomeR_Formats`. -# Visualization ```{r message=FALSE, warning=FALSE} -mc_obj <- as_analyzed_format(obj = raw_silva) -hts <- get_heat_tree_plots(mc_obj, rank_list = c("Class")) -hts$heat_trees$Class +p_obj <- phyloseq_object +# Create the various formats +phy_format <- as_MicrobiomeR_format(obj = p_obj, format = "phyloseq_format") +raw_format <- as_MicrobiomeR_format(obj = p_obj, format = "raw_format") +basic_format <- as_MicrobiomeR_format(obj = p_obj, format = "basic_format") +analyzed_format <- as_MicrobiomeR_format(obj = p_obj, format = "analyzed_format") ``` +The various formats that have been defined include the "phyloseq", "raw", "basic", and "analyzed" +formats. These formats define the level or stage that the taxmap object is in. The only difference +between MicrobiomeR taxmap objects and regular taxmap objects is the naming convention used for the +observation data (e.g. `names(MicrobiomeR_obj$data)`). + +```{r message=FALSE, warning=FALSE} +# Show the difference in MicrobiomeR formats +print(names(phy_format$data)) +print(names(raw_format$data)) +print(names(basic_format$data)) +print(names(analyzed_format$data)) +``` + +MicrobiomeR provides a group of helpful functions that can be used to format taxmap objects including: + +* `which_format()` for returning the format of the taxmap object. +* `is_*_format()` for testing if an object is in a specific format. +* `as_*_format()` for converting an object to a specific format. +* `order_metacoder_data()` for ordering the observation data for analysis. +* `validate_MicrobiomeR_fomrat()` for validating that the taxmap object is in a specific format. + +```{r message=FALSE, warning=FALSE} +which_format(analyzed_format) +is_analyzed_format(analyzed_format) +low_level_format <- validate_MicrobiomeR_format(obj = raw_format, valid_formats = c("analyzed_format", "basic_format"), force_format = TRUE, min_or_max = min) +which_format(low_level_format) +high_level_format <- validate_MicrobiomeR_format(obj = raw_format, valid_formats = c("analyzed_format", "basic_format"), force_format = TRUE, min_or_max = max) +which_format(high_level_format) +``` + +However, most of the time you will simply use `as_MicrobiomeR_format(format=...)` to get an object +into the proper format. + +(**Please note that MicrobiomeR _expects_ the data to be imported with phyloseq and then converted to a taxmap object**) + From c075590f699ad3ff0651e69ae59d9781bcaf3000 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 15:44:27 -0600 Subject: [PATCH 19/80] Updated data-wrangling vignette. --- vignettes/data-wrangling.Rmd | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index 336c930..8259a5e 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -70,9 +70,13 @@ observation data (e.g. `names(MicrobiomeR_obj$data)`). ```{r message=FALSE, warning=FALSE} # Show the difference in MicrobiomeR formats print(names(phy_format$data)) + print(names(raw_format$data)) + print(names(basic_format$data)) + print(names(analyzed_format$data)) + ``` MicrobiomeR provides a group of helpful functions that can be used to format taxmap objects including: @@ -84,10 +88,15 @@ MicrobiomeR provides a group of helpful functions that can be used to format tax * `validate_MicrobiomeR_fomrat()` for validating that the taxmap object is in a specific format. ```{r message=FALSE, warning=FALSE} +# Determine format which_format(analyzed_format) + is_analyzed_format(analyzed_format) + +# Forcing validation low_level_format <- validate_MicrobiomeR_format(obj = raw_format, valid_formats = c("analyzed_format", "basic_format"), force_format = TRUE, min_or_max = min) which_format(low_level_format) + high_level_format <- validate_MicrobiomeR_format(obj = raw_format, valid_formats = c("analyzed_format", "basic_format"), force_format = TRUE, min_or_max = max) which_format(high_level_format) ``` From 7783d4a8d86c7a9914fa243c450a9f6077a8fbf3 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 16:55:27 -0600 Subject: [PATCH 20/80] Updated introduction vignette. --- vignettes/introduction.Rmd | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/vignettes/introduction.Rmd b/vignettes/introduction.Rmd index d2d44c6..68f3dee 100644 --- a/vignettes/introduction.Rmd +++ b/vignettes/introduction.Rmd @@ -18,35 +18,15 @@ knitr::opts_chunk$set( # Introduction -MicrobiomeR is a microbiome workflow package that uses phyloseq for data import, taxa for the primary R -object called a Taxmap, metacoder for data analysis, and a combination of packages for data visualization -including ggplot2. - -The goal of this package is to enhance the use of the [metacoder](https://grunwaldlab.github.io/metacoder_documentation/) -package by providing tools that mimic the functionality of the [phyloseq](http://joey711.github.io/phyloseq/) -package. The only difference being that the main data object is a [taxa::taxmap object](https://github.com/ropensci/taxa#the-taxmap-class) +MicrobiomeR is a microbiome workflow package that uses [phyloseq](https://github.com/joey711/phyloseq) for +data import, [taxa](https://github.com/ropensci/taxa) for the primary R object called a Taxmap, +[metacoder](https://github.com/grunwaldlab/metacoder) for data analysis, and a combination of packages for +data visualization including ggplot2. + +The goal of this package is to enhance the use of the +[metacoder](https://grunwaldlab.github.io/metacoder_documentation/) package by providing tools that mimic +the functionality of the [phyloseq](http://joey711.github.io/phyloseq/) package. The only difference being +that the main data object is a [taxa::taxmap object](https://github.com/ropensci/taxa#the-taxmap-class) instead of a [phyloseq::phyloseq object](http://joey711.github.io/phyloseq/import-data.html#import_biom). -# MicrobiomeR Formats -In order to make metacoder and phyloseq's data objects more understandable, MicrobiomeR uses it's -own "formatted" taxmap object. This is simply a taxmap object with observation data `{r} names(tmap$data)` -that contains a specific naming convention. MicrobiomeR's naming convention format is not only -intuitive, but it also gives the MicrobiomeR package the ability to validate data before it is -analyzed or visualized. - -The formats are listed in order from lowest to highest level. To get a taxmap object into the higher -formats they must be in one of the lower formats. It is also inherently important to understand the -MicrobiomeR_Workflow, which describes some of the important dependencies used to create the MicrobiomeR -formats listed below: - -## Phyloseq Format -**_Level 0._** - The "phyloseq_format" is the format given to a taxmap object that has just been converted from a phyloseq object using metacoder via get_phyloseq_obj. A taxmap object identified by MicrobiomeR to be in this format will contain "otu_table", "tax_data", "sample_data" and "phy_tree" data in the observation tables (metacoder_obj$data), which represents the matching phyloseq::otu_table, phyloseq::tax_table, phyloseq::sample_data, and phyloseq::phy_tree data in the original phyloseq object. - -## Raw Format -**_Level 1._** - The "raw_format" is the format given to a taxmap object that has been processed with as_raw_format. It contains the "otu_abundance" and "otu_annotations" data in the observation tables, which are just name conversions of the otu_table and tax_data table from the "phyloseq_format". - -## Basic Format -**_Level 2._** - The "basic_format" is the format given to a taxmap object that has been processed with as_basic_format. It contains the tables available in the "raw_format" along with "taxa_abundance", "otu_proportions", and "taxa_proportions" tables. -## Analyzed Format -**_Level 3._** - The "analyzed_format" is the format given to a taxmap object that has been processed with as_analyzed_format. It contains the tables available in the "basic_format" along with "statistical_data" and "stats_tax_data" tables. From 53c8ec3f9e9d40d84424a8fb1e352aeea7cedfdb Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 16:56:58 -0600 Subject: [PATCH 21/80] Added initial commit to workflow vignette. --- vignettes/workflow.Rmd | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 vignettes/workflow.Rmd diff --git a/vignettes/workflow.Rmd b/vignettes/workflow.Rmd new file mode 100644 index 0000000..ef164e6 --- /dev/null +++ b/vignettes/workflow.Rmd @@ -0,0 +1,20 @@ +--- +title: "Vignette Title" +author: "Vignette Author" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Vignette Title} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +library(MicrobiomeR) +pkg.data <- MicrobiomeR:::pkg.private +``` + From ad4d19acad29886ac9e2097dcf819f4aae82af4a Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 17:11:18 -0600 Subject: [PATCH 22/80] Added a Data Wrangling section to the workflow vignette. --- vignettes/workflow.Rmd | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/vignettes/workflow.Rmd b/vignettes/workflow.Rmd index ef164e6..70d7942 100644 --- a/vignettes/workflow.Rmd +++ b/vignettes/workflow.Rmd @@ -18,3 +18,40 @@ library(MicrobiomeR) pkg.data <- MicrobiomeR:::pkg.private ``` +# Data Wrangling + +```{r message=FALSE, warning=FALSE} +# Get the data files from package +input_files <- pkg.data$input_files +biom_file <- input_files$biom_files$silva # Path to silva biom file +tree_file <- input_files$tree_files$silva # Path to silva tree file +metadata_file <- input_files$metadata # Path to Nephele metadata +parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations + +# Get the phyloseq object +phy_obj <- get_phyloseq_obj(biom_file = biom_file, + tree_file = tree_file, + metadata_file = metadata_file, + parse_func = parse_func) +# Get the taxmap object in the raw format +raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") +``` + +# Metacoder +Metacoder is a highly useful package that comes with tons of features right out of the box. Functions +such as `metacoder::filter_ambiguous_taxa()`, `taxa::filter_taxa()`, and `taxa::filter_obs()` for instance +can almost always be used in your workflow. + +```{r message=FALSE, warning=FALSE} +# Remove Archaea from the metacoder object +metacoder_obj <- taxa::filter_taxa( + obj = raw_metacoder, + taxon_names == "Archaea", + subtaxa = TRUE, + invert = TRUE +) + +# Ambiguous Annotation Filter - Remove taxonomies with ambiguous names +metacoder_obj <- metacoder::filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) +``` + From 50b0ecd095af24cbaed660ce4de49a3798e193b6 Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 17:13:52 -0600 Subject: [PATCH 23/80] Added a Basic Filtering section to the workflow vignette. --- vignettes/workflow.Rmd | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/vignettes/workflow.Rmd b/vignettes/workflow.Rmd index 70d7942..11d31c5 100644 --- a/vignettes/workflow.Rmd +++ b/vignettes/workflow.Rmd @@ -55,3 +55,21 @@ metacoder_obj <- taxa::filter_taxa( metacoder_obj <- metacoder::filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) ``` +# Basic Filtering +Three functions are provided by MicrobiomeR that do some basic filtering: + +* `sample_id_filter()` for filtering samples. +* `taxon_id_filter()` for filtering by taxon_id, which includes intermediate taxa. +* `otu_id_filter()` for filtering by otu_id, which only includes leaf taxa. + +These functions all take the same parameters, most noteably a transformation function (.f_transform), +a filtering function (.f_filter), and a coditional function (.f_condition). + +```{r message=FALSE, warning=FALSE} +# Low Sample Filter - Remove the low samples +# The sample filter should generally be implemented first +metacoder_obj <- sample_filter(obj = metacoder_obj, + .f_filter = ~sum(.), + .f_condition = ~.>= 20, + validated = TRUE) +``` From df259027fdc692829adca9cc4be9cc53cfaa097f Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 17:46:07 -0600 Subject: [PATCH 24/80] Added the Advanced Filtering section to the workflow vignette. --- vignettes/workflow.Rmd | 64 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/vignettes/workflow.Rmd b/vignettes/workflow.Rmd index 11d31c5..87713e2 100644 --- a/vignettes/workflow.Rmd +++ b/vignettes/workflow.Rmd @@ -33,29 +33,31 @@ phy_obj <- get_phyloseq_obj(biom_file = biom_file, tree_file = tree_file, metadata_file = metadata_file, parse_func = parse_func) + # Get the taxmap object in the raw format raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") ``` # Metacoder + Metacoder is a highly useful package that comes with tons of features right out of the box. Functions such as `metacoder::filter_ambiguous_taxa()`, `taxa::filter_taxa()`, and `taxa::filter_obs()` for instance can almost always be used in your workflow. ```{r message=FALSE, warning=FALSE} # Remove Archaea from the metacoder object -metacoder_obj <- taxa::filter_taxa( - obj = raw_metacoder, - taxon_names == "Archaea", - subtaxa = TRUE, - invert = TRUE -) +metacoder_obj <- taxa::filter_taxa(obj = raw_metacoder, + taxon_names == "Archaea", + subtaxa = TRUE, + invert = TRUE) # Ambiguous Annotation Filter - Remove taxonomies with ambiguous names -metacoder_obj <- metacoder::filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) +metacoder_obj <- metacoder::filter_ambiguous_taxa(metacoder_obj, + subtaxa = TRUE) ``` # Basic Filtering + Three functions are provided by MicrobiomeR that do some basic filtering: * `sample_id_filter()` for filtering samples. @@ -73,3 +75,51 @@ metacoder_obj <- sample_filter(obj = metacoder_obj, .f_condition = ~.>= 20, validated = TRUE) ``` + +# Advanced Filtering + +The advanced filtering functions do several things. They wrap the basic filtering functions mentioned above, +they wrap common metacoder and taxa functions, and they mimic the tools found in the phyloseq package. +Below I've mentioned some of them and how they relate to the phyloseq package: + +* `agglomerate_metacoder()` as `phyloseq::tax_glom()`. +* `otu_proportion_filter()` as seen in the first step in phyloseq's [preprocessing](http://joey711.github.io/phyloseq/preprocess.html#preprocessing) vignette. +* `prevalence filtering` functions filter observations by thier prevelance across samples. + * (Unsupervised) `otu_prevelance_filter()` as seen in phyloseq's [prevalence + filtering](http://web.stanford.edu/class/bios221/MicrobiomeWorkflowII.html#prevalence_filtering) vignette. + * (Supervised) `taxa_prevalence_filter()` as seen in phyloseq's [taxonomic filtering](http://web.stanford.edu/class/bios221/MicrobiomeWorkflowII.html#taxonomic_filtering) vignette. +* `cov_filter()` as seen in the nineth step in phyloseq's [preprocessing](http://joey711.github.io/phyloseq/preprocess.html#preprocessing) vignette. + +```{r message=FALSE, warning=FALSE} +# Master Threshold Filter - Add the otu_proportions table and then filter OTUs based on min % +metacoder_obj <- otu_proportion_filter(obj = metacoder_obj, + otu_percentage = 0.00001) + +# Taxon Prevalence Filter - Add taxa_abundance and taxa_proportions and then filter OTUs that do not +# appear more than a certian amount of times in a certain percentage of samples at the specified +# agglomerated rank. This is considered a supervised method, because it relies on intermediate +# taxonomies to filter the data. +# The default minimum abundance is 5 and the sample percentage is 0.5 (5%). +# Phylum +metacoder_obj <- taxa_prevalence_filter(obj = metacoder_obj, + rank = "Phylum") +# Class +metacoder_obj <- taxa_prevalence_filter(obj = metacoder_obj, + rank = "Class", + validated = TRUE) +# Order +metacoder_obj <- taxa_prevalence_filter(obj = metacoder_obj, + rank = "Order", + validated = TRUE) + +# OTU Prevalence Filter - Filter OTUs that do not appear more than a certian amount of times in a +# certain percentage of samples. This is considered an unsupervised method, because it relies only +# on the leaf OTU ids to filter the data. +metacoder_obj <- otu_prevalence_filter(obj = metacoder_obj, + validated = TRUE) + +# Coefficient of Variation Filter - Filter OTUs based on the coefficient of variation +metacoder_obj <- cov_filter(obj = metacoder_obj, + coefficient_of_variation = 3, + validated = TRUE) +``` From 345f508a5edef7ffe3e767657250651f5573844b Mon Sep 17 00:00:00 2001 From: grabear Date: Mon, 31 Dec 2018 17:48:22 -0600 Subject: [PATCH 25/80] Renamed workflow vignette to filtering vignette. --- vignettes/{workflow.Rmd => filtering.Rmd} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename vignettes/{workflow.Rmd => filtering.Rmd} (98%) diff --git a/vignettes/workflow.Rmd b/vignettes/filtering.Rmd similarity index 98% rename from vignettes/workflow.Rmd rename to vignettes/filtering.Rmd index 87713e2..501b4d8 100644 --- a/vignettes/workflow.Rmd +++ b/vignettes/filtering.Rmd @@ -1,10 +1,10 @@ --- -title: "Vignette Title" -author: "Vignette Author" +title: "MicrobiomeR: Filtering" +author: "Robert Gilmore" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{Vignette Title} + %\VignetteIndexEntry{Filtering} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -38,7 +38,7 @@ phy_obj <- get_phyloseq_obj(biom_file = biom_file, raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") ``` -# Metacoder +# Metacoder Filtering Metacoder is a highly useful package that comes with tons of features right out of the box. Functions such as `metacoder::filter_ambiguous_taxa()`, `taxa::filter_taxa()`, and `taxa::filter_obs()` for instance From 3e3a0fd287f1b5100896c91ae4a692cd1dcaf0c6 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 13:15:33 -0600 Subject: [PATCH 26/80] Added some minor fixes to vignette docs. --- vignettes/filtering.Rmd | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/vignettes/filtering.Rmd b/vignettes/filtering.Rmd index 501b4d8..1b0b215 100644 --- a/vignettes/filtering.Rmd +++ b/vignettes/filtering.Rmd @@ -38,7 +38,7 @@ phy_obj <- get_phyloseq_obj(biom_file = biom_file, raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") ``` -# Metacoder Filtering +# Taxmap Filtering Metacoder is a highly useful package that comes with tons of features right out of the box. Functions such as `metacoder::filter_ambiguous_taxa()`, `taxa::filter_taxa()`, and `taxa::filter_obs()` for instance @@ -78,17 +78,18 @@ metacoder_obj <- sample_filter(obj = metacoder_obj, # Advanced Filtering -The advanced filtering functions do several things. They wrap the basic filtering functions mentioned above, -they wrap common metacoder and taxa functions, and they mimic the tools found in the phyloseq package. -Below I've mentioned some of them and how they relate to the phyloseq package: +The advanced filtering functions available with MicrobiomeR do several things. They wrap the basic +filtering functions mentioned above, they wrap common metacoder and taxa functions, and they mimic +the tools found in the phyloseq package. Below I've mentioned some of them and how they relate to +the phyloseq package: -* `agglomerate_metacoder()` as `phyloseq::tax_glom()`. -* `otu_proportion_filter()` as seen in the first step in phyloseq's [preprocessing](http://joey711.github.io/phyloseq/preprocess.html#preprocessing) vignette. -* `prevalence filtering` functions filter observations by thier prevelance across samples. - * (Unsupervised) `otu_prevelance_filter()` as seen in phyloseq's [prevalence +* `agglomerate_metacoder()` is equivalent to `phyloseq::tax_glom()`. +* `otu_proportion_filter()` is seen in the first step in phyloseq's [preprocessing](http://joey711.github.io/phyloseq/preprocess.html#preprocessing) vignette. +* `Prevalence Filtering` functions filter observations by thier prevelance across samples. + * (Unsupervised) `otu_prevelance_filter()` is seen in phyloseq's [prevalence filtering](http://web.stanford.edu/class/bios221/MicrobiomeWorkflowII.html#prevalence_filtering) vignette. - * (Supervised) `taxa_prevalence_filter()` as seen in phyloseq's [taxonomic filtering](http://web.stanford.edu/class/bios221/MicrobiomeWorkflowII.html#taxonomic_filtering) vignette. -* `cov_filter()` as seen in the nineth step in phyloseq's [preprocessing](http://joey711.github.io/phyloseq/preprocess.html#preprocessing) vignette. + * (Supervised) `taxa_prevalence_filter()` is seen in phyloseq's [taxonomic filtering](http://web.stanford.edu/class/bios221/MicrobiomeWorkflowII.html#taxonomic_filtering) vignette. +* `cov_filter()` is seen in the nineth step in phyloseq's [preprocessing](http://joey711.github.io/phyloseq/preprocess.html#preprocessing) vignette. ```{r message=FALSE, warning=FALSE} # Master Threshold Filter - Add the otu_proportions table and then filter OTUs based on min % @@ -123,3 +124,6 @@ metacoder_obj <- cov_filter(obj = metacoder_obj, coefficient_of_variation = 3, validated = TRUE) ``` + +# Other Filtering + From 3b041534f6991bb29f5c02a1a1d5fb6fce952ce1 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 13:25:15 -0600 Subject: [PATCH 27/80] Updated bug in transposer function. --- R/utils.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils.R b/R/utils.R index aacba32..3765a90 100644 --- a/R/utils.R +++ b/R/utils.R @@ -237,7 +237,7 @@ transposer <- function(.data, ids = NULL, header_name, preserved_categories = TR if (!is.null(separated_categories)) { trans_data <- trans_data %>% tidyr::separate(col = header_name, into = separated_categories, sep = "<_>") } else { - messsage(crayon::yellow("Separated categories have not been supplied. Columns will be named as \"category_#\".")) + message(crayon::yellow("Separated categories have not been supplied. Columns will be named as \"category_#\".")) n_cats <- stringr::str_count(trans_data[[header_name]][1], pattern = "<_>") + 1 trans_data <- trans_data %>% tidyr::separate(col = header_name, into = paste("category", seq(1:n_cats), sep = "_"), sep = "<_>") } From b4a633fbb4c3afdb5b69e2c00c90a4d062a8c29c Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 13:40:25 -0600 Subject: [PATCH 28/80] Added the Other Filtering section. --- vignettes/filtering.Rmd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vignettes/filtering.Rmd b/vignettes/filtering.Rmd index 1b0b215..6d7cda1 100644 --- a/vignettes/filtering.Rmd +++ b/vignettes/filtering.Rmd @@ -127,3 +127,10 @@ metacoder_obj <- cov_filter(obj = metacoder_obj, # Other Filtering +As mentioned previously taxmap filtering can be done in any way that fits your needs with the `taxa` +and `metacoder` packages. However, MicrobiomeR also provides some utility based function for +filtering/manipulating your _observation_ data by hand. Observation data can be accessed within +the metacoder object. Make sure you don't manipulate existing data inside of your taxmap object +unless you're absolutely sure you know what you're doing. + + From ed09379e74c83ecc242447d43ca78177060427a1 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 13:40:43 -0600 Subject: [PATCH 29/80] Added the Transposing subsection. --- vignettes/filtering.Rmd | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/vignettes/filtering.Rmd b/vignettes/filtering.Rmd index 6d7cda1..72730ac 100644 --- a/vignettes/filtering.Rmd +++ b/vignettes/filtering.Rmd @@ -133,4 +133,26 @@ filtering/manipulating your _observation_ data by hand. Observation data can be the metacoder object. Make sure you don't manipulate existing data inside of your taxmap object unless you're absolutely sure you know what you're doing. +## Transposing +```{r message=FALSE, warning=FALSE} +# Get the abundance tables from the taxmap object +taxa_abund <- metacoder_obj$data$taxa_abundance +otu_abund <- metacoder_obj$data$otu_abundance + +# Transposing with one ID (taxon_id) +taxa_abund %>% transposer(ids = "taxon_id", header_name = "samples") + +# Re-Transposing with one ID (taxon_id) +taxa_abund %>% transposer("taxon_id", "samples") %>% transposer("samples", "taxon_id") + +# Transposing with two IDs (taxon_id, otu_id) +# The column headers will be a combination of the categorical data that will +# be parsed and split back into individual columns if retransposed. +otu_abund %>% transposer("otu_id", "samples") + +# Re-Transposing with two IDs (taxon_id, otu_id) +# When you transpose categorical data, the column headers are lost. +# To re-transpose you have to supply these headers +otu_abund %>% transposer("otu_id", "samples") %>% transposer("samples", "otu_id", separated_categories = c("taxon_id", "otu_id")) +``` From 596441876a06ce88748e3be2f9d9d0b87da4a402 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 13:57:16 -0600 Subject: [PATCH 30/80] Updated transformer function. --- R/utils.R | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/R/utils.R b/R/utils.R index 3765a90..fa8d321 100644 --- a/R/utils.R +++ b/R/utils.R @@ -241,9 +241,12 @@ transposer <- function(.data, ids = NULL, header_name, preserved_categories = TR n_cats <- stringr::str_count(trans_data[[header_name]][1], pattern = "<_>") + 1 trans_data <- trans_data %>% tidyr::separate(col = header_name, into = paste("category", seq(1:n_cats), sep = "_"), sep = "<_>") } + message(crayon::silver("Re-Transposed Data.")) + return(trans_data) + } else { + message(crayon::silver("Transposed Data.")) + return(trans_data) } - message(crayon::silver("Transposed Data.")) - return(trans_data) } #' @title Transforming Tidy Data From 72e1be91801ed6c46d73070d1eaba25586012b7d Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 13:58:47 -0600 Subject: [PATCH 31/80] Added the Transforming subsection. --- vignettes/filtering.Rmd | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vignettes/filtering.Rmd b/vignettes/filtering.Rmd index 72730ac..8e572a7 100644 --- a/vignettes/filtering.Rmd +++ b/vignettes/filtering.Rmd @@ -156,3 +156,16 @@ otu_abund %>% transposer("otu_id", "samples") # To re-transpose you have to supply these headers otu_abund %>% transposer("otu_id", "samples") %>% transposer("samples", "otu_id", separated_categories = c("taxon_id", "otu_id")) ``` + +## Transforming + +```{r message=FALSE, warning=FALSE} +# Transforming to proportions/percentages by COLUMN +taxa_abund %>% transformer(func = ~./sum(.)) + +# Transforming by ROW is also possible +# This function will transpose/retranspose so other information is needed +taxa_abund %>% transformer(by = "row", ids = "taxon_id", header_name = "samples", separated_categories = c("taxon_id")) +``` + + From 70b96ce1f2786266f09f4d24493cac6e2478e2bf Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 15:34:10 -0600 Subject: [PATCH 32/80] Updated vlookup function with more pragmatic parameter names. --- R/utils.R | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/R/utils.R b/R/utils.R index fa8d321..ff0bd8d 100644 --- a/R/utils.R +++ b/R/utils.R @@ -318,10 +318,10 @@ transformer <- function(.data, func, by = "column", ids = NULL, header_name = NU #' @title Mock Excel "VlookUp" Function #' @description A function that mimicks excels vlookup, but for R's dataframe. -#' @param lookup_data A vector of items to look up. +#' @param lookup_vector A vector of items to look up. #' @param df The dataframe to search. -#' @param match_data The column name to search in the dataframe. -#' @param return_data The column of data to return when matched. +#' @param match_var The column name to search in the dataframe. +#' @param return_var The column of data to return when matched. #' @return A vector that contains the items of interest. #' @pretty_print TRUE #' @details A function that works like the VLOOKUP function in excel. This function was @@ -335,10 +335,10 @@ transformer <- function(.data, func, by = "column", ids = NULL, header_name = NU #' @export #' @family Data Manipulators #' @rdname vlookup -vlookup <- function(lookup_data, df, match_data, return_data) { +vlookup <- function(lookup_vector, df, match_var, return_var) { # TODO: Update the way this returns data. Allow it to add data to a new column. - m <- match(lookup_data, df[[match_data]]) - df[[return_data]][m] + m <- match(lookup_vector, df[[match_var]]) + df[[return_var]][m] } #' @title Create a table from a data frame From 01e93df045e3a89b4d11cb138df6af799a96d96d Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 16:00:18 -0600 Subject: [PATCH 33/80] Added Vlookup sub section, and reformatted other sections. --- vignettes/filtering.Rmd | 47 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/vignettes/filtering.Rmd b/vignettes/filtering.Rmd index 8e572a7..fcfa03f 100644 --- a/vignettes/filtering.Rmd +++ b/vignettes/filtering.Rmd @@ -144,28 +144,65 @@ otu_abund <- metacoder_obj$data$otu_abundance taxa_abund %>% transposer(ids = "taxon_id", header_name = "samples") # Re-Transposing with one ID (taxon_id) -taxa_abund %>% transposer("taxon_id", "samples") %>% transposer("samples", "taxon_id") +taxa_abund %>% + transposer("taxon_id", "samples") %>% + transposer("samples", "taxon_id") # Transposing with two IDs (taxon_id, otu_id) # The column headers will be a combination of the categorical data that will # be parsed and split back into individual columns if retransposed. -otu_abund %>% transposer("otu_id", "samples") +otu_abund %>% + transposer("otu_id", "samples") # Re-Transposing with two IDs (taxon_id, otu_id) # When you transpose categorical data, the column headers are lost. # To re-transpose you have to supply these headers -otu_abund %>% transposer("otu_id", "samples") %>% transposer("samples", "otu_id", separated_categories = c("taxon_id", "otu_id")) +otu_abund %>% + transposer("otu_id", "samples") %>% + transposer("samples", "otu_id", + separated_categories = c("taxon_id", "otu_id")) ``` ## Transforming ```{r message=FALSE, warning=FALSE} # Transforming to proportions/percentages by COLUMN -taxa_abund %>% transformer(func = ~./sum(.)) +taxa_abund %>% + transformer(func = ~./sum(.)) # Transforming by ROW is also possible # This function will transpose/retranspose so other information is needed -taxa_abund %>% transformer(by = "row", ids = "taxon_id", header_name = "samples", separated_categories = c("taxon_id")) +taxa_abund %>% + transformer(by = "row", + func = ~./sum(.), + ids = "taxon_id", + header_name = "samples", + separated_categories = c("taxon_id")) ``` +## Excel-Like VLookup +This function was # borrowed from \url{https://www.r-bloggers.com/an-r-vlookup-not-so-silly-idea/}. + +```{r message=FALSE, warning=FALSE} +# Get analyzed Data +metacoder_obj <- as_MicrobiomeR_format(obj = metacoder_obj, format = "analyzed_format") + +# Create agglomerated taxmaps for phylum/class +phylum_mo <- agglomerate_metacoder(obj = metacoder_obj, rank = "Phylum") +class_mo <- agglomerate_metacoder(obj = metacoder_obj, rank = "Class") +# Get some observation data +phylum_data <- phylum_mo$data$stats_tax_data +class_data <- class_mo$data$stats_tax_data + +# Take the Phylum in the "phylum_data" and cross reference these in the "class_data". +# Reutrn the "wilcox_p_value" of the class_data. +class_p_value <- vlookup(lookup_vector = phylum_data$Phylum, + df = class_data, + match_var = "Phylum", + return_var = "wilcox_p_value") + +# Create a new column in the phylum_data. +new_data <- phylum_data %>% dplyr::mutate(class_p_value = class_p_value) +new_data[c("taxon_id", "Phylum", "Class", "class_p_value", "wilcox_p_value")] +``` From 813ab4e16bd86a6c9f999de69d802cbede81cd72 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 16:03:23 -0600 Subject: [PATCH 34/80] Initial commit of analysis vignette. --- vignettes/analysis.Rmd | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 vignettes/analysis.Rmd diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd new file mode 100644 index 0000000..1ac063c --- /dev/null +++ b/vignettes/analysis.Rmd @@ -0,0 +1,18 @@ +--- +title: "MicrobiomeR: Analysis" +author: "Vignette Author" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Analysis} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + From 859da3153cb912395b60f0d575c15972deff43be Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 16:03:54 -0600 Subject: [PATCH 35/80] Added Data Wrangling section to analysis vignette. --- vignettes/analysis.Rmd | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd index 1ac063c..9790f3f 100644 --- a/vignettes/analysis.Rmd +++ b/vignettes/analysis.Rmd @@ -16,3 +16,24 @@ knitr::opts_chunk$set( ) ``` +# Data Wrangling + +```{r message=FALSE, warning=FALSE} +# Get the data files from package +input_files <- pkg.data$input_files +biom_file <- input_files$biom_files$silva # Path to silva biom file +tree_file <- input_files$tree_files$silva # Path to silva tree file +metadata_file <- input_files$metadata # Path to Nephele metadata +parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations + +# Get the phyloseq object +phy_obj <- get_phyloseq_obj(biom_file = biom_file, + tree_file = tree_file, + metadata_file = metadata_file, + parse_func = parse_func) + +# Get the taxmap object in the raw format +raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") +``` + + From aa793f0e411b33833e9520edb6f7afafef6e5352 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 16:06:05 -0600 Subject: [PATCH 36/80] Added Filtering section to analysis vignette. --- vignettes/analysis.Rmd | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd index 9790f3f..4af052a 100644 --- a/vignettes/analysis.Rmd +++ b/vignettes/analysis.Rmd @@ -36,4 +36,55 @@ phy_obj <- get_phyloseq_obj(biom_file = biom_file, raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") ``` +# Filtering +```{r message=FALSE, warning=FALSE} +# Remove Archaea from the metacoder object +metacoder_obj <- taxa::filter_taxa(obj = raw_metacoder, + taxon_names == "Archaea", + subtaxa = TRUE, + invert = TRUE) + +# Ambiguous Annotation Filter - Remove taxonomies with ambiguous names +metacoder_obj <- metacoder::filter_ambiguous_taxa(metacoder_obj, + subtaxa = TRUE) + +# Low Sample Filter - Remove the low samples +# The sample filter should generally be implemented first +metacoder_obj <- sample_filter(obj = metacoder_obj, + .f_filter = ~sum(.), + .f_condition = ~.>= 20, + validated = TRUE) + +# Master Threshold Filter - Add the otu_proportions table and then filter OTUs based on min % +metacoder_obj <- otu_proportion_filter(obj = metacoder_obj, + otu_percentage = 0.00001) + +# Taxon Prevalence Filter - Add taxa_abundance and taxa_proportions and then filter OTUs that do not +# appear more than a certian amount of times in a certain percentage of samples at the specified +# agglomerated rank. This is considered a supervised method, because it relies on intermediate +# taxonomies to filter the data. +# The default minimum abundance is 5 and the sample percentage is 0.5 (5%). +# Phylum +metacoder_obj <- taxa_prevalence_filter(obj = metacoder_obj, + rank = "Phylum") +# Class +metacoder_obj <- taxa_prevalence_filter(obj = metacoder_obj, + rank = "Class", + validated = TRUE) +# Order +metacoder_obj <- taxa_prevalence_filter(obj = metacoder_obj, + rank = "Order", + validated = TRUE) + +# OTU Prevalence Filter - Filter OTUs that do not appear more than a certian amount of times in a +# certain percentage of samples. This is considered an unsupervised method, because it relies only +# on the leaf OTU ids to filter the data. +metacoder_obj <- otu_prevalence_filter(obj = metacoder_obj, + validated = TRUE) + +# Coefficient of Variation Filter - Filter OTUs based on the coefficient of variation +metacoder_obj <- cov_filter(obj = metacoder_obj, + coefficient_of_variation = 3, + validated = TRUE) +``` From 5577c6e240227f4f09266faad029a66990fc1a43 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 17:14:58 -0600 Subject: [PATCH 37/80] Added the Statistics sub-section, and updated the Analysis overview. --- vignettes/analysis.Rmd | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd index 4af052a..1a3a355 100644 --- a/vignettes/analysis.Rmd +++ b/vignettes/analysis.Rmd @@ -88,3 +88,28 @@ metacoder_obj <- cov_filter(obj = metacoder_obj, coefficient_of_variation = 3, validated = TRUE) ``` + +# Analysis + +Analysis is primarily done with metacoder, MicrobiomeR, and ggplot2. Before beginning the analysis +it's wise to create an output directory. Use `end_path=FALSE` to avoid the creation of a date +formatted directory. + +```{r message=FALSE, warning=FALSE} +# Create a directory for whichever plot you want to save +htp <- get_output_dir(end_path = FALSE, start_path = "output", plot_type = "heat_tree") +cpp <- get_output_dir(end_path = FALSE, start_path = "output", plot_type = "correlation") +``` + +## Statistics + +Statistical analysis is primarily done with the help of metacoder style functions such as the +`calc_*()` group of functions, and `compare_groups()`. The taxa function `taxonomy_table()` is also +useful for matching stats with the proper taxonomic annotation. MicrobiomeR creates the proper +tables with `as_MicrobiomeR_format(format = "analyzed_format", ...)`. + +```{r message=FALSE, warning=FALSE} +# Get the statistical observation data. +metacoder_obj <- as_MicrobiomeR_format(obj = metacoder_obj, format = "analyzed_format") +``` + From fcd9f32ce48cd048d043aaad06962794d76c0167 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 17:15:15 -0600 Subject: [PATCH 38/80] Fixed get_output_dir logic flow. --- R/utils.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/R/utils.R b/R/utils.R index ff0bd8d..b635e90 100644 --- a/R/utils.R +++ b/R/utils.R @@ -104,25 +104,25 @@ get_output_dir <- function(start_path=NULL, experiment=NULL, plot_type=NULL, end full_path <- file.path(root_path) } # Add the output folder to use (generally a new folder, or pre-existing output folder) - if (!is.null(start_path)) { + if (is.character(start_path)) { full_path <- file.path(full_path, start_path) # Add a folder for the specific experiment you are conducting - if (!is.null(experiment)) { + if (is.character(experiment)) { full_path <- file.path(full_path, experiment) } # Add a folder for the plot_type that's being generated - if (!is.null(plot_type)) { + if (is.character(plot_type)) { full_path <- file.path(full_path, plot_type) } # Add a folder for any extra - if (!is.null(end_path)) { - full_path <- file.path(full_path, extra_path) - } else if (is.null(end_path)) { + if (is.null(end_path)) { full_path <- file.path(full_path, format(Sys.time(), "%Y-%m-%d_%s")) + } else if (is.character(end_path)) { + full_path <- file.path(full_path, end_path) } } else if (is.null(end_path)) { # Add a folder for the plot_type that's being generated - if (!is.null(plot_type)) { + if (is.character(plot_type)) { full_path <- file.path(full_path, plot_type) } else { full_path <- file.path(full_path, "output") From 0ac7fb8062811f41e02179c38a16635994e6dbd0 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 19:18:58 -0600 Subject: [PATCH 39/80] Added output message for corr-plot generation, and added palette customization to the corr-plot function. --- R/correlation-plot.R | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/R/correlation-plot.R b/R/correlation-plot.R index 2293c65..78ea8bf 100644 --- a/R/correlation-plot.R +++ b/R/correlation-plot.R @@ -5,6 +5,7 @@ #' @param secondary_rank The secondary rank used to color the points. Can be an integer specifying #' the number of supertaxon ranks above the primary rank or the name of a supertaxon rank. Default: TRUE #' @param wp_value The Wilcoxian P-Value used to represent significant points. Default: 0.05 +#' @param pal_func A palette function that returns grDevices::colorRampPalette. #' @return A 1:1 correlation plot built with ggplot2. #' @pretty_print TRUE #' @details Correlation plots help to better explain the heat tree findings. @@ -36,7 +37,7 @@ #' @importFrom ggrepel geom_label_repel #' @importFrom crayon yellow correlation_plot <- function(obj, primary_rank, secondary_rank = TRUE, - wp_value = 0.05) { + wp_value = 0.05, pal_func = NULL) { metacoder_object <- object_handler(obj) metacoder_object <- validate_MicrobiomeR_format(obj = metacoder_object, valid_formats = c("analyzed_format")) @@ -99,7 +100,17 @@ correlation_plot <- function(obj, primary_rank, secondary_rank = TRUE, background_limits <- data.frame(id = c("1", "1", "1", "2", "2", "2"), x = c(0, Inf, 0, 0, Inf, Inf), y = c(0, Inf, Inf, 0, 0, Inf)) # Get a color palette secondary_taxa <- length(unique(primary_data[[(secondary_rank)]])) - myPal <- get_color_palette(color_no = secondary_taxa, display = FALSE) + if (is.null(pal_func)) { + pal_func <- combination_palette( + magma = list(palette = viridis::magma, args = list(n=500), range=450:500, rev=TRUE), + inferno = list(palette = viridis::inferno, args = list(n=500), range=100:400, rev=TRUE), + cividis = list(palette = viridis::cividis, args = list(n=500), range=100:200, rev=TRUE), + viridis = list(palette = viridis::viridis, args = list(n=500), range=100:480)) + } + myPal <- get_color_palette( + pal_func = pal_func, + color_no = secondary_taxa, + display = FALSE) # Start ggplot2 workflow corr <- ggplot2::ggplot(primary_data, ggplot2::aes(x = mean_treat1, y = mean_treat2)) + @@ -115,6 +126,7 @@ correlation_plot <- function(obj, primary_rank, secondary_rank = TRUE, ggplot2::scale_fill_manual(values = c("red", "blue", myPal), guide = FALSE) + ggplot2::scale_color_manual(values = c(myPal), name = sprintf("%s:", c(secondary_rank)), guide = ggplot2::guide_legend(ncol = 2)) + ggplot2::geom_abline(slope = 1, intercept = 0, linetype = "dashed") + message(crayon::green(sprintf("Generating Correlation Plot for %s with color based on %s", crayon::bgWhite(primary_rank), crayon::bgWhite(secondary_rank)))) return(corr) } From 38b76c1a6eda8806528dbb19698e1eb92d1f435e Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 19:19:35 -0600 Subject: [PATCH 40/80] Fixed palette bugs and added the rev parameter to get_color_palette function. --- R/palettes.R | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/R/palettes.R b/R/palettes.R index 63217bd..95c9f51 100644 --- a/R/palettes.R +++ b/R/palettes.R @@ -24,7 +24,7 @@ #' @family Color Palettes #' @rdname get_color_palette #' @importFrom graphics pie -get_color_palette <- function(pal_func=viridis_magma_palette, color_no=20, display=TRUE, ...) { +get_color_palette <- function(pal_func=viridis_magma_palette, color_no=20, display=TRUE, rev = FALSE, ...) { err_handle <- try({ pal_func <- pal_func(...) pal <- pal_func(n=color_no, ...) @@ -32,6 +32,9 @@ get_color_palette <- function(pal_func=viridis_magma_palette, color_no=20, displ if (inherits(err_handle, "try-error")) { pal <- pal_func(n=color_no, ...) } + if (rev == TRUE) { + pal <- rev(pal) + } if (display){ pie(rep(1, length(pal)), col=pal) } @@ -101,7 +104,7 @@ scico_palette <- function(scico_palette="batlow", scico_number=800, scico_range= viridis_palette <- function(viridis_palette="viridis", viridis_number=800, viridis_range=0:viridis_number) { pal <- viridis::viridis(viridis_number, option = viridis_palette)[viridis_range] pal <- unique(pal) - crp <- grDevices::colorRampPalette() + crp <- grDevices::colorRampPalette(pal) return(crp) } @@ -239,7 +242,7 @@ combination_palette <- function(...) { #' \code{\link[grDevices]{colorRamp}} #' @importFrom viridis viridis magma viridis_magma_palette <- function(viridis_number = 800, viridis_range = 300:viridis_number, viridis_rev = TRUE, - magma_number = 500, magma_range = 0:magma_number, magma_rev = FALSE, ...) { + magma_number = 500, magma_range = 50:magma_number, magma_rev = FALSE, ...) { if (!missing(...)){ v_args = list(n=viridis_number, ...) m_args = list(n=magma_number, ...) From 7de073ce3836c0e374057c17b6d1391beef6db36 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 19:38:37 -0600 Subject: [PATCH 41/80] Added a Visualization sub-section to the analysis vignette. --- vignettes/analysis.Rmd | 50 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd index 1a3a355..3f1e608 100644 --- a/vignettes/analysis.Rmd +++ b/vignettes/analysis.Rmd @@ -14,6 +14,8 @@ knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) +library(MicrobiomeR) +pkg.data <- MicrobiomeR:::pkg.private ``` # Data Wrangling @@ -92,13 +94,13 @@ metacoder_obj <- cov_filter(obj = metacoder_obj, # Analysis Analysis is primarily done with metacoder, MicrobiomeR, and ggplot2. Before beginning the analysis -it's wise to create an output directory. Use `end_path=FALSE` to avoid the creation of a date -formatted directory. +it's wise to create an output directory. Use `end_path=FALSE` with MicrobiomeR's `get_output_dir()` +function to avoid the creation of a date formatted directory. -```{r message=FALSE, warning=FALSE} +```{r message=FALSE, warning=FALSE, eval=FALSE} # Create a directory for whichever plot you want to save -htp <- get_output_dir(end_path = FALSE, start_path = "output", plot_type = "heat_tree") -cpp <- get_output_dir(end_path = FALSE, start_path = "output", plot_type = "correlation") +heat_tree_path <- get_output_dir(end_path = FALSE, start_path = "output", plot_type = "heat_tree") +corr_plot_path <- get_output_dir(end_path = FALSE, start_path = "output", plot_type = "correlation") ``` ## Statistics @@ -113,3 +115,41 @@ tables with `as_MicrobiomeR_format(format = "analyzed_format", ...)`. metacoder_obj <- as_MicrobiomeR_format(obj = metacoder_obj, format = "analyzed_format") ``` +## Visualization + +Visualization of taxmap objects can be done in several ways. The metacoder package primarily +produces `heat_tree()`s. MicrobiomeR does this as well, but takes care of creating default values +that the developers enjoyed in their heat tree plots. MicrobiomeR also uses ggplot2 to create +`correlation_plot()`s. + +```{r message=FALSE, warning=FALSE} +# Generate heat_trees +heat_tree_plots <- get_heat_tree_plots(metacoder_obj, + rank_list = c("Phylum", "Class", "Order"), + node_label = ifelse(wilcox_p_value > 0.05, taxon_ids, NA), + node_label_size = 2, + node_label_color = c("darkgreen")) +names(heat_tree_plots) +# Generate correlation_plots +corr_plots <- get_correlation_plots(metacoder_obj, primary_ranks = c("Phylum", "Class", "Order")) +names(corr_plots) +``` +```{r message=FALSE, warning=FALSE, eval=FALSE} +# Save plots with a custom output path +save_heat_tree_plots(htrees = heat_tree_plots, custom_path = heat_tree_path) +save_correlation_plots(corr = corr_plots, custom_path = corr_plot_path) +``` +```{r message=FALSE, warning=FALSE, fig.align="center", fig.width=8, fig.height=8} +# Heat Trees +heat_trees <- heat_tree_plots$heat_trees +heat_trees$Phylum +heat_trees$Class +heat_trees$Order +``` + +```{r message=FALSE, warning=FALSE, fig.align="center", fig.width=8, fig.height=5.3} +# Correlation Plots +corr_plots$Phylum +corr_plots$Class +corr_plots$Order +``` From ac774bdb00474873aa1f54214b6800a013c72375 Mon Sep 17 00:00:00 2001 From: grabear Date: Wed, 2 Jan 2019 19:39:10 -0600 Subject: [PATCH 42/80] Updated package after build and install. --- NAMESPACE | 1 + man/correlation_plot.Rd | 4 ++- man/get_color_palette.Rd | 2 +- man/get_phyloseq_obj.Rd | 9 +++++-- man/pick_new_outgroup.Rd | 3 ++- man/root_by_longest_edge.Rd | 3 ++- man/root_phyloseq_tree.Rd | 50 ++++++++++++++++++++++++++++++++++++ man/viridis_magma_palette.Rd | 2 +- man/vlookup.Rd | 8 +++--- 9 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 man/root_phyloseq_tree.Rd diff --git a/NAMESPACE b/NAMESPACE index 4d7fced..a4ee88c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -33,6 +33,7 @@ export(otu_proportion_filter) export(parse_taxonomy_silva_128) export(pick_new_outgroup) export(root_by_longest_edge) +export(root_phyloseq_tree) export(sample_filter) export(save_barplot) export(save_correlation_plots) diff --git a/man/correlation_plot.Rd b/man/correlation_plot.Rd index 7844829..d180214 100644 --- a/man/correlation_plot.Rd +++ b/man/correlation_plot.Rd @@ -5,7 +5,7 @@ \title{Correlation Plot} \usage{ correlation_plot(obj, primary_rank, secondary_rank = TRUE, - wp_value = 0.05) + wp_value = 0.05, pal_func = NULL) } \arguments{ \item{obj}{An object to be converted to a metacoder object with \code{\link[MicrobiomeR]{object_handler}}.} @@ -16,6 +16,8 @@ correlation_plot(obj, primary_rank, secondary_rank = TRUE, the number of supertaxon ranks above the primary rank or the name of a supertaxon rank. Default: TRUE} \item{wp_value}{The Wilcoxian P-Value used to represent significant points. Default: 0.05} + +\item{pal_func}{A palette function that returns grDevices::colorRampPalette.} } \value{ A 1:1 correlation plot built with ggplot2. diff --git a/man/get_color_palette.Rd b/man/get_color_palette.Rd index e8c9ba4..2843fe3 100644 --- a/man/get_color_palette.Rd +++ b/man/get_color_palette.Rd @@ -5,7 +5,7 @@ \title{Get a Color Palette} \usage{ get_color_palette(pal_func = viridis_magma_palette, color_no = 20, - display = TRUE, ...) + display = TRUE, rev = FALSE, ...) } \arguments{ \item{pal_func}{A function that \emph{returns the output function} from \code{\link[grDevices]{colorRamp}} or diff --git a/man/get_phyloseq_obj.Rd b/man/get_phyloseq_obj.Rd index 734999a..0fbe208 100644 --- a/man/get_phyloseq_obj.Rd +++ b/man/get_phyloseq_obj.Rd @@ -6,7 +6,8 @@ \usage{ get_phyloseq_obj(biom_file = NULL, tree_file = NULL, metadata_file = NULL, treatment_group = NULL, parse_func = NULL, - rdata_file = NULL, path = NULL) + rdata_file = NULL, save_rooted_tree = FALSE, + recursive_save = FALSE) } \arguments{ \item{biom_file}{A file in the \href{http://biom-format.org/}{BIOM format}. Default: NULL} @@ -26,7 +27,11 @@ Greengenes or SILVA database. Default: NULL} \item{rdata_file}{A .Rdata file. Default: NULL} -\item{path}{A path for the output tree file. Default: NULL} +\item{save_rooted_tree}{A logical that determines weather or not the rooted tree +is saved. Default: FALSE} + +\item{recursive_save}{If the directory doesn't exists create the parent directories +that don't exist as well. Default: FALSE} } \value{ A phyloseq object, and a phylogenetic tree file if one does not already exist. diff --git a/man/pick_new_outgroup.Rd b/man/pick_new_outgroup.Rd index 3f450e8..1834c6c 100644 --- a/man/pick_new_outgroup.Rd +++ b/man/pick_new_outgroup.Rd @@ -24,6 +24,7 @@ Please see this issue for more details \url{https://github.com/joey711/phyloseq/ \code{\link[ape]{summary.phylo}} -Other Phylogenetic Tree Manipulators: \code{\link{root_by_longest_edge}} +Other Phylogenetic Tree Manipulators: \code{\link{root_by_longest_edge}}, + \code{\link{root_phyloseq_tree}} } \concept{Phylogenetic Tree Manipulators} diff --git a/man/root_by_longest_edge.Rd b/man/root_by_longest_edge.Rd index 2ac3882..3bcaf21 100644 --- a/man/root_by_longest_edge.Rd +++ b/man/root_by_longest_edge.Rd @@ -22,6 +22,7 @@ Please see this issue for more details \url{https://github.com/joey711/phyloseq/ \code{\link[ape]{root}} \code{\link[MicrobiomeR]{pick_new_outgroup}} -Other Phylogenetic Tree Manipulators: \code{\link{pick_new_outgroup}} +Other Phylogenetic Tree Manipulators: \code{\link{pick_new_outgroup}}, + \code{\link{root_phyloseq_tree}} } \concept{Phylogenetic Tree Manipulators} diff --git a/man/root_phyloseq_tree.Rd b/man/root_phyloseq_tree.Rd new file mode 100644 index 0000000..ee68347 --- /dev/null +++ b/man/root_phyloseq_tree.Rd @@ -0,0 +1,50 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/phyloseq.R +\name{root_phyloseq_tree} +\alias{root_phyloseq_tree} +\title{Root phyloseq tree.} +\usage{ +root_phyloseq_tree(phyloseq_object, tree_path, save_rooted_tree, + recursive = TRUE) +} +\arguments{ +\item{phyloseq_object}{A phyloseq object that contains a phylogenetic tree.} + +\item{tree_path}{The path to the existing or desired phylogenetic tree file.} + +\item{save_rooted_tree}{A logical that determines weather or not the rooted tree +is saved.} + +\item{recursive}{If the directory doesn't exists create the parent directories +that don't exist as well, Default: TRUE} +} +\value{ +Returns a phyloseq object with a rooted tree. +} +\description{ +A function for rooting and saving a phylogenetic tree. +} +\details{ +This function is a helper function to get a proper phyloseq object for +downstream analysis. Some analysis requre a rooted tree. The function saves +the rooted tree in the phyloseq object. It can also save the tree as a file +if desired. +} +\examples{ +\dontrun{ +if(interactive()){ + #EXAMPLE1 + } +} +} +\seealso{ +\code{\link[ape]{root}}, \code{\link[ape]{read.tree}}, \code{\link[ape]{write.tree}} + +\code{\link[phyloseq]{phy_tree}} + +\code{\link[tools]{fileutils}} + +Other Phylogenetic Tree Manipulators: \code{\link{pick_new_outgroup}}, + \code{\link{root_by_longest_edge}} +} +\concept{Phylogenetic Tree Manipulators} diff --git a/man/viridis_magma_palette.Rd b/man/viridis_magma_palette.Rd index 49ed72b..661d171 100644 --- a/man/viridis_magma_palette.Rd +++ b/man/viridis_magma_palette.Rd @@ -6,7 +6,7 @@ \usage{ viridis_magma_palette(viridis_number = 800, viridis_range = 300:viridis_number, viridis_rev = TRUE, - magma_number = 500, magma_range = 0:magma_number, + magma_number = 500, magma_range = 50:magma_number, magma_rev = FALSE, ...) } \arguments{ diff --git a/man/vlookup.Rd b/man/vlookup.Rd index f67de3f..6012ae2 100644 --- a/man/vlookup.Rd +++ b/man/vlookup.Rd @@ -4,16 +4,16 @@ \alias{vlookup} \title{Mock Excel "VlookUp" Function} \usage{ -vlookup(lookup_data, df, match_data, return_data) +vlookup(lookup_vector, df, match_var, return_var) } \arguments{ -\item{lookup_data}{A vector of items to look up.} +\item{lookup_vector}{A vector of items to look up.} \item{df}{The dataframe to search.} -\item{match_data}{The column name to search in the dataframe.} +\item{match_var}{The column name to search in the dataframe.} -\item{return_data}{The column of data to return when matched.} +\item{return_var}{The column of data to return when matched.} } \value{ A vector that contains the items of interest. From 30eec659a76f690fc102eb703a42d5f09cdc9545 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 19:39:10 -0600 Subject: [PATCH 43/80] Fixed inconsistent @family names. --- R/utils.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/utils.R b/R/utils.R index b635e90..45cd398 100644 --- a/R/utils.R +++ b/R/utils.R @@ -20,7 +20,7 @@ #' } #' } #' @export -#' @family Formatting and Validation +#' @family Validation #' @rdname object_handler #' @seealso #' \code{\link[metacoder]{parse_phyloseq}} @@ -188,7 +188,7 @@ get_output_dir <- function(start_path=NULL, experiment=NULL, plot_type=NULL, end #' } #' } #' @export -#' @family Data Manipulation +#' @family Data Manipulators #' @rdname transposer #' @seealso #' \code{\link[tibble]{is_tibble}} @@ -284,7 +284,7 @@ transposer <- function(.data, ids = NULL, header_name, preserved_categories = TR #' } #' } #' @export -#' @family Data Manipulator +#' @family Data Manipulators #' @rdname transformer #' @seealso #' \code{\link[MicrobiomeR]{transposer}} From 33e1d2a609e337969abbcda35c8aec1bd1add367 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 19:40:30 -0600 Subject: [PATCH 44/80] Removed get-started vignette. --- vignettes/get-started.Rmd | 65 --------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 vignettes/get-started.Rmd diff --git a/vignettes/get-started.Rmd b/vignettes/get-started.Rmd deleted file mode 100644 index c52071d..0000000 --- a/vignettes/get-started.Rmd +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "Vignette Title" -author: "Vignette Author" -date: "`r Sys.Date()`" -output: rmarkdown::html_vignette -vignette: > - %\VignetteIndexEntry{Vignette Title} - %\VignetteEngine{knitr::rmarkdown} - %\VignetteEncoding{UTF-8} ---- - -```{r setup, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -``` - -Vignettes are long form documentation commonly included in packages. Because they are part of the distribution of the package, they need to be as compact as possible. The `html_vignette` output type provides a custom style sheet (and tweaks some options) to ensure that the resulting html is as small as possible. The `html_vignette` format: - -- Never uses retina figures -- Has a smaller default figure size -- Uses a custom CSS stylesheet instead of the default Twitter Bootstrap style - -## Vignette Info - -Note the various macros within the `vignette` section of the metadata block above. These are required in order to instruct R how to build the vignette. Note that you should change the `title` field and the `\VignetteIndexEntry` to match the title of your vignette. - -## Styles - -The `html_vignette` template includes a basic CSS theme. To override this theme you can specify your own CSS in the document metadata as follows: - - output: - rmarkdown::html_vignette: - css: mystyles.css - -## Figures - -The figure sizes have been customised so that you can easily put two images side-by-side. - -```{r, fig.show='hold'} -plot(1:10) -plot(10:1) -``` - -You can enable figure captions by `fig_caption: yes` in YAML: - - output: - rmarkdown::html_vignette: - fig_caption: yes - -Then you can use the chunk option `fig.cap = "Your figure caption."` in **knitr**. - -## More Examples - -You can write math expressions, e.g. $Y = X\beta + \epsilon$, footnotes^[A footnote here.], and tables, e.g. using `knitr::kable()`. - -```{r, echo=FALSE, results='asis'} -knitr::kable(head(mtcars, 10)) -``` - -Also a quote using `>`: - -> "He who gives up [code] safety for [code] speed deserves neither." -([via](https://twitter.com/hadleywickham/status/504368538874703872)) From 0cb39f5538b02213ef457adcbed439e24f907713 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 19:41:16 -0600 Subject: [PATCH 45/80] Made relevent updates including adding the Data Import reference section. --- _pkgdown.yml | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index cfe80ee..b118a41 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -14,12 +14,18 @@ authors: navbar: title: MicrobiomeR left: - - text: Home + - text: "Home" href: index.html - text: "Vignettes" menu: - - text: "Get Started" - href: articles/get-started.html + - text: "Introduction" + href: articles/introduction.html + - text: "Data Wrangling" + href: articles/data-wrangling.html + - text: "Data Filtering" + href: articles/filtering.html + - text: "Data Analysis" + href: articles/analysis.html - text: "Reference" href: reference/index.html - text: "Changelog" @@ -31,25 +37,11 @@ navbar: href: https://twitter.com/datasnakes reference: -- title: Data Processing +- title: Data Importers contents: - - as_MicrobiomeR_format - - transformer - - transposer + - get_phyloseq_obj + - parse_taxonomy_default + - parse_taxonomy_silva_128 + - parse_taxonomy_greengenes + - parse_taxonomy_qiime -- title: Alpha Diversity - contents: - - get_alpha_diversity_measures - - alpha_diversity_plot - -- title: Data Visualization - contents: - - get_color_palette - - get_heat_tree_plots - - get_correlation_plots - - stacked_barplot - -- title: Utilities - contents: - - create_pub_table - - vlookup From 64bfb02843892e473262b0dfdc3a1e52868fff00 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 19:48:37 -0600 Subject: [PATCH 46/80] Added the Data Formatting reference section. --- _pkgdown.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index b118a41..fe43efe 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -37,7 +37,7 @@ navbar: href: https://twitter.com/datasnakes reference: -- title: Data Importers +- title: Data Import contents: - get_phyloseq_obj - parse_taxonomy_default @@ -45,3 +45,9 @@ reference: - parse_taxonomy_greengenes - parse_taxonomy_qiime +- title: Data Formatting + contents: + - starts_with("as_") + - format_metacoder_object + + From b396565840d627bfe85ef9b241b6875d512207ac Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 20:02:15 -0600 Subject: [PATCH 47/80] Updated reference sections using has_concept to identify family of functions. --- _pkgdown.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index fe43efe..79f3c5d 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -37,17 +37,15 @@ navbar: href: https://twitter.com/datasnakes reference: -- title: Data Import +- title: Import contents: - get_phyloseq_obj - parse_taxonomy_default - parse_taxonomy_silva_128 - parse_taxonomy_greengenes - parse_taxonomy_qiime + - has_concept("Phylogenetic Tree Manipulators") -- title: Data Formatting +- title: Formatting contents: - - starts_with("as_") - - format_metacoder_object - - + - has_concept("Formatting") From b484abafda0164eb0d94e624a47b65b3eba64cf5 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 20:02:38 -0600 Subject: [PATCH 48/80] Added Validation reference section. --- _pkgdown.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index 79f3c5d..1b89bec 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -49,3 +49,7 @@ reference: - title: Formatting contents: - has_concept("Formatting") + +- title: Validation + contents: + - has_concept("Validation") From 5ef635a2a655bac68652f848f6953d8153746939 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 20:02:56 -0600 Subject: [PATCH 49/80] Added Filtering reference section. --- _pkgdown.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index 1b89bec..bc2e675 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -53,3 +53,8 @@ reference: - title: Validation contents: - has_concept("Validation") + +-title: Filtering + contents: + - has_concept("Data Manipulators") + - has_concept("Metacoder Filters") From 5adb643bf288c990d9cff2cdd717f7783258868d Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 20:03:40 -0600 Subject: [PATCH 50/80] Fixed spelling error in data-wrangling vignette. --- vignettes/data-wrangling.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index 8259a5e..8f0924a 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -85,7 +85,7 @@ MicrobiomeR provides a group of helpful functions that can be used to format tax * `is_*_format()` for testing if an object is in a specific format. * `as_*_format()` for converting an object to a specific format. * `order_metacoder_data()` for ordering the observation data for analysis. -* `validate_MicrobiomeR_fomrat()` for validating that the taxmap object is in a specific format. +* `validate_MicrobiomeR_format()` for validating that the taxmap object is in a specific format. ```{r message=FALSE, warning=FALSE} # Determine format From f7007af5eda4f6741b30d8a974cdd3857b29156d Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 20:05:30 -0600 Subject: [PATCH 51/80] Added Visualization reference section. --- _pkgdown.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index bc2e675..afcf96b 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -58,3 +58,9 @@ reference: contents: - has_concept("Data Manipulators") - has_concept("Metacoder Filters") + +- title: Visualization + contents: + - get_output_dir + - has_concept("Color Palettes") + - has_concept("Visualizations") From d315e9c456d0c243dd30e85c2942ed328763c78c Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 20:07:35 -0600 Subject: [PATCH 52/80] Fixed bug. --- _pkgdown.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index afcf96b..c51e327 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -54,7 +54,7 @@ reference: contents: - has_concept("Validation") --title: Filtering +- title: Filtering contents: - has_concept("Data Manipulators") - has_concept("Metacoder Filters") From 10f4d4a646cb31cb0b86b27a0954fadf081de317 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 23:20:26 -0600 Subject: [PATCH 53/80] Updated package after build and install. --- man/is_analyzed_format.Rd | 1 + man/is_basic_format.Rd | 1 + man/is_phyloseq_format.Rd | 1 + man/is_raw_format.Rd | 1 + man/metacoder_comp_func_1.Rd | 3 ++- man/object_handler.Rd | 12 ++++++++++-- man/order_metacoder_data.Rd | 1 + man/transformer.Rd | 5 ++++- man/transposer.Rd | 5 ++++- man/validate_MicrobiomeR_format.Rd | 1 + man/vlookup.Rd | 3 ++- man/which_format.Rd | 1 + 12 files changed, 29 insertions(+), 6 deletions(-) diff --git a/man/is_analyzed_format.Rd b/man/is_analyzed_format.Rd index 2774462..16c55c4 100644 --- a/man/is_analyzed_format.Rd +++ b/man/is_analyzed_format.Rd @@ -22,6 +22,7 @@ The "analyzed_format" is Level 3. in the \link{MicrobiomeR_Formats} hierarchy. Other Validation: \code{\link{is_basic_format}}, \code{\link{is_phyloseq_format}}, \code{\link{is_raw_format}}, + \code{\link{object_handler}}, \code{\link{order_metacoder_data}}, \code{\link{validate_MicrobiomeR_format}}, \code{\link{which_format}} diff --git a/man/is_basic_format.Rd b/man/is_basic_format.Rd index aa3f3e7..d95dd9c 100644 --- a/man/is_basic_format.Rd +++ b/man/is_basic_format.Rd @@ -22,6 +22,7 @@ The "basic_format" is Level 2. in the \link{MicrobiomeR_Formats} hierarchy. Other Validation: \code{\link{is_analyzed_format}}, \code{\link{is_phyloseq_format}}, \code{\link{is_raw_format}}, + \code{\link{object_handler}}, \code{\link{order_metacoder_data}}, \code{\link{validate_MicrobiomeR_format}}, \code{\link{which_format}} diff --git a/man/is_phyloseq_format.Rd b/man/is_phyloseq_format.Rd index cefa964..c50fd22 100644 --- a/man/is_phyloseq_format.Rd +++ b/man/is_phyloseq_format.Rd @@ -36,6 +36,7 @@ if(is_analyzed_format(MicrobiomeR::raw_silva)){ Other Validation: \code{\link{is_analyzed_format}}, \code{\link{is_basic_format}}, \code{\link{is_raw_format}}, + \code{\link{object_handler}}, \code{\link{order_metacoder_data}}, \code{\link{validate_MicrobiomeR_format}}, \code{\link{which_format}} diff --git a/man/is_raw_format.Rd b/man/is_raw_format.Rd index ba2621d..86fa313 100644 --- a/man/is_raw_format.Rd +++ b/man/is_raw_format.Rd @@ -36,6 +36,7 @@ if(is_raw_format(MicrobiomeR::raw_silva)){ Other Validation: \code{\link{is_analyzed_format}}, \code{\link{is_basic_format}}, \code{\link{is_phyloseq_format}}, + \code{\link{object_handler}}, \code{\link{order_metacoder_data}}, \code{\link{validate_MicrobiomeR_format}}, \code{\link{which_format}} diff --git a/man/metacoder_comp_func_1.Rd b/man/metacoder_comp_func_1.Rd index 1189f83..b7bf262 100644 --- a/man/metacoder_comp_func_1.Rd +++ b/man/metacoder_comp_func_1.Rd @@ -26,6 +26,7 @@ every combination of treatment groups. \code{\link[modes]{bimodality_coefficient}} -Other Data Manipulators: \code{\link{vlookup}} +Other Data Manipulators: \code{\link{transformer}}, + \code{\link{transposer}}, \code{\link{vlookup}} } \concept{Data Manipulators} diff --git a/man/object_handler.Rd b/man/object_handler.Rd index 290adb8..05843b7 100644 --- a/man/object_handler.Rd +++ b/man/object_handler.Rd @@ -38,5 +38,13 @@ if(interactive()){ \code{\link[metacoder]{parse_phyloseq}} \code{\link[tools]{fileutils}} -} -\concept{Formatting and Validation} + +Other Validation: \code{\link{is_analyzed_format}}, + \code{\link{is_basic_format}}, + \code{\link{is_phyloseq_format}}, + \code{\link{is_raw_format}}, + \code{\link{order_metacoder_data}}, + \code{\link{validate_MicrobiomeR_format}}, + \code{\link{which_format}} +} +\concept{Validation} diff --git a/man/order_metacoder_data.Rd b/man/order_metacoder_data.Rd index c6575d3..f50dd40 100644 --- a/man/order_metacoder_data.Rd +++ b/man/order_metacoder_data.Rd @@ -25,6 +25,7 @@ Other Validation: \code{\link{is_analyzed_format}}, \code{\link{is_basic_format}}, \code{\link{is_phyloseq_format}}, \code{\link{is_raw_format}}, + \code{\link{object_handler}}, \code{\link{validate_MicrobiomeR_format}}, \code{\link{which_format}} } diff --git a/man/transformer.Rd b/man/transformer.Rd index 97282f1..afe6c7a 100644 --- a/man/transformer.Rd +++ b/man/transformer.Rd @@ -60,5 +60,8 @@ if(interactive()){ \code{\link[MicrobiomeR]{transposer}} \code{\link[dplyr]{select_all}}, \code{\link[dplyr]{select}} \code{\link[purrr]{modify}} + +Other Data Manipulators: \code{\link{metacoder_comp_func_1}}, + \code{\link{transposer}}, \code{\link{vlookup}} } -\concept{Data Manipulator} +\concept{Data Manipulators} diff --git a/man/transposer.Rd b/man/transposer.Rd index ddf6a78..c3c0a92 100644 --- a/man/transposer.Rd +++ b/man/transposer.Rd @@ -54,5 +54,8 @@ if(interactive()){ \code{\link[tidyr]{gather}}, \code{\link[tidyr]{unite}}, \code{\link[tidyr]{spread}}, \code{\link[tidyr]{separate}} \code{\link[stringr]{str_detect}}, \code{\link[stringr]{str_count}} + +Other Data Manipulators: \code{\link{metacoder_comp_func_1}}, + \code{\link{transformer}}, \code{\link{vlookup}} } -\concept{Data Manipulation} +\concept{Data Manipulators} diff --git a/man/validate_MicrobiomeR_format.Rd b/man/validate_MicrobiomeR_format.Rd index ce86ff4..aa2010e 100644 --- a/man/validate_MicrobiomeR_format.Rd +++ b/man/validate_MicrobiomeR_format.Rd @@ -39,6 +39,7 @@ Other Validation: \code{\link{is_analyzed_format}}, \code{\link{is_basic_format}}, \code{\link{is_phyloseq_format}}, \code{\link{is_raw_format}}, + \code{\link{object_handler}}, \code{\link{order_metacoder_data}}, \code{\link{which_format}} } diff --git a/man/vlookup.Rd b/man/vlookup.Rd index 6012ae2..1b5837b 100644 --- a/man/vlookup.Rd +++ b/man/vlookup.Rd @@ -33,6 +33,7 @@ if(interactive()){ } } \seealso{ -Other Data Manipulators: \code{\link{metacoder_comp_func_1}} +Other Data Manipulators: \code{\link{metacoder_comp_func_1}}, + \code{\link{transformer}}, \code{\link{transposer}} } \concept{Data Manipulators} diff --git a/man/which_format.Rd b/man/which_format.Rd index 96dff2f..9c220bc 100644 --- a/man/which_format.Rd +++ b/man/which_format.Rd @@ -33,6 +33,7 @@ Other Validation: \code{\link{is_analyzed_format}}, \code{\link{is_basic_format}}, \code{\link{is_phyloseq_format}}, \code{\link{is_raw_format}}, + \code{\link{object_handler}}, \code{\link{order_metacoder_data}}, \code{\link{validate_MicrobiomeR_format}} } From 28d87bb409813934b9777248d39959a506456bf9 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 23:33:29 -0600 Subject: [PATCH 54/80] Bumped version to 0.1.4 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 449071c..162cc71 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: MicrobiomeR Title: Analyze Microbiome Data -Version: 0.1.2 +Version: 0.1.4 Authors@R: c( person("Robert", "Gilmore", email = "rgilmore@umc.edu", role = "cre"), person("Shaurita", "Hutchins", email = "shutchins2@umc.edu", role = "aut")) From 2b20fda21905407f5fe60e4c6de6aaaf6f68e799 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Thu, 3 Jan 2019 23:33:54 -0600 Subject: [PATCH 55/80] Added a NEWS section for 0.1.4 --- NEWS.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/NEWS.md b/NEWS.md index 580b6c4..5fc06f9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,20 @@ +# MicrobiomeR 0.1.4 + +* Added vignettes to package and pkgdown config. + * Introduction + * Data Wrangling + * Filtering + * Analysis +* Added reference sections to pkgdown config corresponding to @family tag. + * Import + * Formatting + * Validation + * Filtering + * Visualization +* Updated `vlookup` and `get_color_palette` parameters. +* Added the `root_phyloseq_tree` function. +* Fixed minor bugs in code and docs. + # MicrobiomeR 0.1.3 * Added custom css for pkgdown. From 9f7aefc5d9fedf3a06d3bce15ed336316cfcf15d Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:08:23 -0600 Subject: [PATCH 56/80] Updated README. --- README.md | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index c08485b..1c5e050 100644 --- a/README.md +++ b/README.md @@ -3,28 +3,39 @@ # MicrobiomeR -An R package for microbiome analysis combining the `phyloseq`, `metacodeR`, and `microbiome` packages into an easy to use and full featured microbiome analysis package. - -## Features - -- Standardization of data processing. - - Phyloseq for data import. - - MicrobiomeR for data validation and preprocessing. - - Metacoder for data analysis. - - Ggplot2 for data visualization. -- Publication ready figures for various ranks. - - Metacoder Heat Trees - - MicrobiomeR Correlation Plots - - MicrobiomeR Stacked Bar Charts -- Easily access taxonomic ranks from data objects. -- Import various data types from different pipelines. +An R package for microbiome analysis that incorporates [phyloseq](https://github.com/joey711/phyloseq), +[metacoder](https://github.com/grunwaldlab/metacoder), [taxa](https://github.com/ropensci/taxa), and [microbiome](https://github.com/microbiome/microbiome/) into a fully featured bioinformatics workflow. ## Installation +We are currently not on CRAN or Bioconductor: + ```r -install.packages("MicrobiomeR") +library(devtools) # Load the devtools package +install_github("vallenderlab/MicrobiomeR") # Install the package ``` +## Workflow Features + +- Standardization of data wrangling. + - Phyloseq for data import. + - Taxa for the primary data object (**Taxmap**). + - Proprietary data formatting and validation. +- Phyloseq inspired filtering for `taxa::taxmap` objects. + - Metacoder/taxa for mainstream filtering. + - Proprietary basic filtering for samples, taxonomies, and OTUs. + - Proprietary advanced filtering (phyloseq-style). + - Other Proprietary filtering functions for observation data. +- Metacoder enabled statistical analysis functions. +- Various visualization options. + - Output Directories + - Color Palettes + - Heat Trees + - Correlation Plots + - Stacked Bar Plot + - Alpha Diversity Plot + - Ordination Plot + ## Notes * Code Style based on Google's R style developed by Hadley Wickham. From b1fd853ed67f8bf6b4d1905808798cfbcd4fbbaa Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:08:40 -0600 Subject: [PATCH 57/80] Updated analysis vignette. --- vignettes/analysis.Rmd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd index 3f1e608..2e3e884 100644 --- a/vignettes/analysis.Rmd +++ b/vignettes/analysis.Rmd @@ -118,8 +118,9 @@ metacoder_obj <- as_MicrobiomeR_format(obj = metacoder_obj, format = "analyzed_f ## Visualization Visualization of taxmap objects can be done in several ways. The metacoder package primarily -produces `heat_tree()`s. MicrobiomeR does this as well, but takes care of creating default values -that the developers enjoyed in their heat tree plots. MicrobiomeR also uses ggplot2 to create +produces `heat_tree()`s for visualization, which can be used for any taxmap object. MicrobiomeR +does this as well, but takes care of creating default values that we enjoyed in our heat tree plots. +MicrobiomeR also uses ggplot2 to create `correlation_plot()`s. ```{r message=FALSE, warning=FALSE} From 731f2812821cb897f8d965e9ce7e58ceb5ed76a8 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:21:52 -0600 Subject: [PATCH 58/80] Changed sample_filter function, and updated the @family tags. --- R/metacoder.R | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/R/metacoder.R b/R/metacoder.R index edc3292..bf767ea 100644 --- a/R/metacoder.R +++ b/R/metacoder.R @@ -1,4 +1,4 @@ -#' @title Filter Samples from Metacoder Objects +#' @title Filter Samples Ids from Metacoder Objects #' @description This function provides a flexible way to filter unwanted samples from the #' \emph{"otu_abundance"} and \emph{"sample_data"} observations of a MicrobiomeR formatted object. #' @param obj A Taxmap/metacoder object. @@ -15,7 +15,7 @@ #' @examples #' \dontrun{ #' if(interactive()){ -#' # Use the sample_filter early on in your analysis +#' # Use the sample_id_filter early on in your analysis #' library(MicrobiomeR) #' library(metacoder) #' library(taxa) @@ -33,14 +33,14 @@ #' metacoder_obj <- filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) #' #' # Low Sample Filter - Remove the low samples -#' metacoder_obj <- sample_filter(obj = metacoder_obj, +#' metacoder_obj <- sample_id_filter(obj = metacoder_obj, #' .f_filter = ~sum(.), #' .f_condition = ~.>= 20, validated = TRUE) #' } #' } #' @export -#' @family Metacoder Filters -#' @rdname sample_filter +#' @family Basic Metacoder Filters +#' @rdname sample_id_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}}, \code{\link[MicrobiomeR]{transformer}} #' @@ -54,7 +54,7 @@ #' @importFrom purrr map keep #' @importFrom glue glue #' @importFrom crayon red -sample_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_condition = NULL, validated = FALSE, ...) { +sample_id_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_condition = NULL, validated = FALSE, ...) { mo_clone <- obj$clone() # Make sure the required functions are provided. if (!is.null(.f_filter) && !is.null(.f_condition)) { @@ -89,7 +89,7 @@ sample_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_conditi #' @title Filter Taxon Ids from Metacoder Objects #' @description This function provides a flexible way to filter unwanted taxon_ids from the taxmap object and from the #' observations of a MicrobiomeR formatted object. -#' @inheritParams sample_filter +#' @inheritParams sample_id_filter #' @return Returns a metacoder object with taxon_ids that pass the filters. #' @pretty_print TRUE #' @details Get the taxon_ids to keep by using purr and the user supplied transform and filter + condition formulas. @@ -122,7 +122,7 @@ sample_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_conditi #' } #' } #' @export -#' @family Metacoder Filters +#' @family Basic Metacoder Filters #' @rdname taxon_id_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}}, \code{\link[MicrobiomeR]{transposer}}, \code{\link[MicrobiomeR]{transformer}} @@ -173,7 +173,7 @@ taxon_id_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_condi #' @title Filter OTU Ids from Metacoder Objects #' @description This function provides a flexible way to filter unwanted otu_ids from the taxmap object and from the #' observations of a MicrobiomeR formatted object. -#' @inheritParams sample_filter +#' @inheritParams sample_id_filter #' @return Returns a metacoder object with otu_ids that pass the filters. #' @pretty_print TRUE #' @details Get the otu_ids to keep by using purr and the user supplied transform and filter + condition formulas. @@ -200,7 +200,7 @@ taxon_id_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_condi #' } #' } #' @export -#' @family Metacoder Filters +#' @family Basic Metacoder Filters #' @rdname otu_id_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}}, \code{\link[MicrobiomeR]{transposer}}, \code{\link[MicrobiomeR]{transformer}} @@ -274,7 +274,7 @@ otu_id_filter <- function(obj, .f_transform = NULL, .f_filter = NULL, .f_conditi #' } #' } #' @export -#' @family Metacoder Filters +#' @family Advanced Metacoder Filters #' @rdname agglomerate_metacoder #' @seealso #' \code{\link[taxa]{filter_taxa}} @@ -326,7 +326,7 @@ agglomerate_metacoder <- function(obj, rank, validated = FALSE) { #' metacoder_obj <- filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) #' #' # Low Sample Filter - Remove the low samples -#' metacoder_obj <- sample_filter(obj = metacoder_obj, +#' metacoder_obj <- sample_id_filter(obj = metacoder_obj, #' .f_filter = ~sum(.), #' .f_condition = ~.>= 20, validated = TRUE) #' @@ -338,7 +338,7 @@ agglomerate_metacoder <- function(obj, rank, validated = FALSE) { #' } #' } #' @export -#' @family Metacoder Filters +#' @family Advanced Metacoder Filters #' @rdname otu_proportion_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}},\code{\link[MicrobiomeR]{otu_id_filter}} @@ -385,7 +385,7 @@ otu_proportion_filter <- function(obj, otu_percentage = 0.00005, validated = FAL #' metacoder_obj <- filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) #' #' # Low Sample Filter - Remove the low samples -#' metacoder_obj <- sample_filter(obj = metacoder_obj, +#' metacoder_obj <- sample_id_filter(obj = metacoder_obj, #' .f_filter = ~sum(.), #' .f_condition = ~.>= 20, validated = TRUE) #' @@ -400,7 +400,7 @@ otu_proportion_filter <- function(obj, otu_percentage = 0.00005, validated = FAL #' } #' } #' @export -#' @family Metacoder Filters +#' @family Advanced Metacoder Filters #' @rdname otu_prevalence_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}} @@ -465,7 +465,7 @@ otu_prevalence_filter <- function(obj, minimum_abundance = 5, rel_sample_percent #' metacoder_obj <- filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) #' #' # Low Sample Filter - Remove the low samples -#' metacoder_obj <- sample_filter(obj = metacoder_obj, +#' metacoder_obj <- sample_id_filter(obj = metacoder_obj, #' .f_filter = ~sum(.), #' .f_condition = ~.>= 20, validated = TRUE) #' @@ -490,7 +490,7 @@ otu_prevalence_filter <- function(obj, minimum_abundance = 5, rel_sample_percent #' } #' } #' @export -#' @family Metacoder Filters +#' @family Advanced Metacoder Filters #' @rdname taxa_prevalence_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}} @@ -555,7 +555,7 @@ taxa_prevalence_filter <- function(obj, rank, minimum_abundance = 5, rel_sample_ #' metacoder_obj <- filter_ambiguous_taxa(metacoder_obj, subtaxa = TRUE) #' #' # Low Sample Filter - Remove the low samples -#' metacoder_obj <- sample_filter(obj = metacoder_obj, +#' metacoder_obj <- sample_id_filter(obj = metacoder_obj, #' .f_filter = ~sum(.), #' .f_condition = ~.>= 20, validated = TRUE) #' @@ -588,7 +588,7 @@ taxa_prevalence_filter <- function(obj, rank, minimum_abundance = 5, rel_sample_ #' } #' } #' @export -#' @family Metacoder Filters +#' @family Advanced Metacoder Filters #' @rdname cov_filter #' @seealso #' \code{\link[MicrobiomeR]{validate_MicrobiomeR_format}}, \code{\link[MicrobiomeR]{otu_id_filter}} From 5e4bf25b46d6a18fad73c514a4de9b82f2459570 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:23:28 -0600 Subject: [PATCH 59/80] Bumped to 0.2.3. --- DESCRIPTION | 2 +- NEWS.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 162cc71..437f9fd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: MicrobiomeR Title: Analyze Microbiome Data -Version: 0.1.4 +Version: 0.2.3 Authors@R: c( person("Robert", "Gilmore", email = "rgilmore@umc.edu", role = "cre"), person("Shaurita", "Hutchins", email = "shutchins2@umc.edu", role = "aut")) diff --git a/NEWS.md b/NEWS.md index 5fc06f9..ed39810 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# MicrobiomeR 0.1.4 +# MicrobiomeR 0.2.3 * Added vignettes to package and pkgdown config. * Introduction @@ -12,6 +12,7 @@ * Filtering * Visualization * Updated `vlookup` and `get_color_palette` parameters. +* Changed `sample_filter` to `sample_id_filter`. * Added the `root_phyloseq_tree` function. * Fixed minor bugs in code and docs. From 69185c41c7c5ea6ecb9884d11cf4ab053fd89cbc Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:24:12 -0600 Subject: [PATCH 60/80] Reverted to 0.2.0. --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 437f9fd..7ab6f77 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: MicrobiomeR Title: Analyze Microbiome Data -Version: 0.2.3 +Version: 0.2.0 Authors@R: c( person("Robert", "Gilmore", email = "rgilmore@umc.edu", role = "cre"), person("Shaurita", "Hutchins", email = "shutchins2@umc.edu", role = "aut")) diff --git a/NEWS.md b/NEWS.md index ed39810..765fccb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# MicrobiomeR 0.2.3 +# MicrobiomeR 0.2.0 * Added vignettes to package and pkgdown config. * Introduction From c28ce5ddcd89bc8675413060b17df6b783c627f5 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:27:02 -0600 Subject: [PATCH 61/80] Changed get_phyloseq_obj to create_phyloseq. --- R/phyloseq.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/phyloseq.R b/R/phyloseq.R index 6801dc4..7118f6f 100644 --- a/R/phyloseq.R +++ b/R/phyloseq.R @@ -36,11 +36,11 @@ #' md_file <- system.file("extdata", "nephele_metadata.txt", package = "MicrobiomeR") #' } #' # Create a phyloseq object from the data files. -#' phy_obj <- get_phyloseq_obj(biom_file = biome_file, tree_file = tree_file, metadata_file = md_file) +#' phy_obj <- create_phyloseq(biom_file = biome_file, tree_file = tree_file, metadata_file = md_file) #' } #' @export #' @family Data Importers -#' @rdname get_phyloseq_obj +#' @rdname create_phyloseq #' @seealso #' \code{\link[phyloseq]{import_biom}}, \code{\link[phyloseq:sample_data-methods]{phyloseq::sample_data()}}, \code{\link[phyloseq:phy_tree-methods]{phyloseq::phy_tree()}}, \code{\link[phyloseq]{import_qiime_sample_data}}, \code{\link[phyloseq]{merge_phyloseq}} #' @@ -50,7 +50,7 @@ #' @importFrom phyloseq import_biom sample_data phy_tree import_qiime_sample_data merge_phyloseq #' @importFrom ape is.rooted write.tree read.tree #' @importFrom tools file_path_as_absolute -get_phyloseq_obj <- function(biom_file = NULL, tree_file = NULL, metadata_file = NULL, +create_phyloseq <- function(biom_file = NULL, tree_file = NULL, metadata_file = NULL, treatment_group = NULL, parse_func = NULL, rdata_file = NULL, save_rooted_tree = FALSE, recursive_save = FALSE) { if (!is.null(rdata_file)) { From 8d279a286f79d0526c320cfaa85d61cb48773df0 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:29:52 -0600 Subject: [PATCH 62/80] Converted get_phyloseq_obj to create_phyloseq. --- R/package.R | 4 ++-- vignettes/analysis.Rmd | 4 ++-- vignettes/data-wrangling.Rmd | 4 ++-- vignettes/filtering.Rmd | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/R/package.R b/R/package.R index b2df1a0..b37950e 100644 --- a/R/package.R +++ b/R/package.R @@ -8,7 +8,7 @@ #' dependencies used to create the MicrobiomeR formats listed below: #' \describe{ #' \item{phyloseq_format}{Level 0. The "phyloseq_format" is the format given to a \emph{taxmap} object that has just -#' been converted from a \emph{phyloseq} object using \emph{metacoder} via \code{\link[MicrobiomeR]{get_phyloseq_obj}}. A taxmap object identified by MicrobiomeR +#' been converted from a \emph{phyloseq} object using \emph{metacoder} via \code{\link[MicrobiomeR]{create_phyloseq}}. A taxmap object identified by MicrobiomeR #' to be in this format will contain "otu_table", "tax_data", "sample_data" and "phy_tree" data in the observation #' tables (\strong{metacoder_obj$data}), which represents the matching \emph{phyloseq::otu_table}, \emph{phyloseq::tax_table}, #' \emph{phyloseq::sample_data}, and \emph{phyloseq::phy_tree} data in the original phyloseq object.} @@ -32,7 +32,7 @@ NULL #' packages. Primarily \strong{phyloseq}, \strong{taxa}, and \strong{metacoder}. #' #' @section Data Import: -#' Data is imported with the \code{\link[MicrobiomeR]{get_phyloseq_obj}} function or something proprietary that +#' Data is imported with the \code{\link[MicrobiomeR]{create_phyloseq}} function or something proprietary that #' creates a \code{\link[phyloseq:phyloseq-class]{phyloseq object}} with an \code{\link[phyloseq:otu_table-class]{phyloseq::otu_table}}, #' a \code{\link[phyloseq:taxonomyTable-class]{phyloseq::tax_table}}, a \code{\link[phyloseq:sample_data-class]{phyloseq::sample_data}}, #' and a \code{\link[phyloseq:phylo-class]{phyloseq::phy_tree}}. The data is preferrably not filtered diff --git a/vignettes/analysis.Rmd b/vignettes/analysis.Rmd index 2e3e884..9801335 100644 --- a/vignettes/analysis.Rmd +++ b/vignettes/analysis.Rmd @@ -29,7 +29,7 @@ metadata_file <- input_files$metadata # Path to Nephele metadata parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations # Get the phyloseq object -phy_obj <- get_phyloseq_obj(biom_file = biom_file, +phy_obj <- create_phyloseq(biom_file = biom_file, tree_file = tree_file, metadata_file = metadata_file, parse_func = parse_func) @@ -53,7 +53,7 @@ metacoder_obj <- metacoder::filter_ambiguous_taxa(metacoder_obj, # Low Sample Filter - Remove the low samples # The sample filter should generally be implemented first -metacoder_obj <- sample_filter(obj = metacoder_obj, +metacoder_obj <- sample_id_filter(obj = metacoder_obj, .f_filter = ~sum(.), .f_condition = ~.>= 20, validated = TRUE) diff --git a/vignettes/data-wrangling.Rmd b/vignettes/data-wrangling.Rmd index 8f0924a..8ef81d5 100644 --- a/vignettes/data-wrangling.Rmd +++ b/vignettes/data-wrangling.Rmd @@ -23,7 +23,7 @@ pkg.data <- MicrobiomeR:::pkg.private Importing data is done via the [phyloseq](https://github.com/joey711/phyloseq) package. [MicrobiomeR](https://github.com/vallenderlab/MicrobiomeR) was developed by testing data from [Nephele's 16S Qiime](https://nephele.niaid.nih.gov/user_guide_pipes/#amplicon_pipes) pipeline, so that will be our frame of reference for these vignettes. While one can use any phyloseq object generated by phyloseq, the -function `MicrobiomeR::get_phyloseq_obj()` will be used to import the Nephele data, which includes a [biom +function `MicrobiomeR::create_phyloseq()` will be used to import the Nephele data, which includes a [biom file](http://biom-format.org/), a phylogenetic tree file, and the metadata file ([Nephele mapping file](https://nephele.niaid.nih.gov/user_guide/)). file. @@ -40,7 +40,7 @@ metadata_file <- input_files$metadata # Path to Nephele metadata parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations # Get the phyloseq object -phyloseq_object <- get_phyloseq_obj(biom_file = biom_file, +phyloseq_object <- create_phyloseq(biom_file = biom_file, tree_file = tree_file, metadata_file = metadata_file, parse_func = parse_func) diff --git a/vignettes/filtering.Rmd b/vignettes/filtering.Rmd index fcfa03f..15f06f1 100644 --- a/vignettes/filtering.Rmd +++ b/vignettes/filtering.Rmd @@ -29,10 +29,10 @@ metadata_file <- input_files$metadata # Path to Nephele metadata parse_func <- parse_taxonomy_silva_128 # A custom phyloseq parsing function for silva annotations # Get the phyloseq object -phy_obj <- get_phyloseq_obj(biom_file = biom_file, - tree_file = tree_file, - metadata_file = metadata_file, - parse_func = parse_func) +phy_obj <- create_phyloseq(biom_file = biom_file, + tree_file = tree_file, + metadata_file = metadata_file, + parse_func = parse_func) # Get the taxmap object in the raw format raw_metacoder <- as_MicrobiomeR_format(obj = phy_obj, format = "raw_format") @@ -70,7 +70,7 @@ a filtering function (.f_filter), and a coditional function (.f_condition). ```{r message=FALSE, warning=FALSE} # Low Sample Filter - Remove the low samples # The sample filter should generally be implemented first -metacoder_obj <- sample_filter(obj = metacoder_obj, +metacoder_obj <- sample_id_filter(obj = metacoder_obj, .f_filter = ~sum(.), .f_condition = ~.>= 20, validated = TRUE) From ddb49350d7c04ab403a6f322b90ac7981134f24a Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:30:02 -0600 Subject: [PATCH 63/80] Updated pkgdown. --- _pkgdown.yml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index c51e327..ce7888d 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -39,7 +39,7 @@ navbar: reference: - title: Import contents: - - get_phyloseq_obj + - create_phyloseq - parse_taxonomy_default - parse_taxonomy_silva_128 - parse_taxonomy_greengenes @@ -54,13 +54,23 @@ reference: contents: - has_concept("Validation") -- title: Filtering +- title: Basic Filtering + contents: + - has_concept("Basic Metacoder Filters") + +- title: Advanced Filtering + contents: + - has_concept("Advanced Metacoder Filters") + +- title: Other Filtering contents: - has_concept("Data Manipulators") - - has_concept("Metacoder Filters") - title: Visualization contents: - get_output_dir - - has_concept("Color Palettes") - has_concept("Visualizations") + +- title: Color Palettes + contents: + - has_concept("Color Palettes") From f46905c838b02c94910983979fc6f156aff04fc2 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:48:55 -0600 Subject: [PATCH 64/80] Added Visualization family to save_barplot function. --- R/barplot.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/barplot.R b/R/barplot.R index 84eda5a..4390b9f 100644 --- a/R/barplot.R +++ b/R/barplot.R @@ -126,6 +126,7 @@ stacked_barplot <- function(obj, tax_level = "Phylum", fill = "Phylum", xlabel = #' } #' } #' @export +#' @family Visualizations #' @rdname save_barplot #' @seealso #' From 54f11b947991e5e9f76ca84f69587aa1546cd92d Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:49:27 -0600 Subject: [PATCH 65/80] Reorganized formatting functions and changed format_mc_obj to as_custom_format. --- R/metacoder-formatting.R | 96 ++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/R/metacoder-formatting.R b/R/metacoder-formatting.R index eb687ae..6881833 100644 --- a/R/metacoder-formatting.R +++ b/R/metacoder-formatting.R @@ -212,6 +212,51 @@ order_metacoder_data <- function(obj) { return(mo_clone) } +#' @title Validate MicrobiomeR Format +#' @description This funciton validates that taxmap/metacoder objects are in a valid format MicrobiomeR format. +#' @param obj A Taxmap/metacoder object. +#' @param validated This parameter provides a way to override validation steps. Use carefully. Default: FALSE +#' @param valid_formats A vector of formats that are used for validation. +#' @param force_format A logical denoting if the selected format is to be forced. Default: FALSE +#' @param min_or_max A base function (min or max) that determines which format is to be forced. +#' This is particularly useful if you provide multiple \emph{valid_formats}. Min will choose the lowest +#' level format, while max will choose the highest level format. Default: base::max +#' @param ... An optional list of parameters to use in \code{\link[MicrobiomeR]{as_MicrobiomeR_format}}. +#' @return If the object is validated, a Taxmap/metacoder object. +#' @details This function can provide a way to check if a taxmap object has undergone a +#' \code{\link[MicrobiomeR:MicrobiomeR_Workflow]{MicrobiomeR Style Workflow}}. +#' @export +#' @family Validation +#' @rdname validate_MicrobiomeR_format +#' @seealso +#' \code{\link[MicrobiomeR]{which_format}}, \code{\link[MicrobiomeR]{as_MicrobiomeR_format}} +#' @importFrom glue glue +#' @importFrom crayon bgWhite green yellow red +validate_MicrobiomeR_format <- function(obj, validated = FALSE, valid_formats, force_format = FALSE, min_or_max = base::max, ...) { + mo_clone <- obj$clone() + format_list <- pkg.private$format_level_list + if (validated == TRUE) { + return(mo_clone) + } + fmt <- which_format(obj = mo_clone) + rank_list <- c(format_list[[fmt]]) + high_rank <- fmt + if (fmt %in% valid_formats) { + return(mo_clone) + } else if (force_format == TRUE) { + for (v_fmt in valid_formats) { + rank_list <- c(rank_list, format_list[[v_fmt]]) + high_rank <- ifelse(format_list[[v_fmt]] >= min_or_max(rank_list), v_fmt, high_rank) + } + message(crayon::yellow(glue::glue("Forcing the metacoder object from the ", crayon::bgWhite(crayon::red({fmt})), " to the ", + crayon::bgWhite(crayon::green({high_rank})),"."))) + mo_clone <- as_MicrobiomeR_format(obj = mo_clone, format = high_rank, ...) + return(mo_clone) + } else { + stop(glue::glue("The metacoder object is not in one of the valid formats: {valid_formats}." )) + } +} + #' @title As Raw MicrobiomeR Format #' @description Converts a metacoder object to the raw_format. #' @param obj An object to be converted to a metacoder object with \code{\link[MicrobiomeR]{object_handler}}. @@ -458,7 +503,7 @@ as_phyloseq_format <- function(obj, otu_table="otu_abundance", tax_data="otu_ann return(mo_clone) } -#' @title Format Metacoder Objects +#' @title As Custom MicrobiomeR Format #' @description A function for formatting metacoder objects in the MicrobiomeR format. This function #' attempts to give more customization than the as_*_format functions. #' @param obj An object to be converted to a metacoder object with \code{\link[MicrobiomeR]{object_handler}}. @@ -471,12 +516,12 @@ as_phyloseq_format <- function(obj, otu_table="otu_abundance", tax_data="otu_ann #' @details This function is meant to be more helpful for customizing the metacoder object. #' @export #' @family Formatting -#' @rdname format_metacoder_object +#' @rdname as_custom_format #' @seealso #' \code{\link[MicrobiomeR]{object_handler}}, \code{\link[MicrobiomeR]{which_format}}, \code{\link[MicrobiomeR]{order_metacoder_data}}, \code{\link[MicrobiomeR]{as_MicrobiomeR_format}} #' @importFrom glue glue #' @importFrom crayon red -format_metacoder_object <- function(obj, format, change_name_list = NULL, ...) { +as_custom_format <- function(obj, format, change_name_list = NULL, ...) { # Metacoder Objects obj <- object_handler(obj = obj) @@ -538,48 +583,5 @@ format_metacoder_object <- function(obj, format, change_name_list = NULL, ...) { return(mo_clone) } -#' @title Validate MicrobiomeR Format -#' @description This funciton validates that taxmap/metacoder objects are in a valid format MicrobiomeR format. -#' @param obj A Taxmap/metacoder object. -#' @param validated This parameter provides a way to override validation steps. Use carefully. Default: FALSE -#' @param valid_formats A vector of formats that are used for validation. -#' @param force_format A logical denoting if the selected format is to be forced. Default: FALSE -#' @param min_or_max A base function (min or max) that determines which format is to be forced. -#' This is particularly useful if you provide multiple \emph{valid_formats}. Min will choose the lowest -#' level format, while max will choose the highest level format. Default: base::max -#' @param ... An optional list of parameters to use in \code{\link[MicrobiomeR]{as_MicrobiomeR_format}}. -#' @return If the object is validated, a Taxmap/metacoder object. -#' @details This function can provide a way to check if a taxmap object has undergone a -#' \code{\link[MicrobiomeR:MicrobiomeR_Workflow]{MicrobiomeR Style Workflow}}. -#' @export -#' @family Validation -#' @rdname validate_MicrobiomeR_format -#' @seealso -#' \code{\link[MicrobiomeR]{which_format}}, \code{\link[MicrobiomeR]{as_MicrobiomeR_format}} -#' @importFrom glue glue -#' @importFrom crayon bgWhite green yellow red -validate_MicrobiomeR_format <- function(obj, validated = FALSE, valid_formats, force_format = FALSE, min_or_max = base::max, ...) { - mo_clone <- obj$clone() - format_list <- pkg.private$format_level_list - if (validated == TRUE) { - return(mo_clone) - } - fmt <- which_format(obj = mo_clone) - rank_list <- c(format_list[[fmt]]) - high_rank <- fmt - if (fmt %in% valid_formats) { - return(mo_clone) - } else if (force_format == TRUE) { - for (v_fmt in valid_formats) { - rank_list <- c(rank_list, format_list[[v_fmt]]) - high_rank <- ifelse(format_list[[v_fmt]] >= min_or_max(rank_list), v_fmt, high_rank) - } - message(crayon::yellow(glue::glue("Forcing the metacoder object from the ", crayon::bgWhite(crayon::red({fmt})), " to the ", - crayon::bgWhite(crayon::green({high_rank})),"."))) - mo_clone <- as_MicrobiomeR_format(obj = mo_clone, format = high_rank, ...) - return(mo_clone) - } else { - stop(glue::glue("The metacoder object is not in one of the valid formats: {valid_formats}." )) - } -} + From 84f5ed1029b91138525579508626d8d9bb7bc656 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 13:49:48 -0600 Subject: [PATCH 66/80] Added the Formatting family to the MicrobiomeR_Formats section. --- R/package.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/package.R b/R/package.R index b37950e..332f1aa 100644 --- a/R/package.R +++ b/R/package.R @@ -22,7 +22,7 @@ #' processed with \code{\link[MicrobiomeR]{as_analyzed_format}}. It contains the tables available in the "basic_format" along #' with "statistical_data" and "stats_tax_data" tables.} #' } -#' +#' @family Formatting #' @name MicrobiomeR_Formats NULL From f3b0a8e78a0fb44b6bdab01fff559b7265b9b0d0 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 14:18:52 -0600 Subject: [PATCH 67/80] Fixed roxygen build bugs. --- R/MicrobiomeR-package.R | 2 +- R/heat-tree.R | 2 +- R/metacoder-formatting.R | 6 ++---- R/phyloseq.R | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/R/MicrobiomeR-package.R b/R/MicrobiomeR-package.R index 1e90720..1094bd1 100644 --- a/R/MicrobiomeR-package.R +++ b/R/MicrobiomeR-package.R @@ -17,7 +17,7 @@ #' \item{microbiome}{\url{http://microbiome.github.io/microbiome/}} #' \item{MicrobiomeR}{\url{https://github.com/vallenderlab/MicrobiomeR} #' }} -#' The [MicrobiomeR_Workflows] and [MicrobiomeR_Formats] help sections are also useful for understanding the +#' The [MicrobiomeR_Workflow] and [MicrobiomeR_Formats] help sections are also useful for understanding the #' package. #' #' diff --git a/R/heat-tree.R b/R/heat-tree.R index 406040f..cce332c 100644 --- a/R/heat-tree.R +++ b/R/heat-tree.R @@ -98,7 +98,7 @@ get_heat_tree_plots <- function(obj, rank_list = NULL, ...) { #' #' \code{\link[purrr]{list_modify}} #' -#' \code{\link[rlang]{enquos}}, \code{\link[rlang]{is_quosure}}, \code{\link[rlang]{eval_tidy}} +#' \code{\link[rlang:quotation]{enquos}}, \code{\link[rlang:quo]{is_quosure}}, \code{\link[rlang]{eval_tidy}} #' @importFrom taxa n_obs taxon_names #' @importFrom purrr list_modify #' @importFrom rlang enquos is_quosure eval_tidy diff --git a/R/metacoder-formatting.R b/R/metacoder-formatting.R index 6881833..ea677f9 100644 --- a/R/metacoder-formatting.R +++ b/R/metacoder-formatting.R @@ -106,8 +106,7 @@ is_raw_format <- function(obj) { #' print(sprintf("It's %s!", fmt)) #' } #' } -#' } -#' } +#'} #' @export #' @family Validation #' @rdname is_basic_format @@ -138,7 +137,6 @@ is_basic_format <- function(obj) { #' print(sprintf("It's %s!", fmt)) #' } #' } -#' } #' } #' @export #' @family Validation @@ -437,7 +435,7 @@ as_analyzed_format <- function(obj, cols = NULL, groups = NULL, combinations = N #' @family Formatting #' @rdname as_MicrobiomeR_format #' @seealso -#' \code{\link[MicrobiomeR]{which_format}}, \code{\link[MicrobiomeR]{as_raw_format}}, \code{\link[MicrobiomeR]{as_basic_format}}, \code{\link[MicrobiomeR]{as_analyzed_format}}, \code{\link[MicrobiomeR]{as_phyloseq_format}}, \link[MicrobiomeR]{object_handler}}, \code{\link[MicrobiomeR]{order_metacoder_data}} +#' \code{\link[MicrobiomeR]{which_format}}, \code{\link[MicrobiomeR]{as_raw_format}}, \code{\link[MicrobiomeR]{as_basic_format}}, \code{\link[MicrobiomeR]{as_analyzed_format}}, \code{\link[MicrobiomeR]{as_phyloseq_format}}, \code{\link[MicrobiomeR]{object_handler}}, \code{\link[MicrobiomeR]{order_metacoder_data}} #' @importFrom glue glue #' @importFrom crayon silver green red as_MicrobiomeR_format <- function(obj, format, ...) { diff --git a/R/phyloseq.R b/R/phyloseq.R index 7118f6f..e8318fb 100644 --- a/R/phyloseq.R +++ b/R/phyloseq.R @@ -107,7 +107,7 @@ create_phyloseq <- function(biom_file = NULL, tree_file = NULL, metadata_file = #' @seealso #' \code{\link[ape]{root}}, \code{\link[ape]{read.tree}}, \code{\link[ape]{write.tree}} #' -#' \code{\link[phyloseq]{phy_tree}} +#' \code{\link[phyloseq:phy_tree-methods]{phy_tree}} #' #' \code{\link[tools]{fileutils}} #' @importFrom ape is.rooted read.tree write.tree From 8cde9b73d148c64161a3b0fecda200393dff2931 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 17:31:50 -0600 Subject: [PATCH 68/80] Updated roxygen for heat-tree. --- R/heat-tree.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/heat-tree.R b/R/heat-tree.R index cce332c..0283e26 100644 --- a/R/heat-tree.R +++ b/R/heat-tree.R @@ -98,7 +98,7 @@ get_heat_tree_plots <- function(obj, rank_list = NULL, ...) { #' #' \code{\link[purrr]{list_modify}} #' -#' \code{\link[rlang:quotation]{enquos}}, \code{\link[rlang:quo]{is_quosure}}, \code{\link[rlang]{eval_tidy}} +#' \code{\link[rlang:quotation]{enquos}}, \code{\link[rlang:quosure]{is_quosure}}, \code{\link[rlang]{eval_tidy}} #' @importFrom taxa n_obs taxon_names #' @importFrom purrr list_modify #' @importFrom rlang enquos is_quosure eval_tidy From bd7bfe9b855bd253fffc73f723ba41c27a30ae88 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 18:14:44 -0600 Subject: [PATCH 69/80] Updated NEWS.md. --- NEWS.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 765fccb..0f68fbd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ # MicrobiomeR 0.2.0 +## Documentations + * Added vignettes to package and pkgdown config. + * About * Introduction * Data Wrangling * Filtering @@ -9,10 +12,16 @@ * Import * Formatting * Validation - * Filtering + * Filtering (Basic, Advanced, Other) * Visualization + * Color Palettes + +## Functional Changes + +* Renamed `sample_filter` to `sample_id_filter`. +* Renamed `get_phyloseq_obj` to `create_phyloseq`. +* Renamed `format_metacoder_object` to `as_custom_format`. * Updated `vlookup` and `get_color_palette` parameters. -* Changed `sample_filter` to `sample_id_filter`. * Added the `root_phyloseq_tree` function. * Fixed minor bugs in code and docs. From 2f6cd2f41194cf899530c66ed0bbc2839d61e2d6 Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 18:15:01 -0600 Subject: [PATCH 70/80] Fixed build errors. --- R/correlation-plot.R | 4 ++-- R/palettes.R | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/R/correlation-plot.R b/R/correlation-plot.R index 78ea8bf..83daccd 100644 --- a/R/correlation-plot.R +++ b/R/correlation-plot.R @@ -133,8 +133,8 @@ correlation_plot <- function(obj, primary_rank, secondary_rank = TRUE, #' @title Get Multiple Correlation Plots #' @description This function allows the user to create a list of multiple correlation plots. #' @param obj PARAM_DESCRIPTION -#' @param primary_rank A vector of primary ranks used to label the points. -#' @param secondary_rank The secondary rank used to color the points. Can be an integer specifying +#' @param primary_ranks A vector of primary ranks used to label the points. +#' @param secondary_ranks The secondary rank used to color the points. Can be an integer specifying #' the number of supertaxon ranks above the primary rank or the name of a supertaxon rank. Default: TRUE #' @param pairwise This does a pairwise comparison of the primary and secondary ranks. Default: FALSE #' @param ... An optional list of parameters to use in the correlation_plot function. diff --git a/R/palettes.R b/R/palettes.R index 95c9f51..7983fdc 100644 --- a/R/palettes.R +++ b/R/palettes.R @@ -4,6 +4,7 @@ #' a \emph{the output of the output function} from \code{\link[grDevices]{colorRamp}}. Default: viridis_magma_palette #' @param color_no The number of colors in the palette. Default: 20 #' @param display A logical for displaying a pie chart of the palette. Default: TRUE +#' @param rev A logical that will reverse the order of the color palette. #' @param ... Parameters for the \emph{pal_func}. #' @return Returns a color palette in the form of a character vector. #' @pretty_print TRUE From d05557937530943fd1edfd8d733b42bdc60f64ce Mon Sep 17 00:00:00 2001 From: RAG-home Date: Fri, 4 Jan 2019 18:17:29 -0600 Subject: [PATCH 71/80] Added built pkgdown site. --- _pkgdown.yml | 4 + docs/LICENSE-text.html | 180 ++ docs/articles/about.html | 142 + .../Proj4Leaflet-1.0.1/proj4-compressed.js | 3 + .../Proj4Leaflet-1.0.1/proj4leaflet.js | 272 ++ .../figure-html/unnamed-chunk-1-1.png | Bin 0 -> 5194 bytes .../figure-html/unnamed-chunk-1-2.png | Bin 0 -> 5152 bytes .../htmlwidgets-1.3/htmlwidgets.js | 839 ++++++ .../about_files/jquery-1.12.4/jquery.min.js | 5 + .../leaflet-1.3.1/images/layers-2x.png | Bin 0 -> 1259 bytes .../leaflet-1.3.1/images/layers.png | Bin 0 -> 696 bytes .../leaflet-1.3.1/images/marker-icon-2x.png | Bin 0 -> 2464 bytes .../leaflet-1.3.1/images/marker-icon.png | Bin 0 -> 1466 bytes .../leaflet-1.3.1/images/marker-shadow.png | Bin 0 -> 618 bytes .../about_files/leaflet-1.3.1/leaflet.css | 636 ++++ .../about_files/leaflet-1.3.1/leaflet.js | 5 + .../leaflet-binding-2.0.2/leaflet.js | 2682 +++++++++++++++++ .../leafletfix-1.0.0/leafletfix.css | 36 + .../rstudio_leaflet-1.3.1/images/1px.png | Bin 0 -> 68 bytes .../rstudio_leaflet-1.3.1/rstudio_leaflet.css | 32 + docs/articles/analysis.html | 271 ++ .../figure-html/unnamed-chunk-7-1.png | Bin 0 -> 22021 bytes .../figure-html/unnamed-chunk-7-2.png | Bin 0 -> 27889 bytes .../figure-html/unnamed-chunk-7-3.png | Bin 0 -> 31400 bytes .../figure-html/unnamed-chunk-8-1.png | Bin 0 -> 32924 bytes .../figure-html/unnamed-chunk-8-2.png | Bin 0 -> 36503 bytes .../figure-html/unnamed-chunk-8-3.png | Bin 0 -> 40632 bytes docs/articles/color-palettes.html | 350 +++ .../figure-html/unnamed-chunk-1-1.png | Bin 0 -> 5194 bytes .../figure-html/unnamed-chunk-1-2.png | Bin 0 -> 5152 bytes docs/articles/data-wrangling.html | 219 ++ docs/articles/filtering.html | 551 ++++ docs/articles/index.html | 168 ++ docs/articles/introduction.html | 148 + docs/authors.html | 70 +- docs/extra.css | 103 + docs/index.html | 125 +- docs/news/index.html | 262 ++ docs/pkgdown.css | 12 +- docs/pkgdown.js | 19 +- docs/pkgdown.yml | 12 +- docs/reference/MicrobiomeR.html | 200 ++ docs/reference/MicrobiomeR_Formats.html | 221 ++ docs/reference/MicrobiomeR_Workflow.html | 204 ++ docs/reference/agglomerate_metacoder.html | 234 ++ docs/reference/alpha_diversity_plot.html | 235 ++ docs/reference/as_MicrobiomeR_format.html | 218 ++ docs/reference/as_analyzed_format.html | 233 ++ docs/reference/as_basic_format.html | 218 ++ docs/reference/as_custom_format.html | 224 ++ docs/reference/as_phyloseq_format.html | 227 ++ docs/reference/as_raw_format.html | 210 ++ docs/reference/combination_palette.html | 249 ++ docs/reference/correlation_plot.html | 245 ++ docs/reference/cov_filter.html | 275 ++ docs/reference/create_phyloseq.html | 267 ++ docs/reference/create_pub_table.html | 66 +- .../get_alpha_diversity_measures.html | 212 ++ docs/reference/get_color_palette.html | 238 ++ docs/reference/get_correlation_plots.html | 243 ++ docs/reference/get_heat_tree_parameters.html | 221 ++ docs/reference/get_heat_tree_plots.html | 232 ++ docs/reference/get_output_dir.html | 255 ++ docs/reference/get_plot_limits.html | 209 ++ docs/reference/index.html | 380 ++- docs/reference/is_analyzed_format.html | 224 ++ docs/reference/is_basic_format.html | 224 ++ docs/reference/is_phyloseq_format.html | 224 ++ docs/reference/is_raw_format.html | 224 ++ docs/reference/melt_metacoder.html | 191 ++ docs/reference/metacoder_comp_func_1.html | 211 ++ docs/reference/object_handler.html | 227 ++ docs/reference/order_metacoder_data.html | 211 ++ docs/reference/ordination_plot.html | 229 ++ docs/reference/otu_id_filter.html | 254 ++ docs/reference/otu_prevalence_filter.html | 262 ++ docs/reference/otu_proportion_filter.html | 253 ++ docs/reference/parse_taxonomy_silva_128.html | 76 +- docs/reference/phyloseq_greengenes.html | 196 ++ docs/reference/phyloseq_silva.html | 196 ++ docs/reference/pick_new_outgroup.html | 73 +- docs/reference/pipe.html | 66 +- docs/reference/raw_greengenes.html | 204 ++ docs/reference/raw_silva.html | 204 ++ docs/reference/root_by_longest_edge.html | 72 +- docs/reference/root_phyloseq_tree.html | 233 ++ docs/reference/sample_id_filter.html | 261 ++ docs/reference/save_barplot.html | 212 ++ docs/reference/save_correlation_plots.html | 244 ++ docs/reference/save_heat_tree_plots.html | 240 ++ docs/reference/scico_palette.html | 229 ++ docs/reference/stacked_barplot.html | 243 ++ docs/reference/taxa_prevalence_filter.html | 276 ++ docs/reference/taxon_id_filter.html | 260 ++ docs/reference/transform_metacoder.html | 195 ++ docs/reference/transformer.html | 259 ++ docs/reference/transposer.html | 246 ++ .../validate_MicrobiomeR_format.html | 234 ++ docs/reference/viridis_magma_palette.html | 257 ++ docs/reference/viridis_palette.html | 229 ++ docs/reference/vlookup.html | 225 ++ docs/reference/which_format.html | 221 ++ 102 files changed, 20363 insertions(+), 184 deletions(-) create mode 100644 docs/LICENSE-text.html create mode 100644 docs/articles/about.html create mode 100644 docs/articles/about_files/Proj4Leaflet-1.0.1/proj4-compressed.js create mode 100644 docs/articles/about_files/Proj4Leaflet-1.0.1/proj4leaflet.js create mode 100644 docs/articles/about_files/figure-html/unnamed-chunk-1-1.png create mode 100644 docs/articles/about_files/figure-html/unnamed-chunk-1-2.png create mode 100644 docs/articles/about_files/htmlwidgets-1.3/htmlwidgets.js create mode 100644 docs/articles/about_files/jquery-1.12.4/jquery.min.js create mode 100644 docs/articles/about_files/leaflet-1.3.1/images/layers-2x.png create mode 100644 docs/articles/about_files/leaflet-1.3.1/images/layers.png create mode 100644 docs/articles/about_files/leaflet-1.3.1/images/marker-icon-2x.png create mode 100644 docs/articles/about_files/leaflet-1.3.1/images/marker-icon.png create mode 100644 docs/articles/about_files/leaflet-1.3.1/images/marker-shadow.png create mode 100644 docs/articles/about_files/leaflet-1.3.1/leaflet.css create mode 100644 docs/articles/about_files/leaflet-1.3.1/leaflet.js create mode 100644 docs/articles/about_files/leaflet-binding-2.0.2/leaflet.js create mode 100644 docs/articles/about_files/leafletfix-1.0.0/leafletfix.css create mode 100644 docs/articles/about_files/rstudio_leaflet-1.3.1/images/1px.png create mode 100644 docs/articles/about_files/rstudio_leaflet-1.3.1/rstudio_leaflet.css create mode 100644 docs/articles/analysis.html create mode 100644 docs/articles/analysis_files/figure-html/unnamed-chunk-7-1.png create mode 100644 docs/articles/analysis_files/figure-html/unnamed-chunk-7-2.png create mode 100644 docs/articles/analysis_files/figure-html/unnamed-chunk-7-3.png create mode 100644 docs/articles/analysis_files/figure-html/unnamed-chunk-8-1.png create mode 100644 docs/articles/analysis_files/figure-html/unnamed-chunk-8-2.png create mode 100644 docs/articles/analysis_files/figure-html/unnamed-chunk-8-3.png create mode 100644 docs/articles/color-palettes.html create mode 100644 docs/articles/color-palettes_files/figure-html/unnamed-chunk-1-1.png create mode 100644 docs/articles/color-palettes_files/figure-html/unnamed-chunk-1-2.png create mode 100644 docs/articles/data-wrangling.html create mode 100644 docs/articles/filtering.html create mode 100644 docs/articles/index.html create mode 100644 docs/articles/introduction.html create mode 100644 docs/extra.css create mode 100644 docs/news/index.html create mode 100644 docs/reference/MicrobiomeR.html create mode 100644 docs/reference/MicrobiomeR_Formats.html create mode 100644 docs/reference/MicrobiomeR_Workflow.html create mode 100644 docs/reference/agglomerate_metacoder.html create mode 100644 docs/reference/alpha_diversity_plot.html create mode 100644 docs/reference/as_MicrobiomeR_format.html create mode 100644 docs/reference/as_analyzed_format.html create mode 100644 docs/reference/as_basic_format.html create mode 100644 docs/reference/as_custom_format.html create mode 100644 docs/reference/as_phyloseq_format.html create mode 100644 docs/reference/as_raw_format.html create mode 100644 docs/reference/combination_palette.html create mode 100644 docs/reference/correlation_plot.html create mode 100644 docs/reference/cov_filter.html create mode 100644 docs/reference/create_phyloseq.html create mode 100644 docs/reference/get_alpha_diversity_measures.html create mode 100644 docs/reference/get_color_palette.html create mode 100644 docs/reference/get_correlation_plots.html create mode 100644 docs/reference/get_heat_tree_parameters.html create mode 100644 docs/reference/get_heat_tree_plots.html create mode 100644 docs/reference/get_output_dir.html create mode 100644 docs/reference/get_plot_limits.html create mode 100644 docs/reference/is_analyzed_format.html create mode 100644 docs/reference/is_basic_format.html create mode 100644 docs/reference/is_phyloseq_format.html create mode 100644 docs/reference/is_raw_format.html create mode 100644 docs/reference/melt_metacoder.html create mode 100644 docs/reference/metacoder_comp_func_1.html create mode 100644 docs/reference/object_handler.html create mode 100644 docs/reference/order_metacoder_data.html create mode 100644 docs/reference/ordination_plot.html create mode 100644 docs/reference/otu_id_filter.html create mode 100644 docs/reference/otu_prevalence_filter.html create mode 100644 docs/reference/otu_proportion_filter.html create mode 100644 docs/reference/phyloseq_greengenes.html create mode 100644 docs/reference/phyloseq_silva.html create mode 100644 docs/reference/raw_greengenes.html create mode 100644 docs/reference/raw_silva.html create mode 100644 docs/reference/root_phyloseq_tree.html create mode 100644 docs/reference/sample_id_filter.html create mode 100644 docs/reference/save_barplot.html create mode 100644 docs/reference/save_correlation_plots.html create mode 100644 docs/reference/save_heat_tree_plots.html create mode 100644 docs/reference/scico_palette.html create mode 100644 docs/reference/stacked_barplot.html create mode 100644 docs/reference/taxa_prevalence_filter.html create mode 100644 docs/reference/taxon_id_filter.html create mode 100644 docs/reference/transform_metacoder.html create mode 100644 docs/reference/transformer.html create mode 100644 docs/reference/transposer.html create mode 100644 docs/reference/validate_MicrobiomeR_format.html create mode 100644 docs/reference/viridis_magma_palette.html create mode 100644 docs/reference/viridis_palette.html create mode 100644 docs/reference/vlookup.html create mode 100644 docs/reference/which_format.html diff --git a/_pkgdown.yml b/_pkgdown.yml index ce7888d..2698df4 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -26,10 +26,14 @@ navbar: href: articles/filtering.html - text: "Data Analysis" href: articles/analysis.html + - text: "Color Palettes" + href: articles/color-palettes.html - text: "Reference" href: reference/index.html - text: "Changelog" href: news/index.html + - text: "About" + href: articles/about.html right: - icon: fa-github href: https://github.com/vallenderlab/MicrobiomeR diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html new file mode 100644 index 0000000..685847f --- /dev/null +++ b/docs/LICENSE-text.html @@ -0,0 +1,180 @@ + + + + + + + + +License • MicrobiomeR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
MIT License
+
+Copyright (c) 2018 Vallender Lab
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+ +
+ +
+ + + +
+ + + + + + diff --git a/docs/articles/about.html b/docs/articles/about.html new file mode 100644 index 0000000..1b2113d --- /dev/null +++ b/docs/articles/about.html @@ -0,0 +1,142 @@ + + + + + + + +About • MicrobiomeR + + + + + + + + + + +
+
+ + + +
+ + +
+
+ + + + +

The MicrobiomeR package was developed at the University of Mississippi Medical Center in Dr. Eric Vallender’s lab by Rob Gilmore and Shaurita Hutchins.

+

The study associated with this package was conducted by Xiao Zhang.

+
+ +
+ + + +
+ + + +
+ + + + + diff --git a/docs/articles/about_files/Proj4Leaflet-1.0.1/proj4-compressed.js b/docs/articles/about_files/Proj4Leaflet-1.0.1/proj4-compressed.js new file mode 100644 index 0000000..b777613 --- /dev/null +++ b/docs/articles/about_files/Proj4Leaflet-1.0.1/proj4-compressed.js @@ -0,0 +1,3 @@ +!function(a){if("object"==typeof exports)module.exports=a();else if("function"==typeof define&&define.amd)define(a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.proj4=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gf;f++)if(!b||2!==f||void 0!==c.z)switch(0===f?(d=g,e="x"):1===f?(d=h,e="y"):(d=i,e="z"),a.axis[f]){case"e":c[e]=d;break;case"w":c[e]=-d;break;case"n":c[e]=d;break;case"s":c[e]=-d;break;case"u":void 0!==c[e]&&(c.z=d);break;case"d":void 0!==c[e]&&(c.z=-d);break;default:return null}return c}},{}],4:[function(a,b,c){var d=Math.PI/2,e=a("./sign");b.exports=function(a){return Math.abs(a)1&&(a=a>1?1:-1),Math.asin(a)}},{}],7:[function(a,b,c){b.exports=function(a){return 1-.25*a*(1+a/16*(3+1.25*a))}},{}],8:[function(a,b,c){b.exports=function(a){return.375*a*(1+.25*a*(1+.46875*a))}},{}],9:[function(a,b,c){b.exports=function(a){return.05859375*a*a*(1+.75*a)}},{}],10:[function(a,b,c){b.exports=function(a){return a*a*a*(35/3072)}},{}],11:[function(a,b,c){b.exports=function(a,b,c){var d=b*c;return a/Math.sqrt(1-d*d)}},{}],12:[function(a,b,c){b.exports=function(a,b,c,d,e){var f,g;f=a/b;for(var h=0;15>h;h++)if(g=(a-(b*f-c*Math.sin(2*f)+d*Math.sin(4*f)-e*Math.sin(6*f)))/(b-2*c*Math.cos(2*f)+4*d*Math.cos(4*f)-6*e*Math.cos(6*f)),f+=g,Math.abs(g)<=1e-10)return f;return NaN}},{}],13:[function(a,b,c){var d=Math.PI/2;b.exports=function(a,b){var c=1-(1-a*a)/(2*a)*Math.log((1-a)/(1+a));if(Math.abs(Math.abs(b)-c)<1e-6)return 0>b?-1*d:d;for(var e,f,g,h,i=Math.asin(.5*b),j=0;30>j;j++)if(f=Math.sin(i),g=Math.cos(i),h=a*f,e=Math.pow(1-h*h,2)/(2*g)*(b/(1-a*a)-f/(1-h*h)+.5/a*Math.log((1-h)/(1+h))),i+=e,Math.abs(e)<=1e-10)return i;return NaN}},{}],14:[function(a,b,c){b.exports=function(a,b,c,d,e){return a*e-b*Math.sin(2*e)+c*Math.sin(4*e)-d*Math.sin(6*e)}},{}],15:[function(a,b,c){b.exports=function(a,b,c){var d=a*b;return c/Math.sqrt(1-d*d)}},{}],16:[function(a,b,c){var d=Math.PI/2;b.exports=function(a,b){for(var c,e,f=.5*a,g=d-2*Math.atan(b),h=0;15>=h;h++)if(c=a*Math.sin(g),e=d-2*Math.atan(b*Math.pow((1-c)/(1+c),f))-g,g+=e,Math.abs(e)<=1e-10)return g;return-9999}},{}],17:[function(a,b,c){var d=1,e=.25,f=.046875,g=.01953125,h=.01068115234375,i=.75,j=.46875,k=.013020833333333334,l=.007120768229166667,m=.3645833333333333,n=.005696614583333333,o=.3076171875;b.exports=function(a){var b=[];b[0]=d-a*(e+a*(f+a*(g+a*h))),b[1]=a*(i-a*(f+a*(g+a*h)));var c=a*a;return b[2]=c*(j-a*(k+a*l)),c*=a,b[3]=c*(m-a*n),b[4]=c*a*o,b}},{}],18:[function(a,b,c){var d=a("./pj_mlfn"),e=1e-10,f=20;b.exports=function(a,b,c){for(var g=1/(1-b),h=a,i=f;i;--i){var j=Math.sin(h),k=1-b*j*j;if(k=(d(h,j,Math.cos(h),c)-a)*(k*Math.sqrt(k))*g,h-=k,Math.abs(k)1e-7?(c=a*b,(1-a*a)*(b/(1-c*c)-.5/a*Math.log((1-c)/(1+c)))):2*b}},{}],21:[function(a,b,c){b.exports=function(a){return 0>a?-1:1}},{}],22:[function(a,b,c){b.exports=function(a,b){return Math.pow((1-a)/(1+a),b)}},{}],23:[function(a,b,c){b.exports=function(a){var b={x:a[0],y:a[1]};return a.length>2&&(b.z=a[2]),a.length>3&&(b.m=a[3]),b}},{}],24:[function(a,b,c){var d=Math.PI/2;b.exports=function(a,b,c){var e=a*c,f=.5*a;return e=Math.pow((1-e)/(1+e),f),Math.tan(.5*(d-b))/e}},{}],25:[function(a,b,c){c.wgs84={towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},c.ch1903={towgs84:"674.374,15.056,405.346",ellipse:"bessel",datumName:"swiss"},c.ggrs87={towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},c.nad83={towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},c.nad27={nadgrids:"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},c.potsdam={towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},c.carthage={towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},c.hermannskogel={towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},c.ire65={towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},c.rassadiran={towgs84:"-133.63,-157.5,-158.62",ellipse:"intl",datumName:"Rassadiran"},c.nzgd49={towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},c.osgb36={towgs84:"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"},c.s_jtsk={towgs84:"589,76,480",ellipse:"bessel",datumName:"S-JTSK (Ferro)"},c.beduaram={towgs84:"-106,-87,188",ellipse:"clrk80",datumName:"Beduaram"},c.gunung_segara={towgs84:"-403,684,41",ellipse:"bessel",datumName:"Gunung Segara Jakarta"},c.rnb72={towgs84:"106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",ellipse:"intl",datumName:"Reseau National Belge 1972"}},{}],26:[function(a,b,c){c.MERIT={a:6378137,rf:298.257,ellipseName:"MERIT 1983"},c.SGS85={a:6378136,rf:298.257,ellipseName:"Soviet Geodetic System 85"},c.GRS80={a:6378137,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},c.IAU76={a:6378140,rf:298.257,ellipseName:"IAU 1976"},c.airy={a:6377563.396,b:6356256.91,ellipseName:"Airy 1830"},c.APL4={a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},c.NWL9D={a:6378145,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},c.mod_airy={a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},c.andrae={a:6377104.43,rf:300,ellipseName:"Andrae 1876 (Den., Iclnd.)"},c.aust_SA={a:6378160,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},c.GRS67={a:6378160,rf:298.247167427,ellipseName:"GRS 67(IUGG 1967)"},c.bessel={a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},c.bess_nam={a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},c.clrk66={a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},c.clrk80={a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},c.clrk58={a:6378293.645208759,rf:294.2606763692654,ellipseName:"Clarke 1858"},c.CPM={a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},c.delmbr={a:6376428,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},c.engelis={a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},c.evrst30={a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},c.evrst48={a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},c.evrst56={a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},c.evrst69={a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},c.evrstSS={a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},c.fschr60={a:6378166,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},c.fschr60m={a:6378155,rf:298.3,ellipseName:"Fischer 1960"},c.fschr68={a:6378150,rf:298.3,ellipseName:"Fischer 1968"},c.helmert={a:6378200,rf:298.3,ellipseName:"Helmert 1906"},c.hough={a:6378270,rf:297,ellipseName:"Hough"},c.intl={a:6378388,rf:297,ellipseName:"International 1909 (Hayford)"},c.kaula={a:6378163,rf:298.24,ellipseName:"Kaula 1961"},c.lerch={a:6378139,rf:298.257,ellipseName:"Lerch 1979"},c.mprts={a:6397300,rf:191,ellipseName:"Maupertius 1738"},c.new_intl={a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},c.plessis={a:6376523,rf:6355863,ellipseName:"Plessis 1817 (France)"},c.krass={a:6378245,rf:298.3,ellipseName:"Krassovsky, 1942"},c.SEasia={a:6378155,b:6356773.3205,ellipseName:"Southeast Asia"},c.walbeck={a:6376896,b:6355834.8467,ellipseName:"Walbeck"},c.WGS60={a:6378165,rf:298.3,ellipseName:"WGS 60"},c.WGS66={a:6378145,rf:298.25,ellipseName:"WGS 66"},c.WGS7={a:6378135,rf:298.26,ellipseName:"WGS 72"},c.WGS84={a:6378137,rf:298.257223563,ellipseName:"WGS 84"},c.sphere={a:6370997,b:6370997,ellipseName:"Normal Sphere (r=6370997)"}},{}],27:[function(a,b,c){c.greenwich=0,c.lisbon=-9.131906111111,c.paris=2.337229166667,c.bogota=-74.080916666667,c.madrid=-3.687938888889,c.rome=12.452333333333,c.bern=7.439583333333,c.jakarta=106.807719444444,c.ferro=-17.666666666667,c.brussels=4.367975,c.stockholm=18.058277777778,c.athens=23.7163375,c.oslo=10.722916666667},{}],28:[function(a,b,c){c.ft={to_meter:.3048},c["us-ft"]={to_meter:1200/3937}},{}],29:[function(a,b,c){function d(a,b,c){var d;return Array.isArray(c)?(d=g(a,b,c),3===c.length?[d.x,d.y,d.z]:[d.x,d.y]):g(a,b,c)}function e(a){return a instanceof f?a:a.oProj?a.oProj:f(a)}function proj4(a,b,c){a=e(a);var f,g=!1;return"undefined"==typeof b?(b=a,a=h,g=!0):("undefined"!=typeof b.x||Array.isArray(b))&&(c=b,b=a,a=h,g=!0),b=e(b),c?d(a,b,c):(f={forward:function(c){return d(a,b,c)},inverse:function(c){return d(b,a,c)}},g&&(f.oProj=b),f)}var f=a("./Proj"),g=a("./transform"),h=f("WGS84");b.exports=proj4},{"./Proj":2,"./transform":65}],30:[function(a,b,c){var d=Math.PI/2,e=1,f=2,g=3,h=4,i=5,j=484813681109536e-20,k=1.0026,l=.3826834323650898,m=function(a){return this instanceof m?(this.datum_type=h,void(a&&(a.datumCode&&"none"===a.datumCode&&(this.datum_type=i),a.datum_params&&(this.datum_params=a.datum_params.map(parseFloat),(0!==this.datum_params[0]||0!==this.datum_params[1]||0!==this.datum_params[2])&&(this.datum_type=e),this.datum_params.length>3&&(0!==this.datum_params[3]||0!==this.datum_params[4]||0!==this.datum_params[5]||0!==this.datum_params[6])&&(this.datum_type=f,this.datum_params[3]*=j,this.datum_params[4]*=j,this.datum_params[5]*=j,this.datum_params[6]=this.datum_params[6]/1e6+1)),this.datum_type=a.grids?g:this.datum_type,this.a=a.a,this.b=a.b,this.es=a.es,this.ep2=a.ep2,this.datum_type===g&&(this.grids=a.grids)))):new m(a)};m.prototype={compare_datums:function(a){return this.datum_type!==a.datum_type?!1:this.a!==a.a||Math.abs(this.es-a.es)>5e-11?!1:this.datum_type===e?this.datum_params[0]===a.datum_params[0]&&this.datum_params[1]===a.datum_params[1]&&this.datum_params[2]===a.datum_params[2]:this.datum_type===f?this.datum_params[0]===a.datum_params[0]&&this.datum_params[1]===a.datum_params[1]&&this.datum_params[2]===a.datum_params[2]&&this.datum_params[3]===a.datum_params[3]&&this.datum_params[4]===a.datum_params[4]&&this.datum_params[5]===a.datum_params[5]&&this.datum_params[6]===a.datum_params[6]:this.datum_type===g||a.datum_type===g?this.nadgrids===a.nadgrids:!0},geodetic_to_geocentric:function(a){var b,c,e,f,g,h,i,j=a.x,k=a.y,l=a.z?a.z:0,m=0;if(-d>k&&k>-1.001*d)k=-d;else if(k>d&&1.001*d>k)k=d;else if(-d>k||k>d)return null;return j>Math.PI&&(j-=2*Math.PI),g=Math.sin(k),i=Math.cos(k),h=g*g,f=this.a/Math.sqrt(1-this.es*h),b=(f+l)*i*Math.cos(j),c=(f+l)*i*Math.sin(j),e=(f*(1-this.es)+l)*g,a.x=b,a.y=c,a.z=e,m},geocentric_to_geodetic:function(a){var b,c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=1e-12,u=t*t,v=30,w=a.x,x=a.y,y=a.z?a.z:0;if(o=!1,b=Math.sqrt(w*w+x*x),c=Math.sqrt(w*w+x*x+y*y),b/this.au&&v>p);return r=Math.atan(m/Math.abs(l)),a.x=q,a.y=r,a.z=s,a},geocentric_to_geodetic_noniter:function(a){var b,c,e,f,g,h,i,j,m,n,o,p,q,r,s,t,u,v=a.x,w=a.y,x=a.z?a.z:0;if(v=parseFloat(v),w=parseFloat(w),x=parseFloat(x),u=!1,0!==v)b=Math.atan2(w,v);else if(w>0)b=d;else if(0>w)b=-d;else if(u=!0,b=0,x>0)c=d;else{if(!(0>x))return c=d,void(e=-this.b);c=-d}return g=v*v+w*w,f=Math.sqrt(g),h=x*k,j=Math.sqrt(h*h+g),n=h/j,p=f/j,o=n*n*n,i=x+this.b*this.ep2*o,t=f-this.a*this.es*p*p*p,m=Math.sqrt(i*i+t*t),q=i/m,r=t/m,s=this.a/Math.sqrt(1-this.es*q*q),e=r>=l?f/r-s:-l>=r?f/-r-s:x/q+s*(this.es-1),u===!1&&(c=Math.atan(q/r)),a.x=b,a.y=c,a.z=e,a},geocentric_to_wgs84:function(a){if(this.datum_type===e)a.x+=this.datum_params[0],a.y+=this.datum_params[1],a.z+=this.datum_params[2];else if(this.datum_type===f){var b=this.datum_params[0],c=this.datum_params[1],d=this.datum_params[2],g=this.datum_params[3],h=this.datum_params[4],i=this.datum_params[5],j=this.datum_params[6],k=j*(a.x-i*a.y+h*a.z)+b,l=j*(i*a.x+a.y-g*a.z)+c,m=j*(-h*a.x+g*a.y+a.z)+d;a.x=k,a.y=l,a.z=m}},geocentric_from_wgs84:function(a){if(this.datum_type===e)a.x-=this.datum_params[0],a.y-=this.datum_params[1],a.z-=this.datum_params[2];else if(this.datum_type===f){var b=this.datum_params[0],c=this.datum_params[1],d=this.datum_params[2],g=this.datum_params[3],h=this.datum_params[4],i=this.datum_params[5],j=this.datum_params[6],k=(a.x-b)/j,l=(a.y-c)/j,m=(a.z-d)/j;a.x=k+i*l-h*m,a.y=-i*k+l+g*m,a.z=h*k-g*l+m}}},b.exports=m},{}],31:[function(a,b,c){var d=1,e=2,f=3,g=5,h=6378137,i=.006694379990141316;b.exports=function(a,b,c){function j(a){return a===d||a===e}var k,l,m;if(a.compare_datums(b))return c;if(a.datum_type===g||b.datum_type===g)return c;var n=a.a,o=a.es,p=b.a,q=b.es,r=a.datum_type;if(r===f)if(0===this.apply_gridshift(a,0,c))a.a=h,a.es=i;else{if(!a.datum_params)return a.a=n,a.es=a.es,c;for(k=1,l=0,m=a.datum_params.length;m>l;l++)k*=a.datum_params[l];if(0===k)return a.a=n,a.es=a.es,c;r=a.datum_params.length>3?e:d}return b.datum_type===f&&(b.a=h,b.es=i),(a.es!==b.es||a.a!==b.a||j(r)||j(b.datum_type))&&(a.geodetic_to_geocentric(c),j(a.datum_type)&&a.geocentric_to_wgs84(c),j(b.datum_type)&&b.geocentric_from_wgs84(c),b.geocentric_to_geodetic(c)),b.datum_type===f&&this.apply_gridshift(b,1,c),a.a=n,a.es=o,b.a=p,b.es=q,c}},{}],32:[function(a,b,c){function d(a){var b=this;if(2===arguments.length){var c=arguments[1];"string"==typeof c?"+"===c.charAt(0)?d[a]=f(arguments[1]):d[a]=g(arguments[1]):d[a]=c}else if(1===arguments.length){if(Array.isArray(a))return a.map(function(a){Array.isArray(a)?d.apply(b,a):d(a)});if("string"==typeof a){if(a in d)return d[a]}else"EPSG"in a?d["EPSG:"+a.EPSG]=a:"ESRI"in a?d["ESRI:"+a.ESRI]=a:"IAU2000"in a?d["IAU2000:"+a.IAU2000]=a:console.log(a);return}}var e=a("./global"),f=a("./projString"),g=a("./wkt");e(d),b.exports=d},{"./global":35,"./projString":38,"./wkt":66}],33:[function(a,b,c){var d=a("./constants/Datum"),e=a("./constants/Ellipsoid"),f=a("./extend"),g=a("./datum"),h=1e-10,i=.16666666666666666,j=.04722222222222222,k=.022156084656084655;b.exports=function(a){if(a.datumCode&&"none"!==a.datumCode){var b=d[a.datumCode];b&&(a.datum_params=b.towgs84?b.towgs84.split(","):null,a.ellps=b.ellipse,a.datumName=b.datumName?b.datumName:a.datumCode)}if(!a.a){var c=e[a.ellps]?e[a.ellps]:e.WGS84;f(a,c)}return a.rf&&!a.b&&(a.b=(1-1/a.rf)*a.a),(0===a.rf||Math.abs(a.a-a.b)d?this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1):this.ns0=this.con,this.c=this.ms1*this.ms1+this.ns0*this.qs1,this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0)},c.forward=function(a){var b=a.x,c=a.y;this.sin_phi=Math.sin(c),this.cos_phi=Math.cos(c);var d=f(this.e3,this.sin_phi,this.cos_phi),e=this.a*Math.sqrt(this.c-this.ns0*d)/this.ns0,h=this.ns0*g(b-this.long0),i=e*Math.sin(h)+this.x0,j=this.rh-e*Math.cos(h)+this.y0;return a.x=i,a.y=j,a},c.inverse=function(a){var b,c,d,e,f,h;return a.x-=this.x0,a.y=this.rh-a.y+this.y0,this.ns0>=0?(b=Math.sqrt(a.x*a.x+a.y*a.y),d=1):(b=-Math.sqrt(a.x*a.x+a.y*a.y),d=-1),e=0,0!==b&&(e=Math.atan2(d*a.x,d*a.y)),d=b*this.ns0/this.a,this.sphere?h=Math.asin((this.c-d*d)/(2*this.ns0)):(c=(this.c-d*d)/this.ns0,h=this.phi1z(this.e3,c)),f=g(e/this.ns0+this.long0),a.x=f,a.y=h,a},c.phi1z=function(a,b){var c,e,f,g,i,j=h(.5*b);if(d>a)return j;for(var k=a*a,l=1;25>=l;l++)if(c=Math.sin(j),e=Math.cos(j),f=a*c,g=1-f*f,i=.5*g*g/e*(b/(1-k)-c/g+.5/a*Math.log((1-f)/(1+f))),j+=i,Math.abs(i)<=1e-7)return j;return null},c.names=["Albers_Conic_Equal_Area","Albers","aea"]},{"../common/adjust_lon":5,"../common/asinz":6,"../common/msfnz":15,"../common/qsfnz":20}],41:[function(a,b,c){var d=a("../common/adjust_lon"),e=Math.PI/2,f=1e-10,g=a("../common/mlfn"),h=a("../common/e0fn"),i=a("../common/e1fn"),j=a("../common/e2fn"),k=a("../common/e3fn"),l=a("../common/gN"),m=a("../common/asinz"),n=a("../common/imlfn");c.init=function(){this.sin_p12=Math.sin(this.lat0),this.cos_p12=Math.cos(this.lat0)},c.forward=function(a){var b,c,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H=a.x,I=a.y,J=Math.sin(a.y),K=Math.cos(a.y),L=d(H-this.long0);return this.sphere?Math.abs(this.sin_p12-1)<=f?(a.x=this.x0+this.a*(e-I)*Math.sin(L),a.y=this.y0-this.a*(e-I)*Math.cos(L),a):Math.abs(this.sin_p12+1)<=f?(a.x=this.x0+this.a*(e+I)*Math.sin(L),a.y=this.y0+this.a*(e+I)*Math.cos(L),a):(B=this.sin_p12*J+this.cos_p12*K*Math.cos(L),z=Math.acos(B),A=z/Math.sin(z),a.x=this.x0+this.a*A*K*Math.sin(L),a.y=this.y0+this.a*A*(this.cos_p12*J-this.sin_p12*K*Math.cos(L)),a):(b=h(this.es),c=i(this.es),m=j(this.es),n=k(this.es),Math.abs(this.sin_p12-1)<=f?(o=this.a*g(b,c,m,n,e),p=this.a*g(b,c,m,n,I),a.x=this.x0+(o-p)*Math.sin(L),a.y=this.y0-(o-p)*Math.cos(L),a):Math.abs(this.sin_p12+1)<=f?(o=this.a*g(b,c,m,n,e),p=this.a*g(b,c,m,n,I),a.x=this.x0+(o+p)*Math.sin(L),a.y=this.y0+(o+p)*Math.cos(L),a):(q=J/K,r=l(this.a,this.e,this.sin_p12),s=l(this.a,this.e,J),t=Math.atan((1-this.es)*q+this.es*r*this.sin_p12/(s*K)),u=Math.atan2(Math.sin(L),this.cos_p12*Math.tan(t)-this.sin_p12*Math.cos(L)),C=0===u?Math.asin(this.cos_p12*Math.sin(t)-this.sin_p12*Math.cos(t)):Math.abs(Math.abs(u)-Math.PI)<=f?-Math.asin(this.cos_p12*Math.sin(t)-this.sin_p12*Math.cos(t)):Math.asin(Math.sin(L)*Math.cos(t)/Math.sin(u)),v=this.e*this.sin_p12/Math.sqrt(1-this.es),w=this.e*this.cos_p12*Math.cos(u)/Math.sqrt(1-this.es),x=v*w,y=w*w,D=C*C,E=D*C,F=E*C,G=F*C,z=r*C*(1-D*y*(1-y)/6+E/8*x*(1-2*y)+F/120*(y*(4-7*y)-3*v*v*(1-7*y))-G/48*x),a.x=this.x0+z*Math.sin(u),a.y=this.y0+z*Math.cos(u),a))},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I;if(this.sphere){if(b=Math.sqrt(a.x*a.x+a.y*a.y),b>2*e*this.a)return;return c=b/this.a,o=Math.sin(c),p=Math.cos(c),q=this.long0,Math.abs(b)<=f?r=this.lat0:(r=m(p*this.sin_p12+a.y*o*this.cos_p12/b),s=Math.abs(this.lat0)-e,q=d(Math.abs(s)<=f?this.lat0>=0?this.long0+Math.atan2(a.x,-a.y):this.long0-Math.atan2(-a.x,a.y):this.long0+Math.atan2(a.x*o,b*this.cos_p12*p-a.y*this.sin_p12*o))),a.x=q,a.y=r,a}return t=h(this.es),u=i(this.es),v=j(this.es),w=k(this.es),Math.abs(this.sin_p12-1)<=f?(x=this.a*g(t,u,v,w,e),b=Math.sqrt(a.x*a.x+a.y*a.y),y=x-b,r=n(y/this.a,t,u,v,w),q=d(this.long0+Math.atan2(a.x,-1*a.y)),a.x=q,a.y=r,a):Math.abs(this.sin_p12+1)<=f?(x=this.a*g(t,u,v,w,e),b=Math.sqrt(a.x*a.x+a.y*a.y),y=b-x,r=n(y/this.a,t,u,v,w),q=d(this.long0+Math.atan2(a.x,a.y)),a.x=q,a.y=r,a):(b=Math.sqrt(a.x*a.x+a.y*a.y),B=Math.atan2(a.x,a.y),z=l(this.a,this.e,this.sin_p12),C=Math.cos(B),D=this.e*this.cos_p12*C,E=-D*D/(1-this.es),F=3*this.es*(1-E)*this.sin_p12*this.cos_p12*C/(1-this.es),G=b/z,H=G-E*(1+E)*Math.pow(G,3)/6-F*(1+3*E)*Math.pow(G,4)/24,I=1-E*H*H/2-G*H*H*H/6,A=Math.asin(this.sin_p12*Math.cos(H)+this.cos_p12*Math.sin(H)*C),q=d(this.long0+Math.asin(Math.sin(B)*Math.sin(H)/Math.cos(A))),r=Math.atan((1-this.es*I*this.sin_p12/Math.sin(A))*Math.tan(A)/(1-this.es)),a.x=q,a.y=r,a)},c.names=["Azimuthal_Equidistant","aeqd"]},{"../common/adjust_lon":5,"../common/asinz":6,"../common/e0fn":7,"../common/e1fn":8,"../common/e2fn":9,"../common/e3fn":10,"../common/gN":11,"../common/imlfn":12,"../common/mlfn":14}],42:[function(a,b,c){var d=a("../common/mlfn"),e=a("../common/e0fn"),f=a("../common/e1fn"),g=a("../common/e2fn"),h=a("../common/e3fn"),i=a("../common/gN"),j=a("../common/adjust_lon"),k=a("../common/adjust_lat"),l=a("../common/imlfn"),m=Math.PI/2,n=1e-10;c.init=function(){this.sphere||(this.e0=e(this.es),this.e1=f(this.es),this.e2=g(this.es),this.e3=h(this.es),this.ml0=this.a*d(this.e0,this.e1,this.e2,this.e3,this.lat0))},c.forward=function(a){var b,c,e=a.x,f=a.y;if(e=j(e-this.long0),this.sphere)b=this.a*Math.asin(Math.cos(f)*Math.sin(e)),c=this.a*(Math.atan2(Math.tan(f),Math.cos(e))-this.lat0);else{var g=Math.sin(f),h=Math.cos(f),k=i(this.a,this.e,g),l=Math.tan(f)*Math.tan(f),m=e*Math.cos(f),n=m*m,o=this.es*h*h/(1-this.es),p=this.a*d(this.e0,this.e1,this.e2,this.e3,f);b=k*m*(1-n*l*(1/6-(8-l+8*o)*n/120)),c=p-this.ml0+k*g/h*n*(.5+(5-l+6*o)*n/24)}return a.x=b+this.x0,a.y=c+this.y0,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c,d=a.x/this.a,e=a.y/this.a;if(this.sphere){var f=e+this.lat0;b=Math.asin(Math.sin(f)*Math.cos(d)),c=Math.atan2(Math.tan(d),Math.cos(f))}else{var g=this.ml0/this.a+e,h=l(g,this.e0,this.e1,this.e2,this.e3);if(Math.abs(Math.abs(h)-m)<=n)return a.x=this.long0,a.y=m,0>e&&(a.y*=-1),a;var o=i(this.a,this.e,Math.sin(h)),p=o*o*o/this.a/this.a*(1-this.es),q=Math.pow(Math.tan(h),2),r=d*this.a/o,s=r*r;b=h-o*Math.tan(h)/p*r*r*(.5-(1+3*q)*r*r/24),c=r*(1-s*(q/3+(1+3*q)*q*s/15))/Math.cos(h)}return a.x=j(c+this.long0),a.y=k(b),a},c.names=["Cassini","Cassini_Soldner","cass"]},{"../common/adjust_lat":4,"../common/adjust_lon":5,"../common/e0fn":7,"../common/e1fn":8,"../common/e2fn":9,"../common/e3fn":10,"../common/gN":11,"../common/imlfn":12,"../common/mlfn":14}],43:[function(a,b,c){var d=a("../common/adjust_lon"),e=a("../common/qsfnz"),f=a("../common/msfnz"),g=a("../common/iqsfnz");c.init=function(){this.sphere||(this.k0=f(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts)))},c.forward=function(a){var b,c,f=a.x,g=a.y,h=d(f-this.long0);if(this.sphere)b=this.x0+this.a*h*Math.cos(this.lat_ts),c=this.y0+this.a*Math.sin(g)/Math.cos(this.lat_ts);else{var i=e(this.e,Math.sin(g));b=this.x0+this.a*this.k0*h,c=this.y0+this.a*i*.5/this.k0}return a.x=b,a.y=c,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c;return this.sphere?(b=d(this.long0+a.x/this.a/Math.cos(this.lat_ts)),c=Math.asin(a.y/this.a*Math.cos(this.lat_ts))):(c=g(this.e,2*a.y*this.k0/this.a),b=d(this.long0+a.x/(this.a*this.k0))),a.x=b,a.y=c,a},c.names=["cea"]},{"../common/adjust_lon":5,"../common/iqsfnz":13,"../common/msfnz":15,"../common/qsfnz":20}],44:[function(a,b,c){var d=a("../common/adjust_lon"),e=a("../common/adjust_lat");c.init=function(){this.x0=this.x0||0,this.y0=this.y0||0,this.lat0=this.lat0||0,this.long0=this.long0||0,this.lat_ts=this.lat_ts||0,this.title=this.title||"Equidistant Cylindrical (Plate Carre)",this.rc=Math.cos(this.lat_ts)},c.forward=function(a){var b=a.x,c=a.y,f=d(b-this.long0),g=e(c-this.lat0);return a.x=this.x0+this.a*f*this.rc,a.y=this.y0+this.a*g,a},c.inverse=function(a){var b=a.x,c=a.y;return a.x=d(this.long0+(b-this.x0)/(this.a*this.rc)),a.y=e(this.lat0+(c-this.y0)/this.a),a},c.names=["Equirectangular","Equidistant_Cylindrical","eqc"]},{"../common/adjust_lat":4,"../common/adjust_lon":5}],45:[function(a,b,c){var d=a("../common/e0fn"),e=a("../common/e1fn"),f=a("../common/e2fn"),g=a("../common/e3fn"),h=a("../common/msfnz"),i=a("../common/mlfn"),j=a("../common/adjust_lon"),k=a("../common/adjust_lat"),l=a("../common/imlfn"),m=1e-10;c.init=function(){Math.abs(this.lat1+this.lat2)=0?(c=Math.sqrt(a.x*a.x+a.y*a.y),b=1):(c=-Math.sqrt(a.x*a.x+a.y*a.y),b=-1);var f=0;if(0!==c&&(f=Math.atan2(b*a.x,b*a.y)),this.sphere)return e=j(this.long0+f/this.ns),d=k(this.g-c/this.a),a.x=e,a.y=d,a;var g=this.g-c/this.a;return d=l(g,this.e0,this.e1,this.e2,this.e3),e=j(this.long0+f/this.ns),a.x=e,a.y=d,a},c.names=["Equidistant_Conic","eqdc"]},{"../common/adjust_lat":4,"../common/adjust_lon":5,"../common/e0fn":7,"../common/e1fn":8,"../common/e2fn":9,"../common/e3fn":10,"../common/imlfn":12,"../common/mlfn":14,"../common/msfnz":15}],46:[function(a,b,c){var d=Math.PI/4,e=a("../common/srat"),f=Math.PI/2,g=20;c.init=function(){var a=Math.sin(this.lat0),b=Math.cos(this.lat0);b*=b,this.rc=Math.sqrt(1-this.es)/(1-this.es*a*a),this.C=Math.sqrt(1+this.es*b*b/(1-this.es)),this.phic0=Math.asin(a/this.C),this.ratexp=.5*this.C*this.e,this.K=Math.tan(.5*this.phic0+d)/(Math.pow(Math.tan(.5*this.lat0+d),this.C)*e(this.e*a,this.ratexp))},c.forward=function(a){var b=a.x,c=a.y;return a.y=2*Math.atan(this.K*Math.pow(Math.tan(.5*c+d),this.C)*e(this.e*Math.sin(c),this.ratexp))-f,a.x=this.C*b,a},c.inverse=function(a){for(var b=1e-14,c=a.x/this.C,h=a.y,i=Math.pow(Math.tan(.5*h+d)/this.K,1/this.C),j=g;j>0&&(h=2*Math.atan(i*e(this.e*Math.sin(a.y),-.5*this.e))-f,!(Math.abs(h-a.y)0||Math.abs(i)<=e?(j=this.x0+this.a*h*c*Math.sin(f)/i,k=this.y0+this.a*h*(this.cos_p14*b-this.sin_p14*c*g)/i):(j=this.x0+this.infinity_dist*c*Math.sin(f),k=this.y0+this.infinity_dist*(this.cos_p14*b-this.sin_p14*c*g)),a.x=j,a.y=k,a},c.inverse=function(a){var b,c,e,g,h,i;return a.x=(a.x-this.x0)/this.a,a.y=(a.y-this.y0)/this.a,a.x/=this.k0,a.y/=this.k0,(b=Math.sqrt(a.x*a.x+a.y*a.y))?(g=Math.atan2(b,this.rc),c=Math.sin(g),e=Math.cos(g),i=f(e*this.sin_p14+a.y*c*this.cos_p14/b),h=Math.atan2(a.x*c,b*this.cos_p14*e-a.y*this.sin_p14*c),h=d(this.long0+h)):(i=this.phic0,h=0),a.x=h,a.y=i,a},c.names=["gnom"]},{"../common/adjust_lon":5,"../common/asinz":6}],48:[function(a,b,c){var d=a("../common/adjust_lon");c.init=function(){this.a=6377397.155,this.es=.006674372230614,this.e=Math.sqrt(this.es),this.lat0||(this.lat0=.863937979737193),this.long0||(this.long0=.4334234309119251),this.k0||(this.k0=.9999),this.s45=.785398163397448,this.s90=2*this.s45,this.fi0=this.lat0,this.e2=this.es,this.e=Math.sqrt(this.e2),this.alfa=Math.sqrt(1+this.e2*Math.pow(Math.cos(this.fi0),4)/(1-this.e2)),this.uq=1.04216856380474,this.u0=Math.asin(Math.sin(this.fi0)/this.alfa),this.g=Math.pow((1+this.e*Math.sin(this.fi0))/(1-this.e*Math.sin(this.fi0)),this.alfa*this.e/2),this.k=Math.tan(this.u0/2+this.s45)/Math.pow(Math.tan(this.fi0/2+this.s45),this.alfa)*this.g,this.k1=this.k0,this.n0=this.a*Math.sqrt(1-this.e2)/(1-this.e2*Math.pow(Math.sin(this.fi0),2)),this.s0=1.37008346281555,this.n=Math.sin(this.s0),this.ro0=this.k1*this.n0/Math.tan(this.s0),this.ad=this.s90-this.uq},c.forward=function(a){var b,c,e,f,g,h,i,j=a.x,k=a.y,l=d(j-this.long0);return b=Math.pow((1+this.e*Math.sin(k))/(1-this.e*Math.sin(k)),this.alfa*this.e/2),c=2*(Math.atan(this.k*Math.pow(Math.tan(k/2+this.s45),this.alfa)/b)-this.s45),e=-l*this.alfa,f=Math.asin(Math.cos(this.ad)*Math.sin(c)+Math.sin(this.ad)*Math.cos(c)*Math.cos(e)),g=Math.asin(Math.cos(c)*Math.sin(e)/Math.cos(f)),h=this.n*g,i=this.ro0*Math.pow(Math.tan(this.s0/2+this.s45),this.n)/Math.pow(Math.tan(f/2+this.s45),this.n),a.y=i*Math.cos(h)/1,a.x=i*Math.sin(h)/1,this.czech||(a.y*=-1,a.x*=-1),a},c.inverse=function(a){var b,c,d,e,f,g,h,i,j=a.x;a.x=a.y,a.y=j,this.czech||(a.y*=-1,a.x*=-1),g=Math.sqrt(a.x*a.x+a.y*a.y),f=Math.atan2(a.y,a.x),e=f/Math.sin(this.s0),d=2*(Math.atan(Math.pow(this.ro0/g,1/this.n)*Math.tan(this.s0/2+this.s45))-this.s45),b=Math.asin(Math.cos(this.ad)*Math.sin(d)-Math.sin(this.ad)*Math.cos(d)*Math.cos(e)),c=Math.asin(Math.cos(d)*Math.sin(e)/Math.cos(b)),a.x=this.long0-c/this.alfa,h=b,i=0;var k=0;do a.y=2*(Math.atan(Math.pow(this.k,-1/this.alfa)*Math.pow(Math.tan(b/2+this.s45),1/this.alfa)*Math.pow((1+this.e*Math.sin(h))/(1-this.e*Math.sin(h)),this.e/2))-this.s45),Math.abs(h-a.y)<1e-10&&(i=1),h=a.y,k+=1;while(0===i&&15>k);return k>=15?null:a},c.names=["Krovak","krovak"]},{"../common/adjust_lon":5}],49:[function(a,b,c){var d=Math.PI/2,e=Math.PI/4,f=1e-10,g=a("../common/qsfnz"),h=a("../common/adjust_lon");c.S_POLE=1,c.N_POLE=2,c.EQUIT=3,c.OBLIQ=4,c.init=function(){var a=Math.abs(this.lat0);if(Math.abs(a-d)0){var b;switch(this.qp=g(this.e,1),this.mmf=.5/(1-this.es),this.apa=this.authset(this.es),this.mode){case this.N_POLE:this.dd=1;break;case this.S_POLE:this.dd=1;break;case this.EQUIT:this.rq=Math.sqrt(.5*this.qp),this.dd=1/this.rq,this.xmf=1,this.ymf=.5*this.qp;break;case this.OBLIQ:this.rq=Math.sqrt(.5*this.qp),b=Math.sin(this.lat0),this.sinb1=g(this.e,b)/this.qp,this.cosb1=Math.sqrt(1-this.sinb1*this.sinb1),this.dd=Math.cos(this.lat0)/(Math.sqrt(1-this.es*b*b)*this.rq*this.cosb1),this.ymf=(this.xmf=this.rq)/this.dd,this.xmf*=this.dd}}else this.mode===this.OBLIQ&&(this.sinph0=Math.sin(this.lat0),this.cosph0=Math.cos(this.lat0))},c.forward=function(a){var b,c,i,j,k,l,m,n,o,p,q=a.x,r=a.y;if(q=h(q-this.long0),this.sphere){if(k=Math.sin(r),p=Math.cos(r),i=Math.cos(q),this.mode===this.OBLIQ||this.mode===this.EQUIT){if(c=this.mode===this.EQUIT?1+p*i:1+this.sinph0*k+this.cosph0*p*i,f>=c)return null;c=Math.sqrt(2/c),b=c*p*Math.sin(q),c*=this.mode===this.EQUIT?k:this.cosph0*k-this.sinph0*p*i}else if(this.mode===this.N_POLE||this.mode===this.S_POLE){if(this.mode===this.N_POLE&&(i=-i),Math.abs(r+this.phi0)=0?(b=(o=Math.sqrt(l))*j,c=i*(this.mode===this.S_POLE?o:-o)):b=c=0}}return a.x=this.a*b+this.x0,a.y=this.a*c+this.y0,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c,e,g,i,j,k,l=a.x/this.a,m=a.y/this.a;if(this.sphere){var n,o=0,p=0;if(n=Math.sqrt(l*l+m*m),c=.5*n,c>1)return null;switch(c=2*Math.asin(c),(this.mode===this.OBLIQ||this.mode===this.EQUIT)&&(p=Math.sin(c),o=Math.cos(c)),this.mode){case this.EQUIT:c=Math.abs(n)<=f?0:Math.asin(m*p/n),l*=p,m=o*n;break;case this.OBLIQ:c=Math.abs(n)<=f?this.phi0:Math.asin(o*this.sinph0+m*p*this.cosph0/n),l*=p*this.cosph0,m=(o-Math.sin(c)*this.sinph0)*n;break;case this.N_POLE:m=-m,c=d-c;break;case this.S_POLE:c-=d}b=0!==m||this.mode!==this.EQUIT&&this.mode!==this.OBLIQ?Math.atan2(l,m):0}else{if(k=0,this.mode===this.OBLIQ||this.mode===this.EQUIT){if(l/=this.dd,m*=this.dd,j=Math.sqrt(l*l+m*m),f>j)return a.x=0,a.y=this.phi0,a;g=2*Math.asin(.5*j/this.rq),e=Math.cos(g),l*=g=Math.sin(g),this.mode===this.OBLIQ?(k=e*this.sinb1+m*g*this.cosb1/j,i=this.qp*k,m=j*this.cosb1*e-m*this.sinb1*g):(k=m*g/j,i=this.qp*k,m=j*e)}else if(this.mode===this.N_POLE||this.mode===this.S_POLE){if(this.mode===this.N_POLE&&(m=-m),i=l*l+m*m,!i)return a.x=0,a.y=this.phi0,a;k=1-i/this.qp,this.mode===this.S_POLE&&(k=-k)}b=Math.atan2(l,m),c=this.authlat(Math.asin(k),this.apa)}return a.x=h(this.long0+b),a.y=c,a},c.P00=.3333333333333333,c.P01=.17222222222222222,c.P02=.10257936507936508,c.P10=.06388888888888888,c.P11=.0664021164021164,c.P20=.016415012942191543,c.authset=function(a){var b,c=[];return c[0]=a*this.P00,b=a*a,c[0]+=b*this.P01,c[1]=b*this.P10,b*=a,c[0]+=b*this.P02,c[1]+=b*this.P11,c[2]=b*this.P20,c},c.authlat=function(a,b){var c=a+a;return a+b[0]*Math.sin(c)+b[1]*Math.sin(c+c)+b[2]*Math.sin(c+c+c)},c.names=["Lambert Azimuthal Equal Area","Lambert_Azimuthal_Equal_Area","laea"]},{"../common/adjust_lon":5,"../common/qsfnz":20}],50:[function(a,b,c){var d=1e-10,e=a("../common/msfnz"),f=a("../common/tsfnz"),g=Math.PI/2,h=a("../common/sign"),i=a("../common/adjust_lon"),j=a("../common/phi2z");c.init=function(){if(this.lat2||(this.lat2=this.lat1),this.k0||(this.k0=1),this.x0=this.x0||0,this.y0=this.y0||0,!(Math.abs(this.lat1+this.lat2)d?this.ns=Math.log(g/k)/Math.log(h/l):this.ns=b,isNaN(this.ns)&&(this.ns=b),this.f0=g/(this.ns*Math.pow(h,this.ns)),this.rh=this.a*this.f0*Math.pow(m,this.ns),this.title||(this.title="Lambert Conformal Conic")}},c.forward=function(a){var b=a.x,c=a.y;Math.abs(2*Math.abs(c)-Math.PI)<=d&&(c=h(c)*(g-2*d));var e,j,k=Math.abs(Math.abs(c)-g);if(k>d)e=f(this.e,c,Math.sin(c)),j=this.a*this.f0*Math.pow(e,this.ns);else{if(k=c*this.ns,0>=k)return null;j=0}var l=this.ns*i(b-this.long0);return a.x=this.k0*(j*Math.sin(l))+this.x0,a.y=this.k0*(this.rh-j*Math.cos(l))+this.y0,a},c.inverse=function(a){var b,c,d,e,f,h=(a.x-this.x0)/this.k0,k=this.rh-(a.y-this.y0)/this.k0;this.ns>0?(b=Math.sqrt(h*h+k*k),c=1):(b=-Math.sqrt(h*h+k*k),c=-1);var l=0;if(0!==b&&(l=Math.atan2(c*h,c*k)),0!==b||this.ns>0){if(c=1/this.ns,d=Math.pow(b/(this.a*this.f0),c),e=j(this.e,d),-9999===e)return null}else e=-g;return f=i(l/this.ns+this.long0),a.x=f,a.y=e,a},c.names=["Lambert Tangential Conformal Conic Projection","Lambert_Conformal_Conic","Lambert_Conformal_Conic_2SP","lcc"]},{"../common/adjust_lon":5,"../common/msfnz":15,"../common/phi2z":16,"../common/sign":21,"../common/tsfnz":24}],51:[function(a,b,c){function d(a){return a}c.init=function(){},c.forward=d,c.inverse=d,c.names=["longlat","identity"]},{}],52:[function(a,b,c){var d=a("../common/msfnz"),e=Math.PI/2,f=1e-10,g=57.29577951308232,h=a("../common/adjust_lon"),i=Math.PI/4,j=a("../common/tsfnz"),k=a("../common/phi2z");c.init=function(){var a=this.b/this.a;this.es=1-a*a,"x0"in this||(this.x0=0),"y0"in this||(this.y0=0),this.e=Math.sqrt(this.es),this.lat_ts?this.sphere?this.k0=Math.cos(this.lat_ts):this.k0=d(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts)):this.k0||(this.k?this.k0=this.k:this.k0=1)},c.forward=function(a){var b=a.x,c=a.y;if(c*g>90&&-90>c*g&&b*g>180&&-180>b*g)return null;var d,k;if(Math.abs(Math.abs(c)-e)<=f)return null;if(this.sphere)d=this.x0+this.a*this.k0*h(b-this.long0),k=this.y0+this.a*this.k0*Math.log(Math.tan(i+.5*c));else{var l=Math.sin(c),m=j(this.e,c,l);d=this.x0+this.a*this.k0*h(b-this.long0),k=this.y0-this.a*this.k0*Math.log(m)}return a.x=d,a.y=k,a},c.inverse=function(a){var b,c,d=a.x-this.x0,f=a.y-this.y0;if(this.sphere)c=e-2*Math.atan(Math.exp(-f/(this.a*this.k0)));else{var g=Math.exp(-f/(this.a*this.k0));if(c=k(this.e,g),-9999===c)return null}return b=h(this.long0+d/(this.a*this.k0)),a.x=b,a.y=c,a},c.names=["Mercator","Popular Visualisation Pseudo Mercator","Mercator_1SP","Mercator_Auxiliary_Sphere","merc"]},{"../common/adjust_lon":5,"../common/msfnz":15,"../common/phi2z":16,"../common/tsfnz":24}],53:[function(a,b,c){var d=a("../common/adjust_lon");c.init=function(){},c.forward=function(a){var b=a.x,c=a.y,e=d(b-this.long0),f=this.x0+this.a*e,g=this.y0+this.a*Math.log(Math.tan(Math.PI/4+c/2.5))*1.25;return a.x=f,a.y=g,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b=d(this.long0+a.x/this.a),c=2.5*(Math.atan(Math.exp(.8*a.y/this.a))-Math.PI/4);return a.x=b,a.y=c,a},c.names=["Miller_Cylindrical","mill"]},{"../common/adjust_lon":5}],54:[function(a,b,c){var d=a("../common/adjust_lon"),e=1e-10;c.init=function(){},c.forward=function(a){for(var b=a.x,c=a.y,f=d(b-this.long0),g=c,h=Math.PI*Math.sin(c),i=0;!0;i++){var j=-(g+Math.sin(g)-h)/(1+Math.cos(g));if(g+=j,Math.abs(j).999999999999&&(c=.999999999999),b=Math.asin(c);var e=d(this.long0+a.x/(.900316316158*this.a*Math.cos(b)));e<-Math.PI&&(e=-Math.PI),e>Math.PI&&(e=Math.PI),c=(2*b+Math.sin(2*b))/Math.PI,Math.abs(c)>1&&(c=1);var f=Math.asin(c);return a.x=e,a.y=f,a},c.names=["Mollweide","moll"]},{"../common/adjust_lon":5}],55:[function(a,b,c){var d=484813681109536e-20;c.iterations=1,c.init=function(){this.A=[],this.A[1]=.6399175073,this.A[2]=-.1358797613,this.A[3]=.063294409,this.A[4]=-.02526853,this.A[5]=.0117879,this.A[6]=-.0055161,this.A[7]=.0026906,this.A[8]=-.001333,this.A[9]=67e-5,this.A[10]=-34e-5,this.B_re=[],this.B_im=[],this.B_re[1]=.7557853228,this.B_im[1]=0,this.B_re[2]=.249204646,this.B_im[2]=.003371507,this.B_re[3]=-.001541739,this.B_im[3]=.04105856,this.B_re[4]=-.10162907,this.B_im[4]=.01727609,this.B_re[5]=-.26623489,this.B_im[5]=-.36249218,this.B_re[6]=-.6870983,this.B_im[6]=-1.1651967,this.C_re=[],this.C_im=[],this.C_re[1]=1.3231270439,this.C_im[1]=0,this.C_re[2]=-.577245789,this.C_im[2]=-.007809598,this.C_re[3]=.508307513,this.C_im[3]=-.112208952,this.C_re[4]=-.15094762,this.C_im[4]=.18200602,this.C_re[5]=1.01418179,this.C_im[5]=1.64497696,this.C_re[6]=1.9660549,this.C_im[6]=2.5127645,this.D=[],this.D[1]=1.5627014243,this.D[2]=.5185406398,this.D[3]=-.03333098,this.D[4]=-.1052906,this.D[5]=-.0368594,this.D[6]=.007317,this.D[7]=.0122,this.D[8]=.00394,this.D[9]=-.0013},c.forward=function(a){var b,c=a.x,e=a.y,f=e-this.lat0,g=c-this.long0,h=f/d*1e-5,i=g,j=1,k=0;for(b=1;10>=b;b++)j*=h,k+=this.A[b]*j;var l,m,n=k,o=i,p=1,q=0,r=0,s=0;for(b=1;6>=b;b++)l=p*n-q*o,m=q*n+p*o,p=l,q=m,r=r+this.B_re[b]*p-this.B_im[b]*q,s=s+this.B_im[b]*p+this.B_re[b]*q;return a.x=s*this.a+this.x0,a.y=r*this.a+this.y0,a},c.inverse=function(a){var b,c,e,f=a.x,g=a.y,h=f-this.x0,i=g-this.y0,j=i/this.a,k=h/this.a,l=1,m=0,n=0,o=0;for(b=1;6>=b;b++)c=l*j-m*k,e=m*j+l*k,l=c,m=e,n=n+this.C_re[b]*l-this.C_im[b]*m,o=o+this.C_im[b]*l+this.C_re[b]*m;for(var p=0;p=b;b++)q=s*n-t*o,r=t*n+s*o,s=q,t=r,u+=(b-1)*(this.B_re[b]*s-this.B_im[b]*t),v+=(b-1)*(this.B_im[b]*s+this.B_re[b]*t);s=1,t=0;var w=this.B_re[1],x=this.B_im[1];for(b=2;6>=b;b++)q=s*n-t*o,r=t*n+s*o,s=q,t=r,w+=b*(this.B_re[b]*s-this.B_im[b]*t),x+=b*(this.B_im[b]*s+this.B_re[b]*t);var y=w*w+x*x;n=(u*w+v*x)/y,o=(v*w-u*x)/y}var z=n,A=o,B=1,C=0;for(b=1;9>=b;b++)B*=z,C+=this.D[b]*B;var D=this.lat0+C*d*1e5,E=this.long0+A;return a.x=E,a.y=D,a},c.names=["New_Zealand_Map_Grid","nzmg"]},{}],56:[function(a,b,c){var d=a("../common/tsfnz"),e=a("../common/adjust_lon"),f=a("../common/phi2z"),g=Math.PI/2,h=Math.PI/4,i=1e-10;c.init=function(){this.no_off=this.no_off||!1,this.no_rot=this.no_rot||!1,isNaN(this.k0)&&(this.k0=1);var a=Math.sin(this.lat0),b=Math.cos(this.lat0),c=this.e*a;this.bl=Math.sqrt(1+this.es/(1-this.es)*Math.pow(b,4)),this.al=this.a*this.bl*this.k0*Math.sqrt(1-this.es)/(1-c*c);var f=d(this.e,this.lat0,a),g=this.bl/b*Math.sqrt((1-this.es)/(1-c*c));1>g*g&&(g=1);var h,i;if(isNaN(this.longc)){var j=d(this.e,this.lat1,Math.sin(this.lat1)),k=d(this.e,this.lat2,Math.sin(this.lat2));this.lat0>=0?this.el=(g+Math.sqrt(g*g-1))*Math.pow(f,this.bl):this.el=(g-Math.sqrt(g*g-1))*Math.pow(f,this.bl);var l=Math.pow(j,this.bl),m=Math.pow(k,this.bl);h=this.el/l,i=.5*(h-1/h);var n=(this.el*this.el-m*l)/(this.el*this.el+m*l),o=(m-l)/(m+l),p=e(this.long1-this.long2);this.long0=.5*(this.long1+this.long2)-Math.atan(n*Math.tan(.5*this.bl*p)/o)/this.bl,this.long0=e(this.long0);var q=e(this.long1-this.long0);this.gamma0=Math.atan(Math.sin(this.bl*q)/i),this.alpha=Math.asin(g*Math.sin(this.gamma0))}else h=this.lat0>=0?g+Math.sqrt(g*g-1):g-Math.sqrt(g*g-1),this.el=h*Math.pow(f,this.bl),i=.5*(h-1/h),this.gamma0=Math.asin(Math.sin(this.alpha)/g),this.long0=this.longc-Math.asin(i*Math.tan(this.gamma0))/this.bl;this.no_off?this.uc=0:this.lat0>=0?this.uc=this.al/this.bl*Math.atan2(Math.sqrt(g*g-1),Math.cos(this.alpha)):this.uc=-1*this.al/this.bl*Math.atan2(Math.sqrt(g*g-1),Math.cos(this.alpha))},c.forward=function(a){var b,c,f,j=a.x,k=a.y,l=e(j-this.long0);if(Math.abs(Math.abs(k)-g)<=i)f=k>0?-1:1,c=this.al/this.bl*Math.log(Math.tan(h+f*this.gamma0*.5)),b=-1*f*g*this.al/this.bl;else{var m=d(this.e,k,Math.sin(k)),n=this.el/Math.pow(m,this.bl),o=.5*(n-1/n),p=.5*(n+1/n),q=Math.sin(this.bl*l),r=(o*Math.sin(this.gamma0)-q*Math.cos(this.gamma0))/p;c=Math.abs(Math.abs(r)-1)<=i?Number.POSITIVE_INFINITY:.5*this.al*Math.log((1-r)/(1+r))/this.bl,b=Math.abs(Math.cos(this.bl*l))<=i?this.al*this.bl*l:this.al*Math.atan2(o*Math.cos(this.gamma0)+q*Math.sin(this.gamma0),Math.cos(this.bl*l))/this.bl}return this.no_rot?(a.x=this.x0+b,a.y=this.y0+c):(b-=this.uc,a.x=this.x0+c*Math.cos(this.alpha)+b*Math.sin(this.alpha),a.y=this.y0+b*Math.cos(this.alpha)-c*Math.sin(this.alpha)),a},c.inverse=function(a){var b,c;this.no_rot?(c=a.y-this.y0,b=a.x-this.x0):(c=(a.x-this.x0)*Math.cos(this.alpha)-(a.y-this.y0)*Math.sin(this.alpha),b=(a.y-this.y0)*Math.cos(this.alpha)+(a.x-this.x0)*Math.sin(this.alpha),b+=this.uc);var d=Math.exp(-1*this.bl*c/this.al),h=.5*(d-1/d),j=.5*(d+1/d),k=Math.sin(this.bl*b/this.al),l=(k*Math.cos(this.gamma0)+h*Math.sin(this.gamma0))/j,m=Math.pow(this.el/Math.sqrt((1+l)/(1-l)),1/this.bl);return Math.abs(l-1)g?(g=Math.sin(b),c=this.long0+a.x*Math.sqrt(1-this.es*g*g)/(this.a*Math.cos(b)),f=d(c)):j>g-k&&(f=this.long0)),a.x=f,a.y=b,a},c.names=["Sinusoidal","sinu"]},{"../common/adjust_lat":4,"../common/adjust_lon":5,"../common/asinz":6,"../common/pj_enfn":17,"../common/pj_inv_mlfn":18,"../common/pj_mlfn":19}],59:[function(a,b,c){c.init=function(){var a=this.lat0;this.lambda0=this.long0;var b=Math.sin(a),c=this.a,d=this.rf,e=1/d,f=2*e-Math.pow(e,2),g=this.e=Math.sqrt(f);this.R=this.k0*c*Math.sqrt(1-f)/(1-f*Math.pow(b,2)),this.alpha=Math.sqrt(1+f/(1-f)*Math.pow(Math.cos(a),4)),this.b0=Math.asin(b/this.alpha);var h=Math.log(Math.tan(Math.PI/4+this.b0/2)),i=Math.log(Math.tan(Math.PI/4+a/2)),j=Math.log((1+g*b)/(1-g*b));this.K=h-this.alpha*i+this.alpha*g/2*j},c.forward=function(a){var b=Math.log(Math.tan(Math.PI/4-a.y/2)),c=this.e/2*Math.log((1+this.e*Math.sin(a.y))/(1-this.e*Math.sin(a.y))),d=-this.alpha*(b+c)+this.K,e=2*(Math.atan(Math.exp(d))-Math.PI/4),f=this.alpha*(a.x-this.lambda0),g=Math.atan(Math.sin(f)/(Math.sin(this.b0)*Math.tan(e)+Math.cos(this.b0)*Math.cos(f))),h=Math.asin(Math.cos(this.b0)*Math.sin(e)-Math.sin(this.b0)*Math.cos(e)*Math.cos(f));return a.y=this.R/2*Math.log((1+Math.sin(h))/(1-Math.sin(h)))+this.y0,a.x=this.R*g+this.x0,a},c.inverse=function(a){for(var b=a.x-this.x0,c=a.y-this.y0,d=b/this.R,e=2*(Math.atan(Math.exp(c/this.R))-Math.PI/4),f=Math.asin(Math.cos(this.b0)*Math.sin(e)+Math.sin(this.b0)*Math.cos(e)*Math.cos(d)),g=Math.atan(Math.sin(d)/(Math.cos(this.b0)*Math.cos(d)-Math.sin(this.b0)*Math.tan(e))),h=this.lambda0+g/this.alpha,i=0,j=f,k=-1e3,l=0;Math.abs(j-k)>1e-7;){if(++l>20)return;i=1/this.alpha*(Math.log(Math.tan(Math.PI/4+f/2))-this.K)+this.e*Math.log(Math.tan(Math.PI/4+Math.asin(this.e*Math.sin(j))/2)),k=j,j=2*Math.atan(Math.exp(i))-Math.PI/2}return a.x=h,a.y=j,a},c.names=["somerc"]},{}],60:[function(a,b,c){var d=Math.PI/2,e=1e-10,f=a("../common/sign"),g=a("../common/msfnz"),h=a("../common/tsfnz"),i=a("../common/phi2z"),j=a("../common/adjust_lon");c.ssfn_=function(a,b,c){return b*=c,Math.tan(.5*(d+a))*Math.pow((1-b)/(1+b),.5*c)},c.init=function(){this.coslat0=Math.cos(this.lat0),this.sinlat0=Math.sin(this.lat0),this.sphere?1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=e&&(this.k0=.5*(1+f(this.lat0)*Math.sin(this.lat_ts))):(Math.abs(this.coslat0)<=e&&(this.lat0>0?this.con=1:this.con=-1),this.cons=Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e)),1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=e&&(this.k0=.5*this.cons*g(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts))/h(this.e,this.con*this.lat_ts,this.con*Math.sin(this.lat_ts))),this.ms1=g(this.e,this.sinlat0,this.coslat0),this.X0=2*Math.atan(this.ssfn_(this.lat0,this.sinlat0,this.e))-d,this.cosX0=Math.cos(this.X0),this.sinX0=Math.sin(this.X0))},c.forward=function(a){var b,c,f,g,i,k,l=a.x,m=a.y,n=Math.sin(m),o=Math.cos(m),p=j(l-this.long0);return Math.abs(Math.abs(l-this.long0)-Math.PI)<=e&&Math.abs(m+this.lat0)<=e?(a.x=NaN,a.y=NaN,a):this.sphere?(b=2*this.k0/(1+this.sinlat0*n+this.coslat0*o*Math.cos(p)),a.x=this.a*b*o*Math.sin(p)+this.x0,a.y=this.a*b*(this.coslat0*n-this.sinlat0*o*Math.cos(p))+this.y0,a):(c=2*Math.atan(this.ssfn_(m,n,this.e))-d,g=Math.cos(c),f=Math.sin(c),Math.abs(this.coslat0)<=e?(i=h(this.e,m*this.con,this.con*n),k=2*this.a*this.k0*i/this.cons,a.x=this.x0+k*Math.sin(l-this.long0),a.y=this.y0-this.con*k*Math.cos(l-this.long0),a):(Math.abs(this.sinlat0)=k?(a.x=b,a.y=c,a):(c=Math.asin(Math.cos(l)*this.sinlat0+a.y*Math.sin(l)*this.coslat0/k),b=j(Math.abs(this.coslat0)0?this.long0+Math.atan2(a.x,-1*a.y):this.long0+Math.atan2(a.x,a.y):this.long0+Math.atan2(a.x*Math.sin(l),k*this.coslat0*Math.cos(l)-a.y*this.sinlat0*Math.sin(l))),a.x=b,a.y=c,a)}if(Math.abs(this.coslat0)<=e){if(e>=k)return c=this.lat0,b=this.long0,a.x=b,a.y=c,a;a.x*=this.con,a.y*=this.con,f=k*this.cons/(2*this.a*this.k0),c=this.con*i(this.e,f),b=this.con*j(this.con*this.long0+Math.atan2(a.x,-1*a.y))}else g=2*Math.atan(k*this.cosX0/(2*this.a*this.k0*this.ms1)),b=this.long0,e>=k?h=this.X0:(h=Math.asin(Math.cos(g)*this.sinX0+a.y*Math.sin(g)*this.cosX0/k),b=j(this.long0+Math.atan2(a.x*Math.sin(g),k*this.cosX0*Math.cos(g)-a.y*this.sinX0*Math.sin(g)))),c=-1*i(this.e,Math.tan(.5*(d+h)));return a.x=b,a.y=c,a},c.names=["stere","Stereographic_South_Pole","Polar Stereographic (variant B)"]},{"../common/adjust_lon":5,"../common/msfnz":15,"../common/phi2z":16,"../common/sign":21,"../common/tsfnz":24}],61:[function(a,b,c){var d=a("./gauss"),e=a("../common/adjust_lon");c.init=function(){d.init.apply(this),this.rc&&(this.sinc0=Math.sin(this.phic0),this.cosc0=Math.cos(this.phic0),this.R2=2*this.rc,this.title||(this.title="Oblique Stereographic Alternative"))},c.forward=function(a){var b,c,f,g;return a.x=e(a.x-this.long0),d.forward.apply(this,[a]),b=Math.sin(a.y),c=Math.cos(a.y),f=Math.cos(a.x),g=this.k0*this.R2/(1+this.sinc0*b+this.cosc0*c*f),a.x=g*c*Math.sin(a.x),a.y=g*(this.cosc0*b-this.sinc0*c*f),a.x=this.a*a.x+this.x0,a.y=this.a*a.y+this.y0,a},c.inverse=function(a){var b,c,f,g,h;if(a.x=(a.x-this.x0)/this.a,a.y=(a.y-this.y0)/this.a,a.x/=this.k0,a.y/=this.k0,h=Math.sqrt(a.x*a.x+a.y*a.y)){var i=2*Math.atan2(h,this.R2);b=Math.sin(i),c=Math.cos(i),g=Math.asin(c*this.sinc0+a.y*b*this.cosc0/h),f=Math.atan2(a.x*b,h*this.cosc0*c-a.y*this.sinc0*b)}else g=this.phic0,f=0;return a.x=f,a.y=g,d.inverse.apply(this,[a]),a.x=e(a.x+this.long0),a},c.names=["Stereographic_North_Pole","Oblique_Stereographic","Polar_Stereographic","sterea","Oblique Stereographic Alternative"]},{"../common/adjust_lon":5,"./gauss":46}],62:[function(a,b,c){var d=a("../common/e0fn"),e=a("../common/e1fn"),f=a("../common/e2fn"),g=a("../common/e3fn"),h=a("../common/mlfn"),i=a("../common/adjust_lon"),j=Math.PI/2,k=1e-10,l=a("../common/sign"),m=a("../common/asinz");c.init=function(){this.e0=d(this.es),this.e1=e(this.es),this.e2=f(this.es),this.e3=g(this.es),this.ml0=this.a*h(this.e0,this.e1,this.e2,this.e3,this.lat0)},c.forward=function(a){var b,c,d,e=a.x,f=a.y,g=i(e-this.long0),j=Math.sin(f),k=Math.cos(f);if(this.sphere){var l=k*Math.sin(g);if(Math.abs(Math.abs(l)-1)<1e-10)return 93;c=.5*this.a*this.k0*Math.log((1+l)/(1-l)),b=Math.acos(k*Math.cos(g)/Math.sqrt(1-l*l)),0>f&&(b=-b),d=this.a*this.k0*(b-this.lat0)}else{var m=k*g,n=Math.pow(m,2),o=this.ep2*Math.pow(k,2),p=Math.tan(f),q=Math.pow(p,2);b=1-this.es*Math.pow(j,2);var r=this.a/Math.sqrt(b),s=this.a*h(this.e0,this.e1,this.e2,this.e3,f);c=this.k0*r*m*(1+n/6*(1-q+o+n/20*(5-18*q+Math.pow(q,2)+72*o-58*this.ep2)))+this.x0,d=this.k0*(s-this.ml0+r*p*(n*(.5+n/24*(5-q+9*o+4*Math.pow(o,2)+n/30*(61-58*q+Math.pow(q,2)+600*o-330*this.ep2)))))+this.y0}return a.x=c,a.y=d,a},c.inverse=function(a){var b,c,d,e,f,g,h=6;if(this.sphere){var n=Math.exp(a.x/(this.a*this.k0)),o=.5*(n-1/n),p=this.lat0+a.y/(this.a*this.k0),q=Math.cos(p);b=Math.sqrt((1-q*q)/(1+o*o)),f=m(b),0>p&&(f=-f),g=0===o&&0===q?this.long0:i(Math.atan2(o,q)+this.long0)}else{var r=a.x-this.x0,s=a.y-this.y0;for(b=(this.ml0+s/this.k0)/this.a,c=b,e=0;!0&&(d=(b+this.e1*Math.sin(2*c)-this.e2*Math.sin(4*c)+this.e3*Math.sin(6*c))/this.e0-c,c+=d,!(Math.abs(d)<=k));e++)if(e>=h)return 95;if(Math.abs(c)=0?this.y0+Math.PI*this.R*Math.tan(.5*k):this.y0+Math.PI*this.R*-Math.tan(.5*k));var l=.5*Math.abs(Math.PI/j-j/Math.PI),m=l*l,n=Math.sin(k),o=Math.cos(k),p=o/(n+o-1),q=p*p,r=p*(2/n-1),s=r*r,t=Math.PI*this.R*(l*(p-s)+Math.sqrt(m*(p-s)*(p-s)-(s+m)*(q-s)))/(s+m);0>j&&(t=-t),b=this.x0+t;var u=m+p;return t=Math.PI*this.R*(r*u-l*Math.sqrt((s+m)*(m+1)-u*u))/(s+m),c=i>=0?this.y0+t:this.y0-t,a.x=b,a.y=c,a},c.inverse=function(a){var b,c,e,g,h,i,j,k,l,m,n,o,p;return a.x-=this.x0,a.y-=this.y0,n=Math.PI*this.R,e=a.x/n,g=a.y/n,h=e*e+g*g,i=-Math.abs(g)*(1+h),j=i-2*g*g+e*e,k=-2*i+1+2*g*g+h*h,p=g*g/k+(2*j*j*j/k/k/k-9*i*j/k/k)/27,l=(i-j*j/3/k)/k,m=2*Math.sqrt(-l/3),n=3*p/l/m,Math.abs(n)>1&&(n=n>=0?1:-1),o=Math.acos(n)/3,c=a.y>=0?(-m*Math.cos(o+Math.PI/3)-j/3/k)*Math.PI:-(-m*Math.cos(o+Math.PI/3)-j/3/k)*Math.PI,b=Math.abs(e)-1?(b[c]={name:a[0].toLowerCase(),convert:a[1]},3===a.length&&(b[c].auth=a[2])):"SPHEROID"===c?(b[c]={name:a[0],a:a[1],rf:a[2]},4===a.length&&(b[c].auth=a[3])):["GEOGCS","GEOCCS","DATUM","VERT_CS","COMPD_CS","LOCAL_CS","FITTED_CS","LOCAL_DATUM"].indexOf(c)>-1?(a[0]=["name",a[0]],d(b,c,a)):a.every(function(a){return Array.isArray(a)})?d(b,c,a):e(a,b[c])):b[c]=!0,void 0):void(b[a]=!0)}function f(a,b){var c=b[0],d=b[1];!(c in a)&&d in a&&(a[c]=a[d],3===b.length&&(a[c]=b[2](a[c])))}function g(a){return a*i}function h(a){function b(b){var c=a.to_meter||1;return parseFloat(b,10)*c}"GEOGCS"===a.type?a.projName="longlat":"LOCAL_CS"===a.type?(a.projName="identity",a.local=!0):"object"==typeof a.PROJECTION?a.projName=Object.keys(a.PROJECTION)[0]:a.projName=a.PROJECTION,a.UNIT&&(a.units=a.UNIT.name.toLowerCase(),"metre"===a.units&&(a.units="meter"), +a.UNIT.convert&&("GEOGCS"===a.type?a.DATUM&&a.DATUM.SPHEROID&&(a.to_meter=parseFloat(a.UNIT.convert,10)*a.DATUM.SPHEROID.a):a.to_meter=parseFloat(a.UNIT.convert,10))),a.GEOGCS&&(a.GEOGCS.DATUM?a.datumCode=a.GEOGCS.DATUM.name.toLowerCase():a.datumCode=a.GEOGCS.name.toLowerCase(),"d_"===a.datumCode.slice(0,2)&&(a.datumCode=a.datumCode.slice(2)),("new_zealand_geodetic_datum_1949"===a.datumCode||"new_zealand_1949"===a.datumCode)&&(a.datumCode="nzgd49"),"wgs_1984"===a.datumCode&&("Mercator_Auxiliary_Sphere"===a.PROJECTION&&(a.sphere=!0),a.datumCode="wgs84"),"_ferro"===a.datumCode.slice(-6)&&(a.datumCode=a.datumCode.slice(0,-6)),"_jakarta"===a.datumCode.slice(-8)&&(a.datumCode=a.datumCode.slice(0,-8)),~a.datumCode.indexOf("belge")&&(a.datumCode="rnb72"),a.GEOGCS.DATUM&&a.GEOGCS.DATUM.SPHEROID&&(a.ellps=a.GEOGCS.DATUM.SPHEROID.name.replace("_19","").replace(/[Cc]larke\_18/,"clrk"),"international"===a.ellps.toLowerCase().slice(0,13)&&(a.ellps="intl"),a.a=a.GEOGCS.DATUM.SPHEROID.a,a.rf=parseFloat(a.GEOGCS.DATUM.SPHEROID.rf,10)),~a.datumCode.indexOf("osgb_1936")&&(a.datumCode="osgb36")),a.b&&!isFinite(a.b)&&(a.b=a.a);var c=function(b){return f(a,b)},d=[["standard_parallel_1","Standard_Parallel_1"],["standard_parallel_2","Standard_Parallel_2"],["false_easting","False_Easting"],["false_northing","False_Northing"],["central_meridian","Central_Meridian"],["latitude_of_origin","Latitude_Of_Origin"],["latitude_of_origin","Central_Parallel"],["scale_factor","Scale_Factor"],["k0","scale_factor"],["latitude_of_center","Latitude_of_center"],["lat0","latitude_of_center",g],["longitude_of_center","Longitude_Of_Center"],["longc","longitude_of_center",g],["x0","false_easting",b],["y0","false_northing",b],["long0","central_meridian",g],["lat0","latitude_of_origin",g],["lat0","standard_parallel_1",g],["lat1","standard_parallel_1",g],["lat2","standard_parallel_2",g],["alpha","azimuth",g],["srsCode","name"]];d.forEach(c),a.long0||!a.longc||"Albers_Conic_Equal_Area"!==a.projName&&"Lambert_Azimuthal_Equal_Area"!==a.projName||(a.long0=a.longc),a.lat_ts||!a.lat1||"Stereographic_South_Pole"!==a.projName&&"Polar Stereographic (variant B)"!==a.projName||(a.lat0=g(a.lat1>0?90:-90),a.lat_ts=a.lat1)}var i=.017453292519943295,j=a("./extend");b.exports=function(a,b){var c=JSON.parse((","+a).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g,',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g,',"$1"]').replace(/,\["VERTCS".+/,"")),d=c.shift(),f=c.shift();c.unshift(["name",f]),c.unshift(["type",d]),c.unshift("output");var g={};return e(c,g),h(g.output),j(b,g.output)}},{"./extend":34}],67:[function(a,b,c){function d(a){return a*(Math.PI/180)}function e(a){return 180*(a/Math.PI)}function f(a){var b,c,e,f,g,i,j,k,l,m=a.lat,n=a.lon,o=6378137,p=.00669438,q=.9996,r=d(m),s=d(n);l=Math.floor((n+180)/6)+1,180===n&&(l=60),m>=56&&64>m&&n>=3&&12>n&&(l=32),m>=72&&84>m&&(n>=0&&9>n?l=31:n>=9&&21>n?l=33:n>=21&&33>n?l=35:n>=33&&42>n&&(l=37)),b=6*(l-1)-180+3,k=d(b),c=p/(1-p),e=o/Math.sqrt(1-p*Math.sin(r)*Math.sin(r)),f=Math.tan(r)*Math.tan(r),g=c*Math.cos(r)*Math.cos(r),i=Math.cos(r)*(s-k),j=o*((1-p/4-3*p*p/64-5*p*p*p/256)*r-(3*p/8+3*p*p/32+45*p*p*p/1024)*Math.sin(2*r)+(15*p*p/256+45*p*p*p/1024)*Math.sin(4*r)-35*p*p*p/3072*Math.sin(6*r));var t=q*e*(i+(1-f+g)*i*i*i/6+(5-18*f+f*f+72*g-58*c)*i*i*i*i*i/120)+5e5,u=q*(j+e*Math.tan(r)*(i*i/2+(5-f+9*g+4*g*g)*i*i*i*i/24+(61-58*f+f*f+600*g-330*c)*i*i*i*i*i*i/720));return 0>m&&(u+=1e7),{northing:Math.round(u),easting:Math.round(t),zoneNumber:l,zoneLetter:h(m)}}function g(a){var b=a.northing,c=a.easting,d=a.zoneLetter,f=a.zoneNumber;if(0>f||f>60)return null;var h,i,j,k,l,m,n,o,p,q,r=.9996,s=6378137,t=.00669438,u=(1-Math.sqrt(1-t))/(1+Math.sqrt(1-t)),v=c-5e5,w=b;"N">d&&(w-=1e7),o=6*(f-1)-180+3,h=t/(1-t),n=w/r,p=n/(s*(1-t/4-3*t*t/64-5*t*t*t/256)),q=p+(3*u/2-27*u*u*u/32)*Math.sin(2*p)+(21*u*u/16-55*u*u*u*u/32)*Math.sin(4*p)+151*u*u*u/96*Math.sin(6*p),i=s/Math.sqrt(1-t*Math.sin(q)*Math.sin(q)),j=Math.tan(q)*Math.tan(q),k=h*Math.cos(q)*Math.cos(q),l=s*(1-t)/Math.pow(1-t*Math.sin(q)*Math.sin(q),1.5),m=v/(i*r);var x=q-i*Math.tan(q)/l*(m*m/2-(5+3*j+10*k-4*k*k-9*h)*m*m*m*m/24+(61+90*j+298*k+45*j*j-252*h-3*k*k)*m*m*m*m*m*m/720);x=e(x);var y=(m-(1+2*j+k)*m*m*m/6+(5-2*k+28*j-3*k*k+8*h+24*j*j)*m*m*m*m*m/120)/Math.cos(q);y=o+e(y);var z;if(a.accuracy){var A=g({northing:a.northing+a.accuracy,easting:a.easting+a.accuracy,zoneLetter:a.zoneLetter,zoneNumber:a.zoneNumber});z={top:A.lat,right:A.lon,bottom:x,left:y}}else z={lat:x,lon:y};return z}function h(a){var b="Z";return 84>=a&&a>=72?b="X":72>a&&a>=64?b="W":64>a&&a>=56?b="V":56>a&&a>=48?b="U":48>a&&a>=40?b="T":40>a&&a>=32?b="S":32>a&&a>=24?b="R":24>a&&a>=16?b="Q":16>a&&a>=8?b="P":8>a&&a>=0?b="N":0>a&&a>=-8?b="M":-8>a&&a>=-16?b="L":-16>a&&a>=-24?b="K":-24>a&&a>=-32?b="J":-32>a&&a>=-40?b="H":-40>a&&a>=-48?b="G":-48>a&&a>=-56?b="F":-56>a&&a>=-64?b="E":-64>a&&a>=-72?b="D":-72>a&&a>=-80&&(b="C"),b}function i(a,b){var c="00000"+a.easting,d="00000"+a.northing;return a.zoneNumber+a.zoneLetter+j(a.easting,a.northing,a.zoneNumber)+c.substr(c.length-5,b)+d.substr(d.length-5,b)}function j(a,b,c){var d=k(c),e=Math.floor(a/1e5),f=Math.floor(b/1e5)%20;return l(e,f,d)}function k(a){var b=a%q;return 0===b&&(b=q),b}function l(a,b,c){var d=c-1,e=r.charCodeAt(d),f=s.charCodeAt(d),g=e+a-1,h=f+b,i=!1;g>x&&(g=g-x+t-1,i=!0),(g===u||u>e&&g>u||(g>u||u>e)&&i)&&g++,(g===v||v>e&&g>v||(g>v||v>e)&&i)&&(g++,g===u&&g++),g>x&&(g=g-x+t-1),h>w?(h=h-w+t-1,i=!0):i=!1,(h===u||u>f&&h>u||(h>u||u>f)&&i)&&h++,(h===v||v>f&&h>v||(h>v||v>f)&&i)&&(h++,h===u&&h++),h>w&&(h=h-w+t-1);var j=String.fromCharCode(g)+String.fromCharCode(h);return j}function m(a){if(a&&0===a.length)throw"MGRSPoint coverting from nothing";for(var b,c=a.length,d=null,e="",f=0;!/[A-Z]/.test(b=a.charAt(f));){if(f>=2)throw"MGRSPoint bad conversion from: "+a;e+=b,f++}var g=parseInt(e,10);if(0===f||f+3>c)throw"MGRSPoint bad conversion from: "+a;var h=a.charAt(f++);if("A">=h||"B"===h||"Y"===h||h>="Z"||"I"===h||"O"===h)throw"MGRSPoint zone letter "+h+" not handled: "+a;d=a.substring(f,f+=2);for(var i=k(g),j=n(d.charAt(0),i),l=o(d.charAt(1),i);l0&&(q=1e5/Math.pow(10,v),r=a.substring(f,f+v),w=parseFloat(r)*q,s=a.substring(f+v),x=parseFloat(s)*q),t=w+j,u=x+l,{easting:t,northing:u,zoneLetter:h,zoneNumber:g,accuracy:q}}function n(a,b){for(var c=r.charCodeAt(b-1),d=1e5,e=!1;c!==a.charCodeAt(0);){if(c++,c===u&&c++,c===v&&c++,c>x){if(e)throw"Bad character: "+a;c=t,e=!0}d+=1e5}return d}function o(a,b){if(a>"V")throw"MGRSPoint given invalid Northing "+a;for(var c=s.charCodeAt(b-1),d=0,e=!1;c!==a.charCodeAt(0);){if(c++,c===u&&c++,c===v&&c++,c>w){if(e)throw"Bad character: "+a;c=t,e=!0}d+=1e5}return d}function p(a){var b;switch(a){case"C":b=11e5;break;case"D":b=2e6;break;case"E":b=28e5;break;case"F":b=37e5;break;case"G":b=46e5;break;case"H":b=55e5;break;case"J":b=64e5;break;case"K":b=73e5;break;case"L":b=82e5;break;case"M":b=91e5;break;case"N":b=0;break;case"P":b=8e5;break;case"Q":b=17e5;break;case"R":b=26e5;break;case"S":b=35e5;break;case"T":b=44e5;break;case"U":b=53e5;break;case"V":b=62e5;break;case"W":b=7e6;break;case"X":b=79e5;break;default:b=-1}if(b>=0)return b;throw"Invalid zone letter: "+a}var q=6,r="AJSAJS",s="AFAFAF",t=65,u=73,v=79,w=86,x=90;c.forward=function(a,b){return b=b||5,i(f({lat:a[1],lon:a[0]}),b)},c.inverse=function(a){var b=g(m(a.toUpperCase()));return b.lat&&b.lon?[b.lon,b.lat,b.lon,b.lat]:[b.left,b.bottom,b.right,b.top]},c.toPoint=function(a){var b=g(m(a.toUpperCase()));return b.lat&&b.lon?[b.lon,b.lat]:[(b.left+b.right)/2,(b.top+b.bottom)/2]}},{}],68:[function(a,b,c){b.exports={name:"proj4",version:"2.3.14",description:"Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.",main:"lib/index.js",directories:{test:"test",doc:"docs"},scripts:{test:"./node_modules/istanbul/lib/cli.js test ./node_modules/mocha/bin/_mocha test/test.js"},repository:{type:"git",url:"git://github.com/proj4js/proj4js.git"},author:"",license:"MIT",jam:{main:"dist/proj4.js",include:["dist/proj4.js","README.md","AUTHORS","LICENSE.md"]},devDependencies:{"grunt-cli":"~0.1.13",grunt:"~0.4.2","grunt-contrib-connect":"~0.6.0","grunt-contrib-jshint":"~0.8.0",chai:"~1.8.1",mocha:"~1.17.1","grunt-mocha-phantomjs":"~0.4.0",browserify:"~12.0.1","grunt-browserify":"~4.0.1","grunt-contrib-uglify":"~0.11.1",curl:"git://github.com/cujojs/curl.git",istanbul:"~0.2.4",tin:"~0.4.0"},dependencies:{mgrs:"~0.0.2"}}},{}],"./includedProjections":[function(a,b,c){b.exports=a("hTEDpn")},{}],hTEDpn:[function(a,b,c){var d=[a("./lib/projections/tmerc"),a("./lib/projections/utm"),a("./lib/projections/sterea"),a("./lib/projections/stere"),a("./lib/projections/somerc"),a("./lib/projections/omerc"),a("./lib/projections/lcc"),a("./lib/projections/krovak"),a("./lib/projections/cass"),a("./lib/projections/laea"),a("./lib/projections/aea"),a("./lib/projections/gnom"),a("./lib/projections/cea"),a("./lib/projections/eqc"),a("./lib/projections/poly"),a("./lib/projections/nzmg"),a("./lib/projections/mill"),a("./lib/projections/sinu"),a("./lib/projections/moll"),a("./lib/projections/eqdc"),a("./lib/projections/vandg"),a("./lib/projections/aeqd")];b.exports=function(proj4){d.forEach(function(a){proj4.Proj.projections.add(a)})}},{"./lib/projections/aea":40,"./lib/projections/aeqd":41,"./lib/projections/cass":42,"./lib/projections/cea":43,"./lib/projections/eqc":44,"./lib/projections/eqdc":45,"./lib/projections/gnom":47,"./lib/projections/krovak":48,"./lib/projections/laea":49,"./lib/projections/lcc":50,"./lib/projections/mill":53,"./lib/projections/moll":54,"./lib/projections/nzmg":55,"./lib/projections/omerc":56,"./lib/projections/poly":57,"./lib/projections/sinu":58,"./lib/projections/somerc":59,"./lib/projections/stere":60,"./lib/projections/sterea":61,"./lib/projections/tmerc":62,"./lib/projections/utm":63,"./lib/projections/vandg":64}]},{},[36])(36)}); \ No newline at end of file diff --git a/docs/articles/about_files/Proj4Leaflet-1.0.1/proj4leaflet.js b/docs/articles/about_files/Proj4Leaflet-1.0.1/proj4leaflet.js new file mode 100644 index 0000000..5ce8d47 --- /dev/null +++ b/docs/articles/about_files/Proj4Leaflet-1.0.1/proj4leaflet.js @@ -0,0 +1,272 @@ +(function (factory) { + var L, proj4; + if (typeof define === 'function' && define.amd) { + // AMD + define(['leaflet', 'proj4'], factory); + } else if (typeof module === 'object' && typeof module.exports === "object") { + // Node/CommonJS + L = require('leaflet'); + proj4 = require('proj4'); + module.exports = factory(L, proj4); + } else { + // Browser globals + if (typeof window.L === 'undefined' || typeof window.proj4 === 'undefined') + throw 'Leaflet and proj4 must be loaded first'; + factory(window.L, window.proj4); + } +}(function (L, proj4) { + if (proj4.__esModule && proj4.default) { + // If proj4 was bundled as an ES6 module, unwrap it to get + // to the actual main proj4 object. + // See discussion in https://github.com/kartena/Proj4Leaflet/pull/147 + proj4 = proj4.default; + } + + L.Proj = {}; + + L.Proj._isProj4Obj = function(a) { + return (typeof a.inverse !== 'undefined' && + typeof a.forward !== 'undefined'); + }; + + L.Proj.Projection = L.Class.extend({ + initialize: function(code, def, bounds) { + var isP4 = L.Proj._isProj4Obj(code); + this._proj = isP4 ? code : this._projFromCodeDef(code, def); + this.bounds = isP4 ? def : bounds; + }, + + project: function (latlng) { + var point = this._proj.forward([latlng.lng, latlng.lat]); + return new L.Point(point[0], point[1]); + }, + + unproject: function (point, unbounded) { + var point2 = this._proj.inverse([point.x, point.y]); + return new L.LatLng(point2[1], point2[0], unbounded); + }, + + _projFromCodeDef: function(code, def) { + if (def) { + proj4.defs(code, def); + } else if (proj4.defs[code] === undefined) { + var urn = code.split(':'); + if (urn.length > 3) { + code = urn[urn.length - 3] + ':' + urn[urn.length - 1]; + } + if (proj4.defs[code] === undefined) { + throw 'No projection definition for code ' + code; + } + } + + return proj4(code); + } + }); + + L.Proj.CRS = L.Class.extend({ + includes: L.CRS, + + options: { + transformation: new L.Transformation(1, 0, -1, 0) + }, + + initialize: function(a, b, c) { + var code, + proj, + def, + options; + + if (L.Proj._isProj4Obj(a)) { + proj = a; + code = proj.srsCode; + options = b || {}; + + this.projection = new L.Proj.Projection(proj, options.bounds); + } else { + code = a; + def = b; + options = c || {}; + this.projection = new L.Proj.Projection(code, def, options.bounds); + } + + L.Util.setOptions(this, options); + this.code = code; + this.transformation = this.options.transformation; + + if (this.options.origin) { + this.transformation = + new L.Transformation(1, -this.options.origin[0], + -1, this.options.origin[1]); + } + + if (this.options.scales) { + this._scales = this.options.scales; + } else if (this.options.resolutions) { + this._scales = []; + for (var i = this.options.resolutions.length - 1; i >= 0; i--) { + if (this.options.resolutions[i]) { + this._scales[i] = 1 / this.options.resolutions[i]; + } + } + } + + this.infinite = !this.options.bounds; + + }, + + scale: function(zoom) { + var iZoom = Math.floor(zoom), + baseScale, + nextScale, + scaleDiff, + zDiff; + if (zoom === iZoom) { + return this._scales[zoom]; + } else { + // Non-integer zoom, interpolate + baseScale = this._scales[iZoom]; + nextScale = this._scales[iZoom + 1]; + scaleDiff = nextScale - baseScale; + zDiff = (zoom - iZoom); + return baseScale + scaleDiff * zDiff; + } + }, + + zoom: function(scale) { + // Find closest number in this._scales, down + var downScale = this._closestElement(this._scales, scale), + downZoom = this._scales.indexOf(downScale), + nextScale, + nextZoom, + scaleDiff; + // Check if scale is downScale => return array index + if (scale === downScale) { + return downZoom; + } + if (downScale === undefined) { + return -Infinity; + } + // Interpolate + nextZoom = downZoom + 1; + nextScale = this._scales[nextZoom]; + if (nextScale === undefined) { + return Infinity; + } + scaleDiff = nextScale - downScale; + return (scale - downScale) / scaleDiff + downZoom; + }, + + distance: L.CRS.Earth.distance, + + R: L.CRS.Earth.R, + + /* Get the closest lowest element in an array */ + _closestElement: function(array, element) { + var low; + for (var i = array.length; i--;) { + if (array[i] <= element && (low === undefined || low < array[i])) { + low = array[i]; + } + } + return low; + } + }); + + L.Proj.GeoJSON = L.GeoJSON.extend({ + initialize: function(geojson, options) { + this._callLevel = 0; + L.GeoJSON.prototype.initialize.call(this, geojson, options); + }, + + addData: function(geojson) { + var crs; + + if (geojson) { + if (geojson.crs && geojson.crs.type === 'name') { + crs = new L.Proj.CRS(geojson.crs.properties.name); + } else if (geojson.crs && geojson.crs.type) { + crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code); + } + + if (crs !== undefined) { + this.options.coordsToLatLng = function(coords) { + var point = L.point(coords[0], coords[1]); + return crs.projection.unproject(point); + }; + } + } + + // Base class' addData might call us recursively, but + // CRS shouldn't be cleared in that case, since CRS applies + // to the whole GeoJSON, inluding sub-features. + this._callLevel++; + try { + L.GeoJSON.prototype.addData.call(this, geojson); + } finally { + this._callLevel--; + if (this._callLevel === 0) { + delete this.options.coordsToLatLng; + } + } + } + }); + + L.Proj.geoJson = function(geojson, options) { + return new L.Proj.GeoJSON(geojson, options); + }; + + L.Proj.ImageOverlay = L.ImageOverlay.extend({ + initialize: function (url, bounds, options) { + L.ImageOverlay.prototype.initialize.call(this, url, null, options); + this._projectedBounds = bounds; + }, + + // Danger ahead: Overriding internal methods in Leaflet. + // Decided to do this rather than making a copy of L.ImageOverlay + // and doing very tiny modifications to it. + // Future will tell if this was wise or not. + _animateZoom: function (event) { + var scale = this._map.getZoomScale(event.zoom); + var northWest = L.point(this._projectedBounds.min.x, this._projectedBounds.max.y); + var offset = this._projectedToNewLayerPoint(northWest, event.zoom, event.center); + + L.DomUtil.setTransform(this._image, offset, scale); + }, + + _reset: function () { + var zoom = this._map.getZoom(); + var pixelOrigin = this._map.getPixelOrigin(); + var bounds = L.bounds( + this._transform(this._projectedBounds.min, zoom)._subtract(pixelOrigin), + this._transform(this._projectedBounds.max, zoom)._subtract(pixelOrigin) + ); + var size = bounds.getSize(); + + L.DomUtil.setPosition(this._image, bounds.min); + this._image.style.width = size.x + 'px'; + this._image.style.height = size.y + 'px'; + }, + + _projectedToNewLayerPoint: function (point, zoom, center) { + var viewHalf = this._map.getSize()._divideBy(2); + var newTopLeft = this._map.project(center, zoom)._subtract(viewHalf)._round(); + var topLeft = newTopLeft.add(this._map._getMapPanePos()); + + return this._transform(point, zoom)._subtract(topLeft); + }, + + _transform: function (point, zoom) { + var crs = this._map.options.crs; + var transformation = crs.transformation; + var scale = crs.scale(zoom); + + return transformation.transform(point, scale); + } + }); + + L.Proj.imageOverlay = function (url, bounds, options) { + return new L.Proj.ImageOverlay(url, bounds, options); + }; + + return L.Proj; +})); diff --git a/docs/articles/about_files/figure-html/unnamed-chunk-1-1.png b/docs/articles/about_files/figure-html/unnamed-chunk-1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..484fe134094a6f5b245a45413c6e64dcf6baa7fa GIT binary patch literal 5194 zcmeHLX;c$g77kOA}F}x21G<;U))%fM%z(Pl&}dln-Qf+L4=SdKqDfetpR0m zX~7X>RS;7lSdn%K;6k&B6cjXuJtZI|1jrP6=JcF1%b7pjPM?_{RdwHe_q=-VzI(s> zy_dY#%}Hgx&U^xapyJ}ZV;_Mq4$-m@{*}pOx7u<$aEWxn z`Oql>VQJFbBbV0uK7c@=47lvrx*y0I?&yzxV?l8EdUTd*+ZnN3_4>WgmdgO1?SJ!FQECbZYE&QS_UEV5WNt!}W~4*R-VeikYE*(&Yo`w~lb_oGCUa92y0-or zYzpLJ^Om@k4<&Wqr9*=!Hg#o;*yM-YL#^2I7Fnl~XH8tTC$y{+*2snJ+UySqxY)>` zAmCul^9tX|{HMyAu$n%Zw4`1h;R`R>QWSNTZX_Wc>a=Ccz)BJoJqavDM#k0kcEVgC!2VX_6@;9X z;FE~HFgY71Ag%vpyF73X)oZ+7IS*Ze*ye4gle;Wc*I4KI)0Mj{-L6^uI48KcEw;N6 zPgm)3*&g8m$OZqphrcsmY&j0>k?~}^B--<9Y;pHX-sHqqNeAfK6tpA$#VfP38t~X< zn{2)IJMMCu^4vKE-HtEDc?=t&c7`4s_ z|8l#vC`84p%HqQ6D$=CbGu!|=PvsQ^iM$#QVx{YIClG$+6}P~5d%lCDH`4ZV0cMdrZKGN|x+ z?=B0+HLgIK3*hSqF16$m7t zCBv`FmAP6RECP9dSd*5x8Vm((L2g^j4Umz9J&!s3erP+;1~34sKju2k;f9l_x?2H3 zhrcEqV*b7>MtF+DO*O|YL+ZHIzwoi23W3NK_!#z}$H-_hI%}6R^r*e8yDeGxtW|qG zD7Jlkl^C7CHOXqZ!_d(-1U+D59yX=cX=d}p8q8ABghit;>%$X?PR>o<^p>BmhUA)~ zeexB3?3vUEi#DSoNL>cj%)+wemQDjjsJ!CF*H5-p*NhMe+5_<~ zy&e8Vq-vgaZb)zN!a<0ImFkT~{C)uAe-g<RDnq@) zQXuU^S@+&}U$yqtK9(gHF+o-2?NPlT!=Y_}Wn9bG+ru+${w#c5G%kN~gv z1cvm62k^uIEDU*o#$IkIO8jI<1;rgIko6YagqVn7DKup1RpGOPE$5M$L%5tpS$nWK z1DTnrZXuSkbi}pg zU{-tq_;LZ<8+LLKVRKMpx-UyV2EdfBwRs__W;)o{-$2yreKED zk{01CJZqD(2~wN%%YOwgPt}AQW!1Bj)dd2;hWe>W5G0%3fjynjW)J+mMyc-DZ8WDk zDd-NGv*spVKR&^xi3cEM2T;sXa}6v(W2H2Jjhxki(_ZjZ&5P0c zc1H|%$4+Hk*qenXwna}O)+0gqkre9ES0N;-p>CCR-+-xzCTIuQ$9fMRdgD0bySxPWWrb()A;LCoQ8`7h|57TP{vLrm$m=VUMo zg{#khrm@sjV2y|*876-wx6*CU-*>kd|AG_fR1P+9E6YI+Ohajcj6WyNjc$L$jlpIt z{7=qz6-NNM32d~2Kc(OuBvI7uVo~Ys1@sdpDZ?rz9hsTO0kJiVDHk?nW{%Wx7(UGd zb*_v+$a-VQw}E-qrpVHa`&Oon*_o(noo9Ate}gNa7jY_l3o8&`2G|qofr{DYr%)OWu zTjA}FPO3rHXHxD~iudj+;4n< zE5Mrd0K^;TbO3*2Y3{`%flr46|x&z{p$9^*hO+Yc7q4$-~E!Hs(V?Md?XZl)5R1yrtxC_6}^S;({*JSt>9OgN+Och!B zW_)l=O*0d#vL8$8^KTPAvuhCWdj&t$&n^?Z@DxO|Jdc*8guT6#$1K$i%8lA1TPqOx zNp0+nOxx~P3~$>#c`|Lncq~We8%sg5VZXzXnfH z%4Pqs`q@(scln_UXI+8C7yfx;h_Rn_+I9x*rLtx|cCTpk*0`%1V#j0ATyv4F(i3|r?01{&-Y(j&pYq^F=y_4-#v5g-21z~ z`FFuQ~8=ekc zVE(9%dUEkj4gs@C*shAnIfbY^U=d6#K+JMTEnS1S(g&Eei;vUBQ;z2Rf9roI8;KIc z29ws~u|F^N;F@)P-56yLxIZM8>P?znql#P|z3fGeBXK_Lq$Vf64+>7k^; zT17VbDp)r(8wY!jRh;JIM)rY-2lS{w15(qn1f|7^%0owex32&THHcICH}@3DWQ?5}{wSK?`+POFuPV%sVHoS~lY7bd>2B z05BE1I5Y8Efn=LsKZLw&#z0%-DVmL)NvUXBsF1uXeZ~MF`8+f`mVZw}6*P}Gwhv$? z&A{Dd*3CG)wisWf7L)}2%#ykVR=H2Oq!{an-v-Z>{GzIs>;<%~0e0%}=|+59wzl}K zHYJCJ6r>@1Gt`?!uviQZLsYw&wRHTFFfBga!cUL=^&I%-OPiLJpOY4x4gegbJM)@5 zTLsBz=gYSB3})Tn)(UcdlD3B6-xrkf>2CyON4N{RcdDzIQm<0XmB$MT6;Rh$1#+M3rzv+1}s;UO%7a*%ge};BQp6-tq z=um#tfZwqQ`#4%~jc*L;s+IP?R!mbnp@{ob7rkG+a9sS7is3J?>6!~DH@<`g-dT?q zS%I;1z1pqVy;a_{#g4&1CvTW^?Xhk@Fu<0EpeOq4hZ)AKqe>;ow-5lau9g5ahV2d~4nvU2J(LKHp{B7eo)o#cf zG-%M6?}IvIY-Z=4N8${6BR74{2~vt8WQBN;6B}yS?}BoMZqHzcNdIZ_#*Cr7lj=_P z0YGflg~+L>B=@Jll;n9z>z4%aL?h>hv71q}by4q@#!OZcN&^193`Oa{Wv7~sv!#n% zn!_N5bZlT)dH4AKv2-wAr}Ur+*+%xcuP z1<410xQr1k%^Yz5HmS{CCydghF@LzJH_1z-CHks;r;`a-H}-Gyz8#7XhVu4(Fb7j+2AWBq>4!w&tYUMMT5F1jwxg0`)=RPupecdM`I!hKIkk^gXHh@ zQwcfU=vTj;o_u`c<5W;0;;Hj|T+8po1)&qOOUqI<-8DtUWa!+^qfZsFXAfPMV2M-} zv96BE(5c6t(jlo2H)P&?@x?LcCRb5aw61%aYyF2|YZgJLGJy*^#GW+;ePZv8+*y6X zxvA@e^K{+K*#e&@-fec5DB~8cA<7dlNfexO0x8om=%8L7FW9rBWi7CE9%acKqE*8| z&~ho9h@*?kwH{N?q&80g;s?&v zKB@Hd!os1=vS+%Ji}WwGA8rVd4=)b@Ld6MBJSgu^AO)geh_RL2AYTEJ8OdK>!HW+q zvIgH+*6?wm^HAFcj2*mJG^_S2aM*zY#NO9u5kA^sKxpAREb&MK6fx`&0Wdj10OalW zz00-b0@;V^F6ZJ3L2&;Au;hr>6}EIO02RKJXlUw-36R=s#{&RwEefE|DM9JM3YWtM zH_X5~tqW_Dlzu?UXz#HiP&$WLQnlrP`%8&7CG60fbr;w5?*6DLjPd9*Uxo_hJiNG( zMRTCprGA@?-8IHcGm3;!sc@ z;8u6jnrYyk+4vI{9)IPvfYRSO?y9rfApqdCIp0E5oGVQ(fuJCjCLco!B4<=U`IP?if~HBNw5$!j=Pu2kHJyQ9l8D?a z=i_c`j<5Kz5t836hu*4%9tabSVJz)EY3evQe+)~sy@>KDs`Jnu_!MjWeLptjis>;f zxn>IPJN#Y9Ox1eLJmA>NRs9o$crxtm4lDa!E4(;mYf(^Cb&v(9S{}%4iRbzN>QQ$nxvwa>h*rxs)W60K zGR(PmIPy9@l25XYo@n-wHnV79PhOwTm7Ldr>;AeIVeIGqek%Q$|Ep5<3w@bJUNHq4 zZ3)sx_C3;aw-$?TJRKP>PFCdp`4@Yh#9k$Ki8%65uCAG)& z`Hqz&g~|iPZKK5(!|v4PLT9Fg+i7r*8IjyWvwA<7iex?))X-jR{HB~mb8OX%nof2! zc0HTV0OIJ+K<*J!__d(VNLAOU z5`^;Li|7eX$f-=DhYE$;y}}}}+$RVi?qWB5h|3$AU%o@^df4H3l7$u6Y1^=ik-HqM z^q*_w8+M(!npGpJp(>o>`$Lre%y1KTTUyP~dld3ha@4f-JF~zU2aK8<2 zb&v%Pj(|ICqk)6yT?9DQz zz2vp?c=FH(k*w7$JAdR+{@!ZiL{me1SlHK0&y6V@&f9B2>SU1GH!1$HPIfveR2d~c zj!?uA(h&!d+*TMqSkG!ye7+$?ndFN+bg^#mw>`Po8Zt8!1dUc#)pbU;&qKyQ~E-2 z+wNk<^rN(*)ekO)M=").addClass(errClass); + errorSpan.text(err.message); + $el.after(errorSpan); + } + } else if (display === "block") { + // If block, add an error just after the el, set visibility:none on the + // el, and position the error to be on top of the el. + // Mark it with a unique ID and CSS class so we can remove it later. + $el.css("visibility", "hidden"); + if (err.message !== "") { + var errorDiv = $("
").addClass(errClass).css("position", "absolute") + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + // setting width can push out the page size, forcing otherwise + // unnecessary scrollbars to appear and making it impossible for + // the element to shrink; so use max-width instead + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + errorDiv.text(err.message); + $el.after(errorDiv); + + // Really dumb way to keep the size/position of the error in sync with + // the parent element as the window is resized or whatever. + var intId = setInterval(function() { + if (!errorDiv[0].parentElement) { + clearInterval(intId); + return; + } + errorDiv + .css("top", el.offsetTop) + .css("left", el.offsetLeft) + .css("maxWidth", el.offsetWidth) + .css("height", el.offsetHeight); + }, 500); + } + } + }, + clearError: function(el) { + var $el = $(el); + var display = $el.data("restore-display-mode"); + $el.data("restore-display-mode", null); + + if (display === "inline" || display === "inline-block") { + if (display) + $el.css("display", display); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } else if (display === "block"){ + $el.css("visibility", "inherit"); + $(el.nextSibling).filter(".htmlwidgets-error").remove(); + } + }, + sizing: {} + }; + + // Called by widget bindings to register a new type of widget. The definition + // object can contain the following properties: + // - name (required) - A string indicating the binding name, which will be + // used by default as the CSS classname to look for. + // - initialize (optional) - A function(el) that will be called once per + // widget element; if a value is returned, it will be passed as the third + // value to renderValue. + // - renderValue (required) - A function(el, data, initValue) that will be + // called with data. Static contexts will cause this to be called once per + // element; Shiny apps will cause this to be called multiple times per + // element, as the data changes. + window.HTMLWidgets.widget = function(definition) { + if (!definition.name) { + throw new Error("Widget must have a name"); + } + if (!definition.type) { + throw new Error("Widget must have a type"); + } + // Currently we only support output widgets + if (definition.type !== "output") { + throw new Error("Unrecognized widget type '" + definition.type + "'"); + } + // TODO: Verify that .name is a valid CSS classname + + // Support new-style instance-bound definitions. Old-style class-bound + // definitions have one widget "object" per widget per type/class of + // widget; the renderValue and resize methods on such widget objects + // take el and instance arguments, because the widget object can't + // store them. New-style instance-bound definitions have one widget + // object per widget instance; the definition that's passed in doesn't + // provide renderValue or resize methods at all, just the single method + // factory(el, width, height) + // which returns an object that has renderValue(x) and resize(w, h). + // This enables a far more natural programming style for the widget + // author, who can store per-instance state using either OO-style + // instance fields or functional-style closure variables (I guess this + // is in contrast to what can only be called C-style pseudo-OO which is + // what we required before). + if (definition.factory) { + definition = createLegacyDefinitionAdapter(definition); + } + + if (!definition.renderValue) { + throw new Error("Widget must have a renderValue function"); + } + + // For static rendering (non-Shiny), use a simple widget registration + // scheme. We also use this scheme for Shiny apps/documents that also + // contain static widgets. + window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || []; + // Merge defaults into the definition; don't mutate the original definition. + var staticBinding = extend({}, defaults, definition); + overrideMethod(staticBinding, "find", function(superfunc) { + return function(scope) { + var results = superfunc(scope); + // Filter out Shiny outputs, we only want the static kind + return filterByClass(results, "html-widget-output", false); + }; + }); + window.HTMLWidgets.widgets.push(staticBinding); + + if (shinyMode) { + // Shiny is running. Register the definition with an output binding. + // The definition itself will not be the output binding, instead + // we will make an output binding object that delegates to the + // definition. This is because we foolishly used the same method + // name (renderValue) for htmlwidgets definition and Shiny bindings + // but they actually have quite different semantics (the Shiny + // bindings receive data that includes lots of metadata that it + // strips off before calling htmlwidgets renderValue). We can't + // just ignore the difference because in some widgets it's helpful + // to call this.renderValue() from inside of resize(), and if + // we're not delegating, then that call will go to the Shiny + // version instead of the htmlwidgets version. + + // Merge defaults with definition, without mutating either. + var bindingDef = extend({}, defaults, definition); + + // This object will be our actual Shiny binding. + var shinyBinding = new Shiny.OutputBinding(); + + // With a few exceptions, we'll want to simply use the bindingDef's + // version of methods if they are available, otherwise fall back to + // Shiny's defaults. NOTE: If Shiny's output bindings gain additional + // methods in the future, and we want them to be overrideable by + // HTMLWidget binding definitions, then we'll need to add them to this + // list. + delegateMethod(shinyBinding, bindingDef, "getId"); + delegateMethod(shinyBinding, bindingDef, "onValueChange"); + delegateMethod(shinyBinding, bindingDef, "onValueError"); + delegateMethod(shinyBinding, bindingDef, "renderError"); + delegateMethod(shinyBinding, bindingDef, "clearError"); + delegateMethod(shinyBinding, bindingDef, "showProgress"); + + // The find, renderValue, and resize are handled differently, because we + // want to actually decorate the behavior of the bindingDef methods. + + shinyBinding.find = function(scope) { + var results = bindingDef.find(scope); + + // Only return elements that are Shiny outputs, not static ones + var dynamicResults = results.filter(".html-widget-output"); + + // It's possible that whatever caused Shiny to think there might be + // new dynamic outputs, also caused there to be new static outputs. + // Since there might be lots of different htmlwidgets bindings, we + // schedule execution for later--no need to staticRender multiple + // times. + if (results.length !== dynamicResults.length) + scheduleStaticRender(); + + return dynamicResults; + }; + + // Wrap renderValue to handle initialization, which unfortunately isn't + // supported natively by Shiny at the time of this writing. + + shinyBinding.renderValue = function(el, data) { + Shiny.renderDependencies(data.deps); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var i = 0; data.evals && i < data.evals.length; i++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]); + } + if (!bindingDef.renderOnNullValue) { + if (data.x === null) { + el.style.visibility = "hidden"; + return; + } else { + el.style.visibility = "inherit"; + } + } + if (!elementData(el, "initialized")) { + initSizing(el); + + elementData(el, "initialized", true); + if (bindingDef.initialize) { + var result = bindingDef.initialize(el, el.offsetWidth, + el.offsetHeight); + elementData(el, "init_result", result); + } + } + bindingDef.renderValue(el, data.x, elementData(el, "init_result")); + evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]); + }; + + // Only override resize if bindingDef implements it + if (bindingDef.resize) { + shinyBinding.resize = function(el, width, height) { + // Shiny can call resize before initialize/renderValue have been + // called, which doesn't make sense for widgets. + if (elementData(el, "initialized")) { + bindingDef.resize(el, width, height, elementData(el, "init_result")); + } + }; + } + + Shiny.outputBindings.register(shinyBinding, bindingDef.name); + } + }; + + var scheduleStaticRenderTimerId = null; + function scheduleStaticRender() { + if (!scheduleStaticRenderTimerId) { + scheduleStaticRenderTimerId = setTimeout(function() { + scheduleStaticRenderTimerId = null; + window.HTMLWidgets.staticRender(); + }, 1); + } + } + + // Render static widgets after the document finishes loading + // Statically render all elements that are of this widget's class + window.HTMLWidgets.staticRender = function() { + var bindings = window.HTMLWidgets.widgets || []; + forEach(bindings, function(binding) { + var matches = binding.find(document.documentElement); + forEach(matches, function(el) { + var sizeObj = initSizing(el, binding); + + if (hasClass(el, "html-widget-static-bound")) + return; + el.className = el.className + " html-widget-static-bound"; + + var initResult; + if (binding.initialize) { + initResult = binding.initialize(el, + sizeObj ? sizeObj.getWidth() : el.offsetWidth, + sizeObj ? sizeObj.getHeight() : el.offsetHeight + ); + elementData(el, "init_result", initResult); + } + + if (binding.resize) { + var lastSize = { + w: sizeObj ? sizeObj.getWidth() : el.offsetWidth, + h: sizeObj ? sizeObj.getHeight() : el.offsetHeight + }; + var resizeHandler = function(e) { + var size = { + w: sizeObj ? sizeObj.getWidth() : el.offsetWidth, + h: sizeObj ? sizeObj.getHeight() : el.offsetHeight + }; + if (size.w === 0 && size.h === 0) + return; + if (size.w === lastSize.w && size.h === lastSize.h) + return; + lastSize = size; + binding.resize(el, size.w, size.h, initResult); + }; + + on(window, "resize", resizeHandler); + + // This is needed for cases where we're running in a Shiny + // app, but the widget itself is not a Shiny output, but + // rather a simple static widget. One example of this is + // an rmarkdown document that has runtime:shiny and widget + // that isn't in a render function. Shiny only knows to + // call resize handlers for Shiny outputs, not for static + // widgets, so we do it ourselves. + if (window.jQuery) { + window.jQuery(document).on( + "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets", + resizeHandler + ); + window.jQuery(document).on( + "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets", + resizeHandler + ); + } + + // This is needed for the specific case of ioslides, which + // flips slides between display:none and display:block. + // Ideally we would not have to have ioslide-specific code + // here, but rather have ioslides raise a generic event, + // but the rmarkdown package just went to CRAN so the + // window to getting that fixed may be long. + if (window.addEventListener) { + // It's OK to limit this to window.addEventListener + // browsers because ioslides itself only supports + // such browsers. + on(document, "slideenter", resizeHandler); + on(document, "slideleave", resizeHandler); + } + } + + var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']"); + if (scriptData) { + var data = JSON.parse(scriptData.textContent || scriptData.text); + // Resolve strings marked as javascript literals to objects + if (!(data.evals instanceof Array)) data.evals = [data.evals]; + for (var k = 0; data.evals && k < data.evals.length; k++) { + window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]); + } + binding.renderValue(el, data.x, initResult); + evalAndRun(data.jsHooks.render, initResult, [el, data.x]); + } + }); + }); + + invokePostRenderHandlers(); + } + + // Wait until after the document has loaded to render the widgets. + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", function() { + document.removeEventListener("DOMContentLoaded", arguments.callee, false); + window.HTMLWidgets.staticRender(); + }, false); + } else if (document.attachEvent) { + document.attachEvent("onreadystatechange", function() { + if (document.readyState === "complete") { + document.detachEvent("onreadystatechange", arguments.callee); + window.HTMLWidgets.staticRender(); + } + }); + } + + + window.HTMLWidgets.getAttachmentUrl = function(depname, key) { + // If no key, default to the first item + if (typeof(key) === "undefined") + key = 1; + + var link = document.getElementById(depname + "-" + key + "-attachment"); + if (!link) { + throw new Error("Attachment " + depname + "/" + key + " not found in document"); + } + return link.getAttribute("href"); + }; + + window.HTMLWidgets.dataframeToD3 = function(df) { + var names = []; + var length; + for (var name in df) { + if (df.hasOwnProperty(name)) + names.push(name); + if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") { + throw new Error("All fields must be arrays"); + } else if (typeof(length) !== "undefined" && length !== df[name].length) { + throw new Error("All fields must be arrays of the same length"); + } + length = df[name].length; + } + var results = []; + var item; + for (var row = 0; row < length; row++) { + item = {}; + for (var col = 0; col < names.length; col++) { + item[names[col]] = df[names[col]][row]; + } + results.push(item); + } + return results; + }; + + window.HTMLWidgets.transposeArray2D = function(array) { + if (array.length === 0) return array; + var newArray = array[0].map(function(col, i) { + return array.map(function(row) { + return row[i] + }) + }); + return newArray; + }; + // Split value at splitChar, but allow splitChar to be escaped + // using escapeChar. Any other characters escaped by escapeChar + // will be included as usual (including escapeChar itself). + function splitWithEscape(value, splitChar, escapeChar) { + var results = []; + var escapeMode = false; + var currentResult = ""; + for (var pos = 0; pos < value.length; pos++) { + if (!escapeMode) { + if (value[pos] === splitChar) { + results.push(currentResult); + currentResult = ""; + } else if (value[pos] === escapeChar) { + escapeMode = true; + } else { + currentResult += value[pos]; + } + } else { + currentResult += value[pos]; + escapeMode = false; + } + } + if (currentResult !== "") { + results.push(currentResult); + } + return results; + } + // Function authored by Yihui/JJ Allaire + window.HTMLWidgets.evaluateStringMember = function(o, member) { + var parts = splitWithEscape(member, '.', '\\'); + for (var i = 0, l = parts.length; i < l; i++) { + var part = parts[i]; + // part may be a character or 'numeric' member name + if (o !== null && typeof o === "object" && part in o) { + if (i == (l - 1)) { // if we are at the end of the line then evalulate + if (typeof o[part] === "string") + o[part] = eval("(" + o[part] + ")"); + } else { // otherwise continue to next embedded object + o = o[part]; + } + } + } + }; + + // Retrieve the HTMLWidget instance (i.e. the return value of an + // HTMLWidget binding's initialize() or factory() function) + // associated with an element, or null if none. + window.HTMLWidgets.getInstance = function(el) { + return elementData(el, "init_result"); + }; + + // Finds the first element in the scope that matches the selector, + // and returns the HTMLWidget instance (i.e. the return value of + // an HTMLWidget binding's initialize() or factory() function) + // associated with that element, if any. If no element matches the + // selector, or the first matching element has no HTMLWidget + // instance associated with it, then null is returned. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.find = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var el = scope.querySelector(selector); + if (el === null) { + return null; + } else { + return window.HTMLWidgets.getInstance(el); + } + }; + + // Finds all elements in the scope that match the selector, and + // returns the HTMLWidget instances (i.e. the return values of + // an HTMLWidget binding's initialize() or factory() function) + // associated with the elements, in an array. If elements that + // match the selector don't have an associated HTMLWidget + // instance, the returned array will contain nulls. + // + // The scope argument is optional, and defaults to window.document. + window.HTMLWidgets.findAll = function(scope, selector) { + if (arguments.length == 1) { + selector = scope; + scope = document; + } + + var nodes = scope.querySelectorAll(selector); + var results = []; + for (var i = 0; i < nodes.length; i++) { + results.push(window.HTMLWidgets.getInstance(nodes[i])); + } + return results; + }; + + var postRenderHandlers = []; + function invokePostRenderHandlers() { + while (postRenderHandlers.length) { + var handler = postRenderHandlers.shift(); + if (handler) { + handler(); + } + } + } + + // Register the given callback function to be invoked after the + // next time static widgets are rendered. + window.HTMLWidgets.addPostRenderHandler = function(callback) { + postRenderHandlers.push(callback); + }; + + // Takes a new-style instance-bound definition, and returns an + // old-style class-bound definition. This saves us from having + // to rewrite all the logic in this file to accomodate both + // types of definitions. + function createLegacyDefinitionAdapter(defn) { + var result = { + name: defn.name, + type: defn.type, + initialize: function(el, width, height) { + return defn.factory(el, width, height); + }, + renderValue: function(el, x, instance) { + return instance.renderValue(x); + }, + resize: function(el, width, height, instance) { + return instance.resize(width, height); + } + }; + + if (defn.find) + result.find = defn.find; + if (defn.renderError) + result.renderError = defn.renderError; + if (defn.clearError) + result.clearError = defn.clearError; + + return result; + } +})(); + diff --git a/docs/articles/about_files/jquery-1.12.4/jquery.min.js b/docs/articles/about_files/jquery-1.12.4/jquery.min.js new file mode 100644 index 0000000..e836475 --- /dev/null +++ b/docs/articles/about_files/jquery-1.12.4/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("