"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SystemBadgeStylePredicateIds = exports.SystemFlashingCellPredicateIds = exports.SystemFormatColumnPredicateIds = exports.SystemAlertPredicateIds = exports.SystemFilterPredicateIds = exports.SystemPredicateDefs = void 0;
const tslib_1 = require("tslib");
const date_fns_1 = require("date-fns");
const date_fns_2 = require("date-fns");
const date_fns_3 = require("date-fns");
const date_fns_4 = require("date-fns");
const date_fns_5 = require("date-fns");
const date_fns_6 = require("date-fns");
const date_fns_7 = require("date-fns");
const date_fns_8 = require("date-fns");
const date_fns_9 = require("date-fns");
const date_fns_10 = require("date-fns");
const date_fns_11 = require("date-fns");
const date_fns_12 = require("date-fns");
const date_fns_13 = require("date-fns");
const StringExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Extensions/StringExtensions"));
const DateHelper_1 = require("../../Utilities/Helpers/DateHelper");
const Helper_1 = tslib_1.__importDefault(require("../../Utilities/Helpers/Helper"));
/**
 * Array of Predicate Defs which are shipped by AdapTable
 */
exports.SystemPredicateDefs = [
    {
        id: 'In',
        label: 'In',
        icon: { text: 'IN' },
        columnScope: { DataTypes: ['text', 'number', 'date'] },
        moduleScope: ['columnFilter', 'flashingcell', 'formatColumn', 'alert', 'badgeStyle'],
        handler: (context) => {
            const { inputs = [], column, value, adaptableApi } = context;
            const predicateInputs = (context.inputs || []).reduce((acc, input) => {
                const predicate = adaptableApi.predicateApi.getPredicateDefById(input);
                if (predicate) {
                    acc.push(predicate);
                }
                return acc;
            }, []);
            if (predicateInputs.length) {
                const nestedContext = { ...context };
                delete nestedContext.inputs;
                const predicateResult = predicateInputs.some((predicate) => {
                    return adaptableApi.predicateApi.handlePredicate({
                        PredicateId: predicate.id,
                    }, nestedContext, false);
                });
                if (predicateResult) {
                    // We want to use the only true values, to allow for multiple predicates to be used
                    return predicateResult;
                }
            }
            if (inputs.length === 0) {
                return true;
            }
            if (column.dataType === 'date') {
                return inputs.some((input) => {
                    if (adaptableApi.optionsApi.getPredicateOptions().evaluateValuesPredicateUsingTime) {
                        return (0, date_fns_3.isEqual)(input, value);
                    }
                    else {
                        return (0, date_fns_6.isSameDay)((0, DateHelper_1.parseDateValue)(input), (0, DateHelper_1.parseDateValue)(value));
                    }
                });
            }
            if (column.dataType === 'number') {
                return inputs.includes(value);
            }
            if (column.dataType === 'text') {
                return adaptableApi.predicateApi.useCaseSensitivity()
                    ? inputs
                        .map((i) => {
                        return i?.toLocaleLowerCase();
                    })
                        .includes(value?.toLocaleLowerCase())
                    : inputs.includes(value);
            }
            return true;
        },
        toString: ({ inputs }) => `IN (${inputs.join(', ')})`,
        shortcuts: ['#', '['],
    },
    {
        id: 'NotIn',
        label: 'Not In',
        icon: { text: '!IN' },
        columnScope: { DataTypes: ['text', 'number', 'date'] },
        moduleScope: ['columnFilter', 'flashingcell', 'formatColumn', 'alert', 'badgeStyle'],
        handler: (context) => {
            const { inputs, column, value, adaptableApi } = context;
            const predicateInputs = context.inputs.reduce((acc, input) => {
                const predicate = adaptableApi.predicateApi.getPredicateDefById(input);
                if (predicate) {
                    acc.push(predicate);
                }
                return acc;
            }, []);
            if (predicateInputs.length) {
                const nestedContext = { ...context };
                delete nestedContext.inputs;
                const predicateResult = predicateInputs.every((predicate) => {
                    const res = adaptableApi.predicateApi.handlePredicate({
                        PredicateId: predicate.id,
                    }, nestedContext, false);
                    return res === false;
                });
                if (!predicateResult) {
                    // We want to use the only true values, to allow for multiple predicates to be used
                    return false;
                }
            }
            // basically negation of IN
            if (inputs.length === 0) {
                return true;
            }
            if (column.dataType === 'date') {
                if (adaptableApi.optionsApi.getPredicateOptions().evaluateValuesPredicateUsingTime) {
                    return inputs.every((input) => {
                        return !(0, date_fns_3.isEqual)(input, value);
                    });
                }
                else {
                    return inputs.every((input) => {
                        return !(0, date_fns_6.isSameDay)((0, DateHelper_1.parseDateValue)(input), (0, DateHelper_1.parseDateValue)(value));
                    });
                }
            }
            if (column.dataType === 'number') {
                return !inputs.includes(value);
            }
            if (column.dataType === 'text') {
                return adaptableApi.predicateApi.useCaseSensitivity()
                    ? !inputs
                        .map((i) => {
                        return i?.toLocaleLowerCase();
                    })
                        .includes(value?.toLocaleLowerCase())
                    : !inputs.includes(value);
            }
            return true;
        },
        toString: ({ inputs }) => `Exclude (${inputs.join(', ')})`,
    },
    {
        id: 'Blanks',
        label: 'Blanks',
        icon: { name: 'unfilled-circle' },
        columnScope: { All: true },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        handler: ({ value }) => Helper_1.default.isInputNullOrEmpty(value),
    },
    {
        id: 'NonBlanks',
        label: 'Non Blanks',
        icon: { name: 'filled-circle' },
        columnScope: { All: true },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        handler: ({ value }) => Helper_1.default.isInputNotNullOrEmpty(value),
    },
    // Numeric System Filters
    {
        id: 'GreaterThan',
        label: 'Greater Than',
        icon: { name: 'greater-than' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'number' }],
        handler: ({ value, inputs }) => Number(value) > Number(inputs[0]),
        toString: ({ inputs }) => `> ${inputs[0] ?? ''}`,
        shortcuts: ['>'],
    },
    {
        id: 'LessThan',
        label: 'Less Than',
        icon: { name: 'less-than' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'number' }],
        handler: ({ value, inputs }) => Number(value) < Number(inputs[0]),
        toString: ({ inputs }) => `< ${inputs[0] ?? ''}`,
        shortcuts: ['<'],
    },
    {
        id: 'Positive',
        label: 'Positive',
        icon: { text: '>0' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        handler: ({ value }) => Number(value) > 0,
    },
    {
        id: 'Negative',
        label: 'Negative',
        icon: { text: '<0' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        handler: ({ value }) => Number(value) < 0,
    },
    {
        id: 'Zero',
        label: 'Zero',
        icon: { text: '=0' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        handler: ({ value }) => {
            if (typeof value === 'string' && !StringExtensions_1.default.IsNumeric(value)) {
                return false;
            }
            if (Helper_1.default.objectNotExists(value)) {
                return false;
            }
            return Number(value) === 0;
        },
    },
    {
        id: 'Equals',
        label: 'Equals',
        icon: { name: 'equals' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'number' }],
        handler: ({ value, inputs }) => {
            const input = inputs[0];
            if ((typeof value === 'string' && !StringExtensions_1.default.IsNumeric(value)) ||
                (typeof input === 'string' && !StringExtensions_1.default.IsNumeric(input))) {
                return false;
            }
            return Number(value) === Number(inputs[0]);
        },
        toString: ({ inputs }) => `= ${inputs[0] ?? ''}`,
        shortcuts: ['='],
    },
    {
        id: 'NotEquals',
        label: 'Not Equals',
        icon: { name: 'not-equal' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'number' }],
        handler: ({ value, inputs }) => {
            const input = inputs[0];
            if ((typeof value === 'string' && !StringExtensions_1.default.IsNumeric(value)) ||
                (typeof input === 'string' && !StringExtensions_1.default.IsNumeric(input))) {
                return false;
            }
            return Number(value) !== Number(inputs[0]);
        },
        toString: ({ inputs }) => `!= ${inputs[0] ?? ''}`,
        shortcuts: ['!='],
    },
    {
        id: 'Between',
        label: 'Between',
        icon: { text: 'BE' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'number' }, { type: 'number' }],
        handler: ({ value, inputs }) => Number(value) >= Number(inputs[0]) && Number(value) <= Number(inputs[1]),
        toString: ({ inputs }) => `Between ${inputs[0] ?? ''}:${inputs[1]}`,
        shortcuts: [':'],
    },
    {
        id: 'NotBetween',
        label: 'Not Between',
        icon: { text: '!BE' },
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'number' }, { type: 'number' }],
        handler: ({ value, inputs }) => Number(value) < Number(inputs[0]) || Number(value) > Number(inputs[1]),
        toString: ({ inputs }) => `Not Between ${inputs[0] ?? ''}:${inputs[1]}`,
        shortcuts: ['!:'],
    },
    // String System Filters
    {
        id: 'Is',
        label: 'Equals',
        icon: { name: 'equals' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs, adaptableApi }) => {
            if (!value) {
                return false;
            }
            const ignoreCase = !adaptableApi.predicateApi.useCaseSensitivity();
            const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
            const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
            return v == i;
        },
        toString: ({ inputs }) => `= ${inputs[0] ?? ''}`,
        shortcuts: ['='],
    },
    {
        id: 'IsNot',
        label: 'Not Equals',
        icon: { name: 'not-equal' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs, adaptableApi }) => {
            if (!value) {
                return true;
            }
            const ignoreCase = !adaptableApi.predicateApi.useCaseSensitivity();
            const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
            const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
            return v != i;
        },
        toString: ({ inputs }) => `!= ${inputs[0] ?? ''}`,
        shortcuts: ['!='],
    },
    {
        id: 'Contains',
        label: 'Contains',
        icon: { name: 'contains' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs, adaptableApi }) => {
            if (!value) {
                return false;
            }
            const ignoreCase = !adaptableApi.predicateApi.useCaseSensitivity();
            const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
            const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
            return v.indexOf(i) !== -1;
        },
        toString: ({ inputs }) => `Contains ${inputs[0] ?? ''}`,
    },
    {
        id: 'NotContains',
        label: 'Not Contains',
        icon: { name: 'not-contains' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs, adaptableApi }) => {
            if (!value) {
                return true;
            }
            const ignoreCase = !adaptableApi.predicateApi.useCaseSensitivity();
            const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
            const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
            return v.indexOf(i) === -1;
        },
        toString: ({ inputs }) => `Not Contains ${inputs[0] ?? ''}`,
    },
    {
        id: 'StartsWith',
        label: 'Starts With',
        icon: { name: 'starts-with' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs, adaptableApi }) => {
            if (!value) {
                return false;
            }
            const ignoreCase = !adaptableApi.predicateApi.useCaseSensitivity();
            const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
            const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
            return v.startsWith(i);
        },
        toString: ({ inputs }) => `Starts With ${inputs[0] ?? ''}`,
    },
    {
        id: 'EndsWith',
        label: 'Ends With',
        icon: { name: 'ends-with' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs, adaptableApi }) => {
            if (!value) {
                return false;
            }
            const ignoreCase = !adaptableApi.predicateApi.useCaseSensitivity();
            const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
            const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
            return v.endsWith(i);
        },
        toString: ({ inputs }) => `Ends With ${inputs[0] ?? ''}`,
    },
    {
        id: 'Regex',
        label: 'Regex',
        icon: { name: 'regex' },
        columnScope: { DataTypes: ['text'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
        inputs: [{ type: 'text' }],
        handler: ({ value, inputs }) => new RegExp(inputs[0]).test(value),
        toString: ({ inputs }) => `Regex ${inputs[0] ?? ''}`,
    },
    // Date System Filters
    {
        id: 'Today',
        label: 'Today',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_11.isToday)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'Yesterday',
        label: 'Yesterday',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_13.isYesterday)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'Tomorrow',
        label: 'Tomorrow',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_12.isTomorrow)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'ThisWeek',
        label: 'This Week',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_9.isThisWeek)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'ThisMonth',
        label: 'This Month',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_7.isThisMonth)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'ThisQuarter',
        label: 'This Quarter',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_8.isThisQuarter)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'ThisYear',
        label: 'This Year',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_10.isThisYear)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'InPast',
        label: 'In Past',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_5.isPast)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'InFuture',
        label: 'In Future',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => (0, date_fns_4.isFuture)((0, DateHelper_1.parseDateValue)(value)),
    },
    {
        id: 'After',
        label: 'After',
        icon: { name: 'greater-than' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        inputs: [{ type: 'date' }],
        handler: ({ value, inputs }) => (0, date_fns_1.isAfter)((0, DateHelper_1.parseDateValue)(value), (0, DateHelper_1.parseDateValue)(inputs[0])),
        toString: ({ inputs }) => `> ${inputs[0] ?? ''}`,
    },
    {
        id: 'Before',
        label: 'Before',
        icon: { name: 'less-than' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        inputs: [{ type: 'date' }],
        handler: ({ value, inputs }) => (0, date_fns_2.isBefore)((0, DateHelper_1.parseDateValue)(value), (0, DateHelper_1.parseDateValue)(inputs[0])),
        toString: ({ inputs }) => `< ${inputs[0] ?? ''}`,
    },
    {
        id: 'On',
        label: 'Equals',
        icon: { name: 'equals' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        inputs: [{ type: 'date' }],
        handler: ({ value, inputs }) => (0, date_fns_6.isSameDay)((0, DateHelper_1.parseDateValue)(value), (0, DateHelper_1.parseDateValue)(inputs[0])),
        toString: ({ inputs }) => `= ${inputs[0] ?? ''}`,
    },
    {
        id: 'NotOn',
        label: 'NotEquals',
        icon: { name: 'not-equal' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        inputs: [{ type: 'date' }],
        handler: ({ value, inputs }) => !(0, date_fns_6.isSameDay)((0, DateHelper_1.parseDateValue)(value), (0, DateHelper_1.parseDateValue)(inputs[0])),
        toString: ({ inputs }) => `!= ${inputs[0] ?? ''}`,
    },
    {
        id: 'NextWorkDay',
        label: 'Next Work Day',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value, adaptableApi }) => (0, date_fns_6.isSameDay)((0, DateHelper_1.parseDateValue)(value), adaptableApi.calendarApi.getNextWorkingDay()),
    },
    {
        id: 'LastWorkDay',
        label: 'Last Work Day',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value, adaptableApi }) => (0, date_fns_6.isSameDay)((0, DateHelper_1.parseDateValue)(value), adaptableApi.calendarApi.getPreviousWorkingDay()),
    },
    {
        id: 'WorkDay',
        label: 'Working Day',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value, adaptableApi }) => adaptableApi.calendarApi.isWorkingDay(value),
    },
    {
        id: 'Holiday',
        label: 'Holiday',
        icon: { name: 'calendar' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value, adaptableApi }) => adaptableApi.calendarApi.isHoliday(value),
    },
    {
        id: 'InRange',
        label: 'Range',
        icon: { name: 'date-range' },
        columnScope: { DataTypes: ['date'] },
        moduleScope: ['columnFilter'],
        inputs: [{ type: 'date' }, { type: 'date' }],
        handler: ({ value, inputs }) => new Date(value) >= new Date(inputs[0]) && new Date(value) <= new Date(inputs[1]),
    },
    // Boolean System Filters
    {
        id: 'True',
        label: 'True',
        icon: { text: 'T' },
        columnScope: { DataTypes: ['boolean'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => Boolean(value) === true,
    },
    {
        id: 'False',
        label: 'False',
        icon: { text: 'F' },
        columnScope: { DataTypes: ['boolean'] },
        moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn'],
        handler: ({ value }) => Boolean(value) === false,
    },
    {
        id: 'BooleanToggle',
        label: 'BooleanToggle',
        icon: { name: 'boolean-list' },
        columnScope: { DataTypes: ['boolean'] },
        moduleScope: ['columnFilter'],
        inputs: [{ type: 'boolean' }],
        // working with string aliases instead of booleans because the ColumnFilterAPI cannot handle falsy filter values (it ignores them)
        handler: ({ value, inputs }) => {
            if (inputs[0] == 'all') {
                // if it's indeterminate, all values (true&false) are matched
                return true;
            }
            const booleanInputValue = inputs[0] === 'checked' ? true : false;
            return Boolean(value) === Boolean(booleanInputValue);
        },
    },
    // Other System Filters
    {
        id: 'AnyChange',
        label: 'Any Change',
        columnScope: { All: true },
        moduleScope: ['alert', 'flashingcell'],
        handler: ({ value, oldValue }) => value !== oldValue,
    },
    {
        id: 'PercentChange',
        label: 'Percent Change',
        columnScope: { DataTypes: ['number'] },
        moduleScope: ['alert', 'flashingcell'],
        inputs: [{ type: 'number' }],
        handler: ({ value, oldValue, inputs }) => {
            const change = Math.abs(Number(value) - Number(oldValue));
            const base = Math.min(Number(value), Number(oldValue));
            const threshold = Number(inputs[0]);
            return (change / base) * 100 > threshold;
        },
    },
];
exports.SystemFilterPredicateIds = exports.SystemPredicateDefs.filter((p) => p.moduleScope.includes('columnFilter')).map((p) => p.id);
exports.SystemAlertPredicateIds = exports.SystemPredicateDefs.filter((p) => p.moduleScope.includes('alert')).map((p) => p.id);
exports.SystemFormatColumnPredicateIds = exports.SystemPredicateDefs.filter((p) => p.moduleScope.includes('formatColumn')).map((p) => p.id);
exports.SystemFlashingCellPredicateIds = exports.SystemPredicateDefs.filter((p) => p.moduleScope.includes('flashingcell')).map((p) => p.id);
exports.SystemBadgeStylePredicateIds = exports.SystemPredicateDefs.filter((p) => p.moduleScope.includes('badgeStyle')).map((p) => p.id);
