Compare commits

..

13 Commits

Author SHA1 Message Date
Winston Chang
3c4d6803f3 Add tests for glyphicon 2018-10-24 14:41:49 -05:00
Winston Chang
7d96caa42d Remove note about using NULL 2018-10-24 13:22:27 -05:00
Winston Chang
a1c077233b Save fa_icons and fa_version to text for nice diffs 2018-10-24 13:21:59 -05:00
Winston Chang
096c6648be Update NEWS 2018-10-24 10:40:42 -05:00
Winston Chang
0dbad94a74 Update icon tests 2018-10-24 10:38:50 -05:00
Winston Chang
23a10c7a2b icon(): add fa4 and fa5 lib options 2018-10-24 10:38:50 -05:00
Winston Chang
7fc36f9274 Don't store Font-Awesome labels 2018-10-23 20:54:49 -05:00
Winston Chang
869f08c265 Automatically record Font-Awesome version 2018-10-23 20:52:28 -05:00
Winston Chang
b5009a6a87 Re-document 2018-10-23 20:49:50 -05:00
Winston Chang
a98dfaa85a icon(): allow name to be NULL 2018-10-23 20:49:10 -05:00
Winston Chang
35ed850adf Automatically find Font-Awesome CSS prefix class 2018-10-23 16:13:07 -05:00
Winston Chang
c74b1dfa1e Update Font-Awesome to 5.4.1 2018-10-23 16:02:11 -05:00
Winston Chang
0fd633584a Create updateFontAwesome script 2018-10-23 16:00:34 -05:00
281 changed files with 50492 additions and 7044 deletions

View File

@@ -1,3 +1,4 @@
^data-raw$
^\.Rproj\.user$
^\.git$
^examples$
@@ -20,4 +21,3 @@
^revdep$
^TODO-promises.md$
^manualtests$
^\.github$

View File

@@ -1,40 +0,0 @@
---
name : Bug report
about : Report a bug in Shiny.
---
<!--
This issue tracker is for bugs and feature requests in the Shiny package. If you're having trouble with Shiny Server or a related package, please file an issue in the appropriate repository.
If you're having trouble with shinyapps.io, and you have a paid account (Starter, Basic, Standard, or Pro), please file a support ticket via https://support.rstudio.com. If you have a Free account, please post to the RStudio Community with the shinyappsio tag: https://community.rstudio.com/tags/shinyappsio.
Finally, if you are an RStudio customer and are having trouble with one of our Pro products, get in touch with our support team at support@rstudio.com.
Before you file an issue, please upgrade to the latest version of Shiny from CRAN and confirm that the problem persists.
# First, restart R.
# To install latest shiny from CRAN:
install.packages("shiny")
See our guide to writing good bug reports for further guidance: https://github.com/rstudio/shiny/wiki/Writing-Good-Bug-Reports. The better your report is, the likelier we are to be able to reproduce and ultimately solve it.
-->
### System details
Browser Version: <!-- If applicable -->
Output of `sessionInfo()`:
```
# sessionInfo() output goes here
```
### Example application *or* steps to reproduce the problem
<!-- If you're able to create one, a reproducible example is extremely helpful to us. For instructions on how to create one, please see: https://github.com/rstudio/shiny/wiki/Creating-a-Reproducible-Example -->
```R
# Minimal, self-contained example app code goes here
```
### Describe the problem in detail

View File

@@ -1,17 +0,0 @@
---
name : Feature request
about : Request a new feature.
---
<!--
Thanks for taking the time to file a feature request! Please take the time to search for an existing feature request, to avoid creating duplicate requests. If you find an existing feature request, please give it a thumbs-up reaction, as we'll use these reactions to help prioritize the implementation of these features in the future.
If the feature has not yet been filed, then please describe the feature you'd like to see become a part of Shiny. See:
https://github.com/rstudio/shiny/wiki/Writing-Good-Feature-Requests
for a guide on how to write good feature requests.
-->

View File

@@ -1,7 +0,0 @@
---
name : Ask a Question
about : The issue tracker is not for questions -- please ask questions at https://community.rstudio.com/c/shiny.
---
The issue tracker is not for questions. If you have a question, please feel free to ask it on our community site, at https://community.rstudio.com/c/shiny.

1
.gitignore vendored
View File

@@ -9,4 +9,3 @@
shinyapps/
README.html
.*.Rnb.cached
tools/yarn-error.log

View File

@@ -1,26 +1,11 @@
language: r
matrix:
include:
- name: "Roxygen check"
r: release
r_packages:
- devtools
- roxygen2
script: ./tools/checkDocsCurrent.sh
- name: "Javascript check"
language: node_js
cache: yarn
script: ./tools/checkJSCurrent.sh
node_js:
- "10"
- name: "Old Release Check"
r: oldrel
- name: "Current Release Check"
r: release
- name: "Development Release Check"
r: devel
r:
- oldrel
- release
- devel
sudo: false
cache: packages
notifications:
email:
on_success: change

View File

@@ -1,7 +1,7 @@
Package: shiny
Type: Package
Title: Web Application Framework for R
Version: 1.3.2.9001
Version: 1.2.0
Authors@R: c(
person("Winston", "Chang", role = c("aut", "cre"), email = "winston@rstudio.com"),
person("Joe", "Cheng", role = "aut", email = "joe@rstudio.com"),
@@ -65,29 +65,27 @@ Depends:
Imports:
utils,
grDevices,
httpuv (>= 1.5.0),
httpuv (>= 1.4.4),
mime (>= 0.3),
jsonlite (>= 0.9.16),
xtable,
digest,
htmltools (>= 0.3.6),
htmltools (>= 0.3.5),
R6 (>= 2.0),
sourcetools,
later (>= 0.7.2),
promises (>= 1.0.1),
tools,
crayon,
rlang (>= 0.4.0),
fastmap (>= 0.0.0.9001)
rlang
Suggests:
datasets,
Cairo (>= 1.5-5),
testthat (>= 2.1.1),
testthat,
knitr (>= 1.6),
markdown,
rmarkdown,
ggplot2,
reactlog (>= 1.0.0),
magrittr
URL: http://shiny.rstudio.com
BugReports: https://github.com/rstudio/shiny/issues
@@ -108,7 +106,6 @@ Collate:
'cache-utils.R'
'diagnose.R'
'fileupload.R'
'font-awesome.R'
'graph.R'
'reactives.R'
'reactive-domains.R'
@@ -162,6 +159,4 @@ Collate:
'test-export.R'
'timer.R'
'update-input.R'
RoxygenNote: 6.1.1
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 6.1.0

View File

@@ -25,6 +25,7 @@ S3method(as.tags,shiny.render.function)
S3method(format,reactiveExpr)
S3method(format,reactiveVal)
S3method(names,reactivevalues)
S3method(print,key_missing)
S3method(print,reactive)
S3method(print,shiny.appobj)
S3method(str,reactivevalues)
@@ -188,9 +189,6 @@ export(reactiveUI)
export(reactiveVal)
export(reactiveValues)
export(reactiveValuesToList)
export(reactlog)
export(reactlogReset)
export(reactlogShow)
export(registerInputHandler)
export(removeInputHandler)
export(removeModal)
@@ -300,8 +298,5 @@ import(httpuv)
import(methods)
import(mime)
import(xtable)
importFrom(fastmap,fastmap)
importFrom(fastmap,is.key_missing)
importFrom(fastmap,key_missing)
importFrom(grDevices,dev.cur)
importFrom(grDevices,dev.set)

101
NEWS.md
View File

@@ -1,92 +1,3 @@
shiny 1.3.2.9001
=======
## Changes
* Resolved [#1433](https://github.com/rstudio/shiny/issues/1433): `plotOutput()`'s coordmap info now includes discrete axis limits for **ggplot2** plots. As a result, any **shinytest** tests that contain **ggplot2** plots with discrete axes (that were recorded before this change) will now report differences that can safely be updated. This new coordmap info was added to correctly infer what data points are within an input brush and/or near input click/hover in scenarios where a non-trivial discrete axis scale is involved (e.g., whenever `scale_[x/y]_discrete(limits = ...)` and/or free scales across multiple discrete axes are used). ([#2410](https://github.com/rstudio/shiny/pull/2410))
### Improvements
* Resolved [#2402](https://github.com/rstudio/shiny/issues/2402): An informative warning is now thrown for mis-specified (date) strings in `dateInput()`, `updateDateInput()`, `dateRangeInput()`, and `updateDateRangeInput()`. ([#2403](https://github.com/rstudio/shiny/pull/2403))
* Resolved [#2442](https://github.com/rstudio/shiny/issues/2442): The `shiny:inputchanged` JavaScript event now triggers on the related input element instead of `document`. Existing event listeners bound to `document` will still detect the event due to event bubbling. ([#2446](https://github.com/rstudio/shiny/pull/2446))
* Fixed [#1393](https://github.com/rstudio/shiny/issues/1393), [#2223](https://github.com/rstudio/shiny/issues/2223): For plots with any interactions enabled, the image is no longer draggable. ([#2460](https://github.com/rstudio/shiny/pull/2460))
* Partially resolved [#2423](https://github.com/rstudio/shiny/issues/2423): Reactivity in Shiny leaked some memory, because R can leak memory whenever a new symbols is interned, which happens whenever a new name/key is used in an environment. R now uses the fastmap package, which avoids this problem. ([#2429](https://github.com/rstudio/shiny/pull/2429))
* Resolved [#2469](https://github.com/rstudio/shiny/issues/2469): `renderText` now takes a `sep` argument that is passed to `cat`. ([#2497](https://github.com/rstudio/shiny/pull/2497))
* Resolved [#2515](https://github.com/rstudio/shiny/issues/2515): `selectInput()` now deals appropriately with named factors. ([#2524](https://github.com/rstudio/shiny/pull/2524))
### Bug fixes
* Fixed [#2387](https://github.com/rstudio/shiny/issues/2387): Updating a `sliderInput()`'s type from numeric to date no longer changes the rate policy from debounced to immediate. More generally, updating an input binding with a new type should (no longer) incorrectly alter the input rate policy. ([#2404](https://github.com/rstudio/shiny/pull/2404))
* Fixed [#868](https://github.com/rstudio/shiny/issues/868): If an input is initialized with a `NULL` label, it can now be updated with a string. Moreover, if an input label is initialized with a string, it can now be removed by updating with `label=character(0)` (similar to how `choices` and `selected` can be cleared in `updateSelectInput()`). ([#2406](https://github.com/rstudio/shiny/pull/2406))
* Fixed [#2250](https://github.com/rstudio/shiny/issues/2250): `updateSliderInput()` now works with un-specified (or zero-length) `min`, `max`, and `value`. ([#2416](https://github.com/rstudio/shiny/pull/2416))
* Fixed [#2396](https://github.com/rstudio/shiny/issues/2396): `selectInput("myID", ...)` resulting in an extra `myID-selectized` input (introduced in v1.2.0). ([#2418](https://github.com/rstudio/shiny/pull/2418))
* Fixed [#2233](https://github.com/rstudio/shiny/issues/2233): `verbatimTextOutput()` produced wrapped text on Safari, but the text should not be wrapped. ([#2353](https://github.com/rstudio/shiny/pull/2353))
* Fixed [rstudio/reactlog#36](https://github.com/rstudio/reactlog/issues/36): Changes to reactive values not displaying accurately in reactlog. ([#2424](https://github.com/rstudio/shiny/pull/2424))
* Fixed [#2329](https://github.com/rstudio/shiny/issues/2329), [#1817](https://github.com/rstudio/shiny/issues/1817): These bugs were reported as fixed in Shiny 1.3.0 but were not actually fixed because some JavaScript changes were accidentally not included in the release. The fix resolves issues that occur when `withProgressBar()` or bookmarking are combined with the [networkD3](https://christophergandrud.github.io/networkD3/) package's Sankey plot.
shiny 1.3.2
===========
### Bug fixes
* Fixed [#2285](https://github.com/rstudio/shiny/issues/2285), [#2288](https://github.com/rstudio/shiny/issues/2288): Static CSS/JS resources in subapps in R Markdown documents did not render properly. ([#2386](https://github.com/rstudio/shiny/pull/2386))
* Fixed [#2280](https://github.com/rstudio/shiny/issues/2280): Shiny applications that used a www/index.html file did not serve up the index file. ([#2382](https://github.com/rstudio/shiny/pull/2382))
shiny 1.3.1
===========
## Full changelog
### Bug fixes
* Fixed a performance issue introduced in v1.3.0 when using large nested lists within Shiny. ([#2377](https://github.com/rstudio/shiny/pull/2377))
shiny 1.3.0
===========
## Full changelog
### Breaking changes
### New features
* Revamped Shiny's [reactlog](https://github.com/rstudio/reactlog) viewer which debugs reactivity within a shiny application. This allows users to traverse the reactivity history of a shiny application, filter to the dependency tree of a selected reactive object, and search for matching reactive objects. See `?reactlogShow` for more details and how to enable this feature. ([#2107](https://github.com/rstudio/shiny/pull/2107))
* Shiny now serves static files on a background thread. This means that things like JavaScript and CSS assets can be served without blocking or being blocked by the main R thread, and should result in significantly better performance for heavily loaded servers. ([#2280](https://github.com/rstudio/shiny/pull/2280))
### Minor new features and improvements
* The `Shiny-Shared-Secret` security header is now checked using constant-time comparison to prevent timing attacks (thanks @dirkschumacher!). ([#2319](https://github.com/rstudio/shiny/pull/2319))
### Bug fixes
* Fixed [#2245](https://github.com/rstudio/shiny/issues/2245): `updateSelectizeInput()` did not update labels. ([#2248](https://github.com/rstudio/shiny/pull/2248))
* Fixed [#2308](https://github.com/rstudio/shiny/issues/2308): When restoring a bookmarked application, inputs with a leading `.` would not be restored. ([#2311](https://github.com/rstudio/shiny/pull/2311))
* Fixed [#2305](https://github.com/rstudio/shiny/issues/2305), [#2322](https://github.com/rstudio/shiny/issues/2322), [#2351](https://github.com/rstudio/shiny/issues/2351): When an input in dynamic UI is restored from bookmarks, it would keep getting set to the same value. ([#2360](https://github.com/rstudio/shiny/pull/2360))
* Fixed [#2349](https://github.com/rstudio/shiny/issues/2349), [#2329](https://github.com/rstudio/shiny/issues/2329), [#1817](https://github.com/rstudio/shiny/issues/1817): These were various bugs triggered by the presence of the [networkD3](https://christophergandrud.github.io/networkD3/) package's Sankey plot in an app. Impacted features included `dateRangeInput`, `withProgressBar`, and bookmarking ([#2359](https://github.com/rstudio/shiny/pull/2359))
### Documentation Updates
* Fixed [#2247](https://github.com/rstudio/shiny/issues/2247): `renderCachedPlot` now supports using promises for either `expr` or `cacheKeyExpr`. (Shiny v1.2.0 supported async `expr`, but only if `cacheKeyExpr` was async as well; now you can use any combination of sync/async for `expr` and `cacheKeyExpr`.) [#2261](https://github.com/rstudio/shiny/pull/2261)
shiny 1.2.0
===========
@@ -94,17 +5,13 @@ This release features plot caching, an important new tool for improving performa
## Full changelog
### Breaking changes
* The URL paths for FontAwesome CSS/JS/font assets have changed, due to our upgrade from FontAwesome 4 to 5. This shouldn't affect you unless you're using `www/index.html` to provide your UI and have hardcoded the old FontAwesome paths into your HTML. If that's you, consider switching to [HTML templates](https://shiny.rstudio.com/articles/templates.html), which give you the syntax of raw HTML while still taking advantage of Shiny's automatic management of web dependencies.
### New features
* Added `renderCachedPlot()`, which stores plots in a cache so that they can be served up almost instantly. ([#1997](https://github.com/rstudio/shiny/pull/1997))
### Minor new features and improvements
* Upgrade FontAwesome from 4.7.0 to 5.3.1 and made `icon` tags browsable, which means they will display in a web browser or RStudio viewer by default ([#2186](https://github.com/rstudio/shiny/issues/2186)). Note that if your application or library depends on FontAwesome directly using custom CSS, you may need to make some or all of the changes recommended in [Upgrade from Version 4](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4). Font Awesome icons can also now be used in static R Markdown documents.
* Upgrade FontAwesome from 4.7.0 to 5.4.1 and made `icon` tags browsable, which means they will display in a web browser or RStudio viewer by default ([#2186](https://github.com/rstudio/shiny/issues/2186)). Note that if your application or library depends on FontAwesome directly using custom CSS, you may need to make some or all of the changes recommended in [Upgrade from Version 4](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4). By default, the V5 icon will be used, and if it's not present in V5, the V4 icon will be used. It is also possible to specifically use just a V5 or V4 version of an icon. Font Awesome icons can also now be used in static R Markdown documents.
* Address [#174](https://github.com/rstudio/shiny/issues/174): Added `datesdisabled` and `daysofweekdisabled` as new parameters to `dateInput()`. This resolves [#174](https://github.com/rstudio/shiny/issues/174) and exposes the underlying arguments of [Bootstrap Datepicker](http://bootstrap-datepicker.readthedocs.io/en/latest/options.html#datesdisabled). `datesdisabled` expects a character vector with values in `yyyy/mm/dd` format and `daysofweekdisabled` expects an integer vector with day interger ids (Sunday=0, Saturday=6). The default value for both is `NULL`, which leaves all days selectable. Thanks, @nathancday! ([#2147](https://github.com/rstudio/shiny/pull/2147))
@@ -142,10 +49,6 @@ This release features plot caching, an important new tool for improving performa
* Fixed [#2204](https://github.com/rstudio/shiny/issues/2204): `updateDateInput` could set the wrong date on days where DST begins. (Thanks @GaGaMan1101!) [#2212](https://github.com/rstudio/shiny/pull/2212)
* Fixed [#2225](https://github.com/rstudio/shiny/issues/2225): Input event queue can stall in apps that use async. [#2226](https://github.com/rstudio/shiny/pull/2226)
* Fixed [#2228](https://github.com/rstudio/shiny/issues/2228): `reactiveTimer` fails when not owned by a session. Thanks, @P-Bettega! [#2229](https://github.com/rstudio/shiny/pull/2229)
### Documentation Updates
* Addressed [#1864](https://github.com/rstudio/shiny/issues/1864) by changing `optgroup` documentation to use `list` instead of `c`. ([#2084](https://github.com/rstudio/shiny/pull/2084))
@@ -206,7 +109,7 @@ This is a significant release for Shiny, with a major new feature that was nearl
* Improved the error handling inside the `addResourcePath()` function, to give end users more informative error messages when the `directoryPath` argument cannot be normalized. This is especially useful for `runtime: shiny_prerendered` Rmd documents, like `learnr` tutorials. ([#1968](https://github.com/rstudio/shiny/pull/1968))
* Changed script tags in reactlog ([inst/www/reactive-graph.html](https://github.com/rstudio/shiny/blob/v1.1.0/inst/www/reactive-graph.html)) from HTTP to HTTPS in order to avoid mixed content blocking by most browsers. (Thanks, @jekriske-lilly! [#1844](https://github.com/rstudio/shiny/pull/1844))
* Changed script tags in reactlog ([inst/www/reactive-graph.html](https://github.com/rstudio/shiny/blob/master/inst/www/reactive-graph.html)) from HTTP to HTTPS in order to avoid mixed content blocking by most browsers. (Thanks, @jekriske-lilly! [#1844](https://github.com/rstudio/shiny/pull/1844))
* Addressed [#1784](https://github.com/rstudio/shiny/issues/1784): `runApp()` will avoid port 6697, which is considered unsafe by Chrome.

82
R/app.R
View File

@@ -3,38 +3,40 @@
#' Create a Shiny app object
#'
#' These functions create Shiny app objects from either an explicit UI/server
#' pair (`shinyApp`), or by passing the path of a directory that contains a
#' Shiny app (`shinyAppDir`).
#' pair (\code{shinyApp}), or by passing the path of a directory that contains a
#' Shiny app (\code{shinyAppDir}). You generally shouldn't need to use these
#' functions to create/run applications; they are intended for interoperability
#' purposes, such as embedding Shiny apps inside a \pkg{knitr} document.
#'
#' Normally when this function is used at the R console, the Shiny app object is
#' automatically passed to the `print()` function, which runs the app. If
#' automatically passed to the \code{print()} function, which runs the app. If
#' this is called in the middle of a function, the value will not be passed to
#' `print()` and the app will not be run. To make the app run, pass the app
#' object to `print()` or [runApp()].
#' \code{print()} and the app will not be run. To make the app run, pass the app
#' object to \code{print()} or \code{\link{runApp}()}.
#'
#' @param ui The UI definition of the app (for example, a call to
#' `fluidPage()` with nested controls)
#' \code{fluidPage()} with nested controls)
#' @param server A server function
#' @param onStart A function that will be called before the app is actually run.
#' This is only needed for `shinyAppObj`, since in the `shinyAppDir`
#' case, a `global.R` file can be used for this purpose.
#' @param options Named options that should be passed to the `runApp` call
#' This is only needed for \code{shinyAppObj}, since in the \code{shinyAppDir}
#' case, a \code{global.R} file can be used for this purpose.
#' @param options Named options that should be passed to the \code{runApp} call
#' (these can be any of the following: "port", "launch.browser", "host", "quiet",
#' "display.mode" and "test.mode"). You can also specify `width` and
#' `height` parameters which provide a hint to the embedding environment
#' "display.mode" and "test.mode"). You can also specify \code{width} and
#' \code{height} parameters which provide a hint to the embedding environment
#' about the ideal height/width for the app.
#' @param uiPattern A regular expression that will be applied to each `GET`
#' request to determine whether the `ui` should be used to handle the
#' @param uiPattern A regular expression that will be applied to each \code{GET}
#' request to determine whether the \code{ui} should be used to handle the
#' request. Note that the entire request path must match the regular
#' expression in order for the match to be considered successful.
#' @param enableBookmarking Can be one of `"url"`, `"server"`, or
#' `"disable"`. This is equivalent to calling the
#' [enableBookmarking()] function just before calling
#' `shinyApp()`. With the default value (`NULL`), the app will
#' respect the setting from any previous calls to `enableBookmarking()`.
#' See [enableBookmarking()] for more information.
#' @param enableBookmarking Can be one of \code{"url"}, \code{"server"}, or
#' \code{"disable"}. This is equivalent to calling the
#' \code{\link{enableBookmarking}()} function just before calling
#' \code{shinyApp()}. With the default value (\code{NULL}), the app will
#' respect the setting from any previous calls to \code{enableBookmarking()}.
#' See \code{\link{enableBookmarking}} for more information.
#' @return An object that represents the app. Printing the object or passing it
#' to [runApp()] will run the app.
#' to \code{\link{runApp}} will run the app.
#'
#' @examples
#' ## Only run this example in interactive R sessions
@@ -168,14 +170,7 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
}
wwwDir <- file.path.ci(appDir, "www")
if (dirExists(wwwDir)) {
staticPaths <- list("/" = staticPath(wwwDir, indexhtml = FALSE, fallthrough = TRUE))
} else {
staticPaths <- list()
}
fallbackWWWDir <- system.file("www-dir", package = "shiny")
serverSource <- cachedFuncWithFile(appDir, "server.R", case.sensitive = FALSE,
function(serverR) {
# If server.R contains a call to shinyServer (which sets .globals$server),
@@ -225,13 +220,6 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
structure(
list(
staticPaths = staticPaths,
# Even though the wwwDir is handled as a static path, we need to include
# it here to be handled by R as well. This is because the special case
# of index.html: it is specifically not handled as a staticPath for
# reasons explained above, but if someone does want to serve up an
# index.html, we need to handle it, and we do it by using the
# staticHandler in the R code path. (#2380)
httpHandler = joinHandlers(c(uiHandler, wwwDir, fallbackWWWDir)),
serverFuncSource = serverFuncSource,
onStart = onStart,
@@ -321,20 +309,6 @@ shinyAppDir_appR <- function(fileName, appDir, options=list())
}
wwwDir <- file.path.ci(appDir, "www")
if (dirExists(wwwDir)) {
# wwwDir is a static path served by httpuv. It does _not_ serve up
# index.html, for two reasons. (1) It's possible that the user's
# www/index.html file is not actually used as the index, but as a template
# that gets processed before being sent; and (2) the index content may be
# modified by the hosting environment (as in SockJSAdapter.R).
#
# The call to staticPath normalizes the path, so that if the working dir
# later changes, it will continue to point to the right place.
staticPaths <- list("/" = staticPath(wwwDir, indexhtml = FALSE, fallthrough = TRUE))
} else {
staticPaths <- list()
}
fallbackWWWDir <- system.file("www-dir", package = "shiny")
oldwd <- NULL
@@ -353,18 +327,6 @@ shinyAppDir_appR <- function(fileName, appDir, options=list())
structure(
list(
# fallbackWWWDir is _not_ listed in staticPaths, because it needs to
# come after the uiHandler. It also does not need to be fast, since it
# should rarely be hit. The order is wwwDir (in staticPaths), then
# uiHandler, then falbackWWWDir (which is served up by the R
# staticHandler function).
staticPaths = staticPaths,
# Even though the wwwDir is handled as a static path, we need to include
# it here to be handled by R as well. This is because the special case
# of index.html: it is specifically not handled as a staticPath for
# reasons explained above, but if someone does want to serve up an
# index.html, we need to handle it, and we do it by using the
# staticHandler in the R code path. (#2380)
httpHandler = joinHandlers(c(dynHttpHandler, wwwDir, fallbackWWWDir)),
serverFuncSource = dynServerFuncSource,
onStart = onStart,

View File

@@ -426,7 +426,7 @@ RestoreInputSet <- R6Class("RestoreInputSet",
},
asList = function() {
as.list.environment(private$values, all.names = TRUE)
as.list.environment(private$values)
}
)
)
@@ -479,7 +479,7 @@ getCurrentRestoreContext <- function() {
#' Restore an input value
#'
#' This restores an input value from the current restore context. It should be
#' called early on inside of input functions (like [textInput()]).
#' called early on inside of input functions (like \code{\link{textInput}}).
#'
#' @param id Name of the input value to restore.
#' @param default A default value to use, if there's no value to restore.
@@ -509,23 +509,23 @@ restoreInput <- function(id, default) {
#' It typically is called from an observer. Note that this will not work in
#' Internet Explorer 9 and below.
#'
#' For `mode = "push"`, only three updates are currently allowed:
#' For \code{mode = "push"}, only three updates are currently allowed:
#' \enumerate{
#' \item the query string (format: `?param1=val1&param2=val2`)
#' \item the hash (format: `#hash`)
#' \item the query string (format: \code{?param1=val1&param2=val2})
#' \item the hash (format: \code{#hash})
#' \item both the query string and the hash
#' (format: `?param1=val1&param2=val2#hash`)
#' (format: \code{?param1=val1&param2=val2#hash})
#' }
#'
#' In other words, if `mode = "push"`, the `queryString` must start
#' with either `?` or with `#`.
#' In other words, if \code{mode = "push"}, the \code{queryString} must start
#' with either \code{?} or with \code{#}.
#'
#' A technical curiosity: under the hood, this function is calling the HTML5
#' history API (which is where the names for the `mode` argument come from).
#' When `mode = "replace"`, the function called is
#' `window.history.replaceState(null, null, queryString)`.
#' When `mode = "push"`, the function called is
#' `window.history.pushState(null, null, queryString)`.
#' history API (which is where the names for the \code{mode} argument come from).
#' When \code{mode = "replace"}, the function called is
#' \code{window.history.replaceState(null, null, queryString)}.
#' When \code{mode = "push"}, the function called is
#' \code{window.history.pushState(null, null, queryString)}.
#'
#' @param queryString The new query string to show in the location bar.
#' @param mode When the query string is updated, should the the current history
@@ -534,7 +534,7 @@ restoreInput <- function(id, default) {
#' context. The latter is useful if you want to navigate between states using
#' the browser's back and forward buttons. See Examples.
#' @param session A Shiny session object.
#' @seealso [enableBookmarking()], [getQueryString()]
#' @seealso \code{\link{enableBookmarking}}, \code{\link{getQueryString}}
#' @examples
#' ## Only run these examples in interactive sessions
#' if (interactive()) {
@@ -597,7 +597,7 @@ updateQueryString <- function(queryString, mode = c("replace", "push"),
#' Create a button for bookmarking/sharing
#'
#' A `bookmarkButton` is a [actionButton()] with a default label
#' A \code{bookmarkButton} is a \code{\link{actionButton}} with a default label
#' that consists of a link icon and the text "Bookmark...". It is meant to be
#' used for bookmarking state.
#'
@@ -607,10 +607,10 @@ updateQueryString <- function(queryString, mode = c("replace", "push"),
#' @param id An ID for the bookmark button. The only time it is necessary to set
#' the ID unless you have more than one bookmark button in your application.
#' If you specify an input ID, it should be excluded from bookmarking with
#' [setBookmarkExclude()], and you must create an observer that
#' \code{\link{setBookmarkExclude}}, and you must create an observer that
#' does the bookmarking when the button is pressed. See the examples below.
#'
#' @seealso [enableBookmarking()] for more examples.
#' @seealso \code{\link{enableBookmarking}} for more examples.
#'
#' @examples
#' ## Only run these examples in interactive sessions
@@ -660,10 +660,10 @@ bookmarkButton <- function(label = "Bookmark...",
#' Generate a modal dialog that displays a URL
#'
#' The modal dialog generated by `urlModal` will display the URL in a
#' The modal dialog generated by \code{urlModal} will display the URL in a
#' textarea input, and the URL text will be selected so that it can be easily
#' copied. The result from `urlModal` should be passed to the
#' [showModal()] function to display it in the browser.
#' copied. The result from \code{urlModal} should be passed to the
#' \code{\link{showModal}} function to display it in the browser.
#'
#' @param url A URL to display in the dialog box.
#' @param title A title for the dialog box.
@@ -719,8 +719,8 @@ urlModal <- function(url, title = "Bookmarked application link", subtitle = NULL
#' Display a modal dialog for bookmarking
#'
#' This is a wrapper function for [urlModal()] that is automatically
#' called if an application is bookmarked but no other [onBookmark()]
#' This is a wrapper function for \code{\link{urlModal}} that is automatically
#' called if an application is bookmarked but no other \code{\link{onBookmark}}
#' callback was set. It displays a modal dialog with the bookmark URL, along
#' with a subtitle that is appropriate for the type of bookmarking used ("url"
#' or "server").
@@ -761,8 +761,8 @@ showBookmarkUrlModal <- function(url) {
#' @details
#'
#' For restoring state to work properly, the UI must be a function that takes
#' one argument, `request`. In most Shiny applications, the UI is not a
#' function; it might have the form `fluidPage(....)`. Converting it to a
#' one argument, \code{request}. In most Shiny applications, the UI is not a
#' function; it might have the form \code{fluidPage(....)}. Converting it to a
#' function is as simple as wrapping it in a function, as in
#' \code{function(request) \{ fluidPage(....) \}}.
#'
@@ -771,17 +771,17 @@ showBookmarkUrlModal <- function(url) {
#' but not if the state is encoded in a URL.
#'
#' When bookmarking state, arbitrary values can be stored, by passing a function
#' as the `onBookmark` argument. That function will be passed a
#' `ShinySaveState` object. The `values` field of the object is a list
#' as the \code{onBookmark} argument. That function will be passed a
#' \code{ShinySaveState} object. The \code{values} field of the object is a list
#' which can be manipulated to save extra information. Additionally, if the
#' state is being saved on the server, and the `dir` field of that object
#' state is being saved on the server, and the \code{dir} field of that object
#' can be used to save extra information to files in that directory.
#'
#' For saved-to-server state, this is how the state directory is chosen:
#' \itemize{
#' \item If running in a hosting environment such as Shiny Server or
#' Connect, the hosting environment will choose the directory.
#' \item If running an app in a directory with [runApp()], the
#' \item If running an app in a directory with \code{\link{runApp}()}, the
#' saved states will be saved in a subdirectory of the app called
#' shiny_bookmarks.
#' \item If running a Shiny app object that is generated from code (not run
@@ -789,22 +789,22 @@ showBookmarkUrlModal <- function(url) {
#' the current working directory called shiny_bookmarks.
#' }
#'
#' When used with [shinyApp()], this function must be called before
#' `shinyApp()`, or in the `shinyApp()`'s `onStart` function. An
#' alternative to calling the `enableBookmarking()` function is to use the
#' `enableBookmarking` *argument* for `shinyApp()`. See examples
#' When used with \code{\link{shinyApp}()}, this function must be called before
#' \code{shinyApp()}, or in the \code{shinyApp()}'s \code{onStart} function. An
#' alternative to calling the \code{enableBookmarking()} function is to use the
#' \code{enableBookmarking} \emph{argument} for \code{shinyApp()}. See examples
#' below.
#'
#' @param store Either `"url"`, which encodes all of the relevant values in
#' a URL, `"server"`, which saves to disk on the server, or
#' `"disable"`, which disables any previously-enabled bookmarking.
#' @param store Either \code{"url"}, which encodes all of the relevant values in
#' a URL, \code{"server"}, which saves to disk on the server, or
#' \code{"disable"}, which disables any previously-enabled bookmarking.
#'
#' @seealso [onBookmark()], [onBookmarked()],
#' [onRestore()], and [onRestored()] for registering
#' @seealso \code{\link{onBookmark}}, \code{\link{onBookmarked}},
#' \code{\link{onRestore}}, and \code{\link{onRestored}} for registering
#' callback functions that are invoked when the state is bookmarked or
#' restored.
#'
#' Also see [updateQueryString()].
#' Also see \code{\link{updateQueryString}}.
#'
#' @export
#' @examples
@@ -983,7 +983,7 @@ enableBookmarking <- function(store = c("url", "server", "disable")) {
#' @param names A character vector containing names of inputs to exclude from
#' bookmarking.
#' @param session A shiny session object.
#' @seealso [enableBookmarking()] for examples.
#' @seealso \code{\link{enableBookmarking}} for examples.
#' @export
setBookmarkExclude <- function(names = character(0), session = getDefaultReactiveDomain()) {
session$setBookmarkExclude(names)
@@ -998,17 +998,17 @@ setBookmarkExclude <- function(names = character(0), session = getDefaultReactiv
#' should be called within an application's server function.
#'
#' \itemize{
#' \item `onBookmark` registers a function that will be called just
#' \item \code{onBookmark} registers a function that will be called just
#' before Shiny bookmarks state.
#' \item `onBookmarked` registers a function that will be called just
#' \item \code{onBookmarked} registers a function that will be called just
#' after Shiny bookmarks state.
#' \item `onRestore` registers a function that will be called when a
#' \item \code{onRestore} registers a function that will be called when a
#' session is restored, after the server function executes, but before all
#' other reactives, observers and render functions are run.
#' \item `onRestored` registers a function that will be called after a
#' session is restored. This is similar to `onRestore`, but it will be
#' \item \code{onRestored} registers a function that will be called after a
#' session is restored. This is similar to \code{onRestore}, but it will be
#' called after all reactives, observers, and render functions run, and
#' after results are sent to the client browser. `onRestored`
#' after results are sent to the client browser. \code{onRestored}
#' callbacks can be useful for sending update messages to the client
#' browser.
#' }
@@ -1019,25 +1019,25 @@ setBookmarkExclude <- function(names = character(0), session = getDefaultReactiv
#' arguments to cancel the registration.
#'
#' The callback function that is passed to these functions should take one
#' argument, typically named "state" (for `onBookmark`, `onRestore`,
#' and `onRestored`) or "url" (for `onBookmarked`).
#' argument, typically named "state" (for \code{onBookmark}, \code{onRestore},
#' and \code{onRestored}) or "url" (for \code{onBookmarked}).
#'
#' For `onBookmark`, the state object has three relevant fields. The
#' `values` field is an environment which can be used to save arbitrary
#' For \code{onBookmark}, the state object has three relevant fields. The
#' \code{values} field is an environment which can be used to save arbitrary
#' values (see examples). If the state is being saved to disk (as opposed to
#' being encoded in a URL), the `dir` field contains the name of a
#' being encoded in a URL), the \code{dir} field contains the name of a
#' directory which can be used to store extra files. Finally, the state object
#' has an `input` field, which is simply the application's `input`
#' has an \code{input} field, which is simply the application's \code{input}
#' object. It can be read, but not modified.
#'
#' For `onRestore` and `onRestored`, the state object is a list. This
#' list contains `input`, which is a named list of input values to restore,
#' `values`, which is an environment containing arbitrary values that were
#' saved in `onBookmark`, and `dir`, the name of the directory that
#' For \code{onRestore} and \code{onRestored}, the state object is a list. This
#' list contains \code{input}, which is a named list of input values to restore,
#' \code{values}, which is an environment containing arbitrary values that were
#' saved in \code{onBookmark}, and \code{dir}, the name of the directory that
#' the state is being restored from, and which could have been used to save
#' extra files.
#'
#' For `onBookmarked`, the callback function receives a string with the
#' For \code{onBookmarked}, the callback function receives a string with the
#' bookmark URL. This callback function should be used to display UI in the
#' client browser with the bookmark URL. If no callback function is registered,
#' then Shiny will by default display a modal dialog with the bookmark URL.

View File

@@ -10,25 +10,25 @@
#'
#' @param ... Elements to include within the page
#' @param title The browser window title (defaults to the host URL of the page).
#' Can also be set as a side effect of the [titlePanel()] function.
#' Can also be set as a side effect of the \code{\link{titlePanel}} function.
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @param theme Alternative Bootstrap stylesheet (normally a css file within the
#' www directory). For example, to use the theme located at
#' `www/bootstrap.css` you would use `theme = "bootstrap.css"`.
#' \code{www/bootstrap.css} you would use \code{theme = "bootstrap.css"}.
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI defintion that can be passed to the \link{shinyUI} function.
#'
#' @details To create a fluid page use the `fluidPage` function and include
#' instances of `fluidRow` and [column()] within it. As an
#' @details To create a fluid page use the \code{fluidPage} function and include
#' instances of \code{fluidRow} and \code{\link{column}} within it. As an
#' alternative to low-level row and column functions you can also use
#' higher-level layout functions like [sidebarLayout()].
#' higher-level layout functions like \code{\link{sidebarLayout}}.
#'
#' @note See the [
#' Shiny-Application-Layout-Guide](http://shiny.rstudio.com/articles/layout-guide.html) for additional details on laying out fluid
#' @note See the \href{http://shiny.rstudio.com/articles/layout-guide.html}{
#' Shiny-Application-Layout-Guide} for additional details on laying out fluid
#' pages.
#'
#' @seealso [column()], [sidebarLayout()]
#' @seealso \code{\link{column}}, \code{\link{sidebarLayout}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -116,21 +116,21 @@ fluidRow <- function(...) {
#' Bootstrap 3.
#' @param theme Alternative Bootstrap stylesheet (normally a css file within the
#' www directory). For example, to use the theme located at
#' `www/bootstrap.css` you would use `theme = "bootstrap.css"`.
#' \code{www/bootstrap.css} you would use \code{theme = "bootstrap.css"}.
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI defintion that can be passed to the \link{shinyUI} function.
#'
#' @details To create a fixed page use the `fixedPage` function and include
#' instances of `fixedRow` and [column()] within it. Note that
#' unlike [fluidPage()], fixed pages cannot make use of higher-level
#' layout functions like `sidebarLayout`, rather, all layout must be done
#' with `fixedRow` and `column`.
#' @details To create a fixed page use the \code{fixedPage} function and include
#' instances of \code{fixedRow} and \code{\link{column}} within it. Note that
#' unlike \code{\link{fluidPage}}, fixed pages cannot make use of higher-level
#' layout functions like \code{sidebarLayout}, rather, all layout must be done
#' with \code{fixedRow} and \code{column}.
#'
#' @note See the [
#' Shiny Application Layout Guide](http://shiny.rstudio.com/articles/layout-guide.html) for additional details on laying out fixed
#' @note See the \href{http://shiny.rstudio.com/articles/layout-guide.html}{
#' Shiny Application Layout Guide} for additional details on laying out fixed
#' pages.
#'
#' @seealso [column()]
#' @seealso \code{\link{column}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -169,8 +169,8 @@ fixedRow <- function(...) {
#' Create a column within a UI definition
#'
#' Create a column for use within a [fluidRow()] or
#' [fixedRow()]
#' Create a column for use within a \code{\link{fluidRow}} or
#' \code{\link{fixedRow}}
#'
#' @param width The grid width of the column (must be between 1 and 12)
#' @param ... Elements to include within the column
@@ -178,10 +178,10 @@ fixedRow <- function(...) {
#' previous column.
#'
#' @return A column that can be included within a
#' [fluidRow()] or [fixedRow()].
#' \code{\link{fluidRow}} or \code{\link{fixedRow}}.
#'
#'
#' @seealso [fluidRow()], [fixedRow()].
#' @seealso \code{\link{fluidRow}}, \code{\link{fixedRow}}.
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -240,7 +240,7 @@ column <- function(width, ..., offset = 0) {
#' @param windowTitle The title that should be displayed by the browser window.
#'
#' @details Calling this function has the side effect of including a
#' `title` tag within the head. You can also specify a page title
#' \code{title} tag within the head. You can also specify a page title
#' explicitly using the `title` parameter of the top-level page function.
#'
#'
@@ -267,11 +267,11 @@ titlePanel <- function(title, windowTitle=title) {
#' distinct background color and typically contains input controls. The main
#' area occupies 2/3 of the horizontal width and typically contains outputs.
#'
#' @param sidebarPanel The [sidebarPanel] containing input controls
#' @param mainPanel The [mainPanel] containing outputs
#' @param sidebarPanel The \link{sidebarPanel} containing input controls
#' @param mainPanel The \link{mainPanel} containing outputs
#' @param position The position of the sidebar relative to the main area ("left"
#' or "right")
#' @param fluid `TRUE` to use fluid layout; `FALSE` to use fixed
#' @param fluid \code{TRUE} to use fluid layout; \code{FALSE} to use fixed
#' layout.
#'
#' @examples
@@ -343,10 +343,10 @@ sidebarLayout <- function(sidebarPanel,
#' passed to the container will appear on it's own line in the UI)
#'
#' @param ... Elements to include within the container
#' @param fluid `TRUE` to use fluid layout; `FALSE` to use fixed
#' @param fluid \code{TRUE} to use fluid layout; \code{FALSE} to use fixed
#' layout.
#'
#' @seealso [fluidPage()], [flowLayout()]
#' @seealso \code{\link{fluidPage}}, \code{\link{flowLayout}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -377,14 +377,14 @@ verticalLayout <- function(..., fluid = TRUE) {
#' Lays out elements in a left-to-right, top-to-bottom arrangement. The elements
#' on a given row will be top-aligned with each other. This layout will not work
#' well with elements that have a percentage-based width (e.g.
#' [plotOutput()] at its default setting of `width = "100%"`).
#' \code{\link{plotOutput}} at its default setting of \code{width = "100\%"}).
#'
#' @param ... Unnamed arguments will become child elements of the layout. Named
#' arguments will become HTML attributes on the outermost tag.
#' @param cellArgs Any additional attributes that should be used for each cell
#' of the layout.
#'
#' @seealso [verticalLayout()]
#' @seealso \code{\link{verticalLayout}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -415,7 +415,7 @@ flowLayout <- function(..., cellArgs = list()) {
#' Input panel
#'
#' A [flowLayout()] with a grey border and light grey background,
#' A \code{\link{flowLayout}} with a grey border and light grey background,
#' suitable for wrapping inputs.
#'
#' @param ... Input controls or other HTML elements.
@@ -435,7 +435,7 @@ inputPanel <- function(...) {
#' arguments will become HTML attributes on the outermost tag.
#' @param cellWidths Character or numeric vector indicating the widths of the
#' individual cells. Recycling will be used if needed. Character values will
#' be interpreted as CSS lengths (see [validateCssUnit()]), numeric
#' be interpreted as CSS lengths (see \code{\link{validateCssUnit}}), numeric
#' values as pixels.
#' @param cellArgs Any additional attributes that should be used for each cell
#' of the layout.
@@ -509,41 +509,41 @@ splitLayout <- function(..., cellWidths = NULL, cellArgs = list()) {
#'
#' Creates row and column layouts with proportionally-sized cells, using the
#' Flex Box layout model of CSS3. These can be nested to create arbitrary
#' proportional-grid layouts. **Warning:** Flex Box is not well supported
#' proportional-grid layouts. \strong{Warning:} Flex Box is not well supported
#' by Internet Explorer, so these functions should only be used where modern
#' browsers can be assumed.
#'
#' @details If you try to use `fillRow` and `fillCol` inside of other
#' Shiny containers, such as [sidebarLayout()],
#' [navbarPage()], or even `tags$div`, you will probably find
#' that they will not appear. This is due to `fillRow` and `fillCol`
#' defaulting to `height="100%"`, which will only work inside of
#' @details If you try to use \code{fillRow} and \code{fillCol} inside of other
#' Shiny containers, such as \code{\link{sidebarLayout}},
#' \code{\link{navbarPage}}, or even \code{tags$div}, you will probably find
#' that they will not appear. This is due to \code{fillRow} and \code{fillCol}
#' defaulting to \code{height="100\%"}, which will only work inside of
#' containers that have determined their own size (rather than shrinking to
#' the size of their contents, as is usually the case in HTML).
#'
#' To avoid this problem, you have two options:
#' \itemize{
#' \item only use `fillRow`/`fillCol` inside of `fillPage`,
#' `fillRow`, or `fillCol`
#' \item provide an explicit `height` argument to
#' `fillRow`/`fillCol`
#' \item only use \code{fillRow}/\code{fillCol} inside of \code{fillPage},
#' \code{fillRow}, or \code{fillCol}
#' \item provide an explicit \code{height} argument to
#' \code{fillRow}/\code{fillCol}
#' }
#'
#' @param ... UI objects to put in each row/column cell; each argument will
#' occupy a single cell. (To put multiple items in a single cell, you can use
#' [tagList()] or [div()] to combine them.) Named
#' arguments will be used as attributes on the `div` element that
#' \code{\link{tagList}} or \code{\link{div}} to combine them.) Named
#' arguments will be used as attributes on the \code{div} element that
#' encapsulates the row/column.
#' @param flex Determines how space should be distributed to the cells. Can be a
#' single value like `1` or `2` to evenly distribute the available
#' single value like \code{1} or \code{2} to evenly distribute the available
#' space; or use a vector of numbers to specify the proportions. For example,
#' `flex = c(2, 3)` would cause the space to be split 40\%/60\% between
#' \code{flex = c(2, 3)} would cause the space to be split 40\%/60\% between
#' two cells. NA values will cause the corresponding cell to be sized
#' according to its contents (without growing or shrinking).
#' @param width,height The total amount of width and height to use for the
#' entire row/column. For the default height of `"100%"` to be
#' effective, the parent must be `fillPage`, another
#' `fillRow`/`fillCol`, or some other HTML element whose height is
#' entire row/column. For the default height of \code{"100\%"} to be
#' effective, the parent must be \code{fillPage}, another
#' \code{fillRow}/\code{fillCol}, or some other HTML element whose height is
#' not determined by the height of its contents.
#'
#' @examples

View File

@@ -4,27 +4,27 @@ NULL
#' Create a Bootstrap page
#'
#' Create a Shiny UI page that loads the CSS and JavaScript for
#' [Bootstrap](http://getbootstrap.com/), and has no content in the page
#' \href{http://getbootstrap.com/}{Bootstrap}, and has no content in the page
#' body (other than what you provide).
#'
#' This function is primarily intended for users who are proficient in HTML/CSS,
#' and know how to lay out pages in Bootstrap. Most applications should use
#' [fluidPage()] along with layout functions like
#' [fluidRow()] and [sidebarLayout()].
#' \code{\link{fluidPage}} along with layout functions like
#' \code{\link{fluidRow}} and \code{\link{sidebarLayout}}.
#'
#' @param ... The contents of the document body.
#' @param title The browser window title (defaults to the host URL of the page)
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @param theme Alternative Bootstrap stylesheet (normally a css file within the
#' www directory, e.g. `www/bootstrap.css`)
#' www directory, e.g. \code{www/bootstrap.css})
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI defintion that can be passed to the \link{shinyUI} function.
#'
#' @note The `basicPage` function is deprecated, you should use the
#' [fluidPage()] function instead.
#' @note The \code{basicPage} function is deprecated, you should use the
#' \code{\link{fluidPage}} function instead.
#'
#' @seealso [fluidPage()], [fixedPage()]
#' @seealso \code{\link{fluidPage}}, \code{\link{fixedPage}}
#' @export
bootstrapPage <- function(..., title = NULL, responsive = NULL, theme = NULL) {
@@ -52,9 +52,9 @@ bootstrapPage <- function(..., title = NULL, responsive = NULL, theme = NULL) {
#' components in a web page.
#'
#' It isn't necessary to call this function if you use
#' [bootstrapPage()] or others which use `bootstrapPage`, such
#' [basicPage()], [fluidPage()], [fillPage()],
#' [pageWithSidebar()], and [navbarPage()], because they
#' \code{\link{bootstrapPage}} or others which use \code{bootstrapPage}, such
#' \code{\link{basicPage}}, \code{\link{fluidPage}}, \code{\link{fillPage}},
#' \code{\link{pageWithSidebar}}, and \code{\link{navbarPage}}, because they
#' already include the Bootstrap web dependencies.
#'
#' @inheritParams bootstrapPage
@@ -85,34 +85,34 @@ basicPage <- function(...) {
#' Create a page that fills the window
#'
#' `fillPage` creates a page whose height and width always fill the
#' \code{fillPage} creates a page whose height and width always fill the
#' available area of the browser window.
#'
#' The [fluidPage()] and [fixedPage()] functions are used
#' The \code{\link{fluidPage}} and \code{\link{fixedPage}} functions are used
#' for creating web pages that are laid out from the top down, leaving
#' whitespace at the bottom if the page content's height is smaller than the
#' browser window, and scrolling if the content is larger than the window.
#'
#' `fillPage` is designed to latch the document body's size to the size of
#' \code{fillPage} is designed to latch the document body's size to the size of
#' the window. This makes it possible to fill it with content that also scales
#' to the size of the window.
#'
#' For example, `fluidPage(plotOutput("plot", height = "100%"))` will not
#' work as expected; the plot element's effective height will be `0`,
#' because the plot's containing elements (`<div>` and `<body>`) have
#' *automatic* height; that is, they determine their own height based on
#' For example, \code{fluidPage(plotOutput("plot", height = "100\%"))} will not
#' work as expected; the plot element's effective height will be \code{0},
#' because the plot's containing elements (\code{<div>} and \code{<body>}) have
#' \emph{automatic} height; that is, they determine their own height based on
#' the height of their contained elements. However,
#' `fillPage(plotOutput("plot", height = "100%"))` will work because
#' `fillPage` fixes the `<body>` height at 100\% of the window height.
#' \code{fillPage(plotOutput("plot", height = "100\%"))} will work because
#' \code{fillPage} fixes the \code{<body>} height at 100\% of the window height.
#'
#' Note that `fillPage(plotOutput("plot"))` will not cause the plot to fill
#' the page. Like most Shiny output widgets, `plotOutput`'s default height
#' is a fixed number of pixels. You must explicitly set `height = "100%"`
#' Note that \code{fillPage(plotOutput("plot"))} will not cause the plot to fill
#' the page. Like most Shiny output widgets, \code{plotOutput}'s default height
#' is a fixed number of pixels. You must explicitly set \code{height = "100\%"}
#' if you want a plot (or htmlwidget, say) to fill its container.
#'
#' One must be careful what layouts/panels/elements come between the
#' `fillPage` and the plots/widgets. Any container that has an automatic
#' height will cause children with `height = "100%"` to misbehave. Stick
#' \code{fillPage} and the plots/widgets. Any container that has an automatic
#' height will cause children with \code{height = "100\%"} to misbehave. Stick
#' to functions that are designed for fill layouts, such as the ones in this
#' package.
#'
@@ -127,7 +127,7 @@ basicPage <- function(...) {
#' be interpreted as top, right, bottom, and left respectively.
#' @param title The title to use for the browser window/tab (it will not be
#' shown in the document).
#' @param bootstrap If `TRUE`, load the Bootstrap CSS library.
#' @param bootstrap If \code{TRUE}, load the Bootstrap CSS library.
#' @param theme URL to alternative Bootstrap stylesheet.
#'
#' @examples
@@ -183,14 +183,14 @@ collapseSizes <- function(padding) {
#' Create a Shiny UI that contains a header with the application title, a
#' sidebar for input controls, and a main area for output.
#'
#' @param headerPanel The [headerPanel] with the application title
#' @param sidebarPanel The [sidebarPanel] containing input controls
#' @param mainPanel The [mainPanel] containing outputs
#' @param headerPanel The \link{headerPanel} with the application title
#' @param sidebarPanel The \link{sidebarPanel} containing input controls
#' @param mainPanel The \link{mainPanel} containing outputs
#' @return A UI defintion that can be passed to the [shinyUI] function
#' @return A UI defintion that can be passed to the \link{shinyUI} function
#'
#' @note This function is deprecated. You should use [fluidPage()]
#' along with [sidebarLayout()] to implement a page with a sidebar.
#' @note This function is deprecated. You should use \code{\link{fluidPage}}
#' along with \code{\link{sidebarLayout}} to implement a page with a sidebar.
#'
#' @examples
#' # Define UI
@@ -236,57 +236,57 @@ pageWithSidebar <- function(headerPanel,
#' Create a page with a top level navigation bar
#'
#' Create a page that contains a top level navigation bar that can be used to
#' toggle a set of [tabPanel()] elements.
#' toggle a set of \code{\link{tabPanel}} elements.
#'
#' @param title The title to display in the navbar
#' @param ... [tabPanel()] elements to include in the page. The
#' `navbarMenu` function also accepts strings, which will be used as menu
#' section headers. If the string is a set of dashes like `"----"` a
#' @param ... \code{\link{tabPanel}} elements to include in the page. The
#' \code{navbarMenu} function also accepts strings, which will be used as menu
#' section headers. If the string is a set of dashes like \code{"----"} a
#' horizontal separator will be displayed in the menu.
#' @param id If provided, you can use `input$`*`id`* in your
#' @param id If provided, you can use \code{input$}\emph{\code{id}} in your
#' server logic to determine which of the current tabs is active. The value
#' will correspond to the `value` argument that is passed to
#' [tabPanel()].
#' @param selected The `value` (or, if none was supplied, the `title`)
#' of the tab that should be selected by default. If `NULL`, the first
#' will correspond to the \code{value} argument that is passed to
#' \code{\link{tabPanel}}.
#' @param selected The \code{value} (or, if none was supplied, the \code{title})
#' of the tab that should be selected by default. If \code{NULL}, the first
#' tab will be selected.
#' @param position Determines whether the navbar should be displayed at the top
#' of the page with normal scrolling behavior (`"static-top"`), pinned at
#' the top (`"fixed-top"`), or pinned at the bottom
#' (`"fixed-bottom"`). Note that using `"fixed-top"` or
#' `"fixed-bottom"` will cause the navbar to overlay your body content,
#' of the page with normal scrolling behavior (\code{"static-top"}), pinned at
#' the top (\code{"fixed-top"}), or pinned at the bottom
#' (\code{"fixed-bottom"}). Note that using \code{"fixed-top"} or
#' \code{"fixed-bottom"} will cause the navbar to overlay your body content,
#' unless you add padding, e.g.: \code{tags$style(type="text/css", "body
#' {padding-top: 70px;}")}
#' @param header Tag or list of tags to display as a common header above all
#' tabPanels.
#' @param footer Tag or list of tags to display as a common footer below all
#' tabPanels
#' @param inverse `TRUE` to use a dark background and light text for the
#' @param inverse \code{TRUE} to use a dark background and light text for the
#' navigation bar
#' @param collapsible `TRUE` to automatically collapse the navigation
#' @param collapsible \code{TRUE} to automatically collapse the navigation
#' elements into a menu when the width of the browser is less than 940 pixels
#' (useful for viewing on smaller touchscreen device)
#' @param collapsable Deprecated; use `collapsible` instead.
#' @param fluid `TRUE` to use a fluid layout. `FALSE` to use a fixed
#' @param collapsable Deprecated; use \code{collapsible} instead.
#' @param fluid \code{TRUE} to use a fluid layout. \code{FALSE} to use a fixed
#' layout.
#' @param responsive This option is deprecated; it is no longer optional with
#' Bootstrap 3.
#' @param theme Alternative Bootstrap stylesheet (normally a css file within the
#' www directory). For example, to use the theme located at
#' `www/bootstrap.css` you would use `theme = "bootstrap.css"`.
#' \code{www/bootstrap.css} you would use \code{theme = "bootstrap.css"}.
#' @param windowTitle The title that should be displayed by the browser window.
#' Useful if `title` is not a string.
#' @param icon Optional icon to appear on a `navbarMenu` tab.
#' Useful if \code{title} is not a string.
#' @param icon Optional icon to appear on a \code{navbarMenu} tab.
#'
#' @return A UI defintion that can be passed to the [shinyUI] function.
#' @return A UI defintion that can be passed to the \link{shinyUI} function.
#'
#' @details The `navbarMenu` function can be used to create an embedded
#' @details The \code{navbarMenu} function can be used to create an embedded
#' menu within the navbar that in turns includes additional tabPanels (see
#' example below).
#'
#' @seealso [tabPanel()], [tabsetPanel()],
#' [updateNavbarPage()], [insertTab()],
#' [showTab()]
#' @seealso \code{\link{tabPanel}}, \code{\link{tabsetPanel}},
#' \code{\link{updateNavbarPage}}, \code{\link{insertTab}},
#' \code{\link{showTab}}
#'
#' @examples
#' navbarPage("App Title",
@@ -394,9 +394,9 @@ navbarPage <- function(title,
)
}
#' @param menuName A name that identifies this `navbarMenu`. This
#' @param menuName A name that identifies this \code{navbarMenu}. This
#' is needed if you want to insert/remove or show/hide an entire
#' `navbarMenu`.
#' \code{navbarMenu}.
#'
#' @rdname navbarPage
#' @export
@@ -414,8 +414,8 @@ navbarMenu <- function(title, ..., menuName = title, icon = NULL) {
#'
#' @param title An application title to display
#' @param windowTitle The title that should be displayed by the browser window.
#' Useful if `title` is not a string.
#' @return A headerPanel that can be passed to [pageWithSidebar]
#' Useful if \code{title} is not a string.
#' @return A headerPanel that can be passed to \link{pageWithSidebar}
#'
#' @examples
#' headerPanel("Hello Shiny!")
@@ -432,7 +432,7 @@ headerPanel <- function(title, windowTitle=title) {
#' Create a well panel
#'
#' Creates a panel with a slightly inset border and grey background. Equivalent
#' to Bootstrap's `well` CSS class.
#' to Bootstrap's \code{well} CSS class.
#'
#' @param ... UI elements to include inside the panel.
#' @return The newly created panel.
@@ -444,13 +444,13 @@ wellPanel <- function(...) {
#' Create a sidebar panel
#'
#' Create a sidebar panel containing input controls that can in turn be passed
#' to [sidebarLayout()].
#' to \code{\link{sidebarLayout}}.
#'
#' @param ... UI elements to include on the sidebar
#' @param width The width of the sidebar. For fluid layouts this is out of 12
#' total units; for fixed layouts it is out of whatever the width of the
#' sidebar's parent column is.
#' @return A sidebar that can be passed to [sidebarLayout()]
#' @return A sidebar that can be passed to \code{\link{sidebarLayout}}
#'
#' @examples
#' # Sidebar with controls to select a dataset and specify
@@ -473,13 +473,13 @@ sidebarPanel <- function(..., width = 4) {
#' Create a main panel
#'
#' Create a main panel containing output elements that can in turn be passed to
#' [sidebarLayout()].
#' \code{\link{sidebarLayout}}.
#'
#' @param ... Output elements to include in the main panel
#' @param width The width of the main panel. For fluid layouts this is out of 12
#' total units; for fixed layouts it is out of whatever the width of the main
#' panel's parent column is.
#' @return A main panel that can be passed to [sidebarLayout()].
#' @return A main panel that can be passed to \code{\link{sidebarLayout}}.
#'
#' @examples
#' # Show the caption and plot of the requested variable against mpg
@@ -500,22 +500,22 @@ mainPanel <- function(..., width = 8) {
#' JavaScript expression. The JS expression is evaluated once at startup and
#' whenever Shiny detects a relevant change in input/output.
#'
#' In the JS expression, you can refer to `input` and `output`
#' In the JS expression, you can refer to \code{input} and \code{output}
#' JavaScript objects that contain the current values of input and output. For
#' example, if you have an input with an id of `foo`, then you can use
#' `input.foo` to read its value. (Be sure not to modify the input/output
#' example, if you have an input with an id of \code{foo}, then you can use
#' \code{input.foo} to read its value. (Be sure not to modify the input/output
#' objects, as this may cause unpredictable behavior.)
#'
#' @param condition A JavaScript expression that will be evaluated repeatedly to
#' determine whether the panel should be displayed.
#' @param ns The [`namespace()`][NS] object of the current module, if
#' @param ns The \code{\link[=NS]{namespace}} object of the current module, if
#' any.
#' @param ... Elements to include in the panel.
#'
#' @note You are not recommended to use special JavaScript characters such as a
#' period `.` in the input id's, but if you do use them anyway, for
#' example, `inputId = "foo.bar"`, you will have to use
#' `input["foo.bar"]` instead of `input.foo.bar` to read the input
#' period \code{.} in the input id's, but if you do use them anyway, for
#' example, \code{inputId = "foo.bar"}, you will have to use
#' \code{input["foo.bar"]} instead of \code{input.foo.bar} to read the input
#' value.
#' @examples
#' ## Only run this example in interactive R sessions
@@ -589,18 +589,18 @@ helpText <- function(...) {
#' Create a tab panel
#'
#' Create a tab panel that can be included within a [tabsetPanel()].
#' Create a tab panel that can be included within a \code{\link{tabsetPanel}}.
#'
#' @param title Display title for tab
#' @param ... UI elements to include within the tab
#' @param value The value that should be sent when `tabsetPanel` reports
#' that this tab is selected. If omitted and `tabsetPanel` has an
#' `id`, then the title will be used..
#' @param value The value that should be sent when \code{tabsetPanel} reports
#' that this tab is selected. If omitted and \code{tabsetPanel} has an
#' \code{id}, then the title will be used..
#' @param icon Optional icon to appear on the tab. This attribute is only
#' valid when using a `tabPanel` within a [navbarPage()].
#' @return A tab that can be passed to [tabsetPanel()]
#' valid when using a \code{tabPanel} within a \code{\link{navbarPage}}.
#' @return A tab that can be passed to \code{\link{tabsetPanel}}
#'
#' @seealso [tabsetPanel()]
#' @seealso \code{\link{tabsetPanel}}
#'
#' @examples
#' # Show a tabset that includes a plot, summary, and
@@ -623,25 +623,25 @@ tabPanel <- function(title, ..., value = title, icon = NULL) {
#' Create a tabset panel
#'
#' Create a tabset that contains [tabPanel()] elements. Tabsets are
#' Create a tabset that contains \code{\link{tabPanel}} elements. Tabsets are
#' useful for dividing output into multiple independently viewable sections.
#'
#' @param ... [tabPanel()] elements to include in the tabset
#' @param id If provided, you can use `input$`*`id`* in your
#' @param ... \code{\link{tabPanel}} elements to include in the tabset
#' @param id If provided, you can use \code{input$}\emph{\code{id}} in your
#' server logic to determine which of the current tabs is active. The value
#' will correspond to the `value` argument that is passed to
#' [tabPanel()].
#' @param selected The `value` (or, if none was supplied, the `title`)
#' of the tab that should be selected by default. If `NULL`, the first
#' will correspond to the \code{value} argument that is passed to
#' \code{\link{tabPanel}}.
#' @param selected The \code{value} (or, if none was supplied, the \code{title})
#' of the tab that should be selected by default. If \code{NULL}, the first
#' tab will be selected.
#' @param type Use "tabs" for the standard look; Use "pills" for a more plain
#' look where tabs are selected using a background fill color.
#' @param position This argument is deprecated; it has been discontinued in
#' Bootstrap 3.
#' @return A tabset that can be passed to [mainPanel()]
#' @return A tabset that can be passed to \code{\link{mainPanel}}
#'
#' @seealso [tabPanel()], [updateTabsetPanel()],
#' [insertTab()], [showTab()]
#' @seealso \code{\link{tabPanel}}, \code{\link{updateTabsetPanel}},
#' \code{\link{insertTab}}, \code{\link{showTab}}
#'
#' @examples
#' # Show a tabset that includes a plot, summary, and
@@ -687,29 +687,29 @@ tabsetPanel <- function(...,
#' Create a navigation list panel that provides a list of links on the left
#' which navigate to a set of tabPanels displayed to the right.
#'
#' @param ... [tabPanel()] elements to include in the navlist
#' @param id If provided, you can use `input$`*`id`* in your
#' @param ... \code{\link{tabPanel}} elements to include in the navlist
#' @param id If provided, you can use \code{input$}\emph{\code{id}} in your
#' server logic to determine which of the current navlist items is active. The
#' value will correspond to the `value` argument that is passed to
#' [tabPanel()].
#' @param selected The `value` (or, if none was supplied, the `title`)
#' of the navigation item that should be selected by default. If `NULL`,
#' value will correspond to the \code{value} argument that is passed to
#' \code{\link{tabPanel}}.
#' @param selected The \code{value} (or, if none was supplied, the \code{title})
#' of the navigation item that should be selected by default. If \code{NULL},
#' the first navigation will be selected.
#' @param well `TRUE` to place a well (gray rounded rectangle) around the
#' @param well \code{TRUE} to place a well (gray rounded rectangle) around the
#' navigation list.
#' @param fluid `TRUE` to use fluid layout; `FALSE` to use fixed
#' @param fluid \code{TRUE} to use fluid layout; \code{FALSE} to use fixed
#' layout.
#' @param widths Column withs of the navigation list and tabset content areas
#' respectively.
#'
#' @details You can include headers within the `navlistPanel` by including
#' @details You can include headers within the \code{navlistPanel} by including
#' plain text elements in the list. Versions of Shiny before 0.11 supported
#' separators with "------", but as of 0.11, separators were no longer
#' supported. This is because version 0.11 switched to Bootstrap 3, which
#' doesn't support separators.
#'
#' @seealso [tabPanel()], [updateNavlistPanel()],
#' [insertTab()], [showTab()]
#' @seealso \code{\link{tabPanel}}, \code{\link{updateNavlistPanel}},
#' \code{\link{insertTab}}, \code{\link{showTab}}
#'
#' @examples
#' fluidPage(
@@ -918,14 +918,14 @@ buildTabItem <- function(index, tabsetId, foundSelected, tabs = NULL,
#' Create a text output element
#'
#' Render a reactive output variable as text within an application page. The
#' text will be included within an HTML `div` tag by default.
#' text will be included within an HTML \code{div} tag by default.
#' @param outputId output variable to read the value from
#' @param container a function to generate an HTML element to contain the text
#' @param inline use an inline (`span()`) or block container (`div()`)
#' @param inline use an inline (\code{span()}) or block container (\code{div()})
#' for the output
#' @return A text output element that can be included in a panel
#' @details Text is HTML-escaped prior to rendering. This element is often used
#' to display [renderText] output variables.
#' to display \link{renderText} output variables.
#' @examples
#' h3(textOutput("caption"))
#' @export
@@ -936,14 +936,14 @@ textOutput <- function(outputId, container = if (inline) span else div, inline =
#' Create a verbatim text output element
#'
#' Render a reactive output variable as verbatim text within an
#' application page. The text will be included within an HTML `pre` tag.
#' application page. The text will be included within an HTML \code{pre} tag.
#' @param outputId output variable to read the value from
#' @param placeholder if the output is empty or `NULL`, should an empty
#' @param placeholder if the output is empty or \code{NULL}, should an empty
#' rectangle be displayed to serve as a placeholder? (does not affect
#' behavior when the the output in nonempty)
#' @return A verbatim text output element that can be included in a panel
#' @details Text is HTML-escaped prior to rendering. This element is often used
#' with the [renderPrint] function to preserve fixed-width formatting
#' with the \link{renderPrint} function to preserve fixed-width formatting
#' of printed objects.
#' @examples
#' ## Only run this example in interactive R sessions
@@ -1066,85 +1066,86 @@ imageOutput <- function(outputId, width = "100%", height="400px",
#' Create an plot or image output element
#'
#' Render a [renderPlot()] or [renderImage()] within an
#' Render a \code{\link{renderPlot}} or \code{\link{renderImage}} within an
#' application page.
#'
#' @section Interactive plots:
#'
#' Plots and images in Shiny support mouse-based interaction, via clicking,
#' double-clicking, hovering, and brushing. When these interaction events
#' occur, the mouse coordinates will be sent to the server as `input$`
#' variables, as specified by `click`, `dblclick`, `hover`, or
#' `brush`.
#' occur, the mouse coordinates will be sent to the server as \code{input$}
#' variables, as specified by \code{click}, \code{dblclick}, \code{hover}, or
#' \code{brush}.
#'
#' For `plotOutput`, the coordinates will be sent scaled to the data
#' For \code{plotOutput}, the coordinates will be sent scaled to the data
#' space, if possible. (At the moment, plots generated by base graphics and
#' ggplot2 support this scaling, although plots generated by lattice and
#' others do not.) If scaling is not possible, the raw pixel coordinates will
#' be sent. For `imageOutput`, the coordinates will be sent in raw pixel
#' be sent. For \code{imageOutput}, the coordinates will be sent in raw pixel
#' coordinates.
#'
#' With ggplot2 graphics, the code in `renderPlot` should return a ggplot
#' With ggplot2 graphics, the code in \code{renderPlot} should return a ggplot
#' object; if instead the code prints the ggplot2 object with something like
#' `print(p)`, then the coordinates for interactive graphics will not be
#' \code{print(p)}, then the coordinates for interactive graphics will not be
#' properly scaled to the data space.
#'
#' @param outputId output variable to read the plot/image from.
#' @param width,height Image width/height. Must be a valid CSS unit (like
#' `"100%"`, `"400px"`, `"auto"`) or a number, which will be
#' coerced to a string and have `"px"` appended. These two arguments are
#' ignored when `inline = TRUE`, in which case the width/height of a plot
#' must be specified in `renderPlot()`. Note that, for height, using
#' `"auto"` or `"100%"` generally will not work as expected,
#' \code{"100\%"}, \code{"400px"}, \code{"auto"}) or a number, which will be
#' coerced to a string and have \code{"px"} appended. These two arguments are
#' ignored when \code{inline = TRUE}, in which case the width/height of a plot
#' must be specified in \code{renderPlot()}. Note that, for height, using
#' \code{"auto"} or \code{"100\%"} generally will not work as expected,
#' because of how height is computed with HTML/CSS.
#' @param click This can be `NULL` (the default), a string, or an object
#' created by the [clickOpts()] function. If you use a value like
#' `"plot_click"` (or equivalently, `clickOpts(id="plot_click")`),
#' @param click This can be \code{NULL} (the default), a string, or an object
#' created by the \code{\link{clickOpts}} function. If you use a value like
#' \code{"plot_click"} (or equivalently, \code{clickOpts(id="plot_click")}),
#' the plot will send coordinates to the server whenever it is clicked, and
#' the value will be accessible via `input$plot_click`. The value will be
#' a named list with `x` and `y` elements indicating the mouse
#' the value will be accessible via \code{input$plot_click}. The value will be
#' a named list with \code{x} and \code{y} elements indicating the mouse
#' position.
#' @param dblclick This is just like the `click` argument, but for
#' @param dblclick This is just like the \code{click} argument, but for
#' double-click events.
#' @param hover Similar to the `click` argument, this can be `NULL`
#' @param hover Similar to the \code{click} argument, this can be \code{NULL}
#' (the default), a string, or an object created by the
#' [hoverOpts()] function. If you use a value like
#' `"plot_hover"` (or equivalently, `hoverOpts(id="plot_hover")`),
#' \code{\link{hoverOpts}} function. If you use a value like
#' \code{"plot_hover"} (or equivalently, \code{hoverOpts(id="plot_hover")}),
#' the plot will send coordinates to the server pauses on the plot, and the
#' value will be accessible via `input$plot_hover`. The value will be a
#' named list with `x` and `y` elements indicating the mouse
#' value will be accessible via \code{input$plot_hover}. The value will be a
#' named list with \code{x} and \code{y} elements indicating the mouse
#' position. To control the hover time or hover delay type, you must use
#' [hoverOpts()].
#' @param clickId Deprecated; use `click` instead. Also see the
#' [clickOpts()] function.
#' @param hoverId Deprecated; use `hover` instead. Also see the
#' [hoverOpts()] function.
#' @param hoverDelay Deprecated; use `hover` instead. Also see the
#' [hoverOpts()] function.
#' @param hoverDelayType Deprecated; use `hover` instead. Also see the
#' [hoverOpts()] function.
#' @param brush Similar to the `click` argument, this can be `NULL`
#' \code{\link{hoverOpts}}.
#' @param clickId Deprecated; use \code{click} instead. Also see the
#' \code{\link{clickOpts}} function.
#' @param hoverId Deprecated; use \code{hover} instead. Also see the
#' \code{\link{hoverOpts}} function.
#' @param hoverDelay Deprecated; use \code{hover} instead. Also see the
#' \code{\link{hoverOpts}} function.
#' @param hoverDelayType Deprecated; use \code{hover} instead. Also see the
#' \code{\link{hoverOpts}} function.
#' @param brush Similar to the \code{click} argument, this can be \code{NULL}
#' (the default), a string, or an object created by the
#' [brushOpts()] function. If you use a value like
#' `"plot_brush"` (or equivalently, `brushOpts(id="plot_brush")`),
#' \code{\link{brushOpts}} function. If you use a value like
#' \code{"plot_brush"} (or equivalently, \code{brushOpts(id="plot_brush")}),
#' the plot will allow the user to "brush" in the plotting area, and will send
#' information about the brushed area to the server, and the value will be
#' accessible via `input$plot_brush`. Brushing means that the user will
#' accessible via \code{input$plot_brush}. Brushing means that the user will
#' be able to draw a rectangle in the plotting area and drag it around. The
#' value will be a named list with `xmin`, `xmax`, `ymin`, and
#' `ymax` elements indicating the brush area. To control the brush
#' behavior, use [brushOpts()]. Multiple
#' `imageOutput`/`plotOutput` calls may share the same `id`
#' value will be a named list with \code{xmin}, \code{xmax}, \code{ymin}, and
#' \code{ymax} elements indicating the brush area. To control the brush
#' behavior, use \code{\link{brushOpts}}. Multiple
#' \code{imageOutput}/\code{plotOutput} calls may share the same \code{id}
#' value; brushing one image or plot will cause any other brushes with the
#' same `id` to disappear.
#' same \code{id} to disappear.
#' @inheritParams textOutput
#' @note The arguments `clickId` and `hoverId` only work for R base graphics
#' (see the \pkg{\link[graphics:graphics-package]{graphics}} package). They do
#' not work for \pkg{\link[grid:grid-package]{grid}}-based graphics, such as
#' \pkg{ggplot2}, \pkg{lattice}, and so on.
#' @note The arguments \code{clickId} and \code{hoverId} only work for R base
#' graphics (see the \pkg{\link[graphics:graphics-package]{graphics}} package). They do not work for
#' \pkg{\link[grid:grid-package]{grid}}-based graphics, such as \pkg{ggplot2},
#' \pkg{lattice}, and so on.
#'
#' @return A plot or image output element that can be included in a panel.
#' @seealso For the corresponding server-side functions, see [renderPlot()] and
#' [renderImage()].
#' @seealso For the corresponding server-side functions, see
#' \code{\link{renderPlot}} and \code{\link{renderImage}}.
#'
#' @examples
#' # Only run these examples in interactive R sessions
@@ -1323,15 +1324,15 @@ plotOutput <- function(outputId, width = "100%", height="400px",
#' Create a table output element
#'
#' Render a [renderTable()] or [renderDataTable()] within an
#' application page. `renderTable` uses a standard HTML table, while
#' `renderDataTable` uses the DataTables Javascript library to create an
#' Render a \code{\link{renderTable}} or \code{\link{renderDataTable}} within an
#' application page. \code{renderTable} uses a standard HTML table, while
#' \code{renderDataTable} uses the DataTables Javascript library to create an
#' interactive table with more features.
#'
#' @param outputId output variable to read the table from
#' @return A table output element that can be included in a panel
#'
#' @seealso [renderTable()], [renderDataTable()].
#' @seealso \code{\link{renderTable}}, \code{\link{renderDataTable}}.
#' @examples
#' ## Only run this example in interactive R sessions
#' if (interactive()) {
@@ -1393,11 +1394,11 @@ dataTableOutput <- function(outputId) {
#' Create an HTML output element
#'
#' Render a reactive output variable as HTML within an application page. The
#' text will be included within an HTML `div` tag, and is presumed to
#' text will be included within an HTML \code{div} tag, and is presumed to
#' contain HTML content which should not be escaped.
#'
#' `uiOutput` is intended to be used with `renderUI` on the server
#' side. It is currently just an alias for `htmlOutput`.
#' \code{uiOutput} is intended to be used with \code{renderUI} on the server
#' side. It is currently just an alias for \code{htmlOutput}.
#'
#' @param outputId output variable to read the value from
#' @param ... Other arguments to pass to the container tag function. This is
@@ -1429,10 +1430,10 @@ uiOutput <- htmlOutput
#'
#' Use these functions to create a download button or link; when clicked, it
#' will initiate a browser download. The filename and contents are specified by
#' the corresponding [downloadHandler()] defined in the server
#' the corresponding \code{\link{downloadHandler}} defined in the server
#' function.
#'
#' @param outputId The name of the output slot that the `downloadHandler`
#' @param outputId The name of the output slot that the \code{downloadHandler}
#' is assigned to.
#' @param label The label that should appear on the button.
#' @param class Additional CSS classes to apply to the tag, if any.
@@ -1455,7 +1456,7 @@ uiOutput <- htmlOutput
#' }
#'
#' @aliases downloadLink
#' @seealso [downloadHandler()]
#' @seealso \code{\link{downloadHandler}}
#' @export
downloadButton <- function(outputId,
label="Download",
@@ -1484,29 +1485,43 @@ downloadLink <- function(outputId, label="Download", class=NULL, ...) {
#' Create an icon
#'
#' Create an icon for use within a page. Icons can appear on their own, inside
#' of a button, or as an icon for a [tabPanel()] within a
#' [navbarPage()].
#' of a button, or as an icon for a \code{\link{tabPanel}} within a
#' \code{\link{navbarPage}}.
#'
#' @param name Name of icon. Icons are drawn from the
#' [Font Awesome Free](https://fontawesome.com/) (currently icons from
#' the v5.3.1 set are supported with the v4 naming convention) and
#' [Glyphicons](http://getbootstrap.com/components/#glyphicons)
#' \href{https://fontawesome.com/}{Font Awesome Free} (currently icons from
#' version \Sexpr[echo=TRUE,stage=build]{shiny:::fa_version} are supported,
#' along with backward compatibility for v4 icons) and
#' \href{http://getbootstrap.com/components/#glyphicons}{Glyphicons}
#' libraries. Note that the "fa-" and "glyphicon-" prefixes should not be used
#' in icon names (i.e. the "fa-calendar" icon should be referred to as
#' "calendar")
#' "calendar").
#' @param class Additional classes to customize the style of the icon (see the
#' [usage examples](http://fontawesome.io/examples/) for details on
#' \href{http://fontawesome.io/examples/}{usage examples} for details on
#' supported styles).
#' @param lib Icon library to use ("font-awesome" or "glyphicon")
#' @param lib Icon library to use. Can be "font-awesome" (the default), "fa5",
#' "fa4", or "glyphicon". If "font-awesome", that means to use the icon with
#' the given name from the current version of Font-Awesome
#' (\Sexpr[echo=TRUE,stage=build]{shiny:::fa_version}), and if it is not found
#' there, then use the icon from Font-Awesome 4. If "fa5", that means to use
#' Font-Awesome version 5 only; if "fa4", that means to use Font-Awesome
#' version 4 only.
#'
#' @return An icon element
#'
#' @seealso For lists of available icons, see
#' [http://fontawesome.io/icons/](http://fontawesome.io/icons/) and
#' [http://getbootstrap.com/components/#glyphicons](http://getbootstrap.com/components/#glyphicons).
#' \href{http://fontawesome.io/icons/}{http://fontawesome.io/icons/} and
#' \href{http://getbootstrap.com/components/#glyphicons}{http://getbootstrap.com/components/#glyphicons}.
#'
#'
#' @examples
#' icon("calendar") # Standard icon, from Font-Awesome 5
#' icon("calendar", "fa-3x") # 3x normal size
#' icon("calendar", lib = "fa4") # From Font-Awesome 4
#' icon("battery") # This will use the "battery" icon from FA v4,
#' # because "battery" is not present in v5.
#' icon("cog", lib = "glyphicon") # From glyphicon library
#'
#' # add an icon to a submit button
#' submitButton("Update View", icon = icon("refresh"))
#'
@@ -1516,38 +1531,49 @@ downloadLink <- function(outputId, label="Download", class=NULL, ...) {
#' tabPanel("Table", icon = icon("table"))
#' )
#' @export
icon <- function(name, class = NULL, lib = "font-awesome") {
prefixes <- list(
"font-awesome" = "fa",
"glyphicon" = "glyphicon"
)
prefix <- prefixes[[lib]]
icon <- function(
name,
class = NULL,
lib = c("font-awesome", "fa4", "fa5", "glyphicon")
) {
lib <- match.arg(lib)
# determine stylesheet
if (is.null(prefix)) {
stop("Unknown font library '", lib, "' specified. Must be one of ",
paste0('"', names(prefixes), '"', collapse = ", "))
if (lib == "fa4") {
lib <- "font-awesome"
fa_ver <- "v4"
} else if (lib == "fa5") {
lib <- "font-awesome"
fa_ver <- "v5"
} else if (lib == "font-awesome") {
fa_ver <- "default"
}
# build the icon class (allow name to be null so that other functions
# e.g. buildTabset can pass an explicit class value)
iconClass <- ""
if (!is.null(name)) {
prefix_class <- prefix
if (prefix_class == "fa" && name %in% font_awesome_brands) {
prefix_class <- "fab"
if (lib == "font-awesome") {
prefix_class <- find_fa_prefix(name, fa_ver)
prefix <- "fa"
} else{
prefix_class <- "glyphicon"
prefix <- "glyphicon"
}
iconClass <- paste0(prefix_class, " ", prefix, "-", name)
}
if (!is.null(class))
if (!is.null(class)) {
iconClass <- paste(iconClass, class)
}
iconTag <- tags$i(class = iconClass)
# font-awesome needs an additional dependency (glyphicon is in bootstrap)
if (lib == "font-awesome") {
htmlDependencies(iconTag) <- htmlDependency(
"font-awesome", "5.3.1", "www/shared/fontawesome", package = "shiny",
"font-awesome", fa_version, "www/shared/fontawesome", package = "shiny",
stylesheet = c(
"css/all.min.css",
"css/v4-shims.min.css"
@@ -1562,3 +1588,29 @@ icon <- function(name, class = NULL, lib = "font-awesome") {
iconClass <- function(icon) {
if (!is.null(icon)) icon$attribs$class
}
# Returns the default Font-Awesome CSS prefix class to use for a given icon.
find_fa_prefix <- function(name, fa_ver = c("default", "v5", "v4")) {
fa_ver <- match.arg(fa_ver)
idx <- (fa_icons$name == name)
if (sum(idx) != 1) {
stop("Unknown icon name in Font-Awesome: ", name)
}
if (fa_ver == "default") {
prefix <- fa_icons$default[idx]
} else if (fa_ver == "v5") {
prefix <- fa_icons$default_v5[idx]
} else if (fa_ver == "v4") {
prefix <- fa_icons$default_v4[idx]
}
if (is.na(prefix)) {
# Will only get here for v4 or v5; there are no NA's in the `default`
# column.
stop("Unknown icon name in Font-Awesome (", fa_ver, "): ", name)
}
prefix
}

View File

@@ -1,44 +1,44 @@
#' Create a disk cache object
#'
#' A disk cache object is a key-value store that saves the values as files in a
#' directory on disk. Objects can be stored and retrieved using the `get()`
#' and `set()` methods. Objects are automatically pruned from the cache
#' according to the parameters `max_size`, `max_age`, `max_n`,
#' and `evict`.
#' directory on disk. Objects can be stored and retrieved using the \code{get()}
#' and \code{set()} methods. Objects are automatically pruned from the cache
#' according to the parameters \code{max_size}, \code{max_age}, \code{max_n},
#' and \code{evict}.
#'
#'
#' @section Missing Keys:
#'
#' The `missing` and `exec_missing` parameters controls what happens
#' when `get()` is called with a key that is not in the cache (a cache
#' miss). The default behavior is to return a [key_missing()]
#' object. This is a *sentinel value* that indicates that the key was not
#' The \code{missing} and \code{exec_missing} parameters controls what happens
#' when \code{get()} is called with a key that is not in the cache (a cache
#' miss). The default behavior is to return a \code{\link{key_missing}}
#' object. This is a \emph{sentinel value} that indicates that the key was not
#' present in the cache. You can test if the returned value represents a
#' missing key by using the [is.key_missing()] function. You can
#' also have `get()` return a different sentinel value, like `NULL`.
#' missing key by using the \code{\link{is.key_missing}} function. You can
#' also have \code{get()} return a different sentinel value, like \code{NULL}.
#' If you want to throw an error on a cache miss, you can do so by providing a
#' function for `missing` that takes one argument, the key, and also use
#' `exec_missing=TRUE`.
#' function for \code{missing} that takes one argument, the key, and also use
#' \code{exec_missing=TRUE}.
#'
#' When the cache is created, you can supply a value for `missing`, which
#' When the cache is created, you can supply a value for \code{missing}, which
#' sets the default value to be returned for missing values. It can also be
#' overridden when `get()` is called, by supplying a `missing`
#' argument. For example, if you use `cache$get("mykey", missing =
#' NULL)`, it will return `NULL` if the key is not in the cache.
#' overridden when \code{get()} is called, by supplying a \code{missing}
#' argument. For example, if you use \code{cache$get("mykey", missing =
#' NULL)}, it will return \code{NULL} if the key is not in the cache.
#'
#' If your cache is configured so that `get()` returns a sentinel value
#' to represent a cache miss, then `set` will also not allow you to store
#' If your cache is configured so that \code{get()} returns a sentinel value
#' to represent a cache miss, then \code{set} will also not allow you to store
#' the sentinel value in the cache. It will throw an error if you attempt to
#' do so.
#'
#' Instead of returning the same sentinel value each time there is cache miss,
#' the cache can execute a function each time `get()` encounters missing
#' key. If the function returns a value, then `get()` will in turn return
#' the cache can execute a function each time \code{get()} encounters missing
#' key. If the function returns a value, then \code{get()} will in turn return
#' that value. However, a more common use is for the function to throw an
#' error. If an error is thrown, then `get()` will not return a value.
#' error. If an error is thrown, then \code{get()} will not return a value.
#'
#' To do this, pass a one-argument function to `missing`, and use
#' `exec_missing=TRUE`. For example, if you want to throw an error that
#' To do this, pass a one-argument function to \code{missing}, and use
#' \code{exec_missing=TRUE}. For example, if you want to throw an error that
#' prints the missing key, you could do this:
#'
#' \preformatted{
@@ -50,58 +50,58 @@
#' )
#' }
#'
#' If you use this, the code that calls `get()` should be wrapped with
#' [tryCatch()] to gracefully handle missing keys.
#' If you use this, the code that calls \code{get()} should be wrapped with
#' \code{\link{tryCatch}()} to gracefully handle missing keys.
#'
#' @section Cache pruning:
#'
#' Cache pruning occurs when `set()` is called, or it can be invoked
#' manually by calling `prune()`.
#' Cache pruning occurs when \code{set()} is called, or it can be invoked
#' manually by calling \code{prune()}.
#'
#' The disk cache will throttle the pruning so that it does not happen on
#' every call to `set()`, because the filesystem operations for checking
#' every call to \code{set()}, because the filesystem operations for checking
#' the status of files can be slow. Instead, it will prune once in every 20
#' calls to `set()`, or if at least 5 seconds have elapsed since the last
#' calls to \code{set()}, or if at least 5 seconds have elapsed since the last
#' prune occurred, whichever is first. These parameters are currently not
#' customizable, but may be in the future.
#'
#' When a pruning occurs, if there are any objects that are older than
#' `max_age`, they will be removed.
#' \code{max_age}, they will be removed.
#'
#' The `max_size` and `max_n` parameters are applied to the cache as
#' a whole, in contrast to `max_age`, which is applied to each object
#' The \code{max_size} and \code{max_n} parameters are applied to the cache as
#' a whole, in contrast to \code{max_age}, which is applied to each object
#' individually.
#'
#' If the number of objects in the cache exceeds `max_n`, then objects
#' If the number of objects in the cache exceeds \code{max_n}, then objects
#' will be removed from the cache according to the eviction policy, which is
#' set with the `evict` parameter. Objects will be removed so that the
#' number of items is `max_n`.
#' set with the \code{evict} parameter. Objects will be removed so that the
#' number of items is \code{max_n}.
#'
#' If the size of the objects in the cache exceeds `max_size`, then
#' If the size of the objects in the cache exceeds \code{max_size}, then
#' objects will be removed from the cache. Objects will be removed from the
#' cache so that the total size remains under `max_size`. Note that the
#' cache so that the total size remains under \code{max_size}. Note that the
#' size is calculated using the size of the files, not the size of disk space
#' used by the files --- these two values can differ because of files are
#' used by the files -- these two values can differ because of files are
#' stored in blocks on disk. For example, if the block size is 4096 bytes,
#' then a file that is one byte in size will take 4096 bytes on disk.
#'
#' Another time that objects can be removed from the cache is when
#' `get()` is called. If the target object is older than `max_age`,
#' \code{get()} is called. If the target object is older than \code{max_age},
#' it will be removed and the cache will report it as a missing value.
#'
#' @section Eviction policies:
#'
#' If `max_n` or `max_size` are used, then objects will be removed
#' If \code{max_n} or \code{max_size} are used, then objects will be removed
#' from the cache according to an eviction policy. The available eviction
#' policies are:
#'
#' \describe{
#' \item{`"lru"`}{
#' \item{\code{"lru"}}{
#' Least Recently Used. The least recently used objects will be removed.
#' This uses the filesystem's mtime property. When "lru" is used, each
#' `get()` is called, it will update the file's mtime.
#' \code{get()} is called, it will update the file's mtime.
#' }
#' \item{`"fifo"`}{
#' \item{\code{"fifo"}}{
#' First-in-first-out. The oldest objects will be removed.
#' }
#' }
@@ -126,17 +126,17 @@
#' Redis, SQLite, mySQL, or similar.
#'
#' When multiple processes share a cache directory, there are some potential
#' race conditions. For example, if your code calls `exists(key)` to check
#' if an object is in the cache, and then call `get(key)`, the object may
#' be removed from the cache in between those two calls, and `get(key)`
#' race conditions. For example, if your code calls \code{exists(key)} to check
#' if an object is in the cache, and then call \code{get(key)}, the object may
#' be removed from the cache in between those two calls, and \code{get(key)}
#' will throw an error. Instead of calling the two functions, it is better to
#' simply call `get(key)`, and use `tryCatch()` to handle the error
#' simply call \code{get(key)}, and use \code{tryCatch()} to handle the error
#' that is thrown if the object is not in the cache. This effectively tests for
#' existence and gets the object in one operation.
#'
#' It is also possible for one processes to prune objects at the same time that
#' another processes is trying to prune objects. If this happens, you may see
#' a warning from `file.remove()` failing to remove a file that has
#' a warning from \code{file.remove()} failing to remove a file that has
#' already been deleted.
#'
#'
@@ -145,72 +145,72 @@
#' A disk cache object has the following methods:
#'
#' \describe{
#' \item{`get(key, missing, exec_missing)`}{
#' Returns the value associated with `key`. If the key is not in the
#' cache, then it returns the value specified by `missing` or,
#' `missing` is a function and `exec_missing=TRUE`, then
#' executes `missing`. The function can throw an error or return the
#' \item{\code{get(key, missing, exec_missing)}}{
#' Returns the value associated with \code{key}. If the key is not in the
#' cache, then it returns the value specified by \code{missing} or,
#' \code{missing} is a function and \code{exec_missing=TRUE}, then
#' executes \code{missing}. The function can throw an error or return the
#' value. If either of these parameters are specified here, then they
#' will override the defaults that were set when the DiskCache object was
#' created. See section Missing Keys for more information.
#' }
#' \item{`set(key, value)`}{
#' Stores the `key`-`value` pair in the cache.
#' \item{\code{set(key, value)}}{
#' Stores the \code{key}-\code{value} pair in the cache.
#' }
#' \item{`exists(key)`}{
#' Returns `TRUE` if the cache contains the key, otherwise
#' `FALSE`.
#' \item{\code{exists(key)}}{
#' Returns \code{TRUE} if the cache contains the key, otherwise
#' \code{FALSE}.
#' }
#' \item{`size()`}{
#' \item{\code{size()}}{
#' Returns the number of items currently in the cache.
#' }
#' \item{`keys()`}{
#' \item{\code{keys()}}{
#' Returns a character vector of all keys currently in the cache.
#' }
#' \item{`reset()`}{
#' \item{\code{reset()}}{
#' Clears all objects from the cache.
#' }
#' \item{`destroy()`}{
#' \item{\code{destroy()}}{
#' Clears all objects in the cache, and removes the cache directory from
#' disk.
#' }
#' \item{`prune()`}{
#' Prunes the cache, using the parameters specified by `max_size`,
#' `max_age`, `max_n`, and `evict`.
#' \item{\code{prune()}}{
#' Prunes the cache, using the parameters specified by \code{max_size},
#' \code{max_age}, \code{max_n}, and \code{evict}.
#' }
#' }
#'
#' @param dir Directory to store files for the cache. If `NULL` (the
#' @param dir Directory to store files for the cache. If \code{NULL} (the
#' default) it will create and use a temporary directory.
#' @param max_age Maximum age of files in cache before they are evicted, in
#' seconds. Use `Inf` for no age limit.
#' seconds. Use \code{Inf} for no age limit.
#' @param max_size Maximum size of the cache, in bytes. If the cache exceeds
#' this size, cached objects will be removed according to the value of the
#' `evict`. Use `Inf` for no size limit.
#' \code{evict}. Use \code{Inf} for no size limit.
#' @param max_n Maximum number of objects in the cache. If the number of objects
#' exceeds this value, then cached objects will be removed according to the
#' value of `evict`. Use `Inf` for no limit of number of items.
#' value of \code{evict}. Use \code{Inf} for no limit of number of items.
#' @param evict The eviction policy to use to decide which objects are removed
#' when a cache pruning occurs. Currently, `"lru"` and `"fifo"` are
#' when a cache pruning occurs. Currently, \code{"lru"} and \code{"fifo"} are
#' supported.
#' @param destroy_on_finalize If `TRUE`, then when the DiskCache object is
#' @param destroy_on_finalize If \code{TRUE}, then when the DiskCache object is
#' garbage collected, the cache directory and all objects inside of it will be
#' deleted from disk. If `FALSE` (the default), it will do nothing when
#' deleted from disk. If \code{FALSE} (the default), it will do nothing when
#' finalized.
#' @param missing A value to return or a function to execute when
#' `get(key)` is called but the key is not present in the cache. The
#' default is a [key_missing()] object. If it is a function to
#' \code{get(key)} is called but the key is not present in the cache. The
#' default is a \code{\link{key_missing}} object. If it is a function to
#' execute, the function must take one argument (the key), and you must also
#' use `exec_missing = TRUE`. If it is a function, it is useful in most
#' use \code{exec_missing = TRUE}. If it is a function, it is useful in most
#' cases for it to throw an error, although another option is to return a
#' value. If a value is returned, that value will in turn be returned by
#' `get()`. See section Missing keys for more information.
#' @param exec_missing If `FALSE` (the default), then treat `missing`
#' as a value to return when `get()` results in a cache miss. If
#' `TRUE`, treat `missing` as a function to execute when
#' `get()` results in a cache miss.
#' \code{get()}. See section Missing keys for more information.
#' @param exec_missing If \code{FALSE} (the default), then treat \code{missing}
#' as a value to return when \code{get()} results in a cache miss. If
#' \code{TRUE}, treat \code{missing} as a function to execute when
#' \code{get()} results in a cache miss.
#' @param logfile An optional filename or connection object to where logging
#' information will be written. To log to the console, use `stdout()`.
#' information will be written. To log to the console, use \code{stdout()}.
#'
#' @export
diskCache <- function(

View File

@@ -1,50 +1,50 @@
#' Create a memory cache object
#'
#' A memory cache object is a key-value store that saves the values in an
#' environment. Objects can be stored and retrieved using the `get()` and
#' `set()` methods. Objects are automatically pruned from the cache
#' according to the parameters `max_size`, `max_age`, `max_n`,
#' and `evict`.
#' environment. Objects can be stored and retrieved using the \code{get()} and
#' \code{set()} methods. Objects are automatically pruned from the cache
#' according to the parameters \code{max_size}, \code{max_age}, \code{max_n},
#' and \code{evict}.
#'
#' In a `MemoryCache`, R objects are stored directly in the cache; they are
#' not *not* serialized before being stored in the cache. This contrasts
#' with other cache types, like [diskCache()], where objects are
#' In a \code{MemoryCache}, R objects are stored directly in the cache; they are
#' not \emph{not} serialized before being stored in the cache. This contrasts
#' with other cache types, like \code{\link{diskCache}}, where objects are
#' serialized, and the serialized object is cached. This can result in some
#' differences of behavior. For example, as long as an object is stored in a
#' MemoryCache, it will not be garbage collected.
#'
#'
#' @section Missing keys:
#' The `missing` and `exec_missing` parameters controls what happens
#' when `get()` is called with a key that is not in the cache (a cache
#' miss). The default behavior is to return a [key_missing()]
#' object. This is a *sentinel value* that indicates that the key was not
#' The \code{missing} and \code{exec_missing} parameters controls what happens
#' when \code{get()} is called with a key that is not in the cache (a cache
#' miss). The default behavior is to return a \code{\link{key_missing}}
#' object. This is a \emph{sentinel value} that indicates that the key was not
#' present in the cache. You can test if the returned value represents a
#' missing key by using the [is.key_missing()] function. You can
#' also have `get()` return a different sentinel value, like `NULL`.
#' missing key by using the \code{\link{is.key_missing}} function. You can
#' also have \code{get()} return a different sentinel value, like \code{NULL}.
#' If you want to throw an error on a cache miss, you can do so by providing a
#' function for `missing` that takes one argument, the key, and also use
#' `exec_missing=TRUE`.
#' function for \code{missing} that takes one argument, the key, and also use
#' \code{exec_missing=TRUE}.
#'
#' When the cache is created, you can supply a value for `missing`, which
#' When the cache is created, you can supply a value for \code{missing}, which
#' sets the default value to be returned for missing values. It can also be
#' overridden when `get()` is called, by supplying a `missing`
#' argument. For example, if you use `cache$get("mykey", missing =
#' NULL)`, it will return `NULL` if the key is not in the cache.
#' overridden when \code{get()} is called, by supplying a \code{missing}
#' argument. For example, if you use \code{cache$get("mykey", missing =
#' NULL)}, it will return \code{NULL} if the key is not in the cache.
#'
#' If your cache is configured so that `get()` returns a sentinel value
#' to represent a cache miss, then `set` will also not allow you to store
#' If your cache is configured so that \code{get()} returns a sentinel value
#' to represent a cache miss, then \code{set} will also not allow you to store
#' the sentinel value in the cache. It will throw an error if you attempt to
#' do so.
#'
#' Instead of returning the same sentinel value each time there is cache miss,
#' the cache can execute a function each time `get()` encounters missing
#' key. If the function returns a value, then `get()` will in turn return
#' the cache can execute a function each time \code{get()} encounters missing
#' key. If the function returns a value, then \code{get()} will in turn return
#' that value. However, a more common use is for the function to throw an
#' error. If an error is thrown, then `get()` will not return a value.
#' error. If an error is thrown, then \code{get()} will not return a value.
#'
#' To do this, pass a one-argument function to `missing`, and use
#' `exec_missing=TRUE`. For example, if you want to throw an error that
#' To do this, pass a one-argument function to \code{missing}, and use
#' \code{exec_missing=TRUE}. For example, if you want to throw an error that
#' prints the missing key, you could do this:
#'
#' \preformatted{
@@ -56,53 +56,53 @@
#' )
#' }
#'
#' If you use this, the code that calls `get()` should be wrapped with
#' [tryCatch()] to gracefully handle missing keys.
#' If you use this, the code that calls \code{get()} should be wrapped with
#' \code{\link{tryCatch}()} to gracefully handle missing keys.
#'
#' @section Cache pruning:
#'
#' Cache pruning occurs when `set()` is called, or it can be invoked
#' manually by calling `prune()`.
#' Cache pruning occurs when \code{set()} is called, or it can be invoked
#' manually by calling \code{prune()}.
#'
#' When a pruning occurs, if there are any objects that are older than
#' `max_age`, they will be removed.
#' \code{max_age}, they will be removed.
#'
#' The `max_size` and `max_n` parameters are applied to the cache as
#' a whole, in contrast to `max_age`, which is applied to each object
#' The \code{max_size} and \code{max_n} parameters are applied to the cache as
#' a whole, in contrast to \code{max_age}, which is applied to each object
#' individually.
#'
#' If the number of objects in the cache exceeds `max_n`, then objects
#' If the number of objects in the cache exceeds \code{max_n}, then objects
#' will be removed from the cache according to the eviction policy, which is
#' set with the `evict` parameter. Objects will be removed so that the
#' number of items is `max_n`.
#' set with the \code{evict} parameter. Objects will be removed so that the
#' number of items is \code{max_n}.
#'
#' If the size of the objects in the cache exceeds `max_size`, then
#' If the size of the objects in the cache exceeds \code{max_size}, then
#' objects will be removed from the cache. Objects will be removed from the
#' cache so that the total size remains under `max_size`. Note that the
#' cache so that the total size remains under \code{max_size}. Note that the
#' size is calculated using the size of the files, not the size of disk space
#' used by the files --- these two values can differ because of files are
#' used by the files -- these two values can differ because of files are
#' stored in blocks on disk. For example, if the block size is 4096 bytes,
#' then a file that is one byte in size will take 4096 bytes on disk.
#'
#' Another time that objects can be removed from the cache is when
#' `get()` is called. If the target object is older than `max_age`,
#' \code{get()} is called. If the target object is older than \code{max_age},
#' it will be removed and the cache will report it as a missing value.
#'
#' @section Eviction policies:
#'
#' If `max_n` or `max_size` are used, then objects will be removed
#' If \code{max_n} or \code{max_size} are used, then objects will be removed
#' from the cache according to an eviction policy. The available eviction
#' policies are:
#'
#' \describe{
#' \item{`"lru"`}{
#' \item{\code{"lru"}}{
#' Least Recently Used. The least recently used objects will be removed.
#' This uses the filesystem's atime property. Some filesystems do not
#' support atime, or have a very low atime resolution. The DiskCache will
#' check for atime support, and if the filesystem does not support atime,
#' a warning will be issued and the "fifo" policy will be used instead.
#' }
#' \item{`"fifo"`}{
#' \item{\code{"fifo"}}{
#' First-in-first-out. The oldest objects will be removed.
#' }
#' }
@@ -112,38 +112,38 @@
#' A disk cache object has the following methods:
#'
#' \describe{
#' \item{`get(key, missing, exec_missing)`}{
#' Returns the value associated with `key`. If the key is not in the
#' cache, then it returns the value specified by `missing` or,
#' `missing` is a function and `exec_missing=TRUE`, then
#' executes `missing`. The function can throw an error or return the
#' \item{\code{get(key, missing, exec_missing)}}{
#' Returns the value associated with \code{key}. If the key is not in the
#' cache, then it returns the value specified by \code{missing} or,
#' \code{missing} is a function and \code{exec_missing=TRUE}, then
#' executes \code{missing}. The function can throw an error or return the
#' value. If either of these parameters are specified here, then they
#' will override the defaults that were set when the DiskCache object was
#' created. See section Missing Keys for more information.
#' }
#' \item{`set(key, value)`}{
#' Stores the `key`-`value` pair in the cache.
#' \item{\code{set(key, value)}}{
#' Stores the \code{key}-\code{value} pair in the cache.
#' }
#' \item{`exists(key)`}{
#' Returns `TRUE` if the cache contains the key, otherwise
#' `FALSE`.
#' \item{\code{exists(key)}}{
#' Returns \code{TRUE} if the cache contains the key, otherwise
#' \code{FALSE}.
#' }
#' \item{`size()`}{
#' \item{\code{size()}}{
#' Returns the number of items currently in the cache.
#' }
#' \item{`keys()`}{
#' \item{\code{keys()}}{
#' Returns a character vector of all keys currently in the cache.
#' }
#' \item{`reset()`}{
#' \item{\code{reset()}}{
#' Clears all objects from the cache.
#' }
#' \item{`destroy()`}{
#' \item{\code{destroy()}}{
#' Clears all objects in the cache, and removes the cache directory from
#' disk.
#' }
#' \item{`prune()`}{
#' Prunes the cache, using the parameters specified by `max_size`,
#' `max_age`, `max_n`, and `evict`.
#' \item{\code{prune()}}{
#' Prunes the cache, using the parameters specified by \code{max_size},
#' \code{max_age}, \code{max_n}, and \code{evict}.
#' }
#' }
#'
@@ -179,7 +179,7 @@ MemoryCache <- R6Class("MemoryCache",
if (!is.numeric(max_size)) stop("max_size must be a number. Use `Inf` for no limit.")
if (!is.numeric(max_age)) stop("max_age must be a number. Use `Inf` for no limit.")
if (!is.numeric(max_n)) stop("max_n must be a number. Use `Inf` for no limit.")
private$cache <- fastmap()
private$cache <- new.env(parent = emptyenv())
private$max_size <- max_size
private$max_age <- max_age
private$max_n <- max_n
@@ -208,7 +208,7 @@ MemoryCache <- R6Class("MemoryCache",
}
private$log(paste0('get: key "', key, '" found'))
value <- private$cache$get(key)$value
value <- private$cache[[key]]$value
value
},
@@ -226,36 +226,37 @@ MemoryCache <- R6Class("MemoryCache",
size <- NULL
}
private$cache$set(key, list(
private$cache[[key]] <- list(
key = key,
value = value,
size = size,
mtime = time,
atime = time
))
)
self$prune()
invisible(self)
},
exists = function(key) {
validate_key(key)
private$cache$has(key)
# Faster than `exists(key, envir = private$cache, inherits = FALSE)
!is.null(private$cache[[key]])
},
keys = function() {
private$cache$keys()
ls(private$cache, sorted = FALSE) # Faster with sorted=FALSE
},
remove = function(key) {
private$log(paste0('remove: key "', key, '"'))
validate_key(key)
private$cache$remove(key)
rm(list = key, envir = private$cache)
invisible(self)
},
reset = function() {
private$log(paste0('reset'))
private$cache$reset()
rm(list = self$keys(), envir = private$cache)
invisible(self)
},
@@ -270,7 +271,7 @@ MemoryCache <- R6Class("MemoryCache",
rm_idx <- timediff > private$max_age
if (any(rm_idx)) {
private$log(paste0("prune max_age: Removing ", paste(info$key[rm_idx], collapse = ", ")))
private$cache$remove(info$key[rm_idx])
rm(list = info$key[rm_idx], envir = private$cache)
info <- info[!rm_idx, ]
}
}
@@ -297,7 +298,7 @@ MemoryCache <- R6Class("MemoryCache",
ensure_info_is_sorted()
rm_idx <- seq_len(nrow(info)) > private$max_n
private$log(paste0("prune max_n: Removing ", paste(info$key[rm_idx], collapse = ", ")))
private$cache$remove(info$key[rm_idx])
rm(list = info$key[rm_idx], envir = private$cache)
info <- info[!rm_idx, ]
}
@@ -307,7 +308,7 @@ MemoryCache <- R6Class("MemoryCache",
cum_size <- cumsum(info$size)
rm_idx <- cum_size > private$max_size
private$log(paste0("prune max_size: Removing ", paste(info$key[rm_idx], collapse = ", ")))
private$cache$remove(info$key[rm_idx])
rm(list = info$key[rm_idx], envir = private$cache)
info <- info[!rm_idx, ]
}
@@ -334,23 +335,23 @@ MemoryCache <- R6Class("MemoryCache",
maybe_prune_single = function(key) {
if (!is.finite(private$max_age)) return()
obj <- private$cache$get(key)
obj <- private$cache[[key]]
if (is.null(obj)) return()
timediff <- as.numeric(Sys.time()) - obj$mtime
if (timediff > private$max_age) {
private$log(paste0("pruning single object exceeding max_age: Removing ", key))
private$cache$remove(key)
rm(list = key, envir = private$cache)
}
},
object_info = function() {
keys <- private$cache$keys()
keys <- ls(private$cache, sorted = FALSE)
data.frame(
key = keys,
size = vapply(keys, function(key) private$cache$get(key)$size, 0),
mtime = vapply(keys, function(key) private$cache$get(key)$mtime, 0),
atime = vapply(keys, function(key) private$cache$get(key)$atime, 0),
size = vapply(keys, function(key) private$cache[[key]]$size, 0),
mtime = vapply(keys, function(key) private$cache[[key]]$mtime, 0),
atime = vapply(keys, function(key) private$cache[[key]]$atime, 0),
stringsAsFactors = FALSE
)
},

View File

@@ -1,10 +1,26 @@
#' @importFrom fastmap key_missing
#' A Key Missing object
#'
#' A \code{key_missing} object represents a cache miss.
#'
#' @param x An object to test.
#'
#' @seealso \code{\link{diskCache}}, \code{\link{memoryCache}}.
#'
#' @export
fastmap::key_missing
key_missing <- function() {
structure(list(), class = "key_missing")
}
#' @importFrom fastmap is.key_missing
#' @rdname key_missing
#' @export
fastmap::is.key_missing
is.key_missing <- function(x) {
inherits(x, "key_missing")
}
#' @export
print.key_missing <- function(x, ...) {
cat("<Key Missing>\n")
}
validate_key <- function(key) {
@@ -15,4 +31,3 @@ validate_key <- function(key) {
stop("Invalid key: ", key, ". Only lowercase letters and numbers are allowed.")
}
}

View File

@@ -3,9 +3,9 @@
#' Advanced (borderline internal) functions for capturing, printing, and
#' manipulating stack traces.
#'
#' @return `printError` and `printStackTrace` return
#' `invisible()`. The other functions pass through the results of
#' `expr`.
#' @return \code{printError} and \code{printStackTrace} return
#' \code{invisible()}. The other functions pass through the results of
#' \code{expr}.
#'
#' @examples
#' # Keeps tryCatch and withVisible related calls off the
@@ -106,17 +106,17 @@ getCallCategories <- function(calls) {
}, character(1))
}
#' @details `captureStackTraces` runs the given `expr` and if any
#' *uncaught* errors occur, annotates them with stack trace info for use
#' by `printError` and `printStackTrace`. It is not necessary to use
#' `captureStackTraces` around the same expression as
#' `withLogErrors`, as the latter includes a call to the former. Note
#' that if `expr` contains calls (either directly or indirectly) to
#' `try`, or `tryCatch` with an error handler, stack traces therein
#' cannot be captured unless another `captureStackTraces` call is
#' inserted in the interior of the `try` or `tryCatch`. This is
#' @details \code{captureStackTraces} runs the given \code{expr} and if any
#' \emph{uncaught} errors occur, annotates them with stack trace info for use
#' by \code{printError} and \code{printStackTrace}. It is not necessary to use
#' \code{captureStackTraces} around the same expression as
#' \code{withLogErrors}, as the latter includes a call to the former. Note
#' that if \code{expr} contains calls (either directly or indirectly) to
#' \code{try}, or \code{tryCatch} with an error handler, stack traces therein
#' cannot be captured unless another \code{captureStackTraces} call is
#' inserted in the interior of the \code{try} or \code{tryCatch}. This is
#' because these calls catch the error and prevent it from traveling up to the
#' condition handler installed by `captureStackTraces`.
#' condition handler installed by \code{captureStackTraces}.
#'
#' @param expr The expression to wrap.
#' @rdname stacktrace
@@ -209,11 +209,11 @@ doCaptureStack <- function(e) {
stop(e)
}
#' @details `withLogErrors` captures stack traces and logs errors that
#' occur in `expr`, but does allow errors to propagate beyond this point
#' @details \code{withLogErrors} captures stack traces and logs errors that
#' occur in \code{expr}, but does allow errors to propagate beyond this point
#' (i.e. it doesn't catch the error). The same caveats that apply to
#' `captureStackTraces` with regard to `try`/`tryCatch` apply
#' to `withLogErrors`.
#' \code{captureStackTraces} with regard to \code{try}/\code{tryCatch} apply
#' to \code{withLogErrors}.
#' @rdname stacktrace
#' @export
withLogErrors <- function(expr,
@@ -247,19 +247,19 @@ withLogErrors <- function(expr,
)
}
#' @details `printError` prints the error and stack trace (if any) using
#' `warning(immediate.=TRUE)`. `printStackTrace` prints the stack
#' @details \code{printError} prints the error and stack trace (if any) using
#' \code{warning(immediate.=TRUE)}. \code{printStackTrace} prints the stack
#' trace only.
#'
#' @param cond An condition object (generally, an error).
#' @param full If `TRUE`, then every element of `sys.calls()` will be
#' included in the stack trace. By default (`FALSE`), calls that Shiny
#' @param full If \code{TRUE}, then every element of \code{sys.calls()} will be
#' included in the stack trace. By default (\code{FALSE}), calls that Shiny
#' deems uninteresting will be hidden.
#' @param offset If `TRUE` (the default), srcrefs will be reassigned from
#' @param offset If \code{TRUE} (the default), srcrefs will be reassigned from
#' the calls they originated from, to the destinations of those calls. If
#' you're used to stack traces from other languages, this feels more
#' intuitive, as the definition of the function indicated in the call and the
#' location specified by the srcref match up. If `FALSE`, srcrefs will be
#' location specified by the srcref match up. If \code{FALSE}, srcrefs will be
#' left alone (traditional R treatment where the srcref is of the callsite).
#' @rdname stacktrace
#' @export
@@ -361,10 +361,10 @@ printStackTrace <- function(cond,
invisible()
}
#' @details `extractStackTrace` takes a list of calls (e.g. as returned
#' from `conditionStackTrace(cond)`) and returns a data frame with one
#' row for each stack frame and the columns `num` (stack frame number),
#' `call` (a function name or similar), and `loc` (source file path
#' @details \code{extractStackTrace} takes a list of calls (e.g. as returned
#' from \code{conditionStackTrace(cond)}) and returns a data frame with one
#' row for each stack frame and the columns \code{num} (stack frame number),
#' \code{call} (a function name or similar), and \code{loc} (source file path
#' and line number, if available). It was deprecated after shiny 1.0.5 because
#' it doesn't support deep stack traces.
#' @rdname stacktrace
@@ -537,7 +537,7 @@ offsetSrcrefs <- function(calls, offset = TRUE) {
calls
}
#' @details `formatStackTrace` is similar to `extractStackTrace`, but
#' @details \code{formatStackTrace} is similar to \code{extractStackTrace}, but
#' it returns a preformatted character vector instead of a data frame. It was
#' deprecated after shiny 1.0.5 because it doesn't support deep stack traces.
#' @param indent A string to prefix every line of the stack trace.
@@ -588,11 +588,11 @@ stripStackTrace <- function(cond) {
conditionStackTrace(cond) <- NULL
}
#' @details `conditionStackTrace` and `conditionStackTrace<-` are
#' @details \code{conditionStackTrace} and \code{conditionStackTrace<-} are
#' accessor functions for getting/setting stack traces on conditions.
#'
#' @param cond A condition that may have previously been annotated by
#' `captureStackTraces` (or `withLogErrors`).
#' \code{captureStackTraces} (or \code{withLogErrors}).
#' @rdname stacktrace
#' @export
conditionStackTrace <- function(cond) {
@@ -607,8 +607,8 @@ conditionStackTrace <- function(cond) {
invisible(cond)
}
#' @details The two functions `..stacktraceon..` and
#' `..stacktraceoff..` have no runtime behavior during normal execution;
#' @details The two functions \code{..stacktraceon..} and
#' \code{..stacktraceoff..} have no runtime behavior during normal execution;
#' they exist only to create artifacts on the stack trace (sys.call()) that
#' instruct the stack trace pretty printer what parts of the stack trace are
#' interesting or not. The initial state is 1 and we walk from the outermost
@@ -624,4 +624,4 @@ conditionStackTrace <- function(cond) {
#' @export
..stacktraceoff.. <- function(expr) expr
..stacktracefloor.. <- function(expr) expr
..stacktracefloor.. <- function(expr) expr

View File

@@ -1,75 +0,0 @@
font_awesome_brands <- c(
"500px", "accessible-icon", "accusoft", "adn", "adversal",
"affiliatetheme", "algolia", "alipay", "amazon", "amazon-pay",
"amilia", "android", "angellist", "angrycreative", "angular",
"app-store", "app-store-ios", "apper", "apple", "apple-pay",
"asymmetrik", "audible", "autoprefixer", "avianex", "aviato",
"aws", "bandcamp", "behance", "behance-square", "bimobject",
"bitbucket", "bitcoin", "bity", "black-tie", "blackberry", "blogger",
"blogger-b", "bluetooth", "bluetooth-b", "btc", "buromobelexperte",
"buysellads", "cc-amazon-pay", "cc-amex", "cc-apple-pay", "cc-diners-club",
"cc-discover", "cc-jcb", "cc-mastercard", "cc-paypal", "cc-stripe",
"cc-visa", "centercode", "chrome", "cloudscale", "cloudsmith",
"cloudversify", "codepen", "codiepie", "connectdevelop", "contao",
"cpanel", "creative-commons", "creative-commons-by", "creative-commons-nc",
"creative-commons-nc-eu", "creative-commons-nc-jp", "creative-commons-nd",
"creative-commons-pd", "creative-commons-pd-alt", "creative-commons-remix",
"creative-commons-sa", "creative-commons-sampling", "creative-commons-sampling-plus",
"creative-commons-share", "css3", "css3-alt", "cuttlefish", "d-and-d",
"dashcube", "delicious", "deploydog", "deskpro", "deviantart",
"digg", "digital-ocean", "discord", "discourse", "dochub", "docker",
"draft2digital", "dribbble", "dribbble-square", "dropbox", "drupal",
"dyalog", "earlybirds", "ebay", "edge", "elementor", "ello",
"ember", "empire", "envira", "erlang", "ethereum", "etsy", "expeditedssl",
"facebook", "facebook-f", "facebook-messenger", "facebook-square",
"firefox", "first-order", "first-order-alt", "firstdraft", "flickr",
"flipboard", "fly", "font-awesome", "font-awesome-alt", "font-awesome-flag",
"font-awesome-logo-full", "fonticons", "fonticons-fi", "fort-awesome",
"fort-awesome-alt", "forumbee", "foursquare", "free-code-camp",
"freebsd", "fulcrum", "galactic-republic", "galactic-senate",
"get-pocket", "gg", "gg-circle", "git", "git-square", "github",
"github-alt", "github-square", "gitkraken", "gitlab", "gitter",
"glide", "glide-g", "gofore", "goodreads", "goodreads-g", "google",
"google-drive", "google-play", "google-plus", "google-plus-g",
"google-plus-square", "google-wallet", "gratipay", "grav", "gripfire",
"grunt", "gulp", "hacker-news", "hacker-news-square", "hackerrank",
"hips", "hire-a-helper", "hooli", "hornbill", "hotjar", "houzz",
"html5", "hubspot", "imdb", "instagram", "internet-explorer",
"ioxhost", "itunes", "itunes-note", "java", "jedi-order", "jenkins",
"joget", "joomla", "js", "js-square", "jsfiddle", "kaggle", "keybase",
"keycdn", "kickstarter", "kickstarter-k", "korvue", "laravel",
"lastfm", "lastfm-square", "leanpub", "less", "line", "linkedin",
"linkedin-in", "linode", "linux", "lyft", "magento", "mailchimp",
"mandalorian", "markdown", "mastodon", "maxcdn", "medapps", "medium",
"medium-m", "medrt", "meetup", "megaport", "microsoft", "mix",
"mixcloud", "mizuni", "modx", "monero", "napster", "neos", "nimblr",
"nintendo-switch", "node", "node-js", "npm", "ns8", "nutritionix",
"odnoklassniki", "odnoklassniki-square", "old-republic", "opencart",
"openid", "opera", "optin-monster", "osi", "page4", "pagelines",
"palfed", "patreon", "paypal", "periscope", "phabricator", "phoenix-framework",
"phoenix-squadron", "php", "pied-piper", "pied-piper-alt", "pied-piper-hat",
"pied-piper-pp", "pinterest", "pinterest-p", "pinterest-square",
"playstation", "product-hunt", "pushed", "python", "qq", "quinscape",
"quora", "r-project", "ravelry", "react", "readme", "rebel",
"red-river", "reddit", "reddit-alien", "reddit-square", "rendact",
"renren", "replyd", "researchgate", "resolving", "rev", "rocketchat",
"rockrms", "safari", "sass", "schlix", "scribd", "searchengin",
"sellcast", "sellsy", "servicestack", "shirtsinbulk", "shopware",
"simplybuilt", "sistrix", "sith", "skyatlas", "skype", "slack",
"slack-hash", "slideshare", "snapchat", "snapchat-ghost", "snapchat-square",
"soundcloud", "speakap", "spotify", "squarespace", "stack-exchange",
"stack-overflow", "staylinked", "steam", "steam-square", "steam-symbol",
"sticker-mule", "strava", "stripe", "stripe-s", "studiovinari",
"stumbleupon", "stumbleupon-circle", "superpowers", "supple",
"teamspeak", "telegram", "telegram-plane", "tencent-weibo", "the-red-yeti",
"themeco", "themeisle", "trade-federation", "trello", "tripadvisor",
"tumblr", "tumblr-square", "twitch", "twitter", "twitter-square",
"typo3", "uber", "uikit", "uniregistry", "untappd", "usb", "ussunnah",
"vaadin", "viacoin", "viadeo", "viadeo-square", "viber", "vimeo",
"vimeo-square", "vimeo-v", "vine", "vk", "vnv", "vuejs", "weebly",
"weibo", "weixin", "whatsapp", "whatsapp-square", "whmcs", "wikipedia-w",
"windows", "wix", "wolf-pack-battalion", "wordpress", "wordpress-simple",
"wpbeginner", "wpexplorer", "wpforms", "xbox", "xing", "xing-square",
"y-combinator", "yahoo", "yandex", "yandex-international", "yelp",
"yoast", "youtube", "youtube-square", "zhihu"
)

592
R/graph.R
View File

@@ -1,66 +1,21 @@
is_installed <- function(package, version) {
installedVersion <- tryCatch(utils::packageVersion(package), error = function(e) NA)
!is.na(installedVersion) && installedVersion >= version
}
# Check that the version of an suggested package satisfies the requirements
#
# @param package The name of the suggested package
# @param version The version of the package
check_suggested <- function(package, version, location) {
if (is_installed(package, version)) {
return()
writeReactLog <- function(file=stdout(), sessionToken = NULL) {
log <- .graphStack$as_list()
if (!is.null(sessionToken)) {
log <- Filter(function(x) {
is.null(x$session) || identical(x$session, sessionToken)
}, log)
}
missing_location <- missing(location)
msg <- paste0(
sQuote(package),
if (is.na(version)) "" else paste0("(>= ", version, ")"),
" must be installed for this functionality.",
if (!missing_location)
paste0(
"\nPlease install the missing package: \n",
" source(\"https://install-github.me/", location, "\")"
)
)
if (interactive() && missing_location) {
message(msg, "\nWould you like to install it?")
if (utils::menu(c("Yes", "No")) == 1) {
return(utils::install.packages(package))
}
}
stop(msg, call. = FALSE)
cat(toJSON(log, pretty=TRUE), file=file)
}
# domain is like session
# used to help define truly global react id's.
# should work across session and in global namespace
.globals$reactIdCounter <- 0L
nextGlobalReactId <- function() {
.globals$reactIdCounter <- .globals$reactIdCounter + 1L
reactIdStr(.globals$reactIdCounter)
}
reactIdStr <- function(num) {
paste0("r", num)
}
#' Reactive Log Visualizer
#'
#' Provides an interactive browser-based tool for visualizing reactive
#' dependencies and execution in your application.
#'
#' To use the reactive log visualizer, start with a fresh R session and
#' run the command `options(shiny.reactlog=TRUE)`; then launch your
#' application in the usual way (e.g. using [runApp()]). At
#' run the command \code{options(shiny.reactlog=TRUE)}; then launch your
#' application in the usual way (e.g. using \code{\link{runApp}}). At
#' any time you can hit Ctrl+F3 (or for Mac users, Command+F3) in your
#' web browser to launch the reactive log visualization.
#'
@@ -75,499 +30,88 @@ reactIdStr <- function(num) {
#'
#' As an alternative to pressing Ctrl/Command+F3--for example, if you
#' are using reactives outside of the context of a Shiny
#' application--you can run the `reactlogShow` function, which will
#' application--you can run the \code{showReactLog} function, which will
#' generate the reactive log visualization as a static HTML file and
#' launch it in your default browser. In this case, refreshing your
#' browser will not load new activity into the report; you will need to
#' call `reactlogShow()` explicitly.
#' call \code{showReactLog()} explicitly.
#'
#' For security and performance reasons, do not enable
#' `shiny.reactlog` in production environments. When the option is
#' \code{shiny.reactlog} in production environments. When the option is
#' enabled, it's possible for any user of your app to see at least some
#' of the source code of your reactive expressions and observers.
#'
#' @name reactlog
NULL
#' @describeIn reactlog Return a list of reactive information. Can be used in conjunction with
#' [reactlog::reactlog_show] to later display the reactlog graph.
#' @param time A boolean that specifies whether or not to display the
#' time that each reactive.
#' @export
reactlog <- function() {
rLog$asList()
}
#' @describeIn reactlog Display a full reactlog graph for all sessions.
#' @inheritParams reactlog::reactlog_show
#' @export
reactlogShow <- function(time = TRUE) {
check_reactlog()
reactlog::reactlog_show(reactlog(), time = time)
}
#' @describeIn reactlog This function is deprecated. You should use [reactlogShow()]
#' @export
# legacy purposes
showReactLog <- function(time = TRUE) {
shinyDeprecated(new = "`reactlogShow`", version = "1.2.0")
reactlogShow(time = time)
}
#' @describeIn reactlog Resets the entire reactlog stack. Useful for debugging and removing all prior reactive history.
#' @export
reactlogReset <- function() {
rLog$reset()
utils::browseURL(renderReactLog(time = as.logical(time)))
}
# called in "/reactlog" middleware
renderReactlog <- function(sessionToken = NULL, time = TRUE) {
check_reactlog()
reactlog::reactlog_render(
reactlog(),
session_token = sessionToken,
time = time
)
renderReactLog <- function(sessionToken = NULL, time = TRUE) {
templateFile <- system.file('www/reactive-graph.html', package='shiny')
html <- paste(readLines(templateFile, warn=FALSE), collapse='\r\n')
tc <- textConnection(NULL, 'w')
on.exit(close(tc))
writeReactLog(tc, sessionToken)
cat('\n', file=tc)
flush(tc)
html <- sub('__DATA__', paste(textConnectionValue(tc), collapse='\r\n'), html, fixed=TRUE)
html <- sub('__TIME__', paste0('"', time, '"'), html, fixed=TRUE)
file <- tempfile(fileext = '.html')
writeLines(html, file)
return(file)
}
check_reactlog <- function() {
check_suggested("reactlog", reactlog_version())
}
# read reactlog version from description file
# prevents version mismatch in code and description file
reactlog_version <- function() {
desc <- read.dcf(system.file("DESCRIPTION", package = "shiny", mustWork = TRUE))
suggests <- desc[1,"Suggests"][[1]]
suggests_pkgs <- strsplit(suggests, "\n")[[1]]
reactlog_info <- suggests_pkgs[grepl("reactlog", suggests_pkgs)]
if (length(reactlog_info) == 0) {
stop("reactlog can not be found in shiny DESCRIPTION file")
.graphAppend <- function(logEntry, domain = getDefaultReactiveDomain()) {
if (isTRUE(getOption('shiny.reactlog'))) {
sessionToken <- if (is.null(domain)) NULL else domain$token
.graphStack$push(c(logEntry, list(
session = sessionToken,
time = as.numeric(Sys.time())
)))
}
reactlog_info <- sub("^[^\\(]*\\(", "", reactlog_info)
reactlog_info <- sub("\\)[^\\)]*$", "", reactlog_info)
reactlog_info <- sub("^[>= ]*", "", reactlog_info)
package_version(reactlog_info)
if (!is.null(domain)) {
domain$reactlog(logEntry)
}
}
.graphDependsOn <- function(id, label) {
.graphAppend(list(action='dep', id=id, dependsOn=label))
}
RLog <- R6Class(
"RLog",
portable = FALSE,
private = list(
option = "shiny.reactlog",
msgOption = "shiny.reactlog.console",
.graphDependsOnId <- function(id, dependee) {
.graphAppend(list(action='depId', id=id, dependsOn=dependee))
}
appendEntry = function(domain, logEntry) {
if (self$isLogging()) {
sessionToken <- if (is.null(domain)) NULL else domain$token
logStack$push(c(logEntry, list(
session = sessionToken,
time = as.numeric(Sys.time())
)))
}
if (!is.null(domain)) domain$reactlog(logEntry)
}
),
public = list(
msg = "<MessageLogger>",
logStack = "<Stack>",
.graphCreateContext <- function(id, label, type, prevId, domain) {
.graphAppend(list(
action='ctx', id=id, label=paste(label, collapse='\n'),
srcref=as.vector(attr(label, "srcref")), srcfile=attr(label, "srcfile"),
type=type, prevId=prevId
), domain = domain)
}
noReactIdLabel = "NoCtxReactId",
noReactId = reactIdStr("NoCtxReactId"),
dummyReactIdLabel = "DummyReactId",
dummyReactId = reactIdStr("DummyReactId"),
.graphEnterContext <- function(id) {
.graphAppend(list(action='enter', id=id))
}
asList = function() {
ret <- self$logStack$as_list()
attr(ret, "version") <- "1"
ret
},
.graphExitContext <- function(id, domain) {
.graphAppend(list(action='exit', id=id), domain = domain)
}
ctxIdStr = function(ctxId) {
if (is.null(ctxId) || identical(ctxId, "")) return(NULL)
paste0("ctx", ctxId)
},
namesIdStr = function(reactId) {
paste0("names(", reactId, ")")
},
asListIdStr = function(reactId) {
paste0("as.list(", reactId, ")")
},
asListAllIdStr = function(reactId) {
paste0("as.list(", reactId, ", all.names = TRUE)")
},
keyIdStr = function(reactId, key) {
paste0(reactId, "$", key)
},
.graphValueChange <- function(label, value) {
.graphAppend(list(
action = 'valueChange',
id = label,
value = paste(utils::capture.output(utils::str(value)), collapse='\n')
))
}
valueStr = function(value, n = 200) {
if (!self$isLogging()) {
# return a placeholder string to avoid calling str
return("<reactlog is turned off>")
}
output <- try(silent = TRUE, {
# only capture the first level of the object
utils::capture.output(utils::str(value, max.level = 1))
})
outputTxt <- paste0(output, collapse="\n")
msg$shortenString(outputTxt, n = n)
},
initialize = function(rlogOption = "shiny.reactlog", msgOption = "shiny.reactlog.console") {
private$option <- rlogOption
private$msgOption <- msgOption
self$reset()
},
reset = function() {
.globals$reactIdCounter <- 0L
self$logStack <- Stack$new()
self$msg <- MessageLogger$new(option = private$msgOption)
# setup dummy and missing react information
self$msg$setReact(force = TRUE, list(reactId = self$noReactId, label = self$noReactIdLabel))
self$msg$setReact(force = TRUE, list(reactId = self$dummyReactId, label = self$dummyReactIdLabel))
},
isLogging = function() {
isTRUE(getOption(private$option, FALSE))
},
define = function(reactId, value, label, type, domain) {
valueStr <- self$valueStr(value)
if (msg$hasReact(reactId)) {
stop("react definition for id: ", reactId, " already found!!", "Label: ", label, "Type: ", type)
}
msg$setReact(list(reactId = reactId, label = label))
msg$log("define:", msg$reactStr(reactId), msg$typeStr(type = type), msg$valueStr(valueStr))
private$appendEntry(domain, list(
action = "define",
reactId = reactId,
label = msg$shortenString(label),
type = type,
value = valueStr
))
},
defineNames = function(reactId, value, label, domain) {
self$define(self$namesIdStr(reactId), value, self$namesIdStr(label), "reactiveValuesNames", domain)
},
defineAsList = function(reactId, value, label, domain) {
self$define(self$asListIdStr(reactId), value, self$asListIdStr(label), "reactiveValuesAsList", domain)
},
defineAsListAll = function(reactId, value, label, domain) {
self$define(self$asListAllIdStr(reactId), value, self$asListAllIdStr(label), "reactiveValuesAsListAll", domain)
},
defineKey = function(reactId, value, key, label, domain) {
self$define(self$keyIdStr(reactId, key), value, self$keyIdStr(label, key), "reactiveValuesKey", domain)
},
defineObserver = function(reactId, label, domain) {
self$define(reactId, value = NULL, label, "observer", domain)
},
dependsOn = function(reactId, depOnReactId, ctxId, domain) {
if (is.null(reactId)) return()
ctxId <- ctxIdStr(ctxId)
msg$log("dependsOn:", msg$reactStr(reactId), " on", msg$reactStr(depOnReactId), msg$ctxStr(ctxId))
private$appendEntry(domain, list(
action = "dependsOn",
reactId = reactId,
depOnReactId = depOnReactId,
ctxId = ctxId
))
},
dependsOnKey = function(reactId, depOnReactId, key, ctxId, domain) {
self$dependsOn(reactId, self$keyIdStr(depOnReactId, key), ctxId, domain)
},
dependsOnRemove = function(reactId, depOnReactId, ctxId, domain) {
ctxId <- self$ctxIdStr(ctxId)
msg$log("dependsOnRemove:", msg$reactStr(reactId), " on", msg$reactStr(depOnReactId), msg$ctxStr(ctxId))
private$appendEntry(domain, list(
action = "dependsOnRemove",
reactId = reactId,
depOnReactId = depOnReactId,
ctxId = ctxId
))
},
dependsOnKeyRemove = function(reactId, depOnReactId, key, ctxId, domain) {
self$dependsOnRemove(reactId, self$keyIdStr(depOnReactId, key), ctxId, domain)
},
createContext = function(ctxId, label, type, prevCtxId, domain) {
ctxId <- self$ctxIdStr(ctxId)
prevCtxId <- self$ctxIdStr(prevCtxId)
msg$log("createContext:", msg$ctxPrevCtxStr(preCtxIdTxt = " ", ctxId, prevCtxId, type))
private$appendEntry(domain, list(
action = "createContext",
ctxId = ctxId,
label = msg$shortenString(label),
type = type,
prevCtxId = prevCtxId,
srcref = as.vector(attr(label, "srcref")), srcfile=attr(label, "srcfile")
))
},
enter = function(reactId, ctxId, type, domain) {
ctxId <- self$ctxIdStr(ctxId)
if (identical(type, "isolate")) {
msg$log("isolateEnter:", msg$reactStr(reactId), msg$ctxStr(ctxId))
msg$depthIncrement()
private$appendEntry(domain, list(
action = "isolateEnter",
reactId = reactId,
ctxId = ctxId
))
} else {
msg$log("enter:", msg$reactStr(reactId), msg$ctxStr(ctxId, type))
msg$depthIncrement()
private$appendEntry(domain, list(
action = "enter",
reactId = reactId,
ctxId = ctxId,
type = type
))
}
},
exit = function(reactId, ctxId, type, domain) {
ctxId <- self$ctxIdStr(ctxId)
if (identical(type, "isolate")) {
msg$depthDecrement()
msg$log("isolateExit:", msg$reactStr(reactId), msg$ctxStr(ctxId))
private$appendEntry(domain, list(
action = "isolateExit",
reactId = reactId,
ctxId = ctxId
))
} else {
msg$depthDecrement()
msg$log("exit:", msg$reactStr(reactId), msg$ctxStr(ctxId, type))
private$appendEntry(domain, list(
action = "exit",
reactId = reactId,
ctxId = ctxId,
type = type
))
}
},
valueChange = function(reactId, value, domain) {
valueStr <- self$valueStr(value)
msg$log("valueChange:", msg$reactStr(reactId), msg$valueStr(valueStr))
private$appendEntry(domain, list(
action = "valueChange",
reactId = reactId,
value = valueStr
))
},
valueChangeNames = function(reactId, nameValues, domain) {
self$valueChange(self$namesIdStr(reactId), nameValues, domain)
},
valueChangeAsList = function(reactId, listValue, domain) {
self$valueChange(self$asListIdStr(reactId), listValue, domain)
},
valueChangeAsListAll = function(reactId, listValue, domain) {
self$valueChange(self$asListAllIdStr(reactId), listValue, domain)
},
valueChangeKey = function(reactId, key, value, domain) {
self$valueChange(self$keyIdStr(reactId, key), value, domain)
},
invalidateStart = function(reactId, ctxId, type, domain) {
ctxId <- self$ctxIdStr(ctxId)
if (identical(type, "isolate")) {
msg$log("isolateInvalidateStart:", msg$reactStr(reactId), msg$ctxStr(ctxId))
msg$depthIncrement()
private$appendEntry(domain, list(
action = "isolateInvalidateStart",
reactId = reactId,
ctxId = ctxId
))
} else {
msg$log("invalidateStart:", msg$reactStr(reactId), msg$ctxStr(ctxId, type))
msg$depthIncrement()
private$appendEntry(domain, list(
action = "invalidateStart",
reactId = reactId,
ctxId = ctxId,
type = type
))
}
},
invalidateEnd = function(reactId, ctxId, type, domain) {
ctxId <- self$ctxIdStr(ctxId)
if (identical(type, "isolate")) {
msg$depthDecrement()
msg$log("isolateInvalidateEnd:", msg$reactStr(reactId), msg$ctxStr(ctxId))
private$appendEntry(domain, list(
action = "isolateInvalidateEnd",
reactId = reactId,
ctxId = ctxId
))
} else {
msg$depthDecrement()
msg$log("invalidateEnd:", msg$reactStr(reactId), msg$ctxStr(ctxId, type))
private$appendEntry(domain, list(
action = "invalidateEnd",
reactId = reactId,
ctxId = ctxId,
type = type
))
}
},
invalidateLater = function(reactId, runningCtx, millis, domain) {
msg$log("invalidateLater: ", millis, "ms", msg$reactStr(reactId), msg$ctxStr(runningCtx))
private$appendEntry(domain, list(
action = "invalidateLater",
reactId = reactId,
ctxId = runningCtx,
millis = millis
))
},
idle = function(domain = NULL) {
msg$log("idle")
private$appendEntry(domain, list(
action = "idle"
))
},
asyncStart = function(domain = NULL) {
msg$log("asyncStart")
private$appendEntry(domain, list(
action = "asyncStart"
))
},
asyncStop = function(domain = NULL) {
msg$log("asyncStop")
private$appendEntry(domain, list(
action = "asyncStop"
))
},
freezeReactiveVal = function(reactId, domain) {
msg$log("freeze:", msg$reactStr(reactId))
private$appendEntry(domain, list(
action = "freeze",
reactId = reactId
))
},
freezeReactiveKey = function(reactId, key, domain) {
self$freezeReactiveVal(self$keyIdStr(reactId, key), domain)
},
thawReactiveVal = function(reactId, domain) {
msg$log("thaw:", msg$reactStr(reactId))
private$appendEntry(domain, list(
action = "thaw",
reactId = reactId
))
},
thawReactiveKey = function(reactId, key, domain) {
self$thawReactiveVal(self$keyIdStr(reactId, key), domain)
},
userMark = function(domain = NULL) {
msg$log("userMark")
private$appendEntry(domain, list(
action = "userMark"
))
}
)
)
MessageLogger = R6Class(
"MessageLogger",
portable = FALSE,
public = list(
depth = 0L,
reactCache = list(),
option = "shiny.reactlog.console",
initialize = function(option = "shiny.reactlog.console", depth = 0L) {
if (!missing(depth)) self$depth <- depth
if (!missing(option)) self$option <- option
},
isLogging = function() {
isTRUE(getOption(self$option))
},
isNotLogging = function() {
! isTRUE(getOption(self$option))
},
depthIncrement = function() {
if (self$isNotLogging()) return(NULL)
self$depth <- self$depth + 1L
},
depthDecrement = function() {
if (self$isNotLogging()) return(NULL)
self$depth <- self$depth - 1L
},
hasReact = function(reactId) {
if (self$isNotLogging()) return(FALSE)
!is.null(self$getReact(reactId))
},
getReact = function(reactId, force = FALSE) {
if (identical(force, FALSE) && self$isNotLogging()) return(NULL)
self$reactCache[[reactId]]
},
setReact = function(reactObj, force = FALSE) {
if (identical(force, FALSE) && self$isNotLogging()) return(NULL)
self$reactCache[[reactObj$reactId]] <- reactObj
},
shortenString = function(txt, n = 250) {
if (is.null(txt) || isTRUE(is.na(txt))) {
return("")
}
if (nchar(txt) > n) {
return(
paste0(substr(txt, 1, n - 3), "...")
)
}
return(txt)
},
singleLine = function(txt) {
gsub("[^\\]\\n", "\\\\n", txt)
},
valueStr = function(valueStr) {
paste0(
" '", self$shortenString(self$singleLine(valueStr)), "'"
)
},
reactStr = function(reactId) {
if (self$isNotLogging()) return(NULL)
reactInfo <- self$getReact(reactId)
if (is.null(reactInfo)) return(" <UNKNOWN_REACTID>")
paste0(
" ", reactInfo$reactId, ":'", self$shortenString(self$singleLine(reactInfo$label)), "'"
)
},
typeStr = function(type = NULL) {
self$ctxStr(ctxId = NULL, type = type)
},
ctxStr = function(ctxId = NULL, type = NULL) {
if (self$isNotLogging()) return(NULL)
self$ctxPrevCtxStr(ctxId = ctxId, prevCtxId = NULL, type = type)
},
ctxPrevCtxStr = function(ctxId = NULL, prevCtxId = NULL, type = NULL, preCtxIdTxt = " in ") {
if (self$isNotLogging()) return(NULL)
paste0(
if (!is.null(ctxId)) paste0(preCtxIdTxt, ctxId),
if (!is.null(prevCtxId)) paste0(" from ", prevCtxId),
if (!is.null(type) && !identical(type, "other")) paste0(" - ", type)
)
},
log = function(...) {
if (self$isNotLogging()) return(NULL)
msg <- paste0(
paste0(rep("= ", depth), collapse = ""), "- ", paste0(..., collapse = ""),
collapse = ""
)
message(msg)
}
)
)
.graphInvalidate <- function(id, domain) {
.graphAppend(list(action='invalidate', id=id), domain)
}
#' @include stack.R
rLog <- RLog$new("shiny.reactlog", "shiny.reactlog.console")
.graphStack <- Stack$new()

View File

@@ -15,21 +15,21 @@ NULL
#' the conditional on an input or a calculated reactive, you can base it on the
#' query string). However, note that, if you're changing the query string / hash
#' programatically from within the server code, you must use
#' `updateQueryString(_yourNewQueryString_, mode = "push")`. The default
#' `mode` for `updateQueryString` is `"replace"`, which doesn't
#' \code{updateQueryString(_yourNewQueryString_, mode = "push")}. The default
#' \code{mode} for \code{updateQueryString} is \code{"replace"}, which doesn't
#' raise any events, so any observers or reactives that depend on it will
#' *not* get triggered. However, if you're changing the query string / hash
#' \emph{not} get triggered. However, if you're changing the query string / hash
#' directly by typing directly in the browser and hitting enter, you don't have
#' to worry about this.
#'
#' @param session A Shiny session object.
#'
#' @return For `getQueryString`, a named list. For example, the query
#' string `?param1=value1&param2=value2` becomes `list(param1 =
#' value1, param2 = value2)`. For `getUrlHash`, a character vector with
#' the hash (including the leading `#` symbol).
#' @return For \code{getQueryString}, a named list. For example, the query
#' string \code{?param1=value1&param2=value2} becomes \code{list(param1 =
#' value1, param2 = value2)}. For \code{getUrlHash}, a character vector with
#' the hash (including the leading \code{#} symbol).
#'
#' @seealso [updateQueryString()]
#' @seealso \code{\link{updateQueryString}}
#'
#' @examples
#' ## Only run this example in interactive R sessions

View File

@@ -2,20 +2,20 @@
#'
#' Ensure that a file-based HTML dependency (from the htmltools package) can be
#' served over Shiny's HTTP server. This function works by using
#' [addResourcePath()] to map the HTML dependency's directory to a
#' \code{\link{addResourcePath}} to map the HTML dependency's directory to a
#' URL.
#'
#' @param dependency A single HTML dependency object, created using
#' [htmltools::htmlDependency()]. If the `src` value is named,
#' then `href` and/or `file` names must be present.
#' @param scrubFile If TRUE (the default), remove `src$file` for the
#' \code{\link[htmltools]{htmlDependency}}. If the \code{src} value is named,
#' then \code{href} and/or \code{file} names must be present.
#' @param scrubFile If TRUE (the default), remove \code{src$file} for the
#' dependency. This prevents the local file path from being sent to the client
#' when dynamic web dependencies are used. If FALSE, don't remove
#' `src$file`. Setting it to FALSE should be needed only in very unusual
#' \code{src$file}. Setting it to FALSE should be needed only in very unusual
#' cases.
#'
#' @return A single HTML dependency object that has an `href`-named element
#' in its `src`.
#' @return A single HTML dependency object that has an \code{href}-named element
#' in its \code{src}.
#' @export
createWebDependency <- function(dependency, scrubFile = TRUE) {
if (is.null(dependency))

View File

@@ -1,11 +1,11 @@
#' Create an object representing click options
#'
#' This generates an object representing click options, to be passed as the
#' `click` argument of [imageOutput()] or
#' [plotOutput()].
#' \code{click} argument of \code{\link{imageOutput}} or
#' \code{\link{plotOutput}}.
#'
#' @param id Input value name. For example, if the value is `"plot_click"`,
#' then the click coordinates will be available as `input$plot_click`.
#' @param id Input value name. For example, if the value is \code{"plot_click"},
#' then the click coordinates will be available as \code{input$plot_click}.
#' @param clip Should the click area be clipped to the plotting area? If FALSE,
#' then the server will receive click events even when the mouse is outside
#' the plotting area, as long as it is still inside the image.
@@ -24,12 +24,12 @@ clickOpts <- function(id = NULL, clip = TRUE) {
#' Create an object representing double-click options
#'
#' This generates an object representing dobule-click options, to be passed as
#' the `dblclick` argument of [imageOutput()] or
#' [plotOutput()].
#' the \code{dblclick} argument of \code{\link{imageOutput}} or
#' \code{\link{plotOutput}}.
#'
#' @param id Input value name. For example, if the value is
#' `"plot_dblclick"`, then the click coordinates will be available as
#' `input$plot_dblclick`.
#' \code{"plot_dblclick"}, then the click coordinates will be available as
#' \code{input$plot_dblclick}.
#' @param clip Should the click area be clipped to the plotting area? If FALSE,
#' then the server will receive double-click events even when the mouse is
#' outside the plotting area, as long as it is still inside the image.
@@ -50,23 +50,23 @@ dblclickOpts <- function(id = NULL, clip = TRUE, delay = 400) {
#' Create an object representing hover options
#'
#' This generates an object representing hovering options, to be passed as the
#' `hover` argument of [imageOutput()] or
#' [plotOutput()].
#' \code{hover} argument of \code{\link{imageOutput}} or
#' \code{\link{plotOutput}}.
#'
#' @param id Input value name. For example, if the value is `"plot_hover"`,
#' then the hover coordinates will be available as `input$plot_hover`.
#' @param id Input value name. For example, if the value is \code{"plot_hover"},
#' then the hover coordinates will be available as \code{input$plot_hover}.
#' @param delay How long to delay (in milliseconds) when debouncing or
#' throttling, before sending the mouse location to the server.
#' @param delayType The type of algorithm for limiting the number of hover
#' events. Use `"throttle"` to limit the number of hover events to one
#' every `delay` milliseconds. Use `"debounce"` to suspend events
#' events. Use \code{"throttle"} to limit the number of hover events to one
#' every \code{delay} milliseconds. Use \code{"debounce"} to suspend events
#' while the cursor is moving, and wait until the cursor has been at rest for
#' `delay` milliseconds before sending an event.
#' \code{delay} milliseconds before sending an event.
#' @param clip Should the hover area be clipped to the plotting area? If FALSE,
#' then the server will receive hover events even when the mouse is outside
#' the plotting area, as long as it is still inside the image.
#' @param nullOutside If `TRUE` (the default), the value will be set to
#' `NULL` when the mouse exits the plotting area. If `FALSE`, the
#' @param nullOutside If \code{TRUE} (the default), the value will be set to
#' \code{NULL} when the mouse exits the plotting area. If \code{FALSE}, the
#' value will stop changing when the cursor exits the plotting area.
#' @export
hoverOpts <- function(id = NULL, delay = 300,
@@ -87,34 +87,34 @@ hoverOpts <- function(id = NULL, delay = 300,
#' Create an object representing brushing options
#'
#' This generates an object representing brushing options, to be passed as the
#' `brush` argument of [imageOutput()] or
#' [plotOutput()].
#' \code{brush} argument of \code{\link{imageOutput}} or
#' \code{\link{plotOutput}}.
#'
#' @param id Input value name. For example, if the value is `"plot_brush"`,
#' then the coordinates will be available as `input$plot_brush`. Multiple
#' `imageOutput`/`plotOutput` calls may share the same `id`
#' @param id Input value name. For example, if the value is \code{"plot_brush"},
#' then the coordinates will be available as \code{input$plot_brush}. Multiple
#' \code{imageOutput}/\code{plotOutput} calls may share the same \code{id}
#' value; brushing one image or plot will cause any other brushes with the
#' same `id` to disappear.
#' same \code{id} to disappear.
#' @param fill Fill color of the brush.
#' @param stroke Outline color of the brush.
#' @param opacity Opacity of the brush
#' @param delay How long to delay (in milliseconds) when debouncing or
#' throttling, before sending the brush data to the server.
#' @param delayType The type of algorithm for limiting the number of brush
#' events. Use `"throttle"` to limit the number of brush events to one
#' every `delay` milliseconds. Use `"debounce"` to suspend events
#' events. Use \code{"throttle"} to limit the number of brush events to one
#' every \code{delay} milliseconds. Use \code{"debounce"} to suspend events
#' while the cursor is moving, and wait until the cursor has been at rest for
#' `delay` milliseconds before sending an event.
#' \code{delay} milliseconds before sending an event.
#' @param clip Should the brush area be clipped to the plotting area? If FALSE,
#' then the user will be able to brush outside the plotting area, as long as
#' it is still inside the image.
#' @param direction The direction for brushing. If `"xy"`, the brush can be
#' drawn and moved in both x and y directions. If `"x"`, or `"y"`,
#' @param direction The direction for brushing. If \code{"xy"}, the brush can be
#' drawn and moved in both x and y directions. If \code{"x"}, or \code{"y"},
#' the brush wil work horizontally or vertically.
#' @param resetOnNew When a new image is sent to the browser (via
#' [renderImage()]), should the brush be reset? The default,
#' `FALSE`, is useful if you want to update the plot while keeping the
#' brush. Using `TRUE` is useful if you want to clear the brush whenever
#' \code{\link{renderImage}}), should the brush be reset? The default,
#' \code{FALSE}, is useful if you want to update the plot while keeping the
#' brush. Using \code{TRUE} is useful if you want to clear the brush whenever
#' the plot is updated.
#' @export
brushOpts <- function(id = NULL, fill = "#9cf", stroke = "#036",

View File

@@ -1,28 +1,28 @@
#' Find rows of data that are selected by a brush
#'
#' This function returns rows from a data frame which are under a brush used
#' with [plotOutput()].
#' with \code{\link{plotOutput}}.
#'
#' It is also possible for this function to return all rows from the input data
#' frame, but with an additional column `selected_`, which indicates which
#' rows of the input data frame are selected by the brush (`TRUE` for
#' selected, `FALSE` for not-selected). This is enabled by setting
#' `allRows=TRUE` option.
#' frame, but with an additional column \code{selected_}, which indicates which
#' rows of the input data frame are selected by the brush (\code{TRUE} for
#' selected, \code{FALSE} for not-selected). This is enabled by setting
#' \code{allRows=TRUE} option.
#'
#' The `xvar`, `yvar`, `panelvar1`, and `panelvar2`
#' The \code{xvar}, \code{yvar}, \code{panelvar1}, and \code{panelvar2}
#' arguments specify which columns in the data correspond to the x variable, y
#' variable, and panel variables of the plot. For example, if your plot is
#' `plot(x=cars$speed, y=cars$dist)`, and your brush is named
#' `"cars_brush"`, then you would use `brushedPoints(cars,
#' input$cars_brush, "speed", "dist")`.
#' \code{plot(x=cars$speed, y=cars$dist)}, and your brush is named
#' \code{"cars_brush"}, then you would use \code{brushedPoints(cars,
#' input$cars_brush, "speed", "dist")}.
#'
#' For plots created with ggplot2, it should not be necessary to specify the
#' column names; that information will already be contained in the brush,
#' provided that variables are in the original data, and not computed. For
#' example, with `ggplot(cars, aes(x=speed, y=dist)) + geom_point()`, you
#' could use `brushedPoints(cars, input$cars_brush)`. If, however, you use
#' a computed column, like `ggplot(cars, aes(x=speed/2, y=dist)) +
#' geom_point()`, then it will not be able to automatically extract column names
#' example, with \code{ggplot(cars, aes(x=speed, y=dist)) + geom_point()}, you
#' could use \code{brushedPoints(cars, input$cars_brush)}. If, however, you use
#' a computed column, like \code{ggplot(cars, aes(x=speed/2, y=dist)) +
#' geom_point()}, then it will not be able to automatically extract column names
#' and filter on them. If you want to use this function to filter data, it is
#' recommended that you not use computed columns; instead, modify the data
#' first, and then make the plot with "raw" columns in the modified data.
@@ -33,26 +33,26 @@
#' to cover a given character/factor value when it covers the center value.
#'
#' If the brush is operating in just the x or y directions (e.g., with
#' `brushOpts(direction = "x")`, then this function will filter out points
#' \code{brushOpts(direction = "x")}, then this function will filter out points
#' using just the x or y variable, whichever is appropriate.
#'
#' @param brush The data from a brush, such as `input$plot_brush`.
#' @param brush The data from a brush, such as \code{input$plot_brush}.
#' @param df A data frame from which to select rows.
#' @param xvar,yvar A string with the name of the variable on the x or y axis.
#' This must also be the name of a column in `df`. If absent, then this
#' This must also be the name of a column in \code{df}. If absent, then this
#' function will try to infer the variable from the brush (only works for
#' ggplot2).
#' @param panelvar1,panelvar2 Each of these is a string with the name of a panel
#' variable. For example, if with ggplot2, you facet on a variable called
#' `cyl`, then you can use `"cyl"` here. However, specifying the
#' \code{cyl}, then you can use \code{"cyl"} here. However, specifying the
#' panel variable should not be necessary with ggplot2; Shiny should be able
#' to auto-detect the panel variable.
#' @param allRows If `FALSE` (the default) return a data frame containing
#' the selected rows. If `TRUE`, the input data frame will have a new
#' column, `selected_`, which indicates whether the row was inside the
#' brush (`TRUE`) or outside the brush (`FALSE`).
#' @param allRows If \code{FALSE} (the default) return a data frame containing
#' the selected rows. If \code{TRUE}, the input data frame will have a new
#' column, \code{selected_}, which indicates whether the row was inside the
#' brush (\code{TRUE}) or outside the brush (\code{FALSE}).
#'
#' @seealso [plotOutput()] for example usage.
#' @seealso \code{\link{plotOutput}} for example usage.
#' @export
brushedPoints <- function(df, brush, xvar = NULL, yvar = NULL,
panelvar1 = NULL, panelvar2 = NULL,
@@ -88,14 +88,17 @@ brushedPoints <- function(df, brush, xvar = NULL, yvar = NULL,
stop("brushedPoints: not able to automatically infer `xvar` from brush")
if (!(xvar %in% names(df)))
stop("brushedPoints: `xvar` ('", xvar ,"') not in names of input")
keep_rows <- keep_rows & within_brush(df[[xvar]], brush, "x")
# Extract data values from the data frame
x <- asNumber(df[[xvar]])
keep_rows <- keep_rows & (x >= brush$xmin & x <= brush$xmax)
}
if (use_y) {
if (is.null(yvar))
stop("brushedPoints: not able to automatically infer `yvar` from brush")
if (!(yvar %in% names(df)))
stop("brushedPoints: `yvar` ('", yvar ,"') not in names of input")
keep_rows <- keep_rows & within_brush(df[[yvar]], brush, "y")
y <- asNumber(df[[yvar]])
keep_rows <- keep_rows & (y >= brush$ymin & y <= brush$ymax)
}
# Find which rows are matches for the panel vars (if present)
@@ -194,39 +197,39 @@ brushedPoints <- function(df, brush, xvar = NULL, yvar = NULL,
#'Find rows of data that are near a click/hover/double-click
#'
#'This function returns rows from a data frame which are near a click, hover, or
#'double-click, when used with [plotOutput()]. The rows will be sorted
#'double-click, when used with \code{\link{plotOutput}}. The rows will be sorted
#'by their distance to the mouse event.
#'
#'It is also possible for this function to return all rows from the input data
#'frame, but with an additional column `selected_`, which indicates which
#'rows of the input data frame are selected by the brush (`TRUE` for
#'selected, `FALSE` for not-selected). This is enabled by setting
#'`allRows=TRUE` option. If this is used, the resulting data frame will not
#'frame, but with an additional column \code{selected_}, which indicates which
#'rows of the input data frame are selected by the brush (\code{TRUE} for
#'selected, \code{FALSE} for not-selected). This is enabled by setting
#'\code{allRows=TRUE} option. If this is used, the resulting data frame will not
#'be sorted by distance to the mouse event.
#'
#'The `xvar`, `yvar`, `panelvar1`, and `panelvar2` arguments
#'The \code{xvar}, \code{yvar}, \code{panelvar1}, and \code{panelvar2} arguments
#'specify which columns in the data correspond to the x variable, y variable,
#'and panel variables of the plot. For example, if your plot is
#'`plot(x=cars$speed, y=cars$dist)`, and your click variable is named
#'`"cars_click"`, then you would use `nearPoints(cars,
#'input$cars_brush, "speed", "dist")`.
#'\code{plot(x=cars$speed, y=cars$dist)}, and your click variable is named
#'\code{"cars_click"}, then you would use \code{nearPoints(cars,
#'input$cars_brush, "speed", "dist")}.
#'
#'@inheritParams brushedPoints
#'@param coordinfo The data from a mouse event, such as `input$plot_click`.
#'@param coordinfo The data from a mouse event, such as \code{input$plot_click}.
#'@param threshold A maxmimum distance to the click point; rows in the data
#' frame where the distance to the click is less than `threshold` will be
#' frame where the distance to the click is less than \code{threshold} will be
#' returned.
#'@param maxpoints Maximum number of rows to return. If NULL (the default),
#' return all rows that are within the threshold distance.
#'@param addDist If TRUE, add a column named `dist_` that contains the
#'@param addDist If TRUE, add a column named \code{dist_} that contains the
#' distance from the coordinate to the point, in pixels. When no mouse event
#' has yet occured, the value of `dist_` will be `NA`.
#'@param allRows If `FALSE` (the default) return a data frame containing
#' the selected rows. If `TRUE`, the input data frame will have a new
#' column, `selected_`, which indicates whether the row was inside the
#' selected by the mouse event (`TRUE`) or not (`FALSE`).
#' has yet occured, the value of \code{dist_} will be \code{NA}.
#'@param allRows If \code{FALSE} (the default) return a data frame containing
#' the selected rows. If \code{TRUE}, the input data frame will have a new
#' column, \code{selected_}, which indicates whether the row was inside the
#' selected by the mouse event (\code{TRUE}) or not (\code{FALSE}).
#'
#'@seealso [plotOutput()] for more examples.
#'@seealso \code{\link{plotOutput}} for more examples.
#'
#' @examples
#' \dontrun{
@@ -278,8 +281,8 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
stop("nearPoints: `yvar` ('", yvar ,"') not in names of input")
# Extract data values from the data frame
x <- asNumber(df[[xvar]], coordinfo$domain$discrete_limits$x)
y <- asNumber(df[[yvar]], coordinfo$domain$discrete_limits$y)
x <- asNumber(df[[xvar]])
y <- asNumber(df[[yvar]])
# Get the coordinates of the point (in img pixel coordinates)
point_img <- coordinfo$coords_img
@@ -399,27 +402,11 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
# ..$ y: NULL
# $ .nonce : num 0.603
# Helper to determine if data values are within the limits of
# an input brush
within_brush <- function(vals, brush, var = "x") {
var <- match.arg(var, c("x", "y"))
vals <- asNumber(vals, brush$domain$discrete_limits[[var]])
# It's possible for a non-missing data values to not
# map to the axis limits, for example:
# https://github.com/rstudio/shiny/pull/2410#issuecomment-488100881
!is.na(vals) &
vals >= brush[[paste0(var, "min")]] &
vals <= brush[[paste0(var, "max")]]
}
# Coerce various types of variables to numbers. This works for Date, POSIXt,
# characters, and factors. Used because the mouse coords are numeric.
# The `levels` argument should be used when mapping this variable to
# a known set of discrete levels, which is needed for ggplot2 since
# it allows you to control ordering and possible values of a discrete
# positional scale (#2410)
asNumber <- function(x, levels = NULL) {
if (length(levels)) return(match(x, levels))
asNumber <- function(x) {
if (is.character(x)) x <- as.factor(x)
if (is.factor(x)) x <- as.integer(x)
as.numeric(x)

View File

@@ -31,29 +31,29 @@ startPNG <- function(filename, width, height, res, ...) {
#' Run a plotting function and save the output as a PNG
#'
#' This function returns the name of the PNG file that it generates. In
#' essence, it calls `png()`, then `func()`, then `dev.off()`.
#' So `func` must be a function that will generate a plot when used this
#' essence, it calls \code{png()}, then \code{func()}, then \code{dev.off()}.
#' So \code{func} must be a function that will generate a plot when used this
#' way.
#'
#' For output, it will try to use the following devices, in this order:
#' quartz (via [grDevices::png()]), then [Cairo::CairoPNG()],
#' and finally [grDevices::png()]. This is in order of quality of
#' output. Notably, plain `png` output on Linux and Windows may not
#' quartz (via \code{\link[grDevices]{png}}), then \code{\link[Cairo]{CairoPNG}},
#' and finally \code{\link[grDevices]{png}}. This is in order of quality of
#' output. Notably, plain \code{png} output on Linux and Windows may not
#' antialias some point shapes, resulting in poor quality output.
#'
#' In some cases, `Cairo()` provides output that looks worse than
#' `png()`. To disable Cairo output for an app, use
#' `options(shiny.usecairo=FALSE)`.
#' In some cases, \code{Cairo()} provides output that looks worse than
#' \code{png()}. To disable Cairo output for an app, use
#' \code{options(shiny.usecairo=FALSE)}.
#'
#' @param func A function that generates a plot.
#' @param filename The name of the output file. Defaults to a temp file with
#' extension `.png`.
#' extension \code{.png}.
#' @param width Width in pixels.
#' @param height Height in pixels.
#' @param res Resolution in pixels per inch. This value is passed to
#' [grDevices::png()]. Note that this affects the resolution of PNG rendering in
#' \code{\link[grDevices]{png}}. Note that this affects the resolution of PNG rendering in
#' R; it won't change the actual ppi of the browser.
#' @param ... Arguments to be passed through to [grDevices::png()].
#' @param ... Arguments to be passed through to \code{\link[grDevices]{png}}.
#' These can be used to set the width, height, background color, etc.
#' @export
plotPNG <- function(func, filename=tempfile(fileext='.png'),

View File

@@ -6,7 +6,7 @@
#' @inheritParams textInput
#' @param label The contents of the button or link--usually a text label, but
#' you could also use any other HTML, like an image.
#' @param icon An optional [icon()] to appear on the button.
#' @param icon An optional \code{\link{icon}} to appear on the button.
#' @param ... Named attributes to be applied to the button or link.
#'
#' @family input elements
@@ -36,7 +36,7 @@
#'
#' }
#'
#' @seealso [observeEvent()] and [eventReactive()]
#' @seealso \code{\link{observeEvent}} and \code{\link{eventReactive}}
#' @export
actionButton <- function(inputId, label, icon = NULL, width = NULL, ...) {

View File

@@ -3,11 +3,11 @@
#' Create a checkbox that can be used to specify logical values.
#'
#' @inheritParams textInput
#' @param value Initial value (`TRUE` or `FALSE`).
#' @param value Initial value (\code{TRUE} or \code{FALSE}).
#' @return A checkbox control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [checkboxGroupInput()], [updateCheckboxInput()]
#' @seealso \code{\link{checkboxGroupInput}}, \code{\link{updateCheckboxInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions

View File

@@ -7,25 +7,25 @@
#' @inheritParams textInput
#' @param choices List of values to show checkboxes for. If elements of the list
#' are named then that name rather than the value is displayed to the user. If
#' this argument is provided, then `choiceNames` and `choiceValues`
#' this argument is provided, then \code{choiceNames} and \code{choiceValues}
#' must not be provided, and vice-versa. The values should be strings; other
#' types (such as logicals and numbers) will be coerced to strings.
#' @param selected The values that should be initially selected, if any.
#' @param inline If `TRUE`, render the choices inline (i.e. horizontally)
#' @param inline If \code{TRUE}, render the choices inline (i.e. horizontally)
#' @param choiceNames,choiceValues List of names and values, respectively,
#' that are displayed to the user in the app and correspond to the each
#' choice (for this reason, `choiceNames` and `choiceValues`
#' choice (for this reason, \code{choiceNames} and \code{choiceValues}
#' must have the same length). If either of these arguments is
#' provided, then the other *must* be provided and `choices`
#' *must not* be provided. The advantage of using both of these over
#' a named list for `choices` is that `choiceNames` allows any
#' provided, then the other \emph{must} be provided and \code{choices}
#' \emph{must not} be provided. The advantage of using both of these over
#' a named list for \code{choices} is that \code{choiceNames} allows any
#' type of UI object to be passed through (tag objects, icons, HTML code,
#' ...), instead of just simple text. See Examples.
#'
#' @return A list of HTML elements that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [checkboxInput()], [updateCheckboxGroupInput()]
#' @seealso \code{\link{checkboxInput}}, \code{\link{updateCheckboxGroupInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -94,7 +94,7 @@ checkboxGroupInput <- function(inputId, label, choices = NULL, selected = NULL,
tags$div(id = inputId,
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
class = divClass,
shinyInputLabel(inputId, label),
controlLabel(inputId, label),
options
)
}

View File

@@ -3,32 +3,32 @@
#' Creates a text input which, when clicked on, brings up a calendar that
#' the user can click on to select dates.
#'
#' The date `format` string specifies how the date will be displayed in
#' The date \code{format} string specifies how the date will be displayed in
#' the browser. It allows the following values:
#'
#' \itemize{
#' \item `yy` Year without century (12)
#' \item `yyyy` Year with century (2012)
#' \item `mm` Month number, with leading zero (01-12)
#' \item `m` Month number, without leading zero (1-12)
#' \item `M` Abbreviated month name
#' \item `MM` Full month name
#' \item `dd` Day of month with leading zero
#' \item `d` Day of month without leading zero
#' \item `D` Abbreviated weekday name
#' \item `DD` Full weekday name
#' \item \code{yy} Year without century (12)
#' \item \code{yyyy} Year with century (2012)
#' \item \code{mm} Month number, with leading zero (01-12)
#' \item \code{m} Month number, without leading zero (1-12)
#' \item \code{M} Abbreviated month name
#' \item \code{MM} Full month name
#' \item \code{dd} Day of month with leading zero
#' \item \code{d} Day of month without leading zero
#' \item \code{D} Abbreviated weekday name
#' \item \code{DD} Full weekday name
#' }
#'
#' @inheritParams textInput
#' @param value The starting date. Either a Date object, or a string in
#' `yyyy-mm-dd` format. If NULL (the default), will use the current date
#' \code{yyyy-mm-dd} format. If NULL (the default), will use the current date
#' in the client's time zone.
#' @param min The minimum allowed date. Either a Date object, or a string in
#' `yyyy-mm-dd` format.
#' \code{yyyy-mm-dd} format.
#' @param max The maximum allowed date. Either a Date object, or a string in
#' `yyyy-mm-dd` format.
#' \code{yyyy-mm-dd} format.
#' @param format The format of the date to display in the browser. Defaults to
#' `"yyyy-mm-dd"`.
#' \code{"yyyy-mm-dd"}.
#' @param startview The date range shown when the input object is first clicked.
#' Can be "month" (the default), "year", or "decade".
#' @param weekstart Which day is the start of the week. Should be an integer
@@ -44,12 +44,12 @@
#' @param autoclose Whether or not to close the datepicker immediately when a
#' date is selected.
#' @param datesdisabled Which dates should be disabled. Either a Date object,
#' or a string in `yyyy-mm-dd` format.
#' or a string in \code{yyyy-mm-dd} format.
#' @param daysofweekdisabled Days of the week that should be disabled. Should be
#' a integer vector with values from 0 (Sunday) to 6 (Saturday).
#'
#' @family input elements
#' @seealso [dateRangeInput()], [updateDateInput()]
#' @seealso \code{\link{dateRangeInput}}, \code{\link{updateDateInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -78,7 +78,7 @@
#'
#' # Disable Mondays and Tuesdays.
#' dateInput("date7", "Date:", daysofweekdisabled = c(1,2)),
#'
#'
#' # Disable specific dates.
#' dateInput("date8", "Date:", value = "2012-02-29",
#' datesdisabled = c("2012-03-01", "2012-03-02"))
@@ -92,10 +92,14 @@ dateInput <- function(inputId, label, value = NULL, min = NULL, max = NULL,
language = "en", width = NULL, autoclose = TRUE,
datesdisabled = NULL, daysofweekdisabled = NULL) {
value <- dateYMD(value, "value")
min <- dateYMD(min, "min")
max <- dateYMD(max, "max")
datesdisabled <- dateYMD(datesdisabled, "datesdisabled")
# If value is a date object, convert it to a string with yyyy-mm-dd format
# Same for min and max
if (inherits(value, "Date")) value <- format(value, "%Y-%m-%d")
if (inherits(min, "Date")) min <- format(min, "%Y-%m-%d")
if (inherits(max, "Date")) max <- format(max, "%Y-%m-%d")
if (inherits(datesdisabled, "Date")) {
datesdisabled <- format(datesdisabled, "%Y-%m-%d")
}
value <- restoreInput(id = inputId, default = value)
@@ -103,7 +107,7 @@ dateInput <- function(inputId, label, value = NULL, min = NULL, max = NULL,
class = "shiny-date-input form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
controlLabel(inputId, label),
tags$input(type = "text",
class = "form-control",
`data-date-language` = language,

View File

@@ -3,33 +3,33 @@
#' Creates a pair of text inputs which, when clicked on, bring up calendars that
#' the user can click on to select dates.
#'
#' The date `format` string specifies how the date will be displayed in
#' The date \code{format} string specifies how the date will be displayed in
#' the browser. It allows the following values:
#'
#' \itemize{
#' \item `yy` Year without century (12)
#' \item `yyyy` Year with century (2012)
#' \item `mm` Month number, with leading zero (01-12)
#' \item `m` Month number, without leading zero (1-12)
#' \item `M` Abbreviated month name
#' \item `MM` Full month name
#' \item `dd` Day of month with leading zero
#' \item `d` Day of month without leading zero
#' \item `D` Abbreviated weekday name
#' \item `DD` Full weekday name
#' \item \code{yy} Year without century (12)
#' \item \code{yyyy} Year with century (2012)
#' \item \code{mm} Month number, with leading zero (01-12)
#' \item \code{m} Month number, without leading zero (1-12)
#' \item \code{M} Abbreviated month name
#' \item \code{MM} Full month name
#' \item \code{dd} Day of month with leading zero
#' \item \code{d} Day of month without leading zero
#' \item \code{D} Abbreviated weekday name
#' \item \code{DD} Full weekday name
#' }
#'
#' @inheritParams dateInput
#' @param start The initial start date. Either a Date object, or a string in
#' `yyyy-mm-dd` format. If NULL (the default), will use the current
#' \code{yyyy-mm-dd} format. If NULL (the default), will use the current
#' date in the client's time zone.
#' @param end The initial end date. Either a Date object, or a string in
#' `yyyy-mm-dd` format. If NULL (the default), will use the current
#' \code{yyyy-mm-dd} format. If NULL (the default), will use the current
#' date in the client's time zone.
#' @param separator String to display between the start and end input boxes.
#'
#' @family input elements
#' @seealso [dateInput()], [updateDateRangeInput()]
#' @seealso \code{\link{dateInput}}, \code{\link{updateDateRangeInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -76,10 +76,12 @@ dateRangeInput <- function(inputId, label, start = NULL, end = NULL,
weekstart = 0, language = "en", separator = " to ", width = NULL,
autoclose = TRUE) {
start <- dateYMD(start, "start")
end <- dateYMD(end, "end")
min <- dateYMD(min, "min")
max <- dateYMD(max, "max")
# If start and end are date objects, convert to a string with yyyy-mm-dd format
# Same for min and max
if (inherits(start, "Date")) start <- format(start, "%Y-%m-%d")
if (inherits(end, "Date")) end <- format(end, "%Y-%m-%d")
if (inherits(min, "Date")) min <- format(min, "%Y-%m-%d")
if (inherits(max, "Date")) max <- format(max, "%Y-%m-%d")
restored <- restoreInput(id = inputId, default = list(start, end))
start <- restored[[1]]
@@ -90,7 +92,7 @@ dateRangeInput <- function(inputId, label, start = NULL, end = NULL,
class = "shiny-date-range-input form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
controlLabel(inputId, label),
# input-daterange class is needed for dropdown behavior
div(class = "input-daterange input-group",
tags$input(

View File

@@ -6,15 +6,15 @@
#' to a dataframe. This dataframe contains one row for each selected file, and
#' the following columns:
#' \describe{
#' \item{`name`}{The filename provided by the web browser. This is
#' **not** the path to read to get at the actual data that was uploaded
#' \item{\code{name}}{The filename provided by the web browser. This is
#' \strong{not} the path to read to get at the actual data that was uploaded
#' (see
#' `datapath` column).}
#' \item{`size`}{The size of the uploaded data, in
#' \code{datapath} column).}
#' \item{\code{size}}{The size of the uploaded data, in
#' bytes.}
#' \item{`type`}{The MIME type reported by the browser (for example,
#' `text/plain`), or empty string if the browser didn't know.}
#' \item{`datapath`}{The path to a temp file that contains the data that was
#' \item{\code{type}}{The MIME type reported by the browser (for example,
#' \code{text/plain}), or empty string if the browser didn't know.}
#' \item{\code{datapath}}{The path to a temp file that contains the data that was
#' uploaded. This file may be deleted if the user performs another upload
#' operation.}
#' }
@@ -23,8 +23,8 @@
#'
#' @inheritParams textInput
#' @param multiple Whether the user should be allowed to select and upload
#' multiple files at once. **Does not work on older browsers, including
#' Internet Explorer 9 and earlier.**
#' multiple files at once. \bold{Does not work on older browsers, including
#' Internet Explorer 9 and earlier.}
#' @param accept A character vector of MIME types; gives the browser a hint of
#' what kind of files the server is expecting.
#' @param buttonLabel The label used on the button. Can be text or an HTML tag
@@ -103,7 +103,7 @@ fileInput <- function(inputId, label, multiple = FALSE, accept = NULL,
div(class = "form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
label %AND% tags$label(label),
div(class = "input-group",
tags$label(class = "input-group-btn",

View File

@@ -9,7 +9,7 @@
#' @return A numeric input control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [updateNumericInput()]
#' @seealso \code{\link{updateNumericInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -42,7 +42,7 @@ numericInput <- function(inputId, label, value, min = NA, max = NA, step = NA,
div(class = "form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
label %AND% tags$label(label, `for` = inputId),
inputTag
)
}

View File

@@ -6,7 +6,7 @@
#' @return A text input control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [updateTextInput()]
#' @seealso \code{\link{updateTextInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -30,7 +30,7 @@ passwordInput <- function(inputId, label, value = "", width = NULL,
placeholder = NULL) {
div(class = "form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
label %AND% tags$label(label, `for` = inputId),
tags$input(id = inputId, type="password", class="form-control", value=value,
placeholder = placeholder)
)

View File

@@ -3,33 +3,33 @@
#' Create a set of radio buttons used to select an item from a list.
#'
#' If you need to represent a "None selected" state, it's possible to default
#' the radio buttons to have no options selected by using `selected =
#' character(0)`. However, this is not recommended, as it gives the user no way
#' the radio buttons to have no options selected by using \code{selected =
#' character(0)}. However, this is not recommended, as it gives the user no way
#' to return to that state once they've made a selection. Instead, consider
#' having the first of your choices be `c("None selected" = "")`.
#' having the first of your choices be \code{c("None selected" = "")}.
#'
#' @inheritParams textInput
#' @param choices List of values to select from (if elements of the list are
#' named then that name rather than the value is displayed to the user). If
#' this argument is provided, then `choiceNames` and `choiceValues`
#' this argument is provided, then \code{choiceNames} and \code{choiceValues}
#' must not be provided, and vice-versa. The values should be strings; other
#' types (such as logicals and numbers) will be coerced to strings.
#' @param selected The initially selected value (if not specified then defaults
#' to the first value)
#' @param inline If `TRUE`, render the choices inline (i.e. horizontally)
#' @param inline If \code{TRUE}, render the choices inline (i.e. horizontally)
#' @return A set of radio buttons that can be added to a UI definition.
#' @param choiceNames,choiceValues List of names and values, respectively, that
#' are displayed to the user in the app and correspond to the each choice (for
#' this reason, `choiceNames` and `choiceValues` must have the same
#' this reason, \code{choiceNames} and \code{choiceValues} must have the same
#' length). If either of these arguments is provided, then the other
#' *must* be provided and `choices` *must not* be provided. The
#' advantage of using both of these over a named list for `choices` is
#' that `choiceNames` allows any type of UI object to be passed through
#' \emph{must} be provided and \code{choices} \emph{must not} be provided. The
#' advantage of using both of these over a named list for \code{choices} is
#' that \code{choiceNames} allows any type of UI object to be passed through
#' (tag objects, icons, HTML code, ...), instead of just simple text. See
#' Examples.
#'
#' @family input elements
#' @seealso [updateRadioButtons()]
#' @seealso \code{\link{updateRadioButtons}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -102,7 +102,7 @@ radioButtons <- function(inputId, label, choices = NULL, selected = NULL,
tags$div(id = inputId,
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
class = divClass,
shinyInputLabel(inputId, label),
controlLabel(inputId, label),
options
)
}

View File

@@ -3,37 +3,37 @@
#' Create a select list that can be used to choose a single or multiple items
#' from a list of values.
#'
#' By default, `selectInput()` and `selectizeInput()` use the
#' By default, \code{selectInput()} and \code{selectizeInput()} use the
#' JavaScript library \pkg{selectize.js}
#' (<https://github.com/selectize/selectize.js>) instead of the basic
#' (\url{https://github.com/selectize/selectize.js}) to instead of the basic
#' select input element. To use the standard HTML select input element, use
#' `selectInput()` with `selectize=FALSE`.
#' \code{selectInput()} with \code{selectize=FALSE}.
#'
#' In selectize mode, if the first element in `choices` has a value of
#' `""`, its name will be treated as a placeholder prompt. For example:
#' `selectInput("letter", "Letter", c("Choose one" = "", LETTERS))`
#' In selectize mode, if the first element in \code{choices} has a value of
#' \code{""}, its name will be treated as a placeholder prompt. For example:
#' \code{selectInput("letter", "Letter", c("Choose one" = "", LETTERS))}
#'
#' @inheritParams textInput
#' @param choices List of values to select from. If elements of the list are
#' named, then that name --- rather than the value --- is displayed to the
#' user. It's also possible to group related inputs by providing a named list
#' whose elements are (either named or unnamed) lists, vectors, or factors. In this
#' case, the outermost names will be used as the group labels (leveraging the
#' `<optgroup>` HTML tag) for the elements in the respective sublist. See the
#' named, then that name rather than the value is displayed to the user.
#' This can also be a named list whose elements are (either named or
#' unnamed) lists or vectors. If this is the case, the outermost names
#' will be used as the "optgroup" label for the elements in the respective
#' sublist. This allows you to group and label similar choices. See the
#' example section for a small demo of this feature.
#' @param selected The initially selected value (or multiple values if
#' `multiple = TRUE`). If not specified then defaults to the first value
#' \code{multiple = TRUE}). If not specified then defaults to the first value
#' for single-select lists and no values for multiple select lists.
#' @param multiple Is selection of multiple items allowed?
#' @param selectize Whether to use \pkg{selectize.js} or not.
#' @param size Number of items to show in the selection box; a larger number
#' will result in a taller box. Not compatible with `selectize=TRUE`.
#' Normally, when `multiple=FALSE`, a select input will be a drop-down
#' list, but when `size` is set, it will be a box instead.
#' will result in a taller box. Not compatible with \code{selectize=TRUE}.
#' Normally, when \code{multiple=FALSE}, a select input will be a drop-down
#' list, but when \code{size} is set, it will be a box instead.
#' @return A select list control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [updateSelectInput()] [varSelectInput()]
#' @seealso \code{\link{updateSelectInput}} \code{\link{varSelectInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -55,7 +55,7 @@
#' }
#' )
#'
#' # demoing group support in the `choices` arg
#' # demoing optgroup support in the `choices` arg
#' shinyApp(
#' ui = fluidPage(
#' selectInput("state", "Choose a state:",
@@ -105,7 +105,7 @@ selectInput <- function(inputId, label, choices, selected = NULL,
res <- div(
class = "form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
controlLabel(inputId, label),
div(selectTag)
)
@@ -153,21 +153,21 @@ needOptgroup <- function(choices) {
}
#' @rdname selectInput
#' @param ... Arguments passed to `selectInput()`.
#' @param ... Arguments passed to \code{selectInput()}.
#' @param options A list of options. See the documentation of \pkg{selectize.js}
#' for possible options (character option values inside [base::I()] will
#' be treated as literal JavaScript code; see [renderDataTable()]
#' for possible options (character option values inside \code{\link[base]{I}()} will
#' be treated as literal JavaScript code; see \code{\link{renderDataTable}()}
#' for details).
#' @param width The width of the input, e.g. `'400px'`, or `'100%'`;
#' see [validateCssUnit()].
#' @note The selectize input created from `selectizeInput()` allows
#' @param width The width of the input, e.g. \code{'400px'}, or \code{'100\%'};
#' see \code{\link{validateCssUnit}}.
#' @note The selectize input created from \code{selectizeInput()} allows
#' deletion of the selected option even in a single select input, which will
#' return an empty string as its value. This is the default behavior of
#' \pkg{selectize.js}. However, the selectize input created from
#' `selectInput(..., selectize = TRUE)` will ignore the empty string
#' \code{selectInput(..., selectize = TRUE)} will ignore the empty string
#' value when it is a single choice input and the empty string is not in the
#' `choices` argument. This is to keep compatibility with
#' `selectInput(..., selectize = FALSE)`.
#' \code{choices} argument. This is to keep compatibility with
#' \code{selectInput(..., selectize = FALSE)}.
#' @export
selectizeInput <- function(inputId, ..., options = NULL, width = NULL) {
selectizeIt(
@@ -225,30 +225,30 @@ selectizeIt <- function(inputId, select, options, nonempty = FALSE) {
#' Create a select list that can be used to choose a single or multiple items
#' from the column names of a data frame.
#'
#' The resulting server `input` value will be returned as:
#' The resulting server \code{input} value will be returned as:
#' \itemize{
#' \item a symbol if `multiple = FALSE`. The `input` value should be
#' used with rlang's [rlang::!!()]. For example,
#' `ggplot2::aes(!!input$variable)`.
#' \item a list of symbols if `multiple = TRUE`. The `input` value
#' should be used with rlang's [rlang::!!!()] to expand
#' \item a symbol if \code{multiple = FALSE}. The \code{input} value should be
#' used with rlang's \code{\link[rlang]{!!}}. For example,
#' \code{ggplot2::aes(!!input$variable)}.
#' \item a list of symbols if \code{multiple = TRUE}. The \code{input} value
#' should be used with rlang's \code{\link[rlang]{!!!}} to expand
#' the symbol list as individual arguments. For example,
#' `dplyr::select(mtcars, !!!input$variabls)` which is
#' equivalent to `dplyr::select(mtcars, !!input$variabls[[1]], !!input$variabls[[2]], ..., !!input$variabls[[length(input$variabls)]])`.
#' \code{dplyr::select(mtcars, !!!input$variabls)} which is
#' equivalent to \code{dplyr::select(mtcars, !!input$variabls[[1]], !!input$variabls[[2]], ..., !!input$variabls[[length(input$variabls)]])}.
#' }
#'
#' By default, `varSelectInput()` and `selectizeInput()` use the
#' By default, \code{varSelectInput()} and \code{selectizeInput()} use the
#' JavaScript library \pkg{selectize.js}
#' (<https://github.com/selectize/selectize.js>) to instead of the basic
#' (\url{https://github.com/selectize/selectize.js}) to instead of the basic
#' select input element. To use the standard HTML select input element, use
#' `selectInput()` with `selectize=FALSE`.
#' \code{selectInput()} with \code{selectize=FALSE}.
#'
#' @inheritParams selectInput
#' @param data A data frame. Used to retrieve the column names as choices for a [selectInput()]
#' @param data A data frame. Used to retrieve the column names as choices for a \code{\link{selectInput}}
#' @return A variable select list control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [updateSelectInput()]
#' @seealso \code{\link{updateSelectInput}}
#' @examples
#'
#' ## Only run examples in interactive R sessions
@@ -321,21 +321,21 @@ varSelectInput <- function(
#' @rdname varSelectInput
#' @param ... Arguments passed to `varSelectInput()`.
#' @param ... Arguments passed to \code{varSelectInput()}.
#' @param options A list of options. See the documentation of \pkg{selectize.js}
#' for possible options (character option values inside [base::I()] will
#' be treated as literal JavaScript code; see [renderDataTable()]
#' for possible options (character option values inside \code{\link[base]{I}()} will
#' be treated as literal JavaScript code; see \code{\link{renderDataTable}()}
#' for details).
#' @param width The width of the input, e.g. `'400px'`, or `'100%'`;
#' see [validateCssUnit()].
#' @note The variable selectize input created from `varSelectizeInput()` allows
#' @param width The width of the input, e.g. \code{'400px'}, or \code{'100\%'};
#' see \code{\link{validateCssUnit}}.
#' @note The variable selectize input created from \code{varSelectizeInput()} allows
#' deletion of the selected option even in a single select input, which will
#' return an empty string as its value. This is the default behavior of
#' \pkg{selectize.js}. However, the selectize input created from
#' `selectInput(..., selectize = TRUE)` will ignore the empty string
#' \code{selectInput(..., selectize = TRUE)} will ignore the empty string
#' value when it is a single choice input and the empty string is not in the
#' `choices` argument. This is to keep compatibility with
#' `selectInput(..., selectize = FALSE)`.
#' \code{choices} argument. This is to keep compatibility with
#' \code{selectInput(..., selectize = FALSE)}.
#' @export
varSelectizeInput <- function(inputId, ..., options = NULL, width = NULL) {
selectizeIt(

View File

@@ -8,45 +8,45 @@
#' @param value The initial value of the slider. A numeric vector of length one
#' will create a regular slider; a numeric vector of length two will create a
#' double-ended range slider. A warning will be issued if the value doesn't
#' fit between `min` and `max`.
#' fit between \code{min} and \code{max}.
#' @param step Specifies the interval between each selectable value on the
#' slider (if `NULL`, a heuristic is used to determine the step size). If
#' the values are dates, `step` is in days; if the values are times
#' (POSIXt), `step` is in seconds.
#' @param round `TRUE` to round all values to the nearest integer;
#' `FALSE` if no rounding is desired; or an integer to round to that
#' slider (if \code{NULL}, a heuristic is used to determine the step size). If
#' the values are dates, \code{step} is in days; if the values are times
#' (POSIXt), \code{step} is in seconds.
#' @param round \code{TRUE} to round all values to the nearest integer;
#' \code{FALSE} if no rounding is desired; or an integer to round to that
#' number of digits (for example, 1 will round to the nearest 10, and -2 will
#' round to the nearest .01). Any rounding will be applied after snapping to
#' the nearest step.
#' @param format Deprecated.
#' @param locale Deprecated.
#' @param ticks `FALSE` to hide tick marks, `TRUE` to show them
#' @param ticks \code{FALSE} to hide tick marks, \code{TRUE} to show them
#' according to some simple heuristics.
#' @param animate `TRUE` to show simple animation controls with default
#' settings; `FALSE` not to; or a custom settings list, such as those
#' created using [animationOptions()].
#' @param animate \code{TRUE} to show simple animation controls with default
#' settings; \code{FALSE} not to; or a custom settings list, such as those
#' created using \code{\link{animationOptions}}.
#' @param sep Separator between thousands places in numbers.
#' @param pre A prefix string to put in front of the value.
#' @param post A suffix string to put after the value.
#' @param dragRange This option is used only if it is a range slider (with two
#' values). If `TRUE` (the default), the range can be dragged. In other
#' words, the min and max can be dragged together. If `FALSE`, the range
#' values). If \code{TRUE} (the default), the range can be dragged. In other
#' words, the min and max can be dragged together. If \code{FALSE}, the range
#' cannot be dragged.
#' @param timeFormat Only used if the values are Date or POSIXt objects. A time
#' format string, to be passed to the Javascript strftime library. See
#' <https://github.com/samsonjs/strftime> for more details. The allowed
#' \url{https://github.com/samsonjs/strftime} for more details. The allowed
#' format specifications are very similar, but not identical, to those for R's
#' [base::strftime()] function. For Dates, the default is `"%F"`
#' (like `"2015-07-01"`), and for POSIXt, the default is `"%F %T"`
#' (like `"2015-07-01 15:32:10"`).
#' \code{\link[base]{strftime}} function. For Dates, the default is \code{"\%F"}
#' (like \code{"2015-07-01"}), and for POSIXt, the default is \code{"\%F \%T"}
#' (like \code{"2015-07-01 15:32:10"}).
#' @param timezone Only used if the values are POSIXt objects. A string
#' specifying the time zone offset for the displayed times, in the format
#' `"+HHMM"` or `"-HHMM"`. If `NULL` (the default), times will
#' be displayed in the browser's time zone. The value `"+0000"` will
#' \code{"+HHMM"} or \code{"-HHMM"}. If \code{NULL} (the default), times will
#' be displayed in the browser's time zone. The value \code{"+0000"} will
#' result in UTC time.
#' @inheritParams selectizeInput
#' @family input elements
#' @seealso [updateSliderInput()]
#' @seealso \code{\link{updateSliderInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -172,7 +172,7 @@ sliderInput <- function(inputId, label, min, max, value, step = NULL,
sliderTag <- div(class = "form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
if (!is.null(label)) controlLabel(inputId, label),
do.call(tags$input, sliderProps)
)
@@ -253,13 +253,13 @@ findStepSize <- function(min, max, step) {
#' @rdname sliderInput
#'
#' @param interval The interval, in milliseconds, between each animation step.
#' @param loop `TRUE` to automatically restart the animation when it
#' @param loop \code{TRUE} to automatically restart the animation when it
#' reaches the end.
#' @param playButton Specifies the appearance of the play button. Valid values
#' are a one-element character vector (for a simple text label), an HTML tag
#' or list of tags (using [tag()] and friends), or raw HTML (using
#' [HTML()]).
#' @param pauseButton Similar to `playButton`, but for the pause button.
#' or list of tags (using \code{\link{tag}} and friends), or raw HTML (using
#' \code{\link{HTML}}).
#' @param pauseButton Similar to \code{playButton}, but for the pause button.
#' @export
animationOptions <- function(interval=1000,
loop=FALSE,

View File

@@ -3,30 +3,30 @@
#' Create a submit button for an app. Apps that include a submit
#' button do not automatically update their outputs when inputs change,
#' rather they wait until the user explicitly clicks the submit button.
#' The use of `submitButton` is generally discouraged in favor of
#' the more versatile [actionButton()] (see details below).
#' The use of \code{submitButton} is generally discouraged in favor of
#' the more versatile \code{\link{actionButton}} (see details below).
#'
#' Submit buttons are unusual Shiny inputs, and we recommend using
#' [actionButton()] instead of `submitButton` when you
#' \code{\link{actionButton}} instead of \code{submitButton} when you
#' want to delay a reaction.
#' See [this
#' article](http://shiny.rstudio.com/articles/action-buttons.html) for more information (including a demo of how to "translate"
#' code using a `submitButton` to code using an `actionButton`).
#' See \href{http://shiny.rstudio.com/articles/action-buttons.html}{this
#' article} for more information (including a demo of how to "translate"
#' code using a \code{submitButton} to code using an \code{actionButton}).
#'
#' In essence, the presence of a submit button stops all inputs from
#' sending their values automatically to the server. This means, for
#' instance, that if there are *two* submit buttons in the same app,
#' instance, that if there are \emph{two} submit buttons in the same app,
#' clicking either one will cause all inputs in the app to send their
#' values to the server. This is probably not what you'd want, which is
#' why submit button are unwieldy for all but the simplest apps. There
#' are other problems with submit buttons: for example, dynamically
#' created submit buttons (for example, with [renderUI()]
#' or [insertUI()]) will not work.
#' created submit buttons (for example, with \code{\link{renderUI}}
#' or \code{\link{insertUI}}) will not work.
#'
#' @param text Button caption
#' @param icon Optional [icon()] to appear on the button
#' @param width The width of the button, e.g. `'400px'`, or `'100%'`;
#' see [validateCssUnit()].
#' @param icon Optional \code{\link{icon}} to appear on the button
#' @param width The width of the button, e.g. \code{'400px'}, or \code{'100\%'};
#' see \code{\link{validateCssUnit}}.
#' @return A submit button that can be added to a UI definition.
#'
#' @family input elements

View File

@@ -2,18 +2,18 @@
#'
#' Create an input control for entry of unstructured text values
#'
#' @param inputId The `input` slot that will be used to access the value.
#' @param label Display label for the control, or `NULL` for no label.
#' @param inputId The \code{input} slot that will be used to access the value.
#' @param label Display label for the control, or \code{NULL} for no label.
#' @param value Initial value.
#' @param width The width of the input, e.g. `'400px'`, or `'100%'`;
#' see [validateCssUnit()].
#' @param width The width of the input, e.g. \code{'400px'}, or \code{'100\%'};
#' see \code{\link{validateCssUnit}}.
#' @param placeholder A character string giving the user a hint as to what can
#' be entered into the control. Internet Explorer 8 and 9 do not support this
#' option.
#' @return A text input control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [updateTextInput()]
#' @seealso \code{\link{updateTextInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -36,7 +36,7 @@ textInput <- function(inputId, label, value = "", width = NULL,
div(class = "form-group shiny-input-container",
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
shinyInputLabel(inputId, label),
label %AND% tags$label(label, `for` = inputId),
tags$input(id = inputId, type="text", class="form-control", value=value,
placeholder = placeholder)
)

View File

@@ -3,23 +3,22 @@
#' Create a textarea input control for entry of unstructured text values.
#'
#' @inheritParams textInput
#' @param height The height of the input, e.g. `'400px'`, or `'100%'`; see
#' [validateCssUnit()].
#' @param cols Value of the visible character columns of the input, e.g. `80`.
#' This argument will only take effect if there is not a CSS `width` rule
#' defined for this element; such a rule could come from the `width` argument
#' of this function or from a containing page layout such as
#' [fluidPage()].
#' @param rows The value of the visible character rows of the input, e.g. `6`.
#' If the `height` argument is specified, `height` will take precedence in the
#' browser's rendering.
#' @param height The height of the input, e.g. \code{'400px'}, or
#' \code{'100\%'}; see \code{\link{validateCssUnit}}.
#' @param cols Value of the visible character columns of the input, e.g.
#' \code{80}. If used with \code{width}, \code{width} will take precedence in
#' the browser's rendering.
#' @param rows The value of the visible character rows of the input, e.g.
#' \code{6}. If used with \code{height}, \code{height} will take precedence in
#' the browser's rendering.
#' @param resize Which directions the textarea box can be resized. Can be one of
#' `"both"`, `"none"`, `"vertical"`, and `"horizontal"`. The default, `NULL`,
#' will use the client browser's default setting for resizing textareas.
#' \code{"both"}, \code{"none"}, \code{"vertical"}, and \code{"horizontal"}.
#' The default, \code{NULL}, will use the client browser's default setting for
#' resizing textareas.
#' @return A textarea input control that can be added to a UI definition.
#'
#' @family input elements
#' @seealso [updateTextAreaInput()]
#' @seealso \code{\link{updateTextAreaInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -56,7 +55,7 @@ textAreaInput <- function(inputId, label, value = "", width = NULL, height = NUL
if (length(style) == 0) style <- NULL
div(class = "form-group shiny-input-container",
shinyInputLabel(inputId, label),
label %AND% tags$label(label, `for` = inputId),
tags$textarea(
id = inputId,
class = "form-control",

View File

@@ -1,10 +1,5 @@
shinyInputLabel <- function(inputId, label = NULL) {
tags$label(
label,
class = "control-label",
class = if (is.null(label)) "shiny-label-null",
`for` = inputId
)
controlLabel <- function(controlName, label) {
label %AND% tags$label(class = "control-label", `for` = controlName, label)
}
# This function takes in either a list or vector for `choices` (and
@@ -90,58 +85,45 @@ generateOptions <- function(inputId, selected, inline, type = 'checkbox',
div(class = "shiny-options-group", options)
}
# True when a choice list item represents a group of related inputs
isGroup <- function(choice) {
length(choice) > 1 || !is.null(names(choice))
}
# True when choices is a list and contains at least one group of related inputs
hasGroups <- function(choices) {
is.list(choices) && Position(isGroup, choices, nomatch = 0)
}
# Assigns empty names to x if it's unnamed, and then fills any empty names with
# the corresponding value coerced to a character(1)
setDefaultNames <- function(x) {
x <- asNamed(x)
emptyNames <- names(x) == ""
names(x)[emptyNames] <- as.character(x)[emptyNames]
x
}
# Makes a character vector out of x in a way that preserves names if x is a
# factor.
asCharacter <- function(x) {
stats::setNames(as.character(x), names(x))
}
processFlatChoices <- function(choices) {
choices <- setDefaultNames(asCharacter(choices))
as.list(choices)
}
processGroupedChoices <- function(choices) {
choices <- asNamed(choices)
choices <- mapply(function(name, group, choice) {
if (group && name == "") {
stop('All sub-lists in "choices" must be named.')
} else if (group) {
processFlatChoices(choice)
} else {
as.character(choice)
}
}, names(choices), lapply(choices, isGroup), choices, SIMPLIFY = FALSE)
setDefaultNames(choices)
}
# Takes a vector or list, and adds names (same as the value) to any entries
# without names. Coerces all leaf nodes to `character`.
choicesWithNames <- function(choices) {
if (length(choices) == 0) {
choices
} else if (hasGroups(choices)) {
processGroupedChoices(choices)
} else {
processFlatChoices(choices)
# Take a vector or list, and convert to list. Also, if any children are
# vectors with length > 1, convert those to list. If the list is unnamed,
# convert it to a named list with blank names.
listify <- function(obj) {
# If a list/vector is unnamed, give it blank names
makeNamed <- function(x) {
if (is.null(names(x))) names(x) <- character(length(x))
x
}
res <- lapply(obj, function(val) {
if (is.list(val))
listify(val)
else if (length(val) == 1 && is.null(names(val)))
as.character(val)
else
makeNamed(as.list(val))
})
makeNamed(res)
}
choices <- listify(choices)
if (length(choices) == 0) return(choices)
# Recurse into any subgroups
choices <- mapply(choices, names(choices), FUN = function(choice, name) {
if (!is.list(choice)) return(choice)
if (name == "") stop('All sub-lists in "choices" must be named.')
choicesWithNames(choice)
}, SIMPLIFY = FALSE)
# default missing names to choice values
missing <- names(choices) == ""
names(choices)[missing] <- as.character(choices)[missing]
choices
}

View File

@@ -1,43 +1,43 @@
#' Dynamically insert/remove a tabPanel
#'
#' Dynamically insert or remove a [tabPanel()] (or a
#' [navbarMenu()]) from an existing [tabsetPanel()],
#' [navlistPanel()] or [navbarPage()].
#' Dynamically insert or remove a \code{\link{tabPanel}} (or a
#' \code{\link{navbarMenu}}) from an existing \code{\link{tabsetPanel}},
#' \code{\link{navlistPanel}} or \code{\link{navbarPage}}.
#'
#' When you want to insert a new tab before or after an existing tab, you
#' should use `insertTab`. When you want to prepend a tab (i.e. add a
#' tab to the beginning of the `tabsetPanel`), use `prependTab`.
#' should use \code{insertTab}. When you want to prepend a tab (i.e. add a
#' tab to the beginning of the \code{tabsetPanel}), use \code{prependTab}.
#' When you want to append a tab (i.e. add a tab to the end of the
#' `tabsetPanel`), use `appendTab`.
#' \code{tabsetPanel}), use \code{appendTab}.
#'
#' For `navbarPage`, you can insert/remove conventional
#' `tabPanel`s (whether at the top level or nested inside a
#' `navbarMenu`), as well as an entire [navbarMenu()].
#' For the latter case, `target` should be the `menuName` that
#' you gave your `navbarMenu` when you first created it (by default,
#' this is equal to the value of the `title` argument).
#' For \code{navbarPage}, you can insert/remove conventional
#' \code{tabPanel}s (whether at the top level or nested inside a
#' \code{navbarMenu}), as well as an entire \code{\link{navbarMenu}}.
#' For the latter case, \code{target} should be the \code{menuName} that
#' you gave your \code{navbarMenu} when you first created it (by default,
#' this is equal to the value of the \code{title} argument).
#'
#' @param inputId The `id` of the `tabsetPanel` (or
#' `navlistPanel` or `navbarPage`) into which `tab` will
#' @param inputId The \code{id} of the \code{tabsetPanel} (or
#' \code{navlistPanel} or \code{navbarPage}) into which \code{tab} will
#' be inserted/removed.
#'
#' @param tab The item to be added (must be created with `tabPanel`,
#' or with `navbarMenu`).
#' @param tab The item to be added (must be created with \code{tabPanel},
#' or with \code{navbarMenu}).
#'
#' @param target If inserting: the `value` of an existing
#' `tabPanel`, next to which `tab` will be added.
#' If removing: the `value` of the `tabPanel` that
#' @param target If inserting: the \code{value} of an existing
#' \code{tabPanel}, next to which \code{tab} will be added.
#' If removing: the \code{value} of the \code{tabPanel} that
#' you want to remove. See Details if you want to insert next to/remove
#' an entire `navbarMenu` instead.
#' an entire \code{navbarMenu} instead.
#'
#' @param position Should `tab` be added before or after the
#' `target` tab?
#' @param position Should \code{tab} be added before or after the
#' \code{target} tab?
#'
#' @param select Should `tab` be selected upon being inserted?
#' @param select Should \code{tab} be selected upon being inserted?
#'
#' @param session The shiny session within which to call this function.
#'
#' @seealso [showTab()]
#' @seealso \code{\link{showTab}}
#'
#' @examples
#' ## Only run this example in interactive R sessions
@@ -144,16 +144,16 @@ insertTab <- function(inputId, tab, target,
}
#' @param menuName This argument should only be used when you want to
#' prepend (or append) `tab` to the beginning (or end) of an
#' existing [navbarMenu()] (which must itself be part of
#' an existing [navbarPage()]). In this case, this argument
#' should be the `menuName` that you gave your `navbarMenu`
#' prepend (or append) \code{tab} to the beginning (or end) of an
#' existing \code{\link{navbarMenu}} (which must itself be part of
#' an existing \code{\link{navbarPage}}). In this case, this argument
#' should be the \code{menuName} that you gave your \code{navbarMenu}
#' when you first created it (by default, this is equal to the value
#' of the `title` argument). Note that you still need to set the
#' `inputId` argument to whatever the `id` of the parent
#' `navbarPage` is. If `menuName` is left as `NULL`,
#' `tab` will be prepended (or appended) to whatever
#' `inputId` is.
#' of the \code{title} argument). Note that you still need to set the
#' \code{inputId} argument to whatever the \code{id} of the parent
#' \code{navbarPage} is. If \code{menuName} is left as \code{NULL},
#' \code{tab} will be prepended (or appended) to whatever
#' \code{inputId} is.
#'
#' @rdname insertTab
#' @export
@@ -221,30 +221,30 @@ removeTab <- function(inputId, target,
#' Dynamically hide/show a tabPanel
#'
#' Dynamically hide or show a [tabPanel()] (or a
#' [navbarMenu()])from an existing [tabsetPanel()],
#' [navlistPanel()] or [navbarPage()].
#' Dynamically hide or show a \code{\link{tabPanel}} (or a
#' \code{\link{navbarMenu}})from an existing \code{\link{tabsetPanel}},
#' \code{\link{navlistPanel}} or \code{\link{navbarPage}}.
#'
#' For `navbarPage`, you can hide/show conventional
#' `tabPanel`s (whether at the top level or nested inside a
#' `navbarMenu`), as well as an entire [navbarMenu()].
#' For the latter case, `target` should be the `menuName` that
#' you gave your `navbarMenu` when you first created it (by default,
#' this is equal to the value of the `title` argument).
#' For \code{navbarPage}, you can hide/show conventional
#' \code{tabPanel}s (whether at the top level or nested inside a
#' \code{navbarMenu}), as well as an entire \code{\link{navbarMenu}}.
#' For the latter case, \code{target} should be the \code{menuName} that
#' you gave your \code{navbarMenu} when you first created it (by default,
#' this is equal to the value of the \code{title} argument).
#'
#' @param inputId The `id` of the `tabsetPanel` (or
#' `navlistPanel` or `navbarPage`) in which to find
#' `target`.
#' @param inputId The \code{id} of the \code{tabsetPanel} (or
#' \code{navlistPanel} or \code{navbarPage}) in which to find
#' \code{target}.
#'
#' @param target The `value` of the `tabPanel` to be
#' @param target The \code{value} of the \code{tabPanel} to be
#' hidden/shown. See Details if you want to hide/show an entire
#' `navbarMenu` instead.
#' \code{navbarMenu} instead.
#'
#' @param select Should `target` be selected upon being shown?
#' @param select Should \code{target} be selected upon being shown?
#'
#' @param session The shiny session within which to call this function.
#'
#' @seealso [insertTab()]
#' @seealso \code{\link{insertTab}}
#'
#' @examples
#' ## Only run this example in interactive R sessions

View File

@@ -4,51 +4,51 @@
#'
#' This function allows you to dynamically add an arbitrarily large UI
#' object into your app, whenever you want, as many times as you want.
#' Unlike [renderUI()], the UI generated with `insertUI`
#' Unlike \code{\link{renderUI}}, the UI generated with \code{insertUI}
#' is not updatable as a whole: once it's created, it stays there. Each
#' new call to `insertUI` creates more UI objects, in addition to
#' new call to \code{insertUI} creates more UI objects, in addition to
#' the ones already there (all independent from one another). To
#' update a part of the UI (ex: an input object), you must use the
#' appropriate `render` function or a customized `reactive`
#' function. To remove any part of your UI, use [removeUI()].
#' appropriate \code{render} function or a customized \code{reactive}
#' function. To remove any part of your UI, use \code{\link{removeUI}}.
#'
#' @param selector A string that is accepted by jQuery's selector (i.e. the
#' string `s` to be placed in a `$(s)` jQuery call). This selector
#' string \code{s} to be placed in a \code{$(s)} jQuery call). This selector
#' will determine the element(s) relative to which you want to insert your
#' UI object.
#'
#' @param where Where your UI object should go relative to the selector:
#' \describe{
#' \item{`beforeBegin`}{Before the selector element itself}
#' \item{`afterBegin`}{Just inside the selector element, before its
#' \item{\code{beforeBegin}}{Before the selector element itself}
#' \item{\code{afterBegin}}{Just inside the selector element, before its
#' first child}
#' \item{`beforeEnd`}{Just inside the selector element, after its
#' \item{\code{beforeEnd}}{Just inside the selector element, after its
#' last child (default)}
#' \item{`afterEnd`}{After the selector element itself}
#' \item{\code{afterEnd}}{After the selector element itself}
#' }
#' Adapted from
#' [here](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML).
#' \href{https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML}{here}.
#'
#' @param ui The UI object you want to insert. This can be anything that
#' you usually put inside your apps's `ui` function. If you're inserting
#' you usually put inside your apps's \code{ui} function. If you're inserting
#' multiple elements in one call, make sure to wrap them in either a
#' `tagList()` or a `tags$div()` (the latter option has the
#' advantage that you can give it an `id` to make it easier to
#' \code{tagList()} or a \code{tags$div()} (the latter option has the
#' advantage that you can give it an \code{id} to make it easier to
#' reference or remove it later on). If you want to insert raw html, use
#' `ui = HTML()`.
#' \code{ui = HTML()}.
#'
#' @param multiple In case your selector matches more than one element,
#' `multiple` determines whether Shiny should insert the UI object
#' \code{multiple} determines whether Shiny should insert the UI object
#' relative to all matched elements or just relative to the first
#' matched element (default).
#'
#' @param immediate Whether the UI object should be immediately inserted into
#' the app when you call `insertUI`, or whether Shiny should wait until
#' the app when you call \code{insertUI}, or whether Shiny should wait until
#' all outputs have been updated and all observers have been run (default).
#'
#' @param session The shiny session within which to call `insertUI`.
#' @param session The shiny session within which to call \code{insertUI}.
#'
#' @seealso [removeUI()]
#' @seealso \code{\link{removeUI}}
#'
#' @examples
#' ## Only run this example in interactive R sessions
@@ -104,34 +104,34 @@ insertUI <- function(selector,
#'
#' Remove a UI object from the app.
#'
#' This function allows you to remove any part of your UI. Once `removeUI`
#' This function allows you to remove any part of your UI. Once \code{removeUI}
#' is executed on some element, it is gone forever.
#'
#' While it may be a particularly useful pattern to pair this with
#' [insertUI()] (to remove some UI you had previously inserted),
#' there is no restriction on what you can use `removeUI` on. Any
#' \code{\link{insertUI}} (to remove some UI you had previously inserted),
#' there is no restriction on what you can use \code{removeUI} on. Any
#' element that can be selected through a jQuery selector can be removed
#' through this function.
#'
#' @param selector A string that is accepted by jQuery's selector (i.e. the
#' string `s` to be placed in a `$(s)` jQuery call). This selector
#' string \code{s} to be placed in a \code{$(s)} jQuery call). This selector
#' will determine the element(s) to be removed. If you want to remove a
#' Shiny input or output, note that many of these are wrapped in `div`s,
#' so you may need to use a somewhat complex selector --- see the Examples below.
#' Shiny input or output, note that many of these are wrapped in \code{div}s,
#' so you may need to use a somewhat complex selector -- see the Examples below.
#' (Alternatively, you could also wrap the inputs/outputs that you want to be
#' able to remove easily in a `div` with an id.)
#' able to remove easily in a \code{div} with an id.)
#'
#' @param multiple In case your selector matches more than one element,
#' `multiple` determines whether Shiny should remove all the matched
#' \code{multiple} determines whether Shiny should remove all the matched
#' elements or just the first matched element (default).
#'
#' @param immediate Whether the element(s) should be immediately removed from
#' the app when you call `removeUI`, or whether Shiny should wait until
#' the app when you call \code{removeUI}, or whether Shiny should wait until
#' all outputs have been updated and all observers have been run (default).
#'
#' @param session The shiny session within which to call `removeUI`.
#' @param session The shiny session within which to call \code{removeUI}.
#'
#' @seealso [insertUI()]
#' @seealso \code{\link{insertUI}}
#'
#' @examples
#' ## Only run this example in interactive R sessions

View File

@@ -2,32 +2,32 @@
#'
#' Creates a panel whose contents are absolutely positioned.
#'
#' The `absolutePanel` function creates a `<div>` tag whose CSS
#' position is set to `absolute` (or fixed if `fixed = TRUE`). The way
#' The \code{absolutePanel} function creates a \code{<div>} tag whose CSS
#' position is set to \code{absolute} (or fixed if \code{fixed = TRUE}). The way
#' absolute positioning works in HTML is that absolute coordinates are specified
#' relative to its nearest parent element whose position is not set to
#' `static` (which is the default), and if no such parent is found, then
#' \code{static} (which is the default), and if no such parent is found, then
#' relative to the page borders. If you're not sure what that means, just keep
#' in mind that you may get strange results if you use `absolutePanel` from
#' in mind that you may get strange results if you use \code{absolutePanel} from
#' inside of certain types of panels.
#'
#' The `fixedPanel` function is the same as `absolutePanel` with
#' `fixed = TRUE`.
#' The \code{fixedPanel} function is the same as \code{absolutePanel} with
#' \code{fixed = TRUE}.
#'
#' The position (`top`, `left`, `right`, `bottom`) and size
#' (`width`, `height`) parameters are all optional, but you should
#' specify exactly two of `top`, `bottom`, and `height` and
#' exactly two of `left`, `right`, and `width` for predictable
#' The position (\code{top}, \code{left}, \code{right}, \code{bottom}) and size
#' (\code{width}, \code{height}) parameters are all optional, but you should
#' specify exactly two of \code{top}, \code{bottom}, and \code{height} and
#' exactly two of \code{left}, \code{right}, and \code{width} for predictable
#' results.
#'
#' Like most other distance parameters in Shiny, the position and size
#' parameters take a number (interpreted as pixels) or a valid CSS size string,
#' such as `"100px"` (100 pixels) or `"25%"`.
#' such as \code{"100px"} (100 pixels) or \code{"25\%"}.
#'
#' For arcane HTML reasons, to have the panel fill the page or parent you should
#' specify `0` for `top`, `left`, `right`, and `bottom`
#' rather than the more obvious `width = "100%"` and `height =
#' "100%"`.
#' specify \code{0} for \code{top}, \code{left}, \code{right}, and \code{bottom}
#' rather than the more obvious \code{width = "100\%"} and \code{height =
#' "100\%"}.
#'
#' @param ... Attributes (named arguments) or children (unnamed arguments) that
#' should be included in the panel.
@@ -42,16 +42,16 @@
#' page or parent container.
#' @param width Width of the panel.
#' @param height Height of the panel.
#' @param draggable If `TRUE`, allows the user to move the panel by
#' @param draggable If \code{TRUE}, allows the user to move the panel by
#' clicking and dragging.
#' @param fixed Positions the panel relative to the browser window and prevents
#' it from being scrolled with the rest of the page.
#' @param cursor The type of cursor that should appear when the user mouses over
#' the panel. Use `"move"` for a north-east-south-west icon,
#' `"default"` for the usual cursor arrow, or `"inherit"` for the
#' the panel. Use \code{"move"} for a north-east-south-west icon,
#' \code{"default"} for the usual cursor arrow, or \code{"inherit"} for the
#' usual cursor behavior (including changing to an I-beam when the cursor is
#' over text). The default is `"auto"`, which is equivalent to
#' `ifelse(draggable, "move", "inherit")`.
#' over text). The default is \code{"auto"}, which is equivalent to
#' \code{ifelse(draggable, "move", "inherit")}.
#' @return An HTML element or list of elements.
#' @export
absolutePanel <- function(...,

47
R/map.R
View File

@@ -9,58 +9,63 @@
# Remove of unknown key does nothing
# Setting a key twice always results in last-one-wins
# /TESTS
# Note that Map objects can't be saved in one R session and restored in
# another, because they are based on fastmap, which uses an external pointer,
# and external pointers can't be saved and restored in another session.
#' @importFrom fastmap fastmap
Map <- R6Class(
'Map',
portable = FALSE,
public = list(
initialize = function() {
private$map <<- fastmap()
private$env <- new.env(parent=emptyenv())
},
get = function(key) {
map$get(key)
env[[key]]
},
set = function(key, value) {
map$set(key, value)
env[[key]] <- value
value
},
mget = function(keys) {
map$mget(keys)
base::mget(keys, env)
},
mset = function(...) {
map$mset(...)
args <- list(...)
if (length(args) == 0)
return()
arg_names <- names(args)
if (is.null(arg_names) || any(!nzchar(arg_names)))
stop("All elements must be named")
list2env(args, envir = env)
},
remove = function(key) {
if (!map$has(key))
if (!self$containsKey(key))
return(NULL)
result <- map$get(key)
map$remove(key)
result <- env[[key]]
rm(list=key, envir=env, inherits=FALSE)
result
},
containsKey = function(key) {
map$has(key)
exists(key, envir=env, inherits=FALSE)
},
keys = function(sort = FALSE) {
map$keys(sort = sort)
keys = function() {
# Sadly, this is much faster than ls(), because it doesn't sort the keys.
names(as.list(env, all.names=TRUE))
},
values = function(sort = FALSE) {
map$as_list(sort = sort)
values = function() {
as.list(env, all.names=TRUE)
},
clear = function() {
map$reset()
private$env <- new.env(parent=emptyenv())
invisible(NULL)
},
size = function() {
map$size()
length(env)
}
),
private = list(
map = NULL
env = 'environment'
)
)

View File

@@ -2,43 +2,19 @@
NULL
reactLogHandler <- function(req) {
if (! rLog$isLogging()) {
if (!identical(req$PATH_INFO, '/reactlog'))
return(NULL)
if (!isTRUE(getOption('shiny.reactlog'))) {
return(NULL)
}
if (identical(req$PATH_INFO, "/reactlog/mark")) {
sessionToken <- parseQueryString(req$QUERY_STRING)$s
shinysession <- appsByToken$get(sessionToken)
sessionToken <- parseQueryString(req$QUERY_STRING)$s
# log time
withReactiveDomain(shinysession, {
rLog$userMark(getDefaultReactiveDomain())
})
return(httpResponse(
status = 200,
content = "marked",
content_type = "text/plain"
))
} else if (identical(req$PATH_INFO, "/reactlog")){
sessionToken <- parseQueryString(req$QUERY_STRING)$s
# `renderReactLog` will check/throw if reactlog doesn't exist
reactlogFile <- renderReactlog(sessionToken)
return(httpResponse(
status = 200,
content = list(
file = reactlogFile,
owned = TRUE
)
))
} else {
return(NULL)
}
return(httpResponse(
status=200,
content=list(file=renderReactLog(sessionToken), owned=TRUE)
))
}
sessionHandler <- function(req) {

View File

@@ -321,20 +321,21 @@ HandlerManager <- R6Class("HandlerManager",
}
)
},
loadSharedSecret()
getOption('shiny.sharedSecret')
),
onWSOpen = function(ws) {
return(wsHandlers$invoke(ws))
}
)
},
.httpServer = function(handler, checkSharedSecret) {
.httpServer = function(handler, sharedSecret) {
filter <- getOption('shiny.http.response.filter')
if (is.null(filter))
filter <- function(req, response) response
function(req) {
if (!checkSharedSecret(req$HTTP_SHINY_SHARED_SECRET)) {
if (!is.null(sharedSecret)
&& !identical(sharedSecret, req$HTTP_SHINY_SHARED_SECRET)) {
return(list(status=403,
body='<h1>403 Forbidden</h1><p>Shared secret mismatch</p>',
headers=list('Content-Type' = 'text/html')))

View File

@@ -1,13 +1,13 @@
#' Show or remove a modal dialog
#'
#' This causes a modal dialog to be displayed in the client browser, and is
#' typically used with [modalDialog()].
#' typically used with \code{\link{modalDialog}}.
#'
#' @param ui UI content to show in the modal.
#' @param session The `session` object passed to function given to
#' `shinyServer`.
#' @param session The \code{session} object passed to function given to
#' \code{shinyServer}.
#'
#' @seealso [modalDialog()] for examples.
#' @seealso \code{\link{modalDialog}} for examples.
#' @export
showModal <- function(ui, session = getDefaultReactiveDomain()) {
res <- processDeps(ui, session)
@@ -35,15 +35,15 @@ removeModal <- function(session = getDefaultReactiveDomain()) {
#'
#' @param ... UI elements for the body of the modal dialog box.
#' @param title An optional title for the dialog.
#' @param footer UI for footer. Use `NULL` for no footer.
#' @param size One of `"s"` for small, `"m"` (the default) for medium,
#' or `"l"` for large.
#' @param easyClose If `TRUE`, the modal dialog can be dismissed by
#' @param footer UI for footer. Use \code{NULL} for no footer.
#' @param size One of \code{"s"} for small, \code{"m"} (the default) for medium,
#' or \code{"l"} for large.
#' @param easyClose If \code{TRUE}, the modal dialog can be dismissed by
#' clicking outside the dialog box, or be pressing the Escape key. If
#' `FALSE` (the default), the modal dialog can't be dismissed in those
#' \code{FALSE} (the default), the modal dialog can't be dismissed in those
#' ways; instead it must be dismissed by clicking on the dismiss button, or
#' from a call to [removeModal()] on the server.
#' @param fade If `FALSE`, the modal dialog will have no fade-in animation
#' from a call to \code{\link{removeModal}} on the server.
#' @param fade If \code{FALSE}, the modal dialog will have no fade-in animation
#' (it will simply appear rather than fade in to view).
#'
#' @examples
@@ -171,10 +171,10 @@ modalDialog <- function(..., title = NULL, footer = modalButton("Dismiss"),
#' Create a button for a modal dialog
#'
#' When clicked, a `modalButton` will dismiss the modal dialog.
#' When clicked, a \code{modalButton} will dismiss the modal dialog.
#'
#' @inheritParams actionButton
#' @seealso [modalDialog()] for examples.
#' @seealso \code{\link{modalDialog}} for examples.
#' @export
modalButton <- function(label, icon = NULL) {
tags$button(type = "button", class = "btn btn-default",

View File

@@ -42,7 +42,7 @@ createSessionProxy <- function(parentSession, ...) {
#' Shiny's module feature lets you break complicated UI and server logic into
#' smaller, self-contained pieces. Compared to large monolithic Shiny apps,
#' modules are easier to reuse and easier to reason about. See the article at
#' <http://shiny.rstudio.com/articles/modules.html> to learn more.
#' \url{http://shiny.rstudio.com/articles/modules.html} to learn more.
#'
#' @param module A Shiny module server function
#' @param id An ID string that corresponds with the ID used to call the module's
@@ -52,7 +52,7 @@ createSessionProxy <- function(parentSession, ...) {
#' almost always be used)
#'
#' @return The return value, if any, from executing the module server function
#' @seealso <http://shiny.rstudio.com/articles/modules.html>
#' @seealso \url{http://shiny.rstudio.com/articles/modules.html}
#' @export
callModule <- function(module, id, ..., session = getDefaultReactiveDomain()) {
childScope <- session$makeScope(id)

View File

@@ -4,17 +4,17 @@
#'
#' @param ui Content of message.
#' @param action Message content that represents an action. For example, this
#' could be a link that the user can click on. This is separate from `ui`
#' could be a link that the user can click on. This is separate from \code{ui}
#' so customized layouts can handle the main notification content separately
#' from action content.
#' @param duration Number of seconds to display the message before it
#' disappears. Use `NULL` to make the message not automatically
#' disappears. Use \code{NULL} to make the message not automatically
#' disappear.
#' @param closeButton If `TRUE`, display a button which will make the
#' notification disappear when clicked. If `FALSE` do not display.
#' @param closeButton If \code{TRUE}, display a button which will make the
#' notification disappear when clicked. If \code{FALSE} do not display.
#' @param id An ID string. This can be used to change the contents of an
#' existing message with `showNotification`, or to remove it with
#' `removeNotification`. If not provided, one will be generated
#' existing message with \code{showNotification}, or to remove it with
#' \code{removeNotification}. If not provided, one will be generated
#' automatically. If an ID is provided and there does not currently exist a
#' notification with that ID, a new notification will be created with that ID.
#' @param type A string which controls the color of the notification. One of

View File

@@ -3,66 +3,66 @@
#' Reports progress to the user during long-running operations.
#'
#' This package exposes two distinct programming APIs for working with
#' progress. [withProgress()] and [setProgress()]
#' progress. \code{\link{withProgress}} and \code{\link{setProgress}}
#' together provide a simple function-based interface, while the
#' `Progress` reference class provides an object-oriented API.
#' \code{Progress} reference class provides an object-oriented API.
#'
#' Instantiating a `Progress` object causes a progress panel to be
#' created, and it will be displayed the first time the `set`
#' method is called. Calling `close` will cause the progress panel
#' Instantiating a \code{Progress} object causes a progress panel to be
#' created, and it will be displayed the first time the \code{set}
#' method is called. Calling \code{close} will cause the progress panel
#' to be removed.
#'
#' As of version 0.14, the progress indicators use Shiny's new notification API.
#' If you want to use the old styling (for example, you may have used customized
#' CSS), you can use `style="old"` each time you call
#' `Progress$new()`. If you don't want to set the style each time
#' `Progress$new` is called, you can instead call
#' [`shinyOptions(progress.style="old")`][shinyOptions] just once, inside the server
#' CSS), you can use \code{style="old"} each time you call
#' \code{Progress$new()}. If you don't want to set the style each time
#' \code{Progress$new} is called, you can instead call
#' \code{\link{shinyOptions}(progress.style="old")} just once, inside the server
#' function.
#'
#' **Methods**
#' \strong{Methods}
#' \describe{
#' \item{`initialize(session, min = 0, max = 1)`}{
#' \item{\code{initialize(session, min = 0, max = 1)}}{
#' Creates a new progress panel (but does not display it).
#' }
#' \item{`set(value = NULL, message = NULL, detail = NULL)`}{
#' \item{\code{set(value = NULL, message = NULL, detail = NULL)}}{
#' Updates the progress panel. When called the first time, the
#' progress panel is displayed.
#' }
#' \item{`inc(amount = 0.1, message = NULL, detail = NULL)`}{
#' Like `set`, this updates the progress panel. The difference is
#' that `inc` increases the progress bar by `amount`, instead
#' \item{\code{inc(amount = 0.1, message = NULL, detail = NULL)}}{
#' Like \code{set}, this updates the progress panel. The difference is
#' that \code{inc} increases the progress bar by \code{amount}, instead
#' of setting it to a specific value.
#' }
#' \item{`close()`}{
#' Removes the progress panel. Future calls to `set` and
#' `close` will be ignored.
#' \item{\code{close()}}{
#' Removes the progress panel. Future calls to \code{set} and
#' \code{close} will be ignored.
#' }
#' }
#'
#' @param session The Shiny session object, as provided by
#' `shinyServer` to the server function.
#' \code{shinyServer} to the server function.
#' @param min The value that represents the starting point of the
#' progress bar. Must be less than `max`.
#' progress bar. Must be less tham \code{max}.
#' @param max The value that represents the end of the progress bar.
#' Must be greater than `min`.
#' Must be greater than \code{min}.
#' @param message A single-element character vector; the message to be
#' displayed to the user, or `NULL` to hide the current message
#' displayed to the user, or \code{NULL} to hide the current message
#' (if any).
#' @param detail A single-element character vector; the detail message
#' to be displayed to the user, or `NULL` to hide the current
#' to be displayed to the user, or \code{NULL} to hide the current
#' detail message (if any). The detail message will be shown with a
#' de-emphasized appearance relative to `message`.
#' de-emphasized appearance relative to \code{message}.
#' @param value A numeric value at which to set
#' the progress bar, relative to `min` and `max`.
#' @param style Progress display style. If `"notification"` (the default),
#' the progress bar, relative to \code{min} and \code{max}.
#' @param style Progress display style. If \code{"notification"} (the default),
#' the progress indicator will show using Shiny's notification API. If
#' `"old"`, use the same HTML and CSS used in Shiny 0.13.2 and below
#' \code{"old"}, use the same HTML and CSS used in Shiny 0.13.2 and below
#' (this is for backward-compatibility).
#' @param amount Single-element numeric vector; the value at which to set
#' the progress bar, relative to `min` and `max`.
#' `NULL` hides the progress bar, if it is currently visible.
#' @param amount For the `inc()` method, a numeric value to increment the
#' the progress bar, relative to \code{min} and \code{max}.
#' \code{NULL} hides the progress bar, if it is currently visible.
#' @param amount For the \code{inc()} method, a numeric value to increment the
#' progress bar.
#'
#' @examples
@@ -91,7 +91,7 @@
#'
#' shinyApp(ui, server)
#' }
#' @seealso [withProgress()]
#' @seealso \code{\link{withProgress}}
#' @format NULL
#' @usage NULL
#' @export
@@ -186,58 +186,58 @@ Progress <- R6Class(
#' Reports progress to the user during long-running operations.
#'
#' This package exposes two distinct programming APIs for working with progress.
#' Using `withProgress` with `incProgress` or `setProgress`
#' provide a simple function-based interface, while the [Progress()]
#' Using \code{withProgress} with \code{incProgress} or \code{setProgress}
#' provide a simple function-based interface, while the \code{\link{Progress}}
#' reference class provides an object-oriented API.
#'
#' Use `withProgress` to wrap the scope of your work; doing so will cause a
#' Use \code{withProgress} to wrap the scope of your work; doing so will cause a
#' new progress panel to be created, and it will be displayed the first time
#' `incProgress` or `setProgress` are called. When `withProgress`
#' \code{incProgress} or \code{setProgress} are called. When \code{withProgress}
#' exits, the corresponding progress panel will be removed.
#'
#' The `incProgress` function increments the status bar by a specified
#' amount, whereas the `setProgress` function sets it to a specific value,
#' The \code{incProgress} function increments the status bar by a specified
#' amount, whereas the \code{setProgress} function sets it to a specific value,
#' and can also set the text displayed.
#'
#' Generally, `withProgress`/`incProgress`/`setProgress` should
#' Generally, \code{withProgress}/\code{incProgress}/\code{setProgress} should
#' be sufficient; the exception is if the work to be done is asynchronous (this
#' is not common) or otherwise cannot be encapsulated by a single scope. In that
#' case, you can use the `Progress` reference class.
#' case, you can use the \code{Progress} reference class.
#'
#' As of version 0.14, the progress indicators use Shiny's new notification API.
#' If you want to use the old styling (for example, you may have used customized
#' CSS), you can use `style="old"` each time you call
#' `withProgress()`. If you don't want to set the style each time
#' `withProgress` is called, you can instead call
#' [`shinyOptions(progress.style="old")`][shinyOptions] just once, inside the server
#' CSS), you can use \code{style="old"} each time you call
#' \code{withProgress()}. If you don't want to set the style each time
#' \code{withProgress} is called, you can instead call
#' \code{\link{shinyOptions}(progress.style="old")} just once, inside the server
#' function.
#'
#' @param session The Shiny session object, as provided by `shinyServer` to
#' @param session The Shiny session object, as provided by \code{shinyServer} to
#' the server function. The default is to automatically find the session by
#' using the current reactive domain.
#' @param expr The work to be done. This expression should contain calls to
#' `setProgress`.
#' \code{setProgress}.
#' @param min The value that represents the starting point of the progress bar.
#' Must be less tham `max`. Default is 0.
#' Must be less tham \code{max}. Default is 0.
#' @param max The value that represents the end of the progress bar. Must be
#' greater than `min`. Default is 1.
#' @param amount For `incProgress`, the amount to increment the status bar.
#' greater than \code{min}. Default is 1.
#' @param amount For \code{incProgress}, the amount to increment the status bar.
#' Default is 0.1.
#' @param env The environment in which `expr` should be evaluated.
#' @param quoted Whether `expr` is a quoted expression (this is not
#' @param env The environment in which \code{expr} should be evaluated.
#' @param quoted Whether \code{expr} is a quoted expression (this is not
#' common).
#' @param message A single-element character vector; the message to be displayed
#' to the user, or `NULL` to hide the current message (if any).
#' to the user, or \code{NULL} to hide the current message (if any).
#' @param detail A single-element character vector; the detail message to be
#' displayed to the user, or `NULL` to hide the current detail message
#' displayed to the user, or \code{NULL} to hide the current detail message
#' (if any). The detail message will be shown with a de-emphasized appearance
#' relative to `message`.
#' @param style Progress display style. If `"notification"` (the default),
#' relative to \code{message}.
#' @param style Progress display style. If \code{"notification"} (the default),
#' the progress indicator will show using Shiny's notification API. If
#' `"old"`, use the same HTML and CSS used in Shiny 0.13.2 and below
#' \code{"old"}, use the same HTML and CSS used in Shiny 0.13.2 and below
#' (this is for backward-compatibility).
#' @param value Single-element numeric vector; the value at which to set the
#' progress bar, relative to `min` and `max`.
#' progress bar, relative to \code{min} and \code{max}.
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -263,7 +263,7 @@ Progress <- R6Class(
#'
#' shinyApp(ui, server)
#' }
#' @seealso [Progress()]
#' @seealso \code{\link{Progress}}
#' @rdname withProgress
#' @export
withProgress <- function(expr, min = 0, max = 1,

View File

@@ -16,37 +16,25 @@ processId <- local({
}
})
#' @include graph.R
Context <- R6Class(
'Context',
portable = FALSE,
class = FALSE,
public = list(
id = character(0),
.reactId = character(0),
.reactType = "other",
.label = character(0), # For debug purposes
.invalidated = FALSE,
.invalidateCallbacks = list(),
.flushCallbacks = list(),
.domain = NULL,
.pid = NULL,
.weak = NULL,
initialize = function(
domain, label='', type='other', prevId='',
reactId = rLog$noReactId,
id = .getReactiveEnvironment()$nextId(), # For dummy context
weak = FALSE
) {
id <<- id
initialize = function(domain, label='', type='other', prevId='') {
id <<- .getReactiveEnvironment()$nextId()
.label <<- label
.domain <<- domain
.pid <<- processId()
.reactId <<- reactId
.reactType <<- type
.weak <<- weak
rLog$createContext(id, label, type, prevId, domain)
.graphCreateContext(id, label, type, prevId, domain)
},
run = function(func) {
"Run the provided function under this context."
@@ -54,8 +42,10 @@ Context <- R6Class(
promises::with_promise_domain(reactivePromiseDomain(), {
withReactiveDomain(.domain, {
env <- .getReactiveEnvironment()
rLog$enter(.reactId, id, .reactType, .domain)
on.exit(rLog$exit(.reactId, id, .reactType, .domain), add = TRUE)
.graphEnterContext(id)
on.exit({
.graphExitContext(id, domain = .domain)
}, add = TRUE)
env$runWith(self, func)
})
})
@@ -72,9 +62,7 @@ Context <- R6Class(
return()
.invalidated <<- TRUE
rLog$invalidateStart(.reactId, id, .reactType, .domain)
on.exit(rLog$invalidateEnd(.reactId, id, .reactType, .domain), add = TRUE)
.graphInvalidate(id, .domain)
lapply(.invalidateCallbacks, function(func) {
func()
})
@@ -111,9 +99,6 @@ Context <- R6Class(
lapply(.flushCallbacks, function(flushCallback) {
flushCallback()
})
},
isWeak = function() {
.weak
}
)
)
@@ -166,10 +151,7 @@ ReactiveEnvironment <- R6Class(
# If already in a flush, don't start another one
if (.inFlush) return(invisible(FALSE))
.inFlush <<- TRUE
on.exit({
.inFlush <<- FALSE
rLog$idle(domain = NULL)
})
on.exit(.inFlush <<- FALSE)
while (hasPendingFlush()) {
ctx <- .pendingFlush$dequeue()
@@ -201,16 +183,18 @@ flushReact <- function() {
getCurrentContext <- function() {
.getReactiveEnvironment()$currentContext()
}
hasCurrentContext <- function() {
!is.null(.getReactiveEnvironment()$.currentContext)
}
getDummyContext <- function() {
Context$new(
getDefaultReactiveDomain(), '[none]', type = 'isolate',
id = "Dummy", reactId = rLog$dummyReactId
)
}
getDummyContext <- function() {}
local({
dummyContext <- NULL
getDummyContext <<- function() {
if (is.null(dummyContext)) {
dummyContext <<- Context$new(getDefaultReactiveDomain(), '[none]',
type='isolate')
}
return(dummyContext)
}
})
wrapForContext <- function(func, ctx) {
force(func)

View File

@@ -168,31 +168,31 @@ onReactiveDomainEnded <- function(domain, callback, failIfNull = FALSE) {
#' them ends) and error handling.
#'
#' At any given time, there can be either a single "default" reactive domain
#' object, or none (i.e. the reactive domain object is `NULL`). You can
#' object, or none (i.e. the reactive domain object is \code{NULL}). You can
#' access the current default reactive domain by calling
#' `getDefaultReactiveDomain`.
#' \code{getDefaultReactiveDomain}.
#'
#' Unless you specify otherwise, newly created observers and reactive
#' expressions will be assigned to the current default domain (if any). You can
#' override this assignment by providing an explicit `domain` argument to
#' [reactive()] or [observe()].
#' override this assignment by providing an explicit \code{domain} argument to
#' \code{\link{reactive}} or \code{\link{observe}}.
#'
#' For advanced usage, it's possible to override the default domain using
#' `withReactiveDomain`. The `domain` argument will be made the
#' default domain while `expr` is evaluated.
#' \code{withReactiveDomain}. The \code{domain} argument will be made the
#' default domain while \code{expr} is evaluated.
#'
#' Implementers of new reactive primitives can use `onReactiveDomainEnded`
#' Implementers of new reactive primitives can use \code{onReactiveDomainEnded}
#' as a convenience function for registering callbacks. If the reactive domain
#' is `NULL` and `failIfNull` is `FALSE`, then the callback will
#' is \code{NULL} and \code{failIfNull} is \code{FALSE}, then the callback will
#' never be invoked.
#'
#' @name domains
#' @param domain A valid domain object (for example, a Shiny session), or
#' `NULL`
#' @param expr An expression to evaluate under `domain`
#' \code{NULL}
#' @param expr An expression to evaluate under \code{domain}
#' @param callback A callback function to be invoked
#' @param failIfNull If `TRUE` then an error is given if the `domain`
#' is `NULL`
#' @param failIfNull If \code{TRUE} then an error is given if the \code{domain}
#' is \code{NULL}
NULL
#

File diff suppressed because it is too large Load Diff

View File

@@ -2,29 +2,29 @@
#'
#' Renders a reactive plot, with plot images cached to disk.
#'
#' `expr` is an expression that generates a plot, similar to that in
#' `renderPlot`. Unlike with `renderPlot`, this expression does not
#' \code{expr} is an expression that generates a plot, similar to that in
#' \code{renderPlot}. Unlike with \code{renderPlot}, this expression does not
#' take reactive dependencies. It is re-executed only when the cache key
#' changes.
#'
#' `cacheKeyExpr` is an expression which, when evaluated, returns an object
#' which will be serialized and hashed using the [digest::digest()]
#' \code{cacheKeyExpr} is an expression which, when evaluated, returns an object
#' which will be serialized and hashed using the \code{\link[digest]{digest}}
#' function to generate a string that will be used as a cache key. This key is
#' used to identify the contents of the plot: if the cache key is the same as a
#' previous time, it assumes that the plot is the same and can be retrieved from
#' the cache.
#'
#' This `cacheKeyExpr` is reactive, and so it will be re-evaluated when any
#' This \code{cacheKeyExpr} is reactive, and so it will be re-evaluated when any
#' upstream reactives are invalidated. This will also trigger re-execution of
#' the plotting expression, `expr`.
#' the plotting expression, \code{expr}.
#'
#' The key should consist of "normal" R objects, like vectors and lists. Lists
#' should in turn contain other normal R objects. If the key contains
#' environments, external pointers, or reference objects --- or even if it has
#' such objects attached as attributes --- then it is possible that it will
#' environments, external pointers, or reference objects -- or even if it has
#' such objects attached as attributes -- then it is possible that it will
#' change unpredictably even when you do not expect it to. Additionally, because
#' the entire key is serialized and hashed, if it contains a very large object
#' --- a large data set, for example --- there may be a noticeable performance
#' -- a large data set, for example -- there may be a noticeable performance
#' penalty.
#'
#' If you face these issues with the cache key, you can work around them by
@@ -32,12 +32,12 @@
#' to normal R objects before returning them. Your expression could even
#' serialize and hash that information in an efficient way and return a string,
#' which will in turn be hashed (very quickly) by the
#' [digest::digest()] function.
#' \code{\link[digest]{digest}} function.
#'
#' Internally, the result from `cacheKeyExpr` is combined with the name of
#' the output (if you assign it to `output$plot1`, it will be combined
#' with `"plot1"`) to form the actual key that is used. As a result, even
#' if there are multiple plots that have the same `cacheKeyExpr`, they
#' Internally, the result from \code{cacheKeyExpr} is combined with the name of
#' the output (if you assign it to \code{output$plot1}, it will be combined
#' with \code{"plot1"}) to form the actual key that is used. As a result, even
#' if there are multiple plots that have the same \code{cacheKeyExpr}, they
#' will not have cache key collisions.
#'
#' @section Cache scoping:
@@ -49,28 +49,28 @@
#' cache that persists even after the application is shut down and started
#' again.
#'
#' To control the scope of the cache, use the `cache` parameter. There
#' To control the scope of the cache, use the \code{cache} parameter. There
#' are two ways of having Shiny automatically create and clean up the disk
#' cache.
#'
#' \describe{
#' \item{1}{To scope the cache to one run of a Shiny application (shared
#' among possibly multiple user sessions), use `cache="app"`. This
#' among possibly multiple user sessions), use \code{cache="app"}. This
#' is the default. The cache will be shared across multiple sessions, so
#' there is potentially a large performance benefit if there are many users
#' of the application. When the application stops running, the cache will
#' be deleted. If plots cannot be safely shared across users, this should
#' not be used.}
#' \item{2}{To scope the cache to one session, use `cache="session"`.
#' When a new user session starts --- in other words, when a web browser
#' visits the Shiny application --- a new cache will be created on disk
#' \item{2}{To scope the cache to one session, use \code{cache="session"}.
#' When a new user session starts -- in other words, when a web browser
#' visits the Shiny application -- a new cache will be created on disk
#' for that session. When the session ends, the cache will be deleted.
#' The cache will not be shared across multiple sessions.}
#' }
#'
#' If either `"app"` or `"session"` is used, the cache will be 10 MB
#' If either \code{"app"} or \code{"session"} is used, the cache will be 10 MB
#' in size, and will be stored stored in memory, using a
#' [memoryCache()] object. Note that the cache space will be shared
#' \code{\link{memoryCache}} object. Note that the cache space will be shared
#' among all cached plots within a single application or session.
#'
#' In some cases, you may want more control over the caching behavior. For
@@ -79,7 +79,7 @@
#' multiple runs of an application, or even across multiple R processes.
#'
#' To use different settings for an application-scoped cache, you can call
#' [shinyOptions()] at the top of your app.R, server.R, or
#' \code{\link{shinyOptions}()} at the top of your app.R, server.R, or
#' global.R. For example, this will create a cache with 20 MB of space
#' instead of the default 10 MB:
#' \preformatted{
@@ -87,9 +87,9 @@
#' }
#'
#' To use different settings for a session-scoped cache, you can call
#' [shinyOptions()] at the top of your server function. To use
#' the session-scoped cache, you must also call `renderCachedPlot` with
#' `cache="session"`. This will create a 20 MB cache for the session:
#' \code{\link{shinyOptions}()} at the top of your server function. To use
#' the session-scoped cache, you must also call \code{renderCachedPlot} with
#' \code{cache="session"}. This will create a 20 MB cache for the session:
#' \preformatted{
#' function(input, output, session) {
#' shinyOptions(cache = memoryCache(size = 20e6))
@@ -102,7 +102,7 @@
#' }
#'
#' If you want to create a cache that is shared across multiple concurrent
#' R processes, you can use a [diskCache()]. You can create an
#' R processes, you can use a \code{\link{diskCache}}. You can create an
#' application-level shared cache by putting this at the top of your app.R,
#' server.R, or global.R:
#' \preformatted{
@@ -110,7 +110,7 @@
#' }
#'
#' This will create a subdirectory in your system temp directory named
#' `myapp-cache` (replace `myapp-cache` with a unique name of
#' \code{myapp-cache} (replace \code{myapp-cache} with a unique name of
#' your choosing). On most platforms, this directory will be removed when
#' your system reboots. This cache will persist across multiple starts and
#' stops of the R process, as long as you do not reboot.
@@ -126,34 +126,34 @@
#' the directory.
#'
#' You can also scope a cache to just one plot, or selected plots. To do that,
#' create a [memoryCache()] or [diskCache()], and pass it
#' as the `cache` argument of `renderCachedPlot`.
#' create a \code{\link{memoryCache}} or \code{\link{diskCache}}, and pass it
#' as the \code{cache} argument of \code{renderCachedPlot}.
#'
#' @section Interactive plots:
#'
#' `renderCachedPlot` can be used to create interactive plots. See
#' [plotOutput()] for more information and examples.
#' \code{renderCachedPlot} can be used to create interactive plots. See
#' \code{\link{plotOutput}} for more information and examples.
#'
#'
#' @inheritParams renderPlot
#' @param cacheKeyExpr An expression that returns a cache key. This key should
#' be a unique identifier for a plot: the assumption is that if the cache key
#' is the same, then the plot will be the same.
#' @param sizePolicy A function that takes two arguments, `width` and
#' `height`, and returns a list with `width` and `height`. The
#' @param sizePolicy A function that takes two arguments, \code{width} and
#' \code{height}, and returns a list with \code{width} and \code{height}. The
#' purpose is to round the actual pixel dimensions from the browser to some
#' other dimensions, so that this will not generate and cache images of every
#' possible pixel dimension. See [sizeGrowthRatio()] for more
#' possible pixel dimension. See \code{\link{sizeGrowthRatio}} for more
#' information on the default sizing policy.
#' @param res The resolution of the PNG, in pixels per inch.
#' @param cache The scope of the cache, or a cache object. This can be
#' `"app"` (the default), `"session"`, or a cache object like
#' a [diskCache()]. See the Cache Scoping section for more
#' \code{"app"} (the default), \code{"session"}, or a cache object like
#' a \code{\link{diskCache}}. See the Cache Scoping section for more
#' information.
#'
#' @seealso See [renderPlot()] for the regular, non-cached version of
#' @seealso See \code{\link{renderPlot}} for the regular, non-cached version of
#' this function. For more about configuring caches, see
#' [memoryCache()] and [diskCache()].
#' \code{\link{memoryCache}} and \code{\link{diskCache}}.
#'
#'
#' @examples
@@ -379,7 +379,7 @@ renderCachedPlot <- function(expr,
hybrid_chain(
# Depend on the user cache key, even though we don't use the value. When
# it changes, it can cause the drawReactive to re-execute. (Though
# drawReactive will not necessarily re-execute --- it must be called from
# drawReactive will not necessarily re-execute -- it must be called from
# renderFunc, which happens only if there's a cache miss.)
userCacheKey(),
function(userCacheKeyValue) {
@@ -476,64 +476,62 @@ renderCachedPlot <- function(expr,
}
)
},
function(possiblyAsyncResult) {
hybrid_chain(possiblyAsyncResult, function(result) {
width <- result$width
height <- result$height
pixelratio <- result$pixelratio
function(result) {
width <- result$width
height <- result$height
pixelratio <- result$pixelratio
# Three possibilities when we get here:
# 1. There was a cache hit. No need to set a value in the cache.
# 2. There was a cache miss, and the plotObj is already the correct
# size (because drawReactive re-executed). In this case, we need
# to cache it.
# 3. There was a cache miss, and the plotObj was not the corect size.
# In this case, we need to replay the display list, and then cache
# the result.
if (!result$cacheHit) {
# If the image is already the correct size, this just returns the
# object unchanged.
result$plotObj <- do.call("resizeSavedPlot", c(
list(
name,
shinysession,
result$plotObj,
width,
height,
pixelratio,
res
),
args
))
# Three possibilities when we get here:
# 1. There was a cache hit. No need to set a value in the cache.
# 2. There was a cache miss, and the plotObj is already the correct
# size (because drawReactive re-executed). In this case, we need
# to cache it.
# 3. There was a cache miss, and the plotObj was not the corect size.
# In this case, we need to replay the display list, and then cache
# the result.
if (!result$cacheHit) {
# If the image is already the correct size, this just returns the
# object unchanged.
result$plotObj <- do.call("resizeSavedPlot", c(
list(
name,
shinysession,
result$plotObj,
width,
height,
pixelratio,
res
),
args
))
# Save a cached copy of the plotObj. The recorded displaylist for
# the plot can't be serialized and restored properly within the same
# R session, so we NULL it out before saving. (The image data and
# other metadata be saved and restored just fine.) Displaylists can
# also be very large (~1.5MB for a basic ggplot), and they would not
# be commonly used. Note that displaylist serialization was fixed in
# revision 74506 (2e6c669), and should be in R 3.6. A MemoryCache
# doesn't need to serialize objects, so it could actually save a
# display list, but for the reasons listed previously, it's
# generally not worth it.
# The plotResult is not the same as the recordedPlot (it is used to
# retrieve coordmap information for ggplot2 objects) but it is only
# used in conjunction with the recordedPlot, and we'll remove it
# because it can be quite large.
result$plotObj$plotResult <- NULL
result$plotObj$recordedPlot <- NULL
cache$set(result$key, result$plotObj)
}
# Save a cached copy of the plotObj. The recorded displaylist for
# the plot can't be serialized and restored properly within the same
# R session, so we NULL it out before saving. (The image data and
# other metadata be saved and restored just fine.) Displaylists can
# also be very large (~1.5MB for a basic ggplot), and they would not
# be commonly used. Note that displaylist serialization was fixed in
# revision 74506 (2e6c669), and should be in R 3.6. A MemoryCache
# doesn't need to serialize objects, so it could actually save a
# display list, but for the reasons listed previously, it's
# generally not worth it.
# The plotResult is not the same as the recordedPlot (it is used to
# retrieve coordmap information for ggplot2 objects) but it is only
# used in conjunction with the recordedPlot, and we'll remove it
# because it can be quite large.
result$plotObj$plotResult <- NULL
result$plotObj$recordedPlot <- NULL
cache$set(result$key, result$plotObj)
}
img <- result$plotObj$img
# Replace exact pixel dimensions; instead, the max-height and
# max-width will be set to 100% from CSS.
img$class <- "shiny-scalable"
img$width <- NULL
img$height <- NULL
img <- result$plotObj$img
# Replace exact pixel dimensions; instead, the max-height and
# max-width will be set to 100% from CSS.
img$class <- "shiny-scalable"
img$width <- NULL
img$height <- NULL
img
})
img
}
)
}
@@ -562,7 +560,7 @@ renderCachedPlot <- function(expr,
#' @param width,height Base width and height.
#' @param growthRate Growth rate multiplier.
#'
#' @seealso This is to be used with [renderCachedPlot()].
#' @seealso This is to be used with \code{\link{renderCachedPlot}}.
#'
#' @examples
#' f <- sizeGrowthRatio(500, 500, 1.25)

View File

@@ -1,50 +1,48 @@
#' Plot Output
#'
#' Renders a reactive plot that is suitable for assigning to an `output`
#' Renders a reactive plot that is suitable for assigning to an \code{output}
#' slot.
#'
#' The corresponding HTML output tag should be `div` or `img` and have
#' the CSS class name `shiny-plot-output`.
#' The corresponding HTML output tag should be \code{div} or \code{img} and have
#' the CSS class name \code{shiny-plot-output}.
#'
#' @section Interactive plots:
#'
#' With ggplot2 graphics, the code in `renderPlot` should return a ggplot
#' With ggplot2 graphics, the code in \code{renderPlot} should return a ggplot
#' object; if instead the code prints the ggplot2 object with something like
#' `print(p)`, then the coordinates for interactive graphics will not be
#' \code{print(p)}, then the coordinates for interactive graphics will not be
#' properly scaled to the data space.
#'
#' See [plotOutput()] for more information about interactive plots.
#' See \code{\link{plotOutput}} for more information about interactive plots.
#'
#' @seealso For the corresponding client-side output function, and example
#' usage, see [plotOutput()]. For more details on how the plots are
#' generated, and how to control the output, see [plotPNG()].
#' [renderCachedPlot()] offers a way to cache generated plots to
#' expedite the rendering of identical plots.
#' usage, see \code{\link{plotOutput}}. For more details on how the plots are
#' generated, and how to control the output, see \code{\link{plotPNG}}.
#'
#' @param expr An expression that generates a plot.
#' @param width,height The width/height of the rendered plot, in pixels; or
#' `'auto'` to use the `offsetWidth`/`offsetHeight` of the HTML
#' \code{'auto'} to use the \code{offsetWidth}/\code{offsetHeight} of the HTML
#' element that is bound to this plot. You can also pass in a function that
#' returns the width/height in pixels or `'auto'`; in the body of the
#' returns the width/height in pixels or \code{'auto'}; in the body of the
#' function you may reference reactive values and functions. When rendering an
#' inline plot, you must provide numeric values (in pixels) to both
#' `width` and `height`.
#' \code{width} and \code{height}.
#' @param res Resolution of resulting plot, in pixels per inch. This value is
#' passed to [grDevices::png()]. Note that this affects the resolution of PNG
#' passed to \code{\link[grDevices]{png}}. Note that this affects the resolution of PNG
#' rendering in R; it won't change the actual ppi of the browser.
#' @param ... Arguments to be passed through to [grDevices::png()].
#' @param ... Arguments to be passed through to \code{\link[grDevices]{png}}.
#' These can be used to set the width, height, background color, etc.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' is useful if you want to save an expression in a variable.
#' @param execOnResize If `FALSE` (the default), then when a plot is
#' resized, Shiny will *replay* the plot drawing commands with
#' [grDevices::replayPlot()] instead of re-executing `expr`.
#' @param execOnResize If \code{FALSE} (the default), then when a plot is
#' resized, Shiny will \emph{replay} the plot drawing commands with
#' \code{\link[grDevices]{replayPlot}()} instead of re-executing \code{expr}.
#' This can result in faster plot redrawing, but there may be rare cases where
#' it is undesirable. If you encounter problems when resizing a plot, you can
#' have Shiny re-execute the code on resize by setting this to `TRUE`.
#' have Shiny re-execute the code on resize by setting this to \code{TRUE}.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [plotOutput()] when `renderPlot` is used in an
#' call to \code{\link{plotOutput}} when \code{renderPlot} is used in an
#' interactive R Markdown document.
#' @export
renderPlot <- function(expr, width='auto', height='auto', res=72, ...,
@@ -355,88 +353,62 @@ custom_print.ggplot <- function(x) {
# With a faceted ggplot2 plot, the outer list contains two objects, each of
# which represents one panel. In this example, there is one panelvar, but there
# can be up to two of them.
# p <- print(ggplot(mpg) + geom_point(aes(fl, cty), alpha = 0.2) + facet_wrap(~drv, scales = "free_x"))
# str(getGgplotCoordmap(p, 500, 400, 72))
# mtc <- mtcars
# mtc$am <- factor(mtc$am)
# p <- print(ggplot(mtc, aes(wt, mpg)) + geom_point() + facet_wrap(~ am))
# str(getGgplotCoordmap(p, 400, 300, 72))
# List of 2
# $ panels:List of 3
# $ panels:List of 2
# ..$ :List of 8
# .. ..$ panel : num 1
# .. ..$ row : int 1
# .. ..$ col : int 1
# .. ..$ panel_vars:List of 1
# .. .. ..$ panelvar1: chr "4"
# .. .. ..$ panelvar1: Factor w/ 2 levels "0","1": 1
# .. ..$ log :List of 2
# .. .. ..$ x: NULL
# .. .. ..$ y: NULL
# .. ..$ domain :List of 5
# .. .. ..$ left : num 0.4
# .. .. ..$ right : num 4.6
# .. .. ..$ bottom : num 7.7
# .. .. ..$ top : num 36.3
# .. .. ..$ discrete_limits:List of 1
# .. .. .. ..$ x: chr [1:4] "d" "e" "p" "r"
# .. ..$ domain :List of 4
# .. .. ..$ left : num 1.32
# .. .. ..$ right : num 5.62
# .. .. ..$ bottom: num 9.22
# .. .. ..$ top : num 35.1
# .. ..$ mapping :List of 3
# .. .. ..$ x : chr "fl"
# .. .. ..$ y : chr "cty"
# .. .. ..$ panelvar1: chr "drv"
# .. .. ..$ x : chr "wt"
# .. .. ..$ y : chr "mpg"
# .. .. ..$ panelvar1: chr "am"
# .. ..$ range :List of 4
# .. .. ..$ left : num 33.3
# .. .. ..$ right : num 177
# .. .. ..$ bottom: num 448
# .. .. ..$ right : num 191
# .. .. ..$ bottom: num 328
# .. .. ..$ top : num 23.1
# ..$ :List of 8
# .. ..$ panel : num 2
# .. ..$ row : int 1
# .. ..$ col : int 2
# .. ..$ panel_vars:List of 1
# .. .. ..$ panelvar1: chr "f"
# .. .. ..$ panelvar1: Factor w/ 2 levels "0","1": 2
# .. ..$ log :List of 2
# .. .. ..$ x: NULL
# .. .. ..$ y: NULL
# .. ..$ domain :List of 5
# .. .. ..$ left : num 0.4
# .. .. ..$ right : num 5.6
# .. .. ..$ bottom : num 7.7
# .. .. ..$ top : num 36.3
# .. .. ..$ discrete_limits:List of 1
# .. .. .. ..$ x: chr [1:5] "c" "d" "e" "p" ...
# .. ..$ domain :List of 4
# .. .. ..$ left : num 1.32
# .. .. ..$ right : num 5.62
# .. .. ..$ bottom: num 9.22
# .. .. ..$ top : num 35.1
# .. ..$ mapping :List of 3
# .. .. ..$ x : chr "fl"
# .. .. ..$ y : chr "cty"
# .. .. ..$ panelvar1: chr "drv"
# .. .. ..$ x : chr "wt"
# .. .. ..$ y : chr "mpg"
# .. .. ..$ panelvar1: chr "am"
# .. ..$ range :List of 4
# .. .. ..$ left : num 182
# .. .. ..$ right : num 326
# .. .. ..$ bottom: num 448
# .. .. ..$ top : num 23.1
# ..$ :List of 8
# .. ..$ panel : num 3
# .. ..$ row : int 1
# .. ..$ col : int 3
# .. ..$ panel_vars:List of 1
# .. .. ..$ panelvar1: chr "r"
# .. ..$ log :List of 2
# .. .. ..$ x: NULL
# .. .. ..$ y: NULL
# .. ..$ domain :List of 5
# .. .. ..$ left : num 0.4
# .. .. ..$ right : num 3.6
# .. .. ..$ bottom : num 7.7
# .. .. ..$ top : num 36.3
# .. .. ..$ discrete_limits:List of 1
# .. .. .. ..$ x: chr [1:3] "e" "p" "r"
# .. ..$ mapping :List of 3
# .. .. ..$ x : chr "fl"
# .. .. ..$ y : chr "cty"
# .. .. ..$ panelvar1: chr "drv"
# .. ..$ range :List of 4
# .. .. ..$ left : num 331
# .. .. ..$ right : num 475
# .. .. ..$ bottom: num 448
# .. .. ..$ left : num 197
# .. .. ..$ right : num 355
# .. .. ..$ bottom: num 328
# .. .. ..$ top : num 23.1
# $ dims :List of 2
# ..$ width : num 500
# ..$ height: num 400
# ..$ width : num 400
# ..$ height: num 300
getCoordmap <- function(x, width, height, res) {
if (inherits(x, "ggplot_build_gtable")) {
@@ -598,9 +570,6 @@ find_panel_info_api <- function(b) {
domain$bottom <- -domain$bottom
}
domain <- add_discrete_limits(domain, xscale, "x")
domain <- add_discrete_limits(domain, yscale, "y")
domain
}
@@ -720,9 +689,6 @@ find_panel_info_non_api <- function(b, ggplot_format) {
domain$bottom <- -domain$bottom
}
domain <- add_discrete_limits(domain, xscale, "x")
domain <- add_discrete_limits(domain, yscale, "y")
domain
}
@@ -1029,23 +995,3 @@ find_panel_ranges <- function(g, res) {
)
})
}
# Remember the x/y limits of discrete axes. This info is
# necessary to properly inverse map the numeric (i.e., trained)
# positions back to the data scale, for example:
# https://github.com/rstudio/shiny/pull/2410#issuecomment-487783828
# https://github.com/rstudio/shiny/pull/2410#issuecomment-488100881
#
# Eventually, we may want to consider storing the entire ggplot2
# object server-side and querying information from that object
# as we need it...that's the only way we'll ever be able to
# faithfully brush examples like this:
# https://github.com/rstudio/shiny/issues/2411
add_discrete_limits <- function(domain, scale, var = "x") {
var <- match.arg(var, c("x", "y"))
if (!is.function(scale$is_discrete) || !is.function(scale$get_limits)) return(domain)
if (scale$is_discrete()) {
domain$discrete_limits[[var]] <- scale$get_limits()
}
domain
}

View File

@@ -1,50 +1,50 @@
#' Table Output
#'
#' Creates a reactive table that is suitable for assigning to an `output`
#' Creates a reactive table that is suitable for assigning to an \code{output}
#' slot.
#'
#' The corresponding HTML output tag should be `div` and have the CSS
#' class name `shiny-html-output`.
#' The corresponding HTML output tag should be \code{div} and have the CSS
#' class name \code{shiny-html-output}.
#'
#' @param expr An expression that returns an R object that can be used with
#' [xtable::xtable()].
#' @param striped,hover,bordered Logicals: if `TRUE`, apply the
#' \code{\link[xtable]{xtable}}.
#' @param striped,hover,bordered Logicals: if \code{TRUE}, apply the
#' corresponding Bootstrap table format to the output table.
#' @param spacing The spacing between the rows of the table (`xs`
#' stands for "extra small", `s` for "small", `m` for "medium"
#' and `l` for "large").
#' @param spacing The spacing between the rows of the table (\code{xs}
#' stands for "extra small", \code{s} for "small", \code{m} for "medium"
#' and \code{l} for "large").
#' @param width Table width. Must be a valid CSS unit (like "100%", "400px",
#' "auto") or a number, which will be coerced to a string and
#' have "px" appended.
#' @param align A string that specifies the column alignment. If equal to
#' `'l'`, `'c'` or `'r'`, then all columns will be,
#' respectively, left-, center- or right-aligned. Otherwise, `align`
#' \code{'l'}, \code{'c'} or \code{'r'}, then all columns will be,
#' respectively, left-, center- or right-aligned. Otherwise, \code{align}
#' must have the same number of characters as the resulting table (if
#' `rownames = TRUE`, this will be equal to `ncol()+1`), with
#' the *i*-th character specifying the alignment for the
#' *i*-th column (besides `'l'`, `'c'` and
#' `'r'`, `'?'` is also permitted - `'?'` is a placeholder
#' \code{rownames = TRUE}, this will be equal to \code{ncol()+1}), with
#' the \emph{i}-th character specifying the alignment for the
#' \emph{i}-th column (besides \code{'l'}, \code{'c'} and
#' \code{'r'}, \code{'?'} is also permitted - \code{'?'} is a placeholder
#' for that particular column, indicating that it should keep its default
#' alignment). If `NULL`, then all numeric/integer columns (including
#' alignment). If \code{NULL}, then all numeric/integer columns (including
#' the row names, if they are numbers) will be right-aligned and
#' everything else will be left-aligned (`align = '?'` produces the
#' everything else will be left-aligned (\code{align = '?'} produces the
#' same result).
#' @param rownames,colnames Logicals: include rownames? include colnames
#' (column headers)?
#' @param digits An integer specifying the number of decimal places for
#' the numeric columns (this will not apply to columns with an integer
#' class). If `digits` is set to a negative value, then the numeric
#' class). If \code{digits} is set to a negative value, then the numeric
#' columns will be displayed in scientific format with a precision of
#' `abs(digits)` digits.
#' \code{abs(digits)} digits.
#' @param na The string to use in the table cells whose values are missing
#' (i.e. they either evaluate to `NA` or `NaN`).
#' @param ... Arguments to be passed through to [xtable::xtable()]
#' and [xtable::print.xtable()].
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)?
#' (i.e. they either evaluate to \code{NA} or \code{NaN}).
#' @param ... Arguments to be passed through to \code{\link[xtable]{xtable}}
#' and \code{\link[xtable]{print.xtable}}.
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})?
#' This is useful if you want to save an expression in a variable.
#' @param outputArgs A list of arguments to be passed through to the
#' implicit call to [tableOutput()] when `renderTable` is
#' implicit call to \code{\link{tableOutput}} when \code{renderTable} is
#' used in an interactive R Markdown document.
#' @export
renderTable <- function(expr, striped = FALSE, hover = FALSE,

View File

@@ -1,24 +1,24 @@
#' Run a Shiny application from a URL
#'
#' `runUrl()` downloads and launches a Shiny application that is hosted at
#' \code{runUrl()} downloads and launches a Shiny application that is hosted at
#' a downloadable URL. The Shiny application must be saved in a .zip, .tar, or
#' .tar.gz file. The Shiny application files must be contained in the root
#' directory or a subdirectory in the archive. For example, the files might be
#' `myapp/server.r` and `myapp/ui.r`. The functions `runGitHub()`
#' and `runGist()` are based on `runUrl()`, using URL's from GitHub
#' (<https://github.com>) and GitHub gists (<https://gist.github.com>),
#' \code{myapp/server.r} and \code{myapp/ui.r}. The functions \code{runGitHub()}
#' and \code{runGist()} are based on \code{runUrl()}, using URL's from GitHub
#' (\url{https://github.com}) and GitHub gists (\url{https://gist.github.com}),
#' respectively.
#' @param url URL of the application.
#' @param filetype The file type (`".zip"`, `".tar"`, or
#' `".tar.gz"`. Defaults to the file extension taken from the url.
#' @param filetype The file type (\code{".zip"}, \code{".tar"}, or
#' \code{".tar.gz"}. Defaults to the file extension taken from the url.
#' @param subdir A subdirectory in the repository that contains the app. By
#' default, this function will run an app from the top level of the repo, but
#' you can use a path such as `"inst/shinyapp"`.
#' @param destdir Directory to store the downloaded application files. If `NULL`
#' you can use a path such as `\code{"inst/shinyapp"}.
#' @param destdir Directory to store the downloaded application files. If \code{NULL}
#' (the default), the application files will be stored in a temporary directory
#' and removed when the app exits
#' @param ... Other arguments to be passed to [runApp()], such as
#' `port` and `launch.browser`.
#' @param ... Other arguments to be passed to \code{\link{runApp}()}, such as
#' \code{port} and \code{launch.browser}.
#' @export
#' @examples
#' ## Only run this example in interactive R sessions
@@ -88,8 +88,8 @@ runUrl <- function(url, filetype = NULL, subdir = NULL, destdir = NULL, ...) {
#' @rdname runUrl
#' @param gist The identifier of the gist. For example, if the gist is
#' https://gist.github.com/jcheng5/3239667, then `3239667`,
#' `'3239667'`, and `'https://gist.github.com/jcheng5/3239667'` are
#' https://gist.github.com/jcheng5/3239667, then \code{3239667},
#' \code{'3239667'}, and \code{'https://gist.github.com/jcheng5/3239667'} are
#' all valid values.
#' @export
#' @examples
@@ -118,10 +118,10 @@ runGist <- function(gist, destdir = NULL, ...) {
#' @rdname runUrl
#' @param repo Name of the repository.
#' @param username GitHub username. If `repo` is of the form
#' `"username/repo"`, `username` will be taken from `repo`.
#' @param username GitHub username. If \code{repo} is of the form
#' \code{"username/repo"}, \code{username} will be taken from \code{repo}.
#' @param ref Desired git reference. Could be a commit, tag, or branch name.
#' Defaults to `"master"`.
#' Defaults to \code{"master"}.
#' @export
#' @examples
#' ## Only run this example in interactive R sessions

View File

@@ -5,34 +5,34 @@ inputHandlers <- Map$new()
#'
#' Adds an input handler for data of this type. When called, Shiny will use the
#' function provided to refine the data passed back from the client (after being
#' deserialized by jsonlite) before making it available in the `input`
#' variable of the `server.R` file.
#' deserialized by jsonlite) before making it available in the \code{input}
#' variable of the \code{server.R} file.
#'
#' This function will register the handler for the duration of the R process
#' (unless Shiny is explicitly reloaded). For that reason, the `type` used
#' (unless Shiny is explicitly reloaded). For that reason, the \code{type} used
#' should be very specific to this package to minimize the risk of colliding
#' with another Shiny package which might use this data type name. We recommend
#' the format of "packageName.widgetName".
#'
#' Currently Shiny registers the following handlers: `shiny.matrix`,
#' `shiny.number`, and `shiny.date`.
#' Currently Shiny registers the following handlers: \code{shiny.matrix},
#' \code{shiny.number}, and \code{shiny.date}.
#'
#' The `type` of a custom Shiny Input widget will be deduced using the
#' `getType()` JavaScript function on the registered Shiny inputBinding.
#' @param type The type for which the handler should be added --- should be a
#' The \code{type} of a custom Shiny Input widget will be deduced using the
#' \code{getType()} JavaScript function on the registered Shiny inputBinding.
#' @param type The type for which the handler should be added -- should be a
#' single-element character vector.
#' @param fun The handler function. This is the function that will be used to
#' parse the data delivered from the client before it is available in the
#' `input` variable. The function will be called with the following three
#' \code{input} variable. The function will be called with the following three
#' parameters:
#' \enumerate{
#' \item{The value of this input as provided by the client, deserialized
#' using jsonlite.}
#' \item{The `shinysession` in which the input exists.}
#' \item{The \code{shinysession} in which the input exists.}
#' \item{The name of the input.}
#' }
#' @param force If `TRUE`, will overwrite any existing handler without
#' warning. If `FALSE`, will throw an error if this class already has
#' @param force If \code{TRUE}, will overwrite any existing handler without
#' warning. If \code{FALSE}, will throw an error if this class already has
#' a handler defined.
#' @examples
#' \dontrun{
@@ -48,7 +48,7 @@ inputHandlers <- Map$new()
#' }
#'
#' }
#' @seealso [removeInputHandler()]
#' @seealso \code{\link{removeInputHandler}}
#' @export
registerInputHandler <- function(type, fun, force=FALSE){
if (inputHandlers$containsKey(type) && !force){
@@ -63,9 +63,9 @@ registerInputHandler <- function(type, fun, force=FALSE){
#' for data of this type, the default jsonlite serialization will be used.
#'
#' @param type The type for which handlers should be removed.
#' @return The handler previously associated with this `type`, if one
#' existed. Otherwise, `NULL`.
#' @seealso [registerInputHandler()]
#' @return The handler previously associated with this \code{type}, if one
#' existed. Otherwise, \code{NULL}.
#' @seealso \code{\link{registerInputHandler}}
#' @export
removeInputHandler <- function(type){
inputHandlers$remove(type)
@@ -103,8 +103,8 @@ applyInputHandler <- function(name, val, shinysession) {
#' values.
#'
#' The raw input values should be in a named list. Some values may have names
#' like `"x:shiny.date"`. This function would apply the `"shiny.date"`
#' input handler to the value, and then rename the result to `"x"`, in the
#' like \code{"x:shiny.date"}. This function would apply the \code{"shiny.date"}
#' input handler to the value, and then rename the result to \code{"x"}, in the
#' output.
#'
#' @param inputs A named list of input values.

View File

@@ -22,7 +22,6 @@ registerClient <- function(client) {
}
.globals$resourcePaths <- list()
.globals$resources <- list()
.globals$showcaseDefault <- 0
@@ -42,7 +41,12 @@ registerClient <- function(client) {
#' @param directoryPath The directory that contains the static resources to be
#' served.
#'
#' @seealso [singleton()]
#' @details You can call \code{addResourcePath} multiple times for a given
#' \code{prefix}; only the most recent value will be retained. If the
#' normalized \code{directoryPath} is different than the directory that's
#' currently mapped to the \code{prefix}, a warning will be issued.
#'
#' @seealso \code{\link{singleton}}
#'
#' @examples
#' addResourcePath('datasets', system.file('data', package='datasets'))
@@ -62,65 +66,30 @@ addResourcePath <- function(prefix, directoryPath) {
"`prefix` = '", prefix, "'; `directoryPath` = '" , directoryPath, "'")
}
)
# If a shiny app is currently running, dynamically register this path with
# the corresponding httpuv server object.
if (!is.null(getShinyOption("server")))
{
getShinyOption("server")$setStaticPath(.list = stats::setNames(normalizedPath, prefix))
}
# .globals$resourcePaths and .globals$resources persist across runs of applications.
.globals$resourcePaths[[prefix]] <- staticPath(normalizedPath)
# This is necessary because resourcePaths is only for serving assets out of C++;
# to support subapps, we also need assets to be served out of R, because those
# URLs are rewritten by R code (i.e. routeHandler) before they can be matched to
# a resource path.
.globals$resources[[prefix]] <- list(
directoryPath = normalizedPath,
func = staticHandler(normalizedPath)
)
}
# This function handles any GET request with two or more path elements where the
# first path element matches a prefix that was previously added using
# addResourcePath().
#
# For example, if `addResourcePath("foo", "~/bar")` was called, then a GET
# request for /foo/one/two.html would rewrite the PATH_INFO as /one/two.html and
# send it to the resource path function for "foo". As of this writing, that
# function will always be a staticHandler, which serves up a file if it exists
# and NULL if it does not.
#
# Since Shiny 1.3.x, assets registered via addResourcePath should mostly be
# served out of httpuv's native static file serving features. However, in the
# specific case of subapps, the R code path must be used, because subapps insert
# a giant random ID into the beginning of the URL that must be stripped off by
# an R route handler (see addSubApp()).
resourcePathHandler <- function(req) {
if (!identical(req$REQUEST_METHOD, 'GET'))
return(NULL)
# e.g. "/foo/one/two.html"
path <- req$PATH_INFO
match <- regexpr('^/([^/]+)/', path, perl=TRUE)
if (match == -1)
return(NULL)
len <- attr(match, 'capture.length')
# e.g. "foo"
prefix <- substr(path, 2, 2 + len - 1)
resInfo <- .globals$resources[[prefix]]
if (is.null(resInfo))
return(NULL)
# e.g. "/one/two.html"
suffix <- substr(path, 2 + len, nchar(path))
# Create a new request that's a clone of the current request, but adjust
# PATH_INFO and SCRIPT_NAME to reflect that we have already matched the first
# path element (e.g. "/foo"). See routeHandler() for more info.
subreq <- as.environment(as.list(req, all.names=TRUE))
subreq$PATH_INFO <- suffix
subreq$SCRIPT_NAME <- paste(subreq$SCRIPT_NAME, substr(path, 1, 2 + len), sep='')
@@ -132,23 +101,23 @@ resourcePathHandler <- function(req) {
#'
#' Defines the server-side logic of the Shiny application. This generally
#' involves creating functions that map user inputs to various kinds of output.
#' In older versions of Shiny, it was necessary to call `shinyServer()` in
#' the `server.R` file, but this is no longer required as of Shiny 0.10.
#' Now the `server.R` file may simply return the appropriate server
#' In older versions of Shiny, it was necessary to call \code{shinyServer()} in
#' the \code{server.R} file, but this is no longer required as of Shiny 0.10.
#' Now the \code{server.R} file may simply return the appropriate server
#' function (as the last expression in the code), without calling
#' `shinyServer()`.
#' \code{shinyServer()}.
#'
#' Call `shinyServer` from your application's `server.R`
#' Call \code{shinyServer} from your application's \code{server.R}
#' file, passing in a "server function" that provides the server-side logic of
#' your application.
#'
#' The server function will be called when each client (web browser) first loads
#' the Shiny application's page. It must take an `input` and an
#' `output` parameter. Any return value will be ignored. It also takes an
#' optional `session` parameter, which is used when greater control is
#' the Shiny application's page. It must take an \code{input} and an
#' \code{output} parameter. Any return value will be ignored. It also takes an
#' optional \code{session} parameter, which is used when greater control is
#' needed.
#'
#' See the [tutorial](http://rstudio.github.com/shiny/tutorial/) for more
#' See the \href{http://rstudio.github.com/shiny/tutorial/}{tutorial} for more
#' on how to write a server function.
#'
#' @param func The server function for this application. See the details section
@@ -175,7 +144,6 @@ resourcePathHandler <- function(req) {
#' }
#' }
#' @export
#' @keywords internal
shinyServer <- function(func) {
.globals$server <- list(func)
invisible(func)
@@ -219,7 +187,7 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
# This value, if non-NULL, must be present on all HTTP and WebSocket
# requests as the Shiny-Shared-Secret header or else access will be
# denied (403 response for HTTP, and instant close for websocket).
checkSharedSecret <- loadSharedSecret()
sharedSecret <- getOption('shiny.sharedSecret')
appHandlers <- list(
http = joinHandlers(c(
@@ -227,10 +195,10 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
httpHandlers,
sys.www.root,
resourcePathHandler,
reactLogHandler
)),
reactLogHandler)),
ws = function(ws) {
if (!checkSharedSecret(ws$request$HTTP_SHINY_SHARED_SECRET)) {
if (!is.null(sharedSecret)
&& !identical(sharedSecret, ws$request$HTTP_SHINY_SHARED_SECRET)) {
ws$close()
return(TRUE)
}
@@ -449,27 +417,6 @@ startApp <- function(appObj, port, host, quiet) {
handlerManager$addHandler(appHandlers$http, "/", tail = TRUE)
handlerManager$addWSHandler(appHandlers$ws, "/", tail = TRUE)
httpuvApp <- handlerManager$createHttpuvApp()
httpuvApp$staticPaths <- c(
appObj$staticPaths,
list(
# Always handle /session URLs dynamically, even if / is a static path.
"session" = excludeStaticPath(),
"shared" = system.file(package = "shiny", "www", "shared")
),
.globals$resourcePaths
)
httpuvApp$staticPathOptions <- httpuv::staticPathOptions(
html_charset = "utf-8",
headers = list("X-UA-Compatible" = "IE=edge,chrome=1"),
validation =
if (!is.null(getOption("shiny.sharedSecret"))) {
sprintf('"Shiny-Shared-Secret" == "%s"', getOption("shiny.sharedSecret"))
} else {
character(0)
}
)
if (is.numeric(port) || is.integer(port)) {
if (!quiet) {
hostString <- host
@@ -477,7 +424,7 @@ startApp <- function(appObj, port, host, quiet) {
hostString <- paste0("[", hostString, "]")
message('\n', 'Listening on http://', hostString, ':', port)
}
return(startServer(host, port, httpuvApp))
return(startServer(host, port, handlerManager$createHttpuvApp()))
} else if (is.character(port)) {
if (!quiet) {
message('\n', 'Listening on domain socket ', port)
@@ -489,7 +436,7 @@ startApp <- function(appObj, port, host, quiet) {
"configuration (and not domain sockets), then `port` must ",
"be numeric, not a string.")
}
return(startPipeServer(port, mask, httpuvApp))
return(startPipeServer(port, mask, handlerManager$createHttpuvApp()))
}
}
@@ -521,8 +468,8 @@ serviceApp <- function() {
#'
#' This function tests whether a Shiny application is currently running.
#'
#' @return `TRUE` if a Shiny application is currently running. Otherwise,
#' `FALSE`.
#' @return \code{TRUE} if a Shiny application is currently running. Otherwise,
#' \code{FALSE}.
#' @export
isRunning <- function() {
.globals$running
@@ -534,44 +481,44 @@ isRunning <- function() {
#' to stop the application (usually by pressing Ctrl+C or Esc).
#'
#' The host parameter was introduced in Shiny 0.9.0. Its default value of
#' `"127.0.0.1"` means that, contrary to previous versions of Shiny, only
#' \code{"127.0.0.1"} means that, contrary to previous versions of Shiny, only
#' the current machine can access locally hosted Shiny apps. To allow other
#' clients to connect, use the value `"0.0.0.0"` instead (which was the
#' clients to connect, use the value \code{"0.0.0.0"} instead (which was the
#' value that was hard-coded into Shiny in 0.8.0 and earlier).
#'
#' @param appDir The application to run. Should be one of the following:
#' \itemize{
#' \item A directory containing `server.R`, plus, either `ui.R` or
#' a `www` directory that contains the file `index.html`.
#' \item A directory containing `app.R`.
#' \item An `.R` file containing a Shiny application, ending with an
#' \item A directory containing \code{server.R}, plus, either \code{ui.R} or
#' a \code{www} directory that contains the file \code{index.html}.
#' \item A directory containing \code{app.R}.
#' \item An \code{.R} file containing a Shiny application, ending with an
#' expression that produces a Shiny app object.
#' \item A list with `ui` and `server` components.
#' \item A Shiny app object created by [shinyApp()].
#' \item A list with \code{ui} and \code{server} components.
#' \item A Shiny app object created by \code{\link{shinyApp}}.
#' }
#' @param port The TCP port that the application should listen on. If the
#' `port` is not specified, and the `shiny.port` option is set (with
#' `options(shiny.port = XX)`), then that port will be used. Otherwise,
#' \code{port} is not specified, and the \code{shiny.port} option is set (with
#' \code{options(shiny.port = XX)}), then that port will be used. Otherwise,
#' use a random port.
#' @param launch.browser If true, the system's default web browser will be
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only. This value of this parameter can also be a
#' function to call with the application's URL.
#' @param host The IPv4 address that the application should listen on. Defaults
#' to the `shiny.host` option, if set, or `"127.0.0.1"` if not. See
#' to the \code{shiny.host} option, if set, or \code{"127.0.0.1"} if not. See
#' Details.
#' @param workerId Can generally be ignored. Exists to help some editions of
#' Shiny Server Pro route requests to the correct process.
#' @param quiet Should Shiny status messages be shown? Defaults to FALSE.
#' @param display.mode The mode in which to display the application. If set to
#' the value `"showcase"`, shows application code and metadata from a
#' `DESCRIPTION` file in the application directory alongside the
#' application. If set to `"normal"`, displays the application normally.
#' Defaults to `"auto"`, which displays the application in the mode given
#' in its `DESCRIPTION` file, if any.
#' the value \code{"showcase"}, shows application code and metadata from a
#' \code{DESCRIPTION} file in the application directory alongside the
#' application. If set to \code{"normal"}, displays the application normally.
#' Defaults to \code{"auto"}, which displays the application in the mode given
#' in its \code{DESCRIPTION} file, if any.
#' @param test.mode Should the application be launched in test mode? This is
#' only used for recording or running automated tests. Defaults to the
#' `shiny.testmode` option, or FALSE if the option is not set.
#' \code{shiny.testmode} option, or FALSE if the option is not set.
#'
#' @examples
#' \dontrun{
@@ -830,10 +777,6 @@ runApp <- function(appDir=getwd(),
server <- startApp(appParts, port, host, quiet)
# Make the httpuv server object accessible. Needed for calling
# addResourcePath while app is running.
shinyOptions(server = server)
on.exit({
stopServer(server)
}, add = TRUE)
@@ -892,10 +835,10 @@ runApp <- function(appDir=getwd(),
#' Stop the currently running Shiny app
#'
#' Stops the currently running Shiny app, returning control to the caller of
#' [runApp()].
#' \code{\link{runApp}}.
#'
#' @param returnValue The value that should be returned from
#' [runApp()].
#' \code{\link{runApp}}.
#' @export
stopApp <- function(returnValue = invisible()) {
# reterror will indicate whether retval is an error (i.e. it should be passed
@@ -924,7 +867,7 @@ stopApp <- function(returnValue = invisible()) {
#'
#' Launch Shiny example applications, and optionally, your system's web browser.
#'
#' @param example The name of the example to run, or `NA` (the default) to
#' @param example The name of the example to run, or \code{NA} (the default) to
#' list the available examples.
#' @param port The TCP port that the application should listen on. Defaults to
#' choosing a random port.
@@ -932,9 +875,9 @@ stopApp <- function(returnValue = invisible()) {
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only.
#' @param host The IPv4 address that the application should listen on. Defaults
#' to the `shiny.host` option, if set, or `"127.0.0.1"` if not.
#' to the \code{shiny.host} option, if set, or \code{"127.0.0.1"} if not.
#' @param display.mode The mode in which to display the example. Defaults to
#' `showcase`, but may be set to `normal` to see the example without
#' \code{showcase}, but may be set to \code{normal} to see the example without
#' code or commentary.
#'
#' @examples
@@ -981,21 +924,21 @@ runExample <- function(example=NA,
#' Run a gadget
#'
#' Similar to `runApp`, but handles `input$cancel` automatically, and
#' Similar to \code{runApp}, but handles \code{input$cancel} automatically, and
#' if running in RStudio, defaults to viewing the app in the Viewer pane.
#'
#' @param app Either a Shiny app object as created by
#' [`shinyApp()`][shiny] et al, or, a UI object.
#' @param server Ignored if `app` is a Shiny app object; otherwise, passed
#' along to `shinyApp` (i.e. `shinyApp(ui = app, server = server)`).
#' @param port See [`runApp()`][shiny].
#' \code{\link[=shiny]{shinyApp}} et al, or, a UI object.
#' @param server Ignored if \code{app} is a Shiny app object; otherwise, passed
#' along to \code{shinyApp} (i.e. \code{shinyApp(ui = app, server = server)}).
#' @param port See \code{\link[=shiny]{runApp}}.
#' @param viewer Specify where the gadget should be displayed--viewer pane,
#' dialog window, or external browser--by passing in a call to one of the
#' [viewer()] functions.
#' @param stopOnCancel If `TRUE` (the default), then an `observeEvent`
#' is automatically created that handles `input$cancel` by calling
#' `stopApp()` with an error. Pass `FALSE` if you want to handle
#' `input$cancel` yourself.
#' \code{\link{viewer}} functions.
#' @param stopOnCancel If \code{TRUE} (the default), then an \code{observeEvent}
#' is automatically created that handles \code{input$cancel} by calling
#' \code{stopApp()} with an error. Pass \code{FALSE} if you want to handle
#' \code{input$cancel} yourself.
#' @return The value returned by the gadget.
#'
#' @examples
@@ -1060,10 +1003,10 @@ decorateServerFunc <- function(appobj, serverFunc) {
#' other R environments that emulate RStudio's viewer pane/dialog APIs). If
#' viewer APIs are not available in the current R environment, then the gadget
#' will be displayed in the system's default web browser (see
#' [utils::browseURL()]).
#' \code{\link[utils]{browseURL}}).
#'
#' @return A function that takes a single `url` parameter, suitable for
#' passing as the `viewer` argument of [runGadget()].
#' @return A function that takes a single \code{url} parameter, suitable for
#' passing as the \code{viewer} argument of \code{\link{runGadget}}.
#'
#' @rdname viewer
#' @name viewer
@@ -1071,8 +1014,8 @@ NULL
#' @param minHeight The minimum height (in pixels) desired to show the gadget in
#' the viewer pane. If a positive number, resize the pane if necessary to show
#' at least that many pixels. If `NULL`, use the existing viewer pane
#' size. If `"maximize"`, use the maximum available vertical space.
#' at least that many pixels. If \code{NULL}, use the existing viewer pane
#' size. If \code{"maximize"}, use the maximum available vertical space.
#' @rdname viewer
#' @export
paneViewer <- function(minHeight = NULL) {
@@ -1101,7 +1044,7 @@ dialogViewer <- function(dialogName, width = 600, height = 600) {
}
}
#' @param browser See [utils::browseURL()].
#' @param browser See \code{\link[utils]{browseURL}}.
#' @rdname viewer
#' @export
browserViewer <- function(browser = getOption("browser")) {

View File

@@ -16,19 +16,19 @@ getShinyOption <- function(name, default = NULL) {
#' Get or set Shiny options
#'
#' `getShinyOption` retrieves the value of a Shiny option.
#' `shinyOptions` sets the value of Shiny options; it can also be used to
#' \code{getShinyOption} retrieves the value of a Shiny option.
#' \code{shinyOptions} sets the value of Shiny options; it can also be used to
#' return a list of all currently-set Shiny options.
#'
#' There is a global option set, which is available by default. When a Shiny
#' application is run with [runApp()], that option set is duplicated
#' application is run with \code{\link{runApp}}, that option set is duplicated
#' and the new option set is available for getting or setting values. If options
#' are set from global.R, app.R, ui.R, or server.R, or if they are set from
#' inside the server function, then the options will be scoped to the
#' application. When the application exits, the new option set is discarded and
#' the global option set is restored.
#'
#' @param ... Options to set, with the form `name = value`.
#' @param ... Options to set, with the form \code{name = value}.
#'
#' @examples
#' \dontrun{

279
R/shiny.R
View File

@@ -8,11 +8,11 @@ NULL
#' prebuilt widgets make it possible to build beautiful, responsive, and
#' powerful applications with minimal effort.
#'
#' The Shiny tutorial at <http://shiny.rstudio.com/tutorial/> explains
#' The Shiny tutorial at \url{http://shiny.rstudio.com/tutorial/} explains
#' the framework in depth, walks you through building a simple application, and
#' includes extensive annotated examples.
#'
#' @seealso [shiny-options] for documentation about global options.
#' @seealso \link{shiny-options} for documentation about global options.
#'
#' @name shiny-package
#' @aliases shiny
@@ -32,20 +32,20 @@ NULL
#' Global options for Shiny
#'
#' There are a number of global options that affect Shiny's behavior. These can
#' be set with (for example) `options(shiny.trace=TRUE)`.
#' be set with (for example) \code{options(shiny.trace=TRUE)}.
#'
#' \describe{
#' \item{shiny.launch.browser}{A boolean which controls the default behavior
#' when an app is run. See [runApp()] for more information.}
#' when an app is run. See \code{\link{runApp}} for more information.}
#' \item{shiny.port}{A port number that Shiny will listen on. See
#' [runApp()] for more information.}
#' \code{\link{runApp}} for more information.}
#' \item{shiny.trace}{Print messages sent between the R server and the web
#' browser client to the R console. This is useful for debugging. Possible
#' values are `"send"` (only print messages sent to the client),
#' `"recv"` (only print messages received by the server), `TRUE`
#' (print all messages), or `FALSE` (default; don't print any of these
#' values are \code{"send"} (only print messages sent to the client),
#' \code{"recv"} (only print messages received by the server), \code{TRUE}
#' (print all messages), or \code{FALSE} (default; don't print any of these
#' messages).}
#' \item{shiny.autoreload}{If `TRUE` when a Shiny app is launched, the
#' \item{shiny.autoreload}{If \code{TRUE} when a Shiny app is launched, the
#' app directory will be continually monitored for changes to files that
#' have the extensions: r, htm, html, js, css, png, jpg, jpeg, gif. If any
#' changes are detected, all connected Shiny sessions are reloaded. This
@@ -56,59 +56,59 @@ NULL
#'
#' You can customize the file patterns Shiny will monitor by setting the
#' shiny.autoreload.pattern option. For example, to monitor only ui.R:
#' `options(shiny.autoreload.pattern = glob2rx("ui.R"))`
#' \code{options(shiny.autoreload.pattern = glob2rx("ui.R"))}
#'
#' The default polling interval is 500 milliseconds. You can change this
#' by setting e.g. `options(shiny.autoreload.interval = 2000)` (every
#' by setting e.g. \code{options(shiny.autoreload.interval = 2000)} (every
#' two seconds).}
#' \item{shiny.reactlog}{If `TRUE`, enable logging of reactive events,
#' which can be viewed later with the [reactlogShow()] function.
#' \item{shiny.reactlog}{If \code{TRUE}, enable logging of reactive events,
#' which can be viewed later with the \code{\link{showReactLog}} function.
#' This incurs a substantial performance penalty and should not be used in
#' production.}
#' \item{shiny.usecairo}{This is used to disable graphical rendering by the
#' Cairo package, if it is installed. See [plotPNG()] for more
#' Cairo package, if it is installed. See \code{\link{plotPNG}} for more
#' information.}
#' \item{shiny.maxRequestSize}{This is a number which specifies the maximum
#' web request size, which serves as a size limit for file uploads. If
#' unset, the maximum request size defaults to 5MB.}
#' \item{shiny.suppressMissingContextError}{Normally, invoking a reactive
#' outside of a reactive context (or [isolate()]) results in
#' an error. If this is `TRUE`, don't error in these cases. This
#' outside of a reactive context (or \code{\link{isolate}()}) results in
#' an error. If this is \code{TRUE}, don't error in these cases. This
#' should only be used for debugging or demonstrations of reactivity at the
#' console.}
#' \item{shiny.host}{The IP address that Shiny should listen on. See
#' [runApp()] for more information.}
#' \code{\link{runApp}} for more information.}
#' \item{shiny.json.digits}{The number of digits to use when converting
#' numbers to JSON format to send to the client web browser.}
#' \item{shiny.minified}{If this is `TRUE` or unset (the default), then
#' Shiny will use minified JavaScript (`shiny.min.js`). If
#' `FALSE`, then Shiny will use the un-minified JavaScript
#' (`shiny.js`); this can be useful during development.}
#' \item{shiny.minified}{If this is \code{TRUE} or unset (the default), then
#' Shiny will use minified JavaScript (\code{shiny.min.js}). If
#' \code{FALSE}, then Shiny will use the un-minified JavaScript
#' (\code{shiny.js}); this can be useful during development.}
#' \item{shiny.error}{This can be a function which is called when an error
#' occurs. For example, `options(shiny.error=recover)` will result a
#' occurs. For example, \code{options(shiny.error=recover)} will result a
#' the debugger prompt when an error occurs.}
#' \item{shiny.table.class}{CSS class names to use for tables.}
#' \item{shiny.deprecation.messages}{This controls whether messages for
#' deprecated functions in Shiny will be printed. See
#' [shinyDeprecated()] for more information.}
#' \code{\link{shinyDeprecated}} for more information.}
#' \item{shiny.fullstacktrace}{Controls whether "pretty" or full stack traces
#' are dumped to the console when errors occur during Shiny app execution.
#' The default is `FALSE` (pretty stack traces).}
#' \item{shiny.stacktraceoffset}{If `TRUE`, then Shiny's printed stack
#' The default is \code{FALSE} (pretty stack traces).}
#' \item{shiny.stacktraceoffset}{If \code{TRUE}, then Shiny's printed stack
#' traces will display srcrefs one line above their usual location. This is
#' an arguably more intuitive arrangement for casual R users, as the name
#' of a function appears next to the srcref where it is defined, rather than
#' where it is currently being called from.}
#' \item{shiny.sanitize.errors}{If `TRUE`, then normal errors (i.e.
#' errors not wrapped in `safeError`) won't show up in the app; a simple
#' \item{shiny.sanitize.errors}{If \code{TRUE}, then normal errors (i.e.
#' errors not wrapped in \code{safeError}) won't show up in the app; a simple
#' generic error message is printed instead (the error and strack trace printed
#' to the console remain unchanged). The default is `FALSE` (unsanitized
#' to the console remain unchanged). The default is \code{FALSE} (unsanitized
#' errors).If you want to sanitize errors in general, but you DO want a
#' particular error `e` to get displayed to the user, then set this option
#' to `TRUE` and use `stop(safeError(e))` for errors you want the
#' particular error \code{e} to get displayed to the user, then set this option
#' to \code{TRUE} and use \code{stop(safeError(e))} for errors you want the
#' user to see.}
#' \item{shiny.testmode}{If `TRUE`, then enable features for testing Shiny
#' applications. If `FALSE` (the default), do not enable those features.
#' \item{shiny.testmode}{If \code{TRUE}, then enable features for testing Shiny
#' applications. If \code{FALSE} (the default), do not enable those features.
#' }
#' }
#' @name shiny-options
@@ -179,78 +179,78 @@ workerId <- local({
#' Session object
#'
#' Shiny server functions can optionally include `session` as a parameter
#' (e.g. `function(input, output, session)`). The session object is an
#' Shiny server functions can optionally include \code{session} as a parameter
#' (e.g. \code{function(input, output, session)}). The session object is an
#' environment that can be used to access information and functionality
#' relating to the session. The following list describes the items available
#' in the environment; they can be accessed using the `$` operator (for
#' example, `session$clientData$url_search`).
#' in the environment; they can be accessed using the \code{$} operator (for
#' example, \code{session$clientData$url_search}).
#'
#' @return
#' \item{allowReconnect(value)}{
#' If `value` is `TRUE` and run in a hosting environment (Shiny
#' If \code{value} is \code{TRUE} and run in a hosting environment (Shiny
#' Server or Connect) with reconnections enabled, then when the session ends
#' due to the network connection closing, the client will attempt to
#' reconnect to the server. If a reconnection is successful, the browser will
#' send all the current input values to the new session on the server, and
#' the server will recalculate any outputs and send them back to the client.
#' If `value` is `FALSE`, reconnections will be disabled (this is
#' the default state). If `"force"`, then the client browser will always
#' attempt to reconnect. The only reason to use `"force"` is for testing
#' If \code{value} is \code{FALSE}, reconnections will be disabled (this is
#' the default state). If \code{"force"}, then the client browser will always
#' attempt to reconnect. The only reason to use \code{"force"} is for testing
#' on a local connection (without Shiny Server or Connect).
#' }
#' \item{clientData}{
#' A [reactiveValues()] object that contains information about the client.
#' A \code{\link{reactiveValues}} object that contains information about the client.
#' \itemize{
#' \item{`allowDataUriScheme` is a logical value that indicates whether
#' the browser is able to handle URIs that use the `data:` scheme.
#' \item{\code{allowDataUriScheme} is a logical value that indicates whether
#' the browser is able to handle URIs that use the \code{data:} scheme.
#' }
#' \item{`pixelratio` reports the "device pixel ratio" from the web browser,
#' \item{\code{pixelratio} reports the "device pixel ratio" from the web browser,
#' or 1 if none is reported. The value is 2 for Apple Retina displays.
#' }
#' \item{`singletons` - for internal use}
#' \item{`url_protocol`, `url_hostname`, `url_port`,
#' `url_pathname`, `url_search`, `url_hash_initial`
#' and `url_hash` can be used to get the components of the URL
#' \item{\code{singletons} - for internal use}
#' \item{\code{url_protocol}, \code{url_hostname}, \code{url_port},
#' \code{url_pathname}, \code{url_search}, \code{url_hash_initial}
#' and \code{url_hash} can be used to get the components of the URL
#' that was requested by the browser to load the Shiny app page.
#' These values are from the browser's perspective, so neither HTTP
#' proxies nor Shiny Server will affect these values. The
#' `url_search` value may be used with [parseQueryString()]
#' \code{url_search} value may be used with \code{\link{parseQueryString}}
#' to access query string parameters.
#' }
#' }
#' `clientData` also contains information about each output.
#' \code{clientData} also contains information about each output.
#' \code{output_\var{outputId}_width} and \code{output_\var{outputId}_height}
#' give the dimensions (using `offsetWidth` and `offsetHeight`) of
#' give the dimensions (using \code{offsetWidth} and \code{offsetHeight}) of
#' the DOM element that is bound to \code{\var{outputId}}, and
#' \code{output_\var{outputId}_hidden} is a logical that indicates whether
#' the element is hidden. These values may be `NULL` if the output is
#' the element is hidden. These values may be \code{NULL} if the output is
#' not bound.
#' }
#' \item{input}{
#' The session's `input` object (the same as is passed into the Shiny
#' The session's \code{input} object (the same as is passed into the Shiny
#' server function as an argument).
#' }
#' \item{isClosed()}{A function that returns `TRUE` if the client has
#' \item{isClosed()}{A function that returns \code{TRUE} if the client has
#' disconnected.
#' }
#' \item{ns(id)}{
#' Server-side version of [`ns <- NS(id)`][NS]. If bare IDs need to be
#' explicitly namespaced for the current module, `session$ns("name")`
#' Server-side version of \code{ns <- \link{NS}(id)}. If bare IDs need to be
#' explicitly namespaced for the current module, \code{session$ns("name")}
#' will return the fully-qualified ID.
#' }
#' \item{onEnded(callback)}{
#' Synonym for `onSessionEnded`.
#' Synonym for \code{onSessionEnded}.
#' }
#' \item{onFlush(func, once=TRUE)}{
#' Registers a function to be called before the next time (if `once=TRUE`)
#' or every time (if `once=FALSE`) Shiny flushes the reactive system.
#' Registers a function to be called before the next time (if \code{once=TRUE})
#' or every time (if \code{once=FALSE}) Shiny flushes the reactive system.
#' Returns a function that can be called with no arguments to cancel the
#' registration.
#' }
#' \item{onFlushed(func, once=TRUE)}{
#' Registers a function to be called after the next time (if `once=TRUE`)
#' or every time (if `once=FALSE`) Shiny flushes the reactive system.
#' Registers a function to be called after the next time (if \code{once=TRUE})
#' or every time (if \code{once=FALSE}) Shiny flushes the reactive system.
#' Returns a function that can be called with no arguments to cancel the
#' registration.
#' }
@@ -260,7 +260,7 @@ workerId <- local({
#' registration.
#' }
#' \item{output}{
#' The session's `output` object (the same as is passed into the Shiny
#' The session's \code{output} object (the same as is passed into the Shiny
#' server function as an argument).
#' }
#' \item{reactlog}{
@@ -268,13 +268,13 @@ workerId <- local({
#' }
#' \item{registerDataObj(name, data, filterFunc)}{
#' Publishes any R object as a URL endpoint that is unique to this session.
#' `name` must be a single element character vector; it will be used
#' to form part of the URL. `filterFunc` must be a function that takes
#' two arguments: `data` (the value that was passed into
#' `registerDataObj`) and `req` (an environment that implements
#' the Rook specification for HTTP requests). `filterFunc` will be
#' \code{name} must be a single element character vector; it will be used
#' to form part of the URL. \code{filterFunc} must be a function that takes
#' two arguments: \code{data} (the value that was passed into
#' \code{registerDataObj}) and \code{req} (an environment that implements
#' the Rook specification for HTTP requests). \code{filterFunc} will be
#' called with these values whenever an HTTP request is made to the URL
#' endpoint. The return value of `filterFunc` should be a Rook-style
#' endpoint. The return value of \code{filterFunc} should be a Rook-style
#' response.
#' }
#' \item{reload()}{
@@ -291,35 +291,35 @@ workerId <- local({
#' session-specific data they want.
#' }
#' \item{resetBrush(brushId)}{
#' Resets/clears the brush with the given `brushId`, if it exists on
#' any `imageOutput` or `plotOutput` in the app.
#' Resets/clears the brush with the given \code{brushId}, if it exists on
#' any \code{imageOutput} or \code{plotOutput} in the app.
#' }
#' \item{sendCustomMessage(type, message)}{
#' Sends a custom message to the web page. `type` must be a
#' Sends a custom message to the web page. \code{type} must be a
#' single-element character vector giving the type of message, while
#' `message` can be any jsonlite-encodable value. Custom messages
#' \code{message} can be any jsonlite-encodable value. Custom messages
#' have no meaning to Shiny itself; they are used soley to convey information
#' to custom JavaScript logic in the browser. You can do this by adding
#' JavaScript code to the browser that calls
#' \code{Shiny.addCustomMessageHandler(type, function(message){...})}
#' as the page loads; the function you provide to
#' `addCustomMessageHandler` will be invoked each time
#' `sendCustomMessage` is called on the server.
#' \code{addCustomMessageHandler} will be invoked each time
#' \code{sendCustomMessage} is called on the server.
#' }
#' \item{sendBinaryMessage(type, message)}{
#' Similar to `sendCustomMessage`, but the message must be a raw vector
#' Similar to \code{sendCustomMessage}, but the message must be a raw vector
#' and the registration method on the client is
#' \code{Shiny.addBinaryMessageHandler(type, function(message){...})}. The
#' message argument on the client will be a
#' [DataView](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView).
#' \href{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView}{DataView}.
#' }
#' \item{sendInputMessage(inputId, message)}{
#' Sends a message to an input on the session's client web page; if the input
#' is present and bound on the page at the time the message is received, then
#' the input binding object's `receiveMessage(el, message)` method will
#' be called. `sendInputMessage` should generally not be called directly
#' the input binding object's \code{receiveMessage(el, message)} method will
#' be called. \code{sendInputMessage} should generally not be called directly
#' from Shiny apps, but through friendlier wrapper functions like
#' [updateTextInput()].
#' \code{\link{updateTextInput}}.
#' }
#' \item{setBookmarkExclude(names)}{
#' Set input names to be excluded from bookmarking.
@@ -351,10 +351,10 @@ workerId <- local({
#' \item{getTestSnapshotUrl(input=TRUE, output=TRUE, export=TRUE,
#' format="json")}{
#' Returns a URL for the test snapshots. Only has an effect when the
#' `shiny.testmode` option is set to TRUE. For the input, output, and
#' \code{shiny.testmode} option is set to TRUE. For the input, output, and
#' export arguments, TRUE means to return all of these values. It is also
#' possible to specify by name which values to return by providing a
#' character vector, as in `input=c("x", "y")`. The format can be
#' character vector, as in \code{input=c("x", "y")}. The format can be
#' "rds" or "json".
#' }
#'
@@ -363,26 +363,26 @@ NULL
#' Namespaced IDs for inputs/outputs
#'
#' The `NS` function creates namespaced IDs out of bare IDs, by joining
#' them using `ns.sep` as the delimiter. It is intended for use in Shiny
#' modules. See <http://shiny.rstudio.com/articles/modules.html>.
#' The \code{NS} function creates namespaced IDs out of bare IDs, by joining
#' them using \code{ns.sep} as the delimiter. It is intended for use in Shiny
#' modules. See \url{http://shiny.rstudio.com/articles/modules.html}.
#'
#' Shiny applications use IDs to identify inputs and outputs. These IDs must be
#' unique within an application, as accidentally using the same input/output ID
#' more than once will result in unexpected behavior. The traditional solution
#' for preventing name collisions is *namespaces*; a namespace is to an ID
#' as a directory is to a file. Use the `NS` function to turn a bare ID
#' into a namespaced one, by combining them with `ns.sep` in between.
#' for preventing name collisions is \emph{namespaces}; a namespace is to an ID
#' as a directory is to a file. Use the \code{NS} function to turn a bare ID
#' into a namespaced one, by combining them with \code{ns.sep} in between.
#'
#' @param namespace The character vector to use for the namespace. This can have
#' any length, though a single element is most common. Length 0 will cause the
#' `id` to be returned without a namespace, and length 2 will be
#' \code{id} to be returned without a namespace, and length 2 will be
#' interpreted as multiple namespaces, in increasing order of specificity
#' (i.e. starting with the top-level namespace).
#' @param id The id string to be namespaced (optional).
#' @return If `id` is missing, returns a function that expects an id string
#' @return If \code{id} is missing, returns a function that expects an id string
#' as its only argument and returns that id with the namespace prepended.
#' @seealso <http://shiny.rstudio.com/articles/modules.html>
#' @seealso \url{http://shiny.rstudio.com/articles/modules.html}
#' @export
NS <- function(namespace, id = NULL) {
if (length(namespace) == 0)
@@ -513,7 +513,8 @@ ShinySession <- R6Class(
# in the web page; in these cases, there's no output_foo_hidden flag,
# and hidden should be TRUE. In other words, NULL and TRUE should map to
# TRUE, FALSE should map to FALSE.
hidden <- private$.clientData$.values$get(paste0("output_", name, "_hidden"))
hidden <- private$.clientData$.values[[paste("output_", name, "_hidden",
sep="")]]
if (is.null(hidden)) hidden <- TRUE
return(hidden && private$getOutputOption(name, 'suspendWhenHidden', TRUE))
@@ -575,7 +576,7 @@ ShinySession <- R6Class(
# Apply preprocessor functions for inputs that have them.
values$input <- lapply(
stats::setNames(names(values$input), names(values$input)),
setNames(names(values$input), names(values$input)),
function(name) {
preprocess <- private$getSnapshotPreprocessInput(name)
preprocess(values$input[[name]])
@@ -603,7 +604,7 @@ ShinySession <- R6Class(
# Apply snapshotPreprocess functions for outputs that have them.
values$output <- lapply(
stats::setNames(names(values$output), names(values$output)),
setNames(names(values$output), names(values$output)),
function(name) {
preprocess <- private$getSnapshotPreprocessOutput(name)
preprocess(values$output[[name]])
@@ -639,7 +640,7 @@ ShinySession <- R6Class(
# that the resulting object is represented as an object in JSON
# instead of an array, and so that the RDS data structure is of a
# consistent type.
values <- lapply(values, asNamed)
values <- lapply(values, asNamedVector)
if (length(values) == 0) {
return(httpResponse(400, "text/plain",
@@ -682,42 +683,11 @@ ShinySession <- R6Class(
# See cycleStartAction
startCycle = function() {
# TODO: This should check for busyCount == 0L, and remove the checks from
# the call sites
if (length(private$cycleStartActionQueue) > 0) {
head <- private$cycleStartActionQueue[[1L]]
private$cycleStartActionQueue <- private$cycleStartActionQueue[-1L]
# After we execute the current cycleStartAction (head), there may be
# more items left on the queue. If the current busyCount > 0, then that
# means an async task is running; whenever that task finishes, it will
# decrement the busyCount back to 0 and a startCycle will then be
# scheduled. But if the current busyCount is 0, it means that either
# busyCount was incremented and then decremented; OR that running head()
# never touched busyCount (one example of the latter is that an input
# changed that didn't actually cause any observers to be invalidated,
# i.e. an input that's used in the body of an observeEvent). Because of
# the possibility of the latter case, we need to conditionally schedule
# a startCycle ourselves to ensure that the remaining queue items get
# processed.
#
# Since we can't actually tell whether head() increment and decremented
# busyCount, it's possible we're calling startCycle spuriously; that's
# OK, it's essentially a no-op in that case.
on.exit({
if (private$busyCount == 0L && length(private$cycleStartActionQueue) > 0L) {
later::later(function() {
if (private$busyCount == 0L) {
private$startCycle()
}
})
}
}, add = TRUE)
head()
}
invisible()
}
),
public = list(
@@ -749,8 +719,8 @@ ShinySession <- R6Class(
private$flushCallbacks <- Callbacks$new()
private$flushedCallbacks <- Callbacks$new()
private$inputReceivedCallbacks <- Callbacks$new()
private$.input <- ReactiveValues$new(dedupe = FALSE, label = "input")
private$.clientData <- ReactiveValues$new(dedupe = TRUE, label = "clientData")
private$.input <- ReactiveValues$new(dedupe = FALSE)
private$.clientData <- ReactiveValues$new(dedupe = TRUE)
private$timingRecorder <- ShinyServerTimingRecorder$new()
self$progressStack <- Stack$new()
self$files <- Map$new()
@@ -758,7 +728,9 @@ ShinySession <- R6Class(
self$userData <- new.env(parent = emptyenv())
self$input <- .createReactiveValues(private$.input, readonly=TRUE)
.setLabel(self$input, 'input')
self$clientData <- .createReactiveValues(private$.clientData, readonly=TRUE)
.setLabel(self$clientData, 'clientData')
self$output <- .createOutputWriter(self)
@@ -1087,9 +1059,6 @@ ShinySession <- R6Class(
# will be attached to the observer after it's created.
outputAttrs <- attr(func, "outputAttrs", TRUE)
# Save this for getOutput purposes
outputAttrs$renderFunc <- func
funcFormals <- formals(func)
# ..stacktraceon matches with the top-level ..stacktraceoff.., because
# the observer we set up below has ..stacktraceon=FALSE
@@ -1197,9 +1166,6 @@ ShinySession <- R6Class(
stop(paste("Unexpected", class(func), "output for", name))
}
},
getOutput = function(name) {
attr(private$.outputs[[name]], "renderFunc", exact = TRUE)
},
flushOutput = function() {
if (private$busyCount > 0)
return()
@@ -1209,11 +1175,6 @@ ShinySession <- R6Class(
if (self$isClosed())
return()
# This is the only place in the session where the restoreContext is
# flushed.
if (!is.null(self$restoreContext))
self$restoreContext$flushPending()
# Return TRUE if there's any stuff to send to the client.
hasPendingUpdates <- function() {
# Even though progressKeys isn't sent to the client, we use it in this
@@ -1922,7 +1883,7 @@ ShinySession <- R6Class(
fileData <- readBin(file, 'raw', n=bytes)
if (isTRUE(private$.clientData$.values$get("allowDataUriScheme"))) {
if (isTRUE(private$.clientData$.values$allowDataUriScheme)) {
b64 <- rawToBase64(fileData)
return(paste('data:', contentType, ';base64,', b64, sep=''))
} else {
@@ -2033,7 +1994,6 @@ ShinySession <- R6Class(
},
incrementBusyCount = function() {
if (private$busyCount == 0L) {
rLog$asyncStart(domain = self)
private$sendMessage(busy = "busy")
}
private$busyCount <- private$busyCount + 1L
@@ -2041,7 +2001,6 @@ ShinySession <- R6Class(
decrementBusyCount = function() {
private$busyCount <- private$busyCount - 1L
if (private$busyCount == 0L) {
rLog$asyncStop(domain = self)
private$sendMessage(busy = "idle")
self$requestFlush()
# We defer the call to startCycle() using later(), to defend against
@@ -2099,13 +2058,7 @@ ShinySession <- R6Class(
#' @export
`$.shinyoutput` <- function(x, name) {
name <- .subset2(x, 'ns')(name)
if (getOption("shiny.allowoutputreads", FALSE)) {
.subset2(x, 'impl')$getOutput(name)
} else {
stop("Reading from shinyoutput object is not allowed.")
}
stop("Reading objects from shinyoutput object not allowed.")
}
#' @export
@@ -2125,9 +2078,9 @@ ShinySession <- R6Class(
#'
#' These are the available options for an output object:
#' \itemize{
#' \item suspendWhenHidden. When `TRUE` (the default), the output object
#' \item suspendWhenHidden. When \code{TRUE} (the default), the output object
#' will be suspended (not execute) when it is hidden on the web page. When
#' `FALSE`, the output object will not suspend when hidden, and if it
#' \code{FALSE}, the output object will not suspend when hidden, and if it
#' was already hidden and suspended, then it will resume immediately.
#' \item priority. The priority level of the output object. Queued outputs
#' with higher priority values will execute before those with lower values.
@@ -2148,7 +2101,7 @@ ShinySession <- R6Class(
#' outputOptions(output, "myplot")
#' }
#'
#' @param x A shinyoutput object (typically `output`).
#' @param x A shinyoutput object (typically \code{output}).
#' @param name The name of an output observer in the shinyoutput object.
#' @param ... Options to set for the output observer.
#' @export
@@ -2179,9 +2132,9 @@ getCurrentOutputInfo <- function(session = getDefaultReactiveDomain()) {
#' Add callbacks for Shiny session events
#'
#' These functions are for registering callbacks on Shiny session events.
#' `onFlush` registers a function that will be called before Shiny flushes
#' the reactive system. `onFlushed` registers a function that will be
#' called after Shiny flushes the reactive system. `onSessionEnded`
#' \code{onFlush} registers a function that will be called before Shiny flushes
#' the reactive system. \code{onFlushed} registers a function that will be
#' called after Shiny flushes the reactive system. \code{onSessionEnded}
#' registers a function to be called after the client has disconnected.
#'
#' These functions should be called within the application's server function.
@@ -2191,8 +2144,8 @@ getCurrentOutputInfo <- function(session = getDefaultReactiveDomain()) {
#'
#' @param fun A callback function.
#' @param once Should the function be run once, and then cleared, or should it
#' re-run each time the event occurs. (Only for `onFlush` and
#' `onFlushed`.)
#' re-run each time the event occurs. (Only for \code{onFlush} and
#' \code{onFlushed}.)
#' @param session A shiny session object.
#'
#' @export
@@ -2208,7 +2161,7 @@ onFlushed <- function(fun, once = TRUE, session = getDefaultReactiveDomain()) {
#' @rdname onFlush
#'
#' @seealso [onStop()] for registering callbacks that will be
#' @seealso \code{\link{onStop}()} for registering callbacks that will be
#' invoked when the application exits, or when a session ends.
#' @export
onSessionEnded <- function(fun, session = getDefaultReactiveDomain()) {
@@ -2236,20 +2189,20 @@ flushPendingSessions <- function() {
#' Run code after an application or session ends
#'
#' This function registers callback functions that are invoked when the
#' application exits (when [runApp()] exits), or after each user
#' application exits (when \code{\link{runApp}} exits), or after each user
#' session ends (when a client disconnects).
#'
#' @param fun A function that will be called after the app has finished running.
#' @param session A scope for when the callback will run. If `onStop` is
#' @param session A scope for when the callback will run. If \code{onStop} is
#' called from within the server function, this will default to the current
#' session, and the callback will be invoked when the current session ends. If
#' `onStop` is called outside a server function, then the callback will
#' be invoked with the application exits. If `NULL`, it is the same as
#' calling `onStop` outside of the server function, and the callback will
#' \code{onStop} is called outside a server function, then the callback will
#' be invoked with the application exits. If \code{NULL}, it is the same as
#' calling \code{onStop} outside of the server function, and the callback will
#' be invoked when the application exits.
#'
#'
#' @seealso [onSessionEnded()] for the same functionality, but at
#' @seealso \code{\link{onSessionEnded}()} for the same functionality, but at
#' the session level only.
#'
#' @return A function which, if invoked, will cancel the callback.

View File

@@ -4,9 +4,9 @@ NULL
#' Load the MathJax library and typeset math expressions
#'
#' This function adds MathJax to the page and typeset the math expressions (if
#' found) in the content `...`. It only needs to be called once in an app
#' unless the content is rendered *after* the page is loaded, e.g. via
#' [renderUI()], in which case we have to call it explicitly every
#' found) in the content \code{...}. It only needs to be called once in an app
#' unless the content is rendered \emph{after} the page is loaded, e.g. via
#' \code{\link{renderUI}}, in which case we have to call it explicitly every
#' time we write math expressions to the output.
#' @param ... any HTML elements to apply MathJax to
#' @export
@@ -71,7 +71,6 @@ renderPage <- function(ui, connection, showcase=0, testMode=FALSE) {
#'
#' @param ui A user interace definition
#' @return The user interface definition, without modifications or side effects.
#' @keywords internal
#' @export
shinyUI <- function(ui) {
.globals$ui <- list(ui)

View File

@@ -2,7 +2,7 @@ utils::globalVariables('func')
#' Mark a function as a render function
#'
#' Should be called by implementers of `renderXXX` functions in order to
#' Should be called by implementers of \code{renderXXX} functions in order to
#' mark their return values as Shiny render functions, and to provide a hint to
#' Shiny regarding what UI function is most commonly used with this type of
#' render function. This can be used in R Markdown documents to create complete
@@ -12,13 +12,13 @@ utils::globalVariables('func')
#' an output ID.
#' @param renderFunc A function that is suitable for assigning to a Shiny output
#' slot.
#' @param outputArgs A list of arguments to pass to the `uiFunc`. Render
#' functions should include `outputArgs = list()` in their own parameter
#' list, and pass through the value to `markRenderFunction`, to allow
#' @param outputArgs A list of arguments to pass to the \code{uiFunc}. Render
#' functions should include \code{outputArgs = list()} in their own parameter
#' list, and pass through the value to \code{markRenderFunction}, to allow
#' app authors to customize outputs. (Currently, this is only supported for
#' dynamically generated UIs, such as those created by Shiny code snippets
#' embedded in R Markdown documents).
#' @return The `renderFunc` function, with annotations.
#' @return The \code{renderFunc} function, with annotations.
#' @export
markRenderFunction <- function(uiFunc, renderFunc, outputArgs = list()) {
# a mutable object that keeps track of whether `useRenderFunction` has been
@@ -57,22 +57,22 @@ markRenderFunction <- function(uiFunc, renderFunc, outputArgs = list()) {
#' @param func A function without parameters, that returns user data. If the
#' returned value is a promise, then the render function will proceed in async
#' mode.
#' @param transform A function that takes four arguments: `value`,
#' `session`, `name`, and `...` (for future-proofing). This
#' function will be invoked each time a value is returned from `func`,
#' @param transform A function that takes four arguments: \code{value},
#' \code{session}, \code{name}, and \code{...} (for future-proofing). This
#' function will be invoked each time a value is returned from \code{func},
#' and is responsible for changing the value into a JSON-ready value to be
#' JSON-encoded and sent to the browser.
#' @param outputFunc The UI function that is used (or most commonly used) with
#' this render function. This can be used in R Markdown documents to create
#' complete output widgets out of just the render function.
#' @param outputArgs A list of arguments to pass to the `outputFunc`.
#' Render functions should include `outputArgs = list()` in their own
#' @param outputArgs A list of arguments to pass to the \code{outputFunc}.
#' Render functions should include \code{outputArgs = list()} in their own
#' parameter list, and pass through the value as this argument, to allow app
#' authors to customize outputs. (Currently, this is only supported for
#' dynamically generated UIs, such as those created by Shiny code snippets
#' embedded in R Markdown documents).
#' @return An annotated render function, ready to be assigned to an
#' `output` slot.
#' \code{output} slot.
#'
#' @export
createRenderFunction <- function(
@@ -165,37 +165,37 @@ markOutputAttrs <- function(renderFunc, snapshotExclude = NULL,
#' Image file output
#'
#' Renders a reactive image that is suitable for assigning to an `output`
#' Renders a reactive image that is suitable for assigning to an \code{output}
#' slot.
#'
#' The expression `expr` must return a list containing the attributes for
#' the `img` object on the client web page. For the image to display,
#' properly, the list must have at least one entry, `src`, which is the
#' path to the image file. It may also useful to have a `contentType`
#' The expression \code{expr} must return a list containing the attributes for
#' the \code{img} object on the client web page. For the image to display,
#' properly, the list must have at least one entry, \code{src}, which is the
#' path to the image file. It may also useful to have a \code{contentType}
#' entry specifying the MIME type of the image. If one is not provided,
#' `renderImage` will try to autodetect the type, based on the file
#' \code{renderImage} will try to autodetect the type, based on the file
#' extension.
#'
#' Other elements such as `width`, `height`, `class`, and
#' `alt`, can also be added to the list, and they will be used as
#' attributes in the `img` object.
#' Other elements such as \code{width}, \code{height}, \code{class}, and
#' \code{alt}, can also be added to the list, and they will be used as
#' attributes in the \code{img} object.
#'
#' The corresponding HTML output tag should be `div` or `img` and have
#' the CSS class name `shiny-image-output`.
#' The corresponding HTML output tag should be \code{div} or \code{img} and have
#' the CSS class name \code{shiny-image-output}.
#'
#' @seealso For more details on how the images are generated, and how to control
#' the output, see [plotPNG()].
#' the output, see \code{\link{plotPNG}}.
#'
#' @param expr An expression that returns a list.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' is useful if you want to save an expression in a variable.
#' @param deleteFile Should the file in `func()$src` be deleted after
#' @param deleteFile Should the file in \code{func()$src} be deleted after
#' it is sent to the client browser? Generally speaking, if the image is a
#' temp file generated within `func`, then this should be `TRUE`;
#' if the image is not a temp file, this should be `FALSE`.
#' temp file generated within \code{func}, then this should be \code{TRUE};
#' if the image is not a temp file, this should be \code{FALSE}.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [imageOutput()] when `renderImage` is used in an
#' call to \code{\link{imageOutput}} when \code{renderImage} is used in an
#' interactive R Markdown document.
#' @export
#'
@@ -295,30 +295,30 @@ renderImage <- function(expr, env=parent.frame(), quoted=FALSE,
#'
#' Makes a reactive version of the given function that captures any printed
#' output, and also captures its printable result (unless
#' [base::invisible()]), into a string. The resulting function is suitable
#' for assigning to an `output` slot.
#' \code{\link[base]{invisible}}), into a string. The resulting function is suitable
#' for assigning to an \code{output} slot.
#'
#' The corresponding HTML output tag can be anything (though `pre` is
#' The corresponding HTML output tag can be anything (though \code{pre} is
#' recommended if you need a monospace font and whitespace preserved) and should
#' have the CSS class name `shiny-text-output`.
#' have the CSS class name \code{shiny-text-output}.
#'
#' The result of executing `func` will be printed inside a
#' [utils::capture.output()] call.
#' The result of executing \code{func} will be printed inside a
#' \code{\link[utils]{capture.output}} call.
#'
#' Note that unlike most other Shiny output functions, if the given function
#' returns `NULL` then `NULL` will actually be visible in the output.
#' To display nothing, make your function return [base::invisible()].
#' returns \code{NULL} then \code{NULL} will actually be visible in the output.
#' To display nothing, make your function return \code{\link[base]{invisible}()}.
#'
#' @param expr An expression that may print output and/or return a printable R
#' object.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' is useful if you want to save an expression in a variable.
#' @param width The value for `[options][base::options]('width')`.
#' @param width The value for \code{\link[base]{options}('width')}.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [verbatimTextOutput()] when `renderPrint` is used
#' call to \code{\link{verbatimTextOutput}} when \code{renderPrint} is used
#' in an interactive R Markdown document.
#' @seealso [renderText()] for displaying the value returned from a
#' @seealso \code{\link{renderText}} for displaying the value returned from a
#' function, instead of the printed output.
#'
#' @example res/text-example.R
@@ -398,40 +398,38 @@ createRenderPrintPromiseDomain <- function(width) {
#' Text Output
#'
#' Makes a reactive version of the given function that also uses
#' [base::cat()] to turn its result into a single-element character
#' \code{\link[base]{cat}} to turn its result into a single-element character
#' vector.
#'
#' The corresponding HTML output tag can be anything (though `pre` is
#' The corresponding HTML output tag can be anything (though \code{pre} is
#' recommended if you need a monospace font and whitespace preserved) and should
#' have the CSS class name `shiny-text-output`.
#' have the CSS class name \code{shiny-text-output}.
#'
#' The result of executing `func` will passed to `cat`, inside a
#' [utils::capture.output()] call.
#' The result of executing \code{func} will passed to \code{cat}, inside a
#' \code{\link[utils]{capture.output}} call.
#'
#' @param expr An expression that returns an R object that can be used as an
#' argument to `cat`.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' argument to \code{cat}.
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' is useful if you want to save an expression in a variable.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [textOutput()] when `renderText` is used in an
#' call to \code{\link{textOutput}} when \code{renderText} is used in an
#' interactive R Markdown document.
#' @param sep A separator passed to `cat` to be appended after each
#' element.
#'
#' @seealso [renderPrint()] for capturing the print output of a
#' @seealso \code{\link{renderPrint}} for capturing the print output of a
#' function, rather than the returned text value.
#'
#' @example res/text-example.R
#' @export
renderText <- function(expr, env=parent.frame(), quoted=FALSE,
outputArgs=list(), sep=" ") {
outputArgs=list()) {
installExprFunction(expr, "func", env, quoted)
createRenderFunction(
func,
function(value, session, name, ...) {
paste(utils::capture.output(cat(value, sep=sep)), collapse="\n")
paste(utils::capture.output(cat(value)), collapse="\n")
},
textOutput, outputArgs
)
@@ -441,19 +439,19 @@ renderText <- function(expr, env=parent.frame(), quoted=FALSE,
#'
#' Renders reactive HTML using the Shiny UI library.
#'
#' The corresponding HTML output tag should be `div` and have the CSS class
#' name `shiny-html-output` (or use [uiOutput()]).
#' The corresponding HTML output tag should be \code{div} and have the CSS class
#' name \code{shiny-html-output} (or use \code{\link{uiOutput}}).
#'
#' @param expr An expression that returns a Shiny tag object, [HTML()],
#' @param expr An expression that returns a Shiny tag object, \code{\link{HTML}},
#' or a list of such objects.
#' @param env The environment in which to evaluate `expr`.
#' @param quoted Is `expr` a quoted expression (with `quote()`)? This
#' @param env The environment in which to evaluate \code{expr}.
#' @param quoted Is \code{expr} a quoted expression (with \code{quote()})? This
#' is useful if you want to save an expression in a variable.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [uiOutput()] when `renderUI` is used in an
#' call to \code{\link{uiOutput}} when \code{renderUI} is used in an
#' interactive R Markdown document.
#'
#' @seealso [uiOutput()]
#' @seealso \code{\link{uiOutput}}
#' @export
#' @examples
#' ## Only run examples in interactive R sessions
@@ -496,25 +494,25 @@ renderUI <- function(expr, env=parent.frame(), quoted=FALSE,
#' file downloads (for example, downloading the currently visible data as a CSV
#' file). Both filename and contents can be calculated dynamically at the time
#' the user initiates the download. Assign the return value to a slot on
#' `output` in your server function, and in the UI use
#' [downloadButton()] or [downloadLink()] to make the
#' \code{output} in your server function, and in the UI use
#' \code{\link{downloadButton}} or \code{\link{downloadLink}} to make the
#' download available.
#'
#' @param filename A string of the filename, including extension, that the
#' user's web browser should default to when downloading the file; or a
#' function that returns such a string. (Reactive values and functions may be
#' used from this function.)
#' @param content A function that takes a single argument `file` that is a
#' @param content A function that takes a single argument \code{file} that is a
#' file path (string) of a nonexistent temp file, and writes the content to
#' that file path. (Reactive values and functions may be used from this
#' function.)
#' @param contentType A string of the download's
#' [content type](http://en.wikipedia.org/wiki/Internet_media_type), for
#' example `"text/csv"` or `"image/png"`. If `NULL` or
#' `NA`, the content type will be guessed based on the filename
#' extension, or `application/octet-stream` if the extension is unknown.
#' \href{http://en.wikipedia.org/wiki/Internet_media_type}{content type}, for
#' example \code{"text/csv"} or \code{"image/png"}. If \code{NULL} or
#' \code{NA}, the content type will be guessed based on the filename
#' extension, or \code{application/octet-stream} if the extension is unknown.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [downloadButton()] when `downloadHandler` is used
#' call to \code{\link{downloadButton}} when \code{downloadHandler} is used
#' in an interactive R Markdown document.
#'
#' @examples
@@ -558,12 +556,12 @@ downloadHandler <- function(filename, content, contentType=NA, outputArgs=list()
#' searching, filtering, and sorting can be done on the R side using Shiny as
#' the server infrastructure.
#'
#' For the `options` argument, the character elements that have the class
#' `"AsIs"` (usually returned from [base::I()]) will be evaluated in
#' For the \code{options} argument, the character elements that have the class
#' \code{"AsIs"} (usually returned from \code{\link[base]{I}()}) will be evaluated in
#' JavaScript. This is useful when the type of the option value is not supported
#' in JSON, e.g., a JavaScript function, which can be obtained by evaluating a
#' character string. Note this only applies to the root-level elements of the
#' options list, and the `I()` notation does not work for lower-level
#' options list, and the \code{I()} notation does not work for lower-level
#' elements in the list.
#' @param expr An expression that returns a data frame or a matrix.
#' @param options A list of initialization options to be passed to DataTables,
@@ -572,25 +570,25 @@ downloadHandler <- function(filename, content, contentType=NA, outputArgs=list()
#' frequent search requests).
#' @param callback A JavaScript function to be applied to the DataTable object.
#' This is useful for DataTables plug-ins, which often require the DataTable
#' instance to be available (<http://datatables.net/extensions/>).
#' @param escape Whether to escape HTML entities in the table: `TRUE` means
#' to escape the whole table, and `FALSE` means not to escape it.
#' instance to be available (\url{http://datatables.net/extensions/}).
#' @param escape Whether to escape HTML entities in the table: \code{TRUE} means
#' to escape the whole table, and \code{FALSE} means not to escape it.
#' Alternatively, you can specify numeric column indices or column names to
#' indicate which columns to escape, e.g. `1:5` (the first 5 columns),
#' `c(1, 3, 4)`, or `c(-1, -3)` (all columns except the first and
#' third), or `c('Species', 'Sepal.Length')`.
#' indicate which columns to escape, e.g. \code{1:5} (the first 5 columns),
#' \code{c(1, 3, 4)}, or \code{c(-1, -3)} (all columns except the first and
#' third), or \code{c('Species', 'Sepal.Length')}.
#' @param outputArgs A list of arguments to be passed through to the implicit
#' call to [dataTableOutput()] when `renderDataTable` is used
#' call to \code{\link{dataTableOutput}} when \code{renderDataTable} is used
#' in an interactive R Markdown document.
#'
#' @references <http://datatables.net>
#' @references \url{http://datatables.net}
#' @note This function only provides the server-side version of DataTables
#' (using R to process the data object on the server side). There is a
#' separate package \pkg{DT} (<https://github.com/rstudio/DT>) that allows
#' separate package \pkg{DT} (\url{https://github.com/rstudio/DT}) that allows
#' you to create both server-side and client-side DataTables, and supports
#' additional DataTables features. Consider using `DT::renderDataTable()`
#' and `DT::dataTableOutput()` (see
#' <http://rstudio.github.io/DT/shiny.html> for more information).
#' additional DataTables features. Consider using \code{DT::renderDataTable()}
#' and \code{DT::dataTableOutput()} (see
#' \url{http://rstudio.github.io/DT/shiny.html} for more information).
#' @export
#' @inheritParams renderPlot
#' @examples
@@ -709,19 +707,13 @@ checkDT9 <- function(options) {
# Deprecated functions ------------------------------------------------------
#' Deprecated reactive functions
#' @name deprecatedReactives
#' @keywords internal
NULL
#' Plot output (deprecated)
#'
#' `reactivePlot` has been replaced by [renderPlot()].
#' See \code{\link{renderPlot}}.
#' @param func A function.
#' @param width Width.
#' @param height Height.
#' @param ... Other arguments to pass on.
#' @rdname deprecatedReactives
#' @export
reactivePlot <- function(func, width='auto', height='auto', ...) {
shinyDeprecated(new="renderPlot")
@@ -730,8 +722,9 @@ reactivePlot <- function(func, width='auto', height='auto', ...) {
#' Table output (deprecated)
#'
#' `reactiveTable` has been replaced by [renderTable()].
#' @rdname deprecatedReactives
#' See \code{\link{renderTable}}.
#' @param func A function.
#' @param ... Other arguments to pass on.
#' @export
reactiveTable <- function(func, ...) {
shinyDeprecated(new="renderTable")
@@ -740,8 +733,8 @@ reactiveTable <- function(func, ...) {
#' Print output (deprecated)
#'
#' `reactivePrint` has been replaced by [renderPrint()].
#' @rdname deprecatedReactives
#' See \code{\link{renderPrint}}.
#' @param func A function.
#' @export
reactivePrint <- function(func) {
shinyDeprecated(new="renderPrint")
@@ -750,8 +743,8 @@ reactivePrint <- function(func) {
#' UI output (deprecated)
#'
#' `reactiveUI` has been replaced by [renderUI()].
#' @rdname deprecatedReactives
#' See \code{\link{renderUI}}.
#' @param func A function.
#' @export
reactiveUI <- function(func) {
shinyDeprecated(new="renderUI")
@@ -760,8 +753,8 @@ reactiveUI <- function(func) {
#' Text output (deprecated)
#'
#' `reactiveText` has been replaced by [renderText()].
#' @rdname deprecatedReactives
#' See \code{\link{renderText}}.
#' @param func A function.
#' @export
reactiveText <- function(func) {
shinyDeprecated(new="renderText")

BIN
R/sysdata.rda Normal file

Binary file not shown.

View File

@@ -4,10 +4,10 @@
#' event occurs. These events are triggered by accessing a snapshot URL.
#'
#' This function only has an effect if the app is launched in test mode. This is
#' done by calling `runApp()` with `test.mode=TRUE`, or by setting the
#' global option `shiny.testmode` to `TRUE`.
#' done by calling \code{runApp()} with \code{test.mode=TRUE}, or by setting the
#' global option \code{shiny.testmode} to \code{TRUE}.
#'
#' @param quoted_ Are the expression quoted? Default is `FALSE`.
#' @param quoted_ Are the expression quoted? Default is \code{FALSE}.
#' @param env_ The environment in which the expression should be evaluated.
#' @param session_ A Shiny session object.
#' @param ... Named arguments that are quoted or unquoted expressions that will

View File

@@ -4,7 +4,7 @@
#' @param value The value to set for the input object.
#' @param placeholder The placeholder to set for the input object.
#'
#' @seealso [textInput()]
#' @seealso \code{\link{textInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -45,7 +45,7 @@ updateTextInput <- function(session, inputId, label = NULL, value = NULL, placeh
#' @template update-input
#' @inheritParams updateTextInput
#'
#' @seealso [textAreaInput()]
#' @seealso \code{\link{textAreaInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -84,7 +84,7 @@ updateTextAreaInput <- updateTextInput
#' @template update-input
#' @param value The value to set for the input object.
#'
#' @seealso [checkboxInput()]
#' @seealso \code{\link{checkboxInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -117,9 +117,9 @@ updateCheckboxInput <- function(session, inputId, label = NULL, value = NULL) {
#'
#' @template update-input
#' @param icon The icon to set for the input object. To remove the
#' current icon, use `icon=character(0)`.
#' current icon, use \code{icon=character(0)}.
#'
#' @seealso [actionButton()]
#' @seealso \code{\link{actionButton}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -170,13 +170,13 @@ updateActionButton <- function(session, inputId, label = NULL, icon = NULL) {
#'
#' @template update-input
#' @param value The desired date value. Either a Date object, or a string in
#' `yyyy-mm-dd` format. Supply `NA` to clear the date.
#' \code{yyyy-mm-dd} format. Supply \code{NA} to clear the date.
#' @param min The minimum allowed date. Either a Date object, or a string in
#' `yyyy-mm-dd` format.
#' \code{yyyy-mm-dd} format.
#' @param max The maximum allowed date. Either a Date object, or a string in
#' `yyyy-mm-dd` format.
#' \code{yyyy-mm-dd} format.
#'
#' @seealso [dateInput()]
#' @seealso \code{\link{dateInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -205,9 +205,18 @@ updateActionButton <- function(session, inputId, label = NULL, icon = NULL) {
updateDateInput <- function(session, inputId, label = NULL, value = NULL,
min = NULL, max = NULL) {
value <- dateYMD(value, "value")
min <- dateYMD(min, "min")
max <- dateYMD(max, "max")
# Make sure values are NULL or Date objects. This is so we can ensure that
# they will be formatted correctly. For example, the string "2016-08-9" is not
# correctly formatted, but the conversion to Date and back to string will fix
# it.
formatDate <- function(x) {
if (is.null(x))
return(NULL)
format(as.Date(x), "%Y-%m-%d")
}
value <- formatDate(value)
min <- formatDate(min)
max <- formatDate(max)
message <- dropNulls(list(label=label, value=value, min=min, max=max))
session$sendInputMessage(inputId, message)
@@ -218,15 +227,15 @@ updateDateInput <- function(session, inputId, label = NULL, value = NULL,
#'
#' @template update-input
#' @param start The start date. Either a Date object, or a string in
#' `yyyy-mm-dd` format. Supplying `NA` clears the start date.
#' \code{yyyy-mm-dd} format. Supplying \code{NA} clears the start date.
#' @param end The end date. Either a Date object, or a string in
#' `yyyy-mm-dd` format. Supplying `NA` clears the end date.
#' \code{yyyy-mm-dd} format. Supplying \code{NA} clears the end date.
#' @param min The minimum allowed date. Either a Date object, or a string in
#' `yyyy-mm-dd` format.
#' \code{yyyy-mm-dd} format.
#' @param max The maximum allowed date. Either a Date object, or a string in
#' `yyyy-mm-dd` format.
#' \code{yyyy-mm-dd} format.
#'
#' @seealso [dateRangeInput()]
#' @seealso \code{\link{dateRangeInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -257,11 +266,12 @@ updateDateInput <- function(session, inputId, label = NULL, value = NULL,
updateDateRangeInput <- function(session, inputId, label = NULL,
start = NULL, end = NULL, min = NULL,
max = NULL) {
start <- dateYMD(start, "start")
end <- dateYMD(end, "end")
min <- dateYMD(min, "min")
max <- dateYMD(max, "max")
# Make sure start and end are strings, not date objects. This is for
# consistency across different locales.
if (inherits(start, "Date")) start <- format(start, '%Y-%m-%d')
if (inherits(end, "Date")) end <- format(end, '%Y-%m-%d')
if (inherits(min, "Date")) min <- format(min, '%Y-%m-%d')
if (inherits(max, "Date")) max <- format(max, '%Y-%m-%d')
message <- dropNulls(list(
label = label,
@@ -275,14 +285,14 @@ updateDateRangeInput <- function(session, inputId, label = NULL,
#' Change the selected tab on the client
#'
#' @param session The `session` object passed to function given to
#' `shinyServer`.
#' @param inputId The id of the `tabsetPanel`, `navlistPanel`,
#' or `navbarPage` object.
#' @param session The \code{session} object passed to function given to
#' \code{shinyServer}.
#' @param inputId The id of the \code{tabsetPanel}, \code{navlistPanel},
#' or \code{navbarPage} object.
#' @param selected The name of the tab to make active.
#'
#' @seealso [tabsetPanel()], [navlistPanel()],
#' [navbarPage()]
#' @seealso \code{\link{tabsetPanel}}, \code{\link{navlistPanel}},
#' \code{\link{navbarPage}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -333,7 +343,7 @@ updateNavlistPanel <- updateTabsetPanel
#' @param max Maximum value.
#' @param step Step size.
#'
#' @seealso [numericInput()]
#' @seealso \code{\link{numericInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -385,7 +395,7 @@ updateNumericInput <- function(session, inputId, label = NULL, value = NULL,
#' @param timeFormat Date and POSIXt formatting.
#' @param timezone The timezone offset for POSIXt objects.
#'
#' @seealso [sliderInput()]
#' @seealso \code{\link{sliderInput}}
#'
#' @examples
#' ## Only run this example in interactive R sessions
@@ -418,15 +428,13 @@ updateNumericInput <- function(session, inputId, label = NULL, value = NULL,
updateSliderInput <- function(session, inputId, label = NULL, value = NULL,
min = NULL, max = NULL, step = NULL, timeFormat = NULL, timezone = NULL)
{
# If no min/max/value is provided, we won't know the
# type, and this will return an empty string
dataType <- getSliderType(min, max, value)
if (is.null(timeFormat)) {
timeFormat <- switch(dataType, date = "%F", datetime = "%F %T", number = NULL)
}
if (isTRUE(dataType %in% c("date", "datetime"))) {
if (dataType == "date" || dataType == "datetime") {
to_ms <- function(x) 1000 * as.numeric(as.POSIXct(x))
if (!is.null(min)) min <- to_ms(min)
if (!is.null(max)) max <- to_ms(max)
@@ -473,7 +481,7 @@ updateInputOptions <- function(session, inputId, label = NULL, choices = NULL,
#' @template update-input
#' @inheritParams checkboxGroupInput
#'
#' @seealso [checkboxGroupInput()]
#' @seealso \code{\link{checkboxGroupInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -520,7 +528,7 @@ updateCheckboxGroupInput <- function(session, inputId, label = NULL,
#' @template update-input
#' @inheritParams radioButtons
#'
#' @seealso [radioButtons()]
#' @seealso \code{\link{radioButtons}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -568,7 +576,7 @@ updateRadioButtons <- function(session, inputId, label = NULL, choices = NULL,
#' @template update-input
#' @inheritParams selectInput
#'
#' @seealso [selectInput()] [varSelectInput()]
#' @seealso \code{\link{selectInput}} \code{\link{varSelectInput}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -613,9 +621,9 @@ updateSelectInput <- function(session, inputId, label = NULL, choices = NULL,
#' @rdname updateSelectInput
#' @inheritParams selectizeInput
#' @param server whether to store `choices` on the server side, and load
#' @param server whether to store \code{choices} on the server side, and load
#' the select options dynamically on searching, instead of writing all
#' `choices` into the page at once (i.e., only use the client-side
#' \code{choices} into the page at once (i.e., only use the client-side
#' version of \pkg{selectize.js})
#' @export
updateSelectizeInput <- function(session, inputId, label = NULL, choices = NULL,

230
R/utils.R
View File

@@ -14,7 +14,7 @@ NULL
#'
#' @note When called, the returned function attempts to preserve the R session's
#' current seed by snapshotting and restoring
#' [base::.Random.seed()].
#' \code{\link[base]{.Random.seed}}.
#'
#' @examples
#' rnormA <- repeatable(rnorm)
@@ -121,8 +121,8 @@ isWholeNum <- function(x, tol = .Machine$double.eps^0.5) {
}
`%AND%` <- function(x, y) {
if (!is.null(x) && !isTRUE(is.na(x)))
if (!is.null(y) && !isTRUE(is.na(y)))
if (!is.null(x) && !is.na(x))
if (!is.null(y) && !is.na(y))
return(y)
return(NULL)
}
@@ -173,12 +173,12 @@ anyUnnamed <- function(x) {
}
# Given a vector/list, returns a named vector/list (the labels will be blank).
asNamed <- function(x) {
if (is.null(names(x))) {
names(x) <- character(length(x))
}
# Given a vector/list, returns a named vector (the labels will be blank).
asNamedVector <- function(x) {
if (!is.null(names(x)))
return(x)
names(x) <- rep.int("", length(x))
x
}
@@ -468,12 +468,12 @@ exprToFunction <- function(expr, env=parent.frame(), quoted=FALSE) {
#' Installs an expression in the given environment as a function, and registers
#' debug hooks so that breakpoints may be set in the function.
#'
#' This function can replace `exprToFunction` as follows: we may use
#' `func <- exprToFunction(expr)` if we do not want the debug hooks, or
#' `installExprFunction(expr, "func")` if we do. Both approaches create a
#' function named `func` in the current environment.
#' This function can replace \code{exprToFunction} as follows: we may use
#' \code{func <- exprToFunction(expr)} if we do not want the debug hooks, or
#' \code{installExprFunction(expr, "func")} if we do. Both approaches create a
#' function named \code{func} in the current environment.
#'
#' @seealso Wraps [exprToFunction()]; see that method's documentation
#' @seealso Wraps \code{\link{exprToFunction}}; see that method's documentation
#' for more documentation and examples.
#'
#' @param expr A quoted or unquoted expression
@@ -485,7 +485,7 @@ exprToFunction <- function(expr, env=parent.frame(), quoted=FALSE) {
#' @param label A label for the object to be shown in the debugger. Defaults to
#' the name of the calling function.
#' @param wrappedWithLabel,..stacktraceon Advanced use only. For stack manipulation purposes; see
#' [stacktrace()].
#' \code{\link{stacktrace}}.
#' @export
installExprFunction <- function(expr, name, eval.env = parent.frame(2),
quoted = FALSE,
@@ -516,7 +516,6 @@ installExprFunction <- function(expr, name, eval.env = parent.frame(2),
#'
#' Returns a named list of key-value pairs.
#'
#' @noMd
#' @param str The query string. It can have a leading \code{"?"} or not.
#' @param nested Whether to parse the query string of as a nested list when it
#' contains pairs of square brackets \code{[]}. For example, the query
@@ -614,7 +613,7 @@ shinyCallingHandlers <- function(expr) {
#' Print message for deprecated functions in Shiny
#'
#' To disable these messages, use `options(shiny.deprecation.messages=FALSE)`.
#' To disable these messages, use \code{options(shiny.deprecation.messages=FALSE)}.
#'
#' @param new Name of replacement function.
#' @param msg Message to print. If used, this will override the default message.
@@ -950,28 +949,28 @@ columnToRowData <- function(data) {
#'
#' This should be used when you want to let the user see an error
#' message even if the default is to sanitize all errors. If you have an
#' error `e` and call `stop(safeError(e))`, then Shiny will
#' ignore the value of `getOption("shiny.sanitize.errors")` and always
#' error \code{e} and call \code{stop(safeError(e))}, then Shiny will
#' ignore the value of \code{getOption("shiny.sanitize.errors")} and always
#' display the error in the app itself.
#'
#' @param error Either an "error" object or a "character" object (string).
#' In the latter case, the string will become the message of the error
#' returned by `safeError`.
#' returned by \code{safeError}.
#'
#' @return An "error" object
#'
#' @details An error generated by `safeError` has priority over all
#' @details An error generated by \code{safeError} has priority over all
#' other Shiny errors. This can be dangerous. For example, if you have set
#' `options(shiny.sanitize.errors = TRUE)`, then by default all error
#' \code{options(shiny.sanitize.errors = TRUE)}, then by default all error
#' messages are omitted in the app, and replaced by a generic error message.
#' However, this does not apply to `safeError`: whatever you pass
#' through `error` will be displayed to the user. So, this should only
#' However, this does not apply to \code{safeError}: whatever you pass
#' through \code{error} will be displayed to the user. So, this should only
#' be used when you are sure that your error message does not contain any
#' sensitive information. In those situations, `safeError` can make
#' sensitive information. In those situations, \code{safeError} can make
#' your users' lives much easier by giving them a hint as to where the
#' error occurred.
#'
#' @seealso [shiny-options()]
#' @seealso \code{\link{shiny-options}}
#'
#' @examples
#' ## Only run examples in interactive R sessions
@@ -1051,7 +1050,7 @@ safeError <- function(error) {
# #' @examples
# #' ## Note: the breaking of the reactive chain that happens in the app
# #' ## below (when input$txt = 'bad' and input$allowBad = 'FALSE') is
# #' ## easily visualized with `reactlogShow()`
# #' ## easily visualized with `showReactLog()`
# #'
# #' ## Only run examples in interactive R sessions
# #' if (interactive()) {
@@ -1085,58 +1084,58 @@ reactiveStop <- function(message = "", class = NULL) {
#' Validate input values and other conditions
#'
#' For an output rendering function (e.g. [renderPlot()]), you may
#' For an output rendering function (e.g. \code{\link{renderPlot}()}), you may
#' need to check that certain input values are available and valid before you
#' can render the output. `validate` gives you a convenient mechanism for
#' can render the output. \code{validate} gives you a convenient mechanism for
#' doing so.
#'
#' The `validate` function takes any number of (unnamed) arguments, each of
#' The \code{validate} function takes any number of (unnamed) arguments, each of
#' which represents a condition to test. If any of the conditions represent
#' failure, then a special type of error is signaled which stops execution. If
#' this error is not handled by application-specific code, it is displayed to
#' the user by Shiny.
#'
#' An easy way to provide arguments to `validate` is to use the `need`
#' An easy way to provide arguments to \code{validate} is to use the \code{need}
#' function, which takes an expression and a string; if the expression is
#' considered a failure, then the string will be used as the error message. The
#' `need` function considers its expression to be a failure if it is any of
#' \code{need} function considers its expression to be a failure if it is any of
#' the following:
#'
#' \itemize{
#' \item{`FALSE`}
#' \item{`NULL`}
#' \item{`""`}
#' \item{\code{FALSE}}
#' \item{\code{NULL}}
#' \item{\code{""}}
#' \item{An empty atomic vector}
#' \item{An atomic vector that contains only missing values}
#' \item{A logical vector that contains all `FALSE` or missing values}
#' \item{An object of class `"try-error"`}
#' \item{A value that represents an unclicked [actionButton()]}
#' \item{A logical vector that contains all \code{FALSE} or missing values}
#' \item{An object of class \code{"try-error"}}
#' \item{A value that represents an unclicked \code{\link{actionButton}}}
#' }
#'
#' If any of these values happen to be valid, you can explicitly turn them to
#' logical values. For example, if you allow `NA` but not `NULL`, you
#' can use the condition `!is.null(input$foo)`, because `!is.null(NA)
#' == TRUE`.
#' logical values. For example, if you allow \code{NA} but not \code{NULL}, you
#' can use the condition \code{!is.null(input$foo)}, because \code{!is.null(NA)
#' == TRUE}.
#'
#' If you need validation logic that differs significantly from `need`, you
#' If you need validation logic that differs significantly from \code{need}, you
#' can create other validation test functions. A passing test should return
#' `NULL`. A failing test should return an error message as a
#' \code{NULL}. A failing test should return an error message as a
#' single-element character vector, or if the failure should happen silently,
#' `FALSE`.
#' \code{FALSE}.
#'
#' Because validation failure is signaled as an error, you can use
#' `validate` in reactive expressions, and validation failures will
#' \code{validate} in reactive expressions, and validation failures will
#' automatically propagate to outputs that use the reactive expression. In
#' other words, if reactive expression `a` needs `input$x`, and two
#' outputs use `a` (and thus depend indirectly on `input$x`), it's
#' not necessary for the outputs to validate `input$x` explicitly, as long
#' as `a` does validate it.
#' other words, if reactive expression \code{a} needs \code{input$x}, and two
#' outputs use \code{a} (and thus depend indirectly on \code{input$x}), it's
#' not necessary for the outputs to validate \code{input$x} explicitly, as long
#' as \code{a} does validate it.
#'
#' @param ... A list of tests. Each test should equal `NULL` for success,
#' `FALSE` for silent failure, or a string for failure with an error
#' @param ... A list of tests. Each test should equal \code{NULL} for success,
#' \code{FALSE} for silent failure, or a string for failure with an error
#' message.
#' @param errorClass A CSS class to apply. The actual CSS string will have
#' `shiny-output-error-` prepended to this value.
#' \code{shiny-output-error-} prepended to this value.
#' @export
#' @examples
#' ## Only run examples in interactive R sessions
@@ -1188,10 +1187,10 @@ validate <- function(..., errorClass = character(0)) {
#' @param expr An expression to test. The condition will pass if the expression
#' meets the conditions spelled out in Details.
#' @param message A message to convey to the user if the validation condition is
#' not met. If no message is provided, one will be created using `label`.
#' To fail with no message, use `FALSE` for the message.
#' not met. If no message is provided, one will be created using \code{label}.
#' To fail with no message, use \code{FALSE} for the message.
#' @param label A human-readable name for the field that may be missing. This
#' parameter is not needed if `message` is provided, but must be provided
#' parameter is not needed if \code{message} is provided, but must be provided
#' otherwise.
#' @export
#' @rdname validate
@@ -1212,7 +1211,7 @@ need <- function(expr, message = paste(label, "must be provided"), label) {
#' operation is stopped by raising a "silent" exception (not logged by Shiny,
#' nor displayed in the Shiny app's UI).
#'
#' The `req` function was designed to be used in one of two ways. The first
#' The \code{req} function was designed to be used in one of two ways. The first
#' is to call it like a statement (ignoring its return value) before attempting
#' operations using the required values:
#'
@@ -1222,9 +1221,9 @@ need <- function(expr, message = paste(label, "must be provided"), label) {
#' # Code that uses input$a, input$b, and/or rv$state...
#' })}
#'
#' In this example, if `r()` is called and any of `input$a`,
#' `input$b`, and `rv$state` are `NULL`, `FALSE`, `""`,
#' etc., then the `req` call will trigger an error that propagates all the
#' In this example, if \code{r()} is called and any of \code{input$a},
#' \code{input$b}, and \code{rv$state} are \code{NULL}, \code{FALSE}, \code{""},
#' etc., then the \code{req} call will trigger an error that propagates all the
#' way up to whatever render block or observer is executing.
#'
#' The second is to use it to wrap an expression that must be truthy:
@@ -1237,70 +1236,70 @@ need <- function(expr, message = paste(label, "must be provided"), label) {
#' }
#' })}
#'
#' In this example, `req(input$plotType)` first checks that
#' `input$plotType` is truthy, and if so, returns it. This is a convenient
#' In this example, \code{req(input$plotType)} first checks that
#' \code{input$plotType} is truthy, and if so, returns it. This is a convenient
#' way to check for a value "inline" with its first use.
#'
#' **Truthy and falsy values**
#' \strong{Truthy and falsy values}
#'
#' The terms "truthy" and "falsy" generally indicate whether a value, when
#' coerced to a [base::logical()], is `TRUE` or `FALSE`. We use
#' coerced to a \code{\link[base]{logical}}, is \code{TRUE} or \code{FALSE}. We use
#' the term a little loosely here; our usage tries to match the intuitive
#' notions of "Is this value missing or available?", or "Has the user provided
#' an answer?", or in the case of action buttons, "Has the button been
#' clicked?".
#'
#' For example, a `textInput` that has not been filled out by the user has
#' a value of `""`, so that is considered a falsy value.
#' For example, a \code{textInput} that has not been filled out by the user has
#' a value of \code{""}, so that is considered a falsy value.
#'
#' To be precise, `req` considers a value truthy *unless* it is one
#' To be precise, \code{req} considers a value truthy \emph{unless} it is one
#' of:
#'
#' \itemize{
#' \item{`FALSE`}
#' \item{`NULL`}
#' \item{`""`}
#' \item{\code{FALSE}}
#' \item{\code{NULL}}
#' \item{\code{""}}
#' \item{An empty atomic vector}
#' \item{An atomic vector that contains only missing values}
#' \item{A logical vector that contains all `FALSE` or missing values}
#' \item{An object of class `"try-error"`}
#' \item{A value that represents an unclicked [actionButton()]}
#' \item{A logical vector that contains all \code{FALSE} or missing values}
#' \item{An object of class \code{"try-error"}}
#' \item{A value that represents an unclicked \code{\link{actionButton}}}
#' }
#'
#' Note in particular that the value `0` is considered truthy, even though
#' `as.logical(0)` is `FALSE`.
#' Note in particular that the value \code{0} is considered truthy, even though
#' \code{as.logical(0)} is \code{FALSE}.
#'
#' If the built-in rules for truthiness do not match your requirements, you can
#' always work around them. Since `FALSE` is falsy, you can simply provide
#' the results of your own checks to `req`:
#' always work around them. Since \code{FALSE} is falsy, you can simply provide
#' the results of your own checks to \code{req}:
#'
#' `req(input$a != 0)`
#' \code{req(input$a != 0)}
#'
#' **Using `req(FALSE)`**
#' \strong{Using \code{req(FALSE)}}
#'
#' You can use `req(FALSE)` (i.e. no condition) if you've already performed
#' You can use \code{req(FALSE)} (i.e. no condition) if you've already performed
#' all the checks you needed to by that point and just want to stop the reactive
#' chain now. There is no advantange to this, except perhaps ease of readibility
#' if you have a complicated condition to check for (or perhaps if you'd like to
#' divide your condition into nested `if` statements).
#' divide your condition into nested \code{if} statements).
#'
#' **Using `cancelOutput = TRUE`**
#' \strong{Using \code{cancelOutput = TRUE}}
#'
#' When `req(..., cancelOutput = TRUE)` is used, the "silent" exception is
#' When \code{req(..., cancelOutput = TRUE)} is used, the "silent" exception is
#' also raised, but it is treated slightly differently if one or more outputs are
#' currently being evaluated. In those cases, the reactive chain does not proceed
#' or update, but the output(s) are left is whatever state they happen to be in
#' (whatever was their last valid state).
#'
#' Note that this is always going to be the case if
#' this is used inside an output context (e.g. `output$txt <- ...`). It may
#' this is used inside an output context (e.g. \code{output$txt <- ...}). It may
#' or may not be the case if it is used inside a non-output context (e.g.
#' [reactive()], [observe()] or [observeEvent()])
#' --- depending on whether or not there is an `output$...` that is triggered
#' \code{\link{reactive}}, \code{\link{observe}} or \code{\link{observeEvent}})
#' -- depending on whether or not there is an \code{output$...} that is triggered
#' as a result of those calls. See the examples below for concrete scenarios.
#'
#' @param ... Values to check for truthiness.
#' @param cancelOutput If `TRUE` and an output is being evaluated, stop
#' @param cancelOutput If \code{TRUE} and an output is being evaluated, stop
#' processing as usual but instead of clearing the output, leave it in
#' whatever state it happens to be in.
#' @param x An expression whose truthiness value we want to determine
@@ -1439,7 +1438,7 @@ stopWithCondition <- function(class, message) {
#' This function returns the information about the current Shiny Server, such as
#' its version, and whether it is the open source edition or professional
#' edition. If the app is not served through the Shiny Server, this function
#' just returns `list(shinyServer = FALSE)`.
#' just returns \code{list(shinyServer = FALSE)}.
#'
#' This function will only return meaningful data when using Shiny Server
#' version 1.2.2 or later.
@@ -1561,25 +1560,6 @@ URLencode <- function(value, reserved = FALSE) {
if (reserved) encodeURIComponent(value) else encodeURI(value)
}
# Make user-supplied dates are either NULL or can be coerced
# to a yyyy-mm-dd formatted string. If a date is specified, this
# function returns a string for consistency across locales.
# Also, `as.Date()` is used to coerce strings to date objects
# so that strings like "2016-08-9" are expanded to "2016-08-09"
dateYMD <- function(date = NULL, argName = "value") {
if (!length(date)) return(NULL)
if (length(date) > 1) warning("Expected `", argName, "` to be of length 1.")
tryCatch(date <- format(as.Date(date), "%Y-%m-%d"),
error = function(e) {
warning(
"Couldn't coerce the `", argName,
"` argument to a date string with format yyyy-mm-dd",
call. = FALSE
)
}
)
date
}
# This function takes a name and function, and it wraps that function in a new
# function which calls the original function using the specified name. This can
@@ -1750,7 +1730,6 @@ createVarPromiseDomain <- function(env, name, value) {
getSliderType <- function(min, max, value) {
vals <- dropNulls(list(value, min, max))
if (length(vals) == 0) return("")
type <- unique(lapply(vals, function(x) {
if (inherits(x, "Date")) "date"
else if (inherits(x, "POSIXt")) "datetime"
@@ -1761,42 +1740,3 @@ getSliderType <- function(min, max, value) {
}
type[[1]]
}
# Reads the `shiny.sharedSecret` global option, and returns a function that can
# be used to test header values for a match.
loadSharedSecret <- function() {
normalizeToRaw <- function(value, label = "value") {
if (is.null(value)) {
raw()
} else if (is.character(value)) {
charToRaw(paste(value, collapse = "\n"))
} else if (is.raw(value)) {
value
} else {
stop("Wrong type for ", label, "; character or raw expected")
}
}
sharedSecret <- normalizeToRaw(getOption("shiny.sharedSecret"))
if (is.null(sharedSecret)) {
function(x) TRUE
} else {
# We compare the digest of the two values so that their lengths are equalized
function(x) {
x <- normalizeToRaw(x)
# Constant time comparison to avoid timing attacks
constantTimeEquals(sharedSecret, x)
}
}
}
# Compares two raw vectors of equal length for equality, in constant time
constantTimeEquals <- function(raw1, raw2) {
stopifnot(is.raw(raw1))
stopifnot(is.raw(raw2))
if (length(raw1) != length(raw2)) {
return(FALSE)
}
sum(as.integer(xor(raw1, raw2))) == 0
}

View File

@@ -65,4 +65,7 @@ We welcome contributions to the **shiny** package. Please see our [CONTRIBUTING.
## License
The shiny package as a whole is licensed under the GPLv3. See the [LICENSE](LICENSE) file for more details.
The shiny package is licensed under the GPLv3. See these files in the inst directory for additional details:
- COPYING - shiny package license (GPLv3)
- NOTICE - Copyright notices for additional included software

1504
data-raw/fa_icons.csv Normal file

File diff suppressed because it is too large Load Diff

1
data-raw/fa_version.txt Normal file
View File

@@ -0,0 +1 @@
5.4.1

File diff suppressed because one or more lines are too long

View File

@@ -113,6 +113,11 @@ sd_section("Rendering functions",
"renderTable",
"renderUI",
"downloadHandler",
"reactivePlot",
"reactivePrint",
"reactiveTable",
"reactiveText",
"reactiveUI",
"createRenderFunction"
)
)
@@ -129,7 +134,7 @@ sd_section("Reactive programming",
"isolate",
"invalidateLater",
"debounce",
"reactlog",
"showReactLog",
"makeReactiveBinding",
"reactiveFileReader",
"reactivePoll",
@@ -208,7 +213,7 @@ sd_section("Utility functions",
"onStop",
"diskCache",
"memoryCache",
"reexports"
"key_missing"
)
)
sd_section("Plot interaction",

1606
inst/www/reactive-graph.html Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -671,7 +671,7 @@
visualPadding = 10,
container = $(this.o.container),
windowWidth = container.width(),
scrollTop = this.o.container === 'body:first' ? $(document).scrollTop() : container.scrollTop(),
scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
appendOffset = container.offset();
var parentsZindex = [];
@@ -686,7 +686,7 @@
var left = offset.left - appendOffset.left,
top = offset.top - appendOffset.top;
if (this.o.container !== 'body:first') {
if (this.o.container !== 'body') {
top += scrollTop;
}
@@ -1766,7 +1766,7 @@
enableOnReadonly: true,
showOnFocus: true,
zIndexOffset: 10,
container: 'body:first',
container: 'body',
immediateUpdates: false,
title: '',
templates: {

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/*!
* Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
* Font Awesome Free 5.4.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
.fa,
@@ -196,6 +196,9 @@ readers do not read off random characters that represent icons */
.fa-accusoft:before {
content: "\f369"; }
.fa-acquisitions-incorporated:before {
content: "\f6af"; }
.fa-ad:before {
content: "\f641"; }
@@ -511,6 +514,9 @@ readers do not read off random characters that represent icons */
.fa-blender:before {
content: "\f517"; }
.fa-blender-phone:before {
content: "\f6b6"; }
.fa-blind:before {
content: "\f29d"; }
@@ -544,6 +550,9 @@ readers do not read off random characters that represent icons */
.fa-book:before {
content: "\f02d"; }
.fa-book-dead:before {
content: "\f6b7"; }
.fa-book-open:before {
content: "\f518"; }
@@ -646,6 +655,9 @@ readers do not read off random characters that represent icons */
.fa-camera-retro:before {
content: "\f083"; }
.fa-campground:before {
content: "\f6bb"; }
.fa-cannabis:before {
content: "\f55f"; }
@@ -697,6 +709,9 @@ readers do not read off random characters that represent icons */
.fa-cart-plus:before {
content: "\f217"; }
.fa-cat:before {
content: "\f6be"; }
.fa-cc-amazon-pay:before {
content: "\f42d"; }
@@ -733,6 +748,9 @@ readers do not read off random characters that represent icons */
.fa-certificate:before {
content: "\f0a3"; }
.fa-chair:before {
content: "\f6c0"; }
.fa-chalkboard:before {
content: "\f51b"; }
@@ -856,6 +874,12 @@ readers do not read off random characters that represent icons */
.fa-cloud-download-alt:before {
content: "\f381"; }
.fa-cloud-moon:before {
content: "\f6c3"; }
.fa-cloud-sun:before {
content: "\f6c4"; }
.fa-cloud-upload-alt:before {
content: "\f382"; }
@@ -994,9 +1018,15 @@ readers do not read off random characters that represent icons */
.fa-creative-commons-share:before {
content: "\f4f2"; }
.fa-creative-commons-zero:before {
content: "\f4f3"; }
.fa-credit-card:before {
content: "\f09d"; }
.fa-critical-role:before {
content: "\f6c9"; }
.fa-crop:before {
content: "\f125"; }
@@ -1057,6 +1087,9 @@ readers do not read off random characters that represent icons */
.fa-desktop:before {
content: "\f108"; }
.fa-dev:before {
content: "\f6cc"; }
.fa-deviantart:before {
content: "\f1bd"; }
@@ -1069,6 +1102,12 @@ readers do not read off random characters that represent icons */
.fa-dice:before {
content: "\f522"; }
.fa-dice-d20:before {
content: "\f6cf"; }
.fa-dice-d6:before {
content: "\f6d1"; }
.fa-dice-five:before {
content: "\f523"; }
@@ -1120,6 +1159,9 @@ readers do not read off random characters that represent icons */
.fa-docker:before {
content: "\f395"; }
.fa-dog:before {
content: "\f6d3"; }
.fa-dollar-sign:before {
content: "\f155"; }
@@ -1153,6 +1195,9 @@ readers do not read off random characters that represent icons */
.fa-drafting-compass:before {
content: "\f568"; }
.fa-dragon:before {
content: "\f6d5"; }
.fa-draw-polygon:before {
content: "\f5ee"; }
@@ -1171,12 +1216,18 @@ readers do not read off random characters that represent icons */
.fa-drum-steelpan:before {
content: "\f56a"; }
.fa-drumstick-bite:before {
content: "\f6d7"; }
.fa-drupal:before {
content: "\f1a9"; }
.fa-dumbbell:before {
content: "\f44b"; }
.fa-dungeon:before {
content: "\f6d9"; }
.fa-dyalog:before {
content: "\f399"; }
@@ -1294,6 +1345,9 @@ readers do not read off random characters that represent icons */
.fa-facebook-square:before {
content: "\f082"; }
.fa-fantasy-flight-games:before {
content: "\f6dc"; }
.fa-fast-backward:before {
content: "\f049"; }
@@ -1333,6 +1387,9 @@ readers do not read off random characters that represent icons */
.fa-file-contract:before {
content: "\f56c"; }
.fa-file-csv:before {
content: "\f6dd"; }
.fa-file-download:before {
content: "\f56d"; }
@@ -1420,6 +1477,9 @@ readers do not read off random characters that represent icons */
.fa-fish:before {
content: "\f578"; }
.fa-fist-raised:before {
content: "\f6de"; }
.fa-flag:before {
content: "\f024"; }
@@ -1546,6 +1606,9 @@ readers do not read off random characters that represent icons */
.fa-gg-circle:before {
content: "\f261"; }
.fa-ghost:before {
content: "\f6e2"; }
.fa-gift:before {
content: "\f06b"; }
@@ -1720,6 +1783,9 @@ readers do not read off random characters that represent icons */
.fa-hackerrank:before {
content: "\f5f7"; }
.fa-hammer:before {
content: "\f6e3"; }
.fa-hamsa:before {
content: "\f665"; }
@@ -1774,9 +1840,15 @@ readers do not read off random characters that represent icons */
.fa-handshake:before {
content: "\f2b5"; }
.fa-hanukiah:before {
content: "\f6e6"; }
.fa-hashtag:before {
content: "\f292"; }
.fa-hat-wizard:before {
content: "\f6e8"; }
.fa-haykal:before {
content: "\f666"; }
@@ -1807,6 +1879,12 @@ readers do not read off random characters that represent icons */
.fa-highlighter:before {
content: "\f591"; }
.fa-hiking:before {
content: "\f6ec"; }
.fa-hippo:before {
content: "\f6ed"; }
.fa-hips:before {
content: "\f452"; }
@@ -1828,6 +1906,9 @@ readers do not read off random characters that represent icons */
.fa-hornbill:before {
content: "\f592"; }
.fa-horse:before {
content: "\f6f0"; }
.fa-hospital:before {
content: "\f0f8"; }
@@ -1858,9 +1939,15 @@ readers do not read off random characters that represent icons */
.fa-hourglass-start:before {
content: "\f251"; }
.fa-house-damage:before {
content: "\f6f1"; }
.fa-houzz:before {
content: "\f27c"; }
.fa-hryvnia:before {
content: "\f6f2"; }
.fa-html5:before {
content: "\f13b"; }
@@ -2191,6 +2278,9 @@ readers do not read off random characters that represent icons */
.fa-mars-stroke-v:before {
content: "\f22a"; }
.fa-mask:before {
content: "\f6fa"; }
.fa-mastodon:before {
content: "\f4f6"; }
@@ -2323,6 +2413,9 @@ readers do not read off random characters that represent icons */
.fa-motorcycle:before {
content: "\f21c"; }
.fa-mountain:before {
content: "\f6fc"; }
.fa-mouse-pointer:before {
content: "\f245"; }
@@ -2335,6 +2428,9 @@ readers do not read off random characters that represent icons */
.fa-neos:before {
content: "\f612"; }
.fa-network-wired:before {
content: "\f6ff"; }
.fa-neuter:before {
content: "\f22c"; }
@@ -2404,6 +2500,9 @@ readers do not read off random characters that represent icons */
.fa-osi:before {
content: "\f41a"; }
.fa-otter:before {
content: "\f700"; }
.fa-outdent:before {
content: "\f03b"; }
@@ -2491,6 +2590,9 @@ readers do not read off random characters that represent icons */
.fa-pencil-ruler:before {
content: "\f5ae"; }
.fa-penny-arcade:before {
content: "\f704"; }
.fa-people-carry:before {
content: "\f4ce"; }
@@ -2752,6 +2854,9 @@ readers do not read off random characters that represent icons */
.fa-ribbon:before {
content: "\f4d6"; }
.fa-ring:before {
content: "\f70b"; }
.fa-road:before {
content: "\f018"; }
@@ -2791,6 +2896,9 @@ readers do not read off random characters that represent icons */
.fa-ruler-vertical:before {
content: "\f548"; }
.fa-running:before {
content: "\f70c"; }
.fa-rupee-sign:before {
content: "\f156"; }
@@ -2821,6 +2929,9 @@ readers do not read off random characters that represent icons */
.fa-scribd:before {
content: "\f28a"; }
.fa-scroll:before {
content: "\f70e"; }
.fa-search:before {
content: "\f002"; }
@@ -2938,6 +3049,9 @@ readers do not read off random characters that represent icons */
.fa-skull:before {
content: "\f54c"; }
.fa-skull-crossbones:before {
content: "\f714"; }
.fa-skyatlas:before {
content: "\f216"; }
@@ -2950,6 +3064,9 @@ readers do not read off random characters that represent icons */
.fa-slack-hash:before {
content: "\f3ef"; }
.fa-slash:before {
content: "\f715"; }
.fa-sliders-h:before {
content: "\f1de"; }
@@ -3028,6 +3145,9 @@ readers do not read off random characters that represent icons */
.fa-speakap:before {
content: "\f3f3"; }
.fa-spider:before {
content: "\f717"; }
.fa-spinner:before {
content: "\f110"; }
@@ -3331,6 +3451,9 @@ readers do not read off random characters that represent icons */
.fa-toggle-on:before {
content: "\f205"; }
.fa-toilet-paper:before {
content: "\f71e"; }
.fa-toolbox:before {
content: "\f552"; }
@@ -3343,6 +3466,9 @@ readers do not read off random characters that represent icons */
.fa-torii-gate:before {
content: "\f6a1"; }
.fa-tractor:before {
content: "\f722"; }
.fa-trade-federation:before {
content: "\f513"; }
@@ -3502,6 +3628,9 @@ readers do not read off random characters that represent icons */
.fa-user-graduate:before {
content: "\f501"; }
.fa-user-injured:before {
content: "\f728"; }
.fa-user-lock:before {
content: "\f502"; }
@@ -3616,6 +3745,9 @@ readers do not read off random characters that represent icons */
.fa-volume-down:before {
content: "\f027"; }
.fa-volume-mute:before {
content: "\f6a9"; }
.fa-volume-off:before {
content: "\f026"; }
@@ -3667,6 +3799,9 @@ readers do not read off random characters that represent icons */
.fa-wikipedia-w:before {
content: "\f266"; }
.fa-wind:before {
content: "\f72e"; }
.fa-window-close:before {
content: "\f410"; }
@@ -3682,6 +3817,9 @@ readers do not read off random characters that represent icons */
.fa-windows:before {
content: "\f17a"; }
.fa-wine-bottle:before {
content: "\f72f"; }
.fa-wine-glass:before {
content: "\f4e3"; }
@@ -3691,6 +3829,9 @@ readers do not read off random characters that represent icons */
.fa-wix:before {
content: "\f5cf"; }
.fa-wizards-of-the-coast:before {
content: "\f730"; }
.fa-wolf-pack-battalion:before {
content: "\f514"; }

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/*!
* Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
* Font Awesome Free 5.4.1 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
.fa.fa-glass:before {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 633 KiB

After

Width:  |  Height:  |  Size: 673 KiB

View File

@@ -80,7 +80,7 @@
horiz-adv-x="320" d=" M296 192H251.38C272.46 225.99 288 266.35 288 304C288 392.37 230.69 448 160 448S32 392.37 32 304C32 266.35 47.54 225.99 68.62 192H24C10.75 192 0 181.26 0 168V136C0 122.75 10.75 112 24 112H120V-40C120 -53.25 130.75 -64 144 -64H176C189.25 -64 200 -53.25 200 -40V112H296C309.25 112 320 122.75 320 136V168C320 181.26 309.25 192 296 192zM160 368C189.61 368 208 343.48 208 304C208 269.3400000000001 180.86 225.86 160 203.13C139.14 225.85 112 269.34 112 304C112 343.48 130.39 368 160 368z" />
<glyph glyph-name="apple-alt"
unicode="&#xF5D1;"
horiz-adv-x="448" d=" M351.18 318.85C315.65 325.1 253.12 304.49 224 288.04C194.88 304.49 132.34 325.11 96.81 318.85C15.57 304.55 -10.61 194.36 3.72 113.25C18.05 32.14 65.02 -64 160.41 -64C172.47 -64 184.53 -59.39 194.85 -53.66C212.93 -43.63 235.08 -43.63 253.16 -53.66C263.48 -59.39 275.54 -64 287.59 -64C382.98 -64 429.95 32.14 444.27 113.25C458.6 194.36 432.44 304.55 351.18 318.85zM295.63 360.38C326.19 390.94 319.35 447.35 319.35 447.35S262.9400000000001 454.2 232.38 423.63C201.81 393.06 208.66 336.66 208.66 336.66S265.06 329.81 295.63 360.38z" />
horiz-adv-x="448" d=" M350.85 319C376.8200000000001 314.3300000000001 398.12 300.33 414.7700000000001 277C429.42 256.33 439.4100000000001 230.33 444.73 199C449.4000000000001 170.33 449.05 141.67 443.73 113C435.74 65.67 419.76 26 395.79 -6C367.1500000000001 -44.67 331.2000000000001 -64 287.92 -64C277.26 -64 265.62 -60.67 252.96 -54C244.3 -48.67 234.65 -46 223.99 -46S203.69 -48.67 195.02 -54C182.36 -60.67 170.72 -64 160.06 -64C116.78 -64 80.83 -44.67 52.19 -6C28.22 26 12.24 65.67 4.25 113C-1.07 141.67 -1.42 170.33 3.25 199C8.57 230.33 18.56 256.33 33.21 277C49.86 300.33 71.16 314.33 97.13 319C113.11 321.67 135.08 319.3300000000001 163.05 312C187.02 305.3300000000001 207.33 297.3300000000001 223.98 288C240.63 297.3300000000001 260.94 305.33 284.9100000000001 312C312.8900000000001 319.3300000000001 334.87 321.67 350.85 319zM295.9100000000001 360C286.5900000000001 351.33 274.2600000000001 345 258.9500000000001 341C248.2900000000001 337.67 236.6500000000001 336 223.9900000000001 336L209.0100000000001 337C207.68 346.33 207.68 357 209.0100000000001 369C211.68 393 219.3300000000001 411.33 231.9800000000001 424C241.3000000000001 432.67 253.6300000000001 439 268.9400000000001 443C279.6000000000001 446.33 291.2400000000001 448 303.9000000000001 448L318.8800000000001 447L319.8800000000001 432C319.8800000000001 419.33 318.2100000000001 407.67 314.8900000000001 397C310.9000000000001 381.67 304.5800000000001 369.33 295.9100000000001 360z" />
<glyph glyph-name="archive"
unicode="&#xF187;"
horiz-adv-x="512" d=" M32 0C32 -17.7 46.3 -32 64 -32H448C465.7 -32 480 -17.7 480 0V288H32V0zM192 212C192 218.6 197.4 224 204 224H308C314.6 224 320 218.6 320 212V204C320 197.4 314.6 192 308 192H204C197.4 192 192 197.4 192 204V212zM480 416H32C14.3 416 0 401.7 0 384V336C0 327.2 7.2 320 16 320H496C504.8 320 512 327.2 512 336V384C512 401.7 497.7 416 480 416z" />
@@ -225,6 +225,9 @@
<glyph glyph-name="birthday-cake"
unicode="&#xF1FD;"
horiz-adv-x="448" d=" M448 64C419.98 64 416.74 96 373.5 96C330.07 96 326.675 64 298.75 64C271.055 64 267.296 96 224 96C181.158 96 176.782 64 149.5 64C121.352 64 118.298 96 74.75 96C31.203 96 28.097 64 0 64V144C0 170.5 21.5 192 48 192H64V336H128V192H192V336H256V192H320V336H384V192H400C426.5 192 448 170.5 448 144V64zM448 -64H0V32C43.356 32 46.767 64 74.75 64C102.701 64 106.003 32 149.5 32C192.343 32 196.717 64 224 64C252.148 64 255.201 32 298.75 32C342.107 32 345.517 64 373.5 64C400.988 64 404.752 32 448 32V-64zM96 352C78.25 352 64 366.25 64 384C64 415 96 407 96 448C108 448 128 418.5 128 392S113.75 352 96 352zM224 352C206.25 352 192 366.25 192 384C192 415 224 407 224 448C236 448 256 418.5 256 392S241.75 352 224 352zM352 352C334.25 352 320 366.25 320 384C320 415 352 407 352 448C364 448 384 418.5 384 392S369.75 352 352 352z" />
<glyph glyph-name="blender-phone"
unicode="&#xF6B6;"
horiz-adv-x="576" d=" M392 384H558.54L576 448H192V96H480L497.46 160H392C387.58 160 384 163.58 384 168V184C384 188.42 387.58 192 392 192H506.18L523.64 256H392C387.58 256 384 259.5800000000001 384 264V280C384 284.42 387.58 288 392 288H532.36L549.82 352H392C387.58 352 384 355.58 384 360V376C384 380.42 387.58 384 392 384zM158.8 112.99L133.02 176.25C130.24 183.06 123.22 187.24 115.78 186.51L70.75 182.09C53.47 229.03 53.1 281.87 70.75 329.81L115.78 325.39C123.21 324.66 130.24 328.85 133.02 335.65L158.8 398.91C161.82 406.3 159 414.76 152.12 418.98L112.84 443.08C98.51 451.87 80.09 448.5 68.95 436.03C-23.62 332.43 -23.05 176.48 71.05 73.54C80.92 62.74 100.17 61.06 112.7 68.74L152.11 92.92C159 97.14 161.81 105.59 158.8 112.99zM480 64H192C156.65 64 128 35.35 128 0V-32C128 -49.67 142.33 -64 160 -64H512C529.67 -64 544 -49.67 544 -32V0C544 35.35 515.35 64 480 64zM336 -32C318.33 -32 304 -17.67 304 0S318.33 32 336 32S368 17.67 368 0S353.67 -32 336 -32z" />
<glyph glyph-name="blender"
unicode="&#xF517;"
horiz-adv-x="512" d=" M416 64H160C124.65 64 96 35.35 96 0V-32C96 -49.67 110.33 -64 128 -64H448C465.67 -64 480 -49.67 480 -32V0C480 35.35 451.35 64 416 64zM288 -32C270.33 -32 256 -17.67 256 0S270.33 32 288 32S320 17.67 320 0S305.67 -32 288 -32zM328 384H494.54L512 448H48C21.49 448 0 426.51 0 400V240C0 213.49 21.49 192 48 192H151.27L160 96H416L433.46 160H328C323.58 160 320 163.58 320 168V184C320 188.42 323.58 192 328 192H442.18L459.64 256H328C323.58 256 320 259.5800000000001 320 264V280C320 284.42 323.58 288 328 288H468.36L485.82 352H328C323.58 352 320 355.58 320 360V376C320 380.42 323.58 384 328 384zM64 256V384H133.82L145.46 256H64z" />
@@ -246,6 +249,9 @@
<glyph glyph-name="bong"
unicode="&#xF55C;"
horiz-adv-x="448" d=" M302.5 -64C325.68 -64 346.93 -51.42 358.5 -31.34C374.69 -3.26 384 29.25 384 64C384 100.12 373.92 133.81 356.56 162.62L400 206.06L409.38 196.68C415.63 190.43 425.76 190.43 432.01 196.68L443.31 208C449.56 214.25 449.56 224.38 443.31 230.63L390.62 283.32C384.37 289.57 374.24 289.57 367.99 283.32L356.68 272.01C350.43 265.76 350.43 255.63 356.68 249.38L366.06 240L326.65 200.59C315.09 211.96 302.12 221.92 288 230.1V384.26L303.9700000000001 384.28C312.79 384.29 319.9400000000001 391.44 319.9500000000001 400.26L319.9900000000001 431.98C320 440.83 312.82 448.01 303.9700000000001 448L80.03 447.74C71.21 447.73 64.06 440.58 64.05 431.76L64.01 400.03C64 391.18 71.18 384.01 80.03 384.02L96 384.04V230.11C38.67 196.9 0 135.03 0 64C0 29.25 9.31 -3.27 25.5 -31.34C37.08 -51.42 58.33 -64 81.5 -64H302.5zM120.06 188.57L144 202.44V384.0900000000001L240 384.2V202.44L263.94 188.57C288.75 174.2 308.06 152.84 320.5 128H63.5C75.95 152.84 95.25 174.2 120.06 188.57z" />
<glyph glyph-name="book-dead"
unicode="&#xF6B7;"
horiz-adv-x="448" d=" M272 312C280.84 312 288 319.16 288 328S280.84 344 272 344S256 336.8400000000001 256 328S263.1600000000001 312 272 312zM448 89.6V422.4C448 438.4 438.4 448 422.4 448H96C41.6 448 0 406.4 0 352V32C0 -22.4 41.6 -64 96 -64H422.4C435.2 -64 448 -54.4 448 -38.4V-22.4C448 -16 444.8 -9.6 438.4 -3.2C435.2 12.8 435.2 57.6 438.4 70.4C444.8 73.6 448 80 448 89.6zM240 392C284.18 392 320 363.35 320 328C320 307.13 307.32 288.77 288 277.0900000000001V264C288 255.16 280.84 248 272 248H208C199.16 248 192 255.16 192 264V277.0900000000001C172.68 288.77 160 307.13 160 328C160 363.35 195.82 392 240 392zM129.05 214.15A7.996000000000001 7.996000000000001 0 0 0 124.85 224.65L131.14 239.35A7.995 7.995 0 0 0 141.65 243.55L240 201.4L338.35 243.55C342.4100000000001 245.29 347.12 243.4100000000001 348.86 239.35L355.1500000000001 224.65A7.996000000000001 7.996000000000001 0 0 0 350.9500000000001 214.15L280.6 184L350.9400000000001 153.85A7.996000000000001 7.996000000000001 0 0 0 355.1400000000001 143.35L348.85 128.65A8.008 8.008 0 0 0 338.3400000000001 124.4400000000001L240 166.6L141.65 124.4500000000001A8.003 8.003 0 0 0 131.14 128.66L124.85 143.36A7.996000000000001 7.996000000000001 0 0 0 129.05 153.86L199.4 184L129.05 214.15zM380.8 0H96C76.8 0 64 12.8 64 32S80 64 96 64H380.8V0zM208 312C216.84 312 224 319.16 224 328S216.84 344 208 344S192 336.8400000000001 192 328S199.16 312 208 312z" />
<glyph glyph-name="book-open"
unicode="&#xF518;"
horiz-adv-x="576" d=" M542.22 415.95C487.42 412.8400000000001 378.5 401.52 311.26 360.36C306.62 357.52 303.99 352.4700000000001 303.99 347.19V-16.68C303.99 -28.23 316.62 -35.53 327.27 -30.17C396.45 4.65 496.5 14.15 545.97 16.75C562.86 17.64 575.99 31.18 575.99 47.41V385.25C576 402.96 560.64 416.99 542.22 415.95zM264.73 360.36C197.5 401.52 88.58 412.83 33.78 415.95C15.36 416.99 0 402.96 0 385.25V47.4C0 31.16 13.13 17.62 30.02 16.74C79.51 14.1399999999999 179.61 4.6299999999999 248.79 -30.21C259.4100000000001 -35.5600000000001 272 -28.27 272 -16.7500000000001V347.37C272 352.6600000000001 269.38 357.51 264.73 360.36z" />
@@ -287,7 +293,7 @@
horiz-adv-x="640" d=" M150.94 256H184.67C195.68 256 203.28 266.8300000000001 199.53 277.18C194.6 290.76 191.98 305.16 191.98 320S194.6 349.24 199.53 362.82C203.29 373.17 195.68 384 184.67 384H150.94C143.93 384 137.48 379.51 135.53 372.77C130.64 355.79 128 338.12 128 320C128 301.88 130.64 284.2100000000001 135.54 267.24C137.48 260.5 143.93 256 150.94 256zM89.92 424.6600000000001C95.56 435.28 87.97 448 75.96 448H40.63C34.36 448 28.49 444.4100000000001 25.89 438.69C9.4 402.46 0 362.35 0 320C0 295.25 3.12 251.67 26.69 201.14C29.31 195.51 35.11 192 41.3 192H76.14C88.16 192 95.75 204.74 90.09 215.37C40.31 308.69 73.38 393.52 89.92 424.66zM614.06 438.71C611.46 444.42 605.6 448 599.33 448H563.9100000000001C551.9300000000001 448 544.2500000000001 435.34 549.8900000000001 424.75C568.1600000000001 390.46 598.3100000000001 305.33 550.1700000000001 215.52C544.45 204.84 551.97 192 564.08 192H599.3100000000001C605.58 192 611.44 195.58 614.0400000000001 201.29C630.57 237.52 640 277.64 640 320S630.58 402.48 614.06 438.71zM489.06 384H455.33C444.32 384 436.72 373.17 440.47 362.82C445.4 349.24 448.02 334.84 448.02 320S445.4 290.76 440.47 277.18C436.71 266.8300000000001 444.32 256 455.33 256H489.06C496.08 256 502.52 260.49 504.47 267.24C509.37 284.2100000000001 512 301.88 512 320C512 338.12 509.36 355.79 504.46 372.76C502.52 379.51 496.07 384 489.06 384zM372.76 283.88C379.81 294.17 383.96 306.5900000000001 383.96 320C383.96 355.35 355.33 384 320 384C284.68 384 256.04 355.35 256.04 320C256.04 306.5900000000001 260.19 294.17 267.24 283.88L136.74 -29.53C133.34 -37.68 137.2 -47.05 145.35 -50.45L174.86 -62.76C183.01 -66.1600000000001 192.38 -62.3000000000001 195.77 -54.15L244.96 64H395.03L444.23 -54.15C447.63 -62.31 456.99 -66.16 465.14 -62.76L494.65 -50.45C502.8 -47.05 506.65 -37.68 503.26 -29.53L372.76 283.8800000000001zM271.62 128L320 244.19L368.38 128H271.62z" />
<glyph glyph-name="broom"
unicode="&#xF51A;"
horiz-adv-x="512" d=" M10.8 200.8C-0.7 196.2 -3.7 181.3 5 172.6L59.8 117.8L133 142.2L108.6 69L236.6 -59C245.4 -67.7999999999999 260.2 -64.7 264.8 -53.2L362.9 190.5L254.5 298.9L10.8 200.8zM507.3 420.7L484.7 443.3C478.5 449.6 468.3 449.6 462.1 443.3L359.8 341.1L319.4000000000001 381.5C315.2000000000001 385.8 308.0000000000001 384.5 305.5000000000001 379L278.3000000000001 320.4L384.4000000000001 214.3L443.0000000000001 241.5C448.4000000000001 244 449.7000000000001 251.2 445.5000000000001 255.4L405.1000000000002 295.8L507.3 398.1C513.6 404.3 513.6 414.4 507.3 420.7z" />
horiz-adv-x="640" d=" M256.4700000000001 231.23L343.2000000000001 122.05S326.6 19.6899999999999 266.6300000000001 -28.07C206.66 -75.85 0 -62.19 0 -62.19S3.8 -39.05 11 -6.76L105.62 105.41C109.59 110.11 104.75 117.03 98.97 114.91L38.57 92.8200000000001C53.01 134.48 71.29 172.8600000000001 93.17 190.2900000000001C153.14 238.0500000000001 256.4700000000001 231.2300000000001 256.4700000000001 231.2300000000001zM636.53 416.9700000000001L616.67 441.9700000000001C611.18 448.87 601.15 450.02 594.26 444.53L361.78 266.73L327.64 309.7C322.55 316.11 312.5 314.91 309.05 307.49L283.7200000000001 252.94L370.4500000000001 143.76L429.2500000000001 156.21C437.2500000000001 157.9 440.6700000000001 167.41 435.5900000000001 173.81L401.5 216.73L633.98 394.5300000000001C640.87 400.0100000000001 642.02 410.0600000000001 636.53 416.9700000000001z" />
<glyph glyph-name="brush"
unicode="&#xF55D;"
horiz-adv-x="384" d=" M352 448H32C14.33 448 0 433.67 0 416V192H384V416C384 433.67 369.67 448 352 448zM0 128C0 92.65 28.66 64 64 64H128V0C128 -35.35 156.66 -64 192 -64S256 -35.35 256 0V64H320C355.3400000000001 64 384 92.65 384 128V160H0V128zM192 24C205.25 24 216 13.26 216 0C216 -13.25 205.25 -24 192 -24S168 -13.25 168 0C168 13.26 178.75 24 192 24z" />
@@ -342,6 +348,9 @@
<glyph glyph-name="camera"
unicode="&#xF030;"
horiz-adv-x="512" d=" M512 304V16C512 -10.5 490.5 -32 464 -32H48C21.5 -32 0 -10.5 0 16V304C0 330.5 21.5 352 48 352H136L148.3 384.9C155.3 403.6 173.2 416 193.2 416H318.7000000000001C338.7000000000001 416 356.6 403.6 363.6 384.9L376 352H464C490.5 352 512 330.5 512 304zM376 160C376 226.2 322.2 280 256 280S136 226.2 136 160S189.8 40 256 40S376 93.8 376 160zM344 160C344 111.5 304.5 72 256 72S168 111.5 168 160S207.5 248 256 248S344 208.5 344 160z" />
<glyph glyph-name="campground"
unicode="&#xF6BB;"
horiz-adv-x="640" d=" M624 0H599.32L359.54 330.25L412.9500000000001 403.8C418.1400000000001 410.95 416.5600000000001 420.96 409.4100000000001 426.15L383.5100000000001 444.94C376.3600000000001 450.13 366.3600000000001 448.55 361.1600000000001 441.39L320 384.7L278.83 441.4C273.64 448.55 263.63 450.14 256.48 444.95L230.6 426.15C223.45 420.96 221.86 410.95 227.06 403.8L280.47 330.25L40.68 0H16C7.16 0 0 -7.16 0 -16V-48C0 -56.84 7.16 -64 16 -64H624C632.84 -64 640 -56.84 640 -48V-16C640 -7.16 632.84 0 624 0zM320 160L436.36 0H203.64L320 160z" />
<glyph glyph-name="cannabis"
unicode="&#xF55F;"
horiz-adv-x="512" d=" M503.47 87.75C501.91 88.57 471.08 104.64 426.6900000000001 113.56C490.9400000000001 188.68 510.7400000000001 275.23 511.6200000000001 279.2C512.8000000000001 284.53 511.1800000000001 290.1 507.3200000000001 293.9700000000001C504.2900000000001 297.01 500.2 298.67 496.0000000000001 298.67C494.8600000000001 298.67 493.71 298.55 492.5600000000001 298.29C488.6800000000001 297.44 406.0200000000001 278.7 331.98 218.53C331.99 219.99 331.99 221.46 331.99 222.93C331.99 341.72 272.01 436.65 269.4600000000001 440.63A15.973000000000003 15.973000000000003 0 0 1 256 448C250.55 448 245.47 445.2200000000001 242.53 440.63C239.98 436.65 180 341.7200000000001 180 222.93C180 221.46 180.01 219.99 180.01 218.53C105.98 278.69 23.32 297.43 19.43 298.29C18.29 298.54 17.14 298.67 15.99 298.67C11.79 298.67 7.7 297.01 4.67 293.9700000000001A15.986 15.986 0 0 1 0.38 279.2C1.26 275.23 21.06 188.68 85.31 113.56C40.92 104.64 10.1 88.57 8.53 87.75A16.003 16.003 0 0 1 8.51 59.46C10.96 58.17 69.27 27.74 142 27.74C148.14 27.74 153.96 27.84 159.5 28.05C148.13 5.82 142.98 -10.26 142.69 -11.17C140.89 -16.85 142.4 -23.0599999999999 146.6 -27.28A16.019 16.019 0 0 1 162.7 -31.27C164.53 -30.7 200.42 -19.28 240 8.02V-56C240 -60.42 243.58 -64 248 -64H264C268.42 -64 272 -60.42 272 -56V8.01C311.58 -19.29 347.4700000000001 -30.7 349.3 -31.28A16.019 16.019 0 0 1 365.4000000000001 -27.29C369.6 -23.07 371.11 -16.86 369.3100000000001 -11.18C369.0200000000001 -10.27 363.8600000000001 5.81 352.5000000000001 28.04C358.0400000000001 27.83 363.8700000000001 27.73 370.0000000000001 27.73C442.7200000000001 27.73 501.0400000000001 58.16 503.4900000000001 59.4499999999999C508.7300000000001 62.2299999999999 512.0100000000001 67.67 512.0000000000001 73.5999999999999C511.9900000000001 79.5399999999999 508.7100000000001 84.9899999999999 503.4700000000001 87.7499999999999z" />
@@ -393,9 +402,15 @@
<glyph glyph-name="cart-plus"
unicode="&#xF217;"
horiz-adv-x="576" d=" M504.717 128H211.572L218.117 96H486.535C501.936 96 513.351 81.699 509.938 66.681L504.421 42.405C523.112 33.332 536 14.172 536 -8C536 -39.202 510.481 -64.444 479.176 -63.994C449.353 -63.565 424.826 -39.3630000000001 424.021 -9.547C423.581 6.74 430.106 21.502 440.824 32.001H231.176C241.553 21.835 248 7.674 248 -8C248 -39.813 221.472 -65.431 189.33 -63.938C160.79 -62.613 137.579 -39.553 136.079 -11.021C134.921 11.013 146.515 30.434 164.13 40.5650000000001L93.883 384H24C10.745 384 0 394.745 0 408V424C0 437.255 10.745 448 24 448H126.529C137.93 448 147.757 439.979 150.042 428.81L159.208 384H551.99C567.391 384 578.806 369.699 575.393 354.681L528.12 146.681C525.637 135.754 515.923 128 504.717 128zM408 280H360V320C360 328.837 352.837 336 344 336H328C319.163 336 312 328.837 312 320V280H264C255.163 280 248 272.837 248 264V248C248 239.163 255.163 232 264 232H312V192C312 183.163 319.163 176 328 176H344C352.837 176 360 183.163 360 192V232H408C416.837 232 424 239.163 424 248V264C424 272.837 416.837 280 408 280z" />
<glyph glyph-name="cat"
unicode="&#xF6BE;"
horiz-adv-x="512" d=" M290.59 256C270.41 256 183.77 254.02 128 170.05V256C128 308.94 84.94 352 32 352C14.33 352 0 337.67 0 320S14.33 288 32 288C49.64 288 64 273.64 64 256V0C64 -35.3 92.7 -64 128 -64H304C312.84 -64 320 -56.84 320 -48V-32C320 -14.33 305.67 0 288 0H256L384 96V-48C384 -56.84 391.1600000000001 -64 400 -64H432C440.84 -64 448 -56.84 448 -48V158.14C437.71 155.47 427.11 153.6 416 153.6C354.19 153.6 302.48 197.65 290.5900000000001 256zM448 352H384L320 416V281.6C320 228.58 362.98 185.6 416 185.6S512 228.58 512 281.6V416L448 352zM376 272C367.1600000000001 272 360 279.16 360 288S367.1600000000001 304 376 304S392 296.8400000000001 392 288S384.84 272 376 272zM456 272C447.1600000000001 272 440 279.16 440 288S447.1600000000001 304 456 304S472 296.8400000000001 472 288S464.84 272 456 272z" />
<glyph glyph-name="certificate"
unicode="&#xF0A3;"
horiz-adv-x="512" d=" M458.622 192.08L504.607 237.085C518.315 250.062 511.923 273.124 493.943 277.424L431.2930000000001 293.414L448.9540000000001 355.4290000000001C453.9450000000001 373.2670000000001 437.1250000000001 390.092 419.2930000000001 385.1L357.2990000000001 367.433L341.3150000000001 430.1040000000001C337.085 447.803 313.765 454.276 300.99 440.772L256 394.43L211.011 440.771C198.381 454.122 174.964 448.005 170.686 430.103L154.702 367.432L92.707 385.099C74.87 390.093 58.056 373.262 63.046 355.428L80.707 293.413L18.057 277.423C0.069 273.122 -6.31 250.056 7.392 237.085L53.377 192.08L7.392 147.076C-6.316 134.0990000000001 0.076 111.037 18.056 106.737L80.706 90.747L63.045 28.732C58.054 10.894 74.874 -5.931 92.706 -0.939L154.7 16.7280000000001L170.684 -45.9429999999999C175.123 -64.5179999999999 198.38 -69.9609999999999 211.009 -56.6109999999999L256 -10.61L300.989 -56.611C313.489 -70.0989999999999 336.976 -64.097 341.314 -45.943L357.298 16.728L419.2919999999999 -0.939C437.128 -5.933 453.9429999999999 10.898 448.9529999999999 28.732L431.2919999999999 90.747L493.9419999999999 106.737C511.9289999999999 111.0390000000001 518.3079999999999 134.1040000000001 504.6059999999999 147.076L458.6219999999999 192.08z" />
<glyph glyph-name="chair"
unicode="&#xF6C0;"
horiz-adv-x="448" d=" M446.33 106.12L435.66 138.12A31.996 31.996 0 0 1 405.3 160H42.69C28.92 160 16.69 151.19 12.33 138.12L1.66 106.12C-5.24 85.4 10.18 64 32.03 64H32V-48C32 -56.84 39.16 -64 48 -64H80C88.84 -64 96 -56.84 96 -48V64H352V-48C352 -56.84 359.1600000000001 -64 368 -64H400C408.84 -64 416 -56.84 416 -48V64H415.9700000000001C437.8200000000001 64 453.24 85.4 446.3300000000001 106.12zM112 320C112 349.48 128.2 374.99 152 388.87V192H200V400H248V192H296V388.87C319.8 374.99 336 349.48 336 320V192H384V320C384 390.69 326.69 448 256 448H192C121.31 448 64 390.69 64 320V192H112V320z" />
<glyph glyph-name="chalkboard-teacher"
unicode="&#xF51C;"
horiz-adv-x="640" d=" M208 96C205.61 96 203.22 95.65 200.94 94.91C187.98 90.7 174.35 88 160 88C145.65 88 132.02 90.7 119.05 94.91C116.77 95.65 114.39 96 112 96C49.94 96 -0.33 45.52 0 -16.62C0.14 -42.88 21.73 -64 48 -64H272C298.27 -64 319.86 -42.88 320 -16.62C320.33 45.52 270.06 96 208 96zM160 128C213.02 128 256 170.98 256 224S213.02 320 160 320S64 277.02 64 224S106.98 128 160 128zM592 448H208C181.53 448 160 425.75 160 398.41V352C183.42 352 205.1 345.2200000000001 224 334.2V384H576V96H512V160H384V96H307.76C326.86 79.31 340.88 57.27 347.45 32H592C618.47 32 640 54.25 640 81.59V398.41C640 425.75 618.47 448 592 448z" />
@@ -513,6 +528,12 @@
<glyph glyph-name="cloud-download-alt"
unicode="&#xF381;"
horiz-adv-x="640" d=" M537.6 221.4C541.7 232.1 544 243.8 544 256C544 309 501 352 448 352C428.3 352 409.9 346 394.7 335.8C367 383.8 315.3 416 256 416C167.6 416 96 344.4 96 256C96 253.3 96.1 250.6 96.2 247.9C40.2 228.2 0 174.8 0 112C0 32.5 64.5 -32 144 -32H512C582.7 -32 640 25.3 640 96C640 157.9 596 209.6 537.6 221.4zM404.7000000000001 132.7L299.3 27.3C293.1 21.1 282.9000000000001 21.1 276.7 27.3L171.3 132.7C161.2 142.8 168.4 160 182.6 160H248V272C248 280.8 255.2 288 264 288H312C320.8 288 328 280.8 328 272V160H393.4C407.6 160 414.8 142.8 404.7 132.7z" />
<glyph glyph-name="cloud-moon"
unicode="&#xF6C3;"
horiz-adv-x="640" d=" M342.75 95.32C348.49 104.91 352 116.01 352 128C352 163.35 323.35 192 288 192C270.79 192 255.23 185.12 243.73 174.07C227.39 203.7 196.23 224 160 224C106.98 224 64 181.02 64 128C64 126.05 64.46 124.22 64.57 122.3C27.08 109.23 0 73.95 0 32C0 -21.02 42.98 -64 96 -64H336C380.18 -64 416 -28.18 416 16C416 57.87 383.7200000000001 91.84 342.75 95.32zM628.01 124.74C523.78 105.52 428.06 182.9 428.06 284.77C428.06 343.4500000000001 460.51 397.4100000000001 513.24 426.4700000000001C521.37 430.95 519.32 442.88 510.09 444.53C497.14 446.83 484 448 470.84 448C352.25 448 256 354.96 256 240C256 232.74 256.4 225.56 257.15 218.49C267.02 221.87 277.33 224 288 224C340.94 224 384 180.94 384 128C384 124.41 383.79 120.83 383.37 117.27C416.86 101.88 440.8400000000001 70.72 446.61 33.41C454.57 32.54 462.64 31.9999999999999 470.84 31.9999999999999C537.1 31.9999999999999 597.63 61.1899999999999 637.72 109.0199999999999C643.65 116.0899999999999 637.1800000000001 126.43 628.01 124.74z" />
<glyph glyph-name="cloud-sun"
unicode="&#xF6C4;"
horiz-adv-x="640" d=" M342.75 95.32C348.49 104.91 352 116.01 352 128C352 163.35 323.35 192 288 192C270.79 192 255.23 185.12 243.73 174.07C227.39 203.69 196.23 224 160 224C106.98 224 64 181.02 64 128C64 126.05 64.46 124.22 64.57 122.3C27.08 109.23 0 73.95 0 32C0 -21.02 42.98 -64 96 -64H336C380.18 -64 416 -28.18 416 16C416 57.87 383.7200000000001 91.84 342.75 95.32zM585.94 195.12C578.09 201.91 578.09 214.09 585.94 220.88L633.41 262C646.17 273.05 639.25 294.02 622.41 295.3L560.8199999999999 299.9700000000001C550.6299999999999 300.75 543.54 310.4600000000001 545.92 320.4L560.87 382.88C564.76 399.14 546.91 411.9 532.79 402.95L480.28 369.69C471.67 364.23 460.22 367.94 456.4299999999999 377.41L432.9599999999999 436.15C426.64 451.96 404.7699999999999 451.96 398.45 436.15L375.07 377.66C371.24 368.07 359.63 364.31 350.8999999999999 369.8400000000001L298.6099999999999 402.96C284.4799999999999 411.91 266.6299999999999 399.15 270.5299999999999 382.89L285.4799999999999 320.41C287.8599999999999 310.4700000000001 280.7799999999999 300.76 270.58 299.98L209.4299999999999 295.3400000000001C192.4299999999999 294.05 185.4399999999999 272.88 198.3299999999999 261.7200000000001L229.5599999999999 234.67C237.3799999999999 229.5 244.7699999999999 223.66 251.3399999999999 216.83C262.76 221.54 275.07 224.01 287.7099999999999 224.01C293.68 224.01 299.4799999999999 223.3 305.1499999999999 222.25C312.2399999999999 277.23 358.83 320.01 415.7099999999999 320.01C477.4699999999999 320.01 527.7099999999999 269.77 527.7099999999999 208.01S477.4699999999999 96.01 415.7099999999999 96.01C414.76 96.01 413.88 96.27 412.94 96.29C426.7699999999999 83.09 437.55 66.8199999999999 443.1 48.01H470.1199999999999C476.3699999999999 48.01 482.49 46.18 487.72 42.74L532.8 13.06C546.99 4.07 564.6899999999999 17.23 560.7199999999999 33.82L546.0299999999999 95.2C543.5999999999999 105.36 550.8299999999998 115.28 561.2499999999999 116.07L622.4099999999999 120.71C639.2499999999999 121.99 646.1699999999998 142.96 633.4099999999999 154.01L585.9399999999998 195.12zM383.2800000000001 135.18C393.3 130.66 404.32 128 416 128C460.11 128 496 163.89 496 208S460.11 288 416 288C372.75 288 337.61 253.44 336.25 210.51C362.69 194.98 380.8400000000001 167.38 383.28 135.18z" />
<glyph glyph-name="cloud-upload-alt"
unicode="&#xF382;"
horiz-adv-x="640" d=" M537.6 221.4C541.7 232.1 544 243.8 544 256C544 309 501 352 448 352C428.3 352 409.9 346 394.7 335.8C367 383.8 315.3 416 256 416C167.6 416 96 344.4 96 256C96 253.3 96.1 250.6 96.2 247.9C40.2 228.2 0 174.8 0 112C0 32.5 64.5 -32 144 -32H512C582.7 -32 640 25.3 640 96C640 157.9 596 209.6 537.6 221.4zM393.4 160H328V48C328 39.2 320.8 32 312 32H264C255.2 32 248 39.2 248 48V160H182.6C168.3 160 161.2 177.2 171.3 187.3L276.7 292.7000000000001C282.9 298.9 293.1 298.9 299.3 292.7000000000001L404.7000000000001 187.3C414.8000000000001 177.2 407.6 160 393.4000000000001 160z" />
@@ -636,6 +657,12 @@
<glyph glyph-name="diagnoses"
unicode="&#xF470;"
horiz-adv-x="640" d=" M496 192C504.8 192 512 199.2 512 208S504.8 224 496 224S480 216.8 480 208S487.2 192 496 192zM320 272C368.5 272 408 311.5 408 360S368.5 448 320 448S232 408.5 232 360S271.5 272 320 272zM59.8 84C70 68.7 89.1 66.2 102.7 74.2C118.9 83.8 158.9 105.9 208 122.8V32H432V122.7C481.1 105.9 521.1 83.7 537.3 74.1C550.9 66.1 570 68.8 580.1999999999999 83.9L597.9999999999999 110.6C606.7999999999998 123.8 605.5999999999999 145.2 587.9999999999999 155.7C576.0999999999999 162.8 558.2999999999998 172.7 536.8999999999999 183.1C508.7999999999998 137 437.4999999999999 165.3 449.1999999999999 218.2C409.3 230.8 365.1 240 320 240C263 240 207.1 225.5 160 207.8C159.8 167.6 112.4 144.5 80.8 171.8C69.6 165.8 59.5 160.2 52.1 155.8C34.5 145.3 33.3 124 42.1 110.7L59.8 84zM368 104C381.3 104 392 93.3 392 80S381.3 56 368 56S344 66.7 344 80S354.7 104 368 104zM272 200C285.3 200 296 189.3 296 176S285.3 152 272 152S248 162.7 248 176S258.7 200 272 200zM112 192C120.8 192 128 199.2 128 208S120.8 224 112 224S96 216.8 96 208S103.2 192 112 192zM624 0H16C7.2 0 0 -7.2 0 -16V-48C0 -56.8 7.2 -64 16 -64H624C632.8 -64 640 -56.8 640 -48V-16C640 -7.2 632.8 0 624 0z" />
<glyph glyph-name="dice-d20"
unicode="&#xF6CF;"
horiz-adv-x="480" d=" M106.75 232.94L1.2 77.05C-1.88 72.05 1.3 65.55 7.13 64.91L215.39 42.84L106.75 232.9400000000001zM7.41 132.57L82.7 254.92L6.06 300.9C3.39 302.5 0 300.5800000000001 0 297.4700000000001V134.66C0 130.63 5.29 129.13 7.41 132.57zM18.25 24.4L212.65 -63.26C217.95 -65.71 224 -61.83 224 -56V9.67L20.45 31.97C16 32.47 14.22 26.3800000000001 18.25 24.4zM99.47 282.18L179.4 425.12C183.74 432.18 175.81 440.37 168.62 436.26L17.81 337.65C15.34 336.03 15.42 332.39 17.94 330.87L99.47 282.18zM240 272H349.21L253.63 440.38C250.5 445.46 245.25 448 240 448S229.5 445.46 226.37 440.38L130.79 272H240zM473.94 300.9L397.3 254.91L472.59 132.56C474.7 129.12 480.0000000000001 130.62 480.0000000000001 134.66V297.4700000000001C480.0000000000001 300.5800000000001 476.6100000000001 302.5 473.9400000000001 300.9zM380.53 282.18L462.0599999999999 330.88C464.5899999999999 332.4 464.66 336.04 462.1899999999999 337.6600000000001L311.38 436.26C304.19 440.37 296.26 432.18 300.6 425.12L380.53 282.18zM459.55 31.97L256 9.68V-55.99C256 -61.83 262.05 -65.7 267.35 -63.25L461.75 24.41C465.78 26.38 464 32.47 459.55 31.97zM373.25 232.9400000000001L264.62 42.84L472.8799999999999 64.91C478.7099999999999 65.56 481.8899999999999 72.05 478.8099999999999 77.05L373.25 232.94zM240 240H139.57L240 64.25L340.43 240H240z" />
<glyph glyph-name="dice-d6"
unicode="&#xF6D1;"
horiz-adv-x="448" d=" M422.19 338.05L256.21 438.93C236.3 451.03 211.69 451.03 191.78 438.93L25.81 338.05C20.49 334.82 20.52 326.78 25.87 323.5900000000001L224 205.45L422.14 323.59C427.49 326.78 427.52 334.81 422.19 338.05zM436.03 293.42L240 176.54V-47.28C240 -60.16 253.39 -68.1899999999999 264.05 -61.71L416.2100000000001 30.77C435.8900000000001 42.73 448.0000000000001 64.71 448.0000000000001 88.47V286.17C448.0000000000001 292.5800000000001 441.3600000000001 296.6 436.0300000000001 293.42zM0 286.17V88.47C0 64.7000000000001 12.11 42.73 31.79 30.77L183.95 -61.6999999999999C194.62 -68.1799999999999 208 -60.1599999999999 208 -47.2699999999999V176.54L11.97 293.42C6.64 296.6 0 292.5800000000001 0 286.17z" />
<glyph glyph-name="dice-five"
unicode="&#xF523;"
horiz-adv-x="448" d=" M384 416H64C28.65 416 0 387.35 0 352V32C0 -3.35 28.65 -32 64 -32H384C419.35 -32 448 -3.35 448 32V352C448 387.35 419.35 416 384 416zM128 64C110.33 64 96 78.33 96 96S110.33 128 128 128S160 113.67 160 96S145.67 64 128 64zM128 256C110.33 256 96 270.3300000000001 96 288S110.33 320 128 320S160 305.67 160 288S145.67 256 128 256zM224 160C206.33 160 192 174.33 192 192S206.33 224 224 224S256 209.67 256 192S241.67 160 224 160zM320 64C302.33 64 288 78.33 288 96S302.33 128 320 128S352 113.67 352 96S337.67 64 320 64zM320 256C302.33 256 288 270.3300000000001 288 288S302.33 320 320 320S352 305.67 352 288S337.67 256 320 256z" />
@@ -672,6 +699,9 @@
<glyph glyph-name="dna"
unicode="&#xF471;"
horiz-adv-x="448" d=" M0.1 -46.1C-1 -55.6 6.4 -63.9 16 -63.9L48.3 -64C56.4 -64 63.2 -58.1 64.3 -50.1C65 -45.2 66.1 -39 67.7 -32H380C381.6 -38.9 382.9 -45.2 383.5 -50.1C384.6 -58.1 391.4 -64.1 399.5 -64L431.8 -63.9C441.4000000000001 -63.9 448.9000000000001 -55.6 447.7 -46.1C443.1 -8.2 422.1 82.9 328.8 161.6C311.2 149.2000000000001 291.7 137.4 270.3 126.2000000000001C276.5 121.6 281.7 116.8000000000001 287.3 112.0000000000001H159.7C181 130.1000000000001 206.7 147.6000000000001 238.4 163.4C410.5 248.9 442.1 382.2 447.9 430.1C449 439.6 441.6 447.9 432 447.9L399.6 448C391.5 448 384.7000000000001 442.1 383.6 434.1C382.9000000000001 429.2 381.8 423 380.2000000000001 416H67.8C66.2 423 65.1 429.1 64.4 434.1C63.3 442.1 56.5 448.1 48.4 448L16.1 447.9C6.5 447.9 -1 439.6 0.1 430.1C5.3 387.2 31.4 276.2 160 192C31.5 107.8 5.3 -3.2 0.1 -46.1zM224 228.4C198.9 242.1 177.6 256.8 159.7 272H288.2C270.4 256.8 249.1 242 224 228.4zM355.1 352C349.3 341.6 342.3 330.9 334.1 320H114C105.7 330.9 98.7 341.6 93 352H355.1zM92.9 32C98.7 42.4 105.7 53.1 113.9 64H333.3C341.6 53.1 348.7 42.4 354.5 32H92.9z" />
<glyph glyph-name="dog"
unicode="&#xF6D3;"
horiz-adv-x="512" d=" M496 352H432L424.84 366.31A32 32 0 0 1 396.2200000000001 384H342.6L315.3200000000001 411.28C305.23 421.36 288 414.2200000000001 288 399.9700000000001V250.13L416 204.42V240H448C483.35 240 512 268.65 512 304V336C512 344.8400000000001 504.84 352 496 352zM384 304C375.1600000000001 304 368 311.16 368 320S375.1600000000001 336 384 336S400 328.8400000000001 400 320S392.84 304 384 304zM96 224C78.36 224 64 238.36 64 256C64 273.67 49.67 288 32 288S0 273.67 0 256C0 214.34 26.83 179.15 64 165.9V-48C64 -56.84 71.16 -64 80 -64H144C152.84 -64 160 -56.84 160 -48V64H320V-48C320 -56.84 327.1600000000001 -64 336 -64H400C408.84 -64 416 -56.84 416 -48V170.45L266.05 224H96z" />
<glyph glyph-name="dollar-sign"
unicode="&#xF155;"
horiz-adv-x="288" d=" M209.2 214.6L101.2 246.2C88.7 249.8 80 261.5 80 274.5C80 290.8 93.2 304 109.5 304H175.8C188 304 200 300.3 210 293.5C216.1 289.4 224.3 290.4 229.5 295.5L264.3 329.5C271.4000000000001 336.4 270.4000000000001 347.9 262.5 354C238 373.2 207.4 383.9 176 384V432C176 440.8 168.8 448 160 448H128C119.2 448 112 440.8 112 432V384H109.5C45.8 384 -5.4 329.3 0.5 264.4C4.7 218.3 39.9 180.8 84.3 167.8L186.8 137.8C199.3 134.1 208 122.5 208 109.5C208 93.2 194.8 80 178.5 80H112.2C100 80 88 83.7 78 90.5C71.9 94.6 63.7 93.6 58.5 88.5L23.7 54.5C16.6 47.6 17.6 36.1 25.5 30C50 10.8 80.6 0.1 112 0V-48C112 -56.8 119.2 -64 128 -64H160C168.8 -64 176 -56.8 176 -48V0.2C222.6 1.1 266.3 28.8 281.7 72.9C303.2 134.5 267.1 197.7 209.2 214.6z" />
@@ -702,6 +732,9 @@
<glyph glyph-name="drafting-compass"
unicode="&#xF568;"
horiz-adv-x="512" d=" M457.01 103.58C431.96 83.25 404.38 66.4 374.47 54.53L428.85 -39.66L482.8 -62.7C492.61 -66.8900000000001 503.6899999999999 -60.4900000000001 504.97 -49.9L511.99 8.35L457.0099999999999 103.58zM499.5 198.14C504.36 205.81 501.39 216.13 493.45 220.53L465.38 236.1C457.9 240.25 448.77 237.56 444.12 230.38C403.01 166.85 332.25 128 256 128C232.07 128 208.77 132.25 186.59 139.53L253.95 256.21C254.65 256.19 255.29 256 255.99 256S257.34 256.19 258.03 256.21L309.12 167.71C340.35 176.67 368.68 193.46 391.73 216.63L339.94 306.34C347.39 319.9700000000001 352 335.37 352 352C352 405.02 309.02 448 256 448S160 405.02 160 352C160 335.37 164.61 319.9700000000001 172.05 306.3400000000001L103.75 188.03C91.2 199.64 79.79 212.62 70.07 227.03C65.28 234.13 56.1 236.65 48.69 232.36L20.94 216.29C13.09 211.75 10.31 201.39 15.3 193.82C30.87 170.18 49.99 149.61 71.28 131.8L0 8.34L7.02 -49.91C8.3 -60.5 19.38 -66.9 29.19 -62.71L83.14 -39.67L153.94 82.96C186.13 70.72 220.62 64 256 64C355.05 64 446.88 115.01 499.5 198.14zM256 384C273.67 384 288 369.67 288 352S273.67 320 256 320S224 334.33 224 352S238.33 384 256 384z" />
<glyph glyph-name="dragon"
unicode="&#xF6D5;"
horiz-adv-x="640" d=" M18.32 192.22L192 224.04L100.72 155.35C90.64 145.2700000000001 97.78 128.04 112.03 128.04H334.73C325.29 154.44 320 182.51 320 211.42V253.6900000000001L200.27 341.29C176.45 357.17 144.98 355.3 123.21 336.7000000000001L5.81 220.36C-6.57 210.03 2.36 189.94 18.32 192.22zM575.19 158.12L474.5300000000001 208.43A47.992 47.992 0 0 0 448 251.35V288.04H512L540.09 265.41C546.09 259.41 554.23 256.04 562.72 256.04H593.69A32 32 0 0 1 622.3100000000001 273.73L636.62 302.35A32.005 32.005 0 0 1 633.6 335.86L559.07 435.24C553.02 443.3 543.54 448 533.47 448H296.02C288.89 448 285.32 439.43 290.36 434.39L352 384.04L292.42 359.2C286.5200000000001 356.25 286.5200000000001 347.8400000000001 292.42 344.89L352 320.04V211.42C352 139.34 388.03 72.03 448 32.04C252.41 25.23 103.44 -8.97 13.9 -28.87C5.78 -30.67 0 -37.88 0 -46.2C0 -56 7.95 -64 17.76 -64H516.84C580.13 -64.01 636.45 -16.44 639.83 46.76C642.35 94.04 617.1 137.16 575.19 158.12zM489.18 381.75L534.83 370.3400000000001C532.08 359.43 522.36 351.45 510.7 352.08C497.7400000000001 352.79 484.85 364.61 489.1800000000001 381.75z" />
<glyph glyph-name="draw-polygon"
unicode="&#xF5EE;"
horiz-adv-x="448" d=" M384 96C383.65 96 383.33 95.9 382.98 95.9L343.7800000000001 161.22C348.85 170.39 352.0000000000001 180.78 352.0000000000001 192S348.8600000000001 213.61 343.7800000000001 222.78L382.98 288.1C383.3300000000001 288.0900000000001 383.6500000000001 288 384 288C419.35 288 448 316.65 448 352S419.35 416 384 416C360.37 416 339.96 403.05 328.88 384H119.12C108.04 403.05 87.63 416 64 416C28.65 416 0 387.35 0 352C0 328.37 12.95 307.9600000000001 32 296.88V87.13C12.95 76.04 0 55.63 0 32C0 -3.35 28.65 -32 64 -32C87.63 -32 108.04 -19.05 119.12 0H328.87C339.96 -19.05 360.36 -32 383.99 -32C419.3400000000001 -32 447.99 -3.35 447.99 32C448 67.35 419.35 96 384 96zM96 87.12V296.88A63.824999999999996 63.824999999999996 0 0 1 119.12 320H327.48L289.0200000000001 255.9C288.67 255.91 288.35 256 288.0000000000001 256C252.6500000000001 256 224.0000000000001 227.35 224.0000000000001 192S252.6500000000001 128 288.0000000000001 128C288.3500000000001 128 288.6700000000001 128.1 289.0200000000001 128.1L327.48 64H119.12A63.748000000000005 63.748000000000005 0 0 1 96 87.12zM272 192C272 200.82 279.18 208 288 208S304 200.82 304 192S296.82 176 288 176S272 183.18 272 192zM400 352C400 343.18 392.82 336 384 336S368 343.18 368 352S375.18 368 384 368S400 360.82 400 352zM64 368C72.82 368 80 360.82 80 352S72.82 336 64 336S48 343.18 48 352S55.18 368 64 368zM48 32C48 40.82 55.18 48 64 48S80 40.82 80 32S72.82 16 64 16S48 23.18 48 32zM384 16C375.18 16 368 23.18 368 32S375.18 48 384 48S400 40.82 400 32S392.82 16 384 16z" />
@@ -711,9 +744,15 @@
<glyph glyph-name="drum"
unicode="&#xF569;"
horiz-adv-x="576" d=" M458.08 327.12L560.47 388.55C575.63 397.64 580.53 417.3 571.44 432.46C562.34 447.61 542.7 452.53 527.53 443.43L366.84 347.02A629.3200000000002 629.3200000000002 0 0 1 288 352C128.94 352 0 294.69 0 224V63.17C0 32.71 24.03 4.77 64 -17.2V79.17C64 96.77 78.4 111.17 96 111.17S128 96.77 128 79.17V-43.24C165.4 -54.37 209 -61.68 256 -63.99V47.16C256 64.7600000000001 270.4 79.16 288 79.16S320 64.7600000000001 320 47.16V-64C367 -61.69 410.6 -54.38 448 -43.25V79.16C448 96.7600000000001 462.4 111.16 480 111.16S512 96.7600000000001 512 79.16V-17.21C551.97 4.76 576 32.7 576 63.16V223.99C575.99 266.37 529.46 303.8300000000001 458.08 327.12zM288 144C155.45 144 48 179.82 48 224S155.45 304 288 304C290.34 304 292.62 303.9 294.94 303.88L207.53 251.44C192.37 242.35 187.47 222.69 196.56 207.53C206.12 191.6 226.07 187.92 240.47 196.56L403.18 294.18C477.55 280.5900000000001 528 254.26 528 223.99C528 179.81 420.54 144 288 144z" />
<glyph glyph-name="drumstick-bite"
unicode="&#xF6D7;"
horiz-adv-x="512" d=" M462.79 398.43C396.6500000000001 464.52 289.43 464.52 223.29 398.43C187.81 362.98 160.12 320 160.12 256V170.17L119.5 129.5800000000001C109.8 119.8900000000001 95.46 118.5100000000001 82.72 123.6C61 132.28 35.3 127.8900000000001 17.7 110.31C-5.91 86.72 -5.91 48.47 17.7 24.88C32.98 9.61 54.23 5.3 73.84 9.79C69.34 -9.81 73.66 -31.04 88.94 -46.31C112.55 -69.9 150.82 -69.9 174.43 -46.31C192.03 -28.73 196.42 -3.05 187.74 18.66C182.65 31.39 184.02 45.71 193.73 55.41L234.35 96H320.24C343.44 96 363.81 99.72 382.13 106.03C342.49 149.92 342.3 216.26 383.18 257.1C417.56 291.46 469.94 296.56 511.92 273.9C513.22 318.83 497.11 364.15 462.79 398.43z" />
<glyph glyph-name="dumbbell"
unicode="&#xF44B;"
horiz-adv-x="640" d=" M104 352H56C42.7 352 32 341.3 32 328V224H8C3.6 224 0 220.4 0 216V168C0 163.6 3.6 160 8 160H32V56C32 42.7 42.7 32 56 32H104C117.3 32 128 42.7 128 56V328C128 341.3 117.3 352 104 352zM632 224H608V328C608 341.3 597.3 352 584 352H536C522.7 352 512 341.3 512 328V56C512 42.7 522.7 32 536 32H584C597.3 32 608 42.7 608 56V160H632C636.4 160 640 163.6 640 168V216C640 220.4 636.4 224 632 224zM456 416H408C394.7 416 384 405.3 384 392V224H256V392C256 405.3 245.3 416 232 416H184C170.7 416 160 405.3 160 392V-8C160 -21.3 170.7 -32 184 -32H232C245.3 -32 256 -21.3 256 -8V160H384V-8C384 -21.3 394.7 -32 408 -32H456C469.3 -32 480 -21.3 480 -8V392C480 405.3 469.3 416 456 416z" />
<glyph glyph-name="dungeon"
unicode="&#xF6D9;"
horiz-adv-x="512" d=" M128.73 252.68L45.92 304.44C37.88 309.4600000000001 26.93 306.61 22.99 297.99A254.18999999999997 254.18999999999997 0 0 1 0.54 208.72C-0.05 199.63 7.59 192 16.69 192H113.82C121.78 192 127.9 198.25 128.83 206.16C129.92 215.49 132.07 224.49 135.07 233.1C137.63 240.44 135.32 248.56 128.73 252.68zM319.03 440C298.86 445.18 277.77 448 256 448S213.14 445.18 192.97 440C183.8 437.65 179.06 427.4 182.58 418.61L220.05 314.58A16.003 16.003 0 0 1 235.1 304H276.9C283.65 304 289.67 308.23 291.95 314.5800000000001L329.42 418.61C332.94 427.4000000000001 328.2 437.64 319.03 440zM112 160H16C7.16 160 0 152.84 0 144V80C0 71.16 7.16 64 16 64H112C120.84 64 128 71.16 128 80V144C128 152.84 120.84 160 112 160zM112 32H16C7.16 32 0 24.84 0 16V-48C0 -56.84 7.16 -64 16 -64H112C120.84 -64 128 -56.84 128 -48V16C128 24.84 120.84 32 112 32zM189.31 315.67L152.99 406.4700000000001C149.46 415.3 138.86 419.4600000000001 130.57 414.7800000000001A257.308 257.308 0 0 1 58.96 354.89C52.9 347.5700000000001 55.11 336.4100000000001 63.18 331.37L146.11 279.54C152.62 275.4700000000001 160.77 276.92 166.22 282.3300000000001C171.4 287.48 177.01 292.18 183.01 296.38C189.29 300.79 192.16 308.55 189.31 315.67zM398.18 192H495.31C504.41 192 512.05 199.63 511.46 208.72A254.13500000000002 254.13500000000002 0 0 1 489.01 297.99C485.07 306.61 474.12 309.4600000000001 466.08 304.44L383.27 252.68C376.68 248.56 374.37 240.44 376.93 233.1C379.94 224.49 382.08 215.48 383.17 206.16C384.1 198.25 390.2200000000001 192 398.18 192zM453.03 354.89A257.308 257.308 0 0 1 381.42 414.78C373.1400000000001 419.46 362.54 415.3 359 406.47L322.68 315.67C319.83 308.55 322.7 300.79 328.98 296.39C334.98 292.19 340.5900000000001 287.49 345.7700000000001 282.34C351.2100000000001 276.93 359.3700000000001 275.48 365.8800000000001 279.55L448.8100000000001 331.38C456.8800000000001 336.41 459.1000000000001 347.57 453.0300000000001 354.89zM496 160H400C391.1600000000001 160 384 152.84 384 144V80C384 71.16 391.1600000000001 64 400 64H496C504.84 64 512 71.16 512 80V144C512 152.84 504.84 160 496 160zM496 32H400C391.1600000000001 32 384 24.84 384 16V-48C384 -56.84 391.1600000000001 -64 400 -64H496C504.84 -64 512 -56.84 512 -48V16C512 24.84 504.84 32 496 32zM240 270.38V-24C240 -28.42 243.58 -32 248 -32H264C268.42 -32 272 -28.42 272 -24V270.38C266.77 271.27 261.48 272 256 272S245.23 271.27 240 270.38zM176 228.87V-24C176 -28.42 179.58 -32 184 -32H200C204.42 -32 208 -28.42 208 -24V258.64C195.22 251.19 184.16 241.17 176 228.87zM304 258.64V-24C304 -28.42 307.58 -32 312 -32H328C332.42 -32 336 -28.42 336 -24V228.87C327.84 241.17 316.78 251.19 304 258.64z" />
<glyph glyph-name="edit"
unicode="&#xF044;"
horiz-adv-x="576" d=" M402.6 364.8L492.8 274.6C496.6 270.8 496.6 264.6 492.8 260.8L274.4 42.4L181.6 32.1C169.2 30.7 158.7 41.2 160.1 53.6L170.4 146.4L388.8 364.8C392.6 368.6 398.8 368.6 402.6 364.8zM564.6 387.7L515.8000000000001 436.5C500.6000000000001 451.7 475.9000000000001 451.7 460.6000000000001 436.5L425.2000000000001 401.1C421.4000000000001 397.3 421.4000000000001 391.1 425.2000000000001 387.3L515.4000000000001 297.1C519.2 293.3 525.4000000000001 293.3 529.2 297.1L564.6 332.5C579.8000000000001 347.8 579.8000000000001 372.5 564.6 387.7zM384 101.8V0H64V320H293.8C297 320 300 321.3 302.3 323.5L342.3 363.5C349.9000000000001 371.1 344.5 384 333.8 384H48C21.5 384 0 362.5 0 336V-16C0 -42.5 21.5 -64 48 -64H400C426.5 -64 448 -42.5 448 -16V141.8C448 152.5 435.1 157.8 427.5 150.3L387.5 110.3C385.3 108 384 105 384 101.8z" />
@@ -816,6 +855,9 @@
<glyph glyph-name="file-contract"
unicode="&#xF56C;"
horiz-adv-x="384" d=" M224 312V448H24C10.7 448 0 437.3 0 424V-40C0 -53.3 10.7 -64 24 -64H360C373.3 -64 384 -53.3 384 -40V288H248C234.8 288 224 298.8 224 312zM64 376C64 380.42 67.58 384 72 384H152C156.42 384 160 380.42 160 376V360C160 355.58 156.42 352 152 352H72C67.58 352 64 355.58 64 360V376zM64 312C64 316.42 67.58 320 72 320H152C156.42 320 160 316.42 160 312V296C160 291.5800000000001 156.42 288 152 288H72C67.58 288 64 291.5800000000001 64 296V312zM256.81 64H304C312.84 64 320 56.84 320 48S312.84 32 304 32H256.81C240.36 32 225.54 41.14 218.17 55.86C215.22 61.78 210.08 62.38 208 62.38S200.78 61.79 197.98 56.19L190.31 40.85A15.986 15.986 0 0 0 176 32.0100000000001C175.62 32.0100000000001 175.25 32.03 174.8600000000001 32.0600000000001C168.4100000000001 32.5100000000001 162.8600000000001 36.8100000000001 160.8300000000001 42.95L144 93.41L133.39 61.53C127.5 43.87 111.01 32 92.39 32H80C71.16 32 64 39.16 64 48S71.16 64 80 64H92.39C97.22 64 101.5 67.08 103.03 71.66L121.22 126.3C124.52 136.11 133.66 142.71 144 142.71S163.48 136.1200000000001 166.77 126.3L180.65 84.66C200.42 100.85 234.7 94.36 246.65 70.5C248.67 66.44 252.61 64 256.81 64zM377 343L279.1 441C274.6 445.5 268.5 448 262.1 448H256V320H384V326.1C384 332.4 381.5 338.5 377 343z" />
<glyph glyph-name="file-csv"
unicode="&#xF6DD;"
horiz-adv-x="384" d=" M224 312V448H24C10.7 448 0 437.3 0 424V-40C0 -53.3 10.7 -64 24 -64H360C373.3 -64 384 -53.3 384 -40V288H248C234.8 288 224 298.8 224 312zM128 168C128 163.58 124.42 160 120 160H112C103.16 160 96 152.84 96 144V112C96 103.16 103.16 96 112 96H120C124.42 96 128 92.42 128 88V72C128 67.58 124.42 64 120 64H112C85.49 64 64 85.49 64 112V144C64 170.51 85.49 192 112 192H120C124.42 192 128 188.42 128 184V168zM172.27 64H160C155.58 64 152 67.58 152 72V88C152 92.42 155.58 96 160 96H172.27C178.22 96 182.68 99.5 182.68 102.62C182.68 103.92 181.93 105.28 180.56 106.46L158.67 125.23C150.2 132.45 145.34 142.71 145.34 153.37C145.34 174.67 164.36 191.99 187.75 191.99H200C204.42 191.99 208 188.41 208 183.99V167.99C208 163.5699999999999 204.42 159.99 200 159.99H187.73C181.78 159.99 177.32 156.49 177.32 153.37C177.32 152.0699999999999 178.07 150.7099999999999 179.44 149.53L201.33 130.76C209.8 123.54 214.66 113.28 214.66 102.62C214.67 81.33 195.66 64 172.27 64zM256 184V163.2C256 142.93 261.7 123.03 272 106.32C282.3 123.02 288 142.93 288 163.2V184C288 188.42 291.58 192 296 192H312C316.42 192 320 188.42 320 184V163.2C320 127.72 307.12 94.31 283.7200000000001 69.11C280.7000000000001 65.86 276.4500000000001 64 272 64S263.3 65.86 260.28 69.11C236.88 94.31 224 127.72 224 163.2000000000001V184C224 188.42 227.58 192 232 192H248C252.42 192 256 188.42 256 184zM377 343L279.1 441C274.6 445.5 268.5 448 262.1 448H256V320H384V326.1C384 332.4 381.5 338.5 377 343z" />
<glyph glyph-name="file-download"
unicode="&#xF56D;"
horiz-adv-x="384" d=" M224 312V448H24C10.7 448 0 437.3 0 424V-40C0 -53.3 10.7 -64 24 -64H360C373.3 -64 384 -53.3 384 -40V288H248C234.8 288 224 298.8 224 312zM300.45 100.64L204.03 4.94C197.38 -1.67 186.64 -1.67 179.99 4.94L83.57 100.64C73.42 110.71 80.54 128 94.82 128H160V208C160 216.84 167.16 224 176 224H208C216.84 224 224 216.84 224 208V128H289.18C303.46 128 310.58 110.71 300.45 100.64zM377 343L279.1 441C274.6 445.5 268.5 448 262.1 448H256V320H384V326.1C384 332.4 381.5 338.5 377 343z" />
@@ -894,6 +936,9 @@
<glyph glyph-name="fish"
unicode="&#xF578;"
horiz-adv-x="576" d=" M327.1 352C237.13 352 158.56 297.23 114.83 250.37L27.5 316.42C15.37 325.6 -2.74 315.82 0.36 301.76L24.54 192L0.35 82.23C-2.75 68.17 15.36 58.4 27.49 67.57L114.82 133.62C158.55 86.77 237.13 32 327.1 32C464.56 32 576 160 576 192S464.56 352 327.1 352zM414.5300000000001 168C401.2800000000001 168 390.5300000000001 178.75 390.5300000000001 192C390.5300000000001 205.26 401.2800000000001 216 414.5300000000001 216C427.79 216 438.5300000000001 205.26 438.5300000000001 192C438.5300000000001 178.75 427.7800000000001 168 414.5300000000001 168z" />
<glyph glyph-name="fist-raised"
unicode="&#xF6DE;"
horiz-adv-x="384" d=" M255.98 288V432C255.98 440.84 248.82 448 239.98 448H207.98C199.14 448 191.98 440.84 191.98 432V285.07C197 286.85 202.32 288 207.95 288H255.98zM383.98 192.01C383.9700000000001 227.35 355.32 256 319.99 256H207.85C199.07 256 191.95 248.93 191.95 240.15V239.59C191.95 213.32 213.25 192 239.52 192H274.78C284.46 192 287.98 188.42 287.98 184V167.8C287.98 163.51 284.39 160.0200000000001 280.1 159.8C235.58 157.5200000000001 215.94 135.09 184.05 87.25L177.74 77.78A7.993999999999999 7.993999999999999 0 0 0 166.65 75.56L153.34 84.4399999999999A7.993999999999999 7.993999999999999 0 0 0 151.12 95.5299999999999L157.43 104.9999999999999C173.16 128.6 187.63 148.2599999999999 204.74 163.0799999999999C187.47 168.5899999999999 173.34 181.1999999999999 165.87 197.5299999999999C159.28 194.1199999999999 151.91 192.0099999999999 144 192.0099999999999H111.9999999999999C99.6599999999999 192.0099999999999 88.51 196.8199999999999 79.9999999999999 204.4899999999999C71.48 196.81 60.33 192 48 192H16C10.36 192 5.03 193.15 0 194.95V117.02C0 83.07 13.48 50.52 37.49 26.51L63.99 0V-64H319.97V-0.04L355.88 35.88A96.035 96.035 0 0 1 384 103.79L383.98 192.01zM351.9700000000001 282.1V400C351.9700000000001 408.8400000000001 344.81 416 335.9700000000001 416H303.9700000000001C295.1300000000001 416 287.9700000000001 408.8400000000001 287.9700000000001 400V288H319.9700000000001C331.25 288 341.9100000000001 285.69 351.9700000000001 282.1zM16 224H48C56.84 224 64 231.16 64 240V368C64 376.8400000000001 56.84 384 48 384H16C7.16 384 0 376.8400000000001 0 368V240C0 231.16 7.16 224 16 224zM111.99 224H143.99C152.83 224 159.99 231.16 159.99 240V400C159.99 408.8400000000001 152.83 416 143.99 416H111.99C103.15 416 95.99 408.8400000000001 95.99 400V240C95.99 231.16 103.15 224 111.99 224z" />
<glyph glyph-name="flag-checkered"
unicode="&#xF11E;"
horiz-adv-x="512" d=" M466.515 381.072C487.731 390.926 512 375.449 512 352.056V108.956C512 98.43 506.839 88.549 498.157 82.598C462.32 58.034 423.822 41.74 375.652 41.74C308.279 41.74 264.022 76.523 210.435 76.523C159.582 76.523 124.311 66.465 96 54.401V-40C96 -53.255 85.255 -64 72 -64H56C42.745 -64 32 -53.255 32 -40V346.055C17.497 356.175 8 372.974 8 392C8 423.704 34.345 449.254 66.338 447.952C94.806 446.794 118.117 423.984 119.889 395.548C120.409 387.206 119.079 379.238 116.303 371.986C137.039 379.616 159.393 384 184.348 384C251.721 384 295.978 349.217 349.5650000000001 349.217C390.0610000000001 349.217 432.177 365.123 466.515 381.072zM96 313.37V242.88C125 253.55 147.18 260.71 169.6 263.79V335.36C146.1 333.19 129.16 325.57 96 313.37zM316.8 304.18C290.3830000000001 308.852 266.914 318.159 243.2 325.52V258.1C267.375 251.3940000000001 290.766 241.6560000000001 316.8 235.79V304.18zM169.6 263.79V193.75C202.396 196.728 223.51 194.385 243.2 189.95V258.1C217.953 265.135 196.619 267.523 169.6 263.79zM243.2 121.5600000000001C269.538 116.9080000000001 292.932 107.633 316.8 100.2200000000001V167.6300000000001C292.523 174.3760000000001 269.26 184.0800000000001 243.2 189.9500000000001V121.5600000000001zM96 105.9C119.62 114.29 143.79 119.74 169.6 122.46V193.75C143.49 191.4 122.24 185.71 96 176.39V105.9zM464 327.5C442.7 318.65 417.41 309.86 390.4 305.03V233.12C417.71 237.48 440.43 247.22 464 257.01V327.5zM464 117.54V188.03C441.81 173.83 415.2200000000001 165.42 390.4 162.01V90.43C415.47 92.81 438.89 101.47 464 117.54zM316.8 235.79V167.63C342.464 160.496 363.416 158.288 390.4 162.01V233.12C364.401 228.933 340.457 230.444 316.8 235.79z" />
@@ -957,6 +1002,9 @@
<glyph glyph-name="genderless"
unicode="&#xF22D;"
horiz-adv-x="288" d=" M144 272C188.1 272 224 236.1 224 192S188.1 112 144 112S64 147.9 64 192S99.9 272 144 272M144 336C64.5 336 0 271.5 0 192S64.5 48 144 48S288 112.5 288 192S223.5 336 144 336z" />
<glyph glyph-name="ghost"
unicode="&#xF6E2;"
horiz-adv-x="384" d=" M186.1 447.9100000000001C81.01 444.76 0 353.08 0 247.95V-15.97C0 -30.23 17.23 -37.36 27.31 -27.28L52.23 -8.75C58.89 -3.8 68.23 -4.76 73.74 -10.96L116.69 -59.31C122.94 -65.5599999999999 133.07 -65.5599999999999 139.32 -59.31L180.04 -13.46C186.41 -6.29 197.6 -6.29 203.96 -13.46L244.6800000000001 -59.31C250.9300000000001 -65.5599999999999 261.0600000000001 -65.5599999999999 267.3100000000001 -59.31L310.2600000000001 -10.96C315.7700000000001 -4.76 325.1100000000001 -3.79 331.7700000000001 -8.75L356.6900000000001 -27.28C366.7700000000001 -37.36 384.0000000000001 -30.22 384.0000000000001 -15.97V256C384 364 294.83 451.17 186.1 447.9100000000001zM128 224C110.33 224 96 238.33 96 256S110.33 288 128 288S160 273.67 160 256S145.67 224 128 224zM256 224C238.33 224 224 238.33 224 256S238.33 288 256 288S288 273.67 288 256S273.67 224 256 224z" />
<glyph glyph-name="gift"
unicode="&#xF06B;"
horiz-adv-x="512" d=" M32 0C32 -17.7 46.3 -32 64 -32H224V128H32V0zM480 288H437.9C444.1 300.1 448 313.5 448 328C448 376.5 408.5 416 360 416C318.4 416 291.5 394.7 257 347.7C222.5 394.7 195.6 416 154 416C105.5 416 66 376.5 66 328C66 313.5 69.8 300.1 76.1 288H32C14.3 288 0 273.7 0 256V176C0 167.2 7.2 160 16 160H496C504.8 160 512 167.2 512 176V256C512 273.7 497.7 288 480 288zM153.9 288C131.8 288 113.9 305.9 113.9 328S131.8 368 153.9 368C173.8 368 188.5 364.7 240 288H153.9zM360 288H273.9C325.3 364.5 339.6 368 360 368C382.1 368 400 350.1 400 328S382.1 288 360 288zM288 -32H448C465.7 -32 480 -17.7 480 0V128H288V-32z" />
@@ -1047,6 +1095,9 @@
<glyph glyph-name="h-square"
unicode="&#xF0FD;"
horiz-adv-x="448" d=" M448 368V16C448 -10.51 426.51 -32 400 -32H48C21.49 -32 0 -10.51 0 16V368C0 394.51 21.49 416 48 416H400C426.51 416 448 394.51 448 368zM336 320H304C295.163 320 288 312.837 288 304V224H160V304C160 312.837 152.837 320 144 320H112C103.163 320 96 312.837 96 304V80C96 71.163 103.163 64 112 64H144C152.837 64 160 71.163 160 80V160H288V80C288 71.163 295.163 64 304 64H336C344.837 64 352 71.163 352 80V304C352 312.837 344.837 320 336 320z" />
<glyph glyph-name="hammer"
unicode="&#xF6E3;"
horiz-adv-x="576" d=" M571.31 254.06L548.68 276.69C542.43 282.94 532.3 282.94 526.05 276.69L514.74 265.38L485.84 294.28C491.47 315.5900000000001 486.2 339.18 469.49 355.89L424.24 401.14C361.76 463.62 260.4500000000001 463.62 197.96 401.14L288.4700000000001 355.89V337.14C288.4700000000001 320.17 295.2100000000001 303.89 307.2200000000001 291.89L356.36 242.75C373.07 226.04 396.6600000000001 220.77 417.9700000000001 226.4L446.87 197.5L435.56 186.19C429.31 179.94 429.31 169.81 435.56 163.56L458.19 140.93C464.44 134.68 474.57 134.68 480.82 140.93L571.33 231.44C577.5600000000001 237.68 577.5600000000001 247.81 571.3100000000001 254.06zM284.5899999999999 269.26C280.89 272.96 277.75 277.05 274.7399999999999 281.21L19.64 43.04C-5.93 19.16 -6.62 -21.15 18.11 -45.89S83.16 -69.9399999999999 107.04 -44.36L345.17 210.71C341.2100000000001 213.62 337.2700000000001 216.58 333.73 220.12L284.5900000000001 269.26z" />
<glyph glyph-name="hamsa"
unicode="&#xF665;"
horiz-adv-x="512" d=" M509.34 140.75C504.28 152.44 492.75 160 480 160H416V368C416 390 398 408 376 408S336 390 336 368V234C336 228.48 331.52 224 326 224H306C300.48 224 296 228.48 296 234V408C296 430 278 448 256 448S216 430 216 408V234C216 228.48 211.52 224 206 224H186C180.48 224 176 228.48 176 234V368C176 390 158 408 136 408S96 390 96 368V160H32C19.25 160 7.72 152.44 2.66 140.75A31.966 31.966 0 0 1 8.6 106.17L111.29 -3.86C146.97 -42.08 199.69 -64 256 -64S365.03 -42.08 400.7200000000001 -3.86L503.4 106.17A31.966 31.966 0 0 1 509.34 140.75zM256 32C202.98 32 160 96 160 96S202.98 160 256 160S352 96 352 96S309.02 32 256 32zM256 128C238.33 128 224 113.67 224 96S238.33 64 256 64S288 78.33 288 96S273.67 128 256 128z" />
@@ -1101,9 +1152,15 @@
<glyph glyph-name="handshake"
unicode="&#xF2B5;"
horiz-adv-x="640" d=" M434.7 384H348.8C340.8 384 333.1 381 327.2 375.6L228.8999999999999 285.6C228.8 285.5 228.7 285.3 228.5999999999999 285.2C211.9999999999999 269.6 212.2999999999999 244.7 226.4999999999999 229.2C239.1999999999999 215.3 265.8999999999999 211.6 282.5999999999999 226.5C282.7 226.6 282.8999999999999 226.6 282.9999999999999 226.7L362.8999999999999 299.9C369.3999999999999 305.8 379.5999999999999 305.4 385.4999999999999 298.9C391.4999999999999 292.4 390.9999999999999 282.3 384.4999999999999 276.3L358.3999999999999 252.4L504 134.2C506.9 131.8 509.5 129.2 511.9 126.5V320L457.3 374.6C451.4 380.6 443.2 384 434.7 384zM544 319.8V95.9C544 78.2 558.3 63.9 576 63.9H640V319.8H544zM592 95.9C583.2 95.9 576 103.1 576 111.9S583.2 127.9 592 127.9S608 120.7 608 111.9S600.8 95.9 592 95.9zM0 64H64C81.7 64 96 78.3 96 96V319.8H0V64zM48 127.9C56.8 127.9 64 120.7 64 111.9S56.8 95.9 48 95.9S32 103.1 32 111.9C32 120.8 39.2 127.9 48 127.9zM483.9 109.3L334.6 230.5L304.6 203C274.9000000000001 175.9 229.4000000000001 178.5 202.9 207.4C176 236.8 178.1 282.3 207.3000000000001 309.1L289.1 384H205.3C196.8 384 188.7 380.6 182.7 374.6L128 320V96.1H146.3L236.8 14.2C264.2 -8.1 304.5 -3.9 326.8 23.5000000000001L327 23.7L344.9 8.2C360.8 -4.8 384.3 -2.3 397.2 13.6L428.6 52.2L434 47.8000000000001C447.7 36.7 467.8999999999999 38.7 478.9999999999999 52.5000000000001L488.4999999999999 64.2000000000001C499.6999999999999 78.0000000000001 497.6 98.1 483.8999999999999 109.3000000000001z" />
<glyph glyph-name="hanukiah"
unicode="&#xF6E6;"
horiz-adv-x="640" d=" M232 288C227.58 288 224 284.42 224 280V160H256V280C256 284.42 252.42 288 248 288H232zM168 288C163.58 288 160 284.42 160 280V160H192V280C192 284.42 188.42 288 184 288H168zM392 288C387.58 288 384 284.42 384 280V160H416V280C416 284.42 412.42 288 408 288H392zM456 288C451.58 288 448 284.42 448 280V160H480V280C480 284.42 476.42 288 472 288H456zM544 280C544 284.42 540.42 288 536 288H520C515.58 288 512 284.42 512 280V160H544V280zM104 288C99.58 288 96 284.42 96 280V160H128V280C128 284.42 124.42 288 120 288H104zM624 288H592C583.16 288 576 280.8400000000001 576 272V160C576 142.33 561.67 128 544 128H352V320C352 328.8400000000001 344.84 336 336 336H304C295.1600000000001 336 288 328.8400000000001 288 320V128H96C78.33 128 64 142.33 64 160V272C64 280.8400000000001 56.84 288 48 288H16C7.16 288 0 280.8400000000001 0 272V160C0 106.98 42.98 64 96 64H288V0H112C103.16 0 96 -7.16 96 -16V-48C96 -56.84 103.16 -64 112 -64H528C536.84 -64 544 -56.84 544 -48V-16C544 -7.16 536.84 0 528 0H352V64H544C597.02 64 640 106.98 640 160V272C640 280.8400000000001 632.84 288 624 288zM608 320C621.25 320 632 331.94 632 346.67S608 400 608 400S584 361.39 584 346.67S594.75 320 608 320zM32 320C45.25 320 56 331.94 56 346.67S32 400 32 400S8 361.39 8 346.67S18.75 320 32 320zM320 368C333.25 368 344 379.94 344 394.67S320 448 320 448S296 409.39 296 394.67S306.75 368 320 368zM112 320C125.25 320 136 331.94 136 346.67S112 400 112 400S88 361.39 88 346.67S98.75 320 112 320zM176 320C189.25 320 200 331.94 200 346.67S176 400 176 400S152 361.39 152 346.67S162.75 320 176 320zM240 320C253.25 320 264 331.94 264 346.67S240 400 240 400S216 361.39 216 346.67S226.75 320 240 320zM400 320C413.25 320 424 331.94 424 346.67S400 400 400 400S376 361.39 376 346.67S386.75 320 400 320zM464 320C477.25 320 488 331.94 488 346.67S464 400 464 400S440 361.39 440 346.67S450.75 320 464 320zM528 320C541.25 320 552 331.94 552 346.67S528 400 528 400S504 361.39 504 346.67S514.75 320 528 320z" />
<glyph glyph-name="hashtag"
unicode="&#xF292;"
horiz-adv-x="448" d=" M440.667 265.891L447.81 305.891C449.123 313.246 443.468 320 435.997 320H361.187L375.81 401.891C377.123 409.246 371.468 416 363.997 416H323.365A12 12 0 0 1 311.552 406.109L296.175 320H197.54L212.163 401.891C213.477 409.246 207.822 416 200.35 416H159.718A12 12 0 0 1 147.905 406.109L132.528 320H53.432A12 12 0 0 1 41.619 310.1090000000001L34.476 270.1090000000001C33.163 262.754 38.818 256 46.289 256H121.099L98.242 128H19.146A12 12 0 0 1 7.333 118.109L0.19 78.109C-1.123 70.754 4.532 64 12.003 64H86.813L72.19 -17.891C70.877 -25.246 76.532 -32 84.003 -32H124.635A12 12 0 0 1 136.448 -22.109L151.826 64H250.46L235.837 -17.891C234.523 -25.246 240.178 -32 247.65 -32H288.282A12 12 0 0 1 300.095 -22.109L315.472 64H394.568A12 12 0 0 1 406.381 73.891L413.524 113.891C414.837 121.2460000000001 409.182 128 401.711 128H326.901L349.7579999999999 256H428.854A12 12 0 0 1 440.6669999999999 265.891zM261.889 128H163.255L186.112 256H284.746L261.889 128z" />
<glyph glyph-name="hat-wizard"
unicode="&#xF6E8;"
horiz-adv-x="512" d=" M496 0H16C7.16 0 0 -7.16 0 -16V-48C0 -56.84 7.16 -64 16 -64H496C504.84 -64 512 -56.84 512 -48V-16C512 -7.16 504.84 0 496 0zM192 64L128 96L192 128L224 192L256 128L320 96L256 64L240 32H448L361.5900000000001 233.63A63.95499999999999 63.95499999999999 0 0 0 359.7000000000001 279.08L416 448L228.42 340.81A127.98900000000002 127.98900000000002 0 0 1 174.96 281.66L64 32H208L192 64zM256 288L272 320L288 288L320 272L288 256L272 224L256 256L224 272L256 288z" />
<glyph glyph-name="haykal"
unicode="&#xF666;"
horiz-adv-x="512" d=" M496.25 245.48L386.25 260.92L428.07 365.26C434.74 381.9 416.47 397.44 401.48 387.89L307.44 328L273.35 435.18C270.64 443.73 263.32 448 256 448C248.68 448 241.36 443.73 238.65 435.18L204.56 327.99L110.52 387.88C95.53 397.43 77.27 381.89 83.93 365.25L125.75 260.9100000000001L15.75 245.48C-1.79 243.02 -5.93 219.21 9.72 210.81L107.88 158.15L33.4 74.61C22.48 62.36 31.68 43.68 46.69 43.68C48 43.68 49.36 43.8199999999999 50.76 44.1299999999999L159.33 67.7799999999999L155.22 -44.7700000000001C154.79 -56.4200000000001 164.09 -63.9900000000001 173.63 -63.9900000000001C178.78 -63.9900000000001 184.02 -61.7800000000001 187.83 -56.8100000000001L256.01 32.0899999999999L324.19 -56.8100000000001C328 -61.7800000000001 333.23 -63.9900000000001 338.39 -63.9900000000001C347.93 -63.9900000000001 357.23 -56.4200000000001 356.8 -44.7700000000001L352.69 67.7799999999999L461.26 44.1299999999999C478.62 40.37 490.47 61.3299999999999 478.61 74.62L404.13 158.16L502.29 210.82C517.93 219.21 513.79 243.02 496.2499999999999 245.48zM338.51 136.32L286.62 147.62L288.5900000000001 93.83L256 136.32L223.41 93.83L225.37 147.62L173.48 136.32L209.08 176.25L162.16 201.42L214.73 208.8L194.74 258.67L239.69 230.05L256 281.28L272.29 230.05L317.24 258.67L297.25 208.8L349.82 201.42L302.9 176.25L338.51 136.32z" />
@@ -1134,6 +1191,12 @@
<glyph glyph-name="highlighter"
unicode="&#xF591;"
horiz-adv-x="544" d=" M0 -31.98L99.92 -64L135.37 -28.55L68.33 38.49L0 -31.98zM124.61 208.03A36.592 36.592 0 0 1 113.82 169.93L126.87 127.1L75.94 76.16L172.17 -20.07L223.03 30.79L265.7700000000001 17.71C279.5000000000001 13.51 294.42 17.72 303.92 28.49L339.4700000000001 70.1299999999999L166.13 243.47L124.61 208.03zM527.92 368.73L464.72 431.93C444.23 452.42 411.34 453.45 389.6 434.28L190.55 264.32L360.3200000000001 94.54L530.27 293.6C549.4499999999999 315.3400000000001 548.42 348.23 527.92 368.73z" />
<glyph glyph-name="hiking"
unicode="&#xF6EC;"
horiz-adv-x="384" d=" M80.95 -24.23C76.67 -41.39 87.09 -58.76 104.23 -63.04C106.84 -63.7 109.45 -63.99 112.03 -63.99C126.36 -63.99 139.4 -54.29 143.05 -39.76L168.29 61.21L115.51 113.99L80.95 -24.23zM95.84 171.89L137 331C139.19 339.42 133.86 347.95 125.08 350.06C81.2 360.58 36.73 334.99 25.76 292.89L0.49 194.76C-1.7 186.34 3.63 177.81 12.41 175.7L75.97 160.45C84.76 158.35 93.65 163.47 95.84 171.89zM368 288H352C343.1600000000001 288 336 280.8400000000001 336 272V256H301.25L254.47 302.78C243.38 313.89 228.61 320 212.91 320C185.89 320 162.44 301.7 155.88 275.48L128.96 167.76A32.012 32.012 0 0 1 137.38 137.37L224 50.75V-32C224 -49.67 238.33 -64 256 -64S288 -49.67 288 -32V50.75C288 67.84 281.34 83.91 269.25 96L222.43 142.82C222.58 143.32 222.92 143.71 223.05 144.23L242.94 223.8L265.37 201.37C271.37 195.37 279.51 191.99 287.99 191.99H335.99V-48.01C335.99 -56.85 343.1500000000001 -64.01 351.99 -64.01H367.99C376.83 -64.01 383.99 -56.85 383.99 -48.01V272C384 280.8400000000001 376.8400000000001 288 368 288zM240 352C266.51 352 288 373.49 288 400S266.51 448 240 448S192 426.51 192 400S213.49 352 240 352z" />
<glyph glyph-name="hippo"
unicode="&#xF6ED;"
horiz-adv-x="640" d=" M581.12 351.8C553.45 351.95 528.62 334.2200000000001 504.52 325.18C489.98 359.73 455.83 384 416 384C404.7200000000001 384 394.05 381.7 384 378.12V392C384 405.26 373.25 416 360 416H344C330.75 416 320 405.26 320 392V343.02C286.01 368.42 241.24 384 192 384C85.96 384 0 312.36 0 224V-16C0 -24.84 7.16 -32 16 -32H80C88.84 -32 96 -24.84 96 -16V54.79C128.35 40.43 166.72 32 208 32S287.65 40.43 320 54.79V-16C320 -24.84 327.1600000000001 -32 336 -32H400C408.84 -32 416 -24.84 416 -16V160H544V128C544 119.16 551.16 112 560 112H592C600.84 112 608 119.16 608 128V160C625.67 160 640 174.33 640 192V284.02C640 318.11 615.21 351.61 581.12 351.8zM448 272C439.1600000000001 272 432 279.16 432 288S439.1600000000001 304 448 304S464 296.8400000000001 464 288S456.84 272 448 272z" />
<glyph glyph-name="history"
unicode="&#xF1DA;"
horiz-adv-x="512" d=" M504 192.469C504.253 55.829 392.82 -55.903 256.18 -55.999C197.165 -56.041 142.957 -35.469 100.358 -1.088C89.281 7.852 88.453 24.453 98.519 34.519L109.786 45.786C118.395 54.395 132.139 55.337 141.677 47.77C173.062 22.865 212.781 8 256 8C357.705 8 440 90.311 440 192C440 293.705 357.689 376 256 376C207.186 376 162.851 357.031 129.932 326.068L180.686 275.314C190.766 265.234 183.627 248 169.373 248H24C15.163 248 8 255.163 8 264V409.373C8 423.627 25.234 430.766 35.314 420.687L84.686 371.315C129.209 413.864 189.552 440 256 440C392.81 440 503.747 329.2200000000001 504 192.469zM323.088 113.685L332.911 126.315C341.0489999999999 136.778 339.164 151.857 328.701 159.994L288 191.651V296C288 309.255 277.255 320 264 320H248C234.745 320 224 309.255 224 296V160.349L289.409 109.475C299.872 101.338 314.95 103.222 323.088 113.685z" />
@@ -1143,6 +1206,9 @@
<glyph glyph-name="home"
unicode="&#xF015;"
horiz-adv-x="576" d=" M488 135.3V-8C488 -21.3 477.3 -32 464 -32H348C341.4 -32 336 -26.6 336 -20V92C336 98.6 330.6 104 324 104H252C245.4 104 240 98.6 240 92V-20C240 -26.6 234.6 -32 228 -32H112C98.7 -32 88 -21.3 88 -8V135.3C88 138.9 89.6 142.3 92.4 144.6L280.4 299.4000000000001C284.8 303 291.2 303 295.7 299.4000000000001L483.7 144.6C486.4 142.3 488 138.9 488 135.3zM571.6 196.2L488 265.1V403.6C488 410.2 482.6 415.6 476 415.6H420C413.4 415.6 408 410.2 408 403.6V331L318.5 404.7C300.8 419.3 275.2 419.3 257.5 404.7L4.4 196.2C-0.7 192 -1.4 184.4 2.8 179.3L28.3 148.3C32.5 143.2 40.1 142.5 45.2 146.7L280.4 340.4C284.8 344 291.2 344 295.7 340.4L530.9 146.7C536 142.5 543.6 143.2 547.8 148.3L573.3 179.3C577.5 184.5 576.6999999999999 192 571.5999999999999 196.2z" />
<glyph glyph-name="horse"
unicode="&#xF6F0;"
horiz-adv-x="576" d=" M575.92 371.4C575.91 379.53 572.9 387.27 567.3399999999999 393.2C563.56 397.23 558.7599999999999 402.32 553.6499999999999 407.7C564.7099999999998 414.54 573.1499999999999 425.19 575.8299999999998 438.36C576.85 443.32 572.96 448 567.9 448H447.92C377.23 448 319.92 390.69 319.92 320H160C131.16 320 105.6 307.02 88 286.89V288C39.47 288 0 248.53 0 200V144C0 135.16 7.16 128 16 128H32C40.84 128 48 135.16 48 144V200C48 213.22 54.87 224.39 64.78 231.68C64.57 229.1 64 226.63 64 224C64 196.36 75.84 171.64 94.54 154.12L68.82 85.52A63.94500000000001 63.94500000000001 0 0 1 66.66 47.53L91.51 -51.88A15.982 15.982 0 0 1 107.02 -64H172.98C183.39 -64 191.03 -54.22 188.5 -44.12L162.19 61.14L186.03 124.73L320 102.4V-48C320 -56.84 327.1600000000001 -64 336 -64H400C408.84 -64 416 -56.84 416 -48V129.78C435.74 149.97 448 177.53 448 208C448 208.22 447.93 208.42 447.92 208.64V311.11L463.92 304L482.82 266.3C490.27 251.43 507.87 244.75 523.31 250.93L555.8599999999999 263.9500000000001A31.997 31.997 0 0 1 575.9799999999999 293.6900000000001L575.92 371.4000000000001zM511.92 352C503.08 352 495.92 359.16 495.92 368S503.08 384 511.92 384S527.92 376.8400000000001 527.92 368S520.76 352 511.92 352z" />
<glyph glyph-name="hospital-alt"
unicode="&#xF47D;"
horiz-adv-x="576" d=" M544 352H416V416C416 433.7 401.7 448 384 448H192C174.3 448 160 433.7 160 416V352H32C14.3 352 0 337.7 0 320V-48C0 -56.8 7.2 -64 16 -64H560C568.8 -64 576 -56.8 576 -48V320C576 337.7 561.7 352 544 352zM160 12C160 5.4 154.6 0 148 0H108C101.4 0 96 5.4 96 12V52C96 58.6 101.4 64 108 64H148C154.6 64 160 58.6 160 52V12zM160 140C160 133.4 154.6 128 148 128H108C101.4 128 96 133.4 96 140V180C96 186.6 101.4 192 108 192H148C154.6 192 160 186.6 160 180V140zM320 12C320 5.4 314.6 0 308 0H268C261.4 0 256 5.4 256 12V52C256 58.6 261.4 64 268 64H308C314.6 64 320 58.6 320 52V12zM320 140C320 133.4 314.6 128 308 128H268C261.4 128 256 133.4 256 140V180C256 186.6 261.4 192 268 192H308C314.6 192 320 186.6 320 180V140zM336 310C336 306.7 333.3 304 330 304H304V278C304 274.7 301.3 272 298 272H278C274.7 272 272 274.7 272 278V304H246C242.7 304 240 306.7 240 310V330C240 333.3 242.7 336 246 336H272V362C272 365.3 274.7 368 278 368H298C301.3 368 304 365.3 304 362V336H330C333.3 336 336 333.3 336 330V310zM480 12C480 5.4 474.6 0 468 0H428C421.4 0 416 5.4 416 12V52C416 58.6 421.4 64 428 64H468C474.6 64 480 58.6 480 52V12zM480 140C480 133.4 474.6 128 468 128H428C421.4 128 416 133.4 416 140V180C416 186.6 421.4 192 428 192H468C474.6 192 480 186.6 480 180V140z" />
@@ -1170,6 +1236,12 @@
<glyph glyph-name="hourglass"
unicode="&#xF254;"
horiz-adv-x="384" d=" M360 384C373.255 384 384 394.745 384 408V424C384 437.255 373.255 448 360 448H24C10.745 448 0 437.255 0 424V408C0 394.745 10.745 384 24 384C24 293.035 75.016 216.266 144.842 192C75.016 167.734 24 90.965 24 0C10.745 0 0 -10.745 0 -24V-40C0 -53.255 10.745 -64 24 -64H360C373.255 -64 384 -53.255 384 -40V-24C384 -10.745 373.255 0 360 0C360 90.965 308.984 167.734 239.158 192C308.984 216.266 360 293.035 360 384z" />
<glyph glyph-name="house-damage"
unicode="&#xF6F1;"
horiz-adv-x="576" d=" M288 333.04L69.47 140.29C67.85 138.8300000000001 65.78 138.15 64 136.94V-48C64 -56.84 71.16 -64 80 -64H229.23L192 8.81L296.11 72.81L235.95 192.03L384 55.25L279.89 -8.75L319.81 -64H496C504.84 -64 512 -56.84 512 -48V136.9C510.3 138.06 508.28 138.72 506.74 140.1L288 333.04zM570.69 211.72L512 263.55V400C512 408.8400000000001 504.84 416 496 416H432C423.1600000000001 416 416 408.8400000000001 416 400V348.31L314.75 437.69C307.12 444.55 297.56 447.99 288 448S268.9 444.59 261.3 437.73L5.31 211.72C-1.26 205.81 -1.81 195.7 4.1 189.12L25.5 165.3C31.4 158.73 41.52 158.18 48.1 164.09L277.42 366.37C283.4700000000001 371.7 292.54 371.7 298.5900000000001 366.37L527.91 164.1C534.48 158.2000000000001 544.6 158.74 550.51 165.31L571.91 189.13C577.81 195.7 577.27 205.82 570.6899999999999 211.72z" />
<glyph glyph-name="hryvnia"
unicode="&#xF6F2;"
horiz-adv-x="384" d=" M368 208C376.84 208 384 215.16 384 224V256C384 264.8400000000001 376.84 272 368 272H326.14C339.55 300.63 339.88 335.33 322.01 366.05C303.34 398.16 267.1 416 229.96 416H151.14C126.82 416 103.28 407.4700000000001 84.6 391.91L72.83 382.1C62.65 373.61 61.27 358.48 69.76 348.3L90.25 323.71C98.74 313.52 113.87 312.15 124.06 320.64L135.79 330.42C140.11 334.02 145.56 335.99 151.18 335.99H234.8C246.49 335.99 256 326.4700000000001 256 314.79C256 308.88 253.52 303.2100000000001 249.19 299.2100000000001L219.7 272H16C7.16 272 0 264.8400000000001 0 256V224C0 215.16 7.16 208 16 208H150.37L115.7 176H16C7.16 176 0 168.84 0 160V128C0 119.16 7.16 112 16 112H57.86C44.45 83.37 44.12 48.67 61.99 17.95C80.66 -14.15 116.9 -32 154.04 -32H232.86C257.18 -32 280.72 -23.47 299.4 -7.91L311.17 1.9C321.35 10.39 322.73 25.52 314.24 35.7L293.75 60.29C285.26 70.48 270.13 71.85 259.94 63.36L248.19 53.5599999999999A23.992 23.992 0 0 0 232.83 47.9999999999999H149.2C137.51 47.9999999999999 128 57.5199999999999 128 69.1999999999999C128 75.11 130.48 80.7799999999999 134.81 84.7799999999999L164.3 112H368C376.84 112 384 119.16 384 128V160C384 168.84 376.84 176 368 176H233.63L268.3 208H368z" />
<glyph glyph-name="i-cursor"
unicode="&#xF246;"
horiz-adv-x="256" d=" M256 395.952V435.935C256 442.504 250.726 447.852 244.158 447.9340000000001C211.621 448.344 166.469 447.989 128 410.041C90.266 447.264 46.979 448.114 11.913 447.886C5.318 447.843 0 442.481 0 435.886V396.241C0 389.554 5.458 384.163 12.145 384.243C38.111 384.553 96 380.757 96 335.818V224H60C53.373 224 48 218.627 48 212V172C48 165.373 53.373 160 60 160H96V48C96 3.068 39.925 -0.031 12.05 0.041C5.404 0.058 0 -5.306 0 -11.952V-51.935C0 -58.504 5.274 -63.852 11.842 -63.934C44.379 -64.3430000000001 89.531 -63.988 128 -26.04C165.734 -63.263 209.021 -64.1130000000001 244.087 -63.885C250.682 -63.842 256 -58.48 256 -51.885V-12.24C256 -5.553 250.542 -0.162 243.855 -0.242C217.889 -0.553 160 3.061 160 48V160H196C202.627 160 208 165.373 208 172V212C208 218.627 202.627 224 196 224H160V335.818C160 380.75 216.075 384.031 243.95 383.9600000000001C250.596 383.942 256 389.3060000000001 256 395.952z" />
@@ -1389,6 +1461,9 @@
<glyph glyph-name="mars"
unicode="&#xF222;"
horiz-adv-x="384" d=" M372 384H293C282.3 384 277 371.1 284.5 363.5L301.4 346.6L220.7 265.9C198.5 279.9 172.2 288 144 288C64.5 288 0 223.5 0 144S64.5 0 144 0S288 64.5 288 144C288 172.2 279.9 198.5 265.9 220.7L346.6 301.4L363.5 284.5C371.1 276.9 384 282.3 384 293V372C384 378.6 378.6 384 372 384zM144 64C99.9 64 64 99.9 64 144S99.9 224 144 224S224 188.1 224 144S188.1 64 144 64z" />
<glyph glyph-name="mask"
unicode="&#xF6FA;"
horiz-adv-x="640" d=" M320.67 384C-121.93 384 -36.9 0 162.21 0C202.11 0 239.68 20.69 263.63 55.86L289.36 93.65C305.0200000000001 116.6400000000001 336.3300000000001 116.6400000000001 351.99 93.65L377.7200000000001 55.86C401.6600000000001 20.69 439.23 0 479.13 0C668.99 0 769.76 384 320.67 384zM184 139.64C142.94 139.64 116.24 165.3 103.92 180.69C98.69 187.22 98.69 196.78 103.92 203.32C116.24 218.72 142.93 244.37 184 244.37S251.76 218.71 264.08 203.32C269.31 196.79 269.31 187.23 264.08 180.69C251.76 165.29 225.06 139.64 184 139.64zM456 139.64C414.94 139.64 388.24 165.3 375.92 180.69C370.69 187.22 370.69 196.78 375.92 203.32C388.24 218.72 414.93 244.37 456 244.37S523.76 218.71 536.08 203.32C541.3100000000001 196.79 541.3100000000001 187.23 536.08 180.69C523.76 165.29 497.0600000000001 139.64 456.0000000000001 139.64z" />
<glyph glyph-name="medal"
unicode="&#xF5A2;"
horiz-adv-x="512" d=" M223.75 317.25L154.62 432.46A31.997 31.997 0 0 1 127.18 448H16.03C3.08 448 -4.5 433.43 2.92 422.82L114.19 263.86C143.91 291.63 181.71 310.69 223.75 317.25zM495.97 448H384.82C373.58 448 363.16 442.1 357.38 432.46L288.25 317.25C330.29 310.69 368.0900000000001 291.63 397.81 263.87L509.08 422.82C516.5 433.43 508.92 448 495.97 448zM256 288C158.8 288 80 209.2 80 112S158.8 -64 256 -64S432 14.8 432 112S353.2 288 256 288zM348.52 130.74L310.59 93.78L319.56 41.5600000000001C321.1600000000001 32.2 311.3 25.0500000000001 302.9100000000001 29.4700000000001L256 54.12L209.1 29.47C200.7 25.02 190.85 32.21 192.45 41.56L201.42 93.78L163.49 130.74C156.67 137.38 160.44 148.97 169.84 150.3299999999999L222.27 157.9699999999999L245.7 205.4899999999999C247.81 209.7699999999999 251.89 211.8799999999999 255.98 211.8799999999999C260.09 211.8799999999999 264.2 209.7399999999999 266.31 205.4899999999999L289.74 157.9699999999999L342.17 150.3299999999999C351.57 148.9699999999999 355.3400000000001 137.38 348.5200000000001 130.74z" />
@@ -1409,7 +1484,7 @@
horiz-adv-x="640" d=" M640 317.06V352C640 369.67 625.67 384 608 384H32C14.33 384 0 369.67 0 352V317.06C18.6 310.45 32 292.87 32 272S18.6 233.55 0 226.94V128H640V226.94C621.4 233.55 608 251.13 608 272S621.4 310.45 640 317.06zM224 192H160V320H224V192zM352 192H288V320H352V192zM480 192H416V320H480V192zM0 0H64V26.67C64 35.51 71.16 42.67 80 42.67S96 35.51 96 26.67V0H224V26.67C224 35.51 231.16 42.67 240 42.67S256 35.51 256 26.67V0H384V26.67C384 35.51 391.1600000000001 42.67 400 42.67S416 35.51 416 26.67V0H544V26.67C544 35.51 551.16 42.67 560 42.67S576 35.51 576 26.67V0H640V96H0V0z" />
<glyph glyph-name="menorah"
unicode="&#xF676;"
horiz-adv-x="640" d=" M144 288H112C103.16 288 96 280.8400000000001 96 272V160H160V272C160 280.8400000000001 152.84 288 144 288zM240 288H208C199.16 288 192 280.8400000000001 192 272V160H256V272C256 280.8400000000001 248.84 288 240 288zM432 288H400C391.1600000000001 288 384 280.8400000000001 384 272V160H448V272C448 280.8400000000001 440.84 288 432 288zM528 288H496C487.16 288 480 280.8400000000001 480 272V160H544V272C544 280.8400000000001 536.84 288 528 288zM608 320C625.67 320 640 334.33 640 352S608 416 608 416S576 369.67 576 352S590.33 320 608 320zM512 320C529.67 320 544 334.33 544 352S512 416 512 416S480 369.67 480 352S494.33 320 512 320zM416 320C433.67 320 448 334.33 448 352S416 416 416 416S384 369.67 384 352S398.33 320 416 320zM320 352C337.67 352 352 366.33 352 384S320 448 320 448S288 401.67 288 384S302.33 352 320 352zM224 320C241.67 320 256 334.33 256 352S224 416 224 416S192 369.67 192 352S206.33 320 224 320zM128 320C145.67 320 160 334.33 160 352S128 416 128 416S96 369.67 96 352S110.33 320 128 320zM32 320C49.67 320 64 334.33 64 352S32 416 32 416S0 369.67 0 352S14.33 320 32 320zM576 160C576 142.33 561.67 128 544 128H352V304C352 312.8400000000001 344.84 320 336 320H304C295.1600000000001 320 288 312.8400000000001 288 304V128H96C78.33 128 64 142.33 64 160V272C64 280.8400000000001 56.84 288 48 288H16C7.16 288 0 280.8400000000001 0 272V160C0 106.98 42.98 64 96 64H288V0H112C103.16 0 96 -7.16 96 -16V-48C96 -56.84 103.16 -64 112 -64H528C536.84 -64 544 -56.84 544 -48V-16C544 -7.16 536.84 0 528 0H352V64H544C597.02 64 640 106.98 640 160V272C640 280.8400000000001 632.84 288 624 288H592C583.16 288 576 280.8400000000001 576 272V160z" />
horiz-adv-x="640" d=" M144 320H112C103.16 320 96 312.8400000000001 96 304V160H160V304C160 312.8400000000001 152.84 320 144 320zM240 320H208C199.16 320 192 312.8400000000001 192 304V160H256V304C256 312.8400000000001 248.84 320 240 320zM432 320H400C391.1600000000001 320 384 312.8400000000001 384 304V160H448V304C448 312.8400000000001 440.84 320 432 320zM528 320H496C487.16 320 480 312.8400000000001 480 304V160H544V304C544 312.8400000000001 536.84 320 528 320zM608 352C625.67 352 640 366.33 640 384S608 448 608 448S576 401.67 576 384S590.33 352 608 352zM512 352C529.67 352 544 366.33 544 384S512 448 512 448S480 401.67 480 384S494.33 352 512 352zM416 352C433.67 352 448 366.33 448 384S416 448 416 448S384 401.67 384 384S398.33 352 416 352zM320 352C337.67 352 352 366.33 352 384S320 448 320 448S288 401.67 288 384S302.33 352 320 352zM224 352C241.67 352 256 366.33 256 384S224 448 224 448S192 401.67 192 384S206.33 352 224 352zM128 352C145.67 352 160 366.33 160 384S128 448 128 448S96 401.67 96 384S110.33 352 128 352zM32 352C49.67 352 64 366.33 64 384S32 448 32 448S0 401.67 0 384S14.33 352 32 352zM576 160C576 142.33 561.67 128 544 128H352V304C352 312.8400000000001 344.84 320 336 320H304C295.1600000000001 320 288 312.8400000000001 288 304V128H96C78.33 128 64 142.33 64 160V304C64 312.8400000000001 56.84 320 48 320H16C7.16 320 0 312.8400000000001 0 304V160C0 106.98 42.98 64 96 64H288V0H112C103.16 0 96 -7.16 96 -16V-48C96 -56.84 103.16 -64 112 -64H528C536.84 -64 544 -56.84 544 -48V-16C544 -7.16 536.84 0 528 0H352V64H544C597.02 64 640 106.98 640 160V304C640 312.8400000000001 632.84 320 624 320H592C583.16 320 576 312.8400000000001 576 304V160z" />
<glyph glyph-name="mercury"
unicode="&#xF223;"
horiz-adv-x="288" d=" M288 240C288 284.2 268.1 323.7 236.8 350.1C239.3 351.9 241.7 353.9 244 355.9C268.7 377.1 283.8 404.7 287.2 434.7C288.1 441.8 282.5 448 275.3 448H234.8C229 448 224.1 443.9 223 438.2C220.6 425.7 213.4 413.9 202.3 404.4C187 391.2 166.3 384 144 384S101 391.2 85.6 404.4C74.5 413.9 67.4 425.7 64.9 438.2C63.8 443.9 58.9 448 53.2 448H12.7C5.5 448 -0.1 441.8 0.8 434.7C4.2 404.6 19.2 377 44 355.8C46.3 353.8 48.7 351.9 51.2 350C19.9 323.7 0 284.2 0 240C0 171.5 47.9 114.1 112 99.6V48H76C69.4 48 64 42.6 64 36V-4C64 -10.6 69.4 -16 76 -16H112V-52C112 -58.6 117.4 -64 124 -64H164C170.6 -64 176 -58.6 176 -52V-16H212C218.6 -16 224 -10.6 224 -4V36C224 42.6 218.6 48 212 48H176V99.6C240.1 114.1 288 171.5 288 240.0000000000001zM64 240C64 284.1 99.9 320 144 320S224 284.1 224 240S188.1 160 144 160S64 195.9 64 240z" />
@@ -1479,12 +1554,18 @@
<glyph glyph-name="motorcycle"
unicode="&#xF21C;"
horiz-adv-x="640" d=" M512.949 255.997C498.0869999999999 256.105 483.809 253.675 470.515 249.123L437.589 304H520C533.255 304 544 314.745 544 328V360C544 373.255 533.255 384 520 384H474.689A24 24 0 0 1 456.85 376.055L419.3540000000001 334.392L396.5800000000001 372.348A24 24 0 0 1 376 384H296C287.163 384 280 376.837 280 368V352C280 343.163 287.163 336 296 336H362.411L381.611 304H227.904C210.177 327.073 182.98 344 128 344H72.54C59.085 344 47.749 332.9890000000001 48.004 319.536C48.252 306.495 58.9 296 72 296H128C152.504 296 166.686 285.081 175.787 271.231L164.496 250.702C151.49 254.567 137.625 256.438 123.245 255.912C55.857 253.451 1.565 198.395 0.034 130.979C-1.603 58.924 56.317 0 128 0C187.642 0 237.744 40.794 251.953 96H336.189C349.862 96 360.778 107.421 360.165 121.077C358.0470000000001 168.197 377.687 214.742 416.35 246.103L428.8350000000001 225.295C401.189 201.641 383.7380000000001 166.415 384.004 127.116C384.4740000000001 57.56 441.207 0.664 510.762 0.006C582.391 -0.672 640.601 57.493 639.996 129.105C639.408 198.696 582.5409999999999 255.491 512.949 255.997zM128 48C83.888 48 48 83.888 48 128S83.888 208 128 208C132.242 208 136.405 207.659 140.469 207.018L98.97 131.566C90.187 115.593 101.762 96 120 96H201.297C188.927 67.775 160.737 48 128 48zM516.351 48.116C470.272 45.663 432 82.446 432 128C432 149.363 440.4340000000001 168.781 454.125 183.144L503.537 100.792C508.083 93.215 517.912 90.758 525.489 95.304L539.2090000000001 103.5360000000001C546.7860000000001 108.0820000000001 549.243 117.9110000000001 544.6970000000001 125.4880000000001L496.1410000000001 206.4150000000001A80.005 80.005 0 0 0 512 208C557.554 208 594.338 169.727 591.884 123.648C589.724 83.09 556.91 50.276 516.351 48.116z" />
<glyph glyph-name="mountain"
unicode="&#xF6FC;"
horiz-adv-x="640" d=" M634.92 -14.7L346.92 433.3C341.03 442.46 330.89 448 320 448S298.9700000000001 442.46 293.08 433.3L5.08 -14.7A32.001 32.001 0 0 1 3.91 -47.34A32.004 32.004 0 0 1 32 -64H608C619.71 -64 630.48 -57.61 636.09 -47.33A31.982999999999997 31.982999999999997 0 0 1 634.9200000000001 -14.7zM320 356.82L405.39 224H320L256 160L217.94 198.06L320 356.82z" />
<glyph glyph-name="mouse-pointer"
unicode="&#xF245;"
horiz-adv-x="320" d=" M302.189 118.874H196.105L251.936 -17.119C255.825 -26.547 251.381 -37.118 242.492 -41.118L193.327 -62.545C184.162 -66.5450000000001 173.884 -61.974 169.995 -52.831L116.942 76.305L30.278 -12.8330000000001C18.729 -24.71 0 -15.554 0 0.023V429.701C0 446.101 19.921 454.096 30.277 442.557L314.689 150.0150000000001C326.161 138.8360000000001 317.696 118.874 302.189 118.874z" />
<glyph glyph-name="music"
unicode="&#xF001;"
horiz-adv-x="512" d=" M511.99 415.99C511.99 437.7 490.89 453 470.39 446.5L150.4 352C137.1 347.8 128 335.5 128 321.5V60.08C117.95 62.46 107.28 64 96 64C42.98 64 0 35.35 0 0S42.98 -64 96 -64S192 -35.35 192 0V233.69L448 308.71V124.08C437.95 126.46 427.28 128 416 128C362.98 128 320 99.35 320 64S362.98 0 416 0S512 28.65 512 64L511.99 415.99z" />
<glyph glyph-name="network-wired"
unicode="&#xF6FF;"
horiz-adv-x="640" d=" M640 184V200C640 208.84 632.84 216 624 216H344V256H416C433.67 256 448 270.3300000000001 448 288V416C448 433.67 433.67 448 416 448H224C206.33 448 192 433.67 192 416V288C192 270.33 206.33 256 224 256H296V216H16C7.16 216 0 208.84 0 200V184C0 175.16 7.16 168 16 168H120V128H64C46.33 128 32 113.67 32 96V-32C32 -49.67 46.33 -64 64 -64H224C241.67 -64 256 -49.67 256 -32V96C256 113.67 241.67 128 224 128H168V168H472V128H416C398.33 128 384 113.67 384 96V-32C384 -49.67 398.33 -64 416 -64H576C593.67 -64 608 -49.67 608 -32V96C608 113.67 593.67 128 576 128H520V168H624C632.84 168 640 175.16 640 184zM256 320V384H384V320H256zM192 0H96V64H192V0zM544 0H448V64H544V0z" />
<glyph glyph-name="neuter"
unicode="&#xF22C;"
horiz-adv-x="288" d=" M288 272C288 351.5 223.5 416 144 416S0 351.5 0 272C0 203.5 47.9 146.1 112 131.6V-20C112 -26.6 117.4 -32 124 -32H164C170.6 -32 176 -26.6 176 -20V131.6C240.1 146.1 288 203.5 288 272zM144 192C99.9 192 64 227.9 64 272S99.9 352 144 352S224 316.1 224 272S188.1 192 144 192z" />
@@ -1509,6 +1590,9 @@
<glyph glyph-name="om"
unicode="&#xF679;"
horiz-adv-x="512" d=" M360.6 387.06A10.43 10.43 0 0 1 375.36 387.06L396.93 408.62A10.43 10.43 0 0 1 396.93 423.38L375.35 444.94C371.2700000000001 449.01 364.67 449.01 360.5900000000001 444.94L339.0200000000001 423.38A10.43 10.43 0 0 1 339.0200000000001 408.62L360.6 387.06zM412.11 256C385.42 256 360.3400000000001 245.61 341.4700000000001 226.75L317.2200000000001 202.5C310.4400000000001 195.73 301.4400000000001 192 291.8400000000001 192H245C255.54 214.1 259.17 240.11 252.73 267.23C242.63 309.7800000000001 206.37 343.3400000000001 163.21 350.42C127.06 356.35 92.31 345.38 67.2 321.64C59.84 314.68 60.23 302.79 68.32 296.7100000000001L94.47 277.0800000000001C100.19 272.78 108.13 272.76 113.67 277.29C122.12 284.1900000000001 132.69 288 143.94 288C170.41 288 191.95 266.4700000000001 191.95 240.0000000000001S170.41 192 143.94 192H112.04C100.08 192 92.3 179.42 97.65 168.72L113.74 136.55C116.27 131.49 121.34 128.45 126.91 128H159.94C195.24 128 223.95 99.3 223.95 64S195.24 0 159.94 0C63.92 0 37.59 54.02 14.79 92.03C10.26 99.58 0.02 95.61 0 86.81C-0.09 32 41.13 -64 159.94 -64C230.53 -64 287.9600000000001 -6.58 287.9600000000001 64C287.9600000000001 87.42 281.1800000000001 109.1 270.1500000000001 128H291.8400000000001C318.5300000000001 128 343.61 138.39 362.48 157.25L386.73 181.5C393.51 188.27 402.51 192 412.11 192C431.89 192 447.99 175.91 447.99 156.12V56C447.99 42.77 429.2200000000001 32 415.98 32C376.5800000000001 32 349.31 56.24 334.1600000000001 74.89C329.3900000000001 80.76 319.9600000000001 77.43 319.9600000000001 69.87V32S319.9600000000001 -32 415.98 -32C464.52 -32 512 7.47 512 56V156.12C512 211.2 467.2 256 412.11 256zM454.29 380.73C368.74 315.61 285.24 377.98 281.7100000000001 380.68C275.6900000000001 385.3 267.2700000000001 385.06 261.5700000000001 380.13C255.8300000000001 375.2100000000001 254.3000000000001 366.9600000000001 257.9100000000001 360.3300000000001C259.5200000000001 357.38 298.2800000000001 287.99 376.7100000000001 287.99C456.6300000000001 287.99 475.49 319.35 478.46 325.65C479.48 327.77 479.99 330.12 479.99 332.48V368C479.99 381.2200000000001 464.85 388.69 454.29 380.73z" />
<glyph glyph-name="otter"
unicode="&#xF700;"
horiz-adv-x="640" d=" M608 416H576L562.75 429.25A63.97 63.97 0 0 1 517.49 448H497C485.86 448 474.92 445.09 465.25 439.57L312 352H256C149.96 352 64 266.04 64 160V158.39C64 125.64 48 96.25 24.44 73.5C6.25 55.92 -3.66 29.82 1.25 1.7C8.01 -37.1 44.15 -64 83.53 -64H192C209.67 -64 224 -49.67 224 -32S209.67 0 192 0H80C71.17 0 64 7.17 64 16S71.17 32 80 32H304C312.84 32 320 39.16 320 48V64C320 81.67 305.67 96 288 96H224L373.49 176.5L448 32H528C536.84 32 544 39.16 544 48V64C544 81.67 529.67 96 512 96H483.78L428.67 206.21L521.14 256H544C597.02 256 640 298.98 640 352V384C640 401.67 625.67 416 608 416zM512 400C520.84 400 528 392.8400000000001 528 384S520.84 368 512 368S496 375.16 496 384S503.16 400 512 400zM544 304H509.04L407.2 249.16L393.43 276.7100000000001L512 336H589.05C582.43 317.42 564.8299999999999 304 544 304z" />
<glyph glyph-name="outdent"
unicode="&#xF03B;"
horiz-adv-x="448" d=" M0 364V404C0 412.837 7.163 420 16 420H432C440.837 420 448 412.837 448 404V364C448 355.163 440.837 348 432 348H16C7.163 348 0 355.163 0 364zM208 220H432C440.837 220 448 227.163 448 236V276C448 284.837 440.837 292 432 292H208C199.163 292 192 284.837 192 276V236C192 227.163 199.163 220 208 220zM16 -36H432C440.837 -36 448 -28.837 448 -20V20C448 28.837 440.837 36 432 36H16C7.163 36 0 28.837 0 20V-20C0 -28.837 7.163 -36 16 -36zM208 92H432C440.837 92 448 99.163 448 108V148C448 156.837 440.837 164 432 164H208C199.163 164 192 156.837 192 148V108C192 99.163 199.163 92 208 92zM4.687 180.687L100.687 84.703C110.734 74.652 128 81.776 128 96.016V287.992C128 302.3210000000001 110.675 309.296 100.687 299.305L4.687 203.313C-1.562 197.065 -1.562 186.935 4.687 180.687z" />
@@ -1556,7 +1640,7 @@
horiz-adv-x="448" d=" M144 -31H48C21.5 -31 0 -9.5 0 17V369C0 395.5 21.5 417 48 417H144C170.5 417 192 395.5 192 369V17C192 -9.5 170.5 -31 144 -31zM448 17V369C448 395.5 426.5 417 400 417H304C277.5 417 256 395.5 256 369V17C256 -9.5 277.5 -31 304 -31H400C426.5 -31 448 -9.5 448 17z" />
<glyph glyph-name="paw"
unicode="&#xF1B0;"
horiz-adv-x="512" d=" M85.231 117.042C36 117.042 0 174.208 0 216.5C0 244.792 16 274.5420000000001 49.538 274.5420000000001C98.769 274.5420000000001 134.769 217.084 134.769 174.792C134.769 146.5 119.077 117.042 85.231 117.042zM433.231 10.875C433.231 -26.167 401.231 -32 369.846 -32C328.615 -32 295.384 -5.75 256 -5.75C214.769 -5.75 179.692 -31.708 135.077 -31.708C105.23 -31.708 78.769 -22.083 78.769 10.875C78.769 80 180.616 182.667 256 182.667S433.231 79.708 433.231 10.875zM182.462 244.208C132.615 244.208 102.462 303.708 102.462 344.541C102.462 377.208 120.308 416 160 416C210.154 416 240 356.5 240 315.6670000000001C240 283 222.154 244.208 182.462 244.208zM272 315.6670000000001C272 356.5 301.846 416 352 416C391.692 416 409.539 377.208 409.539 344.5420000000001C409.539 303.709 379.385 244.209 329.538 244.209C289.846 244.208 272 283 272 315.6670000000001zM512 216.5C512 174.208 476 117.042 426.769 117.042C392.9220000000001 117.042 377.231 146.5 377.231 174.792C377.231 217.083 413.23 274.5420000000001 462.462 274.5420000000001C496 274.5420000000001 512 244.792 512 216.5z" />
horiz-adv-x="512" d=" M256 224C176.59 224 64 101.24 64 23.75C64 -11.15 90.81 -32 135.74 -32C184.58 -32 216.83 -6.92 256 -6.92C295.51 -6.92 327.85 -32 376.26 -32C421.19 -32 448 -11.15 448 23.75C448 101.24 335.4100000000001 224 256 224zM108.72 236.61C98.32 271.26 66.28 293.7000000000001 37.16 286.74C8.04 279.78 -7.13 246.05 3.27 211.4C13.67 176.75 45.71 154.31 74.83 161.27C103.95 168.23 119.12 201.96 108.72 236.61zM193.44 257.39C224.38 265.5300000000001 239.86 307.3300000000001 228.02 350.75S181.5 422.76 150.56 414.62S104.14 364.68 115.98 321.26C127.82 277.8400000000001 162.51 249.24 193.44 257.39zM474.83 286.73C445.71 293.6900000000001 413.68 271.25 403.27 236.6C392.87 201.95 408.04 168.22 437.16 161.26C466.28 154.3 498.3099999999999 176.74 508.72 211.39C519.12 246.04 503.95 279.77 474.83 286.73zM318.56 257.39C349.5 249.25 384.18 277.8400000000001 396.0199999999999 321.26C407.8599999999999 364.68 392.38 406.4700000000001 361.44 414.62S295.82 394.17 283.98 350.75C272.14 307.3300000000001 287.62 265.5300000000001 318.56 257.3900000000001z" />
<glyph glyph-name="peace"
unicode="&#xF67C;"
horiz-adv-x="496" d=" M248 440C111.03 440 0 328.9700000000001 0 192S111.03 -56 248 -56S496 55.03 496 192S384.9700000000001 440 248 440zM432 192C432 160.07 423.8 130.03 409.43 103.83L280 207.37V373.03C366.23 357.82 432 282.53 432 192zM216 10.97C182.14 16.9400000000001 151.51 32.17 126.71 53.99L216 125.43V10.97zM280 125.43L369.29 54C344.49 32.18 313.86 16.95 280 10.98V125.43zM216 373.03V207.37L86.57 103.83C72.2 130.03 64 160.07 64 192C64 282.53 129.77 357.82 216 373.03z" />
@@ -1740,6 +1824,9 @@
<glyph glyph-name="ribbon"
unicode="&#xF4D6;"
horiz-adv-x="448" d=" M6.1 3.7C-3.5 -7.1 -1.4 -23.9 10.6 -32L79.4 -59.9C89.3 -66.6 102.7 -64.9 110.7 -56.1L202.5 45.8000000000001L123.3 133.7000000000001L6.1 3.7zM441.9000000000001 3.7S149.9 328.3 146.5000000000001 333.8C161.9000000000001 342.2000000000001 186.7000000000001 351.7000000000001 224.0000000000001 351.7000000000001S286.1000000000001 342.2000000000001 301.5000000000001 333.8C298.2000000000001 328.2000000000001 245.5000000000001 269.2000000000001 245.5000000000001 269.2000000000001L324.6 181.5L358.8 219.5C387.5 251.4 392.1 298.1 370.2 335L326.5 408.5C322.2 415.7 316.6 421.8 309.7 426.5C269 454.1 182.3 456.2 138.3 426.5C131.4 421.8 125.8 415.7 121.5 408.5L77.9 335.3C76.4 332.8 40.8 273.1 89.4 219.3L337.5 -56C345.5 -64.9 358.9 -66.5 368.8 -59.8L437.6 -31.9C449.5 -23.9 451.6 -7.1 441.9000000000001 3.7z" />
<glyph glyph-name="ring"
unicode="&#xF70B;"
horiz-adv-x="512" d=" M256 384C110.06 384 0 322.0900000000001 0 240V141.87C0 63.52 114.62 0 256 0S512 63.52 512 141.87V240C512 322.0900000000001 401.94 384 256 384zM256 320C362.04 320 448 284.18 448 240C448 230.74 444.03 221.88 437.09 213.61C392.15 239.79 328.23 256 256 256S119.85 239.79 74.91 213.61C67.97 221.88 64 230.74 64 240C64 284.18 149.96 320 256 320zM120.43 183.36C155.04 198.07 201.64 208 256 208S356.96 198.07 391.57 183.36C356.84 168.93 308.93 160 256 160S155.16 168.93 120.43 183.36z" />
<glyph glyph-name="road"
unicode="&#xF018;"
horiz-adv-x="576" d=" M573.19 45.33L433.4000000000001 365.33C428.43 376.71 417.6 384 405.68 384H308.0900000000001L310.54 360.8400000000001C311.04 356.12 307.3300000000001 352 302.5800000000001 352H273.42C268.67 352 264.9600000000001 356.12 265.4600000000001 360.8400000000001L267.9100000000001 384H170.32C158.39 384 147.56 376.71 142.59 365.33L2.8 45.33C-6.45 24.14 8.31 0 30.54 0H227.38L237.69 97.68C238.55 105.82 245.41 112 253.6 112H322.4C330.59 112 337.45 105.82 338.31 97.68L348.62 0H545.46C567.69 0 582.45 24.14 573.19 45.33zM260.4 312.8400000000001A8 8 0 0 0 268.36 320H307.65C311.74 320 315.18 316.91 315.61 312.8400000000001L320.21 269.26C320.96 262.17 315.4 256 308.28 256H267.74C260.61 256 255.06 262.17 255.81 269.26L260.3999999999999 312.84zM315.64 144H260.35C250.85 144 243.44 152.23 244.44 161.68L249.51 209.68C250.37 217.82 257.23 224 265.42 224H310.57C318.76 224 325.62 217.82 326.48 209.68L331.55 161.68C332.55 152.23 325.14 144 315.64 144z" />
@@ -1773,6 +1860,9 @@
<glyph glyph-name="ruler"
unicode="&#xF545;"
horiz-adv-x="640" d=" M635.7 280.8L556.1 416.3C547.3000000000001 431.3 527.8000000000001 436.4 512.6 427.8L443.6 388.7L503.3 287C505.5 283.2 504.2 278.5 500.4 276.3L486.6 268.5C482.8 266.3 477.9 267.6 475.7 271.4L416 373L360.8 341.7L388.7 294.3C390.9 290.5 389.6 285.8 385.8 283.6L372 275.8C368.2 273.6 363.3 274.9 361.1 278.7000000000001L333.2 326L278 294.7L337.8 193C340 189.3 338.7 184.5 334.9000000000001 182.3L321.1 174.5C317.3 172.3 312.4000000000001 173.6 310.2000000000001 177.4L250.5000000000001 279.1L195.3000000000001 247.8L223.2000000000001 200.4C225.4000000000001 196.5999999999999 224.1000000000001 191.9 220.3000000000001 189.6999999999999L206.5000000000001 181.8999999999999C202.7000000000001 179.6999999999999 197.8000000000001 181 195.6000000000001 184.7999999999999L167.7000000000001 232.2999999999999L112.5 200.9999999999999L172.2000000000001 99.2999999999999C174.4 95.5999999999999 173.1000000000001 90.7999999999999 169.3000000000001 88.5999999999999L155.5 80.7999999999999C151.7 78.5999999999999 146.8000000000001 79.8999999999999 144.6 83.6999999999999L84.9 185.1L15.9 146C0.7 137.3 -4.6 118.2 4.2 103.2L83.8 -32.4C92.6 -47.4 112.1 -52.5 127.3 -43.9L624.1 238C639.3000000000001 246.6 644.5 265.8 635.7 280.8z" />
<glyph glyph-name="running"
unicode="&#xF70C;"
horiz-adv-x="416" d=" M272 352C298.51 352 320 373.49 320 400S298.51 448 272 448S224 426.51 224 400S245.49 352 272 352zM113.69 130.53L98.89 96.01H32C14.33 96.01 0 81.68 0 64.01S14.33 32.01 32 32.01H109.45C128.7 32.01 146.03 43.45 153.56 61.1L162.35 81.62L151.68 87.92C134.36 98.15 121.62 113.29 113.69 130.53zM384 224.01H339.9700000000001L313.9100000000001 277.26C301.4100000000001 302.81 278.4600000000001 321.49 252.13 328.2L181.05 349.34C152.75 356.14 123.28 349.89 100.21 332.2L60.54 301.79C46.51 291.04 43.85 270.96 54.62 256.93S85.46 240.27 99.48 251.01L139.17 281.42C146.84 287.31 156.61 289.42 164.44 287.56L179.14 283.19L141.68 195.8C129.06 166.32 140.37 131.79 167.98 115.49L252.9600000000001 65.32L225.4900000000001 -22.41C220.21 -39.27 229.6000000000001 -57.22 246.4600000000001 -62.5C249.6500000000001 -63.5 252.8700000000001 -63.98 256.04 -63.98C269.6500000000001 -63.98 282.2700000000001 -55.21 286.56 -41.53L318.2 59.53C324.11 80.3 315.31 102.61 296.56 113.92L235.32 150.06L266.63 228.34L286.9 186.91C294.9 170.57 311.82 160.02 330.01 160.02H384C401.67 160.02 416 174.35 416 192.02S401.67 224.01 384 224.01z" />
<glyph glyph-name="rupee-sign"
unicode="&#xF156;"
horiz-adv-x="320" d=" M308 352C314.627 352 320 357.373 320 364V404C320 410.627 314.627 416 308 416H12C5.373 416 0 410.627 0 404V359.252C0 352.625 5.373 347.252 12 347.252H97.28C124.588 347.252 145.541 337.294 158.25 320H12C5.373 320 0 314.627 0 308V268C0 261.373 5.373 256 12 256H170.757C164.54 219.914 137.796 197.368 96 197.368H12C5.373 197.368 0 191.995 0 185.368V132.356C0 129.007 1.4 125.81 3.861 123.538L168.913 -28.818A12.001000000000001 12.001000000000001 0 0 1 177.052 -32H259.614C270.538 -32 275.78 -18.592 267.753 -11.182L116.871 128.094C193.37 130.434 248.015 181.489 255.189 256H308C314.627 256 320 261.373 320 268V308C320 314.627 314.627 320 308 320H249.31C245.824 331.541 241.03 342.246 235.058 352H308z" />
@@ -1791,6 +1881,9 @@
<glyph glyph-name="screwdriver"
unicode="&#xF54A;"
horiz-adv-x="512" d=" M448 448L320 352V289.94L236.97 206.91C243.76 202.66 250.24 197.85 256.04 192.04C261.8400000000001 186.24 266.6600000000001 179.76 270.9100000000001 172.97L353.94 256H416L512 384L448 448zM128 169.41L10.92 52.33C-3.63 37.78 -3.63 14.18 10.92 -0.38L63.62 -53.08C78.18 -67.64 101.77 -67.64 116.33 -53.08L233.41 64C262.52 93.11 262.52 140.3 233.41 169.41S157.11 198.52 128 169.41z" />
<glyph glyph-name="scroll"
unicode="&#xF70E;"
horiz-adv-x="640" d=" M48 448C21.53 448 0 426.4700000000001 0 400V336C0 327.16 7.16 320 16 320H96V400C96 426.4700000000001 74.47 448 48 448zM256 35.43V96H544V352C544 404.94 500.94 448 448 448H111.59C121.74 434.59 128 418.08 128 400V32C128 -6.87 162.65 -37.65 202.75 -31.12C234.22 -26 256 3.54 256 35.43zM288 64V32C288 -20.93 244.94 -64 192 -64H528C589.86 -64 640 -13.86 640 48C640 56.84 632.84 64 624 64H288z" />
<glyph glyph-name="search-dollar"
unicode="&#xF688;"
horiz-adv-x="512" d=" M505.04 5.34L405.3300000000001 105.03C400.8300000000001 109.53 394.73 112.03 388.3300000000001 112.03H372.0300000000001C399.6300000000001 147.33 416.0300000000001 191.72 416.0300000000001 240.02C416.03 354.91 322.92 448 208.02 448S0 354.91 0 240.02S93.11 32.04 208.02 32.04C256.32 32.04 300.73 48.44 336.03 76.04V59.74C336.03 53.34 338.53 47.24 343.03 42.74L442.74 -56.95C452.1399999999999 -66.35 467.34 -66.35 476.6399999999999 -56.95L504.9399999999999 -28.65C514.3399999999999 -19.25 514.3399999999999 -4.06 505.04 5.34zM208.0200000000001 96.04C128.48 96.04 64.02 160.38 64.02 240.02C64.02 319.55 128.37 384 208.0200000000001 384C287.5600000000001 384 352.0200000000001 319.66 352.0200000000001 240.02C352.0200000000001 160.49 287.6700000000001 96.04 208.0200000000001 96.04zM235.1300000000001 248.58L190.1200000000001 262.08C184.9600000000001 263.63 181.3500000000001 268.86 181.3500000000001 274.81C181.3500000000001 282.08 186.6500000000001 288 193.1500000000001 288H221.2600000000001C225.8200000000001 288 230.2200000000001 286.7099999999999 234.0800000000001 284.28C237.3200000000001 282.25 241.4400000000001 282.37 244.2100000000001 285.01L255.9600000000001 296.2199999999999C259.49 299.5899999999999 259.29 305.43 255.3900000000001 308.36C246.2900000000001 315.19 235.3100000000001 319.13 224.0200000000001 319.7099999999999V336C224.0200000000001 340.42 220.44 344 216.0200000000001 344H200.0200000000001C195.6000000000001 344 192.0200000000001 340.42 192.0200000000001 336V319.88C168.3900000000001 319.25 149.34 299.33 149.34 274.81C149.34 254.84 162.3300000000001 237 180.92 231.42L225.93 217.92C231.09 216.37 234.7 211.14 234.7 205.19C234.7 197.92 229.4 192 222.9 192H194.8C190.24 192 185.84 193.29 181.98 195.72C178.74 197.75 174.62 197.63 171.85 194.9900000000001L160.1 183.78C156.57 180.41 156.77 174.5700000000001 160.67 171.6400000000001C169.77 164.8100000000001 180.75 160.8700000000001 192.04 160.29V144C192.04 139.58 195.62 136 200.04 136H216.04C220.46 136 224.04 139.58 224.04 144V160.12C247.67 160.75 266.7200000000001 180.66 266.7200000000001 205.19C266.7200000000001 225.16 253.73 243 235.13 248.58z" />
@@ -1878,9 +1971,15 @@
<glyph glyph-name="sitemap"
unicode="&#xF0E8;"
horiz-adv-x="640" d=" M128 96H32C14.33 96 0 81.67 0 64V-32C0 -49.67 14.33 -64 32 -64H128C145.67 -64 160 -49.67 160 -32V64C160 81.67 145.67 96 128 96zM104 176H296V128H344V176H536V128H584V185.59C584 206.7600000000001 566.77 224 545.59 224H344V288H384C401.67 288 416 302.3300000000001 416 320V416C416 433.67 401.67 448 384 448H256C238.33 448 224 433.67 224 416V320C224 302.33 238.33 288 256 288H296V224H94.41C73.23 224 56 206.77 56 185.59V128H104V176zM368 96H272C254.33 96 240 81.67 240 64V-32C240 -49.67 254.33 -64 272 -64H368C385.67 -64 400 -49.67 400 -32V64C400 81.67 385.67 96 368 96zM608 96H512C494.33 96 480 81.67 480 64V-32C480 -49.67 494.33 -64 512 -64H608C625.67 -64 640 -49.67 640 -32V64C640 81.67 625.67 96 608 96z" />
<glyph glyph-name="skull-crossbones"
unicode="&#xF714;"
horiz-adv-x="448" d=" M439.15 -5.06L297.17 64L439.1600000000001 133.06C447.06 137.01 450.2700000000001 146.62 446.31 154.52L432 183.15C428.05 191.05 418.44 194.26 410.53 190.31L224 99.59L37.47 190.31C29.57 194.26 19.96 191.06 16 183.15L1.69 154.52C-2.26 146.62 0.94 137.01 8.84 133.06L150.83 64L8.85 -5.06C0.95 -9.01 -2.26 -18.62 1.7 -26.53L16.01 -55.16C19.96 -63.0599999999999 29.57 -66.27 37.48 -62.3099999999999L224 28.41L410.53 -62.3099999999999C418.43 -66.26 428.04 -63.0599999999999 432 -55.16L446.31 -26.53C450.26 -18.6199999999999 447.05 -9.01 439.15 -5.0599999999999zM150 210.72L144.52 184.85C141.85 172.23 149.94 160 160.97 160H287.05C298.08 160 306.17 172.23 303.5 184.85L298 210.72C339.78 233.13 368 273.4700000000001 368 320C368 390.69 303.53 448 224 448S80 390.69 80 320C80 273.4700000000001 108.22 233.13 150 210.72zM280 336C297.65 336 312 321.65 312 304S297.65 272 280 272S248 286.35 248 304S262.35 336 280 336zM168 336C185.65 336 200 321.65 200 304S185.65 272 168 272S136 286.35 136 304S150.35 336 168 336z" />
<glyph glyph-name="skull"
unicode="&#xF54C;"
horiz-adv-x="512" d=" M256 448C114.6 448 0 347.7 0 224C0 153.9 36.9 91.4 94.5 50.3C104.1 43.4 109.7 32.2 108 20.4L98.6 -45.8C97.2 -55.4 104.6 -63.9999999999999 114.3 -63.9999999999999H192V-7.9999999999999C192 -3.6 195.6 1e-13 200 1e-13H216C220.4 1e-13 224 -3.6 224 -7.9999999999999V-63.9999999999999H288V-7.9999999999999C288 -3.6 291.6 1e-13 296 1e-13H312C316.4 1e-13 320 -3.6 320 -7.9999999999999V-63.9999999999999H397.7C407.4 -63.9999999999999 414.8 -55.3999999999999 413.4 -45.8L404 20.4C402.3 32.1 407.8 43.4 417.5 50.3C475.1 91.4 512 153.9 512 224C512 347.7 397.4 448 256 448zM160 128C124.7 128 96 156.7 96 192S124.7 256 160 256S224 227.3 224 192S195.3 128 160 128zM352 128C316.7 128 288 156.7 288 192S316.7 256 352 256S416 227.3 416 192S387.3 128 352 128z" />
<glyph glyph-name="slash"
unicode="&#xF715;"
horiz-adv-x="640" d=" M594.53 -60.63L6.18 394.1C-0.79 399.52 -2.05 409.57 3.37 416.55L23.01 441.82C28.43 448.8 38.49 450.06 45.47 444.63L633.82 -10.1C640.7900000000001 -15.52 642.0500000000001 -25.57 636.63 -32.55L616.99 -57.82C611.57 -64.7999999999999 601.51 -66.0499999999999 594.53 -60.63z" />
<glyph glyph-name="sliders-h"
unicode="&#xF1DE;"
horiz-adv-x="512" d=" M496 64H160V80C160 88.8 152.8 96 144 96H112C103.2 96 96 88.8 96 80V64H16C7.2 64 0 56.8 0 48V16C0 7.2 7.2 0 16 0H96V-16C96 -24.8 103.2 -32 112 -32H144C152.8 -32 160 -24.8 160 -16V0H496C504.8 0 512 7.2 512 16V48C512 56.8 504.8 64 496 64zM496 224H416V240C416 248.8 408.8 256 400 256H368C359.2 256 352 248.8 352 240V224H16C7.2 224 0 216.8 0 208V176C0 167.2 7.2 160 16 160H352V144C352 135.2 359.2 128 368 128H400C408.8 128 416 135.2 416 144V160H496C504.8 160 512 167.2 512 176V208C512 216.8 504.8 224 496 224zM496 384H288V400C288 408.8 280.8 416 272 416H240C231.2 416 224 408.8 224 400V384H16C7.2 384 0 376.8 0 368V336C0 327.2 7.2 320 16 320H224V304C224 295.2 231.2 288 240 288H272C280.8 288 288 295.2 288 304V320H496C504.8 320 512 327.2 512 336V368C512 376.8 504.8 384 496 384z" />
@@ -1941,6 +2040,9 @@
<glyph glyph-name="space-shuttle"
unicode="&#xF197;"
horiz-adv-x="640" d=" M592.604 239.756C559.735 255.164 515.777 264 472 264H186.327C181.375 270.555 175.742 275.978 169.607 280H376C229.157 310.253 219.403 416 96.003 416H96V288H80V416C53.49 416 32 387.346 32 352V288C8.803 288 0 277.968 0 264V224C0 210.017 8.819 200 32 200V184C8.803 184 0 173.968 0 160V120C0 106.017 8.819 96 32 96V32C32 -3.346 53.49 -32 80 -32V96H96V-32H96.003C219.403 -32 229.157 73.747 376 104H169.606C175.741 108.022 181.374 113.445 186.326 120H472C515.777 120 559.735 128.836 592.604 144.244C622.282 158.155 640 176.008 640 192S622.282 225.845 592.604 239.756zM488 152A8 8 0 0 0 480 160V224A8 8 0 0 0 488 232C519.909 232 519.942 152 488 152z" />
<glyph glyph-name="spider"
unicode="&#xF717;"
horiz-adv-x="576" d=" M151.17 280.65L177.1 272H181.77L186.99 298.12C187.71 301.7000000000001 188.79 305.7000000000001 190.2 309.91L169.91 350.49L193.71 421.88C196.5 430.26 191.98 439.32 183.59 442.12L168.42 447.18C160.04 449.98 150.97 445.45 148.18 437.06L122.29 359.38A32.04 32.04 0 0 1 124.02 334.95L151.17 280.65zM573.31 98.62L520.56 177.74A32.002 32.002 0 0 1 493.9399999999999 191.99H416L484.99 216.35A32.03 32.03 0 0 1 501.5 228.9600000000001L555.1 309.37C560 316.7200000000001 558.01 326.6600000000001 550.66 331.5600000000001L537.35 340.4400000000001C530 345.3400000000001 520.0600000000001 343.35 515.16 336L464.6 260.17L404.1 240H368L357.63 291.85C355.44 302.82 340.26 352 288 352C235.74 352 220.56 302.82 218.37 291.85L208 240H171.9L111.41 260.17L60.84 336C55.94 343.35 46.01 345.3400000000001 38.65 340.44L25.34 331.56C17.99 326.66 16 316.73 20.9 309.37L74.5 228.96A32.03 32.03 0 0 1 91.01 216.35L160 192H82.06A32.02 32.02 0 0 1 55.43 177.75L2.69 98.62C-2.21 91.27 -0.23 81.33 7.13 76.43L20.44 67.55C27.79 62.65 37.73 64.64 42.63 71.99L90.63 143.99H137.69L76.86 46.66A31.988 31.988 0 0 1 72 29.7V-48C72 -56.84 79.16 -64 88 -64H104C112.84 -64 120 -56.84 120 -48V25.11L194.08 143.64C193.07 129.59 192 115.53 192 101.43C192 48.36 232.76 0 288 0S384 48.36 384 101.43C384 115.53 382.92 129.59 381.92 143.64L456 25.11V-48C456 -56.84 463.16 -64 472 -64H488C496.84 -64 504 -56.84 504 -48V29.71C504 35.71 502.31 41.59 499.14 46.67L438.31 144H485.37L533.37 72C538.27 64.65 548.21 62.66 555.5600000000001 67.56L568.87 76.44C576.23 81.34 578.21 91.27 573.3100000000001 98.62zM406.09 350.49L385.8 309.91C387.21 305.7 388.29 301.7 389.01 298.12L394.23 272H398.9L424.83 280.65L451.98 334.95A31.995 31.995 0 0 1 453.71 359.38L427.82 437.06C425.03 445.44 415.96 449.98 407.58 447.18L392.41 442.12C384.03 439.32 379.5 430.26 382.29 421.88L406.09 350.49z" />
<glyph glyph-name="spinner"
unicode="&#xF110;"
horiz-adv-x="512" d=" M304 400C304 373.49 282.51 352 256 352S208 373.49 208 400S229.49 448 256 448S304 426.51 304 400zM256 32C229.49 32 208 10.51 208 -16S229.49 -64 256 -64S304 -42.51 304 -16S282.51 32 256 32zM464 240C437.49 240 416 218.51 416 192S437.49 144 464 144S512 165.49 512 192S490.51 240 464 240zM96 192C96 218.51 74.51 240 48 240S0 218.51 0 192S21.49 144 48 144S96 165.49 96 192zM108.922 92.922C82.412 92.922 60.922 71.432 60.922 44.922S82.412 -3.078 108.922 -3.078S156.922 18.412 156.922 44.922C156.922 71.431 135.431 92.922 108.922 92.922zM403.078 92.922C376.568 92.922 355.078 71.432 355.078 44.922S376.568 -3.078 403.078 -3.078S451.078 18.412 451.078 44.922C451.078 71.431 429.588 92.922 403.078 92.922zM108.922 387.078C82.412 387.078 60.922 365.588 60.922 339.078S82.412 291.078 108.922 291.078S156.922 312.568 156.922 339.078S135.431 387.078 108.922 387.078z" />
@@ -2172,6 +2274,9 @@
<glyph glyph-name="toggle-on"
unicode="&#xF205;"
horiz-adv-x="576" d=" M576 192C576 85.961 490.039 0 384 0H192C85.961 0 0 85.961 0 192S85.961 384 192 384H384C490.039 384 576 298.039 576 192zM384 320C313.259 320 256 262.751 256 192C256 121.259 313.249 64 384 64C454.741 64 512 121.249 512 192C512 262.741 454.751 320 384 320" />
<glyph glyph-name="toilet-paper"
unicode="&#xF71E;"
horiz-adv-x="576" d=" M128 448C74.98 448 32 362.04 32 256V83.93C32 42.81 22.2 21.16 0.83 -42.94C-2.62 -53.3 5.09 -64 16.01 -64H296.93C310.7 -64 322.93 -55.19 327.29 -42.12C340.12 -3.64 352 30.28 352 83.93V256C352 339.6 375.67 409.52 412.44 448H128zM96 224C87.16 224 80 231.16 80 240S87.16 256 96 256S112 248.84 112 240S104.84 224 96 224zM160 224C151.16 224 144 231.16 144 240S151.16 256 160 256S176 248.84 176 240S168.84 224 160 224zM224 224C215.16 224 208 231.16 208 240S215.16 256 224 256S240 248.84 240 240S232.84 224 224 224zM288 224C279.1600000000001 224 272 231.16 272 240S279.1600000000001 256 288 256S304 248.84 304 240S296.84 224 288 224zM480 448C426.98 448 384 362.04 384 256S426.98 64 480 64S576 149.96 576 256S533.02 448 480 448zM480 192C462.33 192 448 220.65 448 256S462.33 320 480 320S512 291.35 512 256S497.67 192 480 192z" />
<glyph glyph-name="toolbox"
unicode="&#xF552;"
horiz-adv-x="512" d=" M502.63 233.37L457.38 278.62C451.38 284.62 443.24 287.99 434.75 287.99H384V368C384 394.51 362.51 416 336 416H176C149.49 416 128 394.51 128 368V288H77.25C68.76 288 60.63 284.63 54.62 278.63L9.37 233.37C3.37 227.37 0 219.23 0 210.74V128H128V144C128 152.84 135.16 160 144 160H176C184.84 160 192 152.84 192 144V128H320V144C320 152.84 327.1600000000001 160 336 160H368C376.84 160 384 152.84 384 144V128H512V210.75C512 219.23 508.63 227.37 502.63 233.37zM320 288H192V352H320V288zM384 80C384 71.16 376.84 64 368 64H336C327.1600000000001 64 320 71.16 320 80V96H192V80C192 71.16 184.84 64 176 64H144C135.16 64 128 71.16 128 80V96H0V0C0 -17.67 14.33 -32 32 -32H480C497.67 -32 512 -17.67 512 0V96H384V80z" />
@@ -2184,6 +2289,9 @@
<glyph glyph-name="torii-gate"
unicode="&#xF6A1;"
horiz-adv-x="512" d=" M376.45 416H135.55A303.17 303.17 0 0 0 0 448V352C0 334.33 14.33 320 32 320H64V256H16C7.16 256 0 248.84 0 240V208C0 199.16 7.16 192 16 192H64V-48C64 -56.84 71.16 -64 80 -64H112C120.84 -64 128 -56.84 128 -48V192H384V-48C384 -56.84 391.1600000000001 -64 400 -64H432C440.84 -64 448 -56.84 448 -48V192H496C504.84 192 512 199.16 512 208V240C512 248.84 504.84 256 496 256H448V320H480C497.67 320 512 334.33 512 352V448A303.17 303.17 0 0 0 376.45 416zM128 320H224V256H128V320zM384 256H288V320H384V256z" />
<glyph glyph-name="tractor"
unicode="&#xF722;"
horiz-adv-x="640" d=" M528 112C479.4 112 440 72.6 440 24S479.4 -64 528 -64S616 -24.6 616 24S576.6 112 528 112zM528 0C514.77 0 504 10.77 504 24S514.77 48 528 48S552 37.23 552 24S541.23 0 528 0zM608 288H544V328.2C544 342.32 548.7 355.9600000000001 557.15 367.04C561.5699999999999 372.8400000000001 560.6999999999999 381.1 555.8299999999999 386.53L534.2 410.7C527.5400000000001 418.15 515.88 417.62 509.5000000000001 409.92C490.58 387.1 480 358.19 480 328.2V288H377.67L321.58 418.86A47.914 47.914 0 0 1 277.45 448H144C117.53 448 96 426.4700000000001 96 400V253.48C87.37 260.21 75.04 259.94 67.11 252.01L36 220.9C27.41 212.31 27.41 198.38 36 189.79L41.06 184.73C36.07 175.47 32.1 165.91 29.15 156.01H22C9.85 156.01 0 146.16 0 134.01V90.01C0 77.86 9.85 68.01 22 68.01H29.14C32.1 58.1 36.06 48.55 41.05 39.28L35.99 34.22C27.4 25.63 27.4 11.7 35.99 3.11L67.1 -28C75.69 -36.59 89.62 -36.59 98.21 -28L103.27 -22.94C112.53 -27.93 122.09 -31.9 131.99 -34.85V-42C131.99 -54.15 141.84 -64 153.99 -64H197.99C210.14 -64 219.99 -54.15 219.99 -42V-34.86C229.89 -31.91 239.45 -27.94 248.71 -22.95L253.77 -28.01C262.36 -36.6 276.29 -36.6 284.88 -28.01L315.99 3.1C324.58 11.69 324.58 25.62 315.99 34.21L310.93 39.27C315.92 48.53 319.89 58.09 322.8400000000001 67.99H330C342.15 67.99 352 77.84 352 89.99V95.99H432.54C454.45 124.98 488.86 143.99 528 143.99C546.64 143.99 564.07 139.38 579.8 131.79L630.62 182.61C636.62 188.61 639.99 196.75 639.99 205.24V256C640 273.67 625.67 288 608 288zM176 32C131.82 32 96 67.82 96 112S131.82 192 176 192S256 156.18 256 112S220.18 32 176 32zM198 288H160V384H266.89L308.04 288H198z" />
<glyph glyph-name="trademark"
unicode="&#xF25C;"
horiz-adv-x="640" d=" M97.119 284.867H12C5.373 284.867 0 290.24 0 296.867V340C0 346.627 5.373 352 12 352H260.559C267.186 352 272.559 346.627 272.559 340V296.867C272.559 290.24 267.186 284.867 260.559 284.867H175.44V44C175.44 37.373 170.067 32 163.44 32H109.118C102.491 32 97.118 37.373 97.118 44V284.867zM329.825 352H395.25A12 12 0 0 0 406.596 343.907L450.355 216.839C457.516 196.251 466.466 164.027 466.466 164.027H467.362S476.312 196.251 483.473 216.839L527.231 343.907A12 12 0 0 0 538.577 352H603.987A12 12 0 0 0 615.948 340.9700000000001L639.96 44.97C640.527 37.983 635.009 32 627.999 32H573.898A12 12 0 0 0 561.926 43.182L552.844 176.112C551.0540000000001 200.28 552.844 229.8180000000001 552.844 229.8180000000001H551.9480000000001S541.2070000000001 196.2520000000001 534.046 176.112L503.3460000000001 91.381A12 12 0 0 0 492.0640000000001 83.4690000000001H441.7620000000001A12 12 0 0 0 430.4800000000001 91.381L399.7800000000001 176.112C392.6190000000001 196.252 381.8770000000001 229.8180000000001 381.8770000000001 229.8180000000001H380.9820000000001S382.7720000000001 200.28 380.9820000000001 176.112L371.9000000000001 43.182C371.4720000000001 36.887 366.2400000000001 32 359.9300000000001 32H305.4C298.383 32 292.864 37.994 293.441 44.987L317.866 340.987A11.999000000000002 11.999000000000002 0 0 0 329.825 352z" />
@@ -2207,7 +2315,7 @@
horiz-adv-x="448" d=" M0 364V392C0 405.3 10.7 416 24 416H136L145.4 434.7C149.4 442.9 157.7 448 166.8 448H281.1C290.2000000000001 448 298.5 442.9 302.6 434.7L312 416H424C437.3 416 448 405.3 448 392V364C448 357.4 442.6 352 436 352H12C5.4 352 0 357.4 0 364zM415.2 307.3L394.8 -19C393.2 -44.3 372.2 -64 346.9000000000001 -64H101.1C75.8 -64 54.8 -44.3 53.2 -19L32.8 307.3C32.4 314.2000000000001 37.9 320 44.8 320H403.3C410.1 320 415.6 314.2000000000001 415.2 307.3z" />
<glyph glyph-name="tree"
unicode="&#xF1BB;"
horiz-adv-x="384" d=" M377.33 72.571L293.906 160H328C349.017 160 359.872 185.207 345.448 200.479L262.79 288H296C316.878 288 327.851 312.969 313.587 328.331L209.587 440.334C200.102 450.548 183.911 450.563 174.413 440.334L70.413 328.331C56.206 313.031 67.037 288 88 288H121.21L38.551 200.479C24.121 185.199 34.993 160 56 160H90.094L6.665 72.571C-7.869 57.345 2.925 32 24.025 32H144C144 -0.781 132.812 -17.26 110.005 -35.506C98.225 -44.93 104.914 -64 120 -64H264C279.086 -64 285.776 -44.931 273.995 -35.506C254.227 -19.6919999999999 240.003 -3.841 240 31.99V32H359.9700000000001C381.0200000000001 32 391.899 57.309 377.3300000000001 72.571z" />
horiz-adv-x="384" d=" M378.31 69.51L298.42 160H329.05C338.06 160 346.0300000000001 165 349.8300000000001 173.06C353.6300000000001 181.1 352.3800000000001 190.32 346.5500000000001 197.11L268.42 288H297.31C306.4100000000001 288 314.61 293.35 318.17 301.61C321.69 309.74 320.0300000000001 319.2000000000001 313.93 325.69L203.66 443.17C197.63 449.62 186.38 449.62 180.34 443.17L70.06 325.69C63.96 319.2 62.31 309.74 65.82 301.61C69.38 293.35 77.59 288 86.69 288H115.58L37.44 197.09C31.63 190.31 30.38 181.1 34.17 173.05C37.97 165 45.93 160 54.95 160H85.58L5.69 69.51C-0.31 62.72 -1.67 53.42 2.13 45.25C5.88 37.2 14.13 32 23.14 32H160V7.55L129.71 -40.85C124.39 -51.4899999999999 132.13 -64.01 144.02 -64.01H239.98C251.87 -64.01 259.61 -51.49 254.29 -40.85L224 7.55V32H360.86C369.87 32 378.12 37.2 381.87 45.25C385.67 53.42 384.31 62.72 378.31 69.51z" />
<glyph glyph-name="trophy"
unicode="&#xF091;"
horiz-adv-x="576" d=" M552 384H448V424C448 437.3 437.3 448 424 448H152C138.7 448 128 437.3 128 424V384H24C10.7 384 0 373.3 0 360V304C0 268.3 22.5 231.6 61.9 203.3C93.4 180.6 131.7 166.2 171.9 161.6C203.3 109.5 240 88 240 88V16H192C156.7 16 128 -4.7 128 -40V-52C128 -58.6 133.4 -64 140 -64H436C442.6 -64 448 -58.6 448 -52V-40C448 -4.7 419.3 16 384 16H336V88S372.7 109.5 404.1 161.6C444.4000000000001 166.2000000000001 482.7 180.6 514.1 203.3C553.4 231.6 576 268.3 576 304V360C576 373.3 565.3 384 552 384zM99.3 255.2C74.9 272.8 64 292.4 64 304V320H128.2C129.2 287.4 134 258.8 141 233.8C125.9 239 111.8 246.2 99.3 255.2zM512 304C512 287.9 494.3 267.9 476.7 255.2C464.2 246.2 450 239 434.9 233.8C441.9 258.8 446.7 287.4 447.7 320H512V304z" />
@@ -2298,6 +2406,9 @@
<glyph glyph-name="user-graduate"
unicode="&#xF501;"
horiz-adv-x="448" d=" M319.4 127.4L224 32L128.6 127.4C57.1 124.3 0 65.8 0 -6.4V-16C0 -42.5 21.5 -64 48 -64H400C426.5 -64 448 -42.5 448 -16V-6.4C448 65.8 390.9 124.3 319.4 127.4zM13.6 368.2L20 366.7V308.3C13 304.1 8 296.8 8 288C8 279.6 12.6 272.6 19.1 268.3L3.5 206C1.8 199.1 5.6 192 11.1 192H52.9C58.4 192 62.2 199.1 60.5 206L44.9 268.3C51.4 272.6 56 279.6 56 288C56 296.8 51 304.1 44 308.3V360.9L110 345C101.4 327.8 96 308.6 96 288C96 217.3 153.3 160 224 160S352 217.3 352 288C352 308.6 346.7 327.8 338 345L434.3 368.2C452.5 372.6 452.5 395.3 434.3 399.7L243.9 445.7C230.9 448.8 217.2 448.8 204.2 445.7L13.6 399.8C-4.5 395.4 -4.5 372.6 13.6 368.2z" />
<glyph glyph-name="user-injured"
unicode="&#xF728;"
horiz-adv-x="448" d=" M277.37 436.02C261.08 443.53 243.11 448 224 448C170.31 448 124.5 414.87 105.49 368H186.68L277.37 436.02zM342.51 368C334.61 387.4700000000001 321.84 404.2 306.02 417.52L239.99 368H342.51zM224 192C294.69 192 352 249.31 352 320C352 325.48 351.05 330.7 350.39 336H97.61C96.94 330.7 96 325.48 96 320C96 249.31 153.31 192 224 192zM80 148.3V-64H208.26L109.81 157.52A132.835 132.835 0 0 1 80 148.3zM0 -16C0 -42.51 21.49 -64 48 -64V127.76C18.88 103.11 0 66.74 0 25.6V-16zM256 32H200.62L243.29 -64H256C282.4700000000001 -64 304 -42.47 304 -16S282.4700000000001 32 256 32zM313.6 160H296.8900000000001C274.6500000000001 149.82 250.0100000000001 144 224.0000000000001 144S173.3500000000001 149.82 151.1100000000001 160H143.7400000000001L186.4100000000001 64H256C300.11 64 336 28.11 336 -16C336 -34.08 329.74 -50.59 319.59 -64H400C426.51 -64 448 -42.51 448 -16V25.6C448 99.83 387.83 160 313.6 160z" />
<glyph glyph-name="user-lock"
unicode="&#xF502;"
horiz-adv-x="640" d=" M320 128C320 139.1 323.1 149.4 328.1 158.5C323.3 159 318.6 160 313.6 160H296.9000000000001C274.7000000000001 149.8 250.0000000000001 144 224 144S173.4 149.8 151.1 160H134.4C60.2 160 0 99.8 0 25.6V-16C0 -42.5 21.5 -64 48 -64H328.9C323.4 -54.5 320 -43.7 320 -32V128zM224 192C294.7 192 352 249.3 352 320S294.7 448 224 448S96 390.7 96 320S153.3 192 224 192zM608 160H576V208C576 252.2 540.2 288 496 288S416 252.2 416 208V160H384C366.3 160 352 145.7 352 128V-32C352 -49.7 366.3 -64 384 -64H608C625.7 -64 640 -49.7 640 -32V128C640 145.7 625.7 160 608 160zM528 160H464V208C464 225.6 478.4 240 496 240S528 225.6 528 208V160z" />
@@ -2379,6 +2490,9 @@
<glyph glyph-name="volume-down"
unicode="&#xF027;"
horiz-adv-x="384" d=" M215.03 375.96L126.06 287H24C10.74 287 0 276.26 0 263V119C0 105.75 10.74 95 24 95H126.06L215.03 6.05C230.06 -8.98 256 1.58 256 23.02V358.98C256 380.45 230.04 390.9600000000001 215.03 375.9600000000001zM338.23 267.88C326.6500000000001 274.2100000000001 312.04 270.04 305.62 258.43C299.23 246.82 303.46 232.23 315.07 225.82C327.98 218.72 336 205.38 336 191C336 176.62 327.98 163.28 315.08 156.19C303.47 149.78 299.24 135.19 305.63 123.58C312.06 111.92 326.68 107.78 338.24 114.13C366.4700000000001 129.68 384.01 159.13 384.01 191.01S366.47 252.33 338.23 267.88z" />
<glyph glyph-name="volume-mute"
unicode="&#xF6A9;"
horiz-adv-x="512" d=" M215.03 376.95L126.06 288H24C10.74 288 0 277.26 0 264V120C0 106.75 10.74 96 24 96H126.06L215.03 7.05C230.06 -7.98 256 2.58 256 24.02V359.98C256 381.44 230.04 391.9600000000001 215.03 376.95zM461.64 192L507.28 237.64C513.5799999999999 243.94 513.5799999999999 254.16 507.28 260.46L484.46 283.28C478.16 289.58 467.94 289.58 461.64 283.28L416 237.64L370.36 283.28C364.06 289.58 353.8400000000001 289.58 347.54 283.28L324.7200000000001 260.46C318.42 254.16 318.42 243.94 324.7200000000001 237.64L370.36 192L324.73 146.37C318.43 140.07 318.43 129.85 324.73 123.55L347.55 100.73C353.85 94.43 364.07 94.43 370.37 100.73L416 146.36L461.64 100.72C467.94 94.42 478.16 94.42 484.46 100.72L507.28 123.54C513.5799999999999 129.84 513.5799999999999 140.06 507.28 146.36L461.64 192z" />
<glyph glyph-name="volume-off"
unicode="&#xF026;"
horiz-adv-x="257.33" d=" M216.36 376.96L127.39 288H25.33C12.07 288 1.33 277.26 1.33 264V120C1.33 106.75 12.07 96 25.33 96H127.39L216.36 7.05C231.39 -7.98 257.3300000000001 2.58 257.3300000000001 24.02V359.98C257.3300000000001 381.45 231.3700000000001 391.9600000000001 216.3600000000001 376.9600000000001z" />
@@ -2406,6 +2520,9 @@
<glyph glyph-name="wifi"
unicode="&#xF1EB;"
horiz-adv-x="640" d=" M634.91 293.12C457.74 456.99 182.19 456.93 5.09 293.12C-1.57 286.9600000000001 -1.7 276.53 4.74 270.14L38.98 236.17C45.12 230.07 55 229.9400000000001 61.38 235.79C207.3 369.4700000000001 432.68 369.5 578.63 235.79C585.01 229.9400000000001 594.89 230.08 601.03 236.17L635.27 270.14C641.6999999999999 276.53 641.5699999999999 286.9600000000001 634.91 293.12zM320 96C284.65 96 256 67.35 256 32S284.65 -32 320 -32S384 -3.35 384 32S355.35 96 320 96zM522.67 179.59C407.41 281.5200000000001 232.46 281.4100000000001 117.33 179.59C110.43 173.49 110.21 162.9 116.76 156.4400000000001L151.2 122.4500000000001C157.2 116.53 166.86 116.1300000000001 173.25 121.65C257.2 194.22 382.99 194.06 466.74 121.65C473.13 116.1300000000001 482.79 116.5200000000001 488.79 122.4500000000001L523.23 156.4400000000001C529.79 162.9 529.5600000000001 173.5000000000001 522.6700000000001 179.59z" />
<glyph glyph-name="wind"
unicode="&#xF72E;"
horiz-adv-x="512" d=" M156.66 192H16C7.16 192 0 184.84 0 176V144C0 135.16 7.16 128 16 128H158.19C174.14 128 188.96 117.15 191.56 101.42C194.86 81.4 179.42 64 160 64C145.89 64 133.87 73.19 129.63 85.9C127.52 92.21 121.03 96 114.38 96H81.63C71.83 96 63.9 87.19 65.77 77.57C74.39 33.42 113.37 0 160 0C217.09 0 262.7 50.09 255.19 108.63C248.98 157.02 205.45 192 156.66 192zM16 224H352C411.7 224 458.83 278.76 445.83 340.69C438.22 376.92 408.92 406.2200000000001 372.69 413.83C317.25 425.4700000000001 267.56 388.92 257.76 338.3C255.9 328.73 263.85 320 273.6 320H306.4C313.05 320 319.54 323.79 321.65 330.1C325.88 342.81 337.89 352 352 352C371.42 352 386.86 334.61 383.55 314.5900000000001C380.95 298.86 366.13 288 350.18 288H16C7.16 288 0 280.8400000000001 0 272V240C0 231.16 7.16 224 16 224zM400 192H243.68C263.02 175.43 276.87 153.21 283.45 128H400C426.4700000000001 128 448 106.47 448 80S426.4700000000001 32 400 32C382.14 32 366.67 41.86 358.44 56.38C355.59 61.41 349.75 64 343.97 64H310.15C299.24 64 291.19 53.19 294.8 42.9C312.57 -7.7 365.34 -41.85 424.2099999999999 -29.45C465.4299999999999 -20.76 499.3099999999999 12.1999999999999 508.8799999999999 53.23C525.98 126.54 470.48 192 400 192z" />
<glyph glyph-name="window-close"
unicode="&#xF410;"
horiz-adv-x="512" d=" M464 416H48C21.5 416 0 394.5 0 368V16C0 -10.5 21.5 -32 48 -32H464C490.5 -32 512 -10.5 512 16V368C512 394.5 490.5 416 464 416zM380.4 125.5C385.2 120.7 385.2 112.9 380.4 108.1L339.9 67.6C335.1 62.8 327.3 62.8 322.5 67.6L256 134.7L189.5 67.6C184.7 62.8 176.9 62.8 172.1 67.6L131.6 108.1C126.8 112.9 126.8 120.7000000000001 131.6 125.5L198.7 192L131.6 258.5C126.8 263.3 126.8 271.1 131.6 275.9L172.1 316.4C176.9 321.2 184.7 321.2 189.5 316.4L256 249.3L322.5 316.4C327.3 321.2 335.1 321.2 339.9 316.4L380.4 275.9C385.2 271.1 385.2 263.3 380.4 258.5L313.3 192L380.4 125.5z" />
@@ -2418,6 +2535,9 @@
<glyph glyph-name="window-restore"
unicode="&#xF2D2;"
horiz-adv-x="512" d=" M512 400V112C512 85.5 490.5 64 464 64H416V272C416 316.1 380.1 352 336 352H128V400C128 426.5 149.5 448 176 448H464C490.5 448 512 426.5 512 400zM384 272V-16C384 -42.5 362.5 -64 336 -64H48C21.5 -64 0 -42.5 0 -16V272C0 298.5 21.5 320 48 320H336C362.5 320 384 298.5 384 272zM316 244C316 250.6 310.6 256 304 256H76C69.4 256 64 250.6 64 244V192H316V244z" />
<glyph glyph-name="wine-bottle"
unicode="&#xF72F;"
horiz-adv-x="512" d=" M507.31 375.43L439.43 443.31C433.18 449.56 423.05 449.56 416.8 443.31L394.17 420.68C387.92 414.43 387.92 404.3 394.17 398.05L317.5 321.38C270.92 341.08 215.1 332.11 177.13 294.15L18.75 135.77C-6.24 110.78 -6.24 70.25 18.75 45.26L109.26 -45.25C134.25 -70.24 174.78 -70.24 199.77 -45.25L358.16 113.14C396.12 151.1 405.09 206.93 385.39 253.51L462.06 330.18C468.31 323.93 478.44 323.93 484.69 330.18L507.32 352.81C513.56 359.05 513.56 369.18 507.31 375.43zM179.22 24.71L88.71 115.22L210.75 237.26L301.26 146.75L179.22 24.71z" />
<glyph glyph-name="wine-glass-alt"
unicode="&#xF5CE;"
horiz-adv-x="288" d=" M216 -16H176V101.19C244.47 117.08 294.05 181.1 287.4 255.35L271.45 433.45C270.71 441.69 263.9 448 255.74 448H32.26C24.11 448 17.29 441.69 16.56 433.45L0.6 255.34C-6.05 181.09 43.53 117.07 112 101.18V-16H72C49.91 -16 32 -33.91 32 -56C32 -60.42 35.58 -64 40 -64H248C252.42 -64 256 -60.42 256 -56C256 -33.91 238.09 -16 216 -16zM61.75 400H226.25L233.42 320H54.58L61.75 400z" />

Before

Width:  |  Height:  |  Size: 665 KiB

After

Width:  |  Height:  |  Size: 708 KiB

View File

@@ -12,13 +12,6 @@ pre.shiny-text-output.noplaceholder:empty {
height: 0;
}
/* Some browsers (like Safari) will wrap text in <pre> tags with Bootstrap's
CSS. This changes the behavior to not wrap.
*/
pre.shiny-text-output {
word-wrap: normal;
}
.shiny-image-output img.shiny-scalable, .shiny-plot-output img.shiny-scalable {
max-width: 100%;
max-height: 100%;
@@ -216,10 +209,6 @@ pre.shiny-text-output {
font-size: 80%;
}
.shiny-label-null {
display: none;
}
.crosshair {
cursor: crosshair;
}

View File

@@ -12,7 +12,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var exports = window.Shiny = window.Shiny || {};
exports.version = "1.3.2.9001"; // Version number inserted by Grunt
exports.version = "1.2.0"; // Version number inserted by Grunt
var origPushState = window.history.pushState;
window.history.pushState = function () {
@@ -321,24 +321,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if (op === "==") return diff === 0;else if (op === ">=") return diff >= 0;else if (op === ">") return diff > 0;else if (op === "<=") return diff <= 0;else if (op === "<") return diff < 0;else throw "Unknown operator: " + op;
};
function updateLabel(labelTxt, labelNode) {
// Only update if label was specified in the update method
if (typeof labelTxt === "undefined") return;
if (labelNode.length !== 1) {
throw new Error("labelNode must be of length 1");
}
// Should the label be empty?
var emptyLabel = $.isArray(labelTxt) && labelTxt.length === 0;
if (emptyLabel) {
labelNode.addClass("shiny-label-null");
} else {
labelNode.text(labelTxt);
labelNode.removeClass("shiny-label-null");
}
}
//---------------------------------------------------------------------
// Source file: ../srcjs/browser.js
@@ -563,8 +545,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.lastChanceCallback = [];
};
(function () {
this.setInput = function (nameType, value, opts) {
this.pendingData[nameType] = value;
this.setInput = function (name, value, opts) {
this.pendingData[name] = value;
if (!this.reentrant) {
if (opts.priority === "event") {
@@ -600,10 +582,11 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.lastSentValues = this.reset(initialValues);
};
(function () {
this.setInput = function (nameType, value, opts) {
var _splitInputNameType = splitInputNameType(nameType),
inputName = _splitInputNameType.name,
inputType = _splitInputNameType.inputType;
this.setInput = function (name, value, opts) {
var _splitInputNameType = splitInputNameType(name);
var inputName = _splitInputNameType.name;
var inputType = _splitInputNameType.inputType;
var jsonValue = JSON.stringify(value);
@@ -625,11 +608,12 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
for (var inputName in values) {
if (values.hasOwnProperty(inputName)) {
var _splitInputNameType2 = splitInputNameType(inputName),
_name = _splitInputNameType2.name,
inputType = _splitInputNameType2.inputType;
var _splitInputNameType2 = splitInputNameType(inputName);
cacheValues[_name] = {
var name = _splitInputNameType2.name;
var inputType = _splitInputNameType2.inputType;
cacheValues[name] = {
jsonValue: JSON.stringify(values[inputName]),
inputType: inputType
};
@@ -644,10 +628,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.target = target;
};
(function () {
this.setInput = function (nameType, value, opts) {
this.setInput = function (name, value, opts) {
var evt = jQuery.Event("shiny:inputchanged");
var input = splitInputNameType(nameType);
var input = splitInputNameType(name);
evt.name = input.name;
evt.inputType = input.inputType;
evt.value = value;
@@ -655,7 +639,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
evt.el = opts.el;
evt.priority = opts.priority;
$(opts.el).trigger(evt);
$(document).trigger(evt);
if (!evt.isDefaultPrevented()) {
name = evt.name;
@@ -673,37 +657,25 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.inputRatePolicies = {};
};
(function () {
// Note that the first argument of setInput() and setRatePolicy()
// are passed both the input name (i.e., inputId) and type.
// https://github.com/rstudio/shiny/blob/67d3a/srcjs/init_shiny.js#L111-L126
// However, $ensureInit() and $doSetInput() are meant to be passed just
// the input name (i.e., inputId), which is why we distinguish between
// nameType and name.
this.setInput = function (nameType, value, opts) {
var _splitInputNameType3 = splitInputNameType(nameType),
inputName = _splitInputNameType3.name;
this.setInput = function (name, value, opts) {
this.$ensureInit(name);
this.$ensureInit(inputName);
if (opts.priority !== "deferred") this.inputRatePolicies[inputName].immediateCall(nameType, value, opts);else this.inputRatePolicies[inputName].normalCall(nameType, value, opts);
if (opts.priority !== "deferred") this.inputRatePolicies[name].immediateCall(name, value, opts);else this.inputRatePolicies[name].normalCall(name, value, opts);
};
this.setRatePolicy = function (nameType, mode, millis) {
var _splitInputNameType4 = splitInputNameType(nameType),
inputName = _splitInputNameType4.name;
this.setRatePolicy = function (name, mode, millis) {
if (mode === 'direct') {
this.inputRatePolicies[inputName] = new Invoker(this, this.$doSetInput);
this.inputRatePolicies[name] = new Invoker(this, this.$doSetInput);
} else if (mode === 'debounce') {
this.inputRatePolicies[inputName] = new Debouncer(this, this.$doSetInput, millis);
this.inputRatePolicies[name] = new Debouncer(this, this.$doSetInput, millis);
} else if (mode === 'throttle') {
this.inputRatePolicies[inputName] = new Throttler(this, this.$doSetInput, millis);
this.inputRatePolicies[name] = new Throttler(this, this.$doSetInput, millis);
}
};
this.$ensureInit = function (name) {
if (!(name in this.inputRatePolicies)) this.setRatePolicy(name, 'direct');
};
this.$doSetInput = function (nameType, value, opts) {
this.target.setInput(nameType, value, opts);
this.$doSetInput = function (name, value, opts) {
this.target.setInput(name, value, opts);
};
}).call(InputRateDecorator.prototype);
@@ -712,8 +684,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.pendingInput = {};
};
(function () {
this.setInput = function (nameType, value, opts) {
if (/^\./.test(nameType)) this.target.setInput(nameType, value, opts);else this.pendingInput[name] = { value: value, opts: opts };
this.setInput = function (name, value, opts) {
if (/^\./.test(name)) this.target.setInput(name, value, opts);else this.pendingInput[name] = { value: value, opts: opts };
};
this.submit = function () {
for (var name in this.pendingInput) {
@@ -729,12 +701,12 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.target = target;
};
(function () {
this.setInput = function (nameType, value, opts) {
if (!nameType) throw "Can't set input with empty name.";
this.setInput = function (name, value, opts) {
if (!name) throw "Can't set input with empty name.";
opts = addDefaultInputOpts(opts);
this.target.setInput(nameType, value, opts);
this.target.setInput(name, value, opts);
};
}).call(InputValidateDecorator.prototype);
@@ -761,8 +733,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
return opts;
}
function splitInputNameType(nameType) {
var name2 = nameType.split(':');
function splitInputNameType(name) {
var name2 = name.split(':');
return {
name: name2[0],
inputType: name2.length > 1 ? name2[1] : ''
@@ -1799,7 +1771,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var $container = $('.shiny-progress-container');
if ($container.length === 0) {
$container = $('<div class="shiny-progress-container"></div>');
$(document.body).append($container);
$('body').append($container);
}
// Add div for just this progress ID
@@ -1885,9 +1857,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
// Returns a URL which can be queried to get values from inside the server
// function. This is enabled with `options(shiny.testmode=TRUE)`.
this.getTestSnapshotBaseUrl = function () {
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref2$fullUrl = _ref2.fullUrl,
fullUrl = _ref2$fullUrl === undefined ? true : _ref2$fullUrl;
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref2$fullUrl = _ref2.fullUrl;
var fullUrl = _ref2$fullUrl === undefined ? true : _ref2$fullUrl;
var loc = window.location;
var url = "";
@@ -1956,21 +1929,22 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var fadeDuration = 250;
function show() {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref3$html = _ref3.html,
html = _ref3$html === undefined ? '' : _ref3$html,
_ref3$action = _ref3.action,
action = _ref3$action === undefined ? '' : _ref3$action,
_ref3$deps = _ref3.deps,
deps = _ref3$deps === undefined ? [] : _ref3$deps,
_ref3$duration = _ref3.duration,
duration = _ref3$duration === undefined ? 5000 : _ref3$duration,
_ref3$id = _ref3.id,
id = _ref3$id === undefined ? null : _ref3$id,
_ref3$closeButton = _ref3.closeButton,
closeButton = _ref3$closeButton === undefined ? true : _ref3$closeButton,
_ref3$type = _ref3.type,
type = _ref3$type === undefined ? null : _ref3$type;
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref3$html = _ref3.html;
var html = _ref3$html === undefined ? '' : _ref3$html;
var _ref3$action = _ref3.action;
var action = _ref3$action === undefined ? '' : _ref3$action;
var _ref3$deps = _ref3.deps;
var deps = _ref3$deps === undefined ? [] : _ref3$deps;
var _ref3$duration = _ref3.duration;
var duration = _ref3$duration === undefined ? 5000 : _ref3$duration;
var _ref3$id = _ref3.id;
var id = _ref3$id === undefined ? null : _ref3$id;
var _ref3$closeButton = _ref3.closeButton;
var closeButton = _ref3$closeButton === undefined ? true : _ref3$closeButton;
var _ref3$type = _ref3.type;
var type = _ref3$type === undefined ? null : _ref3$type;
if (!id) id = randomId();
@@ -2051,7 +2025,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if ($panel.length > 0) return $panel;
$(document.body).append('<div id="shiny-notification-panel">');
$('body').append('<div id="shiny-notification-panel">');
return $panel;
}
@@ -2114,11 +2088,13 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
// content is non-Bootstrap. Bootstrap modals require some special handling,
// which is coded in here.
show: function show() {
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref4$html = _ref4.html,
html = _ref4$html === undefined ? '' : _ref4$html,
_ref4$deps = _ref4.deps,
deps = _ref4$deps === undefined ? [] : _ref4$deps;
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref4$html = _ref4.html;
var html = _ref4$html === undefined ? '' : _ref4$html;
var _ref4$deps = _ref4.deps;
var deps = _ref4$deps === undefined ? [] : _ref4$deps;
// If there was an existing Bootstrap modal, then there will be a modal-
// backdrop div that was added outside of the modal wrapper, and it must be
@@ -2129,7 +2105,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var $modal = $('#shiny-modal-wrapper');
if ($modal.length === 0) {
$modal = $('<div id="shiny-modal-wrapper"></div>');
$(document.body).append($modal);
$('body').append($modal);
// If the wrapper's content is a Bootstrap modal, then when the inner
// modal is hidden, remove the entire thing, including wrapper.
@@ -2500,8 +2476,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
// Register the various event handlers
// ----------------------------------------------------------
if (opts.clickId) {
imageutils.disableDrag($el, $img);
var clickHandler = imageutils.createClickHandler(opts.clickId, opts.clickClip, opts.coordmap);
$el.on('mousedown2.image_output', clickHandler.mousedown);
@@ -2513,8 +2487,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
}
if (opts.dblclickId) {
imageutils.disableDrag($el, $img);
// We'll use the clickHandler's mousedown function, but register it to
// our custom 'dblclick2' event.
var dblclickHandler = imageutils.createClickHandler(opts.dblclickId, opts.clickClip, opts.coordmap);
@@ -2525,8 +2497,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
}
if (opts.hoverId) {
imageutils.disableDrag($el, $img);
var hoverHandler = imageutils.createHoverHandler(opts.hoverId, opts.hoverDelay, opts.hoverDelayType, opts.hoverClip, opts.hoverNullOutside, opts.coordmap);
$el.on('mousemove.image_output', hoverHandler.mousemove);
$el.on('mouseout.image_output', hoverHandler.mouseout);
@@ -2536,7 +2506,17 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
}
if (opts.brushId) {
imageutils.disableDrag($el, $img);
// Make image non-draggable (Chrome, Safari)
$img.css('-webkit-user-drag', 'none');
// Firefox, IE<=10
$img.on('dragstart.image_output', function () {
return false;
});
// Disable selection of image and text when dragging in IE<=10
$el.on('selectstart.image_output', function () {
return false;
});
var brushHandler = imageutils.createBrushHandler(opts.brushId, $el, opts, opts.coordmap, outputId);
$el.on('mousedown.image_output', brushHandler.mousedown);
@@ -2577,24 +2557,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var imageutils = {};
imageutils.disableDrag = function ($el, $img) {
// Make image non-draggable (Chrome, Safari)
$img.css('-webkit-user-drag', 'none');
// Firefox, IE<=10
// First remove existing handler so we don't keep adding handlers.
$img.off('dragstart.image_output');
$img.on('dragstart.image_output', function () {
return false;
});
// Disable selection of image and text when dragging in IE<=10
$el.off('selectstart.image_output');
$el.on('selectstart.image_output', function () {
return false;
});
};
// Modifies the panel objects in a coordmap, adding scaleImgToData(),
// scaleDataToImg(), and clipImg() functions to each one. The panel objects
// use img and data coordinates only; they do not use css coordinates. The
@@ -4339,12 +4301,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var textInputBinding = new InputBinding();
$.extend(textInputBinding, {
find: function find(scope) {
var $inputs = $(scope).find('input[type="text"], input[type="search"], input[type="url"], input[type="email"]');
// selectize.js 0.12.4 inserts a hidden text input with an
// id that ends in '-selectized'. The .not() selector below
// is to prevent textInputBinding from accidentally picking up
// this hidden element as a shiny input (#2396)
return $inputs.not('input[type="text"][id$="-selectized"]');
return $(scope).find('input[type="text"], input[type="search"], input[type="url"], input[type="email"]');
},
getId: function getId(el) {
return InputBinding.prototype.getId.call(this, el) || el.name;
@@ -4369,7 +4326,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
receiveMessage: function receiveMessage(el, data) {
if (data.hasOwnProperty('value')) this.setValue(el, data.value);
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(data.label);
if (data.hasOwnProperty('placeholder')) el.placeholder = data.placeholder;
@@ -4377,7 +4334,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
},
getState: function getState(el) {
return {
label: this._getLabelNode(el).text(),
label: $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(),
value: el.value,
placeholder: el.placeholder
};
@@ -4387,9 +4344,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
policy: 'debounce',
delay: 250
};
},
_getLabelNode: function _getLabelNode(el) {
return $(el).parent().find('label[for="' + $escape(el.id) + '"]');
}
});
inputBindings.register(textInputBinding, 'shiny.textInput');
@@ -4445,19 +4399,16 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if (data.hasOwnProperty('max')) el.max = data.max;
if (data.hasOwnProperty('step')) el.step = data.step;
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(data.label);
$(el).trigger('change');
},
getState: function getState(el) {
return { label: this._getLabelNode(el).text(),
return { label: $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(),
value: this.getValue(el),
min: Number(el.min),
max: Number(el.max),
step: Number(el.step) };
},
_getLabelNode: function _getLabelNode(el) {
return $(el).parent().find('label[for="' + $escape(el.id) + '"]');
}
});
inputBindings.register(numberInputBinding, 'shiny.numberInput');
@@ -4493,8 +4444,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
receiveMessage: function receiveMessage(el, data) {
if (data.hasOwnProperty('value')) el.checked = data.value;
// checkboxInput()'s label works different from other
// input labels...the label container should always exist
if (data.hasOwnProperty('label')) $(el).parent().find('span').text(data.label);
$(el).trigger('change');
@@ -4623,7 +4572,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
}
}
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $el.parent().find('label[for="' + $escape(el.id) + '"]').text(data.label);
var domElements = ['data-type', 'time-format', 'timezone'];
for (var i = 0; i < domElements.length; i++) {
@@ -4665,9 +4614,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
$el.ionRangeSlider(opts);
},
_getLabelNode: function _getLabelNode(el) {
return $(el).parent().find('label[for="' + $escape(el.id) + '"]');
},
// Number of values; 1 for single slider, 2 for range slider
_numValues: function _numValues(el) {
if ($(el).data('ionRangeSlider').options.type === 'double') return 2;else return 1;
@@ -4829,7 +4776,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if (startview === 2) startview = 'decade';else if (startview === 1) startview = 'year';else if (startview === 0) startview = 'month';
return {
label: this._getLabelNode(el).text(),
label: $el.find('label[for="' + $escape(el.id) + '"]').text(),
value: this.getValue(el),
valueString: $input.val(),
min: min,
@@ -4843,7 +4790,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
receiveMessage: function receiveMessage(el, data) {
var $input = $(el).find('input');
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $(el).find('label[for="' + $escape(el.id) + '"]').text(data.label);
if (data.hasOwnProperty('min')) this._setMin($input[0], data.min);
@@ -4898,9 +4845,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this._setMax($input[0], $input.data('max-date'));
}
},
_getLabelNode: function _getLabelNode(el) {
return $(el).find('label[for="' + $escape(el.id) + '"]');
},
// Given a format object from a date picker, return a string
_formatToString: function _formatToString(format) {
// Format object has structure like:
@@ -5047,7 +4991,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if (startview === 2) startview = 'decade';else if (startview === 1) startview = 'year';else if (startview === 0) startview = 'month';
return {
label: this._getLabelNode(el).text(),
label: $el.find('label[for="' + $escape(el.id) + '"]').text(),
value: this.getValue(el),
valueString: [$startinput.val(), $endinput.val()],
min: min,
@@ -5064,7 +5008,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
var $startinput = $inputs.eq(0);
var $endinput = $inputs.eq(1);
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $el.find('label[for="' + $escape(el.id) + '"]').text(data.label);
if (data.hasOwnProperty('min')) {
this._setMin($startinput[0], data.min);
@@ -5120,9 +5064,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
},
unsubscribe: function unsubscribe(el) {
$(el).off('.dateRangeInputBinding');
},
_getLabelNode: function _getLabelNode(el) {
return $(el).find('label[for="' + $escape(el.id) + '"]');
}
});
inputBindings.register(dateRangeInputBinding, 'shiny.dateRangeInput');
@@ -5154,14 +5095,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
return $(el).val();
},
setValue: function setValue(el, value) {
if (!this._is_selectize(el)) {
$(el).val(value);
} else {
var selectize = this._selectize(el);
if (selectize) {
selectize.setValue(value);
}
}
var selectize = this._selectize(el);
if (typeof selectize !== 'undefined') {
selectize.setValue(value);
} else $(el).val(value);
},
getState: function getState(el) {
// Store options in an array of objects, each with with value and label
@@ -5172,7 +5109,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
}
return {
label: this._getLabelNode(el),
label: $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(),
value: this.getValue(el),
options: options
};
@@ -5254,7 +5191,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.setValue(el, data.value);
}
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $(el).parent().parent().find('label[for="' + $escape(el.id) + '"]').text(data.label);
$(el).trigger('change');
},
@@ -5277,18 +5214,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
initialize: function initialize(el) {
this._selectize(el);
},
_getLabelNode: function _getLabelNode(el) {
var escaped_id = $escape(el.id);
if (this._is_selectize(el)) {
escaped_id += "-selectized";
}
return $(el).parent().parent().find('label[for="' + escaped_id + '"]');
},
// Return true if it's a selectize input, false if it's a regular select input.
_is_selectize: function _is_selectize(el) {
var config = $(el).parent().find('script[data-for="' + $escape(el.id) + '"]');
return config.length > 0;
},
_selectize: function _selectize(el, update) {
if (!$.fn.selectize) return undefined;
var $el = $(el);
@@ -5361,7 +5286,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
}
return {
label: this._getLabelNode(el).text(),
label: $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(),
value: this.getValue(el),
options: options
};
@@ -5380,7 +5305,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if (data.hasOwnProperty('value')) this.setValue(el, data.value);
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $(el).parent().find('label[for="' + $escape(el.id) + '"]').text(data.label);
$(el).trigger('change');
},
@@ -5392,10 +5317,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
unsubscribe: function unsubscribe(el) {
$(el).off('.radioInputBinding');
},
// Get the DOM element that contains the top-level label
_getLabelNode: function _getLabelNode(el) {
return $(el).parent().find('label[for="' + $escape(el.id) + '"]');
},
// Given an input DOM object, get the associated label. Handles labels
// that wrap the input as well as labels associated with 'for' attribute.
_getLabel: function _getLabel(obj) {
@@ -5461,7 +5382,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
label: this._getLabel($objs[i]) };
}
return { label: this._getLabelNode(el).text(),
return { label: $(el).find('label[for="' + $escape(el.id) + '"]').text(),
value: this.getValue(el),
options: options
};
@@ -5480,7 +5401,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
if (data.hasOwnProperty('value')) this.setValue(el, data.value);
updateLabel(data.label, this._getLabelNode(el));
if (data.hasOwnProperty('label')) $el.find('label[for="' + $escape(el.id) + '"]').text(data.label);
$(el).trigger('change');
},
@@ -5492,10 +5413,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
unsubscribe: function unsubscribe(el) {
$(el).off('.checkboxGroupInputBinding');
},
// Get the DOM element that contains the top-level label
_getLabelNode: function _getLabelNode(el) {
return $(el).find('label[for="' + $escape(el.id) + '"]');
},
// Given an input DOM object, get the associated label. Handles labels
// that wrap the input as well as labels associated with 'for' attribute.
_getLabel: function _getLabel(obj) {
@@ -5661,7 +5578,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
this.iframe.id = iframeId;
this.iframe.name = iframeId;
this.iframe.setAttribute('style', 'position: fixed; top: 0; left: 0; width: 0; height: 0; border: none');
$(document.body).append(this.iframe);
$('body').append(this.iframe);
var iframeDestroy = function iframeDestroy() {
// Forces Shiny to flushReact, flush outputs, etc. Without this we get
// invalidated reactives, but observers don't actually execute.
@@ -5991,10 +5908,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
_enableDocumentEvents: function _enableDocumentEvents() {
var _this2 = this;
var $doc = $("html"),
_ZoneClass = this._ZoneClass,
ACTIVE = _ZoneClass.ACTIVE,
OVER = _ZoneClass.OVER;
var $doc = $("html");
var _ZoneClass = this._ZoneClass;
var ACTIVE = _ZoneClass.ACTIVE;
var OVER = _ZoneClass.OVER;
this._enableDraghover($doc).on({
"draghover:enter.draghover": function draghoverEnterDraghover(e) {
@@ -6066,25 +5983,27 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
// support the FileList object though, so the user's expectation that DnD is
// supported based on this highlighting would be incorrect.
if (!this._isIE9()) {
if ($fileInputs.length === 0) this._enableDocumentEvents();
$fileInputs = $fileInputs.add(el);
var $zone = this._zoneOf(el),
OVER = this._ZoneClass.OVER;
(function () {
if ($fileInputs.length === 0) _this3._enableDocumentEvents();
$fileInputs = $fileInputs.add(el);
var $zone = _this3._zoneOf(el);
var OVER = _this3._ZoneClass.OVER;
this._enableDraghover($zone).on({
"draghover:enter.draghover": function draghoverEnterDraghover(e) {
$zone.addClass(OVER);
},
"draghover:leave.draghover": function draghoverLeaveDraghover(e) {
$zone.removeClass(OVER);
// Prevent this event from bubbling to the document handler,
// which would deactivate all zones.
e.stopPropagation();
},
"draghover:drop.draghover": function draghoverDropDraghover(e, dropEvent) {
_this3._handleDrop(dropEvent, el);
}
});
_this3._enableDraghover($zone).on({
"draghover:enter.draghover": function draghoverEnterDraghover(e) {
$zone.addClass(OVER);
},
"draghover:leave.draghover": function draghoverLeaveDraghover(e) {
$zone.removeClass(OVER);
// Prevent this event from bubbling to the document handler,
// which would deactivate all zones.
e.stopPropagation();
},
"draghover:drop.draghover": function draghoverDropDraghover(e, dropEvent) {
_this3._handleDrop(dropEvent, el);
}
});
})();
}
},
@@ -6523,14 +6442,14 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
// Need to register callbacks for each Bootstrap 3 class.
var bs3classes = ['modal', 'dropdown', 'tab', 'tooltip', 'popover', 'collapse'];
$.each(bs3classes, function (idx, classname) {
$(document.body).on('shown.bs.' + classname + '.sendImageSize', '*', filterEventsByNamespace('bs', sendImageSize));
$(document.body).on('shown.bs.' + classname + '.sendOutputHiddenState ' + 'hidden.bs.' + classname + '.sendOutputHiddenState', '*', filterEventsByNamespace('bs', sendOutputHiddenState));
$('body').on('shown.bs.' + classname + '.sendImageSize', '*', filterEventsByNamespace('bs', sendImageSize));
$('body').on('shown.bs.' + classname + '.sendOutputHiddenState ' + 'hidden.bs.' + classname + '.sendOutputHiddenState', '*', filterEventsByNamespace('bs', sendOutputHiddenState));
});
// This is needed for Bootstrap 2 compatibility and for non-Bootstrap
// related shown/hidden events (like conditionalPanel)
$(document.body).on('shown.sendImageSize', '*', sendImageSize);
$(document.body).on('shown.sendOutputHiddenState hidden.sendOutputHiddenState', '*', sendOutputHiddenState);
$('body').on('shown.sendImageSize', '*', sendImageSize);
$('body').on('shown.sendOutputHiddenState hidden.sendOutputHiddenState', '*', sendOutputHiddenState);
// Send initial pixel ratio, and update it if it changes
initialValues['.clientdata_pixelratio'] = pixelRatio();
@@ -6628,25 +6547,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
e.preventDefault();
});
$(document).on('keydown', function (e) {
if (e.which !== 115 || !e.ctrlKey && !e.metaKey || e.shiftKey || e.altKey) return;
var url = 'reactlog/mark?w=' + window.escape(exports.shinyapp.config.workerId) + "&s=" + window.escape(exports.shinyapp.config.sessionId);
// send notification
$.get(url, function (result) {
if (result !== "marked") return;
var html = '<span id="shiny-reactlog-mark-text">Marked time point in reactlog</span>';
exports.notifications.show({
html: html,
closeButton: true
});
});
e.preventDefault();
});
//---------------------------------------------------------------------
// Source file: ../srcjs/_end.js
})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -22,7 +22,7 @@ interpreted as multiple namespaces, in increasing order of specificity
}
\value{
If \code{id} is missing, returns a function that expects an id string
as its only argument and returns that id with the namespace prepended.
as its only argument and returns that id with the namespace prepended.
}
\description{
The \code{NS} function creates namespaced IDs out of bare IDs, by joining

View File

@@ -9,7 +9,7 @@
\code{shinyServer} to the server function.}
\item{min}{The value that represents the starting point of the
progress bar. Must be less than \code{max}.}
progress bar. Must be less tham \code{max}.}
\item{max}{The value that represents the end of the progress bar.
Must be greater than \code{min}.}
@@ -43,7 +43,7 @@ Reports progress to the user during long-running operations.
}
\details{
This package exposes two distinct programming APIs for working with
progress. \code{\link[=withProgress]{withProgress()}} and \code{\link[=setProgress]{setProgress()}}
progress. \code{\link{withProgress}} and \code{\link{setProgress}}
together provide a simple function-based interface, while the
\code{Progress} reference class provides an object-oriented API.
@@ -57,28 +57,28 @@ If you want to use the old styling (for example, you may have used customized
CSS), you can use \code{style="old"} each time you call
\code{Progress$new()}. If you don't want to set the style each time
\code{Progress$new} is called, you can instead call
\code{\link[=shinyOptions]{shinyOptions(progress.style="old")}} just once, inside the server
\code{\link{shinyOptions}(progress.style="old")} just once, inside the server
function.
\strong{Methods}
\describe{
\item{\code{initialize(session, min = 0, max = 1)}}{
Creates a new progress panel (but does not display it).
}
\item{\code{set(value = NULL, message = NULL, detail = NULL)}}{
Updates the progress panel. When called the first time, the
progress panel is displayed.
}
\item{\code{inc(amount = 0.1, message = NULL, detail = NULL)}}{
Like \code{set}, this updates the progress panel. The difference is
that \code{inc} increases the progress bar by \code{amount}, instead
of setting it to a specific value.
}
\item{\code{close()}}{
Removes the progress panel. Future calls to \code{set} and
\code{close} will be ignored.
}
}
\describe{
\item{\code{initialize(session, min = 0, max = 1)}}{
Creates a new progress panel (but does not display it).
}
\item{\code{set(value = NULL, message = NULL, detail = NULL)}}{
Updates the progress panel. When called the first time, the
progress panel is displayed.
}
\item{\code{inc(amount = 0.1, message = NULL, detail = NULL)}}{
Like \code{set}, this updates the progress panel. The difference is
that \code{inc} increases the progress bar by \code{amount}, instead
of setting it to a specific value.
}
\item{\code{close()}}{
Removes the progress panel. Future calls to \code{set} and
\code{close} will be ignored.
}
}
}
\examples{
## Only run examples in interactive R sessions
@@ -108,6 +108,6 @@ shinyApp(ui, server)
}
}
\seealso{
\code{\link[=withProgress]{withProgress()}}
\code{\link{withProgress}}
}
\keyword{datasets}

View File

@@ -77,5 +77,6 @@ such as \code{"100px"} (100 pixels) or \code{"25\%"}.
For arcane HTML reasons, to have the panel fill the page or parent you should
specify \code{0} for \code{top}, \code{left}, \code{right}, and \code{bottom}
rather than the more obvious \code{width = "100\%"} and \code{height = "100\%"}.
rather than the more obvious \code{width = "100\%"} and \code{height =
"100\%"}.
}

Some files were not shown because too many files have changed in this diff Show More