@helix-x/datagrid-ui 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/values.ts","../src/core/useColumnState.ts","../src/core/useEditModel.ts","../src/types.ts","../src/core/useGridState.ts","../src/core/useSelectionModel.ts","../src/core/useServerDataSource.ts","../src/core/useVirtualRows.ts","../src/core/exporters.ts","../src/core/filterModel.ts","../src/components/ColumnsPanel.tsx","../src/components/SelectionCell.tsx","../src/components/FloatingFilterRow.tsx","../src/components/FilterPopover.tsx","../src/components/GridHeader.tsx","../src/components/GridOverlay.tsx","../src/components/GridPagination.tsx","../src/components/editors/BuiltinEditors.tsx","../src/components/editors/registry.ts","../src/components/GridCell.tsx","../src/components/GridRow.tsx","../src/components/DataGrid.tsx"],"names":["useMemo","useState","useCallback","useRef","useEffect","window","jsxs","jsx","Fragment","BUTTON_CLASS","value","memo","className","useLayoutEffect","useImperativeHandle"],"mappings":";;;;;;;;AAEA,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,iBAAA,GAAoB,EAAA;AAG1B,SAAS,QAAA,CAAS,KAAc,IAAA,EAAuB;AACrD,EAAA,IAAI,GAAA,IAAO,MAAM,OAAO,MAAA;AACxB,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG,OAAQ,IAAgC,IAAI,CAAA;AAErE,EAAA,IAAI,OAAA,GAAmB,GAAA;AACvB,EAAA,KAAA,MAAW,OAAA,IAAW,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,EAAG;AACrC,IAAA,IAAI,OAAA,IAAW,IAAA,IAAQ,OAAO,OAAA,KAAY,UAAU,OAAO,MAAA;AAC3D,IAAA,OAAA,GAAW,QAAoC,OAAO,CAAA;AAAA,EACxD;AACA,EAAA,OAAO,OAAA;AACT;AAUO,SAAS,YAAA,CAAgB,KAAQ,MAAA,EAAsC;AAC5E,EAAA,IAAI,MAAA,CAAO,WAAA,EAAa,OAAO,MAAA,CAAO,YAAY,GAAG,CAAA;AAErD,EAAA,MAAM,EAAE,OAAM,GAAI,MAAA;AAClB,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AAEnB,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,EAAK,KAAK,CAAA;AAClC,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,IAAA,GAAQ,MAAkC,KAAK,CAAA;AACrD,EAAA,IAAI,IAAA,KAAS,QAAW,OAAO,IAAA;AAE/B,EAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG;AAC7C,IAAA,MAAM,QAAQ,QAAA,CAAS,GAAA,EAAK,KAAK,CAAA,IAAM,MAAkC,KAAK,CAAA;AAC9E,IAAA,IAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAAA,EAClC;AAEA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,WAAA,CAAe,KAAA,EAAgB,GAAA,EAAQ,MAAA,EAAqC;AAC1F,EAAA,IAAI,OAAO,cAAA,EAAgB,OAAO,MAAA,CAAO,cAAA,CAAe,OAAO,GAAG,CAAA;AAClE,EAAA,IAAI,KAAA,IAAS,MAAM,OAAO,EAAA;AAC1B,EAAA,IAAI,KAAA,YAAiB,MAAM,OAAO,KAAA,CAAM,aAAY,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AACjE,EAAA,IAAI,OAAO,KAAA,KAAU,SAAA,EAAW,OAAO,QAAQ,KAAA,GAAQ,IAAA;AACvD,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAGO,SAAS,WAAA,CAAe,KAAQ,MAAA,EAAqC;AAC1E,EAAA,IAAI,MAAA,CAAO,WAAA,EAAa,OAAO,MAAA,CAAO,YAAY,GAAG,CAAA;AACrD,EAAA,OAAO,YAAY,YAAA,CAAa,GAAA,EAAK,MAAM,CAAA,EAAG,KAAK,MAAM,CAAA;AAC3D;AAGO,SAAS,WAAc,MAAA,EAAqC;AACjE,EAAA,IAAI,MAAA,CAAO,UAAA,EAAY,OAAO,MAAA,CAAO,UAAA;AACrC,EAAA,IAAI,OAAO,MAAA,CAAO,MAAA,KAAW,QAAA,SAAiB,MAAA,CAAO,MAAA;AACrD,EAAA,IAAI,OAAO,MAAA,CAAO,MAAA,KAAW,UAAU,OAAO,MAAA,CAAO,OAAO,MAAM,CAAA;AAClE,EAAA,OAAO,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,IAAS,EAAA;AACzC;AAEO,SAAS,SAAe,MAAA,EAAiC;AAC9D,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA;AAClC,EAAA,IAAI,CAAC,EAAA,EAAI;AACP,IAAA,MAAM,IAAI,MAAM,kEAAkE,CAAA;AAAA,EACpF;AACA,EAAA,OAAO,EAAA;AACT;AAGO,SAAS,cAAoB,MAAA,EAA+C;AACjF,EAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,iBAAA;AACpC,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,KAAA,EAAO,SAAS,MAAM,CAAA;AAAA,IACtB,OAAO,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,KAAA,IAAS,eAAe,QAAQ,CAAA;AAAA,IACvD,QAAA;AAAA,IACA,QAAA,EAAU,OAAO,QAAA,IAAY,IAAA;AAAA,IAC7B,SAAA,EAAW,OAAO,SAAA,IAAa;AAAA,GACjC;AACF;AAEO,SAAS,UAAA,CAAiB,QAAyB,GAAA,EAAiB;AACzE,EAAA,IAAI,OAAO,MAAA,CAAO,QAAA,KAAa,YAAY,OAAO,MAAA,CAAO,SAAS,GAAG,CAAA;AACrE,EAAA,OAAO,OAAO,QAAA,KAAa,IAAA;AAC7B;;;AC7DA,SAAS,aAAmB,OAAA,EAA8C;AACxE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,MAAM,SAAiC,EAAC;AAExC,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,EAAA,GAAK,SAAS,MAAM,CAAA;AAC1B,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,IAAI,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAC/B,IAAA,IAAI,OAAO,KAAA,IAAS,IAAA,EAAM,MAAA,CAAO,EAAE,IAAI,MAAA,CAAO,KAAA;AAC9C,IAAA,IAAI,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,EAAE,IAAI,MAAA,CAAO,MAAA;AAAA,EACzC;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAO;AACzC;AASA,SAAS,cAAA,CACP,QAAA,EACA,SAAA,EACA,QAAA,EACkB;AAClB,EAAA,IAAI,CAAC,WAAW,OAAO,QAAA;AAIvB,EAAA,MAAM,UAAA,GAAa,UAAU,KAAA,CAAM,MAAA,CAAO,CAAC,EAAA,KAAO,QAAA,CAAS,GAAA,CAAI,EAAE,CAAC,CAAA;AAClE,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,UAAU,CAAA;AACnC,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,UAAU,CAAA;AAC5B,EAAA,QAAA,CAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,EAAA,EAAI,KAAA,KAAU;AACpC,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,EAAE,GAAG,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,KAAA,CAAM,MAAM,CAAA,EAAG,GAAG,EAAE,CAAA;AAAA,EAC1E,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,MAAA,EAAA,CAAS,SAAA,CAAU,MAAA,IAAU,QAAA,CAAS,MAAA,EAAQ,MAAA,CAAO,CAAC,EAAA,KAAO,QAAA,CAAS,GAAA,CAAI,EAAE,CAAC,CAAA;AAAA,IAC7E,MAAA,EAAQ,EAAE,GAAG,QAAA,CAAS,QAAQ,GAAI,SAAA,CAAU,MAAA,IAAU,EAAC,EAAG;AAAA,IAC1D,MAAA,EAAQ,EAAE,GAAG,QAAA,CAAS,QAAQ,GAAI,SAAA,CAAU,MAAA,IAAU,EAAC;AAAG,GAC5D;AACF;AAEO,SAAS,cAAA,CACd,OAAA,EACA,SAAA,EACA,QAAA,EACA,cAAA,EAC4B;AAC5B,EAAA,MAAM,QAAA,GAAWA,aAAA,CAAQ,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,aAAA,CAAc,CAAC,CAAC,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAE9E,EAAA,MAAM,IAAA,GAAOA,cAAQ,MAAM;AACzB,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAkC;AAClD,IAAA,KAAA,MAAW,UAAU,QAAA,EAAU,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,OAAO,MAAM,CAAA;AAC3D,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,QAAA,GAAWA,cAAQ,MAAM,YAAA,CAAa,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAE/D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,cAAA;AAAA,IAA2B,MACnD,eAAe,QAAA,EAAU,SAAA,EAAW,IAAI,GAAA,CAAI,QAAA,CAAS,KAAK,CAAC;AAAA,GAC7D;AAEA,EAAA,MAAM,MAAA,GAASC,iBAAA;AAAA,IACb,CAAC,MAAA,KAA4D;AAC3D,MAAA,QAAA,CAAS,CAAC,OAAA,KAAY;AACpB,QAAA,MAAM,IAAA,GAAO,OAAO,OAAO,CAAA;AAC3B,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,OAAO,IAAA;AAAA,MACT,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,MAAM,SAAA,GAAYF,aAAA,CAAQ,MAAM,IAAI,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA,EAAG,CAAC,KAAA,CAAM,MAAM,CAAC,CAAA;AAErE,EAAA,MAAM,UAAA,GAAaA,aAAA;AAAA,IACjB,MACE,KAAA,CAAM,KAAA,CACH,GAAA,CAAI,CAAC,EAAA,KAAO,IAAA,CAAK,GAAA,CAAI,EAAE,CAAC,CAAA,CACxB,MAAA,CAAO,CAAC,CAAA,KAAiC,KAAK,IAAI,CAAA;AAAA,IACvD,CAAC,KAAA,CAAM,KAAA,EAAO,IAAI;AAAA,GACpB;AAEA,EAAA,MAAM,cAAA,GAAiBA,aAAA;AAAA,IACrB,MACE,UAAA,CACG,MAAA,CAAO,CAAC,MAAA,KAAW,CAAC,SAAA,CAAU,GAAA,CAAI,MAAA,CAAO,KAAK,CAAC,CAAA,CAC/C,GAAA;AAAA,MAAI,CAAC,MAAA,KACJ,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,IAAK,IAAA,IAAQ,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,KAAK,KAAK,IAAA,GAChE;AAAA,QACE,GAAG,MAAA;AAAA,QACH,OAAO,IAAA,CAAK,GAAA;AAAA,UACV,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,KAAK,KAAK,MAAA,CAAO,KAAA;AAAA,UACrC,MAAA,CAAO;AAAA,SACT;AAAA,QACA,QAAQ,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,KAAK,KAAK,MAAA,CAAO;AAAA,OAC/C,GACA;AAAA,KACN;AAAA,IACJ,CAAC,UAAA,EAAY,SAAA,EAAW,KAAA,CAAM,MAAA,EAAQ,MAAM,MAAM;AAAA,GACpD;AAMA,EAAA,MAAM,MAAA,GAASA,cAA4B,MAAM;AAE/C,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,MAAA,CAAO,CAAC,GAAA,EAAK,MAAM,GAAA,IAAO,CAAA,CAAE,IAAA,IAAQ,CAAA,CAAA,EAAI,CAAC,CAAA;AAC1E,IAAA,MAAM,aAAa,cAAA,CAAe,MAAA;AAAA,MAChC,CAAC,GAAA,EAAK,CAAA,KAAM,OAAO,CAAA,CAAE,IAAA,GAAO,IAAI,CAAA,CAAE,KAAA,CAAA;AAAA,MAClC;AAAA,KACF;AACA,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,iBAAiB,UAAU,CAAA;AAErD,IAAA,MAAM,OAAA,GAAU,CAAC,MAAA,KAAiC;AAChD,MAAA,IAAI,CAAC,MAAA,CAAO,IAAA,IAAQ,SAAA,KAAc,CAAA,SAAU,MAAA,CAAO,KAAA;AACnD,MAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAO,KAAA,GAAQ,MAAA,CAAO,OAAQ,SAAS,CAAA;AAC1D,MAAA,MAAM,MAAA,GAAS,OAAO,QAAA,GAAW,IAAA,CAAK,IAAI,KAAA,EAAO,MAAA,CAAO,QAAQ,CAAA,GAAI,KAAA;AACpE,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,MAAA,CAAO,QAAQ,CAAA;AAAA,IACzC,CAAA;AAIA,IAAA,MAAM,OAAO,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,MAAM,CAAA;AAC7D,IAAA,MAAM,SAAS,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,EAAE,MAAM,CAAA;AACrD,IAAA,MAAM,QAAQ,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,OAAO,CAAA;AAE/D,IAAA,MAAM,QAAkC,EAAC;AACzC,IAAA,IAAI,MAAA,GAAS,CAAA;AACb,IAAA,IAAI,UAAA,GAAa,CAAA;AAEjB,IAAA,KAAA,MAAW,UAAU,IAAA,EAAM;AACzB,MAAA,MAAM,KAAA,GAAQ,QAAQ,MAAM,CAAA;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,MAAA;AAAA,QACA,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,KAAA;AAAA,QACA,IAAA,EAAM,MAAA;AAAA,QACN,MAAA,EAAQ,MAAA;AAAA,QACR,YAAA,EAAc;AAAA,OACf,CAAA;AACD,MAAA,MAAA,IAAU,KAAA;AACV,MAAA,UAAA,IAAc,KAAA;AAAA,IAChB;AAEA,IAAA,KAAA,MAAW,UAAU,MAAA,EAAQ;AAC3B,MAAA,MAAM,KAAA,GAAQ,QAAQ,MAAM,CAAA;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,YAAA,EAAc,CAAA,EAAG,CAAA;AAChF,MAAA,MAAA,IAAU,KAAA;AAAA,IACZ;AAIA,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AACrC,IAAA,IAAI,WAAA,GAAc,CAAA;AAClB,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,MAAA,YAAA,CAAa,CAAC,CAAA,GAAI,WAAA;AAClB,MAAA,WAAA,IAAe,YAAY,CAAC,CAAA;AAAA,IAC9B;AAEA,IAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,MAAA,EAAQ,KAAA,KAAU;AAC/B,MAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,MAAA;AAAA,QACA,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,KAAA;AAAA,QACA,IAAA,EAAM,MAAA;AAAA,QACN,MAAA,EAAQ,OAAA;AAAA,QACR,YAAA,EAAc,aAAa,KAAK;AAAA,OACjC,CAAA;AACD,MAAA,MAAA,IAAU,KAAA;AAAA,IACZ,CAAC,CAAA;AAED,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,UAAA,EAAY,MAAA;AAAA,MACZ,eAAA,EAAiB,UAAA;AAAA,MACjB,gBAAA,EAAkB;AAAA,KACpB;AAAA,EACF,CAAA,EAAG,CAAC,cAAA,EAAgB,cAAc,CAAC,CAAA;AAEnC,EAAA,MAAM,QAAA,GAAWE,iBAAA,CAAY,CAAC,KAAA,KAAkB,SAAA,CAAU,IAAI,KAAK,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEjF,EAAA,MAAM,SAAA,GAAYA,iBAAA;AAAA,IAChB,CAAC,OAAe,MAAA,KAAoB;AAClC,MAAA,MAAA,CAAO,CAAC,OAAA,MAAa;AAAA,QACnB,GAAG,OAAA;AAAA,QACH,MAAA,EAAQ,SACJ,OAAA,CAAQ,MAAA,CAAO,SAAS,KAAK,CAAA,GAC3B,QAAQ,MAAA,GACR,CAAC,GAAG,OAAA,CAAQ,MAAA,EAAQ,KAAK,CAAA,GAC3B,OAAA,CAAQ,OAAO,MAAA,CAAO,CAAC,EAAA,KAAO,EAAA,KAAO,KAAK;AAAA,OAChD,CAAE,CAAA;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,QAAA,GAAWA,iBAAA;AAAA,IACf,CAAC,OAAe,KAAA,KAAkB;AAChC,MAAA,MAAA,CAAO,CAAC,OAAA,MAAa;AAAA,QACnB,GAAG,OAAA;AAAA,QACH,MAAA,EAAQ,EAAE,GAAG,OAAA,CAAQ,MAAA,EAAQ,CAAC,KAAK,GAAG,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAAE,OAC1D,CAAE,CAAA;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,SAAA,GAAYA,iBAAA;AAAA,IAChB,CAAC,OAAe,MAAA,KAA+B;AAC7C,MAAA,MAAA,CAAO,CAAC,OAAA,KAAY;AAClB,QAAA,MAAM,IAAA,GAAO,EAAE,GAAG,OAAA,CAAQ,MAAA,EAAO;AACjC,QAAA,IAAI,MAAA,EAAQ,IAAA,CAAK,KAAK,CAAA,GAAI,MAAA;AAAA,aACrB,OAAO,KAAK,KAAK,CAAA;AACtB,QAAA,OAAO,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,IAAA,EAAK;AAAA,MACpC,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,UAAA,GAAaA,iBAAA;AAAA,IACjB,CAAC,OAAe,OAAA,KAAoB;AAClC,MAAA,MAAA,CAAO,CAAC,OAAA,KAAY;AAClB,QAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AACxC,QAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,OAAA,EAAS,OAAO,OAAA;AAC5C,QAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,OAAA,CAAQ,KAAK,CAAA;AAC/B,QAAA,KAAA,CAAM,MAAA,CAAO,MAAM,CAAC,CAAA;AACpB,QAAA,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,KAAA,CAAM,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,KAAK,CAAA;AACnE,QAAA,OAAO,EAAE,GAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC7B,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM;AAC9B,IAAA,MAAA,CAAO,MAAM,QAAQ,CAAA;AAAA,EACvB,CAAA,EAAG,CAAC,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAErB,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,cAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AC5QA,SAAS,OAAA,CAAW,GAAA,EAAQ,IAAA,EAAc,KAAA,EAAmB;AAC3D,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,EAAE,GAAG,GAAA,EAAK,CAAC,IAAI,GAAG,KAAA,EAAM;AAAA,EACjC;AACA,EAAA,MAAM,CAAC,IAAA,EAAM,GAAG,IAAI,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AACtC,EAAA,MAAM,OAAA,GAAW,IAAgC,IAAI,CAAA;AACrD,EAAA,OAAO;AAAA,IACL,GAAG,GAAA;AAAA,IACH,CAAC,IAAI,GAAG,OAAA;AAAA,MACL,WAAW,EAAC;AAAA,MACb,IAAA,CAAK,KAAK,GAAG,CAAA;AAAA,MACb;AAAA;AACF,GACF;AACF;AASO,SAAS,aACd,QAAA,EACuB;AACvB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAID,eAA8B,IAAI,CAAA;AAK1D,EAAA,MAAM,OAAA,GAAUE,aAA4B,IAAI,CAAA;AAEhD,EAAA,MAAM,KAAA,GAAQD,iBAAAA;AAAA,IACZ,CAAC,IAAA,KAA8B;AAC7B,MAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,KAAA,GAAQA,iBAAAA,CAAY,CAAC,MAAA,KAAoD;AAC7E,IAAA,MAAM,UAAU,OAAA,CAAQ,OAAA;AACxB,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,MAAM,IAAA,GAAO,OAAO,OAAO,CAAA;AAC3B,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,IAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,EACd,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,SAAA,GAAYA,iBAAAA;AAAA,IAChB,CAAC,KAAA,KAAiB,IAAA,EAAM,KAAA,KAAU,KAAA;AAAA,IAClC,CAAC,IAAI;AAAA,GACP;AAEA,EAAA,MAAM,KAAA,GAAQA,iBAAAA;AAAA,IACZ,CAAC,OAAc,GAAA,KAAW;AACxB,MAAA,KAAA,CAAM,EAAE,KAAA,EAAO,KAAA,EAAO,GAAA,EAAK,QAAA,EAAU,GAAA,EAAK,MAAA,EAAQ,EAAC,EAAG,QAAA,EAAU,KAAA,EAAO,CAAA;AAAA,IACzE,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AAEA,EAAA,MAAM,QAAA,GAAWA,iBAAAA;AAAA,IACf,CAAC,OAAe,KAAA,KAAmB;AACjC,MAAA,KAAA,CAAM,CAAC,OAAA,KAAY;AACjB,QAAA,MAAM,MAAA,GAAS,EAAE,GAAG,OAAA,CAAQ,MAAA,EAAO;AAGnC,QAAA,OAAO,OAAO,KAAK,CAAA;AACnB,QAAA,OAAO,EAAE,GAAG,OAAA,EAAS,KAAA,EAAO,OAAA,CAAQ,QAAQ,KAAA,EAAO,KAAA,EAAO,KAAK,CAAA,EAAG,MAAA,EAAO;AAAA,MAC3E,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,KAAK;AAAA,GACR;AAEA,EAAA,MAAM,MAAA,GAASA,kBAAY,MAAM,KAAA,CAAM,IAAI,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAErD,EAAA,MAAM,MAAA,GAASA,kBAAY,YAAY;AACrC,IAAA,MAAM,QAAQ,OAAA,CAAQ,OAAA;AACtB,IAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,QAAA,EAAU;AAE9B,IAAA,KAAA,CAAM,EAAE,GAAG,KAAA,EAAO,QAAA,EAAU,MAAM,CAAA;AAElC,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,MAAM,QAAA,CAAS,KAAA,CAAM,KAAA,EAAO,MAAM,QAAQ,CAAA;AACzD,MAAA,IAAI,OAAO,EAAA,EAAI;AACb,QAAA,KAAA,CAAM,IAAI,CAAA;AACV,QAAA;AAAA,MACF;AACA,MAAA,KAAA,CAAM,CAAC,OAAA,MAAa,EAAE,GAAG,OAAA,EAAS,QAAQ,MAAA,CAAO,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAM,CAAE,CAAA;AAAA,IAC7E,SAAS,KAAA,EAAO;AACd,MAAA,KAAA,CAAM,CAAC,OAAA,MAAa;AAAA,QAClB,GAAG,OAAA;AAAA,QACH,QAAA,EAAU,KAAA;AAAA,QACV,MAAA,EAAQ;AAAA,UACN,GAAG,OAAA,CAAQ,MAAA;AAAA,UACX,OAAA,EACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU;AAAA;AAC7C,OACF,CAAE,CAAA;AAAA,IACJ;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,KAAA,EAAO,KAAK,CAAC,CAAA;AAE3B,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,QAAA,EAAU,QAAQ,MAAA,EAAO;AAC5D;;;ACyIO,IAAM,kBAAA,GAAqB;;;AC7PlC,IAAM,MAAA,GAAS,MAAA;AAEf,SAAS,KAAK,UAAA,EAAoD;AAChE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,MAAA;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,SAAS,UAAU,CAAA;AAC3D,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA,CAAA;AACjB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAG7B,IAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,CAAA,KAAM,oBAAoB,OAAO,KAAA,CAAA;AACvD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAEA,SAAS,KAAA,CAAM,YAAoB,KAAA,EAAiC;AAClE,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,IAAI;AACF,IAAA,MAAA,CAAO,aAAa,OAAA,CAAQ,MAAA,GAAS,YAAY,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EACxE,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAcO,SAAS,aAAa,UAAA,EAAoD;AAC/E,EAAA,MAAM,UAAA,GAAaC,YAAAA;AAAA,IACjB,UAAA,GAAa,IAAA,CAAK,UAAU,CAAA,GAAI;AAAA,GAClC;AACA,EAAA,MAAM,CAAC,eAAe,gBAAgB,CAAA,GAAIF,eAAS,MAAM,UAAA,CAAW,WAAW,IAAI,CAAA;AAGnF,EAAA,MAAM,UAAA,GAAaE,YAAAA;AAAA,IACjB,WAAW,OAAA,IAAW;AAAA,MACpB,CAAA,EAAG,kBAAA;AAAA,MACH,OAAA,EAAS,EAAE,KAAA,EAAO,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAG,MAAA,EAAQ,EAAC,EAAE;AAAA,MACzD,MAAM,EAAC;AAAA,MACP,SAAS,EAAC;AAAA,MACV,UAAA,EAAY,EAAE,QAAA,EAAU,EAAA;AAAG;AAC7B,GACF;AAEA,EAAA,MAAM,OAAA,GAAUD,iBAAAA;AAAA,IACd,CAAC,KAAA,KAAuC;AACtC,MAAA,IAAI,CAAC,UAAA,EAAY;AACjB,MAAA,UAAA,CAAW,OAAA,GAAU,EAAE,GAAG,UAAA,CAAW,SAAS,GAAG,KAAA,EAAO,GAAG,kBAAA,EAAmB;AAC9E,MAAA,KAAA,CAAM,UAAA,EAAY,WAAW,OAAO,CAAA;AACpC,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA,IACvB,CAAA;AAAA,IACA,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,WAAA,GAAcA,iBAAAA;AAAA,IAClB,CAAC,OAAA,KAA2C,OAAA,CAAQ,EAAE,SAAS,CAAA;AAAA,IAC/D,CAAC,OAAO;AAAA,GACV;AACA,EAAA,MAAM,QAAA,GAAWA,iBAAAA,CAAY,CAAC,IAAA,KAA0B,OAAA,CAAQ,EAAE,IAAA,EAAM,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AACpF,EAAA,MAAM,WAAA,GAAcA,iBAAAA;AAAA,IAClB,CAAC,OAAA,KAA4B,OAAA,CAAQ,EAAE,SAAS,CAAA;AAAA,IAChD,CAAC,OAAO;AAAA,GACV;AACA,EAAA,MAAM,YAAA,GAAeA,iBAAAA;AAAA,IACnB,CAAC,aAAqB,OAAA,CAAQ,EAAE,YAAY,EAAE,QAAA,IAAY,CAAA;AAAA,IAC1D,CAAC,OAAO;AAAA,GACV;AAEA,EAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM;AAC9B,IAAA,IAAI,CAAC,UAAA,IAAc,OAAO,MAAA,KAAW,WAAA,EAAa;AAClD,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,YAAA,CAAa,UAAA,CAAW,MAAA,GAAS,UAAU,CAAA;AAAA,IACpD,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,EACxB,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,OAAO;AAAA,IACL,SAAS,UAAA,CAAW,OAAA;AAAA,IACpB,WAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;ACpFO,SAAS,iBAAA,CACd,IAAA,EACA,QAAA,EACA,kBAAA,EAC4B;AAC5B,EAAA,MAAM,CAAC,aAAa,cAAc,CAAA,GAAID,eAAqB,sBAAM,IAAI,KAAK,CAAA;AAC1E,EAAA,MAAM,mBAAA,GAAsBE,aAAsB,IAAI,CAAA;AAEtD,EAAA,MAAM,OAAA,GAAUA,aAAO,IAAI,CAAA;AAC3B,EAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAClB,EAAA,MAAM,WAAA,GAAcA,aAAO,QAAQ,CAAA;AACnC,EAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAEtB,EAAA,MAAM,MAAA,GAASD,iBAAAA;AAAA,IACb,CAAC,IAAA,KAAqB;AACpB,MAAA,cAAA,CAAe,IAAI,CAAA;AACnB,MAAA,kBAAA,GAAqB,CAAC,GAAG,IAAI,CAAC,CAAA;AAAA,IAChC,CAAA;AAAA,IACA,CAAC,kBAAkB;AAAA,GACrB;AAEA,EAAA,MAAM,UAAA,GAAaA,iBAAAA,CAAY,CAAC,EAAA,KAAc,WAAA,CAAY,IAAI,EAAE,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhF,EAAA,MAAM,UAAA,GAAaF,aAAAA,CAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAA,EAAG,CAAC,IAAA,EAAM,QAAQ,CAAC,CAAA;AAErE,EAAA,MAAM,kBAAA,GACJ,UAAA,CAAW,MAAA,GAAS,CAAA,IAAK,UAAA,CAAW,KAAA,CAAM,CAAC,EAAA,KAAO,WAAA,CAAY,GAAA,CAAI,EAAE,CAAC,CAAA;AACvE,EAAA,MAAM,mBAAA,GACJ,CAAC,kBAAA,IAAsB,UAAA,CAAW,IAAA,CAAK,CAAC,EAAA,KAAO,WAAA,CAAY,GAAA,CAAI,EAAE,CAAC,CAAA;AAEpE,EAAA,MAAM,SAAA,GAAYE,iBAAAA;AAAA,IAChB,CAAC,EAAA,EAAW,KAAA,EAAe,QAAA,KAAsB;AAC/C,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,WAAW,CAAA;AAChC,MAAA,MAAM,SAAS,mBAAA,CAAoB,OAAA;AAEnC,MAAA,IAAI,QAAA,IAAY,MAAA,IAAU,IAAA,IAAQ,MAAA,KAAW,KAAA,EAAO;AAElD,QAAA,MAAM,CAAC,IAAA,EAAM,EAAE,CAAA,GAAI,MAAA,GAAS,KAAA,GAAQ,CAAC,MAAA,EAAQ,KAAK,CAAA,GAAI,CAAC,KAAA,EAAO,MAAM,CAAA;AACpE,QAAA,MAAM,YAAA,GAAe,CAAC,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACjC,QAAA,KAAA,IAAS,CAAA,GAAI,IAAA,EAAM,CAAA,IAAK,EAAA,EAAI,CAAA,EAAA,EAAK;AAC/B,UAAA,MAAM,QAAQ,WAAA,CAAY,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,CAAC,CAAC,CAAA;AACpD,UAAA,IAAI,SAAS,IAAA,EAAM;AACnB,UAAA,IAAI,YAAA,EAAc,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AAAA,eAC3B,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,QACxB;AAAA,MACF,CAAA,MAAA,IAAW,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,EAAG;AACvB,QAAA,IAAA,CAAK,OAAO,EAAE,CAAA;AAAA,MAChB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AAAA,MACb;AAEA,MAAA,mBAAA,CAAoB,OAAA,GAAU,KAAA;AAC9B,MAAA,MAAA,CAAO,IAAI,CAAA;AAAA,IACb,CAAA;AAAA,IACA,CAAC,aAAa,MAAM;AAAA,GACtB;AAEA,EAAA,MAAM,gBAAA,GAAmBA,kBAAY,MAAM;AACzC,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,WAAW,CAAA;AAChC,IAAA,IAAI,kBAAA,EAAoB;AACtB,MAAA,KAAA,MAAW,EAAA,IAAM,UAAA,EAAY,IAAA,CAAK,MAAA,CAAO,EAAE,CAAA;AAAA,IAC7C,CAAA,MAAO;AACL,MAAA,KAAA,MAAW,EAAA,IAAM,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AAAA,IAC1C;AACA,IAAA,mBAAA,CAAoB,OAAA,GAAU,IAAA;AAC9B,IAAA,MAAA,CAAO,IAAI,CAAA;AAAA,EACb,GAAG,CAAC,WAAA,EAAa,kBAAA,EAAoB,UAAA,EAAY,MAAM,CAAC,CAAA;AAExD,EAAA,MAAM,gBAAA,GAAmBA,kBAAY,MAAM;AACzC,IAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,WAAW,CAAA;AAChC,IAAA,KAAA,MAAW,EAAA,IAAM,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA;AACxC,IAAA,MAAA,CAAO,IAAI,CAAA;AAAA,EACb,CAAA,EAAG,CAAC,WAAA,EAAa,UAAA,EAAY,MAAM,CAAC,CAAA;AAEpC,EAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM;AAC9B,IAAA,mBAAA,CAAoB,OAAA,GAAU,IAAA;AAC9B,IAAA,MAAA,iBAAO,IAAI,KAAK,CAAA;AAAA,EAClB,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,eAAA,GAAkBA,iBAAAA;AAAA,IACtB,MAAM,OAAA,CAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAA,KAAQ,WAAA,CAAY,GAAA,CAAI,WAAA,CAAY,OAAA,CAAQ,GAAG,CAAC,CAAC,CAAA;AAAA,IAC/E,CAAC,WAAW;AAAA,GACd;AAEA,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,mBAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,KAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AACF;AC7FA,SAAS,YAAA,CACP,IAAA,EACA,QAAA,EACA,SAAA,EACA,WAAA,EACe;AACf,EAAA,OAAO;AAAA,IACL,UAAU,IAAA,GAAO,QAAA;AAAA,IACjB,MAAA,EAAQ,OAAO,QAAA,GAAW,QAAA;AAAA,IAC1B,SAAA;AAAA,IACA,WAAA;AAAA;AAAA,IAEA,cAAc,EAAC;AAAA,IACf,WAAW,EAAC;AAAA,IACZ,WAAW,EAAC;AAAA,IACZ,SAAA,EAAW,KAAA;AAAA,IACX,WAAW;AAAC,GACd;AACF;AAWO,SAAS,mBAAA,CAAuB;AAAA,EACrC,UAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA,GAAkB,CAAA;AAAA,EAClB;AACF,CAAA,EAAgE;AAC9D,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAID,cAAAA,CAAc,EAAE,CAAA;AACxC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,CAAC,CAAA;AAC5C,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAkB,IAAI,CAAA;AAGhD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAS,CAAC,CAAA;AAElD,EAAA,MAAM,QAAA,GAAWE,YAAAA,iBAAO,IAAI,GAAA,EAA6C,CAAA;AACzE,EAAA,MAAM,YAAA,GAAeA,aAAO,CAAC,CAAA;AAC7B,EAAA,MAAM,QAAA,GAAWA,aAA+B,IAAI,CAAA;AAIpD,EAAA,MAAM,QAAA,GAAWH,aAAAA;AAAA,IACf,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,QAAA,EAAU,SAAA,EAAW,aAAa,CAAA;AAAA,IACzD,CAAC,QAAA,EAAU,SAAA,EAAW,WAAW;AAAA,GACnC;AAGA,EAAAI,eAAA,CAAU,MAAM;AACd,IAAA,QAAA,CAAS,QAAQ,KAAA,EAAM;AAAA,EACzB,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,UAAA,GAAaD,aAAO,OAAO,CAAA;AACjC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAAA,EACvB,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,aAAA,GAAgBD,aAAO,UAAU,CAAA;AACvC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,aAAA,CAAc,OAAA,GAAU,UAAA;AAAA,EAC1B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,QAAA,GAAW,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA;AACrC,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAC5C,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAA,CAAQ,OAAO,IAAI,CAAA;AACnB,MAAA,YAAA,CAAa,OAAO,OAAO,CAAA;AAC3B,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA;AAAA,IACF;AAEA,IAAA,QAAA,CAAS,SAAS,KAAA,EAAM;AACxB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,QAAA,CAAS,OAAA,GAAU,UAAA;AAEnB,IAAA,MAAM,SAAA,GAAY,EAAE,YAAA,CAAa,OAAA;AACjC,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AAEb,IAAA,MAAM,OAAA,GAAU,YAAA,CAAa,IAAA,EAAM,QAAA,EAAU,WAAW,WAAW,CAAA;AAEnE,IAAA,aAAA,CAAc,OAAA,CACX,QAAQ,OAAA,EAAS,UAAA,CAAW,MAAM,CAAA,CAClC,IAAA,CAAK,CAAC,QAAA,KAAa;AAElB,MAAA,IAAI,SAAA,KAAc,aAAa,OAAA,EAAS;AAExC,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,IAAA,CAAK,MAAA;AAClD,MAAA,QAAA,CAAS,OAAA,CAAQ,IAAI,QAAA,EAAU,EAAE,MAAM,QAAA,CAAS,IAAA,EAAM,SAAS,CAAA;AAG/D,MAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,IAAA,GAAO,eAAA,EAAiB;AAC9C,QAAA,MAAM,SAAS,QAAA,CAAS,OAAA,CAAQ,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AAC9C,QAAA,IAAI,WAAW,MAAA,EAAW;AAC1B,QAAA,QAAA,CAAS,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,MAChC;AAEA,MAAA,OAAA,CAAQ,SAAS,IAAI,CAAA;AACrB,MAAA,YAAA,CAAa,OAAO,CAAA;AACpB,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AACd,MAAA,IAAI,UAAA,CAAW,OAAO,OAAA,EAAS;AAC/B,MAAA,IAAI,SAAA,KAAc,aAAa,OAAA,EAAS;AACxC,MAAA,QAAA,CAAS,GAAG,CAAA;AACZ,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,UAAA,CAAW,UAAU,GAAG,CAAA;AAAA,IAC1B,CAAC,CAAA;AAEH,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,KAAA,EAAM;AAAA,IACnB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,IAAA,EAAM,UAAU,SAAA,EAAW,WAAA,EAAa,YAAA,EAAc,eAAe,CAAC,CAAA;AAEpF,EAAA,MAAM,OAAA,GAAUF,iBAAAA,CAAY,CAAC,OAAA,KAAkC;AAC7D,IAAA,IAAI,OAAA,EAAS,KAAA,KAAU,KAAA,EAAO,QAAA,CAAS,QAAQ,KAAA,EAAM;AACrD,IAAA,eAAA,CAAgB,CAAC,KAAA,KAAU,KAAA,GAAQ,CAAC,CAAA;AAAA,EACtC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,SAAA,GAAYA,iBAAAA;AAAA,IAChB,CAAC,SAAc,QAAA,KAA0C;AACvD,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AAC1B,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ,CAAC,QAAA,CAAS,GAAG,CAAA,EAAG,GAAG,CAAC,CAAC,CAAA;AAE/D,MAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAAc;AAC3B,QAAA,IAAI,OAAA,GAAU,KAAA;AACd,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC7B,UAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAC,CAAA;AAC1C,UAAA,IAAI,CAAC,aAAa,OAAO,GAAA;AACzB,UAAA,OAAA,GAAU,IAAA;AACV,UAAA,OAAO,WAAA;AAAA,QACT,CAAC,CAAA;AACD,QAAA,OAAO,UAAU,IAAA,GAAO,IAAA;AAAA,MAC1B,CAAA;AAEA,MAAA,OAAA,CAAQ,KAAK,CAAA;AAGb,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,SAAS,OAAA,EAAS;AAC3C,QAAA,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,EAAE,GAAG,KAAA,EAAO,IAAA,EAAM,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,EAAG,CAAA;AAAA,MACjE;AAAA,IACF,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,KAAA,EAAO,SAAS,SAAA,EAAU;AACjE;ACrJO,SAAS,cAAA,CAAe;AAAA,EAC7B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW;AACb,CAAA,EAAgD;AAC9C,EAAA,MAAM,CAAC,cAAA,EAAgB,sBAAsB,CAAA,GAAID,eAAS,CAAC,CAAA;AAC3D,EAAA,MAAM,CAACI,OAAAA,EAAQ,SAAS,CAAA,GAAIJ,cAAAA,CAAwB,EAAE,UAAA,EAAY,CAAA,EAAG,QAAA,EAAU,CAAA,EAAG,CAAA;AAElF,EAAA,MAAM,YAAA,GAAeE,aAAO,CAAC,CAAA;AAC7B,EAAA,MAAM,QAAA,GAAWA,aAAsB,IAAI,CAAA;AAE3C,EAAA,MAAM,OAAA,GAAUD,iBAAAA;AAAA,IACd,CAAC,WAAmB,MAAA,KAAmB;AACrC,MAAA,IAAI,MAAA,IAAU,CAAA,IAAK,QAAA,KAAa,CAAA,EAAG;AACjC,QAAA,OAAO,EAAE,UAAA,EAAY,CAAA,EAAG,QAAA,EAAU,CAAA,EAAE;AAAA,MACtC;AACA,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,SAAS,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,SAAS,CAAA;AAC5C,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,QAAQ,CAAA;AAAA,QACxC,UAAU,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,KAAA,GAAQ,UAAU,QAAQ;AAAA,OACzD;AAAA,IACF,CAAA;AAAA,IACA,CAAC,QAAA,EAAU,SAAA,EAAW,QAAQ;AAAA,GAChC;AAEA,EAAA,MAAM,KAAA,GAAQA,iBAAAA;AAAA,IACZ,CAAC,WAAmB,MAAA,KAAmB;AACrC,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,SAAA,EAAW,MAAM,CAAA;AACtC,MAAA,SAAA;AAAA,QAAU,CAAC,OAAA,KACT,OAAA,CAAQ,UAAA,KAAe,IAAA,CAAK,cAAc,OAAA,CAAQ,QAAA,KAAa,IAAA,CAAK,QAAA,GAChE,OAAA,GACA;AAAA,OACN;AAAA,IACF,CAAA;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAEA,EAAA,MAAM,QAAA,GAAWA,iBAAAA;AAAA,IACf,CAAC,KAAA,KAA0C;AACzC,MAAA,YAAA,CAAa,OAAA,GAAU,MAAM,aAAA,CAAc,SAAA;AAC3C,MAAA,IAAI,QAAA,CAAS,WAAW,IAAA,EAAM;AAC9B,MAAA,QAAA,CAAS,OAAA,GAAU,sBAAsB,MAAM;AAC7C,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,QAAA,KAAA,CAAM,YAAA,CAAa,SAAS,cAAc,CAAA;AAAA,MAC5C,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,IACA,CAAC,OAAO,cAAc;AAAA,GACxB;AAEA,EAAA,MAAM,iBAAA,GAAoBA,iBAAAA,CAAY,CAAC,MAAA,KAAmB;AACxD,IAAA,sBAAA,CAAuB,CAAC,OAAA,KAAa,OAAA,KAAY,MAAA,GAAS,UAAU,MAAO,CAAA;AAAA,EAC7E,CAAA,EAAG,EAAE,CAAA;AAIL,EAAAE,gBAAU,MAAM;AACd,IAAA,KAAA,CAAM,YAAA,CAAa,SAAS,cAAc,CAAA;AAAA,EAC5C,CAAA,EAAG,CAAC,KAAA,EAAO,cAAc,CAAC,CAAA;AAE1B,EAAAA,eAAAA;AAAA,IACE,MAAM,MAAM;AACV,MAAA,IAAI,QAAA,CAAS,OAAA,IAAW,IAAA,EAAM,oBAAA,CAAqB,SAAS,OAAO,CAAA;AAAA,IACrE,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAAC,OAAAA;AAAA,IACA,aAAa,QAAA,GAAW,SAAA;AAAA,IACxB,QAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF;AACF;;;ACtGA,SAAS,SAAA,CAAU,OAAe,SAAA,EAA2B;AAC3D,EAAA,IAAI,KAAA,KAAU,IAAI,OAAO,EAAA;AACzB,EAAA,MAAM,WAAA,GACJ,KAAA,CAAM,QAAA,CAAS,SAAS,KACxB,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,IAClB,MAAM,QAAA,CAAS,IAAI,CAAA,IACnB,KAAA,CAAM,SAAS,IAAI,CAAA;AACrB,EAAA,OAAO,cAAc,CAAA,CAAA,EAAI,KAAA,CAAM,QAAQ,IAAA,EAAM,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,KAAA;AAC1D;AAEO,SAAS,WAAA,CACd,IAAA,EACA,OAAA,EACA,SAAA,EACQ;AACR,EAAA,MAAM,aAAa,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,CAAC,OAAO,cAAc,CAAA;AAEpE,EAAA,MAAM,KAAA,GAAkB;AAAA,IACtB,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,SAAA,CAAU,UAAA,CAAW,CAAC,CAAA,EAAG,SAAS,CAAC,CAAA,CAAE,IAAA,CAAK,SAAS;AAAA,GAC3E;AAEA,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,UAAA,CACG,GAAA,CAAI,CAAC,MAAA,KAAW,SAAA,CAAU,WAAA,CAAY,GAAA,EAAK,MAAM,CAAA,EAAG,SAAS,CAAC,CAAA,CAC9D,KAAK,SAAS;AAAA,KACnB;AAAA,EACF;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAC1B;AAEO,SAAS,KAAA,CACd,IAAA,EACA,OAAA,EACA,SAAA,GAAY,GAAA,EACJ;AACR,EAAA,OAAO,WAAA,CAAY,IAAA,EAAM,OAAA,EAAS,SAAS,CAAA;AAC7C;AAGO,SAAS,KAAA,CACd,MACA,OAAA,EACQ;AACR,EAAA,OAAO,WAAA,CAAY,IAAA,EAAM,OAAA,EAAS,GAAI,CAAA;AACxC;AAEO,SAAS,WAAA,CAAY,SAAiB,QAAA,EAAwB;AAEnE,EAAA,MAAM,OAAO,IAAI,IAAA,CAAK,CAAC,QAAA,GAAM,OAAO,CAAA,EAAG;AAAA,IACrC,IAAA,EAAM;AAAA,GACP,CAAA;AACD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACzC,EAAA,MAAA,CAAO,IAAA,GAAO,GAAA;AACd,EAAA,MAAA,CAAO,WAAW,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,GAAI,QAAA,GAAW,GAAG,QAAQ,CAAA,IAAA,CAAA;AACpE,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,MAAA,CAAO,KAAA,EAAM;AACb,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAChC,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;AAEA,eAAsB,gBAAgB,IAAA,EAA6B;AACjE,EAAA,IAAI,SAAA,EAAW,WAAW,SAAA,EAAW;AACnC,IAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AACxC,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,UAAU,CAAA;AAClD,EAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AACjB,EAAA,QAAA,CAAS,MAAM,QAAA,GAAW,OAAA;AAC1B,EAAA,QAAA,CAAS,MAAM,OAAA,GAAU,GAAA;AACzB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAClC,EAAA,QAAA,CAAS,MAAA,EAAO;AAChB,EAAA,QAAA,CAAS,YAAY,MAAM,CAAA;AAC3B,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AACpC;;;ACnEO,IAAM,iBAAA,GAAsC;AAAA,EACjD,UAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAEO,IAAM,mBAAA,GAA0C;AAAA,EACrD,QAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,oBAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAEO,IAAM,iBAAA,GAAsC;AAAA,EACjD,QAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AAEO,IAAM,kBAAA,GAA6C;AAAA,EACxD,QAAA,EAAU,UAAA;AAAA,EACV,WAAA,EAAa,kBAAA;AAAA,EACb,MAAA,EAAQ,QAAA;AAAA,EACR,QAAA,EAAU,WAAA;AAAA,EACV,UAAA,EAAY,aAAA;AAAA,EACZ,QAAA,EAAU,WAAA;AAAA,EACV,KAAA,EAAO,UAAA;AAAA,EACP,QAAA,EAAU,cAAA;AAAA,EACV,QAAA,EAAU,WAAA;AAAA,EACV,eAAA,EAAiB,oBAAA;AAAA,EACjB,WAAA,EAAa,cAAA;AAAA,EACb,kBAAA,EAAoB,uBAAA;AAAA,EACpB,OAAA,EAAS,SAAA;AAAA,EACT,MAAA,EAAQ,QAAA;AAAA,EACR,KAAA,EAAO;AACT;AAGO,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,OAAO,IAAA,KAAS,WAAW,IAAA,KAAS,UAAA;AACtC;AAEO,SAAS,cAAc,IAAA,EAAuB;AACnD,EAAA,OAAO,IAAA,KAAS,SAAA;AAClB;AAEO,SAAS,kBAAkB,IAAA,EAA0B;AAC1D,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,MAAA;AACH,MAAA,OAAO,UAAA;AAAA,IACT,KAAK,QAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,OAAO,KAAA;AAAA;AAEb;AAEO,SAAS,eAAA,CAAgB,MAAsB,MAAA,EAAsC;AAC1F,EAAA,IAAI,CAAC,cAAc,IAAI,CAAA,IAAK,OAAO,IAAA,EAAK,KAAM,IAAI,OAAO,IAAA;AACzD,EAAA,OAAO,aAAA,CAAc,IAAI,CAAA,GACrB,EAAE,UAAA,EAAY,MAAA,EAAQ,IAAA,EAAK,GAC3B,EAAE,UAAA,EAAY,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAO;AACzC;AAEO,SAAS,iBAAA,CACd,IAAA,EACA,MAAA,EACA,QAAA,EACsB;AACtB,EAAA,IAAI,cAAc,IAAI,CAAA,SAAU,EAAE,UAAA,EAAY,UAAU,IAAA,EAAK;AAE7D,EAAA,MAAM,IAAA,GAAO,OAAO,MAAM,CAAA;AAC1B,EAAA,IAAI,MAAA,CAAO,MAAK,KAAM,EAAA,IAAM,OAAO,KAAA,CAAM,IAAI,GAAG,OAAO,IAAA;AAEvD,EAAA,IAAI,aAAA,CAAc,IAAI,CAAA,EAAG;AACvB,IAAA,MAAM,EAAA,GAAK,OAAO,QAAQ,CAAA;AAC1B,IAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,IAAA,EAAK,KAAM,MAAM,MAAA,CAAO,KAAA,CAAM,EAAE,CAAA,EAAG,OAAO,IAAA;AACpE,IAAA,OAAO,EAAE,UAAA,EAAY,QAAA,EAAU,MAAM,MAAA,EAAQ,IAAA,EAAM,UAAU,EAAA,EAAG;AAAA,EAClE;AAEA,EAAA,OAAO,EAAE,UAAA,EAAY,QAAA,EAAU,IAAA,EAAM,QAAQ,IAAA,EAAK;AACpD;AAEO,SAAS,eAAA,CACd,IAAA,EACA,QAAA,EACA,MAAA,EACsB;AACtB,EAAA,IAAI,cAAc,IAAI,CAAA,SAAU,EAAE,UAAA,EAAY,QAAQ,IAAA,EAAK;AAC3D,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AAEtB,EAAA,IAAI,aAAA,CAAc,IAAI,CAAA,EAAG;AACvB,IAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,IAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,IAAA,EAAM,UAAU,MAAA,EAAO;AAAA,EACtD;AAEA,EAAA,OAAO,EAAE,UAAA,EAAY,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAS;AAC9C;AAEO,SAAS,eAAe,MAAA,EAAwC;AACrE,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,OAAO,EAAE,UAAA,EAAY,KAAA,EAAO,MAAA,EAAO;AACrC;AAGO,SAAS,UAAA,CACd,KAAA,EACA,KAAA,EACA,MAAA,EACgB;AAChB,EAAA,MAAM,IAAA,GAAO,EAAE,GAAG,KAAA,EAAM;AACxB,EAAA,IAAI,WAAW,IAAA,EAAM;AACnB,IAAA,OAAO,KAAK,KAAK,CAAA;AAAA,EACnB,CAAA,MAAO;AACL,IAAA,IAAA,CAAK,KAAK,CAAA,GAAI,MAAA;AAAA,EAChB;AACA,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,eAAe,MAAA,EAA+B;AAC5D,EAAA,QAAQ,OAAO,UAAA;AAAY,IACzB,KAAK,KAAA;AACH,MAAA,OAAO,MAAA,CAAO,MAAA,CAAO,MAAA,KAAW,CAAA,GAC5B,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,GACf,CAAA,EAAG,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,SAAA,CAAA;AAAA,IAC7B,KAAK,MAAA;AACH,MAAA,OAAO,aAAA,CAAc,MAAA,CAAO,IAAI,CAAA,GAC5B,kBAAA,CAAmB,MAAA,CAAO,IAAI,CAAA,GAC9B,MAAA,CAAO,MAAA,CAAO,MAAA,IAAU,EAAE,CAAA;AAAA,IAChC,KAAK,QAAA;AACH,MAAA,IAAI,cAAc,MAAA,CAAO,IAAI,GAAG,OAAO,kBAAA,CAAmB,OAAO,IAAI,CAAA;AACrE,MAAA,OAAO,cAAc,MAAA,CAAO,IAAI,IAC5B,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA,GAAA,EAAM,MAAA,CAAO,QAAQ,CAAA,CAAA,GACrC,GAAG,kBAAA,CAAmB,MAAA,CAAO,IAAI,CAAC,CAAA,CAAA,EAAI,OAAO,MAAM,CAAA,CAAA;AAAA,IACzD,KAAK,MAAA;AACH,MAAA,IAAI,cAAc,MAAA,CAAO,IAAI,GAAG,OAAO,kBAAA,CAAmB,OAAO,IAAI,CAAA;AACrE,MAAA,OAAO,cAAc,MAAA,CAAO,IAAI,IAC5B,CAAA,EAAG,MAAA,CAAO,QAAQ,CAAA,GAAA,EAAM,MAAA,CAAO,MAAM,CAAA,CAAA,GACrC,GAAG,kBAAA,CAAmB,MAAA,CAAO,IAAI,CAAC,CAAA,CAAA,EAAI,OAAO,QAAQ,CAAA,CAAA;AAAA;AAE/D;AC5JO,SAAS,YAAA,CAAmB;AAAA,EACjC,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIJ,eAAS,EAAE,CAAA;AAEvC,EAAA,MAAM,QAAA,GAAWD,cAAQ,MAAM;AAC7B,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,EAAK,CAAE,WAAA,EAAY;AACzC,IAAA,IAAI,CAAC,QAAQ,OAAO,OAAA;AACpB,IAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,MAAO,CAAC,WACrB,UAAA,CAAW,MAAe,EAAE,WAAA,EAAY,CAAE,SAAS,MAAM;AAAA,KAC3D;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,MAAM,CAAC,CAAA;AAEpB,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,QAAA,CAAS,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,MAAA;AAE/D,EAAA,uBACEM,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sHAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mCAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gFAAA,EAAiF,QAAA,EAAA,SAAA,EAE/F,CAAA;AAAA,sBACAA,cAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,YAAA,EAAW,qBAAA;AAAA,UACX,SAAA,EAAU,iGAAA;AAAA,UACV,OAAA,EAAS,OAAA;AAAA,UACV,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACF,CAAA;AAAA,oBAEAA,cAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,4KAAA;AAAA,QACV,WAAA,EAAY,mBAAA;AAAA,QACZ,KAAA,EAAO,MAAA;AAAA,QACP,UAAU,CAAC,KAAA,KAAU,SAAA,CAAU,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA,KACnD;AAAA,oBAEAD,eAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,8CAAA,EACV,QAAA,EAAA;AAAA,MAAA,YAAA;AAAA,MAAa,MAAA;AAAA,MAAK,OAAA,CAAQ,MAAA;AAAA,MAAO;AAAA,KAAA,EACpC,CAAA;AAAA,mCAEC,KAAA,EAAA,EAAI,SAAA,EAAU,kCACZ,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,MAAA,KAAW;AACxB,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA;AACpC,MAAA,MAAM,KAAA,GAAQ,QAAQ,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,KAAA,KAAU,OAAO,KAAK,CAAA;AAE/D,MAAA,uBACEA,eAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,yFAAA;AAAA,UACV,SAAA,EAAS,IAAA;AAAA,UACT,WAAA,EAAa,CAAC,KAAA,KACZ,KAAA,CAAM,aAAa,OAAA,CAAQ,YAAA,EAAc,OAAO,KAAK,CAAA;AAAA,UAEvD,UAAA,EAAY,CAAC,KAAA,KAAU,KAAA,CAAM,cAAA,EAAe;AAAA,UAC5C,MAAA,EAAQ,CAAC,KAAA,KAAU;AACjB,YAAA,KAAA,CAAM,cAAA,EAAe;AACrB,YAAA,MAAM,OAAA,GAAU,KAAA,CAAM,YAAA,CAAa,OAAA,CAAQ,YAAY,CAAA;AACvD,YAAA,IAAI,WAAW,OAAA,KAAY,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,SAAS,KAAK,CAAA;AAAA,UAChE,CAAA;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uCAAA,EAAwC,aAAA,EAAW,MAAC,QAAA,EAAA,QAAA,EAEpE,CAAA;AAAA,4BAEAD,eAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,kGAAA,EACf,QAAA,EAAA;AAAA,8BAAAC,cAAA;AAAA,gBAAC,OAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,UAAA;AAAA,kBACL,SAAA,EAAU,8BAAA;AAAA,kBACV,SAAS,CAAC,MAAA;AAAA,kBACV,UAAU,MAAM,QAAA,CAAS,MAAA,CAAO,KAAA,EAAO,CAAC,MAAM;AAAA;AAAA,eAChD;AAAA,6CACC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,QAAA,EAAA,UAAA,CAAW,MAAe,CAAA,EAAE;AAAA,aAAA,EAC1D,CAAA;AAAA,4BAEAA,cAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,SAAA,EAAW,CAAA,kCAAA,EACT,MAAA,CAAO,MAAA,GACH,uCACA,iDACN,CAAA,CAAA;AAAA,gBACA,OAAO,MAAA,CAAO,MAAA,GAAS,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA,CAAA,CAAA,GAAM,UAAA;AAAA,gBACpD,OAAA,EAAS,MACP,KAAA,CAAM,MAAA,CAAO,OAAO,MAAA,CAAO,MAAA,GAAS,SAAY,MAAM,CAAA;AAAA,gBAEzD,QAAA,EAAA;AAAA;AAAA;AAED;AAAA,SAAA;AAAA,QAxCK,MAAA,CAAO;AAAA,OAyCd;AAAA,IAEJ,CAAC,CAAA,EACH,CAAA;AAAA,oBAEAA,cAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAU,qKAAA;AAAA,QACV,OAAA,EAAS,OAAA;AAAA,QACV,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EACF,CAAA;AAEJ;AC9HO,IAAM,sBAAA,GAAyB,EAAA;AAc/B,SAAS,aAAA,CAAc;AAAA,EAC5B,OAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEA,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,CAAA,0GAAA,EACT,QAAA,GACI,8BAAA,GACA,YACN,CAAA,CAAA;AAAA,MACA,KAAA,EAAO,EAAE,KAAA,EAAO,sBAAA,EAAwB,UAAU,sBAAA,EAAuB;AAAA,MACzE,OAAA,EAAS,CAAC,KAAA,KAAU,KAAA,CAAM,eAAA,EAAgB;AAAA,MAC1C,aAAA,EAAe,CAAC,KAAA,KAAU,KAAA,CAAM,eAAA,EAAgB;AAAA,MAEhD,QAAA,kBAAAA,cAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,UAAA;AAAA,UACL,SAAA,EAAU,6CAAA;AAAA,UACV,OAAA;AAAA,UACA,YAAA,EAAY,KAAA,KAAU,QAAA,GAAW,iBAAA,GAAoB,YAAA,CAAA;AAAA,UACrD,GAAA,EAAK,CAAC,IAAA,KAAS;AACb,YAAA,IAAI,IAAA,EAAM,IAAA,CAAK,aAAA,GAAgB,aAAA,KAAkB,IAAA;AAAA,UACnD,CAAA;AAAA,UACA,UAAU,MAAM,MAAA;AAAA,UAChB,OAAA,EAAS,CAAC,KAAA,KAAU,QAAA,CAAS,MAAM,QAAQ;AAAA;AAAA;AAC7C;AAAA,GACF;AAEJ;AChCA,IAAM,gBAAA,GACJ,kLAAA;AAQF,SAAS,YAAA,CAAa;AAAA,EACpB,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKG;AACD,EAAA,MAAM,aAAa,IAAA,KAAS,MAAA;AAC5B,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIN,cAAAA;AAAA,IACxB,MAAA,EAAQ,UAAA,KAAe,MAAA,GAAU,MAAA,CAAO,UAAU,EAAA,GAAM;AAAA,GAC1D;AAGA,EAAAG,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAA,EAAY;AACjB,IAAA,QAAA,CAAS,QAAQ,UAAA,KAAe,MAAA,GAAU,MAAA,CAAO,MAAA,IAAU,KAAM,EAAE,CAAA;AAAA,EACrE,CAAA,EAAG,CAAC,MAAA,EAAQ,UAAU,CAAC,CAAA;AAEvB,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,MAAM,OAAA,GAAU,MAAA,GAAS,cAAA,CAAe,MAAM,CAAA,GAAI,EAAA;AAClD,IAAA,uBACEG,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAU,sJAAA;AAAA,QACV,KAAA,EAAO,OAAA;AAAA,QAEN,qCAAWA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAa,QAAA,EAAA,IAAA,EAAE;AAAA;AAAA,KAC7C;AAAA,EAEJ;AAEA,EAAA,uBACEA,cAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAA,EAAW,gBAAA;AAAA,MACX,KAAA,EAAO,KAAA;AAAA,MACP,YAAA,EAAY,UAAU,KAAK,CAAA,CAAA;AAAA,MAC3B,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,QAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,KAAA;AAC1B,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,cAAA,CAAe,KAAA,EAAO,eAAA,CAAgB,UAAA,EAAY,IAAI,CAAC,CAAA;AAAA,MACzD;AAAA;AAAA,GACF;AAEJ;AAEO,SAAS,iBAAA,CAAwB;AAAA,EACtC,MAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAAiC;AAC/B,EAAA,uBACED,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,KAAA;AAAA,MACL,SAAA,EAAU,+FAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,MAAA;AAAA,QACA,KAAA,EAAO,MAAA,CAAO,UAAA,IAAc,UAAA,GAAa,sBAAA,GAAyB,CAAA;AAAA,OACpE;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,UAAA,oBACCC,cAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,sGAAA;AAAA,YACV,KAAA,EAAO,EAAE,KAAA,EAAO,sBAAA,EAAwB,UAAU,sBAAA;AAAuB;AAAA,SAC3E;AAAA,QAGD,MAAA,CAAO,MAAM,GAAA,CAAI,CAAC,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,YAAA,EAAa,KAAM;AAC7D,UAAA,MAAM,KAAA,GAA6B;AAAA,YACjC,KAAA;AAAA,YACA,QAAA,EAAU,KAAA;AAAA,YACV,QAAA,EAAU,KAAA;AAAA,YACV,GAAI,WAAW,MAAA,GACX,EAAE,UAAU,QAAA,EAAU,IAAA,EAAM,cAAc,MAAA,EAAQ,CAAA,KAClD,MAAA,KAAW,OAAA,GACT,EAAE,QAAA,EAAU,QAAA,EAAU,OAAO,YAAA,EAAc,MAAA,EAAQ,GAAE,GACrD;AAAA,WACR;AAEA,UAAA,MAAM,SAAA,GACJ,MAAA,CAAO,MAAA,IAAU,CAAC,OAAO,YAAA,EAAc,sBAAA;AAEzC,UAAA,uBACEA,cAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,SAAA,EAAW,CAAA,4EAAA,EACT,MAAA,GAAS,6BAAA,GAAgC,EAC3C,CAAA,CAAA;AAAA,cACA,KAAA;AAAA,cAEC,QAAA,EAAA,SAAA,IAAa,MAAA,CAAO,MAAA,oBACnBA,cAAAA;AAAA,gBAAC,YAAA;AAAA,gBAAA;AAAA,kBACC,OAAO,MAAA,CAAO,KAAA;AAAA,kBACd,MAAM,MAAA,CAAO,MAAA;AAAA,kBACb,MAAA,EAAQ,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAAA,kBAChC;AAAA;AAAA;AACF,aAAA;AAAA,YAZG,MAAA,CAAO;AAAA,WAcd;AAAA,QAEJ,CAAC;AAAA;AAAA;AAAA,GACH;AAEJ;AC3GA,IAAM,WAAA,GACJ,8MAAA;AAIF,IAAM,YAAA,GACJ,+EAAA;AAEF,SAAS,aAAA,CAAc;AAAA,EACrB,KAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIN,cAAAA;AAAA,IAC5B,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,GAAI,YAAY;AAAC,GAC1C;AACA,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,IAAIA,cAAAA,CAAS,OAAO,cAAc,UAAU,CAAA;AAC1E,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,eAAS,EAAE,CAAA;AACvC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAAA;AAAA,IAC9B,MAAM,IAAI,GAAA,CAAI,KAAA,EAAO,eAAe,KAAA,GAAQ,KAAA,CAAM,MAAA,GAAS,EAAE;AAAA,GAC/D;AAEA,EAAAG,gBAAU,MAAM;AACd,IAAA,IAAI,OAAO,cAAc,UAAA,EAAY;AACnC,MAAA,UAAA,CAAW,MAAM,OAAA,CAAQ,SAAS,CAAA,GAAI,SAAA,GAAY,EAAE,CAAA;AACpD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,SAAA,EAAU,CACP,IAAA,CAAK,CAAC,MAAA,KAAW;AAChB,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,MAAM,CAAA;AAAA,IACnC,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AACX,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,EAAE,CAAA;AAAA,IAC/B,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,CAAC,SAAA,EAAW,YAAA,CAAa,KAAK,CAAA;AAAA,IACpC,CAAC,CAAA;AACH,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,QAAA,GAAWJ,cAAQ,MAAM;AAC7B,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,IAAA,EAAK,CAAE,WAAA,EAAY;AACzC,IAAA,OAAO,MAAA,GAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAY,CAAE,QAAA,CAAS,MAAM,CAAC,CAAA,GAAI,OAAA;AAAA,EAC5E,CAAA,EAAG,CAAC,OAAA,EAAS,MAAM,CAAC,CAAA;AAEpB,EAAA,MAAM,MAAA,GAAS,CAAC,MAAA,KAAmB;AACjC,IAAA,WAAA,CAAY,CAAC,OAAA,KAAY;AACvB,MAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,OAAO,CAAA;AAC5B,MAAA,IAAI,KAAK,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA,CAAK,OAAO,MAAM,CAAA;AAAA,WACnC,IAAA,CAAK,IAAI,MAAM,CAAA;AACpB,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACEM,gBAAAE,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAD,cAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAW,WAAA;AAAA,QACX,WAAA,EAAY,kBAAA;AAAA,QACZ,KAAA,EAAO,MAAA;AAAA,QACP,UAAU,CAAC,KAAA,KAAU,SAAA,CAAU,KAAA,CAAM,OAAO,KAAK;AAAA;AAAA,KACnD;AAAA,oBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8EAAA,EACZ,QAAA,EAAA;AAAA,MAAA,SAAA,oBACCC,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,gDAA+C,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,MAEvE,CAAC,SAAA,IAAa,QAAA,CAAS,MAAA,KAAW,CAAA,oBACjCA,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,8CAAA,EAA+C,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,MAEvE,QAAA,CAAS,GAAA,CAAI,CAAC,MAAA,qBACbD,eAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,mIAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAAC,cAAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,UAAA;AAAA,gBACL,SAAA,EAAU,8BAAA;AAAA,gBACV,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA;AAAA,gBAC5B,QAAA,EAAU,MAAM,MAAA,CAAO,MAAM;AAAA;AAAA,aAC/B;AAAA,4BACAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAY,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA,SAAA;AAAA,QAT9B;AAAA,OAWR;AAAA,KAAA,EACH,CAAA;AAAA,oBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAW,GAAG,YAAY,CAAA,yEAAA,CAAA;AAAA,UAC1B,SAAS,MAAM;AACb,YAAA,WAAA,iBAAY,IAAI,KAAK,CAAA;AACrB,YAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,UACd,CAAA;AAAA,UACD,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,sBACAA,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAW,GAAG,YAAY,CAAA,2CAAA,CAAA;AAAA,UAC1B,OAAA,EAAS,MAAM,OAAA,CAAQ,cAAA,CAAe,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAA;AAAA,UACrD,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;AAGO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,YAAA,GAAeJ,aAAuB,IAAI,CAAA;AAEhD,EAAA,MAAM,QACJ,IAAA,KAAS,MAAA,GACL,iBAAA,GACA,IAAA,KAAS,WACP,mBAAA,GACA,iBAAA;AAER,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIF,eAAiB,MAAM;AAC7C,IAAA,IAAI,KAAA,IAAS,KAAA,CAAM,UAAA,KAAe,KAAA,SAAc,KAAA,CAAM,IAAA;AACtD,IAAA,OAAO,MAAM,CAAC,CAAA;AAAA,EAChB,CAAC,CAAA;AAED,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAiB,MAAM;AACnD,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AACnB,IAAA,IAAI,KAAA,CAAM,UAAA,KAAe,MAAA,EAAQ,OAAO,MAAM,MAAA,IAAU,EAAA;AACxD,IAAA,IAAI,MAAM,UAAA,KAAe,QAAA,SAAiB,KAAA,CAAM,MAAA,EAAQ,UAAS,IAAK,EAAA;AACtE,IAAA,IAAI,KAAA,CAAM,UAAA,KAAe,MAAA,EAAQ,OAAO,MAAM,QAAA,IAAY,EAAA;AAC1D,IAAA,OAAO,EAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAiB,MAAM;AACvD,IAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AACnB,IAAA,IAAI,MAAM,UAAA,KAAe,QAAA,SAAiB,KAAA,CAAM,QAAA,EAAU,UAAS,IAAK,EAAA;AACxE,IAAA,IAAI,KAAA,CAAM,UAAA,KAAe,MAAA,EAAQ,OAAO,MAAM,MAAA,IAAU,EAAA;AACxD,IAAA,OAAO,EAAA;AAAA,EACT,CAAC,CAAA;AAGD,EAAAG,gBAAU,MAAM;AACd,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAsB;AAC3C,MAAA,IAAI,CAAC,YAAA,CAAa,OAAA,EAAS,SAAS,KAAA,CAAM,MAAc,GAAG,OAAA,EAAQ;AAAA,IACrE,CAAA;AACA,IAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAyB;AAC1C,MAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,QAAA,EAAU,OAAA,EAAQ;AAAA,IACtC,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,aAAa,CAAA;AACvD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,SAAS,CAAA;AAAA,IACnD,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,MAAA,OAAA,CAAQ,eAAA,CAAgB,IAAA,EAAe,OAAO,CAAC,CAAA;AAAA,IACjD,CAAA,MAAA,IAAW,SAAS,QAAA,EAAU;AAC5B,MAAA,OAAA,CAAQ,iBAAA,CAAkB,IAAA,EAAe,OAAA,EAAS,SAAS,CAAC,CAAA;AAAA,IAC9D,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,eAAA,CAAgB,IAAA,EAAe,OAAA,EAAS,SAAS,CAAC,CAAA;AAAA,IAC5D;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,YAAY,IAAA,KAAS,MAAA,GAAS,MAAA,GAAS,IAAA,KAAS,WAAW,QAAA,GAAW,MAAA;AAE5E,EAAA,uBACEG,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,YAAA;AAAA,MACL,SAAA,EAAU,mKAAA;AAAA,MACV,OAAA,EAAS,CAAC,KAAA,KAAU,KAAA,CAAM,eAAA,EAAgB;AAAA,MAEzC,QAAA,EAAA,IAAA,KAAS,KAAA,mBACRA,cAAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAc,SAAA,EAAsB,OAAA,EAAkB,CAAA,mBAErED,eAAAA,CAAAE,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAAD,cAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,WAAA;AAAA,YACX,KAAA,EAAO,IAAA;AAAA,YACP,UAAU,CAAC,KAAA,KAAU,OAAA,CAAQ,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,YAE9C,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,qBACVA,cAAAA,CAAC,QAAA,EAAA,EAAoB,KAAA,EAAO,MAAA,EACzB,QAAA,EAAA,kBAAA,CAAmB,MAAM,CAAA,IAAK,MAAA,EAAA,EADpB,MAEb,CACD;AAAA;AAAA,SACH;AAAA,QAEC,CAAC,aAAA,CAAc,IAAI,CAAA,oBAClBA,cAAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,SAAA;AAAA,YACN,SAAA,EAAW,WAAA;AAAA,YACX,KAAA,EAAO,OAAA;AAAA,YACP,SAAA,EAAS,IAAA;AAAA,YACT,WAAA,EAAY,OAAA;AAAA,YACZ,UAAU,CAAC,KAAA,KAAU,UAAA,CAAW,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,YAClD,SAAA,EAAW,CAAC,KAAA,KAAU;AACpB,cAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,OAAA,EAAS,KAAA,EAAM;AAAA,YACnC;AAAA;AAAA,SACF;AAAA,QAGD,aAAA,CAAc,IAAI,CAAA,oBACjBA,cAAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAM,SAAA;AAAA,YACN,SAAA,EAAW,WAAA;AAAA,YACX,KAAA,EAAO,SAAA;AAAA,YACP,WAAA,EAAY,IAAA;AAAA,YACZ,UAAU,CAAC,KAAA,KAAU,YAAA,CAAa,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,YACpD,SAAA,EAAW,CAAC,KAAA,KAAU;AACpB,cAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,OAAA,EAAS,KAAA,EAAM;AAAA,YACnC;AAAA;AAAA,SACF;AAAA,wBAGFD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4BAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,cAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAA,EAAW,GAAG,YAAY,CAAA,yEAAA,CAAA;AAAA,cAC1B,SAAS,MAAM;AACb,gBAAA,UAAA,CAAW,EAAE,CAAA;AACb,gBAAA,YAAA,CAAa,EAAE,CAAA;AACf,gBAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,cACd,CAAA;AAAA,cACD,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAA,cAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAA,EAAW,GAAG,YAAY,CAAA,2CAAA,CAAA;AAAA,cAC1B,OAAA,EAAS,KAAA;AAAA,cACV,QAAA,EAAA;AAAA;AAAA;AAED,SAAA,EACF;AAAA,OAAA,EACF;AAAA;AAAA,GAEJ;AAEJ;ACzPA,SAAS,aAAA,CAAc;AAAA,EACrB,SAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,uBACEA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,qDAAA,EAAsD,aAAA,EAAW,MAAC,QAAA,EAAA,QAAA,EAElF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACED,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAA,EAAuD,eAAW,IAAA,EAC/E,QAAA,EAAA;AAAA,IAAA,SAAA,KAAc,QAAQ,QAAA,GAAM,QAAA;AAAA,IAC5B,6BAAaC,cAAAA,CAAC,SAAI,SAAA,EAAU,mBAAA,EAAqB,kBAAQ,CAAA,EAAE;AAAA,GAAA,EAC9D,CAAA;AAEJ;AAEO,SAAS,UAAA,CAAiB;AAAA,EAC/B,MAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIN,eAAwB,IAAI,CAAA;AAChE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAC5D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAI9D,EAAA,MAAM,SAAA,GAAYE,YAAAA;AAAA,IAChB;AAAA,GACF;AAEA,EAAA,MAAM,WAAA,GAAcD,iBAAAA;AAAA,IAClB,CAAC,OAA2B,IAAA,KAAiC;AAC3D,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,MAAA,SAAA,CAAU,OAAA,GAAU;AAAA,QAClB,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,QAAQ,KAAA,CAAM,OAAA;AAAA,QACd,YAAY,IAAA,CAAK;AAAA,OACnB;AACA,MAAC,KAAA,CAAM,MAAA,CAAuB,iBAAA,CAAkB,KAAA,CAAM,SAAS,CAAA;AAAA,IACjE,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,YAAA,GAAeA,iBAAAA;AAAA,IACnB,CAAC,KAAA,KAA8B;AAC7B,MAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAO,MAAA;AACrC,MAAA,QAAA,CAAS,MAAA,CAAO,OAAO,IAAA,CAAK,GAAA,CAAI,IAAI,MAAA,CAAO,UAAA,GAAa,KAAK,CAAC,CAAA;AAAA,IAChE,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAY,CAAC,KAAA,KAA8B;AAC3D,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AACxB,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAC,KAAA,CAAM,MAAA,CAAuB,qBAAA,CAAsB,KAAA,CAAM,SAAS,CAAA;AAAA,EACrE,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KACnB,SAAA,CAAU,UAAU,CAAC,KAAA,KAAU,KAAA,CAAM,KAAA,KAAU,KAAK,CAAA;AAEtD,EAAA,uBACEI,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,KAAA;AAAA,MACL,SAAA,EAAU,mGAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,MAAA,EAAQ,YAAA;AAAA,QACR,KAAA,EAAO,MAAA,CAAO,UAAA,IAAc,UAAA,GAAa,sBAAA,GAAyB,CAAA;AAAA,OACpE;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,UAAA,oBACCC,cAAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,QAAA,EAAQ,IAAA;AAAA,YACR,OAAA,EAAS,WAAA;AAAA,YACT,aAAA,EAAe,YAAA;AAAA,YACf,QAAA,EAAU,WAAA;AAAA,YACV,KAAA,EAAM;AAAA;AAAA,SACR;AAAA,QAGD,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AACjC,UAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,cAAa,GAAI,IAAA;AAChD,UAAA,MAAM,SAAA,GAAY,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAC1C,UAAA,MAAM,YAAY,SAAA,KAAc,EAAA,GAAK,MAAA,GAAY,SAAA,CAAU,SAAS,CAAA,CAAE,IAAA;AACtE,UAAA,MAAM,YAAA,GAAe,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAC7C,UAAA,MAAM,aAAa,MAAA,CAAO,MAAA;AAE1B,UAAA,MAAM,KAAA,GAA6B;AAAA,YACjC,KAAA;AAAA,YACA,QAAA,EAAU,KAAA;AAAA,YACV,QAAA,EAAU,KAAA;AAAA,YACV,GAAI,WAAW,MAAA,GACX,EAAE,UAAU,QAAA,EAAU,IAAA,EAAM,cAAc,MAAA,EAAQ,CAAA,KAClD,MAAA,KAAW,OAAA,GACT,EAAE,QAAA,EAAU,QAAA,EAAU,OAAO,YAAA,EAAc,MAAA,EAAQ,GAAE,GACrD;AAAA,WACR;AAEA,UAAA,uBACED,eAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,IAAA,EAAK,cAAA;AAAA,cACL,aACE,SAAA,KAAc,KAAA,GACV,WAAA,GACA,SAAA,KAAc,SACZ,YAAA,GACA,MAAA;AAAA,cAER,iBAAe,KAAA,GAAQ,CAAA;AAAA,cACvB,SAAA,EAAW,CAAA,wHAAA,EACT,SAAA,KAAc,MAAA,CAAO,KAAA,GAAQ,eAAe,EAC9C,CAAA,CAAA,EAAI,MAAA,CAAO,eAAA,IAAmB,EAAE,CAAA,CAAA;AAAA,cAChC,KAAA;AAAA,cACA,SAAA,EAAW,CAAC,MAAA,CAAO,YAAA;AAAA,cACnB,WAAA,EAAa,CAAC,KAAA,KAAU;AACtB,gBAAA,YAAA,CAAa,OAAO,KAAK,CAAA;AACzB,gBAAA,KAAA,CAAM,aAAa,aAAA,GAAgB,MAAA;AAAA,cACrC,CAAA;AAAA,cACA,UAAA,EAAY,CAAC,KAAA,KAAU;AACrB,gBAAA,IAAI,SAAA,IAAa,SAAA,KAAc,MAAA,CAAO,KAAA,QAAa,cAAA,EAAe;AAAA,cACpE,CAAA;AAAA,cACA,MAAA,EAAQ,CAAC,KAAA,KAAU;AACjB,gBAAA,KAAA,CAAM,cAAA,EAAe;AACrB,gBAAA,IAAI,aAAa,SAAA,KAAc,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,WAAW,KAAK,CAAA;AACpE,gBAAA,YAAA,CAAa,IAAI,CAAA;AAAA,cACnB,CAAA;AAAA,cACA,SAAA,EAAW,MAAM,YAAA,CAAa,IAAI,CAAA;AAAA,cAElC,QAAA,EAAA;AAAA,gCAAAA,eAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,SAAA,EAAU,gJAAA;AAAA,oBACV,QAAA,EAAU,CAAC,MAAA,CAAO,QAAA;AAAA,oBAClB,OAAA,EAAS,CAAC,KAAA,KAAU,MAAA,CAAO,YAAY,MAAA,CAAO,MAAA,CAAO,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA;AAAA,oBAC1E,KAAA,EAAO,MAAA,CAAO,QAAA,GAAW,2BAAA,GAA8B,MAAA;AAAA,oBAEvD,QAAA,EAAA;AAAA,sCAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,iBAAO,MAAA,EAAO,CAAA;AAAA,sBACzC,MAAA,CAAO,4BACNA,cAAAA;AAAA,wBAAC,aAAA;AAAA,wBAAA;AAAA,0BACC,SAAA;AAAA,0BACA,KAAA,EAAO,SAAA;AAAA,0BACP,SAAA,EAAW,UAAU,MAAA,GAAS;AAAA;AAAA;AAChC;AAAA;AAAA,iBAEJ;AAAA,gBAEC,8BACCA,cAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,YAAA,EAAY,CAAA,OAAA,EAAU,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,oBAClC,SAAA,EAAW,CAAA,oDAAA,EACT,YAAA,GACI,oCAAA,GACA,iDACN,CAAA,CAAA;AAAA,oBACA,KAAA,EAAO,YAAA,GAAe,cAAA,CAAe,YAAY,CAAA,GAAI,QAAA;AAAA,oBACrD,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,sBAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,sBAAA,WAAA,CAAY,IAAI,CAAA;AAChB,sBAAA,aAAA;AAAA,wBAAc,CAAC,OAAA,KACb,OAAA,KAAY,MAAA,CAAO,KAAA,GAAQ,OAAO,MAAA,CAAO;AAAA,uBAC3C;AAAA,oBACF,CAAA;AAAA,oBACD,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gCAGFA,cAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,QAAA;AAAA,oBACL,YAAA,EAAY,CAAA,YAAA,EAAe,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,oBACvC,SAAA,EAAU,uGAAA;AAAA,oBACV,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,sBAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,sBAAA,aAAA,CAAc,IAAI,CAAA;AAClB,sBAAA,WAAA,CAAY,CAAC,OAAA,KAAa,OAAA,KAAY,OAAO,KAAA,GAAQ,IAAA,GAAO,OAAO,KAAM,CAAA;AAAA,oBAC3E,CAAA;AAAA,oBACD,QAAA,EAAA;AAAA;AAAA,iBAED;AAAA,gBAEC,UAAA,KAAe,MAAA,CAAO,KAAA,IAAS,UAAA,oBAC9BA,cAAAA;AAAA,kBAAC,aAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAM,UAAA;AAAA,oBACN,KAAA,EAAO,YAAA;AAAA,oBACP,SAAA,EAAW,OAAO,YAAA,EAAc,MAAA;AAAA,oBAChC,OAAA,EAAS,CAAC,MAAA,KAAW;AACnB,sBAAA,cAAA,CAAe,MAAA,CAAO,OAAO,MAAM,CAAA;AACnC,sBAAA,aAAA,CAAc,IAAI,CAAA;AAAA,oBACpB,CAAA;AAAA,oBACA,OAAA,EAAS,MAAM,aAAA,CAAc,IAAI;AAAA;AAAA,iBACnC;AAAA,gBAGD,QAAA,KAAa,MAAA,CAAO,KAAA,oBACnBA,cAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,gJAAA;AAAA,oBACV,YAAA,EAAc,MAAM,WAAA,CAAY,IAAI,CAAA;AAAA,oBAElC,WAAC,MAAA,EAAQ,OAAO,EAAY,GAAA,CAAI,CAAC,yBACjCA,cAAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBAEC,IAAA,EAAK,QAAA;AAAA,wBACL,SAAA,EAAU,mHAAA;AAAA,wBACV,SAAS,MAAM;AACb,0BAAA,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,MAAA,KAAW,IAAA,GAAO,SAAY,IAAI,CAAA;AACtD,0BAAA,WAAA,CAAY,IAAI,CAAA;AAAA,wBAClB,CAAA;AAAA,wBAEC,qBAAW,IAAA,GAAO,CAAA,MAAA,EAAS,IAAI,CAAA,CAAA,GAAK,OAAO,IAAI,CAAA;AAAA,uBAAA;AAAA,sBAR3C;AAAA,qBAUR;AAAA;AAAA,iBACH;AAAA,gBAGD,MAAA,CAAO,6BACNA,cAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,WAAA;AAAA,oBACL,kBAAA,EAAiB,UAAA;AAAA,oBACjB,SAAA,EAAU,wEAAA;AAAA,oBACV,aAAA,EAAe,CAAC,KAAA,KAAU,WAAA,CAAY,OAAO,IAAI,CAAA;AAAA,oBACjD,aAAA,EAAe,YAAA;AAAA,oBACf,WAAA,EAAa,SAAA;AAAA,oBACb,eAAA,EAAiB,SAAA;AAAA,oBACjB,OAAA,EAAS,CAAC,KAAA,KAAU,KAAA,CAAM,eAAA;AAAgB;AAAA;AAC5C;AAAA,aAAA;AAAA,YA7HG,MAAA,CAAO;AAAA,WA+Hd;AAAA,QAEJ,CAAC;AAAA;AAAA;AAAA,GACH;AAEJ;AChRO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAM,OAAA,EAAQ,EAAqB;AAC/D,EAAA,IAAI,SAAS,SAAA,EAAW;AACtB,IAAA,uBACEA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oHACb,QAAA,kBAAAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+KAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kFAAA,EAAmF,CAAA;AAAA,MAClG,OAAA,IAAW;AAAA,KAAA,EACd,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,SAAS,OAAA,EAAS;AACpB,IAAA,uBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8FAAA,EACb,QAAA,kBAAAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yJAAA,EACZ,QAAA,EAAA,OAAA,IAAW,yCAAA,EACd,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8DAAA,EACb,QAAA,kBAAAA,cAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0CAAA,EACV,QAAA,EAAA,OAAA,IAAW,kBAAA,EACd,CAAA,EACF,CAAA;AAEJ;AC9BA,IAAME,aAAAA,GACJ,oNAAA;AAIK,SAAS,cAAA,CAAe;AAAA,EAC7B,IAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,IAAA,CAAK,SAAA,GAAY,QAAQ,CAAC,CAAA;AAC7D,EAAA,MAAM,KAAA,GAAQ,SAAA,KAAc,CAAA,GAAI,CAAA,GAAI,OAAO,QAAA,GAAW,CAAA;AACtD,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,SAAA,EAAA,CAAY,IAAA,GAAO,KAAK,QAAQ,CAAA;AAEtD,EAAA,uBACEH,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4IAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAAA,eAAAA,CAAC,OAAA,EAAA,EAAM,SAAA,EAAU,0CAAA,EAA2C,QAAA,EAAA;AAAA,QAAA,MAAA;AAAA,wBAE1DC,cAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,2HAAA;AAAA,YACV,KAAA,EAAO,QAAA;AAAA,YACP,QAAA,EAAU,CAAC,KAAA,KAAU,gBAAA,CAAiB,OAAO,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,YAE/D,QAAA,EAAA,eAAA,CAAgB,GAAA,CAAI,CAAC,MAAA,qBACpBA,cAAAA,CAAC,QAAA,EAAA,EAAoB,KAAA,EAAO,MAAA,EACzB,QAAA,EAAA,MAAA,EAAA,EADU,MAEb,CACD;AAAA;AAAA;AACH,OAAA,EACF,CAAA;AAAA,sBAEAA,cAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EACb,QAAA,EAAA,SAAA,GAAY,YAAA,GAAe,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,IAAA,EAAO,SAAS,CAAA,CAAA,EAC9D;AAAA,KAAA,EACF,CAAA;AAAA,oBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACb,QAAA,EAAA;AAAA,sBAAAC,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAWE,aAAAA;AAAA,UACX,UAAU,IAAA,KAAS,CAAA;AAAA,UACnB,OAAA,EAAS,MAAM,YAAA,CAAa,CAAC,CAAA;AAAA,UAC9B,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,sBACAF,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAWE,aAAAA;AAAA,UACX,UAAU,IAAA,KAAS,CAAA;AAAA,UACnB,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA,GAAO,CAAC,CAAA;AAAA,UACrC,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,sBACAH,eAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+CAAA,EAAgD,QAAA,EAAA;AAAA,QAAA,OAAA;AAAA,QACxD,IAAA,GAAO,CAAA;AAAA,QAAE,MAAA;AAAA,QAAK;AAAA,OAAA,EACtB,CAAA;AAAA,sBACAC,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAWE,aAAAA;AAAA,UACX,QAAA,EAAU,OAAO,CAAA,IAAK,SAAA;AAAA,UACtB,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA,GAAO,CAAC,CAAA;AAAA,UACrC,QAAA,EAAA;AAAA;AAAA,OAED;AAAA,sBACAF,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAWE,aAAAA;AAAA,UACX,QAAA,EAAU,OAAO,CAAA,IAAK,SAAA;AAAA,UACtB,OAAA,EAAS,MAAM,YAAA,CAAa,SAAA,GAAY,CAAC,CAAA;AAAA,UAC1C,QAAA,EAAA;AAAA;AAAA;AAED,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;ACxFA,IAAM,WAAA,GACJ,gNAAA;AAKF,IAAM,WAAA,GAAc,iEAAA;AAEpB,SAAS,UAAU,KAAA,EAAwB;AACzC,EAAA,OAAO,KAAA,GAAQ,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,GAAK,WAAA;AACnD;AAGA,SAAS,WAAW,MAAA,EAAwD;AAC1E,EAAA,OAAO,CAAC,KAAA,KAA+B;AACrC,IAAA,IAAI,KAAA,CAAM,QAAQ,OAAA,EAAS;AACzB,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,MAAA,MAAA,CAAO,QAAA,EAAS;AAAA,IAClB,CAAA,MAAA,IAAW,KAAA,CAAM,GAAA,KAAQ,QAAA,EAAU;AACjC,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,MAAA,MAAA,CAAO,QAAA,EAAS;AAAA,IAClB;AAAA,EACF,CAAA;AACF;AAEO,SAAS,UAAA,CAAiB;AAAA,EAC/B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEF,cAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,SAAA,EAAW,UAAU,KAAK,CAAA;AAAA,MAC1B,KAAA,EAAO,KAAA,IAAS,IAAA,GAAO,EAAA,GAAK,OAAO,KAAK,CAAA;AAAA,MACxC,SAAA;AAAA,MACA,WAAA,EAAa,OAAO,YAAA,EAAc,WAAA;AAAA,MAClC,KAAA,EAAO,KAAA;AAAA,MACP,cAAA,EAAc,QAAQ,IAAA,GAAO,MAAA;AAAA,MAC7B,UAAU,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,MAChD,SAAA,EAAW,UAAA,CAAW,EAAE,QAAA,EAAU,UAAU;AAAA;AAAA,GAC9C;AAEJ;AAEO,SAAS,YAAA,CAAmB;AAAA,EACjC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEA,cAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,SAAA,EAAW,UAAU,KAAK,CAAA;AAAA,MAC1B,KAAA,EAAO,KAAA,IAAS,IAAA,GAAO,EAAA,GAAK,OAAO,KAAK,CAAA;AAAA,MACxC,SAAA;AAAA,MACA,KAAA,EAAO,KAAA;AAAA,MACP,cAAA,EAAc,QAAQ,IAAA,GAAO,MAAA;AAAA,MAC7B,QAAA,EAAU,CAAC,KAAA,KACT,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,KAAA,KAAU,EAAA,GAAK,IAAA,GAAO,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MAExE,SAAA,EAAW,UAAA,CAAW,EAAE,QAAA,EAAU,UAAU;AAAA;AAAA,GAC9C;AAEJ;AAEO,SAAS,UAAA,CAAiB;AAAA,EAC/B,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAAuB;AAGrB,EAAA,MAAM,gBAAgB,MAAM;AAC1B,IAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,KAAA,KAAU,EAAA,EAAI,OAAO,EAAA;AAC1C,IAAA,MAAM,IAAA,GAAO,iBAAiB,IAAA,GAAO,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AACnE,IAAA,OAAO,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,CAAA,GAAI,EAAA,GAAK,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,EAC3E,CAAA,GAAG;AAEH,EAAA,uBACEA,cAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,SAAA,EAAW,UAAU,KAAK,CAAA;AAAA,MAC1B,KAAA,EAAO,YAAA;AAAA,MACP,SAAA;AAAA,MACA,KAAA,EAAO,KAAA;AAAA,MACP,cAAA,EAAc,QAAQ,IAAA,GAAO,MAAA;AAAA,MAC7B,QAAA,EAAU,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,CAAM,MAAA,CAAO,KAAA,KAAU,EAAA,GAAK,IAAA,GAAO,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA;AAAA,MACnF,SAAA,EAAW,UAAA,CAAW,EAAE,QAAA,EAAU,UAAU;AAAA;AAAA,GAC9C;AAEJ;AAEO,SAAS,YAAA,CAAmB;AAAA,EACjC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,YAAA,EAAc,OAAA,IAAW,EAAC;AACjD,EAAA,MAAM,gBAAgB,OAAA,CAAQ,SAAA,CAAU,CAAC,MAAA,KAAW,MAAA,CAAO,UAAU,KAAK,CAAA;AAE1E,EAAA,uBACED,eAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,UAAU,KAAK,CAAA;AAAA,MAC1B,KAAA,EAAO,aAAA,KAAkB,EAAA,GAAK,EAAA,GAAK,OAAO,aAAa,CAAA;AAAA,MACvD,SAAA;AAAA,MACA,KAAA,EAAO,KAAA;AAAA,MACP,cAAA,EAAc,QAAQ,IAAA,GAAO,MAAA;AAAA,MAC7B,QAAA,EAAU,CAAC,KAAA,KAAU;AACnB,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA;AACvC,QAAA,QAAA,CAAS,MAAA,CAAO,MAAM,KAAK,CAAA,GAAI,OAAO,OAAA,CAAQ,KAAK,CAAA,EAAG,KAAA,IAAS,IAAI,CAAA;AAAA,MACrE,CAAA;AAAA,MACA,SAAA,EAAW,UAAA,CAAW,EAAE,QAAA,EAAU,UAAU,CAAA;AAAA,MAE5C,QAAA,EAAA;AAAA,wBAAAC,cAAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,EAAA,EAAG,QAAA,EAAA,IAAA,EAAE,CAAA;AAAA,QAClB,OAAA,CAAQ,IAAI,CAAC,MAAA,EAAQ,0BACpBA,cAAAA,CAAC,YAAgD,KAAA,EAAO,KAAA,EACrD,iBAAO,KAAA,EAAA,EADG,CAAA,EAAG,OAAO,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,EAAI,KAAK,EAE7C,CACD;AAAA;AAAA;AAAA,GACH;AAEJ;AAEO,SAAS,cAAA,CAAqB;AAAA,EACnC,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,uBACEA,cAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,UAAA;AAAA,MACL,SAAA,EAAU,0BAAA;AAAA,MACV,SAAS,KAAA,KAAU,IAAA;AAAA,MACnB,SAAA;AAAA,MACA,UAAU,CAAC,KAAA,KAAU,QAAA,CAAS,KAAA,CAAM,OAAO,OAAO,CAAA;AAAA,MAClD,SAAA,EAAW,UAAA,CAAW,EAAE,QAAA,EAAU,UAAU;AAAA;AAAA,GAC9C;AAEJ;;;ACtJO,IAAM,eAAA,GAAkB;AAAA,EAC7B,IAAA,EAAM,UAAA;AAAA,EACN,MAAA,EAAQ,YAAA;AAAA,EACR,IAAA,EAAM,UAAA;AAAA,EACN,MAAA,EAAQ,YAAA;AAAA,EACR,QAAA,EAAU;AACZ;ACKA,IAAM,WAAA,GAAc;AAAA,EAClB,IAAA,EAAM,yBAAA;AAAA,EACN,MAAA,EAAQ,4BAAA;AAAA,EACR,KAAA,EAAO;AACT,CAAA;AAEA,SAAS,aAAA,CAAoB;AAAA,EAC3B,IAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,cAAa,GAAI,IAAA;AAEhD,EAAA,MAAM,KAAA,GAA6B;AAAA,IACjC,KAAA;AAAA,IACA,QAAA,EAAU,KAAA;AAAA,IACV,QAAA,EAAU,KAAA;AAAA,IACV,GAAI,WAAW,MAAA,GACX,EAAE,UAAU,QAAA,EAAU,IAAA,EAAM,cAAc,MAAA,EAAQ,CAAA,KAClD,MAAA,KAAW,OAAA,GACT,EAAE,QAAA,EAAU,QAAA,EAAU,OAAO,YAAA,EAAc,MAAA,EAAQ,GAAE,GACrD;AAAA,GACR;AAEA,EAAA,MAAM,MAAA,GACJ,OAAO,MAAA,CAAO,aAAA,KAAkB,aAC5B,MAAA,CAAO,aAAA,CAAc,GAAG,CAAA,GACxB,MAAA,CAAO,aAAA;AAEb,EAAA,MAAM,IAAA,GACJ,6HAAA,IAEC,MAAA,GAAS,4BAAA,GAA+B,EAAA,CAAA;AAE3C,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,MAAA,CAAO,KAAA,IAAS,MAAM,CAAA;AAIpD,EAAA,MAAM,UAAU,YAAA,IAAgB,KAAA,IAAS,IAAA,IAAQ,UAAA,CAAW,QAAQ,GAAG,CAAA;AAEvE,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA;AACrC,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,KAAA,EAAO,MAAe,CAAA;AAEvD,IAAA,MAAM,MAAA,GACJ,OAAO,MAAA,CAAO,MAAA,KAAW,UAAA,GACrB,OAAO,MAAA,GACP,eAAA,CAAgB,MAAA,CAAO,MAAA,IAAU,MAAM,CAAA;AAE7C,IAAA,uBACEA,cAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,UAAA;AAAA,QACL,WAAW,CAAA,EAAG,IAAI,IAAI,SAAS,CAAA,CAAA,EAAI,UAAU,EAAE,CAAA,CAAA;AAAA,QAC/C,KAAA;AAAA,QACA,eAAa,MAAA,CAAO,KAAA;AAAA,QAEpB,QAAA,kBAAAA,cAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,WAAA;AAAA,YACP,GAAA,EAAK,KAAA;AAAA,YACL,MAAA;AAAA,YACA,OAAA;AAAA,YACA,KAAA;AAAA,YACA,SAAA,EAAW,eAAA;AAAA,YACX,QAAA,EAAU,CAACG,MAAAA,KAAmB,aAAA,CAAc,OAAOA,MAAK,CAAA;AAAA,YACxD,QAAA;AAAA,YACA;AAAA;AAAA;AACF;AAAA,KACF;AAAA,EAEJ;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,GAAA,EAAK,MAAe,CAAA;AAC/C,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,KAAA,EAAO,GAAA,EAAK,MAAe,CAAA;AAEzD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,YAAA,GACnB,MAAA,CAAO,YAAA,CAAa;AAAA,IAClB,GAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACD,CAAA,GACD,SAAA;AAEJ,EAAA,uBACEH,cAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,UAAA;AAAA,MACL,WAAW,CAAA,EAAG,IAAI,IAAI,SAAS,CAAA,CAAA,EAAI,UAAU,EAAE,CAAA,CAAA;AAAA,MAC/C,KAAA;AAAA,MACA,eAAa,MAAA,CAAO,KAAA;AAAA,MACpB,KAAA,EAAO,MAAA,CAAO,YAAA,GAAe,MAAA,GAAY,SAAA,IAAa,MAAA;AAAA,MAErD,QAAA,EAAA,MAAA,CAAO,eACN,OAAA,mBAEAA,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAY,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA,GAE1C;AAEJ;AAOO,IAAM,QAAA,GAAWI,WAAK,aAAa,CAAA;AC3G1C,SAAS,YAAA,CAAmB;AAAA,EAC1B,GAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIV,eAAS,KAAK,CAAA;AACtD,EAAA,MAAM,WAAW,MAAA,CAAO,OAAA;AAIxB,EAAA,MAAM,kBAAA,GAAqB,YAAA,GACvB,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS,UAAA,CAAW,IAAA,CAAK,MAAA,EAAQ,GAAG,CAAC,GAAG,KAAA,GAC3D,MAAA;AAEJ,EAAA,MAAM,UAAA,GAAa,eACf,kCAAA,GACA,UAAA,GACE,qCACA,QAAA,GAAW,CAAA,KAAM,IACf,oCAAA,GACA,2BAAA;AAER,EAAA,uBACEK,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,KAAA;AAAA,MACL,iBAAe,QAAA,GAAW,CAAA;AAAA,MAC1B,eAAA,EAAe,aAAa,UAAA,GAAa,MAAA;AAAA,MACzC,SAAA,EAAW,CAAA,mEAAA,EAAsE,UAAU,CAAA,8CAAA,EACzF,QAAA,GAAW,eAAe,EAC5B,CAAA,CAAA,EACE,YAAA,GACI,8DAAA,GACA,EACN,CAAA,CAAA;AAAA,MACA,KAAA,EAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,OAAO,MAAA,CAAO,UAAA,IAAc,UAAA,GAAa,EAAA,GAAK,CAAA,CAAA,EAAG;AAAA,MACvE,aAAA,EAAe,MAAM,gBAAA,CAAiB,KAAA,EAAO,GAAG,CAAA;AAAA,MAChD,KAAA,EAAO,QAAA;AAAA,MACP,UAAA,EACE,cAAA,GACI,CAAC,KAAA,KAAU;AAET,QAAA,IAAI,CAAC,KAAA,CAAM,YAAA,CAAa,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,EAAG;AACjD,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,KAAA,CAAM,aAAa,UAAA,GAAa,MAAA;AAChC,QAAA,IAAI,CAAC,YAAA,EAAc,eAAA,CAAgB,IAAI,CAAA;AAAA,MACzC,CAAA,GACA,MAAA;AAAA,MAEN,WAAA,EAAa,cAAA,GAAiB,MAAM,eAAA,CAAgB,KAAK,CAAA,GAAI,MAAA;AAAA,MAC7D,MAAA,EACE,cAAA,GACI,CAAC,KAAA,KAAU;AACT,QAAA,IAAI,CAAC,KAAA,CAAM,YAAA,CAAa,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,EAAG;AACjD,QAAA,KAAA,CAAM,cAAA,EAAe;AACrB,QAAA,eAAA,CAAgB,KAAK,CAAA;AACrB,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,aAAa,KAAK,CAAA;AACjD,QAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,cAAA,CAAe,KAAK,KAAK,CAAA;AAAA,MACjD,CAAA,GACA,MAAA;AAAA,MAGL,QAAA,EAAA;AAAA,QAAA,UAAA,oBACCC,cAAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,UAAA;AAAA,YACT,UAAU,CAAC,QAAA,KAAa,cAAA,CAAe,KAAA,EAAO,UAAU,QAAQ;AAAA;AAAA,SAClE;AAAA,QAGD,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAC,yBACjBA,cAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA;AAAA,YACA,GAAA;AAAA,YACA,QAAA;AAAA,YACA,OAAA;AAAA,YACA,GAAA;AAAA,YACA,YAAA;AAAA,YACA,KAAA;AAAA,YACA,MAAA;AAAA,YACA,eAAA,EAAiB,KAAK,KAAA,KAAU,kBAAA;AAAA,YAChC,aAAA;AAAA,YACA,QAAA;AAAA,YACA;AAAA,WAAA;AAAA,UAZK,IAAA,CAAK;AAAA,SAcb;AAAA;AAAA;AAAA,GACH;AAEJ;AAEO,IAAM,OAAA,GAAUI,WAAK,YAAY,CAAA;AC9DxC,IAAM,kBAAA,GAAqB,CAAC,EAAA,EAAI,EAAA,EAAI,IAAI,GAAG,CAAA;AAEpC,SAAS,QAAA,CAAyB;AAAA,EACvC,OAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,YAAA,GAAe,EAAA;AAAA,EACf,cAAA,GAAiB,IAAA;AAAA,EACjB,UAAA,GAAa,IAAA;AAAA,EACb,eAAA,GAAkB,EAAA;AAAA,EAClB,eAAA,GAAkB,kBAAA;AAAA,EAClB,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA,GAAiB,QAAA;AAAA,EACjB,WAAAC,UAAAA,GAAY,EAAA;AAAA,EACZ,MAAA,GAAS,MAAA;AAAA,EACT;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,SAAA,GAAY,aAAa,UAAU,CAAA;AAEzC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIX,cAAAA;AAAA,IAChC,MAAM,SAAA,CAAU,OAAA,EAAS,IAAA,IAAQ;AAAC,GACpC;AACA,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,cAAAA;AAAA,IACpC,MAAM,SAAA,CAAU,OAAA,EAAS,OAAA,IAAW;AAAC,GACvC;AACA,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAAA;AAAA,IAC9B,MAAM,SAAA,CAAU,OAAA,EAAS,UAAA,CAAW,QAAA,IAAY;AAAA,GAClD;AACA,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAS,CAAC,CAAA;AAClC,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIA,eAAS,KAAK,CAAA;AAM9D,EAAA,MAAM,WAAA,GAAcE,aAAuB,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIF,eAAS,CAAC,CAAA;AAEpD,EAAA,MAAM,oBAAA,GAAuB,iBAAiB,EAAA,GAAK,CAAA;AAEnD,EAAAY,qBAAA,CAAgB,MAAM;AACpB,IAAA,MAAM,UAAU,WAAA,CAAY,OAAA;AAC5B,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,CAAC,OAAA,KAAY;AAC/C,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,WAAA;AACzB,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,gBAAA,CAAiB,KAAK,KAAK,CAAA;AAC3B,MAAA,oBAAA,CAAqB,OAAA;AAAA,QACnB,KAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,MAAA,GAAS,eAAe,oBAAoB;AAAA,OAC/D;AAAA,IACF,CAAC,CAAA;AAED,IAAA,QAAA,CAAS,QAAQ,OAAO,CAAA;AACxB,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,YAAA,EAAc,oBAAoB,CAAC,CAAA;AAMvC,EAAA,MAAM,WAAA,GAAc,cAAA;AAAA,IAClB,OAAA;AAAA,IACA,UAAU,OAAA,EAAS,OAAA;AAAA,IACnB,SAAA,CAAU,WAAA;AAAA,IACV,aAAA,IAAiB,aAAa,EAAA,GAAK,CAAA;AAAA,GACrC;AAMA,EAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAW,WAAW,KAAA,EAAO,OAAA,EAAS,WAAU,GAAI,mBAAA;AAAA,IAChE,EAAE,UAAA,EAAY,QAAA,EAAU,IAAA,EAAM,SAAA,EAAW,aAAa,OAAA;AAAQ,GAChE;AAIA,EAAAT,gBAAU,MAAM;AACd,IAAA,IAAI,SAAA,IAAa,cAAc,CAAA,EAAG;AAClC,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,IAAA,CAAK,SAAA,GAAY,QAAQ,CAAC,CAAA;AAC7D,IAAA,IAAI,IAAA,GAAO,SAAA,GAAY,CAAA,EAAG,OAAA,CAAQ,YAAY,CAAC,CAAA;AAAA,EACjD,GAAG,CAAC,SAAA,EAAW,QAAA,EAAU,IAAA,EAAM,SAAS,CAAC,CAAA;AAEzC,EAAA,MAAM,UAAU,cAAA,CAAe,EAAE,UAAU,IAAA,CAAK,MAAA,EAAQ,WAAW,CAAA;AAInE,EAAA,MAAM,oBAAA,GAAuBD,YAAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA;AAC7D,EAAA,oBAAA,CAAqB,UAAU,OAAA,CAAQ,iBAAA;AAMvC,EAAA,MAAM,SAAA,GAAY,iBAAA,CAAqB,IAAA,EAAM,QAAA,EAAU,kBAAkB,CAAA;AAEzE,EAAA,MAAM,UAAA,GAAaD,kBAAY,OAAwB,EAAE,IAAI,IAAA,EAAK,CAAA,EAAI,EAAE,CAAA;AACxE,EAAA,MAAM,OAAA,GAAU,YAAA,CAAgB,WAAA,IAAe,UAAU,CAAA;AAQzD,EAAA,MAAM,SAAA,GAAYA,iBAAAA;AAAA,IAChB,CAAC,IAAA,KAA0B;AACzB,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,SAAA,CAAU,SAAS,IAAI,CAAA;AACvB,MAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACX,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAEA,EAAA,MAAM,YAAA,GAAeA,iBAAAA;AAAA,IACnB,CAAC,IAAA,KAAyB;AACxB,MAAA,cAAA,CAAe,IAAI,CAAA;AACnB,MAAA,SAAA,CAAU,YAAY,IAAI,CAAA;AAC1B,MAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACX,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAEA,EAAA,MAAM,MAAA,GAASA,iBAAAA;AAAA,IACb,CAAC,OAAe,QAAA,KAAsB;AACpC,MAAA,MAAM,WAAW,SAAA,CAAU,IAAA,CAAK,CAAC,KAAA,KAAU,KAAA,CAAM,UAAU,KAAK,CAAA;AAChE,MAAA,MAAM,SAAS,SAAA,CAAU,MAAA,CAAO,CAAC,KAAA,KAAU,KAAA,CAAM,UAAU,KAAK,CAAA;AAGhE,MAAA,MAAM,IAAA,GAAwB,CAAC,QAAA,GAC3B,CAAC,GAAI,QAAA,GAAW,SAAA,GAAY,EAAC,EAAI,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,CAAA,GACvD,QAAA,CAAS,IAAA,KAAS,KAAA,GAChB,CAAC,GAAI,QAAA,GAAW,MAAA,GAAS,EAAC,EAAI,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,CAAA,GACrD,QAAA,GACE,SACA,EAAC;AAET,MAAA,SAAA,CAAU,IAAI,CAAA;AAAA,IAChB,CAAA;AAAA,IACA,CAAC,WAAW,SAAS;AAAA,GACvB;AAEA,EAAA,MAAM,cAAA,GAAiBA,iBAAAA;AAAA,IACrB,CAAC,OAAe,MAAA,KAAiC;AAC/C,MAAA,YAAA,CAAa,UAAA,CAAW,WAAA,EAAa,KAAA,EAAO,MAAM,CAAC,CAAA;AAAA,IACrD,CAAA;AAAA,IACA,CAAC,aAAa,YAAY;AAAA,GAC5B;AAEA,EAAA,MAAM,gBAAA,GAAmBA,iBAAAA;AAAA,IACvB,CAAC,IAAA,KAAiB;AAChB,MAAA,WAAA,CAAY,IAAI,CAAA;AAChB,MAAA,SAAA,CAAU,aAAa,IAAI,CAAA;AAC3B,MAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACX,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAQA,EAAA,MAAM,SAASC,YAAAA,CAAO;AAAA,IACpB,IAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EAAA,MAAA,CAAO,OAAA,GAAU;AAAA,IACf,IAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,GAAA,GAAMH,aAAAA;AAAA,IACV,OAAO;AAAA,MACL,OAAA,EAAS,CAAC,OAAA,KAAY,OAAA,CAAQ,OAAO,CAAA;AAAA,MACrC,gBAAA,EAAkB,MAAM,MAAA,CAAO,OAAA,CAAQ,IAAA;AAAA,MACvC,eAAA,EAAiB,MAAM,MAAA,CAAO,OAAA,CAAQ,UAAU,eAAA,EAAgB;AAAA,MAChE,gBAAgB,MAAM,CAAC,GAAG,MAAA,CAAO,OAAA,CAAQ,UAAU,WAAW,CAAA;AAAA,MAC9D,cAAA,EAAgB,MAAM,MAAA,CAAO,OAAA,CAAQ,UAAU,KAAA,EAAM;AAAA,MACrD,SAAA,EAAW,MAAM,MAAA,CAAO,OAAA,CAAQ,UAAU,gBAAA,EAAiB;AAAA,MAC3D,SAAA,EAAW,CAAC,OAAA,KAA+B;AACzC,QAAA,MAAM,MAAA,GAAS,SAAS,YAAA,GACpB,MAAA,CAAO,QAAQ,SAAA,CAAU,eAAA,EAAgB,GACzC,MAAA,CAAO,OAAA,CAAQ,IAAA;AACnB,QAAA,MAAM,GAAA,GAAM,KAAA;AAAA,UACV,MAAA;AAAA,UACA,MAAA,CAAO,QAAQ,WAAA,CAAY,cAAA;AAAA,UAC3B,SAAS,SAAA,IAAa;AAAA,SACxB;AACA,QAAA,WAAA,CAAY,GAAA,EAAK,OAAA,EAAS,QAAA,IAAY,cAAc,CAAA;AAAA,MACtD,CAAA;AAAA,MACA,0BAA0B,YAAY;AACpC,QAAA,MAAM,QAAA,GAAW,MAAA,CAAO,OAAA,CAAQ,SAAA,CAAU,eAAA,EAAgB;AAC1D,QAAA,MAAM,SAAS,QAAA,CAAS,MAAA,GAAS,CAAA,GAAI,QAAA,GAAW,OAAO,OAAA,CAAQ,IAAA;AAC/D,QAAA,MAAM,eAAA;AAAA,UACJ,KAAA,CAAM,MAAA,EAAQ,MAAA,CAAO,OAAA,CAAQ,YAAY,cAAuB;AAAA,SAClE;AAAA,MACF,CAAA;AAAA,MACA,cAAA,EAAgB,MAAM,MAAA,CAAO,OAAA,CAAQ,WAAA;AAAA,MACrC,cAAA,EAAgB,YAAA;AAAA,MAChB,YAAA,EAAc,MAAM,MAAA,CAAO,OAAA,CAAQ,SAAA;AAAA,MACnC,YAAA,EAAc,SAAA;AAAA,MACd,cAAc,MAAM;AAClB,QAAA,MAAA,CAAO,OAAA,CAAQ,YAAY,KAAA,EAAM;AACjC,QAAA,SAAA,CAAU,KAAA,EAAM;AAAA,MAClB,CAAA;AAAA,MACA,YAAY,CAAC,OAAA,KAAY,UAAU,OAAA,EAAS,MAAA,CAAO,QAAQ,QAAQ,CAAA;AAAA,MACnE,YAAA,EAAc,CAAC,KAAA,KAAU;AACvB,QAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,IAAA;AAAA,UAC9B,CAAC,SAAA,KAAc,MAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,KAAM;AAAA,SACxD;AACA,QAAA,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,MAClD,CAAA;AAAA,MACA,WAAA,EAAa,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,MAAA;AAAO,KACnD,CAAA;AAAA,IACA,CAAC,OAAA,EAAS,YAAA,EAAc,SAAA,EAAW,SAAA,EAAW,WAAW,cAAc;AAAA,GACzE;AAEA,EAAAc,yBAAA,CAAoB,MAAA,EAAQ,MAAM,GAAA,EAAK,CAAC,GAAG,CAAC,CAAA;AAM5C,EAAA,MAAM,gBAAA,GAAmBZ,iBAAAA;AAAA,IACvB,CAAC,OAAc,GAAA,KAAW;AACxB,MAAA,IAAI,WAAA,EAAa,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,GAAG,CAAA;AAAA,IAC3C,CAAA;AAAA,IACA,CAAC,aAAa,OAAO;AAAA,GACvB;AAKA,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,IAAA,EAAM,KAAA,IAAS,IAAA;AAC5C,EAAA,MAAM,aAAA,GAAgBC,YAAAA,CAAO,OAAA,CAAQ,MAAM,CAAA;AAC3C,EAAA,aAAA,CAAc,UAAU,OAAA,CAAQ,MAAA;AAEhC,EAAAC,gBAAU,MAAM;AACd,IAAA,IAAI,gBAAgB,IAAA,EAAM;AAC1B,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAsB;AAC3C,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,CAAQ,+BAA+B,CAAA,gBAAiB,OAAA,EAAQ;AAAA,IAC9E,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,aAAa,CAAA;AACpD,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,aAAa,CAAA;AAAA,EACtE,CAAA,EAAG,CAAC,YAAY,CAAC,CAAA;AAEjB,EAAA,MAAM,eAAeJ,aAAAA,CAAQ,OAAO,EAAC,CAAA,EAAS,EAAE,CAAA;AAChD,EAAA,MAAM,cAAc,OAAA,IAAW,YAAA;AAE/B,EAAA,MAAM,EAAE,UAAA,EAAY,QAAA,EAAS,GAAI,OAAA,CAAQ,MAAA;AACzC,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,UAAA,EAAY,QAAQ,CAAA;AAEnD,EAAA,MAAM,YAAY,CAAC,SAAA,IAAa,CAAC,KAAA,IAAS,KAAK,MAAA,KAAW,CAAA;AAE1D,EAAA,uBACEM,eAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,kHAAkHM,UAAS,CAAA,CAAA;AAAA,MAEtI,QAAA,EAAA;AAAA,wBAAAN,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,4HAAA,EACV,QAAA,EAAA;AAAA,UAAA,OAAA,GAAU,GAAG,CAAA;AAAA,0BACdA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iCAAA,EACb,QAAA,EAAA;AAAA,4BAAAC,cAAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,SAAA,EAAU,kJAAA;AAAA,gBACV,SAAS,MAAM,mBAAA,CAAoB,CAAC,OAAA,KAAY,CAAC,OAAO,CAAA;AAAA,gBACzD,QAAA,EAAA;AAAA;AAAA,aAED;AAAA,4BACAA,cAAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,SAAA,EAAU,kJAAA;AAAA,gBACV,OAAA,EAAS,MAAM,GAAA,CAAI,SAAA,EAAU;AAAA,gBAC9B,QAAA,EAAA;AAAA;AAAA;AAED,WAAA,EACF;AAAA,SAAA,EACJ,CAAA;AAAA,wBAEAD,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACZ,QAAA,EAAA;AAAA,UAAA,gBAAA,oBACCC,cAAAA;AAAA,YAAC,YAAA;AAAA,YAAA;AAAA,cACC,SAAS,WAAA,CAAY,UAAA;AAAA,cACrB,UAAU,WAAA,CAAY,QAAA;AAAA,cACtB,UAAU,WAAA,CAAY,SAAA;AAAA,cACtB,QAAQ,WAAA,CAAY,UAAA;AAAA,cACpB,OAAO,WAAA,CAAY,SAAA;AAAA,cACnB,SAAS,MAAM;AACb,gBAAA,WAAA,CAAY,KAAA,EAAM;AAClB,gBAAA,SAAA,CAAU,KAAA,EAAM;AAAA,cAClB,CAAA;AAAA,cACA,OAAA,EAAS,MAAM,mBAAA,CAAoB,KAAK;AAAA;AAAA,WAC1C;AAAA,0BAGFD,eAAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,WAAA;AAAA,cACL,IAAA,EAAK,MAAA;AAAA,cACL,eAAA,EAAe,SAAA;AAAA,cACf,eAAA,EAAe,WAAA,CAAY,MAAA,CAAO,KAAA,CAAM,MAAA;AAAA,cACxC,WAAA,EAAW,SAAA;AAAA,cACX,SAAA,EAAU,uCAAA;AAAA,cACV,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,cAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,cAElB,QAAA,EAAA;AAAA,gCAAAC,cAAAA;AAAA,kBAAC,UAAA;AAAA,kBAAA;AAAA,oBACC,QAAQ,WAAA,CAAY,MAAA;AAAA,oBACpB,SAAA;AAAA,oBACA,WAAA;AAAA,oBACA,YAAA;AAAA,oBACA,UAAA;AAAA,oBACA,aAAa,SAAA,CAAU,kBAAA;AAAA,oBACvB,cAAc,SAAA,CAAU,mBAAA;AAAA,oBACxB,aAAa,SAAA,CAAU,gBAAA;AAAA,oBACvB,MAAA;AAAA,oBACA,cAAA;AAAA,oBACA,UAAU,WAAA,CAAY,QAAA;AAAA,oBACtB,QAAQ,WAAA,CAAY,UAAA;AAAA,oBACpB,OAAO,WAAA,CAAY;AAAA;AAAA,iBACrB;AAAA,gBAEC,cAAA,oBACCA,cAAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,GAAA,EAAK,YAAA,EAAc,QAAA,EAAU,QAAA,EAAU,MAAA,EAAQ,CAAA,IAC3D,QAAA,kBAAAA,cAAAA;AAAA,kBAAC,iBAAA;AAAA,kBAAA;AAAA,oBACC,QAAQ,WAAA,CAAY,MAAA;AAAA,oBACpB,WAAA;AAAA,oBACA,MAAA,EAAQ,oBAAA;AAAA,oBACR,UAAA;AAAA,oBACA;AAAA;AAAA,iBACF,EACF,CAAA;AAAA,gCAIFA,cAAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,UAAA;AAAA,oBACV,KAAA,EAAO;AAAA,sBACL,QAAQ,OAAA,CAAQ,WAAA;AAAA,sBAChB,KAAA,EAAO,WAAA,CAAY,MAAA,CAAO,UAAA,IAAc,aAAa,EAAA,GAAK,CAAA;AAAA,qBAC5D;AAAA,oBAEC,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,GAAA,EAAK,MAAA,KAAW;AAChC,sBAAA,MAAM,WAAW,UAAA,GAAa,MAAA;AAC9B,sBAAA,MAAM,KAAA,GAAQ,SAAS,GAAG,CAAA;AAC1B,sBAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,IAAA,EAAM,KAAA,KAAU,KAAA;AAE7C,sBAAA,uBACEA,cAAAA;AAAA,wBAAC,KAAA;AAAA,wBAAA;AAAA,0BAEC,sBAAA,EAAsB,eAAe,MAAA,GAAS,MAAA;AAAA,0BAE9C,QAAA,kBAAAA,cAAAA;AAAA,4BAAC,OAAA;AAAA,4BAAA;AAAA,8BACC,GAAA;AAAA,8BACA,KAAA;AAAA,8BACA,QAAA;AAAA,8BACA,KAAK,QAAA,GAAW,SAAA;AAAA,8BAChB,MAAA,EAAQ,SAAA;AAAA,8BACR,QAAQ,WAAA,CAAY,MAAA;AAAA,8BACpB,OAAA,EAAS,WAAA;AAAA,8BACT,GAAA;AAAA,8BACA,UAAA;AAAA,8BACA,UAAA,EAAY,SAAA,CAAU,UAAA,CAAW,KAAK,CAAA;AAAA,8BACtC,YAAA;AAAA,8BACA,KAAA,EAAO,YAAA,GAAgB,OAAA,CAAQ,IAAA,EAAM,SAAS,IAAA,GAAQ,IAAA;AAAA,8BACtD,QAAQ,YAAA,GAAgB,OAAA,CAAQ,MAAM,MAAA,IAAU,KAAM,EAAC;AAAA,8BACvD,QAAA,EAAU,YAAA,IAAgB,OAAA,CAAQ,IAAA,EAAM,QAAA,KAAa,IAAA;AAAA,8BACrD,gBAAgB,SAAA,CAAU,SAAA;AAAA,8BAC1B,eAAe,OAAA,CAAQ,QAAA;AAAA,8BACvB,UAAU,OAAA,CAAQ,MAAA;AAAA,8BAClB,UAAU,OAAA,CAAQ,MAAA;AAAA,8BAClB,gBAAA;AAAA,8BACA,cAAA,EAAgB;AAAA;AAAA;AAClB,yBAAA;AAAA,wBAxBK;AAAA,uBAyBP;AAAA,oBAEJ,CAAC;AAAA;AAAA,iBACH;AAAA,gBAEC,SAAA,oBAAaA,cAAAA,CAAC,WAAA,EAAA,EAAY,MAAK,SAAA,EAAU,CAAA;AAAA,gBACzC,KAAA,IAAS,wBACRA,cAAAA;AAAA,kBAAC,WAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAK,OAAA;AAAA,oBACL,SAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA;AAAA,iBAChE;AAAA,gBAED,6BAAaA,cAAAA,CAAC,eAAY,IAAA,EAAK,OAAA,EAAQ,SAAS,YAAA,EAAc;AAAA;AAAA;AAAA;AACjE,SAAA,EACF,CAAA;AAAA,QAEC,QAAQ,IAAA,oBACPD,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,qIAAA,EACb,QAAA,EAAA;AAAA,0BAAAC,cAAAA,CAAC,UAAK,SAAA,EAAU,kDAAA,EACb,kBAAQ,IAAA,CAAK,MAAA,CAAO,WACnB,qDAAA,EACJ,CAAA;AAAA,0BACAA,cAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAA,EAAU,4HAAA;AAAA,cACV,SAAS,OAAA,CAAQ,MAAA;AAAA,cAClB,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAA,cAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,SAAA,EAAU,0GAAA;AAAA,cACV,QAAA,EAAU,QAAQ,IAAA,CAAK,QAAA;AAAA,cACvB,SAAS,OAAA,CAAQ,MAAA;AAAA,cAEhB,QAAA,EAAA,OAAA,CAAQ,IAAA,CAAK,QAAA,GAAW,WAAA,GAAc;AAAA;AAAA;AACzC,SAAA,EACF,CAAA;AAAA,wBAGFA,cAAAA;AAAA,UAAC,cAAA;AAAA,UAAA;AAAA,YACC,IAAA;AAAA,YACA,QAAA;AAAA,YACA,SAAA;AAAA,YACA,eAAA;AAAA,YACA,SAAA;AAAA,YACA,YAAA,EAAc,OAAA;AAAA,YACd;AAAA;AAAA;AACF;AAAA;AAAA,GACF;AAEJ","file":"index.cjs","sourcesContent":["import type { ColumnDef, ResolvedColumn } from '../types';\n\nconst DEFAULT_WIDTH = 150;\nconst DEFAULT_MIN_WIDTH = 60;\n\n/** Reads `a.b.c` out of an object, tolerating nulls along the way. */\nfunction readPath(row: unknown, path: string): unknown {\n if (row == null) return undefined;\n if (!path.includes('.')) return (row as Record<string, unknown>)[path];\n\n let current: unknown = row;\n for (const segment of path.split('.')) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\n/**\n * Resolves a cell value.\n *\n * Servers that flatten joined relations hand back `{\"customer.businessName\": x}`\n * rather than a nested object -- and some flatten with a different prefix when\n * grouping is on. So: explicit getter, then the dotted path, then the literal\n * flat key, then any declared aliases.\n */\nexport function resolveValue<T>(row: T, column: ColumnDef<T, never>): unknown {\n if (column.valueGetter) return column.valueGetter(row);\n\n const { field } = column;\n if (!field) return undefined;\n\n const nested = readPath(row, field);\n if (nested !== undefined) return nested;\n\n const flat = (row as Record<string, unknown>)?.[field];\n if (flat !== undefined) return flat;\n\n for (const alias of column.fieldAliases ?? []) {\n const value = readPath(row, alias) ?? (row as Record<string, unknown>)?.[alias];\n if (value !== undefined) return value;\n }\n\n return undefined;\n}\n\n/** The display string for a cell, independent of any custom renderer. */\nexport function formatValue<T>(value: unknown, row: T, column: ColumnDef<T, never>): string {\n if (column.valueFormatter) return column.valueFormatter(value, row);\n if (value == null) return '';\n if (value instanceof Date) return value.toISOString().slice(0, 10);\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n return String(value);\n}\n\n/** The string written to CSV / clipboard for a cell. */\nexport function exportValue<T>(row: T, column: ColumnDef<T, never>): string {\n if (column.exportValue) return column.exportValue(row);\n return formatValue(resolveValue(row, column), row, column);\n}\n\n/** Plain-text header, for exports and aria labels. */\nexport function headerText<T>(column: ColumnDef<T, never>): string {\n if (column.headerName) return column.headerName;\n if (typeof column.header === 'string') return column.header;\n if (typeof column.header === 'number') return String(column.header);\n return column.colId ?? column.field ?? '';\n}\n\nexport function columnId<T, C>(column: ColumnDef<T, C>): string {\n const id = column.colId ?? column.field;\n if (!id) {\n throw new Error('@helix-x/datagrid-ui: every column needs a `colId` or a `field`.');\n }\n return id;\n}\n\n/** Fills in the defaults every other module assumes are present. */\nexport function resolveColumn<T, C>(column: ColumnDef<T, C>): ResolvedColumn<T, C> {\n const minWidth = column.minWidth ?? DEFAULT_MIN_WIDTH;\n return {\n ...column,\n colId: columnId(column),\n width: Math.max(column.width ?? DEFAULT_WIDTH, minWidth),\n minWidth,\n sortable: column.sortable ?? true,\n resizable: column.resizable ?? true,\n };\n}\n\nexport function isEditable<T, C>(column: ColumnDef<T, C>, row: T): boolean {\n if (typeof column.editable === 'function') return column.editable(row);\n return column.editable === true;\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type {\n ColumnDef,\n ColumnLayout,\n ColumnLayoutItem,\n Pinned,\n PersistedGridState,\n ResolvedColumn,\n} from '../types';\nimport { columnId, resolveColumn } from './values';\n\nexport interface ColumnStateValue {\n order: string[];\n hidden: string[];\n widths: Record<string, number>;\n pinned: Record<string, Pinned>;\n}\n\nexport interface UseColumnStateResult<T, C> {\n /** Every column, in user order, including hidden ones (for the columns panel). */\n allColumns: ResolvedColumn<T, C>[];\n visibleColumns: ResolvedColumn<T, C>[];\n layout: ColumnLayout<T, C>;\n state: ColumnStateValue;\n isHidden: (colId: string) => boolean;\n setHidden: (colId: string, hidden: boolean) => void;\n setWidth: (colId: string, width: number) => void;\n setPinned: (colId: string, pinned: Pinned | undefined) => void;\n moveColumn: (colId: string, toIndex: number) => void;\n reset: () => void;\n}\n\nfunction defaultsFrom<T, C>(columns: ColumnDef<T, C>[]): ColumnStateValue {\n const order: string[] = [];\n const hidden: string[] = [];\n const widths: Record<string, number> = {};\n const pinned: Record<string, Pinned> = {};\n\n for (const column of columns) {\n const id = columnId(column);\n order.push(id);\n if (column.hide) hidden.push(id);\n if (column.width != null) widths[id] = column.width;\n if (column.pinned) pinned[id] = column.pinned;\n }\n\n return { order, hidden, widths, pinned };\n}\n\n/**\n * Merges persisted state *over* the column defaults, key by key.\n *\n * Deliberately not a wholesale replacement: a saved state that predates a new\n * column must not hide it, and must not discard the defaults for keys it does\n * not mention.\n */\nfunction mergePersisted(\n defaults: ColumnStateValue,\n persisted: PersistedGridState['columns'] | undefined,\n knownIds: Set<string>\n): ColumnStateValue {\n if (!persisted) return defaults;\n\n // Keep the saved order for columns that still exist, then append any new\n // columns in their declared position rather than dumping them at the end.\n const savedOrder = persisted.order.filter((id) => knownIds.has(id));\n const savedSet = new Set(savedOrder);\n const order = [...savedOrder];\n defaults.order.forEach((id, index) => {\n if (!savedSet.has(id)) order.splice(Math.min(index, order.length), 0, id);\n });\n\n return {\n order,\n hidden: (persisted.hidden ?? defaults.hidden).filter((id) => knownIds.has(id)),\n widths: { ...defaults.widths, ...(persisted.widths ?? {}) },\n pinned: { ...defaults.pinned, ...(persisted.pinned ?? {}) },\n };\n}\n\nexport function useColumnState<T, C>(\n columns: ColumnDef<T, C>[],\n persisted: PersistedGridState['columns'] | undefined,\n onChange: (state: ColumnStateValue) => void,\n availableWidth: number\n): UseColumnStateResult<T, C> {\n const resolved = useMemo(() => columns.map((c) => resolveColumn(c)), [columns]);\n\n const byId = useMemo(() => {\n const map = new Map<string, ResolvedColumn<T, C>>();\n for (const column of resolved) map.set(column.colId, column);\n return map;\n }, [resolved]);\n\n const defaults = useMemo(() => defaultsFrom(columns), [columns]);\n\n const [state, setState] = useState<ColumnStateValue>(() =>\n mergePersisted(defaults, persisted, new Set(defaults.order))\n );\n\n const update = useCallback(\n (mutate: (current: ColumnStateValue) => ColumnStateValue) => {\n setState((current) => {\n const next = mutate(current);\n onChange(next);\n return next;\n });\n },\n [onChange]\n );\n\n const hiddenSet = useMemo(() => new Set(state.hidden), [state.hidden]);\n\n const allColumns = useMemo(\n () =>\n state.order\n .map((id) => byId.get(id))\n .filter((c): c is ResolvedColumn<T, C> => c != null),\n [state.order, byId]\n );\n\n const visibleColumns = useMemo(\n () =>\n allColumns\n .filter((column) => !hiddenSet.has(column.colId))\n .map((column) =>\n state.widths[column.colId] != null || state.pinned[column.colId] != null\n ? {\n ...column,\n width: Math.max(\n state.widths[column.colId] ?? column.width,\n column.minWidth\n ),\n pinned: state.pinned[column.colId] ?? column.pinned,\n }\n : column\n ),\n [allColumns, hiddenSet, state.widths, state.pinned]\n );\n\n /**\n * One layout pass produces every geometry number the header and the cells\n * need, so no component computes its own offsets.\n */\n const layout = useMemo<ColumnLayout<T, C>>(() => {\n // Flex columns share whatever space the fixed ones leave over.\n const flexTotal = visibleColumns.reduce((sum, c) => sum + (c.flex ?? 0), 0);\n const fixedWidth = visibleColumns.reduce(\n (sum, c) => sum + (c.flex ? 0 : c.width),\n 0\n );\n const spare = Math.max(0, availableWidth - fixedWidth);\n\n const widthOf = (column: ResolvedColumn<T, C>) => {\n if (!column.flex || flexTotal === 0) return column.width;\n const share = Math.floor((spare * column.flex) / flexTotal);\n const capped = column.maxWidth ? Math.min(share, column.maxWidth) : share;\n return Math.max(capped, column.minWidth);\n };\n\n // Pinned columns keep their declared order but are laid out as three\n // contiguous bands: left-pinned, unpinned, right-pinned.\n const left = visibleColumns.filter((c) => c.pinned === 'left');\n const middle = visibleColumns.filter((c) => !c.pinned);\n const right = visibleColumns.filter((c) => c.pinned === 'right');\n\n const items: ColumnLayoutItem<T, C>[] = [];\n let offset = 0;\n let leftSticky = 0;\n\n for (const column of left) {\n const width = widthOf(column);\n items.push({\n column,\n colId: column.colId,\n width,\n left: offset,\n pinned: 'left',\n stickyOffset: leftSticky,\n });\n offset += width;\n leftSticky += width;\n }\n\n for (const column of middle) {\n const width = widthOf(column);\n items.push({ column, colId: column.colId, width, left: offset, stickyOffset: 0 });\n offset += width;\n }\n\n // Right-pinned sticky offsets accumulate from the right edge, so walk them\n // backwards first.\n const rightWidths = right.map(widthOf);\n let rightSticky = 0;\n const rightOffsets: number[] = [];\n for (let i = right.length - 1; i >= 0; i--) {\n rightOffsets[i] = rightSticky;\n rightSticky += rightWidths[i];\n }\n\n right.forEach((column, index) => {\n const width = rightWidths[index];\n items.push({\n column,\n colId: column.colId,\n width,\n left: offset,\n pinned: 'right',\n stickyOffset: rightOffsets[index],\n });\n offset += width;\n });\n\n return {\n items,\n totalWidth: offset,\n leftPinnedWidth: leftSticky,\n rightPinnedWidth: rightSticky,\n };\n }, [visibleColumns, availableWidth]);\n\n const isHidden = useCallback((colId: string) => hiddenSet.has(colId), [hiddenSet]);\n\n const setHidden = useCallback(\n (colId: string, hidden: boolean) => {\n update((current) => ({\n ...current,\n hidden: hidden\n ? current.hidden.includes(colId)\n ? current.hidden\n : [...current.hidden, colId]\n : current.hidden.filter((id) => id !== colId),\n }));\n },\n [update]\n );\n\n const setWidth = useCallback(\n (colId: string, width: number) => {\n update((current) => ({\n ...current,\n widths: { ...current.widths, [colId]: Math.round(width) },\n }));\n },\n [update]\n );\n\n const setPinned = useCallback(\n (colId: string, pinned: Pinned | undefined) => {\n update((current) => {\n const next = { ...current.pinned };\n if (pinned) next[colId] = pinned;\n else delete next[colId];\n return { ...current, pinned: next };\n });\n },\n [update]\n );\n\n const moveColumn = useCallback(\n (colId: string, toIndex: number) => {\n update((current) => {\n const from = current.order.indexOf(colId);\n if (from === -1 || from === toIndex) return current;\n const order = [...current.order];\n order.splice(from, 1);\n order.splice(Math.max(0, Math.min(toIndex, order.length)), 0, colId);\n return { ...current, order };\n });\n },\n [update]\n );\n\n const reset = useCallback(() => {\n update(() => defaults);\n }, [update, defaults]);\n\n return {\n allColumns,\n visibleColumns,\n layout,\n state,\n isHidden,\n setHidden,\n setWidth,\n setPinned,\n moveColumn,\n reset,\n };\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type { RowCommitResult } from '../types';\nimport type { RowId } from './useSelectionModel';\n\nexport interface EditState<T> {\n rowId: RowId;\n draft: T;\n original: T;\n errors: Record<string, string>;\n isSaving: boolean;\n}\n\nexport interface UseEditModelResult<T> {\n edit: EditState<T> | null;\n isEditing: (rowId: RowId) => boolean;\n start: (rowId: RowId, row: T) => void;\n setField: (field: string, value: unknown) => void;\n cancel: () => void;\n commit: () => Promise<void>;\n}\n\nfunction setPath<T>(row: T, path: string, value: unknown): T {\n if (!path.includes('.')) {\n return { ...row, [path]: value };\n }\n const [head, ...rest] = path.split('.');\n const current = (row as Record<string, unknown>)[head];\n return {\n ...row,\n [head]: setPath(\n (current ?? {}) as Record<string, unknown>,\n rest.join('.'),\n value\n ),\n };\n}\n\n/**\n * Row-level editing against a draft copy.\n *\n * The draft never touches the data source, and the editors never call an API --\n * the single `onCommit` callback owns validation and persistence, so the app can\n * plug in whatever schema library it uses without the grid knowing about it.\n */\nexport function useEditModel<T>(\n onCommit: (draft: T, original: T) => Promise<RowCommitResult> | RowCommitResult\n): UseEditModelResult<T> {\n const [edit, setEdit] = useState<EditState<T> | null>(null);\n\n // A mirror of the state that is safe to read synchronously. `setState`\n // updaters are not guaranteed to run when they are dispatched (and may run\n // twice in StrictMode), so commit() reads the draft from here instead.\n const editRef = useRef<EditState<T> | null>(null);\n\n const apply = useCallback(\n (next: EditState<T> | null) => {\n editRef.current = next;\n setEdit(next);\n },\n []\n );\n\n const patch = useCallback((mutate: (current: EditState<T>) => EditState<T>) => {\n const current = editRef.current;\n if (!current) return;\n const next = mutate(current);\n editRef.current = next;\n setEdit(next);\n }, []);\n\n const isEditing = useCallback(\n (rowId: RowId) => edit?.rowId === rowId,\n [edit]\n );\n\n const start = useCallback(\n (rowId: RowId, row: T) => {\n apply({ rowId, draft: row, original: row, errors: {}, isSaving: false });\n },\n [apply]\n );\n\n const setField = useCallback(\n (field: string, value: unknown) => {\n patch((current) => {\n const errors = { ...current.errors };\n // Clear the error as soon as the field is touched; re-validation\n // happens on commit.\n delete errors[field];\n return { ...current, draft: setPath(current.draft, field, value), errors };\n });\n },\n [patch]\n );\n\n const cancel = useCallback(() => apply(null), [apply]);\n\n const commit = useCallback(async () => {\n const state = editRef.current;\n if (!state || state.isSaving) return;\n\n apply({ ...state, isSaving: true });\n\n try {\n const result = await onCommit(state.draft, state.original);\n if (result.ok) {\n apply(null);\n return;\n }\n patch((current) => ({ ...current, errors: result.errors, isSaving: false }));\n } catch (error) {\n patch((current) => ({\n ...current,\n isSaving: false,\n errors: {\n ...current.errors,\n __row__:\n error instanceof Error ? error.message : 'Failed to save the row.',\n },\n }));\n }\n }, [onCommit, apply, patch]);\n\n return { edit, isEditing, start, setField, cancel, commit };\n}\n","import type { ReactNode } from 'react';\n\n/* -------------------------------------------------------------------------- */\n/* Filter models */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The wire shapes below intentionally mirror what ag-grid's server-side row\n * model posts, because most existing backends that speak \"grid\" already parse\n * them. Keeping them identical is what lets a screen swap grids without a\n * backend change.\n */\n\nexport type TextFilterType =\n | 'contains'\n | 'notContains'\n | 'equals'\n | 'notEqual'\n | 'startsWith'\n | 'endsWith'\n | 'blank'\n | 'notBlank';\n\nexport type NumberFilterType =\n | 'equals'\n | 'notEqual'\n | 'lessThan'\n | 'lessThanOrEqual'\n | 'greaterThan'\n | 'greaterThanOrEqual'\n | 'inRange'\n | 'blank'\n | 'notBlank';\n\nexport type DateFilterType =\n | 'equals'\n | 'notEqual'\n | 'before'\n | 'after'\n | 'inRange'\n | 'blank'\n | 'notBlank';\n\nexport interface TextFilterModel {\n filterType: 'text';\n type: TextFilterType;\n filter?: string;\n}\n\nexport interface NumberFilterModel {\n filterType: 'number';\n type: NumberFilterType;\n filter?: number;\n filterTo?: number;\n}\n\nexport interface DateFilterModel {\n filterType: 'date';\n type: DateFilterType;\n /** `YYYY-MM-DD` */\n dateFrom?: string;\n dateTo?: string;\n}\n\nexport interface SetFilterModel {\n filterType: 'set';\n values: string[];\n}\n\nexport type HxFilterModel =\n | TextFilterModel\n | NumberFilterModel\n | DateFilterModel\n | SetFilterModel;\n\nexport type FilterModelMap = Record<string, HxFilterModel>;\n\nexport type FilterKind = 'text' | 'number' | 'date' | 'set';\n\n/* -------------------------------------------------------------------------- */\n/* Sorting */\n/* -------------------------------------------------------------------------- */\n\nexport type SortDirection = 'asc' | 'desc';\n\nexport interface SortModelItem {\n colId: string;\n sort: SortDirection;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Data source */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Structurally compatible with ag-grid's `IServerSideGetRowsRequest`, so an\n * endpoint written for that model accepts this verbatim. The grouping/pivot\n * fields are always sent empty — this grid does not implement them — but they\n * are present so servers that destructure them do not fall over.\n */\nexport interface HxRowsRequest {\n startRow: number;\n endRow: number;\n sortModel: SortModelItem[];\n filterModel: FilterModelMap;\n rowGroupCols: never[];\n valueCols: never[];\n pivotCols: never[];\n pivotMode: false;\n groupKeys: never[];\n}\n\nexport interface HxRowsResponse<T> {\n rows: T[];\n /** Total row count across all pages, or -1 when unknown. */\n lastRow: number;\n}\n\nexport interface HxDataSource<T> {\n getRows(request: HxRowsRequest, signal: AbortSignal): Promise<HxRowsResponse<T>>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Columns */\n/* -------------------------------------------------------------------------- */\n\nexport type Pinned = 'left' | 'right';\n\nexport interface CellRendererParams<T, C = unknown> {\n row: T;\n rowIndex: number;\n value: unknown;\n formatted: string;\n column: ColumnDef<T, C>;\n /**\n * Arbitrary app state handed to every renderer. Put volatile things here\n * (in-flight ids, permission checks, handlers) so column definitions can stay\n * memoised on `[]` and never rebuild.\n */\n context: C;\n api: GridApi<T>;\n}\n\nexport interface EditorParams<T, C = unknown> {\n value: unknown;\n row: T;\n column: ColumnDef<T, C>;\n context: C;\n /** Writes into the row draft. Never hits the network. */\n onChange: (value: unknown) => void;\n /** Commit the whole row. */\n onCommit: () => void;\n onCancel: () => void;\n error?: string;\n autoFocus?: boolean;\n}\n\nexport type EditorComponent<T, C = unknown> = (\n params: EditorParams<T, C>\n) => ReactNode;\n\nexport type BuiltinEditor = 'text' | 'number' | 'select' | 'date' | 'checkbox';\n\nexport interface SelectOption {\n label: string;\n value: unknown;\n}\n\nexport interface ColumnDef<T, C = unknown> {\n /** Stable identity. Falls back to `field` when omitted. */\n colId?: string;\n /** Dotted path into the row. Also used as the server-side filter/sort key. */\n field?: string;\n header: ReactNode;\n /** Plain-text header, used for exports when `header` is a node. */\n headerName?: string;\n\n width?: number;\n minWidth?: number;\n maxWidth?: number;\n /** Share of the leftover horizontal space. */\n flex?: number;\n\n pinned?: Pinned;\n hide?: boolean;\n sortable?: boolean;\n resizable?: boolean;\n /** Prevent the user dragging this column out of position. */\n lockPosition?: boolean;\n\n filter?: FilterKind | false;\n filterParams?: {\n /** Static values, or a loader for a set filter whose options come from an API. */\n values?: string[] | (() => Promise<string[]>);\n /** Hide the always-visible filter input under the header for this column. */\n suppressFloatingFilter?: boolean;\n };\n\n /** Alternative flat keys to try when the server flattens nested fields. */\n fieldAliases?: string[];\n\n valueGetter?: (row: T) => unknown;\n valueFormatter?: (value: unknown, row: T) => string;\n cellRenderer?: (params: CellRendererParams<T, C>) => ReactNode;\n\n editable?: boolean | ((row: T) => boolean);\n editor?: BuiltinEditor | EditorComponent<T, C>;\n editorParams?: {\n options?: SelectOption[];\n placeholder?: string;\n };\n\n exportValue?: (row: T) => string;\n suppressExport?: boolean;\n\n cellClassName?: string | ((row: T) => string);\n headerClassName?: string;\n /** Horizontal alignment of the cell content. */\n align?: 'left' | 'center' | 'right';\n}\n\n/** A column with every default resolved. Internal, but exported for renderers. */\nexport interface ResolvedColumn<T, C = unknown> extends ColumnDef<T, C> {\n colId: string;\n width: number;\n minWidth: number;\n sortable: boolean;\n resizable: boolean;\n}\n\n/** Geometry for one visible column, computed once per layout change. */\nexport interface ColumnLayoutItem<T, C = unknown> {\n column: ResolvedColumn<T, C>;\n colId: string;\n width: number;\n /** Offset from the left edge of the full (unscrolled) column strip. */\n left: number;\n pinned?: Pinned;\n /** `left`/`right` offset to use for `position: sticky` on pinned columns. */\n stickyOffset: number;\n}\n\nexport interface ColumnLayout<T, C = unknown> {\n items: ColumnLayoutItem<T, C>[];\n totalWidth: number;\n leftPinnedWidth: number;\n rightPinnedWidth: number;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Editing */\n/* -------------------------------------------------------------------------- */\n\nexport type RowCommitResult =\n | { ok: true; row?: unknown }\n | { ok: false; errors: Record<string, string>; message?: string };\n\n/* -------------------------------------------------------------------------- */\n/* Persisted state */\n/* -------------------------------------------------------------------------- */\n\nexport const GRID_STATE_VERSION = 1;\n\nexport interface PersistedGridState {\n v: number;\n columns: {\n order: string[];\n hidden: string[];\n widths: Record<string, number>;\n pinned: Record<string, Pinned>;\n };\n sort: SortModelItem[];\n filters: FilterModelMap;\n pagination: { pageSize: number };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Imperative API */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExportCsvOptions {\n onlySelected?: boolean;\n fileName?: string;\n /** Field separator. Defaults to `,`. */\n separator?: string;\n}\n\nexport interface GridApi<T> {\n /** Re-fetch. `purge` drops every cached block first. */\n refresh(options?: { purge?: boolean }): void;\n getDisplayedRows(): T[];\n getSelectedRows(): T[];\n getSelectedIds(): Array<string | number>;\n clearSelection(): void;\n selectAll(): void;\n exportCsv(options?: ExportCsvOptions): void;\n copySelectionToClipboard(): Promise<void>;\n getFilterModel(): FilterModelMap;\n setFilterModel(model: FilterModelMap): void;\n getSortModel(): SortModelItem[];\n setSortModel(model: SortModelItem[]): void;\n resetColumns(): void;\n /** Patch rows already on screen without a round trip. */\n updateRows(rows: T[]): void;\n startEditing(rowId: string | number): void;\n stopEditing(): void;\n}\n","import { useCallback, useRef, useState } from 'react';\nimport {\n GRID_STATE_VERSION,\n type FilterModelMap,\n type PersistedGridState,\n type SortModelItem,\n} from '../types';\n\nconst PREFIX = 'hxg:';\n\nfunction read(storageKey: string): PersistedGridState | undefined {\n if (typeof window === 'undefined') return undefined;\n try {\n const raw = window.localStorage.getItem(PREFIX + storageKey);\n if (!raw) return undefined;\n const parsed = JSON.parse(raw) as PersistedGridState;\n // A shape from an older version is dropped rather than migrated: the state\n // is a convenience, and a bad restore is worse than starting from defaults.\n if (!parsed || parsed.v !== GRID_STATE_VERSION) return undefined;\n return parsed;\n } catch {\n return undefined;\n }\n}\n\nfunction write(storageKey: string, state: PersistedGridState): void {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(PREFIX + storageKey, JSON.stringify(state));\n } catch {\n // Quota or a privacy mode: persistence is best-effort.\n }\n}\n\nexport interface UseGridStateResult {\n /** Read once on mount; never re-read, so it is safe as an initial value. */\n initial: PersistedGridState | undefined;\n saveColumns: (columns: PersistedGridState['columns']) => void;\n saveSort: (sort: SortModelItem[]) => void;\n saveFilters: (filters: FilterModelMap) => void;\n savePageSize: (pageSize: number) => void;\n clear: () => void;\n hasSavedState: boolean;\n}\n\n/** Versioned, lean localStorage persistence for one grid. */\nexport function useGridState(storageKey: string | undefined): UseGridStateResult {\n const initialRef = useRef<PersistedGridState | undefined>(\n storageKey ? read(storageKey) : undefined\n );\n const [hasSavedState, setHasSavedState] = useState(() => initialRef.current != null);\n\n // The live copy the setters mutate; kept in a ref so saving never re-renders.\n const currentRef = useRef<PersistedGridState>(\n initialRef.current ?? {\n v: GRID_STATE_VERSION,\n columns: { order: [], hidden: [], widths: {}, pinned: {} },\n sort: [],\n filters: {},\n pagination: { pageSize: 20 },\n }\n );\n\n const persist = useCallback(\n (patch: Partial<PersistedGridState>) => {\n if (!storageKey) return;\n currentRef.current = { ...currentRef.current, ...patch, v: GRID_STATE_VERSION };\n write(storageKey, currentRef.current);\n setHasSavedState(true);\n },\n [storageKey]\n );\n\n const saveColumns = useCallback(\n (columns: PersistedGridState['columns']) => persist({ columns }),\n [persist]\n );\n const saveSort = useCallback((sort: SortModelItem[]) => persist({ sort }), [persist]);\n const saveFilters = useCallback(\n (filters: FilterModelMap) => persist({ filters }),\n [persist]\n );\n const savePageSize = useCallback(\n (pageSize: number) => persist({ pagination: { pageSize } }),\n [persist]\n );\n\n const clear = useCallback(() => {\n if (!storageKey || typeof window === 'undefined') return;\n try {\n window.localStorage.removeItem(PREFIX + storageKey);\n } catch {\n // ignore\n }\n setHasSavedState(false);\n }, [storageKey]);\n\n return {\n initial: initialRef.current,\n saveColumns,\n saveSort,\n saveFilters,\n savePageSize,\n clear,\n hasSavedState,\n };\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\n\nexport type RowId = string | number;\n\nexport interface UseSelectionModelResult<T> {\n selectedIds: Set<RowId>;\n isSelected: (id: RowId) => boolean;\n /** True when every row currently on screen is selected. */\n allVisibleSelected: boolean;\n someVisibleSelected: boolean;\n toggleRow: (id: RowId, index: number, shiftKey: boolean) => void;\n toggleAllVisible: () => void;\n clear: () => void;\n selectAllVisible: () => void;\n getSelectedRows: () => T[];\n}\n\n/**\n * Selection lives here as a real React model rather than being read back out of\n * persisted grid state -- that indirection is what made the previous\n * implementation's \"is anything selected?\" check unreliable.\n */\nexport function useSelectionModel<T>(\n rows: T[],\n getRowId: (row: T) => RowId,\n onSelectionChanged?: (ids: RowId[]) => void\n): UseSelectionModelResult<T> {\n const [selectedIds, setSelectedIds] = useState<Set<RowId>>(() => new Set());\n const lastToggledIndexRef = useRef<number | null>(null);\n\n const rowsRef = useRef(rows);\n rowsRef.current = rows;\n const getRowIdRef = useRef(getRowId);\n getRowIdRef.current = getRowId;\n\n const commit = useCallback(\n (next: Set<RowId>) => {\n setSelectedIds(next);\n onSelectionChanged?.([...next]);\n },\n [onSelectionChanged]\n );\n\n const isSelected = useCallback((id: RowId) => selectedIds.has(id), [selectedIds]);\n\n const visibleIds = useMemo(() => rows.map(getRowId), [rows, getRowId]);\n\n const allVisibleSelected =\n visibleIds.length > 0 && visibleIds.every((id) => selectedIds.has(id));\n const someVisibleSelected =\n !allVisibleSelected && visibleIds.some((id) => selectedIds.has(id));\n\n const toggleRow = useCallback(\n (id: RowId, index: number, shiftKey: boolean) => {\n const next = new Set(selectedIds);\n const anchor = lastToggledIndexRef.current;\n\n if (shiftKey && anchor != null && anchor !== index) {\n // Shift extends from the last click across the loaded window.\n const [from, to] = anchor < index ? [anchor, index] : [index, anchor];\n const shouldSelect = !next.has(id);\n for (let i = from; i <= to; i++) {\n const rowId = getRowIdRef.current(rowsRef.current[i]);\n if (rowId == null) continue;\n if (shouldSelect) next.add(rowId);\n else next.delete(rowId);\n }\n } else if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n\n lastToggledIndexRef.current = index;\n commit(next);\n },\n [selectedIds, commit]\n );\n\n const toggleAllVisible = useCallback(() => {\n const next = new Set(selectedIds);\n if (allVisibleSelected) {\n for (const id of visibleIds) next.delete(id);\n } else {\n for (const id of visibleIds) next.add(id);\n }\n lastToggledIndexRef.current = null;\n commit(next);\n }, [selectedIds, allVisibleSelected, visibleIds, commit]);\n\n const selectAllVisible = useCallback(() => {\n const next = new Set(selectedIds);\n for (const id of visibleIds) next.add(id);\n commit(next);\n }, [selectedIds, visibleIds, commit]);\n\n const clear = useCallback(() => {\n lastToggledIndexRef.current = null;\n commit(new Set());\n }, [commit]);\n\n const getSelectedRows = useCallback(\n () => rowsRef.current.filter((row) => selectedIds.has(getRowIdRef.current(row))),\n [selectedIds]\n );\n\n return {\n selectedIds,\n isSelected,\n allVisibleSelected,\n someVisibleSelected,\n toggleRow,\n toggleAllVisible,\n clear,\n selectAllVisible,\n getSelectedRows,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { FilterModelMap, HxDataSource, HxRowsRequest, SortModelItem } from '../types';\n\nexport interface UseServerDataSourceOptions<T> {\n dataSource: HxDataSource<T>;\n pageSize: number;\n page: number;\n sortModel: SortModelItem[];\n filterModel: FilterModelMap;\n /** Blocks to keep around so paging back and forth does not refetch. */\n maxCachedBlocks?: number;\n onError?: (error: unknown) => void;\n}\n\nexport interface UseServerDataSourceResult<T> {\n rows: T[];\n totalRows: number;\n isLoading: boolean;\n error: unknown;\n refresh: (options?: { purge?: boolean }) => void;\n /** Patch loaded rows in place, keyed by the grid's row id. */\n patchRows: (rows: T[], getRowId: (row: T) => string | number) => void;\n}\n\nfunction buildRequest(\n page: number,\n pageSize: number,\n sortModel: SortModelItem[],\n filterModel: FilterModelMap\n): HxRowsRequest {\n return {\n startRow: page * pageSize,\n endRow: page * pageSize + pageSize,\n sortModel,\n filterModel,\n // Sent empty for wire compatibility with grid endpoints that expect them.\n rowGroupCols: [],\n valueCols: [],\n pivotCols: [],\n pivotMode: false,\n groupKeys: [],\n };\n}\n\n/**\n * Server-side paging with a small block cache.\n *\n * Two things here that the ag-grid screen this replaces did not do: every\n * request carries an AbortController and a sequence number, so a slow response\n * for an old sort/filter can never overwrite a newer one; and the cache is\n * dropped wholesale when the query changes, so stale blocks are never mixed\n * with fresh ones.\n */\nexport function useServerDataSource<T>({\n dataSource,\n pageSize,\n page,\n sortModel,\n filterModel,\n maxCachedBlocks = 3,\n onError,\n}: UseServerDataSourceOptions<T>): UseServerDataSourceResult<T> {\n const [rows, setRows] = useState<T[]>([]);\n const [totalRows, setTotalRows] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<unknown>(null);\n\n // Bumping this re-runs the effect without changing the query itself.\n const [refreshToken, setRefreshToken] = useState(0);\n\n const cacheRef = useRef(new Map<string, { rows: T[]; lastRow: number }>());\n const requestIdRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n\n // The query identity. Serialising the models keeps the effect from re-firing\n // on every render just because the caller rebuilt an equal object.\n const queryKey = useMemo(\n () => JSON.stringify({ pageSize, sortModel, filterModel }),\n [pageSize, sortModel, filterModel]\n );\n\n // Any change to the query invalidates every cached block.\n useEffect(() => {\n cacheRef.current.clear();\n }, [queryKey]);\n\n const onErrorRef = useRef(onError);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n const dataSourceRef = useRef(dataSource);\n useEffect(() => {\n dataSourceRef.current = dataSource;\n }, [dataSource]);\n\n useEffect(() => {\n const blockKey = `${queryKey}::${page}`;\n const cached = cacheRef.current.get(blockKey);\n if (cached) {\n setRows(cached.rows);\n setTotalRows(cached.lastRow);\n setError(null);\n return;\n }\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n const requestId = ++requestIdRef.current;\n setIsLoading(true);\n setError(null);\n\n const request = buildRequest(page, pageSize, sortModel, filterModel);\n\n dataSourceRef.current\n .getRows(request, controller.signal)\n .then((response) => {\n // A response from a superseded request must never land.\n if (requestId !== requestIdRef.current) return;\n\n const lastRow = response.lastRow ?? response.rows.length;\n cacheRef.current.set(blockKey, { rows: response.rows, lastRow });\n\n // Evict oldest-first; Map preserves insertion order.\n while (cacheRef.current.size > maxCachedBlocks) {\n const oldest = cacheRef.current.keys().next().value;\n if (oldest === undefined) break;\n cacheRef.current.delete(oldest);\n }\n\n setRows(response.rows);\n setTotalRows(lastRow);\n setIsLoading(false);\n })\n .catch((err) => {\n if (controller.signal.aborted) return;\n if (requestId !== requestIdRef.current) return;\n setError(err);\n setIsLoading(false);\n onErrorRef.current?.(err);\n });\n\n return () => {\n controller.abort();\n };\n }, [queryKey, page, pageSize, sortModel, filterModel, refreshToken, maxCachedBlocks]);\n\n const refresh = useCallback((options?: { purge?: boolean }) => {\n if (options?.purge !== false) cacheRef.current.clear();\n setRefreshToken((token) => token + 1);\n }, []);\n\n const patchRows = useCallback(\n (updated: T[], getRowId: (row: T) => string | number) => {\n if (updated.length === 0) return;\n const byId = new Map(updated.map((row) => [getRowId(row), row]));\n\n const merge = (list: T[]) => {\n let changed = false;\n const next = list.map((row) => {\n const replacement = byId.get(getRowId(row));\n if (!replacement) return row;\n changed = true;\n return replacement;\n });\n return changed ? next : list;\n };\n\n setRows(merge);\n // Keep the cache consistent, or paging away and back would resurrect the\n // pre-save row.\n for (const [key, block] of cacheRef.current) {\n cacheRef.current.set(key, { ...block, rows: merge(block.rows) });\n }\n },\n []\n );\n\n return { rows, totalRows, isLoading, error, refresh, patchRows };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface VirtualWindow {\n startIndex: number;\n endIndex: number;\n}\n\nexport interface UseVirtualRowsOptions {\n rowCount: number;\n rowHeight: number;\n overscan?: number;\n}\n\nexport interface UseVirtualRowsResult {\n window: VirtualWindow;\n totalHeight: number;\n /** Attach to the scrolling element. */\n onScroll: (event: { currentTarget: HTMLElement }) => void;\n /** Call when the viewport is measured or resized. */\n setViewportHeight: (height: number) => void;\n scrollTopRef: React.RefObject<number>;\n}\n\n/**\n * Fixed-height row windowing.\n *\n * Fixed heights are a deliberate constraint: they make the visible range O(1)\n * to compute and remove the measure-then-reflow pass that variable heights\n * force. Scroll position is tracked in a ref and only promoted to state when\n * the computed window actually changes, so scrolling within a row does not\n * re-render anything.\n */\nexport function useVirtualRows({\n rowCount,\n rowHeight,\n overscan = 6,\n}: UseVirtualRowsOptions): UseVirtualRowsResult {\n const [viewportHeight, setViewportHeightState] = useState(0);\n const [window, setWindow] = useState<VirtualWindow>({ startIndex: 0, endIndex: 0 });\n\n const scrollTopRef = useRef(0);\n const frameRef = useRef<number | null>(null);\n\n const compute = useCallback(\n (scrollTop: number, height: number) => {\n if (height <= 0 || rowCount === 0) {\n return { startIndex: 0, endIndex: 0 };\n }\n const first = Math.floor(scrollTop / rowHeight);\n const visible = Math.ceil(height / rowHeight);\n return {\n startIndex: Math.max(0, first - overscan),\n endIndex: Math.min(rowCount, first + visible + overscan),\n };\n },\n [rowCount, rowHeight, overscan]\n );\n\n const apply = useCallback(\n (scrollTop: number, height: number) => {\n const next = compute(scrollTop, height);\n setWindow((current) =>\n current.startIndex === next.startIndex && current.endIndex === next.endIndex\n ? current\n : next\n );\n },\n [compute]\n );\n\n const onScroll = useCallback(\n (event: { currentTarget: HTMLElement }) => {\n scrollTopRef.current = event.currentTarget.scrollTop;\n if (frameRef.current != null) return;\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n apply(scrollTopRef.current, viewportHeight);\n });\n },\n [apply, viewportHeight]\n );\n\n const setViewportHeight = useCallback((height: number) => {\n setViewportHeightState((current) => (current === height ? current : height));\n }, []);\n\n // Row count, row height and viewport size all move the window without a\n // scroll event, so recompute when any of them change.\n useEffect(() => {\n apply(scrollTopRef.current, viewportHeight);\n }, [apply, viewportHeight]);\n\n useEffect(\n () => () => {\n if (frameRef.current != null) cancelAnimationFrame(frameRef.current);\n },\n []\n );\n\n return {\n window,\n totalHeight: rowCount * rowHeight,\n onScroll,\n setViewportHeight,\n scrollTopRef,\n };\n}\n","import type { ColumnDef, ResolvedColumn } from '../types';\nimport { exportValue, headerText } from './values';\n\n/** RFC 4180: quote when the value contains the separator, a quote or a newline. */\nfunction escapeCsv(value: string, separator: string): string {\n if (value === '') return '';\n const needsQuotes =\n value.includes(separator) ||\n value.includes('\"') ||\n value.includes('\\n') ||\n value.includes('\\r');\n return needsQuotes ? `\"${value.replace(/\"/g, '\"\"')}\"` : value;\n}\n\nexport function toDelimited<T>(\n rows: T[],\n columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>,\n separator: string\n): string {\n const exportable = columns.filter((column) => !column.suppressExport);\n\n const lines: string[] = [\n exportable.map((c) => escapeCsv(headerText(c), separator)).join(separator),\n ];\n\n for (const row of rows) {\n lines.push(\n exportable\n .map((column) => escapeCsv(exportValue(row, column), separator))\n .join(separator)\n );\n }\n\n return lines.join('\\r\\n');\n}\n\nexport function toCsv<T>(\n rows: T[],\n columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>,\n separator = ','\n): string {\n return toDelimited(rows, columns, separator);\n}\n\n/** Tab-separated, which is what spreadsheets expect from the clipboard. */\nexport function toTsv<T>(\n rows: T[],\n columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>\n): string {\n return toDelimited(rows, columns, '\\t');\n}\n\nexport function downloadCsv(content: string, fileName: string): void {\n // The BOM is what makes Excel read the file as UTF-8 rather than ANSI.\n const blob = new Blob(['' + content], {\n type: 'text/csv;charset=utf-8;',\n });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName.endsWith('.csv') ? fileName : `${fileName}.csv`;\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n}\n\nexport async function copyToClipboard(text: string): Promise<void> {\n if (navigator?.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n // Older browsers and non-secure origins have no async clipboard API.\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n}\n","import type {\n DateFilterType,\n FilterKind,\n FilterModelMap,\n HxFilterModel,\n NumberFilterType,\n TextFilterType,\n} from '../types';\n\n/**\n * Every wire-format filter shape is built here, so the contract with the server\n * is defined in exactly one place.\n */\n\nexport const TEXT_FILTER_TYPES: TextFilterType[] = [\n 'contains',\n 'notContains',\n 'equals',\n 'notEqual',\n 'startsWith',\n 'endsWith',\n 'blank',\n 'notBlank',\n];\n\nexport const NUMBER_FILTER_TYPES: NumberFilterType[] = [\n 'equals',\n 'notEqual',\n 'lessThan',\n 'lessThanOrEqual',\n 'greaterThan',\n 'greaterThanOrEqual',\n 'inRange',\n 'blank',\n 'notBlank',\n];\n\nexport const DATE_FILTER_TYPES: DateFilterType[] = [\n 'equals',\n 'notEqual',\n 'before',\n 'after',\n 'inRange',\n 'blank',\n 'notBlank',\n];\n\nexport const FILTER_TYPE_LABELS: Record<string, string> = {\n contains: 'Contains',\n notContains: 'Does not contain',\n equals: 'Equals',\n notEqual: 'Not equal',\n startsWith: 'Starts with',\n endsWith: 'Ends with',\n blank: 'Is empty',\n notBlank: 'Is not empty',\n lessThan: 'Less than',\n lessThanOrEqual: 'Less than or equal',\n greaterThan: 'Greater than',\n greaterThanOrEqual: 'Greater than or equal',\n inRange: 'Between',\n before: 'Before',\n after: 'After',\n};\n\n/** Filter types that need no operand. */\nexport function isUnaryFilter(type: string): boolean {\n return type === 'blank' || type === 'notBlank';\n}\n\nexport function isRangeFilter(type: string): boolean {\n return type === 'inRange';\n}\n\nexport function defaultFilterType(kind: FilterKind): string {\n switch (kind) {\n case 'text':\n return 'contains';\n case 'number':\n return 'equals';\n case 'date':\n return 'equals';\n case 'set':\n return 'set';\n }\n}\n\nexport function buildTextFilter(type: TextFilterType, filter: string): HxFilterModel | null {\n if (!isUnaryFilter(type) && filter.trim() === '') return null;\n return isUnaryFilter(type)\n ? { filterType: 'text', type }\n : { filterType: 'text', type, filter };\n}\n\nexport function buildNumberFilter(\n type: NumberFilterType,\n filter: string,\n filterTo?: string\n): HxFilterModel | null {\n if (isUnaryFilter(type)) return { filterType: 'number', type };\n\n const from = Number(filter);\n if (filter.trim() === '' || Number.isNaN(from)) return null;\n\n if (isRangeFilter(type)) {\n const to = Number(filterTo);\n if (!filterTo || filterTo.trim() === '' || Number.isNaN(to)) return null;\n return { filterType: 'number', type, filter: from, filterTo: to };\n }\n\n return { filterType: 'number', type, filter: from };\n}\n\nexport function buildDateFilter(\n type: DateFilterType,\n dateFrom: string,\n dateTo?: string\n): HxFilterModel | null {\n if (isUnaryFilter(type)) return { filterType: 'date', type };\n if (!dateFrom) return null;\n\n if (isRangeFilter(type)) {\n if (!dateTo) return null;\n return { filterType: 'date', type, dateFrom, dateTo };\n }\n\n return { filterType: 'date', type, dateFrom };\n}\n\nexport function buildSetFilter(values: string[]): HxFilterModel | null {\n if (values.length === 0) return null;\n return { filterType: 'set', values };\n}\n\n/** Sets or clears one column's entry, returning a new map. */\nexport function withFilter(\n model: FilterModelMap,\n colId: string,\n filter: HxFilterModel | null\n): FilterModelMap {\n const next = { ...model };\n if (filter === null) {\n delete next[colId];\n } else {\n next[colId] = filter;\n }\n return next;\n}\n\n/** A short label for the floating filter / header indicator. */\nexport function describeFilter(filter: HxFilterModel): string {\n switch (filter.filterType) {\n case 'set':\n return filter.values.length === 1\n ? filter.values[0]\n : `${filter.values.length} selected`;\n case 'text':\n return isUnaryFilter(filter.type)\n ? FILTER_TYPE_LABELS[filter.type]\n : String(filter.filter ?? '');\n case 'number':\n if (isUnaryFilter(filter.type)) return FILTER_TYPE_LABELS[filter.type];\n return isRangeFilter(filter.type)\n ? `${filter.filter} - ${filter.filterTo}`\n : `${FILTER_TYPE_LABELS[filter.type]} ${filter.filter}`;\n case 'date':\n if (isUnaryFilter(filter.type)) return FILTER_TYPE_LABELS[filter.type];\n return isRangeFilter(filter.type)\n ? `${filter.dateFrom} - ${filter.dateTo}`\n : `${FILTER_TYPE_LABELS[filter.type]} ${filter.dateFrom}`;\n }\n}\n","import { useMemo, useState } from 'react';\nimport type { Pinned, ResolvedColumn } from '../types';\nimport { headerText } from '../core/values';\n\nexport interface ColumnsPanelProps<T, C> {\n columns: ResolvedColumn<T, C>[];\n isHidden: (colId: string) => boolean;\n onToggle: (colId: string, hidden: boolean) => void;\n onMove: (colId: string, toIndex: number) => void;\n onPin: (colId: string, pinned: Pinned | undefined) => void;\n onReset: () => void;\n onClose: () => void;\n}\n\n/** Show/hide, reorder and pin, plus the \"reset my preferences\" escape hatch. */\nexport function ColumnsPanel<T, C>({\n columns,\n isHidden,\n onToggle,\n onMove,\n onPin,\n onReset,\n onClose,\n}: ColumnsPanelProps<T, C>) {\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n const needle = search.trim().toLowerCase();\n if (!needle) return columns;\n return columns.filter((column) =>\n headerText(column as never).toLowerCase().includes(needle)\n );\n }, [columns, search]);\n\n const visibleCount = columns.filter((c) => !isHidden(c.colId)).length;\n\n return (\n <div className=\"flex h-full w-60 shrink-0 flex-col gap-2 border-r border-gray-200 bg-white p-2 dark:border-gray-700 dark:bg-gray-900\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300\">\n Columns\n </h3>\n <button\n type=\"button\"\n aria-label=\"Close columns panel\"\n className=\"rounded px-1.5 text-sm text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/5\"\n onClick={onClose}\n >\n ×\n </button>\n </div>\n\n <input\n type=\"search\"\n className=\"h-7 w-full rounded border border-gray-300 bg-white px-2 text-xs text-gray-800 outline-none focus:border-brand-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\n placeholder=\"Search columns...\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n\n <p className=\"text-[11px] text-gray-500 dark:text-gray-400\">\n {visibleCount} of {columns.length} shown\n </p>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {filtered.map((column) => {\n const hidden = isHidden(column.colId);\n const index = columns.findIndex((c) => c.colId === column.colId);\n\n return (\n <div\n key={column.colId}\n className=\"group flex items-center gap-1 rounded px-1 py-1 hover:bg-gray-100 dark:hover:bg-white/5\"\n draggable\n onDragStart={(event) =>\n event.dataTransfer.setData('text/plain', column.colId)\n }\n onDragOver={(event) => event.preventDefault()}\n onDrop={(event) => {\n event.preventDefault();\n const dragged = event.dataTransfer.getData('text/plain');\n if (dragged && dragged !== column.colId) onMove(dragged, index);\n }}\n >\n <span className=\"cursor-grab text-[10px] text-gray-400\" aria-hidden>\n ⠿\n </span>\n\n <label className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 text-xs text-gray-700 dark:text-gray-200\">\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5 accent-brand-500\"\n checked={!hidden}\n onChange={() => onToggle(column.colId, !hidden)}\n />\n <span className=\"truncate\">{headerText(column as never)}</span>\n </label>\n\n <button\n type=\"button\"\n className={`shrink-0 rounded px-1 text-[10px] ${\n column.pinned\n ? 'text-brand-500 dark:text-brand-400'\n : 'text-gray-400 opacity-0 group-hover:opacity-100'\n }`}\n title={column.pinned ? `Unpin (${column.pinned})` : 'Pin left'}\n onClick={() =>\n onPin(column.colId, column.pinned ? undefined : 'left')\n }\n >\n 📌\n </button>\n </div>\n );\n })}\n </div>\n\n <button\n type=\"button\"\n className=\"rounded border border-error-300 px-2 py-1 text-xs font-medium text-error-600 hover:bg-error-50 dark:border-error-700 dark:text-error-400 dark:hover:bg-error-500/10\"\n onClick={onReset}\n >\n Reset to defaults\n </button>\n </div>\n );\n}\n","export const SELECTION_COLUMN_WIDTH = 40;\n\nexport interface SelectionCellProps {\n checked: boolean;\n indeterminate?: boolean;\n onToggle: (shiftKey: boolean) => void;\n isHeader?: boolean;\n label?: string;\n}\n\n/**\n * Pinned to the left of every row. Kept out of the column model so it cannot be\n * hidden, reordered or exported by accident.\n */\nexport function SelectionCell({\n checked,\n indeterminate,\n onToggle,\n isHeader,\n label,\n}: SelectionCellProps) {\n return (\n <div\n className={`sticky left-0 z-[3] flex h-full items-center justify-center border-r border-gray-200 dark:border-gray-700 ${\n isHeader\n ? 'bg-gray-100 dark:bg-gray-800'\n : 'bg-inherit'\n }`}\n style={{ width: SELECTION_COLUMN_WIDTH, minWidth: SELECTION_COLUMN_WIDTH }}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5 cursor-pointer accent-brand-500\"\n checked={checked}\n aria-label={label ?? (isHeader ? 'Select all rows' : 'Select row')}\n ref={(node) => {\n if (node) node.indeterminate = indeterminate === true;\n }}\n onChange={() => undefined}\n onClick={(event) => onToggle(event.shiftKey)}\n />\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { ColumnLayout, FilterModelMap, HxFilterModel } from '../types';\nimport { buildTextFilter, describeFilter } from '../core/filterModel';\nimport { SELECTION_COLUMN_WIDTH } from './SelectionCell';\n\nexport interface FloatingFilterRowProps<T, C> {\n layout: ColumnLayout<T, C>;\n filterModel: FilterModelMap;\n height: number;\n selectable: boolean;\n onFilterChange: (colId: string, filter: HxFilterModel | null) => void;\n}\n\nconst CELL_INPUT_CLASS =\n 'h-6 w-full rounded border border-gray-300 bg-white px-1.5 text-[11px] text-gray-800 ' +\n 'outline-none focus:border-brand-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';\n\n/**\n * A quick text box under each header. Free-text columns get a `contains`\n * filter; the richer types are read-only here and open the full popover from\n * the header, since a single input cannot express a range or a value set.\n */\nfunction FloatingCell({\n colId,\n kind,\n filter,\n onFilterChange,\n}: {\n colId: string;\n kind: 'text' | 'number' | 'date' | 'set';\n filter: HxFilterModel | undefined;\n onFilterChange: (colId: string, filter: HxFilterModel | null) => void;\n}) {\n const isFreeText = kind === 'text';\n const [draft, setDraft] = useState(\n filter?.filterType === 'text' ? (filter.filter ?? '') : ''\n );\n\n // Keep in step when the model is changed elsewhere (popover, reset, restore).\n useEffect(() => {\n if (!isFreeText) return;\n setDraft(filter?.filterType === 'text' ? (filter.filter ?? '') : '');\n }, [filter, isFreeText]);\n\n if (!isFreeText) {\n const summary = filter ? describeFilter(filter) : '';\n return (\n <div\n className=\"flex h-6 items-center truncate rounded border border-dashed border-gray-300 px-1.5 text-[11px] text-gray-500 dark:border-gray-600 dark:text-gray-400\"\n title={summary}\n >\n {summary || <span className=\"opacity-50\">--</span>}\n </div>\n );\n }\n\n return (\n <input\n type=\"search\"\n className={CELL_INPUT_CLASS}\n value={draft}\n aria-label={`Filter ${colId}`}\n onChange={(event) => {\n const next = event.target.value;\n setDraft(next);\n onFilterChange(colId, buildTextFilter('contains', next));\n }}\n />\n );\n}\n\nexport function FloatingFilterRow<T, C>({\n layout,\n filterModel,\n height,\n selectable,\n onFilterChange,\n}: FloatingFilterRowProps<T, C>) {\n return (\n <div\n role=\"row\"\n className=\"sticky z-10 flex border-b border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/60\"\n style={{\n height,\n width: layout.totalWidth + (selectable ? SELECTION_COLUMN_WIDTH : 0),\n }}\n >\n {selectable && (\n <div\n className=\"sticky left-0 z-[3] h-full border-r border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800\"\n style={{ width: SELECTION_COLUMN_WIDTH, minWidth: SELECTION_COLUMN_WIDTH }}\n />\n )}\n\n {layout.items.map(({ column, width, pinned, stickyOffset }) => {\n const style: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n ...(pinned === 'left'\n ? { position: 'sticky', left: stickyOffset, zIndex: 3 }\n : pinned === 'right'\n ? { position: 'sticky', right: stickyOffset, zIndex: 3 }\n : null),\n };\n\n const showInput =\n column.filter && !column.filterParams?.suppressFloatingFilter;\n\n return (\n <div\n key={column.colId}\n className={`flex h-full items-center border-r border-gray-200 px-1 dark:border-gray-700 ${\n pinned ? 'bg-gray-50 dark:bg-gray-800' : ''\n }`}\n style={style}\n >\n {showInput && column.filter && (\n <FloatingCell\n colId={column.colId}\n kind={column.filter}\n filter={filterModel[column.colId]}\n onFilterChange={onFilterChange}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { FilterKind, HxFilterModel } from '../types';\nimport {\n DATE_FILTER_TYPES,\n FILTER_TYPE_LABELS,\n NUMBER_FILTER_TYPES,\n TEXT_FILTER_TYPES,\n buildDateFilter,\n buildNumberFilter,\n buildSetFilter,\n buildTextFilter,\n isRangeFilter,\n isUnaryFilter,\n} from '../core/filterModel';\n\nexport interface FilterPopoverProps {\n kind: FilterKind;\n value: HxFilterModel | undefined;\n setValues?: string[] | (() => Promise<string[]>);\n onApply: (filter: HxFilterModel | null) => void;\n onClose: () => void;\n}\n\nconst FIELD_CLASS =\n 'h-8 w-full rounded border border-gray-300 bg-white px-2 text-xs text-gray-800 ' +\n 'outline-none focus:border-brand-500 focus:ring-1 focus:ring-brand-500 ' +\n 'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';\n\nconst BUTTON_CLASS =\n 'rounded px-2.5 py-1 text-xs font-medium transition-colors disabled:opacity-50';\n\nfunction SetFilterBody({\n value,\n setValues,\n onApply,\n}: {\n value: HxFilterModel | undefined;\n setValues: FilterPopoverProps['setValues'];\n onApply: (filter: HxFilterModel | null) => void;\n}) {\n const [options, setOptions] = useState<string[]>(\n Array.isArray(setValues) ? setValues : []\n );\n const [isLoading, setIsLoading] = useState(typeof setValues === 'function');\n const [search, setSearch] = useState('');\n const [selected, setSelected] = useState<Set<string>>(\n () => new Set(value?.filterType === 'set' ? value.values : [])\n );\n\n useEffect(() => {\n if (typeof setValues !== 'function') {\n setOptions(Array.isArray(setValues) ? setValues : []);\n return;\n }\n let cancelled = false;\n setIsLoading(true);\n setValues()\n .then((loaded) => {\n if (!cancelled) setOptions(loaded);\n })\n .catch(() => {\n if (!cancelled) setOptions([]);\n })\n .finally(() => {\n if (!cancelled) setIsLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [setValues]);\n\n const filtered = useMemo(() => {\n const needle = search.trim().toLowerCase();\n return needle ? options.filter((o) => o.toLowerCase().includes(needle)) : options;\n }, [options, search]);\n\n const toggle = (option: string) => {\n setSelected((current) => {\n const next = new Set(current);\n if (next.has(option)) next.delete(option);\n else next.add(option);\n return next;\n });\n };\n\n return (\n <>\n <input\n type=\"search\"\n className={FIELD_CLASS}\n placeholder=\"Search values...\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n\n <div className=\"max-h-52 overflow-y-auto rounded border border-gray-200 dark:border-gray-700\">\n {isLoading && (\n <p className=\"p-2 text-xs text-gray-500 dark:text-gray-400\">Loading...</p>\n )}\n {!isLoading && filtered.length === 0 && (\n <p className=\"p-2 text-xs text-gray-500 dark:text-gray-400\">No values.</p>\n )}\n {filtered.map((option) => (\n <label\n key={option}\n className=\"flex cursor-pointer items-center gap-2 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5\"\n >\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5 accent-brand-500\"\n checked={selected.has(option)}\n onChange={() => toggle(option)}\n />\n <span className=\"truncate\">{option}</span>\n </label>\n ))}\n </div>\n\n <div className=\"flex justify-between gap-2\">\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-white/5`}\n onClick={() => {\n setSelected(new Set());\n onApply(null);\n }}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} bg-brand-500 text-white hover:bg-brand-600`}\n onClick={() => onApply(buildSetFilter([...selected]))}\n >\n Apply\n </button>\n </div>\n </>\n );\n}\n\n/** Header filter menu. Emits the wire-format model directly. */\nexport function FilterPopover({\n kind,\n value,\n setValues,\n onApply,\n onClose,\n}: FilterPopoverProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n\n const types =\n kind === 'text'\n ? TEXT_FILTER_TYPES\n : kind === 'number'\n ? NUMBER_FILTER_TYPES\n : DATE_FILTER_TYPES;\n\n const [type, setType] = useState<string>(() => {\n if (value && value.filterType !== 'set') return value.type;\n return types[0];\n });\n\n const [operand, setOperand] = useState<string>(() => {\n if (!value) return '';\n if (value.filterType === 'text') return value.filter ?? '';\n if (value.filterType === 'number') return value.filter?.toString() ?? '';\n if (value.filterType === 'date') return value.dateFrom ?? '';\n return '';\n });\n\n const [operandTo, setOperandTo] = useState<string>(() => {\n if (!value) return '';\n if (value.filterType === 'number') return value.filterTo?.toString() ?? '';\n if (value.filterType === 'date') return value.dateTo ?? '';\n return '';\n });\n\n // Close on outside click / Escape, the way a menu is expected to behave.\n useEffect(() => {\n const onPointerDown = (event: MouseEvent) => {\n if (!containerRef.current?.contains(event.target as Node)) onClose();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n document.addEventListener('mousedown', onPointerDown);\n document.addEventListener('keydown', onKeyDown);\n return () => {\n document.removeEventListener('mousedown', onPointerDown);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [onClose]);\n\n const apply = () => {\n if (kind === 'text') {\n onApply(buildTextFilter(type as never, operand));\n } else if (kind === 'number') {\n onApply(buildNumberFilter(type as never, operand, operandTo));\n } else {\n onApply(buildDateFilter(type as never, operand, operandTo));\n }\n };\n\n const inputType = kind === 'date' ? 'date' : kind === 'number' ? 'number' : 'text';\n\n return (\n <div\n ref={containerRef}\n className=\"absolute right-0 top-full z-30 mt-1 flex w-60 flex-col gap-2 rounded-md border border-gray-200 bg-white p-2 shadow-theme-lg dark:border-gray-700 dark:bg-gray-900\"\n onClick={(event) => event.stopPropagation()}\n >\n {kind === 'set' ? (\n <SetFilterBody value={value} setValues={setValues} onApply={onApply} />\n ) : (\n <>\n <select\n className={FIELD_CLASS}\n value={type}\n onChange={(event) => setType(event.target.value)}\n >\n {types.map((option) => (\n <option key={option} value={option}>\n {FILTER_TYPE_LABELS[option] ?? option}\n </option>\n ))}\n </select>\n\n {!isUnaryFilter(type) && (\n <input\n type={inputType}\n className={FIELD_CLASS}\n value={operand}\n autoFocus\n placeholder=\"Value\"\n onChange={(event) => setOperand(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') apply();\n }}\n />\n )}\n\n {isRangeFilter(type) && (\n <input\n type={inputType}\n className={FIELD_CLASS}\n value={operandTo}\n placeholder=\"To\"\n onChange={(event) => setOperandTo(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') apply();\n }}\n />\n )}\n\n <div className=\"flex justify-between gap-2\">\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-white/5`}\n onClick={() => {\n setOperand('');\n setOperandTo('');\n onApply(null);\n }}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} bg-brand-500 text-white hover:bg-brand-600`}\n onClick={apply}\n >\n Apply\n </button>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type {\n ColumnLayout,\n ColumnLayoutItem,\n FilterModelMap,\n HxFilterModel,\n Pinned,\n SortDirection,\n SortModelItem,\n} from '../types';\nimport { describeFilter } from '../core/filterModel';\nimport { FilterPopover } from './FilterPopover';\nimport { SELECTION_COLUMN_WIDTH, SelectionCell } from './SelectionCell';\n\nexport interface GridHeaderProps<T, C> {\n layout: ColumnLayout<T, C>;\n sortModel: SortModelItem[];\n filterModel: FilterModelMap;\n headerHeight: number;\n selectable: boolean;\n allSelected: boolean;\n someSelected: boolean;\n onToggleAll: () => void;\n onSort: (colId: string, additive: boolean) => void;\n onFilterChange: (colId: string, filter: HxFilterModel | null) => void;\n onResize: (colId: string, width: number) => void;\n onMove: (colId: string, toIndex: number) => void;\n onPin: (colId: string, pinned: Pinned | undefined) => void;\n}\n\nfunction SortIndicator({\n direction,\n index,\n showIndex,\n}: {\n direction: SortDirection | undefined;\n index: number;\n showIndex: boolean;\n}) {\n if (!direction) {\n return (\n <span className=\"opacity-0 transition-opacity group-hover:opacity-40\" aria-hidden>\n ↑\n </span>\n );\n }\n return (\n <span className=\"flex items-center text-brand-500 dark:text-brand-400\" aria-hidden>\n {direction === 'asc' ? '↑' : '↓'}\n {showIndex && <sub className=\"ml-0.5 text-[9px]\">{index + 1}</sub>}\n </span>\n );\n}\n\nexport function GridHeader<T, C>({\n layout,\n sortModel,\n filterModel,\n headerHeight,\n selectable,\n allSelected,\n someSelected,\n onToggleAll,\n onSort,\n onFilterChange,\n onResize,\n onMove,\n onPin,\n}: GridHeaderProps<T, C>) {\n const [openFilter, setOpenFilter] = useState<string | null>(null);\n const [openMenu, setOpenMenu] = useState<string | null>(null);\n const [dragColId, setDragColId] = useState<string | null>(null);\n\n // Resizing writes straight to the DOM-free state on each pointer move; the\n // pointer capture keeps the drag alive outside the header.\n const resizeRef = useRef<{ colId: string; startX: number; startWidth: number } | null>(\n null\n );\n\n const startResize = useCallback(\n (event: React.PointerEvent, item: ColumnLayoutItem<T, C>) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n colId: item.colId,\n startX: event.clientX,\n startWidth: item.width,\n };\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n },\n []\n );\n\n const onResizeMove = useCallback(\n (event: React.PointerEvent) => {\n const active = resizeRef.current;\n if (!active) return;\n const delta = event.clientX - active.startX;\n onResize(active.colId, Math.max(40, active.startWidth + delta));\n },\n [onResize]\n );\n\n const endResize = useCallback((event: React.PointerEvent) => {\n if (!resizeRef.current) return;\n resizeRef.current = null;\n (event.target as HTMLElement).releasePointerCapture(event.pointerId);\n }, []);\n\n const sortIndexOf = (colId: string) =>\n sortModel.findIndex((entry) => entry.colId === colId);\n\n return (\n <div\n role=\"row\"\n className=\"sticky top-0 z-10 flex border-b border-gray-300 bg-gray-100 dark:border-gray-600 dark:bg-gray-800\"\n style={{\n height: headerHeight,\n width: layout.totalWidth + (selectable ? SELECTION_COLUMN_WIDTH : 0),\n }}\n >\n {selectable && (\n <SelectionCell\n isHeader\n checked={allSelected}\n indeterminate={someSelected}\n onToggle={onToggleAll}\n label=\"Select all rows on this page\"\n />\n )}\n\n {layout.items.map((item, index) => {\n const { column, width, pinned, stickyOffset } = item;\n const sortIndex = sortIndexOf(column.colId);\n const direction = sortIndex === -1 ? undefined : sortModel[sortIndex].sort;\n const activeFilter = filterModel[column.colId];\n const filterKind = column.filter;\n\n const style: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n ...(pinned === 'left'\n ? { position: 'sticky', left: stickyOffset, zIndex: 3 }\n : pinned === 'right'\n ? { position: 'sticky', right: stickyOffset, zIndex: 3 }\n : null),\n };\n\n return (\n <div\n key={column.colId}\n role=\"columnheader\"\n aria-sort={\n direction === 'asc'\n ? 'ascending'\n : direction === 'desc'\n ? 'descending'\n : 'none'\n }\n aria-colindex={index + 1}\n className={`group relative flex h-full items-center border-r border-gray-300 bg-gray-100 px-2 dark:border-gray-600 dark:bg-gray-800 ${\n dragColId === column.colId ? 'opacity-40' : ''\n } ${column.headerClassName ?? ''}`}\n style={style}\n draggable={!column.lockPosition}\n onDragStart={(event) => {\n setDragColId(column.colId);\n event.dataTransfer.effectAllowed = 'move';\n }}\n onDragOver={(event) => {\n if (dragColId && dragColId !== column.colId) event.preventDefault();\n }}\n onDrop={(event) => {\n event.preventDefault();\n if (dragColId && dragColId !== column.colId) onMove(dragColId, index);\n setDragColId(null);\n }}\n onDragEnd={() => setDragColId(null)}\n >\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 text-left text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300\"\n disabled={!column.sortable}\n onClick={(event) => column.sortable && onSort(column.colId, event.shiftKey)}\n title={column.sortable ? 'Sort (shift-click to add)' : undefined}\n >\n <span className=\"truncate\">{column.header}</span>\n {column.sortable && (\n <SortIndicator\n direction={direction}\n index={sortIndex}\n showIndex={sortModel.length > 1}\n />\n )}\n </button>\n\n {filterKind && (\n <button\n type=\"button\"\n aria-label={`Filter ${column.colId}`}\n className={`ml-1 shrink-0 rounded px-1 text-[10px] leading-none ${\n activeFilter\n ? 'text-brand-500 dark:text-brand-400'\n : 'text-gray-400 opacity-0 group-hover:opacity-100'\n }`}\n title={activeFilter ? describeFilter(activeFilter) : 'Filter'}\n onClick={(event) => {\n event.stopPropagation();\n setOpenMenu(null);\n setOpenFilter((current) =>\n current === column.colId ? null : column.colId\n );\n }}\n >\n ▼\n </button>\n )}\n\n <button\n type=\"button\"\n aria-label={`Options for ${column.colId}`}\n className=\"ml-0.5 shrink-0 rounded px-1 text-[10px] leading-none text-gray-400 opacity-0 group-hover:opacity-100\"\n onClick={(event) => {\n event.stopPropagation();\n setOpenFilter(null);\n setOpenMenu((current) => (current === column.colId ? null : column.colId));\n }}\n >\n ⋮\n </button>\n\n {openFilter === column.colId && filterKind && (\n <FilterPopover\n kind={filterKind}\n value={activeFilter}\n setValues={column.filterParams?.values}\n onApply={(filter) => {\n onFilterChange(column.colId, filter);\n setOpenFilter(null);\n }}\n onClose={() => setOpenFilter(null)}\n />\n )}\n\n {openMenu === column.colId && (\n <div\n className=\"absolute right-0 top-full z-30 mt-1 w-36 rounded-md border border-gray-200 bg-white py-1 shadow-theme-lg dark:border-gray-700 dark:bg-gray-900\"\n onMouseLeave={() => setOpenMenu(null)}\n >\n {(['left', 'right'] as const).map((side) => (\n <button\n key={side}\n type=\"button\"\n className=\"block w-full px-3 py-1 text-left text-xs text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5\"\n onClick={() => {\n onPin(column.colId, pinned === side ? undefined : side);\n setOpenMenu(null);\n }}\n >\n {pinned === side ? `Unpin ${side}` : `Pin ${side}`}\n </button>\n ))}\n </div>\n )}\n\n {column.resizable && (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n className=\"absolute right-0 top-0 h-full w-1 cursor-col-resize hover:bg-brand-400\"\n onPointerDown={(event) => startResize(event, item)}\n onPointerMove={onResizeMove}\n onPointerUp={endResize}\n onPointerCancel={endResize}\n onClick={(event) => event.stopPropagation()}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport interface GridOverlayProps {\n kind: 'loading' | 'empty' | 'error';\n message?: ReactNode;\n}\n\n/**\n * Sits over the row area rather than replacing it, so the header and column\n * widths stay put while a refetch is in flight.\n */\nexport function GridOverlay({ kind, message }: GridOverlayProps) {\n if (kind === 'loading') {\n return (\n <div className=\"pointer-events-none absolute inset-0 z-[5] flex items-start justify-center bg-white/60 pt-10 dark:bg-gray-900/60\">\n <div className=\"flex items-center gap-2 rounded-md border border-gray-200 bg-white px-3 py-1.5 text-xs text-gray-600 shadow-theme-sm dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300\">\n <span className=\"h-3 w-3 animate-spin rounded-full border-2 border-brand-400 border-t-transparent\" />\n {message ?? 'Loading...'}\n </div>\n </div>\n );\n }\n\n if (kind === 'error') {\n return (\n <div className=\"absolute inset-0 z-[5] flex items-start justify-center bg-white/80 pt-10 dark:bg-gray-900/80\">\n <div className=\"max-w-md rounded-md border border-error-300 bg-error-50 px-3 py-2 text-xs text-error-700 dark:border-error-700 dark:bg-error-500/10 dark:text-error-400\">\n {message ?? 'Something went wrong loading this grid.'}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"absolute inset-0 z-[5] flex items-start justify-center pt-10\">\n <p className=\"text-xs text-gray-500 dark:text-gray-400\">\n {message ?? 'No records found'}\n </p>\n </div>\n );\n}\n","export interface GridPaginationProps {\n page: number;\n pageSize: number;\n totalRows: number;\n pageSizeOptions: number[];\n isLoading: boolean;\n onPageChange: (page: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n}\n\nconst BUTTON_CLASS =\n 'rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 transition-colors ' +\n 'hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-40 ' +\n 'dark:border-gray-600 dark:text-gray-200 dark:hover:bg-white/5';\n\nexport function GridPagination({\n page,\n pageSize,\n totalRows,\n pageSizeOptions,\n isLoading,\n onPageChange,\n onPageSizeChange,\n}: GridPaginationProps) {\n const pageCount = Math.max(1, Math.ceil(totalRows / pageSize));\n const first = totalRows === 0 ? 0 : page * pageSize + 1;\n const last = Math.min(totalRows, (page + 1) * pageSize);\n\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-2 border-t border-gray-200 bg-gray-50 px-2 py-1.5 dark:border-gray-700 dark:bg-gray-800/60\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-gray-600 dark:text-gray-300\">\n Rows\n <select\n className=\"ml-1 rounded border border-gray-300 bg-white px-1 py-0.5 text-xs dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\n value={pageSize}\n onChange={(event) => onPageSizeChange(Number(event.target.value))}\n >\n {pageSizeOptions.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n\n <span className=\"text-xs text-gray-600 dark:text-gray-300\">\n {isLoading ? 'Loading...' : `${first}-${last} of ${totalRows}`}\n </span>\n </div>\n\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page === 0}\n onClick={() => onPageChange(0)}\n >\n « First\n </button>\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n >\n ‹ Prev\n </button>\n <span className=\"px-1 text-xs text-gray-600 dark:text-gray-300\">\n Page {page + 1} of {pageCount}\n </span>\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page + 1 >= pageCount}\n onClick={() => onPageChange(page + 1)}\n >\n Next ›\n </button>\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page + 1 >= pageCount}\n onClick={() => onPageChange(pageCount - 1)}\n >\n Last »\n </button>\n </div>\n </div>\n );\n}\n","import type { EditorParams } from '../../types';\n\nconst INPUT_CLASS =\n 'h-7 w-full rounded border px-1.5 text-xs outline-none ' +\n 'border-gray-300 bg-white text-gray-800 ' +\n 'focus:border-brand-500 focus:ring-1 focus:ring-brand-500 ' +\n 'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';\n\nconst ERROR_CLASS = '!border-error-500 focus:!border-error-500 focus:!ring-error-500';\n\nfunction className(error?: string): string {\n return error ? `${INPUT_CLASS} ${ERROR_CLASS}` : INPUT_CLASS;\n}\n\n/** Enter commits the row, Escape abandons it -- shared by every editor. */\nfunction keyHandler(params: { onCommit: () => void; onCancel: () => void }) {\n return (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n params.onCommit();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n params.onCancel();\n }\n };\n}\n\nexport function TextEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n column,\n}: EditorParams<T, C>) {\n return (\n <input\n type=\"text\"\n className={className(error)}\n value={value == null ? '' : String(value)}\n autoFocus={autoFocus}\n placeholder={column.editorParams?.placeholder}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) => onChange(event.target.value)}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n\nexport function NumberEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n}: EditorParams<T, C>) {\n return (\n <input\n type=\"number\"\n className={className(error)}\n value={value == null ? '' : String(value)}\n autoFocus={autoFocus}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) =>\n onChange(event.target.value === '' ? null : Number(event.target.value))\n }\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n\nexport function DateEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n}: EditorParams<T, C>) {\n // Normalise whatever the row holds (ISO string, Date, timestamp) to the\n // `YYYY-MM-DD` a native date input requires.\n const asInputValue = (() => {\n if (value == null || value === '') return '';\n const date = value instanceof Date ? value : new Date(String(value));\n return Number.isNaN(date.getTime()) ? '' : date.toISOString().slice(0, 10);\n })();\n\n return (\n <input\n type=\"date\"\n className={className(error)}\n value={asInputValue}\n autoFocus={autoFocus}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) => onChange(event.target.value === '' ? null : event.target.value)}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n\nexport function SelectEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n column,\n}: EditorParams<T, C>) {\n const options = column.editorParams?.options ?? [];\n const selectedIndex = options.findIndex((option) => option.value === value);\n\n return (\n <select\n className={className(error)}\n value={selectedIndex === -1 ? '' : String(selectedIndex)}\n autoFocus={autoFocus}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) => {\n const index = Number(event.target.value);\n onChange(Number.isNaN(index) ? null : options[index]?.value ?? null);\n }}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n >\n <option value=\"\">--</option>\n {options.map((option, index) => (\n <option key={`${String(option.value)}-${index}`} value={index}>\n {option.label}\n </option>\n ))}\n </select>\n );\n}\n\nexport function CheckboxEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n autoFocus,\n}: EditorParams<T, C>) {\n return (\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 accent-brand-500\"\n checked={value === true}\n autoFocus={autoFocus}\n onChange={(event) => onChange(event.target.checked)}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n","import {\n CheckboxEditor,\n DateEditor,\n NumberEditor,\n SelectEditor,\n TextEditor,\n} from './BuiltinEditors';\n\n/** Maps a `ColumnDef.editor` string to its component. */\nexport const BUILTIN_EDITORS = {\n text: TextEditor,\n number: NumberEditor,\n date: DateEditor,\n select: SelectEditor,\n checkbox: CheckboxEditor,\n} as const;\n","import { memo } from 'react';\nimport type { ColumnLayoutItem, GridApi } from '../types';\nimport { formatValue, isEditable, resolveValue } from '../core/values';\nimport { BUILTIN_EDITORS } from './editors/registry';\n\nexport interface GridCellProps<T, C> {\n item: ColumnLayoutItem<T, C>;\n row: T;\n rowIndex: number;\n context: C;\n api: GridApi<T>;\n isRowEditing: boolean;\n draft: T | null;\n errors: Record<string, string>;\n isFirstEditable: boolean;\n onFieldChange: (field: string, value: unknown) => void;\n onCommit: () => void;\n onCancel: () => void;\n}\n\nconst ALIGN_CLASS = {\n left: 'justify-start text-left',\n center: 'justify-center text-center',\n right: 'justify-end text-right',\n} as const;\n\nfunction GridCellInner<T, C>({\n item,\n row,\n rowIndex,\n context,\n api,\n isRowEditing,\n draft,\n errors,\n isFirstEditable,\n onFieldChange,\n onCommit,\n onCancel,\n}: GridCellProps<T, C>) {\n const { column, width, pinned, stickyOffset } = item;\n\n const style: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n ...(pinned === 'left'\n ? { position: 'sticky', left: stickyOffset, zIndex: 2 }\n : pinned === 'right'\n ? { position: 'sticky', right: stickyOffset, zIndex: 2 }\n : null),\n };\n\n const custom =\n typeof column.cellClassName === 'function'\n ? column.cellClassName(row)\n : column.cellClassName;\n\n const base =\n 'flex h-full items-center gap-1 border-r border-gray-200 px-2 text-xs ' +\n 'text-gray-700 dark:border-gray-700 dark:text-gray-200 ' +\n (pinned ? 'bg-white dark:bg-gray-900 ' : '');\n\n const alignment = ALIGN_CLASS[column.align ?? 'left'];\n\n // While the row is in edit mode, editable columns swap their renderer for the\n // editor and read from the draft rather than the persisted row.\n const editing = isRowEditing && draft != null && isEditable(column, row);\n\n if (editing) {\n const field = column.field ?? column.colId;\n const error = errors[field];\n const editorValue = resolveValue(draft, column as never);\n\n const Editor =\n typeof column.editor === 'function'\n ? column.editor\n : BUILTIN_EDITORS[column.editor ?? 'text'];\n\n return (\n <div\n role=\"gridcell\"\n className={`${base} ${alignment} ${custom ?? ''}`}\n style={style}\n data-col-id={column.colId}\n >\n <Editor\n value={editorValue}\n row={draft}\n column={column}\n context={context}\n error={error}\n autoFocus={isFirstEditable}\n onChange={(value: unknown) => onFieldChange(field, value)}\n onCommit={onCommit}\n onCancel={onCancel}\n />\n </div>\n );\n }\n\n const value = resolveValue(row, column as never);\n const formatted = formatValue(value, row, column as never);\n\n const content = column.cellRenderer\n ? column.cellRenderer({\n row,\n rowIndex,\n value,\n formatted,\n column,\n context,\n api,\n })\n : formatted;\n\n return (\n <div\n role=\"gridcell\"\n className={`${base} ${alignment} ${custom ?? ''}`}\n style={style}\n data-col-id={column.colId}\n title={column.cellRenderer ? undefined : formatted || undefined}\n >\n {column.cellRenderer ? (\n content\n ) : (\n <span className=\"truncate\">{formatted}</span>\n )}\n </div>\n );\n}\n\n/**\n * Memoised on the props that actually change what is painted. Volatile app\n * state reaches renderers through `context`, so a new context object re-renders\n * cells without any column definition being rebuilt.\n */\nexport const GridCell = memo(GridCellInner) as typeof GridCellInner;\n","import { memo, useState } from 'react';\nimport type { ColumnLayout, GridApi } from '../types';\nimport { isEditable } from '../core/values';\nimport type { RowId } from '../core/useSelectionModel';\nimport { GridCell } from './GridCell';\nimport { SelectionCell } from './SelectionCell';\n\nexport interface GridRowProps<T, C> {\n row: T;\n rowId: RowId;\n rowIndex: number;\n top: number;\n height: number;\n layout: ColumnLayout<T, C>;\n context: C;\n api: GridApi<T>;\n selectable: boolean;\n isSelected: boolean;\n isRowEditing: boolean;\n draft: T | null;\n errors: Record<string, string>;\n isSaving: boolean;\n onToggleSelect: (id: RowId, index: number, shiftKey: boolean) => void;\n onFieldChange: (field: string, value: unknown) => void;\n onCommit: () => void;\n onCancel: () => void;\n onRowDoubleClick: (rowId: RowId, row: T) => void;\n /** When set, files dropped on the row are handed to this callback. */\n onFilesDropped?: (row: T, files: File[]) => void;\n}\n\nfunction GridRowInner<T, C>({\n row,\n rowId,\n rowIndex,\n top,\n height,\n layout,\n context,\n api,\n selectable,\n isSelected,\n isRowEditing,\n draft,\n errors,\n isSaving,\n onToggleSelect,\n onFieldChange,\n onCommit,\n onCancel,\n onRowDoubleClick,\n onFilesDropped,\n}: GridRowProps<T, C>) {\n const [isDropTarget, setIsDropTarget] = useState(false);\n const rowError = errors.__row__;\n\n // Only the first editable column autofocuses, so entering edit mode does not\n // fight over the caret.\n const firstEditableColId = isRowEditing\n ? layout.items.find((item) => isEditable(item.column, row))?.colId\n : undefined;\n\n const background = isRowEditing\n ? 'bg-brand-25 dark:bg-brand-500/10'\n : isSelected\n ? 'bg-brand-50 dark:bg-brand-500/15'\n : rowIndex % 2 === 1\n ? 'bg-gray-50/60 dark:bg-white/[0.02]'\n : 'bg-white dark:bg-gray-900';\n\n return (\n <div\n role=\"row\"\n aria-rowindex={rowIndex + 1}\n aria-selected={selectable ? isSelected : undefined}\n className={`absolute left-0 flex border-b border-gray-200 dark:border-gray-700 ${background} hover:bg-brand-25 dark:hover:bg-white/[0.04] ${\n isSaving ? 'opacity-60' : ''\n } ${\n isDropTarget\n ? 'outline-2 -outline-offset-2 outline-dashed outline-brand-500'\n : ''\n }`}\n style={{ top, height, width: layout.totalWidth + (selectable ? 40 : 0) }}\n onDoubleClick={() => onRowDoubleClick(rowId, row)}\n title={rowError}\n onDragOver={\n onFilesDropped\n ? (event) => {\n // Only react to an actual file drag, not a column reorder.\n if (!event.dataTransfer.types.includes('Files')) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n if (!isDropTarget) setIsDropTarget(true);\n }\n : undefined\n }\n onDragLeave={onFilesDropped ? () => setIsDropTarget(false) : undefined}\n onDrop={\n onFilesDropped\n ? (event) => {\n if (!event.dataTransfer.types.includes('Files')) return;\n event.preventDefault();\n setIsDropTarget(false);\n const files = Array.from(event.dataTransfer.files);\n if (files.length > 0) onFilesDropped(row, files);\n }\n : undefined\n }\n >\n {selectable && (\n <SelectionCell\n checked={isSelected}\n onToggle={(shiftKey) => onToggleSelect(rowId, rowIndex, shiftKey)}\n />\n )}\n\n {layout.items.map((item) => (\n <GridCell\n key={item.colId}\n item={item}\n row={row}\n rowIndex={rowIndex}\n context={context}\n api={api}\n isRowEditing={isRowEditing}\n draft={draft}\n errors={errors}\n isFirstEditable={item.colId === firstEditableColId}\n onFieldChange={onFieldChange}\n onCommit={onCommit}\n onCancel={onCancel}\n />\n ))}\n </div>\n );\n}\n\nexport const GridRow = memo(GridRowInner) as typeof GridRowInner;\n","import {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type Ref,\n} from 'react';\nimport type {\n ColumnDef,\n ExportCsvOptions,\n FilterModelMap,\n GridApi,\n HxDataSource,\n HxFilterModel,\n RowCommitResult,\n SortModelItem,\n} from '../types';\nimport { useColumnState } from '../core/useColumnState';\nimport { useEditModel } from '../core/useEditModel';\nimport { useGridState } from '../core/useGridState';\nimport { useSelectionModel, type RowId } from '../core/useSelectionModel';\nimport { useServerDataSource } from '../core/useServerDataSource';\nimport { useVirtualRows } from '../core/useVirtualRows';\nimport { copyToClipboard, downloadCsv, toCsv, toTsv } from '../core/exporters';\nimport { withFilter } from '../core/filterModel';\nimport { ColumnsPanel } from './ColumnsPanel';\nimport { FloatingFilterRow } from './FloatingFilterRow';\nimport { GridHeader } from './GridHeader';\nimport { GridOverlay } from './GridOverlay';\nimport { GridPagination } from './GridPagination';\nimport { GridRow } from './GridRow';\n\nexport interface DataGridProps<T, C = unknown> {\n columns: ColumnDef<T, C>[];\n dataSource: HxDataSource<T>;\n getRowId: (row: T) => RowId;\n\n /** Volatile app state handed to every cell renderer. */\n context?: C;\n\n /** localStorage key for column/sort/filter/page-size preferences. */\n storageKey?: string;\n\n rowHeight?: number;\n headerHeight?: number;\n /** Show the always-visible filter inputs under the header. */\n floatingFilter?: boolean;\n selectable?: boolean;\n\n defaultPageSize?: number;\n pageSizeOptions?: number[];\n\n /** Enables row editing. Return `{ ok:false, errors }` to keep the row open. */\n onRowCommit?: (draft: T, original: T) => Promise<RowCommitResult> | RowCommitResult;\n onSelectionChanged?: (ids: RowId[]) => void;\n /** Enables dropping files onto a row (e.g. to attach documents to it). */\n onRowFilesDropped?: (row: T, files: File[]) => void;\n onError?: (error: unknown) => void;\n\n /** Rendered above the header; receives the live api. */\n toolbar?: (api: GridApi<T>) => ReactNode;\n\n emptyMessage?: ReactNode;\n exportFileName?: string;\n className?: string;\n /** Height of the scrolling area. Defaults to `70vh`. */\n height?: number | string;\n\n apiRef?: Ref<GridApi<T>>;\n}\n\nconst DEFAULT_PAGE_SIZES = [10, 20, 50, 100];\n\nexport function DataGrid<T, C = unknown>({\n columns,\n dataSource,\n getRowId,\n context,\n storageKey,\n rowHeight = 36,\n headerHeight = 36,\n floatingFilter = true,\n selectable = true,\n defaultPageSize = 20,\n pageSizeOptions = DEFAULT_PAGE_SIZES,\n onRowCommit,\n onSelectionChanged,\n onRowFilesDropped,\n onError,\n toolbar,\n emptyMessage,\n exportFileName = 'export',\n className = '',\n height = '70vh',\n apiRef,\n}: DataGridProps<T, C>) {\n const persisted = useGridState(storageKey);\n\n const [sortModel, setSortModel] = useState<SortModelItem[]>(\n () => persisted.initial?.sort ?? []\n );\n const [filterModel, setFilterModel] = useState<FilterModelMap>(\n () => persisted.initial?.filters ?? {}\n );\n const [pageSize, setPageSize] = useState(\n () => persisted.initial?.pagination.pageSize ?? defaultPageSize\n );\n const [page, setPage] = useState(0);\n const [showColumnsPanel, setShowColumnsPanel] = useState(false);\n\n /* ---------------------------------------------------------------------- */\n /* Measurement */\n /* ---------------------------------------------------------------------- */\n\n const viewportRef = useRef<HTMLDivElement>(null);\n const [viewportWidth, setViewportWidth] = useState(0);\n\n const floatingFilterHeight = floatingFilter ? 28 : 0;\n\n useLayoutEffect(() => {\n const element = viewportRef.current;\n if (!element) return;\n\n const observer = new ResizeObserver((entries) => {\n const rect = entries[0]?.contentRect;\n if (!rect) return;\n setViewportWidth(rect.width);\n setViewportHeightRef.current(\n Math.max(0, rect.height - headerHeight - floatingFilterHeight)\n );\n });\n\n observer.observe(element);\n return () => observer.disconnect();\n }, [headerHeight, floatingFilterHeight]);\n\n /* ---------------------------------------------------------------------- */\n /* Columns */\n /* ---------------------------------------------------------------------- */\n\n const columnState = useColumnState<T, C>(\n columns,\n persisted.initial?.columns,\n persisted.saveColumns,\n viewportWidth - (selectable ? 40 : 0)\n );\n\n /* ---------------------------------------------------------------------- */\n /* Data */\n /* ---------------------------------------------------------------------- */\n\n const { rows, totalRows, isLoading, error, refresh, patchRows } = useServerDataSource<T>(\n { dataSource, pageSize, page, sortModel, filterModel, onError }\n );\n\n // A page that no longer exists (filter narrowed the result set) would show an\n // empty grid forever, so walk back to the last real page.\n useEffect(() => {\n if (isLoading || totalRows === 0) return;\n const pageCount = Math.max(1, Math.ceil(totalRows / pageSize));\n if (page > pageCount - 1) setPage(pageCount - 1);\n }, [totalRows, pageSize, page, isLoading]);\n\n const virtual = useVirtualRows({ rowCount: rows.length, rowHeight });\n\n // Held in a ref so the ResizeObserver effect does not depend on the hook's\n // identity and re-subscribe on every render.\n const setViewportHeightRef = useRef(virtual.setViewportHeight);\n setViewportHeightRef.current = virtual.setViewportHeight;\n\n /* ---------------------------------------------------------------------- */\n /* Selection and editing */\n /* ---------------------------------------------------------------------- */\n\n const selection = useSelectionModel<T>(rows, getRowId, onSelectionChanged);\n\n const noopCommit = useCallback((): RowCommitResult => ({ ok: true }), []);\n const editing = useEditModel<T>(onRowCommit ?? noopCommit);\n\n /* ---------------------------------------------------------------------- */\n /* Query mutations */\n /* ---------------------------------------------------------------------- */\n\n // Any change to the query resets to the first page: staying on page 7 of a\n // freshly filtered result is never what the user meant.\n const applySort = useCallback(\n (next: SortModelItem[]) => {\n setSortModel(next);\n persisted.saveSort(next);\n setPage(0);\n },\n [persisted]\n );\n\n const applyFilters = useCallback(\n (next: FilterModelMap) => {\n setFilterModel(next);\n persisted.saveFilters(next);\n setPage(0);\n },\n [persisted]\n );\n\n const onSort = useCallback(\n (colId: string, additive: boolean) => {\n const existing = sortModel.find((entry) => entry.colId === colId);\n const others = sortModel.filter((entry) => entry.colId !== colId);\n\n // asc -> desc -> off\n const next: SortModelItem[] = !existing\n ? [...(additive ? sortModel : []), { colId, sort: 'asc' }]\n : existing.sort === 'asc'\n ? [...(additive ? others : []), { colId, sort: 'desc' }]\n : additive\n ? others\n : [];\n\n applySort(next);\n },\n [sortModel, applySort]\n );\n\n const onFilterChange = useCallback(\n (colId: string, filter: HxFilterModel | null) => {\n applyFilters(withFilter(filterModel, colId, filter));\n },\n [filterModel, applyFilters]\n );\n\n const onPageSizeChange = useCallback(\n (next: number) => {\n setPageSize(next);\n persisted.savePageSize(next);\n setPage(0);\n },\n [persisted]\n );\n\n /* ---------------------------------------------------------------------- */\n /* Imperative API */\n /* ---------------------------------------------------------------------- */\n\n // Latest-value refs keep the api object stable, so passing it into memoised\n // cells never invalidates them.\n const latest = useRef({\n rows,\n selection,\n columnState,\n filterModel,\n sortModel,\n editing,\n getRowId,\n });\n latest.current = {\n rows,\n selection,\n columnState,\n filterModel,\n sortModel,\n editing,\n getRowId,\n };\n\n const api = useMemo<GridApi<T>>(\n () => ({\n refresh: (options) => refresh(options),\n getDisplayedRows: () => latest.current.rows,\n getSelectedRows: () => latest.current.selection.getSelectedRows(),\n getSelectedIds: () => [...latest.current.selection.selectedIds],\n clearSelection: () => latest.current.selection.clear(),\n selectAll: () => latest.current.selection.selectAllVisible(),\n exportCsv: (options?: ExportCsvOptions) => {\n const source = options?.onlySelected\n ? latest.current.selection.getSelectedRows()\n : latest.current.rows;\n const csv = toCsv(\n source,\n latest.current.columnState.visibleColumns as never,\n options?.separator ?? ','\n );\n downloadCsv(csv, options?.fileName ?? exportFileName);\n },\n copySelectionToClipboard: async () => {\n const selected = latest.current.selection.getSelectedRows();\n const source = selected.length > 0 ? selected : latest.current.rows;\n await copyToClipboard(\n toTsv(source, latest.current.columnState.visibleColumns as never)\n );\n },\n getFilterModel: () => latest.current.filterModel,\n setFilterModel: applyFilters,\n getSortModel: () => latest.current.sortModel,\n setSortModel: applySort,\n resetColumns: () => {\n latest.current.columnState.reset();\n persisted.clear();\n },\n updateRows: (updated) => patchRows(updated, latest.current.getRowId),\n startEditing: (rowId) => {\n const row = latest.current.rows.find(\n (candidate) => latest.current.getRowId(candidate) === rowId\n );\n if (row) latest.current.editing.start(rowId, row);\n },\n stopEditing: () => latest.current.editing.cancel(),\n }),\n [refresh, applyFilters, applySort, patchRows, persisted, exportFileName]\n );\n\n useImperativeHandle(apiRef, () => api, [api]);\n\n /* ---------------------------------------------------------------------- */\n /* Row interaction */\n /* ---------------------------------------------------------------------- */\n\n const onRowDoubleClick = useCallback(\n (rowId: RowId, row: T) => {\n if (onRowCommit) editing.start(rowId, row);\n },\n [onRowCommit, editing]\n );\n\n // Clicking away from a row being edited abandons it rather than trapping the\n // user in edit mode. Keyed on the row id so the listener is attached once per\n // edit session, not once per render.\n const editingRowId = editing.edit?.rowId ?? null;\n const cancelEditRef = useRef(editing.cancel);\n cancelEditRef.current = editing.cancel;\n\n useEffect(() => {\n if (editingRowId == null) return;\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (!target.closest('[data-hxg-editing-row=\"true\"]')) cancelEditRef.current();\n };\n document.addEventListener('mousedown', onPointerDown);\n return () => document.removeEventListener('mousedown', onPointerDown);\n }, [editingRowId]);\n\n const emptyContext = useMemo(() => ({}) as C, []);\n const cellContext = context ?? emptyContext;\n\n const { startIndex, endIndex } = virtual.window;\n const visibleRows = rows.slice(startIndex, endIndex);\n\n const showEmpty = !isLoading && !error && rows.length === 0;\n\n return (\n <div\n className={`flex flex-col overflow-hidden rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900 ${className}`}\n >\n <div className=\"flex flex-wrap items-center gap-2 border-b border-gray-200 bg-gray-50 px-2 py-1.5 dark:border-gray-700 dark:bg-gray-800/60\">\n {toolbar?.(api)}\n <div className=\"ml-auto flex items-center gap-1\">\n <button\n type=\"button\"\n className=\"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-white/5\"\n onClick={() => setShowColumnsPanel((current) => !current)}\n >\n Columns\n </button>\n <button\n type=\"button\"\n className=\"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-white/5\"\n onClick={() => api.exportCsv()}\n >\n Export CSV\n </button>\n </div>\n </div>\n\n <div className=\"flex min-h-0 flex-1\">\n {showColumnsPanel && (\n <ColumnsPanel\n columns={columnState.allColumns}\n isHidden={columnState.isHidden}\n onToggle={columnState.setHidden}\n onMove={columnState.moveColumn}\n onPin={columnState.setPinned}\n onReset={() => {\n columnState.reset();\n persisted.clear();\n }}\n onClose={() => setShowColumnsPanel(false)}\n />\n )}\n\n <div\n ref={viewportRef}\n role=\"grid\"\n aria-rowcount={totalRows}\n aria-colcount={columnState.layout.items.length}\n aria-busy={isLoading}\n className=\"relative min-w-0 flex-1 overflow-auto\"\n style={{ height }}\n onScroll={virtual.onScroll}\n >\n <GridHeader\n layout={columnState.layout}\n sortModel={sortModel}\n filterModel={filterModel}\n headerHeight={headerHeight}\n selectable={selectable}\n allSelected={selection.allVisibleSelected}\n someSelected={selection.someVisibleSelected}\n onToggleAll={selection.toggleAllVisible}\n onSort={onSort}\n onFilterChange={onFilterChange}\n onResize={columnState.setWidth}\n onMove={columnState.moveColumn}\n onPin={columnState.setPinned}\n />\n\n {floatingFilter && (\n <div style={{ top: headerHeight, position: 'sticky', zIndex: 9 }}>\n <FloatingFilterRow\n layout={columnState.layout}\n filterModel={filterModel}\n height={floatingFilterHeight}\n selectable={selectable}\n onFilterChange={onFilterChange}\n />\n </div>\n )}\n\n {/* Spacer carries the full scroll height; rows are positioned into it. */}\n <div\n className=\"relative\"\n style={{\n height: virtual.totalHeight,\n width: columnState.layout.totalWidth + (selectable ? 40 : 0),\n }}\n >\n {visibleRows.map((row, offset) => {\n const rowIndex = startIndex + offset;\n const rowId = getRowId(row);\n const isRowEditing = editing.edit?.rowId === rowId;\n\n return (\n <div\n key={rowId}\n data-hxg-editing-row={isRowEditing ? 'true' : undefined}\n >\n <GridRow\n row={row}\n rowId={rowId}\n rowIndex={rowIndex}\n top={rowIndex * rowHeight}\n height={rowHeight}\n layout={columnState.layout}\n context={cellContext}\n api={api}\n selectable={selectable}\n isSelected={selection.isSelected(rowId)}\n isRowEditing={isRowEditing}\n draft={isRowEditing ? (editing.edit?.draft ?? null) : null}\n errors={isRowEditing ? (editing.edit?.errors ?? {}) : {}}\n isSaving={isRowEditing && editing.edit?.isSaving === true}\n onToggleSelect={selection.toggleRow}\n onFieldChange={editing.setField}\n onCommit={editing.commit}\n onCancel={editing.cancel}\n onRowDoubleClick={onRowDoubleClick}\n onFilesDropped={onRowFilesDropped}\n />\n </div>\n );\n })}\n </div>\n\n {isLoading && <GridOverlay kind=\"loading\" />}\n {error != null && (\n <GridOverlay\n kind=\"error\"\n message={error instanceof Error ? error.message : String(error)}\n />\n )}\n {showEmpty && <GridOverlay kind=\"empty\" message={emptyMessage} />}\n </div>\n </div>\n\n {editing.edit && (\n <div className=\"flex items-center justify-end gap-2 border-t border-brand-200 bg-brand-25 px-2 py-1.5 dark:border-brand-500/30 dark:bg-brand-500/10\">\n <span className=\"mr-auto text-xs text-gray-600 dark:text-gray-300\">\n {editing.edit.errors.__row__ ??\n 'Editing row — Enter to save, Escape to cancel.'}\n </span>\n <button\n type=\"button\"\n className=\"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200\"\n onClick={editing.cancel}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"rounded bg-brand-500 px-2.5 py-0.5 text-xs font-medium text-white hover:bg-brand-600 disabled:opacity-50\"\n disabled={editing.edit.isSaving}\n onClick={editing.commit}\n >\n {editing.edit.isSaving ? 'Saving...' : 'Save'}\n </button>\n </div>\n )}\n\n <GridPagination\n page={page}\n pageSize={pageSize}\n totalRows={totalRows}\n pageSizeOptions={pageSizeOptions}\n isLoading={isLoading}\n onPageChange={setPage}\n onPageSizeChange={onPageSizeChange}\n />\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/core/values.ts","../src/core/useColumnState.ts","../src/core/useEditModel.ts","../src/types.ts","../src/core/useGridState.ts","../src/core/useSelectionModel.ts","../src/core/useServerDataSource.ts","../src/core/useVirtualRows.ts","../src/core/exporters.ts","../src/core/filterModel.ts","../src/components/ColumnsPanel.tsx","../src/components/SelectionCell.tsx","../src/components/FloatingFilterRow.tsx","../src/components/FilterPopover.tsx","../src/components/GridHeader.tsx","../src/components/GridOverlay.tsx","../src/components/GridPagination.tsx","../src/components/editors/BuiltinEditors.tsx","../src/components/editors/registry.ts","../src/components/GridCell.tsx","../src/components/GridRow.tsx","../src/components/DataGrid.tsx"],"names":["useMemo","useState","useCallback","useRef","useEffect","window","jsxs","jsx","Fragment","BUTTON_CLASS","value","memo","className","useLayoutEffect","useImperativeHandle"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ColumnDef, ResolvedColumn } from '../types';\n\nconst DEFAULT_WIDTH = 150;\nconst DEFAULT_MIN_WIDTH = 60;\n\n/** Reads `a.b.c` out of an object, tolerating nulls along the way. */\nfunction readPath(row: unknown, path: string): unknown {\n if (row == null) return undefined;\n if (!path.includes('.')) return (row as Record<string, unknown>)[path];\n\n let current: unknown = row;\n for (const segment of path.split('.')) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\n/**\n * Resolves a cell's raw value from its row.\n *\n * Tries, in order: {@link ColumnDef.valueGetter}, the dotted `field` path, the\n * literal flat key, then each {@link ColumnDef.fieldAliases | alias}.\n *\n * @remarks\n * The fallbacks exist because servers that flatten joined relations hand back\n * `{\"customer.businessName\": x}` rather than a nested object — and some change\n * the prefix when grouping is on.\n *\n * @param row - The row to read from.\n * @param column - The column describing what to read.\n * @returns The raw value, or `undefined` if nothing matched.\n *\n * @example\n * ```ts\n * resolveValue({ customer: { name: 'Acme' } }, { field: 'customer.name', header: 'C' });\n * // 'Acme'\n * ```\n */\nexport function resolveValue<T>(row: T, column: ColumnDef<T, never>): unknown {\n if (column.valueGetter) return column.valueGetter(row);\n\n const { field } = column;\n if (!field) return undefined;\n\n const nested = readPath(row, field);\n if (nested !== undefined) return nested;\n\n const flat = (row as Record<string, unknown>)?.[field];\n if (flat !== undefined) return flat;\n\n for (const alias of column.fieldAliases ?? []) {\n const value = readPath(row, alias) ?? (row as Record<string, unknown>)?.[alias];\n if (value !== undefined) return value;\n }\n\n return undefined;\n}\n\n/**\n * The display string for a cell, independent of any custom renderer.\n *\n * Uses {@link ColumnDef.valueFormatter} when present. Otherwise `null` and\n * `undefined` become `''`, `Date` becomes `YYYY-MM-DD`, booleans become\n * `Yes`/`No`, and everything else is stringified.\n *\n * @param value - The raw value, usually from {@link resolveValue}.\n * @param row - The row it came from, passed to the formatter.\n * @param column - The column being formatted.\n * @returns The display string.\n */\nexport function formatValue<T>(value: unknown, row: T, column: ColumnDef<T, never>): string {\n if (column.valueFormatter) return column.valueFormatter(value, row);\n if (value == null) return '';\n if (value instanceof Date) return value.toISOString().slice(0, 10);\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n return String(value);\n}\n\n/**\n * The string written to CSV and the clipboard for a cell.\n *\n * Prefers {@link ColumnDef.exportValue}, falling back to {@link formatValue} —\n * which is why a column with a markup `cellRenderer` should supply one.\n *\n * @param row - The row to export.\n * @param column - The column being exported.\n * @returns The flat string for this cell.\n */\nexport function exportValue<T>(row: T, column: ColumnDef<T, never>): string {\n if (column.exportValue) return column.exportValue(row);\n return formatValue(resolveValue(row, column), row, column);\n}\n\n/**\n * Plain-text header, for exports and aria labels.\n *\n * Prefers {@link ColumnDef.headerName}, then a string or numeric `header`, then\n * falls back to the column id.\n *\n * @param column - The column to label.\n * @returns The header as plain text, or `''` if nothing usable was found.\n */\nexport function headerText<T>(column: ColumnDef<T, never>): string {\n if (column.headerName) return column.headerName;\n if (typeof column.header === 'string') return column.header;\n if (typeof column.header === 'number') return String(column.header);\n return column.colId ?? column.field ?? '';\n}\n\n/**\n * The stable id for a column: `colId`, or `field` when `colId` was omitted.\n *\n * @param column - The column to identify.\n * @returns The column id.\n * @throws If the column has neither `colId` nor `field`.\n */\nexport function columnId<T, C>(column: ColumnDef<T, C>): string {\n const id = column.colId ?? column.field;\n if (!id) {\n throw new Error('@helix-x/datagrid-ui: every column needs a `colId` or a `field`.');\n }\n return id;\n}\n\n/**\n * Fills in the defaults every other module assumes are present.\n *\n * Width defaults to 150 (never below `minWidth`), `minWidth` to 60, and both\n * `sortable` and `resizable` to `true`.\n *\n * @param column - The column as authored.\n * @returns The same column with required fields resolved.\n */\nexport function resolveColumn<T, C>(column: ColumnDef<T, C>): ResolvedColumn<T, C> {\n const minWidth = column.minWidth ?? DEFAULT_MIN_WIDTH;\n return {\n ...column,\n colId: columnId(column),\n width: Math.max(column.width ?? DEFAULT_WIDTH, minWidth),\n minWidth,\n sortable: column.sortable ?? true,\n resizable: column.resizable ?? true,\n };\n}\n\n/**\n * Whether a specific row's cell is editable in this column.\n *\n * @param column - The column to test.\n * @param row - The row to test, for a predicate `editable`.\n * @returns `true` when the cell can be edited.\n */\nexport function isEditable<T, C>(column: ColumnDef<T, C>, row: T): boolean {\n if (typeof column.editable === 'function') return column.editable(row);\n return column.editable === true;\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport type {\n ColumnDef,\n ColumnLayout,\n ColumnLayoutItem,\n Pinned,\n PersistedGridState,\n ResolvedColumn,\n} from '../types';\nimport { columnId, resolveColumn } from './values';\n\n/** The user's column layout, as persisted. */\nexport interface ColumnStateValue {\n /** Column ids in display order. */\n order: string[];\n /** Ids of hidden columns. */\n hidden: string[];\n /** Widths in pixels, by column id. */\n widths: Record<string, number>;\n /** Pinned edge, by column id. */\n pinned: Record<string, Pinned>;\n}\n\n/**\n * What {@link useColumnState} returns.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n */\nexport interface UseColumnStateResult<T, C> {\n /** Every column, in user order, including hidden ones (for the columns panel). */\n allColumns: ResolvedColumn<T, C>[];\n /** Just the visible columns, in display order. */\n visibleColumns: ResolvedColumn<T, C>[];\n /** Measured geometry for the visible columns. */\n layout: ColumnLayout<T, C>;\n /** The raw layout state, ready to persist. */\n state: ColumnStateValue;\n /** Whether a column is hidden. */\n isHidden: (colId: string) => boolean;\n /** Show or hide one column. */\n setHidden: (colId: string, hidden: boolean) => void;\n /** Resize one column. Clamped to its `minWidth` and `maxWidth`. */\n setWidth: (colId: string, width: number) => void;\n /** Pin one column to an edge, or pass `undefined` to unpin it. */\n setPinned: (colId: string, pinned: Pinned | undefined) => void;\n /** Move a column to a new index in the display order. */\n moveColumn: (colId: string, toIndex: number) => void;\n /** Discard the user's layout and return to the column definitions' defaults. */\n reset: () => void;\n}\n\nfunction defaultsFrom<T, C>(columns: ColumnDef<T, C>[]): ColumnStateValue {\n const order: string[] = [];\n const hidden: string[] = [];\n const widths: Record<string, number> = {};\n const pinned: Record<string, Pinned> = {};\n\n for (const column of columns) {\n const id = columnId(column);\n order.push(id);\n if (column.hide) hidden.push(id);\n if (column.width != null) widths[id] = column.width;\n if (column.pinned) pinned[id] = column.pinned;\n }\n\n return { order, hidden, widths, pinned };\n}\n\n/**\n * Merges persisted state *over* the column defaults, key by key.\n *\n * Deliberately not a wholesale replacement: a saved state that predates a new\n * column must not hide it, and must not discard the defaults for keys it does\n * not mention.\n */\nfunction mergePersisted(\n defaults: ColumnStateValue,\n persisted: PersistedGridState['columns'] | undefined,\n knownIds: Set<string>\n): ColumnStateValue {\n if (!persisted) return defaults;\n\n // Keep the saved order for columns that still exist, then append any new\n // columns in their declared position rather than dumping them at the end.\n const savedOrder = persisted.order.filter((id) => knownIds.has(id));\n const savedSet = new Set(savedOrder);\n const order = [...savedOrder];\n defaults.order.forEach((id, index) => {\n if (!savedSet.has(id)) order.splice(Math.min(index, order.length), 0, id);\n });\n\n return {\n order,\n hidden: (persisted.hidden ?? defaults.hidden).filter((id) => knownIds.has(id)),\n widths: { ...defaults.widths, ...(persisted.widths ?? {}) },\n pinned: { ...defaults.pinned, ...(persisted.pinned ?? {}) },\n };\n}\n\n/**\n * Column order, visibility, width and pinning, merged over the definitions'\n * defaults.\n *\n * Persisted state is merged key by key rather than replacing the defaults\n * wholesale — so a layout saved before a new column was added does not hide\n * that column, and does not discard defaults it says nothing about.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n * @returns The resolved columns, their layout, and the mutators.\n */\nexport function useColumnState<T, C>(\n columns: ColumnDef<T, C>[],\n persisted: PersistedGridState['columns'] | undefined,\n onChange: (state: ColumnStateValue) => void,\n availableWidth: number\n): UseColumnStateResult<T, C> {\n const resolved = useMemo(() => columns.map((c) => resolveColumn(c)), [columns]);\n\n const byId = useMemo(() => {\n const map = new Map<string, ResolvedColumn<T, C>>();\n for (const column of resolved) map.set(column.colId, column);\n return map;\n }, [resolved]);\n\n const defaults = useMemo(() => defaultsFrom(columns), [columns]);\n\n const [state, setState] = useState<ColumnStateValue>(() =>\n mergePersisted(defaults, persisted, new Set(defaults.order))\n );\n\n const update = useCallback(\n (mutate: (current: ColumnStateValue) => ColumnStateValue) => {\n setState((current) => {\n const next = mutate(current);\n onChange(next);\n return next;\n });\n },\n [onChange]\n );\n\n const hiddenSet = useMemo(() => new Set(state.hidden), [state.hidden]);\n\n const allColumns = useMemo(\n () =>\n state.order\n .map((id) => byId.get(id))\n .filter((c): c is ResolvedColumn<T, C> => c != null),\n [state.order, byId]\n );\n\n const visibleColumns = useMemo(\n () =>\n allColumns\n .filter((column) => !hiddenSet.has(column.colId))\n .map((column) =>\n state.widths[column.colId] != null || state.pinned[column.colId] != null\n ? {\n ...column,\n width: Math.max(\n state.widths[column.colId] ?? column.width,\n column.minWidth\n ),\n pinned: state.pinned[column.colId] ?? column.pinned,\n }\n : column\n ),\n [allColumns, hiddenSet, state.widths, state.pinned]\n );\n\n /**\n * One layout pass produces every geometry number the header and the cells\n * need, so no component computes its own offsets.\n */\n const layout = useMemo<ColumnLayout<T, C>>(() => {\n // Flex columns share whatever space the fixed ones leave over.\n const flexTotal = visibleColumns.reduce((sum, c) => sum + (c.flex ?? 0), 0);\n const fixedWidth = visibleColumns.reduce(\n (sum, c) => sum + (c.flex ? 0 : c.width),\n 0\n );\n const spare = Math.max(0, availableWidth - fixedWidth);\n\n const widthOf = (column: ResolvedColumn<T, C>) => {\n if (!column.flex || flexTotal === 0) return column.width;\n const share = Math.floor((spare * column.flex) / flexTotal);\n const capped = column.maxWidth ? Math.min(share, column.maxWidth) : share;\n return Math.max(capped, column.minWidth);\n };\n\n // Pinned columns keep their declared order but are laid out as three\n // contiguous bands: left-pinned, unpinned, right-pinned.\n const left = visibleColumns.filter((c) => c.pinned === 'left');\n const middle = visibleColumns.filter((c) => !c.pinned);\n const right = visibleColumns.filter((c) => c.pinned === 'right');\n\n const items: ColumnLayoutItem<T, C>[] = [];\n let offset = 0;\n let leftSticky = 0;\n\n for (const column of left) {\n const width = widthOf(column);\n items.push({\n column,\n colId: column.colId,\n width,\n left: offset,\n pinned: 'left',\n stickyOffset: leftSticky,\n });\n offset += width;\n leftSticky += width;\n }\n\n for (const column of middle) {\n const width = widthOf(column);\n items.push({ column, colId: column.colId, width, left: offset, stickyOffset: 0 });\n offset += width;\n }\n\n // Right-pinned sticky offsets accumulate from the right edge, so walk them\n // backwards first.\n const rightWidths = right.map(widthOf);\n let rightSticky = 0;\n const rightOffsets: number[] = [];\n for (let i = right.length - 1; i >= 0; i--) {\n rightOffsets[i] = rightSticky;\n rightSticky += rightWidths[i];\n }\n\n right.forEach((column, index) => {\n const width = rightWidths[index];\n items.push({\n column,\n colId: column.colId,\n width,\n left: offset,\n pinned: 'right',\n stickyOffset: rightOffsets[index],\n });\n offset += width;\n });\n\n return {\n items,\n totalWidth: offset,\n leftPinnedWidth: leftSticky,\n rightPinnedWidth: rightSticky,\n };\n }, [visibleColumns, availableWidth]);\n\n const isHidden = useCallback((colId: string) => hiddenSet.has(colId), [hiddenSet]);\n\n const setHidden = useCallback(\n (colId: string, hidden: boolean) => {\n update((current) => ({\n ...current,\n hidden: hidden\n ? current.hidden.includes(colId)\n ? current.hidden\n : [...current.hidden, colId]\n : current.hidden.filter((id) => id !== colId),\n }));\n },\n [update]\n );\n\n const setWidth = useCallback(\n (colId: string, width: number) => {\n update((current) => ({\n ...current,\n widths: { ...current.widths, [colId]: Math.round(width) },\n }));\n },\n [update]\n );\n\n const setPinned = useCallback(\n (colId: string, pinned: Pinned | undefined) => {\n update((current) => {\n const next = { ...current.pinned };\n if (pinned) next[colId] = pinned;\n else delete next[colId];\n return { ...current, pinned: next };\n });\n },\n [update]\n );\n\n const moveColumn = useCallback(\n (colId: string, toIndex: number) => {\n update((current) => {\n const from = current.order.indexOf(colId);\n if (from === -1 || from === toIndex) return current;\n const order = [...current.order];\n order.splice(from, 1);\n order.splice(Math.max(0, Math.min(toIndex, order.length)), 0, colId);\n return { ...current, order };\n });\n },\n [update]\n );\n\n const reset = useCallback(() => {\n update(() => defaults);\n }, [update, defaults]);\n\n return {\n allColumns,\n visibleColumns,\n layout,\n state,\n isHidden,\n setHidden,\n setWidth,\n setPinned,\n moveColumn,\n reset,\n };\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type { RowCommitResult } from '../types';\nimport type { RowId } from './useSelectionModel';\n\n/**\n * The row currently being edited.\n *\n * @typeParam T - The row type.\n */\nexport interface EditState<T> {\n /** Which row is open. */\n rowId: RowId;\n /** The working copy, updated as the user types. */\n draft: T;\n /** The row as it was when editing started, for cancel and for the commit callback. */\n original: T;\n /** Server-supplied messages from the last rejected commit, keyed by column id. */\n errors: Record<string, string>;\n /** True while a commit is in flight. */\n isSaving: boolean;\n}\n\n/**\n * What {@link useEditModel} returns.\n *\n * @typeParam T - The row type.\n */\nexport interface UseEditModelResult<T> {\n /** The open row, or `null` when nothing is being edited. */\n edit: EditState<T> | null;\n /** Whether a given row is the one currently open. */\n isEditing: (rowId: RowId) => boolean;\n /** Open a row for editing, replacing any row already open. */\n start: (rowId: RowId, row: T) => void;\n /**\n * Write one field into the draft. Accepts a dotted path, creating\n * intermediate objects as needed.\n */\n setField: (field: string, value: unknown) => void;\n /** Close without saving, discarding the draft. */\n cancel: () => void;\n /** Run the commit callback. Keeps the row open if it returns `ok: false`. */\n commit: () => Promise<void>;\n}\n\nfunction setPath<T>(row: T, path: string, value: unknown): T {\n if (!path.includes('.')) {\n return { ...row, [path]: value };\n }\n const [head, ...rest] = path.split('.');\n const current = (row as Record<string, unknown>)[head];\n return {\n ...row,\n [head]: setPath(\n (current ?? {}) as Record<string, unknown>,\n rest.join('.'),\n value\n ),\n };\n}\n\n/**\n * Row-level editing against a draft copy.\n *\n * @typeParam T - The row type.\n * @param onCommit - Owns validation and persistence. Return\n * `{ ok: false, errors }` to keep the row open with per-field messages.\n * @returns The edit state and its mutators.\n *\n * @remarks\n * The draft never touches the data source, and editors never call an API — the\n * single commit callback owns both, so an app can plug in whatever schema\n * library it uses without the grid knowing about it.\n *\n * @see {@link RowCommitResult}\n */\nexport function useEditModel<T>(\n onCommit: (draft: T, original: T) => Promise<RowCommitResult> | RowCommitResult\n): UseEditModelResult<T> {\n const [edit, setEdit] = useState<EditState<T> | null>(null);\n\n // A mirror of the state that is safe to read synchronously. `setState`\n // updaters are not guaranteed to run when they are dispatched (and may run\n // twice in StrictMode), so commit() reads the draft from here instead.\n const editRef = useRef<EditState<T> | null>(null);\n\n const apply = useCallback(\n (next: EditState<T> | null) => {\n editRef.current = next;\n setEdit(next);\n },\n []\n );\n\n const patch = useCallback((mutate: (current: EditState<T>) => EditState<T>) => {\n const current = editRef.current;\n if (!current) return;\n const next = mutate(current);\n editRef.current = next;\n setEdit(next);\n }, []);\n\n const isEditing = useCallback(\n (rowId: RowId) => edit?.rowId === rowId,\n [edit]\n );\n\n const start = useCallback(\n (rowId: RowId, row: T) => {\n apply({ rowId, draft: row, original: row, errors: {}, isSaving: false });\n },\n [apply]\n );\n\n const setField = useCallback(\n (field: string, value: unknown) => {\n patch((current) => {\n const errors = { ...current.errors };\n // Clear the error as soon as the field is touched; re-validation\n // happens on commit.\n delete errors[field];\n return { ...current, draft: setPath(current.draft, field, value), errors };\n });\n },\n [patch]\n );\n\n const cancel = useCallback(() => apply(null), [apply]);\n\n const commit = useCallback(async () => {\n const state = editRef.current;\n if (!state || state.isSaving) return;\n\n apply({ ...state, isSaving: true });\n\n try {\n const result = await onCommit(state.draft, state.original);\n if (result.ok) {\n apply(null);\n return;\n }\n patch((current) => ({ ...current, errors: result.errors, isSaving: false }));\n } catch (error) {\n patch((current) => ({\n ...current,\n isSaving: false,\n errors: {\n ...current.errors,\n __row__:\n error instanceof Error ? error.message : 'Failed to save the row.',\n },\n }));\n }\n }, [onCommit, apply, patch]);\n\n return { edit, isEditing, start, setField, cancel, commit };\n}\n","/**\n * Every public type in `@helix-x/datagrid-ui`.\n *\n * The filter, sort and row-request shapes deliberately mirror what ag-grid's\n * server-side row model posts, so a backend written for that model accepts this\n * grid's requests unchanged.\n */\n\nimport type { ReactNode } from 'react';\n\n/* -------------------------------------------------------------------------- */\n/* Filter models */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Comparison operators available on a `text` column filter.\n *\n * `blank` and `notBlank` take no operand — see {@link isUnaryFilter}.\n *\n * @see {@link TEXT_FILTER_TYPES} for the same list as a runtime array.\n */\nexport type TextFilterType =\n | 'contains'\n | 'notContains'\n | 'equals'\n | 'notEqual'\n | 'startsWith'\n | 'endsWith'\n | 'blank'\n | 'notBlank';\n\n/**\n * Comparison operators available on a `number` column filter.\n *\n * `inRange` uses both `filter` and `filterTo`; `blank` and `notBlank` take no\n * operand at all.\n *\n * @see {@link NUMBER_FILTER_TYPES} for the same list as a runtime array.\n */\nexport type NumberFilterType =\n | 'equals'\n | 'notEqual'\n | 'lessThan'\n | 'lessThanOrEqual'\n | 'greaterThan'\n | 'greaterThanOrEqual'\n | 'inRange'\n | 'blank'\n | 'notBlank';\n\n/**\n * Comparison operators available on a `date` column filter.\n *\n * `inRange` uses both `dateFrom` and `dateTo`; `blank` and `notBlank` take no\n * operand.\n *\n * @see {@link DATE_FILTER_TYPES} for the same list as a runtime array.\n */\nexport type DateFilterType =\n | 'equals'\n | 'notEqual'\n | 'before'\n | 'after'\n | 'inRange'\n | 'blank'\n | 'notBlank';\n\n/**\n * A text filter as sent to the server.\n *\n * @example\n * ```ts\n * const model: TextFilterModel = {\n * filterType: 'text',\n * type: 'contains',\n * filter: 'acme',\n * };\n * ```\n */\nexport interface TextFilterModel {\n /** Discriminant. Always `'text'`. */\n filterType: 'text';\n /** The comparison to apply. */\n type: TextFilterType;\n /** The search term. Absent for `blank` and `notBlank`. */\n filter?: string;\n}\n\n/**\n * A numeric filter as sent to the server.\n *\n * @example Between two values\n * ```ts\n * const model: NumberFilterModel = {\n * filterType: 'number',\n * type: 'inRange',\n * filter: 10,\n * filterTo: 100,\n * };\n * ```\n */\nexport interface NumberFilterModel {\n /** Discriminant. Always `'number'`. */\n filterType: 'number';\n /** The comparison to apply. */\n type: NumberFilterType;\n /** The operand, or the lower bound when `type` is `'inRange'`. */\n filter?: number;\n /** The upper bound. Only meaningful when `type` is `'inRange'`. */\n filterTo?: number;\n}\n\n/**\n * A date filter as sent to the server.\n *\n * Dates are calendar days, not instants — compare on the day, or a same-day\n * timestamp will never match its own date.\n *\n * @example\n * ```ts\n * const model: DateFilterModel = {\n * filterType: 'date',\n * type: 'after',\n * dateFrom: '2026-01-01',\n * };\n * ```\n */\nexport interface DateFilterModel {\n /** Discriminant. Always `'date'`. */\n filterType: 'date';\n /** The comparison to apply. */\n type: DateFilterType;\n /** Lower bound, formatted `YYYY-MM-DD`. */\n dateFrom?: string;\n /** Upper bound, formatted `YYYY-MM-DD`. Only used by `'inRange'`. */\n dateTo?: string;\n}\n\n/**\n * A set (multi-select) filter as sent to the server.\n *\n * An empty `values` array means \"no constraint\" — that is how the grid clears\n * a set filter. {@link buildSetFilter} returns `null` rather than an empty set.\n *\n * @example\n * ```ts\n * const model: SetFilterModel = {\n * filterType: 'set',\n * values: ['ACTIVE', 'PENDING'],\n * };\n * ```\n */\nexport interface SetFilterModel {\n /** Discriminant. Always `'set'`. */\n filterType: 'set';\n /** The selected values. Compared as strings. */\n values: string[];\n}\n\n/**\n * Any one column filter. Discriminate on `filterType`.\n *\n * @example\n * ```ts\n * function describe(filter: HxFilterModel) {\n * switch (filter.filterType) {\n * case 'text': return filter.filter;\n * case 'number': return filter.filter;\n * case 'date': return filter.dateFrom;\n * case 'set': return filter.values.join(', ');\n * }\n * }\n * ```\n */\nexport type HxFilterModel =\n | TextFilterModel\n | NumberFilterModel\n | DateFilterModel\n | SetFilterModel;\n\n/**\n * Every active filter, keyed by {@link ColumnDef.colId | column id}.\n *\n * A column with no entry is unfiltered. Use {@link withFilter} to add or remove\n * one immutably.\n */\nexport type FilterModelMap = Record<string, HxFilterModel>;\n\n/**\n * Which filter UI a column offers, set via {@link ColumnDef.filter}.\n *\n * Pass `false` on the column instead to disable filtering entirely.\n */\nexport type FilterKind = 'text' | 'number' | 'date' | 'set';\n\n/* -------------------------------------------------------------------------- */\n/* Sorting */\n/* -------------------------------------------------------------------------- */\n\n/** Sort direction for one column. */\nexport type SortDirection = 'asc' | 'desc';\n\n/**\n * One entry in the sort model.\n *\n * The model is an ordered array: the first entry is the primary sort, and later\n * entries break ties in the ones before them.\n *\n * @example Sort by status, then by newest first\n * ```ts\n * const sortModel: SortModelItem[] = [\n * { colId: 'status', sort: 'asc' },\n * { colId: 'createdAt', sort: 'desc' },\n * ];\n * ```\n */\nexport interface SortModelItem {\n /** The {@link ColumnDef.colId | column id} to sort on. */\n colId: string;\n /** Direction to sort in. */\n sort: SortDirection;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Data source */\n/* -------------------------------------------------------------------------- */\n\n/**\n * What the grid asks the server for: one page, with the active sort and\n * filters.\n *\n * Structurally compatible with ag-grid's `IServerSideGetRowsRequest`, so an\n * endpoint written for that model accepts this verbatim. The grouping and pivot\n * fields are always sent empty — this grid does not implement them — but they\n * are present so servers that destructure them do not fall over.\n *\n * @example Handling the request on the server\n * ```ts\n * app.post('/api/rows', (req, res) => {\n * const { startRow, endRow, sortModel, filterModel } = req.body;\n * const filtered = applyFilters(allRows, filterModel);\n * const sorted = applySort(filtered, sortModel);\n * res.json({ rows: sorted.slice(startRow, endRow), lastRow: filtered.length });\n * });\n * ```\n */\nexport interface HxRowsRequest {\n /** Zero-based index of the first row wanted, inclusive. */\n startRow: number;\n /** Index one past the last row wanted, exclusive. */\n endRow: number;\n /** Active sorts, primary first. Empty when unsorted. */\n sortModel: SortModelItem[];\n /** Active filters, keyed by column id. Empty when unfiltered. */\n filterModel: FilterModelMap;\n /** Always empty. Present only for ag-grid wire compatibility. */\n rowGroupCols: never[];\n /** Always empty. Present only for ag-grid wire compatibility. */\n valueCols: never[];\n /** Always empty. Present only for ag-grid wire compatibility. */\n pivotCols: never[];\n /** Always `false`. Present only for ag-grid wire compatibility. */\n pivotMode: false;\n /** Always empty. Present only for ag-grid wire compatibility. */\n groupKeys: never[];\n}\n\n/**\n * What the server returns for one {@link HxRowsRequest}.\n *\n * @typeParam T - The row type.\n */\nexport interface HxRowsResponse<T> {\n /** The rows for the requested page only, not the whole result set. */\n rows: T[];\n /**\n * Total row count across **all** pages — not `rows.length`. This is what\n * drives the pager. Return `-1` when the total is genuinely unknown.\n */\n lastRow: number;\n}\n\n/**\n * The grid's one required dependency: something that turns a request into rows.\n *\n * @typeParam T - The row type.\n *\n * @example\n * ```tsx\n * const dataSource: HxDataSource<Person> = {\n * getRows: async (request, signal) => {\n * const response = await fetch('/api/people', {\n * method: 'POST',\n * headers: { 'content-type': 'application/json' },\n * body: JSON.stringify(request),\n * signal,\n * });\n * return response.json();\n * },\n * };\n * ```\n *\n * @remarks\n * Memoise the object (or define it outside the component). A new identity on\n * every render causes a refetch.\n */\nexport interface HxDataSource<T> {\n /**\n * Fetch one page of rows.\n *\n * @param request - The page, sort and filters being asked for.\n * @param signal - Aborts when the grid supersedes this request. Pass it to\n * `fetch` so a slow response for an old sort can never overwrite a newer one.\n * @returns The page of rows plus the total row count.\n */\n getRows(request: HxRowsRequest, signal: AbortSignal): Promise<HxRowsResponse<T>>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Columns */\n/* -------------------------------------------------------------------------- */\n\n/** Which edge a pinned column sticks to. */\nexport type Pinned = 'left' | 'right';\n\n/**\n * What {@link ColumnDef.cellRenderer} receives.\n *\n * @typeParam T - The row type.\n * @typeParam C - The {@link DataGridProps.context | context} type.\n */\nexport interface CellRendererParams<T, C = unknown> {\n /** The whole row, for cells that need more than their own field. */\n row: T;\n /** Index within the currently loaded page, not the full result set. */\n rowIndex: number;\n /** The raw value, after {@link ColumnDef.valueGetter}. */\n value: unknown;\n /** The display string, after {@link ColumnDef.valueFormatter}. */\n formatted: string;\n /** The column being rendered. */\n column: ColumnDef<T, C>;\n /**\n * Arbitrary app state handed to every renderer. Put volatile things here\n * (in-flight ids, permission checks, handlers) so column definitions can stay\n * memoised on `[]` and never rebuild.\n */\n context: C;\n /** The live imperative API, for renderers that act on the grid. */\n api: GridApi<T>;\n}\n\n/**\n * What a cell editor receives — both the built-ins and your own.\n *\n * @typeParam T - The row type.\n * @typeParam C - The {@link DataGridProps.context | context} type.\n */\nexport interface EditorParams<T, C = unknown> {\n /** Current draft value for this cell. */\n value: unknown;\n /** The row being edited, as a draft copy. */\n row: T;\n /** The column being edited. */\n column: ColumnDef<T, C>;\n /** The grid's {@link DataGridProps.context | context}. */\n context: C;\n /** Writes into the row draft. Never hits the network. */\n onChange: (value: unknown) => void;\n /** Commit the whole row, invoking {@link DataGridProps.onRowCommit}. */\n onCommit: () => void;\n /** Abandon the edit and restore the original row. */\n onCancel: () => void;\n /** Server-supplied message for this field, if the last commit was rejected. */\n error?: string;\n /** True for the first editable cell in the row. */\n autoFocus?: boolean;\n}\n\n/**\n * A custom cell editor.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n *\n * @example A trimming text editor\n * ```tsx\n * const TrimmedEditor: EditorComponent<Person> = ({ value, onChange, onCommit, onCancel }) => (\n * <input\n * autoFocus\n * value={String(value ?? '')}\n * onChange={(e) => onChange(e.target.value.trim())}\n * onKeyDown={(e) => {\n * if (e.key === 'Enter') onCommit();\n * if (e.key === 'Escape') onCancel();\n * }}\n * />\n * );\n * ```\n */\nexport type EditorComponent<T, C = unknown> = (\n params: EditorParams<T, C>\n) => ReactNode;\n\n/**\n * Names of the editors that ship with the grid.\n *\n * @see {@link BUILTIN_EDITORS} for the components these map to.\n */\nexport type BuiltinEditor = 'text' | 'number' | 'select' | 'date' | 'checkbox';\n\n/** One choice offered by the `select` editor. */\nexport interface SelectOption {\n /** Shown to the user. */\n label: string;\n /** Written into the row draft. */\n value: unknown;\n}\n\n/**\n * One column. This is the main thing you write when using the grid.\n *\n * @typeParam T - The row type.\n * @typeParam C - The {@link DataGridProps.context | context} type.\n *\n * @example A representative set of columns\n * ```tsx\n * const columns: ColumnDef<Person>[] = [\n * { field: 'id', header: 'ID', width: 90, filter: 'number' },\n * { field: 'name', header: 'Name', flex: 1, filter: 'text', editable: true },\n * {\n * field: 'status',\n * header: 'Status',\n * filter: 'set',\n * filterParams: { values: () => fetch('/api/statuses').then((r) => r.json()) },\n * editable: true,\n * editor: 'select',\n * editorParams: { options: [{ label: 'Active', value: 'ACTIVE' }] },\n * },\n * {\n * colId: 'fullName',\n * header: 'Full name',\n * sortable: false,\n * valueGetter: (row) => `${row.first} ${row.last}`,\n * },\n * ];\n * ```\n *\n * @remarks\n * Define columns as a module constant or memoise on `[]`. Anything volatile\n * belongs in {@link DataGridProps.context} instead, which reaches every\n * renderer without rebuilding a single definition.\n */\nexport interface ColumnDef<T, C = unknown> {\n /**\n * Stable identity, used as the key in the sort and filter models and in\n * persisted layout. Falls back to {@link ColumnDef.field | field} when\n * omitted; one of the two is required.\n */\n colId?: string;\n /**\n * Dotted path into the row (`'customer.name'`), and the key sent to the\n * server for sorting and filtering.\n *\n * Omit it for purely derived columns and supply `colId` plus\n * {@link ColumnDef.valueGetter | valueGetter} instead.\n */\n field?: string;\n /** Header content. Any node — an icon, a tooltip wrapper, anything. */\n header: ReactNode;\n /**\n * Plain-text header for exports and aria labels. Required in practice\n * whenever `header` is a node rather than a string.\n */\n headerName?: string;\n\n /**\n * Starting width in pixels.\n * @defaultValue 150\n */\n width?: number;\n /**\n * Floor for both `flex` and user resizing.\n * @defaultValue 60\n */\n minWidth?: number;\n /** Ceiling for user resizing. */\n maxWidth?: number;\n /**\n * Share of the leftover horizontal space, like `flex-grow`. A column with\n * `flex: 2` takes twice the slack of one with `flex: 1`.\n */\n flex?: number;\n\n /** Stick this column to an edge while the rest scroll horizontally. */\n pinned?: Pinned;\n /** Start hidden. The user can still reveal it from the columns panel. */\n hide?: boolean;\n /**\n * Allow click-to-sort on the header.\n * @defaultValue true\n */\n sortable?: boolean;\n /**\n * Allow drag-to-resize.\n * @defaultValue true\n */\n resizable?: boolean;\n /** Prevent the user dragging this column out of position. */\n lockPosition?: boolean;\n\n /**\n * Which filter UI to offer, or `false` for none.\n *\n * @defaultValue undefined (no filter)\n */\n filter?: FilterKind | false;\n /** Extra options for the filter named by {@link ColumnDef.filter}. */\n filterParams?: {\n /**\n * Options for a `set` filter: a static list, or a function called the first\n * time the popover opens so the list can come from an API.\n */\n values?: string[] | (() => Promise<string[]>);\n /** Hide the always-visible filter input under the header for this column. */\n suppressFloatingFilter?: boolean;\n };\n\n /**\n * Alternative flat keys to try when the server flattens nested fields — some\n * backends return `{\"customer.name\": x}` rather than a nested object, and\n * change the prefix when grouping is on.\n */\n fieldAliases?: string[];\n\n /**\n * Compute the cell value instead of reading `field`. Takes precedence over\n * every other lookup.\n */\n valueGetter?: (row: T) => unknown;\n /**\n * Turn the raw value into its display string. Also used for exports unless\n * {@link ColumnDef.exportValue} is given.\n */\n valueFormatter?: (value: unknown, row: T) => string;\n /**\n * Render the cell as markup. Presentation only — sorting and filtering still\n * use `field`, so a decorated cell keeps behaving like a plain one.\n */\n cellRenderer?: (params: CellRendererParams<T, C>) => ReactNode;\n\n /** Whether the cell can be edited, optionally per row. */\n editable?: boolean | ((row: T) => boolean);\n /**\n * Which editor to use: a {@link BuiltinEditor} name or your own component.\n * @defaultValue 'text'\n */\n editor?: BuiltinEditor | EditorComponent<T, C>;\n /** Extra options for the editor named by {@link ColumnDef.editor}. */\n editorParams?: {\n /** Choices for the `select` editor. */\n options?: SelectOption[];\n /** Placeholder for the `text` and `number` editors. */\n placeholder?: string;\n };\n\n /**\n * The flat string written to CSV and the clipboard. Supply this whenever\n * {@link ColumnDef.cellRenderer} produces markup.\n */\n exportValue?: (row: T) => string;\n /** Leave this column out of CSV and clipboard output entirely. */\n suppressExport?: boolean;\n\n /** Extra classes on every cell, optionally per row. */\n cellClassName?: string | ((row: T) => string);\n /** Extra classes on the header cell. */\n headerClassName?: string;\n /**\n * Horizontal alignment of the cell content.\n * @defaultValue 'left'\n */\n align?: 'left' | 'center' | 'right';\n}\n\n/**\n * A {@link ColumnDef} with every optional default filled in.\n *\n * Produced by {@link resolveColumn}. Mostly internal, but exported because the\n * exporter helpers and the columns panel take it.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n */\nexport interface ResolvedColumn<T, C = unknown> extends ColumnDef<T, C> {\n /** Always present — `colId`, or `field` when `colId` was omitted. */\n colId: string;\n /** Resolved width, never below `minWidth`. */\n width: number;\n /** Resolved minimum width. */\n minWidth: number;\n /** Resolved sortability. */\n sortable: boolean;\n /** Resolved resizability. */\n resizable: boolean;\n}\n\n/**\n * Geometry for one visible column, computed once per layout change.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n */\nexport interface ColumnLayoutItem<T, C = unknown> {\n /** The column this geometry belongs to. */\n column: ResolvedColumn<T, C>;\n /** Convenience copy of `column.colId`. */\n colId: string;\n /** Final pixel width, after `flex` distribution and user resizing. */\n width: number;\n /** Offset from the left edge of the full (unscrolled) column strip. */\n left: number;\n /** Which edge this column is pinned to, if any. */\n pinned?: Pinned;\n /** `left`/`right` offset to use for `position: sticky` on pinned columns. */\n stickyOffset: number;\n}\n\n/**\n * The measured layout of every visible column.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n */\nexport interface ColumnLayout<T, C = unknown> {\n /** Visible columns in display order, each with its geometry. */\n items: ColumnLayoutItem<T, C>[];\n /** Combined width of all visible columns. */\n totalWidth: number;\n /** Combined width of the left-pinned columns. */\n leftPinnedWidth: number;\n /** Combined width of the right-pinned columns. */\n rightPinnedWidth: number;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Editing */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The outcome of {@link DataGridProps.onRowCommit}.\n *\n * Returning `ok: false` keeps the row in edit mode and paints each message onto\n * the cell whose column id it is keyed by — which is how server-side validation\n * reaches the user without being mirrored in the client.\n *\n * @example\n * ```ts\n * async function onRowCommit(draft: Person): Promise<RowCommitResult> {\n * const response = await fetch(`/api/people/${draft.id}`, {\n * method: 'PATCH',\n * body: JSON.stringify(draft),\n * });\n * if (response.status === 422) {\n * const { errors, message } = await response.json();\n * return { ok: false, errors, message };\n * }\n * return { ok: true, row: await response.json() };\n * }\n * ```\n */\nexport type RowCommitResult =\n | {\n /** Discriminant: the row was saved. */\n ok: true;\n /**\n * The server's canonical copy, which replaces the row in place. Useful\n * when the server fills in derived fields.\n */\n row?: unknown;\n }\n | {\n /** Discriminant: the row was rejected and stays open. */\n ok: false;\n /** Messages keyed by column id, painted onto the offending cells. */\n errors: Record<string, string>;\n /** A single message for the whole row. */\n message?: string;\n };\n\n/* -------------------------------------------------------------------------- */\n/* Persisted state */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Schema version for {@link PersistedGridState}.\n *\n * Saved state carrying a different version is discarded rather than migrated:\n * the layout is a convenience, and a bad restore is worse than starting from\n * the column defaults.\n */\nexport const GRID_STATE_VERSION = 1;\n\n/**\n * What the grid writes to `localStorage` under\n * {@link DataGridProps.storageKey}.\n *\n * Stored under the key `hxg:<storageKey>`.\n */\nexport interface PersistedGridState {\n /** Schema version. Compared against {@link GRID_STATE_VERSION} on read. */\n v: number;\n /** Column layout the user arranged. */\n columns: {\n /** Column ids in display order. */\n order: string[];\n /** Ids of columns the user hid. */\n hidden: string[];\n /** User-resized widths, by column id. */\n widths: Record<string, number>;\n /** User-pinned columns, by column id. */\n pinned: Record<string, Pinned>;\n };\n /** The sort model at the time of saving. */\n sort: SortModelItem[];\n /** The filter model at the time of saving. */\n filters: FilterModelMap;\n /** Paging preferences. */\n pagination: {\n /** Rows per page the user chose. */\n pageSize: number;\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Imperative API */\n/* -------------------------------------------------------------------------- */\n\n/** Options for {@link GridApi.exportCsv}. */\nexport interface ExportCsvOptions {\n /**\n * Export only the selected rows rather than the whole loaded page.\n * @defaultValue false\n */\n onlySelected?: boolean;\n /**\n * File name, with or without the `.csv` suffix.\n * @defaultValue the grid's `exportFileName` prop\n */\n fileName?: string;\n /**\n * Field separator.\n * @defaultValue ','\n */\n separator?: string;\n}\n\n/**\n * The imperative handle onto a live grid.\n *\n * Reach it either through {@link DataGridProps.apiRef} or as\n * {@link DataGridProps.toolbar}'s argument.\n *\n * @typeParam T - The row type.\n *\n * @example\n * ```tsx\n * const apiRef = useRef<GridApi<Person>>(null);\n *\n * <DataGrid\n * apiRef={apiRef}\n * toolbar={(api) => (\n * <button onClick={() => api.exportCsv({ onlySelected: true })}>\n * Export selection\n * </button>\n * )}\n * {...rest}\n * />\n * ```\n */\nexport interface GridApi<T> {\n /**\n * Re-fetch the current page.\n *\n * @param options - `purge: true` drops every cached block first, so nothing\n * stale can survive; otherwise cached neighbouring pages are kept.\n */\n refresh(options?: { purge?: boolean }): void;\n /** The rows currently loaded for this page, in display order. */\n getDisplayedRows(): T[];\n /** The selected rows that are on the current page. */\n getSelectedRows(): T[];\n /** Ids of every selected row, including those on other pages. */\n getSelectedIds(): Array<string | number>;\n /** Deselect everything. */\n clearSelection(): void;\n /** Select every row on the current page. */\n selectAll(): void;\n /** Download the rows as CSV, honouring each column's `exportValue`. */\n exportCsv(options?: ExportCsvOptions): void;\n /** Copy the selection to the clipboard as TSV, which spreadsheets expect. */\n copySelectionToClipboard(): Promise<void>;\n /** The active filters. */\n getFilterModel(): FilterModelMap;\n /** Replace every filter at once, triggering one refetch. */\n setFilterModel(model: FilterModelMap): void;\n /** The active sorts, primary first. */\n getSortModel(): SortModelItem[];\n /** Replace the sort model, triggering one refetch. */\n setSortModel(model: SortModelItem[]): void;\n /** Discard the user's column layout and return to the definitions' defaults. */\n resetColumns(): void;\n /**\n * Patch rows already on screen, matched by `getRowId`, without a round trip.\n *\n * Ids that are not on the current page are ignored, so a live feed can push\n * everything it has without the client filtering first. Scroll position,\n * selection, sort and any open editor are all preserved.\n *\n * @param rows - Whole replacement rows, not partials.\n */\n updateRows(rows: T[]): void;\n /**\n * Open the row editor programmatically.\n * @param rowId - The id, as returned by `getRowId`.\n */\n startEditing(rowId: string | number): void;\n /** Close the editor, abandoning any uncommitted draft. */\n stopEditing(): void;\n}\n","import { useCallback, useRef, useState } from 'react';\nimport {\n GRID_STATE_VERSION,\n type FilterModelMap,\n type PersistedGridState,\n type SortModelItem,\n} from '../types';\n\nconst PREFIX = 'hxg:';\n\nfunction read(storageKey: string): PersistedGridState | undefined {\n if (typeof window === 'undefined') return undefined;\n try {\n const raw = window.localStorage.getItem(PREFIX + storageKey);\n if (!raw) return undefined;\n const parsed = JSON.parse(raw) as PersistedGridState;\n // A shape from an older version is dropped rather than migrated: the state\n // is a convenience, and a bad restore is worse than starting from defaults.\n if (!parsed || parsed.v !== GRID_STATE_VERSION) return undefined;\n return parsed;\n } catch {\n return undefined;\n }\n}\n\nfunction write(storageKey: string, state: PersistedGridState): void {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(PREFIX + storageKey, JSON.stringify(state));\n } catch {\n // Quota or a privacy mode: persistence is best-effort.\n }\n}\n\n/** What {@link useGridState} returns. */\nexport interface UseGridStateResult {\n /**\n * The restored state, read once on mount and never re-read — so it is safe\n * to use as a `useState` initial value. `undefined` when nothing was saved\n * or the saved schema version did not match.\n */\n initial: PersistedGridState | undefined;\n /** Persist the column layout. */\n saveColumns: (columns: PersistedGridState['columns']) => void;\n /** Persist the sort model. */\n saveSort: (sort: SortModelItem[]) => void;\n /** Persist the filter model. */\n saveFilters: (filters: FilterModelMap) => void;\n /** Persist the page size. */\n savePageSize: (pageSize: number) => void;\n /** Delete the saved state entirely. */\n clear: () => void;\n /** Whether anything was restored on mount. */\n hasSavedState: boolean;\n}\n\n/**\n * Versioned `localStorage` persistence for one grid's layout.\n *\n * Writes go through a ref, so saving never causes a re-render. Every read and\n * write is wrapped: a quota error or a privacy mode degrades to not persisting\n * rather than throwing, and state saved under a different\n * {@link GRID_STATE_VERSION} is discarded rather than migrated.\n *\n * @param storageKey - Key to store under, namespaced as `hxg:<storageKey>`.\n * Pass `undefined` to disable persistence entirely.\n * @returns The restored state and its setters.\n */\nexport function useGridState(storageKey: string | undefined): UseGridStateResult {\n const initialRef = useRef<PersistedGridState | undefined>(\n storageKey ? read(storageKey) : undefined\n );\n const [hasSavedState, setHasSavedState] = useState(() => initialRef.current != null);\n\n // The live copy the setters mutate; kept in a ref so saving never re-renders.\n const currentRef = useRef<PersistedGridState>(\n initialRef.current ?? {\n v: GRID_STATE_VERSION,\n columns: { order: [], hidden: [], widths: {}, pinned: {} },\n sort: [],\n filters: {},\n pagination: { pageSize: 20 },\n }\n );\n\n const persist = useCallback(\n (patch: Partial<PersistedGridState>) => {\n if (!storageKey) return;\n currentRef.current = { ...currentRef.current, ...patch, v: GRID_STATE_VERSION };\n write(storageKey, currentRef.current);\n setHasSavedState(true);\n },\n [storageKey]\n );\n\n const saveColumns = useCallback(\n (columns: PersistedGridState['columns']) => persist({ columns }),\n [persist]\n );\n const saveSort = useCallback((sort: SortModelItem[]) => persist({ sort }), [persist]);\n const saveFilters = useCallback(\n (filters: FilterModelMap) => persist({ filters }),\n [persist]\n );\n const savePageSize = useCallback(\n (pageSize: number) => persist({ pagination: { pageSize } }),\n [persist]\n );\n\n const clear = useCallback(() => {\n if (!storageKey || typeof window === 'undefined') return;\n try {\n window.localStorage.removeItem(PREFIX + storageKey);\n } catch {\n // ignore\n }\n setHasSavedState(false);\n }, [storageKey]);\n\n return {\n initial: initialRef.current,\n saveColumns,\n saveSort,\n saveFilters,\n savePageSize,\n clear,\n hasSavedState,\n };\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\n\n/**\n * A row's stable identity, as returned by `getRowId`.\n *\n * Selection, editing and {@link GridApi.updateRows} all key off this.\n */\nexport type RowId = string | number;\n\n/**\n * What {@link useSelectionModel} returns.\n *\n * @typeParam T - The row type.\n */\nexport interface UseSelectionModelResult<T> {\n /** Every selected id, including rows on pages that are not loaded. */\n selectedIds: Set<RowId>;\n /** Whether one id is selected. */\n isSelected: (id: RowId) => boolean;\n /** True when every row currently on screen is selected. */\n allVisibleSelected: boolean;\n /** True when some, but not all, visible rows are selected. */\n someVisibleSelected: boolean;\n /**\n * Toggle one row.\n * @param id - The row to toggle.\n * @param index - Its index in the loaded page, used as the shift anchor.\n * @param shiftKey - Extend from the last toggled row instead of toggling one.\n */\n toggleRow: (id: RowId, index: number, shiftKey: boolean) => void;\n /** Select every visible row, or deselect them if all are already selected. */\n toggleAllVisible: () => void;\n /** Deselect everything, including rows on other pages. */\n clear: () => void;\n /** Select every row on the current page. */\n selectAllVisible: () => void;\n /** The selected rows that are currently loaded. */\n getSelectedRows: () => T[];\n}\n\n/**\n * Multi-row selection with shift-range support.\n *\n * Selection survives paging: ids stay selected even when their rows are not\n * loaded, which is why `getSelectedRows` returns only the loaded subset while\n * `selectedIds` holds everything.\n *\n * @typeParam T - The row type.\n * @param rows - The currently loaded page.\n * @param getRowId - Stable identity for a row.\n * @param onSelectionChanged - Called with every selected id after each change.\n * @returns The selection state and its mutators.\n */\nexport function useSelectionModel<T>(\n rows: T[],\n getRowId: (row: T) => RowId,\n onSelectionChanged?: (ids: RowId[]) => void\n): UseSelectionModelResult<T> {\n const [selectedIds, setSelectedIds] = useState<Set<RowId>>(() => new Set());\n const lastToggledIndexRef = useRef<number | null>(null);\n\n const rowsRef = useRef(rows);\n rowsRef.current = rows;\n const getRowIdRef = useRef(getRowId);\n getRowIdRef.current = getRowId;\n\n const commit = useCallback(\n (next: Set<RowId>) => {\n setSelectedIds(next);\n onSelectionChanged?.([...next]);\n },\n [onSelectionChanged]\n );\n\n const isSelected = useCallback((id: RowId) => selectedIds.has(id), [selectedIds]);\n\n const visibleIds = useMemo(() => rows.map(getRowId), [rows, getRowId]);\n\n const allVisibleSelected =\n visibleIds.length > 0 && visibleIds.every((id) => selectedIds.has(id));\n const someVisibleSelected =\n !allVisibleSelected && visibleIds.some((id) => selectedIds.has(id));\n\n const toggleRow = useCallback(\n (id: RowId, index: number, shiftKey: boolean) => {\n const next = new Set(selectedIds);\n const anchor = lastToggledIndexRef.current;\n\n if (shiftKey && anchor != null && anchor !== index) {\n // Shift extends from the last click across the loaded window.\n const [from, to] = anchor < index ? [anchor, index] : [index, anchor];\n const shouldSelect = !next.has(id);\n for (let i = from; i <= to; i++) {\n const rowId = getRowIdRef.current(rowsRef.current[i]);\n if (rowId == null) continue;\n if (shouldSelect) next.add(rowId);\n else next.delete(rowId);\n }\n } else if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n\n lastToggledIndexRef.current = index;\n commit(next);\n },\n [selectedIds, commit]\n );\n\n const toggleAllVisible = useCallback(() => {\n const next = new Set(selectedIds);\n if (allVisibleSelected) {\n for (const id of visibleIds) next.delete(id);\n } else {\n for (const id of visibleIds) next.add(id);\n }\n lastToggledIndexRef.current = null;\n commit(next);\n }, [selectedIds, allVisibleSelected, visibleIds, commit]);\n\n const selectAllVisible = useCallback(() => {\n const next = new Set(selectedIds);\n for (const id of visibleIds) next.add(id);\n commit(next);\n }, [selectedIds, visibleIds, commit]);\n\n const clear = useCallback(() => {\n lastToggledIndexRef.current = null;\n commit(new Set());\n }, [commit]);\n\n const getSelectedRows = useCallback(\n () => rowsRef.current.filter((row) => selectedIds.has(getRowIdRef.current(row))),\n [selectedIds]\n );\n\n return {\n selectedIds,\n isSelected,\n allVisibleSelected,\n someVisibleSelected,\n toggleRow,\n toggleAllVisible,\n clear,\n selectAllVisible,\n getSelectedRows,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { FilterModelMap, HxDataSource, HxRowsRequest, SortModelItem } from '../types';\n\n/**\n * Options for {@link useServerDataSource}.\n *\n * @typeParam T - The row type.\n */\nexport interface UseServerDataSourceOptions<T> {\n /** Where rows come from. Memoise it, or every render refetches. */\n dataSource: HxDataSource<T>;\n /** Rows per page. */\n pageSize: number;\n /** Zero-based page index. */\n page: number;\n /** Active sorts, primary first. */\n sortModel: SortModelItem[];\n /** Active filters, keyed by column id. */\n filterModel: FilterModelMap;\n /**\n * Blocks to keep around so paging back and forth does not refetch.\n * @defaultValue 3\n */\n maxCachedBlocks?: number;\n /** Called when a fetch throws. Aborted requests are not reported. */\n onError?: (error: unknown) => void;\n}\n\n/**\n * What {@link useServerDataSource} returns.\n *\n * @typeParam T - The row type.\n */\nexport interface UseServerDataSourceResult<T> {\n /** Rows for the current page. Empty while the first fetch is in flight. */\n rows: T[];\n /** Total across all pages, from the response's `lastRow`. */\n totalRows: number;\n /** True while a fetch is in flight. */\n isLoading: boolean;\n /** The last error, or `null`. */\n error: unknown;\n /**\n * Re-fetch the current page.\n * @param options - `purge: true` drops every cached block first.\n */\n refresh: (options?: { purge?: boolean }) => void;\n /**\n * Patch loaded rows in place, matched by id. Ids that are not loaded are\n * ignored. No network request is made.\n */\n patchRows: (rows: T[], getRowId: (row: T) => string | number) => void;\n}\n\nfunction buildRequest(\n page: number,\n pageSize: number,\n sortModel: SortModelItem[],\n filterModel: FilterModelMap\n): HxRowsRequest {\n return {\n startRow: page * pageSize,\n endRow: page * pageSize + pageSize,\n sortModel,\n filterModel,\n // Sent empty for wire compatibility with grid endpoints that expect them.\n rowGroupCols: [],\n valueCols: [],\n pivotCols: [],\n pivotMode: false,\n groupKeys: [],\n };\n}\n\n/**\n * Server-side paging with a small block cache.\n *\n * {@link DataGrid} uses this internally; call it directly only when building a\n * custom surface on top of the same data contract.\n *\n * @typeParam T - The row type.\n * @param options - Data source, page, sort and filters.\n * @returns The current page plus loading state and imperative helpers.\n *\n * @remarks\n * Every request carries an `AbortController` and a sequence number, so a slow\n * response for an old sort or filter can never overwrite a newer one. The cache\n * is dropped wholesale when the query changes, so stale blocks are never mixed\n * with fresh ones.\n *\n * @example\n * ```ts\n * const { rows, totalRows, isLoading, refresh } = useServerDataSource({\n * dataSource,\n * page: 0,\n * pageSize: 50,\n * sortModel: [{ colId: 'name', sort: 'asc' }],\n * filterModel: {},\n * });\n * ```\n */\nexport function useServerDataSource<T>({\n dataSource,\n pageSize,\n page,\n sortModel,\n filterModel,\n maxCachedBlocks = 3,\n onError,\n}: UseServerDataSourceOptions<T>): UseServerDataSourceResult<T> {\n const [rows, setRows] = useState<T[]>([]);\n const [totalRows, setTotalRows] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<unknown>(null);\n\n // Bumping this re-runs the effect without changing the query itself.\n const [refreshToken, setRefreshToken] = useState(0);\n\n const cacheRef = useRef(new Map<string, { rows: T[]; lastRow: number }>());\n const requestIdRef = useRef(0);\n const abortRef = useRef<AbortController | null>(null);\n\n // The query identity. Serialising the models keeps the effect from re-firing\n // on every render just because the caller rebuilt an equal object.\n const queryKey = useMemo(\n () => JSON.stringify({ pageSize, sortModel, filterModel }),\n [pageSize, sortModel, filterModel]\n );\n\n // Any change to the query invalidates every cached block.\n useEffect(() => {\n cacheRef.current.clear();\n }, [queryKey]);\n\n const onErrorRef = useRef(onError);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n const dataSourceRef = useRef(dataSource);\n useEffect(() => {\n dataSourceRef.current = dataSource;\n }, [dataSource]);\n\n useEffect(() => {\n const blockKey = `${queryKey}::${page}`;\n const cached = cacheRef.current.get(blockKey);\n if (cached) {\n setRows(cached.rows);\n setTotalRows(cached.lastRow);\n setError(null);\n return;\n }\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n const requestId = ++requestIdRef.current;\n setIsLoading(true);\n setError(null);\n\n const request = buildRequest(page, pageSize, sortModel, filterModel);\n\n dataSourceRef.current\n .getRows(request, controller.signal)\n .then((response) => {\n // A response from a superseded request must never land.\n if (requestId !== requestIdRef.current) return;\n\n const lastRow = response.lastRow ?? response.rows.length;\n cacheRef.current.set(blockKey, { rows: response.rows, lastRow });\n\n // Evict oldest-first; Map preserves insertion order.\n while (cacheRef.current.size > maxCachedBlocks) {\n const oldest = cacheRef.current.keys().next().value;\n if (oldest === undefined) break;\n cacheRef.current.delete(oldest);\n }\n\n setRows(response.rows);\n setTotalRows(lastRow);\n setIsLoading(false);\n })\n .catch((err) => {\n if (controller.signal.aborted) return;\n if (requestId !== requestIdRef.current) return;\n setError(err);\n setIsLoading(false);\n onErrorRef.current?.(err);\n });\n\n return () => {\n controller.abort();\n };\n }, [queryKey, page, pageSize, sortModel, filterModel, refreshToken, maxCachedBlocks]);\n\n const refresh = useCallback((options?: { purge?: boolean }) => {\n if (options?.purge !== false) cacheRef.current.clear();\n setRefreshToken((token) => token + 1);\n }, []);\n\n const patchRows = useCallback(\n (updated: T[], getRowId: (row: T) => string | number) => {\n if (updated.length === 0) return;\n const byId = new Map(updated.map((row) => [getRowId(row), row]));\n\n const merge = (list: T[]) => {\n let changed = false;\n const next = list.map((row) => {\n const replacement = byId.get(getRowId(row));\n if (!replacement) return row;\n changed = true;\n return replacement;\n });\n return changed ? next : list;\n };\n\n setRows(merge);\n // Keep the cache consistent, or paging away and back would resurrect the\n // pre-save row.\n for (const [key, block] of cacheRef.current) {\n cacheRef.current.set(key, { ...block, rows: merge(block.rows) });\n }\n },\n []\n );\n\n return { rows, totalRows, isLoading, error, refresh, patchRows };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\n/** The slice of rows currently worth rendering. */\nexport interface VirtualWindow {\n /** First row index to render, inclusive. Includes overscan. */\n startIndex: number;\n /** Index one past the last row to render, exclusive. */\n endIndex: number;\n}\n\n/** Options for {@link useVirtualRows}. */\nexport interface UseVirtualRowsOptions {\n /** How many rows exist in the current page. */\n rowCount: number;\n /** Fixed height of every row, in pixels. */\n rowHeight: number;\n /**\n * Extra rows rendered above and below the viewport, so fast scrolling does\n * not show blank space.\n * @defaultValue 6\n */\n overscan?: number;\n}\n\n/** What {@link useVirtualRows} returns. */\nexport interface UseVirtualRowsResult {\n /** The rows to render right now. */\n window: VirtualWindow;\n /** `rowCount * rowHeight` — the spacer height that gives the correct scrollbar. */\n totalHeight: number;\n /** Attach to the scrolling element's `onScroll`. */\n onScroll: (event: { currentTarget: HTMLElement }) => void;\n /** Call when the viewport is measured or resized. */\n setViewportHeight: (height: number) => void;\n /** Live scroll offset, readable without causing a re-render. */\n scrollTopRef: React.RefObject<number>;\n}\n\n/**\n * Fixed-height row windowing.\n *\n * @param options - Row count, row height and overscan.\n * @returns The visible window plus the handlers that maintain it.\n *\n * @remarks\n * Fixed heights are a deliberate constraint: they make the visible range O(1)\n * to compute and remove the measure-then-reflow pass that variable heights\n * force. Scroll position is tracked in a ref and only promoted to state when\n * the computed window actually changes, so scrolling within a single row\n * re-renders nothing.\n *\n * @example\n * ```tsx\n * const { window, totalHeight, onScroll, setViewportHeight } = useVirtualRows({\n * rowCount: rows.length,\n * rowHeight: 36,\n * });\n *\n * <div onScroll={onScroll} style={{ overflow: 'auto' }}>\n * <div style={{ height: totalHeight }}>\n * {rows.slice(window.startIndex, window.endIndex).map(renderRow)}\n * </div>\n * </div>\n * ```\n */\nexport function useVirtualRows({\n rowCount,\n rowHeight,\n overscan = 6,\n}: UseVirtualRowsOptions): UseVirtualRowsResult {\n const [viewportHeight, setViewportHeightState] = useState(0);\n const [window, setWindow] = useState<VirtualWindow>({ startIndex: 0, endIndex: 0 });\n\n const scrollTopRef = useRef(0);\n const frameRef = useRef<number | null>(null);\n\n const compute = useCallback(\n (scrollTop: number, height: number) => {\n if (height <= 0 || rowCount === 0) {\n return { startIndex: 0, endIndex: 0 };\n }\n const first = Math.floor(scrollTop / rowHeight);\n const visible = Math.ceil(height / rowHeight);\n return {\n startIndex: Math.max(0, first - overscan),\n endIndex: Math.min(rowCount, first + visible + overscan),\n };\n },\n [rowCount, rowHeight, overscan]\n );\n\n const apply = useCallback(\n (scrollTop: number, height: number) => {\n const next = compute(scrollTop, height);\n setWindow((current) =>\n current.startIndex === next.startIndex && current.endIndex === next.endIndex\n ? current\n : next\n );\n },\n [compute]\n );\n\n const onScroll = useCallback(\n (event: { currentTarget: HTMLElement }) => {\n scrollTopRef.current = event.currentTarget.scrollTop;\n if (frameRef.current != null) return;\n frameRef.current = requestAnimationFrame(() => {\n frameRef.current = null;\n apply(scrollTopRef.current, viewportHeight);\n });\n },\n [apply, viewportHeight]\n );\n\n const setViewportHeight = useCallback((height: number) => {\n setViewportHeightState((current) => (current === height ? current : height));\n }, []);\n\n // Row count, row height and viewport size all move the window without a\n // scroll event, so recompute when any of them change.\n useEffect(() => {\n apply(scrollTopRef.current, viewportHeight);\n }, [apply, viewportHeight]);\n\n useEffect(\n () => () => {\n if (frameRef.current != null) cancelAnimationFrame(frameRef.current);\n },\n []\n );\n\n return {\n window,\n totalHeight: rowCount * rowHeight,\n onScroll,\n setViewportHeight,\n scrollTopRef,\n };\n}\n","import type { ColumnDef, ResolvedColumn } from '../types';\nimport { exportValue, headerText } from './values';\n\n/** RFC 4180: quote when the value contains the separator, a quote or a newline. */\nfunction escapeCsv(value: string, separator: string): string {\n if (value === '') return '';\n const needsQuotes =\n value.includes(separator) ||\n value.includes('\"') ||\n value.includes('\\n') ||\n value.includes('\\r');\n return needsQuotes ? `\"${value.replace(/\"/g, '\"\"')}\"` : value;\n}\n\n/**\n * Serialises rows to delimited text with a header line.\n *\n * Values are quoted per RFC 4180 when they contain the separator, a quote or a\n * newline. Columns marked {@link ColumnDef.suppressExport} are skipped, and\n * lines are joined with CRLF.\n *\n * @param rows - The rows to serialise.\n * @param columns - Columns to include, in output order.\n * @param separator - The field separator.\n * @returns The delimited document.\n */\nexport function toDelimited<T>(\n rows: T[],\n columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>,\n separator: string\n): string {\n const exportable = columns.filter((column) => !column.suppressExport);\n\n const lines: string[] = [\n exportable.map((c) => escapeCsv(headerText(c), separator)).join(separator),\n ];\n\n for (const row of rows) {\n lines.push(\n exportable\n .map((column) => escapeCsv(exportValue(row, column), separator))\n .join(separator)\n );\n }\n\n return lines.join('\\r\\n');\n}\n\n/**\n * Serialises rows to CSV.\n *\n * @param rows - The rows to serialise.\n * @param columns - Columns to include, in output order.\n * @param separator - Field separator.\n * @returns The CSV document, without a BOM — {@link downloadCsv} adds one.\n *\n * @example\n * ```ts\n * const csv = toCsv(api.getSelectedRows(), columns);\n * ```\n */\nexport function toCsv<T>(\n rows: T[],\n columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>,\n separator = ','\n): string {\n return toDelimited(rows, columns, separator);\n}\n\n/**\n * Serialises rows to tab-separated text, which is what spreadsheets expect to\n * receive from the clipboard.\n *\n * @param rows - The rows to serialise.\n * @param columns - Columns to include, in output order.\n * @returns The TSV document.\n */\nexport function toTsv<T>(\n rows: T[],\n columns: Array<ResolvedColumn<T, never> | ColumnDef<T, never>>\n): string {\n return toDelimited(rows, columns, '\\t');\n}\n\n/**\n * Triggers a browser download of CSV content.\n *\n * A UTF-8 BOM is prepended, which is what makes Excel read the file as UTF-8\n * rather than ANSI. The `.csv` extension is added if missing.\n *\n * @param content - The CSV document, e.g. from {@link toCsv}.\n * @param fileName - File name, with or without the extension.\n */\nexport function downloadCsv(content: string, fileName: string): void {\n // The BOM is what makes Excel read the file as UTF-8 rather than ANSI.\n const blob = new Blob(['' + content], {\n type: 'text/csv;charset=utf-8;',\n });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName.endsWith('.csv') ? fileName : `${fileName}.csv`;\n document.body.appendChild(anchor);\n anchor.click();\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n}\n\n/**\n * Copies text to the clipboard, falling back to a hidden `textarea` on browsers\n * and non-secure origins without the async clipboard API.\n *\n * @param text - The text to copy.\n */\nexport async function copyToClipboard(text: string): Promise<void> {\n if (navigator?.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n // Older browsers and non-secure origins have no async clipboard API.\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n}\n","import type {\n DateFilterType,\n FilterKind,\n FilterModelMap,\n HxFilterModel,\n NumberFilterType,\n TextFilterType,\n} from '../types';\n\n/**\n * Builders and helpers for the wire-format filter shapes.\n *\n * Every filter the grid sends is constructed here, so the contract with the\n * server is defined in exactly one place.\n */\n\n/** Every text operator, in the order the filter UI lists them. */\nexport const TEXT_FILTER_TYPES: TextFilterType[] = [\n 'contains',\n 'notContains',\n 'equals',\n 'notEqual',\n 'startsWith',\n 'endsWith',\n 'blank',\n 'notBlank',\n];\n\n/** Every numeric operator, in the order the filter UI lists them. */\nexport const NUMBER_FILTER_TYPES: NumberFilterType[] = [\n 'equals',\n 'notEqual',\n 'lessThan',\n 'lessThanOrEqual',\n 'greaterThan',\n 'greaterThanOrEqual',\n 'inRange',\n 'blank',\n 'notBlank',\n];\n\n/** Every date operator, in the order the filter UI lists them. */\nexport const DATE_FILTER_TYPES: DateFilterType[] = [\n 'equals',\n 'notEqual',\n 'before',\n 'after',\n 'inRange',\n 'blank',\n 'notBlank',\n];\n\n/**\n * Human-readable label for each operator, e.g. `notEqual` → `'Not equal'`.\n *\n * Replace an entry to relabel an operator throughout the filter UI.\n */\nexport const FILTER_TYPE_LABELS: Record<string, string> = {\n contains: 'Contains',\n notContains: 'Does not contain',\n equals: 'Equals',\n notEqual: 'Not equal',\n startsWith: 'Starts with',\n endsWith: 'Ends with',\n blank: 'Is empty',\n notBlank: 'Is not empty',\n lessThan: 'Less than',\n lessThanOrEqual: 'Less than or equal',\n greaterThan: 'Greater than',\n greaterThanOrEqual: 'Greater than or equal',\n inRange: 'Between',\n before: 'Before',\n after: 'After',\n};\n\n/**\n * Whether an operator takes no operand — `blank` and `notBlank`.\n *\n * @param type - The operator name.\n * @returns `true` when no value is needed.\n */\nexport function isUnaryFilter(type: string): boolean {\n return type === 'blank' || type === 'notBlank';\n}\n\n/**\n * Whether an operator takes two operands — currently only `inRange`.\n *\n * @param type - The operator name.\n * @returns `true` when both bounds are needed.\n */\nexport function isRangeFilter(type: string): boolean {\n return type === 'inRange';\n}\n\n/**\n * The operator a filter starts on when its popover is first opened.\n *\n * `contains` for text, `equals` for numbers and dates.\n *\n * @param kind - The filter kind.\n * @returns The default operator name.\n */\nexport function defaultFilterType(kind: FilterKind): string {\n switch (kind) {\n case 'text':\n return 'contains';\n case 'number':\n return 'equals';\n case 'date':\n return 'equals';\n case 'set':\n return 'set';\n }\n}\n\n/**\n * Builds a text filter, or `null` when there is nothing to send.\n *\n * @param type - The operator.\n * @param filter - The search term. Ignored for unary operators.\n * @returns The filter model, or `null` if a non-unary operator got a blank term.\n *\n * @example\n * ```ts\n * buildTextFilter('contains', 'acme');\n * // { filterType: 'text', type: 'contains', filter: 'acme' }\n * buildTextFilter('contains', ' '); // null\n * ```\n */\nexport function buildTextFilter(type: TextFilterType, filter: string): HxFilterModel | null {\n if (!isUnaryFilter(type) && filter.trim() === '') return null;\n return isUnaryFilter(type)\n ? { filterType: 'text', type }\n : { filterType: 'text', type, filter };\n}\n\n/**\n * Builds a numeric filter, or `null` when the input is incomplete.\n *\n * @param type - The operator.\n * @param filter - The operand, or lower bound for `inRange`, as typed.\n * @param filterTo - The upper bound. Required for `inRange`.\n * @returns The filter model, or `null` if a required operand is missing or not\n * a number.\n *\n * @example\n * ```ts\n * buildNumberFilter('inRange', '10', '100');\n * // { filterType: 'number', type: 'inRange', filter: 10, filterTo: 100 }\n * buildNumberFilter('inRange', '10'); // null — no upper bound\n * ```\n */\nexport function buildNumberFilter(\n type: NumberFilterType,\n filter: string,\n filterTo?: string\n): HxFilterModel | null {\n if (isUnaryFilter(type)) return { filterType: 'number', type };\n\n const from = Number(filter);\n if (filter.trim() === '' || Number.isNaN(from)) return null;\n\n if (isRangeFilter(type)) {\n const to = Number(filterTo);\n if (!filterTo || filterTo.trim() === '' || Number.isNaN(to)) return null;\n return { filterType: 'number', type, filter: from, filterTo: to };\n }\n\n return { filterType: 'number', type, filter: from };\n}\n\n/**\n * Builds a date filter, or `null` when the input is incomplete.\n *\n * @param type - The operator.\n * @param dateFrom - Lower bound, formatted `YYYY-MM-DD`.\n * @param dateTo - Upper bound. Required for `inRange`.\n * @returns The filter model, or `null` if a required bound is missing.\n */\nexport function buildDateFilter(\n type: DateFilterType,\n dateFrom: string,\n dateTo?: string\n): HxFilterModel | null {\n if (isUnaryFilter(type)) return { filterType: 'date', type };\n if (!dateFrom) return null;\n\n if (isRangeFilter(type)) {\n if (!dateTo) return null;\n return { filterType: 'date', type, dateFrom, dateTo };\n }\n\n return { filterType: 'date', type, dateFrom };\n}\n\n/**\n * Builds a set filter, or `null` when nothing is selected.\n *\n * Returning `null` rather than an empty set is what clears the filter — see\n * {@link withFilter}.\n *\n * @param values - The selected values.\n * @returns The filter model, or `null` for an empty selection.\n */\nexport function buildSetFilter(values: string[]): HxFilterModel | null {\n if (values.length === 0) return null;\n return { filterType: 'set', values };\n}\n\n/**\n * Sets or clears one column's filter, returning a new map.\n *\n * Never mutates the map it is given, so the result is safe to hand straight to\n * `setState`.\n *\n * @param model - The current filter model.\n * @param colId - The column to change.\n * @param filter - The new filter, or `null` to remove the column's entry.\n * @returns A new filter model.\n *\n * @example\n * ```ts\n * const next = withFilter(filterModel, 'status', buildSetFilter(['ACTIVE']));\n * const cleared = withFilter(filterModel, 'status', null);\n * ```\n */\nexport function withFilter(\n model: FilterModelMap,\n colId: string,\n filter: HxFilterModel | null\n): FilterModelMap {\n const next = { ...model };\n if (filter === null) {\n delete next[colId];\n } else {\n next[colId] = filter;\n }\n return next;\n}\n\n/**\n * A short human-readable summary of a filter, for the floating filter input and\n * the header's active-filter indicator.\n *\n * @param filter - The filter to describe.\n * @returns A short label, e.g. `'Between 10 - 100'` or `'3 selected'`.\n */\nexport function describeFilter(filter: HxFilterModel): string {\n switch (filter.filterType) {\n case 'set':\n return filter.values.length === 1\n ? filter.values[0]\n : `${filter.values.length} selected`;\n case 'text':\n return isUnaryFilter(filter.type)\n ? FILTER_TYPE_LABELS[filter.type]\n : String(filter.filter ?? '');\n case 'number':\n if (isUnaryFilter(filter.type)) return FILTER_TYPE_LABELS[filter.type];\n return isRangeFilter(filter.type)\n ? `${filter.filter} - ${filter.filterTo}`\n : `${FILTER_TYPE_LABELS[filter.type]} ${filter.filter}`;\n case 'date':\n if (isUnaryFilter(filter.type)) return FILTER_TYPE_LABELS[filter.type];\n return isRangeFilter(filter.type)\n ? `${filter.dateFrom} - ${filter.dateTo}`\n : `${FILTER_TYPE_LABELS[filter.type]} ${filter.dateFrom}`;\n }\n}\n","import { useMemo, useState } from 'react';\nimport type { Pinned, ResolvedColumn } from '../types';\nimport { headerText } from '../core/values';\n\n/**\n * Props for {@link ColumnsPanel}.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type.\n */\nexport interface ColumnsPanelProps<T, C> {\n /** Every column, including hidden ones. */\n columns: ResolvedColumn<T, C>[];\n /** Whether a column is currently hidden. */\n isHidden: (colId: string) => boolean;\n /** Show or hide one column. */\n onToggle: (colId: string, hidden: boolean) => void;\n /** Move a column to a new index. */\n onMove: (colId: string, toIndex: number) => void;\n /** Pin a column, or `undefined` to unpin. */\n onPin: (colId: string, pinned: Pinned | undefined) => void;\n /** Discard the user's layout. */\n onReset: () => void;\n /** Dismiss the panel. */\n onClose: () => void;\n}\n\n/**\n * The side panel for showing, hiding, reordering and pinning columns, with the\n * \"reset my preferences\" escape hatch.\n *\n * {@link DataGrid} renders this from its toolbar; exported for custom surfaces.\n */\nexport function ColumnsPanel<T, C>({\n columns,\n isHidden,\n onToggle,\n onMove,\n onPin,\n onReset,\n onClose,\n}: ColumnsPanelProps<T, C>) {\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n const needle = search.trim().toLowerCase();\n if (!needle) return columns;\n return columns.filter((column) =>\n headerText(column as never).toLowerCase().includes(needle)\n );\n }, [columns, search]);\n\n const visibleCount = columns.filter((c) => !isHidden(c.colId)).length;\n\n return (\n <div className=\"flex h-full w-60 shrink-0 flex-col gap-2 border-r border-gray-200 bg-white p-2 dark:border-gray-700 dark:bg-gray-900\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300\">\n Columns\n </h3>\n <button\n type=\"button\"\n aria-label=\"Close columns panel\"\n className=\"rounded px-1.5 text-sm text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/5\"\n onClick={onClose}\n >\n ×\n </button>\n </div>\n\n <input\n type=\"search\"\n className=\"h-7 w-full rounded border border-gray-300 bg-white px-2 text-xs text-gray-800 outline-none focus:border-brand-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\n placeholder=\"Search columns...\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n\n <p className=\"text-[11px] text-gray-500 dark:text-gray-400\">\n {visibleCount} of {columns.length} shown\n </p>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {filtered.map((column) => {\n const hidden = isHidden(column.colId);\n const index = columns.findIndex((c) => c.colId === column.colId);\n\n return (\n <div\n key={column.colId}\n className=\"group flex items-center gap-1 rounded px-1 py-1 hover:bg-gray-100 dark:hover:bg-white/5\"\n draggable\n onDragStart={(event) =>\n event.dataTransfer.setData('text/plain', column.colId)\n }\n onDragOver={(event) => event.preventDefault()}\n onDrop={(event) => {\n event.preventDefault();\n const dragged = event.dataTransfer.getData('text/plain');\n if (dragged && dragged !== column.colId) onMove(dragged, index);\n }}\n >\n <span className=\"cursor-grab text-[10px] text-gray-400\" aria-hidden>\n ⠿\n </span>\n\n <label className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1.5 text-xs text-gray-700 dark:text-gray-200\">\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5 accent-brand-500\"\n checked={!hidden}\n onChange={() => onToggle(column.colId, !hidden)}\n />\n <span className=\"truncate\">{headerText(column as never)}</span>\n </label>\n\n <button\n type=\"button\"\n className={`shrink-0 rounded px-1 text-[10px] ${\n column.pinned\n ? 'text-brand-500 dark:text-brand-400'\n : 'text-gray-400 opacity-0 group-hover:opacity-100'\n }`}\n title={column.pinned ? `Unpin (${column.pinned})` : 'Pin left'}\n onClick={() =>\n onPin(column.colId, column.pinned ? undefined : 'left')\n }\n >\n 📌\n </button>\n </div>\n );\n })}\n </div>\n\n <button\n type=\"button\"\n className=\"rounded border border-error-300 px-2 py-1 text-xs font-medium text-error-600 hover:bg-error-50 dark:border-error-700 dark:text-error-400 dark:hover:bg-error-500/10\"\n onClick={onReset}\n >\n Reset to defaults\n </button>\n </div>\n );\n}\n","export const SELECTION_COLUMN_WIDTH = 40;\n\nexport interface SelectionCellProps {\n checked: boolean;\n indeterminate?: boolean;\n onToggle: (shiftKey: boolean) => void;\n isHeader?: boolean;\n label?: string;\n}\n\n/**\n * Pinned to the left of every row. Kept out of the column model so it cannot be\n * hidden, reordered or exported by accident.\n */\nexport function SelectionCell({\n checked,\n indeterminate,\n onToggle,\n isHeader,\n label,\n}: SelectionCellProps) {\n return (\n <div\n className={`sticky left-0 z-[3] flex h-full items-center justify-center border-r border-gray-200 dark:border-gray-700 ${\n isHeader\n ? 'bg-gray-100 dark:bg-gray-800'\n : 'bg-inherit'\n }`}\n style={{ width: SELECTION_COLUMN_WIDTH, minWidth: SELECTION_COLUMN_WIDTH }}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => event.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5 cursor-pointer accent-brand-500\"\n checked={checked}\n aria-label={label ?? (isHeader ? 'Select all rows' : 'Select row')}\n ref={(node) => {\n if (node) node.indeterminate = indeterminate === true;\n }}\n onChange={() => undefined}\n onClick={(event) => onToggle(event.shiftKey)}\n />\n </div>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { ColumnLayout, FilterModelMap, HxFilterModel } from '../types';\nimport { buildTextFilter, describeFilter } from '../core/filterModel';\nimport { SELECTION_COLUMN_WIDTH } from './SelectionCell';\n\nexport interface FloatingFilterRowProps<T, C> {\n layout: ColumnLayout<T, C>;\n filterModel: FilterModelMap;\n height: number;\n selectable: boolean;\n onFilterChange: (colId: string, filter: HxFilterModel | null) => void;\n}\n\nconst CELL_INPUT_CLASS =\n 'h-6 w-full rounded border border-gray-300 bg-white px-1.5 text-[11px] text-gray-800 ' +\n 'outline-none focus:border-brand-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';\n\n/**\n * A quick text box under each header. Free-text columns get a `contains`\n * filter; the richer types are read-only here and open the full popover from\n * the header, since a single input cannot express a range or a value set.\n */\nfunction FloatingCell({\n colId,\n kind,\n filter,\n onFilterChange,\n}: {\n colId: string;\n kind: 'text' | 'number' | 'date' | 'set';\n filter: HxFilterModel | undefined;\n onFilterChange: (colId: string, filter: HxFilterModel | null) => void;\n}) {\n const isFreeText = kind === 'text';\n const [draft, setDraft] = useState(\n filter?.filterType === 'text' ? (filter.filter ?? '') : ''\n );\n\n // Keep in step when the model is changed elsewhere (popover, reset, restore).\n useEffect(() => {\n if (!isFreeText) return;\n setDraft(filter?.filterType === 'text' ? (filter.filter ?? '') : '');\n }, [filter, isFreeText]);\n\n if (!isFreeText) {\n const summary = filter ? describeFilter(filter) : '';\n return (\n <div\n className=\"flex h-6 items-center truncate rounded border border-dashed border-gray-300 px-1.5 text-[11px] text-gray-500 dark:border-gray-600 dark:text-gray-400\"\n title={summary}\n >\n {summary || <span className=\"opacity-50\">--</span>}\n </div>\n );\n }\n\n return (\n <input\n type=\"search\"\n className={CELL_INPUT_CLASS}\n value={draft}\n aria-label={`Filter ${colId}`}\n onChange={(event) => {\n const next = event.target.value;\n setDraft(next);\n onFilterChange(colId, buildTextFilter('contains', next));\n }}\n />\n );\n}\n\nexport function FloatingFilterRow<T, C>({\n layout,\n filterModel,\n height,\n selectable,\n onFilterChange,\n}: FloatingFilterRowProps<T, C>) {\n return (\n <div\n role=\"row\"\n className=\"sticky z-10 flex border-b border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800/60\"\n style={{\n height,\n width: layout.totalWidth + (selectable ? SELECTION_COLUMN_WIDTH : 0),\n }}\n >\n {selectable && (\n <div\n className=\"sticky left-0 z-[3] h-full border-r border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800\"\n style={{ width: SELECTION_COLUMN_WIDTH, minWidth: SELECTION_COLUMN_WIDTH }}\n />\n )}\n\n {layout.items.map(({ column, width, pinned, stickyOffset }) => {\n const style: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n ...(pinned === 'left'\n ? { position: 'sticky', left: stickyOffset, zIndex: 3 }\n : pinned === 'right'\n ? { position: 'sticky', right: stickyOffset, zIndex: 3 }\n : null),\n };\n\n const showInput =\n column.filter && !column.filterParams?.suppressFloatingFilter;\n\n return (\n <div\n key={column.colId}\n className={`flex h-full items-center border-r border-gray-200 px-1 dark:border-gray-700 ${\n pinned ? 'bg-gray-50 dark:bg-gray-800' : ''\n }`}\n style={style}\n >\n {showInput && column.filter && (\n <FloatingCell\n colId={column.colId}\n kind={column.filter}\n filter={filterModel[column.colId]}\n onFilterChange={onFilterChange}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport type { FilterKind, HxFilterModel } from '../types';\nimport {\n DATE_FILTER_TYPES,\n FILTER_TYPE_LABELS,\n NUMBER_FILTER_TYPES,\n TEXT_FILTER_TYPES,\n buildDateFilter,\n buildNumberFilter,\n buildSetFilter,\n buildTextFilter,\n isRangeFilter,\n isUnaryFilter,\n} from '../core/filterModel';\n\n/** Props for {@link FilterPopover}. */\nexport interface FilterPopoverProps {\n /** Which filter UI to render. */\n kind: FilterKind;\n /** The column's current filter, or `undefined` when unfiltered. */\n value: HxFilterModel | undefined;\n /**\n * Options for a `set` filter: a static list, or a loader called the first\n * time the popover opens.\n */\n setValues?: string[] | (() => Promise<string[]>);\n /** Called with the new filter, or `null` to clear the column's filter. */\n onApply: (filter: HxFilterModel | null) => void;\n /** Dismiss the popover. */\n onClose: () => void;\n}\n\nconst FIELD_CLASS =\n 'h-8 w-full rounded border border-gray-300 bg-white px-2 text-xs text-gray-800 ' +\n 'outline-none focus:border-brand-500 focus:ring-1 focus:ring-brand-500 ' +\n 'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';\n\nconst BUTTON_CLASS =\n 'rounded px-2.5 py-1 text-xs font-medium transition-colors disabled:opacity-50';\n\nfunction SetFilterBody({\n value,\n setValues,\n onApply,\n}: {\n value: HxFilterModel | undefined;\n setValues: FilterPopoverProps['setValues'];\n onApply: (filter: HxFilterModel | null) => void;\n}) {\n const [options, setOptions] = useState<string[]>(\n Array.isArray(setValues) ? setValues : []\n );\n const [isLoading, setIsLoading] = useState(typeof setValues === 'function');\n const [search, setSearch] = useState('');\n const [selected, setSelected] = useState<Set<string>>(\n () => new Set(value?.filterType === 'set' ? value.values : [])\n );\n\n useEffect(() => {\n if (typeof setValues !== 'function') {\n setOptions(Array.isArray(setValues) ? setValues : []);\n return;\n }\n let cancelled = false;\n setIsLoading(true);\n setValues()\n .then((loaded) => {\n if (!cancelled) setOptions(loaded);\n })\n .catch(() => {\n if (!cancelled) setOptions([]);\n })\n .finally(() => {\n if (!cancelled) setIsLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, [setValues]);\n\n const filtered = useMemo(() => {\n const needle = search.trim().toLowerCase();\n return needle ? options.filter((o) => o.toLowerCase().includes(needle)) : options;\n }, [options, search]);\n\n const toggle = (option: string) => {\n setSelected((current) => {\n const next = new Set(current);\n if (next.has(option)) next.delete(option);\n else next.add(option);\n return next;\n });\n };\n\n return (\n <>\n <input\n type=\"search\"\n className={FIELD_CLASS}\n placeholder=\"Search values...\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n\n <div className=\"max-h-52 overflow-y-auto rounded border border-gray-200 dark:border-gray-700\">\n {isLoading && (\n <p className=\"p-2 text-xs text-gray-500 dark:text-gray-400\">Loading...</p>\n )}\n {!isLoading && filtered.length === 0 && (\n <p className=\"p-2 text-xs text-gray-500 dark:text-gray-400\">No values.</p>\n )}\n {filtered.map((option) => (\n <label\n key={option}\n className=\"flex cursor-pointer items-center gap-2 px-2 py-1 text-xs text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5\"\n >\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5 accent-brand-500\"\n checked={selected.has(option)}\n onChange={() => toggle(option)}\n />\n <span className=\"truncate\">{option}</span>\n </label>\n ))}\n </div>\n\n <div className=\"flex justify-between gap-2\">\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-white/5`}\n onClick={() => {\n setSelected(new Set());\n onApply(null);\n }}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} bg-brand-500 text-white hover:bg-brand-600`}\n onClick={() => onApply(buildSetFilter([...selected]))}\n >\n Apply\n </button>\n </div>\n </>\n );\n}\n\n/** Header filter menu. Emits the wire-format model directly. */\n/**\n * The per-column filter editor, covering all four\n * {@link FilterKind | filter kinds}.\n *\n * {@link DataGrid} opens this from the header; exported for custom surfaces.\n */\nexport function FilterPopover({\n kind,\n value,\n setValues,\n onApply,\n onClose,\n}: FilterPopoverProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n\n const types =\n kind === 'text'\n ? TEXT_FILTER_TYPES\n : kind === 'number'\n ? NUMBER_FILTER_TYPES\n : DATE_FILTER_TYPES;\n\n const [type, setType] = useState<string>(() => {\n if (value && value.filterType !== 'set') return value.type;\n return types[0];\n });\n\n const [operand, setOperand] = useState<string>(() => {\n if (!value) return '';\n if (value.filterType === 'text') return value.filter ?? '';\n if (value.filterType === 'number') return value.filter?.toString() ?? '';\n if (value.filterType === 'date') return value.dateFrom ?? '';\n return '';\n });\n\n const [operandTo, setOperandTo] = useState<string>(() => {\n if (!value) return '';\n if (value.filterType === 'number') return value.filterTo?.toString() ?? '';\n if (value.filterType === 'date') return value.dateTo ?? '';\n return '';\n });\n\n // Close on outside click / Escape, the way a menu is expected to behave.\n useEffect(() => {\n const onPointerDown = (event: MouseEvent) => {\n if (!containerRef.current?.contains(event.target as Node)) onClose();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n document.addEventListener('mousedown', onPointerDown);\n document.addEventListener('keydown', onKeyDown);\n return () => {\n document.removeEventListener('mousedown', onPointerDown);\n document.removeEventListener('keydown', onKeyDown);\n };\n }, [onClose]);\n\n const apply = () => {\n if (kind === 'text') {\n onApply(buildTextFilter(type as never, operand));\n } else if (kind === 'number') {\n onApply(buildNumberFilter(type as never, operand, operandTo));\n } else {\n onApply(buildDateFilter(type as never, operand, operandTo));\n }\n };\n\n const inputType = kind === 'date' ? 'date' : kind === 'number' ? 'number' : 'text';\n\n return (\n <div\n ref={containerRef}\n className=\"absolute right-0 top-full z-30 mt-1 flex w-60 flex-col gap-2 rounded-md border border-gray-200 bg-white p-2 shadow-theme-lg dark:border-gray-700 dark:bg-gray-900\"\n onClick={(event) => event.stopPropagation()}\n >\n {kind === 'set' ? (\n <SetFilterBody value={value} setValues={setValues} onApply={onApply} />\n ) : (\n <>\n <select\n className={FIELD_CLASS}\n value={type}\n onChange={(event) => setType(event.target.value)}\n >\n {types.map((option) => (\n <option key={option} value={option}>\n {FILTER_TYPE_LABELS[option] ?? option}\n </option>\n ))}\n </select>\n\n {!isUnaryFilter(type) && (\n <input\n type={inputType}\n className={FIELD_CLASS}\n value={operand}\n autoFocus\n placeholder=\"Value\"\n onChange={(event) => setOperand(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') apply();\n }}\n />\n )}\n\n {isRangeFilter(type) && (\n <input\n type={inputType}\n className={FIELD_CLASS}\n value={operandTo}\n placeholder=\"To\"\n onChange={(event) => setOperandTo(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') apply();\n }}\n />\n )}\n\n <div className=\"flex justify-between gap-2\">\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} text-gray-600 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-white/5`}\n onClick={() => {\n setOperand('');\n setOperandTo('');\n onApply(null);\n }}\n >\n Clear\n </button>\n <button\n type=\"button\"\n className={`${BUTTON_CLASS} bg-brand-500 text-white hover:bg-brand-600`}\n onClick={apply}\n >\n Apply\n </button>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useCallback, useRef, useState } from 'react';\nimport type {\n ColumnLayout,\n ColumnLayoutItem,\n FilterModelMap,\n HxFilterModel,\n Pinned,\n SortDirection,\n SortModelItem,\n} from '../types';\nimport { describeFilter } from '../core/filterModel';\nimport { FilterPopover } from './FilterPopover';\nimport { SELECTION_COLUMN_WIDTH, SelectionCell } from './SelectionCell';\n\nexport interface GridHeaderProps<T, C> {\n layout: ColumnLayout<T, C>;\n sortModel: SortModelItem[];\n filterModel: FilterModelMap;\n headerHeight: number;\n selectable: boolean;\n allSelected: boolean;\n someSelected: boolean;\n onToggleAll: () => void;\n onSort: (colId: string, additive: boolean) => void;\n onFilterChange: (colId: string, filter: HxFilterModel | null) => void;\n onResize: (colId: string, width: number) => void;\n onMove: (colId: string, toIndex: number) => void;\n onPin: (colId: string, pinned: Pinned | undefined) => void;\n}\n\nfunction SortIndicator({\n direction,\n index,\n showIndex,\n}: {\n direction: SortDirection | undefined;\n index: number;\n showIndex: boolean;\n}) {\n if (!direction) {\n return (\n <span className=\"opacity-0 transition-opacity group-hover:opacity-40\" aria-hidden>\n ↑\n </span>\n );\n }\n return (\n <span className=\"flex items-center text-brand-500 dark:text-brand-400\" aria-hidden>\n {direction === 'asc' ? '↑' : '↓'}\n {showIndex && <sub className=\"ml-0.5 text-[9px]\">{index + 1}</sub>}\n </span>\n );\n}\n\nexport function GridHeader<T, C>({\n layout,\n sortModel,\n filterModel,\n headerHeight,\n selectable,\n allSelected,\n someSelected,\n onToggleAll,\n onSort,\n onFilterChange,\n onResize,\n onMove,\n onPin,\n}: GridHeaderProps<T, C>) {\n const [openFilter, setOpenFilter] = useState<string | null>(null);\n const [openMenu, setOpenMenu] = useState<string | null>(null);\n const [dragColId, setDragColId] = useState<string | null>(null);\n\n // Resizing writes straight to the DOM-free state on each pointer move; the\n // pointer capture keeps the drag alive outside the header.\n const resizeRef = useRef<{ colId: string; startX: number; startWidth: number } | null>(\n null\n );\n\n const startResize = useCallback(\n (event: React.PointerEvent, item: ColumnLayoutItem<T, C>) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n colId: item.colId,\n startX: event.clientX,\n startWidth: item.width,\n };\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n },\n []\n );\n\n const onResizeMove = useCallback(\n (event: React.PointerEvent) => {\n const active = resizeRef.current;\n if (!active) return;\n const delta = event.clientX - active.startX;\n onResize(active.colId, Math.max(40, active.startWidth + delta));\n },\n [onResize]\n );\n\n const endResize = useCallback((event: React.PointerEvent) => {\n if (!resizeRef.current) return;\n resizeRef.current = null;\n (event.target as HTMLElement).releasePointerCapture(event.pointerId);\n }, []);\n\n const sortIndexOf = (colId: string) =>\n sortModel.findIndex((entry) => entry.colId === colId);\n\n return (\n <div\n role=\"row\"\n className=\"sticky top-0 z-10 flex border-b border-gray-300 bg-gray-100 dark:border-gray-600 dark:bg-gray-800\"\n style={{\n height: headerHeight,\n width: layout.totalWidth + (selectable ? SELECTION_COLUMN_WIDTH : 0),\n }}\n >\n {selectable && (\n <SelectionCell\n isHeader\n checked={allSelected}\n indeterminate={someSelected}\n onToggle={onToggleAll}\n label=\"Select all rows on this page\"\n />\n )}\n\n {layout.items.map((item, index) => {\n const { column, width, pinned, stickyOffset } = item;\n const sortIndex = sortIndexOf(column.colId);\n const direction = sortIndex === -1 ? undefined : sortModel[sortIndex].sort;\n const activeFilter = filterModel[column.colId];\n const filterKind = column.filter;\n\n const style: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n ...(pinned === 'left'\n ? { position: 'sticky', left: stickyOffset, zIndex: 3 }\n : pinned === 'right'\n ? { position: 'sticky', right: stickyOffset, zIndex: 3 }\n : null),\n };\n\n return (\n <div\n key={column.colId}\n role=\"columnheader\"\n aria-sort={\n direction === 'asc'\n ? 'ascending'\n : direction === 'desc'\n ? 'descending'\n : 'none'\n }\n aria-colindex={index + 1}\n className={`group relative flex h-full items-center border-r border-gray-300 bg-gray-100 px-2 dark:border-gray-600 dark:bg-gray-800 ${\n dragColId === column.colId ? 'opacity-40' : ''\n } ${column.headerClassName ?? ''}`}\n style={style}\n draggable={!column.lockPosition}\n onDragStart={(event) => {\n setDragColId(column.colId);\n event.dataTransfer.effectAllowed = 'move';\n }}\n onDragOver={(event) => {\n if (dragColId && dragColId !== column.colId) event.preventDefault();\n }}\n onDrop={(event) => {\n event.preventDefault();\n if (dragColId && dragColId !== column.colId) onMove(dragColId, index);\n setDragColId(null);\n }}\n onDragEnd={() => setDragColId(null)}\n >\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 text-left text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300\"\n disabled={!column.sortable}\n onClick={(event) => column.sortable && onSort(column.colId, event.shiftKey)}\n title={column.sortable ? 'Sort (shift-click to add)' : undefined}\n >\n <span className=\"truncate\">{column.header}</span>\n {column.sortable && (\n <SortIndicator\n direction={direction}\n index={sortIndex}\n showIndex={sortModel.length > 1}\n />\n )}\n </button>\n\n {filterKind && (\n <button\n type=\"button\"\n aria-label={`Filter ${column.colId}`}\n className={`ml-1 shrink-0 rounded px-1 text-[10px] leading-none ${\n activeFilter\n ? 'text-brand-500 dark:text-brand-400'\n : 'text-gray-400 opacity-0 group-hover:opacity-100'\n }`}\n title={activeFilter ? describeFilter(activeFilter) : 'Filter'}\n onClick={(event) => {\n event.stopPropagation();\n setOpenMenu(null);\n setOpenFilter((current) =>\n current === column.colId ? null : column.colId\n );\n }}\n >\n ▼\n </button>\n )}\n\n <button\n type=\"button\"\n aria-label={`Options for ${column.colId}`}\n className=\"ml-0.5 shrink-0 rounded px-1 text-[10px] leading-none text-gray-400 opacity-0 group-hover:opacity-100\"\n onClick={(event) => {\n event.stopPropagation();\n setOpenFilter(null);\n setOpenMenu((current) => (current === column.colId ? null : column.colId));\n }}\n >\n ⋮\n </button>\n\n {openFilter === column.colId && filterKind && (\n <FilterPopover\n kind={filterKind}\n value={activeFilter}\n setValues={column.filterParams?.values}\n onApply={(filter) => {\n onFilterChange(column.colId, filter);\n setOpenFilter(null);\n }}\n onClose={() => setOpenFilter(null)}\n />\n )}\n\n {openMenu === column.colId && (\n <div\n className=\"absolute right-0 top-full z-30 mt-1 w-36 rounded-md border border-gray-200 bg-white py-1 shadow-theme-lg dark:border-gray-700 dark:bg-gray-900\"\n onMouseLeave={() => setOpenMenu(null)}\n >\n {(['left', 'right'] as const).map((side) => (\n <button\n key={side}\n type=\"button\"\n className=\"block w-full px-3 py-1 text-left text-xs text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/5\"\n onClick={() => {\n onPin(column.colId, pinned === side ? undefined : side);\n setOpenMenu(null);\n }}\n >\n {pinned === side ? `Unpin ${side}` : `Pin ${side}`}\n </button>\n ))}\n </div>\n )}\n\n {column.resizable && (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n className=\"absolute right-0 top-0 h-full w-1 cursor-col-resize hover:bg-brand-400\"\n onPointerDown={(event) => startResize(event, item)}\n onPointerMove={onResizeMove}\n onPointerUp={endResize}\n onPointerCancel={endResize}\n onClick={(event) => event.stopPropagation()}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\n/** Props for {@link GridOverlay}. */\nexport interface GridOverlayProps {\n /** Which state to show. */\n kind: 'loading' | 'empty' | 'error';\n /** Message body. Falls back to a default per `kind`. */\n message?: ReactNode;\n}\n\n/**\n * The loading, empty and error states shown over the row area.\n *\n * Overlays rather than replaces, so the header and column widths stay put while\n * a refetch is in flight.\n *\n * @param props - Which state to show, and the message.\n */\nexport function GridOverlay({ kind, message }: GridOverlayProps) {\n if (kind === 'loading') {\n return (\n <div className=\"pointer-events-none absolute inset-0 z-[5] flex items-start justify-center bg-white/60 pt-10 dark:bg-gray-900/60\">\n <div className=\"flex items-center gap-2 rounded-md border border-gray-200 bg-white px-3 py-1.5 text-xs text-gray-600 shadow-theme-sm dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300\">\n <span className=\"h-3 w-3 animate-spin rounded-full border-2 border-brand-400 border-t-transparent\" />\n {message ?? 'Loading...'}\n </div>\n </div>\n );\n }\n\n if (kind === 'error') {\n return (\n <div className=\"absolute inset-0 z-[5] flex items-start justify-center bg-white/80 pt-10 dark:bg-gray-900/80\">\n <div className=\"max-w-md rounded-md border border-error-300 bg-error-50 px-3 py-2 text-xs text-error-700 dark:border-error-700 dark:bg-error-500/10 dark:text-error-400\">\n {message ?? 'Something went wrong loading this grid.'}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"absolute inset-0 z-[5] flex items-start justify-center pt-10\">\n <p className=\"text-xs text-gray-500 dark:text-gray-400\">\n {message ?? 'No records found'}\n </p>\n </div>\n );\n}\n","/** Props for {@link GridPagination}. */\nexport interface GridPaginationProps {\n /** Zero-based current page. */\n page: number;\n /** Rows per page. */\n pageSize: number;\n /** Total across all pages. `-1` when the server reported it as unknown. */\n totalRows: number;\n /** Page sizes to offer in the selector. */\n pageSizeOptions: number[];\n /** Disables the controls while a fetch is in flight. */\n isLoading: boolean;\n /** Called with the new zero-based page index. */\n onPageChange: (page: number) => void;\n /** Called with the new page size. */\n onPageSizeChange: (pageSize: number) => void;\n}\n\nconst BUTTON_CLASS =\n 'rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 transition-colors ' +\n 'hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-40 ' +\n 'dark:border-gray-600 dark:text-gray-200 dark:hover:bg-white/5';\n\n/**\n * The grid's pager: range summary, page size selector and navigation.\n *\n * {@link DataGrid} renders this itself. It is exported for apps that build a\n * custom surface on the same hooks.\n */\nexport function GridPagination({\n page,\n pageSize,\n totalRows,\n pageSizeOptions,\n isLoading,\n onPageChange,\n onPageSizeChange,\n}: GridPaginationProps) {\n const pageCount = Math.max(1, Math.ceil(totalRows / pageSize));\n const first = totalRows === 0 ? 0 : page * pageSize + 1;\n const last = Math.min(totalRows, (page + 1) * pageSize);\n\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-2 border-t border-gray-200 bg-gray-50 px-2 py-1.5 dark:border-gray-700 dark:bg-gray-800/60\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-gray-600 dark:text-gray-300\">\n Rows\n <select\n className=\"ml-1 rounded border border-gray-300 bg-white px-1 py-0.5 text-xs dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100\"\n value={pageSize}\n onChange={(event) => onPageSizeChange(Number(event.target.value))}\n >\n {pageSizeOptions.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </select>\n </label>\n\n <span className=\"text-xs text-gray-600 dark:text-gray-300\">\n {isLoading ? 'Loading...' : `${first}-${last} of ${totalRows}`}\n </span>\n </div>\n\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page === 0}\n onClick={() => onPageChange(0)}\n >\n « First\n </button>\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n >\n ‹ Prev\n </button>\n <span className=\"px-1 text-xs text-gray-600 dark:text-gray-300\">\n Page {page + 1} of {pageCount}\n </span>\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page + 1 >= pageCount}\n onClick={() => onPageChange(page + 1)}\n >\n Next ›\n </button>\n <button\n type=\"button\"\n className={BUTTON_CLASS}\n disabled={page + 1 >= pageCount}\n onClick={() => onPageChange(pageCount - 1)}\n >\n Last »\n </button>\n </div>\n </div>\n );\n}\n","/**\n * The five editors that ship with the grid.\n *\n * Each one writes into the row draft through `onChange` and never touches the\n * network — {@link DataGridProps.onRowCommit} owns persistence. Enter commits\n * the row, Escape abandons it.\n */\n\nimport type { EditorParams } from '../../types';\n\nconst INPUT_CLASS =\n 'h-7 w-full rounded border px-1.5 text-xs outline-none ' +\n 'border-gray-300 bg-white text-gray-800 ' +\n 'focus:border-brand-500 focus:ring-1 focus:ring-brand-500 ' +\n 'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';\n\nconst ERROR_CLASS = '!border-error-500 focus:!border-error-500 focus:!ring-error-500';\n\nfunction className(error?: string): string {\n return error ? `${INPUT_CLASS} ${ERROR_CLASS}` : INPUT_CLASS;\n}\n\n/** Enter commits the row, Escape abandons it -- shared by every editor. */\nfunction keyHandler(params: { onCommit: () => void; onCancel: () => void }) {\n return (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n params.onCommit();\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n params.onCancel();\n }\n };\n}\n\n/**\n * Single-line text input. The default editor when a column sets\n * `editable: true` without naming one.\n *\n * Reads `editorParams.placeholder`.\n */\nexport function TextEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n column,\n}: EditorParams<T, C>) {\n return (\n <input\n type=\"text\"\n className={className(error)}\n value={value == null ? '' : String(value)}\n autoFocus={autoFocus}\n placeholder={column.editorParams?.placeholder}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) => onChange(event.target.value)}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n\n/**\n * Numeric input. Writes a `number`, or `null` when the field is cleared, so an\n * empty cell is never stored as `NaN` or `''`.\n *\n * Reads `editorParams.placeholder`.\n */\nexport function NumberEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n}: EditorParams<T, C>) {\n return (\n <input\n type=\"number\"\n className={className(error)}\n value={value == null ? '' : String(value)}\n autoFocus={autoFocus}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) =>\n onChange(event.target.value === '' ? null : Number(event.target.value))\n }\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n\n/**\n * Native date input. Reads and writes `YYYY-MM-DD` strings, matching\n * {@link DateFilterModel}.\n */\nexport function DateEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n}: EditorParams<T, C>) {\n // Normalise whatever the row holds (ISO string, Date, timestamp) to the\n // `YYYY-MM-DD` a native date input requires.\n const asInputValue = (() => {\n if (value == null || value === '') return '';\n const date = value instanceof Date ? value : new Date(String(value));\n return Number.isNaN(date.getTime()) ? '' : date.toISOString().slice(0, 10);\n })();\n\n return (\n <input\n type=\"date\"\n className={className(error)}\n value={asInputValue}\n autoFocus={autoFocus}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) => onChange(event.target.value === '' ? null : event.target.value)}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n\n/**\n * Dropdown over `editorParams.options`. Values round-trip by identity, so a\n * non-string option value is preserved rather than stringified.\n */\nexport function SelectEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n error,\n autoFocus,\n column,\n}: EditorParams<T, C>) {\n const options = column.editorParams?.options ?? [];\n const selectedIndex = options.findIndex((option) => option.value === value);\n\n return (\n <select\n className={className(error)}\n value={selectedIndex === -1 ? '' : String(selectedIndex)}\n autoFocus={autoFocus}\n title={error}\n aria-invalid={error ? true : undefined}\n onChange={(event) => {\n const index = Number(event.target.value);\n onChange(Number.isNaN(index) ? null : options[index]?.value ?? null);\n }}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n >\n <option value=\"\">--</option>\n {options.map((option, index) => (\n <option key={`${String(option.value)}-${index}`} value={index}>\n {option.label}\n </option>\n ))}\n </select>\n );\n}\n\n/** Boolean checkbox. Writes `true` or `false`, never `undefined`. */\nexport function CheckboxEditor<T, C>({\n value,\n onChange,\n onCommit,\n onCancel,\n autoFocus,\n}: EditorParams<T, C>) {\n return (\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 accent-brand-500\"\n checked={value === true}\n autoFocus={autoFocus}\n onChange={(event) => onChange(event.target.checked)}\n onKeyDown={keyHandler({ onCommit, onCancel })}\n />\n );\n}\n","import {\n CheckboxEditor,\n DateEditor,\n NumberEditor,\n SelectEditor,\n TextEditor,\n} from './BuiltinEditors';\n\n/**\n * Maps a {@link BuiltinEditor} name to its component.\n *\n * Look one up to reuse it inside a custom editor, or to check which names are\n * available.\n *\n * @example\n * ```tsx\n * const Base = BUILTIN_EDITORS.text;\n * const UppercaseEditor: EditorComponent<Row> = (params) => (\n * <Base {...params} onChange={(v) => params.onChange(String(v).toUpperCase())} />\n * );\n * ```\n */\nexport const BUILTIN_EDITORS = {\n /** Single-line text input. See {@link TextEditor}. */\n text: TextEditor,\n /** Numeric input that writes `null` when cleared. See {@link NumberEditor}. */\n number: NumberEditor,\n /** Native date input over `YYYY-MM-DD`. See {@link DateEditor}. */\n date: DateEditor,\n /** Dropdown over `editorParams.options`. See {@link SelectEditor}. */\n select: SelectEditor,\n /** Boolean checkbox. See {@link CheckboxEditor}. */\n checkbox: CheckboxEditor,\n} as const;\n","import { memo } from 'react';\nimport type { ColumnLayoutItem, GridApi } from '../types';\nimport { formatValue, isEditable, resolveValue } from '../core/values';\nimport { BUILTIN_EDITORS } from './editors/registry';\n\nexport interface GridCellProps<T, C> {\n item: ColumnLayoutItem<T, C>;\n row: T;\n rowIndex: number;\n context: C;\n api: GridApi<T>;\n isRowEditing: boolean;\n draft: T | null;\n errors: Record<string, string>;\n isFirstEditable: boolean;\n onFieldChange: (field: string, value: unknown) => void;\n onCommit: () => void;\n onCancel: () => void;\n}\n\nconst ALIGN_CLASS = {\n left: 'justify-start text-left',\n center: 'justify-center text-center',\n right: 'justify-end text-right',\n} as const;\n\nfunction GridCellInner<T, C>({\n item,\n row,\n rowIndex,\n context,\n api,\n isRowEditing,\n draft,\n errors,\n isFirstEditable,\n onFieldChange,\n onCommit,\n onCancel,\n}: GridCellProps<T, C>) {\n const { column, width, pinned, stickyOffset } = item;\n\n const style: React.CSSProperties = {\n width,\n minWidth: width,\n maxWidth: width,\n ...(pinned === 'left'\n ? { position: 'sticky', left: stickyOffset, zIndex: 2 }\n : pinned === 'right'\n ? { position: 'sticky', right: stickyOffset, zIndex: 2 }\n : null),\n };\n\n const custom =\n typeof column.cellClassName === 'function'\n ? column.cellClassName(row)\n : column.cellClassName;\n\n const base =\n 'flex h-full items-center gap-1 border-r border-gray-200 px-2 text-xs ' +\n 'text-gray-700 dark:border-gray-700 dark:text-gray-200 ' +\n (pinned ? 'bg-white dark:bg-gray-900 ' : '');\n\n const alignment = ALIGN_CLASS[column.align ?? 'left'];\n\n // While the row is in edit mode, editable columns swap their renderer for the\n // editor and read from the draft rather than the persisted row.\n const editing = isRowEditing && draft != null && isEditable(column, row);\n\n if (editing) {\n const field = column.field ?? column.colId;\n const error = errors[field];\n const editorValue = resolveValue(draft, column as never);\n\n const Editor =\n typeof column.editor === 'function'\n ? column.editor\n : BUILTIN_EDITORS[column.editor ?? 'text'];\n\n return (\n <div\n role=\"gridcell\"\n className={`${base} ${alignment} ${custom ?? ''}`}\n style={style}\n data-col-id={column.colId}\n >\n <Editor\n value={editorValue}\n row={draft}\n column={column}\n context={context}\n error={error}\n autoFocus={isFirstEditable}\n onChange={(value: unknown) => onFieldChange(field, value)}\n onCommit={onCommit}\n onCancel={onCancel}\n />\n </div>\n );\n }\n\n const value = resolveValue(row, column as never);\n const formatted = formatValue(value, row, column as never);\n\n const content = column.cellRenderer\n ? column.cellRenderer({\n row,\n rowIndex,\n value,\n formatted,\n column,\n context,\n api,\n })\n : formatted;\n\n return (\n <div\n role=\"gridcell\"\n className={`${base} ${alignment} ${custom ?? ''}`}\n style={style}\n data-col-id={column.colId}\n title={column.cellRenderer ? undefined : formatted || undefined}\n >\n {column.cellRenderer ? (\n content\n ) : (\n <span className=\"truncate\">{formatted}</span>\n )}\n </div>\n );\n}\n\n/**\n * Memoised on the props that actually change what is painted. Volatile app\n * state reaches renderers through `context`, so a new context object re-renders\n * cells without any column definition being rebuilt.\n */\nexport const GridCell = memo(GridCellInner) as typeof GridCellInner;\n","import { memo, useState } from 'react';\nimport type { ColumnLayout, GridApi } from '../types';\nimport { isEditable } from '../core/values';\nimport type { RowId } from '../core/useSelectionModel';\nimport { GridCell } from './GridCell';\nimport { SelectionCell } from './SelectionCell';\n\nexport interface GridRowProps<T, C> {\n row: T;\n rowId: RowId;\n rowIndex: number;\n top: number;\n height: number;\n layout: ColumnLayout<T, C>;\n context: C;\n api: GridApi<T>;\n selectable: boolean;\n isSelected: boolean;\n isRowEditing: boolean;\n draft: T | null;\n errors: Record<string, string>;\n isSaving: boolean;\n onToggleSelect: (id: RowId, index: number, shiftKey: boolean) => void;\n onFieldChange: (field: string, value: unknown) => void;\n onCommit: () => void;\n onCancel: () => void;\n onRowDoubleClick: (rowId: RowId, row: T) => void;\n /** When set, files dropped on the row are handed to this callback. */\n onFilesDropped?: (row: T, files: File[]) => void;\n}\n\nfunction GridRowInner<T, C>({\n row,\n rowId,\n rowIndex,\n top,\n height,\n layout,\n context,\n api,\n selectable,\n isSelected,\n isRowEditing,\n draft,\n errors,\n isSaving,\n onToggleSelect,\n onFieldChange,\n onCommit,\n onCancel,\n onRowDoubleClick,\n onFilesDropped,\n}: GridRowProps<T, C>) {\n const [isDropTarget, setIsDropTarget] = useState(false);\n const rowError = errors.__row__;\n\n // Only the first editable column autofocuses, so entering edit mode does not\n // fight over the caret.\n const firstEditableColId = isRowEditing\n ? layout.items.find((item) => isEditable(item.column, row))?.colId\n : undefined;\n\n const background = isRowEditing\n ? 'bg-brand-25 dark:bg-brand-500/10'\n : isSelected\n ? 'bg-brand-50 dark:bg-brand-500/15'\n : rowIndex % 2 === 1\n ? 'bg-gray-50/60 dark:bg-white/[0.02]'\n : 'bg-white dark:bg-gray-900';\n\n return (\n <div\n role=\"row\"\n aria-rowindex={rowIndex + 1}\n aria-selected={selectable ? isSelected : undefined}\n className={`absolute left-0 flex border-b border-gray-200 dark:border-gray-700 ${background} hover:bg-brand-25 dark:hover:bg-white/[0.04] ${\n isSaving ? 'opacity-60' : ''\n } ${\n isDropTarget\n ? 'outline-2 -outline-offset-2 outline-dashed outline-brand-500'\n : ''\n }`}\n style={{ top, height, width: layout.totalWidth + (selectable ? 40 : 0) }}\n onDoubleClick={() => onRowDoubleClick(rowId, row)}\n title={rowError}\n onDragOver={\n onFilesDropped\n ? (event) => {\n // Only react to an actual file drag, not a column reorder.\n if (!event.dataTransfer.types.includes('Files')) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'copy';\n if (!isDropTarget) setIsDropTarget(true);\n }\n : undefined\n }\n onDragLeave={onFilesDropped ? () => setIsDropTarget(false) : undefined}\n onDrop={\n onFilesDropped\n ? (event) => {\n if (!event.dataTransfer.types.includes('Files')) return;\n event.preventDefault();\n setIsDropTarget(false);\n const files = Array.from(event.dataTransfer.files);\n if (files.length > 0) onFilesDropped(row, files);\n }\n : undefined\n }\n >\n {selectable && (\n <SelectionCell\n checked={isSelected}\n onToggle={(shiftKey) => onToggleSelect(rowId, rowIndex, shiftKey)}\n />\n )}\n\n {layout.items.map((item) => (\n <GridCell\n key={item.colId}\n item={item}\n row={row}\n rowIndex={rowIndex}\n context={context}\n api={api}\n isRowEditing={isRowEditing}\n draft={draft}\n errors={errors}\n isFirstEditable={item.colId === firstEditableColId}\n onFieldChange={onFieldChange}\n onCommit={onCommit}\n onCancel={onCancel}\n />\n ))}\n </div>\n );\n}\n\nexport const GridRow = memo(GridRowInner) as typeof GridRowInner;\n","import {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type Ref,\n} from 'react';\nimport type {\n ColumnDef,\n ExportCsvOptions,\n FilterModelMap,\n GridApi,\n HxDataSource,\n HxFilterModel,\n RowCommitResult,\n SortModelItem,\n} from '../types';\nimport { useColumnState } from '../core/useColumnState';\nimport { useEditModel } from '../core/useEditModel';\nimport { useGridState } from '../core/useGridState';\nimport { useSelectionModel, type RowId } from '../core/useSelectionModel';\nimport { useServerDataSource } from '../core/useServerDataSource';\nimport { useVirtualRows } from '../core/useVirtualRows';\nimport { copyToClipboard, downloadCsv, toCsv, toTsv } from '../core/exporters';\nimport { withFilter } from '../core/filterModel';\nimport { ColumnsPanel } from './ColumnsPanel';\nimport { FloatingFilterRow } from './FloatingFilterRow';\nimport { GridHeader } from './GridHeader';\nimport { GridOverlay } from './GridOverlay';\nimport { GridPagination } from './GridPagination';\nimport { GridRow } from './GridRow';\n\n/**\n * Props for {@link DataGrid}.\n *\n * @typeParam T - The row type.\n * @typeParam C - The {@link DataGridProps.context | context} type. Inferred\n * from `context`; defaults to `unknown`.\n */\nexport interface DataGridProps<T, C = unknown> {\n /**\n * The columns to render.\n *\n * @remarks\n * Define these as a module constant or memoise on `[]` — anything volatile\n * belongs in {@link DataGridProps.context} instead.\n */\n columns: ColumnDef<T, C>[];\n /**\n * Where rows come from. Memoise it; a new identity causes a refetch.\n *\n * @see {@link HxDataSource}\n */\n dataSource: HxDataSource<T>;\n /**\n * Stable identity for a row, used for selection, editing and\n * {@link GridApi.updateRows}. Must be stable across refetches.\n */\n getRowId: (row: T) => RowId;\n\n /**\n * Volatile app state handed to every cell renderer.\n *\n * This is the escape hatch that keeps `columns` static: put in-flight ids,\n * permission checks and event handlers here, and changing them re-renders\n * cells without rebuilding a single column definition.\n */\n context?: C;\n\n /**\n * `localStorage` key for column layout, sort, filters and page size.\n *\n * Omit it and nothing is persisted. Stored under `hxg:<storageKey>`.\n *\n * @see {@link PersistedGridState}\n */\n storageKey?: string;\n\n /**\n * Row height in pixels. Fixed for every row — that is what keeps\n * virtualization O(1).\n * @defaultValue 36\n */\n rowHeight?: number;\n /**\n * Header height in pixels.\n * @defaultValue 36\n */\n headerHeight?: number;\n /**\n * Show the always-visible filter inputs under the header.\n * @defaultValue true\n */\n floatingFilter?: boolean;\n /**\n * Show the checkbox selection column.\n * @defaultValue true\n */\n selectable?: boolean;\n\n /**\n * Rows per page before the user changes it. A persisted preference wins.\n * @defaultValue 20\n */\n defaultPageSize?: number;\n /**\n * Page sizes offered in the pager.\n * @defaultValue [10, 20, 50, 100]\n */\n pageSizeOptions?: number[];\n\n /**\n * Enables row editing. Called when the user commits a row.\n *\n * Return `{ ok: false, errors }` to keep the row open and paint each message\n * onto the cell whose column id it is keyed by.\n *\n * @param draft - The edited copy.\n * @param original - The row as it was before editing.\n * @see {@link RowCommitResult}\n */\n onRowCommit?: (draft: T, original: T) => Promise<RowCommitResult> | RowCommitResult;\n /**\n * Called whenever the selection changes.\n * @param ids - Every selected row id, including rows on other pages.\n */\n onSelectionChanged?: (ids: RowId[]) => void;\n /** Enables dropping files onto a row (e.g. to attach documents to it). */\n onRowFilesDropped?: (row: T, files: File[]) => void;\n /**\n * Called when a fetch or a commit throws. Aborted requests are not reported.\n */\n onError?: (error: unknown) => void;\n\n /**\n * Rendered into the toolbar strip above the header, left of the built-in\n * Columns and Export CSV buttons.\n *\n * @param api - The live imperative API.\n */\n toolbar?: (api: GridApi<T>) => ReactNode;\n\n /**\n * Shown when a query returns no rows.\n * @defaultValue 'No rows'\n */\n emptyMessage?: ReactNode;\n /**\n * Base file name for CSV export, without the extension.\n * @defaultValue 'export'\n */\n exportFileName?: string;\n /** Extra classes on the grid's outer frame. */\n className?: string;\n /**\n * Height of the whole grid. Any CSS length; a number is treated as pixels.\n * @defaultValue '70vh'\n */\n height?: number | string;\n\n /**\n * Receives the imperative {@link GridApi}. Accepts a ref object or a\n * callback ref.\n */\n apiRef?: Ref<GridApi<T>>;\n}\n\nconst DEFAULT_PAGE_SIZES = [10, 20, 50, 100];\n\n/**\n * A virtualized, server-driven data grid.\n *\n * Paging, sorting and filtering are all resolved by your\n * {@link HxDataSource | data source} — the grid holds one page at a time and\n * never filters or sorts locally. Rows are windowed at a fixed height, so the\n * DOM stays small regardless of the result set.\n *\n * @typeParam T - The row type.\n * @typeParam C - The context type, inferred from the `context` prop.\n *\n * @example Minimal usage\n * ```tsx\n * const columns: ColumnDef<Person>[] = [\n * { field: 'name', header: 'Name', flex: 1, filter: 'text' },\n * { field: 'email', header: 'Email', flex: 1 },\n * ];\n *\n * function People() {\n * const dataSource = useMemo(\n * () => ({ getRows: (request, signal) => api.list(request, signal) }),\n * []\n * );\n *\n * return (\n * <DataGrid\n * columns={columns}\n * dataSource={dataSource}\n * getRowId={(row) => row.id}\n * />\n * );\n * }\n * ```\n *\n * @example With editing, persistence and the imperative API\n * ```tsx\n * const apiRef = useRef<GridApi<Person>>(null);\n *\n * <DataGrid\n * columns={columns}\n * dataSource={dataSource}\n * getRowId={(row) => row.id}\n * storageKey=\"people\"\n * apiRef={apiRef}\n * onRowCommit={async (draft) => {\n * const result = await api.save(draft);\n * return result.ok ? { ok: true } : { ok: false, errors: result.errors };\n * }}\n * toolbar={(api) => (\n * <button onClick={() => api.refresh({ purge: true })}>Refresh</button>\n * )}\n * />\n * ```\n *\n * @remarks\n * Styling is plain Tailwind utility classes — there is no stylesheet to import.\n * Tailwind skips `node_modules` when detecting content, so point it at the\n * shipped bundle explicitly:\n *\n * ```css\n * @import \"tailwindcss\";\n * @source \"../node_modules/@helix-x/datagrid-ui/dist/index.js\";\n * ```\n *\n * @see {@link DataGridProps} for every option.\n * @see {@link GridApi} for what `apiRef` and `toolbar` receive.\n */\nexport function DataGrid<T, C = unknown>({\n columns,\n dataSource,\n getRowId,\n context,\n storageKey,\n rowHeight = 36,\n headerHeight = 36,\n floatingFilter = true,\n selectable = true,\n defaultPageSize = 20,\n pageSizeOptions = DEFAULT_PAGE_SIZES,\n onRowCommit,\n onSelectionChanged,\n onRowFilesDropped,\n onError,\n toolbar,\n emptyMessage,\n exportFileName = 'export',\n className = '',\n height = '70vh',\n apiRef,\n}: DataGridProps<T, C>) {\n const persisted = useGridState(storageKey);\n\n const [sortModel, setSortModel] = useState<SortModelItem[]>(\n () => persisted.initial?.sort ?? []\n );\n const [filterModel, setFilterModel] = useState<FilterModelMap>(\n () => persisted.initial?.filters ?? {}\n );\n const [pageSize, setPageSize] = useState(\n () => persisted.initial?.pagination.pageSize ?? defaultPageSize\n );\n const [page, setPage] = useState(0);\n const [showColumnsPanel, setShowColumnsPanel] = useState(false);\n\n /* ---------------------------------------------------------------------- */\n /* Measurement */\n /* ---------------------------------------------------------------------- */\n\n const viewportRef = useRef<HTMLDivElement>(null);\n const [viewportWidth, setViewportWidth] = useState(0);\n\n const floatingFilterHeight = floatingFilter ? 28 : 0;\n\n useLayoutEffect(() => {\n const element = viewportRef.current;\n if (!element) return;\n\n const observer = new ResizeObserver((entries) => {\n const rect = entries[0]?.contentRect;\n if (!rect) return;\n setViewportWidth(rect.width);\n setViewportHeightRef.current(\n Math.max(0, rect.height - headerHeight - floatingFilterHeight)\n );\n });\n\n observer.observe(element);\n return () => observer.disconnect();\n }, [headerHeight, floatingFilterHeight]);\n\n /* ---------------------------------------------------------------------- */\n /* Columns */\n /* ---------------------------------------------------------------------- */\n\n const columnState = useColumnState<T, C>(\n columns,\n persisted.initial?.columns,\n persisted.saveColumns,\n viewportWidth - (selectable ? 40 : 0)\n );\n\n /* ---------------------------------------------------------------------- */\n /* Data */\n /* ---------------------------------------------------------------------- */\n\n const { rows, totalRows, isLoading, error, refresh, patchRows } = useServerDataSource<T>(\n { dataSource, pageSize, page, sortModel, filterModel, onError }\n );\n\n // A page that no longer exists (filter narrowed the result set) would show an\n // empty grid forever, so walk back to the last real page.\n useEffect(() => {\n if (isLoading || totalRows === 0) return;\n const pageCount = Math.max(1, Math.ceil(totalRows / pageSize));\n if (page > pageCount - 1) setPage(pageCount - 1);\n }, [totalRows, pageSize, page, isLoading]);\n\n const virtual = useVirtualRows({ rowCount: rows.length, rowHeight });\n\n // Held in a ref so the ResizeObserver effect does not depend on the hook's\n // identity and re-subscribe on every render.\n const setViewportHeightRef = useRef(virtual.setViewportHeight);\n setViewportHeightRef.current = virtual.setViewportHeight;\n\n /* ---------------------------------------------------------------------- */\n /* Selection and editing */\n /* ---------------------------------------------------------------------- */\n\n const selection = useSelectionModel<T>(rows, getRowId, onSelectionChanged);\n\n const noopCommit = useCallback((): RowCommitResult => ({ ok: true }), []);\n const editing = useEditModel<T>(onRowCommit ?? noopCommit);\n\n /* ---------------------------------------------------------------------- */\n /* Query mutations */\n /* ---------------------------------------------------------------------- */\n\n // Any change to the query resets to the first page: staying on page 7 of a\n // freshly filtered result is never what the user meant.\n const applySort = useCallback(\n (next: SortModelItem[]) => {\n setSortModel(next);\n persisted.saveSort(next);\n setPage(0);\n },\n [persisted]\n );\n\n const applyFilters = useCallback(\n (next: FilterModelMap) => {\n setFilterModel(next);\n persisted.saveFilters(next);\n setPage(0);\n },\n [persisted]\n );\n\n const onSort = useCallback(\n (colId: string, additive: boolean) => {\n const existing = sortModel.find((entry) => entry.colId === colId);\n const others = sortModel.filter((entry) => entry.colId !== colId);\n\n // asc -> desc -> off\n const next: SortModelItem[] = !existing\n ? [...(additive ? sortModel : []), { colId, sort: 'asc' }]\n : existing.sort === 'asc'\n ? [...(additive ? others : []), { colId, sort: 'desc' }]\n : additive\n ? others\n : [];\n\n applySort(next);\n },\n [sortModel, applySort]\n );\n\n const onFilterChange = useCallback(\n (colId: string, filter: HxFilterModel | null) => {\n applyFilters(withFilter(filterModel, colId, filter));\n },\n [filterModel, applyFilters]\n );\n\n const onPageSizeChange = useCallback(\n (next: number) => {\n setPageSize(next);\n persisted.savePageSize(next);\n setPage(0);\n },\n [persisted]\n );\n\n /* ---------------------------------------------------------------------- */\n /* Imperative API */\n /* ---------------------------------------------------------------------- */\n\n // Latest-value refs keep the api object stable, so passing it into memoised\n // cells never invalidates them.\n const latest = useRef({\n rows,\n selection,\n columnState,\n filterModel,\n sortModel,\n editing,\n getRowId,\n });\n latest.current = {\n rows,\n selection,\n columnState,\n filterModel,\n sortModel,\n editing,\n getRowId,\n };\n\n const api = useMemo<GridApi<T>>(\n () => ({\n refresh: (options) => refresh(options),\n getDisplayedRows: () => latest.current.rows,\n getSelectedRows: () => latest.current.selection.getSelectedRows(),\n getSelectedIds: () => [...latest.current.selection.selectedIds],\n clearSelection: () => latest.current.selection.clear(),\n selectAll: () => latest.current.selection.selectAllVisible(),\n exportCsv: (options?: ExportCsvOptions) => {\n const source = options?.onlySelected\n ? latest.current.selection.getSelectedRows()\n : latest.current.rows;\n const csv = toCsv(\n source,\n latest.current.columnState.visibleColumns as never,\n options?.separator ?? ','\n );\n downloadCsv(csv, options?.fileName ?? exportFileName);\n },\n copySelectionToClipboard: async () => {\n const selected = latest.current.selection.getSelectedRows();\n const source = selected.length > 0 ? selected : latest.current.rows;\n await copyToClipboard(\n toTsv(source, latest.current.columnState.visibleColumns as never)\n );\n },\n getFilterModel: () => latest.current.filterModel,\n setFilterModel: applyFilters,\n getSortModel: () => latest.current.sortModel,\n setSortModel: applySort,\n resetColumns: () => {\n latest.current.columnState.reset();\n persisted.clear();\n },\n updateRows: (updated) => patchRows(updated, latest.current.getRowId),\n startEditing: (rowId) => {\n const row = latest.current.rows.find(\n (candidate) => latest.current.getRowId(candidate) === rowId\n );\n if (row) latest.current.editing.start(rowId, row);\n },\n stopEditing: () => latest.current.editing.cancel(),\n }),\n [refresh, applyFilters, applySort, patchRows, persisted, exportFileName]\n );\n\n useImperativeHandle(apiRef, () => api, [api]);\n\n /* ---------------------------------------------------------------------- */\n /* Row interaction */\n /* ---------------------------------------------------------------------- */\n\n const onRowDoubleClick = useCallback(\n (rowId: RowId, row: T) => {\n if (onRowCommit) editing.start(rowId, row);\n },\n [onRowCommit, editing]\n );\n\n // Clicking away from a row being edited abandons it rather than trapping the\n // user in edit mode. Keyed on the row id so the listener is attached once per\n // edit session, not once per render.\n const editingRowId = editing.edit?.rowId ?? null;\n const cancelEditRef = useRef(editing.cancel);\n cancelEditRef.current = editing.cancel;\n\n useEffect(() => {\n if (editingRowId == null) return;\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (!target.closest('[data-hxg-editing-row=\"true\"]')) cancelEditRef.current();\n };\n document.addEventListener('mousedown', onPointerDown);\n return () => document.removeEventListener('mousedown', onPointerDown);\n }, [editingRowId]);\n\n const emptyContext = useMemo(() => ({}) as C, []);\n const cellContext = context ?? emptyContext;\n\n const { startIndex, endIndex } = virtual.window;\n const visibleRows = rows.slice(startIndex, endIndex);\n\n const showEmpty = !isLoading && !error && rows.length === 0;\n\n return (\n <div\n className={`flex flex-col overflow-hidden rounded-lg border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-900 ${className}`}\n >\n <div className=\"flex flex-wrap items-center gap-2 border-b border-gray-200 bg-gray-50 px-2 py-1.5 dark:border-gray-700 dark:bg-gray-800/60\">\n {toolbar?.(api)}\n <div className=\"ml-auto flex items-center gap-1\">\n <button\n type=\"button\"\n className=\"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-white/5\"\n onClick={() => setShowColumnsPanel((current) => !current)}\n >\n Columns\n </button>\n <button\n type=\"button\"\n className=\"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-white/5\"\n onClick={() => api.exportCsv()}\n >\n Export CSV\n </button>\n </div>\n </div>\n\n <div className=\"flex min-h-0 flex-1\">\n {showColumnsPanel && (\n <ColumnsPanel\n columns={columnState.allColumns}\n isHidden={columnState.isHidden}\n onToggle={columnState.setHidden}\n onMove={columnState.moveColumn}\n onPin={columnState.setPinned}\n onReset={() => {\n columnState.reset();\n persisted.clear();\n }}\n onClose={() => setShowColumnsPanel(false)}\n />\n )}\n\n <div\n ref={viewportRef}\n role=\"grid\"\n aria-rowcount={totalRows}\n aria-colcount={columnState.layout.items.length}\n aria-busy={isLoading}\n className=\"relative min-w-0 flex-1 overflow-auto\"\n style={{ height }}\n onScroll={virtual.onScroll}\n >\n <GridHeader\n layout={columnState.layout}\n sortModel={sortModel}\n filterModel={filterModel}\n headerHeight={headerHeight}\n selectable={selectable}\n allSelected={selection.allVisibleSelected}\n someSelected={selection.someVisibleSelected}\n onToggleAll={selection.toggleAllVisible}\n onSort={onSort}\n onFilterChange={onFilterChange}\n onResize={columnState.setWidth}\n onMove={columnState.moveColumn}\n onPin={columnState.setPinned}\n />\n\n {floatingFilter && (\n <div style={{ top: headerHeight, position: 'sticky', zIndex: 9 }}>\n <FloatingFilterRow\n layout={columnState.layout}\n filterModel={filterModel}\n height={floatingFilterHeight}\n selectable={selectable}\n onFilterChange={onFilterChange}\n />\n </div>\n )}\n\n {/* Spacer carries the full scroll height; rows are positioned into it. */}\n <div\n className=\"relative\"\n style={{\n height: virtual.totalHeight,\n width: columnState.layout.totalWidth + (selectable ? 40 : 0),\n }}\n >\n {visibleRows.map((row, offset) => {\n const rowIndex = startIndex + offset;\n const rowId = getRowId(row);\n const isRowEditing = editing.edit?.rowId === rowId;\n\n return (\n <div\n key={rowId}\n data-hxg-editing-row={isRowEditing ? 'true' : undefined}\n >\n <GridRow\n row={row}\n rowId={rowId}\n rowIndex={rowIndex}\n top={rowIndex * rowHeight}\n height={rowHeight}\n layout={columnState.layout}\n context={cellContext}\n api={api}\n selectable={selectable}\n isSelected={selection.isSelected(rowId)}\n isRowEditing={isRowEditing}\n draft={isRowEditing ? (editing.edit?.draft ?? null) : null}\n errors={isRowEditing ? (editing.edit?.errors ?? {}) : {}}\n isSaving={isRowEditing && editing.edit?.isSaving === true}\n onToggleSelect={selection.toggleRow}\n onFieldChange={editing.setField}\n onCommit={editing.commit}\n onCancel={editing.cancel}\n onRowDoubleClick={onRowDoubleClick}\n onFilesDropped={onRowFilesDropped}\n />\n </div>\n );\n })}\n </div>\n\n {isLoading && <GridOverlay kind=\"loading\" />}\n {error != null && (\n <GridOverlay\n kind=\"error\"\n message={error instanceof Error ? error.message : String(error)}\n />\n )}\n {showEmpty && <GridOverlay kind=\"empty\" message={emptyMessage} />}\n </div>\n </div>\n\n {editing.edit && (\n <div className=\"flex items-center justify-end gap-2 border-t border-brand-200 bg-brand-25 px-2 py-1.5 dark:border-brand-500/30 dark:bg-brand-500/10\">\n <span className=\"mr-auto text-xs text-gray-600 dark:text-gray-300\">\n {editing.edit.errors.__row__ ??\n 'Editing row — Enter to save, Escape to cancel.'}\n </span>\n <button\n type=\"button\"\n className=\"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200\"\n onClick={editing.cancel}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"rounded bg-brand-500 px-2.5 py-0.5 text-xs font-medium text-white hover:bg-brand-600 disabled:opacity-50\"\n disabled={editing.edit.isSaving}\n onClick={editing.commit}\n >\n {editing.edit.isSaving ? 'Saving...' : 'Save'}\n </button>\n </div>\n )}\n\n <GridPagination\n page={page}\n pageSize={pageSize}\n totalRows={totalRows}\n pageSizeOptions={pageSizeOptions}\n isLoading={isLoading}\n onPageChange={setPage}\n onPageSizeChange={onPageSizeChange}\n />\n </div>\n );\n}\n"]}