waffle-batch 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Waffle Board
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # Waffle Batch 🧇
2
+
3
+ **High-Performance React Faceting Engine**
4
+
5
+ `waffle-batch` is a specialized charting engine designed to render **thousands of small multiples** ("trellis charts") efficiently. It solves the performance bottlenecks of rendering massive dashboard grids by leveraging virtualization, shared resource scaling, and optimized data splitting.
6
+
7
+ ![License](https://img.shields.io/badge/license-MIT-blue.svg)
8
+ ![React](https://img.shields.io/badge/react-19-blue)
9
+ ![Vite](https://img.shields.io/badge/vite-6-purple)
10
+
11
+ ## 🚀 Features
12
+
13
+ - **High-Performance Rendering**: Uses `react-intersection-observer` to virtualize charts, rendering only what is in the viewport (with skeleton loading states).
14
+ - **Trellis Architecture**: Automatically groups flat datasets into faceted grids based on any key (e.g., `Region`, `Category`).
15
+ - **Shared Scales**: Calculates global min/max domains across the entire dataset to ensure visual consistency between charts.
16
+ - **Statistical Sorting**: Built-in analytics engine to sort charts by:
17
+ - **Total Value** (Sum)
18
+ - **Volatility** (Standard Deviation)
19
+ - **Trend Direction** (Linear Regression Slope)
20
+ - **Custom Logic** (User-defined functions)
21
+ - **Interactive Search & URL Sync**: Filters charts with debouncing and synchronizes state (Search, Sort, Config) with URL query parameters for deep linking.
22
+ - **Contextual Drill-Down**: Supports clickable charts that can navigate to external dashboards (e.g., `waffle-board`) with context-specific query parameters.
23
+ - **Responsive Layout**: CSS Grid-based layout that adapts chart width to available screen space.
24
+
25
+ ## 📦 Installation
26
+ You can use `waffle-batch` as a standalone library in your React application.
27
+
28
+ ```bash
29
+ npm install waffle-batch
30
+ # OR
31
+ npm install git+https://github.com/mbuchthal/waffle-batch.git
32
+ ```
33
+
34
+ **Peer Dependencies:**
35
+ - `react` >= 18
36
+ - `react-dom` >= 18
37
+
38
+ ## 🛠 Usage
39
+
40
+ ### The `Trellis` Component
41
+
42
+ The core of the library is the `Trellis` component.
43
+
44
+ ```tsx
45
+ import { Trellis } from 'waffle-batch';
46
+
47
+ // 1. Prepare your data (flat array)
48
+ const salesData = [
49
+ { region: 'West', month: 'Jan', value: 400 },
50
+ { region: 'West', month: 'Feb', value: 300 },
51
+ // ...
52
+ { region: 'East', month: 'Jan', value: 200 },
53
+ ];
54
+
55
+ // 2. Render
56
+ <Trellis
57
+ data={salesData}
58
+ facetKey="region" // Group by 'region'
59
+ valueKey="value" // Metric for scaling/sorting
60
+ ChartComponent={MyChartComponent} // Your chart renderer
61
+ minChartWidth={300}
62
+ height={150}
63
+ sharedScale={true} // Enforce same Y-axis across all charts
64
+
65
+ // Optional: Sorting
66
+ sortConfig={{
67
+ type: 'trend', // Sort by growth trend
68
+ direction: 'desc'
69
+ }}
70
+
71
+ // Optional: Drill-Down Interaction
72
+ onChartClick={(key) => {
73
+ window.location.href = `/details?id=${key}`;
74
+ }}
75
+ />
76
+ ```
77
+
78
+ ### Sorting Config
79
+
80
+ The `sortConfig` prop accepts predefined algorithms or custom functions:
81
+
82
+ ```typescript
83
+ // Sort by Volatility (Standard Deviation)
84
+ sortConfig={{ type: 'deviation', direction: 'desc' }}
85
+
86
+ // Sort by Custom Function (e.g., Max Value)
87
+ sortConfig={{
88
+ type: (data) => Math.max(...data.map(d => d.value)),
89
+ direction: 'desc'
90
+ }}
91
+ ```
92
+
93
+ ## 🏗 Development
94
+
95
+ The project supports a dual-build workflow:
96
+
97
+ 1. **Demo App** (Development):
98
+ ```bash
99
+ npm run dev
100
+ ```
101
+ Starts the interactive playground with mock data generation.
102
+
103
+ 2. **Library Build** (Distribution):
104
+ ```bash
105
+ npm run build:lib
106
+ ```
107
+ Compiles `src/index.ts` into a redistributable package (`dist/lib`).
108
+
109
+ ## ✅ Testing
110
+
111
+ Unit tests are written in **Vitest**.
112
+
113
+ ```bash
114
+ npm test
115
+ ```
116
+
117
+ Includes coverage for:
118
+ - Faceting logic
119
+ - Search debouncing
120
+ - Sorting algorithms (including custom functions)
121
+ - Shared scale calculation
122
+
123
+ ## 📄 License
124
+
125
+ MIT
@@ -0,0 +1,35 @@
1
+ import { default as React } from 'react';
2
+ import { MetricType } from './utils/analytics.js';
3
+ export declare function cn(...inputs: (string | undefined | null | false)[]): string;
4
+ export type SortConfig<T> = {
5
+ type: MetricType | ((data: T[]) => number);
6
+ direction: 'asc' | 'desc';
7
+ };
8
+ export type TrellisProps<T> = {
9
+ data: T[];
10
+ facetKey: keyof T | ((d: T) => string);
11
+ ChartComponent: React.ComponentType<{
12
+ data: T[];
13
+ width?: number;
14
+ height?: number;
15
+ yDomain?: [number, number];
16
+ }>;
17
+ valueKey?: keyof T | ((d: T) => number);
18
+ yDomain?: [number, number];
19
+ sharedScale?: boolean;
20
+ className?: string;
21
+ minChartWidth?: number;
22
+ height?: number;
23
+ SkeletonComponent?: React.ComponentType<{
24
+ height: number;
25
+ }>;
26
+ searchable?: boolean;
27
+ /** Controlled search query. If provided, Trellis filters based on this. */
28
+ query?: string;
29
+ /** Callback when search input changes. Required if query is provided. */
30
+ onSearchChange?: (query: string) => void;
31
+ /** Optional callback when a chart is clicked */
32
+ onChartClick?: (key: string, data: T[]) => void;
33
+ sortConfig?: SortConfig<T>;
34
+ };
35
+ export declare function Trellis<T>({ data, facetKey, ChartComponent, valueKey, yDomain: explicitYDomain, sharedScale, className, minChartWidth, height, SkeletonComponent, searchable, query, onSearchChange, onChartClick, sortConfig, }: TrellisProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ export type MetricType = 'sum' | 'deviation' | 'trend' | 'default';
2
+ /**
3
+ * Calculates the slope of the linear regression line (trend) for an array of numbers.
4
+ * Assumes equal spacing between data points (x = 0, 1, 2, ...).
5
+ */
6
+ export declare function calculateTrend(values: number[]): number;
7
+ export declare function calculateMetric<T>(data: T[], valueKey: keyof T | ((d: T) => number), type: MetricType): number;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A hook to sync state with a URL query parameter.
3
+ * @param key The query parameter key (e.g., 'search', 'sort').
4
+ * @param initialValue The default value if the param is missing.
5
+ * @returns [value, setValue] tuple.
6
+ */
7
+ export declare function useUrlState<T extends string | boolean>(key: string, initialValue: T): [T, (val: T) => void];
@@ -0,0 +1,3 @@
1
+ export { Trellis, type TrellisProps, type SortConfig } from './components/Trellis.js';
2
+ export { calculateMetric, type MetricType } from './components/utils/analytics.js';
3
+ export { useUrlState } from './hooks/useUrlState.js';
File without changes
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const z=require("react/jsx-runtime"),P=require("react");function Ve(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const o in e)if(o!=="default"){const r=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,r.get?r:{enumerable:!0,get:()=>e[o]})}}return t.default=e,Object.freeze(t)}const D=Ve(P);function We(e,t){let o=0,r,s=0,a=0;for(let n of e)n!=null&&(n=+n)>=n&&(r=n-s,s+=r/++o,a+=r*(n-s));if(o>1)return a/(o-1)}function De(e,t){const o=We(e);return o&&Math.sqrt(o)}class qe extends Map{constructor(t,o=Ye){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:o}}),t!=null)for(const[r,s]of t)this.set(r,s)}get(t){return super.get(we(this,t))}has(t){return super.has(we(this,t))}set(t,o){return super.set(Qe(this,t),o)}delete(t){return super.delete(Xe(this,t))}}function we({_intern:e,_key:t},o){const r=t(o);return e.has(r)?e.get(r):o}function Qe({_intern:e,_key:t},o){const r=t(o);return e.has(r)?e.get(r):(e.set(r,o),o)}function Xe({_intern:e,_key:t},o){const r=t(o);return e.has(r)&&(o=e.get(r),e.delete(r)),o}function Ye(e){return e!==null&&typeof e=="object"?e.valueOf():e}function xe(e){return e}function Ze(e,...t){return Je(e,xe,xe,t)}function Je(e,t,o,r){return(function s(a,n){if(n>=r.length)return o(a);const i=new qe,l=r[n++];let m=-1;for(const g of a){const h=l(g,++m,a),y=i.get(h);y?y.push(g):i.set(h,[g])}for(const[g,h]of i)i.set(g,s(h,n));return t(i)})(e,0)}function He(e,t){let o=0,r=0;for(let s of e)s!=null&&(s=+s)>=s&&(++o,r+=s);if(o)return r/o}function Ke(e,t){let o=0;for(let r of e)(r=+r)&&(o+=r);return o}function Re(e){var t,o,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(o=Re(e[t]))&&(r&&(r+=" "),r+=o)}else for(o in e)e[o]&&(r&&(r+=" "),r+=o);return r}function et(){for(var e,t,o=0,r="",s=arguments.length;o<s;o++)(e=arguments[o])&&(t=Re(e))&&(r&&(r+=" "),r+=t);return r}const tt=(e,t)=>{const o=new Array(e.length+t.length);for(let r=0;r<e.length;r++)o[r]=e[r];for(let r=0;r<t.length;r++)o[e.length+r]=t[r];return o},rt=(e,t)=>({classGroupId:e,validator:t}),je=(e=new Map,t=null,o)=>({nextPart:e,validators:t,classGroupId:o}),oe="-",ye=[],ot="arbitrary..",nt=e=>{const t=at(e),{conflictingClassGroups:o,conflictingClassGroupModifiers:r}=e;return{getClassGroupId:n=>{if(n.startsWith("[")&&n.endsWith("]"))return st(n);const i=n.split(oe),l=i[0]===""&&i.length>1?1:0;return Me(i,l,t)},getConflictingClassGroupIds:(n,i)=>{if(i){const l=r[n],m=o[n];return l?m?tt(m,l):l:m||ye}return o[n]||ye}}},Me=(e,t,o)=>{if(e.length-t===0)return o.classGroupId;const s=e[t],a=o.nextPart.get(s);if(a){const m=Me(e,t+1,a);if(m)return m}const n=o.validators;if(n===null)return;const i=t===0?e.join(oe):e.slice(t).join(oe),l=n.length;for(let m=0;m<l;m++){const g=n[m];if(g.validator(i))return g.classGroupId}},st=e=>e.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const t=e.slice(1,-1),o=t.indexOf(":"),r=t.slice(0,o);return r?ot+r:void 0})(),at=e=>{const{theme:t,classGroups:o}=e;return it(o,t)},it=(e,t)=>{const o=je();for(const r in e){const s=e[r];ue(s,o,r,t)}return o},ue=(e,t,o,r)=>{const s=e.length;for(let a=0;a<s;a++){const n=e[a];lt(n,t,o,r)}},lt=(e,t,o,r)=>{if(typeof e=="string"){ct(e,t,o);return}if(typeof e=="function"){dt(e,t,o,r);return}ut(e,t,o,r)},ct=(e,t,o)=>{const r=e===""?t:Ie(t,e);r.classGroupId=o},dt=(e,t,o,r)=>{if(mt(e)){ue(e(r),t,o,r);return}t.validators===null&&(t.validators=[]),t.validators.push(rt(o,e))},ut=(e,t,o,r)=>{const s=Object.entries(e),a=s.length;for(let n=0;n<a;n++){const[i,l]=s[n];ue(l,Ie(t,i),o,r)}},Ie=(e,t)=>{let o=e;const r=t.split(oe),s=r.length;for(let a=0;a<s;a++){const n=r[a];let i=o.nextPart.get(n);i||(i=je(),o.nextPart.set(n,i)),o=i}return o},mt=e=>"isThemeGetter"in e&&e.isThemeGetter===!0,ft=e=>{if(e<1)return{get:()=>{},set:()=>{}};let t=0,o=Object.create(null),r=Object.create(null);const s=(a,n)=>{o[a]=n,t++,t>e&&(t=0,r=o,o=Object.create(null))};return{get(a){let n=o[a];if(n!==void 0)return n;if((n=r[a])!==void 0)return s(a,n),n},set(a,n){a in o?o[a]=n:s(a,n)}}},ce="!",ve=":",pt=[],ke=(e,t,o,r,s)=>({modifiers:e,hasImportantModifier:t,baseClassName:o,maybePostfixModifierPosition:r,isExternal:s}),gt=e=>{const{prefix:t,experimentalParseClassName:o}=e;let r=s=>{const a=[];let n=0,i=0,l=0,m;const g=s.length;for(let C=0;C<g;C++){const v=s[C];if(n===0&&i===0){if(v===ve){a.push(s.slice(l,C)),l=C+1;continue}if(v==="/"){m=C;continue}}v==="["?n++:v==="]"?n--:v==="("?i++:v===")"&&i--}const h=a.length===0?s:s.slice(l);let y=h,O=!1;h.endsWith(ce)?(y=h.slice(0,-1),O=!0):h.startsWith(ce)&&(y=h.slice(1),O=!0);const w=m&&m>l?m-l:void 0;return ke(a,O,y,w)};if(t){const s=t+ve,a=r;r=n=>n.startsWith(s)?a(n.slice(s.length)):ke(pt,!1,n,void 0,!0)}if(o){const s=r;r=a=>o({className:a,parseClassName:s})}return r},bt=e=>{const t=new Map;return e.orderSensitiveModifiers.forEach((o,r)=>{t.set(o,1e6+r)}),o=>{const r=[];let s=[];for(let a=0;a<o.length;a++){const n=o[a],i=n[0]==="[",l=t.has(n);i||l?(s.length>0&&(s.sort(),r.push(...s),s=[]),r.push(n)):s.push(n)}return s.length>0&&(s.sort(),r.push(...s)),r}},ht=e=>({cache:ft(e.cacheSize),parseClassName:gt(e),sortModifiers:bt(e),...nt(e)}),wt=/\s+/,xt=(e,t)=>{const{parseClassName:o,getClassGroupId:r,getConflictingClassGroupIds:s,sortModifiers:a}=t,n=[],i=e.trim().split(wt);let l="";for(let m=i.length-1;m>=0;m-=1){const g=i[m],{isExternal:h,modifiers:y,hasImportantModifier:O,baseClassName:w,maybePostfixModifierPosition:C}=o(g);if(h){l=g+(l.length>0?" "+l:l);continue}let v=!!C,T=r(v?w.substring(0,C):w);if(!T){if(!v){l=g+(l.length>0?" "+l:l);continue}if(T=r(w),!T){l=g+(l.length>0?" "+l:l);continue}v=!1}const L=y.length===0?"":y.length===1?y[0]:a(y).join(":"),R=O?L+ce:L,S=R+T;if(n.indexOf(S)>-1)continue;n.push(S);const A=s(T,v);for(let j=0;j<A.length;++j){const G=A[j];n.push(R+G)}l=g+(l.length>0?" "+l:l)}return l},yt=(...e)=>{let t=0,o,r,s="";for(;t<e.length;)(o=e[t++])&&(r=Pe(o))&&(s&&(s+=" "),s+=r);return s},Pe=e=>{if(typeof e=="string")return e;let t,o="";for(let r=0;r<e.length;r++)e[r]&&(t=Pe(e[r]))&&(o&&(o+=" "),o+=t);return o},vt=(e,...t)=>{let o,r,s,a;const n=l=>{const m=t.reduce((g,h)=>h(g),e());return o=ht(m),r=o.cache.get,s=o.cache.set,a=i,i(l)},i=l=>{const m=r(l);if(m)return m;const g=xt(l,o);return s(l,g),g};return a=n,(...l)=>a(yt(...l))},kt=[],x=e=>{const t=o=>o[e]||kt;return t.isThemeGetter=!0,t},Te=/^\[(?:(\w[\w-]*):)?(.+)\]$/i,Ne=/^\((?:(\w[\w-]*):)?(.+)\)$/i,Ct=/^\d+\/\d+$/,St=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,zt=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,At=/^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/,Rt=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,jt=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,q=e=>Ct.test(e),p=e=>!!e&&!Number.isNaN(Number(e)),F=e=>!!e&&Number.isInteger(Number(e)),ie=e=>e.endsWith("%")&&p(e.slice(0,-1)),$=e=>St.test(e),Mt=()=>!0,It=e=>zt.test(e)&&!At.test(e),Oe=()=>!1,Pt=e=>Rt.test(e),Tt=e=>jt.test(e),Nt=e=>!c(e)&&!d(e),Ot=e=>Q(e,Ge,Oe),c=e=>Te.test(e),V=e=>Q(e,_e,It),le=e=>Q(e,$t,p),Ce=e=>Q(e,Ee,Oe),Et=e=>Q(e,Le,Tt),ee=e=>Q(e,$e,Pt),d=e=>Ne.test(e),Y=e=>X(e,_e),Lt=e=>X(e,Bt),Se=e=>X(e,Ee),Gt=e=>X(e,Ge),_t=e=>X(e,Le),te=e=>X(e,$e,!0),Q=(e,t,o)=>{const r=Te.exec(e);return r?r[1]?t(r[1]):o(r[2]):!1},X=(e,t,o=!1)=>{const r=Ne.exec(e);return r?r[1]?t(r[1]):o:!1},Ee=e=>e==="position"||e==="percentage",Le=e=>e==="image"||e==="url",Ge=e=>e==="length"||e==="size"||e==="bg-size",_e=e=>e==="length",$t=e=>e==="number",Bt=e=>e==="family-name",$e=e=>e==="shadow",Ft=()=>{const e=x("color"),t=x("font"),o=x("text"),r=x("font-weight"),s=x("tracking"),a=x("leading"),n=x("breakpoint"),i=x("container"),l=x("spacing"),m=x("radius"),g=x("shadow"),h=x("inset-shadow"),y=x("text-shadow"),O=x("drop-shadow"),w=x("blur"),C=x("perspective"),v=x("aspect"),T=x("ease"),L=x("animate"),R=()=>["auto","avoid","all","avoid-page","page","left","right","column"],S=()=>["center","top","bottom","left","right","top-left","left-top","top-right","right-top","bottom-right","right-bottom","bottom-left","left-bottom"],A=()=>[...S(),d,c],j=()=>["auto","hidden","clip","visible","scroll"],G=()=>["auto","contain","none"],u=()=>[d,c,l],b=()=>[q,"full","auto",...u()],M=()=>[F,"none","subgrid",d,c],N=()=>["auto",{span:["full",F,d,c]},F,d,c],B=()=>[F,"auto",d,c],me=()=>["auto","min","max","fr",d,c],ne=()=>["start","end","center","between","around","evenly","stretch","baseline","center-safe","end-safe"],W=()=>["start","end","center","stretch","center-safe","end-safe"],_=()=>["auto",...u()],U=()=>[q,"auto","full","dvw","dvh","lvw","lvh","svw","svh","min","max","fit",...u()],f=()=>[e,d,c],fe=()=>[...S(),Se,Ce,{position:[d,c]}],pe=()=>["no-repeat",{repeat:["","x","y","space","round"]}],ge=()=>["auto","cover","contain",Gt,Ot,{size:[d,c]}],se=()=>[ie,Y,V],I=()=>["","none","full",m,d,c],E=()=>["",p,Y,V],Z=()=>["solid","dashed","dotted","double"],be=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],k=()=>[p,ie,Se,Ce],he=()=>["","none",w,d,c],J=()=>["none",p,d,c],H=()=>["none",p,d,c],ae=()=>[p,d,c],K=()=>[q,"full",...u()];return{cacheSize:500,theme:{animate:["spin","ping","pulse","bounce"],aspect:["video"],blur:[$],breakpoint:[$],color:[Mt],container:[$],"drop-shadow":[$],ease:["in","out","in-out"],font:[Nt],"font-weight":["thin","extralight","light","normal","medium","semibold","bold","extrabold","black"],"inset-shadow":[$],leading:["none","tight","snug","normal","relaxed","loose"],perspective:["dramatic","near","normal","midrange","distant","none"],radius:[$],shadow:[$],spacing:["px",p],text:[$],"text-shadow":[$],tracking:["tighter","tight","normal","wide","wider","widest"]},classGroups:{aspect:[{aspect:["auto","square",q,c,d,v]}],container:["container"],columns:[{columns:[p,c,d,i]}],"break-after":[{"break-after":R()}],"break-before":[{"break-before":R()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],sr:["sr-only","not-sr-only"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:A()}],overflow:[{overflow:j()}],"overflow-x":[{"overflow-x":j()}],"overflow-y":[{"overflow-y":j()}],overscroll:[{overscroll:G()}],"overscroll-x":[{"overscroll-x":G()}],"overscroll-y":[{"overscroll-y":G()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:b()}],"inset-x":[{"inset-x":b()}],"inset-y":[{"inset-y":b()}],start:[{start:b()}],end:[{end:b()}],top:[{top:b()}],right:[{right:b()}],bottom:[{bottom:b()}],left:[{left:b()}],visibility:["visible","invisible","collapse"],z:[{z:[F,"auto",d,c]}],basis:[{basis:[q,"full","auto",i,...u()]}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["nowrap","wrap","wrap-reverse"]}],flex:[{flex:[p,q,"auto","initial","none",c]}],grow:[{grow:["",p,d,c]}],shrink:[{shrink:["",p,d,c]}],order:[{order:[F,"first","last","none",d,c]}],"grid-cols":[{"grid-cols":M()}],"col-start-end":[{col:N()}],"col-start":[{"col-start":B()}],"col-end":[{"col-end":B()}],"grid-rows":[{"grid-rows":M()}],"row-start-end":[{row:N()}],"row-start":[{"row-start":B()}],"row-end":[{"row-end":B()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":me()}],"auto-rows":[{"auto-rows":me()}],gap:[{gap:u()}],"gap-x":[{"gap-x":u()}],"gap-y":[{"gap-y":u()}],"justify-content":[{justify:[...ne(),"normal"]}],"justify-items":[{"justify-items":[...W(),"normal"]}],"justify-self":[{"justify-self":["auto",...W()]}],"align-content":[{content:["normal",...ne()]}],"align-items":[{items:[...W(),{baseline:["","last"]}]}],"align-self":[{self:["auto",...W(),{baseline:["","last"]}]}],"place-content":[{"place-content":ne()}],"place-items":[{"place-items":[...W(),"baseline"]}],"place-self":[{"place-self":["auto",...W()]}],p:[{p:u()}],px:[{px:u()}],py:[{py:u()}],ps:[{ps:u()}],pe:[{pe:u()}],pt:[{pt:u()}],pr:[{pr:u()}],pb:[{pb:u()}],pl:[{pl:u()}],m:[{m:_()}],mx:[{mx:_()}],my:[{my:_()}],ms:[{ms:_()}],me:[{me:_()}],mt:[{mt:_()}],mr:[{mr:_()}],mb:[{mb:_()}],ml:[{ml:_()}],"space-x":[{"space-x":u()}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":u()}],"space-y-reverse":["space-y-reverse"],size:[{size:U()}],w:[{w:[i,"screen",...U()]}],"min-w":[{"min-w":[i,"screen","none",...U()]}],"max-w":[{"max-w":[i,"screen","none","prose",{screen:[n]},...U()]}],h:[{h:["screen","lh",...U()]}],"min-h":[{"min-h":["screen","lh","none",...U()]}],"max-h":[{"max-h":["screen","lh",...U()]}],"font-size":[{text:["base",o,Y,V]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:[r,d,le]}],"font-stretch":[{"font-stretch":["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded",ie,c]}],"font-family":[{font:[Lt,c,t]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:[s,d,c]}],"line-clamp":[{"line-clamp":[p,"none",d,le]}],leading:[{leading:[a,...u()]}],"list-image":[{"list-image":["none",d,c]}],"list-style-position":[{list:["inside","outside"]}],"list-style-type":[{list:["disc","decimal","none",d,c]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"placeholder-color":[{placeholder:f()}],"text-color":[{text:f()}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...Z(),"wavy"]}],"text-decoration-thickness":[{decoration:[p,"from-font","auto",d,V]}],"text-decoration-color":[{decoration:f()}],"underline-offset":[{"underline-offset":[p,"auto",d,c]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:u()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",d,c]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],wrap:[{wrap:["break-word","anywhere","normal"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",d,c]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:fe()}],"bg-repeat":[{bg:pe()}],"bg-size":[{bg:ge()}],"bg-image":[{bg:["none",{linear:[{to:["t","tr","r","br","b","bl","l","tl"]},F,d,c],radial:["",d,c],conic:[F,d,c]},_t,Et]}],"bg-color":[{bg:f()}],"gradient-from-pos":[{from:se()}],"gradient-via-pos":[{via:se()}],"gradient-to-pos":[{to:se()}],"gradient-from":[{from:f()}],"gradient-via":[{via:f()}],"gradient-to":[{to:f()}],rounded:[{rounded:I()}],"rounded-s":[{"rounded-s":I()}],"rounded-e":[{"rounded-e":I()}],"rounded-t":[{"rounded-t":I()}],"rounded-r":[{"rounded-r":I()}],"rounded-b":[{"rounded-b":I()}],"rounded-l":[{"rounded-l":I()}],"rounded-ss":[{"rounded-ss":I()}],"rounded-se":[{"rounded-se":I()}],"rounded-ee":[{"rounded-ee":I()}],"rounded-es":[{"rounded-es":I()}],"rounded-tl":[{"rounded-tl":I()}],"rounded-tr":[{"rounded-tr":I()}],"rounded-br":[{"rounded-br":I()}],"rounded-bl":[{"rounded-bl":I()}],"border-w":[{border:E()}],"border-w-x":[{"border-x":E()}],"border-w-y":[{"border-y":E()}],"border-w-s":[{"border-s":E()}],"border-w-e":[{"border-e":E()}],"border-w-t":[{"border-t":E()}],"border-w-r":[{"border-r":E()}],"border-w-b":[{"border-b":E()}],"border-w-l":[{"border-l":E()}],"divide-x":[{"divide-x":E()}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":E()}],"divide-y-reverse":["divide-y-reverse"],"border-style":[{border:[...Z(),"hidden","none"]}],"divide-style":[{divide:[...Z(),"hidden","none"]}],"border-color":[{border:f()}],"border-color-x":[{"border-x":f()}],"border-color-y":[{"border-y":f()}],"border-color-s":[{"border-s":f()}],"border-color-e":[{"border-e":f()}],"border-color-t":[{"border-t":f()}],"border-color-r":[{"border-r":f()}],"border-color-b":[{"border-b":f()}],"border-color-l":[{"border-l":f()}],"divide-color":[{divide:f()}],"outline-style":[{outline:[...Z(),"none","hidden"]}],"outline-offset":[{"outline-offset":[p,d,c]}],"outline-w":[{outline:["",p,Y,V]}],"outline-color":[{outline:f()}],shadow:[{shadow:["","none",g,te,ee]}],"shadow-color":[{shadow:f()}],"inset-shadow":[{"inset-shadow":["none",h,te,ee]}],"inset-shadow-color":[{"inset-shadow":f()}],"ring-w":[{ring:E()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:f()}],"ring-offset-w":[{"ring-offset":[p,V]}],"ring-offset-color":[{"ring-offset":f()}],"inset-ring-w":[{"inset-ring":E()}],"inset-ring-color":[{"inset-ring":f()}],"text-shadow":[{"text-shadow":["none",y,te,ee]}],"text-shadow-color":[{"text-shadow":f()}],opacity:[{opacity:[p,d,c]}],"mix-blend":[{"mix-blend":[...be(),"plus-darker","plus-lighter"]}],"bg-blend":[{"bg-blend":be()}],"mask-clip":[{"mask-clip":["border","padding","content","fill","stroke","view"]},"mask-no-clip"],"mask-composite":[{mask:["add","subtract","intersect","exclude"]}],"mask-image-linear-pos":[{"mask-linear":[p]}],"mask-image-linear-from-pos":[{"mask-linear-from":k()}],"mask-image-linear-to-pos":[{"mask-linear-to":k()}],"mask-image-linear-from-color":[{"mask-linear-from":f()}],"mask-image-linear-to-color":[{"mask-linear-to":f()}],"mask-image-t-from-pos":[{"mask-t-from":k()}],"mask-image-t-to-pos":[{"mask-t-to":k()}],"mask-image-t-from-color":[{"mask-t-from":f()}],"mask-image-t-to-color":[{"mask-t-to":f()}],"mask-image-r-from-pos":[{"mask-r-from":k()}],"mask-image-r-to-pos":[{"mask-r-to":k()}],"mask-image-r-from-color":[{"mask-r-from":f()}],"mask-image-r-to-color":[{"mask-r-to":f()}],"mask-image-b-from-pos":[{"mask-b-from":k()}],"mask-image-b-to-pos":[{"mask-b-to":k()}],"mask-image-b-from-color":[{"mask-b-from":f()}],"mask-image-b-to-color":[{"mask-b-to":f()}],"mask-image-l-from-pos":[{"mask-l-from":k()}],"mask-image-l-to-pos":[{"mask-l-to":k()}],"mask-image-l-from-color":[{"mask-l-from":f()}],"mask-image-l-to-color":[{"mask-l-to":f()}],"mask-image-x-from-pos":[{"mask-x-from":k()}],"mask-image-x-to-pos":[{"mask-x-to":k()}],"mask-image-x-from-color":[{"mask-x-from":f()}],"mask-image-x-to-color":[{"mask-x-to":f()}],"mask-image-y-from-pos":[{"mask-y-from":k()}],"mask-image-y-to-pos":[{"mask-y-to":k()}],"mask-image-y-from-color":[{"mask-y-from":f()}],"mask-image-y-to-color":[{"mask-y-to":f()}],"mask-image-radial":[{"mask-radial":[d,c]}],"mask-image-radial-from-pos":[{"mask-radial-from":k()}],"mask-image-radial-to-pos":[{"mask-radial-to":k()}],"mask-image-radial-from-color":[{"mask-radial-from":f()}],"mask-image-radial-to-color":[{"mask-radial-to":f()}],"mask-image-radial-shape":[{"mask-radial":["circle","ellipse"]}],"mask-image-radial-size":[{"mask-radial":[{closest:["side","corner"],farthest:["side","corner"]}]}],"mask-image-radial-pos":[{"mask-radial-at":S()}],"mask-image-conic-pos":[{"mask-conic":[p]}],"mask-image-conic-from-pos":[{"mask-conic-from":k()}],"mask-image-conic-to-pos":[{"mask-conic-to":k()}],"mask-image-conic-from-color":[{"mask-conic-from":f()}],"mask-image-conic-to-color":[{"mask-conic-to":f()}],"mask-mode":[{mask:["alpha","luminance","match"]}],"mask-origin":[{"mask-origin":["border","padding","content","fill","stroke","view"]}],"mask-position":[{mask:fe()}],"mask-repeat":[{mask:pe()}],"mask-size":[{mask:ge()}],"mask-type":[{"mask-type":["alpha","luminance"]}],"mask-image":[{mask:["none",d,c]}],filter:[{filter:["","none",d,c]}],blur:[{blur:he()}],brightness:[{brightness:[p,d,c]}],contrast:[{contrast:[p,d,c]}],"drop-shadow":[{"drop-shadow":["","none",O,te,ee]}],"drop-shadow-color":[{"drop-shadow":f()}],grayscale:[{grayscale:["",p,d,c]}],"hue-rotate":[{"hue-rotate":[p,d,c]}],invert:[{invert:["",p,d,c]}],saturate:[{saturate:[p,d,c]}],sepia:[{sepia:["",p,d,c]}],"backdrop-filter":[{"backdrop-filter":["","none",d,c]}],"backdrop-blur":[{"backdrop-blur":he()}],"backdrop-brightness":[{"backdrop-brightness":[p,d,c]}],"backdrop-contrast":[{"backdrop-contrast":[p,d,c]}],"backdrop-grayscale":[{"backdrop-grayscale":["",p,d,c]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[p,d,c]}],"backdrop-invert":[{"backdrop-invert":["",p,d,c]}],"backdrop-opacity":[{"backdrop-opacity":[p,d,c]}],"backdrop-saturate":[{"backdrop-saturate":[p,d,c]}],"backdrop-sepia":[{"backdrop-sepia":["",p,d,c]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":u()}],"border-spacing-x":[{"border-spacing-x":u()}],"border-spacing-y":[{"border-spacing-y":u()}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["","all","colors","opacity","shadow","transform","none",d,c]}],"transition-behavior":[{transition:["normal","discrete"]}],duration:[{duration:[p,"initial",d,c]}],ease:[{ease:["linear","initial",T,d,c]}],delay:[{delay:[p,d,c]}],animate:[{animate:["none",L,d,c]}],backface:[{backface:["hidden","visible"]}],perspective:[{perspective:[C,d,c]}],"perspective-origin":[{"perspective-origin":A()}],rotate:[{rotate:J()}],"rotate-x":[{"rotate-x":J()}],"rotate-y":[{"rotate-y":J()}],"rotate-z":[{"rotate-z":J()}],scale:[{scale:H()}],"scale-x":[{"scale-x":H()}],"scale-y":[{"scale-y":H()}],"scale-z":[{"scale-z":H()}],"scale-3d":["scale-3d"],skew:[{skew:ae()}],"skew-x":[{"skew-x":ae()}],"skew-y":[{"skew-y":ae()}],transform:[{transform:[d,c,"","none","gpu","cpu"]}],"transform-origin":[{origin:A()}],"transform-style":[{transform:["3d","flat"]}],translate:[{translate:K()}],"translate-x":[{"translate-x":K()}],"translate-y":[{"translate-y":K()}],"translate-z":[{"translate-z":K()}],"translate-none":["translate-none"],accent:[{accent:f()}],appearance:[{appearance:["none","auto"]}],"caret-color":[{caret:f()}],"color-scheme":[{scheme:["normal","dark","light","light-dark","only-dark","only-light"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",d,c]}],"field-sizing":[{"field-sizing":["fixed","content"]}],"pointer-events":[{"pointer-events":["auto","none"]}],resize:[{resize:["none","","y","x"]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":u()}],"scroll-mx":[{"scroll-mx":u()}],"scroll-my":[{"scroll-my":u()}],"scroll-ms":[{"scroll-ms":u()}],"scroll-me":[{"scroll-me":u()}],"scroll-mt":[{"scroll-mt":u()}],"scroll-mr":[{"scroll-mr":u()}],"scroll-mb":[{"scroll-mb":u()}],"scroll-ml":[{"scroll-ml":u()}],"scroll-p":[{"scroll-p":u()}],"scroll-px":[{"scroll-px":u()}],"scroll-py":[{"scroll-py":u()}],"scroll-ps":[{"scroll-ps":u()}],"scroll-pe":[{"scroll-pe":u()}],"scroll-pt":[{"scroll-pt":u()}],"scroll-pr":[{"scroll-pr":u()}],"scroll-pb":[{"scroll-pb":u()}],"scroll-pl":[{"scroll-pl":u()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",d,c]}],fill:[{fill:["none",...f()]}],"stroke-w":[{stroke:[p,Y,V,le]}],stroke:[{stroke:["none",...f()]}],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-x","border-w-y","border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-x","border-color-y","border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],translate:["translate-x","translate-y","translate-none"],"translate-none":["translate","translate-x","translate-y","translate-z"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]},orderSensitiveModifiers:["*","**","after","backdrop","before","details-content","file","first-letter","first-line","marker","placeholder","selection"]}},Ut=vt(Ft);var de=new Map,re=new WeakMap,ze=0,Vt;function Wt(e){return e?(re.has(e)||(ze+=1,re.set(e,ze.toString())),re.get(e)):"0"}function Dt(e){return Object.keys(e).sort().filter(t=>e[t]!==void 0).map(t=>`${t}_${t==="root"?Wt(e.root):e[t]}`).toString()}function qt(e){const t=Dt(e);let o=de.get(t);if(!o){const r=new Map;let s;const a=new IntersectionObserver(n=>{n.forEach(i=>{var l;const m=i.isIntersecting&&s.some(g=>i.intersectionRatio>=g);e.trackVisibility&&typeof i.isVisible>"u"&&(i.isVisible=m),(l=r.get(i.target))==null||l.forEach(g=>{g(m,i)})})},e);s=a.thresholds||(Array.isArray(e.threshold)?e.threshold:[e.threshold||0]),o={id:t,observer:a,elements:r},de.set(t,o)}return o}function Qt(e,t,o={},r=Vt){if(typeof window.IntersectionObserver>"u"&&r!==void 0){const l=e.getBoundingClientRect();return t(r,{isIntersecting:r,target:e,intersectionRatio:typeof o.threshold=="number"?o.threshold:0,time:0,boundingClientRect:l,intersectionRect:l,rootBounds:l}),()=>{}}const{id:s,observer:a,elements:n}=qt(o),i=n.get(e)||[];return n.has(e)||n.set(e,i),i.push(t),a.observe(e),function(){i.splice(i.indexOf(t),1),i.length===0&&(n.delete(e),a.unobserve(e)),n.size===0&&(a.disconnect(),de.delete(s))}}function Xt({threshold:e,delay:t,trackVisibility:o,rootMargin:r,root:s,triggerOnce:a,skip:n,initialInView:i,fallbackInView:l,onChange:m}={}){var g;const[h,y]=D.useState(null),O=D.useRef(m),w=D.useRef(i),[C,v]=D.useState({inView:!!i,entry:void 0});O.current=m,D.useEffect(()=>{if(w.current===void 0&&(w.current=i),n||!h)return;let S;return S=Qt(h,(A,j)=>{const G=w.current;w.current=A,!(G===void 0&&!A)&&(v({inView:A,entry:j}),O.current&&O.current(A,j),j.isIntersecting&&a&&S&&(S(),S=void 0))},{root:s,rootMargin:r,threshold:e,trackVisibility:o,delay:t},l),()=>{S&&S()}},[Array.isArray(e)?e.toString():e,h,s,r,a,n,o,l,t]);const T=(g=C.entry)==null?void 0:g.target,L=D.useRef(void 0);!h&&T&&!a&&!n&&L.current!==T&&(L.current=T,v({inView:!!i,entry:void 0}),w.current=i);const R=[y,C.inView,C.entry];return R.ref=R[0],R.inView=R[1],R.entry=R[2],R}const Yt=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Zt=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,o,r)=>r?r.toUpperCase():o.toLowerCase()),Ae=e=>{const t=Zt(e);return t.charAt(0).toUpperCase()+t.slice(1)},Be=(...e)=>e.filter((t,o,r)=>!!t&&t.trim()!==""&&r.indexOf(t)===o).join(" ").trim(),Jt=e=>{for(const t in e)if(t.startsWith("aria-")||t==="role"||t==="title")return!0};var Ht={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const Kt=P.forwardRef(({color:e="currentColor",size:t=24,strokeWidth:o=2,absoluteStrokeWidth:r,className:s="",children:a,iconNode:n,...i},l)=>P.createElement("svg",{ref:l,...Ht,width:t,height:t,stroke:e,strokeWidth:r?Number(o)*24/Number(t):o,className:Be("lucide",s),...!a&&!Jt(i)&&{"aria-hidden":"true"},...i},[...n.map(([m,g])=>P.createElement(m,g)),...Array.isArray(a)?a:[a]]));const er=(e,t)=>{const o=P.forwardRef(({className:r,...s},a)=>P.createElement(Kt,{ref:a,iconNode:t,className:Be(`lucide-${Yt(Ae(e))}`,`lucide-${e}`,r),...s}));return o.displayName=Ae(e),o};const tr=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],rr=er("search",tr);function or(e){const t=e.length;if(t<2)return 0;const o=(t-1)/2,r=He(e)??0;let s=0,a=0;for(let n=0;n<t;n++){const i=n,l=e[n],m=i-o;s+=m*(l-r),a+=m*m}return a===0?0:s/a}function Fe(e,t,o){if(o==="default")return 0;const r=e.map(s=>typeof t=="function"?t(s):Number(s[t]));switch(o){case"sum":return Ke(r);case"deviation":return De(r)??0;case"trend":return or(r);default:return 0}}function Ue(...e){return Ut(et(e))}function nr(e,t){const[o,r]=P.useState(e);return P.useEffect(()=>{const s=setTimeout(()=>{r(e)},t);return()=>{clearTimeout(s)}},[e,t]),o}const sr=({height:e})=>z.jsx("div",{className:"w-full animate-pulse bg-canvas-subtle rounded-md overflow-hidden",style:{height:e},children:z.jsx("div",{className:"h-full w-full bg-gradient-to-r from-transparent via-canvas-border/50 to-transparent -translate-x-full animate-[shimmer_1.5s_infinite]"})}),ar=({facetKey:e,data:t,ChartComponent:o,SkeletonComponent:r=sr,height:s,yDomain:a,onClick:n})=>{const{ref:i,inView:l}=Xt({triggerOnce:!0,rootMargin:"200px 0px"}),m=!!n;return z.jsxs("div",{ref:i,onClick:()=>m&&n(e,t),onKeyDown:g=>{m&&(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),n(e,t))},role:m?"button":void 0,tabIndex:m?0:void 0,className:Ue("flex flex-col border border-canvas-border rounded-lg p-4 bg-canvas-subtle/30 transition-all duration-300",m&&"cursor-pointer hover:border-indigo-400 hover:ring-2 hover:ring-indigo-100 hover:shadow-md active:scale-[0.99]"),style:{opacity:l?1:.6},children:[z.jsxs("div",{className:"flex items-center justify-between mb-4",children:[z.jsx("h3",{className:"text-sm font-medium text-canvas-fg/70 truncate",title:e,children:e}),m&&z.jsx("div",{className:"text-xs text-indigo-400/0 group-hover:text-indigo-500/100 transition-opacity",children:"↗"})]}),z.jsx("div",{style:{height:s,position:"relative"},children:l?z.jsx(o,{data:t,width:void 0,height:s,yDomain:a}):z.jsx(r,{height:s})})]})};function ir({data:e,facetKey:t,ChartComponent:o,valueKey:r,yDomain:s,sharedScale:a=!0,className:n,minChartWidth:i=300,height:l=200,SkeletonComponent:m,searchable:g,query:h,onSearchChange:y,onChartClick:O,sortConfig:w={type:"default",direction:"asc"}}){const[C,v]=P.useState(""),T=h!==void 0,L=T?h:C,R=u=>{const b=u.target.value;T&&y?y(b):v(b)},S=nr(L,300),A=P.useMemo(()=>Array.from(Ze(e,u=>typeof t=="function"?t(u):String(u[t]))),[e,t]),j=P.useMemo(()=>{let u=A;if(S&&(u=A.filter(([b])=>b.toLowerCase().includes(S.toLowerCase()))),w.type!=="default"){const b=u.map(([M,N])=>{let B=0;return typeof w.type=="function"?B=w.type(N):r&&typeof w.type=="string"&&(B=Fe(N,r,w.type)),{key:M,subset:N,metric:B}});return b.sort((M,N)=>w.direction==="asc"?M.metric-N.metric:N.metric-M.metric),b.map(M=>[M.key,M.subset])}return u.sort((b,M)=>b[0].localeCompare(M[0]))},[A,S,w,r]),G=P.useMemo(()=>{if(!a&&!s)return;if(s)return s;if(!r)return;let u=1/0,b=-1/0;return e.forEach(M=>{const N=typeof r=="function"?r(M):Number(M[r]);N<u&&(u=N),N>b&&(b=N)}),u>0&&(u=0),[u,b]},[e,a,s,r]);return z.jsxs("div",{className:Ue("w-full space-y-4",n),children:[g&&z.jsxs("div",{className:"relative max-w-sm",children:[z.jsx(rr,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-canvas-fg/40"}),z.jsx("input",{type:"text",placeholder:"Search charts...",value:L,onChange:R,className:"w-full pl-9 pr-4 py-2 text-sm border border-canvas-border rounded-md bg-canvas-bg focus:ring-2 focus:ring-indigo-500 outline-none transition-all"}),z.jsxs("div",{className:"absolute right-3 top-1/2 -translate-y-1/2 text-xs text-canvas-fg/40 font-mono",children:[j.length," / ",A.length]})]}),j.length===0?z.jsx("div",{className:"p-8 text-center border border-dashed border-canvas-border rounded-lg text-canvas-fg/50",children:"No charts match your filter."}):z.jsx("div",{className:"grid gap-4 w-full",style:{gridTemplateColumns:`repeat(auto-fill, minmax(${i}px, 1fr))`},children:j.map(([u,b])=>z.jsx(ar,{facetKey:u,data:b,ChartComponent:o,SkeletonComponent:m,height:l,yDomain:G,onClick:O},u))})]})}function lr(e,t){const[o,r]=P.useState(()=>{if(typeof window>"u")return t;const n=new URLSearchParams(window.location.search).get(e);return n===null?t:typeof t=="boolean"?n==="true":n}),s=P.useCallback(a=>{r(a);const n=new URLSearchParams(window.location.search);a===t||a===""?n.delete(e):n.set(e,String(a));const i=`${window.location.pathname}?${n.toString()}`;window.history.replaceState({},"",i)},[e,t]);return P.useEffect(()=>{const a=()=>{const i=new URLSearchParams(window.location.search).get(e);r(i===null?t:typeof t=="boolean"?i==="true":i)};return window.addEventListener("popstate",a),()=>window.removeEventListener("popstate",a)},[e,t]),[o,s]}exports.Trellis=ir;exports.calculateMetric=Fe;exports.useUrlState=lr;