import { Field, ParsedFilter, Filter, FilterBase, PolygonFilter, FieldDomain, TimeRangeFieldDomain, Feature, FeatureValue, LineChart, TimeRangeFilter, RangeFieldDomain, FilterDatasetOpt, FilterRecord, AnimationConfig } from '@kepler.gl/types';
import { DataContainerInterface } from './data-container-interface';
import { KeplerTableModel } from './types';
export declare const durationSecond = 1000;
export declare const durationMinute: number;
export declare const durationHour: number;
export declare const durationDay: number;
export declare const durationWeek: number;
export declare const durationYear: number;
type VisState = any;
export type FilterResult = {
    filteredIndexForDomain?: number[];
    filteredIndex?: number[];
};
export type FilterChanged = {
    [key in keyof FilterRecord]: {
        [key: string]: 'added' | 'deleted' | 'name_changed' | 'value_changed' | 'dataId_changed';
    } | null;
};
export type dataValueAccessor = (data: {
    index: number;
}) => number | null;
export declare const TimestampStepMap: {
    max: number;
    step: number;
}[];
export declare const FILTER_UPDATER_PROPS: {
    dataId: "dataId";
    name: "name";
    layerId: "layerId";
};
export declare const FILTER_COMPONENTS: {
    select: string;
    multiSelect: string;
    timeRange: string;
    range: string;
    polygon: string;
};
export declare const DEFAULT_FILTER_STRUCTURE: {
    dataId: never[];
    id: null;
    enabled: boolean;
    fixedDomain: boolean;
    view: "side";
    isAnimating: boolean;
    animationWindow: "free";
    speed: number;
    name: never[];
    type: null;
    fieldIdx: never[];
    domain: null;
    value: null;
    plotType: {
        type: "histogram";
    };
    yAxis: null;
    gpu: boolean;
};
export declare const FILTER_ID_LENGTH = 4;
export declare const LAYER_FILTERS: "polygon"[];
/**
 * Generates a filter with a dataset id as dataId
 */
export declare function getDefaultFilter({ dataId, id }?: {
    dataId?: string | null | string[];
    id?: string;
}): FilterBase<LineChart>;
/**
 * Check if a filter is valid based on the given dataId
 * @param  filter to validate
 * @param  datasetId id to validate filter against
 * @return true if a filter is valid, false otherwise
 */
export declare function shouldApplyFilter(filter: Filter, datasetId: string): boolean;
/**
 * Validates and modifies polygon filter structure
 * @param dataset
 * @param filter
 * @param layers
 * @return - {filter, dataset}
 */
export declare function validatePolygonFilter<K extends KeplerTableModel<K, L>, L extends {
    id: string;
}>(dataset: K, filter: PolygonFilter, layers: L[]): {
    filter: PolygonFilter | null;
    dataset: K;
};
/**
 * Default validate filter function
 * @param datasets
 * @param datasetId
 * @param filter
 * @return - {filter, dataset}
 */
export declare function validateFilter<K extends KeplerTableModel<K, L>, L>(datasets: Record<string, K>, datasetId: string, filter: ParsedFilter): {
    filter: Filter | null;
    dataset: K;
};
/**
 * Validate saved filter config with new data
 *
 * @param datasets
 * @param datasetId
 * @param filter - filter to be validate
 * @param layers - layers
 * @return validated filter
 */
export declare function validateFilterWithData<K extends KeplerTableModel<K, L>, L>(datasets: Record<string, K>, datasetId: string, filter: ParsedFilter, layers: L[]): {
    filter: Filter;
    dataset: K;
};
/**
 * Get default filter prop based on field type
 *
 * @param field
 * @param fieldDomain
 * @returns default filter
 */
export declare function getFilterProps(field: Field, fieldDomain: FieldDomain): Partial<Filter> & {
    fieldType: string;
};
export declare const getPolygonFilterFunctor: (layer: any, filter: any, dataContainer: any) => (data: any) => any;
/**
 * Check if a GeoJSON feature filter can be applied to a layer
 */
export declare function canApplyFeatureFilter(feature: Feature | null): boolean;
/**
 * @param param An object that represents a row record.
 * @param param.index Index of the row in data container.
 * @returns Returns true to keep the element, or false otherwise.
 */
type filterFunction = (data: {
    index: number;
}) => boolean;
/**
 * @param field dataset Field
 * @param dataId Dataset id
 * @param filter Filter object
 * @param layers list of layers to filter upon
 * @param dataContainer Data container
 * @return filterFunction
 */
export declare function getFilterFunction<L extends {
    config: {
        dataId: string | null;
    };
    id: string;
}>(field: Field | null, dataId: string, filter: Filter, layers: L[], dataContainer: DataContainerInterface): filterFunction;
export declare function updateFilterDataId(dataId: string | string[]): FilterBase<LineChart>;
export declare function filterDataByFilterTypes({ dynamicDomainFilters, cpuFilters, filterFuncs }: {
    dynamicDomainFilters: Filter[] | null;
    cpuFilters: Filter[] | null;
    filterFuncs: {
        [key: string]: filterFunction;
    };
}, dataContainer: DataContainerInterface): FilterResult;
/**
 * Get a record of filters based on domain type and gpu / cpu
 */
export declare function getFilterRecord(dataId: string, filters: Filter[], opt?: FilterDatasetOpt): FilterRecord;
/**
 * Compare filter records to get what has changed
 */
export declare function diffFilters(filterRecord: FilterRecord, oldFilterRecord?: FilterRecord | Record<string, never>): FilterChanged;
/**
 * Call by parsing filters from URL
 * Check if value of filter within filter domain, if not adjust it to match
 * filter domain
 *
 * @returns value - adjusted value to match filter or null to remove filter
 */
export declare function adjustValueToFilterDomain(value: Filter['value'], { domain, type }: {
    domain: any;
    type: any;
}): any;
/**
 * Calculate numeric domain and suitable step
 */
export declare function getNumericFieldDomain(dataContainer: DataContainerInterface, valueAccessor: dataValueAccessor): RangeFieldDomain;
/**
 * Calculate step size for range and timerange filter
 */
export declare function getNumericStepSize(diff: number): number;
/**
 * Calculate timestamp domain and suitable step
 */
export declare function getTimestampFieldDomain(dataContainer: DataContainerInterface, valueAccessor: dataValueAccessor): TimeRangeFieldDomain;
/**
 * round number based on step
 *
 * @param {Number} val
 * @param {Number} step
 * @param {string} bound
 * @returns {Number} rounded number
 */
export declare function formatNumberByStep(val: number, step: number, bound: 'floor' | 'ceil'): number;
export declare function isInRange(val: any, domain: number[]): boolean;
/**
 * Determines whether a point is within the provided polygon
 *
 * @param point as input search [lat, lng]
 * @param polygon Points must be within these (Multi)Polygon(s)
 * @return {boolean}
 */
export declare function isInPolygon(point: number[], polygon: any): boolean;
export declare function getTimeWidgetTitleFormatter(domain: [number, number]): string | null;
/**
 * Sanity check on filters to prepare for save
 * @type {typeof import('./filter-utils').isFilterValidToSave}
 */
export declare function isFilterValidToSave(filter: any): boolean;
/**
 * Sanity check on filters to prepare for save
 * @type {typeof import('./filter-utils').isValidFilterValue}
 */
export declare function isValidFilterValue(type: string | null, value: any): boolean;
export declare function getColumnFilterProps<K extends KeplerTableModel<K, L>, L>(filter: Filter, dataset: K): {
    lineChart: LineChart;
    yAxs: Field;
} | Record<string, any>;
export declare function updateFilterPlot<K extends KeplerTableModel<K, any>>(datasets: {
    [id: string]: K;
}, filter: Filter, dataId?: string | undefined): Filter;
/**
 *
 * @param datasetIds list of dataset ids to be filtered
 * @param datasets all datasets
 * @param filters all filters to be applied to datasets
 * @return datasets - new updated datasets
 */
export declare function applyFiltersToDatasets<K extends KeplerTableModel<K, L>, L extends {
    config: {
        dataId: string | null;
    };
}>(datasetIds: string[], datasets: {
    [id: string]: K;
}, filters: Filter[], layers?: L[]): {
    [id: string]: K;
};
/**
 * Applies a new field name value to filter and update both filter and dataset
 * @param filter - to be applied the new field name on
 * @param datasets - All datasets
 * @param datasetId - Id of the dataset the field belongs to
 * @param fieldName - field.name
 * @param filterDatasetIndex - field.name
 * @param option
 * @return - {filter, datasets}
 */
export declare function applyFilterFieldName<K extends KeplerTableModel<K, L>, L>(filter: Filter, datasets: Record<string, K>, datasetId: string, fieldName: string, filterDatasetIndex?: number, option?: {
    mergeDomain: boolean;
}): {
    filter: Filter | null;
    dataset: K;
};
/**
 * Merge the domains of a filter in case it applies to multiple datasets
 */
export declare function mergeFilterDomain(filter: Filter, datasets: Record<string, KeplerTableModel<any, any>>): (Filter & {
    step?: number;
}) | null;
/**
 * Merge one filter with other filter prop domain
 */
export declare function mergeFilterDomainStep(filter: Filter | null, filterProps?: Partial<Filter>): (Filter & {
    step?: number;
}) | null;
/**
 * Generates polygon filter
 */
export declare const featureToFilterValue: (feature: Feature, filterId: string, properties?: Record<string, any>) => FeatureValue;
export declare const getFilterIdInFeature: (f: FeatureValue) => string;
/**
 * Generates polygon filter
 */
export declare function generatePolygonFilter<L extends {
    config: {
        dataId: string | null;
        label: string;
    };
    id: string;
}>(layers: L[], feature: Feature): PolygonFilter;
/**
 * Run filter entirely on CPU
 */
interface StateType<K extends KeplerTableModel<K, L>, L> {
    layers: L[];
    filters: Filter[];
    datasets: {
        [id: string]: K;
    };
}
export declare function filterDatasetCPU<T extends StateType<K, L>, K extends KeplerTableModel<K, L>, L>(state: T, dataId: string): T;
/**
 * Validate parsed filters with datasets and add filterProps to field
 */
type MinVisStateForFilter = Pick<VisState, 'layers' | 'datasets' | 'isMergingDatasets'>;
export declare function validateFiltersUpdateDatasets<S extends MinVisStateForFilter, K extends KeplerTableModel<K, L>, L extends {
    config: {
        dataId: string | null;
        label: string;
    };
    id: string;
}>(state: S, filtersToValidate?: ParsedFilter[]): {
    validated: Filter[];
    failed: Filter[];
    updatedDatasets: S['datasets'];
};
export declare function removeFilterPlot(filter: Filter, dataId: string): Filter;
export declare function isValidTimeDomain(domain: any): boolean;
export declare function getTimeWidgetHintFormatter(domain: [number, number]): string | undefined;
export declare function isSideFilter(filter: Filter): boolean;
export declare function mergeTimeDomains(domains: ([number, number] | null)[]): [number, number];
/**
 * @param {Layer} layer
 */
export declare function isLayerAnimatable(layer: any): boolean;
/**
 * @param {Layer[]} layers
 * @returns {Layer[]}
 */
export declare function getAnimatableVisibleLayers(layers: any[]): any[];
/**
 * @param {Layer[]} layers
 * @param {string} type
 * @returns {Layer[]}
 */
export declare function getAnimatableVisibleLayersByType(layers: any[], type: string): any[];
/**
 * @param {Layer[]} layers
 * @returns {Layer[]}
 */
export declare function getIntervalBasedAnimationLayers(layers: any[]): any[];
export declare function mergeFilterWithTimeline(filter: TimeRangeFilter, animationConfig: AnimationConfig): {
    filter: TimeRangeFilter;
    animationConfig: AnimationConfig;
};
export declare function scaleSourceDomainToDestination(sourceDomain: [number, number], destinationDomain: [number, number]): [number, number];
export declare function getFilterScaledTimeline(filter: any, animationConfig: any): [number, number] | [];
export {};
