@devalok/shilp-sutra 0.38.0 → 0.40.0
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/AGENTS.md +151 -0
- package/MIGRATION.md +255 -0
- package/README.md +3 -0
- package/dist/_chunks/badge-group.js +76 -75
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/chart-container.js +50 -0
- package/dist/_chunks/chart-container.js.map +1 -0
- package/dist/_chunks/chat.js +236 -228
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/colors.js +30 -0
- package/dist/_chunks/colors.js.map +1 -0
- package/dist/_chunks/document-preview.js +2 -2
- package/dist/_chunks/document-preview.js.map +1 -1
- package/dist/_chunks/emoji-data.js +45 -0
- package/dist/_chunks/emoji-data.js.map +1 -0
- package/dist/_chunks/grid-lines.js +72 -0
- package/dist/_chunks/grid-lines.js.map +1 -0
- package/dist/_chunks/image-preview.js +2 -2
- package/dist/_chunks/image-preview.js.map +1 -1
- package/dist/_chunks/mention-suggestion.js +35 -263
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/normalize-icon.js +18 -0
- package/dist/_chunks/normalize-icon.js.map +1 -0
- package/dist/_chunks/oauth-button.js +227 -0
- package/dist/_chunks/oauth-button.js.map +1 -0
- package/dist/_chunks/popover.js +3 -3
- package/dist/_chunks/popover.js.map +1 -1
- package/dist/_chunks/primitives.js +107 -107
- package/dist/_chunks/primitives.js.map +1 -1
- package/dist/_chunks/shared.js +5 -5
- package/dist/_chunks/shared.js.map +1 -1
- package/dist/_chunks/{text.js → success.js} +26 -63
- package/dist/_chunks/success.js.map +1 -0
- package/dist/_chunks/tiptap.js +1952 -1949
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tooltip.js +58 -0
- package/dist/_chunks/tooltip.js.map +1 -0
- package/dist/_chunks/tree-view.js +101 -96
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/_chunks/use-calendar.js +5 -5
- package/dist/_chunks/use-calendar.js.map +1 -1
- package/dist/ai/ai-command-provider.d.ts +3 -2
- package/dist/ai/ai-command-provider.d.ts.map +1 -1
- package/dist/ai/ai-command-provider.js.map +1 -1
- package/dist/ai/block-renderer.js +11 -9
- package/dist/ai/block-renderer.js.map +1 -1
- package/dist/ai/blocks/error.js +31 -0
- package/dist/ai/blocks/error.js.map +1 -0
- package/dist/ai/blocks/index.d.ts +0 -2
- package/dist/ai/blocks/index.d.ts.map +1 -1
- package/dist/ai/blocks/index.js +2 -2
- package/dist/ai/blocks/text.js +19 -0
- package/dist/ai/blocks/text.js.map +1 -0
- package/dist/ai/command-bar.d.ts.map +1 -1
- package/dist/ai/command-bar.js +198 -193
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.d.ts +2 -1
- package/dist/ai/conversation.d.ts.map +1 -1
- package/dist/ai/conversation.js +92 -87
- package/dist/ai/conversation.js.map +1 -1
- package/dist/ai/index.d.ts +0 -4
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +45 -46
- package/dist/ai/index.js.map +1 -1
- package/dist/composed/activity-feed.d.ts +2 -1
- package/dist/composed/activity-feed.d.ts.map +1 -1
- package/dist/composed/activity-feed.js +5 -5
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/avatar-group.js +4 -4
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.d.ts +2 -2
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +12 -12
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.d.ts +2 -1
- package/dist/composed/command-palette.d.ts.map +1 -1
- package/dist/composed/command-palette.js +106 -101
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/content-card.js +1 -1
- package/dist/composed/content-card.js.map +1 -1
- package/dist/composed/date-picker/index.js +747 -3
- package/dist/composed/date-picker/index.js.map +1 -0
- package/dist/composed/emoji-picker.js +4 -4
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/empty-state.d.ts +3 -3
- package/dist/composed/empty-state.d.ts.map +1 -1
- package/dist/composed/empty-state.js +40 -31
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/error-boundary.js +3 -3
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/extensions/emoji-node.js +81 -0
- package/dist/composed/extensions/emoji-node.js.map +1 -0
- package/dist/composed/extensions/emoji-suggestion.js +117 -0
- package/dist/composed/extensions/emoji-suggestion.js.map +1 -0
- package/dist/composed/file-preview.js +498 -2
- package/dist/composed/file-preview.js.map +1 -0
- package/dist/composed/filter-bar.js +1 -1
- package/dist/composed/filter-bar.js.map +1 -1
- package/dist/composed/index.d.ts +0 -15
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +16 -24
- package/dist/composed/inline-edit.js +1 -1
- package/dist/composed/inline-edit.js.map +1 -1
- package/dist/composed/loading-skeleton.js +9 -9
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/markdown-viewer.js +3 -3
- package/dist/composed/markdown-viewer.js.map +1 -1
- package/dist/composed/multi-select-popover.js +1 -1
- package/dist/composed/multi-select-popover.js.map +1 -1
- package/dist/composed/page-header.js +1 -1
- package/dist/composed/page-header.js.map +1 -1
- package/dist/composed/page-skeletons.js +15 -15
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/priority-indicator.js +3 -3
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/rich-chat-input.js +2073 -2
- package/dist/composed/rich-chat-input.js.map +1 -0
- package/dist/composed/rich-text-editor.js +75 -72
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/schedule-view.js +3 -3
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/composed/status-badge.d.ts +3 -2
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js +58 -53
- package/dist/composed/status-badge.js.map +1 -1
- package/dist/shell/app-command-palette.d.ts +2 -1
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js.map +1 -1
- package/dist/shell/bottom-navbar.d.ts +3 -1
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +94 -86
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/command-registry.d.ts +2 -1
- package/dist/shell/command-registry.d.ts.map +1 -1
- package/dist/shell/command-registry.js.map +1 -1
- package/dist/shell/notification-center.js +8 -8
- package/dist/shell/notification-center.js.map +1 -1
- package/dist/shell/notification-preferences.js +1 -1
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/shell/sidebar.d.ts +7 -4
- package/dist/shell/sidebar.d.ts.map +1 -1
- package/dist/shell/sidebar.js +148 -134
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.d.ts +4 -3
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js +116 -108
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/tokens/semantic.css +82 -9
- package/dist/ui/accordion.js +1 -1
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/alert-dialog.js +3 -3
- package/dist/ui/alert-dialog.js.map +1 -1
- package/dist/ui/alert.js +2 -2
- package/dist/ui/alert.js.map +1 -1
- package/dist/ui/autocomplete.js +2 -2
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/avatar.js +11 -11
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/badge-indicator.js +1 -1
- package/dist/ui/badge-indicator.js.map +1 -1
- package/dist/ui/badge.d.ts +3 -2
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/banner.js +1 -1
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/breadcrumb.js +1 -1
- package/dist/ui/breadcrumb.js.map +1 -1
- package/dist/ui/button.d.ts +5 -4
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +66 -65
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.js +5 -5
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/charts/area-chart.js +177 -0
- package/dist/ui/charts/area-chart.js.map +1 -0
- package/dist/ui/charts/bar-chart.js +127 -0
- package/dist/ui/charts/bar-chart.js.map +1 -0
- package/dist/ui/charts/chart-container.js +3 -0
- package/dist/ui/charts/gauge-chart.js +72 -0
- package/dist/ui/charts/gauge-chart.js.map +1 -0
- package/dist/ui/charts/index.js +10 -1035
- package/dist/ui/charts/line-chart.js +135 -0
- package/dist/ui/charts/line-chart.js.map +1 -0
- package/dist/ui/charts/pie-chart.js +111 -0
- package/dist/ui/charts/pie-chart.js.map +1 -0
- package/dist/ui/charts/radar-chart.js +170 -0
- package/dist/ui/charts/radar-chart.js.map +1 -0
- package/dist/ui/charts/sparkline.js +119 -0
- package/dist/ui/charts/sparkline.js.map +1 -0
- package/dist/ui/chat/message.d.ts +3 -3
- package/dist/ui/chat/message.d.ts.map +1 -1
- package/dist/ui/chat/system-message.d.ts +2 -1
- package/dist/ui/chat/system-message.d.ts.map +1 -1
- package/dist/ui/checkbox.js +1 -1
- package/dist/ui/checkbox.js.map +1 -1
- package/dist/ui/code.js +2 -2
- package/dist/ui/code.js.map +1 -1
- package/dist/ui/color-input.js +10 -10
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/color-swatch.js +3 -3
- package/dist/ui/color-swatch.js.map +1 -1
- package/dist/ui/combobox.d.ts +2 -1
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +100 -95
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/container.d.ts +6 -1
- package/dist/ui/container.d.ts.map +1 -1
- package/dist/ui/container.js +2 -1
- package/dist/ui/container.js.map +1 -1
- package/dist/ui/context-menu.js +6 -6
- package/dist/ui/context-menu.js.map +1 -1
- package/dist/ui/data-table-body.js +1 -1
- package/dist/ui/data-table-body.js.map +1 -1
- package/dist/ui/data-table-bulk-actions.js +2 -2
- package/dist/ui/data-table-bulk-actions.js.map +1 -1
- package/dist/ui/data-table-card.js +2 -2
- package/dist/ui/data-table-card.js.map +1 -1
- package/dist/ui/data-table-header.js +2 -2
- package/dist/ui/data-table-header.js.map +1 -1
- package/dist/ui/data-table-pagination.js +3 -3
- package/dist/ui/data-table-pagination.js.map +1 -1
- package/dist/ui/data-table-toolbar.js +1 -1
- package/dist/ui/data-table-toolbar.js.map +1 -1
- package/dist/ui/data-table.js +1 -1
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/devalok-grain.d.ts +1 -1
- package/dist/ui/devalok-grain.js.map +1 -1
- package/dist/ui/dialog.js +2 -2
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dropdown-menu.js +6 -6
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/file-upload.js +4 -4
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/hover-card.js +1 -1
- package/dist/ui/hover-card.js.map +1 -1
- package/dist/ui/icon-button.d.ts +9 -2
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-button.js +14 -13
- package/dist/ui/icon-button.js.map +1 -1
- package/dist/ui/index.d.ts +1 -3
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +31 -33
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/input-otp.js +1 -1
- package/dist/ui/input-otp.js.map +1 -1
- package/dist/ui/input.js +2 -2
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/lib/icon-input.d.ts +42 -0
- package/dist/ui/lib/icon-input.d.ts.map +1 -0
- package/dist/ui/lib/normalize-icon.d.ts +39 -0
- package/dist/ui/lib/normalize-icon.d.ts.map +1 -0
- package/dist/ui/link.js +1 -1
- package/dist/ui/link.js.map +1 -1
- package/dist/ui/menubar.js +8 -8
- package/dist/ui/menubar.js.map +1 -1
- package/dist/ui/navigation-menu.js +3 -3
- package/dist/ui/navigation-menu.js.map +1 -1
- package/dist/ui/number-input.js +3 -3
- package/dist/ui/number-input.js.map +1 -1
- package/dist/ui/oauth-button/index.d.ts +3 -0
- package/dist/ui/oauth-button/index.d.ts.map +1 -0
- package/dist/ui/oauth-button/index.js +3 -0
- package/dist/ui/oauth-button/oauth-button.d.ts +208 -0
- package/dist/ui/oauth-button/oauth-button.d.ts.map +1 -0
- package/dist/ui/pagination.js +1 -1
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/progress.js +2 -2
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/radio.js +1 -1
- package/dist/ui/radio.js.map +1 -1
- package/dist/ui/segmented-control.d.ts +3 -4
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +53 -45
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/select.js +3 -3
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/sheet.js +2 -2
- package/dist/ui/sheet.js.map +1 -1
- package/dist/ui/sidebar.js +11 -11
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/skeleton.js +9 -9
- package/dist/ui/skeleton.js.map +1 -1
- package/dist/ui/slider.js +2 -2
- package/dist/ui/slider.js.map +1 -1
- package/dist/ui/split-button.js +7 -7
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/stack.d.ts +6 -1
- package/dist/ui/stack.d.ts.map +1 -1
- package/dist/ui/stack.js +2 -1
- package/dist/ui/stack.js.map +1 -1
- package/dist/ui/stat-card.d.ts +2 -3
- package/dist/ui/stat-card.d.ts.map +1 -1
- package/dist/ui/stat-card.js +118 -116
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/status-dot.js +2 -2
- package/dist/ui/status-dot.js.map +1 -1
- package/dist/ui/stepper.d.ts +2 -1
- package/dist/ui/stepper.d.ts.map +1 -1
- package/dist/ui/stepper.js +74 -69
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/switch.js +2 -2
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/tabs.js +3 -3
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/text.d.ts +7 -2
- package/dist/ui/text.d.ts.map +1 -1
- package/dist/ui/text.js +2 -1
- package/dist/ui/text.js.map +1 -1
- package/dist/ui/textarea.js +1 -1
- package/dist/ui/textarea.js.map +1 -1
- package/dist/ui/toast.js +8 -8
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toaster.d.ts +11 -2
- package/dist/ui/toaster.d.ts.map +1 -1
- package/dist/ui/toaster.js.map +1 -1
- package/dist/ui/toggle.js +1 -1
- package/dist/ui/toggle.js.map +1 -1
- package/dist/ui/tooltip.js +12 -12
- package/dist/ui/tooltip.js.map +1 -1
- package/dist/ui/tree-view/tree-item.d.ts +3 -2
- package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
- package/dist/ui/tree-view/use-tree.d.ts +2 -1
- package/dist/ui/tree-view/use-tree.d.ts.map +1 -1
- package/docs/components/_header.md +90 -1
- package/docs/components/ui/oauth-button.md +86 -0
- package/docs/recipes/customize-brand.md +100 -4
- package/docs/recipes/index.md +5 -1
- package/docs/recipes/install-astro.md +15 -0
- package/docs/recipes/install-next-app-router.md +21 -5
- package/docs/recipes/install-next-pages.md +2 -0
- package/docs/recipes/install-remix.md +15 -0
- package/docs/recipes/install-tanstack-start.md +15 -0
- package/docs/recipes/install-vite.md +15 -0
- package/docs/recipes/troubleshoot.md +22 -0
- package/llms-full.txt +177 -2
- package/llms-quick.txt +247 -0
- package/llms.txt +116 -3
- package/package.json +80 -2
- package/scripts/welcome.mjs +219 -0
- package/skill/README.md +99 -0
- package/skill/SKILL.md +163 -0
- package/skill/install.sh +59 -0
- package/skill/references/components-full.md +7083 -0
- package/skill/references/components.md +778 -0
- package/skill/references/customize-brand.md +314 -0
- package/skill/references/server-components.md +211 -0
- package/skill/references/setup-astro.md +195 -0
- package/skill/references/setup-next-app-router.md +248 -0
- package/skill/references/setup-next-pages.md +127 -0
- package/skill/references/setup-remix.md +188 -0
- package/skill/references/setup-tanstack-start.md +160 -0
- package/skill/references/setup-vite.md +187 -0
- package/skill/references/troubleshoot.md +241 -0
- package/dist/_chunks/date-picker.js +0 -748
- package/dist/_chunks/date-picker.js.map +0 -1
- package/dist/_chunks/file-preview.js +0 -499
- package/dist/_chunks/file-preview.js.map +0 -1
- package/dist/_chunks/rich-chat-input.js +0 -2071
- package/dist/_chunks/rich-chat-input.js.map +0 -1
- package/dist/_chunks/text.js.map +0 -1
- package/dist/ui/charts/index.js.map +0 -1
- /package/{LICENSE → skill/LICENSE} +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { motionProps as e, tweens as t } from "../lib/motion.js";
|
|
3
|
+
import { cn as n } from "../lib/utils.js";
|
|
4
|
+
import { n as r, r as i, t as a } from "../../_chunks/tooltip.js";
|
|
5
|
+
import { r as o, t as s } from "../../_chunks/colors.js";
|
|
6
|
+
import { n as c, t as l } from "../../_chunks/grid-lines.js";
|
|
7
|
+
import { t as u } from "../../_chunks/chart-container.js";
|
|
8
|
+
import * as d from "react";
|
|
9
|
+
import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
10
|
+
import { motion as h } from "framer-motion";
|
|
11
|
+
import { scaleLinear as g, scalePoint as _ } from "d3-scale";
|
|
12
|
+
import { area as v, curveLinear as y, curveMonotoneX as b, line as x, stack as S, stackOffsetNone as C, stackOrderNone as w } from "d3-shape";
|
|
13
|
+
//#region src/ui/charts/area-chart.tsx
|
|
14
|
+
var T = d.forwardRef(({ data: T, xKey: E, series: D, curved: O = !1, stacked: k = !1, fillOpacity: A = .3, gradient: j = !1, strokeWidth: M = 2, height: N = 300, showGrid: P = !0, showTooltip: F = !0, showLegend: I = !1, animate: L = !0, xLabel: R, yLabel: z, ariaLabel: B, className: V, ...H }, U) => {
|
|
15
|
+
let { tooltip: W, show: G, hide: K } = r(), q = o(), J = L && !q, Y = D.map((e, t) => s(e.color, t)), X = d.useId();
|
|
16
|
+
return /* @__PURE__ */ m(h.div, {
|
|
17
|
+
ref: U,
|
|
18
|
+
className: n("relative", V),
|
|
19
|
+
...J ? {
|
|
20
|
+
initial: {
|
|
21
|
+
opacity: 0,
|
|
22
|
+
scale: .96
|
|
23
|
+
},
|
|
24
|
+
animate: {
|
|
25
|
+
opacity: 1,
|
|
26
|
+
scale: 1
|
|
27
|
+
},
|
|
28
|
+
transition: t.fade
|
|
29
|
+
} : {},
|
|
30
|
+
...e(H),
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ p(u, {
|
|
33
|
+
height: N,
|
|
34
|
+
ariaLabel: B ?? "Area chart",
|
|
35
|
+
children: ({ width: e, height: t, margin: n }) => {
|
|
36
|
+
let r = T.map((e) => e[E]), i = r.every((e) => typeof e == "number"), a, o, s;
|
|
37
|
+
if (i) {
|
|
38
|
+
let t = r, n = Math.min(...t), i = Math.max(...t), c = g().domain([n, i]).range([0, e]);
|
|
39
|
+
a = c, o = (e) => c(Number(e[E])), s = (e) => c(Number(T[e][E]));
|
|
40
|
+
} else {
|
|
41
|
+
let t = r.map(String), n = _().domain(t).range([0, e]).padding(.5);
|
|
42
|
+
a = n, o = (e) => n(String(e[E])) ?? 0, s = (e) => n(String(T[e][E])) ?? 0;
|
|
43
|
+
}
|
|
44
|
+
let u;
|
|
45
|
+
u = Math.max(...k ? T.map((e) => D.reduce((t, n) => t + (Number(e[n.key]) || 0), 0)) : T.flatMap((e) => D.map((t) => Number(e[t.key]) || 0)));
|
|
46
|
+
let d = g().domain([0, u * 1.1]).range([t, 0]).nice(), h = O ? b : y, N = () => T.map((n, r) => {
|
|
47
|
+
let i = o(n), a = e / Math.max(T.length - 1, 1);
|
|
48
|
+
return /* @__PURE__ */ p("rect", {
|
|
49
|
+
x: i - a / 2,
|
|
50
|
+
y: 0,
|
|
51
|
+
width: a,
|
|
52
|
+
height: t,
|
|
53
|
+
fill: "transparent",
|
|
54
|
+
onMouseMove: (e) => {
|
|
55
|
+
let t = e.currentTarget.closest("div")?.getBoundingClientRect();
|
|
56
|
+
G(e.clientX - (t?.left ?? 0), e.clientY - (t?.top ?? 0), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("div", {
|
|
57
|
+
className: "font-medium",
|
|
58
|
+
children: String(n[E])
|
|
59
|
+
}), D.map((e, t) => /* @__PURE__ */ m("div", {
|
|
60
|
+
className: "flex items-center gap-ds-02",
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ p("span", {
|
|
63
|
+
className: "inline-block h-2 w-2 rounded-pill",
|
|
64
|
+
style: { backgroundColor: Y[t] }
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ m("span", {
|
|
67
|
+
className: "text-surface-fg-muted",
|
|
68
|
+
children: [e.label, ":"]
|
|
69
|
+
}),
|
|
70
|
+
" ",
|
|
71
|
+
Number(n[e.key]).toLocaleString()
|
|
72
|
+
]
|
|
73
|
+
}, e.key))] }));
|
|
74
|
+
},
|
|
75
|
+
onMouseLeave: K
|
|
76
|
+
}, `hover-${r}`);
|
|
77
|
+
}), I = () => j ? /* @__PURE__ */ p("defs", { children: D.map((e, t) => /* @__PURE__ */ m("linearGradient", {
|
|
78
|
+
id: `${X}-gradient-${t}`,
|
|
79
|
+
x1: "0",
|
|
80
|
+
y1: "0",
|
|
81
|
+
x2: "0",
|
|
82
|
+
y2: "1",
|
|
83
|
+
children: [/* @__PURE__ */ p("stop", {
|
|
84
|
+
offset: "0%",
|
|
85
|
+
stopColor: Y[t],
|
|
86
|
+
stopOpacity: A
|
|
87
|
+
}), /* @__PURE__ */ p("stop", {
|
|
88
|
+
offset: "100%",
|
|
89
|
+
stopColor: Y[t],
|
|
90
|
+
stopOpacity: .05
|
|
91
|
+
})]
|
|
92
|
+
}, `grad-${t}`)) }) : null, L = () => /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(c, {
|
|
93
|
+
scale: a,
|
|
94
|
+
orientation: "bottom",
|
|
95
|
+
transform: `translate(0,${t})`,
|
|
96
|
+
label: R
|
|
97
|
+
}), /* @__PURE__ */ p(c, {
|
|
98
|
+
scale: d,
|
|
99
|
+
orientation: "left",
|
|
100
|
+
label: z
|
|
101
|
+
})] });
|
|
102
|
+
if (k) {
|
|
103
|
+
let n = D.map((e) => e.key), r = S().keys(n).order(w).offset(C)(T.map((e) => {
|
|
104
|
+
let t = { [E]: String(e[E]) };
|
|
105
|
+
for (let n of D) t[n.key] = Number(e[n.key]) || 0;
|
|
106
|
+
return t;
|
|
107
|
+
})), i = v().curve(h).x((e, t) => s(t)).y0((e) => d(e[0])).y1((e) => d(e[1])), a = x().curve(h).x((e, t) => s(t)).y((e) => d(e[1]));
|
|
108
|
+
return /* @__PURE__ */ m(f, { children: [
|
|
109
|
+
I(),
|
|
110
|
+
P && /* @__PURE__ */ p(l, {
|
|
111
|
+
width: e,
|
|
112
|
+
height: t,
|
|
113
|
+
yScale: d,
|
|
114
|
+
horizontal: !0
|
|
115
|
+
}),
|
|
116
|
+
[...r].reverse().map((e, t) => {
|
|
117
|
+
let n = r.length - 1 - t, o = e, s = i(o) ?? "", c = a(o) ?? "";
|
|
118
|
+
return /* @__PURE__ */ m("g", { children: [/* @__PURE__ */ p("path", {
|
|
119
|
+
d: s,
|
|
120
|
+
fill: j ? `url(#${X}-gradient-${n})` : Y[n],
|
|
121
|
+
opacity: j ? 1 : A
|
|
122
|
+
}), /* @__PURE__ */ p("path", {
|
|
123
|
+
d: c,
|
|
124
|
+
fill: "none",
|
|
125
|
+
stroke: Y[n],
|
|
126
|
+
strokeWidth: M,
|
|
127
|
+
strokeLinejoin: "round",
|
|
128
|
+
strokeLinecap: "round"
|
|
129
|
+
})] }, D[n].key);
|
|
130
|
+
}),
|
|
131
|
+
F && N(),
|
|
132
|
+
L()
|
|
133
|
+
] });
|
|
134
|
+
}
|
|
135
|
+
let B = v().curve(h).defined((e) => e != null), V = x().curve(h).defined((e) => e != null);
|
|
136
|
+
return /* @__PURE__ */ m(f, { children: [
|
|
137
|
+
I(),
|
|
138
|
+
P && /* @__PURE__ */ p(l, {
|
|
139
|
+
width: e,
|
|
140
|
+
height: t,
|
|
141
|
+
yScale: d,
|
|
142
|
+
horizontal: !0
|
|
143
|
+
}),
|
|
144
|
+
[...D].reverse().map((e, n) => {
|
|
145
|
+
let r = D.length - 1 - n, i = B.x((e) => o(e)).y0(t).y1((t) => d(Number(t[e.key]) || 0)), a = V.x((e) => o(e)).y((t) => d(Number(t[e.key]) || 0)), s = i(T) ?? "", c = a(T) ?? "";
|
|
146
|
+
return /* @__PURE__ */ m("g", { children: [/* @__PURE__ */ p("path", {
|
|
147
|
+
d: s,
|
|
148
|
+
fill: j ? `url(#${X}-gradient-${r})` : Y[r],
|
|
149
|
+
opacity: j ? 1 : A
|
|
150
|
+
}), /* @__PURE__ */ p("path", {
|
|
151
|
+
d: c,
|
|
152
|
+
fill: "none",
|
|
153
|
+
stroke: Y[r],
|
|
154
|
+
strokeWidth: M,
|
|
155
|
+
strokeLinejoin: "round",
|
|
156
|
+
strokeLinecap: "round"
|
|
157
|
+
})] }, e.key);
|
|
158
|
+
}),
|
|
159
|
+
F && N(),
|
|
160
|
+
L()
|
|
161
|
+
] });
|
|
162
|
+
}
|
|
163
|
+
}),
|
|
164
|
+
F && /* @__PURE__ */ p(a, { state: W }),
|
|
165
|
+
I && D.length > 1 && /* @__PURE__ */ p(i, {
|
|
166
|
+
items: D.map((e, t) => ({
|
|
167
|
+
label: e.label,
|
|
168
|
+
color: Y[t]
|
|
169
|
+
})),
|
|
170
|
+
className: "mt-ds-04"
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
T.displayName = "AreaChart";
|
|
176
|
+
//#endregion
|
|
177
|
+
export { T as AreaChart };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"area-chart.js","names":[],"sources":["../../../src/ui/charts/area-chart.tsx"],"sourcesContent":["'use client'\n\nimport type { ScaleLinear, ScalePoint } from 'd3-scale'\nimport { scaleLinear, scalePoint } from 'd3-scale'\nimport {\n area,\n curveLinear,\n curveMonotoneX,\n line,\n stack,\n stackOffsetNone,\n stackOrderNone,\n} from 'd3-shape'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { motionProps,tweens } from '../lib/motion'\nimport { cn } from '../lib/utils'\nimport { useReducedMotion } from './_internal/animation'\nimport { type AnyScale,Axis } from './_internal/axes'\nimport { resolveColor } from './_internal/colors'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport type { DataPoint, Series } from './_internal/types'\nimport { ChartContainer } from './chart-container'\n\nexport interface AreaChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis */\n xKey: string\n /** Series definitions — each becomes an area */\n series: Series[]\n /** Use curved (monotone) interpolation */\n curved?: boolean\n /** Stack areas on top of each other */\n stacked?: boolean\n /** Fill opacity for area shapes */\n fillOpacity?: number\n /** Use vertical gradient fill */\n gradient?: boolean\n /** Stroke width for area outline */\n strokeWidth?: number\n /** Chart height */\n height?: number\n /** Show grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\n/** Type for rows fed to d3 stack — all numeric except the xKey */\ninterface StackableRow {\n [key: string]: number | string\n}\n\nexport const AreaChart = React.forwardRef<HTMLDivElement, AreaChartProps>(\n (\n {\n data,\n xKey,\n series,\n curved = false,\n stacked = false,\n fillOpacity = 0.3,\n gradient = false,\n strokeWidth = 2,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n xLabel,\n yLabel,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Stable unique ID for gradient definitions\n const chartId = React.useId()\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Area chart'}>\n {({ width, height: innerHeight, margin }) => {\n void margin\n\n // Determine if x-axis data is numeric or categorical\n const xValues = data.map((d) => d[xKey])\n const isNumericX = xValues.every((v) => typeof v === 'number')\n\n // Build x scale and accessor\n let xAxisScale: ScaleLinear<number, number> | ScalePoint<string>\n let getX: (d: DataPoint) => number\n let getXByIndex: (i: number) => number\n\n if (isNumericX) {\n const numericValues = xValues as number[]\n const xMin = Math.min(...numericValues)\n const xMax = Math.max(...numericValues)\n const linearX = scaleLinear<number, number>()\n .domain([xMin, xMax])\n .range([0, width])\n xAxisScale = linearX\n getX = (d: DataPoint) => linearX(Number(d[xKey]))\n getXByIndex = (i: number) => linearX(Number(data[i][xKey]))\n } else {\n const categories = xValues.map(String)\n const pointX = scalePoint<string>()\n .domain(categories)\n .range([0, width])\n .padding(0.5)\n xAxisScale = pointX\n getX = (d: DataPoint) => pointX(String(d[xKey])) ?? 0\n getXByIndex = (i: number) => pointX(String(data[i][xKey])) ?? 0\n }\n\n // Build y scale\n let yMax: number\n if (stacked) {\n yMax = Math.max(\n ...data.map((d) =>\n series.reduce((sum, s) => sum + (Number(d[s.key]) || 0), 0),\n ),\n )\n } else {\n yMax = Math.max(\n ...data.flatMap((d) =>\n series.map((s) => Number(d[s.key]) || 0),\n ),\n )\n }\n\n const yScale = scaleLinear<number, number>()\n .domain([0, yMax * 1.1])\n .range([innerHeight, 0])\n .nice()\n\n const curveType = curved ? curveMonotoneX : curveLinear\n\n // Shared tooltip render function\n const renderTooltipZones = () =>\n data.map((d, i) => {\n const cx = getX(d)\n const sliceWidth = width / Math.max(data.length - 1, 1)\n return (\n <rect\n key={`hover-${i}`}\n x={cx - sliceWidth / 2}\n y={0}\n width={sliceWidth}\n height={innerHeight}\n fill=\"transparent\"\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">\n {String(d[xKey])}\n </div>\n {series.map((s, sIdx) => (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-pill\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {Number(d[s.key]).toLocaleString()}\n </div>\n ))}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })\n\n // Shared gradient definitions\n const renderGradientDefs = () =>\n gradient ? (\n <defs>\n {series.map((_, sIdx) => (\n <linearGradient\n key={`grad-${sIdx}`}\n id={`${chartId}-gradient-${sIdx}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop\n offset=\"0%\"\n stopColor={colors[sIdx]}\n stopOpacity={fillOpacity}\n />\n <stop\n offset=\"100%\"\n stopColor={colors[sIdx]}\n stopOpacity={0.05}\n />\n </linearGradient>\n ))}\n </defs>\n ) : null\n\n // Shared axes\n const renderAxes = () => (\n <>\n <Axis\n scale={xAxisScale as AnyScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={yScale} orientation=\"left\" label={yLabel} />\n </>\n )\n\n // Stacked layout\n if (stacked) {\n const seriesKeys = series.map((s) => s.key)\n const stackGen = stack<StackableRow>()\n .keys(seriesKeys)\n .order(stackOrderNone)\n .offset(stackOffsetNone)\n\n // Coerce data to StackableRow (numeric values for series keys)\n const numericData: StackableRow[] = data.map((d) => {\n const row: StackableRow = { [xKey]: String(d[xKey]) }\n for (const s of series) {\n row[s.key] = Number(d[s.key]) || 0\n }\n return row\n })\n\n const stackedData = stackGen(numericData)\n\n const areaGen = area<[number, number]>()\n .curve(curveType)\n .x((_, i) => getXByIndex(i))\n .y0((d) => yScale(d[0]))\n .y1((d) => yScale(d[1]))\n\n const lineGen = line<[number, number]>()\n .curve(curveType)\n .x((_, i) => getXByIndex(i))\n .y((d) => yScale(d[1]))\n\n return (\n <>\n {renderGradientDefs()}\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Stacked areas (render in reverse so first series is on top) */}\n {[...stackedData].reverse().map((layer, reversedIdx) => {\n const seriesIdx = stackedData.length - 1 - reversedIdx\n const layerData = layer as unknown as [number, number][]\n const areaD = areaGen(layerData) ?? ''\n const lineD = lineGen(layerData) ?? ''\n const fillColor = gradient\n ? `url(#${chartId}-gradient-${seriesIdx})`\n : colors[seriesIdx]\n\n return (\n <g key={series[seriesIdx].key}>\n <path\n d={areaD}\n fill={fillColor}\n opacity={gradient ? 1 : fillOpacity}\n />\n <path\n d={lineD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </g>\n )\n })}\n\n {/* Tooltip hover zones */}\n {showTooltip && renderTooltipZones()}\n\n {renderAxes()}\n </>\n )\n }\n\n // Non-stacked areas\n const areaGen = area<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n const lineGen = line<DataPoint>()\n .curve(curveType)\n .defined((d) => d !== undefined && d !== null)\n\n return (\n <>\n {renderGradientDefs()}\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={yScale}\n horizontal\n />\n )}\n\n {/* Areas (render in reverse so first series is visually on top) */}\n {[...series].reverse().map((s, reversedIdx) => {\n const seriesIdx = series.length - 1 - reversedIdx\n\n const areaPath = areaGen\n .x((d) => getX(d))\n .y0(innerHeight)\n .y1((d) => yScale(Number(d[s.key]) || 0))\n\n const linePath = lineGen\n .x((d) => getX(d))\n .y((d) => yScale(Number(d[s.key]) || 0))\n\n const areaD = areaPath(data) ?? ''\n const lineD = linePath(data) ?? ''\n\n const fillColor = gradient\n ? `url(#${chartId}-gradient-${seriesIdx})`\n : colors[seriesIdx]\n\n return (\n <g key={s.key}>\n <path\n d={areaD}\n fill={fillColor}\n opacity={gradient ? 1 : fillOpacity}\n />\n <path\n d={lineD}\n fill=\"none\"\n stroke={colors[seriesIdx]}\n strokeWidth={strokeWidth}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </g>\n )\n })}\n\n {/* Tooltip hover zones */}\n {showTooltip && renderTooltipZones()}\n\n {renderAxes()}\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && series.length > 1 && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nAreaChart.displayName = 'AreaChart'\n"],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { motionProps as e, tweens as t } from "../lib/motion.js";
|
|
3
|
+
import { cn as n } from "../lib/utils.js";
|
|
4
|
+
import { n as r, r as i, t as a } from "../../_chunks/tooltip.js";
|
|
5
|
+
import { r as o, t as s } from "../../_chunks/colors.js";
|
|
6
|
+
import { n as c, t as l } from "../../_chunks/grid-lines.js";
|
|
7
|
+
import { t as u } from "../../_chunks/chart-container.js";
|
|
8
|
+
import * as d from "react";
|
|
9
|
+
import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
10
|
+
import { motion as h } from "framer-motion";
|
|
11
|
+
import { scaleBand as g, scaleLinear as _ } from "d3-scale";
|
|
12
|
+
//#region src/ui/charts/bar-chart.tsx
|
|
13
|
+
var v = d.forwardRef(({ data: d, xKey: v, yKey: y, orientation: b = "vertical", stacked: x = !1, grouped: S = !1, color: C, height: w = 300, showGrid: T = !0, showTooltip: E = !0, showLegend: D = !1, animate: O = !0, barRadius: k = 4, xLabel: A, yLabel: j, seriesLabels: M, ariaLabel: N, className: P, ...F }, I) => {
|
|
14
|
+
let { tooltip: L, show: R, hide: z } = r(), B = o(), V = b === "vertical", H = O && !B, U = Array.isArray(y) ? y : [y], W = U.length > 1, G = W ? U.map((e, t) => s(Array.isArray(C) ? C[t] : typeof C == "string" ? C : void 0, t)) : [s(typeof C == "string" ? C : Array.isArray(C) ? C[0] : void 0, 0)];
|
|
15
|
+
return /* @__PURE__ */ m(h.div, {
|
|
16
|
+
ref: I,
|
|
17
|
+
className: n("relative", P),
|
|
18
|
+
...H ? {
|
|
19
|
+
initial: {
|
|
20
|
+
opacity: 0,
|
|
21
|
+
scale: .96
|
|
22
|
+
},
|
|
23
|
+
animate: {
|
|
24
|
+
opacity: 1,
|
|
25
|
+
scale: 1
|
|
26
|
+
},
|
|
27
|
+
transition: t.fade
|
|
28
|
+
} : {},
|
|
29
|
+
...e(F),
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ p(u, {
|
|
32
|
+
height: w,
|
|
33
|
+
ariaLabel: N ?? "Bar chart",
|
|
34
|
+
children: ({ width: e, height: t, margin: n }) => {
|
|
35
|
+
let r = d.map((e) => String(e[v])), i = d.map((e) => `${String(e[v])} — ${U.map((t, n) => `${M?.[n] ?? t}: ${Number(e[t]).toLocaleString()}`).join(", ")}`).join(". "), a;
|
|
36
|
+
a = Math.max(...x ? d.map((e) => U.reduce((t, n) => t + (Number(e[n]) || 0), 0)) : d.flatMap((e) => U.map((t) => Number(e[t]) || 0)));
|
|
37
|
+
let o = g().domain(r).range(V ? [0, e] : [0, t]).padding(.2), s = _().domain([0, a * 1.1]).range(V ? [t, 0] : [0, e]).nice(), u = o.bandwidth(), h = W && S ? u / U.length : u;
|
|
38
|
+
return /* @__PURE__ */ m(f, { children: [
|
|
39
|
+
/* @__PURE__ */ p("desc", { children: i }),
|
|
40
|
+
T && /* @__PURE__ */ p(l, {
|
|
41
|
+
width: e,
|
|
42
|
+
height: t,
|
|
43
|
+
yScale: V ? s : void 0,
|
|
44
|
+
xScale: V ? void 0 : s,
|
|
45
|
+
horizontal: V,
|
|
46
|
+
vertical: !V
|
|
47
|
+
}),
|
|
48
|
+
d.map((e) => {
|
|
49
|
+
let n = String(e[v]), r = 0;
|
|
50
|
+
return U.map((i, a) => {
|
|
51
|
+
let c = Number(e[i]) || 0, l = G[a] || G[0], u, d, f, g;
|
|
52
|
+
V ? (u = (o(n) ?? 0) + (S && W ? a * h : 0), d = s(x ? r + c : c), f = h, g = x ? s(r) - s(r + c) : t - s(c)) : (u = x ? s(r) : 0, d = (o(n) ?? 0) + (S && W ? a * h : 0), f = x ? s(r + c) - s(r) : s(c), g = h), x && (r += c);
|
|
53
|
+
let _ = M?.[a] ?? i, v = W ? `${n}, ${_}: ${c.toLocaleString()}` : `${n}: ${c.toLocaleString()}`, y = /* @__PURE__ */ m("div", { children: [
|
|
54
|
+
/* @__PURE__ */ p("div", {
|
|
55
|
+
className: "font-medium",
|
|
56
|
+
children: n
|
|
57
|
+
}),
|
|
58
|
+
W && /* @__PURE__ */ p("div", {
|
|
59
|
+
className: "text-surface-fg-muted",
|
|
60
|
+
children: _
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ p("div", { children: c.toLocaleString() })
|
|
63
|
+
] });
|
|
64
|
+
return /* @__PURE__ */ p("rect", {
|
|
65
|
+
x: u,
|
|
66
|
+
y: d,
|
|
67
|
+
width: Math.max(0, f),
|
|
68
|
+
height: Math.max(0, g),
|
|
69
|
+
rx: k,
|
|
70
|
+
fill: l,
|
|
71
|
+
className: "transition-opacity hover:opacity-80 focus-visible:outline-hidden focus-visible:opacity-80",
|
|
72
|
+
tabIndex: E ? 0 : void 0,
|
|
73
|
+
role: E ? "graphics-symbol" : void 0,
|
|
74
|
+
"aria-label": v,
|
|
75
|
+
onMouseMove: (e) => {
|
|
76
|
+
if (E) {
|
|
77
|
+
let t = e.currentTarget.closest("div")?.getBoundingClientRect();
|
|
78
|
+
R(e.clientX - (t?.left ?? 0), e.clientY - (t?.top ?? 0), y);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
onMouseLeave: z,
|
|
82
|
+
onFocus: (e) => {
|
|
83
|
+
if (E) {
|
|
84
|
+
let t = e.currentTarget.closest("div")?.getBoundingClientRect(), n = e.currentTarget.getBoundingClientRect();
|
|
85
|
+
R(n.left + n.width / 2 - (t?.left ?? 0), n.top - (t?.top ?? 0), y);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
onBlur: z
|
|
89
|
+
}, `${n}-${i}`);
|
|
90
|
+
});
|
|
91
|
+
}),
|
|
92
|
+
V ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(c, {
|
|
93
|
+
scale: o,
|
|
94
|
+
orientation: "bottom",
|
|
95
|
+
transform: `translate(0,${t})`,
|
|
96
|
+
label: A
|
|
97
|
+
}), /* @__PURE__ */ p(c, {
|
|
98
|
+
scale: s,
|
|
99
|
+
orientation: "left",
|
|
100
|
+
label: j
|
|
101
|
+
})] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(c, {
|
|
102
|
+
scale: s,
|
|
103
|
+
orientation: "bottom",
|
|
104
|
+
transform: `translate(0,${t})`,
|
|
105
|
+
label: A
|
|
106
|
+
}), /* @__PURE__ */ p(c, {
|
|
107
|
+
scale: o,
|
|
108
|
+
orientation: "left",
|
|
109
|
+
label: j
|
|
110
|
+
})] })
|
|
111
|
+
] });
|
|
112
|
+
}
|
|
113
|
+
}),
|
|
114
|
+
E && /* @__PURE__ */ p(a, { state: L }),
|
|
115
|
+
D && W && /* @__PURE__ */ p(i, {
|
|
116
|
+
items: U.map((e, t) => ({
|
|
117
|
+
label: M?.[t] ?? e,
|
|
118
|
+
color: G[t]
|
|
119
|
+
})),
|
|
120
|
+
className: "mt-ds-04"
|
|
121
|
+
})
|
|
122
|
+
]
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
v.displayName = "BarChart";
|
|
126
|
+
//#endregion
|
|
127
|
+
export { v as BarChart };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-chart.js","names":[],"sources":["../../../src/ui/charts/bar-chart.tsx"],"sourcesContent":["'use client'\n\nimport { scaleBand, scaleLinear } from 'd3-scale'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { motionProps,tweens } from '../lib/motion'\nimport { cn } from '../lib/utils'\nimport { useReducedMotion } from './_internal/animation'\nimport { Axis } from './_internal/axes'\nimport { resolveColor } from './_internal/colors'\nimport { GridLines } from './_internal/grid-lines'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\nimport type { ChartColor,DataPoint } from './_internal/types'\nimport { ChartContainer } from './chart-container'\n\nexport interface BarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'color'> {\n /** Data array */\n data: DataPoint[]\n /** Key for x-axis categories */\n xKey: string\n /** Key(s) for y-axis values. String for single series, array for multi-series */\n yKey: string | string[]\n /** Bar orientation */\n orientation?: 'vertical' | 'horizontal'\n /** Stack multiple series */\n stacked?: boolean\n /** Group multiple series side by side */\n grouped?: boolean\n /** Color(s) for bars */\n color?: ChartColor | ChartColor[] | string | string[]\n /** Chart height in pixels */\n height?: number\n /** Show background grid lines */\n showGrid?: boolean\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend (only for multi-series) */\n showLegend?: boolean\n /** Animate bars on mount */\n animate?: boolean\n /** Bar corner radius */\n barRadius?: number\n /** X-axis label */\n xLabel?: string\n /** Y-axis label */\n yLabel?: string\n /** Series labels (for legend) */\n seriesLabels?: string[]\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const BarChart = React.forwardRef<HTMLDivElement, BarChartProps>(\n (\n {\n data,\n xKey,\n yKey,\n orientation = 'vertical',\n stacked = false,\n grouped = false,\n color,\n height = 300,\n showGrid = true,\n showTooltip = true,\n showLegend = false,\n animate = true,\n barRadius = 4,\n xLabel,\n yLabel,\n seriesLabels,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const isVertical = orientation === 'vertical'\n const shouldAnimate = animate && !reducedMotion\n\n // Normalize yKey to array\n const yKeys = Array.isArray(yKey) ? yKey : [yKey]\n const isMultiSeries = yKeys.length > 1\n\n // Resolve colors\n const colors = isMultiSeries\n ? yKeys.map((_, i) =>\n resolveColor(\n Array.isArray(color) ? color[i] : typeof color === 'string' ? color : undefined,\n i,\n ),\n )\n : [\n resolveColor(\n typeof color === 'string'\n ? color\n : Array.isArray(color)\n ? color[0]\n : undefined,\n 0,\n ),\n ]\n\n return (\n <motion.div\n ref={ref}\n className={cn('relative', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n <ChartContainer height={height} ariaLabel={ariaLabel ?? 'Bar chart'}>\n {({ width, height: innerHeight, margin }) => {\n // Suppress unused-var lint for margin (available for extensions)\n void margin\n\n // Category labels\n const categories = data.map((d) => String(d[xKey]))\n\n // Build data summary for screen readers\n const dataSummary = data.map((d) => {\n const cat = String(d[xKey])\n const vals = yKeys.map((k, i) => {\n const lbl = seriesLabels?.[i] ?? k\n return `${lbl}: ${Number(d[k]).toLocaleString()}`\n }).join(', ')\n return `${cat} — ${vals}`\n }).join('. ')\n\n // Calculate max value\n let maxValue: number\n if (stacked) {\n maxValue = Math.max(\n ...data.map((d) =>\n yKeys.reduce((sum, k) => sum + (Number(d[k]) || 0), 0),\n ),\n )\n } else {\n maxValue = Math.max(\n ...data.flatMap((d) => yKeys.map((k) => Number(d[k]) || 0)),\n )\n }\n\n // Build scales\n const categoryScale = scaleBand()\n .domain(categories)\n .range(isVertical ? [0, width] : [0, innerHeight])\n .padding(0.2)\n\n const valueScale = scaleLinear()\n .domain([0, maxValue * 1.1])\n .range(isVertical ? [innerHeight, 0] : [0, width])\n .nice()\n\n const barBandwidth = categoryScale.bandwidth()\n const barWidth =\n isMultiSeries && grouped\n ? barBandwidth / yKeys.length\n : barBandwidth\n\n return (\n <>\n {/* Screen-reader data summary */}\n <desc>{dataSummary}</desc>\n\n {/* Grid */}\n {showGrid && (\n <GridLines\n width={width}\n height={innerHeight}\n yScale={isVertical ? valueScale : undefined}\n xScale={!isVertical ? valueScale : undefined}\n horizontal={isVertical}\n vertical={!isVertical}\n />\n )}\n\n {/* Bars */}\n {data.map((d) => {\n const category = String(d[xKey])\n let stackOffset = 0\n\n return yKeys.map((key, seriesIdx) => {\n const value = Number(d[key]) || 0\n const barColor = colors[seriesIdx] || colors[0]\n\n let x: number, y: number, w: number, h: number\n\n if (isVertical) {\n x =\n (categoryScale(category) ?? 0) +\n (grouped && isMultiSeries ? seriesIdx * barWidth : 0)\n y = stacked\n ? valueScale(stackOffset + value)\n : valueScale(value)\n w = barWidth\n h = stacked\n ? valueScale(stackOffset) - valueScale(stackOffset + value)\n : innerHeight - valueScale(value)\n } else {\n x = stacked ? valueScale(stackOffset) : 0\n y =\n (categoryScale(category) ?? 0) +\n (grouped && isMultiSeries ? seriesIdx * barWidth : 0)\n w = stacked\n ? valueScale(stackOffset + value) - valueScale(stackOffset)\n : valueScale(value)\n h = barWidth\n }\n\n if (stacked) stackOffset += value\n\n const seriesLabel = seriesLabels?.[seriesIdx] ?? key\n const barAriaLabel = isMultiSeries\n ? `${category}, ${seriesLabel}: ${value.toLocaleString()}`\n : `${category}: ${value.toLocaleString()}`\n\n const tooltipContent = (\n <div>\n <div className=\"font-medium\">{category}</div>\n {isMultiSeries && (\n <div className=\"text-surface-fg-muted\">\n {seriesLabel}\n </div>\n )}\n <div>{value.toLocaleString()}</div>\n </div>\n )\n\n return (\n <rect\n key={`${category}-${key}`}\n x={x}\n y={y}\n width={Math.max(0, w)}\n height={Math.max(0, h)}\n rx={barRadius}\n fill={barColor}\n className=\"transition-opacity hover:opacity-80 focus-visible:outline-hidden focus-visible:opacity-80\"\n tabIndex={showTooltip ? 0 : undefined}\n role={showTooltip ? 'graphics-symbol' : undefined}\n aria-label={barAriaLabel}\n onMouseMove={(e) => {\n if (showTooltip) {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n tooltipContent,\n )\n }\n }}\n onMouseLeave={hide}\n onFocus={(e) => {\n if (showTooltip) {\n const svgRect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n const barRect = e.currentTarget.getBoundingClientRect()\n show(\n barRect.left + barRect.width / 2 - (svgRect?.left ?? 0),\n barRect.top - (svgRect?.top ?? 0),\n tooltipContent,\n )\n }\n }}\n onBlur={hide}\n />\n )\n })\n })}\n\n {/* Axes */}\n {isVertical ? (\n <>\n <Axis\n scale={categoryScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis scale={valueScale} orientation=\"left\" label={yLabel} />\n </>\n ) : (\n <>\n <Axis\n scale={valueScale}\n orientation=\"bottom\"\n transform={`translate(0,${innerHeight})`}\n label={xLabel}\n />\n <Axis\n scale={categoryScale}\n orientation=\"left\"\n label={yLabel}\n />\n </>\n )}\n </>\n )\n }}\n </ChartContainer>\n\n {/* Tooltip overlay */}\n {showTooltip && <ChartTooltip state={tooltip} />}\n\n {/* Legend */}\n {showLegend && isMultiSeries && (\n <Legend\n items={yKeys.map((key, i) => ({\n label: seriesLabels?.[i] ?? key,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nBarChart.displayName = 'BarChart'\n"],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { motionProps as e, tweens as t } from "../lib/motion.js";
|
|
3
|
+
import { cn as n } from "../lib/utils.js";
|
|
4
|
+
import { n as r, r as i, t as a } from "../../_chunks/colors.js";
|
|
5
|
+
import * as o from "react";
|
|
6
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
7
|
+
import { motion as l } from "framer-motion";
|
|
8
|
+
import { arc as u } from "d3-shape";
|
|
9
|
+
//#region src/ui/charts/gauge-chart.tsx
|
|
10
|
+
var d = (e) => e * Math.PI / 180, f = o.forwardRef(({ value: o, max: f = 100, min: p = 0, label: m, valueLabel: h, color: g, trackColor: _ = "var(--color-surface-border)", height: v = 200, startAngle: y = -120, endAngle: b = 120, thickness: x = 16, animate: S = !0, className: C, ...w }, T) => {
|
|
11
|
+
let E = i(), D = r(E, S ? 600 : 0), O = S && !E, k = a(g, 0), A = v, j = A / 2, M = Math.min(Math.max(o, p), f), N = f === p ? 0 : (M - p) / (f - p), P = y + (b - y) * N, F = typeof h == "function" ? h(M) : typeof h == "string" ? h : String(M), I = u().innerRadius(j - x).outerRadius(j).startAngle(d(y)).endAngle(d(b)).cornerRadius(x / 2), L = u().innerRadius(j - x).outerRadius(j).startAngle(d(y)).endAngle(d(P)).cornerRadius(x / 2), R = I(null) ?? "", z = L(null) ?? "";
|
|
12
|
+
return /* @__PURE__ */ s(l.div, {
|
|
13
|
+
ref: T,
|
|
14
|
+
className: n("inline-flex flex-col items-center", C),
|
|
15
|
+
...O ? {
|
|
16
|
+
initial: {
|
|
17
|
+
opacity: 0,
|
|
18
|
+
scale: .96
|
|
19
|
+
},
|
|
20
|
+
animate: {
|
|
21
|
+
opacity: 1,
|
|
22
|
+
scale: 1
|
|
23
|
+
},
|
|
24
|
+
transition: t.fade
|
|
25
|
+
} : {},
|
|
26
|
+
...e(w),
|
|
27
|
+
role: "meter",
|
|
28
|
+
"aria-valuenow": M,
|
|
29
|
+
"aria-valuemin": p,
|
|
30
|
+
"aria-valuemax": f,
|
|
31
|
+
"aria-label": m ?? "Gauge chart",
|
|
32
|
+
children: /* @__PURE__ */ s("svg", {
|
|
33
|
+
width: A,
|
|
34
|
+
height: A,
|
|
35
|
+
role: "img",
|
|
36
|
+
"aria-hidden": "true",
|
|
37
|
+
children: /* @__PURE__ */ c("g", {
|
|
38
|
+
transform: `translate(${j},${j})`,
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ s("path", {
|
|
41
|
+
d: R,
|
|
42
|
+
fill: _
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ s("path", {
|
|
45
|
+
d: z,
|
|
46
|
+
fill: k,
|
|
47
|
+
style: D > 0 ? { transition: `d ${D}ms ease-out` } : void 0
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ s("text", {
|
|
50
|
+
x: 0,
|
|
51
|
+
y: m ? -4 : 0,
|
|
52
|
+
textAnchor: "middle",
|
|
53
|
+
dominantBaseline: "central",
|
|
54
|
+
className: "fill-surface-fg text-ds-2xl font-semibold",
|
|
55
|
+
children: F
|
|
56
|
+
}),
|
|
57
|
+
m && /* @__PURE__ */ s("text", {
|
|
58
|
+
x: 0,
|
|
59
|
+
y: 20,
|
|
60
|
+
textAnchor: "middle",
|
|
61
|
+
dominantBaseline: "central",
|
|
62
|
+
className: "fill-surface-fg-muted text-ds-xs",
|
|
63
|
+
children: m
|
|
64
|
+
})
|
|
65
|
+
]
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
f.displayName = "GaugeChart";
|
|
71
|
+
//#endregion
|
|
72
|
+
export { f as GaugeChart };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gauge-chart.js","names":[],"sources":["../../../src/ui/charts/gauge-chart.tsx"],"sourcesContent":["'use client'\n\nimport { arc } from 'd3-shape'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { motionProps,tweens } from '../lib/motion'\nimport { cn } from '../lib/utils'\nimport { getTransitionDuration,useReducedMotion } from './_internal/animation'\nimport { resolveColor } from './_internal/colors'\n\nexport interface GaugeChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'color'> {\n /** Current value */\n value: number\n /** Maximum value (default: 100) */\n max?: number\n /** Minimum value (default: 0) */\n min?: number\n /** Label below the value */\n label?: string\n /** Custom value display */\n valueLabel?: string | ((value: number) => string)\n /** Arc color */\n color?: string\n /** Track (background) color */\n trackColor?: string\n /** Chart height/width (default: 200) */\n height?: number\n /** Start angle in degrees (default: -120) */\n startAngle?: number\n /** End angle in degrees (default: 120) */\n endAngle?: number\n /** Arc thickness in pixels (default: 16) */\n thickness?: number\n /** Animate the value arc */\n animate?: boolean\n className?: string\n}\n\nconst toRad = (deg: number) => (deg * Math.PI) / 180\n\nexport const GaugeChart = React.forwardRef<HTMLDivElement, GaugeChartProps>(\n (\n {\n value,\n max = 100,\n min = 0,\n label,\n valueLabel,\n color,\n trackColor = 'var(--color-surface-border)',\n height = 200,\n startAngle = -120,\n endAngle = 120,\n thickness = 16,\n animate = true,\n className,\n ...props\n },\n ref,\n ) => {\n const reducedMotion = useReducedMotion()\n const duration = getTransitionDuration(reducedMotion, animate ? 600 : 0)\n const shouldAnimate = animate && !reducedMotion\n\n const resolvedColor = resolveColor(color, 0)\n const size = height\n const radius = size / 2\n\n // Clamp value to [min, max]\n const clampedValue = Math.min(Math.max(value, min), max)\n const valueFraction = max === min ? 0 : (clampedValue - min) / (max - min)\n const valueEndAngle = startAngle + (endAngle - startAngle) * valueFraction\n\n // Display text\n const displayValue =\n typeof valueLabel === 'function'\n ? valueLabel(clampedValue)\n : typeof valueLabel === 'string'\n ? valueLabel\n : String(clampedValue)\n\n // Track arc generator\n const trackGenerator = arc<unknown>()\n .innerRadius(radius - thickness)\n .outerRadius(radius)\n .startAngle(toRad(startAngle))\n .endAngle(toRad(endAngle))\n .cornerRadius(thickness / 2)\n\n // Value arc generator\n const valueGenerator = arc<unknown>()\n .innerRadius(radius - thickness)\n .outerRadius(radius)\n .startAngle(toRad(startAngle))\n .endAngle(toRad(valueEndAngle))\n .cornerRadius(thickness / 2)\n\n const trackPath = trackGenerator(null as unknown as Record<string, never>) ?? ''\n const valuePath = valueGenerator(null as unknown as Record<string, never>) ?? ''\n\n return (\n <motion.div\n ref={ref}\n className={cn('inline-flex flex-col items-center', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n role=\"meter\"\n aria-valuenow={clampedValue}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-label={label ?? 'Gauge chart'}\n >\n <svg width={size} height={size} role=\"img\" aria-hidden=\"true\">\n <g transform={`translate(${radius},${radius})`}>\n {/* Background track */}\n <path d={trackPath} fill={trackColor} />\n\n {/* Value arc */}\n <path\n d={valuePath}\n fill={resolvedColor}\n style={\n duration > 0\n ? { transition: `d ${duration}ms ease-out` }\n : undefined\n }\n />\n\n {/* Center value text */}\n <text\n x={0}\n y={label ? -4 : 0}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"fill-surface-fg text-ds-2xl font-semibold\"\n >\n {displayValue}\n </text>\n\n {/* Label below value */}\n {label && (\n <text\n x={0}\n y={20}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className=\"fill-surface-fg-muted text-ds-xs\"\n >\n {label}\n </text>\n )}\n </g>\n </svg>\n </motion.div>\n )\n },\n)\nGaugeChart.displayName = 'GaugeChart'\n"],"mappings":";;;;;;;;;AAuCA,IAAM,KAAS,MAAiB,IAAM,KAAK,KAAM,KAEpC,IAAa,EAAM,YAE5B,EACE,UACA,SAAM,KACN,SAAM,GACN,UACA,eACA,UACA,gBAAa,+BACb,YAAS,KACT,gBAAa,MACb,cAAW,KACX,eAAY,IACZ,aAAU,IACV,cACA,GAAG,KAEL,MACG;CACL,IAAM,IAAgB,GAAkB,EAClC,IAAW,EAAsB,GAAe,IAAU,MAAM,EAAE,EAClE,IAAgB,KAAW,CAAC,GAE5B,IAAgB,EAAa,GAAO,EAAE,EACtC,IAAO,GACP,IAAS,IAAO,GAGhB,IAAe,KAAK,IAAI,KAAK,IAAI,GAAO,EAAI,EAAE,EAAI,EAClD,IAAgB,MAAQ,IAAM,KAAK,IAAe,MAAQ,IAAM,IAChE,IAAgB,KAAc,IAAW,KAAc,GAGvD,IACJ,OAAO,KAAe,aAClB,EAAW,EAAa,GACxB,OAAO,KAAe,WACpB,IACA,OAAO,EAAa,EAGtB,IAAiB,GAAc,CAClC,YAAY,IAAS,EAAU,CAC/B,YAAY,EAAO,CACnB,WAAW,EAAM,EAAW,CAAC,CAC7B,SAAS,EAAM,EAAS,CAAC,CACzB,aAAa,IAAY,EAAE,EAGxB,IAAiB,GAAc,CAClC,YAAY,IAAS,EAAU,CAC/B,YAAY,EAAO,CACnB,WAAW,EAAM,EAAW,CAAC,CAC7B,SAAS,EAAM,EAAc,CAAC,CAC9B,aAAa,IAAY,EAAE,EAExB,IAAY,EAAe,KAAyC,IAAI,IACxE,IAAY,EAAe,KAAyC,IAAI;AAE9E,QACE,kBAAC,EAAO,KAAR;EACO;EACL,WAAW,EAAG,qCAAqC,EAAU;EAC7D,GAAK,IACD;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GAAE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GAAE,YAAY,EAAO;GAAM,GACpG,EAAE;EACN,GAAI,EAAY,EAAM;EACtB,MAAK;EACL,iBAAe;EACf,iBAAe;EACf,iBAAe;EACf,cAAY,KAAS;YAErB,kBAAC,OAAD;GAAK,OAAO;GAAM,QAAQ;GAAM,MAAK;GAAM,eAAY;aACrD,kBAAC,KAAD;IAAG,WAAW,aAAa,EAAO,GAAG,EAAO;cAA5C;KAEE,kBAAC,QAAD;MAAM,GAAG;MAAW,MAAM;MAAc,CAAA;KAGxC,kBAAC,QAAD;MACE,GAAG;MACH,MAAM;MACN,OACE,IAAW,IACP,EAAE,YAAY,KAAK,EAAS,cAAc,GAC1C,KAAA;MAEN,CAAA;KAGF,kBAAC,QAAD;MACE,GAAG;MACH,GAAG,IAAQ,KAAK;MAChB,YAAW;MACX,kBAAiB;MACjB,WAAU;gBAET;MACI,CAAA;KAGN,KACC,kBAAC,QAAD;MACE,GAAG;MACH,GAAG;MACH,YAAW;MACX,kBAAiB;MACjB,WAAU;gBAET;MACI,CAAA;KAEP;;GACA,CAAA;EACK,CAAA;EAGhB;AACD,EAAW,cAAc"}
|