mgh-components 2.1.0 → 2.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,"file":"index.cjs","sources":["../src/hooks/useResponsive.ts","../src/components/CustomNoRowsOverlay/CustomNoRowsOverlay.tsx","../src/components/MGHDataGrid/MGHDataGrid.tsx","../src/components/iconify/iconify.tsx","../src/components/Label/styles.ts","../src/components/Label/Label.tsx","../src/components/MGHGrid/utils.ts","../src/components/MGHGrid/MGHGrid.styles.ts","../src/components/MGHGrid/context.tsx","../src/components/MGHGrid/hooks.ts","../src/components/MGHGrid/export.ts","../src/components/MGHGrid/print.ts","../src/components/MGHGrid/grouping.ts","../src/components/MGHGrid/icons.tsx","../src/components/MGHGrid/components/primitives.tsx","../src/components/MGHGrid/components/Toolbar.tsx","../src/components/MGHGrid/components/Footer.tsx","../src/components/MGHGrid/components/ColumnsPanel.tsx","../src/components/MGHGrid/components/FilterPanel.tsx","../src/components/MGHGrid/components/ColumnMenu.tsx","../src/components/MGHGrid/components/Overlays.tsx","../src/components/MGHGrid/components/ActionsCell.tsx","../src/components/MGHGrid/MGHGrid.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.styles.ts","../src/components/MGHDateRangePicker/icons.tsx","../src/components/MGHDateRangePicker/utils.ts","../src/components/MGHDateRangePicker/MGHDateRangeCalendar.tsx","../src/components/MGHDateRangePicker/primitives.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.tsx","../src/components/MGHDatePicker/MGHDatePicker.styles.ts","../src/components/MGHDatePicker/utils.ts","../src/components/MGHDatePicker/MGHDateCalendar.tsx","../src/components/MGHDatePicker/MGHDatePicker.tsx","../src/components/Confirm-Dialog/confirm-dialog.tsx","../src/components/CustomGridToolbarExport/CustomGridToolbarExport.tsx","../src/components/Exporting/Exporting-Dialog.tsx"],"sourcesContent":["import useMediaQuery from '@mui/material/useMediaQuery';\nimport { useTheme, Breakpoint } from '@mui/material/styles';\n\n// ----------------------------------------------------------------------\n\ntype ReturnType = boolean;\n\nexport type Query = 'up' | 'down' | 'between' | 'only';\n\nexport type Value = Breakpoint | number;\n\nexport function useResponsive(query: Query, start?: Value, end?: Value): ReturnType {\n const theme = useTheme();\n\n const mediaUp = useMediaQuery(theme.breakpoints.up(start as Value));\n\n const mediaDown = useMediaQuery(theme.breakpoints.down(start as Value));\n\n const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Value, end as Value));\n\n const mediaOnly = useMediaQuery(theme.breakpoints.only(start as Breakpoint));\n\n if (query === 'up') {\n return mediaUp;\n }\n\n if (query === 'down') {\n return mediaDown;\n }\n\n if (query === 'between') {\n return mediaBetween;\n }\n\n return mediaOnly;\n}\n\n// ----------------------------------------------------------------------\n\ntype BreakpointOrNull = Breakpoint | null;\n\nexport function useWidth() {\n const theme = useTheme();\n\n const keys = [...theme.breakpoints.keys].reverse();\n\n return (\n keys.reduce((output: BreakpointOrNull, key: Breakpoint) => {\n const matches = useMediaQuery(theme.breakpoints.up(key));\n\n return !output && matches ? key : output;\n }, null) || 'xs'\n );\n}\n","import styled from '@emotion/styled';\n\nimport { Box } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n// import { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n\nimport React from 'react';\n// import { NoRowsOverlayPropsOverrides } from './CustomNoRowsOverlay.types';\n\n/// ---------------------------------------------------------------------------------------\n\ndeclare module '@mui/x-data-grid-premium' {\n export interface NoRowsOverlayPropsOverrides {\n text: string;\n useSettingsContext?: () => { themeMode?: string };\n }\n}\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomNoRowsOverlay({ text, useSettingsContext }: NoRowsOverlayPropsOverrides) {\n const theme = useTheme();\n const themeMode = useSettingsContext?.()?.themeMode ?? theme.palette.mode ?? 'light';\n\n const StyledGridOverlay = styled('div')(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n '& .ant-empty-img-1': {\n fill: themeMode === 'light' ? '#aeb8c2' : '#262626',\n },\n '& .ant-empty-img-2': {\n fill: themeMode === 'light' ? '#f5f5f7' : '#595959',\n },\n '& .ant-empty-img-3': {\n fill: themeMode === 'light' ? '#dce0e6' : '#434343',\n },\n '& .ant-empty-img-4': {\n fill: themeMode === 'light' ? '#fff' : '#1c1c1c',\n },\n '& .ant-empty-img-5': {\n fillOpacity: themeMode === 'light' ? '0.8' : '0.08',\n fill: themeMode === 'light' ? '#f5f5f5' : '#fff',\n },\n }));\n return (\n <StyledGridOverlay>\n <Box\n component=\"img\"\n alt=\"empty content\"\n src=\"/assets/icons/empty/ic_content.svg\"\n sx={{ width: 50, maxWidth: 160 }}\n />\n <Box sx={{ mb: 0 }}>{text}</Box>\n </StyledGridOverlay>\n );\n}\n","import React, { JSX } from 'react';\nimport dayjs from 'dayjs';\n\nimport { DateRange } from '@mui/x-date-pickers-pro';\n// `GridInitialStatePremium` itself only lives under an internal (non-exported) subpath; the\n// package re-exports it under this name from its public entry point instead.\nimport { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';\nimport { Box, Card, Theme, Badge, styled, SxProps, Tooltip, TextField, CardHeader, InputAdornment } from '@mui/material';\nimport {\n Toolbar,\n GridColDef,\n QuickFilter,\n GridRowParams,\n ToolbarButton,\n GridCloseIcon,\n GridSearchIcon,\n DataGridPremium,\n GridToolbarProps,\n QuickFilterClear,\n GridEventListener,\n GridSlotsComponent,\n FilterPanelTrigger,\n GridViewColumnIcon,\n GridFilterListIcon,\n QuickFilterControl,\n QuickFilterTrigger,\n GridCallbackDetails,\n ColumnsPanelTrigger,\n GridRowHeightParams,\n GridCsvExportOptions,\n GridRowSelectionModel,\n GridCsvExportMenuItem,\n ToolbarPropsOverrides,\n GridRowClassNameParams,\n GridExcelExportOptions,\n GridPrintExportOptions,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n GridSlotsComponentsProps,\n GridExportDisplayOptions,\n GridRowHeightReturnValue,\n GridColumnVisibilityModel,\n GridToolbarExportContainer,\n GridPinnedRowsProp,\n} from '@mui/x-data-grid-premium';\nimport { useResponsive } from '../../hooks/useResponsive';\nimport CustomNoRowsOverlay from '../CustomNoRowsOverlay/CustomNoRowsOverlay';\n\ninterface CustomToolbarProps {\n dateValues: React.SetStateAction<DateRange<dayjs.Dayjs>>;\n setDateValues: React.Dispatch<React.SetStateAction<DateRange<dayjs.Dayjs>>>;\n renderDateRange?: React.ReactNode;\n customMenuItem?: JSX.Element[];\n currentParentFolderKey?: number | null;\n types?: any;\n typeKey?: number;\n setTypeKey?: React.Dispatch<React.SetStateAction<number>>;\n userData?: unknown;\n exporting?: boolean;\n setExporting?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\ninterface MGHDataGridProps {\n rows: any[];\n columns: GridColDef[];\n onRowClick?: GridEventListener<'rowClick'>;\n onRowDoubleClick?: GridEventListener<'rowDoubleClick'>;\n header: string;\n pagination?: boolean;\n pageSize?: number;\n pageSizeOptions?: number[];\n slots?: Partial<GridSlotsComponent>;\n slotProps?: GridSlotsComponentsProps & {\n toolbar?: Partial<GridToolbarProps & ToolbarPropsOverrides & CustomToolbarProps>;\n };\n toolbarProps?: any;\n initialState?: GridInitialStatePremium;\n sx?: SxProps<Theme>;\n cardSx?: SxProps<Theme>;\n boxSx?: SxProps<Theme>;\n columnVisibilityModel?: GridColumnVisibilityModel;\n onColumnVisibilityModelChange?: (model: GridColumnVisibilityModel, details: GridCallbackDetails) => void;\n columnVisibilityStorageKey?: string;\n columnOrderStorageKey?: string;\n disableDensitySelector?: boolean;\n disableRowSelectionOnClick?: boolean;\n disableColumnFilter?: boolean;\n disableColumnMenu?: boolean;\n disableColumnSelector?: boolean;\n renderHeaderEndContent?: JSX.Element;\n renderHeaderCenterContent?: JSX.Element;\n noRowsText?: string;\n checkboxSelection?: boolean;\n checkboxSelectionVisibleOnly?: boolean;\n onRowSelectionModelChange?:\n | ((rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails<any>) => void)\n | undefined;\n rowSelectionModel?: GridRowSelectionModel | undefined;\n getRowClassName?: ((params: GridRowClassNameParams<any>) => string) | undefined;\n getDetailPanelContent?: (params: GridRowParams<any>) => React.ReactNode;\n getDetailPanelHeight?: () => number;\n loading?: boolean;\n isRowSelectable?: (params: GridRowParams<any>) => boolean;\n getRowHeight?: ((params: GridRowHeightParams) => GridRowHeightReturnValue) | undefined;\n showToolbar?: boolean;\n hideFooterRowCount?: boolean;\n onColumnOrderChange?: GridEventListener<'columnOrderChange'> | undefined;\n defaultGroupingExpansionDepth?: number;\n pinnedRows?: GridPinnedRowsProp;\n keepNonExistentRowsSelected?: boolean;\n}\n\nconst canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nconst readLocalStorage = <T,>(key: string): T | null => {\n if (!canUseLocalStorage()) {\n return null;\n }\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nconst writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) {\n return;\n }\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n return;\n }\n};\n\nconst normalizeOrderedFields = (orderedFields: string[] | null, columns: GridColDef[]) => {\n if (!orderedFields || orderedFields.length === 0) {\n return undefined;\n }\n const columnFields = new Set(columns.map((column) => column.field));\n return orderedFields.filter((field) => columnFields.has(field));\n};\n\nexport default function MGHDataGrid({\n header,\n rows,\n columns,\n onRowClick,\n onRowDoubleClick,\n pagination = true,\n pageSize = 25,\n slots = {},\n slotProps = {},\n toolbarProps = {},\n initialState = {},\n pageSizeOptions = [10, 25, 50, 100],\n sx = {},\n cardSx = { flexGrow: 1 },\n boxSx = { flexGrow: 1 },\n columnVisibilityModel,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n disableDensitySelector = false,\n disableRowSelectionOnClick = true,\n disableColumnFilter = false,\n disableColumnMenu = false,\n disableColumnSelector = false,\n checkboxSelectionVisibleOnly = false,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n noRowsText = 'No data found within selected parameters.',\n checkboxSelection = false,\n onRowSelectionModelChange = undefined,\n rowSelectionModel = undefined,\n getRowClassName = undefined,\n getDetailPanelContent,\n getDetailPanelHeight,\n loading = false,\n isRowSelectable = undefined,\n getRowHeight,\n showToolbar = true,\n hideFooterRowCount = false,\n onColumnOrderChange = undefined,\n defaultGroupingExpansionDepth = undefined,\n pinnedRows = undefined,\n keepNonExistentRowsSelected = true,\n}: MGHDataGridProps) {\n const smDown = useResponsive('down', 'sm');\n const persistedColumnVisibilityModel = React.useMemo(() => {\n if (!columnVisibilityStorageKey) {\n return undefined;\n }\n return readLocalStorage<GridColumnVisibilityModel>(columnVisibilityStorageKey) ?? undefined;\n }, [columnVisibilityStorageKey]);\n\n const persistedOrderedFields = React.useMemo(() => {\n if (!columnOrderStorageKey) {\n return undefined;\n }\n const storedOrder = readLocalStorage<string[]>(columnOrderStorageKey);\n return normalizeOrderedFields(storedOrder, columns);\n }, [columnOrderStorageKey, columns]);\n\n const resolvedColumnVisibilityModel =\n columnVisibilityModel !== undefined ? columnVisibilityModel : persistedColumnVisibilityModel;\n\n const handleColumnVisibilityModelChange = React.useCallback(\n (model: GridColumnVisibilityModel, details: GridCallbackDetails) => {\n if (columnVisibilityStorageKey) {\n writeLocalStorage(columnVisibilityStorageKey, model);\n }\n onColumnVisibilityModelChange?.(model, details);\n },\n [columnVisibilityStorageKey, onColumnVisibilityModelChange]\n );\n\n const handleColumnOrderChange = React.useCallback<GridEventListener<'columnOrderChange'>>(\n (params, event, details) => {\n if (columnOrderStorageKey) {\n const orderedFields = details.api.getAllColumns().map((column) => column.field);\n writeLocalStorage(columnOrderStorageKey, orderedFields);\n }\n onColumnOrderChange?.(params, event, details);\n },\n [columnOrderStorageKey, onColumnOrderChange]\n );\n\n const mergedInitialState: GridInitialStatePremium = {\n density: 'compact',\n pagination: { paginationModel: { pageSize } },\n filter: {\n filterModel: {\n items: [],\n quickFilterExcludeHiddenColumns: false,\n },\n },\n ...initialState,\n columns: {\n ...initialState?.columns,\n columnVisibilityModel: resolvedColumnVisibilityModel ?? initialState?.columns?.columnVisibilityModel,\n orderedFields: persistedOrderedFields ?? initialState?.columns?.orderedFields,\n },\n };\n\n return (\n <Card sx={{ height: 'auto', ...cardSx }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', pr: 1 }}>\n <CardHeader title={header} sx={{ mb: 2 }} />\n {renderHeaderCenterContent}\n <Box\n sx={{\n display: 'flex',\n gap: smDown ? 1 : 2,\n alignItems: 'center',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n }}\n >\n {renderHeaderEndContent}\n </Box>\n </Box>\n <Box component=\"div\" sx={{ display: 'flex', flexDirection: 'column', flexGrow: 1, ...boxSx }}>\n <DataGridPremium\n loading={loading}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n rows={rows}\n columns={columns}\n pagination={pagination}\n disableDensitySelector={disableDensitySelector}\n disableRowSelectionOnClick={disableRowSelectionOnClick}\n disableColumnFilter={disableColumnFilter}\n disableColumnMenu={disableColumnMenu}\n disableColumnSelector={disableColumnSelector}\n slots={{ noRowsOverlay: CustomNoRowsOverlay, toolbar: MGHGridToolbar, ...slots }}\n slotProps={{ noRowsOverlay: { text: noRowsText }, toolbar: toolbarProps, ...slotProps }}\n initialState={mergedInitialState}\n pageSizeOptions={pageSizeOptions}\n sx={{\n '& .MuiDataGrid-row:hover': {\n cursor: onRowClick || onRowDoubleClick ? 'pointer' : 'default',\n },\n ...sx,\n }}\n \n onColumnVisibilityModelChange={handleColumnVisibilityModelChange}\n checkboxSelection={checkboxSelection}\n onRowSelectionModelChange={onRowSelectionModelChange}\n rowSelectionModel={rowSelectionModel}\n isRowSelectable={isRowSelectable}\n getRowClassName={getRowClassName}\n getDetailPanelContent={getDetailPanelContent}\n getDetailPanelHeight={getDetailPanelHeight}\n checkboxSelectionVisibleOnly={checkboxSelectionVisibleOnly}\n disableRowSelectionExcludeModel\n showToolbar={showToolbar}\n hideFooterRowCount={hideFooterRowCount}\n getRowHeight={getRowHeight}\n onColumnOrderChange={handleColumnOrderChange}\n defaultGroupingExpansionDepth={defaultGroupingExpansionDepth}\n pinnedRows={pinnedRows}\n keepNonExistentRowsSelected={keepNonExistentRowsSelected}\n />\n </Box>\n </Card>\n );\n}\n\ninterface MGHGridToolbarProps {\n showColumnsButton?: boolean;\n showFilterButton?: boolean;\n showExportButton?: boolean;\n showQuickFilter?: boolean;\n renderOtherButtons?: JSX.Element;\n renderDateRange?: JSX.Element;\n customMenuItem?: JSX.Element[];\n showCsvOption?: boolean;\n}\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n showCsvOption = true,\n}: MGHGridToolbarProps) {\n return (\n <Toolbar style={{ display: 'flex', justifyContent: 'space-between' }}>\n <div>\n {showColumnsButton && (\n <Tooltip title=\"Columns\">\n <ColumnsPanelTrigger render={<ToolbarButton />}>\n <GridViewColumnIcon fontSize=\"small\" />\n </ColumnsPanelTrigger>\n </Tooltip>\n )}\n {showFilterButton && (\n <Tooltip title=\"Filters\">\n <FilterPanelTrigger\n render={(props, state) => (\n <ToolbarButton {...props} color=\"default\">\n <Badge badgeContent={state.filterCount} color=\"primary\" variant=\"dot\">\n <GridFilterListIcon fontSize=\"small\" />\n </Badge>\n </ToolbarButton>\n )}\n />\n </Tooltip>\n )}\n {showExportButton && (\n <CustomGridToolbarExport customMenuItem={customMenuItem} showCsvOption={showCsvOption} />\n )}\n </div>\n\n {renderDateRange}\n\n <div>\n {renderOtherButtons}\n {showQuickFilter && <DataGridQuickFilter />}\n </div>\n </Toolbar>\n );\n}\n\ninterface ExportContainerProps {\n csvOptions?: GridCsvExportOptions & GridExportDisplayOptions;\n excelOptions?: GridExcelExportOptions & GridExportDisplayOptions;\n printOptions?: GridPrintExportOptions & GridExportDisplayOptions;\n customMenuItem?: JSX.Element[] | undefined;\n showCsvOption?: boolean;\n}\nexport const CustomGridToolbarExport = ({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n customMenuItem,\n showCsvOption = true,\n ...other\n}: ExportContainerProps) => (\n <GridToolbarExportContainer {...other}>\n {customMenuItem?.map((el) => el)}\n {showCsvOption && <GridCsvExportMenuItem options={csvOptions} />}\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n);\n\nexport function DataGridQuickFilter() {\n type OwnerState = {\n expanded: boolean;\n };\n\n const StyledQuickFilter = styled(QuickFilter)({\n display: 'grid',\n alignItems: 'center',\n });\n\n const StyledToolbarButton = styled(ToolbarButton)<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n width: 'min-content',\n height: 'min-content',\n zIndex: 1,\n opacity: ownerState.expanded ? 0 : 1,\n pointerEvents: ownerState.expanded ? 'none' : 'auto',\n transition: theme.transitions.create(['opacity']),\n }));\n\n const StyledTextField = styled(TextField)<{\n ownerState: OwnerState;\n }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n overflowX: 'clip',\n width: ownerState.expanded ? 260 : 'var(--trigger-width)',\n opacity: ownerState.expanded ? 1 : 0,\n transition: theme.transitions.create(['width', 'opacity']),\n }));\n\n return (\n <StyledQuickFilter>\n <QuickFilterTrigger\n render={(triggerProps, state) => (\n <Tooltip title=\"Search\" enterDelay={0}>\n <StyledToolbarButton\n {...triggerProps}\n ownerState={{ expanded: state.expanded }}\n color=\"default\"\n aria-disabled={state.expanded}\n >\n <GridSearchIcon fontSize=\"small\" />\n </StyledToolbarButton>\n </Tooltip>\n )}\n />\n <QuickFilterControl\n render={({ ref, ...controlProps }, state) => (\n <StyledTextField\n {...controlProps}\n ownerState={{ expanded: state.expanded }}\n inputRef={ref}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n size=\"small\"\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <GridSearchIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n endAdornment: state.value ? (\n <InputAdornment position=\"end\">\n <QuickFilterClear\n edge=\"end\"\n size=\"small\"\n aria-label=\"Clear search\"\n material={{ sx: { marginRight: -0.75 } }}\n >\n <GridCloseIcon fontSize=\"small\" />\n </QuickFilterClear>\n </InputAdornment>\n ) : null,\n ...controlProps.slotProps?.input,\n },\n ...controlProps.slotProps,\n }}\n />\n )}\n />\n </StyledQuickFilter>\n );\n}\n","import { forwardRef } from 'react';\nimport { Icon } from '@iconify/react';\n\nimport { IconifyProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\ninterface Props {\n icon: IconifyProps;\n width?: number;\n height?: number;\n sx?: any;\n}\n\nconst Iconify = forwardRef<SVGElement, Props>(({ icon, width = 20, sx, ...other }, ref) => (\n <Icon icon={icon} style={{ width: 20, height: width ?? 20, ...sx }} />\n));\n\nexport default Iconify;\n","import type { ComponentProps, ComponentType } from 'react';\nimport Box from '@mui/material/Box';\nimport { alpha, styled, useTheme } from '@mui/material/styles';\nimport { LabelColor, LabelVariant } from './types';\n\n// ----------------------------------------------------------------------\n\ninterface StyledLabelOwnerState {\n color: LabelColor;\n variant: LabelVariant;\n}\n\n// Explicitly annotated so TS doesn't need to synthesize (and re-print) an anonymous type that\n// references @mui/system's install path — under pnpm that path is store-relative and triggers\n// TS2742 (\"inferred type cannot be named without a reference to ...\") during declaration emit.\nexport const StyledLabel = styled(Box)(({\n // theme,\n ownerState,\n}: {\n // theme: Theme;\n ownerState: StyledLabelOwnerState;\n}) => {\n const theme = useTheme();\n\n const lightMode = theme.palette.mode === 'light';\n\n const filledVariant = ownerState.variant === 'filled';\n\n const outlinedVariant = ownerState.variant === 'outlined';\n\n const softVariant = ownerState.variant === 'soft';\n\n const defaultStyle = {\n ...(ownerState.color === 'default' && {\n // FILLED\n ...(filledVariant && {\n color: lightMode ? theme.palette.common.white : theme.palette.grey[800],\n backgroundColor: theme.palette.text.primary,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n border: `2px solid ${theme.palette.text.primary}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.grey[500], 0.16),\n }),\n }),\n };\n\n const colorStyle = {\n ...(ownerState.color !== 'default' && {\n // FILLED\n ...(filledVariant && {\n color: theme.palette[ownerState.color].contrastText,\n backgroundColor: theme.palette[ownerState.color].main,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette[ownerState.color].main,\n border: `2px solid ${theme.palette[ownerState.color].main}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette[ownerState.color][lightMode ? 'dark' : 'light'],\n backgroundColor: alpha(theme.palette[ownerState.color].main, 0.16),\n }),\n }),\n };\n\n return {\n height: 24,\n minWidth: 24,\n lineHeight: 0,\n borderRadius: 6,\n cursor: 'default',\n alignItems: 'center',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n justifyContent: 'center',\n textTransform: 'capitalize',\n padding: theme.spacing(0, 0.75),\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightBold,\n transition: theme.transitions.create('all', {\n duration: theme.transitions.duration.shorter,\n }),\n ...defaultStyle,\n ...colorStyle,\n };\n}) as ComponentType<ComponentProps<typeof Box> & { ownerState: StyledLabelOwnerState }>;\n","import { forwardRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { LabelProps } from './types';\nimport { StyledLabel } from './styles';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nconst Label = forwardRef<HTMLSpanElement, LabelProps>(\n ({ children, color = 'default', variant = 'soft', startIcon, endIcon, sx, ...other }, ref) => {\n // const theme = useTheme();\n\n const iconStyles = {\n width: 16,\n height: 16,\n '& svg, img': { width: 1, height: 1, objectFit: 'cover' },\n };\n\n return (\n <StyledLabel\n ref={ref}\n // component=\"span\"\n ownerState={{ color, variant }}\n sx={{\n ...(startIcon && { pl: 0.75 }),\n ...(endIcon && { pr: 0.75 }),\n ...sx,\n }}\n // theme={theme}\n {...other}\n >\n {startIcon && <Box sx={{ mr: 0.75, ...iconStyles }}> {startIcon} </Box>}\n\n {children}\n\n {endIcon && <Box sx={{ ml: 0.75, ...iconStyles }}> {endIcon} </Box>}\n </StyledLabel>\n );\n }\n);\n\nexport default Label;\n","import dayjs from 'dayjs';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridColType,\n MGHGridComparatorFn,\n MGHGridFilterItem,\n MGHGridFilterOperator,\n MGHGridLocaleText,\n MGHGridRowId,\n MGHGridRowSelectionModel,\n MGHGridRowSelectionModelInput,\n MGHGridValidRowModel,\n MGHGridValueOption,\n MGHGridValueOptionObject,\n} from './MGHGrid.types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * ----------------------------------------------------------------------------------------------- */\n\nexport const GROUPING_COLUMN_FIELD = '__row_group_by_columns_group__';\nexport const CHECKBOX_FIELD = '__check__';\nexport const DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';\nexport const AGGREGATION_FOOTER_ID = '__aggregation_footer__';\nexport const INTERNAL_FIELDS = new Set<string>([CHECKBOX_FIELD, DETAIL_PANEL_TOGGLE_FIELD]);\n\nexport const DENSITY_FACTORS = { compact: 0.7, standard: 1, comfortable: 1.3 } as const;\nexport const DEFAULT_ROW_HEIGHT = 52;\nexport const DEFAULT_HEADER_HEIGHT = 56;\nexport const DEFAULT_COLUMN_WIDTH = 100;\nexport const DEFAULT_COLUMN_MIN_WIDTH = 50;\nexport const CHECKBOX_COLUMN_WIDTH = 50;\nexport const DETAIL_TOGGLE_COLUMN_WIDTH = 50;\nexport const GROUPING_COLUMN_WIDTH = 220;\n\nexport const isInternalField = (field: string) => INTERNAL_FIELDS.has(field) || field === GROUPING_COLUMN_FIELD;\n\n/* -------------------------------------------------------------------------------------------------\n * Generic helpers\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isEmptyValue = (value: unknown) => isNil(value) || value === '' || (Array.isArray(value) && value.length === 0);\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const arraysEqual = <T>(a: T[] | undefined, b: T[] | undefined) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\nexport const moveItem = <T>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n};\n\nexport const uniqueId = (() => {\n let counter = 0;\n return (prefix = 'mgh') => {\n counter += 1;\n return `${prefix}-${counter}`;\n };\n})();\n\n/* -------------------------------------------------------------------------------------------------\n * Local storage\n * ----------------------------------------------------------------------------------------------- */\n\nexport const canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nexport const readLocalStorage = <T>(key: string): T | null => {\n if (!canUseLocalStorage()) return null;\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nexport const writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore quota / privacy errors */\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Rows\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getRowIdFromRow = <R extends MGHGridValidRowModel>(row: R, getRowId?: (row: R) => MGHGridRowId) =>\n getRowId ? getRowId(row) : (row.id as MGHGridRowId);\n\nexport const normalizeSelectionModel = (\n input: MGHGridRowSelectionModelInput | undefined,\n allIds?: MGHGridRowId[]\n): MGHGridRowSelectionModel => {\n if (!input) return { type: 'include', ids: new Set() };\n if (Array.isArray(input)) return { type: 'include', ids: new Set(input) };\n if (input instanceof Set) return { type: 'include', ids: new Set(input) };\n if (input.type === 'exclude' && allIds) {\n const ids = new Set<MGHGridRowId>();\n allIds.forEach((id) => {\n if (!input.ids.has(id)) ids.add(id);\n });\n return { type: 'include', ids };\n }\n return { type: 'include', ids: new Set(input.ids) };\n};\n\nexport const selectionModelsEqual = (a: MGHGridRowSelectionModel, b: MGHGridRowSelectionModel) => {\n if (a.ids.size !== b.ids.size) return false;\n let equal = true;\n a.ids.forEach((id) => {\n if (!b.ids.has(id)) equal = false;\n });\n return equal;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Dates\n * ----------------------------------------------------------------------------------------------- */\n\nexport const toDate = (value: unknown): Date | null => {\n if (isNil(value) || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n if (dayjs.isDayjs(value)) return value.isValid() ? value.toDate() : null;\n if (typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === 'string') {\n const parsed = dayjs(value);\n return parsed.isValid() ? parsed.toDate() : null;\n }\n return null;\n};\n\nexport const formatDate = (value: unknown, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n return dayjs(date).format(withTime ? 'M/D/YYYY h:mm A' : 'M/D/YYYY');\n};\n\nconst startOfUnit = (date: Date, withTime: boolean) =>\n withTime ? dayjs(date).startOf('minute').valueOf() : dayjs(date).startOf('day').valueOf();\n\n/* -------------------------------------------------------------------------------------------------\n * Value options (singleSelect)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isValueOptionObject = (option: MGHGridValueOption): option is MGHGridValueOptionObject =>\n typeof option === 'object' && option !== null;\n\nexport const getOptionValue = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionValue ? col.getOptionValue(option) : isValueOptionObject(option) ? option.value : option;\n\nexport const getOptionLabel = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionLabel ? col.getOptionLabel(option) : isValueOptionObject(option) ? option.label : String(option);\n\nexport const resolveValueOptions = (col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (!col.valueOptions) return [] as MGHGridValueOption[];\n return typeof col.valueOptions === 'function' ? col.valueOptions({ field: col.field, row, id }) : col.valueOptions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Cell values\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getCellValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n const raw = row ? row[col.field] : undefined;\n return col.valueGetter ? col.valueGetter(raw, row, col, api) : raw;\n};\n\nexport const getGroupingValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n if (col.groupingValueGetter) return col.groupingValueGetter(row[col.field], row, col, api);\n return getCellValue(row, col, api);\n};\n\nexport const defaultFormatValue = (value: any, col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (isNil(value)) return '';\n switch (col.type) {\n case 'date':\n return formatDate(value, false);\n case 'dateTime':\n return formatDate(value, true);\n case 'boolean':\n return value ? 'Yes' : 'No';\n case 'singleSelect': {\n const options = resolveValueOptions(col, row, id);\n const match = options.find((option) => getOptionValue(col, option) === value);\n return match !== undefined ? getOptionLabel(col, match) : String(value);\n }\n case 'number':\n return typeof value === 'number' ? (Number.isFinite(value) ? String(value) : '') : String(value);\n default:\n if (value instanceof Date) return formatDate(value, true);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n};\n\nexport const getFormattedValue = (\n value: any,\n row: MGHGridValidRowModel,\n col: MGHGridColDef,\n api: MGHGridApi,\n id?: MGHGridRowId\n) => {\n if (col.valueFormatter) return col.valueFormatter(value, row, col, api);\n return defaultFormatValue(value, col, row, id);\n};\n\nexport const formattedValueToString = (formatted: any): string => {\n if (isNil(formatted)) return '';\n if (typeof formatted === 'string') return formatted;\n if (typeof formatted === 'number' || typeof formatted === 'boolean') return String(formatted);\n if (formatted instanceof Date) return formatDate(formatted, true);\n if (typeof formatted === 'object' && 'props' in formatted) return '';\n return String(formatted);\n};\n\nexport const parseEditValue = (raw: any, col: MGHGridColDef) => {\n switch (col.type) {\n case 'number': {\n if (raw === '' || isNil(raw)) return null;\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case 'boolean':\n return Boolean(raw);\n case 'date':\n case 'dateTime': {\n if (raw === '' || isNil(raw)) return null;\n const d = toDate(raw);\n return d ?? raw;\n }\n default:\n return raw;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Sorting\n * ----------------------------------------------------------------------------------------------- */\n\nconst collator = typeof Intl !== 'undefined' ? new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) : null;\n\nconst nilFirst = (v1: any, v2: any): number | null => {\n const n1 = isNil(v1) || v1 === '';\n const n2 = isNil(v2) || v2 === '';\n if (n1 && n2) return 0;\n if (n1) return -1;\n if (n2) return 1;\n return null;\n};\n\nexport const numberComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(v1) - Number(v2);\n};\n\nexport const stringComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n const s1 = String(v1);\n const s2 = String(v2);\n if (collator) return collator.compare(s1, s2);\n return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;\n};\n\nexport const stringOrNumberComparator: MGHGridComparatorFn = (v1, v2, p1, p2) => {\n if (typeof v1 === 'number' && typeof v2 === 'number') return numberComparator(v1, v2, p1, p2);\n return stringComparator(v1, v2, p1, p2);\n};\n\nexport const dateComparator: MGHGridComparatorFn = (v1, v2) => {\n const d1 = toDate(v1);\n const d2 = toDate(v2);\n const nil = nilFirst(d1, d2);\n if (nil !== null) return nil;\n return (d1 as Date).getTime() - (d2 as Date).getTime();\n};\n\nexport const booleanComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(Boolean(v1)) - Number(Boolean(v2));\n};\n\nexport const getDefaultComparator = (type: MGHGridColType | undefined): MGHGridComparatorFn => {\n switch (type) {\n case 'number':\n return numberComparator;\n case 'date':\n case 'dateTime':\n return dateComparator;\n case 'boolean':\n return booleanComparator;\n default:\n return stringOrNumberComparator;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Filter operators\n * ----------------------------------------------------------------------------------------------- */\n\nconst lower = (value: unknown) => (isNil(value) ? '' : String(value).toLowerCase());\n\nconst hasValue = (item: MGHGridFilterItem) => !isEmptyValue(item.value);\n\nexport const stringFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'contains',\n label: 'contains',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) !== -1;\n },\n },\n {\n value: 'doesNotContain',\n label: 'does not contain',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === -1;\n },\n },\n {\n value: 'equals',\n label: 'equals',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) === needle;\n },\n },\n {\n value: 'doesNotEqual',\n label: 'does not equal',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) !== needle;\n },\n },\n {\n value: 'startsWith',\n label: 'starts with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === 0;\n },\n },\n {\n value: 'endsWith',\n label: 'ends with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => {\n const s = lower(value);\n return s.length >= needle.length && s.lastIndexOf(needle) === s.length - needle.length;\n };\n },\n },\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(lower));\n return (value) => set.has(lower(value));\n },\n },\n];\n\nconst numberOperator = (\n value: string,\n label: string,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: 'number',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterValue = Number(item.value);\n if (Number.isNaN(filterValue)) return null;\n return (cell) => {\n if (isNil(cell) || cell === '') return false;\n const n = Number(cell);\n return !Number.isNaN(n) && compare(n, filterValue);\n };\n },\n});\n\nexport const numberFilterOperators: MGHGridFilterOperator[] = [\n numberOperator('=', '=', (a, b) => a === b),\n numberOperator('!=', '!=', (a, b) => a !== b),\n numberOperator('>', '>', (a, b) => a > b),\n numberOperator('>=', '>=', (a, b) => a >= b),\n numberOperator('<', '<', (a, b) => a < b),\n numberOperator('<=', '<=', (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map((v: any) => Number(v)));\n return (value) => !isNil(value) && set.has(Number(value));\n },\n },\n];\n\nconst dateOperator = (\n value: string,\n label: string,\n withTime: boolean,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: withTime ? 'datetime-local' : 'date',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterDate = toDate(item.value);\n if (!filterDate) return null;\n const filterTime = startOfUnit(filterDate, withTime);\n return (cell) => {\n const cellDate = toDate(cell);\n if (!cellDate) return false;\n return compare(startOfUnit(cellDate, withTime), filterTime);\n };\n },\n});\n\nexport const getDateFilterOperators = (withTime: boolean): MGHGridFilterOperator[] => [\n dateOperator('is', 'is', withTime, (a, b) => a === b),\n dateOperator('not', 'is not', withTime, (a, b) => a !== b),\n dateOperator('after', 'is after', withTime, (a, b) => a > b),\n dateOperator('onOrAfter', 'is on or after', withTime, (a, b) => a >= b),\n dateOperator('before', 'is before', withTime, (a, b) => a < b),\n dateOperator('onOrBefore', 'is on or before', withTime, (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) === null,\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) !== null,\n },\n];\n\nexport const booleanFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'boolean',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '' || item.value === 'any') return null;\n const expected = item.value === true || item.value === 'true';\n return (value) => Boolean(value) === expected;\n },\n },\n];\n\nexport const singleSelectFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) === String(item.value);\n },\n },\n {\n value: 'not',\n label: 'is not',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) !== String(item.value);\n },\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(String));\n return (value) => set.has(String(value));\n },\n },\n];\n\nexport const getDefaultFilterOperators = (type: MGHGridColType | undefined): MGHGridFilterOperator[] => {\n switch (type) {\n case 'number':\n return numberFilterOperators;\n case 'date':\n return getDateFilterOperators(false);\n case 'dateTime':\n return getDateFilterOperators(true);\n case 'boolean':\n return booleanFilterOperators;\n case 'singleSelect':\n return singleSelectFilterOperators;\n case 'actions':\n return [];\n default:\n return stringFilterOperators;\n }\n};\n\nexport const getColumnFilterOperators = (col: MGHGridColDef) => col.filterOperators ?? getDefaultFilterOperators(col.type);\n\n/* -------------------------------------------------------------------------------------------------\n * Column normalisation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const normalizeColumn = <R extends MGHGridValidRowModel>(col: MGHGridColDef<R>): MGHGridColDef<R> => {\n const type = col.type ?? 'string';\n const isNumber = type === 'number';\n const isBoolean = type === 'boolean';\n const isActions = type === 'actions';\n return {\n ...col,\n type,\n headerName: col.headerName ?? col.field,\n width: col.width ?? (isActions ? 100 : isBoolean ? 100 : DEFAULT_COLUMN_WIDTH),\n minWidth: col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n align: col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n headerAlign: col.headerAlign ?? col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n sortable: isActions ? false : (col.sortable ?? true),\n filterable: isActions ? false : (col.filterable ?? true),\n hideable: col.hideable ?? true,\n resizable: col.resizable ?? true,\n pinnable: col.pinnable ?? true,\n groupable: isActions ? false : (col.groupable ?? true),\n aggregable: isActions ? false : (col.aggregable ?? true),\n editable: col.editable ?? false,\n disableColumnMenu: col.disableColumnMenu ?? isActions,\n disableExport: col.disableExport ?? isActions,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Internal (auto-generated) columns\n * ----------------------------------------------------------------------------------------------- */\n\nconst internalColumn = (field: string, width: number): MGHGridColDef =>\n normalizeColumn({\n field,\n headerName: '',\n width,\n minWidth: width,\n maxWidth: width,\n sortable: false,\n filterable: false,\n hideable: false,\n resizable: false,\n pinnable: false,\n groupable: false,\n aggregable: false,\n disableColumnMenu: true,\n disableExport: true,\n disableReorder: true,\n align: 'center',\n headerAlign: 'center',\n });\n\n/** Definition of the checkbox-selection column (equivalent of MUI's GRID_CHECKBOX_SELECTION_COL_DEF). */\nexport const CHECKBOX_COLUMN_DEF: MGHGridColDef = internalColumn(CHECKBOX_FIELD, CHECKBOX_COLUMN_WIDTH);\n/** Definition of the detail-panel toggle column (equivalent of MUI's GRID_DETAIL_PANEL_TOGGLE_COL_DEF). */\nexport const DETAIL_PANEL_TOGGLE_COLUMN_DEF: MGHGridColDef = internalColumn(\n DETAIL_PANEL_TOGGLE_FIELD,\n DETAIL_TOGGLE_COLUMN_WIDTH\n);\n\n/* -------------------------------------------------------------------------------------------------\n * sx -> scoped CSS\n * ----------------------------------------------------------------------------------------------- */\n\nconst UNITLESS_PROPERTIES = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/** Keys that are CSS selectors / at-rules rather than CSS properties. */\nexport const isSelectorKey = (key: string) => /[&.:#>\\[\\s*~+,@]/.test(key);\n\nconst toKebabCase = (property: string) => {\n if (property.indexOf('--') === 0) return property;\n const kebab = property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return kebab.indexOf('ms-') === 0 ? `-${kebab}` : kebab;\n};\n\nconst formatCssValue = (property: string, value: string | number) =>\n typeof value === 'number' && value !== 0 && !UNITLESS_PROPERTIES.has(property) && property.indexOf('--') !== 0\n ? `${value}px`\n : String(value);\n\nconst serializeDeclarations = (block: Record<string, unknown>) =>\n Object.keys(block)\n .filter((key) => {\n const value = block[key];\n return !isSelectorKey(key) && (typeof value === 'string' || typeof value === 'number');\n })\n .map((key) => `${toKebabCase(key)}:${formatCssValue(key, block[key] as string | number)}`)\n .join(';');\n\nconst scopeSelector = (scope: string, selector: string) =>\n selector\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => (part.indexOf('&') !== -1 ? part.replace(/&/g, scope) : `${scope} ${part}`))\n .join(',');\n\n/**\n * Compiles the nested-selector part of an `sx`-like object into CSS scoped under `scope`.\n * Top-level plain properties are ignored here (they are applied as inline styles instead).\n */\nexport const buildScopedCss = (scope: string, sx: Record<string, unknown> | undefined, out: string[] = []): string[] => {\n if (!sx) return out;\n Object.keys(sx).forEach((key) => {\n const value = sx[key];\n if (!value || typeof value !== 'object') return;\n const block = value as Record<string, unknown>;\n if (key.charAt(0) === '@') {\n const inner: string[] = [];\n const declarations = serializeDeclarations(block);\n if (declarations) inner.push(`${scope}{${declarations}}`);\n buildScopedCss(scope, block, inner);\n if (inner.length) out.push(`${key}{${inner.join('')}}`);\n return;\n }\n const selector = scopeSelector(scope, key);\n const declarations = serializeDeclarations(block);\n if (declarations) out.push(`${selector}{${declarations}}`);\n buildScopedCss(selector, block, out);\n });\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nconst numericValues = (values: any[]) =>\n values.map((v) => (typeof v === 'number' ? v : Number(v))).filter((n) => !Number.isNaN(n) && n !== null);\n\nexport const BUILT_IN_AGGREGATION_FUNCTIONS: Record<string, MGHGridAggregationFunction> = {\n sum: {\n label: 'sum',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0);\n },\n },\n avg: {\n label: 'avg',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0) / nums.length;\n },\n },\n min: {\n label: 'min',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.min(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.min(...dates.map((d) => (d as Date).getTime())));\n }\n return defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any))[0];\n },\n },\n max: {\n label: 'max',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.max(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.max(...dates.map((d) => (d as Date).getTime())));\n }\n const sorted = defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any));\n return sorted[sorted.length - 1];\n },\n },\n size: {\n label: 'size',\n apply: ({ values }) => values.length,\n },\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Locale\n * ----------------------------------------------------------------------------------------------- */\n\nexport const DEFAULT_LOCALE_TEXT: MGHGridLocaleText = {\n noRowsLabel: 'No rows',\n loadingLabel: 'Loading…',\n toolbarColumns: 'Columns',\n toolbarFilters: 'Filters',\n toolbarExport: 'Export',\n toolbarDensity: 'Density',\n toolbarQuickFilterPlaceholder: 'Search...',\n toolbarQuickFilterLabel: 'Search',\n toolbarExportCSV: 'Download as CSV',\n toolbarExportExcel: 'Download as Excel',\n toolbarExportPrint: 'Print',\n densityCompact: 'Compact',\n densityStandard: 'Standard',\n densityComfortable: 'Comfortable',\n columnsPanelSearchPlaceholder: 'Search',\n columnsPanelShowAll: 'Show all',\n columnsPanelHideAll: 'Hide all',\n columnsPanelReset: 'Reset',\n filterPanelAddFilter: 'Add filter',\n filterPanelRemoveAll: 'Remove all',\n filterPanelDeleteIcon: 'Delete',\n filterPanelColumns: 'Columns',\n filterPanelOperator: 'Operator',\n filterPanelValue: 'Value',\n filterPanelInputPlaceholder: 'Filter value',\n filterPanelLogicOperator: 'Logic operator',\n filterPanelOperatorAnd: 'And',\n filterPanelOperatorOr: 'Or',\n columnMenuSortAsc: 'Sort by ASC',\n columnMenuSortDesc: 'Sort by DESC',\n columnMenuUnsort: 'Unsort',\n columnMenuFilter: 'Filter',\n columnMenuHideColumn: 'Hide column',\n columnMenuManageColumns: 'Manage columns',\n columnMenuPinLeft: 'Pin to left',\n columnMenuPinRight: 'Pin to right',\n columnMenuUnpin: 'Unpin',\n columnMenuGroup: (name) => `Group by ${name}`,\n columnMenuUngroup: (name) => `Stop grouping by ${name}`,\n columnMenuAggregation: 'Aggregation',\n aggregationMenuItemHeader: 'Aggregation',\n aggregationFunctionLabelNone: 'none',\n aggregationFunctionLabelSum: 'sum',\n aggregationFunctionLabelAvg: 'avg',\n aggregationFunctionLabelMin: 'min',\n aggregationFunctionLabelMax: 'max',\n aggregationFunctionLabelSize: 'size',\n footerRowSelected: (count) => (count === 1 ? '1 row selected' : `${count.toLocaleString()} rows selected`),\n footerTotalRows: 'Total Rows:',\n footerPaginationRowsPerPage: 'Rows per page:',\n footerPaginationDisplayedRows: (from, to, count) => `${from}–${to} of ${count.toLocaleString()}`,\n footerPaginationFirstPage: 'First page',\n footerPaginationPreviousPage: 'Previous page',\n footerPaginationNextPage: 'Next page',\n footerPaginationLastPage: 'Last page',\n checkboxSelectionHeaderName: 'Checkbox selection',\n checkboxSelectionSelectAllRows: 'Select all rows',\n checkboxSelectionUnselectAllRows: 'Unselect all rows',\n checkboxSelectionSelectRow: 'Select row',\n checkboxSelectionUnselectRow: 'Unselect row',\n booleanCellTrueLabel: 'yes',\n booleanCellFalseLabel: 'no',\n detailPanelToggle: 'Detail panel toggle',\n expandDetailPanel: 'Expand',\n collapseDetailPanel: 'Collapse',\n groupingColumnHeaderName: 'Group',\n groupColumn: (name) => `Group by ${name}`,\n unGroupColumn: (name) => `Stop grouping by ${name}`,\n actionsCellMore: 'more',\n columnHeaderSortIconLabel: 'Sort',\n columnMenuLabel: 'Menu',\n clearSearch: 'Clear search',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Text measurement (used for autosize)\n * ----------------------------------------------------------------------------------------------- */\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nexport const measureText = (text: string, font: string) => {\n if (typeof document === 'undefined') return text.length * 8;\n if (measureContext === undefined) {\n const canvas = document.createElement('canvas');\n measureContext = canvas.getContext('2d');\n }\n if (!measureContext) return text.length * 8;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Downloads\n * ----------------------------------------------------------------------------------------------- */\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n window.setTimeout(() => {\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n }, 0);\n};\n","import React from 'react';\n\nexport const MGH_GRID_STYLE_ID = 'mgh-grid-styles';\n\n/**\n * Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,\n * so consumers do not need a CSS loader. All colours are CSS variables so the look can be\n * customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance\n * through the `themeVars` prop.\n */\nexport const MGH_GRID_CSS = `\n.mgh-grid-card {\n --mgh-grid-font-family: inherit;\n --mgh-grid-font-size: 14px;\n --mgh-grid-radius: 16px;\n --mgh-grid-inner-radius: 4px;\n --mgh-grid-paper: #ffffff;\n --mgh-grid-bg: #ffffff;\n --mgh-grid-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-fg-secondary: rgba(0, 0, 0, 0.6);\n --mgh-grid-fg-disabled: rgba(0, 0, 0, 0.38);\n --mgh-grid-border: rgba(224, 224, 224, 1);\n --mgh-grid-header-bg: #ffffff;\n --mgh-grid-header-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-hover: rgba(0, 0, 0, 0.04);\n --mgh-grid-hover-strong: rgba(0, 0, 0, 0.08);\n --mgh-grid-selected: rgba(25, 118, 210, 0.08);\n --mgh-grid-selected-hover: rgba(25, 118, 210, 0.12);\n --mgh-grid-primary: #1976d2;\n --mgh-grid-primary-contrast: #ffffff;\n --mgh-grid-focus: #1976d2;\n --mgh-grid-shadow: 0 0 2px rgba(145, 158, 171, 0.2), 0 12px 24px -4px rgba(145, 158, 171, 0.12);\n --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n --mgh-grid-overlay: rgba(255, 255, 255, 0.6);\n --mgh-grid-input-bg: transparent;\n --mgh-grid-input-border: rgba(0, 0, 0, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.12);\n --mgh-grid-group-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-footer-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-badge: #1976d2;\n --mgh-grid-scrollbar: rgba(0, 0, 0, 0.3);\n\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: var(--mgh-grid-paper);\n color: var(--mgh-grid-fg);\n border-radius: var(--mgh-grid-radius);\n box-shadow: var(--mgh-grid-shadow);\n font-family: var(--mgh-grid-font-family);\n font-size: var(--mgh-grid-font-size);\n line-height: 1.5;\n overflow: hidden;\n box-sizing: border-box;\n}\n.mgh-grid-card[data-mgh-theme=\"dark\"] {\n --mgh-grid-paper: #212b36;\n --mgh-grid-bg: #212b36;\n --mgh-grid-fg: #ffffff;\n --mgh-grid-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-grid-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-grid-border: rgba(81, 81, 81, 1);\n --mgh-grid-header-bg: #212b36;\n --mgh-grid-header-fg: #ffffff;\n --mgh-grid-hover: rgba(255, 255, 255, 0.08);\n --mgh-grid-hover-strong: rgba(255, 255, 255, 0.16);\n --mgh-grid-selected: rgba(144, 202, 249, 0.16);\n --mgh-grid-selected-hover: rgba(144, 202, 249, 0.24);\n --mgh-grid-primary: #90caf9;\n --mgh-grid-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-grid-focus: #90caf9;\n --mgh-grid-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 12px 24px -4px rgba(0, 0, 0, 0.12);\n --mgh-grid-overlay: rgba(33, 43, 54, 0.6);\n --mgh-grid-input-border: rgba(255, 255, 255, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.5);\n --mgh-grid-group-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-footer-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-badge: #90caf9;\n --mgh-grid-scrollbar: rgba(255, 255, 255, 0.3);\n}\n/* Only our own elements get the border-box reset. A blanket descendant reset would leak into\n consumer content rendered through slots (e.g. MUI TextField inputs rely on content-box). */\n[class*=\"mgh-grid\"], [class*=\"mgh-grid\"]::before, [class*=\"mgh-grid\"]::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n/* Title stays on its row; only the end-content group wraps internally (like the legacy MUI card). */\n.mgh-grid-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 16px 16px 0; flex-wrap: nowrap; }\n.mgh-grid-card-title { flex: 0 0 auto; padding: 8px 24px; margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n/* Children are auto-sized so space-between leaves equal gaps title|center|end (like the legacy MUI card).\n Only the end group shrinks (and wraps internally); the centre content keeps its natural width. */\n.mgh-grid-card-header-center { flex: 0 0 auto; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }\n.mgh-grid-card-header-end { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n.mgh-grid-card-header-end:first-child { margin-left: auto; }\n@media (max-width: 599.95px) {\n .mgh-grid-card-header { flex-wrap: wrap; }\n .mgh-grid-card-header-end { gap: 8px; }\n}\n\n/* ---- box + root ---- */\n.mgh-grid-box { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; min-width: 0; }\n.mgh-grid {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n border: 1px solid var(--mgh-grid-border);\n border-radius: var(--mgh-grid-inner-radius);\n background: var(--mgh-grid-bg);\n color: var(--mgh-grid-fg);\n outline: none;\n}\n.mgh-grid--auto-height { flex: 0 0 auto; }\n\n/* ---- toolbar ---- */\n.mgh-grid-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 4px 8px; border-bottom: 1px solid var(--mgh-grid-border); flex-wrap: wrap; }\n.mgh-grid-toolbar-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }\n.mgh-grid-toolbar-center { display: flex; align-items: center; flex: 1 1 auto; justify-content: center; }\n\n/* ---- buttons ---- */\n.mgh-grid-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-grid-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; text-transform: none; white-space: nowrap; }\n.mgh-grid-btn:hover { background: var(--mgh-grid-hover); color: var(--mgh-grid-fg); }\n.mgh-grid-btn:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 1px; }\n.mgh-grid-btn:disabled { color: var(--mgh-grid-fg-disabled); cursor: default; background: transparent; }\n.mgh-grid-btn--icon { padding: 6px; border-radius: 50%; width: 32px; height: 32px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small { width: 26px; height: 26px; padding: 3px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small .mgh-grid-icon { width: 18px; height: 18px; }\n.mgh-grid-btn--primary { color: var(--mgh-grid-primary); }\n.mgh-grid-btn--primary:hover { background: var(--mgh-grid-selected); color: var(--mgh-grid-primary); }\n.mgh-grid-btn--contained { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); }\n.mgh-grid-btn--contained:hover { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); filter: brightness(0.92); }\n.mgh-grid-btn--active { color: var(--mgh-grid-primary); }\n\n/* ---- badge ---- */\n.mgh-grid-badge { position: relative; display: inline-flex; }\n.mgh-grid-badge-dot { position: absolute; top: 0; right: 0; min-width: 8px; height: 8px; border-radius: 4px; background: var(--mgh-grid-badge); transform: translate(50%, -50%); }\n.mgh-grid-badge-count { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--mgh-grid-badge); color: var(--mgh-grid-primary-contrast); font-size: 10px; font-weight: 600; line-height: 16px; text-align: center; transform: translate(50%, -50%); }\n\n/* ---- inputs ---- */\n.mgh-grid-input, .mgh-grid-select { font: inherit; font-size: 0.875rem; color: var(--mgh-grid-fg); background: var(--mgh-grid-input-bg); border: 1px solid var(--mgh-grid-input-border); border-radius: 6px; padding: 6px 10px; height: 36px; min-width: 0; outline: none; transition: border-color .15s, box-shadow .15s; }\n.mgh-grid-input:hover, .mgh-grid-select:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-input:focus, .mgh-grid-select:focus { border-color: var(--mgh-grid-focus); box-shadow: 0 0 0 1px var(--mgh-grid-focus); }\n.mgh-grid-input::placeholder { color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-input--small, .mgh-grid-select--small { height: 32px; padding: 4px 8px; font-size: 0.8125rem; }\n.mgh-grid-select { appearance: none; -webkit-appearance: none; padding-right: 28px; background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'><path d='M7 10l5 5 5-5z'/></svg>\"); background-repeat: no-repeat; background-position: right 6px center; background-size: 18px; cursor: pointer; }\n.mgh-grid-select option { color: initial; background: initial; }\n.mgh-grid-card[data-mgh-theme=\"dark\"] .mgh-grid-select option, .mgh-grid-popover[data-mgh-theme=\"dark\"] .mgh-grid-select option { color: #fff; background: #212b36; }\n.mgh-grid-select[multiple] { height: auto; min-height: 36px; background-image: none; padding-right: 10px; }\n.mgh-grid-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.mgh-grid-field-label { font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-input-adorned { position: relative; display: flex; align-items: center; }\n.mgh-grid-input-adorned .mgh-grid-input { width: 100%; padding-left: 34px; }\n.mgh-grid-input-adorned--clearable .mgh-grid-input { padding-right: 34px; }\n.mgh-grid-input-adornment { position: absolute; left: 10px; display: inline-flex; color: var(--mgh-grid-fg-secondary); pointer-events: none; }\n.mgh-grid-input-adornment--end { left: auto; right: 4px; pointer-events: auto; }\n\n/* ---- checkbox ---- */\n.mgh-grid-checkbox { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; border: 2px solid var(--mgh-grid-fg-secondary); border-radius: 3px; background: transparent; cursor: pointer; display: inline-grid; place-content: center; position: relative; flex: 0 0 auto; transition: background-color .12s, border-color .12s; }\n.mgh-grid-checkbox:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-checkbox:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 2px; }\n.mgh-grid-checkbox:checked, .mgh-grid-checkbox:indeterminate { background: var(--mgh-grid-primary); border-color: var(--mgh-grid-primary); }\n.mgh-grid-checkbox:checked::after { content: \"\"; width: 5px; height: 10px; border: solid var(--mgh-grid-primary-contrast); border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }\n.mgh-grid-checkbox:indeterminate::after { content: \"\"; width: 10px; height: 2px; background: var(--mgh-grid-primary-contrast); }\n.mgh-grid-checkbox:disabled { opacity: 0.4; cursor: default; }\n.mgh-grid-checkbox-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; padding: 6px 4px; border-radius: 4px; }\n.mgh-grid-checkbox-label:hover { background: var(--mgh-grid-hover); }\n\n/* ---- quick filter ---- */\n.mgh-grid-quick-filter { display: grid; align-items: center; }\n.mgh-grid-quick-filter-trigger { grid-area: 1 / 1; z-index: 1; transition: opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-trigger { opacity: 0; pointer-events: none; }\n.mgh-grid-quick-filter-control { grid-area: 1 / 1; width: 32px; opacity: 0; overflow: hidden; transition: width .2s, opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 260px; opacity: 1; }\n@media (max-width: 599.95px) { .mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 180px; } }\n\n/* ---- main / scroller ---- */\n.mgh-grid-main { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }\n.mgh-grid--auto-height .mgh-grid-main { flex: 0 0 auto; }\n.mgh-grid-scroller { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; outline: none; scrollbar-width: thin; }\n.mgh-grid--auto-height .mgh-grid-scroller { overflow-y: hidden; }\n.mgh-grid-scroller::-webkit-scrollbar { width: 10px; height: 10px; }\n.mgh-grid-scroller::-webkit-scrollbar-thumb { background: var(--mgh-grid-scrollbar); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }\n\n/* ---- column headers ---- */\n.mgh-grid-columns { position: sticky; top: 0; z-index: 3; background: var(--mgh-grid-header-bg); border-bottom: 1px solid var(--mgh-grid-border); min-width: 100%; width: max-content; }\n.mgh-grid-header-row { display: flex; min-width: 100%; }\n.mgh-grid-header-cell { position: relative; display: flex; align-items: center; flex: 0 0 auto; height: var(--mgh-grid-header-height); padding: 0 10px; font-weight: 600; font-size: 0.875rem; color: var(--mgh-grid-header-fg); background: var(--mgh-grid-header-bg); white-space: nowrap; overflow: hidden; user-select: none; outline: none; }\n.mgh-grid-header-cell--sortable { cursor: pointer; }\n.mgh-grid-header-cell:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; }\n.mgh-grid-header-cell--align-center { justify-content: center; }\n.mgh-grid-header-cell--align-right { justify-content: flex-end; }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title-container { flex-direction: row-reverse; }\n.mgh-grid-header-title-container { display: flex; align-items: center; gap: 2px; min-width: 0; flex: 1 1 auto; overflow: hidden; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title-container { flex: 0 1 auto; }\n.mgh-grid-header-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.mgh-grid-sort-icon { display: inline-flex; align-items: center; color: var(--mgh-grid-fg-secondary); opacity: 0; transition: opacity .15s; flex: 0 0 auto; }\n.mgh-grid-header-cell:hover .mgh-grid-sort-icon, .mgh-grid-sort-icon--active { opacity: 1; }\n.mgh-grid-sort-index { font-size: 10px; margin-left: -2px; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-header-menu-btn { position: absolute; right: 2px; opacity: 0; transition: opacity .15s; background: var(--mgh-grid-header-bg); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-menu-btn { right: auto; left: 2px; }\n.mgh-grid-header-cell:hover .mgh-grid-header-menu-btn, .mgh-grid-header-menu-btn--open, .mgh-grid-header-cell:focus-within .mgh-grid-header-menu-btn { opacity: 1; }\n.mgh-grid-header-cell--menu-open { background: var(--mgh-grid-hover); }\n.mgh-grid-resize-handle { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 2; display: flex; justify-content: center; touch-action: none; }\n.mgh-grid-resize-handle::after { content: \"\"; width: 1px; height: 60%; margin-top: 20%; background: var(--mgh-grid-border); transition: background .15s, width .15s; }\n.mgh-grid-resize-handle:hover::after, .mgh-grid-resize-handle--active::after { background: var(--mgh-grid-primary); width: 2px; }\n.mgh-grid-header-cell--last .mgh-grid-resize-handle { right: 0; }\n.mgh-grid-header-cell--dragging { opacity: 0.5; }\n.mgh-grid-header-cell--drop-left::before, .mgh-grid-header-cell--drop-right::before { content: \"\"; position: absolute; top: 4px; bottom: 4px; width: 2px; background: var(--mgh-grid-primary); z-index: 3; }\n.mgh-grid-header-cell--drop-left::before { left: 0; }\n.mgh-grid-header-cell--drop-right::before { right: 0; }\n.mgh-grid-header-filler { flex: 1 1 auto; background: var(--mgh-grid-header-bg); }\n\n/* ---- pinned cells ---- */\n.mgh-grid-cell--pinned-left, .mgh-grid-header-cell--pinned-left { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-cell--pinned-right, .mgh-grid-header-cell--pinned-right { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-header-cell--pinned-left, .mgh-grid-header-cell--pinned-right { z-index: 4; background-color: var(--mgh-grid-header-bg); }\n.mgh-grid-cell--pinned-left-last, .mgh-grid-header-cell--pinned-left-last { box-shadow: 2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-cell--pinned-right-first, .mgh-grid-header-cell--pinned-right-first { box-shadow: -2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid--no-pinned-shadow .mgh-grid-cell--pinned-left-last, .mgh-grid--no-pinned-shadow .mgh-grid-header-cell--pinned-left-last { box-shadow: none; }\n\n/* ---- body & rows ---- */\n.mgh-grid-body { position: relative; min-width: 100%; width: max-content; }\n.mgh-grid-body--flow { display: flex; flex-direction: column; }\n.mgh-grid-row-block { min-width: 100%; }\n.mgh-grid-body--virtual .mgh-grid-row-block { position: absolute; left: 0; }\n.mgh-grid-row { display: flex; min-width: 100%; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); position: relative; }\n.mgh-grid-row--auto-height { align-items: stretch; }\n.mgh-grid-row:hover { background: var(--mgh-grid-hover); }\n.mgh-grid-row--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-row--selected:hover { background: var(--mgh-grid-selected-hover); }\n.mgh-grid-row--clickable { cursor: pointer; }\n.mgh-grid-row--group { background: var(--mgh-grid-group-bg); }\n.mgh-grid-row--pinned { background: var(--mgh-grid-bg); }\n.mgh-grid-row--footer { background: var(--mgh-grid-footer-bg); font-weight: 600; }\n.mgh-grid-row:hover .mgh-grid-cell--pinned-left, .mgh-grid-row:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-hover), var(--mgh-grid-hover)); }\n.mgh-grid-row--selected .mgh-grid-cell--pinned-left, .mgh-grid-row--selected .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected), var(--mgh-grid-selected)); }\n.mgh-grid-row--selected:hover .mgh-grid-cell--pinned-left, .mgh-grid-row--selected:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected-hover), var(--mgh-grid-selected-hover)); }\n.mgh-grid-row--group .mgh-grid-cell--pinned-left, .mgh-grid-row--group .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-group-bg), var(--mgh-grid-group-bg)); }\n.mgh-grid-row--footer .mgh-grid-cell--pinned-left, .mgh-grid-row--footer .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-footer-bg), var(--mgh-grid-footer-bg)); }\n.mgh-grid-row-filler { flex: 1 1 auto; }\n\n.mgh-grid-cell { display: flex; align-items: center; flex: 0 0 auto; padding: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.875rem; outline: none; min-height: 100%; }\n.mgh-grid-cell > .mgh-grid-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.mgh-grid-row--auto-height .mgh-grid-cell { white-space: normal; align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }\n.mgh-grid-row--auto-height .mgh-grid-cell > .mgh-grid-cell-text { white-space: normal; word-break: break-word; }\n.mgh-grid-cell--align-center { justify-content: center; }\n.mgh-grid-cell--align-right { justify-content: flex-end; }\n.mgh-grid-cell--focused { outline: 1px solid var(--mgh-grid-focus); outline-offset: -1px; }\n.mgh-grid-cell--editable { cursor: text; }\n.mgh-grid-cell--editing { padding: 0 4px; outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; background: var(--mgh-grid-bg); }\n.mgh-grid-cell--editing .mgh-grid-input, .mgh-grid-cell--editing .mgh-grid-select { width: 100%; height: calc(100% - 6px); border: 0; box-shadow: none; padding: 0 6px; background: transparent; }\n.mgh-grid-cell--checkbox, .mgh-grid-header-cell--checkbox, .mgh-grid-cell--detail-toggle, .mgh-grid-header-cell--detail-toggle { justify-content: center; padding: 0; }\n.mgh-grid-cell--boolean .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-cell--actions { gap: 2px; justify-content: center; }\n.mgh-grid-cell--aggregation { flex-direction: column; align-items: stretch; justify-content: center; line-height: 1.2; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-right { align-items: flex-end; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-center { align-items: center; }\n.mgh-grid-aggregation-label { font-size: 0.65rem; font-weight: 500; text-transform: uppercase; color: var(--mgh-grid-fg-secondary); letter-spacing: .04em; }\n.mgh-grid-group-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }\n.mgh-grid-group-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.mgh-grid-group-count { color: var(--mgh-grid-fg-secondary); margin-left: 2px; }\n.mgh-grid-group-toggle { flex: 0 0 auto; }\n.mgh-grid-group-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-group-toggle--expanded .mgh-grid-icon { transform: rotate(90deg); }\n.mgh-grid-detail-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-detail-toggle--expanded .mgh-grid-icon { transform: rotate(180deg); }\n\n/* ---- pinned rows ---- */\n.mgh-grid-pinned-rows { position: sticky; z-index: 2; min-width: 100%; width: max-content; background: var(--mgh-grid-bg); }\n.mgh-grid-pinned-rows--top { box-shadow: 0 2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom { bottom: 0; box-shadow: 0 -2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom .mgh-grid-row { border-bottom: 0; border-top: 1px solid var(--mgh-grid-border); }\n\n/* ---- detail panel ---- */\n.mgh-grid-detail-panel { position: sticky; left: 0; overflow: auto; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); z-index: 1; }\n\n/* ---- overlays ---- */\n.mgh-grid-overlay { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; z-index: 5; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; pointer-events: none; }\n.mgh-grid-overlay--loading { background: var(--mgh-grid-overlay); pointer-events: auto; }\n.mgh-grid-no-rows { display: flex; align-items: center; justify-content: center; gap: 8px; height: 100%; text-align: center; padding: 16px; }\n.mgh-grid-no-rows img, .mgh-grid-no-rows .mgh-grid-icon { width: 50px; height: 50px; color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--mgh-grid-selected); border-top-color: var(--mgh-grid-primary); animation: mgh-grid-spin .8s linear infinite; }\n@keyframes mgh-grid-spin { to { transform: rotate(360deg); } }\n\n/* ---- footer ---- */\n.mgh-grid-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 0 8px 0 16px; border-top: 1px solid var(--mgh-grid-border); font-size: 0.875rem; color: var(--mgh-grid-fg-secondary); flex-wrap: wrap; }\n.mgh-grid-footer-left { display: flex; align-items: center; gap: 16px; }\n.mgh-grid-pagination { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }\n.mgh-grid-pagination-select { height: 32px; padding: 2px 24px 2px 8px; font-size: 0.875rem; border-color: transparent; }\n.mgh-grid-pagination-select:hover { border-color: transparent; background-color: var(--mgh-grid-hover); }\n.mgh-grid-pagination-actions { display: inline-flex; align-items: center; }\n\n/* ---- popover / menu / panels ---- */\n.mgh-grid-popover {\n --mgh-grid-font-family: inherit; --mgh-grid-font-size: 14px; --mgh-grid-paper: #ffffff; --mgh-grid-bg: #fff; --mgh-grid-fg: rgba(0,0,0,.87); --mgh-grid-fg-secondary: rgba(0,0,0,.6); --mgh-grid-fg-disabled: rgba(0,0,0,.38); --mgh-grid-border: rgba(224,224,224,1); --mgh-grid-hover: rgba(0,0,0,.04); --mgh-grid-selected: rgba(25,118,210,.08); --mgh-grid-primary: #1976d2; --mgh-grid-primary-contrast: #fff; --mgh-grid-focus: #1976d2; --mgh-grid-input-bg: transparent; --mgh-grid-input-border: rgba(0,0,0,.23); --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n position: fixed; z-index: 1300; background: var(--mgh-grid-paper); color: var(--mgh-grid-fg); border-radius: 8px; box-shadow: var(--mgh-grid-popover-shadow); font-family: var(--mgh-grid-font-family); font-size: var(--mgh-grid-font-size); line-height: 1.5; outline: none; max-height: calc(100vh - 16px); overflow: auto; animation: mgh-grid-pop .12s ease-out;\n}\n.mgh-grid-popover[data-mgh-theme=\"dark\"] { --mgh-grid-paper: #212b36; --mgh-grid-bg: #212b36; --mgh-grid-fg: #fff; --mgh-grid-fg-secondary: rgba(255,255,255,.7); --mgh-grid-fg-disabled: rgba(255,255,255,.5); --mgh-grid-border: rgba(81,81,81,1); --mgh-grid-hover: rgba(255,255,255,.08); --mgh-grid-selected: rgba(144,202,249,.16); --mgh-grid-primary: #90caf9; --mgh-grid-primary-contrast: rgba(0,0,0,.87); --mgh-grid-focus: #90caf9; --mgh-grid-input-border: rgba(255,255,255,.23); }\n@keyframes mgh-grid-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }\n.mgh-grid-menu { list-style: none; margin: 0; padding: 6px 0; min-width: 180px; }\n.mgh-grid-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 16px; min-height: 36px; font-size: 0.875rem; cursor: pointer; white-space: nowrap; color: var(--mgh-grid-fg); background: transparent; border: 0; width: 100%; text-align: left; font-family: inherit; outline: none; }\n.mgh-grid-menu-item:hover, .mgh-grid-menu-item:focus-visible { background: var(--mgh-grid-hover); }\n.mgh-grid-menu-item--disabled { color: var(--mgh-grid-fg-disabled); cursor: default; pointer-events: none; }\n.mgh-grid-menu-item--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-menu-item .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); flex: 0 0 auto; }\n.mgh-grid-menu-divider { height: 1px; margin: 6px 0; background: var(--mgh-grid-border); border: 0; }\n.mgh-grid-menu-header { padding: 6px 16px 2px; font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); text-transform: uppercase; letter-spacing: .04em; }\n.mgh-grid-menu-section { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 4px; }\n.mgh-grid-panel { display: flex; flex-direction: column; min-width: 300px; max-width: min(640px, calc(100vw - 16px)); }\n.mgh-grid-panel-header { padding: 12px 12px 4px; }\n.mgh-grid-panel-content { padding: 4px 12px; overflow: auto; max-height: 360px; }\n.mgh-grid-panel-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; }\n.mgh-grid-columns-list { display: flex; flex-direction: column; }\n.mgh-grid-filter-row { display: grid; grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); gap: 8px; align-items: end; margin-bottom: 8px; }\n.mgh-grid-filter-row--first { grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row--with-logic { grid-template-columns: 32px 80px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row .mgh-grid-btn--icon { margin-bottom: 4px; }\n.mgh-grid-filter-empty { padding: 8px 4px; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; }\n@media (max-width: 599.95px) { .mgh-grid-filter-row, .mgh-grid-filter-row--with-logic { grid-template-columns: 1fr; } }\n\n/* ---- misc ---- */\n.mgh-grid-tooltip-anchor { display: inline-flex; }\n.mgh-grid-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }\n@media print { .mgh-grid-toolbar, .mgh-grid-footer { display: none !important; } }\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_GRID_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_GRID_STYLE_ID;\n style.setAttribute('data-mgh-grid', 'true');\n style.textContent = MGH_GRID_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHGridStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridLocaleText,\n MGHGridState,\n MGHGridThemeMode,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\n\nexport interface MGHGridRootProps {\n header?: React.ReactNode;\n pagination: boolean;\n pageSizeOptions: number[];\n hideFooterPagination: boolean;\n hideFooterRowCount: boolean;\n hideFooterSelectedRowCount: boolean;\n disableColumnFilter: boolean;\n disableColumnSelector: boolean;\n disableDensitySelector: boolean;\n disableColumnPinning: boolean;\n disableColumnSorting: boolean;\n disableMultipleColumnsSorting: boolean;\n disableMultipleColumnsFiltering: boolean;\n disableRowGrouping: boolean;\n disableAggregation: boolean;\n checkboxSelection: boolean;\n aggregationFunctions: Record<string, MGHGridAggregationFunction>;\n quickFilterDebounceMs: number;\n}\n\nexport interface MGHGridContextValue {\n api: MGHGridApi;\n state: MGHGridState;\n localeText: MGHGridLocaleText;\n themeMode: MGHGridThemeMode;\n rootProps: MGHGridRootProps;\n /** All user columns (ordered, including hidden). */\n columns: MGHGridColDef[];\n /** Visible user columns. */\n visibleColumns: MGHGridColDef[];\n}\n\nexport const MGHGridContext = React.createContext<MGHGridContextValue | null>(null);\nMGHGridContext.displayName = 'MGHGridContext';\n\nexport const useMGHGridContext = () => {\n const ctx = React.useContext(MGHGridContext);\n if (!ctx) {\n throw new Error('MGHGrid: this component must be rendered inside an <MGHGrid /> (e.g. through a slot).');\n }\n return ctx;\n};\n\n/** Access the grid API from custom toolbars, menu items, cells, etc. */\nexport const useMGHGridApiContext = <R extends MGHGridValidRowModel = any>() => useMGHGridContext().api as MGHGridApi<R>;\n\nexport const useMGHGridLocaleText = () => useMGHGridContext().localeText;\n\n/** Creates a ref to hold the grid API; pass it to `<MGHGrid apiRef={apiRef} />`. */\nexport const useMGHGridApiRef = <R extends MGHGridValidRowModel = any>() =>\n React.useRef<MGHGridApi<R> | null>(null) as React.MutableRefObject<MGHGridApi<R> | null>;\n","import React from 'react';\n\n/** Keeps a ref always pointing at the latest value (assigned during render). */\nexport function useLatestRef<T>(value: T) {\n const ref = React.useRef(value);\n ref.current = value;\n return ref;\n}\n\n/** Returns a stable function that always calls the latest `fn`. */\nexport function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useLatestRef(fn);\n return React.useCallback(((...args: any[]) => ref.current(...args)) as T, []);\n}\n\n/**\n * Controlled / uncontrolled state helper. When `controlled` is defined the internal state is\n * ignored and every change is reported through `onChange` only.\n */\nexport function useControlledState<T>(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void\n): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : internal;\n const valueRef = useLatestRef(value);\n const controlledRef = useLatestRef(isControlled);\n const onChangeRef = useLatestRef(onChange);\n\n const setValue = React.useCallback((next: T | ((prev: T) => T)) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n if (Object.is(resolved, valueRef.current)) return;\n valueRef.current = resolved;\n if (!controlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [value, setValue];\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/** Observes the client size of an element. */\nexport function useElementSize<T extends HTMLElement>(ref: React.RefObject<T | null>, enabled = true): ElementSize {\n const [size, setSize] = React.useState<ElementSize>({ width: 0, height: 0 });\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !enabled) return undefined;\n const update = () => {\n const width = el.clientWidth;\n const height = el.clientHeight;\n setSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n };\n update();\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return size;\n}\n\n/** `window.matchMedia` as a hook. Always false on the server. */\nexport function useMediaQuery(query: string) {\n const getMatch = () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false;\n const [matches, setMatches] = React.useState(getMatch);\n\n React.useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return undefined;\n const media = window.matchMedia(query);\n const listener = () => setMatches(media.matches);\n listener();\n if (media.addEventListener) {\n media.addEventListener('change', listener);\n return () => media.removeEventListener('change', listener);\n }\n media.addListener(listener);\n return () => media.removeListener(listener);\n }, [query]);\n\n return matches;\n}\n\n/** Debounced version of a callback. The returned function is stable. */\nexport function useDebouncedCallback<T extends (...args: any[]) => void>(fn: T, delay: number) {\n const fnRef = useLatestRef(fn);\n const timerRef = React.useRef<number | null>(null);\n\n React.useEffect(\n () => () => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n },\n []\n );\n\n return React.useCallback(\n (...args: Parameters<T>) => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(() => {\n timerRef.current = null;\n fnRef.current(...args);\n }, delay);\n },\n [delay]\n );\n}\n\nexport function useForceUpdate() {\n const [, setTick] = React.useState(0);\n return React.useCallback(() => setTick((t) => t + 1), []);\n}\n\nlet idCounter = 0;\n/** Stable unique id per component instance (React.useId fallback for older Reacts). */\nexport function useStableId(prefix: string) {\n const reactUseId = (React as any).useId as undefined | (() => string);\n if (reactUseId) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const id = reactUseId();\n return `${prefix}-${id.replace(/:/g, '')}`;\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const ref = React.useRef<string | null>(null);\n if (ref.current === null) {\n idCounter += 1;\n ref.current = `${prefix}-${idCounter}`;\n }\n return ref.current;\n}\n","import {\n MGHGridApi,\n MGHGridColDef,\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridExportOptions,\n MGHGridPrintExportOptions,\n MGHGridRowId,\n} from './MGHGrid.types';\nimport {\n downloadBlob,\n formattedValueToString,\n getCellValue,\n getFormattedValue,\n isInternalField,\n isNil,\n toDate,\n} from './utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Shared: resolve the columns & rows to export\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ExportCell {\n raw: any;\n formatted: string;\n col: MGHGridColDef;\n}\n\nexport interface ExportTable {\n columns: MGHGridColDef[];\n headers: string[];\n rows: ExportCell[][];\n}\n\nexport const resolveExportColumns = (api: MGHGridApi, options: MGHGridExportOptions): MGHGridColDef[] => {\n const all = api.getAllColumns();\n let columns: MGHGridColDef[];\n if (options.fields) {\n const byField = new Map<string, MGHGridColDef>();\n all.forEach((c) => byField.set(c.field, c));\n columns = options.fields.map((f) => byField.get(f)).filter(Boolean) as MGHGridColDef[];\n } else if (options.allColumns) {\n columns = all;\n } else {\n columns = api.getVisibleColumns();\n }\n return columns.filter((c) => !c.disableExport && !isInternalField(c.field) && c.type !== 'actions');\n};\n\nexport const buildExportTable = (api: MGHGridApi, options: MGHGridExportOptions): ExportTable => {\n const columns = resolveExportColumns(api, options);\n const ids: MGHGridRowId[] = options.getRowsToExport ? options.getRowsToExport({ api }) : api.getSortedRowIds();\n const rows: ExportCell[][] = [];\n ids.forEach((id) => {\n const row = api.getRow(id);\n if (!row) return;\n rows.push(\n columns.map((col) => {\n const raw = getCellValue(row, col, api);\n const formatted = formattedValueToString(getFormattedValue(raw, row, col, api, id));\n return { raw, formatted, col };\n })\n );\n });\n return { columns, headers: columns.map((c) => c.headerName ?? c.field), rows };\n};\n\nconst sanitizeFileName = (name: string | undefined, fallback: string, extension: string) => {\n const base = (name && name.trim()) || fallback;\n return base.toLowerCase().endsWith(`.${extension}`) ? base : `${base}.${extension}`;\n};\n\nconst defaultFileBase = () => {\n const title = typeof document !== 'undefined' && document.title ? document.title.trim() : '';\n return (title || 'export').replace(/[\\\\/:*?\"<>|]+/g, '-');\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CSV\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeCsvCell = (value: string, delimiter: string) => {\n let text = value;\n // Guard against formula injection when opening in spreadsheet software.\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n if (text.indexOf('\"') !== -1 || text.indexOf(delimiter) !== -1 || /[\\r\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n }\n return text;\n};\n\nexport const getDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const delimiter = options.delimiter ?? ',';\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const lines: string[] = [];\n if (includeHeaders) {\n lines.push(table.headers.map((h) => escapeCsvCell(h, delimiter)).join(delimiter));\n }\n table.rows.forEach((cells) => {\n lines.push(\n cells\n .map((cell) => {\n const text = options.useRawValues ? (isNil(cell.raw) ? '' : String(cell.raw)) : cell.formatted;\n return escapeCsvCell(text, delimiter);\n })\n .join(delimiter)\n );\n });\n return lines.join('\\r\\n');\n};\n\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\nexport const exportDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const csv = getDataAsCsv(api, options);\n const bom = options.utf8WithBom ? UTF8_BOM : '';\n const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'csv'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * XLSX (minimal OOXML writer + store-only ZIP, no dependencies)\n * ----------------------------------------------------------------------------------------------- */\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n += 1) {\n let c = n;\n for (let k = 0; k < 8; k += 1) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nconst crc32 = (bytes: Uint8Array) => {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i += 1) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n};\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst encodeUtf8 = (text: string): Uint8Array => {\n if (textEncoder) return textEncoder.encode(text);\n // Fallback for very old environments.\n const utf8 = unescape(encodeURIComponent(text));\n const out = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i += 1) out[i] = utf8.charCodeAt(i);\n return out;\n};\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nconst concatBytes = (chunks: Uint8Array[]) => {\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n chunks.forEach((c) => {\n out.set(c, offset);\n offset += c.length;\n });\n return out;\n};\n\nconst zipStore = (entries: ZipEntry[]): Uint8Array => {\n const localChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n // 1980-01-01 00:00 in DOS date/time format.\n const dosTime = 0;\n const dosDate = (1 << 5) | 1;\n\n entries.forEach((entry) => {\n const nameBytes = encodeUtf8(entry.name);\n const crc = crc32(entry.data);\n const size = entry.data.length;\n\n const local = new Uint8Array(30 + nameBytes.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0x0800, true); // UTF-8 names\n lv.setUint16(8, 0, true); // store\n lv.setUint16(10, dosTime, true);\n lv.setUint16(12, dosDate, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, size, true);\n lv.setUint32(22, size, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0x0800, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, dosTime, true);\n cv.setUint16(14, dosDate, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, size, true);\n cv.setUint32(24, size, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, offset, true);\n central.set(nameBytes, 46);\n\n localChunks.push(local, entry.data);\n centralChunks.push(central);\n offset += local.length + size;\n });\n\n const centralDirectory = concatBytes(centralChunks);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDirectory.length, true);\n ev.setUint32(16, offset, true);\n ev.setUint16(20, 0, true);\n\n return concatBytes(localChunks.concat([centralDirectory, eocd]));\n};\n\n// Characters that are illegal in XML 1.0 (built without literal control characters in source).\nconst INVALID_XML_CHARS = new RegExp(\n '[' +\n String.fromCharCode(0x00) +\n '-' +\n String.fromCharCode(0x08) +\n String.fromCharCode(0x0b) +\n String.fromCharCode(0x0c) +\n String.fromCharCode(0x0e) +\n '-' +\n String.fromCharCode(0x1f) +\n String.fromCharCode(0xfffe) +\n String.fromCharCode(0xffff) +\n ']',\n 'g'\n);\nconst stripInvalidXml = (text: string) => text.replace(INVALID_XML_CHARS, '');\n\nconst escapeXml = (text: string) =>\n stripInvalidXml(text)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n\nconst columnLetter = (index: number) => {\n let n = index + 1;\n let letters = '';\n while (n > 0) {\n const rem = (n - 1) % 26;\n letters = String.fromCharCode(65 + rem) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return letters;\n};\n\nconst sanitizeSheetName = (name: string | undefined) => {\n const cleaned = (name || 'Sheet1').replace(/[\\[\\]:*?/\\\\]/g, ' ').trim() || 'Sheet1';\n return cleaned.length > 31 ? cleaned.slice(0, 31) : cleaned;\n};\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\nconst buildSheetXml = (table: ExportTable, includeHeaders: boolean, columnWidths: number[]) => {\n const rowsXml: string[] = [];\n let rowIndex = 1;\n\n const inlineString = (ref: string, text: string, style?: number) =>\n `<c r=\"${ref}\" t=\"inlineStr\"${style ? ` s=\"${style}\"` : ''}><is><t xml:space=\"preserve\">${escapeXml(\n text\n )}</t></is></c>`;\n\n if (includeHeaders) {\n const cells = table.headers.map((h, i) => inlineString(`${columnLetter(i)}${rowIndex}`, h, 1)).join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${cells}</row>`);\n rowIndex += 1;\n }\n\n table.rows.forEach((cells) => {\n const xmlCells = cells\n .map((cell, i) => {\n const ref = `${columnLetter(i)}${rowIndex}`;\n const type = cell.col.type;\n if (isNil(cell.raw) || cell.raw === '') return '';\n if (type === 'number' && typeof cell.raw === 'number' && Number.isFinite(cell.raw)) {\n return `<c r=\"${ref}\"><v>${cell.raw}</v></c>`;\n }\n if (type === 'boolean') {\n return `<c r=\"${ref}\" t=\"b\"><v>${cell.raw ? 1 : 0}</v></c>`;\n }\n if ((type === 'date' || type === 'dateTime') && toDate(cell.raw)) {\n // Excel serial date (days since 1899-12-30), written in local time with a date style.\n const d = toDate(cell.raw) as Date;\n const utc = Date.UTC(\n d.getFullYear(),\n d.getMonth(),\n d.getDate(),\n d.getHours(),\n d.getMinutes(),\n d.getSeconds()\n );\n const serial = utc / 86400000 + 25569;\n return `<c r=\"${ref}\" s=\"${type === 'dateTime' ? 3 : 2}\"><v>${serial}</v></c>`;\n }\n return inlineString(ref, cell.formatted);\n })\n .join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${xmlCells}</row>`);\n rowIndex += 1;\n });\n\n const lastCol = columnLetter(Math.max(table.columns.length - 1, 0));\n const lastRow = Math.max(rowIndex - 1, 1);\n const cols = columnWidths.map((w, i) => `<col min=\"${i + 1}\" max=\"${i + 1}\" width=\"${w}\" customWidth=\"1\"/>`).join('');\n\n return (\n XML_HEADER +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<dimension ref=\"A1:${lastCol}${lastRow}\"/>` +\n '<sheetViews><sheetView workbookViewId=\"0\">' +\n (includeHeaders ? '<pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/>' : '') +\n '</sheetView></sheetViews>' +\n '<sheetFormatPr defaultRowHeight=\"15\"/>' +\n (cols ? `<cols>${cols}</cols>` : '') +\n `<sheetData>${rowsXml.join('')}</sheetData>` +\n (includeHeaders && table.rows.length > 0 ? `<autoFilter ref=\"A1:${lastCol}${lastRow}\"/>` : '') +\n '</worksheet>'\n );\n};\n\nconst STYLES_XML =\n XML_HEADER +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"m/d/yyyy\"/><numFmt numFmtId=\"165\" formatCode=\"m/d/yyyy h:mm AM/PM\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '</cellXfs>' +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n '</styleSheet>';\n\nconst CONTENT_TYPES_XML =\n XML_HEADER +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n '</Types>';\n\nconst ROOT_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n '<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>' +\n '</Relationships>';\n\nconst WORKBOOK_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n '</Relationships>';\n\nconst buildWorkbookXml = (sheetName: string) =>\n XML_HEADER +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${escapeXml(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/></sheets>` +\n '</workbook>';\n\nconst buildCoreXml = () => {\n const now = new Date().toISOString();\n return (\n XML_HEADER +\n '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" ' +\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" ' +\n 'xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n '<dc:creator>MGH Grid</dc:creator>' +\n `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n '</cp:coreProperties>'\n );\n};\n\nconst APP_XML =\n XML_HEADER +\n '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" ' +\n 'xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n '<Application>MGH Grid</Application></Properties>';\n\nexport const buildXlsx = (api: MGHGridApi, options: MGHGridExcelExportOptions = {}): Uint8Array => {\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const widths = table.columns.map((col, i) => {\n const explicit = options.columnsStyles?.[col.field]?.width;\n if (explicit) return explicit;\n let max = table.headers[i].length;\n for (let r = 0; r < Math.min(table.rows.length, 500); r += 1) {\n const len = table.rows[r][i].formatted.length;\n if (len > max) max = len;\n }\n return Math.min(Math.max(max + 2, 8), 60);\n });\n const sheetName = sanitizeSheetName(options.sheetName);\n const entries: ZipEntry[] = [\n { name: '[Content_Types].xml', data: encodeUtf8(CONTENT_TYPES_XML) },\n { name: '_rels/.rels', data: encodeUtf8(ROOT_RELS_XML) },\n { name: 'docProps/core.xml', data: encodeUtf8(buildCoreXml()) },\n { name: 'docProps/app.xml', data: encodeUtf8(APP_XML) },\n { name: 'xl/workbook.xml', data: encodeUtf8(buildWorkbookXml(sheetName)) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(WORKBOOK_RELS_XML) },\n { name: 'xl/styles.xml', data: encodeUtf8(STYLES_XML) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(buildSheetXml(table, includeHeaders, widths)) },\n ];\n return zipStore(entries);\n};\n\nexport const exportDataAsExcel = async (api: MGHGridApi, options: MGHGridExcelExportOptions = {}) => {\n const bytes = buildXlsx(api, options);\n const blob = new Blob([bytes as BlobPart], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'xlsx'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Print\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Legacy value-based print (plain HTML table). The grid's `exportDataAsPrint` prints the live DOM instead. */\nexport const exportDataAsPrintTable = (api: MGHGridApi, options: MGHGridPrintExportOptions = {}) => {\n if (typeof document === 'undefined') return;\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const title = options.title ?? options.fileName ?? document.title ?? '';\n\n const headerHtml = includeHeaders\n ? `<thead><tr>${table.headers\n .map((h, i) => `<th class=\"${table.columns[i].align ?? 'left'}\">${escapeHtml(h)}</th>`)\n .join('')}</tr></thead>`\n : '';\n const bodyHtml = `<tbody>${table.rows\n .map(\n (cells) =>\n `<tr>${cells\n .map((cell) => `<td class=\"${cell.col.align ?? 'left'}\">${escapeHtml(cell.formatted)}</td>`)\n .join('')}</tr>`\n )\n .join('')}</tbody>`;\n\n const html =\n '<!doctype html><html><head><meta charset=\"utf-8\" />' +\n `<title>${escapeHtml(title)}</title>` +\n '<style>' +\n 'body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-size:12px;color:#111;margin:16px;}' +\n 'h1{font-size:16px;margin:0 0 12px;}' +\n 'table{border-collapse:collapse;width:100%;}' +\n 'th,td{border:1px solid #ccc;padding:4px 8px;text-align:left;vertical-align:top;}' +\n 'th{background:#f3f3f3;font-weight:600;}' +\n 'td.right,th.right{text-align:right;} td.center,th.center{text-align:center;}' +\n 'tr{page-break-inside:avoid;} thead{display:table-header-group;}' +\n (options.pageStyle ?? '') +\n '</style></head><body>' +\n (title ? `<h1>${escapeHtml(title)}</h1>` : '') +\n `<table>${headerHtml}${bodyHtml}</table>` +\n '</body></html>';\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = '0';\n iframe.style.opacity = '0';\n document.body.appendChild(iframe);\n\n const cleanup = () => {\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 1000);\n };\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (!win) {\n cleanup();\n return;\n }\n try {\n win.focus();\n win.onafterprint = cleanup;\n win.print();\n } catch {\n cleanup();\n }\n };\n\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\n if (doc) {\n doc.open();\n doc.write(html);\n doc.close();\n } else {\n iframe.srcdoc = html;\n }\n};\n","import { MGHGridPrintExportOptions } from './MGHGrid.types';\n\n/**\n * Prints the grid \"as seen on screen\": the live DOM of the grid card is cloned into a hidden iframe\n * together with the page's stylesheets, so anything rendered by `renderCell` (images, chips,\n * links, custom components) prints exactly as displayed. The grid itself must already be rendered\n * in print mode (all rows, no virtualization) when this is called.\n */\n\nconst PRINT_CSS = `\n@page { margin: 10mm; }\nhtml, body { margin: 0; padding: 0; background: #fff; }\n.mgh-grid-print-title { margin: 0 0 12px; font: 600 16px/1.4 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; }\n.mgh-grid-card { box-shadow: none !important; border-radius: 0 !important; height: auto !important; max-height: none !important; overflow: visible !important; background: transparent !important; }\n.mgh-grid-box { height: auto !important; max-height: none !important; flex: none !important; }\n.mgh-grid { height: auto !important; max-height: none !important; border-radius: 0 !important; }\n.mgh-grid-main, .mgh-grid-scroller { overflow: visible !important; height: auto !important; max-height: none !important; }\n.mgh-grid-columns, .mgh-grid-pinned-rows, .mgh-grid-detail-panel { position: static !important; box-shadow: none !important; }\n.mgh-grid-header-cell, .mgh-grid-cell { position: static !important; box-shadow: none !important; background-image: none !important; }\n.mgh-grid-detail-panel { width: auto !important; }\n.mgh-grid-body { min-height: 0 !important; }\n.mgh-grid-row, .mgh-grid-row-block, .mgh-grid-detail-panel { break-inside: avoid; page-break-inside: avoid; }\n.mgh-grid-columns { break-after: avoid; page-break-after: avoid; }\n.mgh-grid-header-menu-btn, .mgh-grid-resize-handle, .mgh-grid-overlay, .mgh-grid-sort-icon:not(.mgh-grid-sort-icon--active) { display: none !important; }\n.mgh-grid-popover { display: none !important; }\n`;\n\nconst collectStyles = (doc: Document) => {\n const styles: string[] = [];\n const links: string[] = [];\n Array.from(doc.styleSheets).forEach((sheet) => {\n try {\n const rules = Array.from(sheet.cssRules)\n .map((rule) => rule.cssText)\n .join('\\n');\n if (rules) styles.push(rules);\n } catch {\n // Cross-origin stylesheet: reference it instead of inlining.\n if (sheet.href) links.push(sheet.href);\n }\n });\n return { styles, links };\n};\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Copies live form-control state (cloneNode does not copy `checked` / `value`). */\nconst syncFormState = (source: HTMLElement, target: HTMLElement) => {\n const sourceInputs = Array.from(source.querySelectorAll('input, select, textarea'));\n const targetInputs = Array.from(target.querySelectorAll('input, select, textarea'));\n sourceInputs.forEach((el, i) => {\n const t = targetInputs[i];\n if (!t || t.tagName !== el.tagName) return;\n // Tag-name checks instead of `instanceof`: the elements may belong to different documents.\n if (el.tagName === 'INPUT') {\n const src = el as HTMLInputElement;\n const dst = t as HTMLInputElement;\n if (src.type === 'checkbox' || src.type === 'radio') {\n dst.checked = src.checked;\n if (src.checked) dst.setAttribute('checked', '');\n dst.indeterminate = src.indeterminate;\n } else {\n dst.value = src.value;\n dst.setAttribute('value', src.value);\n }\n } else if (el.tagName === 'SELECT') {\n (t as HTMLSelectElement).value = (el as HTMLSelectElement).value;\n } else if (el.tagName === 'TEXTAREA') {\n (t as HTMLTextAreaElement).value = (el as HTMLTextAreaElement).value;\n t.textContent = (el as HTMLTextAreaElement).value;\n }\n });\n // Canvases lose their bitmap when cloned: replace them with images.\n const sourceCanvases = Array.from(source.querySelectorAll('canvas'));\n const targetCanvases = Array.from(target.querySelectorAll('canvas'));\n sourceCanvases.forEach((canvas, i) => {\n const t = targetCanvases[i];\n if (!t) return;\n try {\n const img = t.ownerDocument.createElement('img');\n img.src = canvas.toDataURL();\n img.width = canvas.width;\n img.height = canvas.height;\n img.style.cssText = t.style.cssText;\n t.replaceWith(img);\n } catch {\n /* tainted canvas – leave as is */\n }\n });\n};\n\nconst waitForImages = (doc: Document, timeoutMs: number) =>\n new Promise<void>((resolve) => {\n const images = Array.from(doc.images).filter((img) => !img.complete);\n if (images.length === 0) {\n resolve();\n return;\n }\n let remaining = images.length;\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n resolve();\n };\n const timer = window.setTimeout(finish, timeoutMs);\n images.forEach((img) => {\n const onSettled = () => {\n remaining -= 1;\n if (remaining <= 0) {\n window.clearTimeout(timer);\n finish();\n }\n };\n img.addEventListener('load', onSettled, { once: true });\n img.addEventListener('error', onSettled, { once: true });\n });\n });\n\nexport interface PrintGridParams {\n /** The `.mgh-grid-card` element (already rendered in print mode). */\n cardElement: HTMLElement;\n options: MGHGridPrintExportOptions;\n /** Called once the print dialog has been handed off (or failed) so the grid can leave print mode. */\n onDone: () => void;\n}\n\nexport const printGridElement = (params: PrintGridParams) => {\n let done = false;\n const onDone = () => {\n if (done) return;\n done = true;\n params.onDone();\n };\n try {\n printGridElementUnsafe({ ...params, onDone });\n } catch (error) {\n console.error('MGHGrid: print failed', error);\n onDone();\n }\n};\n\nconst printGridElementUnsafe = ({ cardElement, options, onDone }: PrintGridParams) => {\n if (typeof document === 'undefined') {\n onDone();\n return;\n }\n const hideToolbar = options.hideToolbar ?? true;\n const hideFooter = options.hideFooter ?? false;\n const includeHeaders = options.includeHeaders ?? true;\n const copyStyles = options.copyStyles ?? true;\n\n const clone = cardElement.cloneNode(true) as HTMLElement;\n syncFormState(cardElement, clone);\n clone.querySelectorAll('.mgh-grid-card-header').forEach((el) => el.remove());\n if (hideToolbar) clone.querySelectorAll('.mgh-grid-toolbar').forEach((el) => el.remove());\n if (hideFooter) clone.querySelectorAll('.mgh-grid-footer').forEach((el) => el.remove());\n if (!includeHeaders) clone.querySelectorAll('.mgh-grid-columns').forEach((el) => el.remove());\n clone.classList.add('mgh-grid-card--plain');\n // Remove ids to avoid duplicates and drop inline sizing coming from cardStyle/boxStyle.\n clone.querySelectorAll('[id]').forEach((el) => el.removeAttribute('id'));\n clone.style.height = 'auto';\n clone.style.flexGrow = '0';\n\n const title = options.title ?? '';\n const { styles, links } = copyStyles ? collectStyles(document) : { styles: [], links: [] };\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.setAttribute('data-mgh-grid-print', 'true');\n iframe.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:0;opacity:0;pointer-events:none;';\n document.body.appendChild(iframe);\n\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 500);\n onDone();\n };\n\n const win = iframe.contentWindow;\n const doc = iframe.contentDocument || win?.document;\n if (!win || !doc) {\n finish();\n return;\n }\n\n doc.open();\n doc.write(\n `<!doctype html><html><head><meta charset=\"utf-8\" /><title>${escapeHtml(title || document.title || 'Print')}</title>` +\n links.map((href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`).join('') +\n `</head><body></body></html>`\n );\n doc.close();\n\n styles.forEach((css) => {\n const style = doc.createElement('style');\n style.textContent = css;\n doc.head.appendChild(style);\n });\n const printStyle = doc.createElement('style');\n printStyle.textContent = PRINT_CSS + (options.pageStyle ?? '');\n doc.head.appendChild(printStyle);\n\n if (title) {\n const h1 = doc.createElement('h1');\n h1.className = 'mgh-grid-print-title';\n h1.textContent = title;\n doc.body.appendChild(h1);\n }\n doc.body.appendChild(doc.adoptNode(clone));\n\n const run = async () => {\n try {\n await waitForImages(doc, 4000);\n if (options.onBeforePrint) await options.onBeforePrint(doc);\n win.onafterprint = finish;\n win.focus();\n win.print();\n // Most browsers block on print(); if afterprint never fires, still restore the grid.\n window.setTimeout(finish, 1000);\n } catch {\n finish();\n }\n };\n void run();\n};\n","import {\n MGHGridAggregationFunction,\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridColDef,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridRowId,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport { formattedValueToString, getCellValue, getFormattedValue, getGroupingValue, isNil } from './utils';\n\nexport interface RowEntry<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n row: R;\n}\n\n/** Internal tree node used while grouping. */\nexport interface GroupTreeNode<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n depth: number;\n parent: MGHGridRowId | null;\n groupingField: string;\n groupingKey: any;\n groupingLabel: string;\n childGroups: GroupTreeNode<R>[];\n /** Direct leaf children (only populated at the deepest level). */\n leaves: RowEntry<R>[];\n /** Every descendant leaf, in display order after sorting. */\n descendants: RowEntry<R>[];\n}\n\nexport interface DisplayRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n type: 'leaf' | 'group';\n row: R | null;\n node: MGHGridLeafNode | MGHGridGroupNode;\n depth: number;\n group?: GroupTreeNode<R>;\n}\n\nexport const GROUP_ID_PREFIX = 'auto-generated-row-';\n\nconst keyToString = (key: any) => (isNil(key) ? '' : key instanceof Date ? String(key.getTime()) : String(key));\n\nexport const buildGroupTree = <R extends MGHGridValidRowModel>(\n entries: RowEntry<R>[],\n groupingFields: string[],\n columnsByField: Map<string, MGHGridColDef<R>>,\n api: MGHGridApi<R>,\n emptyLabel = '(empty)'\n): GroupTreeNode<R>[] => {\n const build = (items: RowEntry<R>[], depth: number, parentId: MGHGridRowId | null, path: string): GroupTreeNode<R>[] => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return [];\n const buckets = new Map<string, GroupTreeNode<R>>();\n items.forEach((entry) => {\n const key = getGroupingValue(entry.row, col, api);\n const keyStr = keyToString(key);\n let node = buckets.get(keyStr);\n if (!node) {\n const label = formattedValueToString(getFormattedValue(key, entry.row, col, api, entry.id)) || emptyLabel;\n const id = `${GROUP_ID_PREFIX}${path}${field}/${keyStr}`;\n node = {\n id,\n depth,\n parent: parentId,\n groupingField: field,\n groupingKey: key,\n groupingLabel: label,\n childGroups: [],\n leaves: [],\n descendants: [],\n };\n buckets.set(keyStr, node);\n }\n node.leaves.push(entry);\n });\n const nodes: GroupTreeNode<R>[] = [];\n buckets.forEach((node) => {\n if (depth < groupingFields.length - 1) {\n node.childGroups = build(\n node.leaves,\n depth + 1,\n node.id,\n `${path}${field}/${keyToString(node.groupingKey)}|`\n );\n node.descendants = node.leaves;\n node.leaves = [];\n } else {\n node.descendants = node.leaves;\n }\n nodes.push(node);\n });\n return nodes;\n };\n return build(entries, 0, null, '');\n};\n\nexport type GroupComparator<R extends MGHGridValidRowModel = any> = (a: GroupTreeNode<R>, b: GroupTreeNode<R>) => number;\n\n/** Sorts groups (with the given comparator) and leaves (with the given sorter), recursively. */\nexport const sortGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n compareGroups: ((depth: number) => GroupComparator<R> | null) | null,\n sortLeaves: (leaves: RowEntry<R>[]) => RowEntry<R>[]\n): GroupTreeNode<R>[] => {\n const sortLevel = (nodes: GroupTreeNode<R>[], depth: number): GroupTreeNode<R>[] => {\n const comparator = compareGroups ? compareGroups(depth) : null;\n const sorted = comparator\n ? nodes\n .map((node, index) => ({ node, index }))\n .sort((a, b) => comparator(a.node, b.node) || a.index - b.index)\n .map((item) => item.node)\n : nodes;\n sorted.forEach((node) => {\n if (node.childGroups.length > 0) {\n node.childGroups = sortLevel(node.childGroups, depth + 1);\n const descendants: RowEntry<R>[] = [];\n node.childGroups.forEach((child) => child.descendants.forEach((d) => descendants.push(d)));\n node.descendants = descendants;\n } else {\n node.leaves = sortLeaves(node.leaves);\n node.descendants = node.leaves;\n }\n });\n return sorted;\n };\n return sortLevel(roots, 0);\n};\n\nexport const collectTreeLeaves = <R extends MGHGridValidRowModel>(roots: GroupTreeNode<R>[]): RowEntry<R>[] => {\n const out: RowEntry<R>[] = [];\n roots.forEach((root) => root.descendants.forEach((d) => out.push(d)));\n return out;\n};\n\nexport const toGroupNode = <R extends MGHGridValidRowModel>(\n node: GroupTreeNode<R>,\n isExpanded: boolean\n): MGHGridGroupNode => ({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: node.childGroups.length > 0 ? node.childGroups.map((c) => c.id) : node.leaves.map((l) => l.id),\n leafIds: node.descendants.map((d) => d.id),\n isExpanded,\n});\n\n/** Flattens the tree into display rows, honouring expansion state. Also fills `nodesById` with every node. */\nexport const flattenGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n isExpanded: (node: GroupTreeNode<R>) => boolean,\n nodesById: Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>,\n groupsById: Map<MGHGridRowId, GroupTreeNode<R>>\n): DisplayRow<R>[] => {\n const out: DisplayRow<R>[] = [];\n const visit = (nodes: GroupTreeNode<R>[], visible: boolean) => {\n nodes.forEach((node) => {\n const expanded = isExpanded(node);\n const groupNode = toGroupNode(node, expanded);\n nodesById.set(node.id, groupNode);\n groupsById.set(node.id, node);\n if (visible)\n out.push({ id: node.id, type: 'group', row: null, node: groupNode, depth: node.depth, group: node });\n const childVisible = visible && expanded;\n if (node.childGroups.length > 0) {\n visit(node.childGroups, childVisible);\n } else {\n node.leaves.forEach((leaf) => {\n const leafNode: MGHGridLeafNode = { type: 'leaf', id: leaf.id, depth: node.depth + 1, parent: node.id };\n nodesById.set(leaf.id, leafNode);\n if (childVisible)\n out.push({ id: leaf.id, type: 'leaf', row: leaf.row, node: leafNode, depth: node.depth + 1 });\n });\n }\n });\n };\n visit(roots, true);\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const aggregateRows = <R extends MGHGridValidRowModel>(\n rows: R[],\n aggregationModel: MGHGridAggregationModel,\n columnsByField: Map<string, MGHGridColDef<R>>,\n functions: Record<string, MGHGridAggregationFunction>,\n api: MGHGridApi<R>\n): Record<string, { value: any; fn: string }> => {\n const result: Record<string, { value: any; fn: string }> = {};\n Object.keys(aggregationModel).forEach((field) => {\n const fnName = aggregationModel[field];\n const fn = functions[fnName];\n const col = columnsByField.get(field);\n if (!fn || !col || col.aggregable === false) return;\n const values = rows.map((row) => getCellValue(row, col, api));\n result[field] = { value: fn.apply({ values, field }), fn: fnName };\n });\n return result;\n};\n","import React from 'react';\n\n/* Small inline SVG icon set (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHGridIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHGridIconProps>(({ size = 20, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-grid-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const ViewColumnIcon = createIcon(\n <path d=\"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z\" />,\n 'ViewColumnIcon'\n);\nexport const FilterListIcon = createIcon(<path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" />, 'FilterListIcon');\nexport const SearchIcon = createIcon(\n <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />,\n 'SearchIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\nexport const DownloadIcon = createIcon(\n <path d=\"M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67 2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z\" />,\n 'DownloadIcon'\n);\nexport const ArrowUpwardIcon = createIcon(\n <path d=\"m4 12 1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />,\n 'ArrowUpwardIcon'\n);\nexport const ArrowDownwardIcon = createIcon(\n <path d=\"m20 12-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" />,\n 'ArrowDownwardIcon'\n);\nexport const MoreVertIcon = createIcon(\n <path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'MoreVertIcon'\n);\nexport const CheckIcon = createIcon(<path d=\"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />, 'CheckIcon');\nexport const ExpandMoreIcon = createIcon(<path d=\"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z\" />, 'ExpandMoreIcon');\nexport const ChevronRightIcon = createIcon(<path d=\"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />, 'ChevronRightIcon');\nexport const ChevronLeftIcon = createIcon(<path d=\"M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />, 'ChevronLeftIcon');\nexport const FirstPageIcon = createIcon(\n <path d=\"M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z\" />,\n 'FirstPageIcon'\n);\nexport const LastPageIcon = createIcon(\n <path d=\"M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z\" />,\n 'LastPageIcon'\n);\nexport const PushPinIcon = createIcon(\n <path d=\"M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z\" />,\n 'PushPinIcon'\n);\nexport const DeleteIcon = createIcon(\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />,\n 'DeleteIcon'\n);\nexport const AddIcon = createIcon(<path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />, 'AddIcon');\nexport const DensitySmallIcon = createIcon(\n <path d=\"M3 2h18v2H3zm0 18h18v2H3zm0-6h18v2H3zm0-6h18v2H3z\" />,\n 'DensitySmallIcon'\n);\nexport const DensityMediumIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3zm0-8h18v2H3z\" />, 'DensityMediumIcon');\nexport const DensityLargeIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3z\" />, 'DensityLargeIcon');\nexport const DragIndicatorIcon = createIcon(\n <path d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'DragIndicatorIcon'\n);\nexport const PrintIcon = createIcon(\n <path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" />,\n 'PrintIcon'\n);\nexport const TableChartIcon = createIcon(\n <path d=\"M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z\" />,\n 'TableChartIcon'\n);\nexport const DescriptionIcon = createIcon(\n <path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" />,\n 'DescriptionIcon'\n);\nexport const VisibilityOffIcon = createIcon(\n <path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" />,\n 'VisibilityOffIcon'\n);\nexport const FunctionsIcon = createIcon(<path d=\"M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z\" />, 'FunctionsIcon');\nexport const WorkspacesIcon = createIcon(\n <path d=\"M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z\" />,\n 'WorkspacesIcon'\n);\nexport const EmptyBoxIcon = createIcon(\n <>\n <path\n d=\"M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2z\"\n opacity=\".25\"\n />\n <path d=\"M4 8h16v11H4z\" opacity=\".15\" />\n </>,\n 'EmptyBoxIcon'\n);\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { clamp, cx } from '../utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Button / IconButton\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'text' | 'primary' | 'contained';\n size?: 'small' | 'medium';\n startIcon?: React.ReactNode;\n endIcon?: React.ReactNode;\n active?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = 'text', size = 'medium', startIcon, endIcon, active, className, children, type = 'button', ...rest },\n ref\n ) => (\n <button\n ref={ref}\n type={type}\n className={cx(\n 'mgh-grid-btn',\n variant === 'primary' && 'mgh-grid-btn--primary',\n variant === 'contained' && 'mgh-grid-btn--contained',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {startIcon}\n {children}\n {endIcon}\n </button>\n )\n);\nButton.displayName = 'MGHGridButton';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n size?: 'small' | 'medium';\n active?: boolean;\n /** Tooltip (native title) and aria-label. */\n label?: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ size = 'medium', active, label, className, children, type = 'button', ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n title={label}\n aria-label={label}\n className={cx(\n 'mgh-grid-btn mgh-grid-btn--icon',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n )\n);\nIconButton.displayName = 'MGHGridIconButton';\n\n/* -------------------------------------------------------------------------------------------------\n * Badge\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface BadgeProps {\n count?: number;\n variant?: 'dot' | 'count';\n children: React.ReactNode;\n}\n\nexport const Badge = ({ count = 0, variant = 'dot', children }: BadgeProps) => (\n <span className=\"mgh-grid-badge\">\n {children}\n {count > 0 &&\n (variant === 'dot' ? (\n <span className=\"mgh-grid-badge-dot\" />\n ) : (\n <span className=\"mgh-grid-badge-count\">{count > 99 ? '99+' : count}</span>\n ))}\n </span>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Inputs\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(\n ({ size = 'medium', className, ...rest }, ref) => (\n <input\n ref={ref}\n className={cx('mgh-grid-input', size === 'small' && 'mgh-grid-input--small', className)}\n {...rest}\n />\n )\n);\nTextInput.displayName = 'MGHGridTextInput';\n\nexport interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ size = 'medium', className, ...rest }, ref) => (\n <select ref={ref} className={cx('mgh-grid-select', size === 'small' && 'mgh-grid-select--small', className)} {...rest} />\n));\nSelect.displayName = 'MGHGridSelect';\n\nexport interface FieldProps {\n label?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n htmlFor?: string;\n}\n\nexport const Field = ({ label, children, className, htmlFor }: FieldProps) => (\n <div className={cx('mgh-grid-field', className)}>\n {label && (\n <label className=\"mgh-grid-field-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n </div>\n);\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n indeterminate?: boolean;\n label?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ indeterminate = false, label, className, ...rest }, forwardedRef) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const setRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [forwardedRef]\n );\n React.useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n return (\n <input\n ref={setRef}\n type=\"checkbox\"\n title={label}\n aria-label={label}\n className={cx('mgh-grid-checkbox', className)}\n {...rest}\n />\n );\n }\n);\nCheckbox.displayName = 'MGHGridCheckbox';\n\n/* -------------------------------------------------------------------------------------------------\n * Spinner\n * ----------------------------------------------------------------------------------------------- */\n\nexport const Spinner = ({ className }: { className?: string }) => (\n <div className={cx('mgh-grid-spinner', className)} role=\"progressbar\" aria-label=\"Loading\" />\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover (portal, anchored)\n * ----------------------------------------------------------------------------------------------- */\n\nexport type PopoverPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'right-start';\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null | undefined;\n onClose: (reason: 'backdrop' | 'escape') => void;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n themeMode?: MGHGridThemeMode;\n className?: string;\n style?: React.CSSProperties;\n offset?: number;\n role?: string;\n autoFocus?: boolean;\n /** Additional elements considered \"inside\" for outside-click detection. */\n ignoreOutsideClickOn?: Array<React.RefObject<HTMLElement | null>>;\n}\n\nexport function Popover({\n open,\n anchorEl,\n onClose,\n children,\n placement = 'bottom-start',\n themeMode = 'light',\n className,\n style,\n offset = 4,\n role = 'dialog',\n autoFocus = false,\n ignoreOutsideClickOn,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState<{ top: number; left: number; ready: boolean }>({\n top: 0,\n left: 0,\n ready: false,\n });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n if (placement === 'right-start') {\n top = a.top;\n left = a.right + offset;\n if (left + w > vw - 8) left = a.left - offset - w;\n } else {\n top = a.bottom + offset;\n if (top + h > vh - 8 && a.top - offset - h >= 8) top = a.top - offset - h;\n left =\n placement === 'bottom-end'\n ? a.right - w\n : placement === 'bottom'\n ? a.left + a.width / 2 - w / 2\n : a.left;\n }\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement, offset]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n if (ignoreOutsideClickOn?.some((r) => r.current?.contains(target))) return;\n // Clicks inside other popovers (nested menus) should not close this one.\n if ((target as HTMLElement).closest?.('.mgh-grid-popover')) return;\n onClose('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onClose, anchorEl, ignoreOutsideClickOn]);\n\n React.useEffect(() => {\n if (open && autoFocus && ref.current) {\n const focusable = ref.current.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])'\n );\n (focusable ?? ref.current).focus();\n }\n }, [open, autoFocus]);\n\n if (!open || typeof document === 'undefined') return null;\n\n const stop = (event: React.SyntheticEvent) => event.stopPropagation();\n\n return createPortal(\n <div\n ref={ref}\n role={role}\n tabIndex={-1}\n className={cx('mgh-grid-popover', className)}\n data-mgh-theme={themeMode}\n style={{\n top: position.top,\n left: position.left,\n visibility: position.ready ? 'visible' : 'hidden',\n ...style,\n }}\n onClick={stop}\n onDoubleClick={stop}\n onMouseDown={stop}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onClose('escape');\n return;\n }\n event.stopPropagation();\n }}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {\n children: React.ReactNode;\n}\n\nexport const Menu = ({ children, className, onKeyDown, ...rest }: MenuProps) => {\n const ref = React.useRef<HTMLUListElement | null>(null);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Home' && event.key !== 'End') return;\n const items = Array.from(\n ref.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])') ?? []\n );\n if (items.length === 0) return;\n event.preventDefault();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n let next = 0;\n if (event.key === 'ArrowDown') next = currentIndex < 0 ? 0 : (currentIndex + 1) % items.length;\n else if (event.key === 'ArrowUp')\n next = currentIndex < 0 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;\n else if (event.key === 'Home') next = 0;\n else next = items.length - 1;\n items[next].focus();\n };\n\n React.useEffect(() => {\n const first = ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])');\n first?.focus();\n }, []);\n\n return (\n <ul ref={ref} role=\"menu\" className={cx('mgh-grid-menu', className)} onKeyDown={handleKeyDown} {...rest}>\n {children}\n </ul>\n );\n};\n\nexport interface MenuItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n icon?: React.ReactNode;\n selected?: boolean;\n /** Injected by menus that should close after the click. */\n hideMenu?: () => void;\n}\n\nexport const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ icon, selected, disabled, className, children, onClick, hideMenu, ...rest }, ref) => (\n <li role=\"none\">\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n disabled={disabled}\n tabIndex={-1}\n className={cx(\n 'mgh-grid-menu-item',\n disabled && 'mgh-grid-menu-item--disabled',\n selected && 'mgh-grid-menu-item--selected',\n className\n )}\n onClick={(event) => {\n if (disabled) return;\n onClick?.(event);\n hideMenu?.();\n }}\n {...rest}\n >\n {icon}\n <span>{children}</span>\n </button>\n </li>\n )\n);\nMenuItem.displayName = 'MGHGridMenuItem';\n\nexport const MenuDivider = () => <li role=\"separator\" className=\"mgh-grid-menu-divider\" />;\n\nexport const MenuHeader = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-header\">\n {children}\n </li>\n);\n\nexport const MenuSection = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-section\">\n {children}\n </li>\n);\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport {\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridPrintExportOptions,\n MGHGridToolbarProps,\n} from '../MGHGrid.types';\nimport {\n CloseIcon,\n DensityLargeIcon,\n DensityMediumIcon,\n DensitySmallIcon,\n DescriptionIcon,\n DownloadIcon,\n FilterListIcon,\n PrintIcon,\n SearchIcon,\n TableChartIcon,\n ViewColumnIcon,\n} from '../icons';\nimport { cx } from '../utils';\nimport { Badge, IconButton, Menu, MenuItem, MenuItemProps, Popover, TextInput } from './primitives';\n\n/* -------------------------------------------------------------------------------------------------\n * Buttons\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridColumnsButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'columns';\n return (\n <IconButton\n label={localeText.toolbarColumns}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('columns', event.currentTarget))}\n >\n <ViewColumnIcon />\n </IconButton>\n );\n}\n\nexport function MGHGridFiltersButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'filters';\n return (\n <IconButton\n label={localeText.toolbarFilters}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('filters', event.currentTarget))}\n >\n <Badge count={state.filterCount} variant=\"dot\">\n <FilterListIcon />\n </Badge>\n </IconButton>\n );\n}\n\nexport function MGHGridDensitySelector() {\n const { api, state, localeText, themeMode } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const options = [\n { value: 'compact', label: localeText.densityCompact, icon: <DensitySmallIcon /> },\n { value: 'standard', label: localeText.densityStandard, icon: <DensityMediumIcon /> },\n { value: 'comfortable', label: localeText.densityComfortable, icon: <DensityLargeIcon /> },\n ] as const;\n const current = options.find((o) => o.value === state.density) ?? options[1];\n return (\n <>\n <IconButton\n label={localeText.toolbarDensity}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n {current.icon}\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n role=\"menu\"\n >\n <Menu>\n {options.map((option) => (\n <MenuItem\n key={option.value}\n icon={option.icon}\n selected={option.value === state.density}\n onClick={() => api.setDensity(option.value)}\n hideMenu={() => setAnchor(null)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Export menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridExportMenuItemProps extends MenuItemProps {\n /** Injected by MGHGridExportMenu; call it to close the menu after your action. */\n hideMenu?: () => void;\n}\n\n/** Menu item for custom export actions. Drop-in for MUI's GridExportMenuItemProps pattern. */\nexport const MGHGridExportMenuItem = MenuItem as React.ForwardRefExoticComponent<\n MGHGridExportMenuItemProps & React.RefAttributes<HTMLButtonElement>\n>;\n\nexport interface MGHGridExportMenuProps {\n csvOptions?: MGHGridCsvExportOptions;\n excelOptions?: MGHGridExcelExportOptions;\n printOptions?: MGHGridPrintExportOptions;\n showCsvOption?: boolean;\n showExcelOption?: boolean;\n showPrintOption?: boolean;\n customMenuItem?: React.ReactNode;\n}\n\nexport function MGHGridExportMenu({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n customMenuItem,\n}: MGHGridExportMenuProps) {\n const { api, localeText, themeMode, rootProps } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const hideMenu = () => setAnchor(null);\n\n const customItems = React.Children.map(customMenuItem, (child) =>\n React.isValidElement(child) ? React.cloneElement(child as React.ReactElement<any>, { hideMenu }) : child\n );\n\n const resolvedPrintOptions: MGHGridPrintExportOptions = {\n title: typeof rootProps.header === 'string' ? rootProps.header : undefined,\n ...printOptions,\n };\n\n return (\n <>\n <IconButton\n label={localeText.toolbarExport}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n <DownloadIcon />\n </IconButton>\n <Popover open={Boolean(anchor)} anchorEl={anchor} onClose={hideMenu} themeMode={themeMode} role=\"menu\">\n <Menu>\n {customItems}\n {showCsvOption && (\n <MenuItem\n icon={<DescriptionIcon />}\n onClick={() => api.exportDataAsCsv(csvOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportCSV}\n </MenuItem>\n )}\n {showExcelOption && (\n <MenuItem\n icon={<TableChartIcon />}\n onClick={() => {\n void api.exportDataAsExcel(excelOptions);\n }}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportExcel}\n </MenuItem>\n )}\n {showPrintOption && (\n <MenuItem\n icon={<PrintIcon />}\n onClick={() => api.exportDataAsPrint(resolvedPrintOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportPrint}\n </MenuItem>\n )}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Quick filter\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridQuickFilterProps {\n placeholder?: string;\n debounceMs?: number;\n /** Always show the expanded input. */\n alwaysExpanded?: boolean;\n}\n\nexport function MGHGridQuickFilter({ placeholder, debounceMs, alwaysExpanded = false }: MGHGridQuickFilterProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const externalValue = (state.quickFilterValues ?? []).join(' ');\n const [text, setText] = React.useState(externalValue);\n const [expanded, setExpanded] = React.useState(alwaysExpanded || externalValue !== '');\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const timer = React.useRef<number | null>(null);\n const delay = debounceMs ?? rootProps.quickFilterDebounceMs;\n\n // Sync when the model is changed from outside (e.g. api.setQuickFilterValues).\n const lastExternal = React.useRef(externalValue);\n React.useEffect(() => {\n if (externalValue !== lastExternal.current) {\n lastExternal.current = externalValue;\n setText(externalValue);\n if (externalValue !== '') setExpanded(true);\n }\n }, [externalValue]);\n\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n\n const commit = (value: string) => {\n const values = value.split(/\\s+/).filter((v) => v !== '');\n lastExternal.current = values.join(' ');\n api.setQuickFilterValues(values);\n };\n\n const handleChange = (value: string) => {\n setText(value);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => commit(value), delay);\n };\n\n const clear = () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n setText('');\n commit('');\n inputRef.current?.focus();\n };\n\n const expand = () => {\n setExpanded(true);\n window.setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const isExpanded = alwaysExpanded || expanded;\n\n return (\n <div className={cx('mgh-grid-quick-filter', isExpanded && 'mgh-grid-quick-filter--expanded')}>\n <IconButton\n className=\"mgh-grid-quick-filter-trigger\"\n label={localeText.toolbarQuickFilterLabel}\n aria-disabled={isExpanded}\n tabIndex={isExpanded ? -1 : 0}\n onClick={expand}\n >\n <SearchIcon />\n </IconButton>\n <div\n className={cx(\n 'mgh-grid-quick-filter-control mgh-grid-input-adorned',\n text && 'mgh-grid-input-adorned--clearable'\n )}\n >\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n ref={inputRef}\n size=\"small\"\n type=\"search\"\n value={text}\n tabIndex={isExpanded ? 0 : -1}\n placeholder={placeholder ?? localeText.toolbarQuickFilterPlaceholder}\n aria-label={localeText.toolbarQuickFilterLabel}\n onChange={(event) => handleChange(event.target.value)}\n onBlur={() => {\n if (!alwaysExpanded && text.trim() === '') setExpanded(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n if (text) clear();\n else if (!alwaysExpanded) {\n setExpanded(false);\n inputRef.current?.blur();\n }\n }\n if (event.key === 'Enter') {\n if (timer.current !== null) window.clearTimeout(timer.current);\n commit(text);\n }\n }}\n />\n {text && (\n <span className=\"mgh-grid-input-adornment mgh-grid-input-adornment--end\">\n <IconButton size=\"small\" label={localeText.clearSearch} onClick={clear} tabIndex={-1}>\n <CloseIcon />\n </IconButton>\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Default toolbar\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n showDensitySelector = false,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n csvOptions,\n excelOptions,\n printOptions,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n quickFilterPlaceholder,\n quickFilterDebounceMs,\n}: MGHGridToolbarProps) {\n const { rootProps } = useMGHGridContext();\n const showColumns = showColumnsButton && !rootProps.disableColumnSelector;\n const showFilters = showFilterButton && !rootProps.disableColumnFilter;\n const showDensity = showDensitySelector && !rootProps.disableDensitySelector;\n\n return (\n <div className=\"mgh-grid-toolbar\" role=\"toolbar\">\n <div className=\"mgh-grid-toolbar-group\">\n {showColumns && <MGHGridColumnsButton />}\n {showFilters && <MGHGridFiltersButton />}\n {showDensity && <MGHGridDensitySelector />}\n {showExportButton && (\n <MGHGridExportMenu\n csvOptions={csvOptions}\n excelOptions={excelOptions}\n printOptions={printOptions}\n showCsvOption={showCsvOption}\n showExcelOption={showExcelOption}\n showPrintOption={showPrintOption}\n customMenuItem={customMenuItem}\n />\n )}\n </div>\n {renderDateRange && <div className=\"mgh-grid-toolbar-center\">{renderDateRange}</div>}\n <div className=\"mgh-grid-toolbar-group\">\n {renderOtherButtons}\n {showQuickFilter && (\n <MGHGridQuickFilter placeholder={quickFilterPlaceholder} debounceMs={quickFilterDebounceMs} />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { ChevronLeftIcon, ChevronRightIcon, FirstPageIcon, LastPageIcon } from '../icons';\nimport { IconButton, Select } from './primitives';\n\nexport function MGHGridPagination() {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const { page, pageSize } = state.paginationModel;\n const count = state.rowCount;\n const pageCount = state.pageCount;\n const from = count === 0 ? 0 : page * pageSize + 1;\n const to = Math.min(count, (page + 1) * pageSize);\n const options =\n rootProps.pageSizeOptions.indexOf(pageSize) === -1\n ? rootProps.pageSizeOptions.concat([pageSize]).sort((a, b) => a - b)\n : rootProps.pageSizeOptions;\n\n return (\n <div className=\"mgh-grid-pagination\" role=\"navigation\" aria-label=\"Pagination\">\n <span>{localeText.footerPaginationRowsPerPage}</span>\n <Select\n className=\"mgh-grid-pagination-select\"\n value={pageSize}\n aria-label={localeText.footerPaginationRowsPerPage}\n onChange={(event) => api.setPageSize(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </Select>\n <span>{localeText.footerPaginationDisplayedRows(from, to, count)}</span>\n <div className=\"mgh-grid-pagination-actions\">\n <IconButton label={localeText.footerPaginationFirstPage} disabled={page <= 0} onClick={() => api.setPage(0)}>\n <FirstPageIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationPreviousPage}\n disabled={page <= 0}\n onClick={() => api.setPage(page - 1)}\n >\n <ChevronLeftIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationNextPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(page + 1)}\n >\n <ChevronRightIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationLastPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(Math.max(pageCount - 1, 0))}\n >\n <LastPageIcon />\n </IconButton>\n </div>\n </div>\n );\n}\n\nexport function MGHGridFooter() {\n const { state, localeText, rootProps } = useMGHGridContext();\n const selectedCount = state.rowSelectionModel.ids.size;\n const showSelected = selectedCount > 0 && !rootProps.hideFooterSelectedRowCount;\n const showPagination = rootProps.pagination && !rootProps.hideFooterPagination;\n const showRowCount = !showPagination && !rootProps.hideFooterRowCount;\n\n return (\n <div className=\"mgh-grid-footer\">\n <div className=\"mgh-grid-footer-left\">\n {showSelected && <span>{localeText.footerRowSelected(selectedCount)}</span>}\n </div>\n {showRowCount && (\n <span>\n {localeText.footerTotalRows} {state.rowCount.toLocaleString()}\n </span>\n )}\n {showPagination && <MGHGridPagination />}\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { SearchIcon } from '../icons';\nimport { Button, Checkbox, TextInput } from './primitives';\n\nexport function MGHGridColumnsPanel() {\n const { api, state, localeText, columns, visibleColumns } = useMGHGridContext();\n const visibleFields = React.useMemo(() => new Set(visibleColumns.map((col) => col.field)), [visibleColumns]);\n const [search, setSearch] = React.useState('');\n const model = state.columnVisibilityModel;\n\n const hideable = columns.filter((col) => col.hideable !== false);\n const needle = search.trim().toLowerCase();\n const filtered = needle\n ? hideable.filter((col) => (col.headerName ?? col.field).toLowerCase().indexOf(needle) !== -1)\n : hideable;\n\n const setAll = (visible: boolean) => {\n const next = { ...model };\n hideable.forEach((col) => {\n next[col.field] = visible;\n });\n api.setColumnVisibilityModel(next);\n };\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarColumns}>\n <div className=\"mgh-grid-panel-header\">\n <div className=\"mgh-grid-input-adorned\">\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n autoFocus\n size=\"small\"\n value={search}\n placeholder={localeText.columnsPanelSearchPlaceholder}\n aria-label={localeText.columnsPanelSearchPlaceholder}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n </div>\n <div className=\"mgh-grid-panel-content\">\n <div className=\"mgh-grid-columns-list\">\n {filtered.map((col) => {\n const visible = visibleFields.has(col.field);\n return (\n <label key={col.field} className=\"mgh-grid-checkbox-label\">\n <Checkbox checked={visible} onChange={() => api.setColumnVisibility(col.field, !visible)} />\n <span>{col.headerName ?? col.field}</span>\n </label>\n );\n })}\n {filtered.length === 0 && <div className=\"mgh-grid-filter-empty\">No columns</div>}\n </div>\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(true)}>\n {localeText.columnsPanelShowAll}\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(false)}>\n {localeText.columnsPanelHideAll}\n </Button>\n <Button size=\"small\" onClick={() => api.setColumnVisibilityModel({})}>\n {localeText.columnsPanelReset}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridFilterItem, MGHGridFilterOperator } from '../MGHGrid.types';\nimport { AddIcon, DeleteIcon } from '../icons';\nimport { getColumnFilterOperators, getOptionLabel, getOptionValue, resolveValueOptions, uniqueId } from '../utils';\nimport { Button, Field, IconButton, Select, TextInput } from './primitives';\n\ninterface FilterValueInputProps {\n item: MGHGridFilterItem;\n column: MGHGridColDef;\n operator: MGHGridFilterOperator | undefined;\n onChange: (value: any) => void;\n placeholder: string;\n}\n\nconst useDebouncedValue = (value: any, onCommit: (value: any) => void, delay = 250) => {\n const [local, setLocal] = React.useState(value ?? '');\n const timer = React.useRef<number | null>(null);\n React.useEffect(() => {\n setLocal(value ?? '');\n }, [value]);\n const update = (next: any) => {\n setLocal(next);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => onCommit(next), delay);\n };\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n return [local, update] as const;\n};\n\nfunction TextValueInput({ item, onChange, placeholder, type }: FilterValueInputProps & { type: string }) {\n const [local, update] = useDebouncedValue(item.value, onChange);\n return (\n <TextInput\n size=\"small\"\n type={type}\n value={local}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction MultiValueInput({ item, column, onChange, placeholder }: FilterValueInputProps) {\n const joined = Array.isArray(item.value) ? item.value.join(', ') : (item.value ?? '');\n const [local, update] = useDebouncedValue(joined, (text: string) =>\n onChange(\n String(text)\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v !== '')\n )\n );\n if (column.type === 'singleSelect') {\n const options = resolveValueOptions(column);\n const selected: string[] = Array.isArray(item.value) ? item.value.map(String) : [];\n return (\n <Select\n multiple\n size=\"small\"\n value={selected}\n aria-label={placeholder}\n onChange={(event) => {\n const values = Array.from(event.target.selectedOptions).map((option) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === option.value);\n return match !== undefined ? getOptionValue(column, match) : option.value;\n });\n onChange(values);\n }}\n >\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n return (\n <TextInput\n size=\"small\"\n value={local}\n placeholder=\"Comma separated values\"\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction FilterValueInput(props: FilterValueInputProps) {\n const { item, column, operator, onChange, placeholder } = props;\n const { api } = useMGHGridContext();\n const inputType = operator?.inputType ?? 'text';\n\n if (operator?.InputComponent) {\n const Component = operator.InputComponent;\n return <Component item={item} column={column} applyValue={(next) => onChange(next.value)} api={api} />;\n }\n\n switch (inputType) {\n case 'none':\n return <div />;\n case 'boolean':\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n >\n <option value=\"\">any</option>\n <option value=\"true\">yes</option>\n <option value=\"false\">no</option>\n </Select>\n );\n case 'select': {\n const options = resolveValueOptions(column);\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === event.target.value);\n onChange(\n event.target.value === ''\n ? undefined\n : match !== undefined\n ? getOptionValue(column, match)\n : event.target.value\n );\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'multiselect':\n return <MultiValueInput {...props} />;\n case 'number':\n return <TextValueInput {...props} type=\"number\" />;\n case 'date':\n return <TextValueInput {...props} type=\"date\" />;\n case 'datetime-local':\n return <TextValueInput {...props} type=\"datetime-local\" />;\n default:\n return <TextValueInput {...props} type=\"text\" />;\n }\n}\n\nconst createFilterItem = (column: MGHGridColDef | undefined): MGHGridFilterItem => ({\n id: uniqueId('filter'),\n field: column?.field ?? '',\n operator: column ? (getColumnFilterOperators(column)[0]?.value ?? 'contains') : 'contains',\n value: undefined,\n});\n\nexport function MGHGridFilterPanel() {\n const { api, state, localeText, columns, rootProps } = useMGHGridContext();\n const filterableColumns = React.useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);\n const byField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n filterableColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [filterableColumns]);\n\n const items = state.filterModel.items;\n const logicOperator = state.filterModel.logicOperator ?? 'and';\n const targetField = state.preferencePanel.targetField;\n\n // Ensure at least one (possibly empty) item is displayed when the panel opens, like MUI does.\n const seeded = React.useRef(false);\n React.useEffect(() => {\n if (seeded.current) return;\n seeded.current = true;\n if (targetField && byField.has(targetField)) {\n const existing = items.find((item) => item.field === targetField);\n if (!existing) api.upsertFilterItem(createFilterItem(byField.get(targetField)));\n } else if (items.length === 0 && filterableColumns.length > 0) {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n }\n }, [api, byField, filterableColumns, items, targetField]);\n\n const updateItem = (item: MGHGridFilterItem, patch: Partial<MGHGridFilterItem>) => {\n api.upsertFilterItem({ ...item, ...patch });\n };\n\n const addItem = () => {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n };\n\n const canAddMore = !rootProps.disableMultipleColumnsFiltering || items.length === 0;\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarFilters}>\n <div className=\"mgh-grid-panel-content\" style={{ paddingTop: 12 }}>\n {items.length === 0 && <div className=\"mgh-grid-filter-empty\">No filters</div>}\n {items.map((item, index) => {\n const column = byField.get(item.field) ?? filterableColumns[0];\n const operators = column ? getColumnFilterOperators(column) : [];\n const operator = operators.find((op) => op.value === item.operator) ?? operators[0];\n const showLogic = items.length > 1;\n return (\n <div\n key={String(item.id ?? index)}\n className={\n showLogic ? 'mgh-grid-filter-row mgh-grid-filter-row--with-logic' : 'mgh-grid-filter-row'\n }\n >\n <IconButton\n size=\"small\"\n label={localeText.filterPanelDeleteIcon}\n onClick={() => api.deleteFilterItem(item)}\n >\n <DeleteIcon />\n </IconButton>\n {showLogic && (\n <Field label={index === 1 ? localeText.filterPanelLogicOperator : ' '}>\n {index === 0 ? (\n <div style={{ height: 32 }} />\n ) : (\n <Select\n size=\"small\"\n value={logicOperator}\n disabled={index > 1}\n aria-label={localeText.filterPanelLogicOperator}\n onChange={(event) =>\n api.setFilterLogicOperator(event.target.value as 'and' | 'or')\n }\n >\n <option value=\"and\">{localeText.filterPanelOperatorAnd}</option>\n <option value=\"or\">{localeText.filterPanelOperatorOr}</option>\n </Select>\n )}\n </Field>\n )}\n <Field label={localeText.filterPanelColumns}>\n <Select\n size=\"small\"\n value={column?.field ?? ''}\n aria-label={localeText.filterPanelColumns}\n onChange={(event) => {\n const nextColumn = byField.get(event.target.value);\n const nextOperators = nextColumn ? getColumnFilterOperators(nextColumn) : [];\n const keepOperator = nextOperators.some((op) => op.value === item.operator);\n updateItem(item, {\n field: event.target.value,\n operator: keepOperator ? item.operator : (nextOperators[0]?.value ?? 'contains'),\n value: undefined,\n });\n }}\n >\n {filterableColumns.map((col) => (\n <option key={col.field} value={col.field}>\n {col.headerName ?? col.field}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelOperator}>\n <Select\n size=\"small\"\n value={operator?.value ?? ''}\n aria-label={localeText.filterPanelOperator}\n onChange={(event) => {\n const nextOperator = operators.find((op) => op.value === event.target.value);\n const nextIsMulti = nextOperator?.inputType === 'multiselect';\n const currentIsMulti = operator?.inputType === 'multiselect';\n updateItem(item, {\n operator: event.target.value,\n value: nextIsMulti !== currentIsMulti ? undefined : item.value,\n });\n }}\n >\n {operators.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label ?? op.value}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelValue}>\n {column ? (\n <FilterValueInput\n item={item}\n column={column}\n operator={operator}\n placeholder={localeText.filterPanelInputPlaceholder}\n onChange={(value) => updateItem(item, { value })}\n />\n ) : (\n <div />\n )}\n </Field>\n </div>\n );\n })}\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button\n variant=\"primary\"\n size=\"small\"\n startIcon={<AddIcon size={18} />}\n onClick={addItem}\n disabled={!canAddMore}\n >\n {localeText.filterPanelAddFilter}\n </Button>\n <Button\n size=\"small\"\n startIcon={<DeleteIcon size={18} />}\n disabled={items.length === 0}\n onClick={() => api.setFilterModel({ ...state.filterModel, items: [] })}\n >\n {localeText.filterPanelRemoveAll}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridThemeMode } from '../MGHGrid.types';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n FilterListIcon,\n FunctionsIcon,\n PushPinIcon,\n ViewColumnIcon,\n VisibilityOffIcon,\n WorkspacesIcon,\n} from '../icons';\nimport { GROUPING_COLUMN_FIELD } from '../utils';\nimport { Menu, MenuDivider, MenuItem, MenuSection, Popover, Select } from './primitives';\n\nexport interface MGHGridColumnMenuProps {\n column: MGHGridColDef;\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n themeMode: MGHGridThemeMode;\n /** Anchor for panels opened from the menu (usually the toolbar button or the header cell). */\n panelAnchorEl?: HTMLElement | null;\n}\n\nexport function MGHGridColumnMenu({ column, anchorEl, open, onClose, themeMode, panelAnchorEl }: MGHGridColumnMenuProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const field = column.field;\n const isGroupingColumn = field === GROUPING_COLUMN_FIELD;\n const sortItem = state.sortModel.find((item) => item.field === field);\n const pinned = api.isColumnPinned(field);\n const isGrouped = state.rowGroupingModel.indexOf(field) !== -1;\n const aggregation = state.aggregationModel[field];\n\n const canSort = column.sortable !== false && !rootProps.disableColumnSorting;\n const canFilter = column.filterable !== false && !rootProps.disableColumnFilter && !isGroupingColumn;\n const canHide = column.hideable !== false;\n const canPin = column.pinnable !== false && !rootProps.disableColumnPinning;\n const canGroup = column.groupable !== false && !rootProps.disableRowGrouping && !isGroupingColumn;\n const aggregationFunctions = Object.keys(rootProps.aggregationFunctions).filter((name) => {\n const fn = rootProps.aggregationFunctions[name];\n if (column.availableAggregationFunctions && column.availableAggregationFunctions.indexOf(name) === -1) return false;\n if (fn.columnTypes && column.type && fn.columnTypes.indexOf(column.type) === -1) return false;\n return true;\n });\n const canAggregate =\n column.aggregable !== false && !rootProps.disableAggregation && !isGroupingColumn && aggregationFunctions.length > 0;\n\n const anchorForPanel = panelAnchorEl ?? anchorEl;\n const name = column.headerName ?? column.field;\n\n return (\n <Popover open={open} anchorEl={anchorEl} onClose={onClose} themeMode={themeMode} placement=\"bottom-end\" role=\"menu\">\n <Menu aria-label={localeText.columnMenuLabel}>\n {canSort && (\n <>\n <MenuItem\n icon={<ArrowUpwardIcon />}\n selected={sortItem?.sort === 'asc'}\n onClick={() => api.sortColumn(field, 'asc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortAsc}\n </MenuItem>\n <MenuItem\n icon={<ArrowDownwardIcon />}\n selected={sortItem?.sort === 'desc'}\n onClick={() => api.sortColumn(field, 'desc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortDesc}\n </MenuItem>\n {sortItem && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.sortColumn(field, null)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnsort}\n </MenuItem>\n )}\n </>\n )}\n {canFilter && (\n <>\n {canSort && <MenuDivider />}\n <MenuItem\n icon={<FilterListIcon />}\n onClick={() => api.showFilterPanel(field, anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuFilter}\n </MenuItem>\n </>\n )}\n {(canHide || !rootProps.disableColumnSelector) && (\n <>\n {(canSort || canFilter) && <MenuDivider />}\n {canHide && (\n <MenuItem\n icon={<VisibilityOffIcon />}\n onClick={() => api.setColumnVisibility(field, false)}\n hideMenu={onClose}\n >\n {localeText.columnMenuHideColumn}\n </MenuItem>\n )}\n {!rootProps.disableColumnSelector && (\n <MenuItem\n icon={<ViewColumnIcon />}\n onClick={() => api.showPreferences('columns', anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuManageColumns}\n </MenuItem>\n )}\n </>\n )}\n {canPin && (\n <>\n <MenuDivider />\n {pinned !== 'left' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(30deg)' }} />}\n onClick={() => api.pinColumn(field, 'left')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinLeft}\n </MenuItem>\n )}\n {pinned !== 'right' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(-30deg)' }} />}\n onClick={() => api.pinColumn(field, 'right')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinRight}\n </MenuItem>\n )}\n {pinned && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.unpinColumn(field)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnpin}\n </MenuItem>\n )}\n </>\n )}\n {canGroup && (\n <>\n <MenuDivider />\n <MenuItem\n icon={<WorkspacesIcon />}\n onClick={() =>\n isGrouped ? api.removeRowGroupingCriteria(field) : api.addRowGroupingCriteria(field)\n }\n hideMenu={onClose}\n >\n {isGrouped ? localeText.columnMenuUngroup(name) : localeText.columnMenuGroup(name)}\n </MenuItem>\n </>\n )}\n {canAggregate && (\n <>\n <MenuDivider />\n <MenuSection>\n <label\n className=\"mgh-grid-field-label\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <FunctionsIcon size={16} /> {localeText.columnMenuAggregation}\n </label>\n <Select\n size=\"small\"\n value={aggregation ?? ''}\n aria-label={localeText.columnMenuAggregation}\n onChange={(event) => {\n const next = { ...state.aggregationModel };\n if (event.target.value === '') delete next[field];\n else next[field] = event.target.value;\n api.setAggregationModel(next);\n }}\n >\n <option value=\"\">{localeText.aggregationFunctionLabelNone}</option>\n {aggregationFunctions.map((fnName) => (\n <option key={fnName} value={fnName}>\n {rootProps.aggregationFunctions[fnName].label ?? fnName}\n </option>\n ))}\n </Select>\n </MenuSection>\n </>\n )}\n </Menu>\n </Popover>\n );\n}\n","import React from 'react';\nimport { MGHGridLoadingOverlayProps, MGHGridNoRowsOverlayProps } from '../MGHGrid.types';\nimport { EmptyBoxIcon } from '../icons';\nimport { Spinner } from './primitives';\n\n/** Default \"no rows\" overlay. Mirrors the legacy CustomNoRowsOverlay but has no MUI dependency. */\nexport function MGHGridNoRowsOverlay({ text = 'No rows', imageSrc }: MGHGridNoRowsOverlayProps) {\n return (\n <div className=\"mgh-grid-no-rows\" role=\"status\">\n {imageSrc ? <img alt=\"\" src={imageSrc} /> : <EmptyBoxIcon size={50} />}\n <div>{text}</div>\n </div>\n );\n}\n\nexport function MGHGridLoadingOverlay({ text }: MGHGridLoadingOverlayProps) {\n return (\n <>\n <Spinner />\n {text && <div>{text}</div>}\n </>\n );\n}\n","import React from 'react';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { MoreVertIcon } from '../icons';\nimport { IconButton, Menu, MenuItem, Popover } from './primitives';\n\nexport interface MGHGridActionsCellItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n icon?: React.ReactElement;\n label: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Render the action inside the \"more\" menu instead of inline. */\n showInMenu?: boolean;\n disabled?: boolean;\n}\n\n/** Drop-in replacement for MUI's GridActionsCellItem. Use it from `colDef.getActions`. */\nexport function MGHGridActionsCellItem({\n icon,\n label,\n onClick,\n showInMenu,\n disabled,\n className,\n ...rest\n}: MGHGridActionsCellItemProps) {\n return (\n <IconButton\n size=\"small\"\n label={label}\n disabled={disabled}\n className={className}\n onClick={(event) => {\n event.stopPropagation();\n onClick?.(event);\n }}\n {...rest}\n >\n {icon}\n </IconButton>\n );\n}\nMGHGridActionsCellItem.displayName = 'MGHGridActionsCellItem';\n\ninterface ActionsCellProps {\n actions: React.ReactElement[];\n themeMode: MGHGridThemeMode;\n moreLabel: string;\n}\n\nexport function ActionsCell({ actions, themeMode, moreLabel }: ActionsCellProps) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const inline: React.ReactElement[] = [];\n const inMenu: React.ReactElement[] = [];\n actions.forEach((action) => {\n if (!React.isValidElement(action)) return;\n if ((action.props as MGHGridActionsCellItemProps)?.showInMenu) inMenu.push(action);\n else inline.push(action);\n });\n\n return (\n <>\n {inline.map((action, index) => (\n <React.Fragment key={action.key ?? index}>{action}</React.Fragment>\n ))}\n {inMenu.length > 0 && (\n <>\n <IconButton\n size=\"small\"\n label={moreLabel}\n active={Boolean(anchor)}\n onClick={(event) => {\n event.stopPropagation();\n setAnchor((prev) => (prev ? null : event.currentTarget));\n }}\n >\n <MoreVertIcon />\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n placement=\"bottom-end\"\n role=\"menu\"\n >\n <Menu>\n {inMenu.map((action, index) => {\n const props = action.props as MGHGridActionsCellItemProps;\n return (\n <MenuItem\n key={action.key ?? index}\n icon={props.icon}\n disabled={props.disabled}\n onClick={(event) => {\n props.onClick?.(event);\n setAnchor(null);\n }}\n >\n {props.label}\n </MenuItem>\n );\n })}\n </Menu>\n </Popover>\n </>\n )}\n </>\n );\n}\n","import React from 'react';\nimport {\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridApplyFilterFn,\n MGHGridCallbackDetails,\n MGHGridCellParams,\n MGHGridColDef,\n MGHGridColumnVisibilityModel,\n MGHGridDensity,\n MGHGridFilterItem,\n MGHGridFilterModel,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridLocaleText,\n MGHGridPaginationModel,\n MGHGridPinnedColumns,\n MGHGridPinnedSide,\n MGHGridPreferencePanelState,\n MGHGridPrintExportOptions,\n MGHGridProps,\n MGHGridRowGroupingModel,\n MGHGridRowId,\n MGHGridRowNode,\n MGHGridRowParams,\n MGHGridRowSelectionModel,\n MGHGridSortDirection,\n MGHGridSortModel,\n MGHGridState,\n MGHGridSxProps,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport {\n AGGREGATION_FOOTER_ID,\n BUILT_IN_AGGREGATION_FUNCTIONS,\n CHECKBOX_COLUMN_DEF,\n CHECKBOX_FIELD,\n DEFAULT_COLUMN_MIN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_LOCALE_TEXT,\n DEFAULT_ROW_HEIGHT,\n DENSITY_FACTORS,\n DETAIL_PANEL_TOGGLE_COLUMN_DEF,\n DETAIL_PANEL_TOGGLE_FIELD,\n GROUPING_COLUMN_FIELD,\n GROUPING_COLUMN_WIDTH,\n clamp,\n cx,\n defaultFormatValue,\n formattedValueToString,\n getCellValue,\n getColumnFilterOperators,\n getDefaultComparator,\n getFormattedValue,\n getOptionLabel,\n getOptionValue,\n getRowIdFromRow,\n buildScopedCss,\n isInternalField,\n isNil,\n isSelectorKey,\n measureText,\n moveItem,\n normalizeColumn,\n normalizeSelectionModel,\n parseEditValue,\n readLocalStorage,\n resolveValueOptions,\n selectionModelsEqual,\n toDate,\n writeLocalStorage,\n} from './utils';\nimport { useMGHGridStyles } from './MGHGrid.styles';\nimport { MGHGridContext, MGHGridContextValue, MGHGridRootProps } from './context';\nimport { useControlledState, useElementSize, useForceUpdate, useLatestRef, useStableId } from './hooks';\nimport { exportDataAsCsv, exportDataAsExcel, getDataAsCsv } from './export';\nimport { printGridElement } from './print';\nimport {\n DisplayRow,\n GroupTreeNode,\n RowEntry,\n aggregateRows,\n buildGroupTree,\n collectTreeLeaves,\n flattenGroupTree,\n sortGroupTree,\n} from './grouping';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n CheckIcon,\n ChevronRightIcon,\n CloseIcon,\n ExpandMoreIcon,\n MoreVertIcon,\n} from './icons';\nimport { Checkbox, IconButton, Popover, Select, TextInput } from './components/primitives';\nimport { MGHGridToolbar } from './components/Toolbar';\nimport { MGHGridFooter } from './components/Footer';\nimport { MGHGridColumnsPanel } from './components/ColumnsPanel';\nimport { MGHGridFilterPanel } from './components/FilterPanel';\nimport { MGHGridColumnMenu } from './components/ColumnMenu';\nimport { MGHGridLoadingOverlay, MGHGridNoRowsOverlay } from './components/Overlays';\nimport { ActionsCell } from './components/ActionsCell';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants & helpers\n * ----------------------------------------------------------------------------------------------- */\n\nconst EMPTY_ARRAY: any[] = [];\nconst EMPTY_OBJECT: Record<string, any> = {};\nconst EMPTY_MAP = new Map<any, any>();\nconst DEFAULT_SORTING_ORDER: MGHGridSortDirection[] = ['asc', 'desc', null];\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\nconst DEFAULT_FILTER_MODEL: MGHGridFilterModel = { items: [], quickFilterExcludeHiddenColumns: false };\nconst OVERSCAN_ROWS = 6;\nconst DEFAULT_DETAIL_PANEL_HEIGHT = 500;\n\ninterface ColumnLayout {\n col: MGHGridColDef;\n width: number;\n pinned: MGHGridPinnedSide | null;\n /** Sticky offset (left or right) for pinned columns. */\n offset: number;\n /** X position from the start of the row. */\n x: number;\n isLastLeft: boolean;\n isFirstRight: boolean;\n}\n\ntype RenderRowKind = 'leaf' | 'group' | 'pinnedRow' | 'footer';\n\ninterface RenderRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n kind: RenderRowKind;\n row: R | null;\n node: MGHGridRowNode;\n depth: number;\n group?: GroupTreeNode<R>;\n aggregates?: Record<string, { value: any; fn: string }>;\n}\n\ninterface CellCoords {\n id: MGHGridRowId;\n field: string;\n}\n\n/** Keeps only the inline-applicable part of an sx-like object (nested selectors are compiled to CSS). */\nconst sanitizeStyle = (style: MGHGridSxProps | undefined): React.CSSProperties | undefined => {\n if (!style) return undefined;\n const out: Record<string, any> = {};\n Object.keys(style).forEach((key) => {\n if (isSelectorKey(key)) return;\n const value = (style as any)[key];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n out[key] = value;\n });\n return out;\n};\n\nconst computeWidths = (cols: MGHGridColDef[], available: number, overrides: Record<string, number>) => {\n const result: Array<number | null> = cols.map((col) => {\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const override = overrides[col.field];\n if (override) return clamp(override, min, max);\n if (col.flex && col.flex > 0) return null;\n return clamp(col.width ?? 100, min, max);\n });\n const pool: number[] = [];\n let fixedTotal = 0;\n result.forEach((w, i) => {\n if (w === null) pool.push(i);\n else fixedTotal += w;\n });\n if (pool.length > 0) {\n let remainingSpace = Math.max(0, available - fixedTotal);\n let remainingFlex = pool.reduce((acc, i) => acc + (cols[i].flex as number), 0);\n let active = pool.slice();\n let changed = true;\n while (changed && active.length > 0) {\n changed = false;\n for (let k = 0; k < active.length; k += 1) {\n const i = active[k];\n const col = cols[i];\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const share = remainingFlex > 0 ? (remainingSpace * (col.flex as number)) / remainingFlex : 0;\n if (share < min || share > max) {\n const fixed = share < min ? min : max;\n result[i] = fixed;\n remainingSpace = Math.max(0, remainingSpace - fixed);\n remainingFlex -= col.flex as number;\n active = active.filter((idx) => idx !== i);\n changed = true;\n break;\n }\n }\n }\n active.forEach((i) => {\n const col = cols[i];\n result[i] =\n remainingFlex > 0\n ? Math.floor((remainingSpace * (col.flex as number)) / remainingFlex)\n : (col.minWidth ?? 50);\n });\n }\n return result as number[];\n};\n\nconst toDateInputValue = (value: any, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n return withTime ? `${base}T${pad(date.getHours())}:${pad(date.getMinutes())}` : base;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Component\n * ----------------------------------------------------------------------------------------------- */\n\nexport default function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>) {\n const {\n rows,\n columns: columnsProp,\n getRowId,\n loading = false,\n header,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n disableCard = false,\n className,\n cardClassName,\n boxClassName,\n cardStyle,\n cardSx,\n boxStyle,\n boxSx,\n style,\n sx,\n themeMode = 'light',\n themeVars,\n showToolbar = true,\n toolbarProps,\n slots = EMPTY_OBJECT,\n slotProps = EMPTY_OBJECT,\n noRowsText = 'No data found within selected parameters.',\n localeText: localeTextProp,\n rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n columnHeaderHeight = DEFAULT_HEADER_HEIGHT,\n getRowHeight,\n autoHeight = false,\n disableVirtualization = false,\n density: densityProp,\n onDensityChange,\n disableDensitySelector = false,\n pagination = true,\n pageSize = 25,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationModel: paginationModelProp,\n onPaginationModelChange,\n hideFooter = false,\n hideFooterPagination = false,\n hideFooterRowCount = false,\n hideFooterSelectedRowCount = false,\n sortModel: sortModelProp,\n onSortModelChange,\n sortingOrder = DEFAULT_SORTING_ORDER,\n disableMultipleColumnsSorting = false,\n disableColumnSorting = false,\n filterModel: filterModelProp,\n onFilterModelChange,\n disableColumnFilter = false,\n disableMultipleColumnsFiltering = false,\n quickFilterDebounceMs = 150,\n columnVisibilityModel: columnVisibilityModelProp,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n columnWidthStorageKey,\n pinnedColumnsStorageKey,\n onColumnOrderChange,\n onColumnWidthChange,\n disableColumnMenu = false,\n disableColumnSelector = false,\n disableColumnResize = false,\n disableColumnReorder = false,\n disableColumnPinning = false,\n pinnedColumns: pinnedColumnsProp,\n onPinnedColumnsChange,\n checkboxSelection = false,\n checkboxSelectionVisibleOnly = false,\n disableRowSelectionOnClick = true,\n disableMultipleRowSelection = false,\n rowSelectionModel: rowSelectionModelProp,\n onRowSelectionModelChange,\n isRowSelectable,\n keepNonExistentRowsSelected = true,\n getRowClassName,\n onRowClick,\n onRowDoubleClick,\n onCellClick,\n onCellDoubleClick,\n pinnedRows,\n getDetailPanelContent,\n getDetailPanelHeight,\n detailPanelExpandedRowIds: detailPanelExpandedRowIdsProp,\n onDetailPanelExpandedRowIdsChange,\n rowGroupingModel: rowGroupingModelProp,\n onRowGroupingModelChange,\n defaultGroupingExpansionDepth = 0,\n groupingColDef,\n disableRowGrouping = false,\n isGroupExpandedByDefault,\n aggregationModel: aggregationModelProp,\n onAggregationModelChange,\n aggregationFunctions: aggregationFunctionsProp,\n disableAggregation = false,\n aggregationPosition = 'both',\n processRowUpdate,\n onProcessRowUpdateError,\n onCellEditStop,\n isCellEditable,\n initialState,\n apiRef,\n onStateChange,\n } = props;\n\n useMGHGridStyles();\n\n const gridId = useStableId('mgh-grid');\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const cardRef = React.useRef<HTMLDivElement | null>(null);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n const forceUpdate = useForceUpdate();\n\n const localeText = React.useMemo<MGHGridLocaleText>(\n () => ({ ...DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n\n /* ------------------------------------------------------------------ latest ref + api shell */\n\n const latest = React.useRef<any>({});\n const getDetails = React.useCallback((): MGHGridCallbackDetails => ({ api: latest.current.api }), []);\n\n const apiObject = React.useMemo<MGHGridApi<R>>(() => {\n const L = () => latest.current;\n const apiImpl: MGHGridApi<R> = {\n getRow: (id) => L().rowsById.get(id) ?? null,\n getRowModels: () => new Map(L().rowsById),\n getAllRowIds: () => L().rowEntries.map((e: RowEntry<R>) => e.id),\n getRowNode: (id) => L().nodesById.get(id) ?? null,\n getSortedRows: () => L().sortedLeaves.map((e: RowEntry<R>) => e.row),\n getSortedRowIds: () => L().sortedLeaves.map((e: RowEntry<R>) => e.id),\n getVisibleRows: () =>\n L()\n .pagedRows.filter((dr: DisplayRow<R>) => dr.type === 'leaf' && dr.row)\n .map((dr: DisplayRow<R>) => ({ id: dr.id, model: dr.row as R })),\n getRowIndexRelativeToVisibleRows: (id) => L().pagedRows.findIndex((dr: DisplayRow<R>) => dr.id === id),\n updateRows: (updates) => {\n updates.forEach((update) => {\n const id = getRowIdFromRow(update as R, L().getRowId);\n const existing = L().rowsById.get(id);\n if (existing) L().setRowOverride(id, { ...existing, ...update });\n });\n },\n\n getAllColumns: () => L().orderedUserColumns,\n getVisibleColumns: () => L().visibleUserColumns,\n getColumn: (field) => L().getColumn(field),\n getColumnIndex: (field, useVisibleColumns = true) =>\n (useVisibleColumns ? L().visibleUserColumns : L().orderedUserColumns).findIndex(\n (c: MGHGridColDef) => c.field === field\n ),\n getColumnVisibilityModel: () => L().columnVisibilityModel,\n setColumnVisibility: (field, isVisible) =>\n L().setColumnVisibilityModel({ ...L().columnVisibilityModel, [field]: isVisible }),\n setColumnVisibilityModel: (model) => L().setColumnVisibilityModel(model),\n setColumnWidth: (field, width) => L().setColumnWidth(field, width),\n setColumnIndex: (field, targetIndex) => L().setColumnIndex(field, targetIndex),\n autosizeColumns: (options) => L().autosizeColumns(options),\n pinColumn: (field, side) => L().pinColumn(field, side),\n unpinColumn: (field) => L().unpinColumn(field),\n isColumnPinned: (field) => L().isColumnPinned(field),\n getPinnedColumns: () => L().pinnedColumns,\n setPinnedColumns: (model) => L().setPinnedColumns(model),\n\n getSortModel: () => L().sortModel,\n setSortModel: (model) => L().setSortModel(model),\n sortColumn: (field, direction, allowMultipleSorting) => L().sortColumn(field, direction, allowMultipleSorting),\n\n getFilterModel: () => L().filterModel,\n setFilterModel: (model) => L().setFilterModel(model),\n upsertFilterItem: (item) => L().upsertFilterItems([item]),\n upsertFilterItems: (items) => L().upsertFilterItems(items),\n deleteFilterItem: (item) => L().deleteFilterItem(item),\n setFilterLogicOperator: (operator) => L().setFilterModel({ ...L().filterModel, logicOperator: operator }),\n setQuickFilterValues: (values) => L().setFilterModel({ ...L().filterModel, quickFilterValues: values }),\n showFilterPanel: (targetColumnField, anchorEl) => L().showPreferences('filters', anchorEl, targetColumnField),\n hideFilterPanel: () => L().hidePreferences(),\n showPreferences: (panel, anchorEl, targetField) => L().showPreferences(panel, anchorEl, targetField),\n hidePreferences: () => L().hidePreferences(),\n\n getSelectedRows: () => {\n const map = new Map<MGHGridRowId, R>();\n L().selectedIds.forEach((id: MGHGridRowId) => {\n const row = L().rowsById.get(id);\n if (row) map.set(id, row);\n });\n return map;\n },\n getRowSelectionModel: () => ({ type: 'include', ids: L().selectedIds }),\n setRowSelectionModel: (model) => {\n const normalized = normalizeSelectionModel(\n model,\n L().rowEntries.map((e: RowEntry<R>) => e.id)\n );\n L().setSelectedIds(normalized.ids);\n },\n selectRow: (id, isSelected = true, resetSelection = false) => L().selectRows([id], isSelected, resetSelection),\n selectRows: (ids, isSelected = true, resetSelection = false) => L().selectRows(ids, isSelected, resetSelection),\n isRowSelected: (id) => L().selectedIds.has(id),\n isRowSelectable: (id) => L().isRowSelectableFn(id, L().rowsById.get(id)),\n\n setPage: (nextPage) => L().setPaginationModel({ ...L().paginationModel, page: Math.max(0, nextPage) }),\n setPageSize: (nextPageSize) => L().setPaginationModel({ page: 0, pageSize: Math.max(1, nextPageSize) }),\n setPaginationModel: (model) => L().setPaginationModel(model),\n\n setDensity: (value) => L().setDensity(value),\n\n getDataAsCsv: (options) => getDataAsCsv(apiImpl, options),\n exportDataAsCsv: (options) => exportDataAsCsv(apiImpl, options),\n exportDataAsExcel: (options) => exportDataAsExcel(apiImpl, options),\n exportDataAsPrint: (options) => L().startPrint(options),\n\n toggleDetailPanel: (id) => L().toggleDetailPanel(id),\n setExpandedDetailPanels: (ids) => L().setExpandedDetailPanels(new Set(ids)),\n getExpandedDetailPanels: () => Array.from(L().expandedDetailPanels as Set<MGHGridRowId>),\n\n getRowGroupingModel: () => L().rowGroupingModel,\n setRowGroupingModel: (model) => L().setRowGroupingModel(model),\n addRowGroupingCriteria: (field, groupingIndex) => {\n const current: string[] = L().rowGroupingModel.filter((f: string) => f !== field);\n if (groupingIndex === undefined) current.push(field);\n else current.splice(clamp(groupingIndex, 0, current.length), 0, field);\n L().setRowGroupingModel(current);\n },\n removeRowGroupingCriteria: (field) =>\n L().setRowGroupingModel(L().rowGroupingModel.filter((f: string) => f !== field)),\n setRowChildrenExpansion: (id, isExpanded) => L().setRowChildrenExpansion(id, isExpanded),\n getRowGroupChildren: ({ groupId }) => {\n const group = L().groupsById.get(groupId) as GroupTreeNode<R> | undefined;\n return group ? group.descendants.map((d) => d.id) : [];\n },\n\n getAggregationModel: () => L().aggregationModel,\n setAggregationModel: (model) => L().setAggregationModel(model),\n\n startCellEditMode: ({ id, field }) => L().startCellEditMode(id, field),\n stopCellEditMode: ({ id, field, ignoreModifications }) =>\n L().stopCellEditMode(id, field, ignoreModifications, 'api'),\n getCellMode: (id, field) => {\n const editing = L().editingCell as CellCoords | null;\n return editing && editing.id === id && editing.field === field ? 'edit' : 'view';\n },\n setEditCellValue: ({ id, field, value }) => {\n const editing = L().editingCell as CellCoords | null;\n if (editing && editing.id === id && editing.field === field) L().setEditValue(value);\n },\n\n getCellValue: (id, field) => {\n const row = L().rowsById.get(id);\n const col = L().getColumn(field);\n return row && col ? getCellValue(row, col, apiImpl) : undefined;\n },\n getCellParams: (id, field) => {\n const row = L().rowsById.get(id);\n return L().buildCellParams(\n id,\n field,\n row,\n L().nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null }\n );\n },\n setCellFocus: (id, field) => {\n pendingFocusRef.current = true;\n L().setFocusedCell({ id, field });\n },\n\n scrollToIndexes: (params) => L().scrollToIndexes(params),\n scroll: ({ left, top }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n if (left !== undefined) scroller.scrollLeft = left;\n if (top !== undefined) scroller.scrollTop = top;\n },\n getScrollPosition: () => ({\n left: scrollerRef.current?.scrollLeft ?? 0,\n top: scrollerRef.current?.scrollTop ?? 0,\n }),\n\n get state() {\n return L().state as MGHGridState;\n },\n forceUpdate: () => L().forceUpdate(),\n rootElementRef: rootRef,\n };\n return apiImpl;\n }, []);\n if (!latest.current.api) latest.current.api = apiObject;\n\n /* ------------------------------------------------------------------ persisted state */\n\n const persisted = React.useMemo(\n () => ({\n visibility: columnVisibilityStorageKey\n ? readLocalStorage<MGHGridColumnVisibilityModel>(columnVisibilityStorageKey)\n : null,\n order: columnOrderStorageKey ? readLocalStorage<string[]>(columnOrderStorageKey) : null,\n widths: columnWidthStorageKey ? readLocalStorage<Record<string, number>>(columnWidthStorageKey) : null,\n pinned: pinnedColumnsStorageKey ? readLocalStorage<MGHGridPinnedColumns>(pinnedColumnsStorageKey) : null,\n }),\n [columnVisibilityStorageKey, columnOrderStorageKey, columnWidthStorageKey, pinnedColumnsStorageKey]\n );\n\n /* ------------------------------------------------------------------ models */\n\n const [sortModel, setSortModel] = useControlledState<MGHGridSortModel>(\n sortModelProp,\n initialState?.sorting?.sortModel ?? EMPTY_ARRAY,\n (model) => onSortModelChange?.(model, getDetails())\n );\n\n const [filterModel, setFilterModel] = useControlledState<MGHGridFilterModel>(\n filterModelProp,\n initialState?.filter?.filterModel ?? DEFAULT_FILTER_MODEL,\n (model) => onFilterModelChange?.(model, getDetails())\n );\n\n const [paginationModel, setPaginationModel] = useControlledState<MGHGridPaginationModel>(\n paginationModelProp,\n {\n page: initialState?.pagination?.paginationModel?.page ?? 0,\n pageSize: initialState?.pagination?.paginationModel?.pageSize ?? pageSize,\n },\n (model) => onPaginationModelChange?.(model, getDetails())\n );\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useControlledState<MGHGridColumnVisibilityModel>(\n columnVisibilityModelProp,\n persisted.visibility ?? initialState?.columns?.columnVisibilityModel ?? EMPTY_OBJECT,\n (model) => {\n if (columnVisibilityStorageKey) writeLocalStorage(columnVisibilityStorageKey, model);\n onColumnVisibilityModelChange?.(model, getDetails());\n }\n );\n\n const [density, setDensity] = useControlledState<MGHGridDensity>(\n densityProp,\n initialState?.density ?? 'compact',\n (value) => onDensityChange?.(value, getDetails())\n );\n\n const [pinnedColumns, setPinnedColumns] = useControlledState<MGHGridPinnedColumns>(\n pinnedColumnsProp,\n persisted.pinned ?? initialState?.pinnedColumns ?? EMPTY_OBJECT,\n (model) => {\n if (pinnedColumnsStorageKey) writeLocalStorage(pinnedColumnsStorageKey, model);\n onPinnedColumnsChange?.(model, getDetails());\n }\n );\n\n const [rowGroupingModel, setRowGroupingModel] = useControlledState<MGHGridRowGroupingModel>(\n rowGroupingModelProp,\n initialState?.rowGrouping?.model ?? EMPTY_ARRAY,\n (model) => onRowGroupingModelChange?.(model, getDetails())\n );\n\n const [aggregationModel, setAggregationModel] = useControlledState<MGHGridAggregationModel>(\n aggregationModelProp,\n initialState?.aggregation?.model ?? EMPTY_OBJECT,\n (model) => onAggregationModelChange?.(model, getDetails())\n );\n\n const controlledExpandedDetail = React.useMemo(\n () => (detailPanelExpandedRowIdsProp ? new Set<MGHGridRowId>(detailPanelExpandedRowIdsProp) : undefined),\n [detailPanelExpandedRowIdsProp]\n );\n const [expandedDetailPanels, setExpandedDetailPanels] = useControlledState<Set<MGHGridRowId>>(\n controlledExpandedDetail,\n React.useMemo(() => new Set<MGHGridRowId>(initialState?.detailPanel?.expandedRowIds ?? []), []),\n (ids) => onDetailPanelExpandedRowIdsChange?.(Array.from(ids), getDetails())\n );\n\n const controlledSelection = React.useMemo(\n () => (rowSelectionModelProp !== undefined ? normalizeSelectionModel(rowSelectionModelProp).ids : undefined),\n [rowSelectionModelProp]\n );\n const [selectedIds, setSelectedIds] = useControlledState<Set<MGHGridRowId>>(\n controlledSelection,\n React.useMemo(() => new Set<MGHGridRowId>(), []),\n (ids) => onRowSelectionModelChange?.({ type: 'include', ids }, getDetails())\n );\n\n /* ------------------------------------------------------------------ internal state */\n\n const [orderedFields, setOrderedFields] = React.useState<string[] | null>(\n () => persisted.order ?? initialState?.columns?.orderedFields ?? null\n );\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>(() => {\n if (persisted.widths) return persisted.widths;\n const dims = initialState?.columns?.dimensions;\n if (!dims) return {};\n const out: Record<string, number> = {};\n Object.keys(dims).forEach((field) => {\n if (dims[field].width) out[field] = dims[field].width as number;\n });\n return out;\n });\n const [groupExpansion, setGroupExpansion] = React.useState<Map<MGHGridRowId, boolean>>(() => new Map());\n const [editingCell, setEditingCell] = React.useState<CellCoords | null>(null);\n const [editValue, setEditValue] = React.useState<any>(undefined);\n const [focusedCell, setFocusedCell] = React.useState<CellCoords | null>(null);\n const pendingFocusRef = React.useRef(false);\n const [preferencePanel, setPreferencePanel] = React.useState<\n MGHGridPreferencePanelState & { anchorEl: HTMLElement | null }\n >({\n open: false,\n anchorEl: null,\n });\n const [columnMenu, setColumnMenu] = React.useState<{ field: string; anchorEl: HTMLElement } | null>(null);\n const [resizingField, setResizingField] = React.useState<string | null>(null);\n // While set, the grid renders every row (no pagination / virtualization) so the DOM can be printed.\n const [printState, setPrintState] = React.useState<MGHGridPrintExportOptions | null>(null);\n const printing = printState !== null;\n const [drag, setDrag] = React.useState<{ field: string; overField: string | null; side: 'left' | 'right' } | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const scrollRaf = React.useRef(0);\n const lastClickedIdRef = React.useRef<MGHGridRowId | null>(null);\n\n // Row updates (editing / api.updateRows) are kept until the `rows` prop identity changes.\n const [overrideState, setOverrideState] = React.useState<{ rows: R[]; map: Map<MGHGridRowId, R> }>(() => ({\n rows,\n map: new Map(),\n }));\n const rowOverrides: Map<MGHGridRowId, R> = overrideState.rows === rows ? overrideState.map : EMPTY_MAP;\n const setRowOverride = React.useCallback(\n (id: MGHGridRowId, row: R) => {\n setOverrideState((prev) => {\n const map = new Map(prev.rows === rows ? prev.map : []);\n map.set(id, row);\n return { rows, map };\n });\n },\n [rows]\n );\n\n /* ------------------------------------------------------------------ sizes */\n\n const { width: viewportWidth, height: viewportHeight } = useElementSize(scrollerRef);\n const densityFactor = DENSITY_FACTORS[density] ?? 1;\n const rowHeight = Math.round(rowHeightProp * densityFactor);\n const headerHeight = Math.round(columnHeaderHeight * densityFactor);\n\n /* ------------------------------------------------------------------ rows */\n\n const rowEntries = React.useMemo<RowEntry<R>[]>(() => {\n const out: RowEntry<R>[] = [];\n rows.forEach((raw) => {\n const id = getRowIdFromRow(raw, getRowId);\n if (id === undefined || id === null) return;\n out.push({ id, row: rowOverrides.get(id) ?? raw });\n });\n return out;\n }, [rows, getRowId, rowOverrides]);\n\n const rowsById = React.useMemo(() => {\n const map = new Map<MGHGridRowId, R>();\n rowEntries.forEach((entry) => map.set(entry.id, entry.row));\n (pinnedRows?.top ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n (pinnedRows?.bottom ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n return map;\n }, [rowEntries, pinnedRows, getRowId]);\n\n /* ------------------------------------------------------------------ columns */\n\n const userColumns = React.useMemo(() => columnsProp.map((col) => normalizeColumn(col)), [columnsProp]);\n\n const columnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef<R>>();\n userColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [userColumns]);\n\n const groupingFields = React.useMemo(\n () => (disableRowGrouping ? [] : rowGroupingModel.filter((field) => columnsByField.has(field))),\n [rowGroupingModel, columnsByField, disableRowGrouping]\n );\n const groupingActive = groupingFields.length > 0;\n\n const groupingColumn = React.useMemo<MGHGridColDef<R> | null>(() => {\n if (!groupingActive) return null;\n const single = groupingFields.length === 1 ? columnsByField.get(groupingFields[0]) : undefined;\n return normalizeColumn<R>({\n field: GROUPING_COLUMN_FIELD,\n headerName: single ? (single.headerName ?? single.field) : localeText.groupingColumnHeaderName,\n width: GROUPING_COLUMN_WIDTH,\n minWidth: 120,\n sortable: true,\n filterable: false,\n hideable: false,\n groupable: false,\n aggregable: false,\n editable: false,\n disableExport: true,\n disableReorder: true,\n ...(groupingColDef as any),\n });\n }, [groupingActive, groupingFields, columnsByField, localeText.groupingColumnHeaderName, groupingColDef]);\n\n const orderedUserColumns = React.useMemo(() => {\n if (!orderedFields || orderedFields.length === 0) return userColumns;\n const seen = new Set<string>();\n const out: MGHGridColDef<R>[] = [];\n orderedFields.forEach((field) => {\n const col = columnsByField.get(field);\n if (col && !seen.has(field)) {\n seen.add(field);\n out.push(col);\n }\n });\n userColumns.forEach((col) => {\n if (!seen.has(col.field)) out.push(col);\n });\n return out;\n }, [orderedFields, userColumns, columnsByField]);\n\n const isColumnVisible = React.useCallback(\n (field: string) => {\n const value = columnVisibilityModel[field];\n if (value === false) return false;\n if (value === undefined && groupingFields.indexOf(field) !== -1) return false;\n return true;\n },\n [columnVisibilityModel, groupingFields]\n );\n\n const visibleUserColumns = React.useMemo(() => {\n if (printState) {\n let cols = orderedUserColumns.filter((col) => isColumnVisible(col.field));\n if (printState.fields) {\n const wanted = new Set(printState.fields);\n cols = orderedUserColumns.filter((col) => wanted.has(col.field));\n } else if (printState.allColumns) {\n cols = orderedUserColumns;\n }\n return cols.filter((col) => !col.disableExport);\n }\n return orderedUserColumns.filter((col) => isColumnVisible(col.field));\n }, [orderedUserColumns, isColumnVisible, printState]);\n\n const layout = React.useMemo(() => {\n const internal: MGHGridColDef[] = [];\n if (checkboxSelection) internal.push(CHECKBOX_COLUMN_DEF);\n if (getDetailPanelContent) internal.push(DETAIL_PANEL_TOGGLE_COLUMN_DEF);\n const leftFields = disableColumnPinning ? [] : (pinnedColumns.left ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const rightFields = disableColumnPinning\n ? []\n : (pinnedColumns.right ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const visibleByField = new Map<string, MGHGridColDef>();\n visibleUserColumns.forEach((col) => visibleByField.set(col.field, col));\n const left: MGHGridColDef[] = internal.slice();\n if (groupingColumn) left.push(groupingColumn);\n leftFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col) left.push(col);\n });\n const right: MGHGridColDef[] = [];\n rightFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col && leftFields.indexOf(f) === -1) right.push(col);\n });\n const center = visibleUserColumns.filter(\n (col) => leftFields.indexOf(col.field) === -1 && rightFields.indexOf(col.field) === -1\n );\n const ordered = left.concat(center, right);\n const widths = computeWidths(ordered, viewportWidth, columnWidths);\n const hasPinning = left.length > internal.length + (groupingColumn ? 1 : 0) || right.length > 0;\n const columns: ColumnLayout[] = [];\n let x = 0;\n let leftOffset = 0;\n ordered.forEach((col, i) => {\n const width = widths[i];\n const isLeft = i < left.length;\n const isRight = i >= left.length + center.length;\n columns.push({\n col,\n width,\n pinned: isLeft ? 'left' : isRight ? 'right' : null,\n offset: isLeft ? leftOffset : 0,\n x,\n isLastLeft: isLeft && i === left.length - 1,\n isFirstRight: isRight && i === left.length + center.length,\n });\n if (isLeft) leftOffset += width;\n x += width;\n });\n let rightOffset = 0;\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n if (columns[i].pinned !== 'right') break;\n columns[i].offset = rightOffset;\n rightOffset += columns[i].width;\n }\n return { columns, totalWidth: x, hasPinning, leftCount: left.length, rightCount: right.length };\n }, [\n checkboxSelection,\n getDetailPanelContent,\n pinnedColumns,\n disableColumnPinning,\n visibleUserColumns,\n groupingColumn,\n viewportWidth,\n columnWidths,\n ]);\n\n const allDisplayColumnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n layout.columns.forEach((c) => map.set(c.col.field, c.col));\n if (groupingColumn) map.set(GROUPING_COLUMN_FIELD, groupingColumn);\n return map;\n }, [layout.columns, groupingColumn]);\n\n const getColumn = React.useCallback(\n (field: string): MGHGridColDef<R> | undefined =>\n columnsByField.get(field) ?? (allDisplayColumnsByField.get(field) as any),\n [columnsByField, allDisplayColumnsByField]\n );\n\n /* ------------------------------------------------------------------ filtering */\n\n const activeFilters = React.useMemo(() => {\n const out: Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }> = [];\n filterModel.items.forEach((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.filterable === false) return;\n const operator = getColumnFilterOperators(col).find((op) => op.value === item.operator);\n if (!operator) return;\n const fn = operator.getApplyFilterFn(item, col);\n if (fn) out.push({ col, fn });\n });\n return out;\n }, [filterModel.items, columnsByField]);\n\n const quickFilterValues = React.useMemo(\n () => (filterModel.quickFilterValues ?? []).map((v) => String(v).trim()).filter((v) => v !== ''),\n [filterModel.quickFilterValues]\n );\n\n const quickFilterColumns = React.useMemo(() => {\n const base = filterModel.quickFilterExcludeHiddenColumns ? visibleUserColumns : orderedUserColumns;\n return base.filter((col) => col.filterable !== false && col.type !== 'actions');\n }, [filterModel.quickFilterExcludeHiddenColumns, visibleUserColumns, orderedUserColumns]);\n\n const filteredEntries = React.useMemo(() => {\n if (activeFilters.length === 0 && quickFilterValues.length === 0) return rowEntries;\n const logicAnd = (filterModel.logicOperator ?? 'and') === 'and';\n const quickAnd = (filterModel.quickFilterLogicOperator ?? 'and') === 'and';\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const quickFns = quickFilterValues.map((needle) => {\n const lowered = needle.toLowerCase();\n const perColumn = quickFilterColumns.map((col) => {\n if (col.getApplyQuickFilterFn) {\n const custom = col.getApplyQuickFilterFn(needle, col, apiRefLocal);\n return custom ? { col, fn: custom } : null;\n }\n const fn: MGHGridApplyFilterFn<R> = (value, row) => {\n if (isNil(value)) return false;\n const formatted = formattedValueToString(getFormattedValue(value, row, col, apiRefLocal)).toLowerCase();\n if (formatted.indexOf(lowered) !== -1) return true;\n const raw = typeof value === 'object' ? '' : String(value).toLowerCase();\n return raw.indexOf(lowered) !== -1;\n };\n return { col, fn };\n });\n const active = perColumn.filter(Boolean) as Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }>;\n return (row: R) => active.some(({ col, fn }) => fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal));\n });\n return rowEntries.filter(({ row }) => {\n if (activeFilters.length > 0) {\n const results = activeFilters.map(({ col, fn }) =>\n fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal)\n );\n const pass = logicAnd ? results.every(Boolean) : results.some(Boolean);\n if (!pass) return false;\n }\n if (quickFns.length > 0) {\n const results = quickFns.map((fn) => fn(row));\n return quickAnd ? results.every(Boolean) : results.some(Boolean);\n }\n return true;\n });\n }, [\n rowEntries,\n activeFilters,\n quickFilterValues,\n quickFilterColumns,\n filterModel.logicOperator,\n filterModel.quickFilterLogicOperator,\n ]);\n\n /* ------------------------------------------------------------------ sorting */\n\n const compareEntries = React.useMemo(() => {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sorters = sortModel\n .filter((item) => item.sort && item.field !== GROUPING_COLUMN_FIELD)\n .map((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.sortable === false) return null;\n return {\n col,\n dir: item.sort === 'desc' ? -1 : 1,\n comparator: col.sortComparator ?? getDefaultComparator(col.type),\n };\n })\n .filter(Boolean) as Array<{ col: MGHGridColDef<R>; dir: number; comparator: any }>;\n if (sorters.length === 0) return null;\n return (a: RowEntry<R>, b: RowEntry<R>) => {\n for (let i = 0; i < sorters.length; i += 1) {\n const { col, dir, comparator } = sorters[i];\n const v1 = getCellValue(a.row, col, apiRefLocal);\n const v2 = getCellValue(b.row, col, apiRefLocal);\n const result = comparator(\n v1,\n v2,\n { id: a.id, field: col.field, value: v1, row: a.row, api: apiRefLocal },\n { id: b.id, field: col.field, value: v2, row: b.row, api: apiRefLocal }\n );\n if (result !== 0) return result * dir;\n }\n return 0;\n };\n }, [sortModel, columnsByField]);\n\n const sortEntries = React.useCallback(\n (entries: RowEntry<R>[]) => {\n if (!compareEntries) return entries;\n return entries\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => compareEntries(a.entry, b.entry) || a.index - b.index)\n .map((item) => item.entry);\n },\n [compareEntries]\n );\n\n /* ------------------------------------------------------------------ grouping + display rows */\n\n const aggregationFunctions = React.useMemo(\n () => ({ ...BUILT_IN_AGGREGATION_FUNCTIONS, ...aggregationFunctionsProp }),\n [aggregationFunctionsProp]\n );\n const aggregationActive = !disableAggregation && Object.keys(aggregationModel).length > 0;\n\n const isGroupExpanded = React.useCallback(\n (node: GroupTreeNode<R>) => {\n const override = groupExpansion.get(node.id);\n if (override !== undefined) return override;\n if (isGroupExpandedByDefault) {\n return isGroupExpandedByDefault({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: [],\n leafIds: [],\n isExpanded: false,\n });\n }\n return defaultGroupingExpansionDepth === -1 || node.depth < defaultGroupingExpansionDepth;\n },\n [groupExpansion, isGroupExpandedByDefault, defaultGroupingExpansionDepth]\n );\n\n const processed = React.useMemo(() => {\n const nodesById = new Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>();\n const groupsById = new Map<MGHGridRowId, GroupTreeNode<R>>();\n if (!groupingActive) {\n const sorted = sortEntries(filteredEntries);\n const displayRows: DisplayRow<R>[] = sorted.map((entry) => {\n const node: MGHGridLeafNode = { type: 'leaf', id: entry.id, depth: 0, parent: null };\n nodesById.set(entry.id, node);\n return { id: entry.id, type: 'leaf', row: entry.row, node, depth: 0 };\n });\n return { displayRows, sortedLeaves: sorted, nodesById, groupsById, tree: [] as GroupTreeNode<R>[] };\n }\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n let tree = buildGroupTree(filteredEntries, groupingFields, columnsByField, apiRefLocal);\n const groupingSort = sortModel.find((item) => item.field === GROUPING_COLUMN_FIELD && item.sort);\n const compareGroups = (depth: number) => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return null;\n const sortItem = groupingSort ?? sortModel.find((item) => item.field === field && item.sort);\n if (!sortItem) return null;\n const comparator = col.sortComparator ?? getDefaultComparator(col.type);\n const dir = sortItem.sort === 'desc' ? -1 : 1;\n return (a: GroupTreeNode<R>, b: GroupTreeNode<R>) =>\n comparator(\n a.groupingKey,\n b.groupingKey,\n { id: a.id, field, value: a.groupingKey, row: a.descendants[0]?.row, api: apiRefLocal },\n { id: b.id, field, value: b.groupingKey, row: b.descendants[0]?.row, api: apiRefLocal }\n ) * dir;\n };\n tree = sortGroupTree(tree, compareGroups, sortEntries);\n const displayRows = flattenGroupTree(tree, isGroupExpanded, nodesById, groupsById);\n return { displayRows, sortedLeaves: collectTreeLeaves(tree), nodesById, groupsById, tree };\n }, [groupingActive, filteredEntries, sortEntries, groupingFields, columnsByField, sortModel, isGroupExpanded]);\n\n const { displayRows, sortedLeaves, nodesById, groupsById } = processed;\n\n /* ------------------------------------------------------------------ pagination */\n\n const totalDisplayRows = displayRows.length;\n const paginate = pagination && !printing;\n const pageCount = pagination ? Math.max(1, Math.ceil(totalDisplayRows / Math.max(paginationModel.pageSize, 1))) : 1;\n const page = pagination ? clamp(paginationModel.page, 0, pageCount - 1) : 0;\n\n React.useEffect(() => {\n if (pagination && paginationModel.page !== page) {\n setPaginationModel({ ...paginationModel, page });\n }\n }, [pagination, paginationModel, page, setPaginationModel]);\n\n const pagedRows = React.useMemo(\n () =>\n paginate\n ? displayRows.slice(page * paginationModel.pageSize, (page + 1) * paginationModel.pageSize)\n : displayRows,\n [displayRows, paginate, page, paginationModel.pageSize]\n );\n\n /* ------------------------------------------------------------------ aggregation values */\n\n const footerAggregates = React.useMemo(() => {\n if (!aggregationActive || aggregationPosition === 'inline') return null;\n const rowsForFooter = sortedLeaves.map((entry) => entry.row);\n return aggregateRows(rowsForFooter, aggregationModel, columnsByField, aggregationFunctions, latest.current.api);\n }, [aggregationActive, aggregationPosition, sortedLeaves, aggregationModel, columnsByField, aggregationFunctions]);\n\n const groupAggregatesCache = React.useMemo(\n () => new Map<MGHGridRowId, Record<string, { value: any; fn: string }>>(),\n [pagedRows, aggregationModel, aggregationFunctions]\n );\n const getGroupAggregates = (group: GroupTreeNode<R>) => {\n if (!aggregationActive || aggregationPosition === 'footer') return undefined;\n let cached = groupAggregatesCache.get(group.id);\n if (!cached) {\n cached = aggregateRows(\n group.descendants.map((d) => d.row),\n aggregationModel,\n columnsByField,\n aggregationFunctions,\n latest.current.api\n );\n groupAggregatesCache.set(group.id, cached);\n }\n return cached;\n };\n\n /* ------------------------------------------------------------------ row heights + virtualization */\n\n const heights = React.useMemo(() => {\n const rowHeights: number[] = [];\n const detailHeights: number[] = [];\n const offsets: number[] = [];\n let total = 0;\n let hasAuto = autoHeight || disableVirtualization || printing;\n pagedRows.forEach((dr) => {\n let h = rowHeight;\n if (getRowHeight && dr.type === 'leaf' && dr.row) {\n const result = getRowHeight({ id: dr.id, model: dr.row, densityFactor });\n if (result === 'auto') hasAuto = true;\n else if (typeof result === 'number' && result > 0) h = result;\n }\n let d = 0;\n if (dr.type === 'leaf' && getDetailPanelContent && expandedDetailPanels.has(dr.id) && dr.row) {\n const dh = getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row })\n : DEFAULT_DETAIL_PANEL_HEIGHT;\n if (dh === 'auto') hasAuto = true;\n else d = dh;\n }\n rowHeights.push(h);\n detailHeights.push(d);\n offsets.push(total);\n total += h + d;\n });\n return { rowHeights, detailHeights, offsets, total, hasAuto };\n }, [\n pagedRows,\n rowHeight,\n getRowHeight,\n densityFactor,\n getDetailPanelContent,\n getDetailPanelHeight,\n expandedDetailPanels,\n autoHeight,\n disableVirtualization,\n printing,\n ]);\n\n const virtual = !heights.hasAuto;\n\n /* ------------------------------------------------------------------ print */\n\n const startPrint = (options: MGHGridPrintExportOptions = {}) => {\n if (printState) return;\n const resolved: MGHGridPrintExportOptions = {\n title: typeof header === 'string' ? header : undefined,\n ...options,\n };\n if (!cardRef.current || typeof window === 'undefined') return;\n setPrintState(resolved);\n };\n\n React.useEffect(() => {\n if (!printState) return undefined;\n // The un-virtualized rows are already committed when this effect runs; a short timeout lets the\n // browser lay them out first. (A timeout rather than rAF so it also fires in hidden/background tabs.)\n const timer = window.setTimeout(() => {\n if (!cardRef.current) return;\n printGridElement({\n cardElement: cardRef.current,\n options: printState,\n onDone: () => setPrintState(null),\n });\n }, 50);\n return () => window.clearTimeout(timer);\n }, [printState]);\n\n const virtualRange = React.useMemo(() => {\n const count = pagedRows.length;\n if (!virtual || count === 0) return { start: 0, end: count };\n const overscan = OVERSCAN_ROWS * rowHeight;\n const viewTop = Math.max(0, scrollTop - headerHeight - overscan);\n const viewBottom = scrollTop + Math.max(viewportHeight, rowHeight) + overscan;\n const { offsets } = heights;\n let lo = 0;\n let hi = count - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] + heights.rowHeights[mid] + heights.detailHeights[mid] < viewTop) lo = mid + 1;\n else hi = mid;\n }\n const start = lo;\n let end = start;\n while (end < count && offsets[end] < viewBottom) end += 1;\n return { start, end };\n }, [virtual, pagedRows.length, scrollTop, viewportHeight, rowHeight, headerHeight, heights]);\n\n const handleScroll = React.useCallback(() => {\n if (!latest.current.virtual) return;\n if (scrollRaf.current) return;\n scrollRaf.current = window.requestAnimationFrame(() => {\n scrollRaf.current = 0;\n if (scrollerRef.current) setScrollTop(scrollerRef.current.scrollTop);\n });\n }, []);\n\n React.useEffect(\n () => () => {\n if (scrollRaf.current) window.cancelAnimationFrame(scrollRaf.current);\n },\n []\n );\n\n /* ------------------------------------------------------------------ selection */\n\n const isRowSelectableFn = React.useCallback(\n (id: MGHGridRowId, row: R | null | undefined) => {\n if (!row) return false;\n if (!isRowSelectable) return true;\n return isRowSelectable({ id, row, columns: orderedUserColumns, api: latest.current.api });\n },\n [isRowSelectable, orderedUserColumns]\n );\n\n const selectionCandidates = React.useMemo(() => {\n const source: RowEntry<R>[] = checkboxSelectionVisibleOnly\n ? (pagedRows\n .filter((dr) => dr.type === 'leaf' && dr.row)\n .map((dr) => ({ id: dr.id, row: dr.row as R })) as RowEntry<R>[])\n : sortedLeaves;\n return source.filter((entry) => isRowSelectableFn(entry.id, entry.row)).map((entry) => entry.id);\n }, [checkboxSelectionVisibleOnly, pagedRows, sortedLeaves, isRowSelectableFn]);\n\n const selectedCandidateCount = React.useMemo(\n () => selectionCandidates.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0),\n [selectionCandidates, selectedIds]\n );\n const allCandidatesSelected = selectionCandidates.length > 0 && selectedCandidateCount === selectionCandidates.length;\n const someCandidatesSelected = selectedCandidateCount > 0 && !allCandidatesSelected;\n\n const updateSelection = React.useCallback(\n (updater: (prev: Set<MGHGridRowId>) => Set<MGHGridRowId>) => {\n setSelectedIds((prev) => {\n const next = updater(prev);\n return selectionModelsEqual({ type: 'include', ids: prev }, { type: 'include', ids: next }) ? prev : next;\n });\n },\n [setSelectedIds]\n );\n\n const selectRows = React.useCallback(\n (ids: MGHGridRowId[], isSelected = true, resetSelection = false) => {\n updateSelection((prev) => {\n const next = resetSelection ? new Set<MGHGridRowId>() : new Set(prev);\n ids.forEach((id) => {\n if (isSelected) {\n if (isRowSelectableFn(id, rowsById.get(id))) next.add(id);\n } else next.delete(id);\n });\n if (disableMultipleRowSelection && next.size > 1) {\n const lastId = ids[ids.length - 1];\n return new Set<MGHGridRowId>(isSelected && next.has(lastId) ? [lastId] : []);\n }\n return next;\n });\n },\n [updateSelection, isRowSelectableFn, rowsById, disableMultipleRowSelection]\n );\n\n React.useEffect(() => {\n if (keepNonExistentRowsSelected || selectedIds.size === 0) return;\n let changed = false;\n const next = new Set<MGHGridRowId>();\n selectedIds.forEach((id) => {\n if (rowsById.has(id)) next.add(id);\n else changed = true;\n });\n if (changed) setSelectedIds(next);\n }, [rowsById, keepNonExistentRowsSelected, selectedIds, setSelectedIds]);\n\n const toggleAllCandidates = () => {\n if (allCandidatesSelected) selectRows(selectionCandidates, false);\n else selectRows(selectionCandidates, true);\n };\n\n const handleRowSelectionClick = (renderRow: RenderRow<R>, event: React.MouseEvent) => {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const allSelected = leafIds.every((id) => selectedIds.has(id));\n selectRows(leafIds, !allSelected, false);\n return;\n }\n if (renderRow.kind !== 'leaf') return;\n const id = renderRow.id;\n if (!isRowSelectableFn(id, renderRow.row)) return;\n const multiple = !disableMultipleRowSelection;\n if (event.shiftKey && multiple && lastClickedIdRef.current !== null) {\n const ids = pagedRows.filter((dr) => dr.type === 'leaf').map((dr) => dr.id);\n const from = ids.indexOf(lastClickedIdRef.current);\n const to = ids.indexOf(id);\n if (from !== -1 && to !== -1) {\n const [a, b] = from < to ? [from, to] : [to, from];\n selectRows(ids.slice(a, b + 1), true, !checkboxSelection && !event.ctrlKey && !event.metaKey);\n return;\n }\n }\n lastClickedIdRef.current = id;\n const isSelected = selectedIds.has(id);\n const resetSelection = !checkboxSelection && !event.ctrlKey && !event.metaKey;\n if (resetSelection) {\n if (isSelected && selectedIds.size === 1) selectRows([id], false, true);\n else selectRows([id], true, true);\n } else {\n selectRows([id], !isSelected, false);\n }\n };\n\n /* ------------------------------------------------------------------ sorting helpers */\n\n const sortColumn = (field: string, direction?: MGHGridSortDirection, allowMultiple = false) => {\n const col = getColumn(field);\n if (!col || col.sortable === false || disableColumnSorting) return;\n const current = sortModel.find((item) => item.field === field);\n let next: MGHGridSortDirection;\n if (direction === undefined) {\n const order = col.sortingOrder ?? sortingOrder;\n const index = order.indexOf(current?.sort ?? null);\n next = order[(index + 1) % order.length];\n } else {\n next = direction;\n }\n let model: MGHGridSortModel;\n if (allowMultiple && !disableMultipleColumnsSorting) {\n model = sortModel.filter((item) => item.field !== field);\n if (next)\n model = current\n ? sortModel.map((item) => (item.field === field ? { field, sort: next } : item))\n : model.concat([{ field, sort: next }]);\n } else {\n model = next ? [{ field, sort: next }] : [];\n }\n setSortModel(model);\n };\n\n /* ------------------------------------------------------------------ column helpers */\n\n const persistOrder = (fields: string[]) => {\n if (columnOrderStorageKey) writeLocalStorage(columnOrderStorageKey, fields);\n };\n\n const persistWidths = (widths: Record<string, number>) => {\n if (columnWidthStorageKey) writeLocalStorage(columnWidthStorageKey, widths);\n };\n\n const setColumnIndex = (field: string, targetIndex: number, event: React.DragEvent | null = null) => {\n const fields = orderedUserColumns.map((c) => c.field);\n const oldIndex = fields.indexOf(field);\n if (oldIndex === -1) return;\n const next = moveItem(fields, oldIndex, clamp(targetIndex, 0, fields.length - 1));\n setOrderedFields(next);\n persistOrder(next);\n const col = columnsByField.get(field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex, oldIndex }, event, getDetails());\n };\n\n const setColumnWidth = (field: string, width: number) => {\n const col = getColumn(field);\n if (!col) return;\n const clamped = clamp(width, col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n setColumnWidths((prev) => {\n const next = { ...prev, [field]: clamped };\n persistWidths(next);\n return next;\n });\n onColumnWidthChange?.({ colDef: col, width: clamped }, getDetails());\n };\n\n const autosizeColumns = (options: { columns?: string[]; includeHeaders?: boolean; expand?: boolean } = {}) => {\n const includeHeaders = options.includeHeaders ?? true;\n const targets = layout.columns.filter(\n (lc) => !isInternalField(lc.col.field) && (!options.columns || options.columns.indexOf(lc.col.field) !== -1)\n );\n if (targets.length === 0) return;\n const root = rootRef.current;\n const computed = root && typeof window !== 'undefined' ? window.getComputedStyle(root) : null;\n const fontFamily = computed?.fontFamily || 'sans-serif';\n const cellFont = `400 14px ${fontFamily}`;\n const headerFont = `600 14px ${fontFamily}`;\n const sample = sortedLeaves.slice(0, 500);\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const next = { ...columnWidths };\n targets.forEach(({ col }) => {\n let max = includeHeaders ? measureText(col.headerName ?? col.field, headerFont) + 64 : 0;\n sample.forEach((entry) => {\n const value = getCellValue(entry.row, col, apiRefLocal);\n const text = formattedValueToString(getFormattedValue(value, entry.row, col, apiRefLocal, entry.id));\n const w = measureText(text, cellFont) + 24;\n if (w > max) max = w;\n });\n next[col.field] = clamp(Math.ceil(max), col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n });\n setColumnWidths(next);\n persistWidths(next);\n };\n\n const pinColumn = (field: string, side: MGHGridPinnedSide) => {\n if (disableColumnPinning) return;\n const left = (pinnedColumns.left ?? []).filter((f) => f !== field);\n const right = (pinnedColumns.right ?? []).filter((f) => f !== field);\n if (side === 'left') left.push(field);\n else right.unshift(field);\n setPinnedColumns({ left, right });\n };\n\n const unpinColumn = (field: string) => {\n setPinnedColumns({\n left: (pinnedColumns.left ?? []).filter((f) => f !== field),\n right: (pinnedColumns.right ?? []).filter((f) => f !== field),\n });\n };\n\n const isColumnPinned = (field: string): MGHGridPinnedSide | false => {\n if (disableColumnPinning) return false;\n if ((pinnedColumns.left ?? []).indexOf(field) !== -1) return 'left';\n if ((pinnedColumns.right ?? []).indexOf(field) !== -1) return 'right';\n return false;\n };\n\n /* ------------------------------------------------------------------ filter helpers */\n\n const upsertFilterItems = (items: MGHGridFilterItem[]) => {\n let nextItems = filterModel.items.slice();\n items.forEach((item) => {\n const withId =\n item.id === undefined ? { ...item, id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } : item;\n const index = nextItems.findIndex((existing) => existing.id !== undefined && existing.id === withId.id);\n if (index === -1) nextItems.push(withId);\n else nextItems[index] = withId;\n });\n if (disableMultipleColumnsFiltering && nextItems.length > 1) nextItems = nextItems.slice(-1);\n setFilterModel({ ...filterModel, items: nextItems });\n };\n\n const deleteFilterItem = (item: MGHGridFilterItem) => {\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((existing) =>\n item.id !== undefined ? existing.id !== item.id : existing !== item\n ),\n });\n };\n\n const showPreferences = (panel: 'columns' | 'filters', anchorEl?: HTMLElement | null, targetField?: string) => {\n setColumnMenu(null);\n setPreferencePanel({\n open: true,\n openedPanelValue: panel,\n targetField,\n anchorEl: anchorEl ?? toolbarRef.current ?? rootRef.current,\n });\n };\n\n const hidePreferences = React.useCallback(() => {\n setPreferencePanel((prev) => (prev.open ? { open: false, anchorEl: null } : prev));\n }, []);\n\n /* ------------------------------------------------------------------ editing */\n\n const isCellEditableFn = (params: MGHGridCellParams<R>) => {\n if (!params.colDef.editable) return false;\n if (params.rowNode.type !== 'leaf') return false;\n return isCellEditable ? isCellEditable(params) : true;\n };\n\n const startCellEditMode = (id: MGHGridRowId, field: string) => {\n const row = rowsById.get(id);\n const col = getColumn(field);\n if (!row || !col) return;\n const params = buildCellParams(id, field, row, nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null });\n if (!isCellEditableFn(params)) return;\n setEditingCell({ id, field });\n setEditValue(params.value);\n setFocusedCell({ id, field });\n };\n\n const applyRowUpdate = (id: MGHGridRowId, newRow: R, oldRow: R) => {\n if (processRowUpdate) {\n Promise.resolve()\n .then(() => processRowUpdate(newRow, oldRow, { rowId: id }))\n .then((result) => setRowOverride(id, (result ?? newRow) as R))\n .catch((error) => {\n if (onProcessRowUpdateError) onProcessRowUpdateError(error);\n else console.error('MGHGrid: processRowUpdate failed', error);\n });\n } else {\n setRowOverride(id, newRow);\n }\n };\n\n const stopCellEditMode = (\n id: MGHGridRowId,\n field: string,\n ignoreModifications = false,\n reason: 'enterKeyDown' | 'escapeKeyDown' | 'cellFocusOut' | 'tabKeyDown' | 'api' = 'api'\n ) => {\n if (!editingCell || editingCell.id !== id || editingCell.field !== field) return;\n const row = rowsById.get(id);\n const col = getColumn(field);\n setEditingCell(null);\n if (!row || !col) return;\n if (!ignoreModifications) {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const parsed = col.valueParser\n ? col.valueParser(editValue, row, col, apiRefLocal)\n : parseEditValue(editValue, col);\n const currentValue = getCellValue(row, col, apiRefLocal);\n if (!Object.is(parsed, currentValue)) {\n const newRow = col.valueSetter\n ? col.valueSetter(parsed, row, col, apiRefLocal)\n : ({ ...row, [field]: parsed } as R);\n applyRowUpdate(id, newRow, row);\n }\n }\n onCellEditStop?.({ id, field, row, reason }, getDetails());\n pendingFocusRef.current = true;\n setFocusedCell({ id, field });\n };\n\n /* ------------------------------------------------------------------ detail panel & grouping helpers */\n\n const toggleDetailPanel = (id: MGHGridRowId) => {\n setExpandedDetailPanels((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const setRowChildrenExpansion = (id: MGHGridRowId, isExpanded: boolean) => {\n setGroupExpansion((prev) => {\n const next = new Map(prev);\n next.set(id, isExpanded);\n return next;\n });\n };\n\n const groupingKey = groupingFields.join('|');\n const previousGroupingKey = React.useRef(groupingKey);\n React.useEffect(() => {\n if (previousGroupingKey.current === groupingKey) return;\n previousGroupingKey.current = groupingKey;\n setGroupExpansion(new Map());\n }, [groupingKey]);\n\n /* ------------------------------------------------------------------ cell params */\n\n const buildCellParams = (id: MGHGridRowId, field: string, row: R, node: MGHGridRowNode): MGHGridCellParams<R> => {\n const col = getColumn(field) as MGHGridColDef<R>;\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const value = getCellValue(row, col, apiRefLocal);\n const formattedValue = getFormattedValue(value, row, col, apiRefLocal, id);\n const hasFocus = Boolean(focusedCell && focusedCell.id === id && focusedCell.field === field);\n const cellMode = editingCell && editingCell.id === id && editingCell.field === field ? 'edit' : 'view';\n return {\n id,\n field,\n value,\n formattedValue,\n row,\n rowNode: node,\n colDef: col,\n api: apiRefLocal,\n hasFocus,\n tabIndex: hasFocus ? 0 : -1,\n cellMode,\n isEditable: Boolean(col.editable) && node.type === 'leaf',\n };\n };\n\n const buildRowParams = (id: MGHGridRowId, row: R): MGHGridRowParams<R> => ({\n id,\n row,\n columns: orderedUserColumns,\n api: latest.current.api,\n });\n\n /* ------------------------------------------------------------------ keyboard navigation */\n\n React.useEffect(() => {\n if (!pendingFocusRef.current || !focusedCell || !rootRef.current) return;\n pendingFocusRef.current = false;\n const selector = `[data-mgh-row-id=\"${String(focusedCell.id).replace(/\"/g, '\\\\\"')}\"] [data-mgh-field=\"${focusedCell.field.replace(/\"/g, '\\\\\"')}\"]`;\n const el = rootRef.current.querySelector<HTMLElement>(selector);\n if (el && document.activeElement !== el && !el.contains(document.activeElement)) el.focus({ preventScroll: true });\n }, [focusedCell, virtualRange.start, virtualRange.end]);\n\n const scrollToIndexes = (params: { rowIndex?: number; colIndex?: number }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return false;\n if (params.rowIndex !== undefined && virtual) {\n const index = clamp(params.rowIndex, 0, Math.max(pagedRows.length - 1, 0));\n const top = heights.offsets[index] ?? 0;\n const bottom = top + (heights.rowHeights[index] ?? rowHeight);\n const visibleTop = scroller.scrollTop;\n const visibleBottom = scroller.scrollTop + scroller.clientHeight - headerHeight;\n if (top < visibleTop) scroller.scrollTop = top;\n else if (bottom > visibleBottom) scroller.scrollTop = bottom - (scroller.clientHeight - headerHeight);\n } else if (params.rowIndex !== undefined) {\n const el = scroller.querySelector(`[data-mgh-row-index=\"${params.rowIndex}\"]`) as HTMLElement | null | undefined;\n el?.scrollIntoView?.({ block: 'nearest' });\n }\n if (params.colIndex !== undefined) {\n const lc = layout.columns[clamp(params.colIndex, 0, layout.columns.length - 1)];\n if (lc && !lc.pinned) {\n const leftPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'left')\n .reduce((acc, c) => acc + c.width, 0);\n const rightPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'right')\n .reduce((acc, c) => acc + c.width, 0);\n const visibleLeft = scroller.scrollLeft + leftPinnedWidth;\n const visibleRight = scroller.scrollLeft + scroller.clientWidth - rightPinnedWidth;\n if (lc.x < visibleLeft) scroller.scrollLeft = lc.x - leftPinnedWidth;\n else if (lc.x + lc.width > visibleRight)\n scroller.scrollLeft = lc.x + lc.width - scroller.clientWidth + rightPinnedWidth;\n }\n }\n return true;\n };\n\n const moveFocus = (\n rowDelta: number,\n colDelta: number,\n absolute?: { row?: 'first' | 'last'; col?: 'first' | 'last' }\n ) => {\n if (pagedRows.length === 0 || layout.columns.length === 0) return;\n let rowIndex = focusedCell ? pagedRows.findIndex((dr) => dr.id === focusedCell.id) : -1;\n let colIndex = focusedCell ? layout.columns.findIndex((lc) => lc.col.field === focusedCell.field) : -1;\n if (rowIndex === -1) rowIndex = 0;\n if (colIndex === -1) colIndex = 0;\n if (absolute?.row === 'first') rowIndex = 0;\n else if (absolute?.row === 'last') rowIndex = pagedRows.length - 1;\n else rowIndex = clamp(rowIndex + rowDelta, 0, pagedRows.length - 1);\n if (absolute?.col === 'first') colIndex = 0;\n else if (absolute?.col === 'last') colIndex = layout.columns.length - 1;\n else colIndex = clamp(colIndex + colDelta, 0, layout.columns.length - 1);\n const target = { id: pagedRows[rowIndex].id, field: layout.columns[colIndex].col.field };\n pendingFocusRef.current = true;\n setFocusedCell(target);\n scrollToIndexes({ rowIndex, colIndex });\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (editingCell) return;\n const target = event.target as HTMLElement;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'SELECT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'BUTTON')\n ) {\n return;\n }\n const pageRows = Math.max(1, Math.floor(Math.max(viewportHeight - headerHeight, rowHeight) / rowHeight));\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1, 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1, 0);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(0, -1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(0, 1);\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(pageRows, 0);\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(-pageRows, 0);\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'first', col: 'first' } : { col: 'first' });\n break;\n case 'End':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'last', col: 'last' } : { col: 'last' });\n break;\n case 'Enter':\n case 'F2':\n if (focusedCell) {\n const node = nodesById.get(focusedCell.id);\n if (node?.type === 'group' && focusedCell.field === GROUPING_COLUMN_FIELD) {\n const group = groupsById.get(focusedCell.id);\n if (group) setRowChildrenExpansion(group.id, !isGroupExpanded(group));\n } else {\n event.preventDefault();\n startCellEditMode(focusedCell.id, focusedCell.field);\n }\n }\n break;\n case ' ':\n if (focusedCell && (checkboxSelection || !disableRowSelectionOnClick)) {\n const dr = pagedRows.find((r) => r.id === focusedCell.id);\n if (dr && dr.type === 'leaf' && dr.row) {\n event.preventDefault();\n selectRows([dr.id], !selectedIds.has(dr.id), false);\n }\n }\n break;\n case 'Escape':\n if (preferencePanel.open) hidePreferences();\n if (columnMenu) setColumnMenu(null);\n break;\n default:\n if (\n (event.ctrlKey || event.metaKey) &&\n event.key.toLowerCase() === 'a' &&\n checkboxSelection &&\n !disableMultipleRowSelection\n ) {\n event.preventDefault();\n selectRows(selectionCandidates, true);\n }\n }\n };\n\n /* ------------------------------------------------------------------ drag & drop (reorder) */\n\n const canReorder = (col: MGHGridColDef) => !disableColumnReorder && !col.disableReorder && !isInternalField(col.field);\n\n const handleDrop = (targetLc: ColumnLayout, event: React.DragEvent) => {\n event.preventDefault();\n const current = drag;\n setDrag(null);\n if (!current || current.field === targetLc.col.field) return;\n const sourceLc = layout.columns.find((lc) => lc.col.field === current.field);\n if (!sourceLc || sourceLc.pinned !== targetLc.pinned || !canReorder(targetLc.col)) return;\n const side = current.side;\n if (sourceLc.pinned) {\n const key = sourceLc.pinned;\n const list = (pinnedColumns[key] ?? []).slice();\n const from = list.indexOf(current.field);\n let to = list.indexOf(targetLc.col.field);\n if (from === -1 || to === -1) return;\n list.splice(from, 1);\n to = list.indexOf(targetLc.col.field);\n list.splice(side === 'right' ? to + 1 : to, 0, current.field);\n setPinnedColumns({ ...pinnedColumns, [key]: list });\n return;\n }\n const fields = orderedUserColumns.map((c) => c.field);\n const from = fields.indexOf(current.field);\n const without = fields.filter((f) => f !== current.field);\n let to = without.indexOf(targetLc.col.field);\n if (side === 'right') to += 1;\n without.splice(to, 0, current.field);\n setOrderedFields(without);\n persistOrder(without);\n const col = columnsByField.get(current.field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex: to, oldIndex: from }, event, getDetails());\n };\n\n /* ------------------------------------------------------------------ resize */\n\n const resizeRef = React.useRef<{\n field: string;\n startX: number;\n startWidth: number;\n lastWidth: number;\n min: number;\n max: number;\n } | null>(null);\n\n const handleResizeStart = (lc: ColumnLayout, event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n field: lc.col.field,\n startX: event.clientX,\n startWidth: lc.width,\n lastWidth: lc.width,\n min: lc.col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n max: lc.col.maxWidth ?? Infinity,\n };\n setResizingField(lc.col.field);\n const onMove = (e: PointerEvent) => {\n const r = resizeRef.current;\n if (!r) return;\n const width = clamp(r.startWidth + (e.clientX - r.startX), r.min, r.max);\n r.lastWidth = width;\n setColumnWidths((prev) => (prev[r.field] === width ? prev : { ...prev, [r.field]: width }));\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n const r = resizeRef.current;\n resizeRef.current = null;\n setResizingField(null);\n if (!r) return;\n const next = { ...(latest.current.columnWidths as Record<string, number>), [r.field]: r.lastWidth };\n setColumnWidths(next);\n persistWidths(next);\n const col = latest.current.getColumn(r.field);\n if (col && r.lastWidth !== r.startWidth)\n onColumnWidthChange?.({ colDef: col, width: r.lastWidth }, getDetails());\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /* ------------------------------------------------------------------ state snapshot & API */\n\n const filterCount = activeFilters.length;\n const rowCount = groupingActive ? totalDisplayRows : filteredEntries.length;\n\n const state = React.useMemo<MGHGridState>(\n () => ({\n sortModel,\n filterModel,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n pageCount,\n rowCount,\n totalRowCount: rowEntries.length,\n columnVisibilityModel,\n orderedFields: orderedUserColumns.map((c) => c.field),\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n rowSelectionModel: { type: 'include', ids: selectedIds },\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel: {\n open: preferencePanel.open,\n openedPanelValue: preferencePanel.openedPanelValue,\n targetField: preferencePanel.targetField,\n },\n filterCount,\n quickFilterValues,\n }),\n [\n sortModel,\n filterModel,\n page,\n paginationModel.pageSize,\n pageCount,\n rowCount,\n rowEntries.length,\n columnVisibilityModel,\n orderedUserColumns,\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n selectedIds,\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel.open,\n preferencePanel.openedPanelValue,\n preferencePanel.targetField,\n filterCount,\n quickFilterValues,\n ]\n );\n\n latest.current = {\n api: apiObject,\n state,\n rowsById,\n rowEntries,\n nodesById,\n groupsById,\n sortedLeaves,\n pagedRows,\n getRowId,\n setRowOverride,\n orderedUserColumns,\n visibleUserColumns,\n getColumn,\n columnVisibilityModel,\n setColumnVisibilityModel,\n setColumnWidth,\n setColumnIndex,\n columnWidths,\n autosizeColumns,\n pinColumn,\n unpinColumn,\n isColumnPinned,\n pinnedColumns,\n setPinnedColumns,\n sortModel,\n setSortModel,\n sortColumn,\n filterModel,\n setFilterModel,\n upsertFilterItems,\n deleteFilterItem,\n showPreferences,\n hidePreferences,\n selectedIds,\n setSelectedIds,\n selectRows,\n isRowSelectableFn,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n setPaginationModel,\n setDensity,\n toggleDetailPanel,\n expandedDetailPanels,\n setExpandedDetailPanels,\n rowGroupingModel,\n setRowGroupingModel,\n setRowChildrenExpansion,\n aggregationModel,\n setAggregationModel,\n startCellEditMode,\n stopCellEditMode,\n editingCell,\n setEditValue,\n buildCellParams,\n setFocusedCell,\n scrollToIndexes,\n forceUpdate,\n virtual,\n startPrint,\n };\n\n if (apiRef) apiRef.current = apiObject;\n\n React.useEffect(() => {\n onStateChange?.(state, { api: apiObject });\n }, [state, onStateChange, apiObject]);\n\n /* ------------------------------------------------------------------ context */\n\n const rootProps = React.useMemo<MGHGridRootProps>(\n () => ({\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n }),\n [\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n ]\n );\n\n const contextValue = React.useMemo<MGHGridContextValue>(\n () => ({\n api: apiObject,\n state,\n localeText,\n themeMode,\n rootProps,\n columns: orderedUserColumns,\n visibleColumns: visibleUserColumns,\n }),\n [apiObject, state, localeText, themeMode, rootProps, orderedUserColumns, visibleUserColumns]\n );\n\n /* ------------------------------------------------------------------ rendering: cells */\n\n const renderEditor = (params: MGHGridCellParams<R>) => {\n const col = params.colDef;\n const commit = (reason: 'enterKeyDown' | 'cellFocusOut' | 'tabKeyDown') =>\n stopCellEditMode(params.id, params.field, false, reason);\n const cancel = () => stopCellEditMode(params.id, params.field, true, 'escapeKeyDown');\n const keyHandler = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n commit('enterKeyDown');\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n } else if (event.key === 'Tab') {\n commit('tabKeyDown');\n } else {\n event.stopPropagation();\n }\n };\n if (col.renderEditCell) {\n return col.renderEditCell({\n ...params,\n editValue,\n onValueChange: setEditValue,\n commit: () => commit('enterKeyDown'),\n cancel,\n });\n }\n const common = {\n autoFocus: true,\n onKeyDown: keyHandler,\n onBlur: () => commit('cellFocusOut'),\n onClick: (event: React.MouseEvent) => event.stopPropagation(),\n };\n switch (col.type) {\n case 'boolean':\n return (\n <Checkbox\n {...common}\n checked={Boolean(editValue)}\n onChange={(event) => setEditValue(event.target.checked)}\n />\n );\n case 'singleSelect': {\n const options = resolveValueOptions(col, params.row, params.id);\n return (\n <Select\n {...common}\n size=\"small\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(col, o)) === event.target.value);\n setEditValue(match !== undefined ? getOptionValue(col, match) : event.target.value);\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(col, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(col, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'number':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"number\"\n value={editValue === undefined || editValue === null ? '' : editValue}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n case 'date':\n case 'dateTime':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type={col.type === 'date' ? 'date' : 'datetime-local'}\n value={\n typeof editValue === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(editValue)\n ? editValue\n : toDateInputValue(editValue, col.type === 'dateTime')\n }\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n default:\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"text\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n }\n };\n\n const renderCellContent = (lc: ColumnLayout, renderRow: RenderRow<R>): React.ReactNode => {\n const { col } = lc;\n const field = col.field;\n\n if (field === CHECKBOX_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const selectedCount = leafIds.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0);\n return (\n <Checkbox\n checked={leafIds.length > 0 && selectedCount === leafIds.length}\n indeterminate={selectedCount > 0 && selectedCount < leafIds.length}\n label={localeText.checkboxSelectionSelectRow}\n onClick={(event) => event.stopPropagation()}\n onChange={() => selectRows(leafIds, selectedCount !== leafIds.length, false)}\n />\n );\n }\n if (renderRow.kind !== 'leaf') return null;\n const selectable = isRowSelectableFn(renderRow.id, renderRow.row);\n const checked = selectedIds.has(renderRow.id);\n return (\n <Checkbox\n checked={checked}\n disabled={!selectable}\n label={checked ? localeText.checkboxSelectionUnselectRow : localeText.checkboxSelectionSelectRow}\n tabIndex={-1}\n onClick={(event) => event.stopPropagation()}\n onChange={() => {\n lastClickedIdRef.current = renderRow.id;\n selectRows([renderRow.id], !checked, disableMultipleRowSelection);\n }}\n />\n );\n }\n\n if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n if (renderRow.kind !== 'leaf' || !renderRow.row) return null;\n const expanded = expandedDetailPanels.has(renderRow.id);\n const content = getDetailPanelContent?.(buildRowParams(renderRow.id, renderRow.row));\n if (content === null || content === undefined || content === false) return null;\n return (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-detail-toggle', expanded && 'mgh-grid-detail-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n toggleDetailPanel(renderRow.id);\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n );\n }\n\n if (field === GROUPING_COLUMN_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const group = renderRow.group;\n const expanded = isGroupExpanded(group);\n const hideCount = (groupingColDef as any)?.hideDescendantCount;\n return (\n <div className=\"mgh-grid-group-cell\" style={{ paddingLeft: renderRow.depth * 20 }}>\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-group-toggle', expanded && 'mgh-grid-group-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setRowChildrenExpansion(group.id, !expanded);\n }}\n >\n <ChevronRightIcon />\n </IconButton>\n <span className=\"mgh-grid-group-label\" title={group.groupingLabel}>\n {group.groupingLabel}\n </span>\n {!hideCount && <span className=\"mgh-grid-group-count\">({group.descendants.length})</span>}\n </div>\n );\n }\n return null;\n }\n\n if (renderRow.kind === 'group' || renderRow.kind === 'footer') {\n const agg = renderRow.aggregates?.[field];\n if (!agg || isNil(agg.value)) return null;\n const fn = aggregationFunctions[agg.fn];\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sampleRow = (renderRow.group?.descendants[0]?.row ?? latest.current.sortedLeaves[0]?.row ?? {}) as R;\n const formatted = fn?.valueFormatter\n ? fn.valueFormatter(agg.value)\n : col.valueFormatter\n ? col.valueFormatter(agg.value, sampleRow, col as MGHGridColDef<R>, apiRefLocal)\n : defaultFormatValue(agg.value, col);\n return (\n <>\n <span className=\"mgh-grid-aggregation-label\">{fn?.label ?? agg.fn}</span>\n <span className=\"mgh-grid-cell-text\">{formattedValueToString(formatted)}</span>\n </>\n );\n }\n\n if (!renderRow.row) return null;\n const params = buildCellParams(renderRow.id, field, renderRow.row, renderRow.node);\n\n if (params.cellMode === 'edit') return renderEditor(params);\n\n if (col.renderCell) return col.renderCell(params);\n\n if (col.type === 'actions') {\n const actions = col.getActions ? col.getActions(buildRowParams(renderRow.id, renderRow.row)) : [];\n return <ActionsCell actions={actions} themeMode={themeMode} moreLabel={localeText.actionsCellMore} />;\n }\n\n if (col.type === 'boolean') {\n if (isNil(params.value)) return null;\n return params.value ? (\n <CheckIcon aria-label={localeText.booleanCellTrueLabel} />\n ) : (\n <CloseIcon aria-label={localeText.booleanCellFalseLabel} />\n );\n }\n\n const formatted = params.formattedValue;\n if (formatted === null || formatted === undefined) return null;\n if (React.isValidElement(formatted)) return formatted;\n const text = formattedValueToString(formatted);\n return (\n <span className=\"mgh-grid-cell-text\" title={text.length > 20 ? text : undefined}>\n {text}\n </span>\n );\n };\n\n const cellStyle = (lc: ColumnLayout): React.CSSProperties => ({\n width: lc.width,\n minWidth: lc.width,\n maxWidth: lc.width,\n left: lc.pinned === 'left' ? lc.offset : undefined,\n right: lc.pinned === 'right' ? lc.offset : undefined,\n });\n\n const pinnedClasses = (lc: ColumnLayout, prefix: string) =>\n cx(\n lc.pinned === 'left' && `${prefix}--pinned-left`,\n lc.pinned === 'right' && `${prefix}--pinned-right`,\n lc.isLastLeft && layout.hasPinning && `${prefix}--pinned-left-last`,\n lc.isFirstRight && `${prefix}--pinned-right-first`\n );\n\n const renderCell = (lc: ColumnLayout, renderRow: RenderRow<R>, isAutoRow: boolean) => {\n const { col } = lc;\n const field = col.field;\n const isFocused = Boolean(focusedCell && focusedCell.id === renderRow.id && focusedCell.field === field);\n const isEditing = Boolean(editingCell && editingCell.id === renderRow.id && editingCell.field === field);\n const isAggregation =\n (renderRow.kind === 'group' || renderRow.kind === 'footer') && Boolean(renderRow.aggregates?.[field]);\n const params =\n renderRow.kind === 'leaf' && renderRow.row\n ? buildCellParams(renderRow.id, field, renderRow.row, renderRow.node)\n : null;\n const editable = params ? isCellEditableFn(params) : false;\n const customClass =\n params && col.cellClassName\n ? typeof col.cellClassName === 'function'\n ? col.cellClassName(params)\n : col.cellClassName\n : undefined;\n const isCheckbox = field === CHECKBOX_FIELD;\n const isDetailToggle = field === DETAIL_PANEL_TOGGLE_FIELD;\n return (\n <div\n key={field}\n role=\"gridcell\"\n data-mgh-field={field}\n data-mgh-colindex={layout.columns.indexOf(lc)}\n tabIndex={isFocused ? 0 : -1}\n aria-selected={renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : undefined}\n className={cx(\n 'mgh-grid-cell',\n `mgh-grid-cell--align-${col.align ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-cell'),\n isFocused && !isEditing && 'mgh-grid-cell--focused',\n isEditing && 'mgh-grid-cell--editing',\n editable && !isEditing && 'mgh-grid-cell--editable',\n col.type === 'boolean' && 'mgh-grid-cell--boolean',\n col.type === 'actions' && 'mgh-grid-cell--actions',\n isCheckbox && 'mgh-grid-cell--checkbox',\n isDetailToggle && 'mgh-grid-cell--detail-toggle',\n isAggregation && 'mgh-grid-cell--aggregation',\n customClass\n )}\n style={cellStyle(lc)}\n onMouseDown={() => {\n if (renderRow.kind === 'leaf' || renderRow.kind === 'group') {\n if (!isFocused) setFocusedCell({ id: renderRow.id, field });\n }\n }}\n onClick={(event) => {\n if (params && onCellClick) onCellClick(params, event, getDetails());\n }}\n onDoubleClick={(event) => {\n if (params) {\n onCellDoubleClick?.(params, event, getDetails());\n if (editable && !isEditing) {\n event.stopPropagation();\n startCellEditMode(renderRow.id, field);\n }\n }\n }}\n >\n {renderCellContent(lc, renderRow)}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: rows */\n\n const rowIsClickable = Boolean(onRowClick || onRowDoubleClick || !disableRowSelectionOnClick);\n\n const renderRowElement = (\n renderRow: RenderRow<R>,\n options: { height?: number; index: number; isFirst: boolean; isLast: boolean; isAuto: boolean }\n ) => {\n const isSelected = renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : false;\n const customClass =\n renderRow.kind === 'leaf' && renderRow.row && getRowClassName\n ? getRowClassName({\n ...buildRowParams(renderRow.id, renderRow.row),\n indexRelativeToCurrentPage: options.index,\n isFirstVisible: options.isFirst,\n isLastVisible: options.isLast,\n rowNode: renderRow.node,\n })\n : undefined;\n return (\n <div\n role=\"row\"\n aria-rowindex={options.index + 2}\n aria-selected={renderRow.kind === 'leaf' ? isSelected : undefined}\n data-mgh-row-id={String(renderRow.id)}\n data-mgh-row-index={options.index}\n className={cx(\n 'mgh-grid-row',\n isSelected && 'mgh-grid-row--selected',\n rowIsClickable && renderRow.kind === 'leaf' && 'mgh-grid-row--clickable',\n renderRow.kind === 'group' && 'mgh-grid-row--group',\n renderRow.kind === 'pinnedRow' && 'mgh-grid-row--pinned',\n renderRow.kind === 'footer' && 'mgh-grid-row--footer',\n options.isAuto && 'mgh-grid-row--auto-height',\n customClass\n )}\n style={{\n width: layout.totalWidth,\n height: options.isAuto ? undefined : options.height,\n minHeight: options.isAuto ? rowHeight : undefined,\n }}\n onClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n if (!disableRowSelectionOnClick) handleRowSelectionClick(renderRow, event);\n onRowClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n } else if (renderRow.kind === 'group' && renderRow.group) {\n setRowChildrenExpansion(renderRow.group.id, !isGroupExpanded(renderRow.group));\n }\n }}\n onDoubleClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n onRowDoubleClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n }\n }}\n >\n {layout.columns.map((lc) => renderCell(lc, renderRow, options.isAuto))}\n <div className=\"mgh-grid-row-filler\" />\n </div>\n );\n };\n\n const toRenderRow = (dr: DisplayRow<R>): RenderRow<R> => ({\n id: dr.id,\n kind: dr.type,\n row: dr.row,\n node: dr.node,\n depth: dr.depth,\n group: dr.group,\n aggregates: dr.type === 'group' && dr.group ? getGroupAggregates(dr.group) : undefined,\n });\n\n const renderBodyRows = () => {\n const { start, end } = virtualRange;\n const items: React.ReactNode[] = [];\n for (let i = start; i < end; i += 1) {\n const dr = pagedRows[i];\n const renderRow = toRenderRow(dr);\n const detailHeight = heights.detailHeights[i];\n const isExpanded =\n dr.type === 'leaf' && Boolean(dr.row) && Boolean(getDetailPanelContent) && expandedDetailPanels.has(dr.id);\n const detailContent = isExpanded && dr.row ? getDetailPanelContent?.(buildRowParams(dr.id, dr.row)) : null;\n const detailAuto =\n isExpanded && dr.row && getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row }) === 'auto'\n : false;\n const rowAuto =\n !virtual &&\n (getRowHeight && dr.type === 'leaf' && dr.row\n ? getRowHeight({ id: dr.id, model: dr.row, densityFactor }) === 'auto'\n : false);\n items.push(\n <div\n key={String(dr.id)}\n className=\"mgh-grid-row-block\"\n style={virtual ? { top: heights.offsets[i], width: layout.totalWidth } : { width: layout.totalWidth }}\n >\n {renderRowElement(renderRow, {\n height: heights.rowHeights[i],\n index: i,\n isFirst: i === 0,\n isLast: i === pagedRows.length - 1,\n isAuto: rowAuto,\n })}\n {isExpanded && detailContent !== null && detailContent !== undefined && detailContent !== false && (\n <div\n className=\"mgh-grid-detail-panel\"\n style={{\n height: detailAuto ? undefined : detailHeight || undefined,\n width: viewportWidth || undefined,\n }}\n onClick={(event) => event.stopPropagation()}\n >\n {detailContent}\n </div>\n )}\n </div>\n );\n }\n return items;\n };\n\n const renderPinnedRows = (list: R[] | undefined, position: 'top' | 'bottom') => {\n const items: React.ReactNode[] = [];\n (list ?? []).forEach((row, index) => {\n const id = getRowIdFromRow(row, getRowId);\n const renderRow: RenderRow<R> = {\n id,\n kind: 'pinnedRow',\n row,\n node: { type: 'pinnedRow', id, depth: 0, parent: null, position },\n depth: 0,\n };\n items.push(\n <React.Fragment key={String(id)}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: index,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n });\n if (position === 'bottom' && footerAggregates) {\n const renderRow: RenderRow<R> = {\n id: AGGREGATION_FOOTER_ID,\n kind: 'footer',\n row: null,\n node: { type: 'footer', id: AGGREGATION_FOOTER_ID, depth: 0, parent: null },\n depth: 0,\n aggregates: footerAggregates,\n };\n items.push(\n <React.Fragment key={AGGREGATION_FOOTER_ID}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: 0,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n }\n return items;\n };\n\n /* ------------------------------------------------------------------ rendering: header */\n\n const renderHeaderCell = (lc: ColumnLayout, index: number) => {\n const { col } = lc;\n const field = col.field;\n const sortIndex = sortModel.findIndex((item) => item.field === field && item.sort);\n const sortItem = sortIndex !== -1 ? sortModel[sortIndex] : undefined;\n const sortable =\n (col.sortable !== false && !disableColumnSorting && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && col.sortable !== false);\n const showMenu =\n (!disableColumnMenu && !col.disableColumnMenu && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnMenu);\n const resizable =\n (!disableColumnResize && col.resizable !== false && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnResize);\n const draggable = canReorder(col);\n const isDragging = drag?.field === field;\n const isDropTarget = drag && drag.overField === field && drag.field !== field;\n const menuOpen = columnMenu?.field === field;\n const headerParams = { field, colDef: col as MGHGridColDef<R>, api: apiObject };\n const customClass = col.headerClassName\n ? typeof col.headerClassName === 'function'\n ? col.headerClassName(headerParams)\n : col.headerClassName\n : undefined;\n\n let content: React.ReactNode;\n if (field === CHECKBOX_FIELD) {\n content = disableMultipleRowSelection ? null : (\n <Checkbox\n checked={allCandidatesSelected}\n indeterminate={someCandidatesSelected}\n disabled={selectionCandidates.length === 0}\n label={\n allCandidatesSelected\n ? localeText.checkboxSelectionUnselectAllRows\n : localeText.checkboxSelectionSelectAllRows\n }\n onChange={toggleAllCandidates}\n onClick={(event) => event.stopPropagation()}\n />\n );\n } else if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n content = null;\n } else {\n content = col.renderHeader ? (\n col.renderHeader(headerParams)\n ) : (\n <span className=\"mgh-grid-header-title\">{col.headerName ?? field}</span>\n );\n }\n\n return (\n <div\n key={field}\n role=\"columnheader\"\n aria-colindex={index + 1}\n aria-sort={sortItem ? (sortItem.sort === 'asc' ? 'ascending' : 'descending') : sortable ? 'none' : undefined}\n data-mgh-field={field}\n title={col.description}\n tabIndex={-1}\n draggable={draggable}\n className={cx(\n 'mgh-grid-header-cell',\n `mgh-grid-header-cell--align-${col.headerAlign ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-header-cell'),\n sortable && 'mgh-grid-header-cell--sortable',\n field === CHECKBOX_FIELD && 'mgh-grid-header-cell--checkbox',\n field === DETAIL_PANEL_TOGGLE_FIELD && 'mgh-grid-header-cell--detail-toggle',\n index === layout.columns.length - 1 && 'mgh-grid-header-cell--last',\n isDragging && 'mgh-grid-header-cell--dragging',\n isDropTarget && drag?.side === 'left' && 'mgh-grid-header-cell--drop-left',\n isDropTarget && drag?.side === 'right' && 'mgh-grid-header-cell--drop-right',\n menuOpen && 'mgh-grid-header-cell--menu-open',\n customClass\n )}\n style={cellStyle(lc)}\n onClick={(event) => {\n if (!sortable || resizingField) return;\n sortColumn(field, undefined, event.shiftKey);\n }}\n onDragStart={(event) => {\n if (!draggable) return;\n event.dataTransfer.effectAllowed = 'move';\n try {\n event.dataTransfer.setData('text/plain', field);\n } catch {\n /* ignore */\n }\n setDrag({ field, overField: null, side: 'left' });\n }}\n onDragOver={(event) => {\n if (!drag || drag.field === field) return;\n const sourceLc = layout.columns.find((c) => c.col.field === drag.field);\n if (!sourceLc || sourceLc.pinned !== lc.pinned || !canReorder(col)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n const rect = event.currentTarget.getBoundingClientRect();\n const side = event.clientX < rect.left + rect.width / 2 ? 'left' : 'right';\n if (drag.overField !== field || drag.side !== side) setDrag({ ...drag, overField: field, side });\n }}\n onDragLeave={() => {\n if (drag && drag.overField === field) setDrag({ ...drag, overField: null });\n }}\n onDrop={(event) => handleDrop(lc, event)}\n onDragEnd={() => setDrag(null)}\n >\n <div className=\"mgh-grid-header-title-container\">\n {content}\n {sortable && (\n <span\n className={cx('mgh-grid-sort-icon', sortItem && 'mgh-grid-sort-icon--active')}\n aria-hidden=\"true\"\n >\n {sortItem?.sort === 'desc' ? <ArrowDownwardIcon size={18} /> : <ArrowUpwardIcon size={18} />}\n {sortItem && sortModel.filter((s) => s.sort).length > 1 && (\n <span className=\"mgh-grid-sort-index\">{sortIndex + 1}</span>\n )}\n </span>\n )}\n </div>\n {showMenu && (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-header-menu-btn', menuOpen && 'mgh-grid-header-menu-btn--open')}\n label={localeText.columnMenuLabel}\n aria-haspopup=\"menu\"\n aria-expanded={menuOpen}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setColumnMenu((prev) =>\n prev?.field === field ? null : { field, anchorEl: event.currentTarget }\n );\n }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n {resizable && (\n <div\n className={cx('mgh-grid-resize-handle', resizingField === field && 'mgh-grid-resize-handle--active')}\n role=\"separator\"\n aria-orientation=\"vertical\"\n onPointerDown={(event) => handleResizeStart(lc, event)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.stopPropagation();\n autosizeColumns({ columns: [field] });\n }}\n draggable={false}\n onDragStart={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n />\n )}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: slots */\n\n const ToolbarSlot = slots.toolbar === null ? null : (slots.toolbar ?? MGHGridToolbar);\n const FooterSlot = slots.footer === null ? null : (slots.footer ?? MGHGridFooter);\n const NoRowsOverlaySlot = slots.noRowsOverlay ?? MGHGridNoRowsOverlay;\n const LoadingOverlaySlot = slots.loadingOverlay ?? MGHGridLoadingOverlay;\n const mergedToolbarProps = { ...toolbarProps, ...slotProps.toolbar };\n const noRowsProps = { text: noRowsText, ...slotProps.noRowsOverlay };\n const loadingProps = { ...slotProps.loadingOverlay };\n\n const showNoRows = !loading && pagedRows.length === 0;\n const menuColumn = columnMenu ? getColumn(columnMenu.field) : undefined;\n\n const cardStyles: React.CSSProperties = {\n height: 'auto',\n flexGrow: 1,\n ...sanitizeStyle(cardSx),\n ...sanitizeStyle(cardStyle),\n ...(themeVars as any),\n };\n const boxStyles: React.CSSProperties = { flexGrow: 1, ...sanitizeStyle(boxSx), ...sanitizeStyle(boxStyle) };\n const rootStyles: React.CSSProperties = {\n ...sanitizeStyle(sx),\n ...sanitizeStyle(style),\n ['--mgh-grid-header-height' as any]: `${headerHeight}px`,\n ['--mgh-grid-row-height' as any]: `${rowHeight}px`,\n };\n\n // Nested selectors from sx/style props become a <style> block scoped to this grid instance.\n const scopedCss = React.useMemo(() => {\n const css: string[] = [];\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, sx, css);\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, style, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardSx, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardStyle, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxSx, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxStyle, css);\n return css.join('\\n');\n }, [gridId, sx, style, cardSx, cardStyle, boxSx, boxStyle]);\n\n const smDown = viewportWidth > 0 && viewportWidth < 600;\n\n const grid = (\n <div\n ref={rootRef}\n id={gridId}\n data-mgh-grid-id={gridId}\n role=\"grid\"\n aria-rowcount={rowCount + 1}\n aria-colcount={layout.columns.length}\n aria-multiselectable={checkboxSelection && !disableMultipleRowSelection ? true : undefined}\n aria-busy={loading || undefined}\n className={cx(\n 'mgh-grid',\n (autoHeight || printing) && 'mgh-grid--auto-height',\n printing && 'mgh-grid--printing',\n !layout.hasPinning && 'mgh-grid--no-pinned-shadow',\n className\n )}\n style={rootStyles}\n onKeyDown={handleKeyDown}\n >\n {showToolbar && ToolbarSlot && (\n <div ref={toolbarRef}>\n <ToolbarSlot {...mergedToolbarProps} />\n </div>\n )}\n <div className=\"mgh-grid-main\">\n <div ref={scrollerRef} className=\"mgh-grid-scroller\" onScroll={handleScroll} tabIndex={-1}>\n <div className=\"mgh-grid-columns\" role=\"rowgroup\" style={{ width: layout.totalWidth }}>\n <div className=\"mgh-grid-header-row\" role=\"row\" aria-rowindex={1} style={{ height: headerHeight }}>\n {layout.columns.map((lc, index) => renderHeaderCell(lc, index))}\n <div className=\"mgh-grid-header-filler\" />\n </div>\n </div>\n {pinnedRows?.top && pinnedRows.top.length > 0 && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--top\"\n role=\"rowgroup\"\n style={{ top: headerHeight, width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows.top, 'top')}\n </div>\n )}\n <div\n className={cx('mgh-grid-body', virtual ? 'mgh-grid-body--virtual' : 'mgh-grid-body--flow')}\n role=\"rowgroup\"\n style={\n virtual\n ? {\n height: pagedRows.length === 0 ? Math.max(heights.total, 120) : heights.total,\n width: layout.totalWidth,\n }\n : { width: layout.totalWidth, minHeight: showNoRows || loading ? 120 : undefined }\n }\n >\n {renderBodyRows()}\n </div>\n {((pinnedRows?.bottom && pinnedRows.bottom.length > 0) || footerAggregates) && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--bottom\"\n role=\"rowgroup\"\n style={{ width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows?.bottom, 'bottom')}\n </div>\n )}\n </div>\n {loading && (\n <div className=\"mgh-grid-overlay mgh-grid-overlay--loading\" style={{ top: headerHeight }}>\n <LoadingOverlaySlot {...loadingProps} />\n </div>\n )}\n {showNoRows && (\n <div className=\"mgh-grid-overlay\" style={{ top: headerHeight }}>\n <NoRowsOverlaySlot {...noRowsProps} />\n </div>\n )}\n </div>\n {!hideFooter && FooterSlot && <FooterSlot {...slotProps.footer} />}\n\n <Popover\n open={preferencePanel.open}\n anchorEl={preferencePanel.anchorEl}\n onClose={hidePreferences}\n themeMode={themeMode}\n placement=\"bottom-start\"\n autoFocus\n >\n {preferencePanel.openedPanelValue === 'columns' ? <MGHGridColumnsPanel /> : <MGHGridFilterPanel />}\n </Popover>\n\n {menuColumn && columnMenu && (\n <MGHGridColumnMenu\n column={menuColumn}\n anchorEl={columnMenu.anchorEl}\n open\n onClose={() => setColumnMenu(null)}\n themeMode={themeMode}\n panelAnchorEl={toolbarRef.current}\n />\n )}\n </div>\n );\n\n return (\n <MGHGridContext.Provider value={contextValue}>\n <div\n ref={cardRef}\n className={cx('mgh-grid-card', disableCard && 'mgh-grid-card--plain', cardClassName)}\n data-mgh-theme={themeMode}\n data-mgh-grid-card={gridId}\n style={cardStyles}\n >\n {scopedCss && <style data-mgh-grid-sx={gridId}>{scopedCss}</style>}\n {!disableCard && (header !== undefined || renderHeaderCenterContent || renderHeaderEndContent) && (\n <div className=\"mgh-grid-card-header\">\n {header !== undefined && <h3 className=\"mgh-grid-card-title\">{header}</h3>}\n {renderHeaderCenterContent && (\n <div className=\"mgh-grid-card-header-center\">{renderHeaderCenterContent}</div>\n )}\n <div className=\"mgh-grid-card-header-end\" style={{ gap: smDown ? 8 : 16 }}>\n {renderHeaderEndContent}\n </div>\n </div>\n )}\n <div className={cx('mgh-grid-box', boxClassName)} data-mgh-grid-box={gridId} style={boxStyles}>\n {grid}\n </div>\n </div>\n </MGHGridContext.Provider>\n );\n}\n\nMGHGrid.displayName = 'MGHGrid';\n","import React from 'react';\n\nexport const MGH_DATE_RANGE_PICKER_STYLE_ID = 'mgh-drp-styles';\n\n/**\n * Stylesheet for MGHDateRangePicker. Injected once into <head> the first time a picker mounts.\n * Colours are CSS variables (`--mgh-drp-*`). When the picker is rendered inside an MGHGrid card\n * it inherits the grid palette (`--mgh-grid-*`) automatically.\n */\nexport const MGH_DATE_RANGE_PICKER_CSS = `\n.mgh-drp, .mgh-drp-popover, .mgh-drp-calendars, .mgh-dp-calendar {\n --mgh-drp-font-family: var(--mgh-grid-font-family, inherit);\n --mgh-drp-font-size: var(--mgh-grid-font-size, 14px);\n --mgh-drp-paper: var(--mgh-grid-paper, #ffffff);\n --mgh-drp-fg: var(--mgh-grid-fg, rgba(0, 0, 0, 0.87));\n --mgh-drp-fg-secondary: var(--mgh-grid-fg-secondary, rgba(0, 0, 0, 0.6));\n --mgh-drp-fg-disabled: var(--mgh-grid-fg-disabled, rgba(0, 0, 0, 0.38));\n --mgh-drp-border: var(--mgh-grid-border, rgba(224, 224, 224, 1));\n --mgh-drp-input-border: var(--mgh-grid-input-border, rgba(0, 0, 0, 0.23));\n --mgh-drp-hover: var(--mgh-grid-hover, rgba(0, 0, 0, 0.04));\n --mgh-drp-primary: var(--mgh-grid-primary, #1976d2);\n --mgh-drp-primary-contrast: var(--mgh-grid-primary-contrast, #ffffff);\n --mgh-drp-focus: var(--mgh-grid-focus, #1976d2);\n --mgh-drp-selected: var(--mgh-grid-selected, rgba(25, 118, 210, 0.12));\n --mgh-drp-preview: rgba(0, 0, 0, 0.06);\n --mgh-drp-error: #d32f2f;\n --mgh-drp-radius: 4px;\n --mgh-drp-popover-radius: 8px;\n --mgh-drp-popover-shadow: var(--mgh-grid-popover-shadow, 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12));\n --mgh-drp-day-size: 36px;\n --mgh-drp-day-margin: 2px;\n font-family: var(--mgh-drp-font-family);\n font-size: var(--mgh-drp-font-size);\n color: var(--mgh-drp-fg);\n line-height: 1.5;\n}\n/* Dark values also apply to a calendar nested inside a dark picker / popover, so the calendar's own\n defaults (declared above for standalone use) never reset the colours back to light.\n .mgh-dp-calendar is MGHDatePicker's calendar, which shares this stylesheet. */\n.mgh-drp[data-mgh-theme=\"dark\"], .mgh-drp-popover[data-mgh-theme=\"dark\"], .mgh-drp-calendars[data-mgh-theme=\"dark\"], .mgh-dp-calendar[data-mgh-theme=\"dark\"],\n.mgh-drp[data-mgh-theme=\"dark\"] .mgh-drp-calendars, .mgh-drp-popover[data-mgh-theme=\"dark\"] .mgh-drp-calendars,\n.mgh-drp[data-mgh-theme=\"dark\"] .mgh-dp-calendar, .mgh-drp-popover[data-mgh-theme=\"dark\"] .mgh-dp-calendar {\n --mgh-drp-paper: #212b36;\n --mgh-drp-fg: #ffffff;\n --mgh-drp-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-drp-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-drp-border: rgba(81, 81, 81, 1);\n --mgh-drp-input-border: rgba(255, 255, 255, 0.23);\n --mgh-drp-hover: rgba(255, 255, 255, 0.08);\n --mgh-drp-primary: #90caf9;\n --mgh-drp-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-drp-focus: #90caf9;\n --mgh-drp-selected: rgba(144, 202, 249, 0.16);\n --mgh-drp-preview: rgba(255, 255, 255, 0.08);\n --mgh-drp-error: #f44336;\n}\n[class*=\"mgh-drp\"], [class*=\"mgh-drp\"]::before, [class*=\"mgh-drp\"]::after { box-sizing: border-box; }\n\n/* ---- root / multi-input layout ---- */\n.mgh-drp { display: inline-flex; flex-direction: column; vertical-align: top; min-width: 0; }\n.mgh-drp--full-width { display: flex; width: 100%; }\n.mgh-drp-fields { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }\n.mgh-drp-fields .mgh-drp-field { flex: 1 1 0; min-width: 0; }\n.mgh-drp-fields-separator { align-self: center; color: var(--mgh-drp-fg-secondary); padding: 0 2px; }\n\n/* ---- outlined text field (MUI TextField look-alike) ---- */\n.mgh-drp-field { position: relative; display: inline-flex; align-items: center; min-width: 0; width: 100%; border-radius: var(--mgh-drp-radius); color: var(--mgh-drp-fg); }\n.mgh-drp-field--medium { height: 56px; }\n.mgh-drp-field--small { height: 40px; }\n.mgh-drp-field:not(.mgh-drp-field--full-width) { width: 260px; }\n.mgh-drp-field--multi:not(.mgh-drp-field--full-width) { width: 170px; }\n.mgh-drp-field--full-width { width: 100%; }\n.mgh-drp-input { flex: 1 1 auto; min-width: 0; width: 100%; height: 100%; margin: 0; border: 0; outline: none; background: transparent; color: inherit; font: inherit; font-size: 1rem; letter-spacing: inherit; padding: 16.5px 14px; }\n.mgh-drp-field--small .mgh-drp-input { padding: 8.5px 14px; }\n.mgh-drp-field--adorned .mgh-drp-input { padding-right: 0; }\n.mgh-drp-input::placeholder { color: var(--mgh-drp-fg-disabled); opacity: 1; }\n.mgh-drp-input::-webkit-calendar-picker-indicator { display: none; }\n.mgh-drp-field--disabled .mgh-drp-input { color: var(--mgh-drp-fg-disabled); -webkit-text-fill-color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-field--disabled { cursor: default; }\n.mgh-drp-field--clickable .mgh-drp-input { cursor: pointer; }\n.mgh-drp-adornment { display: flex; align-items: center; gap: 0; margin-right: 6px; flex: 0 0 auto; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-field--small .mgh-drp-adornment { margin-right: 4px; }\n\n/* notched outline */\n.mgh-drp-outline { position: absolute; inset: -5px 0 0 0; margin: 0; padding: 0 8px; pointer-events: none; border: 1px solid var(--mgh-drp-input-border); border-radius: inherit; min-width: 0; overflow: hidden; text-align: left; transition: border-color .15s; }\n.mgh-drp-outline legend { float: unset; width: auto; padding: 0; height: 11px; font-size: 0.75em; visibility: hidden; max-width: 0.01px; white-space: nowrap; transition: max-width 50ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; overflow: hidden; display: block; line-height: 11px; }\n.mgh-drp-outline legend > span { padding-left: 5px; padding-right: 5px; display: inline-block; opacity: 0; visibility: visible; }\n.mgh-drp-field--shrink .mgh-drp-outline legend { max-width: 100%; transition: max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms; }\n.mgh-drp-field--no-label .mgh-drp-outline legend { display: none; }\n/* Without a label there is no legend notch, so the fieldset must sit on the field box instead of 5px above it;\n otherwise the visible border is 5px taller than with a label and the field looks off-centre. */\n.mgh-drp-field--no-label .mgh-drp-outline { inset: 0; }\n.mgh-drp-field:hover:not(.mgh-drp-field--disabled) .mgh-drp-outline { border-color: var(--mgh-drp-fg); }\n.mgh-drp-field--focused .mgh-drp-outline, .mgh-drp-field--focused:hover .mgh-drp-outline { border-color: var(--mgh-drp-focus); border-width: 2px; }\n.mgh-drp-field--error .mgh-drp-outline, .mgh-drp-field--error:hover .mgh-drp-outline { border-color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-outline { border-color: var(--mgh-drp-fg-disabled); }\n\n/* floating label */\n.mgh-drp-label { position: absolute; left: 0; top: 0; transform-origin: top left; transform: translate(14px, 16px) scale(1); color: var(--mgh-drp-fg-secondary); font-size: 1rem; line-height: 1.4375em; pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: calc(100% - 24px); transition: color .15s, transform .15s cubic-bezier(0.0, 0, 0.2, 1), max-width .15s; z-index: 1; }\n.mgh-drp-field--small .mgh-drp-label { transform: translate(14px, 9px) scale(1); }\n.mgh-drp-field--shrink .mgh-drp-label, .mgh-drp-field--small.mgh-drp-field--shrink .mgh-drp-label { transform: translate(14px, -9px) scale(0.75); max-width: calc(133% - 32px); }\n.mgh-drp-field--focused .mgh-drp-label { color: var(--mgh-drp-focus); }\n.mgh-drp-field--error .mgh-drp-label { color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-label { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-label-asterisk { margin-left: 2px; }\n\n.mgh-drp-helper { margin: 3px 14px 0; font-size: 0.75rem; line-height: 1.66; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-helper--error { color: var(--mgh-drp-error); }\n\n/* ---- buttons ---- */\n.mgh-drp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-drp-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; white-space: nowrap; text-transform: uppercase; }\n.mgh-drp-btn:hover { background: var(--mgh-drp-hover); color: var(--mgh-drp-fg); }\n.mgh-drp-btn:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-btn:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-btn--primary { color: var(--mgh-drp-primary); }\n.mgh-drp-btn--primary:hover { background: var(--mgh-drp-selected); color: var(--mgh-drp-primary); }\n.mgh-drp-btn--icon { padding: 8px; border-radius: 50%; width: 40px; height: 40px; text-transform: none; }\n.mgh-drp-btn--icon.mgh-drp-btn--small { width: 32px; height: 32px; padding: 4px; }\n.mgh-drp-icon { flex: 0 0 auto; }\n\n/* ---- popover ---- */\n.mgh-drp-popover { position: fixed; z-index: 1300; display: flex; flex-direction: column; background: var(--mgh-drp-paper); color: var(--mgh-drp-fg); border-radius: var(--mgh-drp-popover-radius); box-shadow: var(--mgh-drp-popover-shadow); outline: none; max-height: calc(100vh - 16px); max-width: calc(100vw - 16px); overflow: auto; animation: mgh-drp-pop .12s ease-out; }\n@keyframes mgh-drp-pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }\n.mgh-drp-layout { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-layout--with-toolbar { flex-direction: column; }\n.mgh-drp-layout-main { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-toolbar { padding: 16px 24px 0; }\n.mgh-drp-toolbar-title { font-size: 0.75rem; text-transform: uppercase; letter-spacing: .08em; color: var(--mgh-drp-fg-secondary); margin: 0 0 8px; }\n.mgh-drp-toolbar-range { display: flex; align-items: center; gap: 8px; font-size: 1.5rem; font-weight: 400; line-height: 1.334; }\n.mgh-drp-toolbar-range button { border: 0; background: transparent; padding: 0 2px; font: inherit; color: var(--mgh-drp-fg-secondary); cursor: pointer; border-radius: 4px; }\n.mgh-drp-toolbar-range button.mgh-drp-toolbar-range--active { color: var(--mgh-drp-fg); }\n.mgh-drp-toolbar-range button:hover { background: var(--mgh-drp-hover); }\n\n/* shortcuts (left column) */\n.mgh-drp-shortcuts { list-style: none; margin: 0; padding: 8px 0; min-width: 140px; max-height: 340px; overflow: auto; border-right: 1px solid var(--mgh-drp-border); display: flex; flex-direction: column; gap: 4px; padding-left: 8px; padding-right: 8px; }\n.mgh-drp-shortcut { display: inline-flex; align-items: center; height: 32px; padding: 0 12px; border-radius: 16px; border: 1px solid var(--mgh-drp-input-border); background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.8125rem; cursor: pointer; white-space: nowrap; justify-content: flex-start; transition: background-color .15s; }\n.mgh-drp-shortcut:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-shortcut:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-shortcut:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; }\n.mgh-drp-shortcut--selected { background: var(--mgh-drp-selected); border-color: var(--mgh-drp-primary); color: var(--mgh-drp-primary); }\n\n/* ---- calendars ---- */\n.mgh-drp-calendars { display: flex; flex-direction: row; align-items: flex-start; }\n.mgh-drp-calendar { display: flex; flex-direction: column; width: calc(7 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)) + 24px); padding: 0 12px 8px; }\n.mgh-drp-calendar + .mgh-drp-calendar { border-left: 1px solid var(--mgh-drp-border); }\n.mgh-drp-calendar-header { display: flex; align-items: center; justify-content: space-between; min-height: 40px; margin: 12px 0 8px; padding: 0 4px; }\n.mgh-drp-calendar-label { flex: 1 1 auto; text-align: center; font-size: 1rem; font-weight: 500; }\n.mgh-drp-calendar-header .mgh-drp-btn--icon { color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-calendar-nav-spacer { width: 40px; height: 40px; flex: 0 0 auto; }\n.mgh-drp-weekdays, .mgh-drp-week { display: flex; justify-content: center; }\n.mgh-drp-weekday { width: var(--mgh-drp-day-size); height: 40px; margin: 0 var(--mgh-drp-day-margin); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; color: var(--mgh-drp-fg-secondary); font-weight: 400; }\n.mgh-drp-weeks { display: flex; flex-direction: column; min-height: calc(6 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin))); }\n.mgh-drp-week { margin: var(--mgh-drp-day-margin) 0; }\n\n/* day cell: the outer wrapper carries the range highlight, the inner button the day itself */\n.mgh-drp-day-wrap { position: relative; width: calc(var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)); height: var(--mgh-drp-day-size); display: flex; align-items: center; justify-content: center; }\n.mgh-drp-day-wrap--in-range { background: var(--mgh-drp-selected); }\n.mgh-drp-day-wrap--range-start { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--range-end { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--preview { border-top: 1px dashed var(--mgh-drp-fg-secondary); border-bottom: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--preview-start { border-left: 1px dashed var(--mgh-drp-fg-secondary); border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--preview-end { border-right: 1px dashed var(--mgh-drp-fg-secondary); border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; border-left: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; border-right: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day { width: var(--mgh-drp-day-size); height: var(--mgh-drp-day-size); border-radius: 50%; border: 0; margin: 0; padding: 0; background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.75rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background-color .15s, color .15s; position: relative; }\n.mgh-drp-day:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-day:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: -1px; }\n.mgh-drp-day--today:not(.mgh-drp-day--selected) { border: 1px solid var(--mgh-drp-fg-secondary); }\n.mgh-drp-day--outside { color: var(--mgh-drp-fg-secondary); opacity: .6; }\n.mgh-drp-day--hidden { visibility: hidden; pointer-events: none; }\n.mgh-drp-day--disabled, .mgh-drp-day--disabled:hover { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-day--selected, .mgh-drp-day--selected:hover { background: var(--mgh-drp-primary); color: var(--mgh-drp-primary-contrast); font-weight: 500; }\n.mgh-drp-day--selected:focus-visible { outline-offset: 2px; }\n.mgh-drp-calendar--read-only .mgh-drp-day, .mgh-drp-calendar--disabled .mgh-drp-day { cursor: default; }\n.mgh-drp-calendar--disabled .mgh-drp-day { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-calendar--disabled .mgh-drp-day--selected { opacity: .6; }\n\n/* ---- action bar ---- */\n.mgh-drp-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 8px; border-top: 1px solid var(--mgh-drp-border); }\n.mgh-drp-actions--spread { justify-content: space-between; }\n.mgh-drp-actions-group { display: flex; gap: 8px; }\n\n@media (max-width: 599.95px) {\n .mgh-drp-layout-main { flex-direction: column; }\n .mgh-drp-shortcuts { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--mgh-drp-border); max-height: none; }\n .mgh-drp-calendars { flex-direction: column; align-items: center; }\n .mgh-drp-calendar + .mgh-drp-calendar { border-left: 0; border-top: 1px solid var(--mgh-drp-border); }\n}\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_DATE_RANGE_PICKER_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_DATE_RANGE_PICKER_STYLE_ID;\n style.setAttribute('data-mgh-drp', 'true');\n style.textContent = MGH_DATE_RANGE_PICKER_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHDateRangePicker stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHDateRangePickerStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\n\n/* Inline SVG icons (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHDateRangeIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHDateRangeIconProps>(({ size = 24, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-drp-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const DateRangeIcon = createIcon(\n <path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\" />,\n 'DateRangeIcon'\n);\nexport const ChevronLeftIcon = createIcon(\n <path d=\"M15.41 16.59 10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z\" />,\n 'ChevronLeftIcon'\n);\nexport const ChevronRightIcon = createIcon(\n <path d=\"M8.59 16.59 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\" />,\n 'ChevronRightIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\n/* Used by MGHDatePicker (MUI's default `CalendarIcon` / `ArrowDropDownIcon`). */\nexport const CalendarIcon = createIcon(\n <path d=\"M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z\" />,\n 'CalendarIcon'\n);\nexport const ArrowDropDownIcon = createIcon(<path d=\"M7 10l5 5 5-5z\" />, 'ArrowDropDownIcon');\n","import dayjs, { Dayjs } from 'dayjs';\nimport customParseFormat from 'dayjs/plugin/customParseFormat';\nimport type {\n MGHDateRange,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\n\ndayjs.extend(customParseFormat);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const EMPTY_RANGE: MGHDateRange = [null, null];\n\n/** Coerces Dayjs / Date / ISO string / timestamp into a valid Dayjs (or null). */\nexport const toDayjs = (value: unknown): Dayjs | null => {\n if (value == null || value === '') return null;\n if (dayjs.isDayjs(value)) return value.isValid() ? value : null;\n if (value instanceof Date || typeof value === 'number' || typeof value === 'string') {\n const parsed = dayjs(value as Date | number | string);\n return parsed.isValid() ? parsed : null;\n }\n return null;\n};\n\nexport const isSameDay = (a: Dayjs | null | undefined, b: Dayjs | null | undefined) => !!a && !!b && a.isSame(b, 'day');\nexport const isBeforeDay = (a: Dayjs, b: Dayjs) => a.isBefore(b, 'day');\nexport const isAfterDay = (a: Dayjs, b: Dayjs) => a.isAfter(b, 'day');\nexport const isWithinRange = (day: Dayjs, start: Dayjs | null, end: Dayjs | null) =>\n !!start && !!end && !isBeforeDay(day, start) && !isAfterDay(day, end);\n\nexport const isRangeEqual = (a: MGHDateRange | undefined, b: MGHDateRange | undefined) => {\n if (a === b) return true;\n if (!a || !b) return false;\n const same = (x: Dayjs | null, y: Dayjs | null) => (x == null && y == null) || (!!x && !!y && x.isSame(y, 'day'));\n return same(a[0], b[0]) && same(a[1], b[1]);\n};\n\nexport const normalizeRange = (value: unknown): MGHDateRange => {\n if (!Array.isArray(value)) return EMPTY_RANGE;\n return [toDayjs(value[0]), toDayjs(value[1])];\n};\n\n/** Strict parse with the display format first, then a handful of forgiving fallbacks. */\nexport const parseDateText = (text: string, format: string): Dayjs | null => {\n const trimmed = text.trim();\n if (!trimmed) return null;\n const strict = dayjs(trimmed, format, true);\n if (strict.isValid()) return strict;\n const fallbacks = [\n format.replace(/MM/g, 'M').replace(/DD/g, 'D'),\n 'M/D/YYYY',\n 'M/D/YY',\n 'YYYY-MM-DD',\n 'MM-DD-YYYY',\n 'M-D-YYYY',\n ];\n for (const f of fallbacks) {\n const parsed = dayjs(trimmed, f, true);\n if (parsed.isValid()) return parsed;\n }\n return null;\n};\n\nexport const formatDate = (value: Dayjs | null, format: string) => (value && value.isValid() ? value.format(format) : '');\n\n/** Splits \"start – end\" text typed into the single-input field. */\nexport const splitRangeText = (text: string): [string, string] => {\n const parts = text.split(/\\s+[–—-]\\s+|\\s*–\\s*|\\s*—\\s*|\\s+to\\s+/i);\n if (parts.length >= 2) return [parts[0], parts.slice(1).join(' ')];\n return [text, ''];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validation (mirrors MUI's DateRangeValidationError semantics)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface DateValidationOptions {\n minDate?: Dayjs | null;\n maxDate?: Dayjs | null;\n disablePast?: boolean;\n disableFuture?: boolean;\n shouldDisableDate?: (day: Dayjs, position: MGHDateRangePosition) => boolean;\n}\n\nexport const validateDay = (\n day: Dayjs | null,\n position: MGHDateRangePosition,\n options: DateValidationOptions,\n now: Dayjs = dayjs()\n): MGHDateRangeValidationError => {\n if (day == null) return null;\n if (!day.isValid()) return 'invalidDate';\n if (options.disablePast && isBeforeDay(day, now)) return 'disablePast';\n if (options.disableFuture && isAfterDay(day, now)) return 'disableFuture';\n if (options.minDate && isBeforeDay(day, options.minDate)) return 'minDate';\n if (options.maxDate && isAfterDay(day, options.maxDate)) return 'maxDate';\n if (options.shouldDisableDate?.(day, position)) return 'shouldDisableDate';\n return null;\n};\n\nexport const validateRange = (\n value: MGHDateRange,\n options: DateValidationOptions\n): [MGHDateRangeValidationError, MGHDateRangeValidationError] => {\n const now = dayjs();\n const startError = validateDay(value[0], 'start', options, now);\n const endError = validateDay(value[1], 'end', options, now);\n if (!startError && !endError && value[0] && value[1] && isAfterDay(value[0], value[1])) {\n return ['invalidRange', 'invalidRange'];\n }\n return [startError, endError];\n};\n\nexport const isDayDisabled = (day: Dayjs, position: MGHDateRangePosition, options: DateValidationOptions) =>\n validateDay(day, position, options) != null;\n\n/* -------------------------------------------------------------------------------------------------\n * Calendar grid\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface CalendarWeek {\n key: string;\n days: Array<{ day: Dayjs; outsideMonth: boolean }>;\n}\n\n/**\n * Builds the weeks of `month`. Weeks start on the locale's first day of the week (Sunday for `en`).\n * Pass `fixedWeekNumber` (usually 6) to always render the same number of rows.\n */\nexport const getMonthWeeks = (month: Dayjs, fixedWeekNumber?: number): CalendarWeek[] => {\n const firstOfMonth = month.startOf('month');\n const start = firstOfMonth.startOf('week');\n const weeksInMonth = Math.ceil(firstOfMonth.endOf('month').diff(start, 'day') / 7 + 1 / 7);\n const weekCount = fixedWeekNumber && fixedWeekNumber > 0 ? fixedWeekNumber : Math.max(weeksInMonth, 1);\n const weeks: CalendarWeek[] = [];\n for (let w = 0; w < weekCount; w += 1) {\n const weekStart = start.add(w * 7, 'day');\n weeks.push({\n key: weekStart.format('YYYY-MM-DD'),\n days: Array.from({ length: 7 }, (_, d) => {\n const day = weekStart.add(d, 'day');\n return { day, outsideMonth: !day.isSame(firstOfMonth, 'month') };\n }),\n });\n }\n return weeks;\n};\n\nexport const getWeekDayLabels = (formatter: (day: Dayjs) => string) => {\n const start = dayjs().startOf('week');\n return Array.from({ length: 7 }, (_, i) => {\n const day = start.add(i, 'day');\n return { key: day.format('dd'), label: formatter(day), full: day.format('dddd') };\n });\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Shortcuts (same shape as MUI's PickersShortcuts items)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const MGH_DATE_RANGE_DEFAULT_SHORTCUTS: MGHDateRangeShortcut[] = [\n {\n label: 'This Week',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('week'), today.endOf('week')];\n },\n },\n {\n label: 'Last Week',\n getValue: () => {\n const prev = dayjs().subtract(7, 'day');\n return [prev.startOf('week'), prev.endOf('week')];\n },\n },\n {\n label: 'Last 7 Days',\n getValue: () => {\n const today = dayjs();\n return [today.subtract(7, 'day'), today];\n },\n },\n {\n label: 'Current Month',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('month'), today.endOf('month')];\n },\n },\n {\n label: 'Next Month',\n getValue: () => {\n const next = dayjs().add(1, 'month');\n return [next.startOf('month'), next.endOf('month')];\n },\n },\n { label: 'Reset', getValue: () => [null, null] },\n];\n","import React from 'react';\nimport dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateRange, MGHDateRangeCalendarProps, MGHDateRangePosition } from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { ChevronLeftIcon, ChevronRightIcon } from './icons';\nimport {\n EMPTY_RANGE,\n cx,\n getMonthWeeks,\n getWeekDayLabels,\n isAfterDay,\n isBeforeDay,\n isDayDisabled,\n isSameDay,\n isWithinRange,\n normalizeRange,\n} from './utils';\n\nconst defaultDayOfWeekFormatter = (day: Dayjs) => day.format('dd').charAt(0).toUpperCase();\n\n/**\n * Pure-React port of MUI X's `DateRangeCalendar`: one to three months side by side with range\n * highlighting, hover preview, keyboard navigation and min/max/disabled-day validation.\n */\nexport function MGHDateRangeCalendar({\n value: valueProp,\n defaultValue,\n onChange,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth = false,\n fixedWeekNumber,\n dayOfWeekFormatter = defaultDayOfWeekFormatter,\n disableHighlightToday = false,\n showRangePreview = true,\n autoFocus = false,\n onMonthChange,\n localeText,\n themeMode,\n className,\n style,\n}: MGHDateRangeCalendarProps) {\n useMGHDateRangePickerStyles();\n\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n\n // Month displayed by the first calendar.\n const [currentMonth, setCurrentMonth] = React.useState<Dayjs>(() =>\n (start ?? end ?? referenceDate ?? dayjs()).startOf('month')\n );\n const visibleMonths = React.useMemo(\n () => Array.from({ length: calendars }, (_, i) => currentMonth.add(i, 'month')),\n [currentMonth, calendars]\n );\n const lastVisibleMonth = visibleMonths[visibleMonths.length - 1];\n\n const changeMonth = React.useCallback(\n (month: Dayjs) => {\n const next = month.startOf('month');\n setCurrentMonth((prev) => {\n if (prev.isSame(next, 'month')) return prev;\n onMonthChange?.(next);\n return next;\n });\n },\n [onMonthChange]\n );\n\n const ensureVisible = React.useCallback(\n (day: Dayjs) => {\n if (isBeforeDay(day, currentMonth.startOf('month'))) changeMonth(day);\n else if (isAfterDay(day, lastVisibleMonth.endOf('month'))) changeMonth(day.subtract(calendars - 1, 'month'));\n },\n [currentMonth, lastVisibleMonth, calendars, changeMonth]\n );\n\n // When a value arrives from outside (typed in the field / shortcut) scroll to it.\n const lastSeenRef = React.useRef<MGHDateRange>(value);\n React.useEffect(() => {\n const prev = lastSeenRef.current;\n lastSeenRef.current = value;\n const target = rangePosition === 'end' ? (end ?? start) : (start ?? end);\n if (!target) return;\n const changed = !isSameDay(prev[0], start) || !isSameDay(prev[1], end);\n if (changed) ensureVisible(target);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [start, end]);\n\n const canGoPrev = !minDate || currentMonth.isAfter(minDate, 'month');\n const canGoNext = !maxDate || lastVisibleMonth.isBefore(maxDate, 'month');\n\n /* ---- hover preview ---- */\n const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);\n const preview = React.useMemo<MGHDateRange>(() => {\n if (!showRangePreview || !hoveredDay || disabled || readOnly) return EMPTY_RANGE;\n if (rangePosition === 'end' && start && !end) {\n return isBeforeDay(hoveredDay, start) ? EMPTY_RANGE : [start, hoveredDay];\n }\n if (rangePosition === 'start' && end && !start) {\n return isAfterDay(hoveredDay, end) ? EMPTY_RANGE : [hoveredDay, end];\n }\n return EMPTY_RANGE;\n }, [showRangePreview, hoveredDay, rangePosition, start, end, disabled, readOnly]);\n\n /* ---- selection (MUI semantics) ---- */\n const selectDay = React.useCallback(\n (day: Dayjs) => {\n if (disabled || readOnly) return;\n if (isDayDisabled(day, rangePosition, validation)) return;\n let next: MGHDateRange;\n let nextPosition: MGHDateRangePosition;\n if (rangePosition === 'start') {\n // Picking a start after the current end resets the end (MUI behaviour).\n next = [day, end && isAfterDay(day, end) ? null : end];\n nextPosition = 'end';\n } else if (start && isBeforeDay(day, start)) {\n // An \"end\" before the start becomes the new start; keep asking for the end.\n next = [day, null];\n nextPosition = 'end';\n } else {\n next = [start, day];\n nextPosition = 'start';\n }\n if (!isControlled) setInternalValue(next);\n onChange?.(next, day, rangePosition);\n setRangePosition(nextPosition);\n },\n [disabled, readOnly, rangePosition, validation, end, start, isControlled, onChange, setRangePosition]\n );\n\n /* ---- keyboard navigation (roving tabindex) ---- */\n const [focusedDay, setFocusedDay] = React.useState<Dayjs>(() => start ?? end ?? referenceDate ?? dayjs());\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef(autoFocus);\n\n const focusDay = React.useCallback((day: Dayjs) => {\n const key = day.format('YYYY-MM-DD');\n const el = rootRef.current?.querySelector<HTMLButtonElement>(`[data-day=\"${key}\"]`);\n el?.focus();\n }, []);\n\n React.useEffect(() => {\n if (!pendingFocusRef.current) return;\n pendingFocusRef.current = false;\n const target = focusedDay;\n ensureVisible(target);\n // Wait for a potential month change to render.\n const id = window.setTimeout(() => focusDay(target), 0);\n return () => window.clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const moveFocus = (day: Dayjs) => {\n setFocusedDay(day);\n ensureVisible(day);\n window.setTimeout(() => focusDay(day), 0);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>, day: Dayjs) => {\n let next: Dayjs | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = day.subtract(1, 'day');\n break;\n case 'ArrowRight':\n next = day.add(1, 'day');\n break;\n case 'ArrowUp':\n next = day.subtract(7, 'day');\n break;\n case 'ArrowDown':\n next = day.add(7, 'day');\n break;\n case 'Home':\n next = day.startOf('week');\n break;\n case 'End':\n next = day.endOf('week');\n break;\n case 'PageUp':\n next = event.shiftKey ? day.subtract(1, 'year') : day.subtract(1, 'month');\n break;\n case 'PageDown':\n next = event.shiftKey ? day.add(1, 'year') : day.add(1, 'month');\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n selectDay(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (next) moveFocus(next);\n };\n\n const weekDays = React.useMemo(() => getWeekDayLabels(dayOfWeekFormatter), [dayOfWeekFormatter]);\n const today = dayjs();\n const previewStart = preview[0];\n const previewEnd = preview[1];\n const isRangeComplete = !!start && !!end;\n\n const renderMonth = (month: Dayjs, index: number) => {\n const weeks = getMonthWeeks(month, fixedWeekNumber);\n const isFirst = index === 0;\n const isLast = index === visibleMonths.length - 1;\n const focusedInMonth = focusedDay.isSame(month, 'month') ? focusedDay : null;\n const tabbableDay =\n focusedInMonth ??\n (start && start.isSame(month, 'month') ? start : null) ??\n (end && end.isSame(month, 'month') ? end : null) ??\n (isFirst && !visibleMonths.some((m) => focusedDay.isSame(m, 'month')) ? month.startOf('month') : null);\n\n return (\n <div\n key={month.format('YYYY-MM')}\n className=\"mgh-drp-calendar\"\n role=\"group\"\n aria-label={month.format('MMMM YYYY')}\n >\n <div className=\"mgh-drp-calendar-header\">\n {isFirst ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.previousMonth ?? 'Previous month'}\n title={localeText?.previousMonth ?? 'Previous month'}\n disabled={disabled || !canGoPrev}\n onClick={() => changeMonth(currentMonth.subtract(1, 'month'))}\n >\n <ChevronLeftIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n <div className=\"mgh-drp-calendar-label\" aria-live=\"polite\">\n {month.format('MMMM YYYY')}\n </div>\n {isLast ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.nextMonth ?? 'Next month'}\n title={localeText?.nextMonth ?? 'Next month'}\n disabled={disabled || !canGoNext}\n onClick={() => changeMonth(currentMonth.add(1, 'month'))}\n >\n <ChevronRightIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n </div>\n <div className=\"mgh-drp-weekdays\" role=\"row\">\n {weekDays.map((wd) => (\n <span key={wd.key} className=\"mgh-drp-weekday\" role=\"columnheader\" aria-label={wd.full}>\n {wd.label}\n </span>\n ))}\n </div>\n <div className=\"mgh-drp-weeks\" role=\"grid\" aria-label={month.format('MMMM YYYY')}>\n {weeks.map((week) => (\n <div key={week.key} className=\"mgh-drp-week\" role=\"row\">\n {week.days.map(({ day, outsideMonth }, dayIndex) => {\n const hidden = outsideMonth && !showDaysOutsideCurrentMonth;\n const isStart = isSameDay(day, start);\n const isEnd = isSameDay(day, end);\n const selected = isStart || isEnd;\n const inRange = !hidden && isRangeComplete && isWithinRange(day, start, end);\n const inPreview =\n !hidden &&\n !!previewStart &&\n !!previewEnd &&\n isWithinRange(day, previewStart, previewEnd);\n const dayDisabled = disabled || isDayDisabled(day, rangePosition, validation);\n const isTabbable = !!tabbableDay && isSameDay(day, tabbableDay) && !hidden;\n const firstVisible = dayIndex === 0 || (!showDaysOutsideCurrentMonth && day.date() === 1);\n const lastVisible =\n dayIndex === 6 || (!showDaysOutsideCurrentMonth && day.date() === day.daysInMonth());\n return (\n <div\n key={day.format('YYYY-MM-DD')}\n role=\"gridcell\"\n aria-selected={selected || undefined}\n className={cx(\n 'mgh-drp-day-wrap',\n inRange && 'mgh-drp-day-wrap--in-range',\n inRange && isStart && 'mgh-drp-day-wrap--range-start',\n inRange && isEnd && 'mgh-drp-day-wrap--range-end',\n inPreview && 'mgh-drp-day-wrap--preview',\n inPreview && isSameDay(day, previewStart) && 'mgh-drp-day-wrap--preview-start',\n inPreview && isSameDay(day, previewEnd) && 'mgh-drp-day-wrap--preview-end',\n firstVisible && 'mgh-drp-day-wrap--first-visible',\n lastVisible && 'mgh-drp-day-wrap--last-visible'\n )}\n >\n <button\n type=\"button\"\n data-day={day.format('YYYY-MM-DD')}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={day.format('dddd, MMMM D, YYYY')}\n aria-current={\n !disableHighlightToday && isSameDay(day, today) ? 'date' : undefined\n }\n aria-disabled={dayDisabled || undefined}\n disabled={hidden}\n className={cx(\n 'mgh-drp-day',\n hidden && 'mgh-drp-day--hidden',\n outsideMonth && !hidden && 'mgh-drp-day--outside',\n selected && 'mgh-drp-day--selected',\n !disableHighlightToday && isSameDay(day, today) && 'mgh-drp-day--today',\n dayDisabled && 'mgh-drp-day--disabled'\n )}\n onClick={() => selectDay(day)}\n onMouseEnter={() => setHoveredDay(day)}\n onMouseLeave={() =>\n setHoveredDay((prev) => (prev && isSameDay(prev, day) ? null : prev))\n }\n onFocus={() => setFocusedDay(day)}\n onKeyDown={(event) => handleKeyDown(event, day)}\n >\n {day.date()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={rootRef}\n className={cx(\n 'mgh-drp-calendars',\n disabled && 'mgh-drp-calendar--disabled',\n readOnly && 'mgh-drp-calendar--read-only',\n className\n )}\n data-mgh-theme={themeMode}\n data-range-position={rangePosition}\n style={style}\n onMouseLeave={() => setHoveredDay(null)}\n >\n {visibleMonths.map(renderMonth)}\n </div>\n );\n}\n\nexport default MGHDateRangeCalendar;\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { clamp, cx } from './utils';\n\n/*\n * Field / popover primitives shared by MGHDateRangePicker and MGHDatePicker. They use the\n * `mgh-drp-*` stylesheet (see MGHDateRangePicker.styles.ts), so both pickers look identical and\n * are themed through the same `--mgh-drp-*` CSS variables.\n */\n\n/* -------------------------------------------------------------------------------------------------\n * Anchored popover (portal)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null;\n placement: 'bottom-start' | 'bottom-end' | 'bottom';\n onDismiss: (reason: 'backdrop' | 'escape') => void;\n themeMode?: 'light' | 'dark';\n className?: string;\n style?: React.CSSProperties;\n labelledBy?: string;\n children: React.ReactNode;\n}\n\nexport function Popover({\n open,\n anchorEl,\n placement,\n onDismiss,\n themeMode,\n className,\n style,\n labelledBy,\n children,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState({ top: 0, left: 0, ready: false });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n top = a.bottom + 4;\n if (top + h > vh - 8 && a.top - 4 - h >= 8) top = a.top - 4 - h;\n left = placement === 'bottom-end' ? a.right - w : placement === 'bottom' ? a.left + a.width / 2 - w / 2 : a.left;\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n onDismiss('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onDismiss('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onDismiss, anchorEl]);\n\n if (!open || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={labelledBy}\n tabIndex={-1}\n className={cx('mgh-drp-popover', className)}\n data-mgh-theme={themeMode}\n style={{ top: position.top, left: position.left, visibility: position.ready ? 'visible' : 'hidden', ...style }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Outlined text field (MUI TextField look-alike, no dependency)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextFieldProps {\n id: string;\n label?: React.ReactNode;\n value: string;\n placeholder?: string;\n size: 'small' | 'medium';\n fullWidth?: boolean;\n multi?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n error?: boolean;\n focused?: boolean;\n clickable?: boolean;\n name?: string;\n autoFocus?: boolean;\n inputRef?: React.Ref<HTMLInputElement>;\n adornment?: React.ReactNode;\n ariaLabel?: string;\n onChange: (text: string) => void;\n onFocus: () => void;\n onBlur: () => void;\n onClick?: () => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nexport const TextField = React.forwardRef<HTMLDivElement, TextFieldProps>(function TextField(\n {\n id,\n label,\n value,\n placeholder,\n size,\n fullWidth,\n multi,\n disabled,\n readOnly,\n required,\n error,\n focused,\n clickable,\n name,\n autoFocus,\n inputRef,\n adornment,\n ariaLabel,\n onChange,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n },\n ref\n) {\n const hasLabel = label != null && label !== '';\n const shrink = focused || value !== '' || !hasLabel;\n return (\n <div\n ref={ref}\n className={cx(\n 'mgh-drp-field',\n `mgh-drp-field--${size}`,\n fullWidth && 'mgh-drp-field--full-width',\n multi && 'mgh-drp-field--multi',\n shrink && 'mgh-drp-field--shrink',\n focused && 'mgh-drp-field--focused',\n disabled && 'mgh-drp-field--disabled',\n error && 'mgh-drp-field--error',\n clickable && 'mgh-drp-field--clickable',\n !hasLabel && 'mgh-drp-field--no-label',\n !!adornment && 'mgh-drp-field--adorned'\n )}\n onClick={onClick}\n >\n {hasLabel && (\n <label className=\"mgh-drp-label\" htmlFor={id}>\n {label}\n {required && (\n <span className=\"mgh-drp-label-asterisk\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <input\n id={id}\n ref={inputRef}\n name={name}\n className=\"mgh-drp-input\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"off\"\n spellCheck={false}\n value={value}\n placeholder={shrink ? placeholder : undefined}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n onChange={(event) => onChange(event.target.value)}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n />\n {adornment && <div className=\"mgh-drp-adornment\">{adornment}</div>}\n <fieldset aria-hidden=\"true\" className=\"mgh-drp-outline\">\n <legend>\n <span>\n {hasLabel ? label : ''}\n {hasLabel && required ? ' *' : ''}\n </span>\n </legend>\n </fieldset>\n </div>\n );\n});\n","import React from 'react';\nimport dayjs from 'dayjs';\nimport type {\n MGHDateRange,\n MGHDateRangeChangeContext,\n MGHDateRangePickerLocaleText,\n MGHDateRangePickerProps,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { MGHDateRangeCalendar } from './MGHDateRangeCalendar';\nimport { CloseIcon, DateRangeIcon } from './icons';\nimport { Popover, TextField } from './primitives';\nimport {\n EMPTY_RANGE,\n cx,\n formatDate,\n isRangeEqual,\n normalizeRange,\n parseDateText,\n splitRangeText,\n validateRange,\n} from './utils';\n\nexport const MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT: MGHDateRangePickerLocaleText = {\n start: 'Start',\n end: 'End',\n fieldSeparator: '–',\n openPicker: 'Choose date range',\n clear: 'Clear',\n today: 'Today',\n cancel: 'Cancel',\n accept: 'OK',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n toolbarTitle: 'Select date range',\n};\n\nconst DEFAULT_FORMAT = 'MM/DD/YYYY';\n\n/* -------------------------------------------------------------------------------------------------\n * MGHDateRangePicker\n * ----------------------------------------------------------------------------------------------- */\n\ntype FocusedInput = 'single' | 'start' | 'end' | null;\n\n/**\n * MUI-free port of MUI X Pro's `DateRangePicker` (desktop variant): an outlined text field with a\n * calendar button that opens a two-month range calendar, optional shortcuts and an action bar.\n * Values are dayjs `[start, end]` tuples so existing `DateRange<Dayjs>` state works unchanged.\n */\nexport const MGHDateRangePicker = React.forwardRef<HTMLDivElement, MGHDateRangePickerProps>(function MGHDateRangePicker(\n {\n value: valueProp,\n defaultValue,\n onChange,\n onAccept,\n onError,\n open: openProp,\n onOpen,\n onClose,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n label,\n format = DEFAULT_FORMAT,\n fieldVariant = 'single',\n size = 'small',\n fullWidth = false,\n clearable = false,\n openOnClick,\n disableOpenPicker = false,\n closeOnSelect,\n shortcuts,\n actions = [],\n showToolbar = false,\n localeText: localeTextProp,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n disableHighlightToday,\n showRangePreview,\n onMonthChange,\n name,\n id: idProp,\n placeholder: placeholderProp,\n required,\n error: errorProp,\n helperText,\n autoFocus,\n inputRef,\n themeMode,\n themeVars,\n className,\n style,\n popoverClassName,\n popoverStyle,\n placement = 'bottom-start',\n },\n ref\n) {\n useMGHDateRangePickerStyles();\n\n const localeText = React.useMemo(\n () => ({ ...MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n const datePlaceholder = localeText.datePlaceholder ?? format;\n const isMulti = fieldVariant === 'multi';\n const resolvedOpenOnClick = openOnClick ?? isMulti;\n const resolvedCloseOnSelect = closeOnSelect ?? !actions.includes('accept');\n\n const reactId = React.useId();\n const baseId = idProp ?? `mgh-drp-${reactId.replace(/:/g, '')}`;\n const startId = isMulti ? `${baseId}-start` : baseId;\n const endId = `${baseId}-end`;\n const dialogTitleId = `${baseId}-title`;\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n const validationError = React.useMemo(() => validateRange(value, validation), [value, validation]);\n const isValid = React.useCallback(\n (range: MGHDateRange) => validateRange(range, validation).every((e) => e == null),\n [validation]\n );\n\n const lastErrorRef = React.useRef<[MGHDateRangeValidationError, MGHDateRangeValidationError] | null>(null);\n React.useEffect(() => {\n const prev = lastErrorRef.current;\n if (prev && prev[0] === validationError[0] && prev[1] === validationError[1]) return;\n if (prev !== null || validationError[0] || validationError[1]) onError?.(validationError, value);\n lastErrorRef.current = validationError;\n }, [validationError, value, onError]);\n\n const setValue = React.useCallback(\n (next: MGHDateRange, shortcut?: MGHDateRangeShortcut) => {\n if (!isControlled) setInternalValue(next);\n const context: MGHDateRangeChangeContext = { validationError: validateRange(next, validation) };\n if (shortcut) context.shortcut = shortcut;\n onChange?.(next, context);\n },\n [isControlled, onChange, validation]\n );\n\n /* ---- range position ---- */\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n /* ---- open / close ---- */\n const isOpenControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = React.useState(false);\n const open = isOpenControlled ? !!openProp : internalOpen;\n const valueAtOpenRef = React.useRef<MGHDateRange>(value);\n const lastAcceptedRef = React.useRef<MGHDateRange>(value);\n\n /** Fires `onAccept` only when the value differs from the last accepted one (MUI semantics). */\n const accept = React.useCallback(\n (next: MGHDateRange, force = false) => {\n if (!force && isRangeEqual(next, lastAcceptedRef.current)) return;\n lastAcceptedRef.current = next;\n onAccept?.(next);\n },\n [onAccept]\n );\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n // Without an explicit `themeMode`, follow the closest `[data-mgh-theme]` ancestor (e.g. a dark MGHGrid card)\n // so the portaled popover matches the surface the field sits on.\n const [inheritedTheme, setInheritedTheme] = React.useState<'light' | 'dark' | undefined>(undefined);\n React.useEffect(() => {\n if (themeMode !== undefined) return;\n const attr = rootRef.current?.parentElement?.closest('[data-mgh-theme]')?.getAttribute('data-mgh-theme');\n setInheritedTheme(attr === 'dark' ? 'dark' : attr === 'light' ? 'light' : undefined);\n });\n const effectiveThemeMode = themeMode ?? inheritedTheme;\n\n // The popover anchor lives in state (not only in the ref) so a picker that mounts already open\n // is positioned under the field on its first commit instead of waiting for an unrelated re-render.\n const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null);\n const setRootRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n setAnchorEl(node);\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [ref]\n );\n\n const openPicker = React.useCallback(\n (position?: MGHDateRangePosition) => {\n if (disabled || readOnly || open) return;\n valueAtOpenRef.current = value;\n restoreFocusRef.current = (document.activeElement as HTMLElement | null) ?? null;\n setRangePosition(position ?? (start && !end ? 'end' : 'start'));\n if (!isOpenControlled) setInternalOpen(true);\n onOpen?.();\n },\n [disabled, readOnly, open, value, start, end, setRangePosition, isOpenControlled, onOpen]\n );\n\n const closePicker = React.useCallback(() => {\n if (!open) return;\n if (!isOpenControlled) setInternalOpen(false);\n onClose?.();\n const target = toggleRef.current ?? restoreFocusRef.current;\n window.setTimeout(() => target?.focus?.(), 0);\n }, [open, isOpenControlled, onClose]);\n\n const acceptAndClose = React.useCallback(\n (next: MGHDateRange) => {\n accept(next, true);\n closePicker();\n },\n [accept, closePicker]\n );\n\n const handleDismiss = React.useCallback(() => {\n // Clicking away / Escape keeps whatever was picked (MUI fires onAccept when the value changed).\n accept(value);\n closePicker();\n }, [value, accept, closePicker]);\n\n const handleCalendarChange = React.useCallback(\n (next: MGHDateRange, _day: dayjs.Dayjs, position: MGHDateRangePosition) => {\n setValue(next);\n if (position === 'end' && next[0] && next[1] && resolvedCloseOnSelect) acceptAndClose(next);\n },\n [setValue, resolvedCloseOnSelect, acceptAndClose]\n );\n\n const handleShortcut = (shortcut: MGHDateRangeShortcut) => {\n const next = normalizeRange(shortcut.getValue({ isValid }));\n setValue(next, shortcut);\n setRangePosition('start');\n acceptAndClose(next);\n };\n\n const handleAction = (action: 'clear' | 'today' | 'cancel' | 'accept') => {\n switch (action) {\n case 'clear': {\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n acceptAndClose(EMPTY_RANGE);\n break;\n }\n case 'today': {\n const today = dayjs().startOf('day');\n const next: MGHDateRange = [today, today];\n setValue(next);\n setRangePosition('start');\n if (resolvedCloseOnSelect) acceptAndClose(next);\n break;\n }\n case 'cancel': {\n if (!isRangeEqual(value, valueAtOpenRef.current)) setValue(valueAtOpenRef.current);\n closePicker();\n break;\n }\n case 'accept':\n default:\n acceptAndClose(value);\n }\n };\n\n /* ---- text fields ---- */\n const [focusedInput, setFocusedInput] = React.useState<FocusedInput>(null);\n const formatSingle = React.useCallback(\n (range: MGHDateRange) => {\n const [s, e] = range;\n if (!s && !e) return '';\n return `${s ? formatDate(s, format) : datePlaceholder} ${localeText.fieldSeparator} ${e ? formatDate(e, format) : datePlaceholder}`;\n },\n [format, datePlaceholder, localeText.fieldSeparator]\n );\n\n const [singleText, setSingleText] = React.useState(() => formatSingle(value));\n const [startText, setStartText] = React.useState(() => formatDate(start, format));\n const [endText, setEndText] = React.useState(() => formatDate(end, format));\n const [inputInvalid, setInputInvalid] = React.useState<{ single: boolean; start: boolean; end: boolean }>({\n single: false,\n start: false,\n end: false,\n });\n\n // Keep the text in sync with the value unless the user is typing in that input.\n React.useEffect(() => {\n if (focusedInput !== 'single') {\n setSingleText(formatSingle(value));\n setInputInvalid((prev) => (prev.single ? { ...prev, single: false } : prev));\n }\n if (focusedInput !== 'start') {\n setStartText(formatDate(start, format));\n setInputInvalid((prev) => (prev.start ? { ...prev, start: false } : prev));\n }\n if (focusedInput !== 'end') {\n setEndText(formatDate(end, format));\n setInputInvalid((prev) => (prev.end ? { ...prev, end: false } : prev));\n }\n }, [value, start, end, focusedInput, format, formatSingle]);\n\n const parseSegment = (text: string): { date: dayjs.Dayjs | null; invalid: boolean } => {\n const trimmed = text.trim();\n if (!trimmed || trimmed.toUpperCase() === datePlaceholder.toUpperCase()) return { date: null, invalid: false };\n const parsed = parseDateText(trimmed, format);\n return { date: parsed, invalid: parsed == null };\n };\n\n const handleSingleChange = (text: string) => {\n setSingleText(text);\n const [s, e] = splitRangeText(text);\n const ps = parseSegment(s);\n const pe = parseSegment(e);\n const invalid = ps.invalid || pe.invalid;\n setInputInvalid((prev) => ({ ...prev, single: invalid }));\n if (invalid) return;\n const next: MGHDateRange = [ps.date, pe.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleSideChange = (side: 'start' | 'end', text: string) => {\n if (side === 'start') setStartText(text);\n else setEndText(text);\n const parsed = parseSegment(text);\n setInputInvalid((prev) => ({ ...prev, [side]: parsed.invalid }));\n if (parsed.invalid) return;\n const next: MGHDateRange = side === 'start' ? [parsed.date, end] : [start, parsed.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleBlur = (input: Exclude<FocusedInput, null>) => {\n setFocusedInput((prev) => (prev === input ? null : prev));\n // Re-format on blur unless the text could not be parsed (keep it so the user sees the error).\n if (input === 'single' && !inputInvalid.single) setSingleText(formatSingle(value));\n if (input === 'start' && !inputInvalid.start) setStartText(formatDate(start, format));\n if (input === 'end' && !inputInvalid.end) setEndText(formatDate(end, format));\n // Leaving the field commits a typed value (like pressing Enter).\n if (!open) accept(value);\n };\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, position: MGHDateRangePosition) => {\n if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n openPicker(position);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (!open) accept(value);\n }\n };\n\n const clear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n accept(EMPTY_RANGE);\n };\n\n const hasValue = !!start || !!end;\n const hasValidationError = validationError.some((e) => e != null);\n const showError = !!errorProp || hasValidationError || inputInvalid.single || inputInvalid.start || inputInvalid.end;\n\n const openButton = !disableOpenPicker && (\n <button\n ref={toggleRef}\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.openPicker}\n title={localeText.openPicker}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (open) handleDismiss();\n else openPicker();\n }}\n >\n <DateRangeIcon size={size === 'small' ? 20 : 24} />\n </button>\n );\n\n const clearButton = clearable && hasValue && !disabled && !readOnly && (\n <button\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.clear}\n title={localeText.clear}\n onClick={clear}\n >\n <CloseIcon size={size === 'small' ? 18 : 20} />\n </button>\n );\n\n const themeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...style }),\n [themeVars, style]\n );\n const popoverThemeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...popoverStyle }),\n [themeVars, popoverStyle]\n );\n\n /* ---- shortcuts / actions / toolbar ---- */\n const shortcutItems = React.useMemo(\n () =>\n (shortcuts ?? []).map((shortcut, index) => {\n let shortcutValue: MGHDateRange = EMPTY_RANGE;\n try {\n shortcutValue = normalizeRange(shortcut.getValue({ isValid }));\n } catch {\n /* ignore */\n }\n return { shortcut, key: shortcut.id ?? `${shortcut.label}-${index}`, value: shortcutValue };\n }),\n [shortcuts, isValid]\n );\n\n const renderToolbar = () => (\n <div className=\"mgh-drp-toolbar\">\n <p className=\"mgh-drp-toolbar-title\" id={dialogTitleId}>\n {localeText.toolbarTitle}\n </p>\n <div className=\"mgh-drp-toolbar-range\">\n <button\n type=\"button\"\n className={cx(rangePosition === 'start' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('start')}\n >\n {start ? formatDate(start, format) : localeText.start}\n </button>\n <span>{localeText.fieldSeparator}</span>\n <button\n type=\"button\"\n className={cx(rangePosition === 'end' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('end')}\n >\n {end ? formatDate(end, format) : localeText.end}\n </button>\n </div>\n </div>\n );\n\n const renderActions = () =>\n actions.length > 0 && (\n <div className=\"mgh-drp-actions\">\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n className={cx('mgh-drp-btn', (action === 'accept' || action === 'today') && 'mgh-drp-btn--primary')}\n onClick={() => handleAction(action)}\n >\n {localeText[action]}\n </button>\n ))}\n </div>\n );\n\n const calendar = (\n <MGHDateRangeCalendar\n value={value}\n onChange={handleCalendarChange}\n rangePosition={rangePosition}\n onRangePositionChange={setRangePosition}\n calendars={calendars}\n referenceDate={referenceDate}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n showDaysOutsideCurrentMonth={showDaysOutsideCurrentMonth}\n fixedWeekNumber={fixedWeekNumber}\n dayOfWeekFormatter={dayOfWeekFormatter}\n disableHighlightToday={disableHighlightToday}\n showRangePreview={showRangePreview}\n onMonthChange={onMonthChange}\n localeText={localeText}\n themeMode={effectiveThemeMode}\n autoFocus\n />\n );\n\n /* ---- render ---- */\n const commonFieldProps = {\n size,\n fullWidth,\n disabled,\n readOnly,\n required,\n error: showError,\n };\n\n return (\n <div\n ref={setRootRef}\n className={cx('mgh-drp', fullWidth && 'mgh-drp--full-width', isMulti && 'mgh-drp--multi', className)}\n data-mgh-theme={effectiveThemeMode}\n style={themeStyle}\n >\n {isMulti ? (\n <div className=\"mgh-drp-fields\">\n <TextField\n {...commonFieldProps}\n multi\n id={startId}\n name={name ? `${name}-start` : undefined}\n label={localeText.start}\n value={startText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'start'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n onChange={(text) => handleSideChange('start', text)}\n onFocus={() => {\n setFocusedInput('start');\n setRangePosition('start');\n }}\n onBlur={() => handleBlur('start')}\n onClick={() => resolvedOpenOnClick && openPicker('start')}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n <span className=\"mgh-drp-fields-separator\" aria-hidden=\"true\">\n {localeText.fieldSeparator}\n </span>\n <TextField\n {...commonFieldProps}\n multi\n id={endId}\n name={name ? `${name}-end` : undefined}\n label={localeText.end}\n value={endText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'end'}\n clickable={resolvedOpenOnClick}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={(text) => handleSideChange('end', text)}\n onFocus={() => {\n setFocusedInput('end');\n setRangePosition('end');\n }}\n onBlur={() => handleBlur('end')}\n onClick={() => resolvedOpenOnClick && openPicker('end')}\n onKeyDown={(event) => handleInputKeyDown(event, 'end')}\n />\n </div>\n ) : (\n <TextField\n {...commonFieldProps}\n id={startId}\n name={name}\n label={label}\n value={singleText}\n placeholder={placeholderProp ?? `${datePlaceholder} ${localeText.fieldSeparator} ${datePlaceholder}`}\n focused={focusedInput === 'single'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n ariaLabel={label == null ? localeText.toolbarTitle : undefined}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={handleSingleChange}\n onFocus={() => setFocusedInput('single')}\n onBlur={() => handleBlur('single')}\n onClick={() => resolvedOpenOnClick && openPicker()}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n )}\n {helperText != null && helperText !== '' && (\n <div className={cx('mgh-drp-helper', showError && 'mgh-drp-helper--error')}>{helperText}</div>\n )}\n\n <Popover\n open={open}\n anchorEl={anchorEl}\n placement={placement}\n onDismiss={handleDismiss}\n themeMode={effectiveThemeMode}\n className={popoverClassName}\n style={popoverThemeStyle}\n labelledBy={showToolbar ? dialogTitleId : undefined}\n >\n <div className={cx('mgh-drp-layout', showToolbar && 'mgh-drp-layout--with-toolbar')}>\n {showToolbar && renderToolbar()}\n <div className=\"mgh-drp-layout-main\">\n {shortcutItems.length > 0 && (\n <ul className=\"mgh-drp-shortcuts\" aria-label=\"Shortcuts\">\n {shortcutItems.map(({ shortcut, key, value: shortcutValue }) => (\n <li key={key}>\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-shortcut',\n hasValue &&\n isRangeEqual(shortcutValue, value) &&\n 'mgh-drp-shortcut--selected'\n )}\n disabled={disabled || readOnly}\n onClick={() => handleShortcut(shortcut)}\n >\n {shortcut.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n {calendar}\n </div>\n {renderActions()}\n </div>\n </Popover>\n </div>\n );\n});\n\nMGHDateRangePicker.displayName = 'MGHDateRangePicker';\n\nexport default MGHDateRangePicker;\n","import React from 'react';\nimport { useMGHDateRangePickerStyles } from '../MGHDateRangePicker/MGHDateRangePicker.styles';\n\nexport const MGH_DATE_PICKER_STYLE_ID = 'mgh-dp-styles';\n\n/**\n * Extra rules for MGHDatePicker. The field, popover, buttons, day grid and the `--mgh-drp-*`\n * colour variables come from the MGHDateRangePicker stylesheet, which is injected alongside.\n * Dimensions follow MUI X's `DateCalendar` (320 × 334, 72 × 36 month / year buttons).\n */\nexport const MGH_DATE_PICKER_CSS = `\n[class*=\"mgh-dp-\"], [class*=\"mgh-dp-\"]::before, [class*=\"mgh-dp-\"]::after { box-sizing: border-box; }\n.mgh-dp .mgh-drp-field:not(.mgh-drp-field--full-width) { width: 240px; }\n\n/* ---- calendar ---- */\n.mgh-dp-calendar { display: flex; flex-direction: column; width: 320px; min-height: 334px; max-width: 100%; overflow: hidden; }\n.mgh-dp-header { display: flex; align-items: center; min-height: 40px; max-height: 40px; margin: 12px 0 8px; padding: 0 12px 0 24px; }\n.mgh-dp-header-label-wrap { display: flex; align-items: center; overflow: hidden; margin-right: auto; cursor: pointer; border-radius: 4px; }\n.mgh-dp-header-label-wrap--static, .mgh-dp-calendar--disabled .mgh-dp-header-label-wrap { cursor: default; }\n.mgh-dp-header-label { margin-right: 6px; font-size: 1rem; font-weight: 500; line-height: 1.75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.mgh-dp-header-switch { color: var(--mgh-drp-fg-secondary); }\n.mgh-dp-header-switch .mgh-drp-icon { transition: transform .2s ease; will-change: transform; }\n.mgh-dp-header-switch--open .mgh-drp-icon { transform: rotate(180deg); }\n.mgh-dp-header-nav { display: flex; align-items: center; flex: 0 0 auto; }\n.mgh-dp-header-nav .mgh-drp-btn--icon { color: var(--mgh-drp-fg-secondary); }\n.mgh-dp-header-nav-spacer { width: 24px; flex: 0 0 auto; }\n\n.mgh-dp-view { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }\n.mgh-dp-view--day { padding-bottom: 8px; }\n\n/* ---- month / year grids ---- */\n.mgh-dp-months, .mgh-dp-years { position: relative; display: flex; flex-direction: row; flex-wrap: wrap; align-content: flex-start; width: 100%; padding: 0 4px; }\n.mgh-dp-years { overflow-y: auto; max-height: 280px; }\n.mgh-dp-cell { display: flex; align-items: center; justify-content: center; flex-basis: 33.3333%; }\n.mgh-dp-cell--per-row-4 { flex-basis: 25%; }\n.mgh-dp-pill { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 72px; height: 36px; margin: 8px 0; border: 0; border-radius: 18px; background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 1rem; font-weight: 400; line-height: 1.75; letter-spacing: .00938em; cursor: pointer; transition: background-color .15s, color .15s; }\n.mgh-dp-years .mgh-dp-pill { margin: 6px 0; }\n.mgh-dp-pill:hover { background: var(--mgh-drp-hover); }\n.mgh-dp-pill:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: -1px; }\n.mgh-dp-pill--current:not(.mgh-dp-pill--selected) { border: 1px solid var(--mgh-drp-fg-secondary); }\n.mgh-dp-pill--disabled, .mgh-dp-pill--disabled:hover { color: var(--mgh-drp-fg-disabled); background: transparent; cursor: default; }\n.mgh-dp-pill--selected, .mgh-dp-pill--selected:hover { background: var(--mgh-drp-primary); color: var(--mgh-drp-primary-contrast); font-weight: 500; }\n.mgh-dp-pill--selected:focus-visible { outline-offset: 2px; }\n.mgh-dp-calendar--disabled .mgh-dp-pill, .mgh-dp-calendar--read-only .mgh-dp-pill { cursor: default; }\n.mgh-dp-calendar--disabled .mgh-dp-pill { color: var(--mgh-drp-fg-disabled); }\n.mgh-dp-calendar--disabled .mgh-dp-pill--selected { opacity: .6; }\n.mgh-dp-calendar--disabled .mgh-drp-day { color: var(--mgh-drp-fg-disabled); cursor: default; }\n.mgh-dp-calendar--disabled .mgh-drp-day--selected { opacity: .6; }\n.mgh-dp-calendar--read-only .mgh-drp-day { cursor: default; }\n\n/* ---- toolbar (MUI DatePickerToolbar) ---- */\n.mgh-dp-toolbar-date { display: flex; align-items: center; min-height: 40px; font-size: 2.125rem; font-weight: 400; line-height: 1.235; letter-spacing: .00735em; }\n\n@media (max-width: 599.95px) {\n .mgh-dp-calendar { width: 100%; max-width: 320px; }\n}\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_DATE_PICKER_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_DATE_PICKER_STYLE_ID;\n style.setAttribute('data-mgh-dp', 'true');\n style.textContent = MGH_DATE_PICKER_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHDateRangePicker + MGHDatePicker stylesheets once per document. Safe on the server (no-op). */\nexport const useMGHDatePickerStyles = () => {\n useMGHDateRangePickerStyles();\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateShortcut, MGHDateValidationError, MGHDateValue } from './MGHDatePicker.types';\nimport { isAfterDay, isBeforeDay, toDayjs } from '../MGHDateRangePicker/utils';\n\n/** MUI's default calendar bounds; used for the year grid when no `minDate` / `maxDate` is given. */\nexport const MGH_DATE_PICKER_DEFAULT_MIN_DATE = dayjs('1900-01-01');\nexport const MGH_DATE_PICKER_DEFAULT_MAX_DATE = dayjs('2099-12-31');\n\nexport const normalizeDate = (value: unknown): MGHDateValue => toDayjs(value);\n\nexport const isDateEqual = (a: MGHDateValue | undefined, b: MGHDateValue | undefined) =>\n (a == null && b == null) || (!!a && !!b && a.isSame(b, 'day'));\n\n/** `date`'s calendar day with `time`'s time of day (MUI `mergeDateAndTime`). */\nexport const mergeDateAndTime = (date: Dayjs, time: Dayjs | null | undefined) =>\n time ? date.hour(time.hour()).minute(time.minute()).second(time.second()).millisecond(time.millisecond()) : date;\n\n/** `date` moved to `year`, clamping the day (Feb 29 → Feb 28) instead of overflowing into the next month. */\nexport const setYear = (date: Dayjs, year: number) => {\n const first = date.startOf('month').year(year);\n return mergeDateAndTime(first.date(Math.min(date.date(), first.daysInMonth())), date);\n};\n\n/** `date` moved to `month` (0–11), clamping the day (Jan 31 → Feb 28) instead of overflowing. */\nexport const setMonth = (date: Dayjs, month: number) => {\n const first = date.startOf('month').month(month);\n return mergeDateAndTime(first.date(Math.min(date.date(), first.daysInMonth())), date);\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validation (mirrors MUI's DateValidationError semantics and order)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface DateValidationOptions {\n minDate?: Dayjs | null;\n maxDate?: Dayjs | null;\n disablePast?: boolean;\n disableFuture?: boolean;\n shouldDisableDate?: (day: Dayjs) => boolean;\n shouldDisableMonth?: (month: Dayjs) => boolean;\n shouldDisableYear?: (year: Dayjs) => boolean;\n}\n\nexport const validateDate = (\n value: MGHDateValue,\n options: DateValidationOptions,\n now: Dayjs = dayjs()\n): MGHDateValidationError => {\n if (value == null) return null;\n if (!value.isValid()) return 'invalidDate';\n if (options.shouldDisableDate?.(value)) return 'shouldDisableDate';\n if (options.shouldDisableMonth?.(value)) return 'shouldDisableMonth';\n if (options.shouldDisableYear?.(value)) return 'shouldDisableYear';\n if (options.disableFuture && isAfterDay(value, now)) return 'disableFuture';\n if (options.disablePast && isBeforeDay(value, now)) return 'disablePast';\n if (options.minDate && isBeforeDay(value, options.minDate)) return 'minDate';\n if (options.maxDate && isAfterDay(value, options.maxDate)) return 'maxDate';\n return null;\n};\n\nexport const isDateDisabled = (day: Dayjs, options: DateValidationOptions, now?: Dayjs) =>\n validateDate(day, options, now) != null;\n\n/** A month is disabled when every day in it is out of bounds (MUI `MonthCalendar` semantics). */\nexport const isMonthDisabled = (month: Dayjs, options: DateValidationOptions, now: Dayjs = dayjs()) => {\n const start = month.startOf('month');\n const end = month.endOf('month');\n if (options.disablePast && isBeforeDay(end, now)) return true;\n if (options.disableFuture && isAfterDay(start, now)) return true;\n if (options.minDate && isBeforeDay(end, options.minDate)) return true;\n if (options.maxDate && isAfterDay(start, options.maxDate)) return true;\n return !!options.shouldDisableMonth?.(start);\n};\n\n/** A year is disabled when every day in it is out of bounds (MUI `YearCalendar` semantics). */\nexport const isYearDisabled = (year: Dayjs, options: DateValidationOptions, now: Dayjs = dayjs()) => {\n const start = year.startOf('year');\n const end = year.endOf('year');\n if (options.disablePast && isBeforeDay(end, now)) return true;\n if (options.disableFuture && isAfterDay(start, now)) return true;\n if (options.minDate && isBeforeDay(end, options.minDate)) return true;\n if (options.maxDate && isAfterDay(start, options.maxDate)) return true;\n return !!options.shouldDisableYear?.(start);\n};\n\n/**\n * Nearest enabled day to `date`, searching forwards and backwards at the same time within\n * `minDate` / `maxDate` (MUI `findClosestEnabledDate`). Returns `null` when nothing is enabled.\n */\nexport const findClosestEnabledDate = (date: Dayjs, options: DateValidationOptions, now: Dayjs = dayjs()): Dayjs | null => {\n let minDate = options.minDate ?? MGH_DATE_PICKER_DEFAULT_MIN_DATE;\n let maxDate = options.maxDate ?? MGH_DATE_PICKER_DEFAULT_MAX_DATE;\n if (options.disablePast && isAfterDay(now, minDate)) minDate = now;\n if (options.disableFuture && isBeforeDay(now, maxDate)) maxDate = now;\n if (isAfterDay(minDate, maxDate)) return null;\n\n let forward: Dayjs | null = date;\n let backward: Dayjs | null = date;\n if (isBeforeDay(date, minDate)) {\n forward = minDate;\n backward = null;\n }\n if (isAfterDay(date, maxDate)) {\n if (backward) backward = maxDate;\n forward = null;\n }\n let guard = 0;\n while ((forward || backward) && guard < 100000) {\n guard += 1;\n if (forward && isAfterDay(forward, maxDate)) forward = null;\n if (backward && isBeforeDay(backward, minDate)) backward = null;\n if (forward) {\n if (!isDateDisabled(forward, options, now)) return forward;\n forward = forward.add(1, 'day');\n }\n if (backward) {\n if (!isDateDisabled(backward, options, now)) return backward;\n backward = backward.subtract(1, 'day');\n }\n }\n return null;\n};\n\n/** Years listed in the year view. */\nexport const getYearRange = (minDate?: Dayjs | null, maxDate?: Dayjs | null): number[] => {\n const from = (minDate ?? MGH_DATE_PICKER_DEFAULT_MIN_DATE).year();\n const to = (maxDate ?? MGH_DATE_PICKER_DEFAULT_MAX_DATE).year();\n return Array.from({ length: Math.max(to - from + 1, 1) }, (_, i) => from + i);\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Shortcuts (same shape as MUI's PickersShortcuts items)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const MGH_DATE_PICKER_DEFAULT_SHORTCUTS: MGHDateShortcut[] = [\n { label: 'Today', getValue: () => dayjs().startOf('day') },\n { label: 'Yesterday', getValue: () => dayjs().subtract(1, 'day').startOf('day') },\n { label: 'Tomorrow', getValue: () => dayjs().add(1, 'day').startOf('day') },\n { label: 'Start of Week', getValue: () => dayjs().startOf('week') },\n { label: 'Start of Month', getValue: () => dayjs().startOf('month') },\n { label: 'End of Month', getValue: () => dayjs().endOf('month').startOf('day') },\n { label: 'Reset', getValue: () => null },\n];\n","import React from 'react';\nimport dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateCalendarProps, MGHDateSelectionState, MGHDateValue, MGHDateView } from './MGHDatePicker.types';\nimport { useMGHDatePickerStyles } from './MGHDatePicker.styles';\nimport { ArrowDropDownIcon, ChevronLeftIcon, ChevronRightIcon } from '../MGHDateRangePicker/icons';\nimport { cx, getMonthWeeks, getWeekDayLabels, isAfterDay, isBeforeDay, isSameDay } from '../MGHDateRangePicker/utils';\nimport {\n findClosestEnabledDate,\n getYearRange,\n isDateDisabled,\n isDateEqual,\n isMonthDisabled,\n isYearDisabled,\n mergeDateAndTime,\n normalizeDate,\n setMonth,\n setYear,\n type DateValidationOptions,\n} from './utils';\n\nconst defaultDayOfWeekFormatter = (day: Dayjs) => day.format('dd').charAt(0).toUpperCase();\nconst DEFAULT_VIEWS: MGHDateView[] = ['year', 'day'];\nconst defaultSwitchViewLabel = (view: MGHDateView) =>\n view === 'year' ? 'year view is open, switch to calendar view' : 'calendar view is open, switch to year view';\n\n/**\n * Pure-React port of MUI X's `DateCalendar`: a single month with a header whose ▾ button switches\n * to the year (and optionally month) view, keyboard navigation and min/max/disabled validation.\n */\nexport function MGHDateCalendar({\n value: valueProp,\n defaultValue,\n onChange,\n referenceDate,\n views: viewsProp,\n openTo = 'day',\n view: viewProp,\n onViewChange,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth = false,\n fixedWeekNumber,\n dayOfWeekFormatter = defaultDayOfWeekFormatter,\n disableHighlightToday = false,\n yearsPerRow = 3,\n monthsPerRow = 3,\n autoFocus = false,\n onMonthChange,\n onYearChange,\n localeText,\n themeMode,\n className,\n style,\n}: MGHDateCalendarProps) {\n useMGHDatePickerStyles();\n\n const views = React.useMemo(() => (viewsProp && viewsProp.length > 0 ? viewsProp : DEFAULT_VIEWS), [viewsProp]);\n const today = dayjs();\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateValue>(() => normalizeDate(defaultValue ?? null));\n const value = React.useMemo(\n () => (isControlled ? normalizeDate(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n\n /* ---- view ---- */\n const [internalView, setInternalView] = React.useState<MGHDateView>(() => (views.includes(openTo) ? openTo : views[0]));\n const view: MGHDateView =\n viewProp !== undefined && views.includes(viewProp)\n ? viewProp\n : views.includes(internalView)\n ? internalView\n : views[0];\n const setView = React.useCallback(\n (next: MGHDateView) => {\n if (viewProp === undefined) setInternalView(next);\n onViewChange?.(next);\n },\n [viewProp, onViewChange]\n );\n\n const validation = React.useMemo<DateValidationOptions>(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear]\n );\n\n /* ---- visible month ---- */\n const [currentMonth, setCurrentMonth] = React.useState<Dayjs>(() => (value ?? referenceDate ?? today).startOf('month'));\n const changeMonth = React.useCallback(\n (month: Dayjs) => {\n const next = month.startOf('month');\n if (currentMonth.isSame(next, 'month')) return;\n setCurrentMonth(next);\n onMonthChange?.(next);\n },\n [currentMonth, onMonthChange]\n );\n\n // When a value arrives from outside (typed in the field / shortcut) scroll to it.\n const lastSeenRef = React.useRef<MGHDateValue>(value);\n React.useEffect(() => {\n const prev = lastSeenRef.current;\n lastSeenRef.current = value;\n if (value && !isDateEqual(prev, value) && !value.isSame(currentMonth, 'month')) changeMonth(value);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n const firstEnabledMonth = disablePast && (!minDate || isAfterDay(today, minDate)) ? today : minDate;\n const lastEnabledMonth = disableFuture && (!maxDate || isBeforeDay(today, maxDate)) ? today : maxDate;\n const canGoPrev = !firstEnabledMonth || currentMonth.isAfter(firstEnabledMonth, 'month');\n const canGoNext = !lastEnabledMonth || currentMonth.isBefore(lastEnabledMonth, 'month');\n\n /* ---- focus management (roving tabindex + focus after a view change) ---- */\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const yearsRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef(autoFocus);\n const [focusedDay, setFocusedDay] = React.useState<Dayjs>(() => value ?? referenceDate ?? today);\n\n React.useEffect(() => {\n if (!pendingFocusRef.current) return undefined;\n const id = window.setTimeout(() => {\n pendingFocusRef.current = false;\n rootRef.current?.querySelector<HTMLElement>('.mgh-dp-view [tabindex=\"0\"]')?.focus({ preventScroll: true });\n }, 0);\n return () => window.clearTimeout(id);\n });\n\n // Scroll the selected (or current) year to the middle of the list, like MUI's YearCalendar.\n React.useEffect(() => {\n if (view !== 'year') return;\n const container = yearsRef.current;\n const target =\n container?.querySelector<HTMLElement>('.mgh-dp-pill--selected') ??\n container?.querySelector<HTMLElement>('[tabindex=\"0\"]');\n if (container && target) {\n container.scrollTop = target.offsetTop - container.clientHeight / 2 + target.offsetHeight / 2;\n }\n }, [view]);\n\n /* ---- selection (MUI `useViews` semantics) ---- */\n const commit = React.useCallback(\n (next: Dayjs, fromView: MGHDateView) => {\n const index = views.indexOf(fromView);\n const nextView = index >= 0 ? views[index + 1] : undefined;\n const selectionState: MGHDateSelectionState = nextView ? 'partial' : 'finish';\n if (!isControlled) setInternalValue(next);\n onChange?.(next, selectionState, fromView);\n if (nextView) {\n pendingFocusRef.current = true;\n setView(nextView);\n }\n },\n [views, isControlled, onChange, setView]\n );\n\n const goToNextView = React.useCallback(() => {\n const nextView = views[views.indexOf(view) + 1];\n if (!nextView) return;\n pendingFocusRef.current = true;\n setView(nextView);\n }, [views, view, setView]);\n\n const selectDay = (day: Dayjs) => {\n if (disabled || readOnly || isDateDisabled(day, validation, today)) return;\n setFocusedDay(day);\n commit(mergeDateAndTime(day, value ?? referenceDate), 'day');\n };\n\n /** Shared by the year and month views: move the (or a reference) date, then jump to the closest enabled day. */\n const selectPeriod = (candidate: Dayjs, unit: 'year' | 'month', fromView: MGHDateView) => {\n if (disabled || readOnly) return;\n const periodStart = candidate.startOf(unit);\n const periodEnd = candidate.endOf(unit);\n const closest = isDateDisabled(candidate, validation, today)\n ? findClosestEnabledDate(\n candidate,\n {\n ...validation,\n minDate: minDate && isAfterDay(minDate, periodStart) ? minDate : periodStart,\n maxDate: maxDate && isBeforeDay(maxDate, periodEnd) ? maxDate : periodEnd,\n },\n today\n )\n : candidate;\n if (closest) {\n changeMonth(closest);\n setFocusedDay(closest);\n commit(closest, fromView);\n if (unit === 'year') onYearChange?.(closest);\n } else {\n changeMonth(periodStart);\n goToNextView();\n }\n };\n\n const baseDate = value ?? referenceDate ?? today.startOf('day');\n const selectYear = (year: number) => {\n if (isYearDisabled(dayjs().year(year), validation, today)) return;\n selectPeriod(setYear(baseDate, year), 'year', 'year');\n };\n const selectMonth = (month: number) => {\n const candidate = setMonth(baseDate.year(currentMonth.year()), month);\n if (isMonthDisabled(candidate, validation, today)) return;\n selectPeriod(candidate, 'month', 'month');\n };\n\n const toggleView = () => {\n if (views.length === 1 || disabled) return;\n pendingFocusRef.current = true;\n if (views.length === 2) setView(views.find((v) => v !== view) ?? views[0]);\n else setView(views.indexOf(view) !== 0 ? views[0] : views[1]);\n };\n\n /* ---- keyboard ---- */\n const focusDay = (day: Dayjs) => {\n const key = day.format('YYYY-MM-DD');\n rootRef.current?.querySelector<HTMLButtonElement>(`[data-day=\"${key}\"]`)?.focus();\n };\n const moveDayFocus = (day: Dayjs) => {\n setFocusedDay(day);\n if (!day.isSame(currentMonth, 'month')) changeMonth(day);\n window.setTimeout(() => focusDay(day), 0);\n };\n const handleDayKeyDown = (event: React.KeyboardEvent<HTMLElement>, day: Dayjs) => {\n let next: Dayjs | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = day.subtract(1, 'day');\n break;\n case 'ArrowRight':\n next = day.add(1, 'day');\n break;\n case 'ArrowUp':\n next = day.subtract(7, 'day');\n break;\n case 'ArrowDown':\n next = day.add(7, 'day');\n break;\n case 'Home':\n next = day.startOf('week');\n break;\n case 'End':\n next = day.endOf('week');\n break;\n case 'PageUp':\n next = event.shiftKey ? day.subtract(1, 'year') : day.subtract(1, 'month');\n break;\n case 'PageDown':\n next = event.shiftKey ? day.add(1, 'year') : day.add(1, 'month');\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n selectDay(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (next) moveDayFocus(next);\n };\n\n /** Arrow-key navigation inside the month / year grids (`attr` is `data-month` or `data-year`). */\n const handleGridKeyDown = (\n event: React.KeyboardEvent<HTMLElement>,\n attr: 'data-month' | 'data-year',\n current: number,\n values: number[],\n perRow: number,\n select: (v: number) => void\n ) => {\n const index = values.indexOf(current);\n let nextIndex = index;\n switch (event.key) {\n case 'ArrowLeft':\n nextIndex = index - 1;\n break;\n case 'ArrowRight':\n nextIndex = index + 1;\n break;\n case 'ArrowUp':\n nextIndex = index - perRow;\n break;\n case 'ArrowDown':\n nextIndex = index + perRow;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = values.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n select(current);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (nextIndex < 0 || nextIndex >= values.length) return;\n rootRef.current?.querySelector<HTMLButtonElement>(`[${attr}=\"${values[nextIndex]}\"]`)?.focus();\n };\n\n /* ---- render: header ---- */\n const switchLabel = localeText?.calendarViewSwitchingButtonAriaLabel ?? defaultSwitchViewLabel;\n const renderHeader = () => (\n <div className=\"mgh-dp-header\">\n <div\n role=\"presentation\"\n className={cx('mgh-dp-header-label-wrap', views.length === 1 && 'mgh-dp-header-label-wrap--static')}\n aria-live=\"polite\"\n onClick={toggleView}\n >\n <div className=\"mgh-dp-header-label\">{currentMonth.format('MMMM YYYY')}</div>\n {views.length > 1 && !disabled && (\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-btn mgh-drp-btn--icon mgh-dp-header-switch',\n view !== 'day' && 'mgh-dp-header-switch--open'\n )}\n aria-label={switchLabel(view)}\n >\n <ArrowDropDownIcon />\n </button>\n )}\n </div>\n {view === 'day' && (\n <div className=\"mgh-dp-header-nav\">\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.previousMonth ?? 'Previous month'}\n title={localeText?.previousMonth ?? 'Previous month'}\n disabled={disabled || !canGoPrev}\n onClick={() => changeMonth(currentMonth.subtract(1, 'month'))}\n >\n <ChevronLeftIcon />\n </button>\n <span className=\"mgh-dp-header-nav-spacer\" />\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.nextMonth ?? 'Next month'}\n title={localeText?.nextMonth ?? 'Next month'}\n disabled={disabled || !canGoNext}\n onClick={() => changeMonth(currentMonth.add(1, 'month'))}\n >\n <ChevronRightIcon />\n </button>\n </div>\n )}\n </div>\n );\n\n /* ---- render: day view ---- */\n const weekDays = React.useMemo(() => getWeekDayLabels(dayOfWeekFormatter), [dayOfWeekFormatter]);\n const renderDayView = () => {\n const weeks = getMonthWeeks(currentMonth, fixedWeekNumber);\n const tabbableDay =\n (focusedDay.isSame(currentMonth, 'month') ? focusedDay : null) ??\n (value && value.isSame(currentMonth, 'month') ? value : null) ??\n (today.isSame(currentMonth, 'month') ? today : null) ??\n currentMonth.startOf('month');\n return (\n <div className=\"mgh-dp-view mgh-dp-view--day\" role=\"group\" aria-label={currentMonth.format('MMMM YYYY')}>\n <div className=\"mgh-drp-weekdays\" role=\"row\">\n {weekDays.map((wd) => (\n <span key={wd.key} className=\"mgh-drp-weekday\" role=\"columnheader\" aria-label={wd.full}>\n {wd.label}\n </span>\n ))}\n </div>\n <div className=\"mgh-drp-weeks\" role=\"grid\" aria-label={currentMonth.format('MMMM YYYY')}>\n {weeks.map((week) => (\n <div key={week.key} className=\"mgh-drp-week\" role=\"row\">\n {week.days.map(({ day, outsideMonth }) => {\n const hidden = outsideMonth && !showDaysOutsideCurrentMonth;\n const selected = isSameDay(day, value);\n const isToday = !disableHighlightToday && isSameDay(day, today);\n const dayDisabled = disabled || isDateDisabled(day, validation, today);\n const isTabbable = !hidden && isSameDay(day, tabbableDay);\n return (\n <div\n key={day.format('YYYY-MM-DD')}\n role=\"gridcell\"\n aria-selected={selected || undefined}\n className=\"mgh-drp-day-wrap\"\n >\n <button\n type=\"button\"\n data-day={day.format('YYYY-MM-DD')}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={day.format('dddd, MMMM D, YYYY')}\n aria-current={isToday ? 'date' : undefined}\n aria-disabled={dayDisabled || undefined}\n disabled={hidden}\n className={cx(\n 'mgh-drp-day',\n hidden && 'mgh-drp-day--hidden',\n outsideMonth && !hidden && 'mgh-drp-day--outside',\n selected && 'mgh-drp-day--selected',\n isToday && 'mgh-drp-day--today',\n dayDisabled && 'mgh-drp-day--disabled'\n )}\n onClick={() => selectDay(day)}\n onFocus={() => setFocusedDay(day)}\n onKeyDown={(event) => handleDayKeyDown(event, day)}\n >\n {day.date()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n /* ---- render: month view ---- */\n const renderMonthView = () => {\n const months = Array.from({ length: 12 }, (_, i) => i);\n const selectedMonth = value && value.year() === currentMonth.year() ? value.month() : null;\n const currentMonthIndex = today.year() === currentMonth.year() ? today.month() : null;\n const tabbable = selectedMonth ?? currentMonthIndex ?? 0;\n return (\n <div className=\"mgh-dp-view mgh-dp-view--month\">\n <div className=\"mgh-dp-months\" role=\"radiogroup\" aria-label={currentMonth.format('YYYY')}>\n {months.map((month) => {\n const monthDate = currentMonth.month(month);\n const monthDisabled = disabled || isMonthDisabled(monthDate, validation, today);\n const selected = selectedMonth === month;\n return (\n <div key={month} className={cx('mgh-dp-cell', monthsPerRow === 4 && 'mgh-dp-cell--per-row-4')}>\n <button\n type=\"button\"\n role=\"radio\"\n data-month={month}\n tabIndex={tabbable === month ? 0 : -1}\n aria-checked={selected}\n aria-current={currentMonthIndex === month ? 'date' : undefined}\n aria-disabled={monthDisabled || undefined}\n aria-label={monthDate.format('MMMM YYYY')}\n className={cx(\n 'mgh-dp-pill mgh-dp-month',\n selected && 'mgh-dp-pill--selected',\n currentMonthIndex === month && 'mgh-dp-pill--current',\n monthDisabled && 'mgh-dp-pill--disabled'\n )}\n onClick={() => selectMonth(month)}\n onKeyDown={(event) =>\n handleGridKeyDown(event, 'data-month', month, months, monthsPerRow, selectMonth)\n }\n >\n {monthDate.format('MMM')}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n );\n };\n\n /* ---- render: year view ---- */\n const renderYearView = () => {\n const years = getYearRange(minDate, maxDate);\n const selectedYear = value ? value.year() : null;\n const tabbable =\n (selectedYear != null && years.includes(selectedYear) ? selectedYear : null) ??\n (years.includes(today.year()) ? today.year() : null) ??\n (years.includes(currentMonth.year()) ? currentMonth.year() : years[0]);\n return (\n <div className=\"mgh-dp-view mgh-dp-view--year\">\n <div ref={yearsRef} className=\"mgh-dp-years\" role=\"radiogroup\" aria-label=\"Year\">\n {years.map((year) => {\n const yearDate = currentMonth.year(year);\n const yearDisabled = disabled || isYearDisabled(yearDate, validation, today);\n const selected = selectedYear === year;\n const isCurrent = today.year() === year;\n return (\n <div key={year} className={cx('mgh-dp-cell', yearsPerRow === 4 && 'mgh-dp-cell--per-row-4')}>\n <button\n type=\"button\"\n role=\"radio\"\n data-year={year}\n tabIndex={tabbable === year ? 0 : -1}\n aria-checked={selected}\n aria-current={isCurrent ? 'date' : undefined}\n aria-disabled={yearDisabled || undefined}\n className={cx(\n 'mgh-dp-pill mgh-dp-year',\n selected && 'mgh-dp-pill--selected',\n isCurrent && 'mgh-dp-pill--current',\n yearDisabled && 'mgh-dp-pill--disabled'\n )}\n onClick={() => selectYear(year)}\n onKeyDown={(event) =>\n handleGridKeyDown(event, 'data-year', year, years, yearsPerRow, selectYear)\n }\n >\n {year}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={rootRef}\n className={cx(\n 'mgh-dp-calendar',\n disabled && 'mgh-dp-calendar--disabled',\n readOnly && 'mgh-dp-calendar--read-only',\n className\n )}\n data-mgh-theme={themeMode}\n data-view={view}\n style={style}\n >\n {renderHeader()}\n {view === 'day' && renderDayView()}\n {view === 'month' && renderMonthView()}\n {view === 'year' && renderYearView()}\n </div>\n );\n}\n\nexport default MGHDateCalendar;\n","import React from 'react';\nimport dayjs from 'dayjs';\nimport type {\n MGHDateAction,\n MGHDateChangeContext,\n MGHDatePickerLocaleText,\n MGHDatePickerProps,\n MGHDateSelectionState,\n MGHDateShortcut,\n MGHDateValidationError,\n MGHDateValue,\n} from './MGHDatePicker.types';\nimport { useMGHDatePickerStyles } from './MGHDatePicker.styles';\nimport { MGHDateCalendar } from './MGHDateCalendar';\nimport { CalendarIcon, CloseIcon } from '../MGHDateRangePicker/icons';\nimport { Popover, TextField } from '../MGHDateRangePicker/primitives';\nimport { cx, formatDate, parseDateText } from '../MGHDateRangePicker/utils';\nimport { isDateEqual, normalizeDate, validateDate } from './utils';\n\nexport const MGH_DATE_PICKER_DEFAULT_LOCALE_TEXT: MGHDatePickerLocaleText = {\n openPicker: (formattedDate) => (formattedDate ? `Choose date, selected date is ${formattedDate}` : 'Choose date'),\n clear: 'Clear',\n today: 'Today',\n cancel: 'Cancel',\n accept: 'OK',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n calendarViewSwitchingButtonAriaLabel: (view) =>\n view === 'year' ? 'year view is open, switch to calendar view' : 'calendar view is open, switch to year view',\n toolbarTitle: 'Select date',\n toolbarPlaceholder: '––',\n};\n\nconst DEFAULT_FORMAT = 'MM/DD/YYYY';\nconst DEFAULT_TOOLBAR_FORMAT = 'ddd, MMM D';\n\n/**\n * MUI-free port of MUI X's `DatePicker` (desktop variant): an outlined text field with a calendar\n * button that opens a single-month calendar (with the year view behind the ▾ in the header),\n * optional shortcuts and an action bar. Values are `Dayjs | null`, so existing MUI state works unchanged.\n * Shares its field, popover and stylesheet with `MGHDateRangePicker`.\n */\nexport const MGHDatePicker = React.forwardRef<HTMLDivElement, MGHDatePickerProps>(function MGHDatePicker(\n {\n value: valueProp,\n defaultValue,\n onChange,\n onAccept,\n onError,\n open: openProp,\n onOpen,\n onClose,\n label,\n format = DEFAULT_FORMAT,\n size = 'small',\n fullWidth = false,\n clearable = false,\n openOnClick = false,\n disableOpenPicker = false,\n closeOnSelect,\n shortcuts,\n actions = [],\n showToolbar = false,\n toolbarFormat = DEFAULT_TOOLBAR_FORMAT,\n localeText: localeTextProp,\n referenceDate,\n views,\n openTo,\n view,\n onViewChange,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n disableHighlightToday,\n yearsPerRow,\n monthsPerRow,\n onMonthChange,\n onYearChange,\n name,\n id: idProp,\n placeholder: placeholderProp,\n required,\n error: errorProp,\n helperText,\n autoFocus,\n inputRef,\n themeMode,\n themeVars,\n className,\n style,\n popoverClassName,\n popoverStyle,\n placement = 'bottom-start',\n },\n ref\n) {\n useMGHDatePickerStyles();\n\n const localeText = React.useMemo(\n () => ({ ...MGH_DATE_PICKER_DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n const datePlaceholder = localeText.datePlaceholder ?? format;\n const resolvedCloseOnSelect = closeOnSelect ?? !actions.includes('accept');\n\n const reactId = React.useId();\n const inputId = idProp ?? `mgh-dp-${reactId.replace(/:/g, '')}`;\n const dialogTitleId = `${inputId}-title`;\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateValue>(() => normalizeDate(defaultValue ?? null));\n const value = React.useMemo(\n () => (isControlled ? normalizeDate(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear]\n );\n const validationError = React.useMemo(() => validateDate(value, validation), [value, validation]);\n const isValid = React.useCallback((date: MGHDateValue) => validateDate(date, validation) == null, [validation]);\n\n const lastErrorRef = React.useRef<MGHDateValidationError | undefined>(undefined);\n React.useEffect(() => {\n const prev = lastErrorRef.current;\n if (prev !== undefined && prev === validationError) return;\n if (prev !== undefined || validationError) onError?.(validationError, value);\n lastErrorRef.current = validationError;\n }, [validationError, value, onError]);\n\n const setValue = React.useCallback(\n (next: MGHDateValue, shortcut?: MGHDateShortcut) => {\n if (!isControlled) setInternalValue(next);\n const context: MGHDateChangeContext = { validationError: validateDate(next, validation) };\n if (shortcut) context.shortcut = shortcut;\n onChange?.(next, context);\n },\n [isControlled, onChange, validation]\n );\n\n /* ---- open / close ---- */\n const isOpenControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = React.useState(false);\n const open = isOpenControlled ? !!openProp : internalOpen;\n const valueAtOpenRef = React.useRef<MGHDateValue>(value);\n const lastAcceptedRef = React.useRef<MGHDateValue>(value);\n\n /** Fires `onAccept` only when the value differs from the last accepted one (MUI semantics). */\n const accept = React.useCallback(\n (next: MGHDateValue, force = false) => {\n if (!force && isDateEqual(next, lastAcceptedRef.current)) return;\n lastAcceptedRef.current = next;\n onAccept?.(next);\n },\n [onAccept]\n );\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n // Without an explicit `themeMode`, follow the closest `[data-mgh-theme]` ancestor (e.g. a dark MGHGrid card)\n // so the portaled popover matches the surface the field sits on.\n const [inheritedTheme, setInheritedTheme] = React.useState<'light' | 'dark' | undefined>(undefined);\n React.useEffect(() => {\n if (themeMode !== undefined) return;\n const attr = rootRef.current?.parentElement?.closest('[data-mgh-theme]')?.getAttribute('data-mgh-theme');\n setInheritedTheme(attr === 'dark' ? 'dark' : attr === 'light' ? 'light' : undefined);\n });\n const effectiveThemeMode = themeMode ?? inheritedTheme;\n\n // The popover anchor lives in state (not only in the ref) so a picker that mounts already open\n // is positioned under the field on its first commit instead of waiting for an unrelated re-render.\n const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null);\n const setRootRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n setAnchorEl(node);\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [ref]\n );\n\n const openPicker = React.useCallback(() => {\n if (disabled || readOnly || open) return;\n valueAtOpenRef.current = value;\n restoreFocusRef.current = (document.activeElement as HTMLElement | null) ?? null;\n if (!isOpenControlled) setInternalOpen(true);\n onOpen?.();\n }, [disabled, readOnly, open, value, isOpenControlled, onOpen]);\n\n const closePicker = React.useCallback(() => {\n if (!open) return;\n if (!isOpenControlled) setInternalOpen(false);\n onClose?.();\n const target = toggleRef.current ?? restoreFocusRef.current;\n window.setTimeout(() => target?.focus?.(), 0);\n }, [open, isOpenControlled, onClose]);\n\n const acceptAndClose = React.useCallback(\n (next: MGHDateValue) => {\n accept(next, true);\n closePicker();\n },\n [accept, closePicker]\n );\n\n const handleDismiss = React.useCallback(() => {\n // Clicking away / Escape keeps whatever was picked (MUI fires onAccept when the value changed).\n accept(value);\n closePicker();\n }, [value, accept, closePicker]);\n\n const handleCalendarChange = React.useCallback(\n (next: MGHDateValue, selectionState: MGHDateSelectionState) => {\n setValue(next);\n if (selectionState === 'finish' && resolvedCloseOnSelect) acceptAndClose(next);\n },\n [setValue, resolvedCloseOnSelect, acceptAndClose]\n );\n\n const handleShortcut = (shortcut: MGHDateShortcut) => {\n const next = normalizeDate(shortcut.getValue({ isValid }));\n setValue(next, shortcut);\n acceptAndClose(next);\n };\n\n const handleAction = (action: MGHDateAction) => {\n switch (action) {\n case 'clear': {\n setValue(null);\n acceptAndClose(null);\n break;\n }\n case 'today': {\n const next = dayjs().startOf('day');\n setValue(next);\n if (resolvedCloseOnSelect) acceptAndClose(next);\n break;\n }\n case 'cancel': {\n if (!isDateEqual(value, valueAtOpenRef.current)) setValue(valueAtOpenRef.current);\n closePicker();\n break;\n }\n case 'accept':\n default:\n acceptAndClose(value);\n }\n };\n\n /* ---- text field ---- */\n const [focused, setFocused] = React.useState(false);\n const [text, setText] = React.useState(() => formatDate(value, format));\n const [inputInvalid, setInputInvalid] = React.useState(false);\n\n // Keep the text in sync with the value unless the user is typing. Deliberately not re-run on\n // blur: `handleBlur` decides whether to re-format, so unparseable text stays visible with its error.\n const focusedRef = React.useRef(focused);\n focusedRef.current = focused;\n React.useEffect(() => {\n if (focusedRef.current) return;\n setText(formatDate(value, format));\n setInputInvalid(false);\n }, [value, format]);\n\n const handleTextChange = (nextText: string) => {\n setText(nextText);\n const trimmed = nextText.trim();\n if (!trimmed || trimmed.toUpperCase() === datePlaceholder.toUpperCase()) {\n setInputInvalid(false);\n if (value !== null) setValue(null);\n return;\n }\n const parsed = parseDateText(trimmed, format);\n setInputInvalid(parsed == null);\n if (parsed && !isDateEqual(parsed, value)) setValue(parsed);\n };\n\n const handleBlur = () => {\n setFocused(false);\n // Re-format on blur unless the text could not be parsed (keep it so the user sees the error).\n if (!inputInvalid) setText(formatDate(value, format));\n // Leaving the field commits a typed value (like pressing Enter).\n if (!open) accept(value);\n };\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n openPicker();\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (!open) accept(value);\n }\n };\n\n const clear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setValue(null);\n accept(null);\n };\n\n const hasValue = value != null;\n const showError = !!errorProp || validationError != null || inputInvalid;\n const formattedValue = hasValue ? formatDate(value, format) : null;\n\n const openButton = !disableOpenPicker && (\n <button\n ref={toggleRef}\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.openPicker(formattedValue)}\n title={localeText.openPicker(formattedValue)}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (open) handleDismiss();\n else openPicker();\n }}\n >\n <CalendarIcon size={size === 'small' ? 20 : 24} />\n </button>\n );\n\n const clearButton = clearable && hasValue && !disabled && !readOnly && (\n <button\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.clear}\n title={localeText.clear}\n onClick={clear}\n >\n <CloseIcon size={size === 'small' ? 18 : 20} />\n </button>\n );\n\n const themeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...style }),\n [themeVars, style]\n );\n const popoverThemeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...popoverStyle }),\n [themeVars, popoverStyle]\n );\n\n /* ---- shortcuts / actions / toolbar ---- */\n const shortcutItems = React.useMemo(\n () =>\n (shortcuts ?? []).map((shortcut, index) => {\n let shortcutValue: MGHDateValue = null;\n try {\n shortcutValue = normalizeDate(shortcut.getValue({ isValid }));\n } catch {\n /* ignore */\n }\n return { shortcut, key: shortcut.id ?? `${shortcut.label}-${index}`, value: shortcutValue };\n }),\n [shortcuts, isValid]\n );\n\n const renderToolbar = () => (\n <div className=\"mgh-drp-toolbar mgh-dp-toolbar\">\n <p className=\"mgh-drp-toolbar-title\" id={dialogTitleId}>\n {localeText.toolbarTitle}\n </p>\n <div className=\"mgh-dp-toolbar-date\" aria-live=\"polite\">\n {value ? value.format(toolbarFormat) : localeText.toolbarPlaceholder}\n </div>\n </div>\n );\n\n const renderActions = () =>\n actions.length > 0 && (\n <div className=\"mgh-drp-actions\">\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n className={cx('mgh-drp-btn', (action === 'accept' || action === 'today') && 'mgh-drp-btn--primary')}\n onClick={() => handleAction(action)}\n >\n {localeText[action]}\n </button>\n ))}\n </div>\n );\n\n return (\n <div\n ref={setRootRef}\n className={cx('mgh-drp mgh-dp', fullWidth && 'mgh-drp--full-width', className)}\n data-mgh-theme={effectiveThemeMode}\n style={themeStyle}\n >\n <TextField\n id={inputId}\n name={name}\n label={label}\n value={text}\n placeholder={placeholderProp ?? datePlaceholder}\n size={size}\n fullWidth={fullWidth}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n error={showError}\n focused={focused}\n clickable={openOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n ariaLabel={label == null ? localeText.toolbarTitle : undefined}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={handleTextChange}\n onFocus={() => setFocused(true)}\n onBlur={handleBlur}\n onClick={() => openOnClick && openPicker()}\n onKeyDown={handleInputKeyDown}\n />\n {helperText != null && helperText !== '' && (\n <div className={cx('mgh-drp-helper', showError && 'mgh-drp-helper--error')}>{helperText}</div>\n )}\n\n <Popover\n open={open}\n anchorEl={anchorEl}\n placement={placement}\n onDismiss={handleDismiss}\n themeMode={effectiveThemeMode}\n className={popoverClassName}\n style={popoverThemeStyle}\n labelledBy={showToolbar ? dialogTitleId : undefined}\n >\n <div className={cx('mgh-drp-layout', showToolbar && 'mgh-drp-layout--with-toolbar')}>\n {showToolbar && renderToolbar()}\n <div className=\"mgh-drp-layout-main\">\n {shortcutItems.length > 0 && (\n <ul className=\"mgh-drp-shortcuts\" aria-label=\"Shortcuts\">\n {shortcutItems.map(({ shortcut, key, value: shortcutValue }) => (\n <li key={key}>\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-shortcut',\n hasValue && isDateEqual(shortcutValue, value) && 'mgh-drp-shortcut--selected'\n )}\n disabled={disabled || readOnly}\n onClick={() => handleShortcut(shortcut)}\n >\n {shortcut.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n <MGHDateCalendar\n value={value}\n onChange={handleCalendarChange}\n referenceDate={referenceDate}\n views={views}\n openTo={openTo}\n view={view}\n onViewChange={onViewChange}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n shouldDisableMonth={shouldDisableMonth}\n shouldDisableYear={shouldDisableYear}\n showDaysOutsideCurrentMonth={showDaysOutsideCurrentMonth}\n fixedWeekNumber={fixedWeekNumber}\n dayOfWeekFormatter={dayOfWeekFormatter}\n disableHighlightToday={disableHighlightToday}\n yearsPerRow={yearsPerRow}\n monthsPerRow={monthsPerRow}\n onMonthChange={onMonthChange}\n onYearChange={onYearChange}\n localeText={localeText}\n themeMode={effectiveThemeMode}\n autoFocus\n />\n </div>\n {renderActions()}\n </div>\n </Popover>\n </div>\n );\n});\n\nMGHDatePicker.displayName = 'MGHDatePicker';\n\nexport default MGHDatePicker;\n","import Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\n\nimport { ConfirmDialogProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nexport default function ConfirmDialog({ title, content, action, open, onClose, ...other }: ConfirmDialogProps) {\n return (\n <Dialog fullWidth maxWidth=\"xs\" open={open} onClose={onClose} {...other}>\n <DialogTitle sx={{ pb: 2 }}>{title}</DialogTitle>\n\n {content && <DialogContent sx={{ typography: 'body2' }}> {content} </DialogContent>}\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n {action}\n </DialogActions>\n </Dialog>\n );\n}\n","import {\n GridToolbarExportContainer,\n GridCsvExportMenuItem,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n} from '@mui/x-data-grid-premium';\nimport React from 'react';\nimport { ExportContainerProps } from './CustomGridToolbarExport.types';\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomGridToolbarExport({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n // color,\n customMenuItem,\n ...other\n}: ExportContainerProps) {\n return (\n <GridToolbarExportContainer\n {...other}\n // color={color}\n >\n {customMenuItem}\n <GridCsvExportMenuItem options={csvOptions} />\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n );\n}\n","import { JSX } from 'react';\n\nimport { Dialog, Typography, DialogContent, CircularProgress } from '@mui/material';\nimport React from 'react';\n\n/// ---------------------------------------------------------------------------------------\n\ninterface ExportingProps {\n open: boolean;\n text?: JSX.Element | string;\n}\nexport default function ExportingDialog({\n open,\n text = (\n <>\n Your export is currently being built. Some larger exports can take a couple of minutes to complete. <br />\n <br />\n Please do not close your browser or refresh the page.\n </>\n ),\n}: ExportingProps) {\n return (\n <Dialog open={open} fullWidth sx={{ p: 4 }}>\n <DialogContent sx={{ p: 4, textAlign: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ mb: 3 }}>\n {text}\n </Typography>\n <CircularProgress />\n </DialogContent>\n </Dialog>\n );\n}\n"],"names":["useResponsive","query","start","end","theme","useTheme","mediaUp","useMediaQuery","breakpoints","up","mediaDown","down","mediaBetween","between","mediaOnly","only","CustomNoRowsOverlay","text","useSettingsContext","themeMode","palette","mode","StyledGridOverlay","styled","display","alignItems","justifyContent","height","fill","fillOpacity","React","createElement","Box","component","alt","src","sx","width","maxWidth","mb","canUseLocalStorage","window","localStorage","readLocalStorage","key","value","getItem","JSON","parse","writeLocalStorage","setItem","stringify","MGHGridToolbar","showColumnsButton","showFilterButton","showExportButton","showQuickFilter","renderOtherButtons","renderDateRange","customMenuItem","showCsvOption","Toolbar","style","Tooltip","title","ColumnsPanelTrigger","render","ToolbarButton","GridViewColumnIcon","fontSize","FilterPanelTrigger","props","state","color","Badge","badgeContent","filterCount","variant","GridFilterListIcon","CustomGridToolbarExport","DataGridQuickFilter","csvOptions","allColumns","excelOptions","printOptions","other","GridToolbarExportContainer","map","el","GridCsvExportMenuItem","options","GridExcelExportMenuItem","GridPrintExportMenuItem","StyledQuickFilter","QuickFilter","StyledToolbarButton","ownerState","gridArea","zIndex","opacity","expanded","pointerEvents","transition","transitions","create","StyledTextField","TextField","overflowX","QuickFilterTrigger","triggerProps","enterDelay","GridSearchIcon","QuickFilterControl","ref","controlProps","inputRef","placeholder","size","slotProps","input","startAdornment","InputAdornment","position","endAdornment","QuickFilterClear","edge","material","marginRight","GridCloseIcon","Iconify","forwardRef","icon","Icon","StyledLabel","lightMode","filledVariant","outlinedVariant","softVariant","defaultStyle","common","white","grey","backgroundColor","primary","border","secondary","alpha","colorStyle","contrastText","main","minWidth","lineHeight","borderRadius","cursor","whiteSpace","textTransform","padding","spacing","typography","pxToRem","fontWeight","fontWeightBold","duration","shorter","Label","children","startIcon","endIcon","iconStyles","objectFit","pl","pr","mr","ml","GROUPING_COLUMN_FIELD","CHECKBOX_FIELD","DETAIL_PANEL_TOGGLE_FIELD","AGGREGATION_FOOTER_ID","INTERNAL_FIELDS","Set","DENSITY_FACTORS","compact","standard","comfortable","DEFAULT_ROW_HEIGHT","DEFAULT_HEADER_HEIGHT","DEFAULT_COLUMN_MIN_WIDTH","isInternalField","field","has","isNil","isEmptyValue","Array","isArray","length","clamp","min","max","Math","cx","classNames","filter","Boolean","join","uniqueId","counter","prefix","getRowIdFromRow","row","getRowId","id","normalizeSelectionModel","allIds","type","ids","forEach","add","toDate","Date","Number","isNaN","getTime","dayjs","isDayjs","isValid","d","parsed","formatDate","withTime","date","format","startOfUnit","startOf","valueOf","isValueOptionObject","option","getOptionValue","col","getOptionLabel","label","String","resolveValueOptions","valueOptions","getCellValue","api","raw","undefined","valueGetter","defaultFormatValue","match","find","isFinite","getFormattedValue","valueFormatter","formattedValueToString","formatted","collator","Intl","Collator","numeric","sensitivity","nilFirst","v1","v2","n1","n2","numberComparator","nil","stringComparator","s1","s2","compare","stringOrNumberComparator","p1","p2","dateComparator","d1","d2","booleanComparator","getDefaultComparator","lower","toLowerCase","hasValue","item","stringFilterOperators","inputType","getApplyFilterFn","needle","indexOf","s","lastIndexOf","requiresFilterValue","set","numberOperator","filterValue","cell","n","numberFilterOperators","a","b","v","dateOperator","filterDate","filterTime","cellDate","getDateFilterOperators","booleanFilterOperators","expected","singleSelectFilterOperators","getColumnFilterOperators","filterOperators","getDefaultFilterOperators","normalizeColumn","isNumber","isBoolean","isActions","headerName","align","headerAlign","sortable","filterable","hideable","resizable","pinnable","groupable","aggregable","editable","disableColumnMenu","disableExport","internalColumn","disableReorder","CHECKBOX_COLUMN_DEF","DETAIL_PANEL_TOGGLE_COLUMN_DEF","UNITLESS_PROPERTIES","isSelectorKey","test","serializeDeclarations","block","Object","keys","property","kebab","replace","m","toKebabCase","formatCssValue","buildScopedCss","scope","out","charAt","inner","declarations","push","selector","scopeSelector","split","part","trim","numericValues","values","BUILT_IN_AGGREGATION_FUNCTIONS","sum","columnTypes","apply","nums","reduce","acc","avg","defined","every","dates","slice","sort","sorted","DEFAULT_LOCALE_TEXT","noRowsLabel","loadingLabel","toolbarColumns","toolbarFilters","toolbarExport","toolbarDensity","toolbarQuickFilterPlaceholder","toolbarQuickFilterLabel","toolbarExportCSV","toolbarExportExcel","toolbarExportPrint","densityCompact","densityStandard","densityComfortable","columnsPanelSearchPlaceholder","columnsPanelShowAll","columnsPanelHideAll","columnsPanelReset","filterPanelAddFilter","filterPanelRemoveAll","filterPanelDeleteIcon","filterPanelColumns","filterPanelOperator","filterPanelValue","filterPanelInputPlaceholder","filterPanelLogicOperator","filterPanelOperatorAnd","filterPanelOperatorOr","columnMenuSortAsc","columnMenuSortDesc","columnMenuUnsort","columnMenuFilter","columnMenuHideColumn","columnMenuManageColumns","columnMenuPinLeft","columnMenuPinRight","columnMenuUnpin","columnMenuGroup","name","columnMenuUngroup","columnMenuAggregation","aggregationMenuItemHeader","aggregationFunctionLabelNone","aggregationFunctionLabelSum","aggregationFunctionLabelAvg","aggregationFunctionLabelMin","aggregationFunctionLabelMax","aggregationFunctionLabelSize","footerRowSelected","count","toLocaleString","footerTotalRows","footerPaginationRowsPerPage","footerPaginationDisplayedRows","from","to","footerPaginationFirstPage","footerPaginationPreviousPage","footerPaginationNextPage","footerPaginationLastPage","checkboxSelectionHeaderName","checkboxSelectionSelectAllRows","checkboxSelectionUnselectAllRows","checkboxSelectionSelectRow","checkboxSelectionUnselectRow","booleanCellTrueLabel","booleanCellFalseLabel","detailPanelToggle","expandDetailPanel","collapseDetailPanel","groupingColumnHeaderName","groupColumn","unGroupColumn","actionsCellMore","columnHeaderSortIconLabel","columnMenuLabel","clearSearch","measureContext","measureText","font","document","canvas","getContext","downloadBlob","blob","fileName","url","URL","createObjectURL","anchor","href","download","body","appendChild","click","setTimeout","removeChild","revokeObjectURL","MGH_GRID_STYLE_ID","MGH_GRID_CSS","injected","useInsertion","useInsertionEffect","useLayoutEffect","useEffect","useMGHGridStyles","injectStyles","getElementById","setAttribute","textContent","head","MGHGridContext","createContext","displayName","useMGHGridContext","ctx","useContext","Error","useLatestRef","useRef","current","useControlledState","controlled","defaultValue","onChange","isControlled","internal","setInternal","useState","valueRef","controlledRef","onChangeRef","useCallback","next","resolved","is","idCounter","buildExportTable","columns","resolveExportColumns","all","getAllColumns","fields","byField","Map","c","f","get","getVisibleColumns","getRowsToExport","getSortedRowIds","rows","getRow","headers","sanitizeFileName","fallback","extension","base","endsWith","defaultFileBase","escapeCsvCell","delimiter","getDataAsCsv","includeHeaders","table","lines","h","cells","useRawValues","UTF8_BOM","fromCharCode","CRC_TABLE","Uint32Array","k","textEncoder","TextEncoder","encodeUtf8","encode","utf8","unescape","encodeURIComponent","Uint8Array","i","charCodeAt","concatBytes","chunks","total","offset","zipStore","entries","localChunks","centralChunks","entry","nameBytes","crc","bytes","crc32","data","local","lv","DataView","buffer","setUint32","setUint16","central","cv","centralDirectory","eocd","ev","concat","INVALID_XML_CHARS","RegExp","escapeXml","stripInvalidXml","columnLetter","index","letters","rem","floor","XML_HEADER","buildSheetXml","columnWidths","rowsXml","rowIndex","inlineString","xmlCells","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","lastCol","lastRow","cols","w","STYLES_XML","CONTENT_TYPES_XML","ROOT_RELS_XML","WORKBOOK_RELS_XML","buildWorkbookXml","sheetName","buildCoreXml","now","toISOString","APP_XML","buildXlsx","widths","explicit","columnsStyles","r","len","cleaned","sanitizeSheetName","escapeHtml","printGridElement","params","done","onDone","printGridElementUnsafe","error","console","cardElement","hideToolbar","hideFooter","copyStyles","clone","cloneNode","syncFormState","source","target","sourceInputs","querySelectorAll","targetInputs","t","tagName","dst","checked","indeterminate","sourceCanvases","targetCanvases","img","ownerDocument","toDataURL","cssText","replaceWith","remove","classList","removeAttribute","flexGrow","styles","links","doc","styleSheets","sheet","rules","cssRules","rule","collectStyles","iframe","finished","finish","parentNode","win","contentWindow","contentDocument","open","write","close","css","printStyle","pageStyle","h1","className","adoptNode","async","waitForImages","timeoutMs","Promise","resolve","images","complete","remaining","timer","onSettled","clearTimeout","addEventListener","once","onBeforePrint","onafterprint","focus","print","run","keyToString","buildGroupTree","groupingFields","columnsByField","emptyLabel","build","items","depth","parentId","path","buckets","getGroupingValue","groupingValueGetter","keyStr","node","parent","groupingField","groupingKey","groupingLabel","childGroups","leaves","descendants","nodes","collectTreeLeaves","roots","root","aggregateRows","aggregationModel","functions","result","fnName","fn","createIcon","rest","viewBox","focusable","ViewColumnIcon","FilterListIcon","SearchIcon","CloseIcon","DownloadIcon","ArrowUpwardIcon","ArrowDownwardIcon","MoreVertIcon","CheckIcon","ExpandMoreIcon","ChevronRightIcon","ChevronLeftIcon","FirstPageIcon","LastPageIcon","PushPinIcon","DeleteIcon","AddIcon","DensitySmallIcon","DensityMediumIcon","DensityLargeIcon","DragIndicatorIcon","PrintIcon","TableChartIcon","DescriptionIcon","VisibilityOffIcon","FunctionsIcon","WorkspacesIcon","EmptyBoxIcon","Fragment","Button","active","IconButton","TextInput","Select","Field","htmlFor","Checkbox","forwardedRef","innerRef","setRef","Spinner","role","Popover","anchorEl","onClose","placement","autoFocus","ignoreOutsideClickOn","setPosition","top","left","ready","update","vw","innerWidth","vh","innerHeight","offsetWidth","offsetHeight","isConnected","getBoundingClientRect","right","bottom","prev","observer","ResizeObserver","observe","removeEventListener","disconnect","handlePointerDown","event","contains","some","closest","handleKeyDown","querySelector","stop","stopPropagation","createPortal","tabIndex","visibility","onClick","onDoubleClick","onMouseDown","onKeyDown","Menu","first","preventDefault","currentIndex","activeElement","MenuItem","selected","disabled","hideMenu","MenuDivider","MenuSection","MGHGridColumnsButton","localeText","isOpen","preferencePanel","openedPanelValue","hidePreferences","showPreferences","currentTarget","MGHGridFiltersButton","MGHGridDensitySelector","setAnchor","o","density","setDensity","MGHGridExportMenuItem","MGHGridExportMenu","showExcelOption","showPrintOption","rootProps","customItems","Children","child","isValidElement","cloneElement","resolvedPrintOptions","header","exportDataAsCsv","exportDataAsExcel","exportDataAsPrint","MGHGridQuickFilter","debounceMs","alwaysExpanded","externalValue","quickFilterValues","setText","setExpanded","delay","quickFilterDebounceMs","lastExternal","commit","setQuickFilterValues","clear","isExpanded","expand","handleChange","onBlur","blur","showDensitySelector","quickFilterPlaceholder","showColumns","disableColumnSelector","showFilters","disableColumnFilter","showDensity","disableDensitySelector","MGHGridPagination","page","pageSize","paginationModel","rowCount","pageCount","pageSizeOptions","setPageSize","setPage","MGHGridFooter","selectedCount","rowSelectionModel","showSelected","hideFooterSelectedRowCount","showPagination","pagination","hideFooterPagination","showRowCount","hideFooterRowCount","MGHGridColumnsPanel","visibleColumns","visibleFields","useMemo","search","setSearch","model","columnVisibilityModel","filtered","setAll","visible","setColumnVisibilityModel","setColumnVisibility","useDebouncedValue","onCommit","setLocal","TextValueInput","MultiValueInput","column","joined","multiple","selectedOptions","FilterValueInput","operator","InputComponent","Component","applyValue","createFilterItem","MGHGridFilterPanel","filterableColumns","filterModel","logicOperator","targetField","seeded","upsertFilterItem","updateItem","patch","canAddMore","disableMultipleColumnsFiltering","paddingTop","operators","op","showLogic","deleteFilterItem","setFilterLogicOperator","nextColumn","nextOperators","keepOperator","nextOperator","nextIsMulti","currentIsMulti","addItem","setFilterModel","MGHGridColumnMenu","panelAnchorEl","isGroupingColumn","sortItem","sortModel","pinned","isColumnPinned","isGrouped","rowGroupingModel","aggregation","canSort","disableColumnSorting","canFilter","canHide","canPin","disableColumnPinning","canGroup","disableRowGrouping","aggregationFunctions","availableAggregationFunctions","canAggregate","disableAggregation","anchorForPanel","sortColumn","showFilterPanel","transform","pinColumn","unpinColumn","removeRowGroupingCriteria","addRowGroupingCriteria","gap","setAggregationModel","MGHGridNoRowsOverlay","imageSrc","MGHGridLoadingOverlay","MGHGridActionsCellItem","showInMenu","ActionsCell","actions","moreLabel","inline","inMenu","action","EMPTY_ARRAY","EMPTY_OBJECT","EMPTY_MAP","DEFAULT_SORTING_ORDER","DEFAULT_PAGE_SIZE_OPTIONS","DEFAULT_FILTER_MODEL","quickFilterExcludeHiddenColumns","sanitizeStyle","toDateInputValue","pad","padStart","MGHGrid","columnsProp","loading","renderHeaderEndContent","renderHeaderCenterContent","disableCard","cardClassName","boxClassName","cardStyle","cardSx","boxStyle","boxSx","themeVars","showToolbar","toolbarProps","slots","noRowsText","localeTextProp","rowHeight","rowHeightProp","columnHeaderHeight","getRowHeight","autoHeight","disableVirtualization","densityProp","onDensityChange","paginationModelProp","onPaginationModelChange","sortModelProp","onSortModelChange","sortingOrder","disableMultipleColumnsSorting","filterModelProp","onFilterModelChange","columnVisibilityModelProp","onColumnVisibilityModelChange","columnVisibilityStorageKey","columnOrderStorageKey","columnWidthStorageKey","pinnedColumnsStorageKey","onColumnOrderChange","onColumnWidthChange","disableColumnResize","disableColumnReorder","pinnedColumns","pinnedColumnsProp","onPinnedColumnsChange","checkboxSelection","checkboxSelectionVisibleOnly","disableRowSelectionOnClick","disableMultipleRowSelection","rowSelectionModelProp","onRowSelectionModelChange","isRowSelectable","keepNonExistentRowsSelected","getRowClassName","onRowClick","onRowDoubleClick","onCellClick","onCellDoubleClick","pinnedRows","getDetailPanelContent","getDetailPanelHeight","detailPanelExpandedRowIds","detailPanelExpandedRowIdsProp","onDetailPanelExpandedRowIdsChange","rowGroupingModelProp","onRowGroupingModelChange","defaultGroupingExpansionDepth","groupingColDef","isGroupExpandedByDefault","aggregationModelProp","onAggregationModelChange","aggregationFunctionsProp","aggregationPosition","processRowUpdate","onProcessRowUpdateError","onCellEditStop","isCellEditable","initialState","apiRef","onStateChange","gridId","reactUseId","useId","useStableId","rootRef","cardRef","scrollerRef","toolbarRef","forceUpdate","setTick","useForceUpdate","latest","getDetails","apiObject","L","apiImpl","rowsById","getRowModels","getAllRowIds","rowEntries","e","getRowNode","nodesById","getSortedRows","sortedLeaves","getVisibleRows","pagedRows","dr","getRowIndexRelativeToVisibleRows","findIndex","updateRows","updates","existing","setRowOverride","orderedUserColumns","visibleUserColumns","getColumn","getColumnIndex","useVisibleColumns","getColumnVisibilityModel","isVisible","setColumnWidth","setColumnIndex","targetIndex","autosizeColumns","side","getPinnedColumns","setPinnedColumns","getSortModel","setSortModel","direction","allowMultipleSorting","getFilterModel","upsertFilterItems","targetColumnField","hideFilterPanel","panel","getSelectedRows","selectedIds","getRowSelectionModel","setRowSelectionModel","normalized","setSelectedIds","selectRow","isSelected","resetSelection","selectRows","isRowSelected","isRowSelectableFn","nextPage","setPaginationModel","nextPageSize","csv","bom","utf8WithBom","Blob","startPrint","toggleDetailPanel","setExpandedDetailPanels","getExpandedDetailPanels","expandedDetailPanels","getRowGroupingModel","setRowGroupingModel","groupingIndex","splice","setRowChildrenExpansion","getRowGroupChildren","groupId","group","groupsById","getAggregationModel","startCellEditMode","stopCellEditMode","ignoreModifications","getCellMode","editing","editingCell","setEditCellValue","setEditValue","getCellParams","buildCellParams","setCellFocus","pendingFocusRef","setFocusedCell","scrollToIndexes","scroll","scroller","scrollLeft","scrollTop","getScrollPosition","rootElementRef","persisted","order","sorting","rowGrouping","controlledExpandedDetail","detailPanel","expandedRowIds","controlledSelection","orderedFields","setOrderedFields","setColumnWidths","dims","dimensions","groupExpansion","setGroupExpansion","setEditingCell","editValue","focusedCell","setPreferencePanel","columnMenu","setColumnMenu","resizingField","setResizingField","printState","setPrintState","printing","drag","setDrag","setScrollTop","scrollRaf","lastClickedIdRef","overrideState","setOverrideState","rowOverrides","viewportWidth","viewportHeight","enabled","setSize","clientWidth","clientHeight","useElementSize","densityFactor","round","headerHeight","userColumns","groupingActive","groupingColumn","single","seen","isColumnVisible","wanted","layout","leftFields","rightFields","visibleByField","center","ordered","computeWidths","available","overrides","Infinity","override","flex","pool","fixedTotal","remainingSpace","remainingFlex","changed","share","fixed","idx","hasPinning","x","leftOffset","isLeft","isRight","isLastLeft","isFirstRight","rightOffset","totalWidth","leftCount","rightCount","allDisplayColumnsByField","activeFilters","quickFilterColumns","filteredEntries","logicAnd","quickAnd","quickFilterLogicOperator","apiRefLocal","quickFns","lowered","getApplyQuickFilterFn","custom","results","compareEntries","sorters","dir","comparator","sortComparator","sortEntries","aggregationActive","isGroupExpanded","leafIds","processed","displayRows","tree","groupingSort","sortGroupTree","compareGroups","sortLeaves","sortLevel","flattenGroupTree","visit","groupNode","toGroupNode","l","childVisible","leaf","leafNode","totalDisplayRows","paginate","ceil","footerAggregates","rowsForFooter","groupAggregatesCache","getGroupAggregates","cached","heights","rowHeights","detailHeights","offsets","hasAuto","dh","virtual","virtualRange","overscan","viewTop","viewBottom","lo","hi","mid","handleScroll","requestAnimationFrame","cancelAnimationFrame","selectionCandidates","selectedCandidateCount","allCandidatesSelected","someCandidatesSelected","updateSelection","updater","selectionModelsEqual","equal","delete","lastId","toggleAllCandidates","allowMultiple","persistOrder","persistWidths","targets","lc","computed","getComputedStyle","fontFamily","cellFont","headerFont","sample","isCellEditableFn","colDef","rowNode","reason","valueParser","parseEditValue","currentValue","applyRowUpdate","newRow","oldRow","then","rowId","catch","valueSetter","previousGroupingKey","formattedValue","hasFocus","cellMode","isEditable","buildRowParams","preventScroll","visibleTop","visibleBottom","scrollIntoView","colIndex","leftPinnedWidth","rightPinnedWidth","visibleLeft","visibleRight","moveFocus","rowDelta","colDelta","absolute","canReorder","resizeRef","totalRowCount","clamped","oldIndex","moveItem","list","unshift","nextItems","withId","random","toString","contextValue","renderCellContent","renderRow","kind","selectable","content","hideCount","hideDescendantCount","paddingLeft","agg","aggregates","sampleRow","cancel","renderEditCell","onValueChange","renderEditor","renderCell","getActions","cellStyle","pinnedClasses","rowIsClickable","renderRowElement","customClass","indexRelativeToCurrentPage","isFirstVisible","isFirst","isLastVisible","isLast","isAuto","minHeight","handleRowSelectionClick","allSelected","shiftKey","ctrlKey","metaKey","isFocused","isEditing","isAggregation","cellClassName","isCheckbox","isDetailToggle","toRenderRow","renderPinnedRows","renderHeaderCell","sortIndex","showMenu","draggable","isDragging","isDropTarget","overField","menuOpen","headerParams","headerClassName","renderHeader","description","onDragStart","dataTransfer","effectAllowed","setData","onDragOver","sourceLc","dropEffect","rect","clientX","onDragLeave","onDrop","handleDrop","targetLc","without","onDragEnd","onPointerDown","handleResizeStart","startX","startWidth","lastWidth","onMove","onUp","ToolbarSlot","toolbar","FooterSlot","footer","NoRowsOverlaySlot","noRowsOverlay","LoadingOverlaySlot","loadingOverlay","mergedToolbarProps","noRowsProps","loadingProps","showNoRows","menuColumn","cardStyles","boxStyles","rootStyles","scopedCss","smDown","grid","pageRows","onScroll","renderBodyRows","detailHeight","detailContent","detailAuto","rowAuto","Provider","MGH_DATE_RANGE_PICKER_STYLE_ID","MGH_DATE_RANGE_PICKER_CSS","useMGHDateRangePickerStyles","DateRangeIcon","CalendarIcon","ArrowDropDownIcon","extend","customParseFormat","EMPTY_RANGE","toDayjs","isSameDay","isSame","isBeforeDay","isBefore","isAfterDay","isAfter","isWithinRange","day","isRangeEqual","same","y","normalizeRange","parseDateText","trimmed","strict","fallbacks","validateDay","disablePast","disableFuture","minDate","maxDate","shouldDisableDate","validateRange","startError","endError","isDayDisabled","getMonthWeeks","month","fixedWeekNumber","firstOfMonth","weeksInMonth","endOf","diff","weekCount","weeks","weekStart","days","_","outsideMonth","getWeekDayLabels","formatter","full","MGH_DATE_RANGE_DEFAULT_SHORTCUTS","getValue","today","subtract","defaultDayOfWeekFormatter","toUpperCase","MGHDateRangeCalendar","valueProp","rangePosition","rangePositionProp","onRangePositionChange","calendars","referenceDate","readOnly","showDaysOutsideCurrentMonth","dayOfWeekFormatter","disableHighlightToday","showRangePreview","onMonthChange","internalValue","setInternalValue","internalPosition","setInternalPosition","setRangePosition","validation","currentMonth","setCurrentMonth","visibleMonths","lastVisibleMonth","changeMonth","ensureVisible","lastSeenRef","canGoPrev","canGoNext","hoveredDay","setHoveredDay","preview","selectDay","nextPosition","focusedDay","setFocusedDay","focusDay","weekDays","previewStart","previewEnd","isRangeComplete","onMouseLeave","renderMonth","tabbableDay","previousMonth","nextMonth","wd","week","dayIndex","hidden","isStart","isEnd","inRange","inPreview","dayDisabled","isTabbable","firstVisible","lastVisible","daysInMonth","onMouseEnter","onFocus","onDismiss","labelledBy","fullWidth","multi","required","focused","clickable","adornment","ariaLabel","hasLabel","shrink","inputMode","autoComplete","spellCheck","MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT","fieldSeparator","openPicker","accept","toolbarTitle","MGHDateRangePicker","onAccept","onError","openProp","onOpen","fieldVariant","clearable","openOnClick","disableOpenPicker","closeOnSelect","shortcuts","idProp","placeholderProp","errorProp","helperText","popoverClassName","popoverStyle","datePlaceholder","isMulti","resolvedOpenOnClick","resolvedCloseOnSelect","includes","reactId","baseId","startId","endId","dialogTitleId","validationError","range","lastErrorRef","setValue","shortcut","context","isOpenControlled","internalOpen","setInternalOpen","valueAtOpenRef","lastAcceptedRef","force","toggleRef","restoreFocusRef","inheritedTheme","setInheritedTheme","attr","parentElement","getAttribute","effectiveThemeMode","setAnchorEl","setRootRef","closePicker","acceptAndClose","handleDismiss","handleCalendarChange","_day","focusedInput","setFocusedInput","formatSingle","singleText","setSingleText","startText","setStartText","endText","setEndText","inputInvalid","setInputInvalid","parseSegment","invalid","handleSideChange","handleBlur","handleInputKeyDown","altKey","hasValidationError","showError","openButton","clearButton","themeStyle","popoverThemeStyle","shortcutItems","shortcutValue","calendar","commonFieldProps","parts","splitRangeText","ps","pe","handleShortcut","handleAction","MGH_DATE_PICKER_STYLE_ID","MGH_DATE_PICKER_CSS","useMGHDatePickerStyles","MGH_DATE_PICKER_DEFAULT_MIN_DATE","MGH_DATE_PICKER_DEFAULT_MAX_DATE","normalizeDate","isDateEqual","mergeDateAndTime","time","hour","minute","second","millisecond","validateDate","shouldDisableMonth","shouldDisableYear","isDateDisabled","isMonthDisabled","isYearDisabled","year","findClosestEnabledDate","forward","backward","guard","MGH_DATE_PICKER_DEFAULT_SHORTCUTS","DEFAULT_VIEWS","defaultSwitchViewLabel","view","MGHDateCalendar","views","viewsProp","openTo","viewProp","onViewChange","yearsPerRow","monthsPerRow","onYearChange","internalView","setInternalView","setView","firstEnabledMonth","lastEnabledMonth","yearsRef","container","offsetTop","fromView","nextView","selectionState","goToNextView","selectPeriod","candidate","unit","periodStart","periodEnd","baseDate","selectYear","setYear","selectMonth","setMonth","toggleView","moveDayFocus","handleGridKeyDown","perRow","select","nextIndex","switchLabel","calendarViewSwitchingButtonAriaLabel","renderDayView","isToday","handleDayKeyDown","renderMonthView","months","selectedMonth","currentMonthIndex","tabbable","monthDate","monthDisabled","renderYearView","years","getYearRange","selectedYear","yearDate","yearDisabled","isCurrent","MGH_DATE_PICKER_DEFAULT_LOCALE_TEXT","formattedDate","toolbarPlaceholder","MGHDatePicker","toolbarFormat","inputId","setFocused","focusedRef","nextText","Dialog","DialogTitle","pb","DialogContent","DialogActions","p","textAlign","Typography","CircularProgress","persistedColumnVisibilityModel","persistedOrderedFields","normalizeOrderedFields","columnFields","resolvedColumnVisibilityModel","handleColumnVisibilityModelChange","details","handleColumnOrderChange","mergedInitialState","Card","CardHeader","flexWrap","flexDirection","DataGridPremium","disableRowSelectionExcludeModel","exportDataAsPrintTable","headerHtml","bodyHtml","html","cleanup","onload","srcdoc","useMGHGridApiContext","useMGHGridApiRef","useMGHGridLocaleText"],"mappings":"oiBAWgBA,EAAcC,EAAcC,EAAeC,GACvD,MAAMC,EAAQC,EAAAA,WAERC,EAAUC,EAAcH,EAAMI,YAAYC,GAAGP,IAE7CQ,EAAYH,EAAcH,EAAMI,YAAYG,KAAKT,IAEjDU,EAAeL,EAAcH,EAAMI,YAAYK,QAAQX,EAAgBC,IAEvEW,EAAYP,EAAcH,EAAMI,YAAYO,KAAKb,IAEvD,MAAc,OAAVD,EACOK,EAGG,SAAVL,EACOS,EAGG,YAAVT,EACOW,EAGJE,CACX,CCdc,SAAUE,GAAoBC,KAAEA,EAAIC,mBAAEA,IAChD,MAAMd,EAAQC,EAAAA,WACRc,EAAYD,OAAwBC,WAAaf,EAAMgB,QAAQC,MAAQ,QAEvEC,EAAoBC,EAAO,MAAPA,CAAc,KAAA,CACpCC,QAAS,OACTC,WAAY,SACZC,eAAgB,SAChBC,OAAQ,OACR,qBAAsB,CAClBC,KAAoB,UAAdT,EAAwB,UAAY,WAE9C,qBAAsB,CAClBS,KAAoB,UAAdT,EAAwB,UAAY,WAE9C,qBAAsB,CAClBS,KAAoB,UAAdT,EAAwB,UAAY,WAE9C,qBAAsB,CAClBS,KAAoB,UAAdT,EAAwB,OAAS,WAE3C,qBAAsB,CAClBU,YAA2B,UAAdV,EAAwB,MAAQ,OAC7CS,KAAoB,UAAdT,EAAwB,UAAY,WAGlD,OACIW,gBAACR,EAAiB,KACdQ,EAAAC,cAACC,MAAG,CACAC,UAAU,MACVC,IAAI,gBACJC,IAAI,qCACJC,GAAI,CAAEC,MAAO,GAAIC,SAAU,OAE/BR,EAAAC,cAACC,MAAG,CAACI,GAAI,CAAEG,GAAI,IAAMtB,GAGjC,CCsDA,MAAMuB,EAAqBA,IAAwB,oBAAXC,aAAyD,IAAxBA,OAAOC,aAE1EC,EAAwBC,IAC1B,IAAKJ,IACD,OAAO,KAEX,IACI,MAAMK,EAAQJ,OAAOC,aAAaI,QAAQF,GAC1C,OAAOC,EAASE,KAAKC,MAAMH,GAAe,IAC9C,CAAE,MACE,OAAO,IACX,GAGEI,EAAoBA,CAACL,EAAaC,KACpC,GAAKL,IAGL,IACIC,OAAOC,aAAaQ,QAAQN,EAAKG,KAAKI,UAAUN,GACpD,CAAE,MACE,MACJ,GA2LE,SAAUO,GAAeC,kBAC3BA,GAAoB,EAAIC,iBACxBA,GAAmB,EAAIC,iBACvBA,GAAmB,EAAIC,gBACvBA,GAAkB,EAAIC,mBACtBA,EAAkBC,gBAClBA,EAAeC,eACfA,EAAcC,cACdA,GAAgB,IAEhB,OACI9B,EAAAC,cAAC8B,UAAO,CAACC,MAAO,CAAEtC,QAAS,OAAQE,eAAgB,kBAC/CI,EAAAC,cAAA,MAAA,KACKsB,GACGvB,EAAAC,cAACgC,UAAO,CAACC,MAAM,WACXlC,EAAAC,cAACkC,sBAAmB,CAACC,OAAQpC,EAAAC,cAACoC,EAAAA,cAAa,OACvCrC,EAAAC,cAACqC,sBAAmBC,SAAS,YAIxCf,GACGxB,EAAAC,cAACgC,EAAAA,QAAO,CAACC,MAAM,WACXlC,EAAAC,cAACuC,qBAAkB,CACfJ,OAAQA,CAACK,EAAOC,IACZ1C,gBAACqC,EAAAA,cAAa,IAAKI,EAAOE,MAAM,WAC5B3C,EAAAC,cAAC2C,QAAK,CAACC,aAAcH,EAAMI,YAAaH,MAAM,UAAUI,QAAQ,OAC5D/C,EAAAC,cAAC+C,qBAAkB,CAACT,SAAS,eAOpDd,GACGzB,EAAAC,cAACgD,GAAwBpB,eAAgBA,EAAgBC,cAAeA,KAI/EF,EAED5B,EAAAC,cAAA,MAAA,KACK0B,EACAD,GAAmB1B,EAAAC,cAACiD,SAIrC,CASO,MAAMD,EAA0BA,EACnCE,aAAa,CAAEC,YAAY,GAC3BC,eAAe,CAAED,YAAY,GAC7BE,eACAzB,iBACAC,iBAAgB,KACbyB,KAEHvD,EAAAC,cAACuD,iCAA+BD,GAC3B1B,GAAgB4B,IAAKC,GAAOA,GAC5B5B,GAAiB9B,EAAAC,cAAC0D,yBAAsBC,QAAST,IAClDnD,EAAAC,cAAC4D,0BAAuB,CAACD,QAASP,IAClCrD,EAAAC,cAAC6D,2BAAwBF,QAASN,cAI1BJ,IAKZ,MAAMa,EAAoBtE,SAAOuE,EAAAA,YAAPvE,CAAoB,CAC1CC,QAAS,OACTC,WAAY,WAGVsE,EAAsBxE,EAAAA,OAAO4C,EAAAA,cAAP5C,CAAkD,EAAGnB,QAAO4F,iBAAY,CAChGC,SAAU,QACV5D,MAAO,cACPV,OAAQ,cACRuE,OAAQ,EACRC,QAASH,EAAWI,SAAW,EAAI,EACnCC,cAAeL,EAAWI,SAAW,OAAS,OAC9CE,WAAYlG,EAAMmG,YAAYC,OAAO,CAAC,eAGpCC,EAAkBlF,EAAAA,OAAOmF,EAAAA,UAAPnF,CAErB,EAAGnB,QAAO4F,iBAAY,CACrBC,SAAU,QACVU,UAAW,OACXtE,MAAO2D,EAAWI,SAAW,IAAM,uBACnCD,QAASH,EAAWI,SAAW,EAAI,EACnCE,WAAYlG,EAAMmG,YAAYC,OAAO,CAAC,QAAS,eAGnD,OACI1E,gBAAC+D,EAAiB,KACd/D,EAAAC,cAAC6E,sBACG1C,OAAQA,CAAC2C,EAAcrC,IACnB1C,EAAAC,cAACgC,EAAAA,QAAO,CAACC,MAAM,SAAS8C,WAAY,GAChChF,EAAAC,cAACgE,MACOc,EACJb,WAAY,CAAEI,SAAU5B,EAAM4B,UAC9B3B,MAAM,UAAS,gBACAD,EAAM4B,UAErBtE,EAAAC,cAACgF,kBAAe1C,SAAS,cAKzCvC,EAAAC,cAACiF,sBACG9C,OAAQA,EAAG+C,SAAQC,GAAgB1C,IAC/B1C,EAAAC,cAAC0E,EAAe,IACRS,EACJlB,WAAY,CAAEI,SAAU5B,EAAM4B,UAC9Be,SAAUF,EAAG,aACF,SACXG,YAAY,YACZC,KAAK,QACLC,UAAW,CACPC,MAAO,CACHC,eACI1F,EAAAC,cAAC0F,iBAAc,CAACC,SAAS,SACrB5F,EAAAC,cAACgF,iBAAc,CAAC1C,SAAS,WAGjCsD,aAAcnD,EAAM3B,MAChBf,EAAAC,cAAC0F,EAAAA,eAAc,CAACC,SAAS,OACrB5F,EAAAC,cAAC6F,oBACGC,KAAK,MACLR,KAAK,QAAO,aACD,eACXS,SAAU,CAAE1F,GAAI,CAAE2F,aAAa,OAE/BjG,EAAAC,cAACiG,gBAAa,CAAC3D,SAAS,YAGhC,QACD6C,EAAaI,WAAWC,UAE5BL,EAAaI,eAO5C,CC5cA,MAAMW,EAAUC,EAAAA,WAA8B,EAAGC,OAAM9F,QAAQ,GAAID,QAAOiD,GAAS4B,IACjFnF,EAAAC,cAACqG,OAAI,CAACD,KAAMA,EAAMrE,MAAO,CAAEzB,MAAO,GAAIV,OAAQU,GAAS,MAAOD,MCDnDiG,EAAc9G,EAAAA,OAAOS,EAAPT,CAAY,EAEnCyE,iBAKA,MAAM5F,EAAQC,EAAAA,WAERiI,EAAmC,UAAvBlI,EAAMgB,QAAQC,KAE1BkH,EAAuC,WAAvBvC,EAAWnB,QAE3B2D,EAAyC,aAAvBxC,EAAWnB,QAE7B4D,EAAqC,SAAvBzC,EAAWnB,QAEzB6D,EAAe,IACQ,YAArB1C,EAAWvB,OAAuB,IAE9B8D,GAAiB,CACjB9D,MAAO6D,EAAYlI,EAAMgB,QAAQuH,OAAOC,MAAQxI,EAAMgB,QAAQyH,KAAK,KACnEC,gBAAiB1I,EAAMgB,QAAQH,KAAK8H,YAGpCP,GAAmB,CACnBM,gBAAiB,cACjBrE,MAAOrE,EAAMgB,QAAQH,KAAK8H,QAC1BC,OAAQ,aAAa5I,EAAMgB,QAAQH,KAAK8H,cAGxCN,GAAe,CACfhE,MAAOrE,EAAMgB,QAAQH,KAAKgI,UAC1BH,gBAAiBI,EAAAA,MAAM9I,EAAMgB,QAAQyH,KAAK,KAAM,QAKtDM,EAAa,IACU,YAArBnD,EAAWvB,OAAuB,IAE9B8D,GAAiB,CACjB9D,MAAOrE,EAAMgB,QAAQ4E,EAAWvB,OAAO2E,aACvCN,gBAAiB1I,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,SAGjDb,GAAmB,CACnBM,gBAAiB,cACjBrE,MAAOrE,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,KACvCL,OAAQ,aAAa5I,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,WAGrDZ,GAAe,CACfhE,MAAOrE,EAAMgB,QAAQ4E,EAAWvB,OAAO6D,EAAY,OAAS,SAC5DQ,gBAAiBI,EAAAA,MAAM9I,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,KAAM,QAKzE,MAAO,CACH1H,OAAQ,GACR2H,SAAU,GACVC,WAAY,EACZC,aAAc,EACdC,OAAQ,UACRhI,WAAY,SACZiI,WAAY,SACZlI,QAAS,cACTE,eAAgB,SAChBiI,cAAe,aACfC,QAASxJ,EAAMyJ,QAAQ,EAAG,KAC1BxF,SAAUjE,EAAM0J,WAAWC,QAAQ,IACnCC,WAAY5J,EAAM0J,WAAWG,eAC7B3D,WAAYlG,EAAMmG,YAAYC,OAAO,MAAO,CACxC0D,SAAU9J,EAAMmG,YAAY2D,SAASC,aAEtCzB,KACAS,KCnFLiB,EAAQlC,EAAAA,WACZ,EAAGmC,WAAU5F,QAAQ,UAAWI,UAAU,OAAQyF,YAAWC,UAASnI,QAAOiD,GAAS4B,KAGpF,MAAMuD,EAAa,CACjBnI,MAAO,GACPV,OAAQ,GACR,aAAc,CAAEU,MAAO,EAAGV,OAAQ,EAAG8I,UAAW,UAGlD,OACE3I,EAAAC,cAACsG,EAAW,CACVpB,IAAKA,EAELjB,WAAY,CAAEvB,QAAOI,WACrBzC,GAAI,IACEkI,GAAa,CAAEI,GAAI,QACnBH,GAAW,CAAEI,GAAI,QAClBvI,MAGDiD,GAEHiF,GAAaxI,EAAAC,cAACC,EAAG,CAACI,GAAI,CAAEwI,GAAI,OAASJ,QAAgBF,EAAiB,KAEtED,EAEAE,GAAWzI,EAAAC,cAACC,EAAG,CAACI,GAAI,CAAEyI,GAAI,OAASL,QAAgBD,EAAe,QCd9DO,EAAwB,iCACxBC,EAAiB,YACjBC,EAA4B,0BAC5BC,EAAwB,yBACxBC,EAAkB,IAAIC,IAAY,CAACJ,EAAgBC,IAEnDI,EAAkB,CAAEC,QAAS,GAAKC,SAAU,EAAGC,YAAa,KAC5DC,EAAqB,GACrBC,EAAwB,GAExBC,EAA2B,GAK3BC,EAAmBC,GAAkBV,EAAgBW,IAAID,IAAUA,IAAUd,EAM7EgB,EAASjJ,GAA8CA,QAEvDkJ,EAAgBlJ,GAAmBiJ,EAAMjJ,IAAoB,KAAVA,GAAiBmJ,MAAMC,QAAQpJ,IAA2B,IAAjBA,EAAMqJ,OAElGC,EAAQA,CAACtJ,EAAeuJ,EAAaC,IAAgBC,KAAKF,IAAIE,KAAKD,IAAIxJ,EAAOuJ,GAAMC,GAEpFE,EAAKA,IAAIC,IAAyDA,EAAWC,OAAOC,SAASC,KAAK,KAkBlGC,EAAW,MACpB,IAAIC,EAAU,EACd,MAAO,CAACC,EAAS,SACbD,GAAW,EACJ,GAAGC,KAAUD,IAE3B,EANuB,GAYXrK,EAAqBA,IAAwB,oBAAXC,aAAyD,IAAxBA,OAAOC,aAE1EC,EAAuBC,IAChC,IAAKJ,IAAsB,OAAO,KAClC,IACI,MAAMK,EAAQJ,OAAOC,aAAaI,QAAQF,GAC1C,OAAOC,EAASE,KAAKC,MAAMH,GAAe,IAC9C,CAAE,MACE,OAAO,IACX,GAGSI,EAAoBA,CAACL,EAAaC,KAC3C,GAAKL,IACL,IACIC,OAAOC,aAAaQ,QAAQN,EAAKG,KAAKI,UAAUN,GACpD,CAAE,MACE,GAQKkK,EAAkBA,CAAiCC,EAAQC,IACpEA,EAAWA,EAASD,GAAQA,EAAIE,GAEvBC,EAA0BA,CACnC5F,EACA6F,KAEA,IAAK7F,EAAO,MAAO,CAAE8F,KAAM,UAAWC,IAAK,IAAInC,KAC/C,GAAIa,MAAMC,QAAQ1E,GAAQ,MAAO,CAAE8F,KAAM,UAAWC,IAAK,IAAInC,IAAI5D,IACjE,GAAIA,aAAiB4D,IAAK,MAAO,CAAEkC,KAAM,UAAWC,IAAK,IAAInC,IAAI5D,IACjE,GAAmB,YAAfA,EAAM8F,MAAsBD,EAAQ,CACpC,MAAME,EAAM,IAAInC,IAIhB,OAHAiC,EAAOG,QAASL,IACP3F,EAAM+F,IAAIzB,IAAIqB,IAAKI,EAAIE,IAAIN,KAE7B,CAAEG,KAAM,UAAWC,MAC9B,CACA,MAAO,CAAED,KAAM,UAAWC,IAAK,IAAInC,IAAI5D,EAAM+F,OAgBpCG,EAAU5K,IACnB,GAAIiJ,EAAMjJ,IAAoB,KAAVA,EAAc,OAAO,KACzC,GAAIA,aAAiB6K,KAAM,OAAOC,OAAOC,MAAM/K,EAAMgL,WAAa,KAAOhL,EACzE,GAAIiL,EAAMC,QAAQlL,GAAQ,OAAOA,EAAMmL,UAAYnL,EAAM4K,SAAW,KACpE,GAAqB,iBAAV5K,EAAoB,CAC3B,MAAMoL,EAAI,IAAIP,KAAK7K,GACnB,OAAO8K,OAAOC,MAAMK,EAAEJ,WAAa,KAAOI,CAC9C,CACA,GAAqB,iBAAVpL,EAAoB,CAC3B,MAAMqL,EAASJ,EAAMjL,GACrB,OAAOqL,EAAOF,UAAYE,EAAOT,SAAW,IAChD,CACA,OAAO,MAGEU,EAAaA,CAACtL,EAAgBuL,KACvC,MAAMC,EAAOZ,EAAO5K,GACpB,OAAKwL,EACEP,EAAMO,GAAMC,OAAOF,EAAW,kBAAoB,YADvC,IAIhBG,EAAcA,CAACF,EAAYD,IAC7BA,EAAWN,EAAMO,GAAMG,QAAQ,UAAUC,UAAYX,EAAMO,GAAMG,QAAQ,OAAOC,UAMvEC,EAAuBC,GACd,iBAAXA,GAAkC,OAAXA,EAErBC,EAAiBA,CAACC,EAAoBF,IAC/CE,EAAID,eAAiBC,EAAID,eAAeD,GAAUD,EAAoBC,GAAUA,EAAO9L,MAAQ8L,EAEtFG,EAAiBA,CAACD,EAAoBF,IAC/CE,EAAIC,eAAiBD,EAAIC,eAAeH,GAAUD,EAAoBC,GAAUA,EAAOI,MAAQC,OAAOL,GAE7FM,EAAsBA,CAACJ,EAAoB7B,EAA4BE,IAC3E2B,EAAIK,aAC0B,mBAArBL,EAAIK,aAA8BL,EAAIK,aAAa,CAAEtD,MAAOiD,EAAIjD,MAAOoB,MAAKE,OAAQ2B,EAAIK,aADxE,GAQrBC,GAAeA,CAACnC,EAA2B6B,EAAoBO,KACxE,MAAMC,EAAMrC,EAAMA,EAAI6B,EAAIjD,YAAS0D,EACnC,OAAOT,EAAIU,YAAcV,EAAIU,YAAYF,EAAKrC,EAAK6B,EAAKO,GAAOC,GAQtDG,GAAqBA,CAAC3M,EAAYgM,EAAoB7B,EAA4BE,KAC3F,GAAIpB,EAAMjJ,GAAQ,MAAO,GACzB,OAAQgM,EAAIxB,MACR,IAAK,OACD,OAAOc,EAAWtL,GAAO,GAC7B,IAAK,WACD,OAAOsL,EAAWtL,GAAO,GAC7B,IAAK,UACD,OAAOA,EAAQ,MAAQ,KAC3B,IAAK,eAAgB,CACjB,MACM4M,EADUR,EAAoBJ,EAAK7B,EAAKE,GACxBwC,KAAMf,GAAWC,EAAeC,EAAKF,KAAY9L,GACvE,YAAiByM,IAAVG,EAAsBX,EAAeD,EAAKY,GAAST,OAAOnM,EACrE,CACA,IAAK,SACD,MAAwB,iBAAVA,EAAsB8K,OAAOgC,SAAS9M,GAASmM,OAAOnM,GAAS,GAAMmM,OAAOnM,GAC9F,QACI,GAAIA,aAAiB6K,KAAM,OAAOS,EAAWtL,GAAO,GACpD,GAAqB,iBAAVA,EACP,IACI,OAAOE,KAAKI,UAAUN,EAC1B,CAAE,MACE,OAAOmM,OAAOnM,EAClB,CAEJ,OAAOmM,OAAOnM,KAIb+M,GAAoBA,CAC7B/M,EACAmK,EACA6B,EACAO,EACAlC,IAEI2B,EAAIgB,eAAuBhB,EAAIgB,eAAehN,EAAOmK,EAAK6B,EAAKO,GAC5DI,GAAmB3M,EAAOgM,EAAK7B,EAAKE,GAGlC4C,GAA0BC,GAC/BjE,EAAMiE,GAAmB,GACJ,iBAAdA,EAA+BA,EACjB,iBAAdA,GAA+C,kBAAdA,EAAgCf,OAAOe,GAC/EA,aAAqBrC,KAAaS,EAAW4B,GAAW,GACnC,iBAAdA,GAA0B,UAAWA,EAAkB,GAC3Df,OAAOe,GA2BZC,GAA2B,oBAATC,KAAuB,IAAIA,KAAKC,cAASZ,EAAW,CAAEa,SAAS,EAAMC,YAAa,SAAY,KAEhHC,GAAWA,CAACC,EAASC,KACvB,MAAMC,EAAK1E,EAAMwE,IAAc,KAAPA,EAClBG,EAAK3E,EAAMyE,IAAc,KAAPA,EACxB,OAAIC,GAAMC,EAAW,EACjBD,GAAW,EACXC,EAAW,EACR,MAGEC,GAAwCA,CAACJ,EAAIC,KACtD,MAAMI,EAAMN,GAASC,EAAIC,GACzB,OAAY,OAARI,EAAqBA,EAClBhD,OAAO2C,GAAM3C,OAAO4C,IAGlBK,GAAwCA,CAACN,EAAIC,KACtD,MAAMI,EAAMN,GAASC,EAAIC,GACzB,GAAY,OAARI,EAAc,OAAOA,EACzB,MAAME,EAAK7B,OAAOsB,GACZQ,EAAK9B,OAAOuB,GAClB,OAAIP,GAAiBA,GAASe,QAAQF,EAAIC,GACnCD,EAAKC,GAAK,EAAKD,EAAKC,EAAK,EAAI,GAG3BE,GAAgDA,CAACV,EAAIC,EAAIU,EAAIC,IACpD,iBAAPZ,GAAiC,iBAAPC,EAAwBG,GAAiBJ,EAAIC,GAC3EK,GAAiBN,EAAIC,GAGnBY,GAAsCA,CAACb,EAAIC,KACpD,MAAMa,EAAK3D,EAAO6C,GACZe,EAAK5D,EAAO8C,GACZI,EAAMN,GAASe,EAAIC,GACzB,OAAY,OAARV,EAAqBA,EACjBS,EAAYvD,UAAawD,EAAYxD,WAGpCyD,GAAyCA,CAAChB,EAAIC,KACvD,MAAMI,EAAMN,GAASC,EAAIC,GACzB,OAAY,OAARI,EAAqBA,EAClBhD,OAAOjB,QAAQ4D,IAAO3C,OAAOjB,QAAQ6D,KAGnCgB,GAAwBlE,IACjC,OAAQA,GACJ,IAAK,SACD,OAAOqD,GACX,IAAK,OACL,IAAK,WACD,OAAOS,GACX,IAAK,UACD,OAAOG,GACX,QACI,OAAON,KAQbQ,GAAS3O,GAAoBiJ,EAAMjJ,GAAS,GAAKmM,OAAOnM,GAAO4O,cAE/DC,GAAYC,IAA6B5F,EAAa4F,EAAK9O,OAEpD+O,GAAiD,CAC1D,CACI/O,MAAO,WACPkM,MAAO,WACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK9O,OAC1B,OAAQA,IAA2C,IAAjC2O,GAAM3O,GAAOmP,QAAQD,KAG/C,CACIlP,MAAO,iBACPkM,MAAO,mBACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK9O,OAC1B,OAAQA,IAA2C,IAAjC2O,GAAM3O,GAAOmP,QAAQD,KAG/C,CACIlP,MAAO,SACPkM,MAAO,SACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK9O,OAC1B,OAAQA,GAAU2O,GAAM3O,KAAWkP,IAG3C,CACIlP,MAAO,eACPkM,MAAO,iBACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK9O,OAC1B,OAAQA,GAAU2O,GAAM3O,KAAWkP,IAG3C,CACIlP,MAAO,aACPkM,MAAO,cACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK9O,OAC1B,OAAQA,GAA2C,IAAjC2O,GAAM3O,GAAOmP,QAAQD,KAG/C,CACIlP,MAAO,WACPkM,MAAO,YACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK9O,OAC1B,OAAQA,IACJ,MAAMoP,EAAIT,GAAM3O,GAChB,OAAOoP,EAAE/F,QAAU6F,EAAO7F,QAAU+F,EAAEC,YAAYH,KAAYE,EAAE/F,OAAS6F,EAAO7F,UAI5F,CACIrJ,MAAO,UACPkM,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOjP,GAAUkJ,EAAalJ,IAEpD,CACIA,MAAO,aACPkM,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOjP,IAAWkJ,EAAalJ,IAErD,CACIA,MAAO,UACPkM,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAK3F,MAAMC,QAAQ0F,EAAK9O,QAAgC,IAAtB8O,EAAK9O,MAAMqJ,OAAc,OAAO,KAClE,MAAMkG,EAAM,IAAIjH,IAAIwG,EAAK9O,MAAM0C,IAAIiM,KACnC,OAAQ3O,GAAUuP,EAAIvG,IAAI2F,GAAM3O,OAKtCwP,GAAiBA,CACnBxP,EACAkM,EACAgC,KAAkD,CAElDlO,QACAkM,QACA8C,UAAW,SACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMW,EAAc3E,OAAOgE,EAAK9O,OAChC,OAAI8K,OAAOC,MAAM0E,GAAqB,KAC9BC,IACJ,GAAIzG,EAAMyG,IAAkB,KAATA,EAAa,OAAO,EACvC,MAAMC,EAAI7E,OAAO4E,GACjB,OAAQ5E,OAAOC,MAAM4E,IAAMzB,EAAQyB,EAAGF,OAKrCG,GAAiD,CAC1DJ,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,IAAMC,GACzCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,IAAMC,GAC3CN,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,EAAIC,GACvCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,GAAKC,GAC1CN,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,EAAIC,GACvCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,GAAKC,GAC1C,CACI9P,MAAO,UACPkM,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOjP,GAAUkJ,EAAalJ,IAEpD,CACIA,MAAO,aACPkM,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOjP,IAAWkJ,EAAalJ,IAErD,CACIA,MAAO,UACPkM,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAK3F,MAAMC,QAAQ0F,EAAK9O,QAAgC,IAAtB8O,EAAK9O,MAAMqJ,OAAc,OAAO,KAClE,MAAMkG,EAAM,IAAIjH,IAAIwG,EAAK9O,MAAM0C,IAAKqN,GAAWjF,OAAOiF,KACtD,OAAQ/P,IAAWiJ,EAAMjJ,IAAUuP,EAAIvG,IAAI8B,OAAO9K,OAKxDgQ,GAAeA,CACjBhQ,EACAkM,EACAX,EACA2C,KAAkD,CAElDlO,QACAkM,QACA8C,UAAWzD,EAAW,iBAAmB,OACzC0D,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMmB,EAAarF,EAAOkE,EAAK9O,OAC/B,IAAKiQ,EAAY,OAAO,KACxB,MAAMC,EAAaxE,EAAYuE,EAAY1E,GAC3C,OAAQmE,IACJ,MAAMS,EAAWvF,EAAO8E,GACxB,QAAKS,GACEjC,EAAQxC,EAAYyE,EAAU5E,GAAW2E,OAK/CE,GAA0B7E,GAA+C,CAClFyE,GAAa,KAAM,KAAMzE,EAAU,CAACsE,EAAGC,IAAMD,IAAMC,GACnDE,GAAa,MAAO,SAAUzE,EAAU,CAACsE,EAAGC,IAAMD,IAAMC,GACxDE,GAAa,QAAS,WAAYzE,EAAU,CAACsE,EAAGC,IAAMD,EAAIC,GAC1DE,GAAa,YAAa,iBAAkBzE,EAAU,CAACsE,EAAGC,IAAMD,GAAKC,GACrEE,GAAa,SAAU,YAAazE,EAAU,CAACsE,EAAGC,IAAMD,EAAIC,GAC5DE,GAAa,aAAc,kBAAmBzE,EAAU,CAACsE,EAAGC,IAAMD,GAAKC,GACvE,CACI9P,MAAO,UACPkM,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOjP,GAA4B,OAAlB4K,EAAO5K,IAE9C,CACIA,MAAO,aACPkM,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOjP,GAA4B,OAAlB4K,EAAO5K,KAIrCqQ,GAAkD,CAC3D,CACIrQ,MAAO,KACPkM,MAAO,KACP8C,UAAW,UACXC,iBAAmBH,IACf,GAAI7F,EAAM6F,EAAK9O,QAAyB,KAAf8O,EAAK9O,OAA+B,QAAf8O,EAAK9O,MAAiB,OAAO,KAC3E,MAAMsQ,GAA0B,IAAfxB,EAAK9O,OAAiC,SAAf8O,EAAK9O,MAC7C,OAAQA,GAAU6J,QAAQ7J,KAAWsQ,KAKpCC,GAAuD,CAChE,CACIvQ,MAAO,KACPkM,MAAO,KACP8C,UAAW,SACXC,iBAAmBH,GACX7F,EAAM6F,EAAK9O,QAAyB,KAAf8O,EAAK9O,MAAqB,KAC3CA,GAAUmM,OAAOnM,KAAWmM,OAAO2C,EAAK9O,QAGxD,CACIA,MAAO,MACPkM,MAAO,SACP8C,UAAW,SACXC,iBAAmBH,GACX7F,EAAM6F,EAAK9O,QAAyB,KAAf8O,EAAK9O,MAAqB,KAC3CA,GAAUmM,OAAOnM,KAAWmM,OAAO2C,EAAK9O,QAGxD,CACIA,MAAO,UACPkM,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAK3F,MAAMC,QAAQ0F,EAAK9O,QAAgC,IAAtB8O,EAAK9O,MAAMqJ,OAAc,OAAO,KAClE,MAAMkG,EAAM,IAAIjH,IAAIwG,EAAK9O,MAAM0C,IAAIyJ,SACnC,OAAQnM,GAAUuP,EAAIvG,IAAImD,OAAOnM,OAwBhCwQ,GAA4BxE,GAAuBA,EAAIyE,iBAnB1BjG,KACtC,OAAQA,GACJ,IAAK,SACD,OAAOoF,GACX,IAAK,OACD,OAAOQ,IAAuB,GAClC,IAAK,WACD,OAAOA,IAAuB,GAClC,IAAK,UACD,OAAOC,GACX,IAAK,eACD,OAAOE,GACX,IAAK,UACD,MAAO,GACX,QACI,OAAOxB,KAIoE2B,CAA0B1E,EAAIxB,MAMxGmG,GAAmD3E,IAC5D,MAAMxB,EAAOwB,EAAIxB,MAAQ,SACnBoG,EAAoB,WAATpG,EACXqG,EAAqB,YAATrG,EACZsG,EAAqB,YAATtG,EAClB,MAAO,IACAwB,EACHxB,OACAuG,WAAY/E,EAAI+E,YAAc/E,EAAIjD,MAClCvJ,MAAOwM,EAAIxM,OAAsB,IACjCiH,SAAUuF,EAAIvF,UAAYoC,EAC1BmI,MAAOhF,EAAIgF,QAAUJ,EAAW,QAAUC,GAAaC,EAAY,SAAW,QAC9EG,YAAajF,EAAIiF,aAAejF,EAAIgF,QAAUJ,EAAW,QAAUC,GAAaC,EAAY,SAAW,QACvGI,UAAUJ,IAAqB9E,EAAIkF,WAAY,GAC/CC,YAAYL,IAAqB9E,EAAImF,aAAc,GACnDC,SAAUpF,EAAIoF,WAAY,EAC1BC,UAAWrF,EAAIqF,YAAa,EAC5BC,SAAUtF,EAAIsF,WAAY,EAC1BC,WAAWT,IAAqB9E,EAAIuF,YAAa,GACjDC,YAAYV,IAAqB9E,EAAIwF,aAAc,GACnDC,SAAUzF,EAAIyF,WAAY,EAC1BC,kBAAmB1F,EAAI0F,mBAAqBZ,EAC5Ca,cAAe3F,EAAI2F,eAAiBb,IAQtCc,GAAiBA,CAAC7I,EAAevJ,IACnCmR,GAAgB,CACZ5H,QACAgI,WAAY,GACZvR,QACAiH,SAAUjH,EACVC,SAAUD,EACV0R,UAAU,EACVC,YAAY,EACZC,UAAU,EACVC,WAAW,EACXC,UAAU,EACVC,WAAW,EACXC,YAAY,EACZE,mBAAmB,EACnBC,eAAe,EACfE,gBAAgB,EAChBb,MAAO,SACPC,YAAa,WAIRa,GAAqCF,GAAe1J,EAjmB5B,IAmmBxB6J,GAAgDH,GACzDzJ,EAnmBsC,IA2mBpC6J,GAAsB,IAAI1J,IAAI,CAChC,0BACA,oBACA,mBACA,mBACA,UACA,eACA,kBACA,cACA,UACA,OACA,WACA,eACA,aACA,eACA,YACA,WACA,UACA,aACA,cACA,eACA,aACA,gBACA,iBACA,kBACA,aACA,YACA,aACA,UACA,QACA,UACA,UACA,SACA,SACA,OACA,cACA,eACA,cACA,kBACA,mBACA,mBACA,gBACA,gBAIS2J,GAAiBlS,GAAgB,mBAAmBmS,KAAKnS,GAahEoS,GAAyBC,GAC3BC,OAAOC,KAAKF,GACPxI,OAAQ7J,IACL,MAAMC,EAAQoS,EAAMrS,GACpB,OAAQkS,GAAclS,KAA0B,iBAAVC,GAAuC,iBAAVA,KAEtE0C,IAAK3C,IAAQ,SAjBDwS,KACjB,GAA+B,IAA3BA,EAASpD,QAAQ,MAAa,OAAOoD,EACzC,MAAMC,EAAQD,EAASE,QAAQ,SAAWC,GAAM,IAAIA,EAAE9D,iBACtD,OAAgC,IAAzB4D,EAAMrD,QAAQ,OAAe,IAAIqD,IAAUA,GAc7BG,CAAY5S,MAXbwS,EAWoCxS,EAXlBC,EAWuBoS,EAAMrS,GAVlD,iBAAVC,GAAgC,IAAVA,GAAgBgS,GAAoBhJ,IAAIuJ,IAAwC,IAA3BA,EAASpD,QAAQ,MAE7FhD,OAAOnM,GADP,GAAGA,QAFU4S,IAACL,EAAkBvS,IAYjC8J,KAAK,KAcD+I,GAAiBA,CAACC,EAAevT,EAAyCwT,EAAgB,KAC9FxT,GACL8S,OAAOC,KAAK/S,GAAImL,QAAS3K,IACrB,MAAMC,EAAQT,EAAGQ,GACjB,IAAKC,GAA0B,iBAAVA,EAAoB,OACzC,MAAMoS,EAAQpS,EACd,GAAsB,MAAlBD,EAAIiT,OAAO,GAAY,CACvB,MAAMC,EAAkB,GAClBC,EAAef,GAAsBC,GAI3C,OAHIc,GAAcD,EAAME,KAAK,GAAGL,KAASI,MACzCL,GAAeC,EAAOV,EAAOa,QACzBA,EAAM5J,QAAQ0J,EAAII,KAAK,GAAGpT,KAAOkT,EAAMnJ,KAAK,QAEpD,CACA,MAAMsJ,EA1BQC,EAACP,EAAeM,IAClCA,EACKE,MAAM,KACN5Q,IAAK6Q,GAASA,EAAKC,QACnB5J,OAAOC,SACPnH,IAAK6Q,IAAgC,IAAtBA,EAAKpE,QAAQ,KAAcoE,EAAKd,QAAQ,KAAMK,GAAS,GAAGA,KAASS,KAClFzJ,KAAK,KAoBWuJ,CAAcP,EAAO/S,GAChCmT,EAAef,GAAsBC,GACvCc,GAAcH,EAAII,KAAK,GAAGC,KAAYF,MAC1CL,GAAeO,EAAUhB,EAAOW,KAE7BA,GAlBSA,EAyBdU,GAAiBC,GACnBA,EAAOhR,IAAKqN,GAAoB,iBAANA,EAAiBA,EAAIjF,OAAOiF,IAAKnG,OAAQ+F,IAAO7E,OAAOC,MAAM4E,IAAY,OAANA,GAEpFgE,GAA6E,CACtFC,IAAK,CACD1H,MAAO,MACP2H,YAAa,CAAC,UACdC,MAAOA,EAAGJ,aACN,MAAMK,EAAON,GAAcC,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,IAC7D,OAAoB,IAAhBgE,EAAK1K,OAAqB,KACvB0K,EAAKC,OAAO,CAACC,EAAKtE,IAAMsE,EAAMtE,EAAG,KAGhDuE,IAAK,CACDhI,MAAO,MACP2H,YAAa,CAAC,UACdC,MAAOA,EAAGJ,aACN,MAAMK,EAAON,GAAcC,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,IAC7D,OAAoB,IAAhBgE,EAAK1K,OAAqB,KACvB0K,EAAKC,OAAO,CAACC,EAAKtE,IAAMsE,EAAMtE,EAAG,GAAKoE,EAAK1K,SAG1DE,IAAK,CACD2C,MAAO,MACP2H,YAAa,CAAC,SAAU,OAAQ,YAChCC,MAAOA,EAAGJ,aACN,MAAMS,EAAUT,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,GAClD,GAAuB,IAAnBoE,EAAQ9K,OAAc,OAAO,KACjC,GAAI8K,EAAQC,MAAOrE,GAAmB,iBAANA,GAAiB,OAAOtG,KAAKF,OAAQ4K,GACrE,MAAME,EAAQF,EAAQzR,IAAIkI,GAC1B,OAAIyJ,EAAMD,MAAOhJ,GAAY,OAANA,GACZ,IAAIP,KAAKpB,KAAKF,OAAO8K,EAAM3R,IAAK0I,GAAOA,EAAWJ,aAEtDmJ,EAAQG,QAAQC,KAAK,CAAC1E,EAAGC,IAAM/B,GAAiB8B,EAAGC,IAA8B,KAGhGtG,IAAK,CACD0C,MAAO,MACP2H,YAAa,CAAC,SAAU,OAAQ,YAChCC,MAAOA,EAAGJ,aACN,MAAMS,EAAUT,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,GAClD,GAAuB,IAAnBoE,EAAQ9K,OAAc,OAAO,KACjC,GAAI8K,EAAQC,MAAOrE,GAAmB,iBAANA,GAAiB,OAAOtG,KAAKD,OAAQ2K,GACrE,MAAME,EAAQF,EAAQzR,IAAIkI,GAC1B,GAAIyJ,EAAMD,MAAOhJ,GAAY,OAANA,GACnB,OAAO,IAAIP,KAAKpB,KAAKD,OAAO6K,EAAM3R,IAAK0I,GAAOA,EAAWJ,aAE7D,MAAMwJ,EAASL,EAAQG,QAAQC,KAAK,CAAC1E,EAAGC,IAAM/B,GAAiB8B,EAAGC,IAClE,OAAO0E,EAAOA,EAAOnL,OAAS,KAGtC7E,KAAM,CACF0H,MAAO,OACP4H,MAAOA,EAAGJ,YAAaA,EAAOrK,SAQzBoL,GAAyC,CAClDC,YAAa,UACbC,aAAc,WACdC,eAAgB,UAChBC,eAAgB,UAChBC,cAAe,SACfC,eAAgB,UAChBC,8BAA+B,YAC/BC,wBAAyB,SACzBC,iBAAkB,kBAClBC,mBAAoB,oBACpBC,mBAAoB,QACpBC,eAAgB,UAChBC,gBAAiB,WACjBC,mBAAoB,cACpBC,8BAA+B,SAC/BC,oBAAqB,WACrBC,oBAAqB,WACrBC,kBAAmB,QACnBC,qBAAsB,aACtBC,qBAAsB,aACtBC,sBAAuB,SACvBC,mBAAoB,UACpBC,oBAAqB,WACrBC,iBAAkB,QAClBC,4BAA6B,eAC7BC,yBAA0B,iBAC1BC,uBAAwB,MACxBC,sBAAuB,KACvBC,kBAAmB,cACnBC,mBAAoB,eACpBC,iBAAkB,SAClBC,iBAAkB,SAClBC,qBAAsB,cACtBC,wBAAyB,iBACzBC,kBAAmB,cACnBC,mBAAoB,eACpBC,gBAAiB,QACjBC,gBAAkBC,GAAS,YAAYA,IACvCC,kBAAoBD,GAAS,oBAAoBA,IACjDE,sBAAuB,cACvBC,0BAA2B,cAC3BC,6BAA8B,OAC9BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,6BAA8B,OAC9BC,kBAAoBC,GAAqB,IAAVA,EAAc,iBAAmB,GAAGA,EAAMC,iCACzEC,gBAAiB,cACjBC,4BAA6B,iBAC7BC,8BAA+BA,CAACC,EAAMC,EAAIN,IAAU,GAAGK,KAAQC,QAASN,EAAMC,mBAC9EM,0BAA2B,aAC3BC,6BAA8B,gBAC9BC,yBAA0B,YAC1BC,yBAA0B,YAC1BC,4BAA6B,qBAC7BC,+BAAgC,kBAChCC,iCAAkC,oBAClCC,2BAA4B,aAC5BC,6BAA8B,eAC9BC,qBAAsB,MACtBC,sBAAuB,KACvBC,kBAAmB,sBACnBC,kBAAmB,SACnBC,oBAAqB,WACrBC,yBAA0B,QAC1BC,YAAcjC,GAAS,YAAYA,IACnCkC,cAAgBlC,GAAS,oBAAoBA,IAC7CmC,gBAAiB,OACjBC,0BAA2B,OAC3BC,gBAAiB,OACjBC,YAAa,gBAOjB,IAAIC,GAEG,MAAMC,GAAcA,CAACpb,EAAcqb,KACtC,GAAwB,oBAAbC,SAA0B,OAAqB,EAAdtb,EAAKiL,OACjD,QAAuBoD,IAAnB8M,GAA8B,CAC9B,MAAMI,EAASD,SAASxa,cAAc,UACtCqa,GAAiBI,EAAOC,WAAW,KACvC,CACA,OAAKL,IACLA,GAAeE,KAAOA,EACfF,GAAeC,YAAYpb,GAAMoB,OAFE,EAAdpB,EAAKiL,QASxBwQ,GAAeA,CAACC,EAAYC,KACrC,GAAwB,oBAAbL,SAA0B,OACrC,MAAMM,EAAMC,IAAIC,gBAAgBJ,GAC1BK,EAAST,SAASxa,cAAc,KACtCib,EAAOC,KAAOJ,EACdG,EAAOE,SAAWN,EAClBI,EAAOlZ,MAAMtC,QAAU,OACvB+a,SAASY,KAAKC,YAAYJ,GAC1BA,EAAOK,QACP5a,OAAO6a,WAAW,KACdf,SAASY,KAAKI,YAAYP,GAC1BF,IAAIU,gBAAgBX,IACrB,IC95BMY,GAAoB,kBAQpBC,GAAe,mj1BA+T5B,IAAIC,IAAW,EAEf,MAcMC,GACD9b,EAAc+b,qBAAyC,oBAAXpb,OAAyBX,EAAMgc,gBAAkBhc,EAAMic,WAG3FC,GAAmBA,KAC5BJ,GAAa,KAnBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAeT,IAExB,YADAE,IAAW,GAGf,MAAM7Z,EAAQyY,SAASxa,cAAc,SACrC+B,EAAMoJ,GAAKuQ,GACX3Z,EAAMqa,aAAa,gBAAiB,QACpCra,EAAMsa,YAAcV,GACpBnB,SAAS8B,KAAKjB,YAAYtZ,GAC1B6Z,IAAW,GASPM,IACD,KCpTMK,GAAiBxc,EAAMyc,cAA0C,MAC9ED,GAAeE,YAAc,iBAEtB,MAAMC,GAAoBA,KAC7B,MAAMC,EAAM5c,EAAM6c,WAAWL,IAC7B,IAAKI,EACD,MAAM,IAAIE,MAAM,yFAEpB,OAAOF,GCjDL,SAAUG,GAAgBhc,GAC5B,MAAMoE,EAAMnF,EAAMgd,OAAOjc,GAEzB,OADAoE,EAAI8X,QAAUlc,EACPoE,CACX,UAYgB+X,GACZC,EACAC,EACAC,GAEA,MAAMC,OAA8B9P,IAAf2P,GACdI,EAAUC,GAAexd,EAAMyd,SAAYL,GAC5Crc,EAAQuc,EAAgBH,EAAmBI,EAC3CG,EAAWX,GAAahc,GACxB4c,EAAgBZ,GAAaO,GAC7BM,EAAcb,GAAaM,GAUjC,MAAO,CAACtc,EARSf,EAAM6d,YAAaC,IAChC,MAAMC,EAA2B,mBAATD,EAAuBA,EAAwBJ,EAAST,SAAWa,EACvF1K,OAAO4K,GAAGD,EAAUL,EAAST,WACjCS,EAAST,QAAUc,EACdJ,EAAcV,SAASO,EAAYO,GACxCH,EAAYX,UAAUc,KACvB,IAGP,CAmFA,IAAIE,GAAY,ECxFT,MAeMC,GAAmBA,CAAC5Q,EAAiB1J,KAC9C,MAAMua,EAhB0BC,EAAC9Q,EAAiB1J,KAClD,MAAMya,EAAM/Q,EAAIgR,gBAChB,IAAIH,EACJ,GAAIva,EAAQ2a,OAAQ,CAChB,MAAMC,EAAU,IAAIC,IACpBJ,EAAI5S,QAASiT,GAAMF,EAAQlO,IAAIoO,EAAE5U,MAAO4U,IACxCP,EAAUva,EAAQ2a,OAAO9a,IAAKkb,GAAMH,EAAQI,IAAID,IAAIhU,OAAOC,QAC/D,MACIuT,EADOva,EAAQR,WACLib,EAEA/Q,EAAIuR,oBAElB,OAAOV,EAAQxT,OAAQ+T,IAAOA,EAAEhM,gBAAkB7I,EAAgB6U,EAAE5U,QAAqB,YAAX4U,EAAEnT,OAIhE6S,CAAqB9Q,EAAK1J,GACpC4H,EAAsB5H,EAAQkb,gBAAkBlb,EAAQkb,gBAAgB,CAAExR,QAASA,EAAIyR,kBACvFC,EAAuB,GAY7B,OAXAxT,EAAIC,QAASL,IACT,MAAMF,EAAMoC,EAAI2R,OAAO7T,GAClBF,GACL8T,EAAK9K,KACDiK,EAAQ1a,IAAKsJ,IACT,MAAMQ,EAAMF,GAAanC,EAAK6B,EAAKO,GAEnC,MAAO,CAAEC,MAAKU,UADID,GAAuBF,GAAkBP,EAAKrC,EAAK6B,EAAKO,EAAKlC,IACtD2B,YAI9B,CAAEoR,UAASe,QAASf,EAAQ1a,IAAKib,GAAMA,EAAE5M,YAAc4M,EAAE5U,OAAQkV,SAGtEG,GAAmBA,CAACpH,EAA0BqH,EAAkBC,KAClE,MAAMC,EAAQvH,GAAQA,EAAKxD,QAAW6K,EACtC,OAAOE,EAAK3P,cAAc4P,SAAS,IAAIF,KAAeC,EAAO,GAAGA,KAAQD,KAGtEG,GAAkBA,MACc,oBAAb/E,UAA4BA,SAASvY,MAAQuY,SAASvY,MAAMqS,OAAS,KACzE,UAAUf,QAAQ,iBAAkB,KAOnDiM,GAAgBA,CAAC1e,EAAe2e,KAClC,IAAIvgB,EAAO4B,EAGX,MADI,eAAekS,KAAK9T,KAAOA,EAAO,IAAIA,MAChB,IAAtBA,EAAK+Q,QAAQ,OAA2C,IAA5B/Q,EAAK+Q,QAAQwP,IAAqB,SAASzM,KAAK9T,GACrE,IAAIA,EAAKqU,QAAQ,KAAM,SAE3BrU,GAGEwgB,GAAeA,CAACrS,EAAiB1J,EAAmC,MAC7E,MAAM8b,EAAY9b,EAAQ8b,WAAa,IACjCE,EAAiBhc,EAAQgc,iBAAkB,EAC3CC,EAAQ3B,GAAiB5Q,EAAK1J,GAC9Bkc,EAAkB,GAcxB,OAbIF,GACAE,EAAM5L,KAAK2L,EAAMX,QAAQzb,IAAKsc,GAAMN,GAAcM,EAAGL,IAAY7U,KAAK6U,IAE1EG,EAAMb,KAAKvT,QAASuU,IAChBF,EAAM5L,KACF8L,EACKvc,IAAKgN,IACF,MAAMtR,EAAOyE,EAAQqc,aAAgBjW,EAAMyG,EAAKlD,KAAO,GAAKL,OAAOuD,EAAKlD,KAAQkD,EAAKxC,UACrF,OAAOwR,GAActgB,EAAMugB,KAE9B7U,KAAK6U,MAGXI,EAAMjV,KAAK,SAGhBqV,GAAWhT,OAAOiT,aAAa,OAa/BC,GAAY,MACd,MAAMP,EAAQ,IAAIQ,YAAY,KAC9B,IAAK,IAAI3P,EAAI,EAAGA,EAAI,IAAKA,GAAK,EAAG,CAC7B,IAAIgO,EAAIhO,EACR,IAAK,IAAI4P,EAAI,EAAGA,EAAI,EAAGA,GAAK,EACxB5B,EAAQ,EAAJA,EAAQ,WAAcA,IAAM,EAAKA,IAAM,EAE/CmB,EAAMnP,GAAKgO,IAAM,CACrB,CACA,OAAOmB,CACV,EAViB,GAoBZU,GAAqC,oBAAhBC,YAA8B,IAAIA,YAAgB,KAEvEC,GAActhB,IAChB,GAAIohB,GAAa,OAAOA,GAAYG,OAAOvhB,GAE3C,MAAMwhB,EAAOC,SAASC,mBAAmB1hB,IACnC2U,EAAM,IAAIgN,WAAWH,EAAKvW,QAChC,IAAK,IAAI2W,EAAI,EAAGA,EAAIJ,EAAKvW,OAAQ2W,GAAK,EAAGjN,EAAIiN,GAAKJ,EAAKK,WAAWD,GAClE,OAAOjN,GAQLmN,GAAeC,IACjB,MAAMC,EAAQD,EAAOnM,OAAO,CAACC,EAAK0J,IAAM1J,EAAM0J,EAAEtU,OAAQ,GAClD0J,EAAM,IAAIgN,WAAWK,GAC3B,IAAIC,EAAS,EAKb,OAJAF,EAAOzV,QAASiT,IACZ5K,EAAIxD,IAAIoO,EAAG0C,GACXA,GAAU1C,EAAEtU,SAET0J,GAGLuN,GAAYC,IACd,MAAMC,EAA4B,GAC5BC,EAA8B,GACpC,IAAIJ,EAAS,EAKbE,EAAQ7V,QAASgW,IACb,MAAMC,EAAYjB,GAAWgB,EAAM1J,MAC7B4J,EA7CCC,KACX,IAAID,EAAM,WACV,IAAK,IAAIZ,EAAI,EAAGA,EAAIa,EAAMxX,OAAQ2W,GAAK,EACnCY,EAAMvB,GAA6B,KAAlBuB,EAAMC,EAAMb,KAAeY,IAAQ,EAExD,OAAc,WAANA,KAAsB,GAwCdE,CAAMJ,EAAMK,MAClBvc,EAAOkc,EAAMK,KAAK1X,OAElB2X,EAAQ,IAAIjB,WAAW,GAAKY,EAAUtX,QACtC4X,EAAK,IAAIC,SAASF,EAAMG,QAC9BF,EAAGG,UAAU,EAAG,UAAY,GAC5BH,EAAGI,UAAU,EAAG,IAAI,GACpBJ,EAAGI,UAAU,EAAG,MAAQ,GACxBJ,EAAGI,UAAU,EAAG,GAAG,GACnBJ,EAAGI,UAAU,GAdD,GAcc,GAC1BJ,EAAGI,UAAU,GAdA,IAca,GAC1BJ,EAAGG,UAAU,GAAIR,GAAK,GACtBK,EAAGG,UAAU,GAAI5c,GAAM,GACvByc,EAAGG,UAAU,GAAI5c,GAAM,GACvByc,EAAGI,UAAU,GAAIV,EAAUtX,QAAQ,GACnC4X,EAAGI,UAAU,GAAI,GAAG,GACpBL,EAAMzR,IAAIoR,EAAW,IAErB,MAAMW,EAAU,IAAIvB,WAAW,GAAKY,EAAUtX,QACxCkY,EAAK,IAAIL,SAASI,EAAQH,QAChCI,EAAGH,UAAU,EAAG,UAAY,GAC5BG,EAAGF,UAAU,EAAG,IAAI,GACpBE,EAAGF,UAAU,EAAG,IAAI,GACpBE,EAAGF,UAAU,EAAG,MAAQ,GACxBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GA9BD,GA8Bc,GAC1BE,EAAGF,UAAU,GA9BA,IA8Ba,GAC1BE,EAAGH,UAAU,GAAIR,GAAK,GACtBW,EAAGH,UAAU,GAAI5c,GAAM,GACvB+c,EAAGH,UAAU,GAAI5c,GAAM,GACvB+c,EAAGF,UAAU,GAAIV,EAAUtX,QAAQ,GACnCkY,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGH,UAAU,GAAI,GAAG,GACpBG,EAAGH,UAAU,GAAIf,GAAQ,GACzBiB,EAAQ/R,IAAIoR,EAAW,IAEvBH,EAAYrN,KAAK6N,EAAON,EAAMK,MAC9BN,EAActN,KAAKmO,GACnBjB,GAAUW,EAAM3X,OAAS7E,IAG7B,MAAMgd,EAAmBtB,GAAYO,GAC/BgB,EAAO,IAAI1B,WAAW,IACtB2B,EAAK,IAAIR,SAASO,EAAKN,QAU7B,OATAO,EAAGN,UAAU,EAAG,WAAY,GAC5BM,EAAGL,UAAU,EAAG,GAAG,GACnBK,EAAGL,UAAU,EAAG,GAAG,GACnBK,EAAGL,UAAU,EAAGd,EAAQlX,QAAQ,GAChCqY,EAAGL,UAAU,GAAId,EAAQlX,QAAQ,GACjCqY,EAAGN,UAAU,GAAII,EAAiBnY,QAAQ,GAC1CqY,EAAGN,UAAU,GAAIf,GAAQ,GACzBqB,EAAGL,UAAU,GAAI,GAAG,GAEbnB,GAAYM,EAAYmB,OAAO,CAACH,EAAkBC,MAIvDG,GAAoB,IAAIC,OAC1B,IACI1V,OAAOiT,aAAa,GACpB,IACAjT,OAAOiT,aAAa,GACpBjT,OAAOiT,aAAa,IACpBjT,OAAOiT,aAAa,IACpBjT,OAAOiT,aAAa,IACpB,IACAjT,OAAOiT,aAAa,IACpBjT,OAAOiT,aAAa,OACpBjT,OAAOiT,aAAa,OACpB,IACJ,KAIE0C,GAAa1jB,GAFMA,IAAiBA,EAAKqU,QAAQmP,GAAmB,IAGtEG,CAAgB3jB,GACXqU,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,UACdA,QAAQ,KAAM,UAEjBuP,GAAgBC,IAClB,IAAItS,EAAIsS,EAAQ,EACZC,EAAU,GACd,KAAOvS,EAAI,GAAG,CACV,MAAMwS,GAAOxS,EAAI,GAAK,GACtBuS,EAAU/V,OAAOiT,aAAa,GAAK+C,GAAOD,EAC1CvS,EAAIlG,KAAK2Y,OAAOzS,EAAI,GAAK,GAC7B,CACA,OAAOuS,GAQLG,GAAa,4DAEbC,GAAgBA,CAACxD,EAAoBD,EAAyB0D,KAChE,MAAMC,EAAoB,GAC1B,IAAIC,EAAW,EAEf,MAAMC,EAAeA,CAACte,EAAahG,EAAc6C,IAC7C,SAASmD,mBAAqBnD,EAAQ,OAAOA,KAAW,kCAAkC6gB,GACtF1jB,kBAGR,GAAIygB,EAAgB,CAChB,MAAMI,EAAQH,EAAMX,QAAQzb,IAAI,CAACsc,EAAGgB,IAAM0C,EAAa,GAAGV,GAAahC,KAAKyC,IAAYzD,EAAG,IAAIlV,KAAK,IACpG0Y,EAAQrP,KAAK,WAAWsP,MAAaxD,WACrCwD,GAAY,CAChB,CAEA3D,EAAMb,KAAKvT,QAASuU,IAChB,MAAM0D,EAAW1D,EACZvc,IAAI,CAACgN,EAAMsQ,KACR,MAAM5b,EAAM,GAAG4d,GAAahC,KAAKyC,IAC3BjY,EAAOkF,EAAK1D,IAAIxB,KACtB,GAAIvB,EAAMyG,EAAKlD,MAAqB,KAAbkD,EAAKlD,IAAY,MAAO,GAC/C,GAAa,WAAThC,GAAyC,iBAAbkF,EAAKlD,KAAoB1B,OAAOgC,SAAS4C,EAAKlD,KAC1E,MAAO,SAASpI,SAAWsL,EAAKlD,cAEpC,GAAa,YAAThC,EACA,MAAO,SAASpG,eAAiBsL,EAAKlD,IAAM,EAAI,YAEpD,IAAc,SAAThC,GAA4B,aAATA,IAAwBI,EAAO8E,EAAKlD,KAAM,CAE9D,MAAMpB,EAAIR,EAAO8E,EAAKlD,KAUtB,MAAO,SAASpI,SAAoB,aAAToG,EAAsB,EAAI,SATzCK,KAAK+X,IACbxX,EAAEyX,cACFzX,EAAE0X,WACF1X,EAAE2X,UACF3X,EAAE4X,WACF5X,EAAE6X,aACF7X,EAAE8X,cAEe,MAAW,eAEpC,CACA,OAAOR,EAAate,EAAKsL,EAAKxC,aAEjCpD,KAAK,IACV0Y,EAAQrP,KAAK,WAAWsP,MAAaE,WACrCF,GAAY,IAGhB,MAAMU,EAAUnB,GAAavY,KAAKD,IAAIsV,EAAM1B,QAAQ/T,OAAS,EAAG,IAC1D+Z,EAAU3Z,KAAKD,IAAIiZ,EAAW,EAAG,GACjCY,EAAOd,EAAa7f,IAAI,CAAC4gB,EAAGtD,IAAM,aAAaA,EAAI,WAAWA,EAAI,aAAasD,wBAAwBxZ,KAAK,IAElH,OACIuY,iKAGA,sBAAsBc,IAAUC,kDAE/BvE,EAAiB,6EAA+E,IALjGwD,mEAQCgB,EAAO,SAASA,WAAgB,IACjC,cAAcb,EAAQ1Y,KAAK,mBAC1B+U,GAAkBC,EAAMb,KAAK5U,OAAS,EAAI,uBAAuB8Z,IAAUC,OAAe,IAC3F,gBAIFG,GACFlB,ojCAgBEmB,GACFnB,o2BAWEoB,GACFpB,yhBAOEqB,GACFrB,sXAMEsB,GAAoBC,GACtBvB,gKAGA,wBAAwBP,GAAU8B,oDAGhCC,GAAeA,KACjB,MAAMC,GAAM,IAAIjZ,MAAOkZ,cACvB,OACI1B,uUAKA,8CAA8CyB,sBAC9C,+CAA+CA,4CAKjDE,GACF3B,oOAKS4B,GAAYA,CAAC1X,EAAiB1J,EAAqC,MAC5E,MAAMgc,EAAiBhc,EAAQgc,iBAAkB,EAC3CC,EAAQ3B,GAAiB5Q,EAAK1J,GAC9BqhB,EAASpF,EAAM1B,QAAQ1a,IAAI,CAACsJ,EAAKgU,KACnC,MAAMmE,EAAWthB,EAAQuhB,gBAAgBpY,EAAIjD,QAAQvJ,MACrD,GAAI2kB,EAAU,OAAOA,EACrB,IAAI3a,EAAMsV,EAAMX,QAAQ6B,GAAG3W,OAC3B,IAAK,IAAIgb,EAAI,EAAGA,EAAI5a,KAAKF,IAAIuV,EAAMb,KAAK5U,OAAQ,KAAMgb,GAAK,EAAG,CAC1D,MAAMC,EAAMxF,EAAMb,KAAKoG,GAAGrE,GAAG9S,UAAU7D,OACnCib,EAAM9a,IAAKA,EAAM8a,EACzB,CACA,OAAO7a,KAAKF,IAAIE,KAAKD,IAAIA,EAAM,EAAG,GAAI,MAEpCoa,EA/JiB5M,KACvB,MAAMuN,GAAWvN,GAAQ,UAAUvE,QAAQ,gBAAiB,KAAKe,QAAU,SAC3E,OAAO+Q,EAAQlb,OAAS,GAAKkb,EAAQjQ,MAAM,EAAG,IAAMiQ,GA6JlCC,CAAkB3hB,EAAQ+gB,WACtCrD,EAAsB,CACxB,CAAEvJ,KAAM,sBAAuB+J,KAAMrB,GAAW8D,KAChD,CAAExM,KAAM,cAAe+J,KAAMrB,GAAW+D,KACxC,CAAEzM,KAAM,oBAAqB+J,KAAMrB,GAAWmE,OAC9C,CAAE7M,KAAM,mBAAoB+J,KAAMrB,GAAWsE,KAC7C,CAAEhN,KAAM,kBAAmB+J,KAAMrB,GAAWiE,GAAiBC,KAC7D,CAAE5M,KAAM,6BAA8B+J,KAAMrB,GAAWgE,KACvD,CAAE1M,KAAM,gBAAiB+J,KAAMrB,GAAW6D,KAC1C,CAAEvM,KAAM,2BAA4B+J,KAAMrB,GAAW4C,GAAcxD,EAAOD,EAAgBqF,MAE9F,OAAO5D,GAASC,IAedkE,GAAcrmB,GAChBA,EAAKqU,QAAQ,KAAM,SAASA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,UCrapFgS,GAAcrmB,GAChBA,EAAKqU,QAAQ,KAAM,SAASA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,UAmF7EiS,GAAoBC,IAC7B,IAAIC,GAAO,EACX,MAAMC,EAASA,KACPD,IACJA,GAAO,EACPD,EAAOE,WAEX,IACIC,GAAuB,IAAKH,EAAQE,UACxC,CAAE,MAAOE,GACLC,QAAQD,MAAM,wBAAyBA,GACvCF,GACJ,GAGEC,GAAyBA,EAAGG,cAAapiB,UAASgiB,aACpD,GAAwB,oBAAbnL,SAEP,YADAmL,IAGJ,MAAMK,EAAcriB,EAAQqiB,cAAe,EACrCC,EAAatiB,EAAQsiB,aAAc,EACnCtG,EAAiBhc,EAAQgc,iBAAkB,EAC3CuG,EAAaviB,EAAQuiB,aAAc,EAEnCC,EAAQJ,EAAYK,WAAU,GAzGlBC,EAACC,EAAqBC,KACxC,MAAMC,EAAevc,MAAM6O,KAAKwN,EAAOG,iBAAiB,4BAClDC,EAAezc,MAAM6O,KAAKyN,EAAOE,iBAAiB,4BACxDD,EAAahb,QAAQ,CAAC/H,EAAIqd,KACtB,MAAM6F,EAAID,EAAa5F,GACvB,GAAK6F,GAAKA,EAAEC,UAAYnjB,EAAGmjB,QAE3B,GAAmB,UAAfnjB,EAAGmjB,QAAqB,CACxB,MAAMxmB,EAAMqD,EACNojB,EAAMF,EACK,aAAbvmB,EAAIkL,MAAoC,UAAblL,EAAIkL,MAC/Bub,EAAIC,QAAU1mB,EAAI0mB,QACd1mB,EAAI0mB,SAASD,EAAIzK,aAAa,UAAW,IAC7CyK,EAAIE,cAAgB3mB,EAAI2mB,gBAExBF,EAAI/lB,MAAQV,EAAIU,MAChB+lB,EAAIzK,aAAa,QAAShc,EAAIU,OAEtC,KAA0B,WAAf2C,EAAGmjB,QACTD,EAAwB7lB,MAAS2C,EAAyB3C,MACrC,aAAf2C,EAAGmjB,UACTD,EAA0B7lB,MAAS2C,EAA2B3C,MAC/D6lB,EAAEtK,YAAe5Y,EAA2B3C,SAIpD,MAAMkmB,EAAiB/c,MAAM6O,KAAKwN,EAAOG,iBAAiB,WACpDQ,EAAiBhd,MAAM6O,KAAKyN,EAAOE,iBAAiB,WAC1DO,EAAexb,QAAQ,CAACiP,EAAQqG,KAC5B,MAAM6F,EAAIM,EAAenG,GACzB,GAAK6F,EACL,IACI,MAAMO,EAAMP,EAAEQ,cAAcnnB,cAAc,OAC1CknB,EAAI9mB,IAAMqa,EAAO2M,YACjBF,EAAI5mB,MAAQma,EAAOna,MACnB4mB,EAAItnB,OAAS6a,EAAO7a,OACpBsnB,EAAInlB,MAAMslB,QAAUV,EAAE5kB,MAAMslB,QAC5BV,EAAEW,YAAYJ,EAClB,CAAE,MACE,KAmERb,CAAcN,EAAaI,GAC3BA,EAAMM,iBAAiB,yBAAyBjb,QAAS/H,GAAOA,EAAG8jB,UAC/DvB,GAAaG,EAAMM,iBAAiB,qBAAqBjb,QAAS/H,GAAOA,EAAG8jB,UAC5EtB,GAAYE,EAAMM,iBAAiB,oBAAoBjb,QAAS/H,GAAOA,EAAG8jB,UACzE5H,GAAgBwG,EAAMM,iBAAiB,qBAAqBjb,QAAS/H,GAAOA,EAAG8jB,UACpFpB,EAAMqB,UAAU/b,IAAI,wBAEpB0a,EAAMM,iBAAiB,QAAQjb,QAAS/H,GAAOA,EAAGgkB,gBAAgB,OAClEtB,EAAMpkB,MAAMnC,OAAS,OACrBumB,EAAMpkB,MAAM2lB,SAAW,IAEvB,MAAMzlB,EAAQ0B,EAAQ1B,OAAS,IACzB0lB,OAAEA,EAAMC,MAAEA,GAAU1B,EA3IP2B,KACnB,MAAMF,EAAmB,GACnBC,EAAkB,GAYxB,OAXA3d,MAAM6O,KAAK+O,EAAIC,aAAatc,QAASuc,IACjC,IACI,MAAMC,EAAQ/d,MAAM6O,KAAKiP,EAAME,UAC1BzkB,IAAK0kB,GAASA,EAAKb,SACnBzc,KAAK,MACNod,GAAOL,EAAO1T,KAAK+T,EAC3B,CAAE,MAEMD,EAAM7M,MAAM0M,EAAM3T,KAAK8T,EAAM7M,KACrC,IAEG,CAAEyM,SAAQC,UA6HsBO,CAAc3N,UAAY,CAAEmN,OAAQ,GAAIC,MAAO,IAEhFQ,EAAS5N,SAASxa,cAAc,UACtCooB,EAAOhM,aAAa,cAAe,QACnCgM,EAAOhM,aAAa,sBAAuB,QAC3CgM,EAAOrmB,MAAMslB,QAAU,2FACvB7M,SAASY,KAAKC,YAAY+M,GAE1B,IAAIC,GAAW,EACf,MAAMC,EAASA,KACPD,IACJA,GAAW,EACX3nB,OAAO6a,WAAW,KACV6M,EAAOG,YAAYH,EAAOG,WAAW/M,YAAY4M,IACtD,KACHzC,MAGE6C,EAAMJ,EAAOK,cACbZ,EAAMO,EAAOM,iBAAmBF,GAAKhO,SAC3C,IAAKgO,IAAQX,EAET,YADAS,IAIJT,EAAIc,OACJd,EAAIe,MACA,6DAA6DrD,GAAWtjB,GAASuY,SAASvY,OAAS,mBAC/F2lB,EAAMpkB,IAAK0X,GAAS,gCAAgCqK,GAAWrK,UAAatQ,KAAK,IACjF,+BAERid,EAAIgB,QAEJlB,EAAOnc,QAASsd,IACZ,MAAM/mB,EAAQ8lB,EAAI7nB,cAAc,SAChC+B,EAAMsa,YAAcyM,EACpBjB,EAAIvL,KAAKjB,YAAYtZ,KAEzB,MAAMgnB,EAAalB,EAAI7nB,cAAc,SAIrC,GAHA+oB,EAAW1M,YApMG,09CAoMwB1Y,EAAQqlB,WAAa,IAC3DnB,EAAIvL,KAAKjB,YAAY0N,GAEjB9mB,EAAO,CACP,MAAMgnB,EAAKpB,EAAI7nB,cAAc,MAC7BipB,EAAGC,UAAY,uBACfD,EAAG5M,YAAcpa,EACjB4lB,EAAIzM,KAAKC,YAAY4N,EACzB,CACApB,EAAIzM,KAAKC,YAAYwM,EAAIsB,UAAUhD,IAEvBiD,WACR,SA7HcC,EAACxB,EAAeyB,IAClC,IAAIC,QAAeC,IACf,MAAMC,EAASxf,MAAM6O,KAAK+O,EAAI4B,QAAQ/e,OAAQwc,IAASA,EAAIwC,UAC3D,GAAsB,IAAlBD,EAAOtf,OAEP,YADAqf,IAGJ,IAAIG,EAAYF,EAAOtf,OACnBub,GAAO,EACX,MAAM4C,EAASA,KACP5C,IACJA,GAAO,EACP8D,MAEEI,EAAQlpB,OAAO6a,WAAW+M,EAAQgB,GACxCG,EAAOje,QAAS0b,IACZ,MAAM2C,EAAYA,KACdF,GAAa,EACTA,GAAa,IACbjpB,OAAOopB,aAAaF,GACpBtB,MAGRpB,EAAI6C,iBAAiB,OAAQF,EAAW,CAAEG,MAAM,IAChD9C,EAAI6C,iBAAiB,QAASF,EAAW,CAAEG,MAAM,QAsG3CX,CAAcxB,EAAK,KACrBlkB,EAAQsmB,qBAAqBtmB,EAAQsmB,cAAcpC,GACvDW,EAAI0B,aAAe5B,EACnBE,EAAI2B,QACJ3B,EAAI4B,QAEJ1pB,OAAO6a,WAAW+M,EAAQ,IAC9B,CAAE,MACEA,GACJ,GAEC+B,IC1LHC,GAAezpB,GAAckJ,EAAMlJ,GAAO,GAAKA,aAAe8K,KAAOsB,OAAOpM,EAAIiL,WAAamB,OAAOpM,GAE7F0pB,GAAiBA,CAC1BlJ,EACAmJ,EACAC,EACApd,EACAqd,EAAa,aAEb,MAAMC,EAAQA,CAACC,EAAsBC,EAAeC,EAA+BC,KAC/E,MAAMlhB,EAAQ2gB,EAAeK,GACvB/d,EAAM2d,EAAe9L,IAAI9U,GAC/B,IAAKiD,EAAK,MAAO,GACjB,MAAMke,EAAU,IAAIxM,IACpBoM,EAAMpf,QAASgW,IACX,MAAM3gB,ENkIcoqB,EAAChgB,EAA2B6B,EAAoBO,IACxEP,EAAIoe,oBAA4Bpe,EAAIoe,oBAAoBjgB,EAAI6B,EAAIjD,OAAQoB,EAAK6B,EAAKO,GAC/ED,GAAanC,EAAK6B,EAAKO,GMpIV4d,CAAiBzJ,EAAMvW,IAAK6B,EAAKO,GACvC8d,EAASb,GAAYzpB,GAC3B,IAAIuqB,EAAOJ,EAAQrM,IAAIwM,GACvB,IAAKC,EAAM,CACP,MAAMpe,EAAQe,GAAuBF,GAAkBhN,EAAK2gB,EAAMvW,IAAK6B,EAAKO,EAAKmU,EAAMrW,MAAQuf,EAE/FU,EAAO,CACHjgB,GAFO,sBAAqB4f,IAAOlhB,KAASshB,IAG5CN,QACAQ,OAAQP,EACRQ,cAAezhB,EACf0hB,YAAa1qB,EACb2qB,cAAexe,EACfye,YAAa,GACbC,OAAQ,GACRC,YAAa,IAEjBX,EAAQ3a,IAAI8a,EAAQC,EACxB,CACAA,EAAKM,OAAOzX,KAAKuN,KAErB,MAAMoK,EAA4B,GAgBlC,OAfAZ,EAAQxf,QAAS4f,IACTP,EAAQL,EAAergB,OAAS,GAChCihB,EAAKK,YAAcd,EACfS,EAAKM,OACLb,EAAQ,EACRO,EAAKjgB,GACL,GAAG4f,IAAOlhB,KAASygB,GAAYc,EAAKG,iBAExCH,EAAKO,YAAcP,EAAKM,OACxBN,EAAKM,OAAS,IAEdN,EAAKO,YAAcP,EAAKM,OAE5BE,EAAM3X,KAAKmX,KAERQ,GAEX,OAAOjB,EAAMtJ,EAAS,EAAG,KAAM,KAmCtBwK,GAAqDC,IAC9D,MAAMjY,EAAqB,GAE3B,OADAiY,EAAMtgB,QAASugB,GAASA,EAAKJ,YAAYngB,QAASU,GAAM2H,EAAII,KAAK/H,KAC1D2H,GAwDEmY,GAAgBA,CACzBjN,EACAkN,EACAxB,EACAyB,EACA7e,KAEA,MAAM8e,EAAqD,CAAA,EAS3D,OARAhZ,OAAOC,KAAK6Y,GAAkBzgB,QAAS3B,IACnC,MAAMuiB,EAASH,EAAiBpiB,GAC1BwiB,EAAKH,EAAUE,GACftf,EAAM2d,EAAe9L,IAAI9U,GAC/B,IAAKwiB,IAAOvf,IAA0B,IAAnBA,EAAIwF,WAAsB,OAC7C,MAAMkC,EAASuK,EAAKvb,IAAKyH,GAAQmC,GAAanC,EAAK6B,EAAKO,IACxD8e,EAAOtiB,GAAS,CAAE/I,MAAOurB,EAAGzX,MAAM,CAAEJ,SAAQ3K,UAAUwiB,GAAID,KAEvDD,GCvMLG,GAAaA,CAACvB,EAAuBtO,KACvC,MAAMpW,EAAOtG,EAAMoG,WAA4C,EAAGb,OAAO,GAAI4jB,YAAWnnB,WAAUwqB,GAAQrnB,IACtGnF,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLsnB,QAAQ,YACRlsB,MAAOgF,EACP1F,OAAQ0F,EACRzF,KAAK,eACL4sB,UAAU,QAAO,cACL,OACZvD,UAAW,CAAC,gBAAiBA,GAAWxe,OAAOC,SAASC,KAAK,KAC7D7I,MAAOA,KACHwqB,GAEHxB,IAIT,OADA1kB,EAAKoW,YAAcA,EACZpW,GAGEqmB,GAAiBJ,GAC1BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,sEACR,kBAESygB,GAAiBL,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,mDAAqD,kBACzF0gB,GAAaN,GACtBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,+MACR,cAES2gB,GAAYP,GACrBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,0GACR,aAES4gB,GAAeR,GACxBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,uHACR,gBAES6gB,GAAkBT,GAC3BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,gEACR,mBAES8gB,GAAoBV,GAC7BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,kEACR,qBAES+gB,GAAeX,GACxBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,sJACR,gBAESghB,GAAYZ,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,sDAAwD,aACvFihB,GAAiBb,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,iDAAmD,kBACvFkhB,GAAmBd,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,mDAAqD,oBAC3FmhB,GAAkBf,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,kDAAoD,mBACzFohB,GAAgBhB,GACzBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,+DACR,iBAESqhB,GAAejB,GACxBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,+DACR,gBAESshB,GAAclB,GACvBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,0IACR,eAESuhB,GAAanB,GACtBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,kFACR,cAESwhB,GAAUpB,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,wCAA0C,WACvEyhB,GAAmBrB,GAC5BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,sDACR,oBAES0hB,GAAoBtB,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,0CAA4C,qBACnF2hB,GAAmBvB,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,8BAAgC,oBACtE4hB,GAAoBxB,GAC7BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,wSACR,qBAES6hB,GAAYzB,GACrBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,sJACR,aAES8hB,GAAiB1B,GAC1BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,mIACR,kBAES+hB,GAAkB3B,GAC3BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,mIACR,mBAESgiB,GAAoB5B,GAC7BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,8fACR,qBAESiiB,GAAgB7B,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,+CAAiD,iBACpFkiB,GAAiB9B,GAC1BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,mKACR,kBAESmiB,GAAe/B,GACxBvsB,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAAA,OAAA,CACIkM,EAAE,2NACF9H,QAAQ,QAEZrE,EAAAC,cAAA,OAAA,CAAMkM,EAAE,gBAAgB9H,QAAQ,SAEpC,+hBCrGSmqB,GAASxuB,EAAMoG,WACxB,EACMrD,UAAU,OAAQwC,OAAO,SAAUiD,YAAWC,UAASgmB,SAAQtF,YAAW5gB,WAAUgD,OAAO,YAAaihB,GAC1GrnB,IAEAnF,EAAAC,cAAA,SAAA,CACIkF,IAAKA,EACLoG,KAAMA,EACN4d,UAAW1e,EACP,eACY,YAAZ1H,GAAyB,wBACb,cAAZA,GAA2B,0BAClB,UAATwC,GAAoB,sBACpBkpB,GAAU,uBACVtF,MAEAqD,GAEHhkB,EACAD,EACAE,IAIb+lB,GAAO9R,YAAc,sBASRgS,GAAa1uB,EAAMoG,WAC5B,EAAGb,OAAO,SAAUkpB,SAAQxhB,QAAOkc,YAAW5gB,WAAUgD,OAAO,YAAaihB,GAAQrnB,IAChFnF,EAAAC,cAAA,SAAA,CACIkF,IAAKA,EACLoG,KAAMA,EACNrJ,MAAO+K,EAAK,aACAA,EACZkc,UAAW1e,EACP,kCACS,UAATlF,GAAoB,sBACpBkpB,GAAU,uBACVtF,MAEAqD,GAEHjkB,IAIbmmB,GAAWhS,YAAc,oBAYlB,MAAM9Z,GAAQA,EAAG8V,QAAQ,EAAG3V,UAAU,MAAOwF,cAChDvI,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,kBACX5gB,EACAmQ,EAAQ,IACQ,QAAZ3V,EACG/C,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,uBAEhBnpB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,wBAAwBzQ,EAAQ,GAAK,MAAQA,KAahEiW,GAAY3uB,EAAMoG,WAC3B,EAAGb,OAAO,SAAU4jB,eAAcqD,GAAQrnB,IACtCnF,EAAAC,cAAA,QAAA,CACIkF,IAAKA,EACLgkB,UAAW1e,EAAG,iBAA2B,UAATlF,GAAoB,wBAAyB4jB,MACzEqD,KAIhBmC,GAAUjS,YAAc,yBAMXkS,GAAS5uB,EAAMoG,WAA2C,EAAGb,OAAO,SAAU4jB,eAAcqD,GAAQrnB,IAC7GnF,EAAAC,cAAA,SAAA,CAAQkF,IAAKA,EAAKgkB,UAAW1e,EAAG,kBAA4B,UAATlF,GAAoB,yBAA0B4jB,MAAgBqD,KAErHoC,GAAOlS,YAAc,gBASd,MAAMmS,GAAQA,EAAG5hB,QAAO1E,WAAU4gB,YAAW2F,aAChD9uB,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,EAAG,iBAAkB0e,IAChClc,GACGjN,EAAAC,cAAA,QAAA,CAAOkpB,UAAU,uBAAuB2F,QAASA,GAC5C7hB,GAGR1E,GASIwmB,GAAW/uB,EAAMoG,WAC1B,EAAG4gB,iBAAgB,EAAO/Z,QAAOkc,eAAcqD,GAAQwC,KACnD,MAAMC,EAAWjvB,EAAMgd,OAAgC,MACjDkS,EAASlvB,EAAM6d,YAChBwN,IACG4D,EAAShS,QAAUoO,EACS,mBAAjB2D,EAA6BA,EAAa3D,GAC5C2D,IAAeA,EAAiE/R,QAAUoO,IAEvG,CAAC2D,IAKL,OAHAhvB,EAAMic,UAAU,KACRgT,EAAShS,UAASgS,EAAShS,QAAQ+J,cAAgBA,IACxD,CAACA,IAEAhnB,EAAAC,cAAA,QAAA,CACIkF,IAAK+pB,EACL3jB,KAAK,WACLrJ,MAAO+K,EAAK,aACAA,EACZkc,UAAW1e,EAAG,oBAAqB0e,MAC/BqD,MAKpBuC,GAASrS,YAAc,kBAMhB,MAAMyS,GAAUA,EAAGhG,eACtBnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,EAAG,mBAAoB0e,GAAYiG,KAAK,cAAa,aAAY,qBAyBrEC,IAAQzG,KACpBA,EAAI0G,SACJA,EAAQC,QACRA,EAAOhnB,SACPA,EAAQinB,UACRA,EAAY,eAAcnwB,UAC1BA,EAAY,QAAO8pB,UACnBA,EAASnnB,MACTA,EAAKof,OACLA,EAAS,EAACgO,KACVA,EAAO,SAAQK,UACfA,GAAY,EAAKC,qBACjBA,IAEA,MAAMvqB,EAAMnF,EAAMgd,OAA8B,OACzCpX,EAAU+pB,GAAe3vB,EAAMyd,SAAwD,CAC1FmS,IAAK,EACLC,KAAM,EACNC,OAAO,IAGLC,EAAS/vB,EAAM6d,YAAY,KAC7B,MAAMna,EAAKyB,EAAI8X,QACf,IAAKvZ,EAAI,OACT,MAAMssB,EAAKrvB,OAAOsvB,WACZC,EAAKvvB,OAAOwvB,YACZ9L,EAAI3gB,EAAG0sB,YACPrQ,EAAIrc,EAAG2sB,aACb,IAAIT,EACAC,EACJ,GAAIP,GAAYA,EAASgB,YAAa,CAClC,MAAM1f,EAAI0e,EAASiB,wBACD,gBAAdf,GACAI,EAAMhf,EAAEgf,IACRC,EAAOjf,EAAE4f,MAAQpP,EACbyO,EAAOxL,EAAI2L,EAAK,IAAGH,EAAOjf,EAAEif,KAAOzO,EAASiD,KAEhDuL,EAAMhf,EAAE6f,OAASrP,EACbwO,EAAM7P,EAAImQ,EAAK,GAAKtf,EAAEgf,IAAMxO,EAASrB,GAAK,IAAG6P,EAAMhf,EAAEgf,IAAMxO,EAASrB,GACxE8P,EACkB,eAAdL,EACM5e,EAAE4f,MAAQnM,EACI,WAAdmL,EACE5e,EAAEif,KAAOjf,EAAErQ,MAAQ,EAAI8jB,EAAI,EAC3BzT,EAAEif,KAEtB,MACID,EAAMM,EAAK,EAAInQ,EAAI,EACnB8P,EAAOG,EAAK,EAAI3L,EAAI,EAExBuL,EAAMvlB,EAAMulB,EAAK,EAAGplB,KAAKD,IAAI,EAAG2lB,EAAKnQ,EAAI,IACzC8P,EAAOxlB,EAAMwlB,EAAM,EAAGrlB,KAAKD,IAAI,EAAGylB,EAAK3L,EAAI,IAC3CsL,EAAae,GAAUA,EAAKZ,OAASY,EAAKd,MAAQA,GAAOc,EAAKb,OAASA,EAAOa,EAAO,CAAEd,MAAKC,OAAMC,OAAO,KAC1G,CAACR,EAAUE,EAAWpO,IAwDzB,GAtDAphB,EAAMgc,gBAAgB,KAClB,IAAK4M,EAED,YADA+G,EAAae,GAAUA,EAAKZ,MAAQ,IAAKY,EAAMZ,OAAO,GAAUY,GAGpEX,IACApvB,OAAOqpB,iBAAiB,SAAU+F,GAClCpvB,OAAOqpB,iBAAiB,SAAU+F,GAAQ,GAC1C,IAAIY,EAAkC,KAKtC,MAJ8B,oBAAnBC,gBAAkCzrB,EAAI8X,UAC7C0T,EAAW,IAAIC,eAAe,IAAMb,KACpCY,EAASE,QAAQ1rB,EAAI8X,UAElB,KACHtc,OAAOmwB,oBAAoB,SAAUf,GACrCpvB,OAAOmwB,oBAAoB,SAAUf,GAAQ,GAC7CY,GAAUI,eAEf,CAACnI,EAAMmH,IAEV/vB,EAAMic,UAAU,KACZ,IAAK2M,EAAM,OACX,MAAMoI,EAAqBC,IACvB,MAAMzK,EAASyK,EAAMzK,OAChBA,IACDrhB,EAAI8X,SAASiU,SAAS1K,IACtB8I,GAAU4B,SAAS1K,IACnBkJ,GAAsByB,KAAM/L,GAAMA,EAAEnI,SAASiU,SAAS1K,KAErDA,EAAuB4K,UAAU,sBACtC7B,EAAQ,cAEN8B,EAAiBJ,IACD,WAAdA,EAAMnwB,KAAkByuB,EAAQ,WAKxC,OAHA9U,SAASuP,iBAAiB,YAAagH,GAAmB,GAC1DvW,SAASuP,iBAAiB,aAAcgH,GAAmB,GAC3DvW,SAASuP,iBAAiB,UAAWqH,GAC9B,KACH5W,SAASqW,oBAAoB,YAAaE,GAAmB,GAC7DvW,SAASqW,oBAAoB,aAAcE,GAAmB,GAC9DvW,SAASqW,oBAAoB,UAAWO,KAE7C,CAACzI,EAAM2G,EAASD,EAAUI,IAE7B1vB,EAAMic,UAAU,KACZ,GAAI2M,GAAQ6G,GAAatqB,EAAI8X,QAAS,EAChB9X,EAAI8X,QAAQqU,cAC1B,qEAEUnsB,EAAI8X,SAASmN,OAC/B,GACD,CAACxB,EAAM6G,KAEL7G,GAA4B,oBAAbnO,SAA0B,OAAO,KAErD,MAAM8W,EAAQN,GAAgCA,EAAMO,kBAEpD,OAAOC,eACHzxB,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLiqB,KAAMA,EACNsC,UAAU,EACVvI,UAAW1e,EAAG,mBAAoB0e,GAAU,iBAC5B9pB,EAChB2C,MAAO,CACH4tB,IAAKhqB,EAASgqB,IACdC,KAAMjqB,EAASiqB,KACf8B,WAAY/rB,EAASkqB,MAAQ,UAAY,YACtC9tB,GAEP4vB,QAASL,EACTM,cAAeN,EACfO,YAAaP,EACbQ,UAAYd,IACR,GAAkB,WAAdA,EAAMnwB,IAGN,OAFAmwB,EAAMO,uBACNjC,EAAQ,UAGZ0B,EAAMO,oBAGTjpB,GAELkS,SAASY,KAEjB,CAUO,MAAM2W,GAAOA,EAAGzpB,WAAU4gB,YAAW4I,eAAcvF,MACtD,MAAMrnB,EAAMnF,EAAMgd,OAAgC,MAyBlD,OALAhd,EAAMic,UAAU,KACZ,MAAMgW,EAAQ9sB,EAAI8X,SAASqU,cAA2B,iDACtDW,GAAO7H,SACR,IAGCpqB,EAAAC,cAAA,KAAA,CAAIkF,IAAKA,EAAKiqB,KAAK,OAAOjG,UAAW1e,EAAG,gBAAiB0e,GAAY4I,UAxBlDd,IAEnB,GADAc,IAAYd,GACM,cAAdA,EAAMnwB,KAAqC,YAAdmwB,EAAMnwB,KAAmC,SAAdmwB,EAAMnwB,KAAgC,QAAdmwB,EAAMnwB,IAAe,OACzG,MAAM+pB,EAAQ3gB,MAAM6O,KAChB5T,EAAI8X,SAASyJ,iBAA8B,kDAAoD,IAEnG,GAAqB,IAAjBmE,EAAMzgB,OAAc,OACxB6mB,EAAMiB,iBACN,MAAMC,EAAetH,EAAM3a,QAAQuK,SAAS2X,eAC5C,IAAItU,EAAO,EACoBA,EAAb,cAAdmT,EAAMnwB,IAA4BqxB,EAAe,EAAI,GAAKA,EAAe,GAAKtH,EAAMzgB,OACjE,YAAd6mB,EAAMnwB,IACJqxB,EAAe,EAAItH,EAAMzgB,OAAS,GAAK+nB,EAAe,EAAItH,EAAMzgB,QAAUygB,EAAMzgB,OACpE,SAAd6mB,EAAMnwB,IAAuB,EAC1B+pB,EAAMzgB,OAAS,EAC3BygB,EAAM/M,GAAMsM,YASuFoC,GAC9FjkB,IAYA8pB,GAAWryB,EAAMoG,WAC1B,EAAGC,OAAMisB,WAAUC,WAAUpJ,YAAW5gB,WAAUqpB,UAASY,cAAahG,GAAQrnB,IAC5EnF,EAAAC,cAAA,KAAA,CAAImvB,KAAK,QACLpvB,EAAAC,cAAA,SAAA,CACIkF,IAAKA,EACLoG,KAAK,SACL6jB,KAAK,WAAU,gBACAmD,QAAY/kB,EAC3B+kB,SAAUA,EACVb,UAAU,EACVvI,UAAW1e,EACP,qBACA8nB,GAAY,+BACZD,GAAY,+BACZnJ,GAEJyI,QAAUX,IACFsB,IACJX,IAAUX,GACVuB,WAEAhG,GAEHnmB,EACDrG,EAAAC,cAAA,OAAA,KAAOsI,MAKvB8pB,GAAS3V,YAAc,kBAEhB,MAAM+V,GAAcA,IAAMzyB,EAAAC,cAAA,KAAA,CAAImvB,KAAK,YAAYjG,UAAU,0BAQnDuJ,GAAcA,EAAGnqB,cAC1BvI,sBAAIovB,KAAK,eAAejG,UAAU,yBAC7B5gB,YCvZOoqB,KACZ,MAAMrlB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,GAAejW,KAC7BkW,EAASnwB,EAAMowB,gBAAgBlK,MAAmD,YAA3ClmB,EAAMowB,gBAAgBC,iBACnE,OACI/yB,gBAAC0uB,GAAU,CACPzhB,MAAO2lB,EAAWjd,eAClB8Y,OAAQoE,kBACM,SAAQ,gBACPA,EACfjB,QAAUX,GAAW4B,EAASvlB,EAAI0lB,kBAAoB1lB,EAAI2lB,gBAAgB,UAAWhC,EAAMiC,gBAE3FlzB,EAAAC,cAAC0sB,GAAc,MAG3B,UAEgBwG,KACZ,MAAM7lB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,GAAejW,KAC7BkW,EAASnwB,EAAMowB,gBAAgBlK,MAAmD,YAA3ClmB,EAAMowB,gBAAgBC,iBACnE,OACI/yB,gBAAC0uB,GAAU,CACPzhB,MAAO2lB,EAAWhd,eAClB6Y,OAAQoE,kBACM,SAAQ,gBACPA,EACfjB,QAAUX,GAAW4B,EAASvlB,EAAI0lB,kBAAoB1lB,EAAI2lB,gBAAgB,UAAWhC,EAAMiC,gBAE3FlzB,EAAAC,cAAC2C,GAAK,CAAC8V,MAAOhW,EAAMI,YAAaC,QAAQ,OACrC/C,EAAAC,cAAC2sB,GAAc,OAI/B,UAEgBwG,KACZ,MAAM9lB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,EAAUvzB,UAAEA,GAAcsd,MACvCzB,EAAQmY,GAAarzB,EAAMyd,SAA6B,MACzD7Z,EAAU,CACZ,CAAE7C,MAAO,UAAWkM,MAAO2lB,EAAWxc,eAAgB/P,KAAMrG,EAAAC,cAAC2tB,UAC7D,CAAE7sB,MAAO,WAAYkM,MAAO2lB,EAAWvc,gBAAiBhQ,KAAMrG,EAAAC,cAAC4tB,UAC/D,CAAE9sB,MAAO,cAAekM,MAAO2lB,EAAWtc,mBAAoBjQ,KAAMrG,EAAAC,cAAC6tB,WAEnE7Q,EAAUrZ,EAAQgK,KAAM0lB,GAAMA,EAAEvyB,QAAU2B,EAAM6wB,UAAY3vB,EAAQ,GAC1E,OACI5D,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACyuB,IACGzhB,MAAO2lB,EAAW9c,eAClB2Y,OAAQ7jB,QAAQsQ,mBACF,OACd0W,QAAUX,GAAUoC,EAAW3C,GAAUA,EAAO,KAAOO,EAAMiC,gBAE5DjW,EAAQ5W,MAEbrG,EAAAC,cAACovB,GAAO,CACJzG,KAAMhe,QAAQsQ,GACdoU,SAAUpU,EACVqU,QAASA,IAAM8D,EAAU,MACzBh0B,UAAWA,EACX+vB,KAAK,QAELpvB,EAAAC,cAAC+xB,GAAI,KACApuB,EAAQH,IAAKoJ,GACV7M,EAAAC,cAACoyB,GAAQ,CACLvxB,IAAK+L,EAAO9L,MACZsF,KAAMwG,EAAOxG,KACbisB,SAAUzlB,EAAO9L,QAAU2B,EAAM6wB,QACjC3B,QAASA,IAAMtkB,EAAIkmB,WAAW3mB,EAAO9L,OACrCyxB,SAAUA,IAAMa,EAAU,OAEzBxmB,EAAOI,UAOpC,CAYO,MAAMwmB,GAAwBpB,GAc/B,SAAUqB,IAAkBvwB,WAC9BA,EAAa,CAAEC,YAAY,GAAMC,aACjCA,EAAe,CAAED,YAAY,GAAME,aACnCA,EAAYxB,cACZA,GAAgB,EAAI6xB,gBACpBA,GAAkB,EAAIC,gBACtBA,GAAkB,EAAI/xB,eACtBA,IAEA,MAAMyL,IAAEA,EAAGslB,WAAEA,EAAUvzB,UAAEA,EAASw0B,UAAEA,GAAclX,MAC3CzB,EAAQmY,GAAarzB,EAAMyd,SAA6B,MACzD+U,EAAWA,IAAMa,EAAU,MAE3BS,EAAc9zB,EAAM+zB,SAAStwB,IAAI5B,EAAiBmyB,GACpDh0B,EAAMi0B,eAAeD,GAASh0B,EAAMk0B,aAAaF,EAAkC,CAAExB,aAAcwB,GAGjGG,EAAkD,CACpDjyB,MAAmC,iBAArB2xB,EAAUO,OAAsBP,EAAUO,YAAS5mB,KAC9DlK,GAGP,OACItD,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACyuB,IACGzhB,MAAO2lB,EAAW/c,cAClB4Y,OAAQ7jB,QAAQsQ,GAAO,gBACT,OACd0W,QAAUX,GAAUoC,EAAW3C,GAAUA,EAAO,KAAOO,EAAMiC,gBAE7DlzB,EAAAC,cAAC8sB,UAEL/sB,EAAAC,cAACovB,IAAQzG,KAAMhe,QAAQsQ,GAASoU,SAAUpU,EAAQqU,QAASiD,EAAUnzB,UAAWA,EAAW+vB,KAAK,QAC5FpvB,EAAAC,cAAC+xB,GAAI,KACA8B,EACAhyB,GACG9B,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAACiuB,GAAe,MACtB0D,QAASA,IAAMtkB,EAAI+mB,gBAAgBlxB,GACnCqvB,SAAUA,GAETI,EAAW3c,kBAGnB0d,GACG3zB,EAAAC,cAACoyB,IACGhsB,KAAMrG,EAAAC,cAACguB,GAAc,MACrB2D,QAASA,KACAtkB,EAAIgnB,kBAAkBjxB,IAE/BmvB,SAAUA,GAETI,EAAW1c,oBAGnB0d,GACG5zB,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAAC+tB,GAAS,MAChB4D,QAASA,IAAMtkB,EAAIinB,kBAAkBJ,GACrC3B,SAAUA,GAETI,EAAWzc,sBAOxC,CAaM,SAAUqe,IAAmBlvB,YAAEA,EAAWmvB,WAAEA,EAAUC,eAAEA,GAAiB,IAC3E,MAAMpnB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,EAAUiB,UAAEA,GAAclX,KACxCgY,GAAiBjyB,EAAMkyB,mBAAqB,IAAI/pB,KAAK,MACpD1L,EAAM01B,GAAW70B,EAAMyd,SAASkX,IAChCrwB,EAAUwwB,GAAe90B,EAAMyd,SAASiX,GAAoC,KAAlBC,GAC3DtvB,EAAWrF,EAAMgd,OAAgC,MACjD6M,EAAQ7pB,EAAMgd,OAAsB,MACpC+X,EAAQN,GAAcZ,EAAUmB,sBAGhCC,EAAej1B,EAAMgd,OAAO2X,GAClC30B,EAAMic,UAAU,KACR0Y,IAAkBM,EAAahY,UAC/BgY,EAAahY,QAAU0X,EACvBE,EAAQF,GACc,KAAlBA,GAAsBG,GAAY,KAE3C,CAACH,IAEJ30B,EAAMic,UACF,IAAM,KACoB,OAAlB4N,EAAM5M,SAAkBtc,OAAOopB,aAAaF,EAAM5M,UAE1D,IAGJ,MAAMiY,EAAUn0B,IACZ,MAAM0T,EAAS1T,EAAMsT,MAAM,OAAO1J,OAAQmG,GAAY,KAANA,GAChDmkB,EAAahY,QAAUxI,EAAO5J,KAAK,KACnCyC,EAAI6nB,qBAAqB1gB,IASvB2gB,EAAQA,KACY,OAAlBvL,EAAM5M,SAAkBtc,OAAOopB,aAAaF,EAAM5M,SACtD4X,EAAQ,IACRK,EAAO,IACP7vB,EAAS4X,SAASmN,SAQhBiL,EAAaX,GAAkBpwB,EAErC,OACItE,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,EAAG,wBAAyB4qB,GAAc,oCACtDr1B,EAAAC,cAACyuB,GAAU,CACPvF,UAAU,gCACVlc,MAAO2lB,EAAW5c,wBAAuB,gBAC1Bqf,EACf3D,SAAU2D,GAAa,EAAK,EAC5BzD,QAdG0D,KACXR,GAAY,GACZn0B,OAAO6a,WAAW,IAAMnW,EAAS4X,SAASmN,QAAS,KAc3CpqB,EAAAC,cAAC4sB,UAEL7sB,EAAAC,cAAA,MAAA,CACIkpB,UAAW1e,EACP,uDACAtL,GAAQ,sCAGZa,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,4BACZnpB,EAAAC,cAAC4sB,GAAU,CAACtnB,KAAM,MAEtBvF,EAAAC,cAAC0uB,GAAS,CACNxpB,IAAKE,EACLE,KAAK,QACLgG,KAAK,SACLxK,MAAO5B,EACPuyB,SAAU2D,EAAa,GAAI,EAC3B/vB,YAAaA,GAAestB,EAAW7c,8BAA6B,aACxD6c,EAAW5c,wBACvBqH,SAAW4T,IAAUsE,OAhDfx0B,EAgD4BkwB,EAAMzK,OAAOzlB,MA/C3D8zB,EAAQ9zB,GACc,OAAlB8oB,EAAM5M,SAAkBtc,OAAOopB,aAAaF,EAAM5M,cACtD4M,EAAM5M,QAAUtc,OAAO6a,WAAW,IAAM0Z,EAAOn0B,GAAQg0B,IAHrCh0B,OAiDNy0B,OAAQA,KACCd,GAAkC,KAAhBv1B,EAAKoV,QAAeugB,GAAY,IAE3D/C,UAAYd,IACU,WAAdA,EAAMnwB,MACNmwB,EAAMO,kBACFryB,EAAMi2B,IACAV,IACNI,GAAY,GACZzvB,EAAS4X,SAASwY,SAGR,UAAdxE,EAAMnwB,MACgB,OAAlB+oB,EAAM5M,SAAkBtc,OAAOopB,aAAaF,EAAM5M,SACtDiY,EAAO/1B,OAIlBA,GACGa,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,0DACZnpB,EAAAC,cAACyuB,GAAU,CAACnpB,KAAK,QAAQ0H,MAAO2lB,EAAWvY,YAAauX,QAASwD,EAAO1D,UAAU,GAC9E1xB,EAAAC,cAAC6sB,YAO7B,CAMM,SAAUxrB,IAAeC,kBAC3BA,GAAoB,EAAIC,iBACxBA,GAAmB,EAAIC,iBACvBA,GAAmB,EAAIC,gBACvBA,GAAkB,EAAIg0B,oBACtBA,GAAsB,EAAK5zB,cAC3BA,GAAgB,EAAI6xB,gBACpBA,GAAkB,EAAIC,gBACtBA,GAAkB,EAAIzwB,WACtBA,EAAUE,aACVA,EAAYC,aACZA,EAAY3B,mBACZA,EAAkBC,gBAClBA,EAAeC,eACfA,EAAc8zB,uBACdA,EAAsBX,sBACtBA,IAEA,MAAMnB,UAAEA,GAAclX,KAChBiZ,EAAcr0B,IAAsBsyB,EAAUgC,sBAC9CC,EAAct0B,IAAqBqyB,EAAUkC,oBAC7CC,EAAcN,IAAwB7B,EAAUoC,uBAEtD,OACIj2B,uBAAKmpB,UAAU,mBAAmBiG,KAAK,WACnCpvB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,0BACVyM,GAAe51B,EAAAC,cAAC0yB,GAAoB,MACpCmD,GAAe91B,EAAAC,cAACkzB,GAAoB,MACpC6C,GAAeh2B,EAAAC,cAACmzB,GAAsB,MACtC3xB,GACGzB,EAAAC,cAACyzB,IACGvwB,WAAYA,EACZE,aAAcA,EACdC,aAAcA,EACdxB,cAAeA,EACf6xB,gBAAiBA,EACjBC,gBAAiBA,EACjB/xB,eAAgBA,KAI3BD,GAAmB5B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,2BAA2BvnB,GAC9D5B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,0BACVxnB,EACAD,GACG1B,EAAAC,cAACu0B,GAAkB,CAAClvB,YAAaqwB,EAAwBlB,WAAYO,KAKzF,UCnXgBkB,KACZ,MAAM5oB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,EAAUiB,UAAEA,GAAclX,MACxCwZ,KAAEA,EAAIC,SAAEA,GAAa1zB,EAAM2zB,gBAC3B3d,EAAQhW,EAAM4zB,SACdC,EAAY7zB,EAAM6zB,UAClBxd,EAAiB,IAAVL,EAAc,EAAIyd,EAAOC,EAAW,EAC3Cpd,EAAKxO,KAAKF,IAAIoO,GAAQyd,EAAO,GAAKC,GAClCxyB,GAC8C,IAAhDiwB,EAAU2C,gBAAgBtmB,QAAQkmB,GAC5BvC,EAAU2C,gBAAgB9T,OAAO,CAAC0T,IAAW9gB,KAAK,CAAC1E,EAAGC,IAAMD,EAAIC,GAChEgjB,EAAU2C,gBAEpB,OACIx2B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,sBAAsBiG,KAAK,aAAY,aAAY,cAC9DpvB,EAAAC,cAAA,OAAA,KAAO2yB,EAAW/Z,6BAClB7Y,EAAAC,cAAC2uB,GAAM,CACHzF,UAAU,6BACVpoB,MAAOq1B,EAAQ,aACHxD,EAAW/Z,4BACvBwE,SAAW4T,GAAU3jB,EAAImpB,YAAY5qB,OAAOolB,EAAMzK,OAAOzlB,SAExD6C,EAAQH,IAAKoJ,GACV7M,EAAAC,cAAA,SAAA,CAAQa,IAAK+L,EAAQ9L,MAAO8L,GACvBA,KAIb7M,EAAAC,cAAA,OAAA,KAAO2yB,EAAW9Z,8BAA8BC,EAAMC,EAAIN,IAC1D1Y,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,+BACXnpB,EAAAC,cAACyuB,GAAU,CAACzhB,MAAO2lB,EAAW3Z,0BAA2BsZ,SAAU4D,GAAQ,EAAGvE,QAASA,IAAMtkB,EAAIopB,QAAQ,IACrG12B,EAAAC,cAACstB,UAELvtB,EAAAC,cAACyuB,GAAU,CACPzhB,MAAO2lB,EAAW1Z,6BAClBqZ,SAAU4D,GAAQ,EAClBvE,QAASA,IAAMtkB,EAAIopB,QAAQP,EAAO,IAElCn2B,EAAAC,cAACqtB,UAELttB,EAAAC,cAACyuB,GAAU,CACPzhB,MAAO2lB,EAAWzZ,yBAClBoZ,SAAU4D,GAAQI,EAAY,EAC9B3E,QAASA,IAAMtkB,EAAIopB,QAAQP,EAAO,IAElCn2B,EAAAC,cAACotB,UAELrtB,EAAAC,cAACyuB,GAAU,CACPzhB,MAAO2lB,EAAWxZ,yBAClBmZ,SAAU4D,GAAQI,EAAY,EAC9B3E,QAASA,IAAMtkB,EAAIopB,QAAQlsB,KAAKD,IAAIgsB,EAAY,EAAG,KAEnDv2B,EAAAC,cAACutB,GAAY,QAKjC,UAEgBmJ,KACZ,MAAMj0B,MAAEA,EAAKkwB,WAAEA,EAAUiB,UAAEA,GAAclX,KACnCia,EAAgBl0B,EAAMm0B,kBAAkBrrB,IAAIjG,KAC5CuxB,EAAeF,EAAgB,IAAM/C,EAAUkD,2BAC/CC,EAAiBnD,EAAUoD,aAAepD,EAAUqD,qBACpDC,GAAgBH,IAAmBnD,EAAUuD,mBAEnD,OACIp3B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBACXnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,wBACV2N,GAAgB92B,EAAAC,cAAA,OAAA,KAAO2yB,EAAWna,kBAAkBme,KAExDO,GACGn3B,EAAAC,cAAA,OAAA,KACK2yB,EAAWha,oBAAkBlW,EAAM4zB,SAAS3d,kBAGpDqe,GAAkBh3B,EAAAC,cAACi2B,GAAiB,MAGjD,UC9EgBmB,KACZ,MAAM/pB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,EAAUzU,QAAEA,EAAOmZ,eAAEA,GAAmB3a,KACtD4a,EAAgBv3B,EAAMw3B,QAAQ,IAAM,IAAInuB,IAAIiuB,EAAe7zB,IAAKsJ,GAAQA,EAAIjD,QAAS,CAACwtB,KACrFG,EAAQC,GAAa13B,EAAMyd,SAAS,IACrCka,EAAQj1B,EAAMk1B,sBAEdzlB,EAAWgM,EAAQxT,OAAQoC,IAAyB,IAAjBA,EAAIoF,UACvClC,EAASwnB,EAAOljB,OAAO5E,cACvBkoB,EAAW5nB,EACXkC,EAASxH,OAAQoC,IAAwE,KAA/DA,EAAI+E,YAAc/E,EAAIjD,OAAO6F,cAAcO,QAAQD,IAC7EkC,EAEA2lB,EAAUC,IACZ,MAAMja,EAAO,IAAK6Z,GAClBxlB,EAAS1G,QAASsB,IACd+Q,EAAK/Q,EAAIjD,OAASiuB,IAEtBzqB,EAAI0qB,yBAAyBla,IAGjC,OACI9d,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,iBAAiBiG,KAAK,QAAO,aAAawD,EAAWjd,gBAChE3V,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBACXnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,0BACXnpB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,4BACZnpB,EAAAC,cAAC4sB,GAAU,CAACtnB,KAAM,MAEtBvF,EAAAC,cAAC0uB,GAAS,CACNc,WAAS,EACTlqB,KAAK,QACLxE,MAAO02B,EACPnyB,YAAastB,EAAWrc,8BAA6B,aACzCqc,EAAWrc,8BACvB8G,SAAW4T,GAAUyG,EAAUzG,EAAMzK,OAAOzlB,WAIxDf,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,0BACXnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBACV0O,EAASp0B,IAAKsJ,IACX,MAAMgrB,EAAUR,EAAcxtB,IAAIgD,EAAIjD,OACtC,OACI9J,EAAAC,cAAA,QAAA,CAAOa,IAAKiM,EAAIjD,MAAOqf,UAAU,2BAC7BnpB,EAAAC,cAAC8uB,IAAShI,QAASgR,EAAS1a,SAAUA,IAAM/P,EAAI2qB,oBAAoBlrB,EAAIjD,OAAQiuB,KAChF/3B,EAAAC,cAAA,OAAA,KAAO8M,EAAI+E,YAAc/E,EAAIjD,UAIpB,IAApB+tB,EAASztB,QAAgBpK,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBAAuB,gBAGxEnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBACXnpB,EAAAC,cAACuuB,IAAOzrB,QAAQ,UAAUwC,KAAK,QAAQqsB,QAASA,IAAMkG,GAAO,IACxDlF,EAAWpc,qBAEhBxW,EAAAC,cAACuuB,IAAOzrB,QAAQ,UAAUwC,KAAK,QAAQqsB,QAASA,IAAMkG,GAAO,IACxDlF,EAAWnc,qBAEhBzW,EAAAC,cAACuuB,GAAM,CAACjpB,KAAK,QAAQqsB,QAASA,IAAMtkB,EAAI0qB,yBAAyB,CAAA,IAC5DpF,EAAWlc,oBAKhC,CCtDA,MAAMwhB,GAAoBA,CAACn3B,EAAYo3B,EAAgCpD,EAAQ,OAC3E,MAAOhT,EAAOqW,GAAYp4B,EAAMyd,SAAS1c,GAAS,IAC5C8oB,EAAQ7pB,EAAMgd,OAAsB,MAC1Chd,EAAMic,UAAU,KACZmc,EAASr3B,GAAS,KACnB,CAACA,IAYJ,OANAf,EAAMic,UACF,IAAM,KACoB,OAAlB4N,EAAM5M,SAAkBtc,OAAOopB,aAAaF,EAAM5M,UAE1D,IAEG,CAAC8E,EAXQjE,IACZsa,EAASta,GACa,OAAlB+L,EAAM5M,SAAkBtc,OAAOopB,aAAaF,EAAM5M,SACtD4M,EAAM5M,QAAUtc,OAAO6a,WAAW,IAAM2c,EAASra,GAAOiX,MAWhE,SAASsD,IAAexoB,KAAEA,EAAIwN,SAAEA,EAAQ/X,YAAEA,EAAWiG,KAAEA,IACnD,MAAOwW,EAAOgO,GAAUmI,GAAkBroB,EAAK9O,MAAOsc,GACtD,OACIrd,EAAAC,cAAC0uB,GAAS,CACNppB,KAAK,QACLgG,KAAMA,EACNxK,MAAOghB,EACPzc,YAAaA,EAAW,aACZA,EACZ+X,SAAW4T,GAAUlB,EAAOkB,EAAMzK,OAAOzlB,QAGrD,CAEA,SAASu3B,IAAgBzoB,KAAEA,EAAI0oB,OAAEA,EAAMlb,SAAEA,EAAQ/X,YAAEA,IAC/C,MAAMkzB,EAAStuB,MAAMC,QAAQ0F,EAAK9O,OAAS8O,EAAK9O,MAAM8J,KAAK,MAASgF,EAAK9O,OAAS,IAC3EghB,EAAOgO,GAAUmI,GAAkBM,EAASr5B,GAC/Cke,EACInQ,OAAO/N,GACFkV,MAAM,KACN5Q,IAAKqN,GAAMA,EAAEyD,QACb5J,OAAQmG,GAAY,KAANA,KAG3B,GAAoB,iBAAhBynB,EAAOhtB,KAAyB,CAChC,MAAM3H,EAAUuJ,EAAoBorB,GAC9BjG,EAAqBpoB,MAAMC,QAAQ0F,EAAK9O,OAAS8O,EAAK9O,MAAM0C,IAAIyJ,QAAU,GAChF,OACIlN,gBAAC4uB,GAAM,CACH6J,UAAQ,EACRlzB,KAAK,QACLxE,MAAOuxB,eACKhtB,EACZ+X,SAAW4T,IACP,MAAMxc,EAASvK,MAAM6O,KAAKkY,EAAMzK,OAAOkS,iBAAiBj1B,IAAKoJ,IACzD,MAAMc,EAAQ/J,EAAQgK,KAAM0lB,GAAMpmB,OAAOJ,EAAeyrB,EAAQjF,MAAQzmB,EAAO9L,OAC/E,YAAiByM,IAAVG,EAAsBb,EAAeyrB,EAAQ5qB,GAASd,EAAO9L,QAExEsc,EAAS5I,KAGZ7Q,EAAQH,IAAKoJ,IACV,MAAM9L,EAAQ+L,EAAeyrB,EAAQ1rB,GACrC,OACI7M,EAAAC,cAAA,SAAA,CAAQa,IAAKoM,OAAOnM,GAAQA,MAAOmM,OAAOnM,IACrCiM,EAAeurB,EAAQ1rB,MAMhD,CACA,OACI7M,EAAAC,cAAC0uB,GAAS,CACNppB,KAAK,QACLxE,MAAOghB,EACPzc,YAAY,yBAAwB,aACxBA,EACZ+X,SAAW4T,GAAUlB,EAAOkB,EAAMzK,OAAOzlB,QAGrD,CAEA,SAAS43B,GAAiBl2B,GACtB,MAAMoN,KAAEA,EAAI0oB,OAAEA,EAAMK,SAAEA,EAAQvb,SAAEA,EAAQ/X,YAAEA,GAAgB7C,GACpD6K,IAAEA,GAAQqP,KACV5M,EAAY6oB,GAAU7oB,WAAa,OAEzC,GAAI6oB,GAAUC,eAAgB,CAC1B,MAAMC,EAAYF,EAASC,eAC3B,OAAO74B,EAAAC,cAAC64B,EAAS,CAACjpB,KAAMA,EAAM0oB,OAAQA,EAAQQ,WAAajb,GAAST,EAASS,EAAK/c,OAAQuM,IAAKA,GACnG,CAEA,OAAQyC,GACJ,IAAK,OACD,OAAO/P,4BACX,IAAK,UACD,OACIA,EAAAC,cAAC2uB,GAAM,CACHrpB,KAAK,QACLxE,WAAsByM,IAAfqC,EAAK9O,OAAsC,OAAf8O,EAAK9O,MAAiB,GAAKmM,OAAO2C,EAAK9O,OAAM,aACpEuE,EACZ+X,SAAW4T,GAAU5T,EAAgC,KAAvB4T,EAAMzK,OAAOzlB,WAAeyM,EAAYyjB,EAAMzK,OAAOzlB,QAEnFf,EAAAC,cAAA,SAAA,CAAQc,MAAM,IAAE,OAChBf,EAAAC,cAAA,SAAA,CAAQc,MAAM,QAAM,OACpBf,EAAAC,cAAA,SAAA,CAAQc,MAAM,SAAO,OAGjC,IAAK,SAAU,CACX,MAAM6C,EAAUuJ,EAAoBorB,GACpC,OACIv4B,EAAAC,cAAC2uB,IACGrpB,KAAK,QACLxE,WAAsByM,IAAfqC,EAAK9O,OAAsC,OAAf8O,EAAK9O,MAAiB,GAAKmM,OAAO2C,EAAK9O,OAAM,aACpEuE,EACZ+X,SAAW4T,IACP,MAAMtjB,EAAQ/J,EAAQgK,KAAM0lB,GAAMpmB,OAAOJ,EAAeyrB,EAAQjF,MAAQrC,EAAMzK,OAAOzlB,OACrFsc,EAC2B,KAAvB4T,EAAMzK,OAAOzlB,WACPyM,OACUA,IAAVG,EACEb,EAAeyrB,EAAQ5qB,GACvBsjB,EAAMzK,OAAOzlB,SAI7Bf,EAAAC,cAAA,SAAA,CAAQc,MAAM,KACb6C,EAAQH,IAAKoJ,IACV,MAAM9L,EAAQ+L,EAAeyrB,EAAQ1rB,GACrC,OACI7M,EAAAC,cAAA,SAAA,CAAQa,IAAKoM,OAAOnM,GAAQA,MAAOmM,OAAOnM,IACrCiM,EAAeurB,EAAQ1rB,MAMhD,CACA,IAAK,cACD,OAAO7M,EAAAC,cAACq4B,GAAe,IAAK71B,IAChC,IAAK,SACD,OAAOzC,EAAAC,cAACo4B,GAAc,IAAK51B,EAAO8I,KAAK,WAC3C,IAAK,OACD,OAAOvL,EAAAC,cAACo4B,GAAc,IAAK51B,EAAO8I,KAAK,SAC3C,IAAK,iBACD,OAAOvL,EAAAC,cAACo4B,GAAc,IAAK51B,EAAO8I,KAAK,mBAC3C,QACI,OAAOvL,EAAAC,cAACo4B,GAAc,IAAK51B,EAAO8I,KAAK,SAEnD,CAEA,MAAMytB,GAAoBT,IAAiC,CACvDntB,GAAIN,EAAS,UACbhB,MAAOyuB,GAAQzuB,OAAS,GACxB8uB,SAAUL,EAAUhnB,GAAyBgnB,GAAQ,IAAIx3B,OAAS,WAAc,WAChFA,WAAOyM,aAGKyrB,KACZ,MAAM3rB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,EAAUzU,QAAEA,EAAO0V,UAAEA,GAAclX,KACjDuc,EAAoBl5B,EAAMw3B,QAAQ,IAAMrZ,EAAQxT,OAAQoC,IAA2B,IAAnBA,EAAImF,YAAuB,CAACiM,IAC5FK,EAAUxe,EAAMw3B,QAAQ,KAC1B,MAAM/zB,EAAM,IAAIgb,IAEhB,OADAya,EAAkBztB,QAASsB,GAAQtJ,EAAI6M,IAAIvD,EAAIjD,MAAOiD,IAC/CtJ,GACR,CAACy1B,IAEErO,EAAQnoB,EAAMy2B,YAAYtO,MAC1BuO,EAAgB12B,EAAMy2B,YAAYC,eAAiB,MACnDC,EAAc32B,EAAMowB,gBAAgBuG,YAGpCC,EAASt5B,EAAMgd,QAAO,GAC5Bhd,EAAMic,UAAU,KACZ,IAAIqd,EAAOrc,QAEX,GADAqc,EAAOrc,SAAU,EACboc,GAAe7a,EAAQzU,IAAIsvB,GAAc,CACxBxO,EAAMjd,KAAMiC,GAASA,EAAK/F,QAAUuvB,IACtC/rB,EAAIisB,iBAAiBP,GAAiBxa,EAAQI,IAAIya,IACrE,MAA4B,IAAjBxO,EAAMzgB,QAAgB8uB,EAAkB9uB,OAAS,GACxDkD,EAAIisB,iBAAiBP,GAAiBE,EAAkB,MAE7D,CAAC5rB,EAAKkR,EAAS0a,EAAmBrO,EAAOwO,IAE5C,MAAMG,EAAaA,CAAC3pB,EAAyB4pB,KACzCnsB,EAAIisB,iBAAiB,IAAK1pB,KAAS4pB,KAOjCC,GAAc7F,EAAU8F,iCAAoD,IAAjB9O,EAAMzgB,OAEvE,OACIpK,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,iBAAiBiG,KAAK,QAAO,aAAawD,EAAWhd,gBAChE5V,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBAAyBnnB,MAAO,CAAE43B,WAAY,KACvC,IAAjB/O,EAAMzgB,QAAgBpK,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBAAuB,cAC5D0B,EAAMpnB,IAAI,CAACoM,EAAMmT,KACd,MAAMuV,EAAS/Z,EAAQI,IAAI/O,EAAK/F,QAAUovB,EAAkB,GACtDW,EAAYtB,EAAShnB,GAAyBgnB,GAAU,GACxDK,EAAWiB,EAAUjsB,KAAMksB,GAAOA,EAAG/4B,QAAU8O,EAAK+oB,WAAaiB,EAAU,GAC3EE,EAAYlP,EAAMzgB,OAAS,EACjC,OACIpK,uBACIc,IAAKoM,OAAO2C,EAAKzE,IAAM4X,GACvBmG,UACI4Q,EAAY,sDAAwD,uBAGxE/5B,EAAAC,cAACyuB,IACGnpB,KAAK,QACL0H,MAAO2lB,EAAW/b,sBAClB+a,QAASA,IAAMtkB,EAAI0sB,iBAAiBnqB,IAEpC7P,EAAAC,cAACytB,UAEJqM,GACG/5B,EAAAC,cAAC4uB,GAAK,CAAC5hB,MAAiB,IAAV+V,EAAc4P,EAAW1b,yBAA2B,KACnD,IAAV8L,EACGhjB,EAAAC,cAAA,MAAA,CAAK+B,MAAO,CAAEnC,OAAQ,MAEtBG,EAAAC,cAAC2uB,GAAM,CACHrpB,KAAK,QACLxE,MAAOq4B,EACP7G,SAAUvP,EAAQ,EAAC,aACP4P,EAAW1b,yBACvBmG,SAAW4T,GACP3jB,EAAI2sB,uBAAuBhJ,EAAMzK,OAAOzlB,QAG5Cf,EAAAC,cAAA,SAAA,CAAQc,MAAM,OAAO6xB,EAAWzb,wBAChCnX,EAAAC,cAAA,SAAA,CAAQc,MAAM,MAAM6xB,EAAWxb,yBAK/CpX,EAAAC,cAAC4uB,GAAK,CAAC5hB,MAAO2lB,EAAW9b,oBACrB9W,EAAAC,cAAC2uB,IACGrpB,KAAK,QACLxE,MAAOw3B,GAAQzuB,OAAS,GAAE,aACd8oB,EAAW9b,mBACvBuG,SAAW4T,IACP,MAAMiJ,EAAa1b,EAAQI,IAAIqS,EAAMzK,OAAOzlB,OACtCo5B,EAAgBD,EAAa3oB,GAAyB2oB,GAAc,GACpEE,EAAeD,EAAchJ,KAAM2I,GAAOA,EAAG/4B,QAAU8O,EAAK+oB,UAClEY,EAAW3pB,EAAM,CACb/F,MAAOmnB,EAAMzK,OAAOzlB,MACpB63B,SAAUwB,EAAevqB,EAAK+oB,SAAYuB,EAAc,IAAIp5B,OAAS,WACrEA,WAAOyM,MAId0rB,EAAkBz1B,IAAKsJ,GACpB/M,EAAAC,cAAA,SAAA,CAAQa,IAAKiM,EAAIjD,MAAO/I,MAAOgM,EAAIjD,OAC9BiD,EAAI+E,YAAc/E,EAAIjD,UAKvC9J,EAAAC,cAAC4uB,GAAK,CAAC5hB,MAAO2lB,EAAW7b,qBACrB/W,EAAAC,cAAC2uB,IACGrpB,KAAK,QACLxE,MAAO63B,GAAU73B,OAAS,GAAE,aAChB6xB,EAAW7b,oBACvBsG,SAAW4T,IACP,MAAMoJ,EAAeR,EAAUjsB,KAAMksB,GAAOA,EAAG/4B,QAAUkwB,EAAMzK,OAAOzlB,OAChEu5B,EAA0C,gBAA5BD,GAActqB,UAC5BwqB,EAAyC,gBAAxB3B,GAAU7oB,UACjCypB,EAAW3pB,EAAM,CACb+oB,SAAU3H,EAAMzK,OAAOzlB,MACvBA,MAAOu5B,IAAgBC,OAAiB/sB,EAAYqC,EAAK9O,UAIhE84B,EAAUp2B,IAAKq2B,GACZ95B,EAAAC,cAAA,SAAA,CAAQa,IAAKg5B,EAAG/4B,MAAOA,MAAO+4B,EAAG/4B,OAC5B+4B,EAAG7sB,OAAS6sB,EAAG/4B,UAKhCf,EAAAC,cAAC4uB,GAAK,CAAC5hB,MAAO2lB,EAAW5b,kBACpBuhB,EACGv4B,EAAAC,cAAC04B,GAAgB,CACb9oB,KAAMA,EACN0oB,OAAQA,EACRK,SAAUA,EACVtzB,YAAastB,EAAW3b,4BACxBoG,SAAWtc,GAAUy4B,EAAW3pB,EAAM,CAAE9O,YAG5Cf,EAAAC,cAAA,MAAA,WAOxBD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBACXnpB,EAAAC,cAACuuB,GAAM,CACHzrB,QAAQ,UACRwC,KAAK,QACLiD,UAAWxI,EAAAC,cAAC0tB,GAAO,CAACpoB,KAAM,KAC1BqsB,QApHA4I,KACZltB,EAAIisB,iBAAiBP,GAAiBE,EAAkB,MAoH5C3G,UAAWmH,GAEV9G,EAAWjc,sBAEhB3W,EAAAC,cAACuuB,GAAM,CACHjpB,KAAK,QACLiD,UAAWxI,EAAAC,cAACytB,GAAU,CAACnoB,KAAM,KAC7BgtB,SAA2B,IAAjB1H,EAAMzgB,OAChBwnB,QAASA,IAAMtkB,EAAImtB,eAAe,IAAK/3B,EAAMy2B,YAAatO,MAAO,MAEhE+H,EAAWhc,uBAKhC,CCtTM,SAAU8jB,IAAkBnC,OAAEA,EAAMjJ,SAAEA,EAAQ1G,KAAEA,EAAI2G,QAAEA,EAAOlwB,UAAEA,EAASs7B,cAAEA,IAC5E,MAAMrtB,IAAEA,EAAG5K,MAAEA,EAAKkwB,WAAEA,EAAUiB,UAAEA,GAAclX,KACxC7S,EAAQyuB,EAAOzuB,MACf8wB,EAAmB9wB,IAAUd,EAC7B6xB,EAAWn4B,EAAMo4B,UAAUltB,KAAMiC,GAASA,EAAK/F,QAAUA,GACzDixB,EAASztB,EAAI0tB,eAAelxB,GAC5BmxB,GAAsD,IAA1Cv4B,EAAMw4B,iBAAiBhrB,QAAQpG,GAC3CqxB,EAAcz4B,EAAMwpB,iBAAiBpiB,GAErCsxB,GAA8B,IAApB7C,EAAOtmB,WAAuB4hB,EAAUwH,qBAClDC,GAAkC,IAAtB/C,EAAOrmB,aAAyB2hB,EAAUkC,sBAAwB6E,EAC9EW,GAA8B,IAApBhD,EAAOpmB,SACjBqpB,GAA6B,IAApBjD,EAAOlmB,WAAuBwhB,EAAU4H,qBACjDC,GAAgC,IAArBnD,EAAOjmB,YAAwBuhB,EAAU8H,qBAAuBf,EAC3EgB,EAAuBxoB,OAAOC,KAAKwgB,EAAU+H,sBAAsBjxB,OAAQoN,IAC7E,MAAMuU,EAAKuH,EAAU+H,qBAAqB7jB,GAC1C,QAAIwgB,EAAOsD,gCAAwF,IAAvDtD,EAAOsD,8BAA8B3rB,QAAQ6H,OACrFuU,EAAG1X,cAAe2jB,EAAOhtB,OAAgD,IAAxC+gB,EAAG1X,YAAY1E,QAAQqoB,EAAOhtB,SAGjEuwB,GACoB,IAAtBvD,EAAOhmB,aAAyBshB,EAAUkI,qBAAuBnB,GAAoBgB,EAAqBxxB,OAAS,EAEjH4xB,EAAiBrB,GAAiBrL,EAClCvX,EAAOwgB,EAAOzmB,YAAcymB,EAAOzuB,MAEzC,OACI9J,EAAAC,cAACovB,GAAO,CAACzG,KAAMA,EAAM0G,SAAUA,EAAUC,QAASA,EAASlwB,UAAWA,EAAWmwB,UAAU,aAAaJ,KAAK,QACzGpvB,EAAAC,cAAC+xB,GAAI,CAAA,aAAaY,EAAWxY,iBACxBghB,GACGp7B,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAAC+sB,GAAe,MACtBsF,SAA6B,QAAnBuI,GAAUvlB,KACpBsc,QAASA,IAAMtkB,EAAI2uB,WAAWnyB,EAAO,OACrC0oB,SAAUjD,GAETqD,EAAWvb,mBAEhBrX,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAACgtB,GAAiB,MACxBqF,SAA6B,SAAnBuI,GAAUvlB,KACpBsc,QAASA,IAAMtkB,EAAI2uB,WAAWnyB,EAAO,QACrC0oB,SAAUjD,GAETqD,EAAWtb,oBAEfujB,GACG76B,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAAA,OAAA,CAAM+B,MAAO,CAAEzB,MAAO,MAC5BqxB,QAASA,IAAMtkB,EAAI2uB,WAAWnyB,EAAO,MACrC0oB,SAAUjD,GAETqD,EAAWrb,mBAK3B+jB,GACGt7B,EAAAC,cAAAD,EAAAuuB,SAAA,KACK6M,GAAWp7B,EAAAC,cAACwyB,GAAW,MACxBzyB,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAAC2sB,GAAc,MACrBgF,QAASA,IAAMtkB,EAAI4uB,gBAAgBpyB,EAAOkyB,GAC1CxJ,SAAUjD,GAETqD,EAAWpb,oBAItB+jB,IAAY1H,EAAUgC,wBACpB71B,EAAAC,cAAAD,EAAAuuB,SAAA,MACM6M,GAAWE,IAAct7B,EAAAC,cAACwyB,GAAW,MACtC8I,GACGv7B,EAAAC,cAACoyB,IACGhsB,KAAMrG,EAAAC,cAACkuB,GAAiB,MACxByD,QAASA,IAAMtkB,EAAI2qB,oBAAoBnuB,GAAO,GAC9C0oB,SAAUjD,GAETqD,EAAWnb,uBAGlBoc,EAAUgC,uBACR71B,gBAACqyB,GAAQ,CACLhsB,KAAMrG,gBAAC2sB,GAAc,MACrBiF,QAASA,IAAMtkB,EAAI2lB,gBAAgB,UAAW+I,GAC9CxJ,SAAUjD,GAETqD,EAAWlb,0BAK3B8jB,GACGx7B,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACwyB,GAAW,MACA,SAAXsI,GACG/6B,EAAAC,cAACoyB,IACGhsB,KAAMrG,gBAACytB,GAAW,CAACzrB,MAAO,CAAEm6B,UAAW,mBACvCvK,QAASA,IAAMtkB,EAAI8uB,UAAUtyB,EAAO,QACpC0oB,SAAUjD,GAETqD,EAAWjb,mBAGR,UAAXojB,GACG/6B,EAAAC,cAACoyB,IACGhsB,KAAMrG,gBAACytB,GAAW,CAACzrB,MAAO,CAAEm6B,UAAW,oBACvCvK,QAASA,IAAMtkB,EAAI8uB,UAAUtyB,EAAO,SACpC0oB,SAAUjD,GAETqD,EAAWhb,oBAGnBmjB,GACG/6B,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAAA,OAAA,CAAM+B,MAAO,CAAEzB,MAAO,MAC5BqxB,QAASA,IAAMtkB,EAAI+uB,YAAYvyB,GAC/B0oB,SAAUjD,GAETqD,EAAW/a,kBAK3B6jB,GACG17B,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACwyB,GAAW,MACZzyB,EAAAC,cAACoyB,GAAQ,CACLhsB,KAAMrG,EAAAC,cAACouB,GAAc,MACrBuD,QAASA,IACLqJ,EAAY3tB,EAAIgvB,0BAA0BxyB,GAASwD,EAAIivB,uBAAuBzyB,GAElF0oB,SAAUjD,GAET0L,EAAYrI,EAAW5a,kBAAkBD,GAAQ6a,EAAW9a,gBAAgBC,KAIxF+jB,GACG97B,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACwyB,GAAW,MACZzyB,EAAAC,cAACyyB,GAAW,KACR1yB,EAAAC,cAAA,QAAA,CACIkpB,UAAU,uBACVnnB,MAAO,CAAEtC,QAAS,OAAQC,WAAY,SAAU68B,IAAK,IAErDx8B,EAAAC,cAACmuB,GAAa,CAAC7oB,KAAM,SAAQqtB,EAAW3a,uBAE5CjY,EAAAC,cAAC2uB,IACGrpB,KAAK,QACLxE,MAAOo6B,GAAe,GAAE,aACZvI,EAAW3a,sBACvBoF,SAAW4T,IACP,MAAMnT,EAAO,IAAKpb,EAAMwpB,kBACG,KAAvB+E,EAAMzK,OAAOzlB,aAAqB+c,EAAKhU,GACtCgU,EAAKhU,GAASmnB,EAAMzK,OAAOzlB,MAChCuM,EAAImvB,oBAAoB3e,KAG5B9d,EAAAC,cAAA,SAAA,CAAQc,MAAM,IAAI6xB,EAAWza,8BAC5ByjB,EAAqBn4B,IAAK4oB,GACvBrsB,EAAAC,cAAA,SAAA,CAAQa,IAAKurB,EAAQtrB,MAAOsrB,GACvBwH,EAAU+H,qBAAqBvP,GAAQpf,OAASof,QAUzF,CCjMM,SAAUqQ,IAAqBv9B,KAAEA,EAAO,UAASw9B,SAAEA,IACrD,OACI38B,uBAAKmpB,UAAU,mBAAmBiG,KAAK,UAClCuN,EAAW38B,EAAAC,cAAA,MAAA,CAAKG,IAAI,GAAGC,IAAKs8B,IAAe38B,EAAAC,cAACquB,GAAY,CAAC/oB,KAAM,KAChEvF,EAAAC,cAAA,MAAA,KAAMd,GAGlB,CAEM,SAAUy9B,IAAsBz9B,KAAEA,IACpC,OACIa,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACkvB,GAAO,MACPhwB,GAAQa,EAAAC,cAAA,MAAA,KAAMd,GAG3B,UCPgB09B,IAAuBx2B,KACnCA,EAAI4G,MACJA,EAAK2kB,QACLA,EAAOkL,WACPA,EAAUvK,SACVA,EAAQpJ,UACRA,KACGqD,IAEH,OACIxsB,EAAAC,cAACyuB,GAAU,CACPnpB,KAAK,QACL0H,MAAOA,EACPslB,SAAUA,EACVpJ,UAAWA,EACXyI,QAAUX,IACNA,EAAMO,kBACNI,IAAUX,OAEVzE,GAEHnmB,EAGb,CASM,SAAU02B,IAAYC,QAAEA,EAAO39B,UAAEA,EAAS49B,UAAEA,IAC9C,MAAO/hB,EAAQmY,GAAarzB,EAAMyd,SAA6B,MACzDyf,EAA+B,GAC/BC,EAA+B,GAOrC,OANAH,EAAQvxB,QAAS2xB,IACRp9B,EAAMi0B,eAAemJ,KACrBA,EAAO36B,OAAuCq6B,WAAYK,EAAOjpB,KAAKkpB,GACtEF,EAAOhpB,KAAKkpB,MAIjBp9B,EAAAC,cAAAD,EAAAuuB,SAAA,KACK2O,EAAOz5B,IAAI,CAAC25B,EAAQpa,IACjBhjB,EAAAC,cAACD,EAAMuuB,SAAQ,CAACztB,IAAKs8B,EAAOt8B,KAAOkiB,GAAQoa,IAE9CD,EAAO/yB,OAAS,GACbpK,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAACyuB,IACGnpB,KAAK,QACL0H,MAAOgwB,EACPxO,OAAQ7jB,QAAQsQ,GAChB0W,QAAUX,IACNA,EAAMO,kBACN6B,EAAW3C,GAAUA,EAAO,KAAOO,EAAMiC,iBAG7ClzB,EAAAC,cAACitB,UAELltB,EAAAC,cAACovB,GAAO,CACJzG,KAAMhe,QAAQsQ,GACdoU,SAAUpU,EACVqU,QAASA,IAAM8D,EAAU,MACzBh0B,UAAWA,EACXmwB,UAAU,aACVJ,KAAK,QAELpvB,EAAAC,cAAC+xB,GAAI,KACAmL,EAAO15B,IAAI,CAAC25B,EAAQpa,KACjB,MAAMvgB,EAAQ26B,EAAO36B,MACrB,OACIzC,EAAAC,cAACoyB,GAAQ,CACLvxB,IAAKs8B,EAAOt8B,KAAOkiB,EACnB3c,KAAM5D,EAAM4D,KACZksB,SAAU9vB,EAAM8vB,SAChBX,QAAUX,IACNxuB,EAAMmvB,UAAUX,GAChBoC,EAAU,QAGb5wB,EAAMwK,YAU/C,CAnEA4vB,GAAuBngB,YAAc,yBCqErC,MAAM2gB,GAAqB,GACrBC,GAAoC,CAAA,EACpCC,GAAY,IAAI9e,IAChB+e,GAAgD,CAAC,MAAO,OAAQ,MAChEC,GAA4B,CAAC,GAAI,GAAI,GAAI,KACzCC,GAA2C,CAAE7S,MAAO,GAAI8S,iCAAiC,GAkCzFC,GAAiB57B,IACnB,IAAKA,EAAO,OACZ,MAAM8R,EAA2B,CAAA,EAOjC,OANAV,OAAOC,KAAKrR,GAAOyJ,QAAS3K,IACxB,GAAIkS,GAAclS,GAAM,OACxB,MAAMC,EAASiB,EAAclB,GACR,iBAAVC,GAAuC,iBAAVA,IACxC+S,EAAIhT,GAAOC,KAER+S,GAqDL+pB,GAAmBA,CAAC98B,EAAYuL,KAClC,MAAMC,EAAOZ,EAAO5K,GACpB,IAAKwL,EAAM,MAAO,GAClB,MAAMuxB,EAAOptB,GAAcxD,OAAOwD,GAAGqtB,SAAS,EAAG,KAC3Cze,EAAO,GAAG/S,EAAKqX,iBAAiBka,EAAIvxB,EAAKsX,WAAa,MAAMia,EAAIvxB,EAAKuX,aAC3E,OAAOxX,EAAW,GAAGgT,KAAQwe,EAAIvxB,EAAKwX,eAAe+Z,EAAIvxB,EAAKyX,gBAAkB1E,GAOtE,SAAU0e,GAA8Cv7B,GAClE,MAAMuc,KACFA,EACAb,QAAS8f,EAAW9yB,SACpBA,EAAQ+yB,QACRA,GAAU,EAAK9J,OACfA,EAAM+J,uBACNA,EAAsBC,0BACtBA,EAAyBC,YACzBA,GAAc,EAAKlV,UACnBA,EAASmV,cACTA,EAAaC,aACbA,EAAYC,UACZA,EAASC,OACTA,EAAMC,SACNA,EAAQC,MACRA,EAAK38B,MACLA,EAAK1B,GACLA,EAAEjB,UACFA,EAAY,QAAOu/B,UACnBA,EAASC,YACTA,GAAc,EAAIC,aAClBA,EAAYC,MACZA,EAAQzB,GAAY93B,UACpBA,EAAY83B,GAAY0B,WACxBA,EAAa,4CACbpM,WAAYqM,EACZC,UAAWC,EAAgBz1B,EAAkB01B,mBAC7CA,EAAqBz1B,EAAqB01B,aAC1CA,EAAYC,WACZA,GAAa,EAAKC,sBAClBA,GAAwB,EACxBhM,QAASiM,EAAWC,gBACpBA,EAAexJ,uBACfA,IAAyB,EAAKgB,WAC9BA,IAAa,EAAIb,SACjBA,GAAW,GAAEI,gBACbA,GAAkBiH,GAClBpH,gBAAiBqJ,GAAmBC,wBACpCA,GAAuBzZ,WACvBA,IAAa,EAAKgR,qBAClBA,IAAuB,EAAKE,mBAC5BA,IAAqB,EAAKL,2BAC1BA,IAA6B,EAC7B+D,UAAW8E,GAAaC,kBACxBA,GAAiBC,aACjBA,GAAetC,GAAqBuC,8BACpCA,IAAgC,EAAK1E,qBACrCA,IAAuB,EACvBlC,YAAa6G,GAAeC,oBAC5BA,GAAmBlK,oBACnBA,IAAsB,EAAK4D,gCAC3BA,IAAkC,EAAK3E,sBACvCA,GAAwB,IACxB4C,sBAAuBsI,GAAyBC,8BAChDA,GAA6BC,2BAC7BA,GAA0BC,sBAC1BA,GAAqBC,sBACrBA,GAAqBC,wBACrBA,GAAuBC,oBACvBA,GAAmBC,oBACnBA,GAAmBhuB,kBACnBA,IAAoB,EAAKojB,sBACzBA,IAAwB,EAAK6K,oBAC7BA,IAAsB,EAAKC,qBAC3BA,IAAuB,EAAKlF,qBAC5BA,IAAuB,EACvBmF,cAAeC,GAAiBC,sBAChCA,GAAqBC,kBACrBA,IAAoB,EAAKC,6BACzBA,IAA+B,EAAKC,2BACpCA,IAA6B,EAAIC,4BACjCA,IAA8B,EAC9BrK,kBAAmBsK,GAAqBC,0BACxCA,GAAyBC,gBACzBA,GAAeC,4BACfA,IAA8B,EAAIC,gBAClCA,GAAeC,WACfA,GAAUC,iBACVA,GAAgBC,YAChBA,GAAWC,kBACXA,GAAiBC,WACjBA,GAAUC,sBACVA,GAAqBC,qBACrBA,GACAC,0BAA2BC,GAA6BC,kCACxDA,GACA/G,iBAAkBgH,GAAoBC,yBACtCA,GAAwBC,8BACxBA,GAAgC,EAACC,eACjCA,GAAc1G,mBACdA,IAAqB,EAAK2G,yBAC1BA,GACApW,iBAAkBqW,GAAoBC,yBACtCA,GACA5G,qBAAsB6G,GAAwB1G,mBAC9CA,IAAqB,EAAK2G,oBAC1BA,GAAsB,OAAMC,iBAC5BA,GAAgBC,wBAChBA,GAAuBC,eACvBA,GAAcC,eACdA,GAAcC,aACdA,GAAYC,OACZA,GAAMC,cACNA,IACAxgC,EAEJyZ,KAEA,MAAMgnB,Gb9MJ,SAAsBl4B,GACxB,MAAMm4B,EAAcnjC,EAAcojC,MAClC,GAAID,EAGA,MAAO,GAAGn4B,KADCm4B,IACY3vB,QAAQ,KAAM,MAGzC,MAAMrO,EAAMnF,EAAMgd,OAAsB,MAKxC,OAJoB,OAAhB7X,EAAI8X,UACJgB,IAAa,EACb9Y,EAAI8X,QAAU,GAAGjS,KAAUiT,MAExB9Y,EAAI8X,OACf,CagMmBomB,CAAY,YACrBC,GAAUtjC,EAAMgd,OAA8B,MAC9CumB,GAAUvjC,EAAMgd,OAA8B,MAC9CwmB,GAAcxjC,EAAMgd,OAA8B,MAClDymB,GAAazjC,EAAMgd,OAA8B,MACjD0mB,cbzNN,MAAM,CAAGC,GAAW3jC,EAAMyd,SAAS,GACnC,OAAOzd,EAAM6d,YAAY,IAAM8lB,EAAS/c,GAAMA,EAAI,GAAI,GAC1D,CauNwBgd,GAEdhR,GAAa5yB,EAAMw3B,QACrB,KAAA,IAAYhiB,MAAwBypB,IACpC,CAACA,IAKC4E,GAAS7jC,EAAMgd,OAAY,IAC3B8mB,GAAa9jC,EAAM6d,YAAY,KAAA,CAAiCvQ,IAAKu2B,GAAO5mB,QAAQ3P,MAAQ,IAE5Fy2B,GAAY/jC,EAAMw3B,QAAuB,KAC3C,MAAMwM,EAAIA,IAAMH,GAAO5mB,QACjBgnB,EAAyB,CAC3BhlB,OAAS7T,GAAO44B,IAAIE,SAAStlB,IAAIxT,IAAO,KACxC+4B,aAAcA,IAAM,IAAI1lB,IAAIulB,IAAIE,UAChCE,aAAcA,IAAMJ,IAAIK,WAAW5gC,IAAK6gC,GAAmBA,EAAEl5B,IAC7Dm5B,WAAan5B,GAAO44B,IAAIQ,UAAU5lB,IAAIxT,IAAO,KAC7Cq5B,cAAeA,IAAMT,IAAIU,aAAajhC,IAAK6gC,GAAmBA,EAAEp5B,KAChE6T,gBAAiBA,IAAMilB,IAAIU,aAAajhC,IAAK6gC,GAAmBA,EAAEl5B,IAClEu5B,eAAgBA,IACZX,IACKY,UAAUj6B,OAAQk6B,GAAkC,SAAZA,EAAGt5B,MAAmBs5B,EAAG35B,KACjEzH,IAAKohC,IAAiB,CAAQz5B,GAAIy5B,EAAGz5B,GAAIusB,MAAOkN,EAAG35B,OAC5D45B,iCAAmC15B,GAAO44B,IAAIY,UAAUG,UAAWF,GAAsBA,EAAGz5B,KAAOA,GACnG45B,WAAaC,IACTA,EAAQx5B,QAASskB,IACb,MAAM3kB,EAAKH,EAAgB8kB,EAAaiU,IAAI74B,UACtC+5B,EAAWlB,IAAIE,SAAStlB,IAAIxT,GAC9B85B,GAAUlB,IAAImB,eAAe/5B,EAAI,IAAK85B,KAAanV,OAI/DzR,cAAeA,IAAM0lB,IAAIoB,mBACzBvmB,kBAAmBA,IAAMmlB,IAAIqB,mBAC7BC,UAAYx7B,GAAUk6B,IAAIsB,UAAUx7B,GACpCy7B,eAAgBA,CAACz7B,EAAO07B,GAAoB,KACvCA,EAAoBxB,IAAIqB,mBAAqBrB,IAAIoB,oBAAoBL,UACjErmB,GAAqBA,EAAE5U,QAAUA,GAE1C27B,yBAA0BA,IAAMzB,IAAIpM,sBACpCK,oBAAqBA,CAACnuB,EAAO47B,IACzB1B,IAAIhM,yBAAyB,IAAKgM,IAAIpM,sBAAuB9tB,CAACA,GAAQ47B,IAC1E1N,yBAA2BL,GAAUqM,IAAIhM,yBAAyBL,GAClEgO,eAAgBA,CAAC77B,EAAOvJ,IAAUyjC,IAAI2B,eAAe77B,EAAOvJ,GAC5DqlC,eAAgBA,CAAC97B,EAAO+7B,IAAgB7B,IAAI4B,eAAe97B,EAAO+7B,GAClEC,gBAAkBliC,GAAYogC,IAAI8B,gBAAgBliC,GAClDw4B,UAAWA,CAACtyB,EAAOi8B,IAAS/B,IAAI5H,UAAUtyB,EAAOi8B,GACjD1J,YAAcvyB,GAAUk6B,IAAI3H,YAAYvyB,GACxCkxB,eAAiBlxB,GAAUk6B,IAAIhJ,eAAelxB,GAC9Ck8B,iBAAkBA,IAAMhC,IAAIpD,cAC5BqF,iBAAmBtO,GAAUqM,IAAIiC,iBAAiBtO,GAElDuO,aAAcA,IAAMlC,IAAIlJ,UACxBqL,aAAexO,GAAUqM,IAAImC,aAAaxO,GAC1CsE,WAAYA,CAACnyB,EAAOs8B,EAAWC,IAAyBrC,IAAI/H,WAAWnyB,EAAOs8B,EAAWC,GAEzFC,eAAgBA,IAAMtC,IAAI7K,YAC1BsB,eAAiB9C,GAAUqM,IAAIvJ,eAAe9C,GAC9C4B,iBAAmB1pB,GAASm0B,IAAIuC,kBAAkB,CAAC12B,IACnD02B,kBAAoB1b,GAAUmZ,IAAIuC,kBAAkB1b,GACpDmP,iBAAmBnqB,GAASm0B,IAAIhK,iBAAiBnqB,GACjDoqB,uBAAyBrB,GAAaoL,IAAIvJ,eAAe,IAAKuJ,IAAI7K,YAAaC,cAAeR,IAC9FzD,qBAAuB1gB,GAAWuvB,IAAIvJ,eAAe,IAAKuJ,IAAI7K,YAAavE,kBAAmBngB,IAC9FynB,gBAAiBA,CAACsK,EAAmBlX,IAAa0U,IAAI/Q,gBAAgB,UAAW3D,EAAUkX,GAC3FC,gBAAiBA,IAAMzC,IAAIhR,kBAC3BC,gBAAiBA,CAACyT,EAAOpX,EAAU+J,IAAgB2K,IAAI/Q,gBAAgByT,EAAOpX,EAAU+J,GACxFrG,gBAAiBA,IAAMgR,IAAIhR,kBAE3B2T,gBAAiBA,KACb,MAAMljC,EAAM,IAAIgb,IAKhB,OAJAulB,IAAI4C,YAAYn7B,QAASL,IACrB,MAAMF,EAAM84B,IAAIE,SAAStlB,IAAIxT,GACzBF,GAAKzH,EAAI6M,IAAIlF,EAAIF,KAElBzH,GAEXojC,qBAAsBA,KAAAA,CAASt7B,KAAM,UAAWC,IAAKw4B,IAAI4C,cACzDE,qBAAuBnP,IACnB,MAAMoP,EAAa17B,EACfssB,EACAqM,IAAIK,WAAW5gC,IAAK6gC,GAAmBA,EAAEl5B,KAE7C44B,IAAIgD,eAAeD,EAAWv7B,MAElCy7B,UAAWA,CAAC77B,EAAI87B,GAAa,EAAMC,GAAiB,IAAUnD,IAAIoD,WAAW,CAACh8B,GAAK87B,EAAYC,GAC/FC,WAAYA,CAAC57B,EAAK07B,GAAa,EAAMC,GAAiB,IAAUnD,IAAIoD,WAAW57B,EAAK07B,EAAYC,GAChGE,cAAgBj8B,GAAO44B,IAAI4C,YAAY78B,IAAIqB,GAC3Ci2B,gBAAkBj2B,GAAO44B,IAAIsD,kBAAkBl8B,EAAI44B,IAAIE,SAAStlB,IAAIxT,IAEpEsrB,QAAU6Q,GAAavD,IAAIwD,mBAAmB,IAAKxD,IAAI3N,gBAAiBF,KAAM3rB,KAAKD,IAAI,EAAGg9B,KAC1F9Q,YAAcgR,GAAiBzD,IAAIwD,mBAAmB,CAAErR,KAAM,EAAGC,SAAU5rB,KAAKD,IAAI,EAAGk9B,KACvFD,mBAAqB7P,GAAUqM,IAAIwD,mBAAmB7P,GAEtDnE,WAAazyB,GAAUijC,IAAIxQ,WAAWzyB,GAEtC4e,aAAe/b,GAAY+b,GAAaskB,EAASrgC,GACjDywB,gBAAkBzwB,GZ/TCywB,EAAC/mB,EAAiB1J,EAAmC,MAChF,MAAM8jC,EAAM/nB,GAAarS,EAAK1J,GACxB+jC,EAAM/jC,EAAQgkC,YAAc1nB,GAAW,GACvCrF,EAAO,IAAIgtB,KAAK,CAACF,EAAMD,GAAM,CAAEn8B,KAAM,4BAC3CqP,GAAaC,EAAMsE,GAAiBvb,EAAQkX,SAAU0E,KAAmB,SY2TnC6U,CAAgB4P,EAASrgC,GACvD0wB,kBAAoB1wB,GZiBCylB,OAAO/b,EAAiB1J,EAAqC,MAC1F,MAAMge,EAAQoD,GAAU1X,EAAK1J,GACvBiX,EAAO,IAAIgtB,KAAK,CAACjmB,GAAoB,CACvCrW,KAAM,sEAEVqP,GAAaC,EAAMsE,GAAiBvb,EAAQkX,SAAU0E,KAAmB,UYtBjC8U,CAAkB2P,EAASrgC,GAC3D2wB,kBAAoB3wB,GAAYogC,IAAI8D,WAAWlkC,GAE/CmkC,kBAAoB38B,GAAO44B,IAAI+D,kBAAkB38B,GACjD48B,wBAA0Bx8B,GAAQw4B,IAAIgE,wBAAwB,IAAI3+B,IAAImC,IACtEy8B,wBAAyBA,IAAM/9B,MAAM6O,KAAKirB,IAAIkE,sBAE9CC,oBAAqBA,IAAMnE,IAAI9I,iBAC/BkN,oBAAsBzQ,GAAUqM,IAAIoE,oBAAoBzQ,GACxD4E,uBAAwBA,CAACzyB,EAAOu+B,KAC5B,MAAMprB,EAAoB+mB,IAAI9I,iBAAiBvwB,OAAQgU,GAAcA,IAAM7U,QACrD0D,IAAlB66B,EAA6BprB,EAAQ/I,KAAKpK,GACzCmT,EAAQqrB,OAAOj+B,EAAMg+B,EAAe,EAAGprB,EAAQ7S,QAAS,EAAGN,GAChEk6B,IAAIoE,oBAAoBnrB,IAE5Bqf,0BAA4BxyB,GACxBk6B,IAAIoE,oBAAoBpE,IAAI9I,iBAAiBvwB,OAAQgU,GAAcA,IAAM7U,IAC7Ey+B,wBAAyBA,CAACn9B,EAAIiqB,IAAe2O,IAAIuE,wBAAwBn9B,EAAIiqB,GAC7EmT,oBAAqBA,EAAGC,cACpB,MAAMC,EAAQ1E,IAAI2E,WAAW/pB,IAAI6pB,GACjC,OAAOC,EAAQA,EAAM9c,YAAYnoB,IAAK0I,GAAMA,EAAEf,IAAM,IAGxDw9B,oBAAqBA,IAAM5E,IAAI9X,iBAC/BuQ,oBAAsB9E,GAAUqM,IAAIvH,oBAAoB9E,GAExDkR,kBAAmBA,EAAGz9B,KAAItB,WAAYk6B,IAAI6E,kBAAkBz9B,EAAItB,GAChEg/B,iBAAkBA,EAAG19B,KAAItB,QAAOi/B,yBAC5B/E,IAAI8E,iBAAiB19B,EAAItB,EAAOi/B,EAAqB,OACzDC,YAAaA,CAAC59B,EAAItB,KACd,MAAMm/B,EAAUjF,IAAIkF,YACpB,OAAOD,GAAWA,EAAQ79B,KAAOA,GAAM69B,EAAQn/B,QAAUA,EAAQ,OAAS,QAE9Eq/B,iBAAkBA,EAAG/9B,KAAItB,QAAO/I,YAC5B,MAAMkoC,EAAUjF,IAAIkF,YAChBD,GAAWA,EAAQ79B,KAAOA,GAAM69B,EAAQn/B,QAAUA,GAAOk6B,IAAIoF,aAAaroC,IAGlFsM,aAAcA,CAACjC,EAAItB,KACf,MAAMoB,EAAM84B,IAAIE,SAAStlB,IAAIxT,GACvB2B,EAAMi3B,IAAIsB,UAAUx7B,GAC1B,OAAOoB,GAAO6B,EAAMM,GAAanC,EAAK6B,EAAKk3B,QAAWz2B,GAE1D67B,cAAeA,CAACj+B,EAAItB,KAChB,MAAMoB,EAAM84B,IAAIE,SAAStlB,IAAIxT,GAC7B,OAAO44B,IAAIsF,gBACPl+B,EACAtB,EACAoB,EACA84B,IAAIQ,UAAU5lB,IAAIxT,IAAO,CAAEG,KAAM,OAAQH,KAAI0f,MAAO,EAAGQ,OAAQ,QAGvEie,aAAcA,CAACn+B,EAAItB,KACf0/B,GAAgBvsB,SAAU,EAC1B+mB,IAAIyF,eAAe,CAAEr+B,KAAItB,WAG7B4/B,gBAAkBhkB,GAAWse,IAAI0F,gBAAgBhkB,GACjDikB,OAAQA,EAAG9Z,OAAMD,UACb,MAAMga,EAAWpG,GAAYvmB,QACxB2sB,SACQp8B,IAATqiB,IAAoB+Z,EAASC,WAAaha,QAClCriB,IAARoiB,IAAmBga,EAASE,UAAYla,KAEhDma,kBAAmBA,KAAAA,CACfla,KAAM2T,GAAYvmB,SAAS4sB,YAAc,EACzCja,IAAK4T,GAAYvmB,SAAS6sB,WAAa,IAG3C,SAAIpnC,GACA,OAAOshC,IAAIthC,KACf,EACAghC,YAAaA,IAAMM,IAAIN,cACvBsG,eAAgB1G,IAEpB,OAAOW,GACR,IACEJ,GAAO5mB,QAAQ3P,MAAKu2B,GAAO5mB,QAAQ3P,IAAMy2B,IAI9C,MAAMkG,GAAYjqC,EAAMw3B,QACpB,KAAA,CACI7F,WAAYyO,GACNv/B,EAA+Cu/B,IAC/C,KACN8J,MAAO7J,GAAwBx/B,EAA2Bw/B,IAAyB,KACnFpb,OAAQqb,GAAwBz/B,EAAyCy/B,IAAyB,KAClGvF,OAAQwF,GAA0B1/B,EAAuC0/B,IAA2B,OAExG,CAACH,GAA4BC,GAAuBC,GAAuBC,MAKxEzF,GAAWqL,IAAgBjpB,GAC9B0iB,GACAmD,IAAcoH,SAASrP,WAAauC,GACnC1F,GAAUkI,KAAoBlI,EAAOmM,QAGnC3K,GAAasB,IAAkBvd,GAClC8iB,GACA+C,IAAcp4B,QAAQwuB,aAAeuE,GACpC/F,GAAUsI,KAAsBtI,EAAOmM,QAGrCzN,GAAiBmR,IAAsBtqB,GAC1CwiB,GACA,CACIvJ,KAAM4M,IAAc9L,YAAYZ,iBAAiBF,MAAQ,EACzDC,SAAU2M,IAAc9L,YAAYZ,iBAAiBD,UAAYA,IAEpEuB,GAAUgI,KAA0BhI,EAAOmM,QAGzClM,GAAuBI,IAA4B9a,GACtDgjB,GACA+J,GAAUtY,YAAcoR,IAAc5kB,SAASyZ,uBAAyB0F,GACvE3F,IACOyI,IAA4Bj/B,EAAkBi/B,GAA4BzI,GAC9EwI,KAAgCxI,EAAOmM,SAIxCvQ,GAASC,IAActW,GAC1BsiB,EACAuD,IAAcxP,SAAW,UACxBxyB,GAAU0+B,IAAkB1+B,EAAO+iC,QAGjClD,GAAeqF,IAAoB/oB,GACtC2jB,GACAoJ,GAAUlP,QAAUgI,IAAcnC,eAAiBtD,GAClD3F,IACO4I,IAAyBp/B,EAAkBo/B,GAAyB5I,GACxEmJ,KAAwBnJ,EAAOmM,SAIhC5I,GAAkBkN,IAAuBlrB,GAC5CglB,GACAa,IAAcqH,aAAazS,OAAS0F,GACnC1F,GAAUwK,KAA2BxK,EAAOmM,QAG1C5X,GAAkBuQ,IAAuBvf,GAC5CqlB,GACAQ,IAAc5H,aAAaxD,OAAS2F,GACnC3F,GAAU6K,KAA2B7K,EAAOmM,OAG3CuG,GAA2BrqC,EAAMw3B,QACnC,IAAOwK,GAAgC,IAAI34B,IAAkB24B,SAAiCx0B,EAC9F,CAACw0B,MAEEkG,GAAsBF,IAA2B9qB,GACpDmtB,GACArqC,EAAMw3B,QAAQ,IAAM,IAAInuB,IAAkB05B,IAAcuH,aAAaC,gBAAkB,IAAK,IAC3F/+B,GAAQy2B,KAAoC/3B,MAAM6O,KAAKvN,GAAMs4B,OAG5D0G,GAAsBxqC,EAAMw3B,QAC9B,SAAiChqB,IAA1B2zB,GAAsC91B,EAAwB81B,IAAuB31B,SAAMgC,EAClG,CAAC2zB,MAEEyF,GAAaI,IAAkB9pB,GAClCstB,GACAxqC,EAAMw3B,QAAQ,IAAM,IAAInuB,IAAqB,IAC5CmC,GAAQ41B,KAA4B,CAAE71B,KAAM,UAAWC,OAAOs4B,QAK5D2G,GAAeC,IAAoB1qC,EAAMyd,SAC5C,IAAMwsB,GAAUC,OAASnH,IAAc5kB,SAASssB,eAAiB,OAE9DnnB,GAAcqnB,IAAmB3qC,EAAMyd,SAAiC,KAC3E,GAAIwsB,GAAUhlB,OAAQ,OAAOglB,GAAUhlB,OACvC,MAAM2lB,EAAO7H,IAAc5kB,SAAS0sB,WACpC,IAAKD,EAAM,MAAO,CAAA,EAClB,MAAM92B,EAA8B,CAAA,EAIpC,OAHAV,OAAOC,KAAKu3B,GAAMn/B,QAAS3B,IACnB8gC,EAAK9gC,GAAOvJ,QAAOuT,EAAIhK,GAAS8gC,EAAK9gC,GAAOvJ,SAE7CuT,KAEJg3B,GAAgBC,IAAqB/qC,EAAMyd,SAAqC,IAAM,IAAIgB,MAC1FyqB,GAAa8B,IAAkBhrC,EAAMyd,SAA4B,OACjEwtB,GAAW7B,IAAgBppC,EAAMyd,cAAcjQ,IAC/C09B,GAAazB,IAAkBzpC,EAAMyd,SAA4B,MAClE+rB,GAAkBxpC,EAAMgd,QAAO,IAC9B8V,GAAiBqY,IAAsBnrC,EAAMyd,SAElD,CACEmL,MAAM,EACN0G,SAAU,QAEP8b,GAAYC,IAAiBrrC,EAAMyd,SAA0D,OAC7F6tB,GAAeC,IAAoBvrC,EAAMyd,SAAwB,OAEjE+tB,GAAYC,IAAiBzrC,EAAMyd,SAA2C,MAC/EiuB,GAA0B,OAAfF,IACVG,GAAMC,IAAW5rC,EAAMyd,SAAqF,OAC5GqsB,GAAW+B,IAAgB7rC,EAAMyd,SAAS,GAC3CquB,GAAY9rC,EAAMgd,OAAO,GACzB+uB,GAAmB/rC,EAAMgd,OAA4B,OAGpDgvB,GAAeC,IAAoBjsC,EAAMyd,SAAmD,KAAA,CAC/FuB,OACAvb,IAAK,IAAIgb,OAEPytB,GAAqCF,GAAchtB,OAASA,EAAOgtB,GAAcvoC,IAAM85B,GACvF4H,GAAiBnlC,EAAM6d,YACzB,CAACzS,EAAkBF,KACf+gC,GAAkBvb,IACd,MAAMjtB,EAAM,IAAIgb,IAAIiS,EAAK1R,OAASA,EAAO0R,EAAKjtB,IAAM,IAEpD,OADAA,EAAI6M,IAAIlF,EAAIF,GACL,CAAE8T,OAAMvb,UAGvB,CAACub,KAKGze,MAAO4rC,GAAetsC,OAAQusC,abtmBYjnC,EAAgCknC,GAAU,GAC5F,MAAO9mC,EAAM+mC,GAAWtsC,EAAMyd,SAAsB,CAAEld,MAAO,EAAGV,OAAQ,IAoBxE,OAlBAG,EAAMgc,gBAAgB,KAClB,MAAMtY,EAAKyB,EAAI8X,QACf,IAAKvZ,IAAO2oC,EAAS,OACrB,MAAMtc,EAASA,KACX,MAAMxvB,EAAQmD,EAAG6oC,YACX1sC,EAAS6D,EAAG8oC,aAClBF,EAAS5b,GAAUA,EAAKnwB,QAAUA,GAASmwB,EAAK7wB,SAAWA,EAAS6wB,EAAO,CAAEnwB,QAAOV,YAGxF,GADAkwB,IAC8B,oBAAnBa,eAEP,OADAjwB,OAAOqpB,iBAAiB,SAAU+F,GAC3B,IAAMpvB,OAAOmwB,oBAAoB,SAAUf,GAEtD,MAAMY,EAAW,IAAIC,eAAeb,GAEpC,OADAY,EAASE,QAAQntB,GACV,IAAMitB,EAASI,cACvB,CAAC5rB,EAAKknC,IAEF9mC,CACX,CaglB6DknC,CAAejJ,IAClEkJ,GAAgBpjC,EAAgBiqB,KAAY,EAC5C2L,GAAY10B,KAAKmiC,MAAMxN,EAAgBuN,IACvCE,GAAepiC,KAAKmiC,MAAMvN,EAAqBsN,IAI/CrI,GAAarkC,EAAMw3B,QAAuB,KAC5C,MAAM1jB,EAAqB,GAM3B,OALAkL,EAAKvT,QAAS8B,IACV,MAAMnC,EAAKH,EAAgBsC,EAAKpC,GAC5BC,SACJ0I,EAAII,KAAK,CAAE9I,KAAIF,IAAKghC,GAAattB,IAAIxT,IAAOmC,MAEzCuG,GACR,CAACkL,EAAM7T,EAAU+gC,KAEdhI,GAAWlkC,EAAMw3B,QAAQ,KAC3B,MAAM/zB,EAAM,IAAIgb,IAIhB,OAHA4lB,GAAW54B,QAASgW,GAAUhe,EAAI6M,IAAImR,EAAMrW,GAAIqW,EAAMvW,OACrD02B,IAAYhS,KAAO,IAAInkB,QAASP,GAAQzH,EAAI6M,IAAIrF,EAAgBC,EAAKC,GAAWD,KAChF02B,IAAYnR,QAAU,IAAIhlB,QAASP,GAAQzH,EAAI6M,IAAIrF,EAAgBC,EAAKC,GAAWD,IAC7EzH,GACR,CAAC4gC,GAAYzC,GAAYz2B,IAItB0hC,GAAc7sC,EAAMw3B,QAAQ,IAAMyG,EAAYx6B,IAAKsJ,GAAQ2E,GAAgB3E,IAAO,CAACkxB,IAEnFvT,GAAiB1qB,EAAMw3B,QAAQ,KACjC,MAAM/zB,EAAM,IAAIgb,IAEhB,OADAouB,GAAYphC,QAASsB,GAAQtJ,EAAI6M,IAAIvD,EAAIjD,MAAOiD,IACzCtJ,GACR,CAACopC,KAEEpiB,GAAiBzqB,EAAMw3B,QACzB,IAAOmE,GAAqB,GAAKT,GAAiBvwB,OAAQb,GAAU4gB,GAAe3gB,IAAID,IACvF,CAACoxB,GAAkBxQ,GAAgBiR,KAEjCmR,GAAiBriB,GAAergB,OAAS,EAEzC2iC,GAAiB/sC,EAAMw3B,QAAiC,KAC1D,IAAKsV,GAAgB,OAAO,KAC5B,MAAME,EAAmC,IAA1BviB,GAAergB,OAAesgB,GAAe9L,IAAI6L,GAAe,SAAMjd,EACrF,OAAOkE,GAAmB,CACtB5H,MAAOd,EACP8I,WAAYk7B,EAAUA,EAAOl7B,YAAck7B,EAAOljC,MAAS8oB,GAAW7Y,yBACtExZ,MhBlqByB,IgBmqBzBiH,SAAU,IACVyK,UAAU,EACVC,YAAY,EACZC,UAAU,EACVG,WAAW,EACXC,YAAY,EACZC,UAAU,EACVE,eAAe,EACfE,gBAAgB,KACZyvB,MAET,CAACyK,GAAgBriB,GAAgBC,GAAgBkI,GAAW7Y,yBAA0BsoB,KAEnF+C,GAAqBplC,EAAMw3B,QAAQ,KACrC,IAAKiT,IAA0C,IAAzBA,GAAcrgC,OAAc,OAAOyiC,GACzD,MAAMI,EAAO,IAAI5jC,IACXyK,EAA0B,GAWhC,OAVA22B,GAAch/B,QAAS3B,IACnB,MAAMiD,EAAM2d,GAAe9L,IAAI9U,GAC3BiD,IAAQkgC,EAAKljC,IAAID,KACjBmjC,EAAKvhC,IAAI5B,GACTgK,EAAII,KAAKnH,MAGjB8/B,GAAYphC,QAASsB,IACZkgC,EAAKljC,IAAIgD,EAAIjD,QAAQgK,EAAII,KAAKnH,KAEhC+G,GACR,CAAC22B,GAAeoC,GAAaniB,KAE1BwiB,GAAkBltC,EAAM6d,YACzB/T,IACG,MAAM/I,EAAQ62B,GAAsB9tB,GACpC,OAAc,IAAV/I,SACUyM,IAAVzM,IAAyD,IAAlC0pB,GAAeva,QAAQpG,KAGtD,CAAC8tB,GAAuBnN,KAGtB4a,GAAqBrlC,EAAMw3B,QAAQ,KACrC,GAAIgU,GAAY,CACZ,IAAIpnB,EAAOghB,GAAmBz6B,OAAQoC,GAAQmgC,GAAgBngC,EAAIjD,QAClE,GAAI0hC,GAAWjtB,OAAQ,CACnB,MAAM4uB,EAAS,IAAI9jC,IAAImiC,GAAWjtB,QAClC6F,EAAOghB,GAAmBz6B,OAAQoC,GAAQogC,EAAOpjC,IAAIgD,EAAIjD,OAC7D,MAAW0hC,GAAWpoC,aAClBghB,EAAOghB,IAEX,OAAOhhB,EAAKzZ,OAAQoC,IAASA,EAAI2F,cACrC,CACA,OAAO0yB,GAAmBz6B,OAAQoC,GAAQmgC,GAAgBngC,EAAIjD,SAC/D,CAACs7B,GAAoB8H,GAAiB1B,KAEnC4B,GAASptC,EAAMw3B,QAAQ,KACzB,MAAMja,EAA4B,GAC9BwjB,IAAmBxjB,EAASrJ,KAAKrB,IACjCgvB,IAAuBtkB,EAASrJ,KAAKpB,IACzC,MAAMu6B,EAAa5R,GAAuB,IAAMmF,GAAc/Q,MAAQ,IAAIllB,OAAQgU,GAAMA,IAAM3V,GACxFskC,EAAc7R,GACd,IACCmF,GAAcpQ,OAAS,IAAI7lB,OAAQgU,GAAMA,IAAM3V,GAChDukC,EAAiB,IAAI9uB,IAC3B4mB,GAAmB55B,QAASsB,GAAQwgC,EAAej9B,IAAIvD,EAAIjD,MAAOiD,IAClE,MAAM8iB,EAAwBtS,EAASlI,QACnC03B,IAAgBld,EAAK3b,KAAK64B,IAC9BM,EAAW5hC,QAASkT,IAChB,MAAM5R,EAAMwgC,EAAe3uB,IAAID,GAC3B5R,GAAK8iB,EAAK3b,KAAKnH,KAEvB,MAAMyjB,EAAyB,GAC/B8c,EAAY7hC,QAASkT,IACjB,MAAM5R,EAAMwgC,EAAe3uB,IAAID,GAC3B5R,QAAOsgC,EAAWn9B,QAAQyO,IAAW6R,EAAMtc,KAAKnH,KAExD,MAAMygC,EAASnI,GAAmB16B,OAC7BoC,IAA0C,IAAlCsgC,EAAWn9B,QAAQnD,EAAIjD,aAAiBwjC,EAAYp9B,QAAQnD,EAAIjD,QAEvE2jC,EAAU5d,EAAKnN,OAAO8qB,EAAQhd,GAC9BvL,EArnBQyoB,EAACtpB,EAAuBupB,EAAmBC,KAC7D,MAAMxhB,EAA+BhI,EAAK3gB,IAAKsJ,IAC3C,MAAMzC,EAAMyC,EAAIvF,UAAYoC,EACtBW,EAAMwC,EAAIvM,UAAYqtC,IACtBC,EAAWF,EAAU7gC,EAAIjD,OAC/B,OAAIgkC,EAAiBzjC,EAAMyjC,EAAUxjC,EAAKC,GACtCwC,EAAIghC,MAAQhhC,EAAIghC,KAAO,EAAU,KAC9B1jC,EAAM0C,EAAIxM,OAAS,IAAK+J,EAAKC,KAElCyjC,EAAiB,GACvB,IAAIC,EAAa,EAKjB,GAJA7hB,EAAO3gB,QAAQ,CAAC4Y,EAAGtD,KACL,OAANsD,EAAY2pB,EAAK95B,KAAK6M,GACrBktB,GAAc5pB,IAEnB2pB,EAAK5jC,OAAS,EAAG,CACjB,IAAI8jC,EAAiB1jC,KAAKD,IAAI,EAAGojC,EAAYM,GACzCE,EAAgBH,EAAKj5B,OAAO,CAACC,EAAK+L,IAAM/L,EAAOoP,EAAKrD,GAAGgtB,KAAiB,GACxEtf,EAASuf,EAAK34B,QACd+4B,GAAU,EACd,KAAOA,GAAW3f,EAAOrkB,OAAS,GAAG,CACjCgkC,GAAU,EACV,IAAK,IAAI9tB,EAAI,EAAGA,EAAImO,EAAOrkB,OAAQkW,GAAK,EAAG,CACvC,MAAMS,EAAI0N,EAAOnO,GACXvT,EAAMqX,EAAKrD,GACXzW,EAAMyC,EAAIvF,UAAYoC,EACtBW,EAAMwC,EAAIvM,UAAYqtC,IACtBQ,EAAQF,EAAgB,EAAKD,EAAkBnhC,EAAIghC,KAAmBI,EAAgB,EAC5F,GAAIE,EAAQ/jC,GAAO+jC,EAAQ9jC,EAAK,CAC5B,MAAM+jC,EAAQD,EAAQ/jC,EAAMA,EAAMC,EAClC6hB,EAAOrL,GAAKutB,EACZJ,EAAiB1jC,KAAKD,IAAI,EAAG2jC,EAAiBI,GAC9CH,GAAiBphC,EAAIghC,KACrBtf,EAASA,EAAO9jB,OAAQ4jC,GAAQA,IAAQxtB,GACxCqtB,GAAU,EACV,KACJ,CACJ,CACJ,CACA3f,EAAOhjB,QAASsV,IACZ,MAAMhU,EAAMqX,EAAKrD,GACjBqL,EAAOrL,GACHotB,EAAgB,EACV3jC,KAAK2Y,MAAO+qB,EAAkBnhC,EAAIghC,KAAmBI,GACpDphC,EAAIvF,UAAY,IAEnC,CACA,OAAO4kB,GAskBYshB,CAAcD,EAAStB,GAAe7oB,IAC/CkrB,EAAa3e,EAAKzlB,OAASmT,EAASnT,QAAU2iC,GAAiB,EAAI,IAAMvc,EAAMpmB,OAAS,EACxF+T,EAA0B,GAChC,IAAIswB,EAAI,EACJC,EAAa,EACjBjB,EAAQhiC,QAAQ,CAACsB,EAAKgU,KAClB,MAAMxgB,EAAQ0kB,EAAOlE,GACf4tB,EAAS5tB,EAAI8O,EAAKzlB,OAClBwkC,EAAU7tB,GAAK8O,EAAKzlB,OAASojC,EAAOpjC,OAC1C+T,EAAQjK,KAAK,CACTnH,MACAxM,QACAw6B,OAAQ4T,EAAS,OAASC,EAAU,QAAU,KAC9CxtB,OAAQutB,EAASD,EAAa,EAC9BD,IACAI,WAAYF,GAAU5tB,IAAM8O,EAAKzlB,OAAS,EAC1C0kC,aAAcF,GAAW7tB,IAAM8O,EAAKzlB,OAASojC,EAAOpjC,SAEpDukC,IAAQD,GAAcnuC,GAC1BkuC,GAAKluC,IAET,IAAIwuC,EAAc,EAClB,IAAK,IAAIhuB,EAAI5C,EAAQ/T,OAAS,EAAG2W,GAAK,GACR,UAAtB5C,EAAQ4C,GAAGga,OADsBha,GAAK,EAE1C5C,EAAQ4C,GAAGK,OAAS2tB,EACpBA,GAAe5wB,EAAQ4C,GAAGxgB,MAE9B,MAAO,CAAE4d,UAAS6wB,WAAYP,EAAGD,aAAYS,UAAWpf,EAAKzlB,OAAQ8kC,WAAY1e,EAAMpmB,SACxF,CACC22B,GACAc,GACAjB,GACAnF,GACA4J,GACA0H,GACAZ,GACA7oB,KAGE6rB,GAA2BnvC,EAAMw3B,QAAQ,KAC3C,MAAM/zB,EAAM,IAAIgb,IAGhB,OAFA2uB,GAAOjvB,QAAQ1S,QAASiT,GAAMjb,EAAI6M,IAAIoO,EAAE3R,IAAIjD,MAAO4U,EAAE3R,MACjDggC,IAAgBtpC,EAAI6M,IAAItH,EAAuB+jC,IAC5CtpC,GACR,CAAC2pC,GAAOjvB,QAAS4uB,KAEdzH,GAAYtlC,EAAM6d,YACnB/T,GACG4gB,GAAe9L,IAAI9U,IAAWqlC,GAAyBvwB,IAAI9U,GAC/D,CAAC4gB,GAAgBykB,KAKfC,GAAgBpvC,EAAMw3B,QAAQ,KAChC,MAAM1jB,EAAqE,GAS3E,OARAqlB,GAAYtO,MAAMpf,QAASoE,IACvB,MAAM9C,EAAM2d,GAAe9L,IAAI/O,EAAK/F,OACpC,IAAKiD,IAA0B,IAAnBA,EAAImF,WAAsB,OACtC,MAAM0mB,EAAWrnB,GAAyBxE,GAAKa,KAAMksB,GAAOA,EAAG/4B,QAAU8O,EAAK+oB,UAC9E,IAAKA,EAAU,OACf,MAAMtM,EAAKsM,EAAS5oB,iBAAiBH,EAAM9C,GACvCuf,GAAIxY,EAAII,KAAK,CAAEnH,MAAKuf,SAErBxY,GACR,CAACqlB,GAAYtO,MAAOH,KAEjBkK,GAAoB50B,EAAMw3B,QAC5B,KAAO2B,GAAYvE,mBAAqB,IAAInxB,IAAKqN,GAAM5D,OAAO4D,GAAGyD,QAAQ5J,OAAQmG,GAAY,KAANA,GACvF,CAACqoB,GAAYvE,oBAGXya,GAAqBrvC,EAAMw3B,QAAQ,KACxB2B,GAAYwE,gCAAkC0H,GAAqBD,IACpEz6B,OAAQoC,IAA2B,IAAnBA,EAAImF,YAAqC,YAAbnF,EAAIxB,MAC7D,CAAC4tB,GAAYwE,gCAAiC0H,GAAoBD,KAE/DkK,GAAkBtvC,EAAMw3B,QAAQ,KAClC,GAA6B,IAAzB4X,GAAchlC,QAA6C,IAA7BwqB,GAAkBxqB,OAAc,OAAOi6B,GACzE,MAAMkL,EAAoD,SAAxCpW,GAAYC,eAAiB,OACzCoW,EAA+D,SAAnDrW,GAAYsW,0BAA4B,OACpDC,EAAc7L,GAAO5mB,QAAQ3P,IAC7BqiC,EAAW/a,GAAkBnxB,IAAKwM,IACpC,MAAM2/B,EAAU3/B,EAAON,cAejB8e,EAdY4gB,GAAmB5rC,IAAKsJ,IACtC,GAAIA,EAAI8iC,sBAAuB,CAC3B,MAAMC,EAAS/iC,EAAI8iC,sBAAsB5/B,EAAQlD,EAAK2iC,GACtD,OAAOI,EAAS,CAAE/iC,MAAKuf,GAAIwjB,GAAW,IAC1C,CAQA,MAAO,CAAE/iC,MAAKuf,GAPsBA,CAACvrB,EAAOmK,KACxC,GAAIlB,EAAMjJ,GAAQ,OAAO,EAEzB,IAAmC,IADjBiN,GAAuBF,GAAkB/M,EAAOmK,EAAK6B,EAAK2iC,IAAc//B,cAC5EO,QAAQ0/B,GAAiB,OAAO,EAE9C,OAAgC,KADH,iBAAV7uC,EAAqB,GAAKmM,OAAOnM,GAAO4O,eAChDO,QAAQ0/B,OAIFjlC,OAAOC,SAChC,OAAQM,GAAWujB,EAAO0C,KAAK,EAAGpkB,MAAKuf,QAASA,EAAGjf,GAAanC,EAAK6B,EAAK2iC,GAAcxkC,EAAK6B,EAAK2iC,MAEtG,OAAOrL,GAAW15B,OAAO,EAAGO,UACxB,GAAIkkC,GAAchlC,OAAS,EAAG,CAC1B,MAAM2lC,EAAUX,GAAc3rC,IAAI,EAAGsJ,MAAKuf,QACtCA,EAAGjf,GAAanC,EAAK6B,EAAK2iC,GAAcxkC,EAAK6B,EAAK2iC,IAGtD,KADaH,EAAWQ,EAAQ56B,MAAMvK,SAAWmlC,EAAQ5e,KAAKvmB,UACnD,OAAO,CACtB,CACA,GAAI+kC,EAASvlC,OAAS,EAAG,CACrB,MAAM2lC,EAAUJ,EAASlsC,IAAK6oB,GAAOA,EAAGphB,IACxC,OAAOskC,EAAWO,EAAQ56B,MAAMvK,SAAWmlC,EAAQ5e,KAAKvmB,QAC5D,CACA,OAAO,KAEZ,CACCy5B,GACA+K,GACAxa,GACAya,GACAlW,GAAYC,cACZD,GAAYsW,2BAKVO,GAAiBhwC,EAAMw3B,QAAQ,KACjC,MAAMkY,EAAc7L,GAAO5mB,QAAQ3P,IAC7B2iC,EAAUnV,GACXnwB,OAAQkF,GAASA,EAAKyF,MAAQzF,EAAK/F,QAAUd,GAC7CvF,IAAKoM,IACF,MAAM9C,EAAM2d,GAAe9L,IAAI/O,EAAK/F,OACpC,OAAKiD,IAAwB,IAAjBA,EAAIkF,SACT,CACHlF,MACAmjC,IAAmB,SAAdrgC,EAAKyF,MAAkB,EAAK,EACjC66B,WAAYpjC,EAAIqjC,gBAAkB3gC,GAAqB1C,EAAIxB,OAJpB,OAO9CZ,OAAOC,SACZ,OAAuB,IAAnBqlC,EAAQ7lC,OAAqB,KAC1B,CAACwG,EAAgBC,KACpB,IAAK,IAAIkQ,EAAI,EAAGA,EAAIkvB,EAAQ7lC,OAAQ2W,GAAK,EAAG,CACxC,MAAMhU,IAAEA,EAAGmjC,IAAEA,EAAGC,WAAEA,GAAeF,EAAQlvB,GACnCvS,EAAKnB,GAAauD,EAAE1F,IAAK6B,EAAK2iC,GAC9BjhC,EAAKpB,GAAawD,EAAE3F,IAAK6B,EAAK2iC,GAC9BtjB,EAAS+jB,EACX3hC,EACAC,EACA,CAAErD,GAAIwF,EAAExF,GAAItB,MAAOiD,EAAIjD,MAAO/I,MAAOyN,EAAItD,IAAK0F,EAAE1F,IAAKoC,IAAKoiC,GAC1D,CAAEtkC,GAAIyF,EAAEzF,GAAItB,MAAOiD,EAAIjD,MAAO/I,MAAO0N,EAAIvD,IAAK2F,EAAE3F,IAAKoC,IAAKoiC,IAE9D,GAAe,IAAXtjB,EAAc,OAAOA,EAAS8jB,CACtC,CACA,OAAO,IAEZ,CAACpV,GAAWpQ,KAET2lB,GAAcrwC,EAAM6d,YACrByD,GACQ0uB,GACE1uB,EACF7d,IAAI,CAACge,EAAOuB,KAAK,CAAQvB,QAAOuB,WAChC1N,KAAK,CAAC1E,EAAGC,IAAMm/B,GAAep/B,EAAE6Q,MAAO5Q,EAAE4Q,QAAU7Q,EAAEoS,MAAQnS,EAAEmS,OAC/Dvf,IAAKoM,GAASA,EAAK4R,OAJIH,EAMhC,CAAC0uB,KAKCpU,GAAuB57B,EAAMw3B,QAC/B,KAAA,IAAY9iB,MAAmC+tB,KAC/C,CAACA,KAEC6N,IAAqBvU,IAAsB3oB,OAAOC,KAAK6Y,IAAkB9hB,OAAS,EAElFmmC,GAAkBvwC,EAAM6d,YACzBwN,IACG,MAAMyiB,EAAWhD,GAAelsB,IAAIyM,EAAKjgB,IACzC,YAAiBoC,IAAbsgC,EAA+BA,EAC/BxL,GACOA,GAAyB,CAC5B/2B,KAAM,QACNH,GAAIigB,EAAKjgB,GACT0f,MAAOO,EAAKP,MACZQ,OAAQD,EAAKC,OACbC,cAAeF,EAAKE,cACpBC,YAAaH,EAAKG,YAClBC,cAAeJ,EAAKI,cACpBljB,SAAU,GACVioC,QAAS,GACTnb,YAAY,KAGqB,IAAlC+M,IAAwC/W,EAAKP,MAAQsX,IAEhE,CAAC0I,GAAgBxI,GAA0BF,KAGzCqO,GAAYzwC,EAAMw3B,QAAQ,KAC5B,MAAMgN,EAAY,IAAI/lB,IAChBkqB,EAAa,IAAIlqB,IACvB,IAAKquB,GAAgB,CACjB,MAAMv3B,EAAS86B,GAAYf,IAM3B,MAAO,CAAEoB,YAL4Bn7B,EAAO9R,IAAKge,IAC7C,MAAM4J,EAAwB,CAAE9f,KAAM,OAAQH,GAAIqW,EAAMrW,GAAI0f,MAAO,EAAGQ,OAAQ,MAE9E,OADAkZ,EAAUl0B,IAAImR,EAAMrW,GAAIigB,GACjB,CAAEjgB,GAAIqW,EAAMrW,GAAIG,KAAM,OAAQL,IAAKuW,EAAMvW,IAAKmgB,OAAMP,MAAO,KAEhD4Z,aAAcnvB,EAAQivB,YAAWmE,aAAYgI,KAAM,GAC7E,CACA,MAAMjB,EAAc7L,GAAO5mB,QAAQ3P,IACnC,IAAIqjC,EAAOnmB,GAAe8kB,GAAiB7kB,GAAgBC,GAAgBglB,GAC3E,MAAMkB,EAAe9V,GAAUltB,KAAMiC,GAASA,EAAK/F,QAAUd,GAAyB6G,EAAKyF,MAiB3Fq7B,EVr5BqBE,EACzB9kB,EACA+kB,EACAC,KAEA,MAAMC,EAAYA,CAACnlB,EAA2Bf,KAC1C,MAAMqlB,EAAaW,EAAgBA,EAAchmB,GAAS,KACpDvV,EAAS46B,EACTtkB,EACKpoB,IAAI,CAAC4nB,EAAMrI,KAAK,CAAQqI,OAAMrI,WAC9B1N,KAAK,CAAC1E,EAAGC,IAAMs/B,EAAWv/B,EAAEya,KAAMxa,EAAEwa,OAASza,EAAEoS,MAAQnS,EAAEmS,OACzDvf,IAAKoM,GAASA,EAAKwb,MACxBQ,EAYN,OAXAtW,EAAO9J,QAAS4f,IACZ,GAAIA,EAAKK,YAAYthB,OAAS,EAAG,CAC7BihB,EAAKK,YAAcslB,EAAU3lB,EAAKK,YAAaZ,EAAQ,GACvD,MAAMc,EAA6B,GACnCP,EAAKK,YAAYjgB,QAASuoB,GAAUA,EAAMpI,YAAYngB,QAASU,GAAMyf,EAAY1X,KAAK/H,KACtFkf,EAAKO,YAAcA,CACvB,MACIP,EAAKM,OAASolB,EAAW1lB,EAAKM,QAC9BN,EAAKO,YAAcP,EAAKM,SAGzBpW,GAEX,OAAOy7B,EAAUjlB,EAAO,IU23Bb8kB,CAAcF,EAhBE7lB,IACnB,MAAMhhB,EAAQ2gB,GAAeK,GACvB/d,EAAM2d,GAAe9L,IAAI9U,GAC/B,IAAKiD,EAAK,OAAO,KACjB,MAAM8tB,EAAW+V,GAAgB9V,GAAUltB,KAAMiC,GAASA,EAAK/F,QAAUA,GAAS+F,EAAKyF,MACvF,IAAKulB,EAAU,OAAO,KACtB,MAAMsV,EAAapjC,EAAIqjC,gBAAkB3gC,GAAqB1C,EAAIxB,MAC5D2kC,EAAwB,SAAlBrV,EAASvlB,MAAkB,EAAK,EAC5C,MAAO,CAAC1E,EAAqBC,IACzBs/B,EACIv/B,EAAE4a,YACF3a,EAAE2a,YACF,CAAEpgB,GAAIwF,EAAExF,GAAItB,QAAO/I,MAAO6P,EAAE4a,YAAatgB,IAAK0F,EAAEgb,YAAY,IAAI1gB,IAAKoC,IAAKoiC,GAC1E,CAAEtkC,GAAIyF,EAAEzF,GAAItB,QAAO/I,MAAO8P,EAAE2a,YAAatgB,IAAK2F,EAAE+a,YAAY,IAAI1gB,IAAKoC,IAAKoiC,IAC1EQ,GAE8BG,IAC1C,MAAMK,EVl2BkBO,EAC5BllB,EACAsJ,EACAmP,EACAmE,KAEA,MAAM70B,EAAuB,GACvBo9B,EAAQA,CAACrlB,EAA2BkM,KACtClM,EAAMpgB,QAAS4f,IACX,MAAM/mB,EAAW+wB,EAAWhK,GACtB8lB,EA3BSC,EACvB/lB,EACAgK,KAAmB,CAEnB9pB,KAAM,QACNH,GAAIigB,EAAKjgB,GACT0f,MAAOO,EAAKP,MACZQ,OAAQD,EAAKC,OACbC,cAAeF,EAAKE,cACpBC,YAAaH,EAAKG,YAClBC,cAAeJ,EAAKI,cACpBljB,SAAU8iB,EAAKK,YAAYthB,OAAS,EAAIihB,EAAKK,YAAYjoB,IAAKib,GAAMA,EAAEtT,IAAMigB,EAAKM,OAAOloB,IAAK4tC,GAAMA,EAAEjmC,IACrGolC,QAASnlB,EAAKO,YAAYnoB,IAAK0I,GAAMA,EAAEf,IACvCiqB,eAc0B+b,CAAY/lB,EAAM/mB,GACpCkgC,EAAUl0B,IAAI+a,EAAKjgB,GAAI+lC,GACvBxI,EAAWr4B,IAAI+a,EAAKjgB,GAAIigB,GACpB0M,GACAjkB,EAAII,KAAK,CAAE9I,GAAIigB,EAAKjgB,GAAIG,KAAM,QAASL,IAAK,KAAMmgB,KAAM8lB,EAAWrmB,MAAOO,EAAKP,MAAO4d,MAAOrd,IACjG,MAAMimB,EAAevZ,GAAWzzB,EAC5B+mB,EAAKK,YAAYthB,OAAS,EAC1B8mC,EAAM7lB,EAAKK,YAAa4lB,GAExBjmB,EAAKM,OAAOlgB,QAAS8lC,IACjB,MAAMC,EAA4B,CAAEjmC,KAAM,OAAQH,GAAImmC,EAAKnmC,GAAI0f,MAAOO,EAAKP,MAAQ,EAAGQ,OAAQD,EAAKjgB,IACnGo5B,EAAUl0B,IAAIihC,EAAKnmC,GAAIomC,GACnBF,GACAx9B,EAAII,KAAK,CAAE9I,GAAImmC,EAAKnmC,GAAIG,KAAM,OAAQL,IAAKqmC,EAAKrmC,IAAKmgB,KAAMmmB,EAAU1mB,MAAOO,EAAKP,MAAQ,SAM7G,OADAomB,EAAMnlB,GAAO,GACNjY,GUq0BiBm9B,CAAiBN,EAAMJ,GAAiB/L,EAAWmE,GACvE,MAAO,CAAE+H,cAAahM,aAAc5Y,GAAkB6kB,GAAOnM,YAAWmE,aAAYgI,SACrF,CAAC7D,GAAgBwC,GAAiBe,GAAa5lB,GAAgBC,GAAgBoQ,GAAWyV,MAEvFG,YAAEA,GAAWhM,aAAEA,GAAYF,UAAEA,GAASmE,WAAEA,IAAe8H,GAIvDgB,GAAmBf,GAAYtmC,OAC/BsnC,GAAWza,KAAeyU,GAC1BnV,GAAYU,GAAazsB,KAAKD,IAAI,EAAGC,KAAKmnC,KAAKF,GAAmBjnC,KAAKD,IAAI8rB,GAAgBD,SAAU,KAAO,EAC5GD,GAAOc,GAAa5sB,EAAMgsB,GAAgBF,KAAM,EAAGI,GAAY,GAAK,EAE1Ev2B,EAAMic,UAAU,KACRgb,IAAcZ,GAAgBF,OAASA,IACvCqR,GAAmB,IAAKnR,GAAiBF,WAE9C,CAACc,GAAYZ,GAAiBF,GAAMqR,KAEvC,MAAM5C,GAAY5kC,EAAMw3B,QACpB,IACIka,GACMhB,GAAYr7B,MAAM8gB,GAAOE,GAAgBD,UAAWD,GAAO,GAAKE,GAAgBD,UAChFsa,GACV,CAACA,GAAagB,GAAUvb,GAAME,GAAgBD,WAK5Cwb,GAAmB5xC,EAAMw3B,QAAQ,KACnC,IAAK8Y,IAA6C,WAAxB5N,GAAkC,OAAO,KACnE,MAAMmP,EAAgBnN,GAAajhC,IAAKge,GAAUA,EAAMvW,KACxD,OAAO+gB,GAAc4lB,EAAe3lB,GAAkBxB,GAAgBkR,GAAsBiI,GAAO5mB,QAAQ3P,MAC5G,CAACgjC,GAAmB5N,GAAqBgC,GAAcxY,GAAkBxB,GAAgBkR,KAEtFkW,GAAuB9xC,EAAMw3B,QAC/B,IAAM,IAAI/Y,IACV,CAACmmB,GAAW1Y,GAAkB0P,KAE5BmW,GAAsBrJ,IACxB,IAAK4H,IAA6C,WAAxB5N,GAAkC,OAC5D,IAAIsP,EAASF,GAAqBlzB,IAAI8pB,EAAMt9B,IAW5C,OAVK4mC,IACDA,EAAS/lB,GACLyc,EAAM9c,YAAYnoB,IAAK0I,GAAMA,EAAEjB,KAC/BghB,GACAxB,GACAkR,GACAiI,GAAO5mB,QAAQ3P,KAEnBwkC,GAAqBxhC,IAAIo4B,EAAMt9B,GAAI4mC,IAEhCA,GAKLC,GAAUjyC,EAAMw3B,QAAQ,KAC1B,MAAM0a,EAAuB,GACvBC,EAA0B,GAC1BC,EAAoB,GAC1B,IAAIjxB,EAAQ,EACRkxB,EAAU/S,GAAcC,GAAyBmM,GAqBrD,OApBA9G,GAAUn5B,QAASo5B,IACf,IAAI9kB,EAAImf,GACR,GAAIG,GAA4B,SAAZwF,EAAGt5B,MAAmBs5B,EAAG35B,IAAK,CAC9C,MAAMkhB,EAASiT,EAAa,CAAEj0B,GAAIy5B,EAAGz5B,GAAIusB,MAAOkN,EAAG35B,IAAKwhC,mBACzC,SAAXtgB,EAAmBimB,GAAU,EACN,iBAAXjmB,GAAuBA,EAAS,IAAGrM,EAAIqM,EAC3D,CACA,IAAIjgB,EAAI,EACR,GAAgB,SAAZ04B,EAAGt5B,MAAmBs2B,IAAyBqG,GAAqBn+B,IAAI86B,EAAGz5B,KAAOy5B,EAAG35B,IAAK,CAC1F,MAAMonC,EAAKxQ,GACLA,GAAqB,CAAE12B,GAAIy5B,EAAGz5B,GAAIF,IAAK25B,EAAG35B,MAl9B5B,IAo9BT,SAAPonC,EAAeD,GAAU,EACxBlmC,EAAImmC,CACb,CACAJ,EAAWh+B,KAAK6L,GAChBoyB,EAAcj+B,KAAK/H,GACnBimC,EAAQl+B,KAAKiN,GACbA,GAASpB,EAAI5T,IAEV,CAAE+lC,aAAYC,gBAAeC,UAASjxB,QAAOkxB,YACrD,CACCzN,GACA1F,GACAG,EACAqN,GACA7K,GACAC,GACAoG,GACA5I,EACAC,EACAmM,KAGE6G,IAAWN,GAAQI,QAczBryC,EAAMic,UAAU,KACZ,IAAKuvB,GAAY,OAGjB,MAAM3hB,EAAQlpB,OAAO6a,WAAW,KACvB+nB,GAAQtmB,SACbwI,GAAiB,CACbO,YAAaud,GAAQtmB,QACrBrZ,QAAS4nC,GACT5lB,OAAQA,IAAM6lB,GAAc,SAEjC,IACH,MAAO,IAAM9qC,OAAOopB,aAAaF,IAClC,CAAC2hB,KAEJ,MAAMgH,GAAexyC,EAAMw3B,QAAQ,KAC/B,MAAM9e,EAAQksB,GAAUx6B,OACxB,IAAKmoC,IAAqB,IAAV75B,EAAa,MAAO,CAAEta,MAAO,EAAGC,IAAKqa,GACrD,MAAM+5B,EA3gCQ,EA2gCmBvT,GAC3BwT,EAAUloC,KAAKD,IAAI,EAAGu/B,GAAY8C,GAAe6F,GACjDE,EAAa7I,GAAYt/B,KAAKD,IAAI6hC,GAAgBlN,IAAauT,GAC/DL,QAAEA,GAAYH,GACpB,IAAIW,EAAK,EACLC,EAAKn6B,EAAQ,EACjB,KAAOk6B,EAAKC,GAAI,CACZ,MAAMC,EAAOF,EAAKC,GAAO,EACrBT,EAAQU,GAAOb,GAAQC,WAAWY,GAAOb,GAAQE,cAAcW,GAAOJ,EAASE,EAAKE,EAAM,EACzFD,EAAKC,CACd,CACA,MAAM10C,EAAQw0C,EACd,IAAIv0C,EAAMD,EACV,KAAOC,EAAMqa,GAAS05B,EAAQ/zC,GAAOs0C,GAAYt0C,GAAO,EACxD,MAAO,CAAED,QAAOC,QACjB,CAACk0C,GAAS3N,GAAUx6B,OAAQ0/B,GAAWsC,GAAgBlN,GAAW0N,GAAcqF,KAE7Ec,GAAe/yC,EAAM6d,YAAY,KAC9BgmB,GAAO5mB,QAAQs1B,UAChBzG,GAAU7uB,UACd6uB,GAAU7uB,QAAUtc,OAAOqyC,sBAAsB,KAC7ClH,GAAU7uB,QAAU,EAChBumB,GAAYvmB,SAAS4uB,GAAarI,GAAYvmB,QAAQ6sB,gBAE/D,IAEH9pC,EAAMic,UACF,IAAM,KACE6vB,GAAU7uB,SAAStc,OAAOsyC,qBAAqBnH,GAAU7uB,UAEjE,IAKJ,MAAMqqB,GAAoBtnC,EAAM6d,YAC5B,CAACzS,EAAkBF,MACVA,KACAm2B,IACEA,GAAgB,CAAEj2B,KAAIF,MAAKiT,QAASinB,GAAoB93B,IAAKu2B,GAAO5mB,QAAQ3P,OAEvF,CAAC+zB,GAAiB+D,KAGhB8N,GAAsBlzC,EAAMw3B,QAAQ,KACRwJ,GACvB4D,GACIj6B,OAAQk6B,GAAmB,SAAZA,EAAGt5B,MAAmBs5B,EAAG35B,KACxCzH,IAAKohC,IAAE,CAAQz5B,GAAIy5B,EAAGz5B,GAAIF,IAAK25B,EAAG35B,OACvCw5B,IACQ/5B,OAAQ8W,GAAU6lB,GAAkB7lB,EAAMrW,GAAIqW,EAAMvW,MAAMzH,IAAKge,GAAUA,EAAMrW,IAC9F,CAAC41B,GAA8B4D,GAAWF,GAAc4C,KAErD6L,GAAyBnzC,EAAMw3B,QACjC,IAAM0b,GAAoBn+B,OAAe,CAACC,EAAK5J,IAAO4J,GAAO4xB,GAAY78B,IAAIqB,GAAM,EAAI,GAAI,GAC3F,CAAC8nC,GAAqBtM,KAEpBwM,GAAwBF,GAAoB9oC,OAAS,GAAK+oC,KAA2BD,GAAoB9oC,OACzGipC,GAAyBF,GAAyB,IAAMC,GAExDE,GAAkBtzC,EAAM6d,YACzB01B,IACGvM,GAAgBtW,IACZ,MAAM5S,EAAOy1B,EAAQ7iB,GACrB,MhBlkCoB8iB,EAAC5iC,EAA6BC,KAC9D,GAAID,EAAEpF,IAAIjG,OAASsL,EAAErF,IAAIjG,KAAM,OAAO,EACtC,IAAIkuC,GAAQ,EAIZ,OAHA7iC,EAAEpF,IAAIC,QAASL,IACNyF,EAAErF,IAAIzB,IAAIqB,KAAKqoC,GAAQ,KAEzBA,GgB4jCYD,CAAqB,CAAmBhoC,IAAKklB,GAAQ,CAAmBllB,IAAKsS,IAAU4S,EAAO5S,KAG7G,CAACkpB,KAGCI,GAAapnC,EAAM6d,YACrB,CAACrS,EAAqB07B,GAAa,EAAMC,GAAiB,KACtDmM,GAAiB5iB,IACb,MAAM5S,EAAOqpB,EAAiB,IAAI99B,IAAsB,IAAIA,IAAIqnB,GAMhE,GALAllB,EAAIC,QAASL,IACL87B,EACII,GAAkBl8B,EAAI84B,GAAStlB,IAAIxT,KAAM0S,EAAKpS,IAAIN,GACnD0S,EAAK41B,OAAOtoC,KAEnB81B,IAA+BpjB,EAAKvY,KAAO,EAAG,CAC9C,MAAMouC,EAASnoC,EAAIA,EAAIpB,OAAS,GAChC,OAAO,IAAIf,IAAkB69B,GAAcppB,EAAK/T,IAAI4pC,GAAU,CAACA,GAAU,GAC7E,CACA,OAAO71B,KAGf,CAACw1B,GAAiBhM,GAAmBpD,GAAUhD,KAGnDlhC,EAAMic,UAAU,KACZ,GAAIqlB,IAAoD,IAArBsF,GAAYrhC,KAAY,OAC3D,IAAI6oC,GAAU,EACd,MAAMtwB,EAAO,IAAIzU,IACjBu9B,GAAYn7B,QAASL,IACb84B,GAASn6B,IAAIqB,GAAK0S,EAAKpS,IAAIN,GAC1BgjC,GAAU,IAEfA,GAASpH,GAAelpB,IAC7B,CAAComB,GAAU5C,GAA6BsF,GAAaI,KAExD,MAAM4M,GAAsBA,KACGxM,GAAW8L,IAAlCE,KAsCFnX,GAAaA,CAACnyB,EAAes8B,EAAkCyN,GAAgB,KACjF,MAAM9mC,EAAMu4B,GAAUx7B,GACtB,IAAKiD,IAAwB,IAAjBA,EAAIkF,UAAsBopB,GAAsB,OAC5D,MAAMpe,EAAU6d,GAAUltB,KAAMiC,GAASA,EAAK/F,QAAUA,GACxD,IAAIgU,EAQA6Z,EAPJ,QAAkBnqB,IAAd44B,EAAyB,CACzB,MAAM8D,EAAQn9B,EAAI+yB,cAAgBA,GAC5B9c,EAAQknB,EAAMh6B,QAAQ+M,GAAS3H,MAAQ,MAC7CwI,EAAOosB,GAAOlnB,EAAQ,GAAKknB,EAAM9/B,OACrC,MACI0T,EAAOsoB,EAGPyN,IAAkB9T,IAClBpI,EAAQmD,GAAUnwB,OAAQkF,GAASA,EAAK/F,QAAUA,GAC9CgU,IACA6Z,EAAQ1a,EACF6d,GAAUr3B,IAAKoM,GAAUA,EAAK/F,QAAUA,EAAQ,CAAEA,QAAOwL,KAAMwI,GAASjO,GACxE8nB,EAAMjV,OAAO,CAAC,CAAE5Y,QAAOwL,KAAMwI,OAEvC6Z,EAAQ7Z,EAAO,CAAC,CAAEhU,QAAOwL,KAAMwI,IAAU,GAE7CqoB,GAAaxO,IAKXmc,GAAgBv1B,IACd8hB,IAAuBl/B,EAAkBk/B,GAAuB9hB,IAGlEw1B,GAAiB9uB,IACfqb,IAAuBn/B,EAAkBm/B,GAAuBrb,IA0BlE6gB,GAAkBA,CAACliC,EAA8E,MACnG,MAAMgc,EAAiBhc,EAAQgc,iBAAkB,EAC3Co0B,EAAU5G,GAAOjvB,QAAQxT,OAC1BspC,KAAQpqC,EAAgBoqC,EAAGlnC,IAAIjD,QAAYlG,EAAQua,UAAqD,IAA1Cva,EAAQua,QAAQjO,QAAQ+jC,EAAGlnC,IAAIjD,SAElG,GAAuB,IAAnBkqC,EAAQ5pC,OAAc,OAC1B,MAAM4hB,EAAOsX,GAAQrmB,QACfi3B,EAAWloB,GAA0B,oBAAXrrB,OAAyBA,OAAOwzC,iBAAiBnoB,GAAQ,KACnFooB,EAAaF,GAAUE,YAAc,aACrCC,EAAW,YAAYD,IACvBE,EAAa,YAAYF,IACzBG,EAAS7P,GAAarvB,MAAM,EAAG,KAC/Bq6B,EAAc7L,GAAO5mB,QAAQ3P,IAC7BwQ,EAAO,IAAKwF,IAClB0wB,EAAQvoC,QAAQ,EAAGsB,UACf,IAAIxC,EAAMqV,EAAiBrF,GAAYxN,EAAI+E,YAAc/E,EAAIjD,MAAOwqC,GAAc,GAAK,EACvFC,EAAO9oC,QAASgW,IACZ,MAAM1gB,EAAQsM,GAAaoU,EAAMvW,IAAK6B,EAAK2iC,GACrCvwC,EAAO6O,GAAuBF,GAAkB/M,EAAO0gB,EAAMvW,IAAK6B,EAAK2iC,EAAajuB,EAAMrW,KAC1FiZ,EAAI9J,GAAYpb,EAAMk1C,GAAY,GACpChwB,EAAI9Z,IAAKA,EAAM8Z,KAEvBvG,EAAK/Q,EAAIjD,OAASO,EAAMG,KAAKmnC,KAAKpnC,GAAMwC,EAAIvF,UAAYoC,EAA0BmD,EAAIvM,UAAYqtC,OAEtGlD,GAAgB7sB,GAChBi2B,GAAcj2B,IA4DZkV,GAAkBhzB,EAAM6d,YAAY,KACtCstB,GAAoBza,GAAUA,EAAK9H,KAAO,CAAEA,MAAM,EAAO0G,SAAU,MAASoB,IAC7E,IAIG8jB,GAAoB9uB,KACjBA,EAAO+uB,OAAOjiC,WACS,SAAxBkT,EAAOgvB,QAAQnpC,QACZu3B,IAAiBA,GAAepd,KAGrCmjB,GAAoBA,CAACz9B,EAAkBtB,KACzC,MAAMoB,EAAMg5B,GAAStlB,IAAIxT,GACnB2B,EAAMu4B,GAAUx7B,GACtB,IAAKoB,IAAQ6B,EAAK,OAClB,MAAM2Y,EAAS4jB,GAAgBl+B,EAAItB,EAAOoB,EAAKs5B,GAAU5lB,IAAIxT,IAAO,CAAEG,KAAM,OAAQH,KAAI0f,MAAO,EAAGQ,OAAQ,OACrGkpB,GAAiB9uB,KACtBslB,GAAe,CAAE5/B,KAAItB,UACrBs/B,GAAa1jB,EAAO3kB,OACpB0oC,GAAe,CAAEr+B,KAAItB,YAiBnBg/B,GAAmBA,CACrB19B,EACAtB,EACAi/B,GAAsB,EACtB4L,EAAmF,SAEnF,IAAKzL,IAAeA,GAAY99B,KAAOA,GAAM89B,GAAYp/B,QAAUA,EAAO,OAC1E,MAAMoB,EAAMg5B,GAAStlB,IAAIxT,GACnB2B,EAAMu4B,GAAUx7B,GAEtB,GADAkhC,GAAe,MACV9/B,GAAQ6B,EAAb,CACA,IAAKg8B,EAAqB,CACtB,MAAM2G,EAAc7L,GAAO5mB,QAAQ3P,IAC7BlB,EAASW,EAAI6nC,YACb7nC,EAAI6nC,YAAY3J,GAAW//B,EAAK6B,EAAK2iC,GhBztCzBmF,EAACtnC,EAAUR,KACrC,OAAQA,EAAIxB,MACR,IAAK,SAAU,CACX,GAAY,KAARgC,GAAcvD,EAAMuD,GAAM,OAAO,KACrC,MAAMmD,EAAI7E,OAAO0B,GACjB,OAAO1B,OAAOC,MAAM4E,GAAKnD,EAAMmD,CACnC,CACA,IAAK,UACD,OAAO9F,QAAQ2C,GACnB,IAAK,OACL,IAAK,WACD,MAAY,KAARA,GAAcvD,EAAMuD,GAAa,KAC3B5B,EAAO4B,IACLA,EAEhB,QACI,OAAOA,IgB0sCDsnC,CAAe5J,GAAWl+B,GAC1B+nC,EAAeznC,GAAanC,EAAK6B,EAAK2iC,GAC5C,IAAKt8B,OAAO4K,GAAG5R,EAAQ0oC,GAAe,CA/BvBC,EAAC3pC,EAAkB4pC,EAAWC,KAC7CtS,GACAnZ,QAAQC,UACHyrB,KAAK,IAAMvS,GAAiBqS,EAAQC,EAAQ,CAAEE,MAAO/pC,KACrD8pC,KAAM9oB,GAAW+Y,GAAe/5B,EAAKghB,GAAU4oB,IAC/CI,MAAOtvB,IACA8c,GAAyBA,GAAwB9c,GAChDC,QAAQD,MAAM,mCAAoCA,KAG/Dqf,GAAe/5B,EAAI4pC,IAyBfD,CAAe3pC,EAHA2B,EAAIsoC,YACbtoC,EAAIsoC,YAAYjpC,EAAQlB,EAAK6B,EAAK2iC,GACjC,IAAKxkC,EAAKpB,CAACA,GAAQsC,GACClB,EAC/B,CACJ,CACA23B,KAAiB,CAAEz3B,KAAItB,QAAOoB,MAAKypC,UAAU7Q,MAC7C0F,GAAgBvsB,SAAU,EAC1BwsB,GAAe,CAAEr+B,KAAItB,SAhBH,GAqBhBi+B,GAAqB38B,IACvB48B,GAAyBtX,IACrB,MAAM5S,EAAO,IAAIzU,IAAIqnB,GAGrB,OAFI5S,EAAK/T,IAAIqB,GAAK0S,EAAK41B,OAAOtoC,GACzB0S,EAAKpS,IAAIN,GACP0S,KAITyqB,GAA0BA,CAACn9B,EAAkBiqB,KAC/C0V,GAAmBra,IACf,MAAM5S,EAAO,IAAIW,IAAIiS,GAErB,OADA5S,EAAKxN,IAAIlF,EAAIiqB,GACNvX,KAIT0N,GAAcf,GAAe5f,KAAK,KAClCyqC,GAAsBt1C,EAAMgd,OAAOwO,IACzCxrB,EAAMic,UAAU,KACRq5B,GAAoBr4B,UAAYuO,KACpC8pB,GAAoBr4B,QAAUuO,GAC9Buf,GAAkB,IAAItsB,OACvB,CAAC+M,KAIJ,MAAM8d,GAAkBA,CAACl+B,EAAkBtB,EAAeoB,EAAQmgB,KAC9D,MAAMte,EAAMu4B,GAAUx7B,GAChB4lC,EAAc7L,GAAO5mB,QAAQ3P,IAC7BvM,EAAQsM,GAAanC,EAAK6B,EAAK2iC,GAC/B6F,EAAiBznC,GAAkB/M,EAAOmK,EAAK6B,EAAK2iC,EAAatkC,GACjEoqC,EAAW5qC,QAAQsgC,IAAeA,GAAY9/B,KAAOA,GAAM8/B,GAAYphC,QAAUA,GAEvF,MAAO,CACHsB,KACAtB,QACA/I,QACAw0C,iBACArqC,MACAwpC,QAASrpB,EACTopB,OAAQ1nC,EACRO,IAAKoiC,EACL8F,WACA9jB,SAAU8jB,EAAW,GAAI,EACzBC,SAZavM,IAAeA,GAAY99B,KAAOA,GAAM89B,GAAYp/B,QAAUA,EAAQ,OAAS,OAa5F4rC,WAAY9qC,QAAQmC,EAAIyF,WAA2B,SAAd6Y,EAAK9f,OAI5CoqC,GAAiBA,CAACvqC,EAAkBF,KAAM,CAC5CE,KACAF,MACAiT,QAASinB,GACT93B,IAAKu2B,GAAO5mB,QAAQ3P,MAKxBtN,EAAMic,UAAU,KACZ,IAAKutB,GAAgBvsB,UAAYiuB,KAAgB5H,GAAQrmB,QAAS,OAClEusB,GAAgBvsB,SAAU,EAC1B,MAAM9I,EAAW,qBAAqBjH,OAAOg+B,GAAY9/B,IAAIoI,QAAQ,KAAM,6BAA6B03B,GAAYphC,MAAM0J,QAAQ,KAAM,WAClI9P,EAAK4/B,GAAQrmB,QAAQqU,cAA2Bnd,GAClDzQ,GAAM+W,SAAS2X,gBAAkB1uB,IAAOA,EAAGwtB,SAASzW,SAAS2X,gBAAgB1uB,EAAG0mB,MAAM,CAAEwrB,eAAe,KAC5G,CAAC1K,GAAasH,GAAap0C,MAAOo0C,GAAan0C,MAElD,MAAMqrC,GAAmBhkB,IACrB,MAAMkkB,EAAWpG,GAAYvmB,QAC7B,IAAK2sB,EAAU,OAAO,EACtB,QAAwBp8B,IAApBkY,EAAOlC,UAA0B+uB,GAAS,CAC1C,MAAMvvB,EAAQ3Y,EAAMqb,EAAOlC,SAAU,EAAGhZ,KAAKD,IAAIq6B,GAAUx6B,OAAS,EAAG,IACjEwlB,EAAMqiB,GAAQG,QAAQpvB,IAAU,EAChCyN,EAASb,GAAOqiB,GAAQC,WAAWlvB,IAAUkc,IAC7C2W,EAAajM,EAASE,UACtBgM,EAAgBlM,EAASE,UAAYF,EAAS4C,aAAeI,GAC/Dhd,EAAMimB,EAAYjM,EAASE,UAAYla,EAClCa,EAASqlB,IAAelM,EAASE,UAAYrZ,GAAUmZ,EAAS4C,aAAeI,IAC5F,MAAO,QAAwBp/B,IAApBkY,EAAOlC,SAAwB,CACtC,MAAM9f,EAAKkmC,EAAStY,cAAc,wBAAwB5L,EAAOlC,cACjE9f,GAAIqyC,iBAAiB,CAAE5iC,MAAO,WAClC,CACA,QAAwB3F,IAApBkY,EAAOswB,SAAwB,CAC/B,MAAM/B,EAAK7G,GAAOjvB,QAAQ9T,EAAMqb,EAAOswB,SAAU,EAAG5I,GAAOjvB,QAAQ/T,OAAS,IAC5E,GAAI6pC,IAAOA,EAAGlZ,OAAQ,CAClB,MAAMkb,EAAkB7I,GAAOjvB,QAC1BxT,OAAQ+T,GAAmB,SAAbA,EAAEqc,QAChBhmB,OAAO,CAACC,EAAK0J,IAAM1J,EAAM0J,EAAEne,MAAO,GACjC21C,EAAmB9I,GAAOjvB,QAC3BxT,OAAQ+T,GAAmB,UAAbA,EAAEqc,QAChBhmB,OAAO,CAACC,EAAK0J,IAAM1J,EAAM0J,EAAEne,MAAO,GACjC41C,EAAcvM,EAASC,WAAaoM,EACpCG,EAAexM,EAASC,WAAaD,EAAS2C,YAAc2J,EAC9DjC,EAAGxF,EAAI0H,EAAavM,EAASC,WAAaoK,EAAGxF,EAAIwH,EAC5ChC,EAAGxF,EAAIwF,EAAG1zC,MAAQ61C,IACvBxM,EAASC,WAAaoK,EAAGxF,EAAIwF,EAAG1zC,MAAQqpC,EAAS2C,YAAc2J,EACvE,CACJ,CACA,OAAO,GAGLG,GAAYA,CACdC,EACAC,EACAC,KAEA,GAAyB,IAArB5R,GAAUx6B,QAA0C,IAA1BgjC,GAAOjvB,QAAQ/T,OAAc,OAC3D,IAAIoZ,EAAW0nB,GAActG,GAAUG,UAAWF,GAAOA,EAAGz5B,KAAO8/B,GAAY9/B,KAAM,EACjF4qC,EAAW9K,GAAckC,GAAOjvB,QAAQ4mB,UAAWkP,GAAOA,EAAGlnC,IAAIjD,QAAUohC,GAAYphC,QAAS,OAChG0Z,IAAiBA,EAAW,QAC5BwyB,IAAiBA,EAAW,GACDxyB,EAAT,UAAlBgzB,GAAUtrC,IAA4B,EACf,SAAlBsrC,GAAUtrC,IAA2B05B,GAAUx6B,OAAS,EACjDC,EAAMmZ,EAAW8yB,EAAU,EAAG1R,GAAUx6B,OAAS,GAClC4rC,EAAT,UAAlBQ,GAAUzpC,IAA4B,EACf,SAAlBypC,GAAUzpC,IAA2BqgC,GAAOjvB,QAAQ/T,OAAS,EACtDC,EAAM2rC,EAAWO,EAAU,EAAGnJ,GAAOjvB,QAAQ/T,OAAS,GACtE,MAAMoc,EAAS,CAAEpb,GAAIw5B,GAAUphB,GAAUpY,GAAItB,MAAOsjC,GAAOjvB,QAAQ63B,GAAUjpC,IAAIjD,OACjF0/B,GAAgBvsB,SAAU,EAC1BwsB,GAAejjB,GACfkjB,GAAgB,CAAElmB,WAAUwyB,cA0F1BS,GAAc1pC,IAAwB4zB,KAAyB5zB,EAAI6F,iBAAmB/I,EAAgBkD,EAAIjD,OAoC1G4sC,GAAY12C,EAAMgd,OAOd,MAyCJla,GAAcssC,GAAchlC,OAC5BksB,GAAWwW,GAAiB2E,GAAmBnC,GAAgBllC,OAE/D1H,GAAQ1C,EAAMw3B,QAChB,KAAA,CACIsD,aACA3B,eACA9C,gBAAiB,CAAEF,QAAMC,SAAUC,GAAgBD,UACnDG,aACAD,YACAqgB,cAAetS,GAAWj6B,OAC1BwtB,yBACA6S,cAAerF,GAAmB3hC,IAAKib,GAAMA,EAAE5U,OAC/CwZ,gBACAsd,iBACArN,WACAmZ,iBACA7V,kBAAmB,CAAEtrB,KAAM,UAAWC,IAAKo7B,IAC3C1L,oBACAhP,oBACAgc,wBACApV,gBAAiB,CACblK,KAAMkK,GAAgBlK,KACtBmK,iBAAkBD,GAAgBC,iBAClCsG,YAAavG,GAAgBuG,aAEjCv2B,eACA8xB,uBAEJ,CACIkG,GACA3B,GACAhD,GACAE,GAAgBD,SAChBG,GACAD,GACA+N,GAAWj6B,OACXwtB,GACAwN,GACA9hB,GACAsd,GACArN,GACAmZ,GACA9F,GACA1L,GACAhP,GACAgc,GACApV,GAAgBlK,KAChBkK,GAAgBC,iBAChBD,GAAgBuG,YAChBv2B,GACA8xB,KAIRiP,GAAO5mB,QAAU,CACb3P,IAAKy2B,GACLrhC,SACAwhC,YACAG,cACAG,aACAmE,cACAjE,gBACAE,aACAz5B,WACAg6B,kBACAC,sBACAC,sBACAC,aACA1N,yBACAI,4BACA2N,eAlhBmBA,CAAC77B,EAAevJ,KACnC,MAAMwM,EAAMu4B,GAAUx7B,GACtB,IAAKiD,EAAK,OACV,MAAM6pC,EAAUvsC,EAAM9J,EAAOwM,EAAIvF,UAAYoC,EAA0BmD,EAAIvM,UAAYqtC,KACvFlD,GAAiBja,IACb,MAAM5S,EAAO,IAAK4S,EAAM5mB,CAACA,GAAQ8sC,GAEjC,OADA7C,GAAcj2B,GACPA,IAEX2iB,KAAsB,CAAEgU,OAAQ1nC,EAAKxM,MAAOq2C,GAAW9S,OA0gBvD8B,eA9hBmBA,CAAC97B,EAAe+7B,EAAqB5U,EAAgC,QACxF,MAAM1S,EAAS6mB,GAAmB3hC,IAAKib,GAAMA,EAAE5U,OACzC+sC,EAAWt4B,EAAOrO,QAAQpG,GAChC,IAAiB,IAAb+sC,EAAiB,OACrB,MAAM/4B,EhBpvCUg5B,EAAIC,EAAWh+B,EAAcC,KACjD,MAAM8E,EAAOi5B,EAAK1hC,SACXxF,GAAQiO,EAAKwqB,OAAOvvB,EAAM,GAEjC,OADA+E,EAAKwqB,OAAOtvB,EAAI,EAAGnJ,GACZiO,GgBgvCUg5B,CAASv4B,EAAQs4B,EAAUxsC,EAAMw7B,EAAa,EAAGtnB,EAAOnU,OAAS,IAC9EsgC,GAAiB5sB,GACjBg2B,GAAah2B,GACb,MAAM/Q,EAAM2d,GAAe9L,IAAI9U,GAC3BiD,GAAKyzB,KAAsB,CAAEjI,OAAQxrB,EAAK84B,cAAagR,YAAY5lB,EAAO6S,OAuhB9ExgB,gBACAwiB,mBACA1J,UA9ecA,CAACtyB,EAAei8B,KAC9B,GAAItK,GAAsB,OAC1B,MAAM5L,GAAQ+Q,GAAc/Q,MAAQ,IAAIllB,OAAQgU,GAAMA,IAAM7U,GACtD0mB,GAASoQ,GAAcpQ,OAAS,IAAI7lB,OAAQgU,GAAMA,IAAM7U,GACjD,SAATi8B,EAAiBlW,EAAK3b,KAAKpK,GAC1B0mB,EAAMwmB,QAAQltC,GACnBm8B,GAAiB,CAAEpW,OAAMW,WAyezB6L,YAteiBvyB,IACjBm8B,GAAiB,CACbpW,MAAO+Q,GAAc/Q,MAAQ,IAAIllB,OAAQgU,GAAMA,IAAM7U,GACrD0mB,OAAQoQ,GAAcpQ,OAAS,IAAI7lB,OAAQgU,GAAMA,IAAM7U,MAoe3DkxB,eAheoBlxB,IAChB2xB,MAC8C,KAA7CmF,GAAc/Q,MAAQ,IAAI3f,QAAQpG,GAAsB,QACV,KAA9C82B,GAAcpQ,OAAS,IAAItgB,QAAQpG,IAAsB,SA8d9D82B,iBACAqF,oBACAnL,aACAqL,gBACAlK,cACA9C,eACAsB,kBACA8L,kBA/duB1b,IACvB,IAAIosB,EAAY9d,GAAYtO,MAAMxV,QAClCwV,EAAMpf,QAASoE,IACX,MAAMqnC,OACU1pC,IAAZqC,EAAKzE,GAAmB,IAAKyE,EAAMzE,GAAI,GAAGQ,KAAKiZ,SAASra,KAAK2sC,SAASC,SAAS,IAAI/hC,MAAM,EAAG,MAASxF,EACnGmT,EAAQi0B,EAAUlS,UAAWG,QAA6B13B,IAAhB03B,EAAS95B,IAAoB85B,EAAS95B,KAAO8rC,EAAO9rC,SAChG4X,EAAci0B,EAAU/iC,KAAKgjC,GAC5BD,EAAUj0B,GAASk0B,IAExBvd,IAAmCsd,EAAU7sC,OAAS,IAAG6sC,EAAYA,EAAU5hC,WACnFolB,GAAe,IAAKtB,GAAatO,MAAOosB,KAsdxCjd,iBAndsBnqB,IACtB4qB,GAAe,IACRtB,GACHtO,MAAOsO,GAAYtO,MAAMlgB,OAAQu6B,QACjB13B,IAAZqC,EAAKzE,GAAmB85B,EAAS95B,KAAOyE,EAAKzE,GAAK85B,IAAar1B,MAgdvEojB,gBA3coBA,CAACyT,EAA8BpX,EAA+B+J,KAClFgS,GAAc,MACdF,GAAmB,CACfviB,MAAM,EACNmK,iBAAkB2T,EAClBrN,cACA/J,SAAUA,GAAYmU,GAAWxmB,SAAWqmB,GAAQrmB,WAscxD+V,mBACA4T,eACAI,kBACAI,cACAE,qBACAjR,gBAAiB,CAAEF,QAAMC,SAAUC,GAAgBD,UACnDoR,sBACAhU,cACAuU,qBACAG,wBACAF,2BACA9M,oBACAkN,uBACAG,2BACArc,oBACAuQ,uBACAoM,qBACAC,oBACAI,eACAE,gBACAE,mBACAG,kBACAC,mBACAhG,eACA6O,WACAzK,WAjxBeA,CAAClkC,EAAqC,MACrD,GAAI4nC,GAAY,OAChB,MAAMztB,EAAsC,CACxC7b,MAAyB,iBAAXkyB,EAAsBA,OAAS5mB,KAC1C5J,GAEF2/B,GAAQtmB,SAA6B,oBAAXtc,QAC/B8qC,GAAc1tB,KA6wBdilB,KAAQA,GAAO/lB,QAAU8mB,IAE7B/jC,EAAMic,UAAU,KACZgnB,KAAgBvgC,GAAO,CAAE4K,IAAKy2B,MAC/B,CAACrhC,GAAOugC,GAAec,KAI1B,MAAMlQ,GAAY7zB,EAAMw3B,QACpB,KAAA,CACIpD,SACA6C,cACAT,mBACAU,wBACAE,sBACAL,8BACAhB,uBACAF,yBACAI,0BACAwF,wBACAJ,wBACA0E,iCACApG,mCACAgC,sBACAI,sBACAgF,qBACAnF,wBACA5G,2BAEJ,CACIZ,EACA6C,GACAT,GACAU,GACAE,GACAL,GACAhB,GACAF,GACAI,GACAwF,GACAJ,GACA0E,GACApG,GACAgC,GACAI,GACAgF,GACAnF,GACA5G,KAIFqiB,GAAer3C,EAAMw3B,QACvB,KAAA,CACIlqB,IAAKy2B,GACLrhC,SACAkwB,cACAvzB,YACAw0B,aACA1V,QAASinB,GACT9N,eAAgB+N,KAEpB,CAACtB,GAAWrhC,GAAOkwB,GAAYvzB,EAAWw0B,GAAWuR,GAAoBC,KA+GvEiS,GAAoBA,CAACrD,EAAkBsD,KACzC,MAAMxqC,IAAEA,GAAQknC,EACVnqC,EAAQiD,EAAIjD,MAElB,GAAIA,IAAUb,EAAgB,CAC1B,GAAuB,UAAnBsuC,EAAUC,MAAoBD,EAAU7O,MAAO,CAC/C,MAAM8H,EAAU+G,EAAU7O,MAAM9c,YAAYnoB,IAAK0I,GAAMA,EAAEf,IACnDwrB,EAAgB4Z,EAAQz7B,OAAe,CAACC,EAAK5J,IAAO4J,GAAO4xB,GAAY78B,IAAIqB,GAAM,EAAI,GAAI,GAC/F,OACIpL,EAAAC,cAAC8uB,GAAQ,CACLhI,QAASypB,EAAQpmC,OAAS,GAAKwsB,IAAkB4Z,EAAQpmC,OACzD4c,cAAe4P,EAAgB,GAAKA,EAAgB4Z,EAAQpmC,OAC5D6C,MAAO2lB,GAAWpZ,2BAClBoY,QAAUX,GAAUA,EAAMO,kBAC1BnU,SAAUA,IAAM+pB,GAAWoJ,EAAS5Z,IAAkB4Z,EAAQpmC,QAAQ,IAGlF,CACA,GAAuB,SAAnBmtC,EAAUC,KAAiB,OAAO,KACtC,MAAMC,EAAanQ,GAAkBiQ,EAAUnsC,GAAImsC,EAAUrsC,KACvD6b,EAAU6f,GAAY78B,IAAIwtC,EAAUnsC,IAC1C,OACIpL,gBAAC+uB,GAAQ,CACLhI,QAASA,EACTwL,UAAWklB,EACXxqC,MAAO8Z,EAAU6L,GAAWnZ,6BAA+BmZ,GAAWpZ,2BACtEkY,UAAU,EACVE,QAAUX,GAAUA,EAAMO,kBAC1BnU,SAAUA,KACN0uB,GAAiB9uB,QAAUs6B,EAAUnsC,GACrCg8B,GAAW,CAACmQ,EAAUnsC,KAAM2b,EAASma,MAIrD,CAEA,GAAIp3B,IAAUZ,EAA2B,CACrC,GAAuB,SAAnBquC,EAAUC,OAAoBD,EAAUrsC,IAAK,OAAO,KACxD,MAAM5G,EAAW4jC,GAAqBn+B,IAAIwtC,EAAUnsC,IAC9CssC,EAAU7V,KAAwB8T,GAAe4B,EAAUnsC,GAAImsC,EAAUrsC,MAC/E,OAAIwsC,UAAyD,IAAZA,EAA0B,KAEvE13C,gBAAC0uB,GAAU,CACPnpB,KAAK,QACL4jB,UAAW1e,EAAG,yBAA0BnG,GAAY,oCACpD2I,MAAO3I,EAAWsuB,GAAW9Y,oBAAsB8Y,GAAW/Y,kBAAiB,gBAChEvV,EACfotB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACNuW,GAAkBwP,EAAUnsC,MAGhCpL,EAAAC,cAACmtB,GAAc,MAG3B,CAEA,GAAItjB,IAAUd,EAAuB,CACjC,GAAuB,UAAnBuuC,EAAUC,MAAoBD,EAAU7O,MAAO,CAC/C,MAAMA,EAAQ6O,EAAU7O,MAClBpkC,EAAWisC,GAAgB7H,GAC3BiP,EAAatV,IAAwBuV,oBAC3C,OACI53C,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,sBAAsBnnB,MAAO,CAAE61C,YAA+B,GAAlBN,EAAUzsB,QACjE9qB,EAAAC,cAACyuB,IACGnpB,KAAK,QACL4jB,UAAW1e,EAAG,wBAAyBnG,GAAY,mCACnD2I,MAAO3I,EAAWsuB,GAAW9Y,oBAAsB8Y,GAAW/Y,kBAAiB,gBAChEvV,EACfotB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACN+W,GAAwBG,EAAMt9B,IAAK9G,KAGvCtE,EAAAC,cAACotB,UAELrtB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,uBAAuBjnB,MAAOwmC,EAAMjd,eAC/Cid,EAAMjd,gBAETksB,GAAa33C,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,4BAAyBuf,EAAM9c,YAAYxhB,OAAe,KAGrG,CACA,OAAO,IACX,CAEA,GAAuB,UAAnBmtC,EAAUC,MAAuC,WAAnBD,EAAUC,KAAmB,CAC3D,MAAMM,EAAMP,EAAUQ,aAAajuC,GACnC,IAAKguC,GAAO9tC,EAAM8tC,EAAI/2C,OAAQ,OAAO,KACrC,MAAMurB,EAAKsP,GAAqBkc,EAAIxrB,IAC9BojB,EAAc7L,GAAO5mB,QAAQ3P,IAC7B0qC,EAAaT,EAAU7O,OAAO9c,YAAY,IAAI1gB,KAAO24B,GAAO5mB,QAAQynB,aAAa,IAAIx5B,KAAO,CAAA,EAC5F+C,EAAYqe,GAAIve,eAChBue,EAAGve,eAAe+pC,EAAI/2C,OACtBgM,EAAIgB,eACFhB,EAAIgB,eAAe+pC,EAAI/2C,MAAOi3C,EAAWjrC,EAAyB2iC,GAClEhiC,GAAmBoqC,EAAI/2C,MAAOgM,GACtC,OACI/M,EAAAC,cAAAD,EAAAuuB,SAAA,KACIvuB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,8BAA8BmD,GAAIrf,OAAS6qC,EAAIxrB,IAC/DtsB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,sBAAsBnb,GAAuBC,IAGzE,CAEA,IAAKspC,EAAUrsC,IAAK,OAAO,KAC3B,MAAMwa,EAAS4jB,GAAgBiO,EAAUnsC,GAAItB,EAAOytC,EAAUrsC,IAAKqsC,EAAUlsB,MAE7E,GAAwB,SAApB3F,EAAO+vB,SAAqB,MAxNd/vB,KAClB,MAAM3Y,EAAM2Y,EAAO+uB,OACbvf,EAAUyf,GACZ7L,GAAiBpjB,EAAOta,GAAIsa,EAAO5b,OAAO,EAAO6qC,GAC/CsD,EAASA,IAAMnP,GAAiBpjB,EAAOta,GAAIsa,EAAO5b,OAAO,EAAM,iBAgBrE,GAAIiD,EAAImrC,eACJ,OAAOnrC,EAAImrC,eAAe,IACnBxyB,EACHulB,aACAkN,cAAe/O,GACflU,OAAQA,IAAMA,EAAO,gBACrB+iB,WAGR,MAAMpxC,EAAS,CACX4oB,WAAW,EACXsC,UA1BgBd,IACE,UAAdA,EAAMnwB,KACNmwB,EAAMiB,iBACNjB,EAAMO,kBACN0D,EAAO,iBACc,WAAdjE,EAAMnwB,KACbmwB,EAAMiB,iBACNjB,EAAMO,kBACNymB,KACqB,QAAdhnB,EAAMnwB,IACbo0B,EAAO,cAEPjE,EAAMO,mBAeVgE,OAAQA,IAAMN,EAAO,gBACrBtD,QAAUX,GAA4BA,EAAMO,mBAEhD,OAAQzkB,EAAIxB,MACR,IAAK,UACD,OACIvL,EAAAC,cAAC8uB,GAAQ,IACDloB,EACJkgB,QAASnc,QAAQqgC,IACjB5tB,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOO,WAG3D,IAAK,eAAgB,CACjB,MAAMnjB,EAAUuJ,EAAoBJ,EAAK2Y,EAAOxa,IAAKwa,EAAOta,IAC5D,OACIpL,EAAAC,cAAC2uB,GAAM,IACC/nB,EACJtB,KAAK,QACLxE,MAAOkqC,SAAgD,GAAK/9B,OAAO+9B,IACnE5tB,SAAW4T,IACP,MAAMtjB,EAAQ/J,EAAQgK,KAAM0lB,GAAMpmB,OAAOJ,EAAeC,EAAKumB,MAAQrC,EAAMzK,OAAOzlB,OAClFqoC,QAAuB57B,IAAVG,EAAsBb,EAAeC,EAAKY,GAASsjB,EAAMzK,OAAOzlB,SAGjFf,EAAAC,cAAA,SAAA,CAAQc,MAAM,KACb6C,EAAQH,IAAKoJ,IACV,MAAM9L,EAAQ+L,EAAeC,EAAKF,GAClC,OACI7M,EAAAC,cAAA,SAAA,CAAQa,IAAKoM,OAAOnM,GAAQA,MAAOmM,OAAOnM,IACrCiM,EAAeD,EAAKF,MAM7C,CACA,IAAK,SACD,OACI7M,gBAAC2uB,GAAS,IACF9nB,EACJtB,KAAK,QACLgG,KAAK,SACLxK,MAAOkqC,SAAgD,GAAKA,GAC5D5tB,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOzlB,SAG3D,IAAK,OACL,IAAK,WACD,OACIf,EAAAC,cAAC0uB,GAAS,IACF9nB,EACJtB,KAAK,QACLgG,KAAmB,SAAbwB,EAAIxB,KAAkB,OAAS,iBACrCxK,MACyB,iBAAdkqC,IAA0B,qBAAqBh4B,KAAKg4B,IACrDA,GACApN,GAAiBoN,GAAwB,aAAbl+B,EAAIxB,MAE1C8R,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOzlB,SAG3D,QACI,OACIf,EAAAC,cAAC0uB,GAAS,IACF9nB,EACJtB,KAAK,QACLgG,KAAK,OACLxK,MAAOkqC,SAAgD,GAAK/9B,OAAO+9B,IACnE5tB,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOzlB,WAoHxBq3C,CAAa1yB,GAEpD,GAAI3Y,EAAIsrC,WAAY,OAAOtrC,EAAIsrC,WAAW3yB,GAE1C,GAAiB,YAAb3Y,EAAIxB,KAAoB,CACxB,MAAMyxB,EAAUjwB,EAAIurC,WAAavrC,EAAIurC,WAAW3C,GAAe4B,EAAUnsC,GAAImsC,EAAUrsC,MAAQ,GAC/F,OAAOlL,gBAAC+8B,GAAW,CAACC,QAASA,EAAS39B,UAAWA,EAAW49B,UAAWrK,GAAW1Y,iBACtF,CAEA,GAAiB,YAAbnN,EAAIxB,KACJ,OAAIvB,EAAM0b,EAAO3kB,OAAe,KACzB2kB,EAAO3kB,MACVf,EAAAC,cAACktB,GAAS,CAAA,aAAayF,GAAWlZ,uBAElC1Z,EAAAC,cAAC6sB,GAAS,CAAA,aAAa8F,GAAWjZ,wBAI1C,MAAM1L,EAAYyX,EAAO6vB,eACzB,GAAItnC,QAA+C,OAAO,KAC1D,GAAIjO,EAAMi0B,eAAehmB,GAAY,OAAOA,EAC5C,MAAM9O,EAAO6O,GAAuBC,GACpC,OACIjO,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,qBAAqBjnB,MAAO/C,EAAKiL,OAAS,GAAKjL,OAAOqO,GACjErO,IAKPo5C,GAAatE,IAAgB,CAC/B1zC,MAAO0zC,EAAG1zC,MACViH,SAAUysC,EAAG1zC,MACbC,SAAUyzC,EAAG1zC,MACbsvB,KAAoB,SAAdokB,EAAGlZ,OAAoBkZ,EAAG7yB,YAAS5T,EACzCgjB,MAAqB,UAAdyjB,EAAGlZ,OAAqBkZ,EAAG7yB,YAAS5T,IAGzCgrC,GAAgBA,CAACvE,EAAkBjpC,IACrCP,EACkB,SAAdwpC,EAAGlZ,QAAqB,GAAG/vB,iBACb,UAAdipC,EAAGlZ,QAAsB,GAAG/vB,kBAC5BipC,EAAGpF,YAAczB,GAAOoB,YAAc,GAAGxjC,sBACzCipC,EAAGnF,cAAgB,GAAG9jC,yBAuExBytC,GAAiB7tC,QAAQ42B,IAAcC,KAAqBR,IAE5DyX,GAAmBA,CACrBnB,EACA3zC,KAEA,MAAMsjC,EAAgC,SAAnBqQ,EAAUC,MAAkB5Q,GAAY78B,IAAIwtC,EAAUnsC,IACnEutC,EACiB,SAAnBpB,EAAUC,MAAmBD,EAAUrsC,KAAOq2B,GACxCA,GAAgB,IACToU,GAAe4B,EAAUnsC,GAAImsC,EAAUrsC,KAC1C0tC,2BAA4Bh1C,EAAQof,MACpC61B,eAAgBj1C,EAAQk1C,QACxBC,cAAen1C,EAAQo1C,OACvBtE,QAAS6C,EAAUlsB,YAEvB7d,EACV,OACIxN,EAAAC,cAAA,MAAA,CACImvB,KAAK,MAAK,gBACKxrB,EAAQof,MAAQ,EAAC,gBACE,SAAnBu0B,EAAUC,KAAkBtQ,OAAa15B,EAAS,kBAChDN,OAAOqqC,EAAUnsC,IAAG,qBACjBxH,EAAQof,MAC5BmG,UAAW1e,EACP,eACAy8B,GAAc,yBACduR,IAAqC,SAAnBlB,EAAUC,MAAmB,0BAC5B,UAAnBD,EAAUC,MAAoB,sBACX,cAAnBD,EAAUC,MAAwB,uBACf,WAAnBD,EAAUC,MAAqB,uBAC/B5zC,EAAQq1C,QAAU,4BAClBN,GAEJ32C,MAAO,CACHzB,MAAO6sC,GAAO4B,WACdnvC,OAAQ+D,EAAQq1C,YAASzrC,EAAY5J,EAAQ/D,OAC7Cq5C,UAAWt1C,EAAQq1C,OAAS/Z,QAAY1xB,GAE5CokB,QAAUX,IACiB,SAAnBsmB,EAAUC,MAAmBD,EAAUrsC,KAClC+1B,IAnkCOkY,EAAC5B,EAAyBtmB,KACtD,GAAuB,UAAnBsmB,EAAUC,MAAoBD,EAAU7O,MAAO,CAC/C,MAAM8H,EAAU+G,EAAU7O,MAAM9c,YAAYnoB,IAAK0I,GAAMA,EAAEf,IACnDguC,EAAc5I,EAAQr7B,MAAO/J,GAAOw7B,GAAY78B,IAAIqB,IAE1D,YADAg8B,GAAWoJ,GAAU4I,GAAa,EAEtC,CACA,GAAuB,SAAnB7B,EAAUC,KAAiB,OAC/B,MAAMpsC,EAAKmsC,EAAUnsC,GACrB,IAAKk8B,GAAkBl8B,EAAImsC,EAAUrsC,KAAM,OAC3C,MAAMutB,GAAYyI,GAClB,GAAIjQ,EAAMooB,UAAY5gB,GAAyC,OAA7BsT,GAAiB9uB,QAAkB,CACjE,MAAMzR,EAAMo5B,GAAUj6B,OAAQk6B,GAAmB,SAAZA,EAAGt5B,MAAiB9H,IAAKohC,GAAOA,EAAGz5B,IAClE2N,EAAOvN,EAAI0E,QAAQ67B,GAAiB9uB,SACpCjE,EAAKxN,EAAI0E,QAAQ9E,GACvB,IAAa,IAAT2N,QAAeC,EAAW,CAC1B,MAAOpI,EAAGC,GAAKkI,EAAOC,EAAK,CAACD,EAAMC,GAAM,CAACA,EAAID,GAE7C,YADAquB,GAAW57B,EAAI6J,MAAMzE,EAAGC,EAAI,IAAI,GAAOkwB,KAAsB9P,EAAMqoB,UAAYroB,EAAMsoB,QAEzF,CACJ,CACAxN,GAAiB9uB,QAAU7R,EAC3B,MAAM87B,EAAaN,GAAY78B,IAAIqB,GACX21B,IAAsB9P,EAAMqoB,SAAYroB,EAAMsoB,QAKlEnS,GAAW,CAACh8B,IAAM87B,GAAY,GAH1BA,GAAmC,IAArBN,GAAYrhC,KAAY6hC,GAAW,CAACh8B,IAAK,GAAO,GAC7Dg8B,GAAW,CAACh8B,IAAK,GAAM,IAyiCiB+tC,CAAwB5B,EAAWtmB,GACpEuQ,KAAamU,GAAe4B,EAAUnsC,GAAImsC,EAAUrsC,KAAM+lB,EAAO6S,OACvC,UAAnByT,EAAUC,MAAoBD,EAAU7O,OAC/CH,GAAwBgP,EAAU7O,MAAMt9B,IAAKmlC,GAAgBgH,EAAU7O,SAG/E7W,cAAgBZ,IACW,SAAnBsmB,EAAUC,MAAmBD,EAAUrsC,KACvCu2B,KAAmBkU,GAAe4B,EAAUnsC,GAAImsC,EAAUrsC,KAAM+lB,EAAO6S,QAI9EsJ,GAAOjvB,QAAQ1a,IAAKwwC,GAzHdoE,EAACpE,EAAkBsD,KAClC,MAAMxqC,IAAEA,GAAQknC,EACVnqC,EAAQiD,EAAIjD,MACZ0vC,EAAY5uC,QAAQsgC,IAAeA,GAAY9/B,KAAOmsC,EAAUnsC,IAAM8/B,GAAYphC,QAAUA,GAC5F2vC,EAAY7uC,QAAQs+B,IAAeA,GAAY99B,KAAOmsC,EAAUnsC,IAAM89B,GAAYp/B,QAAUA,GAC5F4vC,GACkB,UAAnBnC,EAAUC,MAAuC,WAAnBD,EAAUC,OAAsB5sC,QAAQ2sC,EAAUQ,aAAajuC,IAC5F4b,EACiB,SAAnB6xB,EAAUC,MAAmBD,EAAUrsC,IACjCo+B,GAAgBiO,EAAUnsC,GAAItB,EAAOytC,EAAUrsC,IAAKqsC,EAAUlsB,MAC9D,KACJ7Y,IAAWkT,GAAS8uB,GAAiB9uB,GACrCizB,EACFjzB,GAAU3Y,EAAI4sC,cACqB,mBAAtB5sC,EAAI4sC,cACP5sC,EAAI4sC,cAAcj0B,GAClB3Y,EAAI4sC,mBACRnsC,EACJosC,EAAa9vC,IAAUb,EACvB4wC,EAAiB/vC,IAAUZ,EACjC,OACIlJ,EAAAC,cAAA,MAAA,CACIa,IAAKgJ,EACLslB,KAAK,WAAU,iBACCtlB,EAAK,oBACFsjC,GAAOjvB,QAAQjO,QAAQ+jC,GAC1CviB,SAAU8nB,EAAY,GAAI,EAAE,gBACM,SAAnBjC,EAAUC,KAAkB5Q,GAAY78B,IAAIwtC,EAAUnsC,SAAMoC,EAC3E2b,UAAW1e,EACP,gBACA,wBAAwBsC,EAAIgF,OAAS,SACrCymC,GAAcvE,EAAI,iBAClBuF,IAAcC,GAAa,yBAC3BA,GAAa,yBACbjnC,IAAainC,GAAa,0BACb,YAAb1sC,EAAIxB,MAAsB,yBACb,YAAbwB,EAAIxB,MAAsB,yBAC1BquC,GAAc,0BACdC,GAAkB,+BAClBH,GAAiB,6BACjBf,GAEJ32C,MAAOu2C,GAAUtE,GACjBniB,YAAaA,KACc,SAAnBylB,EAAUC,MAAsC,UAAnBD,EAAUC,MAClCgC,GAAW/P,GAAe,CAAEr+B,GAAImsC,EAAUnsC,GAAItB,WAG3D8nB,QAAUX,IACFvL,GAAUgc,IAAaA,GAAYhc,EAAQuL,EAAO6S,OAE1DjS,cAAgBZ,IACRvL,IACAic,KAAoBjc,EAAQuL,EAAO6S,MAC/BtxB,IAAainC,IACbxoB,EAAMO,kBACNqX,GAAkB0O,EAAUnsC,GAAItB,OAK3CwtC,GAAkBrD,EAAIsD,KA4DKc,CAAWpE,EAAIsD,EAAW3zC,EAAQq1C,SAC9Dj5C,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,0BAKrB2wB,GAAejV,IAAiB,CAClCz5B,GAAIy5B,EAAGz5B,GACPosC,KAAM3S,EAAGt5B,KACTL,IAAK25B,EAAG35B,IACRmgB,KAAMwZ,EAAGxZ,KACTP,MAAO+Z,EAAG/Z,MACV4d,MAAO7D,EAAG6D,MACVqP,WAAwB,UAAZlT,EAAGt5B,MAAoBs5B,EAAG6D,MAAQqJ,GAAmBlN,EAAG6D,YAASl7B,IAqD3EusC,GAAmBA,CAAChD,EAAuBnxC,KAC7C,MAAMilB,EAA2B,GAsBjC,IArBCksB,GAAQ,IAAItrC,QAAQ,CAACP,EAAK8X,KACvB,MAAM5X,EAAKH,EAAgBC,EAAKC,GAC1BosC,EAA0B,CAC5BnsC,KACAosC,KAAM,YACNtsC,MACAmgB,KAAM,CAAE9f,KAAM,YAAaH,KAAI0f,MAAO,EAAGQ,OAAQ,KAAM1lB,YACvDklB,MAAO,GAEXD,EAAM3W,KACFlU,gBAACA,EAAMuuB,SAAQ,CAACztB,IAAKoM,OAAO9B,IACvBstC,GAAiBnB,EAAW,CACzB13C,OAAQq/B,GACRlc,MAAOA,EACP81B,SAAS,EACTE,QAAQ,EACRC,QAAQ,QAKP,WAAbrzC,GAAyBgsC,GAAkB,CAC3C,MAAM2F,EAA0B,CAC5BnsC,GAAIjC,EACJquC,KAAM,SACNtsC,IAAK,KACLmgB,KAAM,CAAE9f,KAAM,SAAUH,GAAIjC,EAAuB2hB,MAAO,EAAGQ,OAAQ,MACrER,MAAO,EACPitB,WAAYnG,IAEhB/mB,EAAM3W,KACFlU,EAAAC,cAACD,EAAMuuB,SAAQ,CAACztB,IAAKqI,GAChBuvC,GAAiBnB,EAAW,CACzB13C,OAAQq/B,GACRlc,MAAO,EACP81B,SAAS,EACTE,QAAQ,EACRC,QAAQ,KAIxB,CACA,OAAOpuB,GAKLmvB,GAAmBA,CAAC/F,EAAkBjxB,KACxC,MAAMjW,IAAEA,GAAQknC,EACVnqC,EAAQiD,EAAIjD,MACZmwC,EAAYnf,GAAUiK,UAAWl1B,GAASA,EAAK/F,QAAUA,GAAS+F,EAAKyF,MACvEulB,GAAyB,IAAdof,EAAmBnf,GAAUmf,QAAazsC,EACrDyE,GACgB,IAAjBlF,EAAIkF,WAAuBopB,KAAyBxxB,EAAgBC,IACpEA,IAAUd,IAA0C,IAAjB+D,EAAIkF,SACtCioC,GACAznC,KAAsB1F,EAAI0F,oBAAsB5I,EAAgBC,IACjEA,IAAUd,IAA0ByJ,GACnCL,GACAsuB,KAAyC,IAAlB3zB,EAAIqF,YAAwBvI,EAAgBC,IACpEA,IAAUd,IAA0B03B,GACnCyZ,EAAY1D,GAAW1pC,GACvBqtC,EAAazO,IAAM7hC,QAAUA,EAC7BuwC,EAAe1O,IAAQA,GAAK2O,YAAcxwC,GAAS6hC,GAAK7hC,QAAUA,EAClEywC,EAAWnP,IAAYthC,QAAUA,EACjC0wC,EAAe,CAAE1wC,QAAO2qC,OAAQ1nC,EAAyBO,IAAKy2B,IAC9D4U,EAAc5rC,EAAI0tC,gBACa,mBAAxB1tC,EAAI0tC,gBACP1tC,EAAI0tC,gBAAgBD,GACpBztC,EAAI0tC,qBACRjtC,EAEN,IAAIkqC,EA0BJ,OAxBIA,EADA5tC,IAAUb,EACAi4B,GAA8B,KACpClhC,EAAAC,cAAC8uB,IACGhI,QAASqsB,GACTpsB,cAAeqsB,GACf9gB,SAAyC,IAA/B2gB,GAAoB9oC,OAC9B6C,MACImmC,GACMxgB,GAAWrZ,iCACXqZ,GAAWtZ,+BAErB+D,SAAUu2B,GACVhiB,QAAUX,GAAUA,EAAMO,oBAG3B1nB,IAAUZ,EACP,KAEA6D,EAAI2tC,aACV3tC,EAAI2tC,aAAaF,GAEjBx6C,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,yBAAyBpc,EAAI+E,YAAchI,GAK/D9J,EAAAC,cAAA,MAAA,CACIa,IAAKgJ,EACLslB,KAAK,+BACUpM,EAAQ,EAAC,YACb6X,EAA8B,QAAlBA,EAASvlB,KAAiB,YAAc,aAAgBrD,EAAW,YAASzE,EAAS,iBAC5F1D,EAChB5H,MAAO6K,EAAI4tC,YACXjpB,UAAU,EACVyoB,UAAWA,EACXhxB,UAAW1e,EACP,uBACA,+BAA+BsC,EAAIiF,aAAe,SAClDwmC,GAAcvE,EAAI,wBAClBhiC,GAAY,iCACZnI,IAAUb,GAAkB,iCAC5Ba,IAAUZ,GAA6B,sCACvC8Z,IAAUoqB,GAAOjvB,QAAQ/T,OAAS,GAAK,6BACvCgwC,GAAc,iCACdC,GAA+B,SAAf1O,IAAM5F,MAAmB,kCACzCsU,GAA+B,UAAf1O,IAAM5F,MAAoB,mCAC1CwU,GAAY,kCACZ5B,GAEJ32C,MAAOu2C,GAAUtE,GACjBriB,QAAUX,IACDhf,IAAYq5B,IACjBrP,GAAWnyB,OAAO0D,EAAWyjB,EAAMooB,WAEvCuB,YAAc3pB,IACV,GAAKkpB,EAAL,CACAlpB,EAAM4pB,aAAaC,cAAgB,OACnC,IACI7pB,EAAM4pB,aAAaE,QAAQ,aAAcjxC,EAC7C,CAAE,MACE,CAEJ8hC,GAAQ,CAAE9hC,QAAOwwC,UAAW,KAAMvU,KAAM,QAPxB,GASpBiV,WAAa/pB,IACT,IAAK0a,IAAQA,GAAK7hC,QAAUA,EAAO,OACnC,MAAMmxC,EAAW7N,GAAOjvB,QAAQvQ,KAAM8Q,GAAMA,EAAE3R,IAAIjD,QAAU6hC,GAAK7hC,OACjE,IAAKmxC,GAAYA,EAASlgB,SAAWkZ,EAAGlZ,SAAW0b,GAAW1pC,GAAM,OACpEkkB,EAAMiB,iBACNjB,EAAM4pB,aAAaK,WAAa,OAChC,MAAMC,EAAOlqB,EAAMiC,cAAc3C,wBAC3BwV,EAAO9U,EAAMmqB,QAAUD,EAAKtrB,KAAOsrB,EAAK56C,MAAQ,EAAI,OAAS,QAC/DorC,GAAK2O,YAAcxwC,GAAS6hC,GAAK5F,OAASA,GAAM6F,GAAQ,IAAKD,GAAM2O,UAAWxwC,EAAOi8B,UAE7FsV,YAAaA,KACL1P,IAAQA,GAAK2O,YAAcxwC,GAAO8hC,GAAQ,IAAKD,GAAM2O,UAAW,QAExEgB,OAASrqB,GAh2BFsqB,EAACC,EAAwBvqB,KACxCA,EAAMiB,iBACN,MAAMjV,EAAU0uB,GAEhB,GADAC,GAAQ,OACH3uB,GAAWA,EAAQnT,QAAU0xC,EAASzuC,IAAIjD,MAAO,OACtD,MAAMmxC,EAAW7N,GAAOjvB,QAAQvQ,KAAMqmC,GAAOA,EAAGlnC,IAAIjD,QAAUmT,EAAQnT,OACtE,IAAKmxC,GAAYA,EAASlgB,SAAWygB,EAASzgB,SAAW0b,GAAW+E,EAASzuC,KAAM,OACnF,MAAMg5B,EAAO9oB,EAAQ8oB,KACrB,GAAIkV,EAASlgB,OAAQ,CACjB,MAAMj6B,EAAMm6C,EAASlgB,OACfgc,GAAQnW,GAAc9/B,IAAQ,IAAIuU,QAClC0D,EAAOg+B,EAAK7mC,QAAQ+M,EAAQnT,OAClC,IAAIkP,EAAK+9B,EAAK7mC,QAAQsrC,EAASzuC,IAAIjD,OACnC,IAAa,IAATiP,QAAeC,EAAW,OAK9B,OAJA+9B,EAAKzO,OAAOvvB,EAAM,GAClBC,EAAK+9B,EAAK7mC,QAAQsrC,EAASzuC,IAAIjD,OAC/BitC,EAAKzO,OAAgB,UAATvC,EAAmB/sB,EAAK,EAAIA,EAAI,EAAGiE,EAAQnT,YACvDm8B,GAAiB,IAAKrF,GAAe9/B,CAACA,GAAMi2C,GAEhD,CACA,MAAMx4B,EAAS6mB,GAAmB3hC,IAAKib,GAAMA,EAAE5U,OACzCiP,EAAOwF,EAAOrO,QAAQ+M,EAAQnT,OAC9B2xC,EAAUl9B,EAAO5T,OAAQgU,GAAMA,IAAM1B,EAAQnT,OACnD,IAAIkP,EAAKyiC,EAAQvrC,QAAQsrC,EAASzuC,IAAIjD,OACzB,UAATi8B,IAAkB/sB,GAAM,GAC5ByiC,EAAQnT,OAAOtvB,EAAI,EAAGiE,EAAQnT,OAC9B4gC,GAAiB+Q,GACjB3H,GAAa2H,GACb,MAAM1uC,EAAM2d,GAAe9L,IAAI3B,EAAQnT,OACnCiD,GAAKyzB,KAAsB,CAAEjI,OAAQxrB,EAAK84B,YAAa7sB,EAAI69B,SAAU99B,GAAQkY,EAAO6S,OAm0B7DyX,CAAWtH,EAAIhjB,GAClCyqB,UAAWA,IAAM9P,GAAQ,OAEzB5rC,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mCACVuuB,EACAzlC,GACGjS,EAAAC,cAAA,OAAA,CACIkpB,UAAW1e,EAAG,qBAAsBowB,GAAY,4CACpC,QAEQ,SAAnBA,GAAUvlB,KAAkBtV,EAAAC,cAACgtB,GAAiB,CAAC1nB,KAAM,KAASvF,EAAAC,cAAC+sB,GAAe,CAACznB,KAAM,KACrFs1B,GAAYC,GAAUnwB,OAAQwF,GAAMA,EAAEmF,MAAMlL,OAAS,GAClDpK,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,uBAAuB8wB,EAAY,KAKlEC,GACGl6C,EAAAC,cAACyuB,GAAU,CACPnpB,KAAK,QACL4jB,UAAW1e,EAAG,2BAA4B8vC,GAAY,kCACtDttC,MAAO2lB,GAAWxY,gCACJ,OAAM,gBACLmgC,EACf7oB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACN6Z,GAAe3a,GACXA,GAAM5mB,QAAUA,EAAQ,KAAO,CAAEA,QAAOwlB,SAAU2B,EAAMiC,iBAGhEpB,YAAcb,GAAUA,EAAMO,mBAE9BxxB,EAAAC,cAACitB,GAAY,OAGpB9a,GACGpS,EAAAC,cAAA,MAAA,CACIkpB,UAAW1e,EAAG,yBAA0B6gC,KAAkBxhC,GAAS,kCACnEslB,KAAK,+BACY,WACjBusB,cAAgB1qB,GA91BV2qB,EAAC3H,EAAkBhjB,KACzCA,EAAMiB,iBACNjB,EAAMO,kBACNklB,GAAUz5B,QAAU,CAChBnT,MAAOmqC,EAAGlnC,IAAIjD,MACd+xC,OAAQ5qB,EAAMmqB,QACdU,WAAY7H,EAAG1zC,MACfw7C,UAAW9H,EAAG1zC,MACd+J,IAAK2pC,EAAGlnC,IAAIvF,UAAYoC,EACxBW,IAAK0pC,EAAGlnC,IAAIvM,UAAYqtC,KAE5BtC,GAAiB0I,EAAGlnC,IAAIjD,OACxB,MAAMkyC,EAAU1X,IACZ,MAAMlf,EAAIsxB,GAAUz5B,QACpB,IAAKmI,EAAG,OACR,MAAM7kB,EAAQ8J,EAAM+a,EAAE02B,YAAcxX,EAAE8W,QAAUh2B,EAAEy2B,QAASz2B,EAAE9a,IAAK8a,EAAE7a,KACpE6a,EAAE22B,UAAYx7C,EACdoqC,GAAiBja,GAAUA,EAAKtL,EAAEtb,SAAWvJ,EAAQmwB,EAAO,IAAKA,EAAM,CAACtL,EAAEtb,OAAQvJ,KAEhF07C,EAAOA,KACTt7C,OAAOmwB,oBAAoB,cAAekrB,GAC1Cr7C,OAAOmwB,oBAAoB,YAAamrB,GACxC,MAAM72B,EAAIsxB,GAAUz5B,QAGpB,GAFAy5B,GAAUz5B,QAAU,KACpBsuB,GAAiB,OACZnmB,EAAG,OACR,MAAMtH,EAAO,IAAM+lB,GAAO5mB,QAAQqG,aAAyC,CAAC8B,EAAEtb,OAAQsb,EAAE22B,WACxFpR,GAAgB7sB,GAChBi2B,GAAcj2B,GACd,MAAM/Q,EAAM82B,GAAO5mB,QAAQqoB,UAAUlgB,EAAEtb,OACnCiD,GAAOqY,EAAE22B,YAAc32B,EAAE02B,YACzBrb,KAAsB,CAAEgU,OAAQ1nC,EAAKxM,MAAO6kB,EAAE22B,WAAajY,OAEnEnjC,OAAOqpB,iBAAiB,cAAegyB,GACvCr7C,OAAOqpB,iBAAiB,YAAaiyB,IA4zBKL,CAAkB3H,EAAIhjB,GAChDW,QAAUX,GAAUA,EAAMO,kBAC1BK,cAAgBZ,IACZA,EAAMO,kBACNsU,GAAgB,CAAE3nB,QAAS,CAACrU,MAEhCqwC,WAAW,EACXS,YAAc3pB,IACVA,EAAMiB,iBACNjB,EAAMO,uBAUxB0qB,GAAgC,OAAlBnd,EAAMod,QAAmB,KAAQpd,EAAMod,SAAW76C,GAChE86C,GAA8B,OAAjBrd,EAAMsd,OAAkB,KAAQtd,EAAMsd,QAAU1lB,GAC7D2lB,GAAoBvd,EAAMwd,eAAiB7f,GAC3C8f,GAAqBzd,EAAM0d,gBAAkB7f,GAC7C8f,GAAqB,IAAK5d,KAAiBt5B,EAAU22C,SACrDQ,GAAc,CAAEx9C,KAAM6/B,KAAex5B,EAAU+2C,eAC/CK,GAAe,IAAKp3C,EAAUi3C,gBAE9BI,IAAc3e,GAAgC,IAArB0G,GAAUx6B,OACnC0yC,GAAa1R,GAAa9F,GAAU8F,GAAWthC,YAAS0D,EAExDuvC,GAAkC,CACpCl9C,OAAQ,OACR8nB,SAAU,KACPiW,GAAca,MACdb,GAAcY,MACbI,GAEFoe,GAAiC,CAAEr1B,SAAU,KAAMiW,GAAce,MAAWf,GAAcc,IAC1Fue,GAAkC,IACjCrf,GAAct9B,MACds9B,GAAc57B,GACjB,2BAAqC,GAAG4qC,OACxC,wBAAkC,GAAG1N,QAInCge,GAAYl9C,EAAMw3B,QAAQ,KAC5B,MAAMzO,EAAgB,GAOtB,OANAnV,GAAe,sBAAsBsvB,OAAY5iC,EAAIyoB,GACrDnV,GAAe,sBAAsBsvB,OAAYlhC,EAAO+mB,GACxDnV,GAAe,wBAAwBsvB,OAAYzE,EAAQ1V,GAC3DnV,GAAe,wBAAwBsvB,OAAY1E,EAAWzV,GAC9DnV,GAAe,uBAAuBsvB,OAAYvE,EAAO5V,GACzDnV,GAAe,uBAAuBsvB,OAAYxE,EAAU3V,GACrDA,EAAIle,KAAK,OACjB,CAACq4B,GAAQ5iC,EAAI0B,EAAOy8B,EAAQD,EAAWG,EAAOD,IAE3Cye,GAAShR,GAAgB,GAAKA,GAAgB,IAE9CiR,GACFp9C,EAAAC,cAAA,MAAA,CACIkF,IAAKm+B,GACLl4B,GAAI83B,GAAM,mBACQA,GAClB9T,KAAK,OAAM,gBACIkH,GAAW,EAAC,gBACZ8W,GAAOjvB,QAAQ/T,OAAM,0BACd22B,IAAsBG,UAAqC1zB,EAAS,YAC/E0wB,QAAW1wB,EACtB2b,UAAW1e,EACP,YACC60B,GAAcoM,KAAa,wBAC5BA,IAAY,sBACX0B,GAAOoB,YAAc,6BACtBrlB,GAEJnnB,MAAOi7C,GACPlrB,UA/iCed,IACnB,GAAIiY,GAAa,OACjB,MAAM1iB,EAASyK,EAAMzK,OACrB,GACIA,IACoB,UAAnBA,EAAOK,SACe,WAAnBL,EAAOK,SACY,aAAnBL,EAAOK,SACY,WAAnBL,EAAOK,SAEX,OAEJ,MAAMw2B,EAAW7yC,KAAKD,IAAI,EAAGC,KAAK2Y,MAAM3Y,KAAKD,IAAI6hC,GAAiBQ,GAAc1N,IAAaA,KAC7F,OAAQjO,EAAMnwB,KACV,IAAK,YACDmwB,EAAMiB,iBACNmkB,GAAU,EAAG,GACb,MACJ,IAAK,UACDplB,EAAMiB,iBACNmkB,IAAU,EAAI,GACd,MACJ,IAAK,YACDplB,EAAMiB,iBACNmkB,GAAU,MACV,MACJ,IAAK,aACDplB,EAAMiB,iBACNmkB,GAAU,EAAG,GACb,MACJ,IAAK,WACDplB,EAAMiB,iBACNmkB,GAAUgH,EAAU,GACpB,MACJ,IAAK,SACDpsB,EAAMiB,iBACNmkB,IAAWgH,EAAU,GACrB,MACJ,IAAK,OACDpsB,EAAMiB,iBACNmkB,GAAU,EAAG,EAAGplB,EAAMqoB,SAAWroB,EAAMsoB,QAAU,CAAEruC,IAAK,QAAS6B,IAAK,SAAY,CAAEA,IAAK,UACzF,MACJ,IAAK,MACDkkB,EAAMiB,iBACNmkB,GAAU,EAAG,EAAGplB,EAAMqoB,SAAWroB,EAAMsoB,QAAU,CAAEruC,IAAK,OAAQ6B,IAAK,QAAW,CAAEA,IAAK,SACvF,MACJ,IAAK,QACL,IAAK,KACD,GAAIm+B,GAAa,CACb,MAAM7f,EAAOmZ,GAAU5lB,IAAIssB,GAAY9/B,IACvC,GAAmB,UAAfigB,GAAM9f,MAAoB2/B,GAAYphC,QAAUd,EAAuB,CACvE,MAAM0/B,EAAQC,GAAW/pB,IAAIssB,GAAY9/B,IACrCs9B,GAAOH,GAAwBG,EAAMt9B,IAAKmlC,GAAgB7H,GAClE,MACIzX,EAAMiB,iBACN2W,GAAkBqC,GAAY9/B,GAAI8/B,GAAYphC,MAEtD,CACA,MACJ,IAAK,IACD,GAAIohC,KAAgBnK,KAAsBE,IAA6B,CACnE,MAAM4D,EAAKD,GAAUh3B,KAAMwX,GAAMA,EAAEha,KAAO8/B,GAAY9/B,IAClDy5B,GAAkB,SAAZA,EAAGt5B,MAAmBs5B,EAAG35B,MAC/B+lB,EAAMiB,iBACNkV,GAAW,CAACvC,EAAGz5B,KAAMw7B,GAAY78B,IAAI86B,EAAGz5B,KAAK,GAErD,CACA,MACJ,IAAK,SACG0nB,GAAgBlK,MAAMoK,KACtBoY,IAAYC,GAAc,MAC9B,MACJ,SAESpa,EAAMqoB,SAAWroB,EAAMsoB,UACI,MAA5BtoB,EAAMnwB,IAAI6O,eACVoxB,KACCG,KAEDjQ,EAAMiB,iBACNkV,GAAW8L,IAAqB,OAi+BvCrU,GAAeqd,IACZl8C,EAAAC,cAAA,MAAA,CAAKkF,IAAKs+B,IACNzjC,EAAAC,cAACi8C,GAAW,IAAKQ,MAGzB18C,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,iBACXnpB,EAAAC,cAAA,MAAA,CAAKkF,IAAKq+B,GAAara,UAAU,oBAAoBm0B,SAAUvK,GAAcrhB,UAAU,GACnF1xB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBAAmBiG,KAAK,WAAWptB,MAAO,CAAEzB,MAAO6sC,GAAO4B,aACrEhvC,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,sBAAsBiG,KAAK,MAAK,gBAAgB,EAAGptB,MAAO,CAAEnC,OAAQ+sC,KAC9EQ,GAAOjvB,QAAQ1a,IAAI,CAACwwC,EAAIjxB,IAAUg3B,GAAiB/F,EAAIjxB,IACxDhjB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,6BAGtByY,IAAYhS,KAAOgS,GAAWhS,IAAIxlB,OAAS,GACxCpK,EAAAC,cAAA,MAAA,CACIkpB,UAAU,iDACViG,KAAK,WACLptB,MAAO,CAAE4tB,IAAKgd,GAAcrsC,MAAO6sC,GAAO4B,aAEzC+K,GAAiBnY,GAAWhS,IAAK,QAG1C5vB,EAAAC,cAAA,MAAA,CACIkpB,UAAW1e,EAAG,gBAAiB8nC,GAAU,yBAA2B,uBACpEnjB,KAAK,WACLptB,MACIuwC,GACM,CACI1yC,OAA6B,IAArB+kC,GAAUx6B,OAAeI,KAAKD,IAAI0nC,GAAQ9wB,MAAO,KAAO8wB,GAAQ9wB,MACxE5gB,MAAO6sC,GAAO4B,YAElB,CAAEzuC,MAAO6sC,GAAO4B,WAAYkK,UAAW2D,IAAc3e,EAAU,SAAM1wB,IAjW5E+vC,MACnB,MAAMn/C,MAAEA,EAAKC,IAAEA,GAAQm0C,GACjB3nB,EAA2B,GACjC,IAAK,IAAI9J,EAAI3iB,EAAO2iB,EAAI1iB,EAAK0iB,GAAK,EAAG,CACjC,MAAM8jB,EAAKD,GAAU7jB,GACfw2B,EAAYuC,GAAYjV,GACxB2Y,EAAevL,GAAQE,cAAcpxB,GACrCsU,EACU,SAAZwP,EAAGt5B,MAAmBX,QAAQi6B,EAAG35B,MAAQN,QAAQi3B,KAA0BqG,GAAqBn+B,IAAI86B,EAAGz5B,IACrGqyC,EAAgBpoB,GAAcwP,EAAG35B,IAAM22B,KAAwB8T,GAAe9Q,EAAGz5B,GAAIy5B,EAAG35B,MAAQ,KAChGwyC,KACFroB,GAAcwP,EAAG35B,KAAO42B,KACmC,SAArDA,GAAqB,CAAE12B,GAAIy5B,EAAGz5B,GAAIF,IAAK25B,EAAG35B,MAE9CyyC,IACDpL,KACAlT,GAA4B,SAAZwF,EAAGt5B,OAAmBs5B,EAAG35B,KAC0B,SAA9Dm0B,EAAa,CAAEj0B,GAAIy5B,EAAGz5B,GAAIusB,MAAOkN,EAAG35B,IAAKwhC,oBAEnD7hB,EAAM3W,KACFlU,EAAAC,cAAA,MAAA,CACIa,IAAKoM,OAAO23B,EAAGz5B,IACf+d,UAAU,qBACVnnB,MAAOuwC,GAAU,CAAE3iB,IAAKqiB,GAAQG,QAAQrxB,GAAIxgB,MAAO6sC,GAAO4B,YAAe,CAAEzuC,MAAO6sC,GAAO4B,aAExF0J,GAAiBnB,EAAW,CACzB13C,OAAQoyC,GAAQC,WAAWnxB,GAC3BiC,MAAOjC,EACP+3B,QAAe,IAAN/3B,EACTi4B,OAAQj4B,IAAM6jB,GAAUx6B,OAAS,EACjC6uC,OAAQ0E,IAEXtoB,SAAcooB,IAA2E,IAAlBA,GACpEz9C,EAAAC,cAAA,MAAA,CACIkpB,UAAU,wBACVnnB,MAAO,CACHnC,OAAQ69C,OAAalwC,EAAYgwC,QAAgBhwC,EACjDjN,MAAO4rC,SAAiB3+B,GAE5BokB,QAAUX,GAAUA,EAAMO,mBAEzBisB,IAKrB,CACA,OAAO5yB,GAqTU0yB,KAEF3b,IAAYnR,QAAUmR,GAAWnR,OAAOrmB,OAAS,GAAMwnC,KACtD5xC,EAAAC,cAAA,MAAA,CACIkpB,UAAU,oDACViG,KAAK,WACLptB,MAAO,CAAEzB,MAAO6sC,GAAO4B,aAEtB+K,GAAiBnY,IAAYnR,OAAQ,YAIjDyN,GACGl+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,6CAA6CnnB,MAAO,CAAE4tB,IAAKgd,KACtE5sC,EAAAC,cAACu8C,GAAkB,IAAKI,MAG/BC,IACG78C,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBAAmBnnB,MAAO,CAAE4tB,IAAKgd,KAC5C5sC,EAAAC,cAACq8C,GAAiB,IAAKK,QAIjCz2B,IAAck2B,IAAcp8C,EAAAC,cAACm8C,GAAU,IAAK52C,EAAU62C,SAExDr8C,EAAAC,cAACovB,IACGzG,KAAMkK,GAAgBlK,KACtB0G,SAAUwD,GAAgBxD,SAC1BC,QAASyD,GACT3zB,UAAWA,EACXmwB,UAAU,eACVC,WAAS,GAE6B,YAArCqD,GAAgBC,iBAAiC/yB,EAAAC,cAACo3B,GAAmB,MAAMr3B,EAAAC,cAACg5B,GAAkB,OAGlG6jB,IAAc1R,IACXprC,EAAAC,cAACy6B,IACGnC,OAAQukB,GACRxtB,SAAU8b,GAAW9b,SACrB1G,QACA2G,QAASA,IAAM8b,GAAc,MAC7BhsC,UAAWA,EACXs7B,cAAe8I,GAAWxmB,WAM1C,OACIjd,gBAACwc,GAAeohC,SAAQ,CAAC78C,MAAOs2C,IAC5Br3C,EAAAC,cAAA,MAAA,CACIkF,IAAKo+B,GACLpa,UAAW1e,EAAG,gBAAiB4zB,GAAe,uBAAwBC,GAAc,iBACpEj/B,uBACI6jC,GACpBlhC,MAAO+6C,IAENG,IAAal9C,EAAAC,cAAA,QAAA,CAAA,mBAAyBijC,IAASga,KAC9C7e,SAA2B7wB,IAAX4mB,GAAwBgK,GAA6BD,IACnEn+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,6BACC3b,IAAX4mB,GAAwBp0B,EAAAC,cAAA,KAAA,CAAIkpB,UAAU,uBAAuBiL,GAC7DgK,GACGp+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,+BAA+BiV,GAElDp+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,2BAA2BnnB,MAAO,CAAEw6B,IAAK2gB,GAAS,EAAI,KAChEhf,IAIbn+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,EAAG,eAAgB8zB,GAAa,oBAAqB2E,GAAQlhC,MAAOg7C,IAC/EI,KAKrB,CAEApf,GAAQthB,YAAc,UCtvFf,MAAMmhC,GAAiC,iBAOjCC,GAA4B,uwfAuLzC,IAAIjiC,IAAW,EAEf,MAcMC,GACD9b,EAAc+b,qBAAyC,oBAAXpb,OAAyBX,EAAMgc,gBAAkBhc,EAAMic,WAG3F8hC,GAA8BA,KACvCjiC,GAAa,KAnBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAeyhC,IAExB,YADAhiC,IAAW,GAGf,MAAM7Z,EAAQyY,SAASxa,cAAc,SACrC+B,EAAMoJ,GAAKyyC,GACX77C,EAAMqa,aAAa,eAAgB,QACnCra,EAAMsa,YAAcwhC,GACpBrjC,SAAS8B,KAAKjB,YAAYtZ,GAC1B6Z,IAAW,GASPM,IACD,KC/MDoQ,GAAaA,CAACvB,EAAuBtO,KACvC,MAAMpW,EAAOtG,EAAMoG,WAAiD,EAAGb,OAAO,GAAI4jB,YAAWnnB,WAAUwqB,GAAQrnB,IAC3GnF,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLsnB,QAAQ,YACRlsB,MAAOgF,EACP1F,OAAQ0F,EACRzF,KAAK,eACL4sB,UAAU,QAAO,cACL,OACZvD,UAAW,CAAC,eAAgBA,GAAWxe,OAAOC,SAASC,KAAK,KAC5D7I,MAAOA,KACHwqB,GAEHxB,IAIT,OADA1kB,EAAKoW,YAAcA,EACZpW,GAGE03C,GAAgBzxB,GACzBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,uKACR,iBAESmhB,GAAkBf,GAC3BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,6DACR,mBAESkhB,GAAmBd,GAC5BvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,2DACR,oBAES2gB,GAAYP,GACrBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,0GACR,aAGS8xC,GAAe1xB,GACxBvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,6IACR,gBAES+xC,GAAoB3xB,GAAWvsB,EAAAC,cAAA,OAAA,CAAMkM,EAAE,mBAAqB,sKCzCzEH,EAAMmyC,OAAOC,GAEN,MAAM3zC,GAAKA,IAAIC,IAAyDA,EAAWC,OAAOC,SAASC,KAAK,KAElGR,GAAQA,CAACtJ,EAAeuJ,EAAaC,IAAgBC,KAAKF,IAAIE,KAAKD,IAAIxJ,EAAOuJ,GAAMC,GAEpF8zC,GAA4B,CAAC,KAAM,MAGnCC,GAAWv9C,IACpB,GAAa,MAATA,GAA2B,KAAVA,EAAc,OAAO,KAC1C,GAAIiL,EAAMC,QAAQlL,GAAQ,OAAOA,EAAMmL,UAAYnL,EAAQ,KAC3D,GAAIA,aAAiB6K,MAAyB,iBAAV7K,GAAuC,iBAAVA,EAAoB,CACjF,MAAMqL,EAASJ,EAAMjL,GACrB,OAAOqL,EAAOF,UAAYE,EAAS,IACvC,CACA,OAAO,MAGEmyC,GAAYA,CAAC3tC,EAA6BC,MAAkCD,KAAOC,GAAKD,EAAE4tC,OAAO3tC,EAAG,OACpG4tC,GAAcA,CAAC7tC,EAAUC,IAAaD,EAAE8tC,SAAS7tC,EAAG,OACpD8tC,GAAaA,CAAC/tC,EAAUC,IAAaD,EAAEguC,QAAQ/tC,EAAG,OAClDguC,GAAgBA,CAACC,EAAY1gD,EAAqBC,OACzDD,IAAWC,GAAQogD,GAAYK,EAAK1gD,IAAWugD,GAAWG,EAAKzgD,IAExD0gD,GAAeA,CAACnuC,EAA6BC,KACtD,GAAID,IAAMC,EAAG,OAAO,EACpB,IAAKD,IAAMC,EAAG,OAAO,EACrB,MAAMmuC,EAAOA,CAACvQ,EAAiBwQ,IAA0B,MAALxQ,GAAkB,MAALwQ,KAAiBxQ,KAAOwQ,GAAKxQ,EAAE+P,OAAOS,EAAG,OAC1G,OAAOD,EAAKpuC,EAAE,GAAIC,EAAE,KAAOmuC,EAAKpuC,EAAE,GAAIC,EAAE,KAG/BquC,GAAkBn+C,GACtBmJ,MAAMC,QAAQpJ,GACZ,CAACu9C,GAAQv9C,EAAM,IAAKu9C,GAAQv9C,EAAM,KADPs9C,GAKzBc,GAAgBA,CAAChgD,EAAcqN,KACxC,MAAM4yC,EAAUjgD,EAAKoV,OACrB,IAAK6qC,EAAS,OAAO,KACrB,MAAMC,EAASrzC,EAAMozC,EAAS5yC,GAAQ,GACtC,GAAI6yC,EAAOnzC,UAAW,OAAOmzC,EAC7B,MAAMC,EAAY,CACd9yC,EAAOgH,QAAQ,MAAO,KAAKA,QAAQ,MAAO,KAC1C,WACA,SACA,aACA,aACA,YAEJ,IAAK,MAAMmL,KAAK2gC,EAAW,CACvB,MAAMlzC,EAASJ,EAAMozC,EAASzgC,GAAG,GACjC,GAAIvS,EAAOF,UAAW,OAAOE,CACjC,CACA,OAAO,MAGEC,GAAaA,CAACtL,EAAqByL,IAAoBzL,GAASA,EAAMmL,UAAYnL,EAAMyL,OAAOA,GAAU,GAqBzG+yC,GAAcA,CACvBT,EACAl5C,EACAhC,EACAihB,EAAa7Y,MAEF,MAAP8yC,EAAoB,KACnBA,EAAI5yC,UACLtI,EAAQ47C,aAAef,GAAYK,EAAKj6B,GAAa,cACrDjhB,EAAQ67C,eAAiBd,GAAWG,EAAKj6B,GAAa,gBACtDjhB,EAAQ87C,SAAWjB,GAAYK,EAAKl7C,EAAQ87C,SAAiB,UAC7D97C,EAAQ+7C,SAAWhB,GAAWG,EAAKl7C,EAAQ+7C,SAAiB,UAC5D/7C,EAAQg8C,oBAAoBd,EAAKl5C,GAAkB,oBAChD,KANoB,cASlBi6C,GAAgBA,CACzB9+C,EACA6C,KAEA,MAAMihB,EAAM7Y,IACN8zC,EAAaP,GAAYx+C,EAAM,GAAI,QAAS6C,EAASihB,GACrDk7B,EAAWR,GAAYx+C,EAAM,GAAI,MAAO6C,EAASihB,GACvD,OAAKi7B,IAAeC,GAAYh/C,EAAM,IAAMA,EAAM,IAAM49C,GAAW59C,EAAM,GAAIA,EAAM,IACxE,CAAC,eAAgB,gBAErB,CAAC++C,EAAYC,IAGXC,GAAgBA,CAAClB,EAAYl5C,EAAgChC,IAC/B,MAAvC27C,GAAYT,EAAKl5C,EAAUhC,GAelBq8C,GAAgBA,CAACC,EAAcC,KACxC,MAAMC,EAAeF,EAAMxzC,QAAQ,SAC7BtO,EAAQgiD,EAAa1zC,QAAQ,QAC7B2zC,EAAe71C,KAAKmnC,KAAKyO,EAAaE,MAAM,SAASC,KAAKniD,EAAO,OAAS,EAAI,EAAI,GAClFoiD,EAAYL,GAAmBA,EAAkB,EAAIA,EAAkB31C,KAAKD,IAAI81C,EAAc,GAC9FI,EAAwB,GAC9B,IAAK,IAAIp8B,EAAI,EAAGA,EAAIm8B,EAAWn8B,GAAK,EAAG,CACnC,MAAMq8B,EAAYtiD,EAAMsN,IAAQ,EAAJ2Y,EAAO,OACnCo8B,EAAMvsC,KAAK,CACPpT,IAAK4/C,EAAUl0C,OAAO,cACtBm0C,KAAMz2C,MAAM6O,KAAK,CAAE3O,OAAQ,GAAK,CAACw2C,EAAGz0C,KAChC,MAAM2yC,EAAM4B,EAAUh1C,IAAIS,EAAG,OAC7B,MAAO,CAAE2yC,MAAK+B,cAAe/B,EAAIN,OAAO4B,EAAc,aAGlE,CACA,OAAOK,GAGEK,GAAoBC,IAC7B,MAAM3iD,EAAQ4N,IAAQU,QAAQ,QAC9B,OAAOxC,MAAM6O,KAAK,CAAE3O,OAAQ,GAAK,CAACw2C,EAAG7/B,KACjC,MAAM+9B,EAAM1gD,EAAMsN,IAAIqV,EAAG,OACzB,MAAO,CAAEjgB,IAAKg+C,EAAItyC,OAAO,MAAOS,MAAO8zC,EAAUjC,GAAMkC,KAAMlC,EAAItyC,OAAO,YAQnEy0C,GAA2D,CACpE,CACIh0C,MAAO,YACPi0C,SAAUA,KACN,MAAMC,EAAQn1C,IACd,MAAO,CAACm1C,EAAMz0C,QAAQ,QAASy0C,EAAMb,MAAM,WAGnD,CACIrzC,MAAO,YACPi0C,SAAUA,KACN,MAAMxwB,EAAO1kB,IAAQo1C,SAAS,EAAG,OACjC,MAAO,CAAC1wB,EAAKhkB,QAAQ,QAASgkB,EAAK4vB,MAAM,WAGjD,CACIrzC,MAAO,cACPi0C,SAAUA,KACN,MAAMC,EAAQn1C,IACd,MAAO,CAACm1C,EAAMC,SAAS,EAAG,OAAQD,KAG1C,CACIl0C,MAAO,gBACPi0C,SAAUA,KACN,MAAMC,EAAQn1C,IACd,MAAO,CAACm1C,EAAMz0C,QAAQ,SAAUy0C,EAAMb,MAAM,YAGpD,CACIrzC,MAAO,aACPi0C,SAAUA,KACN,MAAMpjC,EAAO9R,IAAQN,IAAI,EAAG,SAC5B,MAAO,CAACoS,EAAKpR,QAAQ,SAAUoR,EAAKwiC,MAAM,YAGlD,CAAErzC,MAAO,QAASi0C,SAAUA,IAAM,CAAC,KAAM,QCtLvCG,GAA6BvC,GAAeA,EAAItyC,OAAO,MAAMuH,OAAO,GAAGutC,cAMvE,SAAUC,IACZxgD,MAAOygD,EAASpkC,aAChBA,EAAYC,SACZA,EACAokC,cAAeC,EAAiBC,sBAChCA,EAAqBC,UACrBA,EAAY,EAACC,cACbA,EAAanC,QACbA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiBrtB,SACjBA,GAAW,EAAKuvB,SAChBA,GAAW,EAAKC,4BAChBA,GAA8B,EAAK5B,gBACnCA,EAAe6B,mBACfA,EAAqBX,GAAyBY,sBAC9CA,GAAwB,EAAKC,iBAC7BA,GAAmB,EAAIzyB,UACvBA,GAAY,EAAK0yB,cACjBA,EAAavvB,WACbA,EAAUvzB,UACVA,EAAS8pB,UACTA,EAASnnB,MACTA,IAEA+7C,KAEA,MAAMzgC,OAA6B9P,IAAdg0C,GACdY,EAAeC,GAAoBriD,EAAMyd,SAAuB,IACnEyhC,GAAe9hC,GAAgBihC,KAE7Bt9C,EAAQf,EAAMw3B,QAChB,IAAOla,EAAe4hC,GAAesC,GAAaY,EAClD,CAAC9kC,EAAckkC,EAAWY,KAEvBhkD,EAAOC,GAAO0C,GAEduhD,EAAkBC,GAAuBviD,EAAMyd,SAA+B,SAC/EgkC,EAAgBC,GAAqBY,EACrCE,EAAmBxiD,EAAM6d,YAC1BjY,SAC6B4H,IAAtBk0C,GAAiCa,EAAoB38C,GACzD+7C,IAAwB/7C,IAE5B,CAAC87C,EAAmBC,IAGlBc,EAAaziD,EAAMw3B,QACrB,KAAA,CAASkoB,UAASC,UAASH,cAAaC,gBAAeG,sBACvD,CAACF,EAASC,EAASH,EAAaC,EAAeG,KAI5C8C,EAAcC,GAAmB3iD,EAAMyd,SAAgB,KACzDrf,GAASC,GAAOwjD,GAAiB71C,KAASU,QAAQ,UAEjDk2C,EAAgB5iD,EAAMw3B,QACxB,IAAMttB,MAAM6O,KAAK,CAAE3O,OAAQw3C,GAAa,CAAChB,EAAG7/B,IAAM2hC,EAAah3C,IAAIqV,EAAG,UACtE,CAAC2hC,EAAcd,IAEbiB,EAAmBD,EAAcA,EAAcx4C,OAAS,GAExD04C,EAAc9iD,EAAM6d,YACrBqiC,IACG,MAAMpiC,EAAOoiC,EAAMxzC,QAAQ,SAC3Bi2C,EAAiBjyB,GACTA,EAAK8tB,OAAO1gC,EAAM,SAAiB4S,GACvCyxB,IAAgBrkC,GACTA,KAGf,CAACqkC,IAGCY,EAAgB/iD,EAAM6d,YACvBihC,IACOL,GAAYK,EAAK4D,EAAah2C,QAAQ,UAAWo2C,EAAYhE,GACxDH,GAAWG,EAAK+D,EAAiBvC,MAAM,WAAWwC,EAAYhE,EAAIsC,SAASQ,EAAY,EAAG,WAEvG,CAACc,EAAcG,EAAkBjB,EAAWkB,IAI1CE,EAAchjD,EAAMgd,OAAqBjc,GAC/Cf,EAAMic,UAAU,KACZ,MAAMyU,EAAOsyB,EAAY/lC,QACzB+lC,EAAY/lC,QAAUlc,EACtB,MAAMylB,EAA2B,QAAlBi7B,EAA2BpjD,GAAOD,EAAUA,GAASC,EACpE,IAAKmoB,EAAQ,SACI+3B,GAAU7tB,EAAK,GAAItyB,KAAWmgD,GAAU7tB,EAAK,GAAIryB,KACrD0kD,EAAcv8B,IAE5B,CAACpoB,EAAOC,IAEX,MAAM4kD,GAAavD,GAAWgD,EAAa9D,QAAQc,EAAS,SACtDwD,GAAavD,GAAWkD,EAAiBnE,SAASiB,EAAS,UAG1DwD,EAAYC,GAAiBpjD,EAAMyd,SAAuB,MAC3D4lC,EAAUrjD,EAAMw3B,QAAsB,KACnC0qB,IAAqBiB,GAAc5wB,GAAYuvB,EAAiBzD,GAC/C,QAAlBoD,GAA2BrjD,IAAUC,EAC9BogD,GAAY0E,EAAY/kD,GAASigD,GAAc,CAACjgD,EAAO+kD,GAE5C,UAAlB1B,GAA6BpjD,IAAQD,EAC9BugD,GAAWwE,EAAY9kD,GAAOggD,GAAc,CAAC8E,EAAY9kD,GAE7DggD,GACR,CAAC6D,EAAkBiB,EAAY1B,EAAerjD,EAAOC,EAAKk0B,EAAUuvB,IAGjEwB,EAAYtjD,EAAM6d,YACnBihC,IACG,GAAIvsB,GAAYuvB,EAAU,OAC1B,GAAI9B,GAAclB,EAAK2C,EAAegB,GAAa,OACnD,IAAI3kC,EACAylC,EACkB,UAAlB9B,GAEA3jC,EAAO,CAACghC,EAAKzgD,GAAOsgD,GAAWG,EAAKzgD,GAAO,KAAOA,GAClDklD,EAAe,OACRnlD,GAASqgD,GAAYK,EAAK1gD,IAEjC0f,EAAO,CAACghC,EAAK,MACbyE,EAAe,QAEfzlC,EAAO,CAAC1f,EAAO0gD,GACfyE,EAAe,SAEdjmC,GAAc+kC,EAAiBvkC,GACpCT,IAAWS,EAAMghC,EAAK2C,GACtBe,EAAiBe,IAErB,CAAChxB,EAAUuvB,EAAUL,EAAegB,EAAYpkD,EAAKD,EAAOkf,EAAcD,EAAUmlC,KAIjFgB,EAAYC,GAAiBzjD,EAAMyd,SAAgB,IAAMrf,GAASC,GAAOwjD,GAAiB71C,KAC3Fs3B,EAAUtjC,EAAMgd,OAA8B,MAC9CwsB,GAAkBxpC,EAAMgd,OAAOyS,GAE/Bi0B,GAAW1jD,EAAM6d,YAAaihC,IAChC,MAAMh+C,EAAMg+C,EAAItyC,OAAO,cACjB9I,EAAK4/B,EAAQrmB,SAASqU,cAAiC,cAAcxwB,OAC3E4C,GAAI0mB,SACL,IAEHpqB,EAAMic,UAAU,KACZ,IAAKutB,GAAgBvsB,QAAS,OAC9BusB,GAAgBvsB,SAAU,EAC1B,MAAMuJ,EAASg9B,EACfT,EAAcv8B,GAEd,MAAMpb,EAAKzK,OAAO6a,WAAW,IAAMkoC,GAASl9B,GAAS,GACrD,MAAO,IAAM7lB,OAAOopB,aAAa3e,IAElC,IAEH,MAMMimB,GAAgBA,CAACJ,EAAyC6tB,KAC5D,IAAIhhC,EAAqB,KACzB,OAAQmT,EAAMnwB,KACV,IAAK,YACDgd,EAAOghC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,aACDtjC,EAAOghC,EAAIpzC,IAAI,EAAG,OAClB,MACJ,IAAK,UACDoS,EAAOghC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,YACDtjC,EAAOghC,EAAIpzC,IAAI,EAAG,OAClB,MACJ,IAAK,OACDoS,EAAOghC,EAAIpyC,QAAQ,QACnB,MACJ,IAAK,MACDoR,EAAOghC,EAAIwB,MAAM,QACjB,MACJ,IAAK,SACDxiC,EAAOmT,EAAMooB,SAAWyF,EAAIsC,SAAS,EAAG,QAAUtC,EAAIsC,SAAS,EAAG,SAClE,MACJ,IAAK,WACDtjC,EAAOmT,EAAMooB,SAAWyF,EAAIpzC,IAAI,EAAG,QAAUozC,EAAIpzC,IAAI,EAAG,SACxD,MACJ,IAAK,QACL,IAAK,IAGD,OAFAulB,EAAMiB,sBACNoxB,EAAUxE,GAEd,QACI,OAER7tB,EAAMiB,iBACFpU,GA1CWghC,KACf2E,EAAc3E,GACdiE,EAAcjE,GACdn+C,OAAO6a,WAAW,IAAMkoC,GAAS5E,GAAM,IAuC7BzI,CAAUv4B,IAGlB6lC,GAAW3jD,EAAMw3B,QAAQ,IAAMspB,GAAiBkB,GAAqB,CAACA,IACtEb,GAAQn1C,IACR43C,GAAeP,EAAQ,GACvBQ,GAAaR,EAAQ,GACrBS,KAAoB1lD,KAAWC,EAsIrC,OACI2B,uBACImF,IAAKm+B,EACLna,UAAW1e,GACP,oBACA8nB,GAAY,6BACZuvB,GAAY,8BACZ34B,GACH,iBACe9pB,wBACKoiD,EACrBz/C,MAAOA,EACP+hD,aAAcA,IAAMX,EAAc,OAEjCR,EAAcn/C,IAlJHugD,CAAC9D,EAAcl9B,KAC/B,MAAMy9B,EAAQR,GAAcC,EAAOC,GAC7BrH,EAAoB,IAAV91B,EACVg2B,EAASh2B,IAAU4/B,EAAcx4C,OAAS,EAE1C65C,GADiBT,EAAWhF,OAAO0B,EAAO,SAAWsD,EAAa,QAGnEplD,GAASA,EAAMogD,OAAO0B,EAAO,SAAW9hD,EAAQ,QAChDC,GAAOA,EAAImgD,OAAO0B,EAAO,SAAW7hD,EAAM,QAC1Cy6C,IAAY8J,EAAczxB,KAAM1d,GAAM+vC,EAAWhF,OAAO/qC,EAAG,UAAYysC,EAAMxzC,QAAQ,SAAW,MAErG,OACI1M,EAAAC,cAAA,MAAA,CACIa,IAAKo/C,EAAM1zC,OAAO,WAClB2c,UAAU,mBACViG,KAAK,QAAO,aACA8wB,EAAM1zC,OAAO,cAEzBxM,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,2BACV2vB,EACG94C,0BACIuL,KAAK,SACL4d,UAAU,gCAA+B,aAC7ByJ,GAAYsxB,eAAiB,iBACzChiD,MAAO0wB,GAAYsxB,eAAiB,iBACpC3xB,SAAUA,IAAa0wB,EACvBrxB,QAASA,IAAMkxB,EAAYJ,EAAatB,SAAS,EAAG,WAEpDphD,EAAAC,cAACqtB,GAAe,OAGpBttB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,gCAEpBnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBAAwB,YAAW,UAC7C+2B,EAAM1zC,OAAO,cAEjBwsC,EACGh5C,0BACIuL,KAAK,SACL4d,UAAU,gCAA+B,aAC7ByJ,GAAYuxB,WAAa,aACrCjiD,MAAO0wB,GAAYuxB,WAAa,aAChC5xB,SAAUA,IAAa2wB,EACvBtxB,QAASA,IAAMkxB,EAAYJ,EAAah3C,IAAI,EAAG,WAE/C1L,EAAAC,cAACotB,GAAgB,OAGrBrtB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,iCAGxBnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBAAmBiG,KAAK,OAClCu0B,GAASlgD,IAAK2gD,GACXpkD,wBAAMc,IAAKsjD,EAAGtjD,IAAKqoB,UAAU,kBAAkBiG,KAAK,eAAc,aAAag1B,EAAGpD,MAC7EoD,EAAGn3C,SAIhBjN,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,gBAAgBiG,KAAK,OAAM,aAAa8wB,EAAM1zC,OAAO,cAC/Di0C,EAAMh9C,IAAK4gD,GACRrkD,EAAAC,cAAA,MAAA,CAAKa,IAAKujD,EAAKvjD,IAAKqoB,UAAU,eAAeiG,KAAK,OAC7Ci1B,EAAK1D,KAAKl9C,IAAI,EAAGq7C,MAAK+B,gBAAgByD,KACnC,MAAMC,EAAS1D,IAAiBkB,EAC1ByC,EAAUjG,GAAUO,EAAK1gD,GACzBqmD,EAAQlG,GAAUO,EAAKzgD,GACvBi0B,EAAWkyB,GAAWC,EACtBC,GAAWH,GAAUT,IAAmBjF,GAAcC,EAAK1gD,EAAOC,GAClEsmD,GACDJ,KACCX,MACAC,IACFhF,GAAcC,EAAK8E,GAAcC,IAC/Be,EAAcryB,GAAYytB,GAAclB,EAAK2C,EAAegB,GAC5DoC,IAAeZ,GAAe1F,GAAUO,EAAKmF,KAAiBM,EAC9DO,EAA4B,IAAbR,IAAoBvC,GAA8C,IAAfjD,EAAIvyC,OACtEw4C,EACW,IAAbT,IAAoBvC,GAA+BjD,EAAIvyC,SAAWuyC,EAAIkG,cAC1E,OACIhlD,EAAAC,cAAA,MAAA,CACIa,IAAKg+C,EAAItyC,OAAO,cAChB4iB,KAAK,2BACUkD,QAAY9kB,EAC3B2b,UAAW1e,GACP,mBACAi6C,GAAW,6BACXA,GAAWF,GAAW,gCACtBE,GAAWD,GAAS,8BACpBE,GAAa,4BACbA,GAAapG,GAAUO,EAAK8E,KAAiB,kCAC7Ce,GAAapG,GAAUO,EAAK+E,KAAe,gCAC3CiB,GAAgB,kCAChBC,GAAe,mCAGnB/kD,EAAAC,cAAA,SAAA,CACIsL,KAAK,oBACKuzC,EAAItyC,OAAO,cACrBklB,SAAUmzB,EAAa,GAAI,EAAE,aACjB/F,EAAItyC,OAAO,sBAAqB,gBAEvCy1C,GAAyB1D,GAAUO,EAAKqC,IAAS,YAAS3zC,kBAEhDo3C,QAAep3C,EAC9B+kB,SAAUgyB,EACVp7B,UAAW1e,GACP,cACA85C,GAAU,sBACV1D,IAAiB0D,GAAU,uBAC3BjyB,GAAY,yBACX2vB,GAAyB1D,GAAUO,EAAKqC,KAAU,qBACnDyD,GAAe,yBAEnBhzB,QAASA,IAAM0xB,EAAUxE,GACzBmG,aAAcA,IAAM7B,EAActE,GAClCiF,aAAcA,IACVX,EAAe1yB,GAAUA,GAAQ6tB,GAAU7tB,EAAMouB,GAAO,KAAOpuB,GAEnEw0B,QAASA,IAAMzB,EAAc3E,GAC7B/sB,UAAYd,GAAUI,GAAcJ,EAAO6tB,IAE1CA,EAAIvyC,iBA6BjD,CCtWM,SAAU8iB,IAAQzG,KACpBA,EAAI0G,SACJA,EAAQE,UACRA,EAAS21B,UACTA,EAAS9lD,UACTA,EAAS8pB,UACTA,EAASnnB,MACTA,EAAKojD,WACLA,EAAU78C,SACVA,IAEA,MAAMpD,EAAMnF,EAAMgd,OAA8B,OACzCpX,EAAU+pB,GAAe3vB,EAAMyd,SAAS,CAAEmS,IAAK,EAAGC,KAAM,EAAGC,OAAO,IAEnEC,EAAS/vB,EAAM6d,YAAY,KAC7B,MAAMna,EAAKyB,EAAI8X,QACf,IAAKvZ,EAAI,OACT,MAAMssB,EAAKrvB,OAAOsvB,WACZC,EAAKvvB,OAAOwvB,YACZ9L,EAAI3gB,EAAG0sB,YACPrQ,EAAIrc,EAAG2sB,aACb,IAAIT,EACAC,EACJ,GAAIP,GAAYA,EAASgB,YAAa,CAClC,MAAM1f,EAAI0e,EAASiB,wBACnBX,EAAMhf,EAAE6f,OAAS,EACbb,EAAM7P,EAAImQ,EAAK,GAAKtf,EAAEgf,IAAM,EAAI7P,GAAK,IAAG6P,EAAMhf,EAAEgf,IAAM,EAAI7P,GAC9D8P,EAAqB,eAAdL,EAA6B5e,EAAE4f,MAAQnM,EAAkB,WAAdmL,EAAyB5e,EAAEif,KAAOjf,EAAErQ,MAAQ,EAAI8jB,EAAI,EAAIzT,EAAEif,IAChH,MACID,EAAMM,EAAK,EAAInQ,EAAI,EACnB8P,EAAOG,EAAK,EAAI3L,EAAI,EAExBuL,EAAMvlB,GAAMulB,EAAK,EAAGplB,KAAKD,IAAI,EAAG2lB,EAAKnQ,EAAI,IACzC8P,EAAOxlB,GAAMwlB,EAAM,EAAGrlB,KAAKD,IAAI,EAAGylB,EAAK3L,EAAI,IAC3CsL,EAAae,GAAUA,EAAKZ,OAASY,EAAKd,MAAQA,GAAOc,EAAKb,OAASA,EAAOa,EAAO,CAAEd,MAAKC,OAAMC,OAAO,KAC1G,CAACR,EAAUE,IA4Cd,OA1CAxvB,EAAMgc,gBAAgB,KAClB,IAAK4M,EAED,YADA+G,EAAae,GAAUA,EAAKZ,MAAQ,IAAKY,EAAMZ,OAAO,GAAUY,GAGpEX,IACApvB,OAAOqpB,iBAAiB,SAAU+F,GAClCpvB,OAAOqpB,iBAAiB,SAAU+F,GAAQ,GAC1C,IAAIY,EAAkC,KAKtC,MAJ8B,oBAAnBC,gBAAkCzrB,EAAI8X,UAC7C0T,EAAW,IAAIC,eAAe,IAAMb,KACpCY,EAASE,QAAQ1rB,EAAI8X,UAElB,KACHtc,OAAOmwB,oBAAoB,SAAUf,GACrCpvB,OAAOmwB,oBAAoB,SAAUf,GAAQ,GAC7CY,GAAUI,eAEf,CAACnI,EAAMmH,IAEV/vB,EAAMic,UAAU,KACZ,IAAK2M,EAAM,OACX,MAAMoI,EAAqBC,IACvB,MAAMzK,EAASyK,EAAMzK,OAChBA,IACDrhB,EAAI8X,SAASiU,SAAS1K,IACtB8I,GAAU4B,SAAS1K,IACvB2+B,EAAU,cAER9zB,EAAiBJ,IACD,WAAdA,EAAMnwB,KAAkBqkD,EAAU,WAK1C,OAHA1qC,SAASuP,iBAAiB,YAAagH,GAAmB,GAC1DvW,SAASuP,iBAAiB,aAAcgH,GAAmB,GAC3DvW,SAASuP,iBAAiB,UAAWqH,GAC9B,KACH5W,SAASqW,oBAAoB,YAAaE,GAAmB,GAC7DvW,SAASqW,oBAAoB,aAAcE,GAAmB,GAC9DvW,SAASqW,oBAAoB,UAAWO,KAE7C,CAACzI,EAAMu8B,EAAW71B,IAEhB1G,GAA4B,oBAAbnO,SAEbgX,eACHzxB,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLiqB,KAAK,sBACM,QAAO,kBACDg2B,EACjB1zB,UAAU,EACVvI,UAAW1e,GAAG,kBAAmB0e,GAAU,iBAC3B9pB,EAChB2C,MAAO,CAAE4tB,IAAKhqB,EAASgqB,IAAKC,KAAMjqB,EAASiqB,KAAM8B,WAAY/rB,EAASkqB,MAAQ,UAAY,YAAa9tB,GACvG8vB,YAAcb,GAAUA,EAAMO,mBAE7BjpB,GAELkS,SAASY,MAhBwC,IAkBzD,CAgCO,MAAMzW,GAAY5E,EAAMoG,WAA2C,UACtEgF,GACIA,EAAE6B,MACFA,EAAKlM,MACLA,EAAKuE,YACLA,EAAWC,KACXA,EAAI8/C,UACJA,EAASC,MACTA,EAAK/yB,SACLA,EAAQuvB,SACRA,EAAQyD,SACRA,EAAQz/B,MACRA,EAAK0/B,QACLA,EAAOC,UACPA,EAAS1tC,KACTA,EAAI0X,UACJA,EAASpqB,SACTA,EAAQqgD,UACRA,EAASC,UACTA,EAAStoC,SACTA,EAAQ6nC,QACRA,EAAO1vB,OACPA,EAAM5D,QACNA,EAAOG,UACPA,GAEJ5sB,GAEA,MAAMygD,EAAoB,MAAT34C,GAA2B,KAAVA,EAC5B44C,EAASL,GAAqB,KAAVzkD,IAAiB6kD,EAC3C,OACI5lD,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLgkB,UAAW1e,GACP,gBACA,kBAAkBlF,IAClB8/C,GAAa,4BACbC,GAAS,uBACTO,GAAU,wBACVL,GAAW,yBACXjzB,GAAY,0BACZzM,GAAS,uBACT2/B,GAAa,4BACZG,GAAY,4BACXF,GAAa,0BAEnB9zB,QAASA,GAERg0B,GACG5lD,EAAAC,cAAA,QAAA,CAAOkpB,UAAU,gBAAgB2F,QAAS1jB,GACrC6B,EACAs4C,GACGvlD,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,yBAAwB,cAAa,QAAM,MAMvEnpB,EAAAC,cAAA,QAAA,CACImL,GAAIA,EACJjG,IAAKE,EACL0S,KAAMA,EACNoR,UAAU,gBACV5d,KAAK,OACLu6C,UAAU,UACVC,aAAa,MACbC,YAAY,EACZjlD,MAAOA,EACPuE,YAAaugD,EAASvgD,OAAckI,EACpC+kB,SAAUA,EACVuvB,SAAUA,EACVyD,SAAUA,EACV91B,UAAWA,eACCk2B,EAAS,eACP7/B,QAAStY,EACvB6P,SAAW4T,GAAU5T,EAAS4T,EAAMzK,OAAOzlB,OAC3CmkD,QAASA,EACT1vB,OAAQA,EACRzD,UAAWA,IAEd2zB,GAAa1lD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,qBAAqBu8B,GAClD1lD,EAAAC,cAAA,WAAA,CAAA,cAAsB,OAAOkpB,UAAU,mBACnCnpB,EAAAC,cAAA,SAAA,KACID,EAAAC,cAAA,OAAA,KACK2lD,EAAW34C,EAAQ,GACnB24C,GAAYL,EAAW,KAAO,MAMvD,GC5NaU,GAA0E,CACnF7nD,MAAO,QACPC,IAAK,MACL6nD,eAAgB,IAChBC,WAAY,oBACZ/wB,MAAO,QACP+rB,MAAO,QACPlJ,OAAQ,SACRmO,OAAQ,KACRlC,cAAe,iBACfC,UAAW,aACXkC,aAAc,qBAgBLC,GAAqBtmD,EAAMoG,WAAoD,UAEpFrF,MAAOygD,EAASpkC,aAChBA,EAAYC,SACZA,EAAQkpC,SACRA,EAAQC,QACRA,EACA59B,KAAM69B,EAAQC,OACdA,EAAMn3B,QACNA,EACAkyB,cAAeC,EAAiBC,sBAChCA,EAAqB10C,MACrBA,EAAKT,OACLA,EA1Be,aA0BQm6C,aACvBA,EAAe,SAAQphD,KACvBA,EAAO,QAAO8/C,UACdA,GAAY,EAAKuB,UACjBA,GAAY,EAAKC,YACjBA,EAAWC,kBACXA,GAAoB,EAAKC,cACzBA,EAAaC,UACbA,EAAShqB,QACTA,EAAU,GAAE6B,YACZA,GAAc,EACdjM,WAAYqM,EAAc2iB,UAC1BA,EAAY,EAACC,cACbA,EAAanC,QACbA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiBrtB,SACjBA,GAAW,EAAKuvB,SAChBA,GAAW,EAAKC,4BAChBA,EAA2B5B,gBAC3BA,EAAe6B,mBACfA,EAAkBC,sBAClBA,EAAqBC,iBACrBA,EAAgBC,cAChBA,EAAapqC,KACbA,EACA3M,GAAI67C,EACJ3hD,YAAa4hD,EAAe3B,SAC5BA,EACAz/B,MAAOqhC,EAASC,WAChBA,EAAU33B,UACVA,EAASpqB,SACTA,EAAQhG,UACRA,EAASu/B,UACTA,EAASzV,UACTA,EAASnnB,MACTA,EAAKqlD,iBACLA,EAAgBC,aAChBA,EAAY93B,UACZA,GAAY,gBAEhBrqB,IAEA44C,KAEA,MAAMnrB,GAAa5yB,EAAMw3B,QACrB,KAAA,IAAYyuB,MAA8ChnB,IAC1D,CAACA,IAECsoB,GAAkB30B,GAAW20B,iBAAmB/6C,EAChDg7C,GAA2B,UAAjBb,EACVc,GAAsBZ,GAAeW,GACrCE,GAAwBX,IAAkB/pB,EAAQ2qB,SAAS,UAE3DC,GAAU5nD,EAAMojC,QAChBykB,GAASZ,GAAU,WAAWW,GAAQp0C,QAAQ,KAAM,MACpDs0C,GAAUN,GAAU,GAAGK,WAAiBA,GACxCE,GAAQ,GAAGF,SACXG,GAAgB,GAAGH,WAGnBvqC,QAA6B9P,IAAdg0C,GACdY,GAAeC,IAAoBriD,EAAMyd,SAAuB,IACnEyhC,GAAe9hC,GAAgBihC,KAE7Bt9C,GAAQf,EAAMw3B,QAChB,IAAOla,GAAe4hC,GAAesC,GAAaY,GAClD,CAAC9kC,GAAckkC,EAAWY,MAEvBhkD,GAAOC,IAAO0C,GAEf0hD,GAAaziD,EAAMw3B,QACrB,KAAA,CAASkoB,UAASC,UAASH,cAAaC,gBAAeG,sBACvD,CAACF,EAASC,EAASH,EAAaC,EAAeG,IAE7CqI,GAAkBjoD,EAAMw3B,QAAQ,IAAMqoB,GAAc9+C,GAAO0hD,IAAa,CAAC1hD,GAAO0hD,KAChFv2C,GAAUlM,EAAM6d,YACjBqqC,GAAwBrI,GAAcqI,EAAOzF,IAAYttC,MAAOmvB,GAAW,MAALA,GACvE,CAACme,KAGC0F,GAAenoD,EAAMgd,OAA0E,MACrGhd,EAAMic,UAAU,KACZ,MAAMyU,EAAOy3B,GAAalrC,QACtByT,GAAQA,EAAK,KAAOu3B,GAAgB,IAAMv3B,EAAK,KAAOu3B,GAAgB,MAC7D,OAATv3B,GAAiBu3B,GAAgB,IAAMA,GAAgB,KAAIzB,IAAUyB,GAAiBlnD,IAC1FonD,GAAalrC,QAAUgrC,KACxB,CAACA,GAAiBlnD,GAAOylD,IAE5B,MAAM4B,GAAWpoD,EAAM6d,YACnB,CAACC,EAAoBuqC,KACZ/qC,IAAc+kC,GAAiBvkC,GACpC,MAAMwqC,EAAqC,CAAEL,gBAAiBpI,GAAc/hC,EAAM2kC,KAC9E4F,IAAUC,EAAQD,SAAWA,GACjChrC,IAAWS,EAAMwqC,IAErB,CAAChrC,GAAcD,EAAUolC,MAItBH,GAAkBC,IAAuBviD,EAAMyd,SAA+B,SAC/EgkC,GAAgBC,GAAqBY,GACrCE,GAAmBxiD,EAAM6d,YAC1BjY,SAC6B4H,IAAtBk0C,GAAiCa,GAAoB38C,GACzD+7C,IAAwB/7C,IAE5B,CAAC87C,EAAmBC,IAIlB4G,QAAgC/6C,IAAbi5C,GAClB+B,GAAcC,IAAmBzoD,EAAMyd,UAAS,GACjDmL,GAAO2/B,KAAqB9B,EAAW+B,GACvCE,GAAiB1oD,EAAMgd,OAAqBjc,IAC5C4nD,GAAkB3oD,EAAMgd,OAAqBjc,IAG7CqlD,GAASpmD,EAAM6d,YACjB,CAACC,EAAoB8qC,GAAQ,MACpBA,GAAS7J,GAAajhC,EAAM6qC,GAAgB1rC,WACjD0rC,GAAgB1rC,QAAUa,EAC1ByoC,IAAWzoC,KAEf,CAACyoC,IAECjjB,GAAUtjC,EAAMgd,OAA8B,MAC9C6rC,GAAY7oD,EAAMgd,OAAiC,MACnD8rC,GAAkB9oD,EAAMgd,OAA2B,OAIlD+rC,GAAgBC,IAAqBhpD,EAAMyd,cAAuCjQ,GACzFxN,EAAMic,UAAU,KACZ,QAAkBzO,IAAdnO,EAAyB,OAC7B,MAAM4pD,EAAO3lB,GAAQrmB,SAASisC,eAAe93B,QAAQ,qBAAqB+3B,aAAa,kBACvFH,GAA2B,SAATC,EAAkB,OAAkB,UAATA,EAAmB,aAAUz7C,KAE9E,MAAM47C,GAAqB/pD,GAAa0pD,IAIjCz5B,GAAU+5B,IAAerpD,EAAMyd,SAAgC,MAChE6rC,GAAatpD,EAAM6d,YACpBwN,IACGiY,GAAQrmB,QAAUoO,EAClBg+B,GAAYh+B,GACO,mBAARlmB,GAAoBA,GAAIkmB,GAC1BlmB,KAAMA,GAAsD8X,QAAUoO,IAEnF,CAAClmB,KAGCghD,GAAanmD,EAAM6d,YACpBjY,IACO2sB,GAAYuvB,GAAYl5B,KAC5B8/B,GAAezrC,QAAUlc,GACzB+nD,GAAgB7rC,QAAWxC,SAAS2X,eAAwC,KAC5EowB,GAAiB58C,IAAaxH,KAAUC,GAAM,MAAQ,UACjDkqD,IAAkBE,IAAgB,GACvC/B,QAEJ,CAACn0B,EAAUuvB,EAAUl5B,GAAM7nB,GAAO3C,GAAOC,GAAKmkD,GAAkB+F,GAAkB7B,IAGhF6C,GAAcvpD,EAAM6d,YAAY,KAClC,IAAK+K,GAAM,OACN2/B,IAAkBE,IAAgB,GACvCl5B,MACA,MAAM/I,EAASqiC,GAAU5rC,SAAW6rC,GAAgB7rC,QACpDtc,OAAO6a,WAAW,IAAMgL,GAAQ4D,UAAW,IAC5C,CAACxB,GAAM2/B,GAAkBh5B,IAEtBi6B,GAAiBxpD,EAAM6d,YACxBC,IACGsoC,GAAOtoC,GAAM,GACbyrC,MAEJ,CAACnD,GAAQmD,KAGPE,GAAgBzpD,EAAM6d,YAAY,KAEpCuoC,GAAOrlD,IACPwoD,MACD,CAACxoD,GAAOqlD,GAAQmD,KAEbG,GAAuB1pD,EAAM6d,YAC/B,CAACC,EAAoB6rC,EAAmB/jD,KACpCwiD,GAAStqC,GACQ,QAAblY,GAAsBkY,EAAK,IAAMA,EAAK,IAAM4pC,IAAuB8B,GAAe1rC,IAE1F,CAACsqC,GAAUV,GAAuB8B,MAsC/BI,GAAcC,IAAmB7pD,EAAMyd,SAAuB,MAC/DqsC,GAAe9pD,EAAM6d,YACtBqqC,IACG,MAAO/3C,EAAGm0B,GAAK4jB,EACf,OAAK/3C,GAAMm0B,EACJ,GAAGn0B,EAAI9D,GAAW8D,EAAG3D,GAAU+6C,MAAmB30B,GAAWszB,kBAAkB5hB,EAAIj4B,GAAWi4B,EAAG93B,GAAU+6C,KAD7F,IAGzB,CAAC/6C,EAAQ+6C,GAAiB30B,GAAWszB,kBAGlC6D,GAAYC,IAAiBhqD,EAAMyd,SAAS,IAAMqsC,GAAa/oD,MAC/DkpD,GAAWC,IAAgBlqD,EAAMyd,SAAS,IAAMpR,GAAWjO,GAAOoO,KAClE29C,GAASC,IAAcpqD,EAAMyd,SAAS,IAAMpR,GAAWhO,GAAKmO,KAC5D69C,GAAcC,IAAmBtqD,EAAMyd,SAA4D,CACtGuvB,QAAQ,EACR5uC,OAAO,EACPC,KAAK,IAIT2B,EAAMic,UAAU,KACS,WAAjB2tC,KACAI,GAAcF,GAAa/oD,KAC3BupD,GAAiB55B,GAAUA,EAAKsc,OAAS,IAAKtc,EAAMsc,QAAQ,GAAUtc,IAErD,UAAjBk5B,KACAM,GAAa79C,GAAWjO,GAAOoO,IAC/B89C,GAAiB55B,GAAUA,EAAKtyB,MAAQ,IAAKsyB,EAAMtyB,OAAO,GAAUsyB,IAEnD,QAAjBk5B,KACAQ,GAAW/9C,GAAWhO,GAAKmO,IAC3B89C,GAAiB55B,GAAUA,EAAKryB,IAAM,IAAKqyB,EAAMryB,KAAK,GAAUqyB,KAErE,CAAC3vB,GAAO3C,GAAOC,GAAKurD,GAAcp9C,EAAQs9C,KAE7C,MAAMS,GAAgBprD,IAClB,MAAMigD,EAAUjgD,EAAKoV,OACrB,IAAK6qC,GAAWA,EAAQkC,gBAAkBiG,GAAgBjG,cAAe,MAAO,CAAE/0C,KAAM,KAAMi+C,SAAS,GACvG,MAAMp+C,EAAS+yC,GAAcC,EAAS5yC,GACtC,MAAO,CAAED,KAAMH,EAAQo+C,QAAmB,MAAVp+C,IAe9Bq+C,GAAmBA,CAAC1kB,EAAuB5mC,KAChC,UAAT4mC,EAAkBmkB,GAAa/qD,GAC9BirD,GAAWjrD,GAChB,MAAMiN,EAASm+C,GAAaprD,GAE5B,GADAmrD,GAAiB55B,IAAI,IAAWA,EAAMqV,CAACA,GAAO35B,EAAOo+C,WACjDp+C,EAAOo+C,QAAS,OACpB,MAAM1sC,EAA8B,UAATioB,EAAmB,CAAC35B,EAAOG,KAAMlO,IAAO,CAACD,GAAOgO,EAAOG,MAC7EwyC,GAAajhC,EAAM/c,KAAQqnD,GAAStqC,IAGvC4sC,GAAcjlD,IAChBokD,GAAiBn5B,GAAUA,IAASjrB,EAAQ,KAAOirB,GAErC,WAAVjrB,GAAuB4kD,GAAard,QAAQgd,GAAcF,GAAa/oD,KAC7D,UAAV0E,GAAsB4kD,GAAajsD,OAAO8rD,GAAa79C,GAAWjO,GAAOoO,IAC/D,QAAV/G,GAAoB4kD,GAAahsD,KAAK+rD,GAAW/9C,GAAWhO,GAAKmO,IAEhEoc,IAAMw9B,GAAOrlD,KAGhB4pD,GAAqBA,CAAC15B,EAA8CrrB,KACpD,cAAdqrB,EAAMnwB,KAAwBmwB,EAAM25B,OAGf,UAAd35B,EAAMnwB,MACbmwB,EAAMiB,iBACDtJ,IAAMw9B,GAAOrlD,MAJlBkwB,EAAMiB,iBACNi0B,GAAWvgD,KAcbgK,KAAaxR,MAAWC,GACxBwsD,GAAqB5C,GAAgB92B,KAAMmT,GAAW,MAALA,GACjDwmB,KAAc3D,GAAa0D,IAAsBR,GAAard,QAAUqd,GAAajsD,OAASisD,GAAahsD,IAE3G0sD,IAAcjE,GAChB9mD,EAAAC,cAAA,SAAA,CACIkF,IAAK0jD,GACLt9C,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATlF,GAAoB,sBAAqB,aAC5EqtB,GAAWuzB,WACvBjkD,MAAO0wB,GAAWuzB,WAAU,gBACd,yBACCv9B,GACf2J,SAAUA,EACVX,QAAUX,IACNA,EAAMO,kBACF5I,GAAM6gC,KACLtD,OAGTnmD,EAAAC,cAAC+9C,GAAa,CAACz4C,KAAe,UAATA,EAAmB,GAAK,MAI/CylD,GAAcpE,GAAah3C,KAAa2iB,IAAauvB,GACvD9hD,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATlF,GAAoB,mCACvDqtB,GAAWwC,MACvBlzB,MAAO0wB,GAAWwC,MAClBxD,QArCOX,IACXA,EAAMO,kBACN42B,GAAS/J,IACTmE,GAAiB,SACjB4D,GAAO/H,MAmCHr+C,EAAAC,cAAC6sB,GAAS,CAACvnB,KAAe,UAATA,EAAmB,GAAK,MAI3C0lD,GAAajrD,EAAMw3B,QACrB,KAAA,IAAaoH,KAAkD58B,IAC/D,CAAC48B,EAAW58B,IAEVkpD,GAAoBlrD,EAAMw3B,QAC5B,KAAA,IAAaoH,KAAkD0oB,IAC/D,CAAC1oB,EAAW0oB,IAIV6D,GAAgBnrD,EAAMw3B,QACxB,KACKwvB,GAAa,IAAIvjD,IAAI,CAAC4kD,EAAUrlC,KAC7B,IAAIooC,EAA8B/M,GAClC,IACI+M,EAAgBlM,GAAemJ,EAASnH,SAAS,CAAEh1C,aACvD,CAAE,MACE,CAEJ,MAAO,CAAEm8C,WAAUvnD,IAAKunD,EAASj9C,IAAM,GAAGi9C,EAASp7C,SAAS+V,IAASjiB,MAAOqqD,KAEpF,CAACpE,EAAW96C,KA4CVm/C,GACFrrD,gBAACuhD,GAAoB,CACjBxgD,MAAOA,GACPsc,SAAUqsC,GACVjI,cAAeA,GACfE,sBAAuBa,GACvBZ,UAAWA,EACXC,cAAeA,EACfnC,QAASA,EACTC,QAASA,EACTH,YAAaA,EACbC,cAAeA,EACfG,kBAAmBA,EACnBmC,4BAA6BA,EAC7B5B,gBAAiBA,EACjB6B,mBAAoBA,EACpBC,sBAAuBA,EACvBC,iBAAkBA,EAClBC,cAAeA,EACfvvB,WAAYA,GACZvzB,UAAW+pD,GACX35B,WAAS,IAKX67B,GAAmB,CACrB/lD,OACA8/C,YACA9yB,WACAuvB,WACAyD,WACAz/B,MAAOglC,IAGX,OACI9qD,EAAAC,cAAA,MAAA,CACIkF,IAAKmkD,GACLngC,UAAW1e,GAAG,UAAW46C,GAAa,sBAAuBmC,IAAW,iBAAkBr+B,GAAU,iBACpFigC,GAChBpnD,MAAOipD,IAENzD,GACGxnD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,kBACXnpB,EAAAC,cAAC2E,GAAS,IACF0mD,GACJhG,OAAK,EACLl6C,GAAI08C,GACJ/vC,KAAMA,EAAO,GAAGA,eAAevK,EAC/BP,MAAO2lB,GAAWx0B,MAClB2C,MAAOkpD,GACP3kD,YAAa4hD,GAAmBK,GAChC/B,QAA0B,UAAjBoE,GACTnE,UAAWgC,GACXh4B,UAAWA,EACXpqB,SAAUA,EACVgY,SAAWle,GAASsrD,GAAiB,QAAStrD,GAC9C+lD,QAASA,KACL2E,GAAgB,SAChBrH,GAAiB,UAErBhtB,OAAQA,IAAMk1B,GAAW,SACzB94B,QAASA,IAAM61B,IAAuBtB,GAAW,SACjDp0B,UAAYd,GAAU05B,GAAmB15B,EAAO,WAEpDjxB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,2BAA0B,cAAa,QAClDyJ,GAAWszB,gBAEhBlmD,EAAAC,cAAC2E,OACO0mD,GACJhG,OAAK,EACLl6C,GAAI28C,GACJhwC,KAAMA,EAAO,GAAGA,aAAavK,EAC7BP,MAAO2lB,GAAWv0B,IAClB0C,MAAOopD,GACP7kD,YAAa4hD,GAAmBK,GAChC/B,QAA0B,QAAjBoE,GACTnE,UAAWgC,GACX/B,UACI1lD,EAAAC,cAAAD,EAAAuuB,SAAA,KACKy8B,GACAD,IAGT1tC,SAAWle,GAASsrD,GAAiB,MAAOtrD,GAC5C+lD,QAASA,KACL2E,GAAgB,OAChBrH,GAAiB,QAErBhtB,OAAQA,IAAMk1B,GAAW,OACzB94B,QAASA,IAAM61B,IAAuBtB,GAAW,OACjDp0B,UAAYd,GAAU05B,GAAmB15B,EAAO,UAIxDjxB,EAAAC,cAAC2E,GAAS,IACF0mD,GACJlgD,GAAI08C,GACJ/vC,KAAMA,EACN9K,MAAOA,EACPlM,MAAOgpD,GACPzkD,YAAa4hD,GAAmB,GAAGK,MAAmB30B,GAAWszB,kBAAkBqB,KACnF/B,QAA0B,WAAjBoE,GACTnE,UAAWgC,GACXh4B,UAAWA,EACXpqB,SAAUA,EACVsgD,UAAoB,MAAT14C,EAAgB2lB,GAAWyzB,kBAAe74C,EACrDk4C,UACI1lD,EAAAC,cAAAD,EAAAuuB,SAAA,KACKy8B,GACAD,IAGT1tC,SAvQYle,IACxB6qD,GAAc7qD,GACd,MAAOgR,EAAGm0B,GHhRanlC,KAC3B,MAAMosD,EAAQpsD,EAAKkV,MAAM,yCACzB,OAAIk3C,EAAMnhD,QAAU,EAAU,CAACmhD,EAAM,GAAIA,EAAMl2C,MAAM,GAAGxK,KAAK,MACtD,CAAC1L,EAAM,KG6QKqsD,CAAersD,GACxBssD,EAAKlB,GAAap6C,GAClBu7C,EAAKnB,GAAajmB,GAClBkmB,EAAUiB,EAAGjB,SAAWkB,EAAGlB,QAEjC,GADAF,GAAiB55B,IAAI,IAAWA,EAAMsc,OAAQwd,KAC1CA,EAAS,OACb,MAAM1sC,EAAqB,CAAC2tC,EAAGl/C,KAAMm/C,EAAGn/C,MACnCwyC,GAAajhC,EAAM/c,KAAQqnD,GAAStqC,IA+P7BonC,QAASA,IAAM2E,GAAgB,UAC/Br0B,OAAQA,IAAMk1B,GAAW,UACzB94B,QAASA,IAAM61B,IAAuBtB,KACtCp0B,UAAYd,GAAU05B,GAAmB15B,EAAO,WAGzC,MAAdm2B,GAAqC,KAAfA,GACnBpnD,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,GAAG,iBAAkBqgD,IAAa,0BAA2B1D,GAGjFpnD,EAAAC,cAACovB,GAAO,CACJzG,KAAMA,GACN0G,SAAUA,GACVE,UAAWA,GACX21B,UAAWsE,GACXpqD,UAAW+pD,GACXjgC,UAAWk+B,EACXrlD,MAAOkpD,GACP9F,WAAYvmB,EAAcmpB,QAAgBx6C,GAE1CxN,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,GAAG,iBAAkBo0B,GAAe,iCAC/CA,GA/Kb7+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBACXnpB,EAAAC,cAAA,IAAA,CAAGkpB,UAAU,wBAAwB/d,GAAI48C,IACpCp1B,GAAWyzB,cAEhBrmD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,yBACXnpB,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GAAqB,UAAlBg3C,IAA6B,iCAC3C7vB,QAASA,IAAM4wB,GAAiB,UAE/BpkD,GAAQiO,GAAWjO,GAAOoO,GAAUomB,GAAWx0B,OAEpD4B,EAAAC,cAAA,OAAA,KAAO2yB,GAAWszB,gBAClBlmD,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GAAqB,QAAlBg3C,IAA2B,iCACzC7vB,QAASA,IAAM4wB,GAAiB,QAE/BnkD,GAAMgO,GAAWhO,GAAKmO,GAAUomB,GAAWv0B,OA8J5C2B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,uBACVgiC,GAAc/gD,OAAS,GACpBpK,EAAAC,cAAA,KAAA,CAAIkpB,UAAU,oBAAmB,aAAY,aACxCgiC,GAAc1nD,IAAI,EAAG4kD,WAAUvnD,MAAKC,MAAOqqD,KACxCprD,EAAAC,cAAA,KAAA,CAAIa,IAAKA,GACLd,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GACP,mBACAmF,IACImvC,GAAaqM,EAAerqD,KAC5B,8BAERwxB,SAAUA,GAAYuvB,EACtBlwB,QAASA,IAzXzBy2B,KACpB,MAAMvqC,EAAOohC,GAAemJ,EAASnH,SAAS,CAAEh1C,cAChDk8C,GAAStqC,EAAMuqC,GACf7F,GAAiB,SACjBgH,GAAe1rC,IAqXoC6tC,CAAetD,IAE7BA,EAASp7C,UAM7Bo+C,IA7KjBruB,EAAQ5yB,OAAS,GACbpK,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBACV6T,EAAQv5B,IAAK25B,GACVp9B,EAAAC,cAAA,SAAA,CACIa,IAAKs8B,EACL7xB,KAAK,SACL4d,UAAW1e,GAAG,eAA2B,WAAX2yB,GAAkC,UAAXA,IAAuB,wBAC5ExL,QAASA,IApNPwL,KAClB,OAAQA,GACJ,IAAK,QACDgrB,GAAS/J,IACTmE,GAAiB,SACjBgH,GAAenL,IACf,MAEJ,IAAK,QAAS,CACV,MAAM8C,EAAQn1C,IAAQU,QAAQ,OACxBoR,EAAqB,CAACqjC,EAAOA,GACnCiH,GAAStqC,GACT0kC,GAAiB,SACbkF,IAAuB8B,GAAe1rC,GAC1C,KACJ,CACA,IAAK,SACIihC,GAAah+C,GAAO2nD,GAAezrC,UAAUmrC,GAASM,GAAezrC,SAC1EssC,KACA,MAGJ,QACIC,GAAezoD,MA6LQ6qD,CAAaxuB,IAE3BxK,GAAWwK,QA2KpC,GAEAkpB,GAAmB5pC,YAAc,qBC9oB1B,MAAMmvC,GAA2B,gBAO3BC,GAAsB,4nHAgDnC,IAAIjwC,IAAW,EAEf,MAcMC,GACD9b,EAAc+b,qBAAyC,oBAAXpb,OAAyBX,EAAMgc,gBAAkBhc,EAAMic,WAG3F8vC,GAAyBA,KAClChO,KACAjiC,GAAa,KApBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAeyvC,IAExB,YADAhwC,IAAW,GAGf,MAAM7Z,EAAQyY,SAASxa,cAAc,SACrC+B,EAAMoJ,GAAKygD,GACX7pD,EAAMqa,aAAa,cAAe,QAClCra,EAAMsa,YAAcwvC,GACpBrxC,SAAS8B,KAAKjB,YAAYtZ,GAC1B6Z,IAAW,GAUPM,IACD,KC7EM6vC,GAAmChgD,EAAM,cACzCigD,GAAmCjgD,EAAM,cAEzCkgD,GAAiBnrD,GAAiCu9C,GAAQv9C,GAE1DorD,GAAcA,CAACv7C,EAA6BC,IAC/C,MAALD,GAAkB,MAALC,KAAiBD,KAAOC,GAAKD,EAAE4tC,OAAO3tC,EAAG,OAG9Cu7C,GAAmBA,CAAC7/C,EAAa8/C,IAC1CA,EAAO9/C,EAAK+/C,KAAKD,EAAKC,QAAQC,OAAOF,EAAKE,UAAUC,OAAOH,EAAKG,UAAUC,YAAYJ,EAAKI,eAAiBlgD,EA4BnGmgD,GAAeA,CACxB3rD,EACA6C,EACAihB,EAAa7Y,MAEA,MAATjL,EAAsB,KACrBA,EAAMmL,UACPtI,EAAQg8C,oBAAoB7+C,GAAe,oBAC3C6C,EAAQ+oD,qBAAqB5rD,GAAe,qBAC5C6C,EAAQgpD,oBAAoB7rD,GAAe,oBAC3C6C,EAAQ67C,eAAiBd,GAAW59C,EAAO8jB,GAAa,gBACxDjhB,EAAQ47C,aAAef,GAAY19C,EAAO8jB,GAAa,cACvDjhB,EAAQ87C,SAAWjB,GAAY19C,EAAO6C,EAAQ87C,SAAiB,UAC/D97C,EAAQ+7C,SAAWhB,GAAW59C,EAAO6C,EAAQ+7C,SAAiB,UAC3D,KARsB,cAWpBkN,GAAiBA,CAAC/N,EAAYl7C,EAAgCihB,IACpC,MAAnC6nC,GAAa5N,EAAKl7C,EAASihB,GAGlBioC,GAAkBA,CAAC5M,EAAct8C,EAAgCihB,EAAa7Y,OACvF,MAAM5N,EAAQ8hD,EAAMxzC,QAAQ,SACtBrO,EAAM6hD,EAAMI,MAAM,SACxB,SAAI18C,EAAQ47C,cAAef,GAAYpgD,EAAKwmB,SACxCjhB,EAAQ67C,gBAAiBd,GAAWvgD,EAAOymB,SAC3CjhB,EAAQ87C,UAAWjB,GAAYpgD,EAAKuF,EAAQ87C,eAC5C97C,EAAQ+7C,UAAWhB,GAAWvgD,EAAOwF,EAAQ+7C,aACxC/7C,EAAQ+oD,qBAAqBvuD,OAI7B2uD,GAAiBA,CAACC,EAAappD,EAAgCihB,EAAa7Y,OACrF,MAAM5N,EAAQ4uD,EAAKtgD,QAAQ,QACrBrO,EAAM2uD,EAAK1M,MAAM,QACvB,SAAI18C,EAAQ47C,cAAef,GAAYpgD,EAAKwmB,SACxCjhB,EAAQ67C,gBAAiBd,GAAWvgD,EAAOymB,SAC3CjhB,EAAQ87C,UAAWjB,GAAYpgD,EAAKuF,EAAQ87C,eAC5C97C,EAAQ+7C,UAAWhB,GAAWvgD,EAAOwF,EAAQ+7C,aACxC/7C,EAAQgpD,oBAAoBxuD,OAO5B6uD,GAAyBA,CAAC1gD,EAAa3I,EAAgCihB,EAAa7Y,OAC7F,IAAI0zC,EAAU97C,EAAQ87C,SAAWsM,GAC7BrM,EAAU/7C,EAAQ+7C,SAAWsM,GAGjC,GAFIroD,EAAQ47C,aAAeb,GAAW95B,EAAK66B,KAAUA,EAAU76B,GAC3DjhB,EAAQ67C,eAAiBhB,GAAY55B,EAAK86B,KAAUA,EAAU96B,GAC9D85B,GAAWe,EAASC,GAAU,OAAO,KAEzC,IAAIuN,EAAwB3gD,EACxB4gD,EAAyB5gD,EACzBkyC,GAAYlyC,EAAMmzC,KAClBwN,EAAUxN,EACVyN,EAAW,MAEXxO,GAAWpyC,EAAMozC,KACbwN,IAAUA,EAAWxN,GACzBuN,EAAU,MAEd,IAAIE,EAAQ,EACZ,MAAQF,GAAWC,IAAaC,EAAQ,KAAQ,CAI5C,GAHAA,GAAS,EACLF,GAAWvO,GAAWuO,EAASvN,KAAUuN,EAAU,MACnDC,GAAY1O,GAAY0O,EAAUzN,KAAUyN,EAAW,MACvDD,EAAS,CACT,IAAKL,GAAeK,EAAStpD,EAASihB,GAAM,OAAOqoC,EACnDA,EAAUA,EAAQxhD,IAAI,EAAG,MAC7B,CACA,GAAIyhD,EAAU,CACV,IAAKN,GAAeM,EAAUvpD,EAASihB,GAAM,OAAOsoC,EACpDA,EAAWA,EAAS/L,SAAS,EAAG,MACpC,CACJ,CACA,OAAO,MAcEiM,GAAuD,CAChE,CAAEpgD,MAAO,QAASi0C,SAAUA,IAAMl1C,IAAQU,QAAQ,QAClD,CAAEO,MAAO,YAAai0C,SAAUA,IAAMl1C,IAAQo1C,SAAS,EAAG,OAAO10C,QAAQ,QACzE,CAAEO,MAAO,WAAYi0C,SAAUA,IAAMl1C,IAAQN,IAAI,EAAG,OAAOgB,QAAQ,QACnE,CAAEO,MAAO,gBAAiBi0C,SAAUA,IAAMl1C,IAAQU,QAAQ,SAC1D,CAAEO,MAAO,iBAAkBi0C,SAAUA,IAAMl1C,IAAQU,QAAQ,UAC3D,CAAEO,MAAO,eAAgBi0C,SAAUA,IAAMl1C,IAAQs0C,MAAM,SAAS5zC,QAAQ,QACxE,CAAEO,MAAO,QAASi0C,SAAUA,IAAM,OCzHhCG,GAA6BvC,GAAeA,EAAItyC,OAAO,MAAMuH,OAAO,GAAGutC,cACvEgM,GAA+B,CAAC,OAAQ,OACxCC,GAA0BC,GACnB,SAATA,EAAkB,6CAA+C,sDAMrDC,IACZ1sD,MAAOygD,EAASpkC,aAChBA,EAAYC,SACZA,EAAQwkC,cACRA,EACA6L,MAAOC,EAASC,OAChBA,EAAS,MACTJ,KAAMK,EAAQC,aACdA,EAAYpO,QACZA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiB+M,mBACjBA,EAAkBC,kBAClBA,EAAiBr6B,SACjBA,GAAW,EAAKuvB,SAChBA,GAAW,EAAKC,4BAChBA,GAA8B,EAAK5B,gBACnCA,EAAe6B,mBACfA,EAAqBX,GAAyBY,sBAC9CA,GAAwB,EAAK8L,YAC7BA,EAAc,EAACC,aACfA,EAAe,EAACv+B,UAChBA,GAAY,EAAK0yB,cACjBA,EAAa8L,aACbA,EAAYr7B,WACZA,EAAUvzB,UACVA,EAAS8pB,UACTA,EAASnnB,MACTA,IAEA+pD,KAEA,MAAM2B,EAAQ1tD,EAAMw3B,QAAQ,IAAOm2B,GAAaA,EAAUvjD,OAAS,EAAIujD,EAAYL,GAAgB,CAACK,IAC9FxM,EAAQn1C,IAGRsR,OAA6B9P,IAAdg0C,GACdY,EAAeC,GAAoBriD,EAAMyd,SAAuB,IAAMyuC,GAAc9uC,GAAgB,OACrGrc,EAAQf,EAAMw3B,QAChB,IAAOla,EAAe4uC,GAAc1K,GAAaY,EACjD,CAAC9kC,EAAckkC,EAAWY,KAIvB8L,EAAcC,GAAmBnuD,EAAMyd,SAAsB,IAAOiwC,EAAM/F,SAASiG,GAAUA,EAASF,EAAM,IAC7GF,OACWhgD,IAAbqgD,GAA0BH,EAAM/F,SAASkG,GACnCA,EACAH,EAAM/F,SAASuG,GACbA,EACAR,EAAM,GACZU,EAAUpuD,EAAM6d,YACjBC,SACoBtQ,IAAbqgD,GAAwBM,EAAgBrwC,GAC5CgwC,IAAehwC,IAEnB,CAAC+vC,EAAUC,IAGTrL,EAAaziD,EAAMw3B,QACrB,KAAA,CAASkoB,UAASC,UAASH,cAAaC,gBAAeG,oBAAmB+M,qBAAoBC,sBAC9F,CAAClN,EAASC,EAASH,EAAaC,EAAeG,EAAmB+M,EAAoBC,KAInFlK,EAAcC,GAAmB3iD,EAAMyd,SAAgB,KAAO1c,GAAS8gD,GAAiBV,GAAOz0C,QAAQ,UACxGo2C,EAAc9iD,EAAM6d,YACrBqiC,IACG,MAAMpiC,EAAOoiC,EAAMxzC,QAAQ,SACvBg2C,EAAalE,OAAO1gC,EAAM,WAC9B6kC,EAAgB7kC,GAChBqkC,IAAgBrkC,KAEpB,CAAC4kC,EAAcP,IAIba,EAAchjD,EAAMgd,OAAqBjc,GAC/Cf,EAAMic,UAAU,KACZ,MAAMyU,EAAOsyB,EAAY/lC,QACzB+lC,EAAY/lC,QAAUlc,GAClBA,GAAUorD,GAAYz7B,EAAM3vB,IAAWA,EAAMy9C,OAAOkE,EAAc,UAAUI,EAAY/hD,IAE7F,CAACA,IAEJ,MAAMstD,GAAoB7O,GAAiBE,IAAWf,GAAWwC,EAAOzB,GAAoBA,EAARyB,EAC9EmN,GAAmB7O,GAAmBE,IAAWlB,GAAY0C,EAAOxB,GAAoBA,EAARwB,EAChF8B,GAAaoL,GAAqB3L,EAAa9D,QAAQyP,EAAmB,SAC1EnL,GAAaoL,GAAoB5L,EAAahE,SAAS4P,EAAkB,SAGzEhrB,EAAUtjC,EAAMgd,OAA8B,MAC9CuxC,EAAWvuD,EAAMgd,OAA8B,MAC/CwsB,EAAkBxpC,EAAMgd,OAAOyS,IAC9B+zB,GAAYC,IAAiBzjD,EAAMyd,SAAgB,IAAM1c,GAAS8gD,GAAiBV,GAE1FnhD,EAAMic,UAAU,KACZ,IAAKutB,EAAgBvsB,QAAS,OAC9B,MAAM7R,EAAKzK,OAAO6a,WAAW,KACzBguB,EAAgBvsB,SAAU,EAC1BqmB,EAAQrmB,SAASqU,cAA2B,gCAAgClH,MAAM,CAAEwrB,eAAe,KACpG,GACH,MAAO,IAAMj1C,OAAOopB,aAAa3e,KAIrCpL,EAAMic,UAAU,KACZ,GAAa,SAATuxC,EAAiB,OACrB,MAAMgB,EAAYD,EAAStxC,QACrBuJ,EACFgoC,GAAWl9B,cAA2B,2BACtCk9B,GAAWl9B,cAA2B,kBACtCk9B,GAAahoC,IACbgoC,EAAU1kB,UAAYtjB,EAAOioC,UAAYD,EAAUhiB,aAAe,EAAIhmB,EAAO6J,aAAe,IAEjG,CAACm9B,IAGJ,MAAMt4B,GAASl1B,EAAM6d,YACjB,CAACC,EAAa4wC,KACV,MAAM1rC,EAAQ0qC,EAAMx9C,QAAQw+C,GACtBC,EAAW3rC,GAAS,EAAI0qC,EAAM1qC,EAAQ,QAAKxV,EAC3CohD,EAAwCD,EAAW,UAAY,SAChErxC,GAAc+kC,EAAiBvkC,GACpCT,IAAWS,EAAM8wC,EAAgBF,GAC7BC,IACAnlB,EAAgBvsB,SAAU,EAC1BmxC,EAAQO,KAGhB,CAACjB,EAAOpwC,EAAcD,EAAU+wC,IAG9BS,GAAe7uD,EAAM6d,YAAY,KACnC,MAAM8wC,EAAWjB,EAAMA,EAAMx9C,QAAQs9C,GAAQ,GACxCmB,IACLnlB,EAAgBvsB,SAAU,EAC1BmxC,EAAQO,KACT,CAACjB,EAAOF,EAAMY,IAEX9K,GAAaxE,IACXvsB,GAAYuvB,GAAY+K,GAAe/N,EAAK2D,EAAYtB,KAC5DsC,GAAc3E,GACd5pB,GAAOk3B,GAAiBtN,EAAK/9C,GAAS8gD,GAAgB,SAIpDiN,GAAeA,CAACC,EAAkBC,EAAwBN,KAC5D,GAAIn8B,GAAYuvB,EAAU,OAC1B,MAAMmN,EAAcF,EAAUriD,QAAQsiD,GAChCE,EAAYH,EAAUzO,MAAM0O,GAC5B59B,EAAUy7B,GAAekC,EAAWtM,EAAYtB,GAChD8L,GACI8B,EACA,IACOtM,EACH/C,QAASA,GAAWf,GAAWe,EAASuP,GAAevP,EAAUuP,EACjEtP,QAASA,GAAWlB,GAAYkB,EAASuP,GAAavP,EAAUuP,GAEpE/N,GAEJ4N,EACF39B,GACA0xB,EAAY1xB,GACZqyB,GAAcryB,GACd8D,GAAO9D,EAASs9B,GACH,SAATM,GAAiBf,IAAe78B,KAEpC0xB,EAAYmM,GACZJ,OAIFM,GAAWpuD,GAAS8gD,GAAiBV,EAAMz0C,QAAQ,OACnD0iD,GAAcpC,IACZD,GAAe/gD,IAAQghD,KAAKA,GAAOvK,EAAYtB,IACnD2N,GD7LeO,EAAC9iD,EAAaygD,KACjC,MAAM/6B,EAAQ1lB,EAAKG,QAAQ,SAASsgD,KAAKA,GACzC,OAAOZ,GAAiBn6B,EAAM1lB,KAAK/B,KAAKF,IAAIiC,EAAKA,OAAQ0lB,EAAM+yB,gBAAiBz4C,IC2L/D8iD,CAAQF,GAAUnC,GAAO,OAAQ,SAE5CsC,GAAepP,IACjB,MAAM6O,ED1LUQ,EAAChjD,EAAa2zC,KAClC,MAAMjuB,EAAQ1lB,EAAKG,QAAQ,SAASwzC,MAAMA,GAC1C,OAAOkM,GAAiBn6B,EAAM1lB,KAAK/B,KAAKF,IAAIiC,EAAKA,OAAQ0lB,EAAM+yB,gBAAiBz4C,ICwL1DgjD,CAASJ,GAASnC,KAAKtK,EAAasK,QAAS9M,GAC3D4M,GAAgBiC,EAAWtM,EAAYtB,IAC3C2N,GAAaC,EAAW,QAAS,UAG/BS,GAAaA,KACM,IAAjB9B,EAAMtjD,QAAgBmoB,IAC1BiX,EAAgBvsB,SAAU,EACL,IAAjBywC,EAAMtjD,OAAcgkD,EAAQV,EAAM9/C,KAAMkD,GAAMA,IAAM08C,IAASE,EAAM,IAClEU,EAAgC,IAAxBV,EAAMx9C,QAAQs9C,GAAcE,EAAM,GAAKA,EAAM,MAQxD+B,GAAgB3Q,IAClB2E,GAAc3E,GACTA,EAAIN,OAAOkE,EAAc,UAAUI,EAAYhE,GACpDn+C,OAAO6a,WAAW,IAPJsjC,KACd,MAAMh+C,EAAMg+C,EAAItyC,OAAO,cACvB82B,EAAQrmB,SAASqU,cAAiC,cAAcxwB,QAAUspB,SAKlDs5B,CAAS5E,GAAM,IA0CrC4Q,GAAoBA,CACtBz+B,EACAg4B,EACAhsC,EACAxI,EACAk7C,EACAC,KAEA,MAAM5sC,EAAQvO,EAAOvE,QAAQ+M,GAC7B,IAAI4yC,EAAY7sC,EAChB,OAAQiO,EAAMnwB,KACV,IAAK,YACD+uD,EAAY7sC,EAAQ,EACpB,MACJ,IAAK,aACD6sC,EAAY7sC,EAAQ,EACpB,MACJ,IAAK,UACD6sC,EAAY7sC,EAAQ2sC,EACpB,MACJ,IAAK,YACDE,EAAY7sC,EAAQ2sC,EACpB,MACJ,IAAK,OACDE,EAAY,EACZ,MACJ,IAAK,MACDA,EAAYp7C,EAAOrK,OAAS,EAC5B,MACJ,IAAK,QACL,IAAK,IAGD,OAFA6mB,EAAMiB,sBACN09B,EAAO3yC,GAEX,QACI,OAERgU,EAAMiB,iBACF29B,EAAY,GAAKA,GAAap7C,EAAOrK,QACzCk5B,EAAQrmB,SAASqU,cAAiC,IAAI23B,MAASx0C,EAAOo7C,SAAiBzlC,SAIrF0lC,GAAcl9B,GAAYm9B,sCAAwCxC,GAoDlE5J,GAAW3jD,EAAMw3B,QAAQ,IAAMspB,GAAiBkB,GAAqB,CAACA,IA6J5E,OACIhiD,EAAAC,cAAA,MAAA,CACIkF,IAAKm+B,EACLna,UAAW1e,GACP,kBACA8nB,GAAY,4BACZuvB,GAAY,6BACZ34B,GACH,iBACe9pB,EAAS,YACdmuD,EACXxrD,MAAOA,GA1NXhC,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,iBACXnpB,EAAAC,cAAA,MAAA,CACImvB,KAAK,eACLjG,UAAW1e,GAAG,2BAA6C,IAAjBijD,EAAMtjD,QAAgB,gDACtD,SACVwnB,QAAS49B,IAETxvD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,uBAAuBu5B,EAAal2C,OAAO,cACzDkhD,EAAMtjD,OAAS,IAAMmoB,GAClBvyB,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GACP,qDACS,QAAT+iD,GAAkB,8BACrB,aACWsC,GAAYtC,IAExBxtD,EAAAC,cAACi+C,GAAiB,QAIpB,QAATsP,GACGxtD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,qBACXnpB,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAU,6CACEyJ,GAAYsxB,eAAiB,iBACzChiD,MAAO0wB,GAAYsxB,eAAiB,iBACpC3xB,SAAUA,IAAa0wB,EACvBrxB,QAASA,IAAMkxB,EAAYJ,EAAatB,SAAS,EAAG,WAEpDphD,EAAAC,cAACqtB,UAELttB,EAAAC,cAAA,OAAA,CAAMkpB,UAAU,6BAChBnpB,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAU,6CACEyJ,GAAYuxB,WAAa,aACrCjiD,MAAO0wB,GAAYuxB,WAAa,aAChC5xB,SAAUA,IAAa2wB,EACvBtxB,QAASA,IAAMkxB,EAAYJ,EAAah3C,IAAI,EAAG,WAE/C1L,EAAAC,cAACotB,GAAgB,SAmLnB,QAATmgC,GA1KawC,MAClB,MAAMvP,EAAQR,GAAcyC,EAAcvC,GACpC8D,GACDT,GAAWhF,OAAOkE,EAAc,SAAWc,GAAa,QACxDziD,GAASA,EAAMy9C,OAAOkE,EAAc,SAAW3hD,EAAQ,QACvDogD,EAAM3C,OAAOkE,EAAc,SAAWvB,EAAQ,OAC/CuB,EAAah2C,QAAQ,SACzB,OACI1M,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,+BAA+BiG,KAAK,qBAAoBszB,EAAal2C,OAAO,cACvFxM,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBAAmBiG,KAAK,OAClCu0B,GAASlgD,IAAK2gD,GACXpkD,wBAAMc,IAAKsjD,EAAGtjD,IAAKqoB,UAAU,kBAAkBiG,KAAK,eAAc,aAAag1B,EAAGpD,MAC7EoD,EAAGn3C,SAIhBjN,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,gBAAgBiG,KAAK,OAAM,aAAaszB,EAAal2C,OAAO,cACtEi0C,EAAMh9C,IAAK4gD,GACRrkD,EAAAC,cAAA,MAAA,CAAKa,IAAKujD,EAAKvjD,IAAKqoB,UAAU,eAAeiG,KAAK,OAC7Ci1B,EAAK1D,KAAKl9C,IAAI,EAAGq7C,MAAK+B,mBACnB,MAAM0D,EAAS1D,IAAiBkB,EAC1BzvB,EAAWisB,GAAUO,EAAK/9C,GAC1BkvD,GAAWhO,GAAyB1D,GAAUO,EAAKqC,GACnDyD,EAAcryB,GAAYs6B,GAAe/N,EAAK2D,EAAYtB,GAC1D0D,GAAcN,GAAUhG,GAAUO,EAAKmF,GAC7C,OACIjkD,uBACIc,IAAKg+C,EAAItyC,OAAO,cAChB4iB,KAAK,WAAU,gBACAkD,QAAY9kB,EAC3B2b,UAAU,oBAEVnpB,EAAAC,cAAA,SAAA,CACIsL,KAAK,SAAQ,WACHuzC,EAAItyC,OAAO,cACrBklB,SAAUmzB,EAAa,GAAI,EAAE,aACjB/F,EAAItyC,OAAO,sBAAqB,eAC9ByjD,EAAU,YAASziD,EAAS,gBAC3Bo3C,QAAep3C,EAC9B+kB,SAAUgyB,EACVp7B,UAAW1e,GACP,cACA85C,GAAU,sBACV1D,IAAiB0D,GAAU,uBAC3BjyB,GAAY,wBACZ29B,GAAW,qBACXrL,GAAe,yBAEnBhzB,QAASA,IAAM0xB,GAAUxE,GACzBoG,QAASA,IAAMzB,GAAc3E,GAC7B/sB,UAAYd,GA1L3Bi/B,EAACj/B,EAAyC6tB,KAC/D,IAAIhhC,EAAqB,KACzB,OAAQmT,EAAMnwB,KACV,IAAK,YACDgd,EAAOghC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,aACDtjC,EAAOghC,EAAIpzC,IAAI,EAAG,OAClB,MACJ,IAAK,UACDoS,EAAOghC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,YACDtjC,EAAOghC,EAAIpzC,IAAI,EAAG,OAClB,MACJ,IAAK,OACDoS,EAAOghC,EAAIpyC,QAAQ,QACnB,MACJ,IAAK,MACDoR,EAAOghC,EAAIwB,MAAM,QACjB,MACJ,IAAK,SACDxiC,EAAOmT,EAAMooB,SAAWyF,EAAIsC,SAAS,EAAG,QAAUtC,EAAIsC,SAAS,EAAG,SAClE,MACJ,IAAK,WACDtjC,EAAOmT,EAAMooB,SAAWyF,EAAIpzC,IAAI,EAAG,QAAUozC,EAAIpzC,IAAI,EAAG,SACxD,MACJ,IAAK,QACL,IAAK,IAGD,OAFAulB,EAAMiB,sBACNoxB,GAAUxE,GAEd,QACI,OAER7tB,EAAMiB,iBACFpU,GAAM2xC,GAAa3xC,IAsJmCoyC,CAAiBj/B,EAAO6tB,IAE7CA,EAAIvyC,gBAsHlByjD,GACT,UAATxC,GA1Ge2C,MACpB,MAAMC,EAASlmD,MAAM6O,KAAK,CAAE3O,OAAQ,IAAM,CAACw2C,EAAG7/B,IAAMA,GAC9CsvC,EAAgBtvD,GAASA,EAAMisD,SAAWtK,EAAasK,OAASjsD,EAAMm/C,QAAU,KAChFoQ,EAAoBnP,EAAM6L,SAAWtK,EAAasK,OAAS7L,EAAMjB,QAAU,KAC3EqQ,EAAWF,GAAiBC,GAAqB,EACvD,OACItwD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,kCACXnpB,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,gBAAgBiG,KAAK,aAAY,aAAaszB,EAAal2C,OAAO,SAC5E4jD,EAAO3sD,IAAKy8C,IACT,MAAMsQ,EAAY9N,EAAaxC,MAAMA,GAC/BuQ,EAAgBl+B,GAAYu6B,GAAgB0D,EAAW/N,EAAYtB,GACnE7uB,EAAW+9B,IAAkBnQ,EACnC,OACIlgD,EAAAC,cAAA,MAAA,CAAKa,IAAKo/C,EAAO/2B,UAAW1e,GAAG,cAAgC,IAAjBujD,GAAsB,2BAChEhuD,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL6jB,KAAK,QAAO,aACA8wB,EACZxuB,SAAU6+B,IAAarQ,EAAQ,GAAI,EAAE,eACvB5tB,EAAQ,eACRg+B,IAAsBpQ,EAAQ,YAAS1yC,EAAS,gBAC/CijD,QAAiBjjD,EAAS,aAC7BgjD,EAAUhkD,OAAO,aAC7B2c,UAAW1e,GACP,2BACA6nB,GAAY,wBACZg+B,IAAsBpQ,GAAS,uBAC/BuQ,GAAiB,yBAErB7+B,QAASA,IAAM09B,GAAYpP,GAC3BnuB,UAAYd,GACRy+B,GAAkBz+B,EAAO,aAAcivB,EAAOkQ,EAAQpC,EAAcsB,KAGvEkB,EAAUhkD,OAAO,cAwErB2jD,GACX,SAAT3C,GA9DckD,MACnB,MAAMC,EDnWcC,EAAClR,EAAwBC,KACjD,MAAM5mC,GAAQ2mC,GAAWsM,IAAkCgB,OACrDh0C,GAAM2mC,GAAWsM,IAAkCe,OACzD,OAAO9iD,MAAM6O,KAAK,CAAE3O,OAAQI,KAAKD,IAAIyO,EAAKD,EAAO,EAAG,IAAM,CAAC6nC,EAAG7/B,IAAMhI,EAAOgI,ICgWzD6vC,CAAalR,EAASC,GAC9BkR,EAAe9vD,EAAQA,EAAMisD,OAAS,KACtCuD,GACe,MAAhBM,GAAwBF,EAAMhJ,SAASkJ,GAAgBA,EAAe,QACtEF,EAAMhJ,SAASxG,EAAM6L,QAAU7L,EAAM6L,OAAS,QAC9C2D,EAAMhJ,SAASjF,EAAasK,QAAUtK,EAAasK,OAAS2D,EAAM,IACvE,OACI3wD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,iCACXnpB,EAAAC,cAAA,MAAA,CAAKkF,IAAKopD,EAAUplC,UAAU,eAAeiG,KAAK,aAAY,aAAY,QACrEuhC,EAAMltD,IAAKupD,IACR,MAAM8D,EAAWpO,EAAasK,KAAKA,GAC7B+D,EAAex+B,GAAYw6B,GAAe+D,EAAUrO,EAAYtB,GAChE7uB,EAAWu+B,IAAiB7D,EAC5BgE,EAAY7P,EAAM6L,SAAWA,EACnC,OACIhtD,EAAAC,cAAA,MAAA,CAAKa,IAAKksD,EAAM7jC,UAAW1e,GAAG,cAA+B,IAAhBsjD,GAAqB,2BAC9D/tD,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL6jB,KAAK,oBACM49B,EACXt7B,SAAU6+B,IAAavD,EAAO,GAAI,EAAE,eACtB16B,iBACA0+B,EAAY,YAASxjD,EAAS,gBAC7BujD,QAAgBvjD,EAC/B2b,UAAW1e,GACP,0BACA6nB,GAAY,wBACZ0+B,GAAa,uBACbD,GAAgB,yBAEpBn/B,QAASA,IAAMw9B,GAAWpC,GAC1Bj7B,UAAYd,GACRy+B,GAAkBz+B,EAAO,YAAa+7B,EAAM2D,EAAO5C,EAAaqB,KAGnEpC,SA0BL0D,GAGhC,CC5gBO,MAAMO,GAA+D,CACxE9K,WAAa+K,GAAmBA,EAAgB,iCAAiCA,IAAkB,cACnG97B,MAAO,QACP+rB,MAAO,QACPlJ,OAAQ,SACRmO,OAAQ,KACRlC,cAAe,iBACfC,UAAW,aACX4L,qCAAuCvC,GAC1B,SAATA,EAAkB,6CAA+C,6CACrEnH,aAAc,cACd8K,mBAAoB,MAYXC,GAAgBpxD,EAAMoG,WAA+C,UAE1ErF,MAAOygD,EAASpkC,aAChBA,EAAYC,SACZA,EAAQkpC,SACRA,EAAQC,QACRA,EACA59B,KAAM69B,EAAQC,OACdA,EAAMn3B,QACNA,EAAOtiB,MACPA,EAAKT,OACLA,EApBe,aAoBQjH,KACvBA,EAAO,QAAO8/C,UACdA,GAAY,EAAKuB,UACjBA,GAAY,EAAKC,YACjBA,GAAc,EAAKC,kBACnBA,GAAoB,EAAKC,cACzBA,EAAaC,UACbA,EAAShqB,QACTA,EAAU,GAAE6B,YACZA,GAAc,EAAKwyB,cACnBA,EA7BuB,aA8BvBz+B,WAAYqM,EAAc4iB,cAC1BA,EAAa6L,MACbA,EAAKE,OACLA,EAAMJ,KACNA,EAAIM,aACJA,EAAYpO,QACZA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiB+M,mBACjBA,EAAkBC,kBAClBA,EAAiBr6B,SACjBA,GAAW,EAAKuvB,SAChBA,GAAW,EAAKC,4BAChBA,EAA2B5B,gBAC3BA,EAAe6B,mBACfA,EAAkBC,sBAClBA,EAAqB8L,YACrBA,EAAWC,aACXA,EAAY7L,cACZA,EAAa8L,aACbA,EAAYl2C,KACZA,EACA3M,GAAI67C,EACJ3hD,YAAa4hD,EAAe3B,SAC5BA,EACAz/B,MAAOqhC,EAASC,WAChBA,EAAU33B,UACVA,EAASpqB,SACTA,EAAQhG,UACRA,EAASu/B,UACTA,GAASzV,UACTA,GAASnnB,MACTA,GAAKqlD,iBACLA,GAAgBC,aAChBA,GAAY93B,UACZA,GAAY,gBAEhBrqB,IAEA4mD,KAEA,MAAMn5B,GAAa5yB,EAAMw3B,QACrB,KAAA,IAAYy5B,MAAwChyB,IACpD,CAACA,IAECsoB,GAAkB30B,GAAW20B,iBAAmB/6C,EAChDk7C,GAAwBX,IAAkB/pB,EAAQ2qB,SAAS,UAE3DC,GAAU5nD,EAAMojC,QAChBkuB,GAAUrK,GAAU,UAAUW,GAAQp0C,QAAQ,KAAM,MACpDw0C,GAAgB,GAAGsJ,WAGnBh0C,QAA6B9P,IAAdg0C,GACdY,GAAeC,IAAoBriD,EAAMyd,SAAuB,IAAMyuC,GAAc9uC,GAAgB,OACrGrc,GAAQf,EAAMw3B,QAChB,IAAOla,GAAe4uC,GAAc1K,GAAaY,GACjD,CAAC9kC,GAAckkC,EAAWY,KAGxBK,GAAaziD,EAAMw3B,QACrB,KAAA,CAASkoB,UAASC,UAASH,cAAaC,gBAAeG,oBAAmB+M,qBAAoBC,sBAC9F,CAAClN,EAASC,EAASH,EAAaC,EAAeG,EAAmB+M,EAAoBC,IAEpF3E,GAAkBjoD,EAAMw3B,QAAQ,IAAMk1B,GAAa3rD,GAAO0hD,IAAa,CAAC1hD,GAAO0hD,KAC/Ev2C,GAAUlM,EAAM6d,YAAatR,GAAyD,MAAlCmgD,GAAangD,EAAMk2C,IAAqB,CAACA,KAE7F0F,GAAenoD,EAAMgd,YAA2CxP,GACtExN,EAAMic,UAAU,KACZ,MAAMyU,EAAOy3B,GAAalrC,aACbzP,IAATkjB,GAAsBA,IAASu3B,WACtBz6C,IAATkjB,GAAsBu3B,KAAiBzB,IAAUyB,GAAiBlnD,IACtEonD,GAAalrC,QAAUgrC,KACxB,CAACA,GAAiBlnD,GAAOylD,IAE5B,MAAM4B,GAAWpoD,EAAM6d,YACnB,CAACC,EAAoBuqC,KACZ/qC,IAAc+kC,GAAiBvkC,GACpC,MAAMwqC,EAAgC,CAAEL,gBAAiByE,GAAa5uC,EAAM2kC,KACxE4F,IAAUC,EAAQD,SAAWA,GACjChrC,IAAWS,EAAMwqC,IAErB,CAAChrC,GAAcD,EAAUolC,KAIvB8F,QAAgC/6C,IAAbi5C,GAClB+B,GAAcC,IAAmBzoD,EAAMyd,UAAS,GACjDmL,GAAO2/B,KAAqB9B,EAAW+B,GACvCE,GAAiB1oD,EAAMgd,OAAqBjc,IAC5C4nD,GAAkB3oD,EAAMgd,OAAqBjc,IAG7CqlD,GAASpmD,EAAM6d,YACjB,CAACC,EAAoB8qC,GAAQ,MACpBA,GAASuD,GAAYruC,EAAM6qC,GAAgB1rC,WAChD0rC,GAAgB1rC,QAAUa,EAC1ByoC,IAAWzoC,KAEf,CAACyoC,IAECjjB,GAAUtjC,EAAMgd,OAA8B,MAC9C6rC,GAAY7oD,EAAMgd,OAAiC,MACnD8rC,GAAkB9oD,EAAMgd,OAA2B,OAIlD+rC,GAAgBC,IAAqBhpD,EAAMyd,cAAuCjQ,GACzFxN,EAAMic,UAAU,KACZ,QAAkBzO,IAAdnO,EAAyB,OAC7B,MAAM4pD,EAAO3lB,GAAQrmB,SAASisC,eAAe93B,QAAQ,qBAAqB+3B,aAAa,kBACvFH,GAA2B,SAATC,EAAkB,OAAkB,UAATA,EAAmB,aAAUz7C,KAE9E,MAAM47C,GAAqB/pD,GAAa0pD,IAIjCz5B,GAAU+5B,IAAerpD,EAAMyd,SAAgC,MAChE6rC,GAAatpD,EAAM6d,YACpBwN,IACGiY,GAAQrmB,QAAUoO,EAClBg+B,GAAYh+B,GACO,mBAARlmB,GAAoBA,GAAIkmB,GAC1BlmB,KAAMA,GAAsD8X,QAAUoO,IAEnF,CAAClmB,KAGCghD,GAAanmD,EAAM6d,YAAY,KAC7B0U,GAAYuvB,GAAYl5B,KAC5B8/B,GAAezrC,QAAUlc,GACzB+nD,GAAgB7rC,QAAWxC,SAAS2X,eAAwC,KACvEm2B,IAAkBE,IAAgB,GACvC/B,QACD,CAACn0B,EAAUuvB,EAAUl5B,GAAM7nB,GAAOwnD,GAAkB7B,IAEjD6C,GAAcvpD,EAAM6d,YAAY,KAClC,IAAK+K,GAAM,OACN2/B,IAAkBE,IAAgB,GACvCl5B,MACA,MAAM/I,EAASqiC,GAAU5rC,SAAW6rC,GAAgB7rC,QACpDtc,OAAO6a,WAAW,IAAMgL,GAAQ4D,UAAW,IAC5C,CAACxB,GAAM2/B,GAAkBh5B,IAEtBi6B,GAAiBxpD,EAAM6d,YACxBC,IACGsoC,GAAOtoC,GAAM,GACbyrC,MAEJ,CAACnD,GAAQmD,KAGPE,GAAgBzpD,EAAM6d,YAAY,KAEpCuoC,GAAOrlD,IACPwoD,MACD,CAACxoD,GAAOqlD,GAAQmD,KAEbG,GAAuB1pD,EAAM6d,YAC/B,CAACC,EAAoB8wC,KACjBxG,GAAStqC,GACc,WAAnB8wC,GAA+BlH,IAAuB8B,GAAe1rC,IAE7E,CAACsqC,GAAUV,GAAuB8B,MAkC/BhE,GAAS+L,IAAcvxD,EAAMyd,UAAS,IACtCte,GAAM01B,IAAW70B,EAAMyd,SAAS,IAAMpR,GAAWtL,GAAOyL,KACxD69C,GAAcC,IAAmBtqD,EAAMyd,UAAS,GAIjD+zC,GAAaxxD,EAAMgd,OAAOwoC,IAChCgM,GAAWv0C,QAAUuoC,GACrBxlD,EAAMic,UAAU,KACRu1C,GAAWv0C,UACf4X,GAAQxoB,GAAWtL,GAAOyL,IAC1B89C,IAAgB,KACjB,CAACvpD,GAAOyL,IAEX,MAqCMoD,GAAoB,MAAT7O,GACX+pD,KAAc3D,GAAgC,MAAnBc,IAA2BoC,GACtD9U,GAAiB3lC,GAAWvD,GAAWtL,GAAOyL,GAAU,KAExDu+C,IAAcjE,GAChB9mD,EAAAC,cAAA,SAAA,CACIkF,IAAK0jD,GACLt9C,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATlF,GAAoB,sBAAqB,aAC5EqtB,GAAWuzB,WAAW5Q,IAClCrzC,MAAO0wB,GAAWuzB,WAAW5Q,IAAe,gBAC9B,SAAQ,gBACP3sB,GACf2J,SAAUA,EACVX,QAAUX,IACNA,EAAMO,kBACF5I,GAAM6gC,KACLtD,OAGTnmD,EAAAC,cAACg+C,GAAY,CAAC14C,KAAe,UAATA,EAAmB,GAAK,MAI9CylD,GAAcpE,GAAah3C,KAAa2iB,IAAauvB,GACvD9hD,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATlF,GAAoB,mCACvDqtB,GAAWwC,MACvBlzB,MAAO0wB,GAAWwC,MAClBxD,QApCOX,IACXA,EAAMO,kBACN42B,GAAS,MACThC,GAAO,QAmCHpmD,EAAAC,cAAC6sB,GAAS,CAACvnB,KAAe,UAATA,EAAmB,GAAK,MAI3C0lD,GAAajrD,EAAMw3B,QACrB,KAAA,IAAaoH,MAAkD58B,KAC/D,CAAC48B,GAAW58B,KAEVkpD,GAAoBlrD,EAAMw3B,QAC5B,KAAA,IAAaoH,MAAkD0oB,KAC/D,CAAC1oB,GAAW0oB,KAIV6D,GAAgBnrD,EAAMw3B,QACxB,KACKwvB,GAAa,IAAIvjD,IAAI,CAAC4kD,EAAUrlC,KAC7B,IAAIooC,EAA8B,KAClC,IACIA,EAAgBc,GAAc7D,EAASnH,SAAS,CAAEh1C,aACtD,CAAE,MACE,CAEJ,MAAO,CAAEm8C,WAAUvnD,IAAKunD,EAASj9C,IAAM,GAAGi9C,EAASp7C,SAAS+V,IAASjiB,MAAOqqD,KAEpF,CAACpE,EAAW96C,KA8BhB,OACIlM,uBACImF,IAAKmkD,GACLngC,UAAW1e,GAAG,iBAAkB46C,GAAa,sBAAuBl8B,qBACpDigC,GAChBpnD,MAAOipD,IAEPjrD,EAAAC,cAAC2E,GAAS,CACNwG,GAAIkmD,GACJv5C,KAAMA,EACN9K,MAAOA,EACPlM,MAAO5B,GACPmG,YAAa4hD,GAAmBK,GAChChiD,KAAMA,EACN8/C,UAAWA,EACX9yB,SAAUA,EACVuvB,SAAUA,EACVyD,SAAUA,EACVz/B,MAAOglC,GACPtF,QAASA,GACTC,UAAWoB,EACXp3B,UAAWA,EACXpqB,SAAUA,EACVsgD,UAAoB,MAAT14C,EAAgB2lB,GAAWyzB,kBAAe74C,EACrDk4C,UACI1lD,EAAAC,cAAAD,EAAAuuB,SAAA,KACKy8B,GACAD,IAGT1tC,SA1Jco0C,IACtB58B,GAAQ48B,GACR,MAAMrS,EAAUqS,EAASl9C,OACzB,IAAK6qC,GAAWA,EAAQkC,gBAAkBiG,GAAgBjG,cAGtD,OAFAgJ,IAAgB,QACF,OAAVvpD,IAAgBqnD,GAAS,OAGjC,MAAMh8C,EAAS+yC,GAAcC,EAAS5yC,GACtC89C,GAA0B,MAAVl+C,GACZA,IAAW+/C,GAAY//C,EAAQrL,KAAQqnD,GAASh8C,IAiJ5C84C,QAASA,IAAMqM,IAAW,GAC1B/7B,OA/IOk1B,KACf6G,IAAW,GAENlH,IAAcx1B,GAAQxoB,GAAWtL,GAAOyL,IAExCoc,IAAMw9B,GAAOrlD,KA2IV6wB,QAASA,IAAMi1B,GAAeV,KAC9Bp0B,UAzIgBd,IACN,cAAdA,EAAMnwB,KAAwBmwB,EAAM25B,OAGf,UAAd35B,EAAMnwB,MACbmwB,EAAMiB,iBACDtJ,IAAMw9B,GAAOrlD,MAJlBkwB,EAAMiB,iBACNi0B,SAwIe,MAAdiB,GAAqC,KAAfA,GACnBpnD,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,GAAG,iBAAkBqgD,IAAa,0BAA2B1D,GAGjFpnD,EAAAC,cAACovB,GAAO,CACJzG,KAAMA,GACN0G,SAAUA,GACVE,UAAWA,GACX21B,UAAWsE,GACXpqD,UAAW+pD,GACXjgC,UAAWk+B,GACXrlD,MAAOkpD,GACP9F,WAAYvmB,EAAcmpB,QAAgBx6C,GAE1CxN,EAAAC,cAAA,MAAA,CAAKkpB,UAAW1e,GAAG,iBAAkBo0B,GAAe,iCAC/CA,GA7Eb7+B,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,kCACXnpB,EAAAC,cAAA,IAAA,CAAGkpB,UAAU,wBAAwB/d,GAAI48C,IACpCp1B,GAAWyzB,cAEhBrmD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,sBAAqB,YAAW,UAC1CpoB,GAAQA,GAAMyL,OAAO6kD,GAAiBz+B,GAAWu+B,qBAyE9CnxD,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,uBACVgiC,GAAc/gD,OAAS,GACpBpK,EAAAC,cAAA,KAAA,CAAIkpB,UAAU,oBAAmB,aAAY,aACxCgiC,GAAc1nD,IAAI,EAAG4kD,WAAUvnD,MAAKC,MAAOqqD,KACxCprD,EAAAC,cAAA,KAAA,CAAIa,IAAKA,GACLd,EAAAC,cAAA,SAAA,CACIsL,KAAK,SACL4d,UAAW1e,GACP,mBACAmF,IAAYu8C,GAAYf,EAAerqD,KAAU,8BAErDwxB,SAAUA,GAAYuvB,EACtBlwB,QAASA,IAzOzBy2B,KACpB,MAAMvqC,EAAOouC,GAAc7D,EAASnH,SAAS,CAAEh1C,cAC/Ck8C,GAAStqC,EAAMuqC,GACfmB,GAAe1rC,IAsOoC6tC,CAAetD,IAE7BA,EAASp7C,UAM9BjN,EAAAC,cAACwtD,IACG1sD,MAAOA,GACPsc,SAAUqsC,GACV7H,cAAeA,EACf6L,MAAOA,EACPE,OAAQA,EACRJ,KAAMA,EACNM,aAAcA,EACdpO,QAASA,EACTC,QAASA,EACTH,YAAaA,EACbC,cAAeA,EACfG,kBAAmBA,EACnB+M,mBAAoBA,EACpBC,kBAAmBA,EACnB7K,4BAA6BA,EAC7B5B,gBAAiBA,EACjB6B,mBAAoBA,EACpBC,sBAAuBA,EACvB8L,YAAaA,EACbC,aAAcA,EACd7L,cAAeA,EACf8L,aAAcA,EACdr7B,WAAYA,GACZvzB,UAAW+pD,GACX35B,WAAS,KAhH7BuN,EAAQ5yB,OAAS,GACbpK,EAAAC,cAAA,MAAA,CAAKkpB,UAAU,mBACV6T,EAAQv5B,IAAK25B,GACVp9B,EAAAC,cAAA,SAAA,CACIa,IAAKs8B,EACL7xB,KAAK,SACL4d,UAAW1e,GAAG,eAA2B,WAAX2yB,GAAkC,UAAXA,IAAuB,wBAC5ExL,QAASA,IA3JPwL,KAClB,OAAQA,GACJ,IAAK,QACDgrB,GAAS,MACToB,GAAe,MACf,MAEJ,IAAK,QAAS,CACV,MAAM1rC,EAAO9R,IAAQU,QAAQ,OAC7B07C,GAAStqC,GACL4pC,IAAuB8B,GAAe1rC,GAC1C,KACJ,CACA,IAAK,SACIquC,GAAYprD,GAAO2nD,GAAezrC,UAAUmrC,GAASM,GAAezrC,SACzEssC,KACA,MAGJ,QACIC,GAAezoD,MAuIQ6qD,CAAaxuB,IAE3BxK,GAAWwK,QA+GpC,GAEAg0B,GAAc10C,YAAc,sCCjfd,UAAwBxa,MAAEA,EAAKw1C,QAAEA,EAAOta,OAAEA,EAAMxU,KAAEA,EAAI2G,QAAEA,KAAYhsB,IAChF,OACEvD,EAAAC,cAACyxD,GAAOrM,WAAS,EAAC7kD,SAAS,KAAKooB,KAAMA,EAAM2G,QAASA,KAAahsB,GAChEvD,EAAAC,cAAC0xD,EAAW,CAACrxD,GAAI,CAAEsxD,GAAI,IAAM1vD,GAE5Bw1C,GAAW13C,EAAAC,cAAC4xD,EAAa,CAACvxD,GAAI,CAAE0H,WAAY,cAAa0vC,EAAyB,KAEnF13C,EAAAC,cAAC6xD,EAAa,KACZ9xD,EAAAC,cAACuuB,EAAM,CAACoD,QAASrC,GAAO,UACvB6N,GAIT,kCCbc,UAAkCj6B,WAC5CA,EAAa,CAAEC,YAAY,GAAMC,aACjCA,EAAe,CAAED,YAAY,GAAME,aACnCA,EAAYzB,eAEZA,KACG0B,IAEH,OACIvD,EAAAC,cAACuD,6BAA0B,IACnBD,GAGH1B,EACD7B,EAAAC,cAAC0D,wBAAqB,CAACC,QAAST,IAChCnD,EAAAC,cAAC4D,0BAAuB,CAACD,QAASP,IAClCrD,EAAAC,cAAC6D,2BAAwBF,QAASN,IAG9C,sFCnBc,UAA0BslB,KACtCA,EAAIzpB,KACJA,EACEa,EAAAC,cAAAD,EAAAuuB,SAAA,4GACsGvuB,EAAAC,cAAA,KAAA,MACpGD,EAAAC,cAAA,KAAA,MAEC,2DAGL,OACED,EAAAC,cAACyxD,SAAM,CAAC9oC,KAAMA,EAAMy8B,WAAS,EAAC/kD,GAAI,CAAEyxD,EAAG,IACrC/xD,EAAAC,cAAC4xD,gBAAa,CAACvxD,GAAI,CAAEyxD,EAAG,EAAGC,UAAW,WACpChyD,EAAAC,cAACgyD,aAAU,CAAClvD,QAAQ,YAAYzC,GAAI,CAAEG,GAAI,IACvCtB,GAEHa,EAAAC,cAACiyD,EAAAA,iBAAgB,OAIzB,kRjCkHc,UAAsB99B,OAChCA,EAAMpV,KACNA,EAAIb,QACJA,EAAOqjB,WACPA,EAAUC,iBACVA,EAAgBxK,WAChBA,GAAa,EAAIb,SACjBA,EAAW,GAAE2I,MACbA,EAAQ,CAAA,EAAEv5B,UACVA,EAAY,CAAA,EAAEs5B,aACdA,EAAe,CAAA,EAAEiE,aACjBA,EAAe,CAAA,EAAEvM,gBACjBA,EAAkB,CAAC,GAAI,GAAI,GAAI,KAAIl2B,GACnCA,EAAK,CAAA,EAAEm+B,OACPA,EAAS,CAAE9W,SAAU,GAAGgX,MACxBA,EAAQ,CAAEhX,SAAU,GAAGiQ,sBACvBA,EAAqBuI,8BACrBA,EAA6BC,2BAC7BA,EAA0BC,sBAC1BA,EAAqBpK,uBACrBA,GAAyB,EAAKgL,2BAC9BA,GAA6B,EAAIlL,oBACjCA,GAAsB,EAAKtjB,kBAC3BA,GAAoB,EAAKojB,sBACzBA,GAAwB,EAAKmL,6BAC7BA,GAA+B,EAAK7C,uBACpCA,EAAsBC,0BACtBA,EAAyBY,WACzBA,EAAa,4CAA2C+B,kBACxDA,GAAoB,EAAKK,0BACzBA,EAAqCvK,kBACrCA,EAA6B0K,gBAC7BA,EAA2BM,sBAC3BA,EAAqBC,qBACrBA,EAAoB5D,QACpBA,GAAU,EAAKmD,gBACfA,EAA2BhC,aAC3BA,EAAYR,YACZA,GAAc,EAAIzH,mBAClBA,GAAqB,EAAKoJ,oBAC1BA,EAA+B4B,8BAC/BA,EAAyCR,WACzCA,EAAsBN,4BACtBA,GAA8B,IAE9B,MAAM6b,EAASj/C,EAAc,OAAQ,MAC/Bi0D,EAAiCnyD,EAAMw3B,QAAQ,KACjD,GAAK4I,EAGL,OAAOv/B,EAA4Cu/B,SAA+B5yB,GACnF,CAAC4yB,IAEEgyB,EAAyBpyD,EAAMw3B,QAAQ,KACzC,IAAK6I,EACD,OAGJ,MAlEuBgyB,EAAC5nB,EAAgCtsB,KAC5D,IAAKssB,GAA0C,IAAzBA,EAAcrgC,OAChC,OAEJ,MAAMkoD,EAAe,IAAIjpD,IAAI8U,EAAQ1a,IAAK80B,GAAWA,EAAOzuB,QAC5D,OAAO2gC,EAAc9/B,OAAQb,GAAUwoD,EAAavoD,IAAID,KA6D7CuoD,CADaxxD,EAA2Bw/B,GACJliB,IAC5C,CAACkiB,EAAuBliB,IAErBo0C,QACwB/kD,IAA1BoqB,EAAsCA,EAAwBu6B,EAE5DK,GAAoCxyD,EAAM6d,YAC5C,CAAC8Z,EAAkC86B,KAC3BryB,GACAj/B,EAAkBi/B,EAA4BzI,GAElDwI,IAAgCxI,EAAO86B,IAE3C,CAACryB,EAA4BD,IAG3BuyB,GAA0B1yD,EAAM6d,YAClC,CAAC6H,EAAQuL,EAAOwhC,KACZ,GAAIpyB,EAAuB,CACvB,MAAMoK,EAAgBgoB,EAAQnlD,IAAIgR,gBAAgB7a,IAAK80B,GAAWA,EAAOzuB,OACzE3I,EAAkBk/B,EAAuBoK,EAC7C,CACAjK,IAAsB9a,EAAQuL,EAAOwhC,IAEzC,CAACpyB,EAAuBG,IAGtBmyB,GAA8C,CAChDp/B,QAAS,UACT0D,WAAY,CAAEZ,gBAAiB,CAAED,aACjCzrB,OAAQ,CACJwuB,YAAa,CACTtO,MAAO,GACP8S,iCAAiC,OAGtCoF,EACH5kB,QAAS,IACF4kB,GAAc5kB,QACjByZ,sBAAuB26B,IAAiCxvB,GAAc5kB,SAASyZ,sBAC/E6S,cAAe2nB,GAA0BrvB,GAAc5kB,SAASssB,gBAIxE,OACIzqC,EAAAC,cAAC2yD,OAAI,CAACtyD,GAAI,CAAET,OAAQ,UAAW4+B,IAC3Bz+B,EAAAC,cAACC,OAAII,GAAI,CAAEZ,QAAS,OAAQE,eAAgB,gBAAiBD,WAAY,SAAUkJ,GAAI,IACnF7I,EAAAC,cAAC4yD,aAAU,CAAC3wD,MAAOkyB,EAAQ9zB,GAAI,CAAEG,GAAI,KACpC29B,EACDp+B,EAAAC,cAACC,EAAAA,IAAG,CACAI,GAAI,CACAZ,QAAS,OACT88B,IAAK2gB,EAAS,EAAI,EAClBx9C,WAAY,SACZmzD,SAAU,OACVlzD,eAAgB,aAGnBu+B,IAGTn+B,EAAAC,cAACC,EAAAA,KAAIC,UAAU,MAAMG,GAAI,CAAEZ,QAAS,OAAQqzD,cAAe,SAAUprC,SAAU,KAAMgX,IACjF3+B,EAAAC,cAAC+yD,kBAAe,CACZ90B,QAASA,EACTsD,WAAYA,EACZC,iBAAkBA,EAClBziB,KAAMA,EACNb,QAASA,EACT8Y,WAAYA,EACZhB,uBAAwBA,EACxBgL,2BAA4BA,EAC5BlL,oBAAqBA,EACrBtjB,kBAAmBA,EACnBojB,sBAAuBA,EACvBkJ,MAAO,CAAEwd,cAAer9C,EAAqBi9C,QAAS76C,KAAmBy9B,GACzEv5B,UAAW,CAAE+2C,cAAe,CAAEp9C,KAAM6/B,GAAcmd,QAASrd,KAAiBt5B,GAC5Eu9B,aAAc4vB,GACdn8B,gBAAiBA,EACjBl2B,GAAI,CACA,2BAA4B,CACxBqH,OAAQ65B,GAAcC,EAAmB,UAAY,cAEtDnhC,GAGP6/B,8BAA+BqyB,GAC/BzxB,kBAAmBA,EACnBK,0BAA2BA,EAC3BvK,kBAAmBA,EACnBwK,gBAAiBA,EACjBE,gBAAiBA,EACjBM,sBAAuBA,EACvBC,qBAAsBA,EACtBd,6BAA8BA,EAC9BiyB,iCAA+B,EAC/Bp0B,YAAaA,EACbzH,mBAAoBA,EACpBiI,aAAcA,EACdmB,oBAAqBkyB,GACrBtwB,8BAA+BA,EAC/BR,WAAYA,EACZN,4BAA6BA,KAKjD,qkEQ+JsC4xB,CAAC5lD,EAAiB1J,EAAqC,MACzF,GAAwB,oBAAb6W,SAA0B,OACrC,MAAMmF,EAAiBhc,EAAQgc,iBAAkB,EAC3CC,EAAQ3B,GAAiB5Q,EAAK1J,GAC9B1B,EAAQ0B,EAAQ1B,OAAS0B,EAAQkX,UAAYL,SAASvY,OAAS,GAE/DixD,EAAavzC,EACb,cAAcC,EAAMX,QACfzb,IAAI,CAACsc,EAAGgB,IAAM,cAAclB,EAAM1B,QAAQ4C,GAAGhP,OAAS,WAAWyT,GAAWzF,WAC5ElV,KAAK,mBACV,GACAuoD,EAAW,UAAUvzC,EAAMb,KAC5Bvb,IACIuc,GACG,OAAOA,EACFvc,IAAKgN,GAAS,cAAcA,EAAK1D,IAAIgF,OAAS,WAAWyT,GAAW/U,EAAKxC,mBACzEpD,KAAK,YAEjBA,KAAK,cAEJwoD,EAEF,6DAAU7tC,GAAWtjB,2eASpB0B,EAAQqlB,WAAa,IACtB,yBACC/mB,EAAQ,OAAOsjB,GAAWtjB,UAAgB,IAC3C,UAAUixD,IAAaC,0BAGrB/qC,EAAS5N,SAASxa,cAAc,UACtCooB,EAAOhM,aAAa,cAAe,QACnCgM,EAAOrmB,MAAM4D,SAAW,QACxByiB,EAAOrmB,MAAMwuB,MAAQ,IACrBnI,EAAOrmB,MAAMyuB,OAAS,IACtBpI,EAAOrmB,MAAMzB,MAAQ,IACrB8nB,EAAOrmB,MAAMnC,OAAS,IACtBwoB,EAAOrmB,MAAMkF,OAAS,IACtBmhB,EAAOrmB,MAAMqC,QAAU,IACvBoW,SAASY,KAAKC,YAAY+M,GAE1B,MAAMirC,EAAUA,KACZ3yD,OAAO6a,WAAW,KACV6M,EAAOG,YAAYH,EAAOG,WAAW/M,YAAY4M,IACtD,MAGPA,EAAOkrC,OAAS,KACZ,MAAM9qC,EAAMJ,EAAOK,cACnB,GAAKD,EAIL,IACIA,EAAI2B,QACJ3B,EAAI0B,aAAempC,EACnB7qC,EAAI4B,OACR,CAAE,MACEipC,GACJ,MATIA,KAYR,MAAMxrC,EAAMO,EAAOM,iBAAmBN,EAAOK,eAAejO,SACxDqN,GACAA,EAAIc,OACJd,EAAIe,MAAMwqC,GACVvrC,EAAIgB,SAEJT,EAAOmrC,OAASH,+LFveYI,IAA4C92C,KAAoBrP,6BAKpEomD,IAC5B1zD,EAAMgd,OAA6B,gEAJH22C,IAAMh3C,KAAoBiW"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/hooks/useResponsive.ts","../src/components/CustomNoRowsOverlay/CustomNoRowsOverlay.tsx","../src/components/MGHDataGrid/MGHDataGrid.tsx","../src/components/iconify/iconify.tsx","../src/components/Label/styles.ts","../src/components/Label/Label.tsx","../src/components/MGHGrid/utils.ts","../src/components/MGHGrid/MGHGrid.styles.ts","../src/components/MGHGrid/context.tsx","../src/components/MGHGrid/hooks.ts","../src/components/MGHGrid/export.ts","../src/components/MGHGrid/print.ts","../src/components/MGHGrid/grouping.ts","../src/components/MGHGrid/icons.tsx","../src/components/MGHGrid/components/primitives.tsx","../src/components/MGHGrid/components/Toolbar.tsx","../src/components/MGHGrid/components/Footer.tsx","../src/components/MGHGrid/components/ColumnsPanel.tsx","../src/components/MGHGrid/components/FilterPanel.tsx","../src/components/MGHGrid/components/ColumnMenu.tsx","../src/components/MGHGrid/components/Overlays.tsx","../src/components/MGHGrid/components/ActionsCell.tsx","../src/components/MGHGrid/MGHGrid.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.styles.ts","../src/components/MGHDateRangePicker/icons.tsx","../src/components/MGHDateRangePicker/utils.ts","../src/components/MGHDateRangePicker/MGHDateRangeCalendar.tsx","../src/components/MGHDateRangePicker/primitives.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.tsx","../src/components/MGHDatePicker/MGHDatePicker.styles.ts","../src/components/MGHDatePicker/utils.ts","../src/components/MGHDatePicker/MGHDateCalendar.tsx","../src/components/MGHDatePicker/MGHDatePicker.tsx","../src/components/Confirm-Dialog/confirm-dialog.tsx","../src/components/CustomGridToolbarExport/CustomGridToolbarExport.tsx","../src/components/Exporting/Exporting-Dialog.tsx"],"sourcesContent":["import useMediaQuery from '@mui/material/useMediaQuery';\nimport { useTheme, Breakpoint } from '@mui/material/styles';\n\n// ----------------------------------------------------------------------\n\ntype ReturnType = boolean;\n\nexport type Query = 'up' | 'down' | 'between' | 'only';\n\nexport type Value = Breakpoint | number;\n\nexport function useResponsive(query: Query, start?: Value, end?: Value): ReturnType {\n const theme = useTheme();\n\n const mediaUp = useMediaQuery(theme.breakpoints.up(start as Value));\n\n const mediaDown = useMediaQuery(theme.breakpoints.down(start as Value));\n\n const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Value, end as Value));\n\n const mediaOnly = useMediaQuery(theme.breakpoints.only(start as Breakpoint));\n\n if (query === 'up') {\n return mediaUp;\n }\n\n if (query === 'down') {\n return mediaDown;\n }\n\n if (query === 'between') {\n return mediaBetween;\n }\n\n return mediaOnly;\n}\n\n// ----------------------------------------------------------------------\n\ntype BreakpointOrNull = Breakpoint | null;\n\nexport function useWidth() {\n const theme = useTheme();\n\n const keys = [...theme.breakpoints.keys].reverse();\n\n return (\n keys.reduce((output: BreakpointOrNull, key: Breakpoint) => {\n const matches = useMediaQuery(theme.breakpoints.up(key));\n\n return !output && matches ? key : output;\n }, null) || 'xs'\n );\n}\n","import styled from '@emotion/styled';\n\nimport { Box } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n// import { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n\nimport React from 'react';\n// import { NoRowsOverlayPropsOverrides } from './CustomNoRowsOverlay.types';\n\n/// ---------------------------------------------------------------------------------------\n\ndeclare module '@mui/x-data-grid-premium' {\n export interface NoRowsOverlayPropsOverrides {\n text: string;\n useSettingsContext?: () => { themeMode?: string };\n }\n}\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomNoRowsOverlay({ text, useSettingsContext }: NoRowsOverlayPropsOverrides) {\n const theme = useTheme();\n const themeMode = useSettingsContext?.()?.themeMode ?? theme.palette.mode ?? 'light';\n\n const StyledGridOverlay = styled('div')(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n '& .ant-empty-img-1': {\n fill: themeMode === 'light' ? '#aeb8c2' : '#262626',\n },\n '& .ant-empty-img-2': {\n fill: themeMode === 'light' ? '#f5f5f7' : '#595959',\n },\n '& .ant-empty-img-3': {\n fill: themeMode === 'light' ? '#dce0e6' : '#434343',\n },\n '& .ant-empty-img-4': {\n fill: themeMode === 'light' ? '#fff' : '#1c1c1c',\n },\n '& .ant-empty-img-5': {\n fillOpacity: themeMode === 'light' ? '0.8' : '0.08',\n fill: themeMode === 'light' ? '#f5f5f5' : '#fff',\n },\n }));\n return (\n <StyledGridOverlay>\n <Box\n component=\"img\"\n alt=\"empty content\"\n src=\"/assets/icons/empty/ic_content.svg\"\n sx={{ width: 50, maxWidth: 160 }}\n />\n <Box sx={{ mb: 0 }}>{text}</Box>\n </StyledGridOverlay>\n );\n}\n","import React, { JSX } from 'react';\nimport dayjs from 'dayjs';\n\nimport { DateRange } from '@mui/x-date-pickers-pro';\n// `GridInitialStatePremium` itself only lives under an internal (non-exported) subpath; the\n// package re-exports it under this name from its public entry point instead.\nimport { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';\nimport { Box, Card, Theme, Badge, styled, SxProps, Tooltip, TextField, CardHeader, InputAdornment } from '@mui/material';\nimport {\n Toolbar,\n GridColDef,\n QuickFilter,\n GridRowParams,\n ToolbarButton,\n GridCloseIcon,\n GridSearchIcon,\n DataGridPremium,\n GridToolbarProps,\n QuickFilterClear,\n GridEventListener,\n GridSlotsComponent,\n FilterPanelTrigger,\n GridViewColumnIcon,\n GridFilterListIcon,\n QuickFilterControl,\n QuickFilterTrigger,\n GridCallbackDetails,\n ColumnsPanelTrigger,\n GridRowHeightParams,\n GridCsvExportOptions,\n GridRowSelectionModel,\n GridCsvExportMenuItem,\n ToolbarPropsOverrides,\n GridRowClassNameParams,\n GridExcelExportOptions,\n GridPrintExportOptions,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n GridSlotsComponentsProps,\n GridExportDisplayOptions,\n GridRowHeightReturnValue,\n GridColumnVisibilityModel,\n GridToolbarExportContainer,\n GridPinnedRowsProp,\n} from '@mui/x-data-grid-premium';\nimport { useResponsive } from '../../hooks/useResponsive';\nimport CustomNoRowsOverlay from '../CustomNoRowsOverlay/CustomNoRowsOverlay';\n\ninterface CustomToolbarProps {\n dateValues: React.SetStateAction<DateRange<dayjs.Dayjs>>;\n setDateValues: React.Dispatch<React.SetStateAction<DateRange<dayjs.Dayjs>>>;\n renderDateRange?: React.ReactNode;\n customMenuItem?: JSX.Element[];\n currentParentFolderKey?: number | null;\n types?: any;\n typeKey?: number;\n setTypeKey?: React.Dispatch<React.SetStateAction<number>>;\n userData?: unknown;\n exporting?: boolean;\n setExporting?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\ninterface MGHDataGridProps {\n rows: any[];\n columns: GridColDef[];\n onRowClick?: GridEventListener<'rowClick'>;\n onRowDoubleClick?: GridEventListener<'rowDoubleClick'>;\n header: string;\n pagination?: boolean;\n pageSize?: number;\n pageSizeOptions?: number[];\n slots?: Partial<GridSlotsComponent>;\n slotProps?: GridSlotsComponentsProps & {\n toolbar?: Partial<GridToolbarProps & ToolbarPropsOverrides & CustomToolbarProps>;\n };\n toolbarProps?: any;\n initialState?: GridInitialStatePremium;\n sx?: SxProps<Theme>;\n cardSx?: SxProps<Theme>;\n boxSx?: SxProps<Theme>;\n columnVisibilityModel?: GridColumnVisibilityModel;\n onColumnVisibilityModelChange?: (model: GridColumnVisibilityModel, details: GridCallbackDetails) => void;\n columnVisibilityStorageKey?: string;\n columnOrderStorageKey?: string;\n disableDensitySelector?: boolean;\n disableRowSelectionOnClick?: boolean;\n disableColumnFilter?: boolean;\n disableColumnMenu?: boolean;\n disableColumnSelector?: boolean;\n renderHeaderEndContent?: JSX.Element;\n renderHeaderCenterContent?: JSX.Element;\n noRowsText?: string;\n checkboxSelection?: boolean;\n checkboxSelectionVisibleOnly?: boolean;\n onRowSelectionModelChange?:\n | ((rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails<any>) => void)\n | undefined;\n rowSelectionModel?: GridRowSelectionModel | undefined;\n getRowClassName?: ((params: GridRowClassNameParams<any>) => string) | undefined;\n getDetailPanelContent?: (params: GridRowParams<any>) => React.ReactNode;\n getDetailPanelHeight?: () => number;\n loading?: boolean;\n isRowSelectable?: (params: GridRowParams<any>) => boolean;\n getRowHeight?: ((params: GridRowHeightParams) => GridRowHeightReturnValue) | undefined;\n showToolbar?: boolean;\n hideFooterRowCount?: boolean;\n onColumnOrderChange?: GridEventListener<'columnOrderChange'> | undefined;\n defaultGroupingExpansionDepth?: number;\n pinnedRows?: GridPinnedRowsProp;\n keepNonExistentRowsSelected?: boolean;\n}\n\nconst canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nconst readLocalStorage = <T,>(key: string): T | null => {\n if (!canUseLocalStorage()) {\n return null;\n }\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nconst writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) {\n return;\n }\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n return;\n }\n};\n\nconst normalizeOrderedFields = (orderedFields: string[] | null, columns: GridColDef[]) => {\n if (!orderedFields || orderedFields.length === 0) {\n return undefined;\n }\n const columnFields = new Set(columns.map((column) => column.field));\n return orderedFields.filter((field) => columnFields.has(field));\n};\n\nexport default function MGHDataGrid({\n header,\n rows,\n columns,\n onRowClick,\n onRowDoubleClick,\n pagination = true,\n pageSize = 25,\n slots = {},\n slotProps = {},\n toolbarProps = {},\n initialState = {},\n pageSizeOptions = [10, 25, 50, 100],\n sx = {},\n cardSx = { flexGrow: 1 },\n boxSx = { flexGrow: 1 },\n columnVisibilityModel,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n disableDensitySelector = false,\n disableRowSelectionOnClick = true,\n disableColumnFilter = false,\n disableColumnMenu = false,\n disableColumnSelector = false,\n checkboxSelectionVisibleOnly = false,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n noRowsText = 'No data found within selected parameters.',\n checkboxSelection = false,\n onRowSelectionModelChange = undefined,\n rowSelectionModel = undefined,\n getRowClassName = undefined,\n getDetailPanelContent,\n getDetailPanelHeight,\n loading = false,\n isRowSelectable = undefined,\n getRowHeight,\n showToolbar = true,\n hideFooterRowCount = false,\n onColumnOrderChange = undefined,\n defaultGroupingExpansionDepth = undefined,\n pinnedRows = undefined,\n keepNonExistentRowsSelected = true,\n}: MGHDataGridProps) {\n const smDown = useResponsive('down', 'sm');\n const persistedColumnVisibilityModel = React.useMemo(() => {\n if (!columnVisibilityStorageKey) {\n return undefined;\n }\n return readLocalStorage<GridColumnVisibilityModel>(columnVisibilityStorageKey) ?? undefined;\n }, [columnVisibilityStorageKey]);\n\n const persistedOrderedFields = React.useMemo(() => {\n if (!columnOrderStorageKey) {\n return undefined;\n }\n const storedOrder = readLocalStorage<string[]>(columnOrderStorageKey);\n return normalizeOrderedFields(storedOrder, columns);\n }, [columnOrderStorageKey, columns]);\n\n const resolvedColumnVisibilityModel =\n columnVisibilityModel !== undefined ? columnVisibilityModel : persistedColumnVisibilityModel;\n\n const handleColumnVisibilityModelChange = React.useCallback(\n (model: GridColumnVisibilityModel, details: GridCallbackDetails) => {\n if (columnVisibilityStorageKey) {\n writeLocalStorage(columnVisibilityStorageKey, model);\n }\n onColumnVisibilityModelChange?.(model, details);\n },\n [columnVisibilityStorageKey, onColumnVisibilityModelChange]\n );\n\n const handleColumnOrderChange = React.useCallback<GridEventListener<'columnOrderChange'>>(\n (params, event, details) => {\n if (columnOrderStorageKey) {\n const orderedFields = details.api.getAllColumns().map((column) => column.field);\n writeLocalStorage(columnOrderStorageKey, orderedFields);\n }\n onColumnOrderChange?.(params, event, details);\n },\n [columnOrderStorageKey, onColumnOrderChange]\n );\n\n const mergedInitialState: GridInitialStatePremium = {\n density: 'compact',\n pagination: { paginationModel: { pageSize } },\n filter: {\n filterModel: {\n items: [],\n quickFilterExcludeHiddenColumns: false,\n },\n },\n ...initialState,\n columns: {\n ...initialState?.columns,\n columnVisibilityModel: resolvedColumnVisibilityModel ?? initialState?.columns?.columnVisibilityModel,\n orderedFields: persistedOrderedFields ?? initialState?.columns?.orderedFields,\n },\n };\n\n return (\n <Card sx={{ height: 'auto', ...cardSx }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', pr: 1 }}>\n <CardHeader title={header} sx={{ mb: 2 }} />\n {renderHeaderCenterContent}\n <Box\n sx={{\n display: 'flex',\n gap: smDown ? 1 : 2,\n alignItems: 'center',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n }}\n >\n {renderHeaderEndContent}\n </Box>\n </Box>\n <Box component=\"div\" sx={{ display: 'flex', flexDirection: 'column', flexGrow: 1, ...boxSx }}>\n <DataGridPremium\n loading={loading}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n rows={rows}\n columns={columns}\n pagination={pagination}\n disableDensitySelector={disableDensitySelector}\n disableRowSelectionOnClick={disableRowSelectionOnClick}\n disableColumnFilter={disableColumnFilter}\n disableColumnMenu={disableColumnMenu}\n disableColumnSelector={disableColumnSelector}\n slots={{ noRowsOverlay: CustomNoRowsOverlay, toolbar: MGHGridToolbar, ...slots }}\n slotProps={{ noRowsOverlay: { text: noRowsText }, toolbar: toolbarProps, ...slotProps }}\n initialState={mergedInitialState}\n pageSizeOptions={pageSizeOptions}\n sx={{\n '& .MuiDataGrid-row:hover': {\n cursor: onRowClick || onRowDoubleClick ? 'pointer' : 'default',\n },\n ...sx,\n }}\n \n onColumnVisibilityModelChange={handleColumnVisibilityModelChange}\n checkboxSelection={checkboxSelection}\n onRowSelectionModelChange={onRowSelectionModelChange}\n rowSelectionModel={rowSelectionModel}\n isRowSelectable={isRowSelectable}\n getRowClassName={getRowClassName}\n getDetailPanelContent={getDetailPanelContent}\n getDetailPanelHeight={getDetailPanelHeight}\n checkboxSelectionVisibleOnly={checkboxSelectionVisibleOnly}\n disableRowSelectionExcludeModel\n showToolbar={showToolbar}\n hideFooterRowCount={hideFooterRowCount}\n getRowHeight={getRowHeight}\n onColumnOrderChange={handleColumnOrderChange}\n defaultGroupingExpansionDepth={defaultGroupingExpansionDepth}\n pinnedRows={pinnedRows}\n keepNonExistentRowsSelected={keepNonExistentRowsSelected}\n />\n </Box>\n </Card>\n );\n}\n\ninterface MGHGridToolbarProps {\n showColumnsButton?: boolean;\n showFilterButton?: boolean;\n showExportButton?: boolean;\n showQuickFilter?: boolean;\n renderOtherButtons?: JSX.Element;\n renderDateRange?: JSX.Element;\n customMenuItem?: JSX.Element[];\n showCsvOption?: boolean;\n}\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n showCsvOption = true,\n}: MGHGridToolbarProps) {\n return (\n <Toolbar style={{ display: 'flex', justifyContent: 'space-between' }}>\n <div>\n {showColumnsButton && (\n <Tooltip title=\"Columns\">\n <ColumnsPanelTrigger render={<ToolbarButton />}>\n <GridViewColumnIcon fontSize=\"small\" />\n </ColumnsPanelTrigger>\n </Tooltip>\n )}\n {showFilterButton && (\n <Tooltip title=\"Filters\">\n <FilterPanelTrigger\n render={(props, state) => (\n <ToolbarButton {...props} color=\"default\">\n <Badge badgeContent={state.filterCount} color=\"primary\" variant=\"dot\">\n <GridFilterListIcon fontSize=\"small\" />\n </Badge>\n </ToolbarButton>\n )}\n />\n </Tooltip>\n )}\n {showExportButton && (\n <CustomGridToolbarExport customMenuItem={customMenuItem} showCsvOption={showCsvOption} />\n )}\n </div>\n\n {renderDateRange}\n\n <div>\n {renderOtherButtons}\n {showQuickFilter && <DataGridQuickFilter />}\n </div>\n </Toolbar>\n );\n}\n\ninterface ExportContainerProps {\n csvOptions?: GridCsvExportOptions & GridExportDisplayOptions;\n excelOptions?: GridExcelExportOptions & GridExportDisplayOptions;\n printOptions?: GridPrintExportOptions & GridExportDisplayOptions;\n customMenuItem?: JSX.Element[] | undefined;\n showCsvOption?: boolean;\n}\nexport const CustomGridToolbarExport = ({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n customMenuItem,\n showCsvOption = true,\n ...other\n}: ExportContainerProps) => (\n <GridToolbarExportContainer {...other}>\n {customMenuItem?.map((el) => el)}\n {showCsvOption && <GridCsvExportMenuItem options={csvOptions} />}\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n);\n\nexport function DataGridQuickFilter() {\n type OwnerState = {\n expanded: boolean;\n };\n\n const StyledQuickFilter = styled(QuickFilter)({\n display: 'grid',\n alignItems: 'center',\n });\n\n const StyledToolbarButton = styled(ToolbarButton)<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n width: 'min-content',\n height: 'min-content',\n zIndex: 1,\n opacity: ownerState.expanded ? 0 : 1,\n pointerEvents: ownerState.expanded ? 'none' : 'auto',\n transition: theme.transitions.create(['opacity']),\n }));\n\n const StyledTextField = styled(TextField)<{\n ownerState: OwnerState;\n }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n overflowX: 'clip',\n width: ownerState.expanded ? 260 : 'var(--trigger-width)',\n opacity: ownerState.expanded ? 1 : 0,\n transition: theme.transitions.create(['width', 'opacity']),\n }));\n\n return (\n <StyledQuickFilter>\n <QuickFilterTrigger\n render={(triggerProps, state) => (\n <Tooltip title=\"Search\" enterDelay={0}>\n <StyledToolbarButton\n {...triggerProps}\n ownerState={{ expanded: state.expanded }}\n color=\"default\"\n aria-disabled={state.expanded}\n >\n <GridSearchIcon fontSize=\"small\" />\n </StyledToolbarButton>\n </Tooltip>\n )}\n />\n <QuickFilterControl\n render={({ ref, ...controlProps }, state) => (\n <StyledTextField\n {...controlProps}\n ownerState={{ expanded: state.expanded }}\n inputRef={ref}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n size=\"small\"\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <GridSearchIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n endAdornment: state.value ? (\n <InputAdornment position=\"end\">\n <QuickFilterClear\n edge=\"end\"\n size=\"small\"\n aria-label=\"Clear search\"\n material={{ sx: { marginRight: -0.75 } }}\n >\n <GridCloseIcon fontSize=\"small\" />\n </QuickFilterClear>\n </InputAdornment>\n ) : null,\n ...controlProps.slotProps?.input,\n },\n ...controlProps.slotProps,\n }}\n />\n )}\n />\n </StyledQuickFilter>\n );\n}\n","import { forwardRef } from 'react';\nimport { Icon } from '@iconify/react';\n\nimport { IconifyProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\ninterface Props {\n icon: IconifyProps;\n width?: number;\n height?: number;\n sx?: any;\n}\n\nconst Iconify = forwardRef<SVGElement, Props>(({ icon, width = 20, sx, ...other }, ref) => (\n <Icon icon={icon} style={{ width: 20, height: width ?? 20, ...sx }} />\n));\n\nexport default Iconify;\n","import type { ComponentProps, ComponentType } from 'react';\nimport Box from '@mui/material/Box';\nimport { alpha, styled, useTheme } from '@mui/material/styles';\nimport { LabelColor, LabelVariant } from './types';\n\n// ----------------------------------------------------------------------\n\ninterface StyledLabelOwnerState {\n color: LabelColor;\n variant: LabelVariant;\n}\n\n// Explicitly annotated so TS doesn't need to synthesize (and re-print) an anonymous type that\n// references @mui/system's install path — under pnpm that path is store-relative and triggers\n// TS2742 (\"inferred type cannot be named without a reference to ...\") during declaration emit.\nexport const StyledLabel = styled(Box)(({\n // theme,\n ownerState,\n}: {\n // theme: Theme;\n ownerState: StyledLabelOwnerState;\n}) => {\n const theme = useTheme();\n\n const lightMode = theme.palette.mode === 'light';\n\n const filledVariant = ownerState.variant === 'filled';\n\n const outlinedVariant = ownerState.variant === 'outlined';\n\n const softVariant = ownerState.variant === 'soft';\n\n const defaultStyle = {\n ...(ownerState.color === 'default' && {\n // FILLED\n ...(filledVariant && {\n color: lightMode ? theme.palette.common.white : theme.palette.grey[800],\n backgroundColor: theme.palette.text.primary,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n border: `2px solid ${theme.palette.text.primary}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.grey[500], 0.16),\n }),\n }),\n };\n\n const colorStyle = {\n ...(ownerState.color !== 'default' && {\n // FILLED\n ...(filledVariant && {\n color: theme.palette[ownerState.color].contrastText,\n backgroundColor: theme.palette[ownerState.color].main,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette[ownerState.color].main,\n border: `2px solid ${theme.palette[ownerState.color].main}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette[ownerState.color][lightMode ? 'dark' : 'light'],\n backgroundColor: alpha(theme.palette[ownerState.color].main, 0.16),\n }),\n }),\n };\n\n return {\n height: 24,\n minWidth: 24,\n lineHeight: 0,\n borderRadius: 6,\n cursor: 'default',\n alignItems: 'center',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n justifyContent: 'center',\n textTransform: 'capitalize',\n padding: theme.spacing(0, 0.75),\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightBold,\n transition: theme.transitions.create('all', {\n duration: theme.transitions.duration.shorter,\n }),\n ...defaultStyle,\n ...colorStyle,\n };\n}) as ComponentType<ComponentProps<typeof Box> & { ownerState: StyledLabelOwnerState }>;\n","import { forwardRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { LabelProps } from './types';\nimport { StyledLabel } from './styles';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nconst Label = forwardRef<HTMLSpanElement, LabelProps>(\n ({ children, color = 'default', variant = 'soft', startIcon, endIcon, sx, ...other }, ref) => {\n // const theme = useTheme();\n\n const iconStyles = {\n width: 16,\n height: 16,\n '& svg, img': { width: 1, height: 1, objectFit: 'cover' },\n };\n\n return (\n <StyledLabel\n ref={ref}\n // component=\"span\"\n ownerState={{ color, variant }}\n sx={{\n ...(startIcon && { pl: 0.75 }),\n ...(endIcon && { pr: 0.75 }),\n ...sx,\n }}\n // theme={theme}\n {...other}\n >\n {startIcon && <Box sx={{ mr: 0.75, ...iconStyles }}> {startIcon} </Box>}\n\n {children}\n\n {endIcon && <Box sx={{ ml: 0.75, ...iconStyles }}> {endIcon} </Box>}\n </StyledLabel>\n );\n }\n);\n\nexport default Label;\n","import dayjs from 'dayjs';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridColType,\n MGHGridComparatorFn,\n MGHGridFilterItem,\n MGHGridFilterOperator,\n MGHGridLocaleText,\n MGHGridRowId,\n MGHGridRowSelectionModel,\n MGHGridRowSelectionModelInput,\n MGHGridValidRowModel,\n MGHGridValueOption,\n MGHGridValueOptionObject,\n} from './MGHGrid.types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * ----------------------------------------------------------------------------------------------- */\n\nexport const GROUPING_COLUMN_FIELD = '__row_group_by_columns_group__';\nexport const CHECKBOX_FIELD = '__check__';\nexport const DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';\nexport const AGGREGATION_FOOTER_ID = '__aggregation_footer__';\nexport const INTERNAL_FIELDS = new Set<string>([CHECKBOX_FIELD, DETAIL_PANEL_TOGGLE_FIELD]);\n\nexport const DENSITY_FACTORS = { compact: 0.7, standard: 1, comfortable: 1.3 } as const;\nexport const DEFAULT_ROW_HEIGHT = 52;\nexport const DEFAULT_HEADER_HEIGHT = 56;\nexport const DEFAULT_COLUMN_WIDTH = 100;\nexport const DEFAULT_COLUMN_MIN_WIDTH = 50;\nexport const CHECKBOX_COLUMN_WIDTH = 50;\nexport const DETAIL_TOGGLE_COLUMN_WIDTH = 50;\nexport const GROUPING_COLUMN_WIDTH = 220;\n\nexport const isInternalField = (field: string) => INTERNAL_FIELDS.has(field) || field === GROUPING_COLUMN_FIELD;\n\n/* -------------------------------------------------------------------------------------------------\n * Generic helpers\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isEmptyValue = (value: unknown) => isNil(value) || value === '' || (Array.isArray(value) && value.length === 0);\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const arraysEqual = <T>(a: T[] | undefined, b: T[] | undefined) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\nexport const moveItem = <T>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n};\n\nexport const uniqueId = (() => {\n let counter = 0;\n return (prefix = 'mgh') => {\n counter += 1;\n return `${prefix}-${counter}`;\n };\n})();\n\n/* -------------------------------------------------------------------------------------------------\n * Local storage\n * ----------------------------------------------------------------------------------------------- */\n\nexport const canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nexport const readLocalStorage = <T>(key: string): T | null => {\n if (!canUseLocalStorage()) return null;\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nexport const writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore quota / privacy errors */\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Rows\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getRowIdFromRow = <R extends MGHGridValidRowModel>(row: R, getRowId?: (row: R) => MGHGridRowId) =>\n getRowId ? getRowId(row) : (row.id as MGHGridRowId);\n\nexport const normalizeSelectionModel = (\n input: MGHGridRowSelectionModelInput | undefined,\n allIds?: MGHGridRowId[]\n): MGHGridRowSelectionModel => {\n if (!input) return { type: 'include', ids: new Set() };\n if (Array.isArray(input)) return { type: 'include', ids: new Set(input) };\n if (input instanceof Set) return { type: 'include', ids: new Set(input) };\n if (input.type === 'exclude' && allIds) {\n const ids = new Set<MGHGridRowId>();\n allIds.forEach((id) => {\n if (!input.ids.has(id)) ids.add(id);\n });\n return { type: 'include', ids };\n }\n return { type: 'include', ids: new Set(input.ids) };\n};\n\nexport const selectionModelsEqual = (a: MGHGridRowSelectionModel, b: MGHGridRowSelectionModel) => {\n if (a.ids.size !== b.ids.size) return false;\n let equal = true;\n a.ids.forEach((id) => {\n if (!b.ids.has(id)) equal = false;\n });\n return equal;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Dates\n * ----------------------------------------------------------------------------------------------- */\n\nexport const toDate = (value: unknown): Date | null => {\n if (isNil(value) || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n if (dayjs.isDayjs(value)) return value.isValid() ? value.toDate() : null;\n if (typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === 'string') {\n const parsed = dayjs(value);\n return parsed.isValid() ? parsed.toDate() : null;\n }\n return null;\n};\n\nexport const formatDate = (value: unknown, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n return dayjs(date).format(withTime ? 'M/D/YYYY h:mm A' : 'M/D/YYYY');\n};\n\nconst startOfUnit = (date: Date, withTime: boolean) =>\n withTime ? dayjs(date).startOf('minute').valueOf() : dayjs(date).startOf('day').valueOf();\n\n/* -------------------------------------------------------------------------------------------------\n * Value options (singleSelect)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isValueOptionObject = (option: MGHGridValueOption): option is MGHGridValueOptionObject =>\n typeof option === 'object' && option !== null;\n\nexport const getOptionValue = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionValue ? col.getOptionValue(option) : isValueOptionObject(option) ? option.value : option;\n\nexport const getOptionLabel = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionLabel ? col.getOptionLabel(option) : isValueOptionObject(option) ? option.label : String(option);\n\nexport const resolveValueOptions = (col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (!col.valueOptions) return [] as MGHGridValueOption[];\n return typeof col.valueOptions === 'function' ? col.valueOptions({ field: col.field, row, id }) : col.valueOptions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Cell values\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getCellValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n const raw = row ? row[col.field] : undefined;\n return col.valueGetter ? col.valueGetter(raw, row, col, api) : raw;\n};\n\nexport const getGroupingValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n if (col.groupingValueGetter) return col.groupingValueGetter(row[col.field], row, col, api);\n return getCellValue(row, col, api);\n};\n\nexport const defaultFormatValue = (value: any, col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (isNil(value)) return '';\n switch (col.type) {\n case 'date':\n return formatDate(value, false);\n case 'dateTime':\n return formatDate(value, true);\n case 'boolean':\n return value ? 'Yes' : 'No';\n case 'singleSelect': {\n const options = resolveValueOptions(col, row, id);\n const match = options.find((option) => getOptionValue(col, option) === value);\n return match !== undefined ? getOptionLabel(col, match) : String(value);\n }\n case 'number':\n return typeof value === 'number' ? (Number.isFinite(value) ? String(value) : '') : String(value);\n default:\n if (value instanceof Date) return formatDate(value, true);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n};\n\nexport const getFormattedValue = (\n value: any,\n row: MGHGridValidRowModel,\n col: MGHGridColDef,\n api: MGHGridApi,\n id?: MGHGridRowId\n) => {\n if (col.valueFormatter) return col.valueFormatter(value, row, col, api);\n return defaultFormatValue(value, col, row, id);\n};\n\nexport const formattedValueToString = (formatted: any): string => {\n if (isNil(formatted)) return '';\n if (typeof formatted === 'string') return formatted;\n if (typeof formatted === 'number' || typeof formatted === 'boolean') return String(formatted);\n if (formatted instanceof Date) return formatDate(formatted, true);\n if (typeof formatted === 'object' && 'props' in formatted) return '';\n return String(formatted);\n};\n\nexport const parseEditValue = (raw: any, col: MGHGridColDef) => {\n switch (col.type) {\n case 'number': {\n if (raw === '' || isNil(raw)) return null;\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case 'boolean':\n return Boolean(raw);\n case 'date':\n case 'dateTime': {\n if (raw === '' || isNil(raw)) return null;\n const d = toDate(raw);\n return d ?? raw;\n }\n default:\n return raw;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Sorting\n * ----------------------------------------------------------------------------------------------- */\n\nconst collator = typeof Intl !== 'undefined' ? new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) : null;\n\nconst nilFirst = (v1: any, v2: any): number | null => {\n const n1 = isNil(v1) || v1 === '';\n const n2 = isNil(v2) || v2 === '';\n if (n1 && n2) return 0;\n if (n1) return -1;\n if (n2) return 1;\n return null;\n};\n\nexport const numberComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(v1) - Number(v2);\n};\n\nexport const stringComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n const s1 = String(v1);\n const s2 = String(v2);\n if (collator) return collator.compare(s1, s2);\n return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;\n};\n\nexport const stringOrNumberComparator: MGHGridComparatorFn = (v1, v2, p1, p2) => {\n if (typeof v1 === 'number' && typeof v2 === 'number') return numberComparator(v1, v2, p1, p2);\n return stringComparator(v1, v2, p1, p2);\n};\n\nexport const dateComparator: MGHGridComparatorFn = (v1, v2) => {\n const d1 = toDate(v1);\n const d2 = toDate(v2);\n const nil = nilFirst(d1, d2);\n if (nil !== null) return nil;\n return (d1 as Date).getTime() - (d2 as Date).getTime();\n};\n\nexport const booleanComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(Boolean(v1)) - Number(Boolean(v2));\n};\n\nexport const getDefaultComparator = (type: MGHGridColType | undefined): MGHGridComparatorFn => {\n switch (type) {\n case 'number':\n return numberComparator;\n case 'date':\n case 'dateTime':\n return dateComparator;\n case 'boolean':\n return booleanComparator;\n default:\n return stringOrNumberComparator;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Filter operators\n * ----------------------------------------------------------------------------------------------- */\n\nconst lower = (value: unknown) => (isNil(value) ? '' : String(value).toLowerCase());\n\nconst hasValue = (item: MGHGridFilterItem) => !isEmptyValue(item.value);\n\nexport const stringFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'contains',\n label: 'contains',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) !== -1;\n },\n },\n {\n value: 'doesNotContain',\n label: 'does not contain',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === -1;\n },\n },\n {\n value: 'equals',\n label: 'equals',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) === needle;\n },\n },\n {\n value: 'doesNotEqual',\n label: 'does not equal',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) !== needle;\n },\n },\n {\n value: 'startsWith',\n label: 'starts with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === 0;\n },\n },\n {\n value: 'endsWith',\n label: 'ends with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => {\n const s = lower(value);\n return s.length >= needle.length && s.lastIndexOf(needle) === s.length - needle.length;\n };\n },\n },\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(lower));\n return (value) => set.has(lower(value));\n },\n },\n];\n\nconst numberOperator = (\n value: string,\n label: string,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: 'number',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterValue = Number(item.value);\n if (Number.isNaN(filterValue)) return null;\n return (cell) => {\n if (isNil(cell) || cell === '') return false;\n const n = Number(cell);\n return !Number.isNaN(n) && compare(n, filterValue);\n };\n },\n});\n\nexport const numberFilterOperators: MGHGridFilterOperator[] = [\n numberOperator('=', '=', (a, b) => a === b),\n numberOperator('!=', '!=', (a, b) => a !== b),\n numberOperator('>', '>', (a, b) => a > b),\n numberOperator('>=', '>=', (a, b) => a >= b),\n numberOperator('<', '<', (a, b) => a < b),\n numberOperator('<=', '<=', (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map((v: any) => Number(v)));\n return (value) => !isNil(value) && set.has(Number(value));\n },\n },\n];\n\nconst dateOperator = (\n value: string,\n label: string,\n withTime: boolean,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: withTime ? 'datetime-local' : 'date',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterDate = toDate(item.value);\n if (!filterDate) return null;\n const filterTime = startOfUnit(filterDate, withTime);\n return (cell) => {\n const cellDate = toDate(cell);\n if (!cellDate) return false;\n return compare(startOfUnit(cellDate, withTime), filterTime);\n };\n },\n});\n\nexport const getDateFilterOperators = (withTime: boolean): MGHGridFilterOperator[] => [\n dateOperator('is', 'is', withTime, (a, b) => a === b),\n dateOperator('not', 'is not', withTime, (a, b) => a !== b),\n dateOperator('after', 'is after', withTime, (a, b) => a > b),\n dateOperator('onOrAfter', 'is on or after', withTime, (a, b) => a >= b),\n dateOperator('before', 'is before', withTime, (a, b) => a < b),\n dateOperator('onOrBefore', 'is on or before', withTime, (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) === null,\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) !== null,\n },\n];\n\nexport const booleanFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'boolean',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '' || item.value === 'any') return null;\n const expected = item.value === true || item.value === 'true';\n return (value) => Boolean(value) === expected;\n },\n },\n];\n\nexport const singleSelectFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) === String(item.value);\n },\n },\n {\n value: 'not',\n label: 'is not',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) !== String(item.value);\n },\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(String));\n return (value) => set.has(String(value));\n },\n },\n];\n\nexport const getDefaultFilterOperators = (type: MGHGridColType | undefined): MGHGridFilterOperator[] => {\n switch (type) {\n case 'number':\n return numberFilterOperators;\n case 'date':\n return getDateFilterOperators(false);\n case 'dateTime':\n return getDateFilterOperators(true);\n case 'boolean':\n return booleanFilterOperators;\n case 'singleSelect':\n return singleSelectFilterOperators;\n case 'actions':\n return [];\n default:\n return stringFilterOperators;\n }\n};\n\nexport const getColumnFilterOperators = (col: MGHGridColDef) => col.filterOperators ?? getDefaultFilterOperators(col.type);\n\n/* -------------------------------------------------------------------------------------------------\n * Column normalisation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const normalizeColumn = <R extends MGHGridValidRowModel>(col: MGHGridColDef<R>): MGHGridColDef<R> => {\n const type = col.type ?? 'string';\n const isNumber = type === 'number';\n const isBoolean = type === 'boolean';\n const isActions = type === 'actions';\n return {\n ...col,\n type,\n headerName: col.headerName ?? col.field,\n // `width` / `minWidth` are intentionally left as given: a column without an explicit width is\n // sized to fit its header text (see `computeWidths` in MGHGrid.tsx), so the defaults live there.\n align: col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n headerAlign: col.headerAlign ?? col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n sortable: isActions ? false : (col.sortable ?? true),\n filterable: isActions ? false : (col.filterable ?? true),\n hideable: col.hideable ?? true,\n resizable: col.resizable ?? true,\n pinnable: col.pinnable ?? true,\n groupable: isActions ? false : (col.groupable ?? true),\n aggregable: isActions ? false : (col.aggregable ?? true),\n editable: col.editable ?? false,\n disableColumnMenu: col.disableColumnMenu ?? isActions,\n disableExport: col.disableExport ?? isActions,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Internal (auto-generated) columns\n * ----------------------------------------------------------------------------------------------- */\n\nconst internalColumn = (field: string, width: number): MGHGridColDef =>\n normalizeColumn({\n field,\n headerName: '',\n width,\n minWidth: width,\n maxWidth: width,\n sortable: false,\n filterable: false,\n hideable: false,\n resizable: false,\n pinnable: false,\n groupable: false,\n aggregable: false,\n disableColumnMenu: true,\n disableExport: true,\n disableReorder: true,\n align: 'center',\n headerAlign: 'center',\n });\n\n/** Definition of the checkbox-selection column (equivalent of MUI's GRID_CHECKBOX_SELECTION_COL_DEF). */\nexport const CHECKBOX_COLUMN_DEF: MGHGridColDef = internalColumn(CHECKBOX_FIELD, CHECKBOX_COLUMN_WIDTH);\n/** Definition of the detail-panel toggle column (equivalent of MUI's GRID_DETAIL_PANEL_TOGGLE_COL_DEF). */\nexport const DETAIL_PANEL_TOGGLE_COLUMN_DEF: MGHGridColDef = internalColumn(\n DETAIL_PANEL_TOGGLE_FIELD,\n DETAIL_TOGGLE_COLUMN_WIDTH\n);\n\n/* -------------------------------------------------------------------------------------------------\n * sx -> scoped CSS\n * ----------------------------------------------------------------------------------------------- */\n\nconst UNITLESS_PROPERTIES = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/** Keys that are CSS selectors / at-rules rather than CSS properties. */\nexport const isSelectorKey = (key: string) => /[&.:#>\\[\\s*~+,@]/.test(key);\n\nconst toKebabCase = (property: string) => {\n if (property.indexOf('--') === 0) return property;\n const kebab = property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return kebab.indexOf('ms-') === 0 ? `-${kebab}` : kebab;\n};\n\nconst formatCssValue = (property: string, value: string | number) =>\n typeof value === 'number' && value !== 0 && !UNITLESS_PROPERTIES.has(property) && property.indexOf('--') !== 0\n ? `${value}px`\n : String(value);\n\nconst serializeDeclarations = (block: Record<string, unknown>) =>\n Object.keys(block)\n .filter((key) => {\n const value = block[key];\n return !isSelectorKey(key) && (typeof value === 'string' || typeof value === 'number');\n })\n .map((key) => `${toKebabCase(key)}:${formatCssValue(key, block[key] as string | number)}`)\n .join(';');\n\nconst scopeSelector = (scope: string, selector: string) =>\n selector\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => (part.indexOf('&') !== -1 ? part.replace(/&/g, scope) : `${scope} ${part}`))\n .join(',');\n\n/**\n * Compiles the nested-selector part of an `sx`-like object into CSS scoped under `scope`.\n * Top-level plain properties are ignored here (they are applied as inline styles instead).\n */\nexport const buildScopedCss = (scope: string, sx: Record<string, unknown> | undefined, out: string[] = []): string[] => {\n if (!sx) return out;\n Object.keys(sx).forEach((key) => {\n const value = sx[key];\n if (!value || typeof value !== 'object') return;\n const block = value as Record<string, unknown>;\n if (key.charAt(0) === '@') {\n const inner: string[] = [];\n const declarations = serializeDeclarations(block);\n if (declarations) inner.push(`${scope}{${declarations}}`);\n buildScopedCss(scope, block, inner);\n if (inner.length) out.push(`${key}{${inner.join('')}}`);\n return;\n }\n const selector = scopeSelector(scope, key);\n const declarations = serializeDeclarations(block);\n if (declarations) out.push(`${selector}{${declarations}}`);\n buildScopedCss(selector, block, out);\n });\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nconst numericValues = (values: any[]) =>\n values.map((v) => (typeof v === 'number' ? v : Number(v))).filter((n) => !Number.isNaN(n) && n !== null);\n\nexport const BUILT_IN_AGGREGATION_FUNCTIONS: Record<string, MGHGridAggregationFunction> = {\n sum: {\n label: 'sum',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0);\n },\n },\n avg: {\n label: 'avg',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0) / nums.length;\n },\n },\n min: {\n label: 'min',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.min(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.min(...dates.map((d) => (d as Date).getTime())));\n }\n return defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any))[0];\n },\n },\n max: {\n label: 'max',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.max(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.max(...dates.map((d) => (d as Date).getTime())));\n }\n const sorted = defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any));\n return sorted[sorted.length - 1];\n },\n },\n size: {\n label: 'size',\n apply: ({ values }) => values.length,\n },\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Locale\n * ----------------------------------------------------------------------------------------------- */\n\nexport const DEFAULT_LOCALE_TEXT: MGHGridLocaleText = {\n noRowsLabel: 'No rows',\n loadingLabel: 'Loading…',\n toolbarColumns: 'Columns',\n toolbarFilters: 'Filters',\n toolbarExport: 'Export',\n toolbarDensity: 'Density',\n toolbarQuickFilterPlaceholder: 'Search...',\n toolbarQuickFilterLabel: 'Search',\n toolbarExportCSV: 'Download as CSV',\n toolbarExportExcel: 'Download as Excel',\n toolbarExportPrint: 'Print',\n densityCompact: 'Compact',\n densityStandard: 'Standard',\n densityComfortable: 'Comfortable',\n columnsPanelSearchPlaceholder: 'Search',\n columnsPanelShowAll: 'Show all',\n columnsPanelHideAll: 'Hide all',\n columnsPanelReset: 'Reset',\n filterPanelAddFilter: 'Add filter',\n filterPanelRemoveAll: 'Remove all',\n filterPanelDeleteIcon: 'Delete',\n filterPanelColumns: 'Columns',\n filterPanelOperator: 'Operator',\n filterPanelValue: 'Value',\n filterPanelInputPlaceholder: 'Filter value',\n filterPanelLogicOperator: 'Logic operator',\n filterPanelOperatorAnd: 'And',\n filterPanelOperatorOr: 'Or',\n columnMenuSortAsc: 'Sort by ASC',\n columnMenuSortDesc: 'Sort by DESC',\n columnMenuUnsort: 'Unsort',\n columnMenuFilter: 'Filter',\n columnMenuHideColumn: 'Hide column',\n columnMenuManageColumns: 'Manage columns',\n columnMenuPinLeft: 'Pin to left',\n columnMenuPinRight: 'Pin to right',\n columnMenuUnpin: 'Unpin',\n columnMenuGroup: (name) => `Group by ${name}`,\n columnMenuUngroup: (name) => `Stop grouping by ${name}`,\n columnMenuAggregation: 'Aggregation',\n aggregationMenuItemHeader: 'Aggregation',\n aggregationFunctionLabelNone: 'none',\n aggregationFunctionLabelSum: 'sum',\n aggregationFunctionLabelAvg: 'avg',\n aggregationFunctionLabelMin: 'min',\n aggregationFunctionLabelMax: 'max',\n aggregationFunctionLabelSize: 'size',\n footerRowSelected: (count) => (count === 1 ? '1 row selected' : `${count.toLocaleString()} rows selected`),\n footerTotalRows: 'Total Rows:',\n footerPaginationRowsPerPage: 'Rows per page:',\n footerPaginationDisplayedRows: (from, to, count) => `${from}–${to} of ${count.toLocaleString()}`,\n footerPaginationFirstPage: 'First page',\n footerPaginationPreviousPage: 'Previous page',\n footerPaginationNextPage: 'Next page',\n footerPaginationLastPage: 'Last page',\n checkboxSelectionHeaderName: 'Checkbox selection',\n checkboxSelectionSelectAllRows: 'Select all rows',\n checkboxSelectionUnselectAllRows: 'Unselect all rows',\n checkboxSelectionSelectRow: 'Select row',\n checkboxSelectionUnselectRow: 'Unselect row',\n booleanCellTrueLabel: 'yes',\n booleanCellFalseLabel: 'no',\n detailPanelToggle: 'Detail panel toggle',\n expandDetailPanel: 'Expand',\n collapseDetailPanel: 'Collapse',\n groupingColumnHeaderName: 'Group',\n groupColumn: (name) => `Group by ${name}`,\n unGroupColumn: (name) => `Stop grouping by ${name}`,\n actionsCellMore: 'more',\n columnHeaderSortIconLabel: 'Sort',\n columnMenuLabel: 'Menu',\n clearSearch: 'Clear search',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Text measurement (used for autosize)\n * ----------------------------------------------------------------------------------------------- */\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nexport const measureText = (text: string, font: string) => {\n if (typeof document === 'undefined') return text.length * 8;\n if (measureContext === undefined) {\n const canvas = document.createElement('canvas');\n measureContext = canvas.getContext('2d');\n }\n if (!measureContext) return text.length * 8;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Downloads\n * ----------------------------------------------------------------------------------------------- */\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n window.setTimeout(() => {\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n }, 0);\n};\n","import React from 'react';\n\nexport const MGH_GRID_STYLE_ID = 'mgh-grid-styles';\n\n/**\n * Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,\n * so consumers do not need a CSS loader. All colours are CSS variables so the look can be\n * customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance\n * through the `themeVars` prop.\n */\nexport const MGH_GRID_CSS = `\n.mgh-grid-card {\n --mgh-grid-font-family: inherit;\n --mgh-grid-font-size: 14px;\n --mgh-grid-radius: 16px;\n --mgh-grid-inner-radius: 4px;\n --mgh-grid-paper: #ffffff;\n --mgh-grid-bg: #ffffff;\n --mgh-grid-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-fg-secondary: rgba(0, 0, 0, 0.6);\n --mgh-grid-fg-disabled: rgba(0, 0, 0, 0.38);\n --mgh-grid-border: rgba(224, 224, 224, 1);\n --mgh-grid-header-bg: #ffffff;\n --mgh-grid-header-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-hover: rgba(0, 0, 0, 0.04);\n --mgh-grid-hover-strong: rgba(0, 0, 0, 0.08);\n --mgh-grid-selected: rgba(25, 118, 210, 0.08);\n --mgh-grid-selected-hover: rgba(25, 118, 210, 0.12);\n --mgh-grid-primary: #1976d2;\n --mgh-grid-primary-contrast: #ffffff;\n --mgh-grid-focus: #1976d2;\n --mgh-grid-shadow: 0 0 2px rgba(145, 158, 171, 0.2), 0 12px 24px -4px rgba(145, 158, 171, 0.12);\n --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n --mgh-grid-overlay: rgba(255, 255, 255, 0.6);\n --mgh-grid-input-bg: transparent;\n --mgh-grid-input-border: rgba(0, 0, 0, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.12);\n --mgh-grid-group-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-footer-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-badge: #1976d2;\n --mgh-grid-scrollbar: rgba(0, 0, 0, 0.3);\n\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: var(--mgh-grid-paper);\n color: var(--mgh-grid-fg);\n border-radius: var(--mgh-grid-radius);\n box-shadow: var(--mgh-grid-shadow);\n font-family: var(--mgh-grid-font-family);\n font-size: var(--mgh-grid-font-size);\n line-height: 1.5;\n overflow: hidden;\n box-sizing: border-box;\n}\n.mgh-grid-card[data-mgh-theme=\"dark\"] {\n --mgh-grid-paper: #212b36;\n --mgh-grid-bg: #212b36;\n --mgh-grid-fg: #ffffff;\n --mgh-grid-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-grid-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-grid-border: rgba(81, 81, 81, 1);\n --mgh-grid-header-bg: #212b36;\n --mgh-grid-header-fg: #ffffff;\n --mgh-grid-hover: rgba(255, 255, 255, 0.08);\n --mgh-grid-hover-strong: rgba(255, 255, 255, 0.16);\n --mgh-grid-selected: rgba(144, 202, 249, 0.16);\n --mgh-grid-selected-hover: rgba(144, 202, 249, 0.24);\n --mgh-grid-primary: #90caf9;\n --mgh-grid-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-grid-focus: #90caf9;\n --mgh-grid-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 12px 24px -4px rgba(0, 0, 0, 0.12);\n --mgh-grid-overlay: rgba(33, 43, 54, 0.6);\n --mgh-grid-input-border: rgba(255, 255, 255, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.5);\n --mgh-grid-group-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-footer-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-badge: #90caf9;\n --mgh-grid-scrollbar: rgba(255, 255, 255, 0.3);\n}\n/* Only our own elements get the border-box reset. A blanket descendant reset would leak into\n consumer content rendered through slots (e.g. MUI TextField inputs rely on content-box). */\n[class*=\"mgh-grid\"], [class*=\"mgh-grid\"]::before, [class*=\"mgh-grid\"]::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n/* Title stays on its row; only the end-content group wraps internally (like the legacy MUI card). */\n.mgh-grid-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 16px 16px 0; flex-wrap: nowrap; }\n.mgh-grid-card-title { flex: 0 0 auto; padding: 8px 24px; margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n/* Children are auto-sized so space-between leaves equal gaps title|center|end (like the legacy MUI card).\n Only the end group shrinks (and wraps internally); the centre content keeps its natural width. */\n.mgh-grid-card-header-center { flex: 0 0 auto; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }\n.mgh-grid-card-header-end { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n.mgh-grid-card-header-end:first-child { margin-left: auto; }\n@media (max-width: 599.95px) {\n .mgh-grid-card-header { flex-wrap: wrap; }\n .mgh-grid-card-header-end { gap: 8px; }\n}\n\n/* ---- box + root ---- */\n.mgh-grid-box { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; min-width: 0; }\n.mgh-grid {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n border: 1px solid var(--mgh-grid-border);\n border-radius: var(--mgh-grid-inner-radius);\n background: var(--mgh-grid-bg);\n color: var(--mgh-grid-fg);\n outline: none;\n}\n.mgh-grid--auto-height { flex: 0 0 auto; }\n\n/* ---- toolbar ---- */\n.mgh-grid-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 4px 8px; border-bottom: 1px solid var(--mgh-grid-border); flex-wrap: wrap; }\n.mgh-grid-toolbar-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }\n.mgh-grid-toolbar-center { display: flex; align-items: center; flex: 1 1 auto; justify-content: center; }\n\n/* ---- buttons ---- */\n.mgh-grid-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-grid-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; text-transform: none; white-space: nowrap; }\n.mgh-grid-btn:hover { background: var(--mgh-grid-hover); color: var(--mgh-grid-fg); }\n.mgh-grid-btn:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 1px; }\n.mgh-grid-btn:disabled { color: var(--mgh-grid-fg-disabled); cursor: default; background: transparent; }\n.mgh-grid-btn--icon { padding: 6px; border-radius: 50%; width: 32px; height: 32px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small { width: 26px; height: 26px; padding: 3px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small .mgh-grid-icon { width: 18px; height: 18px; }\n.mgh-grid-btn--primary { color: var(--mgh-grid-primary); }\n.mgh-grid-btn--primary:hover { background: var(--mgh-grid-selected); color: var(--mgh-grid-primary); }\n.mgh-grid-btn--contained { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); }\n.mgh-grid-btn--contained:hover { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); filter: brightness(0.92); }\n.mgh-grid-btn--active { color: var(--mgh-grid-primary); }\n\n/* ---- badge ---- */\n.mgh-grid-badge { position: relative; display: inline-flex; }\n.mgh-grid-badge-dot { position: absolute; top: 0; right: 0; min-width: 8px; height: 8px; border-radius: 4px; background: var(--mgh-grid-badge); transform: translate(50%, -50%); }\n.mgh-grid-badge-count { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--mgh-grid-badge); color: var(--mgh-grid-primary-contrast); font-size: 10px; font-weight: 600; line-height: 16px; text-align: center; transform: translate(50%, -50%); }\n\n/* ---- inputs ---- */\n.mgh-grid-input, .mgh-grid-select { font: inherit; font-size: 0.875rem; color: var(--mgh-grid-fg); background: var(--mgh-grid-input-bg); border: 1px solid var(--mgh-grid-input-border); border-radius: 6px; padding: 6px 10px; height: 36px; min-width: 0; outline: none; transition: border-color .15s, box-shadow .15s; }\n.mgh-grid-input:hover, .mgh-grid-select:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-input:focus, .mgh-grid-select:focus { border-color: var(--mgh-grid-focus); box-shadow: 0 0 0 1px var(--mgh-grid-focus); }\n.mgh-grid-input::placeholder { color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-input--small, .mgh-grid-select--small { height: 32px; padding: 4px 8px; font-size: 0.8125rem; }\n.mgh-grid-select { appearance: none; -webkit-appearance: none; padding-right: 28px; background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'><path d='M7 10l5 5 5-5z'/></svg>\"); background-repeat: no-repeat; background-position: right 6px center; background-size: 18px; cursor: pointer; }\n.mgh-grid-select option { color: initial; background: initial; }\n.mgh-grid-card[data-mgh-theme=\"dark\"] .mgh-grid-select option, .mgh-grid-popover[data-mgh-theme=\"dark\"] .mgh-grid-select option { color: #fff; background: #212b36; }\n.mgh-grid-select[multiple] { height: auto; min-height: 36px; background-image: none; padding-right: 10px; }\n.mgh-grid-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.mgh-grid-field-label { font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-input-adorned { position: relative; display: flex; align-items: center; }\n.mgh-grid-input-adorned .mgh-grid-input { width: 100%; padding-left: 34px; }\n.mgh-grid-input-adorned--clearable .mgh-grid-input { padding-right: 34px; }\n.mgh-grid-input-adornment { position: absolute; left: 10px; display: inline-flex; color: var(--mgh-grid-fg-secondary); pointer-events: none; }\n.mgh-grid-input-adornment--end { left: auto; right: 4px; pointer-events: auto; }\n\n/* ---- checkbox ---- */\n.mgh-grid-checkbox { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; border: 2px solid var(--mgh-grid-fg-secondary); border-radius: 3px; background: transparent; cursor: pointer; display: inline-grid; place-content: center; position: relative; flex: 0 0 auto; transition: background-color .12s, border-color .12s; }\n.mgh-grid-checkbox:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-checkbox:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 2px; }\n.mgh-grid-checkbox:checked, .mgh-grid-checkbox:indeterminate { background: var(--mgh-grid-primary); border-color: var(--mgh-grid-primary); }\n.mgh-grid-checkbox:checked::after { content: \"\"; width: 5px; height: 10px; border: solid var(--mgh-grid-primary-contrast); border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }\n.mgh-grid-checkbox:indeterminate::after { content: \"\"; width: 10px; height: 2px; background: var(--mgh-grid-primary-contrast); }\n.mgh-grid-checkbox:disabled { opacity: 0.4; cursor: default; }\n.mgh-grid-checkbox-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; padding: 6px 4px; border-radius: 4px; }\n.mgh-grid-checkbox-label:hover { background: var(--mgh-grid-hover); }\n\n/* ---- quick filter ---- */\n.mgh-grid-quick-filter { display: grid; align-items: center; }\n.mgh-grid-quick-filter-trigger { grid-area: 1 / 1; z-index: 1; transition: opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-trigger { opacity: 0; pointer-events: none; }\n.mgh-grid-quick-filter-control { grid-area: 1 / 1; width: 32px; opacity: 0; overflow: hidden; transition: width .2s, opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 260px; opacity: 1; }\n@media (max-width: 599.95px) { .mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 180px; } }\n\n/* ---- main / scroller ---- */\n.mgh-grid-main { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }\n.mgh-grid--auto-height .mgh-grid-main { flex: 0 0 auto; }\n.mgh-grid-scroller { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; outline: none; scrollbar-width: thin; }\n.mgh-grid--auto-height .mgh-grid-scroller { overflow-y: hidden; }\n.mgh-grid-scroller::-webkit-scrollbar { width: 10px; height: 10px; }\n.mgh-grid-scroller::-webkit-scrollbar-thumb { background: var(--mgh-grid-scrollbar); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }\n\n/* ---- column headers ---- */\n.mgh-grid-columns { position: sticky; top: 0; z-index: 3; background: var(--mgh-grid-header-bg); border-bottom: 1px solid var(--mgh-grid-border); min-width: 100%; width: max-content; }\n.mgh-grid-header-row { display: flex; min-width: 100%; }\n.mgh-grid-header-cell { position: relative; display: flex; align-items: center; flex: 0 0 auto; height: var(--mgh-grid-header-height); padding: 0 10px; font-weight: 600; font-size: 0.875rem; color: var(--mgh-grid-header-fg); background: var(--mgh-grid-header-bg); white-space: nowrap; overflow: hidden; user-select: none; outline: none; }\n.mgh-grid-header-cell--sortable { cursor: pointer; }\n.mgh-grid-header-cell:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; }\n.mgh-grid-header-cell--align-center { justify-content: center; }\n.mgh-grid-header-cell--align-right { justify-content: flex-end; }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title-container { flex-direction: row-reverse; }\n.mgh-grid-header-title-container { display: flex; align-items: center; gap: 2px; min-width: 0; flex: 1 1 auto; overflow: hidden; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title-container { flex: 0 1 auto; }\n/* Titles wrap onto as many lines as fit in the header height (see --mgh-grid-header-lines) before truncating. */\n.mgh-grid-header-title { overflow: hidden; text-overflow: ellipsis; white-space: normal; overflow-wrap: break-word; line-height: 1.2; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: var(--mgh-grid-header-lines, 1); line-clamp: var(--mgh-grid-header-lines, 1); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title { text-align: right; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title { text-align: center; }\n.mgh-grid-sort-icon { display: inline-flex; align-items: center; color: var(--mgh-grid-fg-secondary); opacity: 0; transition: opacity .15s; flex: 0 0 auto; }\n.mgh-grid-header-cell:hover .mgh-grid-sort-icon, .mgh-grid-sort-icon--active { opacity: 1; }\n.mgh-grid-sort-index { font-size: 10px; margin-left: -2px; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-header-menu-btn { position: absolute; right: 2px; opacity: 0; transition: opacity .15s; background: var(--mgh-grid-header-bg); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-menu-btn { right: auto; left: 2px; }\n.mgh-grid-header-cell:hover .mgh-grid-header-menu-btn, .mgh-grid-header-menu-btn--open, .mgh-grid-header-cell:focus-within .mgh-grid-header-menu-btn { opacity: 1; }\n.mgh-grid-header-cell--menu-open { background: var(--mgh-grid-hover); }\n.mgh-grid-resize-handle { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 2; display: flex; justify-content: center; touch-action: none; }\n.mgh-grid-resize-handle::after { content: \"\"; width: 1px; height: 60%; margin-top: 20%; background: var(--mgh-grid-border); transition: background .15s, width .15s; }\n.mgh-grid-resize-handle:hover::after, .mgh-grid-resize-handle--active::after { background: var(--mgh-grid-primary); width: 2px; }\n.mgh-grid-header-cell--last .mgh-grid-resize-handle { right: 0; }\n.mgh-grid-header-cell--dragging { opacity: 0.5; }\n.mgh-grid-header-cell--drop-left::before, .mgh-grid-header-cell--drop-right::before { content: \"\"; position: absolute; top: 4px; bottom: 4px; width: 2px; background: var(--mgh-grid-primary); z-index: 3; }\n.mgh-grid-header-cell--drop-left::before { left: 0; }\n.mgh-grid-header-cell--drop-right::before { right: 0; }\n.mgh-grid-header-filler { flex: 1 1 auto; background: var(--mgh-grid-header-bg); }\n\n/* ---- pinned cells ---- */\n.mgh-grid-cell--pinned-left, .mgh-grid-header-cell--pinned-left { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-cell--pinned-right, .mgh-grid-header-cell--pinned-right { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-header-cell--pinned-left, .mgh-grid-header-cell--pinned-right { z-index: 4; background-color: var(--mgh-grid-header-bg); }\n.mgh-grid-cell--pinned-left-last, .mgh-grid-header-cell--pinned-left-last { box-shadow: 2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-cell--pinned-right-first, .mgh-grid-header-cell--pinned-right-first { box-shadow: -2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid--no-pinned-shadow .mgh-grid-cell--pinned-left-last, .mgh-grid--no-pinned-shadow .mgh-grid-header-cell--pinned-left-last { box-shadow: none; }\n\n/* ---- body & rows ---- */\n.mgh-grid-body { position: relative; min-width: 100%; width: max-content; }\n.mgh-grid-body--flow { display: flex; flex-direction: column; }\n.mgh-grid-row-block { min-width: 100%; }\n.mgh-grid-body--virtual .mgh-grid-row-block { position: absolute; left: 0; }\n.mgh-grid-row { display: flex; min-width: 100%; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); position: relative; }\n.mgh-grid-row--auto-height { align-items: stretch; }\n.mgh-grid-row:hover { background: var(--mgh-grid-hover); }\n.mgh-grid-row--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-row--selected:hover { background: var(--mgh-grid-selected-hover); }\n.mgh-grid-row--clickable { cursor: pointer; }\n.mgh-grid-row--group { background: var(--mgh-grid-group-bg); }\n.mgh-grid-row--pinned { background: var(--mgh-grid-bg); }\n.mgh-grid-row--footer { background: var(--mgh-grid-footer-bg); font-weight: 600; }\n.mgh-grid-row:hover .mgh-grid-cell--pinned-left, .mgh-grid-row:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-hover), var(--mgh-grid-hover)); }\n.mgh-grid-row--selected .mgh-grid-cell--pinned-left, .mgh-grid-row--selected .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected), var(--mgh-grid-selected)); }\n.mgh-grid-row--selected:hover .mgh-grid-cell--pinned-left, .mgh-grid-row--selected:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected-hover), var(--mgh-grid-selected-hover)); }\n.mgh-grid-row--group .mgh-grid-cell--pinned-left, .mgh-grid-row--group .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-group-bg), var(--mgh-grid-group-bg)); }\n.mgh-grid-row--footer .mgh-grid-cell--pinned-left, .mgh-grid-row--footer .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-footer-bg), var(--mgh-grid-footer-bg)); }\n.mgh-grid-row-filler { flex: 1 1 auto; }\n\n.mgh-grid-cell { display: flex; align-items: center; flex: 0 0 auto; padding: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.875rem; outline: none; min-height: 100%; }\n.mgh-grid-cell > .mgh-grid-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.mgh-grid-row--auto-height .mgh-grid-cell { white-space: normal; align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }\n.mgh-grid-row--auto-height .mgh-grid-cell > .mgh-grid-cell-text { white-space: normal; word-break: break-word; }\n.mgh-grid-cell--align-center { justify-content: center; }\n.mgh-grid-cell--align-right { justify-content: flex-end; }\n.mgh-grid-cell--focused { outline: 1px solid var(--mgh-grid-focus); outline-offset: -1px; }\n.mgh-grid-cell--editable { cursor: text; }\n.mgh-grid-cell--editing { padding: 0 4px; outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; background: var(--mgh-grid-bg); }\n.mgh-grid-cell--editing .mgh-grid-input, .mgh-grid-cell--editing .mgh-grid-select { width: 100%; height: calc(100% - 6px); border: 0; box-shadow: none; padding: 0 6px; background: transparent; }\n.mgh-grid-cell--checkbox, .mgh-grid-header-cell--checkbox, .mgh-grid-cell--detail-toggle, .mgh-grid-header-cell--detail-toggle { justify-content: center; padding: 0; }\n.mgh-grid-cell--boolean .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-cell--actions { gap: 2px; justify-content: center; }\n.mgh-grid-cell--aggregation { flex-direction: column; align-items: stretch; justify-content: center; line-height: 1.2; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-right { align-items: flex-end; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-center { align-items: center; }\n.mgh-grid-aggregation-label { font-size: 0.65rem; font-weight: 500; text-transform: uppercase; color: var(--mgh-grid-fg-secondary); letter-spacing: .04em; }\n.mgh-grid-group-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }\n.mgh-grid-group-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.mgh-grid-group-count { color: var(--mgh-grid-fg-secondary); margin-left: 2px; }\n.mgh-grid-group-toggle { flex: 0 0 auto; }\n.mgh-grid-group-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-group-toggle--expanded .mgh-grid-icon { transform: rotate(90deg); }\n.mgh-grid-detail-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-detail-toggle--expanded .mgh-grid-icon { transform: rotate(180deg); }\n\n/* ---- pinned rows ---- */\n.mgh-grid-pinned-rows { position: sticky; z-index: 2; min-width: 100%; width: max-content; background: var(--mgh-grid-bg); }\n.mgh-grid-pinned-rows--top { box-shadow: 0 2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom { bottom: 0; box-shadow: 0 -2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom .mgh-grid-row { border-bottom: 0; border-top: 1px solid var(--mgh-grid-border); }\n\n/* ---- detail panel ---- */\n.mgh-grid-detail-panel { position: sticky; left: 0; overflow: auto; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); z-index: 1; }\n\n/* ---- overlays ---- */\n.mgh-grid-overlay { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; z-index: 5; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; pointer-events: none; }\n.mgh-grid-overlay--loading { background: var(--mgh-grid-overlay); pointer-events: auto; }\n.mgh-grid-no-rows { display: flex; align-items: center; justify-content: center; gap: 8px; height: 100%; text-align: center; padding: 16px; }\n.mgh-grid-no-rows img, .mgh-grid-no-rows .mgh-grid-icon { width: 50px; height: 50px; color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--mgh-grid-selected); border-top-color: var(--mgh-grid-primary); animation: mgh-grid-spin .8s linear infinite; }\n@keyframes mgh-grid-spin { to { transform: rotate(360deg); } }\n\n/* ---- footer ---- */\n.mgh-grid-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 0 8px 0 16px; border-top: 1px solid var(--mgh-grid-border); font-size: 0.875rem; color: var(--mgh-grid-fg-secondary); flex-wrap: wrap; }\n.mgh-grid-footer-left { display: flex; align-items: center; gap: 16px; }\n.mgh-grid-pagination { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }\n.mgh-grid-pagination-select { height: 32px; padding: 2px 24px 2px 8px; font-size: 0.875rem; border-color: transparent; }\n.mgh-grid-pagination-select:hover { border-color: transparent; background-color: var(--mgh-grid-hover); }\n.mgh-grid-pagination-actions { display: inline-flex; align-items: center; }\n\n/* ---- popover / menu / panels ---- */\n.mgh-grid-popover {\n --mgh-grid-font-family: inherit; --mgh-grid-font-size: 14px; --mgh-grid-paper: #ffffff; --mgh-grid-bg: #fff; --mgh-grid-fg: rgba(0,0,0,.87); --mgh-grid-fg-secondary: rgba(0,0,0,.6); --mgh-grid-fg-disabled: rgba(0,0,0,.38); --mgh-grid-border: rgba(224,224,224,1); --mgh-grid-hover: rgba(0,0,0,.04); --mgh-grid-selected: rgba(25,118,210,.08); --mgh-grid-primary: #1976d2; --mgh-grid-primary-contrast: #fff; --mgh-grid-focus: #1976d2; --mgh-grid-input-bg: transparent; --mgh-grid-input-border: rgba(0,0,0,.23); --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n position: fixed; z-index: 1300; background: var(--mgh-grid-paper); color: var(--mgh-grid-fg); border-radius: 8px; box-shadow: var(--mgh-grid-popover-shadow); font-family: var(--mgh-grid-font-family); font-size: var(--mgh-grid-font-size); line-height: 1.5; outline: none; max-height: calc(100vh - 16px); overflow: auto; animation: mgh-grid-pop .12s ease-out;\n}\n.mgh-grid-popover[data-mgh-theme=\"dark\"] { --mgh-grid-paper: #212b36; --mgh-grid-bg: #212b36; --mgh-grid-fg: #fff; --mgh-grid-fg-secondary: rgba(255,255,255,.7); --mgh-grid-fg-disabled: rgba(255,255,255,.5); --mgh-grid-border: rgba(81,81,81,1); --mgh-grid-hover: rgba(255,255,255,.08); --mgh-grid-selected: rgba(144,202,249,.16); --mgh-grid-primary: #90caf9; --mgh-grid-primary-contrast: rgba(0,0,0,.87); --mgh-grid-focus: #90caf9; --mgh-grid-input-border: rgba(255,255,255,.23); }\n@keyframes mgh-grid-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }\n.mgh-grid-menu { list-style: none; margin: 0; padding: 6px 0; min-width: 180px; }\n.mgh-grid-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 16px; min-height: 36px; font-size: 0.875rem; cursor: pointer; white-space: nowrap; color: var(--mgh-grid-fg); background: transparent; border: 0; width: 100%; text-align: left; font-family: inherit; outline: none; }\n.mgh-grid-menu-item:hover, .mgh-grid-menu-item:focus-visible { background: var(--mgh-grid-hover); }\n.mgh-grid-menu-item--disabled { color: var(--mgh-grid-fg-disabled); cursor: default; pointer-events: none; }\n.mgh-grid-menu-item--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-menu-item .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); flex: 0 0 auto; }\n.mgh-grid-menu-divider { height: 1px; margin: 6px 0; background: var(--mgh-grid-border); border: 0; }\n.mgh-grid-menu-header { padding: 6px 16px 2px; font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); text-transform: uppercase; letter-spacing: .04em; }\n.mgh-grid-menu-section { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 4px; }\n.mgh-grid-panel { display: flex; flex-direction: column; min-width: 300px; max-width: min(640px, calc(100vw - 16px)); }\n.mgh-grid-panel-header { padding: 12px 12px 4px; }\n.mgh-grid-panel-content { padding: 4px 12px; overflow: auto; max-height: 360px; }\n.mgh-grid-panel-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; }\n.mgh-grid-columns-list { display: flex; flex-direction: column; }\n.mgh-grid-filter-row { display: grid; grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); gap: 8px; align-items: end; margin-bottom: 8px; }\n.mgh-grid-filter-row--first { grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row--with-logic { grid-template-columns: 32px 80px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row .mgh-grid-btn--icon { margin-bottom: 4px; }\n.mgh-grid-filter-empty { padding: 8px 4px; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; }\n@media (max-width: 599.95px) { .mgh-grid-filter-row, .mgh-grid-filter-row--with-logic { grid-template-columns: 1fr; } }\n\n/* ---- misc ---- */\n.mgh-grid-tooltip-anchor { display: inline-flex; }\n.mgh-grid-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }\n@media print { .mgh-grid-toolbar, .mgh-grid-footer { display: none !important; } }\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_GRID_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_GRID_STYLE_ID;\n style.setAttribute('data-mgh-grid', 'true');\n style.textContent = MGH_GRID_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHGridStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridLocaleText,\n MGHGridState,\n MGHGridThemeMode,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\n\nexport interface MGHGridRootProps {\n header?: React.ReactNode;\n pagination: boolean;\n pageSizeOptions: number[];\n hideFooterPagination: boolean;\n hideFooterRowCount: boolean;\n hideFooterSelectedRowCount: boolean;\n disableColumnFilter: boolean;\n disableColumnSelector: boolean;\n disableDensitySelector: boolean;\n disableColumnPinning: boolean;\n disableColumnSorting: boolean;\n disableMultipleColumnsSorting: boolean;\n disableMultipleColumnsFiltering: boolean;\n disableRowGrouping: boolean;\n disableAggregation: boolean;\n checkboxSelection: boolean;\n aggregationFunctions: Record<string, MGHGridAggregationFunction>;\n quickFilterDebounceMs: number;\n}\n\nexport interface MGHGridContextValue {\n api: MGHGridApi;\n state: MGHGridState;\n localeText: MGHGridLocaleText;\n themeMode: MGHGridThemeMode;\n rootProps: MGHGridRootProps;\n /** All user columns (ordered, including hidden). */\n columns: MGHGridColDef[];\n /** Visible user columns. */\n visibleColumns: MGHGridColDef[];\n}\n\nexport const MGHGridContext = React.createContext<MGHGridContextValue | null>(null);\nMGHGridContext.displayName = 'MGHGridContext';\n\nexport const useMGHGridContext = () => {\n const ctx = React.useContext(MGHGridContext);\n if (!ctx) {\n throw new Error('MGHGrid: this component must be rendered inside an <MGHGrid /> (e.g. through a slot).');\n }\n return ctx;\n};\n\n/** Access the grid API from custom toolbars, menu items, cells, etc. */\nexport const useMGHGridApiContext = <R extends MGHGridValidRowModel = any>() => useMGHGridContext().api as MGHGridApi<R>;\n\nexport const useMGHGridLocaleText = () => useMGHGridContext().localeText;\n\n/** Creates a ref to hold the grid API; pass it to `<MGHGrid apiRef={apiRef} />`. */\nexport const useMGHGridApiRef = <R extends MGHGridValidRowModel = any>() =>\n React.useRef<MGHGridApi<R> | null>(null) as React.MutableRefObject<MGHGridApi<R> | null>;\n","import React from 'react';\n\n/** Keeps a ref always pointing at the latest value (assigned during render). */\nexport function useLatestRef<T>(value: T) {\n const ref = React.useRef(value);\n ref.current = value;\n return ref;\n}\n\n/** Returns a stable function that always calls the latest `fn`. */\nexport function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useLatestRef(fn);\n return React.useCallback(((...args: any[]) => ref.current(...args)) as T, []);\n}\n\n/**\n * Controlled / uncontrolled state helper. When `controlled` is defined the internal state is\n * ignored and every change is reported through `onChange` only.\n */\nexport function useControlledState<T>(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void\n): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : internal;\n const valueRef = useLatestRef(value);\n const controlledRef = useLatestRef(isControlled);\n const onChangeRef = useLatestRef(onChange);\n\n const setValue = React.useCallback((next: T | ((prev: T) => T)) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n if (Object.is(resolved, valueRef.current)) return;\n valueRef.current = resolved;\n if (!controlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [value, setValue];\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/** Observes the client size of an element. */\nexport function useElementSize<T extends HTMLElement>(ref: React.RefObject<T | null>, enabled = true): ElementSize {\n const [size, setSize] = React.useState<ElementSize>({ width: 0, height: 0 });\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !enabled) return undefined;\n const update = () => {\n const width = el.clientWidth;\n const height = el.clientHeight;\n setSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n };\n update();\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return size;\n}\n\n/** `window.matchMedia` as a hook. Always false on the server. */\nexport function useMediaQuery(query: string) {\n const getMatch = () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false;\n const [matches, setMatches] = React.useState(getMatch);\n\n React.useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return undefined;\n const media = window.matchMedia(query);\n const listener = () => setMatches(media.matches);\n listener();\n if (media.addEventListener) {\n media.addEventListener('change', listener);\n return () => media.removeEventListener('change', listener);\n }\n media.addListener(listener);\n return () => media.removeListener(listener);\n }, [query]);\n\n return matches;\n}\n\n/** Debounced version of a callback. The returned function is stable. */\nexport function useDebouncedCallback<T extends (...args: any[]) => void>(fn: T, delay: number) {\n const fnRef = useLatestRef(fn);\n const timerRef = React.useRef<number | null>(null);\n\n React.useEffect(\n () => () => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n },\n []\n );\n\n return React.useCallback(\n (...args: Parameters<T>) => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(() => {\n timerRef.current = null;\n fnRef.current(...args);\n }, delay);\n },\n [delay]\n );\n}\n\nexport function useForceUpdate() {\n const [, setTick] = React.useState(0);\n return React.useCallback(() => setTick((t) => t + 1), []);\n}\n\nlet idCounter = 0;\n/** Stable unique id per component instance (React.useId fallback for older Reacts). */\nexport function useStableId(prefix: string) {\n const reactUseId = (React as any).useId as undefined | (() => string);\n if (reactUseId) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const id = reactUseId();\n return `${prefix}-${id.replace(/:/g, '')}`;\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const ref = React.useRef<string | null>(null);\n if (ref.current === null) {\n idCounter += 1;\n ref.current = `${prefix}-${idCounter}`;\n }\n return ref.current;\n}\n","import {\n MGHGridApi,\n MGHGridColDef,\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridExportOptions,\n MGHGridPrintExportOptions,\n MGHGridRowId,\n} from './MGHGrid.types';\nimport {\n downloadBlob,\n formattedValueToString,\n getCellValue,\n getFormattedValue,\n isInternalField,\n isNil,\n toDate,\n} from './utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Shared: resolve the columns & rows to export\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ExportCell {\n raw: any;\n formatted: string;\n col: MGHGridColDef;\n}\n\nexport interface ExportTable {\n columns: MGHGridColDef[];\n headers: string[];\n rows: ExportCell[][];\n}\n\nexport const resolveExportColumns = (api: MGHGridApi, options: MGHGridExportOptions): MGHGridColDef[] => {\n const all = api.getAllColumns();\n let columns: MGHGridColDef[];\n if (options.fields) {\n const byField = new Map<string, MGHGridColDef>();\n all.forEach((c) => byField.set(c.field, c));\n columns = options.fields.map((f) => byField.get(f)).filter(Boolean) as MGHGridColDef[];\n } else if (options.allColumns) {\n columns = all;\n } else {\n columns = api.getVisibleColumns();\n }\n return columns.filter((c) => !c.disableExport && !isInternalField(c.field) && c.type !== 'actions');\n};\n\nexport const buildExportTable = (api: MGHGridApi, options: MGHGridExportOptions): ExportTable => {\n const columns = resolveExportColumns(api, options);\n const ids: MGHGridRowId[] = options.getRowsToExport ? options.getRowsToExport({ api }) : api.getSortedRowIds();\n const rows: ExportCell[][] = [];\n ids.forEach((id) => {\n const row = api.getRow(id);\n if (!row) return;\n rows.push(\n columns.map((col) => {\n const raw = getCellValue(row, col, api);\n const formatted = formattedValueToString(getFormattedValue(raw, row, col, api, id));\n return { raw, formatted, col };\n })\n );\n });\n return { columns, headers: columns.map((c) => c.headerName ?? c.field), rows };\n};\n\nconst sanitizeFileName = (name: string | undefined, fallback: string, extension: string) => {\n const base = (name && name.trim()) || fallback;\n return base.toLowerCase().endsWith(`.${extension}`) ? base : `${base}.${extension}`;\n};\n\nconst defaultFileBase = () => {\n const title = typeof document !== 'undefined' && document.title ? document.title.trim() : '';\n return (title || 'export').replace(/[\\\\/:*?\"<>|]+/g, '-');\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CSV\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeCsvCell = (value: string, delimiter: string) => {\n let text = value;\n // Guard against formula injection when opening in spreadsheet software.\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n if (text.indexOf('\"') !== -1 || text.indexOf(delimiter) !== -1 || /[\\r\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n }\n return text;\n};\n\nexport const getDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const delimiter = options.delimiter ?? ',';\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const lines: string[] = [];\n if (includeHeaders) {\n lines.push(table.headers.map((h) => escapeCsvCell(h, delimiter)).join(delimiter));\n }\n table.rows.forEach((cells) => {\n lines.push(\n cells\n .map((cell) => {\n const text = options.useRawValues ? (isNil(cell.raw) ? '' : String(cell.raw)) : cell.formatted;\n return escapeCsvCell(text, delimiter);\n })\n .join(delimiter)\n );\n });\n return lines.join('\\r\\n');\n};\n\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\nexport const exportDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const csv = getDataAsCsv(api, options);\n const bom = options.utf8WithBom ? UTF8_BOM : '';\n const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'csv'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * XLSX (minimal OOXML writer + store-only ZIP, no dependencies)\n * ----------------------------------------------------------------------------------------------- */\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n += 1) {\n let c = n;\n for (let k = 0; k < 8; k += 1) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nconst crc32 = (bytes: Uint8Array) => {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i += 1) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n};\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst encodeUtf8 = (text: string): Uint8Array => {\n if (textEncoder) return textEncoder.encode(text);\n // Fallback for very old environments.\n const utf8 = unescape(encodeURIComponent(text));\n const out = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i += 1) out[i] = utf8.charCodeAt(i);\n return out;\n};\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nconst concatBytes = (chunks: Uint8Array[]) => {\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n chunks.forEach((c) => {\n out.set(c, offset);\n offset += c.length;\n });\n return out;\n};\n\nconst zipStore = (entries: ZipEntry[]): Uint8Array => {\n const localChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n // 1980-01-01 00:00 in DOS date/time format.\n const dosTime = 0;\n const dosDate = (1 << 5) | 1;\n\n entries.forEach((entry) => {\n const nameBytes = encodeUtf8(entry.name);\n const crc = crc32(entry.data);\n const size = entry.data.length;\n\n const local = new Uint8Array(30 + nameBytes.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0x0800, true); // UTF-8 names\n lv.setUint16(8, 0, true); // store\n lv.setUint16(10, dosTime, true);\n lv.setUint16(12, dosDate, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, size, true);\n lv.setUint32(22, size, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0x0800, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, dosTime, true);\n cv.setUint16(14, dosDate, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, size, true);\n cv.setUint32(24, size, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, offset, true);\n central.set(nameBytes, 46);\n\n localChunks.push(local, entry.data);\n centralChunks.push(central);\n offset += local.length + size;\n });\n\n const centralDirectory = concatBytes(centralChunks);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDirectory.length, true);\n ev.setUint32(16, offset, true);\n ev.setUint16(20, 0, true);\n\n return concatBytes(localChunks.concat([centralDirectory, eocd]));\n};\n\n// Characters that are illegal in XML 1.0 (built without literal control characters in source).\nconst INVALID_XML_CHARS = new RegExp(\n '[' +\n String.fromCharCode(0x00) +\n '-' +\n String.fromCharCode(0x08) +\n String.fromCharCode(0x0b) +\n String.fromCharCode(0x0c) +\n String.fromCharCode(0x0e) +\n '-' +\n String.fromCharCode(0x1f) +\n String.fromCharCode(0xfffe) +\n String.fromCharCode(0xffff) +\n ']',\n 'g'\n);\nconst stripInvalidXml = (text: string) => text.replace(INVALID_XML_CHARS, '');\n\nconst escapeXml = (text: string) =>\n stripInvalidXml(text)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n\nconst columnLetter = (index: number) => {\n let n = index + 1;\n let letters = '';\n while (n > 0) {\n const rem = (n - 1) % 26;\n letters = String.fromCharCode(65 + rem) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return letters;\n};\n\nconst sanitizeSheetName = (name: string | undefined) => {\n const cleaned = (name || 'Sheet1').replace(/[\\[\\]:*?/\\\\]/g, ' ').trim() || 'Sheet1';\n return cleaned.length > 31 ? cleaned.slice(0, 31) : cleaned;\n};\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\nconst buildSheetXml = (table: ExportTable, includeHeaders: boolean, columnWidths: number[]) => {\n const rowsXml: string[] = [];\n let rowIndex = 1;\n\n const inlineString = (ref: string, text: string, style?: number) =>\n `<c r=\"${ref}\" t=\"inlineStr\"${style ? ` s=\"${style}\"` : ''}><is><t xml:space=\"preserve\">${escapeXml(\n text\n )}</t></is></c>`;\n\n if (includeHeaders) {\n const cells = table.headers.map((h, i) => inlineString(`${columnLetter(i)}${rowIndex}`, h, 1)).join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${cells}</row>`);\n rowIndex += 1;\n }\n\n table.rows.forEach((cells) => {\n const xmlCells = cells\n .map((cell, i) => {\n const ref = `${columnLetter(i)}${rowIndex}`;\n const type = cell.col.type;\n if (isNil(cell.raw) || cell.raw === '') return '';\n if (type === 'number' && typeof cell.raw === 'number' && Number.isFinite(cell.raw)) {\n return `<c r=\"${ref}\"><v>${cell.raw}</v></c>`;\n }\n if (type === 'boolean') {\n return `<c r=\"${ref}\" t=\"b\"><v>${cell.raw ? 1 : 0}</v></c>`;\n }\n if ((type === 'date' || type === 'dateTime') && toDate(cell.raw)) {\n // Excel serial date (days since 1899-12-30), written in local time with a date style.\n const d = toDate(cell.raw) as Date;\n const utc = Date.UTC(\n d.getFullYear(),\n d.getMonth(),\n d.getDate(),\n d.getHours(),\n d.getMinutes(),\n d.getSeconds()\n );\n const serial = utc / 86400000 + 25569;\n return `<c r=\"${ref}\" s=\"${type === 'dateTime' ? 3 : 2}\"><v>${serial}</v></c>`;\n }\n return inlineString(ref, cell.formatted);\n })\n .join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${xmlCells}</row>`);\n rowIndex += 1;\n });\n\n const lastCol = columnLetter(Math.max(table.columns.length - 1, 0));\n const lastRow = Math.max(rowIndex - 1, 1);\n const cols = columnWidths.map((w, i) => `<col min=\"${i + 1}\" max=\"${i + 1}\" width=\"${w}\" customWidth=\"1\"/>`).join('');\n\n return (\n XML_HEADER +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<dimension ref=\"A1:${lastCol}${lastRow}\"/>` +\n '<sheetViews><sheetView workbookViewId=\"0\">' +\n (includeHeaders ? '<pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/>' : '') +\n '</sheetView></sheetViews>' +\n '<sheetFormatPr defaultRowHeight=\"15\"/>' +\n (cols ? `<cols>${cols}</cols>` : '') +\n `<sheetData>${rowsXml.join('')}</sheetData>` +\n (includeHeaders && table.rows.length > 0 ? `<autoFilter ref=\"A1:${lastCol}${lastRow}\"/>` : '') +\n '</worksheet>'\n );\n};\n\nconst STYLES_XML =\n XML_HEADER +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"m/d/yyyy\"/><numFmt numFmtId=\"165\" formatCode=\"m/d/yyyy h:mm AM/PM\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '</cellXfs>' +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n '</styleSheet>';\n\nconst CONTENT_TYPES_XML =\n XML_HEADER +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n '</Types>';\n\nconst ROOT_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n '<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>' +\n '</Relationships>';\n\nconst WORKBOOK_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n '</Relationships>';\n\nconst buildWorkbookXml = (sheetName: string) =>\n XML_HEADER +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${escapeXml(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/></sheets>` +\n '</workbook>';\n\nconst buildCoreXml = () => {\n const now = new Date().toISOString();\n return (\n XML_HEADER +\n '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" ' +\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" ' +\n 'xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n '<dc:creator>MGH Grid</dc:creator>' +\n `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n '</cp:coreProperties>'\n );\n};\n\nconst APP_XML =\n XML_HEADER +\n '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" ' +\n 'xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n '<Application>MGH Grid</Application></Properties>';\n\nexport const buildXlsx = (api: MGHGridApi, options: MGHGridExcelExportOptions = {}): Uint8Array => {\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const widths = table.columns.map((col, i) => {\n const explicit = options.columnsStyles?.[col.field]?.width;\n if (explicit) return explicit;\n let max = table.headers[i].length;\n for (let r = 0; r < Math.min(table.rows.length, 500); r += 1) {\n const len = table.rows[r][i].formatted.length;\n if (len > max) max = len;\n }\n return Math.min(Math.max(max + 2, 8), 60);\n });\n const sheetName = sanitizeSheetName(options.sheetName);\n const entries: ZipEntry[] = [\n { name: '[Content_Types].xml', data: encodeUtf8(CONTENT_TYPES_XML) },\n { name: '_rels/.rels', data: encodeUtf8(ROOT_RELS_XML) },\n { name: 'docProps/core.xml', data: encodeUtf8(buildCoreXml()) },\n { name: 'docProps/app.xml', data: encodeUtf8(APP_XML) },\n { name: 'xl/workbook.xml', data: encodeUtf8(buildWorkbookXml(sheetName)) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(WORKBOOK_RELS_XML) },\n { name: 'xl/styles.xml', data: encodeUtf8(STYLES_XML) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(buildSheetXml(table, includeHeaders, widths)) },\n ];\n return zipStore(entries);\n};\n\nexport const exportDataAsExcel = async (api: MGHGridApi, options: MGHGridExcelExportOptions = {}) => {\n const bytes = buildXlsx(api, options);\n const blob = new Blob([bytes as BlobPart], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'xlsx'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Print\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Legacy value-based print (plain HTML table). The grid's `exportDataAsPrint` prints the live DOM instead. */\nexport const exportDataAsPrintTable = (api: MGHGridApi, options: MGHGridPrintExportOptions = {}) => {\n if (typeof document === 'undefined') return;\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const title = options.title ?? options.fileName ?? document.title ?? '';\n\n const headerHtml = includeHeaders\n ? `<thead><tr>${table.headers\n .map((h, i) => `<th class=\"${table.columns[i].align ?? 'left'}\">${escapeHtml(h)}</th>`)\n .join('')}</tr></thead>`\n : '';\n const bodyHtml = `<tbody>${table.rows\n .map(\n (cells) =>\n `<tr>${cells\n .map((cell) => `<td class=\"${cell.col.align ?? 'left'}\">${escapeHtml(cell.formatted)}</td>`)\n .join('')}</tr>`\n )\n .join('')}</tbody>`;\n\n const html =\n '<!doctype html><html><head><meta charset=\"utf-8\" />' +\n `<title>${escapeHtml(title)}</title>` +\n '<style>' +\n 'body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-size:12px;color:#111;margin:16px;}' +\n 'h1{font-size:16px;margin:0 0 12px;}' +\n 'table{border-collapse:collapse;width:100%;}' +\n 'th,td{border:1px solid #ccc;padding:4px 8px;text-align:left;vertical-align:top;}' +\n 'th{background:#f3f3f3;font-weight:600;}' +\n 'td.right,th.right{text-align:right;} td.center,th.center{text-align:center;}' +\n 'tr{page-break-inside:avoid;} thead{display:table-header-group;}' +\n (options.pageStyle ?? '') +\n '</style></head><body>' +\n (title ? `<h1>${escapeHtml(title)}</h1>` : '') +\n `<table>${headerHtml}${bodyHtml}</table>` +\n '</body></html>';\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = '0';\n iframe.style.opacity = '0';\n document.body.appendChild(iframe);\n\n const cleanup = () => {\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 1000);\n };\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (!win) {\n cleanup();\n return;\n }\n try {\n win.focus();\n win.onafterprint = cleanup;\n win.print();\n } catch {\n cleanup();\n }\n };\n\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\n if (doc) {\n doc.open();\n doc.write(html);\n doc.close();\n } else {\n iframe.srcdoc = html;\n }\n};\n","import { MGHGridPrintExportOptions } from './MGHGrid.types';\n\n/**\n * Prints the grid \"as seen on screen\": the live DOM of the grid card is cloned into a hidden iframe\n * together with the page's stylesheets, so anything rendered by `renderCell` (images, chips,\n * links, custom components) prints exactly as displayed. The grid itself must already be rendered\n * in print mode (all rows, no virtualization) when this is called.\n */\n\nconst PRINT_CSS = `\n@page { margin: 10mm; }\nhtml, body { margin: 0; padding: 0; background: #fff; }\n.mgh-grid-print-title { margin: 0 0 12px; font: 600 16px/1.4 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; }\n.mgh-grid-card { box-shadow: none !important; border-radius: 0 !important; height: auto !important; max-height: none !important; overflow: visible !important; background: transparent !important; }\n.mgh-grid-box { height: auto !important; max-height: none !important; flex: none !important; }\n.mgh-grid { height: auto !important; max-height: none !important; border-radius: 0 !important; }\n.mgh-grid-main, .mgh-grid-scroller { overflow: visible !important; height: auto !important; max-height: none !important; }\n.mgh-grid-columns, .mgh-grid-pinned-rows, .mgh-grid-detail-panel { position: static !important; box-shadow: none !important; }\n.mgh-grid-header-cell, .mgh-grid-cell { position: static !important; box-shadow: none !important; background-image: none !important; }\n.mgh-grid-detail-panel { width: auto !important; }\n.mgh-grid-body { min-height: 0 !important; }\n.mgh-grid-row, .mgh-grid-row-block, .mgh-grid-detail-panel { break-inside: avoid; page-break-inside: avoid; }\n.mgh-grid-columns { break-after: avoid; page-break-after: avoid; }\n.mgh-grid-header-menu-btn, .mgh-grid-resize-handle, .mgh-grid-overlay, .mgh-grid-sort-icon:not(.mgh-grid-sort-icon--active) { display: none !important; }\n.mgh-grid-popover { display: none !important; }\n`;\n\nconst collectStyles = (doc: Document) => {\n const styles: string[] = [];\n const links: string[] = [];\n Array.from(doc.styleSheets).forEach((sheet) => {\n try {\n const rules = Array.from(sheet.cssRules)\n .map((rule) => rule.cssText)\n .join('\\n');\n if (rules) styles.push(rules);\n } catch {\n // Cross-origin stylesheet: reference it instead of inlining.\n if (sheet.href) links.push(sheet.href);\n }\n });\n return { styles, links };\n};\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Copies live form-control state (cloneNode does not copy `checked` / `value`). */\nconst syncFormState = (source: HTMLElement, target: HTMLElement) => {\n const sourceInputs = Array.from(source.querySelectorAll('input, select, textarea'));\n const targetInputs = Array.from(target.querySelectorAll('input, select, textarea'));\n sourceInputs.forEach((el, i) => {\n const t = targetInputs[i];\n if (!t || t.tagName !== el.tagName) return;\n // Tag-name checks instead of `instanceof`: the elements may belong to different documents.\n if (el.tagName === 'INPUT') {\n const src = el as HTMLInputElement;\n const dst = t as HTMLInputElement;\n if (src.type === 'checkbox' || src.type === 'radio') {\n dst.checked = src.checked;\n if (src.checked) dst.setAttribute('checked', '');\n dst.indeterminate = src.indeterminate;\n } else {\n dst.value = src.value;\n dst.setAttribute('value', src.value);\n }\n } else if (el.tagName === 'SELECT') {\n (t as HTMLSelectElement).value = (el as HTMLSelectElement).value;\n } else if (el.tagName === 'TEXTAREA') {\n (t as HTMLTextAreaElement).value = (el as HTMLTextAreaElement).value;\n t.textContent = (el as HTMLTextAreaElement).value;\n }\n });\n // Canvases lose their bitmap when cloned: replace them with images.\n const sourceCanvases = Array.from(source.querySelectorAll('canvas'));\n const targetCanvases = Array.from(target.querySelectorAll('canvas'));\n sourceCanvases.forEach((canvas, i) => {\n const t = targetCanvases[i];\n if (!t) return;\n try {\n const img = t.ownerDocument.createElement('img');\n img.src = canvas.toDataURL();\n img.width = canvas.width;\n img.height = canvas.height;\n img.style.cssText = t.style.cssText;\n t.replaceWith(img);\n } catch {\n /* tainted canvas – leave as is */\n }\n });\n};\n\nconst waitForImages = (doc: Document, timeoutMs: number) =>\n new Promise<void>((resolve) => {\n const images = Array.from(doc.images).filter((img) => !img.complete);\n if (images.length === 0) {\n resolve();\n return;\n }\n let remaining = images.length;\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n resolve();\n };\n const timer = window.setTimeout(finish, timeoutMs);\n images.forEach((img) => {\n const onSettled = () => {\n remaining -= 1;\n if (remaining <= 0) {\n window.clearTimeout(timer);\n finish();\n }\n };\n img.addEventListener('load', onSettled, { once: true });\n img.addEventListener('error', onSettled, { once: true });\n });\n });\n\nexport interface PrintGridParams {\n /** The `.mgh-grid-card` element (already rendered in print mode). */\n cardElement: HTMLElement;\n options: MGHGridPrintExportOptions;\n /** Called once the print dialog has been handed off (or failed) so the grid can leave print mode. */\n onDone: () => void;\n}\n\nexport const printGridElement = (params: PrintGridParams) => {\n let done = false;\n const onDone = () => {\n if (done) return;\n done = true;\n params.onDone();\n };\n try {\n printGridElementUnsafe({ ...params, onDone });\n } catch (error) {\n console.error('MGHGrid: print failed', error);\n onDone();\n }\n};\n\nconst printGridElementUnsafe = ({ cardElement, options, onDone }: PrintGridParams) => {\n if (typeof document === 'undefined') {\n onDone();\n return;\n }\n const hideToolbar = options.hideToolbar ?? true;\n const hideFooter = options.hideFooter ?? false;\n const includeHeaders = options.includeHeaders ?? true;\n const copyStyles = options.copyStyles ?? true;\n\n const clone = cardElement.cloneNode(true) as HTMLElement;\n syncFormState(cardElement, clone);\n clone.querySelectorAll('.mgh-grid-card-header').forEach((el) => el.remove());\n if (hideToolbar) clone.querySelectorAll('.mgh-grid-toolbar').forEach((el) => el.remove());\n if (hideFooter) clone.querySelectorAll('.mgh-grid-footer').forEach((el) => el.remove());\n if (!includeHeaders) clone.querySelectorAll('.mgh-grid-columns').forEach((el) => el.remove());\n clone.classList.add('mgh-grid-card--plain');\n // Remove ids to avoid duplicates and drop inline sizing coming from cardStyle/boxStyle.\n clone.querySelectorAll('[id]').forEach((el) => el.removeAttribute('id'));\n clone.style.height = 'auto';\n clone.style.flexGrow = '0';\n\n const title = options.title ?? '';\n const { styles, links } = copyStyles ? collectStyles(document) : { styles: [], links: [] };\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.setAttribute('data-mgh-grid-print', 'true');\n iframe.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:0;opacity:0;pointer-events:none;';\n document.body.appendChild(iframe);\n\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 500);\n onDone();\n };\n\n const win = iframe.contentWindow;\n const doc = iframe.contentDocument || win?.document;\n if (!win || !doc) {\n finish();\n return;\n }\n\n doc.open();\n doc.write(\n `<!doctype html><html><head><meta charset=\"utf-8\" /><title>${escapeHtml(title || document.title || 'Print')}</title>` +\n links.map((href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`).join('') +\n `</head><body></body></html>`\n );\n doc.close();\n\n styles.forEach((css) => {\n const style = doc.createElement('style');\n style.textContent = css;\n doc.head.appendChild(style);\n });\n const printStyle = doc.createElement('style');\n printStyle.textContent = PRINT_CSS + (options.pageStyle ?? '');\n doc.head.appendChild(printStyle);\n\n if (title) {\n const h1 = doc.createElement('h1');\n h1.className = 'mgh-grid-print-title';\n h1.textContent = title;\n doc.body.appendChild(h1);\n }\n doc.body.appendChild(doc.adoptNode(clone));\n\n const run = async () => {\n try {\n await waitForImages(doc, 4000);\n if (options.onBeforePrint) await options.onBeforePrint(doc);\n win.onafterprint = finish;\n win.focus();\n win.print();\n // Most browsers block on print(); if afterprint never fires, still restore the grid.\n window.setTimeout(finish, 1000);\n } catch {\n finish();\n }\n };\n void run();\n};\n","import {\n MGHGridAggregationFunction,\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridColDef,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridRowId,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport { formattedValueToString, getCellValue, getFormattedValue, getGroupingValue, isNil } from './utils';\n\nexport interface RowEntry<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n row: R;\n}\n\n/** Internal tree node used while grouping. */\nexport interface GroupTreeNode<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n depth: number;\n parent: MGHGridRowId | null;\n groupingField: string;\n groupingKey: any;\n groupingLabel: string;\n childGroups: GroupTreeNode<R>[];\n /** Direct leaf children (only populated at the deepest level). */\n leaves: RowEntry<R>[];\n /** Every descendant leaf, in display order after sorting. */\n descendants: RowEntry<R>[];\n}\n\nexport interface DisplayRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n type: 'leaf' | 'group';\n row: R | null;\n node: MGHGridLeafNode | MGHGridGroupNode;\n depth: number;\n group?: GroupTreeNode<R>;\n}\n\nexport const GROUP_ID_PREFIX = 'auto-generated-row-';\n\nconst keyToString = (key: any) => (isNil(key) ? '' : key instanceof Date ? String(key.getTime()) : String(key));\n\nexport const buildGroupTree = <R extends MGHGridValidRowModel>(\n entries: RowEntry<R>[],\n groupingFields: string[],\n columnsByField: Map<string, MGHGridColDef<R>>,\n api: MGHGridApi<R>,\n emptyLabel = '(empty)'\n): GroupTreeNode<R>[] => {\n const build = (items: RowEntry<R>[], depth: number, parentId: MGHGridRowId | null, path: string): GroupTreeNode<R>[] => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return [];\n const buckets = new Map<string, GroupTreeNode<R>>();\n items.forEach((entry) => {\n const key = getGroupingValue(entry.row, col, api);\n const keyStr = keyToString(key);\n let node = buckets.get(keyStr);\n if (!node) {\n const label = formattedValueToString(getFormattedValue(key, entry.row, col, api, entry.id)) || emptyLabel;\n const id = `${GROUP_ID_PREFIX}${path}${field}/${keyStr}`;\n node = {\n id,\n depth,\n parent: parentId,\n groupingField: field,\n groupingKey: key,\n groupingLabel: label,\n childGroups: [],\n leaves: [],\n descendants: [],\n };\n buckets.set(keyStr, node);\n }\n node.leaves.push(entry);\n });\n const nodes: GroupTreeNode<R>[] = [];\n buckets.forEach((node) => {\n if (depth < groupingFields.length - 1) {\n node.childGroups = build(\n node.leaves,\n depth + 1,\n node.id,\n `${path}${field}/${keyToString(node.groupingKey)}|`\n );\n node.descendants = node.leaves;\n node.leaves = [];\n } else {\n node.descendants = node.leaves;\n }\n nodes.push(node);\n });\n return nodes;\n };\n return build(entries, 0, null, '');\n};\n\nexport type GroupComparator<R extends MGHGridValidRowModel = any> = (a: GroupTreeNode<R>, b: GroupTreeNode<R>) => number;\n\n/** Sorts groups (with the given comparator) and leaves (with the given sorter), recursively. */\nexport const sortGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n compareGroups: ((depth: number) => GroupComparator<R> | null) | null,\n sortLeaves: (leaves: RowEntry<R>[]) => RowEntry<R>[]\n): GroupTreeNode<R>[] => {\n const sortLevel = (nodes: GroupTreeNode<R>[], depth: number): GroupTreeNode<R>[] => {\n const comparator = compareGroups ? compareGroups(depth) : null;\n const sorted = comparator\n ? nodes\n .map((node, index) => ({ node, index }))\n .sort((a, b) => comparator(a.node, b.node) || a.index - b.index)\n .map((item) => item.node)\n : nodes;\n sorted.forEach((node) => {\n if (node.childGroups.length > 0) {\n node.childGroups = sortLevel(node.childGroups, depth + 1);\n const descendants: RowEntry<R>[] = [];\n node.childGroups.forEach((child) => child.descendants.forEach((d) => descendants.push(d)));\n node.descendants = descendants;\n } else {\n node.leaves = sortLeaves(node.leaves);\n node.descendants = node.leaves;\n }\n });\n return sorted;\n };\n return sortLevel(roots, 0);\n};\n\nexport const collectTreeLeaves = <R extends MGHGridValidRowModel>(roots: GroupTreeNode<R>[]): RowEntry<R>[] => {\n const out: RowEntry<R>[] = [];\n roots.forEach((root) => root.descendants.forEach((d) => out.push(d)));\n return out;\n};\n\nexport const toGroupNode = <R extends MGHGridValidRowModel>(\n node: GroupTreeNode<R>,\n isExpanded: boolean\n): MGHGridGroupNode => ({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: node.childGroups.length > 0 ? node.childGroups.map((c) => c.id) : node.leaves.map((l) => l.id),\n leafIds: node.descendants.map((d) => d.id),\n isExpanded,\n});\n\n/** Flattens the tree into display rows, honouring expansion state. Also fills `nodesById` with every node. */\nexport const flattenGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n isExpanded: (node: GroupTreeNode<R>) => boolean,\n nodesById: Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>,\n groupsById: Map<MGHGridRowId, GroupTreeNode<R>>\n): DisplayRow<R>[] => {\n const out: DisplayRow<R>[] = [];\n const visit = (nodes: GroupTreeNode<R>[], visible: boolean) => {\n nodes.forEach((node) => {\n const expanded = isExpanded(node);\n const groupNode = toGroupNode(node, expanded);\n nodesById.set(node.id, groupNode);\n groupsById.set(node.id, node);\n if (visible)\n out.push({ id: node.id, type: 'group', row: null, node: groupNode, depth: node.depth, group: node });\n const childVisible = visible && expanded;\n if (node.childGroups.length > 0) {\n visit(node.childGroups, childVisible);\n } else {\n node.leaves.forEach((leaf) => {\n const leafNode: MGHGridLeafNode = { type: 'leaf', id: leaf.id, depth: node.depth + 1, parent: node.id };\n nodesById.set(leaf.id, leafNode);\n if (childVisible)\n out.push({ id: leaf.id, type: 'leaf', row: leaf.row, node: leafNode, depth: node.depth + 1 });\n });\n }\n });\n };\n visit(roots, true);\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const aggregateRows = <R extends MGHGridValidRowModel>(\n rows: R[],\n aggregationModel: MGHGridAggregationModel,\n columnsByField: Map<string, MGHGridColDef<R>>,\n functions: Record<string, MGHGridAggregationFunction>,\n api: MGHGridApi<R>\n): Record<string, { value: any; fn: string }> => {\n const result: Record<string, { value: any; fn: string }> = {};\n Object.keys(aggregationModel).forEach((field) => {\n const fnName = aggregationModel[field];\n const fn = functions[fnName];\n const col = columnsByField.get(field);\n if (!fn || !col || col.aggregable === false) return;\n const values = rows.map((row) => getCellValue(row, col, api));\n result[field] = { value: fn.apply({ values, field }), fn: fnName };\n });\n return result;\n};\n","import React from 'react';\n\n/* Small inline SVG icon set (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHGridIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHGridIconProps>(({ size = 20, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-grid-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const ViewColumnIcon = createIcon(\n <path d=\"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z\" />,\n 'ViewColumnIcon'\n);\nexport const FilterListIcon = createIcon(<path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" />, 'FilterListIcon');\nexport const SearchIcon = createIcon(\n <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />,\n 'SearchIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\nexport const DownloadIcon = createIcon(\n <path d=\"M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67 2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z\" />,\n 'DownloadIcon'\n);\nexport const ArrowUpwardIcon = createIcon(\n <path d=\"m4 12 1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />,\n 'ArrowUpwardIcon'\n);\nexport const ArrowDownwardIcon = createIcon(\n <path d=\"m20 12-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" />,\n 'ArrowDownwardIcon'\n);\nexport const MoreVertIcon = createIcon(\n <path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'MoreVertIcon'\n);\nexport const CheckIcon = createIcon(<path d=\"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />, 'CheckIcon');\nexport const ExpandMoreIcon = createIcon(<path d=\"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z\" />, 'ExpandMoreIcon');\nexport const ChevronRightIcon = createIcon(<path d=\"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />, 'ChevronRightIcon');\nexport const ChevronLeftIcon = createIcon(<path d=\"M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />, 'ChevronLeftIcon');\nexport const FirstPageIcon = createIcon(\n <path d=\"M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z\" />,\n 'FirstPageIcon'\n);\nexport const LastPageIcon = createIcon(\n <path d=\"M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z\" />,\n 'LastPageIcon'\n);\nexport const PushPinIcon = createIcon(\n <path d=\"M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z\" />,\n 'PushPinIcon'\n);\nexport const DeleteIcon = createIcon(\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />,\n 'DeleteIcon'\n);\nexport const AddIcon = createIcon(<path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />, 'AddIcon');\nexport const DensitySmallIcon = createIcon(\n <path d=\"M3 2h18v2H3zm0 18h18v2H3zm0-6h18v2H3zm0-6h18v2H3z\" />,\n 'DensitySmallIcon'\n);\nexport const DensityMediumIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3zm0-8h18v2H3z\" />, 'DensityMediumIcon');\nexport const DensityLargeIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3z\" />, 'DensityLargeIcon');\nexport const DragIndicatorIcon = createIcon(\n <path d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'DragIndicatorIcon'\n);\nexport const PrintIcon = createIcon(\n <path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" />,\n 'PrintIcon'\n);\nexport const TableChartIcon = createIcon(\n <path d=\"M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z\" />,\n 'TableChartIcon'\n);\nexport const DescriptionIcon = createIcon(\n <path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" />,\n 'DescriptionIcon'\n);\nexport const VisibilityOffIcon = createIcon(\n <path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" />,\n 'VisibilityOffIcon'\n);\nexport const FunctionsIcon = createIcon(<path d=\"M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z\" />, 'FunctionsIcon');\nexport const WorkspacesIcon = createIcon(\n <path d=\"M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z\" />,\n 'WorkspacesIcon'\n);\nexport const EmptyBoxIcon = createIcon(\n <>\n <path\n d=\"M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2z\"\n opacity=\".25\"\n />\n <path d=\"M4 8h16v11H4z\" opacity=\".15\" />\n </>,\n 'EmptyBoxIcon'\n);\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { clamp, cx } from '../utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Button / IconButton\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'text' | 'primary' | 'contained';\n size?: 'small' | 'medium';\n startIcon?: React.ReactNode;\n endIcon?: React.ReactNode;\n active?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = 'text', size = 'medium', startIcon, endIcon, active, className, children, type = 'button', ...rest },\n ref\n ) => (\n <button\n ref={ref}\n type={type}\n className={cx(\n 'mgh-grid-btn',\n variant === 'primary' && 'mgh-grid-btn--primary',\n variant === 'contained' && 'mgh-grid-btn--contained',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {startIcon}\n {children}\n {endIcon}\n </button>\n )\n);\nButton.displayName = 'MGHGridButton';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n size?: 'small' | 'medium';\n active?: boolean;\n /** Tooltip (native title) and aria-label. */\n label?: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ size = 'medium', active, label, className, children, type = 'button', ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n title={label}\n aria-label={label}\n className={cx(\n 'mgh-grid-btn mgh-grid-btn--icon',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n )\n);\nIconButton.displayName = 'MGHGridIconButton';\n\n/* -------------------------------------------------------------------------------------------------\n * Badge\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface BadgeProps {\n count?: number;\n variant?: 'dot' | 'count';\n children: React.ReactNode;\n}\n\nexport const Badge = ({ count = 0, variant = 'dot', children }: BadgeProps) => (\n <span className=\"mgh-grid-badge\">\n {children}\n {count > 0 &&\n (variant === 'dot' ? (\n <span className=\"mgh-grid-badge-dot\" />\n ) : (\n <span className=\"mgh-grid-badge-count\">{count > 99 ? '99+' : count}</span>\n ))}\n </span>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Inputs\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(\n ({ size = 'medium', className, ...rest }, ref) => (\n <input\n ref={ref}\n className={cx('mgh-grid-input', size === 'small' && 'mgh-grid-input--small', className)}\n {...rest}\n />\n )\n);\nTextInput.displayName = 'MGHGridTextInput';\n\nexport interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ size = 'medium', className, ...rest }, ref) => (\n <select ref={ref} className={cx('mgh-grid-select', size === 'small' && 'mgh-grid-select--small', className)} {...rest} />\n));\nSelect.displayName = 'MGHGridSelect';\n\nexport interface FieldProps {\n label?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n htmlFor?: string;\n}\n\nexport const Field = ({ label, children, className, htmlFor }: FieldProps) => (\n <div className={cx('mgh-grid-field', className)}>\n {label && (\n <label className=\"mgh-grid-field-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n </div>\n);\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n indeterminate?: boolean;\n label?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ indeterminate = false, label, className, ...rest }, forwardedRef) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const setRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [forwardedRef]\n );\n React.useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n return (\n <input\n ref={setRef}\n type=\"checkbox\"\n title={label}\n aria-label={label}\n className={cx('mgh-grid-checkbox', className)}\n {...rest}\n />\n );\n }\n);\nCheckbox.displayName = 'MGHGridCheckbox';\n\n/* -------------------------------------------------------------------------------------------------\n * Spinner\n * ----------------------------------------------------------------------------------------------- */\n\nexport const Spinner = ({ className }: { className?: string }) => (\n <div className={cx('mgh-grid-spinner', className)} role=\"progressbar\" aria-label=\"Loading\" />\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover (portal, anchored)\n * ----------------------------------------------------------------------------------------------- */\n\nexport type PopoverPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'right-start';\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null | undefined;\n onClose: (reason: 'backdrop' | 'escape') => void;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n themeMode?: MGHGridThemeMode;\n className?: string;\n style?: React.CSSProperties;\n offset?: number;\n role?: string;\n autoFocus?: boolean;\n /** Additional elements considered \"inside\" for outside-click detection. */\n ignoreOutsideClickOn?: Array<React.RefObject<HTMLElement | null>>;\n}\n\nexport function Popover({\n open,\n anchorEl,\n onClose,\n children,\n placement = 'bottom-start',\n themeMode = 'light',\n className,\n style,\n offset = 4,\n role = 'dialog',\n autoFocus = false,\n ignoreOutsideClickOn,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState<{ top: number; left: number; ready: boolean }>({\n top: 0,\n left: 0,\n ready: false,\n });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n if (placement === 'right-start') {\n top = a.top;\n left = a.right + offset;\n if (left + w > vw - 8) left = a.left - offset - w;\n } else {\n top = a.bottom + offset;\n if (top + h > vh - 8 && a.top - offset - h >= 8) top = a.top - offset - h;\n left =\n placement === 'bottom-end'\n ? a.right - w\n : placement === 'bottom'\n ? a.left + a.width / 2 - w / 2\n : a.left;\n }\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement, offset]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n if (ignoreOutsideClickOn?.some((r) => r.current?.contains(target))) return;\n // Clicks inside other popovers (nested menus) should not close this one.\n if ((target as HTMLElement).closest?.('.mgh-grid-popover')) return;\n onClose('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onClose, anchorEl, ignoreOutsideClickOn]);\n\n React.useEffect(() => {\n if (open && autoFocus && ref.current) {\n const focusable = ref.current.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])'\n );\n (focusable ?? ref.current).focus();\n }\n }, [open, autoFocus]);\n\n if (!open || typeof document === 'undefined') return null;\n\n const stop = (event: React.SyntheticEvent) => event.stopPropagation();\n\n return createPortal(\n <div\n ref={ref}\n role={role}\n tabIndex={-1}\n className={cx('mgh-grid-popover', className)}\n data-mgh-theme={themeMode}\n style={{\n top: position.top,\n left: position.left,\n visibility: position.ready ? 'visible' : 'hidden',\n ...style,\n }}\n onClick={stop}\n onDoubleClick={stop}\n onMouseDown={stop}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onClose('escape');\n return;\n }\n event.stopPropagation();\n }}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {\n children: React.ReactNode;\n}\n\nexport const Menu = ({ children, className, onKeyDown, ...rest }: MenuProps) => {\n const ref = React.useRef<HTMLUListElement | null>(null);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Home' && event.key !== 'End') return;\n const items = Array.from(\n ref.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])') ?? []\n );\n if (items.length === 0) return;\n event.preventDefault();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n let next = 0;\n if (event.key === 'ArrowDown') next = currentIndex < 0 ? 0 : (currentIndex + 1) % items.length;\n else if (event.key === 'ArrowUp')\n next = currentIndex < 0 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;\n else if (event.key === 'Home') next = 0;\n else next = items.length - 1;\n items[next].focus();\n };\n\n React.useEffect(() => {\n const first = ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])');\n first?.focus();\n }, []);\n\n return (\n <ul ref={ref} role=\"menu\" className={cx('mgh-grid-menu', className)} onKeyDown={handleKeyDown} {...rest}>\n {children}\n </ul>\n );\n};\n\nexport interface MenuItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n icon?: React.ReactNode;\n selected?: boolean;\n /** Injected by menus that should close after the click. */\n hideMenu?: () => void;\n}\n\nexport const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ icon, selected, disabled, className, children, onClick, hideMenu, ...rest }, ref) => (\n <li role=\"none\">\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n disabled={disabled}\n tabIndex={-1}\n className={cx(\n 'mgh-grid-menu-item',\n disabled && 'mgh-grid-menu-item--disabled',\n selected && 'mgh-grid-menu-item--selected',\n className\n )}\n onClick={(event) => {\n if (disabled) return;\n onClick?.(event);\n hideMenu?.();\n }}\n {...rest}\n >\n {icon}\n <span>{children}</span>\n </button>\n </li>\n )\n);\nMenuItem.displayName = 'MGHGridMenuItem';\n\nexport const MenuDivider = () => <li role=\"separator\" className=\"mgh-grid-menu-divider\" />;\n\nexport const MenuHeader = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-header\">\n {children}\n </li>\n);\n\nexport const MenuSection = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-section\">\n {children}\n </li>\n);\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport {\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridPrintExportOptions,\n MGHGridToolbarProps,\n} from '../MGHGrid.types';\nimport {\n CloseIcon,\n DensityLargeIcon,\n DensityMediumIcon,\n DensitySmallIcon,\n DescriptionIcon,\n DownloadIcon,\n FilterListIcon,\n PrintIcon,\n SearchIcon,\n TableChartIcon,\n ViewColumnIcon,\n} from '../icons';\nimport { cx } from '../utils';\nimport { Badge, IconButton, Menu, MenuItem, MenuItemProps, Popover, TextInput } from './primitives';\n\n/* -------------------------------------------------------------------------------------------------\n * Buttons\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridColumnsButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'columns';\n return (\n <IconButton\n label={localeText.toolbarColumns}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('columns', event.currentTarget))}\n >\n <ViewColumnIcon />\n </IconButton>\n );\n}\n\nexport function MGHGridFiltersButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'filters';\n return (\n <IconButton\n label={localeText.toolbarFilters}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('filters', event.currentTarget))}\n >\n <Badge count={state.filterCount} variant=\"dot\">\n <FilterListIcon />\n </Badge>\n </IconButton>\n );\n}\n\nexport function MGHGridDensitySelector() {\n const { api, state, localeText, themeMode } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const options = [\n { value: 'compact', label: localeText.densityCompact, icon: <DensitySmallIcon /> },\n { value: 'standard', label: localeText.densityStandard, icon: <DensityMediumIcon /> },\n { value: 'comfortable', label: localeText.densityComfortable, icon: <DensityLargeIcon /> },\n ] as const;\n const current = options.find((o) => o.value === state.density) ?? options[1];\n return (\n <>\n <IconButton\n label={localeText.toolbarDensity}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n {current.icon}\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n role=\"menu\"\n >\n <Menu>\n {options.map((option) => (\n <MenuItem\n key={option.value}\n icon={option.icon}\n selected={option.value === state.density}\n onClick={() => api.setDensity(option.value)}\n hideMenu={() => setAnchor(null)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Export menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridExportMenuItemProps extends MenuItemProps {\n /** Injected by MGHGridExportMenu; call it to close the menu after your action. */\n hideMenu?: () => void;\n}\n\n/** Menu item for custom export actions. Drop-in for MUI's GridExportMenuItemProps pattern. */\nexport const MGHGridExportMenuItem = MenuItem as React.ForwardRefExoticComponent<\n MGHGridExportMenuItemProps & React.RefAttributes<HTMLButtonElement>\n>;\n\nexport interface MGHGridExportMenuProps {\n csvOptions?: MGHGridCsvExportOptions;\n excelOptions?: MGHGridExcelExportOptions;\n printOptions?: MGHGridPrintExportOptions;\n showCsvOption?: boolean;\n showExcelOption?: boolean;\n showPrintOption?: boolean;\n customMenuItem?: React.ReactNode;\n}\n\nexport function MGHGridExportMenu({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n customMenuItem,\n}: MGHGridExportMenuProps) {\n const { api, localeText, themeMode, rootProps } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const hideMenu = () => setAnchor(null);\n\n const customItems = React.Children.map(customMenuItem, (child) =>\n React.isValidElement(child) ? React.cloneElement(child as React.ReactElement<any>, { hideMenu }) : child\n );\n\n const resolvedPrintOptions: MGHGridPrintExportOptions = {\n title: typeof rootProps.header === 'string' ? rootProps.header : undefined,\n ...printOptions,\n };\n\n return (\n <>\n <IconButton\n label={localeText.toolbarExport}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n <DownloadIcon />\n </IconButton>\n <Popover open={Boolean(anchor)} anchorEl={anchor} onClose={hideMenu} themeMode={themeMode} role=\"menu\">\n <Menu>\n {customItems}\n {showCsvOption && (\n <MenuItem\n icon={<DescriptionIcon />}\n onClick={() => api.exportDataAsCsv(csvOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportCSV}\n </MenuItem>\n )}\n {showExcelOption && (\n <MenuItem\n icon={<TableChartIcon />}\n onClick={() => {\n void api.exportDataAsExcel(excelOptions);\n }}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportExcel}\n </MenuItem>\n )}\n {showPrintOption && (\n <MenuItem\n icon={<PrintIcon />}\n onClick={() => api.exportDataAsPrint(resolvedPrintOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportPrint}\n </MenuItem>\n )}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Quick filter\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridQuickFilterProps {\n placeholder?: string;\n debounceMs?: number;\n /** Always show the expanded input. */\n alwaysExpanded?: boolean;\n}\n\nexport function MGHGridQuickFilter({ placeholder, debounceMs, alwaysExpanded = false }: MGHGridQuickFilterProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const externalValue = (state.quickFilterValues ?? []).join(' ');\n const [text, setText] = React.useState(externalValue);\n const [expanded, setExpanded] = React.useState(alwaysExpanded || externalValue !== '');\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const timer = React.useRef<number | null>(null);\n const delay = debounceMs ?? rootProps.quickFilterDebounceMs;\n\n // Sync when the model is changed from outside (e.g. api.setQuickFilterValues).\n const lastExternal = React.useRef(externalValue);\n React.useEffect(() => {\n if (externalValue !== lastExternal.current) {\n lastExternal.current = externalValue;\n setText(externalValue);\n if (externalValue !== '') setExpanded(true);\n }\n }, [externalValue]);\n\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n\n const commit = (value: string) => {\n const values = value.split(/\\s+/).filter((v) => v !== '');\n lastExternal.current = values.join(' ');\n api.setQuickFilterValues(values);\n };\n\n const handleChange = (value: string) => {\n setText(value);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => commit(value), delay);\n };\n\n const clear = () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n setText('');\n commit('');\n inputRef.current?.focus();\n };\n\n const expand = () => {\n setExpanded(true);\n window.setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const isExpanded = alwaysExpanded || expanded;\n\n return (\n <div className={cx('mgh-grid-quick-filter', isExpanded && 'mgh-grid-quick-filter--expanded')}>\n <IconButton\n className=\"mgh-grid-quick-filter-trigger\"\n label={localeText.toolbarQuickFilterLabel}\n aria-disabled={isExpanded}\n tabIndex={isExpanded ? -1 : 0}\n onClick={expand}\n >\n <SearchIcon />\n </IconButton>\n <div\n className={cx(\n 'mgh-grid-quick-filter-control mgh-grid-input-adorned',\n text && 'mgh-grid-input-adorned--clearable'\n )}\n >\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n ref={inputRef}\n size=\"small\"\n type=\"search\"\n value={text}\n tabIndex={isExpanded ? 0 : -1}\n placeholder={placeholder ?? localeText.toolbarQuickFilterPlaceholder}\n aria-label={localeText.toolbarQuickFilterLabel}\n onChange={(event) => handleChange(event.target.value)}\n onBlur={() => {\n if (!alwaysExpanded && text.trim() === '') setExpanded(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n if (text) clear();\n else if (!alwaysExpanded) {\n setExpanded(false);\n inputRef.current?.blur();\n }\n }\n if (event.key === 'Enter') {\n if (timer.current !== null) window.clearTimeout(timer.current);\n commit(text);\n }\n }}\n />\n {text && (\n <span className=\"mgh-grid-input-adornment mgh-grid-input-adornment--end\">\n <IconButton size=\"small\" label={localeText.clearSearch} onClick={clear} tabIndex={-1}>\n <CloseIcon />\n </IconButton>\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Default toolbar\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n showDensitySelector = false,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n csvOptions,\n excelOptions,\n printOptions,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n quickFilterPlaceholder,\n quickFilterDebounceMs,\n}: MGHGridToolbarProps) {\n const { rootProps } = useMGHGridContext();\n const showColumns = showColumnsButton && !rootProps.disableColumnSelector;\n const showFilters = showFilterButton && !rootProps.disableColumnFilter;\n const showDensity = showDensitySelector && !rootProps.disableDensitySelector;\n\n return (\n <div className=\"mgh-grid-toolbar\" role=\"toolbar\">\n <div className=\"mgh-grid-toolbar-group\">\n {showColumns && <MGHGridColumnsButton />}\n {showFilters && <MGHGridFiltersButton />}\n {showDensity && <MGHGridDensitySelector />}\n {showExportButton && (\n <MGHGridExportMenu\n csvOptions={csvOptions}\n excelOptions={excelOptions}\n printOptions={printOptions}\n showCsvOption={showCsvOption}\n showExcelOption={showExcelOption}\n showPrintOption={showPrintOption}\n customMenuItem={customMenuItem}\n />\n )}\n </div>\n {renderDateRange && <div className=\"mgh-grid-toolbar-center\">{renderDateRange}</div>}\n <div className=\"mgh-grid-toolbar-group\">\n {renderOtherButtons}\n {showQuickFilter && (\n <MGHGridQuickFilter placeholder={quickFilterPlaceholder} debounceMs={quickFilterDebounceMs} />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { ChevronLeftIcon, ChevronRightIcon, FirstPageIcon, LastPageIcon } from '../icons';\nimport { IconButton, Select } from './primitives';\n\nexport function MGHGridPagination() {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const { page, pageSize } = state.paginationModel;\n const count = state.rowCount;\n const pageCount = state.pageCount;\n const from = count === 0 ? 0 : page * pageSize + 1;\n const to = Math.min(count, (page + 1) * pageSize);\n const options =\n rootProps.pageSizeOptions.indexOf(pageSize) === -1\n ? rootProps.pageSizeOptions.concat([pageSize]).sort((a, b) => a - b)\n : rootProps.pageSizeOptions;\n\n return (\n <div className=\"mgh-grid-pagination\" role=\"navigation\" aria-label=\"Pagination\">\n <span>{localeText.footerPaginationRowsPerPage}</span>\n <Select\n className=\"mgh-grid-pagination-select\"\n value={pageSize}\n aria-label={localeText.footerPaginationRowsPerPage}\n onChange={(event) => api.setPageSize(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </Select>\n <span>{localeText.footerPaginationDisplayedRows(from, to, count)}</span>\n <div className=\"mgh-grid-pagination-actions\">\n <IconButton label={localeText.footerPaginationFirstPage} disabled={page <= 0} onClick={() => api.setPage(0)}>\n <FirstPageIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationPreviousPage}\n disabled={page <= 0}\n onClick={() => api.setPage(page - 1)}\n >\n <ChevronLeftIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationNextPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(page + 1)}\n >\n <ChevronRightIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationLastPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(Math.max(pageCount - 1, 0))}\n >\n <LastPageIcon />\n </IconButton>\n </div>\n </div>\n );\n}\n\nexport function MGHGridFooter() {\n const { state, localeText, rootProps } = useMGHGridContext();\n const selectedCount = state.rowSelectionModel.ids.size;\n const showSelected = selectedCount > 0 && !rootProps.hideFooterSelectedRowCount;\n const showPagination = rootProps.pagination && !rootProps.hideFooterPagination;\n const showRowCount = !showPagination && !rootProps.hideFooterRowCount;\n\n return (\n <div className=\"mgh-grid-footer\">\n <div className=\"mgh-grid-footer-left\">\n {showSelected && <span>{localeText.footerRowSelected(selectedCount)}</span>}\n </div>\n {showRowCount && (\n <span>\n {localeText.footerTotalRows} {state.rowCount.toLocaleString()}\n </span>\n )}\n {showPagination && <MGHGridPagination />}\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { SearchIcon } from '../icons';\nimport { Button, Checkbox, TextInput } from './primitives';\n\nexport function MGHGridColumnsPanel() {\n const { api, state, localeText, columns, visibleColumns } = useMGHGridContext();\n const visibleFields = React.useMemo(() => new Set(visibleColumns.map((col) => col.field)), [visibleColumns]);\n const [search, setSearch] = React.useState('');\n const model = state.columnVisibilityModel;\n\n const hideable = columns.filter((col) => col.hideable !== false);\n const needle = search.trim().toLowerCase();\n const filtered = needle\n ? hideable.filter((col) => (col.headerName ?? col.field).toLowerCase().indexOf(needle) !== -1)\n : hideable;\n\n const setAll = (visible: boolean) => {\n const next = { ...model };\n hideable.forEach((col) => {\n next[col.field] = visible;\n });\n api.setColumnVisibilityModel(next);\n };\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarColumns}>\n <div className=\"mgh-grid-panel-header\">\n <div className=\"mgh-grid-input-adorned\">\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n autoFocus\n size=\"small\"\n value={search}\n placeholder={localeText.columnsPanelSearchPlaceholder}\n aria-label={localeText.columnsPanelSearchPlaceholder}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n </div>\n <div className=\"mgh-grid-panel-content\">\n <div className=\"mgh-grid-columns-list\">\n {filtered.map((col) => {\n const visible = visibleFields.has(col.field);\n return (\n <label key={col.field} className=\"mgh-grid-checkbox-label\">\n <Checkbox checked={visible} onChange={() => api.setColumnVisibility(col.field, !visible)} />\n <span>{col.headerName ?? col.field}</span>\n </label>\n );\n })}\n {filtered.length === 0 && <div className=\"mgh-grid-filter-empty\">No columns</div>}\n </div>\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(true)}>\n {localeText.columnsPanelShowAll}\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(false)}>\n {localeText.columnsPanelHideAll}\n </Button>\n <Button size=\"small\" onClick={() => api.setColumnVisibilityModel({})}>\n {localeText.columnsPanelReset}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridFilterItem, MGHGridFilterOperator } from '../MGHGrid.types';\nimport { AddIcon, DeleteIcon } from '../icons';\nimport { getColumnFilterOperators, getOptionLabel, getOptionValue, resolveValueOptions, uniqueId } from '../utils';\nimport { Button, Field, IconButton, Select, TextInput } from './primitives';\n\ninterface FilterValueInputProps {\n item: MGHGridFilterItem;\n column: MGHGridColDef;\n operator: MGHGridFilterOperator | undefined;\n onChange: (value: any) => void;\n placeholder: string;\n}\n\nconst useDebouncedValue = (value: any, onCommit: (value: any) => void, delay = 250) => {\n const [local, setLocal] = React.useState(value ?? '');\n const timer = React.useRef<number | null>(null);\n React.useEffect(() => {\n setLocal(value ?? '');\n }, [value]);\n const update = (next: any) => {\n setLocal(next);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => onCommit(next), delay);\n };\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n return [local, update] as const;\n};\n\nfunction TextValueInput({ item, onChange, placeholder, type }: FilterValueInputProps & { type: string }) {\n const [local, update] = useDebouncedValue(item.value, onChange);\n return (\n <TextInput\n size=\"small\"\n type={type}\n value={local}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction MultiValueInput({ item, column, onChange, placeholder }: FilterValueInputProps) {\n const joined = Array.isArray(item.value) ? item.value.join(', ') : (item.value ?? '');\n const [local, update] = useDebouncedValue(joined, (text: string) =>\n onChange(\n String(text)\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v !== '')\n )\n );\n if (column.type === 'singleSelect') {\n const options = resolveValueOptions(column);\n const selected: string[] = Array.isArray(item.value) ? item.value.map(String) : [];\n return (\n <Select\n multiple\n size=\"small\"\n value={selected}\n aria-label={placeholder}\n onChange={(event) => {\n const values = Array.from(event.target.selectedOptions).map((option) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === option.value);\n return match !== undefined ? getOptionValue(column, match) : option.value;\n });\n onChange(values);\n }}\n >\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n return (\n <TextInput\n size=\"small\"\n value={local}\n placeholder=\"Comma separated values\"\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction FilterValueInput(props: FilterValueInputProps) {\n const { item, column, operator, onChange, placeholder } = props;\n const { api } = useMGHGridContext();\n const inputType = operator?.inputType ?? 'text';\n\n if (operator?.InputComponent) {\n const Component = operator.InputComponent;\n return <Component item={item} column={column} applyValue={(next) => onChange(next.value)} api={api} />;\n }\n\n switch (inputType) {\n case 'none':\n return <div />;\n case 'boolean':\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n >\n <option value=\"\">any</option>\n <option value=\"true\">yes</option>\n <option value=\"false\">no</option>\n </Select>\n );\n case 'select': {\n const options = resolveValueOptions(column);\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === event.target.value);\n onChange(\n event.target.value === ''\n ? undefined\n : match !== undefined\n ? getOptionValue(column, match)\n : event.target.value\n );\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'multiselect':\n return <MultiValueInput {...props} />;\n case 'number':\n return <TextValueInput {...props} type=\"number\" />;\n case 'date':\n return <TextValueInput {...props} type=\"date\" />;\n case 'datetime-local':\n return <TextValueInput {...props} type=\"datetime-local\" />;\n default:\n return <TextValueInput {...props} type=\"text\" />;\n }\n}\n\nconst createFilterItem = (column: MGHGridColDef | undefined): MGHGridFilterItem => ({\n id: uniqueId('filter'),\n field: column?.field ?? '',\n operator: column ? (getColumnFilterOperators(column)[0]?.value ?? 'contains') : 'contains',\n value: undefined,\n});\n\nexport function MGHGridFilterPanel() {\n const { api, state, localeText, columns, rootProps } = useMGHGridContext();\n const filterableColumns = React.useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);\n const byField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n filterableColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [filterableColumns]);\n\n const items = state.filterModel.items;\n const logicOperator = state.filterModel.logicOperator ?? 'and';\n const targetField = state.preferencePanel.targetField;\n\n // Ensure at least one (possibly empty) item is displayed when the panel opens, like MUI does.\n const seeded = React.useRef(false);\n React.useEffect(() => {\n if (seeded.current) return;\n seeded.current = true;\n if (targetField && byField.has(targetField)) {\n const existing = items.find((item) => item.field === targetField);\n if (!existing) api.upsertFilterItem(createFilterItem(byField.get(targetField)));\n } else if (items.length === 0 && filterableColumns.length > 0) {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n }\n }, [api, byField, filterableColumns, items, targetField]);\n\n const updateItem = (item: MGHGridFilterItem, patch: Partial<MGHGridFilterItem>) => {\n api.upsertFilterItem({ ...item, ...patch });\n };\n\n const addItem = () => {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n };\n\n const canAddMore = !rootProps.disableMultipleColumnsFiltering || items.length === 0;\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarFilters}>\n <div className=\"mgh-grid-panel-content\" style={{ paddingTop: 12 }}>\n {items.length === 0 && <div className=\"mgh-grid-filter-empty\">No filters</div>}\n {items.map((item, index) => {\n const column = byField.get(item.field) ?? filterableColumns[0];\n const operators = column ? getColumnFilterOperators(column) : [];\n const operator = operators.find((op) => op.value === item.operator) ?? operators[0];\n const showLogic = items.length > 1;\n return (\n <div\n key={String(item.id ?? index)}\n className={\n showLogic ? 'mgh-grid-filter-row mgh-grid-filter-row--with-logic' : 'mgh-grid-filter-row'\n }\n >\n <IconButton\n size=\"small\"\n label={localeText.filterPanelDeleteIcon}\n onClick={() => api.deleteFilterItem(item)}\n >\n <DeleteIcon />\n </IconButton>\n {showLogic && (\n <Field label={index === 1 ? localeText.filterPanelLogicOperator : ' '}>\n {index === 0 ? (\n <div style={{ height: 32 }} />\n ) : (\n <Select\n size=\"small\"\n value={logicOperator}\n disabled={index > 1}\n aria-label={localeText.filterPanelLogicOperator}\n onChange={(event) =>\n api.setFilterLogicOperator(event.target.value as 'and' | 'or')\n }\n >\n <option value=\"and\">{localeText.filterPanelOperatorAnd}</option>\n <option value=\"or\">{localeText.filterPanelOperatorOr}</option>\n </Select>\n )}\n </Field>\n )}\n <Field label={localeText.filterPanelColumns}>\n <Select\n size=\"small\"\n value={column?.field ?? ''}\n aria-label={localeText.filterPanelColumns}\n onChange={(event) => {\n const nextColumn = byField.get(event.target.value);\n const nextOperators = nextColumn ? getColumnFilterOperators(nextColumn) : [];\n const keepOperator = nextOperators.some((op) => op.value === item.operator);\n updateItem(item, {\n field: event.target.value,\n operator: keepOperator ? item.operator : (nextOperators[0]?.value ?? 'contains'),\n value: undefined,\n });\n }}\n >\n {filterableColumns.map((col) => (\n <option key={col.field} value={col.field}>\n {col.headerName ?? col.field}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelOperator}>\n <Select\n size=\"small\"\n value={operator?.value ?? ''}\n aria-label={localeText.filterPanelOperator}\n onChange={(event) => {\n const nextOperator = operators.find((op) => op.value === event.target.value);\n const nextIsMulti = nextOperator?.inputType === 'multiselect';\n const currentIsMulti = operator?.inputType === 'multiselect';\n updateItem(item, {\n operator: event.target.value,\n value: nextIsMulti !== currentIsMulti ? undefined : item.value,\n });\n }}\n >\n {operators.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label ?? op.value}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelValue}>\n {column ? (\n <FilterValueInput\n item={item}\n column={column}\n operator={operator}\n placeholder={localeText.filterPanelInputPlaceholder}\n onChange={(value) => updateItem(item, { value })}\n />\n ) : (\n <div />\n )}\n </Field>\n </div>\n );\n })}\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button\n variant=\"primary\"\n size=\"small\"\n startIcon={<AddIcon size={18} />}\n onClick={addItem}\n disabled={!canAddMore}\n >\n {localeText.filterPanelAddFilter}\n </Button>\n <Button\n size=\"small\"\n startIcon={<DeleteIcon size={18} />}\n disabled={items.length === 0}\n onClick={() => api.setFilterModel({ ...state.filterModel, items: [] })}\n >\n {localeText.filterPanelRemoveAll}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridThemeMode } from '../MGHGrid.types';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n FilterListIcon,\n FunctionsIcon,\n PushPinIcon,\n ViewColumnIcon,\n VisibilityOffIcon,\n WorkspacesIcon,\n} from '../icons';\nimport { GROUPING_COLUMN_FIELD } from '../utils';\nimport { Menu, MenuDivider, MenuItem, MenuSection, Popover, Select } from './primitives';\n\nexport interface MGHGridColumnMenuProps {\n column: MGHGridColDef;\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n themeMode: MGHGridThemeMode;\n /** Anchor for panels opened from the menu (usually the toolbar button or the header cell). */\n panelAnchorEl?: HTMLElement | null;\n}\n\nexport function MGHGridColumnMenu({ column, anchorEl, open, onClose, themeMode, panelAnchorEl }: MGHGridColumnMenuProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const field = column.field;\n const isGroupingColumn = field === GROUPING_COLUMN_FIELD;\n const sortItem = state.sortModel.find((item) => item.field === field);\n const pinned = api.isColumnPinned(field);\n const isGrouped = state.rowGroupingModel.indexOf(field) !== -1;\n const aggregation = state.aggregationModel[field];\n\n const canSort = column.sortable !== false && !rootProps.disableColumnSorting;\n const canFilter = column.filterable !== false && !rootProps.disableColumnFilter && !isGroupingColumn;\n const canHide = column.hideable !== false;\n const canPin = column.pinnable !== false && !rootProps.disableColumnPinning;\n const canGroup = column.groupable !== false && !rootProps.disableRowGrouping && !isGroupingColumn;\n const aggregationFunctions = Object.keys(rootProps.aggregationFunctions).filter((name) => {\n const fn = rootProps.aggregationFunctions[name];\n if (column.availableAggregationFunctions && column.availableAggregationFunctions.indexOf(name) === -1) return false;\n if (fn.columnTypes && column.type && fn.columnTypes.indexOf(column.type) === -1) return false;\n return true;\n });\n const canAggregate =\n column.aggregable !== false && !rootProps.disableAggregation && !isGroupingColumn && aggregationFunctions.length > 0;\n\n const anchorForPanel = panelAnchorEl ?? anchorEl;\n const name = column.headerName ?? column.field;\n\n return (\n <Popover open={open} anchorEl={anchorEl} onClose={onClose} themeMode={themeMode} placement=\"bottom-end\" role=\"menu\">\n <Menu aria-label={localeText.columnMenuLabel}>\n {canSort && (\n <>\n <MenuItem\n icon={<ArrowUpwardIcon />}\n selected={sortItem?.sort === 'asc'}\n onClick={() => api.sortColumn(field, 'asc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortAsc}\n </MenuItem>\n <MenuItem\n icon={<ArrowDownwardIcon />}\n selected={sortItem?.sort === 'desc'}\n onClick={() => api.sortColumn(field, 'desc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortDesc}\n </MenuItem>\n {sortItem && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.sortColumn(field, null)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnsort}\n </MenuItem>\n )}\n </>\n )}\n {canFilter && (\n <>\n {canSort && <MenuDivider />}\n <MenuItem\n icon={<FilterListIcon />}\n onClick={() => api.showFilterPanel(field, anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuFilter}\n </MenuItem>\n </>\n )}\n {(canHide || !rootProps.disableColumnSelector) && (\n <>\n {(canSort || canFilter) && <MenuDivider />}\n {canHide && (\n <MenuItem\n icon={<VisibilityOffIcon />}\n onClick={() => api.setColumnVisibility(field, false)}\n hideMenu={onClose}\n >\n {localeText.columnMenuHideColumn}\n </MenuItem>\n )}\n {!rootProps.disableColumnSelector && (\n <MenuItem\n icon={<ViewColumnIcon />}\n onClick={() => api.showPreferences('columns', anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuManageColumns}\n </MenuItem>\n )}\n </>\n )}\n {canPin && (\n <>\n <MenuDivider />\n {pinned !== 'left' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(30deg)' }} />}\n onClick={() => api.pinColumn(field, 'left')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinLeft}\n </MenuItem>\n )}\n {pinned !== 'right' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(-30deg)' }} />}\n onClick={() => api.pinColumn(field, 'right')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinRight}\n </MenuItem>\n )}\n {pinned && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.unpinColumn(field)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnpin}\n </MenuItem>\n )}\n </>\n )}\n {canGroup && (\n <>\n <MenuDivider />\n <MenuItem\n icon={<WorkspacesIcon />}\n onClick={() =>\n isGrouped ? api.removeRowGroupingCriteria(field) : api.addRowGroupingCriteria(field)\n }\n hideMenu={onClose}\n >\n {isGrouped ? localeText.columnMenuUngroup(name) : localeText.columnMenuGroup(name)}\n </MenuItem>\n </>\n )}\n {canAggregate && (\n <>\n <MenuDivider />\n <MenuSection>\n <label\n className=\"mgh-grid-field-label\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <FunctionsIcon size={16} /> {localeText.columnMenuAggregation}\n </label>\n <Select\n size=\"small\"\n value={aggregation ?? ''}\n aria-label={localeText.columnMenuAggregation}\n onChange={(event) => {\n const next = { ...state.aggregationModel };\n if (event.target.value === '') delete next[field];\n else next[field] = event.target.value;\n api.setAggregationModel(next);\n }}\n >\n <option value=\"\">{localeText.aggregationFunctionLabelNone}</option>\n {aggregationFunctions.map((fnName) => (\n <option key={fnName} value={fnName}>\n {rootProps.aggregationFunctions[fnName].label ?? fnName}\n </option>\n ))}\n </Select>\n </MenuSection>\n </>\n )}\n </Menu>\n </Popover>\n );\n}\n","import React from 'react';\nimport { MGHGridLoadingOverlayProps, MGHGridNoRowsOverlayProps } from '../MGHGrid.types';\nimport { EmptyBoxIcon } from '../icons';\nimport { Spinner } from './primitives';\n\n/** Default \"no rows\" overlay. Mirrors the legacy CustomNoRowsOverlay but has no MUI dependency. */\nexport function MGHGridNoRowsOverlay({ text = 'No rows', imageSrc }: MGHGridNoRowsOverlayProps) {\n return (\n <div className=\"mgh-grid-no-rows\" role=\"status\">\n {imageSrc ? <img alt=\"\" src={imageSrc} /> : <EmptyBoxIcon size={50} />}\n <div>{text}</div>\n </div>\n );\n}\n\nexport function MGHGridLoadingOverlay({ text }: MGHGridLoadingOverlayProps) {\n return (\n <>\n <Spinner />\n {text && <div>{text}</div>}\n </>\n );\n}\n","import React from 'react';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { MoreVertIcon } from '../icons';\nimport { IconButton, Menu, MenuItem, Popover } from './primitives';\n\nexport interface MGHGridActionsCellItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n icon?: React.ReactElement;\n label: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Render the action inside the \"more\" menu instead of inline. */\n showInMenu?: boolean;\n disabled?: boolean;\n}\n\n/** Drop-in replacement for MUI's GridActionsCellItem. Use it from `colDef.getActions`. */\nexport function MGHGridActionsCellItem({\n icon,\n label,\n onClick,\n showInMenu,\n disabled,\n className,\n ...rest\n}: MGHGridActionsCellItemProps) {\n return (\n <IconButton\n size=\"small\"\n label={label}\n disabled={disabled}\n className={className}\n onClick={(event) => {\n event.stopPropagation();\n onClick?.(event);\n }}\n {...rest}\n >\n {icon}\n </IconButton>\n );\n}\nMGHGridActionsCellItem.displayName = 'MGHGridActionsCellItem';\n\ninterface ActionsCellProps {\n actions: React.ReactElement[];\n themeMode: MGHGridThemeMode;\n moreLabel: string;\n}\n\nexport function ActionsCell({ actions, themeMode, moreLabel }: ActionsCellProps) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const inline: React.ReactElement[] = [];\n const inMenu: React.ReactElement[] = [];\n actions.forEach((action) => {\n if (!React.isValidElement(action)) return;\n if ((action.props as MGHGridActionsCellItemProps)?.showInMenu) inMenu.push(action);\n else inline.push(action);\n });\n\n return (\n <>\n {inline.map((action, index) => (\n <React.Fragment key={action.key ?? index}>{action}</React.Fragment>\n ))}\n {inMenu.length > 0 && (\n <>\n <IconButton\n size=\"small\"\n label={moreLabel}\n active={Boolean(anchor)}\n onClick={(event) => {\n event.stopPropagation();\n setAnchor((prev) => (prev ? null : event.currentTarget));\n }}\n >\n <MoreVertIcon />\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n placement=\"bottom-end\"\n role=\"menu\"\n >\n <Menu>\n {inMenu.map((action, index) => {\n const props = action.props as MGHGridActionsCellItemProps;\n return (\n <MenuItem\n key={action.key ?? index}\n icon={props.icon}\n disabled={props.disabled}\n onClick={(event) => {\n props.onClick?.(event);\n setAnchor(null);\n }}\n >\n {props.label}\n </MenuItem>\n );\n })}\n </Menu>\n </Popover>\n </>\n )}\n </>\n );\n}\n","import React from 'react';\nimport {\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridApplyFilterFn,\n MGHGridCallbackDetails,\n MGHGridCellParams,\n MGHGridColDef,\n MGHGridColumnVisibilityModel,\n MGHGridDensity,\n MGHGridFilterItem,\n MGHGridFilterModel,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridLocaleText,\n MGHGridPaginationModel,\n MGHGridPinnedColumns,\n MGHGridPinnedSide,\n MGHGridPreferencePanelState,\n MGHGridPrintExportOptions,\n MGHGridProps,\n MGHGridRowGroupingModel,\n MGHGridRowId,\n MGHGridRowNode,\n MGHGridRowParams,\n MGHGridRowSelectionModel,\n MGHGridSortDirection,\n MGHGridSortModel,\n MGHGridState,\n MGHGridSxProps,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport {\n AGGREGATION_FOOTER_ID,\n BUILT_IN_AGGREGATION_FUNCTIONS,\n CHECKBOX_COLUMN_DEF,\n CHECKBOX_FIELD,\n DEFAULT_COLUMN_MIN_WIDTH,\n DEFAULT_COLUMN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_LOCALE_TEXT,\n DEFAULT_ROW_HEIGHT,\n DENSITY_FACTORS,\n DETAIL_PANEL_TOGGLE_COLUMN_DEF,\n DETAIL_PANEL_TOGGLE_FIELD,\n GROUPING_COLUMN_FIELD,\n GROUPING_COLUMN_WIDTH,\n clamp,\n cx,\n defaultFormatValue,\n formattedValueToString,\n getCellValue,\n getColumnFilterOperators,\n getDefaultComparator,\n getFormattedValue,\n getOptionLabel,\n getOptionValue,\n getRowIdFromRow,\n buildScopedCss,\n isInternalField,\n isNil,\n isSelectorKey,\n measureText,\n moveItem,\n normalizeColumn,\n normalizeSelectionModel,\n parseEditValue,\n readLocalStorage,\n resolveValueOptions,\n selectionModelsEqual,\n toDate,\n writeLocalStorage,\n} from './utils';\nimport { useMGHGridStyles } from './MGHGrid.styles';\nimport { MGHGridContext, MGHGridContextValue, MGHGridRootProps } from './context';\nimport { useControlledState, useElementSize, useForceUpdate, useLatestRef, useStableId } from './hooks';\nimport { exportDataAsCsv, exportDataAsExcel, getDataAsCsv } from './export';\nimport { printGridElement } from './print';\nimport {\n DisplayRow,\n GroupTreeNode,\n RowEntry,\n aggregateRows,\n buildGroupTree,\n collectTreeLeaves,\n flattenGroupTree,\n sortGroupTree,\n} from './grouping';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n CheckIcon,\n ChevronRightIcon,\n CloseIcon,\n ExpandMoreIcon,\n MoreVertIcon,\n} from './icons';\nimport { Checkbox, IconButton, Popover, Select, TextInput } from './components/primitives';\nimport { MGHGridToolbar } from './components/Toolbar';\nimport { MGHGridFooter } from './components/Footer';\nimport { MGHGridColumnsPanel } from './components/ColumnsPanel';\nimport { MGHGridFilterPanel } from './components/FilterPanel';\nimport { MGHGridColumnMenu } from './components/ColumnMenu';\nimport { MGHGridLoadingOverlay, MGHGridNoRowsOverlay } from './components/Overlays';\nimport { ActionsCell } from './components/ActionsCell';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants & helpers\n * ----------------------------------------------------------------------------------------------- */\n\nconst EMPTY_ARRAY: any[] = [];\nconst EMPTY_OBJECT: Record<string, any> = {};\nconst EMPTY_MAP = new Map<any, any>();\nconst DEFAULT_SORTING_ORDER: MGHGridSortDirection[] = ['asc', 'desc', null];\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\nconst DEFAULT_FILTER_MODEL: MGHGridFilterModel = { items: [], quickFilterExcludeHiddenColumns: false };\nconst OVERSCAN_ROWS = 6;\nconst DEFAULT_DETAIL_PANEL_HEIGHT = 500;\n\ninterface ColumnLayout {\n col: MGHGridColDef;\n width: number;\n pinned: MGHGridPinnedSide | null;\n /** Sticky offset (left or right) for pinned columns. */\n offset: number;\n /** X position from the start of the row. */\n x: number;\n isLastLeft: boolean;\n isFirstRight: boolean;\n}\n\ntype RenderRowKind = 'leaf' | 'group' | 'pinnedRow' | 'footer';\n\ninterface RenderRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n kind: RenderRowKind;\n row: R | null;\n node: MGHGridRowNode;\n depth: number;\n group?: GroupTreeNode<R>;\n aggregates?: Record<string, { value: any; fn: string }>;\n}\n\ninterface CellCoords {\n id: MGHGridRowId;\n field: string;\n}\n\n/** Keeps only the inline-applicable part of an sx-like object (nested selectors are compiled to CSS). */\nconst sanitizeStyle = (style: MGHGridSxProps | undefined): React.CSSProperties | undefined => {\n if (!style) return undefined;\n const out: Record<string, any> = {};\n Object.keys(style).forEach((key) => {\n if (isSelectorKey(key)) return;\n const value = (style as any)[key];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n out[key] = value;\n });\n return out;\n};\n\n/** Horizontal space a header cell needs besides its title text: cell padding, sort icon, column-menu button. */\nconst HEADER_CELL_PADDING = 20;\nconst HEADER_SORT_ICON_WIDTH = 20;\nconst HEADER_MENU_BUTTON_WIDTH = 28;\n\n/**\n * Column widths for one layout pass.\n * - a width the user dragged / persisted (`overrides`) wins, clamped to the column's own min / max;\n * - `flex` columns share the remaining viewport, never shrinking below their header text unless an\n * explicit `minWidth` says otherwise;\n * - a column with an explicit `width` is used as given (even when narrower than its header);\n * - any other column is at least `DEFAULT_COLUMN_WIDTH` and wide enough to show its whole header.\n */\nconst computeWidths = (\n cols: MGHGridColDef[],\n available: number,\n overrides: Record<string, number>,\n headerWidths: Record<string, number>\n) => {\n const minFor = (col: MGHGridColDef) => col.minWidth ?? Math.max(DEFAULT_COLUMN_MIN_WIDTH, headerWidths[col.field] ?? 0);\n const result: Array<number | null> = cols.map((col) => {\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const override = overrides[col.field];\n if (override) return clamp(override, min, max);\n if (col.flex && col.flex > 0) return null;\n if (col.width !== undefined) return clamp(col.width, min, max);\n return clamp(Math.max(DEFAULT_COLUMN_WIDTH, headerWidths[col.field] ?? 0), min, max);\n });\n const pool: number[] = [];\n let fixedTotal = 0;\n result.forEach((w, i) => {\n if (w === null) pool.push(i);\n else fixedTotal += w;\n });\n if (pool.length > 0) {\n let remainingSpace = Math.max(0, available - fixedTotal);\n let remainingFlex = pool.reduce((acc, i) => acc + (cols[i].flex as number), 0);\n let active = pool.slice();\n let changed = true;\n while (changed && active.length > 0) {\n changed = false;\n for (let k = 0; k < active.length; k += 1) {\n const i = active[k];\n const col = cols[i];\n const min = minFor(col);\n const max = col.maxWidth ?? Infinity;\n const share = remainingFlex > 0 ? (remainingSpace * (col.flex as number)) / remainingFlex : 0;\n if (share < min || share > max) {\n const fixed = share < min ? min : max;\n result[i] = fixed;\n remainingSpace = Math.max(0, remainingSpace - fixed);\n remainingFlex -= col.flex as number;\n active = active.filter((idx) => idx !== i);\n changed = true;\n break;\n }\n }\n }\n active.forEach((i) => {\n const col = cols[i];\n result[i] =\n remainingFlex > 0\n ? Math.floor((remainingSpace * (col.flex as number)) / remainingFlex)\n : minFor(col);\n });\n }\n return result as number[];\n};\n\nconst toDateInputValue = (value: any, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n return withTime ? `${base}T${pad(date.getHours())}:${pad(date.getMinutes())}` : base;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Component\n * ----------------------------------------------------------------------------------------------- */\n\nexport default function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>) {\n const {\n rows,\n columns: columnsProp,\n getRowId,\n loading = false,\n header,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n disableCard = false,\n className,\n cardClassName,\n boxClassName,\n cardStyle,\n cardSx,\n boxStyle,\n boxSx,\n style,\n sx,\n themeMode = 'light',\n themeVars,\n showToolbar = true,\n toolbarProps,\n slots = EMPTY_OBJECT,\n slotProps = EMPTY_OBJECT,\n noRowsText = 'No data found within selected parameters.',\n localeText: localeTextProp,\n rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n columnHeaderHeight = DEFAULT_HEADER_HEIGHT,\n getRowHeight,\n autoHeight = false,\n disableVirtualization = false,\n density: densityProp,\n onDensityChange,\n disableDensitySelector = false,\n pagination = true,\n pageSize = 25,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationModel: paginationModelProp,\n onPaginationModelChange,\n hideFooter = false,\n hideFooterPagination = false,\n hideFooterRowCount = false,\n hideFooterSelectedRowCount = false,\n sortModel: sortModelProp,\n onSortModelChange,\n sortingOrder = DEFAULT_SORTING_ORDER,\n disableMultipleColumnsSorting = false,\n disableColumnSorting = false,\n filterModel: filterModelProp,\n onFilterModelChange,\n disableColumnFilter = false,\n disableMultipleColumnsFiltering = false,\n quickFilterDebounceMs = 150,\n columnVisibilityModel: columnVisibilityModelProp,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n columnWidthStorageKey,\n pinnedColumnsStorageKey,\n onColumnOrderChange,\n onColumnWidthChange,\n disableColumnMenu = false,\n disableColumnSelector = false,\n disableColumnResize = false,\n disableColumnReorder = false,\n disableColumnPinning = false,\n pinnedColumns: pinnedColumnsProp,\n onPinnedColumnsChange,\n checkboxSelection = false,\n checkboxSelectionVisibleOnly = false,\n disableRowSelectionOnClick = true,\n disableMultipleRowSelection = false,\n rowSelectionModel: rowSelectionModelProp,\n onRowSelectionModelChange,\n isRowSelectable,\n keepNonExistentRowsSelected = true,\n getRowClassName,\n onRowClick,\n onRowDoubleClick,\n onCellClick,\n onCellDoubleClick,\n pinnedRows,\n getDetailPanelContent,\n getDetailPanelHeight,\n detailPanelExpandedRowIds: detailPanelExpandedRowIdsProp,\n onDetailPanelExpandedRowIdsChange,\n rowGroupingModel: rowGroupingModelProp,\n onRowGroupingModelChange,\n defaultGroupingExpansionDepth = 0,\n groupingColDef,\n disableRowGrouping = false,\n isGroupExpandedByDefault,\n aggregationModel: aggregationModelProp,\n onAggregationModelChange,\n aggregationFunctions: aggregationFunctionsProp,\n disableAggregation = false,\n aggregationPosition = 'both',\n processRowUpdate,\n onProcessRowUpdateError,\n onCellEditStop,\n isCellEditable,\n initialState,\n apiRef,\n onStateChange,\n } = props;\n\n useMGHGridStyles();\n\n const gridId = useStableId('mgh-grid');\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const cardRef = React.useRef<HTMLDivElement | null>(null);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n const forceUpdate = useForceUpdate();\n\n const localeText = React.useMemo<MGHGridLocaleText>(\n () => ({ ...DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n\n /* ------------------------------------------------------------------ latest ref + api shell */\n\n const latest = React.useRef<any>({});\n const getDetails = React.useCallback((): MGHGridCallbackDetails => ({ api: latest.current.api }), []);\n\n const apiObject = React.useMemo<MGHGridApi<R>>(() => {\n const L = () => latest.current;\n const apiImpl: MGHGridApi<R> = {\n getRow: (id) => L().rowsById.get(id) ?? null,\n getRowModels: () => new Map(L().rowsById),\n getAllRowIds: () => L().rowEntries.map((e: RowEntry<R>) => e.id),\n getRowNode: (id) => L().nodesById.get(id) ?? null,\n getSortedRows: () => L().sortedLeaves.map((e: RowEntry<R>) => e.row),\n getSortedRowIds: () => L().sortedLeaves.map((e: RowEntry<R>) => e.id),\n getVisibleRows: () =>\n L()\n .pagedRows.filter((dr: DisplayRow<R>) => dr.type === 'leaf' && dr.row)\n .map((dr: DisplayRow<R>) => ({ id: dr.id, model: dr.row as R })),\n getRowIndexRelativeToVisibleRows: (id) => L().pagedRows.findIndex((dr: DisplayRow<R>) => dr.id === id),\n updateRows: (updates) => {\n updates.forEach((update) => {\n const id = getRowIdFromRow(update as R, L().getRowId);\n const existing = L().rowsById.get(id);\n if (existing) L().setRowOverride(id, { ...existing, ...update });\n });\n },\n\n getAllColumns: () => L().orderedUserColumns,\n getVisibleColumns: () => L().visibleUserColumns,\n getColumn: (field) => L().getColumn(field),\n getColumnIndex: (field, useVisibleColumns = true) =>\n (useVisibleColumns ? L().visibleUserColumns : L().orderedUserColumns).findIndex(\n (c: MGHGridColDef) => c.field === field\n ),\n getColumnVisibilityModel: () => L().columnVisibilityModel,\n setColumnVisibility: (field, isVisible) =>\n L().setColumnVisibilityModel({ ...L().columnVisibilityModel, [field]: isVisible }),\n setColumnVisibilityModel: (model) => L().setColumnVisibilityModel(model),\n setColumnWidth: (field, width) => L().setColumnWidth(field, width),\n setColumnIndex: (field, targetIndex) => L().setColumnIndex(field, targetIndex),\n autosizeColumns: (options) => L().autosizeColumns(options),\n pinColumn: (field, side) => L().pinColumn(field, side),\n unpinColumn: (field) => L().unpinColumn(field),\n isColumnPinned: (field) => L().isColumnPinned(field),\n getPinnedColumns: () => L().pinnedColumns,\n setPinnedColumns: (model) => L().setPinnedColumns(model),\n\n getSortModel: () => L().sortModel,\n setSortModel: (model) => L().setSortModel(model),\n sortColumn: (field, direction, allowMultipleSorting) => L().sortColumn(field, direction, allowMultipleSorting),\n\n getFilterModel: () => L().filterModel,\n setFilterModel: (model) => L().setFilterModel(model),\n upsertFilterItem: (item) => L().upsertFilterItems([item]),\n upsertFilterItems: (items) => L().upsertFilterItems(items),\n deleteFilterItem: (item) => L().deleteFilterItem(item),\n setFilterLogicOperator: (operator) => L().setFilterModel({ ...L().filterModel, logicOperator: operator }),\n setQuickFilterValues: (values) => L().setFilterModel({ ...L().filterModel, quickFilterValues: values }),\n showFilterPanel: (targetColumnField, anchorEl) => L().showPreferences('filters', anchorEl, targetColumnField),\n hideFilterPanel: () => L().hidePreferences(),\n showPreferences: (panel, anchorEl, targetField) => L().showPreferences(panel, anchorEl, targetField),\n hidePreferences: () => L().hidePreferences(),\n\n getSelectedRows: () => {\n const map = new Map<MGHGridRowId, R>();\n L().selectedIds.forEach((id: MGHGridRowId) => {\n const row = L().rowsById.get(id);\n if (row) map.set(id, row);\n });\n return map;\n },\n getRowSelectionModel: () => ({ type: 'include', ids: L().selectedIds }),\n setRowSelectionModel: (model) => {\n const normalized = normalizeSelectionModel(\n model,\n L().rowEntries.map((e: RowEntry<R>) => e.id)\n );\n L().setSelectedIds(normalized.ids);\n },\n selectRow: (id, isSelected = true, resetSelection = false) => L().selectRows([id], isSelected, resetSelection),\n selectRows: (ids, isSelected = true, resetSelection = false) => L().selectRows(ids, isSelected, resetSelection),\n isRowSelected: (id) => L().selectedIds.has(id),\n isRowSelectable: (id) => L().isRowSelectableFn(id, L().rowsById.get(id)),\n\n setPage: (nextPage) => L().setPaginationModel({ ...L().paginationModel, page: Math.max(0, nextPage) }),\n setPageSize: (nextPageSize) => L().setPaginationModel({ page: 0, pageSize: Math.max(1, nextPageSize) }),\n setPaginationModel: (model) => L().setPaginationModel(model),\n\n setDensity: (value) => L().setDensity(value),\n\n getDataAsCsv: (options) => getDataAsCsv(apiImpl, options),\n exportDataAsCsv: (options) => exportDataAsCsv(apiImpl, options),\n exportDataAsExcel: (options) => exportDataAsExcel(apiImpl, options),\n exportDataAsPrint: (options) => L().startPrint(options),\n\n toggleDetailPanel: (id) => L().toggleDetailPanel(id),\n setExpandedDetailPanels: (ids) => L().setExpandedDetailPanels(new Set(ids)),\n getExpandedDetailPanels: () => Array.from(L().expandedDetailPanels as Set<MGHGridRowId>),\n\n getRowGroupingModel: () => L().rowGroupingModel,\n setRowGroupingModel: (model) => L().setRowGroupingModel(model),\n addRowGroupingCriteria: (field, groupingIndex) => {\n const current: string[] = L().rowGroupingModel.filter((f: string) => f !== field);\n if (groupingIndex === undefined) current.push(field);\n else current.splice(clamp(groupingIndex, 0, current.length), 0, field);\n L().setRowGroupingModel(current);\n },\n removeRowGroupingCriteria: (field) =>\n L().setRowGroupingModel(L().rowGroupingModel.filter((f: string) => f !== field)),\n setRowChildrenExpansion: (id, isExpanded) => L().setRowChildrenExpansion(id, isExpanded),\n getRowGroupChildren: ({ groupId }) => {\n const group = L().groupsById.get(groupId) as GroupTreeNode<R> | undefined;\n return group ? group.descendants.map((d) => d.id) : [];\n },\n\n getAggregationModel: () => L().aggregationModel,\n setAggregationModel: (model) => L().setAggregationModel(model),\n\n startCellEditMode: ({ id, field }) => L().startCellEditMode(id, field),\n stopCellEditMode: ({ id, field, ignoreModifications }) =>\n L().stopCellEditMode(id, field, ignoreModifications, 'api'),\n getCellMode: (id, field) => {\n const editing = L().editingCell as CellCoords | null;\n return editing && editing.id === id && editing.field === field ? 'edit' : 'view';\n },\n setEditCellValue: ({ id, field, value }) => {\n const editing = L().editingCell as CellCoords | null;\n if (editing && editing.id === id && editing.field === field) L().setEditValue(value);\n },\n\n getCellValue: (id, field) => {\n const row = L().rowsById.get(id);\n const col = L().getColumn(field);\n return row && col ? getCellValue(row, col, apiImpl) : undefined;\n },\n getCellParams: (id, field) => {\n const row = L().rowsById.get(id);\n return L().buildCellParams(\n id,\n field,\n row,\n L().nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null }\n );\n },\n setCellFocus: (id, field) => {\n pendingFocusRef.current = true;\n L().setFocusedCell({ id, field });\n },\n\n scrollToIndexes: (params) => L().scrollToIndexes(params),\n scroll: ({ left, top }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n if (left !== undefined) scroller.scrollLeft = left;\n if (top !== undefined) scroller.scrollTop = top;\n },\n getScrollPosition: () => ({\n left: scrollerRef.current?.scrollLeft ?? 0,\n top: scrollerRef.current?.scrollTop ?? 0,\n }),\n\n get state() {\n return L().state as MGHGridState;\n },\n forceUpdate: () => L().forceUpdate(),\n rootElementRef: rootRef,\n };\n return apiImpl;\n }, []);\n if (!latest.current.api) latest.current.api = apiObject;\n\n /* ------------------------------------------------------------------ persisted state */\n\n const persisted = React.useMemo(\n () => ({\n visibility: columnVisibilityStorageKey\n ? readLocalStorage<MGHGridColumnVisibilityModel>(columnVisibilityStorageKey)\n : null,\n order: columnOrderStorageKey ? readLocalStorage<string[]>(columnOrderStorageKey) : null,\n widths: columnWidthStorageKey ? readLocalStorage<Record<string, number>>(columnWidthStorageKey) : null,\n pinned: pinnedColumnsStorageKey ? readLocalStorage<MGHGridPinnedColumns>(pinnedColumnsStorageKey) : null,\n }),\n [columnVisibilityStorageKey, columnOrderStorageKey, columnWidthStorageKey, pinnedColumnsStorageKey]\n );\n\n /* ------------------------------------------------------------------ models */\n\n const [sortModel, setSortModel] = useControlledState<MGHGridSortModel>(\n sortModelProp,\n initialState?.sorting?.sortModel ?? EMPTY_ARRAY,\n (model) => onSortModelChange?.(model, getDetails())\n );\n\n const [filterModel, setFilterModel] = useControlledState<MGHGridFilterModel>(\n filterModelProp,\n initialState?.filter?.filterModel ?? DEFAULT_FILTER_MODEL,\n (model) => onFilterModelChange?.(model, getDetails())\n );\n\n const [paginationModel, setPaginationModel] = useControlledState<MGHGridPaginationModel>(\n paginationModelProp,\n {\n page: initialState?.pagination?.paginationModel?.page ?? 0,\n pageSize: initialState?.pagination?.paginationModel?.pageSize ?? pageSize,\n },\n (model) => onPaginationModelChange?.(model, getDetails())\n );\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useControlledState<MGHGridColumnVisibilityModel>(\n columnVisibilityModelProp,\n persisted.visibility ?? initialState?.columns?.columnVisibilityModel ?? EMPTY_OBJECT,\n (model) => {\n if (columnVisibilityStorageKey) writeLocalStorage(columnVisibilityStorageKey, model);\n onColumnVisibilityModelChange?.(model, getDetails());\n }\n );\n\n const [density, setDensity] = useControlledState<MGHGridDensity>(\n densityProp,\n initialState?.density ?? 'compact',\n (value) => onDensityChange?.(value, getDetails())\n );\n\n const [pinnedColumns, setPinnedColumns] = useControlledState<MGHGridPinnedColumns>(\n pinnedColumnsProp,\n persisted.pinned ?? initialState?.pinnedColumns ?? EMPTY_OBJECT,\n (model) => {\n if (pinnedColumnsStorageKey) writeLocalStorage(pinnedColumnsStorageKey, model);\n onPinnedColumnsChange?.(model, getDetails());\n }\n );\n\n const [rowGroupingModel, setRowGroupingModel] = useControlledState<MGHGridRowGroupingModel>(\n rowGroupingModelProp,\n initialState?.rowGrouping?.model ?? EMPTY_ARRAY,\n (model) => onRowGroupingModelChange?.(model, getDetails())\n );\n\n const [aggregationModel, setAggregationModel] = useControlledState<MGHGridAggregationModel>(\n aggregationModelProp,\n initialState?.aggregation?.model ?? EMPTY_OBJECT,\n (model) => onAggregationModelChange?.(model, getDetails())\n );\n\n const controlledExpandedDetail = React.useMemo(\n () => (detailPanelExpandedRowIdsProp ? new Set<MGHGridRowId>(detailPanelExpandedRowIdsProp) : undefined),\n [detailPanelExpandedRowIdsProp]\n );\n const [expandedDetailPanels, setExpandedDetailPanels] = useControlledState<Set<MGHGridRowId>>(\n controlledExpandedDetail,\n React.useMemo(() => new Set<MGHGridRowId>(initialState?.detailPanel?.expandedRowIds ?? []), []),\n (ids) => onDetailPanelExpandedRowIdsChange?.(Array.from(ids), getDetails())\n );\n\n const controlledSelection = React.useMemo(\n () => (rowSelectionModelProp !== undefined ? normalizeSelectionModel(rowSelectionModelProp).ids : undefined),\n [rowSelectionModelProp]\n );\n const [selectedIds, setSelectedIds] = useControlledState<Set<MGHGridRowId>>(\n controlledSelection,\n React.useMemo(() => new Set<MGHGridRowId>(), []),\n (ids) => onRowSelectionModelChange?.({ type: 'include', ids }, getDetails())\n );\n\n /* ------------------------------------------------------------------ internal state */\n\n const [orderedFields, setOrderedFields] = React.useState<string[] | null>(\n () => persisted.order ?? initialState?.columns?.orderedFields ?? null\n );\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>(() => {\n if (persisted.widths) return persisted.widths;\n const dims = initialState?.columns?.dimensions;\n if (!dims) return {};\n const out: Record<string, number> = {};\n Object.keys(dims).forEach((field) => {\n if (dims[field].width) out[field] = dims[field].width as number;\n });\n return out;\n });\n const [groupExpansion, setGroupExpansion] = React.useState<Map<MGHGridRowId, boolean>>(() => new Map());\n const [editingCell, setEditingCell] = React.useState<CellCoords | null>(null);\n const [editValue, setEditValue] = React.useState<any>(undefined);\n const [focusedCell, setFocusedCell] = React.useState<CellCoords | null>(null);\n const pendingFocusRef = React.useRef(false);\n const [preferencePanel, setPreferencePanel] = React.useState<\n MGHGridPreferencePanelState & { anchorEl: HTMLElement | null }\n >({\n open: false,\n anchorEl: null,\n });\n const [columnMenu, setColumnMenu] = React.useState<{ field: string; anchorEl: HTMLElement } | null>(null);\n const [resizingField, setResizingField] = React.useState<string | null>(null);\n // While set, the grid renders every row (no pagination / virtualization) so the DOM can be printed.\n const [printState, setPrintState] = React.useState<MGHGridPrintExportOptions | null>(null);\n const printing = printState !== null;\n const [drag, setDrag] = React.useState<{ field: string; overField: string | null; side: 'left' | 'right' } | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const scrollRaf = React.useRef(0);\n const lastClickedIdRef = React.useRef<MGHGridRowId | null>(null);\n\n // Row updates (editing / api.updateRows) are kept until the `rows` prop identity changes.\n const [overrideState, setOverrideState] = React.useState<{ rows: R[]; map: Map<MGHGridRowId, R> }>(() => ({\n rows,\n map: new Map(),\n }));\n const rowOverrides: Map<MGHGridRowId, R> = overrideState.rows === rows ? overrideState.map : EMPTY_MAP;\n const setRowOverride = React.useCallback(\n (id: MGHGridRowId, row: R) => {\n setOverrideState((prev) => {\n const map = new Map(prev.rows === rows ? prev.map : []);\n map.set(id, row);\n return { rows, map };\n });\n },\n [rows]\n );\n\n /* ------------------------------------------------------------------ sizes */\n\n const { width: viewportWidth, height: viewportHeight } = useElementSize(scrollerRef);\n const densityFactor = DENSITY_FACTORS[density] ?? 1;\n const rowHeight = Math.round(rowHeightProp * densityFactor);\n const headerHeight = Math.round(columnHeaderHeight * densityFactor);\n // Header titles may wrap onto as many lines as fit in the header height (14px text, line-height 1.2).\n const headerTitleLines = Math.max(1, Math.floor((headerHeight - 4) / (14 * 1.2)));\n\n // The font the grid actually renders with, used to measure header text for column widths / autosize.\n const [fontFamily, setFontFamily] = React.useState('sans-serif');\n React.useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || typeof window === 'undefined') return;\n const family = window.getComputedStyle(root).fontFamily;\n if (family) setFontFamily((prev) => (prev === family ? prev : family));\n }, []);\n const cellFont = `400 14px ${fontFamily}`;\n const headerFont = `600 14px ${fontFamily}`;\n\n /** Width a header cell needs to show its whole title (plus sort icon / menu button when present). */\n const measureHeaderWidth = React.useCallback(\n (col: MGHGridColDef) => {\n const isGrouping = col.field === GROUPING_COLUMN_FIELD;\n const sortable = col.sortable !== false && (isGrouping || !disableColumnSorting);\n const showMenu = !disableColumnMenu && (isGrouping || !col.disableColumnMenu);\n let width = measureText(col.headerName ?? col.field, headerFont) + HEADER_CELL_PADDING + 2;\n if (sortable) width += HEADER_SORT_ICON_WIDTH;\n if (showMenu) width += HEADER_MENU_BUTTON_WIDTH;\n return Math.ceil(width);\n },\n [headerFont, disableColumnSorting, disableColumnMenu]\n );\n\n /* ------------------------------------------------------------------ rows */\n\n const rowEntries = React.useMemo<RowEntry<R>[]>(() => {\n const out: RowEntry<R>[] = [];\n rows.forEach((raw) => {\n const id = getRowIdFromRow(raw, getRowId);\n if (id === undefined || id === null) return;\n out.push({ id, row: rowOverrides.get(id) ?? raw });\n });\n return out;\n }, [rows, getRowId, rowOverrides]);\n\n const rowsById = React.useMemo(() => {\n const map = new Map<MGHGridRowId, R>();\n rowEntries.forEach((entry) => map.set(entry.id, entry.row));\n (pinnedRows?.top ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n (pinnedRows?.bottom ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n return map;\n }, [rowEntries, pinnedRows, getRowId]);\n\n /* ------------------------------------------------------------------ columns */\n\n const userColumns = React.useMemo(() => columnsProp.map((col) => normalizeColumn(col)), [columnsProp]);\n\n const columnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef<R>>();\n userColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [userColumns]);\n\n const groupingFields = React.useMemo(\n () => (disableRowGrouping ? [] : rowGroupingModel.filter((field) => columnsByField.has(field))),\n [rowGroupingModel, columnsByField, disableRowGrouping]\n );\n const groupingActive = groupingFields.length > 0;\n\n const groupingColumn = React.useMemo<MGHGridColDef<R> | null>(() => {\n if (!groupingActive) return null;\n const single = groupingFields.length === 1 ? columnsByField.get(groupingFields[0]) : undefined;\n return normalizeColumn<R>({\n field: GROUPING_COLUMN_FIELD,\n headerName: single ? (single.headerName ?? single.field) : localeText.groupingColumnHeaderName,\n width: GROUPING_COLUMN_WIDTH,\n minWidth: 120,\n sortable: true,\n filterable: false,\n hideable: false,\n groupable: false,\n aggregable: false,\n editable: false,\n disableExport: true,\n disableReorder: true,\n ...(groupingColDef as any),\n });\n }, [groupingActive, groupingFields, columnsByField, localeText.groupingColumnHeaderName, groupingColDef]);\n\n const orderedUserColumns = React.useMemo(() => {\n if (!orderedFields || orderedFields.length === 0) return userColumns;\n const seen = new Set<string>();\n const out: MGHGridColDef<R>[] = [];\n orderedFields.forEach((field) => {\n const col = columnsByField.get(field);\n if (col && !seen.has(field)) {\n seen.add(field);\n out.push(col);\n }\n });\n userColumns.forEach((col) => {\n if (!seen.has(col.field)) out.push(col);\n });\n return out;\n }, [orderedFields, userColumns, columnsByField]);\n\n const isColumnVisible = React.useCallback(\n (field: string) => {\n const value = columnVisibilityModel[field];\n if (value === false) return false;\n if (value === undefined && groupingFields.indexOf(field) !== -1) return false;\n return true;\n },\n [columnVisibilityModel, groupingFields]\n );\n\n const visibleUserColumns = React.useMemo(() => {\n if (printState) {\n let cols = orderedUserColumns.filter((col) => isColumnVisible(col.field));\n if (printState.fields) {\n const wanted = new Set(printState.fields);\n cols = orderedUserColumns.filter((col) => wanted.has(col.field));\n } else if (printState.allColumns) {\n cols = orderedUserColumns;\n }\n return cols.filter((col) => !col.disableExport);\n }\n return orderedUserColumns.filter((col) => isColumnVisible(col.field));\n }, [orderedUserColumns, isColumnVisible, printState]);\n\n const layout = React.useMemo(() => {\n const internal: MGHGridColDef[] = [];\n if (checkboxSelection) internal.push(CHECKBOX_COLUMN_DEF);\n if (getDetailPanelContent) internal.push(DETAIL_PANEL_TOGGLE_COLUMN_DEF);\n const leftFields = disableColumnPinning ? [] : (pinnedColumns.left ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const rightFields = disableColumnPinning\n ? []\n : (pinnedColumns.right ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const visibleByField = new Map<string, MGHGridColDef>();\n visibleUserColumns.forEach((col) => visibleByField.set(col.field, col));\n const left: MGHGridColDef[] = internal.slice();\n if (groupingColumn) left.push(groupingColumn);\n leftFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col) left.push(col);\n });\n const right: MGHGridColDef[] = [];\n rightFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col && leftFields.indexOf(f) === -1) right.push(col);\n });\n const center = visibleUserColumns.filter(\n (col) => leftFields.indexOf(col.field) === -1 && rightFields.indexOf(col.field) === -1\n );\n const ordered = left.concat(center, right);\n const headerWidths: Record<string, number> = {};\n ordered.forEach((col) => {\n // Custom headers can't be measured; internal columns have fixed widths.\n if (isInternalField(col.field) || col.renderHeader) return;\n headerWidths[col.field] = measureHeaderWidth(col);\n });\n const widths = computeWidths(ordered, viewportWidth, columnWidths, headerWidths);\n const hasPinning = left.length > internal.length + (groupingColumn ? 1 : 0) || right.length > 0;\n const columns: ColumnLayout[] = [];\n let x = 0;\n let leftOffset = 0;\n ordered.forEach((col, i) => {\n const width = widths[i];\n const isLeft = i < left.length;\n const isRight = i >= left.length + center.length;\n columns.push({\n col,\n width,\n pinned: isLeft ? 'left' : isRight ? 'right' : null,\n offset: isLeft ? leftOffset : 0,\n x,\n isLastLeft: isLeft && i === left.length - 1,\n isFirstRight: isRight && i === left.length + center.length,\n });\n if (isLeft) leftOffset += width;\n x += width;\n });\n let rightOffset = 0;\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n if (columns[i].pinned !== 'right') break;\n columns[i].offset = rightOffset;\n rightOffset += columns[i].width;\n }\n return { columns, totalWidth: x, hasPinning, leftCount: left.length, rightCount: right.length };\n }, [\n checkboxSelection,\n getDetailPanelContent,\n pinnedColumns,\n disableColumnPinning,\n visibleUserColumns,\n groupingColumn,\n viewportWidth,\n columnWidths,\n measureHeaderWidth,\n ]);\n\n const allDisplayColumnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n layout.columns.forEach((c) => map.set(c.col.field, c.col));\n if (groupingColumn) map.set(GROUPING_COLUMN_FIELD, groupingColumn);\n return map;\n }, [layout.columns, groupingColumn]);\n\n const getColumn = React.useCallback(\n (field: string): MGHGridColDef<R> | undefined =>\n columnsByField.get(field) ?? (allDisplayColumnsByField.get(field) as any),\n [columnsByField, allDisplayColumnsByField]\n );\n\n /* ------------------------------------------------------------------ filtering */\n\n const activeFilters = React.useMemo(() => {\n const out: Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }> = [];\n filterModel.items.forEach((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.filterable === false) return;\n const operator = getColumnFilterOperators(col).find((op) => op.value === item.operator);\n if (!operator) return;\n const fn = operator.getApplyFilterFn(item, col);\n if (fn) out.push({ col, fn });\n });\n return out;\n }, [filterModel.items, columnsByField]);\n\n const quickFilterValues = React.useMemo(\n () => (filterModel.quickFilterValues ?? []).map((v) => String(v).trim()).filter((v) => v !== ''),\n [filterModel.quickFilterValues]\n );\n\n const quickFilterColumns = React.useMemo(() => {\n const base = filterModel.quickFilterExcludeHiddenColumns ? visibleUserColumns : orderedUserColumns;\n return base.filter((col) => col.filterable !== false && col.type !== 'actions');\n }, [filterModel.quickFilterExcludeHiddenColumns, visibleUserColumns, orderedUserColumns]);\n\n const filteredEntries = React.useMemo(() => {\n if (activeFilters.length === 0 && quickFilterValues.length === 0) return rowEntries;\n const logicAnd = (filterModel.logicOperator ?? 'and') === 'and';\n const quickAnd = (filterModel.quickFilterLogicOperator ?? 'and') === 'and';\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const quickFns = quickFilterValues.map((needle) => {\n const lowered = needle.toLowerCase();\n const perColumn = quickFilterColumns.map((col) => {\n if (col.getApplyQuickFilterFn) {\n const custom = col.getApplyQuickFilterFn(needle, col, apiRefLocal);\n return custom ? { col, fn: custom } : null;\n }\n const fn: MGHGridApplyFilterFn<R> = (value, row) => {\n if (isNil(value)) return false;\n const formatted = formattedValueToString(getFormattedValue(value, row, col, apiRefLocal)).toLowerCase();\n if (formatted.indexOf(lowered) !== -1) return true;\n const raw = typeof value === 'object' ? '' : String(value).toLowerCase();\n return raw.indexOf(lowered) !== -1;\n };\n return { col, fn };\n });\n const active = perColumn.filter(Boolean) as Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }>;\n return (row: R) => active.some(({ col, fn }) => fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal));\n });\n return rowEntries.filter(({ row }) => {\n if (activeFilters.length > 0) {\n const results = activeFilters.map(({ col, fn }) =>\n fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal)\n );\n const pass = logicAnd ? results.every(Boolean) : results.some(Boolean);\n if (!pass) return false;\n }\n if (quickFns.length > 0) {\n const results = quickFns.map((fn) => fn(row));\n return quickAnd ? results.every(Boolean) : results.some(Boolean);\n }\n return true;\n });\n }, [\n rowEntries,\n activeFilters,\n quickFilterValues,\n quickFilterColumns,\n filterModel.logicOperator,\n filterModel.quickFilterLogicOperator,\n ]);\n\n /* ------------------------------------------------------------------ sorting */\n\n const compareEntries = React.useMemo(() => {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sorters = sortModel\n .filter((item) => item.sort && item.field !== GROUPING_COLUMN_FIELD)\n .map((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.sortable === false) return null;\n return {\n col,\n dir: item.sort === 'desc' ? -1 : 1,\n comparator: col.sortComparator ?? getDefaultComparator(col.type),\n };\n })\n .filter(Boolean) as Array<{ col: MGHGridColDef<R>; dir: number; comparator: any }>;\n if (sorters.length === 0) return null;\n return (a: RowEntry<R>, b: RowEntry<R>) => {\n for (let i = 0; i < sorters.length; i += 1) {\n const { col, dir, comparator } = sorters[i];\n const v1 = getCellValue(a.row, col, apiRefLocal);\n const v2 = getCellValue(b.row, col, apiRefLocal);\n const result = comparator(\n v1,\n v2,\n { id: a.id, field: col.field, value: v1, row: a.row, api: apiRefLocal },\n { id: b.id, field: col.field, value: v2, row: b.row, api: apiRefLocal }\n );\n if (result !== 0) return result * dir;\n }\n return 0;\n };\n }, [sortModel, columnsByField]);\n\n const sortEntries = React.useCallback(\n (entries: RowEntry<R>[]) => {\n if (!compareEntries) return entries;\n return entries\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => compareEntries(a.entry, b.entry) || a.index - b.index)\n .map((item) => item.entry);\n },\n [compareEntries]\n );\n\n /* ------------------------------------------------------------------ grouping + display rows */\n\n const aggregationFunctions = React.useMemo(\n () => ({ ...BUILT_IN_AGGREGATION_FUNCTIONS, ...aggregationFunctionsProp }),\n [aggregationFunctionsProp]\n );\n const aggregationActive = !disableAggregation && Object.keys(aggregationModel).length > 0;\n\n const isGroupExpanded = React.useCallback(\n (node: GroupTreeNode<R>) => {\n const override = groupExpansion.get(node.id);\n if (override !== undefined) return override;\n if (isGroupExpandedByDefault) {\n return isGroupExpandedByDefault({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: [],\n leafIds: [],\n isExpanded: false,\n });\n }\n return defaultGroupingExpansionDepth === -1 || node.depth < defaultGroupingExpansionDepth;\n },\n [groupExpansion, isGroupExpandedByDefault, defaultGroupingExpansionDepth]\n );\n\n const processed = React.useMemo(() => {\n const nodesById = new Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>();\n const groupsById = new Map<MGHGridRowId, GroupTreeNode<R>>();\n if (!groupingActive) {\n const sorted = sortEntries(filteredEntries);\n const displayRows: DisplayRow<R>[] = sorted.map((entry) => {\n const node: MGHGridLeafNode = { type: 'leaf', id: entry.id, depth: 0, parent: null };\n nodesById.set(entry.id, node);\n return { id: entry.id, type: 'leaf', row: entry.row, node, depth: 0 };\n });\n return { displayRows, sortedLeaves: sorted, nodesById, groupsById, tree: [] as GroupTreeNode<R>[] };\n }\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n let tree = buildGroupTree(filteredEntries, groupingFields, columnsByField, apiRefLocal);\n const groupingSort = sortModel.find((item) => item.field === GROUPING_COLUMN_FIELD && item.sort);\n const compareGroups = (depth: number) => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return null;\n const sortItem = groupingSort ?? sortModel.find((item) => item.field === field && item.sort);\n if (!sortItem) return null;\n const comparator = col.sortComparator ?? getDefaultComparator(col.type);\n const dir = sortItem.sort === 'desc' ? -1 : 1;\n return (a: GroupTreeNode<R>, b: GroupTreeNode<R>) =>\n comparator(\n a.groupingKey,\n b.groupingKey,\n { id: a.id, field, value: a.groupingKey, row: a.descendants[0]?.row, api: apiRefLocal },\n { id: b.id, field, value: b.groupingKey, row: b.descendants[0]?.row, api: apiRefLocal }\n ) * dir;\n };\n tree = sortGroupTree(tree, compareGroups, sortEntries);\n const displayRows = flattenGroupTree(tree, isGroupExpanded, nodesById, groupsById);\n return { displayRows, sortedLeaves: collectTreeLeaves(tree), nodesById, groupsById, tree };\n }, [groupingActive, filteredEntries, sortEntries, groupingFields, columnsByField, sortModel, isGroupExpanded]);\n\n const { displayRows, sortedLeaves, nodesById, groupsById } = processed;\n\n /* ------------------------------------------------------------------ pagination */\n\n const totalDisplayRows = displayRows.length;\n const paginate = pagination && !printing;\n const pageCount = pagination ? Math.max(1, Math.ceil(totalDisplayRows / Math.max(paginationModel.pageSize, 1))) : 1;\n const page = pagination ? clamp(paginationModel.page, 0, pageCount - 1) : 0;\n\n React.useEffect(() => {\n if (pagination && paginationModel.page !== page) {\n setPaginationModel({ ...paginationModel, page });\n }\n }, [pagination, paginationModel, page, setPaginationModel]);\n\n const pagedRows = React.useMemo(\n () =>\n paginate\n ? displayRows.slice(page * paginationModel.pageSize, (page + 1) * paginationModel.pageSize)\n : displayRows,\n [displayRows, paginate, page, paginationModel.pageSize]\n );\n\n /* ------------------------------------------------------------------ aggregation values */\n\n const footerAggregates = React.useMemo(() => {\n if (!aggregationActive || aggregationPosition === 'inline') return null;\n const rowsForFooter = sortedLeaves.map((entry) => entry.row);\n return aggregateRows(rowsForFooter, aggregationModel, columnsByField, aggregationFunctions, latest.current.api);\n }, [aggregationActive, aggregationPosition, sortedLeaves, aggregationModel, columnsByField, aggregationFunctions]);\n\n const groupAggregatesCache = React.useMemo(\n () => new Map<MGHGridRowId, Record<string, { value: any; fn: string }>>(),\n [pagedRows, aggregationModel, aggregationFunctions]\n );\n const getGroupAggregates = (group: GroupTreeNode<R>) => {\n if (!aggregationActive || aggregationPosition === 'footer') return undefined;\n let cached = groupAggregatesCache.get(group.id);\n if (!cached) {\n cached = aggregateRows(\n group.descendants.map((d) => d.row),\n aggregationModel,\n columnsByField,\n aggregationFunctions,\n latest.current.api\n );\n groupAggregatesCache.set(group.id, cached);\n }\n return cached;\n };\n\n /* ------------------------------------------------------------------ row heights + virtualization */\n\n const heights = React.useMemo(() => {\n const rowHeights: number[] = [];\n const detailHeights: number[] = [];\n const offsets: number[] = [];\n let total = 0;\n let hasAuto = autoHeight || disableVirtualization || printing;\n pagedRows.forEach((dr) => {\n let h = rowHeight;\n if (getRowHeight && dr.type === 'leaf' && dr.row) {\n const result = getRowHeight({ id: dr.id, model: dr.row, densityFactor });\n if (result === 'auto') hasAuto = true;\n else if (typeof result === 'number' && result > 0) h = result;\n }\n let d = 0;\n if (dr.type === 'leaf' && getDetailPanelContent && expandedDetailPanels.has(dr.id) && dr.row) {\n const dh = getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row })\n : DEFAULT_DETAIL_PANEL_HEIGHT;\n if (dh === 'auto') hasAuto = true;\n else d = dh;\n }\n rowHeights.push(h);\n detailHeights.push(d);\n offsets.push(total);\n total += h + d;\n });\n return { rowHeights, detailHeights, offsets, total, hasAuto };\n }, [\n pagedRows,\n rowHeight,\n getRowHeight,\n densityFactor,\n getDetailPanelContent,\n getDetailPanelHeight,\n expandedDetailPanels,\n autoHeight,\n disableVirtualization,\n printing,\n ]);\n\n const virtual = !heights.hasAuto;\n\n /* ------------------------------------------------------------------ print */\n\n const startPrint = (options: MGHGridPrintExportOptions = {}) => {\n if (printState) return;\n const resolved: MGHGridPrintExportOptions = {\n title: typeof header === 'string' ? header : undefined,\n ...options,\n };\n if (!cardRef.current || typeof window === 'undefined') return;\n setPrintState(resolved);\n };\n\n React.useEffect(() => {\n if (!printState) return undefined;\n // The un-virtualized rows are already committed when this effect runs; a short timeout lets the\n // browser lay them out first. (A timeout rather than rAF so it also fires in hidden/background tabs.)\n const timer = window.setTimeout(() => {\n if (!cardRef.current) return;\n printGridElement({\n cardElement: cardRef.current,\n options: printState,\n onDone: () => setPrintState(null),\n });\n }, 50);\n return () => window.clearTimeout(timer);\n }, [printState]);\n\n const virtualRange = React.useMemo(() => {\n const count = pagedRows.length;\n if (!virtual || count === 0) return { start: 0, end: count };\n const overscan = OVERSCAN_ROWS * rowHeight;\n const viewTop = Math.max(0, scrollTop - headerHeight - overscan);\n const viewBottom = scrollTop + Math.max(viewportHeight, rowHeight) + overscan;\n const { offsets } = heights;\n let lo = 0;\n let hi = count - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] + heights.rowHeights[mid] + heights.detailHeights[mid] < viewTop) lo = mid + 1;\n else hi = mid;\n }\n const start = lo;\n let end = start;\n while (end < count && offsets[end] < viewBottom) end += 1;\n return { start, end };\n }, [virtual, pagedRows.length, scrollTop, viewportHeight, rowHeight, headerHeight, heights]);\n\n const handleScroll = React.useCallback(() => {\n if (!latest.current.virtual) return;\n if (scrollRaf.current) return;\n scrollRaf.current = window.requestAnimationFrame(() => {\n scrollRaf.current = 0;\n if (scrollerRef.current) setScrollTop(scrollerRef.current.scrollTop);\n });\n }, []);\n\n React.useEffect(\n () => () => {\n if (scrollRaf.current) window.cancelAnimationFrame(scrollRaf.current);\n },\n []\n );\n\n /* ------------------------------------------------------------------ selection */\n\n const isRowSelectableFn = React.useCallback(\n (id: MGHGridRowId, row: R | null | undefined) => {\n if (!row) return false;\n if (!isRowSelectable) return true;\n return isRowSelectable({ id, row, columns: orderedUserColumns, api: latest.current.api });\n },\n [isRowSelectable, orderedUserColumns]\n );\n\n const selectionCandidates = React.useMemo(() => {\n const source: RowEntry<R>[] = checkboxSelectionVisibleOnly\n ? (pagedRows\n .filter((dr) => dr.type === 'leaf' && dr.row)\n .map((dr) => ({ id: dr.id, row: dr.row as R })) as RowEntry<R>[])\n : sortedLeaves;\n return source.filter((entry) => isRowSelectableFn(entry.id, entry.row)).map((entry) => entry.id);\n }, [checkboxSelectionVisibleOnly, pagedRows, sortedLeaves, isRowSelectableFn]);\n\n const selectedCandidateCount = React.useMemo(\n () => selectionCandidates.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0),\n [selectionCandidates, selectedIds]\n );\n const allCandidatesSelected = selectionCandidates.length > 0 && selectedCandidateCount === selectionCandidates.length;\n const someCandidatesSelected = selectedCandidateCount > 0 && !allCandidatesSelected;\n\n const updateSelection = React.useCallback(\n (updater: (prev: Set<MGHGridRowId>) => Set<MGHGridRowId>) => {\n setSelectedIds((prev) => {\n const next = updater(prev);\n return selectionModelsEqual({ type: 'include', ids: prev }, { type: 'include', ids: next }) ? prev : next;\n });\n },\n [setSelectedIds]\n );\n\n const selectRows = React.useCallback(\n (ids: MGHGridRowId[], isSelected = true, resetSelection = false) => {\n updateSelection((prev) => {\n const next = resetSelection ? new Set<MGHGridRowId>() : new Set(prev);\n ids.forEach((id) => {\n if (isSelected) {\n if (isRowSelectableFn(id, rowsById.get(id))) next.add(id);\n } else next.delete(id);\n });\n if (disableMultipleRowSelection && next.size > 1) {\n const lastId = ids[ids.length - 1];\n return new Set<MGHGridRowId>(isSelected && next.has(lastId) ? [lastId] : []);\n }\n return next;\n });\n },\n [updateSelection, isRowSelectableFn, rowsById, disableMultipleRowSelection]\n );\n\n React.useEffect(() => {\n if (keepNonExistentRowsSelected || selectedIds.size === 0) return;\n let changed = false;\n const next = new Set<MGHGridRowId>();\n selectedIds.forEach((id) => {\n if (rowsById.has(id)) next.add(id);\n else changed = true;\n });\n if (changed) setSelectedIds(next);\n }, [rowsById, keepNonExistentRowsSelected, selectedIds, setSelectedIds]);\n\n const toggleAllCandidates = () => {\n if (allCandidatesSelected) selectRows(selectionCandidates, false);\n else selectRows(selectionCandidates, true);\n };\n\n const handleRowSelectionClick = (renderRow: RenderRow<R>, event: React.MouseEvent) => {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const allSelected = leafIds.every((id) => selectedIds.has(id));\n selectRows(leafIds, !allSelected, false);\n return;\n }\n if (renderRow.kind !== 'leaf') return;\n const id = renderRow.id;\n if (!isRowSelectableFn(id, renderRow.row)) return;\n const multiple = !disableMultipleRowSelection;\n if (event.shiftKey && multiple && lastClickedIdRef.current !== null) {\n const ids = pagedRows.filter((dr) => dr.type === 'leaf').map((dr) => dr.id);\n const from = ids.indexOf(lastClickedIdRef.current);\n const to = ids.indexOf(id);\n if (from !== -1 && to !== -1) {\n const [a, b] = from < to ? [from, to] : [to, from];\n selectRows(ids.slice(a, b + 1), true, !checkboxSelection && !event.ctrlKey && !event.metaKey);\n return;\n }\n }\n lastClickedIdRef.current = id;\n const isSelected = selectedIds.has(id);\n const resetSelection = !checkboxSelection && !event.ctrlKey && !event.metaKey;\n if (resetSelection) {\n if (isSelected && selectedIds.size === 1) selectRows([id], false, true);\n else selectRows([id], true, true);\n } else {\n selectRows([id], !isSelected, false);\n }\n };\n\n /* ------------------------------------------------------------------ sorting helpers */\n\n const sortColumn = (field: string, direction?: MGHGridSortDirection, allowMultiple = false) => {\n const col = getColumn(field);\n if (!col || col.sortable === false || disableColumnSorting) return;\n const current = sortModel.find((item) => item.field === field);\n let next: MGHGridSortDirection;\n if (direction === undefined) {\n const order = col.sortingOrder ?? sortingOrder;\n const index = order.indexOf(current?.sort ?? null);\n next = order[(index + 1) % order.length];\n } else {\n next = direction;\n }\n let model: MGHGridSortModel;\n if (allowMultiple && !disableMultipleColumnsSorting) {\n model = sortModel.filter((item) => item.field !== field);\n if (next)\n model = current\n ? sortModel.map((item) => (item.field === field ? { field, sort: next } : item))\n : model.concat([{ field, sort: next }]);\n } else {\n model = next ? [{ field, sort: next }] : [];\n }\n setSortModel(model);\n };\n\n /* ------------------------------------------------------------------ column helpers */\n\n const persistOrder = (fields: string[]) => {\n if (columnOrderStorageKey) writeLocalStorage(columnOrderStorageKey, fields);\n };\n\n const persistWidths = (widths: Record<string, number>) => {\n if (columnWidthStorageKey) writeLocalStorage(columnWidthStorageKey, widths);\n };\n\n const setColumnIndex = (field: string, targetIndex: number, event: React.DragEvent | null = null) => {\n const fields = orderedUserColumns.map((c) => c.field);\n const oldIndex = fields.indexOf(field);\n if (oldIndex === -1) return;\n const next = moveItem(fields, oldIndex, clamp(targetIndex, 0, fields.length - 1));\n setOrderedFields(next);\n persistOrder(next);\n const col = columnsByField.get(field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex, oldIndex }, event, getDetails());\n };\n\n const setColumnWidth = (field: string, width: number) => {\n const col = getColumn(field);\n if (!col) return;\n const clamped = clamp(width, col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n setColumnWidths((prev) => {\n const next = { ...prev, [field]: clamped };\n persistWidths(next);\n return next;\n });\n onColumnWidthChange?.({ colDef: col, width: clamped }, getDetails());\n };\n\n const autosizeColumns = (options: { columns?: string[]; includeHeaders?: boolean; expand?: boolean } = {}) => {\n const includeHeaders = options.includeHeaders ?? true;\n const targets = layout.columns.filter(\n (lc) => !isInternalField(lc.col.field) && (!options.columns || options.columns.indexOf(lc.col.field) !== -1)\n );\n if (targets.length === 0) return;\n const sample = sortedLeaves.slice(0, 500);\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const next = { ...columnWidths };\n targets.forEach(({ col }) => {\n let max = includeHeaders ? measureHeaderWidth(col) : 0;\n sample.forEach((entry) => {\n const value = getCellValue(entry.row, col, apiRefLocal);\n const text = formattedValueToString(getFormattedValue(value, entry.row, col, apiRefLocal, entry.id));\n const w = measureText(text, cellFont) + 24;\n if (w > max) max = w;\n });\n next[col.field] = clamp(Math.ceil(max), col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n });\n setColumnWidths(next);\n persistWidths(next);\n };\n\n const pinColumn = (field: string, side: MGHGridPinnedSide) => {\n if (disableColumnPinning) return;\n const left = (pinnedColumns.left ?? []).filter((f) => f !== field);\n const right = (pinnedColumns.right ?? []).filter((f) => f !== field);\n if (side === 'left') left.push(field);\n else right.unshift(field);\n setPinnedColumns({ left, right });\n };\n\n const unpinColumn = (field: string) => {\n setPinnedColumns({\n left: (pinnedColumns.left ?? []).filter((f) => f !== field),\n right: (pinnedColumns.right ?? []).filter((f) => f !== field),\n });\n };\n\n const isColumnPinned = (field: string): MGHGridPinnedSide | false => {\n if (disableColumnPinning) return false;\n if ((pinnedColumns.left ?? []).indexOf(field) !== -1) return 'left';\n if ((pinnedColumns.right ?? []).indexOf(field) !== -1) return 'right';\n return false;\n };\n\n /* ------------------------------------------------------------------ filter helpers */\n\n const upsertFilterItems = (items: MGHGridFilterItem[]) => {\n let nextItems = filterModel.items.slice();\n items.forEach((item) => {\n const withId =\n item.id === undefined ? { ...item, id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } : item;\n const index = nextItems.findIndex((existing) => existing.id !== undefined && existing.id === withId.id);\n if (index === -1) nextItems.push(withId);\n else nextItems[index] = withId;\n });\n if (disableMultipleColumnsFiltering && nextItems.length > 1) nextItems = nextItems.slice(-1);\n setFilterModel({ ...filterModel, items: nextItems });\n };\n\n const deleteFilterItem = (item: MGHGridFilterItem) => {\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((existing) =>\n item.id !== undefined ? existing.id !== item.id : existing !== item\n ),\n });\n };\n\n const showPreferences = (panel: 'columns' | 'filters', anchorEl?: HTMLElement | null, targetField?: string) => {\n setColumnMenu(null);\n setPreferencePanel({\n open: true,\n openedPanelValue: panel,\n targetField,\n anchorEl: anchorEl ?? toolbarRef.current ?? rootRef.current,\n });\n };\n\n const hidePreferences = React.useCallback(() => {\n setPreferencePanel((prev) => (prev.open ? { open: false, anchorEl: null } : prev));\n }, []);\n\n /* ------------------------------------------------------------------ editing */\n\n const isCellEditableFn = (params: MGHGridCellParams<R>) => {\n if (!params.colDef.editable) return false;\n if (params.rowNode.type !== 'leaf') return false;\n return isCellEditable ? isCellEditable(params) : true;\n };\n\n const startCellEditMode = (id: MGHGridRowId, field: string) => {\n const row = rowsById.get(id);\n const col = getColumn(field);\n if (!row || !col) return;\n const params = buildCellParams(id, field, row, nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null });\n if (!isCellEditableFn(params)) return;\n setEditingCell({ id, field });\n setEditValue(params.value);\n setFocusedCell({ id, field });\n };\n\n const applyRowUpdate = (id: MGHGridRowId, newRow: R, oldRow: R) => {\n if (processRowUpdate) {\n Promise.resolve()\n .then(() => processRowUpdate(newRow, oldRow, { rowId: id }))\n .then((result) => setRowOverride(id, (result ?? newRow) as R))\n .catch((error) => {\n if (onProcessRowUpdateError) onProcessRowUpdateError(error);\n else console.error('MGHGrid: processRowUpdate failed', error);\n });\n } else {\n setRowOverride(id, newRow);\n }\n };\n\n const stopCellEditMode = (\n id: MGHGridRowId,\n field: string,\n ignoreModifications = false,\n reason: 'enterKeyDown' | 'escapeKeyDown' | 'cellFocusOut' | 'tabKeyDown' | 'api' = 'api'\n ) => {\n if (!editingCell || editingCell.id !== id || editingCell.field !== field) return;\n const row = rowsById.get(id);\n const col = getColumn(field);\n setEditingCell(null);\n if (!row || !col) return;\n if (!ignoreModifications) {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const parsed = col.valueParser\n ? col.valueParser(editValue, row, col, apiRefLocal)\n : parseEditValue(editValue, col);\n const currentValue = getCellValue(row, col, apiRefLocal);\n if (!Object.is(parsed, currentValue)) {\n const newRow = col.valueSetter\n ? col.valueSetter(parsed, row, col, apiRefLocal)\n : ({ ...row, [field]: parsed } as R);\n applyRowUpdate(id, newRow, row);\n }\n }\n onCellEditStop?.({ id, field, row, reason }, getDetails());\n pendingFocusRef.current = true;\n setFocusedCell({ id, field });\n };\n\n /* ------------------------------------------------------------------ detail panel & grouping helpers */\n\n const toggleDetailPanel = (id: MGHGridRowId) => {\n setExpandedDetailPanels((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const setRowChildrenExpansion = (id: MGHGridRowId, isExpanded: boolean) => {\n setGroupExpansion((prev) => {\n const next = new Map(prev);\n next.set(id, isExpanded);\n return next;\n });\n };\n\n const groupingKey = groupingFields.join('|');\n const previousGroupingKey = React.useRef(groupingKey);\n React.useEffect(() => {\n if (previousGroupingKey.current === groupingKey) return;\n previousGroupingKey.current = groupingKey;\n setGroupExpansion(new Map());\n }, [groupingKey]);\n\n /* ------------------------------------------------------------------ cell params */\n\n const buildCellParams = (id: MGHGridRowId, field: string, row: R, node: MGHGridRowNode): MGHGridCellParams<R> => {\n const col = getColumn(field) as MGHGridColDef<R>;\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const value = getCellValue(row, col, apiRefLocal);\n const formattedValue = getFormattedValue(value, row, col, apiRefLocal, id);\n const hasFocus = Boolean(focusedCell && focusedCell.id === id && focusedCell.field === field);\n const cellMode = editingCell && editingCell.id === id && editingCell.field === field ? 'edit' : 'view';\n return {\n id,\n field,\n value,\n formattedValue,\n row,\n rowNode: node,\n colDef: col,\n api: apiRefLocal,\n hasFocus,\n tabIndex: hasFocus ? 0 : -1,\n cellMode,\n isEditable: Boolean(col.editable) && node.type === 'leaf',\n };\n };\n\n const buildRowParams = (id: MGHGridRowId, row: R): MGHGridRowParams<R> => ({\n id,\n row,\n columns: orderedUserColumns,\n api: latest.current.api,\n });\n\n /* ------------------------------------------------------------------ keyboard navigation */\n\n React.useEffect(() => {\n if (!pendingFocusRef.current || !focusedCell || !rootRef.current) return;\n pendingFocusRef.current = false;\n const selector = `[data-mgh-row-id=\"${String(focusedCell.id).replace(/\"/g, '\\\\\"')}\"] [data-mgh-field=\"${focusedCell.field.replace(/\"/g, '\\\\\"')}\"]`;\n const el = rootRef.current.querySelector<HTMLElement>(selector);\n if (el && document.activeElement !== el && !el.contains(document.activeElement)) el.focus({ preventScroll: true });\n }, [focusedCell, virtualRange.start, virtualRange.end]);\n\n const scrollToIndexes = (params: { rowIndex?: number; colIndex?: number }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return false;\n if (params.rowIndex !== undefined && virtual) {\n const index = clamp(params.rowIndex, 0, Math.max(pagedRows.length - 1, 0));\n const top = heights.offsets[index] ?? 0;\n const bottom = top + (heights.rowHeights[index] ?? rowHeight);\n const visibleTop = scroller.scrollTop;\n const visibleBottom = scroller.scrollTop + scroller.clientHeight - headerHeight;\n if (top < visibleTop) scroller.scrollTop = top;\n else if (bottom > visibleBottom) scroller.scrollTop = bottom - (scroller.clientHeight - headerHeight);\n } else if (params.rowIndex !== undefined) {\n const el = scroller.querySelector(`[data-mgh-row-index=\"${params.rowIndex}\"]`) as HTMLElement | null | undefined;\n el?.scrollIntoView?.({ block: 'nearest' });\n }\n if (params.colIndex !== undefined) {\n const lc = layout.columns[clamp(params.colIndex, 0, layout.columns.length - 1)];\n if (lc && !lc.pinned) {\n const leftPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'left')\n .reduce((acc, c) => acc + c.width, 0);\n const rightPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'right')\n .reduce((acc, c) => acc + c.width, 0);\n const visibleLeft = scroller.scrollLeft + leftPinnedWidth;\n const visibleRight = scroller.scrollLeft + scroller.clientWidth - rightPinnedWidth;\n if (lc.x < visibleLeft) scroller.scrollLeft = lc.x - leftPinnedWidth;\n else if (lc.x + lc.width > visibleRight)\n scroller.scrollLeft = lc.x + lc.width - scroller.clientWidth + rightPinnedWidth;\n }\n }\n return true;\n };\n\n const moveFocus = (\n rowDelta: number,\n colDelta: number,\n absolute?: { row?: 'first' | 'last'; col?: 'first' | 'last' }\n ) => {\n if (pagedRows.length === 0 || layout.columns.length === 0) return;\n let rowIndex = focusedCell ? pagedRows.findIndex((dr) => dr.id === focusedCell.id) : -1;\n let colIndex = focusedCell ? layout.columns.findIndex((lc) => lc.col.field === focusedCell.field) : -1;\n if (rowIndex === -1) rowIndex = 0;\n if (colIndex === -1) colIndex = 0;\n if (absolute?.row === 'first') rowIndex = 0;\n else if (absolute?.row === 'last') rowIndex = pagedRows.length - 1;\n else rowIndex = clamp(rowIndex + rowDelta, 0, pagedRows.length - 1);\n if (absolute?.col === 'first') colIndex = 0;\n else if (absolute?.col === 'last') colIndex = layout.columns.length - 1;\n else colIndex = clamp(colIndex + colDelta, 0, layout.columns.length - 1);\n const target = { id: pagedRows[rowIndex].id, field: layout.columns[colIndex].col.field };\n pendingFocusRef.current = true;\n setFocusedCell(target);\n scrollToIndexes({ rowIndex, colIndex });\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (editingCell) return;\n const target = event.target as HTMLElement;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'SELECT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'BUTTON')\n ) {\n return;\n }\n const pageRows = Math.max(1, Math.floor(Math.max(viewportHeight - headerHeight, rowHeight) / rowHeight));\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1, 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1, 0);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(0, -1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(0, 1);\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(pageRows, 0);\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(-pageRows, 0);\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'first', col: 'first' } : { col: 'first' });\n break;\n case 'End':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'last', col: 'last' } : { col: 'last' });\n break;\n case 'Enter':\n case 'F2':\n if (focusedCell) {\n const node = nodesById.get(focusedCell.id);\n if (node?.type === 'group' && focusedCell.field === GROUPING_COLUMN_FIELD) {\n const group = groupsById.get(focusedCell.id);\n if (group) setRowChildrenExpansion(group.id, !isGroupExpanded(group));\n } else {\n event.preventDefault();\n startCellEditMode(focusedCell.id, focusedCell.field);\n }\n }\n break;\n case ' ':\n if (focusedCell && (checkboxSelection || !disableRowSelectionOnClick)) {\n const dr = pagedRows.find((r) => r.id === focusedCell.id);\n if (dr && dr.type === 'leaf' && dr.row) {\n event.preventDefault();\n selectRows([dr.id], !selectedIds.has(dr.id), false);\n }\n }\n break;\n case 'Escape':\n if (preferencePanel.open) hidePreferences();\n if (columnMenu) setColumnMenu(null);\n break;\n default:\n if (\n (event.ctrlKey || event.metaKey) &&\n event.key.toLowerCase() === 'a' &&\n checkboxSelection &&\n !disableMultipleRowSelection\n ) {\n event.preventDefault();\n selectRows(selectionCandidates, true);\n }\n }\n };\n\n /* ------------------------------------------------------------------ drag & drop (reorder) */\n\n const canReorder = (col: MGHGridColDef) => !disableColumnReorder && !col.disableReorder && !isInternalField(col.field);\n\n const handleDrop = (targetLc: ColumnLayout, event: React.DragEvent) => {\n event.preventDefault();\n const current = drag;\n setDrag(null);\n if (!current || current.field === targetLc.col.field) return;\n const sourceLc = layout.columns.find((lc) => lc.col.field === current.field);\n if (!sourceLc || sourceLc.pinned !== targetLc.pinned || !canReorder(targetLc.col)) return;\n const side = current.side;\n if (sourceLc.pinned) {\n const key = sourceLc.pinned;\n const list = (pinnedColumns[key] ?? []).slice();\n const from = list.indexOf(current.field);\n let to = list.indexOf(targetLc.col.field);\n if (from === -1 || to === -1) return;\n list.splice(from, 1);\n to = list.indexOf(targetLc.col.field);\n list.splice(side === 'right' ? to + 1 : to, 0, current.field);\n setPinnedColumns({ ...pinnedColumns, [key]: list });\n return;\n }\n const fields = orderedUserColumns.map((c) => c.field);\n const from = fields.indexOf(current.field);\n const without = fields.filter((f) => f !== current.field);\n let to = without.indexOf(targetLc.col.field);\n if (side === 'right') to += 1;\n without.splice(to, 0, current.field);\n setOrderedFields(without);\n persistOrder(without);\n const col = columnsByField.get(current.field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex: to, oldIndex: from }, event, getDetails());\n };\n\n /* ------------------------------------------------------------------ resize */\n\n const resizeRef = React.useRef<{\n field: string;\n startX: number;\n startWidth: number;\n lastWidth: number;\n min: number;\n max: number;\n } | null>(null);\n\n const handleResizeStart = (lc: ColumnLayout, event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n field: lc.col.field,\n startX: event.clientX,\n startWidth: lc.width,\n lastWidth: lc.width,\n min: lc.col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n max: lc.col.maxWidth ?? Infinity,\n };\n setResizingField(lc.col.field);\n const onMove = (e: PointerEvent) => {\n const r = resizeRef.current;\n if (!r) return;\n const width = clamp(r.startWidth + (e.clientX - r.startX), r.min, r.max);\n r.lastWidth = width;\n setColumnWidths((prev) => (prev[r.field] === width ? prev : { ...prev, [r.field]: width }));\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n const r = resizeRef.current;\n resizeRef.current = null;\n setResizingField(null);\n if (!r) return;\n const next = { ...(latest.current.columnWidths as Record<string, number>), [r.field]: r.lastWidth };\n setColumnWidths(next);\n persistWidths(next);\n const col = latest.current.getColumn(r.field);\n if (col && r.lastWidth !== r.startWidth)\n onColumnWidthChange?.({ colDef: col, width: r.lastWidth }, getDetails());\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /* ------------------------------------------------------------------ state snapshot & API */\n\n const filterCount = activeFilters.length;\n const rowCount = groupingActive ? totalDisplayRows : filteredEntries.length;\n\n const state = React.useMemo<MGHGridState>(\n () => ({\n sortModel,\n filterModel,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n pageCount,\n rowCount,\n totalRowCount: rowEntries.length,\n columnVisibilityModel,\n orderedFields: orderedUserColumns.map((c) => c.field),\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n rowSelectionModel: { type: 'include', ids: selectedIds },\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel: {\n open: preferencePanel.open,\n openedPanelValue: preferencePanel.openedPanelValue,\n targetField: preferencePanel.targetField,\n },\n filterCount,\n quickFilterValues,\n }),\n [\n sortModel,\n filterModel,\n page,\n paginationModel.pageSize,\n pageCount,\n rowCount,\n rowEntries.length,\n columnVisibilityModel,\n orderedUserColumns,\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n selectedIds,\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel.open,\n preferencePanel.openedPanelValue,\n preferencePanel.targetField,\n filterCount,\n quickFilterValues,\n ]\n );\n\n latest.current = {\n api: apiObject,\n state,\n rowsById,\n rowEntries,\n nodesById,\n groupsById,\n sortedLeaves,\n pagedRows,\n getRowId,\n setRowOverride,\n orderedUserColumns,\n visibleUserColumns,\n getColumn,\n columnVisibilityModel,\n setColumnVisibilityModel,\n setColumnWidth,\n setColumnIndex,\n columnWidths,\n autosizeColumns,\n pinColumn,\n unpinColumn,\n isColumnPinned,\n pinnedColumns,\n setPinnedColumns,\n sortModel,\n setSortModel,\n sortColumn,\n filterModel,\n setFilterModel,\n upsertFilterItems,\n deleteFilterItem,\n showPreferences,\n hidePreferences,\n selectedIds,\n setSelectedIds,\n selectRows,\n isRowSelectableFn,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n setPaginationModel,\n setDensity,\n toggleDetailPanel,\n expandedDetailPanels,\n setExpandedDetailPanels,\n rowGroupingModel,\n setRowGroupingModel,\n setRowChildrenExpansion,\n aggregationModel,\n setAggregationModel,\n startCellEditMode,\n stopCellEditMode,\n editingCell,\n setEditValue,\n buildCellParams,\n setFocusedCell,\n scrollToIndexes,\n forceUpdate,\n virtual,\n startPrint,\n };\n\n if (apiRef) apiRef.current = apiObject;\n\n React.useEffect(() => {\n onStateChange?.(state, { api: apiObject });\n }, [state, onStateChange, apiObject]);\n\n /* ------------------------------------------------------------------ context */\n\n const rootProps = React.useMemo<MGHGridRootProps>(\n () => ({\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n }),\n [\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n ]\n );\n\n const contextValue = React.useMemo<MGHGridContextValue>(\n () => ({\n api: apiObject,\n state,\n localeText,\n themeMode,\n rootProps,\n columns: orderedUserColumns,\n visibleColumns: visibleUserColumns,\n }),\n [apiObject, state, localeText, themeMode, rootProps, orderedUserColumns, visibleUserColumns]\n );\n\n /* ------------------------------------------------------------------ rendering: cells */\n\n const renderEditor = (params: MGHGridCellParams<R>) => {\n const col = params.colDef;\n const commit = (reason: 'enterKeyDown' | 'cellFocusOut' | 'tabKeyDown') =>\n stopCellEditMode(params.id, params.field, false, reason);\n const cancel = () => stopCellEditMode(params.id, params.field, true, 'escapeKeyDown');\n const keyHandler = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n commit('enterKeyDown');\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n } else if (event.key === 'Tab') {\n commit('tabKeyDown');\n } else {\n event.stopPropagation();\n }\n };\n if (col.renderEditCell) {\n return col.renderEditCell({\n ...params,\n editValue,\n onValueChange: setEditValue,\n commit: () => commit('enterKeyDown'),\n cancel,\n });\n }\n const common = {\n autoFocus: true,\n onKeyDown: keyHandler,\n onBlur: () => commit('cellFocusOut'),\n onClick: (event: React.MouseEvent) => event.stopPropagation(),\n };\n switch (col.type) {\n case 'boolean':\n return (\n <Checkbox\n {...common}\n checked={Boolean(editValue)}\n onChange={(event) => setEditValue(event.target.checked)}\n />\n );\n case 'singleSelect': {\n const options = resolveValueOptions(col, params.row, params.id);\n return (\n <Select\n {...common}\n size=\"small\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(col, o)) === event.target.value);\n setEditValue(match !== undefined ? getOptionValue(col, match) : event.target.value);\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(col, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(col, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'number':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"number\"\n value={editValue === undefined || editValue === null ? '' : editValue}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n case 'date':\n case 'dateTime':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type={col.type === 'date' ? 'date' : 'datetime-local'}\n value={\n typeof editValue === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(editValue)\n ? editValue\n : toDateInputValue(editValue, col.type === 'dateTime')\n }\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n default:\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"text\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n }\n };\n\n const renderCellContent = (lc: ColumnLayout, renderRow: RenderRow<R>): React.ReactNode => {\n const { col } = lc;\n const field = col.field;\n\n if (field === CHECKBOX_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const selectedCount = leafIds.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0);\n return (\n <Checkbox\n checked={leafIds.length > 0 && selectedCount === leafIds.length}\n indeterminate={selectedCount > 0 && selectedCount < leafIds.length}\n label={localeText.checkboxSelectionSelectRow}\n onClick={(event) => event.stopPropagation()}\n onChange={() => selectRows(leafIds, selectedCount !== leafIds.length, false)}\n />\n );\n }\n if (renderRow.kind !== 'leaf') return null;\n const selectable = isRowSelectableFn(renderRow.id, renderRow.row);\n const checked = selectedIds.has(renderRow.id);\n return (\n <Checkbox\n checked={checked}\n disabled={!selectable}\n label={checked ? localeText.checkboxSelectionUnselectRow : localeText.checkboxSelectionSelectRow}\n tabIndex={-1}\n onClick={(event) => event.stopPropagation()}\n onChange={() => {\n lastClickedIdRef.current = renderRow.id;\n selectRows([renderRow.id], !checked, disableMultipleRowSelection);\n }}\n />\n );\n }\n\n if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n if (renderRow.kind !== 'leaf' || !renderRow.row) return null;\n const expanded = expandedDetailPanels.has(renderRow.id);\n const content = getDetailPanelContent?.(buildRowParams(renderRow.id, renderRow.row));\n if (content === null || content === undefined || content === false) return null;\n return (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-detail-toggle', expanded && 'mgh-grid-detail-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n toggleDetailPanel(renderRow.id);\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n );\n }\n\n if (field === GROUPING_COLUMN_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const group = renderRow.group;\n const expanded = isGroupExpanded(group);\n const hideCount = (groupingColDef as any)?.hideDescendantCount;\n return (\n <div className=\"mgh-grid-group-cell\" style={{ paddingLeft: renderRow.depth * 20 }}>\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-group-toggle', expanded && 'mgh-grid-group-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setRowChildrenExpansion(group.id, !expanded);\n }}\n >\n <ChevronRightIcon />\n </IconButton>\n <span className=\"mgh-grid-group-label\" title={group.groupingLabel}>\n {group.groupingLabel}\n </span>\n {!hideCount && <span className=\"mgh-grid-group-count\">({group.descendants.length})</span>}\n </div>\n );\n }\n return null;\n }\n\n if (renderRow.kind === 'group' || renderRow.kind === 'footer') {\n const agg = renderRow.aggregates?.[field];\n if (!agg || isNil(agg.value)) return null;\n const fn = aggregationFunctions[agg.fn];\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sampleRow = (renderRow.group?.descendants[0]?.row ?? latest.current.sortedLeaves[0]?.row ?? {}) as R;\n const formatted = fn?.valueFormatter\n ? fn.valueFormatter(agg.value)\n : col.valueFormatter\n ? col.valueFormatter(agg.value, sampleRow, col as MGHGridColDef<R>, apiRefLocal)\n : defaultFormatValue(agg.value, col);\n return (\n <>\n <span className=\"mgh-grid-aggregation-label\">{fn?.label ?? agg.fn}</span>\n <span className=\"mgh-grid-cell-text\">{formattedValueToString(formatted)}</span>\n </>\n );\n }\n\n if (!renderRow.row) return null;\n const params = buildCellParams(renderRow.id, field, renderRow.row, renderRow.node);\n\n if (params.cellMode === 'edit') return renderEditor(params);\n\n if (col.renderCell) return col.renderCell(params);\n\n if (col.type === 'actions') {\n const actions = col.getActions ? col.getActions(buildRowParams(renderRow.id, renderRow.row)) : [];\n return <ActionsCell actions={actions} themeMode={themeMode} moreLabel={localeText.actionsCellMore} />;\n }\n\n if (col.type === 'boolean') {\n if (isNil(params.value)) return null;\n return params.value ? (\n <CheckIcon aria-label={localeText.booleanCellTrueLabel} />\n ) : (\n <CloseIcon aria-label={localeText.booleanCellFalseLabel} />\n );\n }\n\n const formatted = params.formattedValue;\n if (formatted === null || formatted === undefined) return null;\n if (React.isValidElement(formatted)) return formatted;\n const text = formattedValueToString(formatted);\n return (\n <span className=\"mgh-grid-cell-text\" title={text.length > 20 ? text : undefined}>\n {text}\n </span>\n );\n };\n\n const cellStyle = (lc: ColumnLayout): React.CSSProperties => ({\n width: lc.width,\n minWidth: lc.width,\n maxWidth: lc.width,\n left: lc.pinned === 'left' ? lc.offset : undefined,\n right: lc.pinned === 'right' ? lc.offset : undefined,\n });\n\n const pinnedClasses = (lc: ColumnLayout, prefix: string) =>\n cx(\n lc.pinned === 'left' && `${prefix}--pinned-left`,\n lc.pinned === 'right' && `${prefix}--pinned-right`,\n lc.isLastLeft && layout.hasPinning && `${prefix}--pinned-left-last`,\n lc.isFirstRight && `${prefix}--pinned-right-first`\n );\n\n const renderCell = (lc: ColumnLayout, renderRow: RenderRow<R>, isAutoRow: boolean) => {\n const { col } = lc;\n const field = col.field;\n const isFocused = Boolean(focusedCell && focusedCell.id === renderRow.id && focusedCell.field === field);\n const isEditing = Boolean(editingCell && editingCell.id === renderRow.id && editingCell.field === field);\n const isAggregation =\n (renderRow.kind === 'group' || renderRow.kind === 'footer') && Boolean(renderRow.aggregates?.[field]);\n const params =\n renderRow.kind === 'leaf' && renderRow.row\n ? buildCellParams(renderRow.id, field, renderRow.row, renderRow.node)\n : null;\n const editable = params ? isCellEditableFn(params) : false;\n const customClass =\n params && col.cellClassName\n ? typeof col.cellClassName === 'function'\n ? col.cellClassName(params)\n : col.cellClassName\n : undefined;\n const isCheckbox = field === CHECKBOX_FIELD;\n const isDetailToggle = field === DETAIL_PANEL_TOGGLE_FIELD;\n return (\n <div\n key={field}\n role=\"gridcell\"\n data-mgh-field={field}\n data-mgh-colindex={layout.columns.indexOf(lc)}\n tabIndex={isFocused ? 0 : -1}\n aria-selected={renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : undefined}\n className={cx(\n 'mgh-grid-cell',\n `mgh-grid-cell--align-${col.align ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-cell'),\n isFocused && !isEditing && 'mgh-grid-cell--focused',\n isEditing && 'mgh-grid-cell--editing',\n editable && !isEditing && 'mgh-grid-cell--editable',\n col.type === 'boolean' && 'mgh-grid-cell--boolean',\n col.type === 'actions' && 'mgh-grid-cell--actions',\n isCheckbox && 'mgh-grid-cell--checkbox',\n isDetailToggle && 'mgh-grid-cell--detail-toggle',\n isAggregation && 'mgh-grid-cell--aggregation',\n customClass\n )}\n style={cellStyle(lc)}\n onMouseDown={() => {\n if (renderRow.kind === 'leaf' || renderRow.kind === 'group') {\n if (!isFocused) setFocusedCell({ id: renderRow.id, field });\n }\n }}\n onClick={(event) => {\n if (params && onCellClick) onCellClick(params, event, getDetails());\n }}\n onDoubleClick={(event) => {\n if (params) {\n onCellDoubleClick?.(params, event, getDetails());\n if (editable && !isEditing) {\n event.stopPropagation();\n startCellEditMode(renderRow.id, field);\n }\n }\n }}\n >\n {renderCellContent(lc, renderRow)}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: rows */\n\n const rowIsClickable = Boolean(onRowClick || onRowDoubleClick || !disableRowSelectionOnClick);\n\n const renderRowElement = (\n renderRow: RenderRow<R>,\n options: { height?: number; index: number; isFirst: boolean; isLast: boolean; isAuto: boolean }\n ) => {\n const isSelected = renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : false;\n const customClass =\n renderRow.kind === 'leaf' && renderRow.row && getRowClassName\n ? getRowClassName({\n ...buildRowParams(renderRow.id, renderRow.row),\n indexRelativeToCurrentPage: options.index,\n isFirstVisible: options.isFirst,\n isLastVisible: options.isLast,\n rowNode: renderRow.node,\n })\n : undefined;\n return (\n <div\n role=\"row\"\n aria-rowindex={options.index + 2}\n aria-selected={renderRow.kind === 'leaf' ? isSelected : undefined}\n data-mgh-row-id={String(renderRow.id)}\n data-mgh-row-index={options.index}\n className={cx(\n 'mgh-grid-row',\n isSelected && 'mgh-grid-row--selected',\n rowIsClickable && renderRow.kind === 'leaf' && 'mgh-grid-row--clickable',\n renderRow.kind === 'group' && 'mgh-grid-row--group',\n renderRow.kind === 'pinnedRow' && 'mgh-grid-row--pinned',\n renderRow.kind === 'footer' && 'mgh-grid-row--footer',\n options.isAuto && 'mgh-grid-row--auto-height',\n customClass\n )}\n style={{\n width: layout.totalWidth,\n height: options.isAuto ? undefined : options.height,\n minHeight: options.isAuto ? rowHeight : undefined,\n }}\n onClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n if (!disableRowSelectionOnClick) handleRowSelectionClick(renderRow, event);\n onRowClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n } else if (renderRow.kind === 'group' && renderRow.group) {\n setRowChildrenExpansion(renderRow.group.id, !isGroupExpanded(renderRow.group));\n }\n }}\n onDoubleClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n onRowDoubleClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n }\n }}\n >\n {layout.columns.map((lc) => renderCell(lc, renderRow, options.isAuto))}\n <div className=\"mgh-grid-row-filler\" />\n </div>\n );\n };\n\n const toRenderRow = (dr: DisplayRow<R>): RenderRow<R> => ({\n id: dr.id,\n kind: dr.type,\n row: dr.row,\n node: dr.node,\n depth: dr.depth,\n group: dr.group,\n aggregates: dr.type === 'group' && dr.group ? getGroupAggregates(dr.group) : undefined,\n });\n\n const renderBodyRows = () => {\n const { start, end } = virtualRange;\n const items: React.ReactNode[] = [];\n for (let i = start; i < end; i += 1) {\n const dr = pagedRows[i];\n const renderRow = toRenderRow(dr);\n const detailHeight = heights.detailHeights[i];\n const isExpanded =\n dr.type === 'leaf' && Boolean(dr.row) && Boolean(getDetailPanelContent) && expandedDetailPanels.has(dr.id);\n const detailContent = isExpanded && dr.row ? getDetailPanelContent?.(buildRowParams(dr.id, dr.row)) : null;\n const detailAuto =\n isExpanded && dr.row && getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row }) === 'auto'\n : false;\n const rowAuto =\n !virtual &&\n (getRowHeight && dr.type === 'leaf' && dr.row\n ? getRowHeight({ id: dr.id, model: dr.row, densityFactor }) === 'auto'\n : false);\n items.push(\n <div\n key={String(dr.id)}\n className=\"mgh-grid-row-block\"\n style={virtual ? { top: heights.offsets[i], width: layout.totalWidth } : { width: layout.totalWidth }}\n >\n {renderRowElement(renderRow, {\n height: heights.rowHeights[i],\n index: i,\n isFirst: i === 0,\n isLast: i === pagedRows.length - 1,\n isAuto: rowAuto,\n })}\n {isExpanded && detailContent !== null && detailContent !== undefined && detailContent !== false && (\n <div\n className=\"mgh-grid-detail-panel\"\n style={{\n height: detailAuto ? undefined : detailHeight || undefined,\n width: viewportWidth || undefined,\n }}\n onClick={(event) => event.stopPropagation()}\n >\n {detailContent}\n </div>\n )}\n </div>\n );\n }\n return items;\n };\n\n const renderPinnedRows = (list: R[] | undefined, position: 'top' | 'bottom') => {\n const items: React.ReactNode[] = [];\n (list ?? []).forEach((row, index) => {\n const id = getRowIdFromRow(row, getRowId);\n const renderRow: RenderRow<R> = {\n id,\n kind: 'pinnedRow',\n row,\n node: { type: 'pinnedRow', id, depth: 0, parent: null, position },\n depth: 0,\n };\n items.push(\n <React.Fragment key={String(id)}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: index,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n });\n if (position === 'bottom' && footerAggregates) {\n const renderRow: RenderRow<R> = {\n id: AGGREGATION_FOOTER_ID,\n kind: 'footer',\n row: null,\n node: { type: 'footer', id: AGGREGATION_FOOTER_ID, depth: 0, parent: null },\n depth: 0,\n aggregates: footerAggregates,\n };\n items.push(\n <React.Fragment key={AGGREGATION_FOOTER_ID}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: 0,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n }\n return items;\n };\n\n /* ------------------------------------------------------------------ rendering: header */\n\n const renderHeaderCell = (lc: ColumnLayout, index: number) => {\n const { col } = lc;\n const field = col.field;\n const sortIndex = sortModel.findIndex((item) => item.field === field && item.sort);\n const sortItem = sortIndex !== -1 ? sortModel[sortIndex] : undefined;\n const sortable =\n (col.sortable !== false && !disableColumnSorting && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && col.sortable !== false);\n const showMenu =\n (!disableColumnMenu && !col.disableColumnMenu && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnMenu);\n const resizable =\n (!disableColumnResize && col.resizable !== false && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnResize);\n const draggable = canReorder(col);\n const isDragging = drag?.field === field;\n const isDropTarget = drag && drag.overField === field && drag.field !== field;\n const menuOpen = columnMenu?.field === field;\n const headerParams = { field, colDef: col as MGHGridColDef<R>, api: apiObject };\n const customClass = col.headerClassName\n ? typeof col.headerClassName === 'function'\n ? col.headerClassName(headerParams)\n : col.headerClassName\n : undefined;\n\n let content: React.ReactNode;\n if (field === CHECKBOX_FIELD) {\n content = disableMultipleRowSelection ? null : (\n <Checkbox\n checked={allCandidatesSelected}\n indeterminate={someCandidatesSelected}\n disabled={selectionCandidates.length === 0}\n label={\n allCandidatesSelected\n ? localeText.checkboxSelectionUnselectAllRows\n : localeText.checkboxSelectionSelectAllRows\n }\n onChange={toggleAllCandidates}\n onClick={(event) => event.stopPropagation()}\n />\n );\n } else if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n content = null;\n } else {\n content = col.renderHeader ? (\n col.renderHeader(headerParams)\n ) : (\n <span className=\"mgh-grid-header-title\">{col.headerName ?? field}</span>\n );\n }\n\n return (\n <div\n key={field}\n role=\"columnheader\"\n aria-colindex={index + 1}\n aria-sort={sortItem ? (sortItem.sort === 'asc' ? 'ascending' : 'descending') : sortable ? 'none' : undefined}\n data-mgh-field={field}\n title={col.description}\n tabIndex={-1}\n draggable={draggable}\n className={cx(\n 'mgh-grid-header-cell',\n `mgh-grid-header-cell--align-${col.headerAlign ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-header-cell'),\n sortable && 'mgh-grid-header-cell--sortable',\n field === CHECKBOX_FIELD && 'mgh-grid-header-cell--checkbox',\n field === DETAIL_PANEL_TOGGLE_FIELD && 'mgh-grid-header-cell--detail-toggle',\n index === layout.columns.length - 1 && 'mgh-grid-header-cell--last',\n isDragging && 'mgh-grid-header-cell--dragging',\n isDropTarget && drag?.side === 'left' && 'mgh-grid-header-cell--drop-left',\n isDropTarget && drag?.side === 'right' && 'mgh-grid-header-cell--drop-right',\n menuOpen && 'mgh-grid-header-cell--menu-open',\n customClass\n )}\n style={cellStyle(lc)}\n onClick={(event) => {\n if (!sortable || resizingField) return;\n sortColumn(field, undefined, event.shiftKey);\n }}\n onDragStart={(event) => {\n if (!draggable) return;\n event.dataTransfer.effectAllowed = 'move';\n try {\n event.dataTransfer.setData('text/plain', field);\n } catch {\n /* ignore */\n }\n setDrag({ field, overField: null, side: 'left' });\n }}\n onDragOver={(event) => {\n if (!drag || drag.field === field) return;\n const sourceLc = layout.columns.find((c) => c.col.field === drag.field);\n if (!sourceLc || sourceLc.pinned !== lc.pinned || !canReorder(col)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n const rect = event.currentTarget.getBoundingClientRect();\n const side = event.clientX < rect.left + rect.width / 2 ? 'left' : 'right';\n if (drag.overField !== field || drag.side !== side) setDrag({ ...drag, overField: field, side });\n }}\n onDragLeave={() => {\n if (drag && drag.overField === field) setDrag({ ...drag, overField: null });\n }}\n onDrop={(event) => handleDrop(lc, event)}\n onDragEnd={() => setDrag(null)}\n >\n <div className=\"mgh-grid-header-title-container\">\n {content}\n {sortable && (\n <span\n className={cx('mgh-grid-sort-icon', sortItem && 'mgh-grid-sort-icon--active')}\n aria-hidden=\"true\"\n >\n {sortItem?.sort === 'desc' ? <ArrowDownwardIcon size={18} /> : <ArrowUpwardIcon size={18} />}\n {sortItem && sortModel.filter((s) => s.sort).length > 1 && (\n <span className=\"mgh-grid-sort-index\">{sortIndex + 1}</span>\n )}\n </span>\n )}\n </div>\n {showMenu && (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-header-menu-btn', menuOpen && 'mgh-grid-header-menu-btn--open')}\n label={localeText.columnMenuLabel}\n aria-haspopup=\"menu\"\n aria-expanded={menuOpen}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setColumnMenu((prev) =>\n prev?.field === field ? null : { field, anchorEl: event.currentTarget }\n );\n }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n {resizable && (\n <div\n className={cx('mgh-grid-resize-handle', resizingField === field && 'mgh-grid-resize-handle--active')}\n role=\"separator\"\n aria-orientation=\"vertical\"\n onPointerDown={(event) => handleResizeStart(lc, event)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.stopPropagation();\n autosizeColumns({ columns: [field] });\n }}\n draggable={false}\n onDragStart={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n />\n )}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: slots */\n\n const ToolbarSlot = slots.toolbar === null ? null : (slots.toolbar ?? MGHGridToolbar);\n const FooterSlot = slots.footer === null ? null : (slots.footer ?? MGHGridFooter);\n const NoRowsOverlaySlot = slots.noRowsOverlay ?? MGHGridNoRowsOverlay;\n const LoadingOverlaySlot = slots.loadingOverlay ?? MGHGridLoadingOverlay;\n const mergedToolbarProps = { ...toolbarProps, ...slotProps.toolbar };\n const noRowsProps = { text: noRowsText, ...slotProps.noRowsOverlay };\n const loadingProps = { ...slotProps.loadingOverlay };\n\n const showNoRows = !loading && pagedRows.length === 0;\n const menuColumn = columnMenu ? getColumn(columnMenu.field) : undefined;\n\n const cardStyles: React.CSSProperties = {\n height: 'auto',\n flexGrow: 1,\n ...sanitizeStyle(cardSx),\n ...sanitizeStyle(cardStyle),\n ...(themeVars as any),\n };\n const boxStyles: React.CSSProperties = { flexGrow: 1, ...sanitizeStyle(boxSx), ...sanitizeStyle(boxStyle) };\n const rootStyles: React.CSSProperties = {\n ...sanitizeStyle(sx),\n ...sanitizeStyle(style),\n ['--mgh-grid-header-height' as any]: `${headerHeight}px`,\n ['--mgh-grid-header-lines' as any]: headerTitleLines,\n ['--mgh-grid-row-height' as any]: `${rowHeight}px`,\n };\n\n // Nested selectors from sx/style props become a <style> block scoped to this grid instance.\n const scopedCss = React.useMemo(() => {\n const css: string[] = [];\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, sx, css);\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, style, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardSx, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardStyle, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxSx, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxStyle, css);\n return css.join('\\n');\n }, [gridId, sx, style, cardSx, cardStyle, boxSx, boxStyle]);\n\n const smDown = viewportWidth > 0 && viewportWidth < 600;\n\n const grid = (\n <div\n ref={rootRef}\n id={gridId}\n data-mgh-grid-id={gridId}\n role=\"grid\"\n aria-rowcount={rowCount + 1}\n aria-colcount={layout.columns.length}\n aria-multiselectable={checkboxSelection && !disableMultipleRowSelection ? true : undefined}\n aria-busy={loading || undefined}\n className={cx(\n 'mgh-grid',\n (autoHeight || printing) && 'mgh-grid--auto-height',\n printing && 'mgh-grid--printing',\n !layout.hasPinning && 'mgh-grid--no-pinned-shadow',\n className\n )}\n style={rootStyles}\n onKeyDown={handleKeyDown}\n >\n {showToolbar && ToolbarSlot && (\n <div ref={toolbarRef}>\n <ToolbarSlot {...mergedToolbarProps} />\n </div>\n )}\n <div className=\"mgh-grid-main\">\n <div ref={scrollerRef} className=\"mgh-grid-scroller\" onScroll={handleScroll} tabIndex={-1}>\n <div className=\"mgh-grid-columns\" role=\"rowgroup\" style={{ width: layout.totalWidth }}>\n <div className=\"mgh-grid-header-row\" role=\"row\" aria-rowindex={1} style={{ height: headerHeight }}>\n {layout.columns.map((lc, index) => renderHeaderCell(lc, index))}\n <div className=\"mgh-grid-header-filler\" />\n </div>\n </div>\n {pinnedRows?.top && pinnedRows.top.length > 0 && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--top\"\n role=\"rowgroup\"\n style={{ top: headerHeight, width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows.top, 'top')}\n </div>\n )}\n <div\n className={cx('mgh-grid-body', virtual ? 'mgh-grid-body--virtual' : 'mgh-grid-body--flow')}\n role=\"rowgroup\"\n style={\n virtual\n ? {\n height: pagedRows.length === 0 ? Math.max(heights.total, 120) : heights.total,\n width: layout.totalWidth,\n }\n : { width: layout.totalWidth, minHeight: showNoRows || loading ? 120 : undefined }\n }\n >\n {renderBodyRows()}\n </div>\n {((pinnedRows?.bottom && pinnedRows.bottom.length > 0) || footerAggregates) && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--bottom\"\n role=\"rowgroup\"\n style={{ width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows?.bottom, 'bottom')}\n </div>\n )}\n </div>\n {loading && (\n <div className=\"mgh-grid-overlay mgh-grid-overlay--loading\" style={{ top: headerHeight }}>\n <LoadingOverlaySlot {...loadingProps} />\n </div>\n )}\n {showNoRows && (\n <div className=\"mgh-grid-overlay\" style={{ top: headerHeight }}>\n <NoRowsOverlaySlot {...noRowsProps} />\n </div>\n )}\n </div>\n {!hideFooter && FooterSlot && <FooterSlot {...slotProps.footer} />}\n\n <Popover\n open={preferencePanel.open}\n anchorEl={preferencePanel.anchorEl}\n onClose={hidePreferences}\n themeMode={themeMode}\n placement=\"bottom-start\"\n autoFocus\n >\n {preferencePanel.openedPanelValue === 'columns' ? <MGHGridColumnsPanel /> : <MGHGridFilterPanel />}\n </Popover>\n\n {menuColumn && columnMenu && (\n <MGHGridColumnMenu\n column={menuColumn}\n anchorEl={columnMenu.anchorEl}\n open\n onClose={() => setColumnMenu(null)}\n themeMode={themeMode}\n panelAnchorEl={toolbarRef.current}\n />\n )}\n </div>\n );\n\n return (\n <MGHGridContext.Provider value={contextValue}>\n <div\n ref={cardRef}\n className={cx('mgh-grid-card', disableCard && 'mgh-grid-card--plain', cardClassName)}\n data-mgh-theme={themeMode}\n data-mgh-grid-card={gridId}\n style={cardStyles}\n >\n {scopedCss && <style data-mgh-grid-sx={gridId}>{scopedCss}</style>}\n {!disableCard && (header !== undefined || renderHeaderCenterContent || renderHeaderEndContent) && (\n <div className=\"mgh-grid-card-header\">\n {header !== undefined && <h3 className=\"mgh-grid-card-title\">{header}</h3>}\n {renderHeaderCenterContent && (\n <div className=\"mgh-grid-card-header-center\">{renderHeaderCenterContent}</div>\n )}\n <div className=\"mgh-grid-card-header-end\" style={{ gap: smDown ? 8 : 16 }}>\n {renderHeaderEndContent}\n </div>\n </div>\n )}\n <div className={cx('mgh-grid-box', boxClassName)} data-mgh-grid-box={gridId} style={boxStyles}>\n {grid}\n </div>\n </div>\n </MGHGridContext.Provider>\n );\n}\n\nMGHGrid.displayName = 'MGHGrid';\n","import React from 'react';\n\nexport const MGH_DATE_RANGE_PICKER_STYLE_ID = 'mgh-drp-styles';\n\n/**\n * Stylesheet for MGHDateRangePicker. Injected once into <head> the first time a picker mounts.\n * Colours are CSS variables (`--mgh-drp-*`). When the picker is rendered inside an MGHGrid card\n * it inherits the grid palette (`--mgh-grid-*`) automatically.\n */\nexport const MGH_DATE_RANGE_PICKER_CSS = `\n.mgh-drp, .mgh-drp-popover, .mgh-drp-calendars, .mgh-dp-calendar {\n --mgh-drp-font-family: var(--mgh-grid-font-family, inherit);\n --mgh-drp-font-size: var(--mgh-grid-font-size, 14px);\n --mgh-drp-paper: var(--mgh-grid-paper, #ffffff);\n --mgh-drp-fg: var(--mgh-grid-fg, rgba(0, 0, 0, 0.87));\n --mgh-drp-fg-secondary: var(--mgh-grid-fg-secondary, rgba(0, 0, 0, 0.6));\n --mgh-drp-fg-disabled: var(--mgh-grid-fg-disabled, rgba(0, 0, 0, 0.38));\n --mgh-drp-border: var(--mgh-grid-border, rgba(224, 224, 224, 1));\n --mgh-drp-input-border: var(--mgh-grid-input-border, rgba(0, 0, 0, 0.23));\n --mgh-drp-hover: var(--mgh-grid-hover, rgba(0, 0, 0, 0.04));\n --mgh-drp-primary: var(--mgh-grid-primary, #1976d2);\n --mgh-drp-primary-contrast: var(--mgh-grid-primary-contrast, #ffffff);\n --mgh-drp-focus: var(--mgh-grid-focus, #1976d2);\n --mgh-drp-selected: var(--mgh-grid-selected, rgba(25, 118, 210, 0.12));\n --mgh-drp-preview: rgba(0, 0, 0, 0.06);\n --mgh-drp-error: #d32f2f;\n --mgh-drp-radius: 4px;\n --mgh-drp-popover-radius: 8px;\n --mgh-drp-popover-shadow: var(--mgh-grid-popover-shadow, 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12));\n --mgh-drp-day-size: 36px;\n --mgh-drp-day-margin: 2px;\n font-family: var(--mgh-drp-font-family);\n font-size: var(--mgh-drp-font-size);\n color: var(--mgh-drp-fg);\n line-height: 1.5;\n}\n/* Dark values also apply to a calendar nested inside a dark picker / popover, so the calendar's own\n defaults (declared above for standalone use) never reset the colours back to light.\n .mgh-dp-calendar is MGHDatePicker's calendar, which shares this stylesheet. */\n.mgh-drp[data-mgh-theme=\"dark\"], .mgh-drp-popover[data-mgh-theme=\"dark\"], .mgh-drp-calendars[data-mgh-theme=\"dark\"], .mgh-dp-calendar[data-mgh-theme=\"dark\"],\n.mgh-drp[data-mgh-theme=\"dark\"] .mgh-drp-calendars, .mgh-drp-popover[data-mgh-theme=\"dark\"] .mgh-drp-calendars,\n.mgh-drp[data-mgh-theme=\"dark\"] .mgh-dp-calendar, .mgh-drp-popover[data-mgh-theme=\"dark\"] .mgh-dp-calendar {\n --mgh-drp-paper: #212b36;\n --mgh-drp-fg: #ffffff;\n --mgh-drp-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-drp-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-drp-border: rgba(81, 81, 81, 1);\n --mgh-drp-input-border: rgba(255, 255, 255, 0.23);\n --mgh-drp-hover: rgba(255, 255, 255, 0.08);\n --mgh-drp-primary: #90caf9;\n --mgh-drp-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-drp-focus: #90caf9;\n --mgh-drp-selected: rgba(144, 202, 249, 0.16);\n --mgh-drp-preview: rgba(255, 255, 255, 0.08);\n --mgh-drp-error: #f44336;\n}\n[class*=\"mgh-drp\"], [class*=\"mgh-drp\"]::before, [class*=\"mgh-drp\"]::after { box-sizing: border-box; }\n\n/* ---- root / multi-input layout ---- */\n.mgh-drp { display: inline-flex; flex-direction: column; vertical-align: top; min-width: 0; }\n.mgh-drp--full-width { display: flex; width: 100%; }\n.mgh-drp-fields { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }\n.mgh-drp-fields .mgh-drp-field { flex: 1 1 0; min-width: 0; }\n.mgh-drp-fields-separator { align-self: center; color: var(--mgh-drp-fg-secondary); padding: 0 2px; }\n\n/* ---- outlined text field (MUI TextField look-alike) ---- */\n.mgh-drp-field { position: relative; display: inline-flex; align-items: center; min-width: 0; width: 100%; border-radius: var(--mgh-drp-radius); color: var(--mgh-drp-fg); }\n.mgh-drp-field--medium { height: 56px; }\n.mgh-drp-field--small { height: 40px; }\n.mgh-drp-field:not(.mgh-drp-field--full-width) { width: 260px; }\n.mgh-drp-field--multi:not(.mgh-drp-field--full-width) { width: 170px; }\n.mgh-drp-field--full-width { width: 100%; }\n.mgh-drp-input { flex: 1 1 auto; min-width: 0; width: 100%; height: 100%; margin: 0; border: 0; outline: none; background: transparent; color: inherit; font: inherit; font-size: 1rem; letter-spacing: inherit; padding: 16.5px 14px; }\n.mgh-drp-field--small .mgh-drp-input { padding: 8.5px 14px; }\n.mgh-drp-field--adorned .mgh-drp-input { padding-right: 0; }\n.mgh-drp-input::placeholder { color: var(--mgh-drp-fg-disabled); opacity: 1; }\n.mgh-drp-input::-webkit-calendar-picker-indicator { display: none; }\n.mgh-drp-field--disabled .mgh-drp-input { color: var(--mgh-drp-fg-disabled); -webkit-text-fill-color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-field--disabled { cursor: default; }\n.mgh-drp-field--clickable .mgh-drp-input { cursor: pointer; }\n.mgh-drp-adornment { display: flex; align-items: center; gap: 0; margin-right: 6px; flex: 0 0 auto; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-field--small .mgh-drp-adornment { margin-right: 4px; }\n\n/* notched outline */\n.mgh-drp-outline { position: absolute; inset: -5px 0 0 0; margin: 0; padding: 0 8px; pointer-events: none; border: 1px solid var(--mgh-drp-input-border); border-radius: inherit; min-width: 0; overflow: hidden; text-align: left; transition: border-color .15s; }\n.mgh-drp-outline legend { float: unset; width: auto; padding: 0; height: 11px; font-size: 0.75em; visibility: hidden; max-width: 0.01px; white-space: nowrap; transition: max-width 50ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; overflow: hidden; display: block; line-height: 11px; }\n.mgh-drp-outline legend > span { padding-left: 5px; padding-right: 5px; display: inline-block; opacity: 0; visibility: visible; }\n.mgh-drp-field--shrink .mgh-drp-outline legend { max-width: 100%; transition: max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms; }\n.mgh-drp-field--no-label .mgh-drp-outline legend { display: none; }\n/* Without a label there is no legend notch, so the fieldset must sit on the field box instead of 5px above it;\n otherwise the visible border is 5px taller than with a label and the field looks off-centre. */\n.mgh-drp-field--no-label .mgh-drp-outline { inset: 0; }\n.mgh-drp-field:hover:not(.mgh-drp-field--disabled) .mgh-drp-outline { border-color: var(--mgh-drp-fg); }\n.mgh-drp-field--focused .mgh-drp-outline, .mgh-drp-field--focused:hover .mgh-drp-outline { border-color: var(--mgh-drp-focus); border-width: 2px; }\n.mgh-drp-field--error .mgh-drp-outline, .mgh-drp-field--error:hover .mgh-drp-outline { border-color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-outline { border-color: var(--mgh-drp-fg-disabled); }\n\n/* floating label */\n.mgh-drp-label { position: absolute; left: 0; top: 0; transform-origin: top left; transform: translate(14px, 16px) scale(1); color: var(--mgh-drp-fg-secondary); font-size: 1rem; line-height: 1.4375em; pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: calc(100% - 24px); transition: color .15s, transform .15s cubic-bezier(0.0, 0, 0.2, 1), max-width .15s; z-index: 1; }\n.mgh-drp-field--small .mgh-drp-label { transform: translate(14px, 9px) scale(1); }\n.mgh-drp-field--shrink .mgh-drp-label, .mgh-drp-field--small.mgh-drp-field--shrink .mgh-drp-label { transform: translate(14px, -9px) scale(0.75); max-width: calc(133% - 32px); }\n.mgh-drp-field--focused .mgh-drp-label { color: var(--mgh-drp-focus); }\n.mgh-drp-field--error .mgh-drp-label { color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-label { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-label-asterisk { margin-left: 2px; }\n\n.mgh-drp-helper { margin: 3px 14px 0; font-size: 0.75rem; line-height: 1.66; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-helper--error { color: var(--mgh-drp-error); }\n\n/* ---- buttons ---- */\n.mgh-drp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-drp-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; white-space: nowrap; text-transform: uppercase; }\n.mgh-drp-btn:hover { background: var(--mgh-drp-hover); color: var(--mgh-drp-fg); }\n.mgh-drp-btn:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-btn:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-btn--primary { color: var(--mgh-drp-primary); }\n.mgh-drp-btn--primary:hover { background: var(--mgh-drp-selected); color: var(--mgh-drp-primary); }\n.mgh-drp-btn--icon { padding: 8px; border-radius: 50%; width: 40px; height: 40px; text-transform: none; }\n.mgh-drp-btn--icon.mgh-drp-btn--small { width: 32px; height: 32px; padding: 4px; }\n.mgh-drp-icon { flex: 0 0 auto; }\n\n/* ---- popover ---- */\n.mgh-drp-popover { position: fixed; z-index: 1300; display: flex; flex-direction: column; background: var(--mgh-drp-paper); color: var(--mgh-drp-fg); border-radius: var(--mgh-drp-popover-radius); box-shadow: var(--mgh-drp-popover-shadow); outline: none; max-height: calc(100vh - 16px); max-width: calc(100vw - 16px); overflow: auto; animation: mgh-drp-pop .12s ease-out; }\n@keyframes mgh-drp-pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }\n.mgh-drp-layout { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-layout--with-toolbar { flex-direction: column; }\n.mgh-drp-layout-main { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-toolbar { padding: 16px 24px 0; }\n.mgh-drp-toolbar-title { font-size: 0.75rem; text-transform: uppercase; letter-spacing: .08em; color: var(--mgh-drp-fg-secondary); margin: 0 0 8px; }\n.mgh-drp-toolbar-range { display: flex; align-items: center; gap: 8px; font-size: 1.5rem; font-weight: 400; line-height: 1.334; }\n.mgh-drp-toolbar-range button { border: 0; background: transparent; padding: 0 2px; font: inherit; color: var(--mgh-drp-fg-secondary); cursor: pointer; border-radius: 4px; }\n.mgh-drp-toolbar-range button.mgh-drp-toolbar-range--active { color: var(--mgh-drp-fg); }\n.mgh-drp-toolbar-range button:hover { background: var(--mgh-drp-hover); }\n\n/* shortcuts (left column) */\n.mgh-drp-shortcuts { list-style: none; margin: 0; padding: 8px 0; min-width: 140px; max-height: 340px; overflow: auto; border-right: 1px solid var(--mgh-drp-border); display: flex; flex-direction: column; gap: 4px; padding-left: 8px; padding-right: 8px; }\n.mgh-drp-shortcut { display: inline-flex; align-items: center; height: 32px; padding: 0 12px; border-radius: 16px; border: 1px solid var(--mgh-drp-input-border); background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.8125rem; cursor: pointer; white-space: nowrap; justify-content: flex-start; transition: background-color .15s; }\n.mgh-drp-shortcut:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-shortcut:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-shortcut:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; }\n.mgh-drp-shortcut--selected { background: var(--mgh-drp-selected); border-color: var(--mgh-drp-primary); color: var(--mgh-drp-primary); }\n\n/* ---- calendars ---- */\n.mgh-drp-calendars { display: flex; flex-direction: row; align-items: flex-start; }\n.mgh-drp-calendar { display: flex; flex-direction: column; width: calc(7 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)) + 24px); padding: 0 12px 8px; }\n.mgh-drp-calendar + .mgh-drp-calendar { border-left: 1px solid var(--mgh-drp-border); }\n.mgh-drp-calendar-header { display: flex; align-items: center; justify-content: space-between; min-height: 40px; margin: 12px 0 8px; padding: 0 4px; }\n.mgh-drp-calendar-label { flex: 1 1 auto; text-align: center; font-size: 1rem; font-weight: 500; }\n.mgh-drp-calendar-header .mgh-drp-btn--icon { color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-calendar-nav-spacer { width: 40px; height: 40px; flex: 0 0 auto; }\n.mgh-drp-weekdays, .mgh-drp-week { display: flex; justify-content: center; }\n.mgh-drp-weekday { width: var(--mgh-drp-day-size); height: 40px; margin: 0 var(--mgh-drp-day-margin); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; color: var(--mgh-drp-fg-secondary); font-weight: 400; }\n.mgh-drp-weeks { display: flex; flex-direction: column; min-height: calc(6 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin))); }\n.mgh-drp-week { margin: var(--mgh-drp-day-margin) 0; }\n\n/* day cell: the outer wrapper carries the range highlight, the inner button the day itself */\n.mgh-drp-day-wrap { position: relative; width: calc(var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)); height: var(--mgh-drp-day-size); display: flex; align-items: center; justify-content: center; }\n.mgh-drp-day-wrap--in-range { background: var(--mgh-drp-selected); }\n.mgh-drp-day-wrap--range-start { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--range-end { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--preview { border-top: 1px dashed var(--mgh-drp-fg-secondary); border-bottom: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--preview-start { border-left: 1px dashed var(--mgh-drp-fg-secondary); border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--preview-end { border-right: 1px dashed var(--mgh-drp-fg-secondary); border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; border-left: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; border-right: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day { width: var(--mgh-drp-day-size); height: var(--mgh-drp-day-size); border-radius: 50%; border: 0; margin: 0; padding: 0; background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.75rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background-color .15s, color .15s; position: relative; }\n.mgh-drp-day:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-day:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: -1px; }\n.mgh-drp-day--today:not(.mgh-drp-day--selected) { border: 1px solid var(--mgh-drp-fg-secondary); }\n.mgh-drp-day--outside { color: var(--mgh-drp-fg-secondary); opacity: .6; }\n.mgh-drp-day--hidden { visibility: hidden; pointer-events: none; }\n.mgh-drp-day--disabled, .mgh-drp-day--disabled:hover { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-day--selected, .mgh-drp-day--selected:hover { background: var(--mgh-drp-primary); color: var(--mgh-drp-primary-contrast); font-weight: 500; }\n.mgh-drp-day--selected:focus-visible { outline-offset: 2px; }\n.mgh-drp-calendar--read-only .mgh-drp-day, .mgh-drp-calendar--disabled .mgh-drp-day { cursor: default; }\n.mgh-drp-calendar--disabled .mgh-drp-day { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-calendar--disabled .mgh-drp-day--selected { opacity: .6; }\n\n/* ---- action bar ---- */\n.mgh-drp-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 8px; border-top: 1px solid var(--mgh-drp-border); }\n.mgh-drp-actions--spread { justify-content: space-between; }\n.mgh-drp-actions-group { display: flex; gap: 8px; }\n\n@media (max-width: 599.95px) {\n .mgh-drp-layout-main { flex-direction: column; }\n .mgh-drp-shortcuts { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--mgh-drp-border); max-height: none; }\n .mgh-drp-calendars { flex-direction: column; align-items: center; }\n .mgh-drp-calendar + .mgh-drp-calendar { border-left: 0; border-top: 1px solid var(--mgh-drp-border); }\n}\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_DATE_RANGE_PICKER_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_DATE_RANGE_PICKER_STYLE_ID;\n style.setAttribute('data-mgh-drp', 'true');\n style.textContent = MGH_DATE_RANGE_PICKER_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHDateRangePicker stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHDateRangePickerStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\n\n/* Inline SVG icons (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHDateRangeIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHDateRangeIconProps>(({ size = 24, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-drp-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const DateRangeIcon = createIcon(\n <path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\" />,\n 'DateRangeIcon'\n);\nexport const ChevronLeftIcon = createIcon(\n <path d=\"M15.41 16.59 10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z\" />,\n 'ChevronLeftIcon'\n);\nexport const ChevronRightIcon = createIcon(\n <path d=\"M8.59 16.59 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\" />,\n 'ChevronRightIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\n/* Used by MGHDatePicker (MUI's default `CalendarIcon` / `ArrowDropDownIcon`). */\nexport const CalendarIcon = createIcon(\n <path d=\"M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z\" />,\n 'CalendarIcon'\n);\nexport const ArrowDropDownIcon = createIcon(<path d=\"M7 10l5 5 5-5z\" />, 'ArrowDropDownIcon');\n","import dayjs, { Dayjs } from 'dayjs';\nimport customParseFormat from 'dayjs/plugin/customParseFormat';\nimport type {\n MGHDateRange,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\n\ndayjs.extend(customParseFormat);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const EMPTY_RANGE: MGHDateRange = [null, null];\n\n/** Coerces Dayjs / Date / ISO string / timestamp into a valid Dayjs (or null). */\nexport const toDayjs = (value: unknown): Dayjs | null => {\n if (value == null || value === '') return null;\n if (dayjs.isDayjs(value)) return value.isValid() ? value : null;\n if (value instanceof Date || typeof value === 'number' || typeof value === 'string') {\n const parsed = dayjs(value as Date | number | string);\n return parsed.isValid() ? parsed : null;\n }\n return null;\n};\n\nexport const isSameDay = (a: Dayjs | null | undefined, b: Dayjs | null | undefined) => !!a && !!b && a.isSame(b, 'day');\nexport const isBeforeDay = (a: Dayjs, b: Dayjs) => a.isBefore(b, 'day');\nexport const isAfterDay = (a: Dayjs, b: Dayjs) => a.isAfter(b, 'day');\nexport const isWithinRange = (day: Dayjs, start: Dayjs | null, end: Dayjs | null) =>\n !!start && !!end && !isBeforeDay(day, start) && !isAfterDay(day, end);\n\nexport const isRangeEqual = (a: MGHDateRange | undefined, b: MGHDateRange | undefined) => {\n if (a === b) return true;\n if (!a || !b) return false;\n const same = (x: Dayjs | null, y: Dayjs | null) => (x == null && y == null) || (!!x && !!y && x.isSame(y, 'day'));\n return same(a[0], b[0]) && same(a[1], b[1]);\n};\n\nexport const normalizeRange = (value: unknown): MGHDateRange => {\n if (!Array.isArray(value)) return EMPTY_RANGE;\n return [toDayjs(value[0]), toDayjs(value[1])];\n};\n\n/** Strict parse with the display format first, then a handful of forgiving fallbacks. */\nexport const parseDateText = (text: string, format: string): Dayjs | null => {\n const trimmed = text.trim();\n if (!trimmed) return null;\n const strict = dayjs(trimmed, format, true);\n if (strict.isValid()) return strict;\n const fallbacks = [\n format.replace(/MM/g, 'M').replace(/DD/g, 'D'),\n 'M/D/YYYY',\n 'M/D/YY',\n 'YYYY-MM-DD',\n 'MM-DD-YYYY',\n 'M-D-YYYY',\n ];\n for (const f of fallbacks) {\n const parsed = dayjs(trimmed, f, true);\n if (parsed.isValid()) return parsed;\n }\n return null;\n};\n\nexport const formatDate = (value: Dayjs | null, format: string) => (value && value.isValid() ? value.format(format) : '');\n\n/** Splits \"start – end\" text typed into the single-input field. */\nexport const splitRangeText = (text: string): [string, string] => {\n const parts = text.split(/\\s+[–—-]\\s+|\\s*–\\s*|\\s*—\\s*|\\s+to\\s+/i);\n if (parts.length >= 2) return [parts[0], parts.slice(1).join(' ')];\n return [text, ''];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validation (mirrors MUI's DateRangeValidationError semantics)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface DateValidationOptions {\n minDate?: Dayjs | null;\n maxDate?: Dayjs | null;\n disablePast?: boolean;\n disableFuture?: boolean;\n shouldDisableDate?: (day: Dayjs, position: MGHDateRangePosition) => boolean;\n}\n\nexport const validateDay = (\n day: Dayjs | null,\n position: MGHDateRangePosition,\n options: DateValidationOptions,\n now: Dayjs = dayjs()\n): MGHDateRangeValidationError => {\n if (day == null) return null;\n if (!day.isValid()) return 'invalidDate';\n if (options.disablePast && isBeforeDay(day, now)) return 'disablePast';\n if (options.disableFuture && isAfterDay(day, now)) return 'disableFuture';\n if (options.minDate && isBeforeDay(day, options.minDate)) return 'minDate';\n if (options.maxDate && isAfterDay(day, options.maxDate)) return 'maxDate';\n if (options.shouldDisableDate?.(day, position)) return 'shouldDisableDate';\n return null;\n};\n\nexport const validateRange = (\n value: MGHDateRange,\n options: DateValidationOptions\n): [MGHDateRangeValidationError, MGHDateRangeValidationError] => {\n const now = dayjs();\n const startError = validateDay(value[0], 'start', options, now);\n const endError = validateDay(value[1], 'end', options, now);\n if (!startError && !endError && value[0] && value[1] && isAfterDay(value[0], value[1])) {\n return ['invalidRange', 'invalidRange'];\n }\n return [startError, endError];\n};\n\nexport const isDayDisabled = (day: Dayjs, position: MGHDateRangePosition, options: DateValidationOptions) =>\n validateDay(day, position, options) != null;\n\n/* -------------------------------------------------------------------------------------------------\n * Calendar grid\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface CalendarWeek {\n key: string;\n days: Array<{ day: Dayjs; outsideMonth: boolean }>;\n}\n\n/**\n * Builds the weeks of `month`. Weeks start on the locale's first day of the week (Sunday for `en`).\n * Pass `fixedWeekNumber` (usually 6) to always render the same number of rows.\n */\nexport const getMonthWeeks = (month: Dayjs, fixedWeekNumber?: number): CalendarWeek[] => {\n const firstOfMonth = month.startOf('month');\n const start = firstOfMonth.startOf('week');\n const weeksInMonth = Math.ceil(firstOfMonth.endOf('month').diff(start, 'day') / 7 + 1 / 7);\n const weekCount = fixedWeekNumber && fixedWeekNumber > 0 ? fixedWeekNumber : Math.max(weeksInMonth, 1);\n const weeks: CalendarWeek[] = [];\n for (let w = 0; w < weekCount; w += 1) {\n const weekStart = start.add(w * 7, 'day');\n weeks.push({\n key: weekStart.format('YYYY-MM-DD'),\n days: Array.from({ length: 7 }, (_, d) => {\n const day = weekStart.add(d, 'day');\n return { day, outsideMonth: !day.isSame(firstOfMonth, 'month') };\n }),\n });\n }\n return weeks;\n};\n\nexport const getWeekDayLabels = (formatter: (day: Dayjs) => string) => {\n const start = dayjs().startOf('week');\n return Array.from({ length: 7 }, (_, i) => {\n const day = start.add(i, 'day');\n return { key: day.format('dd'), label: formatter(day), full: day.format('dddd') };\n });\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Shortcuts (same shape as MUI's PickersShortcuts items)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const MGH_DATE_RANGE_DEFAULT_SHORTCUTS: MGHDateRangeShortcut[] = [\n {\n label: 'This Week',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('week'), today.endOf('week')];\n },\n },\n {\n label: 'Last Week',\n getValue: () => {\n const prev = dayjs().subtract(7, 'day');\n return [prev.startOf('week'), prev.endOf('week')];\n },\n },\n {\n label: 'Last 7 Days',\n getValue: () => {\n const today = dayjs();\n return [today.subtract(7, 'day'), today];\n },\n },\n {\n label: 'Current Month',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('month'), today.endOf('month')];\n },\n },\n {\n label: 'Next Month',\n getValue: () => {\n const next = dayjs().add(1, 'month');\n return [next.startOf('month'), next.endOf('month')];\n },\n },\n { label: 'Reset', getValue: () => [null, null] },\n];\n","import React from 'react';\nimport dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateRange, MGHDateRangeCalendarProps, MGHDateRangePosition } from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { ChevronLeftIcon, ChevronRightIcon } from './icons';\nimport {\n EMPTY_RANGE,\n cx,\n getMonthWeeks,\n getWeekDayLabels,\n isAfterDay,\n isBeforeDay,\n isDayDisabled,\n isSameDay,\n isWithinRange,\n normalizeRange,\n} from './utils';\n\nconst defaultDayOfWeekFormatter = (day: Dayjs) => day.format('dd').charAt(0).toUpperCase();\n\n/**\n * Pure-React port of MUI X's `DateRangeCalendar`: one to three months side by side with range\n * highlighting, hover preview, keyboard navigation and min/max/disabled-day validation.\n */\nexport function MGHDateRangeCalendar({\n value: valueProp,\n defaultValue,\n onChange,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth = false,\n fixedWeekNumber,\n dayOfWeekFormatter = defaultDayOfWeekFormatter,\n disableHighlightToday = false,\n showRangePreview = true,\n autoFocus = false,\n onMonthChange,\n localeText,\n themeMode,\n className,\n style,\n}: MGHDateRangeCalendarProps) {\n useMGHDateRangePickerStyles();\n\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n\n // Month displayed by the first calendar.\n const [currentMonth, setCurrentMonth] = React.useState<Dayjs>(() =>\n (start ?? end ?? referenceDate ?? dayjs()).startOf('month')\n );\n const visibleMonths = React.useMemo(\n () => Array.from({ length: calendars }, (_, i) => currentMonth.add(i, 'month')),\n [currentMonth, calendars]\n );\n const lastVisibleMonth = visibleMonths[visibleMonths.length - 1];\n\n const changeMonth = React.useCallback(\n (month: Dayjs) => {\n const next = month.startOf('month');\n setCurrentMonth((prev) => {\n if (prev.isSame(next, 'month')) return prev;\n onMonthChange?.(next);\n return next;\n });\n },\n [onMonthChange]\n );\n\n const ensureVisible = React.useCallback(\n (day: Dayjs) => {\n if (isBeforeDay(day, currentMonth.startOf('month'))) changeMonth(day);\n else if (isAfterDay(day, lastVisibleMonth.endOf('month'))) changeMonth(day.subtract(calendars - 1, 'month'));\n },\n [currentMonth, lastVisibleMonth, calendars, changeMonth]\n );\n\n // When a value arrives from outside (typed in the field / shortcut) scroll to it.\n const lastSeenRef = React.useRef<MGHDateRange>(value);\n React.useEffect(() => {\n const prev = lastSeenRef.current;\n lastSeenRef.current = value;\n const target = rangePosition === 'end' ? (end ?? start) : (start ?? end);\n if (!target) return;\n const changed = !isSameDay(prev[0], start) || !isSameDay(prev[1], end);\n if (changed) ensureVisible(target);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [start, end]);\n\n const canGoPrev = !minDate || currentMonth.isAfter(minDate, 'month');\n const canGoNext = !maxDate || lastVisibleMonth.isBefore(maxDate, 'month');\n\n /* ---- hover preview ---- */\n const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);\n const preview = React.useMemo<MGHDateRange>(() => {\n if (!showRangePreview || !hoveredDay || disabled || readOnly) return EMPTY_RANGE;\n if (rangePosition === 'end' && start && !end) {\n return isBeforeDay(hoveredDay, start) ? EMPTY_RANGE : [start, hoveredDay];\n }\n if (rangePosition === 'start' && end && !start) {\n return isAfterDay(hoveredDay, end) ? EMPTY_RANGE : [hoveredDay, end];\n }\n return EMPTY_RANGE;\n }, [showRangePreview, hoveredDay, rangePosition, start, end, disabled, readOnly]);\n\n /* ---- selection (MUI semantics) ---- */\n const selectDay = React.useCallback(\n (day: Dayjs) => {\n if (disabled || readOnly) return;\n if (isDayDisabled(day, rangePosition, validation)) return;\n let next: MGHDateRange;\n let nextPosition: MGHDateRangePosition;\n if (rangePosition === 'start') {\n // Picking a start after the current end resets the end (MUI behaviour).\n next = [day, end && isAfterDay(day, end) ? null : end];\n nextPosition = 'end';\n } else if (start && isBeforeDay(day, start)) {\n // An \"end\" before the start becomes the new start; keep asking for the end.\n next = [day, null];\n nextPosition = 'end';\n } else {\n next = [start, day];\n nextPosition = 'start';\n }\n if (!isControlled) setInternalValue(next);\n onChange?.(next, day, rangePosition);\n setRangePosition(nextPosition);\n },\n [disabled, readOnly, rangePosition, validation, end, start, isControlled, onChange, setRangePosition]\n );\n\n /* ---- keyboard navigation (roving tabindex) ---- */\n const [focusedDay, setFocusedDay] = React.useState<Dayjs>(() => start ?? end ?? referenceDate ?? dayjs());\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef(autoFocus);\n\n const focusDay = React.useCallback((day: Dayjs) => {\n const key = day.format('YYYY-MM-DD');\n const el = rootRef.current?.querySelector<HTMLButtonElement>(`[data-day=\"${key}\"]`);\n el?.focus();\n }, []);\n\n React.useEffect(() => {\n if (!pendingFocusRef.current) return;\n pendingFocusRef.current = false;\n const target = focusedDay;\n ensureVisible(target);\n // Wait for a potential month change to render.\n const id = window.setTimeout(() => focusDay(target), 0);\n return () => window.clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const moveFocus = (day: Dayjs) => {\n setFocusedDay(day);\n ensureVisible(day);\n window.setTimeout(() => focusDay(day), 0);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>, day: Dayjs) => {\n let next: Dayjs | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = day.subtract(1, 'day');\n break;\n case 'ArrowRight':\n next = day.add(1, 'day');\n break;\n case 'ArrowUp':\n next = day.subtract(7, 'day');\n break;\n case 'ArrowDown':\n next = day.add(7, 'day');\n break;\n case 'Home':\n next = day.startOf('week');\n break;\n case 'End':\n next = day.endOf('week');\n break;\n case 'PageUp':\n next = event.shiftKey ? day.subtract(1, 'year') : day.subtract(1, 'month');\n break;\n case 'PageDown':\n next = event.shiftKey ? day.add(1, 'year') : day.add(1, 'month');\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n selectDay(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (next) moveFocus(next);\n };\n\n const weekDays = React.useMemo(() => getWeekDayLabels(dayOfWeekFormatter), [dayOfWeekFormatter]);\n const today = dayjs();\n const previewStart = preview[0];\n const previewEnd = preview[1];\n const isRangeComplete = !!start && !!end;\n\n const renderMonth = (month: Dayjs, index: number) => {\n const weeks = getMonthWeeks(month, fixedWeekNumber);\n const isFirst = index === 0;\n const isLast = index === visibleMonths.length - 1;\n const focusedInMonth = focusedDay.isSame(month, 'month') ? focusedDay : null;\n const tabbableDay =\n focusedInMonth ??\n (start && start.isSame(month, 'month') ? start : null) ??\n (end && end.isSame(month, 'month') ? end : null) ??\n (isFirst && !visibleMonths.some((m) => focusedDay.isSame(m, 'month')) ? month.startOf('month') : null);\n\n return (\n <div\n key={month.format('YYYY-MM')}\n className=\"mgh-drp-calendar\"\n role=\"group\"\n aria-label={month.format('MMMM YYYY')}\n >\n <div className=\"mgh-drp-calendar-header\">\n {isFirst ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.previousMonth ?? 'Previous month'}\n title={localeText?.previousMonth ?? 'Previous month'}\n disabled={disabled || !canGoPrev}\n onClick={() => changeMonth(currentMonth.subtract(1, 'month'))}\n >\n <ChevronLeftIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n <div className=\"mgh-drp-calendar-label\" aria-live=\"polite\">\n {month.format('MMMM YYYY')}\n </div>\n {isLast ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.nextMonth ?? 'Next month'}\n title={localeText?.nextMonth ?? 'Next month'}\n disabled={disabled || !canGoNext}\n onClick={() => changeMonth(currentMonth.add(1, 'month'))}\n >\n <ChevronRightIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n </div>\n <div className=\"mgh-drp-weekdays\" role=\"row\">\n {weekDays.map((wd) => (\n <span key={wd.key} className=\"mgh-drp-weekday\" role=\"columnheader\" aria-label={wd.full}>\n {wd.label}\n </span>\n ))}\n </div>\n <div className=\"mgh-drp-weeks\" role=\"grid\" aria-label={month.format('MMMM YYYY')}>\n {weeks.map((week) => (\n <div key={week.key} className=\"mgh-drp-week\" role=\"row\">\n {week.days.map(({ day, outsideMonth }, dayIndex) => {\n const hidden = outsideMonth && !showDaysOutsideCurrentMonth;\n const isStart = isSameDay(day, start);\n const isEnd = isSameDay(day, end);\n const selected = isStart || isEnd;\n const inRange = !hidden && isRangeComplete && isWithinRange(day, start, end);\n const inPreview =\n !hidden &&\n !!previewStart &&\n !!previewEnd &&\n isWithinRange(day, previewStart, previewEnd);\n const dayDisabled = disabled || isDayDisabled(day, rangePosition, validation);\n const isTabbable = !!tabbableDay && isSameDay(day, tabbableDay) && !hidden;\n const firstVisible = dayIndex === 0 || (!showDaysOutsideCurrentMonth && day.date() === 1);\n const lastVisible =\n dayIndex === 6 || (!showDaysOutsideCurrentMonth && day.date() === day.daysInMonth());\n return (\n <div\n key={day.format('YYYY-MM-DD')}\n role=\"gridcell\"\n aria-selected={selected || undefined}\n className={cx(\n 'mgh-drp-day-wrap',\n inRange && 'mgh-drp-day-wrap--in-range',\n inRange && isStart && 'mgh-drp-day-wrap--range-start',\n inRange && isEnd && 'mgh-drp-day-wrap--range-end',\n inPreview && 'mgh-drp-day-wrap--preview',\n inPreview && isSameDay(day, previewStart) && 'mgh-drp-day-wrap--preview-start',\n inPreview && isSameDay(day, previewEnd) && 'mgh-drp-day-wrap--preview-end',\n firstVisible && 'mgh-drp-day-wrap--first-visible',\n lastVisible && 'mgh-drp-day-wrap--last-visible'\n )}\n >\n <button\n type=\"button\"\n data-day={day.format('YYYY-MM-DD')}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={day.format('dddd, MMMM D, YYYY')}\n aria-current={\n !disableHighlightToday && isSameDay(day, today) ? 'date' : undefined\n }\n aria-disabled={dayDisabled || undefined}\n disabled={hidden}\n className={cx(\n 'mgh-drp-day',\n hidden && 'mgh-drp-day--hidden',\n outsideMonth && !hidden && 'mgh-drp-day--outside',\n selected && 'mgh-drp-day--selected',\n !disableHighlightToday && isSameDay(day, today) && 'mgh-drp-day--today',\n dayDisabled && 'mgh-drp-day--disabled'\n )}\n onClick={() => selectDay(day)}\n onMouseEnter={() => setHoveredDay(day)}\n onMouseLeave={() =>\n setHoveredDay((prev) => (prev && isSameDay(prev, day) ? null : prev))\n }\n onFocus={() => setFocusedDay(day)}\n onKeyDown={(event) => handleKeyDown(event, day)}\n >\n {day.date()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={rootRef}\n className={cx(\n 'mgh-drp-calendars',\n disabled && 'mgh-drp-calendar--disabled',\n readOnly && 'mgh-drp-calendar--read-only',\n className\n )}\n data-mgh-theme={themeMode}\n data-range-position={rangePosition}\n style={style}\n onMouseLeave={() => setHoveredDay(null)}\n >\n {visibleMonths.map(renderMonth)}\n </div>\n );\n}\n\nexport default MGHDateRangeCalendar;\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { clamp, cx } from './utils';\n\n/*\n * Field / popover primitives shared by MGHDateRangePicker and MGHDatePicker. They use the\n * `mgh-drp-*` stylesheet (see MGHDateRangePicker.styles.ts), so both pickers look identical and\n * are themed through the same `--mgh-drp-*` CSS variables.\n */\n\n/* -------------------------------------------------------------------------------------------------\n * Anchored popover (portal)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null;\n placement: 'bottom-start' | 'bottom-end' | 'bottom';\n onDismiss: (reason: 'backdrop' | 'escape') => void;\n themeMode?: 'light' | 'dark';\n className?: string;\n style?: React.CSSProperties;\n labelledBy?: string;\n children: React.ReactNode;\n}\n\nexport function Popover({\n open,\n anchorEl,\n placement,\n onDismiss,\n themeMode,\n className,\n style,\n labelledBy,\n children,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState({ top: 0, left: 0, ready: false });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n top = a.bottom + 4;\n if (top + h > vh - 8 && a.top - 4 - h >= 8) top = a.top - 4 - h;\n left = placement === 'bottom-end' ? a.right - w : placement === 'bottom' ? a.left + a.width / 2 - w / 2 : a.left;\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n onDismiss('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onDismiss('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onDismiss, anchorEl]);\n\n if (!open || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={labelledBy}\n tabIndex={-1}\n className={cx('mgh-drp-popover', className)}\n data-mgh-theme={themeMode}\n style={{ top: position.top, left: position.left, visibility: position.ready ? 'visible' : 'hidden', ...style }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Outlined text field (MUI TextField look-alike, no dependency)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextFieldProps {\n id: string;\n label?: React.ReactNode;\n value: string;\n placeholder?: string;\n size: 'small' | 'medium';\n fullWidth?: boolean;\n multi?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n error?: boolean;\n focused?: boolean;\n clickable?: boolean;\n name?: string;\n autoFocus?: boolean;\n inputRef?: React.Ref<HTMLInputElement>;\n adornment?: React.ReactNode;\n ariaLabel?: string;\n onChange: (text: string) => void;\n onFocus: () => void;\n onBlur: () => void;\n onClick?: () => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nexport const TextField = React.forwardRef<HTMLDivElement, TextFieldProps>(function TextField(\n {\n id,\n label,\n value,\n placeholder,\n size,\n fullWidth,\n multi,\n disabled,\n readOnly,\n required,\n error,\n focused,\n clickable,\n name,\n autoFocus,\n inputRef,\n adornment,\n ariaLabel,\n onChange,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n },\n ref\n) {\n const hasLabel = label != null && label !== '';\n const shrink = focused || value !== '' || !hasLabel;\n return (\n <div\n ref={ref}\n className={cx(\n 'mgh-drp-field',\n `mgh-drp-field--${size}`,\n fullWidth && 'mgh-drp-field--full-width',\n multi && 'mgh-drp-field--multi',\n shrink && 'mgh-drp-field--shrink',\n focused && 'mgh-drp-field--focused',\n disabled && 'mgh-drp-field--disabled',\n error && 'mgh-drp-field--error',\n clickable && 'mgh-drp-field--clickable',\n !hasLabel && 'mgh-drp-field--no-label',\n !!adornment && 'mgh-drp-field--adorned'\n )}\n onClick={onClick}\n >\n {hasLabel && (\n <label className=\"mgh-drp-label\" htmlFor={id}>\n {label}\n {required && (\n <span className=\"mgh-drp-label-asterisk\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <input\n id={id}\n ref={inputRef}\n name={name}\n className=\"mgh-drp-input\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"off\"\n spellCheck={false}\n value={value}\n placeholder={shrink ? placeholder : undefined}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n onChange={(event) => onChange(event.target.value)}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n />\n {adornment && <div className=\"mgh-drp-adornment\">{adornment}</div>}\n <fieldset aria-hidden=\"true\" className=\"mgh-drp-outline\">\n <legend>\n <span>\n {hasLabel ? label : ''}\n {hasLabel && required ? ' *' : ''}\n </span>\n </legend>\n </fieldset>\n </div>\n );\n});\n","import React from 'react';\nimport dayjs from 'dayjs';\nimport type {\n MGHDateRange,\n MGHDateRangeChangeContext,\n MGHDateRangePickerLocaleText,\n MGHDateRangePickerProps,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { MGHDateRangeCalendar } from './MGHDateRangeCalendar';\nimport { CloseIcon, DateRangeIcon } from './icons';\nimport { Popover, TextField } from './primitives';\nimport {\n EMPTY_RANGE,\n cx,\n formatDate,\n isRangeEqual,\n normalizeRange,\n parseDateText,\n splitRangeText,\n validateRange,\n} from './utils';\n\nexport const MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT: MGHDateRangePickerLocaleText = {\n start: 'Start',\n end: 'End',\n fieldSeparator: '–',\n openPicker: 'Choose date range',\n clear: 'Clear',\n today: 'Today',\n cancel: 'Cancel',\n accept: 'OK',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n toolbarTitle: 'Select date range',\n};\n\nconst DEFAULT_FORMAT = 'MM/DD/YYYY';\n\n/* -------------------------------------------------------------------------------------------------\n * MGHDateRangePicker\n * ----------------------------------------------------------------------------------------------- */\n\ntype FocusedInput = 'single' | 'start' | 'end' | null;\n\n/**\n * MUI-free port of MUI X Pro's `DateRangePicker` (desktop variant): an outlined text field with a\n * calendar button that opens a two-month range calendar, optional shortcuts and an action bar.\n * Values are dayjs `[start, end]` tuples so existing `DateRange<Dayjs>` state works unchanged.\n */\nexport const MGHDateRangePicker = React.forwardRef<HTMLDivElement, MGHDateRangePickerProps>(function MGHDateRangePicker(\n {\n value: valueProp,\n defaultValue,\n onChange,\n onAccept,\n onError,\n open: openProp,\n onOpen,\n onClose,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n label,\n format = DEFAULT_FORMAT,\n fieldVariant = 'single',\n size = 'small',\n fullWidth = false,\n clearable = false,\n openOnClick,\n disableOpenPicker = false,\n closeOnSelect,\n shortcuts,\n actions = [],\n showToolbar = false,\n localeText: localeTextProp,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n disableHighlightToday,\n showRangePreview,\n onMonthChange,\n name,\n id: idProp,\n placeholder: placeholderProp,\n required,\n error: errorProp,\n helperText,\n autoFocus,\n inputRef,\n themeMode,\n themeVars,\n className,\n style,\n popoverClassName,\n popoverStyle,\n placement = 'bottom-start',\n },\n ref\n) {\n useMGHDateRangePickerStyles();\n\n const localeText = React.useMemo(\n () => ({ ...MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n const datePlaceholder = localeText.datePlaceholder ?? format;\n const isMulti = fieldVariant === 'multi';\n const resolvedOpenOnClick = openOnClick ?? isMulti;\n const resolvedCloseOnSelect = closeOnSelect ?? !actions.includes('accept');\n\n const reactId = React.useId();\n const baseId = idProp ?? `mgh-drp-${reactId.replace(/:/g, '')}`;\n const startId = isMulti ? `${baseId}-start` : baseId;\n const endId = `${baseId}-end`;\n const dialogTitleId = `${baseId}-title`;\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n const validationError = React.useMemo(() => validateRange(value, validation), [value, validation]);\n const isValid = React.useCallback(\n (range: MGHDateRange) => validateRange(range, validation).every((e) => e == null),\n [validation]\n );\n\n const lastErrorRef = React.useRef<[MGHDateRangeValidationError, MGHDateRangeValidationError] | null>(null);\n React.useEffect(() => {\n const prev = lastErrorRef.current;\n if (prev && prev[0] === validationError[0] && prev[1] === validationError[1]) return;\n if (prev !== null || validationError[0] || validationError[1]) onError?.(validationError, value);\n lastErrorRef.current = validationError;\n }, [validationError, value, onError]);\n\n const setValue = React.useCallback(\n (next: MGHDateRange, shortcut?: MGHDateRangeShortcut) => {\n if (!isControlled) setInternalValue(next);\n const context: MGHDateRangeChangeContext = { validationError: validateRange(next, validation) };\n if (shortcut) context.shortcut = shortcut;\n onChange?.(next, context);\n },\n [isControlled, onChange, validation]\n );\n\n /* ---- range position ---- */\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n /* ---- open / close ---- */\n const isOpenControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = React.useState(false);\n const open = isOpenControlled ? !!openProp : internalOpen;\n const valueAtOpenRef = React.useRef<MGHDateRange>(value);\n const lastAcceptedRef = React.useRef<MGHDateRange>(value);\n\n /** Fires `onAccept` only when the value differs from the last accepted one (MUI semantics). */\n const accept = React.useCallback(\n (next: MGHDateRange, force = false) => {\n if (!force && isRangeEqual(next, lastAcceptedRef.current)) return;\n lastAcceptedRef.current = next;\n onAccept?.(next);\n },\n [onAccept]\n );\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n // Without an explicit `themeMode`, follow the closest `[data-mgh-theme]` ancestor (e.g. a dark MGHGrid card)\n // so the portaled popover matches the surface the field sits on.\n const [inheritedTheme, setInheritedTheme] = React.useState<'light' | 'dark' | undefined>(undefined);\n React.useEffect(() => {\n if (themeMode !== undefined) return;\n const attr = rootRef.current?.parentElement?.closest('[data-mgh-theme]')?.getAttribute('data-mgh-theme');\n setInheritedTheme(attr === 'dark' ? 'dark' : attr === 'light' ? 'light' : undefined);\n });\n const effectiveThemeMode = themeMode ?? inheritedTheme;\n\n // The popover anchor lives in state (not only in the ref) so a picker that mounts already open\n // is positioned under the field on its first commit instead of waiting for an unrelated re-render.\n const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null);\n const setRootRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n setAnchorEl(node);\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [ref]\n );\n\n const openPicker = React.useCallback(\n (position?: MGHDateRangePosition) => {\n if (disabled || readOnly || open) return;\n valueAtOpenRef.current = value;\n restoreFocusRef.current = (document.activeElement as HTMLElement | null) ?? null;\n setRangePosition(position ?? (start && !end ? 'end' : 'start'));\n if (!isOpenControlled) setInternalOpen(true);\n onOpen?.();\n },\n [disabled, readOnly, open, value, start, end, setRangePosition, isOpenControlled, onOpen]\n );\n\n const closePicker = React.useCallback(() => {\n if (!open) return;\n if (!isOpenControlled) setInternalOpen(false);\n onClose?.();\n const target = toggleRef.current ?? restoreFocusRef.current;\n window.setTimeout(() => target?.focus?.(), 0);\n }, [open, isOpenControlled, onClose]);\n\n const acceptAndClose = React.useCallback(\n (next: MGHDateRange) => {\n accept(next, true);\n closePicker();\n },\n [accept, closePicker]\n );\n\n const handleDismiss = React.useCallback(() => {\n // Clicking away / Escape keeps whatever was picked (MUI fires onAccept when the value changed).\n accept(value);\n closePicker();\n }, [value, accept, closePicker]);\n\n const handleCalendarChange = React.useCallback(\n (next: MGHDateRange, _day: dayjs.Dayjs, position: MGHDateRangePosition) => {\n setValue(next);\n if (position === 'end' && next[0] && next[1] && resolvedCloseOnSelect) acceptAndClose(next);\n },\n [setValue, resolvedCloseOnSelect, acceptAndClose]\n );\n\n const handleShortcut = (shortcut: MGHDateRangeShortcut) => {\n const next = normalizeRange(shortcut.getValue({ isValid }));\n setValue(next, shortcut);\n setRangePosition('start');\n acceptAndClose(next);\n };\n\n const handleAction = (action: 'clear' | 'today' | 'cancel' | 'accept') => {\n switch (action) {\n case 'clear': {\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n acceptAndClose(EMPTY_RANGE);\n break;\n }\n case 'today': {\n const today = dayjs().startOf('day');\n const next: MGHDateRange = [today, today];\n setValue(next);\n setRangePosition('start');\n if (resolvedCloseOnSelect) acceptAndClose(next);\n break;\n }\n case 'cancel': {\n if (!isRangeEqual(value, valueAtOpenRef.current)) setValue(valueAtOpenRef.current);\n closePicker();\n break;\n }\n case 'accept':\n default:\n acceptAndClose(value);\n }\n };\n\n /* ---- text fields ---- */\n const [focusedInput, setFocusedInput] = React.useState<FocusedInput>(null);\n const formatSingle = React.useCallback(\n (range: MGHDateRange) => {\n const [s, e] = range;\n if (!s && !e) return '';\n return `${s ? formatDate(s, format) : datePlaceholder} ${localeText.fieldSeparator} ${e ? formatDate(e, format) : datePlaceholder}`;\n },\n [format, datePlaceholder, localeText.fieldSeparator]\n );\n\n const [singleText, setSingleText] = React.useState(() => formatSingle(value));\n const [startText, setStartText] = React.useState(() => formatDate(start, format));\n const [endText, setEndText] = React.useState(() => formatDate(end, format));\n const [inputInvalid, setInputInvalid] = React.useState<{ single: boolean; start: boolean; end: boolean }>({\n single: false,\n start: false,\n end: false,\n });\n\n // Keep the text in sync with the value unless the user is typing in that input.\n React.useEffect(() => {\n if (focusedInput !== 'single') {\n setSingleText(formatSingle(value));\n setInputInvalid((prev) => (prev.single ? { ...prev, single: false } : prev));\n }\n if (focusedInput !== 'start') {\n setStartText(formatDate(start, format));\n setInputInvalid((prev) => (prev.start ? { ...prev, start: false } : prev));\n }\n if (focusedInput !== 'end') {\n setEndText(formatDate(end, format));\n setInputInvalid((prev) => (prev.end ? { ...prev, end: false } : prev));\n }\n }, [value, start, end, focusedInput, format, formatSingle]);\n\n const parseSegment = (text: string): { date: dayjs.Dayjs | null; invalid: boolean } => {\n const trimmed = text.trim();\n if (!trimmed || trimmed.toUpperCase() === datePlaceholder.toUpperCase()) return { date: null, invalid: false };\n const parsed = parseDateText(trimmed, format);\n return { date: parsed, invalid: parsed == null };\n };\n\n const handleSingleChange = (text: string) => {\n setSingleText(text);\n const [s, e] = splitRangeText(text);\n const ps = parseSegment(s);\n const pe = parseSegment(e);\n const invalid = ps.invalid || pe.invalid;\n setInputInvalid((prev) => ({ ...prev, single: invalid }));\n if (invalid) return;\n const next: MGHDateRange = [ps.date, pe.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleSideChange = (side: 'start' | 'end', text: string) => {\n if (side === 'start') setStartText(text);\n else setEndText(text);\n const parsed = parseSegment(text);\n setInputInvalid((prev) => ({ ...prev, [side]: parsed.invalid }));\n if (parsed.invalid) return;\n const next: MGHDateRange = side === 'start' ? [parsed.date, end] : [start, parsed.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleBlur = (input: Exclude<FocusedInput, null>) => {\n setFocusedInput((prev) => (prev === input ? null : prev));\n // Re-format on blur unless the text could not be parsed (keep it so the user sees the error).\n if (input === 'single' && !inputInvalid.single) setSingleText(formatSingle(value));\n if (input === 'start' && !inputInvalid.start) setStartText(formatDate(start, format));\n if (input === 'end' && !inputInvalid.end) setEndText(formatDate(end, format));\n // Leaving the field commits a typed value (like pressing Enter).\n if (!open) accept(value);\n };\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, position: MGHDateRangePosition) => {\n if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n openPicker(position);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (!open) accept(value);\n }\n };\n\n const clear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n accept(EMPTY_RANGE);\n };\n\n const hasValue = !!start || !!end;\n const hasValidationError = validationError.some((e) => e != null);\n const showError = !!errorProp || hasValidationError || inputInvalid.single || inputInvalid.start || inputInvalid.end;\n\n const openButton = !disableOpenPicker && (\n <button\n ref={toggleRef}\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.openPicker}\n title={localeText.openPicker}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (open) handleDismiss();\n else openPicker();\n }}\n >\n <DateRangeIcon size={size === 'small' ? 20 : 24} />\n </button>\n );\n\n const clearButton = clearable && hasValue && !disabled && !readOnly && (\n <button\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.clear}\n title={localeText.clear}\n onClick={clear}\n >\n <CloseIcon size={size === 'small' ? 18 : 20} />\n </button>\n );\n\n const themeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...style }),\n [themeVars, style]\n );\n const popoverThemeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...popoverStyle }),\n [themeVars, popoverStyle]\n );\n\n /* ---- shortcuts / actions / toolbar ---- */\n const shortcutItems = React.useMemo(\n () =>\n (shortcuts ?? []).map((shortcut, index) => {\n let shortcutValue: MGHDateRange = EMPTY_RANGE;\n try {\n shortcutValue = normalizeRange(shortcut.getValue({ isValid }));\n } catch {\n /* ignore */\n }\n return { shortcut, key: shortcut.id ?? `${shortcut.label}-${index}`, value: shortcutValue };\n }),\n [shortcuts, isValid]\n );\n\n const renderToolbar = () => (\n <div className=\"mgh-drp-toolbar\">\n <p className=\"mgh-drp-toolbar-title\" id={dialogTitleId}>\n {localeText.toolbarTitle}\n </p>\n <div className=\"mgh-drp-toolbar-range\">\n <button\n type=\"button\"\n className={cx(rangePosition === 'start' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('start')}\n >\n {start ? formatDate(start, format) : localeText.start}\n </button>\n <span>{localeText.fieldSeparator}</span>\n <button\n type=\"button\"\n className={cx(rangePosition === 'end' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('end')}\n >\n {end ? formatDate(end, format) : localeText.end}\n </button>\n </div>\n </div>\n );\n\n const renderActions = () =>\n actions.length > 0 && (\n <div className=\"mgh-drp-actions\">\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n className={cx('mgh-drp-btn', (action === 'accept' || action === 'today') && 'mgh-drp-btn--primary')}\n onClick={() => handleAction(action)}\n >\n {localeText[action]}\n </button>\n ))}\n </div>\n );\n\n const calendar = (\n <MGHDateRangeCalendar\n value={value}\n onChange={handleCalendarChange}\n rangePosition={rangePosition}\n onRangePositionChange={setRangePosition}\n calendars={calendars}\n referenceDate={referenceDate}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n showDaysOutsideCurrentMonth={showDaysOutsideCurrentMonth}\n fixedWeekNumber={fixedWeekNumber}\n dayOfWeekFormatter={dayOfWeekFormatter}\n disableHighlightToday={disableHighlightToday}\n showRangePreview={showRangePreview}\n onMonthChange={onMonthChange}\n localeText={localeText}\n themeMode={effectiveThemeMode}\n autoFocus\n />\n );\n\n /* ---- render ---- */\n const commonFieldProps = {\n size,\n fullWidth,\n disabled,\n readOnly,\n required,\n error: showError,\n };\n\n return (\n <div\n ref={setRootRef}\n className={cx('mgh-drp', fullWidth && 'mgh-drp--full-width', isMulti && 'mgh-drp--multi', className)}\n data-mgh-theme={effectiveThemeMode}\n style={themeStyle}\n >\n {isMulti ? (\n <div className=\"mgh-drp-fields\">\n <TextField\n {...commonFieldProps}\n multi\n id={startId}\n name={name ? `${name}-start` : undefined}\n label={localeText.start}\n value={startText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'start'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n onChange={(text) => handleSideChange('start', text)}\n onFocus={() => {\n setFocusedInput('start');\n setRangePosition('start');\n }}\n onBlur={() => handleBlur('start')}\n onClick={() => resolvedOpenOnClick && openPicker('start')}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n <span className=\"mgh-drp-fields-separator\" aria-hidden=\"true\">\n {localeText.fieldSeparator}\n </span>\n <TextField\n {...commonFieldProps}\n multi\n id={endId}\n name={name ? `${name}-end` : undefined}\n label={localeText.end}\n value={endText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'end'}\n clickable={resolvedOpenOnClick}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={(text) => handleSideChange('end', text)}\n onFocus={() => {\n setFocusedInput('end');\n setRangePosition('end');\n }}\n onBlur={() => handleBlur('end')}\n onClick={() => resolvedOpenOnClick && openPicker('end')}\n onKeyDown={(event) => handleInputKeyDown(event, 'end')}\n />\n </div>\n ) : (\n <TextField\n {...commonFieldProps}\n id={startId}\n name={name}\n label={label}\n value={singleText}\n placeholder={placeholderProp ?? `${datePlaceholder} ${localeText.fieldSeparator} ${datePlaceholder}`}\n focused={focusedInput === 'single'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n ariaLabel={label == null ? localeText.toolbarTitle : undefined}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={handleSingleChange}\n onFocus={() => setFocusedInput('single')}\n onBlur={() => handleBlur('single')}\n onClick={() => resolvedOpenOnClick && openPicker()}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n )}\n {helperText != null && helperText !== '' && (\n <div className={cx('mgh-drp-helper', showError && 'mgh-drp-helper--error')}>{helperText}</div>\n )}\n\n <Popover\n open={open}\n anchorEl={anchorEl}\n placement={placement}\n onDismiss={handleDismiss}\n themeMode={effectiveThemeMode}\n className={popoverClassName}\n style={popoverThemeStyle}\n labelledBy={showToolbar ? dialogTitleId : undefined}\n >\n <div className={cx('mgh-drp-layout', showToolbar && 'mgh-drp-layout--with-toolbar')}>\n {showToolbar && renderToolbar()}\n <div className=\"mgh-drp-layout-main\">\n {shortcutItems.length > 0 && (\n <ul className=\"mgh-drp-shortcuts\" aria-label=\"Shortcuts\">\n {shortcutItems.map(({ shortcut, key, value: shortcutValue }) => (\n <li key={key}>\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-shortcut',\n hasValue &&\n isRangeEqual(shortcutValue, value) &&\n 'mgh-drp-shortcut--selected'\n )}\n disabled={disabled || readOnly}\n onClick={() => handleShortcut(shortcut)}\n >\n {shortcut.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n {calendar}\n </div>\n {renderActions()}\n </div>\n </Popover>\n </div>\n );\n});\n\nMGHDateRangePicker.displayName = 'MGHDateRangePicker';\n\nexport default MGHDateRangePicker;\n","import React from 'react';\nimport { useMGHDateRangePickerStyles } from '../MGHDateRangePicker/MGHDateRangePicker.styles';\n\nexport const MGH_DATE_PICKER_STYLE_ID = 'mgh-dp-styles';\n\n/**\n * Extra rules for MGHDatePicker. The field, popover, buttons, day grid and the `--mgh-drp-*`\n * colour variables come from the MGHDateRangePicker stylesheet, which is injected alongside.\n * Dimensions follow MUI X's `DateCalendar` (320 × 334, 72 × 36 month / year buttons).\n */\nexport const MGH_DATE_PICKER_CSS = `\n[class*=\"mgh-dp-\"], [class*=\"mgh-dp-\"]::before, [class*=\"mgh-dp-\"]::after { box-sizing: border-box; }\n.mgh-dp .mgh-drp-field:not(.mgh-drp-field--full-width) { width: 240px; }\n\n/* ---- calendar ---- */\n.mgh-dp-calendar { display: flex; flex-direction: column; width: 320px; min-height: 334px; max-width: 100%; overflow: hidden; }\n.mgh-dp-header { display: flex; align-items: center; min-height: 40px; max-height: 40px; margin: 12px 0 8px; padding: 0 12px 0 24px; }\n.mgh-dp-header-label-wrap { display: flex; align-items: center; overflow: hidden; margin-right: auto; cursor: pointer; border-radius: 4px; }\n.mgh-dp-header-label-wrap--static, .mgh-dp-calendar--disabled .mgh-dp-header-label-wrap { cursor: default; }\n.mgh-dp-header-label { margin-right: 6px; font-size: 1rem; font-weight: 500; line-height: 1.75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.mgh-dp-header-switch { color: var(--mgh-drp-fg-secondary); }\n.mgh-dp-header-switch .mgh-drp-icon { transition: transform .2s ease; will-change: transform; }\n.mgh-dp-header-switch--open .mgh-drp-icon { transform: rotate(180deg); }\n.mgh-dp-header-nav { display: flex; align-items: center; flex: 0 0 auto; }\n.mgh-dp-header-nav .mgh-drp-btn--icon { color: var(--mgh-drp-fg-secondary); }\n.mgh-dp-header-nav-spacer { width: 24px; flex: 0 0 auto; }\n\n.mgh-dp-view { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }\n.mgh-dp-view--day { padding-bottom: 8px; }\n\n/* ---- month / year grids ---- */\n.mgh-dp-months, .mgh-dp-years { position: relative; display: flex; flex-direction: row; flex-wrap: wrap; align-content: flex-start; width: 100%; padding: 0 4px; }\n.mgh-dp-years { overflow-y: auto; max-height: 280px; }\n.mgh-dp-cell { display: flex; align-items: center; justify-content: center; flex-basis: 33.3333%; }\n.mgh-dp-cell--per-row-4 { flex-basis: 25%; }\n.mgh-dp-pill { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 72px; height: 36px; margin: 8px 0; border: 0; border-radius: 18px; background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 1rem; font-weight: 400; line-height: 1.75; letter-spacing: .00938em; cursor: pointer; transition: background-color .15s, color .15s; }\n.mgh-dp-years .mgh-dp-pill { margin: 6px 0; }\n.mgh-dp-pill:hover { background: var(--mgh-drp-hover); }\n.mgh-dp-pill:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: -1px; }\n.mgh-dp-pill--current:not(.mgh-dp-pill--selected) { border: 1px solid var(--mgh-drp-fg-secondary); }\n.mgh-dp-pill--disabled, .mgh-dp-pill--disabled:hover { color: var(--mgh-drp-fg-disabled); background: transparent; cursor: default; }\n.mgh-dp-pill--selected, .mgh-dp-pill--selected:hover { background: var(--mgh-drp-primary); color: var(--mgh-drp-primary-contrast); font-weight: 500; }\n.mgh-dp-pill--selected:focus-visible { outline-offset: 2px; }\n.mgh-dp-calendar--disabled .mgh-dp-pill, .mgh-dp-calendar--read-only .mgh-dp-pill { cursor: default; }\n.mgh-dp-calendar--disabled .mgh-dp-pill { color: var(--mgh-drp-fg-disabled); }\n.mgh-dp-calendar--disabled .mgh-dp-pill--selected { opacity: .6; }\n.mgh-dp-calendar--disabled .mgh-drp-day { color: var(--mgh-drp-fg-disabled); cursor: default; }\n.mgh-dp-calendar--disabled .mgh-drp-day--selected { opacity: .6; }\n.mgh-dp-calendar--read-only .mgh-drp-day { cursor: default; }\n\n/* ---- toolbar (MUI DatePickerToolbar) ---- */\n.mgh-dp-toolbar-date { display: flex; align-items: center; min-height: 40px; font-size: 2.125rem; font-weight: 400; line-height: 1.235; letter-spacing: .00735em; }\n\n@media (max-width: 599.95px) {\n .mgh-dp-calendar { width: 100%; max-width: 320px; }\n}\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_DATE_PICKER_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_DATE_PICKER_STYLE_ID;\n style.setAttribute('data-mgh-dp', 'true');\n style.textContent = MGH_DATE_PICKER_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHDateRangePicker + MGHDatePicker stylesheets once per document. Safe on the server (no-op). */\nexport const useMGHDatePickerStyles = () => {\n useMGHDateRangePickerStyles();\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateShortcut, MGHDateValidationError, MGHDateValue } from './MGHDatePicker.types';\nimport { isAfterDay, isBeforeDay, toDayjs } from '../MGHDateRangePicker/utils';\n\n/** MUI's default calendar bounds; used for the year grid when no `minDate` / `maxDate` is given. */\nexport const MGH_DATE_PICKER_DEFAULT_MIN_DATE = dayjs('1900-01-01');\nexport const MGH_DATE_PICKER_DEFAULT_MAX_DATE = dayjs('2099-12-31');\n\nexport const normalizeDate = (value: unknown): MGHDateValue => toDayjs(value);\n\nexport const isDateEqual = (a: MGHDateValue | undefined, b: MGHDateValue | undefined) =>\n (a == null && b == null) || (!!a && !!b && a.isSame(b, 'day'));\n\n/** `date`'s calendar day with `time`'s time of day (MUI `mergeDateAndTime`). */\nexport const mergeDateAndTime = (date: Dayjs, time: Dayjs | null | undefined) =>\n time ? date.hour(time.hour()).minute(time.minute()).second(time.second()).millisecond(time.millisecond()) : date;\n\n/** `date` moved to `year`, clamping the day (Feb 29 → Feb 28) instead of overflowing into the next month. */\nexport const setYear = (date: Dayjs, year: number) => {\n const first = date.startOf('month').year(year);\n return mergeDateAndTime(first.date(Math.min(date.date(), first.daysInMonth())), date);\n};\n\n/** `date` moved to `month` (0–11), clamping the day (Jan 31 → Feb 28) instead of overflowing. */\nexport const setMonth = (date: Dayjs, month: number) => {\n const first = date.startOf('month').month(month);\n return mergeDateAndTime(first.date(Math.min(date.date(), first.daysInMonth())), date);\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validation (mirrors MUI's DateValidationError semantics and order)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface DateValidationOptions {\n minDate?: Dayjs | null;\n maxDate?: Dayjs | null;\n disablePast?: boolean;\n disableFuture?: boolean;\n shouldDisableDate?: (day: Dayjs) => boolean;\n shouldDisableMonth?: (month: Dayjs) => boolean;\n shouldDisableYear?: (year: Dayjs) => boolean;\n}\n\nexport const validateDate = (\n value: MGHDateValue,\n options: DateValidationOptions,\n now: Dayjs = dayjs()\n): MGHDateValidationError => {\n if (value == null) return null;\n if (!value.isValid()) return 'invalidDate';\n if (options.shouldDisableDate?.(value)) return 'shouldDisableDate';\n if (options.shouldDisableMonth?.(value)) return 'shouldDisableMonth';\n if (options.shouldDisableYear?.(value)) return 'shouldDisableYear';\n if (options.disableFuture && isAfterDay(value, now)) return 'disableFuture';\n if (options.disablePast && isBeforeDay(value, now)) return 'disablePast';\n if (options.minDate && isBeforeDay(value, options.minDate)) return 'minDate';\n if (options.maxDate && isAfterDay(value, options.maxDate)) return 'maxDate';\n return null;\n};\n\nexport const isDateDisabled = (day: Dayjs, options: DateValidationOptions, now?: Dayjs) =>\n validateDate(day, options, now) != null;\n\n/** A month is disabled when every day in it is out of bounds (MUI `MonthCalendar` semantics). */\nexport const isMonthDisabled = (month: Dayjs, options: DateValidationOptions, now: Dayjs = dayjs()) => {\n const start = month.startOf('month');\n const end = month.endOf('month');\n if (options.disablePast && isBeforeDay(end, now)) return true;\n if (options.disableFuture && isAfterDay(start, now)) return true;\n if (options.minDate && isBeforeDay(end, options.minDate)) return true;\n if (options.maxDate && isAfterDay(start, options.maxDate)) return true;\n return !!options.shouldDisableMonth?.(start);\n};\n\n/** A year is disabled when every day in it is out of bounds (MUI `YearCalendar` semantics). */\nexport const isYearDisabled = (year: Dayjs, options: DateValidationOptions, now: Dayjs = dayjs()) => {\n const start = year.startOf('year');\n const end = year.endOf('year');\n if (options.disablePast && isBeforeDay(end, now)) return true;\n if (options.disableFuture && isAfterDay(start, now)) return true;\n if (options.minDate && isBeforeDay(end, options.minDate)) return true;\n if (options.maxDate && isAfterDay(start, options.maxDate)) return true;\n return !!options.shouldDisableYear?.(start);\n};\n\n/**\n * Nearest enabled day to `date`, searching forwards and backwards at the same time within\n * `minDate` / `maxDate` (MUI `findClosestEnabledDate`). Returns `null` when nothing is enabled.\n */\nexport const findClosestEnabledDate = (date: Dayjs, options: DateValidationOptions, now: Dayjs = dayjs()): Dayjs | null => {\n let minDate = options.minDate ?? MGH_DATE_PICKER_DEFAULT_MIN_DATE;\n let maxDate = options.maxDate ?? MGH_DATE_PICKER_DEFAULT_MAX_DATE;\n if (options.disablePast && isAfterDay(now, minDate)) minDate = now;\n if (options.disableFuture && isBeforeDay(now, maxDate)) maxDate = now;\n if (isAfterDay(minDate, maxDate)) return null;\n\n let forward: Dayjs | null = date;\n let backward: Dayjs | null = date;\n if (isBeforeDay(date, minDate)) {\n forward = minDate;\n backward = null;\n }\n if (isAfterDay(date, maxDate)) {\n if (backward) backward = maxDate;\n forward = null;\n }\n let guard = 0;\n while ((forward || backward) && guard < 100000) {\n guard += 1;\n if (forward && isAfterDay(forward, maxDate)) forward = null;\n if (backward && isBeforeDay(backward, minDate)) backward = null;\n if (forward) {\n if (!isDateDisabled(forward, options, now)) return forward;\n forward = forward.add(1, 'day');\n }\n if (backward) {\n if (!isDateDisabled(backward, options, now)) return backward;\n backward = backward.subtract(1, 'day');\n }\n }\n return null;\n};\n\n/** Years listed in the year view. */\nexport const getYearRange = (minDate?: Dayjs | null, maxDate?: Dayjs | null): number[] => {\n const from = (minDate ?? MGH_DATE_PICKER_DEFAULT_MIN_DATE).year();\n const to = (maxDate ?? MGH_DATE_PICKER_DEFAULT_MAX_DATE).year();\n return Array.from({ length: Math.max(to - from + 1, 1) }, (_, i) => from + i);\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Shortcuts (same shape as MUI's PickersShortcuts items)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const MGH_DATE_PICKER_DEFAULT_SHORTCUTS: MGHDateShortcut[] = [\n { label: 'Today', getValue: () => dayjs().startOf('day') },\n { label: 'Yesterday', getValue: () => dayjs().subtract(1, 'day').startOf('day') },\n { label: 'Tomorrow', getValue: () => dayjs().add(1, 'day').startOf('day') },\n { label: 'Start of Week', getValue: () => dayjs().startOf('week') },\n { label: 'Start of Month', getValue: () => dayjs().startOf('month') },\n { label: 'End of Month', getValue: () => dayjs().endOf('month').startOf('day') },\n { label: 'Reset', getValue: () => null },\n];\n","import React from 'react';\nimport dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateCalendarProps, MGHDateSelectionState, MGHDateValue, MGHDateView } from './MGHDatePicker.types';\nimport { useMGHDatePickerStyles } from './MGHDatePicker.styles';\nimport { ArrowDropDownIcon, ChevronLeftIcon, ChevronRightIcon } from '../MGHDateRangePicker/icons';\nimport { cx, getMonthWeeks, getWeekDayLabels, isAfterDay, isBeforeDay, isSameDay } from '../MGHDateRangePicker/utils';\nimport {\n findClosestEnabledDate,\n getYearRange,\n isDateDisabled,\n isDateEqual,\n isMonthDisabled,\n isYearDisabled,\n mergeDateAndTime,\n normalizeDate,\n setMonth,\n setYear,\n type DateValidationOptions,\n} from './utils';\n\nconst defaultDayOfWeekFormatter = (day: Dayjs) => day.format('dd').charAt(0).toUpperCase();\nconst DEFAULT_VIEWS: MGHDateView[] = ['year', 'day'];\nconst defaultSwitchViewLabel = (view: MGHDateView) =>\n view === 'year' ? 'year view is open, switch to calendar view' : 'calendar view is open, switch to year view';\n\n/**\n * Pure-React port of MUI X's `DateCalendar`: a single month with a header whose ▾ button switches\n * to the year (and optionally month) view, keyboard navigation and min/max/disabled validation.\n */\nexport function MGHDateCalendar({\n value: valueProp,\n defaultValue,\n onChange,\n referenceDate,\n views: viewsProp,\n openTo = 'day',\n view: viewProp,\n onViewChange,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth = false,\n fixedWeekNumber,\n dayOfWeekFormatter = defaultDayOfWeekFormatter,\n disableHighlightToday = false,\n yearsPerRow = 3,\n monthsPerRow = 3,\n autoFocus = false,\n onMonthChange,\n onYearChange,\n localeText,\n themeMode,\n className,\n style,\n}: MGHDateCalendarProps) {\n useMGHDatePickerStyles();\n\n const views = React.useMemo(() => (viewsProp && viewsProp.length > 0 ? viewsProp : DEFAULT_VIEWS), [viewsProp]);\n const today = dayjs();\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateValue>(() => normalizeDate(defaultValue ?? null));\n const value = React.useMemo(\n () => (isControlled ? normalizeDate(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n\n /* ---- view ---- */\n const [internalView, setInternalView] = React.useState<MGHDateView>(() => (views.includes(openTo) ? openTo : views[0]));\n const view: MGHDateView =\n viewProp !== undefined && views.includes(viewProp)\n ? viewProp\n : views.includes(internalView)\n ? internalView\n : views[0];\n const setView = React.useCallback(\n (next: MGHDateView) => {\n if (viewProp === undefined) setInternalView(next);\n onViewChange?.(next);\n },\n [viewProp, onViewChange]\n );\n\n const validation = React.useMemo<DateValidationOptions>(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear]\n );\n\n /* ---- visible month ---- */\n const [currentMonth, setCurrentMonth] = React.useState<Dayjs>(() => (value ?? referenceDate ?? today).startOf('month'));\n const changeMonth = React.useCallback(\n (month: Dayjs) => {\n const next = month.startOf('month');\n if (currentMonth.isSame(next, 'month')) return;\n setCurrentMonth(next);\n onMonthChange?.(next);\n },\n [currentMonth, onMonthChange]\n );\n\n // When a value arrives from outside (typed in the field / shortcut) scroll to it.\n const lastSeenRef = React.useRef<MGHDateValue>(value);\n React.useEffect(() => {\n const prev = lastSeenRef.current;\n lastSeenRef.current = value;\n if (value && !isDateEqual(prev, value) && !value.isSame(currentMonth, 'month')) changeMonth(value);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value]);\n\n const firstEnabledMonth = disablePast && (!minDate || isAfterDay(today, minDate)) ? today : minDate;\n const lastEnabledMonth = disableFuture && (!maxDate || isBeforeDay(today, maxDate)) ? today : maxDate;\n const canGoPrev = !firstEnabledMonth || currentMonth.isAfter(firstEnabledMonth, 'month');\n const canGoNext = !lastEnabledMonth || currentMonth.isBefore(lastEnabledMonth, 'month');\n\n /* ---- focus management (roving tabindex + focus after a view change) ---- */\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const yearsRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef(autoFocus);\n const [focusedDay, setFocusedDay] = React.useState<Dayjs>(() => value ?? referenceDate ?? today);\n\n React.useEffect(() => {\n if (!pendingFocusRef.current) return undefined;\n const id = window.setTimeout(() => {\n pendingFocusRef.current = false;\n rootRef.current?.querySelector<HTMLElement>('.mgh-dp-view [tabindex=\"0\"]')?.focus({ preventScroll: true });\n }, 0);\n return () => window.clearTimeout(id);\n });\n\n // Scroll the selected (or current) year to the middle of the list, like MUI's YearCalendar.\n React.useEffect(() => {\n if (view !== 'year') return;\n const container = yearsRef.current;\n const target =\n container?.querySelector<HTMLElement>('.mgh-dp-pill--selected') ??\n container?.querySelector<HTMLElement>('[tabindex=\"0\"]');\n if (container && target) {\n container.scrollTop = target.offsetTop - container.clientHeight / 2 + target.offsetHeight / 2;\n }\n }, [view]);\n\n /* ---- selection (MUI `useViews` semantics) ---- */\n const commit = React.useCallback(\n (next: Dayjs, fromView: MGHDateView) => {\n const index = views.indexOf(fromView);\n const nextView = index >= 0 ? views[index + 1] : undefined;\n const selectionState: MGHDateSelectionState = nextView ? 'partial' : 'finish';\n if (!isControlled) setInternalValue(next);\n onChange?.(next, selectionState, fromView);\n if (nextView) {\n pendingFocusRef.current = true;\n setView(nextView);\n }\n },\n [views, isControlled, onChange, setView]\n );\n\n const goToNextView = React.useCallback(() => {\n const nextView = views[views.indexOf(view) + 1];\n if (!nextView) return;\n pendingFocusRef.current = true;\n setView(nextView);\n }, [views, view, setView]);\n\n const selectDay = (day: Dayjs) => {\n if (disabled || readOnly || isDateDisabled(day, validation, today)) return;\n setFocusedDay(day);\n commit(mergeDateAndTime(day, value ?? referenceDate), 'day');\n };\n\n /** Shared by the year and month views: move the (or a reference) date, then jump to the closest enabled day. */\n const selectPeriod = (candidate: Dayjs, unit: 'year' | 'month', fromView: MGHDateView) => {\n if (disabled || readOnly) return;\n const periodStart = candidate.startOf(unit);\n const periodEnd = candidate.endOf(unit);\n const closest = isDateDisabled(candidate, validation, today)\n ? findClosestEnabledDate(\n candidate,\n {\n ...validation,\n minDate: minDate && isAfterDay(minDate, periodStart) ? minDate : periodStart,\n maxDate: maxDate && isBeforeDay(maxDate, periodEnd) ? maxDate : periodEnd,\n },\n today\n )\n : candidate;\n if (closest) {\n changeMonth(closest);\n setFocusedDay(closest);\n commit(closest, fromView);\n if (unit === 'year') onYearChange?.(closest);\n } else {\n changeMonth(periodStart);\n goToNextView();\n }\n };\n\n const baseDate = value ?? referenceDate ?? today.startOf('day');\n const selectYear = (year: number) => {\n if (isYearDisabled(dayjs().year(year), validation, today)) return;\n selectPeriod(setYear(baseDate, year), 'year', 'year');\n };\n const selectMonth = (month: number) => {\n const candidate = setMonth(baseDate.year(currentMonth.year()), month);\n if (isMonthDisabled(candidate, validation, today)) return;\n selectPeriod(candidate, 'month', 'month');\n };\n\n const toggleView = () => {\n if (views.length === 1 || disabled) return;\n pendingFocusRef.current = true;\n if (views.length === 2) setView(views.find((v) => v !== view) ?? views[0]);\n else setView(views.indexOf(view) !== 0 ? views[0] : views[1]);\n };\n\n /* ---- keyboard ---- */\n const focusDay = (day: Dayjs) => {\n const key = day.format('YYYY-MM-DD');\n rootRef.current?.querySelector<HTMLButtonElement>(`[data-day=\"${key}\"]`)?.focus();\n };\n const moveDayFocus = (day: Dayjs) => {\n setFocusedDay(day);\n if (!day.isSame(currentMonth, 'month')) changeMonth(day);\n window.setTimeout(() => focusDay(day), 0);\n };\n const handleDayKeyDown = (event: React.KeyboardEvent<HTMLElement>, day: Dayjs) => {\n let next: Dayjs | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = day.subtract(1, 'day');\n break;\n case 'ArrowRight':\n next = day.add(1, 'day');\n break;\n case 'ArrowUp':\n next = day.subtract(7, 'day');\n break;\n case 'ArrowDown':\n next = day.add(7, 'day');\n break;\n case 'Home':\n next = day.startOf('week');\n break;\n case 'End':\n next = day.endOf('week');\n break;\n case 'PageUp':\n next = event.shiftKey ? day.subtract(1, 'year') : day.subtract(1, 'month');\n break;\n case 'PageDown':\n next = event.shiftKey ? day.add(1, 'year') : day.add(1, 'month');\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n selectDay(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (next) moveDayFocus(next);\n };\n\n /** Arrow-key navigation inside the month / year grids (`attr` is `data-month` or `data-year`). */\n const handleGridKeyDown = (\n event: React.KeyboardEvent<HTMLElement>,\n attr: 'data-month' | 'data-year',\n current: number,\n values: number[],\n perRow: number,\n select: (v: number) => void\n ) => {\n const index = values.indexOf(current);\n let nextIndex = index;\n switch (event.key) {\n case 'ArrowLeft':\n nextIndex = index - 1;\n break;\n case 'ArrowRight':\n nextIndex = index + 1;\n break;\n case 'ArrowUp':\n nextIndex = index - perRow;\n break;\n case 'ArrowDown':\n nextIndex = index + perRow;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = values.length - 1;\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n select(current);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (nextIndex < 0 || nextIndex >= values.length) return;\n rootRef.current?.querySelector<HTMLButtonElement>(`[${attr}=\"${values[nextIndex]}\"]`)?.focus();\n };\n\n /* ---- render: header ---- */\n const switchLabel = localeText?.calendarViewSwitchingButtonAriaLabel ?? defaultSwitchViewLabel;\n const renderHeader = () => (\n <div className=\"mgh-dp-header\">\n <div\n role=\"presentation\"\n className={cx('mgh-dp-header-label-wrap', views.length === 1 && 'mgh-dp-header-label-wrap--static')}\n aria-live=\"polite\"\n onClick={toggleView}\n >\n <div className=\"mgh-dp-header-label\">{currentMonth.format('MMMM YYYY')}</div>\n {views.length > 1 && !disabled && (\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-btn mgh-drp-btn--icon mgh-dp-header-switch',\n view !== 'day' && 'mgh-dp-header-switch--open'\n )}\n aria-label={switchLabel(view)}\n >\n <ArrowDropDownIcon />\n </button>\n )}\n </div>\n {view === 'day' && (\n <div className=\"mgh-dp-header-nav\">\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.previousMonth ?? 'Previous month'}\n title={localeText?.previousMonth ?? 'Previous month'}\n disabled={disabled || !canGoPrev}\n onClick={() => changeMonth(currentMonth.subtract(1, 'month'))}\n >\n <ChevronLeftIcon />\n </button>\n <span className=\"mgh-dp-header-nav-spacer\" />\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.nextMonth ?? 'Next month'}\n title={localeText?.nextMonth ?? 'Next month'}\n disabled={disabled || !canGoNext}\n onClick={() => changeMonth(currentMonth.add(1, 'month'))}\n >\n <ChevronRightIcon />\n </button>\n </div>\n )}\n </div>\n );\n\n /* ---- render: day view ---- */\n const weekDays = React.useMemo(() => getWeekDayLabels(dayOfWeekFormatter), [dayOfWeekFormatter]);\n const renderDayView = () => {\n const weeks = getMonthWeeks(currentMonth, fixedWeekNumber);\n const tabbableDay =\n (focusedDay.isSame(currentMonth, 'month') ? focusedDay : null) ??\n (value && value.isSame(currentMonth, 'month') ? value : null) ??\n (today.isSame(currentMonth, 'month') ? today : null) ??\n currentMonth.startOf('month');\n return (\n <div className=\"mgh-dp-view mgh-dp-view--day\" role=\"group\" aria-label={currentMonth.format('MMMM YYYY')}>\n <div className=\"mgh-drp-weekdays\" role=\"row\">\n {weekDays.map((wd) => (\n <span key={wd.key} className=\"mgh-drp-weekday\" role=\"columnheader\" aria-label={wd.full}>\n {wd.label}\n </span>\n ))}\n </div>\n <div className=\"mgh-drp-weeks\" role=\"grid\" aria-label={currentMonth.format('MMMM YYYY')}>\n {weeks.map((week) => (\n <div key={week.key} className=\"mgh-drp-week\" role=\"row\">\n {week.days.map(({ day, outsideMonth }) => {\n const hidden = outsideMonth && !showDaysOutsideCurrentMonth;\n const selected = isSameDay(day, value);\n const isToday = !disableHighlightToday && isSameDay(day, today);\n const dayDisabled = disabled || isDateDisabled(day, validation, today);\n const isTabbable = !hidden && isSameDay(day, tabbableDay);\n return (\n <div\n key={day.format('YYYY-MM-DD')}\n role=\"gridcell\"\n aria-selected={selected || undefined}\n className=\"mgh-drp-day-wrap\"\n >\n <button\n type=\"button\"\n data-day={day.format('YYYY-MM-DD')}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={day.format('dddd, MMMM D, YYYY')}\n aria-current={isToday ? 'date' : undefined}\n aria-disabled={dayDisabled || undefined}\n disabled={hidden}\n className={cx(\n 'mgh-drp-day',\n hidden && 'mgh-drp-day--hidden',\n outsideMonth && !hidden && 'mgh-drp-day--outside',\n selected && 'mgh-drp-day--selected',\n isToday && 'mgh-drp-day--today',\n dayDisabled && 'mgh-drp-day--disabled'\n )}\n onClick={() => selectDay(day)}\n onFocus={() => setFocusedDay(day)}\n onKeyDown={(event) => handleDayKeyDown(event, day)}\n >\n {day.date()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n /* ---- render: month view ---- */\n const renderMonthView = () => {\n const months = Array.from({ length: 12 }, (_, i) => i);\n const selectedMonth = value && value.year() === currentMonth.year() ? value.month() : null;\n const currentMonthIndex = today.year() === currentMonth.year() ? today.month() : null;\n const tabbable = selectedMonth ?? currentMonthIndex ?? 0;\n return (\n <div className=\"mgh-dp-view mgh-dp-view--month\">\n <div className=\"mgh-dp-months\" role=\"radiogroup\" aria-label={currentMonth.format('YYYY')}>\n {months.map((month) => {\n const monthDate = currentMonth.month(month);\n const monthDisabled = disabled || isMonthDisabled(monthDate, validation, today);\n const selected = selectedMonth === month;\n return (\n <div key={month} className={cx('mgh-dp-cell', monthsPerRow === 4 && 'mgh-dp-cell--per-row-4')}>\n <button\n type=\"button\"\n role=\"radio\"\n data-month={month}\n tabIndex={tabbable === month ? 0 : -1}\n aria-checked={selected}\n aria-current={currentMonthIndex === month ? 'date' : undefined}\n aria-disabled={monthDisabled || undefined}\n aria-label={monthDate.format('MMMM YYYY')}\n className={cx(\n 'mgh-dp-pill mgh-dp-month',\n selected && 'mgh-dp-pill--selected',\n currentMonthIndex === month && 'mgh-dp-pill--current',\n monthDisabled && 'mgh-dp-pill--disabled'\n )}\n onClick={() => selectMonth(month)}\n onKeyDown={(event) =>\n handleGridKeyDown(event, 'data-month', month, months, monthsPerRow, selectMonth)\n }\n >\n {monthDate.format('MMM')}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n );\n };\n\n /* ---- render: year view ---- */\n const renderYearView = () => {\n const years = getYearRange(minDate, maxDate);\n const selectedYear = value ? value.year() : null;\n const tabbable =\n (selectedYear != null && years.includes(selectedYear) ? selectedYear : null) ??\n (years.includes(today.year()) ? today.year() : null) ??\n (years.includes(currentMonth.year()) ? currentMonth.year() : years[0]);\n return (\n <div className=\"mgh-dp-view mgh-dp-view--year\">\n <div ref={yearsRef} className=\"mgh-dp-years\" role=\"radiogroup\" aria-label=\"Year\">\n {years.map((year) => {\n const yearDate = currentMonth.year(year);\n const yearDisabled = disabled || isYearDisabled(yearDate, validation, today);\n const selected = selectedYear === year;\n const isCurrent = today.year() === year;\n return (\n <div key={year} className={cx('mgh-dp-cell', yearsPerRow === 4 && 'mgh-dp-cell--per-row-4')}>\n <button\n type=\"button\"\n role=\"radio\"\n data-year={year}\n tabIndex={tabbable === year ? 0 : -1}\n aria-checked={selected}\n aria-current={isCurrent ? 'date' : undefined}\n aria-disabled={yearDisabled || undefined}\n className={cx(\n 'mgh-dp-pill mgh-dp-year',\n selected && 'mgh-dp-pill--selected',\n isCurrent && 'mgh-dp-pill--current',\n yearDisabled && 'mgh-dp-pill--disabled'\n )}\n onClick={() => selectYear(year)}\n onKeyDown={(event) =>\n handleGridKeyDown(event, 'data-year', year, years, yearsPerRow, selectYear)\n }\n >\n {year}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={rootRef}\n className={cx(\n 'mgh-dp-calendar',\n disabled && 'mgh-dp-calendar--disabled',\n readOnly && 'mgh-dp-calendar--read-only',\n className\n )}\n data-mgh-theme={themeMode}\n data-view={view}\n style={style}\n >\n {renderHeader()}\n {view === 'day' && renderDayView()}\n {view === 'month' && renderMonthView()}\n {view === 'year' && renderYearView()}\n </div>\n );\n}\n\nexport default MGHDateCalendar;\n","import React from 'react';\nimport dayjs from 'dayjs';\nimport type {\n MGHDateAction,\n MGHDateChangeContext,\n MGHDatePickerLocaleText,\n MGHDatePickerProps,\n MGHDateSelectionState,\n MGHDateShortcut,\n MGHDateValidationError,\n MGHDateValue,\n} from './MGHDatePicker.types';\nimport { useMGHDatePickerStyles } from './MGHDatePicker.styles';\nimport { MGHDateCalendar } from './MGHDateCalendar';\nimport { CalendarIcon, CloseIcon } from '../MGHDateRangePicker/icons';\nimport { Popover, TextField } from '../MGHDateRangePicker/primitives';\nimport { cx, formatDate, parseDateText } from '../MGHDateRangePicker/utils';\nimport { isDateEqual, normalizeDate, validateDate } from './utils';\n\nexport const MGH_DATE_PICKER_DEFAULT_LOCALE_TEXT: MGHDatePickerLocaleText = {\n openPicker: (formattedDate) => (formattedDate ? `Choose date, selected date is ${formattedDate}` : 'Choose date'),\n clear: 'Clear',\n today: 'Today',\n cancel: 'Cancel',\n accept: 'OK',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n calendarViewSwitchingButtonAriaLabel: (view) =>\n view === 'year' ? 'year view is open, switch to calendar view' : 'calendar view is open, switch to year view',\n toolbarTitle: 'Select date',\n toolbarPlaceholder: '––',\n};\n\nconst DEFAULT_FORMAT = 'MM/DD/YYYY';\nconst DEFAULT_TOOLBAR_FORMAT = 'ddd, MMM D';\n\n/**\n * MUI-free port of MUI X's `DatePicker` (desktop variant): an outlined text field with a calendar\n * button that opens a single-month calendar (with the year view behind the ▾ in the header),\n * optional shortcuts and an action bar. Values are `Dayjs | null`, so existing MUI state works unchanged.\n * Shares its field, popover and stylesheet with `MGHDateRangePicker`.\n */\nexport const MGHDatePicker = React.forwardRef<HTMLDivElement, MGHDatePickerProps>(function MGHDatePicker(\n {\n value: valueProp,\n defaultValue,\n onChange,\n onAccept,\n onError,\n open: openProp,\n onOpen,\n onClose,\n label,\n format = DEFAULT_FORMAT,\n size = 'small',\n fullWidth = false,\n clearable = false,\n openOnClick = false,\n disableOpenPicker = false,\n closeOnSelect,\n shortcuts,\n actions = [],\n showToolbar = false,\n toolbarFormat = DEFAULT_TOOLBAR_FORMAT,\n localeText: localeTextProp,\n referenceDate,\n views,\n openTo,\n view,\n onViewChange,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n shouldDisableMonth,\n shouldDisableYear,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n disableHighlightToday,\n yearsPerRow,\n monthsPerRow,\n onMonthChange,\n onYearChange,\n name,\n id: idProp,\n placeholder: placeholderProp,\n required,\n error: errorProp,\n helperText,\n autoFocus,\n inputRef,\n themeMode,\n themeVars,\n className,\n style,\n popoverClassName,\n popoverStyle,\n placement = 'bottom-start',\n },\n ref\n) {\n useMGHDatePickerStyles();\n\n const localeText = React.useMemo(\n () => ({ ...MGH_DATE_PICKER_DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n const datePlaceholder = localeText.datePlaceholder ?? format;\n const resolvedCloseOnSelect = closeOnSelect ?? !actions.includes('accept');\n\n const reactId = React.useId();\n const inputId = idProp ?? `mgh-dp-${reactId.replace(/:/g, '')}`;\n const dialogTitleId = `${inputId}-title`;\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateValue>(() => normalizeDate(defaultValue ?? null));\n const value = React.useMemo(\n () => (isControlled ? normalizeDate(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate, shouldDisableMonth, shouldDisableYear]\n );\n const validationError = React.useMemo(() => validateDate(value, validation), [value, validation]);\n const isValid = React.useCallback((date: MGHDateValue) => validateDate(date, validation) == null, [validation]);\n\n const lastErrorRef = React.useRef<MGHDateValidationError | undefined>(undefined);\n React.useEffect(() => {\n const prev = lastErrorRef.current;\n if (prev !== undefined && prev === validationError) return;\n if (prev !== undefined || validationError) onError?.(validationError, value);\n lastErrorRef.current = validationError;\n }, [validationError, value, onError]);\n\n const setValue = React.useCallback(\n (next: MGHDateValue, shortcut?: MGHDateShortcut) => {\n if (!isControlled) setInternalValue(next);\n const context: MGHDateChangeContext = { validationError: validateDate(next, validation) };\n if (shortcut) context.shortcut = shortcut;\n onChange?.(next, context);\n },\n [isControlled, onChange, validation]\n );\n\n /* ---- open / close ---- */\n const isOpenControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = React.useState(false);\n const open = isOpenControlled ? !!openProp : internalOpen;\n const valueAtOpenRef = React.useRef<MGHDateValue>(value);\n const lastAcceptedRef = React.useRef<MGHDateValue>(value);\n\n /** Fires `onAccept` only when the value differs from the last accepted one (MUI semantics). */\n const accept = React.useCallback(\n (next: MGHDateValue, force = false) => {\n if (!force && isDateEqual(next, lastAcceptedRef.current)) return;\n lastAcceptedRef.current = next;\n onAccept?.(next);\n },\n [onAccept]\n );\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n // Without an explicit `themeMode`, follow the closest `[data-mgh-theme]` ancestor (e.g. a dark MGHGrid card)\n // so the portaled popover matches the surface the field sits on.\n const [inheritedTheme, setInheritedTheme] = React.useState<'light' | 'dark' | undefined>(undefined);\n React.useEffect(() => {\n if (themeMode !== undefined) return;\n const attr = rootRef.current?.parentElement?.closest('[data-mgh-theme]')?.getAttribute('data-mgh-theme');\n setInheritedTheme(attr === 'dark' ? 'dark' : attr === 'light' ? 'light' : undefined);\n });\n const effectiveThemeMode = themeMode ?? inheritedTheme;\n\n // The popover anchor lives in state (not only in the ref) so a picker that mounts already open\n // is positioned under the field on its first commit instead of waiting for an unrelated re-render.\n const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null);\n const setRootRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n setAnchorEl(node);\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [ref]\n );\n\n const openPicker = React.useCallback(() => {\n if (disabled || readOnly || open) return;\n valueAtOpenRef.current = value;\n restoreFocusRef.current = (document.activeElement as HTMLElement | null) ?? null;\n if (!isOpenControlled) setInternalOpen(true);\n onOpen?.();\n }, [disabled, readOnly, open, value, isOpenControlled, onOpen]);\n\n const closePicker = React.useCallback(() => {\n if (!open) return;\n if (!isOpenControlled) setInternalOpen(false);\n onClose?.();\n const target = toggleRef.current ?? restoreFocusRef.current;\n window.setTimeout(() => target?.focus?.(), 0);\n }, [open, isOpenControlled, onClose]);\n\n const acceptAndClose = React.useCallback(\n (next: MGHDateValue) => {\n accept(next, true);\n closePicker();\n },\n [accept, closePicker]\n );\n\n const handleDismiss = React.useCallback(() => {\n // Clicking away / Escape keeps whatever was picked (MUI fires onAccept when the value changed).\n accept(value);\n closePicker();\n }, [value, accept, closePicker]);\n\n const handleCalendarChange = React.useCallback(\n (next: MGHDateValue, selectionState: MGHDateSelectionState) => {\n setValue(next);\n if (selectionState === 'finish' && resolvedCloseOnSelect) acceptAndClose(next);\n },\n [setValue, resolvedCloseOnSelect, acceptAndClose]\n );\n\n const handleShortcut = (shortcut: MGHDateShortcut) => {\n const next = normalizeDate(shortcut.getValue({ isValid }));\n setValue(next, shortcut);\n acceptAndClose(next);\n };\n\n const handleAction = (action: MGHDateAction) => {\n switch (action) {\n case 'clear': {\n setValue(null);\n acceptAndClose(null);\n break;\n }\n case 'today': {\n const next = dayjs().startOf('day');\n setValue(next);\n if (resolvedCloseOnSelect) acceptAndClose(next);\n break;\n }\n case 'cancel': {\n if (!isDateEqual(value, valueAtOpenRef.current)) setValue(valueAtOpenRef.current);\n closePicker();\n break;\n }\n case 'accept':\n default:\n acceptAndClose(value);\n }\n };\n\n /* ---- text field ---- */\n const [focused, setFocused] = React.useState(false);\n const [text, setText] = React.useState(() => formatDate(value, format));\n const [inputInvalid, setInputInvalid] = React.useState(false);\n\n // Keep the text in sync with the value unless the user is typing. Deliberately not re-run on\n // blur: `handleBlur` decides whether to re-format, so unparseable text stays visible with its error.\n const focusedRef = React.useRef(focused);\n focusedRef.current = focused;\n React.useEffect(() => {\n if (focusedRef.current) return;\n setText(formatDate(value, format));\n setInputInvalid(false);\n }, [value, format]);\n\n const handleTextChange = (nextText: string) => {\n setText(nextText);\n const trimmed = nextText.trim();\n if (!trimmed || trimmed.toUpperCase() === datePlaceholder.toUpperCase()) {\n setInputInvalid(false);\n if (value !== null) setValue(null);\n return;\n }\n const parsed = parseDateText(trimmed, format);\n setInputInvalid(parsed == null);\n if (parsed && !isDateEqual(parsed, value)) setValue(parsed);\n };\n\n const handleBlur = () => {\n setFocused(false);\n // Re-format on blur unless the text could not be parsed (keep it so the user sees the error).\n if (!inputInvalid) setText(formatDate(value, format));\n // Leaving the field commits a typed value (like pressing Enter).\n if (!open) accept(value);\n };\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n openPicker();\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (!open) accept(value);\n }\n };\n\n const clear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setValue(null);\n accept(null);\n };\n\n const hasValue = value != null;\n const showError = !!errorProp || validationError != null || inputInvalid;\n const formattedValue = hasValue ? formatDate(value, format) : null;\n\n const openButton = !disableOpenPicker && (\n <button\n ref={toggleRef}\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.openPicker(formattedValue)}\n title={localeText.openPicker(formattedValue)}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (open) handleDismiss();\n else openPicker();\n }}\n >\n <CalendarIcon size={size === 'small' ? 20 : 24} />\n </button>\n );\n\n const clearButton = clearable && hasValue && !disabled && !readOnly && (\n <button\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.clear}\n title={localeText.clear}\n onClick={clear}\n >\n <CloseIcon size={size === 'small' ? 18 : 20} />\n </button>\n );\n\n const themeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...style }),\n [themeVars, style]\n );\n const popoverThemeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...popoverStyle }),\n [themeVars, popoverStyle]\n );\n\n /* ---- shortcuts / actions / toolbar ---- */\n const shortcutItems = React.useMemo(\n () =>\n (shortcuts ?? []).map((shortcut, index) => {\n let shortcutValue: MGHDateValue = null;\n try {\n shortcutValue = normalizeDate(shortcut.getValue({ isValid }));\n } catch {\n /* ignore */\n }\n return { shortcut, key: shortcut.id ?? `${shortcut.label}-${index}`, value: shortcutValue };\n }),\n [shortcuts, isValid]\n );\n\n const renderToolbar = () => (\n <div className=\"mgh-drp-toolbar mgh-dp-toolbar\">\n <p className=\"mgh-drp-toolbar-title\" id={dialogTitleId}>\n {localeText.toolbarTitle}\n </p>\n <div className=\"mgh-dp-toolbar-date\" aria-live=\"polite\">\n {value ? value.format(toolbarFormat) : localeText.toolbarPlaceholder}\n </div>\n </div>\n );\n\n const renderActions = () =>\n actions.length > 0 && (\n <div className=\"mgh-drp-actions\">\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n className={cx('mgh-drp-btn', (action === 'accept' || action === 'today') && 'mgh-drp-btn--primary')}\n onClick={() => handleAction(action)}\n >\n {localeText[action]}\n </button>\n ))}\n </div>\n );\n\n return (\n <div\n ref={setRootRef}\n className={cx('mgh-drp mgh-dp', fullWidth && 'mgh-drp--full-width', className)}\n data-mgh-theme={effectiveThemeMode}\n style={themeStyle}\n >\n <TextField\n id={inputId}\n name={name}\n label={label}\n value={text}\n placeholder={placeholderProp ?? datePlaceholder}\n size={size}\n fullWidth={fullWidth}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n error={showError}\n focused={focused}\n clickable={openOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n ariaLabel={label == null ? localeText.toolbarTitle : undefined}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={handleTextChange}\n onFocus={() => setFocused(true)}\n onBlur={handleBlur}\n onClick={() => openOnClick && openPicker()}\n onKeyDown={handleInputKeyDown}\n />\n {helperText != null && helperText !== '' && (\n <div className={cx('mgh-drp-helper', showError && 'mgh-drp-helper--error')}>{helperText}</div>\n )}\n\n <Popover\n open={open}\n anchorEl={anchorEl}\n placement={placement}\n onDismiss={handleDismiss}\n themeMode={effectiveThemeMode}\n className={popoverClassName}\n style={popoverThemeStyle}\n labelledBy={showToolbar ? dialogTitleId : undefined}\n >\n <div className={cx('mgh-drp-layout', showToolbar && 'mgh-drp-layout--with-toolbar')}>\n {showToolbar && renderToolbar()}\n <div className=\"mgh-drp-layout-main\">\n {shortcutItems.length > 0 && (\n <ul className=\"mgh-drp-shortcuts\" aria-label=\"Shortcuts\">\n {shortcutItems.map(({ shortcut, key, value: shortcutValue }) => (\n <li key={key}>\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-shortcut',\n hasValue && isDateEqual(shortcutValue, value) && 'mgh-drp-shortcut--selected'\n )}\n disabled={disabled || readOnly}\n onClick={() => handleShortcut(shortcut)}\n >\n {shortcut.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n <MGHDateCalendar\n value={value}\n onChange={handleCalendarChange}\n referenceDate={referenceDate}\n views={views}\n openTo={openTo}\n view={view}\n onViewChange={onViewChange}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n shouldDisableMonth={shouldDisableMonth}\n shouldDisableYear={shouldDisableYear}\n showDaysOutsideCurrentMonth={showDaysOutsideCurrentMonth}\n fixedWeekNumber={fixedWeekNumber}\n dayOfWeekFormatter={dayOfWeekFormatter}\n disableHighlightToday={disableHighlightToday}\n yearsPerRow={yearsPerRow}\n monthsPerRow={monthsPerRow}\n onMonthChange={onMonthChange}\n onYearChange={onYearChange}\n localeText={localeText}\n themeMode={effectiveThemeMode}\n autoFocus\n />\n </div>\n {renderActions()}\n </div>\n </Popover>\n </div>\n );\n});\n\nMGHDatePicker.displayName = 'MGHDatePicker';\n\nexport default MGHDatePicker;\n","import Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\n\nimport { ConfirmDialogProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nexport default function ConfirmDialog({ title, content, action, open, onClose, ...other }: ConfirmDialogProps) {\n return (\n <Dialog fullWidth maxWidth=\"xs\" open={open} onClose={onClose} {...other}>\n <DialogTitle sx={{ pb: 2 }}>{title}</DialogTitle>\n\n {content && <DialogContent sx={{ typography: 'body2' }}> {content} </DialogContent>}\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n {action}\n </DialogActions>\n </Dialog>\n );\n}\n","import {\n GridToolbarExportContainer,\n GridCsvExportMenuItem,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n} from '@mui/x-data-grid-premium';\nimport React from 'react';\nimport { ExportContainerProps } from './CustomGridToolbarExport.types';\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomGridToolbarExport({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n // color,\n customMenuItem,\n ...other\n}: ExportContainerProps) {\n return (\n <GridToolbarExportContainer\n {...other}\n // color={color}\n >\n {customMenuItem}\n <GridCsvExportMenuItem options={csvOptions} />\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n );\n}\n","import { JSX } from 'react';\n\nimport { Dialog, Typography, DialogContent, CircularProgress } from '@mui/material';\nimport React from 'react';\n\n/// ---------------------------------------------------------------------------------------\n\ninterface ExportingProps {\n open: boolean;\n text?: JSX.Element | string;\n}\nexport default function ExportingDialog({\n open,\n text = (\n <>\n Your export is currently being built. Some larger exports can take a couple of minutes to complete. <br />\n <br />\n Please do not close your browser or refresh the page.\n </>\n ),\n}: ExportingProps) {\n return (\n <Dialog open={open} fullWidth sx={{ p: 4 }}>\n <DialogContent sx={{ p: 4, textAlign: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ mb: 3 }}>\n {text}\n </Typography>\n <CircularProgress />\n </DialogContent>\n </Dialog>\n );\n}\n"],"names":["useResponsive","query","start","end","theme","useTheme","mediaUp","useMediaQuery","breakpoints","up","mediaDown","down","mediaBetween","between","mediaOnly","only","CustomNoRowsOverlay","text","useSettingsContext","themeMode","palette","mode","StyledGridOverlay","styled","display","alignItems","justifyContent","height","fill","fillOpacity","React","createElement","Box","component","alt","src","sx","width","maxWidth","mb","canUseLocalStorage","window","localStorage","readLocalStorage","key","value","getItem","JSON","parse","writeLocalStorage","setItem","stringify","MGHGridToolbar","showColumnsButton","showFilterButton","showExportButton","showQuickFilter","renderOtherButtons","renderDateRange","customMenuItem","showCsvOption","Toolbar","style","Tooltip","title","ColumnsPanelTrigger","render","ToolbarButton","GridViewColumnIcon","fontSize","FilterPanelTrigger","props","state","color","Badge","badgeContent","filterCount","variant","GridFilterListIcon","CustomGridToolbarExport","DataGridQuickFilter","csvOptions","allColumns","excelOptions","printOptions","other","GridToolbarExportContainer","map","el","GridCsvExportMenuItem","options","GridExcelExportMenuItem","GridPrintExportMenuItem","StyledQuickFilter","QuickFilter","StyledToolbarButton","ownerState","gridArea","zIndex","opacity","expanded","pointerEvents","transition","transitions","create","StyledTextField","TextField","overflowX","QuickFilterTrigger","triggerProps","enterDelay","GridSearchIcon","QuickFilterControl","ref","controlProps","inputRef","placeholder","size","slotProps","input","startAdornment","InputAdornment","position","endAdornment","QuickFilterClear","edge","material","marginRight","GridCloseIcon","Iconify","forwardRef","icon","Icon","StyledLabel","lightMode","filledVariant","outlinedVariant","softVariant","defaultStyle","common","white","grey","backgroundColor","primary","border","secondary","alpha","colorStyle","contrastText","main","minWidth","lineHeight","borderRadius","cursor","whiteSpace","textTransform","padding","spacing","typography","pxToRem","fontWeight","fontWeightBold","duration","shorter","Label","children","startIcon","endIcon","iconStyles","objectFit","pl","pr","mr","ml","GROUPING_COLUMN_FIELD","CHECKBOX_FIELD","DETAIL_PANEL_TOGGLE_FIELD","AGGREGATION_FOOTER_ID","INTERNAL_FIELDS","Set","DENSITY_FACTORS","compact","standard","comfortable","DEFAULT_ROW_HEIGHT","DEFAULT_HEADER_HEIGHT","isInternalField","field","has","isNil","isEmptyValue","Array","isArray","length","clamp","min","max","Math","cx","classNames","filter","Boolean","join","uniqueId","counter","prefix","getRowIdFromRow","row","getRowId","id","normalizeSelectionModel","allIds","type","ids","forEach","add","toDate","Date","Number","isNaN","getTime","dayjs","isDayjs","isValid","d","parsed","formatDate","withTime","date","format","startOfUnit","startOf","valueOf","isValueOptionObject","option","getOptionValue","col","getOptionLabel","label","String","resolveValueOptions","valueOptions","getCellValue","api","raw","undefined","valueGetter","defaultFormatValue","match","find","isFinite","getFormattedValue","valueFormatter","formattedValueToString","formatted","collator","Intl","Collator","numeric","sensitivity","nilFirst","v1","v2","n1","n2","numberComparator","nil","stringComparator","s1","s2","compare","stringOrNumberComparator","p1","p2","dateComparator","d1","d2","booleanComparator","getDefaultComparator","lower","toLowerCase","hasValue","item","stringFilterOperators","inputType","getApplyFilterFn","needle","indexOf","s","lastIndexOf","requiresFilterValue","set","numberOperator","filterValue","cell","n","numberFilterOperators","a","b","v","dateOperator","filterDate","filterTime","cellDate","getDateFilterOperators","booleanFilterOperators","expected","singleSelectFilterOperators","getColumnFilterOperators","filterOperators","getDefaultFilterOperators","normalizeColumn","isNumber","isBoolean","isActions","headerName","align","headerAlign","sortable","filterable","hideable","resizable","pinnable","groupable","aggregable","editable","disableColumnMenu","disableExport","internalColumn","disableReorder","CHECKBOX_COLUMN_DEF","DETAIL_PANEL_TOGGLE_COLUMN_DEF","UNITLESS_PROPERTIES","isSelectorKey","test","serializeDeclarations","block","Object","keys","property","kebab","replace","m","toKebabCase","formatCssValue","buildScopedCss","scope","out","charAt","inner","declarations","push","selector","scopeSelector","split","part","trim","numericValues","values","BUILT_IN_AGGREGATION_FUNCTIONS","sum","columnTypes","apply","nums","reduce","acc","avg","defined","every","dates","slice","sort","sorted","DEFAULT_LOCALE_TEXT","noRowsLabel","loadingLabel","toolbarColumns","toolbarFilters","toolbarExport","toolbarDensity","toolbarQuickFilterPlaceholder","toolbarQuickFilterLabel","toolbarExportCSV","toolbarExportExcel","toolbarExportPrint","densityCompact","densityStandard","densityComfortable","columnsPanelSearchPlaceholder","columnsPanelShowAll","columnsPanelHideAll","columnsPanelReset","filterPanelAddFilter","filterPanelRemoveAll","filterPanelDeleteIcon","filterPanelColumns","filterPanelOperator","filterPanelValue","filterPanelInputPlaceholder","filterPanelLogicOperator","filterPanelOperatorAnd","filterPanelOperatorOr","columnMenuSortAsc","columnMenuSortDesc","columnMenuUnsort","columnMenuFilter","columnMenuHideColumn","columnMenuManageColumns","columnMenuPinLeft","columnMenuPinRight","columnMenuUnpin","columnMenuGroup","name","columnMenuUngroup","columnMenuAggregation","aggregationMenuItemHeader","aggregationFunctionLabelNone","aggregationFunctionLabelSum","aggregationFunctionLabelAvg","aggregationFunctionLabelMin","aggregationFunctionLabelMax","aggregationFunctionLabelSize","footerRowSelected","count","toLocaleString","footerTotalRows","footerPaginationRowsPerPage","footerPaginationDisplayedRows","from","to","footerPaginationFirstPage","footerPaginationPreviousPage","footerPaginationNextPage","footerPaginationLastPage","checkboxSelectionHeaderName","checkboxSelectionSelectAllRows","checkboxSelectionUnselectAllRows","checkboxSelectionSelectRow","checkboxSelectionUnselectRow","booleanCellTrueLabel","booleanCellFalseLabel","detailPanelToggle","expandDetailPanel","collapseDetailPanel","groupingColumnHeaderName","groupColumn","unGroupColumn","actionsCellMore","columnHeaderSortIconLabel","columnMenuLabel","clearSearch","measureContext","measureText","font","document","canvas","getContext","downloadBlob","blob","fileName","url","URL","createObjectURL","anchor","href","download","body","appendChild","click","setTimeout","removeChild","revokeObjectURL","MGH_GRID_STYLE_ID","MGH_GRID_CSS","injected","useInsertion","useInsertionEffect","useLayoutEffect","useEffect","useMGHGridStyles","injectStyles","getElementById","setAttribute","textContent","head","MGHGridContext","createContext","displayName","useMGHGridContext","ctx","useContext","Error","useLatestRef","useRef","current","useControlledState","controlled","defaultValue","onChange","isControlled","internal","setInternal","useState","valueRef","controlledRef","onChangeRef","useCallback","next","resolved","is","idCounter","buildExportTable","columns","resolveExportColumns","all","getAllColumns","fields","byField","Map","c","f","get","getVisibleColumns","getRowsToExport","getSortedRowIds","rows","getRow","headers","sanitizeFileName","fallback","extension","base","endsWith","defaultFileBase","escapeCsvCell","delimiter","getDataAsCsv","includeHeaders","table","lines","h","cells","useRawValues","UTF8_BOM","fromCharCode","CRC_TABLE","Uint32Array","k","textEncoder","TextEncoder","encodeUtf8","encode","utf8","unescape","encodeURIComponent","Uint8Array","i","charCodeAt","concatBytes","chunks","total","offset","zipStore","entries","localChunks","centralChunks","entry","nameBytes","crc","bytes","crc32","data","local","lv","DataView","buffer","setUint32","setUint16","central","cv","centralDirectory","eocd","ev","concat","INVALID_XML_CHARS","RegExp","escapeXml","stripInvalidXml","columnLetter","index","letters","rem","floor","XML_HEADER","buildSheetXml","columnWidths","rowsXml","rowIndex","inlineString","xmlCells","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","lastCol","lastRow","cols","w","STYLES_XML","CONTENT_TYPES_XML","ROOT_RELS_XML","WORKBOOK_RELS_XML","buildWorkbookXml","sheetName","buildCoreXml","now","toISOString","APP_XML","buildXlsx","widths","explicit","columnsStyles","r","len","cleaned","sanitizeSheetName","escapeHtml","printGridElement","params","done","onDone","printGridElementUnsafe","error","console","cardElement","hideToolbar","hideFooter","copyStyles","clone","cloneNode","syncFormState","source","target","sourceInputs","querySelectorAll","targetInputs","t","tagName","dst","checked","indeterminate","sourceCanvases","targetCanvases","img","ownerDocument","toDataURL","cssText","replaceWith","remove","classList","removeAttribute","flexGrow","styles","links","doc","styleSheets","sheet","rules","cssRules","rule","collectStyles","iframe","finished","finish","parentNode","win","contentWindow","contentDocument","open","write","close","css","printStyle","pageStyle","h1","className","adoptNode","async","waitForImages","timeoutMs","Promise","resolve","images","complete","remaining","timer","onSettled","clearTimeout","addEventListener","once","onBeforePrint","onafterprint","focus","print","run","keyToString","buildGroupTree","groupingFields","columnsByField","emptyLabel","build","items","depth","parentId","path","buckets","getGroupingValue","groupingValueGetter","keyStr","node","parent","groupingField","groupingKey","groupingLabel","childGroups","leaves","descendants","nodes","collectTreeLeaves","roots","root","aggregateRows","aggregationModel","functions","result","fnName","fn","createIcon","rest","viewBox","focusable","ViewColumnIcon","FilterListIcon","SearchIcon","CloseIcon","DownloadIcon","ArrowUpwardIcon","ArrowDownwardIcon","MoreVertIcon","CheckIcon","ExpandMoreIcon","ChevronRightIcon","ChevronLeftIcon","FirstPageIcon","LastPageIcon","PushPinIcon","DeleteIcon","AddIcon","DensitySmallIcon","DensityMediumIcon","DensityLargeIcon","DragIndicatorIcon","PrintIcon","TableChartIcon","DescriptionIcon","VisibilityOffIcon","FunctionsIcon","WorkspacesIcon","EmptyBoxIcon","Fragment","Button","active","IconButton","TextInput","Select","Field","htmlFor","Checkbox","forwardedRef","innerRef","setRef","Spinner","role","Popover","anchorEl","onClose","placement","autoFocus","ignoreOutsideClickOn","setPosition","top","left","ready","update","vw","innerWidth","vh","innerHeight","offsetWidth","offsetHeight","isConnected","getBoundingClientRect","right","bottom","prev","observer","ResizeObserver","observe","removeEventListener","disconnect","handlePointerDown","event","contains","some","closest","handleKeyDown","querySelector","stop","stopPropagation","createPortal","tabIndex","visibility","onClick","onDoubleClick","onMouseDown","onKeyDown","Menu","first","preventDefault","currentIndex","activeElement","MenuItem","selected","disabled","hideMenu","MenuDivider","MenuSection","MGHGridColumnsButton","localeText","isOpen","preferencePanel","openedPanelValue","hidePreferences","showPreferences","currentTarget","MGHGridFiltersButton","MGHGridDensitySelector","setAnchor","o","density","setDensity","MGHGridExportMenuItem","MGHGridExportMenu","showExcelOption","showPrintOption","rootProps","customItems","Children","child","isValidElement","cloneElement","resolvedPrintOptions","header","exportDataAsCsv","exportDataAsExcel","exportDataAsPrint","MGHGridQuickFilter","debounceMs","alwaysExpanded","externalValue","quickFilterValues","setText","setExpanded","delay","quickFilterDebounceMs","lastExternal","commit","setQuickFilterValues","clear","isExpanded","expand","handleChange","onBlur","blur","showDensitySelector","quickFilterPlaceholder","showColumns","disableColumnSelector","showFilters","disableColumnFilter","showDensity","disableDensitySelector","MGHGridPagination","page","pageSize","paginationModel","rowCount","pageCount","pageSizeOptions","setPageSize","setPage","MGHGridFooter","selectedCount","rowSelectionModel","showSelected","hideFooterSelectedRowCount","showPagination","pagination","hideFooterPagination","showRowCount","hideFooterRowCount","MGHGridColumnsPanel","visibleColumns","visibleFields","useMemo","search","setSearch","model","columnVisibilityModel","filtered","setAll","visible","setColumnVisibilityModel","setColumnVisibility","useDebouncedValue","onCommit","setLocal","TextValueInput","MultiValueInput","column","joined","multiple","selectedOptions","FilterValueInput","operator","InputComponent","Component","applyValue","createFilterItem","MGHGridFilterPanel","filterableColumns","filterModel","logicOperator","targetField","seeded","upsertFilterItem","updateItem","patch","canAddMore","disableMultipleColumnsFiltering","paddingTop","operators","op","showLogic","deleteFilterItem","setFilterLogicOperator","nextColumn","nextOperators","keepOperator","nextOperator","nextIsMulti","currentIsMulti","addItem","setFilterModel","MGHGridColumnMenu","panelAnchorEl","isGroupingColumn","sortItem","sortModel","pinned","isColumnPinned","isGrouped","rowGroupingModel","aggregation","canSort","disableColumnSorting","canFilter","canHide","canPin","disableColumnPinning","canGroup","disableRowGrouping","aggregationFunctions","availableAggregationFunctions","canAggregate","disableAggregation","anchorForPanel","sortColumn","showFilterPanel","transform","pinColumn","unpinColumn","removeRowGroupingCriteria","addRowGroupingCriteria","gap","setAggregationModel","MGHGridNoRowsOverlay","imageSrc","MGHGridLoadingOverlay","MGHGridActionsCellItem","showInMenu","ActionsCell","actions","moreLabel","inline","inMenu","action","EMPTY_ARRAY","EMPTY_OBJECT","EMPTY_MAP","DEFAULT_SORTING_ORDER","DEFAULT_PAGE_SIZE_OPTIONS","DEFAULT_FILTER_MODEL","quickFilterExcludeHiddenColumns","sanitizeStyle","toDateInputValue","pad","padStart","MGHGrid","columnsProp","loading","renderHeaderEndContent","renderHeaderCenterContent","disableCard","cardClassName","boxClassName","cardStyle","cardSx","boxStyle","boxSx","themeVars","showToolbar","toolbarProps","slots","noRowsText","localeTextProp","rowHeight","rowHeightProp","columnHeaderHeight","getRowHeight","autoHeight","disableVirtualization","densityProp","onDensityChange","paginationModelProp","onPaginationModelChange","sortModelProp","onSortModelChange","sortingOrder","disableMultipleColumnsSorting","filterModelProp","onFilterModelChange","columnVisibilityModelProp","onColumnVisibilityModelChange","columnVisibilityStorageKey","columnOrderStorageKey","columnWidthStorageKey","pinnedColumnsStorageKey","onColumnOrderChange","onColumnWidthChange","disableColumnResize","disableColumnReorder","pinnedColumns","pinnedColumnsProp","onPinnedColumnsChange","checkboxSelection","checkboxSelectionVisibleOnly","disableRowSelectionOnClick","disableMultipleRowSelection","rowSelectionModelProp","onRowSelectionModelChange","isRowSelectable","keepNonExistentRowsSelected","getRowClassName","onRowClick","onRowDoubleClick","onCellClick","onCellDoubleClick","pinnedRows","getDetailPanelContent","getDetailPanelHeight","detailPanelExpandedRowIds","detailPanelExpandedRowIdsProp","onDetailPanelExpandedRowIdsChange","rowGroupingModelProp","onRowGroupingModelChange","defaultGroupingExpansionDepth","groupingColDef","isGroupExpandedByDefault","aggregationModelProp","onAggregationModelChange","aggregationFunctionsProp","aggregationPosition","processRowUpdate","onProcessRowUpdateError","onCellEditStop","isCellEditable","initialState","apiRef","onStateChange","gridId","reactUseId","useId","useStableId","rootRef","cardRef","scrollerRef","toolbarRef","forceUpdate","setTick","useForceUpdate","latest","getDetails","apiObject","L","apiImpl","rowsById","getRowModels","getAllRowIds","rowEntries","e","getRowNode","nodesById","getSortedRows","sortedLeaves","getVisibleRows","pagedRows","dr","getRowIndexRelativeToVisibleRows","findIndex","updateRows","updates","existing","setRowOverride","orderedUserColumns","visibleUserColumns","getColumn","getColumnIndex","useVisibleColumns","getColumnVisibilityModel","isVisible","setColumnWidth","setColumnIndex","targetIndex","autosizeColumns","side","getPinnedColumns","setPinnedColumns","getSortModel","setSortModel","direction","allowMultipleSorting","getFilterModel","upsertFilterItems","targetColumnField","hideFilterPanel","panel","getSelectedRows","selectedIds","getRowSelectionModel","setRowSelectionModel","normalized","setSelectedIds","selectRow","isSelected","resetSelection","selectRows","isRowSelected","isRowSelectableFn","nextPage","setPaginationModel","nextPageSize","csv","bom","utf8WithBom","Blob","startPrint","toggleDetailPanel","setExpandedDetailPanels","getExpandedDetailPanels","expandedDetailPanels","getRowGroupingModel","setRowGroupingModel","groupingIndex","splice","setRowChildrenExpansion","getRowGroupChildren","groupId","group","groupsById","getAggregationModel","startCellEditMode","stopCellEditMode","ignoreModifications","getCellMode","editing","editingCell","setEditCellValue","setEditValue","getCellParams","buildCellParams","setCellFocus","pendingFocusRef","setFocusedCell","scrollToIndexes","scroll","scroller","scrollLeft","scrollTop","getScrollPosition","rootElementRef","persisted","order","sorting","rowGrouping","controlledExpandedDetail","detailPanel","expandedRowIds","controlledSelection","orderedFields","setOrderedFields","setColumnWidths","dims","dimensions","groupExpansion","setGroupExpansion","setEditingCell","editValue","focusedCell","setPreferencePanel","columnMenu","setColumnMenu","resizingField","setResizingField","printState","setPrintState","printing","drag","setDrag","setScrollTop","scrollRaf","lastClickedIdRef","overrideState","setOverrideState","rowOverrides","viewportWidth","viewportHeight","enabled","setSize","clientWidth","clientHeight","useElementSize","densityFactor","round","headerHeight","headerTitleLines","fontFamily","setFontFamily","family","getComputedStyle","cellFont","headerFont","measureHeaderWidth","isGrouping","showMenu","ceil","userColumns","groupingActive","groupingColumn","single","seen","isColumnVisible","wanted","layout","leftFields","rightFields","visibleByField","center","ordered","headerWidths","renderHeader","computeWidths","available","overrides","minFor","Infinity","override","flex","pool","fixedTotal","remainingSpace","remainingFlex","changed","share","fixed","idx","hasPinning","x","leftOffset","isLeft","isRight","isLastLeft","isFirstRight","rightOffset","totalWidth","leftCount","rightCount","allDisplayColumnsByField","activeFilters","quickFilterColumns","filteredEntries","logicAnd","quickAnd","quickFilterLogicOperator","apiRefLocal","quickFns","lowered","getApplyQuickFilterFn","custom","results","compareEntries","sorters","dir","comparator","sortComparator","sortEntries","aggregationActive","isGroupExpanded","leafIds","processed","displayRows","tree","groupingSort","sortGroupTree","compareGroups","sortLeaves","sortLevel","flattenGroupTree","visit","groupNode","toGroupNode","l","childVisible","leaf","leafNode","totalDisplayRows","paginate","footerAggregates","rowsForFooter","groupAggregatesCache","getGroupAggregates","cached","heights","rowHeights","detailHeights","offsets","hasAuto","dh","virtual","virtualRange","overscan","viewTop","viewBottom","lo","hi","mid","handleScroll","requestAnimationFrame","cancelAnimationFrame","selectionCandidates","selectedCandidateCount","allCandidatesSelected","someCandidatesSelected","updateSelection","updater","selectionModelsEqual","equal","delete","lastId","toggleAllCandidates","allowMultiple","persistOrder","persistWidths","targets","lc","sample","isCellEditableFn","colDef","rowNode","reason","valueParser","parseEditValue","currentValue","applyRowUpdate","newRow","oldRow","then","rowId","catch","valueSetter","previousGroupingKey","formattedValue","hasFocus","cellMode","isEditable","buildRowParams","preventScroll","visibleTop","visibleBottom","scrollIntoView","colIndex","leftPinnedWidth","rightPinnedWidth","visibleLeft","visibleRight","moveFocus","rowDelta","colDelta","absolute","canReorder","resizeRef","totalRowCount","clamped","oldIndex","moveItem","list","unshift","nextItems","withId","random","toString","contextValue","renderCellContent","renderRow","kind","selectable","content","hideCount","hideDescendantCount","paddingLeft","agg","aggregates","sampleRow","cancel","renderEditCell","onValueChange","renderEditor","renderCell","getActions","cellStyle","pinnedClasses","rowIsClickable","renderRowElement","customClass","indexRelativeToCurrentPage","isFirstVisible","isFirst","isLastVisible","isLast","isAuto","minHeight","handleRowSelectionClick","allSelected","shiftKey","ctrlKey","metaKey","isFocused","isEditing","isAggregation","cellClassName","isCheckbox","isDetailToggle","toRenderRow","renderPinnedRows","renderHeaderCell","sortIndex","draggable","isDragging","isDropTarget","overField","menuOpen","headerParams","headerClassName","description","onDragStart","dataTransfer","effectAllowed","setData","onDragOver","sourceLc","dropEffect","rect","clientX","onDragLeave","onDrop","handleDrop","targetLc","without","onDragEnd","onPointerDown","handleResizeStart","startX","startWidth","lastWidth","onMove","onUp","ToolbarSlot","toolbar","FooterSlot","footer","NoRowsOverlaySlot","noRowsOverlay","LoadingOverlaySlot","loadingOverlay","mergedToolbarProps","noRowsProps","loadingProps","showNoRows","menuColumn","cardStyles","boxStyles","rootStyles","scopedCss","smDown","grid","pageRows","onScroll","renderBodyRows","detailHeight","detailContent","detailAuto","rowAuto","Provider","MGH_DATE_RANGE_PICKER_STYLE_ID","MGH_DATE_RANGE_PICKER_CSS","useMGHDateRangePickerStyles","DateRangeIcon","CalendarIcon","ArrowDropDownIcon","extend","customParseFormat","EMPTY_RANGE","toDayjs","isSameDay","isSame","isBeforeDay","isBefore","isAfterDay","isAfter","isWithinRange","day","isRangeEqual","same","y","normalizeRange","parseDateText","trimmed","strict","fallbacks","validateDay","disablePast","disableFuture","minDate","maxDate","shouldDisableDate","validateRange","startError","endError","isDayDisabled","getMonthWeeks","month","fixedWeekNumber","firstOfMonth","weeksInMonth","endOf","diff","weekCount","weeks","weekStart","days","_","outsideMonth","getWeekDayLabels","formatter","full","MGH_DATE_RANGE_DEFAULT_SHORTCUTS","getValue","today","subtract","defaultDayOfWeekFormatter","toUpperCase","MGHDateRangeCalendar","valueProp","rangePosition","rangePositionProp","onRangePositionChange","calendars","referenceDate","readOnly","showDaysOutsideCurrentMonth","dayOfWeekFormatter","disableHighlightToday","showRangePreview","onMonthChange","internalValue","setInternalValue","internalPosition","setInternalPosition","setRangePosition","validation","currentMonth","setCurrentMonth","visibleMonths","lastVisibleMonth","changeMonth","ensureVisible","lastSeenRef","canGoPrev","canGoNext","hoveredDay","setHoveredDay","preview","selectDay","nextPosition","focusedDay","setFocusedDay","focusDay","weekDays","previewStart","previewEnd","isRangeComplete","onMouseLeave","renderMonth","tabbableDay","previousMonth","nextMonth","wd","week","dayIndex","hidden","isStart","isEnd","inRange","inPreview","dayDisabled","isTabbable","firstVisible","lastVisible","daysInMonth","onMouseEnter","onFocus","onDismiss","labelledBy","fullWidth","multi","required","focused","clickable","adornment","ariaLabel","hasLabel","shrink","inputMode","autoComplete","spellCheck","MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT","fieldSeparator","openPicker","accept","toolbarTitle","MGHDateRangePicker","onAccept","onError","openProp","onOpen","fieldVariant","clearable","openOnClick","disableOpenPicker","closeOnSelect","shortcuts","idProp","placeholderProp","errorProp","helperText","popoverClassName","popoverStyle","datePlaceholder","isMulti","resolvedOpenOnClick","resolvedCloseOnSelect","includes","reactId","baseId","startId","endId","dialogTitleId","validationError","range","lastErrorRef","setValue","shortcut","context","isOpenControlled","internalOpen","setInternalOpen","valueAtOpenRef","lastAcceptedRef","force","toggleRef","restoreFocusRef","inheritedTheme","setInheritedTheme","attr","parentElement","getAttribute","effectiveThemeMode","setAnchorEl","setRootRef","closePicker","acceptAndClose","handleDismiss","handleCalendarChange","_day","focusedInput","setFocusedInput","formatSingle","singleText","setSingleText","startText","setStartText","endText","setEndText","inputInvalid","setInputInvalid","parseSegment","invalid","handleSideChange","handleBlur","handleInputKeyDown","altKey","hasValidationError","showError","openButton","clearButton","themeStyle","popoverThemeStyle","shortcutItems","shortcutValue","calendar","commonFieldProps","parts","splitRangeText","ps","pe","handleShortcut","handleAction","MGH_DATE_PICKER_STYLE_ID","MGH_DATE_PICKER_CSS","useMGHDatePickerStyles","MGH_DATE_PICKER_DEFAULT_MIN_DATE","MGH_DATE_PICKER_DEFAULT_MAX_DATE","normalizeDate","isDateEqual","mergeDateAndTime","time","hour","minute","second","millisecond","validateDate","shouldDisableMonth","shouldDisableYear","isDateDisabled","isMonthDisabled","isYearDisabled","year","findClosestEnabledDate","forward","backward","guard","MGH_DATE_PICKER_DEFAULT_SHORTCUTS","DEFAULT_VIEWS","defaultSwitchViewLabel","view","MGHDateCalendar","views","viewsProp","openTo","viewProp","onViewChange","yearsPerRow","monthsPerRow","onYearChange","internalView","setInternalView","setView","firstEnabledMonth","lastEnabledMonth","yearsRef","container","offsetTop","fromView","nextView","selectionState","goToNextView","selectPeriod","candidate","unit","periodStart","periodEnd","baseDate","selectYear","setYear","selectMonth","setMonth","toggleView","moveDayFocus","handleGridKeyDown","perRow","select","nextIndex","switchLabel","calendarViewSwitchingButtonAriaLabel","renderDayView","isToday","handleDayKeyDown","renderMonthView","months","selectedMonth","currentMonthIndex","tabbable","monthDate","monthDisabled","renderYearView","years","getYearRange","selectedYear","yearDate","yearDisabled","isCurrent","MGH_DATE_PICKER_DEFAULT_LOCALE_TEXT","formattedDate","toolbarPlaceholder","MGHDatePicker","toolbarFormat","inputId","setFocused","focusedRef","nextText","Dialog","DialogTitle","pb","DialogContent","DialogActions","p","textAlign","Typography","CircularProgress","persistedColumnVisibilityModel","persistedOrderedFields","normalizeOrderedFields","columnFields","resolvedColumnVisibilityModel","handleColumnVisibilityModelChange","details","handleColumnOrderChange","mergedInitialState","Card","CardHeader","flexWrap","flexDirection","DataGridPremium","disableRowSelectionExcludeModel","exportDataAsPrintTable","headerHtml","bodyHtml","html","cleanup","onload","srcdoc","useMGHGridApiContext","useMGHGridApiRef","useMGHGridLocaleText"],"mappings":"oiBAWgBA,EAAcC,EAAcC,EAAeC,GACvD,MAAMC,EAAQC,EAAAA,WAERC,EAAUC,EAAcH,EAAMI,YAAYC,GAAGP,IAE7CQ,EAAYH,EAAcH,EAAMI,YAAYG,KAAKT,IAEjDU,EAAeL,EAAcH,EAAMI,YAAYK,QAAQX,EAAgBC,IAEvEW,EAAYP,EAAcH,EAAMI,YAAYO,KAAKb,IAEvD,MAAc,OAAVD,EACOK,EAGG,SAAVL,EACOS,EAGG,YAAVT,EACOW,EAGJE,CACX,CCdc,SAAUE,GAAoBC,KAAEA,EAAIC,mBAAEA,IAChD,MAAMd,EAAQC,EAAAA,WACRc,EAAYD,OAAwBC,WAAaf,EAAMgB,QAAQC,MAAQ,QAEvEC,EAAoBC,EAAO,MAAPA,CAAc,KAAA,CACpCC,QAAS,OACTC,WAAY,SACZC,eAAgB,SAChBC,OAAQ,OACR,qBAAsB,CAClBC,KAAoB,UAAdT,EAAwB,UAAY,WAE9C,qBAAsB,CAClBS,KAAoB,UAAdT,EAAwB,UAAY,WAE9C,qBAAsB,CAClBS,KAAoB,UAAdT,EAAwB,UAAY,WAE9C,qBAAsB,CAClBS,KAAoB,UAAdT,EAAwB,OAAS,WAE3C,qBAAsB,CAClBU,YAA2B,UAAdV,EAAwB,MAAQ,OAC7CS,KAAoB,UAAdT,EAAwB,UAAY,WAGlD,OACIW,gBAACR,EAAiB,KACdQ,EAAAC,cAACC,MAAG,CACAC,UAAU,MACVC,IAAI,gBACJC,IAAI,qCACJC,GAAI,CAAEC,MAAO,GAAIC,SAAU,OAE/BR,EAAAC,cAACC,MAAG,CAACI,GAAI,CAAEG,GAAI,IAAMtB,GAGjC,CCsDA,MAAMuB,EAAqBA,IAAwB,oBAAXC,aAAyD,IAAxBA,OAAOC,aAE1EC,EAAwBC,IAC1B,IAAKJ,IACD,OAAO,KAEX,IACI,MAAMK,EAAQJ,OAAOC,aAAaI,QAAQF,GAC1C,OAAOC,EAASE,KAAKC,MAAMH,GAAe,IAC9C,CAAE,MACE,OAAO,IACX,GAGEI,EAAoBA,CAACL,EAAaC,KACpC,GAAKL,IAGL,IACIC,OAAOC,aAAaQ,QAAQN,EAAKG,KAAKI,UAAUN,GACpD,CAAE,MACE,MACJ,GA2LE,SAAUO,GAAeC,kBAC3BA,GAAoB,EAAIC,iBACxBA,GAAmB,EAAIC,iBACvBA,GAAmB,EAAIC,gBACvBA,GAAkB,EAAIC,mBACtBA,EAAkBC,gBAClBA,EAAeC,eACfA,EAAcC,cACdA,GAAgB,IAEhB,OACI9B,EAAAC,cAAC8B,UAAO,CAACC,MAAO,CAAEtC,QAAS,OAAQE,eAAgB,kBAC/CI,EAAAC,cAAA,MAAA,KACKsB,GACGvB,EAAAC,cAACgC,UAAO,CAACC,MAAM,WACXlC,EAAAC,cAACkC,sBAAmB,CAACC,OAAQpC,EAAAC,cAACoC,EAAAA,cAAa,OACvCrC,EAAAC,cAACqC,sBAAmBC,SAAS,YAIxCf,GACGxB,EAAAC,cAACgC,EAAAA,QAAO,CAACC,MAAM,WACXlC,EAAAC,cAACuC,qBAAkB,CACfJ,OAAQA,CAACK,EAAOC,IACZ1C,gBAACqC,EAAAA,cAAa,IAAKI,EAAOE,MAAM,WAC5B3C,EAAAC,cAAC2C,QAAK,CAACC,aAAcH,EAAMI,YAAaH,MAAM,UAAUI,QAAQ,OAC5D/C,EAAAC,cAAC+C,qBAAkB,CAACT,SAAS,eAOpDd,GACGzB,EAAAC,cAACgD,GAAwBpB,eAAgBA,EAAgBC,cAAeA,KAI/EF,EAED5B,EAAAC,cAAA,MAAA,KACK0B,EACAD,GAAmB1B,EAAAC,cAACiD,SAIrC,CASO,MAAMD,EAA0BA,EACnCE,aAAa,CAAEC,YAAY,GAC3BC,eAAe,CAAED,YAAY,GAC7BE,eACAzB,iBACAC,iBAAgB,KACbyB,KAEHvD,EAAAC,cAACuD,iCAA+BD,GAC3B1B,GAAgB4B,IAAKC,GAAOA,GAC5B5B,GAAiB9B,EAAAC,cAAC0D,yBAAsBC,QAAST,IAClDnD,EAAAC,cAAC4D,0BAAuB,CAACD,QAASP,IAClCrD,EAAAC,cAAC6D,2BAAwBF,QAASN,cAI1BJ,IAKZ,MAAMa,EAAoBtE,SAAOuE,EAAAA,YAAPvE,CAAoB,CAC1CC,QAAS,OACTC,WAAY,WAGVsE,EAAsBxE,EAAAA,OAAO4C,EAAAA,cAAP5C,CAAkD,EAAGnB,QAAO4F,iBAAY,CAChGC,SAAU,QACV5D,MAAO,cACPV,OAAQ,cACRuE,OAAQ,EACRC,QAASH,EAAWI,SAAW,EAAI,EACnCC,cAAeL,EAAWI,SAAW,OAAS,OAC9CE,WAAYlG,EAAMmG,YAAYC,OAAO,CAAC,eAGpCC,EAAkBlF,EAAAA,OAAOmF,EAAAA,UAAPnF,CAErB,EAAGnB,QAAO4F,iBAAY,CACrBC,SAAU,QACVU,UAAW,OACXtE,MAAO2D,EAAWI,SAAW,IAAM,uBACnCD,QAASH,EAAWI,SAAW,EAAI,EACnCE,WAAYlG,EAAMmG,YAAYC,OAAO,CAAC,QAAS,eAGnD,OACI1E,gBAAC+D,EAAiB,KACd/D,EAAAC,cAAC6E,sBACG1C,OAAQA,CAAC2C,EAAcrC,IACnB1C,EAAAC,cAACgC,EAAAA,QAAO,CAACC,MAAM,SAAS8C,WAAY,GAChChF,EAAAC,cAACgE,MACOc,EACJb,WAAY,CAAEI,SAAU5B,EAAM4B,UAC9B3B,MAAM,UAAS,gBACAD,EAAM4B,UAErBtE,EAAAC,cAACgF,kBAAe1C,SAAS,cAKzCvC,EAAAC,cAACiF,sBACG9C,OAAQA,EAAG+C,SAAQC,GAAgB1C,IAC/B1C,EAAAC,cAAC0E,EAAe,IACRS,EACJlB,WAAY,CAAEI,SAAU5B,EAAM4B,UAC9Be,SAAUF,EAAG,aACF,SACXG,YAAY,YACZC,KAAK,QACLC,UAAW,CACPC,MAAO,CACHC,eACI1F,EAAAC,cAAC0F,iBAAc,CAACC,SAAS,SACrB5F,EAAAC,cAACgF,iBAAc,CAAC1C,SAAS,WAGjCsD,aAAcnD,EAAM3B,MAChBf,EAAAC,cAAC0F,EAAAA,eAAc,CAACC,SAAS,OACrB5F,EAAAC,cAAC6F,oBACGC,KAAK,MACLR,KAAK,QAAO,aACD,eACXS,SAAU,CAAE1F,GAAI,CAAE2F,aAAa,OAE/BjG,EAAAC,cAACiG,gBAAa,CAAC3D,SAAS,YAGhC,QACD6C,EAAaI,WAAWC,UAE5BL,EAAaI,eAO5C,CC5cA,MAAMW,EAAUC,EAAAA,WAA8B,EAAGC,OAAM9F,QAAQ,GAAID,QAAOiD,GAAS4B,IACjFnF,EAAAC,cAACqG,OAAI,CAACD,KAAMA,EAAMrE,MAAO,CAAEzB,MAAO,GAAIV,OAAQU,GAAS,MAAOD,MCDnDiG,EAAc9G,EAAAA,OAAOS,EAAPT,CAAY,EAEnCyE,iBAKA,MAAM5F,EAAQC,EAAAA,WAERiI,EAAmC,UAAvBlI,EAAMgB,QAAQC,KAE1BkH,EAAuC,WAAvBvC,EAAWnB,QAE3B2D,EAAyC,aAAvBxC,EAAWnB,QAE7B4D,EAAqC,SAAvBzC,EAAWnB,QAEzB6D,EAAe,IACQ,YAArB1C,EAAWvB,OAAuB,IAE9B8D,GAAiB,CACjB9D,MAAO6D,EAAYlI,EAAMgB,QAAQuH,OAAOC,MAAQxI,EAAMgB,QAAQyH,KAAK,KACnEC,gBAAiB1I,EAAMgB,QAAQH,KAAK8H,YAGpCP,GAAmB,CACnBM,gBAAiB,cACjBrE,MAAOrE,EAAMgB,QAAQH,KAAK8H,QAC1BC,OAAQ,aAAa5I,EAAMgB,QAAQH,KAAK8H,cAGxCN,GAAe,CACfhE,MAAOrE,EAAMgB,QAAQH,KAAKgI,UAC1BH,gBAAiBI,EAAAA,MAAM9I,EAAMgB,QAAQyH,KAAK,KAAM,QAKtDM,EAAa,IACU,YAArBnD,EAAWvB,OAAuB,IAE9B8D,GAAiB,CACjB9D,MAAOrE,EAAMgB,QAAQ4E,EAAWvB,OAAO2E,aACvCN,gBAAiB1I,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,SAGjDb,GAAmB,CACnBM,gBAAiB,cACjBrE,MAAOrE,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,KACvCL,OAAQ,aAAa5I,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,WAGrDZ,GAAe,CACfhE,MAAOrE,EAAMgB,QAAQ4E,EAAWvB,OAAO6D,EAAY,OAAS,SAC5DQ,gBAAiBI,EAAAA,MAAM9I,EAAMgB,QAAQ4E,EAAWvB,OAAO4E,KAAM,QAKzE,MAAO,CACH1H,OAAQ,GACR2H,SAAU,GACVC,WAAY,EACZC,aAAc,EACdC,OAAQ,UACRhI,WAAY,SACZiI,WAAY,SACZlI,QAAS,cACTE,eAAgB,SAChBiI,cAAe,aACfC,QAASxJ,EAAMyJ,QAAQ,EAAG,KAC1BxF,SAAUjE,EAAM0J,WAAWC,QAAQ,IACnCC,WAAY5J,EAAM0J,WAAWG,eAC7B3D,WAAYlG,EAAMmG,YAAYC,OAAO,MAAO,CACxC0D,SAAU9J,EAAMmG,YAAY2D,SAASC,aAEtCzB,KACAS,KCnFLiB,EAAQlC,EAAAA,WACZ,EAAGmC,WAAU5F,QAAQ,UAAWI,UAAU,OAAQyF,YAAWC,UAASnI,QAAOiD,GAAS4B,KAGpF,MAAMuD,EAAa,CACjBnI,MAAO,GACPV,OAAQ,GACR,aAAc,CAAEU,MAAO,EAAGV,OAAQ,EAAG8I,UAAW,UAGlD,OACE3I,EAAAC,cAACsG,EAAW,CACVpB,IAAKA,EAELjB,WAAY,CAAEvB,QAAOI,WACrBzC,GAAI,IACEkI,GAAa,CAAEI,GAAI,QACnBH,GAAW,CAAEI,GAAI,QAClBvI,MAGDiD,GAEHiF,GAAaxI,EAAAC,cAACC,EAAG,CAACI,GAAI,CAAEwI,GAAI,OAASJ,QAAgBF,EAAiB,KAEtED,EAEAE,GAAWzI,EAAAC,cAACC,EAAG,CAACI,GAAI,CAAEyI,GAAI,OAASL,QAAgBD,EAAe,QCd9DO,EAAwB,iCACxBC,EAAiB,YACjBC,EAA4B,0BAC5BC,EAAwB,yBACxBC,EAAkB,IAAIC,IAAY,CAACJ,EAAgBC,IAEnDI,EAAkB,CAAEC,QAAS,GAAKC,SAAU,EAAGC,YAAa,KAC5DC,EAAqB,GACrBC,EAAwB,GAOxBC,EAAmBC,GAAkBT,EAAgBU,IAAID,IAAUA,IAAUb,EAM7Ee,EAAShJ,GAA8CA,QAEvDiJ,EAAgBjJ,GAAmBgJ,EAAMhJ,IAAoB,KAAVA,GAAiBkJ,MAAMC,QAAQnJ,IAA2B,IAAjBA,EAAMoJ,OAElGC,EAAQA,CAACrJ,EAAesJ,EAAaC,IAAgBC,KAAKF,IAAIE,KAAKD,IAAIvJ,EAAOsJ,GAAMC,GAEpFE,EAAKA,IAAIC,IAAyDA,EAAWC,OAAOC,SAASC,KAAK,KAkBlGC,EAAW,MACpB,IAAIC,EAAU,EACd,MAAO,CAACC,EAAS,SACbD,GAAW,EACJ,GAAGC,KAAUD,IAE3B,EANuB,GAYXpK,EAAqBA,IAAwB,oBAAXC,aAAyD,IAAxBA,OAAOC,aAE1EC,EAAuBC,IAChC,IAAKJ,IAAsB,OAAO,KAClC,IACI,MAAMK,EAAQJ,OAAOC,aAAaI,QAAQF,GAC1C,OAAOC,EAASE,KAAKC,MAAMH,GAAe,IAC9C,CAAE,MACE,OAAO,IACX,GAGSI,EAAoBA,CAACL,EAAaC,KAC3C,GAAKL,IACL,IACIC,OAAOC,aAAaQ,QAAQN,EAAKG,KAAKI,UAAUN,GACpD,CAAE,MACE,GAQKiK,EAAkBA,CAAiCC,EAAQC,IACpEA,EAAWA,EAASD,GAAQA,EAAIE,GAEvBC,EAA0BA,CACnC3F,EACA4F,KAEA,IAAK5F,EAAO,MAAO,CAAE6F,KAAM,UAAWC,IAAK,IAAIlC,KAC/C,GAAIY,MAAMC,QAAQzE,GAAQ,MAAO,CAAE6F,KAAM,UAAWC,IAAK,IAAIlC,IAAI5D,IACjE,GAAIA,aAAiB4D,IAAK,MAAO,CAAEiC,KAAM,UAAWC,IAAK,IAAIlC,IAAI5D,IACjE,GAAmB,YAAfA,EAAM6F,MAAsBD,EAAQ,CACpC,MAAME,EAAM,IAAIlC,IAIhB,OAHAgC,EAAOG,QAASL,IACP1F,EAAM8F,IAAIzB,IAAIqB,IAAKI,EAAIE,IAAIN,KAE7B,CAAEG,KAAM,UAAWC,MAC9B,CACA,MAAO,CAAED,KAAM,UAAWC,IAAK,IAAIlC,IAAI5D,EAAM8F,OAgBpCG,EAAU3K,IACnB,GAAIgJ,EAAMhJ,IAAoB,KAAVA,EAAc,OAAO,KACzC,GAAIA,aAAiB4K,KAAM,OAAOC,OAAOC,MAAM9K,EAAM+K,WAAa,KAAO/K,EACzE,GAAIgL,EAAMC,QAAQjL,GAAQ,OAAOA,EAAMkL,UAAYlL,EAAM2K,SAAW,KACpE,GAAqB,iBAAV3K,EAAoB,CAC3B,MAAMmL,EAAI,IAAIP,KAAK5K,GACnB,OAAO6K,OAAOC,MAAMK,EAAEJ,WAAa,KAAOI,CAC9C,CACA,GAAqB,iBAAVnL,EAAoB,CAC3B,MAAMoL,EAASJ,EAAMhL,GACrB,OAAOoL,EAAOF,UAAYE,EAAOT,SAAW,IAChD,CACA,OAAO,MAGEU,EAAaA,CAACrL,EAAgBsL,KACvC,MAAMC,EAAOZ,EAAO3K,GACpB,OAAKuL,EACEP,EAAMO,GAAMC,OAAOF,EAAW,kBAAoB,YADvC,IAIhBG,EAAcA,CAACF,EAAYD,IAC7BA,EAAWN,EAAMO,GAAMG,QAAQ,UAAUC,UAAYX,EAAMO,GAAMG,QAAQ,OAAOC,UAMvEC,EAAuBC,GACd,iBAAXA,GAAkC,OAAXA,EAErBC,EAAiBA,CAACC,EAAoBF,IAC/CE,EAAID,eAAiBC,EAAID,eAAeD,GAAUD,EAAoBC,GAAUA,EAAO7L,MAAQ6L,EAEtFG,EAAiBA,CAACD,EAAoBF,IAC/CE,EAAIC,eAAiBD,EAAIC,eAAeH,GAAUD,EAAoBC,GAAUA,EAAOI,MAAQC,OAAOL,GAE7FM,EAAsBA,CAACJ,EAAoB7B,EAA4BE,IAC3E2B,EAAIK,aAC0B,mBAArBL,EAAIK,aAA8BL,EAAIK,aAAa,CAAEtD,MAAOiD,EAAIjD,MAAOoB,MAAKE,OAAQ2B,EAAIK,aADxE,GAQrBC,EAAeA,CAACnC,EAA2B6B,EAAoBO,KACxE,MAAMC,EAAMrC,EAAMA,EAAI6B,EAAIjD,YAAS0D,EACnC,OAAOT,EAAIU,YAAcV,EAAIU,YAAYF,EAAKrC,EAAK6B,EAAKO,GAAOC,GAQtDG,GAAqBA,CAAC1M,EAAY+L,EAAoB7B,EAA4BE,KAC3F,GAAIpB,EAAMhJ,GAAQ,MAAO,GACzB,OAAQ+L,EAAIxB,MACR,IAAK,OACD,OAAOc,EAAWrL,GAAO,GAC7B,IAAK,WACD,OAAOqL,EAAWrL,GAAO,GAC7B,IAAK,UACD,OAAOA,EAAQ,MAAQ,KAC3B,IAAK,eAAgB,CACjB,MACM2M,EADUR,EAAoBJ,EAAK7B,EAAKE,GACxBwC,KAAMf,GAAWC,EAAeC,EAAKF,KAAY7L,GACvE,YAAiBwM,IAAVG,EAAsBX,EAAeD,EAAKY,GAAST,OAAOlM,EACrE,CACA,IAAK,SACD,MAAwB,iBAAVA,EAAsB6K,OAAOgC,SAAS7M,GAASkM,OAAOlM,GAAS,GAAMkM,OAAOlM,GAC9F,QACI,GAAIA,aAAiB4K,KAAM,OAAOS,EAAWrL,GAAO,GACpD,GAAqB,iBAAVA,EACP,IACI,OAAOE,KAAKI,UAAUN,EAC1B,CAAE,MACE,OAAOkM,OAAOlM,EAClB,CAEJ,OAAOkM,OAAOlM,KAIb8M,GAAoBA,CAC7B9M,EACAkK,EACA6B,EACAO,EACAlC,IAEI2B,EAAIgB,eAAuBhB,EAAIgB,eAAe/M,EAAOkK,EAAK6B,EAAKO,GAC5DI,GAAmB1M,EAAO+L,EAAK7B,EAAKE,GAGlC4C,GAA0BC,GAC/BjE,EAAMiE,GAAmB,GACJ,iBAAdA,EAA+BA,EACjB,iBAAdA,GAA+C,kBAAdA,EAAgCf,OAAOe,GAC/EA,aAAqBrC,KAAaS,EAAW4B,GAAW,GACnC,iBAAdA,GAA0B,UAAWA,EAAkB,GAC3Df,OAAOe,GA2BZC,GAA2B,oBAATC,KAAuB,IAAIA,KAAKC,cAASZ,EAAW,CAAEa,SAAS,EAAMC,YAAa,SAAY,KAEhHC,GAAWA,CAACC,EAASC,KACvB,MAAMC,EAAK1E,EAAMwE,IAAc,KAAPA,EAClBG,EAAK3E,EAAMyE,IAAc,KAAPA,EACxB,OAAIC,GAAMC,EAAW,EACjBD,GAAW,EACXC,EAAW,EACR,MAGEC,GAAwCA,CAACJ,EAAIC,KACtD,MAAMI,EAAMN,GAASC,EAAIC,GACzB,OAAY,OAARI,EAAqBA,EAClBhD,OAAO2C,GAAM3C,OAAO4C,IAGlBK,GAAwCA,CAACN,EAAIC,KACtD,MAAMI,EAAMN,GAASC,EAAIC,GACzB,GAAY,OAARI,EAAc,OAAOA,EACzB,MAAME,EAAK7B,OAAOsB,GACZQ,EAAK9B,OAAOuB,GAClB,OAAIP,GAAiBA,GAASe,QAAQF,EAAIC,GACnCD,EAAKC,GAAK,EAAKD,EAAKC,EAAK,EAAI,GAG3BE,GAAgDA,CAACV,EAAIC,EAAIU,EAAIC,IACpD,iBAAPZ,GAAiC,iBAAPC,EAAwBG,GAAiBJ,EAAIC,GAC3EK,GAAiBN,EAAIC,GAGnBY,GAAsCA,CAACb,EAAIC,KACpD,MAAMa,EAAK3D,EAAO6C,GACZe,EAAK5D,EAAO8C,GACZI,EAAMN,GAASe,EAAIC,GACzB,OAAY,OAARV,EAAqBA,EACjBS,EAAYvD,UAAawD,EAAYxD,WAGpCyD,GAAyCA,CAAChB,EAAIC,KACvD,MAAMI,EAAMN,GAASC,EAAIC,GACzB,OAAY,OAARI,EAAqBA,EAClBhD,OAAOjB,QAAQ4D,IAAO3C,OAAOjB,QAAQ6D,KAGnCgB,GAAwBlE,IACjC,OAAQA,GACJ,IAAK,SACD,OAAOqD,GACX,IAAK,OACL,IAAK,WACD,OAAOS,GACX,IAAK,UACD,OAAOG,GACX,QACI,OAAON,KAQbQ,GAAS1O,GAAoBgJ,EAAMhJ,GAAS,GAAKkM,OAAOlM,GAAO2O,cAE/DC,GAAYC,IAA6B5F,EAAa4F,EAAK7O,OAEpD8O,GAAiD,CAC1D,CACI9O,MAAO,WACPiM,MAAO,WACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK7O,OAC1B,OAAQA,IAA2C,IAAjC0O,GAAM1O,GAAOkP,QAAQD,KAG/C,CACIjP,MAAO,iBACPiM,MAAO,mBACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK7O,OAC1B,OAAQA,IAA2C,IAAjC0O,GAAM1O,GAAOkP,QAAQD,KAG/C,CACIjP,MAAO,SACPiM,MAAO,SACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK7O,OAC1B,OAAQA,GAAU0O,GAAM1O,KAAWiP,IAG3C,CACIjP,MAAO,eACPiM,MAAO,iBACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK7O,OAC1B,OAAQA,GAAU0O,GAAM1O,KAAWiP,IAG3C,CACIjP,MAAO,aACPiM,MAAO,cACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK7O,OAC1B,OAAQA,GAA2C,IAAjC0O,GAAM1O,GAAOkP,QAAQD,KAG/C,CACIjP,MAAO,WACPiM,MAAO,YACP8C,UAAW,OACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMI,EAASP,GAAMG,EAAK7O,OAC1B,OAAQA,IACJ,MAAMmP,EAAIT,GAAM1O,GAChB,OAAOmP,EAAE/F,QAAU6F,EAAO7F,QAAU+F,EAAEC,YAAYH,KAAYE,EAAE/F,OAAS6F,EAAO7F,UAI5F,CACIpJ,MAAO,UACPiM,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOhP,GAAUiJ,EAAajJ,IAEpD,CACIA,MAAO,aACPiM,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOhP,IAAWiJ,EAAajJ,IAErD,CACIA,MAAO,UACPiM,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAK3F,MAAMC,QAAQ0F,EAAK7O,QAAgC,IAAtB6O,EAAK7O,MAAMoJ,OAAc,OAAO,KAClE,MAAMkG,EAAM,IAAIhH,IAAIuG,EAAK7O,MAAM0C,IAAIgM,KACnC,OAAQ1O,GAAUsP,EAAIvG,IAAI2F,GAAM1O,OAKtCuP,GAAiBA,CACnBvP,EACAiM,EACAgC,KAAkD,CAElDjO,QACAiM,QACA8C,UAAW,SACXC,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMW,EAAc3E,OAAOgE,EAAK7O,OAChC,OAAI6K,OAAOC,MAAM0E,GAAqB,KAC9BC,IACJ,GAAIzG,EAAMyG,IAAkB,KAATA,EAAa,OAAO,EACvC,MAAMC,EAAI7E,OAAO4E,GACjB,OAAQ5E,OAAOC,MAAM4E,IAAMzB,EAAQyB,EAAGF,OAKrCG,GAAiD,CAC1DJ,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,IAAMC,GACzCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,IAAMC,GAC3CN,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,EAAIC,GACvCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,GAAKC,GAC1CN,GAAe,IAAK,IAAK,CAACK,EAAGC,IAAMD,EAAIC,GACvCN,GAAe,KAAM,KAAM,CAACK,EAAGC,IAAMD,GAAKC,GAC1C,CACI7P,MAAO,UACPiM,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOhP,GAAUiJ,EAAajJ,IAEpD,CACIA,MAAO,aACPiM,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOhP,IAAWiJ,EAAajJ,IAErD,CACIA,MAAO,UACPiM,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAK3F,MAAMC,QAAQ0F,EAAK7O,QAAgC,IAAtB6O,EAAK7O,MAAMoJ,OAAc,OAAO,KAClE,MAAMkG,EAAM,IAAIhH,IAAIuG,EAAK7O,MAAM0C,IAAKoN,GAAWjF,OAAOiF,KACtD,OAAQ9P,IAAWgJ,EAAMhJ,IAAUsP,EAAIvG,IAAI8B,OAAO7K,OAKxD+P,GAAeA,CACjB/P,EACAiM,EACAX,EACA2C,KAAkD,CAElDjO,QACAiM,QACA8C,UAAWzD,EAAW,iBAAmB,OACzC0D,iBAAmBH,IACf,IAAKD,GAASC,GAAO,OAAO,KAC5B,MAAMmB,EAAarF,EAAOkE,EAAK7O,OAC/B,IAAKgQ,EAAY,OAAO,KACxB,MAAMC,EAAaxE,EAAYuE,EAAY1E,GAC3C,OAAQmE,IACJ,MAAMS,EAAWvF,EAAO8E,GACxB,QAAKS,GACEjC,EAAQxC,EAAYyE,EAAU5E,GAAW2E,OAK/CE,GAA0B7E,GAA+C,CAClFyE,GAAa,KAAM,KAAMzE,EAAU,CAACsE,EAAGC,IAAMD,IAAMC,GACnDE,GAAa,MAAO,SAAUzE,EAAU,CAACsE,EAAGC,IAAMD,IAAMC,GACxDE,GAAa,QAAS,WAAYzE,EAAU,CAACsE,EAAGC,IAAMD,EAAIC,GAC1DE,GAAa,YAAa,iBAAkBzE,EAAU,CAACsE,EAAGC,IAAMD,GAAKC,GACrEE,GAAa,SAAU,YAAazE,EAAU,CAACsE,EAAGC,IAAMD,EAAIC,GAC5DE,GAAa,aAAc,kBAAmBzE,EAAU,CAACsE,EAAGC,IAAMD,GAAKC,GACvE,CACI7P,MAAO,UACPiM,MAAO,WACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOhP,GAA4B,OAAlB2K,EAAO3K,IAE9C,CACIA,MAAO,aACPiM,MAAO,eACP8C,UAAW,OACXM,qBAAqB,EACrBL,iBAAkBA,IAAOhP,GAA4B,OAAlB2K,EAAO3K,KAIrCoQ,GAAkD,CAC3D,CACIpQ,MAAO,KACPiM,MAAO,KACP8C,UAAW,UACXC,iBAAmBH,IACf,GAAI7F,EAAM6F,EAAK7O,QAAyB,KAAf6O,EAAK7O,OAA+B,QAAf6O,EAAK7O,MAAiB,OAAO,KAC3E,MAAMqQ,GAA0B,IAAfxB,EAAK7O,OAAiC,SAAf6O,EAAK7O,MAC7C,OAAQA,GAAU4J,QAAQ5J,KAAWqQ,KAKpCC,GAAuD,CAChE,CACItQ,MAAO,KACPiM,MAAO,KACP8C,UAAW,SACXC,iBAAmBH,GACX7F,EAAM6F,EAAK7O,QAAyB,KAAf6O,EAAK7O,MAAqB,KAC3CA,GAAUkM,OAAOlM,KAAWkM,OAAO2C,EAAK7O,QAGxD,CACIA,MAAO,MACPiM,MAAO,SACP8C,UAAW,SACXC,iBAAmBH,GACX7F,EAAM6F,EAAK7O,QAAyB,KAAf6O,EAAK7O,MAAqB,KAC3CA,GAAUkM,OAAOlM,KAAWkM,OAAO2C,EAAK7O,QAGxD,CACIA,MAAO,UACPiM,MAAO,YACP8C,UAAW,cACXC,iBAAmBH,IACf,IAAK3F,MAAMC,QAAQ0F,EAAK7O,QAAgC,IAAtB6O,EAAK7O,MAAMoJ,OAAc,OAAO,KAClE,MAAMkG,EAAM,IAAIhH,IAAIuG,EAAK7O,MAAM0C,IAAIwJ,SACnC,OAAQlM,GAAUsP,EAAIvG,IAAImD,OAAOlM,OAwBhCuQ,GAA4BxE,GAAuBA,EAAIyE,iBAnB1BjG,KACtC,OAAQA,GACJ,IAAK,SACD,OAAOoF,GACX,IAAK,OACD,OAAOQ,IAAuB,GAClC,IAAK,WACD,OAAOA,IAAuB,GAClC,IAAK,UACD,OAAOC,GACX,IAAK,eACD,OAAOE,GACX,IAAK,UACD,MAAO,GACX,QACI,OAAOxB,KAIoE2B,CAA0B1E,EAAIxB,MAMxGmG,GAAmD3E,IAC5D,MAAMxB,EAAOwB,EAAIxB,MAAQ,SACnBoG,EAAoB,WAATpG,EACXqG,EAAqB,YAATrG,EACZsG,EAAqB,YAATtG,EAClB,MAAO,IACAwB,EACHxB,OACAuG,WAAY/E,EAAI+E,YAAc/E,EAAIjD,MAGlCiI,MAAOhF,EAAIgF,QAAUJ,EAAW,QAAUC,GAAaC,EAAY,SAAW,QAC9EG,YAAajF,EAAIiF,aAAejF,EAAIgF,QAAUJ,EAAW,QAAUC,GAAaC,EAAY,SAAW,QACvGI,UAAUJ,IAAqB9E,EAAIkF,WAAY,GAC/CC,YAAYL,IAAqB9E,EAAImF,aAAc,GACnDC,SAAUpF,EAAIoF,WAAY,EAC1BC,UAAWrF,EAAIqF,YAAa,EAC5BC,SAAUtF,EAAIsF,WAAY,EAC1BC,WAAWT,IAAqB9E,EAAIuF,YAAa,GACjDC,YAAYV,IAAqB9E,EAAIwF,aAAc,GACnDC,SAAUzF,EAAIyF,WAAY,EAC1BC,kBAAmB1F,EAAI0F,mBAAqBZ,EAC5Ca,cAAe3F,EAAI2F,eAAiBb,IAQtCc,GAAiBA,CAAC7I,EAAetJ,IACnCkR,GAAgB,CACZ5H,QACAgI,WAAY,GACZtR,QACAiH,SAAUjH,EACVC,SAAUD,EACVyR,UAAU,EACVC,YAAY,EACZC,UAAU,EACVC,WAAW,EACXC,UAAU,EACVC,WAAW,EACXC,YAAY,EACZE,mBAAmB,EACnBC,eAAe,EACfE,gBAAgB,EAChBb,MAAO,SACPC,YAAa,WAIRa,GAAqCF,GAAezJ,EAjmB5B,IAmmBxB4J,GAAgDH,GACzDxJ,EAnmBsC,IA2mBpC4J,GAAsB,IAAIzJ,IAAI,CAChC,0BACA,oBACA,mBACA,mBACA,UACA,eACA,kBACA,cACA,UACA,OACA,WACA,eACA,aACA,eACA,YACA,WACA,UACA,aACA,cACA,eACA,aACA,gBACA,iBACA,kBACA,aACA,YACA,aACA,UACA,QACA,UACA,UACA,SACA,SACA,OACA,cACA,eACA,cACA,kBACA,mBACA,mBACA,gBACA,gBAIS0J,GAAiBjS,GAAgB,mBAAmBkS,KAAKlS,GAahEmS,GAAyBC,GAC3BC,OAAOC,KAAKF,GACPxI,OAAQ5J,IACL,MAAMC,EAAQmS,EAAMpS,GACpB,OAAQiS,GAAcjS,KAA0B,iBAAVC,GAAuC,iBAAVA,KAEtE0C,IAAK3C,IAAQ,SAjBDuS,KACjB,GAA+B,IAA3BA,EAASpD,QAAQ,MAAa,OAAOoD,EACzC,MAAMC,EAAQD,EAASE,QAAQ,SAAWC,GAAM,IAAIA,EAAE9D,iBACtD,OAAgC,IAAzB4D,EAAMrD,QAAQ,OAAe,IAAIqD,IAAUA,GAc7BG,CAAY3S,MAXbuS,EAWoCvS,EAXlBC,EAWuBmS,EAAMpS,GAVlD,iBAAVC,GAAgC,IAAVA,GAAgB+R,GAAoBhJ,IAAIuJ,IAAwC,IAA3BA,EAASpD,QAAQ,MAE7FhD,OAAOlM,GADP,GAAGA,QAFU2S,IAACL,EAAkBtS,IAYjC6J,KAAK,KAcD+I,GAAiBA,CAACC,EAAetT,EAAyCuT,EAAgB,KAC9FvT,GACL6S,OAAOC,KAAK9S,GAAIkL,QAAS1K,IACrB,MAAMC,EAAQT,EAAGQ,GACjB,IAAKC,GAA0B,iBAAVA,EAAoB,OACzC,MAAMmS,EAAQnS,EACd,GAAsB,MAAlBD,EAAIgT,OAAO,GAAY,CACvB,MAAMC,EAAkB,GAClBC,EAAef,GAAsBC,GAI3C,OAHIc,GAAcD,EAAME,KAAK,GAAGL,KAASI,MACzCL,GAAeC,EAAOV,EAAOa,QACzBA,EAAM5J,QAAQ0J,EAAII,KAAK,GAAGnT,KAAOiT,EAAMnJ,KAAK,QAEpD,CACA,MAAMsJ,EA1BQC,EAACP,EAAeM,IAClCA,EACKE,MAAM,KACN3Q,IAAK4Q,GAASA,EAAKC,QACnB5J,OAAOC,SACPlH,IAAK4Q,IAAgC,IAAtBA,EAAKpE,QAAQ,KAAcoE,EAAKd,QAAQ,KAAMK,GAAS,GAAGA,KAASS,KAClFzJ,KAAK,KAoBWuJ,CAAcP,EAAO9S,GAChCkT,EAAef,GAAsBC,GACvCc,GAAcH,EAAII,KAAK,GAAGC,KAAYF,MAC1CL,GAAeO,EAAUhB,EAAOW,KAE7BA,GAlBSA,EAyBdU,GAAiBC,GACnBA,EAAO/Q,IAAKoN,GAAoB,iBAANA,EAAiBA,EAAIjF,OAAOiF,IAAKnG,OAAQ+F,IAAO7E,OAAOC,MAAM4E,IAAY,OAANA,GAEpFgE,GAA6E,CACtFC,IAAK,CACD1H,MAAO,MACP2H,YAAa,CAAC,UACdC,MAAOA,EAAGJ,aACN,MAAMK,EAAON,GAAcC,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,IAC7D,OAAoB,IAAhBgE,EAAK1K,OAAqB,KACvB0K,EAAKC,OAAO,CAACC,EAAKtE,IAAMsE,EAAMtE,EAAG,KAGhDuE,IAAK,CACDhI,MAAO,MACP2H,YAAa,CAAC,UACdC,MAAOA,EAAGJ,aACN,MAAMK,EAAON,GAAcC,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,IAC7D,OAAoB,IAAhBgE,EAAK1K,OAAqB,KACvB0K,EAAKC,OAAO,CAACC,EAAKtE,IAAMsE,EAAMtE,EAAG,GAAKoE,EAAK1K,SAG1DE,IAAK,CACD2C,MAAO,MACP2H,YAAa,CAAC,SAAU,OAAQ,YAChCC,MAAOA,EAAGJ,aACN,MAAMS,EAAUT,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,GAClD,GAAuB,IAAnBoE,EAAQ9K,OAAc,OAAO,KACjC,GAAI8K,EAAQC,MAAOrE,GAAmB,iBAANA,GAAiB,OAAOtG,KAAKF,OAAQ4K,GACrE,MAAME,EAAQF,EAAQxR,IAAIiI,GAC1B,OAAIyJ,EAAMD,MAAOhJ,GAAY,OAANA,GACZ,IAAIP,KAAKpB,KAAKF,OAAO8K,EAAM1R,IAAKyI,GAAOA,EAAWJ,aAEtDmJ,EAAQG,QAAQC,KAAK,CAAC1E,EAAGC,IAAM/B,GAAiB8B,EAAGC,IAA8B,KAGhGtG,IAAK,CACD0C,MAAO,MACP2H,YAAa,CAAC,SAAU,OAAQ,YAChCC,MAAOA,EAAGJ,aACN,MAAMS,EAAUT,EAAO9J,OAAQmG,IAAO9G,EAAM8G,IAAY,KAANA,GAClD,GAAuB,IAAnBoE,EAAQ9K,OAAc,OAAO,KACjC,GAAI8K,EAAQC,MAAOrE,GAAmB,iBAANA,GAAiB,OAAOtG,KAAKD,OAAQ2K,GACrE,MAAME,EAAQF,EAAQxR,IAAIiI,GAC1B,GAAIyJ,EAAMD,MAAOhJ,GAAY,OAANA,GACnB,OAAO,IAAIP,KAAKpB,KAAKD,OAAO6K,EAAM1R,IAAKyI,GAAOA,EAAWJ,aAE7D,MAAMwJ,EAASL,EAAQG,QAAQC,KAAK,CAAC1E,EAAGC,IAAM/B,GAAiB8B,EAAGC,IAClE,OAAO0E,EAAOA,EAAOnL,OAAS,KAGtC5E,KAAM,CACFyH,MAAO,OACP4H,MAAOA,EAAGJ,YAAaA,EAAOrK,SAQzBoL,GAAyC,CAClDC,YAAa,UACbC,aAAc,WACdC,eAAgB,UAChBC,eAAgB,UAChBC,cAAe,SACfC,eAAgB,UAChBC,8BAA+B,YAC/BC,wBAAyB,SACzBC,iBAAkB,kBAClBC,mBAAoB,oBACpBC,mBAAoB,QACpBC,eAAgB,UAChBC,gBAAiB,WACjBC,mBAAoB,cACpBC,8BAA+B,SAC/BC,oBAAqB,WACrBC,oBAAqB,WACrBC,kBAAmB,QACnBC,qBAAsB,aACtBC,qBAAsB,aACtBC,sBAAuB,SACvBC,mBAAoB,UACpBC,oBAAqB,WACrBC,iBAAkB,QAClBC,4BAA6B,eAC7BC,yBAA0B,iBAC1BC,uBAAwB,MACxBC,sBAAuB,KACvBC,kBAAmB,cACnBC,mBAAoB,eACpBC,iBAAkB,SAClBC,iBAAkB,SAClBC,qBAAsB,cACtBC,wBAAyB,iBACzBC,kBAAmB,cACnBC,mBAAoB,eACpBC,gBAAiB,QACjBC,gBAAkBC,GAAS,YAAYA,IACvCC,kBAAoBD,GAAS,oBAAoBA,IACjDE,sBAAuB,cACvBC,0BAA2B,cAC3BC,6BAA8B,OAC9BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,4BAA6B,MAC7BC,6BAA8B,OAC9BC,kBAAoBC,GAAqB,IAAVA,EAAc,iBAAmB,GAAGA,EAAMC,iCACzEC,gBAAiB,cACjBC,4BAA6B,iBAC7BC,8BAA+BA,CAACC,EAAMC,EAAIN,IAAU,GAAGK,KAAQC,QAASN,EAAMC,mBAC9EM,0BAA2B,aAC3BC,6BAA8B,gBAC9BC,yBAA0B,YAC1BC,yBAA0B,YAC1BC,4BAA6B,qBAC7BC,+BAAgC,kBAChCC,iCAAkC,oBAClCC,2BAA4B,aAC5BC,6BAA8B,eAC9BC,qBAAsB,MACtBC,sBAAuB,KACvBC,kBAAmB,sBACnBC,kBAAmB,SACnBC,oBAAqB,WACrBC,yBAA0B,QAC1BC,YAAcjC,GAAS,YAAYA,IACnCkC,cAAgBlC,GAAS,oBAAoBA,IAC7CmC,gBAAiB,OACjBC,0BAA2B,OAC3BC,gBAAiB,OACjBC,YAAa,gBAOjB,IAAIC,GAEG,MAAMC,GAAcA,CAACnb,EAAcob,KACtC,GAAwB,oBAAbC,SAA0B,OAAqB,EAAdrb,EAAKgL,OACjD,QAAuBoD,IAAnB8M,GAA8B,CAC9B,MAAMI,EAASD,SAASva,cAAc,UACtCoa,GAAiBI,EAAOC,WAAW,KACvC,CACA,OAAKL,IACLA,GAAeE,KAAOA,EACfF,GAAeC,YAAYnb,GAAMoB,OAFE,EAAdpB,EAAKgL,QASxBwQ,GAAeA,CAACC,EAAYC,KACrC,GAAwB,oBAAbL,SAA0B,OACrC,MAAMM,EAAMC,IAAIC,gBAAgBJ,GAC1BK,EAAST,SAASva,cAAc,KACtCgb,EAAOC,KAAOJ,EACdG,EAAOE,SAAWN,EAClBI,EAAOjZ,MAAMtC,QAAU,OACvB8a,SAASY,KAAKC,YAAYJ,GAC1BA,EAAOK,QACP3a,OAAO4a,WAAW,KACdf,SAASY,KAAKI,YAAYP,GAC1BF,IAAIU,gBAAgBX,IACrB,IC95BMY,GAAoB,kBAQpBC,GAAe,+g2BAkU5B,IAAIC,IAAW,EAEf,MAcMC,GACD7b,EAAc8b,qBAAyC,oBAAXnb,OAAyBX,EAAM+b,gBAAkB/b,EAAMgc,WAG3FC,GAAmBA,KAC5BJ,GAAa,KAnBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAeT,IAExB,YADAE,IAAW,GAGf,MAAM5Z,EAAQwY,SAASva,cAAc,SACrC+B,EAAMmJ,GAAKuQ,GACX1Z,EAAMoa,aAAa,gBAAiB,QACpCpa,EAAMqa,YAAcV,GACpBnB,SAAS8B,KAAKjB,YAAYrZ,GAC1B4Z,IAAW,GASPM,IACD,KCvTMK,GAAiBvc,EAAMwc,cAA0C,MAC9ED,GAAeE,YAAc,iBAEtB,MAAMC,GAAoBA,KAC7B,MAAMC,EAAM3c,EAAM4c,WAAWL,IAC7B,IAAKI,EACD,MAAM,IAAIE,MAAM,yFAEpB,OAAOF,GCjDL,SAAUG,GAAgB/b,GAC5B,MAAMoE,EAAMnF,EAAM+c,OAAOhc,GAEzB,OADAoE,EAAI6X,QAAUjc,EACPoE,CACX,UAYgB8X,GACZC,EACAC,EACAC,GAEA,MAAMC,OAA8B9P,IAAf2P,GACdI,EAAUC,GAAevd,EAAMwd,SAAYL,GAC5Cpc,EAAQsc,EAAgBH,EAAmBI,EAC3CG,EAAWX,GAAa/b,GACxB2c,EAAgBZ,GAAaO,GAC7BM,EAAcb,GAAaM,GAUjC,MAAO,CAACrc,EARSf,EAAM4d,YAAaC,IAChC,MAAMC,EAA2B,mBAATD,EAAuBA,EAAwBJ,EAAST,SAAWa,EACvF1K,OAAO4K,GAAGD,EAAUL,EAAST,WACjCS,EAAST,QAAUc,EACdJ,EAAcV,SAASO,EAAYO,GACxCH,EAAYX,UAAUc,KACvB,IAGP,CAmFA,IAAIE,GAAY,ECxFT,MAeMC,GAAmBA,CAAC5Q,EAAiBzJ,KAC9C,MAAMsa,EAhB0BC,EAAC9Q,EAAiBzJ,KAClD,MAAMwa,EAAM/Q,EAAIgR,gBAChB,IAAIH,EACJ,GAAIta,EAAQ0a,OAAQ,CAChB,MAAMC,EAAU,IAAIC,IACpBJ,EAAI5S,QAASiT,GAAMF,EAAQlO,IAAIoO,EAAE5U,MAAO4U,IACxCP,EAAUta,EAAQ0a,OAAO7a,IAAKib,GAAMH,EAAQI,IAAID,IAAIhU,OAAOC,QAC/D,MACIuT,EADOta,EAAQR,WACLgb,EAEA/Q,EAAIuR,oBAElB,OAAOV,EAAQxT,OAAQ+T,IAAOA,EAAEhM,gBAAkB7I,EAAgB6U,EAAE5U,QAAqB,YAAX4U,EAAEnT,OAIhE6S,CAAqB9Q,EAAKzJ,GACpC2H,EAAsB3H,EAAQib,gBAAkBjb,EAAQib,gBAAgB,CAAExR,QAASA,EAAIyR,kBACvFC,EAAuB,GAY7B,OAXAxT,EAAIC,QAASL,IACT,MAAMF,EAAMoC,EAAI2R,OAAO7T,GAClBF,GACL8T,EAAK9K,KACDiK,EAAQza,IAAKqJ,IACT,MAAMQ,EAAMF,EAAanC,EAAK6B,EAAKO,GAEnC,MAAO,CAAEC,MAAKU,UADID,GAAuBF,GAAkBP,EAAKrC,EAAK6B,EAAKO,EAAKlC,IACtD2B,YAI9B,CAAEoR,UAASe,QAASf,EAAQza,IAAKgb,GAAMA,EAAE5M,YAAc4M,EAAE5U,OAAQkV,SAGtEG,GAAmBA,CAACpH,EAA0BqH,EAAkBC,KAClE,MAAMC,EAAQvH,GAAQA,EAAKxD,QAAW6K,EACtC,OAAOE,EAAK3P,cAAc4P,SAAS,IAAIF,KAAeC,EAAO,GAAGA,KAAQD,KAGtEG,GAAkBA,MACc,oBAAb/E,UAA4BA,SAAStY,MAAQsY,SAAStY,MAAMoS,OAAS,KACzE,UAAUf,QAAQ,iBAAkB,KAOnDiM,GAAgBA,CAACze,EAAe0e,KAClC,IAAItgB,EAAO4B,EAGX,MADI,eAAeiS,KAAK7T,KAAOA,EAAO,IAAIA,MAChB,IAAtBA,EAAK8Q,QAAQ,OAA2C,IAA5B9Q,EAAK8Q,QAAQwP,IAAqB,SAASzM,KAAK7T,GACrE,IAAIA,EAAKoU,QAAQ,KAAM,SAE3BpU,GAGEugB,GAAeA,CAACrS,EAAiBzJ,EAAmC,MAC7E,MAAM6b,EAAY7b,EAAQ6b,WAAa,IACjCE,EAAiB/b,EAAQ+b,iBAAkB,EAC3CC,EAAQ3B,GAAiB5Q,EAAKzJ,GAC9Bic,EAAkB,GAcxB,OAbIF,GACAE,EAAM5L,KAAK2L,EAAMX,QAAQxb,IAAKqc,GAAMN,GAAcM,EAAGL,IAAY7U,KAAK6U,IAE1EG,EAAMb,KAAKvT,QAASuU,IAChBF,EAAM5L,KACF8L,EACKtc,IAAK+M,IACF,MAAMrR,EAAOyE,EAAQoc,aAAgBjW,EAAMyG,EAAKlD,KAAO,GAAKL,OAAOuD,EAAKlD,KAAQkD,EAAKxC,UACrF,OAAOwR,GAAcrgB,EAAMsgB,KAE9B7U,KAAK6U,MAGXI,EAAMjV,KAAK,SAGhBqV,GAAWhT,OAAOiT,aAAa,OAa/BC,GAAY,MACd,MAAMP,EAAQ,IAAIQ,YAAY,KAC9B,IAAK,IAAI3P,EAAI,EAAGA,EAAI,IAAKA,GAAK,EAAG,CAC7B,IAAIgO,EAAIhO,EACR,IAAK,IAAI4P,EAAI,EAAGA,EAAI,EAAGA,GAAK,EACxB5B,EAAQ,EAAJA,EAAQ,WAAcA,IAAM,EAAKA,IAAM,EAE/CmB,EAAMnP,GAAKgO,IAAM,CACrB,CACA,OAAOmB,CACV,EAViB,GAoBZU,GAAqC,oBAAhBC,YAA8B,IAAIA,YAAgB,KAEvEC,GAAcrhB,IAChB,GAAImhB,GAAa,OAAOA,GAAYG,OAAOthB,GAE3C,MAAMuhB,EAAOC,SAASC,mBAAmBzhB,IACnC0U,EAAM,IAAIgN,WAAWH,EAAKvW,QAChC,IAAK,IAAI2W,EAAI,EAAGA,EAAIJ,EAAKvW,OAAQ2W,GAAK,EAAGjN,EAAIiN,GAAKJ,EAAKK,WAAWD,GAClE,OAAOjN,GAQLmN,GAAeC,IACjB,MAAMC,EAAQD,EAAOnM,OAAO,CAACC,EAAK0J,IAAM1J,EAAM0J,EAAEtU,OAAQ,GAClD0J,EAAM,IAAIgN,WAAWK,GAC3B,IAAIC,EAAS,EAKb,OAJAF,EAAOzV,QAASiT,IACZ5K,EAAIxD,IAAIoO,EAAG0C,GACXA,GAAU1C,EAAEtU,SAET0J,GAGLuN,GAAYC,IACd,MAAMC,EAA4B,GAC5BC,EAA8B,GACpC,IAAIJ,EAAS,EAKbE,EAAQ7V,QAASgW,IACb,MAAMC,EAAYjB,GAAWgB,EAAM1J,MAC7B4J,EA7CCC,KACX,IAAID,EAAM,WACV,IAAK,IAAIZ,EAAI,EAAGA,EAAIa,EAAMxX,OAAQ2W,GAAK,EACnCY,EAAMvB,GAA6B,KAAlBuB,EAAMC,EAAMb,KAAeY,IAAQ,EAExD,OAAc,WAANA,KAAsB,GAwCdE,CAAMJ,EAAMK,MAClBtc,EAAOic,EAAMK,KAAK1X,OAElB2X,EAAQ,IAAIjB,WAAW,GAAKY,EAAUtX,QACtC4X,EAAK,IAAIC,SAASF,EAAMG,QAC9BF,EAAGG,UAAU,EAAG,UAAY,GAC5BH,EAAGI,UAAU,EAAG,IAAI,GACpBJ,EAAGI,UAAU,EAAG,MAAQ,GACxBJ,EAAGI,UAAU,EAAG,GAAG,GACnBJ,EAAGI,UAAU,GAdD,GAcc,GAC1BJ,EAAGI,UAAU,GAdA,IAca,GAC1BJ,EAAGG,UAAU,GAAIR,GAAK,GACtBK,EAAGG,UAAU,GAAI3c,GAAM,GACvBwc,EAAGG,UAAU,GAAI3c,GAAM,GACvBwc,EAAGI,UAAU,GAAIV,EAAUtX,QAAQ,GACnC4X,EAAGI,UAAU,GAAI,GAAG,GACpBL,EAAMzR,IAAIoR,EAAW,IAErB,MAAMW,EAAU,IAAIvB,WAAW,GAAKY,EAAUtX,QACxCkY,EAAK,IAAIL,SAASI,EAAQH,QAChCI,EAAGH,UAAU,EAAG,UAAY,GAC5BG,EAAGF,UAAU,EAAG,IAAI,GACpBE,EAAGF,UAAU,EAAG,IAAI,GACpBE,EAAGF,UAAU,EAAG,MAAQ,GACxBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GA9BD,GA8Bc,GAC1BE,EAAGF,UAAU,GA9BA,IA8Ba,GAC1BE,EAAGH,UAAU,GAAIR,GAAK,GACtBW,EAAGH,UAAU,GAAI3c,GAAM,GACvB8c,EAAGH,UAAU,GAAI3c,GAAM,GACvB8c,EAAGF,UAAU,GAAIV,EAAUtX,QAAQ,GACnCkY,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGF,UAAU,GAAI,GAAG,GACpBE,EAAGH,UAAU,GAAI,GAAG,GACpBG,EAAGH,UAAU,GAAIf,GAAQ,GACzBiB,EAAQ/R,IAAIoR,EAAW,IAEvBH,EAAYrN,KAAK6N,EAAON,EAAMK,MAC9BN,EAActN,KAAKmO,GACnBjB,GAAUW,EAAM3X,OAAS5E,IAG7B,MAAM+c,EAAmBtB,GAAYO,GAC/BgB,EAAO,IAAI1B,WAAW,IACtB2B,EAAK,IAAIR,SAASO,EAAKN,QAU7B,OATAO,EAAGN,UAAU,EAAG,WAAY,GAC5BM,EAAGL,UAAU,EAAG,GAAG,GACnBK,EAAGL,UAAU,EAAG,GAAG,GACnBK,EAAGL,UAAU,EAAGd,EAAQlX,QAAQ,GAChCqY,EAAGL,UAAU,GAAId,EAAQlX,QAAQ,GACjCqY,EAAGN,UAAU,GAAII,EAAiBnY,QAAQ,GAC1CqY,EAAGN,UAAU,GAAIf,GAAQ,GACzBqB,EAAGL,UAAU,GAAI,GAAG,GAEbnB,GAAYM,EAAYmB,OAAO,CAACH,EAAkBC,MAIvDG,GAAoB,IAAIC,OAC1B,IACI1V,OAAOiT,aAAa,GACpB,IACAjT,OAAOiT,aAAa,GACpBjT,OAAOiT,aAAa,IACpBjT,OAAOiT,aAAa,IACpBjT,OAAOiT,aAAa,IACpB,IACAjT,OAAOiT,aAAa,IACpBjT,OAAOiT,aAAa,OACpBjT,OAAOiT,aAAa,OACpB,IACJ,KAIE0C,GAAazjB,GAFMA,IAAiBA,EAAKoU,QAAQmP,GAAmB,IAGtEG,CAAgB1jB,GACXoU,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,UACdA,QAAQ,KAAM,UAEjBuP,GAAgBC,IAClB,IAAItS,EAAIsS,EAAQ,EACZC,EAAU,GACd,KAAOvS,EAAI,GAAG,CACV,MAAMwS,GAAOxS,EAAI,GAAK,GACtBuS,EAAU/V,OAAOiT,aAAa,GAAK+C,GAAOD,EAC1CvS,EAAIlG,KAAK2Y,OAAOzS,EAAI,GAAK,GAC7B,CACA,OAAOuS,GAQLG,GAAa,4DAEbC,GAAgBA,CAACxD,EAAoBD,EAAyB0D,KAChE,MAAMC,EAAoB,GAC1B,IAAIC,EAAW,EAEf,MAAMC,EAAeA,CAACre,EAAahG,EAAc6C,IAC7C,SAASmD,mBAAqBnD,EAAQ,OAAOA,KAAW,kCAAkC4gB,GACtFzjB,kBAGR,GAAIwgB,EAAgB,CAChB,MAAMI,EAAQH,EAAMX,QAAQxb,IAAI,CAACqc,EAAGgB,IAAM0C,EAAa,GAAGV,GAAahC,KAAKyC,IAAYzD,EAAG,IAAIlV,KAAK,IACpG0Y,EAAQrP,KAAK,WAAWsP,MAAaxD,WACrCwD,GAAY,CAChB,CAEA3D,EAAMb,KAAKvT,QAASuU,IAChB,MAAM0D,EAAW1D,EACZtc,IAAI,CAAC+M,EAAMsQ,KACR,MAAM3b,EAAM,GAAG2d,GAAahC,KAAKyC,IAC3BjY,EAAOkF,EAAK1D,IAAIxB,KACtB,GAAIvB,EAAMyG,EAAKlD,MAAqB,KAAbkD,EAAKlD,IAAY,MAAO,GAC/C,GAAa,WAAThC,GAAyC,iBAAbkF,EAAKlD,KAAoB1B,OAAOgC,SAAS4C,EAAKlD,KAC1E,MAAO,SAASnI,SAAWqL,EAAKlD,cAEpC,GAAa,YAAThC,EACA,MAAO,SAASnG,eAAiBqL,EAAKlD,IAAM,EAAI,YAEpD,IAAc,SAAThC,GAA4B,aAATA,IAAwBI,EAAO8E,EAAKlD,KAAM,CAE9D,MAAMpB,EAAIR,EAAO8E,EAAKlD,KAUtB,MAAO,SAASnI,SAAoB,aAATmG,EAAsB,EAAI,SATzCK,KAAK+X,IACbxX,EAAEyX,cACFzX,EAAE0X,WACF1X,EAAE2X,UACF3X,EAAE4X,WACF5X,EAAE6X,aACF7X,EAAE8X,cAEe,MAAW,eAEpC,CACA,OAAOR,EAAare,EAAKqL,EAAKxC,aAEjCpD,KAAK,IACV0Y,EAAQrP,KAAK,WAAWsP,MAAaE,WACrCF,GAAY,IAGhB,MAAMU,EAAUnB,GAAavY,KAAKD,IAAIsV,EAAM1B,QAAQ/T,OAAS,EAAG,IAC1D+Z,EAAU3Z,KAAKD,IAAIiZ,EAAW,EAAG,GACjCY,EAAOd,EAAa5f,IAAI,CAAC2gB,EAAGtD,IAAM,aAAaA,EAAI,WAAWA,EAAI,aAAasD,wBAAwBxZ,KAAK,IAElH,OACIuY,iKAGA,sBAAsBc,IAAUC,kDAE/BvE,EAAiB,6EAA+E,IALjGwD,mEAQCgB,EAAO,SAASA,WAAgB,IACjC,cAAcb,EAAQ1Y,KAAK,mBAC1B+U,GAAkBC,EAAMb,KAAK5U,OAAS,EAAI,uBAAuB8Z,IAAUC,OAAe,IAC3F,gBAIFG,GACFlB,ojCAgBEmB,GACFnB,o2BAWEoB,GACFpB,yhBAOEqB,GACFrB,sXAMEsB,GAAoBC,GACtBvB,gKAGA,wBAAwBP,GAAU8B,oDAGhCC,GAAeA,KACjB,MAAMC,GAAM,IAAIjZ,MAAOkZ,cACvB,OACI1B,uUAKA,8CAA8CyB,sBAC9C,+CAA+CA,4CAKjDE,GACF3B,oOAKS4B,GAAYA,CAAC1X,EAAiBzJ,EAAqC,MAC5E,MAAM+b,EAAiB/b,EAAQ+b,iBAAkB,EAC3CC,EAAQ3B,GAAiB5Q,EAAKzJ,GAC9BohB,EAASpF,EAAM1B,QAAQza,IAAI,CAACqJ,EAAKgU,KACnC,MAAMmE,EAAWrhB,EAAQshB,gBAAgBpY,EAAIjD,QAAQtJ,MACrD,GAAI0kB,EAAU,OAAOA,EACrB,IAAI3a,EAAMsV,EAAMX,QAAQ6B,GAAG3W,OAC3B,IAAK,IAAIgb,EAAI,EAAGA,EAAI5a,KAAKF,IAAIuV,EAAMb,KAAK5U,OAAQ,KAAMgb,GAAK,EAAG,CAC1D,MAAMC,EAAMxF,EAAMb,KAAKoG,GAAGrE,GAAG9S,UAAU7D,OACnCib,EAAM9a,IAAKA,EAAM8a,EACzB,CACA,OAAO7a,KAAKF,IAAIE,KAAKD,IAAIA,EAAM,EAAG,GAAI,MAEpCoa,EA/JiB5M,KACvB,MAAMuN,GAAWvN,GAAQ,UAAUvE,QAAQ,gBAAiB,KAAKe,QAAU,SAC3E,OAAO+Q,EAAQlb,OAAS,GAAKkb,EAAQjQ,MAAM,EAAG,IAAMiQ,GA6JlCC,CAAkB1hB,EAAQ8gB,WACtCrD,EAAsB,CACxB,CAAEvJ,KAAM,sBAAuB+J,KAAMrB,GAAW8D,KAChD,CAAExM,KAAM,cAAe+J,KAAMrB,GAAW+D,KACxC,CAAEzM,KAAM,oBAAqB+J,KAAMrB,GAAWmE,OAC9C,CAAE7M,KAAM,mBAAoB+J,KAAMrB,GAAWsE,KAC7C,CAAEhN,KAAM,kBAAmB+J,KAAMrB,GAAWiE,GAAiBC,KAC7D,CAAE5M,KAAM,6BAA8B+J,KAAMrB,GAAWgE,KACvD,CAAE1M,KAAM,gBAAiB+J,KAAMrB,GAAW6D,KAC1C,CAAEvM,KAAM,2BAA4B+J,KAAMrB,GAAW4C,GAAcxD,EAAOD,EAAgBqF,MAE9F,OAAO5D,GAASC,IAedkE,GAAcpmB,GAChBA,EAAKoU,QAAQ,KAAM,SAASA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,UCrapFgS,GAAcpmB,GAChBA,EAAKoU,QAAQ,KAAM,SAASA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,QAAQA,QAAQ,KAAM,UAmF7EiS,GAAoBC,IAC7B,IAAIC,GAAO,EACX,MAAMC,EAASA,KACPD,IACJA,GAAO,EACPD,EAAOE,WAEX,IACIC,GAAuB,IAAKH,EAAQE,UACxC,CAAE,MAAOE,GACLC,QAAQD,MAAM,wBAAyBA,GACvCF,GACJ,GAGEC,GAAyBA,EAAGG,cAAaniB,UAAS+hB,aACpD,GAAwB,oBAAbnL,SAEP,YADAmL,IAGJ,MAAMK,EAAcpiB,EAAQoiB,cAAe,EACrCC,EAAariB,EAAQqiB,aAAc,EACnCtG,EAAiB/b,EAAQ+b,iBAAkB,EAC3CuG,EAAatiB,EAAQsiB,aAAc,EAEnCC,EAAQJ,EAAYK,WAAU,GAzGlBC,EAACC,EAAqBC,KACxC,MAAMC,EAAevc,MAAM6O,KAAKwN,EAAOG,iBAAiB,4BAClDC,EAAezc,MAAM6O,KAAKyN,EAAOE,iBAAiB,4BACxDD,EAAahb,QAAQ,CAAC9H,EAAIod,KACtB,MAAM6F,EAAID,EAAa5F,GACvB,GAAK6F,GAAKA,EAAEC,UAAYljB,EAAGkjB,QAE3B,GAAmB,UAAfljB,EAAGkjB,QAAqB,CACxB,MAAMvmB,EAAMqD,EACNmjB,EAAMF,EACK,aAAbtmB,EAAIiL,MAAoC,UAAbjL,EAAIiL,MAC/Bub,EAAIC,QAAUzmB,EAAIymB,QACdzmB,EAAIymB,SAASD,EAAIzK,aAAa,UAAW,IAC7CyK,EAAIE,cAAgB1mB,EAAI0mB,gBAExBF,EAAI9lB,MAAQV,EAAIU,MAChB8lB,EAAIzK,aAAa,QAAS/b,EAAIU,OAEtC,KAA0B,WAAf2C,EAAGkjB,QACTD,EAAwB5lB,MAAS2C,EAAyB3C,MACrC,aAAf2C,EAAGkjB,UACTD,EAA0B5lB,MAAS2C,EAA2B3C,MAC/D4lB,EAAEtK,YAAe3Y,EAA2B3C,SAIpD,MAAMimB,EAAiB/c,MAAM6O,KAAKwN,EAAOG,iBAAiB,WACpDQ,EAAiBhd,MAAM6O,KAAKyN,EAAOE,iBAAiB,WAC1DO,EAAexb,QAAQ,CAACiP,EAAQqG,KAC5B,MAAM6F,EAAIM,EAAenG,GACzB,GAAK6F,EACL,IACI,MAAMO,EAAMP,EAAEQ,cAAclnB,cAAc,OAC1CinB,EAAI7mB,IAAMoa,EAAO2M,YACjBF,EAAI3mB,MAAQka,EAAOla,MACnB2mB,EAAIrnB,OAAS4a,EAAO5a,OACpBqnB,EAAIllB,MAAMqlB,QAAUV,EAAE3kB,MAAMqlB,QAC5BV,EAAEW,YAAYJ,EAClB,CAAE,MACE,KAmERb,CAAcN,EAAaI,GAC3BA,EAAMM,iBAAiB,yBAAyBjb,QAAS9H,GAAOA,EAAG6jB,UAC/DvB,GAAaG,EAAMM,iBAAiB,qBAAqBjb,QAAS9H,GAAOA,EAAG6jB,UAC5EtB,GAAYE,EAAMM,iBAAiB,oBAAoBjb,QAAS9H,GAAOA,EAAG6jB,UACzE5H,GAAgBwG,EAAMM,iBAAiB,qBAAqBjb,QAAS9H,GAAOA,EAAG6jB,UACpFpB,EAAMqB,UAAU/b,IAAI,wBAEpB0a,EAAMM,iBAAiB,QAAQjb,QAAS9H,GAAOA,EAAG+jB,gBAAgB,OAClEtB,EAAMnkB,MAAMnC,OAAS,OACrBsmB,EAAMnkB,MAAM0lB,SAAW,IAEvB,MAAMxlB,EAAQ0B,EAAQ1B,OAAS,IACzBylB,OAAEA,EAAMC,MAAEA,GAAU1B,EA3IP2B,KACnB,MAAMF,EAAmB,GACnBC,EAAkB,GAYxB,OAXA3d,MAAM6O,KAAK+O,EAAIC,aAAatc,QAASuc,IACjC,IACI,MAAMC,EAAQ/d,MAAM6O,KAAKiP,EAAME,UAC1BxkB,IAAKykB,GAASA,EAAKb,SACnBzc,KAAK,MACNod,GAAOL,EAAO1T,KAAK+T,EAC3B,CAAE,MAEMD,EAAM7M,MAAM0M,EAAM3T,KAAK8T,EAAM7M,KACrC,IAEG,CAAEyM,SAAQC,UA6HsBO,CAAc3N,UAAY,CAAEmN,OAAQ,GAAIC,MAAO,IAEhFQ,EAAS5N,SAASva,cAAc,UACtCmoB,EAAOhM,aAAa,cAAe,QACnCgM,EAAOhM,aAAa,sBAAuB,QAC3CgM,EAAOpmB,MAAMqlB,QAAU,2FACvB7M,SAASY,KAAKC,YAAY+M,GAE1B,IAAIC,GAAW,EACf,MAAMC,EAASA,KACPD,IACJA,GAAW,EACX1nB,OAAO4a,WAAW,KACV6M,EAAOG,YAAYH,EAAOG,WAAW/M,YAAY4M,IACtD,KACHzC,MAGE6C,EAAMJ,EAAOK,cACbZ,EAAMO,EAAOM,iBAAmBF,GAAKhO,SAC3C,IAAKgO,IAAQX,EAET,YADAS,IAIJT,EAAIc,OACJd,EAAIe,MACA,6DAA6DrD,GAAWrjB,GAASsY,SAAStY,OAAS,mBAC/F0lB,EAAMnkB,IAAKyX,GAAS,gCAAgCqK,GAAWrK,UAAatQ,KAAK,IACjF,+BAERid,EAAIgB,QAEJlB,EAAOnc,QAASsd,IACZ,MAAM9mB,EAAQ6lB,EAAI5nB,cAAc,SAChC+B,EAAMqa,YAAcyM,EACpBjB,EAAIvL,KAAKjB,YAAYrZ,KAEzB,MAAM+mB,EAAalB,EAAI5nB,cAAc,SAIrC,GAHA8oB,EAAW1M,YApMG,09CAoMwBzY,EAAQolB,WAAa,IAC3DnB,EAAIvL,KAAKjB,YAAY0N,GAEjB7mB,EAAO,CACP,MAAM+mB,EAAKpB,EAAI5nB,cAAc,MAC7BgpB,EAAGC,UAAY,uBACfD,EAAG5M,YAAcna,EACjB2lB,EAAIzM,KAAKC,YAAY4N,EACzB,CACApB,EAAIzM,KAAKC,YAAYwM,EAAIsB,UAAUhD,IAEvBiD,WACR,SA7HcC,EAACxB,EAAeyB,IAClC,IAAIC,QAAeC,IACf,MAAMC,EAASxf,MAAM6O,KAAK+O,EAAI4B,QAAQ/e,OAAQwc,IAASA,EAAIwC,UAC3D,GAAsB,IAAlBD,EAAOtf,OAEP,YADAqf,IAGJ,IAAIG,EAAYF,EAAOtf,OACnBub,GAAO,EACX,MAAM4C,EAASA,KACP5C,IACJA,GAAO,EACP8D,MAEEI,EAAQjpB,OAAO4a,WAAW+M,EAAQgB,GACxCG,EAAOje,QAAS0b,IACZ,MAAM2C,EAAYA,KACdF,GAAa,EACTA,GAAa,IACbhpB,OAAOmpB,aAAaF,GACpBtB,MAGRpB,EAAI6C,iBAAiB,OAAQF,EAAW,CAAEG,MAAM,IAChD9C,EAAI6C,iBAAiB,QAASF,EAAW,CAAEG,MAAM,QAsG3CX,CAAcxB,EAAK,KACrBjkB,EAAQqmB,qBAAqBrmB,EAAQqmB,cAAcpC,GACvDW,EAAI0B,aAAe5B,EACnBE,EAAI2B,QACJ3B,EAAI4B,QAEJzpB,OAAO4a,WAAW+M,EAAQ,IAC9B,CAAE,MACEA,GACJ,GAEC+B,IC1LHC,GAAexpB,GAAciJ,EAAMjJ,GAAO,GAAKA,aAAe6K,KAAOsB,OAAOnM,EAAIgL,WAAamB,OAAOnM,GAE7FypB,GAAiBA,CAC1BlJ,EACAmJ,EACAC,EACApd,EACAqd,EAAa,aAEb,MAAMC,EAAQA,CAACC,EAAsBC,EAAeC,EAA+BC,KAC/E,MAAMlhB,EAAQ2gB,EAAeK,GACvB/d,EAAM2d,EAAe9L,IAAI9U,GAC/B,IAAKiD,EAAK,MAAO,GACjB,MAAMke,EAAU,IAAIxM,IACpBoM,EAAMpf,QAASgW,IACX,MAAM1gB,ENkIcmqB,EAAChgB,EAA2B6B,EAAoBO,IACxEP,EAAIoe,oBAA4Bpe,EAAIoe,oBAAoBjgB,EAAI6B,EAAIjD,OAAQoB,EAAK6B,EAAKO,GAC/ED,EAAanC,EAAK6B,EAAKO,GMpIV4d,CAAiBzJ,EAAMvW,IAAK6B,EAAKO,GACvC8d,EAASb,GAAYxpB,GAC3B,IAAIsqB,EAAOJ,EAAQrM,IAAIwM,GACvB,IAAKC,EAAM,CACP,MAAMpe,EAAQe,GAAuBF,GAAkB/M,EAAK0gB,EAAMvW,IAAK6B,EAAKO,EAAKmU,EAAMrW,MAAQuf,EAE/FU,EAAO,CACHjgB,GAFO,sBAAqB4f,IAAOlhB,KAASshB,IAG5CN,QACAQ,OAAQP,EACRQ,cAAezhB,EACf0hB,YAAazqB,EACb0qB,cAAexe,EACfye,YAAa,GACbC,OAAQ,GACRC,YAAa,IAEjBX,EAAQ3a,IAAI8a,EAAQC,EACxB,CACAA,EAAKM,OAAOzX,KAAKuN,KAErB,MAAMoK,EAA4B,GAgBlC,OAfAZ,EAAQxf,QAAS4f,IACTP,EAAQL,EAAergB,OAAS,GAChCihB,EAAKK,YAAcd,EACfS,EAAKM,OACLb,EAAQ,EACRO,EAAKjgB,GACL,GAAG4f,IAAOlhB,KAASygB,GAAYc,EAAKG,iBAExCH,EAAKO,YAAcP,EAAKM,OACxBN,EAAKM,OAAS,IAEdN,EAAKO,YAAcP,EAAKM,OAE5BE,EAAM3X,KAAKmX,KAERQ,GAEX,OAAOjB,EAAMtJ,EAAS,EAAG,KAAM,KAmCtBwK,GAAqDC,IAC9D,MAAMjY,EAAqB,GAE3B,OADAiY,EAAMtgB,QAASugB,GAASA,EAAKJ,YAAYngB,QAASU,GAAM2H,EAAII,KAAK/H,KAC1D2H,GAwDEmY,GAAgBA,CACzBjN,EACAkN,EACAxB,EACAyB,EACA7e,KAEA,MAAM8e,EAAqD,CAAA,EAS3D,OARAhZ,OAAOC,KAAK6Y,GAAkBzgB,QAAS3B,IACnC,MAAMuiB,EAASH,EAAiBpiB,GAC1BwiB,EAAKH,EAAUE,GACftf,EAAM2d,EAAe9L,IAAI9U,GAC/B,IAAKwiB,IAAOvf,IAA0B,IAAnBA,EAAIwF,WAAsB,OAC7C,MAAMkC,EAASuK,EAAKtb,IAAKwH,GAAQmC,EAAanC,EAAK6B,EAAKO,IACxD8e,EAAOtiB,GAAS,CAAE9I,MAAOsrB,EAAGzX,MAAM,CAAEJ,SAAQ3K,UAAUwiB,GAAID,KAEvDD,GCvMLG,GAAaA,CAACvB,EAAuBtO,KACvC,MAAMnW,EAAOtG,EAAMoG,WAA4C,EAAGb,OAAO,GAAI2jB,YAAWlnB,WAAUuqB,GAAQpnB,IACtGnF,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLqnB,QAAQ,YACRjsB,MAAOgF,EACP1F,OAAQ0F,EACRzF,KAAK,eACL2sB,UAAU,QAAO,cACL,OACZvD,UAAW,CAAC,gBAAiBA,GAAWxe,OAAOC,SAASC,KAAK,KAC7D5I,MAAOA,KACHuqB,GAEHxB,IAIT,OADAzkB,EAAKmW,YAAcA,EACZnW,GAGEomB,GAAiBJ,GAC1BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,sEACR,kBAESygB,GAAiBL,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,mDAAqD,kBACzF0gB,GAAaN,GACtBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,+MACR,cAES2gB,GAAYP,GACrBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,0GACR,aAES4gB,GAAeR,GACxBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,uHACR,gBAES6gB,GAAkBT,GAC3BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,gEACR,mBAES8gB,GAAoBV,GAC7BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,kEACR,qBAES+gB,GAAeX,GACxBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,sJACR,gBAESghB,GAAYZ,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,sDAAwD,aACvFihB,GAAiBb,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,iDAAmD,kBACvFkhB,GAAmBd,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,mDAAqD,oBAC3FmhB,GAAkBf,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,kDAAoD,mBACzFohB,GAAgBhB,GACzBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,+DACR,iBAESqhB,GAAejB,GACxBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,+DACR,gBAESshB,GAAclB,GACvBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,0IACR,eAESuhB,GAAanB,GACtBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,kFACR,cAESwhB,GAAUpB,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,wCAA0C,WACvEyhB,GAAmBrB,GAC5BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,sDACR,oBAES0hB,GAAoBtB,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,0CAA4C,qBACnF2hB,GAAmBvB,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,8BAAgC,oBACtE4hB,GAAoBxB,GAC7BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,wSACR,qBAES6hB,GAAYzB,GACrBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,sJACR,aAES8hB,GAAiB1B,GAC1BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,mIACR,kBAES+hB,GAAkB3B,GAC3BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,mIACR,mBAESgiB,GAAoB5B,GAC7BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,8fACR,qBAESiiB,GAAgB7B,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,+CAAiD,iBACpFkiB,GAAiB9B,GAC1BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,mKACR,kBAESmiB,GAAe/B,GACxBtsB,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAAA,OAAA,CACIiM,EAAE,2NACF7H,QAAQ,QAEZrE,EAAAC,cAAA,OAAA,CAAMiM,EAAE,gBAAgB7H,QAAQ,SAEpC,+hBCrGSkqB,GAASvuB,EAAMoG,WACxB,EACMrD,UAAU,OAAQwC,OAAO,SAAUiD,YAAWC,UAAS+lB,SAAQtF,YAAW3gB,WAAU+C,OAAO,YAAaihB,GAC1GpnB,IAEAnF,EAAAC,cAAA,SAAA,CACIkF,IAAKA,EACLmG,KAAMA,EACN4d,UAAW1e,EACP,eACY,YAAZzH,GAAyB,wBACb,cAAZA,GAA2B,0BAClB,UAATwC,GAAoB,sBACpBipB,GAAU,uBACVtF,MAEAqD,GAEH/jB,EACAD,EACAE,IAIb8lB,GAAO9R,YAAc,sBASRgS,GAAazuB,EAAMoG,WAC5B,EAAGb,OAAO,SAAUipB,SAAQxhB,QAAOkc,YAAW3gB,WAAU+C,OAAO,YAAaihB,GAAQpnB,IAChFnF,EAAAC,cAAA,SAAA,CACIkF,IAAKA,EACLmG,KAAMA,EACNpJ,MAAO8K,EAAK,aACAA,EACZkc,UAAW1e,EACP,kCACS,UAATjF,GAAoB,sBACpBipB,GAAU,uBACVtF,MAEAqD,GAEHhkB,IAIbkmB,GAAWhS,YAAc,oBAYlB,MAAM7Z,GAAQA,EAAG6V,QAAQ,EAAG1V,UAAU,MAAOwF,cAChDvI,EAAAC,cAAA,OAAA,CAAMipB,UAAU,kBACX3gB,EACAkQ,EAAQ,IACQ,QAAZ1V,EACG/C,EAAAC,cAAA,OAAA,CAAMipB,UAAU,uBAEhBlpB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,wBAAwBzQ,EAAQ,GAAK,MAAQA,KAahEiW,GAAY1uB,EAAMoG,WAC3B,EAAGb,OAAO,SAAU2jB,eAAcqD,GAAQpnB,IACtCnF,EAAAC,cAAA,QAAA,CACIkF,IAAKA,EACL+jB,UAAW1e,EAAG,iBAA2B,UAATjF,GAAoB,wBAAyB2jB,MACzEqD,KAIhBmC,GAAUjS,YAAc,yBAMXkS,GAAS3uB,EAAMoG,WAA2C,EAAGb,OAAO,SAAU2jB,eAAcqD,GAAQpnB,IAC7GnF,EAAAC,cAAA,SAAA,CAAQkF,IAAKA,EAAK+jB,UAAW1e,EAAG,kBAA4B,UAATjF,GAAoB,yBAA0B2jB,MAAgBqD,KAErHoC,GAAOlS,YAAc,gBASd,MAAMmS,GAAQA,EAAG5hB,QAAOzE,WAAU2gB,YAAW2F,aAChD7uB,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,EAAG,iBAAkB0e,IAChClc,GACGhN,EAAAC,cAAA,QAAA,CAAOipB,UAAU,uBAAuB2F,QAASA,GAC5C7hB,GAGRzE,GASIumB,GAAW9uB,EAAMoG,WAC1B,EAAG2gB,iBAAgB,EAAO/Z,QAAOkc,eAAcqD,GAAQwC,KACnD,MAAMC,EAAWhvB,EAAM+c,OAAgC,MACjDkS,EAASjvB,EAAM4d,YAChBwN,IACG4D,EAAShS,QAAUoO,EACS,mBAAjB2D,EAA6BA,EAAa3D,GAC5C2D,IAAeA,EAAiE/R,QAAUoO,IAEvG,CAAC2D,IAKL,OAHA/uB,EAAMgc,UAAU,KACRgT,EAAShS,UAASgS,EAAShS,QAAQ+J,cAAgBA,IACxD,CAACA,IAEA/mB,EAAAC,cAAA,QAAA,CACIkF,IAAK8pB,EACL3jB,KAAK,WACLpJ,MAAO8K,EAAK,aACAA,EACZkc,UAAW1e,EAAG,oBAAqB0e,MAC/BqD,MAKpBuC,GAASrS,YAAc,kBAMhB,MAAMyS,GAAUA,EAAGhG,eACtBlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,EAAG,mBAAoB0e,GAAYiG,KAAK,cAAa,aAAY,qBAyBrEC,IAAQzG,KACpBA,EAAI0G,SACJA,EAAQC,QACRA,EAAO/mB,SACPA,EAAQgnB,UACRA,EAAY,eAAclwB,UAC1BA,EAAY,QAAO6pB,UACnBA,EAASlnB,MACTA,EAAKmf,OACLA,EAAS,EAACgO,KACVA,EAAO,SAAQK,UACfA,GAAY,EAAKC,qBACjBA,IAEA,MAAMtqB,EAAMnF,EAAM+c,OAA8B,OACzCnX,EAAU8pB,GAAe1vB,EAAMwd,SAAwD,CAC1FmS,IAAK,EACLC,KAAM,EACNC,OAAO,IAGLC,EAAS9vB,EAAM4d,YAAY,KAC7B,MAAMla,EAAKyB,EAAI6X,QACf,IAAKtZ,EAAI,OACT,MAAMqsB,EAAKpvB,OAAOqvB,WACZC,EAAKtvB,OAAOuvB,YACZ9L,EAAI1gB,EAAGysB,YACPrQ,EAAIpc,EAAG0sB,aACb,IAAIT,EACAC,EACJ,GAAIP,GAAYA,EAASgB,YAAa,CAClC,MAAM1f,EAAI0e,EAASiB,wBACD,gBAAdf,GACAI,EAAMhf,EAAEgf,IACRC,EAAOjf,EAAE4f,MAAQpP,EACbyO,EAAOxL,EAAI2L,EAAK,IAAGH,EAAOjf,EAAEif,KAAOzO,EAASiD,KAEhDuL,EAAMhf,EAAE6f,OAASrP,EACbwO,EAAM7P,EAAImQ,EAAK,GAAKtf,EAAEgf,IAAMxO,EAASrB,GAAK,IAAG6P,EAAMhf,EAAEgf,IAAMxO,EAASrB,GACxE8P,EACkB,eAAdL,EACM5e,EAAE4f,MAAQnM,EACI,WAAdmL,EACE5e,EAAEif,KAAOjf,EAAEpQ,MAAQ,EAAI6jB,EAAI,EAC3BzT,EAAEif,KAEtB,MACID,EAAMM,EAAK,EAAInQ,EAAI,EACnB8P,EAAOG,EAAK,EAAI3L,EAAI,EAExBuL,EAAMvlB,EAAMulB,EAAK,EAAGplB,KAAKD,IAAI,EAAG2lB,EAAKnQ,EAAI,IACzC8P,EAAOxlB,EAAMwlB,EAAM,EAAGrlB,KAAKD,IAAI,EAAGylB,EAAK3L,EAAI,IAC3CsL,EAAae,GAAUA,EAAKZ,OAASY,EAAKd,MAAQA,GAAOc,EAAKb,OAASA,EAAOa,EAAO,CAAEd,MAAKC,OAAMC,OAAO,KAC1G,CAACR,EAAUE,EAAWpO,IAwDzB,GAtDAnhB,EAAM+b,gBAAgB,KAClB,IAAK4M,EAED,YADA+G,EAAae,GAAUA,EAAKZ,MAAQ,IAAKY,EAAMZ,OAAO,GAAUY,GAGpEX,IACAnvB,OAAOopB,iBAAiB,SAAU+F,GAClCnvB,OAAOopB,iBAAiB,SAAU+F,GAAQ,GAC1C,IAAIY,EAAkC,KAKtC,MAJ8B,oBAAnBC,gBAAkCxrB,EAAI6X,UAC7C0T,EAAW,IAAIC,eAAe,IAAMb,KACpCY,EAASE,QAAQzrB,EAAI6X,UAElB,KACHrc,OAAOkwB,oBAAoB,SAAUf,GACrCnvB,OAAOkwB,oBAAoB,SAAUf,GAAQ,GAC7CY,GAAUI,eAEf,CAACnI,EAAMmH,IAEV9vB,EAAMgc,UAAU,KACZ,IAAK2M,EAAM,OACX,MAAMoI,EAAqBC,IACvB,MAAMzK,EAASyK,EAAMzK,OAChBA,IACDphB,EAAI6X,SAASiU,SAAS1K,IACtB8I,GAAU4B,SAAS1K,IACnBkJ,GAAsByB,KAAM/L,GAAMA,EAAEnI,SAASiU,SAAS1K,KAErDA,EAAuB4K,UAAU,sBACtC7B,EAAQ,cAEN8B,EAAiBJ,IACD,WAAdA,EAAMlwB,KAAkBwuB,EAAQ,WAKxC,OAHA9U,SAASuP,iBAAiB,YAAagH,GAAmB,GAC1DvW,SAASuP,iBAAiB,aAAcgH,GAAmB,GAC3DvW,SAASuP,iBAAiB,UAAWqH,GAC9B,KACH5W,SAASqW,oBAAoB,YAAaE,GAAmB,GAC7DvW,SAASqW,oBAAoB,aAAcE,GAAmB,GAC9DvW,SAASqW,oBAAoB,UAAWO,KAE7C,CAACzI,EAAM2G,EAASD,EAAUI,IAE7BzvB,EAAMgc,UAAU,KACZ,GAAI2M,GAAQ6G,GAAarqB,EAAI6X,QAAS,EAChB7X,EAAI6X,QAAQqU,cAC1B,qEAEUlsB,EAAI6X,SAASmN,OAC/B,GACD,CAACxB,EAAM6G,KAEL7G,GAA4B,oBAAbnO,SAA0B,OAAO,KAErD,MAAM8W,EAAQN,GAAgCA,EAAMO,kBAEpD,OAAOC,eACHxxB,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLgqB,KAAMA,EACNsC,UAAU,EACVvI,UAAW1e,EAAG,mBAAoB0e,GAAU,iBAC5B7pB,EAChB2C,MAAO,CACH2tB,IAAK/pB,EAAS+pB,IACdC,KAAMhqB,EAASgqB,KACf8B,WAAY9rB,EAASiqB,MAAQ,UAAY,YACtC7tB,GAEP2vB,QAASL,EACTM,cAAeN,EACfO,YAAaP,EACbQ,UAAYd,IACR,GAAkB,WAAdA,EAAMlwB,IAGN,OAFAkwB,EAAMO,uBACNjC,EAAQ,UAGZ0B,EAAMO,oBAGThpB,GAELiS,SAASY,KAEjB,CAUO,MAAM2W,GAAOA,EAAGxpB,WAAU2gB,YAAW4I,eAAcvF,MACtD,MAAMpnB,EAAMnF,EAAM+c,OAAgC,MAyBlD,OALA/c,EAAMgc,UAAU,KACZ,MAAMgW,EAAQ7sB,EAAI6X,SAASqU,cAA2B,iDACtDW,GAAO7H,SACR,IAGCnqB,EAAAC,cAAA,KAAA,CAAIkF,IAAKA,EAAKgqB,KAAK,OAAOjG,UAAW1e,EAAG,gBAAiB0e,GAAY4I,UAxBlDd,IAEnB,GADAc,IAAYd,GACM,cAAdA,EAAMlwB,KAAqC,YAAdkwB,EAAMlwB,KAAmC,SAAdkwB,EAAMlwB,KAAgC,QAAdkwB,EAAMlwB,IAAe,OACzG,MAAM8pB,EAAQ3gB,MAAM6O,KAChB3T,EAAI6X,SAASyJ,iBAA8B,kDAAoD,IAEnG,GAAqB,IAAjBmE,EAAMzgB,OAAc,OACxB6mB,EAAMiB,iBACN,MAAMC,EAAetH,EAAM3a,QAAQuK,SAAS2X,eAC5C,IAAItU,EAAO,EACoBA,EAAb,cAAdmT,EAAMlwB,IAA4BoxB,EAAe,EAAI,GAAKA,EAAe,GAAKtH,EAAMzgB,OACjE,YAAd6mB,EAAMlwB,IACJoxB,EAAe,EAAItH,EAAMzgB,OAAS,GAAK+nB,EAAe,EAAItH,EAAMzgB,QAAUygB,EAAMzgB,OACpE,SAAd6mB,EAAMlwB,IAAuB,EAC1B8pB,EAAMzgB,OAAS,EAC3BygB,EAAM/M,GAAMsM,YASuFoC,GAC9FhkB,IAYA6pB,GAAWpyB,EAAMoG,WAC1B,EAAGC,OAAMgsB,WAAUC,WAAUpJ,YAAW3gB,WAAUopB,UAASY,cAAahG,GAAQpnB,IAC5EnF,EAAAC,cAAA,KAAA,CAAIkvB,KAAK,QACLnvB,EAAAC,cAAA,SAAA,CACIkF,IAAKA,EACLmG,KAAK,SACL6jB,KAAK,WAAU,gBACAmD,QAAY/kB,EAC3B+kB,SAAUA,EACVb,UAAU,EACVvI,UAAW1e,EACP,qBACA8nB,GAAY,+BACZD,GAAY,+BACZnJ,GAEJyI,QAAUX,IACFsB,IACJX,IAAUX,GACVuB,WAEAhG,GAEHlmB,EACDrG,EAAAC,cAAA,OAAA,KAAOsI,MAKvB6pB,GAAS3V,YAAc,kBAEhB,MAAM+V,GAAcA,IAAMxyB,EAAAC,cAAA,KAAA,CAAIkvB,KAAK,YAAYjG,UAAU,0BAQnDuJ,GAAcA,EAAGlqB,cAC1BvI,sBAAImvB,KAAK,eAAejG,UAAU,yBAC7B3gB,YCvZOmqB,KACZ,MAAMrlB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,GAAejW,KAC7BkW,EAASlwB,EAAMmwB,gBAAgBlK,MAAmD,YAA3CjmB,EAAMmwB,gBAAgBC,iBACnE,OACI9yB,gBAACyuB,GAAU,CACPzhB,MAAO2lB,EAAWjd,eAClB8Y,OAAQoE,kBACM,SAAQ,gBACPA,EACfjB,QAAUX,GAAW4B,EAASvlB,EAAI0lB,kBAAoB1lB,EAAI2lB,gBAAgB,UAAWhC,EAAMiC,gBAE3FjzB,EAAAC,cAACysB,GAAc,MAG3B,UAEgBwG,KACZ,MAAM7lB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,GAAejW,KAC7BkW,EAASlwB,EAAMmwB,gBAAgBlK,MAAmD,YAA3CjmB,EAAMmwB,gBAAgBC,iBACnE,OACI9yB,gBAACyuB,GAAU,CACPzhB,MAAO2lB,EAAWhd,eAClB6Y,OAAQoE,kBACM,SAAQ,gBACPA,EACfjB,QAAUX,GAAW4B,EAASvlB,EAAI0lB,kBAAoB1lB,EAAI2lB,gBAAgB,UAAWhC,EAAMiC,gBAE3FjzB,EAAAC,cAAC2C,GAAK,CAAC6V,MAAO/V,EAAMI,YAAaC,QAAQ,OACrC/C,EAAAC,cAAC0sB,GAAc,OAI/B,UAEgBwG,KACZ,MAAM9lB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,EAAUtzB,UAAEA,GAAcqd,MACvCzB,EAAQmY,GAAapzB,EAAMwd,SAA6B,MACzD5Z,EAAU,CACZ,CAAE7C,MAAO,UAAWiM,MAAO2lB,EAAWxc,eAAgB9P,KAAMrG,EAAAC,cAAC0tB,UAC7D,CAAE5sB,MAAO,WAAYiM,MAAO2lB,EAAWvc,gBAAiB/P,KAAMrG,EAAAC,cAAC2tB,UAC/D,CAAE7sB,MAAO,cAAeiM,MAAO2lB,EAAWtc,mBAAoBhQ,KAAMrG,EAAAC,cAAC4tB,WAEnE7Q,EAAUpZ,EAAQ+J,KAAM0lB,GAAMA,EAAEtyB,QAAU2B,EAAM4wB,UAAY1vB,EAAQ,GAC1E,OACI5D,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACwuB,IACGzhB,MAAO2lB,EAAW9c,eAClB2Y,OAAQ7jB,QAAQsQ,mBACF,OACd0W,QAAUX,GAAUoC,EAAW3C,GAAUA,EAAO,KAAOO,EAAMiC,gBAE5DjW,EAAQ3W,MAEbrG,EAAAC,cAACmvB,GAAO,CACJzG,KAAMhe,QAAQsQ,GACdoU,SAAUpU,EACVqU,QAASA,IAAM8D,EAAU,MACzB/zB,UAAWA,EACX8vB,KAAK,QAELnvB,EAAAC,cAAC8xB,GAAI,KACAnuB,EAAQH,IAAKmJ,GACV5M,EAAAC,cAACmyB,GAAQ,CACLtxB,IAAK8L,EAAO7L,MACZsF,KAAMuG,EAAOvG,KACbgsB,SAAUzlB,EAAO7L,QAAU2B,EAAM4wB,QACjC3B,QAASA,IAAMtkB,EAAIkmB,WAAW3mB,EAAO7L,OACrCwxB,SAAUA,IAAMa,EAAU,OAEzBxmB,EAAOI,UAOpC,CAYO,MAAMwmB,GAAwBpB,GAc/B,SAAUqB,IAAkBtwB,WAC9BA,EAAa,CAAEC,YAAY,GAAMC,aACjCA,EAAe,CAAED,YAAY,GAAME,aACnCA,EAAYxB,cACZA,GAAgB,EAAI4xB,gBACpBA,GAAkB,EAAIC,gBACtBA,GAAkB,EAAI9xB,eACtBA,IAEA,MAAMwL,IAAEA,EAAGslB,WAAEA,EAAUtzB,UAAEA,EAASu0B,UAAEA,GAAclX,MAC3CzB,EAAQmY,GAAapzB,EAAMwd,SAA6B,MACzD+U,EAAWA,IAAMa,EAAU,MAE3BS,EAAc7zB,EAAM8zB,SAASrwB,IAAI5B,EAAiBkyB,GACpD/zB,EAAMg0B,eAAeD,GAAS/zB,EAAMi0B,aAAaF,EAAkC,CAAExB,aAAcwB,GAGjGG,EAAkD,CACpDhyB,MAAmC,iBAArB0xB,EAAUO,OAAsBP,EAAUO,YAAS5mB,KAC9DjK,GAGP,OACItD,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACwuB,IACGzhB,MAAO2lB,EAAW/c,cAClB4Y,OAAQ7jB,QAAQsQ,GAAO,gBACT,OACd0W,QAAUX,GAAUoC,EAAW3C,GAAUA,EAAO,KAAOO,EAAMiC,gBAE7DjzB,EAAAC,cAAC6sB,UAEL9sB,EAAAC,cAACmvB,IAAQzG,KAAMhe,QAAQsQ,GAASoU,SAAUpU,EAAQqU,QAASiD,EAAUlzB,UAAWA,EAAW8vB,KAAK,QAC5FnvB,EAAAC,cAAC8xB,GAAI,KACA8B,EACA/xB,GACG9B,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAACguB,GAAe,MACtB0D,QAASA,IAAMtkB,EAAI+mB,gBAAgBjxB,GACnCovB,SAAUA,GAETI,EAAW3c,kBAGnB0d,GACG1zB,EAAAC,cAACmyB,IACG/rB,KAAMrG,EAAAC,cAAC+tB,GAAc,MACrB2D,QAASA,KACAtkB,EAAIgnB,kBAAkBhxB,IAE/BkvB,SAAUA,GAETI,EAAW1c,oBAGnB0d,GACG3zB,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAAC8tB,GAAS,MAChB4D,QAASA,IAAMtkB,EAAIinB,kBAAkBJ,GACrC3B,SAAUA,GAETI,EAAWzc,sBAOxC,CAaM,SAAUqe,IAAmBjvB,YAAEA,EAAWkvB,WAAEA,EAAUC,eAAEA,GAAiB,IAC3E,MAAMpnB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,EAAUiB,UAAEA,GAAclX,KACxCgY,GAAiBhyB,EAAMiyB,mBAAqB,IAAI/pB,KAAK,MACpDzL,EAAMy1B,GAAW50B,EAAMwd,SAASkX,IAChCpwB,EAAUuwB,GAAe70B,EAAMwd,SAASiX,GAAoC,KAAlBC,GAC3DrvB,EAAWrF,EAAM+c,OAAgC,MACjD6M,EAAQ5pB,EAAM+c,OAAsB,MACpC+X,EAAQN,GAAcZ,EAAUmB,sBAGhCC,EAAeh1B,EAAM+c,OAAO2X,GAClC10B,EAAMgc,UAAU,KACR0Y,IAAkBM,EAAahY,UAC/BgY,EAAahY,QAAU0X,EACvBE,EAAQF,GACc,KAAlBA,GAAsBG,GAAY,KAE3C,CAACH,IAEJ10B,EAAMgc,UACF,IAAM,KACoB,OAAlB4N,EAAM5M,SAAkBrc,OAAOmpB,aAAaF,EAAM5M,UAE1D,IAGJ,MAAMiY,EAAUl0B,IACZ,MAAMyT,EAASzT,EAAMqT,MAAM,OAAO1J,OAAQmG,GAAY,KAANA,GAChDmkB,EAAahY,QAAUxI,EAAO5J,KAAK,KACnCyC,EAAI6nB,qBAAqB1gB,IASvB2gB,EAAQA,KACY,OAAlBvL,EAAM5M,SAAkBrc,OAAOmpB,aAAaF,EAAM5M,SACtD4X,EAAQ,IACRK,EAAO,IACP5vB,EAAS2X,SAASmN,SAQhBiL,EAAaX,GAAkBnwB,EAErC,OACItE,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,EAAG,wBAAyB4qB,GAAc,oCACtDp1B,EAAAC,cAACwuB,GAAU,CACPvF,UAAU,gCACVlc,MAAO2lB,EAAW5c,wBAAuB,gBAC1Bqf,EACf3D,SAAU2D,GAAa,EAAK,EAC5BzD,QAdG0D,KACXR,GAAY,GACZl0B,OAAO4a,WAAW,IAAMlW,EAAS2X,SAASmN,QAAS,KAc3CnqB,EAAAC,cAAC2sB,UAEL5sB,EAAAC,cAAA,MAAA,CACIipB,UAAW1e,EACP,uDACArL,GAAQ,sCAGZa,EAAAC,cAAA,OAAA,CAAMipB,UAAU,4BACZlpB,EAAAC,cAAC2sB,GAAU,CAACrnB,KAAM,MAEtBvF,EAAAC,cAACyuB,GAAS,CACNvpB,IAAKE,EACLE,KAAK,QACL+F,KAAK,SACLvK,MAAO5B,EACPsyB,SAAU2D,EAAa,GAAI,EAC3B9vB,YAAaA,GAAeqtB,EAAW7c,8BAA6B,aACxD6c,EAAW5c,wBACvBqH,SAAW4T,IAAUsE,OAhDfv0B,EAgD4BiwB,EAAMzK,OAAOxlB,MA/C3D6zB,EAAQ7zB,GACc,OAAlB6oB,EAAM5M,SAAkBrc,OAAOmpB,aAAaF,EAAM5M,cACtD4M,EAAM5M,QAAUrc,OAAO4a,WAAW,IAAM0Z,EAAOl0B,GAAQ+zB,IAHrC/zB,OAiDNw0B,OAAQA,KACCd,GAAkC,KAAhBt1B,EAAKmV,QAAeugB,GAAY,IAE3D/C,UAAYd,IACU,WAAdA,EAAMlwB,MACNkwB,EAAMO,kBACFpyB,EAAMg2B,IACAV,IACNI,GAAY,GACZxvB,EAAS2X,SAASwY,SAGR,UAAdxE,EAAMlwB,MACgB,OAAlB8oB,EAAM5M,SAAkBrc,OAAOmpB,aAAaF,EAAM5M,SACtDiY,EAAO91B,OAIlBA,GACGa,EAAAC,cAAA,OAAA,CAAMipB,UAAU,0DACZlpB,EAAAC,cAACwuB,GAAU,CAAClpB,KAAK,QAAQyH,MAAO2lB,EAAWvY,YAAauX,QAASwD,EAAO1D,UAAU,GAC9EzxB,EAAAC,cAAC4sB,YAO7B,CAMM,SAAUvrB,IAAeC,kBAC3BA,GAAoB,EAAIC,iBACxBA,GAAmB,EAAIC,iBACvBA,GAAmB,EAAIC,gBACvBA,GAAkB,EAAI+zB,oBACtBA,GAAsB,EAAK3zB,cAC3BA,GAAgB,EAAI4xB,gBACpBA,GAAkB,EAAIC,gBACtBA,GAAkB,EAAIxwB,WACtBA,EAAUE,aACVA,EAAYC,aACZA,EAAY3B,mBACZA,EAAkBC,gBAClBA,EAAeC,eACfA,EAAc6zB,uBACdA,EAAsBX,sBACtBA,IAEA,MAAMnB,UAAEA,GAAclX,KAChBiZ,EAAcp0B,IAAsBqyB,EAAUgC,sBAC9CC,EAAcr0B,IAAqBoyB,EAAUkC,oBAC7CC,EAAcN,IAAwB7B,EAAUoC,uBAEtD,OACIh2B,uBAAKkpB,UAAU,mBAAmBiG,KAAK,WACnCnvB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,0BACVyM,GAAe31B,EAAAC,cAACyyB,GAAoB,MACpCmD,GAAe71B,EAAAC,cAACizB,GAAoB,MACpC6C,GAAe/1B,EAAAC,cAACkzB,GAAsB,MACtC1xB,GACGzB,EAAAC,cAACwzB,IACGtwB,WAAYA,EACZE,aAAcA,EACdC,aAAcA,EACdxB,cAAeA,EACf4xB,gBAAiBA,EACjBC,gBAAiBA,EACjB9xB,eAAgBA,KAI3BD,GAAmB5B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,2BAA2BtnB,GAC9D5B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,0BACVvnB,EACAD,GACG1B,EAAAC,cAACs0B,GAAkB,CAACjvB,YAAaowB,EAAwBlB,WAAYO,KAKzF,UCnXgBkB,KACZ,MAAM5oB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,EAAUiB,UAAEA,GAAclX,MACxCwZ,KAAEA,EAAIC,SAAEA,GAAazzB,EAAM0zB,gBAC3B3d,EAAQ/V,EAAM2zB,SACdC,EAAY5zB,EAAM4zB,UAClBxd,EAAiB,IAAVL,EAAc,EAAIyd,EAAOC,EAAW,EAC3Cpd,EAAKxO,KAAKF,IAAIoO,GAAQyd,EAAO,GAAKC,GAClCvyB,GAC8C,IAAhDgwB,EAAU2C,gBAAgBtmB,QAAQkmB,GAC5BvC,EAAU2C,gBAAgB9T,OAAO,CAAC0T,IAAW9gB,KAAK,CAAC1E,EAAGC,IAAMD,EAAIC,GAChEgjB,EAAU2C,gBAEpB,OACIv2B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,sBAAsBiG,KAAK,aAAY,aAAY,cAC9DnvB,EAAAC,cAAA,OAAA,KAAO0yB,EAAW/Z,6BAClB5Y,EAAAC,cAAC0uB,GAAM,CACHzF,UAAU,6BACVnoB,MAAOo1B,EAAQ,aACHxD,EAAW/Z,4BACvBwE,SAAW4T,GAAU3jB,EAAImpB,YAAY5qB,OAAOolB,EAAMzK,OAAOxlB,SAExD6C,EAAQH,IAAKmJ,GACV5M,EAAAC,cAAA,SAAA,CAAQa,IAAK8L,EAAQ7L,MAAO6L,GACvBA,KAIb5M,EAAAC,cAAA,OAAA,KAAO0yB,EAAW9Z,8BAA8BC,EAAMC,EAAIN,IAC1DzY,EAAAC,cAAA,MAAA,CAAKipB,UAAU,+BACXlpB,EAAAC,cAACwuB,GAAU,CAACzhB,MAAO2lB,EAAW3Z,0BAA2BsZ,SAAU4D,GAAQ,EAAGvE,QAASA,IAAMtkB,EAAIopB,QAAQ,IACrGz2B,EAAAC,cAACqtB,UAELttB,EAAAC,cAACwuB,GAAU,CACPzhB,MAAO2lB,EAAW1Z,6BAClBqZ,SAAU4D,GAAQ,EAClBvE,QAASA,IAAMtkB,EAAIopB,QAAQP,EAAO,IAElCl2B,EAAAC,cAACotB,UAELrtB,EAAAC,cAACwuB,GAAU,CACPzhB,MAAO2lB,EAAWzZ,yBAClBoZ,SAAU4D,GAAQI,EAAY,EAC9B3E,QAASA,IAAMtkB,EAAIopB,QAAQP,EAAO,IAElCl2B,EAAAC,cAACmtB,UAELptB,EAAAC,cAACwuB,GAAU,CACPzhB,MAAO2lB,EAAWxZ,yBAClBmZ,SAAU4D,GAAQI,EAAY,EAC9B3E,QAASA,IAAMtkB,EAAIopB,QAAQlsB,KAAKD,IAAIgsB,EAAY,EAAG,KAEnDt2B,EAAAC,cAACstB,GAAY,QAKjC,UAEgBmJ,KACZ,MAAMh0B,MAAEA,EAAKiwB,WAAEA,EAAUiB,UAAEA,GAAclX,KACnCia,EAAgBj0B,EAAMk0B,kBAAkBrrB,IAAIhG,KAC5CsxB,EAAeF,EAAgB,IAAM/C,EAAUkD,2BAC/CC,EAAiBnD,EAAUoD,aAAepD,EAAUqD,qBACpDC,GAAgBH,IAAmBnD,EAAUuD,mBAEnD,OACIn3B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBACXlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,wBACV2N,GAAgB72B,EAAAC,cAAA,OAAA,KAAO0yB,EAAWna,kBAAkBme,KAExDO,GACGl3B,EAAAC,cAAA,OAAA,KACK0yB,EAAWha,oBAAkBjW,EAAM2zB,SAAS3d,kBAGpDqe,GAAkB/2B,EAAAC,cAACg2B,GAAiB,MAGjD,UC9EgBmB,KACZ,MAAM/pB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,EAAUzU,QAAEA,EAAOmZ,eAAEA,GAAmB3a,KACtD4a,EAAgBt3B,EAAMu3B,QAAQ,IAAM,IAAIluB,IAAIguB,EAAe5zB,IAAKqJ,GAAQA,EAAIjD,QAAS,CAACwtB,KACrFG,EAAQC,GAAaz3B,EAAMwd,SAAS,IACrCka,EAAQh1B,EAAMi1B,sBAEdzlB,EAAWgM,EAAQxT,OAAQoC,IAAyB,IAAjBA,EAAIoF,UACvClC,EAASwnB,EAAOljB,OAAO5E,cACvBkoB,EAAW5nB,EACXkC,EAASxH,OAAQoC,IAAwE,KAA/DA,EAAI+E,YAAc/E,EAAIjD,OAAO6F,cAAcO,QAAQD,IAC7EkC,EAEA2lB,EAAUC,IACZ,MAAMja,EAAO,IAAK6Z,GAClBxlB,EAAS1G,QAASsB,IACd+Q,EAAK/Q,EAAIjD,OAASiuB,IAEtBzqB,EAAI0qB,yBAAyBla,IAGjC,OACI7d,EAAAC,cAAA,MAAA,CAAKipB,UAAU,iBAAiBiG,KAAK,QAAO,aAAawD,EAAWjd,gBAChE1V,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBACXlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,0BACXlpB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,4BACZlpB,EAAAC,cAAC2sB,GAAU,CAACrnB,KAAM,MAEtBvF,EAAAC,cAACyuB,GAAS,CACNc,WAAS,EACTjqB,KAAK,QACLxE,MAAOy2B,EACPlyB,YAAaqtB,EAAWrc,8BAA6B,aACzCqc,EAAWrc,8BACvB8G,SAAW4T,GAAUyG,EAAUzG,EAAMzK,OAAOxlB,WAIxDf,EAAAC,cAAA,MAAA,CAAKipB,UAAU,0BACXlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBACV0O,EAASn0B,IAAKqJ,IACX,MAAMgrB,EAAUR,EAAcxtB,IAAIgD,EAAIjD,OACtC,OACI7J,EAAAC,cAAA,QAAA,CAAOa,IAAKgM,EAAIjD,MAAOqf,UAAU,2BAC7BlpB,EAAAC,cAAC6uB,IAAShI,QAASgR,EAAS1a,SAAUA,IAAM/P,EAAI2qB,oBAAoBlrB,EAAIjD,OAAQiuB,KAChF93B,EAAAC,cAAA,OAAA,KAAO6M,EAAI+E,YAAc/E,EAAIjD,UAIpB,IAApB+tB,EAASztB,QAAgBnK,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBAAuB,gBAGxElpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBACXlpB,EAAAC,cAACsuB,IAAOxrB,QAAQ,UAAUwC,KAAK,QAAQosB,QAASA,IAAMkG,GAAO,IACxDlF,EAAWpc,qBAEhBvW,EAAAC,cAACsuB,IAAOxrB,QAAQ,UAAUwC,KAAK,QAAQosB,QAASA,IAAMkG,GAAO,IACxDlF,EAAWnc,qBAEhBxW,EAAAC,cAACsuB,GAAM,CAAChpB,KAAK,QAAQosB,QAASA,IAAMtkB,EAAI0qB,yBAAyB,CAAA,IAC5DpF,EAAWlc,oBAKhC,CCtDA,MAAMwhB,GAAoBA,CAACl3B,EAAYm3B,EAAgCpD,EAAQ,OAC3E,MAAOhT,EAAOqW,GAAYn4B,EAAMwd,SAASzc,GAAS,IAC5C6oB,EAAQ5pB,EAAM+c,OAAsB,MAC1C/c,EAAMgc,UAAU,KACZmc,EAASp3B,GAAS,KACnB,CAACA,IAYJ,OANAf,EAAMgc,UACF,IAAM,KACoB,OAAlB4N,EAAM5M,SAAkBrc,OAAOmpB,aAAaF,EAAM5M,UAE1D,IAEG,CAAC8E,EAXQjE,IACZsa,EAASta,GACa,OAAlB+L,EAAM5M,SAAkBrc,OAAOmpB,aAAaF,EAAM5M,SACtD4M,EAAM5M,QAAUrc,OAAO4a,WAAW,IAAM2c,EAASra,GAAOiX,MAWhE,SAASsD,IAAexoB,KAAEA,EAAIwN,SAAEA,EAAQ9X,YAAEA,EAAWgG,KAAEA,IACnD,MAAOwW,EAAOgO,GAAUmI,GAAkBroB,EAAK7O,MAAOqc,GACtD,OACIpd,EAAAC,cAACyuB,GAAS,CACNnpB,KAAK,QACL+F,KAAMA,EACNvK,MAAO+gB,EACPxc,YAAaA,EAAW,aACZA,EACZ8X,SAAW4T,GAAUlB,EAAOkB,EAAMzK,OAAOxlB,QAGrD,CAEA,SAASs3B,IAAgBzoB,KAAEA,EAAI0oB,OAAEA,EAAMlb,SAAEA,EAAQ9X,YAAEA,IAC/C,MAAMizB,EAAStuB,MAAMC,QAAQ0F,EAAK7O,OAAS6O,EAAK7O,MAAM6J,KAAK,MAASgF,EAAK7O,OAAS,IAC3E+gB,EAAOgO,GAAUmI,GAAkBM,EAASp5B,GAC/Cie,EACInQ,OAAO9N,GACFiV,MAAM,KACN3Q,IAAKoN,GAAMA,EAAEyD,QACb5J,OAAQmG,GAAY,KAANA,KAG3B,GAAoB,iBAAhBynB,EAAOhtB,KAAyB,CAChC,MAAM1H,EAAUsJ,EAAoBorB,GAC9BjG,EAAqBpoB,MAAMC,QAAQ0F,EAAK7O,OAAS6O,EAAK7O,MAAM0C,IAAIwJ,QAAU,GAChF,OACIjN,gBAAC2uB,GAAM,CACH6J,UAAQ,EACRjzB,KAAK,QACLxE,MAAOsxB,eACK/sB,EACZ8X,SAAW4T,IACP,MAAMxc,EAASvK,MAAM6O,KAAKkY,EAAMzK,OAAOkS,iBAAiBh1B,IAAKmJ,IACzD,MAAMc,EAAQ9J,EAAQ+J,KAAM0lB,GAAMpmB,OAAOJ,EAAeyrB,EAAQjF,MAAQzmB,EAAO7L,OAC/E,YAAiBwM,IAAVG,EAAsBb,EAAeyrB,EAAQ5qB,GAASd,EAAO7L,QAExEqc,EAAS5I,KAGZ5Q,EAAQH,IAAKmJ,IACV,MAAM7L,EAAQ8L,EAAeyrB,EAAQ1rB,GACrC,OACI5M,EAAAC,cAAA,SAAA,CAAQa,IAAKmM,OAAOlM,GAAQA,MAAOkM,OAAOlM,IACrCgM,EAAeurB,EAAQ1rB,MAMhD,CACA,OACI5M,EAAAC,cAACyuB,GAAS,CACNnpB,KAAK,QACLxE,MAAO+gB,EACPxc,YAAY,yBAAwB,aACxBA,EACZ8X,SAAW4T,GAAUlB,EAAOkB,EAAMzK,OAAOxlB,QAGrD,CAEA,SAAS23B,GAAiBj2B,GACtB,MAAMmN,KAAEA,EAAI0oB,OAAEA,EAAMK,SAAEA,EAAQvb,SAAEA,EAAQ9X,YAAEA,GAAgB7C,GACpD4K,IAAEA,GAAQqP,KACV5M,EAAY6oB,GAAU7oB,WAAa,OAEzC,GAAI6oB,GAAUC,eAAgB,CAC1B,MAAMC,EAAYF,EAASC,eAC3B,OAAO54B,EAAAC,cAAC44B,EAAS,CAACjpB,KAAMA,EAAM0oB,OAAQA,EAAQQ,WAAajb,GAAST,EAASS,EAAK9c,OAAQsM,IAAKA,GACnG,CAEA,OAAQyC,GACJ,IAAK,OACD,OAAO9P,4BACX,IAAK,UACD,OACIA,EAAAC,cAAC0uB,GAAM,CACHppB,KAAK,QACLxE,WAAsBwM,IAAfqC,EAAK7O,OAAsC,OAAf6O,EAAK7O,MAAiB,GAAKkM,OAAO2C,EAAK7O,OAAM,aACpEuE,EACZ8X,SAAW4T,GAAU5T,EAAgC,KAAvB4T,EAAMzK,OAAOxlB,WAAewM,EAAYyjB,EAAMzK,OAAOxlB,QAEnFf,EAAAC,cAAA,SAAA,CAAQc,MAAM,IAAE,OAChBf,EAAAC,cAAA,SAAA,CAAQc,MAAM,QAAM,OACpBf,EAAAC,cAAA,SAAA,CAAQc,MAAM,SAAO,OAGjC,IAAK,SAAU,CACX,MAAM6C,EAAUsJ,EAAoBorB,GACpC,OACIt4B,EAAAC,cAAC0uB,IACGppB,KAAK,QACLxE,WAAsBwM,IAAfqC,EAAK7O,OAAsC,OAAf6O,EAAK7O,MAAiB,GAAKkM,OAAO2C,EAAK7O,OAAM,aACpEuE,EACZ8X,SAAW4T,IACP,MAAMtjB,EAAQ9J,EAAQ+J,KAAM0lB,GAAMpmB,OAAOJ,EAAeyrB,EAAQjF,MAAQrC,EAAMzK,OAAOxlB,OACrFqc,EAC2B,KAAvB4T,EAAMzK,OAAOxlB,WACPwM,OACUA,IAAVG,EACEb,EAAeyrB,EAAQ5qB,GACvBsjB,EAAMzK,OAAOxlB,SAI7Bf,EAAAC,cAAA,SAAA,CAAQc,MAAM,KACb6C,EAAQH,IAAKmJ,IACV,MAAM7L,EAAQ8L,EAAeyrB,EAAQ1rB,GACrC,OACI5M,EAAAC,cAAA,SAAA,CAAQa,IAAKmM,OAAOlM,GAAQA,MAAOkM,OAAOlM,IACrCgM,EAAeurB,EAAQ1rB,MAMhD,CACA,IAAK,cACD,OAAO5M,EAAAC,cAACo4B,GAAe,IAAK51B,IAChC,IAAK,SACD,OAAOzC,EAAAC,cAACm4B,GAAc,IAAK31B,EAAO6I,KAAK,WAC3C,IAAK,OACD,OAAOtL,EAAAC,cAACm4B,GAAc,IAAK31B,EAAO6I,KAAK,SAC3C,IAAK,iBACD,OAAOtL,EAAAC,cAACm4B,GAAc,IAAK31B,EAAO6I,KAAK,mBAC3C,QACI,OAAOtL,EAAAC,cAACm4B,GAAc,IAAK31B,EAAO6I,KAAK,SAEnD,CAEA,MAAMytB,GAAoBT,IAAiC,CACvDntB,GAAIN,EAAS,UACbhB,MAAOyuB,GAAQzuB,OAAS,GACxB8uB,SAAUL,EAAUhnB,GAAyBgnB,GAAQ,IAAIv3B,OAAS,WAAc,WAChFA,WAAOwM,aAGKyrB,KACZ,MAAM3rB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,EAAUzU,QAAEA,EAAO0V,UAAEA,GAAclX,KACjDuc,EAAoBj5B,EAAMu3B,QAAQ,IAAMrZ,EAAQxT,OAAQoC,IAA2B,IAAnBA,EAAImF,YAAuB,CAACiM,IAC5FK,EAAUve,EAAMu3B,QAAQ,KAC1B,MAAM9zB,EAAM,IAAI+a,IAEhB,OADAya,EAAkBztB,QAASsB,GAAQrJ,EAAI4M,IAAIvD,EAAIjD,MAAOiD,IAC/CrJ,GACR,CAACw1B,IAEErO,EAAQloB,EAAMw2B,YAAYtO,MAC1BuO,EAAgBz2B,EAAMw2B,YAAYC,eAAiB,MACnDC,EAAc12B,EAAMmwB,gBAAgBuG,YAGpCC,EAASr5B,EAAM+c,QAAO,GAC5B/c,EAAMgc,UAAU,KACZ,IAAIqd,EAAOrc,QAEX,GADAqc,EAAOrc,SAAU,EACboc,GAAe7a,EAAQzU,IAAIsvB,GAAc,CACxBxO,EAAMjd,KAAMiC,GAASA,EAAK/F,QAAUuvB,IACtC/rB,EAAIisB,iBAAiBP,GAAiBxa,EAAQI,IAAIya,IACrE,MAA4B,IAAjBxO,EAAMzgB,QAAgB8uB,EAAkB9uB,OAAS,GACxDkD,EAAIisB,iBAAiBP,GAAiBE,EAAkB,MAE7D,CAAC5rB,EAAKkR,EAAS0a,EAAmBrO,EAAOwO,IAE5C,MAAMG,EAAaA,CAAC3pB,EAAyB4pB,KACzCnsB,EAAIisB,iBAAiB,IAAK1pB,KAAS4pB,KAOjCC,GAAc7F,EAAU8F,iCAAoD,IAAjB9O,EAAMzgB,OAEvE,OACInK,EAAAC,cAAA,MAAA,CAAKipB,UAAU,iBAAiBiG,KAAK,QAAO,aAAawD,EAAWhd,gBAChE3V,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBAAyBlnB,MAAO,CAAE23B,WAAY,KACvC,IAAjB/O,EAAMzgB,QAAgBnK,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBAAuB,cAC5D0B,EAAMnnB,IAAI,CAACmM,EAAMmT,KACd,MAAMuV,EAAS/Z,EAAQI,IAAI/O,EAAK/F,QAAUovB,EAAkB,GACtDW,EAAYtB,EAAShnB,GAAyBgnB,GAAU,GACxDK,EAAWiB,EAAUjsB,KAAMksB,GAAOA,EAAG94B,QAAU6O,EAAK+oB,WAAaiB,EAAU,GAC3EE,EAAYlP,EAAMzgB,OAAS,EACjC,OACInK,uBACIc,IAAKmM,OAAO2C,EAAKzE,IAAM4X,GACvBmG,UACI4Q,EAAY,sDAAwD,uBAGxE95B,EAAAC,cAACwuB,IACGlpB,KAAK,QACLyH,MAAO2lB,EAAW/b,sBAClB+a,QAASA,IAAMtkB,EAAI0sB,iBAAiBnqB,IAEpC5P,EAAAC,cAACwtB,UAEJqM,GACG95B,EAAAC,cAAC2uB,GAAK,CAAC5hB,MAAiB,IAAV+V,EAAc4P,EAAW1b,yBAA2B,KACnD,IAAV8L,EACG/iB,EAAAC,cAAA,MAAA,CAAK+B,MAAO,CAAEnC,OAAQ,MAEtBG,EAAAC,cAAC0uB,GAAM,CACHppB,KAAK,QACLxE,MAAOo4B,EACP7G,SAAUvP,EAAQ,EAAC,aACP4P,EAAW1b,yBACvBmG,SAAW4T,GACP3jB,EAAI2sB,uBAAuBhJ,EAAMzK,OAAOxlB,QAG5Cf,EAAAC,cAAA,SAAA,CAAQc,MAAM,OAAO4xB,EAAWzb,wBAChClX,EAAAC,cAAA,SAAA,CAAQc,MAAM,MAAM4xB,EAAWxb,yBAK/CnX,EAAAC,cAAC2uB,GAAK,CAAC5hB,MAAO2lB,EAAW9b,oBACrB7W,EAAAC,cAAC0uB,IACGppB,KAAK,QACLxE,MAAOu3B,GAAQzuB,OAAS,GAAE,aACd8oB,EAAW9b,mBACvBuG,SAAW4T,IACP,MAAMiJ,EAAa1b,EAAQI,IAAIqS,EAAMzK,OAAOxlB,OACtCm5B,EAAgBD,EAAa3oB,GAAyB2oB,GAAc,GACpEE,EAAeD,EAAchJ,KAAM2I,GAAOA,EAAG94B,QAAU6O,EAAK+oB,UAClEY,EAAW3pB,EAAM,CACb/F,MAAOmnB,EAAMzK,OAAOxlB,MACpB43B,SAAUwB,EAAevqB,EAAK+oB,SAAYuB,EAAc,IAAIn5B,OAAS,WACrEA,WAAOwM,MAId0rB,EAAkBx1B,IAAKqJ,GACpB9M,EAAAC,cAAA,SAAA,CAAQa,IAAKgM,EAAIjD,MAAO9I,MAAO+L,EAAIjD,OAC9BiD,EAAI+E,YAAc/E,EAAIjD,UAKvC7J,EAAAC,cAAC2uB,GAAK,CAAC5hB,MAAO2lB,EAAW7b,qBACrB9W,EAAAC,cAAC0uB,IACGppB,KAAK,QACLxE,MAAO43B,GAAU53B,OAAS,GAAE,aAChB4xB,EAAW7b,oBACvBsG,SAAW4T,IACP,MAAMoJ,EAAeR,EAAUjsB,KAAMksB,GAAOA,EAAG94B,QAAUiwB,EAAMzK,OAAOxlB,OAChEs5B,EAA0C,gBAA5BD,GAActqB,UAC5BwqB,EAAyC,gBAAxB3B,GAAU7oB,UACjCypB,EAAW3pB,EAAM,CACb+oB,SAAU3H,EAAMzK,OAAOxlB,MACvBA,MAAOs5B,IAAgBC,OAAiB/sB,EAAYqC,EAAK7O,UAIhE64B,EAAUn2B,IAAKo2B,GACZ75B,EAAAC,cAAA,SAAA,CAAQa,IAAK+4B,EAAG94B,MAAOA,MAAO84B,EAAG94B,OAC5B84B,EAAG7sB,OAAS6sB,EAAG94B,UAKhCf,EAAAC,cAAC2uB,GAAK,CAAC5hB,MAAO2lB,EAAW5b,kBACpBuhB,EACGt4B,EAAAC,cAACy4B,GAAgB,CACb9oB,KAAMA,EACN0oB,OAAQA,EACRK,SAAUA,EACVrzB,YAAaqtB,EAAW3b,4BACxBoG,SAAWrc,GAAUw4B,EAAW3pB,EAAM,CAAE7O,YAG5Cf,EAAAC,cAAA,MAAA,WAOxBD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBACXlpB,EAAAC,cAACsuB,GAAM,CACHxrB,QAAQ,UACRwC,KAAK,QACLiD,UAAWxI,EAAAC,cAACytB,GAAO,CAACnoB,KAAM,KAC1BosB,QApHA4I,KACZltB,EAAIisB,iBAAiBP,GAAiBE,EAAkB,MAoH5C3G,UAAWmH,GAEV9G,EAAWjc,sBAEhB1W,EAAAC,cAACsuB,GAAM,CACHhpB,KAAK,QACLiD,UAAWxI,EAAAC,cAACwtB,GAAU,CAACloB,KAAM,KAC7B+sB,SAA2B,IAAjB1H,EAAMzgB,OAChBwnB,QAASA,IAAMtkB,EAAImtB,eAAe,IAAK93B,EAAMw2B,YAAatO,MAAO,MAEhE+H,EAAWhc,uBAKhC,CCtTM,SAAU8jB,IAAkBnC,OAAEA,EAAMjJ,SAAEA,EAAQ1G,KAAEA,EAAI2G,QAAEA,EAAOjwB,UAAEA,EAASq7B,cAAEA,IAC5E,MAAMrtB,IAAEA,EAAG3K,MAAEA,EAAKiwB,WAAEA,EAAUiB,UAAEA,GAAclX,KACxC7S,EAAQyuB,EAAOzuB,MACf8wB,EAAmB9wB,IAAUb,EAC7B4xB,EAAWl4B,EAAMm4B,UAAUltB,KAAMiC,GAASA,EAAK/F,QAAUA,GACzDixB,EAASztB,EAAI0tB,eAAelxB,GAC5BmxB,GAAsD,IAA1Ct4B,EAAMu4B,iBAAiBhrB,QAAQpG,GAC3CqxB,EAAcx4B,EAAMupB,iBAAiBpiB,GAErCsxB,GAA8B,IAApB7C,EAAOtmB,WAAuB4hB,EAAUwH,qBAClDC,GAAkC,IAAtB/C,EAAOrmB,aAAyB2hB,EAAUkC,sBAAwB6E,EAC9EW,GAA8B,IAApBhD,EAAOpmB,SACjBqpB,GAA6B,IAApBjD,EAAOlmB,WAAuBwhB,EAAU4H,qBACjDC,GAAgC,IAArBnD,EAAOjmB,YAAwBuhB,EAAU8H,qBAAuBf,EAC3EgB,EAAuBxoB,OAAOC,KAAKwgB,EAAU+H,sBAAsBjxB,OAAQoN,IAC7E,MAAMuU,EAAKuH,EAAU+H,qBAAqB7jB,GAC1C,QAAIwgB,EAAOsD,gCAAwF,IAAvDtD,EAAOsD,8BAA8B3rB,QAAQ6H,OACrFuU,EAAG1X,cAAe2jB,EAAOhtB,OAAgD,IAAxC+gB,EAAG1X,YAAY1E,QAAQqoB,EAAOhtB,SAGjEuwB,GACoB,IAAtBvD,EAAOhmB,aAAyBshB,EAAUkI,qBAAuBnB,GAAoBgB,EAAqBxxB,OAAS,EAEjH4xB,EAAiBrB,GAAiBrL,EAClCvX,EAAOwgB,EAAOzmB,YAAcymB,EAAOzuB,MAEzC,OACI7J,EAAAC,cAACmvB,GAAO,CAACzG,KAAMA,EAAM0G,SAAUA,EAAUC,QAASA,EAASjwB,UAAWA,EAAWkwB,UAAU,aAAaJ,KAAK,QACzGnvB,EAAAC,cAAC8xB,GAAI,CAAA,aAAaY,EAAWxY,iBACxBghB,GACGn7B,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAAC8sB,GAAe,MACtBsF,SAA6B,QAAnBuI,GAAUvlB,KACpBsc,QAASA,IAAMtkB,EAAI2uB,WAAWnyB,EAAO,OACrC0oB,SAAUjD,GAETqD,EAAWvb,mBAEhBpX,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAAC+sB,GAAiB,MACxBqF,SAA6B,SAAnBuI,GAAUvlB,KACpBsc,QAASA,IAAMtkB,EAAI2uB,WAAWnyB,EAAO,QACrC0oB,SAAUjD,GAETqD,EAAWtb,oBAEfujB,GACG56B,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAAA,OAAA,CAAM+B,MAAO,CAAEzB,MAAO,MAC5BoxB,QAASA,IAAMtkB,EAAI2uB,WAAWnyB,EAAO,MACrC0oB,SAAUjD,GAETqD,EAAWrb,mBAK3B+jB,GACGr7B,EAAAC,cAAAD,EAAAsuB,SAAA,KACK6M,GAAWn7B,EAAAC,cAACuyB,GAAW,MACxBxyB,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAAC0sB,GAAc,MACrBgF,QAASA,IAAMtkB,EAAI4uB,gBAAgBpyB,EAAOkyB,GAC1CxJ,SAAUjD,GAETqD,EAAWpb,oBAItB+jB,IAAY1H,EAAUgC,wBACpB51B,EAAAC,cAAAD,EAAAsuB,SAAA,MACM6M,GAAWE,IAAcr7B,EAAAC,cAACuyB,GAAW,MACtC8I,GACGt7B,EAAAC,cAACmyB,IACG/rB,KAAMrG,EAAAC,cAACiuB,GAAiB,MACxByD,QAASA,IAAMtkB,EAAI2qB,oBAAoBnuB,GAAO,GAC9C0oB,SAAUjD,GAETqD,EAAWnb,uBAGlBoc,EAAUgC,uBACR51B,gBAACoyB,GAAQ,CACL/rB,KAAMrG,gBAAC0sB,GAAc,MACrBiF,QAASA,IAAMtkB,EAAI2lB,gBAAgB,UAAW+I,GAC9CxJ,SAAUjD,GAETqD,EAAWlb,0BAK3B8jB,GACGv7B,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACuyB,GAAW,MACA,SAAXsI,GACG96B,EAAAC,cAACmyB,IACG/rB,KAAMrG,gBAACwtB,GAAW,CAACxrB,MAAO,CAAEk6B,UAAW,mBACvCvK,QAASA,IAAMtkB,EAAI8uB,UAAUtyB,EAAO,QACpC0oB,SAAUjD,GAETqD,EAAWjb,mBAGR,UAAXojB,GACG96B,EAAAC,cAACmyB,IACG/rB,KAAMrG,gBAACwtB,GAAW,CAACxrB,MAAO,CAAEk6B,UAAW,oBACvCvK,QAASA,IAAMtkB,EAAI8uB,UAAUtyB,EAAO,SACpC0oB,SAAUjD,GAETqD,EAAWhb,oBAGnBmjB,GACG96B,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAAA,OAAA,CAAM+B,MAAO,CAAEzB,MAAO,MAC5BoxB,QAASA,IAAMtkB,EAAI+uB,YAAYvyB,GAC/B0oB,SAAUjD,GAETqD,EAAW/a,kBAK3B6jB,GACGz7B,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACuyB,GAAW,MACZxyB,EAAAC,cAACmyB,GAAQ,CACL/rB,KAAMrG,EAAAC,cAACmuB,GAAc,MACrBuD,QAASA,IACLqJ,EAAY3tB,EAAIgvB,0BAA0BxyB,GAASwD,EAAIivB,uBAAuBzyB,GAElF0oB,SAAUjD,GAET0L,EAAYrI,EAAW5a,kBAAkBD,GAAQ6a,EAAW9a,gBAAgBC,KAIxF+jB,GACG77B,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACuyB,GAAW,MACZxyB,EAAAC,cAACwyB,GAAW,KACRzyB,EAAAC,cAAA,QAAA,CACIipB,UAAU,uBACVlnB,MAAO,CAAEtC,QAAS,OAAQC,WAAY,SAAU48B,IAAK,IAErDv8B,EAAAC,cAACkuB,GAAa,CAAC5oB,KAAM,SAAQotB,EAAW3a,uBAE5ChY,EAAAC,cAAC0uB,IACGppB,KAAK,QACLxE,MAAOm6B,GAAe,GAAE,aACZvI,EAAW3a,sBACvBoF,SAAW4T,IACP,MAAMnT,EAAO,IAAKnb,EAAMupB,kBACG,KAAvB+E,EAAMzK,OAAOxlB,aAAqB8c,EAAKhU,GACtCgU,EAAKhU,GAASmnB,EAAMzK,OAAOxlB,MAChCsM,EAAImvB,oBAAoB3e,KAG5B7d,EAAAC,cAAA,SAAA,CAAQc,MAAM,IAAI4xB,EAAWza,8BAC5ByjB,EAAqBl4B,IAAK2oB,GACvBpsB,EAAAC,cAAA,SAAA,CAAQa,IAAKsrB,EAAQrrB,MAAOqrB,GACvBwH,EAAU+H,qBAAqBvP,GAAQpf,OAASof,QAUzF,CCjMM,SAAUqQ,IAAqBt9B,KAAEA,EAAO,UAASu9B,SAAEA,IACrD,OACI18B,uBAAKkpB,UAAU,mBAAmBiG,KAAK,UAClCuN,EAAW18B,EAAAC,cAAA,MAAA,CAAKG,IAAI,GAAGC,IAAKq8B,IAAe18B,EAAAC,cAACouB,GAAY,CAAC9oB,KAAM,KAChEvF,EAAAC,cAAA,MAAA,KAAMd,GAGlB,CAEM,SAAUw9B,IAAsBx9B,KAAEA,IACpC,OACIa,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACivB,GAAO,MACP/vB,GAAQa,EAAAC,cAAA,MAAA,KAAMd,GAG3B,UCPgBy9B,IAAuBv2B,KACnCA,EAAI2G,MACJA,EAAK2kB,QACLA,EAAOkL,WACPA,EAAUvK,SACVA,EAAQpJ,UACRA,KACGqD,IAEH,OACIvsB,EAAAC,cAACwuB,GAAU,CACPlpB,KAAK,QACLyH,MAAOA,EACPslB,SAAUA,EACVpJ,UAAWA,EACXyI,QAAUX,IACNA,EAAMO,kBACNI,IAAUX,OAEVzE,GAEHlmB,EAGb,CASM,SAAUy2B,IAAYC,QAAEA,EAAO19B,UAAEA,EAAS29B,UAAEA,IAC9C,MAAO/hB,EAAQmY,GAAapzB,EAAMwd,SAA6B,MACzDyf,EAA+B,GAC/BC,EAA+B,GAOrC,OANAH,EAAQvxB,QAAS2xB,IACRn9B,EAAMg0B,eAAemJ,KACrBA,EAAO16B,OAAuCo6B,WAAYK,EAAOjpB,KAAKkpB,GACtEF,EAAOhpB,KAAKkpB,MAIjBn9B,EAAAC,cAAAD,EAAAsuB,SAAA,KACK2O,EAAOx5B,IAAI,CAAC05B,EAAQpa,IACjB/iB,EAAAC,cAACD,EAAMsuB,SAAQ,CAACxtB,IAAKq8B,EAAOr8B,KAAOiiB,GAAQoa,IAE9CD,EAAO/yB,OAAS,GACbnK,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAACwuB,IACGlpB,KAAK,QACLyH,MAAOgwB,EACPxO,OAAQ7jB,QAAQsQ,GAChB0W,QAAUX,IACNA,EAAMO,kBACN6B,EAAW3C,GAAUA,EAAO,KAAOO,EAAMiC,iBAG7CjzB,EAAAC,cAACgtB,UAELjtB,EAAAC,cAACmvB,GAAO,CACJzG,KAAMhe,QAAQsQ,GACdoU,SAAUpU,EACVqU,QAASA,IAAM8D,EAAU,MACzB/zB,UAAWA,EACXkwB,UAAU,aACVJ,KAAK,QAELnvB,EAAAC,cAAC8xB,GAAI,KACAmL,EAAOz5B,IAAI,CAAC05B,EAAQpa,KACjB,MAAMtgB,EAAQ06B,EAAO16B,MACrB,OACIzC,EAAAC,cAACmyB,GAAQ,CACLtxB,IAAKq8B,EAAOr8B,KAAOiiB,EACnB1c,KAAM5D,EAAM4D,KACZisB,SAAU7vB,EAAM6vB,SAChBX,QAAUX,IACNvuB,EAAMkvB,UAAUX,GAChBoC,EAAU,QAGb3wB,EAAMuK,YAU/C,CAnEA4vB,GAAuBngB,YAAc,yBCsErC,MAAM2gB,GAAqB,GACrBC,GAAoC,CAAA,EACpCC,GAAY,IAAI9e,IAChB+e,GAAgD,CAAC,MAAO,OAAQ,MAChEC,GAA4B,CAAC,GAAI,GAAI,GAAI,KACzCC,GAA2C,CAAE7S,MAAO,GAAI8S,iCAAiC,GAkCzFC,GAAiB37B,IACnB,IAAKA,EAAO,OACZ,MAAM6R,EAA2B,CAAA,EAOjC,OANAV,OAAOC,KAAKpR,GAAOwJ,QAAS1K,IACxB,GAAIiS,GAAcjS,GAAM,OACxB,MAAMC,EAASiB,EAAclB,GACR,iBAAVC,GAAuC,iBAAVA,IACxC8S,EAAI/S,GAAOC,KAER8S,GAyEL+pB,GAAmBA,CAAC78B,EAAYsL,KAClC,MAAMC,EAAOZ,EAAO3K,GACpB,IAAKuL,EAAM,MAAO,GAClB,MAAMuxB,EAAOptB,GAAcxD,OAAOwD,GAAGqtB,SAAS,EAAG,KAC3Cze,EAAO,GAAG/S,EAAKqX,iBAAiBka,EAAIvxB,EAAKsX,WAAa,MAAMia,EAAIvxB,EAAKuX,aAC3E,OAAOxX,EAAW,GAAGgT,KAAQwe,EAAIvxB,EAAKwX,eAAe+Z,EAAIvxB,EAAKyX,gBAAkB1E,GAOtE,SAAU0e,GAA8Ct7B,GAClE,MAAMsc,KACFA,EACAb,QAAS8f,EAAW9yB,SACpBA,EAAQ+yB,QACRA,GAAU,EAAK9J,OACfA,EAAM+J,uBACNA,EAAsBC,0BACtBA,EAAyBC,YACzBA,GAAc,EAAKlV,UACnBA,EAASmV,cACTA,EAAaC,aACbA,EAAYC,UACZA,EAASC,OACTA,EAAMC,SACNA,EAAQC,MACRA,EAAK18B,MACLA,EAAK1B,GACLA,EAAEjB,UACFA,EAAY,QAAOs/B,UACnBA,EAASC,YACTA,GAAc,EAAIC,aAClBA,EAAYC,MACZA,EAAQzB,GAAY73B,UACpBA,EAAY63B,GAAY0B,WACxBA,EAAa,4CACbpM,WAAYqM,EACZC,UAAWC,EAAgBx1B,EAAkBy1B,mBAC7CA,EAAqBx1B,EAAqBy1B,aAC1CA,EAAYC,WACZA,GAAa,EAAKC,sBAClBA,GAAwB,EACxBhM,QAASiM,EAAWC,gBACpBA,EAAexJ,uBACfA,IAAyB,EAAKgB,WAC9BA,IAAa,EAAIb,SACjBA,GAAW,GAAEI,gBACbA,GAAkBiH,GAClBpH,gBAAiBqJ,GAAmBC,wBACpCA,GAAuBzZ,WACvBA,IAAa,EAAKgR,qBAClBA,IAAuB,EAAKE,mBAC5BA,IAAqB,EAAKL,2BAC1BA,IAA6B,EAC7B+D,UAAW8E,GAAaC,kBACxBA,GAAiBC,aACjBA,GAAetC,GAAqBuC,8BACpCA,IAAgC,EAAK1E,qBACrCA,IAAuB,EACvBlC,YAAa6G,GAAeC,oBAC5BA,GAAmBlK,oBACnBA,IAAsB,EAAK4D,gCAC3BA,IAAkC,EAAK3E,sBACvCA,GAAwB,IACxB4C,sBAAuBsI,GAAyBC,8BAChDA,GAA6BC,2BAC7BA,GAA0BC,sBAC1BA,GAAqBC,sBACrBA,GAAqBC,wBACrBA,GAAuBC,oBACvBA,GAAmBC,oBACnBA,GAAmBhuB,kBACnBA,IAAoB,EAAKojB,sBACzBA,IAAwB,EAAK6K,oBAC7BA,IAAsB,EAAKC,qBAC3BA,IAAuB,EAAKlF,qBAC5BA,IAAuB,EACvBmF,cAAeC,GAAiBC,sBAChCA,GAAqBC,kBACrBA,IAAoB,EAAKC,6BACzBA,IAA+B,EAAKC,2BACpCA,IAA6B,EAAIC,4BACjCA,IAA8B,EAC9BrK,kBAAmBsK,GAAqBC,0BACxCA,GAAyBC,gBACzBA,GAAeC,4BACfA,IAA8B,EAAIC,gBAClCA,GAAeC,WACfA,GAAUC,iBACVA,GAAgBC,YAChBA,GAAWC,kBACXA,GAAiBC,WACjBA,GAAUC,sBACVA,GAAqBC,qBACrBA,GACAC,0BAA2BC,GAA6BC,kCACxDA,GACA/G,iBAAkBgH,GAAoBC,yBACtCA,GAAwBC,8BACxBA,GAAgC,EAACC,eACjCA,GAAc1G,mBACdA,IAAqB,EAAK2G,yBAC1BA,GACApW,iBAAkBqW,GAAoBC,yBACtCA,GACA5G,qBAAsB6G,GAAwB1G,mBAC9CA,IAAqB,EAAK2G,oBAC1BA,GAAsB,OAAMC,iBAC5BA,GAAgBC,wBAChBA,GAAuBC,eACvBA,GAAcC,eACdA,GAAcC,aACdA,GAAYC,OACZA,GAAMC,cACNA,IACAvgC,EAEJwZ,KAEA,MAAMgnB,GbnOJ,SAAsBl4B,GACxB,MAAMm4B,EAAcljC,EAAcmjC,MAClC,GAAID,EAGA,MAAO,GAAGn4B,KADCm4B,IACY3vB,QAAQ,KAAM,MAGzC,MAAMpO,EAAMnF,EAAM+c,OAAsB,MAKxC,OAJoB,OAAhB5X,EAAI6X,UACJgB,IAAa,EACb7Y,EAAI6X,QAAU,GAAGjS,KAAUiT,MAExB7Y,EAAI6X,OACf,CaqNmBomB,CAAY,YACrBC,GAAUrjC,EAAM+c,OAA8B,MAC9CumB,GAAUtjC,EAAM+c,OAA8B,MAC9CwmB,GAAcvjC,EAAM+c,OAA8B,MAClDymB,GAAaxjC,EAAM+c,OAA8B,MACjD0mB,cb9ON,MAAM,CAAGC,GAAW1jC,EAAMwd,SAAS,GACnC,OAAOxd,EAAM4d,YAAY,IAAM8lB,EAAS/c,GAAMA,EAAI,GAAI,GAC1D,Ca4OwBgd,GAEdhR,GAAa3yB,EAAMu3B,QACrB,KAAA,IAAYhiB,MAAwBypB,IACpC,CAACA,IAKC4E,GAAS5jC,EAAM+c,OAAY,IAC3B8mB,GAAa7jC,EAAM4d,YAAY,KAAA,CAAiCvQ,IAAKu2B,GAAO5mB,QAAQ3P,MAAQ,IAE5Fy2B,GAAY9jC,EAAMu3B,QAAuB,KAC3C,MAAMwM,EAAIA,IAAMH,GAAO5mB,QACjBgnB,EAAyB,CAC3BhlB,OAAS7T,GAAO44B,IAAIE,SAAStlB,IAAIxT,IAAO,KACxC+4B,aAAcA,IAAM,IAAI1lB,IAAIulB,IAAIE,UAChCE,aAAcA,IAAMJ,IAAIK,WAAW3gC,IAAK4gC,GAAmBA,EAAEl5B,IAC7Dm5B,WAAan5B,GAAO44B,IAAIQ,UAAU5lB,IAAIxT,IAAO,KAC7Cq5B,cAAeA,IAAMT,IAAIU,aAAahhC,IAAK4gC,GAAmBA,EAAEp5B,KAChE6T,gBAAiBA,IAAMilB,IAAIU,aAAahhC,IAAK4gC,GAAmBA,EAAEl5B,IAClEu5B,eAAgBA,IACZX,IACKY,UAAUj6B,OAAQk6B,GAAkC,SAAZA,EAAGt5B,MAAmBs5B,EAAG35B,KACjExH,IAAKmhC,IAAiB,CAAQz5B,GAAIy5B,EAAGz5B,GAAIusB,MAAOkN,EAAG35B,OAC5D45B,iCAAmC15B,GAAO44B,IAAIY,UAAUG,UAAWF,GAAsBA,EAAGz5B,KAAOA,GACnG45B,WAAaC,IACTA,EAAQx5B,QAASskB,IACb,MAAM3kB,EAAKH,EAAgB8kB,EAAaiU,IAAI74B,UACtC+5B,EAAWlB,IAAIE,SAAStlB,IAAIxT,GAC9B85B,GAAUlB,IAAImB,eAAe/5B,EAAI,IAAK85B,KAAanV,OAI/DzR,cAAeA,IAAM0lB,IAAIoB,mBACzBvmB,kBAAmBA,IAAMmlB,IAAIqB,mBAC7BC,UAAYx7B,GAAUk6B,IAAIsB,UAAUx7B,GACpCy7B,eAAgBA,CAACz7B,EAAO07B,GAAoB,KACvCA,EAAoBxB,IAAIqB,mBAAqBrB,IAAIoB,oBAAoBL,UACjErmB,GAAqBA,EAAE5U,QAAUA,GAE1C27B,yBAA0BA,IAAMzB,IAAIpM,sBACpCK,oBAAqBA,CAACnuB,EAAO47B,IACzB1B,IAAIhM,yBAAyB,IAAKgM,IAAIpM,sBAAuB9tB,CAACA,GAAQ47B,IAC1E1N,yBAA2BL,GAAUqM,IAAIhM,yBAAyBL,GAClEgO,eAAgBA,CAAC77B,EAAOtJ,IAAUwjC,IAAI2B,eAAe77B,EAAOtJ,GAC5DolC,eAAgBA,CAAC97B,EAAO+7B,IAAgB7B,IAAI4B,eAAe97B,EAAO+7B,GAClEC,gBAAkBjiC,GAAYmgC,IAAI8B,gBAAgBjiC,GAClDu4B,UAAWA,CAACtyB,EAAOi8B,IAAS/B,IAAI5H,UAAUtyB,EAAOi8B,GACjD1J,YAAcvyB,GAAUk6B,IAAI3H,YAAYvyB,GACxCkxB,eAAiBlxB,GAAUk6B,IAAIhJ,eAAelxB,GAC9Ck8B,iBAAkBA,IAAMhC,IAAIpD,cAC5BqF,iBAAmBtO,GAAUqM,IAAIiC,iBAAiBtO,GAElDuO,aAAcA,IAAMlC,IAAIlJ,UACxBqL,aAAexO,GAAUqM,IAAImC,aAAaxO,GAC1CsE,WAAYA,CAACnyB,EAAOs8B,EAAWC,IAAyBrC,IAAI/H,WAAWnyB,EAAOs8B,EAAWC,GAEzFC,eAAgBA,IAAMtC,IAAI7K,YAC1BsB,eAAiB9C,GAAUqM,IAAIvJ,eAAe9C,GAC9C4B,iBAAmB1pB,GAASm0B,IAAIuC,kBAAkB,CAAC12B,IACnD02B,kBAAoB1b,GAAUmZ,IAAIuC,kBAAkB1b,GACpDmP,iBAAmBnqB,GAASm0B,IAAIhK,iBAAiBnqB,GACjDoqB,uBAAyBrB,GAAaoL,IAAIvJ,eAAe,IAAKuJ,IAAI7K,YAAaC,cAAeR,IAC9FzD,qBAAuB1gB,GAAWuvB,IAAIvJ,eAAe,IAAKuJ,IAAI7K,YAAavE,kBAAmBngB,IAC9FynB,gBAAiBA,CAACsK,EAAmBlX,IAAa0U,IAAI/Q,gBAAgB,UAAW3D,EAAUkX,GAC3FC,gBAAiBA,IAAMzC,IAAIhR,kBAC3BC,gBAAiBA,CAACyT,EAAOpX,EAAU+J,IAAgB2K,IAAI/Q,gBAAgByT,EAAOpX,EAAU+J,GACxFrG,gBAAiBA,IAAMgR,IAAIhR,kBAE3B2T,gBAAiBA,KACb,MAAMjjC,EAAM,IAAI+a,IAKhB,OAJAulB,IAAI4C,YAAYn7B,QAASL,IACrB,MAAMF,EAAM84B,IAAIE,SAAStlB,IAAIxT,GACzBF,GAAKxH,EAAI4M,IAAIlF,EAAIF,KAElBxH,GAEXmjC,qBAAsBA,KAAAA,CAASt7B,KAAM,UAAWC,IAAKw4B,IAAI4C,cACzDE,qBAAuBnP,IACnB,MAAMoP,EAAa17B,EACfssB,EACAqM,IAAIK,WAAW3gC,IAAK4gC,GAAmBA,EAAEl5B,KAE7C44B,IAAIgD,eAAeD,EAAWv7B,MAElCy7B,UAAWA,CAAC77B,EAAI87B,GAAa,EAAMC,GAAiB,IAAUnD,IAAIoD,WAAW,CAACh8B,GAAK87B,EAAYC,GAC/FC,WAAYA,CAAC57B,EAAK07B,GAAa,EAAMC,GAAiB,IAAUnD,IAAIoD,WAAW57B,EAAK07B,EAAYC,GAChGE,cAAgBj8B,GAAO44B,IAAI4C,YAAY78B,IAAIqB,GAC3Ci2B,gBAAkBj2B,GAAO44B,IAAIsD,kBAAkBl8B,EAAI44B,IAAIE,SAAStlB,IAAIxT,IAEpEsrB,QAAU6Q,GAAavD,IAAIwD,mBAAmB,IAAKxD,IAAI3N,gBAAiBF,KAAM3rB,KAAKD,IAAI,EAAGg9B,KAC1F9Q,YAAcgR,GAAiBzD,IAAIwD,mBAAmB,CAAErR,KAAM,EAAGC,SAAU5rB,KAAKD,IAAI,EAAGk9B,KACvFD,mBAAqB7P,GAAUqM,IAAIwD,mBAAmB7P,GAEtDnE,WAAaxyB,GAAUgjC,IAAIxQ,WAAWxyB,GAEtC2e,aAAe9b,GAAY8b,GAAaskB,EAASpgC,GACjDwwB,gBAAkBxwB,GZpVCwwB,EAAC/mB,EAAiBzJ,EAAmC,MAChF,MAAM6jC,EAAM/nB,GAAarS,EAAKzJ,GACxB8jC,EAAM9jC,EAAQ+jC,YAAc1nB,GAAW,GACvCrF,EAAO,IAAIgtB,KAAK,CAACF,EAAMD,GAAM,CAAEn8B,KAAM,4BAC3CqP,GAAaC,EAAMsE,GAAiBtb,EAAQiX,SAAU0E,KAAmB,SYgVnC6U,CAAgB4P,EAASpgC,GACvDywB,kBAAoBzwB,GZJCwlB,OAAO/b,EAAiBzJ,EAAqC,MAC1F,MAAM+d,EAAQoD,GAAU1X,EAAKzJ,GACvBgX,EAAO,IAAIgtB,KAAK,CAACjmB,GAAoB,CACvCrW,KAAM,sEAEVqP,GAAaC,EAAMsE,GAAiBtb,EAAQiX,SAAU0E,KAAmB,UYDjC8U,CAAkB2P,EAASpgC,GAC3D0wB,kBAAoB1wB,GAAYmgC,IAAI8D,WAAWjkC,GAE/CkkC,kBAAoB38B,GAAO44B,IAAI+D,kBAAkB38B,GACjD48B,wBAA0Bx8B,GAAQw4B,IAAIgE,wBAAwB,IAAI1+B,IAAIkC,IACtEy8B,wBAAyBA,IAAM/9B,MAAM6O,KAAKirB,IAAIkE,sBAE9CC,oBAAqBA,IAAMnE,IAAI9I,iBAC/BkN,oBAAsBzQ,GAAUqM,IAAIoE,oBAAoBzQ,GACxD4E,uBAAwBA,CAACzyB,EAAOu+B,KAC5B,MAAMprB,EAAoB+mB,IAAI9I,iBAAiBvwB,OAAQgU,GAAcA,IAAM7U,QACrD0D,IAAlB66B,EAA6BprB,EAAQ/I,KAAKpK,GACzCmT,EAAQqrB,OAAOj+B,EAAMg+B,EAAe,EAAGprB,EAAQ7S,QAAS,EAAGN,GAChEk6B,IAAIoE,oBAAoBnrB,IAE5Bqf,0BAA4BxyB,GACxBk6B,IAAIoE,oBAAoBpE,IAAI9I,iBAAiBvwB,OAAQgU,GAAcA,IAAM7U,IAC7Ey+B,wBAAyBA,CAACn9B,EAAIiqB,IAAe2O,IAAIuE,wBAAwBn9B,EAAIiqB,GAC7EmT,oBAAqBA,EAAGC,cACpB,MAAMC,EAAQ1E,IAAI2E,WAAW/pB,IAAI6pB,GACjC,OAAOC,EAAQA,EAAM9c,YAAYloB,IAAKyI,GAAMA,EAAEf,IAAM,IAGxDw9B,oBAAqBA,IAAM5E,IAAI9X,iBAC/BuQ,oBAAsB9E,GAAUqM,IAAIvH,oBAAoB9E,GAExDkR,kBAAmBA,EAAGz9B,KAAItB,WAAYk6B,IAAI6E,kBAAkBz9B,EAAItB,GAChEg/B,iBAAkBA,EAAG19B,KAAItB,QAAOi/B,yBAC5B/E,IAAI8E,iBAAiB19B,EAAItB,EAAOi/B,EAAqB,OACzDC,YAAaA,CAAC59B,EAAItB,KACd,MAAMm/B,EAAUjF,IAAIkF,YACpB,OAAOD,GAAWA,EAAQ79B,KAAOA,GAAM69B,EAAQn/B,QAAUA,EAAQ,OAAS,QAE9Eq/B,iBAAkBA,EAAG/9B,KAAItB,QAAO9I,YAC5B,MAAMioC,EAAUjF,IAAIkF,YAChBD,GAAWA,EAAQ79B,KAAOA,GAAM69B,EAAQn/B,QAAUA,GAAOk6B,IAAIoF,aAAapoC,IAGlFqM,aAAcA,CAACjC,EAAItB,KACf,MAAMoB,EAAM84B,IAAIE,SAAStlB,IAAIxT,GACvB2B,EAAMi3B,IAAIsB,UAAUx7B,GAC1B,OAAOoB,GAAO6B,EAAMM,EAAanC,EAAK6B,EAAKk3B,QAAWz2B,GAE1D67B,cAAeA,CAACj+B,EAAItB,KAChB,MAAMoB,EAAM84B,IAAIE,SAAStlB,IAAIxT,GAC7B,OAAO44B,IAAIsF,gBACPl+B,EACAtB,EACAoB,EACA84B,IAAIQ,UAAU5lB,IAAIxT,IAAO,CAAEG,KAAM,OAAQH,KAAI0f,MAAO,EAAGQ,OAAQ,QAGvEie,aAAcA,CAACn+B,EAAItB,KACf0/B,GAAgBvsB,SAAU,EAC1B+mB,IAAIyF,eAAe,CAAEr+B,KAAItB,WAG7B4/B,gBAAkBhkB,GAAWse,IAAI0F,gBAAgBhkB,GACjDikB,OAAQA,EAAG9Z,OAAMD,UACb,MAAMga,EAAWpG,GAAYvmB,QACxB2sB,SACQp8B,IAATqiB,IAAoB+Z,EAASC,WAAaha,QAClCriB,IAARoiB,IAAmBga,EAASE,UAAYla,KAEhDma,kBAAmBA,KAAAA,CACfla,KAAM2T,GAAYvmB,SAAS4sB,YAAc,EACzCja,IAAK4T,GAAYvmB,SAAS6sB,WAAa,IAG3C,SAAInnC,GACA,OAAOqhC,IAAIrhC,KACf,EACA+gC,YAAaA,IAAMM,IAAIN,cACvBsG,eAAgB1G,IAEpB,OAAOW,GACR,IACEJ,GAAO5mB,QAAQ3P,MAAKu2B,GAAO5mB,QAAQ3P,IAAMy2B,IAI9C,MAAMkG,GAAYhqC,EAAMu3B,QACpB,KAAA,CACI7F,WAAYyO,GACNt/B,EAA+Cs/B,IAC/C,KACN8J,MAAO7J,GAAwBv/B,EAA2Bu/B,IAAyB,KACnFpb,OAAQqb,GAAwBx/B,EAAyCw/B,IAAyB,KAClGvF,OAAQwF,GAA0Bz/B,EAAuCy/B,IAA2B,OAExG,CAACH,GAA4BC,GAAuBC,GAAuBC,MAKxEzF,GAAWqL,IAAgBjpB,GAC9B0iB,GACAmD,IAAcoH,SAASrP,WAAauC,GACnC1F,GAAUkI,KAAoBlI,EAAOmM,QAGnC3K,GAAasB,IAAkBvd,GAClC8iB,GACA+C,IAAcp4B,QAAQwuB,aAAeuE,GACpC/F,GAAUsI,KAAsBtI,EAAOmM,QAGrCzN,GAAiBmR,IAAsBtqB,GAC1CwiB,GACA,CACIvJ,KAAM4M,IAAc9L,YAAYZ,iBAAiBF,MAAQ,EACzDC,SAAU2M,IAAc9L,YAAYZ,iBAAiBD,UAAYA,IAEpEuB,GAAUgI,KAA0BhI,EAAOmM,QAGzClM,GAAuBI,IAA4B9a,GACtDgjB,GACA+J,GAAUtY,YAAcoR,IAAc5kB,SAASyZ,uBAAyB0F,GACvE3F,IACOyI,IAA4Bh/B,EAAkBg/B,GAA4BzI,GAC9EwI,KAAgCxI,EAAOmM,SAIxCvQ,GAASC,IAActW,GAC1BsiB,EACAuD,IAAcxP,SAAW,UACxBvyB,GAAUy+B,IAAkBz+B,EAAO8iC,QAGjClD,GAAeqF,IAAoB/oB,GACtC2jB,GACAoJ,GAAUlP,QAAUgI,IAAcnC,eAAiBtD,GAClD3F,IACO4I,IAAyBn/B,EAAkBm/B,GAAyB5I,GACxEmJ,KAAwBnJ,EAAOmM,SAIhC5I,GAAkBkN,IAAuBlrB,GAC5CglB,GACAa,IAAcqH,aAAazS,OAAS0F,GACnC1F,GAAUwK,KAA2BxK,EAAOmM,QAG1C5X,GAAkBuQ,IAAuBvf,GAC5CqlB,GACAQ,IAAc5H,aAAaxD,OAAS2F,GACnC3F,GAAU6K,KAA2B7K,EAAOmM,OAG3CuG,GAA2BpqC,EAAMu3B,QACnC,IAAOwK,GAAgC,IAAI14B,IAAkB04B,SAAiCx0B,EAC9F,CAACw0B,MAEEkG,GAAsBF,IAA2B9qB,GACpDmtB,GACApqC,EAAMu3B,QAAQ,IAAM,IAAIluB,IAAkBy5B,IAAcuH,aAAaC,gBAAkB,IAAK,IAC3F/+B,GAAQy2B,KAAoC/3B,MAAM6O,KAAKvN,GAAMs4B,OAG5D0G,GAAsBvqC,EAAMu3B,QAC9B,SAAiChqB,IAA1B2zB,GAAsC91B,EAAwB81B,IAAuB31B,SAAMgC,EAClG,CAAC2zB,MAEEyF,GAAaI,IAAkB9pB,GAClCstB,GACAvqC,EAAMu3B,QAAQ,IAAM,IAAIluB,IAAqB,IAC5CkC,GAAQ41B,KAA4B,CAAE71B,KAAM,UAAWC,OAAOs4B,QAK5D2G,GAAeC,IAAoBzqC,EAAMwd,SAC5C,IAAMwsB,GAAUC,OAASnH,IAAc5kB,SAASssB,eAAiB,OAE9DnnB,GAAcqnB,IAAmB1qC,EAAMwd,SAAiC,KAC3E,GAAIwsB,GAAUhlB,OAAQ,OAAOglB,GAAUhlB,OACvC,MAAM2lB,EAAO7H,IAAc5kB,SAAS0sB,WACpC,IAAKD,EAAM,MAAO,CAAA,EAClB,MAAM92B,EAA8B,CAAA,EAIpC,OAHAV,OAAOC,KAAKu3B,GAAMn/B,QAAS3B,IACnB8gC,EAAK9gC,GAAOtJ,QAAOsT,EAAIhK,GAAS8gC,EAAK9gC,GAAOtJ,SAE7CsT,KAEJg3B,GAAgBC,IAAqB9qC,EAAMwd,SAAqC,IAAM,IAAIgB,MAC1FyqB,GAAa8B,IAAkB/qC,EAAMwd,SAA4B,OACjEwtB,GAAW7B,IAAgBnpC,EAAMwd,cAAcjQ,IAC/C09B,GAAazB,IAAkBxpC,EAAMwd,SAA4B,MAClE+rB,GAAkBvpC,EAAM+c,QAAO,IAC9B8V,GAAiBqY,IAAsBlrC,EAAMwd,SAElD,CACEmL,MAAM,EACN0G,SAAU,QAEP8b,GAAYC,IAAiBprC,EAAMwd,SAA0D,OAC7F6tB,GAAeC,IAAoBtrC,EAAMwd,SAAwB,OAEjE+tB,GAAYC,IAAiBxrC,EAAMwd,SAA2C,MAC/EiuB,GAA0B,OAAfF,IACVG,GAAMC,IAAW3rC,EAAMwd,SAAqF,OAC5GqsB,GAAW+B,IAAgB5rC,EAAMwd,SAAS,GAC3CquB,GAAY7rC,EAAM+c,OAAO,GACzB+uB,GAAmB9rC,EAAM+c,OAA4B,OAGpDgvB,GAAeC,IAAoBhsC,EAAMwd,SAAmD,KAAA,CAC/FuB,OACAtb,IAAK,IAAI+a,OAEPytB,GAAqCF,GAAchtB,OAASA,EAAOgtB,GAActoC,IAAM65B,GACvF4H,GAAiBllC,EAAM4d,YACzB,CAACzS,EAAkBF,KACf+gC,GAAkBvb,IACd,MAAMhtB,EAAM,IAAI+a,IAAIiS,EAAK1R,OAASA,EAAO0R,EAAKhtB,IAAM,IAEpD,OADAA,EAAI4M,IAAIlF,EAAIF,GACL,CAAE8T,OAAMtb,UAGvB,CAACsb,KAKGxe,MAAO2rC,GAAersC,OAAQssC,ab3nBYhnC,EAAgCinC,GAAU,GAC5F,MAAO7mC,EAAM8mC,GAAWrsC,EAAMwd,SAAsB,CAAEjd,MAAO,EAAGV,OAAQ,IAoBxE,OAlBAG,EAAM+b,gBAAgB,KAClB,MAAMrY,EAAKyB,EAAI6X,QACf,IAAKtZ,IAAO0oC,EAAS,OACrB,MAAMtc,EAASA,KACX,MAAMvvB,EAAQmD,EAAG4oC,YACXzsC,EAAS6D,EAAG6oC,aAClBF,EAAS5b,GAAUA,EAAKlwB,QAAUA,GAASkwB,EAAK5wB,SAAWA,EAAS4wB,EAAO,CAAElwB,QAAOV,YAGxF,GADAiwB,IAC8B,oBAAnBa,eAEP,OADAhwB,OAAOopB,iBAAiB,SAAU+F,GAC3B,IAAMnvB,OAAOkwB,oBAAoB,SAAUf,GAEtD,MAAMY,EAAW,IAAIC,eAAeb,GAEpC,OADAY,EAASE,QAAQltB,GACV,IAAMgtB,EAASI,cACvB,CAAC3rB,EAAKinC,IAEF7mC,CACX,CaqmB6DinC,CAAejJ,IAClEkJ,GAAgBnjC,EAAgBgqB,KAAY,EAC5C2L,GAAY10B,KAAKmiC,MAAMxN,EAAgBuN,IACvCE,GAAepiC,KAAKmiC,MAAMvN,EAAqBsN,IAE/CG,GAAmBriC,KAAKD,IAAI,EAAGC,KAAK2Y,OAAOypB,GAAe,GAAC,QAG1DE,GAAYC,IAAiB9sC,EAAMwd,SAAS,cACnDxd,EAAM+b,gBAAgB,KAClB,MAAMgQ,EAAOsX,GAAQrmB,QACrB,IAAK+O,GAA0B,oBAAXprB,OAAwB,OAC5C,MAAMosC,EAASpsC,OAAOqsC,iBAAiBjhB,GAAM8gB,WACzCE,GAAQD,GAAerc,GAAUA,IAASsc,EAAStc,EAAOsc,IAC/D,IACH,MAAME,GAAW,YAAYJ,KACvBK,GAAa,YAAYL,KAGzBM,GAAqBntC,EAAM4d,YAC5B9Q,IACG,MAAMsgC,EAAatgC,EAAIjD,QAAUb,EAC3BgJ,GAA4B,IAAjBlF,EAAIkF,WAAuBo7B,IAAehS,IACrDiS,GAAY76B,KAAsB46B,IAAetgC,EAAI0F,mBAC3D,IAAIjS,EAAQ+Z,GAAYxN,EAAI+E,YAAc/E,EAAIjD,MAAOqjC,IAjiBrC,GAiiByE,EAGzF,OAFIl7B,IAAUzR,GAjiBK,IAkiBf8sC,IAAU9sC,GAjiBO,IAkiBdgK,KAAK+iC,KAAK/sC,IAErB,CAAC2sC,GAAY9R,GAAsB5oB,KAKjC4xB,GAAapkC,EAAMu3B,QAAuB,KAC5C,MAAM1jB,EAAqB,GAM3B,OALAkL,EAAKvT,QAAS8B,IACV,MAAMnC,EAAKH,EAAgBsC,EAAKpC,GAC5BC,SACJ0I,EAAII,KAAK,CAAE9I,KAAIF,IAAKghC,GAAattB,IAAIxT,IAAOmC,MAEzCuG,GACR,CAACkL,EAAM7T,EAAU+gC,KAEdhI,GAAWjkC,EAAMu3B,QAAQ,KAC3B,MAAM9zB,EAAM,IAAI+a,IAIhB,OAHA4lB,GAAW54B,QAASgW,GAAU/d,EAAI4M,IAAImR,EAAMrW,GAAIqW,EAAMvW,OACrD02B,IAAYhS,KAAO,IAAInkB,QAASP,GAAQxH,EAAI4M,IAAIrF,EAAgBC,EAAKC,GAAWD,KAChF02B,IAAYnR,QAAU,IAAIhlB,QAASP,GAAQxH,EAAI4M,IAAIrF,EAAgBC,EAAKC,GAAWD,IAC7ExH,GACR,CAAC2gC,GAAYzC,GAAYz2B,IAItBqiC,GAAcvtC,EAAMu3B,QAAQ,IAAMyG,EAAYv6B,IAAKqJ,GAAQ2E,GAAgB3E,IAAO,CAACkxB,IAEnFvT,GAAiBzqB,EAAMu3B,QAAQ,KACjC,MAAM9zB,EAAM,IAAI+a,IAEhB,OADA+uB,GAAY/hC,QAASsB,GAAQrJ,EAAI4M,IAAIvD,EAAIjD,MAAOiD,IACzCrJ,GACR,CAAC8pC,KAEE/iB,GAAiBxqB,EAAMu3B,QACzB,IAAOmE,GAAqB,GAAKT,GAAiBvwB,OAAQb,GAAU4gB,GAAe3gB,IAAID,IACvF,CAACoxB,GAAkBxQ,GAAgBiR,KAEjC8R,GAAiBhjB,GAAergB,OAAS,EAEzCsjC,GAAiBztC,EAAMu3B,QAAiC,KAC1D,IAAKiW,GAAgB,OAAO,KAC5B,MAAME,EAAmC,IAA1BljB,GAAergB,OAAesgB,GAAe9L,IAAI6L,GAAe,SAAMjd,EACrF,OAAOkE,GAAmB,CACtB5H,MAAOb,EACP6I,WAAY67B,EAAUA,EAAO77B,YAAc67B,EAAO7jC,MAAS8oB,GAAW7Y,yBACtEvZ,MhBltByB,IgBmtBzBiH,SAAU,IACVwK,UAAU,EACVC,YAAY,EACZC,UAAU,EACVG,WAAW,EACXC,YAAY,EACZC,UAAU,EACVE,eAAe,EACfE,gBAAgB,KACZyvB,MAET,CAACoL,GAAgBhjB,GAAgBC,GAAgBkI,GAAW7Y,yBAA0BsoB,KAEnF+C,GAAqBnlC,EAAMu3B,QAAQ,KACrC,IAAKiT,IAA0C,IAAzBA,GAAcrgC,OAAc,OAAOojC,GACzD,MAAMI,EAAO,IAAItkC,IACXwK,EAA0B,GAWhC,OAVA22B,GAAch/B,QAAS3B,IACnB,MAAMiD,EAAM2d,GAAe9L,IAAI9U,GAC3BiD,IAAQ6gC,EAAK7jC,IAAID,KACjB8jC,EAAKliC,IAAI5B,GACTgK,EAAII,KAAKnH,MAGjBygC,GAAY/hC,QAASsB,IACZ6gC,EAAK7jC,IAAIgD,EAAIjD,QAAQgK,EAAII,KAAKnH,KAEhC+G,GACR,CAAC22B,GAAe+C,GAAa9iB,KAE1BmjB,GAAkB5tC,EAAM4d,YACzB/T,IACG,MAAM9I,EAAQ42B,GAAsB9tB,GACpC,OAAc,IAAV9I,SACUwM,IAAVxM,IAAyD,IAAlCypB,GAAeva,QAAQpG,KAGtD,CAAC8tB,GAAuBnN,KAGtB4a,GAAqBplC,EAAMu3B,QAAQ,KACrC,GAAIgU,GAAY,CACZ,IAAIpnB,EAAOghB,GAAmBz6B,OAAQoC,GAAQ8gC,GAAgB9gC,EAAIjD,QAClE,GAAI0hC,GAAWjtB,OAAQ,CACnB,MAAMuvB,EAAS,IAAIxkC,IAAIkiC,GAAWjtB,QAClC6F,EAAOghB,GAAmBz6B,OAAQoC,GAAQ+gC,EAAO/jC,IAAIgD,EAAIjD,OAC7D,MAAW0hC,GAAWnoC,aAClB+gB,EAAOghB,IAEX,OAAOhhB,EAAKzZ,OAAQoC,IAASA,EAAI2F,cACrC,CACA,OAAO0yB,GAAmBz6B,OAAQoC,GAAQ8gC,GAAgB9gC,EAAIjD,SAC/D,CAACs7B,GAAoByI,GAAiBrC,KAEnCuC,GAAS9tC,EAAMu3B,QAAQ,KACzB,MAAMja,EAA4B,GAC9BwjB,IAAmBxjB,EAASrJ,KAAKrB,IACjCgvB,IAAuBtkB,EAASrJ,KAAKpB,IACzC,MAAMk7B,EAAavS,GAAuB,IAAMmF,GAAc/Q,MAAQ,IAAIllB,OAAQgU,GAAMA,IAAM1V,GACxFglC,EAAcxS,GACd,IACCmF,GAAcpQ,OAAS,IAAI7lB,OAAQgU,GAAMA,IAAM1V,GAChDilC,EAAiB,IAAIzvB,IAC3B4mB,GAAmB55B,QAASsB,GAAQmhC,EAAe59B,IAAIvD,EAAIjD,MAAOiD,IAClE,MAAM8iB,EAAwBtS,EAASlI,QACnCq4B,IAAgB7d,EAAK3b,KAAKw5B,IAC9BM,EAAWviC,QAASkT,IAChB,MAAM5R,EAAMmhC,EAAetvB,IAAID,GAC3B5R,GAAK8iB,EAAK3b,KAAKnH,KAEvB,MAAMyjB,EAAyB,GAC/Byd,EAAYxiC,QAASkT,IACjB,MAAM5R,EAAMmhC,EAAetvB,IAAID,GAC3B5R,QAAOihC,EAAW99B,QAAQyO,IAAW6R,EAAMtc,KAAKnH,KAExD,MAAMohC,EAAS9I,GAAmB16B,OAC7BoC,IAA0C,IAAlCihC,EAAW99B,QAAQnD,EAAIjD,aAAiBmkC,EAAY/9B,QAAQnD,EAAIjD,QAEvEskC,EAAUve,EAAKnN,OAAOyrB,EAAQ3d,GAC9B6d,EAAuC,CAAA,EAC7CD,EAAQ3iC,QAASsB,IAETlD,EAAgBkD,EAAIjD,QAAUiD,EAAIuhC,eACtCD,EAAathC,EAAIjD,OAASsjC,GAAmBrgC,MAEjD,MAAMkY,EA7pBQspB,EAClBnqB,EACAoqB,EACAC,EACAJ,KAEA,MAAMK,EAAU3hC,GAAuBA,EAAItF,UAAY+C,KAAKD,IhBpJxB,GgBoJsD8jC,EAAathC,EAAIjD,QAAU,GAC/GsiB,EAA+BhI,EAAK1gB,IAAKqJ,IAC3C,MAAMzC,EAAMyC,EAAItF,UhBtJgB,GgBuJ1B8C,EAAMwC,EAAItM,UAAYkuC,IACtBC,EAAWH,EAAU1hC,EAAIjD,OAC/B,OAAI8kC,EAAiBvkC,EAAMukC,EAAUtkC,EAAKC,GACtCwC,EAAI8hC,MAAQ9hC,EAAI8hC,KAAO,EAAU,UACnBrhC,IAAdT,EAAIvM,MAA4B6J,EAAM0C,EAAIvM,MAAO8J,EAAKC,GACnDF,EAAMG,KAAKD,IhB7JU,IgB6JgB8jC,EAAathC,EAAIjD,QAAU,GAAIQ,EAAKC,KAE9EukC,EAAiB,GACvB,IAAIC,EAAa,EAKjB,GAJA3iB,EAAO3gB,QAAQ,CAAC4Y,EAAGtD,KACL,OAANsD,EAAYyqB,EAAK56B,KAAK6M,GACrBguB,GAAc1qB,IAEnByqB,EAAK1kC,OAAS,EAAG,CACjB,IAAI4kC,EAAiBxkC,KAAKD,IAAI,EAAGikC,EAAYO,GACzCE,EAAgBH,EAAK/5B,OAAO,CAACC,EAAK+L,IAAM/L,EAAOoP,EAAKrD,GAAG8tB,KAAiB,GACxEpgB,EAASqgB,EAAKz5B,QACd65B,GAAU,EACd,KAAOA,GAAWzgB,EAAOrkB,OAAS,GAAG,CACjC8kC,GAAU,EACV,IAAK,IAAI5uB,EAAI,EAAGA,EAAImO,EAAOrkB,OAAQkW,GAAK,EAAG,CACvC,MAAMS,EAAI0N,EAAOnO,GACXvT,EAAMqX,EAAKrD,GACXzW,EAAMokC,EAAO3hC,GACbxC,EAAMwC,EAAItM,UAAYkuC,IACtBQ,EAAQF,EAAgB,EAAKD,EAAkBjiC,EAAI8hC,KAAmBI,EAAgB,EAC5F,GAAIE,EAAQ7kC,GAAO6kC,EAAQ5kC,EAAK,CAC5B,MAAM6kC,EAAQD,EAAQ7kC,EAAMA,EAAMC,EAClC6hB,EAAOrL,GAAKquB,EACZJ,EAAiBxkC,KAAKD,IAAI,EAAGykC,EAAiBI,GAC9CH,GAAiBliC,EAAI8hC,KACrBpgB,EAASA,EAAO9jB,OAAQ0kC,GAAQA,IAAQtuB,GACxCmuB,GAAU,EACV,KACJ,CACJ,CACJ,CACAzgB,EAAOhjB,QAASsV,IACZ,MAAMhU,EAAMqX,EAAKrD,GACjBqL,EAAOrL,GACHkuB,EAAgB,EACVzkC,KAAK2Y,MAAO6rB,EAAkBjiC,EAAI8hC,KAAmBI,GACrDP,EAAO3hC,IAEzB,CACA,OAAOqf,GAumBYmiB,CAAcH,EAASjC,GAAe7oB,GAAc+qB,GAC7DiB,EAAazf,EAAKzlB,OAASmT,EAASnT,QAAUsjC,GAAiB,EAAI,IAAMld,EAAMpmB,OAAS,EACxF+T,EAA0B,GAChC,IAAIoxB,EAAI,EACJC,EAAa,EACjBpB,EAAQ3iC,QAAQ,CAACsB,EAAKgU,KAClB,MAAMvgB,EAAQykB,EAAOlE,GACf0uB,EAAS1uB,EAAI8O,EAAKzlB,OAClBslC,EAAU3uB,GAAK8O,EAAKzlB,OAAS+jC,EAAO/jC,OAC1C+T,EAAQjK,KAAK,CACTnH,MACAvM,QACAu6B,OAAQ0U,EAAS,OAASC,EAAU,QAAU,KAC9CtuB,OAAQquB,EAASD,EAAa,EAC9BD,IACAI,WAAYF,GAAU1uB,IAAM8O,EAAKzlB,OAAS,EAC1CwlC,aAAcF,GAAW3uB,IAAM8O,EAAKzlB,OAAS+jC,EAAO/jC,SAEpDqlC,IAAQD,GAAchvC,GAC1B+uC,GAAK/uC,IAET,IAAIqvC,EAAc,EAClB,IAAK,IAAI9uB,EAAI5C,EAAQ/T,OAAS,EAAG2W,GAAK,GACR,UAAtB5C,EAAQ4C,GAAGga,OADsBha,GAAK,EAE1C5C,EAAQ4C,GAAGK,OAASyuB,EACpBA,GAAe1xB,EAAQ4C,GAAGvgB,MAE9B,MAAO,CAAE2d,UAAS2xB,WAAYP,EAAGD,aAAYS,UAAWlgB,EAAKzlB,OAAQ4lC,WAAYxf,EAAMpmB,SACxF,CACC22B,GACAc,GACAjB,GACAnF,GACA4J,GACAqI,GACAvB,GACA7oB,GACA8pB,KAGE6C,GAA2BhwC,EAAMu3B,QAAQ,KAC3C,MAAM9zB,EAAM,IAAI+a,IAGhB,OAFAsvB,GAAO5vB,QAAQ1S,QAASiT,GAAMhb,EAAI4M,IAAIoO,EAAE3R,IAAIjD,MAAO4U,EAAE3R,MACjD2gC,IAAgBhqC,EAAI4M,IAAIrH,EAAuBykC,IAC5ChqC,GACR,CAACqqC,GAAO5vB,QAASuvB,KAEdpI,GAAYrlC,EAAM4d,YACnB/T,GACG4gB,GAAe9L,IAAI9U,IAAWmmC,GAAyBrxB,IAAI9U,GAC/D,CAAC4gB,GAAgBulB,KAKfC,GAAgBjwC,EAAMu3B,QAAQ,KAChC,MAAM1jB,EAAqE,GAS3E,OARAqlB,GAAYtO,MAAMpf,QAASoE,IACvB,MAAM9C,EAAM2d,GAAe9L,IAAI/O,EAAK/F,OACpC,IAAKiD,IAA0B,IAAnBA,EAAImF,WAAsB,OACtC,MAAM0mB,EAAWrnB,GAAyBxE,GAAKa,KAAMksB,GAAOA,EAAG94B,QAAU6O,EAAK+oB,UAC9E,IAAKA,EAAU,OACf,MAAMtM,EAAKsM,EAAS5oB,iBAAiBH,EAAM9C,GACvCuf,GAAIxY,EAAII,KAAK,CAAEnH,MAAKuf,SAErBxY,GACR,CAACqlB,GAAYtO,MAAOH,KAEjBkK,GAAoB30B,EAAMu3B,QAC5B,KAAO2B,GAAYvE,mBAAqB,IAAIlxB,IAAKoN,GAAM5D,OAAO4D,GAAGyD,QAAQ5J,OAAQmG,GAAY,KAANA,GACvF,CAACqoB,GAAYvE,oBAGXub,GAAqBlwC,EAAMu3B,QAAQ,KACxB2B,GAAYwE,gCAAkC0H,GAAqBD,IACpEz6B,OAAQoC,IAA2B,IAAnBA,EAAImF,YAAqC,YAAbnF,EAAIxB,MAC7D,CAAC4tB,GAAYwE,gCAAiC0H,GAAoBD,KAE/DgL,GAAkBnwC,EAAMu3B,QAAQ,KAClC,GAA6B,IAAzB0Y,GAAc9lC,QAA6C,IAA7BwqB,GAAkBxqB,OAAc,OAAOi6B,GACzE,MAAMgM,EAAoD,SAAxClX,GAAYC,eAAiB,OACzCkX,EAA+D,SAAnDnX,GAAYoX,0BAA4B,OACpDC,EAAc3M,GAAO5mB,QAAQ3P,IAC7BmjC,EAAW7b,GAAkBlxB,IAAKuM,IACpC,MAAMygC,EAAUzgC,EAAON,cAejB8e,EAdY0hB,GAAmBzsC,IAAKqJ,IACtC,GAAIA,EAAI4jC,sBAAuB,CAC3B,MAAMC,EAAS7jC,EAAI4jC,sBAAsB1gC,EAAQlD,EAAKyjC,GACtD,OAAOI,EAAS,CAAE7jC,MAAKuf,GAAIskB,GAAW,IAC1C,CAQA,MAAO,CAAE7jC,MAAKuf,GAPsBA,CAACtrB,EAAOkK,KACxC,GAAIlB,EAAMhJ,GAAQ,OAAO,EAEzB,IAAmC,IADjBgN,GAAuBF,GAAkB9M,EAAOkK,EAAK6B,EAAKyjC,IAAc7gC,cAC5EO,QAAQwgC,GAAiB,OAAO,EAE9C,OAAgC,KADH,iBAAV1vC,EAAqB,GAAKkM,OAAOlM,GAAO2O,eAChDO,QAAQwgC,OAIF/lC,OAAOC,SAChC,OAAQM,GAAWujB,EAAO0C,KAAK,EAAGpkB,MAAKuf,QAASA,EAAGjf,EAAanC,EAAK6B,EAAKyjC,GAActlC,EAAK6B,EAAKyjC,MAEtG,OAAOnM,GAAW15B,OAAO,EAAGO,UACxB,GAAIglC,GAAc9lC,OAAS,EAAG,CAC1B,MAAMymC,EAAUX,GAAcxsC,IAAI,EAAGqJ,MAAKuf,QACtCA,EAAGjf,EAAanC,EAAK6B,EAAKyjC,GAActlC,EAAK6B,EAAKyjC,IAGtD,KADaH,EAAWQ,EAAQ17B,MAAMvK,SAAWimC,EAAQ1f,KAAKvmB,UACnD,OAAO,CACtB,CACA,GAAI6lC,EAASrmC,OAAS,EAAG,CACrB,MAAMymC,EAAUJ,EAAS/sC,IAAK4oB,GAAOA,EAAGphB,IACxC,OAAOolC,EAAWO,EAAQ17B,MAAMvK,SAAWimC,EAAQ1f,KAAKvmB,QAC5D,CACA,OAAO,KAEZ,CACCy5B,GACA6L,GACAtb,GACAub,GACAhX,GAAYC,cACZD,GAAYoX,2BAKVO,GAAiB7wC,EAAMu3B,QAAQ,KACjC,MAAMgZ,EAAc3M,GAAO5mB,QAAQ3P,IAC7ByjC,EAAUjW,GACXnwB,OAAQkF,GAASA,EAAKyF,MAAQzF,EAAK/F,QAAUb,GAC7CvF,IAAKmM,IACF,MAAM9C,EAAM2d,GAAe9L,IAAI/O,EAAK/F,OACpC,OAAKiD,IAAwB,IAAjBA,EAAIkF,SACT,CACHlF,MACAikC,IAAmB,SAAdnhC,EAAKyF,MAAkB,EAAK,EACjC27B,WAAYlkC,EAAImkC,gBAAkBzhC,GAAqB1C,EAAIxB,OAJpB,OAO9CZ,OAAOC,SACZ,OAAuB,IAAnBmmC,EAAQ3mC,OAAqB,KAC1B,CAACwG,EAAgBC,KACpB,IAAK,IAAIkQ,EAAI,EAAGA,EAAIgwB,EAAQ3mC,OAAQ2W,GAAK,EAAG,CACxC,MAAMhU,IAAEA,EAAGikC,IAAEA,EAAGC,WAAEA,GAAeF,EAAQhwB,GACnCvS,EAAKnB,EAAauD,EAAE1F,IAAK6B,EAAKyjC,GAC9B/hC,EAAKpB,EAAawD,EAAE3F,IAAK6B,EAAKyjC,GAC9BpkB,EAAS6kB,EACXziC,EACAC,EACA,CAAErD,GAAIwF,EAAExF,GAAItB,MAAOiD,EAAIjD,MAAO9I,MAAOwN,EAAItD,IAAK0F,EAAE1F,IAAKoC,IAAKkjC,GAC1D,CAAEplC,GAAIyF,EAAEzF,GAAItB,MAAOiD,EAAIjD,MAAO9I,MAAOyN,EAAIvD,IAAK2F,EAAE3F,IAAKoC,IAAKkjC,IAE9D,GAAe,IAAXpkB,EAAc,OAAOA,EAAS4kB,CACtC,CACA,OAAO,IAEZ,CAAClW,GAAWpQ,KAETymB,GAAclxC,EAAM4d,YACrByD,GACQwvB,GACExvB,EACF5d,IAAI,CAAC+d,EAAOuB,KAAK,CAAQvB,QAAOuB,WAChC1N,KAAK,CAAC1E,EAAGC,IAAMigC,GAAelgC,EAAE6Q,MAAO5Q,EAAE4Q,QAAU7Q,EAAEoS,MAAQnS,EAAEmS,OAC/Dtf,IAAKmM,GAASA,EAAK4R,OAJIH,EAMhC,CAACwvB,KAKClV,GAAuB37B,EAAMu3B,QAC/B,KAAA,IAAY9iB,MAAmC+tB,KAC/C,CAACA,KAEC2O,IAAqBrV,IAAsB3oB,OAAOC,KAAK6Y,IAAkB9hB,OAAS,EAElFinC,GAAkBpxC,EAAM4d,YACzBwN,IACG,MAAMujB,EAAW9D,GAAelsB,IAAIyM,EAAKjgB,IACzC,YAAiBoC,IAAbohC,EAA+BA,EAC/BtM,GACOA,GAAyB,CAC5B/2B,KAAM,QACNH,GAAIigB,EAAKjgB,GACT0f,MAAOO,EAAKP,MACZQ,OAAQD,EAAKC,OACbC,cAAeF,EAAKE,cACpBC,YAAaH,EAAKG,YAClBC,cAAeJ,EAAKI,cACpBjjB,SAAU,GACV8oC,QAAS,GACTjc,YAAY,KAGqB,IAAlC+M,IAAwC/W,EAAKP,MAAQsX,IAEhE,CAAC0I,GAAgBxI,GAA0BF,KAGzCmP,GAAYtxC,EAAMu3B,QAAQ,KAC5B,MAAMgN,EAAY,IAAI/lB,IAChBkqB,EAAa,IAAIlqB,IACvB,IAAKgvB,GAAgB,CACjB,MAAMl4B,EAAS47B,GAAYf,IAM3B,MAAO,CAAEoB,YAL4Bj8B,EAAO7R,IAAK+d,IAC7C,MAAM4J,EAAwB,CAAE9f,KAAM,OAAQH,GAAIqW,EAAMrW,GAAI0f,MAAO,EAAGQ,OAAQ,MAE9E,OADAkZ,EAAUl0B,IAAImR,EAAMrW,GAAIigB,GACjB,CAAEjgB,GAAIqW,EAAMrW,GAAIG,KAAM,OAAQL,IAAKuW,EAAMvW,IAAKmgB,OAAMP,MAAO,KAEhD4Z,aAAcnvB,EAAQivB,YAAWmE,aAAY8I,KAAM,GAC7E,CACA,MAAMjB,EAAc3M,GAAO5mB,QAAQ3P,IACnC,IAAImkC,EAAOjnB,GAAe4lB,GAAiB3lB,GAAgBC,GAAgB8lB,GAC3E,MAAMkB,EAAe5W,GAAUltB,KAAMiC,GAASA,EAAK/F,QAAUb,GAAyB4G,EAAKyF,MAiB3Fm8B,EV58BqBE,EACzB5lB,EACA6lB,EACAC,KAEA,MAAMC,EAAYA,CAACjmB,EAA2Bf,KAC1C,MAAMmmB,EAAaW,EAAgBA,EAAc9mB,GAAS,KACpDvV,EAAS07B,EACTplB,EACKnoB,IAAI,CAAC2nB,EAAMrI,KAAK,CAAQqI,OAAMrI,WAC9B1N,KAAK,CAAC1E,EAAGC,IAAMogC,EAAWrgC,EAAEya,KAAMxa,EAAEwa,OAASza,EAAEoS,MAAQnS,EAAEmS,OACzDtf,IAAKmM,GAASA,EAAKwb,MACxBQ,EAYN,OAXAtW,EAAO9J,QAAS4f,IACZ,GAAIA,EAAKK,YAAYthB,OAAS,EAAG,CAC7BihB,EAAKK,YAAcomB,EAAUzmB,EAAKK,YAAaZ,EAAQ,GACvD,MAAMc,EAA6B,GACnCP,EAAKK,YAAYjgB,QAASuoB,GAAUA,EAAMpI,YAAYngB,QAASU,GAAMyf,EAAY1X,KAAK/H,KACtFkf,EAAKO,YAAcA,CACvB,MACIP,EAAKM,OAASkmB,EAAWxmB,EAAKM,QAC9BN,EAAKO,YAAcP,EAAKM,SAGzBpW,GAEX,OAAOu8B,EAAU/lB,EAAO,IUk7Bb4lB,CAAcF,EAhBE3mB,IACnB,MAAMhhB,EAAQ2gB,GAAeK,GACvB/d,EAAM2d,GAAe9L,IAAI9U,GAC/B,IAAKiD,EAAK,OAAO,KACjB,MAAM8tB,EAAW6W,GAAgB5W,GAAUltB,KAAMiC,GAASA,EAAK/F,QAAUA,GAAS+F,EAAKyF,MACvF,IAAKulB,EAAU,OAAO,KACtB,MAAMoW,EAAalkC,EAAImkC,gBAAkBzhC,GAAqB1C,EAAIxB,MAC5DylC,EAAwB,SAAlBnW,EAASvlB,MAAkB,EAAK,EAC5C,MAAO,CAAC1E,EAAqBC,IACzBogC,EACIrgC,EAAE4a,YACF3a,EAAE2a,YACF,CAAEpgB,GAAIwF,EAAExF,GAAItB,QAAO9I,MAAO4P,EAAE4a,YAAatgB,IAAK0F,EAAEgb,YAAY,IAAI1gB,IAAKoC,IAAKkjC,GAC1E,CAAEplC,GAAIyF,EAAEzF,GAAItB,QAAO9I,MAAO6P,EAAE2a,YAAatgB,IAAK2F,EAAE+a,YAAY,IAAI1gB,IAAKoC,IAAKkjC,IAC1EQ,GAE8BG,IAC1C,MAAMK,EVz5BkBO,EAC5BhmB,EACAsJ,EACAmP,EACAmE,KAEA,MAAM70B,EAAuB,GACvBk+B,EAAQA,CAACnmB,EAA2BkM,KACtClM,EAAMpgB,QAAS4f,IACX,MAAM9mB,EAAW8wB,EAAWhK,GACtB4mB,EA3BSC,EACvB7mB,EACAgK,KAAmB,CAEnB9pB,KAAM,QACNH,GAAIigB,EAAKjgB,GACT0f,MAAOO,EAAKP,MACZQ,OAAQD,EAAKC,OACbC,cAAeF,EAAKE,cACpBC,YAAaH,EAAKG,YAClBC,cAAeJ,EAAKI,cACpBjjB,SAAU6iB,EAAKK,YAAYthB,OAAS,EAAIihB,EAAKK,YAAYhoB,IAAKgb,GAAMA,EAAEtT,IAAMigB,EAAKM,OAAOjoB,IAAKyuC,GAAMA,EAAE/mC,IACrGkmC,QAASjmB,EAAKO,YAAYloB,IAAKyI,GAAMA,EAAEf,IACvCiqB,eAc0B6c,CAAY7mB,EAAM9mB,GACpCigC,EAAUl0B,IAAI+a,EAAKjgB,GAAI6mC,GACvBtJ,EAAWr4B,IAAI+a,EAAKjgB,GAAIigB,GACpB0M,GACAjkB,EAAII,KAAK,CAAE9I,GAAIigB,EAAKjgB,GAAIG,KAAM,QAASL,IAAK,KAAMmgB,KAAM4mB,EAAWnnB,MAAOO,EAAKP,MAAO4d,MAAOrd,IACjG,MAAM+mB,EAAera,GAAWxzB,EAC5B8mB,EAAKK,YAAYthB,OAAS,EAC1B4nC,EAAM3mB,EAAKK,YAAa0mB,GAExB/mB,EAAKM,OAAOlgB,QAAS4mC,IACjB,MAAMC,EAA4B,CAAE/mC,KAAM,OAAQH,GAAIinC,EAAKjnC,GAAI0f,MAAOO,EAAKP,MAAQ,EAAGQ,OAAQD,EAAKjgB,IACnGo5B,EAAUl0B,IAAI+hC,EAAKjnC,GAAIknC,GACnBF,GACAt+B,EAAII,KAAK,CAAE9I,GAAIinC,EAAKjnC,GAAIG,KAAM,OAAQL,IAAKmnC,EAAKnnC,IAAKmgB,KAAMinB,EAAUxnB,MAAOO,EAAKP,MAAQ,SAM7G,OADAknB,EAAMjmB,GAAO,GACNjY,GU43BiBi+B,CAAiBN,EAAMJ,GAAiB7M,EAAWmE,GACvE,MAAO,CAAE6I,cAAa9M,aAAc5Y,GAAkB2lB,GAAOjN,YAAWmE,aAAY8I,SACrF,CAAChE,GAAgB2C,GAAiBe,GAAa1mB,GAAgBC,GAAgBoQ,GAAWuW,MAEvFG,YAAEA,GAAW9M,aAAEA,GAAYF,UAAEA,GAASmE,WAAEA,IAAe4I,GAIvDgB,GAAmBf,GAAYpnC,OAC/BooC,GAAWvb,KAAeyU,GAC1BnV,GAAYU,GAAazsB,KAAKD,IAAI,EAAGC,KAAK+iC,KAAKgF,GAAmB/nC,KAAKD,IAAI8rB,GAAgBD,SAAU,KAAO,EAC5GD,GAAOc,GAAa5sB,EAAMgsB,GAAgBF,KAAM,EAAGI,GAAY,GAAK,EAE1Et2B,EAAMgc,UAAU,KACRgb,IAAcZ,GAAgBF,OAASA,IACvCqR,GAAmB,IAAKnR,GAAiBF,WAE9C,CAACc,GAAYZ,GAAiBF,GAAMqR,KAEvC,MAAM5C,GAAY3kC,EAAMu3B,QACpB,IACIgb,GACMhB,GAAYn8B,MAAM8gB,GAAOE,GAAgBD,UAAWD,GAAO,GAAKE,GAAgBD,UAChFob,GACV,CAACA,GAAagB,GAAUrc,GAAME,GAAgBD,WAK5Cqc,GAAmBxyC,EAAMu3B,QAAQ,KACnC,IAAK4Z,IAA6C,WAAxB1O,GAAkC,OAAO,KACnE,MAAMgQ,EAAgBhO,GAAahhC,IAAK+d,GAAUA,EAAMvW,KACxD,OAAO+gB,GAAcymB,EAAexmB,GAAkBxB,GAAgBkR,GAAsBiI,GAAO5mB,QAAQ3P,MAC5G,CAAC8jC,GAAmB1O,GAAqBgC,GAAcxY,GAAkBxB,GAAgBkR,KAEtF+W,GAAuB1yC,EAAMu3B,QAC/B,IAAM,IAAI/Y,IACV,CAACmmB,GAAW1Y,GAAkB0P,KAE5BgX,GAAsBlK,IACxB,IAAK0I,IAA6C,WAAxB1O,GAAkC,OAC5D,IAAImQ,EAASF,GAAqB/zB,IAAI8pB,EAAMt9B,IAW5C,OAVKynC,IACDA,EAAS5mB,GACLyc,EAAM9c,YAAYloB,IAAKyI,GAAMA,EAAEjB,KAC/BghB,GACAxB,GACAkR,GACAiI,GAAO5mB,QAAQ3P,KAEnBqlC,GAAqBriC,IAAIo4B,EAAMt9B,GAAIynC,IAEhCA,GAKLC,GAAU7yC,EAAMu3B,QAAQ,KAC1B,MAAMub,EAAuB,GACvBC,EAA0B,GAC1BC,EAAoB,GAC1B,IAAI9xB,EAAQ,EACR+xB,EAAU5T,GAAcC,GAAyBmM,GAqBrD,OApBA9G,GAAUn5B,QAASo5B,IACf,IAAI9kB,EAAImf,GACR,GAAIG,GAA4B,SAAZwF,EAAGt5B,MAAmBs5B,EAAG35B,IAAK,CAC9C,MAAMkhB,EAASiT,EAAa,CAAEj0B,GAAIy5B,EAAGz5B,GAAIusB,MAAOkN,EAAG35B,IAAKwhC,mBACzC,SAAXtgB,EAAmB8mB,GAAU,EACN,iBAAX9mB,GAAuBA,EAAS,IAAGrM,EAAIqM,EAC3D,CACA,IAAIjgB,EAAI,EACR,GAAgB,SAAZ04B,EAAGt5B,MAAmBs2B,IAAyBqG,GAAqBn+B,IAAI86B,EAAGz5B,KAAOy5B,EAAG35B,IAAK,CAC1F,MAAMioC,EAAKrR,GACLA,GAAqB,CAAE12B,GAAIy5B,EAAGz5B,GAAIF,IAAK25B,EAAG35B,MAxgC5B,IA0gCT,SAAPioC,EAAeD,GAAU,EACxB/mC,EAAIgnC,CACb,CACAJ,EAAW7+B,KAAK6L,GAChBizB,EAAc9+B,KAAK/H,GACnB8mC,EAAQ/+B,KAAKiN,GACbA,GAASpB,EAAI5T,IAEV,CAAE4mC,aAAYC,gBAAeC,UAAS9xB,QAAO+xB,YACrD,CACCtO,GACA1F,GACAG,EACAqN,GACA7K,GACAC,GACAoG,GACA5I,EACAC,EACAmM,KAGE0H,IAAWN,GAAQI,QAczBjzC,EAAMgc,UAAU,KACZ,IAAKuvB,GAAY,OAGjB,MAAM3hB,EAAQjpB,OAAO4a,WAAW,KACvB+nB,GAAQtmB,SACbwI,GAAiB,CACbO,YAAaud,GAAQtmB,QACrBpZ,QAAS2nC,GACT5lB,OAAQA,IAAM6lB,GAAc,SAEjC,IACH,MAAO,IAAM7qC,OAAOmpB,aAAaF,IAClC,CAAC2hB,KAEJ,MAAM6H,GAAepzC,EAAMu3B,QAAQ,KAC/B,MAAM9e,EAAQksB,GAAUx6B,OACxB,IAAKgpC,IAAqB,IAAV16B,EAAa,MAAO,CAAEra,MAAO,EAAGC,IAAKoa,GACrD,MAAM46B,EAjkCQ,EAikCmBpU,GAC3BqU,EAAU/oC,KAAKD,IAAI,EAAGu/B,GAAY8C,GAAe0G,GACjDE,EAAa1J,GAAYt/B,KAAKD,IAAI6hC,GAAgBlN,IAAaoU,GAC/DL,QAAEA,GAAYH,GACpB,IAAIW,EAAK,EACLC,EAAKh7B,EAAQ,EACjB,KAAO+6B,EAAKC,GAAI,CACZ,MAAMC,EAAOF,EAAKC,GAAO,EACrBT,EAAQU,GAAOb,GAAQC,WAAWY,GAAOb,GAAQE,cAAcW,GAAOJ,EAASE,EAAKE,EAAM,EACzFD,EAAKC,CACd,CACA,MAAMt1C,EAAQo1C,EACd,IAAIn1C,EAAMD,EACV,KAAOC,EAAMoa,GAASu6B,EAAQ30C,GAAOk1C,GAAYl1C,GAAO,EACxD,MAAO,CAAED,QAAOC,QACjB,CAAC80C,GAASxO,GAAUx6B,OAAQ0/B,GAAWsC,GAAgBlN,GAAW0N,GAAckG,KAE7Ec,GAAe3zC,EAAM4d,YAAY,KAC9BgmB,GAAO5mB,QAAQm2B,UAChBtH,GAAU7uB,UACd6uB,GAAU7uB,QAAUrc,OAAOizC,sBAAsB,KAC7C/H,GAAU7uB,QAAU,EAChBumB,GAAYvmB,SAAS4uB,GAAarI,GAAYvmB,QAAQ6sB,gBAE/D,IAEH7pC,EAAMgc,UACF,IAAM,KACE6vB,GAAU7uB,SAASrc,OAAOkzC,qBAAqBhI,GAAU7uB,UAEjE,IAKJ,MAAMqqB,GAAoBrnC,EAAM4d,YAC5B,CAACzS,EAAkBF,MACVA,KACAm2B,IACEA,GAAgB,CAAEj2B,KAAIF,MAAKiT,QAASinB,GAAoB93B,IAAKu2B,GAAO5mB,QAAQ3P,OAEvF,CAAC+zB,GAAiB+D,KAGhB2O,GAAsB9zC,EAAMu3B,QAAQ,KACRwJ,GACvB4D,GACIj6B,OAAQk6B,GAAmB,SAAZA,EAAGt5B,MAAmBs5B,EAAG35B,KACxCxH,IAAKmhC,IAAE,CAAQz5B,GAAIy5B,EAAGz5B,GAAIF,IAAK25B,EAAG35B,OACvCw5B,IACQ/5B,OAAQ8W,GAAU6lB,GAAkB7lB,EAAMrW,GAAIqW,EAAMvW,MAAMxH,IAAK+d,GAAUA,EAAMrW,IAC9F,CAAC41B,GAA8B4D,GAAWF,GAAc4C,KAErD0M,GAAyB/zC,EAAMu3B,QACjC,IAAMuc,GAAoBh/B,OAAe,CAACC,EAAK5J,IAAO4J,GAAO4xB,GAAY78B,IAAIqB,GAAM,EAAI,GAAI,GAC3F,CAAC2oC,GAAqBnN,KAEpBqN,GAAwBF,GAAoB3pC,OAAS,GAAK4pC,KAA2BD,GAAoB3pC,OACzG8pC,GAAyBF,GAAyB,IAAMC,GAExDE,GAAkBl0C,EAAM4d,YACzBu2B,IACGpN,GAAgBtW,IACZ,MAAM5S,EAAOs2B,EAAQ1jB,GACrB,MhBznCoB2jB,EAACzjC,EAA6BC,KAC9D,GAAID,EAAEpF,IAAIhG,OAASqL,EAAErF,IAAIhG,KAAM,OAAO,EACtC,IAAI8uC,GAAQ,EAIZ,OAHA1jC,EAAEpF,IAAIC,QAASL,IACNyF,EAAErF,IAAIzB,IAAIqB,KAAKkpC,GAAQ,KAEzBA,GgBmnCYD,CAAqB,CAAmB7oC,IAAKklB,GAAQ,CAAmBllB,IAAKsS,IAAU4S,EAAO5S,KAG7G,CAACkpB,KAGCI,GAAannC,EAAM4d,YACrB,CAACrS,EAAqB07B,GAAa,EAAMC,GAAiB,KACtDgN,GAAiBzjB,IACb,MAAM5S,EAAOqpB,EAAiB,IAAI79B,IAAsB,IAAIA,IAAIonB,GAMhE,GALAllB,EAAIC,QAASL,IACL87B,EACII,GAAkBl8B,EAAI84B,GAAStlB,IAAIxT,KAAM0S,EAAKpS,IAAIN,GACnD0S,EAAKy2B,OAAOnpC,KAEnB81B,IAA+BpjB,EAAKtY,KAAO,EAAG,CAC9C,MAAMgvC,EAAShpC,EAAIA,EAAIpB,OAAS,GAChC,OAAO,IAAId,IAAkB49B,GAAcppB,EAAK/T,IAAIyqC,GAAU,CAACA,GAAU,GAC7E,CACA,OAAO12B,KAGf,CAACq2B,GAAiB7M,GAAmBpD,GAAUhD,KAGnDjhC,EAAMgc,UAAU,KACZ,GAAIqlB,IAAoD,IAArBsF,GAAYphC,KAAY,OAC3D,IAAI0pC,GAAU,EACd,MAAMpxB,EAAO,IAAIxU,IACjBs9B,GAAYn7B,QAASL,IACb84B,GAASn6B,IAAIqB,GAAK0S,EAAKpS,IAAIN,GAC1B8jC,GAAU,IAEfA,GAASlI,GAAelpB,IAC7B,CAAComB,GAAU5C,GAA6BsF,GAAaI,KAExD,MAAMyN,GAAsBA,KACGrN,GAAW2M,IAAlCE,KAsCFhY,GAAaA,CAACnyB,EAAes8B,EAAkCsO,GAAgB,KACjF,MAAM3nC,EAAMu4B,GAAUx7B,GACtB,IAAKiD,IAAwB,IAAjBA,EAAIkF,UAAsBopB,GAAsB,OAC5D,MAAMpe,EAAU6d,GAAUltB,KAAMiC,GAASA,EAAK/F,QAAUA,GACxD,IAAIgU,EAQA6Z,EAPJ,QAAkBnqB,IAAd44B,EAAyB,CACzB,MAAM8D,EAAQn9B,EAAI+yB,cAAgBA,GAC5B9c,EAAQknB,EAAMh6B,QAAQ+M,GAAS3H,MAAQ,MAC7CwI,EAAOosB,GAAOlnB,EAAQ,GAAKknB,EAAM9/B,OACrC,MACI0T,EAAOsoB,EAGPsO,IAAkB3U,IAClBpI,EAAQmD,GAAUnwB,OAAQkF,GAASA,EAAK/F,QAAUA,GAC9CgU,IACA6Z,EAAQ1a,EACF6d,GAAUp3B,IAAKmM,GAAUA,EAAK/F,QAAUA,EAAQ,CAAEA,QAAOwL,KAAMwI,GAASjO,GACxE8nB,EAAMjV,OAAO,CAAC,CAAE5Y,QAAOwL,KAAMwI,OAEvC6Z,EAAQ7Z,EAAO,CAAC,CAAEhU,QAAOwL,KAAMwI,IAAU,GAE7CqoB,GAAaxO,IAKXgd,GAAgBp2B,IACd8hB,IAAuBj/B,EAAkBi/B,GAAuB9hB,IAGlEq2B,GAAiB3vB,IACfqb,IAAuBl/B,EAAkBk/B,GAAuBrb,IA0BlE6gB,GAAkBA,CAACjiC,EAA8E,MACnG,MAAM+b,EAAiB/b,EAAQ+b,iBAAkB,EAC3Ci1B,EAAU9G,GAAO5vB,QAAQxT,OAC1BmqC,KAAQjrC,EAAgBirC,EAAG/nC,IAAIjD,QAAYjG,EAAQsa,UAAqD,IAA1Cta,EAAQsa,QAAQjO,QAAQ4kC,EAAG/nC,IAAIjD,SAElG,GAAuB,IAAnB+qC,EAAQzqC,OAAc,OAC1B,MAAM2qC,EAASrQ,GAAarvB,MAAM,EAAG,KAC/Bm7B,EAAc3M,GAAO5mB,QAAQ3P,IAC7BwQ,EAAO,IAAKwF,IAClBuxB,EAAQppC,QAAQ,EAAGsB,UACf,IAAIxC,EAAMqV,EAAiBwtB,GAAmBrgC,GAAO,EACrDgoC,EAAOtpC,QAASgW,IACZ,MAAMzgB,EAAQqM,EAAaoU,EAAMvW,IAAK6B,EAAKyjC,GACrCpxC,EAAO4O,GAAuBF,GAAkB9M,EAAOygB,EAAMvW,IAAK6B,EAAKyjC,EAAa/uB,EAAMrW,KAC1FiZ,EAAI9J,GAAYnb,EAAM8tC,IAAY,GACpC7oB,EAAI9Z,IAAKA,EAAM8Z,KAEvBvG,EAAK/Q,EAAIjD,OAASO,EAAMG,KAAK+iC,KAAKhjC,GAAMwC,EAAItF,UhB32ChB,GgB22CsDsF,EAAItM,UAAYkuC,OAEtGhE,GAAgB7sB,GAChB82B,GAAc92B,IA4DZkV,GAAkB/yB,EAAM4d,YAAY,KACtCstB,GAAoBza,GAAUA,EAAK9H,KAAO,CAAEA,MAAM,EAAO0G,SAAU,MAASoB,IAC7E,IAIGskB,GAAoBtvB,KACjBA,EAAOuvB,OAAOziC,WACS,SAAxBkT,EAAOwvB,QAAQ3pC,QACZu3B,IAAiBA,GAAepd,KAGrCmjB,GAAoBA,CAACz9B,EAAkBtB,KACzC,MAAMoB,EAAMg5B,GAAStlB,IAAIxT,GACnB2B,EAAMu4B,GAAUx7B,GACtB,IAAKoB,IAAQ6B,EAAK,OAClB,MAAM2Y,EAAS4jB,GAAgBl+B,EAAItB,EAAOoB,EAAKs5B,GAAU5lB,IAAIxT,IAAO,CAAEG,KAAM,OAAQH,KAAI0f,MAAO,EAAGQ,OAAQ,OACrG0pB,GAAiBtvB,KACtBslB,GAAe,CAAE5/B,KAAItB,UACrBs/B,GAAa1jB,EAAO1kB,OACpByoC,GAAe,CAAEr+B,KAAItB,YAiBnBg/B,GAAmBA,CACrB19B,EACAtB,EACAi/B,GAAsB,EACtBoM,EAAmF,SAEnF,IAAKjM,IAAeA,GAAY99B,KAAOA,GAAM89B,GAAYp/B,QAAUA,EAAO,OAC1E,MAAMoB,EAAMg5B,GAAStlB,IAAIxT,GACnB2B,EAAMu4B,GAAUx7B,GAEtB,GADAkhC,GAAe,MACV9/B,GAAQ6B,EAAb,CACA,IAAKg8B,EAAqB,CACtB,MAAMyH,EAAc3M,GAAO5mB,QAAQ3P,IAC7BlB,EAASW,EAAIqoC,YACbroC,EAAIqoC,YAAYnK,GAAW//B,EAAK6B,EAAKyjC,GhB3wCzB6E,EAAC9nC,EAAUR,KACrC,OAAQA,EAAIxB,MACR,IAAK,SAAU,CACX,GAAY,KAARgC,GAAcvD,EAAMuD,GAAM,OAAO,KACrC,MAAMmD,EAAI7E,OAAO0B,GACjB,OAAO1B,OAAOC,MAAM4E,GAAKnD,EAAMmD,CACnC,CACA,IAAK,UACD,OAAO9F,QAAQ2C,GACnB,IAAK,OACL,IAAK,WACD,MAAY,KAARA,GAAcvD,EAAMuD,GAAa,KAC3B5B,EAAO4B,IACLA,EAEhB,QACI,OAAOA,IgB4vCD8nC,CAAepK,GAAWl+B,GAC1BuoC,EAAejoC,EAAanC,EAAK6B,EAAKyjC,GAC5C,IAAKp9B,OAAO4K,GAAG5R,EAAQkpC,GAAe,CA/BvBC,EAACnqC,EAAkBoqC,EAAWC,KAC7C9S,GACAnZ,QAAQC,UACHisB,KAAK,IAAM/S,GAAiB6S,EAAQC,EAAQ,CAAEE,MAAOvqC,KACrDsqC,KAAMtpB,GAAW+Y,GAAe/5B,EAAKghB,GAAUopB,IAC/CI,MAAO9vB,IACA8c,GAAyBA,GAAwB9c,GAChDC,QAAQD,MAAM,mCAAoCA,KAG/Dqf,GAAe/5B,EAAIoqC,IAyBfD,CAAenqC,EAHA2B,EAAI8oC,YACb9oC,EAAI8oC,YAAYzpC,EAAQlB,EAAK6B,EAAKyjC,GACjC,IAAKtlC,EAAKpB,CAACA,GAAQsC,GACClB,EAC/B,CACJ,CACA23B,KAAiB,CAAEz3B,KAAItB,QAAOoB,MAAKiqC,UAAUrR,MAC7C0F,GAAgBvsB,SAAU,EAC1BwsB,GAAe,CAAEr+B,KAAItB,SAhBH,GAqBhBi+B,GAAqB38B,IACvB48B,GAAyBtX,IACrB,MAAM5S,EAAO,IAAIxU,IAAIonB,GAGrB,OAFI5S,EAAK/T,IAAIqB,GAAK0S,EAAKy2B,OAAOnpC,GACzB0S,EAAKpS,IAAIN,GACP0S,KAITyqB,GAA0BA,CAACn9B,EAAkBiqB,KAC/C0V,GAAmBra,IACf,MAAM5S,EAAO,IAAIW,IAAIiS,GAErB,OADA5S,EAAKxN,IAAIlF,EAAIiqB,GACNvX,KAIT0N,GAAcf,GAAe5f,KAAK,KAClCirC,GAAsB71C,EAAM+c,OAAOwO,IACzCvrB,EAAMgc,UAAU,KACR65B,GAAoB74B,UAAYuO,KACpCsqB,GAAoB74B,QAAUuO,GAC9Buf,GAAkB,IAAItsB,OACvB,CAAC+M,KAIJ,MAAM8d,GAAkBA,CAACl+B,EAAkBtB,EAAeoB,EAAQmgB,KAC9D,MAAMte,EAAMu4B,GAAUx7B,GAChB0mC,EAAc3M,GAAO5mB,QAAQ3P,IAC7BtM,EAAQqM,EAAanC,EAAK6B,EAAKyjC,GAC/BuF,EAAiBjoC,GAAkB9M,EAAOkK,EAAK6B,EAAKyjC,EAAaplC,GACjE4qC,EAAWprC,QAAQsgC,IAAeA,GAAY9/B,KAAOA,GAAM8/B,GAAYphC,QAAUA,GAEvF,MAAO,CACHsB,KACAtB,QACA9I,QACA+0C,iBACA7qC,MACAgqC,QAAS7pB,EACT4pB,OAAQloC,EACRO,IAAKkjC,EACLwF,WACAtkB,SAAUskB,EAAW,GAAI,EACzBC,SAZa/M,IAAeA,GAAY99B,KAAOA,GAAM89B,GAAYp/B,QAAUA,EAAQ,OAAS,OAa5FosC,WAAYtrC,QAAQmC,EAAIyF,WAA2B,SAAd6Y,EAAK9f,OAI5C4qC,GAAiBA,CAAC/qC,EAAkBF,KAAM,CAC5CE,KACAF,MACAiT,QAASinB,GACT93B,IAAKu2B,GAAO5mB,QAAQ3P,MAKxBrN,EAAMgc,UAAU,KACZ,IAAKutB,GAAgBvsB,UAAYiuB,KAAgB5H,GAAQrmB,QAAS,OAClEusB,GAAgBvsB,SAAU,EAC1B,MAAM9I,EAAW,qBAAqBjH,OAAOg+B,GAAY9/B,IAAIoI,QAAQ,KAAM,6BAA6B03B,GAAYphC,MAAM0J,QAAQ,KAAM,WAClI7P,EAAK2/B,GAAQrmB,QAAQqU,cAA2Bnd,GAClDxQ,GAAM8W,SAAS2X,gBAAkBzuB,IAAOA,EAAGutB,SAASzW,SAAS2X,gBAAgBzuB,EAAGymB,MAAM,CAAEgsB,eAAe,KAC5G,CAAClL,GAAamI,GAAah1C,MAAOg1C,GAAa/0C,MAElD,MAAMorC,GAAmBhkB,IACrB,MAAMkkB,EAAWpG,GAAYvmB,QAC7B,IAAK2sB,EAAU,OAAO,EACtB,QAAwBp8B,IAApBkY,EAAOlC,UAA0B4vB,GAAS,CAC1C,MAAMpwB,EAAQ3Y,EAAMqb,EAAOlC,SAAU,EAAGhZ,KAAKD,IAAIq6B,GAAUx6B,OAAS,EAAG,IACjEwlB,EAAMkjB,GAAQG,QAAQjwB,IAAU,EAChCyN,EAASb,GAAOkjB,GAAQC,WAAW/vB,IAAUkc,IAC7CmX,EAAazM,EAASE,UACtBwM,EAAgB1M,EAASE,UAAYF,EAAS4C,aAAeI,GAC/Dhd,EAAMymB,EAAYzM,EAASE,UAAYla,EAClCa,EAAS6lB,IAAe1M,EAASE,UAAYrZ,GAAUmZ,EAAS4C,aAAeI,IAC5F,MAAO,QAAwBp/B,IAApBkY,EAAOlC,SAAwB,CACtC,MAAM7f,EAAKimC,EAAStY,cAAc,wBAAwB5L,EAAOlC,cACjE7f,GAAI4yC,iBAAiB,CAAEpjC,MAAO,WAClC,CACA,QAAwB3F,IAApBkY,EAAO8wB,SAAwB,CAC/B,MAAM1B,EAAK/G,GAAO5vB,QAAQ9T,EAAMqb,EAAO8wB,SAAU,EAAGzI,GAAO5vB,QAAQ/T,OAAS,IAC5E,GAAI0qC,IAAOA,EAAG/Z,OAAQ,CAClB,MAAM0b,EAAkB1I,GAAO5vB,QAC1BxT,OAAQ+T,GAAmB,SAAbA,EAAEqc,QAChBhmB,OAAO,CAACC,EAAK0J,IAAM1J,EAAM0J,EAAEle,MAAO,GACjCk2C,EAAmB3I,GAAO5vB,QAC3BxT,OAAQ+T,GAAmB,UAAbA,EAAEqc,QAChBhmB,OAAO,CAACC,EAAK0J,IAAM1J,EAAM0J,EAAEle,MAAO,GACjCm2C,EAAc/M,EAASC,WAAa4M,EACpCG,EAAehN,EAASC,WAAaD,EAAS2C,YAAcmK,EAC9D5B,EAAGvF,EAAIoH,EAAa/M,EAASC,WAAaiL,EAAGvF,EAAIkH,EAC5C3B,EAAGvF,EAAIuF,EAAGt0C,MAAQo2C,IACvBhN,EAASC,WAAaiL,EAAGvF,EAAIuF,EAAGt0C,MAAQopC,EAAS2C,YAAcmK,EACvE,CACJ,CACA,OAAO,GAGLG,GAAYA,CACdC,EACAC,EACAC,KAEA,GAAyB,IAArBpS,GAAUx6B,QAA0C,IAA1B2jC,GAAO5vB,QAAQ/T,OAAc,OAC3D,IAAIoZ,EAAW0nB,GAActG,GAAUG,UAAWF,GAAOA,EAAGz5B,KAAO8/B,GAAY9/B,KAAM,EACjForC,EAAWtL,GAAc6C,GAAO5vB,QAAQ4mB,UAAW+P,GAAOA,EAAG/nC,IAAIjD,QAAUohC,GAAYphC,QAAS,OAChG0Z,IAAiBA,EAAW,QAC5BgzB,IAAiBA,EAAW,GACDhzB,EAAT,UAAlBwzB,GAAU9rC,IAA4B,EACf,SAAlB8rC,GAAU9rC,IAA2B05B,GAAUx6B,OAAS,EACjDC,EAAMmZ,EAAWszB,EAAU,EAAGlS,GAAUx6B,OAAS,GAClCosC,EAAT,UAAlBQ,GAAUjqC,IAA4B,EACf,SAAlBiqC,GAAUjqC,IAA2BghC,GAAO5vB,QAAQ/T,OAAS,EACtDC,EAAMmsC,EAAWO,EAAU,EAAGhJ,GAAO5vB,QAAQ/T,OAAS,GACtE,MAAMoc,EAAS,CAAEpb,GAAIw5B,GAAUphB,GAAUpY,GAAItB,MAAOikC,GAAO5vB,QAAQq4B,GAAUzpC,IAAIjD,OACjF0/B,GAAgBvsB,SAAU,EAC1BwsB,GAAejjB,GACfkjB,GAAgB,CAAElmB,WAAUgzB,cA0F1BS,GAAclqC,IAAwB4zB,KAAyB5zB,EAAI6F,iBAAmB/I,EAAgBkD,EAAIjD,OAoC1GotC,GAAYj3C,EAAM+c,OAOd,MAyCJja,GAAcmtC,GAAc9lC,OAC5BksB,GAAWmX,GAAiB8E,GAAmBnC,GAAgBhmC,OAE/DzH,GAAQ1C,EAAMu3B,QAChB,KAAA,CACIsD,aACA3B,eACA9C,gBAAiB,CAAEF,QAAMC,SAAUC,GAAgBD,UACnDG,aACAD,YACA6gB,cAAe9S,GAAWj6B,OAC1BwtB,yBACA6S,cAAerF,GAAmB1hC,IAAKgb,GAAMA,EAAE5U,OAC/CwZ,gBACAsd,iBACArN,WACAmZ,iBACA7V,kBAAmB,CAAEtrB,KAAM,UAAWC,IAAKo7B,IAC3C1L,oBACAhP,oBACAgc,wBACApV,gBAAiB,CACblK,KAAMkK,GAAgBlK,KACtBmK,iBAAkBD,GAAgBC,iBAClCsG,YAAavG,GAAgBuG,aAEjCt2B,eACA6xB,uBAEJ,CACIkG,GACA3B,GACAhD,GACAE,GAAgBD,SAChBG,GACAD,GACA+N,GAAWj6B,OACXwtB,GACAwN,GACA9hB,GACAsd,GACArN,GACAmZ,GACA9F,GACA1L,GACAhP,GACAgc,GACApV,GAAgBlK,KAChBkK,GAAgBC,iBAChBD,GAAgBuG,YAChBt2B,GACA6xB,KAIRiP,GAAO5mB,QAAU,CACb3P,IAAKy2B,GACLphC,SACAuhC,YACAG,cACAG,aACAmE,cACAjE,gBACAE,aACAz5B,WACAg6B,kBACAC,sBACAC,sBACAC,aACA1N,yBACAI,4BACA2N,eA7gBmBA,CAAC77B,EAAetJ,KACnC,MAAMuM,EAAMu4B,GAAUx7B,GACtB,IAAKiD,EAAK,OACV,MAAMqqC,EAAU/sC,EAAM7J,EAAOuM,EAAItF,UhBj1CD,GgBi1CuCsF,EAAItM,UAAYkuC,KACvFhE,GAAiBja,IACb,MAAM5S,EAAO,IAAK4S,EAAM5mB,CAACA,GAAQstC,GAEjC,OADAxC,GAAc92B,GACPA,IAEX2iB,KAAsB,CAAEwU,OAAQloC,EAAKvM,MAAO42C,GAAWtT,OAqgBvD8B,eAzhBmBA,CAAC97B,EAAe+7B,EAAqB5U,EAAgC,QACxF,MAAM1S,EAAS6mB,GAAmB1hC,IAAKgb,GAAMA,EAAE5U,OACzCutC,EAAW94B,EAAOrO,QAAQpG,GAChC,IAAiB,IAAbutC,EAAiB,OACrB,MAAMv5B,EhB3yCUw5B,EAAIC,EAAWx+B,EAAcC,KACjD,MAAM8E,EAAOy5B,EAAKliC,SACXxF,GAAQiO,EAAKwqB,OAAOvvB,EAAM,GAEjC,OADA+E,EAAKwqB,OAAOtvB,EAAI,EAAGnJ,GACZiO,GgBuyCUw5B,CAAS/4B,EAAQ84B,EAAUhtC,EAAMw7B,EAAa,EAAGtnB,EAAOnU,OAAS,IAC9EsgC,GAAiB5sB,GACjB62B,GAAa72B,GACb,MAAM/Q,EAAM2d,GAAe9L,IAAI9U,GAC3BiD,GAAKyzB,KAAsB,CAAEjI,OAAQxrB,EAAK84B,cAAawR,YAAYpmB,EAAO6S,OAkhB9ExgB,gBACAwiB,mBACA1J,UA9ecA,CAACtyB,EAAei8B,KAC9B,GAAItK,GAAsB,OAC1B,MAAM5L,GAAQ+Q,GAAc/Q,MAAQ,IAAIllB,OAAQgU,GAAMA,IAAM7U,GACtD0mB,GAASoQ,GAAcpQ,OAAS,IAAI7lB,OAAQgU,GAAMA,IAAM7U,GACjD,SAATi8B,EAAiBlW,EAAK3b,KAAKpK,GAC1B0mB,EAAMgnB,QAAQ1tC,GACnBm8B,GAAiB,CAAEpW,OAAMW,WAyezB6L,YAteiBvyB,IACjBm8B,GAAiB,CACbpW,MAAO+Q,GAAc/Q,MAAQ,IAAIllB,OAAQgU,GAAMA,IAAM7U,GACrD0mB,OAAQoQ,GAAcpQ,OAAS,IAAI7lB,OAAQgU,GAAMA,IAAM7U,MAoe3DkxB,eAheoBlxB,IAChB2xB,MAC8C,KAA7CmF,GAAc/Q,MAAQ,IAAI3f,QAAQpG,GAAsB,QACV,KAA9C82B,GAAcpQ,OAAS,IAAItgB,QAAQpG,IAAsB,SA8d9D82B,iBACAqF,oBACAnL,aACAqL,gBACAlK,cACA9C,eACAsB,kBACA8L,kBA/duB1b,IACvB,IAAI4sB,EAAYte,GAAYtO,MAAMxV,QAClCwV,EAAMpf,QAASoE,IACX,MAAM6nC,OACUlqC,IAAZqC,EAAKzE,GAAmB,IAAKyE,EAAMzE,GAAI,GAAGQ,KAAKiZ,SAASra,KAAKmtC,SAASC,SAAS,IAAIviC,MAAM,EAAG,MAASxF,EACnGmT,EAAQy0B,EAAU1S,UAAWG,QAA6B13B,IAAhB03B,EAAS95B,IAAoB85B,EAAS95B,KAAOssC,EAAOtsC,SAChG4X,EAAcy0B,EAAUvjC,KAAKwjC,GAC5BD,EAAUz0B,GAAS00B,IAExB/d,IAAmC8d,EAAUrtC,OAAS,IAAGqtC,EAAYA,EAAUpiC,WACnFolB,GAAe,IAAKtB,GAAatO,MAAO4sB,KAsdxCzd,iBAndsBnqB,IACtB4qB,GAAe,IACRtB,GACHtO,MAAOsO,GAAYtO,MAAMlgB,OAAQu6B,QACjB13B,IAAZqC,EAAKzE,GAAmB85B,EAAS95B,KAAOyE,EAAKzE,GAAK85B,IAAar1B,MAgdvEojB,gBA3coBA,CAACyT,EAA8BpX,EAA+B+J,KAClFgS,GAAc,MACdF,GAAmB,CACfviB,MAAM,EACNmK,iBAAkB2T,EAClBrN,cACA/J,SAAUA,GAAYmU,GAAWxmB,SAAWqmB,GAAQrmB,WAscxD+V,mBACA4T,eACAI,kBACAI,cACAE,qBACAjR,gBAAiB,CAAEF,QAAMC,SAAUC,GAAgBD,UACnDoR,sBACAhU,cACAuU,qBACAG,wBACAF,2BACA9M,oBACAkN,uBACAG,2BACArc,oBACAuQ,uBACAoM,qBACAC,oBACAI,eACAE,gBACAE,mBACAG,kBACAC,mBACAhG,eACA0P,WACAtL,WA5wBeA,CAACjkC,EAAqC,MACrD,GAAI2nC,GAAY,OAChB,MAAMztB,EAAsC,CACxC5b,MAAyB,iBAAXiyB,EAAsBA,OAAS5mB,KAC1C3J,GAEF0/B,GAAQtmB,SAA6B,oBAAXrc,QAC/B6qC,GAAc1tB,KAwwBdilB,KAAQA,GAAO/lB,QAAU8mB,IAE7B9jC,EAAMgc,UAAU,KACZgnB,KAAgBtgC,GAAO,CAAE2K,IAAKy2B,MAC/B,CAACphC,GAAOsgC,GAAec,KAI1B,MAAMlQ,GAAY5zB,EAAMu3B,QACpB,KAAA,CACIpD,SACA6C,cACAT,mBACAU,wBACAE,sBACAL,8BACAhB,uBACAF,yBACAI,0BACAwF,wBACAJ,wBACA0E,iCACApG,mCACAgC,sBACAI,sBACAgF,qBACAnF,wBACA5G,2BAEJ,CACIZ,EACA6C,GACAT,GACAU,GACAE,GACAL,GACAhB,GACAF,GACAI,GACAwF,GACAJ,GACA0E,GACApG,GACAgC,GACAI,GACAgF,GACAnF,GACA5G,KAIF6iB,GAAe53C,EAAMu3B,QACvB,KAAA,CACIlqB,IAAKy2B,GACLphC,SACAiwB,cACAtzB,YACAu0B,aACA1V,QAASinB,GACT9N,eAAgB+N,KAEpB,CAACtB,GAAWphC,GAAOiwB,GAAYtzB,EAAWu0B,GAAWuR,GAAoBC,KA+GvEyS,GAAoBA,CAAChD,EAAkBiD,KACzC,MAAMhrC,IAAEA,GAAQ+nC,EACVhrC,EAAQiD,EAAIjD,MAElB,GAAIA,IAAUZ,EAAgB,CAC1B,GAAuB,UAAnB6uC,EAAUC,MAAoBD,EAAUrP,MAAO,CAC/C,MAAM4I,EAAUyG,EAAUrP,MAAM9c,YAAYloB,IAAKyI,GAAMA,EAAEf,IACnDwrB,EAAgB0a,EAAQv8B,OAAe,CAACC,EAAK5J,IAAO4J,GAAO4xB,GAAY78B,IAAIqB,GAAM,EAAI,GAAI,GAC/F,OACInL,EAAAC,cAAC6uB,GAAQ,CACLhI,QAASuqB,EAAQlnC,OAAS,GAAKwsB,IAAkB0a,EAAQlnC,OACzD4c,cAAe4P,EAAgB,GAAKA,EAAgB0a,EAAQlnC,OAC5D6C,MAAO2lB,GAAWpZ,2BAClBoY,QAAUX,GAAUA,EAAMO,kBAC1BnU,SAAUA,IAAM+pB,GAAWkK,EAAS1a,IAAkB0a,EAAQlnC,QAAQ,IAGlF,CACA,GAAuB,SAAnB2tC,EAAUC,KAAiB,OAAO,KACtC,MAAMC,EAAa3Q,GAAkByQ,EAAU3sC,GAAI2sC,EAAU7sC,KACvD6b,EAAU6f,GAAY78B,IAAIguC,EAAU3sC,IAC1C,OACInL,gBAAC8uB,GAAQ,CACLhI,QAASA,EACTwL,UAAW0lB,EACXhrC,MAAO8Z,EAAU6L,GAAWnZ,6BAA+BmZ,GAAWpZ,2BACtEkY,UAAU,EACVE,QAAUX,GAAUA,EAAMO,kBAC1BnU,SAAUA,KACN0uB,GAAiB9uB,QAAU86B,EAAU3sC,GACrCg8B,GAAW,CAAC2Q,EAAU3sC,KAAM2b,EAASma,MAIrD,CAEA,GAAIp3B,IAAUX,EAA2B,CACrC,GAAuB,SAAnB4uC,EAAUC,OAAoBD,EAAU7sC,IAAK,OAAO,KACxD,MAAM3G,EAAW2jC,GAAqBn+B,IAAIguC,EAAU3sC,IAC9C8sC,EAAUrW,KAAwBsU,GAAe4B,EAAU3sC,GAAI2sC,EAAU7sC,MAC/E,OAAIgtC,UAAyD,IAAZA,EAA0B,KAEvEj4C,gBAACyuB,GAAU,CACPlpB,KAAK,QACL2jB,UAAW1e,EAAG,yBAA0BlG,GAAY,oCACpD0I,MAAO1I,EAAWquB,GAAW9Y,oBAAsB8Y,GAAW/Y,kBAAiB,gBAChEtV,EACfmtB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACNuW,GAAkBgQ,EAAU3sC,MAGhCnL,EAAAC,cAACktB,GAAc,MAG3B,CAEA,GAAItjB,IAAUb,EAAuB,CACjC,GAAuB,UAAnB8uC,EAAUC,MAAoBD,EAAUrP,MAAO,CAC/C,MAAMA,EAAQqP,EAAUrP,MAClBnkC,EAAW8sC,GAAgB3I,GAC3ByP,EAAa9V,IAAwB+V,oBAC3C,OACIn4C,EAAAC,cAAA,MAAA,CAAKipB,UAAU,sBAAsBlnB,MAAO,CAAEo2C,YAA+B,GAAlBN,EAAUjtB,QACjE7qB,EAAAC,cAACwuB,IACGlpB,KAAK,QACL2jB,UAAW1e,EAAG,wBAAyBlG,GAAY,mCACnD0I,MAAO1I,EAAWquB,GAAW9Y,oBAAsB8Y,GAAW/Y,kBAAiB,gBAChEtV,EACfmtB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACN+W,GAAwBG,EAAMt9B,IAAK7G,KAGvCtE,EAAAC,cAACmtB,UAELptB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,uBAAuBhnB,MAAOumC,EAAMjd,eAC/Cid,EAAMjd,gBAET0sB,GAAal4C,EAAAC,cAAA,OAAA,CAAMipB,UAAU,4BAAyBuf,EAAM9c,YAAYxhB,OAAe,KAGrG,CACA,OAAO,IACX,CAEA,GAAuB,UAAnB2tC,EAAUC,MAAuC,WAAnBD,EAAUC,KAAmB,CAC3D,MAAMM,EAAMP,EAAUQ,aAAazuC,GACnC,IAAKwuC,GAAOtuC,EAAMsuC,EAAIt3C,OAAQ,OAAO,KACrC,MAAMsrB,EAAKsP,GAAqB0c,EAAIhsB,IAC9BkkB,EAAc3M,GAAO5mB,QAAQ3P,IAC7BkrC,EAAaT,EAAUrP,OAAO9c,YAAY,IAAI1gB,KAAO24B,GAAO5mB,QAAQynB,aAAa,IAAIx5B,KAAO,CAAA,EAC5F+C,EAAYqe,GAAIve,eAChBue,EAAGve,eAAeuqC,EAAIt3C,OACtB+L,EAAIgB,eACFhB,EAAIgB,eAAeuqC,EAAIt3C,MAAOw3C,EAAWzrC,EAAyByjC,GAClE9iC,GAAmB4qC,EAAIt3C,MAAO+L,GACtC,OACI9M,EAAAC,cAAAD,EAAAsuB,SAAA,KACItuB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,8BAA8BmD,GAAIrf,OAASqrC,EAAIhsB,IAC/DrsB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,sBAAsBnb,GAAuBC,IAGzE,CAEA,IAAK8pC,EAAU7sC,IAAK,OAAO,KAC3B,MAAMwa,EAAS4jB,GAAgByO,EAAU3sC,GAAItB,EAAOiuC,EAAU7sC,IAAK6sC,EAAU1sB,MAE7E,GAAwB,SAApB3F,EAAOuwB,SAAqB,MAxNdvwB,KAClB,MAAM3Y,EAAM2Y,EAAOuvB,OACb/f,EAAUigB,GACZrM,GAAiBpjB,EAAOta,GAAIsa,EAAO5b,OAAO,EAAOqrC,GAC/CsD,EAASA,IAAM3P,GAAiBpjB,EAAOta,GAAIsa,EAAO5b,OAAO,EAAM,iBAgBrE,GAAIiD,EAAI2rC,eACJ,OAAO3rC,EAAI2rC,eAAe,IACnBhzB,EACHulB,aACA0N,cAAevP,GACflU,OAAQA,IAAMA,EAAO,gBACrBujB,WAGR,MAAM3xC,EAAS,CACX2oB,WAAW,EACXsC,UA1BgBd,IACE,UAAdA,EAAMlwB,KACNkwB,EAAMiB,iBACNjB,EAAMO,kBACN0D,EAAO,iBACc,WAAdjE,EAAMlwB,KACbkwB,EAAMiB,iBACNjB,EAAMO,kBACNinB,KACqB,QAAdxnB,EAAMlwB,IACbm0B,EAAO,cAEPjE,EAAMO,mBAeVgE,OAAQA,IAAMN,EAAO,gBACrBtD,QAAUX,GAA4BA,EAAMO,mBAEhD,OAAQzkB,EAAIxB,MACR,IAAK,UACD,OACItL,EAAAC,cAAC6uB,GAAQ,IACDjoB,EACJigB,QAASnc,QAAQqgC,IACjB5tB,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOO,WAG3D,IAAK,eAAgB,CACjB,MAAMljB,EAAUsJ,EAAoBJ,EAAK2Y,EAAOxa,IAAKwa,EAAOta,IAC5D,OACInL,EAAAC,cAAC0uB,GAAM,IACC9nB,EACJtB,KAAK,QACLxE,MAAOiqC,SAAgD,GAAK/9B,OAAO+9B,IACnE5tB,SAAW4T,IACP,MAAMtjB,EAAQ9J,EAAQ+J,KAAM0lB,GAAMpmB,OAAOJ,EAAeC,EAAKumB,MAAQrC,EAAMzK,OAAOxlB,OAClFooC,QAAuB57B,IAAVG,EAAsBb,EAAeC,EAAKY,GAASsjB,EAAMzK,OAAOxlB,SAGjFf,EAAAC,cAAA,SAAA,CAAQc,MAAM,KACb6C,EAAQH,IAAKmJ,IACV,MAAM7L,EAAQ8L,EAAeC,EAAKF,GAClC,OACI5M,EAAAC,cAAA,SAAA,CAAQa,IAAKmM,OAAOlM,GAAQA,MAAOkM,OAAOlM,IACrCgM,EAAeD,EAAKF,MAM7C,CACA,IAAK,SACD,OACI5M,gBAAC0uB,GAAS,IACF7nB,EACJtB,KAAK,QACL+F,KAAK,SACLvK,MAAOiqC,SAAgD,GAAKA,GAC5D5tB,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOxlB,SAG3D,IAAK,OACL,IAAK,WACD,OACIf,EAAAC,cAACyuB,GAAS,IACF7nB,EACJtB,KAAK,QACL+F,KAAmB,SAAbwB,EAAIxB,KAAkB,OAAS,iBACrCvK,MACyB,iBAAdiqC,IAA0B,qBAAqBh4B,KAAKg4B,IACrDA,GACApN,GAAiBoN,GAAwB,aAAbl+B,EAAIxB,MAE1C8R,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOxlB,SAG3D,QACI,OACIf,EAAAC,cAACyuB,GAAS,IACF7nB,EACJtB,KAAK,QACL+F,KAAK,OACLvK,MAAOiqC,SAAgD,GAAK/9B,OAAO+9B,IACnE5tB,SAAW4T,GAAUmY,GAAanY,EAAMzK,OAAOxlB,WAoHxB43C,CAAalzB,GAEpD,GAAI3Y,EAAI8rC,WAAY,OAAO9rC,EAAI8rC,WAAWnzB,GAE1C,GAAiB,YAAb3Y,EAAIxB,KAAoB,CACxB,MAAMyxB,EAAUjwB,EAAI+rC,WAAa/rC,EAAI+rC,WAAW3C,GAAe4B,EAAU3sC,GAAI2sC,EAAU7sC,MAAQ,GAC/F,OAAOjL,gBAAC88B,GAAW,CAACC,QAASA,EAAS19B,UAAWA,EAAW29B,UAAWrK,GAAW1Y,iBACtF,CAEA,GAAiB,YAAbnN,EAAIxB,KACJ,OAAIvB,EAAM0b,EAAO1kB,OAAe,KACzB0kB,EAAO1kB,MACVf,EAAAC,cAACitB,GAAS,CAAA,aAAayF,GAAWlZ,uBAElCzZ,EAAAC,cAAC4sB,GAAS,CAAA,aAAa8F,GAAWjZ,wBAI1C,MAAM1L,EAAYyX,EAAOqwB,eACzB,GAAI9nC,QAA+C,OAAO,KAC1D,GAAIhO,EAAMg0B,eAAehmB,GAAY,OAAOA,EAC5C,MAAM7O,EAAO4O,GAAuBC,GACpC,OACIhO,EAAAC,cAAA,OAAA,CAAMipB,UAAU,qBAAqBhnB,MAAO/C,EAAKgL,OAAS,GAAKhL,OAAOoO,GACjEpO,IAKP25C,GAAajE,IAAgB,CAC/Bt0C,MAAOs0C,EAAGt0C,MACViH,SAAUqtC,EAAGt0C,MACbC,SAAUq0C,EAAGt0C,MACbqvB,KAAoB,SAAdilB,EAAG/Z,OAAoB+Z,EAAG1zB,YAAS5T,EACzCgjB,MAAqB,UAAdskB,EAAG/Z,OAAqB+Z,EAAG1zB,YAAS5T,IAGzCwrC,GAAgBA,CAAClE,EAAkB9pC,IACrCP,EACkB,SAAdqqC,EAAG/Z,QAAqB,GAAG/vB,iBACb,UAAd8pC,EAAG/Z,QAAsB,GAAG/vB,kBAC5B8pC,EAAGnF,YAAc5B,GAAOuB,YAAc,GAAGtkC,sBACzC8pC,EAAGlF,cAAgB,GAAG5kC,yBAuExBiuC,GAAiBruC,QAAQ42B,IAAcC,KAAqBR,IAE5DiY,GAAmBA,CACrBnB,EACAl0C,KAEA,MAAMqjC,EAAgC,SAAnB6Q,EAAUC,MAAkBpR,GAAY78B,IAAIguC,EAAU3sC,IACnE+tC,EACiB,SAAnBpB,EAAUC,MAAmBD,EAAU7sC,KAAOq2B,GACxCA,GAAgB,IACT4U,GAAe4B,EAAU3sC,GAAI2sC,EAAU7sC,KAC1CkuC,2BAA4Bv1C,EAAQmf,MACpCq2B,eAAgBx1C,EAAQy1C,QACxBC,cAAe11C,EAAQ21C,OACvBtE,QAAS6C,EAAU1sB,YAEvB7d,EACV,OACIvN,EAAAC,cAAA,MAAA,CACIkvB,KAAK,MAAK,gBACKvrB,EAAQmf,MAAQ,EAAC,gBACE,SAAnB+0B,EAAUC,KAAkB9Q,OAAa15B,EAAS,kBAChDN,OAAO6qC,EAAU3sC,IAAG,qBACjBvH,EAAQmf,MAC5BmG,UAAW1e,EACP,eACAy8B,GAAc,yBACd+R,IAAqC,SAAnBlB,EAAUC,MAAmB,0BAC5B,UAAnBD,EAAUC,MAAoB,sBACX,cAAnBD,EAAUC,MAAwB,uBACf,WAAnBD,EAAUC,MAAqB,uBAC/Bn0C,EAAQ41C,QAAU,4BAClBN,GAEJl3C,MAAO,CACHzB,MAAOutC,GAAO+B,WACdhwC,OAAQ+D,EAAQ41C,YAASjsC,EAAY3J,EAAQ/D,OAC7C45C,UAAW71C,EAAQ41C,OAASva,QAAY1xB,GAE5CokB,QAAUX,IACiB,SAAnB8mB,EAAUC,MAAmBD,EAAU7sC,KAClC+1B,IA9jCO0Y,EAAC5B,EAAyB9mB,KACtD,GAAuB,UAAnB8mB,EAAUC,MAAoBD,EAAUrP,MAAO,CAC/C,MAAM4I,EAAUyG,EAAUrP,MAAM9c,YAAYloB,IAAKyI,GAAMA,EAAEf,IACnDwuC,EAActI,EAAQn8B,MAAO/J,GAAOw7B,GAAY78B,IAAIqB,IAE1D,YADAg8B,GAAWkK,GAAUsI,GAAa,EAEtC,CACA,GAAuB,SAAnB7B,EAAUC,KAAiB,OAC/B,MAAM5sC,EAAK2sC,EAAU3sC,GACrB,IAAKk8B,GAAkBl8B,EAAI2sC,EAAU7sC,KAAM,OAC3C,MAAMutB,GAAYyI,GAClB,GAAIjQ,EAAM4oB,UAAYphB,GAAyC,OAA7BsT,GAAiB9uB,QAAkB,CACjE,MAAMzR,EAAMo5B,GAAUj6B,OAAQk6B,GAAmB,SAAZA,EAAGt5B,MAAiB7H,IAAKmhC,GAAOA,EAAGz5B,IAClE2N,EAAOvN,EAAI0E,QAAQ67B,GAAiB9uB,SACpCjE,EAAKxN,EAAI0E,QAAQ9E,GACvB,IAAa,IAAT2N,QAAeC,EAAW,CAC1B,MAAOpI,EAAGC,GAAKkI,EAAOC,EAAK,CAACD,EAAMC,GAAM,CAACA,EAAID,GAE7C,YADAquB,GAAW57B,EAAI6J,MAAMzE,EAAGC,EAAI,IAAI,GAAOkwB,KAAsB9P,EAAM6oB,UAAY7oB,EAAM8oB,QAEzF,CACJ,CACAhO,GAAiB9uB,QAAU7R,EAC3B,MAAM87B,EAAaN,GAAY78B,IAAIqB,GACX21B,IAAsB9P,EAAM6oB,SAAY7oB,EAAM8oB,QAKlE3S,GAAW,CAACh8B,IAAM87B,GAAY,GAH1BA,GAAmC,IAArBN,GAAYphC,KAAY4hC,GAAW,CAACh8B,IAAK,GAAO,GAC7Dg8B,GAAW,CAACh8B,IAAK,GAAM,IAoiCiBuuC,CAAwB5B,EAAW9mB,GACpEuQ,KAAa2U,GAAe4B,EAAU3sC,GAAI2sC,EAAU7sC,KAAM+lB,EAAO6S,OACvC,UAAnBiU,EAAUC,MAAoBD,EAAUrP,OAC/CH,GAAwBwP,EAAUrP,MAAMt9B,IAAKimC,GAAgB0G,EAAUrP,SAG/E7W,cAAgBZ,IACW,SAAnB8mB,EAAUC,MAAmBD,EAAU7sC,KACvCu2B,KAAmB0U,GAAe4B,EAAU3sC,GAAI2sC,EAAU7sC,KAAM+lB,EAAO6S,QAI9EiK,GAAO5vB,QAAQza,IAAKoxC,GAzHd+D,EAAC/D,EAAkBiD,KAClC,MAAMhrC,IAAEA,GAAQ+nC,EACVhrC,EAAQiD,EAAIjD,MACZkwC,EAAYpvC,QAAQsgC,IAAeA,GAAY9/B,KAAO2sC,EAAU3sC,IAAM8/B,GAAYphC,QAAUA,GAC5FmwC,EAAYrvC,QAAQs+B,IAAeA,GAAY99B,KAAO2sC,EAAU3sC,IAAM89B,GAAYp/B,QAAUA,GAC5FowC,GACkB,UAAnBnC,EAAUC,MAAuC,WAAnBD,EAAUC,OAAsBptC,QAAQmtC,EAAUQ,aAAazuC,IAC5F4b,EACiB,SAAnBqyB,EAAUC,MAAmBD,EAAU7sC,IACjCo+B,GAAgByO,EAAU3sC,GAAItB,EAAOiuC,EAAU7sC,IAAK6sC,EAAU1sB,MAC9D,KACJ7Y,IAAWkT,GAASsvB,GAAiBtvB,GACrCyzB,EACFzzB,GAAU3Y,EAAIotC,cACqB,mBAAtBptC,EAAIotC,cACPptC,EAAIotC,cAAcz0B,GAClB3Y,EAAIotC,mBACR3sC,EACJ4sC,EAAatwC,IAAUZ,EACvBmxC,EAAiBvwC,IAAUX,EACjC,OACIlJ,EAAAC,cAAA,MAAA,CACIa,IAAK+I,EACLslB,KAAK,WAAU,iBACCtlB,EAAK,oBACFikC,GAAO5vB,QAAQjO,QAAQ4kC,GAC1CpjB,SAAUsoB,EAAY,GAAI,EAAE,gBACM,SAAnBjC,EAAUC,KAAkBpR,GAAY78B,IAAIguC,EAAU3sC,SAAMoC,EAC3E2b,UAAW1e,EACP,gBACA,wBAAwBsC,EAAIgF,OAAS,SACrCinC,GAAclE,EAAI,iBAClBkF,IAAcC,GAAa,yBAC3BA,GAAa,yBACbznC,IAAaynC,GAAa,0BACb,YAAbltC,EAAIxB,MAAsB,yBACb,YAAbwB,EAAIxB,MAAsB,yBAC1B6uC,GAAc,0BACdC,GAAkB,+BAClBH,GAAiB,6BACjBf,GAEJl3C,MAAO82C,GAAUjE,GACjBhjB,YAAaA,KACc,SAAnBimB,EAAUC,MAAsC,UAAnBD,EAAUC,MAClCgC,GAAWvQ,GAAe,CAAEr+B,GAAI2sC,EAAU3sC,GAAItB,WAG3D8nB,QAAUX,IACFvL,GAAUgc,IAAaA,GAAYhc,EAAQuL,EAAO6S,OAE1DjS,cAAgBZ,IACRvL,IACAic,KAAoBjc,EAAQuL,EAAO6S,MAC/BtxB,IAAaynC,IACbhpB,EAAMO,kBACNqX,GAAkBkP,EAAU3sC,GAAItB,OAK3CguC,GAAkBhD,EAAIiD,KA4DKc,CAAW/D,EAAIiD,EAAWl0C,EAAQ41C,SAC9Dx5C,EAAAC,cAAA,MAAA,CAAKipB,UAAU,0BAKrBmxB,GAAezV,IAAiB,CAClCz5B,GAAIy5B,EAAGz5B,GACP4sC,KAAMnT,EAAGt5B,KACTL,IAAK25B,EAAG35B,IACRmgB,KAAMwZ,EAAGxZ,KACTP,MAAO+Z,EAAG/Z,MACV4d,MAAO7D,EAAG6D,MACV6P,WAAwB,UAAZ1T,EAAGt5B,MAAoBs5B,EAAG6D,MAAQkK,GAAmB/N,EAAG6D,YAASl7B,IAqD3E+sC,GAAmBA,CAAChD,EAAuB1xC,KAC7C,MAAMglB,EAA2B,GAsBjC,IArBC0sB,GAAQ,IAAI9rC,QAAQ,CAACP,EAAK8X,KACvB,MAAM5X,EAAKH,EAAgBC,EAAKC,GAC1B4sC,EAA0B,CAC5B3sC,KACA4sC,KAAM,YACN9sC,MACAmgB,KAAM,CAAE9f,KAAM,YAAaH,KAAI0f,MAAO,EAAGQ,OAAQ,KAAMzlB,YACvDilB,MAAO,GAEXD,EAAM3W,KACFjU,gBAACA,EAAMsuB,SAAQ,CAACxtB,IAAKmM,OAAO9B,IACvB8tC,GAAiBnB,EAAW,CACzBj4C,OAAQo/B,GACRlc,MAAOA,EACPs2B,SAAS,EACTE,QAAQ,EACRC,QAAQ,QAKP,WAAb5zC,GAAyB4sC,GAAkB,CAC3C,MAAMsF,EAA0B,CAC5B3sC,GAAIhC,EACJ4uC,KAAM,SACN9sC,IAAK,KACLmgB,KAAM,CAAE9f,KAAM,SAAUH,GAAIhC,EAAuB0hB,MAAO,EAAGQ,OAAQ,MACrER,MAAO,EACPytB,WAAY9F,IAEhB5nB,EAAM3W,KACFjU,EAAAC,cAACD,EAAMsuB,SAAQ,CAACxtB,IAAKqI,GAChB8vC,GAAiBnB,EAAW,CACzBj4C,OAAQo/B,GACRlc,MAAO,EACPs2B,SAAS,EACTE,QAAQ,EACRC,QAAQ,KAIxB,CACA,OAAO5uB,GAKL2vB,GAAmBA,CAAC1F,EAAkB9xB,KACxC,MAAMjW,IAAEA,GAAQ+nC,EACVhrC,EAAQiD,EAAIjD,MACZ2wC,EAAY3f,GAAUiK,UAAWl1B,GAASA,EAAK/F,QAAUA,GAAS+F,EAAKyF,MACvEulB,GAAyB,IAAd4f,EAAmB3f,GAAU2f,QAAajtC,EACrDyE,GACgB,IAAjBlF,EAAIkF,WAAuBopB,KAAyBxxB,EAAgBC,IACpEA,IAAUb,IAA0C,IAAjB8D,EAAIkF,SACtCq7B,GACA76B,KAAsB1F,EAAI0F,oBAAsB5I,EAAgBC,IACjEA,IAAUb,IAA0BwJ,GACnCL,GACAsuB,KAAyC,IAAlB3zB,EAAIqF,YAAwBvI,EAAgBC,IACpEA,IAAUb,IAA0By3B,GACnCga,EAAYzD,GAAWlqC,GACvB4tC,EAAahP,IAAM7hC,QAAUA,EAC7B8wC,EAAejP,IAAQA,GAAKkP,YAAc/wC,GAAS6hC,GAAK7hC,QAAUA,EAClEgxC,EAAW1P,IAAYthC,QAAUA,EACjCixC,EAAe,CAAEjxC,QAAOmrC,OAAQloC,EAAyBO,IAAKy2B,IAC9DoV,EAAcpsC,EAAIiuC,gBACa,mBAAxBjuC,EAAIiuC,gBACPjuC,EAAIiuC,gBAAgBD,GACpBhuC,EAAIiuC,qBACRxtC,EAEN,IAAI0qC,EA0BJ,OAxBIA,EADApuC,IAAUZ,EACAg4B,GAA8B,KACpCjhC,EAAAC,cAAC6uB,IACGhI,QAASktB,GACTjtB,cAAektB,GACf3hB,SAAyC,IAA/BwhB,GAAoB3pC,OAC9B6C,MACIgnC,GACMrhB,GAAWrZ,iCACXqZ,GAAWtZ,+BAErB+D,SAAUo3B,GACV7iB,QAAUX,GAAUA,EAAMO,oBAG3B1nB,IAAUX,EACP,KAEA4D,EAAIuhC,aACVvhC,EAAIuhC,aAAayM,GAEjB96C,EAAAC,cAAA,OAAA,CAAMipB,UAAU,yBAAyBpc,EAAI+E,YAAchI,GAK/D7J,EAAAC,cAAA,MAAA,CACIa,IAAK+I,EACLslB,KAAK,+BACUpM,EAAQ,EAAC,YACb6X,EAA8B,QAAlBA,EAASvlB,KAAiB,YAAc,aAAgBrD,EAAW,YAASzE,EAAS,iBAC5F1D,EAChB3H,MAAO4K,EAAIkuC,YACXvpB,UAAU,EACVgpB,UAAWA,EACXvxB,UAAW1e,EACP,uBACA,+BAA+BsC,EAAIiF,aAAe,SAClDgnC,GAAclE,EAAI,wBAClB7iC,GAAY,iCACZnI,IAAUZ,GAAkB,iCAC5BY,IAAUX,GAA6B,sCACvC6Z,IAAU+qB,GAAO5vB,QAAQ/T,OAAS,GAAK,6BACvCuwC,GAAc,iCACdC,GAA+B,SAAfjP,IAAM5F,MAAmB,kCACzC6U,GAA+B,UAAfjP,IAAM5F,MAAoB,mCAC1C+U,GAAY,kCACZ3B,GAEJl3C,MAAO82C,GAAUjE,GACjBljB,QAAUX,IACDhf,IAAYq5B,IACjBrP,GAAWnyB,OAAO0D,EAAWyjB,EAAM4oB,WAEvCqB,YAAcjqB,IACV,GAAKypB,EAAL,CACAzpB,EAAMkqB,aAAaC,cAAgB,OACnC,IACInqB,EAAMkqB,aAAaE,QAAQ,aAAcvxC,EAC7C,CAAE,MACE,CAEJ8hC,GAAQ,CAAE9hC,QAAO+wC,UAAW,KAAM9U,KAAM,QAPxB,GASpBuV,WAAarqB,IACT,IAAK0a,IAAQA,GAAK7hC,QAAUA,EAAO,OACnC,MAAMyxC,EAAWxN,GAAO5vB,QAAQvQ,KAAM8Q,GAAMA,EAAE3R,IAAIjD,QAAU6hC,GAAK7hC,OACjE,IAAKyxC,GAAYA,EAASxgB,SAAW+Z,EAAG/Z,SAAWkc,GAAWlqC,GAAM,OACpEkkB,EAAMiB,iBACNjB,EAAMkqB,aAAaK,WAAa,OAChC,MAAMC,EAAOxqB,EAAMiC,cAAc3C,wBAC3BwV,EAAO9U,EAAMyqB,QAAUD,EAAK5rB,KAAO4rB,EAAKj7C,MAAQ,EAAI,OAAS,QAC/DmrC,GAAKkP,YAAc/wC,GAAS6hC,GAAK5F,OAASA,GAAM6F,GAAQ,IAAKD,GAAMkP,UAAW/wC,EAAOi8B,UAE7F4V,YAAaA,KACLhQ,IAAQA,GAAKkP,YAAc/wC,GAAO8hC,GAAQ,IAAKD,GAAMkP,UAAW,QAExEe,OAAS3qB,GAh2BF4qB,EAACC,EAAwB7qB,KACxCA,EAAMiB,iBACN,MAAMjV,EAAU0uB,GAEhB,GADAC,GAAQ,OACH3uB,GAAWA,EAAQnT,QAAUgyC,EAAS/uC,IAAIjD,MAAO,OACtD,MAAMyxC,EAAWxN,GAAO5vB,QAAQvQ,KAAMknC,GAAOA,EAAG/nC,IAAIjD,QAAUmT,EAAQnT,OACtE,IAAKyxC,GAAYA,EAASxgB,SAAW+gB,EAAS/gB,SAAWkc,GAAW6E,EAAS/uC,KAAM,OACnF,MAAMg5B,EAAO9oB,EAAQ8oB,KACrB,GAAIwV,EAASxgB,OAAQ,CACjB,MAAMh6B,EAAMw6C,EAASxgB,OACfwc,GAAQ3W,GAAc7/B,IAAQ,IAAIsU,QAClC0D,EAAOw+B,EAAKrnC,QAAQ+M,EAAQnT,OAClC,IAAIkP,EAAKu+B,EAAKrnC,QAAQ4rC,EAAS/uC,IAAIjD,OACnC,IAAa,IAATiP,QAAeC,EAAW,OAK9B,OAJAu+B,EAAKjP,OAAOvvB,EAAM,GAClBC,EAAKu+B,EAAKrnC,QAAQ4rC,EAAS/uC,IAAIjD,OAC/BytC,EAAKjP,OAAgB,UAATvC,EAAmB/sB,EAAK,EAAIA,EAAI,EAAGiE,EAAQnT,YACvDm8B,GAAiB,IAAKrF,GAAe7/B,CAACA,GAAMw2C,GAEhD,CACA,MAAMh5B,EAAS6mB,GAAmB1hC,IAAKgb,GAAMA,EAAE5U,OACzCiP,EAAOwF,EAAOrO,QAAQ+M,EAAQnT,OAC9BiyC,EAAUx9B,EAAO5T,OAAQgU,GAAMA,IAAM1B,EAAQnT,OACnD,IAAIkP,EAAK+iC,EAAQ7rC,QAAQ4rC,EAAS/uC,IAAIjD,OACzB,UAATi8B,IAAkB/sB,GAAM,GAC5B+iC,EAAQzT,OAAOtvB,EAAI,EAAGiE,EAAQnT,OAC9B4gC,GAAiBqR,GACjBpH,GAAaoH,GACb,MAAMhvC,EAAM2d,GAAe9L,IAAI3B,EAAQnT,OACnCiD,GAAKyzB,KAAsB,CAAEjI,OAAQxrB,EAAK84B,YAAa7sB,EAAIq+B,SAAUt+B,GAAQkY,EAAO6S,OAm0B7D+X,CAAW/G,EAAI7jB,GAClC+qB,UAAWA,IAAMpQ,GAAQ,OAEzB3rC,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mCACV+uB,EACAjmC,GACGhS,EAAAC,cAAA,OAAA,CACIipB,UAAW1e,EAAG,qBAAsBowB,GAAY,4CACpC,QAEQ,SAAnBA,GAAUvlB,KAAkBrV,EAAAC,cAAC+sB,GAAiB,CAACznB,KAAM,KAASvF,EAAAC,cAAC8sB,GAAe,CAACxnB,KAAM,KACrFq1B,GAAYC,GAAUnwB,OAAQwF,GAAMA,EAAEmF,MAAMlL,OAAS,GAClDnK,EAAAC,cAAA,OAAA,CAAMipB,UAAU,uBAAuBsxB,EAAY,KAKlEnN,GACGrtC,EAAAC,cAACwuB,GAAU,CACPlpB,KAAK,QACL2jB,UAAW1e,EAAG,2BAA4BqwC,GAAY,kCACtD7tC,MAAO2lB,GAAWxY,gCACJ,OAAM,gBACL0gC,EACfppB,UAAU,EACVE,QAAUX,IACNA,EAAMO,kBACN6Z,GAAe3a,GACXA,GAAM5mB,QAAUA,EAAQ,KAAO,CAAEA,QAAOwlB,SAAU2B,EAAMiC,iBAGhEpB,YAAcb,GAAUA,EAAMO,mBAE9BvxB,EAAAC,cAACgtB,GAAY,OAGpB9a,GACGnS,EAAAC,cAAA,MAAA,CACIipB,UAAW1e,EAAG,yBAA0B6gC,KAAkBxhC,GAAS,kCACnEslB,KAAK,+BACY,WACjB6sB,cAAgBhrB,GA91BVirB,EAACpH,EAAkB7jB,KACzCA,EAAMiB,iBACNjB,EAAMO,kBACN0lB,GAAUj6B,QAAU,CAChBnT,MAAOgrC,EAAG/nC,IAAIjD,MACdqyC,OAAQlrB,EAAMyqB,QACdU,WAAYtH,EAAGt0C,MACf67C,UAAWvH,EAAGt0C,MACd8J,IAAKwqC,EAAG/nC,IAAItF,UhBrvDgB,GgBsvD5B8C,IAAKuqC,EAAG/nC,IAAItM,UAAYkuC,KAE5BpD,GAAiBuJ,EAAG/nC,IAAIjD,OACxB,MAAMwyC,EAAUhY,IACZ,MAAMlf,EAAI8xB,GAAUj6B,QACpB,IAAKmI,EAAG,OACR,MAAM5kB,EAAQ6J,EAAM+a,EAAEg3B,YAAc9X,EAAEoX,QAAUt2B,EAAE+2B,QAAS/2B,EAAE9a,IAAK8a,EAAE7a,KACpE6a,EAAEi3B,UAAY77C,EACdmqC,GAAiBja,GAAUA,EAAKtL,EAAEtb,SAAWtJ,EAAQkwB,EAAO,IAAKA,EAAM,CAACtL,EAAEtb,OAAQtJ,KAEhF+7C,EAAOA,KACT37C,OAAOkwB,oBAAoB,cAAewrB,GAC1C17C,OAAOkwB,oBAAoB,YAAayrB,GACxC,MAAMn3B,EAAI8xB,GAAUj6B,QAGpB,GAFAi6B,GAAUj6B,QAAU,KACpBsuB,GAAiB,OACZnmB,EAAG,OACR,MAAMtH,EAAO,IAAM+lB,GAAO5mB,QAAQqG,aAAyC,CAAC8B,EAAEtb,OAAQsb,EAAEi3B,WACxF1R,GAAgB7sB,GAChB82B,GAAc92B,GACd,MAAM/Q,EAAM82B,GAAO5mB,QAAQqoB,UAAUlgB,EAAEtb,OACnCiD,GAAOqY,EAAEi3B,YAAcj3B,EAAEg3B,YACzB3b,KAAsB,CAAEwU,OAAQloC,EAAKvM,MAAO4kB,EAAEi3B,WAAavY,OAEnEljC,OAAOopB,iBAAiB,cAAesyB,GACvC17C,OAAOopB,iBAAiB,YAAauyB,IA4zBKL,CAAkBpH,EAAI7jB,GAChDW,QAAUX,GAAUA,EAAMO,kBAC1BK,cAAgBZ,IACZA,EAAMO,kBACNsU,GAAgB,CAAE3nB,QAAS,CAACrU,MAEhC4wC,WAAW,EACXQ,YAAcjqB,IACVA,EAAMiB,iBACNjB,EAAMO,uBAUxBgrB,GAAgC,OAAlBzd,EAAM0d,QAAmB,KAAQ1d,EAAM0d,SAAWl7C,GAChEm7C,GAA8B,OAAjB3d,EAAM4d,OAAkB,KAAQ5d,EAAM4d,QAAUhmB,GAC7DimB,GAAoB7d,EAAM8d,eAAiBngB,GAC3CogB,GAAqB/d,EAAMge,gBAAkBngB,GAC7CogB,GAAqB,IAAKle,KAAiBr5B,EAAUg3C,SACrDQ,GAAc,CAAE79C,KAAM4/B,KAAev5B,EAAUo3C,eAC/CK,GAAe,IAAKz3C,EAAUs3C,gBAE9BI,IAAcjf,GAAgC,IAArB0G,GAAUx6B,OACnCgzC,GAAahS,GAAa9F,GAAU8F,GAAWthC,YAAS0D,EAExD6vC,GAAkC,CACpCv9C,OAAQ,OACR6nB,SAAU,KACPiW,GAAca,MACdb,GAAcY,MACbI,GAEF0e,GAAiC,CAAE31B,SAAU,KAAMiW,GAAce,MAAWf,GAAcc,IAC1F6e,GAAkC,IACjC3f,GAAcr9B,MACdq9B,GAAc37B,GACjB,2BAAqC,GAAG2qC,OACxC,0BAAoCC,GACpC,wBAAkC,GAAG3N,QAInCse,GAAYv9C,EAAMu3B,QAAQ,KAC5B,MAAMzO,EAAgB,GAOtB,OANAnV,GAAe,sBAAsBsvB,OAAY3iC,EAAIwoB,GACrDnV,GAAe,sBAAsBsvB,OAAYjhC,EAAO8mB,GACxDnV,GAAe,wBAAwBsvB,OAAYzE,EAAQ1V,GAC3DnV,GAAe,wBAAwBsvB,OAAY1E,EAAWzV,GAC9DnV,GAAe,uBAAuBsvB,OAAYvE,EAAO5V,GACzDnV,GAAe,uBAAuBsvB,OAAYxE,EAAU3V,GACrDA,EAAIle,KAAK,OACjB,CAACq4B,GAAQ3iC,EAAI0B,EAAOw8B,EAAQD,EAAWG,EAAOD,IAE3C+e,GAAStR,GAAgB,GAAKA,GAAgB,IAE9CuR,GACFz9C,EAAAC,cAAA,MAAA,CACIkF,IAAKk+B,GACLl4B,GAAI83B,GAAM,mBACQA,GAClB9T,KAAK,OAAM,gBACIkH,GAAW,EAAC,gBACZyX,GAAO5vB,QAAQ/T,OAAM,0BACd22B,IAAsBG,UAAqC1zB,EAAS,YAC/E0wB,QAAW1wB,EACtB2b,UAAW1e,EACP,YACC60B,GAAcoM,KAAa,wBAC5BA,IAAY,sBACXqC,GAAOuB,YAAc,6BACtBnmB,GAEJlnB,MAAOs7C,GACPxrB,UAhjCed,IACnB,GAAIiY,GAAa,OACjB,MAAM1iB,EAASyK,EAAMzK,OACrB,GACIA,IACoB,UAAnBA,EAAOK,SACe,WAAnBL,EAAOK,SACY,aAAnBL,EAAOK,SACY,WAAnBL,EAAOK,SAEX,OAEJ,MAAM82B,EAAWnzC,KAAKD,IAAI,EAAGC,KAAK2Y,MAAM3Y,KAAKD,IAAI6hC,GAAiBQ,GAAc1N,IAAaA,KAC7F,OAAQjO,EAAMlwB,KACV,IAAK,YACDkwB,EAAMiB,iBACN2kB,GAAU,EAAG,GACb,MACJ,IAAK,UACD5lB,EAAMiB,iBACN2kB,IAAU,EAAI,GACd,MACJ,IAAK,YACD5lB,EAAMiB,iBACN2kB,GAAU,MACV,MACJ,IAAK,aACD5lB,EAAMiB,iBACN2kB,GAAU,EAAG,GACb,MACJ,IAAK,WACD5lB,EAAMiB,iBACN2kB,GAAU8G,EAAU,GACpB,MACJ,IAAK,SACD1sB,EAAMiB,iBACN2kB,IAAW8G,EAAU,GACrB,MACJ,IAAK,OACD1sB,EAAMiB,iBACN2kB,GAAU,EAAG,EAAG5lB,EAAM6oB,SAAW7oB,EAAM8oB,QAAU,CAAE7uC,IAAK,QAAS6B,IAAK,SAAY,CAAEA,IAAK,UACzF,MACJ,IAAK,MACDkkB,EAAMiB,iBACN2kB,GAAU,EAAG,EAAG5lB,EAAM6oB,SAAW7oB,EAAM8oB,QAAU,CAAE7uC,IAAK,OAAQ6B,IAAK,QAAW,CAAEA,IAAK,SACvF,MACJ,IAAK,QACL,IAAK,KACD,GAAIm+B,GAAa,CACb,MAAM7f,EAAOmZ,GAAU5lB,IAAIssB,GAAY9/B,IACvC,GAAmB,UAAfigB,GAAM9f,MAAoB2/B,GAAYphC,QAAUb,EAAuB,CACvE,MAAMy/B,EAAQC,GAAW/pB,IAAIssB,GAAY9/B,IACrCs9B,GAAOH,GAAwBG,EAAMt9B,IAAKimC,GAAgB3I,GAClE,MACIzX,EAAMiB,iBACN2W,GAAkBqC,GAAY9/B,GAAI8/B,GAAYphC,MAEtD,CACA,MACJ,IAAK,IACD,GAAIohC,KAAgBnK,KAAsBE,IAA6B,CACnE,MAAM4D,EAAKD,GAAUh3B,KAAMwX,GAAMA,EAAEha,KAAO8/B,GAAY9/B,IAClDy5B,GAAkB,SAAZA,EAAGt5B,MAAmBs5B,EAAG35B,MAC/B+lB,EAAMiB,iBACNkV,GAAW,CAACvC,EAAGz5B,KAAMw7B,GAAY78B,IAAI86B,EAAGz5B,KAAK,GAErD,CACA,MACJ,IAAK,SACG0nB,GAAgBlK,MAAMoK,KACtBoY,IAAYC,GAAc,MAC9B,MACJ,SAESpa,EAAM6oB,SAAW7oB,EAAM8oB,UACI,MAA5B9oB,EAAMlwB,IAAI4O,eACVoxB,KACCG,KAEDjQ,EAAMiB,iBACNkV,GAAW2M,IAAqB,OAk+BvClV,GAAe2d,IACZv8C,EAAAC,cAAA,MAAA,CAAKkF,IAAKq+B,IACNxjC,EAAAC,cAACs8C,GAAW,IAAKQ,MAGzB/8C,EAAAC,cAAA,MAAA,CAAKipB,UAAU,iBACXlpB,EAAAC,cAAA,MAAA,CAAKkF,IAAKo+B,GAAara,UAAU,oBAAoBy0B,SAAUhK,GAAcliB,UAAU,GACnFzxB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBAAmBiG,KAAK,WAAWntB,MAAO,CAAEzB,MAAOutC,GAAO+B,aACrE7vC,EAAAC,cAAA,MAAA,CAAKipB,UAAU,sBAAsBiG,KAAK,MAAK,gBAAgB,EAAGntB,MAAO,CAAEnC,OAAQ8sC,KAC9EmB,GAAO5vB,QAAQza,IAAI,CAACoxC,EAAI9xB,IAAUw3B,GAAiB1F,EAAI9xB,IACxD/iB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,6BAGtByY,IAAYhS,KAAOgS,GAAWhS,IAAIxlB,OAAS,GACxCnK,EAAAC,cAAA,MAAA,CACIipB,UAAU,iDACViG,KAAK,WACLntB,MAAO,CAAE2tB,IAAKgd,GAAcpsC,MAAOutC,GAAO+B,aAEzCyK,GAAiB3Y,GAAWhS,IAAK,QAG1C3vB,EAAAC,cAAA,MAAA,CACIipB,UAAW1e,EAAG,gBAAiB2oC,GAAU,yBAA2B,uBACpEhkB,KAAK,WACLntB,MACImxC,GACM,CACItzC,OAA6B,IAArB8kC,GAAUx6B,OAAeI,KAAKD,IAAIuoC,GAAQ3xB,MAAO,KAAO2xB,GAAQ3xB,MACxE3gB,MAAOutC,GAAO+B,YAElB,CAAEtvC,MAAOutC,GAAO+B,WAAY4J,UAAWyD,IAAcjf,EAAU,SAAM1wB,IAlW5EqwC,MACnB,MAAMx/C,MAAEA,EAAKC,IAAEA,GAAQ+0C,GACjBxoB,EAA2B,GACjC,IAAK,IAAI9J,EAAI1iB,EAAO0iB,EAAIziB,EAAKyiB,GAAK,EAAG,CACjC,MAAM8jB,EAAKD,GAAU7jB,GACfg3B,EAAYuC,GAAYzV,GACxBiZ,EAAehL,GAAQE,cAAcjyB,GACrCsU,EACU,SAAZwP,EAAGt5B,MAAmBX,QAAQi6B,EAAG35B,MAAQN,QAAQi3B,KAA0BqG,GAAqBn+B,IAAI86B,EAAGz5B,IACrG2yC,EAAgB1oB,GAAcwP,EAAG35B,IAAM22B,KAAwBsU,GAAetR,EAAGz5B,GAAIy5B,EAAG35B,MAAQ,KAChG8yC,KACF3oB,GAAcwP,EAAG35B,KAAO42B,KACmC,SAArDA,GAAqB,CAAE12B,GAAIy5B,EAAGz5B,GAAIF,IAAK25B,EAAG35B,MAE9C+yC,IACD7K,KACA/T,GAA4B,SAAZwF,EAAGt5B,OAAmBs5B,EAAG35B,KAC0B,SAA9Dm0B,EAAa,CAAEj0B,GAAIy5B,EAAGz5B,GAAIusB,MAAOkN,EAAG35B,IAAKwhC,oBAEnD7hB,EAAM3W,KACFjU,EAAAC,cAAA,MAAA,CACIa,IAAKmM,OAAO23B,EAAGz5B,IACf+d,UAAU,qBACVlnB,MAAOmxC,GAAU,CAAExjB,IAAKkjB,GAAQG,QAAQlyB,GAAIvgB,MAAOutC,GAAO+B,YAAe,CAAEtvC,MAAOutC,GAAO+B,aAExFoJ,GAAiBnB,EAAW,CACzBj4C,OAAQgzC,GAAQC,WAAWhyB,GAC3BiC,MAAOjC,EACPu4B,QAAe,IAANv4B,EACTy4B,OAAQz4B,IAAM6jB,GAAUx6B,OAAS,EACjCqvC,OAAQwE,IAEX5oB,SAAc0oB,IAA2E,IAAlBA,GACpE99C,EAAAC,cAAA,MAAA,CACIipB,UAAU,wBACVlnB,MAAO,CACHnC,OAAQk+C,OAAaxwC,EAAYswC,QAAgBtwC,EACjDhN,MAAO2rC,SAAiB3+B,GAE5BokB,QAAUX,GAAUA,EAAMO,mBAEzBusB,IAKrB,CACA,OAAOlzB,GAsTUgzB,KAEFjc,IAAYnR,QAAUmR,GAAWnR,OAAOrmB,OAAS,GAAMqoC,KACtDxyC,EAAAC,cAAA,MAAA,CACIipB,UAAU,oDACViG,KAAK,WACLntB,MAAO,CAAEzB,MAAOutC,GAAO+B,aAEtByK,GAAiB3Y,IAAYnR,OAAQ,YAIjDyN,GACGj+B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,6CAA6ClnB,MAAO,CAAE2tB,IAAKgd,KACtE3sC,EAAAC,cAAC48C,GAAkB,IAAKI,MAG/BC,IACGl9C,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBAAmBlnB,MAAO,CAAE2tB,IAAKgd,KAC5C3sC,EAAAC,cAAC08C,GAAiB,IAAKK,QAIjC/2B,IAAcw2B,IAAcz8C,EAAAC,cAACw8C,GAAU,IAAKj3C,EAAUk3C,SAExD18C,EAAAC,cAACmvB,IACGzG,KAAMkK,GAAgBlK,KACtB0G,SAAUwD,GAAgBxD,SAC1BC,QAASyD,GACT1zB,UAAWA,EACXkwB,UAAU,eACVC,WAAS,GAE6B,YAArCqD,GAAgBC,iBAAiC9yB,EAAAC,cAACm3B,GAAmB,MAAMp3B,EAAAC,cAAC+4B,GAAkB,OAGlGmkB,IAAchS,IACXnrC,EAAAC,cAACw6B,IACGnC,OAAQ6kB,GACR9tB,SAAU8b,GAAW9b,SACrB1G,QACA2G,QAASA,IAAM8b,GAAc,MAC7B/rC,UAAWA,EACXq7B,cAAe8I,GAAWxmB,WAM1C,OACIhd,gBAACuc,GAAe0hC,SAAQ,CAACl9C,MAAO62C,IAC5B53C,EAAAC,cAAA,MAAA,CACIkF,IAAKm+B,GACLpa,UAAW1e,EAAG,gBAAiB4zB,GAAe,uBAAwBC,GAAc,iBACpEh/B,uBACI4jC,GACpBjhC,MAAOo7C,IAENG,IAAav9C,EAAAC,cAAA,QAAA,CAAA,mBAAyBgjC,IAASsa,KAC9Cnf,SAA2B7wB,IAAX4mB,GAAwBgK,GAA6BD,IACnEl+B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,6BACC3b,IAAX4mB,GAAwBn0B,EAAAC,cAAA,KAAA,CAAIipB,UAAU,uBAAuBiL,GAC7DgK,GACGn+B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,+BAA+BiV,GAElDn+B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,2BAA2BlnB,MAAO,CAAEu6B,IAAKihB,GAAS,EAAI,KAChEtf,IAIbl+B,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,EAAG,eAAgB8zB,GAAa,oBAAqB2E,GAAQjhC,MAAOq7C,IAC/EI,KAKrB,CAEA1f,GAAQthB,YAAc,UCzyFf,MAAMyhC,GAAiC,iBAOjCC,GAA4B,uwfAuLzC,IAAIviC,IAAW,EAEf,MAcMC,GACD7b,EAAc8b,qBAAyC,oBAAXnb,OAAyBX,EAAM+b,gBAAkB/b,EAAMgc,WAG3FoiC,GAA8BA,KACvCviC,GAAa,KAnBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAe+hC,IAExB,YADAtiC,IAAW,GAGf,MAAM5Z,EAAQwY,SAASva,cAAc,SACrC+B,EAAMmJ,GAAK+yC,GACXl8C,EAAMoa,aAAa,eAAgB,QACnCpa,EAAMqa,YAAc8hC,GACpB3jC,SAAS8B,KAAKjB,YAAYrZ,GAC1B4Z,IAAW,GASPM,IACD,KC/MDoQ,GAAaA,CAACvB,EAAuBtO,KACvC,MAAMnW,EAAOtG,EAAMoG,WAAiD,EAAGb,OAAO,GAAI2jB,YAAWlnB,WAAUuqB,GAAQpnB,IAC3GnF,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLqnB,QAAQ,YACRjsB,MAAOgF,EACP1F,OAAQ0F,EACRzF,KAAK,eACL2sB,UAAU,QAAO,cACL,OACZvD,UAAW,CAAC,eAAgBA,GAAWxe,OAAOC,SAASC,KAAK,KAC5D5I,MAAOA,KACHuqB,GAEHxB,IAIT,OADAzkB,EAAKmW,YAAcA,EACZnW,GAGE+3C,GAAgB/xB,GACzBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,uKACR,iBAESmhB,GAAkBf,GAC3BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,6DACR,mBAESkhB,GAAmBd,GAC5BtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,2DACR,oBAES2gB,GAAYP,GACrBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,0GACR,aAGSoyC,GAAehyB,GACxBtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,6IACR,gBAESqyC,GAAoBjyB,GAAWtsB,EAAAC,cAAA,OAAA,CAAMiM,EAAE,mBAAqB,sKCzCzEH,EAAMyyC,OAAOC,GAEN,MAAMj0C,GAAKA,IAAIC,IAAyDA,EAAWC,OAAOC,SAASC,KAAK,KAElGR,GAAQA,CAACrJ,EAAesJ,EAAaC,IAAgBC,KAAKF,IAAIE,KAAKD,IAAIvJ,EAAOsJ,GAAMC,GAEpFo0C,GAA4B,CAAC,KAAM,MAGnCC,GAAW59C,IACpB,GAAa,MAATA,GAA2B,KAAVA,EAAc,OAAO,KAC1C,GAAIgL,EAAMC,QAAQjL,GAAQ,OAAOA,EAAMkL,UAAYlL,EAAQ,KAC3D,GAAIA,aAAiB4K,MAAyB,iBAAV5K,GAAuC,iBAAVA,EAAoB,CACjF,MAAMoL,EAASJ,EAAMhL,GACrB,OAAOoL,EAAOF,UAAYE,EAAS,IACvC,CACA,OAAO,MAGEyyC,GAAYA,CAACjuC,EAA6BC,MAAkCD,KAAOC,GAAKD,EAAEkuC,OAAOjuC,EAAG,OACpGkuC,GAAcA,CAACnuC,EAAUC,IAAaD,EAAEouC,SAASnuC,EAAG,OACpDouC,GAAaA,CAACruC,EAAUC,IAAaD,EAAEsuC,QAAQruC,EAAG,OAClDsuC,GAAgBA,CAACC,EAAY/gD,EAAqBC,OACzDD,IAAWC,GAAQygD,GAAYK,EAAK/gD,IAAW4gD,GAAWG,EAAK9gD,IAExD+gD,GAAeA,CAACzuC,EAA6BC,KACtD,GAAID,IAAMC,EAAG,OAAO,EACpB,IAAKD,IAAMC,EAAG,OAAO,EACrB,MAAMyuC,EAAOA,CAAC/P,EAAiBgQ,IAA0B,MAALhQ,GAAkB,MAALgQ,KAAiBhQ,KAAOgQ,GAAKhQ,EAAEuP,OAAOS,EAAG,OAC1G,OAAOD,EAAK1uC,EAAE,GAAIC,EAAE,KAAOyuC,EAAK1uC,EAAE,GAAIC,EAAE,KAG/B2uC,GAAkBx+C,GACtBkJ,MAAMC,QAAQnJ,GACZ,CAAC49C,GAAQ59C,EAAM,IAAK49C,GAAQ59C,EAAM,KADP29C,GAKzBc,GAAgBA,CAACrgD,EAAcoN,KACxC,MAAMkzC,EAAUtgD,EAAKmV,OACrB,IAAKmrC,EAAS,OAAO,KACrB,MAAMC,EAAS3zC,EAAM0zC,EAASlzC,GAAQ,GACtC,GAAImzC,EAAOzzC,UAAW,OAAOyzC,EAC7B,MAAMC,EAAY,CACdpzC,EAAOgH,QAAQ,MAAO,KAAKA,QAAQ,MAAO,KAC1C,WACA,SACA,aACA,aACA,YAEJ,IAAK,MAAMmL,KAAKihC,EAAW,CACvB,MAAMxzC,EAASJ,EAAM0zC,EAAS/gC,GAAG,GACjC,GAAIvS,EAAOF,UAAW,OAAOE,CACjC,CACA,OAAO,MAGEC,GAAaA,CAACrL,EAAqBwL,IAAoBxL,GAASA,EAAMkL,UAAYlL,EAAMwL,OAAOA,GAAU,GAqBzGqzC,GAAcA,CACvBT,EACAv5C,EACAhC,EACAghB,EAAa7Y,MAEF,MAAPozC,EAAoB,KACnBA,EAAIlzC,UACLrI,EAAQi8C,aAAef,GAAYK,EAAKv6B,GAAa,cACrDhhB,EAAQk8C,eAAiBd,GAAWG,EAAKv6B,GAAa,gBACtDhhB,EAAQm8C,SAAWjB,GAAYK,EAAKv7C,EAAQm8C,SAAiB,UAC7Dn8C,EAAQo8C,SAAWhB,GAAWG,EAAKv7C,EAAQo8C,SAAiB,UAC5Dp8C,EAAQq8C,oBAAoBd,EAAKv5C,GAAkB,oBAChD,KANoB,cASlBs6C,GAAgBA,CACzBn/C,EACA6C,KAEA,MAAMghB,EAAM7Y,IACNo0C,EAAaP,GAAY7+C,EAAM,GAAI,QAAS6C,EAASghB,GACrDw7B,EAAWR,GAAY7+C,EAAM,GAAI,MAAO6C,EAASghB,GACvD,OAAKu7B,IAAeC,GAAYr/C,EAAM,IAAMA,EAAM,IAAMi+C,GAAWj+C,EAAM,GAAIA,EAAM,IACxE,CAAC,eAAgB,gBAErB,CAACo/C,EAAYC,IAGXC,GAAgBA,CAAClB,EAAYv5C,EAAgChC,IAC/B,MAAvCg8C,GAAYT,EAAKv5C,EAAUhC,GAelB08C,GAAgBA,CAACC,EAAcC,KACxC,MAAMC,EAAeF,EAAM9zC,QAAQ,SAC7BrO,EAAQqiD,EAAah0C,QAAQ,QAC7Bi0C,EAAen2C,KAAK+iC,KAAKmT,EAAaE,MAAM,SAASC,KAAKxiD,EAAO,OAAS,EAAI,EAAI,GAClFyiD,EAAYL,GAAmBA,EAAkB,EAAIA,EAAkBj2C,KAAKD,IAAIo2C,EAAc,GAC9FI,EAAwB,GAC9B,IAAK,IAAI18B,EAAI,EAAGA,EAAIy8B,EAAWz8B,GAAK,EAAG,CACnC,MAAM28B,EAAY3iD,EAAMqN,IAAQ,EAAJ2Y,EAAO,OACnC08B,EAAM7sC,KAAK,CACPnT,IAAKigD,EAAUx0C,OAAO,cACtBy0C,KAAM/2C,MAAM6O,KAAK,CAAE3O,OAAQ,GAAK,CAAC82C,EAAG/0C,KAChC,MAAMizC,EAAM4B,EAAUt1C,IAAIS,EAAG,OAC7B,MAAO,CAAEizC,MAAK+B,cAAe/B,EAAIN,OAAO4B,EAAc,aAGlE,CACA,OAAOK,GAGEK,GAAoBC,IAC7B,MAAMhjD,EAAQ2N,IAAQU,QAAQ,QAC9B,OAAOxC,MAAM6O,KAAK,CAAE3O,OAAQ,GAAK,CAAC82C,EAAGngC,KACjC,MAAMq+B,EAAM/gD,EAAMqN,IAAIqV,EAAG,OACzB,MAAO,CAAEhgB,IAAKq+C,EAAI5yC,OAAO,MAAOS,MAAOo0C,EAAUjC,GAAMkC,KAAMlC,EAAI5yC,OAAO,YAQnE+0C,GAA2D,CACpE,CACIt0C,MAAO,YACPu0C,SAAUA,KACN,MAAMC,EAAQz1C,IACd,MAAO,CAACy1C,EAAM/0C,QAAQ,QAAS+0C,EAAMb,MAAM,WAGnD,CACI3zC,MAAO,YACPu0C,SAAUA,KACN,MAAM9wB,EAAO1kB,IAAQ01C,SAAS,EAAG,OACjC,MAAO,CAAChxB,EAAKhkB,QAAQ,QAASgkB,EAAKkwB,MAAM,WAGjD,CACI3zC,MAAO,cACPu0C,SAAUA,KACN,MAAMC,EAAQz1C,IACd,MAAO,CAACy1C,EAAMC,SAAS,EAAG,OAAQD,KAG1C,CACIx0C,MAAO,gBACPu0C,SAAUA,KACN,MAAMC,EAAQz1C,IACd,MAAO,CAACy1C,EAAM/0C,QAAQ,SAAU+0C,EAAMb,MAAM,YAGpD,CACI3zC,MAAO,aACPu0C,SAAUA,KACN,MAAM1jC,EAAO9R,IAAQN,IAAI,EAAG,SAC5B,MAAO,CAACoS,EAAKpR,QAAQ,SAAUoR,EAAK8iC,MAAM,YAGlD,CAAE3zC,MAAO,QAASu0C,SAAUA,IAAM,CAAC,KAAM,QCtLvCG,GAA6BvC,GAAeA,EAAI5yC,OAAO,MAAMuH,OAAO,GAAG6tC,cAMvE,SAAUC,IACZ7gD,MAAO8gD,EAAS1kC,aAChBA,EAAYC,SACZA,EACA0kC,cAAeC,EAAiBC,sBAChCA,EAAqBC,UACrBA,EAAY,EAACC,cACbA,EAAanC,QACbA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiB3tB,SACjBA,GAAW,EAAK6vB,SAChBA,GAAW,EAAKC,4BAChBA,GAA8B,EAAK5B,gBACnCA,EAAe6B,mBACfA,EAAqBX,GAAyBY,sBAC9CA,GAAwB,EAAKC,iBAC7BA,GAAmB,EAAI/yB,UACvBA,GAAY,EAAKgzB,cACjBA,EAAa7vB,WACbA,EAAUtzB,UACVA,EAAS6pB,UACTA,EAASlnB,MACTA,IAEAo8C,KAEA,MAAM/gC,OAA6B9P,IAAds0C,GACdY,EAAeC,GAAoB1iD,EAAMwd,SAAuB,IACnE+hC,GAAepiC,GAAgBuhC,KAE7B39C,EAAQf,EAAMu3B,QAChB,IAAOla,EAAekiC,GAAesC,GAAaY,EAClD,CAACplC,EAAcwkC,EAAWY,KAEvBrkD,EAAOC,GAAO0C,GAEd4hD,EAAkBC,GAAuB5iD,EAAMwd,SAA+B,SAC/EskC,EAAgBC,GAAqBY,EACrCE,EAAmB7iD,EAAM4d,YAC1BhY,SAC6B2H,IAAtBw0C,GAAiCa,EAAoBh9C,GACzDo8C,IAAwBp8C,IAE5B,CAACm8C,EAAmBC,IAGlBc,EAAa9iD,EAAMu3B,QACrB,KAAA,CAASwoB,UAASC,UAASH,cAAaC,gBAAeG,sBACvD,CAACF,EAASC,EAASH,EAAaC,EAAeG,KAI5C8C,EAAcC,GAAmBhjD,EAAMwd,SAAgB,KACzDpf,GAASC,GAAO6jD,GAAiBn2C,KAASU,QAAQ,UAEjDw2C,EAAgBjjD,EAAMu3B,QACxB,IAAMttB,MAAM6O,KAAK,CAAE3O,OAAQ83C,GAAa,CAAChB,EAAGngC,IAAMiiC,EAAat3C,IAAIqV,EAAG,UACtE,CAACiiC,EAAcd,IAEbiB,EAAmBD,EAAcA,EAAc94C,OAAS,GAExDg5C,EAAcnjD,EAAM4d,YACrB2iC,IACG,MAAM1iC,EAAO0iC,EAAM9zC,QAAQ,SAC3Bu2C,EAAiBvyB,GACTA,EAAKouB,OAAOhhC,EAAM,SAAiB4S,GACvC+xB,IAAgB3kC,GACTA,KAGf,CAAC2kC,IAGCY,EAAgBpjD,EAAM4d,YACvBuhC,IACOL,GAAYK,EAAK4D,EAAat2C,QAAQ,UAAW02C,EAAYhE,GACxDH,GAAWG,EAAK+D,EAAiBvC,MAAM,WAAWwC,EAAYhE,EAAIsC,SAASQ,EAAY,EAAG,WAEvG,CAACc,EAAcG,EAAkBjB,EAAWkB,IAI1CE,EAAcrjD,EAAM+c,OAAqBhc,GAC/Cf,EAAMgc,UAAU,KACZ,MAAMyU,EAAO4yB,EAAYrmC,QACzBqmC,EAAYrmC,QAAUjc,EACtB,MAAMwlB,EAA2B,QAAlBu7B,EAA2BzjD,GAAOD,EAAUA,GAASC,EACpE,IAAKkoB,EAAQ,SACIq4B,GAAUnuB,EAAK,GAAIryB,KAAWwgD,GAAUnuB,EAAK,GAAIpyB,KACrD+kD,EAAc78B,IAE5B,CAACnoB,EAAOC,IAEX,MAAMilD,GAAavD,GAAWgD,EAAa9D,QAAQc,EAAS,SACtDwD,GAAavD,GAAWkD,EAAiBnE,SAASiB,EAAS,UAG1DwD,EAAYC,GAAiBzjD,EAAMwd,SAAuB,MAC3DkmC,EAAU1jD,EAAMu3B,QAAsB,KACnCgrB,IAAqBiB,GAAclxB,GAAY6vB,EAAiBzD,GAC/C,QAAlBoD,GAA2B1jD,IAAUC,EAC9BygD,GAAY0E,EAAYplD,GAASsgD,GAAc,CAACtgD,EAAOolD,GAE5C,UAAlB1B,GAA6BzjD,IAAQD,EAC9B4gD,GAAWwE,EAAYnlD,GAAOqgD,GAAc,CAAC8E,EAAYnlD,GAE7DqgD,GACR,CAAC6D,EAAkBiB,EAAY1B,EAAe1jD,EAAOC,EAAKi0B,EAAU6vB,IAGjEwB,EAAY3jD,EAAM4d,YACnBuhC,IACG,GAAI7sB,GAAY6vB,EAAU,OAC1B,GAAI9B,GAAclB,EAAK2C,EAAegB,GAAa,OACnD,IAAIjlC,EACA+lC,EACkB,UAAlB9B,GAEAjkC,EAAO,CAACshC,EAAK9gD,GAAO2gD,GAAWG,EAAK9gD,GAAO,KAAOA,GAClDulD,EAAe,OACRxlD,GAAS0gD,GAAYK,EAAK/gD,IAEjCyf,EAAO,CAACshC,EAAK,MACbyE,EAAe,QAEf/lC,EAAO,CAACzf,EAAO+gD,GACfyE,EAAe,SAEdvmC,GAAcqlC,EAAiB7kC,GACpCT,IAAWS,EAAMshC,EAAK2C,GACtBe,EAAiBe,IAErB,CAACtxB,EAAU6vB,EAAUL,EAAegB,EAAYzkD,EAAKD,EAAOif,EAAcD,EAAUylC,KAIjFgB,EAAYC,GAAiB9jD,EAAMwd,SAAgB,IAAMpf,GAASC,GAAO6jD,GAAiBn2C,KAC3Fs3B,EAAUrjC,EAAM+c,OAA8B,MAC9CwsB,GAAkBvpC,EAAM+c,OAAOyS,GAE/Bu0B,GAAW/jD,EAAM4d,YAAauhC,IAChC,MAAMr+C,EAAMq+C,EAAI5yC,OAAO,cACjB7I,EAAK2/B,EAAQrmB,SAASqU,cAAiC,cAAcvwB,OAC3E4C,GAAIymB,SACL,IAEHnqB,EAAMgc,UAAU,KACZ,IAAKutB,GAAgBvsB,QAAS,OAC9BusB,GAAgBvsB,SAAU,EAC1B,MAAMuJ,EAASs9B,EACfT,EAAc78B,GAEd,MAAMpb,EAAKxK,OAAO4a,WAAW,IAAMwoC,GAASx9B,GAAS,GACrD,MAAO,IAAM5lB,OAAOmpB,aAAa3e,IAElC,IAEH,MAMMimB,GAAgBA,CAACJ,EAAyCmuB,KAC5D,IAAIthC,EAAqB,KACzB,OAAQmT,EAAMlwB,KACV,IAAK,YACD+c,EAAOshC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,aACD5jC,EAAOshC,EAAI1zC,IAAI,EAAG,OAClB,MACJ,IAAK,UACDoS,EAAOshC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,YACD5jC,EAAOshC,EAAI1zC,IAAI,EAAG,OAClB,MACJ,IAAK,OACDoS,EAAOshC,EAAI1yC,QAAQ,QACnB,MACJ,IAAK,MACDoR,EAAOshC,EAAIwB,MAAM,QACjB,MACJ,IAAK,SACD9iC,EAAOmT,EAAM4oB,SAAWuF,EAAIsC,SAAS,EAAG,QAAUtC,EAAIsC,SAAS,EAAG,SAClE,MACJ,IAAK,WACD5jC,EAAOmT,EAAM4oB,SAAWuF,EAAI1zC,IAAI,EAAG,QAAU0zC,EAAI1zC,IAAI,EAAG,SACxD,MACJ,IAAK,QACL,IAAK,IAGD,OAFAulB,EAAMiB,sBACN0xB,EAAUxE,GAEd,QACI,OAERnuB,EAAMiB,iBACFpU,GA1CWshC,KACf2E,EAAc3E,GACdiE,EAAcjE,GACdx+C,OAAO4a,WAAW,IAAMwoC,GAAS5E,GAAM,IAuC7BvI,CAAU/4B,IAGlBmmC,GAAWhkD,EAAMu3B,QAAQ,IAAM4pB,GAAiBkB,GAAqB,CAACA,IACtEb,GAAQz1C,IACRk4C,GAAeP,EAAQ,GACvBQ,GAAaR,EAAQ,GACrBS,KAAoB/lD,KAAWC,EAsIrC,OACI2B,uBACImF,IAAKk+B,EACLna,UAAW1e,GACP,oBACA8nB,GAAY,6BACZ6vB,GAAY,8BACZj5B,GACH,iBACe7pB,wBACKyiD,EACrB9/C,MAAOA,EACPoiD,aAAcA,IAAMX,EAAc,OAEjCR,EAAcx/C,IAlJH4gD,CAAC9D,EAAcx9B,KAC/B,MAAM+9B,EAAQR,GAAcC,EAAOC,GAC7BnH,EAAoB,IAAVt2B,EACVw2B,EAASx2B,IAAUkgC,EAAc94C,OAAS,EAE1Cm6C,GADiBT,EAAWhF,OAAO0B,EAAO,SAAWsD,EAAa,QAGnEzlD,GAASA,EAAMygD,OAAO0B,EAAO,SAAWniD,EAAQ,QAChDC,GAAOA,EAAIwgD,OAAO0B,EAAO,SAAWliD,EAAM,QAC1Cg7C,IAAY4J,EAAc/xB,KAAM1d,GAAMqwC,EAAWhF,OAAOrrC,EAAG,UAAY+sC,EAAM9zC,QAAQ,SAAW,MAErG,OACIzM,EAAAC,cAAA,MAAA,CACIa,IAAKy/C,EAAMh0C,OAAO,WAClB2c,UAAU,mBACViG,KAAK,QAAO,aACAoxB,EAAMh0C,OAAO,cAEzBvM,EAAAC,cAAA,MAAA,CAAKipB,UAAU,2BACVmwB,EACGr5C,0BACIsL,KAAK,SACL4d,UAAU,gCAA+B,aAC7ByJ,GAAY4xB,eAAiB,iBACzCriD,MAAOywB,GAAY4xB,eAAiB,iBACpCjyB,SAAUA,IAAagxB,EACvB3xB,QAASA,IAAMwxB,EAAYJ,EAAatB,SAAS,EAAG,WAEpDzhD,EAAAC,cAACotB,GAAe,OAGpBrtB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,gCAEpBlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBAAwB,YAAW,UAC7Cq3B,EAAMh0C,OAAO,cAEjBgtC,EACGv5C,0BACIsL,KAAK,SACL4d,UAAU,gCAA+B,aAC7ByJ,GAAY6xB,WAAa,aACrCtiD,MAAOywB,GAAY6xB,WAAa,aAChClyB,SAAUA,IAAaixB,EACvB5xB,QAASA,IAAMwxB,EAAYJ,EAAat3C,IAAI,EAAG,WAE/CzL,EAAAC,cAACmtB,GAAgB,OAGrBptB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,iCAGxBlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBAAmBiG,KAAK,OAClC60B,GAASvgD,IAAKghD,GACXzkD,wBAAMc,IAAK2jD,EAAG3jD,IAAKooB,UAAU,kBAAkBiG,KAAK,eAAc,aAAas1B,EAAGpD,MAC7EoD,EAAGz3C,SAIhBhN,EAAAC,cAAA,MAAA,CAAKipB,UAAU,gBAAgBiG,KAAK,OAAM,aAAaoxB,EAAMh0C,OAAO,cAC/Du0C,EAAMr9C,IAAKihD,GACR1kD,EAAAC,cAAA,MAAA,CAAKa,IAAK4jD,EAAK5jD,IAAKooB,UAAU,eAAeiG,KAAK,OAC7Cu1B,EAAK1D,KAAKv9C,IAAI,EAAG07C,MAAK+B,gBAAgByD,KACnC,MAAMC,EAAS1D,IAAiBkB,EAC1ByC,EAAUjG,GAAUO,EAAK/gD,GACzB0mD,EAAQlG,GAAUO,EAAK9gD,GACvBg0B,EAAWwyB,GAAWC,EACtBC,GAAWH,GAAUT,IAAmBjF,GAAcC,EAAK/gD,EAAOC,GAClE2mD,GACDJ,KACCX,MACAC,IACFhF,GAAcC,EAAK8E,GAAcC,IAC/Be,EAAc3yB,GAAY+tB,GAAclB,EAAK2C,EAAegB,GAC5DoC,IAAeZ,GAAe1F,GAAUO,EAAKmF,KAAiBM,EAC9DO,EAA4B,IAAbR,IAAoBvC,GAA8C,IAAfjD,EAAI7yC,OACtE84C,EACW,IAAbT,IAAoBvC,GAA+BjD,EAAI7yC,SAAW6yC,EAAIkG,cAC1E,OACIrlD,EAAAC,cAAA,MAAA,CACIa,IAAKq+C,EAAI5yC,OAAO,cAChB4iB,KAAK,2BACUkD,QAAY9kB,EAC3B2b,UAAW1e,GACP,mBACAu6C,GAAW,6BACXA,GAAWF,GAAW,gCACtBE,GAAWD,GAAS,8BACpBE,GAAa,4BACbA,GAAapG,GAAUO,EAAK8E,KAAiB,kCAC7Ce,GAAapG,GAAUO,EAAK+E,KAAe,gCAC3CiB,GAAgB,kCAChBC,GAAe,mCAGnBplD,EAAAC,cAAA,SAAA,CACIqL,KAAK,oBACK6zC,EAAI5yC,OAAO,cACrBklB,SAAUyzB,EAAa,GAAI,EAAE,aACjB/F,EAAI5yC,OAAO,sBAAqB,gBAEvC+1C,GAAyB1D,GAAUO,EAAKqC,IAAS,YAASj0C,kBAEhD03C,QAAe13C,EAC9B+kB,SAAUsyB,EACV17B,UAAW1e,GACP,cACAo6C,GAAU,sBACV1D,IAAiB0D,GAAU,uBAC3BvyB,GAAY,yBACXiwB,GAAyB1D,GAAUO,EAAKqC,KAAU,qBACnDyD,GAAe,yBAEnBtzB,QAASA,IAAMgyB,EAAUxE,GACzBmG,aAAcA,IAAM7B,EAActE,GAClCiF,aAAcA,IACVX,EAAehzB,GAAUA,GAAQmuB,GAAUnuB,EAAM0uB,GAAO,KAAO1uB,GAEnE80B,QAASA,IAAMzB,EAAc3E,GAC7BrtB,UAAYd,GAAUI,GAAcJ,EAAOmuB,IAE1CA,EAAI7yC,iBA6BjD,CCtWM,SAAU8iB,IAAQzG,KACpBA,EAAI0G,SACJA,EAAQE,UACRA,EAASi2B,UACTA,EAASnmD,UACTA,EAAS6pB,UACTA,EAASlnB,MACTA,EAAKyjD,WACLA,EAAUl9C,SACVA,IAEA,MAAMpD,EAAMnF,EAAM+c,OAA8B,OACzCnX,EAAU8pB,GAAe1vB,EAAMwd,SAAS,CAAEmS,IAAK,EAAGC,KAAM,EAAGC,OAAO,IAEnEC,EAAS9vB,EAAM4d,YAAY,KAC7B,MAAMla,EAAKyB,EAAI6X,QACf,IAAKtZ,EAAI,OACT,MAAMqsB,EAAKpvB,OAAOqvB,WACZC,EAAKtvB,OAAOuvB,YACZ9L,EAAI1gB,EAAGysB,YACPrQ,EAAIpc,EAAG0sB,aACb,IAAIT,EACAC,EACJ,GAAIP,GAAYA,EAASgB,YAAa,CAClC,MAAM1f,EAAI0e,EAASiB,wBACnBX,EAAMhf,EAAE6f,OAAS,EACbb,EAAM7P,EAAImQ,EAAK,GAAKtf,EAAEgf,IAAM,EAAI7P,GAAK,IAAG6P,EAAMhf,EAAEgf,IAAM,EAAI7P,GAC9D8P,EAAqB,eAAdL,EAA6B5e,EAAE4f,MAAQnM,EAAkB,WAAdmL,EAAyB5e,EAAEif,KAAOjf,EAAEpQ,MAAQ,EAAI6jB,EAAI,EAAIzT,EAAEif,IAChH,MACID,EAAMM,EAAK,EAAInQ,EAAI,EACnB8P,EAAOG,EAAK,EAAI3L,EAAI,EAExBuL,EAAMvlB,GAAMulB,EAAK,EAAGplB,KAAKD,IAAI,EAAG2lB,EAAKnQ,EAAI,IACzC8P,EAAOxlB,GAAMwlB,EAAM,EAAGrlB,KAAKD,IAAI,EAAGylB,EAAK3L,EAAI,IAC3CsL,EAAae,GAAUA,EAAKZ,OAASY,EAAKd,MAAQA,GAAOc,EAAKb,OAASA,EAAOa,EAAO,CAAEd,MAAKC,OAAMC,OAAO,KAC1G,CAACR,EAAUE,IA4Cd,OA1CAvvB,EAAM+b,gBAAgB,KAClB,IAAK4M,EAED,YADA+G,EAAae,GAAUA,EAAKZ,MAAQ,IAAKY,EAAMZ,OAAO,GAAUY,GAGpEX,IACAnvB,OAAOopB,iBAAiB,SAAU+F,GAClCnvB,OAAOopB,iBAAiB,SAAU+F,GAAQ,GAC1C,IAAIY,EAAkC,KAKtC,MAJ8B,oBAAnBC,gBAAkCxrB,EAAI6X,UAC7C0T,EAAW,IAAIC,eAAe,IAAMb,KACpCY,EAASE,QAAQzrB,EAAI6X,UAElB,KACHrc,OAAOkwB,oBAAoB,SAAUf,GACrCnvB,OAAOkwB,oBAAoB,SAAUf,GAAQ,GAC7CY,GAAUI,eAEf,CAACnI,EAAMmH,IAEV9vB,EAAMgc,UAAU,KACZ,IAAK2M,EAAM,OACX,MAAMoI,EAAqBC,IACvB,MAAMzK,EAASyK,EAAMzK,OAChBA,IACDphB,EAAI6X,SAASiU,SAAS1K,IACtB8I,GAAU4B,SAAS1K,IACvBi/B,EAAU,cAERp0B,EAAiBJ,IACD,WAAdA,EAAMlwB,KAAkB0kD,EAAU,WAK1C,OAHAhrC,SAASuP,iBAAiB,YAAagH,GAAmB,GAC1DvW,SAASuP,iBAAiB,aAAcgH,GAAmB,GAC3DvW,SAASuP,iBAAiB,UAAWqH,GAC9B,KACH5W,SAASqW,oBAAoB,YAAaE,GAAmB,GAC7DvW,SAASqW,oBAAoB,aAAcE,GAAmB,GAC9DvW,SAASqW,oBAAoB,UAAWO,KAE7C,CAACzI,EAAM68B,EAAWn2B,IAEhB1G,GAA4B,oBAAbnO,SAEbgX,eACHxxB,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACLgqB,KAAK,sBACM,QAAO,kBACDs2B,EACjBh0B,UAAU,EACVvI,UAAW1e,GAAG,kBAAmB0e,GAAU,iBAC3B7pB,EAChB2C,MAAO,CAAE2tB,IAAK/pB,EAAS+pB,IAAKC,KAAMhqB,EAASgqB,KAAM8B,WAAY9rB,EAASiqB,MAAQ,UAAY,YAAa7tB,GACvG6vB,YAAcb,GAAUA,EAAMO,mBAE7BhpB,GAELiS,SAASY,MAhBwC,IAkBzD,CAgCO,MAAMxW,GAAY5E,EAAMoG,WAA2C,UACtE+E,GACIA,EAAE6B,MACFA,EAAKjM,MACLA,EAAKuE,YACLA,EAAWC,KACXA,EAAImgD,UACJA,EAASC,MACTA,EAAKrzB,SACLA,EAAQ6vB,SACRA,EAAQyD,SACRA,EAAQ//B,MACRA,EAAKggC,QACLA,EAAOC,UACPA,EAAShuC,KACTA,EAAI0X,UACJA,EAASnqB,SACTA,EAAQ0gD,UACRA,EAASC,UACTA,EAAS5oC,SACTA,EAAQmoC,QACRA,EAAOhwB,OACPA,EAAM5D,QACNA,EAAOG,UACPA,GAEJ3sB,GAEA,MAAM8gD,EAAoB,MAATj5C,GAA2B,KAAVA,EAC5Bk5C,EAASL,GAAqB,KAAV9kD,IAAiBklD,EAC3C,OACIjmD,EAAAC,cAAA,MAAA,CACIkF,IAAKA,EACL+jB,UAAW1e,GACP,gBACA,kBAAkBjF,IAClBmgD,GAAa,4BACbC,GAAS,uBACTO,GAAU,wBACVL,GAAW,yBACXvzB,GAAY,0BACZzM,GAAS,uBACTigC,GAAa,4BACZG,GAAY,4BACXF,GAAa,0BAEnBp0B,QAASA,GAERs0B,GACGjmD,EAAAC,cAAA,QAAA,CAAOipB,UAAU,gBAAgB2F,QAAS1jB,GACrC6B,EACA44C,GACG5lD,EAAAC,cAAA,OAAA,CAAMipB,UAAU,yBAAwB,cAAa,QAAM,MAMvElpB,EAAAC,cAAA,QAAA,CACIkL,GAAIA,EACJhG,IAAKE,EACLyS,KAAMA,EACNoR,UAAU,gBACV5d,KAAK,OACL66C,UAAU,UACVC,aAAa,MACbC,YAAY,EACZtlD,MAAOA,EACPuE,YAAa4gD,EAAS5gD,OAAciI,EACpC+kB,SAAUA,EACV6vB,SAAUA,EACVyD,SAAUA,EACVp2B,UAAWA,eACCw2B,EAAS,eACPngC,QAAStY,EACvB6P,SAAW4T,GAAU5T,EAAS4T,EAAMzK,OAAOxlB,OAC3CwkD,QAASA,EACThwB,OAAQA,EACRzD,UAAWA,IAEdi0B,GAAa/lD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,qBAAqB68B,GAClD/lD,EAAAC,cAAA,WAAA,CAAA,cAAsB,OAAOipB,UAAU,mBACnClpB,EAAAC,cAAA,SAAA,KACID,EAAAC,cAAA,OAAA,KACKgmD,EAAWj5C,EAAQ,GACnBi5C,GAAYL,EAAW,KAAO,MAMvD,GC5NaU,GAA0E,CACnFloD,MAAO,QACPC,IAAK,MACLkoD,eAAgB,IAChBC,WAAY,oBACZrxB,MAAO,QACPqsB,MAAO,QACPhJ,OAAQ,SACRiO,OAAQ,KACRlC,cAAe,iBACfC,UAAW,aACXkC,aAAc,qBAgBLC,GAAqB3mD,EAAMoG,WAAoD,UAEpFrF,MAAO8gD,EAAS1kC,aAChBA,EAAYC,SACZA,EAAQwpC,SACRA,EAAQC,QACRA,EACAl+B,KAAMm+B,EAAQC,OACdA,EAAMz3B,QACNA,EACAwyB,cAAeC,EAAiBC,sBAChCA,EAAqBh1C,MACrBA,EAAKT,OACLA,EA1Be,aA0BQy6C,aACvBA,EAAe,SAAQzhD,KACvBA,EAAO,QAAOmgD,UACdA,GAAY,EAAKuB,UACjBA,GAAY,EAAKC,YACjBA,EAAWC,kBACXA,GAAoB,EAAKC,cACzBA,EAAaC,UACbA,EAAStqB,QACTA,EAAU,GAAE6B,YACZA,GAAc,EACdjM,WAAYqM,EAAcijB,UAC1BA,EAAY,EAACC,cACbA,EAAanC,QACbA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiB3tB,SACjBA,GAAW,EAAK6vB,SAChBA,GAAW,EAAKC,4BAChBA,EAA2B5B,gBAC3BA,EAAe6B,mBACfA,EAAkBC,sBAClBA,EAAqBC,iBACrBA,EAAgBC,cAChBA,EAAa1qC,KACbA,EACA3M,GAAIm8C,EACJhiD,YAAaiiD,EAAe3B,SAC5BA,EACA//B,MAAO2hC,EAASC,WAChBA,EAAUj4B,UACVA,EAASnqB,SACTA,EAAQhG,UACRA,EAASs/B,UACTA,EAASzV,UACTA,EAASlnB,MACTA,EAAK0lD,iBACLA,EAAgBC,aAChBA,EAAYp4B,UACZA,GAAY,gBAEhBpqB,IAEAi5C,KAEA,MAAMzrB,GAAa3yB,EAAMu3B,QACrB,KAAA,IAAY+uB,MAA8CtnB,IAC1D,CAACA,IAEC4oB,GAAkBj1B,GAAWi1B,iBAAmBr7C,EAChDs7C,GAA2B,UAAjBb,EACVc,GAAsBZ,GAAeW,GACrCE,GAAwBX,IAAkBrqB,EAAQirB,SAAS,UAE3DC,GAAUjoD,EAAMmjC,QAChB+kB,GAASZ,GAAU,WAAWW,GAAQ10C,QAAQ,KAAM,MACpD40C,GAAUN,GAAU,GAAGK,WAAiBA,GACxCE,GAAQ,GAAGF,SACXG,GAAgB,GAAGH,WAGnB7qC,QAA6B9P,IAAds0C,GACdY,GAAeC,IAAoB1iD,EAAMwd,SAAuB,IACnE+hC,GAAepiC,GAAgBuhC,KAE7B39C,GAAQf,EAAMu3B,QAChB,IAAOla,GAAekiC,GAAesC,GAAaY,GAClD,CAACplC,GAAcwkC,EAAWY,MAEvBrkD,GAAOC,IAAO0C,GAEf+hD,GAAa9iD,EAAMu3B,QACrB,KAAA,CAASwoB,UAASC,UAASH,cAAaC,gBAAeG,sBACvD,CAACF,EAASC,EAASH,EAAaC,EAAeG,IAE7CqI,GAAkBtoD,EAAMu3B,QAAQ,IAAM2oB,GAAcn/C,GAAO+hD,IAAa,CAAC/hD,GAAO+hD,KAChF72C,GAAUjM,EAAM4d,YACjB2qC,GAAwBrI,GAAcqI,EAAOzF,IAAY5tC,MAAOmvB,GAAW,MAALA,GACvE,CAACye,KAGC0F,GAAexoD,EAAM+c,OAA0E,MACrG/c,EAAMgc,UAAU,KACZ,MAAMyU,EAAO+3B,GAAaxrC,QACtByT,GAAQA,EAAK,KAAO63B,GAAgB,IAAM73B,EAAK,KAAO63B,GAAgB,MAC7D,OAAT73B,GAAiB63B,GAAgB,IAAMA,GAAgB,KAAIzB,IAAUyB,GAAiBvnD,IAC1FynD,GAAaxrC,QAAUsrC,KACxB,CAACA,GAAiBvnD,GAAO8lD,IAE5B,MAAM4B,GAAWzoD,EAAM4d,YACnB,CAACC,EAAoB6qC,KACZrrC,IAAcqlC,GAAiB7kC,GACpC,MAAM8qC,EAAqC,CAAEL,gBAAiBpI,GAAcriC,EAAMilC,KAC9E4F,IAAUC,EAAQD,SAAWA,GACjCtrC,IAAWS,EAAM8qC,IAErB,CAACtrC,GAAcD,EAAU0lC,MAItBH,GAAkBC,IAAuB5iD,EAAMwd,SAA+B,SAC/EskC,GAAgBC,GAAqBY,GACrCE,GAAmB7iD,EAAM4d,YAC1BhY,SAC6B2H,IAAtBw0C,GAAiCa,GAAoBh9C,GACzDo8C,IAAwBp8C,IAE5B,CAACm8C,EAAmBC,IAIlB4G,QAAgCr7C,IAAbu5C,GAClB+B,GAAcC,IAAmB9oD,EAAMwd,UAAS,GACjDmL,GAAOigC,KAAqB9B,EAAW+B,GACvCE,GAAiB/oD,EAAM+c,OAAqBhc,IAC5CioD,GAAkBhpD,EAAM+c,OAAqBhc,IAG7C0lD,GAASzmD,EAAM4d,YACjB,CAACC,EAAoBorC,GAAQ,MACpBA,GAAS7J,GAAavhC,EAAMmrC,GAAgBhsC,WACjDgsC,GAAgBhsC,QAAUa,EAC1B+oC,IAAW/oC,KAEf,CAAC+oC,IAECvjB,GAAUrjC,EAAM+c,OAA8B,MAC9CmsC,GAAYlpD,EAAM+c,OAAiC,MACnDosC,GAAkBnpD,EAAM+c,OAA2B,OAIlDqsC,GAAgBC,IAAqBrpD,EAAMwd,cAAuCjQ,GACzFvN,EAAMgc,UAAU,KACZ,QAAkBzO,IAAdlO,EAAyB,OAC7B,MAAMiqD,EAAOjmB,GAAQrmB,SAASusC,eAAep4B,QAAQ,qBAAqBq4B,aAAa,kBACvFH,GAA2B,SAATC,EAAkB,OAAkB,UAATA,EAAmB,aAAU/7C,KAE9E,MAAMk8C,GAAqBpqD,GAAa+pD,IAIjC/5B,GAAUq6B,IAAe1pD,EAAMwd,SAAgC,MAChEmsC,GAAa3pD,EAAM4d,YACpBwN,IACGiY,GAAQrmB,QAAUoO,EAClBs+B,GAAYt+B,GACO,mBAARjmB,GAAoBA,GAAIimB,GAC1BjmB,KAAMA,GAAsD6X,QAAUoO,IAEnF,CAACjmB,KAGCqhD,GAAaxmD,EAAM4d,YACpBhY,IACO0sB,GAAY6vB,GAAYx5B,KAC5BogC,GAAe/rC,QAAUjc,GACzBooD,GAAgBnsC,QAAWxC,SAAS2X,eAAwC,KAC5E0wB,GAAiBj9C,IAAaxH,KAAUC,GAAM,MAAQ,UACjDuqD,IAAkBE,IAAgB,GACvC/B,QAEJ,CAACz0B,EAAU6vB,EAAUx5B,GAAM5nB,GAAO3C,GAAOC,GAAKwkD,GAAkB+F,GAAkB7B,IAGhF6C,GAAc5pD,EAAM4d,YAAY,KAClC,IAAK+K,GAAM,OACNigC,IAAkBE,IAAgB,GACvCx5B,MACA,MAAM/I,EAAS2iC,GAAUlsC,SAAWmsC,GAAgBnsC,QACpDrc,OAAO4a,WAAW,IAAMgL,GAAQ4D,UAAW,IAC5C,CAACxB,GAAMigC,GAAkBt5B,IAEtBu6B,GAAiB7pD,EAAM4d,YACxBC,IACG4oC,GAAO5oC,GAAM,GACb+rC,MAEJ,CAACnD,GAAQmD,KAGPE,GAAgB9pD,EAAM4d,YAAY,KAEpC6oC,GAAO1lD,IACP6oD,MACD,CAAC7oD,GAAO0lD,GAAQmD,KAEbG,GAAuB/pD,EAAM4d,YAC/B,CAACC,EAAoBmsC,EAAmBpkD,KACpC6iD,GAAS5qC,GACQ,QAAbjY,GAAsBiY,EAAK,IAAMA,EAAK,IAAMkqC,IAAuB8B,GAAehsC,IAE1F,CAAC4qC,GAAUV,GAAuB8B,MAsC/BI,GAAcC,IAAmBlqD,EAAMwd,SAAuB,MAC/D2sC,GAAenqD,EAAM4d,YACtB2qC,IACG,MAAOr4C,EAAGm0B,GAAKkkB,EACf,OAAKr4C,GAAMm0B,EACJ,GAAGn0B,EAAI9D,GAAW8D,EAAG3D,GAAUq7C,MAAmBj1B,GAAW4zB,kBAAkBliB,EAAIj4B,GAAWi4B,EAAG93B,GAAUq7C,KAD7F,IAGzB,CAACr7C,EAAQq7C,GAAiBj1B,GAAW4zB,kBAGlC6D,GAAYC,IAAiBrqD,EAAMwd,SAAS,IAAM2sC,GAAappD,MAC/DupD,GAAWC,IAAgBvqD,EAAMwd,SAAS,IAAMpR,GAAWhO,GAAOmO,KAClEi+C,GAASC,IAAczqD,EAAMwd,SAAS,IAAMpR,GAAW/N,GAAKkO,KAC5Dm+C,GAAcC,IAAmB3qD,EAAMwd,SAA4D,CACtGkwB,QAAQ,EACRtvC,OAAO,EACPC,KAAK,IAIT2B,EAAMgc,UAAU,KACS,WAAjBiuC,KACAI,GAAcF,GAAappD,KAC3B4pD,GAAiBl6B,GAAUA,EAAKid,OAAS,IAAKjd,EAAMid,QAAQ,GAAUjd,IAErD,UAAjBw5B,KACAM,GAAan+C,GAAWhO,GAAOmO,IAC/Bo+C,GAAiBl6B,GAAUA,EAAKryB,MAAQ,IAAKqyB,EAAMryB,OAAO,GAAUqyB,IAEnD,QAAjBw5B,KACAQ,GAAWr+C,GAAW/N,GAAKkO,IAC3Bo+C,GAAiBl6B,GAAUA,EAAKpyB,IAAM,IAAKoyB,EAAMpyB,KAAK,GAAUoyB,KAErE,CAAC1vB,GAAO3C,GAAOC,GAAK4rD,GAAc19C,EAAQ49C,KAE7C,MAAMS,GAAgBzrD,IAClB,MAAMsgD,EAAUtgD,EAAKmV,OACrB,IAAKmrC,GAAWA,EAAQkC,gBAAkBiG,GAAgBjG,cAAe,MAAO,CAAEr1C,KAAM,KAAMu+C,SAAS,GACvG,MAAM1+C,EAASqzC,GAAcC,EAASlzC,GACtC,MAAO,CAAED,KAAMH,EAAQ0+C,QAAmB,MAAV1+C,IAe9B2+C,GAAmBA,CAAChlB,EAAuB3mC,KAChC,UAAT2mC,EAAkBykB,GAAaprD,GAC9BsrD,GAAWtrD,GAChB,MAAMgN,EAASy+C,GAAazrD,GAE5B,GADAwrD,GAAiBl6B,IAAI,IAAWA,EAAMqV,CAACA,GAAO35B,EAAO0+C,WACjD1+C,EAAO0+C,QAAS,OACpB,MAAMhtC,EAA8B,UAATioB,EAAmB,CAAC35B,EAAOG,KAAMjO,IAAO,CAACD,GAAO+N,EAAOG,MAC7E8yC,GAAavhC,EAAM9c,KAAQ0nD,GAAS5qC,IAGvCktC,GAActlD,IAChBykD,GAAiBz5B,GAAUA,IAAShrB,EAAQ,KAAOgrB,GAErC,WAAVhrB,GAAuBilD,GAAahd,QAAQ2c,GAAcF,GAAappD,KAC7D,UAAV0E,GAAsBilD,GAAatsD,OAAOmsD,GAAan+C,GAAWhO,GAAOmO,IAC/D,QAAV9G,GAAoBilD,GAAarsD,KAAKosD,GAAWr+C,GAAW/N,GAAKkO,IAEhEoc,IAAM89B,GAAO1lD,KAGhBiqD,GAAqBA,CAACh6B,EAA8CprB,KACpD,cAAdorB,EAAMlwB,KAAwBkwB,EAAMi6B,OAGf,UAAdj6B,EAAMlwB,MACbkwB,EAAMiB,iBACDtJ,IAAM89B,GAAO1lD,MAJlBiwB,EAAMiB,iBACNu0B,GAAW5gD,KAcb+J,KAAavR,MAAWC,GACxB6sD,GAAqB5C,GAAgBp3B,KAAMmT,GAAW,MAALA,GACjD8mB,KAAc3D,GAAa0D,IAAsBR,GAAahd,QAAUgd,GAAatsD,OAASssD,GAAarsD,IAE3G+sD,IAAcjE,GAChBnnD,EAAAC,cAAA,SAAA,CACIkF,IAAK+jD,GACL59C,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATjF,GAAoB,sBAAqB,aAC5EotB,GAAW6zB,WACvBtkD,MAAOywB,GAAW6zB,WAAU,gBACd,yBACC79B,GACf2J,SAAUA,EACVX,QAAUX,IACNA,EAAMO,kBACF5I,GAAMmhC,KACLtD,OAGTxmD,EAAAC,cAACo+C,GAAa,CAAC94C,KAAe,UAATA,EAAmB,GAAK,MAI/C8lD,GAAcpE,GAAat3C,KAAa2iB,IAAa6vB,GACvDniD,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATjF,GAAoB,mCACvDotB,GAAWwC,MACvBjzB,MAAOywB,GAAWwC,MAClBxD,QArCOX,IACXA,EAAMO,kBACNk3B,GAAS/J,IACTmE,GAAiB,SACjB4D,GAAO/H,MAmCH1+C,EAAAC,cAAC4sB,GAAS,CAACtnB,KAAe,UAATA,EAAmB,GAAK,MAI3C+lD,GAAatrD,EAAMu3B,QACrB,KAAA,IAAaoH,KAAkD38B,IAC/D,CAAC28B,EAAW38B,IAEVupD,GAAoBvrD,EAAMu3B,QAC5B,KAAA,IAAaoH,KAAkDgpB,IAC/D,CAAChpB,EAAWgpB,IAIV6D,GAAgBxrD,EAAMu3B,QACxB,KACK8vB,GAAa,IAAI5jD,IAAI,CAACilD,EAAU3lC,KAC7B,IAAI0oC,EAA8B/M,GAClC,IACI+M,EAAgBlM,GAAemJ,EAASnH,SAAS,CAAEt1C,aACvD,CAAE,MACE,CAEJ,MAAO,CAAEy8C,WAAU5nD,IAAK4nD,EAASv9C,IAAM,GAAGu9C,EAAS17C,SAAS+V,IAAShiB,MAAO0qD,KAEpF,CAACpE,EAAWp7C,KA4CVy/C,GACF1rD,gBAAC4hD,GAAoB,CACjB7gD,MAAOA,GACPqc,SAAU2sC,GACVjI,cAAeA,GACfE,sBAAuBa,GACvBZ,UAAWA,EACXC,cAAeA,EACfnC,QAASA,EACTC,QAASA,EACTH,YAAaA,EACbC,cAAeA,EACfG,kBAAmBA,EACnBmC,4BAA6BA,EAC7B5B,gBAAiBA,EACjB6B,mBAAoBA,EACpBC,sBAAuBA,EACvBC,iBAAkBA,EAClBC,cAAeA,EACf7vB,WAAYA,GACZtzB,UAAWoqD,GACXj6B,WAAS,IAKXm8B,GAAmB,CACrBpmD,OACAmgD,YACApzB,WACA6vB,WACAyD,WACA//B,MAAOslC,IAGX,OACInrD,EAAAC,cAAA,MAAA,CACIkF,IAAKwkD,GACLzgC,UAAW1e,GAAG,UAAWk7C,GAAa,sBAAuBmC,IAAW,iBAAkB3+B,GAAU,iBACpFugC,GAChBznD,MAAOspD,IAENzD,GACG7nD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,kBACXlpB,EAAAC,cAAC2E,GAAS,IACF+mD,GACJhG,OAAK,EACLx6C,GAAIg9C,GACJrwC,KAAMA,EAAO,GAAGA,eAAevK,EAC/BP,MAAO2lB,GAAWv0B,MAClB2C,MAAOupD,GACPhlD,YAAaiiD,GAAmBK,GAChC/B,QAA0B,UAAjBoE,GACTnE,UAAWgC,GACXt4B,UAAWA,EACXnqB,SAAUA,EACV+X,SAAWje,GAAS2rD,GAAiB,QAAS3rD,GAC9ComD,QAASA,KACL2E,GAAgB,SAChBrH,GAAiB,UAErBttB,OAAQA,IAAMw1B,GAAW,SACzBp5B,QAASA,IAAMm2B,IAAuBtB,GAAW,SACjD10B,UAAYd,GAAUg6B,GAAmBh6B,EAAO,WAEpDhxB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,2BAA0B,cAAa,QAClDyJ,GAAW4zB,gBAEhBvmD,EAAAC,cAAC2E,OACO+mD,GACJhG,OAAK,EACLx6C,GAAIi9C,GACJtwC,KAAMA,EAAO,GAAGA,aAAavK,EAC7BP,MAAO2lB,GAAWt0B,IAClB0C,MAAOypD,GACPllD,YAAaiiD,GAAmBK,GAChC/B,QAA0B,QAAjBoE,GACTnE,UAAWgC,GACX/B,UACI/lD,EAAAC,cAAAD,EAAAsuB,SAAA,KACK+8B,GACAD,IAGThuC,SAAWje,GAAS2rD,GAAiB,MAAO3rD,GAC5ComD,QAASA,KACL2E,GAAgB,OAChBrH,GAAiB,QAErBttB,OAAQA,IAAMw1B,GAAW,OACzBp5B,QAASA,IAAMm2B,IAAuBtB,GAAW,OACjD10B,UAAYd,GAAUg6B,GAAmBh6B,EAAO,UAIxDhxB,EAAAC,cAAC2E,GAAS,IACF+mD,GACJxgD,GAAIg9C,GACJrwC,KAAMA,EACN9K,MAAOA,EACPjM,MAAOqpD,GACP9kD,YAAaiiD,GAAmB,GAAGK,MAAmBj1B,GAAW4zB,kBAAkBqB,KACnF/B,QAA0B,WAAjBoE,GACTnE,UAAWgC,GACXt4B,UAAWA,EACXnqB,SAAUA,EACV2gD,UAAoB,MAATh5C,EAAgB2lB,GAAW+zB,kBAAen5C,EACrDw4C,UACI/lD,EAAAC,cAAAD,EAAAsuB,SAAA,KACK+8B,GACAD,IAGThuC,SAvQYje,IACxBkrD,GAAclrD,GACd,MAAO+Q,EAAGm0B,GHhRallC,KAC3B,MAAMysD,EAAQzsD,EAAKiV,MAAM,yCACzB,OAAIw3C,EAAMzhD,QAAU,EAAU,CAACyhD,EAAM,GAAIA,EAAMx2C,MAAM,GAAGxK,KAAK,MACtD,CAACzL,EAAM,KG6QK0sD,CAAe1sD,GACxB2sD,EAAKlB,GAAa16C,GAClB67C,EAAKnB,GAAavmB,GAClBwmB,EAAUiB,EAAGjB,SAAWkB,EAAGlB,QAEjC,GADAF,GAAiBl6B,IAAI,IAAWA,EAAMid,OAAQmd,KAC1CA,EAAS,OACb,MAAMhtC,EAAqB,CAACiuC,EAAGx/C,KAAMy/C,EAAGz/C,MACnC8yC,GAAavhC,EAAM9c,KAAQ0nD,GAAS5qC,IA+P7B0nC,QAASA,IAAM2E,GAAgB,UAC/B30B,OAAQA,IAAMw1B,GAAW,UACzBp5B,QAASA,IAAMm2B,IAAuBtB,KACtC10B,UAAYd,GAAUg6B,GAAmBh6B,EAAO,WAGzC,MAAdy2B,GAAqC,KAAfA,GACnBznD,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,GAAG,iBAAkB2gD,IAAa,0BAA2B1D,GAGjFznD,EAAAC,cAACmvB,GAAO,CACJzG,KAAMA,GACN0G,SAAUA,GACVE,UAAWA,GACXi2B,UAAWsE,GACXzqD,UAAWoqD,GACXvgC,UAAWw+B,EACX1lD,MAAOupD,GACP9F,WAAY7mB,EAAcypB,QAAgB96C,GAE1CvN,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,GAAG,iBAAkBo0B,GAAe,iCAC/CA,GA/Kb5+B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBACXlpB,EAAAC,cAAA,IAAA,CAAGipB,UAAU,wBAAwB/d,GAAIk9C,IACpC11B,GAAW+zB,cAEhB1mD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,yBACXlpB,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GAAqB,UAAlBs3C,IAA6B,iCAC3CnwB,QAASA,IAAMkxB,GAAiB,UAE/BzkD,GAAQgO,GAAWhO,GAAOmO,GAAUomB,GAAWv0B,OAEpD4B,EAAAC,cAAA,OAAA,KAAO0yB,GAAW4zB,gBAClBvmD,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GAAqB,QAAlBs3C,IAA2B,iCACzCnwB,QAASA,IAAMkxB,GAAiB,QAE/BxkD,GAAM+N,GAAW/N,GAAKkO,GAAUomB,GAAWt0B,OA8J5C2B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,uBACVsiC,GAAcrhD,OAAS,GACpBnK,EAAAC,cAAA,KAAA,CAAIipB,UAAU,oBAAmB,aAAY,aACxCsiC,GAAc/nD,IAAI,EAAGilD,WAAU5nD,MAAKC,MAAO0qD,KACxCzrD,EAAAC,cAAA,KAAA,CAAIa,IAAKA,GACLd,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GACP,mBACAmF,IACIyvC,GAAaqM,EAAe1qD,KAC5B,8BAERuxB,SAAUA,GAAY6vB,EACtBxwB,QAASA,IAzXzB+2B,KACpB,MAAM7qC,EAAO0hC,GAAemJ,EAASnH,SAAS,CAAEt1C,cAChDw8C,GAAS5qC,EAAM6qC,GACf7F,GAAiB,SACjBgH,GAAehsC,IAqXoCmuC,CAAetD,IAE7BA,EAAS17C,UAM7B0+C,IA7KjB3uB,EAAQ5yB,OAAS,GACbnK,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBACV6T,EAAQt5B,IAAK05B,GACVn9B,EAAAC,cAAA,SAAA,CACIa,IAAKq8B,EACL7xB,KAAK,SACL4d,UAAW1e,GAAG,eAA2B,WAAX2yB,GAAkC,UAAXA,IAAuB,wBAC5ExL,QAASA,IApNPwL,KAClB,OAAQA,GACJ,IAAK,QACDsrB,GAAS/J,IACTmE,GAAiB,SACjBgH,GAAenL,IACf,MAEJ,IAAK,QAAS,CACV,MAAM8C,EAAQz1C,IAAQU,QAAQ,OACxBoR,EAAqB,CAAC2jC,EAAOA,GACnCiH,GAAS5qC,GACTglC,GAAiB,SACbkF,IAAuB8B,GAAehsC,GAC1C,KACJ,CACA,IAAK,SACIuhC,GAAar+C,GAAOgoD,GAAe/rC,UAAUyrC,GAASM,GAAe/rC,SAC1E4sC,KACA,MAGJ,QACIC,GAAe9oD,MA6LQkrD,CAAa9uB,IAE3BxK,GAAWwK,QA2KpC,GAEAwpB,GAAmBlqC,YAAc,qBC9oB1B,MAAMyvC,GAA2B,gBAO3BC,GAAsB,4nHAgDnC,IAAIvwC,IAAW,EAEf,MAcMC,GACD7b,EAAc8b,qBAAyC,oBAAXnb,OAAyBX,EAAM+b,gBAAkB/b,EAAMgc,WAG3FowC,GAAyBA,KAClChO,KACAviC,GAAa,KApBIK,MACjB,GAAIN,IAAgC,oBAAbpB,SAA0B,OACjD,GAAIA,SAAS2B,eAAe+vC,IAExB,YADAtwC,IAAW,GAGf,MAAM5Z,EAAQwY,SAASva,cAAc,SACrC+B,EAAMmJ,GAAK+gD,GACXlqD,EAAMoa,aAAa,cAAe,QAClCpa,EAAMqa,YAAc8vC,GACpB3xC,SAAS8B,KAAKjB,YAAYrZ,GAC1B4Z,IAAW,GAUPM,IACD,KC7EMmwC,GAAmCtgD,EAAM,cACzCugD,GAAmCvgD,EAAM,cAEzCwgD,GAAiBxrD,GAAiC49C,GAAQ59C,GAE1DyrD,GAAcA,CAAC77C,EAA6BC,IAC/C,MAALD,GAAkB,MAALC,KAAiBD,KAAOC,GAAKD,EAAEkuC,OAAOjuC,EAAG,OAG9C67C,GAAmBA,CAACngD,EAAaogD,IAC1CA,EAAOpgD,EAAKqgD,KAAKD,EAAKC,QAAQC,OAAOF,EAAKE,UAAUC,OAAOH,EAAKG,UAAUC,YAAYJ,EAAKI,eAAiBxgD,EA4BnGygD,GAAeA,CACxBhsD,EACA6C,EACAghB,EAAa7Y,MAEA,MAAThL,EAAsB,KACrBA,EAAMkL,UACPrI,EAAQq8C,oBAAoBl/C,GAAe,oBAC3C6C,EAAQopD,qBAAqBjsD,GAAe,qBAC5C6C,EAAQqpD,oBAAoBlsD,GAAe,oBAC3C6C,EAAQk8C,eAAiBd,GAAWj+C,EAAO6jB,GAAa,gBACxDhhB,EAAQi8C,aAAef,GAAY/9C,EAAO6jB,GAAa,cACvDhhB,EAAQm8C,SAAWjB,GAAY/9C,EAAO6C,EAAQm8C,SAAiB,UAC/Dn8C,EAAQo8C,SAAWhB,GAAWj+C,EAAO6C,EAAQo8C,SAAiB,UAC3D,KARsB,cAWpBkN,GAAiBA,CAAC/N,EAAYv7C,EAAgCghB,IACpC,MAAnCmoC,GAAa5N,EAAKv7C,EAASghB,GAGlBuoC,GAAkBA,CAAC5M,EAAc38C,EAAgCghB,EAAa7Y,OACvF,MAAM3N,EAAQmiD,EAAM9zC,QAAQ,SACtBpO,EAAMkiD,EAAMI,MAAM,SACxB,SAAI/8C,EAAQi8C,cAAef,GAAYzgD,EAAKumB,SACxChhB,EAAQk8C,gBAAiBd,GAAW5gD,EAAOwmB,SAC3ChhB,EAAQm8C,UAAWjB,GAAYzgD,EAAKuF,EAAQm8C,eAC5Cn8C,EAAQo8C,UAAWhB,GAAW5gD,EAAOwF,EAAQo8C,aACxCp8C,EAAQopD,qBAAqB5uD,OAI7BgvD,GAAiBA,CAACC,EAAazpD,EAAgCghB,EAAa7Y,OACrF,MAAM3N,EAAQivD,EAAK5gD,QAAQ,QACrBpO,EAAMgvD,EAAK1M,MAAM,QACvB,SAAI/8C,EAAQi8C,cAAef,GAAYzgD,EAAKumB,SACxChhB,EAAQk8C,gBAAiBd,GAAW5gD,EAAOwmB,SAC3ChhB,EAAQm8C,UAAWjB,GAAYzgD,EAAKuF,EAAQm8C,eAC5Cn8C,EAAQo8C,UAAWhB,GAAW5gD,EAAOwF,EAAQo8C,aACxCp8C,EAAQqpD,oBAAoB7uD,OAO5BkvD,GAAyBA,CAAChhD,EAAa1I,EAAgCghB,EAAa7Y,OAC7F,IAAIg0C,EAAUn8C,EAAQm8C,SAAWsM,GAC7BrM,EAAUp8C,EAAQo8C,SAAWsM,GAGjC,GAFI1oD,EAAQi8C,aAAeb,GAAWp6B,EAAKm7B,KAAUA,EAAUn7B,GAC3DhhB,EAAQk8C,eAAiBhB,GAAYl6B,EAAKo7B,KAAUA,EAAUp7B,GAC9Do6B,GAAWe,EAASC,GAAU,OAAO,KAEzC,IAAIuN,EAAwBjhD,EACxBkhD,EAAyBlhD,EACzBwyC,GAAYxyC,EAAMyzC,KAClBwN,EAAUxN,EACVyN,EAAW,MAEXxO,GAAW1yC,EAAM0zC,KACbwN,IAAUA,EAAWxN,GACzBuN,EAAU,MAEd,IAAIE,EAAQ,EACZ,MAAQF,GAAWC,IAAaC,EAAQ,KAAQ,CAI5C,GAHAA,GAAS,EACLF,GAAWvO,GAAWuO,EAASvN,KAAUuN,EAAU,MACnDC,GAAY1O,GAAY0O,EAAUzN,KAAUyN,EAAW,MACvDD,EAAS,CACT,IAAKL,GAAeK,EAAS3pD,EAASghB,GAAM,OAAO2oC,EACnDA,EAAUA,EAAQ9hD,IAAI,EAAG,MAC7B,CACA,GAAI+hD,EAAU,CACV,IAAKN,GAAeM,EAAU5pD,EAASghB,GAAM,OAAO4oC,EACpDA,EAAWA,EAAS/L,SAAS,EAAG,MACpC,CACJ,CACA,OAAO,MAcEiM,GAAuD,CAChE,CAAE1gD,MAAO,QAASu0C,SAAUA,IAAMx1C,IAAQU,QAAQ,QAClD,CAAEO,MAAO,YAAau0C,SAAUA,IAAMx1C,IAAQ01C,SAAS,EAAG,OAAOh1C,QAAQ,QACzE,CAAEO,MAAO,WAAYu0C,SAAUA,IAAMx1C,IAAQN,IAAI,EAAG,OAAOgB,QAAQ,QACnE,CAAEO,MAAO,gBAAiBu0C,SAAUA,IAAMx1C,IAAQU,QAAQ,SAC1D,CAAEO,MAAO,iBAAkBu0C,SAAUA,IAAMx1C,IAAQU,QAAQ,UAC3D,CAAEO,MAAO,eAAgBu0C,SAAUA,IAAMx1C,IAAQ40C,MAAM,SAASl0C,QAAQ,QACxE,CAAEO,MAAO,QAASu0C,SAAUA,IAAM,OCzHhCG,GAA6BvC,GAAeA,EAAI5yC,OAAO,MAAMuH,OAAO,GAAG6tC,cACvEgM,GAA+B,CAAC,OAAQ,OACxCC,GAA0BC,GACnB,SAATA,EAAkB,6CAA+C,sDAMrDC,IACZ/sD,MAAO8gD,EAAS1kC,aAChBA,EAAYC,SACZA,EAAQ8kC,cACRA,EACA6L,MAAOC,EAASC,OAChBA,EAAS,MACTJ,KAAMK,EAAQC,aACdA,EAAYpO,QACZA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiB+M,mBACjBA,EAAkBC,kBAClBA,EAAiB36B,SACjBA,GAAW,EAAK6vB,SAChBA,GAAW,EAAKC,4BAChBA,GAA8B,EAAK5B,gBACnCA,EAAe6B,mBACfA,EAAqBX,GAAyBY,sBAC9CA,GAAwB,EAAK8L,YAC7BA,EAAc,EAACC,aACfA,EAAe,EAAC7+B,UAChBA,GAAY,EAAKgzB,cACjBA,EAAa8L,aACbA,EAAY37B,WACZA,EAAUtzB,UACVA,EAAS6pB,UACTA,EAASlnB,MACTA,IAEAoqD,KAEA,MAAM2B,EAAQ/tD,EAAMu3B,QAAQ,IAAOy2B,GAAaA,EAAU7jD,OAAS,EAAI6jD,EAAYL,GAAgB,CAACK,IAC9FxM,EAAQz1C,IAGRsR,OAA6B9P,IAAds0C,GACdY,EAAeC,GAAoB1iD,EAAMwd,SAAuB,IAAM+uC,GAAcpvC,GAAgB,OACrGpc,EAAQf,EAAMu3B,QAChB,IAAOla,EAAekvC,GAAc1K,GAAaY,EACjD,CAACplC,EAAcwkC,EAAWY,KAIvB8L,EAAcC,GAAmBxuD,EAAMwd,SAAsB,IAAOuwC,EAAM/F,SAASiG,GAAUA,EAASF,EAAM,IAC7GF,OACWtgD,IAAb2gD,GAA0BH,EAAM/F,SAASkG,GACnCA,EACAH,EAAM/F,SAASuG,GACbA,EACAR,EAAM,GACZU,EAAUzuD,EAAM4d,YACjBC,SACoBtQ,IAAb2gD,GAAwBM,EAAgB3wC,GAC5CswC,IAAetwC,IAEnB,CAACqwC,EAAUC,IAGTrL,EAAa9iD,EAAMu3B,QACrB,KAAA,CAASwoB,UAASC,UAASH,cAAaC,gBAAeG,oBAAmB+M,qBAAoBC,sBAC9F,CAAClN,EAASC,EAASH,EAAaC,EAAeG,EAAmB+M,EAAoBC,KAInFlK,EAAcC,GAAmBhjD,EAAMwd,SAAgB,KAAOzc,GAASmhD,GAAiBV,GAAO/0C,QAAQ,UACxG02C,EAAcnjD,EAAM4d,YACrB2iC,IACG,MAAM1iC,EAAO0iC,EAAM9zC,QAAQ,SACvBs2C,EAAalE,OAAOhhC,EAAM,WAC9BmlC,EAAgBnlC,GAChB2kC,IAAgB3kC,KAEpB,CAACklC,EAAcP,IAIba,EAAcrjD,EAAM+c,OAAqBhc,GAC/Cf,EAAMgc,UAAU,KACZ,MAAMyU,EAAO4yB,EAAYrmC,QACzBqmC,EAAYrmC,QAAUjc,GAClBA,GAAUyrD,GAAY/7B,EAAM1vB,IAAWA,EAAM89C,OAAOkE,EAAc,UAAUI,EAAYpiD,IAE7F,CAACA,IAEJ,MAAM2tD,GAAoB7O,GAAiBE,IAAWf,GAAWwC,EAAOzB,GAAoBA,EAARyB,EAC9EmN,GAAmB7O,GAAmBE,IAAWlB,GAAY0C,EAAOxB,GAAoBA,EAARwB,EAChF8B,GAAaoL,GAAqB3L,EAAa9D,QAAQyP,EAAmB,SAC1EnL,GAAaoL,GAAoB5L,EAAahE,SAAS4P,EAAkB,SAGzEtrB,EAAUrjC,EAAM+c,OAA8B,MAC9C6xC,EAAW5uD,EAAM+c,OAA8B,MAC/CwsB,EAAkBvpC,EAAM+c,OAAOyS,IAC9Bq0B,GAAYC,IAAiB9jD,EAAMwd,SAAgB,IAAMzc,GAASmhD,GAAiBV,GAE1FxhD,EAAMgc,UAAU,KACZ,IAAKutB,EAAgBvsB,QAAS,OAC9B,MAAM7R,EAAKxK,OAAO4a,WAAW,KACzBguB,EAAgBvsB,SAAU,EAC1BqmB,EAAQrmB,SAASqU,cAA2B,gCAAgClH,MAAM,CAAEgsB,eAAe,KACpG,GACH,MAAO,IAAMx1C,OAAOmpB,aAAa3e,KAIrCnL,EAAMgc,UAAU,KACZ,GAAa,SAAT6xC,EAAiB,OACrB,MAAMgB,EAAYD,EAAS5xC,QACrBuJ,EACFsoC,GAAWx9B,cAA2B,2BACtCw9B,GAAWx9B,cAA2B,kBACtCw9B,GAAatoC,IACbsoC,EAAUhlB,UAAYtjB,EAAOuoC,UAAYD,EAAUtiB,aAAe,EAAIhmB,EAAO6J,aAAe,IAEjG,CAACy9B,IAGJ,MAAM54B,GAASj1B,EAAM4d,YACjB,CAACC,EAAakxC,KACV,MAAMhsC,EAAQgrC,EAAM99C,QAAQ8+C,GACtBC,EAAWjsC,GAAS,EAAIgrC,EAAMhrC,EAAQ,QAAKxV,EAC3C0hD,EAAwCD,EAAW,UAAY,SAChE3xC,GAAcqlC,EAAiB7kC,GACpCT,IAAWS,EAAMoxC,EAAgBF,GAC7BC,IACAzlB,EAAgBvsB,SAAU,EAC1ByxC,EAAQO,KAGhB,CAACjB,EAAO1wC,EAAcD,EAAUqxC,IAG9BS,GAAelvD,EAAM4d,YAAY,KACnC,MAAMoxC,EAAWjB,EAAMA,EAAM99C,QAAQ49C,GAAQ,GACxCmB,IACLzlB,EAAgBvsB,SAAU,EAC1ByxC,EAAQO,KACT,CAACjB,EAAOF,EAAMY,IAEX9K,GAAaxE,IACX7sB,GAAY6vB,GAAY+K,GAAe/N,EAAK2D,EAAYtB,KAC5DsC,GAAc3E,GACdlqB,GAAOw3B,GAAiBtN,EAAKp+C,GAASmhD,GAAgB,SAIpDiN,GAAeA,CAACC,EAAkBC,EAAwBN,KAC5D,GAAIz8B,GAAY6vB,EAAU,OAC1B,MAAMmN,EAAcF,EAAU3iD,QAAQ4iD,GAChCE,EAAYH,EAAUzO,MAAM0O,GAC5Bl+B,EAAU+7B,GAAekC,EAAWtM,EAAYtB,GAChD8L,GACI8B,EACA,IACOtM,EACH/C,QAASA,GAAWf,GAAWe,EAASuP,GAAevP,EAAUuP,EACjEtP,QAASA,GAAWlB,GAAYkB,EAASuP,GAAavP,EAAUuP,GAEpE/N,GAEJ4N,EACFj+B,GACAgyB,EAAYhyB,GACZ2yB,GAAc3yB,GACd8D,GAAO9D,EAAS49B,GACH,SAATM,GAAiBf,IAAen9B,KAEpCgyB,EAAYmM,GACZJ,OAIFM,GAAWzuD,GAASmhD,GAAiBV,EAAM/0C,QAAQ,OACnDgjD,GAAcpC,IACZD,GAAerhD,IAAQshD,KAAKA,GAAOvK,EAAYtB,IACnD2N,GD7LeO,EAACpjD,EAAa+gD,KACjC,MAAMr7B,EAAQ1lB,EAAKG,QAAQ,SAAS4gD,KAAKA,GACzC,OAAOZ,GAAiBz6B,EAAM1lB,KAAK/B,KAAKF,IAAIiC,EAAKA,OAAQ0lB,EAAMqzB,gBAAiB/4C,IC2L/DojD,CAAQF,GAAUnC,GAAO,OAAQ,SAE5CsC,GAAepP,IACjB,MAAM6O,ED1LUQ,EAACtjD,EAAai0C,KAClC,MAAMvuB,EAAQ1lB,EAAKG,QAAQ,SAAS8zC,MAAMA,GAC1C,OAAOkM,GAAiBz6B,EAAM1lB,KAAK/B,KAAKF,IAAIiC,EAAKA,OAAQ0lB,EAAMqzB,gBAAiB/4C,ICwL1DsjD,CAASJ,GAASnC,KAAKtK,EAAasK,QAAS9M,GAC3D4M,GAAgBiC,EAAWtM,EAAYtB,IAC3C2N,GAAaC,EAAW,QAAS,UAG/BS,GAAaA,KACM,IAAjB9B,EAAM5jD,QAAgBmoB,IAC1BiX,EAAgBvsB,SAAU,EACL,IAAjB+wC,EAAM5jD,OAAcskD,EAAQV,EAAMpgD,KAAMkD,GAAMA,IAAMg9C,IAASE,EAAM,IAClEU,EAAgC,IAAxBV,EAAM99C,QAAQ49C,GAAcE,EAAM,GAAKA,EAAM,MAQxD+B,GAAgB3Q,IAClB2E,GAAc3E,GACTA,EAAIN,OAAOkE,EAAc,UAAUI,EAAYhE,GACpDx+C,OAAO4a,WAAW,IAPJ4jC,KACd,MAAMr+C,EAAMq+C,EAAI5yC,OAAO,cACvB82B,EAAQrmB,SAASqU,cAAiC,cAAcvwB,QAAUqpB,SAKlD45B,CAAS5E,GAAM,IA0CrC4Q,GAAoBA,CACtB/+B,EACAs4B,EACAtsC,EACAxI,EACAw7C,EACAC,KAEA,MAAMltC,EAAQvO,EAAOvE,QAAQ+M,GAC7B,IAAIkzC,EAAYntC,EAChB,OAAQiO,EAAMlwB,KACV,IAAK,YACDovD,EAAYntC,EAAQ,EACpB,MACJ,IAAK,aACDmtC,EAAYntC,EAAQ,EACpB,MACJ,IAAK,UACDmtC,EAAYntC,EAAQitC,EACpB,MACJ,IAAK,YACDE,EAAYntC,EAAQitC,EACpB,MACJ,IAAK,OACDE,EAAY,EACZ,MACJ,IAAK,MACDA,EAAY17C,EAAOrK,OAAS,EAC5B,MACJ,IAAK,QACL,IAAK,IAGD,OAFA6mB,EAAMiB,sBACNg+B,EAAOjzC,GAEX,QACI,OAERgU,EAAMiB,iBACFi+B,EAAY,GAAKA,GAAa17C,EAAOrK,QACzCk5B,EAAQrmB,SAASqU,cAAiC,IAAIi4B,MAAS90C,EAAO07C,SAAiB/lC,SAIrFgmC,GAAcx9B,GAAYy9B,sCAAwCxC,GAoDlE5J,GAAWhkD,EAAMu3B,QAAQ,IAAM4pB,GAAiBkB,GAAqB,CAACA,IA6J5E,OACIriD,EAAAC,cAAA,MAAA,CACIkF,IAAKk+B,EACLna,UAAW1e,GACP,kBACA8nB,GAAY,4BACZ6vB,GAAY,6BACZj5B,GACH,iBACe7pB,EAAS,YACdwuD,EACX7rD,MAAOA,GA1NXhC,EAAAC,cAAA,MAAA,CAAKipB,UAAU,iBACXlpB,EAAAC,cAAA,MAAA,CACIkvB,KAAK,eACLjG,UAAW1e,GAAG,2BAA6C,IAAjBujD,EAAM5jD,QAAgB,gDACtD,SACVwnB,QAASk+B,IAET7vD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,uBAAuB65B,EAAax2C,OAAO,cACzDwhD,EAAM5jD,OAAS,IAAMmoB,GAClBtyB,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GACP,qDACS,QAATqjD,GAAkB,8BACrB,aACWsC,GAAYtC,IAExB7tD,EAAAC,cAACs+C,GAAiB,QAIpB,QAATsP,GACG7tD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,qBACXlpB,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAU,6CACEyJ,GAAY4xB,eAAiB,iBACzCriD,MAAOywB,GAAY4xB,eAAiB,iBACpCjyB,SAAUA,IAAagxB,EACvB3xB,QAASA,IAAMwxB,EAAYJ,EAAatB,SAAS,EAAG,WAEpDzhD,EAAAC,cAACotB,UAELrtB,EAAAC,cAAA,OAAA,CAAMipB,UAAU,6BAChBlpB,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAU,6CACEyJ,GAAY6xB,WAAa,aACrCtiD,MAAOywB,GAAY6xB,WAAa,aAChClyB,SAAUA,IAAaixB,EACvB5xB,QAASA,IAAMwxB,EAAYJ,EAAat3C,IAAI,EAAG,WAE/CzL,EAAAC,cAACmtB,GAAgB,SAmLnB,QAATygC,GA1KawC,MAClB,MAAMvP,EAAQR,GAAcyC,EAAcvC,GACpC8D,GACDT,GAAWhF,OAAOkE,EAAc,SAAWc,GAAa,QACxD9iD,GAASA,EAAM89C,OAAOkE,EAAc,SAAWhiD,EAAQ,QACvDygD,EAAM3C,OAAOkE,EAAc,SAAWvB,EAAQ,OAC/CuB,EAAat2C,QAAQ,SACzB,OACIzM,EAAAC,cAAA,MAAA,CAAKipB,UAAU,+BAA+BiG,KAAK,qBAAoB4zB,EAAax2C,OAAO,cACvFvM,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBAAmBiG,KAAK,OAClC60B,GAASvgD,IAAKghD,GACXzkD,wBAAMc,IAAK2jD,EAAG3jD,IAAKooB,UAAU,kBAAkBiG,KAAK,eAAc,aAAas1B,EAAGpD,MAC7EoD,EAAGz3C,SAIhBhN,EAAAC,cAAA,MAAA,CAAKipB,UAAU,gBAAgBiG,KAAK,OAAM,aAAa4zB,EAAax2C,OAAO,cACtEu0C,EAAMr9C,IAAKihD,GACR1kD,EAAAC,cAAA,MAAA,CAAKa,IAAK4jD,EAAK5jD,IAAKooB,UAAU,eAAeiG,KAAK,OAC7Cu1B,EAAK1D,KAAKv9C,IAAI,EAAG07C,MAAK+B,mBACnB,MAAM0D,EAAS1D,IAAiBkB,EAC1B/vB,EAAWusB,GAAUO,EAAKp+C,GAC1BuvD,GAAWhO,GAAyB1D,GAAUO,EAAKqC,GACnDyD,EAAc3yB,GAAY46B,GAAe/N,EAAK2D,EAAYtB,GAC1D0D,GAAcN,GAAUhG,GAAUO,EAAKmF,GAC7C,OACItkD,uBACIc,IAAKq+C,EAAI5yC,OAAO,cAChB4iB,KAAK,WAAU,gBACAkD,QAAY9kB,EAC3B2b,UAAU,oBAEVlpB,EAAAC,cAAA,SAAA,CACIqL,KAAK,SAAQ,WACH6zC,EAAI5yC,OAAO,cACrBklB,SAAUyzB,EAAa,GAAI,EAAE,aACjB/F,EAAI5yC,OAAO,sBAAqB,eAC9B+jD,EAAU,YAAS/iD,EAAS,gBAC3B03C,QAAe13C,EAC9B+kB,SAAUsyB,EACV17B,UAAW1e,GACP,cACAo6C,GAAU,sBACV1D,IAAiB0D,GAAU,uBAC3BvyB,GAAY,wBACZi+B,GAAW,qBACXrL,GAAe,yBAEnBtzB,QAASA,IAAMgyB,GAAUxE,GACzBoG,QAASA,IAAMzB,GAAc3E,GAC7BrtB,UAAYd,GA1L3Bu/B,EAACv/B,EAAyCmuB,KAC/D,IAAIthC,EAAqB,KACzB,OAAQmT,EAAMlwB,KACV,IAAK,YACD+c,EAAOshC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,aACD5jC,EAAOshC,EAAI1zC,IAAI,EAAG,OAClB,MACJ,IAAK,UACDoS,EAAOshC,EAAIsC,SAAS,EAAG,OACvB,MACJ,IAAK,YACD5jC,EAAOshC,EAAI1zC,IAAI,EAAG,OAClB,MACJ,IAAK,OACDoS,EAAOshC,EAAI1yC,QAAQ,QACnB,MACJ,IAAK,MACDoR,EAAOshC,EAAIwB,MAAM,QACjB,MACJ,IAAK,SACD9iC,EAAOmT,EAAM4oB,SAAWuF,EAAIsC,SAAS,EAAG,QAAUtC,EAAIsC,SAAS,EAAG,SAClE,MACJ,IAAK,WACD5jC,EAAOmT,EAAM4oB,SAAWuF,EAAI1zC,IAAI,EAAG,QAAU0zC,EAAI1zC,IAAI,EAAG,SACxD,MACJ,IAAK,QACL,IAAK,IAGD,OAFAulB,EAAMiB,sBACN0xB,GAAUxE,GAEd,QACI,OAERnuB,EAAMiB,iBACFpU,GAAMiyC,GAAajyC,IAsJmC0yC,CAAiBv/B,EAAOmuB,IAE7CA,EAAI7yC,gBAsHlB+jD,GACT,UAATxC,GA1Ge2C,MACpB,MAAMC,EAASxmD,MAAM6O,KAAK,CAAE3O,OAAQ,IAAM,CAAC82C,EAAGngC,IAAMA,GAC9C4vC,EAAgB3vD,GAASA,EAAMssD,SAAWtK,EAAasK,OAAStsD,EAAMw/C,QAAU,KAChFoQ,EAAoBnP,EAAM6L,SAAWtK,EAAasK,OAAS7L,EAAMjB,QAAU,KAC3EqQ,EAAWF,GAAiBC,GAAqB,EACvD,OACI3wD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,kCACXlpB,EAAAC,cAAA,MAAA,CAAKipB,UAAU,gBAAgBiG,KAAK,aAAY,aAAa4zB,EAAax2C,OAAO,SAC5EkkD,EAAOhtD,IAAK88C,IACT,MAAMsQ,EAAY9N,EAAaxC,MAAMA,GAC/BuQ,EAAgBx+B,GAAY66B,GAAgB0D,EAAW/N,EAAYtB,GACnEnvB,EAAWq+B,IAAkBnQ,EACnC,OACIvgD,EAAAC,cAAA,MAAA,CAAKa,IAAKy/C,EAAOr3B,UAAW1e,GAAG,cAAgC,IAAjB6jD,GAAsB,2BAChEruD,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL6jB,KAAK,QAAO,aACAoxB,EACZ9uB,SAAUm/B,IAAarQ,EAAQ,GAAI,EAAE,eACvBluB,EAAQ,eACRs+B,IAAsBpQ,EAAQ,YAAShzC,EAAS,gBAC/CujD,QAAiBvjD,EAAS,aAC7BsjD,EAAUtkD,OAAO,aAC7B2c,UAAW1e,GACP,2BACA6nB,GAAY,wBACZs+B,IAAsBpQ,GAAS,uBAC/BuQ,GAAiB,yBAErBn/B,QAASA,IAAMg+B,GAAYpP,GAC3BzuB,UAAYd,GACR++B,GAAkB/+B,EAAO,aAAcuvB,EAAOkQ,EAAQpC,EAAcsB,KAGvEkB,EAAUtkD,OAAO,cAwErBikD,GACX,SAAT3C,GA9DckD,MACnB,MAAMC,EDnWcC,EAAClR,EAAwBC,KACjD,MAAMlnC,GAAQinC,GAAWsM,IAAkCgB,OACrDt0C,GAAMinC,GAAWsM,IAAkCe,OACzD,OAAOpjD,MAAM6O,KAAK,CAAE3O,OAAQI,KAAKD,IAAIyO,EAAKD,EAAO,EAAG,IAAM,CAACmoC,EAAGngC,IAAMhI,EAAOgI,ICgWzDmwC,CAAalR,EAASC,GAC9BkR,EAAenwD,EAAQA,EAAMssD,OAAS,KACtCuD,GACe,MAAhBM,GAAwBF,EAAMhJ,SAASkJ,GAAgBA,EAAe,QACtEF,EAAMhJ,SAASxG,EAAM6L,QAAU7L,EAAM6L,OAAS,QAC9C2D,EAAMhJ,SAASjF,EAAasK,QAAUtK,EAAasK,OAAS2D,EAAM,IACvE,OACIhxD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,iCACXlpB,EAAAC,cAAA,MAAA,CAAKkF,IAAKypD,EAAU1lC,UAAU,eAAeiG,KAAK,aAAY,aAAY,QACrE6hC,EAAMvtD,IAAK4pD,IACR,MAAM8D,EAAWpO,EAAasK,KAAKA,GAC7B+D,EAAe9+B,GAAY86B,GAAe+D,EAAUrO,EAAYtB,GAChEnvB,EAAW6+B,IAAiB7D,EAC5BgE,EAAY7P,EAAM6L,SAAWA,EACnC,OACIrtD,EAAAC,cAAA,MAAA,CAAKa,IAAKusD,EAAMnkC,UAAW1e,GAAG,cAA+B,IAAhB4jD,GAAqB,2BAC9DpuD,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL6jB,KAAK,oBACMk+B,EACX57B,SAAUm/B,IAAavD,EAAO,GAAI,EAAE,eACtBh7B,iBACAg/B,EAAY,YAAS9jD,EAAS,gBAC7B6jD,QAAgB7jD,EAC/B2b,UAAW1e,GACP,0BACA6nB,GAAY,wBACZg/B,GAAa,uBACbD,GAAgB,yBAEpBz/B,QAASA,IAAM89B,GAAWpC,GAC1Bv7B,UAAYd,GACR++B,GAAkB/+B,EAAO,YAAaq8B,EAAM2D,EAAO5C,EAAaqB,KAGnEpC,SA0BL0D,GAGhC,CC5gBO,MAAMO,GAA+D,CACxE9K,WAAa+K,GAAmBA,EAAgB,iCAAiCA,IAAkB,cACnGp8B,MAAO,QACPqsB,MAAO,QACPhJ,OAAQ,SACRiO,OAAQ,KACRlC,cAAe,iBACfC,UAAW,aACX4L,qCAAuCvC,GAC1B,SAATA,EAAkB,6CAA+C,6CACrEnH,aAAc,cACd8K,mBAAoB,MAYXC,GAAgBzxD,EAAMoG,WAA+C,UAE1ErF,MAAO8gD,EAAS1kC,aAChBA,EAAYC,SACZA,EAAQwpC,SACRA,EAAQC,QACRA,EACAl+B,KAAMm+B,EAAQC,OACdA,EAAMz3B,QACNA,EAAOtiB,MACPA,EAAKT,OACLA,EApBe,aAoBQhH,KACvBA,EAAO,QAAOmgD,UACdA,GAAY,EAAKuB,UACjBA,GAAY,EAAKC,YACjBA,GAAc,EAAKC,kBACnBA,GAAoB,EAAKC,cACzBA,EAAaC,UACbA,EAAStqB,QACTA,EAAU,GAAE6B,YACZA,GAAc,EAAK8yB,cACnBA,EA7BuB,aA8BvB/+B,WAAYqM,EAAckjB,cAC1BA,EAAa6L,MACbA,EAAKE,OACLA,EAAMJ,KACNA,EAAIM,aACJA,EAAYpO,QACZA,EAAOC,QACPA,EAAOH,YACPA,EAAWC,cACXA,EAAaG,kBACbA,EAAiB+M,mBACjBA,EAAkBC,kBAClBA,EAAiB36B,SACjBA,GAAW,EAAK6vB,SAChBA,GAAW,EAAKC,4BAChBA,EAA2B5B,gBAC3BA,EAAe6B,mBACfA,EAAkBC,sBAClBA,EAAqB8L,YACrBA,EAAWC,aACXA,EAAY7L,cACZA,EAAa8L,aACbA,EAAYx2C,KACZA,EACA3M,GAAIm8C,EACJhiD,YAAaiiD,EAAe3B,SAC5BA,EACA//B,MAAO2hC,EAASC,WAChBA,EAAUj4B,UACVA,EAASnqB,SACTA,EAAQhG,UACRA,EAASs/B,UACTA,GAASzV,UACTA,GAASlnB,MACTA,GAAK0lD,iBACLA,GAAgBC,aAChBA,GAAYp4B,UACZA,GAAY,gBAEhBpqB,IAEAinD,KAEA,MAAMz5B,GAAa3yB,EAAMu3B,QACrB,KAAA,IAAY+5B,MAAwCtyB,IACpD,CAACA,IAEC4oB,GAAkBj1B,GAAWi1B,iBAAmBr7C,EAChDw7C,GAAwBX,IAAkBrqB,EAAQirB,SAAS,UAE3DC,GAAUjoD,EAAMmjC,QAChBwuB,GAAUrK,GAAU,UAAUW,GAAQ10C,QAAQ,KAAM,MACpD80C,GAAgB,GAAGsJ,WAGnBt0C,QAA6B9P,IAAds0C,GACdY,GAAeC,IAAoB1iD,EAAMwd,SAAuB,IAAM+uC,GAAcpvC,GAAgB,OACrGpc,GAAQf,EAAMu3B,QAChB,IAAOla,GAAekvC,GAAc1K,GAAaY,GACjD,CAACplC,GAAcwkC,EAAWY,KAGxBK,GAAa9iD,EAAMu3B,QACrB,KAAA,CAASwoB,UAASC,UAASH,cAAaC,gBAAeG,oBAAmB+M,qBAAoBC,sBAC9F,CAAClN,EAASC,EAASH,EAAaC,EAAeG,EAAmB+M,EAAoBC,IAEpF3E,GAAkBtoD,EAAMu3B,QAAQ,IAAMw1B,GAAahsD,GAAO+hD,IAAa,CAAC/hD,GAAO+hD,KAC/E72C,GAAUjM,EAAM4d,YAAatR,GAAyD,MAAlCygD,GAAazgD,EAAMw2C,IAAqB,CAACA,KAE7F0F,GAAexoD,EAAM+c,YAA2CxP,GACtEvN,EAAMgc,UAAU,KACZ,MAAMyU,EAAO+3B,GAAaxrC,aACbzP,IAATkjB,GAAsBA,IAAS63B,WACtB/6C,IAATkjB,GAAsB63B,KAAiBzB,IAAUyB,GAAiBvnD,IACtEynD,GAAaxrC,QAAUsrC,KACxB,CAACA,GAAiBvnD,GAAO8lD,IAE5B,MAAM4B,GAAWzoD,EAAM4d,YACnB,CAACC,EAAoB6qC,KACZrrC,IAAcqlC,GAAiB7kC,GACpC,MAAM8qC,EAAgC,CAAEL,gBAAiByE,GAAalvC,EAAMilC,KACxE4F,IAAUC,EAAQD,SAAWA,GACjCtrC,IAAWS,EAAM8qC,IAErB,CAACtrC,GAAcD,EAAU0lC,KAIvB8F,QAAgCr7C,IAAbu5C,GAClB+B,GAAcC,IAAmB9oD,EAAMwd,UAAS,GACjDmL,GAAOigC,KAAqB9B,EAAW+B,GACvCE,GAAiB/oD,EAAM+c,OAAqBhc,IAC5CioD,GAAkBhpD,EAAM+c,OAAqBhc,IAG7C0lD,GAASzmD,EAAM4d,YACjB,CAACC,EAAoBorC,GAAQ,MACpBA,GAASuD,GAAY3uC,EAAMmrC,GAAgBhsC,WAChDgsC,GAAgBhsC,QAAUa,EAC1B+oC,IAAW/oC,KAEf,CAAC+oC,IAECvjB,GAAUrjC,EAAM+c,OAA8B,MAC9CmsC,GAAYlpD,EAAM+c,OAAiC,MACnDosC,GAAkBnpD,EAAM+c,OAA2B,OAIlDqsC,GAAgBC,IAAqBrpD,EAAMwd,cAAuCjQ,GACzFvN,EAAMgc,UAAU,KACZ,QAAkBzO,IAAdlO,EAAyB,OAC7B,MAAMiqD,EAAOjmB,GAAQrmB,SAASusC,eAAep4B,QAAQ,qBAAqBq4B,aAAa,kBACvFH,GAA2B,SAATC,EAAkB,OAAkB,UAATA,EAAmB,aAAU/7C,KAE9E,MAAMk8C,GAAqBpqD,GAAa+pD,IAIjC/5B,GAAUq6B,IAAe1pD,EAAMwd,SAAgC,MAChEmsC,GAAa3pD,EAAM4d,YACpBwN,IACGiY,GAAQrmB,QAAUoO,EAClBs+B,GAAYt+B,GACO,mBAARjmB,GAAoBA,GAAIimB,GAC1BjmB,KAAMA,GAAsD6X,QAAUoO,IAEnF,CAACjmB,KAGCqhD,GAAaxmD,EAAM4d,YAAY,KAC7B0U,GAAY6vB,GAAYx5B,KAC5BogC,GAAe/rC,QAAUjc,GACzBooD,GAAgBnsC,QAAWxC,SAAS2X,eAAwC,KACvEy2B,IAAkBE,IAAgB,GACvC/B,QACD,CAACz0B,EAAU6vB,EAAUx5B,GAAM5nB,GAAO6nD,GAAkB7B,IAEjD6C,GAAc5pD,EAAM4d,YAAY,KAClC,IAAK+K,GAAM,OACNigC,IAAkBE,IAAgB,GACvCx5B,MACA,MAAM/I,EAAS2iC,GAAUlsC,SAAWmsC,GAAgBnsC,QACpDrc,OAAO4a,WAAW,IAAMgL,GAAQ4D,UAAW,IAC5C,CAACxB,GAAMigC,GAAkBt5B,IAEtBu6B,GAAiB7pD,EAAM4d,YACxBC,IACG4oC,GAAO5oC,GAAM,GACb+rC,MAEJ,CAACnD,GAAQmD,KAGPE,GAAgB9pD,EAAM4d,YAAY,KAEpC6oC,GAAO1lD,IACP6oD,MACD,CAAC7oD,GAAO0lD,GAAQmD,KAEbG,GAAuB/pD,EAAM4d,YAC/B,CAACC,EAAoBoxC,KACjBxG,GAAS5qC,GACc,WAAnBoxC,GAA+BlH,IAAuB8B,GAAehsC,IAE7E,CAAC4qC,GAAUV,GAAuB8B,MAkC/BhE,GAAS+L,IAAc5xD,EAAMwd,UAAS,IACtCre,GAAMy1B,IAAW50B,EAAMwd,SAAS,IAAMpR,GAAWrL,GAAOwL,KACxDm+C,GAAcC,IAAmB3qD,EAAMwd,UAAS,GAIjDq0C,GAAa7xD,EAAM+c,OAAO8oC,IAChCgM,GAAW70C,QAAU6oC,GACrB7lD,EAAMgc,UAAU,KACR61C,GAAW70C,UACf4X,GAAQxoB,GAAWrL,GAAOwL,IAC1Bo+C,IAAgB,KACjB,CAAC5pD,GAAOwL,IAEX,MAqCMoD,GAAoB,MAAT5O,GACXoqD,KAAc3D,GAAgC,MAAnBc,IAA2BoC,GACtD5U,GAAiBnmC,GAAWvD,GAAWrL,GAAOwL,GAAU,KAExD6+C,IAAcjE,GAChBnnD,EAAAC,cAAA,SAAA,CACIkF,IAAK+jD,GACL59C,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATjF,GAAoB,sBAAqB,aAC5EotB,GAAW6zB,WAAW1Q,IAClC5zC,MAAOywB,GAAW6zB,WAAW1Q,IAAe,gBAC9B,SAAQ,gBACPntB,GACf2J,SAAUA,EACVX,QAAUX,IACNA,EAAMO,kBACF5I,GAAMmhC,KACLtD,OAGTxmD,EAAAC,cAACq+C,GAAY,CAAC/4C,KAAe,UAATA,EAAmB,GAAK,MAI9C8lD,GAAcpE,GAAat3C,KAAa2iB,IAAa6vB,GACvDniD,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GAAG,gCAA0C,UAATjF,GAAoB,mCACvDotB,GAAWwC,MACvBjzB,MAAOywB,GAAWwC,MAClBxD,QApCOX,IACXA,EAAMO,kBACNk3B,GAAS,MACThC,GAAO,QAmCHzmD,EAAAC,cAAC4sB,GAAS,CAACtnB,KAAe,UAATA,EAAmB,GAAK,MAI3C+lD,GAAatrD,EAAMu3B,QACrB,KAAA,IAAaoH,MAAkD38B,KAC/D,CAAC28B,GAAW38B,KAEVupD,GAAoBvrD,EAAMu3B,QAC5B,KAAA,IAAaoH,MAAkDgpB,KAC/D,CAAChpB,GAAWgpB,KAIV6D,GAAgBxrD,EAAMu3B,QACxB,KACK8vB,GAAa,IAAI5jD,IAAI,CAACilD,EAAU3lC,KAC7B,IAAI0oC,EAA8B,KAClC,IACIA,EAAgBc,GAAc7D,EAASnH,SAAS,CAAEt1C,aACtD,CAAE,MACE,CAEJ,MAAO,CAAEy8C,WAAU5nD,IAAK4nD,EAASv9C,IAAM,GAAGu9C,EAAS17C,SAAS+V,IAAShiB,MAAO0qD,KAEpF,CAACpE,EAAWp7C,KA8BhB,OACIjM,uBACImF,IAAKwkD,GACLzgC,UAAW1e,GAAG,iBAAkBk7C,GAAa,sBAAuBx8B,qBACpDugC,GAChBznD,MAAOspD,IAEPtrD,EAAAC,cAAC2E,GAAS,CACNuG,GAAIwmD,GACJ75C,KAAMA,EACN9K,MAAOA,EACPjM,MAAO5B,GACPmG,YAAaiiD,GAAmBK,GAChCriD,KAAMA,EACNmgD,UAAWA,EACXpzB,SAAUA,EACV6vB,SAAUA,EACVyD,SAAUA,EACV//B,MAAOslC,GACPtF,QAASA,GACTC,UAAWoB,EACX13B,UAAWA,EACXnqB,SAAUA,EACV2gD,UAAoB,MAATh5C,EAAgB2lB,GAAW+zB,kBAAen5C,EACrDw4C,UACI/lD,EAAAC,cAAAD,EAAAsuB,SAAA,KACK+8B,GACAD,IAGThuC,SA1Jc00C,IACtBl9B,GAAQk9B,GACR,MAAMrS,EAAUqS,EAASx9C,OACzB,IAAKmrC,GAAWA,EAAQkC,gBAAkBiG,GAAgBjG,cAGtD,OAFAgJ,IAAgB,QACF,OAAV5pD,IAAgB0nD,GAAS,OAGjC,MAAMt8C,EAASqzC,GAAcC,EAASlzC,GACtCo+C,GAA0B,MAAVx+C,GACZA,IAAWqgD,GAAYrgD,EAAQpL,KAAQ0nD,GAASt8C,IAiJ5Co5C,QAASA,IAAMqM,IAAW,GAC1Br8B,OA/IOw1B,KACf6G,IAAW,GAENlH,IAAc91B,GAAQxoB,GAAWrL,GAAOwL,IAExCoc,IAAM89B,GAAO1lD,KA2IV4wB,QAASA,IAAMu1B,GAAeV,KAC9B10B,UAzIgBd,IACN,cAAdA,EAAMlwB,KAAwBkwB,EAAMi6B,OAGf,UAAdj6B,EAAMlwB,MACbkwB,EAAMiB,iBACDtJ,IAAM89B,GAAO1lD,MAJlBiwB,EAAMiB,iBACNu0B,SAwIe,MAAdiB,GAAqC,KAAfA,GACnBznD,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,GAAG,iBAAkB2gD,IAAa,0BAA2B1D,GAGjFznD,EAAAC,cAACmvB,GAAO,CACJzG,KAAMA,GACN0G,SAAUA,GACVE,UAAWA,GACXi2B,UAAWsE,GACXzqD,UAAWoqD,GACXvgC,UAAWw+B,GACX1lD,MAAOupD,GACP9F,WAAY7mB,EAAcypB,QAAgB96C,GAE1CvN,EAAAC,cAAA,MAAA,CAAKipB,UAAW1e,GAAG,iBAAkBo0B,GAAe,iCAC/CA,GA7Eb5+B,EAAAC,cAAA,MAAA,CAAKipB,UAAU,kCACXlpB,EAAAC,cAAA,IAAA,CAAGipB,UAAU,wBAAwB/d,GAAIk9C,IACpC11B,GAAW+zB,cAEhB1mD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,sBAAqB,YAAW,UAC1CnoB,GAAQA,GAAMwL,OAAOmlD,GAAiB/+B,GAAW6+B,qBAyE9CxxD,EAAAC,cAAA,MAAA,CAAKipB,UAAU,uBACVsiC,GAAcrhD,OAAS,GACpBnK,EAAAC,cAAA,KAAA,CAAIipB,UAAU,oBAAmB,aAAY,aACxCsiC,GAAc/nD,IAAI,EAAGilD,WAAU5nD,MAAKC,MAAO0qD,KACxCzrD,EAAAC,cAAA,KAAA,CAAIa,IAAKA,GACLd,EAAAC,cAAA,SAAA,CACIqL,KAAK,SACL4d,UAAW1e,GACP,mBACAmF,IAAY68C,GAAYf,EAAe1qD,KAAU,8BAErDuxB,SAAUA,GAAY6vB,EACtBxwB,QAASA,IAzOzB+2B,KACpB,MAAM7qC,EAAO0uC,GAAc7D,EAASnH,SAAS,CAAEt1C,cAC/Cw8C,GAAS5qC,EAAM6qC,GACfmB,GAAehsC,IAsOoCmuC,CAAetD,IAE7BA,EAAS17C,UAM9BhN,EAAAC,cAAC6tD,IACG/sD,MAAOA,GACPqc,SAAU2sC,GACV7H,cAAeA,EACf6L,MAAOA,EACPE,OAAQA,EACRJ,KAAMA,EACNM,aAAcA,EACdpO,QAASA,EACTC,QAASA,EACTH,YAAaA,EACbC,cAAeA,EACfG,kBAAmBA,EACnB+M,mBAAoBA,EACpBC,kBAAmBA,EACnB7K,4BAA6BA,EAC7B5B,gBAAiBA,EACjB6B,mBAAoBA,EACpBC,sBAAuBA,EACvB8L,YAAaA,EACbC,aAAcA,EACd7L,cAAeA,EACf8L,aAAcA,EACd37B,WAAYA,GACZtzB,UAAWoqD,GACXj6B,WAAS,KAhH7BuN,EAAQ5yB,OAAS,GACbnK,EAAAC,cAAA,MAAA,CAAKipB,UAAU,mBACV6T,EAAQt5B,IAAK05B,GACVn9B,EAAAC,cAAA,SAAA,CACIa,IAAKq8B,EACL7xB,KAAK,SACL4d,UAAW1e,GAAG,eAA2B,WAAX2yB,GAAkC,UAAXA,IAAuB,wBAC5ExL,QAASA,IA3JPwL,KAClB,OAAQA,GACJ,IAAK,QACDsrB,GAAS,MACToB,GAAe,MACf,MAEJ,IAAK,QAAS,CACV,MAAMhsC,EAAO9R,IAAQU,QAAQ,OAC7Bg8C,GAAS5qC,GACLkqC,IAAuB8B,GAAehsC,GAC1C,KACJ,CACA,IAAK,SACI2uC,GAAYzrD,GAAOgoD,GAAe/rC,UAAUyrC,GAASM,GAAe/rC,SACzE4sC,KACA,MAGJ,QACIC,GAAe9oD,MAuIQkrD,CAAa9uB,IAE3BxK,GAAWwK,QA+GpC,GAEAs0B,GAAch1C,YAAc,sCCjfd,UAAwBva,MAAEA,EAAK+1C,QAAEA,EAAO9a,OAAEA,EAAMxU,KAAEA,EAAI2G,QAAEA,KAAY/rB,IAChF,OACEvD,EAAAC,cAAC8xD,GAAOrM,WAAS,EAACllD,SAAS,KAAKmoB,KAAMA,EAAM2G,QAASA,KAAa/rB,GAChEvD,EAAAC,cAAC+xD,EAAW,CAAC1xD,GAAI,CAAE2xD,GAAI,IAAM/vD,GAE5B+1C,GAAWj4C,EAAAC,cAACiyD,EAAa,CAAC5xD,GAAI,CAAE0H,WAAY,cAAaiwC,EAAyB,KAEnFj4C,EAAAC,cAACkyD,EAAa,KACZnyD,EAAAC,cAACsuB,EAAM,CAACoD,QAASrC,GAAO,UACvB6N,GAIT,kCCbc,UAAkCh6B,WAC5CA,EAAa,CAAEC,YAAY,GAAMC,aACjCA,EAAe,CAAED,YAAY,GAAME,aACnCA,EAAYzB,eAEZA,KACG0B,IAEH,OACIvD,EAAAC,cAACuD,6BAA0B,IACnBD,GAGH1B,EACD7B,EAAAC,cAAC0D,wBAAqB,CAACC,QAAST,IAChCnD,EAAAC,cAAC4D,0BAAuB,CAACD,QAASP,IAClCrD,EAAAC,cAAC6D,2BAAwBF,QAASN,IAG9C,sFCnBc,UAA0BqlB,KACtCA,EAAIxpB,KACJA,EACEa,EAAAC,cAAAD,EAAAsuB,SAAA,4GACsGtuB,EAAAC,cAAA,KAAA,MACpGD,EAAAC,cAAA,KAAA,MAEC,2DAGL,OACED,EAAAC,cAAC8xD,SAAM,CAACppC,KAAMA,EAAM+8B,WAAS,EAACplD,GAAI,CAAE8xD,EAAG,IACrCpyD,EAAAC,cAACiyD,gBAAa,CAAC5xD,GAAI,CAAE8xD,EAAG,EAAGC,UAAW,WACpCryD,EAAAC,cAACqyD,aAAU,CAACvvD,QAAQ,YAAYzC,GAAI,CAAEG,GAAI,IACvCtB,GAEHa,EAAAC,cAACsyD,EAAAA,iBAAgB,OAIzB,kRjCkHc,UAAsBp+B,OAChCA,EAAMpV,KACNA,EAAIb,QACJA,EAAOqjB,WACPA,EAAUC,iBACVA,EAAgBxK,WAChBA,GAAa,EAAIb,SACjBA,EAAW,GAAE2I,MACbA,EAAQ,CAAA,EAAEt5B,UACVA,EAAY,CAAA,EAAEq5B,aACdA,EAAe,CAAA,EAAEiE,aACjBA,EAAe,CAAA,EAAEvM,gBACjBA,EAAkB,CAAC,GAAI,GAAI,GAAI,KAAIj2B,GACnCA,EAAK,CAAA,EAAEk+B,OACPA,EAAS,CAAE9W,SAAU,GAAGgX,MACxBA,EAAQ,CAAEhX,SAAU,GAAGiQ,sBACvBA,EAAqBuI,8BACrBA,EAA6BC,2BAC7BA,EAA0BC,sBAC1BA,EAAqBpK,uBACrBA,GAAyB,EAAKgL,2BAC9BA,GAA6B,EAAIlL,oBACjCA,GAAsB,EAAKtjB,kBAC3BA,GAAoB,EAAKojB,sBACzBA,GAAwB,EAAKmL,6BAC7BA,GAA+B,EAAK7C,uBACpCA,EAAsBC,0BACtBA,EAAyBY,WACzBA,EAAa,4CAA2C+B,kBACxDA,GAAoB,EAAKK,0BACzBA,EAAqCvK,kBACrCA,EAA6B0K,gBAC7BA,EAA2BM,sBAC3BA,EAAqBC,qBACrBA,EAAoB5D,QACpBA,GAAU,EAAKmD,gBACfA,EAA2BhC,aAC3BA,EAAYR,YACZA,GAAc,EAAIzH,mBAClBA,GAAqB,EAAKoJ,oBAC1BA,EAA+B4B,8BAC/BA,EAAyCR,WACzCA,EAAsBN,4BACtBA,GAA8B,IAE9B,MAAMmc,EAASt/C,EAAc,OAAQ,MAC/Bs0D,EAAiCxyD,EAAMu3B,QAAQ,KACjD,GAAK4I,EAGL,OAAOt/B,EAA4Cs/B,SAA+B5yB,GACnF,CAAC4yB,IAEEsyB,EAAyBzyD,EAAMu3B,QAAQ,KACzC,IAAK6I,EACD,OAGJ,MAlEuBsyB,EAACloB,EAAgCtsB,KAC5D,IAAKssB,GAA0C,IAAzBA,EAAcrgC,OAChC,OAEJ,MAAMwoD,EAAe,IAAItpD,IAAI6U,EAAQza,IAAK60B,GAAWA,EAAOzuB,QAC5D,OAAO2gC,EAAc9/B,OAAQb,GAAU8oD,EAAa7oD,IAAID,KA6D7C6oD,CADa7xD,EAA2Bu/B,GACJliB,IAC5C,CAACkiB,EAAuBliB,IAErB00C,QACwBrlD,IAA1BoqB,EAAsCA,EAAwB66B,EAE5DK,GAAoC7yD,EAAM4d,YAC5C,CAAC8Z,EAAkCo7B,KAC3B3yB,GACAh/B,EAAkBg/B,EAA4BzI,GAElDwI,IAAgCxI,EAAOo7B,IAE3C,CAAC3yB,EAA4BD,IAG3B6yB,GAA0B/yD,EAAM4d,YAClC,CAAC6H,EAAQuL,EAAO8hC,KACZ,GAAI1yB,EAAuB,CACvB,MAAMoK,EAAgBsoB,EAAQzlD,IAAIgR,gBAAgB5a,IAAK60B,GAAWA,EAAOzuB,OACzE1I,EAAkBi/B,EAAuBoK,EAC7C,CACAjK,IAAsB9a,EAAQuL,EAAO8hC,IAEzC,CAAC1yB,EAAuBG,IAGtByyB,GAA8C,CAChD1/B,QAAS,UACT0D,WAAY,CAAEZ,gBAAiB,CAAED,aACjCzrB,OAAQ,CACJwuB,YAAa,CACTtO,MAAO,GACP8S,iCAAiC,OAGtCoF,EACH5kB,QAAS,IACF4kB,GAAc5kB,QACjByZ,sBAAuBi7B,IAAiC9vB,GAAc5kB,SAASyZ,sBAC/E6S,cAAeioB,GAA0B3vB,GAAc5kB,SAASssB,gBAIxE,OACIxqC,EAAAC,cAACgzD,OAAI,CAAC3yD,GAAI,CAAET,OAAQ,UAAW2+B,IAC3Bx+B,EAAAC,cAACC,OAAII,GAAI,CAAEZ,QAAS,OAAQE,eAAgB,gBAAiBD,WAAY,SAAUkJ,GAAI,IACnF7I,EAAAC,cAACizD,aAAU,CAAChxD,MAAOiyB,EAAQ7zB,GAAI,CAAEG,GAAI,KACpC09B,EACDn+B,EAAAC,cAACC,EAAAA,IAAG,CACAI,GAAI,CACAZ,QAAS,OACT68B,IAAKihB,EAAS,EAAI,EAClB79C,WAAY,SACZwzD,SAAU,OACVvzD,eAAgB,aAGnBs+B,IAGTl+B,EAAAC,cAACC,EAAAA,KAAIC,UAAU,MAAMG,GAAI,CAAEZ,QAAS,OAAQ0zD,cAAe,SAAU1rC,SAAU,KAAMgX,IACjF1+B,EAAAC,cAACozD,kBAAe,CACZp1B,QAASA,EACTsD,WAAYA,EACZC,iBAAkBA,EAClBziB,KAAMA,EACNb,QAASA,EACT8Y,WAAYA,EACZhB,uBAAwBA,EACxBgL,2BAA4BA,EAC5BlL,oBAAqBA,EACrBtjB,kBAAmBA,EACnBojB,sBAAuBA,EACvBkJ,MAAO,CAAE8d,cAAe19C,EAAqBs9C,QAASl7C,KAAmBw9B,GACzEt5B,UAAW,CAAEo3C,cAAe,CAAEz9C,KAAM4/B,GAAcyd,QAAS3d,KAAiBr5B,GAC5Es9B,aAAckwB,GACdz8B,gBAAiBA,EACjBj2B,GAAI,CACA,2BAA4B,CACxBqH,OAAQ45B,GAAcC,EAAmB,UAAY,cAEtDlhC,GAGP4/B,8BAA+B2yB,GAC/B/xB,kBAAmBA,EACnBK,0BAA2BA,EAC3BvK,kBAAmBA,EACnBwK,gBAAiBA,EACjBE,gBAAiBA,EACjBM,sBAAuBA,EACvBC,qBAAsBA,EACtBd,6BAA8BA,EAC9BuyB,iCAA+B,EAC/B10B,YAAaA,EACbzH,mBAAoBA,EACpBiI,aAAcA,EACdmB,oBAAqBwyB,GACrB5wB,8BAA+BA,EAC/BR,WAAYA,EACZN,4BAA6BA,KAKjD,qkEQ+JsCkyB,CAAClmD,EAAiBzJ,EAAqC,MACzF,GAAwB,oBAAb4W,SAA0B,OACrC,MAAMmF,EAAiB/b,EAAQ+b,iBAAkB,EAC3CC,EAAQ3B,GAAiB5Q,EAAKzJ,GAC9B1B,EAAQ0B,EAAQ1B,OAAS0B,EAAQiX,UAAYL,SAAStY,OAAS,GAE/DsxD,EAAa7zC,EACb,cAAcC,EAAMX,QACfxb,IAAI,CAACqc,EAAGgB,IAAM,cAAclB,EAAM1B,QAAQ4C,GAAGhP,OAAS,WAAWyT,GAAWzF,WAC5ElV,KAAK,mBACV,GACA6oD,EAAW,UAAU7zC,EAAMb,KAC5Btb,IACIsc,GACG,OAAOA,EACFtc,IAAK+M,GAAS,cAAcA,EAAK1D,IAAIgF,OAAS,WAAWyT,GAAW/U,EAAKxC,mBACzEpD,KAAK,YAEjBA,KAAK,cAEJ8oD,EAEF,6DAAUnuC,GAAWrjB,2eASpB0B,EAAQolB,WAAa,IACtB,yBACC9mB,EAAQ,OAAOqjB,GAAWrjB,UAAgB,IAC3C,UAAUsxD,IAAaC,0BAGrBrrC,EAAS5N,SAASva,cAAc,UACtCmoB,EAAOhM,aAAa,cAAe,QACnCgM,EAAOpmB,MAAM4D,SAAW,QACxBwiB,EAAOpmB,MAAMuuB,MAAQ,IACrBnI,EAAOpmB,MAAMwuB,OAAS,IACtBpI,EAAOpmB,MAAMzB,MAAQ,IACrB6nB,EAAOpmB,MAAMnC,OAAS,IACtBuoB,EAAOpmB,MAAMkF,OAAS,IACtBkhB,EAAOpmB,MAAMqC,QAAU,IACvBmW,SAASY,KAAKC,YAAY+M,GAE1B,MAAMurC,EAAUA,KACZhzD,OAAO4a,WAAW,KACV6M,EAAOG,YAAYH,EAAOG,WAAW/M,YAAY4M,IACtD,MAGPA,EAAOwrC,OAAS,KACZ,MAAMprC,EAAMJ,EAAOK,cACnB,GAAKD,EAIL,IACIA,EAAI2B,QACJ3B,EAAI0B,aAAeypC,EACnBnrC,EAAI4B,OACR,CAAE,MACEupC,GACJ,MATIA,KAYR,MAAM9rC,EAAMO,EAAOM,iBAAmBN,EAAOK,eAAejO,SACxDqN,GACAA,EAAIc,OACJd,EAAIe,MAAM8qC,GACV7rC,EAAIgB,SAEJT,EAAOyrC,OAASH,+LFveYI,IAA4Cp3C,KAAoBrP,6BAKpE0mD,IAC5B/zD,EAAM+c,OAA6B,gEAJHi3C,IAAMt3C,KAAoBiW"}