aliencharts 0.2.0 → 0.3.1

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/README.md CHANGED
@@ -7,7 +7,7 @@ GPU-rendered chart grid for multi-metric dashboards — such as monitoring AI tr
7
7
 
8
8
  By rendering every series with WebGL, AlienCharts keeps dense chart grids smooth where SVG/Canvas libraries stall.
9
9
 
10
- > **Note:** AlienCharts currently supports **line charts** only. Other chart types may be added in the future.
10
+ > **Note:** AlienCharts currently supports **line charts** and **bar charts**. Other chart types may be added in the future.
11
11
 
12
12
  ![AlienCharts chart grid example](./assets/chartgrid.png)
13
13
 
@@ -34,6 +34,45 @@ import "aliencharts/styles.css";
34
34
 
35
35
  Dark mode follows a `.dark` class on any ancestor element (e.g. `<html class="dark">`).
36
36
 
37
+ ## React
38
+
39
+ If you use React in your application, import the React entry point:
40
+
41
+ ```jsx
42
+ import { useRef, useState } from "react";
43
+ import "aliencharts/styles.css";
44
+ import { ChartGrid, createLineSeries } from "aliencharts/react";
45
+
46
+ const series = createLineSeries({
47
+ id: "run-1",
48
+ x: [0, 1, 2, 3, 4],
49
+ y: [2.5, 1.9, 1.4, 1.1, 0.9],
50
+ });
51
+
52
+ export default function Dashboard() {
53
+ const gridRef = useRef(null);
54
+ const [dataRevision, setDataRevision] = useState(0);
55
+
56
+ const append = () => {
57
+ series.append([series.length], [Math.random()]);
58
+ setDataRevision((value) => value + 1);
59
+ };
60
+
61
+ return (
62
+ <div style={{ height: "100vh" }}>
63
+ <button onClick={append}>Append</button>
64
+ <ChartGrid
65
+ ref={gridRef}
66
+ charts={[{ id: "loss", title: "train/loss", series: [series] }]}
67
+ dataRevision={dataRevision}
68
+ />
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ See the [React demo source](https://github.com/FarangLab/AlienCharts/blob/main/examples/DemoPage.jsx) for a larger controlled-state example.
75
+
37
76
  ## Vanilla Web
38
77
 
39
78
  ```html
@@ -42,9 +81,9 @@ Dark mode follows a `.dark` class on any ancestor element (e.g. `<html class="da
42
81
 
43
82
  ```js
44
83
  import "aliencharts/styles.css";
45
- import { createChartGrid, createSeries } from "aliencharts/vanilla";
84
+ import { createChartGrid, createLineSeries } from "aliencharts/vanilla";
46
85
 
47
- const series = createSeries({
86
+ const series = createLineSeries({
48
87
  id: "run-1",
49
88
  name: "Run 1",
50
89
  color: "#38bdf8",
@@ -81,76 +120,129 @@ grid.destroy();
81
120
 
82
121
  See the [Vanilla Web example source](https://github.com/FarangLab/AlienCharts/blob/main/examples/vanilla.js) for a more complete setup.
83
122
 
84
- ## React
123
+ ### CDN / script tag
85
124
 
86
- If you use React in your application, import the React entry point:
125
+ For browser use without npm or a bundler, load the stylesheet and standalone
126
+ build from jsDelivr:
87
127
 
88
- ```jsx
89
- import { useRef, useState } from "react";
90
- import "aliencharts/styles.css";
91
- import { ChartGrid, createSeries } from "aliencharts/react";
128
+ ```html
129
+ <link
130
+ rel="stylesheet"
131
+ href="https://cdn.jsdelivr.net/npm/aliencharts@0.3.0/dist/aliencharts.css"
132
+ >
92
133
 
93
- const series = createSeries({
94
- id: "run-1",
95
- x: [0, 1, 2, 3, 4],
96
- y: [2.5, 1.9, 1.4, 1.1, 0.9],
97
- });
134
+ <div id="charts" style="height: 100vh"></div>
98
135
 
99
- export default function Dashboard() {
100
- const gridRef = useRef(null);
101
- const [dataRevision, setDataRevision] = useState(0);
136
+ <script src="https://cdn.jsdelivr.net/npm/aliencharts@0.3.0/dist/aliencharts.global.min.js"></script>
137
+ <script>
138
+ const series = AlienCharts.createLineSeries({
139
+ id: "run-1",
140
+ x: [0, 1, 2, 3],
141
+ y: [2.5, 1.9, 1.4, 1.1],
142
+ });
143
+
144
+ const grid = AlienCharts.createChartGrid(
145
+ document.querySelector("#charts"),
146
+ {
147
+ charts: [{
148
+ id: "loss",
149
+ title: "train/loss",
150
+ series: [series],
151
+ }],
152
+ },
153
+ );
154
+ </script>
155
+ ```
102
156
 
103
- const append = () => {
104
- series.append([series.length], [Math.random()]);
105
- setDataRevision((value) => value + 1);
106
- };
157
+ ## Data API
107
158
 
108
- return (
109
- <div style={{ height: "100vh" }}>
110
- <button onClick={append}>Append</button>
111
- <ChartGrid
112
- ref={gridRef}
113
- charts={[{ id: "loss", title: "train/loss", series: [series] }]}
114
- dataRevision={dataRevision}
115
- />
116
- </div>
117
- );
118
- }
159
+ Framework-neutral data helpers are also available from the package root:
160
+
161
+ ### Line series
162
+
163
+ ```js
164
+ import { createLineSeries, createMockCharts, LineSeries } from "aliencharts";
119
165
  ```
120
166
 
121
- See the [React demo source](https://github.com/FarangLab/AlienCharts/blob/main/examples/DemoPage.jsx) for a larger controlled-state example.
167
+ `createLineSeries(options)` accepts an id, optional name/color, X/Y arrays or typed arrays, and an optional maximum LOD level count. Its `append(xValues, yValues)` method efficiently extends the typed backing arrays. The existing `createSeries(options)` API remains available as a backward-compatible alias.
122
168
 
123
- ## Shared data API
169
+ ### Bar series
124
170
 
125
- Framework-neutral data helpers are also available from the package root:
171
+ Use `createBarSeries()` for grouped GPU-rendered bars. The data meaning is the
172
+ same in both orientations: `x` is the numeric category position and `y` is the
173
+ value.
174
+
175
+ ```js
176
+ import { createBarSeries } from "aliencharts";
177
+
178
+ const vertical = createBarSeries({
179
+ id: "revenue",
180
+ x: [0, 1, 2, 3],
181
+ y: [12, 18, -4, 25],
182
+ });
183
+
184
+ const horizontal = createBarSeries({
185
+ id: "latency",
186
+ orientation: "horizontal",
187
+ x: [0, 1, 2, 3],
188
+ y: [40, 65, 32, 80],
189
+ });
190
+ ```
191
+
192
+ Multiple bar series in one chart are grouped in series order. Every series in a
193
+ chart must use the same orientation.
194
+
195
+ ## Chart configuration
196
+
197
+ Charts have the shape `{ id, title, series }` and may additionally define
198
+ `pinned`, `categories`, `xAxisLabel`, and a fixed `{ min, max }` Y range.
199
+
200
+ ### Categories
201
+
202
+ Add `categories` to the chart to display text labels at bar positions. String
203
+ entries use their array index as the numeric X value:
126
204
 
127
205
  ```js
128
- import { createSeries, createMockCharts, LineSeries } from "aliencharts";
206
+ const models = ["Gemini 3.5", "GPT-5.6", "Claude 4.5"];
207
+
208
+ const chart = {
209
+ id: "model-scores",
210
+ title: "Model scores",
211
+ categories: models,
212
+ xAxisLabel: "MODEL",
213
+ series: [createBarSeries({
214
+ id: "score",
215
+ x: models.map((_, index) => index),
216
+ y: [82, 91, 87],
217
+ })],
218
+ };
129
219
  ```
130
220
 
131
- `createSeries(options)` accepts an id, optional name/color, X/Y arrays or typed arrays, and an optional maximum LOD level count. Its `append(xValues, yValues)` method efficiently extends the typed backing arrays.
132
-
133
- Charts have the shape `{ id, title, series }` and may additionally define `pinned` and a fixed `{ min, max }` Y range.
134
-
135
- ## Common options
136
-
137
- | Option | Default | Description |
138
- | --- | --- | --- |
139
- | `charts` | required | Chart objects to render. |
140
- | `columns` | `2` | Responsive grid column count. |
141
- | `initialVisiblePoints` | all | Initial X window size. |
142
- | `backgroundColor` | `#f5f9ff` | Chart background. |
143
- | `antialiasLines` | `false` | GPU-expanded antialiased lines. |
144
- | `gridLines` | `false` | Boolean or `{ xSpacing, ySpacing }`. |
145
- | `showToolbar` | `true` | Focused-chart toolbar. |
146
- | `showLatestValueLine` | `true` | Latest value connector and label. |
147
- | `showTooltips` | `true` | Crosshair and nearest-value tooltip. |
148
- | `followLatest` | `false` | Always follow appended values. |
149
- | `followVisibleLatest` | `true` | Follow appends when the latest point was visible. |
150
- | `drawings` | `[]` | Initial or replacement drawing state. |
151
- | `movingAverageByChart` | `{}` | Moving-average state keyed by chart id. |
152
- | `topMarkers` | `[]` | Clickable markers positioned by `x` or `step`. |
153
- | `disableDrawings` | `false` | Disable drawing and moving-average controls. |
221
+ For sparse or non-indexed numeric X values, use
222
+ `{ value: number, label: string }` entries instead.
223
+
224
+ ### Common options
225
+
226
+ | Option | Default | Chart types | Description |
227
+ | --- | --- | --- | --- |
228
+ | `charts` | required | Line, Bar | Chart objects to render. |
229
+ | `columns` | `2` | Line, Bar | Responsive grid column count. |
230
+ | `initialVisiblePoints` | all | Line, Bar | Initial X window size. |
231
+ | `backgroundColor` | `#f5f9ff` | Line, Bar | Chart background. |
232
+ | `antialiasLines` | `false` | Line | GPU-expanded antialiased lines. |
233
+ | `gridLines` | `false` | Line, Bar | Boolean or `{ xSpacing, ySpacing }`. |
234
+ | `showToolbar` | `true` | Line, Bar | Focused-chart toolbar. |
235
+ | `showLatestValueLine` | `true` | Line | Latest value connector and label. |
236
+ | `showTooltips` | `true` | Line, Bar | Crosshair and nearest-value tooltip. |
237
+ | `xAxisLabel` | `STEP` | Line, Bar | Default tooltip label for the category/X value. |
238
+ | `followLatest` | `false` | Line, Bar | Always follow appended values. |
239
+ | `followVisibleLatest` | `true` | Line, Bar | Follow appends when the latest point was visible. |
240
+ | `drawings` | `[]` | Line | Initial or replacement drawing state. |
241
+ | `movingAverageByChart` | `{}` | Line | Moving-average state keyed by chart id. |
242
+ | `topMarkers` | `[]` | Line | Clickable markers positioned by `x` or `step`. |
243
+ | `disableDrawings` | `false` | Line | Disable drawing and moving-average controls. |
244
+
245
+ ### Drawings and callbacks
154
246
 
155
247
  Drawing, selection, active-tool, moving-average, marker, clearing, and context-menu callbacks work in both entry points. The controller updates its own state before emitting change callbacks; passing an explicit replacement through `setOptions()` or React props synchronizes external state back into it.
156
248
 
@@ -169,7 +261,9 @@ npm run examples
169
261
  Then open:
170
262
 
171
263
  - Vanilla Web: <http://127.0.0.1:4178/examples/vanilla.html>
264
+ - Standalone script: <http://127.0.0.1:4178/examples/standalone.html>
172
265
  - React: <http://127.0.0.1:4178/examples/react.html>
266
+ - Bar charts: <http://127.0.0.1:4178/examples/bars.html>
173
267
 
174
268
  ## License
175
269
 
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--color-orange-500:oklch(70.5% .213 47.604);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--blur-sm:8px}}@layer base{.aliencharts-root,.aliencharts-root *,.aliencharts-root :before,.aliencharts-root :after{box-sizing:border-box;border:0 solid}.aliencharts-root button,.aliencharts-root input{font:inherit;color:inherit;letter-spacing:inherit;background:0 0;margin:0}.aliencharts-root button{cursor:pointer;padding:0}.aliencharts-root button:disabled{cursor:default}.aliencharts-root svg{display:block}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.inset-x-0{inset-inline:0}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-12{top:calc(var(--spacing) * 12)}.right-0{right:0}.right-16{right:calc(var(--spacing) * 16)}.bottom-0{bottom:0}.left-0{left:0}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-full{left:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-\[60\]{z-index:60}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.my-1{margin-block:var(--spacing)}.mt-1{margin-top:var(--spacing)}.mb-1{margin-bottom:var(--spacing)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-full{height:100%}.h-px{height:1px}.min-h-0{min-height:0}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-\[220px\]{width:220px}.w-full{width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-45{rotate:-45deg}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-background{border-color:var(--background)}.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.border-foreground\/40{border-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.border-foreground\/40{border-color:color-mix(in oklab, var(--foreground) 40%, transparent)}}.border-primary\/70{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.border-primary\/70{border-color:color-mix(in oklab, var(--primary) 70%, transparent)}}.bg-background,.bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/80{background-color:color-mix(in oklab, var(--background) 80%, transparent)}}.bg-background\/85{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/85{background-color:color-mix(in oklab, var(--background) 85%, transparent)}}.bg-popover\/80{background-color:var(--popover)}@supports (color:color-mix(in lab, red, red)){.bg-popover\/80{background-color:color-mix(in oklab, var(--popover) 80%, transparent)}}.bg-primary\/10{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.bg-primary\/15{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/15{background-color:color-mix(in oklab, var(--primary) 15%, transparent)}}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-1{padding-top:var(--spacing)}.pr-3{padding-right:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-border\/40{color:var(--border)}@supports (color:color-mix(in lab, red, red)){.text-border\/40{color:color-mix(in oklab, var(--border) 40%, transparent)}}.text-foreground,.text-foreground\/50{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/50{color:color-mix(in oklab, var(--foreground) 50%, transparent)}}.text-foreground\/70{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/70{color:color-mix(in oklab, var(--foreground) 70%, transparent)}}.text-foreground\/80{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/80{color:color-mix(in oklab, var(--foreground) 80%, transparent)}}.text-muted-foreground{color:var(--muted-foreground)}.text-orange-500{color:var(--color-orange-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-70{opacity:.7}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-primary\/40{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.ring-primary\/40{--tw-ring-color:color-mix(in oklab, var(--primary) 40%, transparent)}}.ring-primary\/70{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.ring-primary\/70{--tw-ring-color:color-mix(in oklab, var(--primary) 70%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}}}.aliencharts-root{--radius:.5rem;--background:#fff;--foreground:#161616;--popover:#fff;--popover-foreground:#161616;--primary:#45aeee;--muted-foreground:#626262;--accent:#d1d1d1;--accent-foreground:#494949;--border:#626262}.dark .aliencharts-root,.aliencharts-root.dark{--background:#1c1719;--foreground:#e8e3e5;--popover:#1c1719;--popover-foreground:#e8e3e5;--primary:#077dc4;--muted-foreground:#a69399;--accent:#332a2d;--accent-foreground:#bdafb4;--border:#a69399}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--color-orange-500:oklch(70.5% .213 47.604);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--blur-sm:8px}}@layer base{.aliencharts-root,.aliencharts-root *,.aliencharts-root :before,.aliencharts-root :after{box-sizing:border-box;border:0 solid}.aliencharts-root button,.aliencharts-root input{font:inherit;color:inherit;letter-spacing:inherit;background:0 0;margin:0}.aliencharts-root button{cursor:pointer;padding:0}.aliencharts-root button:disabled{cursor:default}.aliencharts-root svg{display:block}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-x-2{inset-inline:calc(var(--spacing) * 2)}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-12{top:calc(var(--spacing) * 12)}.right-16{right:calc(var(--spacing) * 16)}.left-0{left:0}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-full{left:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-\[60\]{z-index:60}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.my-1{margin-block:var(--spacing)}.mt-1{margin-top:var(--spacing)}.mb-1{margin-bottom:var(--spacing)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-full{height:100%}.h-px{height:1px}.min-h-0{min-height:0}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-\[220px\]{width:220px}.w-full{width:100%}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-rotate-45{rotate:-45deg}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-background{border-color:var(--background)}.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.border-foreground\/40{border-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.border-foreground\/40{border-color:color-mix(in oklab, var(--foreground) 40%, transparent)}}.border-primary\/70{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.border-primary\/70{border-color:color-mix(in oklab, var(--primary) 70%, transparent)}}.bg-background,.bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/80{background-color:color-mix(in oklab, var(--background) 80%, transparent)}}.bg-background\/85{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/85{background-color:color-mix(in oklab, var(--background) 85%, transparent)}}.bg-popover\/80{background-color:var(--popover)}@supports (color:color-mix(in lab, red, red)){.bg-popover\/80{background-color:color-mix(in oklab, var(--popover) 80%, transparent)}}.bg-primary\/10{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.bg-primary\/15{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/15{background-color:color-mix(in oklab, var(--primary) 15%, transparent)}}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-1{padding-top:var(--spacing)}.pr-3{padding-right:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-right{text-align:right}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-border\/40{color:var(--border)}@supports (color:color-mix(in lab, red, red)){.text-border\/40{color:color-mix(in oklab, var(--border) 40%, transparent)}}.text-foreground,.text-foreground\/50{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/50{color:color-mix(in oklab, var(--foreground) 50%, transparent)}}.text-foreground\/70{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/70{color:color-mix(in oklab, var(--foreground) 70%, transparent)}}.text-foreground\/80{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/80{color:color-mix(in oklab, var(--foreground) 80%, transparent)}}.text-muted-foreground{color:var(--muted-foreground)}.text-orange-500{color:var(--color-orange-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-70{opacity:.7}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-primary\/40{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.ring-primary\/40{--tw-ring-color:color-mix(in oklab, var(--primary) 40%, transparent)}}.ring-primary\/70{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.ring-primary\/70{--tw-ring-color:color-mix(in oklab, var(--primary) 70%, transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}}}.aliencharts-root{--radius:.5rem;--background:#fff;--foreground:#161616;--popover:#fff;--popover-foreground:#161616;--primary:#45aeee;--muted-foreground:#626262;--accent:#d1d1d1;--accent-foreground:#494949;--border:#626262}.dark .aliencharts-root,.aliencharts-root.dark{--background:#1c1719;--foreground:#e8e3e5;--popover:#1c1719;--popover-foreground:#e8e3e5;--primary:#077dc4;--muted-foreground:#a69399;--accent:#332a2d;--accent-foreground:#bdafb4;--border:#a69399}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}