{"version":3,"file":"react-querybuilder_core.production.mjs","names":["numericQuantityRegex","shouldNegate","escapeDoubleQuotes","processNumber","shouldNegate","escapeSingleQuotes","escapeStringValueQuotes","escapeSingleQuotes","negateIfNotOp","immerSetAutoFreeze","dummyFD"],"sources":["../src/controlPropKeys.ts","../src/defaults.ts","../src/utils/abortReasons.ts","../src/utils/arrayUtils.ts","../../../node_modules/clsx/dist/clsx.mjs","../src/utils/misc.ts","../src/utils/isRuleGroup.ts","../src/utils/signature.ts","../src/utils/coalesce.ts","../src/utils/convertQuery.ts","../src/utils/deriveClassNames.ts","../src/utils/defaultValidator.ts","../src/utils/objectUtils.ts","../src/utils/optGroupUtils.ts","../src/utils/filterFieldsByComparator.ts","../src/utils/deriveRuleContext.ts","../src/utils/parseNumber.ts","../src/utils/deriveValueEditor.ts","../src/utils/transformQuery.ts","../src/utils/isRuleOrGroupValid.ts","../src/utils/getParseNumberMethod.ts","../src/utils/formatQuery/utils.ts","../src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts","../src/utils/formatQuery/defaultRuleProcessorCEL.ts","../src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts","../src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts","../src/utils/formatQuery/defaultRuleProcessorMongoDB.ts","../src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts","../src/utils/formatQuery/defaultRuleProcessorSpEL.ts","../src/utils/formatQuery/defaultValueProcessorByRule.ts","../src/utils/formatQuery/defaultRuleGroupProcessorCypher.ts","../src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts","../src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts","../src/utils/formatQuery/defaultRuleGroupProcessorGremlin.ts","../src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts","../src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts","../src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts","../src/utils/formatQuery/defaultRuleGroupProcessorMongoDB.ts","../src/utils/formatQuery/defaultRuleGroupProcessorNL.ts","../src/utils/formatQuery/defaultRuleGroupProcessorParameterized.ts","../src/utils/formatQuery/defaultRuleGroupProcessorPrisma.ts","../src/utils/formatQuery/defaultRuleGroupProcessorSequelize.ts","../src/utils/formatQuery/defaultRuleGroupProcessorSPARQL.ts","../src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts","../src/utils/formatQuery/defaultRuleGroupProcessorTanStackDB.ts","../src/utils/formatQuery/defaultRuleGroupProcessorDiagnostics.ts","../src/utils/formatQuery/defaultRuleProcessorCypher.ts","../src/utils/formatQuery/defaultRuleProcessorDrizzle.ts","../src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts","../src/utils/formatQuery/defaultRuleProcessorGremlin.ts","../src/utils/formatQuery/defaultRuleProcessorJSONata.ts","../src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts","../src/utils/formatQuery/defaultRuleProcessorLDAP.ts","../src/utils/formatQuery/defaultValueProcessorNL.ts","../src/utils/formatQuery/defaultRuleProcessorNL.ts","../src/utils/formatQuery/defaultRuleProcessorSQL.ts","../src/utils/formatQuery/defaultRuleProcessorParameterized.ts","../src/utils/formatQuery/defaultRuleProcessorPrisma.ts","../src/utils/formatQuery/defaultRuleProcessorSequelize.ts","../src/utils/formatQuery/defaultRuleProcessorSPARQL.ts","../src/utils/formatQuery/defaultRuleProcessorTanStackDB.ts","../src/utils/formatQuery/formatQuery.ts","../src/utils/formatQuery/index.ts","../src/utils/pathUtils.ts","../src/utils/generateAccessibleDescription.ts","../src/utils/generateID.ts","../src/utils/immerInstances.ts","../src/utils/getMatchModesUtil.ts","../src/utils/getRuleDefaultValue.ts","../src/utils/getValidationClassNames.ts","../src/utils/getValueSourcesUtil.ts","../src/utils/mergeAnyTranslations.ts","../src/utils/mergeClassnames.ts","../src/utils/optionResolvers.ts","../src/utils/optionsEqual.ts","../src/utils/preferProp.ts","../src/utils/prepareQueryObjects.ts","../src/utils/regenerateIDs.ts","../src/utils/queryTools.ts","../src/utils/queryActions.ts","../src/utils/ruleFactory.ts","../src/utils/QueryManager.ts"],"sourcesContent":["/**\n * Runtime data describing the set of query builder controls and the props each one receives.\n *\n * These live in `@react-querybuilder/core` (not `react-querybuilder`) so that non-React ports\n * can consume them without a React dependency.\n *\n * Nothing here can drift from the React implementation unnoticed:\n * `react-querybuilder`'s `types/controlPropKeys.test.ts` gates {@link controlKeys} against\n * `defaultControlElements` and `ControlElementsProp`, and every entry of\n * {@link controlPropKeys} against the corresponding props interface—both at runtime and at\n * compile time, in both directions.\n */\n\n/**\n * The name of every query builder control, alphabetized.\n *\n * @group Props\n */\nexport const controlKeys = [\n  'actionElement',\n  'addGroupAction',\n  'addRuleAction',\n  'cloneGroupAction',\n  'cloneRuleAction',\n  'combinatorSelector',\n  'dragHandle',\n  'fieldSelector',\n  'inlineCombinator',\n  'lockGroupAction',\n  'lockRuleAction',\n  'matchModeEditor',\n  'muteGroupAction',\n  'muteRuleAction',\n  'notToggle',\n  'operatorSelector',\n  'removeGroupAction',\n  'removeRuleAction',\n  'rule',\n  'ruleGroup',\n  'ruleGroupBodyElements',\n  'ruleGroupHeaderElements',\n  'shiftActions',\n  'undoRedoActions',\n  'valueEditor',\n  'valueSelector',\n  'valueSourceSelector',\n] as const;\n\n/**\n * The name of a query builder control.\n *\n * @group Props\n */\nexport type ControlKey = (typeof controlKeys)[number];\n\n/**\n * The full set of prop names each default control receives. Ports can use this to declare\n * every prop explicitly instead of relying on fall-through/attribute inheritance.\n *\n * Each array is the complete, alphabetized key set of the control's props interface in\n * `react-querybuilder`. The lists are written out in full rather than composed from shared\n * bases because `--isolatedDeclarations` cannot infer array types built with spreads. A\n * compile-time gate in `react-querybuilder` (`types/controlPropKeys.test.ts`) fails the build\n * if any list drifts from its interface in either direction.\n *\n * @group Props\n */\nexport const controlPropKeys = {\n  actionElement: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  addGroupAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  addRuleAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  cloneGroupAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  cloneRuleAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  combinatorSelector: [\n    'className',\n    'context',\n    'disabled',\n    'handleOnChange',\n    'level',\n    'options',\n    'path',\n    'ruleGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n    'value',\n  ],\n  dragHandle: [\n    'className',\n    'context',\n    'disabled',\n    'dragHandleAttributes',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  fieldSelector: [\n    'className',\n    'context',\n    'disabled',\n    'handleOnChange',\n    'level',\n    'operator',\n    'options',\n    'path',\n    'rule',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n    'value',\n  ],\n  inlineCombinator: [\n    'className',\n    'component',\n    'context',\n    'disabled',\n    'handleOnChange',\n    'level',\n    'options',\n    'path',\n    'ruleGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n    'value',\n  ],\n  lockGroupAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  lockRuleAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  matchModeEditor: [\n    'className',\n    'classNames',\n    'context',\n    'disabled',\n    'field',\n    'fieldData',\n    'handleOnChange',\n    'level',\n    'match',\n    'numericEditorComponent',\n    'options',\n    'path',\n    'rule',\n    'schema',\n    'selectorComponent',\n    'testID',\n    'thresholdPlaceholder',\n    'title',\n    'validation',\n    'value',\n  ],\n  muteGroupAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  muteRuleAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  notToggle: [\n    'checked',\n    'className',\n    'context',\n    'disabled',\n    'handleOnChange',\n    'label',\n    'level',\n    'path',\n    'ruleGroup',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  operatorSelector: [\n    'className',\n    'context',\n    'disabled',\n    'field',\n    'fieldData',\n    'handleOnChange',\n    'level',\n    'options',\n    'path',\n    'rule',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n    'value',\n  ],\n  removeGroupAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  removeRuleAction: [\n    'className',\n    'context',\n    'disabled',\n    'disabledTranslation',\n    'handleOnClick',\n    'label',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'rules',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n  ],\n  rule: [\n    'actions',\n    'context',\n    'disabled',\n    'dndRef',\n    'dragHandleAttributes',\n    'dragMonitorId',\n    'dragRef',\n    'dropEffect',\n    'dropMonitorId',\n    'dropNotAllowed',\n    'field',\n    'groupItems',\n    'id',\n    'isDragging',\n    'isOver',\n    'operator',\n    'parentDisabled',\n    'parentMuted',\n    'path',\n    'rule',\n    'schema',\n    'shiftDownDisabled',\n    'shiftUpDisabled',\n    'translations',\n    'value',\n    'valueSource',\n  ],\n  ruleGroup: [\n    'actions',\n    'combinator',\n    'context',\n    'disabled',\n    'dragHandleAttributes',\n    'dragMonitorId',\n    'dragRef',\n    'dropEffect',\n    'dropMonitorId',\n    'dropNotAllowed',\n    'dropRef',\n    'groupItems',\n    'id',\n    'isDragging',\n    'isOver',\n    'not',\n    'parentDisabled',\n    'parentMuted',\n    'path',\n    'previewRef',\n    'ruleGroup',\n    'rules',\n    'schema',\n    'shiftDownDisabled',\n    'shiftUpDisabled',\n    'translations',\n  ],\n  ruleGroupBodyElements: [\n    'accessibleDescription',\n    'actions',\n    'addGroup',\n    'addRule',\n    'classNames',\n    'cloneGroup',\n    'combinator',\n    'context',\n    'disabled',\n    'dragHandleAttributes',\n    'dragMonitorId',\n    'dragRef',\n    'dropEffect',\n    'dropMonitorId',\n    'dropNotAllowed',\n    'dropRef',\n    'groupItems',\n    'id',\n    'isDragging',\n    'isOver',\n    'muted',\n    'not',\n    'onCombinatorChange',\n    'onGroupAdd',\n    'onIndependentCombinatorChange',\n    'onNotToggleChange',\n    'outerClassName',\n    'parentDisabled',\n    'parentMuted',\n    'path',\n    'pathsMemo',\n    'previewRef',\n    'removeGroup',\n    'ruleGroup',\n    'rules',\n    'schema',\n    'shiftDownDisabled',\n    'shiftGroupDown',\n    'shiftGroupUp',\n    'shiftUpDisabled',\n    'toggleLockGroup',\n    'toggleMuteGroup',\n    'translations',\n    'validationClassName',\n    'validationResult',\n  ],\n  ruleGroupHeaderElements: [\n    'accessibleDescription',\n    'actions',\n    'addGroup',\n    'addRule',\n    'classNames',\n    'cloneGroup',\n    'combinator',\n    'context',\n    'disabled',\n    'dragHandleAttributes',\n    'dragMonitorId',\n    'dragRef',\n    'dropEffect',\n    'dropMonitorId',\n    'dropNotAllowed',\n    'dropRef',\n    'groupItems',\n    'id',\n    'isDragging',\n    'isOver',\n    'muted',\n    'not',\n    'onCombinatorChange',\n    'onGroupAdd',\n    'onIndependentCombinatorChange',\n    'onNotToggleChange',\n    'outerClassName',\n    'parentDisabled',\n    'parentMuted',\n    'path',\n    'pathsMemo',\n    'previewRef',\n    'removeGroup',\n    'ruleGroup',\n    'rules',\n    'schema',\n    'shiftDownDisabled',\n    'shiftGroupDown',\n    'shiftGroupUp',\n    'shiftUpDisabled',\n    'toggleLockGroup',\n    'toggleMuteGroup',\n    'translations',\n    'validationClassName',\n    'validationResult',\n  ],\n  shiftActions: [\n    'className',\n    'context',\n    'disabled',\n    'labels',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'schema',\n    'shiftDown',\n    'shiftDownDisabled',\n    'shiftUp',\n    'shiftUpDisabled',\n    'testID',\n    'title',\n    'titles',\n    'validation',\n  ],\n  undoRedoActions: [\n    'className',\n    'classNames',\n    'context',\n    'disabled',\n    'labels',\n    'level',\n    'path',\n    'ruleOrGroup',\n    'schema',\n    'testID',\n    'title',\n    'titles',\n    'validation',\n  ],\n  valueEditor: [\n    'className',\n    'context',\n    'disabled',\n    'field',\n    'fieldData',\n    'handleOnChange',\n    'inputType',\n    'level',\n    'listsAsArrays',\n    'operator',\n    'parseNumbers',\n    'path',\n    'rule',\n    'schema',\n    'selectorComponent',\n    'separator',\n    'skipHook',\n    'testID',\n    'title',\n    'type',\n    'validation',\n    'value',\n    'valueSource',\n    'values',\n  ],\n  valueSelector: [\n    'className',\n    'context',\n    'disabled',\n    'handleOnChange',\n    'level',\n    'listsAsArrays',\n    'multiple',\n    'options',\n    'path',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n    'value',\n  ],\n  valueSourceSelector: [\n    'className',\n    'context',\n    'disabled',\n    'field',\n    'fieldData',\n    'handleOnChange',\n    'level',\n    'options',\n    'path',\n    'rule',\n    'schema',\n    'testID',\n    'title',\n    'validation',\n    'value',\n  ],\n} as const;\n\n/**\n * Which bulk override, if any, applies to each control: `\"action\"` for controls that a supplied\n * `actionElement` replaces, `\"selector\"` for controls that a supplied `valueSelector` replaces,\n * and `null` for controls that neither replaces.\n *\n * `actionElement` and `valueSelector` are themselves `null`—they are the _source_ of a bulk\n * override, not a target of one.\n *\n * Replaces name-suffix sniffing (`key.endsWith('Action')`), which would silently misclassify a\n * future control named e.g. `pathSelector`, and which disagrees between implementations about\n * whether `shiftActions`/`undoRedoActions` (plural) match. They do not: neither receives the\n * `actionElement` bulk override.\n *\n * @group Props\n */\nexport const controlKind = {\n  actionElement: null,\n  addGroupAction: 'action',\n  addRuleAction: 'action',\n  cloneGroupAction: 'action',\n  cloneRuleAction: 'action',\n  combinatorSelector: 'selector',\n  dragHandle: null,\n  fieldSelector: 'selector',\n  inlineCombinator: null,\n  lockGroupAction: 'action',\n  lockRuleAction: 'action',\n  matchModeEditor: null,\n  muteGroupAction: 'action',\n  muteRuleAction: 'action',\n  notToggle: null,\n  operatorSelector: 'selector',\n  removeGroupAction: 'action',\n  removeRuleAction: 'action',\n  rule: null,\n  ruleGroup: null,\n  ruleGroupBodyElements: null,\n  ruleGroupHeaderElements: null,\n  shiftActions: null,\n  undoRedoActions: null,\n  valueEditor: null,\n  valueSelector: null,\n  valueSourceSelector: 'selector',\n} as const;\n","import type {\n  BaseTranslationsFull,\n  Classnames,\n  DefaultCombinatorName,\n  DefaultCombinatorNameExtended,\n  DefaultOperatorName,\n  MatchMode,\n  Path,\n  QueryBuilderFlags,\n  StringUnionToFullOptionArray,\n} from './types';\n\n// DO NOT ALTER OR REMOVE REGION NAMES. Some of them are used\n// to generate code snippets in the documentation.\n\n/**\n * @group Defaults\n */\nexport const defaultPlaceholderName = '~';\n/**\n * @group Defaults\n */\nexport const defaultPlaceholderLabel = '------';\n/**\n * Default `name` for placeholder option in the `fields` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderFieldName: typeof defaultPlaceholderName = defaultPlaceholderName;\n/**\n * Default `label` for placeholder option in the `fields` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderFieldLabel: typeof defaultPlaceholderLabel = defaultPlaceholderLabel;\n/**\n * Default `label` for placeholder option group in the `fields` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderFieldGroupLabel: typeof defaultPlaceholderLabel =\n  defaultPlaceholderLabel;\n/**\n * Default `name` for placeholder option in the `operators` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderOperatorName: typeof defaultPlaceholderName = defaultPlaceholderName;\n/**\n * Default `label` for placeholder option in the `operators` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderOperatorLabel: typeof defaultPlaceholderLabel =\n  defaultPlaceholderLabel;\n/**\n * Default `label` for placeholder option group in the `operators` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderOperatorGroupLabel: typeof defaultPlaceholderLabel =\n  defaultPlaceholderLabel;\n/**\n * Default `name` for placeholder option in the `values` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderValueName: typeof defaultPlaceholderName = defaultPlaceholderName;\n/**\n * Default `label` for placeholder option in the `values` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderValueLabel: typeof defaultPlaceholderLabel = defaultPlaceholderLabel;\n/**\n * Default `label` for placeholder option group in the `values` array.\n *\n * @group Defaults\n */\nexport const defaultPlaceholderValueGroupLabel: typeof defaultPlaceholderLabel =\n  defaultPlaceholderLabel;\n\n/**\n * Default configuration of translatable strings.\n *\n * @group Defaults\n */\n// #region docs-translations\nexport const defaultTranslations: BaseTranslationsFull = {\n  fields: {\n    title: 'Field',\n    placeholderName: defaultPlaceholderFieldName,\n    placeholderLabel: defaultPlaceholderFieldLabel,\n    placeholderGroupLabel: defaultPlaceholderFieldGroupLabel,\n  } as const,\n  operators: {\n    title: 'Operator',\n    placeholderName: defaultPlaceholderOperatorName,\n    placeholderLabel: defaultPlaceholderOperatorLabel,\n    placeholderGroupLabel: defaultPlaceholderOperatorGroupLabel,\n  } as const,\n  values: {\n    title: 'Values',\n    placeholderName: defaultPlaceholderValueName,\n    placeholderLabel: defaultPlaceholderValueLabel,\n    placeholderGroupLabel: defaultPlaceholderValueGroupLabel,\n  } as const,\n  matchMode: { title: 'Match mode' } as const,\n  matchThreshold: { title: 'Match threshold', placeholderName: '#' } as const,\n  value: { title: 'Value' } as const,\n  removeRule: { label: '⨯', title: 'Remove rule' } as const,\n  removeGroup: { label: '⨯', title: 'Remove group' } as const,\n  addRule: { label: '+ Rule', title: 'Add rule' } as const,\n  addGroup: { label: '+ Group', title: 'Add group' } as const,\n  combinators: { title: 'Combinator' } as const,\n  notToggle: { label: 'Not', title: 'Invert this group' } as const,\n  cloneRule: { label: '⧉', title: 'Clone rule' } as const,\n  cloneRuleGroup: { label: '⧉', title: 'Clone group' } as const,\n  shiftActionUp: { label: '˄', title: 'Shift up' } as const,\n  shiftActionDown: { label: '˅', title: 'Shift down' } as const,\n  undo: { label: '↶', title: 'Undo' } as const,\n  redo: { label: '↷', title: 'Redo' } as const,\n  dragHandle: { label: '⁞⁞', title: 'Drag handle' } as const,\n  lockRule: { label: '🔓', title: 'Lock rule' } as const,\n  lockGroup: { label: '🔓', title: 'Lock group' } as const,\n  lockRuleDisabled: { label: '🔒', title: 'Unlock rule' } as const,\n  lockGroupDisabled: { label: '🔒', title: 'Unlock group' } as const,\n  muteRule: { label: '🔊', title: 'Mute rule' } as const,\n  muteGroup: { label: '🔊', title: 'Mute group' } as const,\n  unmuteRule: { label: '🔇', title: 'Unmute rule' } as const,\n  unmuteGroup: { label: '🔇', title: 'Unmute group' } as const,\n  valueSourceSelector: { title: 'Value source' } as const,\n} satisfies BaseTranslationsFull;\n// #endregion\n\n/**\n * Default character used to `.join` and `.split` arrays.\n *\n * @group Defaults\n */\nexport const defaultJoinChar = ',';\n\nexport type DefaultOperators = StringUnionToFullOptionArray<DefaultOperatorName>;\n\nexport const defaultOperatorLabelMap: Record<DefaultOperatorName, string> = {\n  '=': '=',\n  '!=': '!=',\n  '<': '<',\n  '>': '>',\n  '<=': '<=',\n  '>=': '>=',\n  contains: 'contains',\n  beginsWith: 'begins with',\n  endsWith: 'ends with',\n  doesNotContain: 'does not contain',\n  doesNotBeginWith: 'does not begin with',\n  doesNotEndWith: 'does not end with',\n  null: 'is null',\n  notNull: 'is not null',\n  in: 'in',\n  notIn: 'not in',\n  between: 'between',\n  notBetween: 'not between',\n};\n\nexport const defaultCombinatorLabelMap: Record<DefaultCombinatorNameExtended, string> = {\n  and: 'AND',\n  or: 'OR',\n  xor: 'XOR',\n};\n\n/**\n * Default operator list.\n *\n * @group Defaults\n */\n// #region docs-operators\nexport const defaultOperators: DefaultOperators = [\n  { name: '=', value: '=', label: '=' },\n  { name: '!=', value: '!=', label: '!=' },\n  { name: '<', value: '<', label: '<' },\n  { name: '>', value: '>', label: '>' },\n  { name: '<=', value: '<=', label: '<=' },\n  { name: '>=', value: '>=', label: '>=' },\n  { name: 'contains', value: 'contains', label: 'contains' },\n  { name: 'beginsWith', value: 'beginsWith', label: 'begins with' },\n  { name: 'endsWith', value: 'endsWith', label: 'ends with' },\n  { name: 'doesNotContain', value: 'doesNotContain', label: 'does not contain' },\n  { name: 'doesNotBeginWith', value: 'doesNotBeginWith', label: 'does not begin with' },\n  { name: 'doesNotEndWith', value: 'doesNotEndWith', label: 'does not end with' },\n  { name: 'null', value: 'null', label: 'is null' },\n  { name: 'notNull', value: 'notNull', label: 'is not null' },\n  { name: 'in', value: 'in', label: 'in' },\n  { name: 'notIn', value: 'notIn', label: 'not in' },\n  { name: 'between', value: 'between', label: 'between' },\n  { name: 'notBetween', value: 'notBetween', label: 'not between' },\n];\n// #endregion\n\n/**\n * Map of default operators to their respective opposite/negating operators.\n *\n * @group Defaults\n */\nexport const defaultOperatorNegationMap: Record<DefaultOperatorName, DefaultOperatorName> = {\n  '=': '!=',\n  '!=': '=',\n  '<': '>=',\n  '<=': '>',\n  '>': '<=',\n  '>=': '<',\n  beginsWith: 'doesNotBeginWith',\n  doesNotBeginWith: 'beginsWith',\n  endsWith: 'doesNotEndWith',\n  doesNotEndWith: 'endsWith',\n  contains: 'doesNotContain',\n  doesNotContain: 'contains',\n  between: 'notBetween',\n  notBetween: 'between',\n  in: 'notIn',\n  notIn: 'in',\n  notNull: 'null',\n  null: 'notNull',\n} satisfies Record<DefaultOperatorName, DefaultOperatorName>;\n\n/**\n * Relational/comparison operators (`=`, `!=`, `<`, `>`, `<=`, `>=`).\n *\n * @group Defaults\n */\nexport const relationalOperators: Set<DefaultOperatorName> = new Set([\n  '=',\n  '!=',\n  '<',\n  '>',\n  '<=',\n  '>=',\n]);\n\n/**\n * Substring/text-matching operators (`contains`, `beginsWith`, `endsWith`, and negations).\n *\n * @group Defaults\n */\nexport const substringOperators: Set<DefaultOperatorName> = new Set([\n  'contains',\n  'beginsWith',\n  'endsWith',\n  'doesNotContain',\n  'doesNotBeginWith',\n  'doesNotEndWith',\n]);\n\n/**\n * Null-check operators (`null`, `notNull`).\n *\n * @group Defaults\n */\nexport const nullOperators: Set<DefaultOperatorName> = new Set(['null', 'notNull']);\n\n/**\n * List-membership operators (`in`, `notIn`).\n *\n * @group Defaults\n */\nexport const inOperators: Set<DefaultOperatorName> = new Set(['in', 'notIn']);\n\n/**\n * Range operators (`between`, `notBetween`).\n *\n * @group Defaults\n */\nexport const betweenOperators: Set<DefaultOperatorName> = new Set(['between', 'notBetween']);\n\nexport type DefaultCombinators = StringUnionToFullOptionArray<DefaultCombinatorName>;\n\n/**\n * Default combinator list.\n *\n * @group Defaults\n */\n// #region docs-combinators\nexport const defaultCombinators: DefaultCombinators = [\n  { name: 'and', value: 'and', label: 'AND' } as const,\n  { name: 'or', value: 'or', label: 'OR' } as const,\n];\n// #endregion\n\nexport type DefaultCombinatorsExtended =\n  StringUnionToFullOptionArray<DefaultCombinatorNameExtended>;\n\n/**\n * Default combinator list, with `XOR` added.\n *\n * @group Defaults\n */\nexport const defaultCombinatorsExtended: DefaultCombinatorsExtended = [\n  ...defaultCombinators,\n  { name: 'xor', value: 'xor', label: 'XOR' } as const,\n];\n\nexport type DefaultMatchModes = StringUnionToFullOptionArray<MatchMode>;\n\n/**\n * Default match modes.\n *\n * @group Defaults\n */\n// #region docs-matchmodes\nexport const defaultMatchModes: DefaultMatchModes = [\n  { name: 'all', value: 'all', label: 'all' },\n  { name: 'some', value: 'some', label: 'some' },\n  { name: 'none', value: 'none', label: 'none' },\n  { name: 'atLeast', value: 'atLeast', label: 'at least' },\n  { name: 'atMost', value: 'atMost', label: 'at most' },\n  { name: 'exactly', value: 'exactly', label: 'exactly' },\n];\n// #endregion\n\n/**\n * Standard classnames applied to each component.\n *\n * @group Defaults\n */\n// #region docs-standardclassnames\nexport const standardClassnames = {\n  queryBuilder: 'queryBuilder',\n  ruleGroup: 'ruleGroup',\n  header: 'ruleGroup-header',\n  body: 'ruleGroup-body',\n  combinators: 'ruleGroup-combinators',\n  addRule: 'ruleGroup-addRule',\n  addGroup: 'ruleGroup-addGroup',\n  cloneRule: 'rule-cloneRule',\n  cloneGroup: 'ruleGroup-cloneGroup',\n  removeGroup: 'ruleGroup-remove',\n  notToggle: 'ruleGroup-notToggle',\n  rule: 'rule',\n  fields: 'rule-fields',\n  matchMode: 'rule-matchMode',\n  matchThreshold: 'rule-matchThreshold',\n  operators: 'rule-operators',\n  value: 'rule-value',\n  removeRule: 'rule-remove',\n  betweenRules: 'betweenRules',\n  valid: 'queryBuilder-valid',\n  invalid: 'queryBuilder-invalid',\n  shiftActions: 'shiftActions',\n  undoRedoActions: 'undoRedoActions',\n  undoAction: 'undoRedoActions-undo',\n  redoAction: 'undoRedoActions-redo',\n  dndDragging: 'dndDragging',\n  dndOver: 'dndOver',\n  dndCopy: 'dndCopy',\n  dndGroup: 'dndGroup',\n  dndDropNotAllowed: 'dndDropNotAllowed',\n  dndPreviewPosition: 'dndPreviewPosition',\n  dndHidden: 'dndHidden',\n  dragHandle: 'queryBuilder-dragHandle',\n  disabled: 'queryBuilder-disabled',\n  muted: 'queryBuilder-muted',\n  lockRule: 'rule-lock',\n  lockGroup: 'ruleGroup-lock',\n  muteRule: 'rule-mute',\n  muteGroup: 'ruleGroup-mute',\n  valueSource: 'rule-valueSource',\n  valueListItem: 'rule-value-list-item',\n  branches: 'queryBuilder-branches',\n  justified: 'queryBuilder-justified',\n  responsive: 'queryBuilder-responsive',\n  hasSubQuery: 'rule-hasSubQuery',\n  loading: 'queryBuilder-loading',\n  valueDateTimeRelative: 'rule-value-dateTimeRelative',\n} as const;\n// #endregion\n\n/**\n * Default classnames for each component.\n *\n * @group Defaults\n */\nexport const defaultControlClassnames: Classnames = {\n  queryBuilder: '',\n  ruleGroup: '',\n  header: '',\n  body: '',\n  combinators: '',\n  addRule: '',\n  addGroup: '',\n  cloneRule: '',\n  cloneGroup: '',\n  removeGroup: '',\n  notToggle: '',\n  rule: '',\n  fields: '',\n  matchMode: '',\n  matchThreshold: '',\n  operators: '',\n  value: '',\n  removeRule: '',\n  shiftActions: '',\n  undoRedoActions: '',\n  undoAction: '',\n  redoAction: '',\n  dragHandle: '',\n  lockRule: '',\n  lockGroup: '',\n  muteRule: '',\n  muteGroup: '',\n  muted: '',\n  valueSource: '',\n  actionElement: '',\n  valueSelector: '',\n  betweenRules: '',\n  valid: '',\n  invalid: '',\n  dndDragging: '',\n  dndOver: '',\n  dndGroup: '',\n  dndCopy: '',\n  dndDropNotAllowed: '',\n  dndPreviewPosition: '',\n  dndHidden: '',\n  disabled: '',\n  valueListItem: '',\n  branches: '',\n  hasSubQuery: '',\n  loading: '',\n  valueDateTimeRelative: '',\n} satisfies Classnames;\n\n/**\n * Default reason codes for a group being invalid.\n *\n * @group Defaults\n */\nexport const groupInvalidReasons = {\n  empty: 'empty',\n  invalidCombinator: 'invalid combinator',\n  invalidIndependentCombinators: 'invalid independent combinators',\n} as const;\n\n/**\n * Component identifiers for testing.\n *\n * @group Defaults\n */\nexport const TestID = {\n  rule: 'rule',\n  ruleGroup: 'rule-group',\n  inlineCombinator: 'inline-combinator',\n  addGroup: 'add-group',\n  removeGroup: 'remove-group',\n  cloneGroup: 'clone-group',\n  cloneRule: 'clone-rule',\n  addRule: 'add-rule',\n  removeRule: 'remove-rule',\n  combinators: 'combinators',\n  fields: 'fields',\n  operators: 'operators',\n  valueEditor: 'value-editor',\n  notToggle: 'not-toggle',\n  shiftActions: 'shift-actions',\n  undoRedoActions: 'undo-redo-actions',\n  undoAction: 'undo-action',\n  redoAction: 'redo-action',\n  dragHandle: 'drag-handle',\n  lockRule: 'lock-rule',\n  lockGroup: 'lock-group',\n  muteRule: 'mute-rule',\n  muteGroup: 'mute-group',\n  valueSourceSelector: 'value-source-selector',\n  matchModeEditor: 'match-mode-editor',\n} as const;\n\nexport const LogType = {\n  parentPathDisabled: 'action aborted: parent path disabled',\n  pathDisabled: 'action aborted: path is disabled',\n  queryUpdate: 'query updated',\n  onAddRuleFalse: 'onAddRule callback returned false',\n  onAddGroupFalse: 'onAddGroup callback returned false',\n  onGroupRuleFalse: 'onGroupRule callback returned false',\n  onGroupGroupFalse: 'onGroupGroup callback returned false',\n  onMoveRuleFalse: 'onMoveRule callback returned false',\n  onMoveGroupFalse: 'onMoveGroup callback returned false',\n  onRemoveFalse: 'onRemove callback returned false',\n  add: 'rule or group added',\n  remove: 'rule or group removed',\n  update: 'rule or group updated',\n  move: 'rule or group moved',\n  group: 'rule or group grouped with another',\n} as const;\n\n/**\n * The {@link Path} of the root group.\n *\n * @group Defaults\n */\nexport const rootPath: Path = [] satisfies Path;\n\n/**\n * Default values for all `boolean`\n * {@link react-querybuilder!QueryBuilder QueryBuilder} options.\n *\n * @group Defaults\n */\nexport const queryBuilderFlagDefaults: Required<QueryBuilderFlags> = {\n  addRuleToNewGroups: false,\n  autoSelectField: true,\n  autoSelectOperator: true,\n  autoSelectValue: false,\n  debugMode: false,\n  enableDragAndDrop: false,\n  enableMountQueryChange: true,\n  listsAsArrays: false,\n  preserveQueryStateOnUnmount: false,\n  resetOnFieldChange: true,\n  resetOnOperatorChange: false,\n  showCloneButtons: false,\n  showCombinatorsBetweenRules: false,\n  showLockButtons: false,\n  showMuteButtons: false,\n  showNotToggle: false,\n  showShiftActions: false,\n  showUndoRedo: false,\n  suppressStandardClassnames: false,\n};\n\n/**\n * Default maximum number of undo steps retained by query history.\n *\n * @group Defaults\n */\nexport const defaultMaxHistory = 50;\n\n/**\n * Default time window (in milliseconds) within which consecutive changes to the same\n * property of the same rule are coalesced into a single undo step.\n *\n * @group Defaults\n */\nexport const defaultCoalesceMs = 500;\n","import type { AbortReason } from './queryTools';\n\n/**\n * Abort reasons that {@link QueryManager}'s `strict` mode treats as errors. The remaining\n * reasons—`\"same-location\"` and `\"no-change\"`—describe valid operations that had nothing to do,\n * so they are reported to `onInvalidTarget` but never throw.\n *\n * Declared apart from `QueryManager` so the `@react-querybuilder/core/derivations` entry point can\n * export it without putting the manager in its module graph.\n *\n * @group Query Tools\n */\nexport const strictAbortReasons: readonly AbortReason[] = [\n  'target-not-found',\n  'parent-not-found',\n  'parent-not-a-group',\n  'destination-not-found',\n  'root-not-allowed',\n  'not-a-combinator-slot',\n  'target-disabled',\n  'parent-disabled',\n  'max-levels-exceeded',\n];\n\n/** @internal */\nexport const strictAbortReasonSet: ReadonlySet<AbortReason> = new Set<AbortReason>(\n  strictAbortReasons\n);\n","import { defaultJoinChar } from '../defaults';\n\n/**\n * Splits a string by a given character (see {@link defaultJoinChar}). Escaped characters\n * (characters preceded by a backslash) will not apply to the split, and the backslash will\n * be removed in the array element. Inverse of {@link joinWith}.\n *\n * @example\n * splitBy('this\\\\,\\\\,that,,the other,,,\\\\,')\n * // or\n * splitBy('this\\\\,\\\\,that,,the other,,,\\\\,', ',')\n * // would return\n * ['this,,that', '', 'the other', '', '', ',']\n */\nexport const splitBy = (str?: string, splitChar: string = defaultJoinChar): string[] =>\n  typeof str === 'string'\n    ? str\n        .split(`\\\\${splitChar}`)\n        .map(c => c.split(splitChar))\n        .reduce((prev, curr, idx) => {\n          if (idx === 0) {\n            return curr;\n          }\n          return [...prev.slice(0, -1), `${prev.at(-1)}${splitChar}${curr[0]}`, ...curr.slice(1)];\n        }, [])\n    : [];\n\n/**\n * Joins an array of strings using the given character (see {@link defaultJoinChar}). When\n * the given character appears in an array element, a backslash will be added just before it\n * to distinguish it from the join character. Effectively the inverse of {@link splitBy}.\n *\n * TIP: The join character can actually be a string of any length. Only the first character\n * will be searched for in the array elements and preceded by a backslash.\n *\n * @example\n * joinWith(['this,,that', '', 'the other', '', '', ','], ', ')\n * // would return\n * 'this\\\\,\\\\,that, , the other, , , \\\\,'\n */\nexport const joinWith = (strArr: unknown[], joinChar: string = defaultJoinChar): string =>\n  strArr.map(str => `${str ?? ''}`.replaceAll(joinChar[0], `\\\\${joinChar[0]}`)).join(joinChar);\n\ntype IsUnknown<T> = unknown extends T ? true : false;\ntype Trimmed<T> = IsUnknown<T> extends true ? string : T;\n\n/**\n * Trims the value if it is a string. Otherwise returns the value as is.\n */\nexport const trimIfString = <T>(val: T): Trimmed<T> =>\n  (typeof val === 'string' ? val.trim() : val) as Trimmed<T>;\n\ntype ToArrayResult<T> =\n  IsUnknown<T> extends true\n    ? string[]\n    : T extends readonly (infer U)[]\n      ? Trimmed<U>[]\n      : T extends string\n        ? string[]\n        : T extends number\n          ? number[]\n          : never[];\n\n/**\n * Splits a string by comma then trims each element. Arrays are returned as is except\n * any string elements are trimmed.\n */\nexport const toArray = <T>(\n  a: T,\n  { retainEmptyStrings }: { retainEmptyStrings?: boolean } = {}\n): ToArrayResult<T> =>\n  (Array.isArray(a)\n    ? a.map(trimIfString)\n    : typeof a === 'string'\n      ? splitBy(a, defaultJoinChar)\n          .filter(retainEmptyStrings ? () => true : s => !/^\\s*$/.test(s))\n          .map(s => s.trim())\n      : typeof a === 'number'\n        ? [a]\n        : []) as ToArrayResult<T>;\n\n/**\n * Determines if an array is free of `null`/`undefined`.\n */\nexport const nullFreeArray = <T>(arr: T[]): arr is Exclude<T, null>[] =>\n  arr.every(el => el === false || (el ?? false) !== false);\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { numericRegex as numericQuantityRegex } from 'numeric-quantity';\n\n/**\n * Converts a value to lowercase if it's a string, otherwise returns the value as is.\n */\n// v8 ignore next\nexport const lc = <T>(v: T): T => (typeof v === 'string' ? (v.toLowerCase() as T) : v);\n\n/**\n * Regex matching numeric strings. Passes for positive/negative integers, decimals,\n * and E notation, with optional surrounding whitespace.\n */\nexport const numericRegex: RegExp = new RegExp(\n  numericQuantityRegex.source.replace(/^\\^/, String.raw`^\\s*`).replace(/\\$$/, String.raw`\\s*$`)\n);\n\n/**\n * Determines if a variable is a plain old JavaScript object, aka POJO.\n */\n// oxlint-disable-next-line typescript/no-explicit-any\nexport const isPojo = (obj: unknown): obj is Record<string, any> =>\n  obj !== null && typeof obj === 'object' && Object.getPrototypeOf(obj) === Object.prototype;\n\n/**\n * Simple helper to determine whether a value is null, undefined, or an empty string.\n */\nexport const nullOrUndefinedOrEmpty = (value: unknown): value is null | undefined | '' =>\n  value === null || value === undefined || value === '';\n","import type { RuleGroupType, RuleGroupTypeAny, RuleGroupTypeIC, RuleType } from '../types';\nimport { isPojo } from './misc';\n\n/**\n * Determines if an object is a {@link RuleType} (only checks for a `field` property).\n */\nexport const isRuleType = (s: unknown): s is RuleType =>\n  isPojo(s) && 'field' in s && typeof s.field === 'string';\n\n/**\n * Determines if an object is a {@link RuleGroupType} or {@link RuleGroupTypeIC}.\n */\nexport const isRuleGroup = (rg: unknown): rg is RuleGroupTypeAny =>\n  isPojo(rg) && Array.isArray(rg.rules);\n\n/**\n * Determines if an object is a {@link RuleGroupType}.\n */\nexport const isRuleGroupType = (rg: unknown): rg is RuleGroupType =>\n  isRuleGroup(rg) && typeof rg.combinator === 'string';\n\n/**\n * Determines if an object is a {@link RuleGroupTypeIC}.\n */\nexport const isRuleGroupTypeIC = (rg: unknown): rg is RuleGroupTypeIC =>\n  isRuleGroup(rg) && rg.combinator === undefined;\n","import type { RuleGroupTypeAny, RuleType } from '../types';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Signature returned when a change alters the _shape_ of the query—rules or groups added,\n * removed, moved, or reordered—rather than the properties of a single node. Structural changes\n * never coalesce with each other, so each one produces its own history entry.\n */\nexport const structuralSignature = '~structural';\n\n/**\n * Signature returned when two queries differ by reference only, with no observable difference\n * in their properties.\n */\nexport const unchangedSignature = '';\n\n/**\n * Returns the list of property names that differ between two nodes, ignoring `rules` (which is\n * compared structurally by the caller).\n */\nconst changedProps = (prev: object, next: object): string[] => {\n  const keys = new Set([...Object.keys(prev), ...Object.keys(next)]);\n  keys.delete('rules');\n  const changed: string[] = [];\n  for (const key of keys) {\n    if (!Object.is(prev[key as keyof object], next[key as keyof object])) {\n      changed.push(key);\n    }\n  }\n  return changed.toSorted();\n};\n\nconst signatureOfNode = (\n  prev: RuleGroupTypeAny | RuleType | string,\n  next: RuleGroupTypeAny | RuleType | string,\n  /** Identifier of the parent group, used to describe independent combinator changes. */\n  parentId: string,\n  /** Index within the parent's `rules` array, used to describe independent combinator changes. */\n  index: number\n): string => {\n  // Immer's structural sharing means untouched subtrees keep their identity, so reference\n  // equality prunes the walk to the single mutated path.\n  if (prev === next) return unchangedSignature;\n\n  // Independent combinators are plain strings in the `rules` array.\n  if (typeof prev === 'string' || typeof next === 'string') {\n    return typeof prev === typeof next ? `${parentId}:combinator[${index}]` : structuralSignature;\n  }\n\n  const prevIsGroup = isRuleGroup(prev);\n  const nextIsGroup = isRuleGroup(next);\n  // A rule replaced by a group (or vice versa) is a structural change.\n  if (prevIsGroup !== nextIsGroup) return structuralSignature;\n\n  if (!prevIsGroup || !nextIsGroup) {\n    const props = changedProps(prev, next);\n    return props.length === 0 ? unchangedSignature : `${next.id ?? ''}:${props.join(',')}`;\n  }\n\n  // Adding or removing children is structural.\n  if (prev.rules.length !== next.rules.length) return structuralSignature;\n\n  const ownProps = changedProps(prev, next);\n\n  let changedIndex = -1;\n  for (const [i, prevRule] of prev.rules.entries()) {\n    if (prevRule !== next.rules[i]) {\n      // More than one child changed, which means children were moved or reordered.\n      if (changedIndex !== -1) return structuralSignature;\n      changedIndex = i;\n    }\n  }\n\n  if (changedIndex === -1) {\n    return ownProps.length === 0 ? unchangedSignature : `${next.id ?? ''}:${ownProps.join(',')}`;\n  }\n\n  // Both this group's own properties and one of its children changed, which no single edit\n  // does—treat it as structural rather than attributing it to either.\n  if (ownProps.length > 0) return structuralSignature;\n\n  return signatureOfNode(\n    prev.rules[changedIndex],\n    next.rules[changedIndex],\n    next.id ?? '',\n    changedIndex\n  );\n};\n\n/**\n * Describes _what changed_ between two versions of a query as a short string, so that\n * consecutive edits to the same property of the same rule (e.g. typing in a value editor) can\n * be recognized and coalesced into a single history entry.\n *\n * Returns {@link structuralSignature} for changes to the shape of the query, {@link unchangedSignature} when the\n * two queries differ by reference only, and `\"<id>:<props>\"` otherwise.\n *\n * The walk prunes on reference equality, so it costs O(depth) rather than O(size) for the\n * single-node edits that make up the overwhelming majority of changes.\n *\n * Note that this relies on the structural sharing that Immer—and therefore every query\n * produced by RQB's own update functions—guarantees: nodes that did not change keep their\n * identity. A query that has been wholly rebuilt (deep-cloned, round-tripped through JSON,\n * re-parsed from a string) shares no identity with its predecessor, so it is reported as\n * {@link structuralSignature} and will not coalesce. That is a graceful degradation—every change simply\n * gets its own history entry—but controlled components that clone the query on every change\n * will not benefit from coalescing.\n */\nexport const signatureOf = (prev: RuleGroupTypeAny, next: RuleGroupTypeAny): string =>\n  signatureOfNode(prev, next, '', -1);\n","import { defaultCoalesceMs } from '../defaults';\nimport { structuralSignature } from './signature';\n\n/**\n * Determines whether a change should be absorbed into the current history entry instead of\n * pushing a new one. This is the exact rule {@link QueryManager} applies when recording history,\n * exposed so non-React implementations can manage their own history stacks without\n * reimplementing (and drifting from) the semantics.\n *\n * A change coalesces only when all three hold:\n * - the change is not structural (rules/groups added, removed, moved, or reordered)\n * - its signature matches the previously recorded signature\n * - it occurred within `coalesceMs` of the previous recording\n *\n * Note that {@link unchangedSignature} is not handled here. A change with no observable\n * difference is never recorded at all, which is a separate decision made before this check.\n *\n * @param prevSig Signature of the previously recorded change, or `undefined` if there is none.\n * @param nextSig Signature of the change being recorded, from {@link signatureOf}.\n * @param prevAt Timestamp of the previous recording.\n * @param now Timestamp of the change being recorded.\n * @param coalesceMs Coalescing window in milliseconds.\n */\nexport const shouldCoalesce = (\n  prevSig: string | undefined,\n  nextSig: string,\n  prevAt: number,\n  now: number,\n  coalesceMs: number = defaultCoalesceMs\n): boolean =>\n  nextSig !== structuralSignature &&\n  nextSig === prevSig &&\n  now >= prevAt &&\n  now - prevAt < coalesceMs;\n","import type {\n  RuleGroupArray,\n  RuleGroupICArray,\n  RuleGroupType,\n  RuleGroupTypeAny,\n  RuleGroupTypeIC,\n  RuleType,\n  ToRuleGroupType,\n  ToRuleGroupTypeIC,\n} from '../types';\nimport { isRuleGroup, isRuleGroupType, isRuleGroupTypeIC } from './isRuleGroup';\nimport { lc } from './misc';\n\nconst combinatorLevels = ['or', 'xor', 'and'] as const;\n\nconst isSameString = (a: unknown, b: string) => lc(a) === b;\n\nconst generateRuleGroupICWithConsistentCombinators = (\n  rg: RuleGroupTypeIC,\n  baseCombinatorLevel: number = 0\n): RuleGroupTypeIC => {\n  const baseCombinator = combinatorLevels[baseCombinatorLevel];\n\n  // oxlint-disable-next-line typescript/no-explicit-any\n  if (!rg.rules.includes(baseCombinator as any)) {\n    // No instances of this combinator, so group based on the next\n    // combinator level if at least two levels remain\n    return baseCombinatorLevel < combinatorLevels.length - 2\n      ? generateRuleGroupICWithConsistentCombinators(rg, baseCombinatorLevel + 1)\n      : rg;\n  }\n\n  const newRules = [...rg.rules] as RuleGroupICArray;\n  let cursor = 0;\n\n  // Group all chains of combinators in the rule array that are not the base combinator\n  while (cursor < newRules.length - 2) {\n    if (isSameString(newRules[cursor + 1], baseCombinator)) {\n      cursor += 2;\n      continue;\n    }\n\n    let nextBaseCombinatorIndex = -1;\n    for (let i = cursor + 2; i < newRules.length; i++) {\n      if (typeof newRules[i] === 'string' && lc(newRules[i]) === baseCombinator) {\n        nextBaseCombinatorIndex = i;\n        break;\n      }\n    }\n\n    if (nextBaseCombinatorIndex === -1) {\n      // No more instances of this combinator, so group all remaining rules and exit the loop\n      newRules.splice(\n        cursor,\n        newRules.length,\n        generateRuleGroupICWithConsistentCombinators(\n          // oxlint-disable-next-line typescript/no-explicit-any\n          { rules: newRules.slice(cursor) as any },\n          baseCombinatorLevel + 1\n        )\n      );\n      break;\n    } else {\n      // Group all rules between the current cursor and the next instance of the base combinator\n      newRules.splice(\n        cursor,\n        nextBaseCombinatorIndex - cursor,\n        generateRuleGroupICWithConsistentCombinators(\n          // oxlint-disable-next-line typescript/no-explicit-any\n          { rules: newRules.slice(cursor, nextBaseCombinatorIndex) as any },\n          baseCombinatorLevel + 1\n        )\n      );\n    }\n  }\n\n  return { ...rg, rules: newRules };\n};\n\n/**\n * Converts a {@link RuleGroupTypeIC} to {@link RuleGroupType}.\n *\n * This function is idempotent: {@link RuleGroupType} queries will be\n * returned as-is.\n *\n * @group Query Tools\n */\nexport const convertFromIC = <RG extends RuleGroupTypeAny>(rg: RG): ToRuleGroupType<RG> => {\n  if (isRuleGroupType(rg)) {\n    return rg as ToRuleGroupType<RG>;\n  }\n  const processedRG = generateRuleGroupICWithConsistentCombinators(rg);\n  const rules: RuleGroupArray = [];\n  let combinator = 'and';\n  for (const [idx, r] of processedRG.rules.entries()) {\n    if (typeof r === 'string') {\n      if (idx === 1) combinator = r;\n    } else {\n      rules.push(isRuleGroup(r) ? convertFromIC(r) : r);\n    }\n  }\n  return { ...processedRG, combinator, rules } as ToRuleGroupType<RG>;\n};\n\n/**\n * Converts a {@link RuleGroupType} to {@link RuleGroupTypeIC}.\n *\n * This function is idempotent: {@link RuleGroupTypeIC} queries will be\n * returned as-is.\n *\n * @group Query Tools\n */\nexport const convertToIC = <RG extends RuleGroupTypeAny>(rg: RG): ToRuleGroupTypeIC<RG> => {\n  if (isRuleGroupTypeIC(rg)) {\n    return rg as ToRuleGroupTypeIC<RG>;\n  }\n  const { combinator, ...queryWithoutCombinator } = rg;\n  const rules: (RuleGroupTypeIC | RuleType | string)[] = [];\n  const { length } = rg.rules;\n  for (let idx = 0; idx < length; idx++) {\n    const r = rg.rules[idx];\n    if (isRuleGroup(r)) {\n      rules.push(convertToIC(r));\n    } else {\n      rules.push(r);\n    }\n    if (combinator && idx < length - 1) {\n      rules.push(combinator);\n    }\n  }\n  return { ...queryWithoutCombinator, rules } as ToRuleGroupTypeIC<RG>;\n};\n\n/**\n * Converts a {@link RuleGroupType} to {@link RuleGroupTypeIC}. For a more explicit\n * operation, use {@link convertToIC}.\n *\n * @group Query Tools\n */\nfunction convertQuery(query: RuleGroupType): RuleGroupTypeIC;\n/**\n * Converts a {@link RuleGroupTypeIC} to {@link RuleGroupType}. For a more explicit\n * operation, use {@link convertFromIC}.\n *\n * @group Query Tools\n */\nfunction convertQuery(query: RuleGroupTypeIC): RuleGroupType;\nfunction convertQuery(query: RuleGroupType | RuleGroupTypeIC): RuleGroupType | RuleGroupTypeIC {\n  return isRuleGroupTypeIC(query) ? convertFromIC(query) : convertToIC(query);\n}\n\nexport { convertQuery };\n","import type { ClassValue } from 'clsx';\nimport { standardClassnames } from '../defaults';\nimport type { Classname, Classnames, ValidationMap } from '../types';\nimport { clsx } from './clsx';\n\n/** Classname keys that have both a standard class and a `controlClassnames` entry. */\ntype StandardClassnameKey = keyof typeof standardClassnames & keyof Classnames;\n\n/**\n * A classname applied only when `when` returns true for the current state.\n *\n * `key` is used to look up both the standard classname and the corresponding `controlClassnames`\n * entry. Set `standardOnly` when the standard class is conditional but no custom class\n * corresponds to it.\n */\nexport interface ClassnameCondition<S> {\n  key: StandardClassnameKey;\n  when: (state: S) => boolean | undefined;\n  standardOnly?: boolean;\n}\n\n/**\n * How one derived classname is composed: the `controlClassnames` keys that contribute to it (in\n * application order, after the standard classname), plus any state-dependent classes.\n */\nexport interface ClassnameSpec<S> {\n  sources: readonly (keyof Classnames)[];\n  conditions?: readonly ClassnameCondition<S>[];\n}\n\ntype ClassnameSpecMap<K extends string, S> = Record<\n  K,\n  readonly (keyof Classnames)[] | ClassnameSpec<S>\n>;\n\n/** Keys of the `classNames` object returned for a rule. */\nexport type RuleClassnameKey =\n  | 'shiftActions'\n  | 'dragHandle'\n  | 'fields'\n  | 'matchMode'\n  | 'matchThreshold'\n  | 'operators'\n  | 'valueSource'\n  | 'value'\n  | 'cloneRule'\n  | 'lockRule'\n  | 'muteRule'\n  | 'removeRule'\n  | 'valueListItem';\n\n/** Keys of the `classNames` object returned for a rule group. */\nexport type RuleGroupClassnameKey =\n  | 'header'\n  | 'shiftActions'\n  | 'undoRedoActions'\n  | 'undoAction'\n  | 'redoAction'\n  | 'dragHandle'\n  | 'combinators'\n  | 'notToggle'\n  | 'addRule'\n  | 'addGroup'\n  | 'cloneGroup'\n  | 'lockGroup'\n  | 'muteGroup'\n  | 'removeGroup'\n  | 'body';\n\n/** Drag-and-drop state that can contribute conditional classnames. */\nexport interface DndClassNameState {\n  isDragging?: boolean;\n  isOver?: boolean;\n  dropEffect?: 'move' | 'copy';\n  groupItems?: boolean;\n  dropNotAllowed?: boolean;\n}\n\n/** State that contributes conditional classnames to a rule's wrapper element. */\nexport interface RuleClassNameState extends DndClassNameState {\n  disabled?: boolean;\n  muted?: boolean;\n  hasSubQuery?: boolean;\n}\n\nconst ruleClassnameSources: ClassnameSpecMap<RuleClassnameKey, RuleClassNameState> = {\n  shiftActions: ['shiftActions'],\n  dragHandle: ['dragHandle'],\n  fields: ['valueSelector', 'fields'],\n  matchMode: ['valueSelector', 'matchMode'],\n  matchThreshold: ['valueSelector', 'matchThreshold'],\n  operators: ['valueSelector', 'operators'],\n  valueSource: ['valueSelector', 'valueSource'],\n  value: ['value'],\n  cloneRule: ['actionElement', 'cloneRule'],\n  lockRule: ['actionElement', 'lockRule'],\n  muteRule: ['actionElement', 'muteRule'],\n  removeRule: ['actionElement', 'removeRule'],\n  valueListItem: ['valueListItem'],\n};\n\nconst ruleGroupClassnameSources: ClassnameSpecMap<RuleGroupClassnameKey, DndClassNameState> = {\n  header: {\n    sources: ['header'],\n    conditions: [\n      // The standard `dndOver` class has no custom counterpart on the header element.\n      { key: 'dndOver', when: s => s.isOver, standardOnly: true },\n      { key: 'dndCopy', when: s => s.isOver && s.dropEffect === 'copy' },\n      { key: 'dndDropNotAllowed', when: s => s.dropNotAllowed },\n    ],\n  },\n  shiftActions: ['shiftActions'],\n  undoRedoActions: ['undoRedoActions'],\n  undoAction: ['actionElement', 'undoAction'],\n  redoAction: ['actionElement', 'redoAction'],\n  dragHandle: ['dragHandle'],\n  combinators: ['valueSelector', 'combinators'],\n  notToggle: ['notToggle'],\n  addRule: ['actionElement', 'addRule'],\n  addGroup: ['actionElement', 'addGroup'],\n  cloneGroup: ['actionElement', 'cloneGroup'],\n  lockGroup: ['actionElement', 'lockGroup'],\n  muteGroup: ['actionElement', 'muteGroup'],\n  removeGroup: ['actionElement', 'removeGroup'],\n  body: ['body'],\n};\n\n/**\n * Conditional classes applied to a rule's wrapper element.\n *\n * Note that this is deliberately _not_ the same set as {@link ruleGroupOuterConditions}: a rule\n * reflects more drag-and-drop states than a group does. Declaring each set separately is what\n * keeps an implementation from assuming they're symmetric.\n */\nconst ruleOuterConditions: readonly ClassnameCondition<RuleClassNameState>[] = [\n  { key: 'disabled', when: s => s.disabled },\n  { key: 'muted', when: s => s.muted },\n  { key: 'dndDragging', when: s => s.isDragging },\n  { key: 'dndOver', when: s => s.isOver },\n  { key: 'dndCopy', when: s => s.isOver && s.dropEffect === 'copy' },\n  { key: 'dndGroup', when: s => s.isOver && s.groupItems },\n  { key: 'dndDropNotAllowed', when: s => s.dropNotAllowed },\n  { key: 'hasSubQuery', when: s => s.hasSubQuery },\n];\n\n/** Conditional classes applied to a rule group's wrapper element. */\nconst ruleGroupOuterConditions: readonly ClassnameCondition<RuleClassNameState>[] = [\n  { key: 'disabled', when: s => s.disabled },\n  { key: 'muted', when: s => s.muted },\n  { key: 'dndDragging', when: s => s.isDragging },\n  { key: 'dndGroup', when: s => s.isOver && s.groupItems },\n];\n\n/** State that contributes conditional classnames to the query builder's wrapper element. */\nexport interface QueryBuilderClassNameState {\n  disabled?: boolean;\n  validationResult?: boolean | ValidationMap;\n}\n\n/**\n * Conditional classes applied to the query builder's wrapper element.\n *\n * Only a `boolean` validation result contributes a class; a {@link ValidationMap} describes\n * individual rules and groups, not the query as a whole.\n */\nconst queryBuilderOuterConditions: readonly ClassnameCondition<QueryBuilderClassNameState>[] = [\n  { key: 'disabled', when: s => s.disabled },\n  { key: 'valid', when: s => typeof s.validationResult === 'boolean' && s.validationResult },\n  { key: 'invalid', when: s => typeof s.validationResult === 'boolean' && !s.validationResult },\n];\n\n/** Options common to every classname derivation. */\nexport interface DeriveClassNamesOptions {\n  /** The merged `controlClassnames` for the query builder. */\n  classNames: Partial<Classnames> | undefined;\n  /** When `true`, standard (`rule`, `ruleGroup-*`, etc.) classnames are omitted. */\n  suppressStandardClassnames?: boolean;\n}\n\n/**\n * Expands conditions into `clsx` arguments: every custom class first (in declaration order),\n * then a single object of standard classes.\n */\nconst conditionArgs = <S>(\n  conditions: readonly ClassnameCondition<S>[],\n  state: S,\n  { classNames, suppressStandardClassnames }: DeriveClassNamesOptions\n): ClassValue[] => {\n  const evaluated = conditions.map(condition => [condition, !!condition.when(state)] as const);\n\n  return [\n    ...evaluated\n      .filter(([condition]) => !condition.standardOnly)\n      .map(([condition, active]) => active && classNames?.[condition.key]),\n    suppressStandardClassnames ||\n      Object.fromEntries(\n        evaluated.map(([condition, active]) => [standardClassnames[condition.key], active])\n      ),\n  ];\n};\n\n/** Composes the classname for a single entry of a spec map. */\nconst deriveFromSpec = <S>(\n  key: string,\n  spec: readonly (keyof Classnames)[] | ClassnameSpec<S>,\n  state: S,\n  options: DeriveClassNamesOptions\n): string => {\n  const { sources, conditions }: ClassnameSpec<S> = Array.isArray(spec)\n    ? { sources: spec }\n    : (spec as ClassnameSpec<S>);\n\n  // `classNames` is optional chained because React Native passes a partial schema.\n  return clsx(\n    options.suppressStandardClassnames ||\n      standardClassnames[key as keyof typeof standardClassnames],\n    ...sources.map(source => options.classNames?.[source]),\n    ...(conditions ? conditionArgs(conditions, state, options) : [])\n  );\n};\n\nconst deriveFromSpecs = <K extends string, S>(\n  specs: ClassnameSpecMap<K, S>,\n  state: S,\n  options: DeriveClassNamesOptions\n): Record<K, string> => {\n  const result = {} as Record<K, string>;\n\n  for (const [key, spec] of Object.entries(specs) as [\n    K,\n    readonly (keyof Classnames)[] | ClassnameSpec<S>,\n  ][]) {\n    result[key] = deriveFromSpec(key, spec, state, options);\n  }\n\n  return result;\n};\n\n/**\n * Classnames for each element rendered by a rule. This is the framework-agnostic core of the\n * `classNames` object returned by the `useRule` hook.\n *\n * @group Query Tools\n */\nexport const deriveRuleClassNames = (\n  options: DeriveClassNamesOptions\n): Record<RuleClassnameKey, string> => deriveFromSpecs(ruleClassnameSources, {}, options);\n\n/**\n * The classname for a single element of a rule, composed from the same table as\n * {@link deriveRuleClassNames}. Useful where only one is needed, such as the items of a\n * multi-value editor.\n *\n * @group Query Tools\n */\nexport const deriveRuleClassName = (\n  key: RuleClassnameKey,\n  options: DeriveClassNamesOptions\n): string => deriveFromSpec(key, ruleClassnameSources[key], {}, options);\n\n/**\n * Classnames for each element rendered by a rule group, including its conditionally-classed\n * `header`. This is the framework-agnostic core of the `classNames` object returned by the\n * `useRuleGroup` hook.\n *\n * @group Query Tools\n */\nexport const deriveRuleGroupClassNames = (\n  options: DeriveClassNamesOptions & DndClassNameState\n): Record<RuleGroupClassnameKey, string> =>\n  deriveFromSpecs(ruleGroupClassnameSources, options, options);\n\n/** Inputs common to every outer (wrapper) classname derivation. */\nexport interface OuterClassNameOptionsBase extends DeriveClassNamesOptions {\n  /**\n   * Classnames contributed by the rule or group itself and its configuration, applied first.\n   * For a rule that is the rule/field/operator classnames; for a group, the group and combinator\n   * classnames.\n   */\n  leadingClassNames?: (Classname | null)[];\n  /** Appended last, as produced by `getValidationClassNames`. */\n  validationClassName?: Classname;\n}\n\n/** Inputs to {@link deriveRuleOuterClassName} and {@link deriveRuleGroupOuterClassName}. */\nexport interface OuterClassNameOptions extends OuterClassNameOptionsBase, RuleClassNameState {}\n\nconst deriveOuterClassName = <S extends OuterClassNameOptionsBase>(\n  standardKey: 'rule' | 'ruleGroup' | 'queryBuilder',\n  conditions: readonly ClassnameCondition<S>[],\n  options: S\n): string => {\n  const {\n    classNames,\n    suppressStandardClassnames,\n    leadingClassNames = [],\n    validationClassName,\n  } = options;\n\n  return clsx(\n    ...leadingClassNames,\n    suppressStandardClassnames || standardClassnames[standardKey],\n    classNames?.[standardKey],\n    ...conditionArgs(conditions, options, options),\n    validationClassName\n  );\n};\n\n/**\n * The outer (wrapper) classname for a rule, including every conditional state class.\n *\n * @group Query Tools\n */\nexport const deriveRuleOuterClassName = (options: OuterClassNameOptions): string =>\n  deriveOuterClassName('rule', ruleOuterConditions, options);\n\n/**\n * The outer (wrapper) classname for a rule group, including every conditional state class.\n *\n * A group reflects fewer drag-and-drop states than a rule—`dndOver`, `dndCopy`,\n * `dndDropNotAllowed`, and `hasSubQuery` do not apply—so this is not interchangeable with\n * {@link deriveRuleOuterClassName}.\n *\n * @group Query Tools\n */\nexport const deriveRuleGroupOuterClassName = (options: OuterClassNameOptions): string =>\n  deriveOuterClassName('ruleGroup', ruleGroupOuterConditions, options);\n\n/**\n * The outer (wrapper) classname for the query builder itself, including the conditional\n * `disabled`, `valid`, and `invalid` state classes.\n *\n * @group Query Tools\n */\nexport const deriveQueryBuilderClassNames = (\n  options: OuterClassNameOptionsBase & QueryBuilderClassNameState\n): string => deriveOuterClassName('queryBuilder', queryBuilderOuterConditions, options);\n","import { defaultCombinators, groupInvalidReasons } from '../defaults';\nimport type { QueryValidator, RuleGroupTypeAny, RuleType, ValidationMap } from '../types';\nimport { isRuleGroup, isRuleGroupType } from './isRuleGroup';\n\n/**\n * This is an example validation function you can pass to {@link react-querybuilder!QueryBuilder QueryBuilder} in the\n * `validator` prop. It assumes that you want to validate groups, and has a no-op\n * for validating rules which you can replace with your own implementation.\n */\nexport const defaultValidator: QueryValidator = query => {\n  const result: ValidationMap = {};\n\n  /**\n   * Replace this with your custom rule validator.\n   */\n  const validateRule = (rule: RuleType) => {\n    // Set `result[rule.id] = true` for a valid rule, or either\n    // `{ valid: false, reasons: ['whatever', 'reasons', 'here'] }`\n    // or simply `false` for an invalid rule.\n    /* v8 ignore start -- @preserve */\n    // oxlint-disable-next-line no-unused-expressions\n    if (rule.id) result[rule.id]; // = true;\n    /* v8 ignore stop -- @preserve */\n  };\n\n  const validateGroup = (rg: RuleGroupTypeAny) => {\n    // oxlint-disable-next-line typescript/no-explicit-any\n    const reasons: any[] = [];\n    if (rg.rules.length === 0) {\n      reasons.push(groupInvalidReasons.empty);\n    } else if (!isRuleGroupType(rg)) {\n      // Odd indexes should be valid combinators and even indexes should be rules or groups\n      let invalidICs = false;\n      for (let i = 0; i < rg.rules.length && !invalidICs; i++) {\n        if (\n          (i % 2 === 0 && typeof rg.rules[i] === 'string') ||\n          (i % 2 === 1 && typeof rg.rules[i] !== 'string') ||\n          (i % 2 === 1 &&\n            typeof rg.rules[i] === 'string' &&\n            !defaultCombinators.map(c => c.name as string).includes(rg.rules[i] as string))\n        ) {\n          invalidICs = true;\n        }\n      }\n      if (invalidICs) {\n        reasons.push(groupInvalidReasons.invalidIndependentCombinators);\n      }\n    }\n    // Non-independent combinators should be valid, but only checked if there are multiple rules\n    // since combinators don't really apply to groups with only one rule/group\n    if (\n      isRuleGroupType(rg) &&\n      !defaultCombinators.map(c => c.name as string).includes(rg.combinator) &&\n      rg.rules.length > 1\n    ) {\n      reasons.push(groupInvalidReasons.invalidCombinator);\n    }\n    /* v8 ignore else -- @preserve */\n    if (rg.id) {\n      result[rg.id] = reasons.length > 0 ? { valid: false, reasons } : true;\n    }\n    for (const r of rg.rules) {\n      if (typeof r === 'string') {\n        // Validation for this case was done earlier\n      } else if (isRuleGroup(r)) {\n        validateGroup(r);\n      } else {\n        validateRule(r);\n      }\n    }\n  };\n\n  validateGroup(query);\n\n  return result;\n  // You can return the result object itself like above, or if you just\n  // want the entire query to be marked invalid if _any_ rules/groups are\n  // invalid, return a boolean like this:\n  //   return Object.values(result).map(rv => (typeof rv !== 'boolean')).includes(true);\n  // That will return `true` if no errors were found.\n};\n","// All code in this file is adapted from:\n// npm: https://www.npmjs.com/package/ts-extras\n// src: https://github.com/sindresorhus/ts-extras\n\n/**\n * Original looked like this (not sure why template string is used):\n * ```\n * type ObjectKeys<T extends object> = `${Exclude<keyof T, symbol>}`;\n * ```\n */\ntype ObjectKeys<T extends object> = Exclude<keyof T, symbol>;\n\n/**\n * A strongly-typed version of `Object.keys()`.\n *\n * [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-keys.ts)\n */\nexport const objectKeys = Object.keys as <Type extends object>(\n  value: Type\n) => Array<ObjectKeys<Type>>;\n\n/**\n * A strongly-typed version of `Object.entries()`.\n *\n * [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-entries.ts)\n */\nexport const objectEntries = Object.entries as <Type extends Record<PropertyKey, unknown>>(\n  value: Type\n) => Array<[ObjectKeys<Type>, Type[ObjectKeys<Type>]]>;\n\n/**\n * Returns `true` if the key could cause prototype pollution when used\n * as a property name in bracket-notation assignment.\n */\nexport const isUnsafeKey = (key: unknown): boolean =>\n  key === '__proto__' || key === 'constructor' || key === 'prototype';\n","import type { RequireAtLeastOne } from 'type-fest';\nimport { defaultPlaceholderLabel, defaultPlaceholderName } from '../defaults';\nimport type {\n  BaseOption,\n  BaseOptionMap,\n  FlexibleOption,\n  FlexibleOptionGroup,\n  FlexibleOptionList,\n  FlexibleOptionListProp,\n  FullOption,\n  FullOptionList,\n  FullOptionMap,\n  FullOptionRecord,\n  GetOptionIdentifierType,\n  Option,\n  OptionGroup,\n  Placeholder,\n  ToFullOption,\n  ValueOption,\n  WithUnknownIndex,\n} from '../types';\nimport { isPojo } from './misc';\nimport { objectKeys } from './objectUtils';\n\nconst isOptionWithName = (opt: BaseOption): opt is Option =>\n  isPojo(opt) && 'name' in opt && typeof opt.name === 'string';\nconst isOptionWithValue = (opt: BaseOption): opt is ValueOption =>\n  isPojo(opt) && 'value' in opt && typeof opt.value === 'string';\n\n/**\n * Converts an {@link Option} or {@link ValueOption} (i.e., {@link BaseOption})\n * into a {@link FullOption}. Full options are left unchanged.\n *\n * @group Option Lists\n */\nexport function toFullOption<Opt extends BaseOption>(\n  opt: Opt | string,\n  baseProperties?: Record<string, unknown>,\n  labelMap?: Record<string, unknown>\n): ToFullOption<Opt> {\n  if (typeof opt === 'string') {\n    return {\n      ...baseProperties,\n      name: opt,\n      value: opt,\n      label: labelMap?.[opt] ?? opt,\n    } as ToFullOption<Opt>;\n  }\n\n  const idObj: { name?: string; value?: string } = {};\n  let needsUpdating = !!baseProperties;\n\n  if (isOptionWithName(opt) && !isOptionWithValue(opt)) {\n    idObj.value = opt.name;\n    needsUpdating = true;\n  } else if (!isOptionWithName(opt) && isOptionWithValue(opt)) {\n    idObj.name = opt.value;\n    needsUpdating = true;\n  }\n\n  if (needsUpdating) {\n    return Object.assign({}, baseProperties, opt, idObj) as ToFullOption<Opt>;\n  }\n\n  return opt as ToFullOption<Opt>;\n}\n\n/**\n * Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.\n * Lists of full options are left unchanged.\n *\n * @group Option Lists\n */\nexport function toFullOptionList<Opt extends BaseOption>(\n  optList: unknown[],\n  baseProperties?: Record<string, unknown>,\n  labelMap?: Record<string, unknown>\n): FullOptionList<Opt> {\n  if (!Array.isArray(optList)) {\n    return [] as unknown as FullOptionList<Opt>;\n  }\n\n  const list = optList as FlexibleOptionList<Opt>;\n\n  if (isFlexibleOptionGroupArray(list)) {\n    return list.map(optGroup => ({\n      ...optGroup,\n      options: optGroup.options.map(opt => toFullOption(opt, baseProperties, labelMap)),\n    })) as unknown as FullOptionList<Opt>;\n  }\n\n  return (list as Opt[]).map(opt =>\n    toFullOption(opt, baseProperties, labelMap)\n  ) as FullOptionList<Opt>;\n}\n\n/**\n * Converts a {@link FlexibleOptionList} into a {@link FullOptionList}.\n * Lists of full options are left unchanged.\n *\n * @group Option Lists\n */\nexport function toFullOptionMap<OptMap extends BaseOptionMap>(\n  optMap: OptMap,\n  baseProperties?: Record<string, unknown>\n): OptMap extends BaseOptionMap<infer V, infer K> ? Partial<Record<K, ToFullOption<V>>> : never {\n  type FullOptMapType =\n    OptMap extends BaseOptionMap<infer VT, infer KT>\n      ? Partial<Record<KT, ToFullOption<VT>>>\n      : never;\n\n  return Object.fromEntries(\n    (Object.entries(optMap) as [string, FlexibleOption][]).map(([k, v]) => [\n      k,\n      toFullOption(v, baseProperties),\n    ])\n  ) as FullOptMapType;\n}\n\n/**\n * @deprecated Renamed to {@link uniqByIdentifier}.\n *\n * @group Option Lists\n */\nexport const uniqByName = <\n  T extends { name: string; value?: string } | { name?: string; value: string },\n>(\n  originalArray: T[]\n): T[] => uniqByIdentifier(originalArray);\n\n/**\n * Generates a new array of objects with duplicates removed based\n * on the identifying property (`value` or `name`)\n *\n * @group Option Lists\n */\nexport const uniqByIdentifier = <\n  T extends RequireAtLeastOne<{ name: string; value: string }, 'name' | 'value'>,\n>(\n  originalArray: T[]\n): T[] => {\n  const names = new Set<string>();\n  const newArray: T[] = [];\n  for (const el of originalArray) {\n    if (!names.has((el.value ?? el.name)!)) {\n      names.add((el.value ?? el.name)!);\n      newArray.push(el);\n    }\n  }\n  return originalArray.length === newArray.length ? originalArray : newArray;\n};\n\n/**\n * Determines if an {@link OptionList} is an {@link OptionGroup} array.\n *\n * @group Option Lists\n */\nexport const isOptionGroupArray = (arr: unknown): arr is OptionGroup<BaseOption>[] =>\n  Array.isArray(arr) &&\n  arr.length > 0 &&\n  isPojo(arr[0]) &&\n  'options' in arr[0] &&\n  Array.isArray(arr[0].options);\n\n/**\n * Determines if an array is a flat array of {@link FlexibleOption}.\n *\n * @group Option Lists\n */\nexport const isFlexibleOptionArray = (arr: unknown): arr is FlexibleOption[] => {\n  let isFOA = false;\n  if (Array.isArray(arr)) {\n    for (const o of arr) {\n      if (isOptionWithName(o) || isOptionWithValue(o)) {\n        isFOA = true;\n      } else {\n        return false;\n      }\n    }\n  }\n  return isFOA;\n};\n\n/**\n * Determines if an array is a flat array of {@link FullOption}.\n *\n * @group Option Lists\n */\nexport const isFullOptionArray = (arr: unknown): arr is FullOption[] => {\n  let isFOA = false;\n  if (Array.isArray(arr)) {\n    for (const o of arr) {\n      if (isOptionWithName(o) && isOptionWithValue(o)) {\n        isFOA = true;\n      } else {\n        return false;\n      }\n    }\n  }\n  return isFOA;\n};\n\n/**\n * Determines if a {@link FlexibleOptionList} is a {@link FlexibleOptionGroup} array.\n *\n * @group Option Lists\n */\nexport const isFlexibleOptionGroupArray = (\n  arr: unknown,\n  { allowEmpty = false }: { allowEmpty?: boolean } = {}\n): arr is FlexibleOptionGroup[] => {\n  let isFOGA = false;\n  if (Array.isArray(arr)) {\n    for (const og of arr) {\n      if (\n        isPojo(og) &&\n        'options' in og &&\n        (isFlexibleOptionArray(og.options) ||\n          (allowEmpty && Array.isArray(og.options) && og.options.length === 0))\n      ) {\n        isFOGA = true;\n      } else {\n        return false;\n      }\n    }\n  }\n  return isFOGA;\n};\n\n/**\n * Determines if a {@link FlexibleOptionList} is a {@link OptionGroup} array of {@link FullOption}.\n *\n * @group Option Lists\n */\nexport const isFullOptionGroupArray = (\n  arr: unknown,\n  { allowEmpty = false }: { allowEmpty?: boolean } = {}\n): arr is OptionGroup<FullOption>[] => {\n  let isFOGA = false;\n  if (Array.isArray(arr)) {\n    for (const og of arr) {\n      if (\n        isPojo(og) &&\n        'options' in og &&\n        (isFullOptionArray(og.options) ||\n          (allowEmpty && Array.isArray(og.options) && og.options.length === 0))\n      ) {\n        isFOGA = true;\n      } else {\n        return false;\n      }\n    }\n  }\n  return isFOGA;\n};\n\n/**\n * Gets the option from an {@link OptionList} with the given `name`. Handles\n * {@link Option} arrays as well as {@link OptionGroup} arrays.\n *\n * @group Option Lists\n */\nexport function getOption<OptType extends FullOption>(\n  arr: FullOptionList<OptType>,\n  name: string\n): OptType | undefined;\nexport function getOption<OptType extends ValueOption>(\n  arr: FlexibleOptionList<OptType>,\n  name: string\n): OptType | undefined;\nexport function getOption<OptType extends Option>(\n  arr: FlexibleOptionList<OptType>,\n  name: string\n): OptType | undefined;\nexport function getOption<OptType extends BaseOption>(\n  arr: FlexibleOptionList<OptType>,\n  name: string\n): OptType | undefined {\n  const options = isFlexibleOptionGroupArray(arr, { allowEmpty: true })\n    ? arr.flatMap(og => og.options)\n    : arr;\n  return options.find(op => op.value === name || op.name === name) as OptType | undefined;\n}\n\n/**\n * Gets the first option from an {@link OptionList}.\n *\n * @group Option Lists\n */\nexport function getFirstOption<Opt extends FullOption>(\n  arr?: OptionGroup<Opt>[] | Opt[]\n): GetOptionIdentifierType<Opt> | null;\nexport function getFirstOption<Opt extends ValueOption>(\n  arr?: OptionGroup<Opt>[] | Opt[]\n): GetOptionIdentifierType<Opt> | null;\nexport function getFirstOption<Opt extends Option>(\n  arr?: OptionGroup<Opt>[] | Opt[]\n): GetOptionIdentifierType<Opt> | null;\nexport function getFirstOption<Opt extends BaseOption>(\n  arr?: FlexibleOptionGroup<Opt>[] | Opt[]\n): GetOptionIdentifierType<Opt> | null {\n  if (!Array.isArray(arr) || arr.length === 0) {\n    return null;\n  } else if (isFlexibleOptionGroupArray(arr, { allowEmpty: true })) {\n    for (const og of arr) {\n      if (og.options.length > 0) {\n        return (og.options[0].value ?? og.options[0].name) as GetOptionIdentifierType<Opt>;\n      }\n    }\n    // v8 ignore next\n    return null;\n  }\n\n  return (arr[0].value ?? arr[0].name) as GetOptionIdentifierType<Opt>;\n}\n\n/**\n * Flattens {@link FlexibleOptionGroup} arrays into {@link BaseOption} arrays.\n * If the array is already flat, it is returned as is.\n *\n * @group Option Lists\n */\nexport const toFlatOptionArray = <T extends FullOption>(arr: FullOptionList<T>) =>\n  uniqByIdentifier(isOptionGroupArray(arr) ? arr.flatMap(og => og.options) : arr) as T[];\n\n/**\n * Generates a new {@link OptionGroup} array with duplicates\n * removed based on the identifying property (`value` or `name`).\n *\n * @group Option Lists\n */\nexport const uniqOptGroups = <T extends BaseOption>(\n  originalArray: FlexibleOptionGroup<T>[]\n): OptionGroup<ToFullOption<T>>[] => {\n  type K = T extends BaseOption<infer KT> ? KT : never;\n  const labels = new Set<string>();\n  const names = new Set<K>();\n  const newArray: OptionGroup<ToFullOption<T>>[] = [];\n  for (const el of originalArray) {\n    if (!labels.has(el.label)) {\n      labels.add(el.label);\n      const optionsForThisGroup: WithUnknownIndex<ToFullOption<T>>[] = [];\n      for (const opt of el.options) {\n        if (!names.has((opt.value ?? opt.name) as K)) {\n          names.add((opt.value ?? opt.name) as K);\n          optionsForThisGroup.push(toFullOption(opt) as WithUnknownIndex<ToFullOption<T>>);\n        }\n      }\n      newArray.push({ ...el, options: optionsForThisGroup });\n    }\n  }\n  return newArray;\n};\n\n/**\n * Generates a new {@link Option} or {@link OptionGroup} array with duplicates\n * removed based on the identifier property (`value` or `name`).\n *\n * @group Option Lists\n */\nexport const uniqOptList = <T extends BaseOption>(\n  originalArray: FlexibleOptionList<T>\n): WithUnknownIndex<BaseOption & FullOption>[] | OptionGroup<ToFullOption<T>>[] => {\n  if (isFlexibleOptionGroupArray(originalArray)) {\n    return uniqOptGroups(originalArray) as OptionGroup<ToFullOption<T>>[];\n  }\n  return uniqByIdentifier((originalArray as BaseOption[]).map(o => toFullOption(o)));\n};\n\n/** Result of {@link prepareOptionList}. */\nexport interface PreparedOptionList<O extends FullOption> {\n  defaultOption: FullOption;\n  optionList: FullOptionList<O>;\n  optionsMap: Partial<FullOptionRecord<O>>;\n}\n\n/** Parameters for {@link prepareOptionList}. */\nexport interface PrepareOptionListParams<O extends FullOption> {\n  placeholder?: Placeholder;\n  optionList?: FlexibleOptionListProp<O> | BaseOptionMap<O>;\n  baseOption?: Record<string, unknown>;\n  labelMap?: Record<string, string>;\n  autoSelectOption?: boolean;\n}\n\n/**\n * Normalizes any accepted option list shape—array, option groups, or a record—into a\n * `FullOptionList`, applying `baseOption` properties and (when `autoSelectOption` is `false`)\n * a leading placeholder option. Also returns the flattened lookup map and the option that\n * should be selected by default.\n *\n * Note: `labelMap` overrides only apply to array/option group input (where string options are\n * expanded); record input derives labels from the record values themselves.\n *\n * This is the same normalization `<QueryBuilder />` applies to `fields`, `operators`,\n * `combinators`, and value lists, so a non-React implementation resolves options identically.\n *\n * @group Option Lists\n */\nexport const prepareOptionList = <O extends FullOption>(\n  props: PrepareOptionListParams<O>\n): PreparedOptionList<O> => {\n  type OptionIdentifier = GetOptionIdentifierType<O>;\n\n  // v8 ignore next\n  const {\n    optionList: optionListPropOriginal,\n    baseOption = {},\n    labelMap = {},\n    placeholder: {\n      placeholderName = defaultPlaceholderName,\n      placeholderLabel = defaultPlaceholderLabel,\n      placeholderGroupLabel = defaultPlaceholderLabel,\n    } = {},\n    autoSelectOption = true,\n  } = props;\n\n  const defaultOption = {\n    id: placeholderName,\n    name: placeholderName,\n    value: placeholderName,\n    label: placeholderLabel,\n  } as FullOption;\n\n  const optionsProp = optionListPropOriginal ?? ([defaultOption] as FlexibleOptionList<O>);\n\n  let optionList: FullOptionList<O>;\n  const opts = (\n    Array.isArray(optionsProp)\n      ? toFullOptionList(optionsProp, baseOption, labelMap)\n      : (objectKeys(toFullOptionMap(optionsProp, baseOption)) as unknown as OptionIdentifier[])\n          // oxlint-disable-next-line no-map-spread\n          .map<FullOption<OptionIdentifier>>(opt => ({\n            ...optionsProp[opt]!,\n            name: opt,\n            value: opt,\n          }))\n          // oxlint-disable-next-line no-array-sort\n          .sort((a, b) => a.label.localeCompare(b.label))\n  ) as FullOptionList<O>;\n  if (isFlexibleOptionGroupArray(opts)) {\n    optionList = autoSelectOption\n      ? (uniqOptGroups(opts) as FullOptionList<O>)\n      : (uniqOptGroups([\n          {\n            label: placeholderGroupLabel,\n            options: [defaultOption],\n          },\n          ...opts,\n        ]) as FullOptionList<O>);\n  } else {\n    optionList = autoSelectOption\n      ? (uniqByIdentifier(opts as O[]) as FullOptionList<O>)\n      : (uniqByIdentifier([defaultOption, ...(opts as O[])]) as FullOptionList<O>);\n  }\n\n  let optionsMap: Partial<FullOptionRecord<O>> = {};\n  if (!Array.isArray(optionsProp)) {\n    const op = toFullOptionMap(optionsProp, baseOption) as FullOptionMap<O, OptionIdentifier>;\n    optionsMap = autoSelectOption ? op : { ...op, [placeholderName]: defaultOption };\n  } else {\n    if (isFlexibleOptionGroupArray(optionList)) {\n      for (const og of optionList as OptionGroup<ToFullOption<O>>[]) {\n        for (const opt of og.options) {\n          optionsMap[\n            (opt.value ??\n              /* v8 ignore start -- @preserve */ opt.name) /* v8 ignore stop -- @preserve */ as OptionIdentifier\n          ] = toFullOption(opt, baseOption);\n        }\n      }\n    } else {\n      for (const opt of optionList as ToFullOption<O>[]) {\n        optionsMap[\n          (opt.value ??\n            /* v8 ignore start -- @preserve */ opt.name) /* v8 ignore stop -- @preserve */ as OptionIdentifier\n        ] = toFullOption(opt, baseOption);\n      }\n    }\n  }\n\n  return { defaultOption, optionList, optionsMap };\n};\n","import type { FullField, OptionList, WithUnknownIndex } from '../types';\nimport { isFlexibleOptionGroupArray, toFullOption } from './optGroupUtils';\n\nconst filterByComparator = (field: FullField, operator: string, fieldToCompare: FullField) => {\n  const fullField = toFullOption(field);\n  const fullFieldToCompare = toFullOption(fieldToCompare);\n  if (fullField.value === fullFieldToCompare.value) {\n    return false;\n  }\n  if (typeof fullField.comparator === 'string') {\n    return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];\n  }\n  return (\n    fullField.comparator?.(fullFieldToCompare, operator) ??\n    /* v8 ignore start -- @preserve */ false /* v8 ignore stop -- @preserve */\n  );\n};\n\n/**\n * For a given {@link FullField}, returns the `fields` list filtered for\n * other fields that match by `comparator`. Only fields *other than the\n * one in question* will ever be included, even if `comparator` is `null`\n * or `undefined`. If `comparator` is a string, fields with the same value\n * for that property will be included. If `comparator` is a function, each\n * field will be passed to the function along with the `operator` and fields\n * for which the function returns `true` will be included.\n *\n * @group Option Lists\n */\nexport const filterFieldsByComparator = (\n  /** The field in question. */\n  field: FullField,\n  /** The full {@link FullField} list to be filtered. */\n  fields: OptionList<FullField>,\n  operator: string\n):\n  | FullField[]\n  | {\n      options: WithUnknownIndex<FullField>[];\n      label: string;\n    }[] => {\n  if (!field.comparator) {\n    const filterOutSameField = (f: FullField) =>\n      (f.value ?? /* v8 ignore start -- @preserve */ f.name) /* v8 ignore stop -- @preserve */ !==\n      (field.value ??\n        /* v8 ignore start -- @preserve */ field.name); /* v8 ignore stop -- @preserve */\n    if (isFlexibleOptionGroupArray(fields)) {\n      return fields.map(og => ({\n        ...og,\n        options: og.options.filter(v => filterOutSameField(v)),\n      }));\n    }\n    return fields.filter(v => filterOutSameField(v));\n  }\n\n  if (isFlexibleOptionGroupArray(fields)) {\n    return fields\n      .map(og => ({\n        ...og,\n        options: og.options.filter(f => filterByComparator(field, operator, f)),\n      }))\n      .filter(og => og.options.length > 0);\n  }\n\n  return fields.filter(f => filterByComparator(field, operator, f));\n};\n","import type {\n  Classname,\n  FlexibleOptionList,\n  FullCombinator,\n  FullOptionList,\n  FullField,\n  FullOperator,\n  FullOptionRecord,\n  InputType,\n  MatchModeOptions,\n  Option,\n  OptionList,\n  RuleGroupTypeAny,\n  RuleType,\n  ValidationMap,\n  ValidationResult,\n  ValueEditorType,\n  ValueSourceFullOptions,\n  ValueSources,\n} from '../types';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { isRuleGroupType, isRuleGroupTypeIC } from './isRuleGroup';\nimport { lc } from './misc';\nimport {\n  getFirstOption,\n  getOption,\n  isFlexibleOptionArray,\n  isFlexibleOptionGroupArray,\n  toFullOptionList,\n} from './optGroupUtils';\n\n/**\n * Functions used by {@link deriveRuleContext} to resolve a rule's configuration. Each corresponds\n * to the `QueryBuilder` prop (or `useQueryBuilderSetup` output) of the same name.\n */\nexport interface RuleContextResolvers<F extends FullField = FullField> {\n  fields: OptionList<F>;\n  fieldMap: Partial<FullOptionRecord<FullField>>;\n  getInputType: (field: string, operator: string, misc: { fieldData: F }) => InputType | null;\n  getMatchModes: (field: string, misc: { fieldData: F }) => MatchModeOptions;\n  getOperators: (field: string, misc: { fieldData: F }) => OptionList<FullOperator>;\n  getParameters: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => FlexibleOptionList<Option>;\n  getValueEditorType: (field: string, operator: string, misc: { fieldData: F }) => ValueEditorType;\n  getValues: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => FlexibleOptionList<Option>;\n  getValueSources: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => ValueSourceFullOptions;\n  getSubQueryBuilderProps?: (field: string, misc: { fieldData: F }) => Record<string, unknown>;\n}\n\n/**\n * Everything {@link deriveRuleContext} resolves for a single rule.\n */\nexport interface RuleContext<F extends FullField = FullField> {\n  fieldData: F;\n  hideValueControls: boolean;\n  inputType: InputType | null;\n  matchModes: MatchModeOptions;\n  operatorObject: FullOperator | undefined;\n  operators: OptionList<FullOperator>;\n  parameters: FlexibleOptionList<Option> | null;\n  validationResult: boolean | ValidationResult;\n  valueEditorType: ValueEditorType;\n  values: FlexibleOptionList<Option>;\n  valueSourceOptions: ValueSourceFullOptions;\n  valueSources: ValueSources;\n  subQueryBuilderProps: Record<string, unknown>;\n}\n\n/**\n * Resolves the field configuration for a rule's `field`, falling back to a minimal option object\n * when the field isn't present in the field map.\n */\nexport const getFieldData = (\n  field: string,\n  fieldMap: Partial<FullOptionRecord<FullField>>\n): FullField => fieldMap?.[field] ?? { name: field, value: field, label: field };\n\n/**\n * The input type for a rule. A field's own `inputType` takes precedence over `getInputType`.\n */\nexport const getRuleInputType = <F extends FullField = FullField>(\n  field: string,\n  operator: string,\n  fieldData: F,\n  getInputType: RuleContextResolvers<F>['getInputType']\n): InputType | null => fieldData.inputType ?? getInputType(field, operator, { fieldData });\n\n/**\n * Whether the value editor(s) should be hidden for an operator, based on its `arity`.\n */\nexport const hideValueControlsForOperator = (operatorObject?: FullOperator): boolean => {\n  const arity = operatorObject?.arity;\n  return (\n    (typeof arity === 'string' && arity === 'unary') || (typeof arity === 'number' && arity < 2)\n  );\n};\n\n/**\n * The subset of a rule that determines its configuration. Accepting only these properties (rather\n * than the whole rule) lets React callers keep granular memoization dependencies, so editing a\n * rule's `value` doesn't recompute its operators, value sources, or option lists.\n */\nexport type RuleFacet = Pick<RuleType, 'field' | 'operator' | 'valueSource'>;\n\n/**\n * Value source options for a rule. A `valueSource` present on the rule but absent from the\n * configured list is appended, so the current selection is always representable.\n */\nexport const getRuleValueSourceOptions = <F extends FullField = FullField>(\n  rule: RuleFacet,\n  fieldData: F,\n  getValueSources: RuleContextResolvers<F>['getValueSources']\n): ValueSourceFullOptions => {\n  const configuredVSs = getValueSources(rule.field, rule.operator, { fieldData });\n  if (rule.valueSource && !getOption(configuredVSs, rule.valueSource)) {\n    return [\n      ...configuredVSs,\n      { name: rule.valueSource, value: rule.valueSource, label: rule.valueSource },\n    ] as ValueSourceFullOptions;\n  }\n  return configuredVSs;\n};\n\n/**\n * Normalizes the result of `getParameters` to a non-empty list or `null`.\n */\nexport const getParametersAsList = (\n  parameters: FlexibleOptionList<Option>\n): FlexibleOptionList<Option> | null => (parameters && parameters.length > 0 ? parameters : null);\n\n/**\n * The value editor type for a rule. `valueSource: \"field\"` always uses a select list, and\n * `valueSource: \"parameter\"` uses a (multi)select when parameters are available.\n */\nexport const getRuleValueEditorType = <F extends FullField = FullField>(\n  rule: RuleFacet,\n  fieldData: F,\n  parametersAsList: FlexibleOptionList<Option> | null,\n  getValueEditorType: RuleContextResolvers<F>['getValueEditorType']\n): ValueEditorType =>\n  rule.valueSource === 'field'\n    ? 'select'\n    : rule.valueSource === 'parameter'\n      ? parametersAsList\n        ? lc(rule.operator) === 'in' || lc(rule.operator) === 'notin'\n          ? 'multiselect'\n          : 'select'\n        : 'text'\n      : getValueEditorType(rule.field, rule.operator, { fieldData });\n\n/**\n * The option list presented by a rule's value editor, resolved from its `valueSource`.\n */\nexport const getRuleValues = <F extends FullField = FullField>(\n  rule: RuleFacet,\n  fieldData: F,\n  fields: OptionList<F>,\n  parametersAsList: FlexibleOptionList<Option> | null,\n  getValues: RuleContextResolvers<F>['getValues']\n): FlexibleOptionList<Option> => {\n  const v =\n    rule.valueSource === 'field'\n      ? filterFieldsByComparator(fieldData, fields, rule.operator)\n      : rule.valueSource === 'parameter'\n        ? (parametersAsList ?? [])\n        : getValues(rule.field, rule.operator, { fieldData });\n  return isFlexibleOptionArray(v) || isFlexibleOptionGroupArray(v) ? toFullOptionList(v) : v;\n};\n\n/**\n * The validation result for a rule: the entry from a query-level {@link ValidationMap} if present,\n * otherwise the field's own `validator` result, otherwise `null`.\n */\nexport const getRuleValidationResult = (\n  rule: RuleType,\n  fieldData: FullField,\n  validationMap: ValidationMap = {},\n  id: string = rule.id ?? ''\n): boolean | ValidationResult =>\n  validationMap[id] ??\n  (typeof fieldData.validator === 'function' ? fieldData.validator(rule) : null);\n\n/**\n * Resolves everything about a single rule that depends on the field/operator configuration:\n * its field data, operators, value editor type, value list, value sources, match modes, and\n * validation result.\n *\n * This is the framework-agnostic core of the `useRule` hook, shared with\n * {@link QueryManager.getRuleContext} so that non-React implementations derive identical results.\n * It performs no memoization; callers are responsible for caching as appropriate.\n *\n * @group Query Tools\n */\nexport const deriveRuleContext = <F extends FullField = FullField>(\n  rule: RuleType,\n  resolvers: RuleContextResolvers<F>,\n  options: { validationMap?: ValidationMap; id?: string } = {}\n): RuleContext<F> => {\n  const {\n    fields,\n    fieldMap,\n    getInputType,\n    getMatchModes,\n    getOperators,\n    getParameters,\n    getValueEditorType,\n    getValues,\n    getValueSources,\n    getSubQueryBuilderProps,\n  } = resolvers;\n\n  const fieldData = getFieldData(rule.field, fieldMap) as F;\n  const inputType = fieldData.inputType ?? getInputType(rule.field, rule.operator, { fieldData });\n  const matchModes = getMatchModes(rule.field, { fieldData });\n  const operators = getOperators(rule.field, { fieldData });\n  const operatorObject = getOption(operators, rule.operator);\n  const valueSourceOptions = getRuleValueSourceOptions(rule, fieldData, getValueSources);\n  const parameters = getParametersAsList(getParameters(rule.field, rule.operator, { fieldData }));\n\n  return {\n    fieldData,\n    hideValueControls: hideValueControlsForOperator(operatorObject),\n    inputType,\n    matchModes,\n    operatorObject,\n    operators,\n    parameters,\n    validationResult: getRuleValidationResult(rule, fieldData, options.validationMap, options.id),\n    valueEditorType: getRuleValueEditorType(rule, fieldData, parameters, getValueEditorType),\n    values: getRuleValues(rule, fieldData, fields, parameters, getValues),\n    valueSourceOptions,\n    valueSources: valueSourceOptions.map(({ value }) => value) as ValueSources,\n    subQueryBuilderProps: getSubQueryBuilderProps?.(rule.field, { fieldData }) ?? {},\n  };\n};\n\n/**\n * Everything {@link deriveRuleGroupContext} resolves for a single rule group.\n */\nexport interface RuleGroupContext<C extends FullCombinator = FullCombinator> {\n  combinator: string;\n  combinatorObject: C | undefined;\n  combinators: FullOptionList<C>;\n  /** The `className` of the selected combinator, or `null` for independent combinators. */\n  combinatorBasedClassName: Classname | null;\n  independentCombinators: boolean;\n  validationResult: boolean | ValidationResult;\n}\n\n/**\n * The effective combinator for a group: its own `combinator` when it has one, otherwise the\n * first configured combinator (which is the case for groups with independent combinators).\n *\n * This intentionally covers only the current property-based API. The `RuleGroup` component\n * additionally falls back to its deprecated `combinator` prop; that fallback stays in the hook.\n */\nexport const getRuleGroupCombinator = <C extends FullCombinator = FullCombinator>(\n  ruleGroup: RuleGroupTypeAny,\n  combinators: FullOptionList<C>\n): string =>\n  isRuleGroupType(ruleGroup) ? ruleGroup.combinator : (getFirstOption(combinators) ?? '');\n\n/**\n * Resolves everything about a rule group that depends on the combinator configuration, plus its\n * validation result.\n *\n * Note that unlike {@link deriveRuleContext}, there is no field-level validator fallback—a\n * group's validation result comes only from the query-level {@link ValidationMap}.\n *\n * @group Query Tools\n */\nexport const deriveRuleGroupContext = <C extends FullCombinator = FullCombinator>(\n  ruleGroup: RuleGroupTypeAny,\n  combinators: FullOptionList<C>,\n  options: { validationMap?: ValidationMap; id?: string } = {}\n): RuleGroupContext<C> => {\n  const independentCombinators = isRuleGroupTypeIC(ruleGroup);\n  const combinator = getRuleGroupCombinator(ruleGroup, combinators);\n  const combinatorObject = getOption(combinators, combinator);\n\n  return {\n    combinator,\n    combinatorObject,\n    combinators,\n    combinatorBasedClassName: independentCombinators ? null : (combinatorObject?.className ?? ''),\n    independentCombinators,\n    validationResult: (options.validationMap ?? {})[options.id ?? ruleGroup.id ?? ''] ?? null,\n  };\n};\n","import { numericQuantity } from 'numeric-quantity';\nimport type { ParseNumberMethod } from '../types';\n\n/**\n * Options object for {@link parseNumber}.\n */\nexport interface ParseNumberOptions {\n  parseNumbers?: ParseNumberMethod;\n  /**\n   * Generates a `bigint` value if the string represents a valid integer\n   * outside the safe boundaries of the `number` type.\n   */\n  bigIntOnOverflow?: boolean;\n}\n\n/**\n * Converts a string to a number. Uses native `parseFloat` if `parseNumbers` is \"native\",\n * otherwise uses [`numeric-quantity`](https://jakeboone02.github.io/numeric-quantity/).\n * If that returns `NaN`, the string is returned unchanged. Numeric values are returned\n * as-is regardless of the `parseNumbers` option.\n */\nexport const parseNumber = (\n  val: unknown,\n  { parseNumbers, bigIntOnOverflow }: ParseNumberOptions = {}\n  // oxlint-disable-next-line typescript/no-explicit-any\n): any => {\n  if (!parseNumbers || typeof val === 'bigint' || typeof val === 'number') {\n    return val;\n  }\n\n  if (parseNumbers === 'native') {\n    return Number.parseFloat(val as string);\n  }\n\n  const valAsNum: number | bigint =\n    // TODO?: Make these options configurable\n    numericQuantity(val, {\n      allowTrailingInvalid: parseNumbers === 'enhanced',\n      bigIntOnOverflow,\n      romanNumerals: false,\n      round: false,\n    });\n\n  return typeof valAsNum === 'bigint' || !Number.isNaN(valAsNum) ? valAsNum : val;\n};\n","import type { InputType, ParseNumberMethod } from '../types';\nimport { joinWith, toArray } from './arrayUtils';\nimport { getFirstOption } from './optGroupUtils';\nimport { parseNumber } from './parseNumber';\n\n/** Operators whose value is a list rather than a single scalar. */\nconst multiValueOperators = new Set(['between', 'notBetween', 'in', 'notIn']);\n\n/**\n * Whether an operator's value is a list of two bounds.\n *\n * @group Value Editors\n */\nexport const isBetweenOperator = (operator: string): boolean =>\n  operator === 'between' || operator === 'notBetween';\n\n/**\n * Determines whether a rule's `value` needs to be collapsed to a single element because it no\n * longer represents a list, and what it should become.\n *\n * This happens when the value is an array (or a comma-containing string in a `number` input,\n * which `<input type=\"number\">` can't display) while the operator is not one of the multi-value\n * operators and the editor is not a multiselect—typically right after the operator changes from\n * `\"in\"` or `\"between\"` to something else.\n *\n * The React `useValueEditor` hook applies the result in an effect; other implementations may\n * apply it wherever is idiomatic.\n *\n * @group Value Editors\n */\nexport const getValueEditorReset = ({\n  skipHook,\n  type,\n  operator,\n  value,\n  inputType,\n}: {\n  skipHook?: boolean;\n  type?: string;\n  operator: string;\n  value: unknown;\n  inputType?: InputType | null;\n}): { reset: boolean; value: unknown } => {\n  const reset =\n    !skipHook &&\n    type !== 'multiselect' &&\n    !multiValueOperators.has(operator) &&\n    (Array.isArray(value) ||\n      (inputType === 'number' && typeof value === 'string' && value.includes(',')));\n\n  return reset\n    ? { reset: true, value: toArray(value, { retainEmptyStrings: true })[0] ?? '' }\n    : { reset: false, value };\n};\n\n/**\n * Produces the next value for a series of value editors when the editor at `index` changes.\n *\n * For `between`/`notBetween`, editing the first bound guarantees an array of at least two\n * elements, seeding the second from the first available option. The result is a comma-joined\n * string unless `listsAsArrays` is `true`.\n *\n * @group Value Editors\n */\nexport const getMultiValueUpdate = ({\n  value,\n  index,\n  valueAsArray,\n  operator,\n  values,\n  listsAsArrays,\n  parseNumberMethod,\n}: {\n  value: unknown;\n  index: number;\n  valueAsArray: unknown[];\n  operator: string;\n  // Matches the `values` prop on value editors, which is loosely typed by design.\n  // oxlint-disable-next-line typescript/no-explicit-any\n  values?: any[];\n  listsAsArrays?: boolean;\n  parseNumberMethod?: ParseNumberMethod;\n}): unknown => {\n  const parsedVal = parseNumber(value, { parseNumbers: parseNumberMethod });\n  const needsBetweenFix =\n    index === 0 &&\n    isBetweenOperator(operator) &&\n    (valueAsArray.length < 2 || valueAsArray[1] === undefined);\n\n  // Unchanged at this index and no bounds to backfill: hand back the array as-is.\n  if (valueAsArray[index] === parsedVal && !needsBetweenFix) {\n    return listsAsArrays ? valueAsArray : joinWith(valueAsArray, ',');\n  }\n\n  const v = [...valueAsArray];\n  v[index] = parsedVal;\n  if (needsBetweenFix) {\n    // `values` may be absent or empty (a plain text editor, for example), in which case the\n    // second bound is seeded with an empty string rather than `undefined`.\n    v[1] = getFirstOption(values) ?? '';\n  }\n\n  return listsAsArrays ? v : joinWith(v, ',');\n};\n\n/**\n * Coerces a value to a `bigint`, falling back to the parsed number when it can't be represented\n * as one (an empty string or a decimal, for example).\n *\n * @group Value Editors\n */\nexport const coerceBigIntValue = (\n  value: unknown,\n  parseNumberMethod?: ParseNumberMethod\n): unknown => {\n  const valAsMaybeNumber = parseNumber(value, {\n    parseNumbers: parseNumberMethod,\n    bigIntOnOverflow: true,\n  });\n\n  try {\n    return BigInt(valAsMaybeNumber as string | number | bigint);\n  } catch {\n    return valAsMaybeNumber;\n  }\n};\n\n/**\n * The `type` attribute an `<input>` should use for a rule. `bigint` values and the `in`/`notIn`\n * operators (whose value is a comma-separated list) both require a text input.\n *\n * @group Value Editors\n */\nexport const coerceInputType = (\n  inputType: InputType | null | undefined,\n  operator: string\n): InputType =>\n  inputType === 'bigint' || operator === 'in' || operator === 'notIn'\n    ? 'text'\n    : inputType || 'text';\n\n/**\n * Produces the next value for a value selector. Multiselect values are normalized to an array\n * first, then comma-joined unless `listsAsArrays` is `true`. Single-select values pass through.\n *\n * @group Value Editors\n */\nexport const getValueSelectorUpdate = (\n  value: string | string[],\n  { multiple, listsAsArrays }: { multiple?: boolean; listsAsArrays?: boolean } = {}\n): string | string[] => {\n  if (!multiple) return value;\n\n  const valueAsArray = toArray(value);\n  return listsAsArrays ? valueAsArray : joinWith(valueAsArray, ',');\n};\n\n/**\n * Normalizes a value selector's current value for display. Multiselect values become an array of\n * strings so they match option names, which are always strings (e.g. `[42]` becomes `[\"42\"]`).\n *\n * @group Value Editors\n */\nexport const normalizeValueSelectorValue = (\n  value: unknown,\n  multiple?: boolean\n  // oxlint-disable-next-line typescript/no-explicit-any\n): any => (multiple ? toArray(value).map(String) : value);\n","/**\n * Recursively steps through a query object ({@link index!RuleGroupType RuleGroupType} or {@link index!RuleGroupTypeIC RuleGroupTypeIC}),\n * passing each {@link index!RuleType RuleType} object to a provided `ruleProcessor` function and returning a\n * new query object if there were any referential changes.\n *\n * @module transformQuery\n */\n\nimport type { RuleGroupType, RuleGroupTypeAny, RuleGroupTypeIC, RuleType } from '../types';\nimport { isRuleGroup, isRuleGroupType } from './isRuleGroup';\nimport { isUnsafeKey } from './objectUtils';\n\nconst remapProperties = (\n  obj: Record<string, unknown>,\n  propertyMap: Record<string, string | false>,\n  deleteRemappedProperties: boolean\n): Record<string, unknown> => {\n  const result: Record<string, unknown> = {};\n\n  for (const key in obj) {\n    if (isUnsafeKey(key)) continue;\n    const mappedKey = propertyMap[key];\n    if (mappedKey === false) {\n      continue;\n    }\n    if (mappedKey && key !== mappedKey) {\n      if (!isUnsafeKey(mappedKey)) {\n        result[mappedKey] = obj[key];\n      }\n      if (!deleteRemappedProperties) {\n        result[key] = obj[key];\n      }\n    } else {\n      result[key] = obj[key];\n    }\n  }\n\n  return result;\n};\n\n/**\n * Options object for {@link index!transformQuery transformQuery}.\n */\nexport interface TransformQueryOptions<RG extends RuleGroupTypeAny = RuleGroupType> {\n  /**\n   * When a rule is encountered in the hierarchy, it will be replaced\n   * with the result of this function.\n   *\n   * @defaultValue `r => r`\n   */\n  // oxlint-disable-next-line typescript/no-explicit-any\n  ruleProcessor?: (rule: RuleType) => any;\n  /**\n   * When a group is encountered in the hierarchy (including the root group, the\n   * query itself), it will be replaced with the result of this function.\n   *\n   * @defaultValue `rg => rg`\n   */\n  // oxlint-disable-next-line typescript/no-explicit-any\n  ruleGroupProcessor?: (ruleGroup: RG) => Record<string, any>;\n  /**\n   * For each rule and group in the query, any properties matching a key\n   * in this object will be renamed to the corresponding value. To retain both\n   * the new _and_ the original properties, set `deleteRemappedProperties`\n   * to `false`.\n   *\n   * If a key has a value of `false`, the corresponding property will be removed\n   * without being copied to a new property name. (Warning: `{ rules: false }`\n   * will prevent recursion and only return the processed root group.)\n   *\n   * @defaultValue `{}`\n   *\n   * @example\n   * ```\n   *   transformQuery(\n   *     { combinator: 'and', not: true, rules: [] },\n   *     { propertyMap: { combinator: 'AndOr', not: false } }\n   *   )\n   *   // Returns: { AndOr: 'and', rules: [] }\n   * ```\n   */\n  propertyMap?: Record<string, string | false>;\n  /**\n   * Any combinator values (including independent combinators) will be translated\n   * from the key in this object to the value.\n   *\n   * @defaultValue `{}`\n   *\n   * @example\n   * ```\n   *   transformQuery(\n   *     { combinator: 'and', rules: [] },\n   *     { combinatorMap: { and: '&&', or: '||' } }\n   *   )\n   *   // Returns: { combinator: '&&', rules: [] }\n   * ```\n   */\n  combinatorMap?: Record<string, string>;\n  /**\n   * Any operator values will be translated from the key in this object to the value.\n   *\n   * @defaultValue `{}`\n   *\n   * @example\n   * ```\n   *   transformQuery(\n   *     { combinator: 'and', rules: [{ field: 'name', operator: '=', value: 'Steve Vai' }] },\n   *     { operatorMap: { '=': 'is' } }\n   *   )\n   *   // Returns:\n   *   // {\n   *   //   combinator: 'and',\n   *   //   rules: [{ field: 'name', operator: 'is', value: 'Steve Vai' }]\n   *   // }\n   * ```\n   */\n  operatorMap?: Record<string, string>;\n  /**\n   * Prevents the `path` property (see {@link index!Path Path}) from being added to each\n   * rule and group in the hierarchy.\n   *\n   * @defaultValue `false`\n   */\n  omitPath?: boolean;\n  /**\n   * Original properties remapped according to the `propertyMap` option will be removed.\n   *\n   * @defaultValue `true`\n   *\n   * @example\n   * ```\n   *   transformQuery(\n   *     { combinator: 'and', rules: [] },\n   *     { propertyMap: { combinator: 'AndOr' }, deleteRemappedProperties: false }\n   *   )\n   *   // Returns: { combinator: 'and', AndOr: 'and', rules: [] }\n   * ```\n   */\n  deleteRemappedProperties?: boolean;\n}\n\n/**\n * Recursively process a query heirarchy using this versatile utility function.\n *\n * [Documentation](https://react-querybuilder.js.org/docs/utils/misc#transformquery)\n */\nexport function transformQuery(\n  query: RuleGroupType,\n  options?: TransformQueryOptions\n  // oxlint-disable-next-line typescript/no-explicit-any\n): any;\n/**\n * Recursively process a query heirarchy with independent combinators using this\n * versatile utility function.\n *\n * [Documentation](https://react-querybuilder.js.org/docs/utils/misc#transformquery)\n */\nexport function transformQuery(\n  query: RuleGroupTypeIC,\n  options?: TransformQueryOptions<RuleGroupTypeIC>\n  // oxlint-disable-next-line typescript/no-explicit-any\n): any;\nexport function transformQuery<RG extends RuleGroupTypeAny>(\n  query: RG,\n  options: TransformQueryOptions<RG> = {}\n) {\n  const {\n    ruleProcessor = r => r,\n    ruleGroupProcessor = rg => rg,\n    propertyMap = {},\n    combinatorMap = {},\n    operatorMap = {},\n    omitPath = false,\n    deleteRemappedProperties = true,\n  } = options;\n\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const processGroup = (rg: RuleGroupTypeAny): any => ({\n    ...ruleGroupProcessor(\n      remapProperties(\n        {\n          ...rg,\n          ...(isRuleGroupType(rg)\n            ? { combinator: combinatorMap[rg.combinator] ?? rg.combinator }\n            : {}),\n        },\n        propertyMap,\n        deleteRemappedProperties\n      ) as RG\n    ),\n    ...(propertyMap['rules'] === false\n      ? null\n      : {\n          // oxlint-disable-next-line typescript/no-explicit-any\n          [propertyMap['rules'] ?? 'rules']: rg.rules.map((r: any, idx) => {\n            const pathObject = omitPath ? null : { path: [...rg.path!, idx] };\n            if (typeof r === 'string') {\n              // independent combinators\n              return combinatorMap[r] ?? r;\n            } else if (isRuleGroup(r)) {\n              // sub-groups\n              return processGroup({ ...r, ...pathObject });\n            }\n            // rules\n            return ruleProcessor(\n              remapProperties(\n                {\n                  ...r,\n                  ...pathObject,\n                  ...('operator' in r ? { operator: operatorMap[r.operator] ?? r.operator } : {}),\n                },\n                propertyMap,\n                deleteRemappedProperties\n              ) as unknown as RuleType\n            );\n          }),\n        }),\n  });\n\n  return processGroup({ ...query, ...(omitPath ? null : { path: [] }) });\n}\n","import type { RuleGroupTypeAny, RuleType, RuleValidator, ValidationResult } from '../types';\nimport { isRuleGroup } from './isRuleGroup';\nimport { isPojo } from './misc';\n\n/**\n * Determines if an object is useful as a validation result.\n */\nexport const isValidationResult = (vr?: ValidationResult): vr is ValidationResult =>\n  isPojo(vr) && typeof vr.valid === 'boolean';\n\n/**\n * Determines if a rule or group is valid based on a validation result (if defined)\n * or a validator function. Returns `true` if neither are defined and the `muted`\n * property is not `true`.\n */\nexport const isRuleOrGroupValid = (\n  rg: RuleType | RuleGroupTypeAny,\n  validationResult?: boolean | ValidationResult,\n  validator?: RuleValidator\n): boolean => {\n  if (rg.muted) {\n    return false;\n  }\n  if (typeof validationResult === 'boolean') {\n    return validationResult;\n  }\n  if (isValidationResult(validationResult)) {\n    return validationResult.valid;\n  }\n  if (typeof validator === 'function' && !isRuleGroup(rg)) {\n    const vr = validator(rg);\n    if (typeof vr === 'boolean') {\n      return vr;\n    }\n    // v8 ignore else\n    if (isValidationResult(vr)) {\n      return vr.valid;\n    }\n  }\n  return true;\n};\n","import type { InputType, ParseNumberMethod, ParseNumbersPropConfig } from '../types';\n\nexport const getParseNumberMethod = ({\n  parseNumbers,\n  inputType,\n}: {\n  parseNumbers?: ParseNumbersPropConfig;\n  inputType?: InputType | null;\n}): ParseNumberMethod => {\n  if (typeof parseNumbers === 'string') {\n    const [method, level] = parseNumbers.split('-') as\n      | [ParseNumberMethod, 'limited']\n      | [ParseNumberMethod];\n    if (level === 'limited') {\n      return inputType === 'number' ? method : false;\n    }\n\n    return method;\n  }\n\n  return parseNumbers ? 'strict' : false;\n};\n","import type { SetRequired } from 'type-fest';\nimport type {\n  ConstituentWordOrder,\n  DefaultCombinatorName,\n  FormatQueryOptions,\n  FullField,\n  GroupVariantCondition,\n  MatchMode,\n  NLTranslationKey,\n  NLTranslations,\n  OptionList,\n  RuleGroupTypeAny,\n  RuleType,\n  ValueProcessorByRule,\n  ValueProcessorLegacy,\n  ValueProcessorOptions,\n} from '../../types';\nimport { joinWith, splitBy, toArray } from '../arrayUtils';\nimport { getParseNumberMethod } from '../getParseNumberMethod';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isPojo, lc, numericRegex } from '../misc';\nimport { getOption } from '../optGroupUtils';\nimport { parseNumber } from '../parseNumber';\n\n/**\n * Maps a {@link DefaultOperatorName} to a SQL operator.\n *\n * @group Export\n */\nexport const mapSQLOperator = (rqbOperator: string): string => {\n  switch (lc(rqbOperator)) {\n    case 'null':\n      return 'is null';\n    case 'notnull':\n      return 'is not null';\n    case 'notin':\n      return 'not in';\n    case 'notbetween':\n      return 'not between';\n    case 'contains':\n    case 'beginswith':\n    case 'endswith':\n      return 'like';\n    case 'doesnotcontain':\n    case 'doesnotbeginwith':\n    case 'doesnotendwith':\n      return 'not like';\n    default:\n      return rqbOperator;\n  }\n};\n\n/**\n * Returns a preset-aware SQL string-concatenation function. Emits `CONCAT(a, b, ...)` when\n * `concatOperator` is `\"CONCAT\"` (case-insensitive), otherwise joins with the infix operator\n * (e.g. `a || b`, `a + b`).\n *\n * @group Export\n */\nexport const getSQLConcat =\n  (concatOperator = '||') =>\n  (...values: string[]): string =>\n    concatOperator.toUpperCase() === 'CONCAT'\n      ? `CONCAT(${values.join(', ')})`\n      : values.join(` ${concatOperator} `);\n\n/**\n * Returns the `[prefix, suffix]` `LIKE` wildcards for a string-match operator (e.g. `contains`\n * → `['%', '%']`, `beginsWith` → `['', '%']`, `endsWith` → `['%', '']`). Unknown operators\n * yield `['', '']`.\n *\n * @group Export\n */\nexport const getLikeWildcards = (operatorLC: string): [string, string] => {\n  switch (operatorLC) {\n    case 'contains':\n    case 'doesnotcontain':\n      return ['%', '%'];\n    case 'beginswith':\n    case 'doesnotbeginwith':\n      return ['', '%'];\n    case 'endswith':\n    case 'doesnotendwith':\n      return ['%', ''];\n    default:\n      return ['', ''];\n  }\n};\n\n/**\n * Wraps an already-serialized SQL fragment (a quoted field name or an expression) with the\n * `LIKE` wildcards for the given (lowercase) string-match operator, concatenating the literal\n * `%` markers via the preset-aware {@link getSQLConcat}. Returns the fragment untouched for\n * operators without wildcards.\n *\n * @group Export\n */\nexport const wrapLikeFragment = (\n  fragment: string,\n  operatorLC: string,\n  {\n    concatOperator = '||',\n    quoteValuesWith,\n    wrapValueWith = ['', ''],\n  }: {\n    concatOperator?: string;\n    quoteValuesWith?: string;\n    wrapValueWith?: [string, string];\n  } = {}\n): string => {\n  const [pre, post] = getLikeWildcards(operatorLC);\n  const quoteChar = quoteValuesWith || `'`;\n  const quote = (p: string) => `${wrapValueWith[0]}${quoteChar}${p}${quoteChar}${wrapValueWith[1]}`;\n  const parts = [pre && quote(pre), fragment, post && quote(post)].filter(Boolean);\n  return parts.length > 1 ? getSQLConcat(concatOperator)(...parts) : fragment;\n};\n\n/**\n * Maps a (lowercase) {@link DefaultOperatorName} to a MongoDB operator.\n *\n * @group Export\n */\nexport const mongoOperators = {\n  '=': '$eq',\n  '!=': '$ne',\n  '<': '$lt',\n  '<=': '$lte',\n  '>': '$gt',\n  '>=': '$gte',\n  in: '$in',\n  notin: '$nin',\n  notIn: '$nin', // only here for backwards compatibility\n};\n\n/**\n * Maps a (lowercase) {@link DefaultOperatorName} to a Prisma ORM operator.\n *\n * @group Export\n */\nexport const prismaOperators = {\n  '=': 'equals',\n  '!=': 'not',\n  '<': 'lt',\n  '<=': 'lte',\n  '>': 'gt',\n  '>=': 'gte',\n  in: 'in',\n  notin: 'notIn',\n};\n\n/**\n * Maps a {@link DefaultCombinatorName} to a CEL combinator.\n *\n * @group Export\n */\nexport const celCombinatorMap: {\n  and: '&&';\n  or: '||';\n} = {\n  and: '&&',\n  or: '||',\n} satisfies Record<DefaultCombinatorName, '&&' | '||'>;\n\n/**\n * Register these operators with `jsonLogic` before applying the result\n * of `formatQuery(query, 'jsonlogic')`.\n *\n * @example\n * ```\n * for (const [op, func] of Object.entries(jsonLogicAdditionalOperators)) {\n *   jsonLogic.add_operation(op, func);\n * }\n * jsonLogic.apply({ \"startsWith\": [{ \"var\": \"firstName\" }, \"Stev\"] }, data);\n * ```\n *\n * @group Export\n */\nexport const jsonLogicAdditionalOperators: Record<\n  'startsWith' | 'endsWith',\n  (a: string, b: string) => boolean\n> = {\n  startsWith: (a: string, b: string) => typeof a === 'string' && a.startsWith(b),\n  endsWith: (a: string, b: string) => typeof a === 'string' && a.endsWith(b),\n};\n\n/**\n * Returns a new query object with all `string`-type `value` properties converted\n * to `number` where appropriate.\n *\n * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.\n *\n * @group Export\n */\nexport const numerifyValues = (\n  rg: RuleGroupTypeAny,\n  options: SetRequired<FormatQueryOptions, 'fields'>\n): RuleGroupTypeAny => ({\n  ...rg,\n  // @ts-expect-error TS doesn't keep track of odd/even indexes here\n  rules: rg.rules.map(r => {\n    if (typeof r === 'string') {\n      return r;\n    }\n\n    if (isRuleGroup(r)) {\n      return numerifyValues(r, options);\n    }\n\n    const fieldData = getOption(options.fields as OptionList<FullField>, r.field);\n    const parseNumbers = getParseNumberMethod({\n      parseNumbers: options.parseNumbers,\n      inputType: fieldData?.inputType,\n    });\n\n    if (Array.isArray(r.value)) {\n      return { ...r, value: r.value.map(v => parseNumber(v, { parseNumbers })) };\n    }\n\n    const valAsArray = toArray(r.value, { retainEmptyStrings: true }).map(v =>\n      parseNumber(v, { parseNumbers })\n    );\n    if (valAsArray.every(v => typeof v === 'number')) {\n      // v8 ignore else\n      if (valAsArray.length > 1) {\n        return { ...r, value: valAsArray };\n      } else if (valAsArray.length === 1) {\n        return { ...r, value: valAsArray[0] };\n      }\n    }\n\n    return r;\n  }),\n});\n\n/**\n * Determines whether a value is _anything_ except an empty `string` or `NaN`.\n *\n * @group Export\n */\nexport const isValidValue = (value: unknown): boolean =>\n  (typeof value === 'string' && value.length > 0) ||\n  (typeof value === 'number' && !Number.isNaN(value)) ||\n  (typeof value !== 'string' && typeof value !== 'number');\n\n/**\n * Determines whether {@link formatQuery} should render the given value as a number.\n * As long as `parseNumbers` is `true`, `number` and `bigint` values will return `true` and\n * `string` values will return `true` if they test positive against {@link numericRegex}.\n *\n * @group Export\n */\nexport const shouldRenderAsNumber = (value: unknown, parseNumbers?: boolean): boolean =>\n  !!parseNumbers &&\n  (typeof value === 'number' ||\n    typeof value === 'bigint' ||\n    (typeof value === 'string' && numericRegex.test(value)));\n\n/**\n * Used by {@link formatQuery} to determine whether the given value processor is a\n * \"legacy\" value processor by counting the number of arguments. Legacy value\n * processors take 3 arguments (not counting any arguments with default values), while\n * rule-based value processors take no more than 2 arguments.\n *\n * @group Export\n */\nexport const isValueProcessorLegacy = (\n  valueProcessor: ValueProcessorLegacy | ValueProcessorByRule\n): valueProcessor is ValueProcessorLegacy => valueProcessor.length >= 3;\n\n/**\n * Converts the `quoteFieldNamesWith` option into an array of two strings.\n * If the option is a string, the array elements are both that string.\n *\n * @default\n * ['', '']\n *\n * @group Export\n */\nexport const getQuoteFieldNamesWithArray = (\n  // v8 ignore next\n  quoteFieldNamesWith: null | string | [string, string] = ['', '']\n): [string, string] =>\n  Array.isArray(quoteFieldNamesWith)\n    ? quoteFieldNamesWith\n    : typeof quoteFieldNamesWith === 'string'\n      ? [quoteFieldNamesWith, quoteFieldNamesWith]\n      : (quoteFieldNamesWith ?? ['', '']);\n\n/**\n * Given a field name and relevant {@link ValueProcessorOptions}, returns the field name\n * wrapped in the configured quote character(s).\n *\n * @group Export\n */\nexport const getQuotedFieldName = (\n  fieldName: string,\n  { quoteFieldNamesWith, fieldIdentifierSeparator }: ValueProcessorOptions\n): string => {\n  const [qPre, qPost] = getQuoteFieldNamesWithArray(quoteFieldNamesWith);\n  return typeof fieldIdentifierSeparator === 'string' && fieldIdentifierSeparator.length > 0\n    ? joinWith(\n        splitBy(fieldName, fieldIdentifierSeparator).map(part => `${qPre}${part}${qPost}`),\n        fieldIdentifierSeparator\n      )\n    : `${qPre}${fieldName}${qPost}`;\n};\n\nconst defaultWordOrder = ['S', 'V', 'O'];\n\n/**\n * Given a [Constituent word order](https://en.wikipedia.org/wiki/Word_order#Constituent_word_orders)\n * like \"svo\" or \"sov\", returns a permutation of `[\"S\", \"V\", \"O\"]` based on the first occurrence of\n * each letter in the input string (case insensitive). This widens the valid input from abbreviations\n * like \"svo\" to more expressive strings like \"subject-verb-object\" or \"sub ver obj\". Any missing\n * letters are appended in the default order \"SVO\" (e.g., \"object\" would yield `[\"O\", \"S\", \"V\"]`).\n *\n * @group Export\n */\nexport const normalizeConstituentWordOrder = (input: string): ConstituentWordOrder => {\n  const result: string[] = [];\n  const letterSet = new Set(defaultWordOrder);\n\n  for (const char of input.toUpperCase()) {\n    if (letterSet.has(char)) {\n      result.push(char);\n      letterSet.delete(char);\n      if (letterSet.size === 0) break;\n    }\n  }\n\n  // Add any missing letters in default order\n  for (const letter of defaultWordOrder) {\n    if (letterSet.has(letter)) {\n      result.push(letter);\n    }\n  }\n\n  return result as ConstituentWordOrder;\n};\n\n/**\n * Prefixes a named-parameter value with the given `paramPrefix` unless the value already\n * begins with it. Used by {@link formatQuery} to render rules whose `valueSource` is\n * `\"parameter\"` (e.g. `\"p1\"` with prefix `\":\"` → `\":p1\"`; `\":p1\"` → `\":p1\"`).\n *\n * @group Export\n */\nexport const withParamPrefix = (value: unknown, paramPrefix = ':'): string => {\n  const v = `${value ?? ''}`;\n  return paramPrefix && v.startsWith(paramPrefix) ? v : `${paramPrefix}${v}`;\n};\n\n/**\n * Strips a leading `paramPrefix` from a named-parameter value if present. Inverse of\n * {@link withParamPrefix}; used to normalize parameter names for validation/lookup.\n *\n * @group Export\n */\nexport const stripParamPrefix = (value: unknown, paramPrefix = ':'): string => {\n  const v = `${value ?? ''}`;\n  return paramPrefix && v.startsWith(paramPrefix) ? v.slice(paramPrefix.length) : v;\n};\n\n/**\n * Default translations used by {@link formatQuery} for \"natural_language\" format.\n *\n * @group Export\n */\n// The ones commented below are unnecessary for the default implementation,\n// but they can be overridden for customized implementations.\nexport const defaultNLTranslations: NLTranslations = {\n  // and: 'and',\n  // or: 'or',\n  // true: 'true',\n  // false: 'false',\n  groupPrefix: '',\n  // groupPrefix_not: '',\n  groupPrefix_not_xor: 'either zero or more than one of',\n  groupPrefix_xor: 'exactly one of',\n  groupSuffix: 'is true',\n  groupSuffix_not: 'is not true',\n  // groupSuffix_not_xor: 'is true',\n  // groupSuffix_xor: 'is true',\n};\n\n/**\n * Note: This function assumes `conditions.length > 0`\n */\nconst translationMatchFilter = (\n  key: NLTranslationKey,\n  keyToTest: string,\n  conditions: GroupVariantCondition[]\n) =>\n  // The translation matches the base key\n  keyToTest.startsWith(key) &&\n  // The translation specifies all conditions\n  conditions.every(\n    c =>\n      // This translation specifies _this_ condition\n      keyToTest.includes(`_${c}`) &&\n      // This translation specifies the same _total number_ of conditions\n      keyToTest.match(/_/g)?.length === conditions.length\n  );\n\n/**\n * Used by {@link formatQuery} to get a translation based on certain conditions\n * for the \"natural_language\" format.\n *\n * @group Export\n */\nexport const getNLTranslataion = (\n  key: NLTranslationKey,\n  translations: NLTranslations,\n  conditions: GroupVariantCondition[] = []\n): string =>\n  conditions.length === 0\n    ? (translations[key] ??\n      defaultNLTranslations[key] ??\n      /* v8 ignore start -- @preserve */ '') /* v8 ignore stop -- @preserve */\n    : (Object.entries(translations).find(([keyToTest]) =>\n        translationMatchFilter(key, keyToTest, conditions)\n      )?.[1] ??\n      Object.entries(defaultNLTranslations).find(([keyToTest]) =>\n        translationMatchFilter(key, keyToTest, conditions)\n      )?.[1] ??\n      defaultNLTranslations[key] ??\n      /* v8 ignore next -- @preserve */ '');\n\ntype ProcessedMatchMode =\n  | { mode: 'all'; threshold?: number | null | undefined }\n  | { mode: 'none'; threshold?: number | null | undefined }\n  | { mode: 'some'; threshold?: number | null | undefined }\n  | { mode: 'atleast'; threshold: number }\n  | { mode: 'atmost'; threshold: number }\n  | { mode: 'exactly'; threshold: number };\n\n/**\n * Transforms\n * - `match: { mode: \"atLeast\", threshold: 1 }` to `match: { mode: \"some\" }`\n * - `match: { mode: \"atMost\", threshold: 0 }` to `match: { mode: \"none\" }`.\n *\n * Returns:\n * - Processed `{ mode, threshold }` object for valid subqueries\n * - `null` if match mode is not applicable for the rule\n * - `false` if match mode is valid, but either\n *   1. `threshold` is required and invalid, or\n *   2. `value` is not a valid rule group.\n */\nexport const processMatchMode = (rule: RuleType): null | false | ProcessedMatchMode => {\n  const { mode, threshold } = rule.match ?? {};\n\n  if (!mode) return null;\n\n  if (!isRuleGroup(rule.value)) return false;\n\n  const matchModeLC = lc(mode) as Lowercase<MatchMode>;\n\n  const matchModeCoerced =\n    matchModeLC === 'atleast' && threshold === 1\n      ? 'some'\n      : matchModeLC === 'atmost' && threshold === 0\n        ? 'none'\n        : matchModeLC;\n\n  if (\n    (matchModeCoerced === 'atleast' ||\n      matchModeCoerced === 'atmost' ||\n      matchModeCoerced === 'exactly') &&\n    (typeof threshold !== 'number' || threshold < 0)\n  ) {\n    return false;\n  }\n\n  return { mode: matchModeCoerced, threshold: threshold! };\n};\n\n/**\n * Base alias assigned to the element binding of a subquery generated for a rule's\n * {@link MatchMode `match` mode} (e.g. `unnest(field) as elem_alias`).\n */\nexport const subqueryElementAliasBase = 'elem_alias';\n\n/**\n * Returns the element alias for a subquery at the given nesting depth. Depth 0 (the common,\n * non-nested case) uses {@link subqueryElementAliasBase} unchanged; deeper levels are suffixed\n * with the depth, so a subquery nested within a subquery cannot shadow its parent's binding.\n *\n * Deterministic by depth rather than randomized, so output remains stable and snapshot-friendly.\n *\n * @group Export\n */\nexport const getSubqueryElementAlias = (subqueryDepth = 0): string =>\n  subqueryDepth > 0 ? `${subqueryElementAliasBase}_${subqueryDepth}` : subqueryElementAliasBase;\n\n/**\n * \"Replacer\" method for JSON.stringify's second argument. Converts `bigint` values to\n * objects with a `$bigint` property having a value of a string representation of\n * the actual `bigint`-type value.\n *\n * Inverse of {@link bigIntJsonParseReviver}.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json\n */\nexport const bigIntJsonStringifyReplacer = (_key: string, value: unknown): unknown =>\n  typeof value === 'bigint' ? { $bigint: value.toString() } : value;\n\n/**\n * \"Reviver\" method for JSON.parse's second argument. Converts objects having a single\n * `$bigint: string` property to an actual `bigint` value.\n *\n * Inverse of {@link bigIntJsonStringifyReplacer}.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json\n */\nexport const bigIntJsonParseReviver = (_key: string, value: unknown): unknown =>\n  isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === 'string'\n    ? BigInt(value.$bigint)\n    : value;\n","import type { DefaultCombinatorName, RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\nimport { celCombinatorMap } from './utils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"cel\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorCEL: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermost?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = celCombinatorMap[rule as DefaultCombinatorName];\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule);\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Rules\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        /* v8 ignore next -- @preserve */\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const fieldData = getOption(fields, rule.field);\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    const expression = processedRules.join(\n      isRuleGroupType(rg) ? ` ${celCombinatorMap[rg.combinator as DefaultCombinatorName]} ` : ' '\n    );\n\n    const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? '!' : ''}(`, ')'] : ['', ''];\n\n    return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type { FormatQueryFinalOptions, RuleGroupType, RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { lc, nullOrUndefinedOrEmpty } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorCEL } from './defaultRuleGroupProcessorCEL';\nimport { processMatchMode, getSubqueryElementAlias, shouldRenderAsNumber } from './utils';\n\nconst shouldNegate = (op: string) => op.startsWith('not') || op.startsWith('doesnot');\n\nconst escapeDoubleQuotes = (v: unknown, escapeQuotes?: boolean) =>\n  typeof v !== 'string' || !escapeQuotes ? `${v}` : v.replaceAll(`\"`, `\\\\\"`);\n\n/**\n * Default rule processor used by {@link formatQuery} for \"cel\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorCEL: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  opts = {}\n) => {\n  const { escapeQuotes, parseNumbers, preserveValueOrder } = opts;\n  const { field, operator, value, valueSource } = rule;\n  // Paradigm A: parameters render as bare variable references (like field sources),\n  // since CEL has no external bind-parameter concept.\n  const valueIsField = valueSource === 'field' || valueSource === 'parameter';\n  const operatorTL = lc(operator === '=' ? '==' : operator);\n  const useBareValue =\n    typeof value === 'number' ||\n    typeof value === 'boolean' ||\n    typeof value === 'bigint' ||\n    shouldRenderAsNumber(value, parseNumbers);\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return '';\n  } else if (matchEval) {\n    const { mode, threshold } = matchEval;\n\n    const subqueryDepth = opts.subqueryDepth ?? 0;\n    const arrayElementAlias = getSubqueryElementAlias(subqueryDepth);\n\n    const celQuery = transformQuery(rule.value as RuleGroupType, {\n      ruleProcessor: r => ({ ...r, field: `${arrayElementAlias}${r.field ? `.${r.field}` : ''}` }),\n    });\n    const nestedArrayFilter = defaultRuleGroupProcessorCEL(celQuery, {\n      ...(opts as FormatQueryFinalOptions),\n      subqueryDepth: subqueryDepth + 1,\n    });\n\n    switch (mode) {\n      case 'all':\n        return `${field}.all(${arrayElementAlias}, ${nestedArrayFilter})`;\n\n      case 'none':\n      case 'some':\n        return `${mode === 'none' ? '!' : ''}${field}.exists(${arrayElementAlias}, ${nestedArrayFilter})`;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const totalCount = `double(${field}.size())`;\n        const filteredCount = `${field}.filter(${arrayElementAlias}, ${nestedArrayFilter}).size()`;\n\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '==';\n\n        if (threshold > 0 && threshold < 1) {\n          return `double(${filteredCount}) ${op} (${totalCount} * ${threshold})`;\n        }\n        return `${filteredCount} ${op} ${threshold}`;\n      }\n    }\n  }\n\n  switch (operatorTL) {\n    case '<':\n    case '<=':\n    case '==':\n    case '!=':\n    case '>':\n    case '>=':\n      return `${field} ${operatorTL} ${\n        valueIsField || useBareValue\n          ? trimIfString(value)\n          : `\"${escapeDoubleQuotes(value, escapeQuotes)}\"`\n      }`;\n\n    case 'contains':\n    case 'doesnotcontain': {\n      const negate = shouldNegate(operatorTL) ? '!' : '';\n      return `${negate}${field}.contains(${\n        valueIsField ? trimIfString(value) : `\"${escapeDoubleQuotes(value, escapeQuotes)}\"`\n      })`;\n    }\n\n    case 'beginswith':\n    case 'doesnotbeginwith': {\n      const negate = shouldNegate(operatorTL) ? '!' : '';\n      return `${negate}${field}.startsWith(${\n        valueIsField ? trimIfString(value) : `\"${escapeDoubleQuotes(value, escapeQuotes)}\"`\n      })`;\n    }\n\n    case 'endswith':\n    case 'doesnotendwith': {\n      const negate = shouldNegate(operatorTL) ? '!' : '';\n      return `${negate}${field}.endsWith(${\n        valueIsField ? trimIfString(value) : `\"${escapeDoubleQuotes(value, escapeQuotes)}\"`\n      })`;\n    }\n\n    case 'null':\n      return `${field} == null`;\n\n    case 'notnull':\n      return `${field} != null`;\n\n    case 'in':\n    case 'notin': {\n      const [prefix, suffix] = shouldNegate(operatorTL) ? ['!(', ')'] : ['', ''];\n      const valueAsArray = toArray(value);\n      return `${prefix}${field} in [${valueAsArray\n        .map(val =>\n          valueIsField || shouldRenderAsNumber(val, parseNumbers)\n            ? `${trimIfString(val)}`\n            : `\"${escapeDoubleQuotes(val, escapeQuotes)}\"`\n        )\n        .join(', ')}]${suffix}`;\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        !nullOrUndefinedOrEmpty(valueAsArray[0]) &&\n        !nullOrUndefinedOrEmpty(valueAsArray[1])\n      ) {\n        const [first, second] = valueAsArray;\n        // For backwards compatibility, default to parsing numbers for between operators\n        // unless parseNumbers is explicitly set to false\n        const shouldParseNumbers = !(parseNumbers === false);\n        const firstNum = shouldRenderAsNumber(first, shouldParseNumbers)\n          ? parseNumber(first, { parseNumbers: shouldParseNumbers })\n          : Number.NaN;\n        const secondNum = shouldRenderAsNumber(second, shouldParseNumbers)\n          ? parseNumber(second, { parseNumbers: shouldParseNumbers })\n          : Number.NaN;\n        let firstValue = Number.isNaN(firstNum)\n          ? valueIsField\n            ? `${first}`\n            : `\"${escapeDoubleQuotes(first, escapeQuotes)}\"`\n          : firstNum;\n        let secondValue = Number.isNaN(secondNum)\n          ? valueIsField\n            ? `${second}`\n            : `\"${escapeDoubleQuotes(second, escapeQuotes)}\"`\n          : secondNum;\n\n        if (\n          !preserveValueOrder &&\n          firstValue === firstNum &&\n          secondValue === secondNum &&\n          secondNum < firstNum\n        ) {\n          const tempNum = secondNum;\n          secondValue = firstNum;\n          firstValue = tempNum;\n        }\n\n        return operatorTL === 'between'\n          ? `(${field} >= ${firstValue} && ${field} <= ${secondValue})`\n          : `(${field} < ${firstValue} || ${field} > ${secondValue})`;\n      } else {\n        return '';\n      }\n    }\n  }\n  return '';\n};\n","import type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { lc } from '../misc';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Default fallback object used by {@link formatQuery} for \"mongodb_query\" format.\n *\n * @group Export\n */\nexport const mongoDbFallback = { $and: [{ $expr: true }] } as const;\n\n/**\n * Rule group processor used by {@link formatQuery} for \"mongodb_query\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorMongoDBQuery: RuleGroupProcessor = (\n  ruleGroup,\n  options,\n  meta\n) => {\n  const {\n    context,\n    fields,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const { inExpressionContext } = (context ?? {}) as { inExpressionContext?: boolean };\n\n  const processRuleGroup = (rg: RuleGroupType, outermost?: boolean) => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? mongoDbFallback : false;\n    }\n\n    const combinator = `$${lc(rg.combinator)}`;\n    let hasChildRules = false;\n\n    const expressions: Record<string, unknown>[] = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          const processedRuleGroup = processRuleGroup(rule);\n          if (processedRuleGroup) {\n            hasChildRules = true;\n            return processedRuleGroup;\n          }\n          return false;\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return false;\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(\n          rule,\n          {\n            ...options,\n            parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n            fieldData,\n          },\n          meta\n        );\n      })\n      .filter(Boolean);\n\n    const result =\n      expressions.length > 0\n        ? expressions.length === 1 && !hasChildRules\n          ? expressions[0]\n          : { [combinator]: expressions }\n        : mongoDbFallback;\n\n    return rg.not ? (inExpressionContext ? { $not: result } : { $nor: [result] }) : result;\n  };\n\n  return processRuleGroup(convertFromIC(ruleGroup), true);\n};\n","import type { FormatQueryFinalOptions, RuleGroupType, RuleProcessor } from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorMongoDBQuery } from './defaultRuleGroupProcessorMongoDBQuery';\nimport { isValidValue, mongoOperators, processMatchMode, shouldRenderAsNumber } from './utils';\n\nconst processNumber = <T>(value: unknown, fallback: T, parseNumbers = false) =>\n  shouldRenderAsNumber(value, parseNumbers || typeof value === 'bigint')\n    ? Number(parseNumber(value, { parseNumbers: 'strict' }))\n    : fallback;\n\n/**\n * Default rule processor used by {@link formatQuery} for \"mongodb_query\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorMongoDBQuery: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  options = {}\n) => {\n  const { field, operator, value, valueSource } = rule;\n  const { parseNumbers, preserveValueOrder, context } = options;\n  const valueIsField = valueSource === 'field';\n\n  const { avoidFieldsAsKeys } = (context ?? {}) as { avoidFieldsAsKeys?: boolean };\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return undefined;\n  } else if (matchEval) {\n    const { mode, threshold } = matchEval;\n\n    const totalCount = { $size: { $ifNull: [`$${field}`, []] } };\n    const subQueryNoAggCtx = defaultRuleGroupProcessorMongoDBQuery(\n      transformQuery(value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: r.field ? `${field}.${r.field}` : field }),\n      }),\n      {\n        ...(options as FormatQueryFinalOptions),\n        // We have to override `ruleProcessor` in case original `format` is \"mongodb\"\n        ruleProcessor: defaultRuleProcessorMongoDBQuery,\n        context: { ...options.context, avoidFieldsAsKeys: false },\n      }\n    );\n    const subQueryWithAggCtx = defaultRuleGroupProcessorMongoDBQuery(\n      transformQuery(value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: r.field ? `$item.${r.field}` : '$item' }),\n      }),\n      {\n        ...(options as FormatQueryFinalOptions),\n        // We have to override `ruleProcessor` in case original `format` is \"mongodb\"\n        ruleProcessor: defaultRuleProcessorMongoDBQuery,\n        context: { ...options.context, avoidFieldsAsKeys: true, inExpressionContext: true },\n      }\n    );\n\n    const filteredCount = {\n      $size: {\n        $ifNull: [\n          { $filter: { input: `$${field}`, as: 'item', cond: { $and: [subQueryWithAggCtx] } } },\n          [],\n        ],\n      },\n    };\n\n    switch (mode) {\n      case 'all':\n        return { $expr: { $eq: [filteredCount, totalCount] } };\n\n      case 'none':\n        return { $nor: [subQueryNoAggCtx] };\n\n      case 'some':\n        return subQueryNoAggCtx;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op =\n          mode === 'atleast'\n            ? mongoOperators['>=']\n            : mode === 'atmost'\n              ? mongoOperators['<=']\n              : mongoOperators['='];\n\n        if (threshold > 0 && threshold < 1) {\n          return { $expr: { [op]: [filteredCount, { $multiply: [totalCount, threshold] }] } };\n        }\n        return { $expr: { [op]: [filteredCount, threshold] } };\n      }\n    }\n  }\n\n  if (operator === '=' && !valueIsField) {\n    return avoidFieldsAsKeys\n      ? { $eq: [`$${field}`, processNumber(value, value, parseNumbers)] }\n      : { [field]: processNumber(value, value, parseNumbers) };\n  }\n\n  const operatorLC = lc(operator);\n  switch (operatorLC) {\n    case '<':\n    case '<=':\n    case '=':\n    case '!=':\n    case '>':\n    case '>=': {\n      const mongoOperator = mongoOperators[operatorLC];\n      return valueIsField\n        ? { [mongoOperator]: [`$${field}`, `$${value}`] }\n        : avoidFieldsAsKeys\n          ? {\n              $and: [\n                { $ne: [`$${field}`, null] },\n                { [mongoOperator]: [`$${field}`, processNumber(value, value, parseNumbers)] },\n              ],\n            }\n          : { [field]: { [mongoOperator]: processNumber(value, value, parseNumbers) } };\n    }\n\n    case 'contains':\n      return valueIsField\n        ? { $where: `this.${field}.includes(this.${value})` }\n        : avoidFieldsAsKeys\n          ? { $regexMatch: { input: `$${field}`, regex: value } }\n          : { [field]: { $regex: value } };\n\n    case 'beginswith':\n      return valueIsField\n        ? { $where: `this.${field}.startsWith(this.${value})` }\n        : avoidFieldsAsKeys\n          ? { $regexMatch: { input: `$${field}`, regex: `^${value}` } }\n          : { [field]: { $regex: `^${value}` } };\n\n    case 'endswith':\n      return valueIsField\n        ? { $where: `this.${field}.endsWith(this.${value})` }\n        : avoidFieldsAsKeys\n          ? { $regexMatch: { input: `$${field}`, regex: `${value}$` } }\n          : { [field]: { $regex: `${value}$` } };\n\n    case 'doesnotcontain':\n      return valueIsField\n        ? { $where: `!this.${field}.includes(this.${value})` }\n        : avoidFieldsAsKeys\n          ? { $not: { $regexMatch: { input: `$${field}`, regex: value } } }\n          : { [field]: { $not: { $regex: value } } };\n\n    case 'doesnotbeginwith':\n      return valueIsField\n        ? { $where: `!this.${field}.startsWith(this.${value})` }\n        : avoidFieldsAsKeys\n          ? { $not: { $regexMatch: { input: `$${field}`, regex: `^${value}` } } }\n          : { [field]: { $not: { $regex: `^${value}` } } };\n\n    case 'doesnotendwith':\n      return valueIsField\n        ? { $where: `!this.${field}.endsWith(this.${value})` }\n        : avoidFieldsAsKeys\n          ? { $not: { $regexMatch: { input: `$${field}`, regex: `${value}$` } } }\n          : { [field]: { $not: { $regex: `${value}$` } } };\n\n    case 'null':\n      return avoidFieldsAsKeys ? { $eq: [`$${field}`, null] } : { [field]: null };\n\n    case 'notnull':\n      return avoidFieldsAsKeys ? { $ne: [`$${field}`, null] } : { [field]: { $ne: null } };\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value);\n      return valueIsField\n        ? {\n            $where: `${operatorLC === 'notin' ? '!' : ''}[${valueAsArray\n              .map(val => `this.${val}`)\n              .join(',')}].includes(this.${field})`,\n          }\n        : avoidFieldsAsKeys\n          ? operatorLC === 'notin'\n            ? {\n                $not: {\n                  [mongoOperators.in]: [\n                    `$${field}`,\n                    valueAsArray.map(val => processNumber(val, val, parseNumbers)),\n                  ],\n                },\n              }\n            : {\n                [mongoOperators[operatorLC]]: [\n                  `$${field}`,\n                  valueAsArray.map(val => processNumber(val, val, parseNumbers)),\n                ],\n              }\n          : {\n              [field]: {\n                [mongoOperators[operatorLC]]: valueAsArray.map(val =>\n                  processNumber(val, val, parseNumbers)\n                ),\n              },\n            };\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        isValidValue(valueAsArray[0]) &&\n        isValidValue(valueAsArray[1])\n      ) {\n        const [first, second] = valueAsArray;\n        const firstNum = processNumber(first, Number.NaN, true);\n        const secondNum = processNumber(second, Number.NaN, true);\n        let firstValue = valueIsField ? first : Number.isNaN(firstNum) ? first : firstNum;\n        let secondValue = valueIsField ? second : Number.isNaN(secondNum) ? second : secondNum;\n        if (\n          !preserveValueOrder &&\n          firstValue === firstNum &&\n          secondValue === secondNum &&\n          secondNum < firstNum\n        ) {\n          const tempNum = secondNum;\n          secondValue = firstNum;\n          firstValue = tempNum;\n        }\n\n        if (operatorLC === 'between') {\n          return valueIsField\n            ? { $gte: [`$${field}`, `$${firstValue}`], $lte: [`$${field}`, `$${secondValue}`] }\n            : avoidFieldsAsKeys\n              ? {\n                  $and: [{ $gte: [`$${field}`, firstValue] }, { $lte: [`$${field}`, secondValue] }],\n                }\n              : { [field]: { $gte: firstValue, $lte: secondValue } };\n        } else {\n          return valueIsField\n            ? {\n                $or: [\n                  { $lt: [`$${field}`, `$${firstValue}`] },\n                  { $gt: [`$${field}`, `$${secondValue}`] },\n                ],\n              }\n            : avoidFieldsAsKeys\n              ? {\n                  $or: [{ $lt: [`$${field}`, firstValue] }, { $gt: [`$${field}`, secondValue] }],\n                }\n              : { $or: [{ [field]: { $lt: firstValue } }, { [field]: { $gt: secondValue } }] };\n        }\n      } else {\n        return '';\n      }\n    }\n  }\n  return '';\n};\n","import type { RuleProcessor } from '../../types';\nimport { defaultRuleProcessorMongoDBQuery } from './defaultRuleProcessorMongoDBQuery';\n\n/**\n * Default rule processor used by {@link formatQuery} for \"mongodb\" format.\n *\n * Note that the \"mongodb\" format is deprecated in favor of the \"mongodb_query\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorMongoDB: RuleProcessor = (rule, options) => {\n  const queryObj = defaultRuleProcessorMongoDBQuery(rule, options);\n  return queryObj ? JSON.stringify(queryObj) : '';\n};\n","import type { RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Default rule processor used by {@link formatQuery} for \"spel\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorSpEL: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermost?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = rule;\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule);\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Rules\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        /* v8 ignore next -- @preserve */\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const fieldData = getOption(fields, rule.field);\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    const expression = processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : ' ');\n\n    const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? '!' : ''}(`, ')'] : ['', ''];\n\n    return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type { FormatQueryFinalOptions, RuleGroupType, RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { lc, nullOrUndefinedOrEmpty } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorSpEL } from './defaultRuleGroupProcessorSpEL';\nimport { processMatchMode, shouldRenderAsNumber } from './utils';\n\nconst shouldNegate = (op: string) => op.startsWith('not') || op.startsWith('doesnot');\n\nconst wrapInNegation = (clause: string, negate: boolean) => (negate ? `!(${clause})` : clause);\n\nconst escapeSingleQuotes = (v: unknown, escapeQuotes?: boolean) =>\n  typeof v !== 'string' || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\\\'`);\n\n/**\n * Default rule processor used by {@link formatQuery} for \"spel\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorSpEL: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  opts = {}\n) => {\n  const { field, operator, value, valueSource } = rule;\n  const { escapeQuotes, parseNumbers, preserveValueOrder } = opts;\n  // Paradigm A: parameters render as bare variable references (like field sources),\n  // since SpEL has no external bind-parameter concept.\n  const valueIsField = valueSource === 'field' || valueSource === 'parameter';\n  const operatorTL = lc(operator === '=' ? '==' : operator);\n  const useBareValue =\n    typeof value === 'number' ||\n    typeof value === 'boolean' ||\n    typeof value === 'bigint' ||\n    shouldRenderAsNumber(value, parseNumbers);\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return '';\n  } else if (matchEval) {\n    const { mode, threshold } = matchEval;\n\n    const nestedArrayFilter = defaultRuleGroupProcessorSpEL(\n      transformQuery(rule.value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: r.field || '#this' }),\n      }),\n      opts as FormatQueryFinalOptions\n    );\n\n    const totalCount = `${field}.size()`;\n    const filteredCount = `${field}.?[${nestedArrayFilter}].size()`;\n\n    switch (mode) {\n      case 'all':\n        return `${filteredCount} == ${totalCount}`;\n\n      case 'none':\n        return `${filteredCount} == 0`;\n\n      case 'some':\n        return `${filteredCount} >= 1`;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '==';\n\n        if (threshold > 0 && threshold < 1) {\n          return `${filteredCount} ${op} (${totalCount} * ${threshold})`;\n        }\n        return `${filteredCount} ${op} ${threshold}`;\n      }\n    }\n  }\n\n  switch (operatorTL) {\n    case '<':\n    case '<=':\n    case '==':\n    case '!=':\n    case '>':\n    case '>=':\n      return `${field} ${operatorTL} ${\n        valueIsField || useBareValue\n          ? trimIfString(value)\n          : `'${escapeSingleQuotes(value, escapeQuotes)}'`\n      }`;\n\n    case 'contains':\n    case 'doesnotcontain': {\n      const valueTL = valueIsField\n        ? `'.*'.concat(${trimIfString(value)}).concat('.*')`\n        : `'.*${escapeSingleQuotes(value, escapeQuotes)}.*'`;\n\n      return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate(operatorTL));\n    }\n\n    case 'beginswith':\n    case 'doesnotbeginwith': {\n      const valueTL = valueIsField\n        ? `'^'.concat(${trimIfString(value)}).concat('.*')`\n        : `'${(typeof value === 'string' && !value.startsWith('^')) || useBareValue ? '^' : ''}${escapeSingleQuotes(value, escapeQuotes)}.*'`;\n\n      return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate(operatorTL));\n    }\n\n    case 'endswith':\n    case 'doesnotendwith': {\n      const valueTL = valueIsField\n        ? `'.*'.concat(${trimIfString(value)}).concat('$')`\n        : `'.*${escapeSingleQuotes(value, escapeQuotes)}${(typeof value === 'string' && !value.endsWith('$')) || useBareValue ? '$' : ''}'`;\n\n      return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate(operatorTL));\n    }\n\n    case 'null':\n      return `${field} == null`;\n\n    case 'notnull':\n      return `${field} != null`;\n\n    case 'in':\n    case 'notin': {\n      const negate = shouldNegate(operatorTL) ? '!' : '';\n      const valueAsArray = toArray(value);\n      return valueAsArray.length > 0\n        ? `${negate}(${valueAsArray\n            .map(\n              val =>\n                `${field} == ${\n                  valueIsField || shouldRenderAsNumber(val, parseNumbers)\n                    ? `${trimIfString(val)}`\n                    : `'${escapeSingleQuotes(val, escapeQuotes)}'`\n                }`\n            )\n            .join(' or ')})`\n        : '';\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        !nullOrUndefinedOrEmpty(valueAsArray[0]) &&\n        !nullOrUndefinedOrEmpty(valueAsArray[1])\n      ) {\n        const [first, second] = valueAsArray;\n        // For backwards compatibility in SpEL format, between operators should parse numbers\n        // unless parseNumbers is explicitly set to false\n        const shouldParseNumbers = !(parseNumbers === false);\n        const firstNum = shouldRenderAsNumber(first, shouldParseNumbers)\n          ? parseNumber(first, { parseNumbers: shouldParseNumbers })\n          : Number.NaN;\n        const secondNum = shouldRenderAsNumber(second, shouldParseNumbers)\n          ? parseNumber(second, { parseNumbers: shouldParseNumbers })\n          : Number.NaN;\n        let firstValue = Number.isNaN(firstNum)\n          ? valueIsField\n            ? `${first}`\n            : `'${escapeSingleQuotes(first, escapeQuotes)}'`\n          : firstNum;\n        let secondValue = Number.isNaN(secondNum)\n          ? valueIsField\n            ? `${second}`\n            : `'${escapeSingleQuotes(second, escapeQuotes)}'`\n          : secondNum;\n        if (\n          !preserveValueOrder &&\n          firstValue === firstNum &&\n          secondValue === secondNum &&\n          secondNum < firstNum\n        ) {\n          const tempNum = secondNum;\n          secondValue = firstNum;\n          firstValue = tempNum;\n        }\n        return operatorTL === 'between'\n          ? `(${field} >= ${firstValue} and ${field} <= ${secondValue})`\n          : `(${field} < ${firstValue} or ${field} > ${secondValue})`;\n      } else {\n        return '';\n      }\n    }\n  }\n\n  return '';\n};\n","import type { ValueProcessorByRule } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport {\n  getQuotedFieldName,\n  isValidValue,\n  shouldRenderAsNumber,\n  withParamPrefix,\n  wrapLikeFragment,\n} from './utils';\n\nconst escapeStringValueQuotes = (v: unknown, quoteChar: string, escapeQuotes?: boolean) =>\n  escapeQuotes && typeof v === 'string'\n    ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`)\n    : v;\n\n/**\n * Default value processor used by {@link formatQuery} for \"sql\" format.\n *\n * @group Export\n */\nexport const defaultValueProcessorByRule: ValueProcessorByRule = (\n  { operator, value, valueSource },\n  // v8 ignore next - defaultRuleProcessorSQL always provides options\n  {\n    escapeQuotes,\n    parseNumbers,\n    preserveValueOrder,\n    quoteFieldNamesWith,\n    quoteValuesWith,\n    concatOperator = '||',\n    fieldIdentifierSeparator,\n    paramPrefix,\n    wrapValueWith = ['', ''] as [string, string],\n    translations,\n  } = {}\n) => {\n  // Parameter value sources render as a (prefix-aware) bind-variable reference.\n  if (valueSource === 'parameter') {\n    const operatorLowerCase = lc(operator);\n    if (operatorLowerCase === 'between' || operatorLowerCase === 'notbetween') {\n      const valueAsArray = toArray(value, { retainEmptyStrings: true });\n      if (\n        valueAsArray.length < 2 ||\n        !isValidValue(valueAsArray[0]) ||\n        !isValidValue(valueAsArray[1])\n      ) {\n        return '';\n      }\n      const [first, second] = valueAsArray;\n      // Note: `translations` should not be used for SQL.\n      // This is only here to support the \"natural_language\" format.\n      return [withParamPrefix(first, paramPrefix), withParamPrefix(second, paramPrefix)].join(\n        ` ${translations?.betweenAnd ?? translations?.and ?? 'and'} `\n      );\n    }\n    if (operatorLowerCase === 'in' || operatorLowerCase === 'notin') {\n      const valueAsArray = toArray(value);\n      if (valueAsArray.length === 0) {\n        return '';\n      }\n      return `(${valueAsArray.map(v => withParamPrefix(v, paramPrefix)).join(', ')})`;\n    }\n    const paramRef = withParamPrefix(value, paramPrefix);\n    // String-match operators concatenate `%` wildcards onto the bind-variable reference.\n    switch (operatorLowerCase) {\n      case 'contains':\n      case 'doesnotcontain':\n      case 'beginswith':\n      case 'doesnotbeginwith':\n      case 'endswith':\n      case 'doesnotendwith':\n        return wrapLikeFragment(paramRef, operatorLowerCase, {\n          concatOperator,\n          quoteValuesWith,\n          wrapValueWith,\n        });\n    }\n    return paramRef;\n  }\n\n  const valueIsField = valueSource === 'field';\n  const operatorLowerCase = lc(operator);\n  const quoteChar = quoteValuesWith || \"'\";\n\n  const quoteValue = (v: unknown) =>\n    `${wrapValueWith[0]}${quoteChar}${v}${quoteChar}${wrapValueWith[1]}`;\n  const escapeValue = (v: unknown) => escapeStringValueQuotes(v, quoteChar, escapeQuotes);\n  const wrapAndEscape = (v: unknown) => quoteValue(escapeValue(v));\n  const wrapFieldName = (v: unknown) =>\n    getQuotedFieldName(v as string, { quoteFieldNamesWith, fieldIdentifierSeparator });\n  const likeOpts = { concatOperator, quoteValuesWith, wrapValueWith };\n\n  switch (operatorLowerCase) {\n    case 'null':\n    case 'notnull': {\n      return '';\n    }\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value);\n      if (valueAsArray.length > 0) {\n        return `(${valueAsArray\n          .map(v =>\n            valueIsField\n              ? wrapFieldName(v)\n              : shouldRenderAsNumber(v, parseNumbers)\n                ? `${trimIfString(v)}`\n                : `${wrapAndEscape(v)}`\n          )\n          .join(', ')})`;\n      }\n      return '';\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value, { retainEmptyStrings: true });\n      if (\n        valueAsArray.length < 2 ||\n        !isValidValue(valueAsArray[0]) ||\n        !isValidValue(valueAsArray[1])\n      ) {\n        return '';\n      }\n\n      const [first, second] = valueAsArray;\n\n      const firstNum = shouldRenderAsNumber(first, parseNumbers)\n        ? parseNumber(first, { parseNumbers: 'strict' })\n        : Number.NaN;\n      const secondNum = shouldRenderAsNumber(second, parseNumbers)\n        ? parseNumber(second, { parseNumbers: 'strict' })\n        : Number.NaN;\n      const firstValue = Number.isNaN(firstNum) ? (valueIsField ? `${first}` : first) : firstNum;\n      const secondValue = Number.isNaN(secondNum)\n        ? valueIsField\n          ? `${second}`\n          : second\n        : secondNum;\n\n      const valsOneAndTwoOnly = [firstValue, secondValue];\n      if (\n        !preserveValueOrder &&\n        firstValue === firstNum &&\n        secondValue === secondNum &&\n        secondNum < firstNum\n      ) {\n        valsOneAndTwoOnly[0] = secondNum;\n        valsOneAndTwoOnly[1] = firstNum;\n      }\n\n      return (\n        (\n          valueIsField\n            ? valsOneAndTwoOnly.map(v => wrapFieldName(v))\n            : valsOneAndTwoOnly.every(v => shouldRenderAsNumber(v, parseNumbers))\n              ? valsOneAndTwoOnly.map(v => parseNumber(v, { parseNumbers: 'strict' }))\n              : valsOneAndTwoOnly.map(v => wrapAndEscape(v))\n        )\n          // Note: `translations` should not be used for SQL.\n          // This is only here to support the \"natural_language\" format.\n          .join(` ${translations?.betweenAnd ?? translations?.and ?? 'and'} `)\n      );\n    }\n\n    case 'contains':\n    case 'doesnotcontain':\n      return valueIsField\n        ? wrapLikeFragment(wrapFieldName(value), operatorLowerCase, likeOpts)\n        : quoteValue(`%${escapeValue(value)}%`);\n\n    case 'beginswith':\n    case 'doesnotbeginwith':\n      return valueIsField\n        ? wrapLikeFragment(wrapFieldName(value), operatorLowerCase, likeOpts)\n        : quoteValue(`${escapeValue(value)}%`);\n\n    case 'endswith':\n    case 'doesnotendwith':\n      return valueIsField\n        ? wrapLikeFragment(wrapFieldName(value), operatorLowerCase, likeOpts)\n        : quoteValue(`%${escapeValue(value)}`);\n  }\n\n  if (typeof value === 'boolean') {\n    return value ? 'TRUE' : 'FALSE';\n  }\n\n  return valueIsField\n    ? wrapFieldName(value)\n    : shouldRenderAsNumber(value, parseNumbers)\n      ? `${trimIfString(value)}`\n      : `${wrapAndEscape(value)}`;\n};\n","import type { DefaultCombinatorName, RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Maps a {@link DefaultCombinatorName} to a Cypher combinator keyword.\n *\n * @group Export\n */\nexport const cypherCombinatorMap: {\n  and: 'AND';\n  or: 'OR';\n} = {\n  and: 'AND',\n  or: 'OR',\n} satisfies Record<DefaultCombinatorName, 'AND' | 'OR'>;\n\n/**\n * Rule group processor used by {@link formatQuery} for \"cypher\" and \"gql\" formats.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorCypher: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermost?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = cypherCombinatorMap[rule as DefaultCombinatorName];\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule);\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Rules\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        /* v8 ignore next -- @preserve */\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const fieldData = getOption(fields, rule.field);\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    const expression = processedRules.join(\n      isRuleGroupType(rg) ? ` ${cypherCombinatorMap[rg.combinator as DefaultCombinatorName]} ` : ' '\n    );\n\n    const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? 'NOT ' : ''}(`, ')'] : ['', ''];\n\n    return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type { Column, Operators, SQL, Table } from 'drizzle-orm';\nimport type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Minimal structural shape of Drizzle's `Operators` object. Declared locally so the public type\n * surface of this package never references `drizzle-orm`, which is an optional peer dependency.\n * (Referencing it would force consumers to install it to typecheck without `skipLibCheck`.)\n *\n * @group Export\n */\nexport interface DrizzleOperatorsLike {\n  // oxlint-disable-next-line typescript/no-explicit-any\n  and: (...conditions: any[]) => any;\n  // oxlint-disable-next-line typescript/no-explicit-any\n  or: (...conditions: any[]) => any;\n  // oxlint-disable-next-line typescript/no-explicit-any\n  not: (...conditions: any[]) => any;\n}\n\n/**\n * Return type of {@link defaultRuleGroupProcessorDrizzle}—the function assignable to the `where`\n * property in the Drizzle relational queries API. The Drizzle `SQL` result type is inferred from\n * the caller's own operators object, so it stays exact without importing `drizzle-orm` here.\n *\n * @group Export\n */\nexport type DrizzleWhereCallback = <Ops extends DrizzleOperatorsLike>(\n  columns: object,\n  drizzleOperators: Ops\n) => ReturnType<Ops['and']>;\n\n/**\n * Default rule group processor used by {@link formatQuery} for the \"drizzle\" format. The returned\n * function can be assigned to the `where` property in the Drizzle relational queries API.\n *\n * @example\n * const where = formatQuery(query, 'drizzle');\n * const results = db.query.users.findMany({ where });\n *\n * @returns Function that takes a Drizzle table config and an object of Drizzle operators.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorDrizzle: RuleGroupProcessor<DrizzleWhereCallback> = (\n  ruleGroup,\n  options,\n  _meta\n) =>\n  ((columns: Table | Record<string, Column>, drizzleOperators: Operators) => {\n    const {\n      fields,\n      getParseNumberBoolean,\n      placeholderFieldName,\n      placeholderOperatorName,\n      placeholderValueName,\n      validateRule,\n      validationMap,\n      ruleProcessor,\n    } = options;\n\n    if (!columns || !drizzleOperators) return undefined;\n\n    const { and, not, or } = drizzleOperators;\n\n    const processRuleGroup = (rg: RuleGroupType, _outermost?: boolean): SQL | undefined => {\n      if (\n        !isRuleOrGroupValid(\n          rg,\n          validationMap[\n            rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n          ]\n        )\n      ) {\n        return undefined;\n      }\n\n      const processedRules = rg.rules\n        .map(rule => {\n          if (isRuleGroup(rule)) {\n            return processRuleGroup(rule);\n          }\n          const [validationResult, fieldValidator] = validateRule(rule);\n          if (\n            !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n            rule.field === placeholderFieldName ||\n            rule.operator === placeholderOperatorName ||\n            /* v8 ignore next -- @preserve */\n            (placeholderValueName !== undefined && rule.value === placeholderValueName)\n          ) {\n            return undefined;\n          }\n          const fieldData = getOption(fields, rule.field);\n          return ruleProcessor(rule, {\n            ...options,\n            parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n            fieldData,\n            context: { ...options.context, columns, drizzleOperators },\n          });\n        })\n        .filter(Boolean);\n\n      if (processedRules.length === 0) {\n        return undefined;\n      }\n\n      const ruleGroupSQL: SQL | undefined =\n        rg.combinator === 'or' ? or(...processedRules)! : and(...processedRules)!;\n\n      return rg.not ? not(ruleGroupSQL) : ruleGroupSQL;\n    };\n\n    return processRuleGroup(convertFromIC(ruleGroup), true);\n  }) as DrizzleWhereCallback;\n","import type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"elasticsearch\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorElasticSearch: RuleGroupProcessor<Record<string, unknown>> = (\n  ruleGroup,\n  options\n) => {\n  const {\n    fields,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const processRuleGroup = (rg: RuleGroupType): Record<string, any> | false => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return false;\n    }\n\n    const processedRules = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          return processRuleGroup(rule);\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return false;\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(rule, {\n          ...options,\n          parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n          fieldData,\n        });\n      })\n      .filter(Boolean);\n\n    if (processedRules.length === 0) {\n      return false;\n    }\n\n    return {\n      bool: rg.not\n        ? {\n            must_not: /^or$/i.test(rg.combinator)\n              ? { bool: { should: processedRules } }\n              : processedRules,\n          }\n        : { [/^or$/i.test(rg.combinator) ? 'should' : 'must']: processedRules },\n    };\n  };\n\n  const processedRuleGroup = processRuleGroup(convertFromIC(ruleGroup));\n  return processedRuleGroup === false ? {} : processedRuleGroup;\n};\n","import type { RuleGroupProcessor, RuleGroupType, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"gremlin\" format.\n *\n * At the top level, filter rules produce chained `.has()` steps (implicit AND).\n * Nested groups use `.and()` / `.or()` / `.not()` compound traversals with\n * `__` anonymous traversal prefixes.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorGremlin: RuleGroupProcessor<string> = (\n  ruleGroup,\n  options\n) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const validateAndProcess = (rule: (typeof ruleGroup.rules)[number]) => {\n    // v8 ignore next -- @preserve\n    if (typeof rule === 'string' || isRuleGroup(rule)) return undefined;\n\n    const [validationResult, fieldValidator] = validateRule(rule);\n    if (\n      !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n      /* v8 ignore next 2 -- @preserve */\n      rule.field === placeholderFieldName ||\n      rule.operator === placeholderOperatorName ||\n      /* v8 ignore next -- @preserve */\n      (placeholderValueName !== undefined && rule.value === placeholderValueName)\n    ) {\n      return undefined;\n    }\n\n    const fieldData = getOption(fields, rule.field);\n    return ruleProcessor(rule, {\n      ...options,\n      parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n      escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n      fieldData,\n    });\n  };\n\n  /** Recursively processes a nested group into `.and()`/`.or()`/`.not()` form. */\n  const processNested = (rg: RuleGroupTypeAny): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return '';\n    }\n\n    const predicates: string[] = [];\n\n    for (const rule of rg.rules) {\n      if (typeof rule === 'string') continue;\n\n      if (isRuleGroup(rule)) {\n        const nested = processNested(rule);\n        if (nested) predicates.push(nested);\n        continue;\n      }\n\n      const processed = validateAndProcess(rule);\n      if (processed) predicates.push(processed);\n    }\n\n    if (predicates.length === 0) return '';\n\n    const combinator = (rg as RuleGroupType).combinator ?? 'and';\n    const prefix = rg.not ? 'not' : combinator;\n\n    if (predicates.length === 1 && !rg.not) return predicates[0];\n\n    // Wrap each step with `__` anonymous traversal prefix when it starts with `.`\n    const args = predicates.map(p => (p.startsWith('.') ? `__${p}` : p)).join(', ');\n    return `.${prefix}(${args})`;\n  };\n\n  // Top level: chain steps directly (implicit AND for outermost group)\n  if (\n    !isRuleOrGroupValid(\n      ruleGroup,\n      validationMap[\n        ruleGroup.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n      ]\n    )\n  ) {\n    return fallbackExpression;\n  }\n\n  const steps: string[] = [];\n\n  for (const rule of ruleGroup.rules) {\n    if (typeof rule === 'string') continue;\n\n    if (isRuleGroup(rule)) {\n      const compound = processNested(rule);\n      if (compound) steps.push(compound);\n      continue;\n    }\n\n    const processed = validateAndProcess(rule);\n    if (processed) steps.push(processed);\n  }\n\n  if (steps.length === 0) return fallbackExpression;\n\n  return steps.join('');\n};\n","import type { RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"jsonata\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorJSONata: RuleGroupProcessor<string> = (\n  ruleGroup,\n  options\n) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermost?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = rule;\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule);\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Rules\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        /* v8 ignore next -- @preserve */\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const fieldData = getOption(fields, rule.field);\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    const expression = processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : ' ');\n\n    const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? '$not' : ''}(`, ')'] : ['', ''];\n\n    return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type {\n  DefaultCombinatorName,\n  RQBJsonLogic,\n  RuleGroupProcessor,\n  RuleGroupType,\n} from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"jsonlogic\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorJsonLogic: RuleGroupProcessor<RQBJsonLogic> = (\n  ruleGroup,\n  options\n) => {\n  const {\n    fields,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const query = convertFromIC(ruleGroup);\n\n  const processRuleGroup = (rg: RuleGroupType, _outermost?: boolean): RQBJsonLogic => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return false;\n    }\n\n    const processedRules = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          return processRuleGroup(rule);\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return false;\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(rule, {\n          ...options,\n          parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n          fieldData,\n        });\n      })\n      .filter(Boolean);\n\n    if (processedRules.length === 0) {\n      return false;\n    }\n\n    const jsonRuleGroup: RQBJsonLogic = { [rg.combinator]: processedRules } as {\n      [k in DefaultCombinatorName]: [RQBJsonLogic, RQBJsonLogic, ...RQBJsonLogic[]];\n    };\n\n    return rg.not ? { '!': jsonRuleGroup } : jsonRuleGroup;\n  };\n\n  return processRuleGroup(query, true);\n};\n","import type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"ldap\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorLDAP: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupType, outermost?: boolean) => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const rules: string[] = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          return processRuleGroup(rule);\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return '';\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(rule, {\n          ...options,\n          parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n          escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n          fieldData,\n        });\n      })\n      .filter(Boolean);\n\n    const expression = rules.join('');\n\n    const [notPrefix, notSuffix] = rg.not ? ['(!', ')'] : ['', ''];\n    const [prefix, suffix] =\n      rules.length > 1\n        ? [`${notPrefix}(${rg.combinator === 'or' ? '|' : '&'}`, `)${notSuffix}`]\n        : [notPrefix, notSuffix];\n\n    return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;\n  };\n\n  return processRuleGroup(convertFromIC(ruleGroup), true);\n};\n","import type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { lc } from '../misc';\nimport { getOption } from '../optGroupUtils';\n\nconst isBracketed = (str: string) => str.startsWith('{') && str.endsWith('}');\n\n/**\n * Rule group processor used by {@link formatQuery} for \"mongodb\" format.\n *\n * Note that the \"mongodb\" format is deprecated in favor of the \"mongodb_query\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorMongoDB: RuleGroupProcessor<string> = (\n  ruleGroup,\n  options,\n  meta\n) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupType, outermost?: boolean) => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const combinator = `\"$${lc(rg.combinator)}\"`;\n    let hasChildRules = false;\n\n    const expressions: string[] = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          const processedRuleGroup = processRuleGroup(rule);\n          if (processedRuleGroup) {\n            hasChildRules = true;\n            // Don't wrap in curly braces if the result already is.\n            return isBracketed(processedRuleGroup) ? processedRuleGroup : `{${processedRuleGroup}}`;\n          }\n          return '';\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return '';\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(\n          rule,\n          {\n            ...options,\n            parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n            fieldData,\n          },\n          meta\n        );\n      })\n      .filter(Boolean);\n\n    const result =\n      expressions.length > 0\n        ? expressions.length === 1 && !hasChildRules\n          ? expressions[0]\n          : `${combinator}:[${expressions.join(',')}]`\n        : fallbackExpression;\n\n    return rg.not ? `\"$nor\":[${isBracketed(result) ? result : `{${result}}`}]` : result;\n  };\n\n  const processedQuery = processRuleGroup(convertFromIC(ruleGroup), true);\n  return isBracketed(processedQuery) ? processedQuery : `{${processedQuery}}`;\n};\n","import type { NLTranslationKey, RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup, isRuleGroupType, isRuleGroupTypeIC } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { lc } from '../misc';\nimport { getOption } from '../optGroupUtils';\nimport { getNLTranslataion } from './utils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"natural_language\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorNL: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    translations,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermostOrLonelyInGroup?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermostOrLonelyInGroup ? fallbackExpression : '';\n    }\n\n    const rg2 =\n      isRuleGroupTypeIC(rg) && rg.rules.some(r => typeof r === 'string' && lc(r) === 'xor')\n        ? convertFromIC(rg)\n        : rg;\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg2.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        const sep = translations.ruleSeparator ?? ', ';\n        precedingCombinator = `${sep}${translations[rule as NLTranslationKey] ?? rule} `;\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(\n          rule,\n          rg2.rules.length === 1 &&\n            !(\n              rg2.not ||\n              /^xor$/i.test(\n                rg2.combinator ??\n                  /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n              )\n            )\n        );\n        // v8 ignore else\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Basic rule validation\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        /* v8 ignore next -- @preserve */\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const escapeQuotes = (rule.valueSource ?? 'value') === 'value';\n\n      const fieldData = getOption(fields, rule.field);\n\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes,\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    if (processedRules.length === 0) {\n      return fallbackExpression;\n    }\n\n    const isXOR = lc(rg2.combinator ?? '') === 'xor';\n    const combinator = isXOR ? rg2.combinator!.slice(1) : rg2.combinator;\n    const mustWrap = rg2.not || !outermostOrLonelyInGroup || (isXOR && processedRules.length > 1);\n\n    const [prefixTL, suffixTL] = (['groupPrefix', 'groupSuffix'] as const).map(key =>\n      rg2.not\n        ? isXOR\n          ? getNLTranslataion(key, translations, ['not', 'xor'])\n          : getNLTranslataion(key, translations, ['not'])\n        : isXOR\n          ? getNLTranslataion(key, translations, ['xor'])\n          : getNLTranslataion(key, translations)\n    );\n\n    const prefix = mustWrap ? `${prefixTL} (`.trim() : '';\n    const suffix = mustWrap ? `) ${suffixTL}`.trim() : '';\n\n    const sep = translations.ruleSeparator ?? ', ';\n\n    return `${prefix}${processedRules.join(\n      isRuleGroupType(rg2)\n        ? `${sep}${translations[combinator as NLTranslationKey] ?? combinator} `\n        : ''\n    )}${suffix}`;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type {\n  ParameterizedNamedSQL,\n  ParameterizedSQL,\n  RuleGroupProcessor,\n  RuleGroupTypeAny,\n  RuleType,\n} from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { isPojo } from '../misc';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"parameterized\" and\n * \"parameterized_named\" formats.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorParameterized: RuleGroupProcessor<\n  ParameterizedSQL | ParameterizedNamedSQL\n> = (ruleGroup, options) => {\n  const {\n    format,\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const parameterized = format === 'parameterized';\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const params: any[] = [];\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const paramsNamed: Record<string, any> = {};\n  const fieldParams: Map<string, Set<string>> = new Map();\n\n  const getNextNamedParam = (field: string) => {\n    if (!fieldParams.has(field)) {\n      fieldParams.set(field, new Set());\n    }\n    const nextNamedParam = `${field}_${fieldParams.get(field)!.size + 1}`;\n    fieldParams.get(field)!.add(nextNamedParam);\n    return nextNamedParam;\n  };\n\n  const processRule = (rule: RuleType) => {\n    const [validationResult, fieldValidator] = validateRule(rule);\n    if (\n      !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n      rule.field === placeholderFieldName ||\n      rule.operator === placeholderOperatorName ||\n      /* v8 ignore start -- @preserve */\n      (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      /* v8 ignore stop -- @preserve */\n    ) {\n      return '';\n    }\n\n    const fieldData = getOption(fields, rule.field);\n\n    const fieldParamNames = Object.fromEntries(\n      ([...fieldParams.entries()] as [string, Set<string>][]).map(([f, s]) => [f, [...s]])\n    );\n\n    const processedRule = ruleProcessor(\n      rule,\n      {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        getNextNamedParam,\n        fieldParamNames,\n        fieldData,\n      },\n      { processedParams: params }\n    );\n\n    if (!isPojo(processedRule)) {\n      return '';\n    }\n\n    const { sql, params: customParams } = processedRule;\n\n    if (typeof sql !== 'string' || !sql) {\n      return '';\n    }\n\n    // v8 ignore else\n    if (format === 'parameterized' && Array.isArray(customParams)) {\n      params.push(...customParams);\n    } else if (format === 'parameterized_named' && isPojo(customParams)) {\n      Object.assign(paramsNamed, customParams);\n      // `getNextNamedParam` already adds new params to the list, but a custom\n      // rule processor might not call it so we need to make sure we add\n      // any new params here.\n      for (const p of Object.keys(customParams)) fieldParams.get(rule.field)?.add(p);\n    }\n\n    return sql;\n  };\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermostOrLonelyInGroup?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermostOrLonelyInGroup ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = rule;\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule, rg.rules.length === 1);\n        // v8 ignore else\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Rules\n      const processedRule = processRule(rule);\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    if (processedRules.length === 0) {\n      return fallbackExpression;\n    }\n\n    return `${rg.not ? 'NOT ' : ''}(${processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : ' ')})`;\n  };\n\n  if (parameterized) {\n    return { sql: processRuleGroup(ruleGroup, true), params };\n  }\n  return { sql: processRuleGroup(ruleGroup, true), params: paramsNamed };\n};\n","import type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Default fallback object used by {@link formatQuery} for \"prisma\" format.\n *\n * @group Export\n */\nexport const prismaFallback = {} as const;\n\n/**\n * Rule group processor used by {@link formatQuery} for \"prisma\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorPrisma: RuleGroupProcessor<\n  Record<string, unknown> | undefined\n> = (ruleGroup, options) => {\n  const {\n    fields,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupType, outermost?: boolean) => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? prismaFallback : undefined;\n    }\n\n    const combinator = rg.combinator.toUpperCase();\n    let hasChildRules = false;\n\n    const expressions: Record<string, unknown>[] = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          const processedRuleGroup = processRuleGroup(rule);\n          if (processedRuleGroup) {\n            hasChildRules = true;\n            return processedRuleGroup;\n          }\n          return undefined;\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return undefined;\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(rule, {\n          ...options,\n          parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n          fieldData,\n        });\n      })\n      .filter(Boolean);\n\n    return expressions.length > 0\n      ? expressions.length === 1 && !hasChildRules\n        ? expressions[0]\n        : { [combinator]: expressions }\n      : prismaFallback;\n  };\n\n  const result = processRuleGroup(convertFromIC(ruleGroup), true);\n\n  return ruleGroup.not ? { NOT: result } : result;\n};\n","import type { Op as _OpTypes } from 'sequelize';\nimport type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { lc } from '../misc';\nimport { getOption } from '../optGroupUtils';\n\ntype OpTypes = typeof _OpTypes;\n\n/**\n * Structural stand-in for Sequelize's `WhereOptions`. Declared locally so the public type surface\n * of this package never references `sequelize`, which is an optional peer dependency.\n * (Referencing it would force consumers to install it to typecheck without `skipLibCheck`.)\n * Assignable to `WhereOptions` at the call site, e.g. `Model.findAll({ where })`.\n *\n * @group Export\n */\nexport interface SequelizeWhereOptionsLike {\n  [key: string | symbol]: unknown;\n}\n\n/**\n * Rule group processor used by {@link formatQuery} for \"sequelize\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorSequelize: RuleGroupProcessor<\n  SequelizeWhereOptionsLike | undefined\n> = (ruleGroup, options) => {\n  // v8 ignore next\n  const {\n    fields,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n    context = {},\n  } = options;\n\n  const { sequelizeOperators: Op } = context as {\n    sequelizeOperators: OpTypes;\n  };\n\n  if (!Op) return undefined;\n\n  const processRuleGroup = (\n    rg: RuleGroupType,\n    _outermost?: boolean\n  ): SequelizeWhereOptionsLike | undefined => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return undefined;\n    }\n\n    const combinator = rg.combinator.toUpperCase();\n    let hasChildRules = false;\n\n    const expressions: Record<string, unknown>[] = rg.rules\n      .map(rule => {\n        if (isRuleGroup(rule)) {\n          const processedRuleGroup = processRuleGroup(rule);\n          if (processedRuleGroup) {\n            hasChildRules = true;\n            return processedRuleGroup;\n          }\n          return undefined;\n        }\n        const [validationResult, fieldValidator] = validateRule(rule);\n        if (\n          !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n          rule.field === placeholderFieldName ||\n          rule.operator === placeholderOperatorName ||\n          /* v8 ignore next -- @preserve */\n          (placeholderValueName !== undefined && rule.value === placeholderValueName)\n        ) {\n          return undefined;\n        }\n        const fieldData = getOption(fields, rule.field);\n        return ruleProcessor(rule, {\n          ...options,\n          parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n          fieldData,\n        });\n      })\n      .filter(Boolean);\n\n    if (expressions.length === 0) return undefined;\n\n    const result =\n      expressions.length === 1 && !hasChildRules\n        ? expressions[0]\n        : { [lc(combinator) === 'or' ? Op.or : Op.and]: expressions };\n\n    return rg.not ? { [Op.not]: result } : result;\n  };\n\n  return processRuleGroup(convertFromIC(ruleGroup), true);\n};\n","import type { DefaultCombinatorName, RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\nimport { celCombinatorMap } from './utils';\n\n/**\n * Rule group processor used by {@link formatQuery} for \"sparql\" format.\n *\n * SPARQL uses the same combinators as CEL (`&&` / `||`) and `!()` for negation.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorSPARQL: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermost?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermost ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = celCombinatorMap[rule as DefaultCombinatorName];\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule);\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Rules\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        /* v8 ignore next -- @preserve */\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const fieldData = getOption(fields, rule.field);\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes: (rule.valueSource ?? 'value') === 'value',\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    const expression = processedRules.join(\n      isRuleGroupType(rg) ? ` ${celCombinatorMap[rg.combinator as DefaultCombinatorName]} ` : ' '\n    );\n\n    const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? '!' : ''}(`, ')'] : ['', ''];\n\n    return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type { RuleGroupProcessor, RuleGroupTypeAny } from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\n\n/**\n * Default rule processor used by {@link formatQuery} for \"sql\" format.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorSQL: RuleGroupProcessor<string> = (ruleGroup, options) => {\n  const {\n    fields,\n    fallbackExpression,\n    getParseNumberBoolean,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    ruleProcessor,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const processRuleGroup = (rg: RuleGroupTypeAny, outermostOrLonelyInGroup?: boolean): string => {\n    if (\n      !isRuleOrGroupValid(\n        rg,\n        validationMap[\n          rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n        ]\n      )\n    ) {\n      return outermostOrLonelyInGroup ? fallbackExpression : '';\n    }\n\n    const processedRules = [];\n    let precedingCombinator = '';\n    let firstRule = true;\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        precedingCombinator = rule;\n        continue;\n      }\n\n      // Groups\n      if (isRuleGroup(rule)) {\n        const processedGroup = processRuleGroup(rule, rg.rules.length === 1);\n        // v8 ignore else\n        if (processedGroup) {\n          if (!firstRule && precedingCombinator) {\n            processedRules.push(precedingCombinator);\n            precedingCombinator = '';\n          }\n          firstRule = false;\n          processedRules.push(processedGroup);\n        }\n        continue;\n      }\n\n      // Basic rule validation\n      const [validationResult, fieldValidator] = validateRule(rule);\n      if (\n        !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n        rule.field === placeholderFieldName ||\n        rule.operator === placeholderOperatorName ||\n        (placeholderValueName !== undefined && rule.value === placeholderValueName)\n      ) {\n        continue;\n      }\n\n      const escapeQuotes = (rule.valueSource ?? 'value') === 'value';\n\n      const fieldData = getOption(fields, rule.field);\n\n      const processedRule = ruleProcessor(rule, {\n        ...options,\n        parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n        escapeQuotes,\n        fieldData,\n      });\n\n      if (processedRule) {\n        if (!firstRule && precedingCombinator) {\n          processedRules.push(precedingCombinator);\n          precedingCombinator = '';\n        }\n        firstRule = false;\n        processedRules.push(processedRule);\n      }\n    }\n\n    if (processedRules.length === 0) {\n      return fallbackExpression;\n    }\n\n    return `${rg.not ? 'NOT ' : ''}(${processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : ' ')})`;\n  };\n\n  return processRuleGroup(ruleGroup, true);\n};\n","import type { RuleGroupProcessor, RuleGroupType } from '../../types';\nimport { convertFromIC } from '../convertQuery';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { isRuleOrGroupValid } from '../isRuleOrGroupValid';\nimport { getOption } from '../optGroupUtils';\nimport type { TanStackDbWhereCallback, TsDbExpression, TsDbOperators } from './tanStackDbTypes.ts';\n\n/**\n * Default rule group processor used by {@link formatQuery} for the \"tanstack_db\" format.\n * Returns a `WhereCallback` suitable for TanStack DB's `.where()` method.\n *\n * @example\n * const where = formatQuery(query, { format: 'tanstack_db', context: { tanstackDb: tsdb } });\n * const results = useLiveQuery(q => q.from({ todo: todosCollection }).where(where));\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorTanStackDB: RuleGroupProcessor<TanStackDbWhereCallback> =\n  (ruleGroup, options) => refs => {\n    const {\n      fields,\n      getParseNumberBoolean,\n      placeholderFieldName,\n      placeholderOperatorName,\n      placeholderValueName,\n      validateRule,\n      validationMap,\n      context = {},\n      ruleProcessor,\n    } = options;\n\n    const ops = context.tanStackDbOperators as TsDbOperators;\n\n    if (!ops) return undefined;\n\n    const { and, eq, not, or } = ops;\n\n    const fallback = eq(1, 1);\n\n    // Grab ref keys for field resolution (first key is primary)\n    const refKeys = Object.keys(refs);\n\n    /* v8 ignore next -- @preserve */\n    if (refKeys.length === 0) return fallback;\n\n    const processRuleGroup = (rg: RuleGroupType): TsDbExpression | undefined => {\n      if (\n        !isRuleOrGroupValid(\n          rg,\n          validationMap[\n            rg.id ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n          ]\n        )\n      ) {\n        return undefined;\n      }\n\n      const processedRules: TsDbExpression[] = rg.rules\n        .map(rule => {\n          if (isRuleGroup(rule)) {\n            return processRuleGroup(rule);\n          }\n          const [validationResult, fieldValidator] = validateRule(rule);\n          if (\n            !isRuleOrGroupValid(rule, validationResult, fieldValidator) ||\n            rule.field === placeholderFieldName ||\n            rule.operator === placeholderOperatorName ||\n            /* v8 ignore next -- @preserve */\n            (placeholderValueName !== undefined && rule.value === placeholderValueName)\n          ) {\n            return undefined;\n          }\n          const fieldData = getOption(fields, rule.field);\n          return ruleProcessor(rule, {\n            ...options,\n            parseNumbers: getParseNumberBoolean(fieldData?.inputType),\n            fieldData,\n            context: {\n              ...context,\n              _tanstackDbRefs: refs,\n              _tanstackDbPrimaryRef: refKeys[0],\n            },\n          });\n        })\n        .filter(Boolean);\n\n      if (processedRules.length === 0) {\n        return fallback;\n      }\n\n      // Single expression: no wrapper needed\n      const ruleGroupExpr =\n        processedRules.length === 1\n          ? processedRules[0]\n          : rg.combinator === 'or'\n            ? or(...(processedRules as Parameters<typeof or>))\n            : and(...(processedRules as Parameters<typeof and>));\n\n      return rg.not ? not(ruleGroupExpr) : ruleGroupExpr;\n    };\n\n    return processRuleGroup(convertFromIC(ruleGroup)) ?? fallback;\n  };\n","import type {\n  DiagnosticEntry,\n  DiagnosticsFieldSummaryEntry,\n  DiagnosticsResult,\n  DiagnosticsStats,\n  FullField,\n  RuleGroupDiagnosticsResult,\n  RuleGroupICDiagnosticsArray,\n  RuleGroupICDiagnosticsResult,\n  RuleGroupProcessor,\n  RuleGroupTypeAny,\n  RuleDiagnosticsResult,\n  RuleType,\n  RuleValidator,\n  ValidationResult,\n} from '../../types';\nimport { isRuleGroup, isRuleGroupType } from '../isRuleGroup';\nimport { isRuleOrGroupValid, isValidationResult } from '../isRuleOrGroupValid';\nimport { numericRegex } from '../misc';\nimport { toFlatOptionArray } from '../optGroupUtils';\n\nconst numericInputTypes = new Set(['number', 'range', 'bigint']);\n\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst timeRegex = /^\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?$/;\nconst monthRegex = /^\\d{4}-\\d{2}$/;\nconst weekRegex = /^\\d{4}-W\\d{2}$/;\nconst colorRegex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nconst isValidDateComponents = (y: number, m: number, d: number): boolean => {\n  const date = new Date(Date.UTC(y, m - 1, d));\n  return date.getUTCFullYear() === y && date.getUTCMonth() === m - 1 && date.getUTCDate() === d;\n};\n\nconst isValidTimeComponents = (s: string): boolean => {\n  const parts = s.split(':');\n  const h = Number(parts[0]);\n  const m = Number(parts[1]);\n  const sec = parts[2] ? Number.parseFloat(parts[2]) : 0;\n  return h >= 0 && h <= 23 && m >= 0 && m <= 59 && sec >= 0 && sec < 60;\n};\n\n/**\n * Checks whether a value is compatible with the given {@link FullField.inputType}.\n * Returns a diagnostic code string if there is a mismatch, or `undefined` if OK.\n */\nconst checkValueTypeMismatch = (value: unknown, inputType: string): string | undefined => {\n  if (value === null || value === undefined || value === '') return undefined;\n\n  if (numericInputTypes.has(inputType)) {\n    const v = typeof value === 'string' ? value.trim() : value;\n    if (typeof v === 'number' || typeof v === 'bigint') return undefined;\n    if (typeof v === 'string' && numericRegex.test(v)) return undefined;\n    return 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'date') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    const v = value.trim();\n    if (!dateRegex.test(v)) return 'VALUE_TYPE_MISMATCH';\n    const [y, m, d] = v.split('-').map(Number);\n    return isValidDateComponents(y, m, d) ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'datetime-local') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    // Strip optional timezone suffix (Z, ±hh:mm, ±hhmm, ±hh)\n    const base = value.trim().replace(/(Z|[+-]\\d{2}:?\\d{2}|[+-]\\d{2})$/, '');\n    const tIndex = base.indexOf('T');\n    if (tIndex === -1) return 'VALUE_TYPE_MISMATCH';\n    const datePart = base.slice(0, tIndex);\n    const timePart = base.slice(tIndex + 1);\n    if (!dateRegex.test(datePart) || !timeRegex.test(timePart)) return 'VALUE_TYPE_MISMATCH';\n    const [y, m, d] = datePart.split('-').map(Number);\n    if (!isValidDateComponents(y, m, d)) return 'VALUE_TYPE_MISMATCH';\n    return isValidTimeComponents(timePart) ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'time') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    const v = value.trim();\n    if (!timeRegex.test(v)) return 'VALUE_TYPE_MISMATCH';\n    return isValidTimeComponents(v) ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'month') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    const v = value.trim();\n    if (!monthRegex.test(v)) return 'VALUE_TYPE_MISMATCH';\n    const m = Number(v.slice(5));\n    return m >= 1 && m <= 12 ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'week') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    const v = value.trim();\n    if (!weekRegex.test(v)) return 'VALUE_TYPE_MISMATCH';\n    const w = Number(v.slice(6));\n    return w >= 1 && w <= 53 ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'color') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    return colorRegex.test(value.trim()) ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  if (inputType === 'url') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    try {\n      void new URL(value.trim());\n      return undefined;\n    } catch {\n      return 'VALUE_TYPE_MISMATCH';\n    }\n  }\n\n  if (inputType === 'email') {\n    if (typeof value !== 'string') return 'VALUE_TYPE_MISMATCH';\n    return emailRegex.test(value.trim()) ? undefined : 'VALUE_TYPE_MISMATCH';\n  }\n\n  return undefined;\n};\n\n/**\n * Rule group processor used by {@link formatQuery} for \"diagnostics\" format.\n *\n * Produces a {@link DiagnosticsResult} containing an annotated copy of the query\n * tree (`query`) with `valid`, `reasons`, `path`, and `level` properties on every\n * rule and group; a flat `diagnostics` array; aggregate `stats`; and a per-field\n * `fieldSummary`.\n *\n * @group Export\n */\nexport const defaultRuleGroupProcessorDiagnostics: RuleGroupProcessor<DiagnosticsResult> = (\n  ruleGroup,\n  options\n) => {\n  const {\n    fields: fieldsOption,\n    placeholderFieldName,\n    placeholderOperatorName,\n    placeholderValueName,\n    validateRule,\n    validationMap,\n  } = options;\n\n  const diagnostics: DiagnosticEntry[] = [];\n  const stats: DiagnosticsStats = {\n    totalRules: 0,\n    totalGroups: 0,\n    validRules: 0,\n    invalidRules: 0,\n    validGroups: 0,\n    invalidGroups: 0,\n  };\n  const fieldSummary: Record<string, DiagnosticsFieldSummaryEntry> = {};\n\n  const uniqueFields = toFlatOptionArray(fieldsOption) satisfies FullField[];\n  const fieldsByName = new Map<string, FullField>();\n  for (const f of uniqueFields) {\n    fieldsByName.set(f.name, f);\n  }\n  const hasFieldsConfig = fieldsByName.size > 0;\n\n  const processRuleGroup = (\n    rg: RuleGroupTypeAny,\n    path: number[]\n  ): RuleGroupDiagnosticsResult | RuleGroupICDiagnosticsResult => {\n    stats.totalGroups++;\n    const level = path.length;\n    const groupValidationEntry = validationMap[rg.id ?? ''];\n    const groupSelfValid = isRuleOrGroupValid(rg, groupValidationEntry);\n\n    const groupReasons = getReasons(groupValidationEntry);\n\n    // Collect group-level diagnostics\n    if (rg.muted) {\n      diagnostics.push({\n        id: rg.id ?? '',\n        path,\n        code: 'MUTED',\n        message: 'Group is muted',\n        source: 'muted',\n      });\n    } else if (!groupSelfValid && groupValidationEntry !== undefined) {\n      diagnostics.push({\n        id: rg.id ?? '',\n        path,\n        code: 'CUSTOM_VALIDATOR',\n        message: groupReasons ? `Invalid: ${groupReasons.join(', ')}` : 'Group failed validation',\n        source: 'query-validator',\n      });\n    }\n\n    let allChildrenValid = true;\n    let ruleIndex = 0;\n    const annotatedRules: (\n      | RuleDiagnosticsResult\n      | RuleGroupDiagnosticsResult\n      | RuleGroupICDiagnosticsResult\n      | string\n    )[] = [];\n\n    for (const rule of rg.rules) {\n      // Independent combinators\n      if (typeof rule === 'string') {\n        annotatedRules.push(rule);\n        ruleIndex++;\n        continue;\n      }\n\n      const childPath = [...path, ruleIndex];\n\n      // Sub-groups\n      if (isRuleGroup(rule)) {\n        const annotatedGroup = processRuleGroup(rule, childPath);\n        if (!annotatedGroup.valid) {\n          allChildrenValid = false;\n        }\n        annotatedRules.push(annotatedGroup);\n        ruleIndex++;\n        continue;\n      }\n\n      // Rules\n      stats.totalRules++;\n      const childLevel = childPath.length;\n      const [validationResult, fieldValidator] = validateRule(rule);\n      const ruleValid =\n        isRuleOrGroupValid(rule, validationResult, fieldValidator) &&\n        rule.field !== placeholderFieldName &&\n        rule.operator !== placeholderOperatorName &&\n        !(placeholderValueName !== undefined && rule.value === placeholderValueName);\n\n      // Collect rule-level diagnostics\n      collectRuleDiagnostics(\n        rule,\n        childPath,\n        validationResult,\n        fieldValidator,\n        ruleValid,\n        diagnostics,\n        placeholderFieldName,\n        placeholderOperatorName,\n        placeholderValueName,\n        hasFieldsConfig,\n        fieldsByName\n      );\n\n      if (!ruleValid) {\n        allChildrenValid = false;\n        stats.invalidRules++;\n      } else {\n        stats.validRules++;\n      }\n\n      // Field summary\n      const fieldName = rule.field;\n      if (!fieldSummary[fieldName]) {\n        fieldSummary[fieldName] = { ruleCount: 0, invalidCount: 0 };\n      }\n      fieldSummary[fieldName].ruleCount++;\n      if (!ruleValid) {\n        fieldSummary[fieldName].invalidCount++;\n      }\n\n      const ruleReasons =\n        getReasons(validationResult) ?? getFieldValidatorReasons(rule, fieldValidator);\n\n      const annotatedRule: RuleDiagnosticsResult = {\n        ...rule,\n        valid: ruleValid,\n        ...(ruleReasons ? { reasons: ruleReasons } : null),\n        path: childPath,\n        level: childLevel,\n      };\n\n      annotatedRules.push(annotatedRule);\n      ruleIndex++;\n    }\n\n    const groupValid = groupSelfValid && allChildrenValid;\n\n    if (groupValid) {\n      stats.validGroups++;\n    } else {\n      stats.invalidGroups++;\n    }\n\n    if (isRuleGroupType(rg)) {\n      const result: RuleGroupDiagnosticsResult = {\n        ...rg,\n        valid: groupValid,\n        ...(groupReasons ? { reasons: groupReasons } : null),\n        path,\n        level,\n        rules: annotatedRules as (RuleDiagnosticsResult | RuleGroupDiagnosticsResult)[],\n      };\n      return result;\n    }\n\n    const result: RuleGroupICDiagnosticsResult = {\n      ...rg,\n      valid: groupValid,\n      ...(groupReasons ? { reasons: groupReasons } : null),\n      path,\n      level,\n      rules: annotatedRules as unknown as RuleGroupICDiagnosticsArray,\n    };\n    return result;\n  };\n\n  const query = processRuleGroup(ruleGroup, []);\n\n  // Add diagnostics for fields defined in config but not referenced in the query\n  if (hasFieldsConfig) {\n    const referencedFields = new Set(Object.keys(fieldSummary));\n    for (const [fieldName] of fieldsByName) {\n      if (!referencedFields.has(fieldName)) {\n        diagnostics.push({\n          id: '',\n          path: [],\n          code: 'UNREFERENCED_FIELD',\n          message: `Field \"${fieldName}\" is defined in the fields config but not used in the query`,\n          source: 'field-check',\n        });\n      }\n    }\n  }\n\n  return { query, diagnostics, stats, fieldSummary };\n};\n\n/**\n * Collects diagnostic entries for a single rule.\n */\nconst collectRuleDiagnostics = (\n  rule: RuleType,\n  path: number[],\n  validationResult: boolean | ValidationResult | undefined,\n  fieldValidator: RuleValidator | undefined,\n  ruleValid: boolean,\n  diagnostics: DiagnosticEntry[],\n  placeholderFieldName: string,\n  placeholderOperatorName: string,\n  placeholderValueName: string | undefined,\n  hasFieldsConfig: boolean,\n  fieldsByName: Map<string, FullField>\n): void => {\n  const id = rule.id ?? '';\n\n  if (rule.muted) {\n    diagnostics.push({\n      id,\n      path,\n      code: 'MUTED',\n      message: 'Rule is muted',\n      source: 'muted',\n    });\n  }\n\n  if (rule.field === placeholderFieldName) {\n    diagnostics.push({\n      id,\n      path,\n      code: 'PLACEHOLDER_FIELD',\n      message: 'Rule has a placeholder field',\n      source: 'placeholder',\n    });\n  }\n\n  if (rule.operator === placeholderOperatorName) {\n    diagnostics.push({\n      id,\n      path,\n      code: 'PLACEHOLDER_OPERATOR',\n      message: 'Rule has a placeholder operator',\n      source: 'placeholder',\n    });\n  }\n\n  if (placeholderValueName !== undefined && rule.value === placeholderValueName) {\n    diagnostics.push({\n      id,\n      path,\n      code: 'PLACEHOLDER_VALUE',\n      message: 'Rule has a placeholder value',\n      source: 'placeholder',\n    });\n  }\n\n  // Custom validator diagnostics (only if not already covered by other checks)\n  if (\n    !rule.muted &&\n    rule.field !== placeholderFieldName &&\n    rule.operator !== placeholderOperatorName &&\n    !(placeholderValueName !== undefined && rule.value === placeholderValueName)\n  ) {\n    if (typeof validationResult === 'boolean' && !validationResult) {\n      diagnostics.push({\n        id,\n        path,\n        code: 'CUSTOM_VALIDATOR',\n        message: 'Rule failed validation',\n        source: 'query-validator',\n      });\n    } else if (\n      typeof validationResult !== 'boolean' &&\n      isValidationResult(validationResult) &&\n      !validationResult.valid\n    ) {\n      const reasons = validationResult.reasons;\n      diagnostics.push({\n        id,\n        path,\n        code: 'CUSTOM_VALIDATOR',\n        message: reasons ? `Invalid: ${reasons.join(', ')}` : 'Rule failed validation',\n        source: 'query-validator',\n      });\n    } else if (!ruleValid && typeof fieldValidator === 'function') {\n      const vr = fieldValidator(rule);\n      const reasons =\n        typeof vr !== 'boolean' && isValidationResult(vr) && !vr.valid ? vr.reasons : undefined;\n      diagnostics.push({\n        id,\n        path,\n        code: 'CUSTOM_VALIDATOR',\n        message: reasons ? `Invalid: ${reasons.join(', ')}` : 'Rule failed field validation',\n        source: 'field-validator',\n      });\n    }\n  }\n\n  // Undefined field check\n  if (hasFieldsConfig && !fieldsByName.has(rule.field) && rule.field !== placeholderFieldName) {\n    diagnostics.push({\n      id,\n      path,\n      code: 'UNDEFINED_FIELD',\n      message: `Field \"${rule.field}\" is not defined in the fields config`,\n      source: 'field-check',\n    });\n  }\n\n  // Value/type mismatch check\n  if (hasFieldsConfig) {\n    const fieldDef = fieldsByName.get(rule.field);\n    if (fieldDef?.inputType) {\n      const mismatchCode = checkValueTypeMismatch(rule.value, fieldDef.inputType);\n      if (mismatchCode) {\n        diagnostics.push({\n          id,\n          path,\n          code: mismatchCode,\n          message: `Value \"${rule.value}\" is not compatible with input type \"${fieldDef.inputType}\"`,\n          source: 'type-check',\n        });\n      }\n    }\n  }\n};\n\n/**\n * Extracts `reasons` from a validation result, if present.\n */\nconst getReasons = (\n  validationResult: boolean | ValidationResult | undefined\n  // oxlint-disable-next-line typescript/no-explicit-any\n): any[] | undefined => {\n  if (\n    typeof validationResult !== 'boolean' &&\n    isValidationResult(validationResult) &&\n    !validationResult.valid &&\n    validationResult.reasons\n  ) {\n    return validationResult.reasons;\n  }\n  return undefined;\n};\n\n/**\n * Runs a field-level validator and extracts `reasons` if present.\n */\nconst getFieldValidatorReasons = (\n  rule: RuleType,\n  fieldValidator: RuleValidator | undefined\n  // oxlint-disable-next-line typescript/no-explicit-any\n): any[] | undefined => {\n  if (typeof fieldValidator === 'function') {\n    const vr = fieldValidator(rule);\n    if (typeof vr !== 'boolean' && isValidationResult(vr) && !vr.valid && vr.reasons) {\n      return vr.reasons;\n    }\n  }\n  return undefined;\n};\n","import type { RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { shouldRenderAsNumber } from './utils';\n\nconst escapeSingleQuotes = (v: unknown, escapeQuotes?: boolean) =>\n  typeof v !== 'string' || !escapeQuotes ? `${v}` : v.replaceAll(\"'\", \"\\\\'\");\n\n/**\n * Default rule processor used by {@link formatQuery} for \"cypher\" and \"gql\" formats.\n *\n * @group Export\n */\nexport const defaultRuleProcessorCypher: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  opts = {}\n) => {\n  const { escapeQuotes, parseNumbers } = opts;\n  const { field, operator, value, valueSource } = rule;\n  const valueIsField = valueSource === 'field';\n  const operatorTL = operator.toLowerCase();\n\n  const fmtVal = (v: unknown): string => {\n    if (v === null || v === undefined) return 'null';\n    if (typeof v === 'boolean' || typeof v === 'bigint') return String(v);\n    if (valueIsField) return trimIfString(v) as string;\n    if (typeof v === 'number' || shouldRenderAsNumber(v, parseNumbers))\n      return trimIfString(v) as string;\n    return `'${escapeSingleQuotes(v, escapeQuotes)}'`;\n  };\n\n  switch (operatorTL) {\n    case '=':\n      return `${field} = ${fmtVal(value)}`;\n    case '!=':\n    case '<>':\n      return `${field} <> ${fmtVal(value)}`;\n    case '<':\n    case '>':\n    case '<=':\n    case '>=':\n      return `${field} ${operatorTL} ${fmtVal(value)}`;\n    case 'contains':\n      return `${field} CONTAINS ${fmtVal(value)}`;\n    case 'doesnotcontain':\n      return `NOT ${field} CONTAINS ${fmtVal(value)}`;\n    case 'beginswith':\n      return `${field} STARTS WITH ${fmtVal(value)}`;\n    case 'doesnotbeginwith':\n      return `NOT ${field} STARTS WITH ${fmtVal(value)}`;\n    case 'endswith':\n      return `${field} ENDS WITH ${fmtVal(value)}`;\n    case 'doesnotendwith':\n      return `NOT ${field} ENDS WITH ${fmtVal(value)}`;\n    case 'null':\n      return `${field} IS NULL`;\n    case 'notnull':\n      return `${field} IS NOT NULL`;\n    case 'in':\n    case 'notin': {\n      const values = toArray(value).map(fmtVal);\n      if (!values.length) return '';\n      const prefix = operatorTL === 'notin' ? 'NOT ' : '';\n      return `${prefix}${field} IN [${values.join(', ')}]`;\n    }\n    case 'between':\n    case 'notbetween': {\n      const arr = toArray(value);\n      if (arr.length < 2) return '';\n      const [low, high] = [fmtVal(arr[0]), fmtVal(arr[1])];\n      const expr = `${low} <= ${field} AND ${field} <= ${high}`;\n      return operatorTL === 'notbetween' ? `NOT (${expr})` : expr;\n    }\n    default:\n      return `${field} ${operator} ${fmtVal(value)}`;\n  }\n};\n","import type { Column, Operators, SQL, SQLWrapper } from 'drizzle-orm';\nimport type { FormatQueryFinalOptions, RuleGroupType, RuleProcessor } from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorDrizzle } from './defaultRuleGroupProcessorDrizzle';\nimport {\n  getSubqueryElementAlias,\n  isValidValue,\n  processMatchMode,\n  shouldRenderAsNumber,\n} from './utils';\n\n/**\n * Default rule processor used by {@link formatQuery} for the \"drizzle\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorDrizzle: RuleProcessor = (rule, _options): SQL | undefined => {\n  const opts = _options ?? /* v8 ignore start -- @preserve */ {}; /* v8 ignore stop -- @preserve */\n  // v8 ignore next\n  const { parseNumbers, preserveValueOrder, context = {} } = opts;\n  const { columns, drizzleOperators, useRawFields } = context as {\n    columns: Record<string, Column>;\n    drizzleOperators: Operators;\n    useRawFields?: boolean;\n  };\n\n  if (!columns || !drizzleOperators) return undefined;\n\n  const {\n    between,\n    eq,\n    gt,\n    gte,\n    inArray,\n    isNotNull,\n    isNull,\n    like,\n    lt,\n    lte,\n    ne,\n    notBetween,\n    notInArray,\n    notLike,\n    sql,\n  } = drizzleOperators;\n\n  const { field, operator, value, valueSource } = rule;\n  const column =\n    useRawFields && /^[a-z_][a-z0-9_.]*$/i.test(field)\n      ? (sql.raw(field) as Exclude<SQLWrapper, SQL.Aliased | Column>)\n      : columns[field];\n  const operatorLC = lc(operator);\n\n  const valueIsField = valueSource === 'field';\n  const asFieldOrValue = (v: string | number) => (valueIsField ? columns[v] : v);\n\n  // Parse value as number when applicable\n  const maybeParseNumber = (v: unknown) => {\n    if (valueIsField || !parseNumbers) return asFieldOrValue(v as string);\n    return shouldRenderAsNumber(v, true) ? parseNumber(v, { parseNumbers: true }) : v;\n  };\n\n  if (!column) return undefined;\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return undefined;\n  } else if (matchEval) {\n    // We only support PostgreSQL nested arrays\n    if (opts.preset !== 'postgresql') return undefined;\n\n    const { mode, threshold } = matchEval;\n\n    const subqueryDepth = opts.subqueryDepth ?? 0;\n    const arrayElementAlias = getSubqueryElementAlias(subqueryDepth);\n\n    const sqlQuery = transformQuery(rule.value as RuleGroupType, {\n      ruleProcessor: r => ({ ...r, field: arrayElementAlias }),\n    });\n\n    const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(sqlQuery, {\n      ...(opts as FormatQueryFinalOptions),\n      context: { ...opts.context, useRawFields: true },\n      subqueryDepth: subqueryDepth + 1,\n    });\n\n    switch (mode) {\n      case 'all':\n        return sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) = array_length(${column}, 1)`;\n\n      case 'none':\n        return sql`not exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;\n\n      case 'some':\n        return sql`exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '=';\n\n        return threshold > 0 && threshold < 1\n          ? sql`(select count(*)::float / array_length(${column}, 1) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`\n          : sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`;\n      }\n    }\n  }\n\n  switch (operatorLC) {\n    case '=':\n      return eq(column, maybeParseNumber(value));\n    case '!=':\n      return ne(column, maybeParseNumber(value));\n    case '>':\n      return gt(column, maybeParseNumber(value));\n    case '<':\n      return lt(column, maybeParseNumber(value));\n    case '>=':\n      return gte(column, maybeParseNumber(value));\n    case '<=':\n      return lte(column, maybeParseNumber(value));\n    case 'beginswith':\n    case 'doesnotbeginwith':\n      return (operatorLC === 'doesnotbeginwith' ? notLike : like)(\n        column as SQL,\n        valueIsField ? sql`${asFieldOrValue(value)} || '%'` : `${value}%`\n      );\n    case 'contains':\n    case 'doesnotcontain':\n      return (operatorLC === 'doesnotcontain' ? notLike : like)(\n        column as SQL,\n        valueIsField ? sql`'%' || ${asFieldOrValue(value)} || '%'` : `%${value}%`\n      );\n    case 'endswith':\n    case 'doesnotendwith':\n      return (operatorLC === 'doesnotendwith' ? notLike : like)(\n        column as SQL,\n        valueIsField ? sql`'%' || ${asFieldOrValue(value)}` : `%${value}`\n      );\n    case 'null':\n      return isNull(column);\n    case 'notnull':\n      return isNotNull(column);\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value).map(v => maybeParseNumber(v));\n      return operatorLC === 'notin'\n        ? notInArray(column, valueAsArray)\n        : inArray(column, valueAsArray);\n    }\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        isValidValue(valueAsArray[0]) &&\n        isValidValue(valueAsArray[1])\n      ) {\n        type ColumnType = (typeof columns)[keyof typeof columns];\n        type ValueAsArray = (string | number | ColumnType)[];\n        let [first, second]: ValueAsArray = valueAsArray;\n        // For backwards compatibility, default to parsing numbers for between operators\n        // unless parseNumbers is explicitly set to false\n        const shouldParseNumbers = !(parseNumbers === false);\n        if (\n          !valueIsField &&\n          shouldRenderAsNumber(first, shouldParseNumbers) &&\n          shouldRenderAsNumber(second, shouldParseNumbers)\n        ) {\n          const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });\n          const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });\n          if (!preserveValueOrder && secondNum < firstNum) {\n            const tempNum = secondNum;\n            second = firstNum;\n            first = tempNum;\n          } else {\n            first = firstNum;\n            second = secondNum;\n          }\n        } else {\n          // v8 ignore else\n          if (valueIsField) {\n            first = asFieldOrValue(first);\n            second = asFieldOrValue(second);\n          }\n        }\n        return operatorLC === 'notbetween'\n          ? notBetween(column, first, second)\n          : between(column, first, second);\n      }\n      return undefined;\n    }\n    default:\n      return undefined;\n  }\n};\n","import type {\n  DefaultOperatorName,\n  FormatQueryFinalOptions,\n  RuleGroupType,\n  RuleProcessor,\n} from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorElasticSearch } from './defaultRuleGroupProcessorElasticSearch';\nimport { isValidValue, processMatchMode, shouldRenderAsNumber } from './utils';\n\ntype RangeOperator = 'gt' | 'gte' | 'lt' | 'lte';\ntype RangeRule = (\n  | { gt: string | number }\n  | { gte: string | number }\n  | { lt: string | number }\n  | { lte: string | number }\n) & { [k in RangeOperator]?: string | number };\ntype ElasticSearchRule =\n  | { range: Record<string, RangeRule> }\n  // oxlint-disable-next-line typescript/no-explicit-any\n  | { term: Record<string, any> }\n  | { exists: { field: string } }\n  | { regexp: { [k: string]: { value: string } } }\n  | { nested: { path: string; query: ElasticSearchQuery | ElasticSearchRule } };\ntype ElasticSearchQuery = {\n  bool:\n    | { filter: { script: { script: string } } }\n    | { must: ElasticSearchRule | ElasticSearchQuery | (ElasticSearchRule | ElasticSearchQuery)[] }\n    | {\n        must_not:\n          | ElasticSearchRule\n          | ElasticSearchQuery\n          | (ElasticSearchRule | ElasticSearchQuery)[];\n      }\n    | {\n        should: ElasticSearchRule | ElasticSearchQuery | (ElasticSearchRule | ElasticSearchQuery)[];\n      };\n};\n\nconst rangeOperatorMap = { '<': 'lt', '<=': 'lte', '>': 'gt', '>=': 'gte' } satisfies Record<\n  '<' | '<=' | '>' | '>=',\n  RangeOperator\n>;\n\nconst negateIfNotOp = (\n  op: string,\n  elasticSearchRule: ElasticSearchRule\n): ElasticSearchQuery | ElasticSearchRule =>\n  op.startsWith('not') || op.startsWith('doesnot')\n    ? { bool: { must_not: elasticSearchRule } }\n    : elasticSearchRule;\n\nconst escapeSQ = (s: string) => s?.replace(/('|\\\\)/g, `\\\\$1`);\n\nconst textFunctionMap: Partial<Record<Lowercase<DefaultOperatorName>, string>> = {\n  beginswith: 'startsWith',\n  doesnotbeginwith: 'startsWith',\n  doesnotcontain: 'contains',\n  doesnotendwith: 'endsWith',\n  endswith: 'endsWith',\n};\nconst getTextScript = (f: string, o: Lowercase<DefaultOperatorName>, v: string) => {\n  const script = `doc['${f}'].value.${textFunctionMap[o] ?? o}(doc['${v}'].value)`;\n  return o.startsWith('d') ? `!${script}` : script;\n};\n\nconst valueRenderer = (v: unknown, parseNumbers?: boolean) =>\n  typeof v === 'boolean'\n    ? v\n    : shouldRenderAsNumber(v, parseNumbers)\n      ? parseNumber(v, { parseNumbers })\n      : v;\n\n/**\n * Default rule processor used by {@link formatQuery} for \"elasticsearch\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorElasticSearch: RuleProcessor = (\n  rule,\n  options = {}\n): ElasticSearchQuery | ElasticSearchRule | false => {\n  const { field, operator, value, valueSource } = rule;\n  const { parseNumbers, preserveValueOrder } = options;\n  const operatorLC = lc(operator) as Lowercase<DefaultOperatorName>;\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return false;\n  } else if (matchEval) {\n    const { mode } = matchEval;\n\n    const subQuery = defaultRuleGroupProcessorElasticSearch(\n      transformQuery(rule.value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: r.field ? `${field}.${r.field}` : field }),\n      }),\n      options as FormatQueryFinalOptions\n    ) as ElasticSearchQuery | ElasticSearchRule;\n\n    // If the subquery didn't produce valid output, return false\n    if (Object.keys(subQuery).length === 0) {\n      return false;\n    }\n\n    switch (mode) {\n      case 'some': {\n        return {\n          nested: {\n            path: field,\n            query: subQuery,\n          },\n        };\n      }\n\n      case 'none': {\n        return {\n          bool: {\n            must_not: {\n              nested: {\n                path: field,\n                query: subQuery,\n              },\n            },\n          },\n        };\n      }\n\n      // ElasticSearch nested queries match if _any_ nested document matches, so \"all\" is not supported\n      case 'all':\n      // Threshold modes require script-based filtering in ElasticSearch.\n      // We cannot easily express \"at least N matches\" with nested queries alone.\n      // For now, return false to indicate these modes are not fully supported.\n      // A full implementation would require aggregation or script queries.\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        return false;\n      }\n    }\n  }\n\n  if (valueSource === 'field') {\n    // Bail out if not all values are strings\n    if (toArray(value).some(v => typeof v !== 'string')) return false;\n\n    const fieldForScript = escapeSQ(field);\n\n    switch (operatorLC) {\n      case '=':\n      case '!=':\n      case '>':\n      case '>=':\n      case '<':\n      case '<=': {\n        const operatorForScript = operatorLC === '=' ? '==' : operatorLC;\n        const valueForScript = escapeSQ(value);\n        return valueForScript\n          ? {\n              bool: {\n                filter: {\n                  script: {\n                    script: `doc['${fieldForScript}'].value ${operatorForScript} doc['${valueForScript}'].value`,\n                  },\n                },\n              },\n            }\n          : false;\n      }\n\n      case 'in':\n      case 'notin': {\n        const valueAsArray = toArray(value);\n        if (valueAsArray.length > 0) {\n          const arr = valueAsArray.map(v => ({\n            bool: {\n              filter: { script: { script: `doc['${fieldForScript}'].value == doc['${v}'].value` } },\n            },\n          }));\n          return { bool: operatorLC === 'in' ? { should: arr } : { must_not: arr } };\n        }\n        return false;\n      }\n\n      case 'between':\n      case 'notbetween': {\n        const valueAsArray = toArray(value);\n        if (valueAsArray.length >= 2 && valueAsArray[0] && valueAsArray[1]) {\n          const script = `doc['${fieldForScript}'].value >= doc['${valueAsArray[0]}'].value && doc['${fieldForScript}'].value <= doc['${valueAsArray[1]}'].value`;\n          return {\n            bool: {\n              filter: { script: { script: operatorLC === 'notbetween' ? `!(${script})` : script } },\n            },\n          };\n        }\n        return false;\n      }\n\n      case 'contains':\n      case 'doesnotcontain':\n      case 'beginswith':\n      case 'doesnotbeginwith':\n      case 'endswith':\n      case 'doesnotendwith': {\n        const valueForScript = escapeSQ(value);\n        if (!valueForScript) return false;\n        const script = getTextScript(fieldForScript, operatorLC, valueForScript);\n        return {\n          bool: {\n            filter: {\n              script: {\n                script,\n              },\n            },\n          },\n        };\n      }\n    }\n  }\n\n  switch (operatorLC) {\n    case '<':\n    case '<=':\n    case '>':\n    case '>=':\n      return {\n        range: {\n          [field]: {\n            [rangeOperatorMap[operatorLC]]: valueRenderer(value, parseNumbers),\n          } as RangeRule,\n        },\n      };\n\n    case '=':\n      return { term: { [field]: valueRenderer(value, parseNumbers) } };\n\n    case '!=':\n      return { bool: { must_not: { term: { [field]: valueRenderer(value, parseNumbers) } } } };\n\n    case 'null':\n      return { bool: { must_not: { exists: { field } } } };\n\n    case 'notnull':\n      return { exists: { field } };\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value).map(v => valueRenderer(v, parseNumbers));\n      if (valueAsArray.length > 0) {\n        const arr = valueAsArray.map(v => ({ term: { [field]: valueRenderer(v, parseNumbers) } }));\n        return { bool: operatorLC === 'in' ? { should: arr } : { must_not: arr } };\n      }\n      return false;\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        isValidValue(valueAsArray[0]) &&\n        isValidValue(valueAsArray[1])\n      ) {\n        let [first, second] = valueAsArray;\n        // For backwards compatibility, default to parsing numbers for between operators\n        // unless parseNumbers is explicitly set to false\n        const shouldParseNumbers = !(parseNumbers === false);\n        if (\n          shouldRenderAsNumber(first, shouldParseNumbers) &&\n          shouldRenderAsNumber(second, shouldParseNumbers)\n        ) {\n          const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });\n          const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });\n          if (!preserveValueOrder && secondNum < firstNum) {\n            const tempNum = secondNum;\n            second = firstNum;\n            first = tempNum;\n          } else {\n            first = firstNum;\n            second = secondNum;\n          }\n        }\n        return negateIfNotOp(operatorLC, { range: { [field]: { gte: first, lte: second } } });\n      }\n      return false;\n    }\n\n    case 'contains':\n    case 'doesnotcontain':\n      return negateIfNotOp(operatorLC, { regexp: { [field]: { value: `.*${value}.*` } } });\n\n    case 'beginswith':\n    case 'doesnotbeginwith':\n      return negateIfNotOp(operatorLC, { regexp: { [field]: { value: `${value}.*` } } });\n\n    case 'endswith':\n    case 'doesnotendwith':\n      return negateIfNotOp(operatorLC, { regexp: { [field]: { value: `.*${value}` } } });\n  }\n  return false;\n};\n","import type { RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { shouldRenderAsNumber } from './utils';\n\nconst escapeSingleQuotes = (v: unknown, escapeQuotes?: boolean) =>\n  typeof v !== 'string' || !escapeQuotes ? `${v}` : v.replaceAll(\"'\", \"\\\\'\");\n\n/**\n * Default rule processor used by {@link formatQuery} for \"gremlin\" format.\n *\n * Each rule becomes a `.has()` step (or `.hasNot()`/`.has()` for null checks).\n *\n * @group Export\n */\nexport const defaultRuleProcessorGremlin: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  opts = {}\n) => {\n  const { escapeQuotes, parseNumbers } = opts;\n  const { field, operator, value, valueSource } = rule;\n  const valueIsField = valueSource === 'field';\n  const operatorTL = operator.toLowerCase();\n\n  // Gremlin uses the last segment of dotted field names as the property key\n  const prop = field.includes('.') ? field.split('.').pop()! : field;\n\n  const fmtVal = (v: unknown): string => {\n    if (v === null || v === undefined) return 'null';\n    if (typeof v === 'boolean' || typeof v === 'bigint') return String(v);\n    if (valueIsField) return trimIfString(v) as string;\n    if (typeof v === 'number' || shouldRenderAsNumber(v, parseNumbers))\n      return trimIfString(v) as string;\n    return `'${escapeSingleQuotes(v, escapeQuotes)}'`;\n  };\n\n  switch (operatorTL) {\n    case '=':\n      return `.has('${prop}', ${fmtVal(value)})`;\n    case '!=':\n    case '<>':\n      return `.has('${prop}', neq(${fmtVal(value)}))`;\n    case '<':\n      return `.has('${prop}', lt(${fmtVal(value)}))`;\n    case '>':\n      return `.has('${prop}', gt(${fmtVal(value)}))`;\n    case '<=':\n      return `.has('${prop}', lte(${fmtVal(value)}))`;\n    case '>=':\n      return `.has('${prop}', gte(${fmtVal(value)}))`;\n    case 'contains':\n      return `.has('${prop}', containing(${fmtVal(value)}))`;\n    case 'doesnotcontain':\n      return `.has('${prop}', notContaining(${fmtVal(value)}))`;\n    case 'beginswith':\n      return `.has('${prop}', startingWith(${fmtVal(value)}))`;\n    case 'doesnotbeginwith':\n      return `.has('${prop}', notStartingWith(${fmtVal(value)}))`;\n    case 'endswith':\n      return `.has('${prop}', endingWith(${fmtVal(value)}))`;\n    case 'doesnotendwith':\n      return `.has('${prop}', notEndingWith(${fmtVal(value)}))`;\n    case 'null':\n      return `.hasNot('${prop}')`;\n    case 'notnull':\n      return `.has('${prop}')`;\n    case 'in': {\n      const items = toArray(value).map(fmtVal);\n      if (!items.length) return '';\n      return `.has('${prop}', within(${items.join(', ')}))`;\n    }\n    case 'notin': {\n      const items = toArray(value).map(fmtVal);\n      if (!items.length) return '';\n      return `.has('${prop}', without(${items.join(', ')}))`;\n    }\n    case 'between': {\n      const arr = toArray(value);\n      if (arr.length < 2) return '';\n      return `.has('${prop}', between(${fmtVal(arr[0])}, ${fmtVal(arr[1])}))`;\n    }\n    case 'notbetween': {\n      const arr = toArray(value);\n      if (arr.length < 2) return '';\n      return `.has('${prop}', outside(${fmtVal(arr[0])}, ${fmtVal(arr[1])}))`;\n    }\n    default:\n      return `.has('${prop}', ${fmtVal(value)})`;\n  }\n};\n","import type { FormatQueryFinalOptions, RuleGroupType, RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { lc, nullOrUndefinedOrEmpty } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorJSONata } from './defaultRuleGroupProcessorJSONata';\nimport { getQuotedFieldName, processMatchMode, shouldRenderAsNumber } from './utils';\n\nconst shouldNegate = (op: string) => op.startsWith('not') || op.startsWith('doesnot');\n\nconst quote = (v: unknown, escapeQuotes?: boolean) =>\n  `\"${typeof v !== 'string' || !escapeQuotes ? `${v}` : v.replaceAll(`\"`, `\\\\\"`)}\"`;\n\nconst negate = (clause: string, neg: boolean) => (neg ? `$not(${clause})` : clause);\n\nconst escapeStringRegex = (s: string) =>\n  `${s}`.replaceAll(/[/$()*+.?[\\\\\\]^{|}]/g, String.raw`\\$&`).replaceAll('-', String.raw`\\x2d`);\n\n/**\n * Default rule processor used by {@link formatQuery} for \"jsonata\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorJSONata: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  options = {}\n) => {\n  const { field, operator, value, valueSource } = rule;\n  const {\n    escapeQuotes,\n    parseNumbers,\n    preserveValueOrder,\n    quoteFieldNamesWith = ['', ''] as [string, string],\n    fieldIdentifierSeparator = '',\n  } = options;\n\n  const valueIsField = valueSource === 'field';\n  const useBareValue =\n    typeof value === 'number' ||\n    typeof value === 'boolean' ||\n    typeof value === 'bigint' ||\n    shouldRenderAsNumber(value, parseNumbers);\n\n  const qfn = (f: unknown) =>\n    getQuotedFieldName(f as string, { quoteFieldNamesWith, fieldIdentifierSeparator });\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return undefined;\n  } else if (matchEval) {\n    const { mode, threshold } = matchEval;\n\n    const totalCount = `$count(${qfn(field)})`;\n    const filteredCount = `$count($filter(${qfn(field)}, function($v) {${defaultRuleGroupProcessorJSONata(\n      transformQuery(value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: r.field ? `$v.${r.field}` : '$v' }),\n      }),\n      options as FormatQueryFinalOptions\n    )}}))`;\n\n    switch (mode) {\n      case 'all':\n        return `${filteredCount} = ${totalCount}`;\n\n      case 'none':\n        return `${filteredCount} = 0`;\n\n      case 'some':\n        return `${filteredCount} > 0`;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '=';\n\n        if (threshold > 0 && threshold < 1) {\n          return `${filteredCount} ${op} (${totalCount} * ${threshold})`;\n        }\n        return `${filteredCount} ${op} ${threshold}`;\n      }\n    }\n  }\n\n  const operatorLC = lc(operator);\n  switch (operatorLC) {\n    case '<':\n    case '<=':\n    case '=':\n    case '!=':\n    case '>':\n    case '>=':\n      return `${qfn(field)} ${operatorLC} ${\n        valueIsField\n          ? qfn(trimIfString(value))\n          : useBareValue\n            ? trimIfString(value)\n            : quote(value, escapeQuotes)\n      }`;\n\n    case 'contains':\n    case 'doesnotcontain':\n      return negate(\n        `$contains(${qfn(field)}, ${valueIsField ? qfn(trimIfString(value)) : quote(value, escapeQuotes)})`,\n        shouldNegate(operatorLC)\n      );\n\n    case 'beginswith':\n    case 'doesnotbeginwith':\n      return negate(\n        valueIsField\n          ? `$substring(${qfn(field)}, 0, $length(${qfn(trimIfString(value))})) = ${qfn(trimIfString(value))}`\n          : `$contains(${qfn(field)}, /^${escapeStringRegex(value)}/)`,\n        shouldNegate(operatorLC)\n      );\n\n    case 'endswith':\n    case 'doesnotendwith':\n      return negate(\n        valueIsField\n          ? `$substring(${qfn(field)}, $length(${qfn(field)}) - $length(${qfn(trimIfString(value))})) = ${qfn(trimIfString(value))}`\n          : `$contains(${qfn(field)}, /${escapeStringRegex(value)}$/)`,\n        shouldNegate(operatorLC)\n      );\n\n    case 'null':\n      return `${qfn(field)} = null`;\n\n    case 'notnull':\n      return `${qfn(field)} != null`;\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value);\n      return negate(\n        `${qfn(field)} in [${valueAsArray\n          .map(val =>\n            valueIsField\n              ? `${qfn(trimIfString(val))}`\n              : shouldRenderAsNumber(val, parseNumbers)\n                ? `${trimIfString(val)}`\n                : quote(val, escapeQuotes)\n          )\n          .join(', ')}]`,\n        shouldNegate(operatorLC)\n      );\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length < 2 ||\n        nullOrUndefinedOrEmpty(valueAsArray[0]) ||\n        nullOrUndefinedOrEmpty(valueAsArray[1])\n      ) {\n        return '';\n      }\n\n      const [first, second] = valueAsArray;\n      // For backwards compatibility, default to parsing numbers for between operators\n      // unless parseNumbers is explicitly set to false\n      const shouldParseNumbers = !(parseNumbers === false);\n      const firstNum = shouldRenderAsNumber(first, shouldParseNumbers)\n        ? parseNumber(first, { parseNumbers: shouldParseNumbers })\n        : Number.NaN;\n      const secondNum = shouldRenderAsNumber(second, shouldParseNumbers)\n        ? parseNumber(second, { parseNumbers: shouldParseNumbers })\n        : Number.NaN;\n      let firstValue = Number.isNaN(firstNum) ? (valueIsField ? `${first}` : first) : firstNum;\n      let secondValue = Number.isNaN(secondNum) ? (valueIsField ? `${second}` : second) : secondNum;\n\n      if (\n        !preserveValueOrder &&\n        firstValue === firstNum &&\n        secondValue === secondNum &&\n        secondNum < firstNum\n      ) {\n        const tempNum = secondNum;\n        secondValue = firstNum;\n        firstValue = tempNum;\n      }\n\n      const renderAsNumbers =\n        shouldRenderAsNumber(first, parseNumbers) && shouldRenderAsNumber(second, parseNumbers);\n      const getValueString = (raw: unknown, val: string | number) =>\n        valueIsField ? qfn(raw) : renderAsNumbers ? val : quote(val, escapeQuotes);\n\n      const expression = `${qfn(field)} >= ${getValueString(first, firstValue)} and ${qfn(field)} <= ${getValueString(second, secondValue)}`;\n\n      return operatorLC === 'between' ? `(${expression})` : negate(expression, true);\n    }\n  }\n\n  return '';\n};\n","import type {\n  FormatQueryFinalOptions,\n  JsonLogicVar,\n  RQBJsonLogic,\n  RuleProcessor,\n} from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { isRuleGroup } from '../isRuleGroup';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { defaultRuleGroupProcessorJsonLogic } from './defaultRuleGroupProcessorJsonLogic';\nimport { isValidValue, processMatchMode, shouldRenderAsNumber } from './utils';\n\nconst convertOperator = (op: '<' | '<=' | '=' | '!=' | '>' | '>=') =>\n  op\n    .replace(/^(=)$/, '$1=')\n    .replace(/^notnull$/i, '!=')\n    .replace(/^null$/i, '==') as '<' | '<=' | '==' | '!=' | '===' | '!==' | '>' | '>=';\n\nconst negateIfNotOp = (op: string, jsonRule: RQBJsonLogic) =>\n  op.startsWith('not') || op.startsWith('doesnot') ? { '!': jsonRule } : jsonRule;\n\n/**\n * Default rule processor used by {@link formatQuery} for \"jsonlogic\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorJsonLogic: RuleProcessor = (rule, options = {}): RQBJsonLogic => {\n  const { field, operator, value, valueSource } = rule;\n  const { parseNumbers, preserveValueOrder } = options;\n  const valueIsField = valueSource === 'field';\n  const fieldObject: JsonLogicVar = { var: field };\n  const fieldOrNumberRenderer = (v: unknown) =>\n    valueIsField\n      ? { var: `${v}` }\n      : shouldRenderAsNumber(v, parseNumbers)\n        ? parseNumber(v, { parseNumbers })\n        : v;\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return false;\n  } else if (matchEval) {\n    const { mode, threshold } = matchEval;\n\n    switch (mode) {\n      case 'all':\n      case 'none':\n      case 'some':\n        return {\n          [mode]: [\n            { var: field },\n            value.rules.length === 1 && !isRuleGroup(value.rules[0])\n              ? defaultRuleProcessorJsonLogic(value.rules[0], options)\n              : defaultRuleGroupProcessorJsonLogic(value, options as FormatQueryFinalOptions),\n          ],\n        } as RQBJsonLogic;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '==';\n\n        const filteredCount = {\n          reduce: [\n            {\n              filter: [\n                { var: field },\n                value.rules.length === 1 && !isRuleGroup(value.rules[0])\n                  ? defaultRuleProcessorJsonLogic(value.rules[0], options)\n                  : defaultRuleGroupProcessorJsonLogic(value, options as FormatQueryFinalOptions),\n              ],\n            },\n            { '+': [1, { var: 'accumulator' }] },\n            0,\n          ],\n        };\n\n        if (threshold > 0 && threshold < 1) {\n          const totalCount = {\n            reduce: [{ var: field }, { '+': [1, { var: 'accumulator' }] }, 0],\n          };\n          return { [op]: [filteredCount, { '*': [totalCount, threshold] }] } as RQBJsonLogic;\n        }\n        return { [op]: [filteredCount, threshold] } as RQBJsonLogic;\n      }\n    }\n  }\n\n  const operatorLC = lc(operator);\n  switch (operatorLC) {\n    case '<':\n    case '<=':\n    case '=':\n    case '!=':\n    case '>':\n    case '>=':\n      return {\n        [convertOperator(operatorLC)]: [fieldObject, fieldOrNumberRenderer(value)],\n      } as RQBJsonLogic;\n\n    case 'null':\n    case 'notnull': {\n      return {\n        [`${operatorLC === 'notnull' ? '!' : '='}=`]: [fieldObject, null],\n      } as RQBJsonLogic;\n    }\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value).map(v => fieldOrNumberRenderer(v));\n      return negateIfNotOp(operatorLC, { in: [fieldObject, valueAsArray] });\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        isValidValue(valueAsArray[0]) &&\n        isValidValue(valueAsArray[1])\n      ) {\n        type ValueAsArray = (string | number | { var: string | number })[];\n        let [first, second]: ValueAsArray = valueAsArray;\n        // For backwards compatibility, default to parsing numbers for between operators\n        // unless parseNumbers is explicitly set to false\n        const shouldParseNumbers = !(parseNumbers === false);\n        if (\n          !valueIsField &&\n          shouldRenderAsNumber(first, shouldParseNumbers) &&\n          shouldRenderAsNumber(second, shouldParseNumbers)\n        ) {\n          const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });\n          const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });\n          if (!preserveValueOrder && secondNum < firstNum) {\n            const tempNum = secondNum;\n            second = firstNum;\n            first = tempNum;\n          } else {\n            first = firstNum;\n            second = secondNum;\n          }\n        } else if (valueIsField) {\n          first = { var: first };\n          second = { var: second };\n        }\n        const jsonRule: RQBJsonLogic = { '<=': [first, fieldObject, second] };\n        return negateIfNotOp(operatorLC, jsonRule);\n      }\n      return false;\n    }\n\n    case 'contains':\n    case 'doesnotcontain': {\n      const jsonRule: RQBJsonLogic = {\n        in: [fieldOrNumberRenderer(value), fieldObject],\n      };\n      return negateIfNotOp(operatorLC, jsonRule);\n    }\n\n    case 'beginswith':\n    case 'doesnotbeginwith': {\n      const jsonRule: RQBJsonLogic = {\n        startsWith: [fieldObject, fieldOrNumberRenderer(value)],\n      };\n      return negateIfNotOp(operatorLC, jsonRule);\n    }\n\n    case 'endswith':\n    case 'doesnotendwith': {\n      const jsonRule: RQBJsonLogic = {\n        endsWith: [fieldObject, fieldOrNumberRenderer(value)],\n      };\n      return negateIfNotOp(operatorLC, jsonRule);\n    }\n  }\n  return false;\n};\n","import type { RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { lc, nullOrUndefinedOrEmpty } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { processMatchMode, shouldRenderAsNumber } from './utils';\n\nconst negateIf = (clause: string, negate: boolean) => (negate ? `(!${clause})` : `${clause}`);\n\nconst ldapEscape = (s: unknown) =>\n  `${trimIfString(s)}`.replaceAll(\n    /[()&|=<>~*\\\\/]/g,\n    (m: string) => `\\\\${m.codePointAt(0)!.toString(16)}`\n  );\n\n/**\n * Default rule processor used by {@link formatQuery} for \"ldap\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorLDAP: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  options = {}\n) => {\n  const { field, operator, value, valueSource } = rule;\n  const { preserveValueOrder } = options;\n  const operatorLC = lc(operator);\n\n  // Bail out if...\n  if (\n    // This is a field comparison (which LDAP does not support), or\n    valueSource === 'field' ||\n    // `value` is null/undefined/empty and the operator is not unary, or\n    (nullOrUndefinedOrEmpty(value) && operatorLC !== 'null' && operatorLC !== 'notnull') ||\n    // a valid `match` property is found (match modes are not supported in this format)\n    processMatchMode(rule)\n  ) {\n    return '';\n  }\n\n  switch (operatorLC) {\n    case '=':\n    case '!=':\n      return negateIf(`(${field}=${ldapEscape(value)})`, operatorLC === '!=');\n\n    case '>':\n    case '>=':\n      return `(${field}>=${ldapEscape(value)})`;\n\n    case '<':\n    case '<=':\n      return `(${field}<=${ldapEscape(value)})`;\n\n    case 'contains':\n    case 'doesnotcontain':\n      return negateIf(`(${field}=*${ldapEscape(value)}*)`, operatorLC === 'doesnotcontain');\n\n    case 'beginswith':\n    case 'doesnotbeginwith':\n      return negateIf(`(${field}=${ldapEscape(value)}*)`, operatorLC === 'doesnotbeginwith');\n\n    case 'endswith':\n    case 'doesnotendwith':\n      return negateIf(`(${field}=*${ldapEscape(value)})`, operatorLC === 'doesnotendwith');\n\n    case 'null':\n    case 'notnull':\n      return negateIf(`(${field}=*)`, operatorLC === 'notnull');\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value);\n      return negateIf(\n        `(|${valueAsArray.map(val => `(${field}=${ldapEscape(val)})`).join('')})`,\n        operatorLC === 'notin'\n      );\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length < 2 ||\n        nullOrUndefinedOrEmpty(valueAsArray[0]) ||\n        nullOrUndefinedOrEmpty(valueAsArray[1])\n      ) {\n        return '';\n      }\n\n      const [first, second] = valueAsArray;\n      const firstNum = shouldRenderAsNumber(first, true)\n        ? parseNumber(first, { parseNumbers: true })\n        : Number.NaN;\n      const secondNum = shouldRenderAsNumber(second, true)\n        ? parseNumber(second, { parseNumbers: true })\n        : Number.NaN;\n      let firstValue = Number.isNaN(firstNum) ? first : firstNum;\n      let secondValue = Number.isNaN(secondNum) ? second : secondNum;\n\n      if (\n        !preserveValueOrder &&\n        firstValue === firstNum &&\n        secondValue === secondNum &&\n        secondNum < firstNum\n      ) {\n        const tempNum = secondNum;\n        secondValue = firstNum;\n        firstValue = tempNum;\n      }\n\n      return negateIf(\n        `(&(${field}>=${ldapEscape(firstValue)})(${field}<=${ldapEscape(secondValue)}))`,\n        operatorLC === 'notbetween'\n      );\n    }\n  }\n\n  // v8 ignore next\n  return '';\n};\n","import type { FullField, ValueProcessorByRule } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { getOption } from '../optGroupUtils';\nimport { defaultValueProcessorByRule } from './defaultValueProcessorByRule';\nimport { getQuotedFieldName, isValidValue, shouldRenderAsNumber } from './utils';\n\nconst escapeStringValueQuotes = (v: unknown, quoteChar: string, escapeQuotes?: boolean) =>\n  escapeQuotes && typeof v === 'string'\n    ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`)\n    : /* v8 ignore next -- @preserve */ v;\n\n/**\n * Default value processor used by {@link formatQuery} for \"natural_language\" format.\n *\n * @group Export\n */\nexport const defaultValueProcessorNL: ValueProcessorByRule = (\n  rule,\n  // v8 ignore next - defaultRuleProcessorNL always provides options\n  opts = {}\n) => {\n  const {\n    escapeQuotes,\n    fields,\n    parseNumbers,\n    quoteFieldNamesWith,\n    quoteValuesWith,\n    fieldIdentifierSeparator,\n    translations,\n  } = opts;\n  const valueIsField = rule.valueSource === 'field';\n  const operatorLowerCase = lc(rule.operator);\n  const quoteChar =\n    quoteValuesWith || /* v8 ignore start -- @preserve */ \"'\"; /* v8 ignore stop -- @preserve */\n\n  const quoteValue = (v: unknown) => `${quoteChar}${v}${quoteChar}`;\n  const escapeValue = (v: unknown) => escapeStringValueQuotes(v, quoteChar, escapeQuotes);\n  const wrapAndEscape = (v: unknown) => quoteValue(escapeValue(v));\n  const wrapFieldName = (v: string) =>\n    getQuotedFieldName(v, { quoteFieldNamesWith, fieldIdentifierSeparator });\n\n  const t = translations ?? /* v8 ignore start -- @preserve */ {}; /* v8 ignore stop -- @preserve */\n  const orTL = t.or ?? 'or';\n  const trueTL = t.true ?? 'true';\n  const falseTL = t.false ?? 'false';\n  const listSep = t.listSeparator ?? ', ';\n  const useOxfordComma = !t.listSeparator;\n\n  switch (operatorLowerCase) {\n    case 'null':\n    case 'notnull': {\n      return '';\n    }\n\n    case 'between':\n    case 'notbetween': {\n      if (!valueIsField) {\n        return defaultValueProcessorByRule(rule, opts);\n      }\n\n      const valueAsArray = toArray(rule.value, { retainEmptyStrings: true })\n        .slice(0, 2)\n        .map(v =>\n          wrapFieldName(\n            getOption(\n              (fields as FullField[]) ??\n                /* v8 ignore start -- @preserve */ [] /* v8 ignore stop -- @preserve */,\n              v\n            )?.label ?? v\n          )\n        );\n      if (\n        valueAsArray.length < 2 ||\n        !isValidValue(valueAsArray[0]) ||\n        !isValidValue(valueAsArray[1])\n      ) {\n        return '';\n      }\n      return defaultValueProcessorByRule({ ...rule, value: valueAsArray }, opts);\n    }\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(rule.value);\n      if (valueAsArray.length === 0) return '';\n      const valStringArray = valueAsArray.map(v =>\n        valueIsField\n          ? wrapFieldName(\n              getOption(\n                (fields as FullField[]) ??\n                  /* v8 ignore start -- @preserve */ [] /* v8 ignore stop -- @preserve */,\n                v\n              )?.label ?? v\n            )\n          : shouldRenderAsNumber(v, parseNumbers)\n            ? `${trimIfString(v)}`\n            : `${wrapAndEscape(v)}`\n      );\n      if (valStringArray.length === 1) {\n        return valStringArray[0];\n      }\n      const oxfordComma = useOxfordComma && valStringArray.length > 2 ? ',' : '';\n      const list = `${valStringArray.slice(0, -1).join(listSep)}${oxfordComma} ${orTL} ${valStringArray.at(-1)}`;\n      return `(${list})`;\n    }\n  }\n\n  if (typeof rule.value === 'boolean') {\n    return rule.value ? trueTL : falseTL;\n  }\n\n  return valueIsField\n    ? wrapFieldName(\n        getOption(\n          (fields as FullField[]) ??\n            /* v8 ignore start -- @preserve */ [] /* v8 ignore stop -- @preserve */,\n          rule.value\n        )?.label ?? rule.value\n      )\n    : shouldRenderAsNumber(rule.value, parseNumbers)\n      ? `${trimIfString(rule.value)}`\n      : `${wrapAndEscape(rule.value)}`;\n};\n","import type {\n  DefaultOperatorName,\n  ExportOperatorMap,\n  FormatQueryFinalOptions,\n  FullOption,\n  RuleProcessor,\n} from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { getOption, toFullOptionList } from '../optGroupUtils';\nimport { defaultRuleGroupProcessorNL } from './defaultRuleGroupProcessorNL';\nimport { defaultValueProcessorNL } from './defaultValueProcessorNL';\nimport { getQuotedFieldName, normalizeConstituentWordOrder, processMatchMode } from './utils';\n\n/**\n * Default operator map used by {@link formatQuery} for \"natural_language\" format.\n *\n * @group Export\n */\nexport const defaultExportOperatorMap: ExportOperatorMap = {\n  '=': ['is', 'is the same as the value in'],\n  '!=': ['is not', 'is not the same as the value in'],\n  '<': ['is less than', 'is less than the value in'],\n  '>': ['is greater than', 'is greater than the value in'],\n  '<=': ['is less than or equal to', 'is less than or equal to the value in'],\n  '>=': ['is greater than or equal to', 'is greater than or equal to the value in'],\n  contains: ['contains', 'contains the value in'],\n  beginswith: ['starts with', 'starts with the value in'],\n  endswith: ['ends with', 'ends with the value in'],\n  doesnotcontain: ['does not contain', 'does not contain the value in'],\n  doesnotbeginwith: ['does not start with', 'does not start with the value in'],\n  doesnotendwith: ['does not end with', 'does not end with the value in'],\n  null: 'is null',\n  notnull: 'is not null',\n  in: ['is one of the values', 'is the same as a value in'],\n  notin: ['is not one of the values', 'is not the same as any value in'],\n  between: ['is between', 'is between the values in'],\n  notbetween: ['is not between', 'is not between the values in'],\n};\n\n/* v8 ignore next -- @preserve */\nconst defaultGetOperators = () => [];\n\n/**\n * Default operator processor used by {@link formatQuery} for \"natural_language\" format.\n *\n * @group Export\n */\nexport const defaultOperatorProcessorNL: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  opts = {}\n) => {\n  const { field, operator, valueSource = 'value' } = rule;\n  // v8 ignore next\n  const {\n    getOperators = defaultGetOperators,\n    operatorMap: operatorMapParam = defaultExportOperatorMap,\n  } = opts;\n\n  // Build the merged operator map (default + custom overrides)\n  const mergedOperatorMap = new Map<string, string | [string, string]>(\n    Object.entries(defaultExportOperatorMap)\n  );\n  for (const [key, value] of Object.entries(operatorMapParam)) {\n    mergedOperatorMap.set(lc(key), value);\n  }\n  const operatorMap = Object.fromEntries(mergedOperatorMap);\n\n  // For single-valued in/notin, use the = or != operator labels for clarity\n  const operatorLC = lc(operator);\n\n  var normalizedOperator = operator;\n\n  const hasSingleValue = toArray(rule.value).length === 1;\n\n  if (operatorLC === 'in' && hasSingleValue) {\n    normalizedOperator = '=';\n  } else if (operatorLC === 'notin' && hasSingleValue) {\n    normalizedOperator = '!=';\n  }\n\n  const { value: operatorNL, label } = getOption(\n    toFullOptionList(\n      getOperators(field, {\n        fieldData: opts.fieldData ?? {\n          name: field,\n          value: field,\n          label: field,\n        },\n      }) ?? /* v8 ignore start -- @preserve */ [] /* v8 ignore stop -- @preserve */\n    ) as FullOption[],\n    normalizedOperator\n  ) ?? {\n    name: normalizedOperator,\n    value: normalizedOperator,\n    label: normalizedOperator,\n  };\n\n  // Retrieve the natural language translation for the operator\n  const operatorTL = operatorMap[operatorNL as DefaultOperatorName] ??\n    operatorMap[lc(operatorNL) as Lowercase<DefaultOperatorName>] ?? [label, label];\n\n  // Return field-aware translation (e.g., \"is\" vs \"is the same as the value in\")\n  return typeof operatorTL === 'string' ? operatorTL : operatorTL[valueSource === 'field' ? 1 : 0];\n};\n\n/**\n * Default rule processor used by {@link formatQuery} for \"natural_language\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorNL: RuleProcessor = (rule, opts) => {\n  const { field, operator } = rule;\n  // v8 ignore next\n  const {\n    fieldData,\n    quoteFieldNamesWith = ['', ''] as [string, string],\n    fieldIdentifierSeparator = '',\n    quoteValuesWith = `'`,\n    operatorProcessor = defaultOperatorProcessorNL,\n    valueProcessor = defaultValueProcessorNL,\n    concatOperator = '||',\n    wordOrder = 'SVO',\n  } = opts ?? /* v8 ignore start -- @preserve */ {}; /* v8 ignore stop -- @preserve */\n\n  const processedField = getQuotedFieldName(fieldData?.label ?? field, {\n    quoteFieldNamesWith,\n    fieldIdentifierSeparator,\n  });\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return '';\n  } else if (matchEval) {\n    const { mode, threshold } = matchEval;\n\n    const nestedArrayFilter = defaultRuleGroupProcessorNL(rule.value, {\n      ...(opts as FormatQueryFinalOptions),\n      fields: toFullOptionList(fieldData?.subproperties ?? []),\n    });\n\n    // (H)as (S)ub(P)roperties\n    const hsp = (fieldData?.subproperties?.length ?? 0) > 0;\n\n    switch (mode) {\n      case 'all':\n        return `(${hsp ? 'for ' : ''}every item in ${processedField}${hsp ? ',' : ''} ${nestedArrayFilter})`;\n\n      case 'none':\n        return `(${hsp ? 'for ' : ''}no item in ${processedField}${hsp ? ',' : ''} ${nestedArrayFilter})`;\n\n      case 'some':\n        return `(${hsp ? 'for ' : ''}at least one item in ${processedField}${hsp ? ',' : ''} ${nestedArrayFilter})`;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const mm = mode.replace('at', 'at ');\n        if (threshold > 0 && threshold < 1) {\n          return `(${hsp ? 'for ' : ''}${mm} ${threshold * 100}% of the items in ${processedField}${hsp ? ',' : ''} ${nestedArrayFilter})`;\n        }\n        return `(${hsp ? 'for ' : ''}${mm} ${threshold} of the items in ${processedField}${hsp ? ',' : ''} ${nestedArrayFilter})`;\n      }\n    }\n  }\n\n  const value = valueProcessor(rule, {\n    ...opts,\n    quoteFieldNamesWith,\n    fieldIdentifierSeparator,\n    quoteValuesWith,\n    concatOperator,\n  });\n\n  const operatorLC = lc(operator);\n  if (\n    (operatorLC === 'in' ||\n      operatorLC === 'notin' ||\n      operatorLC === 'between' ||\n      operatorLC === 'notbetween') &&\n    !value\n  ) {\n    return '';\n  }\n\n  const processedOperator = operatorProcessor(rule, opts);\n\n  const wordOrderMap = {\n    S: processedField,\n    V: processedOperator,\n    O: value,\n  };\n\n  const translations = opts?.translations ?? {};\n  const suffixMap: Record<string, string> = {\n    S: translations.afterSubject ?? ' ',\n    V: translations.afterVerb ?? ' ',\n    O: translations.afterObject ?? ' ',\n  };\n\n  const wordOrderTuple = normalizeConstituentWordOrder(wordOrder).filter(\n    term => wordOrderMap[term] !== ''\n  );\n  return wordOrderTuple\n    .map(\n      (term, i) => `${wordOrderMap[term]}${i < wordOrderTuple.length - 1 ? suffixMap[term] : ''}`\n    )\n    .join('')\n    .trim();\n};\n","import type { FormatQueryFinalOptions, RuleGroupType, RuleProcessor } from '../../types';\nimport { lc } from '../misc';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorSQL } from './defaultRuleGroupProcessorSQL';\nimport { defaultValueProcessorByRule } from './defaultValueProcessorByRule';\nimport {\n  getQuotedFieldName,\n  getSubqueryElementAlias,\n  mapSQLOperator,\n  processMatchMode,\n} from './utils';\n\n/**\n * Default operator processor used by {@link formatQuery} for \"sql\" and \"parameterized*\" formats.\n *\n * @group Export\n */\nexport const defaultOperatorProcessorSQL: RuleProcessor = rule => lc(mapSQLOperator(rule.operator));\n\n/**\n * Default rule processor used by {@link formatQuery} for \"sql\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorSQL: RuleProcessor = (rule, opts = {}) => {\n  const {\n    quoteFieldNamesWith = ['', ''] as [string, string],\n    fieldIdentifierSeparator = '',\n    quoteValuesWith = `'`,\n    operatorProcessor = defaultOperatorProcessorSQL,\n    valueProcessor = defaultValueProcessorByRule,\n    concatOperator = '||',\n  } = opts;\n\n  const wrapFieldName = (v: string) =>\n    getQuotedFieldName(v, { quoteFieldNamesWith, fieldIdentifierSeparator });\n\n  const ruleField = wrapFieldName(rule.field);\n\n  const matchEval = processMatchMode(rule);\n\n  if (matchEval === false) {\n    return undefined;\n  } else if (matchEval) {\n    // We only support PostgreSQL nested arrays\n    if (opts?.preset !== 'postgresql') return '';\n\n    const { mode, threshold } = matchEval;\n\n    const subqueryDepth = opts.subqueryDepth ?? 0;\n    const arrayElementAlias = getSubqueryElementAlias(subqueryDepth);\n\n    const nestedArrayFilter = defaultRuleGroupProcessorSQL(\n      transformQuery(rule.value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: arrayElementAlias }),\n      }),\n      { ...(opts as FormatQueryFinalOptions), subqueryDepth: subqueryDepth + 1 }\n    );\n\n    switch (mode) {\n      case 'all':\n        return `(select count(*) from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter}) = array_length(${ruleField}, 1)`;\n\n      case 'none':\n        return `not exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter})`;\n\n      case 'some':\n        return `exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter})`;\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '=';\n\n        return `(select count(*)${threshold > 0 && threshold < 1 ? `::float / array_length(${ruleField}, 1)` : ''} from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter}) ${op} ${threshold}`;\n      }\n    }\n  }\n\n  const value = valueProcessor(rule, {\n    ...opts,\n    quoteFieldNamesWith,\n    fieldIdentifierSeparator,\n    quoteValuesWith,\n    concatOperator,\n  });\n\n  const operator = operatorProcessor(rule, opts);\n\n  const operatorLowerCase = lc(operator);\n  if (\n    (operatorLowerCase === 'in' ||\n      operatorLowerCase === 'not in' ||\n      operatorLowerCase === 'between' ||\n      operatorLowerCase === 'not between') &&\n    !value\n  ) {\n    return '';\n  }\n\n  return `${ruleField} ${operator} ${value}`.trim();\n};\n","import type { FormatQueryFinalOptions, FullField, RuleGroupType, RuleProcessor } from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { transformQuery } from '../transformQuery';\nimport { defaultRuleGroupProcessorParameterized } from './defaultRuleGroupProcessorParameterized';\nimport { defaultOperatorProcessorSQL } from './defaultRuleProcessorSQL';\nimport { defaultValueProcessorByRule } from './defaultValueProcessorByRule';\nimport {\n  getQuotedFieldName,\n  getSubqueryElementAlias,\n  processMatchMode,\n  shouldRenderAsNumber,\n  stripParamPrefix,\n  withParamPrefix,\n  wrapLikeFragment,\n} from './utils';\n\n/**\n * Default rule processor used by {@link formatQuery} for \"parameterized\" and\n * \"parameterized_named\" formats.\n *\n * @group Export\n */\nexport const defaultRuleProcessorParameterized: RuleProcessor = (rule, opts, meta) => {\n  // v8 ignore next\n  const {\n    fieldData,\n    format,\n    getNextNamedParam,\n    parseNumbers,\n    paramPrefix,\n    paramsKeepPrefix,\n    numberedParams,\n    quoteFieldNamesWith = ['', ''] as [string, string],\n    fieldIdentifierSeparator,\n    concatOperator,\n    operatorProcessor = defaultOperatorProcessorSQL,\n    valueProcessor = defaultValueProcessorByRule,\n  } = opts ?? {};\n\n  const { processedParams = [] } = meta ?? {};\n\n  const parameterized = format === 'parameterized';\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const params: any[] = [];\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const paramsNamed: Record<string, any> = {};\n\n  const finalize = (sql: string) =>\n    parameterized ? { sql, params } : { sql, params: paramsNamed };\n\n  const wrapFieldName = (v: string) =>\n    getQuotedFieldName(v, { quoteFieldNamesWith, fieldIdentifierSeparator });\n\n  const ruleField = wrapFieldName(rule.field);\n\n  const matchEval = processMatchMode(rule);\n\n  /* v8 ignore start -- @preserve */\n  if (matchEval === false) {\n    return undefined;\n  } else if (matchEval) {\n    // We only support PostgreSQL nested arrays\n    if (opts?.preset !== 'postgresql') return finalize('');\n\n    const { mode, threshold } = matchEval;\n\n    const subqueryDepth = opts.subqueryDepth ?? 0;\n    const arrayElementAlias = getSubqueryElementAlias(subqueryDepth);\n\n    const { sql: nestedSQL, params: nestedParams } = defaultRuleGroupProcessorParameterized(\n      transformQuery(rule.value as RuleGroupType, {\n        ruleProcessor: r => ({ ...r, field: arrayElementAlias }),\n      }),\n      {\n        ...(opts as FormatQueryFinalOptions),\n        fields: [] as FullField[],\n        subqueryDepth: subqueryDepth + 1,\n      }\n    );\n    // Ignore the \"parameterized_named\" case because PostgreSQL doesn't support named parameters\n    if (Array.isArray(nestedParams)) {\n      params.push(...nestedParams);\n    } else {\n      Object.assign(paramsNamed, nestedParams);\n    }\n\n    switch (mode) {\n      case 'all':\n        return finalize(\n          `(select count(*) from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL}) = array_length(${ruleField}, 1)`\n        );\n\n      case 'none':\n        return finalize(\n          `not exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL})`\n        );\n\n      case 'some':\n        return finalize(\n          `exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL})`\n        );\n\n      case 'atleast':\n      case 'atmost':\n      case 'exactly': {\n        const op = mode === 'atleast' ? '>=' : mode === 'atmost' ? '<=' : '=';\n\n        return finalize(\n          `(select count(*)${threshold > 0 && threshold < 1 ? `::float / array_length(${ruleField}, 1)` : ''} from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL}) ${op} ${threshold}`\n        );\n      }\n    }\n  }\n  /* v8 ignore stop -- @preserve */\n\n  const value = valueProcessor(rule, {\n    parseNumbers,\n    quoteFieldNamesWith,\n    concatOperator,\n    fieldData,\n    format,\n  });\n\n  const sqlOperator = operatorProcessor(rule, opts);\n  const sqlOperatorLowerCase = lc(sqlOperator);\n  const [qPre, qPost] = quoteFieldNamesWith;\n\n  if (\n    (sqlOperatorLowerCase === 'in' ||\n      sqlOperatorLowerCase === 'not in' ||\n      sqlOperatorLowerCase === 'between' ||\n      sqlOperatorLowerCase === 'not between') &&\n    !value\n  ) {\n    return finalize('');\n  } else if (sqlOperatorLowerCase === 'is null' || sqlOperatorLowerCase === 'is not null') {\n    return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator}`);\n  } else if (rule.valueSource === 'parameter') {\n    // Named-parameter reference: emit inline (binding supplied externally). For\n    // \"parameterized_named\", register the key(s) with a `null` placeholder so callers\n    // can see which bindings are expected (and so the key survives `JSON.stringify`,\n    // which drops `undefined`). Positional \"parameterized\" leaves `params` untouched\n    // to avoid desyncing placeholder indices.\n    const registerParam = (v: unknown) => {\n      const ref = withParamPrefix(v, paramPrefix);\n      if (!parameterized) {\n        paramsNamed[paramsKeepPrefix ? ref : stripParamPrefix(v, paramPrefix)] = null;\n      }\n      return ref;\n    };\n    if (sqlOperatorLowerCase === 'between' || sqlOperatorLowerCase === 'not between') {\n      const valueAsArray = toArray(rule.value, { retainEmptyStrings: true });\n      const [first, second] = valueAsArray.slice(0, 2);\n      return finalize(\n        `${qPre}${rule.field}${qPost} ${sqlOperator} ${registerParam(first)} and ${registerParam(second)}`.trim()\n      );\n    }\n    if (sqlOperatorLowerCase === 'in' || sqlOperatorLowerCase === 'not in') {\n      const splitValue = toArray(rule.value);\n      return finalize(\n        `${qPre}${rule.field}${qPost} ${sqlOperator} (${splitValue.map(v => registerParam(v)).join(', ')})`\n      );\n    }\n    // String-match operators concatenate `%` wildcards onto the bind-variable reference;\n    // `wrapLikeFragment` is a no-op for all other operators.\n    return finalize(\n      `${qPre}${rule.field}${qPost} ${sqlOperator} ${wrapLikeFragment(registerParam(rule.value), lc(rule.operator), { concatOperator })}`.trim()\n    );\n  } else if (rule.valueSource === 'field') {\n    return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${value}`.trim());\n  } else if (sqlOperatorLowerCase === 'in' || sqlOperatorLowerCase === 'not in') {\n    const splitValue = toArray(rule.value);\n    if (parameterized) {\n      for (const v of splitValue) {\n        params.push(shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v);\n      }\n      return finalize(\n        `${qPre}${rule.field}${qPost} ${sqlOperator} (${splitValue\n          .map((_v, i) =>\n            numberedParams\n              ? `${paramPrefix}${processedParams.length + 1 + splitValue.length - (splitValue.length - i)}`\n              : '?'\n          )\n          .join(', ')})`\n      );\n    }\n    const inParams: string[] = [];\n    for (const v of splitValue) {\n      const thisParamName = getNextNamedParam!(rule.field);\n      inParams.push(`${paramPrefix}${thisParamName}`);\n      paramsNamed[`${paramsKeepPrefix ? paramPrefix : ''}${thisParamName}`] = shouldRenderAsNumber(\n        v,\n        parseNumbers\n      )\n        ? parseNumber(v, { parseNumbers })\n        : v;\n    }\n    return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} (${inParams.join(', ')})`);\n  } else if (sqlOperatorLowerCase === 'between' || sqlOperatorLowerCase === 'not between') {\n    const valueAsArray = toArray(rule.value, { retainEmptyStrings: true });\n    const [first, second] = valueAsArray\n      .slice(0, 2)\n      .map(v => (shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v));\n    if (parameterized) {\n      params.push(first, second);\n      return finalize(\n        `${qPre}${rule.field}${qPost} ${sqlOperator} ${\n          numberedParams ? `${paramPrefix}${processedParams.length + 1}` : '?'\n        } and ${numberedParams ? `${paramPrefix}${processedParams.length + 2}` : '?'}`\n      );\n    }\n    const firstParamName = getNextNamedParam!(rule.field);\n    const secondParamName = getNextNamedParam!(rule.field);\n    paramsNamed[`${paramsKeepPrefix ? paramPrefix : ''}${firstParamName}`] = first;\n    paramsNamed[`${paramsKeepPrefix ? paramPrefix : ''}${secondParamName}`] = second;\n    return finalize(\n      `${qPre}${rule.field}${qPost} ${sqlOperator} ${paramPrefix}${firstParamName} and ${paramPrefix}${secondParamName}`\n    );\n  }\n\n  let paramValue = rule.value;\n  if (typeof rule.value === 'string') {\n    if (shouldRenderAsNumber(rule.value, parseNumbers)) {\n      paramValue = parseNumber(rule.value, { parseNumbers });\n    } else {\n      // Note that we're using `value` here, which has been processed through\n      // a `valueProcessor`, as opposed to `rule.value` which has not\n      paramValue = /^'.*'$/g.test(value)\n        ? value.replaceAll(/(^'|'$)/g, '')\n        : /* v8 ignore next -- @preserve */ value;\n    }\n  }\n\n  let paramName = '';\n  if (parameterized) {\n    params.push(paramValue);\n  } else {\n    paramName = getNextNamedParam!(rule.field);\n    paramsNamed[`${paramsKeepPrefix ? paramPrefix : ''}${paramName}`] = paramValue;\n  }\n\n  return finalize(\n    `${qPre}${rule.field}${qPost} ${sqlOperator} ${\n      parameterized\n        ? numberedParams\n          ? `${paramPrefix}${processedParams.length + 1}`\n          : '?'\n        : `${paramPrefix}${paramName}`\n    }`.trim()\n  );\n};\n","import type { ParseNumbersPropConfig, RuleProcessor } from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { isValidValue, prismaOperators, processMatchMode, shouldRenderAsNumber } from './utils';\n\nconst processNumber = <T>(value: unknown, fallback: T, parseNumbers?: ParseNumbersPropConfig) =>\n  shouldRenderAsNumber(value, !!parseNumbers || typeof value === 'bigint')\n    ? Number(parseNumber(value, { parseNumbers: !!parseNumbers }))\n    : fallback;\n\n/**\n * Default rule processor used by {@link formatQuery} for \"prisma\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorPrisma: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  options = {}\n) => {\n  const { field, operator, value, valueSource } = rule;\n  // v8 ignore next\n  const { parseNumbers, preserveValueOrder } = options;\n\n  // Neither field-to-field comparisons nor match modes are supported in this format\n  if (valueSource === 'field' || processMatchMode(rule)) return undefined;\n\n  const operatorLC = lc(operator);\n  switch (operatorLC) {\n    case '=':\n      return { [field]: processNumber(value, value, parseNumbers) };\n\n    case '!=':\n    case '<':\n    case '<=':\n    case '>':\n    case '>=': {\n      const prismaOperator = prismaOperators[operatorLC];\n      return {\n        [field]: {\n          [prismaOperator]: processNumber(value, value, parseNumbers),\n        },\n      };\n    }\n\n    case 'contains':\n      return { [field]: { contains: value } };\n\n    case 'beginswith':\n      return { [field]: { startsWith: value } };\n\n    case 'endswith':\n      return { [field]: { endsWith: value } };\n\n    case 'doesnotcontain':\n      return { NOT: { [field]: { contains: value } } };\n\n    case 'doesnotbeginwith':\n      return { NOT: { [field]: { startsWith: value } } };\n\n    case 'doesnotendwith':\n      return { NOT: { [field]: { endsWith: value } } };\n\n    case 'null':\n      return { [field]: null };\n\n    case 'notnull':\n      return { [field]: { not: null } };\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value);\n      return {\n        [field]: {\n          [prismaOperators[operatorLC]]: valueAsArray.map(val =>\n            processNumber(val, val, parseNumbers)\n          ),\n        },\n      };\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        isValidValue(valueAsArray[0]) &&\n        isValidValue(valueAsArray[1])\n      ) {\n        const [first, second] = valueAsArray;\n        // For backwards compatibility, default to parsing numbers for between operators\n        // unless parseNumbers is explicitly set to false\n        const shouldParseNumbers = !(parseNumbers === false);\n        const firstNum = shouldRenderAsNumber(first, shouldParseNumbers)\n          ? parseNumber(first, { parseNumbers })\n          : Number.NaN;\n        const secondNum = shouldRenderAsNumber(second, shouldParseNumbers)\n          ? parseNumber(second, { parseNumbers })\n          : Number.NaN;\n        let firstValue = Number.isNaN(firstNum) ? first : firstNum;\n        let secondValue = Number.isNaN(secondNum) ? second : secondNum;\n        if (\n          !preserveValueOrder &&\n          firstValue === firstNum &&\n          secondValue === secondNum &&\n          secondNum < firstNum\n        ) {\n          const tempNum = secondNum;\n          secondValue = firstNum;\n          firstValue = tempNum;\n        }\n\n        return operatorLC === 'between'\n          ? { [field]: { gte: firstValue, lte: secondValue } }\n          : { OR: [{ [field]: { lt: firstValue } }, { [field]: { gt: secondValue } }] };\n      } else {\n        return '';\n      }\n    }\n  }\n  return '';\n};\n","import type { Op as _OpTypes, col as _colType, fn as _fnType } from 'sequelize';\nimport type { Simplify } from 'type-fest';\nimport type { RuleProcessor } from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport { isValidValue, processMatchMode, shouldRenderAsNumber } from './utils';\n\ntype OpTypes = Simplify<typeof _OpTypes>;\ntype ColType = typeof _colType;\ntype FnType = typeof _fnType;\n\n/**\n * Default rule processor used by {@link formatQuery} for the \"sequelize\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorSequelize: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  { parseNumbers, preserveValueOrder, context = {} } = {}\n): Record<string, unknown> | undefined => {\n  const {\n    sequelizeOperators: Op,\n    sequelizeCol: col,\n    sequelizeFn: fn,\n  } = context as {\n    sequelizeOperators: OpTypes;\n    sequelizeCol?: ColType;\n    sequelizeFn?: FnType;\n  };\n\n  // Match modes are not supported in this format\n  if (processMatchMode(rule)) return undefined;\n\n  const { field, operator, value, valueSource } = rule;\n  const valueIsField = valueSource === 'field';\n\n  const operatorLC = lc(operator);\n\n  if (\n    // Bail out if we don't have the Op symbols\n    !Op ||\n    // ...or valueSource is 'field' and we don't have the `col` function,\n    (valueIsField &&\n      (!col ||\n        // ...or valueSource is 'field' and we don't have the `fn` function\n        // and the operator is a string-matching one\n        (!fn &&\n          [\n            'contains',\n            'doesnotcontain',\n            'beginswith',\n            'doesnotbeginwith',\n            'endswith',\n            'doesnotendwith',\n          ].includes(operatorLC))))\n  ) {\n    return undefined;\n  }\n\n  switch (operatorLC) {\n    case '=':\n    case '!=':\n    case '<':\n    case '<=':\n    case '>':\n    case '>=': {\n      const sequelizeOperator = {\n        '=': Op.eq,\n        '!=': Op.ne,\n        '<': Op.lt,\n        '<=': Op.lte,\n        '>': Op.gt,\n        '>=': Op.gte,\n      }[operatorLC];\n      return {\n        [field]:\n          valueIsField && operatorLC === '='\n            ? { [Op.col]: value }\n            : {\n                [sequelizeOperator]: valueIsField\n                  ? col!(value)\n                  : shouldRenderAsNumber(value, parseNumbers)\n                    ? parseNumber(value, { parseNumbers: 'strict' })\n                    : value,\n              },\n      };\n    }\n\n    case 'contains':\n      return {\n        [field]: {\n          [valueIsField ? Op.like : Op.substring]: valueIsField\n            ? fn!('CONCAT', '%', col!(value), '%')\n            : `${value}`,\n        },\n      };\n\n    case 'beginswith':\n      return {\n        [field]: {\n          [valueIsField ? Op.like : Op.startsWith]: valueIsField\n            ? fn!('CONCAT', col!(value), '%')\n            : `${value}`,\n        },\n      };\n\n    case 'endswith':\n      return {\n        [field]: {\n          [valueIsField ? Op.like : Op.endsWith]: valueIsField\n            ? fn!('CONCAT', '%', col!(value))\n            : `${value}`,\n        },\n      };\n\n    case 'doesnotcontain':\n      return {\n        [field]: {\n          [Op.notLike]: valueIsField ? fn!('CONCAT', '%', col!(value), '%') : `%${value}%`,\n        },\n      };\n\n    case 'doesnotbeginwith':\n      return {\n        [field]: { [Op.notLike]: valueIsField ? fn!('CONCAT', col!(value), '%') : `${value}%` },\n      };\n\n    case 'doesnotendwith':\n      return {\n        [field]: { [Op.notLike]: valueIsField ? fn!('CONCAT', '%', col!(value)) : `%${value}` },\n      };\n\n    case 'null':\n      return { [field]: { [Op.is]: null } };\n\n    case 'notnull':\n      return { [field]: { [Op.not]: null } };\n\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value);\n      return {\n        [field]: {\n          [operatorLC === 'in' ? Op.in : Op.notIn]: valueAsArray.map(val =>\n            valueIsField\n              ? col!(val)\n              : shouldRenderAsNumber(val, parseNumbers)\n                ? parseNumber(val, { parseNumbers: 'strict' })\n                : val\n          ),\n        },\n      };\n    }\n\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value, { retainEmptyStrings: true });\n      if (\n        valueAsArray.length < 2 ||\n        !isValidValue(valueAsArray[0]) ||\n        !isValidValue(valueAsArray[1])\n      ) {\n        return undefined;\n      }\n\n      const [first, second] = valueAsArray;\n\n      const firstNum = shouldRenderAsNumber(first, parseNumbers)\n        ? parseNumber(first, { parseNumbers: 'strict' })\n        : Number.NaN;\n      const secondNum = shouldRenderAsNumber(second, parseNumbers)\n        ? parseNumber(second, { parseNumbers: 'strict' })\n        : Number.NaN;\n      const firstValue = Number.isNaN(firstNum) ? first : firstNum;\n      const secondValue = Number.isNaN(secondNum) ? second : secondNum;\n      const valsOneAndTwoOnly = [firstValue, secondValue];\n      if (\n        !preserveValueOrder &&\n        firstValue === firstNum &&\n        secondValue === secondNum &&\n        secondNum < firstNum\n      ) {\n        valsOneAndTwoOnly[0] = secondNum;\n        valsOneAndTwoOnly[1] = firstNum;\n      }\n\n      return {\n        [field]: {\n          [operatorLC === 'between' ? Op.between : Op.notBetween]: valueIsField\n            ? valsOneAndTwoOnly.map(v => col!(v))\n            : valsOneAndTwoOnly.every(v => shouldRenderAsNumber(v, parseNumbers))\n              ? valsOneAndTwoOnly.map(v => parseNumber(v, { parseNumbers: 'strict' }))\n              : valsOneAndTwoOnly,\n        },\n      };\n    }\n  }\n  return undefined;\n};\n","import type { RuleProcessor } from '../../types';\nimport { toArray, trimIfString } from '../arrayUtils';\nimport { shouldRenderAsNumber } from './utils';\n\nconst escapeDoubleQuotes = (v: unknown, escapeQuotes?: boolean) =>\n  typeof v !== 'string' || !escapeQuotes ? `${v}` : v.replaceAll(`\"`, `\\\\\"`);\n\n/** Auto-prefix a SPARQL variable name with `?` unless it's already prefixed, a URI, or a prefixed name.\n *\n * @group Export\n */\nexport const sparqlVar = (name: string): string =>\n  /^[?<]/.test(name) || name.includes(':') ? name : `?${name}`;\n\n/**\n * Default rule processor used by {@link formatQuery} for \"sparql\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorSPARQL: RuleProcessor = (\n  rule,\n  // v8 ignore next\n  opts = {}\n) => {\n  const { escapeQuotes, parseNumbers } = opts;\n  const { field: rawField, operator, value, valueSource } = rule;\n  const valueIsField = valueSource === 'field';\n  const operatorTL = operator.toLowerCase();\n  const field = sparqlVar(rawField);\n\n  const fmtVal = (v: unknown): string => {\n    if (v === null || v === undefined) return '\"\"';\n    if (typeof v === 'boolean') return `\"${v}\"^^xsd:boolean`;\n    if (typeof v === 'bigint') return String(v);\n    if (valueIsField) return sparqlVar(trimIfString(v) as string);\n    if (typeof v === 'number' || shouldRenderAsNumber(v, parseNumbers))\n      return trimIfString(v) as string;\n    /* v8 ignore start -- @preserve */\n    const s = typeof v === 'string' ? v : (JSON.stringify(v) ?? '');\n    /* v8 ignore stop -- @preserve */\n    // Don't quote variable references or URIs\n    if (s.startsWith('?') || s.startsWith('<') || s.includes(':')) return s;\n    return `\"${escapeDoubleQuotes(s, escapeQuotes)}\"`;\n  };\n\n  switch (operatorTL) {\n    case '=':\n    case '!=':\n    case '<':\n    case '>':\n    case '<=':\n    case '>=':\n      return `${field} ${operatorTL} ${fmtVal(value)}`;\n    case '<>':\n      return `${field} != ${fmtVal(value)}`;\n    case 'contains':\n      return `CONTAINS(${field}, ${fmtVal(value)})`;\n    case 'doesnotcontain':\n      return `!CONTAINS(${field}, ${fmtVal(value)})`;\n    case 'beginswith':\n      return `STRSTARTS(${field}, ${fmtVal(value)})`;\n    case 'doesnotbeginwith':\n      return `!STRSTARTS(${field}, ${fmtVal(value)})`;\n    case 'endswith':\n      return `STRENDS(${field}, ${fmtVal(value)})`;\n    case 'doesnotendwith':\n      return `!STRENDS(${field}, ${fmtVal(value)})`;\n    case 'null':\n      return `!BOUND(${field})`;\n    case 'notnull':\n      return `BOUND(${field})`;\n    case 'in': {\n      const items = toArray(value).map(fmtVal);\n      if (!items.length) return '';\n      return `${field} IN (${items.join(', ')})`;\n    }\n    case 'notin': {\n      const items = toArray(value).map(fmtVal);\n      if (!items.length) return '';\n      return `${field} NOT IN (${items.join(', ')})`;\n    }\n    case 'between': {\n      const arr = toArray(value);\n      if (arr.length < 2) return '';\n      return `${field} >= ${fmtVal(arr[0])} && ${field} <= ${fmtVal(arr[1])}`;\n    }\n    case 'notbetween': {\n      const arr = toArray(value);\n      if (arr.length < 2) return '';\n      return `(${field} < ${fmtVal(arr[0])} || ${field} > ${fmtVal(arr[1])})`;\n    }\n    default:\n      return `${field} ${operator} ${fmtVal(value)}`;\n  }\n};\n","import type { RuleProcessor } from '../../types';\nimport { toArray } from '../arrayUtils';\nimport { lc } from '../misc';\nimport { parseNumber } from '../parseNumber';\nimport type { TsDbExpression } from './tanStackDbTypes.ts';\nimport { isValidValue, shouldRenderAsNumber } from './utils';\n\n/**\n * Default rule processor used by {@link formatQuery} for the \"tanstack_db\" format.\n *\n * @group Export\n */\nexport const defaultRuleProcessorTanStackDB: RuleProcessor = (\n  rule,\n  _options\n): TsDbExpression | undefined => {\n  const opts = _options ?? /* v8 ignore start -- @preserve */ {}; /* v8 ignore stop -- @preserve */\n  const { parseNumbers, preserveValueOrder, context = {} } = opts;\n  const ops = context.tanStackDbOperators;\n  const refs = context._tanstackDbRefs;\n  const primaryRef: string | undefined = context._tanstackDbPrimaryRef;\n\n  if (!ops || !refs || !primaryRef) return undefined;\n\n  const { and, eq, gt, gte, inArray, isNull, like, lt, lte, not } = ops;\n\n  // Resolve a field name to a ref column:\n  // - Dotted: \"todo.age\" → refs.todo.age\n  // - Bare: \"age\" → refs[primaryRef].age\n  const resolveField = (fieldName: string) => {\n    const dotIdx = fieldName.indexOf('.');\n    if (dotIdx > 0) {\n      const prefix = fieldName.slice(0, dotIdx);\n      const rest = fieldName.slice(dotIdx + 1);\n      if (refs[prefix]) return refs[prefix][rest];\n    }\n    // Bare field: use primary ref\n    return refs[primaryRef][fieldName];\n  };\n\n  const { field, operator, value, valueSource } = rule;\n  const column = resolveField(field);\n  const operatorLC = lc(operator);\n\n  const valueIsField = valueSource === 'field';\n  const asFieldOrValue = (v: unknown) => (valueIsField ? resolveField(v as string) : v);\n\n  // Parse value as number when applicable\n  const maybeParseNumber = (v: unknown) => {\n    if (valueIsField || !parseNumbers) return asFieldOrValue(v);\n    return shouldRenderAsNumber(v, true) ? parseNumber(v, { parseNumbers: true }) : v;\n  };\n\n  switch (operatorLC) {\n    case '=':\n      return eq(column, maybeParseNumber(value));\n    case '!=':\n      return not(eq(column, maybeParseNumber(value)));\n    case '>':\n      return gt(column, maybeParseNumber(value));\n    case '<':\n      return lt(column, maybeParseNumber(value));\n    case '>=':\n      return gte(column, maybeParseNumber(value));\n    case '<=':\n      return lte(column, maybeParseNumber(value));\n    case 'beginswith':\n    case 'doesnotbeginwith': {\n      const pattern = valueIsField ? undefined : `${value}%`;\n      const expr = like(column, pattern);\n      return operatorLC === 'doesnotbeginwith' ? not(expr) : expr;\n    }\n    case 'contains':\n    case 'doesnotcontain': {\n      const pattern = valueIsField ? undefined : `%${value}%`;\n      const expr = like(column, pattern);\n      return operatorLC === 'doesnotcontain' ? not(expr) : expr;\n    }\n    case 'endswith':\n    case 'doesnotendwith': {\n      const pattern = valueIsField ? undefined : `%${value}`;\n      const expr = like(column, pattern);\n      return operatorLC === 'doesnotendwith' ? not(expr) : expr;\n    }\n    case 'null':\n      return isNull(column);\n    case 'notnull':\n      return not(isNull(column));\n    case 'in':\n    case 'notin': {\n      const valueAsArray = toArray(value).map(v => maybeParseNumber(v));\n      const expr = inArray(column, valueAsArray);\n      return operatorLC === 'notin' ? not(expr) : expr;\n    }\n    case 'between':\n    case 'notbetween': {\n      const valueAsArray = toArray(value);\n      if (\n        valueAsArray.length >= 2 &&\n        isValidValue(valueAsArray[0]) &&\n        isValidValue(valueAsArray[1])\n      ) {\n        let [first, second] = valueAsArray;\n        const shouldParseNumbers = !(parseNumbers === false);\n        if (\n          !valueIsField &&\n          shouldRenderAsNumber(first, shouldParseNumbers) &&\n          shouldRenderAsNumber(second, shouldParseNumbers)\n        ) {\n          const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });\n          const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });\n          if (!preserveValueOrder && secondNum < firstNum) {\n            const tempNum = secondNum;\n            second = firstNum;\n            first = tempNum;\n          } else {\n            first = firstNum;\n            second = secondNum;\n          }\n        } else if (valueIsField) {\n          first = asFieldOrValue(first);\n          second = asFieldOrValue(second);\n        }\n        const expr = and(gte(column, first), lte(column, second));\n        return operatorLC === 'notbetween' ? not(expr) : expr;\n      }\n      return undefined;\n    }\n    default:\n      return undefined;\n  }\n};\n","import type { SetOptional } from 'type-fest';\nimport { defaultPlaceholderFieldName, defaultPlaceholderOperatorName } from '../../defaults';\nimport type {\n  DiagnosticsResult,\n  ExportFormat,\n  ExportObjectFormats,\n  FormatQueryFinalOptions,\n  FormatQueryOptions,\n  FullField,\n  FullOperator,\n  FullOptionList,\n  InputType,\n  ParameterizedNamedSQL,\n  ParameterizedSQL,\n  RQBJsonLogic,\n  RuleGroupProcessor,\n  RuleGroupTypeAny,\n  RuleProcessor,\n  RuleType,\n  RuleValidator,\n  SQLPreset,\n  ValidationMap,\n  ValidationResult,\n  ValueProcessorByRule,\n} from '../../types';\nimport { getParseNumberMethod } from '../getParseNumberMethod';\nimport { lc } from '../misc';\nimport { getOption, toFlatOptionArray, toFullOptionList } from '../optGroupUtils';\nimport { defaultRuleGroupProcessorCEL } from './defaultRuleGroupProcessorCEL';\nimport { defaultRuleGroupProcessorCypher } from './defaultRuleGroupProcessorCypher';\nimport { defaultRuleGroupProcessorDiagnostics } from './defaultRuleGroupProcessorDiagnostics';\nimport { defaultRuleGroupProcessorDrizzle } from './defaultRuleGroupProcessorDrizzle';\nimport { defaultRuleGroupProcessorElasticSearch } from './defaultRuleGroupProcessorElasticSearch';\nimport { defaultRuleGroupProcessorGremlin } from './defaultRuleGroupProcessorGremlin';\nimport { defaultRuleGroupProcessorJSONata } from './defaultRuleGroupProcessorJSONata';\nimport { defaultRuleGroupProcessorJsonLogic } from './defaultRuleGroupProcessorJsonLogic';\nimport { defaultRuleGroupProcessorLDAP } from './defaultRuleGroupProcessorLDAP';\nimport { defaultRuleGroupProcessorMongoDB } from './defaultRuleGroupProcessorMongoDB';\nimport {\n  defaultRuleGroupProcessorMongoDBQuery,\n  mongoDbFallback,\n} from './defaultRuleGroupProcessorMongoDBQuery';\nimport { defaultRuleGroupProcessorNL } from './defaultRuleGroupProcessorNL';\nimport { defaultRuleGroupProcessorParameterized } from './defaultRuleGroupProcessorParameterized';\nimport { defaultRuleGroupProcessorPrisma, prismaFallback } from './defaultRuleGroupProcessorPrisma';\nimport { defaultRuleGroupProcessorSequelize } from './defaultRuleGroupProcessorSequelize';\nimport { defaultRuleGroupProcessorSPARQL } from './defaultRuleGroupProcessorSPARQL';\nimport { defaultRuleGroupProcessorSpEL } from './defaultRuleGroupProcessorSpEL';\nimport { defaultRuleGroupProcessorSQL } from './defaultRuleGroupProcessorSQL';\nimport { defaultRuleGroupProcessorTanStackDB } from './defaultRuleGroupProcessorTanStackDB';\nimport { defaultRuleProcessorCEL } from './defaultRuleProcessorCEL';\nimport { defaultRuleProcessorCypher } from './defaultRuleProcessorCypher';\nimport { defaultRuleProcessorDrizzle } from './defaultRuleProcessorDrizzle';\nimport { defaultRuleProcessorElasticSearch } from './defaultRuleProcessorElasticSearch';\nimport { defaultRuleProcessorGremlin } from './defaultRuleProcessorGremlin';\nimport { defaultRuleProcessorJSONata } from './defaultRuleProcessorJSONata';\nimport { defaultRuleProcessorJsonLogic } from './defaultRuleProcessorJsonLogic';\nimport { defaultRuleProcessorLDAP } from './defaultRuleProcessorLDAP';\nimport { defaultRuleProcessorMongoDB } from './defaultRuleProcessorMongoDB';\nimport { defaultRuleProcessorMongoDBQuery } from './defaultRuleProcessorMongoDBQuery';\nimport { defaultOperatorProcessorNL, defaultRuleProcessorNL } from './defaultRuleProcessorNL';\nimport { defaultRuleProcessorParameterized } from './defaultRuleProcessorParameterized';\nimport { defaultRuleProcessorPrisma } from './defaultRuleProcessorPrisma';\nimport { defaultRuleProcessorSequelize } from './defaultRuleProcessorSequelize';\nimport { defaultRuleProcessorSPARQL } from './defaultRuleProcessorSPARQL';\nimport { defaultRuleProcessorSpEL } from './defaultRuleProcessorSpEL';\nimport { defaultOperatorProcessorSQL, defaultRuleProcessorSQL } from './defaultRuleProcessorSQL';\nimport { defaultRuleProcessorTanStackDB } from './defaultRuleProcessorTanStackDB';\nimport { defaultValueProcessorByRule } from './defaultValueProcessorByRule';\nimport { defaultValueProcessorNL } from './defaultValueProcessorNL';\nimport {\n  bigIntJsonStringifyReplacer,\n  getQuoteFieldNamesWithArray,\n  isValueProcessorLegacy,\n  numerifyValues,\n  stripParamPrefix,\n} from './utils';\n\n/**\n * A collection of option presets for {@link formatQuery}, specifically for SQL-based formats.\n *\n * @group Export\n */\nexport const sqlDialectPresets: Record<SQLPreset, FormatQueryOptions> = {\n  ansi: {}, // This should always be empty\n  sqlite: {\n    paramsKeepPrefix: true,\n  },\n  oracle: {},\n  mssql: {\n    concatOperator: '+',\n    quoteFieldNamesWith: ['[', ']'],\n    fieldIdentifierSeparator: '.',\n    paramPrefix: '@',\n  },\n  mysql: {\n    concatOperator: 'CONCAT',\n  },\n  postgresql: {\n    quoteFieldNamesWith: '\"',\n    numberedParams: true,\n    paramPrefix: '$',\n  },\n};\n\n/**\n * A collection of option presets for {@link formatQuery}.\n *\n * @group Export\n */\nexport const formatQueryOptionPresets: Record<string, FormatQueryOptions> = {\n  ...sqlDialectPresets,\n};\n\nconst defaultRuleProcessors = {\n  cel: defaultRuleProcessorCEL,\n  drizzle: defaultRuleProcessorDrizzle,\n  elasticsearch: defaultRuleProcessorElasticSearch,\n  json_without_ids: defaultRuleProcessorSQL,\n  json: defaultRuleProcessorSQL,\n  jsonata: defaultRuleProcessorJSONata,\n  jsonlogic: defaultRuleProcessorJsonLogic,\n  ldap: defaultRuleProcessorLDAP,\n  mongodb_query: defaultRuleProcessorMongoDBQuery,\n  mongodb: defaultRuleProcessorMongoDB,\n  natural_language: defaultRuleProcessorNL,\n  parameterized_named: defaultRuleProcessorParameterized,\n  parameterized: defaultRuleProcessorParameterized,\n  prisma: defaultRuleProcessorPrisma,\n  sequelize: defaultRuleProcessorSequelize,\n  spel: defaultRuleProcessorSpEL,\n  sql: defaultRuleProcessorSQL,\n  tanstack_db: defaultRuleProcessorTanStackDB,\n  cypher: defaultRuleProcessorCypher,\n  gql: defaultRuleProcessorCypher,\n  sparql: defaultRuleProcessorSPARQL,\n  gremlin: defaultRuleProcessorGremlin,\n  diagnostics: defaultRuleProcessorSQL,\n} satisfies Record<ExportFormat, RuleProcessor>;\n\n/* v8 ignore next -- @preserve */\nconst defaultOperatorProcessor: RuleProcessor = r => r.operator;\nconst defaultOperatorProcessors = {\n  cel: defaultOperatorProcessor,\n  drizzle: defaultOperatorProcessor,\n  elasticsearch: defaultOperatorProcessor,\n  json_without_ids: defaultOperatorProcessor,\n  json: defaultOperatorProcessor,\n  jsonata: defaultOperatorProcessor,\n  jsonlogic: defaultOperatorProcessor,\n  ldap: defaultOperatorProcessor,\n  mongodb_query: defaultOperatorProcessor,\n  mongodb: defaultOperatorProcessor,\n  natural_language: defaultOperatorProcessorNL,\n  parameterized_named: defaultOperatorProcessorSQL,\n  parameterized: defaultOperatorProcessorSQL,\n  prisma: defaultOperatorProcessor,\n  sequelize: defaultOperatorProcessor,\n  spel: defaultOperatorProcessor,\n  sql: defaultOperatorProcessorSQL,\n  tanstack_db: defaultOperatorProcessor,\n  cypher: defaultOperatorProcessor,\n  gql: defaultOperatorProcessor,\n  sparql: defaultOperatorProcessor,\n  gremlin: defaultOperatorProcessor,\n  diagnostics: defaultOperatorProcessor,\n} satisfies Record<ExportFormat, RuleProcessor>;\n\nconst defaultFallbackExpressions: Partial<Record<ExportFormat, string>> = {\n  cel: '1 == 1',\n  ldap: '',\n  mongodb: '\"$and\":[{\"$expr\":true}]',\n  natural_language: '1 is 1',\n  sparql: '1 = 1',\n  gremlin: '',\n  spel: '1 == 1',\n  sql: '(1 = 1)',\n};\n\ntype MostFormatQueryOptions = SetOptional<\n  Required<FormatQueryOptions>,\n  | 'context'\n  | 'fallbackExpression'\n  | 'operatorProcessor'\n  | 'ruleGroupProcessor'\n  | 'ruleProcessor'\n  | 'validator'\n  | 'valueProcessor'\n  | 'placeholderValueName'\n  | 'parseNumbers'\n  | 'getParameters'\n>;\n\nconst defaultFormatQueryOptions = {\n  format: 'json',\n  fields: [] as FullOptionList<FullField>,\n  quoteFieldNamesWith: ['', ''],\n  fieldIdentifierSeparator: '',\n  getOperators: () => [] as FullOptionList<FullOperator>,\n  paramPrefix: ':',\n  paramsKeepPrefix: false,\n  numberedParams: false,\n  preserveValueOrder: false,\n  placeholderFieldName: defaultPlaceholderFieldName,\n  placeholderOperatorName: defaultPlaceholderOperatorName,\n  quoteValuesWith: \"'\",\n  concatOperator: '||',\n  preset: 'ansi',\n  wordOrder: 'SVO',\n  translations: {},\n  operatorMap: {},\n} satisfies MostFormatQueryOptions;\n\nconst valueProcessorCanActAsRuleProcessor = new Set<ExportFormat>([\n  'cel',\n  'drizzle',\n  'elasticsearch',\n  'jsonata',\n  'jsonlogic',\n  'ldap',\n  'mongodb_query',\n  'mongodb',\n  'prisma',\n  'sequelize',\n  'spel',\n  'tanstack_db',\n]);\n\nconst sqlFormats = new Set<ExportFormat>([\n  'sql',\n  'parameterized',\n  'parameterized_named',\n  'drizzle',\n  'prisma',\n  'sequelize',\n]);\n\n/**\n * Generates a formatted (indented two spaces) JSON string from a query object.\n *\n * @group Export\n */\nfunction formatQuery(ruleGroup: RuleGroupTypeAny): string;\n/**\n * Generates a result based on the provided rule group processor.\n *\n * @group Export\n */\nfunction formatQuery<TResult = unknown>(\n  ruleGroup: RuleGroupTypeAny,\n  options: FormatQueryOptions & { ruleGroupProcessor: RuleGroupProcessor<TResult> }\n): TResult;\n/**\n * Generates a {@link index!ParameterizedSQL ParameterizedSQL} object from a query object.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'parameterized' | (FormatQueryOptions & { format: 'parameterized' })\n): ParameterizedSQL;\n/**\n * Generates a {@link index!ParameterizedNamedSQL ParameterizedNamedSQL} object from a query object.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'parameterized_named' | (FormatQueryOptions & { format: 'parameterized_named' })\n): ParameterizedNamedSQL;\n/**\n * Generates a {@link index!RQBJsonLogic JsonLogic} object from a query object.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'jsonlogic' | (FormatQueryOptions & { format: 'jsonlogic' })\n): RQBJsonLogic;\n/**\n * Generates an ElasticSearch query object from an RQB query object.\n *\n * NOTE: Support for the ElasticSearch format is experimental.\n * You may have better results exporting \"sql\" format then using\n * [ElasticSearch SQL](https://www.elastic.co/guide/en/elasticsearch/reference/current/xpack-sql.html).\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'elasticsearch' | (FormatQueryOptions & { format: 'elasticsearch' })\n  // oxlint-disable-next-line typescript/no-explicit-any\n): Record<string, any>;\n/**\n * Generates a MongoDB query object from an RQB query object.\n *\n * This is equivalent to the \"mongodb\" format, but returns a JSON object\n * instead of a string.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'mongodb_query' | (FormatQueryOptions & { format: 'mongodb_query' })\n  // oxlint-disable-next-line typescript/no-explicit-any\n): Record<string, any>;\n/**\n * Generates a JSON.stringify'd MongoDB query object from an RQB query object.\n *\n * This is equivalent to the \"mongodb_query\" format, but returns a string\n * instead of a JSON object.\n *\n * @deprecated Use the \"mongodb_query\" format for greater flexibility.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'mongodb' | (FormatQueryOptions & { format: 'mongodb' })\n): string;\n/**\n * Generates a Prisma ORM query object from an RQB query object.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'prisma' | (FormatQueryOptions & { format: 'prisma' })\n  // oxlint-disable-next-line typescript/no-explicit-any\n): Record<string, any>;\n/**\n * Generates a Drizzle ORM query function from an RQB query object. The function can\n * be assigned to the `where` property in the Drizzle relational queries API.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'drizzle' | (FormatQueryOptions & { format: 'drizzle' })\n): ReturnType<typeof defaultRuleGroupProcessorDrizzle>;\n/**\n * Generates a TanStack DB WhereCallback from an RQB query object. The callback can\n * be passed directly to TanStack DB's `.where()` method.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'tanstack_db' | (FormatQueryOptions & { format: 'tanstack_db' })\n): ReturnType<typeof defaultRuleGroupProcessorTanStackDB>;\n/**\n * be assigned to the `where` property in the Sequelize query functions.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'sequelize' | (FormatQueryOptions & { format: 'sequelize' })\n): ReturnType<typeof defaultRuleGroupProcessorSequelize>;\n/**\n * Generates a JSONata query string from an RQB query object.\n *\n * NOTE: Either `parseNumbers: \"strict-limited\"` or `parseNumbers: true`\n * are recommended for this format.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'jsonata' | (FormatQueryOptions & { format: 'jsonata' })\n): string;\n/**\n * Generates an LDAP query string from an RQB query object.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'ldap' | (FormatQueryOptions & { format: 'ldap' })\n): string;\n/**\n * Generates a {@link DiagnosticsResult} from a query object, containing an annotated\n * query tree, a flat diagnostics array, aggregate stats, and a per-field summary.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: 'diagnostics' | (FormatQueryOptions & { format: 'diagnostics' })\n): DiagnosticsResult;\n/**\n * Generates a formatted (indented two spaces) JSON string from a query object.\n *\n * @group Export\n */\nfunction formatQuery(ruleGroup: RuleGroupTypeAny, options: FormatQueryOptions): string;\n/**\n * Generates a query string in the requested format.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: Exclude<ExportFormat, ExportObjectFormats>\n): string;\n/**\n * Generates a query string in the requested format.\n *\n * @group Export\n */\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  options: FormatQueryOptions & { format: Exclude<ExportFormat, ExportObjectFormats> }\n): string;\nfunction formatQuery(\n  ruleGroup: RuleGroupTypeAny,\n  optionParam: FormatQueryOptions | ExportFormat = {}\n) {\n  const options = typeof optionParam === 'string' ? { format: lc(optionParam) } : optionParam;\n\n  const optObj: MostFormatQueryOptions = {\n    ...defaultFormatQueryOptions,\n    ...(!options.format || sqlFormats.has(options.format)\n      ? (sqlDialectPresets[options.preset ?? 'ansi'] ?? null)\n      : null),\n    ...options,\n    ...(!options.format &&\n      (Object.keys(sqlDialectPresets).includes(options.preset ?? '') ? { format: 'sql' } : null)),\n  };\n\n  const format = lc(optObj.format);\n\n  const {\n    fallbackExpression: fallbackExpression_option,\n    getOperators: getOperators_option,\n    operatorProcessor: operatorProcessor_option,\n    parseNumbers,\n    quoteFieldNamesWith: quoteFieldNamesWith_option,\n    ruleGroupProcessor: ruleGroupProcessor_option,\n    ruleProcessor: ruleProcessor_option,\n    validator,\n    valueProcessor: valueProcessor_option,\n    context,\n  } = optObj;\n\n  const getParseNumberBoolean = (inputType?: InputType | null): boolean | undefined => {\n    const parseNumberMethod = getParseNumberMethod({ parseNumbers, inputType });\n    return typeof parseNumberMethod === 'string'\n      ? true\n      : typeof parseNumbers === 'boolean'\n        ? parseNumbers\n        : undefined;\n  };\n\n  const operatorProcessor =\n    typeof operatorProcessor_option === 'function'\n      ? operatorProcessor_option\n      : (defaultOperatorProcessors[format] ?? defaultOperatorProcessor);\n\n  const valueProcessor: ValueProcessorByRule =\n    typeof valueProcessor_option === 'function'\n      ? isValueProcessorLegacy(valueProcessor_option)\n        ? r => valueProcessor_option(r.field, r.operator, r.value, r.valueSource)\n        : valueProcessor_option\n      : format === 'natural_language'\n        ? defaultValueProcessorNL\n        : valueProcessorCanActAsRuleProcessor.has(format)\n          ? (ruleProcessor_option ?? defaultRuleProcessors[format])\n          : defaultValueProcessorByRule;\n\n  const ruleProcessor =\n    (typeof ruleProcessor_option === 'function' ? ruleProcessor_option : null) ??\n    (valueProcessorCanActAsRuleProcessor.has(format) &&\n    typeof ruleProcessor_option !== 'function' &&\n    valueProcessor_option\n      ? valueProcessor\n      : null) ??\n    defaultRuleProcessors[format] ??\n    defaultRuleProcessorSQL;\n\n  const quoteFieldNamesWith = getQuoteFieldNamesWithArray(quoteFieldNamesWith_option);\n  const fields = toFullOptionList(optObj.fields);\n  const getOperators: FormatQueryOptions['getOperators'] = (f, m) =>\n    toFullOptionList(\n      getOperators_option(f, m) ??\n        /* v8 ignore start -- @preserve */ [] /* v8 ignore stop -- @preserve */\n    );\n\n  const fallbackExpression =\n    fallbackExpression_option ??\n    defaultFallbackExpressions[format] ??\n    defaultFallbackExpressions.sql!;\n\n  // #region Validation\n  let validationMap: ValidationMap = {};\n\n  // v8 ignore else\n  if (typeof validator === 'function') {\n    const validationResult = validator(ruleGroup);\n    if (typeof validationResult === 'boolean') {\n      // v8 ignore else\n      if (!validationResult) {\n        // The \"diagnostics\" format still annotates the full tree\n        // when the validator returns `false`.\n        if (format !== 'diagnostics') {\n          return format === 'parameterized'\n            ? { sql: fallbackExpression, params: [] }\n            : format === 'parameterized_named'\n              ? { sql: fallbackExpression, params: {} }\n              : format === 'mongodb'\n                ? `{${fallbackExpression}}`\n                : format === 'mongodb_query'\n                  ? mongoDbFallback\n                  : format === 'prisma'\n                    ? prismaFallback\n                    : format === 'jsonlogic'\n                      ? false\n                      : format === 'elasticsearch'\n                        ? {}\n                        : format === 'drizzle' || format === 'sequelize' || format === 'tanstack_db'\n                          ? undefined\n                          : fallbackExpression;\n        }\n      }\n    } else {\n      validationMap = validationResult;\n    }\n  }\n\n  const validatorMap: Record<string, RuleValidator> = {};\n  const uniqueFields = toFlatOptionArray(fields) satisfies FullField[];\n  for (const f of uniqueFields) {\n    // v8 ignore else\n    if (typeof f.validator === 'function') {\n      validatorMap[\n        f.value ?? /* v8 ignore start -- @preserve */ f.name /* v8 ignore stop -- @preserve */\n      ] = f.validator as RuleValidator;\n    }\n  }\n\n  const validateRule = (rule: RuleType) => {\n    let validationResult: boolean | ValidationResult | undefined;\n    let fieldValidator: RuleValidator | undefined;\n    if (rule.id) {\n      validationResult = validationMap[rule.id];\n    }\n    if (uniqueFields.length > 0) {\n      const fieldArr = uniqueFields.filter(f => f.name === rule.field);\n      if (fieldArr.length > 0) {\n        const field = fieldArr[0];\n        // v8 ignore else\n        if (typeof field.validator === 'function') {\n          fieldValidator = field.validator as RuleValidator;\n        }\n      }\n    }\n    // Invalidate rules referencing an unknown named parameter\n    if (rule.valueSource === 'parameter' && typeof optObj.getParameters === 'function') {\n      const fieldData = getOption(fields, rule.field) as FullField;\n      const validParamNames = new Set(\n        toFlatOptionArray(\n          toFullOptionList(optObj.getParameters(rule.field, rule.operator, { fieldData }))\n        ).map(p => stripParamPrefix(p.value, optObj.paramPrefix))\n      );\n      if (!validParamNames.has(stripParamPrefix(rule.value, optObj.paramPrefix))) {\n        validationResult = false;\n      }\n    }\n    return [validationResult, fieldValidator] as const;\n  };\n  // #endregion\n\n  const finalOptions: FormatQueryFinalOptions = {\n    ...optObj,\n    fallbackExpression,\n    fields,\n    format,\n    getOperators,\n    getParseNumberBoolean,\n    quoteFieldNamesWith,\n    operatorProcessor,\n    ruleProcessor,\n    valueProcessor,\n    validateRule,\n    validationMap,\n    context,\n  };\n\n  if (typeof ruleGroupProcessor_option === 'function') {\n    return ruleGroupProcessor_option(ruleGroup, finalOptions);\n  }\n\n  switch (format) {\n    case 'json':\n    case 'json_without_ids': {\n      const rg = parseNumbers ? numerifyValues(ruleGroup, finalOptions) : ruleGroup;\n      if (format === 'json_without_ids') {\n        return JSON.stringify(rg, (key, value) =>\n          // Remove `id` and `path` keys; leave everything else unchanged.\n          key === 'id' || key === 'path' ? undefined : bigIntJsonStringifyReplacer(key, value)\n        );\n      }\n      return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);\n    }\n\n    case 'sql':\n      return defaultRuleGroupProcessorSQL(ruleGroup, finalOptions);\n\n    case 'parameterized':\n    case 'parameterized_named':\n      return defaultRuleGroupProcessorParameterized(ruleGroup, finalOptions);\n\n    case 'mongodb':\n      return defaultRuleGroupProcessorMongoDB(ruleGroup, finalOptions);\n\n    case 'mongodb_query':\n      return defaultRuleGroupProcessorMongoDBQuery(ruleGroup, finalOptions);\n\n    case 'cel':\n      return defaultRuleGroupProcessorCEL(ruleGroup, finalOptions);\n\n    case 'spel':\n      return defaultRuleGroupProcessorSpEL(ruleGroup, finalOptions);\n\n    case 'jsonata':\n      return defaultRuleGroupProcessorJSONata(ruleGroup, finalOptions);\n\n    case 'jsonlogic':\n      return defaultRuleGroupProcessorJsonLogic(ruleGroup, finalOptions);\n\n    case 'elasticsearch':\n      return defaultRuleGroupProcessorElasticSearch(ruleGroup, finalOptions);\n\n    case 'natural_language':\n      return defaultRuleGroupProcessorNL(ruleGroup, finalOptions);\n\n    case 'ldap':\n      return defaultRuleGroupProcessorLDAP(ruleGroup, finalOptions);\n\n    case 'prisma':\n      return defaultRuleGroupProcessorPrisma(ruleGroup, finalOptions);\n\n    case 'drizzle':\n      return defaultRuleGroupProcessorDrizzle(ruleGroup, finalOptions);\n\n    case 'tanstack_db':\n      return defaultRuleGroupProcessorTanStackDB(ruleGroup, finalOptions);\n\n    case 'sequelize':\n      return defaultRuleGroupProcessorSequelize(ruleGroup, finalOptions);\n\n    case 'cypher':\n    case 'gql':\n      return defaultRuleGroupProcessorCypher(ruleGroup, finalOptions);\n\n    case 'sparql':\n      return defaultRuleGroupProcessorSPARQL(ruleGroup, finalOptions);\n\n    case 'gremlin':\n      return defaultRuleGroupProcessorGremlin(ruleGroup, finalOptions);\n\n    case 'diagnostics':\n      return defaultRuleGroupProcessorDiagnostics(ruleGroup, finalOptions);\n\n    default:\n      return '';\n  }\n}\n\nexport { formatQuery };\n","/**\n * Converts a given query object into one of the supported {@link index!ExportFormat ExportFormat} formats.\n *\n * @module formatQuery\n */\n\nimport type { RuleProcessor, ValueProcessorByRule, ValueProcessorLegacy } from '../../types';\nimport { defaultRuleProcessorCEL } from './defaultRuleProcessorCEL';\nimport { defaultRuleProcessorMongoDB } from './defaultRuleProcessorMongoDB';\nimport { defaultRuleProcessorSpEL } from './defaultRuleProcessorSpEL';\nimport { defaultValueProcessorByRule } from './defaultValueProcessorByRule';\n\nconst generateValueProcessor =\n  (vpbr: ValueProcessorByRule): ValueProcessorLegacy =>\n  (field, operator, value, valueSource) =>\n    vpbr({ field, operator, value, valueSource }, { parseNumbers: false });\n/**\n * Default value processor used by {@link formatQuery} for \"sql\" format.\n *\n * @deprecated Prefer {@link defaultValueProcessorByRule}.\n *\n * @group Export\n */\nexport const defaultValueProcessor: ValueProcessorLegacy = generateValueProcessor(\n  defaultValueProcessorByRule\n);\n/**\n * @deprecated Prefer {@link defaultRuleProcessorMongoDB}.\n *\n * @group Export\n */\nexport const defaultMongoDBValueProcessor: ValueProcessorLegacy = generateValueProcessor(\n  defaultRuleProcessorMongoDB\n);\n/**\n * @deprecated Prefer {@link defaultRuleProcessorCEL}.\n *\n * @group Export\n */\nexport const defaultCELValueProcessor: ValueProcessorLegacy =\n  generateValueProcessor(defaultRuleProcessorCEL);\n/**\n * @deprecated Prefer {@link defaultRuleProcessorSpEL}.\n *\n * @group Export\n */\nexport const defaultSpELValueProcessor: ValueProcessorLegacy =\n  generateValueProcessor(defaultRuleProcessorSpEL);\n\nexport * from './defaultRuleGroupProcessorCEL';\nexport * from './defaultRuleGroupProcessorCypher';\nexport * from './defaultRuleGroupProcessorDrizzle';\nexport * from './defaultRuleGroupProcessorElasticSearch';\nexport * from './defaultRuleGroupProcessorGremlin';\nexport * from './defaultRuleGroupProcessorJSONata';\nexport * from './defaultRuleGroupProcessorJsonLogic';\nexport * from './defaultRuleGroupProcessorLDAP';\nexport * from './defaultRuleGroupProcessorMongoDB';\nexport * from './defaultRuleGroupProcessorMongoDBQuery';\nexport * from './defaultRuleGroupProcessorNL';\nexport * from './defaultRuleGroupProcessorParameterized';\nexport * from './defaultRuleGroupProcessorPrisma';\nexport * from './defaultRuleGroupProcessorSequelize';\nexport * from './defaultRuleGroupProcessorSPARQL';\nexport * from './defaultRuleGroupProcessorSpEL';\nexport * from './defaultRuleGroupProcessorSQL';\nexport * from './defaultRuleGroupProcessorTanStackDB';\nexport * from './defaultRuleGroupProcessorDiagnostics';\nexport * from './defaultRuleProcessorCypher';\nexport * from './defaultRuleProcessorDrizzle';\nexport * from './defaultRuleProcessorElasticSearch';\nexport * from './defaultRuleProcessorGremlin';\nexport * from './defaultRuleProcessorJSONata';\nexport * from './defaultRuleProcessorJsonLogic';\nexport * from './defaultRuleProcessorLDAP';\nexport * from './defaultRuleProcessorMongoDBQuery';\nexport * from './defaultRuleProcessorNL';\nexport * from './defaultRuleProcessorParameterized';\nexport * from './defaultRuleProcessorPrisma';\nexport * from './defaultRuleProcessorSequelize';\nexport * from './defaultRuleProcessorSPARQL';\nexport * from './defaultRuleProcessorSQL';\nexport * from './defaultRuleProcessorTanStackDB';\nexport * from './defaultValueProcessorNL';\nexport * from './formatQuery';\nexport * from './utils';\nexport {\n  defaultRuleProcessorCEL,\n  defaultRuleProcessorMongoDB,\n  defaultRuleProcessorSpEL,\n  defaultValueProcessorByRule,\n};\n/**\n * @deprecated Renamed to {@link defaultRuleProcessorCEL}.\n *\n * @group Export\n */\nexport const defaultValueProcessorCELByRule: RuleProcessor = defaultRuleProcessorCEL;\n/**\n * @deprecated Renamed to {@link defaultRuleProcessorMongoDB}.\n *\n * @group Export\n */\nexport const defaultValueProcessorMongoDBByRule: RuleProcessor = defaultRuleProcessorMongoDB;\n/**\n * @deprecated Renamed to {@link defaultRuleProcessorSpEL}.\n *\n * @group Export\n */\nexport const defaultValueProcessorSpELByRule: RuleProcessor = defaultRuleProcessorSpEL;\n","import type { Path, RuleGroupTypeAny, RuleType } from '../types';\nimport { isRuleGroup } from './isRuleGroup';\nimport { isPojo } from './misc';\n\n/**\n * Return type for {@link findPath}.\n */\nexport type FindPathReturnType = RuleGroupTypeAny | RuleType | null;\n\n/**\n * Returns the {@link RuleType} or {@link RuleGroupType}/{@link RuleGroupTypeIC}\n * at the given path within a query.\n */\nexport const findPath = (path: Path, query: RuleGroupTypeAny): FindPathReturnType => {\n  let target: FindPathReturnType = query;\n  let level = 0;\n  while (level < path.length && target && isRuleGroup(target)) {\n    const t: RuleGroupTypeAny | RuleType | string = target.rules[path[level]];\n    target = typeof t === 'string' ? null : t;\n    level++;\n  }\n\n  return level < path.length ? null : target;\n};\n\n/**\n * Returns the {@link RuleType} or {@link RuleGroupType}/{@link RuleGroupTypeIC}\n * with the given `id` within a query.\n */\nexport const findID = (id: string, query: RuleGroupTypeAny): FindPathReturnType => {\n  if (query.id === id) {\n    return query;\n  }\n\n  for (const rule of query.rules) {\n    if (typeof rule === 'string') continue;\n    if (rule.id === id) {\n      return rule;\n    } else if (isRuleGroup(rule)) {\n      const subRule = findID(id, rule);\n      if (subRule) {\n        return subRule;\n      }\n    }\n  }\n\n  return null;\n};\n\n/**\n * Returns the {@link Path} of the {@link RuleType} or {@link RuleGroupType}/{@link RuleGroupTypeIC}\n * with the given `id` within a query.\n */\nexport const getPathOfID = (id: string, query: RuleGroupTypeAny): Path | null => {\n  if (query.id === id) return [];\n\n  const idx = query.rules.findIndex(r => !(typeof r === 'string') && r.id === id);\n\n  if (idx >= 0) {\n    return [idx];\n  }\n\n  for (const [i, r] of Object.entries(query.rules)) {\n    if (isRuleGroup(r)) {\n      const subPath = getPathOfID(id, r);\n      if (Array.isArray(subPath)) {\n        return [Number.parseInt(i), ...subPath];\n      }\n    }\n  }\n\n  return null;\n};\n\n/**\n * Truncates the last element of an array and returns the result as a new array.\n */\nexport const getParentPath = (path: Path): Path => path.slice(0, -1);\n\n/**\n * Determines if two paths (each `Path`) are equivalent.\n */\nexport const pathsAreEqual = (path1: Path, path2: Path): boolean => {\n  if (path1.length !== path2.length) return false;\n  for (let i = 0; i < path1.length; i++) {\n    if (path1[i] !== path2[i]) return false;\n  }\n  return true;\n};\n\n/**\n * Determines if the first path is an ancestor of the second path. The first path must\n * be shorter and exactly match the second path up through the length of the first path.\n */\nexport const isAncestor = (maybeAncestor: Path, path: Path): boolean => {\n  if (maybeAncestor.length >= path.length) return false;\n  for (let i = 0; i < maybeAncestor.length; i++) {\n    if (maybeAncestor[i] !== path[i]) return false;\n  }\n  return true;\n};\n\n/**\n * Finds the deepest/longest path that two paths have in common.\n */\nexport const getCommonAncestorPath = (path1: Path, path2: Path): Path => {\n  const commonAncestorPath: Path = [];\n  const parentPath1 = getParentPath(path1);\n  const parentPath2 = getParentPath(path2);\n  let i = 0;\n\n  while (i < parentPath1.length && i < parentPath2.length && parentPath1[i] === parentPath2[i]) {\n    commonAncestorPath.push(parentPath2[i]);\n    i++;\n  }\n\n  return commonAncestorPath;\n};\n\n/**\n * Determines if the rule or group at the specified path is either disabled itself\n * or disabled by an ancestor group.\n */\nexport const pathIsDisabled = (path: Path, query: RuleGroupTypeAny): boolean => {\n  let disabled = !!query.disabled;\n  let target: RuleType | RuleGroupTypeAny = query;\n  let level = 0;\n  while (level < path.length && !disabled && isRuleGroup(target)) {\n    const t: RuleGroupTypeAny | RuleType | string = target.rules[path[level]];\n    if (isPojo(t) && (isRuleGroup(t) || ('field' in t && !!t.field))) {\n      disabled = !!t.disabled;\n      target = t;\n    }\n    level++;\n  }\n  return disabled;\n};\n\n/**\n * Determines if the rule or group at the specified path is disabled by `disabledPaths`—the array\n * form of the `QueryBuilder` `disabled` prop, which disables nodes by position rather than by a\n * `disabled` property on the node itself. A path is disabled if it appears in `disabledPaths` or\n * descends from a path that does.\n *\n * @group Paths\n */\nexport const pathIsDisabledByPaths = (path: Path, disabledPaths: Path[] = []): boolean =>\n  disabledPaths.some(p => pathsAreEqual(p, path) || isAncestor(p, path));\n\n/** The path of a child rule or group, and whether it is disabled. */ export interface PathInfo {\n  path: Path;\n  disabled: boolean;\n}\n\n/**\n * Builds the {@link PathInfo} for each child of a group at `path`. A child is disabled if its\n * parent is disabled or if its own path appears in `disabledPaths`.\n *\n * @group Paths\n */\nexport const derivePathInfo = (\n  path: Path,\n  childCount: number,\n  { disabled = false, disabledPaths = [] }: { disabled?: boolean; disabledPaths?: Path[] } = {}\n): PathInfo[] => {\n  const paths: PathInfo[] = [];\n  for (let i = 0; i < childCount; i++) {\n    const thisPath = [...path, i];\n    paths[i] = {\n      path: thisPath,\n      disabled: disabled || disabledPaths.some(p => pathsAreEqual(thisPath, p)),\n    };\n  }\n  return paths;\n};\n","import type { AccessibleDescriptionGenerator as ADG } from '../types';\nimport { pathsAreEqual } from './pathUtils';\n\n/**\n * The default `accessibleDescriptionGenerator`. Produces the `aria-label` for a rule group:\n * `\"Query builder\"` for the root group, `\"Rule group at path 0-1\"` for any other.\n *\n * @group Accessibility\n */\nexport const generateAccessibleDescription: ADG = params =>\n  pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join('-')}`;\n","/* v8 ignore file -- this is fine */\n\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\nconst cryptoModule = globalThis.crypto;\n\nexport const uuidV4regex: RegExp =\n  /^[\\da-f]{8}-[\\da-f]{4}-4[\\da-f]{3}-[89ab][\\da-f]{3}-[\\da-f]{12}$/i;\n\n/**\n * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`\n * when available, otherwise uses an alternate method based on `getRandomValues`.\n * The returned string is guaranteed to match this regex:\n * ```\n * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i\n * ```\n * @returns Valid v4 UUID\n */\n// Default implementation adapted from https://stackoverflow.com/a/68141099/217579\n// v8 ignore next\nexport let generateID = (): UUID =>\n  '00-0-4-2-000'.replaceAll(/[^-]/g, s =>\n    (((Math.random() + Math.trunc(s as unknown as number)) * 0x1_00_00) >> Number.parseInt(s))\n      .toString(16)\n      .padStart(4, '0')\n  ) as UUID;\n\n// Improve on the default implementation by using the crypto package if it's available\n// v8 ignore else\nif (cryptoModule) {\n  // v8 ignore else\n  if (typeof cryptoModule.randomUUID === 'function') {\n    generateID = () => cryptoModule.randomUUID();\n  } else if (typeof cryptoModule.getRandomValues === 'function') {\n    // `randomUUID` is much simpler and faster, but it's only guaranteed to be\n    // available in secure contexts (server-side, https, etc.). `generateID`\n    // doesn't really need to be cryptographically secure, it only needs a\n    // fairly low chance of collisions. We fall back to the always-available\n    // `getRandomValues` here (while still generating a valid v4 UUID) when\n    // `randomUUID` is not available.\n    const position19vals = '89ab';\n    const container = new Uint32Array(32);\n\n    generateID = () => {\n      cryptoModule.getRandomValues(container);\n      let id = (container[0] % 16).toString(16);\n      for (let i = 1; i < 32; i++) {\n        if (i === 12) {\n          id = `${id}${'4'}`;\n        } else if (i === 16) {\n          id = `${id}${position19vals[container[17] % 4]}`;\n        } else {\n          id = `${id}${(container[i] % 16).toString(16)}`;\n        }\n\n        if (i === 7 || i === 11 || i === 15 || i === 19) {\n          id = `${id}${'-'}`;\n        }\n      }\n      return id as UUID;\n    };\n  }\n}\n","import { Immer, produce, setAutoFreeze as immerSetAutoFreeze } from 'immer';\n\n/**\n * Globally enables or disables immer's auto-freeze, i.e. the deep freeze applied to every query\n * returned by {@link add}, {@link update}, {@link remove}, {@link move}, {@link insert}, and\n * {@link group}.\n *\n * Re-exported from immer so that consumers mixing these tools with their own `produce` calls can\n * switch both at once. Prefer the per-call `freeze` option, or the {@link QueryManager} option of\n * the same name, when the change should not be process-wide. A per-call `freeze: false` wins\n * regardless of this setting; a per-call `freeze: true` does not re-enable freezing once this has\n * turned it off, since it selects immer's default instance.\n *\n * @group Query Tools\n */\nexport const setAutoFreeze: (autoFreeze: boolean) => void = immerSetAutoFreeze;\n\n// Immer has no per-call auto-freeze control, so a second instance with auto-freeze disabled\n// serves calls that opt out. `setAutoFreeze` (re-exported from the root) affects the default\n// instance only, which is what a global escape hatch should do.\nconst unfrozenImmer = new Immer({ autoFreeze: false });\n\n/**\n * The `produce` implementation matching the requested freeze behavior.\n *\n * @internal\n */\nexport const producerFor = (freeze = true): typeof produce =>\n  freeze ? produce : unfrozenImmer.produce;\n","import { defaultMatchModes } from '../defaults';\nimport type {\n  FlexibleOption,\n  FullField,\n  GetOptionIdentifierType,\n  MatchMode,\n  MatchModeOptions,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst dummyFD = {\n  name: 'name',\n  value: 'name',\n  matchModes: null,\n  label: 'label',\n};\n\n/**\n * Utility function to get the match modes array for the given\n * field. If the field definition does not define a `matchModes`\n * property, the `getMatchModes` prop is used. Returns\n * `FullOption<MatchMode>[]` of all match modes by default.\n */\nexport const getMatchModesUtil = <F extends FullField>(\n  fieldData: F,\n  getMatchModes?: (\n    field: GetOptionIdentifierType<F>,\n    misc: { fieldData: F }\n  ) => boolean | MatchMode[] | FlexibleOption<MatchMode>[]\n): MatchModeOptions => {\n  // TypeScript doesn't allow it directly, but in practice\n  // `fieldData` can end up being undefined or null. The nullish\n  // coalescing assignment below avoids errors like\n  // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n  const fd = fieldData ? toFullOption(fieldData) : /* v8 ignore next -- @preserve */ dummyFD;\n\n  let matchModes: boolean | MatchMode[] | FlexibleOption<MatchMode>[] = fd.matchModes ?? false;\n\n  if (!matchModes && getMatchModes) {\n    matchModes = getMatchModes(fd.value as GetOptionIdentifierType<F>, {\n      fieldData: fd as F,\n    });\n  }\n\n  if (matchModes === true) {\n    return defaultMatchModes;\n  } else if (matchModes === false) {\n    return [];\n  }\n\n  if (isFlexibleOptionArray(matchModes)) {\n    return toFullOptionList(matchModes) as MatchModeOptions;\n  }\n\n  return (matchModes?.map(\n    mm =>\n      defaultMatchModes.find(dmm => dmm.value === lc(mm)) ?? {\n        name: mm,\n        value: mm,\n        label: mm,\n      }\n  ) ?? []) as MatchModeOptions;\n};\n","import type {\n  FullField,\n  FullOptionList,\n  Option,\n  OptionList,\n  RuleType,\n  ValueEditorType,\n} from '../types';\nimport { joinWith } from './arrayUtils';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { getFirstOption } from './optGroupUtils';\n\n// First option of a list, paired for `between`/`notBetween` operators (array or joined string).\nconst getFirstOptionsFrom = (opts: OptionList, r: RuleType, listsAsArrays?: boolean) => {\n  const firstOption = getFirstOption(opts);\n\n  if (r.operator === 'between' || r.operator === 'notBetween') {\n    const valueAsArray = [firstOption, firstOption];\n    return listsAsArrays\n      ? valueAsArray\n      : joinWith(\n          valueAsArray.map(\n            v => v ?? /* v8 ignore start -- @preserve */ '' /* v8 ignore stop -- @preserve */\n          ),\n          ','\n        );\n  }\n\n  return firstOption;\n};\n\n/** Options for {@link getRuleDefaultValue}. */\nexport interface GetRuleDefaultValueOptions<F extends FullField = FullField> {\n  /** Resolved field configuration for `rule.field` (e.g. `fieldMap[rule.field] ?? {}`). */\n  fieldData: F;\n  /** Full field list, used to seed a comparator-valid field when `valueSource` is `'field'`. */\n  fields: FullOptionList<F>;\n  /** Resolves the editor type for the field/operator (drives select/radio/checkbox defaults). */\n  getValueEditorType: (field: string, operator: string, meta: { fieldData: F }) => ValueEditorType;\n  /** Resolves the value option list for the field/operator. */\n  getValues: (field: string, operator: string, meta: { fieldData: F }) => FullOptionList<Option>;\n  /** Optional escape hatch overriding the computed default. */\n  getDefaultValue?: (rule: RuleType, meta: { fieldData: F }) => unknown;\n  /** Named parameter options, used to seed a default when `valueSource` is `'parameter'`. */\n  getParameters?: (\n    field: string,\n    operator: string,\n    meta: { fieldData: F }\n  ) => FullOptionList<Option> | null;\n  /** When `true`, multi-value defaults are arrays instead of comma-joined strings. */\n  listsAsArrays?: boolean;\n}\n\n/**\n * Computes the default `value` for a rule given its `field`/`operator`/`valueSource`, mirroring\n * the precedence the {@link react-querybuilder!QueryBuilder QueryBuilder} applies: a field's\n * `defaultValue`, then a `getDefaultValue` override, then a value derived from the field/operator's\n * value list and editor type (first option for `select`/`radio`, `false` for `checkbox`, paired for\n * `between`/`notBetween`), or a comparator-valid field when `valueSource` is `'field'`. Falls back\n * to `''`.\n *\n * @group Option Lists\n */\nexport const getRuleDefaultValue = <F extends FullField = FullField>(\n  rule: RuleType,\n  options: GetRuleDefaultValueOptions<F>\n): unknown => {\n  const {\n    fieldData,\n    fields,\n    getValueEditorType,\n    getValues,\n    getDefaultValue,\n    getParameters,\n    listsAsArrays,\n  } = options;\n\n  if (fieldData?.defaultValue !== undefined && fieldData.defaultValue !== null) {\n    return fieldData.defaultValue;\n  } else if (getDefaultValue) {\n    return getDefaultValue(rule, { fieldData });\n  }\n\n  let value: string | (string | null)[] | boolean | null = '';\n\n  const values = getValues(rule.field, rule.operator, { fieldData });\n\n  if (rule.valueSource === 'field') {\n    const filteredFields = filterFieldsByComparator(fieldData, fields, rule.operator);\n    value =\n      filteredFields.length > 0 ? getFirstOptionsFrom(filteredFields, rule, listsAsArrays) : '';\n  } else if (rule.valueSource === 'parameter') {\n    const parameters = getParameters\n      ? getParameters(rule.field, rule.operator, { fieldData })\n      : null;\n    value = parameters && parameters.length > 0 ? getFirstOption(parameters) : '';\n  } else if (values.length > 0) {\n    const editorType = getValueEditorType(rule.field, rule.operator, { fieldData });\n    if (editorType === 'multiselect') {\n      value = listsAsArrays ? [] : '';\n    } else if (editorType === 'select' || editorType === 'radio') {\n      value = getFirstOptionsFrom(values, rule, listsAsArrays);\n    }\n  } else {\n    const editorType = getValueEditorType(rule.field, rule.operator, { fieldData });\n    if (editorType === 'checkbox') {\n      value = false;\n    }\n  }\n\n  return value;\n};\n","import { standardClassnames } from '../defaults';\nimport type { ValidationResult } from '../types';\n\n/**\n * Gets the standard classname for valid or invalid components\n * based on the given validation result.\n */\nexport const getValidationClassNames = (\n  validationResult: boolean | ValidationResult\n): '' | (typeof standardClassnames)['valid'] | (typeof standardClassnames)['invalid'] => {\n  const valid =\n    typeof validationResult === 'boolean'\n      ? validationResult\n      : typeof validationResult === 'object' && validationResult !== null\n        ? validationResult.valid\n        : null;\n  return typeof valid === 'boolean'\n    ? valid\n      ? standardClassnames.valid\n      : standardClassnames.invalid\n    : '';\n};\n","import type {\n  FullField,\n  GetOptionIdentifierType,\n  ValueSourceFlexibleOptions,\n  ValueSourceFullOptions,\n  ValueSources,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst defaultValueSourcesArray: ValueSourceFullOptions = [\n  { name: 'value', value: 'value', label: 'value' },\n];\n\nconst dummyFD = {\n  name: 'name',\n  value: 'name',\n  valueSources: null,\n  label: 'label',\n};\n\n/**\n * Utility function to get the value sources array for the given\n * field and operator. If the field definition does not define a\n * `valueSources` property, the `getValueSources` prop is used.\n * Returns `[FullOption<\"value\">]` by default.\n */\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters\nexport const getValueSourcesUtil = <F extends FullField, O extends string>(\n  fieldData: F,\n  operator: string,\n  getValueSources?: (\n    field: GetOptionIdentifierType<F>,\n    operator: O,\n    misc: { fieldData: F }\n  ) => ValueSources | ValueSourceFlexibleOptions\n): ValueSourceFullOptions => {\n  // TypeScript doesn't allow it directly, but in practice\n  // `fieldData` can end up being undefined or null. The nullish\n  // coalescing assignment below avoids errors like\n  // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n  const fd = fieldData ? toFullOption(fieldData) : dummyFD;\n\n  let valueSourcesNEW:\n    | false\n    | ValueSources\n    | ValueSourceFlexibleOptions\n    | ((operator: string) => ValueSources | ValueSourceFlexibleOptions) = fd.valueSources ?? false;\n\n  if (typeof valueSourcesNEW === 'function') {\n    valueSourcesNEW = valueSourcesNEW(operator);\n  }\n\n  if (!valueSourcesNEW && getValueSources) {\n    valueSourcesNEW = getValueSources(fd.value as GetOptionIdentifierType<F>, operator as O, {\n      fieldData: fd as F,\n    });\n  }\n\n  if (!valueSourcesNEW) {\n    return defaultValueSourcesArray;\n  }\n\n  if (isFlexibleOptionArray(valueSourcesNEW)) {\n    return toFullOptionList(valueSourcesNEW as ValueSourceFullOptions) as ValueSourceFullOptions;\n  }\n\n  return valueSourcesNEW.map(\n    vs =>\n      defaultValueSourcesArray.find(dmm => dmm.value === lc(vs)) ?? {\n        name: vs,\n        value: vs,\n        label: vs,\n      }\n  ) as ValueSourceFullOptions;\n};\n","import { isUnsafeKey, objectEntries, objectKeys } from './objectUtils';\n\n/**\n * Merges any number of partial translations into a single definition.\n */\nexport const mergeAnyTranslations = (\n  base: Record<string, Record<string, unknown>>,\n  ...otherTranslations: (Record<string, Record<string, unknown>> | undefined)[]\n): Record<string, Record<string, unknown>> => {\n  const result = { ...base };\n\n  for (const translations of otherTranslations) {\n    // v8 ignore else\n    if (translations) {\n      for (const key of objectKeys(translations)) {\n        if (isUnsafeKey(key)) continue;\n        if (result[key]) {\n          result[key] = { ...result[key], ...translations[key] };\n        } else {\n          result[key] = { ...translations[key] };\n        }\n      }\n    }\n  }\n\n  return result;\n};\n\nexport const mergeAnyTranslation = (\n  el: string,\n  keyPropContextMap: Record<string, [unknown, unknown]>,\n  defaults?: Record<string, Record<string, unknown>>\n): Record<string, Record<string, unknown>> | undefined => {\n  if (isUnsafeKey(el)) return undefined;\n  const finalKeys = objectEntries(keyPropContextMap)\n    .map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]])\n    .filter(k => !isUnsafeKey(k[0] as string) && !!k[1]);\n  if (finalKeys.length > 0 || defaults) {\n    const defaultProperties = defaults?.[el] ?? {};\n    const finalObject = Object.assign({}, defaultProperties, Object.fromEntries(finalKeys));\n    return { [el]: finalObject };\n  }\n  return undefined;\n};\n","import type { Classnames } from '../types';\nimport { clsx } from './clsx';\n\ntype MergeClassnamesParams = (Partial<Classnames> | undefined)[];\n\nconst joinClassnamesByName = (name: keyof Classnames, args: MergeClassnamesParams) => {\n  let result = '';\n  for (let i = 0; i < args.length; i++) {\n    const v = args[i]?.[name];\n    if (!v) continue;\n    // clsx only needed for array/object values; plain strings (common case) pass through\n    const s = typeof v === 'string' ? v : clsx(v);\n    if (s) result = result ? `${result} ${s}` : s;\n  }\n  return result;\n};\n\n/**\n * Merges a list of partial {@link Classnames} definitions into a single definition.\n */\nexport const mergeClassnames = (...args: MergeClassnamesParams): Classnames => ({\n  queryBuilder: joinClassnamesByName('queryBuilder', args),\n  ruleGroup: joinClassnamesByName('ruleGroup', args),\n  header: joinClassnamesByName('header', args),\n  body: joinClassnamesByName('body', args),\n  combinators: joinClassnamesByName('combinators', args),\n  addRule: joinClassnamesByName('addRule', args),\n  addGroup: joinClassnamesByName('addGroup', args),\n  cloneRule: joinClassnamesByName('cloneRule', args),\n  cloneGroup: joinClassnamesByName('cloneGroup', args),\n  removeGroup: joinClassnamesByName('removeGroup', args),\n  rule: joinClassnamesByName('rule', args),\n  fields: joinClassnamesByName('fields', args),\n  operators: joinClassnamesByName('operators', args),\n  value: joinClassnamesByName('value', args),\n  removeRule: joinClassnamesByName('removeRule', args),\n  notToggle: joinClassnamesByName('notToggle', args),\n  shiftActions: joinClassnamesByName('shiftActions', args),\n  undoRedoActions: joinClassnamesByName('undoRedoActions', args),\n  undoAction: joinClassnamesByName('undoAction', args),\n  redoAction: joinClassnamesByName('redoAction', args),\n  dragHandle: joinClassnamesByName('dragHandle', args),\n  lockRule: joinClassnamesByName('lockRule', args),\n  lockGroup: joinClassnamesByName('lockGroup', args),\n  muteRule: joinClassnamesByName('muteRule', args),\n  muteGroup: joinClassnamesByName('muteGroup', args),\n  muted: joinClassnamesByName('muted', args),\n  valueSource: joinClassnamesByName('valueSource', args),\n  actionElement: joinClassnamesByName('actionElement', args),\n  valueSelector: joinClassnamesByName('valueSelector', args),\n  betweenRules: joinClassnamesByName('betweenRules', args),\n  valid: joinClassnamesByName('valid', args),\n  invalid: joinClassnamesByName('invalid', args),\n  dndDragging: joinClassnamesByName('dndDragging', args),\n  dndOver: joinClassnamesByName('dndOver', args),\n  dndCopy: joinClassnamesByName('dndCopy', args),\n  dndGroup: joinClassnamesByName('dndGroup', args),\n  dndDropNotAllowed: joinClassnamesByName('dndDropNotAllowed', args),\n  dndPreviewPosition: joinClassnamesByName('dndPreviewPosition', args),\n  dndHidden: joinClassnamesByName('dndHidden', args),\n  disabled: joinClassnamesByName('disabled', args),\n  valueListItem: joinClassnamesByName('valueListItem', args),\n  matchMode: joinClassnamesByName('matchMode', args),\n  matchThreshold: joinClassnamesByName('matchThreshold', args),\n  branches: joinClassnamesByName('branches', args),\n  hasSubQuery: joinClassnamesByName('hasSubQuery', args),\n  loading: joinClassnamesByName('loading', args),\n  valueDateTimeRelative: joinClassnamesByName('valueDateTimeRelative', args),\n});\n","import { defaultOperatorLabelMap } from '../defaults';\nimport type {\n  FlexibleOptionList,\n  FlexibleOptionListProp,\n  FullField,\n  FullOperator,\n  FullOption,\n  FullOptionList,\n  Option,\n  Placeholder,\n  ValueEditorType,\n} from '../types';\nimport { getFirstOption, prepareOptionList } from './optGroupUtils';\n\n/**\n * Options shared by the resolvers below that produce a normalized option list.\n */\nexport interface ResolveOptionListOptions {\n  /**\n   * Prepended as an empty placeholder option when `autoSelectOption` is `false`. Supplied by the\n   * `translations` prop in React; omit it where translations don't apply.\n   */\n  placeholder?: Placeholder;\n  /** Properties applied to every option in the resulting list. */\n  baseOption?: Record<string, unknown>;\n  /** When `false`, an empty placeholder option is prepended. */\n  autoSelectOption?: boolean;\n}\n\n/**\n * Resolves the operator list for a field, applying the same precedence as the `QueryBuilder`\n * component: the field's own `operators`, then the `getOperators` callback, then the\n * query-level operator list.\n *\n * @group Option Lists\n */\nexport const resolveOperatorList = <\n  F extends FullField = FullField,\n  O extends FullOperator = FullOperator,\n>({\n  field,\n  fieldData,\n  getOperators,\n  operators,\n  placeholder,\n  baseOption,\n  autoSelectOption,\n}: {\n  field: string;\n  fieldData: F;\n  getOperators?: (field: string, misc: { fieldData: F }) => FlexibleOptionList<O> | null;\n  operators: FullOptionList<O>;\n} & ResolveOptionListOptions): FullOptionList<O> =>\n  prepareOptionList<O>({\n    optionList: (fieldData?.operators ??\n      getOperators?.(field, { fieldData }) ??\n      operators) as FlexibleOptionListProp<O>,\n    placeholder,\n    baseOption,\n    labelMap: defaultOperatorLabelMap,\n    autoSelectOption,\n  }).optionList;\n\n/**\n * Resolves the default operator for a field, applying the same precedence as the `QueryBuilder`\n * component: the field's own `defaultOperator`, then the `getDefaultOperator` option (a string or\n * a function), then the first available operator.\n *\n * @group Option Lists\n */\nexport const resolveDefaultOperator = <F extends FullField = FullField>({\n  field,\n  fieldData,\n  getDefaultOperator,\n  getOperators,\n}: {\n  field: string;\n  fieldData: F;\n  getDefaultOperator?: string | ((field: string, misc: { fieldData: F }) => string);\n  /** Produces the operator list for the field, i.e. {@link resolveOperatorList} already bound. */\n  getOperators: (field: string, misc: { fieldData: F }) => FullOptionList<FullOperator>;\n}): string => {\n  if (fieldData?.defaultOperator) return fieldData.defaultOperator;\n\n  if (getDefaultOperator) {\n    return typeof getDefaultOperator === 'function'\n      ? getDefaultOperator(field, { fieldData })\n      : getDefaultOperator;\n  }\n\n  return getFirstOption(getOperators(field, { fieldData })) ?? '';\n};\n\n/**\n * Resolves the value editor type for a field/operator pair, applying the same precedence as the\n * `QueryBuilder` component: the field's own `valueEditorType` (a string or a function of the\n * operator), then the `getValueEditorType` callback, then `\"text\"`.\n *\n * @group Option Lists\n */\nexport const resolveValueEditorType = <F extends FullField = FullField>({\n  field,\n  operator,\n  fieldData,\n  getValueEditorType,\n}: {\n  field: string;\n  operator: string;\n  fieldData: F;\n  getValueEditorType?: (field: string, operator: string, misc: { fieldData: F }) => ValueEditorType;\n}): ValueEditorType => {\n  if (fieldData?.valueEditorType) {\n    return typeof fieldData.valueEditorType === 'function'\n      ? fieldData.valueEditorType(operator)\n      : fieldData.valueEditorType;\n  }\n\n  return getValueEditorType?.(field, operator, { fieldData }) ?? 'text';\n};\n\n/**\n * Resolves the value option list for a field/operator pair, applying the same precedence as the\n * `QueryBuilder` component: the field's own `values`, then the `getValues` callback, then an\n * empty list.\n *\n * @group Option Lists\n */\nexport const resolveValueList = <F extends FullField = FullField>({\n  field,\n  operator,\n  fieldData,\n  getValues,\n  placeholder,\n  baseOption,\n  autoSelectOption,\n}: {\n  field: string;\n  operator: string;\n  fieldData: F;\n  getValues?: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => FlexibleOptionList<Option> | null;\n} & ResolveOptionListOptions): FullOptionList<Option> =>\n  prepareOptionList<FullOption>({\n    optionList: fieldData?.values ?? getValues?.(field, operator, { fieldData }) ?? [],\n    placeholder,\n    baseOption,\n    autoSelectOption,\n  }).optionList;\n","import type { FullCombinator, FullField, FullOperator } from '../types';\n// Type-only, so this does not create a cycle with `QueryManager.ts`, which imports `optionsEqual`.\nimport type { QueryManagerOptions } from './QueryManager';\n\nconst isPlainObject = (x: object): boolean => {\n  const proto = Object.getPrototypeOf(x);\n  return proto === null || proto === Object.prototype;\n};\n\n/**\n * Structural equality for {@link QueryManagerOptions} values. Arrays and plain objects are\n * compared by value; everything else — functions, class instances, `Map`s, `Date`s — by\n * identity.\n *\n * That split is what makes an options object rebuilt on every render compare equal as long as\n * its _data_ did not change, which is the entire point: a caller that passes object literals\n * (`fields={[...]}`, `translations={{...}}`) hands a fresh identity to every reconfigure, so an\n * identity-only comparison would report a change every time.\n *\n * Comparing functions by identity is deliberate rather than a limitation. Two functions cannot\n * be proven equivalent, so a caller that rebuilds `getDefaultValue` per render must either\n * memoize it or accept the reconfigure.\n */\nexport const valuesEqual = (a: unknown, b: unknown): boolean => {\n  if (Object.is(a, b)) return true;\n\n  if (Array.isArray(a) || Array.isArray(b)) {\n    return (\n      Array.isArray(a) &&\n      Array.isArray(b) &&\n      a.length === b.length &&\n      a.every((v, i) => valuesEqual(v, b[i]))\n    );\n  }\n\n  if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n\n  // Different shapes are never equal, and non-plain objects (class instances, `Date`, `Map`,\n  // …) are compared by identity only — their state is not exhausted by their own enumerable\n  // keys, so a key-wise walk would report two distinct `Date`s as equal.\n  if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b) || !isPlainObject(a)) return false;\n\n  const aKeys = Object.keys(a);\n  return (\n    aKeys.length === Object.keys(b).length &&\n    aKeys.every(k =>\n      valuesEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])\n    )\n  );\n};\n\n/**\n * Whether two {@link QueryManagerOptions} objects describe the same configuration, per\n * {@link valuesEqual}: data by value, functions by identity.\n *\n * {@link QueryManager.reconfigure} uses this to gate itself, so most callers never need it\n * directly. It is exported for framework adapters that decide whether to _call_ `reconfigure`\n * at all — skipping the call avoids building the merged options object in the first place.\n *\n * Nested option objects (`history`, `translations`, …) are descended into rather than compared\n * by identity, so `{ history: { maxHistory: 10 } }` rebuilt per render compares equal.\n */\nexport const optionsEqual = <\n  F extends FullField = FullField,\n  O extends FullOperator = FullOperator,\n  C extends FullCombinator = FullCombinator,\n>(\n  a: Partial<QueryManagerOptions<F, O, C>> | undefined,\n  b: Partial<QueryManagerOptions<F, O, C>> | undefined\n): boolean => valuesEqual(a, b);\n","import { queryBuilderFlagDefaults } from '../defaults';\nimport type { QueryBuilderFlags } from '../types';\nimport { objectEntries } from './objectUtils';\n\nconst preferPropDefaultTrue = (prop?: boolean, context?: boolean) =>\n  prop === false ? false : prop ? true : !(context === false);\n\nconst preferPropDefaultFalse = (prop?: boolean, context?: boolean) =>\n  prop ? true : prop === false ? false : !!context;\n\n/**\n * For given default, prop, and context values, return the first provided of prop,\n * context, and default, in that order.\n */\nexport const preferProp = (\n  def: boolean,\n  prop?: boolean,\n  context?: boolean,\n  doNotFinalize?: boolean\n): boolean =>\n  !doNotFinalize\n    ? def\n      ? preferPropDefaultTrue(prop, context)\n      : preferPropDefaultFalse(prop, context)\n    : (prop ?? (context as boolean));\n\n/**\n * For given default, prop, and context values, return the first provided of prop,\n * context, and default, in that order.\n */\n// oxlint-disable-next-line typescript/no-explicit-any\nexport const preferAnyProp = (def?: any, prop?: any, context?: any): any =>\n  prop !== undefined && prop != null\n    ? prop\n    : context !== undefined && context != null\n      ? context\n      : def;\n\n/**\n * For a given set of defaults, props, and context values, return the first provided of prop,\n * context, and default—in that order—for each property in the defaults object.\n */\nexport const preferFlagProps = (\n  props: QueryBuilderFlags = {},\n  contextVals: QueryBuilderFlags = {},\n  finalize?: boolean\n): QueryBuilderFlags =>\n  objectEntries(queryBuilderFlagDefaults).reduce<QueryBuilderFlags>((acc, [key, def]) => {\n    acc[key] = preferProp(def, props[key], contextVals[key], !finalize);\n    return acc;\n  }, {});\n","import type {\n  RuleGroupArray,\n  RuleGroupICArray,\n  RuleGroupType,\n  RuleGroupTypeAny,\n  RuleGroupTypeIC,\n  RuleType,\n} from '../types';\nimport { processMatchMode } from './formatQuery/utils';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Options for {@link prepareRule}/{@link prepareRuleGroup}.\n */\nexport interface PreparerOptions {\n  idGenerator?: () => string;\n}\n\n/**\n * Ensures that a rule is valid by adding an `id` property if it does not already exist.\n */\nexport const prepareRule = (\n  rule: RuleType,\n  { idGenerator = generateID }: PreparerOptions = {}\n): RuleType => {\n  const needsId = !rule.id;\n  const hasMatchMode = processMatchMode(rule);\n\n  if (!needsId && !hasMatchMode) {\n    return rule;\n  }\n\n  return {\n    ...rule,\n    ...(needsId && { id: idGenerator() }),\n    ...(hasMatchMode && { value: prepareRuleGroup(rule.value, { idGenerator }) }),\n  };\n};\n\n/**\n * Ensures that a rule group is valid by recursively adding an `id` property to the group itself\n * and all its rules and subgroups where one does not already exist.\n */\nexport const prepareRuleGroup = <RG extends RuleGroupTypeAny>(\n  queryObject: RG,\n  { idGenerator = generateID }: PreparerOptions = {}\n): RG => {\n  const needsId = !queryObject.id;\n  let rulesChanged = false;\n  const newRules: (RuleGroupTypeAny | RuleType | string)[] = [];\n\n  for (let i = 0; i < queryObject.rules.length; i++) {\n    const r = queryObject.rules[i];\n    if (typeof r === 'string') {\n      newRules.push(r);\n    } else {\n      const prepared = isRuleGroup(r)\n        ? prepareRuleGroup(r, { idGenerator })\n        : prepareRule(r, { idGenerator });\n      newRules.push(prepared);\n      if (prepared !== r) {\n        rulesChanged = true;\n      }\n    }\n  }\n\n  if (!needsId && !rulesChanged) {\n    return queryObject;\n  }\n\n  return {\n    ...queryObject,\n    ...(needsId && { id: idGenerator() }),\n    rules: newRules as RuleGroupArray | RuleGroupICArray,\n  };\n};\n\n/**\n * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.\n */\nexport const prepareRuleOrGroup = (\n  rg: RuleGroupTypeAny | RuleType,\n  { idGenerator = generateID }: PreparerOptions = {}\n): RuleGroupType | RuleGroupTypeIC | RuleType =>\n  isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });\n\n/**\n * Resolves the query a query builder should render from the available sources, in precedence\n * order: the controlled `query`, then whatever is already in the store, then the uncontrolled\n * `defaultQuery`, then a freshly created empty group.\n *\n * The result is prepared with {@link prepareRuleGroup} unless it already has an `id`, which is\n * taken to mean it has been prepared before—most often because the caller is passing back the\n * object it received from `onQueryChange`.\n *\n * @group Query Tools\n */\nexport const resolveCandidateQuery = <RG extends RuleGroupTypeAny>(\n  sources: {\n    query?: RG;\n    storeQuery?: RG;\n    defaultQuery?: RG;\n    fallbackQuery: RG;\n  },\n  options?: { idGenerator?: () => string }\n): RG => {\n  const candidateQuery =\n    sources.query ?? sources.storeQuery ?? sources.defaultQuery ?? sources.fallbackQuery;\n\n  return candidateQuery.id ? candidateQuery : prepareRuleGroup(candidateQuery, options);\n};\n","import type { SetRequired } from 'type-fest';\nimport type { RuleGroupTypeAny, RuleType } from '../types';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\nimport { isPojo } from './misc';\n\n/**\n * Options object for {@link regenerateID}/{@link regenerateIDs}.\n */\nexport interface RegenerateIdOptions {\n  idGenerator?: () => string;\n}\n\n/**\n * Generates a new `id` property for a rule.\n */\nexport const regenerateID = <R extends RuleType>(\n  rule: R,\n  { idGenerator = generateID }: RegenerateIdOptions = {}\n): SetRequired<R, 'id'> => structuredClone({ ...rule, id: idGenerator() } as SetRequired<R, 'id'>);\n\n/**\n * Recursively generates new `id` properties for a rule group and all its rules and subgroups.\n */\nexport const regenerateIDs = <RG>(\n  subject: RG,\n  { idGenerator = generateID }: RegenerateIdOptions = {}\n): RG & { id: string } => {\n  if (!isPojo(subject)) return subject as RG & { id: string };\n\n  if (!isRuleGroup(subject)) {\n    return structuredClone({\n      ...subject,\n      id: idGenerator(),\n    });\n  }\n\n  const newGroup = { ...subject, id: idGenerator() } as RuleGroupTypeAny;\n\n  // v8 ignore else\n  if (Array.isArray(newGroup.rules)) {\n    // oxlint-disable-next-line no-explicit-any\n    (newGroup.rules as any) = subject.rules.map((r: unknown) =>\n      typeof r === 'string'\n        ? r\n        : isRuleGroup(r)\n          ? regenerateIDs(r, { idGenerator })\n          : regenerateID(r as RuleType, { idGenerator })\n    );\n  }\n\n  return newGroup as unknown as RG & { id: string };\n};\n","import { current, isDraft } from 'immer';\nimport { defaultCombinators } from '../defaults';\nimport type {\n  MatchModeOptions,\n  OptionList,\n  Path,\n  RuleGroupTypeAny,\n  RuleType,\n  UpdateableProperties,\n  UpdateValueMap,\n  ValueSourceFlexibleOptions,\n  ValueSources,\n} from '../types';\nimport { generateID } from './generateID';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { producerFor } from './immerInstances';\nimport { isRuleGroup, isRuleGroupType, isRuleGroupTypeIC } from './isRuleGroup';\nimport { getFirstOption, getOption } from './optGroupUtils';\nimport {\n  findID,\n  findPath,\n  getCommonAncestorPath,\n  getParentPath,\n  getPathOfID,\n  isAncestor,\n  pathIsDisabled,\n  pathIsDisabledByPaths,\n  pathsAreEqual,\n} from './pathUtils';\nimport { prepareRuleOrGroup } from './prepareQueryObjects';\nimport { regenerateIDs } from './regenerateIDs';\n\n/**\n * Why a query tool returned the query unmodified. Query tools never throw; when they cannot\n * carry out an operation they return the original query and report the reason through\n * {@link AbortOptions.onAbort}.\n *\n * `\"same-location\"` and `\"no-change\"` describe operations that were valid but had nothing to\n * do, so they are not errors. Every other reason indicates a target that could not be used.\n *\n * @group Query Tools\n */\nexport type AbortReason =\n  /** The rule/group identified by the given path or `id` does not exist. */\n  | 'target-not-found'\n  /** The parent group identified by the given path or `id` does not exist. */\n  | 'parent-not-found'\n  /** The given parent path or `id` refers to a rule rather than a group. */\n  | 'parent-not-a-group'\n  /** The destination's parent group does not exist. */\n  | 'destination-not-found'\n  /** The root group cannot be removed, moved, or grouped. */\n  | 'root-not-allowed'\n  /** In a query with independent combinators, the target index holds a rule, not a combinator. */\n  | 'not-a-combinator-slot'\n  /** The rule/group is already at the destination. Not an error. */\n  | 'same-location'\n  /** The property already has the given value. Not an error. */\n  | 'no-change'\n  /** The target rule/group is disabled, or descends from a disabled group. */\n  | 'target-disabled'\n  /** The parent group is disabled, or descends from a disabled group. */\n  | 'parent-disabled'\n  /** Adding the group would nest it deeper than `maxLevels` allows. */\n  | 'max-levels-exceeded';\n\n/**\n * Details about an aborted query tool operation.\n *\n * @group Query Tools\n */\nexport interface AbortInfo {\n  /** Why the operation was aborted. */\n  reason: AbortReason;\n  /** The query tool that aborted. */\n  operation: 'add' | 'remove' | 'update' | 'move' | 'insert' | 'group';\n  /** The path or `id` that could not be used, when the reason relates to a specific target. */\n  pathOrID?: Path | string;\n}\n\n/**\n * Options that block a mutation before it is attempted.\n *\n * `disabled` is a property of the query itself, so honoring it is a matter of data integrity\n * rather than presentation: a query saved with a locked rule should stay locked when it is\n * loaded again. It is opt-in here only to preserve the existing behavior of the standalone\n * query tools; {@link QueryManager} enables it by default.\n *\n * @group Query Tools\n */\nexport interface GuardOptions {\n  /**\n   * Abort when the target (or its parent, for `add`/`insert`) is disabled, either directly or\n   * by descending from a disabled group. Defaults to `false`.\n   *\n   * Updating a rule or group's own `disabled` property is always permitted, since it is the\n   * only way to re-enable it.\n   */\n  respectDisabled?: boolean;\n  /**\n   * Paths that are disabled without the corresponding rule or group carrying a `disabled`\n   * property, mirroring the array form of the `QueryBuilder` `disabled` prop. A path is treated\n   * as disabled if it appears here or descends from a path that does.\n   *\n   * Like the `disabled` property, this is only honored when `respectDisabled` is `true`, and\n   * updating a rule or group's own `disabled` property is still permitted.\n   */\n  disabledPaths?: Path[];\n  /** Abort every mutation, as though the entire query were disabled. Defaults to `false`. */\n  queryDisabled?: boolean;\n  /**\n   * The maximum depth at which a group may be added. A group whose parent path is already this\n   * deep is rejected by `add` and `insert`. Rules are unaffected. Defaults to `Infinity`.\n   */\n  maxLevels?: number;\n}\n\n/**\n * Options for reporting aborted query tool operations.\n *\n * @group Query Tools\n */\nexport interface AbortOptions extends GuardOptions {\n  /**\n   * Called when the operation returns the query unmodified, with the reason why. Query tools\n   * never throw, so this is the only way to distinguish \"the target was invalid\" from\n   * \"the operation had nothing to do\".\n   */\n  onAbort?: (info: AbortInfo) => void;\n}\n\n/**\n * Options shared by every query tool.\n *\n * @group Query Tools\n */\nexport interface QueryToolOptions extends AbortOptions {\n  /**\n   * Set `false` to skip immer's auto-freeze on the returned query, e.g. when the query will be\n   * handed to a framework that wraps it in a proxy (Vue `reactive`, Solid stores) or otherwise\n   * needs to mutate it. Ignored by the `*InPlace` variants, which never freeze.\n   *\n   * @default true\n   */\n  freeze?: boolean;\n}\n\n/**\n * Whether a mutation targeting `pathOrID` is blocked by the given guards, and why.\n * Returns `null` when the mutation may proceed.\n *\n * Exported so that callers which run their own logic before mutating—such as a UI layer that\n * invokes a confirmation callback—can apply the same rules without duplicating them.\n *\n * @group Query Tools\n */\nexport const getGuardAbortReason = (\n  query: RuleGroupTypeAny,\n  pathOrID: Path | string | undefined,\n  guards: GuardOptions = {},\n  { asParent = false }: { asParent?: boolean } = {}\n): AbortReason | null => {\n  if (guards.queryDisabled) return asParent ? 'parent-disabled' : 'target-disabled';\n\n  if (!guards.respectDisabled || pathOrID === undefined) return null;\n\n  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);\n  if (path && (pathIsDisabled(path, query) || pathIsDisabledByPaths(path, guards.disabledPaths))) {\n    return asParent ? 'parent-disabled' : 'target-disabled';\n  }\n\n  return null;\n};\n\n/**\n * Whether adding a group beneath `parentPath` would exceed `maxLevels`.\n *\n * @group Query Tools\n */\nexport const exceedsMaxLevels = (\n  parentPath: Path | undefined,\n  { maxLevels = Infinity }: GuardOptions = {}\n): boolean => !!parentPath && parentPath.length >= maxLevels;\n\n/**\n * Options for {@link add}.\n *\n * @group Query Tools\n */\nexport interface AddOptions extends QueryToolOptions {\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query has independent\n   * combinators), then the first combinator in this list will be inserted\n   * before the new rule/group if the parent group is not empty. This option\n   * is overridden by `combinatorPreceding`.\n   */\n  combinators?: OptionList;\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query has independent\n   * combinators), then this combinator will be inserted before the new rule/group\n   * if the parent group is not empty. This option will supersede `combinators`.\n   */\n  combinatorPreceding?: string;\n  /**\n   * ID generator.\n   */\n  idGenerator?: () => string;\n}\n\nexport interface AddMethod {\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** The rule or group to add. */\n    ruleOrGroup: RG | RuleType,\n    /** Path or ID of the group to add to. */\n    parentPathOrID: Path | string,\n    /** Options. */\n    options?: AddOptions\n  ): RG;\n}\n\n/**\n * Adds a rule or group to a query without mutating the original query.\n *\n * @returns A new query with the rule or group added.\n *\n * @group Query Tools\n */\nexport const add: AddMethod = (query, ruleOrGroup, parentPathOrID, options = {}): typeof query =>\n  producerFor(options.freeze)(query, q =>\n    addInPlace(q, ruleOrGroup as RuleType, parentPathOrID, options)\n  );\n\n/**\n * Adds a rule or group to a query in place.\n *\n * @returns The query (mutated in place) with the rule or group added.\n *\n * @group Query Tools\n */\nexport const addInPlace: AddMethod = (\n  query,\n  ruleOrGroup,\n  parentPathOrID,\n  options = {}\n): typeof query => {\n  const {\n    combinators = defaultCombinators,\n    combinatorPreceding,\n    idGenerator = generateID,\n    onAbort,\n  } = options;\n  const parent = Array.isArray(parentPathOrID)\n    ? findPath(parentPathOrID, query)\n    : findID(parentPathOrID, query);\n\n  if (!parent) {\n    onAbort?.({ reason: 'parent-not-found', operation: 'add', pathOrID: parentPathOrID });\n    return query;\n  }\n\n  if (!isRuleGroup(parent)) {\n    onAbort?.({ reason: 'parent-not-a-group', operation: 'add', pathOrID: parentPathOrID });\n    return query;\n  }\n\n  // The parent is known to exist by this point, so the path always resolves.\n  const parentPath = (\n    Array.isArray(parentPathOrID) ? parentPathOrID : getPathOfID(parentPathOrID, query)\n  ) as Path;\n\n  const addGuardReason = getGuardAbortReason(query, parentPath, options, { asParent: true });\n  if (addGuardReason) {\n    onAbort?.({ reason: addGuardReason, operation: 'add', pathOrID: parentPathOrID });\n    return query;\n  }\n\n  if (isRuleGroup(ruleOrGroup) && exceedsMaxLevels(parentPath, options)) {\n    onAbort?.({ reason: 'max-levels-exceeded', operation: 'add', pathOrID: parentPathOrID });\n    return query;\n  }\n\n  if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {\n    const prevCombinator = parent.rules.at(-2);\n    parent.rules.push(\n      // @ts-expect-error This is technically a type violation until the next push\n      // to the rules array, but that happens immediately and unconditionally so\n      // there's no significant risk.\n      combinatorPreceding ??\n        (typeof prevCombinator === 'string' ? prevCombinator : getFirstOption(combinators))\n    );\n  }\n  // `as RuleType` is only here to avoid the ambiguity with `RuleGroupTypeAny`\n  parent.rules.push(prepareRuleOrGroup(ruleOrGroup, { idGenerator }) as RuleType);\n\n  return query;\n};\n\n/**\n * Options for {@link update}.\n *\n * @group Query Tools\n */\nexport interface UpdateOptions extends QueryToolOptions {\n  /**\n   * When updating the `field` of a rule, the rule's `operator`, `value`, and `valueSource`\n   * will be reset to their respective defaults. Defaults to `true`.\n   */\n  resetOnFieldChange?: boolean;\n  /**\n   * When updating the `operator` of a rule, the rule's `value` and `valueSource`\n   * will be reset to their respective defaults. Defaults to `false`.\n   */\n  resetOnOperatorChange?: boolean;\n  /**\n   * Determines the default operator name for a given field.\n   */\n  getRuleDefaultOperator?: (field: string) => string;\n  /**\n   * Determines the valid value sources for a given field and operator.\n   */\n  getValueSources?: (field: string, operator: string) => ValueSources | ValueSourceFlexibleOptions;\n  /**\n   * Gets the default value for a given rule, in case the value needs to be reset.\n   */\n  // oxlint-disable-next-line typescript/no-explicit-any\n  getRuleDefaultValue?: (rule: RuleType) => any;\n  /**\n   * Determines the valid match modes for a given field.\n   */\n  getMatchModes?: (field: string) => MatchModeOptions;\n}\n\nexport interface UpdateMethod {\n  /**\n   * Updates a single property of a rule or group.\n   */\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** The name of the property to update. */\n    prop: UpdateableProperties,\n    /** The new value of the property. */\n    // oxlint-disable-next-line typescript/no-explicit-any\n    value: any,\n    /** The path or ID of the rule or group to update. */\n    pathOrID: Path | string,\n    /** Options. */\n    options?: UpdateOptions\n  ): RG;\n  /**\n   * Updates multiple properties of a rule or group using parallel arrays of\n   * property names and corresponding values.\n   */\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** The names of the properties to update. */\n    props: UpdateableProperties[],\n    /** The new values, in the same order as `props`. */\n    // oxlint-disable-next-line typescript/no-explicit-any\n    values: any[],\n    /** The path or ID of the rule or group to update. */\n    pathOrID: Path | string,\n    /** Options. */\n    options?: UpdateOptions\n  ): RG;\n  /**\n   * Updates multiple properties of a rule or group using a map of property\n   * names to their new values.\n   */\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** A map of property names to their new values. */\n    props: UpdateValueMap,\n    /** The path or ID of the rule or group to update. */\n    pathOrID: Path | string,\n    /** Options. */\n    options?: UpdateOptions\n  ): RG;\n}\n\n/**\n * Relative order in which properties are applied during a multi-property update.\n * Lower ranks apply first; `value` applies last so an explicitly-provided value\n * is never clobbered by a reset triggered by a `field`/`operator`/`valueSource`\n * change. Unranked properties default to `3` (between `valueSource` and `value`).\n */\nconst updatePropRank: Record<string, number> = { field: 0, operator: 1, valueSource: 2, value: 4 };\n\n/** Stable-sorts `[prop, value]` entries by {@link updatePropRank}. */\nconst orderUpdateEntries = (entries: [string, unknown][]): [string, unknown][] =>\n  entries.toSorted((x, y) => (updatePropRank[x[0]] ?? 3) - (updatePropRank[y[0]] ?? 3));\n\n/**\n * Normalizes the variadic {@link update}/{@link updateInPlace} arguments (single\n * prop+value, parallel arrays, or property map) into a canonically-ordered list\n * of `[prop, value]` entries plus the target path/ID and options.\n */\nconst normalizeUpdateArgs = (\n  a: unknown,\n  b: unknown,\n  c: unknown,\n  d: unknown\n): { entries: [string, unknown][]; pathOrID: Path | string; options: UpdateOptions } => {\n  // Single property: (prop, value, pathOrID, options)\n  if (typeof a === 'string') {\n    return { entries: [[a, b]], pathOrID: c as Path | string, options: (d as UpdateOptions) ?? {} };\n  }\n  // Parallel arrays: (props, values, pathOrID, options)\n  if (Array.isArray(a)) {\n    const values = b as unknown[];\n    return {\n      entries: orderUpdateEntries(a.map((prop, i): [string, unknown] => [prop, values[i]])),\n      pathOrID: c as Path | string,\n      options: (d as UpdateOptions) ?? {},\n    };\n  }\n  // Property map: (props, pathOrID, options)\n  return {\n    entries: orderUpdateEntries(Object.entries(a as Record<string, unknown>)),\n    pathOrID: b as Path | string,\n    options: (c as UpdateOptions) ?? {},\n  };\n};\n\n/**\n * The options argument of an {@link update} call, whose position depends on the argument form.\n * Cheaper than {@link normalizeUpdateArgs} when only the options are needed.\n */\nconst updateOptionsOf = (a: unknown, b: unknown, c: unknown, d: unknown): UpdateOptions =>\n  ((typeof a === 'string' || Array.isArray(a) ? d : c) as UpdateOptions) ?? {};\n\n/**\n * Applies one or more property updates to a query in place. Shared by\n * {@link update} and {@link updateInPlace}.\n */\nconst applyUpdatesInPlace = <RG extends RuleGroupTypeAny>(\n  query: RG,\n  a: unknown,\n  b: unknown,\n  c: unknown,\n  d: unknown\n): RG => {\n  const { entries, pathOrID, options } = normalizeUpdateArgs(a, b, c, d);\n  for (const [prop, value] of entries) {\n    updateInPlaceSingle(query, prop, value, pathOrID, options);\n  }\n  return query;\n};\n\n/**\n * Updates one or more properties of a rule or group within a query without\n * mutating the original query. Properties may be supplied individually\n * (`prop`, `value`), as parallel arrays (`props`, `values`), or as a\n * property-to-value map. For multi-property updates, `field`, `operator`, and\n * `valueSource` are applied before `value`, so an explicit `value` is never\n * reset by a change to one of those properties.\n *\n * @returns A new query with the rule or group properties updated.\n *\n * @group Query Tools\n */\nexport const update = (<RG extends RuleGroupTypeAny>(\n  query: RG,\n  a: unknown,\n  b?: unknown,\n  c?: unknown,\n  d?: unknown\n): RG =>\n  producerFor(updateOptionsOf(a, b, c, d).freeze)(query, q => {\n    applyUpdatesInPlace(q, a, b, c, d);\n  })) as UpdateMethod;\n\n/**\n * Updates one or more properties of a rule or group within a query in place.\n * See {@link update} for the supported argument forms and ordering semantics.\n *\n * @returns The query (mutated in place) with the rule or group properties updated.\n *\n * @group Query Tools\n */\nexport const updateInPlace = (<RG extends RuleGroupTypeAny>(\n  query: RG,\n  a: unknown,\n  b?: unknown,\n  c?: unknown,\n  d?: unknown\n): RG => applyUpdatesInPlace(query, a, b, c, d)) as UpdateMethod;\n\n/**\n * Updates a single property of a rule or group within a query in place.\n */\nconst updateInPlaceSingle = <RG extends RuleGroupTypeAny>(\n  query: RG,\n  prop: UpdateableProperties,\n  // oxlint-disable-next-line typescript/no-explicit-any\n  value: any,\n  pathOrID: Path | string,\n  options: UpdateOptions = {}\n): RG => {\n  const {\n    resetOnFieldChange: _resetOnFieldChange = true,\n    resetOnOperatorChange = false,\n    getRuleDefaultOperator = () => '=',\n    getValueSources = () => ['value'],\n    getRuleDefaultValue = () => '',\n    getMatchModes = () => [],\n    onAbort,\n  } = options;\n\n  let resetOnFieldChange = _resetOnFieldChange;\n\n  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);\n\n  // Ignore invalid paths/ids\n  if (!path) {\n    onAbort?.({ reason: 'target-not-found', operation: 'update', pathOrID });\n    return query;\n  }\n\n  // A node's own `disabled` property is exempt from `respectDisabled`—otherwise a disabled node\n  // could never be re-enabled. `queryDisabled` still blocks it, since that disables everything.\n  const updateGuards =\n    prop === 'disabled' ? { queryDisabled: options.queryDisabled } : (options as GuardOptions);\n  const updateGuardReason = getGuardAbortReason(query, path, updateGuards);\n  if (updateGuardReason) {\n    onAbort?.({ reason: updateGuardReason, operation: 'update', pathOrID });\n    return query;\n  }\n\n  // Independent combinators\n  if (prop === 'combinator' && !isRuleGroupType(query)) {\n    // The combinator slot itself is a bare string, so `findPath` can't confirm the target\n    // exists; the containing group has to be resolved instead.\n    const parent = findPath(getParentPath(path), query);\n    if (!parent || !isRuleGroup(parent)) {\n      onAbort?.({ reason: 'target-not-found', operation: 'update', pathOrID });\n      return query;\n    }\n    const parentRules = parent.rules;\n    // Only update an independent combinator if it occupies an odd index\n    if (path.at(-1)! % 2 === 1) {\n      if (parentRules[path.at(-1)!] === value) {\n        onAbort?.({ reason: 'no-change', operation: 'update', pathOrID });\n      } else {\n        parentRules[path.at(-1)!] = value;\n      }\n    } else {\n      onAbort?.({ reason: 'not-a-combinator-slot', operation: 'update', pathOrID });\n    }\n    return query;\n  }\n\n  const ruleOrGroup = findPath(path, query);\n\n  // Ignore invalid paths\n  if (!ruleOrGroup) {\n    onAbort?.({ reason: 'target-not-found', operation: 'update', pathOrID });\n    return query;\n  }\n\n  const isGroup = isRuleGroup(ruleOrGroup);\n\n  // Only update if there is actually a change\n  // @ts-expect-error prop can refer to rule or group properties\n  if (ruleOrGroup[prop] === value) {\n    onAbort?.({ reason: 'no-change', operation: 'update', pathOrID });\n    return query;\n  }\n\n  // Handle valueSource updates later\n  if (prop !== 'valueSource') {\n    // @ts-expect-error prop can refer to rule or group properties\n    ruleOrGroup[prop] = value;\n  }\n\n  // If this is a group, there's no more to do\n  if (isGroup) return query;\n\n  let resetValueSource = false;\n  let resetValue = false;\n\n  if (prop === 'field') {\n    const fromFieldMatchModes = getMatchModes(ruleOrGroup.field);\n    const toFieldMatchModes = getMatchModes(value);\n\n    if (toFieldMatchModes.length === 0) {\n      delete ruleOrGroup.match;\n    } else {\n      const nextMatchMode =\n        ruleOrGroup.match?.mode && getOption(toFieldMatchModes, ruleOrGroup.match.mode)\n          ? null\n          : getFirstOption(toFieldMatchModes);\n      if (nextMatchMode) {\n        ruleOrGroup.match = { mode: nextMatchMode, threshold: 1 };\n      }\n    }\n\n    if (fromFieldMatchModes.length > 0 || toFieldMatchModes.length > 0) {\n      // Force `resetOnFieldChange` when field is updated FROM or TO one that has match modes\n      resetOnFieldChange = true;\n    }\n  }\n\n  // Set default operator, valueSource, and value for field change\n  if (resetOnFieldChange && prop === 'field') {\n    ruleOrGroup.operator = getRuleDefaultOperator(value);\n    resetValueSource = true;\n    resetValue = true;\n  }\n\n  // Set default valueSource and value for operator change\n  if (resetOnOperatorChange && prop === 'operator') {\n    resetValueSource = true;\n    resetValue = true;\n  }\n\n  const valueSources = getValueSourcesUtil(\n    { name: ruleOrGroup.field, value: ruleOrGroup.field, label: '' },\n    ruleOrGroup.operator,\n    getValueSources\n  );\n  const defaultValueSource = getFirstOption(valueSources);\n  if (\n    (resetValueSource &&\n      ruleOrGroup.valueSource &&\n      defaultValueSource !== ruleOrGroup.valueSource) ||\n    (prop === 'valueSource' && value !== ruleOrGroup.valueSource)\n  ) {\n    // Only reset the value if we're changing the valueSource either\n    // 1) from `undefined` to something that is _not_ the default, or\n    // 2) from the current (defined) value to something else\n    resetValue =\n      !!ruleOrGroup.valueSource || (!ruleOrGroup.valueSource && value !== defaultValueSource);\n    ruleOrGroup.valueSource = resetValueSource ? defaultValueSource : value;\n  }\n\n  if (resetValue) {\n    // The default value should be a valid field name if defaultValueSource is 'field'\n    ruleOrGroup.value = getRuleDefaultValue(ruleOrGroup);\n  }\n\n  return query;\n};\n\n/**\n * Options for {@link remove}.\n *\n * @group Query Tools\n */\nexport interface RemoveOptions extends QueryToolOptions {}\n\nexport interface RemoveMethod {\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** The path or ID of the rule or group to remove. */\n    pathOrID: Path | string,\n    /** Options. */\n    options?: RemoveOptions\n  ): RG;\n}\n\n/**\n * Removes a rule or group from a query without mutating the original query.\n *\n * @returns A new query with the rule or group removed.\n *\n * @group Query Tools\n */\nexport const remove: RemoveMethod = (query, pathOrID, options = {}): typeof query =>\n  producerFor(options.freeze)(query, q => removeInPlace(q, pathOrID, options));\n\n/**\n * Removes a rule or group from a query in place.\n *\n * @returns The query (mutated in place) with the rule or group removed.\n *\n * @group Query Tools\n */\nexport const removeInPlace: RemoveMethod = (query, pathOrID, options = {}): typeof query => {\n  const { onAbort } = options;\n  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);\n\n  // Ignore invalid paths/ids\n  if (!path) {\n    onAbort?.({ reason: 'target-not-found', operation: 'remove', pathOrID });\n    return query;\n  }\n\n  // Can't remove the root group\n  if (path.length === 0) {\n    onAbort?.({ reason: 'root-not-allowed', operation: 'remove', pathOrID });\n    return query;\n  }\n\n  const removeGuardReason = getGuardAbortReason(query, path, options);\n  if (removeGuardReason) {\n    onAbort?.({ reason: removeGuardReason, operation: 'remove', pathOrID });\n    return query;\n  }\n\n  // The target must actually exist. This also covers independent combinators, which `findPath`\n  // reports as missing because they are bare strings rather than rules—they can only be removed\n  // alongside the rule they precede or follow.\n  if (!findPath(path, query)) {\n    onAbort?.({ reason: 'target-not-found', operation: 'remove', pathOrID });\n    return query;\n  }\n\n  // The target resolved, so at a non-root path its parent is necessarily an existing group.\n  const index = path.at(-1)!;\n  const parent = findPath(getParentPath(path), query) as RuleGroupTypeAny;\n  if (!isRuleGroupType(parent) && parent.rules.length > 1) {\n    const idxStartDelete = index === 0 ? 0 : index - 1;\n    parent.rules.splice(idxStartDelete, 2);\n  } else {\n    parent.rules.splice(index, 1);\n  }\n\n  return query;\n};\n\nconst getNextPath = (\n  query: RuleGroupTypeAny,\n  currentPath: Path,\n  newPathOrShiftDirection: Path | 'up' | 'down'\n): Path => {\n  if (Array.isArray(newPathOrShiftDirection)) {\n    return newPathOrShiftDirection;\n  }\n\n  const ic = isRuleGroupTypeIC(query);\n\n  if (newPathOrShiftDirection === 'up') {\n    if (pathsAreEqual(currentPath, [0])) {\n      return currentPath;\n    } else if (currentPath.at(-1) === 0) {\n      const parentPath = getParentPath(currentPath);\n      return [...getParentPath(parentPath), Math.max(0, parentPath.at(-1)! - (ic ? 1 : 0))];\n    } else {\n      const evaluationPath = [\n        ...getParentPath(currentPath),\n        Math.max(0, currentPath.at(-1)! - (ic ? 2 : 1)),\n      ];\n      const entityAtTarget = findPath(evaluationPath, query);\n      if (isRuleGroup(entityAtTarget)) {\n        return [...evaluationPath, entityAtTarget.rules.length];\n      } else {\n        const targetPath = [\n          ...getParentPath(currentPath),\n          Math.max(0, currentPath.at(-1)! - (ic ? 3 : 1)),\n        ];\n        return targetPath;\n      }\n    }\n  } else if (newPathOrShiftDirection === 'down') {\n    if (pathsAreEqual([query.rules.length - 1], currentPath)) {\n      return currentPath;\n    } else if (\n      currentPath.at(-1) ===\n      (findPath(getParentPath(currentPath), query) as RuleGroupTypeAny).rules.length - 1\n    ) {\n      const parentPath = getParentPath(currentPath);\n      return [...getParentPath(parentPath), parentPath.at(-1)! + 1];\n    } else {\n      const evaluationPath = [...getParentPath(currentPath), currentPath.at(-1)! + (ic ? 2 : 1)];\n      const entityToEvaluate = findPath(evaluationPath, query);\n      if (isRuleGroup(entityToEvaluate)) {\n        return [...evaluationPath, 0];\n      } else {\n        const targetPath = [...getParentPath(currentPath), currentPath.at(-1)! + (ic ? 3 : 2)];\n        return targetPath;\n      }\n    }\n  }\n\n  return currentPath;\n};\n\n/**\n * Options for {@link move}.\n *\n * @group Query Tools\n */\nexport interface MoveOptions extends QueryToolOptions {\n  /**\n   * When `true`, the source rule/group will not be removed from its original path.\n   */\n  clone?: boolean;\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query is using independent\n   * combinators), then the first combinator in this list will be inserted before\n   * the rule/group if necessary.\n   */\n  combinators?: OptionList;\n  /**\n   * ID generator.\n   */\n  idGenerator?: () => string;\n}\n\nexport interface MoveMethod {\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** ID or original path of the rule or group to move. */\n    oldPathOrID: Path | string,\n    /** Path to move the rule or group to, or a shift direction. */\n    newPath: Path | 'up' | 'down',\n    /** Options. */\n    options?: MoveOptions\n  ): RG;\n}\n\n/**\n * Moves a rule or group from one path to another without mutating the original query.\n * In the options parameter, pass `{ clone: true }` to copy instead of move.\n *\n * @returns A new query with the rule or group moved or cloned.\n *\n * @group Query Tools\n */\nexport const move: MoveMethod = (query, oldPathOrID, newPath, options = {}): typeof query =>\n  producerFor(options.freeze)(query, q => moveInPlace(q, oldPathOrID, newPath, options));\n\n/**\n * Moves a rule or group from one path to another in place.\n * In the options parameter, pass `{ clone: true }` to copy instead of move.\n *\n * @returns The query (mutated in place) with the rule or group moved or cloned.\n *\n * @group Query Tools\n */\nexport const moveInPlace: MoveMethod = (\n  query,\n  oldPathOrID,\n  newPath,\n  options = {}\n): typeof query => {\n  const {\n    clone = false,\n    combinators = defaultCombinators,\n    idGenerator = generateID,\n    onAbort,\n  } = options;\n  const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);\n\n  // Ignore invalid paths/ids\n  if (!oldPath) {\n    onAbort?.({ reason: 'target-not-found', operation: 'move', pathOrID: oldPathOrID });\n    return query;\n  }\n\n  // Ignore paths that don't identify anything. This must happen before `getNextPath`, which\n  // assumes the source exists when resolving a shift direction.\n  const ruleOrGroupOriginal = findPath(oldPath, query);\n  if (!ruleOrGroupOriginal) {\n    onAbort?.({ reason: 'target-not-found', operation: 'move', pathOrID: oldPathOrID });\n    return query;\n  }\n\n  const nextPath = getNextPath(query, oldPath, newPath);\n\n  // Can't move the root group\n  if (oldPath.length === 0) {\n    onAbort?.({ reason: 'root-not-allowed', operation: 'move', pathOrID: oldPathOrID });\n    return query;\n  }\n\n  const moveGuardReason = getGuardAbortReason(query, oldPath, options);\n  if (moveGuardReason) {\n    onAbort?.({ reason: moveGuardReason, operation: 'move', pathOrID: oldPathOrID });\n    return query;\n  }\n\n  // Don't move to the same location\n  if (pathsAreEqual(oldPath, nextPath)) {\n    onAbort?.({ reason: 'same-location', operation: 'move', pathOrID: oldPathOrID });\n    return query;\n  }\n\n  // Don't move to a path that doesn't exist yet\n  if (!findPath(getParentPath(nextPath), query)) {\n    onAbort?.({ reason: 'destination-not-found', operation: 'move', pathOrID: newPath });\n    return query;\n  }\n\n  // Don't move a group inside itself. The destination is part of the subtree being relocated,\n  // so it ceases to exist the moment the source is spliced out. (Cloning is fine: the source\n  // stays put and a regenerated copy is inserted.)\n  if (!clone && isAncestor(oldPath, nextPath)) {\n    onAbort?.({ reason: 'destination-not-found', operation: 'move', pathOrID: newPath });\n    return query;\n  }\n\n  const ruleOrGroup = clone\n    ? regenerateIDs(\n        isDraft(ruleOrGroupOriginal) ? current(ruleOrGroupOriginal) : ruleOrGroupOriginal,\n        { idGenerator }\n      )\n    : ruleOrGroupOriginal;\n\n  const independentCombinators = isRuleGroupTypeIC(query);\n  const parentOfRuleToRemove = findPath(getParentPath(oldPath), query) as typeof query;\n  const ruleToRemoveIndex = oldPath.at(-1)!;\n  const oldPrevCombinator =\n    independentCombinators && ruleToRemoveIndex > 0\n      ? (parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] as string)\n      : null;\n  const oldNextCombinator =\n    independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1\n      ? (parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] as string)\n      : null;\n\n  // Remove the source item if not cloning\n  if (!clone) {\n    const idxStartDelete = independentCombinators\n      ? Math.max(0, ruleToRemoveIndex - 1)\n      : ruleToRemoveIndex;\n    const deleteLength = independentCombinators ? 2 : 1;\n    parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);\n  }\n\n  const newNewPath = [...nextPath];\n  if (independentCombinators && newNewPath.at(-1)! % 2 === 1) {\n    // Odd indexes in an independent combinator array identify combinators, not\n    // rules/groups. Dropping on a combinator means \"insert after the rule that\n    // precedes it\", which is the same slot as the next (even) index. Normalizing\n    // here keeps the destination index even, which the insertion logic below\n    // relies on to maintain the rule/combinator alternation.\n    newNewPath[newNewPath.length - 1] += 1;\n  }\n  const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);\n  if (\n    !clone &&\n    oldPath.length === commonAncestorPath.length + 1 &&\n    newNewPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]\n  ) {\n    // Getting here means there will be a shift of paths upward at the common\n    // ancestor level because the object at `oldPath` will be spliced out. The\n    // real new path should therefore be one or two higher than `nextPath`.\n    newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;\n  }\n  const newNewParentPath = getParentPath(newNewPath);\n  const parentToInsertInto = findPath(newNewParentPath, query) as typeof query;\n  const newIndex = newNewPath.at(-1)!;\n  // For independent combinator arrays, `newIndex` is the (even) index the moved\n  // rule/group should end up at, but the splice inserts a `[combinator, ruleOrGroup]`\n  // pair, so it must happen one slot earlier.\n  const spliceIndex = independentCombinators && newIndex > 0 ? newIndex - 1 : newIndex;\n\n  /**\n   * This function 1) glosses over the need for type assertions to splice directly\n   * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.\n   */\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const insertRuleOrGroup = (...args: any[]) =>\n    parentToInsertInto.rules.splice(spliceIndex, 0, ...args);\n\n  // Insert the source item at the target path\n  if (parentToInsertInto.rules.length === 0 || !independentCombinators) {\n    insertRuleOrGroup(ruleOrGroup);\n  } else {\n    if (newIndex === 0) {\n      if (ruleToRemoveIndex === 0 && oldNextCombinator) {\n        insertRuleOrGroup(ruleOrGroup, oldNextCombinator);\n      } else {\n        const newNextCombinator =\n          parentToInsertInto.rules[1] ?? oldPrevCombinator ?? getFirstOption(combinators);\n        insertRuleOrGroup(ruleOrGroup, newNextCombinator);\n      }\n    } else {\n      if (oldPrevCombinator) {\n        insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);\n      } else {\n        const newPrevCombinator =\n          parentToInsertInto.rules[spliceIndex - 2] ??\n          oldNextCombinator ??\n          getFirstOption(combinators);\n        insertRuleOrGroup(newPrevCombinator, ruleOrGroup);\n      }\n    }\n  }\n\n  return query;\n};\n\n/**\n * Options for {@link insert}.\n *\n * @group Query Tools\n */\nexport interface InsertOptions extends QueryToolOptions {\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query has independent\n   * combinators), then the first combinator in this list will be inserted\n   * before the new rule/group if the parent group is not empty. This option\n   * is overridden by `combinatorPreceding`.\n   */\n  combinators?: OptionList;\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query has independent\n   * combinators), then this combinator will be inserted before the new rule/group\n   * if the parent group is not empty and the new rule/group is not the first in the\n   * group (`path.at(-1) > 0`). This option will supersede `combinators`.\n   */\n  combinatorPreceding?: string;\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query has independent\n   * combinators), then this combinator will be inserted after the new rule/group\n   * if the parent group is not empty and the new rule/group is the first in the\n   * group (`path.at(-1) === 0`). This option will supersede `combinators`.\n   */\n  combinatorSucceeding?: string;\n  /**\n   * ID generator.\n   *\n   * @default generateID\n   */\n  idGenerator?: () => string;\n  /**\n   * When `true`, the new rule/group will replace the rule/group at `path`.\n   */\n  replace?: boolean;\n}\n\nexport interface InsertMethod {\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** The rule or group to insert. */\n    ruleOrGroup: RG | RuleType,\n    /** Path at which to insert the rule or group. */\n    path: number[],\n    /** Options. */\n    options?: InsertOptions\n  ): RG;\n}\n\n/**\n * Inserts a rule or group into a query without mutating the original query.\n *\n * @returns A new query with the rule or group inserted.\n *\n * @group Query Tools\n */\nexport const insert: InsertMethod = (query, ruleOrGroup, path, options = {}): typeof query =>\n  producerFor(options.freeze)(query, q => insertInPlace(q, ruleOrGroup as RuleType, path, options));\n\n/**\n * Inserts a rule or group into a query in place.\n *\n * @returns The query (mutated in place) with the rule or group inserted.\n *\n * @group Query Tools\n */\nexport const insertInPlace: InsertMethod = (\n  query,\n  ruleOrGroup,\n  path,\n  options = {}\n): typeof query => {\n  const {\n    combinators = defaultCombinators,\n    combinatorPreceding,\n    combinatorSucceeding,\n    idGenerator = generateID,\n    replace = false,\n    onAbort,\n  } = options;\n\n  const parentToInsertInto = findPath(getParentPath(path), query) as typeof query;\n  if (!parentToInsertInto) {\n    onAbort?.({ reason: 'parent-not-found', operation: 'insert', pathOrID: path });\n    return query;\n  }\n\n  if (!isRuleGroup(parentToInsertInto)) {\n    onAbort?.({ reason: 'parent-not-a-group', operation: 'insert', pathOrID: path });\n    return query;\n  }\n\n  const parentPath = getParentPath(path);\n  const insertGuardReason = getGuardAbortReason(query, parentPath, options, { asParent: true });\n  if (insertGuardReason) {\n    onAbort?.({ reason: insertGuardReason, operation: 'insert', pathOrID: path });\n    return query;\n  }\n\n  if (isRuleGroup(ruleOrGroup) && exceedsMaxLevels(parentPath, options)) {\n    onAbort?.({ reason: 'max-levels-exceeded', operation: 'insert', pathOrID: path });\n    return query;\n  }\n\n  const rorg = regenerateIDs(ruleOrGroup, { idGenerator });\n  const independentCombinators = isRuleGroupTypeIC(query);\n  const newIndex = path.at(-1)!;\n\n  /**\n   * This function 1) glosses over the need for type assertions to splice directly\n   * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.\n   */\n  // oxlint-disable-next-line typescript/no-explicit-any\n  const insertRuleOrGroup = (idx: number, ...args: any[]) =>\n    parentToInsertInto.rules.splice(idx, replace ? args.length : 0, ...args);\n\n  // Insert the source item at the target path\n  if (parentToInsertInto.rules.length === 0 || !independentCombinators) {\n    insertRuleOrGroup(newIndex, rorg);\n  } else if (replace && independentCombinators) {\n    insertRuleOrGroup(newIndex + (newIndex % 2), rorg);\n  } else {\n    if (newIndex === 0) {\n      if (rorg.path?.at(-1) === 0 && combinatorSucceeding) {\n        insertRuleOrGroup(newIndex, rorg, combinatorSucceeding);\n      } else {\n        const newNextCombinator =\n          parentToInsertInto.rules[1] ?? combinatorPreceding ?? getFirstOption(combinators);\n        insertRuleOrGroup(newIndex, rorg, newNextCombinator);\n      }\n    } else {\n      const normalizedNewIndex = newIndex % 2 === 0 ? newIndex - 1 : newIndex;\n      if (combinatorPreceding) {\n        insertRuleOrGroup(normalizedNewIndex, combinatorPreceding, rorg);\n      } else {\n        const newPrevCombinator =\n          parentToInsertInto.rules[normalizedNewIndex - 2] ??\n          combinatorSucceeding ??\n          getFirstOption(combinators);\n        insertRuleOrGroup(normalizedNewIndex, newPrevCombinator, rorg);\n      }\n    }\n  }\n\n  return query;\n};\n\n/**\n * Options for {@link group}.\n *\n * @group Query Tools\n */\nexport interface GroupOptions extends QueryToolOptions {\n  /**\n   * When `true`, the source rule/group will not be removed from its original path.\n   */\n  clone?: boolean;\n  /**\n   * If the query extends `RuleGroupTypeIC` (i.e. the query is using independent\n   * combinators), then the first combinator in this list will be inserted between\n   * the two rules/groups.\n   */\n  combinators?: OptionList;\n  /**\n   * ID generator.\n   */\n  idGenerator?: () => string;\n}\n\nexport interface GroupMethod {\n  <RG extends RuleGroupTypeAny>(\n    /** The query to update. */\n    query: RG,\n    /** Path of the rule/group to move or clone. */\n    sourcePathOrID: Path | string,\n    /** Path of the target rule/group, which will become the path of the new group. */\n    targetPathOrID: Path | string,\n    /** Options. */\n    options?: GroupOptions\n  ): RG;\n}\n\n/**\n * Creates a new group at a target path with its `rules` array containing the current\n * objects at the target path and the source path without mutating the original query.\n * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.\n *\n * @returns A new query with the rules or groups grouped.\n *\n * @group Query Tools\n */\nexport const group: GroupMethod = (\n  query,\n  sourcePathOrID,\n  targetPathOrID,\n  options = {}\n): typeof query =>\n  producerFor(options.freeze)(query, q => groupInPlace(q, sourcePathOrID, targetPathOrID, options));\n\n/**\n * Creates a new group at a target path with its `rules` array containing the current\n * objects at the target path and the source path in place.\n * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.\n *\n * @returns The query (mutated in place) with the rules or groups grouped.\n *\n * @group Query Tools\n */\nexport const groupInPlace: GroupMethod = (\n  query,\n  sourcePathOrID,\n  targetPathOrID,\n  options = {}\n): typeof query => {\n  const {\n    clone = false,\n    combinators = defaultCombinators,\n    idGenerator = generateID,\n    onAbort,\n  } = options;\n  const sourcePath = Array.isArray(sourcePathOrID)\n    ? sourcePathOrID\n    : getPathOfID(sourcePathOrID, query);\n  const targetPath = Array.isArray(targetPathOrID)\n    ? targetPathOrID\n    : getPathOfID(targetPathOrID, query);\n\n  // Ignore invalid paths/ids\n  if (!sourcePath) {\n    onAbort?.({ reason: 'target-not-found', operation: 'group', pathOrID: sourcePathOrID });\n    return query;\n  }\n\n  if (!targetPath) {\n    onAbort?.({ reason: 'target-not-found', operation: 'group', pathOrID: targetPathOrID });\n    return query;\n  }\n\n  const nextPath = getNextPath(query, sourcePath, targetPath);\n\n  // Can't group the root group\n  if (sourcePath.length === 0) {\n    onAbort?.({ reason: 'root-not-allowed', operation: 'group', pathOrID: sourcePathOrID });\n    return query;\n  }\n\n  const groupGuardReason = getGuardAbortReason(query, sourcePath, options);\n  if (groupGuardReason) {\n    onAbort?.({ reason: groupGuardReason, operation: 'group', pathOrID: sourcePathOrID });\n    return query;\n  }\n\n  // Don't move to the same location\n  if (pathsAreEqual(sourcePath, nextPath)) {\n    onAbort?.({ reason: 'same-location', operation: 'group', pathOrID: sourcePathOrID });\n    return query;\n  }\n\n  // Don't move to a path that doesn't exist yet\n  if (!findPath(getParentPath(nextPath), query)) {\n    onAbort?.({ reason: 'destination-not-found', operation: 'group', pathOrID: targetPathOrID });\n    return query;\n  }\n\n  // Don't group a group with something inside itself. See the equivalent check in `moveInPlace`.\n  if (!clone && isAncestor(sourcePath, nextPath)) {\n    onAbort?.({ reason: 'destination-not-found', operation: 'group', pathOrID: targetPathOrID });\n    return query;\n  }\n\n  const sourceRuleOrGroupOriginal = findPath(sourcePath, query);\n  const targetRuleOrGroup = findPath(targetPath, query);\n  if (!sourceRuleOrGroupOriginal) {\n    onAbort?.({ reason: 'target-not-found', operation: 'group', pathOrID: sourcePathOrID });\n    return query;\n  }\n\n  if (!targetRuleOrGroup) {\n    onAbort?.({ reason: 'target-not-found', operation: 'group', pathOrID: targetPathOrID });\n    return query;\n  }\n  const sourceRuleOrGroup = clone\n    ? regenerateIDs(\n        isDraft(sourceRuleOrGroupOriginal)\n          ? current(sourceRuleOrGroupOriginal)\n          : sourceRuleOrGroupOriginal,\n        { idGenerator }\n      )\n    : sourceRuleOrGroupOriginal;\n\n  const independentCombinators = isRuleGroupTypeIC(query);\n  const parentOfRuleToRemove = findPath(getParentPath(sourcePath), query) as typeof query;\n  const ruleToRemoveIndex = sourcePath.at(-1)!;\n\n  // Remove the source item if not cloning\n  if (!clone) {\n    const idxStartDelete = independentCombinators\n      ? Math.max(0, ruleToRemoveIndex - 1)\n      : ruleToRemoveIndex;\n    const deleteLength = independentCombinators ? 2 : 1;\n    parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);\n  }\n\n  const newNewPath = [...nextPath];\n  const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);\n  if (\n    !clone &&\n    sourcePath.length === commonAncestorPath.length + 1 &&\n    nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]\n  ) {\n    // Getting here means there will be a shift of paths upward at the common\n    // ancestor level because the object at `oldPath` will be spliced out. The\n    // real new path should therefore be one or two higher than `newPathCalc`.\n    newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;\n  }\n  const newNewParentPath = getParentPath(newNewPath);\n  const parentOfTargetPath = findPath(newNewParentPath, query) as typeof query;\n  const targetPathIndex = newNewPath.at(-1)!;\n\n  // Convert the target path to a group and insert the source and target items as children\n  parentOfTargetPath.rules.splice(\n    targetPathIndex,\n    1,\n    prepareRuleOrGroup(\n      (independentCombinators\n        ? { rules: [targetRuleOrGroup, getFirstOption(combinators), sourceRuleOrGroup] }\n        : {\n            combinator: getFirstOption(combinators),\n            rules: [targetRuleOrGroup, sourceRuleOrGroup],\n            // oxlint-disable-next-line typescript/no-explicit-any\n          }) as any,\n      { idGenerator }\n      // oxlint-disable-next-line typescript/no-explicit-any\n    ) as any\n  );\n\n  return query;\n};\n","import { LogType } from '../defaults';\nimport type {\n  MatchModeOptions,\n  OptionList,\n  Path,\n  RuleGroupTypeAny,\n  RuleGroupTypeIC,\n  RuleType,\n  UpdateableProperties,\n  ValueSourceFullOptions,\n} from '../types';\nimport { isRuleGroup } from './isRuleGroup';\nimport { findPath } from './pathUtils';\nimport { add, getGuardAbortReason, group, move, remove, update } from './queryTools';\n\n/* oxlint-disable typescript/no-explicit-any */\n\n/**\n * Confirmation callbacks invoked before a mutation is applied. Their return values are\n * interpreted differently depending on the operation:\n *\n * - `onAddRule`/`onAddGroup` may return `true` to proceed, a falsy value to cancel, or a\n *   _replacement rule/group_ to add instead of the one provided.\n * - `onMoveRule`/`onMoveGroup`/`onGroupRule`/`onGroupGroup` may return `true` to proceed, a\n *   falsy value to cancel, or a _replacement query_ to apply instead of the computed one.\n * - `onRemove` is boolean only.\n *\n * @group Query Tools\n */\nexport interface QueryActionCallbacks {\n  onAddRule?: (rule: RuleType, parentPath: Path, query: any, context?: any) => RuleType | boolean;\n  onAddGroup?: (\n    ruleGroup: any,\n    parentPath: Path,\n    query: any,\n    context?: any\n  ) => RuleGroupTypeAny | boolean;\n  onRemove?: (ruleOrGroup: any, path: Path, query: any, context?: any) => boolean;\n  onMoveRule?: (...args: any[]) => RuleGroupTypeAny | boolean;\n  onMoveGroup?: (...args: any[]) => RuleGroupTypeAny | boolean;\n  onGroupRule?: (...args: any[]) => RuleGroupTypeAny | boolean;\n  onGroupGroup?: (...args: any[]) => RuleGroupTypeAny | boolean;\n}\n\n/**\n * Configuration for {@link createQueryActions}.\n *\n * @group Query Tools\n */\nexport interface QueryActionsConfig extends QueryActionCallbacks {\n  /** Identifier included in every log payload. */\n  qbId?: string;\n  combinators?: OptionList;\n  idGenerator?: () => string;\n  /** The maximum depth at which groups may be added. Defaults to `Infinity`. */\n  maxLevels?: number;\n  /** Abort every mutation, as though the entire query were disabled. */\n  queryDisabled?: boolean;\n  /**\n   * Honor `disabled` properties within the query. Defaults to `true`, matching the\n   * `QueryBuilder` component; a node's own `disabled` property can always be changed.\n   */\n  respectDisabled?: boolean;\n  /**\n   * Paths disabled by position rather than by a `disabled` property on the node itself, mirroring\n   * the array form of the `QueryBuilder` `disabled` prop. Honored only when `respectDisabled` is\n   * `true`; as with the `disabled` property, a node's own `disabled` can always be changed.\n   */\n  disabledPaths?: Path[];\n  resetOnFieldChange?: boolean;\n  resetOnOperatorChange?: boolean;\n  getRuleDefaultOperator?: (field: string) => string;\n  getValueSources?: (field: string, operator: string) => ValueSourceFullOptions;\n  getRuleDefaultValue?: (rule: RuleType) => any;\n  getMatchModes?: (field: string) => MatchModeOptions;\n  /**\n   * Set `false` to skip immer's auto-freeze on the queries these handlers return, matching the\n   * option of the same name on the query tools and {@link QueryManager}.\n   *\n   * Deep-freezing throws on the reactive proxies used by signals-based frameworks (Svelte\n   * `$state`, Vue `reactive`), so an adapter whose storage may hand a proxied query to these\n   * handlers has to turn it off.\n   *\n   * @default true\n   */\n  freeze?: boolean;\n  /** Receives a structured event for every action, applied or aborted. */\n  onLog?: (payload: Record<string, any>) => void;\n}\n\n/**\n * The six mutations a query builder performs. Each takes the current query and returns the next\n * one, or `undefined` when the mutation was aborted—because the target is disabled, a\n * confirmation callback declined, or a depth limit was reached.\n *\n * @group Query Tools\n */\nexport interface QueryActionHandlers {\n  addRule: (query: any, rule: RuleType, parentPath: Path, context?: any) => any;\n  addGroup: (query: any, ruleGroup: any, parentPath: Path, context?: any) => any;\n  propChange: (query: any, prop: UpdateableProperties, value: any, path: Path) => any;\n  removeRuleOrGroup: (query: any, path: Path, context?: any) => any;\n  moveRule: (\n    query: any,\n    oldPath: Path,\n    newPath: Path | 'up' | 'down',\n    clone?: boolean,\n    context?: any\n  ) => any;\n  groupRule: (\n    query: any,\n    sourcePath: Path,\n    targetPath: Path,\n    clone?: boolean,\n    context?: any\n  ) => any;\n}\n\n/**\n * Builds the query builder's six mutation handlers as pure functions of the current query.\n *\n * This is the framework-agnostic core of the action handlers in `useQueryBuilderSchema`. It owns\n * the policy that surrounds the query tools—disabled gating, the confirmation callback protocol,\n * `maxLevels`, and debug logging—so an implementation only has to supply its own storage: read\n * the current query, call the action, and apply a non-`undefined` result.\n *\n * @group Query Tools\n */\nexport const createQueryActions = (config: QueryActionsConfig = {}): QueryActionHandlers => {\n  const {\n    qbId,\n    combinators,\n    idGenerator,\n    maxLevels = Infinity,\n    queryDisabled,\n    respectDisabled = true,\n    disabledPaths,\n    resetOnFieldChange,\n    resetOnOperatorChange,\n    getRuleDefaultOperator,\n    getValueSources,\n    getRuleDefaultValue,\n    getMatchModes,\n    freeze,\n    onAddRule,\n    onAddGroup,\n    onRemove,\n    onMoveRule,\n    onMoveGroup,\n    onGroupRule,\n    onGroupGroup,\n    onLog,\n  } = config;\n\n  const log = (payload: Record<string, any>) => onLog?.({ qbId, ...payload });\n\n  const guards = { respectDisabled, queryDisabled, disabledPaths };\n\n  /** Whether the mutation is blocked, using the same rules the query tools apply internally. */\n  const blocked = (query: RuleGroupTypeAny, path: Path, asParent = false) =>\n    !!getGuardAbortReason(query, path, guards, { asParent });\n\n  return {\n    addRule: (query, rule, parentPath, context) => {\n      if (blocked(query, parentPath, true)) {\n        log({ type: LogType.parentPathDisabled, rule, parentPath, query });\n        return undefined;\n      }\n\n      const nextRule = onAddRule ? onAddRule(rule, parentPath, query, context) : true;\n      if (!nextRule) {\n        log({ type: LogType.onAddRuleFalse, rule, parentPath, query });\n        return undefined;\n      }\n\n      const newRule = nextRule === true ? rule : nextRule;\n      const newQuery = add(query, newRule, parentPath, {\n        combinators,\n        combinatorPreceding: (newRule as unknown as RuleGroupTypeIC).combinatorPreceding,\n        idGenerator,\n        freeze,\n      });\n      log({ type: LogType.add, query, newQuery, newRule, parentPath });\n      return newQuery;\n    },\n\n    addGroup: (query, ruleGroup, parentPath, context) => {\n      // Depth is checked before anything else, and is deliberately not logged.\n      if (parentPath.length >= maxLevels) return undefined;\n\n      if (blocked(query, parentPath, true)) {\n        log({ type: LogType.parentPathDisabled, ruleGroup, parentPath, query });\n        return undefined;\n      }\n\n      const nextGroup = onAddGroup ? onAddGroup(ruleGroup, parentPath, query, context) : true;\n      if (!nextGroup) {\n        log({ type: LogType.onAddGroupFalse, ruleGroup, parentPath, query });\n        return undefined;\n      }\n\n      const newGroup = nextGroup === true ? ruleGroup : nextGroup;\n      const newQuery = add(query, newGroup, parentPath, {\n        combinators,\n        combinatorPreceding: (newGroup as RuleGroupTypeIC).combinatorPreceding ?? undefined,\n        idGenerator,\n        freeze,\n      });\n      log({ type: LogType.add, query, newQuery, newGroup, parentPath });\n      return newQuery;\n    },\n\n    propChange: (query, prop, value, path) => {\n      // Changing `disabled` is exempt from the path check—otherwise a disabled node could never\n      // be re-enabled—but `queryDisabled` still blocks it.\n      const propGuards = prop === 'disabled' ? { queryDisabled } : guards;\n      if (getGuardAbortReason(query, path, propGuards)) {\n        log({ type: LogType.pathDisabled, path, prop, value, query });\n        return undefined;\n      }\n\n      const newQuery = update(query, prop, value, path, {\n        resetOnFieldChange,\n        resetOnOperatorChange,\n        getRuleDefaultOperator,\n        getValueSources,\n        getRuleDefaultValue,\n        getMatchModes,\n        freeze,\n      });\n      log({ type: LogType.update, query, newQuery, prop, value, path });\n      return newQuery;\n    },\n\n    removeRuleOrGroup: (query, path, context) => {\n      if (blocked(query, path)) {\n        log({ type: LogType.pathDisabled, path, query });\n        return undefined;\n      }\n\n      const ruleOrGroup = findPath(path, query);\n      /* v8 ignore next -- @preserve */\n      if (!ruleOrGroup) return undefined;\n\n      if (onRemove && !onRemove(ruleOrGroup, path, query, context)) {\n        log({ type: LogType.onRemoveFalse, ruleOrGroup, path, query });\n        return undefined;\n      }\n\n      const newQuery = remove(query, path, { freeze });\n      log({ type: LogType.remove, query, newQuery, path, ruleOrGroup });\n      return newQuery;\n    },\n\n    moveRule: (query, oldPath, newPath, clone, context) => {\n      if (blocked(query, oldPath)) {\n        log({ type: LogType.pathDisabled, oldPath, newPath, query });\n        return undefined;\n      }\n\n      // A path that no longer resolves isn't caught by the guards, so confirm it before\n      // computing anything or handing a null node to the callback.\n      const ruleOrGroup = findPath(oldPath, query);\n      if (!ruleOrGroup) return undefined;\n\n      // Computed before the callback so it can inspect the prospective result.\n      const nextQuery = move(query, oldPath, newPath, { clone, combinators, idGenerator, freeze });\n      const isGroup = isRuleGroup(ruleOrGroup);\n      const callback = isGroup ? onMoveGroup : onMoveRule;\n      const callbackResult = callback\n        ? callback(ruleOrGroup, oldPath, newPath, query, nextQuery, { clone, combinators }, context)\n        : true;\n\n      if (!callbackResult) {\n        log({\n          type: isGroup ? LogType.onMoveGroupFalse : LogType.onMoveRuleFalse,\n          ruleOrGroup,\n          oldPath,\n          newPath,\n          clone,\n          query,\n          nextQuery,\n        });\n        return undefined;\n      }\n\n      const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;\n      log({ type: LogType.move, query, newQuery, oldPath, newPath, clone });\n      return newQuery;\n    },\n\n    groupRule: (query, sourcePath, targetPath, clone, context) => {\n      if (blocked(query, sourcePath)) {\n        log({ type: LogType.pathDisabled, sourcePath, targetPath, query });\n        return undefined;\n      }\n\n      // A path that no longer resolves isn't caught by the guards, so confirm it before\n      // computing anything or handing a null node to the callback.\n      const ruleOrGroup = findPath(sourcePath, query);\n      if (!ruleOrGroup) return undefined;\n\n      // Computed before the callback so it can inspect the prospective result.\n      const nextQuery = group(query, sourcePath, targetPath, {\n        clone,\n        combinators,\n        idGenerator,\n        freeze,\n      });\n      const isGroup = isRuleGroup(ruleOrGroup);\n      const callback = isGroup ? onGroupGroup : onGroupRule;\n      const callbackResult = callback\n        ? callback(\n            ruleOrGroup,\n            sourcePath,\n            targetPath,\n            query,\n            nextQuery,\n            { clone, combinators },\n            context\n          )\n        : true;\n\n      if (!callbackResult) {\n        log({\n          type: isGroup ? LogType.onGroupGroupFalse : LogType.onGroupRuleFalse,\n          ruleOrGroup,\n          sourcePath,\n          targetPath,\n          clone,\n          query,\n          nextQuery,\n        });\n        return undefined;\n      }\n\n      const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;\n      log({ type: LogType.group, query, newQuery, sourcePath, targetPath, clone });\n      return newQuery;\n    },\n  };\n};\n","import type {\n  FullCombinator,\n  FullField,\n  FullOptionList,\n  MatchModeOptions,\n  RuleGroupTypeAny,\n  RuleType,\n  ValueSourceFullOptions,\n} from '../types';\nimport { generateID } from './generateID';\nimport { getFirstOption, getOption } from './optGroupUtils';\n\n/**\n * Everything {@link createRule} needs to produce a new rule. Each member corresponds to the\n * `QueryBuilder` prop (or `useQueryBuilderSetup` output) of the same name.\n */\nexport interface CreateRuleOptions<F extends FullField = FullField> {\n  fields: FullOptionList<F>;\n  getDefaultField?: string | ((fieldsData: FullOptionList<F>) => string);\n  /** Produces the default operator for a field, i.e. `resolveDefaultOperator` already bound. */\n  getRuleDefaultOperator: (field: string) => string;\n  /** Produces the value sources for a field/operator pair. */\n  getValueSources: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => ValueSourceFullOptions;\n  /** Produces the match modes for a field. */\n  getMatchModes: (field: string, misc: { fieldData: F }) => MatchModeOptions;\n  /** Produces the default `value` for an otherwise-complete rule. */\n  getRuleDefaultValue: (rule: RuleType) => unknown;\n  idGenerator?: () => string;\n}\n\n/**\n * Creates a rule from the given configuration, applying the same precedence as the\n * `QueryBuilder` component. The `value` is computed in a second pass, once `field`, `operator`,\n * and `valueSource` are known, since the default value depends on all three.\n *\n * @group Query Tools\n */\nexport const createRule = <F extends FullField = FullField>({\n  fields,\n  getDefaultField,\n  getRuleDefaultOperator,\n  getValueSources,\n  getMatchModes,\n  getRuleDefaultValue,\n  idGenerator = generateID,\n}: CreateRuleOptions<F>): RuleType => {\n  let field = getFirstOption(fields) ?? '';\n\n  if (getDefaultField) {\n    if (typeof getDefaultField === 'function') {\n      const defaultField = getDefaultField(fields);\n      // A falsy return leaves the first option in place, rather than producing an empty field.\n      if (defaultField) field = defaultField;\n    } else {\n      field = getDefaultField;\n    }\n  }\n\n  const fieldData = getOption(fields, field) as F;\n  const operator = getRuleDefaultOperator(field);\n  const valueSource = getFirstOption(getValueSources(field, operator, { fieldData })) ?? 'value';\n  const matchMode = getFirstOption(getMatchModes(field, { fieldData }));\n\n  const newRule: RuleType = {\n    id: idGenerator(),\n    field,\n    operator,\n    valueSource,\n    value: '',\n    ...(matchMode ? { match: { mode: matchMode, threshold: 1 } } : null),\n  };\n\n  return { ...newRule, value: getRuleDefaultValue(newRule) };\n};\n\n/**\n * Everything {@link createRuleGroup} needs to produce a new group.\n */\nexport interface CreateRuleGroupOptions<C extends FullCombinator = FullCombinator> {\n  combinators: FullOptionList<C>;\n  /** When `true`, the new group contains one new rule. */\n  addRuleToNewGroups?: boolean;\n  /** Produces that rule, i.e. {@link createRule} already bound. */\n  createRule: () => RuleType;\n  idGenerator?: () => string;\n}\n\n/**\n * Creates a group from the given configuration. Pass `true` for `independentCombinators` to omit\n * the `combinator` property.\n *\n * The group's own `id` is generated _before_ any contained rule's, matching the order the\n * `QueryBuilder` component has always used. This is observable when `idGenerator` is\n * deterministic, as it often is in tests.\n *\n * @group Query Tools\n */\nexport const createRuleGroup = <C extends FullCombinator = FullCombinator>(\n  {\n    combinators,\n    addRuleToNewGroups,\n    createRule: createRuleMain,\n    idGenerator = generateID,\n  }: CreateRuleGroupOptions<C>,\n  independentCombinators?: boolean\n): RuleGroupTypeAny => {\n  // Evaluation order matters: the group's `id` comes first.\n  const id = idGenerator();\n  const rules = addRuleToNewGroups ? [createRuleMain()] : [];\n\n  if (independentCombinators) {\n    return { id, rules, not: false } as RuleGroupTypeAny;\n  }\n\n  return {\n    id,\n    rules,\n    combinator: getFirstOption(combinators) ?? '',\n    not: false,\n  } as RuleGroupTypeAny;\n};\n","import { freeze } from 'immer';\nimport {\n  defaultCoalesceMs,\n  defaultCombinators,\n  defaultMaxHistory,\n  defaultOperatorLabelMap,\n  defaultOperators,\n} from '../defaults';\nimport type {\n  BaseOptionMap,\n  BaseTranslations,\n  DiagnosticsResult,\n  ExportFormat,\n  ExportObjectFormats,\n  FlexibleOption,\n  FlexibleOptionList,\n  FlexibleOptionListProp,\n  FormatQueryOptions,\n  FullCombinator,\n  FullField,\n  FullOperator,\n  FullOption,\n  FullOptionList,\n  FullOptionRecord,\n  InputType,\n  MatchMode,\n  MatchModeOptions,\n  Option,\n  OptionList,\n  ParameterizedNamedSQL,\n  ParameterizedSQL,\n  Path,\n  QueryHistoryOptions,\n  QueryValidator,\n  RQBJsonLogic,\n  RuleGroupProcessor,\n  RuleGroupType,\n  RuleGroupTypeAny,\n  RuleType,\n  ToRuleGroupType,\n  ToRuleGroupTypeIC,\n  UpdateableProperties,\n  UpdateValueMap,\n  ValidationMap,\n  ValueEditorType,\n  ValueSourceFlexibleOptions,\n  ValueSourceFullOptions,\n  ValueSources,\n} from '../types';\nimport { strictAbortReasonSet } from './abortReasons';\nimport { shouldCoalesce } from './coalesce';\nimport { convertFromIC, convertToIC } from './convertQuery';\nimport { defaultValidator } from './defaultValidator';\nimport type { RuleContext, RuleGroupContext } from './deriveRuleContext';\nimport { deriveRuleContext, deriveRuleGroupContext, getFieldData } from './deriveRuleContext';\nimport type {\n  defaultRuleGroupProcessorDrizzle,\n  defaultRuleGroupProcessorSequelize,\n  defaultRuleGroupProcessorTanStackDB,\n} from './formatQuery';\nimport { formatQuery } from './formatQuery';\nimport { generateID } from './generateID';\nimport { getMatchModesUtil } from './getMatchModesUtil';\nimport { getRuleDefaultValue } from './getRuleDefaultValue';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { isRuleGroup, isRuleGroupTypeIC } from './isRuleGroup';\nimport { prepareOptionList } from './optGroupUtils';\nimport {\n  resolveDefaultOperator,\n  resolveOperatorList,\n  resolveValueEditorType,\n  resolveValueList,\n} from './optionResolvers';\nimport { optionsEqual } from './optionsEqual';\nimport type { FindPathReturnType } from './pathUtils';\nimport { findPath, getParentPath, pathIsDisabled } from './pathUtils';\nimport { prepareRuleGroup } from './prepareQueryObjects';\nimport type {\n  AbortInfo,\n  AbortReason,\n  AddOptions,\n  GroupOptions,\n  GuardOptions,\n  InsertOptions,\n  MoveOptions,\n  RemoveOptions,\n  UpdateOptions,\n} from './queryTools';\nimport { add, group, insert, move, remove, update } from './queryTools';\nimport { regenerateIDs } from './regenerateIDs';\nimport { createRule, createRuleGroup } from './ruleFactory';\nimport { signatureOf, unchangedSignature } from './signature';\nimport type { TransformQueryOptions } from './transformQuery';\nimport { transformQuery } from './transformQuery';\n\n/**\n * Thrown by {@link QueryManager} methods in `strict` mode when an operation cannot be carried\n * out because its target could not be used.\n *\n * @group Query Tools\n */\nexport class QueryManagerError extends Error {\n  /** Why the operation was aborted. */\n  readonly code: AbortReason;\n  /** Full details about the aborted operation. */\n  readonly info: AbortInfo;\n\n  constructor(info: AbortInfo) {\n    super(\n      `QueryManager: \"${info.operation}\" aborted (${info.reason})${\n        info.pathOrID === undefined ? '' : ` for target ${JSON.stringify(info.pathOrID)}`\n      }.`\n    );\n    this.name = 'QueryManagerError';\n    this.code = info.reason;\n    this.info = info;\n    // Required for `instanceof` to work when targeting ES5.\n    Object.setPrototypeOf(this, QueryManagerError.prototype);\n  }\n}\n\n/**\n * Per-call overrides for {@link QueryManager}'s abort handling. Every mutating method accepts\n * these alongside the options of the query tool it delegates to.\n *\n * @group Query Tools\n */\nexport interface StrictOptions {\n  /**\n   * Throw a {@link QueryManagerError} when an operation is aborted for one of the\n   * {@link strictAbortReasons}. Overrides the manager's own `strict` option.\n   */\n  strict?: boolean;\n  /**\n   * Called whenever an operation is aborted, including for the non-error reasons\n   * `\"same-location\"` and `\"no-change\"`. Runs before any `strict` throw, so an operation can be\n   * both observed and enforced. Overrides the manager's own `onInvalidTarget` option.\n   */\n  onInvalidTarget?: (info: AbortInfo) => void;\n}\n\n/**\n * The `getDefaultField` option: either a field name or a function that picks one.\n *\n * Named separately from {@link QueryManagerOptions} so callers building the option value\n * conditionally can annotate the intermediate. TypeScript cannot reconcile the two arms of a\n * ternary against an inline union, which otherwise forces a cast.\n *\n * @group Query Tools\n */\nexport type DefaultFieldProp<F extends FullField = FullField> =\n  | string\n  | ((fieldsData: FullOptionList<F>) => string);\n\n/**\n * The `getDefaultOperator` option: either an operator name or a function that picks one.\n *\n * Named separately from {@link QueryManagerOptions} for the same reason as\n * {@link DefaultFieldProp}.\n *\n * @group Query Tools\n */\nexport type DefaultOperatorProp<F extends FullField = FullField> =\n  | string\n  | ((field: string, misc: { fieldData: F }) => string);\n\n/**\n * Options for {@link QueryManager}. Mirrors the subset of\n * {@link react-querybuilder!QueryBuilder QueryBuilder} props that affect query\n * _structure_ rather than rendering, so the same configuration objects can drive both.\n *\n * @group Query Tools\n */\nexport interface QueryManagerOptions<\n  F extends FullField = FullField,\n  O extends FullOperator = FullOperator,\n  C extends FullCombinator = FullCombinator,\n> {\n  /** The fields available for rules. Accepts the same shapes as the `fields` prop. */\n  fields?: FlexibleOptionListProp<F> | BaseOptionMap<F>;\n  /** The operators available for rules. Accepts the same shapes as the `operators` prop. */\n  operators?: FlexibleOptionListProp<O> | BaseOptionMap<O>;\n  /** The combinators available for groups. Defaults to `defaultCombinators`. */\n  combinators?: FlexibleOptionListProp<C> | BaseOptionMap<C>;\n  /** Properties applied to every field in `fields`. */\n  baseField?: Record<string, unknown>;\n  /** Properties applied to every operator in `operators`. */\n  baseOperator?: Record<string, unknown>;\n  /** Properties applied to every combinator in `combinators`. */\n  baseCombinator?: Record<string, unknown>;\n  /** When `false`, an empty placeholder option is prepended to the field list. */\n  autoSelectField?: boolean;\n  /** When `false`, an empty placeholder option is prepended to each operator list. */\n  autoSelectOperator?: boolean;\n  /** When `false`, an empty placeholder option is prepended to each value list. */\n  autoSelectValue?: boolean;\n  /**\n   * Translations, accepting the same shape as the `translations` prop. Only the placeholder\n   * properties of `fields`, `operators`, and `values` are used, and only when the corresponding\n   * `autoSelect*` option is `false`; the remaining keys describe UI elements that have no\n   * meaning outside the `QueryBuilder` component. Labels are typed as `unknown` so the React\n   * `Translations` type, whose labels are `ReactNode`, can be passed as-is.\n   */\n  translations?: Partial<BaseTranslations<unknown>>;\n  /** The default `field` for rules created by {@link QueryManager.createRule}. */\n  getDefaultField?: DefaultFieldProp<F>;\n  /** The default `operator` for a given field. */\n  getDefaultOperator?: DefaultOperatorProp<F>;\n  /** Overrides the computed default `value` for a new rule. */\n  getDefaultValue?: (rule: RuleType, misc: { fieldData: F }) => unknown;\n  /** The operators available for a given field. */\n  getOperators?: (field: string, misc: { fieldData: F }) => FlexibleOptionList<O> | null;\n  /** The value editor type for a given field/operator, which informs the default value. */\n  getValueEditorType?: (field: string, operator: string, misc: { fieldData: F }) => ValueEditorType;\n  /** The value list for a given field/operator, which informs the default value. */\n  getValues?: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => FlexibleOptionList<Option>;\n  /** The valid value sources for a given field/operator. */\n  getValueSources?: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => ValueSources | ValueSourceFlexibleOptions;\n  /** The valid match modes for a given field. */\n  getMatchModes?: (\n    field: string,\n    misc: { fieldData: F }\n  ) => boolean | MatchMode[] | FlexibleOption<MatchMode>[];\n  /** The named parameters available for a given field/operator. */\n  getParameters?: (\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ) => FlexibleOptionList<Option> | null;\n  /** When `true`, multi-value defaults are arrays instead of comma-joined strings. */\n  listsAsArrays?: boolean;\n  /** When `true`, groups created by {@link QueryManager.createRuleGroup} contain one new rule. */\n  addRuleToNewGroups?: boolean;\n  /**\n   * When updating a rule's `field`, reset its `operator`, `value`, and `valueSource` to their\n   * defaults. Defaults to `true`, matching the `QueryBuilder` prop of the same name.\n   */\n  resetOnFieldChange?: boolean;\n  /**\n   * When updating a rule's `operator`, reset its `value` to the default. Defaults to `false`,\n   * matching the `QueryBuilder` prop of the same name.\n   */\n  resetOnOperatorChange?: boolean;\n  /**\n   * The maximum depth at which groups may be added. As with the `QueryBuilder` prop of the same\n   * name, a non-positive value means unlimited. Defaults to `Infinity`.\n   */\n  maxLevels?: number;\n  /**\n   * Honor `disabled` properties within the query, so mutations targeting a disabled rule or\n   * group (or a descendant of a disabled group) are aborted. Updating a node's own `disabled`\n   * property is always permitted. Defaults to `true`, matching the `QueryBuilder` component;\n   * pass `false` to mutate freely regardless of the property.\n   */\n  respectDisabled?: boolean;\n  /**\n   * Paths that are disabled without the corresponding rule or group carrying a `disabled`\n   * property. This mirrors the array form of the `QueryBuilder` `disabled` prop\n   * (e.g. `disabled={[[2]]}`), which disables nodes by position rather than by data.\n   *\n   * A path is treated as disabled if it appears here or descends from a path that does. Honored\n   * only when `respectDisabled` is `true`; as with the `disabled` property, a node's own\n   * `disabled` can always be changed so it is never permanently locked.\n   */\n  disabledPaths?: Path[];\n  /** Abort every mutation, as though the entire query were disabled. Defaults to `false`. */\n  queryDisabled?: boolean;\n  /** The input type for a given field/operator, surfaced by {@link QueryManager.getRuleContext}. */\n  getInputType?: (field: string, operator: string, misc: { fieldData: F }) => InputType | null;\n  /** Extra props for a subquery builder, surfaced by {@link QueryManager.getRuleContext}. */\n  getSubQueryBuilderProps?: (field: string, misc: { fieldData: F }) => Record<string, unknown>;\n  /**\n   * Enables undo/redo recording. Pass `true` for the defaults, or an object to configure\n   * `maxHistory` and/or `coalesceMs`. Disabled by default, so instances that never undo\n   * retain no extra references.\n   */\n  history?: boolean | QueryHistoryOptions;\n  /**\n   * Throw a {@link QueryManagerError} when a mutation is aborted because its target could not\n   * be used. Disabled by default, in which case such mutations are silent no-ops. Can be\n   * overridden per call.\n   */\n  strict?: boolean;\n  /**\n   * Called whenever a mutation is aborted, including for the non-error reasons\n   * `\"same-location\"` and `\"no-change\"`. Can be overridden per call.\n   */\n  onInvalidTarget?: (info: AbortInfo) => void;\n  /**\n   * Deep-freeze everything the manager hands out—the query, the field list, the field map, and\n   * the combinator list—so accidental mutation throws in strict mode. Defaults to `true`.\n   *\n   * Pass `false` when the manager's output is handed to a framework that wraps objects in\n   * proxies (Vue `reactive`, Solid stores) or otherwise needs to mutate them. This also disables\n   * immer's auto-freeze for mutations made through the manager.\n   *\n   * The shallow copy returned by {@link QueryManager.getOptions} is frozen either way: it is a\n   * one-level copy that no framework proxy is placed inside, so freezing it costs nothing and\n   * still prevents callers from mutating the options snapshot they were handed.\n   */\n  freeze?: boolean;\n  /** Validates the query. Defaults to {@link defaultValidator}. */\n  validator?: QueryValidator;\n  /** Generates `id` properties for new rules and groups. Defaults to {@link generateID}. */\n  idGenerator?: () => string;\n  /**\n   * Clock used to time history coalescing. Defaults to `Date.now`.\n   *\n   * @internal Test seam. Exists so that history recording can be compared against the\n   * `react-querybuilder/history` implementation without depending on wall-clock timing.\n   */\n  now?: () => number;\n}\n\n/** Everything {@link QueryManager.batch} restores when the batched function throws. */\ninterface QueryManagerSnapshot<RG extends RuleGroupTypeAny> {\n  query: RG;\n  past: RG[];\n  future: RG[];\n  lastSig: string | undefined;\n  lastAt: number;\n}\n\n/**\n * What changed in the notification a {@link QueryManager.subscribe} listener is receiving.\n *\n * The two flags are independent, and at least one is always `true`. A single notification can\n * report both: a {@link QueryManager.batch batch} containing a\n * {@link QueryManager.reconfigure reconfigure} and a mutation emits one\n * `{ query: true, config: true }`.\n *\n * Listeners that ignore their argument keep working exactly as before — this exists so that a\n * framework adapter can skip the work a change does not affect (re-deriving option lists on a\n * query-only change, say) without diffing the manager's output to find out.\n *\n * @group Query Tools\n */\nexport interface SubscriptionChange {\n  /** The query was replaced. */\n  query: boolean;\n  /** Options were applied, so option lists and any derived configuration may have changed. */\n  config: boolean;\n}\n\n/**\n * A single rule or group encountered by {@link QueryManager.walk}, along with where it was found.\n *\n * @group Query Tools\n */ export interface QueryNode<RG extends RuleGroupTypeAny = RuleGroupType> {\n  /** The rule or group itself. */\n  node: RG | RuleType;\n  /** The {@link Path} of `node` within the query. The root group's path is `[]`. */\n  path: Path;\n  /** The group containing `node`, or `null` for the root group. */\n  parent: RG | null;\n}\n\n/**\n * Options for {@link QueryManager.walk} and its derivatives.\n *\n * @group Query Tools\n */\nexport interface WalkOptions {\n  /**\n   * Traverse only the subtree rooted at this path or `id` instead of the whole query. The node\n   * itself is visited first. When the path or `id` can't be resolved, nothing is visited.\n   */\n  from?: Path | string;\n  /** Visit only rules. Groups are still traversed, just not yielded (except as `parent`). */\n  rulesOnly?: boolean;\n  /** Visit only groups. */\n  groupsOnly?: boolean;\n}\n\n/**\n * Coerces the result of a conditional query type back into something assignable to\n * {@link QueryManager}'s `RG` parameter, which TypeScript cannot verify on its own.\n */\ntype AsRuleGroup<T> = T extends RuleGroupTypeAny ? T : RuleGroupTypeAny;\n\n/**\n * Key of the single own property holding every {@link QueryManager} instance's state.\n *\n * `#private` fields are unreachable from a `Proxy`: inside a method invoked through one, `this`\n * _is_ the proxy, and the private brand lives on the target, so every access throws\n * `TypeError: Cannot read private member`. Frameworks wrap objects in proxies routinely — Vue's\n * `reactive()`, and by extension Vue Test Utils' handling of mount props, do it implicitly — so\n * consumers hit that failure by accident rather than by choice.\n *\n * A `WeakMap` keyed by instance does not fix it either, for the same reason: `weakMap.get(this)`\n * misses the entry stored under the target. An ordinary own property is the only mechanism that\n * reads correctly through a proxy, because the `get` trap forwards to the target.\n *\n * The symbol is module-private and never exported. Reaching into the state bag (via\n * `Object.getOwnPropertySymbols`, say) is not a supported access path and its contents may change\n * in any release.\n */\nconst kState: unique symbol = Symbol('QueryManager.state');\n\n// The three possible notification payloads. Shared and frozen: subscribers receive them\n// directly, and there is no per-notification data beyond the two flags.\nconst queryChange: SubscriptionChange = freeze({ query: true, config: false });\nconst configChange: SubscriptionChange = freeze({ query: false, config: true });\nconst queryAndConfigChange: SubscriptionChange = freeze({ query: true, config: true });\n\n/**\n * Every mutable member of a {@link QueryManager}. The option-derived members are assigned by\n * `applyOptions`, which the constructor calls before anything else; the rest are initialized by\n * {@link createManagerState}.\n */\ninterface ManagerState<\n  RG extends RuleGroupTypeAny,\n  F extends FullField,\n  O extends FullOperator,\n  C extends FullCombinator,\n> {\n  query: RG;\n  // The members below are derived from the options and are reassigned by `reconfigure`, so none\n  // of them can be `readonly`. Anything handed out directly is frozen instead.\n  options: QueryManagerOptions<F, O, C>;\n  fields: FullOptionList<F>;\n  fieldMap: Partial<FullOptionRecord<F>>;\n  operators: FullOptionList<O>;\n  combinators: FullOptionList<C>;\n  idGenerator: () => string;\n  validator: QueryValidator;\n  strict: boolean;\n  respectDisabled: boolean;\n  onInvalidTarget: ((info: AbortInfo) => void) | undefined;\n  freezeEnabled: boolean;\n  readonly listeners: Set<(change: SubscriptionChange) => void>;\n  historyEnabled: boolean;\n  maxHistory: number;\n  coalesceMs: number;\n  now: () => number;\n  /** Incremented by every {@link QueryManager.reconfigure} call. See `getConfigVersion`. */\n  configVersion: number;\n  past: RG[];\n  future: RG[];\n  lastSig: string | undefined;\n  lastAt: number;\n  batchDepth: number;\n  batchSnapshot: QueryManagerSnapshot<RG> | undefined;\n  /** Whether a history-stack method ran inside the batch currently in progress. */\n  historyBypassed: boolean;\n  /**\n   * Whether a `reconfigure` ran inside the batch currently in progress. Its notification is\n   * deferred to the batch's end and merged into that one, so a batch never emits two.\n   */\n  pendingConfigNotify: boolean;\n  /**\n   * The query the caches below were derived from. Caches are keyed on query _identity_ rather\n   * than invalidated from `commit` because `undo`, `redo`, and `batch`'s rollback all assign\n   * `query` directly.\n   */\n  cacheFor: RG | undefined;\n  idPathIndex: Map<string, Path> | undefined;\n  validation: boolean | ValidationMap | undefined;\n}\n\n/**\n * Builds the state bag. The option-derived members are left unset for `applyOptions` to fill in,\n * hence the assertion.\n */\nconst createManagerState = <\n  RG extends RuleGroupTypeAny,\n  F extends FullField,\n  O extends FullOperator,\n  C extends FullCombinator,\n>(): ManagerState<RG, F, O, C> => {\n  const state = {\n    listeners: new Set<(change: SubscriptionChange) => void>(),\n    configVersion: 0,\n    past: [],\n    future: [],\n    lastAt: 0,\n    batchDepth: 0,\n    historyBypassed: false,\n    pendingConfigNotify: false,\n  } as unknown as ManagerState<RG, F, O, C>;\n\n  // Vue's `reactive()` skips any object carrying a truthy `__v_skip` — this is exactly what\n  // `markRaw` sets. Without it the bag would be lazily deep-proxied on first access, so every\n  // internal read (the cached-reader path, `index`, `walkFrom`) would go through a proxy, and\n  // `idPathIndex` would become a reactive `Map` for no benefit. Set here rather than by importing\n  // `markRaw`, which would make core depend on a framework.\n  Object.defineProperty(state, '__v_skip', { value: true, enumerable: false });\n\n  return state;\n};\n\n/**\n * Stateful wrapper around the {@link add}/{@link remove}/{@link update}/{@link move}/\n * {@link insert}/{@link group} query tools, plus rule/group factories, {@link defaultValidator\n * validation}, and {@link formatQuery formatting}.\n *\n * The query is held internally, so each method takes the same arguments as its `queryTools`\n * counterpart minus the leading `query` parameter, and returns the manager itself for chaining.\n * Mutations use the non-`InPlace` tools, so a query previously handed out by\n * {@link QueryManager.getQuery} is never modified. Under `freeze: false` that remains true, but\n * as a convention rather than a runtime-enforced guarantee.\n *\n * ```ts\n * const q = new QueryManager(undefined, { fields });\n * q.add(q.createRule()).add({ field: 'firstName', operator: '=', value: 'Steve' });\n * q.format('sql');\n * ```\n *\n * Like the underlying query tools, methods are a no-op when the target path or `id` can't be\n * resolved (including attempts to remove the root group). By default nothing is thrown; pass\n * `strict: true` to raise a {@link QueryManagerError} instead, or `onInvalidTarget` to observe\n * aborted operations without changing control flow.\n *\n * @group Query Tools\n */\nexport class QueryManager<\n  RG extends RuleGroupTypeAny = RuleGroupType,\n  F extends FullField = FullField,\n  O extends FullOperator = FullOperator,\n  C extends FullCombinator = FullCombinator,\n> {\n  /**\n   * All instance state, rather than `#private` fields. See `kState` for why.\n   *\n   * The property itself is symbol-keyed and installed by the constructor; this accessor exists\n   * because `isolatedDeclarations` cannot emit a computed property name keyed by a symbol the\n   * module does not export, and exporting it would put it in the public API surface. A\n   * prototype accessor is proxy-safe for the same reason the own property is: `this` is the\n   * proxy, and the `get` trap forwards to the target.\n   */\n  private get state(): ManagerState<RG, F, O, C> {\n    return (this as unknown as Record<typeof kState, ManagerState<RG, F, O, C>>)[kState];\n  }\n\n  constructor(query?: RG, options: QueryManagerOptions<F, O, C> = {}) {\n    // Every subsequent member access goes through this property, so it has to be installed\n    // before anything else runs. `applyOptions` fills in the option-derived members.\n    Object.defineProperty(this, kState, {\n      value: createManagerState<RG, F, O, C>(),\n      enumerable: false,\n      writable: false,\n      configurable: false,\n    });\n\n    this.applyOptions(options);\n\n    this.state.query = this.freeze(\n      query\n        ? prepareRuleGroup(query, { idGenerator: this.state.idGenerator })\n        : this.createRuleGroup()\n    );\n  }\n\n  /**\n   * Deep-freezes `x` unless the `freeze` option is `false`. Every value the manager hands out\n   * directly goes through here; the shallow copies returned by {@link QueryManager.getOptions}\n   * and passed to `applyOptions` are frozen unconditionally instead.\n   */\n  private freeze<T>(x: T): T {\n    return this.state.freezeEnabled ? freeze(x, true) : x;\n  }\n\n  /**\n   * Assigns `options` and every field derived from it. Shared by the constructor and\n   * {@link QueryManager.reconfigure}, so the two can never drift apart. Does not touch the\n   * query, the history stacks, the caches, or the subscriber list.\n   */\n  private applyOptions(options: QueryManagerOptions<F, O, C>): void {\n    this.state.options = options;\n    this.state.freezeEnabled = options.freeze ?? true;\n    this.state.idGenerator = options.idGenerator ?? generateID;\n    this.state.validator = options.validator ?? defaultValidator;\n    this.state.strict = options.strict ?? false;\n    this.state.respectDisabled = options.respectDisabled ?? true;\n    this.state.onInvalidTarget = options.onInvalidTarget;\n\n    const history = options.history ?? false;\n    const historyOptions: QueryHistoryOptions = typeof history === 'object' ? history : {};\n    this.state.historyEnabled = history !== false;\n    this.state.maxHistory = historyOptions.maxHistory ?? defaultMaxHistory;\n    this.state.coalesceMs = historyOptions.coalesceMs ?? defaultCoalesceMs;\n    this.state.now = options.now ?? Date.now;\n\n    const { optionList: fields, optionsMap: fieldMap } = prepareOptionList<F>({\n      optionList: options.fields,\n      baseOption: options.baseField,\n      autoSelectOption: options.autoSelectField,\n      placeholder: options.translations?.fields,\n    });\n    // Both are frozen (unless `freeze` is `false`) because `getFields` and `getFieldData` hand\n    // their contents out directly. `prepareOptionList` builds the map's values as separate\n    // objects from the list's, so freezing one does not freeze the other.\n    this.state.fields = this.freeze(fields);\n    this.state.fieldMap = this.freeze(fieldMap);\n\n    this.state.operators = prepareOptionList<O>({\n      optionList: (options.operators ?? defaultOperators) as FlexibleOptionListProp<O>,\n      baseOption: options.baseOperator,\n      labelMap: defaultOperatorLabelMap,\n      autoSelectOption: options.autoSelectOperator,\n      placeholder: options.translations?.operators,\n    }).optionList;\n\n    // Frozen because `getCombinators` hands this array out directly; see also `fields`.\n    this.state.combinators = this.freeze(\n      prepareOptionList<C>({\n        optionList: (options.combinators ?? defaultCombinators) as FlexibleOptionListProp<C>,\n        baseOption: options.baseCombinator,\n      }).optionList\n    );\n  }\n\n  // #region Internal resolution\n\n  /** Resolves the field configuration for a field name. */\n  private fieldData(field: string): F {\n    return ((this.state.fieldMap as Record<string, F | undefined>)[field] ?? {}) as F;\n  }\n\n  /** Resolves the operator list for a field, mirroring `QueryBuilder`'s precedence. */\n  private operatorsFor(field: string): FullOptionList<O> {\n    return resolveOperatorList<F, O>({\n      field,\n      fieldData: this.fieldData(field),\n      getOperators: this.state.options.getOperators,\n      operators: this.state.operators,\n      baseOption: this.state.options.baseOperator,\n      autoSelectOption: this.state.options.autoSelectOperator,\n      placeholder: this.state.options.translations?.operators,\n    });\n  }\n\n  /** Resolves the default operator for a field, mirroring `QueryBuilder`'s precedence. */\n  private defaultOperator(field: string): string {\n    return resolveDefaultOperator<F>({\n      field,\n      fieldData: this.fieldData(field),\n      getDefaultOperator: this.state.options.getDefaultOperator,\n      getOperators: (f: string) => this.operatorsFor(f),\n    });\n  }\n\n  private valueSourcesFor(field: string, operator: string) {\n    return getValueSourcesUtil<F, string>(\n      this.fieldData(field),\n      operator,\n      this.state.options.getValueSources\n    );\n  }\n\n  private matchModesFor(field: string): MatchModeOptions {\n    return getMatchModesUtil<F>(this.fieldData(field), this.state.options.getMatchModes);\n  }\n\n  private valuesFor(field: string, operator: string): FullOptionList<Option> {\n    return resolveValueList<F>({\n      field,\n      operator,\n      fieldData: this.fieldData(field),\n      getValues: this.state.options.getValues,\n      autoSelectOption: this.state.options.autoSelectValue,\n      placeholder: this.state.options.translations?.values,\n    });\n  }\n\n  private valueEditorTypeFor(field: string, operator: string): ValueEditorType {\n    return resolveValueEditorType<F>({\n      field,\n      operator,\n      fieldData: this.fieldData(field),\n      getValueEditorType: this.state.options.getValueEditorType,\n    });\n  }\n\n  /** Computes the default `value` for a rule, mirroring `QueryBuilder`'s precedence. */\n  private defaultValue(rule: RuleType): unknown {\n    const { getDefaultValue, getParameters, listsAsArrays } = this.state.options;\n    return getRuleDefaultValue<F>(rule, {\n      fieldData: this.fieldData(rule.field),\n      fields: this.state.fields,\n      listsAsArrays,\n      getValueEditorType: (f, o) => this.valueEditorTypeFor(f, o),\n      getValues: (f, o) => this.valuesFor(f, o),\n      getDefaultValue: getDefaultValue && ((r, misc) => getDefaultValue(r, misc)),\n      getParameters: getParameters && ((f, o, misc) => this.parametersFor(f, o, misc)),\n    });\n  }\n\n  /**\n   * Resolves the parameter list for a field/operator pair, normalized the same way as every\n   * other option list. Shared by `defaultValue` and {@link QueryManager.getRuleContext} so both\n   * see the same shape.\n   */\n  private parametersFor(\n    field: string,\n    operator: string,\n    misc: { fieldData: F }\n  ): FullOptionList<Option> {\n    return prepareOptionList<FullOption>({\n      optionList: this.state.options.getParameters?.(field, operator, misc) ?? [],\n      autoSelectOption: this.state.options.autoSelectValue,\n    }).optionList;\n  }\n\n  /** Defaults shared by every mutating method, overridable per call. */\n  private guardOptions(): GuardOptions & { freeze: boolean } {\n    const { maxLevels } = this.state.options;\n\n    return {\n      // Spread by every tool call the manager makes, so the `freeze` option lives here rather\n      // than in `toolOptions`, which `remove` does not use.\n      freeze: this.state.freezeEnabled,\n      // `QueryBuilder` treats a non-positive `maxLevels` as unlimited; match that.\n      maxLevels: (maxLevels ?? 0) > 0 ? Number(maxLevels) : Infinity,\n      respectDisabled: this.state.respectDisabled,\n      disabledPaths: this.state.options.disabledPaths,\n      queryDisabled: this.state.options.queryDisabled,\n    };\n  }\n\n  private toolOptions() {\n    return {\n      combinators: this.state.combinators,\n      idGenerator: this.state.idGenerator,\n      ...this.guardOptions(),\n    };\n  }\n\n  /**\n   * Builds the `onAbort` handler passed to the query tools, applying the per-call overrides on\n   * top of the manager's own options.\n   */\n  private onAbort({ strict, onInvalidTarget }: StrictOptions): (info: AbortInfo) => void {\n    const strictMain = strict ?? this.state.strict;\n    const handler = onInvalidTarget ?? this.state.onInvalidTarget;\n\n    return info => {\n      // The handler always runs, for every reason, before `strict` is considered.\n      handler?.(info);\n\n      if (strictMain && strictAbortReasonSet.has(info.reason)) {\n        throw new QueryManagerError(info);\n      }\n    };\n  }\n\n  /** Defaults for {@link update}, so resets mirror `QueryBuilder`'s behavior. */\n  private updateOptions(): UpdateOptions {\n    return {\n      getRuleDefaultOperator: f => this.defaultOperator(f),\n      getRuleDefaultValue: r => this.defaultValue(r),\n      getValueSources: (f, o) => this.valueSourcesFor(f, o),\n      getMatchModes: f => this.matchModesFor(f),\n      resetOnFieldChange: this.state.options.resetOnFieldChange,\n      resetOnOperatorChange: this.state.options.resetOnOperatorChange,\n      ...this.guardOptions(),\n    };\n  }\n\n  /**\n   * Applies a new query, recording history and notifying subscribers as appropriate. Every\n   * mutation funnels through here. A tool that could not resolve its target returns the same\n   * query object, which is treated as a no-op.\n   */\n  private commit(next: RG): void {\n    const prev = this.state.query;\n    if (prev === next) return;\n\n    this.state.query = next;\n\n    // Within a batch, history and notification are deferred until the outermost call ends,\n    // so a batch produces one undo step and one notification.\n    if (this.state.batchDepth > 0) return;\n\n    this.record(prev, next);\n    this.notify(queryChange);\n  }\n\n  /**\n   * Records a change, either as a new history entry or by absorbing it into the current one.\n   * Mirrors the recording semantics of the `react-querybuilder/history` entry point.\n   */\n  private record(prev: RG, next: RG): void {\n    if (!this.state.historyEnabled) return;\n\n    const sig = signatureOf(prev, next);\n\n    // The query object changed but nothing observable did, so an entry here would appear to do\n    // nothing when undone.\n    if (sig === unchangedSignature) return;\n\n    const now = this.state.now();\n    const canCoalesce = shouldCoalesce(\n      this.state.lastSig,\n      sig,\n      this.state.lastAt,\n      now,\n      this.state.coalesceMs\n    );\n\n    if (!canCoalesce) {\n      this.state.past.push(prev);\n      if (this.state.past.length > this.state.maxHistory) this.state.past.shift();\n      this.state.future = [];\n    }\n\n    this.state.lastSig = sig;\n    this.state.lastAt = now;\n  }\n\n  private notify(change: SubscriptionChange): void {\n    for (const listener of this.state.listeners) listener(change);\n  }\n\n  /**\n   * Records that a history-stack method ran inside the current batch. Those methods manage\n   * `past`/`future` themselves, so the batch must not also record an entry on completion —\n   * doing so would push a duplicate onto `past` and clear the redo stack that `undo` just\n   * populated.\n   */\n  private markHistoryBypassed(): void {\n    if (this.state.batchDepth > 0) this.state.historyBypassed = true;\n  }\n\n  /**\n   * Discards every cached derivation when the query has been replaced since they were computed.\n   * Called at the top of each cached reader.\n   */\n  private ensureCache(): void {\n    if (this.state.cacheFor === this.state.query) return;\n\n    this.state.cacheFor = this.state.query;\n    this.state.idPathIndex = undefined;\n    this.state.validation = undefined;\n  }\n\n  /**\n   * The single traversal implementation. Combinator strings in independent-combinator groups\n   * are skipped.\n   *\n   * @yields The subtree rooted at `node`, depth-first in pre-order, starting with `node` itself.\n   */\n  private *walkFrom(node: RG | RuleType, path: Path, parent: RG | null): Generator<QueryNode<RG>> {\n    yield { node, path, parent };\n\n    if (!isRuleGroup(node)) return;\n\n    const startGroup = node as RG;\n    for (const [index, child] of startGroup.rules.entries()) {\n      // Independent-combinator groups interleave combinator strings among the rules.\n      if (typeof child === 'string') continue;\n      yield* this.walkFrom(child as RG | RuleType, [...path, index], startGroup);\n    }\n  }\n\n  /** Builds (once per query) the `id` to {@link Path} index backing `findID`/`getPathOfID`. */\n  private index(): Map<string, Path> {\n    this.ensureCache();\n\n    if (!this.state.idPathIndex) {\n      const index = new Map<string, Path>();\n      for (const { node, path } of this.walkFrom(this.state.query, [], null)) {\n        // The first occurrence wins, matching `findID`'s depth-first search order.\n        if (node.id !== undefined && !index.has(node.id)) index.set(node.id, path);\n      }\n      this.state.idPathIndex = index;\n    }\n\n    return this.state.idPathIndex;\n  }\n\n  /** Resolves a path or `id` to a path, or `null` when the `id` isn't present. */\n  private toPath(pathOrID: Path | string): Path | null {\n    return typeof pathOrID === 'string' ? (this.index().get(pathOrID) ?? null) : pathOrID;\n  }\n\n  // #endregion\n\n  // #region State access\n\n  /**\n   * The current query. The returned object is structurally shared, so it is safe to retain and\n   * compare by reference to detect changes. It is also frozen unless the `freeze` option is\n   * `false`.\n   *\n   * Like {@link QueryManager.subscribe}, this method is bound to the instance, so it can be\n   * passed as a bare reference (e.g. as the `getSnapshot` argument to `useSyncExternalStore`).\n   */\n  getQuery = (): RG => this.state.query;\n\n  /** Replaces the current query, ensuring every rule and group has an `id`. */\n  setQuery(query: RG): this {\n    this.commit(this.freeze(prepareRuleGroup(query, { idGenerator: this.state.idGenerator })));\n    return this;\n  }\n\n  // #endregion\n\n  // #region Factories\n\n  /**\n   * Creates a rule using the configured fields, operators, and defaults. The rule is not added\n   * to the query—pass it to {@link QueryManager.add} or {@link QueryManager.insert}.\n   */\n  createRule(): RuleType {\n    return createRule<F>({\n      fields: this.state.fields,\n      getDefaultField: this.state.options.getDefaultField,\n      getRuleDefaultOperator: f => this.defaultOperator(f),\n      getValueSources: (f, o) => this.valueSourcesFor(f, o),\n      getMatchModes: f => this.matchModesFor(f),\n      getRuleDefaultValue: r => this.defaultValue(r),\n      idGenerator: this.state.idGenerator,\n    });\n  }\n\n  /**\n   * Creates a group. Pass `true` for a group with independent combinators. The group is not\n   * added to the query—pass it to {@link QueryManager.add} or {@link QueryManager.insert}.\n   */\n  createRuleGroup(independentCombinators?: boolean): RG {\n    return createRuleGroup<C>(\n      {\n        combinators: this.state.combinators,\n        addRuleToNewGroups: this.state.options.addRuleToNewGroups,\n        createRule: () => this.createRule(),\n        idGenerator: this.state.idGenerator,\n      },\n      independentCombinators\n    ) as RG;\n  }\n\n  // #endregion\n\n  // #region Mutators\n\n  /**\n   * Adds a rule or group to the end of the group at `parentPathOrID`, which defaults to the\n   * root group.\n   */\n  add(\n    ruleOrGroup: RG | RuleType,\n    parentPathOrID: Path | string = [],\n    options: AddOptions & StrictOptions = {}\n  ): this {\n    const { strict, onInvalidTarget, ...toolOptions } = options;\n    this.commit(\n      add(this.state.query, ruleOrGroup, parentPathOrID, {\n        ...this.toolOptions(),\n        ...toolOptions,\n        onAbort: this.onAbort({ strict, onInvalidTarget }),\n      })\n    );\n    return this;\n  }\n\n  /** Removes the rule or group at the given path or `id`. The root group cannot be removed. */\n  remove(pathOrID: Path | string, options: RemoveOptions & StrictOptions = {}): this {\n    const { strict, onInvalidTarget, ...toolOptions } = options;\n    this.commit(\n      remove(this.state.query, pathOrID, {\n        ...this.guardOptions(),\n        ...toolOptions,\n        onAbort: this.onAbort({ strict, onInvalidTarget }),\n      })\n    );\n    return this;\n  }\n\n  /** Updates a single property of the rule or group at the given path or `id`. */\n  update(\n    prop: UpdateableProperties,\n    value: unknown,\n    pathOrID: Path | string,\n    options?: UpdateOptions & StrictOptions\n  ): this;\n  /** Updates multiple properties using parallel arrays of names and values. */\n  update(\n    props: UpdateableProperties[],\n    values: unknown[],\n    pathOrID: Path | string,\n    options?: UpdateOptions & StrictOptions\n  ): this;\n  /** Updates multiple properties using a map of names to values. */\n  update(\n    props: UpdateValueMap,\n    pathOrID: Path | string,\n    options?: UpdateOptions & StrictOptions\n  ): this;\n  update(a: unknown, b?: unknown, c?: unknown, d?: unknown): this {\n    // The property map form shifts `pathOrID` and `options` one position earlier.\n    const optionsIndex = typeof a === 'string' || Array.isArray(a) ? 3 : 2;\n    const args = [a, b, c, d];\n    const { strict, onInvalidTarget, ...toolOptions }: UpdateOptions & StrictOptions =\n      args[optionsIndex] ?? {};\n    args[optionsIndex] = {\n      ...this.updateOptions(),\n      ...toolOptions,\n      onAbort: this.onAbort({ strict, onInvalidTarget }),\n    };\n\n    // oxlint-disable-next-line typescript/no-explicit-any\n    this.commit((update as any)(this.state.query, ...args.slice(0, optionsIndex + 1)));\n    return this;\n  }\n\n  /** Moves the rule or group at `oldPathOrID` to `newPath`, or shifts it `'up'`/`'down'`. */\n  move(\n    oldPathOrID: Path | string,\n    newPath: Path | 'up' | 'down',\n    options: MoveOptions & StrictOptions = {}\n  ): this {\n    const { strict, onInvalidTarget, ...toolOptions } = options;\n    this.commit(\n      move(this.state.query, oldPathOrID, newPath, {\n        ...this.toolOptions(),\n        ...toolOptions,\n        onAbort: this.onAbort({ strict, onInvalidTarget }),\n      })\n    );\n    return this;\n  }\n\n  /**\n   * Inserts a rule or group at the given path. Unlike the other methods, this accepts a path\n   * only—inserting _at_ an `id` would be ambiguous.\n   */\n  insert(\n    ruleOrGroup: RG | RuleType,\n    path: Path,\n    options: InsertOptions & StrictOptions = {}\n  ): this {\n    const { strict, onInvalidTarget, ...toolOptions } = options;\n    this.commit(\n      insert(this.state.query, ruleOrGroup, path, {\n        ...this.toolOptions(),\n        ...toolOptions,\n        onAbort: this.onAbort({ strict, onInvalidTarget }),\n      })\n    );\n    return this;\n  }\n\n  /**\n   * Creates a new group at `targetPathOrID` containing the rules/groups currently at\n   * `targetPathOrID` and `sourcePathOrID`.\n   */\n  group(\n    sourcePathOrID: Path | string,\n    targetPathOrID: Path | string,\n    options: GroupOptions & StrictOptions = {}\n  ): this {\n    const { strict, onInvalidTarget, ...toolOptions } = options;\n    this.commit(\n      group(this.state.query, sourcePathOrID, targetPathOrID, {\n        ...this.toolOptions(),\n        ...toolOptions,\n        onAbort: this.onAbort({ strict, onInvalidTarget }),\n      })\n    );\n    return this;\n  }\n\n  // #endregion\n\n  // #region Configuration\n\n  /**\n   * The options currently in effect, as a frozen shallow copy. Reflects everything applied by\n   * the constructor and any subsequent {@link QueryManager.reconfigure} calls, but not the\n   * defaults filled in for options that were never provided.\n   */\n  getOptions(): Readonly<QueryManagerOptions<F, O, C>> {\n    return freeze({ ...this.state.options });\n  }\n\n  /**\n   * Updates the manager's configuration in place, keeping the current query, the undo/redo\n   * history, and every subscriber. Use this to propagate new `translations`, `fields`,\n   * `operators`, and so on without discarding state:\n   *\n   * ```ts\n   * q.reconfigure({ translations: { fields: { placeholderLabel: 'Choisir un champ' } } });\n   * ```\n   *\n   * The incoming options are shallow-merged over the current ones, so keys left out are\n   * preserved. Passing a key explicitly as `undefined` resets it to its default. Object-valued\n   * options like `translations` are replaced wholesale rather than deep-merged — spread the\n   * current value in yourself to patch one key. Pass `{ replace: true }` to discard the\n   * existing options entirely and start from the incoming set.\n   *\n   * The query is never rewritten, even when the new options no longer describe it: a rule whose\n   * `field` is not in the new `fields` list is left as-is. Call\n   * {@link QueryManager.validate validate} to detect that, or `setQuery(getQuery())` to\n   * re-normalize.\n   *\n   * History options are honored immediately: lowering `maxHistory` trims the undo stack, and\n   * turning history off clears both stacks.\n   *\n   * A call that resolves to the configuration already in effect is a **no-op**: nothing is\n   * re-derived, {@link QueryManager.getConfigVersion} does not change, and subscribers are not\n   * notified. Equality is structural for data and by identity for functions\n   * ({@link optionsEqual}), so a caller that rebuilds its options object on every render — which\n   * every framework adapter does — does not force a reconfigure as long as the data is the same.\n   * Rebuilding a callback per render _does_ count as a change; memoize it to avoid that.\n   *\n   * Otherwise subscribers are notified once and `getConfigVersion` is incremented. Inside a\n   * {@link QueryManager.batch batch} the options are still applied immediately — configuration\n   * is not part of a batch's rollback — but the notification is deferred and merged into the\n   * batch's single notification.\n   */\n  reconfigure(\n    options: Partial<QueryManagerOptions<F, O, C>>,\n    config?: { replace?: boolean }\n  ): this {\n    const merged = config?.replace ? { ...options } : { ...this.state.options, ...options };\n\n    // Gate on the merged result rather than the argument, so `reconfigure({})` behaves like\n    // `reconfigure(currentOptions)`. `reconcileHistoryConfig` is skipped along with everything\n    // else, which is only correct because `history` is part of the comparison — `optionsEqual`\n    // descends into nested plain objects rather than comparing them by identity.\n    if (optionsEqual(this.state.options, merged)) return this;\n\n    this.applyOptions(freeze(merged));\n\n    // `ensureCache` is keyed on query identity, and the query has not changed, so it will not\n    // clear this on its own. Validation depends on `validator` and `fields`, both of which may\n    // have just changed. `idPathIndex` is derived from the query alone and stays valid.\n    this.state.validation = undefined;\n\n    this.reconcileHistoryConfig();\n\n    ++this.state.configVersion;\n\n    // Inside a batch the notification is deferred and merged into the batch's own, so a batch\n    // containing a `reconfigure` still emits exactly one. The configuration itself is applied\n    // immediately either way — it is not part of a batch's rollback.\n    if (this.state.batchDepth > 0) {\n      this.state.pendingConfigNotify = true;\n    } else {\n      this.notify(configChange);\n    }\n\n    return this;\n  }\n\n  /**\n   * Brings the history stacks in line with the current history configuration. Unlike\n   * {@link QueryManager.clearHistory}, this does _not_ set `historyBypassed`: it reflects a\n   * configuration change rather than a deliberate history repositioning, so a later mutation in\n   * the same batch must still be recorded normally.\n   *\n   * Called by {@link QueryManager.reconfigure} and again after a failed\n   * {@link QueryManager.batch batch} restores its snapshot, since that snapshot predates the\n   * configuration change (configuration is not part of a batch's rollback).\n   */\n  private reconcileHistoryConfig(): void {\n    if (this.state.historyEnabled) {\n      // Only ever shrinks; a raised `maxHistory` simply allows more entries from here on.\n      if (this.state.past.length > this.state.maxHistory) {\n        this.state.past.splice(0, this.state.past.length - this.state.maxHistory);\n      }\n    } else {\n      this.state.past = [];\n      this.state.future = [];\n      this.state.lastSig = undefined;\n    }\n  }\n\n  /**\n   * A counter incremented by every {@link QueryManager.reconfigure} call. Because reconfiguring\n   * leaves the query object untouched, subscribers that compare query identity alone cannot see\n   * it; this provides a snapshot that does change.\n   *\n   * Bound to the instance, so it can be passed directly to `useSyncExternalStore` alongside\n   * {@link QueryManager.subscribe}. The `useQueryManager` hook from `react-querybuilder`\n   * already does this.\n   */\n  getConfigVersion = (): number => this.state.configVersion;\n\n  // #endregion\n\n  // #region Cloning\n\n  /**\n   * Creates an independent manager with the same configuration and the current query.\n   *\n   * Subscribers and history are _not_ carried over: the clone starts with no listeners and an\n   * empty undo stack. Because every mutation produces a new query object, the two managers\n   * share the initial query safely and diverge from the first change.\n   *\n   * Pass `{ regenerateIDs: true }` to give every rule and group in the clone a new `id`, which\n   * is useful when both queries will be used together (e.g. inserted into the same tree).\n   */\n  clone(options?: { regenerateIDs?: boolean }): QueryManager<RG, F, O, C> {\n    const query = options?.regenerateIDs\n      ? regenerateIDs(this.state.query, { idGenerator: this.state.idGenerator })\n      : this.state.query;\n    return new QueryManager<RG, F, O, C>(query, this.state.options);\n  }\n\n  // #endregion\n\n  // #region Subscriptions\n\n  /**\n   * Registers a listener called after every change to the query, and returns a function that\n   * unregisters it. Mutations that resolve to a no-op do not notify, and a\n   * {@link QueryManager.batch batch} notifies once no matter how many changes it contains.\n   *\n   * Together with {@link QueryManager.getQuery}, this satisfies React's `useSyncExternalStore`\n   * contract. Both methods are bound to the instance, so they are stable references across\n   * renders and can be passed directly:\n   *\n   * ```ts\n   * const query = useSyncExternalStore(q.subscribe, q.getQuery);\n   * ```\n   *\n   * In React, prefer the `useQueryManager` hook from `react-querybuilder`, which wraps this.\n   *\n   * The listener receives a {@link SubscriptionChange} describing what changed. It is optional:\n   * a zero-argument listener — including `useSyncExternalStore`'s `onStoreChange` — is still a\n   * valid listener and behaves as it always has.\n   */\n  subscribe = (listener: (change: SubscriptionChange) => void): (() => void) => {\n    this.state.listeners.add(listener);\n    return () => {\n      this.state.listeners.delete(listener);\n    };\n  };\n\n  // #endregion\n\n  // #region Batching\n\n  /**\n   * Runs `fn`, deferring history recording and subscriber notification until it returns. The\n   * whole batch becomes a single undo step and triggers a single notification, or neither if\n   * the query ends up unchanged.\n   *\n   * Batches may be nested; only the outermost one commits. If `fn` throws, the query and its\n   * history are restored to their pre-batch state and the error propagates, so a batch either\n   * applies completely or not at all.\n   *\n   * {@link QueryManager.undo}, {@link QueryManager.redo}, and {@link QueryManager.clearHistory}\n   * may be called inside a batch; their notifications are deferred like everything else. Because\n   * they manage the history stacks themselves, a batch containing one of them records no entry of\n   * its own, leaving the stacks exactly as those methods left them.\n   */\n  batch(fn: () => void): this {\n    this.state.batchDepth++;\n    if (this.state.batchDepth === 1) {\n      this.state.batchSnapshot = {\n        query: this.state.query,\n        past: [...this.state.past],\n        future: [...this.state.future],\n        lastSig: this.state.lastSig,\n        lastAt: this.state.lastAt,\n      };\n    }\n\n    try {\n      fn();\n    } catch (error) {\n      // Only the outermost batch rolls back; `batchDepth` has not been decremented yet.\n      if (this.state.batchDepth === 1) {\n        const snapshot = this.state.batchSnapshot!;\n        // History is restored alongside the query because `undo`/`redo` may have run inside\n        // the batch, which mutates the stacks directly.\n        this.state.query = snapshot.query;\n        this.state.past = snapshot.past;\n        this.state.future = snapshot.future;\n        this.state.lastSig = snapshot.lastSig;\n        this.state.lastAt = snapshot.lastAt;\n        // The snapshot predates any `reconfigure` call made inside the batch, and configuration\n        // is not rolled back, so the restored stacks must be re-reconciled against it.\n        this.reconcileHistoryConfig();\n      }\n      throw error;\n    } finally {\n      this.state.batchDepth--;\n\n      if (this.state.batchDepth === 0) {\n        const { query: base } = this.state.batchSnapshot!;\n        this.state.batchSnapshot = undefined;\n\n        const queryChanged = base !== this.state.query;\n        // A `reconfigure` inside the batch deferred its notification to here. It fires even on\n        // the rollback path, because options are not rolled back — the configuration change\n        // survived, so subscribers must hear about it.\n        const configChanged = this.state.pendingConfigNotify;\n        this.state.pendingConfigNotify = false;\n\n        if (queryChanged) {\n          // `undo`/`redo`/`clearHistory` already positioned the stacks deliberately; recording\n          // here would duplicate the batch's own base entry and discard the redo stack.\n          if (!this.state.historyBypassed) this.record(base, this.state.query);\n        }\n        // One notification for the whole batch, describing everything that happened in it.\n        if (queryChanged || configChanged) {\n          this.notify(\n            queryChanged ? (configChanged ? queryAndConfigChange : queryChange) : configChange\n          );\n        }\n        this.state.historyBypassed = false;\n      }\n    }\n\n    return this;\n  }\n\n  // #endregion\n\n  // #region History\n\n  /** Whether there is a previous query to restore. Always `false` unless `history` is enabled. */\n  canUndo(): boolean {\n    return this.state.past.length > 0;\n  }\n\n  /** Whether there is an undone query to restore. Always `false` unless `history` is enabled. */\n  canRedo(): boolean {\n    return this.state.future.length > 0;\n  }\n\n  /** Restores the previous query. No-op when {@link QueryManager.canUndo} is `false`. */\n  undo(): this {\n    if (this.state.past.length === 0) return this;\n\n    this.state.future.unshift(this.state.query);\n    this.state.query = this.state.past.pop()!;\n    // Prevent the next change from coalescing into the restored entry.\n    this.state.lastSig = undefined;\n    this.markHistoryBypassed();\n    // Within a batch, the outermost call notifies once for everything.\n    if (this.state.batchDepth === 0) this.notify(queryChange);\n\n    return this;\n  }\n\n  /** Restores the most recently undone query. No-op when {@link QueryManager.canRedo} is `false`. */\n  redo(): this {\n    if (this.state.future.length === 0) return this;\n\n    this.state.past.push(this.state.query);\n    this.state.query = this.state.future.shift()!;\n    this.state.lastSig = undefined;\n    this.markHistoryBypassed();\n    if (this.state.batchDepth === 0) this.notify(queryChange);\n\n    return this;\n  }\n\n  /** Discards all undo/redo history without changing the current query. */\n  clearHistory(): this {\n    this.markHistoryBypassed();\n    this.state.past = [];\n    this.state.future = [];\n    this.state.lastSig = undefined;\n    return this;\n  }\n\n  /**\n   * The recorded history: `past` oldest first, `future` newest first. Both are copies, so\n   * mutating them does not affect the manager.\n   */\n  getHistory(): { past: RG[]; future: RG[] } {\n    return { past: [...this.state.past], future: [...this.state.future] };\n  }\n\n  // #endregion\n\n  // #region Validation\n\n  /**\n   * Validates the current query with the configured validator.\n   *\n   * The result is cached until the query changes, so a custom `validator` with side effects (or\n   * one that depends on anything other than the query) may run fewer times than expected.\n   */\n  validate(): boolean | ValidationMap {\n    this.ensureCache();\n    this.state.validation ??= this.state.validator(this.state.query);\n    return this.state.validation;\n  }\n\n  // #endregion\n\n  // #region Formatting\n\n  /** Generates a JSON string from the current query. */\n  format(): string;\n  /** Generates a result based on the provided rule group processor. */\n  format<TResult = unknown>(\n    options: FormatQueryOptions & { ruleGroupProcessor: RuleGroupProcessor<TResult> }\n  ): TResult;\n  /** Generates a {@link ParameterizedSQL} object from the current query. */\n  format(\n    options: 'parameterized' | (FormatQueryOptions & { format: 'parameterized' })\n  ): ParameterizedSQL;\n  /** Generates a {@link ParameterizedNamedSQL} object from the current query. */\n  format(\n    options: 'parameterized_named' | (FormatQueryOptions & { format: 'parameterized_named' })\n  ): ParameterizedNamedSQL;\n  /** Generates a JsonLogic object from the current query. */\n  format(options: 'jsonlogic' | (FormatQueryOptions & { format: 'jsonlogic' })): RQBJsonLogic;\n  /** Generates an ElasticSearch query object from the current query. */\n  format(\n    options: 'elasticsearch' | (FormatQueryOptions & { format: 'elasticsearch' })\n    // oxlint-disable-next-line typescript/no-explicit-any\n  ): Record<string, any>;\n  /** Generates a MongoDB query object from the current query. */\n  format(\n    options: 'mongodb_query' | (FormatQueryOptions & { format: 'mongodb_query' })\n    // oxlint-disable-next-line typescript/no-explicit-any\n  ): Record<string, any>;\n  /** Generates a Prisma ORM query object from the current query. */\n  format(\n    options: 'prisma' | (FormatQueryOptions & { format: 'prisma' })\n    // oxlint-disable-next-line typescript/no-explicit-any\n  ): Record<string, any>;\n  /** Generates a Drizzle ORM query object from the current query. */\n  format(\n    options: 'drizzle' | (FormatQueryOptions & { format: 'drizzle' })\n  ): ReturnType<typeof defaultRuleGroupProcessorDrizzle>;\n  /** Generates a TanStack DB query object from the current query. */\n  format(\n    options: 'tanstack_db' | (FormatQueryOptions & { format: 'tanstack_db' })\n  ): ReturnType<typeof defaultRuleGroupProcessorTanStackDB>;\n  /** Generates a Sequelize ORM query object from the current query. */\n  format(\n    options: 'sequelize' | (FormatQueryOptions & { format: 'sequelize' })\n  ): ReturnType<typeof defaultRuleGroupProcessorSequelize>;\n  /** Generates a diagnostics result from the current query. */\n  format(\n    options: 'diagnostics' | (FormatQueryOptions & { format: 'diagnostics' })\n  ): DiagnosticsResult;\n  /** Generates a query string in the requested format. */\n  format(options: Exclude<ExportFormat, ExportObjectFormats>): string;\n  /** Generates a query string in the requested format. */\n  format(\n    options: FormatQueryOptions & { format: Exclude<ExportFormat, ExportObjectFormats> }\n  ): string;\n  /** Generates a query string in the requested format. */\n  format(options: FormatQueryOptions): string;\n  format(options?: FormatQueryOptions | ExportFormat): unknown {\n    return formatQuery(this.state.query, options as FormatQueryOptions);\n  }\n\n  // #endregion\n\n  // #region Traversal\n\n  /**\n   * Yields every rule and group in the query, depth-first in pre-order, starting with the root\n   * group itself. Combinator strings in independent-combinator groups are skipped.\n   *\n   * ```ts\n   * for (const { node, path, parent } of qm.walk({ rulesOnly: true })) {\n   *   console.log(path, node.field);\n   * }\n   * ```\n   *\n   * Traversal operates on the query as it was when iteration began, so mutating the manager\n   * mid-iteration does not affect a walk already in progress. Because generators are lazy, that\n   * happens on the first iteration step rather than when `walk` is called.\n   *\n   * @yields Every rule and group in the query, subject to `options`.\n   */\n  *walk(options: WalkOptions = {}): Generator<QueryNode<RG>> {\n    const { from, rulesOnly, groupsOnly } = options;\n\n    let start: RG | RuleType = this.state.query;\n    let startPath: Path = [];\n    let startParent: RG | null = null;\n\n    if (from !== undefined) {\n      const path = this.toPath(from);\n      const node = path && findPath(path, this.state.query);\n      // An unresolvable path or `id` yields nothing rather than falling back to the root.\n      if (!path || !node) return;\n      start = node as RG | RuleType;\n      startPath = path;\n      startParent =\n        path.length === 0 ? null : (findPath(getParentPath(path), this.state.query) as RG);\n    }\n\n    for (const entry of this.walkFrom(start, startPath, startParent)) {\n      if (rulesOnly && isRuleGroup(entry.node)) continue;\n      if (groupsOnly && !isRuleGroup(entry.node)) continue;\n      yield entry;\n    }\n  }\n\n  /** Yields every rule in the query. Shorthand for `walk({ ...options, rulesOnly: true })`. */\n  rules(options: Omit<WalkOptions, 'rulesOnly' | 'groupsOnly'> = {}): Generator<QueryNode<RG>> {\n    return this.walk({ ...options, rulesOnly: true });\n  }\n\n  /**\n   * Yields every group in the query, including the root group. Shorthand for\n   * `walk({ ...options, groupsOnly: true })`.\n   */\n  groups(options: Omit<WalkOptions, 'rulesOnly' | 'groupsOnly'> = {}): Generator<QueryNode<RG>> {\n    return this.walk({ ...options, groupsOnly: true });\n  }\n\n  /** Returns the first node matching `predicate`, or `null` if there is none. */\n  find(\n    predicate: (entry: QueryNode<RG>) => boolean,\n    options: WalkOptions = {}\n  ): QueryNode<RG> | null {\n    for (const entry of this.walk(options)) {\n      if (predicate(entry)) return entry;\n    }\n    return null;\n  }\n\n  /** Returns every node matching `predicate`. */\n  filter(predicate: (entry: QueryNode<RG>) => boolean, options: WalkOptions = {}): QueryNode<RG>[] {\n    const results: QueryNode<RG>[] = [];\n    for (const entry of this.walk(options)) {\n      if (predicate(entry)) results.push(entry);\n    }\n    return results;\n  }\n\n  /** Equivalent to {@link QueryManager.walk} with no options, enabling `for...of` and spread. */\n  [Symbol.iterator](): Generator<QueryNode<RG>> {\n    return this.walk();\n  }\n\n  // #endregion\n\n  // #region Path utilities\n\n  /**\n   * Returns the rule or group at the given path, or `null` if the path can't be resolved.\n   *\n   * Unlike the standalone {@link findPath}, which can return `undefined` for an out-of-range\n   * index, unresolvable paths are always normalized to `null` here.\n   */\n  findPath(path: Path): FindPathReturnType {\n    return findPath(path, this.state.query) ?? null;\n  }\n\n  /**\n   * Returns the rule or group with the given `id`, or `null` if there is none. Backed by an\n   * index built once per query, so repeated lookups are constant time.\n   */\n  findID(id: string): FindPathReturnType {\n    const path = this.index().get(id);\n    // A path from the index always resolves, so no normalization is needed here.\n    return path === undefined ? null : findPath(path, this.state.query);\n  }\n\n  /**\n   * Returns the {@link Path} of the rule or group with the given `id`, or `null` if there is\n   * none. Backed by an index built once per query, so repeated lookups are constant time.\n   */\n  getPathOfID(id: string): Path | null {\n    return this.index().get(id) ?? null;\n  }\n\n  /**\n   * Determines whether the rule or group at the given path is disabled, either itself or by an\n   * ancestor group.\n   */\n  pathIsDisabled(path: Path): boolean {\n    return pathIsDisabled(path, this.state.query);\n  }\n\n  /** Returns the rule or group at the given path or `id`, or `null` if it can't be resolved. */\n  getNode(pathOrID: Path | string): FindPathReturnType {\n    const path = this.toPath(pathOrID);\n    return path === null ? null : (findPath(path, this.state.query) ?? null);\n  }\n\n  /**\n   * Returns the rule at the given path or `id`, or `null` if it can't be resolved _or_ resolves\n   * to a group.\n   */\n  getRule(pathOrID: Path | string): RuleType | null {\n    const node = this.getNode(pathOrID);\n    return node && !isRuleGroup(node) ? node : null;\n  }\n\n  /**\n   * Returns the group at the given path or `id`, or `null` if it can't be resolved _or_\n   * resolves to a rule.\n   */\n  getGroup(pathOrID: Path | string): RG | null {\n    const node = this.getNode(pathOrID);\n    return node && isRuleGroup(node) ? (node as RG) : null;\n  }\n\n  /**\n   * Returns the group containing the rule or group at the given path or `id`. Returns `null`\n   * for the root group, which has no parent, and when the target can't be resolved.\n   */\n  getParent(pathOrID: Path | string): RG | null {\n    const path = this.toPath(pathOrID);\n    if (path === null || path.length === 0) return null;\n    // Confirm the target itself exists, so a bogus path doesn't return a real parent.\n    if (!findPath(path, this.state.query)) return null;\n    // An existing non-root node always has a parent group.\n    return findPath(getParentPath(path), this.state.query) as RG;\n  }\n\n  // #endregion\n\n  // #region Rule configuration\n\n  /**\n   * The normalized field list, as the `QueryBuilder` component would render it. Needed to\n   * populate a field selector.\n   */\n  getFields(): FullOptionList<F> {\n    return this.state.fields;\n  }\n\n  /**\n   * The normalized combinator list, as the `QueryBuilder` component would render it. Needed to\n   * populate a combinator selector.\n   */\n  getCombinators(): FullOptionList<C> {\n    return this.state.combinators;\n  }\n\n  /**\n   * The field configuration for a field name. When the field isn't configured, returns the same\n   * minimal fallback (`{ name, value, label }`, all set to the field name) that\n   * {@link QueryManager.getRuleContext} reports as `fieldData`, so both access paths agree.\n   */\n  getFieldData(field: string): F {\n    return getFieldData(field, this.state.fieldMap) as F;\n  }\n\n  /** The operator list for a field, mirroring `QueryBuilder`'s precedence. */\n  getOperators(field: string): FullOptionList<O> {\n    return this.operatorsFor(field);\n  }\n\n  /** The value sources available for a field/operator pair. */\n  getValueSources(field: string, operator: string): ValueSourceFullOptions {\n    return this.valueSourcesFor(field, operator);\n  }\n\n  /** The match modes available for a field. */\n  getMatchModes(field: string): MatchModeOptions {\n    return this.matchModesFor(field);\n  }\n\n  /** The value option list for a field/operator pair. */\n  getValues(field: string, operator: string): FullOptionList<Option> {\n    return this.valuesFor(field, operator);\n  }\n\n  /** The value editor type for a field/operator pair. */\n  getValueEditorType(field: string, operator: string): ValueEditorType {\n    return this.valueEditorTypeFor(field, operator);\n  }\n\n  /**\n   * The default `operator` for a field, identical to the operator\n   * {@link QueryManager.createRule} would assign to a new rule on that field.\n   */\n  getRuleDefaultOperator(field: string): string {\n    return this.defaultOperator(field);\n  }\n\n  /**\n   * The default `value` for a rule, identical to the value {@link QueryManager.createRule} and\n   * {@link QueryManager.update} would assign after a field or operator change.\n   */\n  getRuleDefaultValue(rule: RuleType): unknown {\n    return this.defaultValue(rule);\n  }\n\n  /**\n   * The flattened field record backing {@link QueryManager.getFieldData}, keyed by field name\n   * with option groups flattened away.\n   *\n   * Treat the result as read-only. It may or may not be frozen depending on configuration, so\n   * do not rely on frozen-ness to prevent mutation.\n   */\n  getFieldMap(): Partial<FullOptionRecord<F>> {\n    return this.state.fieldMap;\n  }\n\n  /**\n   * Resolves everything about a rule that depends on the field/operator configuration—field data,\n   * operators, value editor type, value list, value sources, match modes, and validation result.\n   * Returns `null` when the target can't be resolved or isn't a rule.\n   *\n   * This is the same derivation the `useRule` hook performs, so a non-React implementation can\n   * render a rule without reimplementing the configuration precedence rules.\n   */\n  getRuleContext(pathOrID: Path | string): RuleContext<F> | null {\n    const rule = this.getRule(pathOrID);\n    if (!rule) return null;\n\n    const validation = this.validate();\n\n    return deriveRuleContext<F>(\n      rule,\n      {\n        fields: this.state.fields as OptionList<F>,\n        fieldMap: this.state.fieldMap,\n        getInputType: (f: string, o: string, misc: { fieldData: F }) =>\n          this.state.options.getInputType?.(f, o, misc) ?? null,\n        getMatchModes: (f: string) => this.matchModesFor(f),\n        getOperators: (f: string) => this.operatorsFor(f),\n        getParameters: (f: string, o: string, misc: { fieldData: F }) =>\n          this.parametersFor(f, o, misc),\n        getValueEditorType: (f: string, o: string) => this.valueEditorTypeFor(f, o),\n        getValues: (f: string, o: string) => this.valuesFor(f, o),\n        getValueSources: (f: string, o: string) => this.getValueSources(f, o),\n        getSubQueryBuilderProps: (f: string, misc: { fieldData: F }) =>\n          this.state.options.getSubQueryBuilderProps?.(f, misc) ?? {},\n      },\n      {\n        validationMap: typeof validation === 'boolean' ? {} : validation,\n        id: rule.id,\n      }\n    );\n  }\n\n  /**\n   * Resolves everything about a rule group that depends on the combinator configuration, plus its\n   * validation result. Returns `null` when the target can't be resolved or isn't a group.\n   *\n   * This is the same derivation the `useRuleGroup` hook performs.\n   */\n  getRuleGroupContext(pathOrID: Path | string = []): RuleGroupContext<C> | null {\n    const ruleGroup = this.getGroup(pathOrID);\n    if (!ruleGroup) return null;\n\n    const validation = this.validate();\n\n    return deriveRuleGroupContext<C>(ruleGroup, this.state.combinators, {\n      validationMap: typeof validation === 'boolean' ? {} : validation,\n      id: ruleGroup.id,\n    });\n  }\n\n  // #endregion\n\n  // #region Query inspection\n\n  /** Whether the current query uses independent combinators. */\n  isIC(): boolean {\n    return isRuleGroupTypeIC(this.state.query);\n  }\n\n  /**\n   * Returns the signature describing how the current query differs from `other`, as used by\n   * this manager's history coalescing.\n   */\n  signatureOf(other: RuleGroupTypeAny): string {\n    return signatureOf(this.state.query, other);\n  }\n\n  /** Generates a {@link DiagnosticsResult}. Shorthand for `format('diagnostics')`. */\n  diagnostics(): DiagnosticsResult {\n    return formatQuery(this.state.query, 'diagnostics');\n  }\n\n  /**\n   * Returns the current query, so `JSON.stringify(queryManager)` produces the same output as\n   * `JSON.stringify(queryManager.getQuery())`.\n   */\n  toJSON(): RG {\n    return this.state.query;\n  }\n\n  // #endregion\n\n  // #region Transforms\n\n  /**\n   * Returns a new manager with the same configuration and the current query converted to use\n   * independent combinators. Idempotent, and never modifies this manager. As with\n   * {@link QueryManager.clone}, subscribers and history are not carried over.\n   */\n  toIC(): QueryManager<AsRuleGroup<ToRuleGroupTypeIC<RG>>, F, O, C> {\n    return new QueryManager(\n      convertToIC(this.state.query) as AsRuleGroup<ToRuleGroupTypeIC<RG>>,\n      this.state.options\n    );\n  }\n\n  /**\n   * Returns a new manager with the same configuration and the current query converted to use a\n   * single combinator per group. Idempotent, and never modifies this manager. As with\n   * {@link QueryManager.clone}, subscribers and history are not carried over.\n   */\n  fromIC(): QueryManager<AsRuleGroup<ToRuleGroupType<RG>>, F, O, C> {\n    return new QueryManager(\n      convertFromIC(this.state.query) as AsRuleGroup<ToRuleGroupType<RG>>,\n      this.state.options\n    );\n  }\n\n  /**\n   * Runs {@link transformQuery} against the current query and returns its result.\n   *\n   * Unlike {@link QueryManager.toIC}/{@link QueryManager.fromIC}, this returns the raw\n   * transformed value rather than a new manager, since `transformQuery` can produce arbitrary\n   * shapes that are no longer valid queries. This manager is never modified.\n   */\n  // oxlint-disable-next-line typescript/no-explicit-any, typescript/no-unnecessary-type-parameters\n  transform<T = any>(options?: TransformQueryOptions<RG>): T {\n    // oxlint-disable-next-line typescript/no-explicit-any\n    return (transformQuery as any)(this.state.query, options);\n  }\n\n  // #endregion\n}\n"],"x_google_ignoreList":[4],"mappings":"yKAkBA,MAAa,EAAc,waA4B3B,EAqBa,EAAkB,CAC7B,cAAe,CACb,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,eAAgB,CACd,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,cAAe,CACb,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,iBAAkB,CAChB,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,gBAAiB,CACf,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,mBAAoB,CAClB,YACA,UACA,WACA,iBACA,QACA,UACA,OACA,YACA,QACA,SACA,SACA,QACA,aACA,OACF,EACA,WAAY,CACV,YACA,UACA,WACA,uBACA,QACA,QACA,OACA,cACA,SACA,SACA,QACA,YACF,EACA,cAAe,CACb,YACA,UACA,WACA,iBACA,QACA,WACA,UACA,OACA,OACA,SACA,SACA,QACA,aACA,OACF,EACA,iBAAkB,CAChB,YACA,YACA,UACA,WACA,iBACA,QACA,UACA,OACA,YACA,QACA,SACA,SACA,QACA,aACA,OACF,EACA,gBAAiB,CACf,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,eAAgB,CACd,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,gBAAiB,CACf,YACA,aACA,UACA,WACA,QACA,YACA,iBACA,QACA,QACA,yBACA,UACA,OACA,OACA,SACA,oBACA,SACA,uBACA,QACA,aACA,OACF,EACA,gBAAiB,CACf,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,eAAgB,CACd,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,UAAW,CACT,UACA,YACA,UACA,WACA,iBACA,QACA,QACA,OACA,YACA,SACA,SACA,QACA,YACF,EACA,iBAAkB,CAChB,YACA,UACA,WACA,QACA,YACA,iBACA,QACA,UACA,OACA,OACA,SACA,SACA,QACA,aACA,OACF,EACA,kBAAmB,CACjB,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,iBAAkB,CAChB,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,YACF,EACA,KAAM,0RA2BN,EACA,UAAW,+RA2BX,EACA,sBAAuB,sjBA8CvB,EACA,wBAAyB,sjBA8CzB,EACA,aAAc,CACZ,YACA,UACA,WACA,SACA,QACA,OACA,cACA,SACA,YACA,oBACA,UACA,kBACA,SACA,QACA,SACA,YACF,EACA,gBAAiB,CACf,YACA,aACA,UACA,WACA,SACA,QACA,OACA,cACA,SACA,SACA,QACA,SACA,YACF,EACA,YAAa,CACX,YACA,UACA,WACA,QACA,YACA,iBACA,YACA,QACA,gBACA,WACA,eACA,OACA,OACA,SACA,oBACA,YACA,WACA,SACA,QACA,OACA,aACA,QACA,cACA,QACF,EACA,cAAe,CACb,YACA,UACA,WACA,iBACA,QACA,gBACA,WACA,UACA,OACA,SACA,SACA,QACA,aACA,OACF,EACA,oBAAqB,CACnB,YACA,UACA,WACA,QACA,YACA,iBACA,QACA,UACA,OACA,OACA,SACA,SACA,QACA,aACA,OACF,CACF,EAiBa,EAAc,CACzB,cAAe,KACf,eAAgB,SAChB,cAAe,SACf,iBAAkB,SAClB,gBAAiB,SACjB,mBAAoB,WACpB,WAAY,KACZ,cAAe,WACf,iBAAkB,KAClB,gBAAiB,SACjB,eAAgB,SAChB,gBAAiB,KACjB,gBAAiB,S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"}