diff options
Diffstat (limited to 'docs')
32 files changed, 4925 insertions, 196 deletions
diff --git a/docs/404.html b/docs/404.html index 80410c2..22c2979 100644 --- a/docs/404.html +++ b/docs/404.html @@ -61,7 +61,7 @@ Content not found. Please use links in the navbar. </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer> diff --git a/docs/404.md b/docs/404.md new file mode 100644 index 0000000..5107f89 --- /dev/null +++ b/docs/404.md @@ -0,0 +1,3 @@ +Content not found. Please use links in the navbar. + +# Page not found (404) diff --git a/docs/authors.html b/docs/authors.html index d892a2a..a11c70d 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -66,7 +66,7 @@ R package version 0.4.1, <a href="https://pkgdown.jrwb.de/chents">https://pkgdow </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer></div> diff --git a/docs/authors.md b/docs/authors.md new file mode 100644 index 0000000..e297afa --- /dev/null +++ b/docs/authors.md @@ -0,0 +1,21 @@ +# Authors and Citation + +## Authors + +- **Johannes Ranke**. Author, maintainer, copyright holder. + +## Citation + +Source: +[`DESCRIPTION`](https://github.com/jranke/chents/blob/HEAD/DESCRIPTION) + +Ranke J (2026). *chents: Chemical Entities as R Objects*. R package +version 0.4.1, <https://pkgdown.jrwb.de/chents>. + + @Manual{, + title = {chents: Chemical Entities as R Objects}, + author = {Johannes Ranke}, + year = {2026}, + note = {R package version 0.4.1}, + url = {https://pkgdown.jrwb.de/chents}, + } diff --git a/docs/coverage/coverage.html b/docs/coverage/coverage.html index 1e9d0ad..5b3b3f1 100644 --- a/docs/coverage/coverage.html +++ b/docs/coverage/coverage.html @@ -3,16 +3,16 @@ <head> <meta charset="utf-8"/> <style>body{background-color:white;}</style> -<link href="lib/htmltools-fill-0.5.8.1/fill.css" rel="stylesheet" /> +<link href="lib/htmltools-fill-0.5.9/fill.css" rel="stylesheet" /> <script src="lib/htmlwidgets-1.6.4/htmlwidgets.js"></script> <link href="lib/datatables-css-0.0.0/datatables-crosstalk.css" rel="stylesheet" /> -<script src="lib/datatables-binding-0.33/datatables.js"></script> +<script src="lib/datatables-binding-0.34.0/datatables.js"></script> <script src="lib/jquery-3.6.0/jquery-3.6.0.min.js"></script> <link href="lib/dt-core-1.13.6/css/jquery.dataTables.min.css" rel="stylesheet" /> <link href="lib/dt-core-1.13.6/css/jquery.dataTables.extra.css" rel="stylesheet" /> <script src="lib/dt-core-1.13.6/js/jquery.dataTables.min.js"></script> -<link href="lib/crosstalk-1.2.1/css/crosstalk.min.css" rel="stylesheet" /> -<script src="lib/crosstalk-1.2.1/js/crosstalk.min.js"></script> +<link href="lib/crosstalk-1.2.2/css/crosstalk.min.css" rel="stylesheet" /> +<script src="lib/crosstalk-1.2.2/js/crosstalk.min.js"></script> <link href="lib/highlight.js-6.2/rstudio.css" rel="stylesheet" /> <script src="lib/highlight.js-6.2/highlight.pack.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1" /> @@ -95,7 +95,7 @@ table.table-condensed { font-size: 11px; }</style> <div class="col-md-8 col-md-offset-2"> - <h2>chents coverage - 34.64%</h2> + <h2>chents coverage - 33.77%</h2> <div class="tabbable"> <ul class="nav nav-tabs" data-tabsetid="covr"> <li class="active"> @@ -107,8 +107,8 @@ table.table-condensed { </ul> <div class="tab-content" data-tabsetid="covr"> <div class="tab-pane active" title="Files" data-value="Files" id="tab-covr-1"> - <div class="datatables html-widget html-fill-item" id="htmlwidget-702167ad1bbf5cac83c0" style="width:100%;height:500px;"></div> - <script type="application/json" data-for="htmlwidget-702167ad1bbf5cac83c0">{"x":{"filter":"none","vertical":false,"fillContainer":false,"data":[["<a href=\"#\">R/zzz.R<\/a>","<a href=\"#\">R/chent.R<\/a>"],[9,828],[7,299],[0,106],[7,193],["0","1"],["0.00%","35.45%"]],"container":"<table class=\"row-border\">\n <thead>\n <tr>\n <th>File<\/th>\n <th>Lines<\/th>\n <th>Relevant<\/th>\n <th>Covered<\/th>\n <th>Missed<\/th>\n <th>Hits / Line<\/th>\n <th>Coverage<\/th>\n <\/tr>\n <\/thead>\n<\/table>","options":{"searching":false,"dom":"t","paging":false,"columnDefs":[{"targets":6,"createdCell":"function(td, cellData, rowData, row, col) {\n var percent = cellData.replace(\"%\", \"\");\n if (percent > 90) {\n var grad = \"linear-gradient(90deg, #edfde7 \" + cellData + \", white \" + cellData + \")\";\n } else if (percent > 75) {\n var grad = \"linear-gradient(90deg, #f9ffe5 \" + cellData + \", white \" + cellData + \")\";\n } else {\n var grad = \"linear-gradient(90deg, #fcece9 \" + cellData + \", white \" + cellData + \")\";\n }\n $(td).css(\"background\", grad);\n}\n"},{"className":"dt-right","targets":[1,2,3,4]},{"name":"File","targets":0},{"name":"Lines","targets":1},{"name":"Relevant","targets":2},{"name":"Covered","targets":3},{"name":"Missed","targets":4},{"name":"Hits / Line","targets":5},{"name":"Coverage","targets":6}],"order":[],"autoWidth":false,"orderClasses":false},"callback":"function(table) {\ntable.on('click.dt', 'a', function() {\n files = $('div#files div');\n files.not('div.hidden').addClass('hidden');\n id = $(this).text();\n files.filter('div[id=\\'' + id + '\\']').removeClass('hidden');\n $('ul.nav a[data-value=Source]').text(id).tab('show');\n});\n}"},"evals":["options.columnDefs.0.createdCell","callback"],"jsHooks":[]}</script> + <div class="datatables html-widget html-fill-item" id="htmlwidget-1091363a91657664bb06" style="width:100%;height:500px;"></div> + <script type="application/json" data-for="htmlwidget-1091363a91657664bb06">{"x":{"filter":"none","vertical":false,"fillContainer":false,"data":[["<a href=\"#\">R/zzz.R<\/a>","<a href=\"#\">R/chent.R<\/a>"],[9,828],[7,301],[0,104],[7,197],["0","0"],["0.00%","34.55%"]],"container":"<table class=\"row-border\">\n <thead>\n <tr>\n <th>File<\/th>\n <th>Lines<\/th>\n <th>Relevant<\/th>\n <th>Covered<\/th>\n <th>Missed<\/th>\n <th>Hits / Line<\/th>\n <th>Coverage<\/th>\n <\/tr>\n <\/thead>\n<\/table>","options":{"searching":false,"dom":"t","paging":false,"columnDefs":[{"targets":6,"createdCell":"function(td, cellData, rowData, row, col) {\n var percent = cellData.replace(\"%\", \"\");\n if (percent > 90) {\n var grad = \"linear-gradient(90deg, #edfde7 \" + cellData + \", white \" + cellData + \")\";\n } else if (percent > 75) {\n var grad = \"linear-gradient(90deg, #f9ffe5 \" + cellData + \", white \" + cellData + \")\";\n } else {\n var grad = \"linear-gradient(90deg, #fcece9 \" + cellData + \", white \" + cellData + \")\";\n }\n $(td).css(\"background\", grad);\n}\n"},{"className":"dt-right","targets":[1,2,3,4]},{"name":"File","targets":0},{"name":"Lines","targets":1},{"name":"Relevant","targets":2},{"name":"Covered","targets":3},{"name":"Missed","targets":4},{"name":"Hits / Line","targets":5},{"name":"Coverage","targets":6}],"order":[],"autoWidth":false,"orderClasses":false},"callback":"function(table) {\ntable.on('click.dt', 'a', function() {\n files = $('div#files div');\n files.not('div.hidden').addClass('hidden');\n id = $(this).text();\n files.filter('div[id=\\'' + id + '\\']').removeClass('hidden');\n $('ul.nav a[data-value=Source]').text(id).tab('show');\n});\n}"},"evals":["options.columnDefs.0.createdCell","callback"],"jsHooks":[]}</script> </div> <div class="tab-pane" title="Source" data-value="Source" id="tab-covr-2"> <div id="files"> @@ -990,16 +990,16 @@ table.table-condensed { <pre class="language-r"> if (rdkit) {</pre> </td> </tr> - <tr class="covered"> + <tr class="missed"> <td class="num">126</td> - <td class="coverage">1<em>x</em></td> + <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> if (rdkit_available) {</pre> </td> </tr> - <tr class="covered"> + <tr class="missed"> <td class="num">127</td> - <td class="coverage">1<em>x</em></td> + <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> self$get_rdkit(template = template)</pre> </td> @@ -1692,28 +1692,28 @@ table.table-condensed { </tr> <tr class="covered"> <td class="num">226</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> available_smiles <- names(self$smiles)</pre> </td> </tr> <tr class="covered"> <td class="num">227</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> smiles_preference <- c("user", "PubChem", "PubChem_Connectivity")</pre> </td> </tr> <tr class="covered"> <td class="num">228</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> smiles_preferred_i <- min(match(available_smiles, smiles_preference))</pre> </td> </tr> <tr class="covered"> <td class="num">229</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> smiles_preferred <- smiles_preference[smiles_preferred_i]</pre> </td> @@ -1727,56 +1727,56 @@ table.table-condensed { </tr> <tr class="covered"> <td class="num">231</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> message("Get chemical information from RDKit using ",</pre> </td> </tr> <tr class="covered"> <td class="num">232</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> smiles_preferred, " SMILES\n",</pre> </td> </tr> <tr class="covered"> <td class="num">233</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$smiles[smiles_preferred])</pre> </td> </tr> <tr class="covered"> <td class="num">234</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$rdkit <- list()</pre> </td> </tr> <tr class="covered"> <td class="num">235</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$mol <- rdkit_module$Chem$MolFromSmiles(self$smiles[1])</pre> </td> </tr> <tr class="covered"> <td class="num">236</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$rdkit$mw <- rdkit_module$Chem$Descriptors$MolWt(self$mol)</pre> </td> </tr> <tr class="covered"> <td class="num">237</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (!is.null(self$mw) && !is.na(self$mw)) {</pre> </td> </tr> <tr class="covered"> <td class="num">238</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (round(self$rdkit$mw, 1) != round(self$mw, 1)) {</pre> </td> @@ -1839,14 +1839,14 @@ table.table-condensed { </tr> <tr class="covered"> <td class="num">247</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> rdkit_module$Chem$rdDepictor$Compute2DCoords(self$mol)</pre> </td> </tr> <tr class="covered"> <td class="num">248</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (!is.null(template)) {</pre> </td> @@ -1881,56 +1881,56 @@ table.table-condensed { </tr> <tr class="covered"> <td class="num">253</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> d2d <- rdkit_module$Chem$Draw$rdMolDraw2D$MolDraw2DSVG(400L, 400L)</pre> </td> </tr> <tr class="covered"> <td class="num">254</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> d2d$DrawMolecule(self$mol)</pre> </td> </tr> <tr class="covered"> <td class="num">255</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> d2d$FinishDrawing()</pre> </td> </tr> <tr class="covered"> <td class="num">256</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$svg <- d2d$GetDrawingText()</pre> </td> </tr> <tr class="covered"> <td class="num">257</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> svgfile <- tempfile(fileext = ".svg")</pre> </td> </tr> <tr class="covered"> <td class="num">258</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> psfile <- tempfile(fileext = ".ps")</pre> </td> </tr> <tr class="covered"> <td class="num">259</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> writeLines(self$svg, svgfile)</pre> </td> </tr> <tr class="covered"> <td class="num">260</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> rsvg::rsvg_ps(svgfile, psfile)</pre> </td> @@ -1951,21 +1951,21 @@ table.table-condensed { </tr> <tr class="covered"> <td class="num">263</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> ps_font_line <- grep("Tm$", readLines(psfile), value = TRUE)[1]</pre> </td> </tr> <tr class="covered"> <td class="num">264</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> ps_font_size <- gsub(" .*$", "", ps_font_line)</pre> </td> </tr> <tr class="covered"> <td class="num">265</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$Pict_font_size = as.numeric(ps_font_size)</pre> </td> @@ -1986,35 +1986,35 @@ table.table-condensed { </tr> <tr class="covered"> <td class="num">268</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> xmlfile <- tempfile(fileext = ".xml")</pre> </td> </tr> <tr class="covered"> <td class="num">269</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> PostScriptTrace(psfile, outfilename = xmlfile)</pre> </td> </tr> <tr class="covered"> <td class="num">270</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> unlink(paste0("capture", basename(psfile)))</pre> </td> </tr> <tr class="covered"> <td class="num">271</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$Picture <- readPicture(xmlfile)</pre> </td> </tr> <tr class="covered"> <td class="num">272</td> - <td class="coverage">2<em>x</em></td> + <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> unlink(c(xmlfile, psfile, svgfile))</pre> </td> @@ -4690,126 +4690,126 @@ table.table-condensed { <td class="num">654</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' # On Travis, we get a certificate validation error,</pre> + <pre class="language-r">#' atr <- pai$new("atrazine")</pre> </td> </tr> <tr class="never"> <td class="num">655</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' # likely because the system (xenial) is so old,</pre> + <pre class="language-r">#' print(atr)</pre> </td> </tr> <tr class="never"> <td class="num">656</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' # therefore don't run this example on Travis</pre> + <pre class="language-r">#' if (!is.null(atr$Picture)) {</pre> </td> </tr> <tr class="never"> <td class="num">657</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' if (Sys.getenv("TRAVIS") == "") {</pre> + <pre class="language-r">#' plot(atr)</pre> </td> </tr> <tr class="never"> <td class="num">658</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#'</pre> + <pre class="language-r">#' }</pre> </td> </tr> <tr class="never"> <td class="num">659</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' atr <- pai$new("atrazine")</pre> + <pre class="language-r">#' # We can also define pais that are not found on the BCPC site</pre> </td> </tr> <tr class="never"> <td class="num">660</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' print(atr)</pre> + <pre class="language-r">#' decanol <- pai$new("1-Decanol")</pre> </td> </tr> <tr class="never"> <td class="num">661</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' if (!is.null(atr$Picture)) {</pre> + <pre class="language-r">#' print(decanol)</pre> </td> </tr> <tr class="never"> <td class="num">662</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' plot(atr)</pre> + <pre class="language-r">pai <- R6Class("pai",</pre> </td> </tr> <tr class="never"> <td class="num">663</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' }</pre> + <pre class="language-r"> inherit = chent,</pre> </td> </tr> <tr class="never"> <td class="num">664</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#'</pre> + <pre class="language-r"> public = list(</pre> </td> </tr> <tr class="never"> <td class="num">665</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">#' }</pre> + <pre class="language-r"></pre> </td> </tr> <tr class="never"> <td class="num">666</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r">pai <- R6Class("pai",</pre> + <pre class="language-r"> #' @field iso ISO common name of the active ingredient according to ISO 1750</pre> </td> </tr> <tr class="never"> <td class="num">667</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r"> inherit = chent,</pre> + <pre class="language-r"> iso = NULL,</pre> </td> </tr> <tr class="never"> <td class="num">668</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r"> public = list(</pre> + <pre class="language-r"></pre> </td> </tr> <tr class="never"> <td class="num">669</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r"></pre> + <pre class="language-r"> #' @field bcpc Information retrieved from the BCPC compendium available online</pre> </td> </tr> <tr class="never"> <td class="num">670</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r"> #' @field iso ISO common name of the active ingredient according to ISO 1750</pre> + <pre class="language-r"> #' at <pesticidecompendium.bcpc.org></pre> </td> </tr> <tr class="never"> <td class="num">671</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r"> iso = NULL,</pre> + <pre class="language-r"> bcpc = NULL,</pre> </td> </tr> <tr class="never"> @@ -4823,602 +4823,602 @@ table.table-condensed { <td class="num">673</td> <td class="coverage"></td> <td class="col-sm-12"> - <pre class="language-r"> #' @field bcpc Information retrieved from the BCPC compendium available online</pre> - </td> - </tr> - <tr class="never"> - <td class="num">674</td> - <td class="coverage"></td> - <td class="col-sm-12"> - <pre class="language-r"> #' at <pesticidecompendium.bcpc.org></pre> - </td> - </tr> - <tr class="never"> - <td class="num">675</td> - <td class="coverage"></td> - <td class="col-sm-12"> - <pre class="language-r"> bcpc = NULL,</pre> - </td> - </tr> - <tr class="never"> - <td class="num">676</td> - <td class="coverage"></td> - <td class="col-sm-12"> - <pre class="language-r"></pre> - </td> - </tr> - <tr class="never"> - <td class="num">677</td> - <td class="coverage"></td> - <td class="col-sm-12"> <pre class="language-r"> #' @description</pre> </td> </tr> <tr class="never"> - <td class="num">678</td> + <td class="num">674</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' Create a new pai object</pre> </td> </tr> <tr class="never"> - <td class="num">679</td> + <td class="num">675</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param iso The ISO common name to be used in the query of the</pre> </td> </tr> <tr class="never"> - <td class="num">680</td> + <td class="num">676</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' BCPC compendium</pre> </td> </tr> <tr class="never"> - <td class="num">681</td> + <td class="num">677</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param identifier Alternative identifier used for querying pubchem</pre> </td> </tr> <tr class="never"> - <td class="num">682</td> + <td class="num">678</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param smiles Optional user provided SMILES code</pre> </td> </tr> <tr class="never"> - <td class="num">683</td> + <td class="num">679</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param inchikey Optional user provided InChI Key</pre> </td> </tr> <tr class="never"> - <td class="num">684</td> + <td class="num">680</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param bcpc Should the BCPC compendium be queried?</pre> </td> </tr> <tr class="never"> - <td class="num">685</td> + <td class="num">681</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param pubchem Should an attempt be made to retrieve chemical</pre> </td> </tr> <tr class="never"> - <td class="num">686</td> + <td class="num">682</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' information from PubChem via the webchem package?</pre> </td> </tr> <tr class="never"> - <td class="num">687</td> + <td class="num">683</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param pubchem_from Possibility to select the argument</pre> </td> </tr> <tr class="never"> - <td class="num">688</td> + <td class="num">684</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' that is used to query pubchem</pre> </td> </tr> <tr class="never"> - <td class="num">689</td> + <td class="num">685</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param rdkit Should an attempt be made to retrieve chemical</pre> </td> </tr> <tr class="never"> - <td class="num">690</td> + <td class="num">686</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' information from a local rdkit installation via python</pre> </td> </tr> <tr class="never"> - <td class="num">691</td> + <td class="num">687</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' and the reticulate package?</pre> </td> </tr> <tr class="never"> - <td class="num">692</td> + <td class="num">688</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param template An optional SMILES code to be used as template for RDKit</pre> </td> </tr> <tr class="never"> - <td class="num">693</td> + <td class="num">689</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> #' @param chyaml Should we look for a identifier.yaml file in the working</pre> </td> </tr> <tr class="never"> - <td class="num">694</td> + <td class="num">690</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> initialize = function(iso, identifier = iso,</pre> </td> </tr> <tr class="never"> - <td class="num">695</td> + <td class="num">691</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> smiles = NULL, inchikey = NULL, bcpc = TRUE,</pre> </td> </tr> <tr class="never"> - <td class="num">696</td> + <td class="num">692</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> pubchem = TRUE, pubchem_from = 'auto',</pre> </td> </tr> <tr class="never"> - <td class="num">697</td> + <td class="num">693</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> rdkit = TRUE, template = NULL,</pre> </td> </tr> <tr class="never"> - <td class="num">698</td> + <td class="num">694</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> chyaml = FALSE)</pre> </td> </tr> <tr class="never"> - <td class="num">699</td> + <td class="num">695</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> {</pre> </td> </tr> <tr class="never"> - <td class="num">700</td> + <td class="num">696</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="covered"> - <td class="num">701</td> + <td class="num">697</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (!is.null(inchikey)) {</pre> </td> </tr> <tr class="missed"> - <td class="num">702</td> + <td class="num">698</td> <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> self$inchikey = inchikey</pre> </td> </tr> <tr class="missed"> - <td class="num">703</td> + <td class="num">699</td> <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> attr(self$inchikey, "source") <- "user"</pre> </td> </tr> <tr class="never"> - <td class="num">704</td> + <td class="num">700</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">705</td> + <td class="num">701</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="covered"> - <td class="num">706</td> + <td class="num">702</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (!missing(iso) & bcpc) {</pre> </td> </tr> <tr class="covered"> - <td class="num">707</td> + <td class="num">703</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> message("Querying BCPC for ", identifier, " ...")</pre> </td> </tr> <tr class="covered"> - <td class="num">708</td> + <td class="num">704</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> bcpc_result = webchem::bcpc_query(identifier, from = "name")</pre> </td> </tr> <tr class="never"> - <td class="num">709</td> + <td class="num">705</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="never"> - <td class="num">710</td> + <td class="num">706</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> # Use first element of list, as we passed a query of length one</pre> </td> </tr> <tr class="covered"> - <td class="num">711</td> + <td class="num">707</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (is.na(bcpc_result[[1]][1])) {</pre> </td> </tr> <tr class="missed"> - <td class="num">712</td> + <td class="num">708</td> <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> message("Common name ", identifier, " is not known at the BCPC compendium, trying PubChem")</pre> </td> </tr> <tr class="never"> - <td class="num">713</td> + <td class="num">709</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> } else {</pre> </td> </tr> <tr class="covered"> - <td class="num">714</td> + <td class="num">710</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$bcpc = bcpc_result[[1]]</pre> </td> </tr> <tr class="covered"> - <td class="num">715</td> + <td class="num">711</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$iso = self$bcpc$cname</pre> </td> </tr> <tr class="covered"> - <td class="num">716</td> + <td class="num">712</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> attr(self$iso, "source") <- "bcpc"</pre> </td> </tr> <tr class="covered"> - <td class="num">717</td> + <td class="num">713</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> attr(self$iso, "status") <- self$bcpc$status</pre> </td> </tr> <tr class="covered"> - <td class="num">718</td> + <td class="num">714</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> bcpc_ik = self$bcpc$inchikey</pre> </td> </tr> <tr class="covered"> - <td class="num">719</td> + <td class="num">715</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (length(bcpc_ik) == 1 && !is.na(bcpc_ik)) {</pre> </td> </tr> <tr class="covered"> - <td class="num">720</td> + <td class="num">716</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (is.null(self$inchikey)) {</pre> </td> </tr> <tr class="covered"> - <td class="num">721</td> + <td class="num">717</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> self$inchikey = substr(self$bcpc$inchikey, 1, 27)</pre> </td> </tr> <tr class="covered"> - <td class="num">722</td> + <td class="num">718</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> attr(self$inchikey, "source") <- "bcpc"</pre> </td> </tr> <tr class="never"> - <td class="num">723</td> + <td class="num">719</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> } else {</pre> </td> </tr> <tr class="missed"> - <td class="num">724</td> + <td class="num">720</td> <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> if (bcpc_ik == self$inchikey) {</pre> </td> </tr> <tr class="missed"> - <td class="num">725</td> + <td class="num">721</td> <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> attr(self$inchikey, "source") = c(attr(self$inchikey, "source"), "bcpc")</pre> </td> </tr> <tr class="never"> - <td class="num">726</td> + <td class="num">722</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> } else {</pre> </td> </tr> <tr class="missed"> - <td class="num">727</td> + <td class="num">723</td> <td class="coverage">!</td> <td class="col-sm-12"> <pre class="language-r"> warning("InChIKey ", self$inchikey, " differs from ", bcpc_ik, " obtained from bcpc.org")</pre> </td> </tr> <tr class="never"> - <td class="num">728</td> + <td class="num">724</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">729</td> + <td class="num">725</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">730</td> + <td class="num">726</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">731</td> + <td class="num">727</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">732</td> + <td class="num">728</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">733</td> + <td class="num">729</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="never"> - <td class="num">734</td> + <td class="num">730</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> # Set pubchem_from if not specified</pre> </td> </tr> <tr class="covered"> - <td class="num">735</td> + <td class="num">731</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (pubchem_from == 'auto') {</pre> </td> </tr> <tr class="covered"> - <td class="num">736</td> + <td class="num">732</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> pubchem_from = 'name'</pre> </td> </tr> <tr class="covered"> - <td class="num">737</td> + <td class="num">733</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> if (!is.null(self$inchikey)) {</pre> </td> </tr> <tr class="covered"> - <td class="num">738</td> + <td class="num">734</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> pubchem_from = 'inchikey'</pre> </td> </tr> <tr class="never"> - <td class="num">739</td> + <td class="num">735</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">740</td> + <td class="num">736</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">741</td> + <td class="num">737</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="covered"> - <td class="num">742</td> + <td class="num">738</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> super$initialize(identifier = identifier,</pre> </td> </tr> <tr class="covered"> - <td class="num">743</td> + <td class="num">739</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> smiles = smiles, inchikey = self$inchikey,</pre> </td> </tr> <tr class="covered"> - <td class="num">744</td> + <td class="num">740</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> pubchem = pubchem, pubchem_from = pubchem_from,</pre> </td> </tr> <tr class="covered"> - <td class="num">745</td> + <td class="num">741</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> rdkit = rdkit, template = template, chyaml = chyaml)</pre> </td> </tr> <tr class="never"> - <td class="num">746</td> + <td class="num">742</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="covered"> - <td class="num">747</td> + <td class="num">743</td> <td class="coverage">1<em>x</em></td> <td class="col-sm-12"> <pre class="language-r"> invisible(self)</pre> </td> </tr> <tr class="never"> - <td class="num">748</td> + <td class="num">744</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> }</pre> </td> </tr> <tr class="never"> - <td class="num">749</td> + <td class="num">745</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"> )</pre> </td> </tr> <tr class="never"> - <td class="num">750</td> + <td class="num">746</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">)</pre> </td> </tr> <tr class="never"> - <td class="num">751</td> + <td class="num">747</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r"></pre> </td> </tr> <tr class="never"> - <td class="num">752</td> + <td class="num">748</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">#' Printing method for pai objects (pesticidal active ingredients)</pre> </td> </tr> <tr class="never"> - <td class="num">753</td> + <td class="num">749</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">#'</pre> </td> </tr> <tr class="never"> - <td class="num">754</td> + <td class="num">750</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">#' @param x The chent object to be printed</pre> </td> </tr> <tr class="never"> - <td class="num">755</td> + <td class="num">751</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">#' @param ... Further arguments for compatibility with the S3 method</pre> </td> </tr> <tr class="never"> - <td class="num">756</td> + <td class="num">752</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">#' @export</pre> </td> </tr> <tr class="never"> - <td class="num">757</td> + <td class="num">753</td> <td class="coverage"></td> <td class="col-sm-12"> <pre class="language-r">print.pai = function(x, ...) {</pre> </td> </tr> <tr class="missed"> - <td class="num">758</td> + <td class="num">754</td> + <td class="coverage">!</td> + <td class="col-sm-12"> + <pre class="language-r"> if (is.null(x$iso)) {</pre> + </td> + </tr> + <tr class="missed"> + <td class="num">755</td> <td class="coverage">!</td> <td class="col-sm-12"> - <pre class="language-r"> cat("<pai> with ISO common name $iso", x$iso, "\n")</pre> + <pre class="language-r"> cat("<pai> without ISO common name\n")</pre> + </td> + </tr> + <tr class="never"> + <td class="num">756</td> + <td class="coverage"></td> + <td class="col-sm-12"> + <pre class="language-r"> } else {</pre> + </td> + </tr> + <tr class="missed"> + <td class="num">757</td> + <td class="coverage">!</td> + <td class="col-sm-12"> + <pre class="language-r"> cat("<pai> with ISO common name $iso", x$iso, "\n")</pre> + </td> + </tr> + <tr class="never"> + <td class="num">758</td> + <td class="coverage"></td> + <td class="col-sm-12"> + <pre class="language-r"> }</pre> </td> </tr> <tr class="missed"> diff --git a/docs/coverage/lib/crosstalk-1.2.2/css/crosstalk.min.css b/docs/coverage/lib/crosstalk-1.2.2/css/crosstalk.min.css new file mode 100644 index 0000000..6b45382 --- /dev/null +++ b/docs/coverage/lib/crosstalk-1.2.2/css/crosstalk.min.css @@ -0,0 +1 @@ +.container-fluid.crosstalk-bscols{margin-left:-30px;margin-right:-30px;white-space:normal}body>.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} diff --git a/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.js b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.js new file mode 100644 index 0000000..fd9eb53 --- /dev/null +++ b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.js @@ -0,0 +1,1474 @@ +(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Events = function () { + function Events() { + _classCallCheck(this, Events); + + this._types = {}; + this._seq = 0; + } + + _createClass(Events, [{ + key: "on", + value: function on(eventType, listener) { + var subs = this._types[eventType]; + if (!subs) { + subs = this._types[eventType] = {}; + } + var sub = "sub" + this._seq++; + subs[sub] = listener; + return sub; + } + + // Returns false if no match, or string for sub name if matched + + }, { + key: "off", + value: function off(eventType, listener) { + var subs = this._types[eventType]; + if (typeof listener === "function") { + for (var key in subs) { + if (subs.hasOwnProperty(key)) { + if (subs[key] === listener) { + delete subs[key]; + return key; + } + } + } + return false; + } else if (typeof listener === "string") { + if (subs && subs[listener]) { + delete subs[listener]; + return listener; + } + return false; + } else { + throw new Error("Unexpected type for listener"); + } + } + }, { + key: "trigger", + value: function trigger(eventType, arg, thisObj) { + var subs = this._types[eventType]; + for (var key in subs) { + if (subs.hasOwnProperty(key)) { + subs[key].call(thisObj, arg); + } + } + } + }]); + + return Events; +}(); + +exports.default = Events; + +},{}],2:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FilterHandle = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +var _filterset = require("./filterset"); + +var _filterset2 = _interopRequireDefault(_filterset); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function getFilterSet(group) { + var fsVar = group.var("filterset"); + var result = fsVar.get(); + if (!result) { + result = new _filterset2.default(); + fsVar.set(result); + } + return result; +} + +var id = 1; +function nextId() { + return id++; +} + +/** + * Use this class to contribute to, and listen for changes to, the filter set + * for the given group of widgets. Filter input controls should create one + * `FilterHandle` and only call {@link FilterHandle#set}. Output widgets that + * wish to displayed filtered data should create one `FilterHandle` and use + * the {@link FilterHandle#filteredKeys} property and listen for change + * events. + * + * If two (or more) `FilterHandle` instances in the same webpage share the + * same group name, they will contribute to a single "filter set". Each + * `FilterHandle` starts out with a `null` value, which means they take + * nothing away from the set of data that should be shown. To make a + * `FilterHandle` actually remove data from the filter set, set its value to + * an array of keys which should be displayed. Crosstalk will aggregate the + * various key arrays by finding their intersection; only keys that are + * present in all non-null filter handles are considered part of the filter + * set. + * + * @param {string} [group] - The name of the Crosstalk group, or if none, + * null or undefined (or any other falsy value). This can be changed later + * via the {@link FilterHandle#setGroup} method. + * @param {Object} [extraInfo] - An object whose properties will be copied to + * the event object whenever an event is emitted. + */ + +var FilterHandle = exports.FilterHandle = function () { + function FilterHandle(group, extraInfo) { + _classCallCheck(this, FilterHandle); + + this._eventRelay = new _events2.default(); + this._emitter = new util.SubscriptionTracker(this._eventRelay); + + // Name of the group we're currently tracking, if any. Can change over time. + this._group = null; + // The filterSet that we're tracking, if any. Can change over time. + this._filterSet = null; + // The Var we're currently tracking, if any. Can change over time. + this._filterVar = null; + // The event handler subscription we currently have on var.on("change"). + this._varOnChangeSub = null; + + this._extraInfo = util.extend({ sender: this }, extraInfo); + + this._id = "filter" + nextId(); + + this.setGroup(group); + } + + /** + * Changes the Crosstalk group membership of this FilterHandle. If `set()` was + * previously called on this handle, switching groups will clear those keys + * from the old group's filter set. These keys will not be applied to the new + * group's filter set either. In other words, `setGroup()` effectively calls + * `clear()` before switching groups. + * + * @param {string} group - The name of the Crosstalk group, or null (or + * undefined) to clear the group. + */ + + + _createClass(FilterHandle, [{ + key: "setGroup", + value: function setGroup(group) { + var _this = this; + + // If group is unchanged, do nothing + if (this._group === group) return; + // Treat null, undefined, and other falsy values the same + if (!this._group && !group) return; + + if (this._filterVar) { + this._filterVar.off("change", this._varOnChangeSub); + this.clear(); + this._varOnChangeSub = null; + this._filterVar = null; + this._filterSet = null; + } + + this._group = group; + + if (group) { + group = (0, _group2.default)(group); + this._filterSet = getFilterSet(group); + this._filterVar = (0, _group2.default)(group).var("filter"); + var sub = this._filterVar.on("change", function (e) { + _this._eventRelay.trigger("change", e, _this); + }); + this._varOnChangeSub = sub; + } + } + + /** + * Combine the given `extraInfo` (if any) with the handle's default + * `_extraInfo` (if any). + * @private + */ + + }, { + key: "_mergeExtraInfo", + value: function _mergeExtraInfo(extraInfo) { + return util.extend({}, this._extraInfo ? this._extraInfo : null, extraInfo ? extraInfo : null); + } + + /** + * Close the handle. This clears this handle's contribution to the filter set, + * and unsubscribes all event listeners. + */ + + }, { + key: "close", + value: function close() { + this._emitter.removeAllListeners(); + this.clear(); + this.setGroup(null); + } + + /** + * Clear this handle's contribution to the filter set. + * + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any options that were + * passed into the `FilterHandle` constructor). + * + * @fires FilterHandle#change + */ + + }, { + key: "clear", + value: function clear(extraInfo) { + if (!this._filterSet) return; + this._filterSet.clear(this._id); + this._onChange(extraInfo); + } + + /** + * Set this handle's contribution to the filter set. This array should consist + * of the keys of the rows that _should_ be displayed; any keys that are not + * present in the array will be considered _filtered out_. Note that multiple + * `FilterHandle` instances in the group may each contribute an array of keys, + * and only those keys that appear in _all_ of the arrays make it through the + * filter. + * + * @param {string[]} keys - Empty array, or array of keys. To clear the + * filter, don't pass an empty array; instead, use the + * {@link FilterHandle#clear} method. + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any options that were + * passed into the `FilterHandle` constructor). + * + * @fires FilterHandle#change + */ + + }, { + key: "set", + value: function set(keys, extraInfo) { + if (!this._filterSet) return; + this._filterSet.update(this._id, keys); + this._onChange(extraInfo); + } + + /** + * @return {string[]|null} - Either: 1) an array of keys that made it through + * all of the `FilterHandle` instances, or, 2) `null`, which means no filter + * is being applied (all data should be displayed). + */ + + }, { + key: "on", + + + /** + * Subscribe to events on this `FilterHandle`. + * + * @param {string} eventType - Indicates the type of events to listen to. + * Currently, only `"change"` is supported. + * @param {FilterHandle~listener} listener - The callback function that + * will be invoked when the event occurs. + * @return {string} - A token to pass to {@link FilterHandle#off} to cancel + * this subscription. + */ + value: function on(eventType, listener) { + return this._emitter.on(eventType, listener); + } + + /** + * Cancel event subscriptions created by {@link FilterHandle#on}. + * + * @param {string} eventType - The type of event to unsubscribe. + * @param {string|FilterHandle~listener} listener - Either the callback + * function previously passed into {@link FilterHandle#on}, or the + * string that was returned from {@link FilterHandle#on}. + */ + + }, { + key: "off", + value: function off(eventType, listener) { + return this._emitter.off(eventType, listener); + } + }, { + key: "_onChange", + value: function _onChange(extraInfo) { + if (!this._filterSet) return; + this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo)); + } + + /** + * @callback FilterHandle~listener + * @param {Object} event - An object containing details of the event. For + * `"change"` events, this includes the properties `value` (the new + * value of the filter set, or `null` if no filter set is active), + * `oldValue` (the previous value of the filter set), and `sender` (the + * `FilterHandle` instance that made the change). + */ + + }, { + key: "filteredKeys", + get: function get() { + return this._filterSet ? this._filterSet.value : null; + } + }]); + + return FilterHandle; +}(); + +/** + * @event FilterHandle#change + * @type {object} + * @property {object} value - The new value of the filter set, or `null` + * if no filter set is active. + * @property {object} oldValue - The previous value of the filter set. + * @property {FilterHandle} sender - The `FilterHandle` instance that + * changed the value. + */ + +},{"./events":1,"./filterset":3,"./group":4,"./util":11}],3:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _util = require("./util"); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function naturalComparator(a, b) { + if (a === b) { + return 0; + } else if (a < b) { + return -1; + } else if (a > b) { + return 1; + } +} + +/** + * @private + */ + +var FilterSet = function () { + function FilterSet() { + _classCallCheck(this, FilterSet); + + this.reset(); + } + + _createClass(FilterSet, [{ + key: "reset", + value: function reset() { + // Key: handle ID, Value: array of selected keys, or null + this._handles = {}; + // Key: key string, Value: count of handles that include it + this._keys = {}; + this._value = null; + this._activeHandles = 0; + } + }, { + key: "update", + value: function update(handleId, keys) { + if (keys !== null) { + keys = keys.slice(0); // clone before sorting + keys.sort(naturalComparator); + } + + var _diffSortedLists = (0, _util.diffSortedLists)(this._handles[handleId], keys), + added = _diffSortedLists.added, + removed = _diffSortedLists.removed; + + this._handles[handleId] = keys; + + for (var i = 0; i < added.length; i++) { + this._keys[added[i]] = (this._keys[added[i]] || 0) + 1; + } + for (var _i = 0; _i < removed.length; _i++) { + this._keys[removed[_i]]--; + } + + this._updateValue(keys); + } + + /** + * @param {string[]} keys Sorted array of strings that indicate + * a superset of possible keys. + * @private + */ + + }, { + key: "_updateValue", + value: function _updateValue() { + var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._allKeys; + + var handleCount = Object.keys(this._handles).length; + if (handleCount === 0) { + this._value = null; + } else { + this._value = []; + for (var i = 0; i < keys.length; i++) { + var count = this._keys[keys[i]]; + if (count === handleCount) { + this._value.push(keys[i]); + } + } + } + } + }, { + key: "clear", + value: function clear(handleId) { + if (typeof this._handles[handleId] === "undefined") { + return; + } + + var keys = this._handles[handleId]; + if (!keys) { + keys = []; + } + + for (var i = 0; i < keys.length; i++) { + this._keys[keys[i]]--; + } + delete this._handles[handleId]; + + this._updateValue(); + } + }, { + key: "value", + get: function get() { + return this._value; + } + }, { + key: "_allKeys", + get: function get() { + var allKeys = Object.keys(this._keys); + allKeys.sort(naturalComparator); + return allKeys; + } + }]); + + return FilterSet; +}(); + +exports.default = FilterSet; + +},{"./util":11}],4:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.default = group; + +var _var2 = require("./var"); + +var _var3 = _interopRequireDefault(_var2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +// Use a global so that multiple copies of crosstalk.js can be loaded and still +// have groups behave as singletons across all copies. +global.__crosstalk_groups = global.__crosstalk_groups || {}; +var groups = global.__crosstalk_groups; + +function group(groupName) { + if (groupName && typeof groupName === "string") { + if (!groups.hasOwnProperty(groupName)) { + groups[groupName] = new Group(groupName); + } + return groups[groupName]; + } else if ((typeof groupName === "undefined" ? "undefined" : _typeof(groupName)) === "object" && groupName._vars && groupName.var) { + // Appears to already be a group object + return groupName; + } else if (Array.isArray(groupName) && groupName.length == 1 && typeof groupName[0] === "string") { + return group(groupName[0]); + } else { + throw new Error("Invalid groupName argument"); + } +} + +var Group = function () { + function Group(name) { + _classCallCheck(this, Group); + + this.name = name; + this._vars = {}; + } + + _createClass(Group, [{ + key: "var", + value: function _var(name) { + if (!name || typeof name !== "string") { + throw new Error("Invalid var name"); + } + + if (!this._vars.hasOwnProperty(name)) this._vars[name] = new _var3.default(this, name); + return this._vars[name]; + } + }, { + key: "has", + value: function has(name) { + if (!name || typeof name !== "string") { + throw new Error("Invalid var name"); + } + + return this._vars.hasOwnProperty(name); + } + }]); + + return Group; +}(); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./var":12}],5:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _selection = require("./selection"); + +var _filter = require("./filter"); + +var _input = require("./input"); + +require("./input_selectize"); + +require("./input_checkboxgroup"); + +require("./input_slider"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var defaultGroup = (0, _group2.default)("default"); + +function var_(name) { + return defaultGroup.var(name); +} + +function has(name) { + return defaultGroup.has(name); +} + +if (global.Shiny) { + global.Shiny.addCustomMessageHandler("update-client-value", function (message) { + if (typeof message.group === "string") { + (0, _group2.default)(message.group).var(message.name).set(message.value); + } else { + var_(message.name).set(message.value); + } + }); +} + +var crosstalk = { + group: _group2.default, + var: var_, + has: has, + SelectionHandle: _selection.SelectionHandle, + FilterHandle: _filter.FilterHandle, + bind: _input.bind +}; + +/** + * @namespace crosstalk + */ +exports.default = crosstalk; + +global.crosstalk = crosstalk; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./group":4,"./input":6,"./input_checkboxgroup":7,"./input_selectize":8,"./input_slider":9,"./selection":10}],6:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.register = register; +exports.bind = bind; +var $ = global.jQuery; + +var bindings = {}; + +function register(reg) { + bindings[reg.className] = reg; + if (global.document && global.document.readyState !== "complete") { + $(function () { + bind(); + }); + } else if (global.document) { + setTimeout(bind, 100); + } +} + +function bind() { + Object.keys(bindings).forEach(function (className) { + var binding = bindings[className]; + $("." + binding.className).not(".crosstalk-input-bound").each(function (i, el) { + bindInstance(binding, el); + }); + }); +} + +// Escape jQuery identifier +function $escape(val) { + return val.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1"); +} + +function bindEl(el) { + var $el = $(el); + Object.keys(bindings).forEach(function (className) { + if ($el.hasClass(className) && !$el.hasClass("crosstalk-input-bound")) { + var binding = bindings[className]; + bindInstance(binding, el); + } + }); +} + +function bindInstance(binding, el) { + var jsonEl = $(el).find("script[type='application/json'][data-for='" + $escape(el.id) + "']"); + var data = JSON.parse(jsonEl[0].innerText); + + var instance = binding.factory(el, data); + $(el).data("crosstalk-instance", instance); + $(el).addClass("crosstalk-input-bound"); +} + +if (global.Shiny) { + var inputBinding = new global.Shiny.InputBinding(); + var _$ = global.jQuery; + _$.extend(inputBinding, { + find: function find(scope) { + return _$(scope).find(".crosstalk-input"); + }, + initialize: function initialize(el) { + if (!_$(el).hasClass("crosstalk-input-bound")) { + bindEl(el); + } + }, + getId: function getId(el) { + return el.id; + }, + getValue: function getValue(el) {}, + setValue: function setValue(el, value) {}, + receiveMessage: function receiveMessage(el, data) {}, + subscribe: function subscribe(el, callback) { + _$(el).data("crosstalk-instance").resume(); + }, + unsubscribe: function unsubscribe(el) { + _$(el).data("crosstalk-instance").suspend(); + } + }); + global.Shiny.inputBindings.register(inputBinding, "crosstalk.inputBinding"); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],7:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; + +input.register({ + className: "crosstalk-input-checkboxgroup", + + factory: function factory(el, data) { + /* + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + var ctHandle = new _filter.FilterHandle(data.group); + + var lastKnownKeys = void 0; + var $el = $(el); + $el.on("change", "input[type='checkbox']", function () { + var checked = $el.find("input[type='checkbox']:checked"); + if (checked.length === 0) { + lastKnownKeys = null; + ctHandle.clear(); + } else { + var keys = {}; + checked.each(function () { + data.map[this.value].forEach(function (key) { + keys[key] = true; + }); + }); + var keyArray = Object.keys(keys); + keyArray.sort(); + lastKnownKeys = keyArray; + ctHandle.set(keyArray); + } + }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6}],8:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; + +input.register({ + className: "crosstalk-input-select", + + factory: function factory(el, data) { + /* + * items: {value: [...], label: [...]} + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + + var first = [{ value: "", label: "(All)" }]; + var items = util.dataframeToD3(data.items); + var opts = { + options: first.concat(items), + valueField: "value", + labelField: "label", + searchField: "label" + }; + + var select = $(el).find("select")[0]; + + var selectize = $(select).selectize(opts)[0].selectize; + + var ctHandle = new _filter.FilterHandle(data.group); + + var lastKnownKeys = void 0; + selectize.on("change", function () { + if (selectize.items.length === 0) { + lastKnownKeys = null; + ctHandle.clear(); + } else { + var keys = {}; + selectize.items.forEach(function (group) { + data.map[group].forEach(function (key) { + keys[key] = true; + }); + }); + var keyArray = Object.keys(keys); + keyArray.sort(); + lastKnownKeys = keyArray; + ctHandle.set(keyArray); + } + }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6,"./util":11}],9:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _input = require("./input"); + +var input = _interopRequireWildcard(_input); + +var _filter = require("./filter"); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +var $ = global.jQuery; +var strftime = global.strftime; + +input.register({ + className: "crosstalk-input-slider", + + factory: function factory(el, data) { + /* + * map: {"groupA": ["keyA", "keyB", ...], ...} + * group: "ct-groupname" + */ + var ctHandle = new _filter.FilterHandle(data.group); + + var opts = {}; + var $el = $(el).find("input"); + var dataType = $el.data("data-type"); + var timeFormat = $el.data("time-format"); + var round = $el.data("round"); + var timeFormatter = void 0; + + // Set up formatting functions + if (dataType === "date") { + timeFormatter = strftime.utc(); + opts.prettify = function (num) { + return timeFormatter(timeFormat, new Date(num)); + }; + } else if (dataType === "datetime") { + var timezone = $el.data("timezone"); + if (timezone) timeFormatter = strftime.timezone(timezone);else timeFormatter = strftime; + + opts.prettify = function (num) { + return timeFormatter(timeFormat, new Date(num)); + }; + } else if (dataType === "number") { + if (typeof round !== "undefined") opts.prettify = function (num) { + var factor = Math.pow(10, round); + return Math.round(num * factor) / factor; + }; + } + + $el.ionRangeSlider(opts); + + function getValue() { + var result = $el.data("ionRangeSlider").result; + + // Function for converting numeric value from slider to appropriate type. + var convert = void 0; + var dataType = $el.data("data-type"); + if (dataType === "date") { + convert = function convert(val) { + return formatDateUTC(new Date(+val)); + }; + } else if (dataType === "datetime") { + convert = function convert(val) { + // Convert ms to s + return +val / 1000; + }; + } else { + convert = function convert(val) { + return +val; + }; + } + + if ($el.data("ionRangeSlider").options.type === "double") { + return [convert(result.from), convert(result.to)]; + } else { + return convert(result.from); + } + } + + var lastKnownKeys = null; + + $el.on("change.crosstalkSliderInput", function (event) { + if (!$el.data("updating") && !$el.data("animating")) { + var _getValue = getValue(), + _getValue2 = _slicedToArray(_getValue, 2), + from = _getValue2[0], + to = _getValue2[1]; + + var keys = []; + for (var i = 0; i < data.values.length; i++) { + var val = data.values[i]; + if (val >= from && val <= to) { + keys.push(data.keys[i]); + } + } + keys.sort(); + ctHandle.set(keys); + lastKnownKeys = keys; + } + }); + + // let $el = $(el); + // $el.on("change", "input[type="checkbox"]", function() { + // let checked = $el.find("input[type="checkbox"]:checked"); + // if (checked.length === 0) { + // ctHandle.clear(); + // } else { + // let keys = {}; + // checked.each(function() { + // data.map[this.value].forEach(function(key) { + // keys[key] = true; + // }); + // }); + // let keyArray = Object.keys(keys); + // keyArray.sort(); + // ctHandle.set(keyArray); + // } + // }); + + return { + suspend: function suspend() { + ctHandle.clear(); + }, + resume: function resume() { + if (lastKnownKeys) ctHandle.set(lastKnownKeys); + } + }; + } +}); + +// Convert a number to a string with leading zeros +function padZeros(n, digits) { + var str = n.toString(); + while (str.length < digits) { + str = "0" + str; + }return str; +} + +// Given a Date object, return a string in yyyy-mm-dd format, using the +// UTC date. This may be a day off from the date in the local time zone. +function formatDateUTC(date) { + if (date instanceof Date) { + return date.getUTCFullYear() + "-" + padZeros(date.getUTCMonth() + 1, 2) + "-" + padZeros(date.getUTCDate(), 2); + } else { + return null; + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./filter":2,"./input":6}],10:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SelectionHandle = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +var _group = require("./group"); + +var _group2 = _interopRequireDefault(_group); + +var _util = require("./util"); + +var util = _interopRequireWildcard(_util); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Use this class to read and write (and listen for changes to) the selection + * for a Crosstalk group. This is intended to be used for linked brushing. + * + * If two (or more) `SelectionHandle` instances in the same webpage share the + * same group name, they will share the same state. Setting the selection using + * one `SelectionHandle` instance will result in the `value` property instantly + * changing across the others, and `"change"` event listeners on all instances + * (including the one that initiated the sending) will fire. + * + * @param {string} [group] - The name of the Crosstalk group, or if none, + * null or undefined (or any other falsy value). This can be changed later + * via the [SelectionHandle#setGroup](#setGroup) method. + * @param {Object} [extraInfo] - An object whose properties will be copied to + * the event object whenever an event is emitted. + */ +var SelectionHandle = exports.SelectionHandle = function () { + function SelectionHandle() { + var group = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var extraInfo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + _classCallCheck(this, SelectionHandle); + + this._eventRelay = new _events2.default(); + this._emitter = new util.SubscriptionTracker(this._eventRelay); + + // Name of the group we're currently tracking, if any. Can change over time. + this._group = null; + // The Var we're currently tracking, if any. Can change over time. + this._var = null; + // The event handler subscription we currently have on var.on("change"). + this._varOnChangeSub = null; + + this._extraInfo = util.extend({ sender: this }, extraInfo); + + this.setGroup(group); + } + + /** + * Changes the Crosstalk group membership of this SelectionHandle. The group + * being switched away from (if any) will not have its selection value + * modified as a result of calling `setGroup`, even if this handle was the + * most recent handle to set the selection of the group. + * + * The group being switched to (if any) will also not have its selection value + * modified as a result of calling `setGroup`. If you want to set the + * selection value of the new group, call `set` explicitly. + * + * @param {string} group - The name of the Crosstalk group, or null (or + * undefined) to clear the group. + */ + + + _createClass(SelectionHandle, [{ + key: "setGroup", + value: function setGroup(group) { + var _this = this; + + // If group is unchanged, do nothing + if (this._group === group) return; + // Treat null, undefined, and other falsy values the same + if (!this._group && !group) return; + + if (this._var) { + this._var.off("change", this._varOnChangeSub); + this._var = null; + this._varOnChangeSub = null; + } + + this._group = group; + + if (group) { + this._var = (0, _group2.default)(group).var("selection"); + var sub = this._var.on("change", function (e) { + _this._eventRelay.trigger("change", e, _this); + }); + this._varOnChangeSub = sub; + } + } + + /** + * Retrieves the current selection for the group represented by this + * `SelectionHandle`. + * + * - If no selection is active, then this value will be falsy. + * - If a selection is active, but no data points are selected, then this + * value will be an empty array. + * - If a selection is active, and data points are selected, then the keys + * of the selected data points will be present in the array. + */ + + }, { + key: "_mergeExtraInfo", + + + /** + * Combines the given `extraInfo` (if any) with the handle's default + * `_extraInfo` (if any). + * @private + */ + value: function _mergeExtraInfo(extraInfo) { + // Important incidental effect: shallow clone is returned + return util.extend({}, this._extraInfo ? this._extraInfo : null, extraInfo ? extraInfo : null); + } + + /** + * Overwrites the current selection for the group, and raises the `"change"` + * event among all of the group's '`SelectionHandle` instances (including + * this one). + * + * @fires SelectionHandle#change + * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see + * {@link SelectionHandle#value}). + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any options that were + * passed into the `SelectionHandle` constructor). + */ + + }, { + key: "set", + value: function set(selectedKeys, extraInfo) { + if (this._var) this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo)); + } + + /** + * Overwrites the current selection for the group, and raises the `"change"` + * event among all of the group's '`SelectionHandle` instances (including + * this one). + * + * @fires SelectionHandle#change + * @param {Object} [extraInfo] - Extra properties to be included on the event + * object that's passed to listeners (in addition to any that were passed + * into the `SelectionHandle` constructor). + */ + + }, { + key: "clear", + value: function clear(extraInfo) { + if (this._var) this.set(void 0, this._mergeExtraInfo(extraInfo)); + } + + /** + * Subscribes to events on this `SelectionHandle`. + * + * @param {string} eventType - Indicates the type of events to listen to. + * Currently, only `"change"` is supported. + * @param {SelectionHandle~listener} listener - The callback function that + * will be invoked when the event occurs. + * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel + * this subscription. + */ + + }, { + key: "on", + value: function on(eventType, listener) { + return this._emitter.on(eventType, listener); + } + + /** + * Cancels event subscriptions created by {@link SelectionHandle#on}. + * + * @param {string} eventType - The type of event to unsubscribe. + * @param {string|SelectionHandle~listener} listener - Either the callback + * function previously passed into {@link SelectionHandle#on}, or the + * string that was returned from {@link SelectionHandle#on}. + */ + + }, { + key: "off", + value: function off(eventType, listener) { + return this._emitter.off(eventType, listener); + } + + /** + * Shuts down the `SelectionHandle` object. + * + * Removes all event listeners that were added through this handle. + */ + + }, { + key: "close", + value: function close() { + this._emitter.removeAllListeners(); + this.setGroup(null); + } + }, { + key: "value", + get: function get() { + return this._var ? this._var.get() : null; + } + }]); + + return SelectionHandle; +}(); + +/** + * @callback SelectionHandle~listener + * @param {Object} event - An object containing details of the event. For + * `"change"` events, this includes the properties `value` (the new + * value of the selection, or `undefined` if no selection is active), + * `oldValue` (the previous value of the selection), and `sender` (the + * `SelectionHandle` instance that made the change). + */ + +/** + * @event SelectionHandle#change + * @type {object} + * @property {object} value - The new value of the selection, or `undefined` + * if no selection is active. + * @property {object} oldValue - The previous value of the selection. + * @property {SelectionHandle} sender - The `SelectionHandle` instance that + * changed the value. + */ + +},{"./events":1,"./group":4,"./util":11}],11:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +exports.extend = extend; +exports.checkSorted = checkSorted; +exports.diffSortedLists = diffSortedLists; +exports.dataframeToD3 = dataframeToD3; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function extend(target) { + for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + for (var i = 0; i < sources.length; i++) { + var src = sources[i]; + if (typeof src === "undefined" || src === null) continue; + + for (var key in src) { + if (src.hasOwnProperty(key)) { + target[key] = src[key]; + } + } + } + return target; +} + +function checkSorted(list) { + for (var i = 1; i < list.length; i++) { + if (list[i] <= list[i - 1]) { + throw new Error("List is not sorted or contains duplicate"); + } + } +} + +function diffSortedLists(a, b) { + var i_a = 0; + var i_b = 0; + + if (!a) a = []; + if (!b) b = []; + + var a_only = []; + var b_only = []; + + checkSorted(a); + checkSorted(b); + + while (i_a < a.length && i_b < b.length) { + if (a[i_a] === b[i_b]) { + i_a++; + i_b++; + } else if (a[i_a] < b[i_b]) { + a_only.push(a[i_a++]); + } else { + b_only.push(b[i_b++]); + } + } + + if (i_a < a.length) a_only = a_only.concat(a.slice(i_a)); + if (i_b < b.length) b_only = b_only.concat(b.slice(i_b)); + return { + removed: a_only, + added: b_only + }; +} + +// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... } +// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ] +function dataframeToD3(df) { + var names = []; + var length = void 0; + 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 = void 0; + 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; +} + +/** + * Keeps track of all event listener additions/removals and lets all active + * listeners be removed with a single operation. + * + * @private + */ + +var SubscriptionTracker = exports.SubscriptionTracker = function () { + function SubscriptionTracker(emitter) { + _classCallCheck(this, SubscriptionTracker); + + this._emitter = emitter; + this._subs = {}; + } + + _createClass(SubscriptionTracker, [{ + key: "on", + value: function on(eventType, listener) { + var sub = this._emitter.on(eventType, listener); + this._subs[sub] = eventType; + return sub; + } + }, { + key: "off", + value: function off(eventType, listener) { + var sub = this._emitter.off(eventType, listener); + if (sub) { + delete this._subs[sub]; + } + return sub; + } + }, { + key: "removeAllListeners", + value: function removeAllListeners() { + var _this = this; + + var current_subs = this._subs; + this._subs = {}; + Object.keys(current_subs).forEach(function (sub) { + _this._emitter.off(current_subs[sub], sub); + }); + } + }]); + + return SubscriptionTracker; +}(); + +},{}],12:[function(require,module,exports){ +(function (global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _events = require("./events"); + +var _events2 = _interopRequireDefault(_events); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Var = function () { + function Var(group, name, /*optional*/value) { + _classCallCheck(this, Var); + + this._group = group; + this._name = name; + this._value = value; + this._events = new _events2.default(); + } + + _createClass(Var, [{ + key: "get", + value: function get() { + return this._value; + } + }, { + key: "set", + value: function set(value, /*optional*/event) { + if (this._value === value) { + // Do nothing; the value hasn't changed + return; + } + var oldValue = this._value; + this._value = value; + // Alert JavaScript listeners that the value has changed + var evt = {}; + if (event && (typeof event === "undefined" ? "undefined" : _typeof(event)) === "object") { + for (var k in event) { + if (event.hasOwnProperty(k)) evt[k] = event[k]; + } + } + evt.oldValue = oldValue; + evt.value = value; + this._events.trigger("change", evt, this); + + // TODO: Make this extensible, to let arbitrary back-ends know that + // something has changed + if (global.Shiny && global.Shiny.onInputChange) { + global.Shiny.onInputChange(".clientValue-" + (this._group.name !== null ? this._group.name + "-" : "") + this._name, typeof value === "undefined" ? null : value); + } + } + }, { + key: "on", + value: function on(eventType, listener) { + return this._events.on(eventType, listener); + } + }, { + key: "off", + value: function off(eventType, listener) { + return this._events.off(eventType, listener); + } + }]); + + return Var; +}(); + +exports.default = Var; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./events":1}]},{},[5]) +//# sourceMappingURL=crosstalk.js.map diff --git a/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.js.map b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.js.map new file mode 100644 index 0000000..cff94f0 --- /dev/null +++ b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.js.map @@ -0,0 +1,37 @@ +{ + "version": 3, + "sources": [ + "node_modules/browser-pack/_prelude.js", + "javascript/src/events.js", + "javascript/src/filter.js", + "javascript/src/filterset.js", + "javascript/src/group.js", + "javascript/src/index.js", + "javascript/src/input.js", + "javascript/src/input_checkboxgroup.js", + "javascript/src/input_selectize.js", + "javascript/src/input_slider.js", + "javascript/src/selection.js", + "javascript/src/util.js", + "javascript/src/var.js" + ], + "names": [], + "mappings": "AAAA;;;;;;;;;;;ICAqB,M;AACnB,oBAAc;AAAA;;AACZ,SAAK,MAAL,GAAc,EAAd;AACA,SAAK,IAAL,GAAY,CAAZ;AACD;;;;uBAEE,S,EAAW,Q,EAAU;AACtB,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,UAAI,CAAC,IAAL,EAAW;AACT,eAAO,KAAK,MAAL,CAAY,SAAZ,IAAyB,EAAhC;AACD;AACD,UAAI,MAAM,QAAS,KAAK,IAAL,EAAnB;AACA,WAAK,GAAL,IAAY,QAAZ;AACA,aAAO,GAAP;AACD;;AAED;;;;wBACI,S,EAAW,Q,EAAU;AACvB,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,UAAI,OAAO,QAAP,KAAqB,UAAzB,EAAqC;AACnC,aAAK,IAAI,GAAT,IAAgB,IAAhB,EAAsB;AACpB,cAAI,KAAK,cAAL,CAAoB,GAApB,CAAJ,EAA8B;AAC5B,gBAAI,KAAK,GAAL,MAAc,QAAlB,EAA4B;AAC1B,qBAAO,KAAK,GAAL,CAAP;AACA,qBAAO,GAAP;AACD;AACF;AACF;AACD,eAAO,KAAP;AACD,OAVD,MAUO,IAAI,OAAO,QAAP,KAAqB,QAAzB,EAAmC;AACxC,YAAI,QAAQ,KAAK,QAAL,CAAZ,EAA4B;AAC1B,iBAAO,KAAK,QAAL,CAAP;AACA,iBAAO,QAAP;AACD;AACD,eAAO,KAAP;AACD,OANM,MAMA;AACL,cAAM,IAAI,KAAJ,CAAU,8BAAV,CAAN;AACD;AACF;;;4BAEO,S,EAAW,G,EAAK,O,EAAS;AAC/B,UAAI,OAAO,KAAK,MAAL,CAAY,SAAZ,CAAX;AACA,WAAK,IAAI,GAAT,IAAgB,IAAhB,EAAsB;AACpB,YAAI,KAAK,cAAL,CAAoB,GAApB,CAAJ,EAA8B;AAC5B,eAAK,GAAL,EAAU,IAAV,CAAe,OAAf,EAAwB,GAAxB;AACD;AACF;AACF;;;;;;kBA/CkB,M;;;;;;;;;;;;ACArB;;;;AACA;;;;AACA;;;;AACA;;IAAY,I;;;;;;;;AAEZ,SAAS,YAAT,CAAsB,KAAtB,EAA6B;AAC3B,MAAI,QAAQ,MAAM,GAAN,CAAU,WAAV,CAAZ;AACA,MAAI,SAAS,MAAM,GAAN,EAAb;AACA,MAAI,CAAC,MAAL,EAAa;AACX,aAAS,yBAAT;AACA,UAAM,GAAN,CAAU,MAAV;AACD;AACD,SAAO,MAAP;AACD;;AAED,IAAI,KAAK,CAAT;AACA,SAAS,MAAT,GAAkB;AAChB,SAAO,IAAP;AACD;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;IAwBa,Y,WAAA,Y;AACX,wBAAY,KAAZ,EAAmB,SAAnB,EAA8B;AAAA;;AAC5B,SAAK,WAAL,GAAmB,sBAAnB;AACA,SAAK,QAAL,GAAgB,IAAI,KAAK,mBAAT,CAA6B,KAAK,WAAlC,CAAhB;;AAEA;AACA,SAAK,MAAL,GAAc,IAAd;AACA;AACA,SAAK,UAAL,GAAkB,IAAlB;AACA;AACA,SAAK,UAAL,GAAkB,IAAlB;AACA;AACA,SAAK,eAAL,GAAuB,IAAvB;;AAEA,SAAK,UAAL,GAAkB,KAAK,MAAL,CAAY,EAAE,QAAQ,IAAV,EAAZ,EAA8B,SAA9B,CAAlB;;AAEA,SAAK,GAAL,GAAW,WAAW,QAAtB;;AAEA,SAAK,QAAL,CAAc,KAAd;AACD;;AAED;;;;;;;;;;;;;;6BAUS,K,EAAO;AAAA;;AACd;AACA,UAAI,KAAK,MAAL,KAAgB,KAApB,EACE;AACF;AACA,UAAI,CAAC,KAAK,MAAN,IAAgB,CAAC,KAArB,EACE;;AAEF,UAAI,KAAK,UAAT,EAAqB;AACnB,aAAK,UAAL,CAAgB,GAAhB,CAAoB,QAApB,EAA8B,KAAK,eAAnC;AACA,aAAK,KAAL;AACA,aAAK,eAAL,GAAuB,IAAvB;AACA,aAAK,UAAL,GAAkB,IAAlB;AACA,aAAK,UAAL,GAAkB,IAAlB;AACD;;AAED,WAAK,MAAL,GAAc,KAAd;;AAEA,UAAI,KAAJ,EAAW;AACT,gBAAQ,qBAAI,KAAJ,CAAR;AACA,aAAK,UAAL,GAAkB,aAAa,KAAb,CAAlB;AACA,aAAK,UAAL,GAAkB,qBAAI,KAAJ,EAAW,GAAX,CAAe,QAAf,CAAlB;AACA,YAAI,MAAM,KAAK,UAAL,CAAgB,EAAhB,CAAmB,QAAnB,EAA6B,UAAC,CAAD,EAAO;AAC5C,gBAAK,WAAL,CAAiB,OAAjB,CAAyB,QAAzB,EAAmC,CAAnC;AACD,SAFS,CAAV;AAGA,aAAK,eAAL,GAAuB,GAAvB;AACD;AACF;;AAED;;;;;;;;oCAKgB,S,EAAW;AACzB,aAAO,KAAK,MAAL,CAAY,EAAZ,EACL,KAAK,UAAL,GAAkB,KAAK,UAAvB,GAAoC,IAD/B,EAEL,YAAY,SAAZ,GAAwB,IAFnB,CAAP;AAGD;;AAED;;;;;;;4BAIQ;AACN,WAAK,QAAL,CAAc,kBAAd;AACA,WAAK,KAAL;AACA,WAAK,QAAL,CAAc,IAAd;AACD;;AAED;;;;;;;;;;;;0BASM,S,EAAW;AACf,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,KAAhB,CAAsB,KAAK,GAA3B;AACA,WAAK,SAAL,CAAe,SAAf;AACD;;AAED;;;;;;;;;;;;;;;;;;;;wBAiBI,I,EAAM,S,EAAW;AACnB,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,MAAhB,CAAuB,KAAK,GAA5B,EAAiC,IAAjC;AACA,WAAK,SAAL,CAAe,SAAf;AACD;;AAED;;;;;;;;;;AASA;;;;;;;;;;uBAUG,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;AAED;;;;;;;;;;;wBAQI,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAP;AACD;;;8BAES,S,EAAW;AACnB,UAAI,CAAC,KAAK,UAAV,EACE;AACF,WAAK,UAAL,CAAgB,GAAhB,CAAoB,KAAK,UAAL,CAAgB,KAApC,EAA2C,KAAK,eAAL,CAAqB,SAArB,CAA3C;AACD;;AAED;;;;;;;;;;;wBApCmB;AACjB,aAAO,KAAK,UAAL,GAAkB,KAAK,UAAL,CAAgB,KAAlC,GAA0C,IAAjD;AACD;;;;;;AA6CH;;;;;;;;;;;;;;;;;;;ACzNA;;;;AAEA,SAAS,iBAAT,CAA2B,CAA3B,EAA8B,CAA9B,EAAiC;AAC/B,MAAI,MAAM,CAAV,EAAa;AACX,WAAO,CAAP;AACD,GAFD,MAEO,IAAI,IAAI,CAAR,EAAW;AAChB,WAAO,CAAC,CAAR;AACD,GAFM,MAEA,IAAI,IAAI,CAAR,EAAW;AAChB,WAAO,CAAP;AACD;AACF;;AAED;;;;IAGqB,S;AACnB,uBAAc;AAAA;;AACZ,SAAK,KAAL;AACD;;;;4BAEO;AACN;AACA,WAAK,QAAL,GAAgB,EAAhB;AACA;AACA,WAAK,KAAL,GAAa,EAAb;AACA,WAAK,MAAL,GAAc,IAAd;AACA,WAAK,cAAL,GAAsB,CAAtB;AACD;;;2BAMM,Q,EAAU,I,EAAM;AACrB,UAAI,SAAS,IAAb,EAAmB;AACjB,eAAO,KAAK,KAAL,CAAW,CAAX,CAAP,CADiB,CACK;AACtB,aAAK,IAAL,CAAU,iBAAV;AACD;;AAJoB,6BAME,2BAAgB,KAAK,QAAL,CAAc,QAAd,CAAhB,EAAyC,IAAzC,CANF;AAAA,UAMhB,KANgB,oBAMhB,KANgB;AAAA,UAMT,OANS,oBAMT,OANS;;AAOrB,WAAK,QAAL,CAAc,QAAd,IAA0B,IAA1B;;AAEA,WAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,MAAM,MAA1B,EAAkC,GAAlC,EAAuC;AACrC,aAAK,KAAL,CAAW,MAAM,CAAN,CAAX,IAAuB,CAAC,KAAK,KAAL,CAAW,MAAM,CAAN,CAAX,KAAwB,CAAzB,IAA8B,CAArD;AACD;AACD,WAAK,IAAI,KAAI,CAAb,EAAgB,KAAI,QAAQ,MAA5B,EAAoC,IAApC,EAAyC;AACvC,aAAK,KAAL,CAAW,QAAQ,EAAR,CAAX;AACD;;AAED,WAAK,YAAL,CAAkB,IAAlB;AACD;;AAED;;;;;;;;mCAKmC;AAAA,UAAtB,IAAsB,uEAAf,KAAK,QAAU;;AACjC,UAAI,cAAc,OAAO,IAAP,CAAY,KAAK,QAAjB,EAA2B,MAA7C;AACA,UAAI,gBAAgB,CAApB,EAAuB;AACrB,aAAK,MAAL,GAAc,IAAd;AACD,OAFD,MAEO;AACL,aAAK,MAAL,GAAc,EAAd;AACA,aAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,cAAI,QAAQ,KAAK,KAAL,CAAW,KAAK,CAAL,CAAX,CAAZ;AACA,cAAI,UAAU,WAAd,EAA2B;AACzB,iBAAK,MAAL,CAAY,IAAZ,CAAiB,KAAK,CAAL,CAAjB;AACD;AACF;AACF;AACF;;;0BAEK,Q,EAAU;AACd,UAAI,OAAO,KAAK,QAAL,CAAc,QAAd,CAAP,KAAoC,WAAxC,EAAqD;AACnD;AACD;;AAED,UAAI,OAAO,KAAK,QAAL,CAAc,QAAd,CAAX;AACA,UAAI,CAAC,IAAL,EAAW;AACT,eAAO,EAAP;AACD;;AAED,WAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,aAAK,KAAL,CAAW,KAAK,CAAL,CAAX;AACD;AACD,aAAO,KAAK,QAAL,CAAc,QAAd,CAAP;;AAEA,WAAK,YAAL;AACD;;;wBA3DW;AACV,aAAO,KAAK,MAAZ;AACD;;;wBA2Dc;AACb,UAAI,UAAU,OAAO,IAAP,CAAY,KAAK,KAAjB,CAAd;AACA,cAAQ,IAAR,CAAa,iBAAb;AACA,aAAO,OAAP;AACD;;;;;;kBA/EkB,S;;;;;;;;;;;;;;kBCRG,K;;AAPxB;;;;;;;;AAEA;AACA;AACA,OAAO,kBAAP,GAA4B,OAAO,kBAAP,IAA6B,EAAzD;AACA,IAAI,SAAS,OAAO,kBAApB;;AAEe,SAAS,KAAT,CAAe,SAAf,EAA0B;AACvC,MAAI,aAAa,OAAO,SAAP,KAAsB,QAAvC,EAAiD;AAC/C,QAAI,CAAC,OAAO,cAAP,CAAsB,SAAtB,CAAL,EAAuC;AACrC,aAAO,SAAP,IAAoB,IAAI,KAAJ,CAAU,SAAV,CAApB;AACD;AACD,WAAO,OAAO,SAAP,CAAP;AACD,GALD,MAKO,IAAI,QAAO,SAAP,yCAAO,SAAP,OAAsB,QAAtB,IAAkC,UAAU,KAA5C,IAAqD,UAAU,GAAnE,EAAwE;AAC7E;AACA,WAAO,SAAP;AACD,GAHM,MAGA,IAAI,MAAM,OAAN,CAAc,SAAd,KACP,UAAU,MAAV,IAAoB,CADb,IAEP,OAAO,UAAU,CAAV,CAAP,KAAyB,QAFtB,EAEgC;AACrC,WAAO,MAAM,UAAU,CAAV,CAAN,CAAP;AACD,GAJM,MAIA;AACL,UAAM,IAAI,KAAJ,CAAU,4BAAV,CAAN;AACD;AACF;;IAEK,K;AACJ,iBAAY,IAAZ,EAAkB;AAAA;;AAChB,SAAK,IAAL,GAAY,IAAZ;AACA,SAAK,KAAL,GAAa,EAAb;AACD;;;;yBAEG,I,EAAM;AACR,UAAI,CAAC,IAAD,IAAS,OAAO,IAAP,KAAiB,QAA9B,EAAwC;AACtC,cAAM,IAAI,KAAJ,CAAU,kBAAV,CAAN;AACD;;AAED,UAAI,CAAC,KAAK,KAAL,CAAW,cAAX,CAA0B,IAA1B,CAAL,EACE,KAAK,KAAL,CAAW,IAAX,IAAmB,kBAAQ,IAAR,EAAc,IAAd,CAAnB;AACF,aAAO,KAAK,KAAL,CAAW,IAAX,CAAP;AACD;;;wBAEG,I,EAAM;AACR,UAAI,CAAC,IAAD,IAAS,OAAO,IAAP,KAAiB,QAA9B,EAAwC;AACtC,cAAM,IAAI,KAAJ,CAAU,kBAAV,CAAN;AACD;;AAED,aAAO,KAAK,KAAL,CAAW,cAAX,CAA0B,IAA1B,CAAP;AACD;;;;;;;;;;;;;;;;AC/CH;;;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;AAEA,IAAM,eAAe,qBAAM,SAAN,CAArB;;AAEA,SAAS,IAAT,CAAc,IAAd,EAAoB;AAClB,SAAO,aAAa,GAAb,CAAiB,IAAjB,CAAP;AACD;;AAED,SAAS,GAAT,CAAa,IAAb,EAAmB;AACjB,SAAO,aAAa,GAAb,CAAiB,IAAjB,CAAP;AACD;;AAED,IAAI,OAAO,KAAX,EAAkB;AAChB,SAAO,KAAP,CAAa,uBAAb,CAAqC,qBAArC,EAA4D,UAAS,OAAT,EAAkB;AAC5E,QAAI,OAAO,QAAQ,KAAf,KAA0B,QAA9B,EAAwC;AACtC,2BAAM,QAAQ,KAAd,EAAqB,GAArB,CAAyB,QAAQ,IAAjC,EAAuC,GAAvC,CAA2C,QAAQ,KAAnD;AACD,KAFD,MAEO;AACL,WAAK,QAAQ,IAAb,EAAmB,GAAnB,CAAuB,QAAQ,KAA/B;AACD;AACF,GAND;AAOD;;AAED,IAAM,YAAY;AAChB,wBADgB;AAEhB,OAAK,IAFW;AAGhB,OAAK,GAHW;AAIhB,6CAJgB;AAKhB,oCALgB;AAMhB;AANgB,CAAlB;;AASA;;;kBAGe,S;;AACf,OAAO,SAAP,GAAmB,SAAnB;;;;;;;;;;;QCrCgB,Q,GAAA,Q;QAWA,I,GAAA,I;AAfhB,IAAI,IAAI,OAAO,MAAf;;AAEA,IAAI,WAAW,EAAf;;AAEO,SAAS,QAAT,CAAkB,GAAlB,EAAuB;AAC5B,WAAS,IAAI,SAAb,IAA0B,GAA1B;AACA,MAAI,OAAO,QAAP,IAAmB,OAAO,QAAP,CAAgB,UAAhB,KAA+B,UAAtD,EAAkE;AAChE,MAAE,YAAM;AACN;AACD,KAFD;AAGD,GAJD,MAIO,IAAI,OAAO,QAAX,EAAqB;AAC1B,eAAW,IAAX,EAAiB,GAAjB;AACD;AACF;;AAEM,SAAS,IAAT,GAAgB;AACrB,SAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAS,SAAT,EAAoB;AAChD,QAAI,UAAU,SAAS,SAAT,CAAd;AACA,MAAE,MAAM,QAAQ,SAAhB,EAA2B,GAA3B,CAA+B,wBAA/B,EAAyD,IAAzD,CAA8D,UAAS,CAAT,EAAY,EAAZ,EAAgB;AAC5E,mBAAa,OAAb,EAAsB,EAAtB;AACD,KAFD;AAGD,GALD;AAMD;;AAED;AACA,SAAS,OAAT,CAAiB,GAAjB,EAAsB;AACpB,SAAO,IAAI,OAAJ,CAAY,uCAAZ,EAAqD,MAArD,CAAP;AACD;;AAED,SAAS,MAAT,CAAgB,EAAhB,EAAoB;AAClB,MAAI,MAAM,EAAE,EAAF,CAAV;AACA,SAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAS,SAAT,EAAoB;AAChD,QAAI,IAAI,QAAJ,CAAa,SAAb,KAA2B,CAAC,IAAI,QAAJ,CAAa,uBAAb,CAAhC,EAAuE;AACrE,UAAI,UAAU,SAAS,SAAT,CAAd;AACA,mBAAa,OAAb,EAAsB,EAAtB;AACD;AACF,GALD;AAMD;;AAED,SAAS,YAAT,CAAsB,OAAtB,EAA+B,EAA/B,EAAmC;AACjC,MAAI,SAAS,EAAE,EAAF,EAAM,IAAN,CAAW,+CAA+C,QAAQ,GAAG,EAAX,CAA/C,GAAgE,IAA3E,CAAb;AACA,MAAI,OAAO,KAAK,KAAL,CAAW,OAAO,CAAP,EAAU,SAArB,CAAX;;AAEA,MAAI,WAAW,QAAQ,OAAR,CAAgB,EAAhB,EAAoB,IAApB,CAAf;AACA,IAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,QAAjC;AACA,IAAE,EAAF,EAAM,QAAN,CAAe,uBAAf;AACD;;AAED,IAAI,OAAO,KAAX,EAAkB;AAChB,MAAI,eAAe,IAAI,OAAO,KAAP,CAAa,YAAjB,EAAnB;AACA,MAAI,KAAI,OAAO,MAAf;AACA,KAAE,MAAF,CAAS,YAAT,EAAuB;AACrB,UAAM,cAAS,KAAT,EAAgB;AACpB,aAAO,GAAE,KAAF,EAAS,IAAT,CAAc,kBAAd,CAAP;AACD,KAHoB;AAIrB,gBAAY,oBAAS,EAAT,EAAa;AACvB,UAAI,CAAC,GAAE,EAAF,EAAM,QAAN,CAAe,uBAAf,CAAL,EAA8C;AAC5C,eAAO,EAAP;AACD;AACF,KARoB;AASrB,WAAO,eAAS,EAAT,EAAa;AAClB,aAAO,GAAG,EAAV;AACD,KAXoB;AAYrB,cAAU,kBAAS,EAAT,EAAa,CAEtB,CAdoB;AAerB,cAAU,kBAAS,EAAT,EAAa,KAAb,EAAoB,CAE7B,CAjBoB;AAkBrB,oBAAgB,wBAAS,EAAT,EAAa,IAAb,EAAmB,CAElC,CApBoB;AAqBrB,eAAW,mBAAS,EAAT,EAAa,QAAb,EAAuB;AAChC,SAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,MAAjC;AACD,KAvBoB;AAwBrB,iBAAa,qBAAS,EAAT,EAAa;AACxB,SAAE,EAAF,EAAM,IAAN,CAAW,oBAAX,EAAiC,OAAjC;AACD;AA1BoB,GAAvB;AA4BA,SAAO,KAAP,CAAa,aAAb,CAA2B,QAA3B,CAAoC,YAApC,EAAkD,wBAAlD;AACD;;;;;;;;AChFD;;IAAY,K;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,+BADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;AAIA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,sBAAJ;AACA,QAAI,MAAM,EAAE,EAAF,CAAV;AACA,QAAI,EAAJ,CAAO,QAAP,EAAiB,wBAAjB,EAA2C,YAAW;AACpD,UAAI,UAAU,IAAI,IAAJ,CAAS,gCAAT,CAAd;AACA,UAAI,QAAQ,MAAR,KAAmB,CAAvB,EAA0B;AACxB,wBAAgB,IAAhB;AACA,iBAAS,KAAT;AACD,OAHD,MAGO;AACL,YAAI,OAAO,EAAX;AACA,gBAAQ,IAAR,CAAa,YAAW;AACtB,eAAK,GAAL,CAAS,KAAK,KAAd,EAAqB,OAArB,CAA6B,UAAS,GAAT,EAAc;AACzC,iBAAK,GAAL,IAAY,IAAZ;AACD,WAFD;AAGD,SAJD;AAKA,YAAI,WAAW,OAAO,IAAP,CAAY,IAAZ,CAAf;AACA,iBAAS,IAAT;AACA,wBAAgB,QAAhB;AACA,iBAAS,GAAT,CAAa,QAAb;AACD;AACF,KAjBD;;AAmBA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AAxCY,CAAf;;;;;;;;ACLA;;IAAY,K;;AACZ;;IAAY,I;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,wBADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;;;AAMA,QAAI,QAAQ,CAAC,EAAC,OAAO,EAAR,EAAY,OAAO,OAAnB,EAAD,CAAZ;AACA,QAAI,QAAQ,KAAK,aAAL,CAAmB,KAAK,KAAxB,CAAZ;AACA,QAAI,OAAO;AACT,eAAS,MAAM,MAAN,CAAa,KAAb,CADA;AAET,kBAAY,OAFH;AAGT,kBAAY,OAHH;AAIT,mBAAa;AAJJ,KAAX;;AAOA,QAAI,SAAS,EAAE,EAAF,EAAM,IAAN,CAAW,QAAX,EAAqB,CAArB,CAAb;;AAEA,QAAI,YAAY,EAAE,MAAF,EAAU,SAAV,CAAoB,IAApB,EAA0B,CAA1B,EAA6B,SAA7C;;AAEA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,sBAAJ;AACA,cAAU,EAAV,CAAa,QAAb,EAAuB,YAAW;AAChC,UAAI,UAAU,KAAV,CAAgB,MAAhB,KAA2B,CAA/B,EAAkC;AAChC,wBAAgB,IAAhB;AACA,iBAAS,KAAT;AACD,OAHD,MAGO;AACL,YAAI,OAAO,EAAX;AACA,kBAAU,KAAV,CAAgB,OAAhB,CAAwB,UAAS,KAAT,EAAgB;AACtC,eAAK,GAAL,CAAS,KAAT,EAAgB,OAAhB,CAAwB,UAAS,GAAT,EAAc;AACpC,iBAAK,GAAL,IAAY,IAAZ;AACD,WAFD;AAGD,SAJD;AAKA,YAAI,WAAW,OAAO,IAAP,CAAY,IAAZ,CAAf;AACA,iBAAS,IAAT;AACA,wBAAgB,QAAhB;AACA,iBAAS,GAAT,CAAa,QAAb;AACD;AACF,KAhBD;;AAkBA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AArDY,CAAf;;;;;;;;;;ACNA;;IAAY,K;;AACZ;;;;AAEA,IAAI,IAAI,OAAO,MAAf;AACA,IAAI,WAAW,OAAO,QAAtB;;AAEA,MAAM,QAAN,CAAe;AACb,aAAW,wBADE;;AAGb,WAAS,iBAAS,EAAT,EAAa,IAAb,EAAmB;AAC1B;;;;AAIA,QAAI,WAAW,yBAAiB,KAAK,KAAtB,CAAf;;AAEA,QAAI,OAAO,EAAX;AACA,QAAI,MAAM,EAAE,EAAF,EAAM,IAAN,CAAW,OAAX,CAAV;AACA,QAAI,WAAW,IAAI,IAAJ,CAAS,WAAT,CAAf;AACA,QAAI,aAAa,IAAI,IAAJ,CAAS,aAAT,CAAjB;AACA,QAAI,QAAQ,IAAI,IAAJ,CAAS,OAAT,CAAZ;AACA,QAAI,sBAAJ;;AAEA;AACA,QAAI,aAAa,MAAjB,EAAyB;AACvB,sBAAgB,SAAS,GAAT,EAAhB;AACA,WAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,eAAO,cAAc,UAAd,EAA0B,IAAI,IAAJ,CAAS,GAAT,CAA1B,CAAP;AACD,OAFD;AAID,KAND,MAMO,IAAI,aAAa,UAAjB,EAA6B;AAClC,UAAI,WAAW,IAAI,IAAJ,CAAS,UAAT,CAAf;AACA,UAAI,QAAJ,EACE,gBAAgB,SAAS,QAAT,CAAkB,QAAlB,CAAhB,CADF,KAGE,gBAAgB,QAAhB;;AAEF,WAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,eAAO,cAAc,UAAd,EAA0B,IAAI,IAAJ,CAAS,GAAT,CAA1B,CAAP;AACD,OAFD;AAGD,KAVM,MAUA,IAAI,aAAa,QAAjB,EAA2B;AAChC,UAAI,OAAO,KAAP,KAAiB,WAArB,EACE,KAAK,QAAL,GAAgB,UAAS,GAAT,EAAc;AAC5B,YAAI,SAAS,KAAK,GAAL,CAAS,EAAT,EAAa,KAAb,CAAb;AACA,eAAO,KAAK,KAAL,CAAW,MAAM,MAAjB,IAA2B,MAAlC;AACD,OAHD;AAIH;;AAED,QAAI,cAAJ,CAAmB,IAAnB;;AAEA,aAAS,QAAT,GAAoB;AAClB,UAAI,SAAS,IAAI,IAAJ,CAAS,gBAAT,EAA2B,MAAxC;;AAEA;AACA,UAAI,gBAAJ;AACA,UAAI,WAAW,IAAI,IAAJ,CAAS,WAAT,CAAf;AACA,UAAI,aAAa,MAAjB,EAAyB;AACvB,kBAAU,iBAAS,GAAT,EAAc;AACtB,iBAAO,cAAc,IAAI,IAAJ,CAAS,CAAC,GAAV,CAAd,CAAP;AACD,SAFD;AAGD,OAJD,MAIO,IAAI,aAAa,UAAjB,EAA6B;AAClC,kBAAU,iBAAS,GAAT,EAAc;AACtB;AACA,iBAAO,CAAC,GAAD,GAAO,IAAd;AACD,SAHD;AAID,OALM,MAKA;AACL,kBAAU,iBAAS,GAAT,EAAc;AAAE,iBAAO,CAAC,GAAR;AAAc,SAAxC;AACD;;AAED,UAAI,IAAI,IAAJ,CAAS,gBAAT,EAA2B,OAA3B,CAAmC,IAAnC,KAA4C,QAAhD,EAA0D;AACxD,eAAO,CAAC,QAAQ,OAAO,IAAf,CAAD,EAAuB,QAAQ,OAAO,EAAf,CAAvB,CAAP;AACD,OAFD,MAEO;AACL,eAAO,QAAQ,OAAO,IAAf,CAAP;AACD;AACF;;AAED,QAAI,gBAAgB,IAApB;;AAEA,QAAI,EAAJ,CAAO,6BAAP,EAAsC,UAAS,KAAT,EAAgB;AACpD,UAAI,CAAC,IAAI,IAAJ,CAAS,UAAT,CAAD,IAAyB,CAAC,IAAI,IAAJ,CAAS,WAAT,CAA9B,EAAqD;AAAA,wBAClC,UADkC;AAAA;AAAA,YAC9C,IAD8C;AAAA,YACxC,EADwC;;AAEnD,YAAI,OAAO,EAAX;AACA,aAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAL,CAAY,MAAhC,EAAwC,GAAxC,EAA6C;AAC3C,cAAI,MAAM,KAAK,MAAL,CAAY,CAAZ,CAAV;AACA,cAAI,OAAO,IAAP,IAAe,OAAO,EAA1B,EAA8B;AAC5B,iBAAK,IAAL,CAAU,KAAK,IAAL,CAAU,CAAV,CAAV;AACD;AACF;AACD,aAAK,IAAL;AACA,iBAAS,GAAT,CAAa,IAAb;AACA,wBAAgB,IAAhB;AACD;AACF,KAdD;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,WAAO;AACL,eAAS,mBAAW;AAClB,iBAAS,KAAT;AACD,OAHI;AAIL,cAAQ,kBAAW;AACjB,YAAI,aAAJ,EACE,SAAS,GAAT,CAAa,aAAb;AACH;AAPI,KAAP;AASD;AApHY,CAAf;;AAwHA;AACA,SAAS,QAAT,CAAkB,CAAlB,EAAqB,MAArB,EAA6B;AAC3B,MAAI,MAAM,EAAE,QAAF,EAAV;AACA,SAAO,IAAI,MAAJ,GAAa,MAApB;AACE,UAAM,MAAM,GAAZ;AADF,GAEA,OAAO,GAAP;AACD;;AAED;AACA;AACA,SAAS,aAAT,CAAuB,IAAvB,EAA6B;AAC3B,MAAI,gBAAgB,IAApB,EAA0B;AACxB,WAAO,KAAK,cAAL,KAAwB,GAAxB,GACA,SAAS,KAAK,WAAL,KAAmB,CAA5B,EAA+B,CAA/B,CADA,GACoC,GADpC,GAEA,SAAS,KAAK,UAAL,EAAT,EAA4B,CAA5B,CAFP;AAID,GALD,MAKO;AACL,WAAO,IAAP;AACD;AACF;;;;;;;;;;;;;;ACjJD;;;;AACA;;;;AACA;;IAAY,I;;;;;;;;AAEZ;;;;;;;;;;;;;;;;IAgBa,e,WAAA,e;AAEX,6BAA4C;AAAA,QAAhC,KAAgC,uEAAxB,IAAwB;AAAA,QAAlB,SAAkB,uEAAN,IAAM;;AAAA;;AAC1C,SAAK,WAAL,GAAmB,sBAAnB;AACA,SAAK,QAAL,GAAgB,IAAI,KAAK,mBAAT,CAA6B,KAAK,WAAlC,CAAhB;;AAEA;AACA,SAAK,MAAL,GAAc,IAAd;AACA;AACA,SAAK,IAAL,GAAY,IAAZ;AACA;AACA,SAAK,eAAL,GAAuB,IAAvB;;AAEA,SAAK,UAAL,GAAkB,KAAK,MAAL,CAAY,EAAE,QAAQ,IAAV,EAAZ,EAA8B,SAA9B,CAAlB;;AAEA,SAAK,QAAL,CAAc,KAAd;AACD;;AAED;;;;;;;;;;;;;;;;;6BAaS,K,EAAO;AAAA;;AACd;AACA,UAAI,KAAK,MAAL,KAAgB,KAApB,EACE;AACF;AACA,UAAI,CAAC,KAAK,MAAN,IAAgB,CAAC,KAArB,EACE;;AAEF,UAAI,KAAK,IAAT,EAAe;AACb,aAAK,IAAL,CAAU,GAAV,CAAc,QAAd,EAAwB,KAAK,eAA7B;AACA,aAAK,IAAL,GAAY,IAAZ;AACA,aAAK,eAAL,GAAuB,IAAvB;AACD;;AAED,WAAK,MAAL,GAAc,KAAd;;AAEA,UAAI,KAAJ,EAAW;AACT,aAAK,IAAL,GAAY,qBAAI,KAAJ,EAAW,GAAX,CAAe,WAAf,CAAZ;AACA,YAAI,MAAM,KAAK,IAAL,CAAU,EAAV,CAAa,QAAb,EAAuB,UAAC,CAAD,EAAO;AACtC,gBAAK,WAAL,CAAiB,OAAjB,CAAyB,QAAzB,EAAmC,CAAnC;AACD,SAFS,CAAV;AAGA,aAAK,eAAL,GAAuB,GAAvB;AACD;AACF;;AAED;;;;;;;;;;;;;;;AAcA;;;;;oCAKgB,S,EAAW;AACzB;AACA,aAAO,KAAK,MAAL,CAAY,EAAZ,EACL,KAAK,UAAL,GAAkB,KAAK,UAAvB,GAAoC,IAD/B,EAEL,YAAY,SAAZ,GAAwB,IAFnB,CAAP;AAGD;;AAED;;;;;;;;;;;;;;;wBAYI,Y,EAAc,S,EAAW;AAC3B,UAAI,KAAK,IAAT,EACE,KAAK,IAAL,CAAU,GAAV,CAAc,YAAd,EAA4B,KAAK,eAAL,CAAqB,SAArB,CAA5B;AACH;;AAED;;;;;;;;;;;;;0BAUM,S,EAAW;AACf,UAAI,KAAK,IAAT,EACE,KAAK,GAAL,CAAS,KAAK,CAAd,EAAiB,KAAK,eAAL,CAAqB,SAArB,CAAjB;AACH;;AAED;;;;;;;;;;;;;uBAUG,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;AAED;;;;;;;;;;;wBAQI,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAP;AACD;;AAED;;;;;;;;4BAKQ;AACN,WAAK,QAAL,CAAc,kBAAd;AACA,WAAK,QAAL,CAAc,IAAd;AACD;;;wBAlFW;AACV,aAAO,KAAK,IAAL,GAAY,KAAK,IAAL,CAAU,GAAV,EAAZ,GAA8B,IAArC;AACD;;;;;;AAmFH;;;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;QCpLgB,M,GAAA,M;QAeA,W,GAAA,W;QAQA,e,GAAA,e;QAoCA,a,GAAA,a;;;;AA3DT,SAAS,MAAT,CAAgB,MAAhB,EAAoC;AAAA,oCAAT,OAAS;AAAT,WAAS;AAAA;;AACzC,OAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,QAAQ,MAA5B,EAAoC,GAApC,EAAyC;AACvC,QAAI,MAAM,QAAQ,CAAR,CAAV;AACA,QAAI,OAAO,GAAP,KAAgB,WAAhB,IAA+B,QAAQ,IAA3C,EACE;;AAEF,SAAK,IAAI,GAAT,IAAgB,GAAhB,EAAqB;AACnB,UAAI,IAAI,cAAJ,CAAmB,GAAnB,CAAJ,EAA6B;AAC3B,eAAO,GAAP,IAAc,IAAI,GAAJ,CAAd;AACD;AACF;AACF;AACD,SAAO,MAAP;AACD;;AAEM,SAAS,WAAT,CAAqB,IAArB,EAA2B;AAChC,OAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAzB,EAAiC,GAAjC,EAAsC;AACpC,QAAI,KAAK,CAAL,KAAW,KAAK,IAAE,CAAP,CAAf,EAA0B;AACxB,YAAM,IAAI,KAAJ,CAAU,0CAAV,CAAN;AACD;AACF;AACF;;AAEM,SAAS,eAAT,CAAyB,CAAzB,EAA4B,CAA5B,EAA+B;AACpC,MAAI,MAAM,CAAV;AACA,MAAI,MAAM,CAAV;;AAEA,MAAI,CAAC,CAAL,EAAQ,IAAI,EAAJ;AACR,MAAI,CAAC,CAAL,EAAQ,IAAI,EAAJ;;AAER,MAAI,SAAS,EAAb;AACA,MAAI,SAAS,EAAb;;AAEA,cAAY,CAAZ;AACA,cAAY,CAAZ;;AAEA,SAAO,MAAM,EAAE,MAAR,IAAkB,MAAM,EAAE,MAAjC,EAAyC;AACvC,QAAI,EAAE,GAAF,MAAW,EAAE,GAAF,CAAf,EAAuB;AACrB;AACA;AACD,KAHD,MAGO,IAAI,EAAE,GAAF,IAAS,EAAE,GAAF,CAAb,EAAqB;AAC1B,aAAO,IAAP,CAAY,EAAE,KAAF,CAAZ;AACD,KAFM,MAEA;AACL,aAAO,IAAP,CAAY,EAAE,KAAF,CAAZ;AACD;AACF;;AAED,MAAI,MAAM,EAAE,MAAZ,EACE,SAAS,OAAO,MAAP,CAAc,EAAE,KAAF,CAAQ,GAAR,CAAd,CAAT;AACF,MAAI,MAAM,EAAE,MAAZ,EACE,SAAS,OAAO,MAAP,CAAc,EAAE,KAAF,CAAQ,GAAR,CAAd,CAAT;AACF,SAAO;AACL,aAAS,MADJ;AAEL,WAAO;AAFF,GAAP;AAID;;AAED;AACA;AACO,SAAS,aAAT,CAAuB,EAAvB,EAA2B;AAChC,MAAI,QAAQ,EAAZ;AACA,MAAI,eAAJ;AACA,OAAK,IAAI,IAAT,IAAiB,EAAjB,EAAqB;AACnB,QAAI,GAAG,cAAH,CAAkB,IAAlB,CAAJ,EACE,MAAM,IAAN,CAAW,IAAX;AACF,QAAI,QAAO,GAAG,IAAH,CAAP,MAAqB,QAArB,IAAiC,OAAO,GAAG,IAAH,EAAS,MAAhB,KAA4B,WAAjE,EAA8E;AAC5E,YAAM,IAAI,KAAJ,CAAU,2BAAV,CAAN;AACD,KAFD,MAEO,IAAI,OAAO,MAAP,KAAmB,WAAnB,IAAkC,WAAW,GAAG,IAAH,EAAS,MAA1D,EAAkE;AACvE,YAAM,IAAI,KAAJ,CAAU,8CAAV,CAAN;AACD;AACD,aAAS,GAAG,IAAH,EAAS,MAAlB;AACD;AACD,MAAI,UAAU,EAAd;AACA,MAAI,aAAJ;AACA,OAAK,IAAI,MAAM,CAAf,EAAkB,MAAM,MAAxB,EAAgC,KAAhC,EAAuC;AACrC,WAAO,EAAP;AACA,SAAK,IAAI,MAAM,CAAf,EAAkB,MAAM,MAAM,MAA9B,EAAsC,KAAtC,EAA6C;AAC3C,WAAK,MAAM,GAAN,CAAL,IAAmB,GAAG,MAAM,GAAN,CAAH,EAAe,GAAf,CAAnB;AACD;AACD,YAAQ,IAAR,CAAa,IAAb;AACD;AACD,SAAO,OAAP;AACD;;AAED;;;;;;;IAMa,mB,WAAA,mB;AACX,+BAAY,OAAZ,EAAqB;AAAA;;AACnB,SAAK,QAAL,GAAgB,OAAhB;AACA,SAAK,KAAL,GAAa,EAAb;AACD;;;;uBAEE,S,EAAW,Q,EAAU;AACtB,UAAI,MAAM,KAAK,QAAL,CAAc,EAAd,CAAiB,SAAjB,EAA4B,QAA5B,CAAV;AACA,WAAK,KAAL,CAAW,GAAX,IAAkB,SAAlB;AACA,aAAO,GAAP;AACD;;;wBAEG,S,EAAW,Q,EAAU;AACvB,UAAI,MAAM,KAAK,QAAL,CAAc,GAAd,CAAkB,SAAlB,EAA6B,QAA7B,CAAV;AACA,UAAI,GAAJ,EAAS;AACP,eAAO,KAAK,KAAL,CAAW,GAAX,CAAP;AACD;AACD,aAAO,GAAP;AACD;;;yCAEoB;AAAA;;AACnB,UAAI,eAAe,KAAK,KAAxB;AACA,WAAK,KAAL,GAAa,EAAb;AACA,aAAO,IAAP,CAAY,YAAZ,EAA0B,OAA1B,CAAkC,UAAC,GAAD,EAAS;AACzC,cAAK,QAAL,CAAc,GAAd,CAAkB,aAAa,GAAb,CAAlB,EAAqC,GAArC;AACD,OAFD;AAGD;;;;;;;;;;;;;;;;;;ACpHH;;;;;;;;IAEqB,G;AACnB,eAAY,KAAZ,EAAmB,IAAnB,EAAyB,YAAa,KAAtC,EAA6C;AAAA;;AAC3C,SAAK,MAAL,GAAc,KAAd;AACA,SAAK,KAAL,GAAa,IAAb;AACA,SAAK,MAAL,GAAc,KAAd;AACA,SAAK,OAAL,GAAe,sBAAf;AACD;;;;0BAEK;AACJ,aAAO,KAAK,MAAZ;AACD;;;wBAEG,K,EAAO,YAAa,K,EAAO;AAC7B,UAAI,KAAK,MAAL,KAAgB,KAApB,EAA2B;AACzB;AACA;AACD;AACD,UAAI,WAAW,KAAK,MAApB;AACA,WAAK,MAAL,GAAc,KAAd;AACA;AACA,UAAI,MAAM,EAAV;AACA,UAAI,SAAS,QAAO,KAAP,yCAAO,KAAP,OAAkB,QAA/B,EAAyC;AACvC,aAAK,IAAI,CAAT,IAAc,KAAd,EAAqB;AACnB,cAAI,MAAM,cAAN,CAAqB,CAArB,CAAJ,EACE,IAAI,CAAJ,IAAS,MAAM,CAAN,CAAT;AACH;AACF;AACD,UAAI,QAAJ,GAAe,QAAf;AACA,UAAI,KAAJ,GAAY,KAAZ;AACA,WAAK,OAAL,CAAa,OAAb,CAAqB,QAArB,EAA+B,GAA/B,EAAoC,IAApC;;AAEA;AACA;AACA,UAAI,OAAO,KAAP,IAAgB,OAAO,KAAP,CAAa,aAAjC,EAAgD;AAC9C,eAAO,KAAP,CAAa,aAAb,CACE,mBACG,KAAK,MAAL,CAAY,IAAZ,KAAqB,IAArB,GAA4B,KAAK,MAAL,CAAY,IAAZ,GAAmB,GAA/C,GAAqD,EADxD,IAEE,KAAK,KAHT,EAIE,OAAO,KAAP,KAAkB,WAAlB,GAAgC,IAAhC,GAAuC,KAJzC;AAMD;AACF;;;uBAEE,S,EAAW,Q,EAAU;AACtB,aAAO,KAAK,OAAL,CAAa,EAAb,CAAgB,SAAhB,EAA2B,QAA3B,CAAP;AACD;;;wBAEG,S,EAAW,Q,EAAU;AACvB,aAAO,KAAK,OAAL,CAAa,GAAb,CAAiB,SAAjB,EAA4B,QAA5B,CAAP;AACD;;;;;;kBAjDkB,G", + "file": "generated.js", + "sourceRoot": "", + "sourcesContent": [ + "(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()", + "export default class Events {\n constructor() {\n this._types = {};\n this._seq = 0;\n }\n\n on(eventType, listener) {\n let subs = this._types[eventType];\n if (!subs) {\n subs = this._types[eventType] = {};\n }\n let sub = \"sub\" + (this._seq++);\n subs[sub] = listener;\n return sub;\n }\n\n // Returns false if no match, or string for sub name if matched\n off(eventType, listener) {\n let subs = this._types[eventType];\n if (typeof(listener) === \"function\") {\n for (let key in subs) {\n if (subs.hasOwnProperty(key)) {\n if (subs[key] === listener) {\n delete subs[key];\n return key;\n }\n }\n }\n return false;\n } else if (typeof(listener) === \"string\") {\n if (subs && subs[listener]) {\n delete subs[listener];\n return listener;\n }\n return false;\n } else {\n throw new Error(\"Unexpected type for listener\");\n }\n }\n\n trigger(eventType, arg, thisObj) {\n let subs = this._types[eventType];\n for (let key in subs) {\n if (subs.hasOwnProperty(key)) {\n subs[key].call(thisObj, arg);\n }\n }\n }\n}\n", + "import Events from \"./events\";\nimport FilterSet from \"./filterset\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\nfunction getFilterSet(group) {\n let fsVar = group.var(\"filterset\");\n let result = fsVar.get();\n if (!result) {\n result = new FilterSet();\n fsVar.set(result);\n }\n return result;\n}\n\nlet id = 1;\nfunction nextId() {\n return id++;\n}\n\n/**\n * Use this class to contribute to, and listen for changes to, the filter set\n * for the given group of widgets. Filter input controls should create one\n * `FilterHandle` and only call {@link FilterHandle#set}. Output widgets that\n * wish to displayed filtered data should create one `FilterHandle` and use\n * the {@link FilterHandle#filteredKeys} property and listen for change\n * events.\n *\n * If two (or more) `FilterHandle` instances in the same webpage share the\n * same group name, they will contribute to a single \"filter set\". Each\n * `FilterHandle` starts out with a `null` value, which means they take\n * nothing away from the set of data that should be shown. To make a\n * `FilterHandle` actually remove data from the filter set, set its value to\n * an array of keys which should be displayed. Crosstalk will aggregate the\n * various key arrays by finding their intersection; only keys that are\n * present in all non-null filter handles are considered part of the filter\n * set.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the {@link FilterHandle#setGroup} method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class FilterHandle {\n constructor(group, extraInfo) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The filterSet that we're tracking, if any. Can change over time.\n this._filterSet = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._filterVar = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this._id = \"filter\" + nextId();\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this FilterHandle. If `set()` was\n * previously called on this handle, switching groups will clear those keys\n * from the old group's filter set. These keys will not be applied to the new\n * group's filter set either. In other words, `setGroup()` effectively calls\n * `clear()` before switching groups.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._filterVar) {\n this._filterVar.off(\"change\", this._varOnChangeSub);\n this.clear();\n this._varOnChangeSub = null;\n this._filterVar = null;\n this._filterSet = null;\n }\n\n this._group = group;\n\n if (group) {\n group = grp(group);\n this._filterSet = getFilterSet(group);\n this._filterVar = grp(group).var(\"filter\");\n let sub = this._filterVar.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Combine the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Close the handle. This clears this handle's contribution to the filter set,\n * and unsubscribes all event listeners.\n */\n close() {\n this._emitter.removeAllListeners();\n this.clear();\n this.setGroup(null);\n }\n\n /**\n * Clear this handle's contribution to the filter set.\n *\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n clear(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.clear(this._id);\n this._onChange(extraInfo);\n }\n\n /**\n * Set this handle's contribution to the filter set. This array should consist\n * of the keys of the rows that _should_ be displayed; any keys that are not\n * present in the array will be considered _filtered out_. Note that multiple\n * `FilterHandle` instances in the group may each contribute an array of keys,\n * and only those keys that appear in _all_ of the arrays make it through the\n * filter.\n *\n * @param {string[]} keys - Empty array, or array of keys. To clear the\n * filter, don't pass an empty array; instead, use the\n * {@link FilterHandle#clear} method.\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n set(keys, extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.update(this._id, keys);\n this._onChange(extraInfo);\n }\n\n /**\n * @return {string[]|null} - Either: 1) an array of keys that made it through\n * all of the `FilterHandle` instances, or, 2) `null`, which means no filter\n * is being applied (all data should be displayed).\n */\n get filteredKeys() {\n return this._filterSet ? this._filterSet.value : null;\n }\n\n /**\n * Subscribe to events on this `FilterHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {FilterHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link FilterHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancel event subscriptions created by {@link FilterHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|FilterHandle~listener} listener - Either the callback\n * function previously passed into {@link FilterHandle#on}, or the\n * string that was returned from {@link FilterHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n _onChange(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * @callback FilterHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the filter set, or `null` if no filter set is active),\n * `oldValue` (the previous value of the filter set), and `sender` (the\n * `FilterHandle` instance that made the change).\n */\n\n}\n\n/**\n * @event FilterHandle#change\n * @type {object}\n * @property {object} value - The new value of the filter set, or `null`\n * if no filter set is active.\n * @property {object} oldValue - The previous value of the filter set.\n * @property {FilterHandle} sender - The `FilterHandle` instance that\n * changed the value.\n */\n", + "import { diffSortedLists } from \"./util\";\n\nfunction naturalComparator(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n}\n\n/**\n * @private\n */\nexport default class FilterSet {\n constructor() {\n this.reset();\n }\n\n reset() {\n // Key: handle ID, Value: array of selected keys, or null\n this._handles = {};\n // Key: key string, Value: count of handles that include it\n this._keys = {};\n this._value = null;\n this._activeHandles = 0;\n }\n\n get value() {\n return this._value;\n }\n\n update(handleId, keys) {\n if (keys !== null) {\n keys = keys.slice(0); // clone before sorting\n keys.sort(naturalComparator);\n }\n\n let {added, removed} = diffSortedLists(this._handles[handleId], keys);\n this._handles[handleId] = keys;\n\n for (let i = 0; i < added.length; i++) {\n this._keys[added[i]] = (this._keys[added[i]] || 0) + 1;\n }\n for (let i = 0; i < removed.length; i++) {\n this._keys[removed[i]]--;\n }\n\n this._updateValue(keys);\n }\n\n /**\n * @param {string[]} keys Sorted array of strings that indicate\n * a superset of possible keys.\n * @private\n */\n _updateValue(keys = this._allKeys) {\n let handleCount = Object.keys(this._handles).length;\n if (handleCount === 0) {\n this._value = null;\n } else {\n this._value = [];\n for (let i = 0; i < keys.length; i++) {\n let count = this._keys[keys[i]];\n if (count === handleCount) {\n this._value.push(keys[i]);\n }\n }\n }\n }\n\n clear(handleId) {\n if (typeof(this._handles[handleId]) === \"undefined\") {\n return;\n }\n\n let keys = this._handles[handleId];\n if (!keys) {\n keys = [];\n }\n\n for (let i = 0; i < keys.length; i++) {\n this._keys[keys[i]]--;\n }\n delete this._handles[handleId];\n\n this._updateValue();\n }\n\n get _allKeys() {\n let allKeys = Object.keys(this._keys);\n allKeys.sort(naturalComparator);\n return allKeys;\n }\n}\n", + "import Var from \"./var\";\n\n// Use a global so that multiple copies of crosstalk.js can be loaded and still\n// have groups behave as singletons across all copies.\nglobal.__crosstalk_groups = global.__crosstalk_groups || {};\nlet groups = global.__crosstalk_groups;\n\nexport default function group(groupName) {\n if (groupName && typeof(groupName) === \"string\") {\n if (!groups.hasOwnProperty(groupName)) {\n groups[groupName] = new Group(groupName);\n }\n return groups[groupName];\n } else if (typeof(groupName) === \"object\" && groupName._vars && groupName.var) {\n // Appears to already be a group object\n return groupName;\n } else if (Array.isArray(groupName) &&\n groupName.length == 1 &&\n typeof(groupName[0]) === \"string\") {\n return group(groupName[0]);\n } else {\n throw new Error(\"Invalid groupName argument\");\n }\n}\n\nclass Group {\n constructor(name) {\n this.name = name;\n this._vars = {};\n }\n\n var(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n if (!this._vars.hasOwnProperty(name))\n this._vars[name] = new Var(this, name);\n return this._vars[name];\n }\n\n has(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n return this._vars.hasOwnProperty(name);\n }\n}\n", + "import group from \"./group\";\nimport { SelectionHandle } from \"./selection\";\nimport { FilterHandle } from \"./filter\";\nimport { bind } from \"./input\";\nimport \"./input_selectize\";\nimport \"./input_checkboxgroup\";\nimport \"./input_slider\";\n\nconst defaultGroup = group(\"default\");\n\nfunction var_(name) {\n return defaultGroup.var(name);\n}\n\nfunction has(name) {\n return defaultGroup.has(name);\n}\n\nif (global.Shiny) {\n global.Shiny.addCustomMessageHandler(\"update-client-value\", function(message) {\n if (typeof(message.group) === \"string\") {\n group(message.group).var(message.name).set(message.value);\n } else {\n var_(message.name).set(message.value);\n }\n });\n}\n\nconst crosstalk = {\n group: group,\n var: var_,\n has: has,\n SelectionHandle: SelectionHandle,\n FilterHandle: FilterHandle,\n bind: bind\n};\n\n/**\n * @namespace crosstalk\n */\nexport default crosstalk;\nglobal.crosstalk = crosstalk;\n", + "let $ = global.jQuery;\n\nlet bindings = {};\n\nexport function register(reg) {\n bindings[reg.className] = reg;\n if (global.document && global.document.readyState !== \"complete\") {\n $(() => {\n bind();\n });\n } else if (global.document) {\n setTimeout(bind, 100);\n }\n}\n\nexport function bind() {\n Object.keys(bindings).forEach(function(className) {\n let binding = bindings[className];\n $(\".\" + binding.className).not(\".crosstalk-input-bound\").each(function(i, el) {\n bindInstance(binding, el);\n });\n });\n}\n\n// Escape jQuery identifier\nfunction $escape(val) {\n return val.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n}\n\nfunction bindEl(el) {\n let $el = $(el);\n Object.keys(bindings).forEach(function(className) {\n if ($el.hasClass(className) && !$el.hasClass(\"crosstalk-input-bound\")) {\n let binding = bindings[className];\n bindInstance(binding, el);\n }\n });\n}\n\nfunction bindInstance(binding, el) {\n let jsonEl = $(el).find(\"script[type='application/json'][data-for='\" + $escape(el.id) + \"']\");\n let data = JSON.parse(jsonEl[0].innerText);\n\n let instance = binding.factory(el, data);\n $(el).data(\"crosstalk-instance\", instance);\n $(el).addClass(\"crosstalk-input-bound\");\n}\n\nif (global.Shiny) {\n let inputBinding = new global.Shiny.InputBinding();\n let $ = global.jQuery;\n $.extend(inputBinding, {\n find: function(scope) {\n return $(scope).find(\".crosstalk-input\");\n },\n initialize: function(el) {\n if (!$(el).hasClass(\"crosstalk-input-bound\")) {\n bindEl(el);\n }\n },\n getId: function(el) {\n return el.id;\n },\n getValue: function(el) {\n\n },\n setValue: function(el, value) {\n\n },\n receiveMessage: function(el, data) {\n\n },\n subscribe: function(el, callback) {\n $(el).data(\"crosstalk-instance\").resume();\n },\n unsubscribe: function(el) {\n $(el).data(\"crosstalk-instance\").suspend();\n }\n });\n global.Shiny.inputBindings.register(inputBinding, \"crosstalk.inputBinding\");\n}\n", + "import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-checkboxgroup\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n let $el = $(el);\n $el.on(\"change\", \"input[type='checkbox']\", function() {\n let checked = $el.find(\"input[type='checkbox']:checked\");\n if (checked.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n checked.each(function() {\n data.map[this.value].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n", + "import * as input from \"./input\";\nimport * as util from \"./util\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-select\",\n\n factory: function(el, data) {\n /*\n * items: {value: [...], label: [...]}\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n\n let first = [{value: \"\", label: \"(All)\"}];\n let items = util.dataframeToD3(data.items);\n let opts = {\n options: first.concat(items),\n valueField: \"value\",\n labelField: \"label\",\n searchField: \"label\"\n };\n\n let select = $(el).find(\"select\")[0];\n\n let selectize = $(select).selectize(opts)[0].selectize;\n\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n selectize.on(\"change\", function() {\n if (selectize.items.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n selectize.items.forEach(function(group) {\n data.map[group].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n", + "import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\nlet strftime = global.strftime;\n\ninput.register({\n className: \"crosstalk-input-slider\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let opts = {};\n let $el = $(el).find(\"input\");\n let dataType = $el.data(\"data-type\");\n let timeFormat = $el.data(\"time-format\");\n let round = $el.data(\"round\");\n let timeFormatter;\n\n // Set up formatting functions\n if (dataType === \"date\") {\n timeFormatter = strftime.utc();\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n\n } else if (dataType === \"datetime\") {\n let timezone = $el.data(\"timezone\");\n if (timezone)\n timeFormatter = strftime.timezone(timezone);\n else\n timeFormatter = strftime;\n\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n } else if (dataType === \"number\") {\n if (typeof round !== \"undefined\")\n opts.prettify = function(num) {\n let factor = Math.pow(10, round);\n return Math.round(num * factor) / factor;\n };\n }\n\n $el.ionRangeSlider(opts);\n\n function getValue() {\n let result = $el.data(\"ionRangeSlider\").result;\n\n // Function for converting numeric value from slider to appropriate type.\n let convert;\n let dataType = $el.data(\"data-type\");\n if (dataType === \"date\") {\n convert = function(val) {\n return formatDateUTC(new Date(+val));\n };\n } else if (dataType === \"datetime\") {\n convert = function(val) {\n // Convert ms to s\n return +val / 1000;\n };\n } else {\n convert = function(val) { return +val; };\n }\n\n if ($el.data(\"ionRangeSlider\").options.type === \"double\") {\n return [convert(result.from), convert(result.to)];\n } else {\n return convert(result.from);\n }\n }\n\n let lastKnownKeys = null;\n\n $el.on(\"change.crosstalkSliderInput\", function(event) {\n if (!$el.data(\"updating\") && !$el.data(\"animating\")) {\n let [from, to] = getValue();\n let keys = [];\n for (let i = 0; i < data.values.length; i++) {\n let val = data.values[i];\n if (val >= from && val <= to) {\n keys.push(data.keys[i]);\n }\n }\n keys.sort();\n ctHandle.set(keys);\n lastKnownKeys = keys;\n }\n });\n\n\n // let $el = $(el);\n // $el.on(\"change\", \"input[type=\"checkbox\"]\", function() {\n // let checked = $el.find(\"input[type=\"checkbox\"]:checked\");\n // if (checked.length === 0) {\n // ctHandle.clear();\n // } else {\n // let keys = {};\n // checked.each(function() {\n // data.map[this.value].forEach(function(key) {\n // keys[key] = true;\n // });\n // });\n // let keyArray = Object.keys(keys);\n // keyArray.sort();\n // ctHandle.set(keyArray);\n // }\n // });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n\n\n// Convert a number to a string with leading zeros\nfunction padZeros(n, digits) {\n let str = n.toString();\n while (str.length < digits)\n str = \"0\" + str;\n return str;\n}\n\n// Given a Date object, return a string in yyyy-mm-dd format, using the\n// UTC date. This may be a day off from the date in the local time zone.\nfunction formatDateUTC(date) {\n if (date instanceof Date) {\n return date.getUTCFullYear() + \"-\" +\n padZeros(date.getUTCMonth()+1, 2) + \"-\" +\n padZeros(date.getUTCDate(), 2);\n\n } else {\n return null;\n }\n}\n", + "import Events from \"./events\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\n/**\n * Use this class to read and write (and listen for changes to) the selection\n * for a Crosstalk group. This is intended to be used for linked brushing.\n *\n * If two (or more) `SelectionHandle` instances in the same webpage share the\n * same group name, they will share the same state. Setting the selection using\n * one `SelectionHandle` instance will result in the `value` property instantly\n * changing across the others, and `\"change\"` event listeners on all instances\n * (including the one that initiated the sending) will fire.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the [SelectionHandle#setGroup](#setGroup) method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class SelectionHandle {\n\n constructor(group = null, extraInfo = null) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._var = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this SelectionHandle. The group\n * being switched away from (if any) will not have its selection value\n * modified as a result of calling `setGroup`, even if this handle was the\n * most recent handle to set the selection of the group.\n *\n * The group being switched to (if any) will also not have its selection value\n * modified as a result of calling `setGroup`. If you want to set the\n * selection value of the new group, call `set` explicitly.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._var) {\n this._var.off(\"change\", this._varOnChangeSub);\n this._var = null;\n this._varOnChangeSub = null;\n }\n\n this._group = group;\n\n if (group) {\n this._var = grp(group).var(\"selection\");\n let sub = this._var.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Retrieves the current selection for the group represented by this\n * `SelectionHandle`.\n *\n * - If no selection is active, then this value will be falsy.\n * - If a selection is active, but no data points are selected, then this\n * value will be an empty array.\n * - If a selection is active, and data points are selected, then the keys\n * of the selected data points will be present in the array.\n */\n get value() {\n return this._var ? this._var.get() : null;\n }\n\n /**\n * Combines the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n // Important incidental effect: shallow clone is returned\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see\n * {@link SelectionHandle#value}).\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `SelectionHandle` constructor).\n */\n set(selectedKeys, extraInfo) {\n if (this._var)\n this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any that were passed\n * into the `SelectionHandle` constructor).\n */\n clear(extraInfo) {\n if (this._var)\n this.set(void 0, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Subscribes to events on this `SelectionHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {SelectionHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancels event subscriptions created by {@link SelectionHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|SelectionHandle~listener} listener - Either the callback\n * function previously passed into {@link SelectionHandle#on}, or the\n * string that was returned from {@link SelectionHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n /**\n * Shuts down the `SelectionHandle` object.\n *\n * Removes all event listeners that were added through this handle.\n */\n close() {\n this._emitter.removeAllListeners();\n this.setGroup(null);\n }\n}\n\n/**\n * @callback SelectionHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the selection, or `undefined` if no selection is active),\n * `oldValue` (the previous value of the selection), and `sender` (the\n * `SelectionHandle` instance that made the change).\n */\n\n/**\n * @event SelectionHandle#change\n * @type {object}\n * @property {object} value - The new value of the selection, or `undefined`\n * if no selection is active.\n * @property {object} oldValue - The previous value of the selection.\n * @property {SelectionHandle} sender - The `SelectionHandle` instance that\n * changed the value.\n */\n", + "export function extend(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n let src = sources[i];\n if (typeof(src) === \"undefined\" || src === null)\n continue;\n\n for (let key in src) {\n if (src.hasOwnProperty(key)) {\n target[key] = src[key];\n }\n }\n }\n return target;\n}\n\nexport function checkSorted(list) {\n for (let i = 1; i < list.length; i++) {\n if (list[i] <= list[i-1]) {\n throw new Error(\"List is not sorted or contains duplicate\");\n }\n }\n}\n\nexport function diffSortedLists(a, b) {\n let i_a = 0;\n let i_b = 0;\n\n if (!a) a = [];\n if (!b) b = [];\n\n let a_only = [];\n let b_only = [];\n\n checkSorted(a);\n checkSorted(b);\n\n while (i_a < a.length && i_b < b.length) {\n if (a[i_a] === b[i_b]) {\n i_a++;\n i_b++;\n } else if (a[i_a] < b[i_b]) {\n a_only.push(a[i_a++]);\n } else {\n b_only.push(b[i_b++]);\n }\n }\n\n if (i_a < a.length)\n a_only = a_only.concat(a.slice(i_a));\n if (i_b < b.length)\n b_only = b_only.concat(b.slice(i_b));\n return {\n removed: a_only,\n added: b_only\n };\n}\n\n// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... }\n// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ]\nexport function dataframeToD3(df) {\n let names = [];\n let length;\n for (let name in df) {\n if (df.hasOwnProperty(name))\n names.push(name);\n if (typeof(df[name]) !== \"object\" || typeof(df[name].length) === \"undefined\") {\n throw new Error(\"All fields must be arrays\");\n } else if (typeof(length) !== \"undefined\" && length !== df[name].length) {\n throw new Error(\"All fields must be arrays of the same length\");\n }\n length = df[name].length;\n }\n let results = [];\n let item;\n for (let row = 0; row < length; row++) {\n item = {};\n for (let col = 0; col < names.length; col++) {\n item[names[col]] = df[names[col]][row];\n }\n results.push(item);\n }\n return results;\n}\n\n/**\n * Keeps track of all event listener additions/removals and lets all active\n * listeners be removed with a single operation.\n *\n * @private\n */\nexport class SubscriptionTracker {\n constructor(emitter) {\n this._emitter = emitter;\n this._subs = {};\n }\n\n on(eventType, listener) {\n let sub = this._emitter.on(eventType, listener);\n this._subs[sub] = eventType;\n return sub;\n }\n\n off(eventType, listener) {\n let sub = this._emitter.off(eventType, listener);\n if (sub) {\n delete this._subs[sub];\n }\n return sub;\n }\n\n removeAllListeners() {\n let current_subs = this._subs;\n this._subs = {};\n Object.keys(current_subs).forEach((sub) => {\n this._emitter.off(current_subs[sub], sub);\n });\n }\n}\n", + "import Events from \"./events\";\n\nexport default class Var {\n constructor(group, name, /*optional*/ value) {\n this._group = group;\n this._name = name;\n this._value = value;\n this._events = new Events();\n }\n\n get() {\n return this._value;\n }\n\n set(value, /*optional*/ event) {\n if (this._value === value) {\n // Do nothing; the value hasn't changed\n return;\n }\n let oldValue = this._value;\n this._value = value;\n // Alert JavaScript listeners that the value has changed\n let evt = {};\n if (event && typeof(event) === \"object\") {\n for (let k in event) {\n if (event.hasOwnProperty(k))\n evt[k] = event[k];\n }\n }\n evt.oldValue = oldValue;\n evt.value = value;\n this._events.trigger(\"change\", evt, this);\n\n // TODO: Make this extensible, to let arbitrary back-ends know that\n // something has changed\n if (global.Shiny && global.Shiny.onInputChange) {\n global.Shiny.onInputChange(\n \".clientValue-\" +\n (this._group.name !== null ? this._group.name + \"-\" : \"\") +\n this._name,\n typeof(value) === \"undefined\" ? null : value\n );\n }\n }\n\n on(eventType, listener) {\n return this._events.on(eventType, listener);\n }\n\n off(eventType, listener) {\n return this._events.off(eventType, listener);\n }\n}\n" + ] +}
\ No newline at end of file diff --git a/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.min.js b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.min.js new file mode 100644 index 0000000..b7ec0ac --- /dev/null +++ b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.min.js @@ -0,0 +1,2 @@ +!function o(u,a,l){function s(n,e){if(!a[n]){if(!u[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(f)return f(n,!0);var r=new Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r}var i=a[n]={exports:{}};u[n][0].call(i.exports,function(e){var t=u[n][1][e];return s(t||e)},i,i.exports,o,u,a,l)}return a[n].exports}for(var f="function"==typeof require&&require,e=0;e<l.length;e++)s(l[e]);return s}({1:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}();var i=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this._types={},this._seq=0}return r(e,[{key:"on",value:function(e,t){var n=this._types[e];n||(n=this._types[e]={});var r="sub"+this._seq++;return n[r]=t,r}},{key:"off",value:function(e,t){var n=this._types[e];if("function"==typeof t){for(var r in n)if(n.hasOwnProperty(r)&&n[r]===t)return delete n[r],r;return!1}if("string"==typeof t)return!(!n||!n[t])&&(delete n[t],t);throw new Error("Unexpected type for listener")}},{key:"trigger",value:function(e,t,n){var r=this._types[e];for(var i in r)r.hasOwnProperty(i)&&r[i].call(n,t)}}]),e}();n.default=i},{}],2:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.FilterHandle=void 0;var r=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}(),i=l(e("./events")),o=l(e("./filterset")),u=l(e("./group")),a=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(e("./util"));function l(e){return e&&e.__esModule?e:{default:e}}var s=1;n.FilterHandle=function(){function n(e,t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),this._eventRelay=new i.default,this._emitter=new a.SubscriptionTracker(this._eventRelay),this._group=null,this._filterSet=null,this._filterVar=null,this._varOnChangeSub=null,this._extraInfo=a.extend({sender:this},t),this._id="filter"+s++,this.setGroup(e)}return r(n,[{key:"setGroup",value:function(e){var t,n,r=this;if(this._group!==e&&((this._group||e)&&(this._filterVar&&(this._filterVar.off("change",this._varOnChangeSub),this.clear(),this._varOnChangeSub=null,this._filterVar=null,this._filterSet=null),this._group=e))){e=(0,u.default)(e),this._filterSet=(t=e.var("filterset"),(n=t.get())||(n=new o.default,t.set(n)),n),this._filterVar=(0,u.default)(e).var("filter");var i=this._filterVar.on("change",function(e){r._eventRelay.trigger("change",e,r)});this._varOnChangeSub=i}}},{key:"_mergeExtraInfo",value:function(e){return a.extend({},this._extraInfo?this._extraInfo:null,e||null)}},{key:"close",value:function(){this._emitter.removeAllListeners(),this.clear(),this.setGroup(null)}},{key:"clear",value:function(e){this._filterSet&&(this._filterSet.clear(this._id),this._onChange(e))}},{key:"set",value:function(e,t){this._filterSet&&(this._filterSet.update(this._id,e),this._onChange(t))}},{key:"on",value:function(e,t){return this._emitter.on(e,t)}},{key:"off",value:function(e,t){return this._emitter.off(e,t)}},{key:"_onChange",value:function(e){this._filterSet&&this._filterVar.set(this._filterSet.value,this._mergeExtraInfo(e))}},{key:"filteredKeys",get:function(){return this._filterSet?this._filterSet.value:null}}]),n}()},{"./events":1,"./filterset":3,"./group":4,"./util":11}],3:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}(),a=e("./util");function l(e,t){return e===t?0:e<t?-1:t<e?1:void 0}var i=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.reset()}return r(e,[{key:"reset",value:function(){this._handles={},this._keys={},this._value=null,this._activeHandles=0}},{key:"update",value:function(e,t){null!==t&&(t=t.slice(0)).sort(l);var n=(0,a.diffSortedLists)(this._handles[e],t),r=n.added,i=n.removed;this._handles[e]=t;for(var o=0;o<r.length;o++)this._keys[r[o]]=(this._keys[r[o]]||0)+1;for(var u=0;u<i.length;u++)this._keys[i[u]]--;this._updateValue(t)}},{key:"_updateValue",value:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:this._allKeys,t=Object.keys(this._handles).length;if(0===t)this._value=null;else{this._value=[];for(var n=0;n<e.length;n++){this._keys[e[n]]===t&&this._value.push(e[n])}}}},{key:"clear",value:function(e){if(void 0!==this._handles[e]){var t=this._handles[e];t||(t=[]);for(var n=0;n<t.length;n++)this._keys[t[n]]--;delete this._handles[e],this._updateValue()}}},{key:"value",get:function(){return this._value}},{key:"_allKeys",get:function(){var e=Object.keys(this._keys);return e.sort(l),e}}]),e}();n.default=i},{"./util":11}],4:[function(l,e,s){(function(e){"use strict";Object.defineProperty(s,"__esModule",{value:!0});var n=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}(),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};s.default=function e(t){{if(t&&"string"==typeof t)return u.hasOwnProperty(t)||(u[t]=new a(t)),u[t];if("object"===(void 0===t?"undefined":r(t))&&t._vars&&t.var)return t;if(Array.isArray(t)&&1==t.length&&"string"==typeof t[0])return e(t[0]);throw new Error("Invalid groupName argument")}};var t,i=l("./var"),o=(t=i)&&t.__esModule?t:{default:t};e.__crosstalk_groups=e.__crosstalk_groups||{};var u=e.__crosstalk_groups;var a=function(){function t(e){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.name=e,this._vars={}}return n(t,[{key:"var",value:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid var name");return this._vars.hasOwnProperty(e)||(this._vars[e]=new o.default(this,e)),this._vars[e]}},{key:"has",value:function(e){if(!e||"string"!=typeof e)throw new Error("Invalid var name");return this._vars.hasOwnProperty(e)}}]),t}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./var":12}],5:[function(f,e,c){(function(e){"use strict";Object.defineProperty(c,"__esModule",{value:!0});var t,n=f("./group"),r=(t=n)&&t.__esModule?t:{default:t},i=f("./selection"),o=f("./filter"),u=f("./input");f("./input_selectize"),f("./input_checkboxgroup"),f("./input_slider");var a=(0,r.default)("default");function l(e){return a.var(e)}e.Shiny&&e.Shiny.addCustomMessageHandler("update-client-value",function(e){"string"==typeof e.group?(0,r.default)(e.group).var(e.name).set(e.value):l(e.name).set(e.value)});var s={group:r.default,var:l,has:function(e){return a.has(e)},SelectionHandle:i.SelectionHandle,FilterHandle:o.FilterHandle,bind:u.bind};c.default=s,e.crosstalk=s}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./group":4,"./input":6,"./input_checkboxgroup":7,"./input_selectize":8,"./input_slider":9,"./selection":10}],6:[function(e,t,a){(function(t){"use strict";Object.defineProperty(a,"__esModule",{value:!0}),a.register=function(e){r[e.className]=e,t.document&&"complete"!==t.document.readyState?o(function(){n()}):t.document&&setTimeout(n,100)},a.bind=n;var o=t.jQuery,r={};function n(){Object.keys(r).forEach(function(e){var n=r[e];o("."+n.className).not(".crosstalk-input-bound").each(function(e,t){i(n,t)})})}function i(e,t){var n=o(t).find("script[type='application/json'][data-for='"+t.id.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g,"\\$1")+"']"),r=JSON.parse(n[0].innerText),i=e.factory(t,r);o(t).data("crosstalk-instance",i),o(t).addClass("crosstalk-input-bound")}if(t.Shiny){var e=new t.Shiny.InputBinding,u=t.jQuery;u.extend(e,{find:function(e){return u(e).find(".crosstalk-input")},initialize:function(e){var t,n;u(e).hasClass("crosstalk-input-bound")||(n=o(t=e),Object.keys(r).forEach(function(e){n.hasClass(e)&&!n.hasClass("crosstalk-input-bound")&&i(r[e],t)}))},getId:function(e){return e.id},getValue:function(e){},setValue:function(e,t){},receiveMessage:function(e,t){},subscribe:function(e,t){u(e).data("crosstalk-instance").resume()},unsubscribe:function(e){u(e).data("crosstalk-instance").suspend()}}),t.Shiny.inputBindings.register(e,"crosstalk.inputBinding")}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],7:[function(r,e,t){(function(e){"use strict";var t=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(r("./input")),n=r("./filter");var a=e.jQuery;t.register({className:"crosstalk-input-checkboxgroup",factory:function(e,r){var i=new n.FilterHandle(r.group),o=void 0,u=a(e);return u.on("change","input[type='checkbox']",function(){var e=u.find("input[type='checkbox']:checked");if(0===e.length)o=null,i.clear();else{var t={};e.each(function(){r.map[this.value].forEach(function(e){t[e]=!0})});var n=Object.keys(t);n.sort(),o=n,i.set(n)}}),{suspend:function(){i.clear()},resume:function(){o&&i.set(o)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6}],8:[function(r,e,t){(function(e){"use strict";var t=n(r("./input")),l=n(r("./util")),s=r("./filter");function n(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}var f=e.jQuery;t.register({className:"crosstalk-input-select",factory:function(e,n){var t=l.dataframeToD3(n.items),r={options:[{value:"",label:"(All)"}].concat(t),valueField:"value",labelField:"label",searchField:"label"},i=f(e).find("select")[0],o=f(i).selectize(r)[0].selectize,u=new s.FilterHandle(n.group),a=void 0;return o.on("change",function(){if(0===o.items.length)a=null,u.clear();else{var t={};o.items.forEach(function(e){n.map[e].forEach(function(e){t[e]=!0})});var e=Object.keys(t);e.sort(),a=e,u.set(e)}}),{suspend:function(){u.clear()},resume:function(){a&&u.set(a)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6,"./util":11}],9:[function(n,e,t){(function(e){"use strict";var d=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,i=!1,o=void 0;try{for(var u,a=e[Symbol.iterator]();!(r=(u=a.next()).done)&&(n.push(u.value),!t||n.length!==t);r=!0);}catch(e){i=!0,o=e}finally{try{!r&&a.return&&a.return()}finally{if(i)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},t=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(n("./input")),a=n("./filter");var v=e.jQuery,p=e.strftime;function y(e,t){for(var n=e.toString();n.length<t;)n="0"+n;return n}t.register({className:"crosstalk-input-slider",factory:function(e,l){var s=new a.FilterHandle(l.group),t={},f=v(e).find("input"),n=f.data("data-type"),r=f.data("time-format"),i=f.data("round"),o=void 0;if("date"===n)o=p.utc(),t.prettify=function(e){return o(r,new Date(e))};else if("datetime"===n){var u=f.data("timezone");o=u?p.timezone(u):p,t.prettify=function(e){return o(r,new Date(e))}}else"number"===n&&void 0!==i&&(t.prettify=function(e){var t=Math.pow(10,i);return Math.round(e*t)/t});function c(){var e=f.data("ionRangeSlider").result,t=void 0,n=f.data("data-type");return t="date"===n?function(e){return(t=new Date(+e))instanceof Date?t.getUTCFullYear()+"-"+y(t.getUTCMonth()+1,2)+"-"+y(t.getUTCDate(),2):null;var t}:"datetime"===n?function(e){return+e/1e3}:function(e){return+e},"double"===f.data("ionRangeSlider").options.type?[t(e.from),t(e.to)]:t(e.from)}f.ionRangeSlider(t);var h=null;return f.on("change.crosstalkSliderInput",function(e){if(!f.data("updating")&&!f.data("animating")){for(var t=c(),n=d(t,2),r=n[0],i=n[1],o=[],u=0;u<l.values.length;u++){var a=l.values[u];r<=a&&a<=i&&o.push(l.keys[u])}o.sort(),s.set(o),h=o}}),{suspend:function(){s.clear()},resume:function(){h&&s.set(h)}}}})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./filter":2,"./input":6}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.SelectionHandle=void 0;var r=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}(),i=a(e("./events")),o=a(e("./group")),u=function(e){{if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}}(e("./util"));function a(e){return e&&e.__esModule?e:{default:e}}n.SelectionHandle=function(){function n(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null,t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),this._eventRelay=new i.default,this._emitter=new u.SubscriptionTracker(this._eventRelay),this._group=null,this._var=null,this._varOnChangeSub=null,this._extraInfo=u.extend({sender:this},t),this.setGroup(e)}return r(n,[{key:"setGroup",value:function(e){var t=this;if(this._group!==e&&(this._group||e)&&(this._var&&(this._var.off("change",this._varOnChangeSub),this._var=null,this._varOnChangeSub=null),this._group=e)){this._var=(0,o.default)(e).var("selection");var n=this._var.on("change",function(e){t._eventRelay.trigger("change",e,t)});this._varOnChangeSub=n}}},{key:"_mergeExtraInfo",value:function(e){return u.extend({},this._extraInfo?this._extraInfo:null,e||null)}},{key:"set",value:function(e,t){this._var&&this._var.set(e,this._mergeExtraInfo(t))}},{key:"clear",value:function(e){this._var&&this.set(void 0,this._mergeExtraInfo(e))}},{key:"on",value:function(e,t){return this._emitter.on(e,t)}},{key:"off",value:function(e,t){return this._emitter.off(e,t)}},{key:"close",value:function(){this._emitter.removeAllListeners(),this.setGroup(null)}},{key:"value",get:function(){return this._var?this._var.get():null}}]),n}()},{"./events":1,"./group":4,"./util":11}],11:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}(),l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function u(e){for(var t=1;t<e.length;t++)if(e[t]<=e[t-1])throw new Error("List is not sorted or contains duplicate")}n.extend=function(e){for(var t=arguments.length,n=Array(1<t?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];for(var i=0;i<n.length;i++){var o=n[i];if(null!=o)for(var u in o)o.hasOwnProperty(u)&&(e[u]=o[u])}return e},n.checkSorted=u,n.diffSortedLists=function(e,t){var n=0,r=0;e||(e=[]);t||(t=[]);var i=[],o=[];u(e),u(t);for(;n<e.length&&r<t.length;)e[n]===t[r]?(n++,r++):e[n]<t[r]?i.push(e[n++]):o.push(t[r++]);n<e.length&&(i=i.concat(e.slice(n)));r<t.length&&(o=o.concat(t.slice(r)));return{removed:i,added:o}},n.dataframeToD3=function(e){var t=[],n=void 0;for(var r in e){if(e.hasOwnProperty(r)&&t.push(r),"object"!==l(e[r])||void 0===e[r].length)throw new Error("All fields must be arrays");if(void 0!==n&&n!==e[r].length)throw new Error("All fields must be arrays of the same length");n=e[r].length}for(var i=[],o=void 0,u=0;u<n;u++){o={};for(var a=0;a<t.length;a++)o[t[a]]=e[t[a]][u];i.push(o)}return i};n.SubscriptionTracker=function(){function t(e){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this._emitter=e,this._subs={}}return r(t,[{key:"on",value:function(e,t){var n=this._emitter.on(e,t);return this._subs[n]=e,n}},{key:"off",value:function(e,t){var n=this._emitter.off(e,t);return n&&delete this._subs[n],n}},{key:"removeAllListeners",value:function(){var t=this,n=this._subs;this._subs={},Object.keys(n).forEach(function(e){t._emitter.off(n[e],e)})}}]),t}()},{}],12:[function(a,e,l){(function(o){"use strict";Object.defineProperty(l,"__esModule",{value:!0});var e,u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(){function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}}(),n=a("./events"),i=(e=n)&&e.__esModule?e:{default:e};var r=function(){function r(e,t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,r),this._group=e,this._name=t,this._value=n,this._events=new i.default}return t(r,[{key:"get",value:function(){return this._value}},{key:"set",value:function(e,t){if(this._value!==e){var n=this._value;this._value=e;var r={};if(t&&"object"===(void 0===t?"undefined":u(t)))for(var i in t)t.hasOwnProperty(i)&&(r[i]=t[i]);r.oldValue=n,r.value=e,this._events.trigger("change",r,this),o.Shiny&&o.Shiny.onInputChange&&o.Shiny.onInputChange(".clientValue-"+(null!==this._group.name?this._group.name+"-":"")+this._name,void 0===e?null:e)}}},{key:"on",value:function(e,t){return this._events.on(e,t)}},{key:"off",value:function(e,t){return this._events.off(e,t)}}]),r}();l.default=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./events":1}]},{},[5]); +//# sourceMappingURL=crosstalk.min.js.map
\ No newline at end of file diff --git a/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.min.js.map b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.min.js.map new file mode 100644 index 0000000..886ebee --- /dev/null +++ b/docs/coverage/lib/crosstalk-1.2.2/js/crosstalk.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","javascript/src/events.js","javascript/src/filter.js","javascript/src/filterset.js","javascript/src/group.js","javascript/src/index.js","javascript/src/input.js","javascript/src/input_checkboxgroup.js","javascript/src/input_selectize.js","javascript/src/input_slider.js","javascript/src/selection.js","javascript/src/util.js","javascript/src/var.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","Events","_classCallCheck","this","_types","_seq","eventType","listener","subs","sub","key","hasOwnProperty","arg","thisObj","util","id","FilterHandle","group","extraInfo","_eventRelay","_events2","default","_emitter","SubscriptionTracker","_group","_filterSet","_filterVar","_varOnChangeSub","_extraInfo","extend","sender","_id","setGroup","fsVar","result","_this","off","clear","_group2","var","get","_filterset2","set","on","trigger","removeAllListeners","_onChange","keys","update","value","_mergeExtraInfo","_util","naturalComparator","b","FilterSet","reset","_handles","_keys","_value","_activeHandles","handleId","slice","sort","_diffSortedLists","diffSortedLists","added","removed","_i","_updateValue","arguments","undefined","_allKeys","handleCount","Object","push","allKeys","groupName","groups","Group","_typeof","_vars","Array","isArray","_var2","global","__crosstalk_groups","name","_var3","_selection","_filter","_input","defaultGroup","var_","Shiny","addCustomMessageHandler","message","crosstalk","has","SelectionHandle","bind","register","reg","bindings","className","document","readyState","$","setTimeout","jQuery","forEach","binding","not","each","el","bindInstance","jsonEl","find","replace","data","JSON","parse","innerText","instance","factory","addClass","inputBinding","InputBinding","_$","scope","initialize","$el","hasClass","getId","getValue","setValue","receiveMessage","subscribe","callback","resume","unsubscribe","suspend","inputBindings","input","ctHandle","lastKnownKeys","checked","map","keyArray","items","dataframeToD3","opts","options","label","concat","valueField","labelField","searchField","select","selectize","strftime","padZeros","digits","str","toString","dataType","timeFormat","round","timeFormatter","utc","prettify","num","Date","timezone","factor","Math","pow","convert","val","date","getUTCFullYear","getUTCMonth","getUTCDate","type","from","to","ionRangeSlider","event","_getValue","_getValue2","_slicedToArray","values","_var","selectedKeys","checkSorted","list","target","_len","sources","_key","src","i_a","i_b","a_only","b_only","df","names","results","item","row","col","emitter","_subs","current_subs","_events","Var","_name","oldValue","evt","k","onInputChange"],"mappings":"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","file":"crosstalk.min.js","sourcesContent":["(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()","export default class Events {\n constructor() {\n this._types = {};\n this._seq = 0;\n }\n\n on(eventType, listener) {\n let subs = this._types[eventType];\n if (!subs) {\n subs = this._types[eventType] = {};\n }\n let sub = \"sub\" + (this._seq++);\n subs[sub] = listener;\n return sub;\n }\n\n // Returns false if no match, or string for sub name if matched\n off(eventType, listener) {\n let subs = this._types[eventType];\n if (typeof(listener) === \"function\") {\n for (let key in subs) {\n if (subs.hasOwnProperty(key)) {\n if (subs[key] === listener) {\n delete subs[key];\n return key;\n }\n }\n }\n return false;\n } else if (typeof(listener) === \"string\") {\n if (subs && subs[listener]) {\n delete subs[listener];\n return listener;\n }\n return false;\n } else {\n throw new Error(\"Unexpected type for listener\");\n }\n }\n\n trigger(eventType, arg, thisObj) {\n let subs = this._types[eventType];\n for (let key in subs) {\n if (subs.hasOwnProperty(key)) {\n subs[key].call(thisObj, arg);\n }\n }\n }\n}\n","import Events from \"./events\";\nimport FilterSet from \"./filterset\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\nfunction getFilterSet(group) {\n let fsVar = group.var(\"filterset\");\n let result = fsVar.get();\n if (!result) {\n result = new FilterSet();\n fsVar.set(result);\n }\n return result;\n}\n\nlet id = 1;\nfunction nextId() {\n return id++;\n}\n\n/**\n * Use this class to contribute to, and listen for changes to, the filter set\n * for the given group of widgets. Filter input controls should create one\n * `FilterHandle` and only call {@link FilterHandle#set}. Output widgets that\n * wish to displayed filtered data should create one `FilterHandle` and use\n * the {@link FilterHandle#filteredKeys} property and listen for change\n * events.\n *\n * If two (or more) `FilterHandle` instances in the same webpage share the\n * same group name, they will contribute to a single \"filter set\". Each\n * `FilterHandle` starts out with a `null` value, which means they take\n * nothing away from the set of data that should be shown. To make a\n * `FilterHandle` actually remove data from the filter set, set its value to\n * an array of keys which should be displayed. Crosstalk will aggregate the\n * various key arrays by finding their intersection; only keys that are\n * present in all non-null filter handles are considered part of the filter\n * set.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the {@link FilterHandle#setGroup} method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class FilterHandle {\n constructor(group, extraInfo) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The filterSet that we're tracking, if any. Can change over time.\n this._filterSet = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._filterVar = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this._id = \"filter\" + nextId();\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this FilterHandle. If `set()` was\n * previously called on this handle, switching groups will clear those keys\n * from the old group's filter set. These keys will not be applied to the new\n * group's filter set either. In other words, `setGroup()` effectively calls\n * `clear()` before switching groups.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._filterVar) {\n this._filterVar.off(\"change\", this._varOnChangeSub);\n this.clear();\n this._varOnChangeSub = null;\n this._filterVar = null;\n this._filterSet = null;\n }\n\n this._group = group;\n\n if (group) {\n group = grp(group);\n this._filterSet = getFilterSet(group);\n this._filterVar = grp(group).var(\"filter\");\n let sub = this._filterVar.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Combine the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Close the handle. This clears this handle's contribution to the filter set,\n * and unsubscribes all event listeners.\n */\n close() {\n this._emitter.removeAllListeners();\n this.clear();\n this.setGroup(null);\n }\n\n /**\n * Clear this handle's contribution to the filter set.\n *\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n clear(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.clear(this._id);\n this._onChange(extraInfo);\n }\n\n /**\n * Set this handle's contribution to the filter set. This array should consist\n * of the keys of the rows that _should_ be displayed; any keys that are not\n * present in the array will be considered _filtered out_. Note that multiple\n * `FilterHandle` instances in the group may each contribute an array of keys,\n * and only those keys that appear in _all_ of the arrays make it through the\n * filter.\n *\n * @param {string[]} keys - Empty array, or array of keys. To clear the\n * filter, don't pass an empty array; instead, use the\n * {@link FilterHandle#clear} method.\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `FilterHandle` constructor).\n * \n * @fires FilterHandle#change\n */\n set(keys, extraInfo) {\n if (!this._filterSet)\n return;\n this._filterSet.update(this._id, keys);\n this._onChange(extraInfo);\n }\n\n /**\n * @return {string[]|null} - Either: 1) an array of keys that made it through\n * all of the `FilterHandle` instances, or, 2) `null`, which means no filter\n * is being applied (all data should be displayed).\n */\n get filteredKeys() {\n return this._filterSet ? this._filterSet.value : null;\n }\n\n /**\n * Subscribe to events on this `FilterHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {FilterHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link FilterHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancel event subscriptions created by {@link FilterHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|FilterHandle~listener} listener - Either the callback\n * function previously passed into {@link FilterHandle#on}, or the\n * string that was returned from {@link FilterHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n _onChange(extraInfo) {\n if (!this._filterSet)\n return;\n this._filterVar.set(this._filterSet.value, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * @callback FilterHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the filter set, or `null` if no filter set is active),\n * `oldValue` (the previous value of the filter set), and `sender` (the\n * `FilterHandle` instance that made the change).\n */\n\n}\n\n/**\n * @event FilterHandle#change\n * @type {object}\n * @property {object} value - The new value of the filter set, or `null`\n * if no filter set is active.\n * @property {object} oldValue - The previous value of the filter set.\n * @property {FilterHandle} sender - The `FilterHandle` instance that\n * changed the value.\n */\n","import { diffSortedLists } from \"./util\";\n\nfunction naturalComparator(a, b) {\n if (a === b) {\n return 0;\n } else if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n}\n\n/**\n * @private\n */\nexport default class FilterSet {\n constructor() {\n this.reset();\n }\n\n reset() {\n // Key: handle ID, Value: array of selected keys, or null\n this._handles = {};\n // Key: key string, Value: count of handles that include it\n this._keys = {};\n this._value = null;\n this._activeHandles = 0;\n }\n\n get value() {\n return this._value;\n }\n\n update(handleId, keys) {\n if (keys !== null) {\n keys = keys.slice(0); // clone before sorting\n keys.sort(naturalComparator);\n }\n\n let {added, removed} = diffSortedLists(this._handles[handleId], keys);\n this._handles[handleId] = keys;\n\n for (let i = 0; i < added.length; i++) {\n this._keys[added[i]] = (this._keys[added[i]] || 0) + 1;\n }\n for (let i = 0; i < removed.length; i++) {\n this._keys[removed[i]]--;\n }\n\n this._updateValue(keys);\n }\n\n /**\n * @param {string[]} keys Sorted array of strings that indicate\n * a superset of possible keys.\n * @private\n */\n _updateValue(keys = this._allKeys) {\n let handleCount = Object.keys(this._handles).length;\n if (handleCount === 0) {\n this._value = null;\n } else {\n this._value = [];\n for (let i = 0; i < keys.length; i++) {\n let count = this._keys[keys[i]];\n if (count === handleCount) {\n this._value.push(keys[i]);\n }\n }\n }\n }\n\n clear(handleId) {\n if (typeof(this._handles[handleId]) === \"undefined\") {\n return;\n }\n\n let keys = this._handles[handleId];\n if (!keys) {\n keys = [];\n }\n\n for (let i = 0; i < keys.length; i++) {\n this._keys[keys[i]]--;\n }\n delete this._handles[handleId];\n\n this._updateValue();\n }\n\n get _allKeys() {\n let allKeys = Object.keys(this._keys);\n allKeys.sort(naturalComparator);\n return allKeys;\n }\n}\n","import Var from \"./var\";\n\n// Use a global so that multiple copies of crosstalk.js can be loaded and still\n// have groups behave as singletons across all copies.\nglobal.__crosstalk_groups = global.__crosstalk_groups || {};\nlet groups = global.__crosstalk_groups;\n\nexport default function group(groupName) {\n if (groupName && typeof(groupName) === \"string\") {\n if (!groups.hasOwnProperty(groupName)) {\n groups[groupName] = new Group(groupName);\n }\n return groups[groupName];\n } else if (typeof(groupName) === \"object\" && groupName._vars && groupName.var) {\n // Appears to already be a group object\n return groupName;\n } else if (Array.isArray(groupName) &&\n groupName.length == 1 &&\n typeof(groupName[0]) === \"string\") {\n return group(groupName[0]);\n } else {\n throw new Error(\"Invalid groupName argument\");\n }\n}\n\nclass Group {\n constructor(name) {\n this.name = name;\n this._vars = {};\n }\n\n var(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n if (!this._vars.hasOwnProperty(name))\n this._vars[name] = new Var(this, name);\n return this._vars[name];\n }\n\n has(name) {\n if (!name || typeof(name) !== \"string\") {\n throw new Error(\"Invalid var name\");\n }\n\n return this._vars.hasOwnProperty(name);\n }\n}\n","import group from \"./group\";\nimport { SelectionHandle } from \"./selection\";\nimport { FilterHandle } from \"./filter\";\nimport { bind } from \"./input\";\nimport \"./input_selectize\";\nimport \"./input_checkboxgroup\";\nimport \"./input_slider\";\n\nconst defaultGroup = group(\"default\");\n\nfunction var_(name) {\n return defaultGroup.var(name);\n}\n\nfunction has(name) {\n return defaultGroup.has(name);\n}\n\nif (global.Shiny) {\n global.Shiny.addCustomMessageHandler(\"update-client-value\", function(message) {\n if (typeof(message.group) === \"string\") {\n group(message.group).var(message.name).set(message.value);\n } else {\n var_(message.name).set(message.value);\n }\n });\n}\n\nconst crosstalk = {\n group: group,\n var: var_,\n has: has,\n SelectionHandle: SelectionHandle,\n FilterHandle: FilterHandle,\n bind: bind\n};\n\n/**\n * @namespace crosstalk\n */\nexport default crosstalk;\nglobal.crosstalk = crosstalk;\n","let $ = global.jQuery;\n\nlet bindings = {};\n\nexport function register(reg) {\n bindings[reg.className] = reg;\n if (global.document && global.document.readyState !== \"complete\") {\n $(() => {\n bind();\n });\n } else if (global.document) {\n setTimeout(bind, 100);\n }\n}\n\nexport function bind() {\n Object.keys(bindings).forEach(function(className) {\n let binding = bindings[className];\n $(\".\" + binding.className).not(\".crosstalk-input-bound\").each(function(i, el) {\n bindInstance(binding, el);\n });\n });\n}\n\n// Escape jQuery identifier\nfunction $escape(val) {\n return val.replace(/([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n}\n\nfunction bindEl(el) {\n let $el = $(el);\n Object.keys(bindings).forEach(function(className) {\n if ($el.hasClass(className) && !$el.hasClass(\"crosstalk-input-bound\")) {\n let binding = bindings[className];\n bindInstance(binding, el);\n }\n });\n}\n\nfunction bindInstance(binding, el) {\n let jsonEl = $(el).find(\"script[type='application/json'][data-for='\" + $escape(el.id) + \"']\");\n let data = JSON.parse(jsonEl[0].innerText);\n\n let instance = binding.factory(el, data);\n $(el).data(\"crosstalk-instance\", instance);\n $(el).addClass(\"crosstalk-input-bound\");\n}\n\nif (global.Shiny) {\n let inputBinding = new global.Shiny.InputBinding();\n let $ = global.jQuery;\n $.extend(inputBinding, {\n find: function(scope) {\n return $(scope).find(\".crosstalk-input\");\n },\n initialize: function(el) {\n if (!$(el).hasClass(\"crosstalk-input-bound\")) {\n bindEl(el);\n }\n },\n getId: function(el) {\n return el.id;\n },\n getValue: function(el) {\n\n },\n setValue: function(el, value) {\n\n },\n receiveMessage: function(el, data) {\n\n },\n subscribe: function(el, callback) {\n $(el).data(\"crosstalk-instance\").resume();\n },\n unsubscribe: function(el) {\n $(el).data(\"crosstalk-instance\").suspend();\n }\n });\n global.Shiny.inputBindings.register(inputBinding, \"crosstalk.inputBinding\");\n}\n","import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-checkboxgroup\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n let $el = $(el);\n $el.on(\"change\", \"input[type='checkbox']\", function() {\n let checked = $el.find(\"input[type='checkbox']:checked\");\n if (checked.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n checked.each(function() {\n data.map[this.value].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n","import * as input from \"./input\";\nimport * as util from \"./util\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\n\ninput.register({\n className: \"crosstalk-input-select\",\n\n factory: function(el, data) {\n /*\n * items: {value: [...], label: [...]}\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n\n let first = [{value: \"\", label: \"(All)\"}];\n let items = util.dataframeToD3(data.items);\n let opts = {\n options: first.concat(items),\n valueField: \"value\",\n labelField: \"label\",\n searchField: \"label\"\n };\n\n let select = $(el).find(\"select\")[0];\n\n let selectize = $(select).selectize(opts)[0].selectize;\n\n let ctHandle = new FilterHandle(data.group);\n\n let lastKnownKeys;\n selectize.on(\"change\", function() {\n if (selectize.items.length === 0) {\n lastKnownKeys = null;\n ctHandle.clear();\n } else {\n let keys = {};\n selectize.items.forEach(function(group) {\n data.map[group].forEach(function(key) {\n keys[key] = true;\n });\n });\n let keyArray = Object.keys(keys);\n keyArray.sort();\n lastKnownKeys = keyArray;\n ctHandle.set(keyArray);\n }\n });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n","import * as input from \"./input\";\nimport { FilterHandle } from \"./filter\";\n\nlet $ = global.jQuery;\nlet strftime = global.strftime;\n\ninput.register({\n className: \"crosstalk-input-slider\",\n\n factory: function(el, data) {\n /*\n * map: {\"groupA\": [\"keyA\", \"keyB\", ...], ...}\n * group: \"ct-groupname\"\n */\n let ctHandle = new FilterHandle(data.group);\n\n let opts = {};\n let $el = $(el).find(\"input\");\n let dataType = $el.data(\"data-type\");\n let timeFormat = $el.data(\"time-format\");\n let round = $el.data(\"round\");\n let timeFormatter;\n\n // Set up formatting functions\n if (dataType === \"date\") {\n timeFormatter = strftime.utc();\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n\n } else if (dataType === \"datetime\") {\n let timezone = $el.data(\"timezone\");\n if (timezone)\n timeFormatter = strftime.timezone(timezone);\n else\n timeFormatter = strftime;\n\n opts.prettify = function(num) {\n return timeFormatter(timeFormat, new Date(num));\n };\n } else if (dataType === \"number\") {\n if (typeof round !== \"undefined\")\n opts.prettify = function(num) {\n let factor = Math.pow(10, round);\n return Math.round(num * factor) / factor;\n };\n }\n\n $el.ionRangeSlider(opts);\n\n function getValue() {\n let result = $el.data(\"ionRangeSlider\").result;\n\n // Function for converting numeric value from slider to appropriate type.\n let convert;\n let dataType = $el.data(\"data-type\");\n if (dataType === \"date\") {\n convert = function(val) {\n return formatDateUTC(new Date(+val));\n };\n } else if (dataType === \"datetime\") {\n convert = function(val) {\n // Convert ms to s\n return +val / 1000;\n };\n } else {\n convert = function(val) { return +val; };\n }\n\n if ($el.data(\"ionRangeSlider\").options.type === \"double\") {\n return [convert(result.from), convert(result.to)];\n } else {\n return convert(result.from);\n }\n }\n\n let lastKnownKeys = null;\n\n $el.on(\"change.crosstalkSliderInput\", function(event) {\n if (!$el.data(\"updating\") && !$el.data(\"animating\")) {\n let [from, to] = getValue();\n let keys = [];\n for (let i = 0; i < data.values.length; i++) {\n let val = data.values[i];\n if (val >= from && val <= to) {\n keys.push(data.keys[i]);\n }\n }\n keys.sort();\n ctHandle.set(keys);\n lastKnownKeys = keys;\n }\n });\n\n\n // let $el = $(el);\n // $el.on(\"change\", \"input[type=\"checkbox\"]\", function() {\n // let checked = $el.find(\"input[type=\"checkbox\"]:checked\");\n // if (checked.length === 0) {\n // ctHandle.clear();\n // } else {\n // let keys = {};\n // checked.each(function() {\n // data.map[this.value].forEach(function(key) {\n // keys[key] = true;\n // });\n // });\n // let keyArray = Object.keys(keys);\n // keyArray.sort();\n // ctHandle.set(keyArray);\n // }\n // });\n\n return {\n suspend: function() {\n ctHandle.clear();\n },\n resume: function() {\n if (lastKnownKeys)\n ctHandle.set(lastKnownKeys);\n }\n };\n }\n});\n\n\n// Convert a number to a string with leading zeros\nfunction padZeros(n, digits) {\n let str = n.toString();\n while (str.length < digits)\n str = \"0\" + str;\n return str;\n}\n\n// Given a Date object, return a string in yyyy-mm-dd format, using the\n// UTC date. This may be a day off from the date in the local time zone.\nfunction formatDateUTC(date) {\n if (date instanceof Date) {\n return date.getUTCFullYear() + \"-\" +\n padZeros(date.getUTCMonth()+1, 2) + \"-\" +\n padZeros(date.getUTCDate(), 2);\n\n } else {\n return null;\n }\n}\n","import Events from \"./events\";\nimport grp from \"./group\";\nimport * as util from \"./util\";\n\n/**\n * Use this class to read and write (and listen for changes to) the selection\n * for a Crosstalk group. This is intended to be used for linked brushing.\n *\n * If two (or more) `SelectionHandle` instances in the same webpage share the\n * same group name, they will share the same state. Setting the selection using\n * one `SelectionHandle` instance will result in the `value` property instantly\n * changing across the others, and `\"change\"` event listeners on all instances\n * (including the one that initiated the sending) will fire.\n *\n * @param {string} [group] - The name of the Crosstalk group, or if none,\n * null or undefined (or any other falsy value). This can be changed later\n * via the [SelectionHandle#setGroup](#setGroup) method.\n * @param {Object} [extraInfo] - An object whose properties will be copied to\n * the event object whenever an event is emitted.\n */\nexport class SelectionHandle {\n\n constructor(group = null, extraInfo = null) {\n this._eventRelay = new Events();\n this._emitter = new util.SubscriptionTracker(this._eventRelay);\n\n // Name of the group we're currently tracking, if any. Can change over time.\n this._group = null;\n // The Var we're currently tracking, if any. Can change over time.\n this._var = null;\n // The event handler subscription we currently have on var.on(\"change\").\n this._varOnChangeSub = null;\n\n this._extraInfo = util.extend({ sender: this }, extraInfo);\n\n this.setGroup(group);\n }\n\n /**\n * Changes the Crosstalk group membership of this SelectionHandle. The group\n * being switched away from (if any) will not have its selection value\n * modified as a result of calling `setGroup`, even if this handle was the\n * most recent handle to set the selection of the group.\n *\n * The group being switched to (if any) will also not have its selection value\n * modified as a result of calling `setGroup`. If you want to set the\n * selection value of the new group, call `set` explicitly.\n *\n * @param {string} group - The name of the Crosstalk group, or null (or\n * undefined) to clear the group.\n */\n setGroup(group) {\n // If group is unchanged, do nothing\n if (this._group === group)\n return;\n // Treat null, undefined, and other falsy values the same\n if (!this._group && !group)\n return;\n\n if (this._var) {\n this._var.off(\"change\", this._varOnChangeSub);\n this._var = null;\n this._varOnChangeSub = null;\n }\n\n this._group = group;\n\n if (group) {\n this._var = grp(group).var(\"selection\");\n let sub = this._var.on(\"change\", (e) => {\n this._eventRelay.trigger(\"change\", e, this);\n });\n this._varOnChangeSub = sub;\n }\n }\n\n /**\n * Retrieves the current selection for the group represented by this\n * `SelectionHandle`.\n *\n * - If no selection is active, then this value will be falsy.\n * - If a selection is active, but no data points are selected, then this\n * value will be an empty array.\n * - If a selection is active, and data points are selected, then the keys\n * of the selected data points will be present in the array.\n */\n get value() {\n return this._var ? this._var.get() : null;\n }\n\n /**\n * Combines the given `extraInfo` (if any) with the handle's default\n * `_extraInfo` (if any).\n * @private\n */\n _mergeExtraInfo(extraInfo) {\n // Important incidental effect: shallow clone is returned\n return util.extend({},\n this._extraInfo ? this._extraInfo : null,\n extraInfo ? extraInfo : null);\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {string[]} selectedKeys - Falsy, empty array, or array of keys (see\n * {@link SelectionHandle#value}).\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any options that were\n * passed into the `SelectionHandle` constructor).\n */\n set(selectedKeys, extraInfo) {\n if (this._var)\n this._var.set(selectedKeys, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Overwrites the current selection for the group, and raises the `\"change\"`\n * event among all of the group's '`SelectionHandle` instances (including\n * this one).\n *\n * @fires SelectionHandle#change\n * @param {Object} [extraInfo] - Extra properties to be included on the event\n * object that's passed to listeners (in addition to any that were passed\n * into the `SelectionHandle` constructor).\n */\n clear(extraInfo) {\n if (this._var)\n this.set(void 0, this._mergeExtraInfo(extraInfo));\n }\n\n /**\n * Subscribes to events on this `SelectionHandle`.\n *\n * @param {string} eventType - Indicates the type of events to listen to.\n * Currently, only `\"change\"` is supported.\n * @param {SelectionHandle~listener} listener - The callback function that\n * will be invoked when the event occurs.\n * @return {string} - A token to pass to {@link SelectionHandle#off} to cancel\n * this subscription.\n */\n on(eventType, listener) {\n return this._emitter.on(eventType, listener);\n }\n\n /**\n * Cancels event subscriptions created by {@link SelectionHandle#on}.\n *\n * @param {string} eventType - The type of event to unsubscribe.\n * @param {string|SelectionHandle~listener} listener - Either the callback\n * function previously passed into {@link SelectionHandle#on}, or the\n * string that was returned from {@link SelectionHandle#on}.\n */\n off(eventType, listener) {\n return this._emitter.off(eventType, listener);\n }\n\n /**\n * Shuts down the `SelectionHandle` object.\n *\n * Removes all event listeners that were added through this handle.\n */\n close() {\n this._emitter.removeAllListeners();\n this.setGroup(null);\n }\n}\n\n/**\n * @callback SelectionHandle~listener\n * @param {Object} event - An object containing details of the event. For\n * `\"change\"` events, this includes the properties `value` (the new\n * value of the selection, or `undefined` if no selection is active),\n * `oldValue` (the previous value of the selection), and `sender` (the\n * `SelectionHandle` instance that made the change).\n */\n\n/**\n * @event SelectionHandle#change\n * @type {object}\n * @property {object} value - The new value of the selection, or `undefined`\n * if no selection is active.\n * @property {object} oldValue - The previous value of the selection.\n * @property {SelectionHandle} sender - The `SelectionHandle` instance that\n * changed the value.\n */\n","export function extend(target, ...sources) {\n for (let i = 0; i < sources.length; i++) {\n let src = sources[i];\n if (typeof(src) === \"undefined\" || src === null)\n continue;\n\n for (let key in src) {\n if (src.hasOwnProperty(key)) {\n target[key] = src[key];\n }\n }\n }\n return target;\n}\n\nexport function checkSorted(list) {\n for (let i = 1; i < list.length; i++) {\n if (list[i] <= list[i-1]) {\n throw new Error(\"List is not sorted or contains duplicate\");\n }\n }\n}\n\nexport function diffSortedLists(a, b) {\n let i_a = 0;\n let i_b = 0;\n\n if (!a) a = [];\n if (!b) b = [];\n\n let a_only = [];\n let b_only = [];\n\n checkSorted(a);\n checkSorted(b);\n\n while (i_a < a.length && i_b < b.length) {\n if (a[i_a] === b[i_b]) {\n i_a++;\n i_b++;\n } else if (a[i_a] < b[i_b]) {\n a_only.push(a[i_a++]);\n } else {\n b_only.push(b[i_b++]);\n }\n }\n\n if (i_a < a.length)\n a_only = a_only.concat(a.slice(i_a));\n if (i_b < b.length)\n b_only = b_only.concat(b.slice(i_b));\n return {\n removed: a_only,\n added: b_only\n };\n}\n\n// Convert from wide: { colA: [1,2,3], colB: [4,5,6], ... }\n// to long: [ {colA: 1, colB: 4}, {colA: 2, colB: 5}, ... ]\nexport function dataframeToD3(df) {\n let names = [];\n let length;\n for (let name in df) {\n if (df.hasOwnProperty(name))\n names.push(name);\n if (typeof(df[name]) !== \"object\" || typeof(df[name].length) === \"undefined\") {\n throw new Error(\"All fields must be arrays\");\n } else if (typeof(length) !== \"undefined\" && length !== df[name].length) {\n throw new Error(\"All fields must be arrays of the same length\");\n }\n length = df[name].length;\n }\n let results = [];\n let item;\n for (let row = 0; row < length; row++) {\n item = {};\n for (let col = 0; col < names.length; col++) {\n item[names[col]] = df[names[col]][row];\n }\n results.push(item);\n }\n return results;\n}\n\n/**\n * Keeps track of all event listener additions/removals and lets all active\n * listeners be removed with a single operation.\n *\n * @private\n */\nexport class SubscriptionTracker {\n constructor(emitter) {\n this._emitter = emitter;\n this._subs = {};\n }\n\n on(eventType, listener) {\n let sub = this._emitter.on(eventType, listener);\n this._subs[sub] = eventType;\n return sub;\n }\n\n off(eventType, listener) {\n let sub = this._emitter.off(eventType, listener);\n if (sub) {\n delete this._subs[sub];\n }\n return sub;\n }\n\n removeAllListeners() {\n let current_subs = this._subs;\n this._subs = {};\n Object.keys(current_subs).forEach((sub) => {\n this._emitter.off(current_subs[sub], sub);\n });\n }\n}\n","import Events from \"./events\";\n\nexport default class Var {\n constructor(group, name, /*optional*/ value) {\n this._group = group;\n this._name = name;\n this._value = value;\n this._events = new Events();\n }\n\n get() {\n return this._value;\n }\n\n set(value, /*optional*/ event) {\n if (this._value === value) {\n // Do nothing; the value hasn't changed\n return;\n }\n let oldValue = this._value;\n this._value = value;\n // Alert JavaScript listeners that the value has changed\n let evt = {};\n if (event && typeof(event) === \"object\") {\n for (let k in event) {\n if (event.hasOwnProperty(k))\n evt[k] = event[k];\n }\n }\n evt.oldValue = oldValue;\n evt.value = value;\n this._events.trigger(\"change\", evt, this);\n\n // TODO: Make this extensible, to let arbitrary back-ends know that\n // something has changed\n if (global.Shiny && global.Shiny.onInputChange) {\n global.Shiny.onInputChange(\n \".clientValue-\" +\n (this._group.name !== null ? this._group.name + \"-\" : \"\") +\n this._name,\n typeof(value) === \"undefined\" ? null : value\n );\n }\n }\n\n on(eventType, listener) {\n return this._events.on(eventType, listener);\n }\n\n off(eventType, listener) {\n return this._events.off(eventType, listener);\n }\n}\n"]}
\ No newline at end of file diff --git a/docs/coverage/lib/crosstalk-1.2.2/scss/crosstalk.scss b/docs/coverage/lib/crosstalk-1.2.2/scss/crosstalk.scss new file mode 100644 index 0000000..3566561 --- /dev/null +++ b/docs/coverage/lib/crosstalk-1.2.2/scss/crosstalk.scss @@ -0,0 +1,75 @@ +/* Adjust margins outwards, so column contents line up with the edges of the + parent of container-fluid. */ +.container-fluid.crosstalk-bscols { + margin-left: -30px; + margin-right: -30px; + white-space: normal; +} + +/* But don't adjust the margins outwards if we're directly under the body, + i.e. we were the top-level of something at the console. */ +body > .container-fluid.crosstalk-bscols { + margin-left: auto; + margin-right: auto; +} + +.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { + display: inline-block; + padding-right: 12px; + vertical-align: top; +} + +@media only screen and (max-width:480px) { + .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { + display: block; + padding-right: inherit; + } +} + +/* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ +.crosstalk-input { + margin-bottom: 15px; /* a la .form-group */ + .control-label { + margin-bottom: 0; + vertical-align: middle; + } + input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px; + line-height: normal; + } + .checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; + } + .checkbox > label{ + padding-left: 20px; + margin-bottom: 0; + font-weight: 400; + cursor: pointer; + } + .checkbox input[type="checkbox"], + .checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 2px; + margin-left: -20px; + } + .checkbox + .checkbox { + margin-top: -5px; + } + .checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: 400; + vertical-align: middle; + cursor: pointer; + } + .checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; + } +} diff --git a/docs/coverage/lib/datatables-binding-0.34.0/datatables.js b/docs/coverage/lib/datatables-binding-0.34.0/datatables.js new file mode 100644 index 0000000..136a8b9 --- /dev/null +++ b/docs/coverage/lib/datatables-binding-0.34.0/datatables.js @@ -0,0 +1,1539 @@ +(function() { + +// some helper functions: using a global object DTWidget so that it can be used +// in JS() code, e.g. datatable(options = list(foo = JS('code'))); unlike R's +// dynamic scoping, when 'code' is eval'ed, JavaScript does not know objects +// from the "parent frame", e.g. JS('DTWidget') will not work unless it was made +// a global object +var DTWidget = {}; + +// 123456666.7890 -> 123,456,666.7890 +var markInterval = function(d, digits, interval, mark, decMark, precision) { + x = precision ? d.toPrecision(digits) : d.toFixed(digits); + if (!/^-?[\d.]+$/.test(x)) return x; + var xv = x.split('.'); + if (xv.length > 2) return x; // should have at most one decimal point + xv[0] = xv[0].replace(new RegExp('\\B(?=(\\d{' + interval + '})+(?!\\d))', 'g'), mark); + return xv.join(decMark); +}; + +DTWidget.formatCurrency = function(data, currency, digits, interval, mark, decMark, before, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + var res = markInterval(d, digits, interval, mark, decMark); + res = before ? (/^-/.test(res) ? '-' + currency + res.replace(/^-/, '') : currency + res) : + res + currency; + return res; +}; + +DTWidget.formatString = function(data, prefix, suffix) { + var d = data; + if (d === null) return ''; + return prefix + d + suffix; +}; + +DTWidget.formatPercentage = function(data, digits, interval, mark, decMark, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + return markInterval(d * 100, digits, interval, mark, decMark) + '%'; +}; + +DTWidget.formatRound = function(data, digits, interval, mark, decMark, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + return markInterval(d, digits, interval, mark, decMark); +}; + +DTWidget.formatSignif = function(data, digits, interval, mark, decMark, zeroPrint) { + var d = parseFloat(data); + if (isNaN(d)) return ''; + if (zeroPrint !== null && d === 0.0) return zeroPrint; + return markInterval(d, digits, interval, mark, decMark, true); +}; + +DTWidget.formatDate = function(data, method, params) { + var d = data; + if (d === null) return ''; + // (new Date('2015-10-28')).toDateString() may return 2015-10-27 because the + // actual time created could be like 'Tue Oct 27 2015 19:00:00 GMT-0500 (CDT)', + // i.e. the date-only string is treated as UTC time instead of local time + if ((method === 'toDateString' || method === 'toLocaleDateString') && /^\d{4,}\D\d{2}\D\d{2}$/.test(d)) { + d = d.split(/\D/); + d = new Date(d[0], d[1] - 1, d[2]); + } else { + d = new Date(d); + } + return d[method].apply(d, params); +}; + +window.DTWidget = DTWidget; + +// A helper function to update the properties of existing filters +var setFilterProps = function(td, props) { + // Update enabled/disabled state + var $input = $(td).find('input').first(); + var searchable = $input.data('searchable'); + $input.prop('disabled', !searchable || props.disabled); + + // Based on the filter type, set its new values + var type = td.getAttribute('data-type'); + if (['factor', 'logical'].includes(type)) { + // Reformat the new dropdown options for use with selectize + var new_vals = props.params.options.map(function(item) { + return { text: item, value: item }; + }); + + // Find the selectize object + var dropdown = $(td).find('.selectized').eq(0)[0].selectize; + + // Note the current values + var old_vals = dropdown.getValue(); + + // Remove the existing values + dropdown.clearOptions(); + + // Add the new options + dropdown.addOption(new_vals); + + // Preserve the existing values + dropdown.setValue(old_vals); + + } else if (['number', 'integer', 'date', 'time'].includes(type)) { + // Apply internal scaling to new limits. Updating scale not yet implemented. + var slider = $(td).find('.noUi-target').eq(0); + var scale = Math.pow(10, Math.max(0, +slider.data('scale') || 0)); + var new_vals = [props.params.min * scale, props.params.max * scale]; + + // Note what the new limits will be just for this filter + var new_lims = new_vals.slice(); + + // Determine the current values and limits + var old_vals = slider.val().map(Number); + var old_lims = slider.noUiSlider('options').range; + old_lims = [old_lims.min, old_lims.max]; + + // Preserve the current values if filters have been applied; otherwise, apply no filtering + if (old_vals[0] != old_lims[0]) { + new_vals[0] = Math.max(old_vals[0], new_vals[0]); + } + + if (old_vals[1] != old_lims[1]) { + new_vals[1] = Math.min(old_vals[1], new_vals[1]); + } + + // Update the endpoints of the slider + slider.noUiSlider({ + start: new_vals, + range: {'min': new_lims[0], 'max': new_lims[1]} + }, true); + } +}; + +var transposeArray2D = function(a) { + return a.length === 0 ? a : HTMLWidgets.transposeArray2D(a); +}; + +var crosstalkPluginsInstalled = false; + +function maybeInstallCrosstalkPlugins() { + if (crosstalkPluginsInstalled) + return; + crosstalkPluginsInstalled = true; + + $.fn.dataTable.ext.afnFiltering.push( + function(oSettings, aData, iDataIndex) { + var ctfilter = oSettings.nTable.ctfilter; + if (ctfilter && !ctfilter[iDataIndex]) + return false; + + var ctselect = oSettings.nTable.ctselect; + if (ctselect && !ctselect[iDataIndex]) + return false; + + return true; + } + ); +} + +HTMLWidgets.widget({ + name: "datatables", + type: "output", + renderOnNullValue: true, + initialize: function(el, width, height) { + // in order that the type=number inputs return a number + $.valHooks.number = { + get: function(el) { + var value = parseFloat(el.value); + return isNaN(value) ? "" : value; + } + }; + $(el).html(' '); + return { + data: null, + ctfilterHandle: new crosstalk.FilterHandle(), + ctfilterSubscription: null, + ctselectHandle: new crosstalk.SelectionHandle(), + ctselectSubscription: null + }; + }, + renderValue: function(el, data, instance) { + if ((el.offsetWidth === 0 || el.offsetHeight === 0) && data.lazyRender !== false) { + instance.data = data; + return; + } + instance.data = null; + var $el = $(el); + $el.empty(); + + if (data === null) { + $el.append(' '); + // clear previous Shiny inputs (if any) + for (var i in instance.clearInputs) instance.clearInputs[i](); + instance.clearInputs = {}; + return; + } + + var crosstalkOptions = data.crosstalkOptions; + if (!crosstalkOptions) crosstalkOptions = { + 'key': null, 'group': null + }; + if (crosstalkOptions.group) { + maybeInstallCrosstalkPlugins(); + instance.ctfilterHandle.setGroup(crosstalkOptions.group); + instance.ctselectHandle.setGroup(crosstalkOptions.group); + } + + // if we are in the viewer then we always want to fillContainer and + // and autoHideNavigation (unless the user has explicitly set these) + if (window.HTMLWidgets.viewerMode) { + if (!data.hasOwnProperty("fillContainer")) + data.fillContainer = true; + if (!data.hasOwnProperty("autoHideNavigation")) + data.autoHideNavigation = true; + } + + // propagate fillContainer to instance (so we have it in resize) + instance.fillContainer = data.fillContainer; + + var cells = data.data; + + if (cells instanceof Array) cells = transposeArray2D(cells); + + $el.append(data.container); + var $table = $el.find('table'); + if (data.class) $table.addClass(data.class); + if (data.caption) $table.prepend(data.caption); + + if (!data.selection) data.selection = { + mode: 'none', selected: null, target: 'row', selectable: null + }; + if (HTMLWidgets.shinyMode && data.selection.mode !== 'none' && + data.selection.target === 'row+column') { + if ($table.children('tfoot').length === 0) { + $table.append($('<tfoot>')); + $table.find('thead tr').clone().appendTo($table.find('tfoot')); + } + } + + // column filters + var filterRow; + switch (data.filter) { + case 'top': + $table.children('thead').append(data.filterHTML); + filterRow = $table.find('thead tr:last td'); + break; + case 'bottom': + if ($table.children('tfoot').length === 0) { + $table.append($('<tfoot>')); + } + $table.children('tfoot').prepend(data.filterHTML); + filterRow = $table.find('tfoot tr:first td'); + break; + } + + var options = { searchDelay: 1000 }; + if (cells !== null) $.extend(options, { + data: cells + }); + + // options for fillContainer + var bootstrapActive = typeof($.fn.popover) != 'undefined'; + if (instance.fillContainer) { + + // force scrollX/scrollY and turn off autoWidth + options.scrollX = true; + options.scrollY = "100px"; // can be any value, we'll adjust below + + // if we aren't paginating then move around the info/filter controls + // to save space at the bottom and rephrase the info callback + if (data.options.paging === false) { + + // we know how to do this cleanly for bootstrap, not so much + // for other themes/layouts + if (bootstrapActive) { + options.dom = "<'row'<'col-sm-4'i><'col-sm-8'f>>" + + "<'row'<'col-sm-12'tr>>"; + } + + options.fnInfoCallback = function(oSettings, iStart, iEnd, + iMax, iTotal, sPre) { + return Number(iTotal).toLocaleString() + " records"; + }; + } + } + + // auto hide navigation if requested + // Note, this only works on client-side processing mode as on server-side, + // cells (data.data) is null; In addition, we require the pageLength option + // being provided explicitly to enable this. Despite we may be able to deduce + // the default value of pageLength, it may complicate things so we'd rather + // put this responsiblity to users and warn them on the R side. + if (data.autoHideNavigation === true && data.options.paging !== false) { + // strip all nav if length >= cells + if ((cells instanceof Array) && data.options.pageLength >= cells.length) + options.dom = bootstrapActive ? "<'row'<'col-sm-12'tr>>" : "t"; + // alternatively lean things out for flexdashboard mobile portrait + else if (bootstrapActive && window.FlexDashboard && window.FlexDashboard.isMobilePhone()) + options.dom = "<'row'<'col-sm-12'f>>" + + "<'row'<'col-sm-12'tr>>" + + "<'row'<'col-sm-12'p>>"; + } + + $.extend(true, options, data.options || {}); + + var searchCols = options.searchCols; + if (searchCols) { + searchCols = searchCols.map(function(x) { + return x === null ? '' : x.search; + }); + // FIXME: this means I don't respect the escapeRegex setting + delete options.searchCols; + } + + // server-side processing? + var server = options.serverSide === true; + + // use the dataSrc function to pre-process JSON data returned from R + var DT_rows_all = [], DT_rows_current = []; + if (server && HTMLWidgets.shinyMode && typeof options.ajax === 'object' && + /^session\/[\da-z]+\/dataobj/.test(options.ajax.url) && !options.ajax.dataSrc) { + options.ajax.dataSrc = function(json) { + DT_rows_all = $.makeArray(json.DT_rows_all); + DT_rows_current = $.makeArray(json.DT_rows_current); + var data = json.data; + if (!colReorderEnabled()) return data; + var table = $table.DataTable(), order = table.colReorder.order(), flag = true, i, j, row; + for (i = 0; i < order.length; ++i) if (order[i] !== i) flag = false; + if (flag) return data; + for (i = 0; i < data.length; ++i) { + row = data[i].slice(); + for (j = 0; j < order.length; ++j) data[i][j] = row[order[j]]; + } + return data; + }; + } + + var thiz = this; + if (instance.fillContainer) $table.on('init.dt', function(e) { + thiz.fillAvailableHeight(el, $(el).innerHeight()); + }); + // If the page contains serveral datatables and one of which enables colReorder, + // the table.colReorder.order() function will exist but throws error when called. + // So it seems like the only way to know if colReorder is enabled or not is to + // check the options. + var colReorderEnabled = function() { return "colReorder" in options; }; + var table = $table.DataTable(options); + $el.data('datatable', table); + + if ('rowGroup' in options) { + // Maintain RowGroup dataSrc when columns are reordered (#1109) + table.on('column-reorder', function(e, settings, details) { + var oldDataSrc = table.rowGroup().dataSrc(); + var newDataSrc = details.mapping[oldDataSrc]; + table.rowGroup().dataSrc(newDataSrc); + }); + } + + // Unregister previous Crosstalk event subscriptions, if they exist + if (instance.ctfilterSubscription) { + instance.ctfilterHandle.off("change", instance.ctfilterSubscription); + instance.ctfilterSubscription = null; + } + if (instance.ctselectSubscription) { + instance.ctselectHandle.off("change", instance.ctselectSubscription); + instance.ctselectSubscription = null; + } + + if (!crosstalkOptions.group) { + $table[0].ctfilter = null; + $table[0].ctselect = null; + } else { + var key = crosstalkOptions.key; + function keysToMatches(keys) { + if (!keys) { + return null; + } else { + var selectedKeys = {}; + for (var i = 0; i < keys.length; i++) { + selectedKeys[keys[i]] = true; + } + var matches = {}; + for (var j = 0; j < key.length; j++) { + if (selectedKeys[key[j]]) + matches[j] = true; + } + return matches; + } + } + + function applyCrosstalkFilter(e) { + $table[0].ctfilter = keysToMatches(e.value); + table.draw(); + } + instance.ctfilterSubscription = instance.ctfilterHandle.on("change", applyCrosstalkFilter); + applyCrosstalkFilter({value: instance.ctfilterHandle.filteredKeys}); + + function applyCrosstalkSelection(e) { + if (e.sender !== instance.ctselectHandle) { + table + .rows('.' + selClass, {search: 'applied'}) + .nodes() + .to$() + .removeClass(selClass); + if (selectedRows) + changeInput('rows_selected', selectedRows(), void 0, true); + } + + if (e.sender !== instance.ctselectHandle && e.value && e.value.length) { + var matches = keysToMatches(e.value); + + // persistent selection with plotly (& leaflet) + var ctOpts = crosstalk.var("plotlyCrosstalkOpts").get() || {}; + if (ctOpts.persistent === true) { + var matches = $.extend(matches, $table[0].ctselect); + } + + $table[0].ctselect = matches; + table.draw(); + } else { + if ($table[0].ctselect) { + $table[0].ctselect = null; + table.draw(); + } + } + } + instance.ctselectSubscription = instance.ctselectHandle.on("change", applyCrosstalkSelection); + // TODO: This next line doesn't seem to work when renderDataTable is used + applyCrosstalkSelection({value: instance.ctselectHandle.value}); + } + + var inArray = function(val, array) { + return $.inArray(val, $.makeArray(array)) > -1; + }; + + // search the i-th column + var searchColumn = function(i, value) { + var regex = false, ci = true; + if (options.search) { + regex = options.search.regex, + ci = options.search.caseInsensitive !== false; + } + // need to transpose the column index when colReorder is enabled + if (table.colReorder) i = table.colReorder.transpose(i); + return table.column(i).search(value, regex, !regex, ci); + }; + + if (data.filter !== 'none') { + if (!data.hasOwnProperty('filterSettings')) data.filterSettings = {}; + + filterRow.each(function(i, td) { + + var $td = $(td), type = $td.data('type'), filter; + var $input = $td.children('div').first().children('input'); + var disabled = $input.prop('disabled'); + var searchable = table.settings()[0].aoColumns[i].bSearchable; + $input.prop('disabled', !searchable || disabled); + $input.data('searchable', searchable); // for updating later + $input.on('input blur', function() { + $input.next('span').toggle(Boolean($input.val())); + }); + // Bootstrap sets pointer-events to none and we won't be able to click + // the clear button + $input.next('span').css('pointer-events', 'auto').hide().click(function() { + $(this).hide().prev('input').val('').trigger('input').focus(); + }); + var searchCol; // search string for this column + if (searchCols && searchCols[i]) { + searchCol = searchCols[i]; + $input.val(searchCol).trigger('input'); + } + var $x = $td.children('div').last(); + + // remove the overflow: hidden attribute of the scrollHead + // (otherwise the scrolling table body obscures the filters) + // The workaround and the discussion from + // https://github.com/rstudio/DT/issues/554#issuecomment-518007347 + // Otherwise the filter selection will not be anchored to the values + // when the columns number is many and scrollX is enabled. + var scrollHead = $(el).find('.dataTables_scrollHead,.dataTables_scrollFoot'); + var cssOverflowHead = scrollHead.css('overflow'); + var scrollBody = $(el).find('.dataTables_scrollBody'); + var cssOverflowBody = scrollBody.css('overflow'); + var scrollTable = $(el).find('.dataTables_scroll'); + var cssOverflowTable = scrollTable.css('overflow'); + if (cssOverflowHead === 'hidden') { + $x.on('show hide', function(e) { + if (e.type === 'show') { + scrollHead.css('overflow', 'visible'); + scrollBody.css('overflow', 'visible'); + scrollTable.css('overflow-x', 'scroll'); + } else { + scrollHead.css('overflow', cssOverflowHead); + scrollBody.css('overflow', cssOverflowBody); + scrollTable.css('overflow-x', cssOverflowTable); + } + }); + $x.css('z-index', 25); + } + + if (inArray(type, ['factor', 'logical'])) { + $input.on({ + click: function() { + $input.parent().hide(); $x.show().trigger('show'); filter[0].selectize.focus(); + }, + input: function() { + var v1 = JSON.stringify(filter[0].selectize.getValue()), v2 = $input.val(); + if (v1 === '[]') v1 = ''; + if (v1 !== v2) filter[0].selectize.setValue(v2 === '' ? [] : JSON.parse(v2)); + } + }); + var $input2 = $x.children('select'); + filter = $input2.selectize($.extend({ + options: $input2.data('options').map(function(v, i) { + return ({text: v, value: v}); + }), + plugins: ['remove_button'], + hideSelected: true, + onChange: function(value) { + if (value === null) value = []; // compatibility with jQuery 3.0 + $input.val(value.length ? JSON.stringify(value) : ''); + if (value.length) $input.trigger('input'); + $input.attr('title', $input.val()); + if (server) { + searchColumn(i, value.length ? JSON.stringify(value) : '').draw(); + return; + } + // turn off filter if nothing selected + $td.data('filter', value.length > 0); + table.draw(); // redraw table, and filters will be applied + } + }, data.filterSettings.select)); + filter[0].selectize.on('blur', function() { + $x.hide().trigger('hide'); $input.parent().show(); $input.trigger('blur'); + }); + filter.next('div').css('margin-bottom', 'auto'); + } else if (type === 'character') { + var fun = function() { + searchColumn(i, $input.val()).draw(); + }; + // throttle searching for server-side processing + var throttledFun = $.fn.dataTable.util.throttle(fun, options.searchDelay); + $input.on('input', function(e, immediate) { + // always bypass throttling when immediate = true (via the updateSearch method) + (immediate || !server) ? fun() : throttledFun(); + }); + } else if (inArray(type, ['number', 'integer', 'date', 'time'])) { + var $x0 = $x; + $x = $x0.children('div').first(); + $x0.css({ + 'background-color': '#fff', + 'border': '1px #ddd solid', + 'border-radius': '4px', + 'padding': data.vertical ? '35px 20px': '20px 20px 10px 20px' + }); + var $spans = $x0.children('span').css({ + 'margin-top': data.vertical ? '0' : '10px', + 'white-space': 'nowrap' + }); + var $span1 = $spans.first(), $span2 = $spans.last(); + var r1 = +$x.data('min'), r2 = +$x.data('max'); + // when the numbers are too small or have many decimal places, the + // slider may have numeric precision problems (#150) + var scale = Math.pow(10, Math.max(0, +$x.data('scale') || 0)); + r1 = Math.round(r1 * scale); r2 = Math.round(r2 * scale); + var scaleBack = function(x, scale) { + if (scale === 1) return x; + var d = Math.round(Math.log(scale) / Math.log(10)); + // to avoid problems like 3.423/100 -> 0.034230000000000003 + return (x / scale).toFixed(d); + }; + var slider_min = function() { + return filter.noUiSlider('options').range.min; + }; + var slider_max = function() { + return filter.noUiSlider('options').range.max; + }; + $input.on({ + focus: function() { + $x0.show().trigger('show'); + // first, make sure the slider div leaves at least 20px between + // the two (slider value) span's + $x0.width(Math.max(160, $span1.outerWidth() + $span2.outerWidth() + 20)); + // then, if the input is really wide or slider is vertical, + // make the slider the same width as the input + if ($x0.outerWidth() < $input.outerWidth() || data.vertical) { + $x0.outerWidth($input.outerWidth()); + } + // make sure the slider div does not reach beyond the right margin + if ($(window).width() < $x0.offset().left + $x0.width()) { + $x0.offset({ + 'left': $input.offset().left + $input.outerWidth() - $x0.outerWidth() + }); + } + }, + blur: function() { + $x0.hide().trigger('hide'); + }, + input: function() { + if ($input.val() === '') filter.val([slider_min(), slider_max()]); + }, + change: function() { + var v = $input.val().replace(/\s/g, ''); + if (v === '') return; + v = v.split('...'); + if (v.length !== 2) { + $input.parent().addClass('has-error'); + return; + } + if (v[0] === '') v[0] = slider_min(); + if (v[1] === '') v[1] = slider_max(); + $input.parent().removeClass('has-error'); + // treat date as UTC time at midnight + var strTime = function(x) { + var s = type === 'date' ? 'T00:00:00Z' : ''; + var t = new Date(x + s).getTime(); + // add 10 minutes to date since it does not hurt the date, and + // it helps avoid the tricky floating point arithmetic problems, + // e.g. sometimes the date may be a few milliseconds earlier + // than the midnight due to precision problems in noUiSlider + return type === 'date' ? t + 3600000 : t; + }; + if (inArray(type, ['date', 'time'])) { + v[0] = strTime(v[0]); + v[1] = strTime(v[1]); + } + if (v[0] != slider_min()) v[0] *= scale; + if (v[1] != slider_max()) v[1] *= scale; + filter.val(v); + } + }); + var formatDate = function(d) { + d = scaleBack(d, scale); + if (type === 'number') return d; + if (type === 'integer') return parseInt(d); + var x = new Date(+d); + if (type === 'date') { + var pad0 = function(x) { + return ('0' + x).substr(-2, 2); + }; + return x.getUTCFullYear() + '-' + pad0(1 + x.getUTCMonth()) + + '-' + pad0(x.getUTCDate()); + } else { + return x.toISOString(); + } + }; + var opts = type === 'date' ? { step: 60 * 60 * 1000 } : + type === 'integer' ? { step: 1 } : {}; + + opts.orientation = data.vertical ? 'vertical': 'horizontal'; + opts.direction = data.vertical ? 'rtl': 'ltr'; + + filter = $x.noUiSlider($.extend({ + start: [r1, r2], + range: {min: r1, max: r2}, + connect: true + }, opts, data.filterSettings.slider)); + if (scale > 1) (function() { + var t1 = r1, t2 = r2; + var val = filter.val(); + while (val[0] > r1 || val[1] < r2) { + if (val[0] > r1) { + t1 -= val[0] - r1; + } + if (val[1] < r2) { + t2 += r2 - val[1]; + } + filter = $x.noUiSlider($.extend({ + start: [t1, t2], + range: {min: t1, max: t2}, + connect: true + }, opts, data.filterSettings.slider), true); + val = filter.val(); + } + r1 = t1; r2 = t2; + })(); + // format with active column renderer, if defined + var colDef = data.options.columnDefs.find(function(def) { + return (def.targets === i || inArray(i, def.targets)) && 'render' in def; + }); + var updateSliderText = function(v1, v2) { + // we only know how to use function renderers + if (colDef && typeof colDef.render === 'function') { + var restore = function(v) { + v = scaleBack(v, scale); + return inArray(type, ['date', 'time']) ? new Date(+v) : v; + } + $span1.text(colDef.render(restore(v1), 'display')); + $span2.text(colDef.render(restore(v2), 'display')); + } else { + $span1.text(formatDate(v1)); + $span2.text(formatDate(v2)); + } + }; + updateSliderText(r1, r2); + var updateSlider = function(e) { + var val = filter.val(); + // turn off filter if in full range + $td.data('filter', val[0] > slider_min() || val[1] < slider_max()); + var v1 = formatDate(val[0]), v2 = formatDate(val[1]), ival; + if ($td.data('filter')) { + ival = v1 + ' ... ' + v2; + $input.attr('title', ival).val(ival).trigger('input'); + } else { + $input.attr('title', '').val(''); + } + updateSliderText(val[0], val[1]); + if (e.type === 'slide') return; // no searching when sliding only + if (server) { + searchColumn(i, $td.data('filter') ? ival : '').draw(); + return; + } + table.draw(); + }; + filter.on({ + set: updateSlider, + slide: updateSlider + }); + } + + // server-side processing will be handled by R (or whatever server + // language you use); the following code is only needed for client-side + // processing + if (server) { + // if a search string has been pre-set, search now + if (searchCol) $input.trigger('input').trigger('change'); + return; + } + + var customFilter = function(settings, data, dataIndex) { + // there is no way to attach a search function to a specific table, + // and we need to make sure a global search function is not applied to + // all tables (i.e. a range filter in a previous table should not be + // applied to the current table); we use the settings object to + // determine if we want to perform searching on the current table, + // since settings.sTableId will be different to different tables + if (table.settings()[0] !== settings) return true; + // no filter on this column or no need to filter this column + if (typeof filter === 'undefined' || !$td.data('filter')) return true; + + var r = filter.val(), v, r0, r1; + var i_data = function(i) { + if (!colReorderEnabled()) return i; + var order = table.colReorder.order(), k; + for (k = 0; k < order.length; ++k) if (order[k] === i) return k; + return i; // in theory it will never be here... + } + v = data[i_data(i)]; + if (type === 'number' || type === 'integer') { + v = parseFloat(v); + // how to handle NaN? currently exclude these rows + if (isNaN(v)) return(false); + r0 = parseFloat(scaleBack(r[0], scale)) + r1 = parseFloat(scaleBack(r[1], scale)); + if (v >= r0 && v <= r1) return true; + } else if (type === 'date' || type === 'time') { + v = new Date(v); + r0 = new Date(r[0] / scale); r1 = new Date(r[1] / scale); + if (v >= r0 && v <= r1) return true; + } else if (type === 'factor') { + if (r.length === 0 || inArray(v, r)) return true; + } else if (type === 'logical') { + if (r.length === 0) return true; + if (inArray(v === '' ? 'na' : v, r)) return true; + } + return false; + }; + + $.fn.dataTable.ext.search.push(customFilter); + + // search for the preset search strings if it is non-empty + if (searchCol) $input.trigger('input').trigger('change'); + + }); + + } + + // highlight search keywords + var highlight = function() { + var body = $(table.table().body()); + // removing the old highlighting first + body.unhighlight(); + + // don't highlight the "not found" row, so we get the rows using the api + if (table.rows({ filter: 'applied' }).data().length === 0) return; + // highlight global search keywords + body.highlight($.trim(table.search()).split(/\s+/)); + // then highlight keywords from individual column filters + if (filterRow) filterRow.each(function(i, td) { + var $td = $(td), type = $td.data('type'); + if (type !== 'character') return; + var $input = $td.children('div').first().children('input'); + var column = table.column(i).nodes().to$(), + val = $.trim($input.val()); + if (type !== 'character' || val === '') return; + column.highlight(val.split(/\s+/)); + }); + }; + + if (options.searchHighlight) { + table + .on('draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth', highlight) + .on('destroy', function() { + // remove event handler + table.off('draw.dt.dth column-visibility.dt.dth column-reorder.dt.dth'); + }); + + // Set the option for escaping regex characters in our search string. This will be used + // for all future matching. + jQuery.fn.highlight.options.escapeRegex = (!options.search || !options.search.regex); + + // initial highlight for state saved conditions and initial states + highlight(); + } + + // run the callback function on the table instance + if (typeof data.callback === 'function') data.callback(table); + + // double click to edit the cell, row, column, or all cells + if (data.editable) table.on('dblclick.dt', 'tbody td', function(e) { + // only bring up the editor when the cell itself is dbclicked, and ignore + // other dbclick events bubbled up (e.g. from the <input>) + if (e.target !== this) return; + var target = [], immediate = false; + switch (data.editable.target) { + case 'cell': + target = [this]; + immediate = true; // edit will take effect immediately + break; + case 'row': + target = table.cells(table.cell(this).index().row, '*').nodes(); + break; + case 'column': + target = table.cells('*', table.cell(this).index().column).nodes(); + break; + case 'all': + target = table.cells().nodes(); + break; + default: + throw 'The editable parameter must be "cell", "row", "column", or "all"'; + } + var disableCols = data.editable.disable ? data.editable.disable.columns : null; + var numericCols = data.editable.numeric; + var areaCols = data.editable.area; + var dateCols = data.editable.date; + for (var i = 0; i < target.length; i++) { + (function(cell, current) { + var $cell = $(cell), html = $cell.html(); + var _cell = table.cell(cell), value = _cell.data(), index = _cell.index().column; + var $input; + if (inArray(index, numericCols)) { + $input = $('<input type="number">'); + } else if (inArray(index, areaCols)) { + $input = $('<textarea></textarea>'); + } else if (inArray(index, dateCols)) { + $input = $('<input type="date">'); + } else { + $input = $('<input type="text">'); + } + if (!immediate) { + $cell.data('input', $input).data('html', html); + $input.attr('title', 'Hit Ctrl+Enter to finish editing, or Esc to cancel'); + } + $input.val(value); + if (inArray(index, disableCols)) { + $input.attr('readonly', '').css('filter', 'invert(25%)'); + } + $cell.empty().append($input); + if (cell === current) $input.focus(); + $input.css('width', '100%'); + + if (immediate) $input.on('blur', function(e) { + var valueNew = $input.val(); + if (valueNew !== value) { + _cell.data(valueNew); + if (HTMLWidgets.shinyMode) { + changeInput('cell_edit', [cellInfo(cell)], 'DT.cellInfo', null, {priority: 'event'}); + } + // for server-side processing, users have to call replaceData() to update the table + if (!server) table.draw(false); + } else { + $cell.html(html); + } + }).on('keyup', function(e) { + // hit Escape to cancel editing + if (e.keyCode === 27) $input.trigger('blur'); + }); + + // bulk edit (row, column, or all) + if (!immediate) $input.on('keyup', function(e) { + var removeInput = function($cell, restore) { + $cell.data('input').remove(); + if (restore) $cell.html($cell.data('html')); + } + if (e.keyCode === 27) { + for (var i = 0; i < target.length; i++) { + removeInput($(target[i]), true); + } + } else if (e.keyCode === 13 && e.ctrlKey) { + // Ctrl + Enter + var cell, $cell, _cell, cellData = []; + for (var i = 0; i < target.length; i++) { + cell = target[i]; $cell = $(cell); _cell = table.cell(cell); + _cell.data($cell.data('input').val()); + HTMLWidgets.shinyMode && cellData.push(cellInfo(cell)); + removeInput($cell, false); + } + if (HTMLWidgets.shinyMode) { + changeInput('cell_edit', cellData, 'DT.cellInfo', null, {priority: "event"}); + } + if (!server) table.draw(false); + } + }); + })(target[i], this); + } + }); + + // interaction with shiny + if (!HTMLWidgets.shinyMode && !crosstalkOptions.group) return; + + var methods = {}; + var shinyData = {}; + + methods.updateCaption = function(caption) { + if (!caption) return; + $table.children('caption').replaceWith(caption); + } + + // register clear functions to remove input values when the table is removed + instance.clearInputs = {}; + + var changeInput = function(id, value, type, noCrosstalk, opts) { + var event = id; + id = el.id + '_' + id; + if (type) id = id + ':' + type; + // do not update if the new value is the same as old value + if (event !== 'cell_edit' && !/_clicked$/.test(event) && shinyData.hasOwnProperty(id) && shinyData[id] === JSON.stringify(value)) + return; + shinyData[id] = JSON.stringify(value); + if (HTMLWidgets.shinyMode && Shiny.setInputValue) { + Shiny.setInputValue(id, value, opts); + if (!instance.clearInputs[id]) instance.clearInputs[id] = function() { + Shiny.setInputValue(id, null); + } + } + + // HACK + if (event === "rows_selected" && !noCrosstalk) { + if (crosstalkOptions.group) { + var keys = crosstalkOptions.key; + var selectedKeys = null; + if (value) { + selectedKeys = []; + for (var i = 0; i < value.length; i++) { + // The value array's contents use 1-based row numbers, so we must + // convert to 0-based before indexing into the keys array. + selectedKeys.push(keys[value[i] - 1]); + } + } + instance.ctselectHandle.set(selectedKeys); + } + } + }; + + var addOne = function(x) { + return x.map(function(i) { return 1 + i; }); + }; + + var unique = function(x) { + var ux = []; + $.each(x, function(i, el){ + if ($.inArray(el, ux) === -1) ux.push(el); + }); + return ux; + } + + // change the row index of a cell + var tweakCellIndex = function(cell) { + var info = cell.index(); + // some cell may not be valid. e.g, #759 + // when using the RowGroup extension, datatables will + // generate the row label and the cells are not part of + // the data thus contain no row/col info + if (info === undefined) + return {row: null, col: null}; + if (server) { + info.row = DT_rows_current[info.row]; + } else { + info.row += 1; + } + return {row: info.row, col: info.column}; + } + + var cleanSelectedValues = function() { + changeInput('rows_selected', []); + changeInput('columns_selected', []); + changeInput('cells_selected', transposeArray2D([]), 'shiny.matrix'); + } + // #828 we should clean the selection on the server-side when the table reloads + cleanSelectedValues(); + + // a flag to indicates if select extension is initialized or not + var flagSelectExt = table.settings()[0]._select !== undefined; + // the Select extension should only be used in the client mode and + // when the selection.mode is set to none + if (data.selection.mode === 'none' && !server && flagSelectExt) { + var updateRowsSelected = function() { + var rows = table.rows({selected: true}); + var selected = []; + $.each(rows.indexes().toArray(), function(i, v) { + selected.push(v + 1); + }); + changeInput('rows_selected', selected); + } + var updateColsSelected = function() { + var columns = table.columns({selected: true}); + changeInput('columns_selected', columns.indexes().toArray()); + } + var updateCellsSelected = function() { + var cells = table.cells({selected: true}); + var selected = []; + cells.every(function() { + var row = this.index().row; + var col = this.index().column; + selected = selected.concat([[row + 1, col]]); + }); + changeInput('cells_selected', transposeArray2D(selected), 'shiny.matrix'); + } + table.on('select deselect', function(e, dt, type, indexes) { + updateRowsSelected(); + updateColsSelected(); + updateCellsSelected(); + }) + updateRowsSelected(); + updateColsSelected(); + updateCellsSelected(); + } + + var selMode = data.selection.mode, selTarget = data.selection.target; + var selDisable = data.selection.selectable === false; + if (inArray(selMode, ['single', 'multiple'])) { + var selClass = inArray(data.style, ['bootstrap', 'bootstrap4']) ? 'active' : 'selected'; + // selected1: row indices; selected2: column indices + var initSel = function(x) { + if (x === null || typeof x === 'boolean' || selTarget === 'cell') { + return {rows: [], cols: []}; + } else if (selTarget === 'row') { + return {rows: $.makeArray(x), cols: []}; + } else if (selTarget === 'column') { + return {rows: [], cols: $.makeArray(x)}; + } else if (selTarget === 'row+column') { + return {rows: $.makeArray(x.rows), cols: $.makeArray(x.cols)}; + } + } + var selected = data.selection.selected; + var selected1 = initSel(selected).rows, selected2 = initSel(selected).cols; + // selectable should contain either all positive or all non-positive values, not both + // positive values indicate "selectable" while non-positive values means "nonselectable" + // the assertion is performed on R side. (only column indicides could be zero which indicates + // the row name) + var selectable = data.selection.selectable; + var selectable1 = initSel(selectable).rows, selectable2 = initSel(selectable).cols; + + // After users reorder the rows or filter the table, we cannot use the table index + // directly. Instead, we need this function to find out the rows between the two clicks. + // If user filter the table again between the start click and the end click, the behavior + // would be undefined, but it should not be a problem. + var shiftSelRowsIndex = function(start, end) { + var indexes = server ? DT_rows_all : table.rows({ search: 'applied' }).indexes().toArray(); + start = indexes.indexOf(start); end = indexes.indexOf(end); + // if start is larger than end, we need to swap + if (start > end) { + var tmp = end; end = start; start = tmp; + } + return indexes.slice(start, end + 1); + } + + var serverRowIndex = function(clientRowIndex) { + return server ? DT_rows_current[clientRowIndex] : clientRowIndex + 1; + } + + // row, column, or cell selection + var lastClickedRow; + if (inArray(selTarget, ['row', 'row+column'])) { + // Get the current selected rows. It will also + // update the selected1's value based on the current row selection state + // Note we can't put this function inside selectRows() directly, + // the reason is method.selectRows() will override selected1's value but this + // function will add rows to selected1 (keep the existing selection), which is + // inconsistent with column and cell selection. + var selectedRows = function() { + var rows = table.rows('.' + selClass); + var idx = rows.indexes().toArray(); + if (!server) { + selected1 = addOne(idx); + return selected1; + } + idx = idx.map(function(i) { + return DT_rows_current[i]; + }); + selected1 = selMode === 'multiple' ? unique(selected1.concat(idx)) : idx; + return selected1; + } + // Change selected1's value based on selectable1, then refresh the row state + var onlyKeepSelectableRows = function() { + if (selDisable) { // users can't select; useful when only want backend select + selected1 = []; + return; + } + if (selectable1.length === 0) return; + var nonselectable = selectable1[0] <= 0; + if (nonselectable) { + // should make selectable1 positive + selected1 = $(selected1).not(selectable1.map(function(i) { return -i; })).get(); + } else { + selected1 = $(selected1).filter(selectable1).get(); + } + } + // Change selected1's value based on selectable1, then + // refresh the row selection state according to values in selected1 + var selectRows = function(ignoreSelectable) { + if (!ignoreSelectable) onlyKeepSelectableRows(); + table.$('tr.' + selClass).removeClass(selClass); + if (selected1.length === 0) return; + if (server) { + table.rows({page: 'current'}).every(function() { + if (inArray(DT_rows_current[this.index()], selected1)) { + $(this.node()).addClass(selClass); + } + }); + } else { + var selected0 = selected1.map(function(i) { return i - 1; }); + $(table.rows(selected0).nodes()).addClass(selClass); + } + } + table.on('mousedown.dt', 'tbody tr', function(e) { + var $this = $(this), thisRow = table.row(this); + if (selMode === 'multiple') { + if (e.shiftKey && lastClickedRow !== undefined) { + // select or de-select depends on the last clicked row's status + var flagSel = !$this.hasClass(selClass); + var crtClickedRow = serverRowIndex(thisRow.index()); + if (server) { + var rowsIndex = shiftSelRowsIndex(lastClickedRow, crtClickedRow); + // update current page's selClass + rowsIndex.map(function(i) { + var rowIndex = DT_rows_current.indexOf(i); + if (rowIndex >= 0) { + var row = table.row(rowIndex).nodes().to$(); + var flagRowSel = !row.hasClass(selClass); + if (flagSel === flagRowSel) row.toggleClass(selClass); + } + }); + // update selected1 + if (flagSel) { + selected1 = unique(selected1.concat(rowsIndex)); + } else { + selected1 = selected1.filter(function(index) { + return !inArray(index, rowsIndex); + }); + } + } else { + // js starts from 0 + shiftSelRowsIndex(lastClickedRow - 1, crtClickedRow - 1).map(function(value) { + var row = table.row(value).nodes().to$(); + var flagRowSel = !row.hasClass(selClass); + if (flagSel === flagRowSel) row.toggleClass(selClass); + }); + } + e.preventDefault(); + } else { + $this.toggleClass(selClass); + } + } else { + if ($this.hasClass(selClass)) { + $this.removeClass(selClass); + } else { + table.$('tr.' + selClass).removeClass(selClass); + $this.addClass(selClass); + } + } + if (server && !$this.hasClass(selClass)) { + var id = DT_rows_current[thisRow.index()]; + // remove id from selected1 since its class .selected has been removed + if (inArray(id, selected1)) selected1.splice($.inArray(id, selected1), 1); + } + selectedRows(); // update selected1's value based on selClass + selectRows(false); // only keep the selectable rows + changeInput('rows_selected', selected1); + changeInput('row_last_clicked', serverRowIndex(thisRow.index()), null, null, {priority: 'event'}); + lastClickedRow = serverRowIndex(thisRow.index()); + }); + selectRows(false); // in case users have specified pre-selected rows + // restore selected rows after the table is redrawn (e.g. sort/search/page); + // client-side tables will preserve the selections automatically; for + // server-side tables, we have to *real* row indices are in `selected1` + changeInput('rows_selected', selected1); + if (server) table.on('draw.dt', function(e) { selectRows(false); }); + methods.selectRows = function(selected, ignoreSelectable) { + selected1 = $.makeArray(selected); + selectRows(ignoreSelectable); + changeInput('rows_selected', selected1); + } + } + + if (inArray(selTarget, ['column', 'row+column'])) { + if (selTarget === 'row+column') { + $(table.columns().footer()).css('cursor', 'pointer'); + } + // update selected2's value based on selectable2 + var onlyKeepSelectableCols = function() { + if (selDisable) { // users can't select; useful when only want backend select + selected2 = []; + return; + } + if (selectable2.length === 0) return; + var nonselectable = selectable2[0] <= 0; + if (nonselectable) { + // need to make selectable2 positive + selected2 = $(selected2).not(selectable2.map(function(i) { return -i; })).get(); + } else { + selected2 = $(selected2).filter(selectable2).get(); + } + } + // update selected2 and then + // refresh the col selection state according to values in selected2 + var selectCols = function(ignoreSelectable) { + if (!ignoreSelectable) onlyKeepSelectableCols(); + // if selected2 is not a valide index (e.g., larger than the column number) + // table.columns(selected2) will fail and result in a blank table + // this is different from the table.rows(), where the out-of-range indexes + // doesn't affect at all + selected2 = $(selected2).filter(table.columns().indexes()).get(); + table.columns().nodes().flatten().to$().removeClass(selClass); + if (selected2.length > 0) + table.columns(selected2).nodes().flatten().to$().addClass(selClass); + } + var callback = function() { + var colIdx = selTarget === 'column' ? table.cell(this).index().column : + $.inArray(this, table.columns().footer()), + thisCol = $(table.column(colIdx).nodes()); + if (colIdx === -1) return; + if (thisCol.hasClass(selClass)) { + thisCol.removeClass(selClass); + selected2.splice($.inArray(colIdx, selected2), 1); + } else { + if (selMode === 'single') $(table.cells().nodes()).removeClass(selClass); + thisCol.addClass(selClass); + selected2 = selMode === 'single' ? [colIdx] : unique(selected2.concat([colIdx])); + } + selectCols(false); // update selected2 based on selectable + changeInput('columns_selected', selected2); + } + if (selTarget === 'column') { + $(table.table().body()).on('click.dt', 'td', callback); + } else { + $(table.table().footer()).on('click.dt', 'tr th', callback); + } + selectCols(false); // in case users have specified pre-selected columns + changeInput('columns_selected', selected2); + if (server) table.on('draw.dt', function(e) { selectCols(false); }); + methods.selectColumns = function(selected, ignoreSelectable) { + selected2 = $.makeArray(selected); + selectCols(ignoreSelectable); + changeInput('columns_selected', selected2); + } + } + + if (selTarget === 'cell') { + var selected3 = [], selectable3 = []; + if (selected !== null) selected3 = selected; + if (selectable !== null && typeof selectable !== 'boolean') selectable3 = selectable; + var findIndex = function(ij, sel) { + for (var i = 0; i < sel.length; i++) { + if (ij[0] === sel[i][0] && ij[1] === sel[i][1]) return i; + } + return -1; + } + // Change selected3's value based on selectable3, then refresh the cell state + var onlyKeepSelectableCells = function() { + if (selDisable) { // users can't select; useful when only want backend select + selected3 = []; + return; + } + if (selectable3.length === 0) return; + var nonselectable = selectable3[0][0] <= 0; + var out = []; + if (nonselectable) { + selected3.map(function(ij) { + // should make selectable3 positive + if (findIndex([-ij[0], -ij[1]], selectable3) === -1) { out.push(ij); } + }); + } else { + selected3.map(function(ij) { + if (findIndex(ij, selectable3) > -1) { out.push(ij); } + }); + } + selected3 = out; + } + // Change selected3's value based on selectable3, then + // refresh the cell selection state according to values in selected3 + var selectCells = function(ignoreSelectable) { + if (!ignoreSelectable) onlyKeepSelectableCells(); + table.$('td.' + selClass).removeClass(selClass); + if (selected3.length === 0) return; + if (server) { + table.cells({page: 'current'}).every(function() { + var info = tweakCellIndex(this); + if (findIndex([info.row, info.col], selected3) > -1) + $(this.node()).addClass(selClass); + }); + } else { + selected3.map(function(ij) { + $(table.cell(ij[0] - 1, ij[1]).node()).addClass(selClass); + }); + } + }; + table.on('click.dt', 'tbody td', function() { + var $this = $(this), info = tweakCellIndex(table.cell(this)); + if ($this.hasClass(selClass)) { + $this.removeClass(selClass); + selected3.splice(findIndex([info.row, info.col], selected3), 1); + } else { + if (selMode === 'single') $(table.cells().nodes()).removeClass(selClass); + $this.addClass(selClass); + selected3 = selMode === 'single' ? [[info.row, info.col]] : + unique(selected3.concat([[info.row, info.col]])); + } + selectCells(false); // must call this to update selected3 based on selectable3 + changeInput('cells_selected', transposeArray2D(selected3), 'shiny.matrix'); + }); + selectCells(false); // in case users have specified pre-selected columns + changeInput('cells_selected', transposeArray2D(selected3), 'shiny.matrix'); + + if (server) table.on('draw.dt', function(e) { selectCells(false); }); + methods.selectCells = function(selected, ignoreSelectable) { + selected3 = selected ? selected : []; + selectCells(ignoreSelectable); + changeInput('cells_selected', transposeArray2D(selected3), 'shiny.matrix'); + } + } + } + + // expose some table info to Shiny + var updateTableInfo = function(e, settings) { + // TODO: is anyone interested in the page info? + // changeInput('page_info', table.page.info()); + var updateRowInfo = function(id, modifier) { + var idx; + if (server) { + idx = modifier.page === 'current' ? DT_rows_current : DT_rows_all; + } else { + var rows = table.rows($.extend({ + search: 'applied', + page: 'all' + }, modifier)); + idx = addOne(rows.indexes().toArray()); + } + changeInput('rows' + '_' + id, idx); + }; + updateRowInfo('current', {page: 'current'}); + updateRowInfo('all', {}); + } + table.on('draw.dt', updateTableInfo); + updateTableInfo(); + + // state info + table.on('draw.dt column-visibility.dt', function() { + changeInput('state', table.state()); + }); + changeInput('state', table.state()); + + // search info + var updateSearchInfo = function() { + changeInput('search', table.search()); + if (filterRow) changeInput('search_columns', filterRow.toArray().map(function(td) { + return $(td).find('input').first().val(); + })); + } + table.on('draw.dt', updateSearchInfo); + updateSearchInfo(); + + var cellInfo = function(thiz) { + var info = tweakCellIndex(table.cell(thiz)); + info.value = table.cell(thiz).data(); + return info; + } + // the current cell clicked on + table.on('click.dt', 'tbody td', function() { + changeInput('cell_clicked', cellInfo(this), null, null, {priority: 'event'}); + }) + changeInput('cell_clicked', {}); + + // do not trigger table selection when clicking on links unless they have classes + table.on('mousedown.dt', 'tbody td a', function(e) { + if (this.className === '') e.stopPropagation(); + }); + + methods.addRow = function(data, rowname, resetPaging) { + var n = table.columns().indexes().length, d = n - data.length; + if (d === 1) { + data = rowname.concat(data) + } else if (d !== 0) { + console.log(data); + console.log(table.columns().indexes()); + throw 'New data must be of the same length as current data (' + n + ')'; + }; + table.row.add(data).draw(resetPaging); + } + + methods.updateSearch = function(keywords) { + if (keywords.global !== null) + $(table.table().container()).find('input[type=search]').first() + .val(keywords.global).trigger('input'); + var columns = keywords.columns; + if (!filterRow || columns === null) return; + filterRow.toArray().map(function(td, i) { + var v = typeof columns === 'string' ? columns : columns[i]; + if (typeof v === 'undefined') { + console.log('The search keyword for column ' + i + ' is undefined') + return; + } + // Update column search string and values on linked filter widgets. + // 'input' for factor and char filters, 'change' for numeric filters. + $(td).find('input').first().val(v).trigger('input', [true]).trigger('change'); + }); + table.draw(); + } + + methods.hideCols = function(hide, reset) { + if (reset) table.columns().visible(true, false); + table.columns(hide).visible(false); + } + + methods.showCols = function(show, reset) { + if (reset) table.columns().visible(false, false); + table.columns(show).visible(true); + } + + methods.colReorder = function(order, origOrder) { + table.colReorder.order(order, origOrder); + } + + methods.selectPage = function(page) { + if (table.page.info().pages < page || page < 1) { + throw 'Selected page is out of range'; + }; + table.page(page - 1).draw(false); + } + + methods.reloadData = function(resetPaging, clearSelection) { + // empty selections first if necessary + if (methods.selectRows && inArray('row', clearSelection)) methods.selectRows([]); + if (methods.selectColumns && inArray('column', clearSelection)) methods.selectColumns([]); + if (methods.selectCells && inArray('cell', clearSelection)) methods.selectCells([]); + table.ajax.reload(null, resetPaging); + } + + // update table filters (set new limits of sliders) + methods.updateFilters = function(newProps) { + // loop through each filter in the filter row + filterRow.each(function(i, td) { + var k = i; + if (filterRow.length > newProps.length) { + if (i === 0) return; // first column is row names + k = i - 1; + } + // Update the filters to reflect the updated data. + // Allow "falsy" (e.g. NULL) to signify a no-op. + if (newProps[k]) { + setFilterProps(td, newProps[k]); + } + }); + }; + + table.shinyMethods = methods; + }, + resize: function(el, width, height, instance) { + if (instance.data) this.renderValue(el, instance.data, instance); + + // dynamically adjust height if fillContainer = TRUE + if (instance.fillContainer) + this.fillAvailableHeight(el, height); + + this.adjustWidth(el); + }, + + // dynamically set the scroll body to fill available height + // (used with fillContainer = TRUE) + fillAvailableHeight: function(el, availableHeight) { + + // see how much of the table is occupied by header/footer elements + // and use that to compute a target scroll body height + var dtWrapper = $(el).find('div.dataTables_wrapper'); + var dtScrollBody = $(el).find($('div.dataTables_scrollBody')); + var framingHeight = dtWrapper.innerHeight() - dtScrollBody.innerHeight(); + var scrollBodyHeight = availableHeight - framingHeight; + + // we need to set `max-height` to none as datatables library now sets this + // to a fixed height, disabling the ability to resize to fill the window, + // as it will be set to a fixed 100px under such circumstances, e.g., RStudio IDE, + // or FlexDashboard + // see https://github.com/rstudio/DT/issues/951#issuecomment-1026464509 + dtScrollBody.css('max-height', 'none'); + // set the height + dtScrollBody.height(scrollBodyHeight + 'px'); + }, + + // adjust the width of columns; remove the hard-coded widths on table and the + // scroll header when scrollX/Y are enabled + adjustWidth: function(el) { + var $el = $(el), table = $el.data('datatable'); + if (table) table.columns.adjust(); + $el.find('.dataTables_scrollHeadInner').css('width', '') + .children('table').css('margin-left', ''); + } +}); + + if (!HTMLWidgets.shinyMode) return; + + Shiny.addCustomMessageHandler('datatable-calls', function(data) { + var id = data.id; + var el = document.getElementById(id); + var table = el ? $(el).data('datatable') : null; + if (!table) { + console.log("Couldn't find table with id " + id); + return; + } + + var methods = table.shinyMethods, call = data.call; + if (methods[call.method]) { + methods[call.method].apply(table, call.args); + } else { + console.log("Unknown method " + call.method); + } + }); + +})(); diff --git a/docs/coverage/lib/htmltools-fill-0.5.9/fill.css b/docs/coverage/lib/htmltools-fill-0.5.9/fill.css new file mode 100644 index 0000000..841ea9d --- /dev/null +++ b/docs/coverage/lib/htmltools-fill-0.5.9/fill.css @@ -0,0 +1,21 @@ +@layer htmltools { + .html-fill-container { + display: flex; + flex-direction: column; + /* Prevent the container from expanding vertically or horizontally beyond its + parent's constraints. */ + min-height: 0; + min-width: 0; + } + .html-fill-container > .html-fill-item { + /* Fill items can grow and shrink freely within + available vertical space in fillable container */ + flex: 1 1 auto; + min-height: 0; + min-width: 0; + } + .html-fill-container > :not(.html-fill-item) { + /* Prevent shrinking or growing of non-fill items */ + flex: 0 0 auto; + } +} diff --git a/docs/index.html b/docs/index.html index d9d44ad..6623b75 100644 --- a/docs/index.html +++ b/docs/index.html @@ -148,7 +148,7 @@ </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer> diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..199ad78 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,111 @@ +# chents + +[](https://pkgdown.jrwb.de/chents/) +[](https://jranke.r-universe.dev/chents) +[](https://pkgdown.jrwb.de/chents/coverage/coverage.html) + +The R package **chents** provides some utilities for working with +chemical entities in R. + +When first defining a chemical entity, some chemical information is +retrieved from the [PubChem](https://pubchem.ncbi.nlm.nih.gov/) website +using the [webchem](https://docs.ropensci.org/webchem/) package. + +``` r +library(chents) +caffeine <- chent$new("caffeine") +#> Querying PubChem ... +#> Trying to get chemical information from RDKit using PubChem SMILES +#> CN1C=NC2=C1C(=O)N(C(=O)N2C)C +``` + +If Python and [RDKit](https://rdkit.org) (\> 2015.03) are installed and +configured for use with the +[reticulate](https://rstudio.github.io/reticulate/) package, some +additional chemical information including a 2D graph are computed. + +The print method gives an overview of the information that was +collected. + +``` r +print(caffeine) +#> <chent> +#> Identifier $identifier caffeine +#> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N +#> SMILES string $smiles: +#> PubChem +#> "CN1C=NC2=C1C(=O)N(C(=O)N2C)C" +#> Molecular weight $mw: 194.2 +#> PubChem synonyms (up to 10): +#> [1] "caffeine" "58-08-2" +#> [3] "Guaranine" "1,3,7-Trimethylxanthine" +#> [5] "Methyltheobromine" "Theine" +#> [7] "Thein" "Cafeina" +#> [9] "Koffein" "Mateina" +``` + +There is a very simple plotting method for the chemical structure. + +``` r +plot(caffeine) +``` + + + +Additional information can be (but is rarely ever) read from a local +.yaml file. This information can be leveraged e.g. by the +[PEC_soil](https://pkgdown.jrwb.de/pfm/reference/PEC_soil.html) function +of the ‘pfm’ package. + +If you have a so-called ISO common name of a pesticide active +ingredient, you can use the ‘pai’ class derived from the ‘chent’ class, +which starts with querying the [BCPC +compendium](http://www.bcpcpesticidecompendium.org/) first. + +``` r +lambda <- pai$new("lambda-cyhalothrin") +#> Querying BCPC for lambda-cyhalothrin ... +#> Querying PubChem ... +#> Trying to get chemical information from RDKit using PubChem SMILES +#> CC1([C@@H]([C@@H]1C(=O)O[C@@H](C#N)C2=CC(=CC=C2)OC3=CC=CC=C3)/C=C(/C(F)(F)F)\Cl)C +#> RDKit mw is 449.856 +#> mw is 449.8 +plot(lambda) +``` + + + +## Installation + +You can conveniently install chents from the repository kindly made +available by the R-Universe project: + +``` R +install.packages("chents", + repos = c("https://jranke.r-universe.dev", "https://cran.r-project.org")) +``` + +In order to profit from the chemoinformatics, you need to install RDKit +and its python bindings. On a Debian type Linux distribution, just use + +``` R +sudo apt install python3-rdkit +``` + +If you use this package on Windows or MacOS, I would be happy to include +installation instructions here if you share them with me, e.g. via a +Pull Request. + +## Configuration of the Python version to use + +On Debian type Linux distributions, you can use the following line in +your global or project specific `.Rprofile` file to tell the +`reticulate` package to use the system Python version that will find the +RDKit installed in the system location. + +``` R +Sys.setenv(RETICULATE_PYTHON="/usr/bin/python3") +``` diff --git a/docs/llms.txt b/docs/llms.txt new file mode 100644 index 0000000..60135e4 --- /dev/null +++ b/docs/llms.txt @@ -0,0 +1,133 @@ +# chents + +[](https://pkgdown.jrwb.de/chents/) +[](https://jranke.r-universe.dev/chents) +[](https://pkgdown.jrwb.de/chents/coverage/coverage.html) + +The R package **chents** provides some utilities for working with +chemical entities in R. + +When first defining a chemical entity, some chemical information is +retrieved from the [PubChem](https://pubchem.ncbi.nlm.nih.gov/) website +using the [webchem](https://docs.ropensci.org/webchem/) package. + +``` r +library(chents) +caffeine <- chent$new("caffeine") +#> Querying PubChem ... +#> Trying to get chemical information from RDKit using PubChem SMILES +#> CN1C=NC2=C1C(=O)N(C(=O)N2C)C +``` + +If Python and [RDKit](https://rdkit.org) (\> 2015.03) are installed and +configured for use with the +[reticulate](https://rstudio.github.io/reticulate/) package, some +additional chemical information including a 2D graph are computed. + +The print method gives an overview of the information that was +collected. + +``` r +print(caffeine) +#> <chent> +#> Identifier $identifier caffeine +#> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N +#> SMILES string $smiles: +#> PubChem +#> "CN1C=NC2=C1C(=O)N(C(=O)N2C)C" +#> Molecular weight $mw: 194.2 +#> PubChem synonyms (up to 10): +#> [1] "caffeine" "58-08-2" +#> [3] "Guaranine" "1,3,7-Trimethylxanthine" +#> [5] "Methyltheobromine" "Theine" +#> [7] "Thein" "Cafeina" +#> [9] "Koffein" "Mateina" +``` + +There is a very simple plotting method for the chemical structure. + +``` r +plot(caffeine) +``` + + + +Additional information can be (but is rarely ever) read from a local +.yaml file. This information can be leveraged e.g. by the +[PEC_soil](https://pkgdown.jrwb.de/pfm/reference/PEC_soil.html) function +of the ‘pfm’ package. + +If you have a so-called ISO common name of a pesticide active +ingredient, you can use the ‘pai’ class derived from the ‘chent’ class, +which starts with querying the [BCPC +compendium](http://www.bcpcpesticidecompendium.org/) first. + +``` r +lambda <- pai$new("lambda-cyhalothrin") +#> Querying BCPC for lambda-cyhalothrin ... +#> Querying PubChem ... +#> Trying to get chemical information from RDKit using PubChem SMILES +#> CC1([C@@H]([C@@H]1C(=O)O[C@@H](C#N)C2=CC(=CC=C2)OC3=CC=CC=C3)/C=C(/C(F)(F)F)\Cl)C +#> RDKit mw is 449.856 +#> mw is 449.8 +plot(lambda) +``` + + + +## Installation + +You can conveniently install chents from the repository kindly made +available by the R-Universe project: + +``` R +install.packages("chents", + repos = c("https://jranke.r-universe.dev", "https://cran.r-project.org")) +``` + +In order to profit from the chemoinformatics, you need to install RDKit +and its python bindings. On a Debian type Linux distribution, just use + +``` R +sudo apt install python3-rdkit +``` + +If you use this package on Windows or MacOS, I would be happy to include +installation instructions here if you share them with me, e.g. via a +Pull Request. + +## Configuration of the Python version to use + +On Debian type Linux distributions, you can use the following line in +your global or project specific `.Rprofile` file to tell the +`reticulate` package to use the system Python version that will find the +RDKit installed in the system location. + +``` R +Sys.setenv(RETICULATE_PYTHON="/usr/bin/python3") +``` + +# Package index + +## R6 Class definitions and methods + +- [`chent`](https://pkgdown.jrwb.de/chents/reference/chent.md) : An R6 + class for chemical entities with associated data +- [`pai`](https://pkgdown.jrwb.de/chents/reference/pai.md) : An R6 class + for pesticidal active ingredients and associated data +- [`ppp`](https://pkgdown.jrwb.de/chents/reference/ppp.md) : R6 class + for a plant protection product with at least one active ingredient +- [`draw_svg.chent()`](https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.md) + : Draw SVG graph from a chent object using RDKit +- [`plot(`*`<chent>`*`)`](https://pkgdown.jrwb.de/chents/reference/plot.chent.md) + : Plot method for chent objects +- [`print(`*`<chent>`*`)`](https://pkgdown.jrwb.de/chents/reference/print.chent.md) + : Printing method for chent objects +- [`print(`*`<pai>`*`)`](https://pkgdown.jrwb.de/chents/reference/print.pai.md) + : Printing method for pai objects (pesticidal active ingredients) +- [`print(`*`<ppp>`*`)`](https://pkgdown.jrwb.de/chents/reference/print.ppp.md) + : Printing method for ppp objects (plant protection products) + diff --git a/docs/news/index.html b/docs/news/index.html index fd27893..1020efc 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -58,7 +58,7 @@ </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer></div> diff --git a/docs/news/index.md b/docs/news/index.md new file mode 100644 index 0000000..32ad5c9 --- /dev/null +++ b/docs/news/index.md @@ -0,0 +1,37 @@ +# Changelog + +## version 0.4.1 + +- R/chent.R: Improve print method for `pai` objects. + +## version 0.4.0 + +- R/chent.R: PubChem has changed the names of the SMILES codes they + provide. The former isomeric smiles that was incorporated in our chent + objects as “Pubchem_Isomeric” is now simply calles SMILES, and is + incorporated in our objects as “PubChem”. The SMILES code formerly + given as “canonical” is now termed “connectivity SMILES” because it + does not contain isotopic or stereochemical specifications. In the + chents object, it is now available under the name + “PubChem_Connectivity”. This is a breaking change, so objects + generated with versions \< 0.4.0 may produce errors when used with + current versions. + +## version 0.3.7 + +- R/chent.R: Do not attempt to load a chyaml file per default, as the + format of such a file and the resulting chyaml list object is not + documented and would need to be inferred from its use in the pfm + package. + +## version 0.3.6 + +- R/chent.R: Set the fields `smiles`, `inchikey` and `mw` to NA if these + fields are still NULL at the end of the initialization, with `source` + attribute set to “user”, assuming that the initialisation was + carefully done and `pubchem` and `rdkit` were skipped because the + structure is not well-defined. + +Please refer to the ChangeLog for commit messages up to November 2021, +where I changed the GNUmakefile not to include commit messages in that +file any more. diff --git a/docs/reference/chent.html b/docs/reference/chent.html index 131d548..e2f241d 100644 --- a/docs/reference/chent.html +++ b/docs/reference/chent.html @@ -11,7 +11,7 @@ generated using RDKit if RDKit and its python bindings are installed."></head><b <a class="navbar-brand me-2" href="../index.html">chents</a> - <small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">0.4.0</small> + <small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">0.4.1</small> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation"> @@ -790,7 +790,9 @@ or according to Freundlich</p></dd> <div class="section level2"> <h2 id="ref-examples">Examples<a class="anchor" aria-label="anchor" href="#ref-examples"></a></h2> - <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="va">caffeine</span> <span class="op"><-</span> <span class="va">chent</span><span class="op">$</span><span class="fu">new</span><span class="op">(</span><span class="st">"caffeine"</span><span class="op">)</span></span></span> + <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="co"># Don't run examples per default, as PubChem may be unavailable</span></span></span> +<span class="r-in"><span><span class="co"># \dontrun{</span></span></span> +<span class="r-in"><span><span class="va">caffeine</span> <span class="op"><-</span> <span class="va">chent</span><span class="op">$</span><span class="fu">new</span><span class="op">(</span><span class="st">"caffeine"</span><span class="op">)</span></span></span> <span class="r-msg co"><span class="r-pr">#></span> Querying PubChem for name caffeine ...</span> <span class="r-msg co"><span class="r-pr">#></span> Get chemical information from RDKit using PubChem SMILES</span> <span class="r-msg co"><span class="r-pr">#></span> CN1C=NC2=C1C(=O)N(C(=O)N2C)C</span> @@ -807,7 +809,7 @@ or according to Freundlich</p></dd> <span class="r-out co"><span class="r-pr">#></span> [3] "Guaranine" "1,3,7-Trimethylxanthine"</span> <span class="r-out co"><span class="r-pr">#></span> [5] "Methyltheobromine" "Theine" </span> <span class="r-out co"><span class="r-pr">#></span> [7] "Thein" "Cafeina" </span> -<span class="r-out co"><span class="r-pr">#></span> [9] "Koffein" "Mateina" </span> +<span class="r-out co"><span class="r-pr">#></span> [9] "Caffein" "Cafipel" </span> <span class="r-in"><span><span class="kw">if</span> <span class="op">(</span><span class="op">!</span><span class="fu"><a href="https://rdrr.io/r/base/NULL.html" class="external-link">is.null</a></span><span class="op">(</span><span class="va">caffeine</span><span class="op">$</span><span class="va">Picture</span><span class="op">)</span><span class="op">)</span> <span class="op">{</span></span></span> <span class="r-in"><span> <span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">caffeine</span><span class="op">)</span></span></span> <span class="r-in"><span><span class="op">}</span></span></span> @@ -823,6 +825,7 @@ or according to Freundlich</p></dd> <span class="r-out co"><span class="r-pr">#></span> user </span> <span class="r-out co"><span class="r-pr">#></span> "CCCCCCCCO" </span> <span class="r-out co"><span class="r-pr">#></span> Molecular weight $mw: 130.2 </span> +<span class="r-in"><span><span class="co"># }</span></span></span> </code></pre></div> </div> </main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2> @@ -834,7 +837,7 @@ or according to Freundlich</p></dd> </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer></div> diff --git a/docs/reference/chent.md b/docs/reference/chent.md new file mode 100644 index 0000000..40716ce --- /dev/null +++ b/docs/reference/chent.md @@ -0,0 +1,802 @@ +# An R6 class for chemical entities with associated data + +The class is initialised with an identifier. Chemical information is +retrieved from the internet. Additionally, it can be generated using +RDKit if RDKit and its python bindings are installed. + +## Format + +An [R6::R6Class](https://r6.r-lib.org/reference/R6Class.html) generator +object + +## Public fields + +- `identifier`: + + (`character(1)`) + The identifier that was used to initiate the object, with attribute + 'source' + +- `inchikey`: + + (`character(1)`) + InChI Key, with attribute 'source' + +- `smiles`: + + ([`character()`](https://rdrr.io/r/base/character.html)) + SMILES code(s), with attribute 'source' + +- `mw`: + + (`numeric(1)`) + Molecular weight, with attribute 'source' + +- `pubchem`: + + ([`list()`](https://rdrr.io/r/base/list.html)) + List of information retrieved from PubChem + +- `rdkit`: + + List of information obtained with RDKit + +- `mol`: + + \<rdkit.Chem.rdchem.Mol\> object + +- `svg`: + + SVG code + +- `Picture`: + + Graph as a + [grImport::Picture](https://rdrr.io/pkg/grImport/man/Picture-class.html) + object obtained using the grImport package + +- `Pict_font_size`: + + Font size as extracted from the intermediate PostScript file + +- `pdf_height`: + + Height of the MediaBox in the pdf after cropping + +- `p0`: + + Vapour pressure in Pa + +- `cwsat`: + + Water solubility in mg/L + +- `PUF`: + + Plant uptake factor + +- `chyaml`: + + List of information obtained from a YAML file + +- `TPs`: + + List of transformation products as chent objects + +- `transformations`: + + Data frame of observed transformations + +- `soil_degradation`: + + Dataframe of modelling DT50 values + +- `soil_ff`: + + Dataframe of formation fractions + +- `soil_sorption`: + + Dataframe of soil sorption data + +## Methods + +### Public methods + +- [`chent$new()`](#method-chent-new) + +- [`chent$try_pubchem()`](#method-chent-try_pubchem) + +- [`chent$get_pubchem()`](#method-chent-get_pubchem) + +- [`chent$get_rdkit()`](#method-chent-get_rdkit) + +- [`chent$get_chyaml()`](#method-chent-get_chyaml) + +- [`chent$add_p0()`](#method-chent-add_p0) + +- [`chent$add_cwsat()`](#method-chent-add_cwsat) + +- [`chent$add_PUF()`](#method-chent-add_PUF) + +- [`chent$add_TP()`](#method-chent-add_TP) + +- [`chent$add_transformation()`](#method-chent-add_transformation) + +- [`chent$add_soil_degradation()`](#method-chent-add_soil_degradation) + +- [`chent$add_soil_ff()`](#method-chent-add_soil_ff) + +- [`chent$add_soil_sorption()`](#method-chent-add_soil_sorption) + +- [`chent$pdf()`](#method-chent-pdf) + +- [`chent$png()`](#method-chent-png) + +- [`chent$emf()`](#method-chent-emf) + +- [`chent$clone()`](#method-chent-clone) + +------------------------------------------------------------------------ + +### Method `new()` + +Creates a new instance of this +[R6](https://r6.r-lib.org/reference/R6Class.html) class. + +#### Usage + + chent$new( + identifier, + smiles = NULL, + inchikey = NULL, + pubchem = TRUE, + pubchem_from = c("name", "smiles", "inchikey"), + rdkit = TRUE, + template = NULL, + chyaml = FALSE + ) + +#### Arguments + +- `identifier`: + + Identifier to be stored in the object + +- `smiles`: + + Optional user provided SMILES code + +- `inchikey`: + + Optional user provided InChI Key + +- `pubchem`: + + Should an attempt be made to retrieve chemical information from + PubChem via the webchem package? + +- `pubchem_from`: + + Possibility to select the argument that is used to query pubchem + +- `rdkit`: + + Should an attempt be made to retrieve chemical information from a + local rdkit installation via python and the reticulate package? + +- `template`: + + An optional SMILES code to be used as template for RDKit + +- `chyaml`: + + Should we look for a identifier.yaml file in the working directory? + +------------------------------------------------------------------------ + +### Method `try_pubchem()` + +Try to get chemical information from PubChem + +#### Usage + + chent$try_pubchem(query = self$identifier, from = "name") + +#### Arguments + +- `query`: + + Query string to be passed to + [get_cid](https://docs.ropensci.org/webchem/reference/get_cid.html) + +- `from`: + + Passed to + [get_cid](https://docs.ropensci.org/webchem/reference/get_cid.html) + +------------------------------------------------------------------------ + +### Method `get_pubchem()` + +Get chemical information from PubChem for a known PubChem CID + +#### Usage + + chent$get_pubchem(pubchem_cid) + +#### Arguments + +- `pubchem_cid`: + + CID + +------------------------------------------------------------------------ + +### Method `get_rdkit()` + +Get chemical information from RDKit if available + +#### Usage + + chent$get_rdkit(template = NULL) + +#### Arguments + +- `template`: + + An optional SMILES code to be used as template for RDKit + +------------------------------------------------------------------------ + +### Method `get_chyaml()` + +Obtain information from a YAML file + +#### Usage + + chent$get_chyaml( + repo = c("wd", "local", "web"), + chyaml = paste0(URLencode(self$identifier), ".yaml") + ) + +#### Arguments + +- `repo`: + + Should the file be looked for in the current working directory, a + local git repository under `~/git/chyaml`, or from the web (not + implemented). + +- `chyaml`: + + The filename to be looked for + +------------------------------------------------------------------------ + +### Method `add_p0()` + +Add a vapour pressure + +#### Usage + + chent$add_p0(p0, T = NA, source = NA, page = NA, remark = "") + +#### Arguments + +- `p0`: + + The vapour pressure in Pa + +- `T`: + + Temperature + +- `source`: + + An acronym specifying the source of the information + +- `page`: + + The page from which the information was taken + +- `remark`: + + A remark + +------------------------------------------------------------------------ + +### Method `add_cwsat()` + +Add a water solubility + +#### Usage + + chent$add_cwsat(cwsat, T = NA, pH = NA, source = NA, page = NA, remark = "") + +#### Arguments + +- `cwsat`: + + The water solubility in mg/L + +- `T`: + + Temperature + +- `pH`: + + pH value + +- `source`: + + An acronym specifying the source of the information + +- `page`: + + The page from which the information was taken + +- `remark`: + + A remark + +------------------------------------------------------------------------ + +### Method `add_PUF()` + +Add a plant uptake factor + +#### Usage + + chent$add_PUF( + PUF = 0, + source = "focus_generic_gw_2014", + page = 41, + remark = "Conservative default value" + ) + +#### Arguments + +- `PUF`: + + The plant uptake factor, a number between 0 and 1 + +- `source`: + + An acronym specifying the source of the information + +- `page`: + + The page from which the information was taken + +- `remark`: + + A remark + +------------------------------------------------------------------------ + +### Method `add_TP()` + +Add a transformation product to the internal list + +#### Usage + + chent$add_TP(x, smiles = NULL, pubchem = FALSE) + +#### Arguments + +- `x`: + + A chent object, or an identifier to generate a chent object + +- `smiles`: + + Optional user provided SMILES code + +- `pubchem`: + + Should chemical information be obtained from PubChem? + +------------------------------------------------------------------------ + +### Method `add_transformation()` + +Add a line in the internal dataframe holding observed transformations + +#### Usage + + chent$add_transformation( + study_type, + TP_identifier, + max_occurrence, + remark = "", + source = NA, + pages = NA + ) + +#### Arguments + +- `study_type`: + + A characterisation of the study type + +- `TP_identifier`: + + An identifier of one of the transformation products in `self$TPs` + +- `max_occurrence`: + + The maximum observed occurrence of the transformation product, + expressed as a fraction of the amount that would result from + stochiometric transformation + +- `remark`: + + A remark + +- `source`: + + An acronym specifying the source of the information + +- `pages`: + + The pages from which the information was taken + +------------------------------------------------------------------------ + +### Method `add_soil_degradation()` + +Add a line in the internal dataframe holding modelling DT50 values + +#### Usage + + chent$add_soil_degradation( + soils, + DT50_mod, + DT50_mod_ref, + type = NA, + country = NA, + pH_orig = NA, + pH_medium = NA, + pH_H2O = NA, + perc_OC = NA, + temperature = NA, + moisture = NA, + category = "lab", + formulation = NA, + model = NA, + chi2 = NA, + remark = "", + source, + page = NA + ) + +#### Arguments + +- `soils`: + + Names of the soils + +- `DT50_mod`: + + The modelling DT50 in the sense of regulatory pesticide fate modelling + +- `DT50_mod_ref`: + + The normalised modelling DT50 in the sense of regulatory pesticide + fate modelling + +- `type`: + + The soil type + +- `country`: + + The country (mainly for field studies) + +- `pH_orig`: + + The pH stated in the study + +- `pH_medium`: + + The medium in which this pH was measured + +- `pH_H2O`: + + The pH extrapolated to pure water + +- `perc_OC`: + + The percentage of organic carbon in the soil + +- `temperature`: + + The temperature during the study in degrees Celsius + +- `moisture`: + + The moisture during the study + +- `category`: + + Is it a laboratory ('lab') or field study ('field') + +- `formulation`: + + Name of the formulation applied, if it was not the technical active + ingredient + +- `model`: + + The degradation model used for deriving `DT50_mod` + +- `chi2`: + + The relative error as defined in FOCUS kinetics + +- `remark`: + + A remark + +- `source`: + + An acronym specifying the source of the information + +- `page`: + + The page from which the information was taken + +------------------------------------------------------------------------ + +### Method `add_soil_ff()` + +Add one or more formation fractions for degradation in soil + +#### Usage + + chent$add_soil_ff(target, soils, ff = 1, remark = "", source, page = NA) + +#### Arguments + +- `target`: + + The identifier(s) of the transformation product + +- `soils`: + + The soil name(s) in which the transformation was observed + +- `ff`: + + The formation fraction(s) + +- `remark`: + + A remark + +- `source`: + + An acronym specifying the source of the information + +- `page`: + + The page from which the information was taken + +------------------------------------------------------------------------ + +### Method `add_soil_sorption()` + +Add soil sorption data + +#### Usage + + chent$add_soil_sorption( + soils, + Kf, + Kfoc, + N, + type = NA, + pH_orig = NA, + pH_medium = NA, + pH_H2O = NA, + perc_OC = NA, + perc_clay = NA, + CEC = NA, + remark = "", + source, + page = NA + ) + +#### Arguments + +- `soils`: + + Names of the soils + +- `Kf`: + + The sorption constant in L/kg, either linear (then `N` is 1) or + according to Freundlich + +- `Kfoc`: + + The constant from above, normalised to soil organic carbon + +- `N`: + + The Freundlich exponent + +- `type`: + + The soil type + +- `pH_orig`: + + The pH stated in the study + +- `pH_medium`: + + The medium in which this pH was measured + +- `pH_H2O`: + + The pH extrapolated to pure water + +- `perc_OC`: + + The percentage of organic carbon in the soil + +- `perc_clay`: + + The percentage of clay in the soil + +- `CEC`: + + The cation exchange capacity + +- `remark`: + + A remark + +- `source`: + + An acronym specifying the source of the information + +- `page`: + + The page from which the information was taken + +------------------------------------------------------------------------ + +### Method [`pdf()`](https://rdrr.io/r/grDevices/pdf.html) + +Write a PDF image of the structure + +#### Usage + + chent$pdf( + file = paste0(self$identifier, ".pdf"), + dir = "structures/pdf", + template = NULL + ) + +#### Arguments + +- `file`: + + The file to write to + +- `dir`: + + The directory to write the file to + +- `template`: + + An optional SMILES code to be used as template for RDKit + +------------------------------------------------------------------------ + +### Method [`png()`](https://rdrr.io/r/grDevices/png.html) + +Write a PNG image of the structure + +#### Usage + + chent$png( + file = paste0(self$identifier, ".png"), + dir = "structures/png", + antialias = "gray" + ) + +#### Arguments + +- `file`: + + The file to write to + +- `dir`: + + The directory to write the file to + +- `antialias`: + + Passed to [png](https://rdrr.io/r/grDevices/png.html) + +------------------------------------------------------------------------ + +### Method `emf()` + +Write an EMF image of the structure using +[emf](https://rdrr.io/pkg/devEMF/man/emf.html) + +#### Usage + + chent$emf(file = paste0(self$identifier, ".emf"), dir = "structures/emf") + +#### Arguments + +- `file`: + + The file to write to + +- `dir`: + + The directory to write the file to + +------------------------------------------------------------------------ + +### Method `clone()` + +The objects of this class are cloneable with this method. + +#### Usage + + chent$clone(deep = FALSE) + +#### Arguments + +- `deep`: + + Whether to make a deep clone. + +## Examples + +``` r +# Don't run examples per default, as PubChem may be unavailable +# \dontrun{ +caffeine <- chent$new("caffeine") +#> Querying PubChem for name caffeine ... +#> Get chemical information from RDKit using PubChem SMILES +#> CN1C=NC2=C1C(=O)N(C(=O)N2C)C +print(caffeine) +#> <chent> +#> Identifier $identifier caffeine +#> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N +#> SMILES string $smiles: +#> PubChem +#> "CN1C=NC2=C1C(=O)N(C(=O)N2C)C" +#> Molecular weight $mw: 194.2 +#> PubChem synonyms (up to 10): +#> [1] "caffeine" "58-08-2" +#> [3] "Guaranine" "1,3,7-Trimethylxanthine" +#> [5] "Methyltheobromine" "Theine" +#> [7] "Thein" "Cafeina" +#> [9] "Caffein" "Cafipel" +if (!is.null(caffeine$Picture)) { + plot(caffeine) +} + +oct <- chent$new("1-octanol", smiles = "CCCCCCCCO", pubchem = FALSE) +#> Get chemical information from RDKit using user SMILES +#> CCCCCCCCO +print(oct) +#> <chent> +#> Identifier $identifier 1-octanol +#> InChI Key $inchikey NA +#> SMILES string $smiles: +#> user +#> "CCCCCCCCO" +#> Molecular weight $mw: 130.2 +# } +``` diff --git a/docs/reference/draw_svg.chent.md b/docs/reference/draw_svg.chent.md new file mode 100644 index 0000000..7b43988 --- /dev/null +++ b/docs/reference/draw_svg.chent.md @@ -0,0 +1,37 @@ +# Draw SVG graph from a chent object using RDKit + +Draw SVG graph from a chent object using RDKit + +## Usage + +``` r +draw_svg.chent( + x, + width = 300, + height = 150, + filename = paste0(names(x$identifier), ".svg"), + subdir = "svg" +) +``` + +## Arguments + +- x: + + The chent object to be plotted + +- width: + + The desired width in pixels + +- height: + + The desired height in pixels + +- filename: + + The filename + +- subdir: + + The path to which the file should be written diff --git a/docs/reference/index.html b/docs/reference/index.html index a8a9c05..52b7cfb 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -36,8 +36,7 @@ - - </div><div class="section level2"> + <dl></dl></div><div class="section level2"> @@ -48,43 +47,50 @@ </dt> <dd>An R6 class for chemical entities with associated data</dd> - </dl><dl><dt> + + <dt> <code><a href="pai.html">pai</a></code> </dt> <dd>An R6 class for pesticidal active ingredients and associated data</dd> - </dl><dl><dt> + + <dt> <code><a href="ppp.html">ppp</a></code> </dt> <dd>R6 class for a plant protection product with at least one active ingredient</dd> - </dl><dl><dt> + + <dt> <code><a href="draw_svg.chent.html">draw_svg.chent()</a></code> </dt> <dd>Draw SVG graph from a chent object using RDKit</dd> - </dl><dl><dt> + + <dt> <code><a href="plot.chent.html">plot(<i><chent></i>)</a></code> </dt> <dd>Plot method for chent objects</dd> - </dl><dl><dt> + + <dt> <code><a href="print.chent.html">print(<i><chent></i>)</a></code> </dt> <dd>Printing method for chent objects</dd> - </dl><dl><dt> + + <dt> <code><a href="print.pai.html">print(<i><pai></i>)</a></code> </dt> <dd>Printing method for pai objects (pesticidal active ingredients)</dd> - </dl><dl><dt> + + <dt> <code><a href="print.ppp.html">print(<i><ppp></i>)</a></code> @@ -99,7 +105,7 @@ </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer></div> diff --git a/docs/reference/index.md b/docs/reference/index.md new file mode 100644 index 0000000..c927189 --- /dev/null +++ b/docs/reference/index.md @@ -0,0 +1,20 @@ +# Package index + +## R6 Class definitions and methods + +- [`chent`](https://pkgdown.jrwb.de/chents/reference/chent.md) : An R6 + class for chemical entities with associated data +- [`pai`](https://pkgdown.jrwb.de/chents/reference/pai.md) : An R6 class + for pesticidal active ingredients and associated data +- [`ppp`](https://pkgdown.jrwb.de/chents/reference/ppp.md) : R6 class + for a plant protection product with at least one active ingredient +- [`draw_svg.chent()`](https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.md) + : Draw SVG graph from a chent object using RDKit +- [`plot(`*`<chent>`*`)`](https://pkgdown.jrwb.de/chents/reference/plot.chent.md) + : Plot method for chent objects +- [`print(`*`<chent>`*`)`](https://pkgdown.jrwb.de/chents/reference/print.chent.md) + : Printing method for chent objects +- [`print(`*`<pai>`*`)`](https://pkgdown.jrwb.de/chents/reference/print.pai.md) + : Printing method for pai objects (pesticidal active ingredients) +- [`print(`*`<ppp>`*`)`](https://pkgdown.jrwb.de/chents/reference/print.ppp.md) + : Printing method for ppp objects (plant protection products) diff --git a/docs/reference/pai.html b/docs/reference/pai.html index 25ca564..29f9368 100644 --- a/docs/reference/pai.html +++ b/docs/reference/pai.html @@ -184,7 +184,9 @@ and the reticulate package?</p></dd> <div class="section level2"> <h2 id="ref-examples">Examples<a class="anchor" aria-label="anchor" href="#ref-examples"></a></h2> - <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="va">atr</span> <span class="op"><-</span> <span class="va">pai</span><span class="op">$</span><span class="fu">new</span><span class="op">(</span><span class="st">"atrazine"</span><span class="op">)</span></span></span> + <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="co"># Don't run examples per default, as PubChem may be unavailable</span></span></span> +<span class="r-in"><span><span class="co"># \dontrun{</span></span></span> +<span class="r-in"><span><span class="va">atr</span> <span class="op"><-</span> <span class="va">pai</span><span class="op">$</span><span class="fu">new</span><span class="op">(</span><span class="st">"atrazine"</span><span class="op">)</span></span></span> <span class="r-msg co"><span class="r-pr">#></span> Querying BCPC for atrazine ...</span> <span class="r-msg co"><span class="r-pr">#></span> Querying PubChem for inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N ...</span> <span class="r-msg co"><span class="r-pr">#></span> Get chemical information from RDKit using PubChem SMILES</span> @@ -225,6 +227,7 @@ and the reticulate package?</p></dd> <span class="r-out co"><span class="r-pr">#></span> [1] "1-DECANOL" "Decan-1-ol" "Decyl alcohol" "112-30-1" </span> <span class="r-out co"><span class="r-pr">#></span> [5] "n-Decyl alcohol" "n-Decanol" "Capric alcohol" "Nonylcarbinol" </span> <span class="r-out co"><span class="r-pr">#></span> [9] "Antak" "Royaltac" </span> +<span class="r-in"><span><span class="co"># }</span></span></span> </code></pre></div> </div> </main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2> @@ -236,7 +239,7 @@ and the reticulate package?</p></dd> </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer></div> diff --git a/docs/reference/pai.md b/docs/reference/pai.md new file mode 100644 index 0000000..2291653 --- /dev/null +++ b/docs/reference/pai.md @@ -0,0 +1,187 @@ +# An R6 class for pesticidal active ingredients and associated data + +This class is derived from +[chent](https://pkgdown.jrwb.de/chents/reference/chent.md). It makes it +easy to create a +[chent](https://pkgdown.jrwb.de/chents/reference/chent.md) from the ISO +common name of a pesticide active ingredient, and additionally stores +the ISO name as well as the complete result of querying the BCPC +compendium using +[bcpc_query](https://docs.ropensci.org/webchem/reference/bcpc_query.html). + +## Format + +An [R6::R6Class](https://r6.r-lib.org/reference/R6Class.html) generator +object + +## Super class + +[`chents::chent`](https://pkgdown.jrwb.de/chents/reference/chent.md) -\> +`pai` + +## Public fields + +- `iso`: + + ISO common name of the active ingredient according to ISO 1750 + +- `bcpc`: + + Information retrieved from the BCPC compendium available online at + \<pesticidecompendium.bcpc.org\> + +## Methods + +### Public methods + +- [`pai$new()`](#method-pai-new) + +- [`pai$clone()`](#method-pai-clone) + +Inherited methods + +- [`chents::chent$add_PUF()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_PUF) +- [`chents::chent$add_TP()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_TP) +- [`chents::chent$add_cwsat()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_cwsat) +- [`chents::chent$add_p0()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_p0) +- [`chents::chent$add_soil_degradation()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_soil_degradation) +- [`chents::chent$add_soil_ff()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_soil_ff) +- [`chents::chent$add_soil_sorption()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_soil_sorption) +- [`chents::chent$add_transformation()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-add_transformation) +- [`chents::chent$emf()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-emf) +- [`chents::chent$get_chyaml()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-get_chyaml) +- [`chents::chent$get_pubchem()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-get_pubchem) +- [`chents::chent$get_rdkit()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-get_rdkit) +- [`chents::chent$pdf()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-pdf) +- [`chents::chent$png()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-png) +- [`chents::chent$try_pubchem()`](https://pkgdown.jrwb.de/chents/reference/chent.html#method-try_pubchem) + +------------------------------------------------------------------------ + +### Method `new()` + +Create a new pai object + +#### Usage + + pai$new( + iso, + identifier = iso, + smiles = NULL, + inchikey = NULL, + bcpc = TRUE, + pubchem = TRUE, + pubchem_from = "auto", + rdkit = TRUE, + template = NULL, + chyaml = FALSE + ) + +#### Arguments + +- `iso`: + + The ISO common name to be used in the query of the BCPC compendium + +- `identifier`: + + Alternative identifier used for querying pubchem + +- `smiles`: + + Optional user provided SMILES code + +- `inchikey`: + + Optional user provided InChI Key + +- `bcpc`: + + Should the BCPC compendium be queried? + +- `pubchem`: + + Should an attempt be made to retrieve chemical information from + PubChem via the webchem package? + +- `pubchem_from`: + + Possibility to select the argument that is used to query pubchem + +- `rdkit`: + + Should an attempt be made to retrieve chemical information from a + local rdkit installation via python and the reticulate package? + +- `template`: + + An optional SMILES code to be used as template for RDKit + +- `chyaml`: + + Should we look for a identifier.yaml file in the working + +------------------------------------------------------------------------ + +### Method `clone()` + +The objects of this class are cloneable with this method. + +#### Usage + + pai$clone(deep = FALSE) + +#### Arguments + +- `deep`: + + Whether to make a deep clone. + +## Examples + +``` r +# Don't run examples per default, as PubChem may be unavailable +# \dontrun{ +atr <- pai$new("atrazine") +#> Querying BCPC for atrazine ... +#> Querying PubChem for inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N ... +#> Get chemical information from RDKit using PubChem SMILES +#> CCNC1=NC(=NC(=N1)Cl)NC(C)C +print(atr) +#> <pai> with ISO common name $iso atrazine +#> <chent> +#> Identifier $identifier atrazine +#> InChI Key $inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N +#> SMILES string $smiles: +#> PubChem +#> "CCNC1=NC(=NC(=N1)Cl)NC(C)C" +#> Molecular weight $mw: 215.7 +#> PubChem synonyms (up to 10): +#> [1] "atrazine" "1912-24-9" "Gesaprim" "Aatrex" "Atranex" +#> [6] "Atrazin" "Oleogesaprim" "Atazinax" "Atrasine" "Chromozin" +if (!is.null(atr$Picture)) { + plot(atr) +} + +# We can also define pais that are not found on the BCPC site +decanol <- pai$new("1-Decanol") +#> Querying BCPC for 1-Decanol ... +#> Common name 1-Decanol is not known at the BCPC compendium, trying PubChem +#> Querying PubChem for name 1-Decanol ... +#> Get chemical information from RDKit using PubChem SMILES +#> CCCCCCCCCCO +print(decanol) +#> <pai> without ISO common name +#> <chent> +#> Identifier $identifier 1-Decanol +#> InChI Key $inchikey MWKFXSUHUHTGQN-UHFFFAOYSA-N +#> SMILES string $smiles: +#> PubChem +#> "CCCCCCCCCCO" +#> Molecular weight $mw: 158.3 +#> PubChem synonyms (up to 10): +#> [1] "1-DECANOL" "Decan-1-ol" "Decyl alcohol" "112-30-1" +#> [5] "n-Decyl alcohol" "n-Decanol" "Capric alcohol" "Nonylcarbinol" +#> [9] "Antak" "Royaltac" +# } +``` diff --git a/docs/reference/plot.chent.html b/docs/reference/plot.chent.html index 49f54b2..c33b732 100644 --- a/docs/reference/plot.chent.html +++ b/docs/reference/plot.chent.html @@ -7,7 +7,7 @@ <a class="navbar-brand me-2" href="../index.html">chents</a> - <small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">0.4.0</small> + <small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">0.4.1</small> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation"> @@ -58,9 +58,11 @@ <div class="section level2"> <h2 id="ref-examples">Examples<a class="anchor" aria-label="anchor" href="#ref-examples"></a></h2> - <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="va">caffeine</span> <span class="op"><-</span> <span class="va"><a href="chent.html">chent</a></span><span class="op">$</span><span class="fu">new</span><span class="op">(</span><span class="st">"caffeine"</span><span class="op">)</span></span></span> -<span class="r-msg co"><span class="r-pr">#></span> PubChem:</span> -<span class="r-msg co"><span class="r-pr">#></span> Trying to get chemical information from RDKit using PubChem SMILES</span> + <div class="sourceCode"><pre class="sourceCode r"><code><span class="r-in"><span><span class="co"># Don't run examples per default, as PubChem may be unavailable</span></span></span> +<span class="r-in"><span><span class="co"># \dontrun{</span></span></span> +<span class="r-in"><span><span class="va">caffeine</span> <span class="op"><-</span> <span class="va"><a href="chent.html">chent</a></span><span class="op">$</span><span class="fu">new</span><span class="op">(</span><span class="st">"caffeine"</span><span class="op">)</span></span></span> +<span class="r-msg co"><span class="r-pr">#></span> Querying PubChem for name caffeine ...</span> +<span class="r-msg co"><span class="r-pr">#></span> Get chemical information from RDKit using PubChem SMILES</span> <span class="r-msg co"><span class="r-pr">#></span> CN1C=NC2=C1C(=O)N(C(=O)N2C)C</span> <span class="r-in"><span><span class="fu"><a href="https://rdrr.io/r/base/print.html" class="external-link">print</a></span><span class="op">(</span><span class="va">caffeine</span><span class="op">)</span></span></span> <span class="r-out co"><span class="r-pr">#></span> <chent></span> @@ -75,11 +77,12 @@ <span class="r-out co"><span class="r-pr">#></span> [3] "Guaranine" "1,3,7-Trimethylxanthine"</span> <span class="r-out co"><span class="r-pr">#></span> [5] "Methyltheobromine" "Theine" </span> <span class="r-out co"><span class="r-pr">#></span> [7] "Thein" "Cafeina" </span> -<span class="r-out co"><span class="r-pr">#></span> [9] "Koffein" "Mateina" </span> +<span class="r-out co"><span class="r-pr">#></span> [9] "Caffein" "Cafipel" </span> <span class="r-in"><span><span class="kw">if</span> <span class="op">(</span><span class="op">!</span><span class="fu"><a href="https://rdrr.io/r/base/NULL.html" class="external-link">is.null</a></span><span class="op">(</span><span class="va">caffeine</span><span class="op">$</span><span class="va">Picture</span><span class="op">)</span><span class="op">)</span> <span class="op">{</span></span></span> <span class="r-in"><span> <span class="fu"><a href="https://rdrr.io/r/graphics/plot.default.html" class="external-link">plot</a></span><span class="op">(</span><span class="va">caffeine</span><span class="op">)</span></span></span> <span class="r-in"><span><span class="op">}</span></span></span> <span class="r-plt img"><img src="plot.chent-1.png" alt="" width="700" height="433"></span> +<span class="r-in"><span><span class="co"># }</span></span></span> </code></pre></div> </div> </main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2> @@ -91,7 +94,7 @@ </div> <div class="pkgdown-footer-right"> - <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.1.3.</p> + <p>Site built with <a href="https://pkgdown.r-lib.org/" class="external-link">pkgdown</a> 2.2.0.</p> </div> </footer></div> diff --git a/docs/reference/plot.chent.md b/docs/reference/plot.chent.md new file mode 100644 index 0000000..eaa6817 --- /dev/null +++ b/docs/reference/plot.chent.md @@ -0,0 +1,51 @@ +# Plot method for chent objects + +Plot method for chent objects + +## Usage + +``` r +# S3 method for class 'chent' +plot(x, ...) +``` + +## Arguments + +- x: + + The chent object to be plotted + +- ...: + + Further arguments passed to + [grImport::grid.picture](https://rdrr.io/pkg/grImport/man/grid.picture.html) + +## Examples + +``` r +# Don't run examples per default, as PubChem may be unavailable +# \dontrun{ +caffeine <- chent$new("caffeine") +#> Querying PubChem for name caffeine ... +#> Get chemical information from RDKit using PubChem SMILES +#> CN1C=NC2=C1C(=O)N(C(=O)N2C)C +print(caffeine) +#> <chent> +#> Identifier $identifier caffeine +#> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N +#> SMILES string $smiles: +#> PubChem +#> "CN1C=NC2=C1C(=O)N(C(=O)N2C)C" +#> Molecular weight $mw: 194.2 +#> PubChem synonyms (up to 10): +#> [1] "caffeine" "58-08-2" +#> [3] "Guaranine" "1,3,7-Trimethylxanthine" +#> [5] "Methyltheobromine" "Theine" +#> [7] "Thein" "Cafeina" +#> [9] "Caffein" "Cafipel" +if (!is.null(caffeine$Picture)) { + plot(caffeine) +} + +# } +``` diff --git a/docs/reference/ppp.md b/docs/reference/ppp.md new file mode 100644 index 0000000..77ff2b6 --- /dev/null +++ b/docs/reference/ppp.md @@ -0,0 +1,102 @@ +# R6 class for a plant protection product with at least one active ingredient + +Contains basic information about the active ingredients in the product + +## Format + +An [R6::R6Class](https://r6.r-lib.org/reference/R6Class.html) generator +object. + +## Public fields + +- `name`: + + The name of the product + +- `ais`: + + A list of active ingredients + +- `concentrations`: + + The concentration of the ais + +- `concentration_units`: + + Defaults to g/L + +- `density`: + + The density of the product + +- `density_units`: + + Defaults to g/L + +## Methods + +### Public methods + +- [`ppp$new()`](#method-ppp-new) + +- [`ppp$clone()`](#method-ppp-clone) + +------------------------------------------------------------------------ + +### Method `new()` + +Creates a new instance of this +[R6](https://r6.r-lib.org/reference/R6Class.html) class. + +#### Usage + + ppp$new( + name, + ..., + concentrations, + concentration_units = "g/L", + density = 1000, + density_units = "g/L" + ) + +#### Arguments + +- `name`: + + The name of the product + +- `...`: + + Identifiers of the active ingredients + +- `concentrations`: + + Concentrations of the active ingredients + +- `concentration_units`: + + Defaults to g/L + +- `density`: + + The density + +- `density_units`: + + Defaults to g/L + +------------------------------------------------------------------------ + +### Method `clone()` + +The objects of this class are cloneable with this method. + +#### Usage + + ppp$clone(deep = FALSE) + +#### Arguments + +- `deep`: + + Whether to make a deep clone. diff --git a/docs/reference/print.chent.md b/docs/reference/print.chent.md new file mode 100644 index 0000000..f4d84bf --- /dev/null +++ b/docs/reference/print.chent.md @@ -0,0 +1,20 @@ +# Printing method for chent objects + +Printing method for chent objects + +## Usage + +``` r +# S3 method for class 'chent' +print(x, ...) +``` + +## Arguments + +- x: + + The chent object to be printed + +- ...: + + Further arguments for compatibility with the S3 method diff --git a/docs/reference/print.pai.md b/docs/reference/print.pai.md new file mode 100644 index 0000000..86cad4b --- /dev/null +++ b/docs/reference/print.pai.md @@ -0,0 +1,20 @@ +# Printing method for pai objects (pesticidal active ingredients) + +Printing method for pai objects (pesticidal active ingredients) + +## Usage + +``` r +# S3 method for class 'pai' +print(x, ...) +``` + +## Arguments + +- x: + + The chent object to be printed + +- ...: + + Further arguments for compatibility with the S3 method diff --git a/docs/reference/print.ppp.md b/docs/reference/print.ppp.md new file mode 100644 index 0000000..8387a54 --- /dev/null +++ b/docs/reference/print.ppp.md @@ -0,0 +1,20 @@ +# Printing method for ppp objects (plant protection products) + +Printing method for ppp objects (plant protection products) + +## Usage + +``` r +# S3 method for class 'ppp' +print(x, ...) +``` + +## Arguments + +- x: + + The chent object to be printed + +- ...: + + Further arguments for compatibility with the S3 method diff --git a/docs/search.json b/docs/search.json index 5f22f90..0312572 100644 --- a/docs/search.json +++ b/docs/search.json @@ -1 +1 @@ -[{"path":"https://pkgdown.jrwb.de/chents/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Johannes Ranke. Author, maintainer, copyright holder.","code":""},{"path":"https://pkgdown.jrwb.de/chents/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Ranke J (2026). chents: Chemical Entities R Objects. R package version 0.4.1, https://pkgdown.jrwb.de/chents.","code":"@Manual{, title = {chents: Chemical Entities as R Objects}, author = {Johannes Ranke}, year = {2026}, note = {R package version 0.4.1}, url = {https://pkgdown.jrwb.de/chents}, }"},{"path":"https://pkgdown.jrwb.de/chents/index.html","id":"chents","dir":"","previous_headings":"","what":"Chemical Entities as R Objects","title":"Chemical Entities as R Objects","text":"R package chents provides utilities working chemical entities R. first defining chemical entity, chemical information retrieved PubChem website using webchem package. Python RDKit (> 2015.03) installed configured use reticulate package, additional chemical information including 2D graph computed. print method gives overview information collected. simple plotting method chemical structure. Additional information can (rarely ever) read local .yaml file. information can leveraged e.g. PEC_soil function ‘pfm’ package. -called ISO common name pesticide active ingredient, can use ‘pai’ class derived ‘chent’ class, starts querying BCPC compendium first.","code":"library(chents) caffeine <- chent$new(\"caffeine\") #> Querying PubChem ... #> Trying to get chemical information from RDKit using PubChem SMILES #> CN1C=NC2=C1C(=O)N(C(=O)N2C)C print(caffeine) #> <chent> #> Identifier $identifier caffeine #> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CN1C=NC2=C1C(=O)N(C(=O)N2C)C\" #> Molecular weight $mw: 194.2 #> PubChem synonyms (up to 10): #> [1] \"caffeine\" \"58-08-2\" #> [3] \"Guaranine\" \"1,3,7-Trimethylxanthine\" #> [5] \"Methyltheobromine\" \"Theine\" #> [7] \"Thein\" \"Cafeina\" #> [9] \"Koffein\" \"Mateina\" plot(caffeine) lambda <- pai$new(\"lambda-cyhalothrin\") #> Querying BCPC for lambda-cyhalothrin ... #> Querying PubChem ... #> Trying to get chemical information from RDKit using PubChem SMILES #> CC1([C@@H]([C@@H]1C(=O)O[C@@H](C#N)C2=CC(=CC=C2)OC3=CC=CC=C3)/C=C(/C(F)(F)F)\\Cl)C #> RDKit mw is 449.856 #> mw is 449.8 plot(lambda)"},{"path":"https://pkgdown.jrwb.de/chents/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Chemical Entities as R Objects","text":"can conveniently install chents repository kindly made available R-Universe project: order profit chemoinformatics, need install RDKit python bindings. Debian type Linux distribution, just use use package Windows MacOS, happy include installation instructions share , e.g. via Pull Request.","code":"install.packages(\"chents\", repos = c(\"https://jranke.r-universe.dev\", \"https://cran.r-project.org\")) sudo apt install python3-rdkit"},{"path":"https://pkgdown.jrwb.de/chents/index.html","id":"configuration-of-the-python-version-to-use","dir":"","previous_headings":"","what":"Configuration of the Python version to use","title":"Chemical Entities as R Objects","text":"Debian type Linux distributions, can use following line global project specific .Rprofile file tell reticulate package use system Python version find RDKit installed system location.","code":"Sys.setenv(RETICULATE_PYTHON=\"/usr/bin/python3\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":null,"dir":"Reference","previous_headings":"","what":"An R6 class for chemical entities with associated data — chent","title":"An R6 class for chemical entities with associated data — chent","text":"class initialised identifier. Chemical information retrieved internet. Additionally, can generated using RDKit RDKit python bindings installed.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"An R6 class for chemical entities with associated data — chent","text":"R6::R6Class generator object","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"public-fields","dir":"Reference","previous_headings":"","what":"Public fields","title":"An R6 class for chemical entities with associated data — chent","text":"identifier (character(1)) identifier used initiate object, attribute 'source' inchikey (character(1)) InChI Key, attribute 'source' smiles (character()) SMILES code(s), attribute 'source' mw (numeric(1)) Molecular weight, attribute 'source' pubchem (list()) List information retrieved PubChem rdkit List information obtained RDKit mol <rdkit.Chem.rdchem.Mol> object svg SVG code Picture Graph grImport::Picture object obtained using grImport package Pict_font_size Font size extracted intermediate PostScript file pdf_height Height MediaBox pdf cropping p0 Vapour pressure Pa cwsat Water solubility mg/L PUF Plant uptake factor chyaml List information obtained YAML file TPs List transformation products chent objects transformations Data frame observed transformations soil_degradation Dataframe modelling DT50 values soil_ff Dataframe formation fractions soil_sorption Dataframe soil sorption data","code":""},{"path":[]},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"public-methods","dir":"Reference","previous_headings":"","what":"Public methods","title":"An R6 class for chemical entities with associated data — chent","text":"chent$new() chent$try_pubchem() chent$get_pubchem() chent$get_rdkit() chent$get_chyaml() chent$add_p0() chent$add_cwsat() chent$add_PUF() chent$add_TP() chent$add_transformation() chent$add_soil_degradation() chent$add_soil_ff() chent$add_soil_sorption() chent$pdf() chent$png() chent$emf() chent$clone()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-new-","dir":"Reference","previous_headings":"","what":"Method new()","title":"An R6 class for chemical entities with associated data — chent","text":"Creates new instance R6 class.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$new( identifier, smiles = NULL, inchikey = NULL, pubchem = TRUE, pubchem_from = c(\"name\", \"smiles\", \"inchikey\"), rdkit = TRUE, template = NULL, chyaml = FALSE )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"identifier Identifier stored object smiles Optional user provided SMILES code inchikey Optional user provided InChI Key pubchem attempt made retrieve chemical information PubChem via webchem package? pubchem_from Possibility select argument used query pubchem rdkit attempt made retrieve chemical information local rdkit installation via python reticulate package? template optional SMILES code used template RDKit chyaml look identifier.yaml file working directory?","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-try-pubchem-","dir":"Reference","previous_headings":"","what":"Method try_pubchem()","title":"An R6 class for chemical entities with associated data — chent","text":"Try get chemical information PubChem","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-1","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$try_pubchem(query = self$identifier, from = \"name\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-1","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"query Query string passed get_cid Passed get_cid","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-get-pubchem-","dir":"Reference","previous_headings":"","what":"Method get_pubchem()","title":"An R6 class for chemical entities with associated data — chent","text":"Get chemical information PubChem known PubChem CID","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-2","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$get_pubchem(pubchem_cid)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-2","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"pubchem_cid CID","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-get-rdkit-","dir":"Reference","previous_headings":"","what":"Method get_rdkit()","title":"An R6 class for chemical entities with associated data — chent","text":"Get chemical information RDKit available","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-3","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$get_rdkit(template = NULL)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-3","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"template optional SMILES code used template RDKit","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-get-chyaml-","dir":"Reference","previous_headings":"","what":"Method get_chyaml()","title":"An R6 class for chemical entities with associated data — chent","text":"Obtain information YAML file","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-4","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$get_chyaml( repo = c(\"wd\", \"local\", \"web\"), chyaml = paste0(URLencode(self$identifier), \".yaml\") )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-4","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"repo file looked current working directory, local git repository ~/git/chyaml, web (implemented). chyaml filename looked ","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-p-","dir":"Reference","previous_headings":"","what":"Method add_p0()","title":"An R6 class for chemical entities with associated data — chent","text":"Add vapour pressure","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-5","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_p0(p0, T = NA, source = NA, page = NA, remark = \"\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-5","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"p0 vapour pressure Pa T Temperature source acronym specifying source information page page information taken remark remark","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-cwsat-","dir":"Reference","previous_headings":"","what":"Method add_cwsat()","title":"An R6 class for chemical entities with associated data — chent","text":"Add water solubility","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-6","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_cwsat(cwsat, T = NA, pH = NA, source = NA, page = NA, remark = \"\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-6","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"cwsat water solubility mg/L T Temperature pH pH value source acronym specifying source information page page information taken remark remark","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-puf-","dir":"Reference","previous_headings":"","what":"Method add_PUF()","title":"An R6 class for chemical entities with associated data — chent","text":"Add plant uptake factor","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-7","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_PUF( PUF = 0, source = \"focus_generic_gw_2014\", page = 41, remark = \"Conservative default value\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-7","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"PUF plant uptake factor, number 0 1 source acronym specifying source information page page information taken remark remark","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-tp-","dir":"Reference","previous_headings":"","what":"Method add_TP()","title":"An R6 class for chemical entities with associated data — chent","text":"Add transformation product internal list","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-8","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_TP(x, smiles = NULL, pubchem = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-8","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"x chent object, identifier generate chent object smiles Optional user provided SMILES code pubchem chemical information obtained PubChem?","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-transformation-","dir":"Reference","previous_headings":"","what":"Method add_transformation()","title":"An R6 class for chemical entities with associated data — chent","text":"Add line internal dataframe holding observed transformations","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-9","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_transformation( study_type, TP_identifier, max_occurrence, remark = \"\", source = NA, pages = NA )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-9","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"study_type characterisation study type TP_identifier identifier one transformation products self$TPs max_occurrence maximum observed occurrence transformation product, expressed fraction amount result stochiometric transformation remark remark source acronym specifying source information pages pages information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-soil-degradation-","dir":"Reference","previous_headings":"","what":"Method add_soil_degradation()","title":"An R6 class for chemical entities with associated data — chent","text":"Add line internal dataframe holding modelling DT50 values","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-10","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_soil_degradation( soils, DT50_mod, DT50_mod_ref, type = NA, country = NA, pH_orig = NA, pH_medium = NA, pH_H2O = NA, perc_OC = NA, temperature = NA, moisture = NA, category = \"lab\", formulation = NA, model = NA, chi2 = NA, remark = \"\", source, page = NA )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-10","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"soils Names soils DT50_mod modelling DT50 sense regulatory pesticide fate modelling DT50_mod_ref normalised modelling DT50 sense regulatory pesticide fate modelling type soil type country country (mainly field studies) pH_orig pH stated study pH_medium medium pH measured pH_H2O pH extrapolated pure water perc_OC percentage organic carbon soil temperature temperature study degrees Celsius moisture moisture study category laboratory ('lab') field study ('field') formulation Name formulation applied, technical active ingredient model degradation model used deriving DT50_mod chi2 relative error defined FOCUS kinetics remark remark source acronym specifying source information page page information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-soil-ff-","dir":"Reference","previous_headings":"","what":"Method add_soil_ff()","title":"An R6 class for chemical entities with associated data — chent","text":"Add one formation fractions degradation soil","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-11","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_soil_ff(target, soils, ff = 1, remark = \"\", source, page = NA)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-11","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"target identifier(s) transformation product soils soil name(s) transformation observed ff formation fraction(s) remark remark source acronym specifying source information page page information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-soil-sorption-","dir":"Reference","previous_headings":"","what":"Method add_soil_sorption()","title":"An R6 class for chemical entities with associated data — chent","text":"Add soil sorption data","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-12","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_soil_sorption( soils, Kf, Kfoc, N, type = NA, pH_orig = NA, pH_medium = NA, pH_H2O = NA, perc_OC = NA, perc_clay = NA, CEC = NA, remark = \"\", source, page = NA )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-12","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"soils Names soils Kf sorption constant L/kg, either linear (N 1) according Freundlich Kfoc constant , normalised soil organic carbon N Freundlich exponent type soil type pH_orig pH stated study pH_medium medium pH measured pH_H2O pH extrapolated pure water perc_OC percentage organic carbon soil perc_clay percentage clay soil CEC cation exchange capacity remark remark source acronym specifying source information page page information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-pdf-","dir":"Reference","previous_headings":"","what":"Method pdf()","title":"An R6 class for chemical entities with associated data — chent","text":"Write PDF image structure","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-13","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$pdf( file = paste0(self$identifier, \".pdf\"), dir = \"structures/pdf\", template = NULL )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-13","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"file file write dir directory write file template optional SMILES code used template RDKit","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-png-","dir":"Reference","previous_headings":"","what":"Method png()","title":"An R6 class for chemical entities with associated data — chent","text":"Write PNG image structure","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-14","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$png( file = paste0(self$identifier, \".png\"), dir = \"structures/png\", antialias = \"gray\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-14","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"file file write dir directory write file antialias Passed png","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-emf-","dir":"Reference","previous_headings":"","what":"Method emf()","title":"An R6 class for chemical entities with associated data — chent","text":"Write EMF image structure using emf","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-15","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$emf(file = paste0(self$identifier, \".emf\"), dir = \"structures/emf\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-15","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"file file write dir directory write file ","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-clone-","dir":"Reference","previous_headings":"","what":"Method clone()","title":"An R6 class for chemical entities with associated data — chent","text":"objects class cloneable method.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-16","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$clone(deep = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-16","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"deep Whether make deep clone.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"caffeine <- chent$new(\"caffeine\") #> Querying PubChem for name caffeine ... #> Get chemical information from RDKit using PubChem SMILES #> CN1C=NC2=C1C(=O)N(C(=O)N2C)C print(caffeine) #> <chent> #> Identifier $identifier caffeine #> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CN1C=NC2=C1C(=O)N(C(=O)N2C)C\" #> Molecular weight $mw: 194.2 #> PubChem synonyms (up to 10): #> [1] \"caffeine\" \"58-08-2\" #> [3] \"Guaranine\" \"1,3,7-Trimethylxanthine\" #> [5] \"Methyltheobromine\" \"Theine\" #> [7] \"Thein\" \"Cafeina\" #> [9] \"Koffein\" \"Mateina\" if (!is.null(caffeine$Picture)) { plot(caffeine) } oct <- chent$new(\"1-octanol\", smiles = \"CCCCCCCCO\", pubchem = FALSE) #> Get chemical information from RDKit using user SMILES #> CCCCCCCCO print(oct) #> <chent> #> Identifier $identifier 1-octanol #> InChI Key $inchikey NA #> SMILES string $smiles: #> user #> \"CCCCCCCCO\" #> Molecular weight $mw: 130.2"},{"path":"https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.html","id":null,"dir":"Reference","previous_headings":"","what":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","title":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","text":"Draw SVG graph chent object using RDKit","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","text":"","code":"draw_svg.chent( x, width = 300, height = 150, filename = paste0(names(x$identifier), \".svg\"), subdir = \"svg\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","text":"x chent object plotted width desired width pixels height desired height pixels filename filename subdir path file written","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":null,"dir":"Reference","previous_headings":"","what":"An R6 class for pesticidal active ingredients and associated data — pai","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"class derived chent. makes easy create chent ISO common name pesticide active ingredient, additionally stores ISO name well complete result querying BCPC compendium using bcpc_query.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"R6::R6Class generator object","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"super-class","dir":"Reference","previous_headings":"","what":"Super class","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"chents::chent -> pai","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"public-fields","dir":"Reference","previous_headings":"","what":"Public fields","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"iso ISO common name active ingredient according ISO 1750 bcpc Information retrieved BCPC compendium available online <pesticidecompendium.bcpc.org>","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"methods","dir":"Reference","previous_headings":"","what":"Methods","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"chents::chent$add_PUF() chents::chent$add_TP() chents::chent$add_cwsat() chents::chent$add_p0() chents::chent$add_soil_degradation() chents::chent$add_soil_ff() chents::chent$add_soil_sorption() chents::chent$add_transformation() chents::chent$emf() chents::chent$get_chyaml() chents::chent$get_pubchem() chents::chent$get_rdkit() chents::chent$pdf() chents::chent$png() chents::chent$try_pubchem()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"public-methods","dir":"Reference","previous_headings":"","what":"Public methods","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"pai$new() pai$clone()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"method-new-","dir":"Reference","previous_headings":"","what":"Method new()","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"Create new pai object","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"usage","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"","code":"pai$new( iso, identifier = iso, smiles = NULL, inchikey = NULL, bcpc = TRUE, pubchem = TRUE, pubchem_from = \"auto\", rdkit = TRUE, template = NULL, chyaml = FALSE )"},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"iso ISO common name used query BCPC compendium identifier Alternative identifier used querying pubchem smiles Optional user provided SMILES code inchikey Optional user provided InChI Key bcpc BCPC compendium queried? pubchem attempt made retrieve chemical information PubChem via webchem package? pubchem_from Possibility select argument used query pubchem rdkit attempt made retrieve chemical information local rdkit installation via python reticulate package? template optional SMILES code used template RDKit chyaml look identifier.yaml file working","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"method-clone-","dir":"Reference","previous_headings":"","what":"Method clone()","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"objects class cloneable method.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"usage-1","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"","code":"pai$clone(deep = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"arguments-1","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"deep Whether make deep clone.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"","code":"atr <- pai$new(\"atrazine\") #> Querying BCPC for atrazine ... #> Querying PubChem for inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N ... #> Get chemical information from RDKit using PubChem SMILES #> CCNC1=NC(=NC(=N1)Cl)NC(C)C print(atr) #> <pai> with ISO common name $iso atrazine #> <chent> #> Identifier $identifier atrazine #> InChI Key $inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CCNC1=NC(=NC(=N1)Cl)NC(C)C\" #> Molecular weight $mw: 215.7 #> PubChem synonyms (up to 10): #> [1] \"atrazine\" \"1912-24-9\" \"Gesaprim\" \"Aatrex\" \"Atranex\" #> [6] \"Atrazin\" \"Oleogesaprim\" \"Atazinax\" \"Atrasine\" \"Chromozin\" if (!is.null(atr$Picture)) { plot(atr) } # We can also define pais that are not found on the BCPC site decanol <- pai$new(\"1-Decanol\") #> Querying BCPC for 1-Decanol ... #> Common name 1-Decanol is not known at the BCPC compendium, trying PubChem #> Querying PubChem for name 1-Decanol ... #> Get chemical information from RDKit using PubChem SMILES #> CCCCCCCCCCO print(decanol) #> <pai> without ISO common name #> <chent> #> Identifier $identifier 1-Decanol #> InChI Key $inchikey MWKFXSUHUHTGQN-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CCCCCCCCCCO\" #> Molecular weight $mw: 158.3 #> PubChem synonyms (up to 10): #> [1] \"1-DECANOL\" \"Decan-1-ol\" \"Decyl alcohol\" \"112-30-1\" #> [5] \"n-Decyl alcohol\" \"n-Decanol\" \"Capric alcohol\" \"Nonylcarbinol\" #> [9] \"Antak\" \"Royaltac\""},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot method for chent objects — plot.chent","title":"Plot method for chent objects — plot.chent","text":"Plot method chent objects","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot method for chent objects — plot.chent","text":"","code":"# S3 method for class 'chent' plot(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot method for chent objects — plot.chent","text":"x chent object plotted ... arguments passed grImport::grid.picture","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Plot method for chent objects — plot.chent","text":"","code":"caffeine <- chent$new(\"caffeine\") #> PubChem: #> Trying to get chemical information from RDKit using PubChem SMILES #> CN1C=NC2=C1C(=O)N(C(=O)N2C)C print(caffeine) #> <chent> #> Identifier $identifier caffeine #> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CN1C=NC2=C1C(=O)N(C(=O)N2C)C\" #> Molecular weight $mw: 194.2 #> PubChem synonyms (up to 10): #> [1] \"caffeine\" \"58-08-2\" #> [3] \"Guaranine\" \"1,3,7-Trimethylxanthine\" #> [5] \"Methyltheobromine\" \"Theine\" #> [7] \"Thein\" \"Cafeina\" #> [9] \"Koffein\" \"Mateina\" if (!is.null(caffeine$Picture)) { plot(caffeine) }"},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":null,"dir":"Reference","previous_headings":"","what":"R6 class for a plant protection product with at least one active ingredient — ppp","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"Contains basic information active ingredients product","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"R6::R6Class generator object.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"public-fields","dir":"Reference","previous_headings":"","what":"Public fields","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"name name product ais list active ingredients concentrations concentration ais concentration_units Defaults g/L density density product density_units Defaults g/L","code":""},{"path":[]},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"public-methods","dir":"Reference","previous_headings":"","what":"Public methods","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"ppp$new() ppp$clone()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"method-new-","dir":"Reference","previous_headings":"","what":"Method new()","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"Creates new instance R6 class.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"usage","dir":"Reference","previous_headings":"","what":"Usage","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"","code":"ppp$new( name, ..., concentrations, concentration_units = \"g/L\", density = 1000, density_units = \"g/L\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"name name product ... Identifiers active ingredients concentrations Concentrations active ingredients concentration_units Defaults g/L density density density_units Defaults g/L","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"method-clone-","dir":"Reference","previous_headings":"","what":"Method clone()","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"objects class cloneable method.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"usage-1","dir":"Reference","previous_headings":"","what":"Usage","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"","code":"ppp$clone(deep = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"arguments-1","dir":"Reference","previous_headings":"","what":"Arguments","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"deep Whether make deep clone.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.chent.html","id":null,"dir":"Reference","previous_headings":"","what":"Printing method for chent objects — print.chent","title":"Printing method for chent objects — print.chent","text":"Printing method chent objects","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.chent.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Printing method for chent objects — print.chent","text":"","code":"# S3 method for class 'chent' print(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/print.chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Printing method for chent objects — print.chent","text":"x chent object printed ... arguments compatibility S3 method","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.pai.html","id":null,"dir":"Reference","previous_headings":"","what":"Printing method for pai objects (pesticidal active ingredients) — print.pai","title":"Printing method for pai objects (pesticidal active ingredients) — print.pai","text":"Printing method pai objects (pesticidal active ingredients)","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.pai.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Printing method for pai objects (pesticidal active ingredients) — print.pai","text":"","code":"# S3 method for class 'pai' print(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/print.pai.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Printing method for pai objects (pesticidal active ingredients) — print.pai","text":"x chent object printed ... arguments compatibility S3 method","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.ppp.html","id":null,"dir":"Reference","previous_headings":"","what":"Printing method for ppp objects (plant protection products) — print.ppp","title":"Printing method for ppp objects (plant protection products) — print.ppp","text":"Printing method ppp objects (plant protection products)","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.ppp.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Printing method for ppp objects (plant protection products) — print.ppp","text":"","code":"# S3 method for class 'ppp' print(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/print.ppp.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Printing method for ppp objects (plant protection products) — print.ppp","text":"x chent object printed ... arguments compatibility S3 method","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-041","dir":"Changelog","previous_headings":"","what":"version 0.4.1","title":"version 0.4.1","text":"R/chent.R: Improve print method pai objects.","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-040","dir":"Changelog","previous_headings":"","what":"version 0.4.0","title":"version 0.4.0","text":"R/chent.R: PubChem changed names SMILES codes provide. former isomeric smiles incorporated chent objects “Pubchem_Isomeric” now simply calles SMILES, incorporated objects “PubChem”. SMILES code formerly given “canonical” now termed “connectivity SMILES” contain isotopic stereochemical specifications. chents object, now available name “PubChem_Connectivity”. breaking change, objects generated versions < 0.4.0 may produce errors used current versions.","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-037","dir":"Changelog","previous_headings":"","what":"version 0.3.7","title":"version 0.3.7","text":"R/chent.R: attempt load chyaml file per default, format file resulting chyaml list object documented need inferred use pfm package.","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-036","dir":"Changelog","previous_headings":"","what":"version 0.3.6","title":"version 0.3.6","text":"R/chent.R: Set fields smiles, inchikey mw NA fields still NULL end initialization, source attribute set “user”, assuming initialisation carefully done pubchem rdkit skipped structure well-defined. Please refer ChangeLog commit messages November 2021, changed GNUmakefile include commit messages file .","code":""}] +[{"path":"https://pkgdown.jrwb.de/chents/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Johannes Ranke. Author, maintainer, copyright holder.","code":""},{"path":"https://pkgdown.jrwb.de/chents/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Ranke J (2026). chents: Chemical Entities R Objects. R package version 0.4.1, https://pkgdown.jrwb.de/chents.","code":"@Manual{, title = {chents: Chemical Entities as R Objects}, author = {Johannes Ranke}, year = {2026}, note = {R package version 0.4.1}, url = {https://pkgdown.jrwb.de/chents}, }"},{"path":"https://pkgdown.jrwb.de/chents/index.html","id":"chents","dir":"","previous_headings":"","what":"Chemical Entities as R Objects","title":"Chemical Entities as R Objects","text":"R package chents provides utilities working chemical entities R. first defining chemical entity, chemical information retrieved PubChem website using webchem package. Python RDKit (> 2015.03) installed configured use reticulate package, additional chemical information including 2D graph computed. print method gives overview information collected. simple plotting method chemical structure. Additional information can (rarely ever) read local .yaml file. information can leveraged e.g. PEC_soil function ‘pfm’ package. -called ISO common name pesticide active ingredient, can use ‘pai’ class derived ‘chent’ class, starts querying BCPC compendium first.","code":"library(chents) caffeine <- chent$new(\"caffeine\") #> Querying PubChem ... #> Trying to get chemical information from RDKit using PubChem SMILES #> CN1C=NC2=C1C(=O)N(C(=O)N2C)C print(caffeine) #> <chent> #> Identifier $identifier caffeine #> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CN1C=NC2=C1C(=O)N(C(=O)N2C)C\" #> Molecular weight $mw: 194.2 #> PubChem synonyms (up to 10): #> [1] \"caffeine\" \"58-08-2\" #> [3] \"Guaranine\" \"1,3,7-Trimethylxanthine\" #> [5] \"Methyltheobromine\" \"Theine\" #> [7] \"Thein\" \"Cafeina\" #> [9] \"Koffein\" \"Mateina\" plot(caffeine) lambda <- pai$new(\"lambda-cyhalothrin\") #> Querying BCPC for lambda-cyhalothrin ... #> Querying PubChem ... #> Trying to get chemical information from RDKit using PubChem SMILES #> CC1([C@@H]([C@@H]1C(=O)O[C@@H](C#N)C2=CC(=CC=C2)OC3=CC=CC=C3)/C=C(/C(F)(F)F)\\Cl)C #> RDKit mw is 449.856 #> mw is 449.8 plot(lambda)"},{"path":"https://pkgdown.jrwb.de/chents/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Chemical Entities as R Objects","text":"can conveniently install chents repository kindly made available R-Universe project: order profit chemoinformatics, need install RDKit python bindings. Debian type Linux distribution, just use use package Windows MacOS, happy include installation instructions share , e.g. via Pull Request.","code":"install.packages(\"chents\", repos = c(\"https://jranke.r-universe.dev\", \"https://cran.r-project.org\")) sudo apt install python3-rdkit"},{"path":"https://pkgdown.jrwb.de/chents/index.html","id":"configuration-of-the-python-version-to-use","dir":"","previous_headings":"","what":"Configuration of the Python version to use","title":"Chemical Entities as R Objects","text":"Debian type Linux distributions, can use following line global project specific .Rprofile file tell reticulate package use system Python version find RDKit installed system location.","code":"Sys.setenv(RETICULATE_PYTHON=\"/usr/bin/python3\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":null,"dir":"Reference","previous_headings":"","what":"An R6 class for chemical entities with associated data — chent","title":"An R6 class for chemical entities with associated data — chent","text":"class initialised identifier. Chemical information retrieved internet. Additionally, can generated using RDKit RDKit python bindings installed.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"An R6 class for chemical entities with associated data — chent","text":"R6::R6Class generator object","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"public-fields","dir":"Reference","previous_headings":"","what":"Public fields","title":"An R6 class for chemical entities with associated data — chent","text":"identifier (character(1)) identifier used initiate object, attribute 'source' inchikey (character(1)) InChI Key, attribute 'source' smiles (character()) SMILES code(s), attribute 'source' mw (numeric(1)) Molecular weight, attribute 'source' pubchem (list()) List information retrieved PubChem rdkit List information obtained RDKit mol <rdkit.Chem.rdchem.Mol> object svg SVG code Picture Graph grImport::Picture object obtained using grImport package Pict_font_size Font size extracted intermediate PostScript file pdf_height Height MediaBox pdf cropping p0 Vapour pressure Pa cwsat Water solubility mg/L PUF Plant uptake factor chyaml List information obtained YAML file TPs List transformation products chent objects transformations Data frame observed transformations soil_degradation Dataframe modelling DT50 values soil_ff Dataframe formation fractions soil_sorption Dataframe soil sorption data","code":""},{"path":[]},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"public-methods","dir":"Reference","previous_headings":"","what":"Public methods","title":"An R6 class for chemical entities with associated data — chent","text":"chent$new() chent$try_pubchem() chent$get_pubchem() chent$get_rdkit() chent$get_chyaml() chent$add_p0() chent$add_cwsat() chent$add_PUF() chent$add_TP() chent$add_transformation() chent$add_soil_degradation() chent$add_soil_ff() chent$add_soil_sorption() chent$pdf() chent$png() chent$emf() chent$clone()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-new-","dir":"Reference","previous_headings":"","what":"Method new()","title":"An R6 class for chemical entities with associated data — chent","text":"Creates new instance R6 class.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$new( identifier, smiles = NULL, inchikey = NULL, pubchem = TRUE, pubchem_from = c(\"name\", \"smiles\", \"inchikey\"), rdkit = TRUE, template = NULL, chyaml = FALSE )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"identifier Identifier stored object smiles Optional user provided SMILES code inchikey Optional user provided InChI Key pubchem attempt made retrieve chemical information PubChem via webchem package? pubchem_from Possibility select argument used query pubchem rdkit attempt made retrieve chemical information local rdkit installation via python reticulate package? template optional SMILES code used template RDKit chyaml look identifier.yaml file working directory?","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-try-pubchem-","dir":"Reference","previous_headings":"","what":"Method try_pubchem()","title":"An R6 class for chemical entities with associated data — chent","text":"Try get chemical information PubChem","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-1","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$try_pubchem(query = self$identifier, from = \"name\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-1","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"query Query string passed get_cid Passed get_cid","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-get-pubchem-","dir":"Reference","previous_headings":"","what":"Method get_pubchem()","title":"An R6 class for chemical entities with associated data — chent","text":"Get chemical information PubChem known PubChem CID","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-2","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$get_pubchem(pubchem_cid)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-2","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"pubchem_cid CID","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-get-rdkit-","dir":"Reference","previous_headings":"","what":"Method get_rdkit()","title":"An R6 class for chemical entities with associated data — chent","text":"Get chemical information RDKit available","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-3","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$get_rdkit(template = NULL)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-3","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"template optional SMILES code used template RDKit","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-get-chyaml-","dir":"Reference","previous_headings":"","what":"Method get_chyaml()","title":"An R6 class for chemical entities with associated data — chent","text":"Obtain information YAML file","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-4","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$get_chyaml( repo = c(\"wd\", \"local\", \"web\"), chyaml = paste0(URLencode(self$identifier), \".yaml\") )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-4","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"repo file looked current working directory, local git repository ~/git/chyaml, web (implemented). chyaml filename looked ","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-p-","dir":"Reference","previous_headings":"","what":"Method add_p0()","title":"An R6 class for chemical entities with associated data — chent","text":"Add vapour pressure","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-5","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_p0(p0, T = NA, source = NA, page = NA, remark = \"\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-5","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"p0 vapour pressure Pa T Temperature source acronym specifying source information page page information taken remark remark","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-cwsat-","dir":"Reference","previous_headings":"","what":"Method add_cwsat()","title":"An R6 class for chemical entities with associated data — chent","text":"Add water solubility","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-6","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_cwsat(cwsat, T = NA, pH = NA, source = NA, page = NA, remark = \"\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-6","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"cwsat water solubility mg/L T Temperature pH pH value source acronym specifying source information page page information taken remark remark","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-puf-","dir":"Reference","previous_headings":"","what":"Method add_PUF()","title":"An R6 class for chemical entities with associated data — chent","text":"Add plant uptake factor","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-7","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_PUF( PUF = 0, source = \"focus_generic_gw_2014\", page = 41, remark = \"Conservative default value\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-7","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"PUF plant uptake factor, number 0 1 source acronym specifying source information page page information taken remark remark","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-tp-","dir":"Reference","previous_headings":"","what":"Method add_TP()","title":"An R6 class for chemical entities with associated data — chent","text":"Add transformation product internal list","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-8","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_TP(x, smiles = NULL, pubchem = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-8","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"x chent object, identifier generate chent object smiles Optional user provided SMILES code pubchem chemical information obtained PubChem?","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-transformation-","dir":"Reference","previous_headings":"","what":"Method add_transformation()","title":"An R6 class for chemical entities with associated data — chent","text":"Add line internal dataframe holding observed transformations","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-9","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_transformation( study_type, TP_identifier, max_occurrence, remark = \"\", source = NA, pages = NA )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-9","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"study_type characterisation study type TP_identifier identifier one transformation products self$TPs max_occurrence maximum observed occurrence transformation product, expressed fraction amount result stochiometric transformation remark remark source acronym specifying source information pages pages information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-soil-degradation-","dir":"Reference","previous_headings":"","what":"Method add_soil_degradation()","title":"An R6 class for chemical entities with associated data — chent","text":"Add line internal dataframe holding modelling DT50 values","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-10","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_soil_degradation( soils, DT50_mod, DT50_mod_ref, type = NA, country = NA, pH_orig = NA, pH_medium = NA, pH_H2O = NA, perc_OC = NA, temperature = NA, moisture = NA, category = \"lab\", formulation = NA, model = NA, chi2 = NA, remark = \"\", source, page = NA )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-10","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"soils Names soils DT50_mod modelling DT50 sense regulatory pesticide fate modelling DT50_mod_ref normalised modelling DT50 sense regulatory pesticide fate modelling type soil type country country (mainly field studies) pH_orig pH stated study pH_medium medium pH measured pH_H2O pH extrapolated pure water perc_OC percentage organic carbon soil temperature temperature study degrees Celsius moisture moisture study category laboratory ('lab') field study ('field') formulation Name formulation applied, technical active ingredient model degradation model used deriving DT50_mod chi2 relative error defined FOCUS kinetics remark remark source acronym specifying source information page page information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-soil-ff-","dir":"Reference","previous_headings":"","what":"Method add_soil_ff()","title":"An R6 class for chemical entities with associated data — chent","text":"Add one formation fractions degradation soil","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-11","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_soil_ff(target, soils, ff = 1, remark = \"\", source, page = NA)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-11","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"target identifier(s) transformation product soils soil name(s) transformation observed ff formation fraction(s) remark remark source acronym specifying source information page page information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-add-soil-sorption-","dir":"Reference","previous_headings":"","what":"Method add_soil_sorption()","title":"An R6 class for chemical entities with associated data — chent","text":"Add soil sorption data","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-12","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$add_soil_sorption( soils, Kf, Kfoc, N, type = NA, pH_orig = NA, pH_medium = NA, pH_H2O = NA, perc_OC = NA, perc_clay = NA, CEC = NA, remark = \"\", source, page = NA )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-12","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"soils Names soils Kf sorption constant L/kg, either linear (N 1) according Freundlich Kfoc constant , normalised soil organic carbon N Freundlich exponent type soil type pH_orig pH stated study pH_medium medium pH measured pH_H2O pH extrapolated pure water perc_OC percentage organic carbon soil perc_clay percentage clay soil CEC cation exchange capacity remark remark source acronym specifying source information page page information taken","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-pdf-","dir":"Reference","previous_headings":"","what":"Method pdf()","title":"An R6 class for chemical entities with associated data — chent","text":"Write PDF image structure","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-13","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$pdf( file = paste0(self$identifier, \".pdf\"), dir = \"structures/pdf\", template = NULL )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-13","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"file file write dir directory write file template optional SMILES code used template RDKit","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-png-","dir":"Reference","previous_headings":"","what":"Method png()","title":"An R6 class for chemical entities with associated data — chent","text":"Write PNG image structure","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-14","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$png( file = paste0(self$identifier, \".png\"), dir = \"structures/png\", antialias = \"gray\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-14","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"file file write dir directory write file antialias Passed png","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-emf-","dir":"Reference","previous_headings":"","what":"Method emf()","title":"An R6 class for chemical entities with associated data — chent","text":"Write EMF image structure using emf","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-15","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$emf(file = paste0(self$identifier, \".emf\"), dir = \"structures/emf\")"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-15","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"file file write dir directory write file ","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"method-clone-","dir":"Reference","previous_headings":"","what":"Method clone()","title":"An R6 class for chemical entities with associated data — chent","text":"objects class cloneable method.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"usage-16","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"chent$clone(deep = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"arguments-16","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for chemical entities with associated data — chent","text":"deep Whether make deep clone.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/chent.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"An R6 class for chemical entities with associated data — chent","text":"","code":"# Don't run examples per default, as PubChem may be unavailable # \\dontrun{ caffeine <- chent$new(\"caffeine\") #> Querying PubChem for name caffeine ... #> Get chemical information from RDKit using PubChem SMILES #> CN1C=NC2=C1C(=O)N(C(=O)N2C)C print(caffeine) #> <chent> #> Identifier $identifier caffeine #> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CN1C=NC2=C1C(=O)N(C(=O)N2C)C\" #> Molecular weight $mw: 194.2 #> PubChem synonyms (up to 10): #> [1] \"caffeine\" \"58-08-2\" #> [3] \"Guaranine\" \"1,3,7-Trimethylxanthine\" #> [5] \"Methyltheobromine\" \"Theine\" #> [7] \"Thein\" \"Cafeina\" #> [9] \"Caffein\" \"Cafipel\" if (!is.null(caffeine$Picture)) { plot(caffeine) } oct <- chent$new(\"1-octanol\", smiles = \"CCCCCCCCO\", pubchem = FALSE) #> Get chemical information from RDKit using user SMILES #> CCCCCCCCO print(oct) #> <chent> #> Identifier $identifier 1-octanol #> InChI Key $inchikey NA #> SMILES string $smiles: #> user #> \"CCCCCCCCO\" #> Molecular weight $mw: 130.2 # }"},{"path":"https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.html","id":null,"dir":"Reference","previous_headings":"","what":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","title":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","text":"Draw SVG graph chent object using RDKit","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","text":"","code":"draw_svg.chent( x, width = 300, height = 150, filename = paste0(names(x$identifier), \".svg\"), subdir = \"svg\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/draw_svg.chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Draw SVG graph from a chent object using RDKit — draw_svg.chent","text":"x chent object plotted width desired width pixels height desired height pixels filename filename subdir path file written","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":null,"dir":"Reference","previous_headings":"","what":"An R6 class for pesticidal active ingredients and associated data — pai","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"class derived chent. makes easy create chent ISO common name pesticide active ingredient, additionally stores ISO name well complete result querying BCPC compendium using bcpc_query.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"R6::R6Class generator object","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"super-class","dir":"Reference","previous_headings":"","what":"Super class","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"chents::chent -> pai","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"public-fields","dir":"Reference","previous_headings":"","what":"Public fields","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"iso ISO common name active ingredient according ISO 1750 bcpc Information retrieved BCPC compendium available online <pesticidecompendium.bcpc.org>","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"methods","dir":"Reference","previous_headings":"","what":"Methods","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"chents::chent$add_PUF() chents::chent$add_TP() chents::chent$add_cwsat() chents::chent$add_p0() chents::chent$add_soil_degradation() chents::chent$add_soil_ff() chents::chent$add_soil_sorption() chents::chent$add_transformation() chents::chent$emf() chents::chent$get_chyaml() chents::chent$get_pubchem() chents::chent$get_rdkit() chents::chent$pdf() chents::chent$png() chents::chent$try_pubchem()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"public-methods","dir":"Reference","previous_headings":"","what":"Public methods","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"pai$new() pai$clone()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"method-new-","dir":"Reference","previous_headings":"","what":"Method new()","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"Create new pai object","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"usage","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"","code":"pai$new( iso, identifier = iso, smiles = NULL, inchikey = NULL, bcpc = TRUE, pubchem = TRUE, pubchem_from = \"auto\", rdkit = TRUE, template = NULL, chyaml = FALSE )"},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"iso ISO common name used query BCPC compendium identifier Alternative identifier used querying pubchem smiles Optional user provided SMILES code inchikey Optional user provided InChI Key bcpc BCPC compendium queried? pubchem attempt made retrieve chemical information PubChem via webchem package? pubchem_from Possibility select argument used query pubchem rdkit attempt made retrieve chemical information local rdkit installation via python reticulate package? template optional SMILES code used template RDKit chyaml look identifier.yaml file working","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"method-clone-","dir":"Reference","previous_headings":"","what":"Method clone()","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"objects class cloneable method.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"usage-1","dir":"Reference","previous_headings":"","what":"Usage","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"","code":"pai$clone(deep = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"arguments-1","dir":"Reference","previous_headings":"","what":"Arguments","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"deep Whether make deep clone.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/pai.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"An R6 class for pesticidal active ingredients and associated data — pai","text":"","code":"# Don't run examples per default, as PubChem may be unavailable # \\dontrun{ atr <- pai$new(\"atrazine\") #> Querying BCPC for atrazine ... #> Querying PubChem for inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N ... #> Get chemical information from RDKit using PubChem SMILES #> CCNC1=NC(=NC(=N1)Cl)NC(C)C print(atr) #> <pai> with ISO common name $iso atrazine #> <chent> #> Identifier $identifier atrazine #> InChI Key $inchikey MXWJVTOOROXGIU-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CCNC1=NC(=NC(=N1)Cl)NC(C)C\" #> Molecular weight $mw: 215.7 #> PubChem synonyms (up to 10): #> [1] \"atrazine\" \"1912-24-9\" \"Gesaprim\" \"Aatrex\" \"Atranex\" #> [6] \"Atrazin\" \"Oleogesaprim\" \"Atazinax\" \"Atrasine\" \"Chromozin\" if (!is.null(atr$Picture)) { plot(atr) } # We can also define pais that are not found on the BCPC site decanol <- pai$new(\"1-Decanol\") #> Querying BCPC for 1-Decanol ... #> Common name 1-Decanol is not known at the BCPC compendium, trying PubChem #> Querying PubChem for name 1-Decanol ... #> Get chemical information from RDKit using PubChem SMILES #> CCCCCCCCCCO print(decanol) #> <pai> without ISO common name #> <chent> #> Identifier $identifier 1-Decanol #> InChI Key $inchikey MWKFXSUHUHTGQN-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CCCCCCCCCCO\" #> Molecular weight $mw: 158.3 #> PubChem synonyms (up to 10): #> [1] \"1-DECANOL\" \"Decan-1-ol\" \"Decyl alcohol\" \"112-30-1\" #> [5] \"n-Decyl alcohol\" \"n-Decanol\" \"Capric alcohol\" \"Nonylcarbinol\" #> [9] \"Antak\" \"Royaltac\" # }"},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot method for chent objects — plot.chent","title":"Plot method for chent objects — plot.chent","text":"Plot method chent objects","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot method for chent objects — plot.chent","text":"","code":"# S3 method for class 'chent' plot(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot method for chent objects — plot.chent","text":"x chent object plotted ... arguments passed grImport::grid.picture","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/plot.chent.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Plot method for chent objects — plot.chent","text":"","code":"# Don't run examples per default, as PubChem may be unavailable # \\dontrun{ caffeine <- chent$new(\"caffeine\") #> Querying PubChem for name caffeine ... #> Get chemical information from RDKit using PubChem SMILES #> CN1C=NC2=C1C(=O)N(C(=O)N2C)C print(caffeine) #> <chent> #> Identifier $identifier caffeine #> InChI Key $inchikey RYYVLZVUVIJVGH-UHFFFAOYSA-N #> SMILES string $smiles: #> PubChem #> \"CN1C=NC2=C1C(=O)N(C(=O)N2C)C\" #> Molecular weight $mw: 194.2 #> PubChem synonyms (up to 10): #> [1] \"caffeine\" \"58-08-2\" #> [3] \"Guaranine\" \"1,3,7-Trimethylxanthine\" #> [5] \"Methyltheobromine\" \"Theine\" #> [7] \"Thein\" \"Cafeina\" #> [9] \"Caffein\" \"Cafipel\" if (!is.null(caffeine$Picture)) { plot(caffeine) } # }"},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":null,"dir":"Reference","previous_headings":"","what":"R6 class for a plant protection product with at least one active ingredient — ppp","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"Contains basic information active ingredients product","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"R6::R6Class generator object.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"public-fields","dir":"Reference","previous_headings":"","what":"Public fields","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"name name product ais list active ingredients concentrations concentration ais concentration_units Defaults g/L density density product density_units Defaults g/L","code":""},{"path":[]},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"public-methods","dir":"Reference","previous_headings":"","what":"Public methods","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"ppp$new() ppp$clone()","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"method-new-","dir":"Reference","previous_headings":"","what":"Method new()","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"Creates new instance R6 class.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"usage","dir":"Reference","previous_headings":"","what":"Usage","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"","code":"ppp$new( name, ..., concentrations, concentration_units = \"g/L\", density = 1000, density_units = \"g/L\" )"},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"name name product ... Identifiers active ingredients concentrations Concentrations active ingredients concentration_units Defaults g/L density density density_units Defaults g/L","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"method-clone-","dir":"Reference","previous_headings":"","what":"Method clone()","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"objects class cloneable method.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"usage-1","dir":"Reference","previous_headings":"","what":"Usage","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"","code":"ppp$clone(deep = FALSE)"},{"path":"https://pkgdown.jrwb.de/chents/reference/ppp.html","id":"arguments-1","dir":"Reference","previous_headings":"","what":"Arguments","title":"R6 class for a plant protection product with at least one active ingredient — ppp","text":"deep Whether make deep clone.","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.chent.html","id":null,"dir":"Reference","previous_headings":"","what":"Printing method for chent objects — print.chent","title":"Printing method for chent objects — print.chent","text":"Printing method chent objects","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.chent.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Printing method for chent objects — print.chent","text":"","code":"# S3 method for class 'chent' print(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/print.chent.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Printing method for chent objects — print.chent","text":"x chent object printed ... arguments compatibility S3 method","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.pai.html","id":null,"dir":"Reference","previous_headings":"","what":"Printing method for pai objects (pesticidal active ingredients) — print.pai","title":"Printing method for pai objects (pesticidal active ingredients) — print.pai","text":"Printing method pai objects (pesticidal active ingredients)","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.pai.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Printing method for pai objects (pesticidal active ingredients) — print.pai","text":"","code":"# S3 method for class 'pai' print(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/print.pai.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Printing method for pai objects (pesticidal active ingredients) — print.pai","text":"x chent object printed ... arguments compatibility S3 method","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.ppp.html","id":null,"dir":"Reference","previous_headings":"","what":"Printing method for ppp objects (plant protection products) — print.ppp","title":"Printing method for ppp objects (plant protection products) — print.ppp","text":"Printing method ppp objects (plant protection products)","code":""},{"path":"https://pkgdown.jrwb.de/chents/reference/print.ppp.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Printing method for ppp objects (plant protection products) — print.ppp","text":"","code":"# S3 method for class 'ppp' print(x, ...)"},{"path":"https://pkgdown.jrwb.de/chents/reference/print.ppp.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Printing method for ppp objects (plant protection products) — print.ppp","text":"x chent object printed ... arguments compatibility S3 method","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-041","dir":"Changelog","previous_headings":"","what":"version 0.4.1","title":"version 0.4.1","text":"R/chent.R: Improve print method pai objects.","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-040","dir":"Changelog","previous_headings":"","what":"version 0.4.0","title":"version 0.4.0","text":"R/chent.R: PubChem changed names SMILES codes provide. former isomeric smiles incorporated chent objects “Pubchem_Isomeric” now simply calles SMILES, incorporated objects “PubChem”. SMILES code formerly given “canonical” now termed “connectivity SMILES” contain isotopic stereochemical specifications. chents object, now available name “PubChem_Connectivity”. breaking change, objects generated versions < 0.4.0 may produce errors used current versions.","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-037","dir":"Changelog","previous_headings":"","what":"version 0.3.7","title":"version 0.3.7","text":"R/chent.R: attempt load chyaml file per default, format file resulting chyaml list object documented need inferred use pfm package.","code":""},{"path":"https://pkgdown.jrwb.de/chents/news/index.html","id":"version-036","dir":"Changelog","previous_headings":"","what":"version 0.3.6","title":"version 0.3.6","text":"R/chent.R: Set fields smiles, inchikey mw NA fields still NULL end initialization, source attribute set “user”, assuming initialisation carefully done pubchem rdkit skipped structure well-defined. Please refer ChangeLog commit messages November 2021, changed GNUmakefile include commit messages file .","code":""}] |
