this function produces an interactive view of the specified spatial object(s) on top of the specified base maps.
Usage
# S4 method for class 'RasterLayer'
mapView(
x,
map = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = mapviewGetOption("use.layer.names"),
map.types = mapviewGetOption("basemaps"),
alpha.regions = 0.8,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = mapviewGetOption("trim"),
verbose = mapviewGetOption("verbose"),
layer.name = NULL,
homebutton = mapviewGetOption("homebutton"),
native.crs = mapviewGetOption("native.crs"),
method = mapviewGetOption("method"),
label = TRUE,
query.type = mapviewGetOption("query.type"),
query.digits = mapviewGetOption("query.digits"),
query.position = mapviewGetOption("query.position"),
query.prefix = mapviewGetOption("query.prefix"),
viewer.suppress = mapviewGetOption("viewer.suppress"),
hide = FALSE,
...
)
# S4 method for class 'stars'
mapView(
x,
band = 1,
map = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = mapviewGetOption("use.layer.names"),
map.types = mapviewGetOption("basemaps"),
alpha.regions = 0.8,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = mapviewGetOption("trim"),
verbose = mapviewGetOption("verbose"),
layer.name = NULL,
homebutton = mapviewGetOption("homebutton"),
native.crs = mapviewGetOption("native.crs"),
method = mapviewGetOption("method"),
label = TRUE,
query.type = mapviewGetOption("query.type"),
query.digits = mapviewGetOption("query.digits"),
query.position = mapviewGetOption("query.position"),
query.prefix = mapviewGetOption("query.prefix"),
viewer.suppress = mapviewGetOption("viewer.suppress"),
pane = "auto",
hide = FALSE,
...
)
# S4 method for class 'stars_proxy'
mapView(
x,
band = 1,
map = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = mapviewGetOption("use.layer.names"),
map.types = mapviewGetOption("basemaps"),
alpha.regions = 0.8,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = mapviewGetOption("trim"),
verbose = mapviewGetOption("verbose"),
layer.name = NULL,
homebutton = mapviewGetOption("homebutton"),
native.crs = mapviewGetOption("native.crs"),
method = mapviewGetOption("method"),
label = TRUE,
query.type = mapviewGetOption("query.type"),
query.digits = mapviewGetOption("query.digits"),
query.position = mapviewGetOption("query.position"),
query.prefix = mapviewGetOption("query.prefix"),
viewer.suppress = mapviewGetOption("viewer.suppress"),
pane = "auto",
hide = FALSE,
...
)
# S4 method for class 'SpatRaster'
mapView(
x,
band = 1,
map = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = mapviewGetOption("use.layer.names"),
map.types = mapviewGetOption("basemaps"),
alpha.regions = 0.8,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = mapviewGetOption("trim"),
verbose = mapviewGetOption("verbose"),
layer.name = NULL,
homebutton = mapviewGetOption("homebutton"),
native.crs = mapviewGetOption("native.crs"),
method = mapviewGetOption("method"),
label = TRUE,
query.type = mapviewGetOption("query.type"),
query.digits = mapviewGetOption("query.digits"),
query.position = mapviewGetOption("query.position"),
query.prefix = mapviewGetOption("query.prefix"),
viewer.suppress = mapviewGetOption("viewer.suppress"),
pane = "auto",
hide = FALSE,
...
)
# S4 method for class 'RasterStackBrick'
mapView(
x,
map = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = TRUE,
map.types = mapviewGetOption("basemaps"),
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = TRUE,
verbose = mapviewGetOption("verbose"),
homebutton = mapviewGetOption("homebutton"),
method = mapviewGetOption("method"),
label = TRUE,
query.type = c("mousemove", "click"),
query.digits = mapviewGetOption("query.digits"),
query.position = mapviewGetOption("query.position"),
query.prefix = "Layer",
viewer.suppress = mapviewGetOption("viewer.suppress"),
hide = FALSE,
...
)
# S4 method for class 'Satellite'
mapView(
x,
map = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
map.types = mapviewGetOption("basemaps"),
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = TRUE,
verbose = mapviewGetOption("verbose"),
homebutton = mapviewGetOption("homebutton"),
method = c("bilinear", "ngb"),
label = TRUE,
hide = FALSE,
...
)
# S4 method for class 'sf'
mapView(
x,
map = NULL,
pane = "auto",
canvas = useCanvas(x),
viewer.suppress = mapviewGetOption("viewer.suppress"),
zcol = NULL,
burst = FALSE,
color = mapviewGetOption("vector.palette"),
col.regions = mapviewGetOption("vector.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
cex = 6,
lwd = lineWidth(x),
alpha = 0.9,
alpha.regions = regionOpacity(x),
na.alpha = regionOpacity(x),
map.types = mapviewGetOption("basemaps"),
verbose = mapviewGetOption("verbose"),
popup = TRUE,
layer.name = NULL,
label = zcol,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
highlight = mapviewHighlightOptions(x, alpha.regions, alpha, lwd),
maxpoints = getMaxFeatures(x),
hide = FALSE,
...
)
# S4 method for class 'SpatVector'
mapView(
x,
map = NULL,
pane = "auto",
canvas = useCanvas(x),
viewer.suppress = mapviewGetOption("viewer.suppress"),
zcol = NULL,
burst = FALSE,
color = mapviewGetOption("vector.palette"),
col.regions = mapviewGetOption("vector.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
cex = 6,
lwd = lineWidth(x),
alpha = 0.9,
alpha.regions = regionOpacity(x),
na.alpha = regionOpacity(x),
map.types = mapviewGetOption("basemaps"),
verbose = mapviewGetOption("verbose"),
popup = TRUE,
layer.name = NULL,
label = zcol,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
highlight = mapviewHighlightOptions(x, alpha.regions, alpha, lwd),
maxpoints = getMaxFeatures(x),
hide = FALSE,
...
)
# S4 method for class 'sfc'
mapView(
x,
map = NULL,
pane = "auto",
canvas = useCanvas(x),
viewer.suppress = mapviewGetOption("viewer.suppress"),
color = standardColor(x),
col.regions = standardColRegions(x),
at = NULL,
na.color = mapviewGetOption("na.color"),
cex = 6,
lwd = lineWidth(x),
alpha = 0.9,
alpha.regions = regionOpacity(x),
map.types = mapviewGetOption("basemaps"),
verbose = mapviewGetOption("verbose"),
popup = NULL,
layer.name = deparse(substitute(x, env = parent.frame())),
label = makeLabels(x),
legend = mapviewGetOption("legend"),
legend.opacity = 1,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
highlight = mapviewHighlightOptions(x, alpha.regions, alpha, lwd),
maxpoints = getMaxFeatures(x),
hide = FALSE,
...
)
# S4 method for class 'character'
mapView(
x,
map = NULL,
tms = TRUE,
color = standardColor(),
col.regions = standardColRegions(),
at = NULL,
na.color = mapviewGetOption("na.color"),
cex = 6,
lwd = 2,
alpha = 0.9,
alpha.regions = 0.6,
na.alpha = 0.6,
map.types = mapviewGetOption("basemaps"),
verbose = FALSE,
layer.name = x,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
canvas = FALSE,
viewer.suppress = mapviewGetOption("viewer.suppress"),
...
)
# S4 method for class 'numeric'
mapView(x, y, type = "p", grid = TRUE, label, ...)
# S4 method for class 'data.frame'
mapView(
x,
xcol,
ycol,
grid = TRUE,
aspect = 1,
popup = leafpop::popupTable(x, className = "mapview-popup"),
label,
crs = NA,
...
)
# S4 method for class 'XY'
mapView(
x,
map = NULL,
pane = "auto",
canvas = useCanvas(x),
viewer.suppress = mapviewGetOption("viewer.suppress"),
color = standardColor(x),
col.regions = standardColRegions(x),
at = NULL,
na.color = mapviewGetOption("na.color"),
cex = 6,
lwd = lineWidth(x),
alpha = 0.9,
alpha.regions = regionOpacity(x),
map.types = mapviewGetOption("basemaps"),
verbose = mapviewGetOption("verbose"),
popup = NULL,
layer.name = deparse(substitute(x, env = parent.frame(1))),
label = makeLabels(x),
legend = mapviewGetOption("legend"),
legend.opacity = 1,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
highlight = mapviewHighlightOptions(x, alpha.regions, alpha, lwd),
maxpoints = getMaxFeatures(x),
hide = FALSE,
...
)
# S4 method for class 'XYZ'
mapView(x, layer.name = deparse(substitute(x, env = parent.frame(1))), ...)
# S4 method for class 'XYM'
mapView(x, layer.name = deparse(substitute(x, env = parent.frame(1))), ...)
# S4 method for class 'XYZM'
mapView(x, layer.name = deparse(substitute(x, env = parent.frame(1))), ...)
# S4 method for class 'bbox'
mapView(
x,
layer.name = deparse(substitute(x, env = parent.frame(1))),
alpha.regions = 0.2,
...
)
# S4 method for class 'missing'
mapView(map.types = mapviewGetOption("basemaps"), ...)
# S4 method for class 'NULL'
mapView(x, ...)
# S4 method for class 'list'
mapView(
x,
map = NULL,
zcol = NULL,
burst = FALSE,
color = mapviewGetOption("vector.palette"),
col.regions = mapviewGetOption("vector.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
cex = 6,
lwd = lapply(x, lineWidth),
alpha = 0.9,
alpha.regions = lapply(x, regionOpacity),
na.alpha = lapply(x, regionOpacity),
map.types = mapviewGetOption("basemaps"),
verbose = mapviewGetOption("verbose"),
popup = TRUE,
layer.name = deparse(substitute(x, env = parent.frame()), width.cutoff = 500L),
label = lapply(x, makeLabels),
legend = mapviewGetOption("legend"),
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
hide = FALSE,
...
)
# S4 method for class 'ANY'
mapview(...)
# S4 method for class 'SpatialPixelsDataFrame'
mapView(
x,
map = NULL,
zcol = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = FALSE,
map.types = mapviewGetOption("basemaps"),
alpha.regions = 0.8,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = TRUE,
verbose = mapviewGetOption("verbose"),
layer.name = NULL,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
method = mapviewGetOption("method"),
label = TRUE,
query.type = c("mousemove", "click"),
query.digits,
query.position = "topright",
query.prefix = "Layer",
viewer.suppress = mapviewGetOption("viewer.suppress"),
hide = FALSE,
...
)
# S4 method for class 'SpatialGridDataFrame'
mapView(
x,
map = NULL,
zcol = NULL,
maxpixels = mapviewGetOption("mapview.maxpixels"),
col.regions = mapviewGetOption("raster.palette"),
at = NULL,
na.color = mapviewGetOption("na.color"),
use.layer.names = FALSE,
map.types = mapviewGetOption("basemaps"),
alpha.regions = 0.8,
legend = mapviewGetOption("legend"),
legend.opacity = 1,
trim = TRUE,
verbose = mapviewGetOption("verbose"),
layer.name = NULL,
homebutton = mapviewGetOption("homebutton"),
native.crs = FALSE,
method = mapviewGetOption("method"),
label = TRUE,
query.type = c("mousemove", "click"),
query.digits,
query.position = "topright",
query.prefix = "Layer",
viewer.suppress = mapviewGetOption("viewer.suppress"),
hide = FALSE,
...
)
# S4 method for class 'SpatialPointsDataFrame'
mapView(x, zcol = NULL, layer.name = NULL, ...)
# S4 method for class 'SpatialPoints'
mapView(x, zcol = NULL, layer.name = NULL, ...)
# S4 method for class 'SpatialPolygonsDataFrame'
mapView(x, zcol = NULL, layer.name = NULL, ...)
# S4 method for class 'SpatialPolygons'
mapView(x, zcol = NULL, layer.name = NULL, ...)
# S4 method for class 'SpatialLinesDataFrame'
mapView(x, zcol = NULL, layer.name = NULL, ...)
# S4 method for class 'SpatialLines'
mapView(x, zcol = NULL, layer.name = NULL, ...)Arguments
- x
a
Raster*orSpatial*orSatelliteorsforstarsobject or a list of any combination of those. Furthermore, this can also be adata.frame, anumeric vectoror acharacter stringpointing to a tile image folder or file on disk. If missing, a blank map will be drawn. A value of NULL will return NULL.- map
an optional existing map to be updated/added to.
- maxpixels
integer > 0. Maximum number of cells to use for the plot. If maxpixels <
ncell(x), sampleRegular is used before plotting.- col.regions
color (palette) pixels. See
levelplotfor details.- at
the breakpoints used for the visualisation. See
levelplotfor details.- na.color
color for missing values
- use.layer.names
should layer names of the Raster* object be used?
- map.types
character specifications for the base maps. see https://leaflet-extras.github.io/leaflet-providers/preview/ for available options.
- alpha.regions
opacity of the fills of points, polygons or raster layer(s)
- legend
should a legend be plotted
- legend.opacity
opacity of the legend
- trim
should the raster be trimmed in case there are NAs on the edges
- verbose
should some details be printed during the process
- layer.name
the name of the layer to be shown on the map. By default this is the character version of whatever is passed to
x. NOTE: This is being passed to underlying leaflet functions as the group argument. So if you use mapview to set up a map and want to refer to a certain layer later on, this is what you should refer to ingroup.logical, whether to add a zoom-to-layer button to the map. Defaults to TRUE
- native.crs
logical whether to reproject to web map coordinate reference system (web mercator - epsg:3857) or render using native CRS of the supplied data (can also be NA). Default is FALSE which will render in web mercator. If set to TRUE now background maps will be drawn (but rendering may be much quicker as no reprojecting is necessary). Currently only works for simple features.
- method
for raster data only (raster/stars). Method used to compute values for the resampled layer that is passed on to leaflet. mapview does projection on-the-fly to ensure correct display and therefore needs to know how to do this projection. The default is 'bilinear' (bilinear interpolation), which is appropriate for continuous variables. The other option, 'ngb' (nearest neighbor), is useful for categorical variables. Ignored if the raster layer is of class
factorin which case "ngb" is used.- label
For vector data (sf/sp) a character vector of labels to be shown on mouseover. See
addControlfor details. For raster data (Raster*/stars) a logical indicating whether to add image query.- query.type
for raster methods only. Whether to show raster value query on
'mousemove'or'click'. Ignored iflabel = FALSE.- query.digits
for raster methods only. The amount of digits to be shown by raster value query. Ignored if
label = FALSE.- query.position
for raster methods only. The position of the raster value query info box. See
positionargument ofaddLegendfor possible values. Ignored iflabel = FALSE.- query.prefix
for raster methods only. a character string to be shown as prefix for the layerId. Ignored if
label = FALSE.- viewer.suppress
deprecated. Use
mapviewOptions(viewer.suppress = TRUE/FALSE)instead.- hide
either a logical, a vector of layer names or a vector of layer indices. See Details for more information on what exactly it does for different raster types.
- ...
additional arguments passed on to respective functions. See
addRasterImage,addCircles,addPolygons,addPolylinesfor details. Furthermore, you can pass hidden arguments to some methods. See Details for a list of supported hidden arguments.- band
for stars layers, the band number to be plotted.
- pane
name of the map pane in which to render features. See
addMapPanefor details. Currently only supported for vector layers. Ignored ifcanvas = TRUE. The default"auto"will create different panes for points, lines and polygons such that points overlay lines overlay polygons. Set toNULLto get default leaflet behaviour where allfeatures are rendered in the same pane and layer order is determined automatically/sequentially.- canvas
whether to use canvas rendering rather than svg. May help performance with larger data. See https://leafletjs.com/index.html#canvas for more information. Only applicable for vector data. The default setting will decide automatically, based on feature complexity.
- zcol
attribute name(s) or column number(s) in attribute table of the column(s) to be rendered. See also Details.
- burst
whether to show all (TRUE) or only one (FALSE) layer(s). See also Details.
- color
color (palette) for points/polygons/lines
- cex
attribute name(s) or column number(s) in attribute table of the column(s) to be used for defining the size of circles
- lwd
line width
- alpha
opacity of lines
- na.alpha
opacity of missing values
- popup
either
logical,character vectoror alistof HTML strings with the popup contents, usually created frompopupTable. SeeaddControlfor details. IfFALSEorNULLno popups will be created, ifTRUEa table with all feature attributes/columns will be created. If acharacter vectorof column names, the table will only show the respective column entries.- highlight
either
FALSE,NULLor a list of styling options for feature highlighting on mouse hover. SeehighlightOptionsfor details.- maxpoints
the maximum number of points making up the geometry. In case of lines and polygons this refers to the number of vertices. See Details for more information.
- tms
whether the tiles are served as TMS tiles.
- y
numeric vector.
- type
whether to render the numeric vector
xas a point"p"or line"l"plot.- grid
whether to plot a (scatter plot) xy-grid to aid interpretation of the visualisation. Only relevant for the data.frame method.
- xcol
the column to be mapped to the x-axis. Only relevant for the data.frame method.
- ycol
the column to be mapped to the y-axis. Only relevant for the data.frame method.
- aspect
the ratio of x/y axis coordinates to adjust the plotting space to fit the screen. Only relevant for the data.frame method.
- crs
an optional crs specification for the provided data to enable rendering on a basemap. See argument description in
st_sffor details.
Details
If zcol is not NULL but a length one character vector
(referring to a column name of the attribute table)
and burst is TRUE, one layer for each unique value
of zcol will be drawn. The same will happen if burst is
a length one character vector (again referring to a column of
the attribute table).
NOTE: if XYZ or XYM or XYZM data from package sf is passed to mapview,
dimensions Z and M will be stripped to ensure smooth rendering even though
the popup will potentially still say something like "POLYGON Z".
maxpoints is taken to determine when to switch rendering from svg
to canvas overlay for performance. The threshold calculation is done as follows:
if the number of points (in case of point data) or vertices (in case of
polygon or line data) > maxpoints then render using special render
function. Within this render function we approximate the complexity of
features by maxFeatures <- maxfeatures / (npts(data) / length(data))
where npts determines the number of points/vertices and length
the number of features (points, lines or polygons). When the number of
features in the current view window is larger than maxFeatures then
features are rendered on the canvas, otherwise they are rendered as svg objects
and fully queriable.hide if TRUE, will hide the layer in case of a single RasterLayer
and all but the first layer in case of a multilayer RasterStackBrick.
If a vector of layer names or indices is supplied, these will be hidden
(only applicable for multi-layer RasterStackBricks).
Methods (by class)
mapView(stars):starsmapView(stars_proxy):stars_proxymapView(SpatRaster):SpatRastermapView(Satellite):satellitemapView(sf):sfmapView(SpatVector):SpatVectormapView(sfc):st_sfcmapView(character):charactermapView(numeric):numericmapView(data.frame):data.framemapView(XY):st_sfcmapView(XYZ):st_sfcmapView(XYM):st_sfcmapView(XYZM):st_sfcmapView(bbox):st_bboxmapView(missing): initiate a map without an objectmapView(`NULL`): initiate a map without an objectmapView(list):listmapview(ANY): alias for ease of typingmapView(SpatialPixelsDataFrame):SpatialPixelsDataFramemapView(SpatialGridDataFrame):SpatialGridDataFramemapView(SpatialPointsDataFrame):SpatialPointsDataFramemapView(SpatialPoints):SpatialPointsmapView(SpatialPolygonsDataFrame):SpatialPolygonsDataFramemapView(SpatialPolygons):SpatialPolygonsmapView(SpatialLinesDataFrame):SpatialLinesDataFramemapView(SpatialLines):SpatialLines
Examples
if (FALSE) { # \dontrun{
mapview()
## simple features ====================================================
library(sf)
# sf
mapview(breweries)
mapview(franconia)
# sfc
mapview(st_geometry(breweries)) # no popup
# sfg / XY - taken from ?sf::st_point
outer = matrix(c(0,0,10,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
hole1 = matrix(c(1,1,1,2,2,2,2,1,1,1),ncol=2, byrow=TRUE)
hole2 = matrix(c(5,5,5,6,6,6,6,5,5,5),ncol=2, byrow=TRUE)
pts = list(outer, hole1, hole2)
(pl1 = st_polygon(pts))
mapview(pl1)
## raster ==============================================================
if (interactive()) {
library(plainview)
mapview(plainview::poppendorf[[5]])
}
## spatial objects =====================================================
mapview(leaflet::gadmCHE)
mapview(leaflet::atlStorms2005)
## styling options & legends ===========================================
mapview(franconia, color = "white", col.regions = "red")
mapview(franconia, color = "magenta", col.regions = "white")
mapview(breweries, zcol = "founded")
mapview(breweries, zcol = "founded", at = seq(1400, 2200, 200), legend = TRUE)
mapview(franconia, zcol = "district", legend = TRUE)
clrs <- sf.colors
mapview(franconia, zcol = "district", col.regions = clrs, legend = TRUE)
### multiple layers ====================================================
mapview(franconia) + breweries
mapview(list(breweries, franconia))
mapview(franconia) + mapview(breweries) + trails
mapview(franconia, zcol = "district") + mapview(breweries, zcol = "village")
mapview(list(franconia, breweries),
zcol = list("district", NULL),
legend = list(TRUE, FALSE))
### burst ==============================================================
mapview(franconia, burst = TRUE)
mapview(franconia, burst = TRUE, hide = TRUE)
mapview(franconia, zcol = "district", burst = TRUE)
### ceci constitue la fin du pipe ======================================
library(poorman)
library(sf)
franconia %>%
sf::st_union() %>%
mapview()
franconia %>%
group_by(district) %>%
summarize() %>%
mapview(zcol = "district")
franconia %>%
group_by(district) %>%
summarize() %>%
mutate(area = st_area(.) / 1e6) %>%
mapview(zcol = "area")
franconia %>%
mutate(area = sf::st_area(.)) %>%
mapview(zcol = "area", legend = TRUE)
breweries %>%
st_intersection(franconia) %>%
mapview(zcol = "district")
franconia %>%
mutate(count = lengths(st_contains(., breweries))) %>%
mapview(zcol = "count")
franconia %>%
mutate(count = lengths(st_contains(., breweries)),
density = count / st_area(.)) %>%
mapview(zcol = "density")
} # }