diff --git a/CHANGELOG-2021.md b/CHANGELOG-2021.md index eee5066d1c..581acbc615 100644 --- a/CHANGELOG-2021.md +++ b/CHANGELOG-2021.md @@ -24,9 +24,9 @@ Update D3 to 7.2.1. [Released December 4, 2021.](https://github.com/observablehq/plot/releases/tag/v0.3.0) -Plot can now produce [legends for *color* and *opacity* scales](./README.md#legends)! +Plot can now produce [legends for *color* and *opacity* scales](https://observablehq.com/plot/features/legends)! -[a scatterplot with a color legend](https://observablehq.com/@observablehq/plot-legends) +[a scatterplot with a color legend](https://observablehq.com/plot/features/legends) ```js Plot.plot({ @@ -41,9 +41,9 @@ Plot.plot({ The top-level plot *scale*.**legend** option generates an inline legend for the given *scale* (*color* or *opacity*). Alternatively, the new *plot*.legend(*name*) function returns a legend for the scale with the given *name*. The new standalone Plot.**legend**(*options*) function also allows you to create a legend independently of a chart. Two forms of color legend are provided: *swatches* for ordinal or discrete scales (*e.g.*, threshold color scales), and *ramp* for continuous scales. -The new [Plot.image](./README.md#image) mark centers an image on the given *xy* position. +The new [Plot.image](https://observablehq.com/plot/marks/image) mark centers an image on the given *xy* position. -[a scatterplot of U.S. presidents](https://observablehq.com/@observablehq/plot-image) +[a scatterplot of U.S. presidents](https://observablehq.com/plot/marks/image) ```js Plot.plot({ @@ -223,7 +223,7 @@ The *x1* and *x2* outputs now default to undefined if *x* is explicitly defined; ### Marks -The [*marks* option](./README.md#mark-options) now accepts render functions, null, and undefined as shorthand mark definitions. Nullish marks produce no output and are useful for conditional display (equivalent to the empty array). Render functions are invoked when plotting and may return an SVG element to insert into the plot, such as a legend or annotation. +The [*marks* option](https://observablehq.com/plot/features/plots#marks-option) now accepts render functions, null, and undefined as shorthand mark definitions. Nullish marks produce no output and are useful for conditional display (equivalent to the empty array). Render functions are invoked when plotting and may return an SVG element to insert into the plot, such as a legend or annotation. a line chart of Apple, Inc.’s daily closing stock price from 2013 to 2018, with a red ‘hello world’ label @@ -234,7 +234,7 @@ Plot.marks( ).plot() ``` -The [Plot.marks(...*marks*)](./README.md#plotmarksmarks) function provides [*mark*.plot](./README.md#plotplotoptions) shorthand for array marks. This is useful for composite marks, such as [boxes](https://github.com/observablehq/plot/blob/8fef4fa52a4cca4135f5f964e3c328ef8f18f672/test/plots/morley-boxplot.js#L18-L23). +The [Plot.marks(...*marks*)](https://observablehq.com/plot/features/marks#marks) function provides [*mark*.plot](https://observablehq.com/plot/features/plots#mark_plot) shorthand for array marks. This is useful for composite marks, such as [boxes](https://github.com/observablehq/plot/blob/8fef4fa52a4cca4135f5f964e3c328ef8f18f672/test/plots/morley-boxplot.js#L18-L23). All marks now support the [shapeRendering](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering) option. (This is a constant; it may not vary across marks.) All marks now allow strokeWidth to be specified as a channel. (The strokeWidth channel is unscaled; values are specified in literal pixels.) Text marks now also allow stroke and strokeOpacity to be specified as channels. If its fill is not *none*, a line’s default stroke is now *none* rather than *currentColor*, making it consistent with dot and other marks. When a fill or fillOpacity channel is used with a link, or when a stroke or strokeOpacity channel is used with a rule, undefined values will now be filtered. The text mark now uses attributes instead of styles for font rendering properties, improving compatibility with Firefox. @@ -256,7 +256,7 @@ The link mark now supports *x* or *y* shorthand for one-dimensional links, equiv ### Scales -The new [*sort* options](./README.md#sort-options) allow convenient control over the order of ordinal domains, including the *fx* and *fy* facet domains. The aggregation method can be controlled via the *reduce* option, which defaults to *max*. The *reverse* and *limit* options are also supported. For example, a bar chart can be sorted by descending value like so: +The new [*sort* mark option](https://observablehq.com/plot/features/scales#sort-mark-option) allows convenient control over the order of ordinal domains, including the *fx* and *fy* facet domains. The aggregation method can be controlled via the *reduce* option, which defaults to *max*. The *reverse* and *limit* options are also supported. For example, a bar chart can be sorted by descending value like so: a bar chart showing the frequency of letters in the English language in order of descending frequency, starting with E at 13% and ending with Z at almost 0% diff --git a/CHANGELOG-2022.md b/CHANGELOG-2022.md index dd9e9502fa..76976e0590 100644 --- a/CHANGELOG-2022.md +++ b/CHANGELOG-2022.md @@ -6,9 +6,9 @@ Year: [Current (2023)](./CHANGELOG.md) · **2022** · [2021](./CHANGELOG-2021.md [Released December 12, 2022.](https://github.com/observablehq/plot/releases/tag/v0.6.1) -The new [geo mark](./README.md#geo) renders GeoJSON geometries such as polygons, lines, and points. Together with Plot’s new [projection system](https://observablehq.com/@observablehq/plot-projections), Plot can now produce [thematic maps](https://observablehq.com/@observablehq/plot-mapping). For example, the choropleth map below shows unemployment rates by U.S. county. +The new [geo mark](https://observablehq.com/plot/marks/geo) renders GeoJSON geometries such as polygons, lines, and points. Together with Plot’s new [projection system](https://observablehq.com/plot/features/projections), Plot can now produce [thematic maps](https://observablehq.com/@observablehq/plot-mapping). For example, the choropleth map below shows unemployment rates by U.S. county. -[A choropleth of unemployment rate by U.S. county](https://observablehq.com/@observablehq/plot-geo) +[A choropleth of unemployment rate by U.S. county](https://observablehq.com/plot/marks/geo) ```js Plot.geo(counties, {fill: (d) => d.properties.unemployment}).plot({ @@ -23,9 +23,9 @@ Plot.geo(counties, {fill: (d) => d.properties.unemployment}).plot({ }) ``` -The new top-level [**projection** option](./README.md#projection-options) controls how geometric coordinates are transformed to the screen and supports a variety of common geographic projections, including the composite U.S. Albers projection shown above, the Equal Earth projection, the Mercator projection, the orthographic and stereographic projections, several conic and azimuthal projections, among others. Projections can be fit to geometry using the projection.**domain** option, and rotated to an arbitrary aspect using the projection.**rotate** option. +The new top-level [**projection** option](https://observablehq.com/plot/features/projections) controls how geometric coordinates are transformed to the screen and supports a variety of common geographic projections, including the composite U.S. Albers projection shown above, the Equal Earth projection, the Mercator projection, the orthographic and stereographic projections, several conic and azimuthal projections, among others. Projections can be fit to geometry using the projection.**domain** option, and rotated to an arbitrary aspect using the projection.**rotate** option. -[A world map using the orthographic projection, centered somewhere around San Antonio, Texas](https://observablehq.com/@observablehq/plot-projections) +[A world map using the orthographic projection, centered somewhere around San Antonio, Texas](https://observablehq.com/plot/features/projections) ```js Plot.plot({ @@ -67,9 +67,9 @@ Plot.plot({ }) ``` -For the [line mark](./README.md#line), the specified projection doesn’t simply project control points; the projection has full control over how geometry is transformed from its native coordinate system (often spherical) to the screen. This allows line geometry to be represented as [geodesics](https://en.wikipedia.org/wiki/Geodesic), which are sampled and clipped during projection. For example, the map below shows the route of Charles Darwin’s voyage on the HMS *Beagle*; note that the line is cut when it crosses the antimeridian in the Pacific ocean. (Also note the use of the *stroke* channel to vary color.) +For the [line mark](https://observablehq.com/plot/marks/line), the specified projection doesn’t simply project control points; the projection has full control over how geometry is transformed from its native coordinate system (often spherical) to the screen. This allows line geometry to be represented as [geodesics](https://en.wikipedia.org/wiki/Geodesic), which are sampled and clipped during projection. For example, the map below shows the route of Charles Darwin’s voyage on the HMS *Beagle*; note that the line is cut when it crosses the antimeridian in the Pacific ocean. (Also note the use of the *stroke* channel to vary color.) -[A map of the route of the HMS Beagle, 1831–1836; color indicates direction, with the ship initially departing London and heading southwest before circumnavigating the globe](https://observablehq.com/@observablehq/plot-geo) +[A map of the route of the HMS Beagle, 1831–1836; color indicates direction, with the ship initially departing London and heading southwest before circumnavigating the globe](https://observablehq.com/plot/marks/geo) ```js Plot.plot({ @@ -121,7 +121,7 @@ Plot.plot({ }) ``` -In addition to the included basic projections, Plot’s projection system can be extended using any projection implementation compatible with D3’s [projection stream interface](https://github.com/d3/d3-geo/blob/main/README.md#streams). This includes all the projections provided by the [d3-geo-projection](https://github.com/d3/d3-geo-projection) and [d3-geo-polygon](https://github.com/d3/d3-geo-polygon) libraries! For example, here is a world map using Goode’s interrupted homolosine projection. +In addition to the included basic projections, Plot’s projection system can be extended using any projection implementation compatible with D3’s [projection stream interface](https://d3js.org/d3-geo/stream). This includes all the projections provided by the [d3-geo-projection](https://github.com/d3/d3-geo-projection) and [d3-geo-polygon](https://github.com/d3/d3-geo-polygon) libraries! For example, here is a world map using Goode’s interrupted homolosine projection. [A world map using Goode’s interrupted homolosine projection](https://observablehq.com/@observablehq/plot-extended-projections) @@ -142,9 +142,9 @@ Plot.plot({ }) ``` -Plot now supports [mark-level faceting](./README.md#facet-options) via the new *mark*.**fx** and *mark*.**fy** options. Mark-level faceting makes it easier to control which marks are faceted (versus repeated across facets), especially when combining multiple datasets or specifying faceted annotations. +Plot now supports [mark-level faceting](https://observablehq.com/plot/features/facets#mark-facet-options) via the new *mark*.**fx** and *mark*.**fy** options. Mark-level faceting makes it easier to control which marks are faceted (versus repeated across facets), especially when combining multiple datasets or specifying faceted annotations. -[A faceted scatterplot of Anscombe’s quartet](https://observablehq.com/@observablehq/plot-facets) +[A faceted scatterplot of Anscombe’s quartet](https://observablehq.com/plot/features/facets) ```js Plot.plot({ @@ -162,7 +162,7 @@ In addition to the above new features, this release also includes a variety of b [Released September 7, 2022.](https://github.com/observablehq/plot/releases/tag/v0.6.0) -[A smoothed line chart of Apple’s stock price](https://observablehq.com/@observablehq/plot-window) +[A smoothed line chart of Apple’s stock price](https://observablehq.com/plot/transforms/window) ```js Plot.plot({ @@ -174,7 +174,7 @@ Plot.plot({ }) ``` -[breaking] [Plot.window](./README.md#plotwindowk), [Plot.windowX](./README.md#plotwindowxk-options) and [Plot.windowY](./README.md#plotwindowyk-options) now return an aggregate value even when the window contains undefined values, for example at the beginning or end of a series. Set the new **strict** option to true to instead return undefined if the window contains any undefined values. +[breaking] [Plot.window](https://observablehq.com/plot/transforms/window#window), [Plot.windowX](https://observablehq.com/plot/transforms/window#windowX) and [Plot.windowY](https://observablehq.com/plot/transforms/window#windowY) now return an aggregate value even when the window contains undefined values, for example at the beginning or end of a series. Set the new **strict** option to true to instead return undefined if the window contains any undefined values. Parts of the README have been incorporated throughout the codebase as JSDoc comments. This allows IDEs to display the documentation as tooltips. @@ -192,9 +192,9 @@ Plot now uses D3 7.6.1, using [d3.blur2](https://observablehq.com/@d3/d3-blur) f [Released June 27, 2022.](https://github.com/observablehq/plot/releases/tag/v0.5.1) -The new [density mark](./README.md#density) creates contours representing the [estimated density](https://en.wikipedia.org/wiki/Multivariate_kernel_density_estimation) of two-dimensional point clouds. The **bandwidth** and number of **thresholds** are configurable. +The new [density mark](https://observablehq.com/plot/marks/density) creates contours representing the [estimated density](https://en.wikipedia.org/wiki/Multivariate_kernel_density_estimation) of two-dimensional point clouds. The **bandwidth** and number of **thresholds** are configurable. -[A scatterplot showing the relationship between the idle duration and eruption duration for Old Faithful](https://observablehq.com/@observablehq/plot-density) +[A scatterplot showing the relationship between the idle duration and eruption duration for Old Faithful](https://observablehq.com/plot/marks/density) ```js Plot.plot({ @@ -209,7 +209,7 @@ Plot.plot({ By default, as shown above, the density is represented by contour lines. By setting the **fill** option to *density*, you can draw filled regions with a sequential color encoding instead. -[A contour plot showing the relationship between diamond price and weight](https://observablehq.com/@observablehq/plot-density) +[A contour plot showing the relationship between diamond price and weight](https://observablehq.com/plot/marks/density) ```js Plot.density(diamonds, {x: "carat", y: "price", fill: "density"}).plot({ @@ -221,9 +221,9 @@ Plot.density(diamonds, {x: "carat", y: "price", fill: "density"}).plot({ }) ``` -The new [linear regression marks](./README.md#linear-regression) produce [linear regressions](https://en.wikipedia.org/wiki/Linear_regression) with [confidence interval](https://en.wikipedia.org/wiki/Confidence_interval) bands, representing the estimated relation of a dependent variable (typically *y*) on an independent variable (typically *x*). +The new [linear regression marks](https://observablehq.com/plot/marks/linear-regression) produce [linear regressions](https://en.wikipedia.org/wiki/Linear_regression) with [confidence interval](https://en.wikipedia.org/wiki/Confidence_interval) bands, representing the estimated relation of a dependent variable (typically *y*) on an independent variable (typically *x*). -[a scatterplot of penguin culmens, showing the length and depth of several species, with linear regression models by species and for the whole population, illustrating Simpson’s paradox](https://observablehq.com/@observablehq/plot-linear-regression) +[a scatterplot of penguin culmens, showing the length and depth of several species, with linear regression models by species and for the whole population, illustrating Simpson’s paradox](https://observablehq.com/plot/marks/linear-regression) ```js Plot.plot({ @@ -236,9 +236,9 @@ Plot.plot({ }) ``` -The new [Delaunay and Voronoi marks](./README.md#delaunay) produce Delaunay triangulations and Voronoi tesselations: [Plot.delaunayLink](./README.md#plotdelaunaylinkdata-options) draws links for each edge of the Delaunay triangulation of the given points, [Plot.delaunayMesh](./README.md#plotdelaunaymeshdata-options) draws a mesh of the Delaunay triangulation of the given points, [Plot.hull](./README.md#plothulldata-options) draws a convex hull around the given points, [Plot.voronoi](./README.md#plotvoronoidata-options) draws polygons for each cell of the Voronoi tesselation of the given points, and [Plot.voronoiMesh](./README.md#plotvoronoimeshdata-options) draws a mesh for the cell boundaries of the Voronoi tesselation of the given points. +The new [Delaunay and Voronoi marks](https://observablehq.com/plot/marks/delaunay) produce Delaunay triangulations and Voronoi tesselations: [Plot.delaunayLink](https://observablehq.com/plot/marks/delaunay#delaunayLink) draws links for each edge of the Delaunay triangulation of the given points, [Plot.delaunayMesh](https://observablehq.com/plot/marks/delaunay#delaunayMesh) draws a mesh of the Delaunay triangulation of the given points, [Plot.hull](https://observablehq.com/plot/marks/delaunay#hull) draws a convex hull around the given points, [Plot.voronoi](https://observablehq.com/plot/marks/delaunay#voronoi) draws polygons for each cell of the Voronoi tesselation of the given points, and [Plot.voronoiMesh](https://observablehq.com/plot/marks/delaunay#voronoiMesh) draws a mesh for the cell boundaries of the Voronoi tesselation of the given points. -[a Voronoi diagram of penguin culmens, showing the length and depth of several species](https://observablehq.com/@observablehq/plot-delaunay) +[a Voronoi diagram of penguin culmens, showing the length and depth of several species](https://observablehq.com/plot/marks/delaunay) ```js Plot.plot({ @@ -249,7 +249,7 @@ Plot.plot({ }) ``` -For data at regular intervals, such as integer values or daily samples, the new [*scale*.**interval** option](./README.md#scale-options) can be used to enforce uniformity. The specified *interval*—such as d3.utcMonth—sets the default *scale*.transform to the given interval’s *interval*.floor function. In addition, for ordinal scales the default *scale*.**domain** is an array of uniformly-spaced values spanning the extent of the values associated with the scale. +For data at regular intervals, such as integer values or daily samples, the new [*scale*.**interval** option](https://observablehq.com/plot/features/scales#interval) can be used to enforce uniformity. The specified *interval*—such as d3.utcMonth—sets the default *scale*.transform to the given interval’s *interval*.floor function. In addition, for ordinal scales the default *scale*.**domain** is an array of uniformly-spaced values spanning the extent of the values associated with the scale. All marks now support the **pointerEvents** option to set the [pointer-events attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events). The frame decoration mark now supports the **rx** and **ry** options. The cell mark now respects the **dx** and **dy** options. @@ -263,11 +263,11 @@ Improve the error message when the **facet** option is used without **data**. Th [Released June 7, 2022.](https://github.com/observablehq/plot/releases/tag/v0.5.0) -Plot now supports [mark initializers](./README.md#initializers) via the **initializer** option. Initializers can transform data, channels, and indexes. Unlike [data transforms](./README.md#transforms) which operate in abstract data space, initializers can operate in screen space such as pixel coordinates and colors. For example, initializers can modify a marks’ positions to avoid occlusion. The new hexbin and dodge transforms are implemented as mark initializers. +Plot now supports [mark initializers](https://observablehq.com/plot/features/transforms#custom-initializers) via the **initializer** option. Initializers can transform data, channels, and indexes. Unlike [data transforms](https://observablehq.com/plot/features/transforms) which operate in abstract data space, initializers can operate in screen space such as pixel coordinates and colors. For example, initializers can modify a marks’ positions to avoid occlusion. The new hexbin and dodge transforms are implemented as mark initializers. -The new [hexbin transform](./README.md#hexbin) functions similarly to the bin transform, except it aggregates both *x* and *y* into hexagonal bins before reducing. The size of the hexagons can be specified with the **binWidth** option, which controls the width of the (pointy-topped) hexagons. +The new [hexbin transform](https://observablehq.com/plot/transforms/hexbin) functions similarly to the bin transform, except it aggregates both *x* and *y* into hexagonal bins before reducing. The size of the hexagons can be specified with the **binWidth** option, which controls the width of the (pointy-topped) hexagons. -[a chart showing the inverse relationship of fuel economy to engine displacement, and the positive correlation of engine displacement and weight; hexagonal bins of varying size represent the number of cars at each location, while color encodes the mean weight of nearby cars](https://observablehq.com/@observablehq/plot-hexbin) +[a chart showing the inverse relationship of fuel economy to engine displacement, and the positive correlation of engine displacement and weight; hexagonal bins of varying size represent the number of cars at each location, while color encodes the mean weight of nearby cars](https://observablehq.com/plot/transforms/hexbin) ```js Plot.plot({ @@ -286,9 +286,9 @@ Plot.plot({ }) ``` -The new [dodge transform](./README.md#dodge) can be used to produce beeswarm plots. Given an *x* channel representing the desired horizontal position of circles, the dodgeY transform derives a new *y* (vertical position) channel such that the circles do not overlap; the dodgeX transform similarly derives a new *x* channel given a *y* channel. +The new [dodge transform](https://observablehq.com/plot/transforms/dodge) can be used to produce beeswarm plots. Given an *x* channel representing the desired horizontal position of circles, the dodgeY transform derives a new *y* (vertical position) channel such that the circles do not overlap; the dodgeX transform similarly derives a new *x* channel given a *y* channel. -[a beeswarm chart showing a random normal distribution; each of 800 samples is represented by a dot positioned along the x-axis, stacked on top of the y-axis like grains of sand](https://observablehq.com/@observablehq/plot-dodge) +[a beeswarm chart showing a random normal distribution; each of 800 samples is represented by a dot positioned along the x-axis, stacked on top of the y-axis like grains of sand](https://observablehq.com/plot/transforms/dodge) ```js Plot.plot({ @@ -304,7 +304,7 @@ Plot.plot({ If an *r* channel is specified, the circles may have varying radius. By default, the dodge transform sorts the input data by descending radius, such that the largest circles are placed first. The order of placement greatly affects the resulting layout; to change the placement order, use the standard mark **sort** option. -[a chart showing the monthly percent change in travel by U.S. county in March 2020 after the coronavirus outbreak; each county is represented as a circle with area proportional to its population, positioned according to the change in travel; most counties, and especially those with stay-at-home orders, show a significant reduction in travel](https://observablehq.com/@observablehq/plot-dodge) +[a chart showing the monthly percent change in travel by U.S. county in March 2020 after the coronavirus outbreak; each county is represented as a circle with area proportional to its population, positioned according to the change in travel; most counties, and especially those with stay-at-home orders, show a significant reduction in travel](https://observablehq.com/plot/transforms/dodge) ```js Plot.plot({ @@ -331,13 +331,13 @@ When using the dodgeY transform, you should set the height of your plot explicit [breaking] Color scales with diverging color schemes now default to the *diverging* scale type instead of the *linear* scale type. This includes the *brbg*, *prgn*, *piyg*, *puor*, *rdbu*, *rdgy*, *rdylbu*, *rdylgn*, *spectral*, *burd*, and *buylrd* schemes. If you want to use a diverging color scheme with a linear color scale, set the scale **type** option to *linear*. Color scales will also default to diverging if the scale **pivot** option is set. (For diverging scales, the pivot defaults to zero.) -The [sort transform](./README.md#plotsortorder-options) now supports sorting on an existing channel, avoiding the need to duplicate the channel definition. For example, to sort dots by ascending radius: +The [sort transform](https://observablehq.com/plot/transforms/sort) now supports sorting on an existing channel, avoiding the need to duplicate the channel definition. For example, to sort dots by ascending radius: ~~~js Plot.dot(earthquakes, {x: "longitude", y: "latitude", r: "intensity", sort: {channel: "r"}}) ~~~ -The [dot mark](./README.md#dot) now sorts by descending radius by default to reduce occlusion. The dot mark now supports the *hexagon* symbol type for pointy-topped hexagons. The new [circle](./README.md#plotcircledata-options) and [hexagon](./README.md#plothexagondata-options) marks are convenience shorthand for dot marks with the *circle* and *hexagon* symbol, respectively. The dotX, dotY, textX, and textY marks now support the **interval** option. The rule mark now correctly respects the **dx** and **dy** options. The new [hexgrid decoration mark](./README.md#hexgrid) draws a hexagonal grid; it is intended to be used with the hexbin transform as an alternative to the default horizontal and vertical axis grid. +The [dot mark](https://observablehq.com/plot/marks/dot) now sorts by descending radius by default to reduce occlusion. The dot mark now supports the *hexagon* symbol type for pointy-topped hexagons. The new [circle](https://observablehq.com/plot/marks/dot#circle) and [hexagon](https://observablehq.com/plot/marks/dot#hexagon) marks are convenience shorthand for dot marks with the *circle* and *hexagon* symbol, respectively. The dotX, dotY, textX, and textY marks now support the **interval** option. The rule mark now correctly respects the **dx** and **dy** options. The new [hexgrid decoration mark](https://observablehq.com/plot/marks/hexgrid) draws a hexagonal grid; it is intended to be used with the hexbin transform as an alternative to the default horizontal and vertical axis grid. The **zero** scale option (like the **nice** and **clamp** scale options) may now be specified as a top-level option, applying to all quantitative scales. @@ -345,7 +345,7 @@ Marks can now define a channel hint to set the default range of the *r* scale. T Improve the performance of internal array operations, including type coercion. Thanks, @yurivish! -Fix a crash when using the [area mark](./README.md#area) shorthand. +Fix a crash when using the [area mark](https://observablehq.com/plot/marks/area) shorthand. [breaking] The return signature of the internal *mark*.initialize method has changed. It now returns a {data, facets, channels} object instead of {index, channels}, and *channels* is now represented as an object with named properties representing channels rather than an iterable of [*name*, *channel*]. @@ -353,7 +353,7 @@ Fix a crash when using the [area mark](./README.md#area) shorthand. [Released April 12, 2022.](https://github.com/observablehq/plot/releases/tag/v0.4.3) -The new [tree mark and transforms](./README.md#tree) can generate hierarchical node-link diagrams using D3’s [“tidy” tree](https://observablehq.com/@d3/tree) or [cluster (dendrogram)](https://observablehq.com/@d3/cluster) layout. The tree transform uses [d3.stratify](https://observablehq.com/@d3/d3-stratify) to convert tabular data into a hierarchy by parsing a slash-separated **path** for each row. +The new [tree mark and transforms](https://observablehq.com/plot/marks/tree) can generate hierarchical node-link diagrams using D3’s [“tidy” tree](https://observablehq.com/@d3/tree) or [cluster (dendrogram)](https://observablehq.com/@d3/cluster) layout. The tree transform uses [d3.stratify](https://observablehq.com/@d3/d3-stratify) to convert tabular data into a hierarchy by parsing a slash-separated **path** for each row. a node-link tree diagram representing a software hierarchy @@ -367,7 +367,7 @@ Plot.plot({ }) ``` -The [line](./README.md#line) and [area](./README.md#area) marks (specifically lineX, lineY, areaX, and areaY) now support an implicit [bin transform](./README.md#bin) with the **interval** option. This can be used to “regularize” time series data, say to show gaps or default to zero when data is missing, rather than interpolating across missing data. This is also useful for stacking time series data that is sampled at irregular intervals or with missing samples. +The [line](https://observablehq.com/plot/marks/line) and [area](https://observablehq.com/plot/marks/area) marks (specifically lineX, lineY, areaX, and areaY) now support an implicit [bin transform](https://observablehq.com/plot/transforms/bin) with the **interval** option. This can be used to “regularize” time series data, say to show gaps or default to zero when data is missing, rather than interpolating across missing data. This is also useful for stacking time series data that is sampled at irregular intervals or with missing samples. a time-series area chart showing downloads per day with gaps for missing data @@ -395,7 +395,7 @@ Plot.plot({ }) ``` -The [stack transform](./README.md#stack) now allows the **offset** option to be specified as a function. For example, this can be used to visualize Likert survey results with a neutral category as a [diverging stacked bar chart](https://observablehq.com/@observablehq/plot-diverging-stacked-bar). +The [stack transform](https://observablehq.com/plot/transforms/stack) now allows the **offset** option to be specified as a function. For example, this can be used to visualize Likert survey results with a neutral category as a [diverging stacked bar chart](https://observablehq.com/@observablehq/plot-diverging-stacked-bar). a diverging bar chart of responses to a Likert survey question @@ -427,7 +427,7 @@ function Likert( } ``` -The new [_quantize_ scale type](./README.md#color-options) transforms a continuous domain into discrete, evenly-spaced thresholds. The _threshold_ scale type now supports domains in descending order (in addition to ascending order), such as [20, 10, 5, 0] instead of [0, 5, 10, 20]. +The new [_quantize_ scale type](https://observablehq.com/plot/features/scales#color-scale-options) transforms a continuous domain into discrete, evenly-spaced thresholds. The _threshold_ scale type now supports domains in descending order (in addition to ascending order), such as [20, 10, 5, 0] instead of [0, 5, 10, 20]. a scatterplot of Simpsons episodes showing the correlation between number of U.S. viewers and IMDb rating; the decline of the Simspons over time is shown with a quantized color encoding by season @@ -445,17 +445,17 @@ Plot.plot({ }) ``` -The [bin transform](./README.md#bin) now coerces the input channel (the quantity being binned) to numbers as necessary. In addition, the bin transform now correctly handles typed array input channels representing temporal data. The [rect mark](./README.md#rect) now promotes the _x_ channel to _x1_ and _x2_ if the latter two are not specified, and likewise the _y_ channel to _y1_ and _y2_. +The [bin transform](https://observablehq.com/plot/transforms/bin) now coerces the input channel (the quantity being binned) to numbers as necessary. In addition, the bin transform now correctly handles typed array input channels representing temporal data. The [rect mark](https://observablehq.com/plot/marks/rect) now promotes the _x_ channel to _x1_ and _x2_ if the latter two are not specified, and likewise the _y_ channel to _y1_ and _y2_. Fix a crash when **text** or **title** channels contain heterogenous types; each value is now independently formatted in a type-appropriate default formatter. Fix a rendering bug with one-dimensional rects whose opposite dimension is a band scale. Fix a rendering bug with swoopy arrows. Improve error messages to give more context. -New helpers make it easier to implement custom transforms. [Plot.column](./README.md#plotcolumnsource) constructs lazily-evaluated columns for derived channels, and [Plot.transform](./README.md#plottransformoptions-transform) composes a [custom data transform](./README.md#custom-transforms) with any of Plot’s built-in [basic transforms](./README.md#transforms). +New helpers make it easier to implement custom transforms. [Plot.column](https://observablehq.com/plot/features/transforms#column) constructs lazily-evaluated columns for derived channels, and [Plot.transform](https://observablehq.com/plot/features/transforms#transform) composes a [custom data transform](https://observablehq.com/plot/features/transforms#custom-transforms) with any of Plot’s built-in [basic transforms](https://observablehq.com/plot/features/transforms). ## 0.4.2 [Released February 26, 2022.](https://github.com/observablehq/plot/releases/tag/v0.4.2) -The new [box mark](./README.md#box) generates a horizontal or vertical boxplot suitable for visualizing one-dimensional distributions. It is a convenience mark that composites a rule, bar, tick, and dot. +The new [box mark](https://observablehq.com/plot/marks/box) generates a horizontal or vertical boxplot suitable for visualizing one-dimensional distributions. It is a convenience mark that composites a rule, bar, tick, and dot. a boxplot of Michelson’s 1879 measurements of the speed of light @@ -463,7 +463,7 @@ The new [box mark](./README.md#box) generates a horizontal or vertical boxplot s Plot.boxX(morley, {x: "Speed", y: "Expt"}).plot({x: {grid: true, inset: 6}}) ``` -[Plot’s shorthand syntax](https://observablehq.com/@observablehq/plot-shorthand) has been expanded. The [bar mark](./README.md#bar) now supports one-dimensional shorthand: if no *options* are specified, then Plot.barX and Plot.barY can be used to visualize an array of numbers. This shorthand also now applies to the [rect mark](./README.md#rect) and the [vector mark](./README.md#vector). The [area mark](./README.md#area) now supports two-dimensional shorthand: if no *options* are specified, then Plot.area can be used to visualize an array of *xy*-tuples, similar to Plot.line. +[Plot’s shorthand syntax](https://observablehq.com/plot/features/shorthand) has been expanded. The [bar mark](https://observablehq.com/plot/marks/bar) now supports one-dimensional shorthand: if no *options* are specified, then Plot.barX and Plot.barY can be used to visualize an array of numbers. This shorthand also now applies to the [rect mark](https://observablehq.com/plot/marks/rect) and the [vector mark](https://observablehq.com/plot/marks/vector). The [area mark](https://observablehq.com/plot/marks/area) now supports two-dimensional shorthand: if no *options* are specified, then Plot.area can be used to visualize an array of *xy*-tuples, similar to Plot.line. a bar chart of twenty random values @@ -471,7 +471,7 @@ Plot.boxX(morley, {x: "Speed", y: "Expt"}).plot({x: {grid: true, inset: 6}}) Plot.barY(d3.range(20).map(Math.random)).plot() ``` -The mark [sort options](./README.md#sort-options) now support implicit “width” and “height” channels, defined as |*x2* - *x1*| and |*y2* - *y1*| respectively. These channels are useful for sorting rects and bars by length. The *reverse* option defaults to true when sorting by these channels. When sorting by *y* and no *y* channel is available, sorting will now fallback to *y2* if available; the same fallback logic applies to *x* and *x2*. (This behavior was previously supported on marks that support implicit stacking but now applies universally to all marks.) +The mark [sort option](https://observablehq.com/plot/features/scales#sort-mark-option) now supports implicit “width” and “height” channels, defined as |*x2* - *x1*| and |*y2* - *y1*| respectively. These channels are useful for sorting rects and bars by length. The *reverse* option defaults to true when sorting by these channels. When sorting by *y* and no *y* channel is available, sorting will now fallback to *y2* if available; the same fallback logic applies to *x* and *x2*. (This behavior was previously supported on marks that support implicit stacking but now applies universally to all marks.) a bar chart of energy production by source from 1949 to present, with categorical colors assigned in order of the tallest bar @@ -479,7 +479,7 @@ The mark [sort options](./README.md#sort-options) now support implicit “width Plot.rectY(energy, {x: "Year", interval: 1, y: "Value", fill: "Description", sort: {color: "height"}}) ``` -The [bin transform](./README.md#bin) now supports *x* and *y* reducers which represent the midpoint of the bin: (*x1* + *x2*) / 2 and (*y1* + *y2*) / 2 respectively. The [bin](./README.md#bin), [group](./README.md#group), and [window](./README.md#window) transforms now support percentile reducers of the form *pXX* where *XX* is a number in [00, 99]; for example *p25* represents the first quartile and *p75* represents the third quartile. +The [bin transform](https://observablehq.com/plot/transforms/bin) now supports *x* and *y* reducers which represent the midpoint of the bin: (*x1* + *x2*) / 2 and (*y1* + *y2*) / 2 respectively. The [bin](https://observablehq.com/plot/transforms/bin), [group](https://observablehq.com/plot/transforms/group), and [window](https://observablehq.com/plot/transforms/window) transforms now support percentile reducers of the form *pXX* where *XX* is a number in [00, 99]; for example *p25* represents the first quartile and *p75* represents the third quartile. The error message when attempting to create a standalone legend without a valid scale definition has been improved. The high cardinality warning for the implicit *z* channel has been relaxed; it is now only triggered if more than half of the values are distinct. When the axis *ticks* option is specified as null, no ticks are generated. When the axis *tickFormat* option is specified as null, no tick labels are generated. @@ -487,7 +487,7 @@ The error message when attempting to create a standalone legend without a valid [Released February 17, 2022.](https://github.com/observablehq/plot/releases/tag/v0.4.1) -The [area](./README.md#area) and [line marks](./README.md#line) now support varying fill, stroke, title, and other channels within series. For example, this chart of unemployment rates by metro area highlights increases in red and decreases in blue using a window transform with the *difference* reducer. +The [area](https://observablehq.com/plot/marks/area) and [line marks](https://observablehq.com/plot/marks/line) now support varying fill, stroke, title, and other channels within series. For example, this chart of unemployment rates by metro area highlights increases in red and decreases in blue using a window transform with the *difference* reducer. a line chart of unemployment rates by metro area; increases are shown in red, and decreases in blue @@ -515,7 +515,7 @@ Plot.line(aapl, {x: "Date", y: "Close"}) // 🌶 Oops, Date is a string! We will add [more warnings](https://github.com/observablehq/plot/issues/755) in the future. If Plot did something you didn’t expect, please [let us know](https://github.com/observablehq/plot/discussions); perhaps it will inspire a new warning that will help other users. -The [text mark](./README.md#text) now supports automatic wrapping for easier annotation. The new **lineWidth** option specifies the desired length of a line in ems. The line breaking, wrapping, and text metrics implementations are all rudimentary, but they should be acceptable for text that is mostly ASCII. (For more control, you can hard-wrap text manually.) The **monospace** option now provides convenient defaults for monospaced text. +The [text mark](https://observablehq.com/plot/marks/text) now supports automatic wrapping for easier annotation. The new **lineWidth** option specifies the desired length of a line in ems. The line breaking, wrapping, and text metrics implementations are all rudimentary, but they should be acceptable for text that is mostly ASCII. (For more control, you can hard-wrap text manually.) The **monospace** option now provides convenient defaults for monospaced text. a snippet of Moby Dick demonstrating line wrapping @@ -523,7 +523,7 @@ The [text mark](./README.md#text) now supports automatic wrapping for easier ann Plot.text([mobydick], {dx: 6, dy: 6, fontSize: 12, lineWidth: 80, lineHeight: 1.2, frameAnchor: "top-left", monospace: true}) ``` -The line and link marks now support [marker options](./README.md#markers) for drawing a shape such as a dot or arrowhead on each vertex. Circle and arrow markers are provided, or you can implement a custom marker function that returns an SVG marker element. Markers automatically inherit the stroke color of the associated mark. +The line and link marks now support [marker options](https://observablehq.com/plot/features/markers) for drawing a shape such as a dot or arrowhead on each vertex. Circle and arrow markers are provided, or you can implement a custom marker function that returns an SVG marker element. Markers automatically inherit the stroke color of the associated mark. a line chart with circle markers overlaid on each data point @@ -557,9 +557,9 @@ Fix a crash in default tuple accessors for *x* and *y* when data is undefined. F [Released January 20, 2022.](https://github.com/observablehq/plot/releases/tag/v0.4.0) -The new [arrow mark](./README.md#arrow) draws arrows between pairs of points. It is similar to the [link mark](./README.md#link), except it is suitable for directed edges (say for representing change over time) and supports a configurable arrowhead. It also supports “swoopy” arrows with the *bend* option, and insets for arrows to shorten the arrow’s start or end. +The new [arrow mark](https://observablehq.com/plot/marks/arrow) draws arrows between pairs of points. It is similar to the [link mark](https://observablehq.com/plot/marks/link), except it is suitable for directed edges (say for representing change over time) and supports a configurable arrowhead. It also supports “swoopy” arrows with the *bend* option, and insets for arrows to shorten the arrow’s start or end. -[a scatterplot with arrows](https://observablehq.com/@observablehq/plot-arrow) +[a scatterplot with arrows](https://observablehq.com/plot/marks/arrow) ```js Plot.arrow(data, { @@ -572,9 +572,9 @@ Plot.arrow(data, { }) ``` -The new [vector mark](./README.md#vector) similarly draws arrows at the given position (*x* and *y*) with the given magnitude (*length*) and direction (*rotate*). It is intended to visualize vector fields, such as a map of wind speed and direction. +The new [vector mark](https://observablehq.com/plot/marks/vector) similarly draws arrows at the given position (*x* and *y*) with the given magnitude (*length*) and direction (*rotate*). It is intended to visualize vector fields, such as a map of wind speed and direction. -[a vector field](https://observablehq.com/@observablehq/plot-vector) +[a vector field](https://observablehq.com/plot/marks/vector) ```js Plot.vector((T => d3.cross(T, T))(d3.ticks(0, 2 * Math.PI, 20)), { @@ -583,17 +583,17 @@ Plot.vector((T => d3.cross(T, T))(d3.ticks(0, 2 * Math.PI, 20)), { }) ``` -The [dot mark](./README.md#dot) now supports a *symbol* option to control the displayed shape, which defaults to *circle*. The *symbol* channel (and associated *symbol* scale) can also be used as an categorical encoding. The default symbol set is based on whether symbols are stroked or filled, improving differentiability and giving uniform weight. Plot supports all of D3’s built-in symbol types: *circle*, *cross*, *diamond*, *square*, *star*, *triangle*, and *wye* (for fill) and *circle*, *plus*, *times*, *triangle2*, *asterisk*, *square2*, and *diamond2* (for stroke, based on [Heman Robinson’s research](https://www.tandfonline.com/doi/abs/10.1080/10618600.2019.1637746)); you can also implement a [custom symbol type](https://github.com/d3/d3-shape/blob/main/README.md#custom-symbol-types). +The [dot mark](https://observablehq.com/plot/marks/dot) now supports a *symbol* option to control the displayed shape, which defaults to *circle*. The *symbol* channel (and associated *symbol* scale) can also be used as an categorical encoding. The default symbol set is based on whether symbols are stroked or filled, improving differentiability and giving uniform weight. Plot supports all of D3’s built-in symbol types: *circle*, *cross*, *diamond*, *square*, *star*, *triangle*, and *wye* (for fill) and *circle*, *plus*, *times*, *triangle2*, *asterisk*, *square2*, and *diamond2* (for stroke, based on [Heman Robinson’s research](https://www.tandfonline.com/doi/abs/10.1080/10618600.2019.1637746)); you can also implement a [custom symbol type](https://d3js.org/d3-shape/symbol#custom-symbols). -[a scatterplot of penguins by mass and flipper length](https://observablehq.com/@observablehq/plot-dot) +[a scatterplot of penguins by mass and flipper length](https://observablehq.com/plot/marks/dot) ```js Plot.dot(penguins, {x: "body_mass_g", y: "flipper_length_mm", stroke: "species", symbol: "species"}) ``` -The [text mark](./README.md#text) now supports multiline text! When a text value contains `\r`, `\r\n`, or `\n`, it will be split into multiple lines using tspan elements. The new *lineAnchor* and *lineHeight* options control how the lines are positioned relative to the given *xy* position. The text, dot, and image marks now also support a *frameAnchor* option for positioning relative to the frame rather than according to data. This is particularly useful for annotations. +The [text mark](https://observablehq.com/plot/marks/text) now supports multiline text! When a text value contains `\r`, `\r\n`, or `\n`, it will be split into multiple lines using tspan elements. The new *lineAnchor* and *lineHeight* options control how the lines are positioned relative to the given *xy* position. The text, dot, and image marks now also support a *frameAnchor* option for positioning relative to the frame rather than according to data. This is particularly useful for annotations. -[This Is Just To Say, by William Carlos Williams](https://observablehq.com/@observablehq/plot-text) +[This Is Just To Say, by William Carlos Williams](https://observablehq.com/plot/marks/text) ```js Plot.plot({ @@ -613,9 +613,9 @@ All marks now support the new standard *href* channel and *target* option, turni Plot.barY(alphabet, {x: "letter", y: "frequency", href: d => `https://en.wikipedia.org/wiki/${d.letter}`}) ``` -The [bin](./README.md#bin) and [group](./README.md#group) transforms now propagate the *title* and *href* channels, if present, by default. The default reducer for the *title* channel automatically selects the top five distinct title values by count, making it easier to inspect the contents of a given bin or group. +The [bin](https://observablehq.com/plot/transforms/bin) and [group](https://observablehq.com/plot/transforms/group) transforms now propagate the *title* and *href* channels, if present, by default. The default reducer for the *title* channel automatically selects the top five distinct title values by count, making it easier to inspect the contents of a given bin or group. -[a histogram of penguins by species](https://observablehq.com/@observablehq/plot-bin) +[a histogram of penguins by species](https://observablehq.com/plot/transforms/bin) ```js Plot.rectY(data, Plot.binX({y: "count"}, {x: "body_mass_g", fill: "species", title: d => `${d.species} ${d.sex}`})) @@ -623,7 +623,7 @@ Plot.rectY(data, Plot.binX({y: "count"}, {x: "body_mass_g", fill: "species", tit The bin transform now supports shorthand reducers for the bin extent: *x1*, *x2*, *y1*, and *y2*. The window transform now supports the *first* and *last* reducers to select the first or last element of the window, respectively. -The new generalized [select transform](./README.md#select) can now call a custom selector function, or the shorthand *min* and *max*, to select the points to display. The selector function is passed two arguments: the index of the current group (*e.g.*, [0, 1, 2, …]) and the given channel’s values. For example, to select the dot with the greatest *fill* value: +The new generalized [select transform](https://observablehq.com/plot/transforms/select) can now call a custom selector function, or the shorthand *min* and *max*, to select the points to display. The selector function is passed two arguments: the index of the current group (*e.g.*, [0, 1, 2, …]) and the given channel’s values. For example, to select the dot with the greatest *fill* value: ```js Plot.dotX(data, Plot.select({fill: "max"}, {x: "letter", fill: "frequency", stroke: "black"}) @@ -631,7 +631,7 @@ Plot.dotX(data, Plot.select({fill: "max"}, {x: "letter", fill: "frequency", stro The *color* scale now defaults to an *identity* scale if all associated defined values are valid CSS colors, rather than defaulting to the tableau10 categorical color scheme. The new *symbol* scale similarly defaults to *identity* if all associated defined values are valid symbol names (or symbol type objects). -[a chart with red and black bars](https://observablehq.com/@observablehq/plot-bar) +[a chart with red and black bars](https://observablehq.com/plot/marks/bar) ```js Plot.barY(alphabet, {x: "letter", y: "frequency", fill: d => /[AEIOU]/.test(d.letter) ? "red" : "black"}) @@ -639,13 +639,13 @@ Plot.barY(alphabet, {x: "letter", y: "frequency", fill: d => /[AEIOU]/.test(d.le The *color* scale now has a special default range for boolean data, encoding false as light gray and true as dark gray. If you’d prefer more color, specify a sequential scheme such as *reds* or *blues*. (You can opt-out of the special boolean range by setting the scale type to *categorical* or by specifying an explicit *range*.) -[a chart with grey and black bars](https://observablehq.com/@observablehq/plot-bar) +[a chart with grey and black bars](https://observablehq.com/plot/marks/bar) ```js Plot.barY(alphabet, {x: "letter", y: "frequency", fill: d => /[AEIOU]/.test(d.letter)}) ``` -The new [Plot.scale](./README.md#scale-options) method allows you to construct a standalone scale for use independent of any chart, or across charts. The returned object has the same form as *plot*.scale(*name*), allowing you to inspect the scale options and invoke the scale programmatically with *scale*.apply (and *scale*.invert, where applicable). +The new [Plot.scale](https://observablehq.com/plot/features/scales#scale) method allows you to construct a standalone scale for use independent of any chart, or across charts. The returned object has the same form as *plot*.scale(*name*), allowing you to inspect the scale options and invoke the scale programmatically with *scale*.apply (and *scale*.invert, where applicable). ```js const scale = Plot.scale({color: {type: "linear"}}); diff --git a/CHANGELOG.md b/CHANGELOG.md index 27b971440d..e7de2c7826 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,145 @@ Year: **Current (2023)** · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) +## 0.6.10 + +[Released August 14, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.10) + +The new **title** and **subtitle** [plot options](https://observablehq.com/plot/features/plots#other-options) specify a primary and secondary heading. Headings are implemented as h2 and h3 elements by default, but you can provide existing elements instead of text for greater control. Like the existing **caption** option, headings add context and assist interpretation. + +A chart with a title, subtitle, and caption. + +```js +Plot.plot({ + title: "For charts, an informative title", + subtitle: "Subtitle to follow with additional context", + caption: "Figure 1. A chart with a title, subtitle, and caption.", + marks: [ + Plot.frame(), + Plot.text(["Titles, subtitles, captions, and annotations assist inter­pretation by telling the reader what’s interesting. Don’t make the reader work to find what you already know."], {lineWidth: 30, frameAnchor: "middle"}) + ] +}) +``` + +When a chart has a title, subtitle, caption, or legend, Plot automatically wraps the chart’s SVG element with an HTML figure element. The new **figure** plot option, if true, wraps the chart in a figure even if it doesn’t have these other elements; likewise, if false, Plot ignores these other elements and returns a bare SVG element. The figure element now has an associated class (`plot-d6a7b5-figure`). + +The new **clip** plot option determines the default clipping behavior if the [**clip** mark option](https://observablehq.com/plot/features/marks#mark-options) is not specified; set it to true to enable clipping. This option does not affect axis, grid, and frame marks, whose **clip** option defaults to false. + +A line chart of the AAPL ticker, clipped to the frame. + +```js +Plot.plot({ + clip: true, + x: {domain: [new Date(2015, 0, 1), new Date(2015, 3, 1)]}, + y: {grid: true}, + marks: [ + Plot.areaY(aapl, {x: "Date", y: "Close", fillOpacity: 0.1}), + Plot.lineY(aapl, {x: "Date", y: "Close"}), + Plot.ruleY([0], {clip: false}) + ] +}); +``` + +The new [bollinger mark](https://observablehq.com/plot/marks/bollinger) composes a line representing a moving average and an area representing volatility as a band; the band thickness is proportional to the deviation of nearby values. The bollinger mark is built on the new [bollinger map method](https://observablehq.com/plot/marks/bollinger#bollinger), and is often used to analyze the price of financial instruments such as stocks. + +A bollinger chart of the AAPL ticker, computed on a window of the 20 most recent values and a bandwidth of 2 standard deviations. + +```js +Plot.bollingerY(aapl, {x: "Date", y: "Close", n: 20, k: 2}).plot() +``` + +The [arrow mark](https://observablehq.com/plot/marks/arrow) supports a new **sweep** option to control the bend orientation. Below, we set this option to *-y* to draw arrows bulging right, independent of the relative vertical positions of its source and target. + +[Detail of an arc diagram connecting characters in Les Misérables that appear in the same chapters.](https://observablehq.com/@observablehq/plot-arc-diagram?intent=fork) + +```js +Plot.plot({ + height: 1080, + marginLeft: 100, + axis: null, + x: {domain: [0, 1]}, // see https://github.com/observablehq/plot/issues/1541 + color: {domain: d3.range(10), unknown: "#ccc"}, + marks: [ + Plot.dot(miserables.nodes, {x: 0, y: "id", fill: "group", sort: {y: "fill"}}), + Plot.text(miserables.nodes, {x: 0, y: "id", text: "id", textAnchor: "end", dx: -6, fill: "group"}), + Plot.arrow(miserables.links, {x: 0, y1: "source", y2: "target", sweep: "-y", bend: 90, headLength: 0, stroke: samegroup, sort: samegroup, reverse: true}) + ] +}) +``` + +The [auto mark](https://observablehq.com/plot/marks/auto) now does a better job determining the appropriate bar mark implementation, such as with ordinal time series bar charts. + +A stacked bar chart from a time series. + +```js +Plot.auto(timeSeries, {x: "date", y: {value: "value", reduce: "sum"}, color: "type", mark: "bar"}).plot() +``` + +The [pointerX and pointerY transform](https://observablehq.com/plot/interactions/pointer) now use unscaled distance to decide the closest point across facets, preventing points from distant facets from being considered closest. The pointer transform now correctly reports the closest point when moving between facets, and no longer reports multiple closest points if they are the same distance across facets. + +Plot’s documentation now has an [API index](https://observablehq.com/plot/api), version badges pointing to the release notes for a particular feature (or to the pull request for a prerelease feature), and shorter anchors. + +The [tip mark](https://observablehq.com/plot/marks/tip) now shows both labels for paired channels such as *y1*–*y2* or *x1*–*y2* when the channel labels differ. When the **tip** option is set to true on a [geo mark](https://observablehq.com/plot/marks/geo) without a projection, as when using preprojected planar geometry, the display no longer collapses. + +The [stack transform](https://observablehq.com/plot/transforms/stack) now emits a friendlier error message when the supplied value is null. + +## 0.6.9 + +[Released June 27, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.9) + +Time [axes](https://observablehq.com/plot/marks/axis) now default to multi-line ticks, greatly improving readability. When a tick has the same second field value as the previous tick (*e.g.*, “19 Jan” after “17 Jan”), only the first field (“19”) is shown for brevity. The tick format is now based on the tick interval and hence is always consistent, whereas the prior “multi-scale” format varied based on the date, such as “Jan 29” (for Sunday, January 29) and “Tue 31” (for Tuesday, January 31). The new ticks are similar to [Datawrapper](https://blog.datawrapper.de/new-axis-ticks/). + +Before:
+A horizontal time axis showing dates “Wed 25”, “Fri 27”, “Jan 29”, “Tue 31”, and so on. + +After:
+A horizontal time axis showing dates “17 Jan”, “19”, “21”, through “2 Feb”, “4”, and so on. When the month name is shown, it is on a second line below the date. + +It is now easier to construct a “piecewise” [continuous scale](https://observablehq.com/plot/features/scales#continuous-scales) with more than two elements in the **domain** or **range**. This is most often used for a custom color scheme interpolating through fixed colors, such as this pleasing rainbow (sometimes used by artist [Dave Whyte](https://beesandbombs.com/), *a.k.a.* beesandbombs). + +A one-dimensional cell plot of the numbers 0 through 39, laid out horizontally, with color varying smoothly through red, yellow, green-blue, and purple. + +```js +Plot.plot({ + color: { + type: "linear", + range: ["#d70441", "#f4e904", "#009978", "#5e3688"] + }, + marks: [ + Plot.cellX(d3.range(40), {fill: Plot.identity}) + ] +}) +``` + +The [tree mark](https://observablehq.com/plot/marks/tree) now supports a **textLayout** option, which defaults to *mirrored* to alternate the orientation of labels for internal (non-leaf) *vs.* external (leaf) nodes. The treeNode and treeLink marks now also support a new **treeFilter** option, allowing these marks to be filtered without affecting the tree layout. + +A small family tree diagram of Greek gods. Chaos beget Eros, Erebus, Tartarus, and Gaia; Gaia beget Mountains, Pontus, and Uranus. + +```js +Plot.plot({ + axis: null, + height: 100, + margin: 10, + marginLeft: 40, + marginRight: 120, + marks: [ + Plot.tree(gods, {textStroke: "white"}) + ] +}) +``` + +The [barycentric interpolator](https://observablehq.com/plot/marks/raster#interpolatorBarycentric) used by the [raster](https://observablehq.com/plot/marks/raster) and [contour](https://observablehq.com/plot/marks/contour) marks now behaves correctly outside the convex hull of samples. The new algorithm (below right) radiates outwards from the hull, ensuring a continuous image; the old algorithm (below left) radiated inwards from values imputed on the frame’s edges, producing discontinuities. + +A before-and-after comparison of the barycentric interpolator applied to three sample points; in the new algorithm, lines radiate outward perpendicular from the triangle’s sides, producing a more coherent and understandable image. + +The [tip mark](https://observablehq.com/plot/marks/tip) now automatically sets the pointer-events attribute to *none* when associated with the [pointer transform](https://observablehq.com/plot/interactions/pointer) when the the pointer is not sticky, as when hovering a chart without clicking to lock the pointer. This prevents the tip mark from interfering with interaction on other marks, such as clickable links. + +The [auto mark](https://observablehq.com/plot/marks/auto) now renders as a cell, instead of a degenerate invisible rect, when **x** and **y** are both ordinal and the **mark** option is set to *bar*. The [tree mark](https://observablehq.com/plot/marks/tree) no longer produces duplicate tips with the **tip** option. The [rule mark](https://observablehq.com/plot/marks/rule) now respects the top-level **document** option, if any, when using the **clip** option. The [axis mark](https://observablehq.com/plot/marks/axis) now correctly handles the **sort**, **filter**, **reverse**, and **initializer** options. + +The **title**, **ariaLabel**, and **href** channels no longer filter by default; these channels may now be sparsely defined and the associated mark instance will still render. + +The [pointer transform](https://observablehq.com/plot/interactions/pointer) now handles non-faceted marks in faceted plots. The [window transform](https://observablehq.com/plot/transforms/window)’s *median*, *deviation*, *variance*, and percentile reducers have been fixed. + ## 0.6.8 [Released June 2, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.8) @@ -196,13 +335,13 @@ Fix the auto mark to choose the rect mark instead of rectX or rectY when appropr 👉 https://observablehq.com/plot 👈 -The [image mark](./README.md#image) can now generate circular images with the **r** channel, and rotate images with the **rotate** channel. +The [image mark](https://observablehq.com/plot/marks/image) can now generate circular images with the **r** channel, and rotate images with the **rotate** channel. -The [axis mark](./README.md#axis) now properly respects the **margin** shorthand option, changing the default for **marginTop**, **marginRight**, **marginBottom**, and **marginLeft**. The axis mark now correctly renders the axis label when the **href** option is used, or any other option that may be interpreted as a channel. +The [axis mark](https://observablehq.com/plot/marks/axis) now properly respects the **margin** shorthand option, changing the default for **marginTop**, **marginRight**, **marginBottom**, and **marginLeft**. The axis mark now correctly renders the axis label when the **href** option is used, or any other option that may be interpreted as a channel. Facet scale domains are now imputed correctly when the **sort** mark option is used with a **limit**, or otherwise causing the facet domain to be truncated. Plot no longer generates a spurious warning when faceting and using non-array data, such as an Arquero table. The **interval** scale option, when expressed as a fractional number such as 0.2, now has better floating point precision. -The [Plot.indexOf](./README.md#plotindexof) channel transform, used internally by some mark shorthand, is now exported. +The [Plot.indexOf](https://observablehq.com/plot/features/transforms#indexOf) channel transform, used internally by some mark shorthand, is now exported. Plot has a few improvements for server-side rendering. Plot now assumes a high pixel density display when headless. The default class name for plots is now deterministically generated (`plot-d6a7b5`) rather than randomly generated; this makes it easier to apply overrides to Plot’s default styles with an external stylesheet. (The default class name will change if Plot’s default styles change in a future release.) The **className** plot option is now inherited by a plot’s legends, if any. The density mark now respects the Plot’s **document** option, and the **caption** option now uses a duck test instead of testing against the global Node. @@ -244,7 +383,7 @@ The interfaces for reduce and map implementations have changed. To better disamb [Released February 28, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.4) -The new top-level [**aspectRatio** option](./README.md#layout-options) changes the default plot **height** such that, assuming both *x* and *y* are *linear* scales, a scaled unit distance in *x* divided by a scaled unit distance in *y* is the given aspect ratio. For example, if *x* and *y* represent the same units (say, degrees Fahrenheit), and if the **aspectRatio** is one, then scaled distances in *x* and *y* will be equivalent. +The new top-level [**aspectRatio** option](https://observablehq.com/plot/features/plots#aspectRatio) changes the default plot **height** such that, assuming both *x* and *y* are *linear* scales, a scaled unit distance in *x* divided by a scaled unit distance in *y* is the given aspect ratio. For example, if *x* and *y* represent the same units (say, degrees Fahrenheit), and if the **aspectRatio** is one, then scaled distances in *x* and *y* will be equivalent. A scatterplot of daily temperature variation (y) vs. daily low temperature (x). @@ -266,17 +405,17 @@ Plot.plot({ }) ``` -The new **textOverflow** option for the [text mark](./README.md#text) allows text to be truncated when a line of text is longer than the specified **lineWidth**. Overflowing characters can either be clipped (*clip*) or replaced with an ellipsis (*ellipsis*), either at the start, middle, or end of each line. +The new **textOverflow** option for the [text mark](https://observablehq.com/plot/marks/text) allows text to be truncated when a line of text is longer than the specified **lineWidth**. Overflowing characters can either be clipped (*clip*) or replaced with an ellipsis (*ellipsis*), either at the start, middle, or end of each line. A demonstration of Plot’s text overflow methods, including clip-start, clip-end, ellipsis-start, ellipsis-middle, ellipsis-end, applied to titles of Hayao Miyazaki films. When wrapping or truncating, the text mark now more accurately estimates the width of ellipses and emojis, and no longer separates combining marks or emoji character sequences such as 👨‍👩‍👧‍👦. -The [link mark](./README.md#link) now respects the current [**projection**](./README.md#projection-options), if any, given the default [**curve**](./README.md#curves) of *auto*. This matches the behavior of the line mark. To opt-out of the projection and draw a straight line, set the **curve** to *linear*. +The [link mark](https://observablehq.com/plot/marks/link) now respects the current [**projection**](https://observablehq.com/plot/features/projections), if any, given the default [**curve**](https://observablehq.com/plot/features/curves) of *auto*. This matches the behavior of the line mark. To opt-out of the projection and draw a straight line, set the **curve** to *linear*. -The [image mark](./README.md#image) now supports the **imageRendering** option. (Note: Safari currently ignores the SVG image-rendering attribute.) +The [image mark](https://observablehq.com/plot/marks/image) now supports the **imageRendering** option. (Note: Safari currently ignores the SVG image-rendering attribute.) -You can now override the scale for a given [mark channel](./README.md#mark-options) by specifying the corresponding option as a {value, scale} object. For example, to force the **stroke** channel to be unscaled, interpreting the associated values as literal color strings: +You can now override the scale for a given [mark channel](https://observablehq.com/plot/features/marks#marks-have-channels) by specifying the corresponding option as a {value, scale} object. For example, to force the **stroke** channel to be unscaled, interpreting the associated values as literal color strings: ```js Plot.dot(data, {stroke: {value: "foo", scale: null}}) @@ -290,9 +429,9 @@ Plot.dot(data, {stroke: {value: "foo", scale: "color"}}) Color channels (**fill** and **stroke**) are bound to the *color* scale by default, unless the provided values are all valid CSS color strings or nullish, in which case the values are interpreted literally and unscaled. Likewise, if the dot mark’s **symbol** channel values are all symbols, symbol names, or nullish, values are interpreted literally and unscaled; otherwise, the channel is bound to the *symbol* scale. (If some color channels are literal values while other color channels are not, the channels with literal values will now automatically opt-out of the color scale; the same goes for symbol channels. This deviates from the previous behavior, where *all* channels associated with a scale were required to be literal values in order to have the scale default to an *identity* scale.) -The mark [**facetAnchor** option](./README.md#facet-options) can now be set to *empty* such that a mark is only rendered on empty facets. This is typically used for annotation. +The mark [**facetAnchor** option](https://observablehq.com/plot/features/facets#facetAnchor) can now be set to *empty* such that a mark is only rendered on empty facets. This is typically used for annotation. -The new Plot.autoSpec method takes *data* and *options* suitable for [Plot.auto](./README.md#aut) and returns a corresponding *options* object with default options realized. While intended primarily as an internal helper, Plot.autoSpec may be useful for debugging by letting you inspect which mark and reducers are chosen by Plot.auto. +The new Plot.autoSpec method takes *data* and *options* suitable for [Plot.auto](https://observablehq.com/plot/marks/auto) and returns a corresponding *options* object with default options realized. While intended primarily as an internal helper, Plot.autoSpec may be useful for debugging by letting you inspect which mark and reducers are chosen by Plot.auto. Fix Plot.auto to only default to the *bar* mark if *x* or *y* is zeroed. Fix Plot.auto’s support for the *area* mark. Fix Plot.auto’s use of the *bar* mark with possibly ordinal reducers. Fix a bug where arrays of values could be erroneously interpreted as reducers. Fix a crash when the mark **facet** option is set to *exclude*, but the mark is not faceted; the option is now ignored. Fix a crash coercing BigInt values to numbers. @@ -300,51 +439,51 @@ Fix Plot.auto to only default to the *bar* mark if *x* or *y* is zeroed. Fix Plo [Released February 6, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.3) -The new [auto mark](./README.md#auto) ([Plot.auto](./README.md#plotautodata-options)) automatically selects a mark type that best represents the given dimensions of data according to some simple heuristics. For example, +The new [auto mark](https://observablehq.com/plot/marks/auto) ([Plot.auto](https://observablehq.com/plot/marks/auto#auto)) automatically selects a mark type that best represents the given dimensions of data according to some simple heuristics. For example, -[A scatterplot height and weight of olympic athletes.](https://observablehq.com/@observablehq/plot-auto) +[A scatterplot height and weight of olympic athletes.](https://observablehq.com/plot/marks/auto) ```js Plot.auto(olympians, {x: "height", y: "weight"}).plot() ``` -makes a scatterplot (equivalent to [dot](./README.md#plotdotdata-options)); adding **color** as +makes a scatterplot (equivalent to [dot](https://observablehq.com/plot/marks/dot)); adding **color** as -[A heatmap of .](https://observablehq.com/@observablehq/plot-auto) +[A heatmap of .](https://observablehq.com/plot/marks/auto) ```js Plot.auto(olympians, {x: "height", y: "weight", color: "count"}).plot() ``` -makes a heatmap (equivalent to [rect](./README.md#plotrectdata-options) and [bin](./README.md#plotbinoutputs-options); chosen since _height_ and _weight_ are quantitative); switching to +makes a heatmap (equivalent to [rect](https://observablehq.com/plot/marks/rect) and [bin](https://observablehq.com/plot/transforms/bin); chosen since _height_ and _weight_ are quantitative); switching to -[A line chart of Apple stock price.](https://observablehq.com/@observablehq/plot-auto) +[A line chart of Apple stock price.](https://observablehq.com/plot/marks/auto) ```js Plot.auto(aapl, {x: "Date", y: "Close"}).plot() ``` -makes a line chart (equivalent to [lineY](./README.md#plotlineydata-options); chosen because the selected *x* dimension *Date* is temporal and monotonic, _i.e._, the data is in chronological order); +makes a line chart (equivalent to [lineY](https://observablehq.com/plot/marks/line#lineY); chosen because the selected *x* dimension *Date* is temporal and monotonic, _i.e._, the data is in chronological order); -[A histogram of penguin body mass.](https://observablehq.com/@observablehq/plot-auto) +[A histogram of penguin body mass.](https://observablehq.com/plot/marks/auto) ```js Plot.auto(penguins, {x: "body_mass_g"}).plot() ``` -makes a histogram (equivalent to [rectY](./README.md#plotrectydata-options) and [binX](./README.md#plotbinxoutputs-options); chosen because the _body_mass_g_ column is quantitative); and +makes a histogram (equivalent to [rectY](https://observablehq.com/plot/marks/rect#rectY) and [binX](https://observablehq.com/plot/transforms/bin#binX); chosen because the _body_mass_g_ column is quantitative); and -[A vertical bar chart of penguins by island.](https://observablehq.com/@observablehq/plot-auto) +[A vertical bar chart of penguins by island.](https://observablehq.com/plot/marks/auto) ```js Plot.auto(penguins, {x: "island"}).plot() ``` -makes a bar chart (equivalent to [barY](./README.md#plotbarydata-options) and [groupX](./README.md#plotgroupxoutputs-options); chosen because the _island_ column is categorical). The auto mark is intended to support fast exploratory analysis where the goal is to get a useful plot as quickly as possible. It’s also great if you’re new to Plot, since you can get started with a minimal API. +makes a bar chart (equivalent to [barY](https://observablehq.com/plot/marks/bar#barY) and [groupX](https://observablehq.com/plot/transforms/group#groupX); chosen because the _island_ column is categorical). The auto mark is intended to support fast exploratory analysis where the goal is to get a useful plot as quickly as possible. It’s also great if you’re new to Plot, since you can get started with a minimal API. -Plot’s new [axis](./README.md#axis) and [grid](./README.md#axis) marks allow customization and styling of axes. This has been one of our most asked-for features, closing more than a dozen feature requests (see [#1197](https://github.com/observablehq/plot/pull/1197))! The new axis mark composes a [vector](./README.md#vector) for tick marks and a [text](./README.md#text) for tick and axis labels. As such, you can use the rich capabilities of these marks, such the **lineWidth** option to wrap long text labels. +Plot’s new [axis](https://observablehq.com/plot/marks/axis) and [grid](https://observablehq.com/plot/marks/grid) marks allow customization and styling of axes. This has been one of our most asked-for features, closing more than a dozen feature requests (see [#1197](https://github.com/observablehq/plot/pull/1197))! The new axis mark composes a [vector](https://observablehq.com/plot/marks/vector) for tick marks and a [text](https://observablehq.com/plot/marks/text) for tick and axis labels. As such, you can use the rich capabilities of these marks, such the **lineWidth** option to wrap long text labels. -[A bar chart of parodical survey responses demonstrating text wrapping of long axis labels.](https://observablehq.com/@observablehq/plot-auto) +[A bar chart of parodical survey responses demonstrating text wrapping of long axis labels.](https://observablehq.com/plot/marks/auto) ```js Plot.plot({ @@ -360,7 +499,7 @@ Plot.plot({ And since axes and grids are now proper marks, you can interleave them with other marks, for example to produce ggplot2-style axes with a gray background and white grid lines. -[A line chart of Apple’s stock price demonstrating styled axes with a gray background overlaid with white grid lines.](https://observablehq.com/@observablehq/plot-auto) +[A line chart of Apple’s stock price demonstrating styled axes with a gray background overlaid with white grid lines.](https://observablehq.com/plot/marks/auto) ```js Plot.plot({ @@ -376,7 +515,7 @@ Plot.plot({ The *x* and *y* axes are now automatically repeated in empty facets, improving readability by reducing eye travel to read tick values. Below, note that the *x* axis for culmen depth (with ticks at 15 and 20 mm) is rendered below the Adelie/null-sex facet in the top-right. -[A scatterplot showing the culmen length and depth of various penguins, faceted by species and sex; the facets are arranged in a grid, with the y-axis on the left and the x-axis on the bottom.](https://observablehq.com/@observablehq/plot-axes) +[A scatterplot showing the culmen length and depth of various penguins, faceted by species and sex; the facets are arranged in a grid, with the y-axis on the left and the x-axis on the bottom.](ttps://observablehq.com/plot/marks/axis) ```js Plot.plot({ @@ -391,21 +530,21 @@ Plot.plot({ }) ``` -See [Plot: Axes](https://observablehq.com/@observablehq/plot-axes) for more examples, including the new _both_ **axis** option to repeat axes on both sides of the plot, dashed grid lines via the **strokeDasharray** option, data-driven tick placement, and layering axes to show hierarchical time intervals (years, months, weeks). +See [Plot: Axes](https://observablehq.com/plot/marks/axis) for more examples, including the new _both_ **axis** option to repeat axes on both sides of the plot, dashed grid lines via the **strokeDasharray** option, data-driven tick placement, and layering axes to show hierarchical time intervals (years, months, weeks). Marks can now declare default margins via the **marginTop**, **marginRight**, **marginBottom**, and **marginLeft** options, and the **margin** shorthand. For each side, the maximum corresponding margin across marks becomes the plot’s default. While most marks default to zero margins (because they are drawn inside the chart area), Plot‘s axis mark provides default margins depending on their anchor. The facet margin options (*e.g.*, facet.**marginRight**) now correctly affect the positioning of the *x* and *y* axis labels. -The new [*mark*.**facetAnchor**](#facetanchor) mark option controls the facets in which the mark will appear when faceting. It defaults to null for all marks except for axis marks, where it defaults to *top-empty* if the axis anchor is *top*, *right-empty* if anchor is *right*, *bottom-empty* if anchor is *bottom*, and *left-empty* if anchor is *left*. This ensures the proper positioning of the axes with respect to empty facets. +The new [*mark*.**facetAnchor**](https://observablehq.com/plot/features/facets#facetAnchor) mark option controls the facets in which the mark will appear when faceting. It defaults to null for all marks except for axis marks, where it defaults to *top-empty* if the axis anchor is *top*, *right-empty* if anchor is *right*, *bottom-empty* if anchor is *bottom*, and *left-empty* if anchor is *left*. This ensures the proper positioning of the axes with respect to empty facets. -The [frame mark](./README.md#frame)’s new **anchor** option allows you to draw a line on one side of the frame (as opposed to the default behavior where a rect is drawn around all four sides); this feature is now used by the *scale*.**line** option for *x* and *y* scales. The [text mark](./README.md#text) now supports soft hyphens (`\xad`); lines are now eligible to break at soft hyphens, in which case a hyphen (-) will appear at the end of the line before the break. The [raster mark](./README.md#raster) no longer crashes with an _identity_ color scale. The [voronoi mark](./README.md#plotvoronoidata-options) now correctly respects the **target**, **mixBlendMode**, and **opacity** options. +The [frame mark](https://observablehq.com/plot/marks/frame)’s new **anchor** option allows you to draw a line on one side of the frame (as opposed to the default behavior where a rect is drawn around all four sides); this feature is now used by the *scale*.**line** option for *x* and *y* scales. The [text mark](https://observablehq.com/plot/marks/text) now supports soft hyphens (`\xad`); lines are now eligible to break at soft hyphens, in which case a hyphen (-) will appear at the end of the line before the break. The [raster mark](https://observablehq.com/plot/marks/raster) no longer crashes with an _identity_ color scale. The [voronoi mark](https://observablehq.com/plot/marks/delaunay#voronoi) now correctly respects the **target**, **mixBlendMode**, and **opacity** options. ## 0.6.2 [Released January 18, 2023.](https://github.com/observablehq/plot/releases/tag/v0.6.2) -The new [raster mark](./README.md#raster) and [contour mark](./README.md#contour) generate a raster image and smooth contours, respectively, from spatial samples. For example, the plot below shows a gridded digital elevation model of Maungawhau (R’s [`volcano` dataset](./test/data/volcano.json)) with contours every 10 meters: +The new [raster mark](https://observablehq.com/plot/marks/raster) and [contour mark](https://observablehq.com/plot/marks/contour) generate a raster image and smooth contours, respectively, from spatial samples. For example, the plot below shows a gridded digital elevation model of Maungawhau (R’s [`volcano` dataset](./test/data/volcano.json)) with contours every 10 meters: -[A heatmap of Maungawhau’s topography, showing the circular caldera and surrounding slopes](https://observablehq.com/@observablehq/plot-raster) +[A heatmap of Maungawhau’s topography, showing the circular caldera and surrounding slopes](https://observablehq.com/plot/marks/raster) ```js Plot.plot({ @@ -417,9 +556,9 @@ Plot.plot({ }) ``` -For non-gridded or sparse data, the raster and contour marks implement a variety of [spatial interpolation methods](./README.md#spatial-interpolation) to populate the raster grid. The *barycentric* interpolation method, shown below with data from the [Great Britain aeromagnetic survey](https://www.bgs.ac.uk/datasets/gb-aeromagnetic-survey/), uses barycentric coordinates from a Delaunay triangulation of the samples (small black dots). +For non-gridded or sparse data, the raster and contour marks implement a variety of [spatial interpolation methods](https://observablehq.com/plot/marks/raster#spatial-interpolators) to populate the raster grid. The *barycentric* interpolation method, shown below with data from the [Great Britain aeromagnetic survey](https://www.bgs.ac.uk/datasets/gb-aeromagnetic-survey/), uses barycentric coordinates from a Delaunay triangulation of the samples (small black dots). -[A map showing the varying intensity of the magnetic field as periodically observed from an airplane flying in an approximate grid pattern](https://observablehq.com/@observablehq/plot-raster) +[A map showing the varying intensity of the magnetic field as periodically observed from an airplane flying in an approximate grid pattern](https://observablehq.com/plot/marks/raster) ```js Plot.plot({ @@ -438,7 +577,7 @@ Plot.plot({ The same data, with a smidge of blur, as filled contours in projected coordinates: -[A map showing the varying intensity of the magnetic field as periodically observed from an airplane flying in an approximate grid pattern](https://observablehq.com/@observablehq/plot-contour) +[A map showing the varying intensity of the magnetic field as periodically observed from an airplane flying in an approximate grid pattern](https://observablehq.com/plot/marks/contour) ```js Plot.plot({ @@ -450,9 +589,9 @@ Plot.plot({ }) ``` -Naturally, the raster and contour mark are compatible with Plot’s [projection system](./README.md#projection-options), allowing spatial samples to be shown in any geographic projection and in conjunction with other geographic data. The *equirectangular* projection is the natural choice for this gridded global water vapor dataset from [NASA Earth Observations](https://neo.gsfc.nasa.gov/view.php?datasetId=MYDAL2_M_SKY_WV&date=2022-11-01). +Naturally, the raster and contour mark are compatible with Plot’s [projection system](https://observablehq.com/plot/features/projections), allowing spatial samples to be shown in any geographic projection and in conjunction with other geographic data. The *equirectangular* projection is the natural choice for this gridded global water vapor dataset from [NASA Earth Observations](https://neo.gsfc.nasa.gov/view.php?datasetId=MYDAL2_M_SKY_WV&date=2022-11-01). -[A map of global atmospheric water vapor, showing a higher concentration of water vapor near the equator](https://observablehq.com/@observablehq/plot-raster) +[A map of global atmospheric water vapor, showing a higher concentration of water vapor near the equator](https://observablehq.com/plot/marks/raster) ```js Plot.plot({ @@ -480,7 +619,7 @@ Plot.plot({ The raster and contour mark also support sampling continuous spatial functions *f*(*x*, *y*). For example, here is the famous Mandelbrot set, with color encoding the number of iterations before the point escapes: -[The Mandelbrot set](https://observablehq.com/@observablehq/plot-raster) +[The Mandelbrot set](https://observablehq.com/plot/marks/raster) ```js Plot.plot({ @@ -503,7 +642,7 @@ Plot.plot({ }) ``` -The [vector mark](./README.md#vector) now supports the **shape** constant option; the built-in shapes are *arrow* (default) and *spike*. A custom shape can also be implemented, returning the corresponding SVG path data for the desired shape. The new [spike convenience constructor](./README.md#plotspikedata-options) creates a vector suitable for spike maps. The vector mark also now supports an **r** constant option to set the shape radius. +The [vector mark](https://observablehq.com/plot/marks/vector) now supports the **shape** constant option; the built-in shapes are *arrow* (default) and *spike*. A custom shape can also be implemented, returning the corresponding SVG path data for the desired shape. The new [spike convenience constructor](https://observablehq.com/plot/marks/vector#spike) creates a vector suitable for spike maps. The vector mark also now supports an **r** constant option to set the shape radius. [A spike map of U.S. county population](https://observablehq.com/@observablehq/plot-spike) @@ -523,9 +662,9 @@ Plot.plot({ }); ``` -The new [geoCentroid transform](./README.md#plotgeocentroidoptions) and [centroid initializer](./README.md#plotcentroidoptions) compute the spherical and projected planar centroids of geometry, respectively. The new [identity](./README.md#plotidentity) channel helper returns a source array as-is, avoiding an extra copy. +The new [geoCentroid transform](https://observablehq.com/plot/transforms/centroid#geoCentroid) and [centroid initializer](https://observablehq.com/plot/transforms/centroid#centroid) compute the spherical and projected planar centroids of geometry, respectively. The new [identity](https://observablehq.com/plot/features/transforms#identity) channel helper returns a source array as-is, avoiding an extra copy. -The **interval** option now supports named time intervals such as “sunday” and “hour”, equivalent to the corresponding d3-time interval (_e.g._, d3.utcSunday and d3.utcHour). The [bin transform](./README.md#bin) is now many times faster, especially when there are many bins and when binning temporal data. +The **interval** option now supports named time intervals such as “sunday” and “hour”, equivalent to the corresponding d3-time interval (_e.g._, d3.utcSunday and d3.utcHour). The [bin transform](https://observablehq.com/plot/transforms/bin) is now many times faster, especially when there are many bins and when binning temporal data. Diverging scales now correctly handle descending domains. When the stack **order** option is used without a *z* channel, a helpful error message is now thrown. The **clip** option *frame* now correctly handles band scales. Using D3 7.8, generated SVG path data is now rounded to three decimal points to reduce output size. Fix a crash when a facet scale’s domain includes a value for which there is no corresponding facet data. The bin, group, and hexbin transforms now correctly ignore undefined outputs. Upgrade D3 to 7.8.2. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2724123003..ce9e603351 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Observable Plot - Contributing -Observable Plot is open source and released under the [ISC license](./LICENSE). You are welcome to [send us pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) to contribute bug fixes or new features. We also invite you to participate in [issues](https://github.com/observablehq/plot/issues) and [discussions](https://github.com/observablehq/plot/discussions). We use issues to track and diagnose bugs, as well as to debate and design enhancements to Plot. Discussions are intended for you to ask for help using Plot, or to share something cool you’ve built with Plot. You can also ask for help on the [Observable Forum](https://talk.observablehq.com) and the [Observable community Slack](https://observable-community.slack.com/ssb/redirect). +Observable Plot is open source and released under the [ISC license](./LICENSE). You are welcome to [send us pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) to contribute bug fixes or new features. We also invite you to participate in [issues](https://github.com/observablehq/plot/issues) and [discussions](https://github.com/observablehq/plot/discussions). We use issues to track and diagnose bugs, as well as to debate and design enhancements to Plot. Discussions are intended for you to ask for help using Plot, or to share something cool you’ve built with Plot. You can also ask for help on the [Observable Forum](https://talk.observablehq.com) and the [Observable community Slack](https://join.slack.com/t/observable-community/shared_invite/zt-1x7gs4fck-UHhEFxUXKHVE8Qt3XmJCig). We request that you abide by our [code of conduct](https://observablehq.com/@observablehq/code-of-conduct) when contributing and participating in discussions. @@ -81,7 +81,7 @@ export async function lineUnemployment() { } ``` -When a snapshot test is run, its output is compared against the SVG or HTML snapshot saved in the `test/output` folder. This makes it easier to review the effect of code changes and to catch unintended changes. Snapshot tests must have deterministic, reproducible behavior; they should not depend on live data, external servers, the current time, the weather, etc. To use randomness in a test, use a seeded random number generator such as [d3.randomLcg](https://github.com/d3/d3-random/blob/master/README.md#randomLcg). +When a snapshot test is run, its output is compared against the SVG or HTML snapshot saved in the `test/output` folder. This makes it easier to review the effect of code changes and to catch unintended changes. Snapshot tests must have deterministic, reproducible behavior; they should not depend on live data, external servers, the current time, the weather, etc. To use randomness in a test, use a seeded random number generator such as [d3.randomLcg](https://d3js.org/d3-random#randomLcg). To add a new snapshot test, create a new JavaScript file in the `test/plots` folder using the pattern shown above. Then export your snapshot test function from [`test/plots/index.ts`](./test/plots/index.ts). For example: diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index cea3e017cc..fa9a56dfa6 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,4 +1,5 @@ -import path from "path"; +import {fileURLToPath, URL} from "node:url"; +import path from "node:path"; import {defineConfig} from "vitepress"; import plot from "./markdown-it-plot.js"; @@ -11,9 +12,10 @@ export default defineConfig({ cleanUrls: true, vite: { resolve: { - alias: { - "@observablehq/plot": path.resolve("./src/index.js") - } + alias: [ + {find: "@observablehq/plot", replacement: path.resolve("./src/index.js")}, + {find: /^.*\/VPFooter\.vue$/, replacement: fileURLToPath(new URL("./theme/CustomFooter.vue", import.meta.url))} + ] } }, markdown: { @@ -27,6 +29,9 @@ export default defineConfig({ ["script", {async: "", src: "https://www.googletagmanager.com/gtag/js?id=G-9B88TP6PKQ"}], ["script", {}, "window.dataLayer=window.dataLayer||[];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js',new Date());\ngtag('config','G-9B88TP6PKQ');"] ], + sitemap: { + hostname: 'https://observablehq.com/plot' + }, themeConfig: { // https://vitepress.dev/reference/default-theme-config // Theme related configurations. @@ -77,6 +82,7 @@ export default defineConfig({ {text: "Auto", link: "/marks/auto"}, {text: "Axis", link: "/marks/axis"}, {text: "Bar", link: "/marks/bar"}, + {text: "Bollinger", link: "/marks/bollinger"}, {text: "Box", link: "/marks/box"}, {text: "Cell", link: "/marks/cell"}, {text: "Contour", link: "/marks/contour"}, @@ -89,7 +95,7 @@ export default defineConfig({ {text: "Hexgrid", link: "/marks/hexgrid"}, {text: "Image", link: "/marks/image"}, {text: "Line", link: "/marks/line"}, - {text: "Linear Regression", link: "/marks/linear-regression"}, + {text: "Linear regression", link: "/marks/linear-regression"}, {text: "Link", link: "/marks/link"}, {text: "Raster", link: "/marks/raster"}, {text: "Rect", link: "/marks/rect"}, @@ -128,7 +134,8 @@ export default defineConfig({ {text: "Crosshair", link: "/interactions/crosshair"}, {text: "Pointer", link: "/interactions/pointer"} ] - } + }, + {text: "API index", link: "/api"} ], search: { provider: "local" @@ -137,7 +144,7 @@ export default defineConfig({ {icon: "github", link: "https://github.com/observablehq/plot"}, {icon: "twitter", link: "https://twitter.com/observablehq"}, {icon: "mastodon", link: "https://vis.social/@observablehq"}, - {icon: "slack", link: "https://observable-community.slack.com/ssb/redirect"}, + {icon: "slack", link: "https://join.slack.com/t/observable-community/shared_invite/zt-1x7gs4fck-UHhEFxUXKHVE8Qt3XmJCig"}, {icon: "linkedin", link: "https://www.linkedin.com/company/observable"}, {icon: "youtube", link: "https://www.youtube.com/c/Observablehq"} ], diff --git a/docs/.vitepress/markdown-it-plot.ts b/docs/.vitepress/markdown-it-plot.ts index f338f0ba3b..eb6253f421 100644 --- a/docs/.vitepress/markdown-it-plot.ts +++ b/docs/.vitepress/markdown-it-plot.ts @@ -26,7 +26,7 @@ export default function plot(md) { directives.includes("hidden") ? `
\n` : href - ? `Fork` + ? `Fork` : "" }`; if (/^Plot\.plot\(/.test(content)) { diff --git a/docs/.vitepress/theme/CustomFooter.vue b/docs/.vitepress/theme/CustomFooter.vue new file mode 100644 index 0000000000..868e4ad684 --- /dev/null +++ b/docs/.vitepress/theme/CustomFooter.vue @@ -0,0 +1,51 @@ + + + diff --git a/docs/.vitepress/theme/CustomLayout.vue b/docs/.vitepress/theme/CustomLayout.vue new file mode 100644 index 0000000000..30c1a7ec13 --- /dev/null +++ b/docs/.vitepress/theme/CustomLayout.vue @@ -0,0 +1,16 @@ + + + diff --git a/docs/.vitepress/theme/ObservablePromo.vue b/docs/.vitepress/theme/ObservablePromo.vue new file mode 100644 index 0000000000..0e199464e3 --- /dev/null +++ b/docs/.vitepress/theme/ObservablePromo.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/docs/.vitepress/theme/VersionBadge.vue b/docs/.vitepress/theme/VersionBadge.vue new file mode 100644 index 0000000000..f58d251a77 --- /dev/null +++ b/docs/.vitepress/theme/VersionBadge.vue @@ -0,0 +1,12 @@ + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index 573e7817ce..6c4e2c5c57 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -31,6 +31,27 @@ z-index: 1; } +.vp-doc .plot-figure { + margin: 16px 0 0; +} + +.vp-doc .plot-figure h2, +.vp-doc .plot-figure h3 { + all: unset; + display: block; +} + +.vp-doc .plot-figure h2 { + line-height: 28px; + font-size: 20px; + font-weight: 600; + letter-spacing: -0.01em; +} + +.vp-doc .plot a:hover { + text-decoration: initial; +} + :root [aria-label="tip"][fill="white"], :root [aria-label="tip"] [fill="white"] { fill: var(--vp-c-bg-alt); @@ -58,6 +79,7 @@ .label-input > label { display: inline-flex; + align-items: center; } .label-input > input, @@ -99,3 +121,53 @@ a.plot-fork:hover { .vp-doc p:hover .header-anchor { opacity: 1; } + +.bg-alt { + background: var(--vp-c-bg-alt); +} + +.lh-normal { + line-height: normal; +} + +.flex { + display: flex; +} + +.flex-grow-1 { + flex-grow: 1; +} + +.ma4 { + margin: 2rem; +} + +.ml1 { + margin-left: 1rem; +} + +.mb2 { + margin-bottom: 0.5rem; +} + +.f12 { + font-size: 12px; +} + +.f14 { + font-size: 14px; +} + +.fw6 { + font-weight: 600; +} + +.fb6 { + flex-basis: 10rem; +} + +@media screen and (min-width: 960px) { + .flex-l { + display: flex; + } +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 3e7f52c081..2586ce3da3 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -2,13 +2,17 @@ import DefaultTheme from "vitepress/theme-without-fonts"; import {useData} from "vitepress"; import {watch} from "vue"; import PlotRender from "../../components/PlotRender.js"; +import CustomLayout from "./CustomLayout.vue"; +import VersionBadge from "./VersionBadge.vue"; import "./custom.css"; export default { extends: DefaultTheme, + Layout: CustomLayout, enhanceApp({app, router}) { Object.defineProperty(app.config.globalProperties, "$dark", {get: () => useData().isDark.value}); app.component("PlotRender", PlotRender); + app.component("VersionBadge", VersionBadge); enableAnalytics(router); } }; diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000000..fc5b914929 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,34 @@ + + +# API index + +## Methods + + + +## Options + + + + diff --git a/docs/community.md b/docs/community.md index 7ff2f5ced7..75d20a1aea 100644 --- a/docs/community.md +++ b/docs/community.md @@ -4,7 +4,11 @@ Learning Plot? Love data visualization? Don’t go it alone! Join our community ## Staying up-to-date -Plot is getting better all the time. If you like Plot, please star ⭐️ our [GitHub repo](https://github.com/observablehq/plot) to help get the word out and to see updates on your GitHub dashboard. +:::tip +Please star ⭐️ our [GitHub repo](https://github.com/observablehq/plot) to show your support for us on GitHub! +::: + +Plot is getting better all the time; catch up on [recent releases](https://github.com/observablehq/plot/releases) by reading our [CHANGELOG](https://github.com/observablehq/plot/blob/main/CHANGELOG.md). For email updates, sign up for the [Observable Plot Twist](https://observablehq.com/@observablehq/plot-twist-newsletter-signup) newsletter. (See our [back issues](https://observablehq.com/collection/@observablehq/newsletters/2) and [blog](https://observablehq.com/blog), too.) This monthly newsletter will let you know about new features in Plot, inspiring work by the community, upcoming workshops and community events, and more. @@ -12,9 +16,9 @@ And of course, follow us on [Observable](https://observablehq.com/@observablehq? ## Getting help -We recommend asking for help on the [Observable forum](https://talk.observablehq.com/c/help/6). Or if you prefer chat, join the [Observable community Slack](https://observable-community.slack.com/ssb/redirect). +We recommend asking for help on the [Observable forum](https://talk.observablehq.com/c/help/6). Or if you prefer chat, join the [Observable community Slack](https://join.slack.com/t/observable-community/shared_invite/zt-1x7gs4fck-UHhEFxUXKHVE8Qt3XmJCig). -We encourage you to share your work, no matter how messy, on [Observable](https://observablehq.com). Sharing live code is the easiest way to let people see what you see, and to debug your problem. Strive for a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example)—it helps people hone in on your problem more quickly. +We encourage you to share your work, no matter how messy, on [Observable](https://observablehq.com). Sharing live code is the easiest way to let people see what you see, and to debug your problem. Strive for a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) — it helps people hone in on your problem more quickly. When asking for help, don’t just post your code and ask people to fix it. Provide context, and say what you want help with. For example: @@ -23,7 +27,7 @@ When asking for help, don’t just post your code and ask people to fix it. Prov - What behavior are you currently seeing? - Is the current behavior not what you expect? -If you think you’ve found a bug in Plot, please file a [GitHub issue](https://github.com/observablehq/plot/issues). But don’t use an issue to ask for help—you’ll have better luck on the forum or Slack. +If you think you’ve found a bug in Plot, please file a [GitHub issue](https://github.com/observablehq/plot/issues). But don’t use an issue to ask for help — you’ll have better luck on the forum or Slack. ## Getting involved @@ -33,7 +37,7 @@ We’d love for you to join the community! Here are some ways to participate: * Upvote 👍 or comment on [GitHub issues](https://github.com/observablehq/plot/issues). We’d love your input on what to build next. If your desired feature isn’t already there, or if you’ve found a bug, file an issue and tell us about it. -* Answer questions or participate in discussions on the [Observable forum](https://talk.observablehq.com/) and the [Observable community Slack](https://observable-community.slack.com/ssb/redirect). You’ll help others, and might learn something yourself, too. +* Answer questions or participate in discussions on the [Observable forum](https://talk.observablehq.com/) and the [Observable community Slack](https://join.slack.com/t/observable-community/shared_invite/zt-1x7gs4fck-UHhEFxUXKHVE8Qt3XmJCig). You’ll help others, and might learn something yourself, too. * Open a pull request! Read our [guide to contributing](https://github.com/observablehq/plot/blob/main/CONTRIBUTING.md). diff --git a/docs/components/PlotRender.js b/docs/components/PlotRender.js index 07b6acf171..519d1f678f 100644 --- a/docs/components/PlotRender.js +++ b/docs/components/PlotRender.js @@ -69,6 +69,11 @@ class Element { dispatchEvent() { // ignored; interaction needs real DOM } + append(...children) { + for (const child of children) { + this.appendChild(child?.ownerDocument ? child : this.ownerDocument.createTextNode(child)); + } + } appendChild(child) { this.children.push(child); child.parentNode = this; @@ -212,7 +217,10 @@ export default { } if (typeof document !== "undefined") { const plot = Plot[method](options); - const replace = (el) => el.firstChild.replaceWith(plot); + const replace = (el) => { + while (el.lastChild) el.lastChild.remove(); + el.append(plot); + }; return withDirectives(h("span", [toHyperScript(plot)]), [[{mounted: replace, updated: replace}]]); } return h("span", [Plot[method]({...options, document: new Document()}).toHyperScript()]); diff --git a/docs/components/links.js b/docs/components/links.js new file mode 100644 index 0000000000..ed46b5fdfe --- /dev/null +++ b/docs/components/links.js @@ -0,0 +1,48 @@ +import {readdir, readFile, stat} from "fs/promises"; + +// Anchors can be derived from headers, or explicitly written as {#names}. +export function getAnchors(text) { + text = text.replace(/<(?:Version)?Badge[^/]*\/>/g, ""); // ignore badges + const anchors = []; + for (const [, header] of text.matchAll(/^#+ ([*\w][*().,\w\d -]+)\n/gm)) { + anchors.push( + header + .replace(/[^\w\d\s]+/g, " ") + .trim() + .replace(/ +/g, "-") + .toLowerCase() + ); + } + for (const [, anchor] of text.matchAll(/ \{#([\w\d-]+)\}/g)) { + anchors.push(anchor); + } + return anchors; +} + +// Internal links. +export function getLinks(file, text) { + const links = []; + for (const match of text.matchAll(/\[[^\]]+\]\(([^)]+)\)/g)) { + const [, link] = match; + if (/^\w+:/.test(link)) continue; // absolute link with protocol + const {pathname, hash} = new URL(link, new URL(file, "https://example.com/")); + links.push({pathname, hash}); + } + return links; +} + +// In source files, ignore comments. +export async function readMarkdownSource(f) { + return (await readFile(f, "utf8")).replaceAll(//gs, ""); +} + +// Recursively find all md files in the directory. +export async function* readMarkdownFiles(root, subpath = "/") { + for (const fname of await readdir(root + subpath)) { + if (!fname.includes(".") && (await stat(root + subpath + fname)).isDirectory()) { + yield* readMarkdownFiles(root, subpath + fname + "/"); + } else if (fname.endsWith(".md")) { + yield subpath + fname; + } + } +} diff --git a/docs/data/api.data.ts b/docs/data/api.data.ts new file mode 100644 index 0000000000..f159806e72 --- /dev/null +++ b/docs/data/api.data.ts @@ -0,0 +1,167 @@ +import {rollup, sort} from "d3"; +import {FunctionDeclaration, Node, Project, VariableStatement} from "ts-morph"; +import {readMarkdownFiles, readMarkdownSource, getAnchors} from "../components/links.js"; + +// These interfaces tend to represent things that Plot constructs internally, +// rather than objects that the user is expected to provide. +function isInternalInterface(name) { + return ( + name === "AutoSpec" || + name === "Channel" || + name === "ChannelDomainOptions" || // TODO + name === "ChannelTransform" || + name === "Context" || + name === "Dimensions" || + name === "Plot" || + name === "Scale" + ); +} + +// This tries to get a brief human-readable, one-sentence summary description of +// the exported symbol. We might want to formalize this so that we can be more +// intentional when authoring documentation. +function getDescription(node: FunctionDeclaration | VariableStatement): string { + return node + .getJsDocs()[0] + ?.getDescription() + .replace(/\n/g, " ") // replace newlines with spaces + .replace(/[*_]/g, "") // remove bold and italics formatting + .replace(/[.:]($|\s+).*/g, "") // truncate at the first period or colon + .replace(/\[([^[]+)\]\[\d+\]/g, "$1") // strip links (assuming [1] syntax) + .trim(); +} + +// While we try to keep the source code file structure as close as possible to +// the documentation URL structure, there are some inevitable deviations that +// are codified by this function. When new files are added, please try to keep +// this function up-to-date, and try to generalize patterns so that we +// automatically generate correct links. (TODO Verify that the links are valid.) +function getHref(name: string, path: string): string { + path = path.replace(/\.d\.ts$/, ""); // drop trailing .d.ts + path = path.replace(/([a-z0-9])([A-Z])/, (_, a, b) => `${a}-${b.toLowerCase()}`); // camel case conversion + if (path.split("/").length === 1) path = `features/${path}`; // top-level declarations are features + switch (path) { + case "features/curve": + case "features/format": + case "features/mark": + case "features/marker": + case "features/plot": + case "features/projection": + return `${path}s`; + case "features/inset": + return "features/scales"; + case "features/options": + return "features/transforms"; + case "marks/axis": { + switch (name) { + case "gridX": + case "gridY": + case "gridFx": + case "gridFy": + return "marks/grid"; + } + break; + } + case "marks/crosshair": + return "interactions/crosshair"; + case "transforms/basic": { + switch (name) { + case "filter": + return "transforms/filter"; + case "reverse": + case "shuffle": + case "sort": + return "transforms/sort"; + } + return "features/transforms"; + } + } + return path; +} + +function getInterfaceName(name: string, path: string): string { + name = name.replace(/(Transform|Corner|X|Y|Output)?(Defaults|Options|Styles)$/, ""); + name = name.replace(/([a-z0-9])([A-Z])/, (_, a, b) => `${a} ${b}`); // camel case conversion + name = name.toLowerCase(); + if (name === "curve auto") name = "curve"; + if (name === "plot facet") name = "plot"; + if (path.startsWith("marks/")) name += " mark"; + else if (path.startsWith("transforms/")) name += " transform"; + return name; +} + +export default { + watch: [], + async load() { + // Parse the TypeScript declarations to get exported symbols. + const project = new Project({tsConfigFilePath: "tsconfig.json"}); + const allMethods: {name: string; comment: string; href: string}[] = []; + const allOptions: {name: string; context: {name: string; href: string}}[] = []; + const index = project.getSourceFile("src/index.d.ts")!; + for (const [name, declarations] of index.getExportedDeclarations()) { + for (const declaration of declarations) { + if (Node.isInterfaceDeclaration(declaration)) { + if (isInternalInterface(name)) continue; + for (const property of declaration.getProperties()) { + const path = index.getRelativePathTo(declaration.getSourceFile()); + const href = getHref(name, path); + if (property.getJsDocs().some((d) => d.getTags().some((d) => Node.isJSDocDeprecatedTag(d)))) continue; + allOptions.push({name: property.getName(), context: {name: getInterfaceName(name, path), href}}); + } + } else if (Node.isFunctionDeclaration(declaration)) { + const comment = getDescription(declaration); + if (comment) { + const href = getHref(name, index.getRelativePathTo(declaration.getSourceFile())); + allMethods.push({name, comment, href}); + } + } else if (Node.isVariableDeclaration(declaration)) { + const comment = getDescription(declaration.getVariableStatement()!); + if (comment) { + const href = getHref(name, index.getRelativePathTo(declaration.getSourceFile())); + allMethods.push({name, comment, href}); + } + } + } + } + // Parse the Markdown files to get all known anchors. + const root = "docs"; + const anchors = new Map(); + for await (const file of readMarkdownFiles(root)) { + const text = await readMarkdownSource(root + file); + anchors.set(file, getAnchors(text)); + } + // Cross-reference the generated links. + for (const {name, href} of allMethods) { + if (!anchors.has(`/${href}.md`)) { + throw new Error(`file not found: ${href}`); + } + if (!anchors.get(`/${href}.md`).includes(name)) { + throw new Error(`anchor not found: ${href}#${name}`); + } + } + for (const {context: {href}} of allOptions) { + if (!anchors.has(`/${href}.md`)) { + throw new Error(`file not found: ${href}`); + } + } + return { + methods: sort(allMethods, ({name}) => name), + options: sort( + rollup( + allOptions, + (D) => + sort( + rollup( + D.map((d) => d.context), + ([d]) => d, + (d) => d.name + ).values(), + (d) => d.name + ), + (d) => d.name + ), + ([name]) => name + ) + }; + } +}; diff --git a/docs/data/miserables.data.ts b/docs/data/miserables.data.ts new file mode 100644 index 0000000000..3862663751 --- /dev/null +++ b/docs/data/miserables.data.ts @@ -0,0 +1,8 @@ +import fs from "node:fs"; + +export default { + watch: ["../public/data/miserables.json"], + load([file]) { + return JSON.parse(fs.readFileSync(file, "utf-8")); + } +}; diff --git a/docs/data/miserables.ts b/docs/data/miserables.ts new file mode 100644 index 0000000000..aa1ecae79e --- /dev/null +++ b/docs/data/miserables.ts @@ -0,0 +1,3 @@ +import {data} from "./miserables.data"; + +export default Object.assign(data, {groups: new Map(data.nodes.map((d) => [d.id, d.group]))}); diff --git a/docs/features/curves.md b/docs/features/curves.md index 28f15f0831..a01780b4c5 100644 --- a/docs/features/curves.md +++ b/docs/features/curves.md @@ -11,7 +11,7 @@ const numbers = d3.range(20).map(d3.randomLcg(42)); # Curves -A **curve** defines how to turn a discrete representation of a line as a sequence of points [[*x₀*, *y₀*], [*x₁*, *y₁*], [*x₂*, *y₂*], …] into a continuous path; *i.e.*, how to interpolate between points. Curves are used by the [line](../marks/line.md), [area](../marks/area.md), and [link](../marks/link.md) marks, and are implemented by [d3-shape](https://github.com/d3/d3-shape/blob/main/README.md#curves). +A **curve** defines how to turn a discrete representation of a line as a sequence of points [[*x₀*, *y₀*], [*x₁*, *y₁*], [*x₂*, *y₂*], …] into a continuous path; *i.e.*, how to interpolate between points. Curves are used by the [line](../marks/line.md), [area](../marks/area.md), and [link](../marks/link.md) marks, and are implemented by [d3-shape](https://d3js.org/d3-shape/curve).

+``` +::: + +See our [Plot + Svelte REPL](https://svelte.dev/repl/ebf78a6a6c1145ecb84cf9345a7f82ae?version=4.2.0) for details. diff --git a/docs/interactions/crosshair.md b/docs/interactions/crosshair.md index 17e27c9644..8c58bc03f2 100644 --- a/docs/interactions/crosshair.md +++ b/docs/interactions/crosshair.md @@ -8,7 +8,7 @@ import penguins from "../data/penguins.ts"; -# Crosshair mark +# Crosshair mark The **crosshair mark** shows the *x* (horizontal↔︎ position) and *y* (vertical↕︎ position) value of the point closest to the [pointer](./pointer.md) on the bottom and left sides of the frame, respectively. @@ -23,7 +23,7 @@ Plot.plot({ ``` ::: -For charts which have a “dominant” dimension, such as time in a time-series chart, use the crosshairX or crosshairY mark for the [pointerX](./pointer.md#pointerx-options) or [pointerY](./pointer.md#pointery-options) transform as appropriate. +For charts which have a “dominant” dimension, such as time in a time-series chart, use the crosshairX or crosshairY mark for the [pointerX](./pointer.md#pointerX) or [pointerY](./pointer.md#pointerY) transform as appropriate. :::plot defer https://observablehq.com/@observablehq/plot-crosshairx ```js @@ -84,7 +84,7 @@ The following options are supported: The crosshair mark supports faceting, but most other mark options are ignored. -## crosshair(*data*, *options*) +## crosshair(*data*, *options*) {#crosshair} ```js Plot.crosshair(cars, {x: "economy (mpg)", y: "cylinders"}) @@ -92,18 +92,18 @@ Plot.crosshair(cars, {x: "economy (mpg)", y: "cylinders"}) Returns a new crosshair for the given *data* and *options*, drawing horizontal and vertical rules. The corresponding **x** and **y** values are also drawn just outside the bottom and left sides of the frame, respectively, typically on top of the axes. If either **x** or **y** is not specified, the crosshair will be one-dimensional. -## crosshairX(*data*, *options*) +## crosshairX(*data*, *options*) {#crosshairX} ```js Plot.crosshairX(aapl, {x: "Date", y: "Close"}) ``` -Like crosshair, but using [pointerX](./pointer.md#pointerx-options) when *x* is the dominant dimension, like time in a time-series chart. +Like crosshair, but using [pointerX](./pointer.md#pointerX) when *x* is the dominant dimension, like time in a time-series chart. -## crosshairY(*data*, *options*) +## crosshairY(*data*, *options*) {#crosshairY} ```js Plot.crosshairY(aapl, {x: "Date", y: "Close"}) ``` -Like crosshair, but using [pointerY](./pointer.md#pointery-options) when *y* is the dominant dimension. +Like crosshair, but using [pointerY](./pointer.md#pointerY) when *y* is the dominant dimension. diff --git a/docs/interactions/pointer.md b/docs/interactions/pointer.md index 0a89d28e2d..89b6a8e253 100644 --- a/docs/interactions/pointer.md +++ b/docs/interactions/pointer.md @@ -21,7 +21,7 @@ onMounted(() => { -# Pointer transform +# Pointer transform The **pointer transform** filters a mark interactively such that only the point closest to the pointer is rendered. It is typically used to show details on hover, often with a [tip](../marks/tip.md) or [crosshair](./crosshair.md) mark, but it can be paired with any mark. @@ -72,7 +72,7 @@ Plot.plot({ The pointer transform is similar to the [filter](../transforms/filter.md) and [select](../transforms/select.md) transforms: it filters the mark’s index to show a subset of the data. The difference is that the pointer transform is *interactive*: it listens to [pointer events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events) and re-renders the mark as the closest point changes. Since the mark is lazily rendered during interaction, it is fast: only the visible elements are rendered as needed. And, like the filter and select transforms, unfiltered channel values are incorporated into default scale domains. -The pointer transform supports both one- and two-dimensional pointing modes. The two-dimensional mode, [pointer](#pointer-options-1), is used above and is suitable for scatterplots and the general case: it finds the point closest to the pointer by measuring distance in *x* and *y*. The one-dimensional modes, [pointerX](#pointerx-options) and [pointerY](#pointery-options), in contrast only consider distance in one dimension; this is desirable when a chart has a “dominant” dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart. +The pointer transform supports both one- and two-dimensional pointing modes. The two-dimensional mode, [pointer](#pointer), is used above and is suitable for scatterplots and the general case: it finds the point closest to the pointer by measuring distance in *x* and *y*. The one-dimensional modes, [pointerX](#pointerX) and [pointerY](#pointerY), in contrast only consider distance in one dimension; this is desirable when a chart has a “dominant” dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart. Try the different modes on the line chart below to get a feel for their behavior. @@ -180,7 +180,7 @@ To resolve the horizontal target position, the pointer transform applies the fol The same precedence applies to the **py**, **y**, **y1**, and **y2** channels. -## pointer(*options*) +## pointer(*options*) {#pointer} ```js Plot.tip(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm"})) @@ -188,18 +188,18 @@ Plot.tip(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm"})) Applies the pointer render transform to the specified *options* to filter the mark index such that only the point closest to the pointer is rendered; the mark will re-render interactively in response to pointer events. -## pointerX(*options*) +## pointerX(*options*) {#pointerX} ```js Plot.tip(aapl, Plot.pointerX({x: "Date", y: "Close"})) ``` -Like [pointer](#pointer-options-1), except the determination of the closest point considers mostly the *x* (horizontal↔︎) position; this should be used for plots where *x* is the dominant dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart. +Like [pointer](#pointer), except the determination of the closest point considers mostly the *x* (horizontal↔︎) position; this should be used for plots where *x* is the dominant dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart. -## pointerY(*options*) +## pointerY(*options*) {#pointerY} ```js Plot.tip(alphabet, Plot.pointerY({x: "frequency", y: "letter"})) ``` -Like [pointer](#pointer-options-1), except the determination of the closest point considers mostly the *y* (vertical↕︎) position; this should be used for plots where *y* is the dominant dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart. +Like [pointer](#pointer), except the determination of the closest point considers mostly the *y* (vertical↕︎) position; this should be used for plots where *y* is the dominant dimension, such as time in a time-series chart, the binned quantitative dimension in a histogram, or the categorical dimension of a bar chart. diff --git a/docs/marks/area.md b/docs/marks/area.md index 3a6673b6da..bec175a637 100644 --- a/docs/marks/area.md +++ b/docs/marks/area.md @@ -18,7 +18,7 @@ Plot.areaY(aapl, {x: "Date", y: "Close"}).plot() ``` ::: -The area mark has three constructors: [areaY](#areay-data-options) for when the baseline and topline share *x* values, as in a time-series area chart where time goes right→ (or ←left); [areaX](#areax-data-options) for when the baseline and topline share *y* values, as in a time-series area chart where time goes up↑ (or down↓); and lastly the rarely-used [area](#area-data-options) where the baseline and topline share neither *x* nor *y* values. +The area mark has three constructors: [areaY](#areaY) for when the baseline and topline share *x* values, as in a time-series area chart where time goes right→ (or ←left); [areaX](#areaX) for when the baseline and topline share *y* values, as in a time-series area chart where time goes up↑ (or down↓); and lastly the rarely-used [area](#area) where the baseline and topline share neither *x* nor *y* values. The area mark is often paired with a [line](./line.md) and [rule](./rule.md) mark to accentuate the topline and baseline. @@ -102,7 +102,7 @@ Plot.plot({ ``` ::: -For a vertically-oriented baseline and topline, such as when time goes up↑ instead of right→, use [areaX](#areax-data-options) instead of [areaY](#areay-data-options) and swap **x** and **y**. +For a vertically-oriented baseline and topline, such as when time goes up↑ instead of right→, use [areaX](#areaX) instead of [areaY](#areaY) and swap **x** and **y**. :::plot defer https://observablehq.com/@observablehq/plot-vertical-area-chart ```js @@ -282,7 +282,7 @@ In addition to the [standard mark options](../features/marks.md#mark-options), t * **y2** - the vertical position of the topline; bound to the *y* scale * **z** - a categorical value to group data into series -If **x2** is not specified, it defaults to **x1**. If **y2** is not specified, it defaults to **y1**. These defaults facilitate sharing *x* or *y* coordinates between the baseline and topline. See also the implicit stack transform and shorthand **x** and **y** options supported by [areaY](#areay-data-options) and [areaX](#areax-data-options). +If **x2** is not specified, it defaults to **x1**. If **y2** is not specified, it defaults to **y1**. These defaults facilitate sharing *x* or *y* coordinates between the baseline and topline. See also the implicit stack transform and shorthand **x** and **y** options supported by [areaY](#areaY) and [areaX](#areaX). By default, the data is assumed to represent a single series (*i.e.*, a single value that varies over time). If the **z** channel is specified, data is grouped by **z** to form separate series. Typically **z** is a categorical value such as a series name. If **z** is not specified, it defaults to **fill** if a channel, or **stroke** if a channel. @@ -290,9 +290,9 @@ The **stroke** defaults to *none*. The **fill** defaults to *currentColor* if th Points along the baseline and topline are connected in input order. Likewise, if there are multiple series via the **z**, **fill**, or **stroke** channel, the series are drawn in input order such that the last series is drawn on top. Typically, the data is already in sorted order, such as chronological for time series; if sorting is needed, consider a [sort transform](../transforms/sort.md). -The area mark supports [curve options](../features/curves.md) to control interpolation between points. If any of the **x1**, **y1**, **x2**, or **y2** values are invalid (undefined, null, or NaN), the baseline and topline will be interrupted, resulting in a break that divides the area shape into multiple segments. (See [d3-shape’s *area*.defined](https://github.com/d3/d3-shape/blob/main/README.md#area_defined) for more.) If an area segment consists of only a single point, it may appear invisible unless rendered with rounded or square line caps. In addition, some curves such as *cardinal-open* only render a visible segment if it contains multiple points. +The area mark supports [curve options](../features/curves.md) to control interpolation between points. If any of the **x1**, **y1**, **x2**, or **y2** values are invalid (undefined, null, or NaN), the baseline and topline will be interrupted, resulting in a break that divides the area shape into multiple segments. (See [d3-shape’s *area*.defined](https://d3js.org/d3-shape/area#area_defined) for more.) If an area segment consists of only a single point, it may appear invisible unless rendered with rounded or square line caps. In addition, some curves such as *cardinal-open* only render a visible segment if it contains multiple points. -## areaY(*data*, *options*) +## areaY(*data*, *options*) {#areaY} ```js Plot.areaY(aapl, {x: "Date", y: "Close"}) @@ -310,7 +310,7 @@ The **interval** option is recommended to “regularize” sampled data; for exa The **areaY** mark draws the region between a baseline (*y1*) and a topline (*y2*) as in an area chart. When the baseline is *y* = 0, the *y* channel can be specified instead of *y1* and *y2*. For example, here is an area chart of Apple’s stock price. -## areaX(*data*, *options*) +## areaX(*data*, *options*) {#areaX} ```js Plot.areaX(aapl, {y: "Date", x: "Close"}) @@ -326,10 +326,10 @@ Plot.areaX(observations, {y: "date", x: "temperature", interval: "day"}) The **interval** option is recommended to “regularize” sampled data; for example, if your data represents timestamped temperature measurements and you expect one sample per day, use "day" as the interval. -## area(*data*, *options*) +## area(*data*, *options*) {#area} ```js Plot.area(aapl, {x1: "Date", y1: 0, y2: "Close"}) ``` -Returns a new area with the given *data* and *options*. This method is rarely used directly; it is only needed when the baseline and topline have neither common **x** nor **y** values. [areaY](#areay-data-options) is used in the common horizontal orientation where the baseline and topline share **x** values, while [areaX](#areax-data-options) is used in the vertical orientation where the baseline and topline share **y** values. +Returns a new area with the given *data* and *options*. This method is rarely used directly; it is only needed when the baseline and topline have neither common **x** nor **y** values. [areaY](#areaY) is used in the common horizontal orientation where the baseline and topline share **x** values, while [areaX](#areaX) is used in the vertical orientation where the baseline and topline share **y** values. diff --git a/docs/marks/arrow.md b/docs/marks/arrow.md index 07023ff507..0c94fa4762 100644 --- a/docs/marks/arrow.md +++ b/docs/marks/arrow.md @@ -3,14 +3,28 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; import metros from "../data/metros.ts"; +import miserables from "../data/miserables.ts"; -const matrix = [[3, 2, 5], [1, 7, 2], [1, 1, 8]]; -const nodes = matrix.map((m, i) => d3.pointRadial(((2 - i) * 2 * Math.PI) / matrix.length, 100)); -const edges = matrix.flatMap((m, i) => m.map((value, j) => ([nodes[i], nodes[j], value]))); +const markov = (() => { + const matrix = [[3, 2, 5], [1, 7, 2], [1, 1, 8]]; + const nodes = matrix.map((m, i) => d3.pointRadial(((2 - i) * 2 * Math.PI) / matrix.length, 100)); + const edges = matrix.flatMap((m, i) => m.map((value, j) => ([nodes[i], nodes[j], value]))); + return {nodes, edges}; +})(); + +function samegroup({source, target}) { + source = miserables.groups.get(source); + target = miserables.groups.get(target); + return source === target ? source : null; +} -# Arrow mark +# Arrow mark + +:::tip +See also the [vector mark](./vector.md), which draws arrows of a given length and direction. +::: The **arrow mark** draws arrows between two points [**x1**, **y1**] and [**x2**, **y2**] in quantitative dimensions. It is similar to the [link mark](./link.md), except it draws an arrowhead and is suitable for directed edges. With the **bend** option, it can be swoopy.⤵︎ @@ -67,8 +81,8 @@ Plot.plot({ aspectRatio: 1, axis: null, marks: [ - Plot.dot(nodes, {r: 40}), - Plot.arrow(edges, { + Plot.dot(markov.nodes, {r: 40}), + Plot.arrow(markov.edges, { x1: ([[x1]]) => x1, y1: ([[, y1]]) => y1, x2: ([, [x2]]) => x2, @@ -79,8 +93,8 @@ Plot.plot({ headLength: 24, inset: 48 }), - Plot.text(nodes, {text: ["A", "B", "C"], dy: 12}), - Plot.text(edges, { + Plot.text(markov.nodes, {text: ["A", "B", "C"], dy: 12}), + Plot.text(markov.edges, { x: ([[x1, y1], [x2, y2]]) => (x1 + x2) / 2 + (y1 - y2) * 0.15, y: ([[x1, y1], [x2, y2]]) => (y1 + y2) / 2 - (x1 - x2) * 0.15, text: ([,, value]) => value @@ -90,7 +104,24 @@ Plot.plot({ ``` ::: -See also the [vector mark](./vector.md), which draws arrows of a given length and direction. +For undirected edges, as in the arc diagram of character co-occurrence in *Les Misérables* below, set the **sweep** option to the desired orientation: *-y* for right-bulging links whose endpoints are vertically separated. + +:::plot https://observablehq.com/@observablehq/plot-arc-diagram +```js +Plot.plot({ + height: 1080, + marginLeft: 100, + axis: null, + x: {domain: [0, 1]}, // see https://github.com/observablehq/plot/issues/1541 + color: {domain: d3.range(10), unknown: "#ccc"}, + marks: [ + Plot.dot(miserables.nodes, {x: 0, y: "id", fill: "group", sort: {y: "fill"}}), + Plot.text(miserables.nodes, {x: 0, y: "id", text: "id", textAnchor: "end", dx: -6, fill: "group"}), + Plot.arrow(miserables.links, {x: 0, y1: "source", y2: "target", sweep: "-y", bend: 90, headLength: 0, stroke: samegroup, sort: samegroup, reverse: true}) + ] +}) +``` +::: ## Arrow options @@ -111,10 +142,13 @@ The arrow mark supports the [standard mark options](../features/marks.md#mark-op * **insetEnd** - inset at the end of the arrow (useful if the arrow points to a dot) * **insetStart** - inset at the start of the arrow * **inset** - shorthand for the two insets +* **sweep** - the sweep order The **bend** option sets the angle between the straight line connecting the two points and the outgoing direction of the arrow from the start point. It must be within ±90°. A positive angle will produce a clockwise curve; a negative angle will produce a counterclockwise curve; zero will produce a straight line. The **headAngle** determines how pointy the arrowhead is; it is typically between 0° and 180°. The **headLength** determines the scale of the arrowhead relative to the stroke width. Assuming the default of stroke width 1.5px, the **headLength** is the length of the arrowhead’s side in pixels. -## arrow(*data*, *options*) +The **sweep** option controls the bend orientation. It defaults to 1 indicating a positive (clockwise) bend angle; -1 indicates a negative (anticlockwise) bend angle; 0 effectively clears the bend angle. If *-x*, the bend angle is flipped when the ending point is to the left of the starting point — ensuring all arrows bulge up (down if bend is negative); if *-y*, the bend angle is flipped when the ending point is above the starting point — ensuring all arrows bulge right (left if bend is negative); the sign is negated for *+x* and *+y*. + +## arrow(*data*, *options*) {#arrow} ```js Plot.arrow(inequality, {x1: "POP_1980", y1: "R90_10_1980", x2: "POP_2015", y2: "R90_10_2015", bend: true}) diff --git a/docs/marks/auto.md b/docs/marks/auto.md index 582108a154..640c1e44ae 100644 --- a/docs/marks/auto.md +++ b/docs/marks/auto.md @@ -15,9 +15,9 @@ onMounted(() => { -# Auto mark +# Auto mark -The magic ✨ **auto mark** automatically selects a mark type that best represents the given dimensions of the data according to some simple heuristics. The auto mark—which powers [Observable’s chart cell](https://observablehq.com/@observablehq/chart-cell)—is intended to support fast exploratory analysis where the goal is to get a useful plot as quickly as possible. For example, two quantitative dimensions make a scatterplot: +The magic ✨ **auto mark** automatically selects a mark type that best represents the given dimensions of the data according to some simple heuristics. The auto mark — which powers [Observable’s chart cell](https://observablehq.com/@observablehq/chart-cell) — is intended to support fast exploratory analysis where the goal is to get a useful plot as quickly as possible. For example, two quantitative dimensions make a scatterplot: :::plot https://observablehq.com/@observablehq/plot-auto-mark-scatterplot ```js @@ -82,7 +82,7 @@ Plot.rect(olympians, Plot.bin({fill: "count"}, {x: "weight", y: "height"})).plot Notice that the code above makes you think about nested functions and two different options objects, which the auto mark flattens. The auto mark infers that it should use a [rect](./rect.md); that it should [bin](../transforms/bin.md) on **x** and **y**; that the kind of color should be a **fill**; and that **fill** is an “output” of the reducer, whereas **x** and **y** are “inputs”. -This saves you a little bit of typing, but, more importantly, it means that switching from showing one dimension to another only involves changing _one thing_. In the code above, if you change **y** from *weight* to *sex*, it’ll break, because *sex* is ordinal instead of quantitative. (You’d also have to change [rect](./rect.md) to [barX](./bar.md#barx-data-options), and [bin](../transforms/bin.md#bin-outputs-options) to [binX](../transforms/bin.md#binx-outputs-options).) With the auto mark, it just works: +This saves you a little bit of typing, but, more importantly, it means that switching from showing one dimension to another only involves changing _one thing_. In the code above, if you change **y** from *weight* to *sex*, it’ll break, because *sex* is ordinal instead of quantitative. (You’d also have to change [rect](./rect.md) to [barX](./bar.md#barX), and [bin](../transforms/bin.md#bin) to [binX](../transforms/bin.md#binX).) With the auto mark, it just works: :::plot defer https://observablehq.com/@observablehq/plot-auto-mark-heatmap-2 ```js @@ -90,7 +90,7 @@ Plot.auto(olympians, {x: "weight", y: "sex", color: "count"}).plot() ``` ::: -Similarly, with explicit marks and transforms, changing a vertical histogram to a horizontal histogram involves switching [rectY](./rect.md#recty-data-options) to [rectX](./rect.md#rectx-data-options), [binX](../transforms/bin.md#binx-outputs-options) to [binY](../transforms/bin.md#biny-outputs-options), **x** to **y**, and **y** to **x**. With the auto mark, just specify **y** instead of **x**: +Similarly, with explicit marks and transforms, changing a vertical histogram to a horizontal histogram involves switching [rectY](./rect.md#rectY) to [rectX](./rect.md#rectX), [binX](../transforms/bin.md#binX) to [binY](../transforms/bin.md#binY), **x** to **y**, and **y** to **x**. With the auto mark, just specify **y** instead of **x**: :::plot https://observablehq.com/@observablehq/plot-auto-mark-horizontal-histogram ```js @@ -220,7 +220,7 @@ The auto mark chooses the mark type automatically based on several simple heuris The chosen mark type depends both on the options you provide (*e.g.*, whether you specified **x** or **y** or both) and the inferred type of the corresponding data values (whether the associated dimension of data is quantitative, categorical, monotonic, *etc.*). -## auto(*data*, *options*) +## auto(*data*, *options*) {#auto} ```js Plot.auto(olympians, {x: "weight", y: "height", color: "count"}) // equivalent to rect + bin, say @@ -228,7 +228,7 @@ Plot.auto(olympians, {x: "weight", y: "height", color: "count"}) // equivalent t Returns an automatically-chosen mark with the given *data* and *options*, suitable for a quick view of the data. -## autoSpec(*data*, *options*) +## autoSpec(*data*, *options*) {#autoSpec} ```js Plot.autoSpec(olympians, {x: "weight", y: "height", color: "count"}) diff --git a/docs/marks/axis.md b/docs/marks/axis.md index 0f9411640c..c792615cea 100644 --- a/docs/marks/axis.md +++ b/docs/marks/axis.md @@ -21,7 +21,7 @@ const responses = [ -# Axis mark +# Axis mark The **axis mark** conveys the meaning of a position [scale](../features/scales.md): _x_ or _y_, and _fx_ or _fy_ when [faceting](../features/facets.md). Plot automatically adds default axis marks as needed, but you can customize the appearance of axes either through scale options or by explicitly declaring an axis mark. @@ -143,34 +143,22 @@ Plot.plot({ ``` ::: -You can emulate [Datawrapper’s time axes](https://blog.datawrapper.de/new-axis-ticks/) using `\n` (the line feed character) for multi-line tick labels, plus a bit of date math to detect the first month of each year. +Time axes default to a consistent multi-line tick format , [à la Datawrapper](https://blog.datawrapper.de/new-axis-ticks/), for example showing the first month of each quarter, and the year: :::plot https://observablehq.com/@observablehq/plot-datawrapper-style-date-axis ```js Plot.plot({ marks: [ Plot.ruleY([0]), - Plot.line(aapl, {x: "Date", y: "Close"}), + Plot.axisX({ticks: "3 months"}), Plot.gridX(), - Plot.axisX({ - ticks: 20, - tickFormat: ( - (formatYear, formatMonth) => (x) => - x.getUTCMonth() === 0 - ? `${formatMonth(x)}\n${formatYear(x)}` - : formatMonth(x) - )(d3.utcFormat("%Y"), d3.utcFormat("%b")) - }) + Plot.line(aapl, {x: "Date", y: "Close"}) ] }) ``` ::: -:::tip -In the future, Plot may generate multi-line time axis labels by default. If you’re interested in this feature, please upvote [#1285](https://github.com/observablehq/plot/issues/1285). -::: - -Alternatively, you can add multiple axes with options for hierarchical time intervals, here showing weeks, months, and years. +The format is inferred from the tick interval, and consists of two fields (*e.g.*, month and year, day and month, minutes and hours); when a tick has the same second field value as the previous tick (*e.g.*, “19 Jan” after “17 Jan”), only the first field (“19”) is shown for brevity. Alternatively, you can specify multiple explicit axes with options for hierarchical time intervals, here showing weeks, months, and years. :::plot https://observablehq.com/@observablehq/plot-multiscale-date-axis ```js @@ -357,7 +345,7 @@ In addition to the [standard mark options](../features/marks.md), the axis mark * **fontVariant** - the ticks’ font-variant; defaults to *tabular-nums* for quantitative axes * **label** - a string to label the axis; defaults to the scale’s label, perhaps with an arrow * **labelAnchor** - the label anchor: *top*, *right*, *bottom*, *left*, or *center* -* **labelArrow** - the label arrow: *auto* (default), *up*, *right*, *down*, *left*, *none*, or true +* **labelArrow** - the label arrow: *auto* (default), *up*, *right*, *down*, *left*, *none*, or true * **labelOffset** - the label position offset (in pixels; default depends on margins and orientation) * **color** - the color of the ticks and labels (defaults to *currentColor*) * **textStroke** - the color of the stroke around tick labels (defaults to *none*) @@ -379,7 +367,7 @@ The axis mark’s default margins depend on its orientation (**anchor**) as foll For simplicity’s sake and for consistent layout across plots, axis margins are not automatically sized to make room for tick labels; instead, shorten your tick labels (for example using the *k* SI-prefix tick format, or setting a *scale*.transform to show thousands or millions, or setting the **textOverflow** option to *ellipsis* and the **lineWidth** option to clip long labels) or increase the margins as needed. -## axisX(*data*, *options*) +## axisX(*data*, *options*) {#axisX} ```js Plot.axisX({anchor: "bottom", tickSpacing: 80}) @@ -387,7 +375,7 @@ Plot.axisX({anchor: "bottom", tickSpacing: 80}) Returns a new *x* axis with the given *options*. -## axisY(*data*, *options*) +## axisY(*data*, *options*) {#axisY} ```js Plot.axisY({anchor: "left", tickSpacing: 35}) @@ -395,7 +383,7 @@ Plot.axisY({anchor: "left", tickSpacing: 35}) Returns a new *y* axis with the given *options*. -## axisFx(*data*, *options*) +## axisFx(*data*, *options*) {#axisFx} ```js Plot.axisFx({anchor: "top", label: null}) @@ -403,7 +391,7 @@ Plot.axisFx({anchor: "top", label: null}) Returns a new *fx* axis with the given *options*. -## axisFy(*data*, *options*) +## axisFy(*data*, *options*) {#axisFy} ```js Plot.axisFy({anchor: "right", label: null}) diff --git a/docs/marks/bar.md b/docs/marks/bar.md index 5ca6773851..9516c3b13b 100644 --- a/docs/marks/bar.md +++ b/docs/marks/bar.md @@ -29,7 +29,7 @@ const timeseries = [ The bar mark is one of several marks in Plot for drawing rectangles; it should be used when one dimension is ordinal and the other is quantitative. See also [rect](./rect.md) and [cell](./cell.md). ::: -The **bar mark** comes in two orientations: [barY](#bary-data-options) extends vertically↑ as in a vertical bar chart or column chart, while [barX](#barx-data-options) extends horizontally→. For example, the bar chart below shows the frequency of letters in the English language. +The **bar mark** comes in two orientations: [barY](#barY) extends vertically↑ as in a vertical bar chart or column chart, while [barX](#barX) extends horizontally→. For example, the bar chart below shows the frequency of letters in the English language. :::plot https://observablehq.com/@observablehq/plot-vertical-bars ```js @@ -134,7 +134,7 @@ Plot.plot({ The **percent** scale option is useful for showing percentages; it applies a [scale transform](../features/scales.md#scale-transforms) that multiplies associated channel values by 100. ::: -When ordinal data is regular, such as the yearly observations of the time-series bar chart of world population below, use the **interval** option to enforce uniformity and show gaps for missing data. It can be set to a named interval such as *hour* or *day*, a number for numeric intervals, a [d3-time interval](https://github.com/d3/d3-time/blob/main/README.md#api-reference), or a custom implementation. +When ordinal data is regular, such as the yearly observations of the time-series bar chart of world population below, use the **interval** option to enforce uniformity and show gaps for missing data. It can be set to a named interval such as *hour* or *day*, a number for numeric intervals, a [d3-time interval](https://d3js.org/d3-time#_interval), or a custom implementation.

+ + +

+ +:::plot hidden +```js +Plot.bollingerY(aapl, {x: "Date", y: "Close", n, k}).plot() +``` +::: + +```js-vue +Plot.bollingerY(aapl, {x: "Date", y: "Close", n: {{n}}, k: {{k}}}).plot() +``` + +For more control, you can also use the [bollinger map method](#bollinger) directly with the [map transform](../transforms/map.md). + +:::plot +```js +Plot.plot({ + marks: [ + Plot.lineY(aapl, Plot.mapY(Plot.bollinger({n: 20, k: -2}), {x: "Date", y: "Close", stroke: "red"})), + Plot.lineY(aapl, Plot.mapY(Plot.bollinger({n: 20, k: 2}), {x: "Date", y: "Close", stroke: "green"})), + Plot.lineY(aapl, {x: "Date", y: "Close"}) + ] +}) +``` +::: + +Below a candlestick chart is constructed from two [rule marks](./rule.md), with a bollinger mark underneath to emphasize the days when the stock was more volatile. + +:::plot +```js +Plot.plot({ + x: {domain: [new Date("2014-01-01"), new Date("2014-06-01")]}, + y: {domain: [68, 92], grid: true}, + color: {domain: [-1, 0, 1], range: ["red", "black", "green"]}, + marks: [ + Plot.bollingerY(aapl, {x: "Date", y: "Close", stroke: "none", clip: true}), + Plot.ruleX(aapl, {x: "Date", y1: "Low", y2: "High", strokeWidth: 1, clip: true}), + Plot.ruleX(aapl, {x: "Date", y1: "Open", y2: "Close", strokeWidth: 3, stroke: (d) => Math.sign(d.Close - d.Open), clip: true}) + ] +}) +``` +::: + +The bollinger mark has two constructors: the common [bollingerY](#bollingerY) for when time goes right→ (or ←left); and the rare [bollingerX](#bollingerX) for when time goes up↑ (or down↓). + +:::plot +```js +Plot.bollingerX(aapl, {y: "Date", x: "Close"}).plot() +``` +::: + +As [shorthand](../features/shorthand.md), you can pass an array of numbers as data. Below, the *x* axis represents the zero-based index into the data (*i.e.*, trading days since May 13, 2013). + +:::plot +```js +Plot.bollingerY(aapl.map((d) => d.Close)).plot() +``` +::: + +## Bollinger options + +The bollinger mark is a [composite mark](../features/marks.md#marks) consisting of two marks: + +* an [area](../marks/area.md) representing volatility as a band, and +* a [line](../marks/line.md) representing a moving average + +The bollinger mark supports the following special options: + +* **n** - the window size (the window transform’s **k** option), an integer; defaults to 20 +* **k** - the band radius, a number representing a multiple of standard deviations; defaults to 2 +* **color** - the fill color of the area, and the stroke color of the line; defaults to *currentColor* +* **opacity** - the fill opacity of the area; defaults to 0.2 +* **fill** - the fill color of the area; defaults to **color** +* **fillOpacity** - the fill opacity of the area; defaults to **opacity** +* **stroke** - the stroke color of the line; defaults to **color** +* **strokeOpacity** - the stroke opacity of the line; defaults to 1 +* **strokeWidth** - the stroke width of the line in pixels; defaults to 1.5 + +Any additional options are passed through to the underlying [line mark](./line.md), [area mark](./area.md), and [window transform](../transforms/window.md). Unlike the window transform, the **strict** option defaults to true, and the **anchor** option defaults to *end* (which assumes that the data is in chronological order). + +## bollingerX(*data*, *options*) {#bollingerX} + +```js +Plot.bollingerX(aapl, {y: "Date", x: "Close"}) +``` + +Returns a bollinger mark for when time goes up↑ (or down↓). If the **x** option is not specified, it defaults to the identity function, as when *data* is an array of numbers [*x₀*, *x₁*, *x₂*, …]. If the **y** option is not specified, it defaults to [0, 1, 2, …]. + +## bollingerY(*data*, *options*) {#bollingerY} + +```js +Plot.bollingerY(aapl, {x: "Date", y: "Close"}) +``` + +Returns a bollinger mark for when time goes right→ (or ←left). If the **y** option is not specified, it defaults to the identity function, as when *data* is an array of numbers [*y₀*, *y₁*, *y₂*, …]. If the **x** option is not specified, it defaults to [0, 1, 2, …]. + +## bollinger(*options*) {#bollinger} + +```js +Plot.lineY(data, Plot.map({y: Plot.bollinger({n: 20})}, {x: "Date", y: "Close"})) +``` + +Returns a bollinger map method for use with the [map transform](../transforms/map.md). The **k** option here defaults to zero instead of two. diff --git a/docs/marks/box.md b/docs/marks/box.md index 31972b0e67..a4bdfa5970 100644 --- a/docs/marks/box.md +++ b/docs/marks/box.md @@ -13,9 +13,9 @@ onMounted(() => { -# Box mark +# Box mark -The **box mark** summarizes one-dimensional distributions as boxplots. It is a [composite mark](../features/marks.md#marks-marks) consisting of a [rule](./rule.md) to represent the extreme values (not including outliers), a [bar](./bar.md) to represent the interquartile range (trimmed to the data), a [tick](./tick.md) to represent the median value, and a [dot](./dot.md) to represent any outliers. The [group transform](../transforms/group.md) is used to group and aggregate data. +The **box mark** summarizes one-dimensional distributions as boxplots. It is a [composite mark](../features/marks.md#marks) consisting of a [rule](./rule.md) to represent the extreme values (not including outliers), a [bar](./bar.md) to represent the interquartile range (trimmed to the data), a [tick](./tick.md) to represent the median value, and a [dot](./dot.md) to represent any outliers. The [group transform](../transforms/group.md) is used to group and aggregate data. For example, the boxplot below shows [A.A. Michelson’s experimental measurements](https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/morley.html) of the speed of light. (Speed is in km/sec minus 299,000.) @@ -33,7 +33,7 @@ Plot.plot({ ``` ::: -[boxY](#boxy-data-options) produces vertical boxplots; for horizontal boxplots, use [boxX](#boxx-data-options) and swap **x** and **y**. +[boxY](#boxY) produces vertical boxplots; for horizontal boxplots, use [boxX](#boxX) and swap **x** and **y**. :::plot https://observablehq.com/@observablehq/plot-horizontal-box-plot ```js @@ -107,7 +107,7 @@ Plot.plot({ ## Box options -The box mark is a [composite mark](../features/marks.md#marks-marks) consisting of four marks: +The box mark is a [composite mark](../features/marks.md#marks) consisting of four marks: * a [rule](../marks/rule.md) representing the extreme values (not including outliers) * a [bar](../marks/bar.md) representing the interquartile range (trimmed to the data) @@ -122,7 +122,7 @@ The given *options* are passed through to these underlying marks, with the excep * **strokeOpacity** - the stroke opacity of the rule, tick, and dot; defaults to 1 * **strokeWidth** - the stroke width of the tick; defaults to 1 -## boxX(*data*, *options*) +## boxX(*data*, *options*) {#boxX} ```js Plot.boxX(simpsons.map((d) => d.imdb_rating)) @@ -130,7 +130,7 @@ Plot.boxX(simpsons.map((d) => d.imdb_rating)) Returns a horizontal box mark. If the **x** option is not specified, it defaults to the identity function, as when *data* is an array of numbers. If the **y** option is not specified, it defaults to null; if the **y** option is specified, it should represent an ordinal (discrete) value. -## boxY(*data*, *options*) +## boxY(*data*, *options*) {#boxY} ```js Plot.boxY(simpsons.map((d) => d.imdb_rating)) diff --git a/docs/marks/cell.md b/docs/marks/cell.md index 47481ba0b4..8a8d19b0dd 100644 --- a/docs/marks/cell.md +++ b/docs/marks/cell.md @@ -26,7 +26,7 @@ The cell mark is one of several marks in Plot for drawing rectangles; it should The **cell mark** draws rectangles positioned in two ordinal dimensions. Hence, the plot’s *x* and *y* scales are [band scales](../features/scales.md). Cells typically also have a **fill** color encoding. -For example, the heatmap below shows the decline of *The Simpsons* after Season 9: high IMDb ratings are dark green, while low ratings are dark pink. (The worst episode ever—cue Comic Book Guy—is season 23’s [“Lisa Goes Gaga”](https://en.wikipedia.org/wiki/Lisa_Goes_Gaga).) +For example, the heatmap below shows the decline of *The Simpsons* after Season 9: high IMDb ratings are dark green, while low ratings are dark pink. (The worst episode ever — cue Comic Book Guy — is season 23’s [“Lisa Goes Gaga”](https://en.wikipedia.org/wiki/Lisa_Goes_Gaga).) :::plot defer https://observablehq.com/@observablehq/plot-simpsons-ratings ```js @@ -122,7 +122,7 @@ Plot.cell(alphabet, {x: "letter", fill: "frequency"}).plot() ``` ::: -When ordinal data is regular, such as the yearly observations of the warming stripes below, use the **interval** scale option to enforce uniformity and show gaps for missing data. It can be set to a named interval such as *hour* or *day*, a number for numeric intervals, a [d3-time interval](https://github.com/d3/d3-time/blob/main/README.md#api-reference), or a custom implementation. +When ordinal data is regular, such as the yearly observations of the warming stripes below, use the **interval** scale option to enforce uniformity and show gaps for missing data. It can be set to a named interval such as *hour* or *day*, a number for numeric intervals, a [d3-time interval](https://d3js.org/d3-time#_interval), or a custom implementation. :::plot https://observablehq.com/@observablehq/plot-ordinal-scale-interval-2 ```js{5} @@ -158,7 +158,7 @@ If **x** is not specified, the cell will span the full horizontal extent of the The **stroke** defaults to *none*. The **fill** defaults to *currentColor* if the stroke is *none*, and to *none* otherwise. -## cell(*data*, *options*) +## cell(*data*, *options*) {#cell} ```js Plot.cell(simpsons, {x: "number_in_season", y: "season", fill: "imdb_rating"}) @@ -166,18 +166,18 @@ Plot.cell(simpsons, {x: "number_in_season", y: "season", fill: "imdb_rating"}) Returns a new cell with the given *data* and *options*. If neither the **x** nor **y** options are specified, *data* is assumed to be an array of pairs [[*x₀*, *y₀*], [*x₁*, *y₁*], [*x₂*, *y₂*], …] such that **x** = [*x₀*, *x₁*, *x₂*, …] and **y** = [*y₀*, *y₁*, *y₂*, …]. -## cellX(*data*, *options*) +## cellX(*data*, *options*) {#cellX} ```js Plot.cellX(simpsons.map((d) => d.imdb_rating)) ``` -Equivalent to [cell](#cell-data-options), except that if the **x** option is not specified, it defaults to [0, 1, 2, …], and if the **fill** option is not specified and **stroke** is not a channel, the fill defaults to the identity function and assumes that *data* = [*x₀*, *x₁*, *x₂*, …]. +Equivalent to [cell](#cell), except that if the **x** option is not specified, it defaults to [0, 1, 2, …], and if the **fill** option is not specified and **stroke** is not a channel, the fill defaults to the identity function and assumes that *data* = [*x₀*, *x₁*, *x₂*, …]. -## cellY(*data*, *options*) +## cellY(*data*, *options*) {#cellY} ```js Plot.cellY(simpsons.map((d) => d.imdb_rating)) ``` -Equivalent to [cell](#cell-data-options), except that if the **y** option is not specified, it defaults to [0, 1, 2, …], and if the **fill** option is not specified and **stroke** is not a channel, the fill defaults to the identity function and assumes that *data* = [*y₀*, *y₁*, *y₂*, …]. +Equivalent to [cell](#cell), except that if the **y** option is not specified, it defaults to [0, 1, 2, …], and if the **fill** option is not specified and **stroke** is not a channel, the fill defaults to the identity function and assumes that *data* = [*y₀*, *y₁*, *y₂*, …]. diff --git a/docs/marks/contour.md b/docs/marks/contour.md index ec15e50624..234e3ae39e 100644 --- a/docs/marks/contour.md +++ b/docs/marks/contour.md @@ -23,7 +23,7 @@ function mandelbrot(x, y) { -# Contour mark +# Contour mark :::tip To produce a heatmap instead of contours, see the [raster mark](./raster.md). For contours of estimated point density, see the [density mark](./density.md). @@ -271,7 +271,7 @@ As shorthand, a single channel may be specified, in which case it is promoted to Plot.contour(volcano.values, {width: volcano.width, height: volcano.height, fill: Plot.identity}) ``` -## contour(*data*, *options*) +## contour(*data*, *options*) {#contour} ```js Plot.contour(volcano.values, {width: volcano.width, height: volcano.height, fill: Plot.identity}) diff --git a/docs/marks/delaunay.md b/docs/marks/delaunay.md index 8ef48883b0..ff1b4e7c26 100644 --- a/docs/marks/delaunay.md +++ b/docs/marks/delaunay.md @@ -17,11 +17,11 @@ onMounted(() => { -# Delaunay marks +# Delaunay marks Given set of points in **x** and **y**, the **Delaunay marks** compute the [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation), its dual the [Voronoi tessellation](https://en.wikipedia.org/wiki/Voronoi_diagram), and the [convex hull](https://en.wikipedia.org/wiki/Convex_hull). -The [voronoi mark](#voronoi-data-options) computes the region closest to each point (its *Voronoi cell*). The cell can be empty if another point shares the exact same coordinates. Together, the cells cover the entire plot. Voronoi diagrams can group related points with color, for example. +The [voronoi mark](#voronoi) computes the region closest to each point (its *Voronoi cell*). The cell can be empty if another point shares the exact same coordinates. Together, the cells cover the entire plot. Voronoi diagrams can group related points with color, for example. :::plot https://observablehq.com/@observablehq/plot-voronoi-scatterplot ```js @@ -38,7 +38,7 @@ Plot.plot({ Each cell is associated with a particular data point, and channels such as **stroke**, **fill**, **fillOpacity**, **strokeOpacity**, **href**, _etc._, work as they do on other marks, such as [dots](./dot.md). -To show the local density of a scatterplot, one can draw the whole boundary at once with [voronoiMesh](#voronoimesh-data-options). Whereas the [voronoi mark](#voronoi-data-options) will draw shared cell boundaries twice, the mesh will draw them only once. +To show the local density of a scatterplot, one can draw the whole boundary at once with [voronoiMesh](#voronoiMesh). Whereas the [voronoi mark](#voronoi) will draw shared cell boundaries twice, the mesh will draw them only once. :::plot https://observablehq.com/@observablehq/plot-voronoi-mesh ```js @@ -51,7 +51,7 @@ Plot.plot({ ``` ::: -The boundary between two neighboring Voronoi cells is a line segment defined by equal distance from their two respective points. The construction of the Voronoi diagram involves the computation of the Delaunay graph, which defines these neighbors. Use [delaunayMesh](#delaunaymesh-data-options) to draw the graph. +The boundary between two neighboring Voronoi cells is a line segment defined by equal distance from their two respective points. The construction of the Voronoi diagram involves the computation of the Delaunay graph, which defines these neighbors. Use [delaunayMesh](#delaunayMesh) to draw the graph. :::plot https://observablehq.com/@observablehq/plot-delaunay-mesh ```js @@ -66,7 +66,7 @@ Plot.plot({ As shown above, the Delaunay graph is computed separately for each color; specifying **z**, **stroke**, or **fill** creates independent series. -Another derivative of the Delaunay graph is the convex hull of a set of points: the polygon with the minimum perimeter that contains all the points. The [hull mark](#hull-data-options) will draw this hull. +Another derivative of the Delaunay graph is the convex hull of a set of points: the polygon with the minimum perimeter that contains all the points. The [hull mark](#hull) will draw this hull. :::plot defer https://observablehq.com/@observablehq/plot-convex-hull ```js @@ -129,7 +129,7 @@ Distances between projected points are not exactly proportional to the correspon ::: -## delaunayLink(*data*, *options*) +## delaunayLink(*data*, *options*) {#delaunayLink} ```js Plot.delaunayLink(penguins, {x: "culmen_depth_mm", y: "culmen_length_mm"}) @@ -139,7 +139,7 @@ Draws links for each edge of the Delaunay triangulation of the points given by t If a **z** channel is specified, the input points are grouped by *z*, and separate Delaunay triangulations are constructed for each group. -## delaunayMesh(*data*, *options*) +## delaunayMesh(*data*, *options*) {#delaunayMesh} ```js Plot.delaunayMesh(penguins, {x: "culmen_depth_mm", y: "culmen_length_mm"}) @@ -149,7 +149,7 @@ Draws a mesh of the Delaunay triangulation of the points given by the **x** and If a **z** channel is specified, the input points are grouped by *z*, and separate Delaunay triangulations are constructed for each group. -## hull(*data*, *options*) +## hull(*data*, *options*) {#hull} ```js Plot.hull(penguins, {x: "culmen_depth_mm", y: "culmen_length_mm"}) @@ -159,7 +159,7 @@ Draws a convex hull around the points given by the **x** and **y** channels. The If a **z** channel is specified, the input points are grouped by *z*, and separate convex hulls are constructed for each group. If the **z** channel is not specified, it defaults to either the **fill** channel, if any, or the **stroke** channel, if any. -## voronoi(*data*, *options*) +## voronoi(*data*, *options*) {#voronoi} ```js Plot.voronoi(penguins, {x: "culmen_depth_mm", y: "culmen_length_mm"}) @@ -169,7 +169,7 @@ Draws polygons for each cell of the Voronoi tessellation of the points given by If a **z** channel is specified, the input points are grouped by *z*, and separate Voronoi tessellations are constructed for each group. -## voronoiMesh(*data*, *options*) +## voronoiMesh(*data*, *options*) {#voronoiMesh} ```js Plot.voronoiMesh(penguins, {x: "culmen_depth_mm", y: "culmen_length_mm"}) diff --git a/docs/marks/density.md b/docs/marks/density.md index 0358e7832f..45a8b40218 100644 --- a/docs/marks/density.md +++ b/docs/marks/density.md @@ -24,7 +24,7 @@ onMounted(() => { -# Density mark +# Density mark :::tip For contours of spatially-distributed quantitative values, see the [contour mark](./contour.md). @@ -165,7 +165,7 @@ Plot.plot({ ``` ::: - + The **weight** channel specifies the contribution of each data point to the estimated density; it defaults to 1, weighing each point equally. This can be used to give some points more influence than others. Try adjusting the skew slider below to transition between female- and male-weighted density. @@ -245,7 +245,7 @@ The **thresholds** option, which defaults to 20, specifies one more than the num If a **z**, **stroke** or **fill** channel is specified, the input points are grouped by series, and separate sets of contours are generated for each series. If the **stroke** or **fill** is specified as *density*, a color channel is constructed with values representing the density threshold value of each contour. -## density(*data*, *options*) +## density(*data*, *options*) {#density} ```js Plot.density(faithful, {x: "waiting", y: "eruptions"}) diff --git a/docs/marks/dot.md b/docs/marks/dot.md index 10da569beb..f82ddef678 100644 --- a/docs/marks/dot.md +++ b/docs/marks/dot.md @@ -241,7 +241,7 @@ Plot.dotX([ ::: :::info -The stroked symbols are based on [Heman Robinson’s research](https://www.tandfonline.com/doi/abs/10.1080/10618600.2019.1637746). There is also a *hexagon* symbol; it is primarily intended for the [hexbin transform](../transforms/hexbin.md). You can even specify a D3 or custom symbol type as an object that implements the [*symbol*.draw(*context*, *size*)](https://github.com/d3/d3-shape/blob/main/README.md#custom-symbol-types) method. +The stroked symbols are based on [Heman Robinson’s research](https://www.tandfonline.com/doi/abs/10.1080/10618600.2019.1637746). There is also a *hexagon* symbol; it is primarily intended for the [hexbin transform](../transforms/hexbin.md). You can even specify a D3 or custom symbol type as an object that implements the [*symbol*.draw(*context*, *size*)](https://d3js.org/d3-shape/symbol#symbolType_draw) method. ::: The dot mark can be combined with the [stack transform](../transforms/stack.md). The diverging stacked dot plot below shows the age and gender distribution of the U.S. Congress in 2023. @@ -281,7 +281,7 @@ The stackY2 transform places each dot at the upper bound of the associated stack The [dodge transform](../transforms/dodge.md) can also be used to produce beeswarm plots; this is particularly effective when dots have varying radius. ::: -Dots are sorted by descending radius by default to mitigate occlusion; the smallest dots are drawn on top. Set the **sort** option to null to draw them in input order. Use the checkbox below to see the effect of sorting on a bubble map of U.S. county population. +Dots are sorted by descending radius by default to mitigate occlusion; the smallest dots are drawn on top. Set the **sort** option to null to draw them in input order. Use the checkbox below to see the effect of sorting on a bubble map of U.S. county population.

This is a fancy title`, + * marks: … + * }) + * ``` + * + * [1]: https://github.com/observablehq/htl + */ + title?: string | Node | null; + + /** + * The figure subtitle. If present, Plot wraps the generated SVG element in an + * HTML figure element with the subtitle in a h3 element, returning the + * figure. To specify an HTML subtitle, consider using the [`html` tagged + * template literal][1]; otherwise, the specified string represents text that + * will be escaped as needed. + * + * ```js + * Plot.plot({ + * subtitle: html`This is a fancy subtitle`, + * marks: … + * }) + * ``` + * + * [1]: https://github.com/observablehq/htl + */ + subtitle?: string | Node | null; + /** * The figure caption. If present, Plot wraps the generated SVG element in an * HTML figure element with a figcaption, returning the figure. To specify an - * HTML caption, consider using the [`html` tagged template - * literal](http://github.com/observablehq/htl); otherwise, the specified - * string represents text that will be escaped as needed. + * HTML caption, consider using the [`html` tagged template literal][1]; + * otherwise, the specified string represents text that will be escaped as + * needed. * * ```js * Plot.plot({ @@ -120,32 +156,45 @@ export interface PlotOptions extends ScaleDefaults { * marks: … * }) * ``` + * + * [1]: https://github.com/observablehq/htl */ caption?: string | Node | null; /** - * The [aria-label - * attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label) - * on the SVG root. + * Whether to wrap the generated SVG element with an HTML figure element. By + * default, this is determined by the presence of non-chart elements such as + * legends, title, subtitle, and caption; if false, these non-chart element + * options are ignored. + */ + figure?: boolean; + + /** + * The [aria-label attribute][1] on the SVG root. + * + * [1]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label */ ariaLabel?: string | null; /** - * The [aria-description - * attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-description) - * on the SVG root. + * The [aria-description attribute][1] on the SVG root. + * + * [1]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-description */ ariaDescription?: string | null; /** - * The owner - * [Document](https://developer.mozilla.org/en-US/docs/Web/API/Document) used - * to create DOM elements. Defaults to window.document, but can be changed to - * another document, say when using a virtual DOM library for server-side - * rendering in Node. + * The owner [Document][1] used to create DOM elements. Defaults to + * window.document, but can be changed to another document, say when using a + * virtual DOM library for server-side rendering in Node. + * + * [1]: https://developer.mozilla.org/en-US/docs/Web/API/Document */ document?: Document; + /** The default clip for all marks. */ + clip?: MarkOptions["clip"]; + // scale, axis, and legend definitions /** @@ -181,10 +230,11 @@ export interface PlotOptions extends ScaleDefaults { * first quartile of values has a radius of 3 pixels, but no value has a * radius greater than 30 pixels. * - * Plot does not currently implement a radius legend; see - * [#236](https://github.com/observablehq/plot/issues/236). We recommend - * either implementing one manually or labeling points so that values can be - * read directly from the plot. + * Plot does not currently implement a radius legend; see [#236][1]. We + * recommend either implementing one manually or labeling points so that + * values can be read directly from the plot. + * + * [1]: https://github.com/observablehq/plot/issues/236 */ r?: ScaleOptions; diff --git a/src/plot.js b/src/plot.js index 6862ebf42d..11d83282f9 100644 --- a/src/plot.js +++ b/src/plot.js @@ -9,17 +9,18 @@ import {Mark} from "./mark.js"; import {axisFx, axisFy, axisX, axisY, gridFx, gridFy, gridX, gridY} from "./marks/axis.js"; import {frame} from "./marks/frame.js"; import {tip} from "./marks/tip.js"; -import {arrayify, isColor, isIterable, isNone, isScaleOptions, map, yes, maybeIntervalTransform} from "./options.js"; +import {isColor, isIterable, isNone, isScaleOptions} from "./options.js"; +import {arrayify, map, yes, maybeIntervalTransform, subarray} from "./options.js"; import {createProjection, getGeometryChannels, hasProjection} from "./projection.js"; import {createScales, createScaleFunctions, autoScaleRange, exposeScales} from "./scales.js"; import {innerDimensions, outerDimensions} from "./scales.js"; -import {position, registry as scaleRegistry} from "./scales/index.js"; +import {isPosition, registry as scaleRegistry} from "./scales/index.js"; import {applyInlineStyles, maybeClassName} from "./style.js"; import {initializer} from "./transforms/basic.js"; import {consumeWarnings, warn} from "./warnings.js"; export function plot(options = {}) { - const {facet, style, caption, ariaLabel, ariaDescription} = options; + const {facet, style, title, subtitle, caption, ariaLabel, ariaDescription} = options; // className for inline styles const className = maybeClassName(options.className); @@ -140,11 +141,11 @@ export function plot(options = {}) { // Initalize the scales and dimensions. const scaleDescriptors = createScales(addScaleChannels(channelsByScale, stateByMark, options), options); - const scales = createScaleFunctions(scaleDescriptors); const dimensions = createDimensions(scaleDescriptors, marks, options); autoScaleRange(scaleDescriptors, dimensions); + const scales = createScaleFunctions(scaleDescriptors); const {fx, fy} = scales; const subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions; const superdimensions = fx || fy ? actualDimensions(scales, dimensions) : dimensions; @@ -200,7 +201,7 @@ export function plot(options = {}) { // channels as-is rather than creating new scales, and assume that // they already have the scale’s transform applied, if any (e.g., when // generating ticks for the axis mark). - if (scale != null && scaleRegistry.get(scale) !== position) { + if (scale != null && !isPosition(scaleRegistry.get(scale))) { applyScaleTransform(channel, options); newByScale.add(scale); } @@ -220,9 +221,10 @@ export function plot(options = {}) { addScaleChannels(newChannelsByScale, stateByMark, options, (key) => newByScale.has(key)); addScaleChannels(channelsByScale, stateByMark, options, (key) => newByScale.has(key)); const newScaleDescriptors = inheritScaleLabels(createScales(newChannelsByScale, options), scaleDescriptors); - const newScales = createScaleFunctions(newScaleDescriptors); + const {scales: newExposedScales, ...newScales} = createScaleFunctions(newScaleDescriptors); Object.assign(scaleDescriptors, newScaleDescriptors); Object.assign(scales, newScales); + Object.assign(scales.scales, newExposedScales); } // Sort and filter the facets to match the fx and fy domains; this is needed @@ -298,7 +300,8 @@ export function plot(options = {}) { index = indexes[faceted ? f.i : 0]; index = mark.filter(index, channels, values); if (index.length === 0) continue; - if (faceted) (index.fx = f.x), (index.fy = f.y), (index.fi = f.i); + if (!faceted && index === indexes[0]) index = subarray(index); // copy before assigning fx, fy, fi + (index.fx = f.x), (index.fy = f.y), (index.fi = f.i); } const node = mark.render(index, scales, values, subdimensions, context); if (node == null) continue; @@ -318,21 +321,20 @@ export function plot(options = {}) { } } - // Wrap the plot in a figure with a caption, if desired. + // Wrap the plot in a figure, if needed. const legends = createLegends(scaleDescriptors, context, options); - if (caption != null || legends.length > 0) { + const {figure: figured = title != null || subtitle != null || caption != null || legends.length > 0} = options; + if (figured) { figure = document.createElement("figure"); - figure.style.maxWidth = "initial"; - for (const legend of legends) figure.appendChild(legend); - figure.appendChild(svg); - if (caption != null) { - const figcaption = document.createElement("figcaption"); - figcaption.appendChild(caption?.ownerDocument ? caption : document.createTextNode(caption)); - figure.appendChild(figcaption); - } + figure.className = `${className}-figure`; + figure.style.maxWidth = "initial"; // avoid Observable default style + if (title != null) figure.append(createTitleElement(document, title, "h2")); + if (subtitle != null) figure.append(createTitleElement(document, subtitle, "h3")); + figure.append(...legends, svg); + if (caption != null) figure.append(createFigcaption(document, caption)); } - figure.scale = exposeScales(scaleDescriptors); + figure.scale = exposeScales(scales.scales); figure.legend = exposeLegends(scaleDescriptors, context, options); const w = consumeWarnings(); @@ -352,6 +354,19 @@ export function plot(options = {}) { return figure; } +function createTitleElement(document, contents, tag) { + if (contents.ownerDocument) return contents; + const e = document.createElement(tag); + e.append(contents); + return e; +} + +function createFigcaption(document, caption) { + const e = document.createElement("figcaption"); + e.append(caption); + return e; +} + function plotThis({marks = [], ...options} = {}) { return plot({...options, marks: [...marks, this]}); } diff --git a/src/projection.d.ts b/src/projection.d.ts index 82bd130c8e..8856c28c6b 100644 --- a/src/projection.d.ts +++ b/src/projection.d.ts @@ -85,14 +85,14 @@ export interface ProjectionOptions extends InsetOptions { /** * The [standard parallels][1]. For conic projections only. * - * [1]: https://github.com/d3/d3-geo/blob/main/README.md#conic_parallels + * [1]: https://d3js.org/d3-geo/conic#conic_parallels */ parallels?: [y1: number, y2: number]; /** * The projection’s [sampling threshold][1]. * - * [1]: https://github.com/d3/d3-geo/blob/main/README.md#projection_precision + * [1]: https://d3js.org/d3-geo/projection#projection_precision */ precision?: number; diff --git a/src/scales.d.ts b/src/scales.d.ts index de20207526..3d548745f1 100644 --- a/src/scales.d.ts +++ b/src/scales.d.ts @@ -161,9 +161,9 @@ export type ScaleName = "x" | "y" | "fx" | "fy" | "r" | "color" | "opacity" | "s /** * The instantiated scales’ apply functions; passed to marks and initializers - * for rendering. + * for rendering. The scales property exposes all the scale definitions. */ -export type ScaleFunctions = {[key in ScaleName]?: (value: any) => any}; +export type ScaleFunctions = {[key in ScaleName]?: (value: any) => any} & {scales: {[key in ScaleName]?: Scale}}; /** * The supported scale types. For quantitative data, one of: @@ -579,9 +579,12 @@ export interface ScaleOptions extends ScaleDefaults { /** * How to format inputs (abstract values) for axis tick labels; one of: * - * - a [d3-format](https://github.com/d3/d3-format) string for numeric scales - * - a [d3-time-format](https://github.com/d3/d3-time-format) string for temporal scales + * - a [d3-format][1] string for numeric scales + * - a [d3-time-format][2] string for temporal scales * - a function passed a tick *value* and *index*, returning a string + * + * [1]: https://d3js.org/d3-time + * [2]: https://d3js.org/d3-time-format */ tickFormat?: string | ((t: any, i: number) => any) | null; diff --git a/src/scales.js b/src/scales.js index 5b993c18e7..5bc4865f04 100644 --- a/src/scales.js +++ b/src/scales.js @@ -97,17 +97,19 @@ export function createScales( return scales; } -export function createScaleFunctions(scales) { - return Object.fromEntries( - Object.entries(scales) - .filter(([, {scale}]) => scale) // drop identity scales - .map(([name, {scale, type, interval, label}]) => { - scale.type = type; // for axis - if (interval != null) scale.interval = interval; // for axis - if (label != null) scale.label = label; // for axis - return [name, scale]; - }) - ); +export function createScaleFunctions(descriptors) { + const scales = {}; + const scaleFunctions = {scales}; + for (const [key, descriptor] of Object.entries(descriptors)) { + const {scale, type, interval, label} = descriptor; + scales[key] = exposeScale(descriptor); + scaleFunctions[key] = scale; + // TODO: pass these properties, which are needed for axes, in the descriptor. + scale.type = type; + if (interval != null) scale.interval = interval; + if (label != null) scale.label = label; + } + return scaleFunctions; } // Mutates scale.range! @@ -362,7 +364,7 @@ function createScale(key, channels = [], options = {}) { case "band": return createScaleBand(key, channels, options); case "identity": - return registry.get(key) === position ? createScaleIdentity() : {type: "identity"}; + return createScaleIdentity(key); case undefined: return; default: @@ -513,10 +515,10 @@ export function scale(options = {}) { return scale; } -export function exposeScales(scaleDescriptors) { +export function exposeScales(scales) { return (key) => { if (!registry.has((key = `${key}`))) throw new Error(`unknown scale: ${key}`); - return key in scaleDescriptors ? exposeScale(scaleDescriptors[key]) : undefined; + return scales[key]; }; } diff --git a/src/scales/index.js b/src/scales/index.js index a152db0ef8..ee2f2b2688 100644 --- a/src/scales/index.js +++ b/src/scales/index.js @@ -23,6 +23,7 @@ export const opacity = Symbol("opacity"); export const symbol = Symbol("symbol"); // There isn’t really a projection scale; this represents x and y for geometry. +// This is used to denote channels that should be projected. export const projection = Symbol("projection"); // TODO Rather than hard-coding the list of known scale names, collect the names @@ -40,3 +41,11 @@ export const registry = new Map([ ["length", length], ["projection", projection] ]); + +export function isPosition(kind) { + return kind === position || kind === projection; +} + +export function hasNumericRange(kind) { + return kind === position || kind === radius || kind === length || kind === opacity; +} diff --git a/src/scales/ordinal.js b/src/scales/ordinal.js index 2e7dd0c0de..caf18a4e13 100644 --- a/src/scales/ordinal.js +++ b/src/scales/ordinal.js @@ -17,7 +17,7 @@ function createScaleO(key, scale, channels, {type, interval, domain, range, reve if (domain === undefined) domain = inferDomain(channels, interval, key); if (type === "categorical" || type === ordinalImplicit) type = "ordinal"; // shorthand for color schemes if (reverse) domain = reverseof(domain); - scale.domain(domain); + domain = scale.domain(domain).domain(); // deduplicate if (range !== undefined) { // If the range is specified as a function, pass it the domain. if (typeof range === "function") range = range(domain); diff --git a/src/scales/quantitative.js b/src/scales/quantitative.js index dbbc4a6d75..0625ffcf01 100644 --- a/src/scales/quantitative.js +++ b/src/scales/quantitative.js @@ -10,6 +10,7 @@ import { max, median, min, + piecewise, quantile, quantize, reverse as reverseof, @@ -24,8 +25,7 @@ import { } from "d3"; import {finite, negative, positive} from "../defined.js"; import {arrayify, constant, maybeNiceInterval, maybeRangeInterval, orderof, slice} from "../options.js"; -import {warn} from "../warnings.js"; -import {color, length, opacity, radius, registry} from "./index.js"; +import {color, length, opacity, radius, registry, hasNumericRange} from "./index.js"; import {ordinalRange, quantitativeScheme} from "./schemes.js"; export const flip = (i) => (t) => i(1 - t); @@ -81,30 +81,24 @@ export function createScaleQ( ) { interval = maybeRangeInterval(interval, type); if (type === "cyclical" || type === "sequential") type = "linear"; // shorthand for color schemes + if (typeof interpolate !== "function") interpolate = maybeInterpolator(interpolate); // named interpolator reverse = !!reverse; - // If an explicit range is specified, ensure that the domain and range have - // the same length; truncate to whichever one is shorter. + // If an explicit range is specified, and it has a different length than the + // domain, then redistribute the range using a piecewise interpolator. if (range !== undefined) { const n = (domain = arrayify(domain)).length; const m = (range = arrayify(range)).length; - if (n > m) { - domain = domain.slice(0, m); - warn(`Warning: the ${key} scale domain contains extra elements.`); - } else if (m > n) { - range = range.slice(0, n); - warn(`Warning: the ${key} scale range contains extra elements.`); + if (n !== m) { + if (interpolate.length === 1) throw new Error("invalid piecewise interpolator"); // e.g., turbo + interpolate = piecewise(interpolate, range); + range = undefined; } } - // Sometimes interpolate is a named interpolator, such as "lab" for Lab color - // space. Other times interpolate is a function that takes two arguments and - // is used in conjunction with the range. And other times the interpolate - // function is a “fixed” interpolator on the [0, 1] interval, as when a - // color scheme such as interpolateRdBu is used. - if (typeof interpolate !== "function") { - interpolate = maybeInterpolator(interpolate); - } + // Disambiguate between a two-argument interpolator that is used in + // conjunction with the range, and a one-argument “fixed” interpolator on the + // [0, 1] interval as with the RdBu color scheme. if (interpolate.length === 1) { if (reverse) { interpolate = flip(interpolate); @@ -263,8 +257,12 @@ function isOrdered(domain, sign) { return true; } -export function createScaleIdentity() { - return {type: "identity", scale: scaleIdentity()}; +// For non-numeric identity scales such as color and symbol, we can’t use D3’s +// identity scale because it coerces to number; and we can’t compute the domain +// (and equivalently range) since we can’t know whether the values are +// continuous or discrete. +export function createScaleIdentity(key) { + return {type: "identity", scale: hasNumericRange(registry.get(key)) ? scaleIdentity() : (d) => d}; } export function inferDomain(channels, f = finite) { diff --git a/src/style.js b/src/style.js index 8a1723c1eb..8480173152 100644 --- a/src/style.js +++ b/src/style.js @@ -2,17 +2,8 @@ import {geoPath, group, namespaces} from "d3"; import {create} from "./context.js"; import {defined, nonempty} from "./defined.js"; import {formatDefault} from "./format.js"; -import { - string, - number, - maybeColorChannel, - maybeNumberChannel, - maybeKeyword, - isNoneish, - isNone, - isRound, - keyof -} from "./options.js"; +import {isNone, isNoneish, isRound, maybeColorChannel, maybeNumberChannel} from "./options.js"; +import {keyof, keyword, number, string} from "./options.js"; import {warn} from "./warnings.js"; export const offset = (typeof window !== "undefined" ? window.devicePixelRatio > 1 : typeof it === "undefined") ? 0 : 0.5; // prettier-ignore @@ -143,9 +134,9 @@ export function styles( mark.shapeRendering = impliedString(shapeRendering, "auto"); return { - title: {value: title, optional: true}, - href: {value: href, optional: true}, - ariaLabel: {value: variaLabel, optional: true}, + title: {value: title, optional: true, filter: null}, + href: {value: href, optional: true, filter: null}, + ariaLabel: {value: variaLabel, optional: true, filter: null}, fill: {value: vfill, scale: "auto", optional: true}, fillOpacity: {value: vfillOpacity, scale: "auto", optional: true}, stroke: {value: vstroke, scale: "auto", optional: true}, @@ -311,14 +302,16 @@ export function* groupIndex(I, position, mark, channels) { export function maybeClip(clip) { if (clip === true) clip = "frame"; else if (clip === false) clip = null; - return maybeKeyword(clip, "clip", ["frame", "sphere"]); + else if (clip != null) clip = keyword(clip, "clip", ["frame", "sphere"]); + return clip; } // TODO avoid creating a new clip-path each time? // Note: may mutate selection.node! function applyClip(selection, mark, dimensions, context) { let clipUrl; - switch (mark.clip) { + const {clip = context.clip} = mark; + switch (clip) { case "frame": { const {width, height, marginLeft, marginRight, marginTop, marginBottom} = dimensions; const id = getClipId(); @@ -378,7 +371,8 @@ export function applyIndirectStyles(selection, mark, dimensions, context) { applyAttr(selection, "shape-rendering", mark.shapeRendering); applyAttr(selection, "filter", mark.imageFilter); applyAttr(selection, "paint-order", mark.paintOrder); - applyAttr(selection, "pointer-events", mark.pointerEvents); + const {pointerEvents = context.pointerSticky === false ? "none" : undefined} = mark; + applyAttr(selection, "pointer-events", pointerEvents); } export function applyDirectStyles(selection, mark) { diff --git a/src/time.js b/src/time.js index fb1cd0d4dc..661a928184 100644 --- a/src/time.js +++ b/src/time.js @@ -1,7 +1,34 @@ +import {bisector, extent, median, pairs, timeFormat, utcFormat} from "d3"; import {utcSecond, utcMinute, utcHour, unixDay, utcWeek, utcMonth, utcYear} from "d3"; import {utcMonday, utcTuesday, utcWednesday, utcThursday, utcFriday, utcSaturday, utcSunday} from "d3"; import {timeSecond, timeMinute, timeHour, timeDay, timeWeek, timeMonth, timeYear} from "d3"; import {timeMonday, timeTuesday, timeWednesday, timeThursday, timeFriday, timeSaturday, timeSunday} from "d3"; +import {orderof} from "./options.js"; + +const durationSecond = 1000; +const durationMinute = durationSecond * 60; +const durationHour = durationMinute * 60; +const durationDay = durationHour * 24; +const durationWeek = durationDay * 7; +const durationMonth = durationDay * 30; +const durationYear = durationDay * 365; + +// See https://github.com/d3/d3-time/blob/9e8dc940f38f78d7588aad68a54a25b1f0c2d97b/src/ticks.js#L14-L33 +const formats = [ + ["millisecond", 0.5 * durationSecond], + ["second", durationSecond], + ["second", 30 * durationSecond], + ["minute", durationMinute], + ["minute", 30 * durationMinute], + ["hour", durationHour], + ["hour", 12 * durationHour], + ["day", durationDay], + ["day", 2 * durationDay], + ["week", durationWeek], + ["month", durationMonth], + ["month", 3 * durationMonth], + ["year", durationYear] +]; const timeIntervals = new Map([ ["second", timeSecond], @@ -82,3 +109,55 @@ export function isTimeYear(i) { const date = i.floor(new Date(2000, 11, 31)); return timeYear(date) >= date; // coercing equality } + +export function formatTimeTicks(scale, data, ticks, anchor) { + const format = scale.type === "time" ? timeFormat : utcFormat; + const template = + anchor === "left" || anchor === "right" + ? (f1, f2) => `\n${f1}\n${f2}` // extra newline to keep f1 centered + : anchor === "top" + ? (f1, f2) => `${f2}\n${f1}` + : (f1, f2) => `${f1}\n${f2}`; + switch (getTimeTicksInterval(scale, data, ticks)) { + case "millisecond": + return formatConditional(format(".%L"), format(":%M:%S"), template); + case "second": + return formatConditional(format(":%S"), format("%-I:%M"), template); + case "minute": + return formatConditional(format("%-I:%M"), format("%p"), template); + case "hour": + return formatConditional(format("%-I %p"), format("%b %-d"), template); + case "day": + return formatConditional(format("%-d"), format("%b"), template); + case "week": + return formatConditional(format("%-d"), format("%b"), template); + case "month": + return formatConditional(format("%b"), format("%Y"), template); + case "year": + return format("%Y"); + } + throw new Error("unable to format time ticks"); +} + +// Compute the median difference between adjacent ticks, ignoring repeated +// ticks; this implies an effective time interval, assuming that ticks are +// regularly spaced; choose the largest format less than this interval so that +// the ticks show the field that is changing. If the ticks are not available, +// fallback to an approximation based on the desired number of ticks. +function getTimeTicksInterval(scale, data, ticks) { + const medianStep = median(pairs(data, (a, b) => Math.abs(b - a) || NaN)); + if (medianStep > 0) return formats[bisector(([, step]) => step).right(formats, medianStep, 1, formats.length) - 1][0]; + const [start, stop] = extent(scale.domain()); + const count = typeof ticks === "number" ? ticks : 10; + const step = Math.abs(stop - start) / count; + return formats[bisector(([, step]) => Math.log(step)).center(formats, Math.log(step))][0]; +} + +function formatConditional(format1, format2, template) { + return (x, i, X) => { + const f1 = format1(x, i); // always shown + const f2 = format2(x, i); // only shown if different + const j = i - orderof(X); // detect reversed domains + return i !== j && X[j] !== undefined && f2 === format2(X[j], j) ? f1 : template(f1, f2); + }; +} diff --git a/src/transforms/bin.d.ts b/src/transforms/bin.d.ts index 6f5e5552cc..61edab725f 100644 --- a/src/transforms/bin.d.ts +++ b/src/transforms/bin.d.ts @@ -42,8 +42,8 @@ export type ThresholdsFunction = (values: T[], min: T, max: T) => Range * built-in thresholds implementations, [d3.ticks][1] is used for numeric * domains and [d3.utcTicks][2] is used for temporal domains. * - * [1]: https://github.com/d3/d3-array/blob/main/README.md#ticks - * [2]: https://github.com/d3/d3-time/blob/main/README.md#utcTicks + * [1]: https://d3js.org/d3-array/ticks + * [2]: https://d3js.org/d3-time#utcTicks */ export type Thresholds = ThresholdsName | ThresholdsFunction | RangeInterval | T[] | number; diff --git a/src/transforms/centroid.js b/src/transforms/centroid.js index 6be53a1fc0..b832775164 100644 --- a/src/transforms/centroid.js +++ b/src/transforms/centroid.js @@ -11,7 +11,14 @@ export function centroid({geometry = identity, ...options} = {}) { const Y = new Float64Array(n); const path = geoPath(projection); for (let i = 0; i < n; ++i) [X[i], Y[i]] = path.centroid(G[i]); - return {data, facets, channels: {x: {value: X, source: null}, y: {value: Y, source: null}}}; + return { + data, + facets, + channels: { + x: {value: X, scale: projection == null ? "x" : null, source: null}, + y: {value: Y, scale: projection == null ? "y" : null, source: null} + } + }; }); } diff --git a/src/transforms/stack.d.ts b/src/transforms/stack.d.ts index 5d6ba75a47..528fe5007f 100644 --- a/src/transforms/stack.d.ts +++ b/src/transforms/stack.d.ts @@ -14,7 +14,7 @@ import type {CompareFunction, Transformed} from "./basic.js"; * *wiggle* offset is recommended for streamgraphs in conjunction with the * *inside-out* order. For more, see [Byron & Wattenberg][1]. * - * [1]: http://leebyron.com/streamgraph/ + * [1]: https://leebyron.com/streamgraph/ */ export type StackOffsetName = | "center" @@ -53,7 +53,7 @@ export type StackOffset = StackOffsetName | StackOffsetFunction; * The *inside-out* order is recommended for streamgraphs in conjunction with * the *wiggle* offset. For more, see [Byron & Wattenberg][1]. * - * [1]: http://leebyron.com/streamgraph/ + * [1]: https://leebyron.com/streamgraph/ */ export type StackOrderName = "value" | "x" | "y" | "z" | "sum" | "appearance" | "inside-out"; diff --git a/src/transforms/stack.js b/src/transforms/stack.js index 7c92fc0d82..25d676fe2f 100644 --- a/src/transforms/stack.js +++ b/src/transforms/stack.js @@ -75,6 +75,7 @@ function mergeOptions(options) { const lengthy = {length: true}; function stack(x, y = one, kx, ky, {offset, order, reverse}, options) { + if (y === null) throw new Error(`stack requires ${ky}`); const z = maybeZ(options); const [X, setX] = maybeColumn(x); const [Y1, setY1] = column(y); diff --git a/src/transforms/tree.d.ts b/src/transforms/tree.d.ts index 3b704fd074..3e8814dd77 100644 --- a/src/transforms/tree.d.ts +++ b/src/transforms/tree.d.ts @@ -32,8 +32,8 @@ export interface TreeTransformOptions { * Reingold–Tilford “tidy” algorithm. Use [d3.cluster][2] instead to align * leaf nodes; see also Plot.cluster. * - * [1]: https://github.com/d3/d3-hierarchy/blob/main/README.md#tree - * [2]: https://github.com/d3/d3-hierarchy/blob/main/README.md#cluster + * [1]: https://d3js.org/d3-hierarchy/tree + * [2]: https://d3js.org/d3-hierarchy/cluster */ treeLayout?: () => any; @@ -44,7 +44,7 @@ export interface TreeTransformOptions { * in the hierarchy and returns the desired (relative) amount of separation; * see [d3-hierarchy’s _tree_.separation][1] for more. * - * [1]: https://github.com/d3/d3-hierarchy/blob/main/README.md#tree_separation + * [1]: https://d3js.org/d3-hierarchy/tree#tree_separation */ treeSeparation?: CompareFunction | null; @@ -58,7 +58,7 @@ export interface TreeTransformOptions { * node value such as *node:name*. * * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort - * [2]: https://github.com/d3/d3-hierarchy/blob/main/README.md#node_sort + * [2]: https://d3js.org/d3-hierarchy/hierarchy#node_sort */ treeSort?: CompareFunction | {node: (node: any) => any} | string | null; } @@ -75,6 +75,7 @@ export interface TreeTransformOptions { * * *node:name* - the node’s name (the last part of its path) * * *node:path* - the node’s full, normalized, slash-separated path * * *node:internal* - true if the node is internal, or false for leaves + * * *node:external* - true if the node is a leaf, or false for internal nodes * * *node:depth* - the distance from the node to the root * * *node:height* - the distance from the node to its deepest descendant * @@ -97,6 +98,7 @@ export function treeNode(options?: T & TreeTransformOptions): Transformed; * * *node:name* - the child node’s name (the last part of its path) * * *node:path* - the child node’s full, normalized, slash-separated path * * *node:internal* - true if the child node is internal, or false for leaves + * * *node:external* - true if the child node is a leaf, or false for external nodes * * *node:depth* - the distance from the child node to the root * * *node:height* - the distance from the child node to its deepest descendant * * *parent:name* - the parent node’s name (the last part of its path) diff --git a/src/transforms/tree.js b/src/transforms/tree.js index 9ff9871ba1..44d42cf474 100644 --- a/src/transforms/tree.js +++ b/src/transforms/tree.js @@ -11,10 +11,12 @@ export function treeNode({ treeSort, treeSeparation, treeAnchor, + treeFilter, ...options } = {}) { treeAnchor = maybeTreeAnchor(treeAnchor); treeSort = maybeTreeSort(treeSort); + if (treeFilter != null) treeFilter = maybeNodeValue(treeFilter); if (frameAnchor === undefined) frameAnchor = treeAnchor.frameAnchor; const normalize = normalizer(delimiter); const outputs = treeOutputs(options, maybeNodeValue); @@ -42,6 +44,7 @@ export function treeNode({ if (treeSort != null) root.sort(treeSort); layout(root); for (const node of root.descendants()) { + if (treeFilter != null && !treeFilter(node)) continue; treeFacet.push(++treeIndex); treeData[treeIndex] = node.data; treeAnchor.position(node, treeIndex, X, Y); @@ -66,10 +69,12 @@ export function treeLink({ treeSort, treeSeparation, treeAnchor, + treeFilter, ...options } = {}) { treeAnchor = maybeTreeAnchor(treeAnchor); treeSort = maybeTreeSort(treeSort); + if (treeFilter != null) treeFilter = maybeLinkValue(treeFilter); options = {curve, stroke, strokeWidth, strokeOpacity, ...options}; const normalize = normalizer(delimiter); const outputs = treeOutputs(options, maybeLinkValue); @@ -102,6 +107,7 @@ export function treeLink({ if (treeSort != null) root.sort(treeSort); layout(root); for (const {source, target} of root.links()) { + if (treeFilter != null && !treeFilter(target, source)) continue; treeFacet.push(++treeIndex); treeData[treeIndex] = target.data; treeAnchor.position(source, treeIndex, X1, Y1); @@ -194,6 +200,8 @@ function maybeNodeValue(value) { return nodePath; case "node:internal": return nodeInternal; + case "node:external": + return nodeExternal; case "node:depth": return nodeDepth; case "node:height": @@ -222,6 +230,8 @@ function maybeLinkValue(value) { return nodePath; case "node:internal": return nodeInternal; + case "node:external": + return nodeExternal; case "node:depth": return nodeDepth; case "node:height": @@ -250,6 +260,10 @@ function nodeInternal(node) { return !!node.children; } +function nodeExternal(node) { + return !node.children; +} + function parentValue(evaluate) { return (child, parent) => (parent == null ? undefined : evaluate(parent)); } diff --git a/src/transforms/window.d.ts b/src/transforms/window.d.ts index bdce4be443..36c959a089 100644 --- a/src/transforms/window.d.ts +++ b/src/transforms/window.d.ts @@ -15,9 +15,11 @@ import type {Map} from "./map.js"; * - *max* - the maximum value * - *mean* - the mean (average) value * - *median* - the median value - * - *variance* - the variance per [Welford’s algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm) + * - *variance* - the variance per [Welford’s algorithm][1] * - *mode* - the mode (most common occurrence) * - *pXX* - the percentile value, where XX is a number in [00,99] + * + * [1]: https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm */ export type WindowReducerName = | "difference" // specific to window diff --git a/src/transforms/window.js b/src/transforms/window.js index be733dd8bc..a9a918927a 100644 --- a/src/transforms/window.js +++ b/src/transforms/window.js @@ -1,6 +1,6 @@ -import {deviation, max, min, median, mode, variance} from "d3"; +import {deviation, max, median, min, mode, variance} from "d3"; import {defined} from "../defined.js"; -import {percentile, taker} from "../options.js"; +import {percentile, subarray, taker} from "../options.js"; import {warn} from "../warnings.js"; import {mapX, mapY} from "./map.js"; @@ -83,10 +83,6 @@ function maybeReduce(reduce = "mean") { return reduceArray(taker(reduce)); } -function slice(I, i, j) { - return I.subarray ? I.subarray(i, j) : I.slice(i, j); -} - // Note that the subarray may include NaN in the non-strict case; we expect the // function f to handle that itself (e.g., by filtering as needed). The D3 // reducers (e.g., min, max, mean, median) do, and it’s faster to avoid @@ -96,24 +92,24 @@ function reduceAccessor(f) { strict ? { mapIndex(I, S, T) { - const s = (i) => (S[i] == null ? NaN : +S[i]); + const v = (i) => (S[i] == null ? NaN : +S[i]); let nans = 0; - for (let i = 0; i < k - 1; ++i) if (isNaN(s(i))) ++nans; + for (let i = 0; i < k - 1; ++i) if (isNaN(v(i))) ++nans; for (let i = 0, n = I.length - k + 1; i < n; ++i) { - if (isNaN(s(i + k - 1))) ++nans; - T[I[i + s]] = nans === 0 ? f(slice(I, i, i + k), s) : NaN; - if (isNaN(s(i))) --nans; + if (isNaN(v(i + k - 1))) ++nans; + T[I[i + s]] = nans === 0 ? f(subarray(I, i, i + k), v) : NaN; + if (isNaN(v(i))) --nans; } } } : { mapIndex(I, S, T) { - const s = (i) => (S[i] == null ? NaN : +S[i]); + const v = (i) => (S[i] == null ? NaN : +S[i]); for (let i = -s; i < 0; ++i) { - T[I[i + s]] = f(slice(I, 0, i + k), s); + T[I[i + s]] = f(subarray(I, 0, i + k), v); } for (let i = 0, n = I.length - s; i < n; ++i) { - T[I[i + s]] = f(slice(I, i, i + k), s); + T[I[i + s]] = f(subarray(I, i, i + k), v); } } }; @@ -128,7 +124,7 @@ function reduceArray(f) { for (let i = 0; i < k - 1; ++i) count += defined(S[I[i]]); for (let i = 0, n = I.length - k + 1; i < n; ++i) { count += defined(S[I[i + k - 1]]); - if (count === k) T[I[i + s]] = f(slice(I, i, i + k), S); + if (count === k) T[I[i + s]] = f(subarray(I, i, i + k), S); count -= defined(S[I[i]]); } } @@ -136,10 +132,10 @@ function reduceArray(f) { : { mapIndex(I, S, T) { for (let i = -s; i < 0; ++i) { - T[I[i + s]] = f(slice(I, 0, i + k), S); + T[I[i + s]] = f(subarray(I, 0, i + k), S); } for (let i = 0, n = I.length - s; i < n; ++i) { - T[I[i + s]] = f(slice(I, i, i + k), S); + T[I[i + s]] = f(subarray(I, i, i + k), S); } } }; diff --git a/test/data/README.md b/test/data/README.md index 2fa8480ed8..23c68ca50f 100644 --- a/test/data/README.md +++ b/test/data/README.md @@ -115,6 +115,10 @@ https://observablehq.com/@tophtucker/examples-of-bitemporal-charts The New York Times https://www.nytimes.com/2019/12/02/upshot/wealth-poverty-divide-american-cities.html +## miserables.json +Character interactions in the chapters of “Les Miserables”, Donald Knuth, Stanford Graph Base +https://www-cs-faculty.stanford.edu/~knuth/sgb.html + ## mtcars.csv 1974 *Motor Trend* US magazine https://www.rdocumentation.org/packages/datasets/versions/3.6.2/topics/mtcars diff --git a/test/data/miserables.json b/test/data/miserables.json new file mode 100644 index 0000000000..7db92850f8 --- /dev/null +++ b/test/data/miserables.json @@ -0,0 +1,337 @@ +{ + "nodes": [ + {"id": "Myriel", "group": 1}, + {"id": "Napoleon", "group": 1}, + {"id": "Mlle.Baptistine", "group": 1}, + {"id": "Mme.Magloire", "group": 1}, + {"id": "CountessdeLo", "group": 1}, + {"id": "Geborand", "group": 1}, + {"id": "Champtercier", "group": 1}, + {"id": "Cravatte", "group": 1}, + {"id": "Count", "group": 1}, + {"id": "OldMan", "group": 1}, + {"id": "Labarre", "group": 2}, + {"id": "Valjean", "group": 2}, + {"id": "Marguerite", "group": 3}, + {"id": "Mme.deR", "group": 2}, + {"id": "Isabeau", "group": 2}, + {"id": "Gervais", "group": 2}, + {"id": "Tholomyes", "group": 3}, + {"id": "Listolier", "group": 3}, + {"id": "Fameuil", "group": 3}, + {"id": "Blacheville", "group": 3}, + {"id": "Favourite", "group": 3}, + {"id": "Dahlia", "group": 3}, + {"id": "Zephine", "group": 3}, + {"id": "Fantine", "group": 3}, + {"id": "Mme.Thenardier", "group": 4}, + {"id": "Thenardier", "group": 4}, + {"id": "Cosette", "group": 5}, + {"id": "Javert", "group": 4}, + {"id": "Fauchelevent", "group": 0}, + {"id": "Bamatabois", "group": 2}, + {"id": "Perpetue", "group": 3}, + {"id": "Simplice", "group": 2}, + {"id": "Scaufflaire", "group": 2}, + {"id": "Woman1", "group": 2}, + {"id": "Judge", "group": 2}, + {"id": "Champmathieu", "group": 2}, + {"id": "Brevet", "group": 2}, + {"id": "Chenildieu", "group": 2}, + {"id": "Cochepaille", "group": 2}, + {"id": "Pontmercy", "group": 4}, + {"id": "Boulatruelle", "group": 6}, + {"id": "Eponine", "group": 4}, + {"id": "Anzelma", "group": 4}, + {"id": "Woman2", "group": 5}, + {"id": "MotherInnocent", "group": 0}, + {"id": "Gribier", "group": 0}, + {"id": "Jondrette", "group": 7}, + {"id": "Mme.Burgon", "group": 7}, + {"id": "Gavroche", "group": 8}, + {"id": "Gillenormand", "group": 5}, + {"id": "Magnon", "group": 5}, + {"id": "Mlle.Gillenormand", "group": 5}, + {"id": "Mme.Pontmercy", "group": 5}, + {"id": "Mlle.Vaubois", "group": 5}, + {"id": "Lt.Gillenormand", "group": 5}, + {"id": "Marius", "group": 8}, + {"id": "BaronessT", "group": 5}, + {"id": "Mabeuf", "group": 8}, + {"id": "Enjolras", "group": 8}, + {"id": "Combeferre", "group": 8}, + {"id": "Prouvaire", "group": 8}, + {"id": "Feuilly", "group": 8}, + {"id": "Courfeyrac", "group": 8}, + {"id": "Bahorel", "group": 8}, + {"id": "Bossuet", "group": 8}, + {"id": "Joly", "group": 8}, + {"id": "Grantaire", "group": 8}, + {"id": "MotherPlutarch", "group": 9}, + {"id": "Gueulemer", "group": 4}, + {"id": "Babet", "group": 4}, + {"id": "Claquesous", "group": 4}, + {"id": "Montparnasse", "group": 4}, + {"id": "Toussaint", "group": 5}, + {"id": "Child1", "group": 10}, + {"id": "Child2", "group": 10}, + {"id": "Brujon", "group": 4}, + {"id": "Mme.Hucheloup", "group": 8} + ], + "links": [ + {"source": "Napoleon", "target": "Myriel", "value": 1}, + {"source": "Mlle.Baptistine", "target": "Myriel", "value": 8}, + {"source": "Mme.Magloire", "target": "Myriel", "value": 10}, + {"source": "Mme.Magloire", "target": "Mlle.Baptistine", "value": 6}, + {"source": "CountessdeLo", "target": "Myriel", "value": 1}, + {"source": "Geborand", "target": "Myriel", "value": 1}, + {"source": "Champtercier", "target": "Myriel", "value": 1}, + {"source": "Cravatte", "target": "Myriel", "value": 1}, + {"source": "Count", "target": "Myriel", "value": 2}, + {"source": "OldMan", "target": "Myriel", "value": 1}, + {"source": "Valjean", "target": "Labarre", "value": 1}, + {"source": "Valjean", "target": "Mme.Magloire", "value": 3}, + {"source": "Valjean", "target": "Mlle.Baptistine", "value": 3}, + {"source": "Valjean", "target": "Myriel", "value": 5}, + {"source": "Marguerite", "target": "Valjean", "value": 1}, + {"source": "Mme.deR", "target": "Valjean", "value": 1}, + {"source": "Isabeau", "target": "Valjean", "value": 1}, + {"source": "Gervais", "target": "Valjean", "value": 1}, + {"source": "Listolier", "target": "Tholomyes", "value": 4}, + {"source": "Fameuil", "target": "Tholomyes", "value": 4}, + {"source": "Fameuil", "target": "Listolier", "value": 4}, + {"source": "Blacheville", "target": "Tholomyes", "value": 4}, + {"source": "Blacheville", "target": "Listolier", "value": 4}, + {"source": "Blacheville", "target": "Fameuil", "value": 4}, + {"source": "Favourite", "target": "Tholomyes", "value": 3}, + {"source": "Favourite", "target": "Listolier", "value": 3}, + {"source": "Favourite", "target": "Fameuil", "value": 3}, + {"source": "Favourite", "target": "Blacheville", "value": 4}, + {"source": "Dahlia", "target": "Tholomyes", "value": 3}, + {"source": "Dahlia", "target": "Listolier", "value": 3}, + {"source": "Dahlia", "target": "Fameuil", "value": 3}, + {"source": "Dahlia", "target": "Blacheville", "value": 3}, + {"source": "Dahlia", "target": "Favourite", "value": 5}, + {"source": "Zephine", "target": "Tholomyes", "value": 3}, + {"source": "Zephine", "target": "Listolier", "value": 3}, + {"source": "Zephine", "target": "Fameuil", "value": 3}, + {"source": "Zephine", "target": "Blacheville", "value": 3}, + {"source": "Zephine", "target": "Favourite", "value": 4}, + {"source": "Zephine", "target": "Dahlia", "value": 4}, + {"source": "Fantine", "target": "Tholomyes", "value": 3}, + {"source": "Fantine", "target": "Listolier", "value": 3}, + {"source": "Fantine", "target": "Fameuil", "value": 3}, + {"source": "Fantine", "target": "Blacheville", "value": 3}, + {"source": "Fantine", "target": "Favourite", "value": 4}, + {"source": "Fantine", "target": "Dahlia", "value": 4}, + {"source": "Fantine", "target": "Zephine", "value": 4}, + {"source": "Fantine", "target": "Marguerite", "value": 2}, + {"source": "Fantine", "target": "Valjean", "value": 9}, + {"source": "Mme.Thenardier", "target": "Fantine", "value": 2}, + {"source": "Mme.Thenardier", "target": "Valjean", "value": 7}, + {"source": "Thenardier", "target": "Mme.Thenardier", "value": 13}, + {"source": "Thenardier", "target": "Fantine", "value": 1}, + {"source": "Thenardier", "target": "Valjean", "value": 12}, + {"source": "Cosette", "target": "Mme.Thenardier", "value": 4}, + {"source": "Cosette", "target": "Valjean", "value": 31}, + {"source": "Cosette", "target": "Tholomyes", "value": 1}, + {"source": "Cosette", "target": "Thenardier", "value": 1}, + {"source": "Javert", "target": "Valjean", "value": 17}, + {"source": "Javert", "target": "Fantine", "value": 5}, + {"source": "Javert", "target": "Thenardier", "value": 5}, + {"source": "Javert", "target": "Mme.Thenardier", "value": 1}, + {"source": "Javert", "target": "Cosette", "value": 1}, + {"source": "Fauchelevent", "target": "Valjean", "value": 8}, + {"source": "Fauchelevent", "target": "Javert", "value": 1}, + {"source": "Bamatabois", "target": "Fantine", "value": 1}, + {"source": "Bamatabois", "target": "Javert", "value": 1}, + {"source": "Bamatabois", "target": "Valjean", "value": 2}, + {"source": "Perpetue", "target": "Fantine", "value": 1}, + {"source": "Simplice", "target": "Perpetue", "value": 2}, + {"source": "Simplice", "target": "Valjean", "value": 3}, + {"source": "Simplice", "target": "Fantine", "value": 2}, + {"source": "Simplice", "target": "Javert", "value": 1}, + {"source": "Scaufflaire", "target": "Valjean", "value": 1}, + {"source": "Woman1", "target": "Valjean", "value": 2}, + {"source": "Woman1", "target": "Javert", "value": 1}, + {"source": "Judge", "target": "Valjean", "value": 3}, + {"source": "Judge", "target": "Bamatabois", "value": 2}, + {"source": "Champmathieu", "target": "Valjean", "value": 3}, + {"source": "Champmathieu", "target": "Judge", "value": 3}, + {"source": "Champmathieu", "target": "Bamatabois", "value": 2}, + {"source": "Brevet", "target": "Judge", "value": 2}, + {"source": "Brevet", "target": "Champmathieu", "value": 2}, + {"source": "Brevet", "target": "Valjean", "value": 2}, + {"source": "Brevet", "target": "Bamatabois", "value": 1}, + {"source": "Chenildieu", "target": "Judge", "value": 2}, + {"source": "Chenildieu", "target": "Champmathieu", "value": 2}, + {"source": "Chenildieu", "target": "Brevet", "value": 2}, + {"source": "Chenildieu", "target": "Valjean", "value": 2}, + {"source": "Chenildieu", "target": "Bamatabois", "value": 1}, + {"source": "Cochepaille", "target": "Judge", "value": 2}, + {"source": "Cochepaille", "target": "Champmathieu", "value": 2}, + {"source": "Cochepaille", "target": "Brevet", "value": 2}, + {"source": "Cochepaille", "target": "Chenildieu", "value": 2}, + {"source": "Cochepaille", "target": "Valjean", "value": 2}, + {"source": "Cochepaille", "target": "Bamatabois", "value": 1}, + {"source": "Pontmercy", "target": "Thenardier", "value": 1}, + {"source": "Boulatruelle", "target": "Thenardier", "value": 1}, + {"source": "Eponine", "target": "Mme.Thenardier", "value": 2}, + {"source": "Eponine", "target": "Thenardier", "value": 3}, + {"source": "Anzelma", "target": "Eponine", "value": 2}, + {"source": "Anzelma", "target": "Thenardier", "value": 2}, + {"source": "Anzelma", "target": "Mme.Thenardier", "value": 1}, + {"source": "Woman2", "target": "Valjean", "value": 3}, + {"source": "Woman2", "target": "Cosette", "value": 1}, + {"source": "Woman2", "target": "Javert", "value": 1}, + {"source": "MotherInnocent", "target": "Fauchelevent", "value": 3}, + {"source": "MotherInnocent", "target": "Valjean", "value": 1}, + {"source": "Gribier", "target": "Fauchelevent", "value": 2}, + {"source": "Mme.Burgon", "target": "Jondrette", "value": 1}, + {"source": "Gavroche", "target": "Mme.Burgon", "value": 2}, + {"source": "Gavroche", "target": "Thenardier", "value": 1}, + {"source": "Gavroche", "target": "Javert", "value": 1}, + {"source": "Gavroche", "target": "Valjean", "value": 1}, + {"source": "Gillenormand", "target": "Cosette", "value": 3}, + {"source": "Gillenormand", "target": "Valjean", "value": 2}, + {"source": "Magnon", "target": "Gillenormand", "value": 1}, + {"source": "Magnon", "target": "Mme.Thenardier", "value": 1}, + {"source": "Mlle.Gillenormand", "target": "Gillenormand", "value": 9}, + {"source": "Mlle.Gillenormand", "target": "Cosette", "value": 2}, + {"source": "Mlle.Gillenormand", "target": "Valjean", "value": 2}, + {"source": "Mme.Pontmercy", "target": "Mlle.Gillenormand", "value": 1}, + {"source": "Mme.Pontmercy", "target": "Pontmercy", "value": 1}, + {"source": "Mlle.Vaubois", "target": "Mlle.Gillenormand", "value": 1}, + {"source": "Lt.Gillenormand", "target": "Mlle.Gillenormand", "value": 2}, + {"source": "Lt.Gillenormand", "target": "Gillenormand", "value": 1}, + {"source": "Lt.Gillenormand", "target": "Cosette", "value": 1}, + {"source": "Marius", "target": "Mlle.Gillenormand", "value": 6}, + {"source": "Marius", "target": "Gillenormand", "value": 12}, + {"source": "Marius", "target": "Pontmercy", "value": 1}, + {"source": "Marius", "target": "Lt.Gillenormand", "value": 1}, + {"source": "Marius", "target": "Cosette", "value": 21}, + {"source": "Marius", "target": "Valjean", "value": 19}, + {"source": "Marius", "target": "Tholomyes", "value": 1}, + {"source": "Marius", "target": "Thenardier", "value": 2}, + {"source": "Marius", "target": "Eponine", "value": 5}, + {"source": "Marius", "target": "Gavroche", "value": 4}, + {"source": "BaronessT", "target": "Gillenormand", "value": 1}, + {"source": "BaronessT", "target": "Marius", "value": 1}, + {"source": "Mabeuf", "target": "Marius", "value": 1}, + {"source": "Mabeuf", "target": "Eponine", "value": 1}, + {"source": "Mabeuf", "target": "Gavroche", "value": 1}, + {"source": "Enjolras", "target": "Marius", "value": 7}, + {"source": "Enjolras", "target": "Gavroche", "value": 7}, + {"source": "Enjolras", "target": "Javert", "value": 6}, + {"source": "Enjolras", "target": "Mabeuf", "value": 1}, + {"source": "Enjolras", "target": "Valjean", "value": 4}, + {"source": "Combeferre", "target": "Enjolras", "value": 15}, + {"source": "Combeferre", "target": "Marius", "value": 5}, + {"source": "Combeferre", "target": "Gavroche", "value": 6}, + {"source": "Combeferre", "target": "Mabeuf", "value": 2}, + {"source": "Prouvaire", "target": "Gavroche", "value": 1}, + {"source": "Prouvaire", "target": "Enjolras", "value": 4}, + {"source": "Prouvaire", "target": "Combeferre", "value": 2}, + {"source": "Feuilly", "target": "Gavroche", "value": 2}, + {"source": "Feuilly", "target": "Enjolras", "value": 6}, + {"source": "Feuilly", "target": "Prouvaire", "value": 2}, + {"source": "Feuilly", "target": "Combeferre", "value": 5}, + {"source": "Feuilly", "target": "Mabeuf", "value": 1}, + {"source": "Feuilly", "target": "Marius", "value": 1}, + {"source": "Courfeyrac", "target": "Marius", "value": 9}, + {"source": "Courfeyrac", "target": "Enjolras", "value": 17}, + {"source": "Courfeyrac", "target": "Combeferre", "value": 13}, + {"source": "Courfeyrac", "target": "Gavroche", "value": 7}, + {"source": "Courfeyrac", "target": "Mabeuf", "value": 2}, + {"source": "Courfeyrac", "target": "Eponine", "value": 1}, + {"source": "Courfeyrac", "target": "Feuilly", "value": 6}, + {"source": "Courfeyrac", "target": "Prouvaire", "value": 3}, + {"source": "Bahorel", "target": "Combeferre", "value": 5}, + {"source": "Bahorel", "target": "Gavroche", "value": 5}, + {"source": "Bahorel", "target": "Courfeyrac", "value": 6}, + {"source": "Bahorel", "target": "Mabeuf", "value": 2}, + {"source": "Bahorel", "target": "Enjolras", "value": 4}, + {"source": "Bahorel", "target": "Feuilly", "value": 3}, + {"source": "Bahorel", "target": "Prouvaire", "value": 2}, + {"source": "Bahorel", "target": "Marius", "value": 1}, + {"source": "Bossuet", "target": "Marius", "value": 5}, + {"source": "Bossuet", "target": "Courfeyrac", "value": 12}, + {"source": "Bossuet", "target": "Gavroche", "value": 5}, + {"source": "Bossuet", "target": "Bahorel", "value": 4}, + {"source": "Bossuet", "target": "Enjolras", "value": 10}, + {"source": "Bossuet", "target": "Feuilly", "value": 6}, + {"source": "Bossuet", "target": "Prouvaire", "value": 2}, + {"source": "Bossuet", "target": "Combeferre", "value": 9}, + {"source": "Bossuet", "target": "Mabeuf", "value": 1}, + {"source": "Bossuet", "target": "Valjean", "value": 1}, + {"source": "Joly", "target": "Bahorel", "value": 5}, + {"source": "Joly", "target": "Bossuet", "value": 7}, + {"source": "Joly", "target": "Gavroche", "value": 3}, + {"source": "Joly", "target": "Courfeyrac", "value": 5}, + {"source": "Joly", "target": "Enjolras", "value": 5}, + {"source": "Joly", "target": "Feuilly", "value": 5}, + {"source": "Joly", "target": "Prouvaire", "value": 2}, + {"source": "Joly", "target": "Combeferre", "value": 5}, + {"source": "Joly", "target": "Mabeuf", "value": 1}, + {"source": "Joly", "target": "Marius", "value": 2}, + {"source": "Grantaire", "target": "Bossuet", "value": 3}, + {"source": "Grantaire", "target": "Enjolras", "value": 3}, + {"source": "Grantaire", "target": "Combeferre", "value": 1}, + {"source": "Grantaire", "target": "Courfeyrac", "value": 2}, + {"source": "Grantaire", "target": "Joly", "value": 2}, + {"source": "Grantaire", "target": "Gavroche", "value": 1}, + {"source": "Grantaire", "target": "Bahorel", "value": 1}, + {"source": "Grantaire", "target": "Feuilly", "value": 1}, + {"source": "Grantaire", "target": "Prouvaire", "value": 1}, + {"source": "MotherPlutarch", "target": "Mabeuf", "value": 3}, + {"source": "Gueulemer", "target": "Thenardier", "value": 5}, + {"source": "Gueulemer", "target": "Valjean", "value": 1}, + {"source": "Gueulemer", "target": "Mme.Thenardier", "value": 1}, + {"source": "Gueulemer", "target": "Javert", "value": 1}, + {"source": "Gueulemer", "target": "Gavroche", "value": 1}, + {"source": "Gueulemer", "target": "Eponine", "value": 1}, + {"source": "Babet", "target": "Thenardier", "value": 6}, + {"source": "Babet", "target": "Gueulemer", "value": 6}, + {"source": "Babet", "target": "Valjean", "value": 1}, + {"source": "Babet", "target": "Mme.Thenardier", "value": 1}, + {"source": "Babet", "target": "Javert", "value": 2}, + {"source": "Babet", "target": "Gavroche", "value": 1}, + {"source": "Babet", "target": "Eponine", "value": 1}, + {"source": "Claquesous", "target": "Thenardier", "value": 4}, + {"source": "Claquesous", "target": "Babet", "value": 4}, + {"source": "Claquesous", "target": "Gueulemer", "value": 4}, + {"source": "Claquesous", "target": "Valjean", "value": 1}, + {"source": "Claquesous", "target": "Mme.Thenardier", "value": 1}, + {"source": "Claquesous", "target": "Javert", "value": 1}, + {"source": "Claquesous", "target": "Eponine", "value": 1}, + {"source": "Claquesous", "target": "Enjolras", "value": 1}, + {"source": "Montparnasse", "target": "Javert", "value": 1}, + {"source": "Montparnasse", "target": "Babet", "value": 2}, + {"source": "Montparnasse", "target": "Gueulemer", "value": 2}, + {"source": "Montparnasse", "target": "Claquesous", "value": 2}, + {"source": "Montparnasse", "target": "Valjean", "value": 1}, + {"source": "Montparnasse", "target": "Gavroche", "value": 1}, + {"source": "Montparnasse", "target": "Eponine", "value": 1}, + {"source": "Montparnasse", "target": "Thenardier", "value": 1}, + {"source": "Toussaint", "target": "Cosette", "value": 2}, + {"source": "Toussaint", "target": "Javert", "value": 1}, + {"source": "Toussaint", "target": "Valjean", "value": 1}, + {"source": "Child1", "target": "Gavroche", "value": 2}, + {"source": "Child2", "target": "Gavroche", "value": 2}, + {"source": "Child2", "target": "Child1", "value": 3}, + {"source": "Brujon", "target": "Babet", "value": 3}, + {"source": "Brujon", "target": "Gueulemer", "value": 3}, + {"source": "Brujon", "target": "Thenardier", "value": 3}, + {"source": "Brujon", "target": "Gavroche", "value": 1}, + {"source": "Brujon", "target": "Eponine", "value": 1}, + {"source": "Brujon", "target": "Claquesous", "value": 1}, + {"source": "Brujon", "target": "Montparnasse", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Bossuet", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Joly", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Grantaire", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Bahorel", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Courfeyrac", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Gavroche", "value": 1}, + {"source": "Mme.Hucheloup", "target": "Enjolras", "value": 1} + ] +} diff --git a/test/docs-test.js b/test/docs-test.js new file mode 100644 index 0000000000..b35aee9e30 --- /dev/null +++ b/test/docs-test.js @@ -0,0 +1,30 @@ +import assert from "assert"; +import {readMarkdownFiles, readMarkdownSource, getAnchors, getLinks} from "../docs/components/links.js"; + +it("documentation links point to existing internal anchors", async () => { + const root = "docs"; + + // Crawl all files, read their links and anchors. + const anchors = new Map(); + const links = []; + for await (const file of readMarkdownFiles(root)) { + const text = await readMarkdownSource(root + file); + anchors.set(file, getAnchors(text)); + for (const {pathname, hash} of getLinks(file, text)) { + links.push({source: file, target: pathname, hash}); + } + } + + // Check for broken links. + let errors = []; + for (let {source, target, hash} of links) { + if (!target.endsWith(".md")) { + errors.push(`- ${source} points to ${target} instead of ${target}.md.`); + target += ".md"; + } + + if (!hash || anchors.get(target).includes(hash.slice(1))) continue; + errors.push(`- ${source} points to missing ${target}${hash}.`); + } + assert(errors.length === 0, new Error(`${errors.length} broken links:\n${errors.join("\n")}`)); +}); diff --git a/test/output/aaplBollingerCandlestick.svg b/test/output/aaplBollingerCandlestick.svg new file mode 100644 index 0000000000..6e8c439860 --- /dev/null +++ b/test/output/aaplBollingerCandlestick.svg @@ -0,0 +1,2619 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 68 + 70 + 72 + 74 + 76 + 78 + 80 + 82 + 84 + 86 + 88 + 90 + 92 + + + + + + + + + + + Jan2014 + Feb + Mar + Apr + May + Jun + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/aaplCandlestick.svg b/test/output/aaplCandlestick.svg index 92e6ddda36..b60901d70f 100644 --- a/test/output/aaplCandlestick.svg +++ b/test/output/aaplCandlestick.svg @@ -63,11 +63,11 @@ - December - 2018 - February - March - April + Dec2017 + Jan2018 + Feb + Mar + Apr May diff --git a/test/output/aaplCloseClip.svg b/test/output/aaplCloseClip.svg new file mode 100644 index 0000000000..9b60fb1f6f --- /dev/null +++ b/test/output/aaplCloseClip.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 20 + 40 + 60 + 80 + 100 + 120 + 140 + 160 + 180 + + + ↑ Close + + + + + + + + + + + + + + + + + + 4Jan + 11 + 18 + 25 + 1Feb + 8 + 15 + 22 + 1Mar + 8 + 15 + 22 + 29 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/aaplVolumeRect.svg b/test/output/aaplVolumeRect.svg index 42a109c0a3..85fb7accd7 100644 --- a/test/output/aaplVolumeRect.svg +++ b/test/output/aaplVolumeRect.svg @@ -75,14 +75,14 @@ - Mar 18 - Mar 25 - April - Apr 08 - Apr 15 - Apr 22 - Apr 29 - May 06 + 18Mar + 25 + 1Apr + 8 + 15 + 22 + 29 + 6May diff --git a/test/output/arcCollatz.svg b/test/output/arcCollatz.svg new file mode 100644 index 0000000000..e4c78eaf14 --- /dev/null +++ b/test/output/arcCollatz.svg @@ -0,0 +1,51 @@ + + + + 12 + 6 + 3 + 10 + 5 + 16 + 8 + 4 + 2 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/arcCollatzUp.svg b/test/output/arcCollatzUp.svg new file mode 100644 index 0000000000..140d26e2bb --- /dev/null +++ b/test/output/arcCollatzUp.svg @@ -0,0 +1,67 @@ + + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/arcMiserables.svg b/test/output/arcMiserables.svg new file mode 100644 index 0000000000..a310a317f1 --- /dev/null +++ b/test/output/arcMiserables.svg @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Myriel + Napoleon + Mlle.Baptistine + Mme.Magloire + CountessdeLo + Geborand + Champtercier + Cravatte + Count + OldMan + Labarre + Valjean + Marguerite + Mme.deR + Isabeau + Gervais + Tholomyes + Listolier + Fameuil + Blacheville + Favourite + Dahlia + Zephine + Fantine + Mme.Thenardier + Thenardier + Cosette + Javert + Fauchelevent + Bamatabois + Perpetue + Simplice + Scaufflaire + Woman1 + Judge + Champmathieu + Brevet + Chenildieu + Cochepaille + Pontmercy + Boulatruelle + Eponine + Anzelma + Woman2 + MotherInnocent + Gribier + Jondrette + Mme.Burgon + Gavroche + Gillenormand + Magnon + Mlle.Gillenormand + Mme.Pontmercy + Mlle.Vaubois + Lt.Gillenormand + Marius + BaronessT + Mabeuf + Enjolras + Combeferre + Prouvaire + Feuilly + Courfeyrac + Bahorel + Bossuet + Joly + Grantaire + MotherPlutarch + Gueulemer + Babet + Claquesous + Montparnasse + Toussaint + Child1 + Child2 + Brujon + Mme.Hucheloup + + \ No newline at end of file diff --git a/test/output/athletesSortNationality.html b/test/output/athletesSortNationality.html index d371b42a1e..15732dce20 100644 --- a/test/output/athletesSortNationality.html +++ b/test/output/athletesSortNationality.html @@ -1,4 +1,4 @@ -
+
+ + + + + + + + + + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + ↑ value + + + + + + + + + + + 2023-04-01 + 2023-04-05 + 2023-04-10 + 2023-04-15 + 2023-04-20 + 2023-04-25 + + + date + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoBarTimeSeriesReduce.svg b/test/output/autoBarTimeSeriesReduce.svg new file mode 100644 index 0000000000..058c8bf0cc --- /dev/null +++ b/test/output/autoBarTimeSeriesReduce.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + 0 + 2 + 4 + 6 + 8 + 10 + 12 + 14 + 16 + 18 + + + ↑ value + + + + + + + + + + + 26Mar + 2Apr + 9 + 16 + 23 + 30 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoChannels.svg b/test/output/autoChannels.svg index b699889687..45c8e3f586 100644 --- a/test/output/autoChannels.svg +++ b/test/output/autoChannels.svg @@ -11307,5 +11307,5 @@ - + \ No newline at end of file diff --git a/test/output/autoConnectedScatterplot.svg b/test/output/autoConnectedScatterplot.svg index 18e4198d0c..baa0429c36 100644 --- a/test/output/autoConnectedScatterplot.svg +++ b/test/output/autoConnectedScatterplot.svg @@ -64,5 +64,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDot.svg b/test/output/autoDot.svg index 4f7489afbc..48baa508ae 100644 --- a/test/output/autoDot.svg +++ b/test/output/autoDot.svg @@ -395,5 +395,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotBin.svg b/test/output/autoDotBin.svg index 80ce1aa876..e482e88392 100644 --- a/test/output/autoDotBin.svg +++ b/test/output/autoDotBin.svg @@ -115,5 +115,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotColor.svg b/test/output/autoDotColor.svg index ee830cd60d..5b8bf803e1 100644 --- a/test/output/autoDotColor.svg +++ b/test/output/autoDotColor.svg @@ -461,5 +461,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotFacet.svg b/test/output/autoDotFacet.svg index c00103c25e..644e8bd592 100644 --- a/test/output/autoDotFacet.svg +++ b/test/output/autoDotFacet.svg @@ -451,8 +451,8 @@ - - - + + + \ No newline at end of file diff --git a/test/output/autoDotFacet2.svg b/test/output/autoDotFacet2.svg index 87a466f49e..d515d82c8d 100644 --- a/test/output/autoDotFacet2.svg +++ b/test/output/autoDotFacet2.svg @@ -491,10 +491,10 @@ - - - - - + + + + + \ No newline at end of file diff --git a/test/output/autoDotGroup.svg b/test/output/autoDotGroup.svg index 6b31c0f580..255480d5bd 100644 --- a/test/output/autoDotGroup.svg +++ b/test/output/autoDotGroup.svg @@ -46,5 +46,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotOrdCont.svg b/test/output/autoDotOrdCont.svg index b3a68b1b5d..de4a5fa70b 100644 --- a/test/output/autoDotOrdCont.svg +++ b/test/output/autoDotOrdCont.svg @@ -387,5 +387,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotOrdinal.svg b/test/output/autoDotOrdinal.svg index 92c35ec91c..4a4b8f3ba0 100644 --- a/test/output/autoDotOrdinal.svg +++ b/test/output/autoDotOrdinal.svg @@ -855,5 +855,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotSize.svg b/test/output/autoDotSize.svg index 911d7af5a9..25400d6092 100644 --- a/test/output/autoDotSize.svg +++ b/test/output/autoDotSize.svg @@ -1289,5 +1289,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotSize2.svg b/test/output/autoDotSize2.svg index 4d6046f2c6..258403ed7e 100644 --- a/test/output/autoDotSize2.svg +++ b/test/output/autoDotSize2.svg @@ -397,5 +397,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotUnsortedDate.svg b/test/output/autoDotUnsortedDate.svg index c60edb4130..11f25a36ad 100644 --- a/test/output/autoDotUnsortedDate.svg +++ b/test/output/autoDotUnsortedDate.svg @@ -11277,5 +11277,5 @@ - + \ No newline at end of file diff --git a/test/output/autoDotZero.svg b/test/output/autoDotZero.svg index b80fa592e3..4676c4f3c2 100644 --- a/test/output/autoDotZero.svg +++ b/test/output/autoDotZero.svg @@ -124,5 +124,5 @@ - + \ No newline at end of file diff --git a/test/output/autoHeatmap.svg b/test/output/autoHeatmap.svg index d1d8d80c6e..0ea35b80e7 100644 --- a/test/output/autoHeatmap.svg +++ b/test/output/autoHeatmap.svg @@ -121,5 +121,5 @@ - + \ No newline at end of file diff --git a/test/output/autoHeatmapOrdCont.svg b/test/output/autoHeatmapOrdCont.svg index e1beba4b13..d19ba56ac3 100644 --- a/test/output/autoHeatmapOrdCont.svg +++ b/test/output/autoHeatmapOrdCont.svg @@ -73,5 +73,5 @@ - + \ No newline at end of file diff --git a/test/output/autoHeatmapOrdinal.svg b/test/output/autoHeatmapOrdinal.svg index 5c0e3e4f03..55ef16b202 100644 --- a/test/output/autoHeatmapOrdinal.svg +++ b/test/output/autoHeatmapOrdinal.svg @@ -46,5 +46,5 @@ - + \ No newline at end of file diff --git a/test/output/autoHistogram.svg b/test/output/autoHistogram.svg index 1f842833e4..3af36918ce 100644 --- a/test/output/autoHistogram.svg +++ b/test/output/autoHistogram.svg @@ -141,5 +141,5 @@ - + \ No newline at end of file diff --git a/test/output/autoHistogramDate.svg b/test/output/autoHistogramDate.svg index 04936980d3..b07ae693e8 100644 --- a/test/output/autoHistogramDate.svg +++ b/test/output/autoHistogramDate.svg @@ -121,5 +121,5 @@ - + \ No newline at end of file diff --git a/test/output/autoHistogramGroup.svg b/test/output/autoHistogramGroup.svg index 37e1e1ed3f..7dec704e20 100644 --- a/test/output/autoHistogramGroup.svg +++ b/test/output/autoHistogramGroup.svg @@ -59,5 +59,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLine.svg b/test/output/autoLine.svg index 4a1d9412d9..c4a3187007 100644 --- a/test/output/autoLine.svg +++ b/test/output/autoLine.svg @@ -65,5 +65,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineColor.svg b/test/output/autoLineColor.svg index 040c20dec4..897a16cc9f 100644 --- a/test/output/autoLineColor.svg +++ b/test/output/autoLineColor.svg @@ -1265,5 +1265,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineColorSeries.svg b/test/output/autoLineColorSeries.svg index 58f44896fd..00f1b26d20 100644 --- a/test/output/autoLineColorSeries.svg +++ b/test/output/autoLineColorSeries.svg @@ -86,5 +86,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineFacet.svg b/test/output/autoLineFacet.svg index f8a087c5e9..26574e9010 100644 --- a/test/output/autoLineFacet.svg +++ b/test/output/autoLineFacet.svg @@ -260,19 +260,19 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/autoLineHistogram.svg b/test/output/autoLineHistogram.svg index e2266b545a..211fbb7825 100644 --- a/test/output/autoLineHistogram.svg +++ b/test/output/autoLineHistogram.svg @@ -71,5 +71,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineMean.svg b/test/output/autoLineMean.svg index 2d9608f259..c39bcdbeee 100644 --- a/test/output/autoLineMean.svg +++ b/test/output/autoLineMean.svg @@ -49,5 +49,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineMeanColor.svg b/test/output/autoLineMeanColor.svg index ea7699d075..0acdd68044 100644 --- a/test/output/autoLineMeanColor.svg +++ b/test/output/autoLineMeanColor.svg @@ -65,5 +65,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineMeanThresholds.svg b/test/output/autoLineMeanThresholds.svg index 09caafd181..e32145a840 100644 --- a/test/output/autoLineMeanThresholds.svg +++ b/test/output/autoLineMeanThresholds.svg @@ -55,5 +55,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineMeanZero.svg b/test/output/autoLineMeanZero.svg index 4aeac11c28..a164072f5f 100644 --- a/test/output/autoLineMeanZero.svg +++ b/test/output/autoLineMeanZero.svg @@ -62,5 +62,5 @@ - + \ No newline at end of file diff --git a/test/output/autoLineZero.svg b/test/output/autoLineZero.svg index 17fc92f071..591ee68c3e 100644 --- a/test/output/autoLineZero.svg +++ b/test/output/autoLineZero.svg @@ -91,5 +91,5 @@ - + \ No newline at end of file diff --git a/test/output/autoNullReduceContinuous.svg b/test/output/autoNullReduceContinuous.svg index 0d787b6a34..f8f053b76c 100644 --- a/test/output/autoNullReduceContinuous.svg +++ b/test/output/autoNullReduceContinuous.svg @@ -374,5 +374,5 @@ - + \ No newline at end of file diff --git a/test/output/autoNullReduceDate.svg b/test/output/autoNullReduceDate.svg index 119addad42..74d24996d2 100644 --- a/test/output/autoNullReduceDate.svg +++ b/test/output/autoNullReduceDate.svg @@ -11580,5 +11580,5 @@ - + \ No newline at end of file diff --git a/test/output/autoNullReduceOrdinal.svg b/test/output/autoNullReduceOrdinal.svg index b3f5abed33..2558830673 100644 --- a/test/output/autoNullReduceOrdinal.svg +++ b/test/output/autoNullReduceOrdinal.svg @@ -31,5 +31,5 @@ - + \ No newline at end of file diff --git a/test/output/autoRectColorReducer.svg b/test/output/autoRectColorReducer.svg index 6c6e40576d..3ef4421c15 100644 --- a/test/output/autoRectColorReducer.svg +++ b/test/output/autoRectColorReducer.svg @@ -75,5 +75,5 @@ - + \ No newline at end of file diff --git a/test/output/autoRectStackColor.svg b/test/output/autoRectStackColor.svg index 81526e4f98..4e7d1a89e1 100644 --- a/test/output/autoRectStackColor.svg +++ b/test/output/autoRectStackColor.svg @@ -95,5 +95,5 @@ - + \ No newline at end of file diff --git a/test/output/autoRuleZero.svg b/test/output/autoRuleZero.svg index b7d4cd4662..f298cb1179 100644 --- a/test/output/autoRuleZero.svg +++ b/test/output/autoRuleZero.svg @@ -121,5 +121,5 @@ - + \ No newline at end of file diff --git a/test/output/availability.svg b/test/output/availability.svg index b153c1f0a3..fe2ff96428 100644 --- a/test/output/availability.svg +++ b/test/output/availability.svg @@ -41,12 +41,12 @@ - 2020 - April - July - October - 2021 - April + Jan2020 + Apr + Jul + Oct + Jan2021 + Apr diff --git a/test/output/axisFilter.svg b/test/output/axisFilter.svg new file mode 100644 index 0000000000..8218746e64 --- /dev/null +++ b/test/output/axisFilter.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + A + B + + + + + + + 1 + 2 + + \ No newline at end of file diff --git a/test/output/bigint1.svg b/test/output/bigint1.svg index 46aa0a8b51..0c78468c35 100644 --- a/test/output/bigint1.svg +++ b/test/output/bigint1.svg @@ -82,5 +82,5 @@ - + \ No newline at end of file diff --git a/test/output/bigintOrdinal.html b/test/output/bigintOrdinal.html index 57bd09462f..6f0ecad4c6 100644 --- a/test/output/bigintOrdinal.html +++ b/test/output/bigintOrdinal.html @@ -1,4 +1,4 @@ -
+
+ + + + + 0 + + + + 5 + + + + 10 + + + + 15 + + + + 20 + + + + + + + + + + + + + + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/test/output/warnMisalignedLinearDomain.html b/test/output/colorPiecewiseLinearRange.html similarity index 76% rename from test/output/warnMisalignedLinearDomain.html rename to test/output/colorPiecewiseLinearRange.html index 5209ae62a4..8fb79f9a34 100644 --- a/test/output/warnMisalignedLinearDomain.html +++ b/test/output/colorPiecewiseLinearRange.html @@ -1,4 +1,4 @@ -
+
- + @@ -83,16 +83,15 @@ - - - - - - - - - - + + + + + + + + + + - ⚠️1 warning. Please check the console.
\ No newline at end of file diff --git a/test/output/warnMisalignedLinearRange.html b/test/output/colorPiecewiseLinearRangeHcl.html similarity index 73% rename from test/output/warnMisalignedLinearRange.html rename to test/output/colorPiecewiseLinearRangeHcl.html index 5209ae62a4..18e652c6d2 100644 --- a/test/output/warnMisalignedLinearRange.html +++ b/test/output/colorPiecewiseLinearRangeHcl.html @@ -1,4 +1,4 @@ -
+
- + @@ -83,16 +83,15 @@ - - - - - - - - - - + + + + + + + + + + - ⚠️1 warning. Please check the console.
\ No newline at end of file diff --git a/test/output/warnMisalignedLinearDomainReverse.html b/test/output/colorPiecewiseLinearRangeReverse.html similarity index 76% rename from test/output/warnMisalignedLinearDomainReverse.html rename to test/output/colorPiecewiseLinearRangeReverse.html index b4308ac587..71d2d3c567 100644 --- a/test/output/warnMisalignedLinearDomainReverse.html +++ b/test/output/colorPiecewiseLinearRangeReverse.html @@ -1,4 +1,4 @@ -
+
- + - 10 + 0 - 8 + 2 - 6 + 4 - 4 + 6 - 2 + 8 - 0 + 10 @@ -82,17 +82,16 @@ 10 - - - - - - - - - - + + + + + + + + + + - ⚠️1 warning. Please check the console.
\ No newline at end of file diff --git a/test/output/covidIhmeProjectedDeaths.svg b/test/output/covidIhmeProjectedDeaths.svg index d09f543845..c1838e9c5f 100644 --- a/test/output/covidIhmeProjectedDeaths.svg +++ b/test/output/covidIhmeProjectedDeaths.svg @@ -115,28 +115,6 @@ ↑ Deaths per day to COVID-19 (projected) - - - - - - - - - - - - - - - - - - - - - - @@ -160,27 +138,49 @@ - 01March - 08 + 1Mar + 8 15 22 29 - 05April + 5Apr 12 19 26 - 03May + 3May 10 17 24 31 - 07June + 7Jun 14 21 28 - 05July + 5Jul 12 + + + + + + + + + + + + + + + + + + + + + + cone of uncertainty diff --git a/test/output/crosshairDodge.svg b/test/output/crosshairDodge.svg index 1928b02332..b5bb02f041 100644 --- a/test/output/crosshairDodge.svg +++ b/test/output/crosshairDodge.svg @@ -374,6 +374,6 @@ - - + +
\ No newline at end of file diff --git a/test/output/crosshairDot.svg b/test/output/crosshairDot.svg index b87417e4ff..d310f29258 100644 --- a/test/output/crosshairDot.svg +++ b/test/output/crosshairDot.svg @@ -397,8 +397,8 @@ - - - - + + + +
\ No newline at end of file diff --git a/test/output/crosshairDotFacet.svg b/test/output/crosshairDotFacet.svg index 6c5958d5e1..2891d8bd5c 100644 --- a/test/output/crosshairDotFacet.svg +++ b/test/output/crosshairDotFacet.svg @@ -442,23 +442,23 @@ - - - + + + - - - + + + - - - + + + - - - + + +
\ No newline at end of file diff --git a/test/output/crosshairHexbin.svg b/test/output/crosshairHexbin.svg index 99d91017a8..4e809bccf8 100644 --- a/test/output/crosshairHexbin.svg +++ b/test/output/crosshairHexbin.svg @@ -302,8 +302,8 @@ - - - - + + + + \ No newline at end of file diff --git a/test/output/crosshairLine.svg b/test/output/crosshairLine.svg index 714f0c0819..7298cd8414 100644 --- a/test/output/crosshairLine.svg +++ b/test/output/crosshairLine.svg @@ -65,8 +65,8 @@ - - - - + + + + \ No newline at end of file diff --git a/test/output/decathlon.html b/test/output/decathlon.html index 61394ba1e7..e9f22f828f 100644 --- a/test/output/decathlon.html +++ b/test/output/decathlon.html @@ -1,4 +1,4 @@ -
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - /flare - /flare/analytics - /flare/animate - /flare/data - /flare/display - /flare/flex - /flare/physics - /flare/query - /flare/scale - /flare/util - /flare/vis - /flare/analytics/cluster - /flare/analytics/graph - /flare/analytics/optimization + /flare + /flare/analytics + /flare/animate + /flare/data + /flare/display + /flare/flex + /flare/physics + /flare/query + /flare/scale + /flare/util + /flare/vis + /flare/analytics/cluster + /flare/analytics/graph + /flare/analytics/optimization /flare/animate/Easing /flare/animate/FunctionSequence - /flare/animate/interpolate + /flare/animate/interpolate /flare/animate/ISchedulable /flare/animate/Parallel /flare/animate/Pause @@ -293,7 +293,7 @@ /flare/animate/Transitioner /flare/animate/TransitionEvent /flare/animate/Tween - /flare/data/converters + /flare/data/converters /flare/data/DataField /flare/data/DataSchema /flare/data/DataSet @@ -331,7 +331,7 @@ /flare/query/Literal /flare/query/Match /flare/query/Maximum - /flare/query/methods + /flare/query/methods /flare/query/Minimum /flare/query/Not /flare/query/Or @@ -358,25 +358,25 @@ /flare/util/Displays /flare/util/Filter /flare/util/Geometry - /flare/util/heap + /flare/util/heap /flare/util/IEvaluable /flare/util/IPredicate /flare/util/IValueProxy - /flare/util/math + /flare/util/math /flare/util/Maths /flare/util/Orientation - /flare/util/palette + /flare/util/palette /flare/util/Property /flare/util/Shapes /flare/util/Sort /flare/util/Stats /flare/util/Strings - /flare/vis/axis - /flare/vis/controls - /flare/vis/data - /flare/vis/events - /flare/vis/legend - /flare/vis/operator + /flare/vis/axis + /flare/vis/controls + /flare/vis/data + /flare/vis/events + /flare/vis/legend + /flare/vis/operator /flare/vis/Visualization /flare/analytics/cluster/AgglomerativeCluster /flare/analytics/cluster/CommunityStructure @@ -464,7 +464,7 @@ /flare/vis/data/DataSprite /flare/vis/data/EdgeSprite /flare/vis/data/NodeSprite - /flare/vis/data/render + /flare/vis/data/render /flare/vis/data/ScaleBinding /flare/vis/data/Tree /flare/vis/data/TreeBuilder @@ -475,12 +475,12 @@ /flare/vis/legend/Legend /flare/vis/legend/LegendItem /flare/vis/legend/LegendRange - /flare/vis/operator/distortion - /flare/vis/operator/encoder - /flare/vis/operator/filter + /flare/vis/operator/distortion + /flare/vis/operator/encoder + /flare/vis/operator/filter /flare/vis/operator/IOperator - /flare/vis/operator/label - /flare/vis/operator/layout + /flare/vis/operator/label + /flare/vis/operator/layout /flare/vis/operator/Operator /flare/vis/operator/OperatorList /flare/vis/operator/OperatorSequence @@ -521,23 +521,8 @@ /flare/vis/operator/layout/TreeMapLayout - flare/flare - analytics/flare/analytics - animate/flare/animate - data/flare/data - display/flare/display - flex/flare/flex - physics/flare/physics - query/flare/query - scale/flare/scale - util/flare/util - vis/flare/vis - cluster/flare/analytics/cluster - graph/flare/analytics/graph - optimization/flare/analytics/optimization Easing/flare/animate/Easing FunctionSequence/flare/animate/FunctionSequence - interpolate/flare/animate/interpolate ISchedulable/flare/animate/ISchedulable Parallel/flare/animate/Parallel Pause/flare/animate/Pause @@ -547,7 +532,6 @@ Transitioner/flare/animate/Transitioner TransitionEvent/flare/animate/TransitionEvent Tween/flare/animate/Tween - converters/flare/data/converters DataField/flare/data/DataField DataSchema/flare/data/DataSchema DataSet/flare/data/DataSet @@ -585,7 +569,6 @@ Literal/flare/query/Literal Match/flare/query/Match Maximum/flare/query/Maximum - methods/flare/query/methods Minimum/flare/query/Minimum Not/flare/query/Not Or/flare/query/Or @@ -612,25 +595,16 @@ Displays/flare/util/Displays Filter/flare/util/Filter Geometry/flare/util/Geometry - heap/flare/util/heap IEvaluable/flare/util/IEvaluable IPredicate/flare/util/IPredicate IValueProxy/flare/util/IValueProxy - math/flare/util/math Maths/flare/util/Maths Orientation/flare/util/Orientation - palette/flare/util/palette Property/flare/util/Property Shapes/flare/util/Shapes Sort/flare/util/Sort Stats/flare/util/Stats Strings/flare/util/Strings - axis/flare/vis/axis - controls/flare/vis/controls - data/flare/vis/data - events/flare/vis/events - legend/flare/vis/legend - operator/flare/vis/operator Visualization/flare/vis/Visualization AgglomerativeCluster/flare/analytics/cluster/AgglomerativeCluster CommunityStructure/flare/analytics/cluster/CommunityStructure @@ -718,7 +692,6 @@ DataSprite/flare/vis/data/DataSprite EdgeSprite/flare/vis/data/EdgeSprite NodeSprite/flare/vis/data/NodeSprite - render/flare/vis/data/render ScaleBinding/flare/vis/data/ScaleBinding Tree/flare/vis/data/Tree TreeBuilder/flare/vis/data/TreeBuilder @@ -729,12 +702,7 @@ Legend/flare/vis/legend/Legend LegendItem/flare/vis/legend/LegendItem LegendRange/flare/vis/legend/LegendRange - distortion/flare/vis/operator/distortion - encoder/flare/vis/operator/encoder - filter/flare/vis/operator/filter IOperator/flare/vis/operator/IOperator - label/flare/vis/operator/label - layout/flare/vis/operator/layout Operator/flare/vis/operator/Operator OperatorList/flare/vis/operator/OperatorList OperatorSequence/flare/vis/operator/OperatorSequence @@ -774,4 +742,38 @@ StackedAreaLayout/flare/vis/operator/layout/StackedAreaLayout TreeMapLayout/flare/vis/operator/layout/TreeMapLayout + + flare/flare + analytics/flare/analytics + animate/flare/animate + data/flare/data + display/flare/display + flex/flare/flex + physics/flare/physics + query/flare/query + scale/flare/scale + util/flare/util + vis/flare/vis + cluster/flare/analytics/cluster + graph/flare/analytics/graph + optimization/flare/analytics/optimization + interpolate/flare/animate/interpolate + converters/flare/data/converters + methods/flare/query/methods + heap/flare/util/heap + math/flare/util/math + palette/flare/util/palette + axis/flare/vis/axis + controls/flare/vis/controls + data/flare/vis/data + events/flare/vis/events + legend/flare/vis/legend + operator/flare/vis/operator + render/flare/vis/data/render + distortion/flare/vis/operator/distortion + encoder/flare/vis/operator/encoder + filter/flare/vis/operator/filter + label/flare/vis/operator/label + layout/flare/vis/operator/layout + \ No newline at end of file diff --git a/test/output/flareTree.svg b/test/output/flareTree.svg index 2d9271f72a..691f0bb2d8 100644 --- a/test/output/flareTree.svg +++ b/test/output/flareTree.svg @@ -17,481 +17,449 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - flare/flare - analytics/flare/analytics - animate/flare/animate - data/flare/data - display/flare/display - flex/flare/flex - physics/flare/physics - query/flare/query - scale/flare/scale - util/flare/util - vis/flare/vis - cluster/flare/analytics/cluster - graph/flare/analytics/graph - optimization/flare/analytics/optimization - Easing/flare/animate/Easing - FunctionSequence/flare/animate/FunctionSequence - interpolate/flare/animate/interpolate - ISchedulable/flare/animate/ISchedulable - Parallel/flare/animate/Parallel - Pause/flare/animate/Pause - Scheduler/flare/animate/Scheduler - Sequence/flare/animate/Sequence - Transition/flare/animate/Transition - Transitioner/flare/animate/Transitioner - TransitionEvent/flare/animate/TransitionEvent - Tween/flare/animate/Tween - converters/flare/data/converters - DataField/flare/data/DataField - DataSchema/flare/data/DataSchema - DataSet/flare/data/DataSet - DataSource/flare/data/DataSource - DataTable/flare/data/DataTable - DataUtil/flare/data/DataUtil - DirtySprite/flare/display/DirtySprite - LineSprite/flare/display/LineSprite - RectSprite/flare/display/RectSprite - TextSprite/flare/display/TextSprite - FlareVis/flare/flex/FlareVis - DragForce/flare/physics/DragForce - GravityForce/flare/physics/GravityForce - IForce/flare/physics/IForce - NBodyForce/flare/physics/NBodyForce - Particle/flare/physics/Particle - Simulation/flare/physics/Simulation - Spring/flare/physics/Spring - SpringForce/flare/physics/SpringForce - AggregateExpression/flare/query/AggregateExpression - And/flare/query/And - Arithmetic/flare/query/Arithmetic - Average/flare/query/Average - BinaryExpression/flare/query/BinaryExpression - Comparison/flare/query/Comparison - CompositeExpression/flare/query/CompositeExpression - Count/flare/query/Count - DateUtil/flare/query/DateUtil - Distinct/flare/query/Distinct - Expression/flare/query/Expression - ExpressionIterator/flare/query/ExpressionIterator - Fn/flare/query/Fn - If/flare/query/If - IsA/flare/query/IsA - Literal/flare/query/Literal - Match/flare/query/Match - Maximum/flare/query/Maximum - methods/flare/query/methods - Minimum/flare/query/Minimum - Not/flare/query/Not - Or/flare/query/Or - Query/flare/query/Query - Range/flare/query/Range - StringUtil/flare/query/StringUtil - Sum/flare/query/Sum - Variable/flare/query/Variable - Variance/flare/query/Variance - Xor/flare/query/Xor - IScaleMap/flare/scale/IScaleMap - LinearScale/flare/scale/LinearScale - LogScale/flare/scale/LogScale - OrdinalScale/flare/scale/OrdinalScale - QuantileScale/flare/scale/QuantileScale - QuantitativeScale/flare/scale/QuantitativeScale - RootScale/flare/scale/RootScale - Scale/flare/scale/Scale - ScaleType/flare/scale/ScaleType - TimeScale/flare/scale/TimeScale - Arrays/flare/util/Arrays - Colors/flare/util/Colors - Dates/flare/util/Dates - Displays/flare/util/Displays - Filter/flare/util/Filter - Geometry/flare/util/Geometry - heap/flare/util/heap - IEvaluable/flare/util/IEvaluable - IPredicate/flare/util/IPredicate - IValueProxy/flare/util/IValueProxy - math/flare/util/math - Maths/flare/util/Maths - Orientation/flare/util/Orientation - palette/flare/util/palette - Property/flare/util/Property - Shapes/flare/util/Shapes - Sort/flare/util/Sort - Stats/flare/util/Stats - Strings/flare/util/Strings - axis/flare/vis/axis - controls/flare/vis/controls - data/flare/vis/data - events/flare/vis/events - legend/flare/vis/legend - operator/flare/vis/operator - Visualization/flare/vis/Visualization - AgglomerativeCluster/flare/analytics/cluster/AgglomerativeCluster - CommunityStructure/flare/analytics/cluster/CommunityStructure - HierarchicalCluster/flare/analytics/cluster/HierarchicalCluster - MergeEdge/flare/analytics/cluster/MergeEdge - BetweennessCentrality/flare/analytics/graph/BetweennessCentrality - LinkDistance/flare/analytics/graph/LinkDistance - MaxFlowMinCut/flare/analytics/graph/MaxFlowMinCut - ShortestPaths/flare/analytics/graph/ShortestPaths - SpanningTree/flare/analytics/graph/SpanningTree - AspectRatioBanker/flare/analytics/optimization/AspectRatioBanker - ArrayInterpolator/flare/animate/interpolate/ArrayInterpolator - ColorInterpolator/flare/animate/interpolate/ColorInterpolator - DateInterpolator/flare/animate/interpolate/DateInterpolator - Interpolator/flare/animate/interpolate/Interpolator - MatrixInterpolator/flare/animate/interpolate/MatrixInterpolator - NumberInterpolator/flare/animate/interpolate/NumberInterpolator - ObjectInterpolator/flare/animate/interpolate/ObjectInterpolator - PointInterpolator/flare/animate/interpolate/PointInterpolator - RectangleInterpolator/flare/animate/interpolate/RectangleInterpolator - Converters/flare/data/converters/Converters - DelimitedTextConverter/flare/data/converters/DelimitedTextConverter - GraphMLConverter/flare/data/converters/GraphMLConverter - IDataConverter/flare/data/converters/IDataConverter - JSONConverter/flare/data/converters/JSONConverter - add/flare/query/methods/add - and/flare/query/methods/and - average/flare/query/methods/average - count/flare/query/methods/count - distinct/flare/query/methods/distinct - div/flare/query/methods/div - eq/flare/query/methods/eq - fn/flare/query/methods/fn - gt/flare/query/methods/gt - gte/flare/query/methods/gte - iff/flare/query/methods/iff - isa/flare/query/methods/isa - lt/flare/query/methods/lt - lte/flare/query/methods/lte - max/flare/query/methods/max - min/flare/query/methods/min - mod/flare/query/methods/mod - mul/flare/query/methods/mul - neq/flare/query/methods/neq - not/flare/query/methods/not - or/flare/query/methods/or - orderby/flare/query/methods/orderby - range/flare/query/methods/range - select/flare/query/methods/select - stddev/flare/query/methods/stddev - sub/flare/query/methods/sub - sum/flare/query/methods/sum - update/flare/query/methods/update - variance/flare/query/methods/variance - where/flare/query/methods/where - xor/flare/query/methods/xor - _/flare/query/methods/_ - FibonacciHeap/flare/util/heap/FibonacciHeap - HeapNode/flare/util/heap/HeapNode - DenseMatrix/flare/util/math/DenseMatrix - IMatrix/flare/util/math/IMatrix - SparseMatrix/flare/util/math/SparseMatrix - ColorPalette/flare/util/palette/ColorPalette - Palette/flare/util/palette/Palette - ShapePalette/flare/util/palette/ShapePalette - SizePalette/flare/util/palette/SizePalette - Axes/flare/vis/axis/Axes - Axis/flare/vis/axis/Axis - AxisGridLine/flare/vis/axis/AxisGridLine - AxisLabel/flare/vis/axis/AxisLabel - CartesianAxes/flare/vis/axis/CartesianAxes - AnchorControl/flare/vis/controls/AnchorControl - ClickControl/flare/vis/controls/ClickControl - Control/flare/vis/controls/Control - ControlList/flare/vis/controls/ControlList - DragControl/flare/vis/controls/DragControl - ExpandControl/flare/vis/controls/ExpandControl - HoverControl/flare/vis/controls/HoverControl - IControl/flare/vis/controls/IControl - PanZoomControl/flare/vis/controls/PanZoomControl - SelectionControl/flare/vis/controls/SelectionControl - TooltipControl/flare/vis/controls/TooltipControl - Data/flare/vis/data/Data - DataList/flare/vis/data/DataList - DataSprite/flare/vis/data/DataSprite - EdgeSprite/flare/vis/data/EdgeSprite - NodeSprite/flare/vis/data/NodeSprite - render/flare/vis/data/render - ScaleBinding/flare/vis/data/ScaleBinding - Tree/flare/vis/data/Tree - TreeBuilder/flare/vis/data/TreeBuilder - DataEvent/flare/vis/events/DataEvent - SelectionEvent/flare/vis/events/SelectionEvent - TooltipEvent/flare/vis/events/TooltipEvent - VisualizationEvent/flare/vis/events/VisualizationEvent - Legend/flare/vis/legend/Legend - LegendItem/flare/vis/legend/LegendItem - LegendRange/flare/vis/legend/LegendRange - distortion/flare/vis/operator/distortion - encoder/flare/vis/operator/encoder - filter/flare/vis/operator/filter - IOperator/flare/vis/operator/IOperator - label/flare/vis/operator/label - layout/flare/vis/operator/layout - Operator/flare/vis/operator/Operator - OperatorList/flare/vis/operator/OperatorList - OperatorSequence/flare/vis/operator/OperatorSequence - OperatorSwitch/flare/vis/operator/OperatorSwitch - SortOperator/flare/vis/operator/SortOperator + Easing/flare/animate/Easing + FunctionSequence/flare/animate/FunctionSequence + ISchedulable/flare/animate/ISchedulable + Parallel/flare/animate/Parallel + Pause/flare/animate/Pause + Scheduler/flare/animate/Scheduler + Sequence/flare/animate/Sequence + Transition/flare/animate/Transition + Transitioner/flare/animate/Transitioner + TransitionEvent/flare/animate/TransitionEvent + Tween/flare/animate/Tween + DataField/flare/data/DataField + DataSchema/flare/data/DataSchema + DataSet/flare/data/DataSet + DataSource/flare/data/DataSource + DataTable/flare/data/DataTable + DataUtil/flare/data/DataUtil + DirtySprite/flare/display/DirtySprite + LineSprite/flare/display/LineSprite + RectSprite/flare/display/RectSprite + TextSprite/flare/display/TextSprite + FlareVis/flare/flex/FlareVis + DragForce/flare/physics/DragForce + GravityForce/flare/physics/GravityForce + IForce/flare/physics/IForce + NBodyForce/flare/physics/NBodyForce + Particle/flare/physics/Particle + Simulation/flare/physics/Simulation + Spring/flare/physics/Spring + SpringForce/flare/physics/SpringForce + AggregateExpression/flare/query/AggregateExpression + And/flare/query/And + Arithmetic/flare/query/Arithmetic + Average/flare/query/Average + BinaryExpression/flare/query/BinaryExpression + Comparison/flare/query/Comparison + CompositeExpression/flare/query/CompositeExpression + Count/flare/query/Count + DateUtil/flare/query/DateUtil + Distinct/flare/query/Distinct + Expression/flare/query/Expression + ExpressionIterator/flare/query/ExpressionIterator + Fn/flare/query/Fn + If/flare/query/If + IsA/flare/query/IsA + Literal/flare/query/Literal + Match/flare/query/Match + Maximum/flare/query/Maximum + Minimum/flare/query/Minimum + Not/flare/query/Not + Or/flare/query/Or + Query/flare/query/Query + Range/flare/query/Range + StringUtil/flare/query/StringUtil + Sum/flare/query/Sum + Variable/flare/query/Variable + Variance/flare/query/Variance + Xor/flare/query/Xor + IScaleMap/flare/scale/IScaleMap + LinearScale/flare/scale/LinearScale + LogScale/flare/scale/LogScale + OrdinalScale/flare/scale/OrdinalScale + QuantileScale/flare/scale/QuantileScale + QuantitativeScale/flare/scale/QuantitativeScale + RootScale/flare/scale/RootScale + Scale/flare/scale/Scale + ScaleType/flare/scale/ScaleType + TimeScale/flare/scale/TimeScale + Arrays/flare/util/Arrays + Colors/flare/util/Colors + Dates/flare/util/Dates + Displays/flare/util/Displays + Filter/flare/util/Filter + Geometry/flare/util/Geometry + IEvaluable/flare/util/IEvaluable + IPredicate/flare/util/IPredicate + IValueProxy/flare/util/IValueProxy + Maths/flare/util/Maths + Orientation/flare/util/Orientation + Property/flare/util/Property + Shapes/flare/util/Shapes + Sort/flare/util/Sort + Stats/flare/util/Stats + Strings/flare/util/Strings + Visualization/flare/vis/Visualization + AgglomerativeCluster/flare/analytics/cluster/AgglomerativeCluster + CommunityStructure/flare/analytics/cluster/CommunityStructure + HierarchicalCluster/flare/analytics/cluster/HierarchicalCluster + MergeEdge/flare/analytics/cluster/MergeEdge + BetweennessCentrality/flare/analytics/graph/BetweennessCentrality + LinkDistance/flare/analytics/graph/LinkDistance + MaxFlowMinCut/flare/analytics/graph/MaxFlowMinCut + ShortestPaths/flare/analytics/graph/ShortestPaths + SpanningTree/flare/analytics/graph/SpanningTree + AspectRatioBanker/flare/analytics/optimization/AspectRatioBanker + ArrayInterpolator/flare/animate/interpolate/ArrayInterpolator + ColorInterpolator/flare/animate/interpolate/ColorInterpolator + DateInterpolator/flare/animate/interpolate/DateInterpolator + Interpolator/flare/animate/interpolate/Interpolator + MatrixInterpolator/flare/animate/interpolate/MatrixInterpolator + NumberInterpolator/flare/animate/interpolate/NumberInterpolator + ObjectInterpolator/flare/animate/interpolate/ObjectInterpolator + PointInterpolator/flare/animate/interpolate/PointInterpolator + RectangleInterpolator/flare/animate/interpolate/RectangleInterpolator + Converters/flare/data/converters/Converters + DelimitedTextConverter/flare/data/converters/DelimitedTextConverter + GraphMLConverter/flare/data/converters/GraphMLConverter + IDataConverter/flare/data/converters/IDataConverter + JSONConverter/flare/data/converters/JSONConverter + add/flare/query/methods/add + and/flare/query/methods/and + average/flare/query/methods/average + count/flare/query/methods/count + distinct/flare/query/methods/distinct + div/flare/query/methods/div + eq/flare/query/methods/eq + fn/flare/query/methods/fn + gt/flare/query/methods/gt + gte/flare/query/methods/gte + iff/flare/query/methods/iff + isa/flare/query/methods/isa + lt/flare/query/methods/lt + lte/flare/query/methods/lte + max/flare/query/methods/max + min/flare/query/methods/min + mod/flare/query/methods/mod + mul/flare/query/methods/mul + neq/flare/query/methods/neq + not/flare/query/methods/not + or/flare/query/methods/or + orderby/flare/query/methods/orderby + range/flare/query/methods/range + select/flare/query/methods/select + stddev/flare/query/methods/stddev + sub/flare/query/methods/sub + sum/flare/query/methods/sum + update/flare/query/methods/update + variance/flare/query/methods/variance + where/flare/query/methods/where + xor/flare/query/methods/xor + _/flare/query/methods/_ + FibonacciHeap/flare/util/heap/FibonacciHeap + HeapNode/flare/util/heap/HeapNode + DenseMatrix/flare/util/math/DenseMatrix + IMatrix/flare/util/math/IMatrix + SparseMatrix/flare/util/math/SparseMatrix + ColorPalette/flare/util/palette/ColorPalette + Palette/flare/util/palette/Palette + ShapePalette/flare/util/palette/ShapePalette + SizePalette/flare/util/palette/SizePalette + Axes/flare/vis/axis/Axes + Axis/flare/vis/axis/Axis + AxisGridLine/flare/vis/axis/AxisGridLine + AxisLabel/flare/vis/axis/AxisLabel + CartesianAxes/flare/vis/axis/CartesianAxes + AnchorControl/flare/vis/controls/AnchorControl + ClickControl/flare/vis/controls/ClickControl + Control/flare/vis/controls/Control + ControlList/flare/vis/controls/ControlList + DragControl/flare/vis/controls/DragControl + ExpandControl/flare/vis/controls/ExpandControl + HoverControl/flare/vis/controls/HoverControl + IControl/flare/vis/controls/IControl + PanZoomControl/flare/vis/controls/PanZoomControl + SelectionControl/flare/vis/controls/SelectionControl + TooltipControl/flare/vis/controls/TooltipControl + Data/flare/vis/data/Data + DataList/flare/vis/data/DataList + DataSprite/flare/vis/data/DataSprite + EdgeSprite/flare/vis/data/EdgeSprite + NodeSprite/flare/vis/data/NodeSprite + ScaleBinding/flare/vis/data/ScaleBinding + Tree/flare/vis/data/Tree + TreeBuilder/flare/vis/data/TreeBuilder + DataEvent/flare/vis/events/DataEvent + SelectionEvent/flare/vis/events/SelectionEvent + TooltipEvent/flare/vis/events/TooltipEvent + VisualizationEvent/flare/vis/events/VisualizationEvent + Legend/flare/vis/legend/Legend + LegendItem/flare/vis/legend/LegendItem + LegendRange/flare/vis/legend/LegendRange + IOperator/flare/vis/operator/IOperator + Operator/flare/vis/operator/Operator + OperatorList/flare/vis/operator/OperatorList + OperatorSequence/flare/vis/operator/OperatorSequence + OperatorSwitch/flare/vis/operator/OperatorSwitch + SortOperator/flare/vis/operator/SortOperator ArrowType/flare/vis/data/render/ArrowType EdgeRenderer/flare/vis/data/render/EdgeRenderer IRenderer/flare/vis/data/render/IRenderer @@ -526,4 +494,38 @@ StackedAreaLayout/flare/vis/operator/layout/StackedAreaLayout TreeMapLayout/flare/vis/operator/layout/TreeMapLayout + + flare/flare + analytics/flare/analytics + animate/flare/animate + data/flare/data + display/flare/display + flex/flare/flex + physics/flare/physics + query/flare/query + scale/flare/scale + util/flare/util + vis/flare/vis + cluster/flare/analytics/cluster + graph/flare/analytics/graph + optimization/flare/analytics/optimization + interpolate/flare/animate/interpolate + converters/flare/data/converters + methods/flare/query/methods + heap/flare/util/heap + math/flare/util/math + palette/flare/util/palette + axis/flare/vis/axis + controls/flare/vis/controls + data/flare/vis/data + events/flare/vis/events + legend/flare/vis/legend + operator/flare/vis/operator + render/flare/vis/data/render + distortion/flare/vis/operator/distortion + encoder/flare/vis/operator/encoder + filter/flare/vis/operator/filter + label/flare/vis/operator/label + layout/flare/vis/operator/layout + \ No newline at end of file diff --git a/test/output/frameFillCategorical.html b/test/output/frameFillCategorical.html index 09dec9776a..5880ec9571 100644 --- a/test/output/frameFillCategorical.html +++ b/test/output/frameFillCategorical.html @@ -1,4 +1,4 @@ -
+
- - - - - - - + + + + + + + - /Chaos - /Chaos/Eros - /Chaos/Erebus - /Chaos/Tartarus - /Chaos/Gaia + /Chaos + /Chaos/Eros + /Chaos/Erebus + /Chaos/Tartarus + /Chaos/Gaia /Chaos/Gaia/Mountains /Chaos/Gaia/Pontus /Chaos/Gaia/Uranus - Chaos/Chaos - Eros/Chaos/Eros - Erebus/Chaos/Erebus - Tartarus/Chaos/Tartarus - Gaia/Chaos/Gaia + Eros/Chaos/Eros + Erebus/Chaos/Erebus + Tartarus/Chaos/Tartarus Mountains/Chaos/Gaia/Mountains Pontus/Chaos/Gaia/Pontus Uranus/Chaos/Gaia/Uranus + + Chaos/Chaos + Gaia/Chaos/Gaia + \ No newline at end of file diff --git a/test/output/greekGodsTip.svg b/test/output/greekGodsTip.svg new file mode 100644 index 0000000000..212fbf4e05 --- /dev/null +++ b/test/output/greekGodsTip.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + Eros/Chaos/Eros + Erebus/Chaos/Erebus + Tartarus/Chaos/Tartarus + Mountains/Chaos/Gaia/Mountains + Pontus/Chaos/Gaia/Pontus + Uranus/Chaos/Gaia/Uranus + + + Chaos/Chaos + Gaia/Chaos/Gaia + + + \ No newline at end of file diff --git a/test/output/hexbinR.html b/test/output/hexbinR.html index 3f7144b913..0cfb6a423b 100644 --- a/test/output/hexbinR.html +++ b/test/output/hexbinR.html @@ -1,4 +1,4 @@ -
+
+ + H1 + + H2 + + H3 + + H4 +
+ + + + 2014 + + + 2015 + + + 2016 + + + 2017 + + + 2018 + + + 2019 + + + 2020 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + 2 + 3 + 4 + + + 0 + 1 + 2 + 3 + 4 + + + 0 + 1 + 2 + 3 + 4 + + + 0 + 1 + 2 + 3 + 4 + + + 0 + 1 + 2 + 3 + 4 + + + 0 + 1 + 2 + 3 + 4 + + + 0 + 1 + 2 + 3 + 4 + + + + rate (%) ↑ + + + + + + + + + + + + + + + + 2016 + 2018 + 2020 + 2022 + 2024 + 2026 + 2028 + 2030 + + + + about → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/test/output/likertSurvey.html b/test/output/likertSurvey.html index bafcad0b79..69e3096bba 100644 --- a/test/output/likertSurvey.html +++ b/test/output/likertSurvey.html @@ -1,4 +1,4 @@ -
+
+ + + + + + + + + + + + 0 + 5 + 10 + 15 + 20 + 25 + 30 + 35 + + + ↑ value + + + + + + + + + + + 0 + 2 + 4 + 6 + 8 + 10 + + + time → + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/pointerNonFaceted.svg b/test/output/pointerNonFaceted.svg new file mode 100644 index 0000000000..e3c7e45bdd --- /dev/null +++ b/test/output/pointerNonFaceted.svg @@ -0,0 +1,2623 @@ + + + + + false + + + true + + + + + + + + + + + + + + + + + + + + + + + + + 60 + 80 + 100 + 120 + 140 + 160 + 180 + + + 60 + 80 + 100 + 120 + 140 + 160 + 180 + + + + ↑ Close + + + + + + + + + + + + + 2014 + 2015 + 2016 + 2017 + 2018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/pointerRenderCompose.svg b/test/output/pointerRenderCompose.svg index dd0d1c367f..1557462e9c 100644 --- a/test/output/pointerRenderCompose.svg +++ b/test/output/pointerRenderCompose.svg @@ -53,7 +53,7 @@ culmen_length_mm → - + diff --git a/test/output/pointerViewof.html b/test/output/pointerViewof.html index decf83aef9..c5fb990f89 100644 --- a/test/output/pointerViewof.html +++ b/test/output/pointerViewof.html @@ -397,7 +397,7 @@ - +
\ No newline at end of file diff --git a/test/output/rasterCa55Barycentric.svg b/test/output/rasterCa55Barycentric.svg index 463c98d850..a252b93c47 100644 --- a/test/output/rasterCa55Barycentric.svg +++ b/test/output/rasterCa55Barycentric.svg @@ -14,6 +14,6 @@ } - + \ No newline at end of file diff --git a/test/output/rasterFacet.svg b/test/output/rasterFacet.svg new file mode 100644 index 0000000000..a339e632b3 --- /dev/null +++ b/test/output/rasterFacet.svg @@ -0,0 +1,88 @@ + + + + + 0 + + + 1 + + + + + + + + + + + + −1 + 0 + 1 + + + + + + + + + + + + + 0 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/rasterPenguinsBarycentric.svg b/test/output/rasterPenguinsBarycentric.svg index fb5f3197e5..1d3a0de8ee 100644 --- a/test/output/rasterPenguinsBarycentric.svg +++ b/test/output/rasterPenguinsBarycentric.svg @@ -66,7 +66,7 @@ body_mass_g → - + diff --git a/test/output/rasterPrecision.svg b/test/output/rasterPrecision.svg new file mode 100644 index 0000000000..58317959bb --- /dev/null +++ b/test/output/rasterPrecision.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + 350 + 300 + 250 + 200 + 150 + 100 + 50 + + + + + + + + + + + 100 + 200 + 300 + 400 + 500 + 600 + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/rasterVapor2.html b/test/output/rasterVapor2.html index 8fb782f84a..575486fac1 100644 --- a/test/output/rasterVapor2.html +++ b/test/output/rasterVapor2.html @@ -1,4 +1,4 @@ -
+
- + diff --git a/test/output/rasterWalmartBarycentricOpacity.svg b/test/output/rasterWalmartBarycentricOpacity.svg index 02629ee3da..a4517c0413 100644 --- a/test/output/rasterWalmartBarycentricOpacity.svg +++ b/test/output/rasterWalmartBarycentricOpacity.svg @@ -14,7 +14,7 @@ } - + diff --git a/test/output/seattlePrecipitationSum.svg b/test/output/seattlePrecipitationSum.svg index da4dfb089c..1585a8495c 100644 --- a/test/output/seattlePrecipitationSum.svg +++ b/test/output/seattlePrecipitationSum.svg @@ -62,17 +62,17 @@ - Fri 11 - Dec 13 - Tue 15 - Thu 17 - Sat 19 - Mon 21 - Wed 23 - Fri 25 - Dec 27 - Tue 29 - Thu 31 + 11Dec + 13 + 15 + 17 + 19 + 21 + 23 + 25 + 27 + 29 + 31 diff --git a/test/output/seattleTemperatureAmplitude.html b/test/output/seattleTemperatureAmplitude.html index 9a11e575a6..4ca71f952a 100644 --- a/test/output/seattleTemperatureAmplitude.html +++ b/test/output/seattleTemperatureAmplitude.html @@ -1,4 +1,4 @@ -
+
- April - July - October - 2021 - April - July + Apr2020 + Jul + Oct + Jan2021 + Apr + Jul specimen_collection_date → diff --git a/test/output/sfTemperatureBand.svg b/test/output/sfTemperatureBand.svg index 5538505657..395e0ea167 100644 --- a/test/output/sfTemperatureBand.svg +++ b/test/output/sfTemperatureBand.svg @@ -61,15 +61,15 @@ - October - 2011 - April - July - October - 2012 - April - July - October + Oct2010 + Jan2011 + Apr + Jul + Oct + Jan2012 + Apr + Jul + Oct diff --git a/test/output/sfTemperatureBandArea.svg b/test/output/sfTemperatureBandArea.svg index c109fd42ac..f55308e19a 100644 --- a/test/output/sfTemperatureBandArea.svg +++ b/test/output/sfTemperatureBandArea.svg @@ -79,15 +79,15 @@ - October - 2011 - April - July - October - 2012 - April - July - October + Oct2010 + Jan2011 + Apr + Jul + Oct + Jan2012 + Apr + Jul + Oct diff --git a/test/output/sfTemperatureWindow.svg b/test/output/sfTemperatureWindow.svg new file mode 100644 index 0000000000..32e1398581 --- /dev/null +++ b/test/output/sfTemperatureWindow.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 38 + 40 + 42 + 44 + 46 + 48 + 50 + 52 + 54 + 56 + 58 + 60 + 62 + + + ↑ Temperature (°F) + + + + + + + + + + + + + + Oct2010 + Jan2011 + Apr + Jul + Oct + Jan2012 + Apr + Jul + Oct + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/shorthandArea.svg b/test/output/shorthandArea.svg index ad3565ece5..016d698ab2 100644 --- a/test/output/shorthandArea.svg +++ b/test/output/shorthandArea.svg @@ -46,14 +46,14 @@ - Jan 07 - Jan 14 - Jan 21 - Jan 28 - Feb 04 - Feb 11 - Feb 18 - Feb 25 + 7Jan + 14 + 21 + 28 + 4Feb + 11 + 18 + 25 diff --git a/test/output/shorthandDot.svg b/test/output/shorthandDot.svg index f9548f1faf..2b8dfb76a4 100644 --- a/test/output/shorthandDot.svg +++ b/test/output/shorthandDot.svg @@ -52,14 +52,14 @@ - Jan 07 - Jan 14 - Jan 21 - Jan 28 - Feb 04 - Feb 11 - Feb 18 - Feb 25 + 7Jan + 14 + 21 + 28 + 4Feb + 11 + 18 + 25 diff --git a/test/output/shorthandLine.svg b/test/output/shorthandLine.svg index ccfa5c0ed0..967e97d799 100644 --- a/test/output/shorthandLine.svg +++ b/test/output/shorthandLine.svg @@ -52,14 +52,14 @@ - Jan 07 - Jan 14 - Jan 21 - Jan 28 - Feb 04 - Feb 11 - Feb 18 - Feb 25 + 7Jan + 14 + 21 + 28 + 4Feb + 11 + 18 + 25 diff --git a/test/output/shorthandText.svg b/test/output/shorthandText.svg index 7e8b1a4bbe..7b9a6c043b 100644 --- a/test/output/shorthandText.svg +++ b/test/output/shorthandText.svg @@ -52,14 +52,14 @@ - Jan 07 - Jan 14 - Jan 21 - Jan 28 - Feb 04 - Feb 11 - Feb 18 - Feb 25 + 7Jan + 14 + 21 + 28 + 4Feb + 11 + 18 + 25 0 diff --git a/test/output/shorthandVector.svg b/test/output/shorthandVector.svg index e96509c09e..a0be321182 100644 --- a/test/output/shorthandVector.svg +++ b/test/output/shorthandVector.svg @@ -52,14 +52,14 @@ - Jan 07 - Jan 14 - Jan 21 - Jan 28 - Feb 04 - Feb 11 - Feb 18 - Feb 25 + 7Jan + 14 + 21 + 28 + 4Feb + 11 + 18 + 25 diff --git a/test/output/simpsonsViews.html b/test/output/simpsonsViews.html index 4c9f211dcc..7a2bfb4631 100644 --- a/test/output/simpsonsViews.html +++ b/test/output/simpsonsViews.html @@ -1,4 +1,4 @@ -
+
- December - 2021 - February - March - April + Dec2020 + Jan2021 + Feb + Mar + Apr May - June + Jun diff --git a/test/output/stargazersBinned.svg b/test/output/stargazersBinned.svg index b85fbac89e..66b295ca41 100644 --- a/test/output/stargazersBinned.svg +++ b/test/output/stargazersBinned.svg @@ -72,14 +72,14 @@ - November - December - 2021 - February - March - April + Nov2020 + Dec + Jan2021 + Feb + Mar + Apr May - June + Jun 2020-11-01 to 2020-11-08 diff --git a/test/output/timeAxisBottom.svg b/test/output/timeAxisBottom.svg new file mode 100644 index 0000000000..9a4d080945 --- /dev/null +++ b/test/output/timeAxisBottom.svg @@ -0,0 +1,1386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .000:00:00 + .100 + .200 + .300 + .400 + .500 + .600 + .700 + .800 + .900 + .000:00:01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .000:00:00 + .500 + .000:00:01 + .500 + .000:00:02 + .500 + .000:00:03 + .500 + .000:00:04 + .500 + .000:00:05 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :0012:00 + :01 + :02 + :03 + :04 + :05 + :06 + :07 + :08 + :09 + :10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :0012:00 + :05 + :10 + :15 + :20 + :25 + :30 + :35 + :40 + :45 + :50 + :55 + :0012:01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + :0012:00 + :15 + :30 + :45 + :0012:01 + :15 + :30 + :45 + :0012:02 + + + + + + + + + + + + + + + + + + + + + + + + + + + + :0012:00 + :30 + :0012:01 + :30 + :0012:02 + :30 + :0012:03 + :30 + :0012:04 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:01 + 12:02 + 12:03 + 12:04 + 12:05 + 12:06 + 12:07 + 12:08 + 12:09 + 12:10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:05 + 12:10 + 12:15 + 12:20 + 12:25 + 12:30 + 12:35 + 12:40 + 12:45 + 12:50 + 12:55 + 1:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:15 + 12:30 + 12:45 + 1:00 + 1:15 + 1:30 + 1:45 + 2:00 + 2:15 + 2:30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:30 + 1:00 + 1:30 + 2:00 + 2:30 + 3:00 + 3:30 + 4:00 + 4:30 + 5:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10:00AM + 10:30 + 11:00 + 11:30 + 12:00PM + 12:30 + 1:00 + 1:30 + 2:00 + 2:30 + 3:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 1 + 1 AM + 2 AM + 3 AM + 4 AM + 5 AM + 6 AM + 7 AM + 8 AM + 9 AM + 10 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 1 + 3 AM + 6 AM + 9 AM + 12 PM + 3 PM + 6 PM + 9 PM + 12 AMJan 2 + 3 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 1 + 6 AM + 12 PM + 6 PM + 12 AMJan 2 + 6 AM + 12 PM + 6 PM + 12 AMJan 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 1 + 12 PM + 12 AMJan 2 + 12 PM + 12 AMJan 3 + 12 PM + 12 AMJan 4 + 12 PM + 12 AMJan 5 + + + + + + + + + + + + + + + + + + + + + + + + 5Jan + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1Jan + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1Jan + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21 + 23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 17Jan + 19 + 21 + 23 + 25 + 27 + 29 + 31 + 2Feb + 4 + 6 + 8 + 10 + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1Jan + 8 + 15 + 22 + 29 + 5Feb + 12 + 19 + 26 + 5Mar + 12 + 19 + 26 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan2023 + Feb + Mar + Apr + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + Jan2024 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Apr2023 + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + Jan2024 + Feb + Mar + Apr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan2023 + Apr + Jul + Oct + Jan2024 + Apr + Jul + Oct + Jan2025 + Apr + Jul + Oct + Jan2026 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023 + 2024 + 2025 + 2026 + 2027 + 2028 + 2029 + 2030 + 2031 + 2032 + 2033 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2020 + 2025 + 2030 + 2035 + 2040 + 2045 + 2050 + 2055 + 2060 + 2065 + 2070 + + + \ No newline at end of file diff --git a/test/output/timeAxisExplicitInterval.svg b/test/output/timeAxisExplicitInterval.svg new file mode 100644 index 0000000000..ec925189ec --- /dev/null +++ b/test/output/timeAxisExplicitInterval.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + 0 + 20 + 40 + 60 + 80 + 100 + 120 + 140 + 160 + 180 + + + ↑ Close + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jul2013 + Oct + Jan2014 + Apr + Jul + Oct + Jan2015 + Apr + Jul + Oct + Jan2016 + Apr + Jul + Oct + Jan2017 + Apr + Jul + Oct + Jan2018 + Apr + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/timeAxisLeft.svg b/test/output/timeAxisLeft.svg new file mode 100644 index 0000000000..868e69fa0a --- /dev/null +++ b/test/output/timeAxisLeft.svg @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .000:00:00 + .100 + .200 + .300 + .400 + .500 + .600 + .700 + .800 + .900 + .000:00:01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :0012:00 + :05 + :10 + :15 + :20 + :25 + :30 + :35 + :40 + :45 + :50 + :55 + :0012:01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:01 + 12:02 + 12:03 + 12:04 + 12:05 + 12:06 + 12:07 + 12:08 + 12:09 + 12:10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:30 + 1:00 + 1:30 + 2:00 + 2:30 + 3:00 + 3:30 + 4:00 + 4:30 + 5:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 1 + 3 AM + 6 AM + 9 AM + 12 PM + 3 PM + 6 PM + 9 PM + 12 AMJan 2 + 3 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 5 + 12 PM + 12 AMJan 6 + 12 PM + 12 AMJan 7 + 12 PM + 12 AMJan 8 + 12 PM + 12 AMJan 9 + 12 PM + 12 AMJan 10 + 12 PM + 12 AMJan 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 17Jan + 19 + 21 + 23 + 25 + 27 + 29 + 31 + 2Feb + 4 + 6 + 8 + 10 + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Apr2023 + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + Jan2024 + Feb + Mar + Apr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2020 + 2025 + 2030 + 2035 + 2040 + 2045 + 2050 + 2055 + 2060 + 2065 + 2070 + + + \ No newline at end of file diff --git a/test/output/timeAxisRight.svg b/test/output/timeAxisRight.svg new file mode 100644 index 0000000000..c745687eb1 --- /dev/null +++ b/test/output/timeAxisRight.svg @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .000:00:00 + .100 + .200 + .300 + .400 + .500 + .600 + .700 + .800 + .900 + .000:00:01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :0012:00 + :05 + :10 + :15 + :20 + :25 + :30 + :35 + :40 + :45 + :50 + :55 + :0012:01 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:01 + 12:02 + 12:03 + 12:04 + 12:05 + 12:06 + 12:07 + 12:08 + 12:09 + 12:10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00AM + 12:30 + 1:00 + 1:30 + 2:00 + 2:30 + 3:00 + 3:30 + 4:00 + 4:30 + 5:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 1 + 3 AM + 6 AM + 9 AM + 12 PM + 3 PM + 6 PM + 9 PM + 12 AMJan 2 + 3 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 AMJan 5 + 12 PM + 12 AMJan 6 + 12 PM + 12 AMJan 7 + 12 PM + 12 AMJan 8 + 12 PM + 12 AMJan 9 + 12 PM + 12 AMJan 10 + 12 PM + 12 AMJan 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 17Jan + 19 + 21 + 23 + 25 + 27 + 29 + 31 + 2Feb + 4 + 6 + 8 + 10 + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Apr2023 + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + Jan2024 + Feb + Mar + Apr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2020 + 2025 + 2030 + 2035 + 2040 + 2045 + 2050 + 2055 + 2060 + 2065 + 2070 + + + \ No newline at end of file diff --git a/test/output/timeAxisTop.svg b/test/output/timeAxisTop.svg new file mode 100644 index 0000000000..07030bbaee --- /dev/null +++ b/test/output/timeAxisTop.svg @@ -0,0 +1,1386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :00:00.000 + .100 + .200 + .300 + .400 + .500 + .600 + .700 + .800 + .900 + :00:01.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :00:00.000 + .500 + :00:01.000 + .500 + :00:02.000 + .500 + :00:03.000 + .500 + :00:04.000 + .500 + :00:05.000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00:00 + :01 + :02 + :03 + :04 + :05 + :06 + :07 + :08 + :09 + :10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00:00 + :05 + :10 + :15 + :20 + :25 + :30 + :35 + :40 + :45 + :50 + :55 + 12:01:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00:00 + :15 + :30 + :45 + 12:01:00 + :15 + :30 + :45 + 12:02:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12:00:00 + :30 + 12:01:00 + :30 + 12:02:00 + :30 + 12:03:00 + :30 + 12:04:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AM12:00 + 12:01 + 12:02 + 12:03 + 12:04 + 12:05 + 12:06 + 12:07 + 12:08 + 12:09 + 12:10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AM12:00 + 12:05 + 12:10 + 12:15 + 12:20 + 12:25 + 12:30 + 12:35 + 12:40 + 12:45 + 12:50 + 12:55 + 1:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AM12:00 + 12:15 + 12:30 + 12:45 + 1:00 + 1:15 + 1:30 + 1:45 + 2:00 + 2:15 + 2:30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AM12:00 + 12:30 + 1:00 + 1:30 + 2:00 + 2:30 + 3:00 + 3:30 + 4:00 + 4:30 + 5:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AM10:00 + 10:30 + 11:00 + 11:30 + PM12:00 + 12:30 + 1:00 + 1:30 + 2:00 + 2:30 + 3:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan 112 AM + 1 AM + 2 AM + 3 AM + 4 AM + 5 AM + 6 AM + 7 AM + 8 AM + 9 AM + 10 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan 112 AM + 3 AM + 6 AM + 9 AM + 12 PM + 3 PM + 6 PM + 9 PM + Jan 212 AM + 3 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan 112 AM + 6 AM + 12 PM + 6 PM + Jan 212 AM + 6 AM + 12 PM + 6 PM + Jan 312 AM + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan 112 AM + 12 PM + Jan 212 AM + 12 PM + Jan 312 AM + 12 PM + Jan 412 AM + 12 PM + Jan 512 AM + + + + + + + + + + + + + + + + + + + + + + + + Jan5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 + 21 + 23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan17 + 19 + 21 + 23 + 25 + 27 + 29 + 31 + Feb2 + 4 + 6 + 8 + 10 + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Jan1 + 8 + 15 + 22 + 29 + Feb5 + 12 + 19 + 26 + Mar5 + 12 + 19 + 26 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023Jan + Feb + Mar + Apr + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + 2024Jan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023Apr + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + 2024Jan + Feb + Mar + Apr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023Jan + Apr + Jul + Oct + 2024Jan + Apr + Jul + Oct + 2025Jan + Apr + Jul + Oct + 2026Jan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2023 + 2024 + 2025 + 2026 + 2027 + 2028 + 2029 + 2030 + 2031 + 2032 + 2033 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2020 + 2025 + 2030 + 2035 + 2040 + 2045 + 2050 + 2055 + 2060 + 2065 + 2070 + + + \ No newline at end of file diff --git a/test/output/tipAreaBand.svg b/test/output/tipAreaBand.svg new file mode 100644 index 0000000000..9ad11da81c --- /dev/null +++ b/test/output/tipAreaBand.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + 60 + 70 + 80 + 90 + 100 + 110 + 120 + 130 + 140 + 150 + 160 + 170 + 180 + 190 + + + + + + + + + + 2014 + 2015 + 2016 + 2017 + 2018 + + + + + + \ No newline at end of file diff --git a/test/output/tipAreaStack.svg b/test/output/tipAreaStack.svg index 768d2891e2..9e109a2acb 100644 --- a/test/output/tipAreaStack.svg +++ b/test/output/tipAreaStack.svg @@ -68,5 +68,5 @@ - +
\ No newline at end of file diff --git a/test/output/tipBar.svg b/test/output/tipBar.svg index 89403a504b..e470216044 100644 --- a/test/output/tipBar.svg +++ b/test/output/tipBar.svg @@ -123,5 +123,5 @@ - +
\ No newline at end of file diff --git a/test/output/tipBin.svg b/test/output/tipBin.svg index 5a315ad72c..d990379108 100644 --- a/test/output/tipBin.svg +++ b/test/output/tipBin.svg @@ -138,5 +138,5 @@ - + \ No newline at end of file diff --git a/test/output/tipBinStack.svg b/test/output/tipBinStack.svg index 9d96f3d16d..b1c2f8d138 100644 --- a/test/output/tipBinStack.svg +++ b/test/output/tipBinStack.svg @@ -185,5 +185,5 @@ - + \ No newline at end of file diff --git a/test/output/tipCell.svg b/test/output/tipCell.svg index 5c72903d12..5b5a26b979 100644 --- a/test/output/tipCell.svg +++ b/test/output/tipCell.svg @@ -145,5 +145,5 @@ - + \ No newline at end of file diff --git a/test/output/tipCellFacet.svg b/test/output/tipCellFacet.svg index 06b40c5f6f..7dac76253b 100644 --- a/test/output/tipCellFacet.svg +++ b/test/output/tipCellFacet.svg @@ -154,7 +154,7 @@ - - + + \ No newline at end of file diff --git a/test/output/tipDodge.svg b/test/output/tipDodge.svg index 3127891ebb..17f977cc2d 100644 --- a/test/output/tipDodge.svg +++ b/test/output/tipDodge.svg @@ -374,5 +374,5 @@ - + \ No newline at end of file diff --git a/test/output/tipDot.svg b/test/output/tipDot.svg index 1991c3a98c..ced1791ba3 100644 --- a/test/output/tipDot.svg +++ b/test/output/tipDot.svg @@ -397,5 +397,5 @@ - + \ No newline at end of file diff --git a/test/output/tipDotFacets.svg b/test/output/tipDotFacets.svg index 34b727ba82..94af127248 100644 --- a/test/output/tipDotFacets.svg +++ b/test/output/tipDotFacets.svg @@ -11214,12 +11214,12 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/test/output/tipDotFilter.svg b/test/output/tipDotFilter.svg index 172bb3ef50..ec1742bfbe 100644 --- a/test/output/tipDotFilter.svg +++ b/test/output/tipDotFilter.svg @@ -390,6 +390,6 @@ - - + + \ No newline at end of file diff --git a/test/output/tipDotX.svg b/test/output/tipDotX.svg index 1f683a4786..814b20bd57 100644 --- a/test/output/tipDotX.svg +++ b/test/output/tipDotX.svg @@ -49,5 +49,5 @@ - + \ No newline at end of file diff --git a/test/output/tipFacetX.svg b/test/output/tipFacetX.svg new file mode 100644 index 0000000000..2625017782 --- /dev/null +++ b/test/output/tipFacetX.svg @@ -0,0 +1,201 @@ + + + + + a + + + b + + + + f + + + + + + + + + + + + + + + + + + 0 + 2 + 4 + 6 + + + 0 + 2 + 4 + 6 + + + + ↑ y + + + + + + + + + + + + + 0 + 20 + 40 + 60 + 80 + + + + x → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/tipGeoCentroid.svg b/test/output/tipGeoCentroid.svg index 462df284b3..11275c03b4 100644 --- a/test/output/tipGeoCentroid.svg +++ b/test/output/tipGeoCentroid.svg @@ -16,6 +16,6 @@ - - + + \ No newline at end of file diff --git a/test/output/tipGeoNoProjection.svg b/test/output/tipGeoNoProjection.svg new file mode 100644 index 0000000000..7cff830917 --- /dev/null +++ b/test/output/tipGeoNoProjection.svg @@ -0,0 +1,3170 @@ + + + + + + + + + + + + + + + + + + 26 + 28 + 30 + 32 + 34 + 36 + 38 + 40 + 42 + 44 + 46 + 48 + + + + + + + + + + + −120 + −110 + −100 + −90 + −80 + −70 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/tipGeoProjection.svg b/test/output/tipGeoProjection.svg new file mode 100644 index 0000000000..761e0d81b7 --- /dev/null +++ b/test/output/tipGeoProjection.svg @@ -0,0 +1,3126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/tipGroupPrimitives.svg b/test/output/tipGroupPrimitives.svg index 5c08a8e086..2307a9eb1e 100644 --- a/test/output/tipGroupPrimitives.svg +++ b/test/output/tipGroupPrimitives.svg @@ -60,5 +60,5 @@ - + \ No newline at end of file diff --git a/test/output/tipHexbin.svg b/test/output/tipHexbin.svg index 2e6d1ea5f5..9df33103d3 100644 --- a/test/output/tipHexbin.svg +++ b/test/output/tipHexbin.svg @@ -302,5 +302,5 @@ - + \ No newline at end of file diff --git a/test/output/tipHexbinExplicit.svg b/test/output/tipHexbinExplicit.svg index f4ca6b4cc8..1b8bb17266 100644 --- a/test/output/tipHexbinExplicit.svg +++ b/test/output/tipHexbinExplicit.svg @@ -302,5 +302,5 @@ - + \ No newline at end of file diff --git a/test/output/tipLine.svg b/test/output/tipLine.svg index 4a1d9412d9..c4a3187007 100644 --- a/test/output/tipLine.svg +++ b/test/output/tipLine.svg @@ -65,5 +65,5 @@ - + \ No newline at end of file diff --git a/test/output/tipRaster.svg b/test/output/tipRaster.svg index 66a9e730af..b680582935 100644 --- a/test/output/tipRaster.svg +++ b/test/output/tipRaster.svg @@ -16,5 +16,5 @@ - + \ No newline at end of file diff --git a/test/output/tipRule.svg b/test/output/tipRule.svg index 99b687131f..2e4c4fe4f6 100644 --- a/test/output/tipRule.svg +++ b/test/output/tipRule.svg @@ -378,5 +378,5 @@ - + \ No newline at end of file diff --git a/test/output/tipRuleAnchored.svg b/test/output/tipRuleAnchored.svg index e077cfcc19..db381ae45b 100644 --- a/test/output/tipRuleAnchored.svg +++ b/test/output/tipRuleAnchored.svg @@ -378,5 +378,5 @@ - + \ No newline at end of file diff --git a/test/output/tipTransform.html b/test/output/tipTransform.html index f3e1362aec..6418046b69 100644 --- a/test/output/tipTransform.html +++ b/test/output/tipTransform.html @@ -1,4 +1,4 @@ -
+
\ No newline at end of file diff --git a/test/output/title.html b/test/output/title.html new file mode 100644 index 0000000000..42281deb04 --- /dev/null +++ b/test/output/title.html @@ -0,0 +1,417 @@ +
+

A title about penguins

+

A subtitle about body_mass_g

+
+ + + Adelie + + Chinstrap + + Gentoo +
+ + + + + + + + + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + + + body_mass_g → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/test/output/titleHtml.html b/test/output/titleHtml.html new file mode 100644 index 0000000000..81d78a1c95 --- /dev/null +++ b/test/output/titleHtml.html @@ -0,0 +1,384 @@ +
+

A fancy title about penguins

+ A fancy subtitle + + + + + + + + + + + + 3,000 + 3,500 + 4,000 + 4,500 + 5,000 + 5,500 + 6,000 + + + body_mass_g → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/test/output/trafficHorizon.html b/test/output/trafficHorizon.html index bb11d9b198..14013e3bb2 100644 --- a/test/output/trafficHorizon.html +++ b/test/output/trafficHorizon.html @@ -1,4 +1,4 @@ -
+
- - - - - - - - - - - - - - - - - - - Mon 04 - 12 PM - Tue 05 - 12 PM - Wed 06 - 12 PM - Thu 07 - 12 PM - Fri 08 - 12 PM - Sat 09 - 12 PM - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - Von der Heydt + Von der Heydt - Kirschheck + Kirschheck - Saarbrücken-Neuhaus + Saarbrücken-Neuhaus - Riegelsberg + Riegelsberg - Holz + Holz - Göttelborn + Göttelborn - Illingen + Illingen - AS Eppelborn + AS Eppelborn - Hasborn + Hasborn - Kastel + Kastel - Otzenhausen + Otzenhausen - Bierfeld + Bierfeld - Nonnweiler + Nonnweiler - Hetzerath + Hetzerath - Laufeld + Laufeld - Nettersheim + Nettersheim - Euskirchen/Bliesheim + Euskirchen/Bliesheim - Hürth + Hürth - Köln-Nord + Köln-Nord - Schloss Burg + Schloss Burg - Hagen-Vorhalle + Hagen-Vorhalle - Hengsen + Hengsen - Unna + Unna - Ascheberg + Ascheberg - Ladbergen + Ladbergen - Lotte + Lotte - HB-Silbersee + HB-Silbersee - HB-Weserbrücke + HB-Weserbrücke - HB-Mahndorfer See + HB-Mahndorfer See - Groß Ippener + Groß Ippener - Uphusen + Uphusen - Bockel + Bockel - Dibbersen + Dibbersen - Glüsingen + Glüsingen - Barsbüttel + Barsbüttel - Bad Schwartau + Bad Schwartau - Oldenburg (Holstein) + Oldenburg (Holstein) - Neustadt i. H.-Süd + Neustadt i. H.-Süd + + + + + + + + + + + + + + + + + + + + 12 PM + Jan 512 AM + 12 PM + Jan 612 AM + 12 PM + Jan 712 AM + 12 PM + Jan 812 AM + 12 PM + Jan 912 AM + 12 PM diff --git a/test/output/travelersCovidDrop.svg b/test/output/travelersCovidDrop.svg index bb821a9386..bb5c75e408 100644 --- a/test/output/travelersCovidDrop.svg +++ b/test/output/travelersCovidDrop.svg @@ -65,16 +65,16 @@ - March - April + Mar2020 + Apr May - June - July - August - September - October - November - December + Jun + Jul + Aug + Sep + Oct + Nov + Dec diff --git a/test/output/travelersYearOverYear.svg b/test/output/travelersYearOverYear.svg index df259a5e29..8ec3bbcab5 100644 --- a/test/output/travelersYearOverYear.svg +++ b/test/output/travelersYearOverYear.svg @@ -83,16 +83,16 @@ - March - April + Mar2020 + Apr May - June - July - August - September - October - November - December + Jun + Jul + Aug + Sep + Oct + Nov + Dec diff --git a/test/output/usCountyChoropleth.html b/test/output/usCountyChoropleth.html index 61fe5ba2d3..51dc58f4c6 100644 --- a/test/output/usCountyChoropleth.html +++ b/test/output/usCountyChoropleth.html @@ -1,4 +1,4 @@ -
+
diff --git a/test/plots/index.ts b/test/plots/index.ts index 15ade2348a..65c6cfb5c6 100644 --- a/test/plots/index.ts +++ b/test/plots/index.ts @@ -8,6 +8,7 @@ export * from "./aapl-monthly.js"; export * from "./aapl-volume-rect.js"; export * from "./aapl-volume.js"; export * from "./anscombe-quartet.js"; +export * from "./arc.js"; export * from "./armadillo.js"; export * from "./aspectRatio.js"; export * from "./athletes-bins-colors.js"; @@ -27,6 +28,7 @@ export * from "./athletes-weight-cumulative.js"; export * from "./athletes-weight.js"; export * from "./autoplot.js"; export * from "./availability.js"; +export * from "./axis-filter.js"; export * from "./axis-labels.js"; export * from "./ballot-status-race.js"; export * from "./band-clip.js"; @@ -48,7 +50,7 @@ export * from "./cars-parcoords.js"; export * from "./channel-domain.js"; export * from "./clamp.js"; export * from "./collapsed-histogram.js"; -export * from "./color-misaligned.js"; +export * from "./color-piecewise.js"; export * from "./country-centroids.js"; export * from "./covid-ihme-projected-deaths.js"; export * from "./crimean-war-arrow.js"; @@ -206,6 +208,7 @@ export * from "./penguin-species-island-sex.js"; export * from "./penguin-species-island.js"; export * from "./penguin-species.js"; export * from "./penguin-voronoi-1d.js"; +export * from "./pointer-linked.js"; export * from "./pointer.js"; export * from "./polylinear.js"; export * from "./population-by-latitude.js"; @@ -232,6 +235,7 @@ export * from "./random-quantile.js"; export * from "./random-walk.js"; export * from "./raster-ca55.js"; export * from "./raster-penguins.js"; +export * from "./raster-precision.js"; export * from "./raster-vapor.js"; export * from "./raster-walmart.js"; export * from "./rect-band.js"; @@ -245,6 +249,7 @@ export * from "./seattle-temperature-cell.js"; export * from "./sf-covid-deaths.js"; export * from "./sf-temperature-band-area.js"; export * from "./sf-temperature-band.js"; +export * from "./sf-temperature-window.js"; export * from "./shorthand-area.js"; export * from "./shorthand-areaY.js"; export * from "./shorthand-barY.js"; @@ -271,6 +276,7 @@ export * from "./single-value-bar.js"; export * from "./single-value-bin.js"; export * from "./software-versions.js"; export * from "./sparse-cell.js"; +export * from "./sparse-title.js"; export * from "./stacked-bar.js"; export * from "./stacked-rect.js"; export * from "./stargazers-binned.js"; @@ -280,7 +286,9 @@ export * from "./stargazers.js"; export * from "./stocks-index.js"; export * from "./text-overflow.js"; export * from "./this-is-just-to-say.js"; +export * from "./time-axis.js"; export * from "./tip.js"; +export * from "./title.js"; export * from "./traffic-horizon.js"; export * from "./travelers-covid-drop.js"; export * from "./travelers-year-over-year.js"; @@ -310,6 +318,7 @@ export * from "./walmarts-decades.js"; export * from "./walmarts-density-unprojected.js"; export * from "./walmarts-density.js"; export * from "./walmarts.js"; +export * from "./warn-misaligned-diverging.js"; export * from "./wealth-britain-bar.js"; export * from "./wealth-britain-proportion-plot.js"; export * from "./word-cloud.js"; diff --git a/test/plots/libor-projections.ts b/test/plots/libor-projections.ts index 78001de3e6..ea8f24a512 100644 --- a/test/plots/libor-projections.ts +++ b/test/plots/libor-projections.ts @@ -24,3 +24,23 @@ export async function liborProjections() { y: {grid: true, line: true} }); } + +export async function liborProjectionsFacet() { + const libor = await d3.csv("data/libor-projections.csv", d3.autoType); + return Plot.plot({ + fy: {tickFormat: "d"}, + y: {percent: true, nice: true, grid: true, axis: "right", label: "rate (%)"}, + color: {legend: true}, + marks: [ + Plot.frame(), + Plot.lineY(libor, { + markerStart: true, + fy: (d) => d.on.getFullYear(), + x: "about", + stroke: (d) => "H" + (1 + d3.utcMonth.count(d3.utcYear(d.on), d.on)) / 3, + y: "value", + tip: true + }) + ] + }); +} diff --git a/test/plots/pointer-linked.ts b/test/plots/pointer-linked.ts new file mode 100644 index 0000000000..b5852fcba7 --- /dev/null +++ b/test/plots/pointer-linked.ts @@ -0,0 +1,16 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function pointerLinkedRectInterval() { + const a = d3.range(10).map((i) => ({series: "A", time: i, value: 15 + i - 0.3 * (i * i)})); + const b = d3.range(12).map((i) => ({series: "B", time: i, value: 12 * i - i * i})); + const round = {floor: (x) => Math.floor(x) - 0.5, offset: (x) => x + 1}; + const series = [...a, ...b]; + return Plot.plot({ + marks: [ + Plot.rect(series, Plot.pointerX({x: "time", interval: round, fillOpacity: 0.1})), + Plot.lineY(series, {stroke: "series", x: "time", y: "value", marker: true, curve: "natural"}), + Plot.arrow(series, Plot.pointerX(Plot.groupX({y1: "min", y2: "max"}, {x: "time", y: "value", inset: 10}))) + ] + }); +} diff --git a/test/plots/pointer.ts b/test/plots/pointer.ts index d6ea70904a..1e9df45067 100644 --- a/test/plots/pointer.ts +++ b/test/plots/pointer.ts @@ -34,3 +34,14 @@ export async function pointerViewof() { plot.oninput = oninput; // update during interaction return html`
${plot}${textarea}
`; } + +export async function pointerNonFaceted() { + const aapl = await d3.csv("data/aapl.csv", d3.autoType); + return Plot.plot({ + marks: [ + Plot.lineY(aapl, {x: "Date", y: "Close", fy: (d) => d.Close % 2 === 0}), + Plot.ruleX(aapl, {x: "Date", strokeOpacity: 0.1}), + Plot.ruleX(aapl, Plot.pointerX({x: "Date", stroke: "red"})) + ] + }); +} diff --git a/test/plots/raster-precision.ts b/test/plots/raster-precision.ts new file mode 100644 index 0000000000..b0ae134dd2 --- /dev/null +++ b/test/plots/raster-precision.ts @@ -0,0 +1,40 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +// Test for floating point precision issue in interpolateBarycentric. +export async function rasterPrecision() { + const data = d3.range(4).map((i) => { + const x = i % 2; + const y = Math.floor(i / 2); + return [49.4 + 100 * (x + y), 150.4 + 100 * (x - y)]; + }); + return Plot.plot({ + x: {type: "identity"}, + y: {type: "identity"}, + color: {scheme: "Sinebow"}, + marks: [ + Plot.raster(data, { + fill: (d, i) => i, + interpolate: "barycentric" + }), + Plot.dot(data, {fill: (d, i) => i, stroke: "white"}) + ] + }); +} + +export async function rasterFacet() { + const points = d3.range(0, 2 * Math.PI, Math.PI / 10).map((d) => [Math.cos(d), Math.sin(d)]); + return Plot.plot({ + aspectRatio: 1, + inset: 100, + color: {scheme: "Sinebow"}, + marks: [ + Plot.raster(points, { + fill: "0", + fx: (d, i) => i % 2, + interpolate: "barycentric" + }), + Plot.dot(points, {fx: (d, i) => i % 2, fill: "0", stroke: "white"}) + ] + }); +} diff --git a/test/plots/sf-temperature-window.ts b/test/plots/sf-temperature-window.ts new file mode 100644 index 0000000000..23d175d488 --- /dev/null +++ b/test/plots/sf-temperature-window.ts @@ -0,0 +1,18 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function sfTemperatureWindow() { + const sftemp = await d3.csv("data/sf-temperatures.csv", d3.autoType); + return Plot.plot({ + y: { + grid: true, + label: "Temperature (°F)" + }, + marks: [ + Plot.lineY(sftemp, {x: "date", y: "low", strokeOpacity: 0.3}), + Plot.lineY(sftemp, Plot.windowY({k: 28, reduce: "min"}, {x: "date", y: "low", stroke: "blue"})), + Plot.lineY(sftemp, Plot.windowY({k: 28, reduce: "max"}, {x: "date", y: "low", stroke: "red"})), + Plot.lineY(sftemp, Plot.windowY({k: 28, reduce: "median"}, {x: "date", y: "low"})) + ] + }); +} diff --git a/test/plots/sparse-title.ts b/test/plots/sparse-title.ts new file mode 100644 index 0000000000..69cb2fdec8 --- /dev/null +++ b/test/plots/sparse-title.ts @@ -0,0 +1,46 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export async function sparseTitle() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + grid: true, + marks: [ + Plot.dot(olympians, { + x: "weight", + y: "height", + fy: "sex", + sort: (d) => !!d.info, + fill: (d) => (d.info ? "currentColor" : "#aaa"), + stroke: "white", + strokeWidth: 0.25, + title: (d) => (d.info ? [(d.name, d.info)].join("\n\n") : undefined) + }) + ] + }); +} + +export async function sparseTitleTip() { + const olympians = await d3.csv("data/athletes.csv", d3.autoType); + return Plot.plot({ + grid: true, + marks: [ + Plot.dot(olympians, { + x: "weight", + y: "height", + fy: "sex", + sort: (d) => !!d.info, + stroke: (d) => (d.info ? "currentColor" : "#aaa") + }), + Plot.tip( + olympians, + Plot.pointer({ + x: "weight", + y: "height", + fy: "sex", + title: (d) => (d.info ? [(d.name, d.info)].join("\n\n") : undefined) + }) + ) + ] + }); +} diff --git a/test/plots/time-axis.ts b/test/plots/time-axis.ts new file mode 100644 index 0000000000..dcb19f7fb0 --- /dev/null +++ b/test/plots/time-axis.ts @@ -0,0 +1,84 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; +import {svg} from "htl"; + +const domains = [ + [new Date("2023-01-01"), new Date("2023-01-01T00:00:01Z")], // 100ms + [new Date("2023-01-01"), new Date("2023-01-01T00:00:05Z")], // 500ms + [new Date("2023-01-01"), new Date("2023-01-01T00:00:10Z")], // 1s + [new Date("2023-01-01"), new Date("2023-01-01T00:01Z")], // 5s + [new Date("2023-01-01"), new Date("2023-01-01T00:02Z")], // 15s + [new Date("2023-01-01"), new Date("2023-01-01T00:04Z")], // 30s + [new Date("2023-01-01"), new Date("2023-01-01T00:10Z")], // 1m + [new Date("2023-01-01"), new Date("2023-01-01T01:00Z")], // 5m + [new Date("2023-01-01"), new Date("2023-01-01T02:30Z")], // 15m + [new Date("2023-01-01"), new Date("2023-01-01T05:00Z")], // 30m + [new Date("2023-01-01T10:00Z"), new Date("2023-01-01T15:00Z")], // 30m + [new Date("2023-01-01"), new Date("2023-01-01T10:00Z")], // 1h + [new Date("2023-01-01"), new Date("2023-01-02T05:00Z")], // 3h + [new Date("2023-01-01"), new Date("2023-01-03")], // 6h + [new Date("2023-01-01"), new Date("2023-01-05")], // 12h + [new Date("2023-01-05"), new Date("2023-01-11")], // 1d + [new Date("2023-01-01"), new Date("2023-01-11")], // 1d + [new Date("2023-01-01"), new Date("2023-01-23")], // 2d + [new Date("2023-01-17"), new Date("2023-02-13")], // 2d + [new Date("2023-01-01"), new Date("2023-04-01")], // 1w + [new Date("2023-01-01"), new Date("2024-01-01")], // 1m + [new Date("2023-04-01"), new Date("2024-04-01")], // 1m + [new Date("2023-01-01"), new Date("2026-01-01")], // 3m + [new Date("2023-01-01"), new Date("2033-01-01")], // 1y + [new Date("2020-01-01"), new Date("2070-01-01")] // 5y +]; + +export async function timeAxisBottom() { + return svg`${domains.map( + (domain, i) => + svg`${Plot.plot({ + marginBottom: 40, + height: 60, + x: {axis: "bottom", grid: true, type: "utc", domain} + })}` + )}`; +} + +export async function timeAxisTop() { + return svg`${domains.map( + (domain, i) => + svg`${Plot.plot({ + marginTop: 40, + height: 60, + x: {axis: "top", grid: true, type: "utc", domain} + })}` + )}`; +} + +export async function timeAxisLeft() { + const somedomains = domains.filter((d, i) => i % 3 === 0); + return svg`${somedomains.map( + (domain, i) => + svg`${Plot.plot({ + marginLeft: 60, + width: 80, + y: {grid: true, axis: "left", type: "utc", domain} + })}` + )}`; +} + +export async function timeAxisRight() { + const somedomains = domains.filter((d, i) => i % 3 === 0); + return svg`${somedomains.map( + (domain, i) => + svg`${Plot.plot({ + marginRight: 60, + width: 80, + y: {grid: true, axis: "right", type: "utc", domain} + })}` + )}`; +} + +export async function timeAxisExplicitInterval() { + const aapl = await d3.csv("data/aapl.csv", d3.autoType); + return Plot.plot({ + marks: [Plot.ruleY([0]), Plot.axisX({ticks: "3 months"}), Plot.gridX(), Plot.line(aapl, {x: "Date", y: "Close"})] + }); +} diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 55e005dc20..41bcaf5105 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -2,6 +2,11 @@ import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; import {feature, mesh} from "topojson-client"; +export async function tipAreaBand() { + const aapl = await d3.csv("data/aapl.csv", d3.autoType); + return Plot.areaY(aapl, {x: "Date", y1: "Low", y2: "High", tip: true, curve: "step", stroke: "currentColor"}).plot(); +} + export async function tipAreaStack() { const industries = await d3.csv("data/bls-industry-unemployment.csv", d3.autoType); return Plot.areaY(industries, {x: "date", y: "unemployed", fill: "industry", tip: true}).plot({marginLeft: 50}); @@ -100,6 +105,24 @@ export async function tipDotFilter() { }); } +export async function tipGeoNoProjection() { + const counties = await d3.json("data/us-counties-10m.json").then((us) => feature(us, us.objects.counties)); + counties.features = counties.features.filter((d) => { + const [x, y] = d3.geoCentroid(d); + return x > -126 && x < -68 && y > 25 && y < 49; + }); + return Plot.geo(counties, Plot.centroid({title: (d) => d.properties.name, tip: true})).plot(); +} + +export async function tipGeoProjection() { + const counties = await d3.json("data/us-counties-10m.json").then((us) => feature(us, us.objects.counties)); + counties.features = counties.features.filter((d) => { + const [x, y] = d3.geoCentroid(d); + return x > -126 && x < -68 && y > 25 && y < 49; + }); + return Plot.geo(counties, Plot.centroid({title: (d) => d.properties.name, tip: true})).plot({projection: "albers"}); +} + export async function tipGeoCentroid() { const [[counties, countymesh]] = await Promise.all([ d3 @@ -214,3 +237,22 @@ export async function tipTransform() { marks: [Plot.dotX([0, 0.1, 0.3, 1], {fill: Plot.identity, r: 10, frameAnchor: "middle", tip: true})] }); } + +export async function tipFacetX() { + const data = d3.range(100).map((i) => ({f: i > 60 || i % 2 ? "b" : "a", x: i, y: i / 10})); + return Plot.plot({ + inset: 10, + y: {domain: [0, 7]}, + marks: [ + Plot.frame(), + Plot.dot(data, {fy: "f", x: "x", y: "y", tip: "x", fill: "f"}), + Plot.dot( + [ + {f: "a", y: 3}, + {f: "b", y: 1} + ], + {fy: "f", x: 90, y: "y", r: 30, fill: "f", fillOpacity: 0.1, stroke: "currentColor", strokeDasharray: 4} + ) + ] + }); +} diff --git a/test/plots/title.ts b/test/plots/title.ts new file mode 100644 index 0000000000..2a19918b85 --- /dev/null +++ b/test/plots/title.ts @@ -0,0 +1,20 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; +import {html} from "htl"; + +export async function title() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.dotX(penguins, {x: "body_mass_g", stroke: "species"}).plot({ + title: "A title about penguins", + subtitle: "A subtitle about body_mass_g", + color: {legend: true} + }); +} + +export async function titleHtml() { + const penguins = await d3.csv("data/penguins.csv", d3.autoType); + return Plot.dotX(penguins, {x: "body_mass_g"}).plot({ + title: html`

A fancy title about penguins

`, + subtitle: html`A fancy subtitle` + }); +} diff --git a/test/plots/traffic-horizon.ts b/test/plots/traffic-horizon.ts index 3b229abad9..14ee18d1c1 100644 --- a/test/plots/traffic-horizon.ts +++ b/test/plots/traffic-horizon.ts @@ -10,9 +10,8 @@ export async function trafficHorizon() { return Plot.plot({ width: 960, height: 1100, - x: { - axis: "top" - }, + margin: 0, + marginTop: 30, y: { axis: null, domain: [0, step] @@ -27,16 +26,12 @@ export async function trafficHorizon() { legend: true }, fy: { - axis: null, domain: data.map((d) => d.location) // respect input order }, - facet: { - data, - y: "location" - }, marks: [ - ticks.map((t) => Plot.areaY(data, {x: "date", y: (d) => d.vehicles - t, fill: t, clip: true})), - Plot.text(data, Plot.selectFirst({text: "location", frameAnchor: "left"})) + ticks.map((t) => Plot.areaY(data, {x: "date", y: (d) => d.vehicles - t, fy: "location", fill: t, clip: true})), + Plot.axisFy({frameAnchor: "left", label: null}), + Plot.axisX({anchor: "top", filter: (d, i) => i > 0}) // drop first tick ] }); } diff --git a/test/plots/us-state-population-change.ts b/test/plots/us-state-population-change.ts index dad80d4c0d..ed87f456e9 100644 --- a/test/plots/us-state-population-change.ts +++ b/test/plots/us-state-population-change.ts @@ -33,3 +33,36 @@ export async function usStatePopulationChange() { ] }); } + +export async function usStatePopulationChangeRelative() { + const statepop = await d3.csv("data/us-state-population-2010-2019.csv", d3.autoType); + const change = new Map(statepop.map((d) => [d.State, (d[2019] - d[2010]) / d[2010]])); + return Plot.plot({ + height: 800, + label: null, + x: { + axis: "top", + grid: true, + label: "← decrease · Change in population, 2010–2019 (%) · increase →", + labelAnchor: "center", + tickFormat: "+", + percent: true + }, + color: { + scheme: "PiYG", + type: "ordinal" + }, + marks: [ + Plot.barX(statepop, { + y: "State", + x: (d) => change.get(d.State), + fill: (d) => Math.sign(change.get(d.State)), + sort: {y: "x"} + }), + Plot.axisY({x: 0, filter: (d) => change.get(d) >= 0, anchor: "left"}), + Plot.axisY({x: 0, filter: (d) => change.get(d) < 0, anchor: "right"}), + Plot.gridX({stroke: "white", strokeOpacity: 0.5}), + Plot.ruleX([0]) + ] + }); +} diff --git a/test/plots/warn-misaligned-diverging.ts b/test/plots/warn-misaligned-diverging.ts new file mode 100644 index 0000000000..903f3c1f4d --- /dev/null +++ b/test/plots/warn-misaligned-diverging.ts @@ -0,0 +1,8 @@ +import * as Plot from "@observablehq/plot"; +import * as d3 from "d3"; + +export function warnMisalignedDivergingDomain() { + return Plot.cellX(d3.range(-5, 6), {x: Plot.identity, fill: Plot.identity}).plot({ + color: {legend: true, type: "diverging", domain: [-5, 5, 10]} + }); +} diff --git a/test/scales/scales-test.js b/test/scales/scales-test.js index 736ac984c9..5135cec632 100644 --- a/test/scales/scales-test.js +++ b/test/scales/scales-test.js @@ -724,72 +724,72 @@ it("plot(…).scale('color') can return a “polylinear” piecewise linear scal }); }); -it("plot(…).scale('color') ignores extra domain elements with an explicit range", () => { - const plot = assert.warns( - () => - Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ - color: {type: "linear", domain: [0, 100, 200], range: ["red", "blue"]} - }), - /domain contains extra/ - ); - scaleEqual(plot.scale("color"), { +it("plot(…).scale('color') distributes an explicit range equally across more domain elements", () => { + const plot = Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ + color: {type: "linear", domain: [0, 100, 200], range: ["red", "blue"]} + }); + const color = plot.scale("color"); + scaleEqual(color, { type: "linear", - domain: [0, 100], - range: ["red", "blue"], - interpolate: d3.interpolateRgb, + domain: [0, 100, 200], + range: [0, 0.5, 1], + interpolate: color.interpolate, clamp: false }); + assert.strictEqual(color.interpolate(0), "rgb(255, 0, 0)"); + assert.strictEqual(color.interpolate(0.5), "rgb(128, 0, 128)"); + assert.strictEqual(color.interpolate(1), "rgb(0, 0, 255)"); }); -it("plot(…).scale('color') ignores extra range elements with an explicit range", () => { - const plot = assert.warns( - () => - Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ - color: {type: "linear", domain: [0, 100], range: ["red", "blue", "green"]} - }), - /range contains extra/ - ); - scaleEqual(plot.scale("color"), { +it("plot(…).scale('color') distributes an explicit range equally across fewer domain elements", () => { + const plot = Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ + color: {type: "linear", domain: [0, 100], range: ["red", "blue", "green"]} + }); + const color = plot.scale("color"); + scaleEqual(color, { type: "linear", domain: [0, 100], - range: ["red", "blue"], - interpolate: d3.interpolateRgb, + range: [0, 1], + interpolate: color.interpolate, clamp: false }); + assert.strictEqual(color.interpolate(0), "rgb(255, 0, 0)"); + assert.strictEqual(color.interpolate(0.5), "rgb(0, 0, 255)"); + assert.strictEqual(color.interpolate(1), "rgb(0, 128, 0)"); }); it("plot(…).scale('color') ignores extra domain elements with an explicit range when reversed", () => { - const plot = assert.warns( - () => - Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ - color: {type: "linear", domain: [0, 100, 200], range: ["red", "blue"], reverse: true} - }), - /domain contains extra/ - ); - scaleEqual(plot.scale("color"), { + const plot = Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ + color: {type: "linear", domain: [0, 100, 200], range: ["red", "blue"], reverse: true} + }); + const color = plot.scale("color"); + scaleEqual(color, { type: "linear", - domain: [100, 0], - range: ["red", "blue"], - interpolate: d3.interpolateRgb, + domain: [0, 100, 200], + range: [0, 0.5, 1], + interpolate: color.interpolate, clamp: false }); + assert.strictEqual(color.interpolate(0), "rgb(0, 0, 255)"); + assert.strictEqual(color.interpolate(0.5), "rgb(128, 0, 128)"); + assert.strictEqual(color.interpolate(1), "rgb(255, 0, 0)"); }); it("plot(…).scale('color') ignores extra range elements with an explicit range when reversed", () => { - const plot = assert.warns( - () => - Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ - color: {type: "linear", domain: [0, 100], range: ["red", "blue", "green"], reverse: true} - }), - /range contains extra/ - ); - scaleEqual(plot.scale("color"), { + const plot = Plot.cellX([100, 200, 300, 400], {fill: Plot.identity}).plot({ + color: {type: "linear", domain: [0, 100], range: ["red", "blue", "green"], reverse: true} + }); + const color = plot.scale("color"); + scaleEqual(color, { type: "linear", - domain: [100, 0], - range: ["red", "blue"], - interpolate: d3.interpolateRgb, + domain: [0, 100], + range: [0, 1], + interpolate: color.interpolate, clamp: false }); + assert.strictEqual(color.interpolate(0), "rgb(0, 128, 0)"); + assert.strictEqual(color.interpolate(0.5), "rgb(0, 0, 255)"); + assert.strictEqual(color.interpolate(1), "rgb(255, 0, 0)"); }); it("plot(…).scale('color') can return a polylinear piecewise linear scale with an explicit scheme", () => { @@ -2102,6 +2102,96 @@ it("plot(…).scale(name).apply and invert return the expected functions", () => ]); }); +it("Plot.plot passes render functions scale descriptors", async () => { + const seed = d3.randomLcg(42); + const x = d3.randomNormal.source(seed)(); + Plot.plot({ + marks: [ + Plot.dotX({length: 10001}, {x, fill: seed}), + (index, {x, color, scales}) => { + assert.deepStrictEqual(Object.keys(scales), ["color", "x"]); + assert.strictEqual(x(0), 314.6324357568407); + assert.strictEqual(x(1), 400.26512486789505); + assert.strictEqual(color(0), "rgb(35, 23, 27)"); + assert.strictEqual(color(1), "rgb(144, 12, 0)"); + scaleEqual(scales.color, { + type: "linear", + domain: [0.0003394410014152527, 0.999856373295188], + range: [0, 1], + clamp: false, + interpolate: d3.interpolateTurbo + }); + scaleEqual(scales.x, { + type: "linear", + domain: [-3.440653783215207, 3.5660162890264693], + range: [20, 620], + clamp: false, + interpolate: d3.interpolateNumber + }); + return null; + } + ] + }); +}); + +it("Plot.plot passes render functions re-initialized scale descriptors and functions", async () => { + const seed = d3.randomLcg(42); + const x = d3.randomNormal.source(seed)(); + const y = d3.randomNormal.source(seed)(); + Plot.plot({ + marks: [ + Plot.dot({length: 10001}, Plot.hexbin({fill: "count"}, {x, y})), + (index, {x, y, color, scales}) => { + assert.deepStrictEqual(Object.keys(scales), ["x", "y", "color"]); + assert.ok(Math.abs(x(0) - 351) < 1); + assert.ok(Math.abs(x(1) - 426) < 1); + assert.ok(Math.abs(y(0) - 196) < 1); + assert.ok(Math.abs(y(1) - 148) < 1); + assert.strictEqual(color(1), "rgb(35, 23, 27)"); + assert.strictEqual(color(10), "rgb(72, 58, 164)"); + scaleEqual(scales.color, { + type: "linear", + domain: [1, 161], + range: [0, 1], + clamp: false, + interpolate: d3.interpolateTurbo + }); + return null; + } + ] + }); +}); + +it("plot(…).scale(name) returns a deduplicated ordinal domain", () => { + const letters = "abbbcaabbcc"; + const plot = Plot.dotX(letters).plot({x: {domain: letters}}); + scaleEqual(plot.scale("x"), { + align: 0.5, + bandwidth: 0, + domain: ["a", "b", "c"], + padding: 0.5, + range: [20, 620], + round: true, + step: 200, + type: "point" + }); +}); + +it("plot(…).scale(name) returns a deduplicated ordinal/temporal domain", () => { + const dates = ["2001", "2002", "2004", "2004"].map(d3.isoParse); + const plot = Plot.dotX(dates).plot({x: {type: "point", domain: dates}}); + scaleEqual(plot.scale("x"), { + align: 0.5, + bandwidth: 0, + domain: dates.slice(0, 3), + padding: 0.5, + range: [20, 620], + round: true, + step: 200, + type: "point" + }); +}); + // Given a plot specification (or, as shorthand, an array of marks or a single // mark), asserts that the given named scales, when materialized from the first // plot and used to produce a second plot, produce the same output and the same diff --git a/yarn.lock b/yarn.lock index 08719b9524..c45db2c2b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,163 +2,168 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.2.tgz#1c9ffcfac7fc4733fe97356247b25d9d7a83538c" - integrity sha512-hkG80c9kx9ClVAEcUJbTd2ziVC713x9Bji9Ty4XJfKXlxlsx3iXsoNhAwfeR4ulzIUg7OE5gez0UU1zVDdG7kg== - dependencies: - "@algolia/autocomplete-plugin-algolia-insights" "1.9.2" - "@algolia/autocomplete-shared" "1.9.2" - -"@algolia/autocomplete-plugin-algolia-insights@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.2.tgz#b4672d5662acc2d0a0547d14dfbdcc70c17625de" - integrity sha512-2LVsf4W66hVHQ3Ua/8k15oPlxjELCztbAkQm/hP42Sw+GLkHAdY1vaVRYziaWq64+Oljfg6FKkZHCdgXH+CGIA== - dependencies: - "@algolia/autocomplete-shared" "1.9.2" +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@algolia/autocomplete-core@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7" + integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== + dependencies: + "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-plugin-algolia-insights@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587" + integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== + dependencies: + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-preset-algolia@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da" + integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA== + dependencies: + "@algolia/autocomplete-shared" "1.9.3" -"@algolia/autocomplete-preset-algolia@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.2.tgz#a31fc9a88800ee7312cd177c738e9e4c0e0f78e8" - integrity sha512-pqgIm2GNqtCT59Y1ICctIPrYTi34+wNPiNWEclD/yDzp5uDUUsyGe5XrUjCNyQRTKonAlmYxoaEHOn8FWgmBHA== - dependencies: - "@algolia/autocomplete-shared" "1.9.2" - -"@algolia/autocomplete-shared@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.2.tgz#b5b909377439c45774cfb91947ad8e6ebd4652c1" - integrity sha512-XxX6YDn+7LG+SmdpXEOnj7fc3TjiVpQ0CbGhjLwrd2tYr6LVY2D4Iiu/iuYJ4shvVDWWnpwArSk0uIWC/8OPUA== - -"@algolia/cache-browser-local-storage@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.1.tgz#b2f204a436893b4856165670ec4dda12cdc055b8" - integrity sha512-e91Jpu93X3t3mVdQwF3ZDjSFMFIfzSc+I76G4EX8nl9RYXgqcjframoL05VTjcD2YCsI18RIHAWVCBoCXVZnrw== - dependencies: - "@algolia/cache-common" "4.17.1" - -"@algolia/cache-common@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.17.1.tgz#f4877f6fdc594a29ce6d032fae96f0517bf80b1d" - integrity sha512-fvi1WT8aSiGAKrcTw8Qg3RYgcwW8GZMHcqEm4AyDBEy72JZlFBSY80cTQ75MslINjCHXLDT+9EN8AGI9WVY7uA== - -"@algolia/cache-in-memory@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.17.1.tgz#7b3ab5f6de897677d92db549f8228966c62966d5" - integrity sha512-NbBt6eBWlsXc5geSpfPRC5dkIB/0Ptthw8r0yM5Z7D3sPlYdnTZSO9y9XWXIptRMwmZe4cM8iBMN8y0tzbcBkA== - dependencies: - "@algolia/cache-common" "4.17.1" - -"@algolia/client-account@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.17.1.tgz#81747c0828d2688af4a98bbed3d3b0aa7daa25f6" - integrity sha512-3rL/6ofJvyL+q8TiWM3qoM9tig+SY4gB1Vbsj+UeJPnJm8Khm+7OS+r+mFraqR6pTehYqN8yGYoE7x4diEn4aA== - dependencies: - "@algolia/client-common" "4.17.1" - "@algolia/client-search" "4.17.1" - "@algolia/transporter" "4.17.1" - -"@algolia/client-analytics@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.17.1.tgz#d6ecc75fd792fb1dee67c01497098ce175f1c4c9" - integrity sha512-Bepr2w249vODqeBtM7i++tPmUsQ9B81aupUGbDWmjA/FX+jzQqOdhW8w1CFO5kWViNKTbz2WBIJ9U3x8hOa4bA== - dependencies: - "@algolia/client-common" "4.17.1" - "@algolia/client-search" "4.17.1" - "@algolia/requester-common" "4.17.1" - "@algolia/transporter" "4.17.1" - -"@algolia/client-common@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.17.1.tgz#a8b561c1e3a19cce2c24e9a49bd822477c2f56d9" - integrity sha512-+r7kg4EgbFnGsDnoGSVNtXZO8xvZ0vzf1WAOV7sqV9PMf1bp6cpJP/3IuPrSk4t5w2KVl+pC8jfTM7HcFlfBEQ== - dependencies: - "@algolia/requester-common" "4.17.1" - "@algolia/transporter" "4.17.1" - -"@algolia/client-personalization@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.17.1.tgz#26b2c8e13e9b69afd4e2c17879f538d408b708f3" - integrity sha512-gJku9DG/THJpfsSlG/az0a3QIn+VVff9kKh8PG8+7ZfxOHS+C+Y5YSeZVsC+c2cfoKLPo3CuHIiJ/p86erR3bA== - dependencies: - "@algolia/client-common" "4.17.1" - "@algolia/requester-common" "4.17.1" - "@algolia/transporter" "4.17.1" - -"@algolia/client-search@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.17.1.tgz#defaf56083e613fb593a9a49837b6aa551ed38eb" - integrity sha512-Q5YfT5gVkx60PZDQBqp/zH9aUbBdC7HVvxupiHUgnCKqRQsRZjOhLest7AI6FahepuZLBZS62COrO7v+JvKY7w== - dependencies: - "@algolia/client-common" "4.17.1" - "@algolia/requester-common" "4.17.1" - "@algolia/transporter" "4.17.1" - -"@algolia/logger-common@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.17.1.tgz#fe50f67a86276cebdfd8337bc5d925f7a3bf9e43" - integrity sha512-Us28Ot+fLEmX9M96sa65VZ8EyEEzhYPxfhV9aQyKDjfXbUdJlJxKt6wZpoEg9RAPSdO8IjK9nmuW2P8au3rRsg== - -"@algolia/logger-console@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.17.1.tgz#d9d6dc0bb6ad1321b66163491cc4618d27beb73d" - integrity sha512-iKGQTpOjHiE64W3JIOu6dmDvn+AfYIElI9jf/Nt6umRPmP/JI9rK+OHUoW4pKrBtdG0DPd62ppeNXzSnLxY6/g== +"@algolia/autocomplete-shared@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa" + integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== + +"@algolia/cache-browser-local-storage@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.19.1.tgz#d29f42775ed4d117182897ac164519c593faf399" + integrity sha512-FYAZWcGsFTTaSAwj9Std8UML3Bu8dyWDncM7Ls8g+58UOe4XYdlgzXWbrIgjaguP63pCCbMoExKr61B+ztK3tw== + dependencies: + "@algolia/cache-common" "4.19.1" + +"@algolia/cache-common@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.19.1.tgz#faa5eeacaffd6023c2cf26e9866bdb06193f9b26" + integrity sha512-XGghi3l0qA38HiqdoUY+wvGyBsGvKZ6U3vTiMBT4hArhP3fOGLXpIINgMiiGjTe4FVlTa5a/7Zf2bwlIHfRqqg== + +"@algolia/cache-in-memory@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.19.1.tgz#afe4f0f21149800358379871089e0141fb72415b" + integrity sha512-+PDWL+XALGvIginigzu8oU6eWw+o76Z8zHbBovWYcrtWOEtinbl7a7UTt3x3lthv+wNuFr/YD1Gf+B+A9V8n5w== + dependencies: + "@algolia/cache-common" "4.19.1" + +"@algolia/client-account@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.19.1.tgz#1fa65881baab79ad35af6bcf44646a13b8d5edc9" + integrity sha512-Oy0ritA2k7AMxQ2JwNpfaEcgXEDgeyKu0V7E7xt/ZJRdXfEpZcwp9TOg4TJHC7Ia62gIeT2Y/ynzsxccPw92GA== + dependencies: + "@algolia/client-common" "4.19.1" + "@algolia/client-search" "4.19.1" + "@algolia/transporter" "4.19.1" + +"@algolia/client-analytics@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.19.1.tgz#e6ed79acd4de5a0284c9696bf4e1c25278ba34db" + integrity sha512-5QCq2zmgdZLIQhHqwl55ZvKVpLM3DNWjFI4T+bHr3rGu23ew2bLO4YtyxaZeChmDb85jUdPDouDlCumGfk6wOg== + dependencies: + "@algolia/client-common" "4.19.1" + "@algolia/client-search" "4.19.1" + "@algolia/requester-common" "4.19.1" + "@algolia/transporter" "4.19.1" + +"@algolia/client-common@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.19.1.tgz#40a8387316fa61d62ad1091beb3a8e227f008e75" + integrity sha512-3kAIVqTcPrjfS389KQvKzliC559x+BDRxtWamVJt8IVp7LGnjq+aVAXg4Xogkur1MUrScTZ59/AaUd5EdpyXgA== + dependencies: + "@algolia/requester-common" "4.19.1" + "@algolia/transporter" "4.19.1" + +"@algolia/client-personalization@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.19.1.tgz#fe362e0684dc74c3504c3641c5a7488c6ae02e07" + integrity sha512-8CWz4/H5FA+krm9HMw2HUQenizC/DxUtsI5oYC0Jxxyce1vsr8cb1aEiSJArQT6IzMynrERif1RVWLac1m36xw== + dependencies: + "@algolia/client-common" "4.19.1" + "@algolia/requester-common" "4.19.1" + "@algolia/transporter" "4.19.1" + +"@algolia/client-search@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.19.1.tgz#5e54601aa5f5cea790cec3f2cde4af9d6403871e" + integrity sha512-mBecfMFS4N+yK/p0ZbK53vrZbL6OtWMk8YmnOv1i0LXx4pelY8TFhqKoTit3NPVPwoSNN0vdSN9dTu1xr1XOVw== + dependencies: + "@algolia/client-common" "4.19.1" + "@algolia/requester-common" "4.19.1" + "@algolia/transporter" "4.19.1" + +"@algolia/logger-common@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.19.1.tgz#0e46a11510f3e94e1afc0ac780ae52e9597be78f" + integrity sha512-i6pLPZW/+/YXKis8gpmSiNk1lOmYCmRI6+x6d2Qk1OdfvX051nRVdalRbEcVTpSQX6FQAoyeaui0cUfLYW5Elw== + +"@algolia/logger-console@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.19.1.tgz#656a6f4ebb5de39af6ef7095c398d9ab3cceb87d" + integrity sha512-jj72k9GKb9W0c7TyC3cuZtTr0CngLBLmc8trzZlXdfvQiigpUdvTi1KoWIb2ZMcRBG7Tl8hSb81zEY3zI2RlXg== dependencies: - "@algolia/logger-common" "4.17.1" + "@algolia/logger-common" "4.19.1" -"@algolia/requester-browser-xhr@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.1.tgz#8be50e4196cd9d1ec311970845a42f2aee35860e" - integrity sha512-W5mGfGDsyfVR+r4pUFrYLGBEM18gs38+GNt5PE5uPULy4uVTSnnVSkJkWeRkmLBk9zEZ/Nld8m4zavK6dtEuYg== +"@algolia/requester-browser-xhr@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.19.1.tgz#7341ea2f980b8980a2976110142026721e452187" + integrity sha512-09K/+t7lptsweRTueHnSnmPqIxbHMowejAkn9XIcJMLdseS3zl8ObnS5GWea86mu3vy4+8H+ZBKkUN82Zsq/zg== dependencies: - "@algolia/requester-common" "4.17.1" + "@algolia/requester-common" "4.19.1" -"@algolia/requester-common@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.17.1.tgz#3b3912c8df1e05f0fd49f4c9a7caa3fe45d2d995" - integrity sha512-HggXdjvVFQR0I5l7hM5WdHgQ1tqcRWeyXZz8apQ7zPWZhirmY2E9D6LVhDh/UnWQNEm7nBtM+eMFONJ3bZccIQ== +"@algolia/requester-common@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.19.1.tgz#f3396c77631b9d36e8d4d6f819a2c27f9ddbf7a1" + integrity sha512-BisRkcWVxrDzF1YPhAckmi2CFYK+jdMT60q10d7z3PX+w6fPPukxHRnZwooiTUrzFe50UBmLItGizWHP5bDzVQ== -"@algolia/requester-node-http@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.17.1.tgz#f4eeee985833ad2b51ac9ff757be5c1a786ff80a" - integrity sha512-NzFWecXT6d0PPsQY9L+/qoK2deF74OLcpvqCH+Vh3mh+QzPsFafcBExdguAjZsAWDn1R6JEeFW7/fo/p0SE57w== +"@algolia/requester-node-http@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.19.1.tgz#ea210de9642628b3bdda1dd7fcd1fcb686da442e" + integrity sha512-6DK52DHviBHTG2BK/Vv2GIlEw7i+vxm7ypZW0Z7vybGCNDeWzADx+/TmxjkES2h15+FZOqVf/Ja677gePsVItA== dependencies: - "@algolia/requester-common" "4.17.1" + "@algolia/requester-common" "4.19.1" -"@algolia/transporter@4.17.1": - version "4.17.1" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.17.1.tgz#9508e08e984e110603ec66a19362017c1df59e05" - integrity sha512-ZM+qhX47Vh46mWH8/U9ihvy98HdTYpYQDSlqBD7IbiUbbyoCMke+qmdSX2MGhR2FCcXBSxejsJKKVAfbpaLVgg== +"@algolia/transporter@4.19.1": + version "4.19.1" + resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.19.1.tgz#b5787299740c4bec9ba05502d98c14b5999860c8" + integrity sha512-nkpvPWbpuzxo1flEYqNIbGz7xhfhGOKGAZS7tzC+TELgEmi7z99qRyTfNSUlW7LZmB3ACdnqAo+9A9KFBENviQ== dependencies: - "@algolia/cache-common" "4.17.1" - "@algolia/logger-common" "4.17.1" - "@algolia/requester-common" "4.17.1" + "@algolia/cache-common" "4.19.1" + "@algolia/logger-common" "4.19.1" + "@algolia/requester-common" "4.19.1" "@babel/parser@^7.20.15", "@babel/parser@^7.21.3": - version "7.22.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.4.tgz#a770e98fd785c231af9d93f6459d36770993fb32" - integrity sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" + integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== -"@docsearch/css@3.5.0", "@docsearch/css@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.5.0.tgz#5f6cb94a7c40122b21621c30a4b2460bd42d7dd0" - integrity sha512-Ob5FQLubplcBNihAVtriR59FRBeP8u69F6mu4L4yIr60KfsPc10bOV0DoPErJw0zF9IBN2cNLW9qdmt8zWPxyg== +"@docsearch/css@3.5.1", "@docsearch/css@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.5.1.tgz#4adf9884735bbfea621c3716e80ea97baa419b73" + integrity sha512-2Pu9HDg/uP/IT10rbQ+4OrTQuxIWdKVUEdcw9/w7kZJv9NeHS6skJx1xuRiFyoGKwAzcHXnLp7csE99sj+O1YA== -"@docsearch/js@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.5.0.tgz#870ba9322e1c917d4c2c27fa7051641379c89817" - integrity sha512-WqB+z+zVKSXDkGq028nClT9RvMzfFlemZuIulX5ZwWkdUtl4k7M9cmZA/c6kuZf7FG24XQsMHWuBjeUo9hLRyA== +"@docsearch/js@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.5.1.tgz#6d8de3b4fcf7de94462c0e592e333efa9ebbbabd" + integrity sha512-EXi8de5njxgP6TV3N9ytnGRLG9zmBNTEZjR4VzwPcpPLbZxxTLG2gaFyJyKiFVQxHW/DPlMrDJA3qoRRGEkgZw== dependencies: - "@docsearch/react" "3.5.0" + "@docsearch/react" "3.5.1" preact "^10.0.0" -"@docsearch/react@3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.5.0.tgz#2468fa67dea86e4ef2935754a3453e01d850c56f" - integrity sha512-3IG8mmSMzSHNGy2S1VuPyYU9tFCxFpj5Ov8SYwsSHM4yMvFsaO9oFxXocA5lSenliIELhuOuS5+BdxHa/Qlf2A== +"@docsearch/react@3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.5.1.tgz#35f4a75f948211d8bb6830d2147c575f96a85274" + integrity sha512-t5mEODdLzZq4PTFAm/dvqcvZFdPDMdfPE5rJS5SC8OUq9mPzxEy6b+9THIqNM9P0ocCb4UC5jqBrxKclnuIbzQ== dependencies: - "@algolia/autocomplete-core" "1.9.2" - "@algolia/autocomplete-preset-algolia" "1.9.2" - "@docsearch/css" "3.5.0" + "@algolia/autocomplete-core" "1.9.3" + "@algolia/autocomplete-preset-algolia" "1.9.3" + "@docsearch/css" "3.5.1" algoliasearch "^4.0.0" "@esbuild-kit/core-utils@^3.1.0": @@ -174,131 +179,241 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + "@esbuild/android-arm@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + "@esbuild/android-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + "@esbuild/darwin-arm64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + "@esbuild/darwin-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + "@esbuild/freebsd-arm64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + "@esbuild/freebsd-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + "@esbuild/linux-arm64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + "@esbuild/linux-arm@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + "@esbuild/linux-ia32@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + "@esbuild/linux-loong64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + "@esbuild/linux-mips64el@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + "@esbuild/linux-ppc64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + "@esbuild/linux-riscv64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + "@esbuild/linux-s390x@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + "@esbuild/linux-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + "@esbuild/netbsd-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + "@esbuild/openbsd-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + "@esbuild/sunos-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + "@esbuild/win32-arm64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + "@esbuild/win32-ia32@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + "@esbuild/win32-x64@0.17.19": version "0.17.19" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== -"@eslint-community/eslint-utils@^4.2.0": +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== +"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.2" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -306,10 +421,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.42.0": - version "8.42.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.42.0.tgz#484a1d638de2911e6f5a30c12f49c7e4a3270fb6" - integrity sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw== +"@eslint/js@^8.47.0": + version "8.47.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d" + integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== "@humanwhocodes/config-array@^0.11.10": version "0.11.10" @@ -339,10 +454,10 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== "@jridgewell/set-array@^1.0.1": version "1.1.2" @@ -350,35 +465,30 @@ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/source-map@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" - integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@^0.3.9": - version "0.3.18" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" - integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@mapbox/node-pre-gyp@^1.0.0": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" - integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== + version "1.0.11" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" + integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== dependencies: detect-libc "^2.0.0" https-proxy-agent "^5.0.0" @@ -411,10 +521,15 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@rollup/plugin-commonjs@^24.0.1": - version "24.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz#79e54bd83bb64396761431eee6c44152ef322100" - integrity sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ== +"@one-ini/wasm@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323" + integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw== + +"@rollup/plugin-commonjs@^25.0.2": + version "25.0.4" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.4.tgz#a7547a0c4ec3fa79818eb313e1de0023e548f4e6" + integrity sha512-L92Vz9WUZXDnlQQl3EwbypJR4+DM2EbsO+/KOcEkP4Mc6Ct453EeDB2uH9lgRwj4w5yflgNpq9pHOiY8aoUXBQ== dependencies: "@rollup/pluginutils" "^5.0.1" commondir "^1.0.1" @@ -452,9 +567,9 @@ terser "^5.17.4" "@rollup/pluginutils@^5.0.1": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" - integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== + version "5.0.3" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.3.tgz#183126d69aeb1cfa23401d5a71cb4b8c16c4a4e0" + integrity sha512-hfllNN4a80rwNQ9QCxhxuHCGHMAvabXqxNdaChUSSadMre7t4iEUI6fFAhBOn/eIYTgYVhBv7vCLsAJ4u3lf3g== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -465,6 +580,16 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@ts-morph/common@~0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af" + integrity sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q== + dependencies: + fast-glob "^3.2.12" + minimatch "^7.4.3" + mkdirp "^2.1.6" + path-browserify "^1.0.1" + "@types/d3-array@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.5.tgz#857c1afffd3f51319bbc5b301956aca68acaa7b8" @@ -685,17 +810,22 @@ resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.10.tgz#6dfbf5ea17142f7f9a043809f1cd4c448cb68249" integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA== -"@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.12": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/node@^20.5.0": + version "20.5.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313" + integrity sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q== + "@types/resolve@1.20.2": version "1.20.2" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== -"@types/semver@^7.3.12": +"@types/semver@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== @@ -705,89 +835,90 @@ resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz#5c9f3c617f64a9735d7b72a7cc671e166d900c40" integrity sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA== -"@typescript-eslint/eslint-plugin@^5.54.1": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.8.tgz#1e7a3e5318ece22251dfbc5c9c6feeb4793cc509" - integrity sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ== +"@typescript-eslint/eslint-plugin@^6.0.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz#53428b616f7d80fe879f45a08f11cc0f0b62cf13" + integrity sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg== dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/type-utils" "5.59.8" - "@typescript-eslint/utils" "5.59.8" + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.4.0" + "@typescript-eslint/type-utils" "6.4.0" + "@typescript-eslint/utils" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.54.1": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.8.tgz#60cbb00671d86cf746044ab797900b1448188567" - integrity sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw== - dependencies: - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.0.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.4.0.tgz#47e7c6e22ff1248e8675d95f488890484de67600" + integrity sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg== + dependencies: + "@typescript-eslint/scope-manager" "6.4.0" + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/typescript-estree" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.8.tgz#ff4ad4fec6433647b817c4a7d4b4165d18ea2fa8" - integrity sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig== +"@typescript-eslint/scope-manager@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz#3048e4262ba3eafa4e2e69b08912d9037ec646ae" + integrity sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig== dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" -"@typescript-eslint/type-utils@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.8.tgz#aa6c029a9d7706d26bbd25eb4666398781df6ea2" - integrity sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA== +"@typescript-eslint/type-utils@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz#c8ac92716ed6a9d5443aa3e342910355b0796ba0" + integrity sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg== dependencies: - "@typescript-eslint/typescript-estree" "5.59.8" - "@typescript-eslint/utils" "5.59.8" + "@typescript-eslint/typescript-estree" "6.4.0" + "@typescript-eslint/utils" "6.4.0" debug "^4.3.4" - tsutils "^3.21.0" + ts-api-utils "^1.0.1" -"@typescript-eslint/types@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.8.tgz#212e54414733618f5d0fd50b2da2717f630aebf8" - integrity sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w== +"@typescript-eslint/types@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.4.0.tgz#5b109a59a805f0d8d375895e42d9e5f0037f66ee" + integrity sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg== -"@typescript-eslint/typescript-estree@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.8.tgz#801a7b1766481629481b3b0878148bd7a1f345d7" - integrity sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg== +"@typescript-eslint/typescript-estree@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz#3c58d20632db93fec3d6ab902acbedf593d37276" + integrity sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA== dependencies: - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/visitor-keys" "5.59.8" + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/visitor-keys" "6.4.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.8.tgz#34d129f35a2134c67fdaf024941e8f96050dca2b" - integrity sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.8" - "@typescript-eslint/types" "5.59.8" - "@typescript-eslint/typescript-estree" "5.59.8" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.8": - version "5.59.8" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.8.tgz#aa6a7ef862add919401470c09e1609392ef3cc40" - integrity sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ== - dependencies: - "@typescript-eslint/types" "5.59.8" - eslint-visitor-keys "^3.3.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.4.0.tgz#23e996b693603c5924b1fbb733cc73196256baa5" + integrity sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.4.0" + "@typescript-eslint/types" "6.4.0" + "@typescript-eslint/typescript-estree" "6.4.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz#96a426cdb1add28274abd7a34aefe27f8b7d51ef" + integrity sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA== + dependencies: + "@typescript-eslint/types" "6.4.0" + eslint-visitor-keys "^3.4.1" "@vitejs/plugin-vue@^4.2.3": version "4.2.3" @@ -889,36 +1020,36 @@ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780" integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ== -"@vueuse/core@10.1.2", "@vueuse/core@^10.1.2": - version "10.1.2" - resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.1.2.tgz#2499eadec36c5d7109338e3a2b73725040ae8011" - integrity sha512-roNn8WuerI56A5uiTyF/TEYX0Y+VKlhZAF94unUfdhbDUI+NfwQMn4FUnUscIRUhv3344qvAghopU4bzLPNFlA== +"@vueuse/core@10.3.0", "@vueuse/core@^10.2.1": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.3.0.tgz#b2dab7821ef206811b925fc935163c38056fd82b" + integrity sha512-BEM5yxcFKb5btFjTSAFjTu5jmwoW66fyV9uJIP4wUXXU8aR5Hl44gndaaXp7dC5HSObmgbnR2RN+Un1p68Mf5Q== dependencies: "@types/web-bluetooth" "^0.0.17" - "@vueuse/metadata" "10.1.2" - "@vueuse/shared" "10.1.2" - vue-demi ">=0.14.0" + "@vueuse/metadata" "10.3.0" + "@vueuse/shared" "10.3.0" + vue-demi ">=0.14.5" -"@vueuse/integrations@^10.1.2": - version "10.1.2" - resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.1.2.tgz#e318ed2cec87711b2a110dceca2150d7fe1452d0" - integrity sha512-wUpG3Wv6LiWerOwCzOAM0iGhNQ4vfFUTkhj/xQy7TLXduh2M3D8N08aS0KqlxsejY6R8NLxydDIM+68QfHZZ8Q== +"@vueuse/integrations@^10.2.1": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.3.0.tgz#765e9505358590f21531998194c6e60a8b23655c" + integrity sha512-Jgiv7oFyIgC6BxmDtiyG/fxyGysIds00YaY7sefwbhCZ2/tjEx1W/1WcsISSJPNI30in28+HC2J4uuU8184ekg== dependencies: - "@vueuse/core" "10.1.2" - "@vueuse/shared" "10.1.2" - vue-demi ">=0.14.0" + "@vueuse/core" "10.3.0" + "@vueuse/shared" "10.3.0" + vue-demi ">=0.14.5" -"@vueuse/metadata@10.1.2": - version "10.1.2" - resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.1.2.tgz#d8ffe557b1042efd03a0aa88540a00c25d193ee3" - integrity sha512-3mc5BqN9aU2SqBeBuWE7ne4OtXHoHKggNgxZR2K+zIW4YLsy6xoZ4/9vErQs6tvoKDX6QAqm3lvsrv0mczAwIQ== +"@vueuse/metadata@10.3.0": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.3.0.tgz#14fe6cc909573785f73a56e4d9351edf3830b796" + integrity sha512-Ema3YhNOa4swDsV0V7CEY5JXvK19JI/o1szFO1iWxdFg3vhdFtCtSTP26PCvbUpnUtNHBY2wx5y3WDXND5Pvnw== -"@vueuse/shared@10.1.2": - version "10.1.2" - resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.1.2.tgz#31d8733a217a6396eb67706319133bf62cdd8baa" - integrity sha512-1uoUTPBlgyscK9v6ScGeVYDDzlPSFXBlxuK7SfrDGyUTBiznb3mNceqhwvZHjtDRELZEN79V5uWPTF1VDV8svA== +"@vueuse/shared@10.3.0": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.3.0.tgz#ce6b4b6860e14aaa293025dcf0cbe1036a25869f" + integrity sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg== dependencies: - vue-demi ">=0.14.0" + vue-demi ">=0.14.5" abab@^2.0.6: version "2.0.6" @@ -930,28 +1061,15 @@ abbrev@1, abbrev@^1.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn-globals@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" - integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== - dependencies: - acorn "^8.1.0" - acorn-walk "^8.0.2" - acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^8.0.2: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.1.0, acorn@^8.8.0, acorn@^8.8.2: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.8.2, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -960,7 +1078,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -971,24 +1089,24 @@ ajv@^6.10.0, ajv@^6.12.4: uri-js "^4.2.2" algoliasearch@^4.0.0: - version "4.17.1" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.17.1.tgz#23926448b815bbf9a921bc6077abc1ce8d3224b2" - integrity sha512-4GDQ1RhP2qUR3x8PevFRbEdqZqIARNViZYjgTJmA1T7wRNtFA3W4Aqc/RsODqa1J8IO/QDla5x4tWuUS8NV8wA== - dependencies: - "@algolia/cache-browser-local-storage" "4.17.1" - "@algolia/cache-common" "4.17.1" - "@algolia/cache-in-memory" "4.17.1" - "@algolia/client-account" "4.17.1" - "@algolia/client-analytics" "4.17.1" - "@algolia/client-common" "4.17.1" - "@algolia/client-personalization" "4.17.1" - "@algolia/client-search" "4.17.1" - "@algolia/logger-common" "4.17.1" - "@algolia/logger-console" "4.17.1" - "@algolia/requester-browser-xhr" "4.17.1" - "@algolia/requester-common" "4.17.1" - "@algolia/requester-node-http" "4.17.1" - "@algolia/transporter" "4.17.1" + version "4.19.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.19.1.tgz#18111fb422eaf841737adb92d5ab12133d244218" + integrity sha512-IJF5b93b2MgAzcE/tuzW0yOPnuUyRgGAtaPv5UUywXM8kzqfdwZTO4sPJBzoGz1eOy6H9uEchsJsBFTELZSu+g== + dependencies: + "@algolia/cache-browser-local-storage" "4.19.1" + "@algolia/cache-common" "4.19.1" + "@algolia/cache-in-memory" "4.19.1" + "@algolia/client-account" "4.19.1" + "@algolia/client-analytics" "4.19.1" + "@algolia/client-common" "4.19.1" + "@algolia/client-personalization" "4.19.1" + "@algolia/client-search" "4.19.1" + "@algolia/logger-common" "4.19.1" + "@algolia/logger-console" "4.19.1" + "@algolia/requester-browser-xhr" "4.19.1" + "@algolia/requester-common" "4.19.1" + "@algolia/requester-node-http" "4.19.1" + "@algolia/transporter" "4.19.1" ansi-colors@4.1.1: version "4.1.1" @@ -1001,9 +1119,9 @@ ansi-regex@^5.0.1: integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-sequence-parser@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz#4d790f31236ac20366b23b3916b789e1bde39aed" - integrity sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" + integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" @@ -1161,6 +1279,11 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +code-block-writer@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" + integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -1185,7 +1308,7 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@2, commander@^2.19.0, commander@^2.20.0: +commander@2, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -1195,6 +1318,11 @@ commander@7: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1525,7 +1653,7 @@ decompress-response@^4.2.0: dependencies: mimic-response "^2.0.0" -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -1553,9 +1681,9 @@ delegates@^1.0.0: integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== diff@5.0.0: version "5.0.0" @@ -1583,15 +1711,15 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" -editorconfig@^0.15.3: - version "0.15.3" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" - integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== +editorconfig@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-1.0.4.tgz#040c9a8e9a6c5288388b87c2db07028aa89f53a3" + integrity sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q== dependencies: - commander "^2.19.0" - lru-cache "^4.1.5" - semver "^5.6.0" - sigmund "^1.0.1" + "@one-ini/wasm" "0.1.1" + commander "^10.0.0" + minimatch "9.0.1" + semver "^7.5.3" emoji-regex@^8.0.0: version "8.0.0" @@ -1603,7 +1731,35 @@ entities@^4.4.0: resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -esbuild@^0.17.5, esbuild@~0.17.6: +esbuild@^0.18.10: + version "0.18.20" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +esbuild@~0.17.6: version "0.17.19" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== @@ -1641,65 +1797,45 @@ escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - eslint-config-prettier@^8.5.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" - integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.16.0: - version "8.42.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.42.0.tgz#7bebdc3a55f9ed7167251fe7259f75219cade291" - integrity sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A== + version "8.47.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.47.0.tgz#c95f9b935463fb4fad7005e626c7621052e90806" + integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.42.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "^8.47.0" "@humanwhocodes/config-array" "^0.11.10" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.1" - espree "^9.5.2" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -1709,7 +1845,6 @@ eslint@^8.16.0: globals "^13.19.0" graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" @@ -1719,25 +1854,19 @@ eslint@^8.16.0: lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" -esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - esquery@^1.4.2: version "1.5.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" @@ -1752,11 +1881,6 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" @@ -1777,10 +1901,10 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.2.12, fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1793,7 +1917,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== @@ -1845,12 +1969,12 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -focus-trap@^7.4.3: - version "7.4.3" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.4.3.tgz#a3dae73d44df359eb92bbf37b18e173e813b16c5" - integrity sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg== +focus-trap@^7.5.2: + version "7.5.2" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.2.tgz#e5ee678d10a18651f2591ffb66c949fb098d57cf" + integrity sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw== dependencies: - tabbable "^6.1.2" + tabbable "^6.2.0" form-data@^4.0.0: version "4.0.0" @@ -1904,9 +2028,9 @@ get-caller-file@^2.0.5: integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-tsconfig@^4.1.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.6.0.tgz#e977690993a42f3e320e932427502a40f7af6d05" - integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== + version "4.7.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.0.tgz#06ce112a1463e93196aa90320c35df5039147e34" + integrity sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw== dependencies: resolve-pkg-maps "^1.0.0" @@ -1960,9 +2084,9 @@ glob@^8.0.3, glob@^8.1.0: once "^1.3.0" globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + version "13.21.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571" + integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== dependencies: type-fest "^0.20.2" @@ -1978,11 +2102,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -2046,12 +2165,12 @@ iconv-lite@0.6, iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2108,10 +2227,10 @@ is-builtin-module@^3.2.1: dependencies: builtin-modules "^3.3.0" -is-core-module@^2.11.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" - integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" @@ -2180,12 +2299,12 @@ isoformat@^0.2.0: integrity sha512-tFLRAygk9NqrRPhJSnNGh7g7oaVWDwR0wKh/GM2LgmPa50Eg4UfyaCO4I8k6EqJHl1/uh2RAD6g06n5ygEnrjQ== js-beautify@1: - version "1.14.8" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.8.tgz#e0c570c15b5445b006de6d9a3e70fb62f9e408e9" - integrity sha512-4S7HFeI9YfRvRgKnEweohs0tgJj28InHVIj4Nl8Htf96Y6pHg3+tJrmo4ucAM9f7l4SHbFI3IvFAZ2a1eQPbyg== + version "1.14.9" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.14.9.tgz#a5db728bc5a0d84d3b1a597c376b29bd4d39c8e5" + integrity sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg== dependencies: config-chain "^1.1.13" - editorconfig "^0.15.3" + editorconfig "^1.0.3" glob "^8.1.0" nopt "^6.0.0" @@ -2196,19 +2315,16 @@ js-yaml@4.1.0, js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsdom@^21.0.0: - version "21.1.2" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-21.1.2.tgz#6433f751b8718248d646af1cdf6662dc8a1ca7f9" - integrity sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ== +jsdom@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-22.1.0.tgz#0fca6d1a37fbeb7f4aac93d1090d782c56b611c8" + integrity sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw== dependencies: abab "^2.0.6" - acorn "^8.8.2" - acorn-globals "^7.0.0" cssstyle "^3.0.0" data-urls "^4.0.0" decimal.js "^10.4.3" domexception "^4.0.0" - escodegen "^2.0.0" form-data "^4.0.0" html-encoding-sniffer "^3.0.0" http-proxy-agent "^5.0.0" @@ -2251,14 +2367,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -2279,14 +2387,6 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -2302,11 +2402,11 @@ magic-string@^0.27.0: "@jridgewell/sourcemap-codec" "^1.4.13" magic-string@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.0.tgz#fd58a4748c5c4547338a424e90fa5dd17f4de529" - integrity sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ== + version "0.30.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.2.tgz#dcf04aad3d0d1314bc743d076c50feb29b3c7aca" + integrity sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug== dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" + "@jridgewell/sourcemap-codec" "^1.4.15" make-dir@^3.1.0: version "3.1.0" @@ -2362,6 +2462,13 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -2376,6 +2483,13 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^7.4.3: + version "7.4.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" + integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== + dependencies: + brace-expansion "^2.0.1" + minipass@^3.0.0: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" @@ -2406,6 +2520,11 @@ mkdirp@^1.0.3: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" + integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== + mocha@^10.0.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" @@ -2434,9 +2553,9 @@ mocha@^10.0.0: yargs-unparser "2.0.0" module-alias@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" - integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== + version "2.2.3" + resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.3.tgz#ec2e85c68973bda6ab71ce7c93b763ec96053221" + integrity sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q== ms@2.1.2: version "2.1.2" @@ -2463,20 +2582,15 @@ nanoid@^3.3.6: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== node-fetch@^2.6.7: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== dependencies: whatwg-url "^5.0.0" @@ -2510,9 +2624,9 @@ npmlog@^5.0.1: set-blocking "^2.0.0" nwsapi@^2.2.4: - version "2.2.5" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.5.tgz#a52744c61b3889dd44b0a158687add39b8d935e2" - integrity sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ== + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== object-assign@^4.1.1: version "4.1.1" @@ -2526,29 +2640,17 @@ once@^1.3.0, once@^1.3.1: dependencies: wrappy "1" -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" p-limit@^3.0.2: version "3.1.0" @@ -2578,6 +2680,11 @@ parse5@^7.1.2: dependencies: entities "^4.4.0" +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -2613,45 +2720,35 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -postcss@^8.1.10, postcss@^8.4.23: - version "8.4.24" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" - integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== +postcss@^8.1.10, postcss@^8.4.26: + version "8.4.28" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.28.tgz#c6cc681ed00109072816e1557f889ef51cf950a5" + integrity sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" preact@^10.0.0: - version "10.15.1" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.15.1.tgz#a1de60c9fc0c79a522d969c65dcaddc5d994eede" - integrity sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g== + version "10.17.0" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.17.0.tgz#77c0e3402767c999ac0f1ba39bd43cd85beab06b" + integrity sha512-SNsI8cbaCcUS5tbv9nlXuCfIXnJ9ysBMWk0WnB6UWwcVA3qZ2O6FxqDFECMAMttvLQcW/HaNZUe2BLidyvrVYw== prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - -prettier@^2.7.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.2.tgz#78fcecd6d870551aa5547437cdae39d4701dca5b" + integrity sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ== proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== - psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -2716,11 +2813,11 @@ resolve-pkg-maps@^1.0.0: integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== resolve@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== dependencies: - is-core-module "^2.11.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -2741,10 +2838,10 @@ robust-predicates@^3.0.0: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== -rollup@^3.21.0, rollup@^3.7.0: - version "3.23.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.23.0.tgz#b8d6146dac4bf058ee817f92820988e9b358b564" - integrity sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ== +rollup@^3.25.2, rollup@^3.7.0: + version "3.28.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.28.0.tgz#a3c70004b01934760c0cb8df717c7a1d932389a2" + integrity sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw== optionalDependencies: fsevents "~2.3.2" @@ -2782,20 +2879,15 @@ saxes@^6.0.0: dependencies: xmlchars "^2.2.0" -semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.3.7: - version "7.5.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" - integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== +semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -2830,21 +2922,16 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shiki@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.2.tgz#d51440800b701392b31ce2336036058e338247a1" - integrity sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A== +shiki@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.3.tgz#d1a93c463942bdafb9866d74d619a4347d0bbf64" + integrity sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g== dependencies: ansi-sequence-parser "^1.1.0" jsonc-parser "^3.2.0" vscode-oniguruma "^1.7.0" vscode-textmate "^8.0.0" -sigmund@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - integrity sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g== - signal-exit@^3.0.0: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -2887,7 +2974,7 @@ source-map-support@^0.5.21, source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@~0.6.1: +source-map@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -2915,7 +3002,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -2944,10 +3031,10 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -tabbable@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.1.2.tgz#b0d3ca81d582d48a80f71b267d1434b1469a3703" - integrity sha512-qCN98uP7i9z0fIS4amQ5zbGBOq+OSigYeGvPy7NDk8Y9yncqDZ9pRPgfsc2PJIVM9RrJj7GIfuRgmjoUU9zTHQ== +tabbable@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" + integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== tar@^6.1.11: version "6.1.15" @@ -2962,9 +3049,9 @@ tar@^6.1.11: yallist "^4.0.0" terser@^5.17.4: - version "5.17.7" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.17.7.tgz#2a8b134826fe179b711969fd9d9a0c2479b2a8c3" - integrity sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ== + version "5.19.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.2.tgz#bdb8017a9a4a8de4663a7983f45c506534f9234e" + integrity sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -2991,9 +3078,9 @@ topojson-client@^3.1.0: commander "2" tough-cookie@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -3012,17 +3099,18 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== +ts-morph@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169" + integrity sha512-D6qcpiJdn46tUqV45vr5UGM2dnIEuTGNxVhg0sk5NX11orcouwj6i1bMqZIz2mZTZB1Hcgy7C3oEVhAT+f6mbQ== dependencies: - tslib "^1.8.1" + "@ts-morph/common" "~0.20.0" + code-block-writer "^12.0.0" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -3031,22 +3119,15 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== typescript@^5.0.2: - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== universalify@^0.2.0: version "0.2.0" @@ -3073,34 +3154,34 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -vite@^4.0.0, vite@^4.3.9: - version "4.3.9" - resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.9.tgz#db896200c0b1aa13b37cdc35c9e99ee2fdd5f96d" - integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg== +vite@4.4.7, vite@^4.4.7: + version "4.4.7" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.7.tgz#71b8a37abaf8d50561aca084dbb77fa342824154" + integrity sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw== dependencies: - esbuild "^0.17.5" - postcss "^8.4.23" - rollup "^3.21.0" + esbuild "^0.18.10" + postcss "^8.4.26" + rollup "^3.25.2" optionalDependencies: fsevents "~2.3.2" -vitepress@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.0.0-beta.2.tgz#b277b8d539c5697db274c0f98172809f9516a9bf" - integrity sha512-DBXYjtYbm3W1IPPJ2TiCaK/XK+o/2XmL2+jslOGKm+txcbmG0kbeB+vadC5tCUZA9NdA+9Ywj3M4548c7t/SDg== +vitepress@1.0.0-beta.7: + version "1.0.0-beta.7" + resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.0.0-beta.7.tgz#edf7f0806e700ed9b08d84e48131d78e453d3a19" + integrity sha512-P9Rw+FXatKIU4fVdtKxqwHl6fby8E/8zE3FIfep6meNgN4BxbWqoKJ6yfuuQQR9IrpQqwnyaBh4LSabyll6tWg== dependencies: - "@docsearch/css" "^3.5.0" - "@docsearch/js" "^3.5.0" + "@docsearch/css" "^3.5.1" + "@docsearch/js" "^3.5.1" "@vitejs/plugin-vue" "^4.2.3" "@vue/devtools-api" "^6.5.0" - "@vueuse/core" "^10.1.2" - "@vueuse/integrations" "^10.1.2" + "@vueuse/core" "^10.2.1" + "@vueuse/integrations" "^10.2.1" body-scroll-lock "4.0.0-beta.0" - focus-trap "^7.4.3" + focus-trap "^7.5.2" mark.js "8.11.1" minisearch "^6.1.0" - shiki "^0.14.2" - vite "^4.3.9" + shiki "^0.14.3" + vite "^4.4.7" vue "^3.3.4" vscode-oniguruma@^1.7.0: @@ -3113,7 +3194,7 @@ vscode-textmate@^8.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== -vue-demi@>=0.14.0: +vue-demi@>=0.14.5: version "0.14.5" resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9" integrity sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA== @@ -3188,11 +3269,6 @@ wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - workerpool@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" @@ -3232,11 +3308,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"