@rowsncolumns/charts 28.1.6 → 28.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/basic-chart/basic-chart.d.ts +1 -1
- package/dist/cjs/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/basic-chart/basic-chart.js +207 -152
- package/dist/cjs/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/chart-editor.js +5 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/cjs/plotly/basic-chart/basic-chart.js +169 -96
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/axis-number-format.d.ts +26 -7
- package/dist/cjs/utils/axis-number-format.d.ts.map +1 -1
- package/dist/cjs/utils/axis-number-format.js +94 -16
- package/dist/cjs/utils/doughnut.d.ts +19 -0
- package/dist/cjs/utils/doughnut.d.ts.map +1 -0
- package/dist/cjs/utils/doughnut.js +28 -0
- package/dist/cjs/utils/overrides.d.ts +12 -3
- package/dist/cjs/utils/overrides.d.ts.map +1 -1
- package/dist/cjs/utils/overrides.js +41 -16
- package/dist/cjs/utils/radar.d.ts +31 -5
- package/dist/cjs/utils/radar.d.ts.map +1 -1
- package/dist/cjs/utils/radar.js +67 -27
- package/dist/esm/basic-chart/basic-chart.d.ts +1 -1
- package/dist/esm/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/basic-chart/basic-chart.js +129 -63
- package/dist/esm/components/editors/chart-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/chart-editor.js +5 -1
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.d.ts.map +1 -1
- package/dist/esm/plotly/basic-chart/basic-chart.js +99 -23
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/axis-number-format.d.ts +26 -7
- package/dist/esm/utils/axis-number-format.d.ts.map +1 -1
- package/dist/esm/utils/axis-number-format.js +83 -13
- package/dist/esm/utils/doughnut.d.ts +19 -0
- package/dist/esm/utils/doughnut.d.ts.map +1 -0
- package/dist/esm/utils/doughnut.js +21 -0
- package/dist/esm/utils/overrides.d.ts +12 -3
- package/dist/esm/utils/overrides.d.ts.map +1 -1
- package/dist/esm/utils/overrides.js +40 -16
- package/dist/esm/utils/radar.d.ts +31 -5
- package/dist/esm/utils/radar.d.ts.map +1 -1
- package/dist/esm/utils/radar.js +44 -16
- package/package.json +4 -4
|
@@ -5,7 +5,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal
|
|
|
5
5
|
import { chartPaletteColorAt, debug, expandChartPalette, isAFormula, isNil, ssfFormat, } from "@rowsncolumns/utils";
|
|
6
6
|
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { aggregateSeriesByDomain, getDomainValuesForAxis, sanitizeDomainValues, shouldAggregateSeries, } from "../../utils/aggregation";
|
|
8
|
-
import { formatAxisValue, numberFormatToPlotlyTicks, resolveSeriesNumberFormats, resolveValueAxisNumberFormat, valueAxisNameGap, } from "../../utils/axis-number-format";
|
|
8
|
+
import { formatAxisValue, numberFormatToPlotlyTicks, plotlySeparators, resolveSeriesNumberFormats, resolveValueAxisNumberFormat, valueAxisNameGap, } from "../../utils/axis-number-format";
|
|
9
9
|
import { computeBoxplotSummary } from "../../utils/boxplot";
|
|
10
10
|
import { createBubbleSizeScale, prepareBubbleSeriesData, toLabelString, } from "../../utils/bubble";
|
|
11
11
|
import { canSwitchRowColumn, cellLabelGetterFromRangeReader, switchRowColumn, } from "../../utils/chart-orientation";
|
|
@@ -17,6 +17,8 @@ import { computeErrorBars, resolveCustomErrorBarValues, } from "../../utils/erro
|
|
|
17
17
|
import { plotlyMulticategoryX, resolveCategoryLevels, } from "../../utils/category-levels";
|
|
18
18
|
import { gradientToPlotly } from "../../utils/gradient";
|
|
19
19
|
import { BAND_GAP, legendLabelsFrom, measureTextWidth, reservePlotlyLegendBand, } from "../../utils/legend-layout";
|
|
20
|
+
import { clampDoughnutHole, doughnutRings } from "../../utils/doughnut";
|
|
21
|
+
import { resolveSeriesDataLabels } from "../../utils/overrides";
|
|
20
22
|
import { plotlyTitleText } from "../../utils/plotly-title";
|
|
21
23
|
import { explosionToPlotlyPull, resolveExplosion, } from "../../utils/pie-explosion";
|
|
22
24
|
import { resolvePlotlyClickSelection, wasDragged, } from "../../utils/plotly-click";
|
|
@@ -179,14 +181,44 @@ const PLOTLY_DLBL_POS_BAR = {
|
|
|
179
181
|
insideEnd: "inside",
|
|
180
182
|
outsideEnd: "outside",
|
|
181
183
|
bestFit: "outside",
|
|
184
|
+
above: "outside",
|
|
185
|
+
below: "outside",
|
|
186
|
+
left: "outside",
|
|
187
|
+
right: "outside",
|
|
182
188
|
};
|
|
183
|
-
|
|
189
|
+
// A scatter trace (line / area / scatter) places its text with the compass
|
|
190
|
+
// positions, and only draws it when `mode` carries `text`. Excel's line
|
|
191
|
+
// placements are centre / left / right / above / below; the bar-only ones
|
|
192
|
+
// land on Excel's default for a line, above the point (#1049).
|
|
193
|
+
const PLOTLY_DLBL_POS_POINT = {
|
|
194
|
+
center: "middle center",
|
|
195
|
+
inside: "middle center",
|
|
196
|
+
outside: "top center",
|
|
197
|
+
insideEnd: "top center",
|
|
198
|
+
outsideEnd: "top center",
|
|
199
|
+
bestFit: "top center",
|
|
200
|
+
above: "top center",
|
|
201
|
+
below: "bottom center",
|
|
202
|
+
left: "middle left",
|
|
203
|
+
right: "middle right",
|
|
204
|
+
};
|
|
205
|
+
const withTextMode = (mode) => {
|
|
206
|
+
const base = typeof mode === "string" && mode ? mode : "lines+markers";
|
|
207
|
+
return base.split("+").includes("text") ? base : `${base}+text`;
|
|
208
|
+
};
|
|
209
|
+
const applyDataLabelsToTracePlotly = (trace, opts, chartType, sourceNumberFormat, locale) => {
|
|
184
210
|
if (!opts?.show)
|
|
185
211
|
return trace;
|
|
186
212
|
const next = { ...trace };
|
|
187
213
|
const isCircular = chartType === "pie" || chartType === "doughnut";
|
|
188
|
-
const
|
|
189
|
-
const
|
|
214
|
+
const isPoint = !isCircular && next.type === "scatter";
|
|
215
|
+
const posMap = isCircular
|
|
216
|
+
? PLOTLY_DLBL_POS_PIE
|
|
217
|
+
: isPoint
|
|
218
|
+
? PLOTLY_DLBL_POS_POINT
|
|
219
|
+
: PLOTLY_DLBL_POS_BAR;
|
|
220
|
+
const fallback = isPoint ? "top center" : "inside";
|
|
221
|
+
const position = opts.position ? posMap[opts.position] ?? fallback : fallback;
|
|
190
222
|
if (isCircular) {
|
|
191
223
|
// Plotly's pie trace uses `textinfo` to control which fields render.
|
|
192
224
|
const parts = [];
|
|
@@ -204,7 +236,7 @@ const applyDataLabelsToTracePlotly = (trace, opts, chartType, sourceNumberFormat
|
|
|
204
236
|
const pattern = opts.numberFormatPattern ?? sourceNumberFormat;
|
|
205
237
|
if (pattern) {
|
|
206
238
|
const values = Array.isArray(next.values) ? next.values : [];
|
|
207
|
-
next.text = values.map((v) => formatAxisValue(pattern, v));
|
|
239
|
+
next.text = values.map((v) => formatAxisValue(pattern, v, locale));
|
|
208
240
|
next.texttemplate = next.textinfo
|
|
209
241
|
.split("+")
|
|
210
242
|
.map((part) => (part === "value" ? "%{text}" : `%{${part}}`))
|
|
@@ -223,9 +255,13 @@ const applyDataLabelsToTracePlotly = (trace, opts, chartType, sourceNumberFormat
|
|
|
223
255
|
const values = next.orientation === "h" ? next.x : next.y;
|
|
224
256
|
const vals = Array.isArray(values) ? values : [];
|
|
225
257
|
next.text = pattern
|
|
226
|
-
? vals.map((v) =>
|
|
227
|
-
:
|
|
258
|
+
? vals.map((v) => v === null || v === undefined ? "" : ssfFormat(pattern, v, locale))
|
|
259
|
+
: locale
|
|
260
|
+
? vals.map((v) => formatAxisValue(undefined, v, locale))
|
|
261
|
+
: values;
|
|
228
262
|
next.textposition = position;
|
|
263
|
+
if (isPoint)
|
|
264
|
+
next.mode = withTextMode(next.mode);
|
|
229
265
|
}
|
|
230
266
|
return next;
|
|
231
267
|
};
|
|
@@ -345,7 +381,7 @@ const addAlphaToColor = (color, alpha) => {
|
|
|
345
381
|
}
|
|
346
382
|
return color;
|
|
347
383
|
};
|
|
348
|
-
export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, readonly, getDomainValuesFromRange, getSeriesValuesFromRange, getFormattingFromRange, onDeleteChart, onUpdateChart, onRequestEdit, onRequestCalculate, isSelected, fieldButtons, }) => {
|
|
384
|
+
export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, readonly, getDomainValuesFromRange, getSeriesValuesFromRange, getFormattingFromRange, onDeleteChart, onUpdateChart, onRequestEdit, onRequestCalculate, isSelected, fieldButtons, locale, }) => {
|
|
349
385
|
const spec = chart.spec;
|
|
350
386
|
const hierarchyTitleRef = useRef(undefined);
|
|
351
387
|
const explicitChartTitle = chart.spec.title ?? undefined;
|
|
@@ -848,7 +884,10 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
848
884
|
}
|
|
849
885
|
// buildRadarIndicators keeps category/value alignment consistent
|
|
850
886
|
// with the echarts renderer (and validates we have axes).
|
|
851
|
-
|
|
887
|
+
// One value scale for every axis (Excel), from the spec's value-axis
|
|
888
|
+
// min / max when set (#1066).
|
|
889
|
+
const radarAxisOptions = spec.valueAxisOptions;
|
|
890
|
+
const indicators = buildRadarIndicators(categories, radarInputs, radarAxisOptions);
|
|
852
891
|
for (let i = 0; i < radarInputs.length; i++) {
|
|
853
892
|
const input = radarInputs[i];
|
|
854
893
|
const seriesColor = spec.series?.[i]?.color ?? undefined;
|
|
@@ -864,7 +903,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
864
903
|
...(seriesColor ? { line: { color: seriesColor } } : {}),
|
|
865
904
|
});
|
|
866
905
|
}
|
|
867
|
-
const
|
|
906
|
+
const radarScale = indicators[0] ?? { min: 0, max: 1 };
|
|
868
907
|
setPlotData(radarTraces);
|
|
869
908
|
setLayout({
|
|
870
909
|
title: { text: plotlyTitleText(title, spec.titleTextFormat) },
|
|
@@ -874,8 +913,8 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
874
913
|
showlegend: radarTraces.length > 1,
|
|
875
914
|
polar: {
|
|
876
915
|
radialaxis: {
|
|
877
|
-
visible:
|
|
878
|
-
range: [
|
|
916
|
+
visible: radarAxisOptions?.visible !== false,
|
|
917
|
+
range: [radarScale.min, radarScale.max],
|
|
879
918
|
},
|
|
880
919
|
},
|
|
881
920
|
margin: { l: 50, r: 50, t: 50, b: 50 },
|
|
@@ -1833,6 +1872,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1833
1872
|
: valueAxisNameGap({
|
|
1834
1873
|
values: primaryValues,
|
|
1835
1874
|
pattern: primaryAxisNumberFormat,
|
|
1875
|
+
locale,
|
|
1836
1876
|
fontSize: axisFontSize,
|
|
1837
1877
|
minimum: 0,
|
|
1838
1878
|
}) -
|
|
@@ -1848,6 +1888,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
1848
1888
|
? trace.y
|
|
1849
1889
|
: []),
|
|
1850
1890
|
pattern: secondaryAxisNumberFormat,
|
|
1891
|
+
locale,
|
|
1851
1892
|
fontSize: axisFontSize,
|
|
1852
1893
|
minimum: 0,
|
|
1853
1894
|
}) -
|
|
@@ -2008,8 +2049,26 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2008
2049
|
: {}),
|
|
2009
2050
|
};
|
|
2010
2051
|
// Phase 5.1: apply data labels per trace, and set the doughnut hole
|
|
2011
|
-
// when chartType === "doughnut".
|
|
2052
|
+
// when chartType === "doughnut". A series' own `dataLabels` replace the
|
|
2053
|
+
// chart-level ones for its trace (#1059).
|
|
2012
2054
|
const dlOpts = spec.dataLabels;
|
|
2055
|
+
// Excel nests a doughnut's series as concentric rings, series 0
|
|
2056
|
+
// innermost (#1065): each pie trace is scaled into a centred sub-domain
|
|
2057
|
+
// whose radius is its ring's outer edge, with the hole at the inner one.
|
|
2058
|
+
const doughnutSeriesOrder = spec.chartType === "doughnut"
|
|
2059
|
+
? traces
|
|
2060
|
+
.filter((t) => t?.type === "pie")
|
|
2061
|
+
.map((t) => t?.meta?.rncSeriesIndex)
|
|
2062
|
+
.filter((i) => typeof i === "number")
|
|
2063
|
+
.sort((a, b) => a - b)
|
|
2064
|
+
: [];
|
|
2065
|
+
const doughnutRingSet = spec.chartType === "doughnut"
|
|
2066
|
+
? doughnutRings(clampDoughnutHole(spec.doughnutHoleSize), doughnutSeriesOrder.length)
|
|
2067
|
+
: [];
|
|
2068
|
+
const traceDataLabels = (trace) => {
|
|
2069
|
+
const specIndex = trace?.meta?.rncSeriesIndex;
|
|
2070
|
+
return resolveSeriesDataLabels(dlOpts, typeof specIndex === "number" ? spec.series?.[specIndex] : undefined);
|
|
2071
|
+
};
|
|
2013
2072
|
const doughnutHole = spec.doughnutHoleSize;
|
|
2014
2073
|
// Data labels are linked to each series' OWN source cells (Excel's
|
|
2015
2074
|
// `<c:dLbls><c:numFmt sourceLinked="1">`); the axis format only steps
|
|
@@ -2028,14 +2087,19 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2028
2087
|
const piePull = isOfPie ? undefined : explosionToPlotlyPull(resolveExplosion(spec));
|
|
2029
2088
|
const formattedTraces = traces.map((trace) => {
|
|
2030
2089
|
const pattern = traceNumberFormat(trace);
|
|
2031
|
-
let next = applyDataLabelsToTracePlotly(trace,
|
|
2090
|
+
let next = applyDataLabelsToTracePlotly(trace, traceDataLabels(trace), spec.chartType, pattern, locale);
|
|
2032
2091
|
if (next.type === "pie") {
|
|
2092
|
+
// Plotly's pie prints every slice's percentage by default; Excel
|
|
2093
|
+
// draws nothing until data labels are on (#1062).
|
|
2094
|
+
if (!traceDataLabels(trace)?.show) {
|
|
2095
|
+
next = { ...next, textinfo: "none" };
|
|
2096
|
+
}
|
|
2033
2097
|
// Hover values format like the slice's source cell.
|
|
2034
2098
|
if (pattern && !next.text) {
|
|
2035
2099
|
const values = Array.isArray(next.values) ? next.values : [];
|
|
2036
2100
|
next = {
|
|
2037
2101
|
...next,
|
|
2038
|
-
text: values.map((v) => formatAxisValue(pattern, v)),
|
|
2102
|
+
text: values.map((v) => formatAxisValue(pattern, v, locale)),
|
|
2039
2103
|
hoverinfo: "label+text+percent+name",
|
|
2040
2104
|
};
|
|
2041
2105
|
}
|
|
@@ -2062,7 +2126,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2062
2126
|
if (seriesPattern && Array.isArray(values)) {
|
|
2063
2127
|
next = {
|
|
2064
2128
|
...next,
|
|
2065
|
-
customdata: values.map((v) => formatAxisValue(seriesPattern, v)),
|
|
2129
|
+
customdata: values.map((v) => formatAxisValue(seriesPattern, v, locale)),
|
|
2066
2130
|
hovertemplate: `${horizontal ? "%{y}" : "%{x}"}<br>%{customdata}<extra>%{fullData.name}</extra>`,
|
|
2067
2131
|
};
|
|
2068
2132
|
}
|
|
@@ -2072,12 +2136,17 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2072
2136
|
// (doughnutHoleSize); clamp like the echarts renderer and default
|
|
2073
2137
|
// to 0.5 when unset.
|
|
2074
2138
|
if (spec.chartType === "doughnut" && next.type === "pie") {
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2139
|
+
const rank = doughnutSeriesOrder.indexOf(next.meta?.rncSeriesIndex);
|
|
2140
|
+
const ring = doughnutRingSet[rank] ?? doughnutRings(clampDoughnutHole(doughnutHole), 1)[0];
|
|
2141
|
+
// Plotly's `hole` is a fraction of the trace's own radius.
|
|
2142
|
+
next = { ...next, hole: ring.inner / ring.outer };
|
|
2143
|
+
if (doughnutRingSet.length > 1) {
|
|
2144
|
+
const half = ring.outer / 2;
|
|
2145
|
+
next = {
|
|
2146
|
+
...next,
|
|
2147
|
+
domain: { x: [0.5 - half, 0.5 + half], y: [0.5 - half, 0.5 + half] },
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2081
2150
|
}
|
|
2082
2151
|
return next;
|
|
2083
2152
|
});
|
|
@@ -2104,6 +2173,7 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2104
2173
|
getDomainValuesFromRange,
|
|
2105
2174
|
getSeriesValuesFromRange,
|
|
2106
2175
|
getFormattingFromRange,
|
|
2176
|
+
locale,
|
|
2107
2177
|
]);
|
|
2108
2178
|
// Update theme
|
|
2109
2179
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -2141,7 +2211,13 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
|
|
|
2141
2211
|
scrollZoom: false,
|
|
2142
2212
|
doubleClick: false,
|
|
2143
2213
|
};
|
|
2144
|
-
|
|
2214
|
+
// Ticks and hover values plotly formats itself use the sheet's separators.
|
|
2215
|
+
const separators = useMemo(() => plotlySeparators(locale), [locale]);
|
|
2216
|
+
const plotLayout = useMemo(() => ({
|
|
2217
|
+
...layout,
|
|
2218
|
+
dragmode: false,
|
|
2219
|
+
...(separators ? { separators } : {}),
|
|
2220
|
+
}), [layout, separators]);
|
|
2145
2221
|
// Excel's "Rounded Corners" chart frame (`<c:roundedCorners val="1"/>`
|
|
2146
2222
|
// at the chartSpace root). Default per OOXML §21.2.2.183 is square,
|
|
2147
2223
|
// so only opt in when the workbook explicitly set the flag.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../../config.ts","../../echarts-gl.d.ts","../../geo-modules.d.ts","../../index.ts","../../plotly-dist.d.ts","../../types.ts","../../vitest.config.ts","../../atoms/editing-chart.atom.ts","../../atoms/pivot-chart.atom.ts","../../basic-chart/basic-chart.tsx","../../basic-chart/helpers.ts","../../basic-chart/index.tsx","../../components/dialogs/chart-editor-dialog.tsx","../../components/dialogs/pivot-chart-dialog.tsx","../../components/editors/chart-editor.tsx","../../components/editors/chart-range-input.tsx","../../hooks/use-chart-editor.ts","../../hooks/use-charts.ts","../../hooks/use-on-create-chart.ts","../../hooks/use-on-delete-chart.ts","../../hooks/use-on-move-chart-to-sheet.ts","../../hooks/use-on-move-chart.ts","../../hooks/use-on-resize-chart.ts","../../hooks/use-on-update-chart.ts","../../interface/create-chart.ts","../../interface/delete-chart.ts","../../interface/move-chart-to-sheet.ts","../../interface/move-chart.ts","../../interface/resize-chart.ts","../../interface/shift-chart-ranges.ts","../../interface/update-chart.ts","../../plotly/plot.ts","../../plotly/basic-chart/basic-chart.tsx","../../plotly/basic-chart/helpers.ts","../../plotly/basic-chart/index.tsx","../../utils/aggregation.ts","../../utils/axis-number-format.ts","../../utils/bar-layout.ts","../../utils/boxplot.ts","../../utils/bubble.ts","../../utils/category-levels.ts","../../utils/chart-image.ts","../../utils/chart-orientation.ts","../../utils/chart-spec-utils.ts","../../utils/chart-styles.ts","../../utils/echarts-gl-loader.ts","../../utils/empty-cells.ts","../../utils/error-bars.ts","../../utils/gradient.ts","../../utils/hierarchy.ts","../../utils/histogram.ts","../../utils/legend-layout.ts","../../utils/of-pie.ts","../../utils/overrides.ts","../../utils/pie-explosion.ts","../../utils/plotly-click.ts","../../utils/plotly-surface.ts","../../utils/plotly-title.ts","../../utils/radar.ts","../../utils/region-map-loader.ts","../../utils/region-map.ts","../../utils/series-click.ts","../../utils/stock.ts","../../utils/three-d.ts","../../utils/trendline.ts","../../utils/waterfall.ts","../../utils/webgl.ts"],"version":"5.8.3"}
|
|
1
|
+
{"root":["../../config.ts","../../echarts-gl.d.ts","../../geo-modules.d.ts","../../index.ts","../../plotly-dist.d.ts","../../types.ts","../../vitest.config.ts","../../atoms/editing-chart.atom.ts","../../atoms/pivot-chart.atom.ts","../../basic-chart/basic-chart.tsx","../../basic-chart/helpers.ts","../../basic-chart/index.tsx","../../components/dialogs/chart-editor-dialog.tsx","../../components/dialogs/pivot-chart-dialog.tsx","../../components/editors/chart-editor.tsx","../../components/editors/chart-range-input.tsx","../../hooks/use-chart-editor.ts","../../hooks/use-charts.ts","../../hooks/use-on-create-chart.ts","../../hooks/use-on-delete-chart.ts","../../hooks/use-on-move-chart-to-sheet.ts","../../hooks/use-on-move-chart.ts","../../hooks/use-on-resize-chart.ts","../../hooks/use-on-update-chart.ts","../../interface/create-chart.ts","../../interface/delete-chart.ts","../../interface/move-chart-to-sheet.ts","../../interface/move-chart.ts","../../interface/resize-chart.ts","../../interface/shift-chart-ranges.ts","../../interface/update-chart.ts","../../plotly/plot.ts","../../plotly/basic-chart/basic-chart.tsx","../../plotly/basic-chart/helpers.ts","../../plotly/basic-chart/index.tsx","../../utils/aggregation.ts","../../utils/axis-number-format.ts","../../utils/bar-layout.ts","../../utils/boxplot.ts","../../utils/bubble.ts","../../utils/category-levels.ts","../../utils/chart-image.ts","../../utils/chart-orientation.ts","../../utils/chart-spec-utils.ts","../../utils/chart-styles.ts","../../utils/doughnut.ts","../../utils/echarts-gl-loader.ts","../../utils/empty-cells.ts","../../utils/error-bars.ts","../../utils/gradient.ts","../../utils/hierarchy.ts","../../utils/histogram.ts","../../utils/legend-layout.ts","../../utils/of-pie.ts","../../utils/overrides.ts","../../utils/pie-explosion.ts","../../utils/plotly-click.ts","../../utils/plotly-surface.ts","../../utils/plotly-title.ts","../../utils/radar.ts","../../utils/region-map-loader.ts","../../utils/region-map.ts","../../utils/series-click.ts","../../utils/stock.ts","../../utils/three-d.ts","../../utils/trendline.ts","../../utils/waterfall.ts","../../utils/webgl.ts"],"version":"5.8.3"}
|
|
@@ -26,17 +26,28 @@ export declare const resolveValueAxisNumberFormat: ({ axisOptions, series, getFo
|
|
|
26
26
|
getFormattingFromRange: RangeFormatReader | undefined;
|
|
27
27
|
hiddenDimensionStrategy?: HIDDEN_DIMENSION_STRATEGY | null;
|
|
28
28
|
}) => string | undefined;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
export declare const formatPlainNumber: (value: number, locale: string | undefined, grouping?: boolean) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Format one numeric value through the resolved pattern; non-numbers pass
|
|
32
|
+
* through. `locale` is the spreadsheet locale the cells format with: it
|
|
33
|
+
* picks the pattern's separators, and a number without a pattern reads
|
|
34
|
+
* like a `General` cell in that locale.
|
|
35
|
+
*/
|
|
36
|
+
export declare const formatAxisValue: (pattern: string | undefined, value: unknown, locale?: string) => string;
|
|
37
|
+
/**
|
|
38
|
+
* echarts `axisLabel.formatter` / `tooltip.valueFormatter` for a value
|
|
39
|
+
* axis. Without a pattern the ticks keep echarts' own labels unless a
|
|
40
|
+
* locale is given, in which case they group thousands the way echarts
|
|
41
|
+
* does but with the locale's separators (#1050).
|
|
42
|
+
*/
|
|
43
|
+
export declare const valueAxisLabelFormatter: (pattern: string | undefined, locale?: string) => ((value: unknown) => string) | undefined;
|
|
33
44
|
/**
|
|
34
45
|
* echarts `tooltip.valueFormatter` for a series whose data items are
|
|
35
46
|
* tuples (candlestick, 3-D points): every number formats through the
|
|
36
47
|
* pattern; `undefined` when there is no pattern so echarts keeps its
|
|
37
48
|
* default.
|
|
38
49
|
*/
|
|
39
|
-
export declare const tooltipValueFormatter: (pattern: string | undefined) => ((value: unknown) => string | string[]) | undefined;
|
|
50
|
+
export declare const tooltipValueFormatter: (pattern: string | undefined, locale?: string) => ((value: unknown) => string | string[]) | undefined;
|
|
40
51
|
/**
|
|
41
52
|
* Excel's data labels and tooltips are linked to *each series' own* source
|
|
42
53
|
* cells, not to the axis: a revenue series formatted `$#,##0` next to a
|
|
@@ -45,11 +56,18 @@ export declare const tooltipValueFormatter: (pattern: string | undefined) => ((v
|
|
|
45
56
|
*/
|
|
46
57
|
export declare const resolveSeriesNumberFormats: (series: Pick<ChartData, "sources">[] | undefined, getFormattingFromRange: RangeFormatReader | undefined, hiddenDimensionStrategy?: HIDDEN_DIMENSION_STRATEGY | null) => (string | undefined)[];
|
|
47
58
|
/** echarts pie / doughnut tooltip: `name: value (percent%)` with the value formatted. */
|
|
48
|
-
export declare const circularTooltipFormatter: (pattern: string | undefined) => (params: {
|
|
59
|
+
export declare const circularTooltipFormatter: (pattern: string | undefined, locale?: string) => (params: {
|
|
49
60
|
name?: string;
|
|
50
61
|
value?: unknown;
|
|
51
62
|
percent?: number;
|
|
52
63
|
}) => string;
|
|
64
|
+
/**
|
|
65
|
+
* plotly `layout.separators` for the spreadsheet locale: the decimal
|
|
66
|
+
* separator followed by the thousands separator, so ticks and hover
|
|
67
|
+
* values plotly formats itself read like the sheet's cells (#1050).
|
|
68
|
+
* `undefined` without a locale keeps plotly's default (`.,`).
|
|
69
|
+
*/
|
|
70
|
+
export declare const plotlySeparators: (locale: string | undefined) => string | undefined;
|
|
53
71
|
export type PlotlyTickFormat = {
|
|
54
72
|
tickformat?: string;
|
|
55
73
|
tickprefix?: string;
|
|
@@ -73,9 +91,10 @@ export declare const numberFormatToPlotlyTicks: (pattern: string | undefined) =>
|
|
|
73
91
|
* measured; the fixed default of 50px only fits labels up to ~4 digits and
|
|
74
92
|
* lets a currency axis title paint over its own tick labels.
|
|
75
93
|
*/
|
|
76
|
-
export declare const valueAxisNameGap: ({ values, pattern, fontSize, minimum, }: {
|
|
94
|
+
export declare const valueAxisNameGap: ({ values, pattern, locale, fontSize, minimum, }: {
|
|
77
95
|
values: readonly unknown[];
|
|
78
96
|
pattern: string | undefined;
|
|
97
|
+
locale?: string;
|
|
79
98
|
fontSize?: number;
|
|
80
99
|
minimum?: number;
|
|
81
100
|
}) => number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axis-number-format.d.ts","sourceRoot":"","sources":["../../../utils/axis-number-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,yBAAyB,EACzB,KAAK,EACL,UAAU,EACX,MAAM,2BAA2B,CAAC;AAWnC,KAAK,iBAAiB,GAAG,CACvB,UAAU,EAAE,UAAU,EACtB,uBAAuB,CAAC,EAAE,yBAAyB,KAChD,OAAO,EAAE,CAAC;AAMf;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,GAAG,SAAS,YAGjC,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GACpC,SAAS,UAAU,EAAE,GAAG,SAAS,EACjC,wBAAwB,iBAAiB,GAAG,SAAS,EACrD,0BAA0B,yBAAyB,GAAG,IAAI,KACzD,MAAM,GAAG,SAWX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,2EAK1C;IACD,WAAW,EAAE,KAAK,CAAC;QAAE,mBAAmB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACxE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;IACrC,sBAAsB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtD,uBAAuB,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC5D,KAAG,MAAM,GAAG,SAQZ,CAAC;
|
|
1
|
+
{"version":3,"file":"axis-number-format.d.ts","sourceRoot":"","sources":["../../../utils/axis-number-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,26 +37,76 @@ export const resolveValueAxisNumberFormat = ({ axisOptions, series, getFormattin
|
|
|
37
37
|
return isGeneralNumberFormat(explicit) ? undefined : explicit;
|
|
38
38
|
return resolveSourceNumberFormat(series[0]?.sources, getFormattingFromRange, hiddenDimensionStrategy);
|
|
39
39
|
};
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// A number with no number format, in the spreadsheet locale (#1050). The
|
|
41
|
+
// grid's cells show such a value through `General` — the locale's decimal
|
|
42
|
+
// separator, no grouping — so a data label or tooltip reads the same;
|
|
43
|
+
// echarts' default tick label groups thousands, so ticks keep grouping.
|
|
44
|
+
// `toPrecision(15)` is Excel's significant-digit view of the double, which
|
|
45
|
+
// drops binary noise such as `0.30000000000000004`.
|
|
46
|
+
const plainNumberFormatters = new Map();
|
|
47
|
+
const plainNumberFormatter = (locale, grouping) => {
|
|
48
|
+
const key = `${locale}\u0000${grouping ? 1 : 0}`;
|
|
49
|
+
let formatter = plainNumberFormatters.get(key);
|
|
50
|
+
if (!formatter) {
|
|
51
|
+
try {
|
|
52
|
+
formatter = new Intl.NumberFormat(locale, {
|
|
53
|
+
useGrouping: grouping,
|
|
54
|
+
maximumFractionDigits: 20,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
formatter = new Intl.NumberFormat("en-US", {
|
|
59
|
+
useGrouping: grouping,
|
|
60
|
+
maximumFractionDigits: 20,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
plainNumberFormatters.set(key, formatter);
|
|
64
|
+
}
|
|
65
|
+
return formatter;
|
|
66
|
+
};
|
|
67
|
+
export const formatPlainNumber = (value, locale, grouping = false) => Number.isFinite(value)
|
|
68
|
+
? plainNumberFormatter(locale ?? "en-US", grouping).format(Number(value.toPrecision(15)))
|
|
69
|
+
: String(value);
|
|
70
|
+
/**
|
|
71
|
+
* Format one numeric value through the resolved pattern; non-numbers pass
|
|
72
|
+
* through. `locale` is the spreadsheet locale the cells format with: it
|
|
73
|
+
* picks the pattern's separators, and a number without a pattern reads
|
|
74
|
+
* like a `General` cell in that locale.
|
|
75
|
+
*/
|
|
76
|
+
export const formatAxisValue = (pattern, value, locale) => {
|
|
42
77
|
if (value === undefined || value === null)
|
|
43
78
|
return "";
|
|
44
|
-
if (
|
|
45
|
-
|
|
79
|
+
if (typeof value === "number") {
|
|
80
|
+
if (pattern)
|
|
81
|
+
return ssfFormat(pattern, value, locale);
|
|
82
|
+
if (locale)
|
|
83
|
+
return formatPlainNumber(value, locale);
|
|
84
|
+
}
|
|
46
85
|
return String(value);
|
|
47
86
|
};
|
|
48
|
-
/**
|
|
49
|
-
|
|
87
|
+
/**
|
|
88
|
+
* echarts `axisLabel.formatter` / `tooltip.valueFormatter` for a value
|
|
89
|
+
* axis. Without a pattern the ticks keep echarts' own labels unless a
|
|
90
|
+
* locale is given, in which case they group thousands the way echarts
|
|
91
|
+
* does but with the locale's separators (#1050).
|
|
92
|
+
*/
|
|
93
|
+
export const valueAxisLabelFormatter = (pattern, locale) => pattern
|
|
94
|
+
? (value) => formatAxisValue(pattern, value, locale)
|
|
95
|
+
: locale
|
|
96
|
+
? (value) => typeof value === "number"
|
|
97
|
+
? formatPlainNumber(value, locale, true)
|
|
98
|
+
: formatAxisValue(undefined, value)
|
|
99
|
+
: undefined;
|
|
50
100
|
/**
|
|
51
101
|
* echarts `tooltip.valueFormatter` for a series whose data items are
|
|
52
102
|
* tuples (candlestick, 3-D points): every number formats through the
|
|
53
103
|
* pattern; `undefined` when there is no pattern so echarts keeps its
|
|
54
104
|
* default.
|
|
55
105
|
*/
|
|
56
|
-
export const tooltipValueFormatter = (pattern) => pattern
|
|
106
|
+
export const tooltipValueFormatter = (pattern, locale) => pattern
|
|
57
107
|
? (value) => Array.isArray(value)
|
|
58
|
-
? value.map((entry) => formatAxisValue(pattern, entry))
|
|
59
|
-
: formatAxisValue(pattern, value)
|
|
108
|
+
? value.map((entry) => formatAxisValue(pattern, entry, locale))
|
|
109
|
+
: formatAxisValue(pattern, value, locale)
|
|
60
110
|
: undefined;
|
|
61
111
|
/**
|
|
62
112
|
* Excel's data labels and tooltips are linked to *each series' own* source
|
|
@@ -66,7 +116,27 @@ export const tooltipValueFormatter = (pattern) => pattern
|
|
|
66
116
|
*/
|
|
67
117
|
export const resolveSeriesNumberFormats = (series, getFormattingFromRange, hiddenDimensionStrategy) => (series ?? []).map((entry) => resolveSourceNumberFormat(entry?.sources, getFormattingFromRange, hiddenDimensionStrategy));
|
|
68
118
|
/** echarts pie / doughnut tooltip: `name: value (percent%)` with the value formatted. */
|
|
69
|
-
export const circularTooltipFormatter = (pattern) => (params) => `${params.name ?? ""}: ${formatAxisValue(pattern, params.value)} (${params.percent ?? ""}%)`;
|
|
119
|
+
export const circularTooltipFormatter = (pattern, locale) => (params) => `${params.name ?? ""}: ${formatAxisValue(pattern, params.value, locale)} (${params.percent ?? ""}%)`;
|
|
120
|
+
/**
|
|
121
|
+
* plotly `layout.separators` for the spreadsheet locale: the decimal
|
|
122
|
+
* separator followed by the thousands separator, so ticks and hover
|
|
123
|
+
* values plotly formats itself read like the sheet's cells (#1050).
|
|
124
|
+
* `undefined` without a locale keeps plotly's default (`.,`).
|
|
125
|
+
*/
|
|
126
|
+
export const plotlySeparators = (locale) => {
|
|
127
|
+
if (!locale)
|
|
128
|
+
return undefined;
|
|
129
|
+
let parts;
|
|
130
|
+
try {
|
|
131
|
+
parts = new Intl.NumberFormat(locale).formatToParts(1234.5);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
const decimal = parts.find((p) => p.type === "decimal")?.value ?? ".";
|
|
137
|
+
const group = parts.find((p) => p.type === "group")?.value ?? ",";
|
|
138
|
+
return `${decimal}${group}`;
|
|
139
|
+
};
|
|
70
140
|
/**
|
|
71
141
|
* Translate the numeric subset of a SpreadsheetML pattern into plotly's
|
|
72
142
|
* d3-format axis settings (`tickformat` + literal prefix / suffix). Plotly
|
|
@@ -190,15 +260,15 @@ const measureLabelWidth = (text, fontSize) => {
|
|
|
190
260
|
* measured; the fixed default of 50px only fits labels up to ~4 digits and
|
|
191
261
|
* lets a currency axis title paint over its own tick labels.
|
|
192
262
|
*/
|
|
193
|
-
export const valueAxisNameGap = ({ values, pattern, fontSize = 12, minimum = 50, }) => {
|
|
263
|
+
export const valueAxisNameGap = ({ values, pattern, locale, fontSize = 12, minimum = 50, }) => {
|
|
194
264
|
const numbers = values.filter((v) => typeof v === "number" && Number.isFinite(v));
|
|
195
265
|
if (!numbers.length)
|
|
196
266
|
return minimum;
|
|
197
267
|
const min = Math.min(...numbers, 0);
|
|
198
268
|
const max = Math.max(...numbers, 0);
|
|
199
269
|
// echarts' default axis label puts thousands separators on plain numbers.
|
|
200
|
-
const defaultLabel = (v) => v
|
|
201
|
-
const labels = [min, max].map((v) => pattern ? formatAxisValue(pattern, v) : defaultLabel(v));
|
|
270
|
+
const defaultLabel = (v) => formatPlainNumber(v, locale, true);
|
|
271
|
+
const labels = [min, max].map((v) => pattern ? formatAxisValue(pattern, v, locale) : defaultLabel(v));
|
|
202
272
|
const widest = Math.max(...labels.map((l) => measureLabelWidth(l, fontSize)));
|
|
203
273
|
// 8px tick-label margin + the rotated title's own line box + breathing room.
|
|
204
274
|
const AXIS_LABEL_MARGIN = 8;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doughnut geometry shared by the renderers (rowsncolumns/spreadsheet#1064,
|
|
3
|
+
* #1065). Every fraction here is of the doughnut's OUTER radius — Excel's
|
|
4
|
+
* `<c:holeSize val="75"/>` is 0.75 of the outer edge, whatever the chart
|
|
5
|
+
* draws that edge at (echarts: 75% of the chart; plotly: the trace domain).
|
|
6
|
+
*/
|
|
7
|
+
/** `doughnutHoleSize` clamped to Excel's 0-90% range; 0.5 when unset. */
|
|
8
|
+
export declare const clampDoughnutHole: (hole: unknown) => number;
|
|
9
|
+
export type DoughnutRing = {
|
|
10
|
+
inner: number;
|
|
11
|
+
outer: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Excel draws a doughnut's series as concentric rings, nested from the hole
|
|
15
|
+
* outwards — series 0 innermost — splitting the band between the hole and
|
|
16
|
+
* the outer edge evenly. One ring (the whole band) for a single series.
|
|
17
|
+
*/
|
|
18
|
+
export declare const doughnutRings: (hole: number, count: number) => DoughnutRing[];
|
|
19
|
+
//# sourceMappingURL=doughnut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doughnut.d.ts","sourceRoot":"","sources":["../../../utils/doughnut.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,GAAI,MAAM,OAAO,KAAG,MACiB,CAAC;AAEpE,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,YAAY,EAOvE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doughnut geometry shared by the renderers (rowsncolumns/spreadsheet#1064,
|
|
3
|
+
* #1065). Every fraction here is of the doughnut's OUTER radius — Excel's
|
|
4
|
+
* `<c:holeSize val="75"/>` is 0.75 of the outer edge, whatever the chart
|
|
5
|
+
* draws that edge at (echarts: 75% of the chart; plotly: the trace domain).
|
|
6
|
+
*/
|
|
7
|
+
/** `doughnutHoleSize` clamped to Excel's 0-90% range; 0.5 when unset. */
|
|
8
|
+
export const clampDoughnutHole = (hole) => typeof hole === "number" ? Math.max(0, Math.min(0.9, hole)) : 0.5;
|
|
9
|
+
/**
|
|
10
|
+
* Excel draws a doughnut's series as concentric rings, nested from the hole
|
|
11
|
+
* outwards — series 0 innermost — splitting the band between the hole and
|
|
12
|
+
* the outer edge evenly. One ring (the whole band) for a single series.
|
|
13
|
+
*/
|
|
14
|
+
export const doughnutRings = (hole, count) => {
|
|
15
|
+
const n = Math.max(1, Math.floor(count));
|
|
16
|
+
const band = 1 - hole;
|
|
17
|
+
return Array.from({ length: n }, (_, k) => ({
|
|
18
|
+
inner: hole + (band * k) / n,
|
|
19
|
+
outer: hole + (band * (k + 1)) / n,
|
|
20
|
+
}));
|
|
21
|
+
};
|
|
@@ -7,9 +7,18 @@ export declare const applyLegendOverrides: (legend: LegendComponentOption, opts:
|
|
|
7
7
|
* the linked source-cell format — see `resolveValueAxisNumberFormat`); it
|
|
8
8
|
* becomes the tick-label formatter.
|
|
9
9
|
*/
|
|
10
|
-
export declare const applyAxisOverrides: (axis: any, opts: any, numberFormatPattern?: string) => any;
|
|
11
|
-
export declare const dataLabelFormatter: (opts: any) => (params: any) => string;
|
|
12
|
-
|
|
10
|
+
export declare const applyAxisOverrides: (axis: any, opts: any, numberFormatPattern?: string, locale?: string) => any;
|
|
11
|
+
export declare const dataLabelFormatter: (opts: any, locale?: string) => (params: any) => string;
|
|
12
|
+
/**
|
|
13
|
+
* The data-label options one series renders with: its own
|
|
14
|
+
* `ChartData.dataLabels` when it has them (OOXML's `<c:ser><c:dLbls>`
|
|
15
|
+
* override — `{ show: false }` turns a labelled chart's labels off for
|
|
16
|
+
* that series alone), else the chart-level `ChartSpec.dataLabels`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const resolveSeriesDataLabels: <T>(chartLevel: T | null | undefined, series: {
|
|
19
|
+
dataLabels?: T | null;
|
|
20
|
+
} | null | undefined) => T | null | undefined;
|
|
21
|
+
export declare const buildSeriesLabelOption: (opts: any, seriesType?: string, locale?: string) => {
|
|
13
22
|
readonly show: true;
|
|
14
23
|
readonly position: any;
|
|
15
24
|
readonly formatter: (params: any) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAAI,MAAM,GAAG,EAAE,SAAS,MAAM,MAAM,QAAQ,GAAG,WAiC7E,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCA/E0D,GAAG;aA4F7E,CAAC"}
|