@react-querybuilder/core 8.23.0 → 8.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +507 -448
  2. package/dist/cjs/react-querybuilder_core.cjs.development.js +169 -6
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  4. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +507 -448
  5. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  6. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  7. package/dist/derivations.d.mts +288 -237
  8. package/dist/derivations.d.ts +288 -237
  9. package/dist/derivations.js +137 -4
  10. package/dist/derivations.js.map +1 -1
  11. package/dist/derivations.mjs +136 -5
  12. package/dist/derivations.mjs.map +1 -1
  13. package/dist/formatQuery.d.mts +1 -1
  14. package/dist/formatQuery.d.ts +1 -1
  15. package/dist/formatQuery.js +7 -4
  16. package/dist/formatQuery.js.map +1 -1
  17. package/dist/formatQuery.mjs +7 -4
  18. package/dist/formatQuery.mjs.map +1 -1
  19. package/dist/{index-OF2Q1gTp.d.mts → index-94yESPHr.d.mts} +4 -2
  20. package/dist/{index-XueTy_XQ.d.ts → index-D41_Ba4j.d.ts} +4 -2
  21. package/dist/parseCEL.d.mts +110 -110
  22. package/dist/parseCEL.d.ts +110 -110
  23. package/dist/parseCEL.js +4 -4
  24. package/dist/parseCEL.js.map +1 -1
  25. package/dist/parseCEL.mjs +4 -4
  26. package/dist/parseCEL.mjs.map +1 -1
  27. package/dist/parseCypher.d.mts +7 -7
  28. package/dist/parseCypher.d.ts +7 -7
  29. package/dist/parseGremlin.d.mts +4 -4
  30. package/dist/parseGremlin.d.ts +4 -4
  31. package/dist/parseJSONata.d.mts +37 -37
  32. package/dist/parseJSONata.d.ts +37 -37
  33. package/dist/parseJSONata.js +2 -2
  34. package/dist/parseJSONata.mjs +2 -2
  35. package/dist/parseJsonLogic.d.mts +8 -8
  36. package/dist/parseJsonLogic.d.ts +8 -8
  37. package/dist/parseJsonLogic.js +3 -3
  38. package/dist/parseJsonLogic.mjs +3 -3
  39. package/dist/parseMongoDB.d.mts +7 -7
  40. package/dist/parseMongoDB.d.ts +7 -7
  41. package/dist/parseMongoDB.js +3 -3
  42. package/dist/parseMongoDB.mjs +3 -3
  43. package/dist/parseSPARQL.d.mts +4 -4
  44. package/dist/parseSPARQL.d.ts +4 -4
  45. package/dist/parseSQL.d.mts +61 -61
  46. package/dist/parseSQL.d.ts +61 -61
  47. package/dist/parseSQL.js +4 -4
  48. package/dist/parseSQL.js.map +1 -1
  49. package/dist/parseSQL.mjs +4 -4
  50. package/dist/parseSQL.mjs.map +1 -1
  51. package/dist/parseSpEL.d.mts +55 -55
  52. package/dist/parseSpEL.d.ts +55 -55
  53. package/dist/parseSpEL.js +4 -4
  54. package/dist/parseSpEL.js.map +1 -1
  55. package/dist/parseSpEL.mjs +4 -4
  56. package/dist/parseSpEL.mjs.map +1 -1
  57. package/dist/{parserUtils-DbBXyAht.js → parserUtils-2VtG7m8L.js} +3 -3
  58. package/dist/{parserUtils-DbBXyAht.js.map → parserUtils-2VtG7m8L.js.map} +1 -1
  59. package/dist/{parserUtils-BKPstAaO.mjs → parserUtils-BlafvoFb.mjs} +3 -3
  60. package/dist/{parserUtils-BKPstAaO.mjs.map → parserUtils-BlafvoFb.mjs.map} +1 -1
  61. package/dist/{prepareQueryObjects-Dj9cTl9D.js → prepareQueryObjects-DJ_VjOLb.js} +2 -2
  62. package/dist/{prepareQueryObjects-Dj9cTl9D.js.map → prepareQueryObjects-DJ_VjOLb.js.map} +1 -1
  63. package/dist/{prepareQueryObjects-Dmyf3Wi_.mjs → prepareQueryObjects-DawsH4e3.mjs} +2 -2
  64. package/dist/{prepareQueryObjects-Dmyf3Wi_.mjs.map → prepareQueryObjects-DawsH4e3.mjs.map} +1 -1
  65. package/dist/react-querybuilder_core.d.mts +507 -448
  66. package/dist/react-querybuilder_core.legacy-esm.d.ts +507 -448
  67. package/dist/react-querybuilder_core.legacy-esm.js +172 -14
  68. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  69. package/dist/react-querybuilder_core.mjs +168 -7
  70. package/dist/react-querybuilder_core.mjs.map +1 -1
  71. package/dist/react-querybuilder_core.production.d.mts +507 -448
  72. package/dist/react-querybuilder_core.production.mjs +1 -1
  73. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  74. package/dist/{utils-e-7KHkjV.js → utils-B4E1-ZvU.js} +12 -2
  75. package/dist/utils-B4E1-ZvU.js.map +1 -0
  76. package/dist/{utils-CP5Jqy1P.mjs → utils-DLZCoyAh.mjs} +12 -2
  77. package/dist/utils-DLZCoyAh.mjs.map +1 -0
  78. package/package.json +20 -19
  79. package/dist/utils-CP5Jqy1P.mjs.map +0 -1
  80. package/dist/utils-e-7KHkjV.js.map +0 -1
@@ -1 +1 @@
1
- {"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,SACjB,eAAgB,SAChB,UAAW,KACX,iBAAkB,WAClB,kBAAmB,SACnB,iBAAkB,SAClB,KAAM,KACN,UAAW,KACX,sBAAuB,KACvB,wBAAyB,KACzB,aAAc,KACd,gBAAiB,KACjB,YAAa,KACb,cAAe,KACf,oBAAqB,UACvB,ECtnBa,EAAyB,IAIzB,EAA0B,SAM1B,EAAA,IAMA,EAA+D,EAM/D,EACX,EAMW,EAAA,IAMA,EACX,EAMW,EACX,EAMW,EAAA,IAMA,EAA+D,EAM/D,EACX,EAQW,EAA4C,CACvD,OAAQ,CACN,MAAO,QACP,gBAAA,IACA,iBAAkB,EAClB,sBAAuB,CACzB,EACA,UAAW,CACT,MAAO,WACP,gBAAA,IACA,iBAAkB,EAClB,sBAAuB,CACzB,EACA,OAAQ,CACN,MAAO,SACP,gBAAA,IACA,iBAAkB,EAClB,sBAAuB,CACzB,EACA,UAAW,CAAE,MAAO,YAAa,EACjC,eAAgB,CAAE,MAAO,kBAAmB,gBAAiB,GAAI,EACjE,MAAO,CAAE,MAAO,OAAQ,EACxB,WAAY,CAAE,MAAO,IAAK,MAAO,aAAc,EAC/C,YAAa,CAAE,MAAO,IAAK,MAAO,cAAe,EACjD,QAAS,CAAE,MAAO,SAAU,MAAO,UAAW,EAC9C,SAAU,CAAE,MAAO,UAAW,MAAO,WAAY,EACjD,YAAa,CAAE,MAAO,YAAa,EACnC,UAAW,CAAE,MAAO,MAAO,MAAO,mBAAoB,EACtD,UAAW,CAAE,MAAO,IAAK,MAAO,YAAa,EAC7C,eAAgB,CAAE,MAAO,IAAK,MAAO,aAAc,EACnD,cAAe,CAAE,MAAO,IAAK,MAAO,UAAW,EAC/C,gBAAiB,CAAE,MAAO,IAAK,MAAO,YAAa,EACnD,KAAM,CAAE,MAAO,IAAK,MAAO,MAAO,EAClC,KAAM,CAAE,MAAO,IAAK,MAAO,MAAO,EAClC,WAAY,CAAE,MAAO,KAAM,MAAO,aAAc,EAChD,SAAU,CAAE,MAAO,KAAM,MAAO,WAAY,EAC5C,UAAW,CAAE,MAAO,KAAM,MAAO,YAAa,EAC9C,iBAAkB,CAAE,MAAO,KAAM,MAAO,aAAc,EACtD,kBAAmB,CAAE,MAAO,KAAM,MAAO,cAAe,EACxD,SAAU,CAAE,MAAO,KAAM,MAAO,WAAY,EAC5C,UAAW,CAAE,MAAO,KAAM,MAAO,YAAa,EAC9C,WAAY,CAAE,MAAO,KAAM,MAAO,aAAc,EAChD,YAAa,CAAE,MAAO,KAAM,MAAO,cAAe,EAClD,oBAAqB,CAAE,MAAO,cAAe,CAC/C,EAQa,EAAkB,IAIlB,EAA+D,CAC1E,IAAK,IACL,KAAM,KACN,IAAK,IACL,IAAK,IACL,KAAM,KACN,KAAM,KACN,SAAU,WACV,WAAY,cACZ,SAAU,YACV,eAAgB,mBAChB,iBAAkB,sBAClB,eAAgB,oBAChB,KAAM,UACN,QAAS,cACT,GAAI,KACJ,MAAO,SACP,QAAS,UACT,WAAY,aACd,EAEa,EAA2E,CACtF,IAAK,MACL,GAAI,KACJ,IAAK,KACP,EAQa,EAAqC,CAChD,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,GAAI,EACpC,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,GAAI,EACpC,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,GAAI,EACpC,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,WAAY,MAAO,WAAY,MAAO,UAAW,EACzD,CAAE,KAAM,aAAc,MAAO,aAAc,MAAO,aAAc,EAChE,CAAE,KAAM,WAAY,MAAO,WAAY,MAAO,WAAY,EAC1D,CAAE,KAAM,iBAAkB,MAAO,iBAAkB,MAAO,kBAAmB,EAC7E,CAAE,KAAM,mBAAoB,MAAO,mBAAoB,MAAO,qBAAsB,EACpF,CAAE,KAAM,iBAAkB,MAAO,iBAAkB,MAAO,mBAAoB,EAC9E,CAAE,KAAM,OAAQ,MAAO,OAAQ,MAAO,SAAU,EAChD,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,aAAc,EAC1D,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,QAAS,MAAO,QAAS,MAAO,QAAS,EACjD,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,SAAU,EACtD,CAAE,KAAM,aAAc,MAAO,aAAc,MAAO,aAAc,CAClE,EAQa,EAA+E,CAC1F,IAAK,KACL,KAAM,IACN,IAAK,KACL,KAAM,IACN,IAAK,KACL,KAAM,IACN,WAAY,mBACZ,iBAAkB,aAClB,SAAU,iBACV,eAAgB,WAChB,SAAU,iBACV,eAAgB,WAChB,QAAS,aACT,WAAY,UACZ,GAAI,QACJ,MAAO,KACP,QAAS,OACT,KAAM,SACR,EAOa,EAAgD,IAAI,IAAI,CACnE,IACA,KACA,IACA,IACA,KACA,IACF,CAAC,EAOY,GAA+C,IAAI,IAAI,CAClE,WACA,aACA,WACA,iBACA,mBACA,gBACF,CAAC,EAOY,GAA0C,IAAI,IAAI,CAAC,OAAQ,SAAS,CAAC,EAOrE,GAAwC,IAAI,IAAI,CAAC,KAAM,OAAO,CAAC,EAO/D,GAA6C,IAAI,IAAI,CAAC,UAAW,YAAY,CAAC,EAU9E,EAAyC,CACpD,CAAE,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,EAC1C,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,CACzC,EAWa,GAAyD,CACpE,GAAG,EACH,CAAE,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,CAC5C,EAUa,GAAuC,CAClD,CAAE,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,EAC1C,CAAE,KAAM,OAAQ,MAAO,OAAQ,MAAO,MAAO,EAC7C,CAAE,KAAM,OAAQ,MAAO,OAAQ,MAAO,MAAO,EAC7C,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,UAAW,EACvD,CAAE,KAAM,SAAU,MAAO,SAAU,MAAO,SAAU,EACpD,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,SAAU,CACxD,EASa,GAAqB,CAChC,aAAc,eACd,UAAW,YACX,OAAQ,mBACR,KAAM,iBACN,YAAa,wBACb,QAAS,oBACT,SAAU,qBACV,UAAW,iBACX,WAAY,uBACZ,YAAa,mBACb,UAAW,sBACX,KAAM,OACN,OAAQ,cACR,UAAW,iBACX,eAAgB,sBAChB,UAAW,iBACX,MAAO,aACP,WAAY,cACZ,aAAc,eACd,MAAO,qBACP,QAAS,uBACT,aAAc,eACd,gBAAiB,kBACjB,WAAY,uBACZ,WAAY,uBACZ,YAAa,cACb,QAAS,UACT,QAAS,UACT,SAAU,WACV,kBAAmB,oBACnB,mBAAoB,qBACpB,UAAW,YACX,WAAY,0BACZ,SAAU,wBACV,MAAO,qBACP,SAAU,YACV,UAAW,iBACX,SAAU,YACV,UAAW,iBACX,YAAa,mBACb,cAAe,uBACf,SAAU,wBACV,UAAW,yBACX,WAAY,0BACZ,YAAa,mBACb,QAAS,uBACT,sBAAuB,6BACzB,EAQa,GAAuC,CAClD,aAAc,GACd,UAAW,GACX,OAAQ,GACR,KAAM,GACN,YAAa,GACb,QAAS,GACT,SAAU,GACV,UAAW,GACX,WAAY,GACZ,YAAa,GACb,UAAW,GACX,KAAM,GACN,OAAQ,GACR,UAAW,GACX,eAAgB,GAChB,UAAW,GACX,MAAO,GACP,WAAY,GACZ,aAAc,GACd,gBAAiB,GACjB,WAAY,GACZ,WAAY,GACZ,WAAY,GACZ,SAAU,GACV,UAAW,GACX,SAAU,GACV,UAAW,GACX,MAAO,GACP,YAAa,GACb,cAAe,GACf,cAAe,GACf,aAAc,GACd,MAAO,GACP,QAAS,GACT,YAAa,GACb,QAAS,GACT,SAAU,GACV,QAAS,GACT,kBAAmB,GACnB,mBAAoB,GACpB,UAAW,GACX,SAAU,GACV,cAAe,GACf,SAAU,GACV,YAAa,GACb,QAAS,GACT,sBAAuB,EACzB,EAOa,GAAsB,CACjC,MAAO,QACP,kBAAmB,qBACnB,8BAA+B,iCACjC,EAOa,GAAS,CACpB,KAAM,OACN,UAAW,aACX,iBAAkB,oBAClB,SAAU,YACV,YAAa,eACb,WAAY,cACZ,UAAW,aACX,QAAS,WACT,WAAY,cACZ,YAAa,cACb,OAAQ,SACR,UAAW,YACX,YAAa,eACb,UAAW,aACX,aAAc,gBACd,gBAAiB,oBACjB,WAAY,cACZ,WAAY,cACZ,WAAY,cACZ,SAAU,YACV,UAAW,aACX,SAAU,YACV,UAAW,aACX,oBAAqB,wBACrB,gBAAiB,mBACnB,EAEa,EAAU,CACrB,mBAAoB,uCACpB,aAAc,mCACd,YAAa,gBACb,eAAgB,oCAChB,gBAAiB,qCACjB,iBAAkB,sCAClB,kBAAmB,uCACnB,gBAAiB,qCACjB,iBAAkB,sCAClB,cAAe,mCACf,IAAK,sBACL,OAAQ,wBACR,OAAQ,wBACR,KAAM,sBACN,MAAO,oCACT,EAOa,GAAiB,CAAC,EAQlB,GAAwD,CACnE,mBAAoB,GACpB,gBAAiB,GACjB,mBAAoB,GACpB,gBAAiB,GACjB,UAAW,GACX,kBAAmB,GACnB,uBAAwB,GACxB,cAAe,GACf,4BAA6B,GAC7B,mBAAoB,GACpB,sBAAuB,GACvB,iBAAkB,GAClB,4BAA6B,GAC7B,gBAAiB,GACjB,gBAAiB,GACjB,cAAe,GACf,iBAAkB,GAClB,aAAc,GACd,2BAA4B,EAC9B,EAOa,GAAoB,GAQpB,GAAoB,ICjhBpB,GAA6C,CACxD,mBACA,mBACA,qBACA,wBACA,mBACA,wBACA,kBACA,kBACA,qBACF,EAGa,GAAiD,IAAI,IAChE,EACF,ECba,IAAW,EAAc,EAAA,MACpC,OAAO,GAAQ,SACX,EACG,MAAM,KAAK,GAAW,CAAC,CACvB,IAAI,GAAK,EAAE,MAAM,CAAS,CAAC,CAAC,CAC5B,QAAQ,EAAM,EAAM,IACf,IAAQ,EACH,EAEF,CAAC,GAAG,EAAK,MAAM,EAAG,EAAE,EAAG,GAAG,EAAK,GAAG,EAAE,IAAI,IAAY,EAAK,KAAM,GAAG,EAAK,MAAM,CAAC,CAAC,EACrF,CAAC,CAAC,EACP,CAAC,EAeM,IAAY,EAAmB,EAAA,MAC1C,EAAO,IAAI,GAAO,GAAG,GAAO,KAAK,WAAW,EAAS,GAAI,KAAK,EAAS,IAAI,CAAC,CAAC,CAAC,KAAK,CAAQ,EAQhF,EAAmB,GAC7B,OAAO,GAAQ,SAAW,EAAI,KAAK,EAAI,EAiB7B,GACX,EACA,CAAE,sBAAyD,CAAC,IAE3D,MAAM,QAAQ,CAAC,EACZ,EAAE,IAAI,CAAY,EAClB,OAAO,GAAM,SACX,GAAQ,EAAA,GAAkB,CAAC,CACxB,OAAO,MAA2B,GAAO,GAAK,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAC/D,IAAI,GAAK,EAAE,KAAK,CAAC,EACpB,OAAO,GAAM,SACX,CAAC,CAAC,EACF,CAAC,EAKE,GAAoB,GAC/B,EAAI,MAAM,GAAM,IAAO,KAAU,GAAM,MAAW,EAAK,ECrFzD,SAAS,GAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,GAAa,OAAO,GAAjB,UAA8B,OAAO,GAAjB,SAAmB,GAAG,OAAO,GAAa,OAAO,GAAjB,SAAmB,IAAG,MAAM,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAE,EAAE,EAAE,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE,MAAM,IAAI,KAAK,EAAE,EAAE,KAAK,IAAI,GAAG,KAAK,GAAG,EAAA,CAAG,OAAO,CAAC,CAAC,SAAgB,IAAM,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,OAAO,EAAE,EAAE,KAAK,EAAE,UAAU,MAAM,EAAE,GAAE,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG,OAAO,CAAC,CCM/W,MAAa,EAAS,GAAa,OAAO,GAAM,SAAY,EAAE,YAAY,EAAU,EAMvE,GAAuB,IAAI,OACtCA,EAAqB,OAAO,QAAQ,MAAO,OAAO,GAAG,MAAM,CAAC,CAAC,QAAQ,MAAO,OAAO,GAAG,MAAM,CAC9F,EAMa,EAAU,GACL,OAAO,GAAQ,YAA/B,GAA2C,OAAO,eAAe,CAAG,IAAM,OAAO,UAKtE,GAA0B,GACrC,GAAU,MAA+B,IAAU,GCrBxC,GAAc,GACzB,EAAO,CAAC,GAAK,UAAW,GAAK,OAAO,EAAE,OAAU,SAKrC,EAAe,GAC1B,EAAO,CAAE,GAAK,MAAM,QAAQ,EAAG,KAAK,EAKzB,EAAmB,GAC9B,EAAY,CAAE,GAAK,OAAO,EAAG,YAAe,SAKjC,EAAqB,GAChC,EAAY,CAAE,GAAK,EAAG,aAAe,IAAA,GCjB1B,GAAsB,cAMtB,GAAqB,GAM5B,IAAgB,EAAc,IAA2B,CAC7D,IAAM,EAAO,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAI,EAAG,GAAG,OAAO,KAAK,CAAI,CAAC,CAAC,EACjE,EAAK,OAAO,OAAO,EACnB,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAM,KAAO,EACX,OAAO,GAAG,EAAK,GAAsB,EAAK,EAAoB,GACjE,EAAQ,KAAK,CAAG,EAGpB,OAAO,EAAQ,SAAS,CAC1B,EAEM,IACJ,EACA,EAEA,EAEA,IACW,CAGX,GAAI,IAAS,EAAM,MAAA,GAGnB,GAAI,OAAO,GAAS,UAAY,OAAO,GAAS,SAC9C,OAAO,OAAO,GAAS,OAAO,EAAO,GAAG,EAAS,cAAc,EAAM,GAAK,GAG5E,IAAM,EAAc,EAAY,CAAI,EAC9B,EAAc,EAAY,CAAI,EAEpC,GAAI,IAAgB,EAAa,OAAO,GAExC,GAAI,CAAC,GAAe,CAAC,EAAa,CAChC,IAAM,EAAQ,GAAa,EAAM,CAAI,EACrC,OAAO,EAAM,SAAW,EAAA,GAAyB,GAAG,EAAK,IAAM,GAAG,GAAG,EAAM,KAAK,GAAG,GACrF,CAGA,GAAI,EAAK,MAAM,SAAW,EAAK,MAAM,OAAQ,OAAO,GAEpD,IAAM,EAAW,GAAa,EAAM,CAAI,EAEpC,EAAe,GACnB,IAAK,GAAM,CAAC,EAAG,KAAa,EAAK,MAAM,QAAQ,EAC7C,GAAI,IAAa,EAAK,MAAM,GAAI,CAE9B,GAAI,IAAiB,GAAI,OAAO,GAChC,EAAe,CACjB,CAWF,OARI,IAAiB,GACZ,EAAS,SAAW,EAAA,GAAyB,GAAG,EAAK,IAAM,GAAG,GAAG,EAAS,KAAK,GAAG,IAKvF,EAAS,OAAS,EAAU,GAEzB,GACL,EAAK,MAAM,GACX,EAAK,MAAM,GACX,EAAK,IAAM,GACX,CACF,CACF,EAqBa,IAAe,EAAwB,IAClD,GAAgB,EAAM,EAAM,GAAI,EAAE,ECtFvB,IACX,EACA,EACA,EACA,EACA,EAAA,MAEA,IAAA,eACA,IAAY,GACZ,GAAO,GACP,EAAM,EAAS,ECpBX,GAAmB,CAAC,KAAM,MAAO,KAAK,EAEtC,IAAgB,EAAY,IAAc,EAAG,CAAC,IAAM,EAEpD,IACJ,EACA,EAA8B,IACV,CACpB,IAAM,EAAiB,GAAiB,GAGxC,GAAI,CAAC,EAAG,MAAM,SAAS,CAAqB,EAG1C,OAAO,EAAsB,GAAiB,OAAS,EACnD,GAA6C,EAAI,EAAsB,CAAC,EACxE,EAGN,IAAM,EAAW,CAAC,GAAG,EAAG,KAAK,EACzB,EAAS,EAGb,KAAO,EAAS,EAAS,OAAS,GAAG,CACnC,GAAI,GAAa,EAAS,EAAS,GAAI,CAAc,EAAG,CACtD,GAAU,EACV,QACF,CAEA,IAAI,EAA0B,GAC9B,IAAK,IAAI,EAAI,EAAS,EAAG,EAAI,EAAS,OAAQ,IAC5C,GAAI,OAAO,EAAS,IAAO,UAAY,EAAG,EAAS,EAAE,IAAM,EAAgB,CACzE,EAA0B,EAC1B,KACF,CAGF,GAAI,IAA4B,GAAI,CAElC,EAAS,OACP,EACA,EAAS,OACT,GAEE,CAAE,MAAO,EAAS,MAAM,CAAM,CAAS,EACvC,EAAsB,CACxB,CACF,EACA,KACF,CAEE,EAAS,OACP,EACA,EAA0B,EAC1B,GAEE,CAAE,MAAO,EAAS,MAAM,EAAQ,CAAuB,CAAS,EAChE,EAAsB,CACxB,CACF,CAEJ,CAEA,MAAO,CAAE,GAAG,EAAI,MAAO,CAAS,CAClC,EAUa,EAA8C,GAAgC,CACzF,GAAI,EAAgB,CAAE,EACpB,OAAO,EAET,IAAM,EAAc,GAA6C,CAAE,EAC7D,EAAwB,CAAC,EAC3B,EAAa,MACjB,IAAK,GAAM,CAAC,EAAK,KAAM,EAAY,MAAM,QAAQ,EAC3C,OAAO,GAAM,SACX,IAAQ,IAAG,EAAa,GAE5B,EAAM,KAAK,EAAY,CAAC,EAAI,EAAc,CAAC,EAAI,CAAC,EAGpD,MAAO,CAAE,GAAG,EAAa,aAAY,OAAM,CAC7C,EAUa,GAA4C,GAAkC,CACzF,GAAI,EAAkB,CAAE,EACtB,OAAO,EAET,GAAM,CAAE,aAAY,GAAG,GAA2B,EAC5C,EAAiD,CAAC,EAClD,CAAE,UAAW,EAAG,MACtB,IAAK,IAAI,EAAM,EAAG,EAAM,EAAQ,IAAO,CACrC,IAAM,EAAI,EAAG,MAAM,GACf,EAAY,CAAC,EACf,EAAM,KAAK,GAAY,CAAC,CAAC,EAEzB,EAAM,KAAK,CAAC,EAEV,GAAc,EAAM,EAAS,GAC/B,EAAM,KAAK,CAAU,CAEzB,CACA,MAAO,CAAE,GAAG,EAAwB,OAAM,CAC5C,EAgBA,SAAS,GAAa,EAAyE,CAC7F,OAAO,EAAkB,CAAK,EAAI,EAAc,CAAK,EAAI,GAAY,CAAK,CAC5E,CChEA,MAAM,GAA+E,CACnF,aAAc,CAAC,cAAc,EAC7B,WAAY,CAAC,YAAY,EACzB,OAAQ,CAAC,gBAAiB,QAAQ,EAClC,UAAW,CAAC,gBAAiB,WAAW,EACxC,eAAgB,CAAC,gBAAiB,gBAAgB,EAClD,UAAW,CAAC,gBAAiB,WAAW,EACxC,YAAa,CAAC,gBAAiB,aAAa,EAC5C,MAAO,CAAC,OAAO,EACf,UAAW,CAAC,gBAAiB,WAAW,EACxC,SAAU,CAAC,gBAAiB,UAAU,EACtC,SAAU,CAAC,gBAAiB,UAAU,EACtC,WAAY,CAAC,gBAAiB,YAAY,EAC1C,cAAe,CAAC,eAAe,CACjC,EAEM,GAAwF,CAC5F,OAAQ,CACN,QAAS,CAAC,QAAQ,EAClB,WAAY,CAEV,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,OAAQ,aAAc,EAAK,EAC1D,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,QAAU,EAAE,aAAe,MAAO,EACjE,CAAE,IAAK,oBAAqB,KAAM,GAAK,EAAE,cAAe,CAC1D,CACF,EACA,aAAc,CAAC,cAAc,EAC7B,gBAAiB,CAAC,iBAAiB,EACnC,WAAY,CAAC,gBAAiB,YAAY,EAC1C,WAAY,CAAC,gBAAiB,YAAY,EAC1C,WAAY,CAAC,YAAY,EACzB,YAAa,CAAC,gBAAiB,aAAa,EAC5C,UAAW,CAAC,WAAW,EACvB,QAAS,CAAC,gBAAiB,SAAS,EACpC,SAAU,CAAC,gBAAiB,UAAU,EACtC,WAAY,CAAC,gBAAiB,YAAY,EAC1C,UAAW,CAAC,gBAAiB,WAAW,EACxC,UAAW,CAAC,gBAAiB,WAAW,EACxC,YAAa,CAAC,gBAAiB,aAAa,EAC5C,KAAM,CAAC,MAAM,CACf,EASM,GAAyE,CAC7E,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAS,EACzC,CAAE,IAAK,QAAS,KAAM,GAAK,EAAE,KAAM,EACnC,CAAE,IAAK,cAAe,KAAM,GAAK,EAAE,UAAW,EAC9C,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,MAAO,EACtC,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,QAAU,EAAE,aAAe,MAAO,EACjE,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAU,EAAE,UAAW,EACvD,CAAE,IAAK,oBAAqB,KAAM,GAAK,EAAE,cAAe,EACxD,CAAE,IAAK,cAAe,KAAM,GAAK,EAAE,WAAY,CACjD,EAGM,GAA8E,CAClF,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAS,EACzC,CAAE,IAAK,QAAS,KAAM,GAAK,EAAE,KAAM,EACnC,CAAE,IAAK,cAAe,KAAM,GAAK,EAAE,UAAW,EAC9C,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAU,EAAE,UAAW,CACzD,EAcM,GAAyF,CAC7F,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAS,EACzC,CAAE,IAAK,QAAS,KAAM,GAAK,OAAO,EAAE,kBAAqB,WAAa,EAAE,gBAAiB,EACzF,CAAE,IAAK,UAAW,KAAM,GAAK,OAAO,EAAE,kBAAqB,WAAa,CAAC,EAAE,gBAAiB,CAC9F,EAcM,IACJ,EACA,EACA,CAAE,aAAY,gCACG,CACjB,IAAM,EAAY,EAAW,IAAI,GAAa,CAAC,EAAW,CAAC,CAAC,EAAU,KAAK,CAAK,CAAC,CAAU,EAE3F,MAAO,CACL,GAAG,EACA,QAAQ,CAAC,KAAe,CAAC,EAAU,YAAY,CAAC,CAChD,KAAK,CAAC,EAAW,KAAY,GAAU,IAAa,EAAU,IAAI,EACrE,GACE,OAAO,YACL,EAAU,KAAK,CAAC,EAAW,KAAY,CAAC,GAAmB,EAAU,KAAM,CAAM,CAAC,CACpF,CACJ,CACF,EAGM,IACJ,EACA,EACA,EACA,IACW,CACX,GAAM,CAAE,UAAS,cAAiC,MAAM,QAAQ,CAAI,EAChE,CAAE,QAAS,CAAK,EACf,EAGL,OAAO,GACL,EAAQ,4BACN,GAAmB,GACrB,GAAG,EAAQ,IAAI,GAAU,EAAQ,aAAa,EAAO,EACrD,GAAI,EAAa,GAAc,EAAY,EAAO,CAAO,EAAI,CAAC,CAChE,CACF,EAEM,IACJ,EACA,EACA,IACsB,CACtB,IAAM,EAAS,CAAC,EAEhB,IAAK,GAAM,CAAC,EAAK,KAAS,OAAO,QAAQ,CAAK,EAI5C,EAAO,GAAO,GAAe,EAAK,EAAM,EAAO,CAAO,EAGxD,OAAO,CACT,EAQa,GACX,GACqC,GAAgB,GAAsB,CAAC,EAAG,CAAO,EAS3E,IACX,EACA,IACW,GAAe,EAAK,GAAqB,GAAM,CAAC,EAAG,CAAO,EAS1D,GACX,GAEA,GAAgB,GAA2B,EAAS,CAAO,EAiBvD,IACJ,EACA,EACA,IACW,CACX,GAAM,CACJ,aACA,6BACA,oBAAoB,CAAC,EACrB,uBACE,EAEJ,OAAO,GACL,GAAG,EACH,GAA8B,GAAmB,GACjD,IAAa,GACb,GAAG,GAAc,EAAY,EAAS,CAAO,EAC7C,CACF,CACF,EAOa,GAA4B,GACvC,GAAqB,OAAQ,GAAqB,CAAO,EAW9C,GAAiC,GAC5C,GAAqB,YAAa,GAA0B,CAAO,EAQxD,GACX,GACW,GAAqB,eAAgB,GAA6B,CAAO,ECvUzE,GAAmC,GAAS,CACvD,IAAM,EAAwB,CAAC,EAKzB,EAAgB,GAAmB,CAMnC,EAAK,IAAI,EAAO,EAAK,GAE3B,EAEM,EAAiB,GAAyB,CAE9C,IAAM,EAAiB,CAAC,EACxB,GAAI,EAAG,MAAM,SAAW,EACtB,EAAQ,KAAK,GAAoB,KAAK,OACjC,GAAI,CAAC,EAAgB,CAAE,EAAG,CAE/B,IAAI,EAAa,GACjB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,MAAM,QAAU,CAAC,EAAY,KAE/C,EAAI,GAAM,GAAK,OAAO,EAAG,MAAM,IAAO,UACtC,EAAI,GAAM,GAAK,OAAO,EAAG,MAAM,IAAO,UACtC,EAAI,GAAM,GACT,OAAO,EAAG,MAAM,IAAO,UACvB,CAAC,EAAmB,IAAI,GAAK,EAAE,IAAc,CAAC,CAAC,SAAS,EAAG,MAAM,EAAY,KAE/E,EAAa,IAGb,GACF,EAAQ,KAAK,GAAoB,6BAA6B,CAElE,CAIE,EAAgB,CAAE,GAClB,CAAC,EAAmB,IAAI,GAAK,EAAE,IAAc,CAAC,CAAC,SAAS,EAAG,UAAU,GACrE,EAAG,MAAM,OAAS,GAElB,EAAQ,KAAK,GAAoB,iBAAiB,EAGhD,EAAG,KACL,EAAO,EAAG,IAAM,EAAQ,OAAS,EAAI,CAAE,MAAO,GAAO,SAAQ,EAAI,IAEnE,IAAK,IAAM,KAAK,EAAG,MACb,OAAO,GAAM,WAEN,EAAY,CAAC,EACtB,EAAc,CAAC,EAEf,EAAa,CAAC,EAGpB,EAIA,OAFA,EAAc,CAAK,EAEZ,CAMT,EC/Da,GAAa,OAAO,KASpB,GAAgB,OAAO,QAQvB,GAAe,GAC1B,IAAQ,aAAe,IAAQ,eAAiB,IAAQ,YCXpD,GAAoB,GACxB,EAAO,CAAG,GAAK,SAAU,GAAO,OAAO,EAAI,MAAS,SAChD,GAAqB,GACzB,EAAO,CAAG,GAAK,UAAW,GAAO,OAAO,EAAI,OAAU,SAQxD,SAAgB,EACd,EACA,EACA,EACmB,CACnB,GAAI,OAAO,GAAQ,SACjB,MAAO,CACL,GAAG,EACH,KAAM,EACN,MAAO,EACP,MAAO,IAAW,IAAQ,CAC5B,EAGF,IAAM,EAA2C,CAAC,EAC9C,EAAgB,CAAC,CAAC,EActB,OAZI,GAAiB,CAAG,GAAK,CAAC,GAAkB,CAAG,GACjD,EAAM,MAAQ,EAAI,KAClB,EAAgB,IACP,CAAC,GAAiB,CAAG,GAAK,GAAkB,CAAG,IACxD,EAAM,KAAO,EAAI,MACjB,EAAgB,IAGd,EACK,OAAO,OAAO,CAAC,EAAG,EAAgB,EAAK,CAAK,EAG9C,CACT,CAQA,SAAgB,EACd,EACA,EACA,EACqB,CACrB,GAAI,CAAC,MAAM,QAAQ,CAAO,EACxB,MAAO,CAAC,EAGV,IAAM,EAAO,EASb,OAPI,GAA2B,CAAI,EAC1B,EAAK,IAAI,IAAa,CAC3B,GAAG,EACH,QAAS,EAAS,QAAQ,IAAI,GAAO,EAAa,EAAK,EAAgB,CAAQ,CAAC,CAClF,EAAE,EAGI,EAAe,IAAI,GACzB,EAAa,EAAK,EAAgB,CAAQ,CAC5C,CACF,CAQA,SAAgB,GACd,EACA,EAC8F,CAM9F,OAAO,OAAO,YACX,OAAO,QAAQ,CAAM,CAAC,CAAgC,KAAK,CAAC,EAAG,KAAO,CACrE,EACA,EAAa,EAAG,CAAc,CAChC,CAAC,CACH,CACF,CAOA,MAAa,GAGX,GACQ,GAAiB,CAAa,EAQ3B,GAGX,GACQ,CACR,IAAM,EAAQ,IAAI,IACZ,EAAgB,CAAC,EACvB,IAAK,IAAM,KAAM,EACV,EAAM,IAAK,EAAG,OAAS,EAAG,IAAM,IACnC,EAAM,IAAK,EAAG,OAAS,EAAG,IAAM,EAChC,EAAS,KAAK,CAAE,GAGpB,OAAO,EAAc,SAAW,EAAS,OAAS,EAAgB,CACpE,EAOa,GAAsB,GACjC,MAAM,QAAQ,CAAG,GACjB,EAAI,OAAS,GACb,EAAO,EAAI,EAAE,GACb,YAAa,EAAI,IACjB,MAAM,QAAQ,EAAI,EAAE,CAAC,OAAO,EAOjB,GAAyB,GAA0C,CAC9E,IAAI,EAAQ,GACZ,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAK,EACd,GAAI,GAAiB,CAAC,GAAK,GAAkB,CAAC,EAC5C,EAAQ,QAER,MAAO,GAIb,OAAO,CACT,EAOa,GAAqB,GAAsC,CACtE,IAAI,EAAQ,GACZ,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAK,EACd,GAAI,GAAiB,CAAC,GAAK,GAAkB,CAAC,EAC5C,EAAQ,QAER,MAAO,GAIb,OAAO,CACT,EAOa,IACX,EACA,CAAE,aAAa,IAAoC,CAAC,IACnB,CACjC,IAAI,EAAS,GACb,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAM,EACf,GACE,EAAO,CAAE,GACT,YAAa,IACZ,GAAsB,EAAG,OAAO,GAC9B,GAAc,MAAM,QAAQ,EAAG,OAAO,GAAK,EAAG,QAAQ,SAAW,GAEpE,EAAS,QAET,MAAO,GAIb,OAAO,CACT,EAOa,IACX,EACA,CAAE,aAAa,IAAoC,CAAC,IACf,CACrC,IAAI,EAAS,GACb,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAM,EACf,GACE,EAAO,CAAE,GACT,YAAa,IACZ,GAAkB,EAAG,OAAO,GAC1B,GAAc,MAAM,QAAQ,EAAG,OAAO,GAAK,EAAG,QAAQ,SAAW,GAEpE,EAAS,QAET,MAAO,GAIb,OAAO,CACT,EAoBA,SAAgB,EACd,EACA,EACqB,CAIrB,OAHgB,GAA2B,EAAK,CAAE,WAAY,EAAK,CAAC,EAChE,EAAI,QAAQ,GAAM,EAAG,OAAO,EAC5B,EAAA,CACW,KAAK,GAAM,EAAG,QAAU,GAAQ,EAAG,OAAS,CAAI,CACjE,CAgBA,SAAgB,EACd,EACqC,CACrC,GAAI,CAAC,MAAM,QAAQ,CAAG,GAAK,EAAI,SAAW,EACxC,OAAO,KACF,GAAI,GAA2B,EAAK,CAAE,WAAY,EAAK,CAAC,EAAG,CAChE,IAAK,IAAM,KAAM,EACf,GAAI,EAAG,QAAQ,OAAS,EACtB,OAAQ,EAAG,QAAQ,EAAE,CAAC,OAAS,EAAG,QAAQ,EAAE,CAAC,KAIjD,OAAO,IACT,CAEA,OAAQ,EAAI,EAAE,CAAC,OAAS,EAAI,EAAE,CAAC,IACjC,CAQA,MAAa,GAA2C,GACtD,GAAiB,GAAmB,CAAG,EAAI,EAAI,QAAQ,GAAM,EAAG,OAAO,EAAI,CAAG,EAQnE,GACX,GACmC,CAEnC,IAAM,EAAS,IAAI,IACb,EAAQ,IAAI,IACZ,EAA2C,CAAC,EAClD,IAAK,IAAM,KAAM,EACf,GAAI,CAAC,EAAO,IAAI,EAAG,KAAK,EAAG,CACzB,EAAO,IAAI,EAAG,KAAK,EACnB,IAAM,EAA2D,CAAC,EAClE,IAAK,IAAM,KAAO,EAAG,QACd,EAAM,IAAK,EAAI,OAAS,EAAI,IAAU,IACzC,EAAM,IAAK,EAAI,OAAS,EAAI,IAAU,EACtC,EAAoB,KAAK,EAAa,CAAG,CAAsC,GAGnF,EAAS,KAAK,CAAE,GAAG,EAAI,QAAS,CAAoB,CAAC,CACvD,CAEF,OAAO,CACT,EAQa,GACX,GAEI,GAA2B,CAAa,EACnC,GAAc,CAAa,EAE7B,GAAkB,EAA+B,IAAI,GAAK,EAAa,CAAC,CAAC,CAAC,EAiCtE,GACX,GAC0B,CAI1B,GAAM,CACJ,WAAY,EACZ,aAAa,CAAC,EACd,WAAW,CAAC,EACZ,YAAa,CACX,kBAAA,IACA,mBAAmB,EACnB,wBAAwB,GACtB,CAAC,EACL,mBAAmB,IACjB,EAEE,EAAgB,CACpB,GAAI,EACJ,KAAM,EACN,MAAO,EACP,MAAO,CACT,EAEM,EAAc,GAA2B,CAAC,CAAa,EAEzD,EACE,EACJ,MAAM,QAAQ,CAAW,EACrB,EAAiB,EAAa,EAAY,CAAQ,EACjD,GAAW,GAAgB,EAAa,CAAU,CAAC,CAAC,CAElD,IAAkC,IAAQ,CACzC,GAAG,EAAY,GACf,KAAM,EACN,MAAO,CACT,EAAE,CAAC,CAEF,MAAM,EAAG,IAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC,EAEtD,AAWE,EAXE,GAA2B,CAAI,EAE5B,GADQ,EACM,EACA,CACb,CACE,MAAO,EACP,QAAS,CAAC,CAAa,CACzB,EACA,GAAG,CACL,CAAC,EAGA,GADQ,EACS,EACA,CAAC,EAAe,GAAI,CAAY,CAAC,EAGzD,IAAI,EAA2C,CAAC,EAChD,GAAI,CAAC,MAAM,QAAQ,CAAW,EAAG,CAC/B,IAAM,EAAK,GAAgB,EAAa,CAAU,EAClD,EAAa,EAAmB,EAAK,CAAE,GAAG,GAAK,GAAkB,CAAc,CACjF,MACE,GAAI,GAA2B,CAAU,EACvC,IAAK,IAAM,KAAM,EACf,IAAK,IAAM,KAAO,EAAG,QACnB,EACG,EAAI,OACgC,EAAI,MACvC,EAAa,EAAK,CAAU,OAIpC,IAAK,IAAM,KAAO,EAChB,EACG,EAAI,OACgC,EAAI,MACvC,EAAa,EAAK,CAAU,EAKtC,MAAO,CAAE,gBAAe,aAAY,YAAW,CACjD,EC9dM,IAAsB,EAAkB,EAAkB,IAA8B,CAC5F,IAAM,EAAY,EAAa,CAAK,EAC9B,EAAqB,EAAa,CAAc,EAOtD,OANI,EAAU,QAAU,EAAmB,MAClC,GAEL,OAAO,EAAU,YAAe,SAC3B,EAAU,EAAU,cAAgB,EAAmB,EAAU,YAGxE,EAAU,aAAa,EAAoB,CAAQ,GAChB,EAEvC,EAaa,IAEX,EAEA,EACA,IAMS,CACT,GAAI,CAAC,EAAM,WAAY,CACrB,IAAM,EAAsB,IACzB,EAAE,OAA4C,EAAE,SAChD,EAAM,OAC8B,EAAM,MAO7C,OANI,GAA2B,CAAM,EAC5B,EAAO,IAAI,IAAO,CACvB,GAAG,EACH,QAAS,EAAG,QAAQ,OAAO,GAAK,EAAmB,CAAC,CAAC,CACvD,EAAE,EAEG,EAAO,OAAO,GAAK,EAAmB,CAAC,CAAC,CACjD,CAWA,OATI,GAA2B,CAAM,EAC5B,EACJ,IAAI,IAAO,CACV,GAAG,EACH,QAAS,EAAG,QAAQ,OAAO,GAAK,GAAmB,EAAO,EAAU,CAAC,CAAC,CACxE,EAAE,CAAC,CACF,OAAO,GAAM,EAAG,QAAQ,OAAS,CAAC,EAGhC,EAAO,OAAO,GAAK,GAAmB,EAAO,EAAU,CAAC,CAAC,CAClE,ECkBa,IACX,EACA,IACc,IAAW,IAAU,CAAE,KAAM,EAAO,MAAO,EAAO,MAAO,CAAM,EAKlE,IACX,EACA,EACA,EACA,IACqB,EAAU,WAAa,EAAa,EAAO,EAAU,CAAE,WAAU,CAAC,EAK5E,GAAgC,GAA2C,CACtF,IAAM,EAAQ,GAAgB,MAC9B,OACG,OAAO,GAAU,UAAY,IAAU,SAAa,OAAO,GAAU,UAAY,EAAQ,CAE9F,EAaa,IACX,EACA,EACA,IAC2B,CAC3B,IAAM,EAAgB,EAAgB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAO9E,OANI,EAAK,aAAe,CAAC,EAAU,EAAe,EAAK,WAAW,EACzD,CACL,GAAG,EACH,CAAE,KAAM,EAAK,YAAa,MAAO,EAAK,YAAa,MAAO,EAAK,WAAY,CAC7E,EAEK,CACT,EAKa,GACX,GACuC,GAAc,EAAW,OAAS,EAAI,EAAa,KAM/E,IACX,EACA,EACA,EACA,IAEA,EAAK,cAAgB,QACjB,SACA,EAAK,cAAgB,YACnB,EACE,EAAG,EAAK,QAAQ,IAAM,MAAQ,EAAG,EAAK,QAAQ,IAAM,QAClD,cACA,SACF,OACF,EAAmB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAKtD,IACX,EACA,EACA,EACA,EACA,IAC+B,CAC/B,IAAM,EACJ,EAAK,cAAgB,QACjB,GAAyB,EAAW,EAAQ,EAAK,QAAQ,EACzD,EAAK,cAAgB,YAClB,GAAoB,CAAC,EACtB,EAAU,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAC1D,OAAO,GAAsB,CAAC,GAAK,GAA2B,CAAC,EAAI,EAAiB,CAAC,EAAI,CAC3F,EAMa,IACX,EACA,EACA,EAA+B,CAAC,EAChC,EAAa,EAAK,IAAM,KAExB,EAAc,KACb,OAAO,EAAU,WAAc,WAAa,EAAU,UAAU,CAAI,EAAI,MAa9D,IACX,EACA,EACA,EAA0D,CAAC,IACxC,CACnB,GAAM,CACJ,SACA,WACA,eACA,gBACA,eACA,gBACA,qBACA,YACA,kBACA,2BACE,EAEE,EAAY,GAAa,EAAK,MAAO,CAAQ,EAC7C,EAAY,EAAU,WAAa,EAAa,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EACxF,EAAa,EAAc,EAAK,MAAO,CAAE,WAAU,CAAC,EACpD,EAAY,EAAa,EAAK,MAAO,CAAE,WAAU,CAAC,EAClD,EAAiB,EAAU,EAAW,EAAK,QAAQ,EACnD,EAAqB,GAA0B,EAAM,EAAW,CAAe,EAC/E,EAAa,GAAoB,EAAc,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,CAAC,EAE9F,MAAO,CACL,YACA,kBAAmB,GAA6B,CAAc,EAC9D,YACA,aACA,iBACA,YACA,aACA,iBAAkB,GAAwB,EAAM,EAAW,EAAQ,cAAe,EAAQ,EAAE,EAC5F,gBAAiB,GAAuB,EAAM,EAAW,EAAY,CAAkB,EACvF,OAAQ,GAAc,EAAM,EAAW,EAAQ,EAAY,CAAS,EACpE,qBACA,aAAc,EAAmB,KAAK,CAAE,WAAY,CAAK,EACzD,qBAAsB,IAA0B,EAAK,MAAO,CAAE,WAAU,CAAC,GAAK,CAAC,CACjF,CACF,EAsBa,IACX,EACA,IAEA,EAAgB,CAAS,EAAI,EAAU,WAAc,EAAe,CAAW,GAAK,GAWzE,IACX,EACA,EACA,EAA0D,CAAC,IACnC,CACxB,IAAM,EAAyB,EAAkB,CAAS,EACpD,EAAa,GAAuB,EAAW,CAAW,EAC1D,EAAmB,EAAU,EAAa,CAAU,EAE1D,MAAO,CACL,aACA,mBACA,cACA,yBAA0B,EAAyB,KAAQ,GAAkB,WAAa,GAC1F,yBACA,kBAAmB,EAAQ,eAAiB,CAAC,EAAA,CAAG,EAAQ,IAAM,EAAU,IAAM,KAAO,IACvF,CACF,ECtRa,GACX,EACA,CAAE,eAAc,oBAAyC,CAAC,IAElD,CACR,GAAI,CAAC,GAAgB,OAAO,GAAQ,UAAY,OAAO,GAAQ,SAC7D,OAAO,EAGT,GAAI,IAAiB,SACnB,OAAO,OAAO,WAAW,CAAa,EAGxC,IAAM,EAEJ,EAAgB,EAAK,CACnB,qBAAsB,IAAiB,WACvC,mBACA,cAAe,GACf,MAAO,EACT,CAAC,EAEH,OAAO,OAAO,GAAa,UAAY,CAAC,OAAO,MAAM,CAAQ,EAAI,EAAW,CAC9E,ECtCM,GAAsB,IAAI,IAAI,CAAC,UAAW,aAAc,KAAM,OAAO,CAAC,EAO/D,GAAqB,GAChC,IAAa,WAAa,IAAa,aAgB5B,IAAuB,CAClC,WACA,OACA,WACA,QACA,eASE,CAAC,GACD,IAAS,eACT,CAAC,GAAoB,IAAI,CAAQ,IAChC,MAAM,QAAQ,CAAK,GACjB,IAAc,UAAY,OAAO,GAAU,UAAY,EAAM,SAAS,GAAG,GAG1E,CAAE,MAAO,GAAM,MAAO,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,CAAC,CAAC,IAAM,EAAG,EAC5E,CAAE,MAAO,GAAO,OAAM,EAYf,IAAuB,CAClC,QACA,QACA,eACA,WACA,SACA,gBACA,uBAWa,CACb,IAAM,EAAY,EAAY,EAAO,CAAE,aAAc,CAAkB,CAAC,EAClE,EACJ,IAAU,GACV,GAAkB,CAAQ,IACzB,EAAa,OAAS,GAAK,EAAa,KAAO,IAAA,IAGlD,GAAI,EAAa,KAAW,GAAa,CAAC,EACxC,OAAO,EAAgB,EAAe,GAAS,EAAc,GAAG,EAGlE,IAAM,EAAI,CAAC,GAAG,CAAY,EAQ1B,MAPA,GAAE,GAAS,EACP,IAGF,EAAE,GAAK,EAAe,CAAM,GAAK,IAG5B,EAAgB,EAAI,GAAS,EAAG,GAAG,CAC5C,EAQa,IACX,EACA,IACY,CACZ,IAAM,EAAmB,EAAY,EAAO,CAC1C,aAAc,EACd,iBAAkB,EACpB,CAAC,EAED,GAAI,CACF,OAAO,OAAO,CAA4C,CAC5D,MAAQ,CACN,OAAO,CACT,CACF,EAQa,IACX,EACA,IAEA,IAAc,UAAY,IAAa,MAAQ,IAAa,QACxD,OACA,GAAa,OAQN,IACX,EACA,CAAE,WAAU,iBAAmE,CAAC,IAC1D,CACtB,GAAI,CAAC,EAAU,OAAO,EAEtB,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,EAAgB,EAAe,GAAS,EAAc,GAAG,CAClE,EAQa,IACX,EACA,IAES,EAAW,EAAQ,CAAK,CAAC,CAAC,IAAI,MAAM,EAAI,EC3J7C,IACJ,EACA,EACA,IAC4B,CAC5B,IAAM,EAAkC,CAAC,EAEzC,IAAK,IAAM,KAAO,EAAK,CACrB,GAAI,GAAY,CAAG,EAAG,SACtB,IAAM,EAAY,EAAY,GAC1B,IAAc,KAGd,GAAa,IAAQ,GAClB,GAAY,CAAS,IACxB,EAAO,GAAa,EAAI,IAErB,IACH,EAAO,GAAO,EAAI,KAGpB,EAAO,GAAO,EAAI,GAEtB,CAEA,OAAO,CACT,EA4HA,SAAgB,EACd,EACA,EAAqC,CAAC,EACtC,CACA,GAAM,CACJ,gBAAgB,GAAK,EACrB,qBAAqB,GAAM,EAC3B,cAAc,CAAC,EACf,gBAAgB,CAAC,EACjB,cAAc,CAAC,EACf,WAAW,GACX,2BAA2B,IACzB,EAGE,EAAgB,IAA+B,CACnD,GAAG,EACD,GACE,CACE,GAAG,EACH,GAAI,EAAgB,CAAE,EAClB,CAAE,WAAY,EAAc,EAAG,aAAe,EAAG,UAAW,EAC5D,CAAC,CACP,EACA,EACA,CACF,CACF,EACA,GAAI,EAAY,QAAa,GACzB,KACA,EAEG,EAAY,OAAY,SAAU,EAAG,MAAM,KAAK,EAAQ,IAAQ,CAC/D,IAAM,EAAa,EAAW,KAAO,CAAE,KAAM,CAAC,GAAG,EAAG,KAAO,CAAG,CAAE,EAShE,OARI,OAAO,GAAM,SAER,EAAc,IAAM,EAClB,EAAY,CAAC,EAEf,EAAa,CAAE,GAAG,EAAG,GAAG,CAAW,CAAC,EAGtC,EACL,GACE,CACE,GAAG,EACH,GAAG,EACH,GAAI,aAAc,EAAI,CAAE,SAAU,EAAY,EAAE,WAAa,EAAE,QAAS,EAAI,CAAC,CAC/E,EACA,EACA,CACF,CACF,CACF,CAAC,CACH,CACN,GAEA,OAAO,EAAa,CAAE,GAAG,EAAO,GAAI,EAAW,KAAO,CAAE,KAAM,CAAC,CAAE,CAAG,CAAC,CACvE,CCrNA,MAAa,GAAsB,GACjC,EAAO,CAAE,GAAK,OAAO,EAAG,OAAU,UAOvB,GACX,EACA,EACA,IACY,CACZ,GAAI,EAAG,MACL,MAAO,GAET,GAAI,OAAO,GAAqB,UAC9B,OAAO,EAET,GAAI,GAAmB,CAAgB,EACrC,OAAO,EAAiB,MAE1B,GAAI,OAAO,GAAc,YAAc,CAAC,EAAY,CAAE,EAAG,CACvD,IAAM,EAAK,EAAU,CAAE,EACvB,GAAI,OAAO,GAAO,UAChB,OAAO,EAGT,GAAI,GAAmB,CAAE,EACvB,OAAO,EAAG,KAEd,CACA,MAAO,EACT,ECtCa,IAAwB,CACnC,eACA,eAIuB,CACvB,GAAI,OAAO,GAAiB,SAAU,CACpC,GAAM,CAAC,EAAQ,GAAS,EAAa,MAAM,GAAG,EAO9C,OAJI,IAAU,UACL,IAAc,UAAW,EAG3B,CACT,CAEA,OAAO,EAAe,SAAW,EACnC,ECQa,GAAkB,GAAgC,CAC7D,OAAQ,EAAG,CAAW,EAAtB,CACE,IAAK,OACH,MAAO,UACT,IAAK,UACH,MAAO,cACT,IAAK,QACH,MAAO,SACT,IAAK,aACH,MAAO,cACT,IAAK,WACL,IAAK,aACL,IAAK,WACH,MAAO,OACT,IAAK,iBACL,IAAK,mBACL,IAAK,iBACH,MAAO,WACT,QACE,OAAO,CACX,CACF,EASa,IACV,EAAiB,QACjB,GAAG,IACF,EAAe,YAAY,IAAM,SAC7B,UAAU,EAAO,KAAK,IAAI,EAAE,GAC5B,EAAO,KAAK,IAAI,EAAe,EAAE,EAS5B,GAAoB,GAAyC,CACxE,OAAQ,EAAR,CACE,IAAK,WACL,IAAK,iBACH,MAAO,CAAC,IAAK,GAAG,EAClB,IAAK,aACL,IAAK,mBACH,MAAO,CAAC,GAAI,GAAG,EACjB,IAAK,WACL,IAAK,iBACH,MAAO,CAAC,IAAK,EAAE,EACjB,QACE,MAAO,CAAC,GAAI,EAAE,CAClB,CACF,EAUa,IACX,EACA,EACA,CACE,iBAAiB,KACjB,kBACA,gBAAgB,CAAC,GAAI,EAAE,GAKrB,CAAC,IACM,CACX,GAAM,CAAC,EAAK,GAAQ,GAAiB,CAAU,EACzC,EAAY,GAAmB,IAC/B,EAAS,GAAc,GAAG,EAAc,KAAK,IAAY,IAAI,IAAY,EAAc,KACvF,EAAQ,CAAC,GAAO,EAAM,CAAG,EAAG,EAAU,GAAQ,EAAM,CAAI,CAAC,CAAC,CAAC,OAAO,OAAO,EAC/E,OAAO,EAAM,OAAS,EAAI,GAAa,CAAc,CAAC,CAAC,GAAG,CAAK,EAAI,CACrE,EAOa,GAAiB,CAC5B,IAAK,MACL,KAAM,MACN,IAAK,MACL,KAAM,OACN,IAAK,MACL,KAAM,OACN,GAAI,MACJ,MAAO,OACP,MAAO,MACT,EAOa,GAAkB,CAC7B,IAAK,SACL,KAAM,MACN,IAAK,KACL,KAAM,MACN,IAAK,KACL,KAAM,MACN,GAAI,KACJ,MAAO,OACT,EAOa,GAGT,CACF,IAAK,KACL,GAAI,IACN,EAgBa,GAGT,CACF,YAAa,EAAW,IAAc,OAAO,GAAM,UAAY,EAAE,WAAW,CAAC,EAC7E,UAAW,EAAW,IAAc,OAAO,GAAM,UAAY,EAAE,SAAS,CAAC,CAC3E,EAUa,IACX,EACA,KACsB,CACtB,GAAG,EAEH,MAAO,EAAG,MAAM,IAAI,GAAK,CACvB,GAAI,OAAO,GAAM,SACf,OAAO,EAGT,GAAI,EAAY,CAAC,EACf,OAAO,GAAe,EAAG,CAAO,EAGlC,IAAM,EAAY,EAAU,EAAQ,OAAiC,EAAE,KAAK,EACtE,EAAe,GAAqB,CACxC,aAAc,EAAQ,aACtB,UAAW,GAAW,SACxB,CAAC,EAED,GAAI,MAAM,QAAQ,EAAE,KAAK,EACvB,MAAO,CAAE,GAAG,EAAG,MAAO,EAAE,MAAM,IAAI,GAAK,EAAY,EAAG,CAAE,cAAa,CAAC,CAAC,CAAE,EAG3E,IAAM,EAAa,EAAQ,EAAE,MAAO,CAAE,mBAAoB,EAAK,CAAC,CAAC,CAAC,IAAI,GACpE,EAAY,EAAG,CAAE,cAAa,CAAC,CACjC,EACA,GAAI,EAAW,MAAM,GAAK,OAAO,GAAM,QAAQ,EAAG,CAEhD,GAAI,EAAW,OAAS,EACtB,MAAO,CAAE,GAAG,EAAG,MAAO,CAAW,EAC5B,GAAI,EAAW,SAAW,EAC/B,MAAO,CAAE,GAAG,EAAG,MAAO,EAAW,EAAG,CAExC,CAEA,OAAO,CACT,CAAC,CACH,GAOa,EAAgB,GAC1B,OAAO,GAAU,UAAY,EAAM,OAAS,GAC5C,OAAO,GAAU,UAAY,CAAC,OAAO,MAAM,CAAK,GAChD,OAAO,GAAU,UAAY,OAAO,GAAU,SASpC,GAAwB,EAAgB,IACnD,CAAC,CAAC,IACD,OAAO,GAAU,UAChB,OAAO,GAAU,UAChB,OAAO,GAAU,UAAY,GAAa,KAAK,CAAK,GAU5C,GACX,GAC2C,EAAe,QAAU,EAWzD,IAEX,EAAwD,CAAC,GAAI,EAAE,IAE/D,MAAM,QAAQ,CAAmB,EAC7B,EACA,OAAO,GAAwB,SAC7B,CAAC,EAAqB,CAAmB,EACxC,GAAuB,CAAC,GAAI,EAAE,EAQ1B,IACX,EACA,CAAE,sBAAqB,8BACZ,CACX,GAAM,CAAC,EAAM,GAAS,GAA4B,CAAmB,EACrE,OAAO,OAAO,GAA6B,UAAY,EAAyB,OAAS,EACrF,GACE,GAAQ,EAAW,CAAwB,CAAC,CAAC,IAAI,GAAQ,GAAG,IAAO,IAAO,GAAO,EACjF,CACF,EACA,GAAG,IAAO,IAAY,GAC5B,EAEM,GAAmB,CAAC,IAAK,IAAK,GAAG,EAW1B,GAAiC,GAAwC,CACpF,IAAM,EAAmB,CAAC,EACpB,EAAY,IAAI,IAAI,EAAgB,EAE1C,IAAK,IAAM,KAAQ,EAAM,YAAY,EACnC,GAAI,EAAU,IAAI,CAAI,IACpB,EAAO,KAAK,CAAI,EAChB,EAAU,OAAO,CAAI,EACjB,EAAU,OAAS,GAAG,MAK9B,IAAK,IAAM,KAAU,GACf,EAAU,IAAI,CAAM,GACtB,EAAO,KAAK,CAAM,EAItB,OAAO,CACT,EASa,IAAmB,EAAgB,EAAc,MAAgB,CAC5E,IAAM,EAAI,GAAG,GAAS,KACtB,OAAO,GAAe,EAAE,WAAW,CAAW,EAAI,EAAI,GAAG,IAAc,GACzE,EAQa,IAAoB,EAAgB,EAAc,MAAgB,CAC7E,IAAM,EAAI,GAAG,GAAS,KACtB,OAAO,GAAe,EAAE,WAAW,CAAW,EAAI,EAAE,MAAM,EAAY,MAAM,EAAI,CAClF,EASa,GAAwC,CAKnD,YAAa,GAEb,oBAAqB,kCACrB,gBAAiB,iBACjB,YAAa,UACb,gBAAiB,aAGnB,EAKM,IACJ,EACA,EACA,IAGA,EAAU,WAAW,CAAG,GAExB,EAAW,MACT,GAEE,EAAU,SAAS,IAAI,GAAG,GAE1B,EAAU,MAAM,IAAI,CAAC,EAAE,SAAW,EAAW,MACjD,EAQW,IACX,EACA,EACA,EAAsC,CAAC,IAEvC,EAAW,SAAW,EACjB,EAAa,IACd,GAAsB,IACa,GAClC,OAAO,QAAQ,CAAY,CAAC,CAAC,MAAM,CAAC,KACnC,GAAuB,EAAK,EAAW,CAAU,CACnD,CAAC,GAAG,IACJ,OAAO,QAAQ,EAAqB,CAAC,CAAC,MAAM,CAAC,KAC3C,GAAuB,EAAK,EAAW,CAAU,CACnD,CAAC,GAAG,IACJ,GAAsB,IACY,GAsB3B,EAAoB,GAAsD,CACrF,GAAM,CAAE,OAAM,aAAc,EAAK,OAAS,CAAC,EAE3C,GAAI,CAAC,EAAM,OAAO,KAElB,GAAI,CAAC,EAAY,EAAK,KAAK,EAAG,MAAO,GAErC,IAAM,EAAc,EAAG,CAAI,EAErB,EACJ,IAAgB,WAAa,IAAc,EACvC,OACA,IAAgB,UAAY,IAAc,EACxC,OACA,EAWR,OARG,IAAqB,WACpB,IAAqB,UACrB,IAAqB,aACtB,OAAO,GAAc,UAAY,EAAY,GAEvC,GAGF,CAAE,KAAM,EAA6B,WAAW,CACzD,EAMa,GAA2B,aAW3B,IAA2B,EAAgB,IACtD,EAAgB,EAAI,GAAG,GAAyB,GAAG,IAAkB,GAW1D,IAA+B,EAAc,IACxD,OAAO,GAAU,SAAW,CAAE,QAAS,EAAM,SAAS,CAAE,EAAI,EAUjD,IAA0B,EAAc,IACnD,EAAO,CAAK,GAAK,OAAO,KAAK,CAAK,CAAC,CAAC,SAAW,GAAK,OAAO,EAAM,SAAY,SACzE,OAAO,EAAM,OAAO,EACpB,EC1fO,IAA4D,EAAW,IAAY,CAC9F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,GAAiB,GACvC,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAChC,EAAgB,CAAE,EAAI,IAAI,GAAiB,EAAG,YAAqC,GAAK,GAC1F,EAEM,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,IAAM,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAExF,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC7FMC,GAAgB,GAAe,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAE9EC,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAO9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,eAAc,sBAAuB,EACrD,CAAE,QAAO,WAAU,QAAO,eAAgB,EAG1C,EAAe,IAAgB,SAAW,IAAgB,YAC1D,EAAa,EAAG,IAAa,IAAM,KAAO,CAAQ,EAClD,EACJ,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,OAAO,GAAU,UACjB,EAAqB,EAAO,CAAY,EAEpC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,EAAW,EAAe,EAAK,MAAwB,CAC3D,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,GAAG,IAAoB,EAAE,MAAQ,IAAI,EAAE,QAAU,IAAK,EAC5F,CAAC,EACK,EAAoB,GAA6B,EAAU,CAC/D,GAAI,EACJ,cAAe,EAAgB,CACjC,CAAC,EAED,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,GAAG,EAAM,OAAO,EAAkB,IAAI,EAAkB,GAEjE,IAAK,OACL,IAAK,OACH,MAAO,GAAG,IAAS,OAAS,IAAM,KAAK,EAAM,UAAU,EAAkB,IAAI,EAAkB,GAEjG,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAa,UAAU,EAAM,UAC7B,EAAgB,GAAG,EAAM,UAAU,EAAkB,IAAI,EAAkB,UAE3E,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,KAKlE,OAHI,EAAY,GAAK,EAAY,EACxB,UAAU,EAAc,IAAI,EAAG,IAAI,EAAW,KAAK,EAAU,GAE/D,GAAG,EAAc,GAAG,EAAG,GAAG,GACnC,CACF,CACF,CAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAC5B,GAAgB,EACZ,EAAa,CAAK,EAClB,IAAIA,GAAmB,EAAO,CAAY,EAAE,KAGpD,IAAK,WACL,IAAK,iBAEH,MAAO,GADQD,GAAa,CAAU,EAAI,IAAM,KAC7B,EAAM,YACvB,EAAe,EAAa,CAAK,EAAI,IAAIC,GAAmB,EAAO,CAAY,EAAE,GAClF,GAGH,IAAK,aACL,IAAK,mBAEH,MAAO,GADQD,GAAa,CAAU,EAAI,IAAM,KAC7B,EAAM,cACvB,EAAe,EAAa,CAAK,EAAI,IAAIC,GAAmB,EAAO,CAAY,EAAE,GAClF,GAGH,IAAK,WACL,IAAK,iBAEH,MAAO,GADQD,GAAa,CAAU,EAAI,IAAM,KAC7B,EAAM,YACvB,EAAe,EAAa,CAAK,EAAI,IAAIC,GAAmB,EAAO,CAAY,EAAE,GAClF,GAGH,IAAK,OACH,MAAO,GAAG,EAAM,UAElB,IAAK,UACH,MAAO,GAAG,EAAM,UAElB,IAAK,KACL,IAAK,QAAS,CACZ,GAAM,CAAC,EAAQ,GAAUD,GAAa,CAAU,EAAI,CAAC,KAAM,GAAG,EAAI,CAAC,GAAI,EAAE,EAEzE,MAAO,GAAG,IAAS,EAAM,OADJ,EAAQ,CACc,CAAC,CACzC,IAAI,GACH,GAAgB,EAAqB,EAAK,CAAY,EAClD,GAAG,EAAa,CAAG,IACnB,IAAIC,GAAmB,EAAK,CAAY,EAAE,EAChD,CAAC,CACA,KAAK,IAAI,EAAE,GAAG,GACnB,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,CAAC,GAAuB,EAAa,EAAE,GACvC,CAAC,GAAuB,EAAa,EAAE,EACvC,CACA,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EACvD,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EACxD,IACA,EAAa,OAAO,MAAM,CAAQ,EAClC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAO,CAAY,EAAE,GAC9C,EACA,EAAc,OAAO,MAAM,CAAS,EACpC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAQ,CAAY,EAAE,GAC/C,EAEJ,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,OAAO,IAAe,UAClB,IAAI,EAAM,MAAM,EAAW,MAAM,EAAM,MAAM,EAAY,GACzD,IAAI,EAAM,KAAK,EAAW,MAAM,EAAM,KAAK,EAAY,EAC7D,CACE,MAAO,EAEX,CACF,CACA,MAAO,EACT,EC1Ka,GAAkB,CAAE,KAAM,CAAC,CAAE,MAAO,EAAK,CAAC,CAAE,EAO5C,IACX,EACA,EACA,IACG,CACH,GAAM,CACJ,UACA,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,CAAE,uBAAyB,GAAW,CAAC,EAEvC,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,GAAkB,GAGvC,IAAM,EAAa,IAAI,EAAG,EAAG,UAAU,IACnC,EAAgB,GAEd,EAAyC,EAAG,MAC/C,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAKhD,OAJI,GACF,EAAgB,GACT,GAEF,EACT,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EACL,EACA,CACE,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,EACA,CACF,CACF,CAAC,CAAC,CACD,OAAO,OAAO,EAEX,EACJ,EAAY,OAAS,EACjB,EAAY,SAAW,GAAK,CAAC,EAC3B,EAAY,GACZ,EAAG,GAAa,CAAY,EAC9B,GAEN,OAAO,EAAG,IAAO,EAAsB,CAAE,KAAM,CAAO,EAAI,CAAE,KAAM,CAAC,CAAM,CAAE,EAAK,CAClF,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,ECzFMC,IAAoB,EAAgB,EAAa,EAAe,KACpE,EAAqB,EAAO,GAAgB,OAAO,GAAU,QAAQ,EACjE,OAAO,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,CAAC,EACrD,EAOO,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,qBAAoB,WAAY,EAChD,EAAe,IAAgB,QAE/B,CAAE,qBAAuB,GAAW,CAAC,EAErC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAa,CAAE,MAAO,CAAE,QAAS,CAAC,IAAI,IAAS,CAAC,CAAC,CAAE,CAAE,EACrD,EAAmB,GACvB,EAAe,EAAwB,CACrC,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,GAAG,EAAM,GAAG,EAAE,QAAU,CAAM,EAC9E,CAAC,EACD,CACE,GAAI,EAEJ,cAAe,GACf,QAAS,CAAE,GAAG,EAAQ,QAAS,kBAAmB,EAAM,CAC1D,CACF,EACM,EAAqB,GACzB,EAAe,EAAwB,CACrC,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,SAAS,EAAE,QAAU,OAAQ,EAC7E,CAAC,EACD,CACE,GAAI,EAEJ,cAAe,GACf,QAAS,CAAE,GAAG,EAAQ,QAAS,kBAAmB,GAAM,oBAAqB,EAAK,CACpF,CACF,EAEM,EAAgB,CACpB,MAAO,CACL,QAAS,CACP,CAAE,QAAS,CAAE,MAAO,IAAI,IAAS,GAAI,OAAQ,KAAM,CAAE,KAAM,CAAC,CAAkB,CAAE,CAAE,CAAE,EACpF,CAAC,CACH,CACF,CACF,EAEA,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,CAAE,MAAO,CAAE,IAAK,CAAC,EAAe,CAAU,CAAE,CAAE,EAEvD,IAAK,OACH,MAAO,CAAE,KAAM,CAAC,CAAgB,CAAE,EAEpC,IAAK,OACH,OAAO,EAET,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EACJ,IAAS,UACL,GAAe,MACf,IAAS,SACP,GAAe,MACf,GAAe,KAKvB,OAHI,EAAY,GAAK,EAAY,EACxB,CAAE,MAAO,EAAG,GAAK,CAAC,EAAe,CAAE,UAAW,CAAC,EAAY,CAAS,CAAE,CAAC,CAAE,CAAE,EAE7E,CAAE,MAAO,EAAG,GAAK,CAAC,EAAe,CAAS,CAAE,CAAE,CACvD,CACF,CACF,CAEA,GAAI,IAAa,KAAO,CAAC,EACvB,OAAO,EACH,CAAE,IAAK,CAAC,IAAI,IAASA,GAAc,EAAO,EAAO,CAAY,CAAC,CAAE,EAChE,EAAG,GAAQA,GAAc,EAAO,EAAO,CAAY,CAAE,EAG3D,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAgB,GAAe,GACrC,OAAO,EACH,EAAG,GAAgB,CAAC,IAAI,IAAS,IAAI,GAAO,CAAE,EAC9C,EACE,CACE,KAAM,CACJ,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,CAAE,EAC3B,EAAG,GAAgB,CAAC,IAAI,IAASA,GAAc,EAAO,EAAO,CAAY,CAAC,CAAE,CAC9E,CACF,EACA,EAAG,GAAQ,EAAG,GAAgBA,GAAc,EAAO,EAAO,CAAY,CAAE,CAAE,CAClF,CAEA,IAAK,WACH,OAAO,EACH,CAAE,OAAQ,QAAQ,EAAM,iBAAiB,EAAM,EAAG,EAClD,EACE,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,CAAM,CAAE,EACpD,EAAG,GAAQ,CAAE,OAAQ,CAAM,CAAE,EAErC,IAAK,aACH,OAAO,EACH,CAAE,OAAQ,QAAQ,EAAM,mBAAmB,EAAM,EAAG,EACpD,EACE,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,IAAI,GAAQ,CAAE,EAC1D,EAAG,GAAQ,CAAE,OAAQ,IAAI,GAAQ,CAAE,EAE3C,IAAK,WACH,OAAO,EACH,CAAE,OAAQ,QAAQ,EAAM,iBAAiB,EAAM,EAAG,EAClD,EACE,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,GAAG,EAAM,EAAG,CAAE,EAC1D,EAAG,GAAQ,CAAE,OAAQ,GAAG,EAAM,EAAG,CAAE,EAE3C,IAAK,iBACH,OAAO,EACH,CAAE,OAAQ,SAAS,EAAM,iBAAiB,EAAM,EAAG,EACnD,EACE,CAAE,KAAM,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,CAAM,CAAE,CAAE,EAC9D,EAAG,GAAQ,CAAE,KAAM,CAAE,OAAQ,CAAM,CAAE,CAAE,EAE/C,IAAK,mBACH,OAAO,EACH,CAAE,OAAQ,SAAS,EAAM,mBAAmB,EAAM,EAAG,EACrD,EACE,CAAE,KAAM,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,IAAI,GAAQ,CAAE,CAAE,EACpE,EAAG,GAAQ,CAAE,KAAM,CAAE,OAAQ,IAAI,GAAQ,CAAE,CAAE,EAErD,IAAK,iBACH,OAAO,EACH,CAAE,OAAQ,SAAS,EAAM,iBAAiB,EAAM,EAAG,EACnD,EACE,CAAE,KAAM,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,GAAG,EAAM,EAAG,CAAE,CAAE,EACpE,EAAG,GAAQ,CAAE,KAAM,CAAE,OAAQ,GAAG,EAAM,EAAG,CAAE,CAAE,EAErD,IAAK,OACH,OAAO,EAAoB,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,CAAE,EAAI,EAAG,GAAQ,IAAK,EAE5E,IAAK,UACH,OAAO,EAAoB,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,CAAE,EAAI,EAAG,GAAQ,CAAE,IAAK,IAAK,CAAE,EAErF,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,EACH,CACE,OAAQ,GAAG,IAAe,QAAU,IAAM,GAAG,GAAG,EAC7C,IAAI,GAAO,QAAQ,GAAK,CAAC,CACzB,KAAK,GAAG,EAAE,kBAAkB,EAAM,EACvC,EACA,EACE,IAAe,QACb,CACE,KAAM,EACH,GAAe,IAAK,CACnB,IAAI,IACJ,EAAa,IAAI,GAAOA,GAAc,EAAK,EAAK,CAAY,CAAC,CAC/D,CACF,CACF,EACA,EACG,GAAe,IAAc,CAC5B,IAAI,IACJ,EAAa,IAAI,GAAOA,GAAc,EAAK,EAAK,CAAY,CAAC,CAC/D,CACF,EACF,EACG,GAAQ,EACN,GAAe,IAAc,EAAa,IAAI,GAC7CA,GAAc,EAAK,EAAK,CAAY,CACtC,CACF,CACF,CACR,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAM,CAAC,EAAO,GAAU,EAClB,EAAWA,GAAc,EAAO,IAAY,EAAI,EAChD,EAAYA,GAAc,EAAQ,IAAY,EAAI,EACpD,EAAa,GAAuB,OAAO,MAAM,CAAQ,EAA7B,EAAyC,EACrE,EAAc,GAAwB,OAAO,MAAM,CAAS,EAA/B,EAA4C,EAC7E,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAWE,OATE,IAAe,UACV,EACH,CAAE,KAAM,CAAC,IAAI,IAAS,IAAI,GAAY,EAAG,KAAM,CAAC,IAAI,IAAS,IAAI,GAAa,CAAE,EAChF,EACE,CACE,KAAM,CAAC,CAAE,KAAM,CAAC,IAAI,IAAS,CAAU,CAAE,EAAG,CAAE,KAAM,CAAC,IAAI,IAAS,CAAW,CAAE,CAAC,CAClF,EACA,EAAG,GAAQ,CAAE,KAAM,EAAY,KAAM,CAAY,CAAE,EAElD,EACH,CACE,IAAK,CACH,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,GAAY,CAAE,EACvC,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,GAAa,CAAE,CAC1C,CACF,EACA,EACE,CACE,IAAK,CAAC,CAAE,IAAK,CAAC,IAAI,IAAS,CAAU,CAAE,EAAG,CAAE,IAAK,CAAC,IAAI,IAAS,CAAW,CAAE,CAAC,CAC/E,EACA,CAAE,IAAK,CAAC,EAAG,GAAQ,CAAE,IAAK,CAAW,CAAE,EAAG,EAAG,GAAQ,CAAE,IAAK,CAAY,CAAE,CAAC,CAAE,CAEvF,CACE,MAAO,EAEX,CACF,CACA,MAAO,EACT,ECxPa,IAA8C,EAAM,IAAY,CAC3E,IAAM,EAAW,GAAiC,EAAM,CAAO,EAC/D,OAAO,EAAW,KAAK,UAAU,CAAQ,EAAI,EAC/C,ECHa,IAA6D,EAAW,IAAY,CAC/F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAEjF,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,IAAM,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAExF,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC1FMC,GAAgB,GAAe,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAE9E,IAAkB,EAAgB,IAAqB,EAAS,KAAK,EAAO,GAAK,EAEjFC,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAO9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,eAAc,sBAAuB,EAGrD,EAAe,IAAgB,SAAW,IAAgB,YAC1D,EAAa,EAAG,IAAa,IAAM,KAAO,CAAQ,EAClD,EACJ,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,OAAO,GAAU,UACjB,EAAqB,EAAO,CAAY,EAEpC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAoB,GACxB,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,OAAS,OAAQ,EACzD,CAAC,EACD,CACF,EAEM,EAAa,GAAG,EAAM,SACtB,EAAgB,GAAG,EAAM,KAAK,EAAkB,UAEtD,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,GAAG,EAAc,MAAM,IAEhC,IAAK,OACH,MAAO,GAAG,EAAc,OAE1B,IAAK,OACH,MAAO,GAAG,EAAc,OAE1B,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,KAKlE,OAHI,EAAY,GAAK,EAAY,EACxB,GAAG,EAAc,GAAG,EAAG,IAAI,EAAW,KAAK,EAAU,GAEvD,GAAG,EAAc,GAAG,EAAG,GAAG,GACnC,CACF,CACF,CAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAC5B,GAAgB,EACZ,EAAa,CAAK,EAClB,IAAIA,GAAmB,EAAO,CAAY,EAAE,KAGpD,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAU,EACZ,eAAe,EAAa,CAAK,EAAE,gBACnC,MAAMA,GAAmB,EAAO,CAAY,EAAE,KAElD,OAAO,GAAe,GAAG,EAAM,WAAW,IAAWD,GAAa,CAAU,CAAC,CAC/E,CAEA,IAAK,aACL,IAAK,mBAAoB,CACvB,IAAM,EAAU,EACZ,cAAc,EAAa,CAAK,EAAE,gBAClC,IAAK,OAAO,GAAU,UAAY,CAAC,EAAM,WAAW,GAAG,GAAM,EAAe,IAAM,KAAKC,GAAmB,EAAO,CAAY,EAAE,KAEnI,OAAO,GAAe,GAAG,EAAM,WAAW,IAAWD,GAAa,CAAU,CAAC,CAC/E,CAEA,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAU,EACZ,eAAe,EAAa,CAAK,EAAE,eACnC,MAAMC,GAAmB,EAAO,CAAY,IAAK,OAAO,GAAU,UAAY,CAAC,EAAM,SAAS,GAAG,GAAM,EAAe,IAAM,GAAG,GAEnI,OAAO,GAAe,GAAG,EAAM,WAAW,IAAWD,GAAa,CAAU,CAAC,CAC/E,CAEA,IAAK,OACH,MAAO,GAAG,EAAM,UAElB,IAAK,UACH,MAAO,GAAG,EAAM,UAElB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAASA,GAAa,CAAU,EAAI,IAAM,GAC1C,EAAe,EAAQ,CAAK,EAClC,OAAO,EAAa,OAAS,EACzB,GAAG,EAAO,GAAG,EACV,IACC,GACE,GAAG,EAAM,MACP,GAAgB,EAAqB,EAAK,CAAY,EAClD,GAAG,EAAa,CAAG,IACnB,IAAIC,GAAmB,EAAK,CAAY,EAAE,IAEpD,CAAC,CACA,KAAK,MAAM,EAAE,GAChB,EACN,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,CAAC,GAAuB,EAAa,EAAE,GACvC,CAAC,GAAuB,EAAa,EAAE,EACvC,CACA,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EACvD,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EACxD,IACA,EAAa,OAAO,MAAM,CAAQ,EAClC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAO,CAAY,EAAE,GAC9C,EACA,EAAc,OAAO,MAAM,CAAS,EACpC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAQ,CAAY,EAAE,GAC/C,EACJ,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CACA,OAAO,IAAe,UAClB,IAAI,EAAM,MAAM,EAAW,OAAO,EAAM,MAAM,EAAY,GAC1D,IAAI,EAAM,KAAK,EAAW,MAAM,EAAM,KAAK,EAAY,EAC7D,CACE,MAAO,EAEX,CACF,CAEA,MAAO,EACT,ECjLMC,IAA2B,EAAY,EAAmB,IAC9D,GAAgB,OAAO,GAAM,SACzB,EAAE,WAAW,GAAG,IAAa,GAAG,IAAY,GAAW,EACvD,EAOO,IACX,CAAE,WAAU,QAAO,eAEnB,CACE,eACA,eACA,qBACA,sBACA,kBACA,iBAAiB,KACjB,2BACA,cACA,gBAAgB,CAAC,GAAI,EAAE,EACvB,gBACE,CAAC,IACF,CAEH,GAAI,IAAgB,YAAa,CAC/B,IAAM,EAAoB,EAAG,CAAQ,EACrC,GAAI,IAAsB,WAAa,IAAsB,aAAc,CACzE,IAAM,EAAe,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,EAChE,GACE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAE7B,MAAO,GAET,GAAM,CAAC,EAAO,GAAU,EAGxB,MAAO,CAAC,GAAgB,EAAO,CAAW,EAAG,GAAgB,EAAQ,CAAW,CAAC,CAAC,CAAC,KACjF,IAAI,GAAc,YAAc,GAAc,KAAO,MAAM,EAC7D,CACF,CACA,GAAI,IAAsB,MAAQ,IAAsB,QAAS,CAC/D,IAAM,EAAe,EAAQ,CAAK,EAIlC,OAHI,EAAa,SAAW,EACnB,GAEF,IAAI,EAAa,IAAI,GAAK,GAAgB,EAAG,CAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAC/E,CACA,IAAM,EAAW,GAAgB,EAAO,CAAW,EAEnD,OAAQ,EAAR,CACE,IAAK,WACL,IAAK,iBACL,IAAK,aACL,IAAK,mBACL,IAAK,WACL,IAAK,iBACH,OAAO,GAAiB,EAAU,EAAmB,CACnD,iBACA,kBACA,eACF,CAAC,CACL,CACA,OAAO,CACT,CAEA,IAAM,EAAe,IAAgB,QAC/B,EAAoB,EAAG,CAAQ,EAC/B,EAAY,GAAmB,IAE/B,EAAc,GAClB,GAAG,EAAc,KAAK,IAAY,IAAI,IAAY,EAAc,KAC5D,EAAe,GAAeA,GAAwB,EAAG,EAAW,CAAY,EAChF,EAAiB,GAAe,EAAW,EAAY,CAAC,CAAC,EACzD,EAAiB,GACrB,GAAmB,EAAa,CAAE,sBAAqB,0BAAyB,CAAC,EAC7E,EAAW,CAAE,iBAAgB,kBAAiB,eAAc,EAElE,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,UACH,MAAO,GAGT,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAYlC,OAXI,EAAa,OAAS,EACjB,IAAI,EACR,IAAI,GACH,EACI,EAAc,CAAC,EACf,EAAqB,EAAG,CAAY,EAClC,GAAG,EAAa,CAAC,IACjB,GAAG,EAAc,CAAC,GAC1B,CAAC,CACA,KAAK,IAAI,EAAE,GAET,EACT,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,EAChE,GACE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAE7B,MAAO,GAGT,GAAM,CAAC,EAAO,GAAU,EAElB,EAAW,EAAqB,EAAO,CAAY,EACrD,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,EAC7C,IACE,EAAY,EAAqB,EAAQ,CAAY,EACvD,EAAY,EAAQ,CAAE,aAAc,QAAS,CAAC,EAC9C,IACE,EAAa,OAAO,MAAM,CAAQ,EAAK,EAAe,GAAG,IAAU,EAAS,EAC5E,EAAc,OAAO,MAAM,CAAS,EACtC,EACE,GAAG,IACH,EACF,EAEE,EAAoB,CAAC,EAAY,CAAW,EAWlD,MATE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,IAEZ,EAAkB,GAAK,EACvB,EAAkB,GAAK,IAKrB,EACI,EAAkB,IAAI,GAAK,EAAc,CAAC,CAAC,EAC3C,EAAkB,MAAM,GAAK,EAAqB,EAAG,CAAY,CAAC,EAChE,EAAkB,IAAI,GAAK,EAAY,EAAG,CAAE,aAAc,QAAS,CAAC,CAAC,EACrE,EAAkB,IAAI,GAAK,EAAc,CAAC,CAAC,EAAA,CAIhD,KAAK,IAAI,GAAc,YAAc,GAAc,KAAO,MAAM,EAAE,CAEzE,CAEA,IAAK,WACL,IAAK,iBACH,OAAO,EACH,GAAiB,EAAc,CAAK,EAAG,EAAmB,CAAQ,EAClE,EAAW,IAAI,EAAY,CAAK,EAAE,EAAE,EAE1C,IAAK,aACL,IAAK,mBACH,OAAO,EACH,GAAiB,EAAc,CAAK,EAAG,EAAmB,CAAQ,EAClE,EAAW,GAAG,EAAY,CAAK,EAAE,EAAE,EAEzC,IAAK,WACL,IAAK,iBACH,OAAO,EACH,GAAiB,EAAc,CAAK,EAAG,EAAmB,CAAQ,EAClE,EAAW,IAAI,EAAY,CAAK,GAAG,CAC3C,CAMA,OAJI,OAAO,GAAU,UACZ,EAAQ,OAAS,QAGnB,EACH,EAAc,CAAK,EACnB,EAAqB,EAAO,CAAY,EACtC,GAAG,EAAa,CAAK,IACrB,GAAG,EAAc,CAAK,GAC9B,EC1La,GAGT,CACF,IAAK,MACL,GAAI,IACN,EAOa,IAA+D,EAAW,IAAY,CACjG,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,GAAoB,GAC1C,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAChC,EAAgB,CAAE,EAAI,IAAI,GAAoB,EAAG,YAAqC,GAAK,GAC7F,EAEM,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,OAAS,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAE3F,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EClEa,IACX,EACA,EACA,MAEE,EAAyC,IAAgC,CACzE,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,eACA,gBACA,iBACE,EAEJ,GAAI,CAAC,GAAW,CAAC,EAAkB,OAEnC,GAAM,CAAE,MAAK,MAAK,MAAO,EAEnB,GAAoB,EAAmB,IAA0C,CACrF,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAGF,IAAM,EAAiB,EAAG,MACvB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,YACA,QAAS,CAAE,GAAG,EAAQ,QAAS,UAAS,kBAAiB,CAC3D,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAe,SAAW,EAC5B,OAGF,IAAM,EACJ,EAAG,aAAe,KAAO,EAAG,GAAG,CAAc,EAAK,EAAI,GAAG,CAAc,EAEzE,OAAO,EAAG,IAAM,EAAI,CAAY,EAAI,CACtC,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,GCzGW,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAGE,EAAoB,GAAmD,CAC3E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,MAAO,GAGT,IAAM,EAAiB,EAAG,MACvB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAMjB,OAJI,EAAe,SAAW,GAIvB,CACL,KAAM,EAAG,IACL,CACE,SAAU,QAAQ,KAAK,EAAG,UAAU,EAChC,CAAE,KAAM,CAAE,OAAQ,CAAe,CAAE,EACnC,CACN,EACA,EAAG,QAAQ,KAAK,EAAG,UAAU,EAAI,SAAW,QAAS,CAAe,CAC1E,CACF,EAEM,EAAqB,EAAiB,EAAc,CAAS,CAAC,EACpE,OAAO,IAAuB,GAAQ,CAAC,EAAI,CAC7C,EClEa,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,EAAsB,GAA2C,CAErE,GAAI,OAAO,GAAS,UAAY,EAAY,CAAI,EAAG,OAEnD,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAE1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,CACH,EAGM,EAAiB,GAAiC,CACtD,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,MAAO,GAGT,IAAM,EAAuB,CAAC,EAE9B,IAAK,IAAM,KAAQ,EAAG,MAAO,CAC3B,GAAI,OAAO,GAAS,SAAU,SAE9B,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAS,EAAc,CAAI,EAC7B,GAAQ,EAAW,KAAK,CAAM,EAClC,QACF,CAEA,IAAM,EAAY,EAAmB,CAAI,EACrC,GAAW,EAAW,KAAK,CAAS,CAC1C,CAEA,GAAI,EAAW,SAAW,EAAG,MAAO,GAEpC,IAAM,EAAc,EAAqB,YAAc,MACjD,EAAS,EAAG,IAAM,MAAQ,EAMhC,OAJI,EAAW,SAAW,GAAK,CAAC,EAAG,IAAY,EAAW,GAInD,IAAI,EAAO,GADL,EAAW,IAAI,GAAM,EAAE,WAAW,GAAG,EAAI,KAAK,IAAM,CAAE,CAAC,CAAC,KAAK,IAClD,EAAE,EAC5B,EAGA,GACE,CAAC,EACC,EACA,EACE,EAAU,IAAyC,GAEvD,EAEA,OAAO,EAGT,IAAM,EAAkB,CAAC,EAEzB,IAAK,IAAM,KAAQ,EAAU,MAAO,CAClC,GAAI,OAAO,GAAS,SAAU,SAE9B,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAW,EAAc,CAAI,EAC/B,GAAU,EAAM,KAAK,CAAQ,EACjC,QACF,CAEA,IAAM,EAAY,EAAmB,CAAI,EACrC,GAAW,EAAM,KAAK,CAAS,CACrC,CAIA,OAFI,EAAM,SAAW,EAAU,EAExB,EAAM,KAAK,EAAE,CACtB,ECnHa,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAEjF,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,OAAS,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAE3F,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,ECrFa,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,EAAQ,EAAc,CAAS,EAE/B,GAAoB,EAAmB,IAAuC,CAClF,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,MAAO,GAGT,IAAM,EAAiB,EAAG,MACvB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAe,SAAW,EAC5B,MAAO,GAGT,IAAM,EAA8B,EAAG,EAAG,YAAa,CAAe,EAItE,OAAO,EAAG,IAAM,CAAE,IAAK,CAAc,EAAI,CAC3C,EAEA,OAAO,EAAiB,EAAO,EAAI,CACrC,ECtEa,IAA6D,EAAW,IAAY,CAC/F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAkB,EAAG,MACxB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEX,EAAa,EAAM,KAAK,EAAE,EAE1B,CAAC,EAAW,GAAa,EAAG,IAAM,CAAC,KAAM,GAAG,EAAI,CAAC,GAAI,EAAE,EACvD,CAAC,EAAQ,GACb,EAAM,OAAS,EACX,CAAC,GAAG,EAAU,GAAG,EAAG,aAAe,KAAO,IAAM,MAAO,IAAI,GAAW,EACtE,CAAC,EAAW,CAAS,EAE3B,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,EClEM,GAAe,GAAgB,EAAI,WAAW,GAAG,GAAK,EAAI,SAAS,GAAG,EAS/D,IACX,EACA,EACA,IACG,CACH,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAa,KAAK,EAAG,EAAG,UAAU,EAAE,GACtC,EAAgB,GAEd,EAAwB,EAAG,MAC9B,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAMhD,OALI,GACF,EAAgB,GAET,GAAY,CAAkB,EAAI,EAAqB,IAAI,EAAmB,IAEhF,EACT,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EACL,EACA,CACE,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,EACA,CACF,CACF,CAAC,CAAC,CACD,OAAO,OAAO,EAEX,EACJ,EAAY,OAAS,EACjB,EAAY,SAAW,GAAK,CAAC,EAC3B,EAAY,GACZ,GAAG,EAAW,IAAI,EAAY,KAAK,GAAG,EAAE,GAC1C,EAEN,OAAO,EAAG,IAAM,WAAW,GAAY,CAAM,EAAI,EAAS,IAAI,EAAO,GAAG,GAAK,CAC/E,EAEM,EAAiB,EAAiB,EAAc,CAAS,EAAG,EAAI,EACtE,OAAO,GAAY,CAAc,EAAI,EAAiB,IAAI,EAAe,EAC3E,ECjFa,IAA2D,EAAW,IAAY,CAC7F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAA+C,CAC7F,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAA2B,EAAqB,GAGzD,IAAM,EACJ,EAAkB,CAAE,GAAK,EAAG,MAAM,KAAK,GAAK,OAAO,GAAM,UAAY,EAAG,CAAC,IAAM,KAAK,EAChF,EAAc,CAAE,EAChB,EAEA,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAI,MAAO,CAE5B,GAAI,OAAO,GAAS,SAAU,CAE5B,EAAsB,GADV,EAAa,eAAiB,OACX,EAAa,IAA6B,EAAK,GAC9E,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EACrB,EACA,EAAI,MAAM,SAAW,GACnB,EACE,EAAI,KACJ,SAAS,KACP,EAAI,YACiC,EACvC,EAEN,EAEI,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,GAAgB,EAAK,aAAe,WAAa,QAEjD,EAAY,EAAU,EAAQ,EAAK,KAAK,EAExC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,eACA,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,GAAI,EAAe,SAAW,EAC5B,OAAO,EAGT,IAAM,EAAQ,EAAG,EAAI,YAAc,EAAE,IAAM,MACrC,EAAa,EAAQ,EAAI,WAAY,MAAM,CAAC,EAAI,EAAI,WACpD,EAAW,EAAI,KAAO,CAAC,GAA6B,GAAS,EAAe,OAAS,EAErF,CAAC,EAAU,GAAa,CAAC,cAAe,aAAa,CAAC,CAAW,IAAI,GACzE,EAAI,IACA,EACE,GAAkB,EAAK,EAAc,CAAC,MAAO,KAAK,CAAC,EACnD,GAAkB,EAAK,EAAc,CAAC,KAAK,CAAC,EAC9C,EACE,GAAkB,EAAK,EAAc,CAAC,KAAK,CAAC,EAC5C,GAAkB,EAAK,CAAY,CAC3C,EAEM,EAAS,EAAW,GAAG,EAAS,IAAI,KAAK,EAAI,GAC7C,EAAS,EAAW,KAAK,IAAW,KAAK,EAAI,GAE7C,EAAM,EAAa,eAAiB,KAE1C,MAAO,GAAG,IAAS,EAAe,KAChC,EAAgB,CAAG,EACf,GAAG,IAAM,EAAa,IAAmC,EAAW,GACpE,EACN,IAAI,GACN,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC/Ha,IAER,EAAW,IAAY,CAC1B,GAAM,CACJ,SACA,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,EAAgB,IAAW,gBAE3B,EAAgB,CAAC,EAEjB,EAAmC,CAAC,EACpC,EAAwC,IAAI,IAE5C,EAAqB,GAAkB,CACtC,EAAY,IAAI,CAAK,GACxB,EAAY,IAAI,EAAO,IAAI,GAAK,EAElC,IAAM,EAAiB,GAAG,EAAM,GAAG,EAAY,IAAI,CAAK,CAAC,CAAE,KAAO,IAElE,OADA,EAAY,IAAI,CAAK,CAAC,CAAE,IAAI,CAAc,EACnC,CACT,EAEM,EAAe,GAAmB,CACtC,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAGtD,MAAO,GAGT,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAExC,EAAkB,OAAO,YAC5B,CAAC,GAAG,EAAY,QAAQ,CAAC,CAAC,CAA6B,KAAK,CAAC,EAAG,KAAO,CAAC,EAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CACrF,EAEM,EAAgB,EACpB,EACA,CACE,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,oBACA,kBACA,WACF,EACA,CAAE,gBAAiB,CAAO,CAC5B,EAEA,GAAI,CAAC,EAAO,CAAa,EACvB,MAAO,GAGT,GAAM,CAAE,MAAK,OAAQ,GAAiB,EAEtC,GAAI,OAAO,GAAQ,UAAY,CAAC,EAC9B,MAAO,GAIT,GAAI,IAAW,iBAAmB,MAAM,QAAQ,CAAY,EAC1D,EAAO,KAAK,GAAG,CAAY,OACtB,GAAI,IAAW,uBAAyB,EAAO,CAAY,EAAG,CACnE,OAAO,OAAO,EAAa,CAAY,EAIvC,IAAK,IAAM,KAAK,OAAO,KAAK,CAAY,EAAG,EAAY,IAAI,EAAK,KAAK,CAAC,EAAE,IAAI,CAAC,CAC/E,CAEA,OAAO,CACT,EAEM,GAAoB,EAAsB,IAA+C,CAC7F,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAA2B,EAAqB,GAGzD,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,EAAM,EAAG,MAAM,SAAW,CAAC,EAE/D,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,IAAM,EAAgB,EAAY,CAAI,EAClC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAMA,OAJI,EAAe,SAAW,EACrB,EAGF,GAAG,EAAG,IAAM,OAAS,GAAG,GAAG,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAAE,EAC1G,EAKA,OAHI,EACK,CAAE,IAAK,EAAiB,EAAW,EAAI,EAAG,QAAO,EAEnD,CAAE,IAAK,EAAiB,EAAW,EAAI,EAAG,OAAQ,CAAY,CACvE,EC3Ja,GAAiB,CAAC,EAOlB,IAER,EAAW,IAAY,CAC1B,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,GAAiB,IAAA,GAGtC,IAAM,EAAa,EAAG,WAAW,YAAY,EACzC,EAAgB,GAEd,EAAyC,EAAG,MAC/C,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAKhD,OAJI,GACF,EAAgB,GACT,GAET,MACF,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,OAAO,EAAY,OAAS,EACxB,EAAY,SAAW,GAAK,CAAC,EAC3B,EAAY,GACZ,EAAG,GAAa,CAAY,EAC9B,EACN,EAEM,EAAS,EAAiB,EAAc,CAAS,EAAG,EAAI,EAE9D,OAAO,EAAU,IAAM,CAAE,IAAK,CAAO,EAAI,CAC3C,EC3Da,IAER,EAAW,IAAY,CAE1B,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,gBACA,UAAU,CAAC,GACT,EAEE,CAAE,mBAAoB,GAAO,EAInC,GAAI,CAAC,EAAI,OAET,IAAM,GACJ,EACA,IAC0C,CAC1C,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAGF,IAAM,EAAa,EAAG,WAAW,YAAY,EACzC,EAAgB,GAEd,EAAyC,EAAG,MAC/C,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAKhD,OAJI,GACF,EAAgB,GACT,GAET,MACF,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAY,SAAW,EAAG,OAE9B,IAAM,EACJ,EAAY,SAAW,GAAK,CAAC,EACzB,EAAY,GACZ,EAAG,EAAG,CAAU,IAAM,KAAO,EAAG,GAAK,EAAG,KAAM,CAAY,EAEhE,OAAO,EAAG,IAAM,EAAG,EAAG,KAAM,CAAO,EAAI,CACzC,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,EC9Fa,IAA+D,EAAW,IAAY,CACjG,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,GAAiB,GACvC,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAChC,EAAgB,CAAE,EAAI,IAAI,GAAiB,EAAG,YAAqC,GAAK,GAC1F,EAEM,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,IAAM,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAExF,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC7Fa,IAA4D,EAAW,IAAY,CAC9F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAA+C,CAC7F,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAA2B,EAAqB,GAGzD,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,EAAM,EAAG,MAAM,SAAW,CAAC,EAE/D,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GACjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,GAAgB,EAAK,aAAe,WAAa,QAEjD,EAAY,EAAU,EAAQ,EAAK,KAAK,EAExC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,eACA,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAMA,OAJI,EAAe,SAAW,EACrB,EAGF,GAAG,EAAG,IAAM,OAAS,GAAG,GAAG,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAAE,EAC1G,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,ECpFa,IACV,EAAW,IAAY,GAAQ,CAC9B,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,eACA,gBACA,UAAU,CAAC,EACX,iBACE,EAEE,EAAM,EAAQ,oBAEpB,GAAI,CAAC,EAAK,OAEV,GAAM,CAAE,MAAK,KAAI,MAAK,MAAO,EAEvB,EAAW,EAAG,EAAG,CAAC,EAGlB,EAAU,OAAO,KAAK,CAAI,EAGhC,GAAI,EAAQ,SAAW,EAAG,OAAO,EAEjC,IAAM,EAAoB,GAAkD,CAC1E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAGF,IAAM,EAAmC,EAAG,MACzC,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,YACA,QAAS,CACP,GAAG,EACH,gBAAiB,EACjB,sBAAuB,EAAQ,EACjC,CACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAe,SAAW,EAC5B,OAAO,EAIT,IAAM,EACJ,EAAe,SAAW,EACtB,EAAe,GACf,EAAG,aAAe,KAChB,EAAG,GAAI,CAAwC,EAC/C,EAAI,GAAI,CAAyC,EAEzD,OAAO,EAAG,IAAM,EAAI,CAAa,EAAI,CACvC,EAEA,OAAO,EAAiB,EAAc,CAAS,CAAC,GAAK,CACvD,ECjFI,GAAoB,IAAI,IAAI,CAAC,SAAU,QAAS,QAAQ,CAAC,EAEzD,GAAY,sBACZ,GAAY,iCACZ,GAAa,gBACb,GAAY,iBACZ,GAAa,gCACb,GAAa,6BAEb,IAAyB,EAAW,EAAW,IAAuB,CAC1E,IAAM,EAAO,IAAI,KAAK,KAAK,IAAI,EAAG,EAAI,EAAG,CAAC,CAAC,EAC3C,OAAO,EAAK,eAAe,IAAM,GAAK,EAAK,YAAY,IAAM,EAAI,GAAK,EAAK,WAAW,IAAM,CAC9F,EAEM,GAAyB,GAAuB,CACpD,IAAM,EAAQ,EAAE,MAAM,GAAG,EACnB,EAAI,OAAO,EAAM,EAAE,EACnB,EAAI,OAAO,EAAM,EAAE,EACnB,EAAM,EAAM,GAAK,OAAO,WAAW,EAAM,EAAE,EAAI,EACrD,OAAO,GAAK,GAAK,GAAK,IAAM,GAAK,GAAK,GAAK,IAAM,GAAO,GAAK,EAAM,EACrE,EAMM,IAA0B,EAAgB,IAA0C,CACpF,MAAU,MAA+B,IAAU,GAEvD,IAAI,GAAkB,IAAI,CAAS,EAAG,CACpC,IAAM,EAAI,OAAO,GAAU,SAAW,EAAM,KAAK,EAAI,EAGrD,OAFI,OAAO,GAAM,UAAY,OAAO,GAAM,UACtC,OAAO,GAAM,UAAY,GAAa,KAAK,CAAC,EAAG,OAC5C,qBACT,CAEA,GAAI,IAAc,OAAQ,CACxB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EACrB,GAAI,CAAC,GAAU,KAAK,CAAC,EAAG,MAAO,sBAC/B,GAAM,CAAC,EAAG,EAAG,GAAK,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,EACzC,OAAO,GAAsB,EAAG,EAAG,CAAC,EAAI,IAAA,GAAY,qBACtD,CAEA,GAAI,IAAc,iBAAkB,CAClC,GAAI,OAAO,GAAU,SAAU,MAAO,sBAEtC,IAAM,EAAO,EAAM,KAAK,CAAC,CAAC,QAAQ,kCAAmC,EAAE,EACjE,EAAS,EAAK,QAAQ,GAAG,EAC/B,GAAI,IAAW,GAAI,MAAO,sBAC1B,IAAM,EAAW,EAAK,MAAM,EAAG,CAAM,EAC/B,EAAW,EAAK,MAAM,EAAS,CAAC,EACtC,GAAI,CAAC,GAAU,KAAK,CAAQ,GAAK,CAAC,GAAU,KAAK,CAAQ,EAAG,MAAO,sBACnE,GAAM,CAAC,EAAG,EAAG,GAAK,EAAS,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,EAEhD,OADK,GAAsB,EAAG,EAAG,CAAC,GAC3B,GAAsB,CAAQ,EAAI,IAAA,GAAY,qBACvD,CAEA,GAAI,IAAc,OAAQ,CACxB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EAErB,OADK,GAAU,KAAK,CAAC,GACd,GAAsB,CAAC,EAAI,IAAA,GAAY,qBAChD,CAEA,GAAI,IAAc,QAAS,CACzB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EACrB,GAAI,CAAC,GAAW,KAAK,CAAC,EAAG,MAAO,sBAChC,IAAM,EAAI,OAAO,EAAE,MAAM,CAAC,CAAC,EAC3B,OAAO,GAAK,GAAK,GAAK,GAAK,IAAA,GAAY,qBACzC,CAEA,GAAI,IAAc,OAAQ,CACxB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EACrB,GAAI,CAAC,GAAU,KAAK,CAAC,EAAG,MAAO,sBAC/B,IAAM,EAAI,OAAO,EAAE,MAAM,CAAC,CAAC,EAC3B,OAAO,GAAK,GAAK,GAAK,GAAK,IAAA,GAAY,qBACzC,CAEA,GAAI,IAAc,QAEhB,OADI,OAAO,GAAU,UACd,GAAW,KAAK,EAAM,KAAK,CAAC,EAAI,IAAA,GAAY,sBAGrD,GAAI,IAAc,MAAO,CACvB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,GAAI,CACF,IAAS,IAAI,EAAM,KAAK,CAAC,EACzB,MACF,MAAQ,CACN,MAAO,qBACT,CACF,CAEA,GAAI,IAAc,QAEhB,OADI,OAAO,GAAU,UACd,GAAW,KAAK,EAAM,KAAK,CAAC,EAAI,IAAA,GAAY,qBAhErD,CAoEF,EAYa,IACX,EACA,IACG,CACH,GAAM,CACJ,OAAQ,EACR,uBACA,0BACA,uBACA,eACA,iBACE,EAEE,EAAiC,CAAC,EAClC,EAA0B,CAC9B,WAAY,EACZ,YAAa,EACb,WAAY,EACZ,aAAc,EACd,YAAa,EACb,cAAe,CACjB,EACM,EAA6D,CAAC,EAE9D,EAAe,GAAkB,CAAY,EAC7C,EAAe,IAAI,IACzB,IAAK,IAAM,KAAK,EACd,EAAa,IAAI,EAAE,KAAM,CAAC,EAE5B,IAAM,EAAkB,EAAa,KAAO,EAEtC,GACJ,EACA,IAC8D,CAC9D,EAAM,cACN,IAAM,EAAQ,EAAK,OACb,EAAuB,EAAc,EAAG,IAAM,IAC9C,EAAiB,EAAmB,EAAI,CAAoB,EAE5D,EAAe,GAAW,CAAoB,EAGhD,EAAG,MACL,EAAY,KAAK,CACf,GAAI,EAAG,IAAM,GACb,OACA,KAAM,QACN,QAAS,iBACT,OAAQ,OACV,CAAC,EACQ,CAAC,GAAkB,IAAyB,IAAA,IACrD,EAAY,KAAK,CACf,GAAI,EAAG,IAAM,GACb,OACA,KAAM,mBACN,QAAS,EAAe,YAAY,EAAa,KAAK,IAAI,IAAM,0BAChE,OAAQ,iBACV,CAAC,EAGH,IAAI,EAAmB,GACnB,EAAY,EACV,EAKA,CAAC,EAEP,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAe,KAAK,CAAI,EACxB,IACA,QACF,CAEA,IAAM,EAAY,CAAC,GAAG,EAAM,CAAS,EAGrC,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,EAAM,CAAS,EAClD,EAAe,QAClB,EAAmB,IAErB,EAAe,KAAK,CAAc,EAClC,IACA,QACF,CAGA,EAAM,aACN,IAAM,EAAa,EAAU,OACvB,CAAC,EAAkB,GAAkB,EAAa,CAAI,EACtD,EACJ,EAAmB,EAAM,EAAkB,CAAc,GACzD,EAAK,QAAU,GACf,EAAK,WAAa,IAChB,IAAyB,IAAA,IAAa,EAAK,QAAU,GAGzD,GACE,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,EAEK,EAIH,EAAM,cAHN,EAAmB,GACnB,EAAM,gBAMR,IAAM,EAAY,EAAK,MAClB,EAAa,KAChB,EAAa,GAAa,CAAE,UAAW,EAAG,aAAc,CAAE,GAE5D,EAAa,EAAU,CAAC,YACnB,GACH,EAAa,EAAU,CAAC,eAG1B,IAAM,EACJ,GAAW,CAAgB,GAAK,GAAyB,EAAM,CAAc,EAEzE,EAAuC,CAC3C,GAAG,EACH,MAAO,EACP,GAAI,EAAc,CAAE,QAAS,CAAY,EAAI,KAC7C,KAAM,EACN,MAAO,CACT,EAEA,EAAe,KAAK,CAAa,EACjC,GACF,CAEA,IAAM,EAAa,GAAkB,EA4BrC,OA1BI,EACF,EAAM,cAEN,EAAM,gBAGJ,EAAgB,CAAE,EASb,CAPL,GAAG,EACH,MAAO,EACP,GAAI,EAAe,CAAE,QAAS,CAAa,EAAI,KAC/C,OACA,QACA,MAAO,CAEG,CAYhB,EAEM,EAAQ,EAAiB,EAAW,CAAC,CAAC,EAG5C,GAAI,EAAiB,CACnB,IAAM,EAAmB,IAAI,IAAI,OAAO,KAAK,CAAY,CAAC,EAC1D,IAAK,GAAM,CAAC,KAAc,EACnB,EAAiB,IAAI,CAAS,GACjC,EAAY,KAAK,CACf,GAAI,GACJ,KAAM,CAAC,EACP,KAAM,qBACN,QAAS,UAAU,EAAU,6DAC7B,OAAQ,aACV,CAAC,CAGP,CAEA,MAAO,CAAE,QAAO,cAAa,QAAO,cAAa,CACnD,EAKM,IACJ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACS,CACT,IAAM,EAAK,EAAK,IAAM,GA2CtB,GAzCI,EAAK,OACP,EAAY,KAAK,CACf,KACA,OACA,KAAM,QACN,QAAS,gBACT,OAAQ,OACV,CAAC,EAGC,EAAK,QAAU,GACjB,EAAY,KAAK,CACf,KACA,OACA,KAAM,oBACN,QAAS,+BACT,OAAQ,aACV,CAAC,EAGC,EAAK,WAAa,GACpB,EAAY,KAAK,CACf,KACA,OACA,KAAM,uBACN,QAAS,kCACT,OAAQ,aACV,CAAC,EAGC,IAAyB,IAAA,IAAa,EAAK,QAAU,GACvD,EAAY,KAAK,CACf,KACA,OACA,KAAM,oBACN,QAAS,+BACT,OAAQ,aACV,CAAC,EAKD,CAAC,EAAK,OACN,EAAK,QAAU,GACf,EAAK,WAAa,IAChB,IAAyB,IAAA,IAAa,EAAK,QAAU,GACvD,CACA,GAAI,OAAO,GAAqB,WAAa,CAAC,EAC5C,EAAY,KAAK,CACf,KACA,OACA,KAAM,mBACN,QAAS,yBACT,OAAQ,iBACV,CAAC,OACI,GACL,OAAO,GAAqB,WAC5B,GAAmB,CAAgB,GACnC,CAAC,EAAiB,MAClB,CACA,IAAM,EAAU,EAAiB,QACjC,EAAY,KAAK,CACf,KACA,OACA,KAAM,mBACN,QAAS,EAAU,YAAY,EAAQ,KAAK,IAAI,IAAM,yBACtD,OAAQ,iBACV,CAAC,CACH,MAAO,GAAI,CAAC,GAAa,OAAO,GAAmB,WAAY,CAC7D,IAAM,EAAK,EAAe,CAAI,EACxB,EACJ,OAAO,GAAO,WAAa,GAAmB,CAAE,GAAK,CAAC,EAAG,MAAQ,EAAG,QAAU,IAAA,GAChF,EAAY,KAAK,CACf,KACA,OACA,KAAM,mBACN,QAAS,EAAU,YAAY,EAAQ,KAAK,IAAI,IAAM,+BACtD,OAAQ,iBACV,CAAC,CACH,CACF,CAcA,GAXI,GAAmB,CAAC,EAAa,IAAI,EAAK,KAAK,GAAK,EAAK,QAAU,GACrE,EAAY,KAAK,CACf,KACA,OACA,KAAM,kBACN,QAAS,UAAU,EAAK,MAAM,uCAC9B,OAAQ,aACV,CAAC,EAIC,EAAiB,CACnB,IAAM,EAAW,EAAa,IAAI,EAAK,KAAK,EAC5C,GAAI,GAAU,UAAW,CACvB,IAAM,EAAe,GAAuB,EAAK,MAAO,EAAS,SAAS,EACtE,GACF,EAAY,KAAK,CACf,KACA,OACA,KAAM,EACN,QAAS,UAAU,EAAK,MAAM,uCAAuC,EAAS,UAAU,GACxF,OAAQ,YACV,CAAC,CAEL,CACF,CACF,EAKM,GACJ,GAEsB,CACtB,GACE,OAAO,GAAqB,WAC5B,GAAmB,CAAgB,GACnC,CAAC,EAAiB,OAClB,EAAiB,QAEjB,OAAO,EAAiB,OAG5B,EAKM,IACJ,EACA,IAEsB,CACtB,GAAI,OAAO,GAAmB,WAAY,CACxC,IAAM,EAAK,EAAe,CAAI,EAC9B,GAAI,OAAO,GAAO,WAAa,GAAmB,CAAE,GAAK,CAAC,EAAG,OAAS,EAAG,QACvE,OAAO,EAAG,OAEd,CAEF,EC7eMC,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAO9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,gBAAiB,EACjC,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAe,IAAgB,QAC/B,EAAa,EAAS,YAAY,EAElC,EAAU,GACV,GAAM,KAAgC,OACtC,OAAO,GAAM,WAAa,OAAO,GAAM,SAAiB,OAAO,CAAC,EAChE,GACA,OAAO,GAAM,UAAY,EAAqB,EAAG,CAAY,EACxD,EAAa,CAAC,EAChB,IAAIA,GAAmB,EAAG,CAAY,EAAE,GAGjD,OAAQ,EAAR,CACE,IAAK,IACH,MAAO,GAAG,EAAM,KAAK,EAAO,CAAK,IACnC,IAAK,KACL,IAAK,KACH,MAAO,GAAG,EAAM,MAAM,EAAO,CAAK,IACpC,IAAK,IACL,IAAK,IACL,IAAK,KACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAAG,EAAO,CAAK,IAC/C,IAAK,WACH,MAAO,GAAG,EAAM,YAAY,EAAO,CAAK,IAC1C,IAAK,iBACH,MAAO,OAAO,EAAM,YAAY,EAAO,CAAK,IAC9C,IAAK,aACH,MAAO,GAAG,EAAM,eAAe,EAAO,CAAK,IAC7C,IAAK,mBACH,MAAO,OAAO,EAAM,eAAe,EAAO,CAAK,IACjD,IAAK,WACH,MAAO,GAAG,EAAM,aAAa,EAAO,CAAK,IAC3C,IAAK,iBACH,MAAO,OAAO,EAAM,aAAa,EAAO,CAAK,IAC/C,IAAK,OACH,MAAO,GAAG,EAAM,UAClB,IAAK,UACH,MAAO,GAAG,EAAM,cAClB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAS,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAGxC,OAFK,EAAO,OAEL,GADQ,IAAe,QAAU,OAAS,KAC9B,EAAM,OAAO,EAAO,KAAK,IAAI,EAAE,GAFvB,EAG7B,CACA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAM,EAAQ,CAAK,EACzB,GAAI,EAAI,OAAS,EAAG,MAAO,GAC3B,GAAM,CAAC,EAAK,GAAQ,CAAC,EAAO,EAAI,EAAE,EAAG,EAAO,EAAI,EAAE,CAAC,EAC7C,EAAO,GAAG,EAAI,MAAM,EAAM,OAAO,EAAM,MAAM,IACnD,OAAO,IAAe,aAAe,QAAQ,EAAK,GAAK,CACzD,CACA,QACE,MAAO,GAAG,EAAM,GAAG,EAAS,GAAG,EAAO,CAAK,GAC/C,CACF,ECzDa,IAA8C,EAAM,IAA8B,CAC7F,IAAM,EAAO,GAA+C,CAAC,EAEvD,CAAE,eAAc,qBAAoB,UAAU,CAAC,GAAM,EACrD,CAAE,UAAS,mBAAkB,gBAAiB,EAMpD,GAAI,CAAC,GAAW,CAAC,EAAkB,OAEnC,GAAM,CACJ,UACA,KACA,KACA,MACA,UACA,YACA,SACA,OACA,KACA,MACA,KACA,aACA,aACA,UACA,OACE,EAEE,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EACJ,GAAgB,uBAAuB,KAAK,CAAK,EAC5C,EAAI,IAAI,CAAK,EACd,EAAQ,GACR,GAAa,EAAG,CAAQ,EAExB,GAAe,IAAgB,QAC/B,GAAkB,GAAwB,GAAe,EAAQ,GAAK,EAGtE,GAAoB,GACpB,IAAgB,CAAC,EAAqB,GAAe,CAAW,EAC7D,EAAqB,EAAG,EAAI,EAAI,EAAY,EAAG,CAAE,aAAc,EAAK,CAAC,EAAI,EAGlF,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAY,EAAiB,CAAI,EAEnC,OAAc,GAEX,IAAI,EAAW,CAEpB,GAAI,EAAK,SAAW,aAAc,OAElC,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,EAAW,EAAe,EAAK,MAAwB,CAC3D,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,CAAkB,EACxD,CAAC,EAEK,EAAoB,GAAiC,EAAU,CACnE,GAAI,EACJ,QAAS,CAAE,GAAG,EAAK,QAAS,aAAc,EAAK,EAC/C,cAAe,EAAgB,CACjC,CAAC,EAED,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,EAAG,gCAAgC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,mBAAmB,EAAO,MAEhK,IAAK,OACH,MAAO,EAAG,oCAAoC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,GAE1I,IAAK,OACH,MAAO,EAAG,gCAAgC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,GAEtI,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAElE,OAAO,EAAY,GAAK,EAAY,EAChC,CAAG,0CAA0C,EAAO,mBAAmB,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,IAAI,EAAI,IAAI,GAAG,EAAG,GAAG,GAAW,IACjM,CAAG,gCAAgC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,IAAI,EAAI,IAAI,GAAG,EAAG,GAAG,GAAW,GACnK,CACF,CACF,CAEA,OAAQ,GAAR,CACE,IAAK,IACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,IACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,IACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAI,EAAQ,GAAiB,CAAK,CAAC,EAC5C,IAAK,KACH,OAAO,EAAI,EAAQ,GAAiB,CAAK,CAAC,EAC5C,IAAK,aACL,IAAK,mBACH,OAAQ,KAAe,mBAAqB,EAAU,EAAA,CACpD,EACA,GAAe,CAAG,GAAG,GAAe,CAAK,EAAE,SAAW,GAAG,EAAM,EACjE,EACF,IAAK,WACL,IAAK,iBACH,OAAQ,KAAe,iBAAmB,EAAU,EAAA,CAClD,EACA,GAAe,CAAG,UAAU,GAAe,CAAK,EAAE,SAAW,IAAI,EAAM,EACzE,EACF,IAAK,WACL,IAAK,iBACH,OAAQ,KAAe,iBAAmB,EAAU,EAAA,CAClD,EACA,GAAe,CAAG,UAAU,GAAe,CAAK,IAAM,IAAI,GAC5D,EACF,IAAK,OACH,OAAO,EAAO,CAAM,EACtB,IAAK,UACH,OAAO,EAAU,CAAM,EACzB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,GAAiB,CAAC,CAAC,EAChE,OAAO,KAAe,QAClB,EAAW,EAAQ,CAAY,EAC/B,EAAQ,EAAQ,CAAY,CAClC,CACA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CAGA,GAAI,CAAC,EAAO,GAAwB,EAG9B,EAAuB,IAAiB,GAC9C,GACE,CAAC,IACD,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,MAEM,KACF,EAAQ,GAAe,CAAK,EAC5B,EAAS,GAAe,CAAM,GAGlC,OAAO,KAAe,aAClB,EAAW,EAAQ,EAAO,CAAM,EAChC,EAAQ,EAAQ,EAAO,CAAM,CACnC,CACA,MACF,CACA,QACE,MACJ,CAxFA,CAyFF,EC7JM,GAAmB,CAAE,IAAK,KAAM,KAAM,MAAO,IAAK,KAAM,KAAM,KAAM,EAKpEC,IACJ,EACA,IAEA,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAC3C,CAAE,KAAM,CAAE,SAAU,CAAkB,CAAE,EACxC,EAEA,GAAY,GAAc,GAAG,QAAQ,UAAW,MAAM,EAEtD,GAA2E,CAC/E,WAAY,aACZ,iBAAkB,aAClB,eAAgB,WAChB,eAAgB,WAChB,SAAU,UACZ,EACM,IAAiB,EAAW,EAAmC,IAAc,CACjF,IAAM,EAAS,QAAQ,EAAE,WAAW,GAAgB,IAAM,EAAE,QAAQ,EAAE,WACtE,OAAO,EAAE,WAAW,GAAG,EAAI,IAAI,IAAW,CAC5C,EAEM,IAAiB,EAAY,IACjC,OAAO,GAAM,UACT,EACA,EAAqB,EAAG,CAAY,EAClC,EAAY,EAAG,CAAE,cAAa,CAAC,EAC/B,EAOK,IACX,EACA,EAAU,CAAC,IACwC,CACnD,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,sBAAuB,EACvC,EAAa,EAAG,CAAQ,EAExB,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,QAAS,EAEX,EAAW,GACf,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,GAAG,EAAM,GAAG,EAAE,QAAU,CAAM,EAC9E,CAAC,EACD,CACF,EAGA,GAAI,OAAO,KAAK,CAAQ,CAAC,CAAC,SAAW,EACnC,MAAO,GAGT,OAAQ,EAAR,CACE,IAAK,OACH,MAAO,CACL,OAAQ,CACN,KAAM,EACN,MAAO,CACT,CACF,EAGF,IAAK,OACH,MAAO,CACL,KAAM,CACJ,SAAU,CACR,OAAQ,CACN,KAAM,EACN,MAAO,CACT,CACF,CACF,CACF,EAIF,IAAK,MAKL,IAAK,UACL,IAAK,SACL,IAAK,UACH,MAAO,EAEX,CACF,CAEA,GAAI,IAAgB,QAAS,CAE3B,GAAI,EAAQ,CAAK,CAAC,CAAC,KAAK,GAAK,OAAO,GAAM,QAAQ,EAAG,MAAO,GAE5D,IAAM,EAAiB,GAAS,CAAK,EAErC,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAoB,IAAe,IAAM,KAAO,EAChD,EAAiB,GAAS,CAAK,EACrC,OAAO,EACH,CACE,KAAM,CACJ,OAAQ,CACN,OAAQ,CACN,OAAQ,QAAQ,EAAe,WAAW,EAAkB,QAAQ,EAAe,SACrF,CACF,CACF,CACF,EACA,EACN,CAEA,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,GAAI,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAM,EAAa,IAAI,IAAM,CACjC,KAAM,CACJ,OAAQ,CAAE,OAAQ,CAAE,OAAQ,QAAQ,EAAe,mBAAmB,EAAE,SAAU,CAAE,CACtF,CACF,EAAE,EACF,MAAO,CAAE,KAAM,IAAe,KAAO,CAAE,OAAQ,CAAI,EAAI,CAAE,SAAU,CAAI,CAAE,CAC3E,CACA,MAAO,EACT,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GAAI,EAAa,QAAU,GAAK,EAAa,IAAM,EAAa,GAAI,CAClE,IAAM,EAAS,QAAQ,EAAe,mBAAmB,EAAa,GAAG,mBAAmB,EAAe,mBAAmB,EAAa,GAAG,UAC9I,MAAO,CACL,KAAM,CACJ,OAAQ,CAAE,OAAQ,CAAE,OAAQ,IAAe,aAAe,KAAK,EAAO,GAAK,CAAO,CAAE,CACtF,CACF,CACF,CACA,MAAO,EACT,CAEA,IAAK,WACL,IAAK,iBACL,IAAK,aACL,IAAK,mBACL,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAiB,GAAS,CAAK,EAGrC,OAFK,EAEE,CACL,KAAM,CACJ,OAAQ,CACN,OAAQ,CACN,OALO,GAAc,EAAgB,EAAY,CAK5C,CACP,CACF,CACF,CACF,EAV4B,EAW9B,CACF,CACF,CAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,CACL,MAAO,EACJ,GAAQ,EACN,GAAiB,IAAc,GAAc,EAAO,CAAY,CACnE,CACF,CACF,EAEF,IAAK,IACH,MAAO,CAAE,KAAM,EAAG,GAAQ,GAAc,EAAO,CAAY,CAAE,CAAE,EAEjE,IAAK,KACH,MAAO,CAAE,KAAM,CAAE,SAAU,CAAE,KAAM,EAAG,GAAQ,GAAc,EAAO,CAAY,CAAE,CAAE,CAAE,CAAE,EAEzF,IAAK,OACH,MAAO,CAAE,KAAM,CAAE,SAAU,CAAE,OAAQ,CAAE,OAAM,CAAE,CAAE,CAAE,EAErD,IAAK,UACH,MAAO,CAAE,OAAQ,CAAE,OAAM,CAAE,EAE7B,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,GAAc,EAAG,CAAY,CAAC,EAC3E,GAAI,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAM,EAAa,IAAI,IAAM,CAAE,KAAM,EAAG,GAAQ,GAAc,EAAG,CAAY,CAAE,CAAE,EAAE,EACzF,MAAO,CAAE,KAAM,IAAe,KAAO,CAAE,OAAQ,CAAI,EAAI,CAAE,SAAU,CAAI,CAAE,CAC3E,CACA,MAAO,EACT,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAI,CAAC,EAAO,GAAU,EAGhB,EAAuB,IAAiB,GAC9C,GACE,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,CACA,OAAOA,GAAc,EAAY,CAAE,MAAO,EAAG,GAAQ,CAAE,IAAK,EAAO,IAAK,CAAO,CAAE,CAAE,CAAC,CACtF,CACA,MAAO,EACT,CAEA,IAAK,WACL,IAAK,iBACH,OAAOA,GAAc,EAAY,CAAE,OAAQ,EAAG,GAAQ,CAAE,MAAO,KAAK,EAAM,GAAI,CAAE,CAAE,CAAC,EAErF,IAAK,aACL,IAAK,mBACH,OAAOA,GAAc,EAAY,CAAE,OAAQ,EAAG,GAAQ,CAAE,MAAO,GAAG,EAAM,GAAI,CAAE,CAAE,CAAC,EAEnF,IAAK,WACL,IAAK,iBACH,OAAOA,GAAc,EAAY,CAAE,OAAQ,EAAG,GAAQ,CAAE,MAAO,KAAK,GAAQ,CAAE,CAAE,CAAC,CACrF,CACA,MAAO,EACT,EC3SM,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAS9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,gBAAiB,EACjC,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAe,IAAgB,QAC/B,EAAa,EAAS,YAAY,EAGlC,EAAO,EAAM,SAAS,GAAG,EAAI,EAAM,MAAM,GAAG,CAAC,CAAC,IAAI,EAAK,EAEvD,EAAU,GACV,GAAM,KAAgC,OACtC,OAAO,GAAM,WAAa,OAAO,GAAM,SAAiB,OAAO,CAAC,EAChE,GACA,OAAO,GAAM,UAAY,EAAqB,EAAG,CAAY,EACxD,EAAa,CAAC,EAChB,IAAI,GAAmB,EAAG,CAAY,EAAE,GAGjD,OAAQ,EAAR,CACE,IAAK,IACH,MAAO,SAAS,EAAK,KAAK,EAAO,CAAK,EAAE,GAC1C,IAAK,KACL,IAAK,KACH,MAAO,SAAS,EAAK,SAAS,EAAO,CAAK,EAAE,IAC9C,IAAK,IACH,MAAO,SAAS,EAAK,QAAQ,EAAO,CAAK,EAAE,IAC7C,IAAK,IACH,MAAO,SAAS,EAAK,QAAQ,EAAO,CAAK,EAAE,IAC7C,IAAK,KACH,MAAO,SAAS,EAAK,SAAS,EAAO,CAAK,EAAE,IAC9C,IAAK,KACH,MAAO,SAAS,EAAK,SAAS,EAAO,CAAK,EAAE,IAC9C,IAAK,WACH,MAAO,SAAS,EAAK,gBAAgB,EAAO,CAAK,EAAE,IACrD,IAAK,iBACH,MAAO,SAAS,EAAK,mBAAmB,EAAO,CAAK,EAAE,IACxD,IAAK,aACH,MAAO,SAAS,EAAK,kBAAkB,EAAO,CAAK,EAAE,IACvD,IAAK,mBACH,MAAO,SAAS,EAAK,qBAAqB,EAAO,CAAK,EAAE,IAC1D,IAAK,WACH,MAAO,SAAS,EAAK,gBAAgB,EAAO,CAAK,EAAE,IACrD,IAAK,iBACH,MAAO,SAAS,EAAK,mBAAmB,EAAO,CAAK,EAAE,IACxD,IAAK,OACH,MAAO,YAAY,EAAK,IAC1B,IAAK,UACH,MAAO,SAAS,EAAK,IACvB,IAAK,KAAM,CACT,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,SAAS,EAAK,YAAY,EAAM,KAAK,IAAI,EAAE,IADxB,EAE5B,CACA,IAAK,QAAS,CACZ,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,SAAS,EAAK,aAAa,EAAM,KAAK,IAAI,EAAE,IADzB,EAE5B,CACA,IAAK,UAAW,CACd,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,SAAS,EAAK,aAAa,EAAO,EAAI,EAAE,EAAE,IAAI,EAAO,EAAI,EAAE,EAAE,GACtE,CACA,IAAK,aAAc,CACjB,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,SAAS,EAAK,aAAa,EAAO,EAAI,EAAE,EAAE,IAAI,EAAO,EAAI,EAAE,EAAE,GACtE,CACA,QACE,MAAO,SAAS,EAAK,KAAK,EAAO,CAAK,EAAE,EAC5C,CACF,ECjFM,GAAgB,GAAe,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAE9E,IAAS,EAAY,IACzB,IAAI,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAAE,GAE3E,IAAU,EAAgB,IAAkB,EAAM,QAAQ,EAAO,GAAK,EAEtE,GAAqB,GACzB,GAAG,IAAI,WAAW,uBAAwB,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,IAAK,OAAO,GAAG,MAAM,EAOhF,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CACJ,eACA,eACA,qBACA,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BAA2B,IACzB,EAEE,EAAe,IAAgB,QAC/B,EACJ,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,OAAO,GAAU,UACjB,EAAqB,EAAO,CAAY,EAEpC,EAAO,GACX,GAAmB,EAAa,CAAE,sBAAqB,0BAAyB,CAAC,EAE7E,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAa,UAAU,EAAI,CAAK,EAAE,GAClC,EAAgB,kBAAkB,EAAI,CAAK,EAAE,kBAAkB,GACnE,EAAe,EAAwB,CACrC,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,MAAM,EAAE,QAAU,IAAK,EACvE,CAAC,EACD,CACF,EAAE,KAEF,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,GAAG,EAAc,KAAK,IAE/B,IAAK,OACH,MAAO,GAAG,EAAc,MAE1B,IAAK,OACH,MAAO,GAAG,EAAc,MAE1B,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAKlE,OAHI,EAAY,GAAK,EAAY,EACxB,GAAG,EAAc,GAAG,EAAG,IAAI,EAAW,KAAK,EAAU,GAEvD,GAAG,EAAc,GAAG,EAAG,GAAG,GACnC,CACF,CACF,CAEA,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,GAAG,EAAI,CAAK,EAAE,GAAG,EAAW,GACjC,EACI,EAAI,EAAa,CAAK,CAAC,EACvB,EACE,EAAa,CAAK,EAClB,GAAM,EAAO,CAAY,IAGnC,IAAK,WACL,IAAK,iBACH,OAAO,GACL,aAAa,EAAI,CAAK,EAAE,IAAI,EAAe,EAAI,EAAa,CAAK,CAAC,EAAI,GAAM,EAAO,CAAY,EAAE,GACjG,GAAa,CAAU,CACzB,EAEF,IAAK,aACL,IAAK,mBACH,OAAO,GACL,EACI,cAAc,EAAI,CAAK,EAAE,eAAe,EAAI,EAAa,CAAK,CAAC,EAAE,OAAO,EAAI,EAAa,CAAK,CAAC,IAC/F,aAAa,EAAI,CAAK,EAAE,MAAM,GAAkB,CAAK,EAAE,IAC3D,GAAa,CAAU,CACzB,EAEF,IAAK,WACL,IAAK,iBACH,OAAO,GACL,EACI,cAAc,EAAI,CAAK,EAAE,YAAY,EAAI,CAAK,EAAE,cAAc,EAAI,EAAa,CAAK,CAAC,EAAE,OAAO,EAAI,EAAa,CAAK,CAAC,IACrH,aAAa,EAAI,CAAK,EAAE,KAAK,GAAkB,CAAK,EAAE,KAC1D,GAAa,CAAU,CACzB,EAEF,IAAK,OACH,MAAO,GAAG,EAAI,CAAK,EAAE,SAEvB,IAAK,UACH,MAAO,GAAG,EAAI,CAAK,EAAE,UAEvB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,GACL,GAAG,EAAI,CAAK,EAAE,OAAO,EAClB,IAAI,GACH,EACI,GAAG,EAAI,EAAa,CAAG,CAAC,IACxB,EAAqB,EAAK,CAAY,EACpC,GAAG,EAAa,CAAG,IACnB,GAAM,EAAK,CAAY,CAC/B,CAAC,CACA,KAAK,IAAI,EAAE,GACd,GAAa,CAAU,CACzB,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,OAAS,GACtB,GAAuB,EAAa,EAAE,GACtC,GAAuB,EAAa,EAAE,EAEtC,MAAO,GAGT,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EACvD,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EACxD,IACA,EAAa,OAAO,MAAM,CAAQ,EAAK,EAAe,GAAG,IAAU,EAAS,EAC5E,EAAc,OAAO,MAAM,CAAS,EAAK,EAAe,GAAG,IAAW,EAAU,EAEpF,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,IAAM,EACJ,EAAqB,EAAO,CAAY,GAAK,EAAqB,EAAQ,CAAY,EAClF,GAAkB,EAAc,IACpC,EAAe,EAAI,CAAG,EAAI,EAAkB,EAAM,GAAM,EAAK,CAAY,EAErE,EAAa,GAAG,EAAI,CAAK,EAAE,MAAM,EAAe,EAAO,CAAU,EAAE,OAAO,EAAI,CAAK,EAAE,MAAM,EAAe,EAAQ,CAAW,IAEnI,OAAO,IAAe,UAAY,IAAI,EAAW,GAAK,GAAO,EAAY,EAAI,CAC/E,CACF,CAEA,MAAO,EACT,ECvLM,GAAmB,GACvB,EACG,QAAQ,QAAS,KAAK,CAAC,CACvB,QAAQ,aAAc,IAAI,CAAC,CAC3B,QAAQ,UAAW,IAAI,EAEtB,IAAiB,EAAY,IACjC,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAAI,CAAE,IAAK,CAAS,EAAI,EAO5D,IAAgD,EAAM,EAAU,CAAC,IAAoB,CAChG,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,sBAAuB,EACvC,EAAe,IAAgB,QAC/B,EAA4B,CAAE,IAAK,CAAM,EACzC,EAAyB,GAC7B,EACI,CAAE,IAAK,GAAG,GAAI,EACd,EAAqB,EAAG,CAAY,EAClC,EAAY,EAAG,CAAE,cAAa,CAAC,EAC/B,EAEF,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAE5B,OAAQ,EAAR,CACE,IAAK,MACL,IAAK,OACL,IAAK,OACH,MAAO,EACJ,GAAO,CACN,CAAE,IAAK,CAAM,EACb,EAAM,MAAM,SAAW,GAAK,CAAC,EAAY,EAAM,MAAM,EAAE,EACnD,GAA8B,EAAM,MAAM,GAAI,CAAO,EACrD,GAAmC,EAAO,CAAkC,CAClF,CACF,EAEF,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,KAE5D,EAAgB,CACpB,OAAQ,CACN,CACE,OAAQ,CACN,CAAE,IAAK,CAAM,EACb,EAAM,MAAM,SAAW,GAAK,CAAC,EAAY,EAAM,MAAM,EAAE,EACnD,GAA8B,EAAM,MAAM,GAAI,CAAO,EACrD,GAAmC,EAAO,CAAkC,CAClF,CACF,EACA,CAAE,IAAK,CAAC,EAAG,CAAE,IAAK,aAAc,CAAC,CAAE,EACnC,CACF,CACF,EAEA,GAAI,EAAY,GAAK,EAAY,EAAG,CAClC,IAAM,EAAa,CACjB,OAAQ,CAAC,CAAE,IAAK,CAAM,EAAG,CAAE,IAAK,CAAC,EAAG,CAAE,IAAK,aAAc,CAAC,CAAE,EAAG,CAAC,CAClE,EACA,MAAO,EAAG,GAAK,CAAC,EAAe,CAAE,IAAK,CAAC,EAAY,CAAS,CAAE,CAAC,CAAE,CACnE,CACA,MAAO,EAAG,GAAK,CAAC,EAAe,CAAS,CAAE,CAC5C,CACF,CACF,CAEA,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,EACJ,GAAgB,CAAU,GAAI,CAAC,EAAa,EAAsB,CAAK,CAAC,CAC3E,EAEF,IAAK,OACL,IAAK,UACH,MAAO,EACJ,GAAG,IAAe,UAAY,IAAM,IAAI,IAAK,CAAC,EAAa,IAAI,CAClE,EAGF,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,EAAsB,CAAC,CAAC,EACrE,OAAO,GAAc,EAAY,CAAE,GAAI,CAAC,EAAa,CAAY,CAAE,CAAC,CACtE,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CAEA,GAAI,CAAC,EAAO,GAAwB,EAG9B,EAAuB,IAAiB,GAC9C,GACE,CAAC,GACD,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,MAAW,IACT,EAAQ,CAAE,IAAK,CAAM,EACrB,EAAS,CAAE,IAAK,CAAO,GAGzB,OAAO,GAAc,EAAY,CADA,KAAM,CAAC,EAAO,EAAa,CAAM,CAC1B,CAAC,CAC3C,CACA,MAAO,EACT,CAEA,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAyB,CAC7B,GAAI,CAAC,EAAsB,CAAK,EAAG,CAAW,CAChD,EACA,OAAO,GAAc,EAAY,CAAQ,CAC3C,CAEA,IAAK,aACL,IAAK,mBAAoB,CACvB,IAAM,EAAyB,CAC7B,WAAY,CAAC,EAAa,EAAsB,CAAK,CAAC,CACxD,EACA,OAAO,GAAc,EAAY,CAAQ,CAC3C,CAEA,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAyB,CAC7B,SAAU,CAAC,EAAa,EAAsB,CAAK,CAAC,CACtD,EACA,OAAO,GAAc,EAAY,CAAQ,CAC3C,CACF,CACA,MAAO,EACT,EC5KM,IAAY,EAAgB,IAAqB,EAAS,KAAK,EAAO,GAAK,GAAG,IAE9E,GAAc,GAClB,GAAG,EAAa,CAAC,IAAI,WACnB,kBACC,GAAc,KAAK,EAAE,YAAY,CAAC,CAAC,CAAE,SAAS,EAAE,GACnD,EAOW,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,sBAAuB,EACzB,EAAa,EAAG,CAAQ,EAG9B,GAEE,IAAgB,SAEf,GAAuB,CAAK,GAAK,IAAe,QAAU,IAAe,WAE1E,EAAiB,CAAI,EAErB,MAAO,GAGT,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACH,OAAO,GAAS,IAAI,EAAM,GAAG,GAAW,CAAK,EAAE,GAAI,IAAe,IAAI,EAExE,IAAK,IACL,IAAK,KACH,MAAO,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,GAEzC,IAAK,IACL,IAAK,KACH,MAAO,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,GAEzC,IAAK,WACL,IAAK,iBACH,OAAO,GAAS,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,IAAK,IAAe,gBAAgB,EAEtF,IAAK,aACL,IAAK,mBACH,OAAO,GAAS,IAAI,EAAM,GAAG,GAAW,CAAK,EAAE,IAAK,IAAe,kBAAkB,EAEvF,IAAK,WACL,IAAK,iBACH,OAAO,GAAS,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,GAAI,IAAe,gBAAgB,EAErF,IAAK,OACL,IAAK,UACH,OAAO,GAAS,IAAI,EAAM,KAAM,IAAe,SAAS,EAE1D,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,GACL,KAAK,EAAa,IAAI,GAAO,IAAI,EAAM,GAAG,GAAW,CAAG,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,GACvE,IAAe,OACjB,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,OAAS,GACtB,GAAuB,EAAa,EAAE,GACtC,GAAuB,EAAa,EAAE,EAEtC,MAAO,GAGT,GAAM,CAAC,EAAO,GAAU,EAClB,EAAW,EAAqB,EAAO,EAAI,EAC7C,EAAY,EAAO,CAAE,aAAc,EAAK,CAAC,EACzC,IACE,EAAY,EAAqB,EAAQ,EAAI,EAC/C,EAAY,EAAQ,CAAE,aAAc,EAAK,CAAC,EAC1C,IACA,EAAa,OAAO,MAAM,CAAQ,EAAI,EAAQ,EAC9C,EAAc,OAAO,MAAM,CAAS,EAAI,EAAS,EAErD,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,OAAO,GACL,MAAM,EAAM,IAAI,GAAW,CAAU,EAAE,IAAI,EAAM,IAAI,GAAW,CAAW,EAAE,IAC7E,IAAe,YACjB,CACF,CACF,CAGA,MAAO,EACT,EChHM,IAA2B,EAAY,EAAmB,IAC9D,GAAgB,OAAO,GAAM,SACzB,EAAE,WAAW,GAAG,IAAa,GAAG,IAAY,GAAW,EACrB,EAO3B,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CACJ,eACA,SACA,eACA,sBACA,kBACA,2BACA,gBACE,EACE,EAAe,EAAK,cAAgB,QACpC,EAAoB,EAAG,EAAK,QAAQ,EACpC,EACJ,GAAsD,IAElD,EAAc,GAAe,GAAG,IAAY,IAAI,IAChD,EAAe,GAAe,GAAwB,EAAG,EAAW,CAAY,EAChF,EAAiB,GAAe,EAAW,EAAY,CAAC,CAAC,EACzD,EAAiB,GACrB,GAAmB,EAAG,CAAE,sBAAqB,0BAAyB,CAAC,EAEnE,EAAI,GAAmD,CAAC,EACxD,EAAO,EAAE,IAAM,KACf,EAAS,EAAE,MAAQ,OACnB,EAAU,EAAE,OAAS,QACrB,EAAU,EAAE,eAAiB,KAC7B,EAAiB,CAAC,EAAE,cAE1B,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,UACH,MAAO,GAGT,IAAK,UACL,IAAK,aAAc,CACjB,GAAI,CAAC,EACH,OAAO,GAA4B,EAAM,CAAI,EAG/C,IAAM,EAAe,EAAQ,EAAK,MAAO,CAAE,mBAAoB,EAAK,CAAC,CAAC,CACnE,MAAM,EAAG,CAAC,CAAC,CACX,IAAI,GACH,EACE,EACG,GACoC,CAAC,EACtC,CACF,CAAC,EAAE,OAAS,CACd,CACF,EAQF,OANE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAEtB,GAEF,GAA4B,CAAE,GAAG,EAAM,MAAO,CAAa,EAAG,CAAI,CAC3E,CAEA,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,EAAK,KAAK,EACvC,GAAI,EAAa,SAAW,EAAG,MAAO,GACtC,IAAM,EAAiB,EAAa,IAAI,GACtC,EACI,EACE,EACG,GACoC,CAAC,EACtC,CACF,CAAC,EAAE,OAAS,CACd,EACA,EAAqB,EAAG,CAAY,EAClC,GAAG,EAAa,CAAC,IACjB,GAAG,EAAc,CAAC,GAC1B,EACA,GAAI,EAAe,SAAW,EAC5B,OAAO,EAAe,GAExB,IAAM,EAAc,GAAkB,EAAe,OAAS,EAAI,IAAM,GAExE,MAAO,IAAI,GADK,EAAe,MAAM,EAAG,EAAE,CAAC,CAAC,KAAK,CAAO,IAAI,EAAY,GAAG,EAAK,GAAG,EAAe,GAAG,EAAE,IACvF,EAClB,CACF,CAMA,OAJI,OAAO,EAAK,OAAU,UACjB,EAAK,MAAQ,EAAS,EAGxB,EACH,EACE,EACG,GACoC,CAAC,EACtC,EAAK,KACP,CAAC,EAAE,OAAS,EAAK,KACnB,EACA,EAAqB,EAAK,MAAO,CAAY,EAC3C,GAAG,EAAa,EAAK,KAAK,IAC1B,GAAG,EAAc,EAAK,KAAK,GACnC,ECxGa,GAA8C,CACzD,IAAK,CAAC,KAAM,6BAA6B,EACzC,KAAM,CAAC,SAAU,iCAAiC,EAClD,IAAK,CAAC,eAAgB,2BAA2B,EACjD,IAAK,CAAC,kBAAmB,8BAA8B,EACvD,KAAM,CAAC,2BAA4B,uCAAuC,EAC1E,KAAM,CAAC,8BAA+B,0CAA0C,EAChF,SAAU,CAAC,WAAY,uBAAuB,EAC9C,WAAY,CAAC,cAAe,0BAA0B,EACtD,SAAU,CAAC,YAAa,wBAAwB,EAChD,eAAgB,CAAC,mBAAoB,+BAA+B,EACpE,iBAAkB,CAAC,sBAAuB,kCAAkC,EAC5E,eAAgB,CAAC,oBAAqB,gCAAgC,EACtE,KAAM,UACN,QAAS,cACT,GAAI,CAAC,uBAAwB,2BAA2B,EACxD,MAAO,CAAC,2BAA4B,iCAAiC,EACrE,QAAS,CAAC,aAAc,0BAA0B,EAClD,WAAY,CAAC,iBAAkB,8BAA8B,CAC/D,EAGM,OAA4B,CAAC,EAOtB,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,QAAO,WAAU,cAAc,SAAY,EAE7C,CACJ,eAAe,GACf,YAAa,EAAmB,IAC9B,EAGE,EAAoB,IAAI,IAC5B,OAAO,QAAQ,EAAwB,CACzC,EACA,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAgB,EACxD,EAAkB,IAAI,EAAG,CAAG,EAAG,CAAK,EAEtC,IAAM,EAAc,OAAO,YAAY,CAAiB,EAGlD,EAAa,EAAG,CAAQ,EAE9B,IAAI,EAAqB,EAEzB,IAAM,EAAiB,EAAQ,EAAK,KAAK,CAAC,CAAC,SAAW,EAElD,IAAe,MAAQ,EACzB,EAAqB,IACZ,IAAe,SAAW,IACnC,EAAqB,MAGvB,GAAM,CAAE,MAAO,EAAY,SAAU,EACnC,EACE,EAAa,EAAO,CAClB,UAAW,EAAK,WAAa,CAC3B,KAAM,EACN,MAAO,EACP,MAAO,CACT,CACF,CAAC,GAAwC,CAAC,CAC5C,EACA,CACF,GAAK,CACH,KAAM,EACN,MAAO,EACP,MAAO,CACT,EAGM,EAAa,EAAY,IAC7B,EAAY,EAAG,CAAU,IAAwC,CAAC,EAAO,CAAK,EAGhF,OAAO,OAAO,GAAe,SAAW,EAAa,EAAW,MAAgB,SAClF,EAOa,IAAyC,EAAM,IAAS,CACnE,GAAM,CAAE,QAAO,YAAa,EAEtB,CACJ,YACA,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BAA2B,GAC3B,kBAAkB,IAClB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,KACjB,YAAY,OACV,GAA2C,CAAC,EAE1C,EAAiB,GAAmB,GAAW,OAAS,EAAO,CACnE,sBACA,0BACF,CAAC,EAEK,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAoB,GAA4B,EAAK,MAAO,CAChE,GAAI,EACJ,OAAQ,EAAiB,GAAW,eAAiB,CAAC,CAAC,CACzD,CAAC,EAGK,GAAO,GAAW,eAAe,QAAU,GAAK,EAEtD,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,IAAI,EAAM,OAAS,GAAG,gBAAgB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAEpG,IAAK,OACH,MAAO,IAAI,EAAM,OAAS,GAAG,aAAa,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAEjG,IAAK,OACH,MAAO,IAAI,EAAM,OAAS,GAAG,uBAAuB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAE3G,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,EAAK,QAAQ,KAAM,KAAK,EAInC,OAHI,EAAY,GAAK,EAAY,EACxB,IAAI,EAAM,OAAS,KAAK,EAAG,GAAG,EAAY,IAAI,oBAAoB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAEzH,IAAI,EAAM,OAAS,KAAK,EAAG,GAAG,EAAU,mBAAmB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,EACzH,CACF,CACF,CAEA,IAAM,EAAQ,EAAe,EAAM,CACjC,GAAG,EACH,sBACA,2BACA,kBACA,gBACF,CAAC,EAEK,EAAa,EAAG,CAAQ,EAC9B,IACG,IAAe,MACd,IAAe,SACf,IAAe,WACf,IAAe,eACjB,CAAC,EAED,MAAO,GAKT,IAAM,EAAe,CACnB,EAAG,EACH,EAJwB,EAAkB,EAAM,CAI7B,EACnB,EAAG,CACL,EAEM,EAAe,GAAM,cAAgB,CAAC,EACtC,EAAoC,CACxC,EAAG,EAAa,cAAgB,IAChC,EAAG,EAAa,WAAa,IAC7B,EAAG,EAAa,aAAe,GACjC,EAEM,EAAiB,GAA8B,CAAS,CAAC,CAAC,OAC9D,GAAQ,EAAa,KAAU,EACjC,EACA,OAAO,EACJ,KACE,EAAM,IAAM,GAAG,EAAa,KAAQ,EAAI,EAAe,OAAS,EAAI,EAAU,GAAQ,IACzF,CAAC,CACA,KAAK,EAAE,CAAC,CACR,KAAK,CACV,EClMa,GAA6C,GAAQ,EAAG,GAAe,EAAK,QAAQ,CAAC,EAOrF,IAA0C,EAAM,EAAO,CAAC,IAAM,CACzE,GAAM,CACJ,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BAA2B,GAC3B,kBAAkB,IAClB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,MACf,EAEE,EAAiB,GACrB,GAAmB,EAAG,CAAE,sBAAqB,0BAAyB,CAAC,EAEnE,EAAY,EAAc,EAAK,KAAK,EAEpC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CAEpB,GAAI,GAAM,SAAW,aAAc,MAAO,GAE1C,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,EAAoB,GACxB,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,CAAkB,EACxD,CAAC,EACD,CAAE,GAAI,EAAkC,cAAe,EAAgB,CAAE,CAC3E,EAEA,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,mBAAmB,EAAU,MAEnJ,IAAK,OACH,MAAO,oCAAoC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,GAE1H,IAAK,OACH,MAAO,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,GAEtH,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAElE,MAAO,mBAAmB,EAAY,GAAK,EAAY,EAAI,0BAA0B,EAAU,MAAQ,GAAG,eAAe,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,IAAI,EAAG,GAAG,GAClN,CACF,CACF,CAEA,IAAM,EAAQ,EAAe,EAAM,CACjC,GAAG,EACH,sBACA,2BACA,kBACA,gBACF,CAAC,EAEK,EAAW,EAAkB,EAAM,CAAI,EAEvC,EAAoB,EAAG,CAAQ,EAWrC,OATG,IAAsB,MACrB,IAAsB,UACtB,IAAsB,WACtB,IAAsB,gBACxB,CAAC,EAEM,GAGF,GAAG,EAAU,GAAG,EAAS,GAAG,IAAQ,KAAK,CAClD,EC7Ea,IAAoD,EAAM,EAAM,IAAS,CAEpF,GAAM,CACJ,YACA,SACA,oBACA,eACA,cACA,mBACA,iBACA,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BACA,iBACA,oBAAoB,GACpB,iBAAiB,IACf,GAAQ,CAAC,EAEP,CAAE,kBAAkB,CAAC,GAAM,GAAQ,CAAC,EAEpC,EAAgB,IAAW,gBAE3B,EAAgB,CAAC,EAEjB,EAAmC,CAAC,EAEpC,EAAY,GAChB,EAAgB,CAAE,MAAK,QAAO,EAAI,CAAE,MAAK,OAAQ,CAAY,EAEzD,EAAiB,GACrB,GAAmB,EAAG,CAAE,sBAAqB,0BAAyB,CAAC,EAEnE,EAAY,EAAc,EAAK,KAAK,EAEpC,EAAY,EAAiB,CAAI,EAGvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CAEpB,GAAI,GAAM,SAAW,aAAc,OAAO,EAAS,EAAE,EAErD,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,CAAE,IAAK,EAAW,OAAQ,GAAiB,GAC/C,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,CAAkB,EACxD,CAAC,EACD,CACE,GAAI,EACJ,OAAQ,CAAC,EACT,cAAe,EAAgB,CACjC,CACF,EAQA,OANI,MAAM,QAAQ,CAAY,EAC5B,EAAO,KAAK,GAAG,CAAY,EAE3B,OAAO,OAAO,EAAa,CAAY,EAGjC,EAAR,CACE,IAAK,MACH,OAAO,EACL,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,mBAAmB,EAAU,KACpI,EAEF,IAAK,OACH,OAAO,EACL,oCAAoC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,EAC3G,EAEF,IAAK,OACH,OAAO,EACL,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,EACvG,EAEF,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAElE,OAAO,EACL,mBAAmB,EAAY,GAAK,EAAY,EAAI,0BAA0B,EAAU,MAAQ,GAAG,eAAe,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,IAAI,EAAG,GAAG,GACnM,CACF,CACF,CACF,CAGA,IAAM,EAAQ,EAAe,EAAM,CACjC,eACA,sBACA,iBACA,YACA,QACF,CAAC,EAEK,EAAc,EAAkB,EAAM,CAAI,EAC1C,EAAuB,EAAG,CAAW,EACrC,CAAC,EAAM,GAAS,EAEtB,IACG,IAAyB,MACxB,IAAyB,UACzB,IAAyB,WACzB,IAAyB,gBAC3B,CAAC,EAED,OAAO,EAAS,EAAE,EACb,GAAI,IAAyB,WAAa,IAAyB,cACxE,OAAO,EAAS,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,GAAa,EACxD,GAAI,EAAK,cAAgB,YAAa,CAM3C,IAAM,EAAiB,GAAe,CACpC,IAAM,EAAM,GAAgB,EAAG,CAAW,EAI1C,OAHK,IACH,EAAY,EAAmB,EAAM,GAAiB,EAAG,CAAW,GAAK,MAEpE,CACT,EACA,GAAI,IAAyB,WAAa,IAAyB,cAAe,CAEhF,GAAM,CAAC,EAAO,GADO,EAAQ,EAAK,MAAO,CAAE,mBAAoB,EAAK,CACjC,CAAC,CAAC,MAAM,EAAG,CAAC,EAC/C,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,EAAc,CAAK,EAAE,OAAO,EAAc,CAAM,IAAI,KAAK,CAC1G,CACF,CACA,GAAI,IAAyB,MAAQ,IAAyB,SAAU,CACtE,IAAM,EAAa,EAAQ,EAAK,KAAK,EACrC,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,IAAI,EAAW,IAAI,GAAK,EAAc,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EACnG,CACF,CAGA,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,GAAiB,EAAc,EAAK,KAAK,EAAG,EAAG,EAAK,QAAQ,EAAG,CAAE,gBAAe,CAAC,IAAI,KAAK,CAC3I,CACF,CAAO,GAAI,EAAK,cAAgB,QAC9B,OAAO,EAAS,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,IAAQ,KAAK,CAAC,EACxE,GAAI,IAAyB,MAAQ,IAAyB,SAAU,CAC7E,IAAM,EAAa,EAAQ,EAAK,KAAK,EACrC,GAAI,EAAe,CACjB,IAAK,IAAM,KAAK,EACd,EAAO,KAAK,EAAqB,EAAG,CAAY,EAAI,EAAY,EAAG,CAAE,cAAa,CAAC,EAAI,CAAC,EAE1F,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,IAAI,EAC7C,KAAK,EAAI,IACR,EACI,GAAG,IAAc,EAAgB,OAAS,EAAI,EAAW,QAAU,EAAW,OAAS,KACvF,GACN,CAAC,CACA,KAAK,IAAI,EAAE,EAChB,CACF,CACA,IAAM,EAAqB,CAAC,EAC5B,IAAK,IAAM,KAAK,EAAY,CAC1B,IAAM,EAAgB,EAAmB,EAAK,KAAK,EACnD,EAAS,KAAK,GAAG,IAAc,GAAe,EAC9C,EAAY,GAAG,EAAmB,EAAc,KAAK,KAAmB,EACtE,EACA,CACF,EACI,EAAY,EAAG,CAAE,cAAa,CAAC,EAC/B,CACN,CACA,OAAO,EAAS,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,IAAI,EAAS,KAAK,IAAI,EAAE,EAAE,CACxF,CAAO,GAAI,IAAyB,WAAa,IAAyB,cAAe,CAEvF,GAAM,CAAC,EAAO,GADO,EAAQ,EAAK,MAAO,CAAE,mBAAoB,EAAK,CACjC,CAAC,CACjC,MAAM,EAAG,CAAC,CAAC,CACX,IAAI,GAAM,EAAqB,EAAG,CAAY,EAAI,EAAY,EAAG,CAAE,cAAa,CAAC,EAAI,CAAE,EAC1F,GAAI,EAEF,OADA,EAAO,KAAK,EAAO,CAAM,EAClB,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAC1C,EAAiB,GAAG,IAAc,EAAgB,OAAS,IAAM,IAClE,OAAO,EAAiB,GAAG,IAAc,EAAgB,OAAS,IAAM,KAC3E,EAEF,IAAM,EAAiB,EAAmB,EAAK,KAAK,EAC9C,EAAkB,EAAmB,EAAK,KAAK,EAGrD,MAFA,GAAY,GAAG,EAAmB,EAAc,KAAK,KAAoB,EACzE,EAAY,GAAG,EAAmB,EAAc,KAAK,KAAqB,EACnE,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,IAAc,EAAe,OAAO,IAAc,GACnG,CACF,CAEA,IAAI,EAAa,EAAK,MAClB,OAAO,EAAK,OAAU,WACxB,AAKE,EALE,EAAqB,EAAK,MAAO,CAAY,EAClC,EAAY,EAAK,MAAO,CAAE,cAAa,CAAC,EAIxC,UAAU,KAAK,CAAK,EAC7B,EAAM,WAAW,WAAY,EAAE,EACG,GAI1C,IAAI,GAAY,GAQhB,OAPI,EACF,EAAO,KAAK,CAAU,GAEtB,GAAY,EAAmB,EAAK,KAAK,EACzC,EAAY,GAAG,EAAmB,EAAc,KAAK,MAAe,GAG/D,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAC1C,EACI,EACE,GAAG,IAAc,EAAgB,OAAS,IAC1C,IACF,GAAG,IAAc,OACpB,KAAK,CACV,CACF,ECtPM,IAAoB,EAAgB,EAAa,IACrD,EAAqB,EAAO,CAAC,CAAC,GAAgB,OAAO,GAAU,QAAQ,EACnE,OAAO,EAAY,EAAO,CAAE,aAAc,CAAC,CAAC,CAAa,CAAC,CAAC,EAC3D,EAOO,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAE1C,CAAE,eAAc,sBAAuB,EAG7C,GAAI,IAAgB,SAAW,EAAiB,CAAI,EAAG,OAEvD,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACH,MAAO,EAAG,GAAQ,GAAc,EAAO,EAAO,CAAY,CAAE,EAE9D,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAiB,GAAgB,GACvC,MAAO,EACJ,GAAQ,EACN,GAAiB,GAAc,EAAO,EAAO,CAAY,CAC5D,CACF,CACF,CAEA,IAAK,WACH,MAAO,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,EAExC,IAAK,aACH,MAAO,EAAG,GAAQ,CAAE,WAAY,CAAM,CAAE,EAE1C,IAAK,WACH,MAAO,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,EAExC,IAAK,iBACH,MAAO,CAAE,IAAK,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,CAAE,EAEjD,IAAK,mBACH,MAAO,CAAE,IAAK,EAAG,GAAQ,CAAE,WAAY,CAAM,CAAE,CAAE,EAEnD,IAAK,iBACH,MAAO,CAAE,IAAK,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,CAAE,EAEjD,IAAK,OACH,MAAO,EAAG,GAAQ,IAAK,EAEzB,IAAK,UACH,MAAO,EAAG,GAAQ,CAAE,IAAK,IAAK,CAAE,EAElC,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,MAAO,EACJ,GAAQ,EACN,GAAgB,IAAc,EAAa,IAAI,GAC9C,GAAc,EAAK,EAAK,CAAY,CACtC,CACF,CACF,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,cAAa,CAAC,EACnC,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,cAAa,CAAC,EACpC,IACA,EAAa,OAAO,MAAM,CAAQ,EAAI,EAAQ,EAC9C,EAAc,OAAO,MAAM,CAAS,EAAI,EAAS,EACrD,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,OAAO,IAAe,UAClB,EAAG,GAAQ,CAAE,IAAK,EAAY,IAAK,CAAY,CAAE,EACjD,CAAE,GAAI,CAAC,EAAG,GAAQ,CAAE,GAAI,CAAW,CAAE,EAAG,EAAG,GAAQ,CAAE,GAAI,CAAY,CAAE,CAAC,CAAE,CAChF,CACE,MAAO,EAEX,CACF,CACA,MAAO,EACT,ECzGa,IACX,EAEA,CAAE,eAAc,qBAAoB,UAAU,CAAC,GAAM,CAAC,IACd,CACxC,GAAM,CACJ,mBAAoB,EACpB,aAAc,EACd,YAAa,GACX,EAOJ,GAAI,EAAiB,CAAI,EAAG,OAE5B,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAe,IAAgB,QAE/B,EAAa,EAAG,CAAQ,EAI5B,MAAC,GAEA,IACE,CAAC,GAGC,CAAC,GACA,CACE,WACA,iBACA,aACA,mBACA,WACA,gBACF,CAAC,CAAC,SAAS,CAAU,IAK7B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAoB,CACxB,IAAK,EAAG,GACR,KAAM,EAAG,GACT,IAAK,EAAG,GACR,KAAM,EAAG,IACT,IAAK,EAAG,GACR,KAAM,EAAG,GACX,EAAE,GACF,MAAO,EACJ,GACC,GAAgB,IAAe,IAC3B,EAAG,EAAG,KAAM,CAAM,EAClB,EACG,GAAoB,EACjB,EAAK,CAAK,EACV,EAAqB,EAAO,CAAY,EACtC,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,EAC7C,CACR,CACR,CACF,CAEA,IAAK,WACH,MAAO,EACJ,GAAQ,EACN,EAAe,EAAG,KAAO,EAAG,WAAY,EACrC,EAAI,SAAU,IAAK,EAAK,CAAK,EAAG,GAAG,EACnC,GAAG,GACT,CACF,EAEF,IAAK,aACH,MAAO,EACJ,GAAQ,EACN,EAAe,EAAG,KAAO,EAAG,YAAa,EACtC,EAAI,SAAU,EAAK,CAAK,EAAG,GAAG,EAC9B,GAAG,GACT,CACF,EAEF,IAAK,WACH,MAAO,EACJ,GAAQ,EACN,EAAe,EAAG,KAAO,EAAG,UAAW,EACpC,EAAI,SAAU,IAAK,EAAK,CAAK,CAAC,EAC9B,GAAG,GACT,CACF,EAEF,IAAK,iBACH,MAAO,EACJ,GAAQ,EACN,EAAG,SAAU,EAAe,EAAI,SAAU,IAAK,EAAK,CAAK,EAAG,GAAG,EAAI,IAAI,EAAM,EAChF,CACF,EAEF,IAAK,mBACH,MAAO,EACJ,GAAQ,EAAG,EAAG,SAAU,EAAe,EAAI,SAAU,EAAK,CAAK,EAAG,GAAG,EAAI,GAAG,EAAM,EAAG,CACxF,EAEF,IAAK,iBACH,MAAO,EACJ,GAAQ,EAAG,EAAG,SAAU,EAAe,EAAI,SAAU,IAAK,EAAK,CAAK,CAAC,EAAI,IAAI,GAAQ,CACxF,EAEF,IAAK,OACH,MAAO,EAAG,GAAQ,EAAG,EAAG,IAAK,IAAK,CAAE,EAEtC,IAAK,UACH,MAAO,EAAG,GAAQ,EAAG,EAAG,KAAM,IAAK,CAAE,EAEvC,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,MAAO,EACJ,GAAQ,EACN,IAAe,KAAO,EAAG,GAAK,EAAG,OAAQ,EAAa,IAAI,GACzD,EACI,EAAK,CAAG,EACR,EAAqB,EAAK,CAAY,EACpC,EAAY,EAAK,CAAE,aAAc,QAAS,CAAC,EAC3C,CACR,CACF,CACF,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,EAChE,GACE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAE7B,OAGF,GAAM,CAAC,EAAO,GAAU,EAElB,EAAW,EAAqB,EAAO,CAAY,EACrD,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,EAC7C,IACE,EAAY,EAAqB,EAAQ,CAAY,EACvD,EAAY,EAAQ,CAAE,aAAc,QAAS,CAAC,EAC9C,IACE,EAAa,OAAO,MAAM,CAAQ,EAAI,EAAQ,EAC9C,EAAc,OAAO,MAAM,CAAS,EAAI,EAAS,EACjD,EAAoB,CAAC,EAAY,CAAW,EAWlD,MATE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,IAEZ,EAAkB,GAAK,EACvB,EAAkB,GAAK,GAGlB,EACJ,GAAQ,EACN,IAAe,UAAY,EAAG,QAAU,EAAG,YAAa,EACrD,EAAkB,IAAI,GAAK,EAAK,CAAC,CAAC,EAClC,EAAkB,MAAM,GAAK,EAAqB,EAAG,CAAY,CAAC,EAChE,EAAkB,IAAI,GAAK,EAAY,EAAG,CAAE,aAAc,QAAS,CAAC,CAAC,EACrE,CACR,CACF,CACF,CACF,CAEF,ECpMM,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAM9D,GAAa,GACxB,QAAQ,KAAK,CAAI,GAAK,EAAK,SAAS,GAAG,EAAI,EAAO,IAAI,IAO3C,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,gBAAiB,EACjC,CAAE,MAAO,EAAU,WAAU,QAAO,eAAgB,EACpD,EAAe,IAAgB,QAC/B,EAAa,EAAS,YAAY,EAClC,EAAQ,GAAU,CAAQ,EAE1B,EAAU,GAAuB,CACrC,GAAI,GAAM,KAAyB,MAAO,KAC1C,GAAI,OAAO,GAAM,UAAW,MAAO,IAAI,EAAE,gBACzC,GAAI,OAAO,GAAM,SAAU,OAAO,OAAO,CAAC,EAC1C,GAAI,EAAc,OAAO,GAAU,EAAa,CAAC,CAAW,EAC5D,GAAI,OAAO,GAAM,UAAY,EAAqB,EAAG,CAAY,EAC/D,OAAO,EAAa,CAAC,EAEvB,IAAM,EAAI,OAAO,GAAM,SAAW,EAAK,KAAK,UAAU,CAAC,GAAK,GAI5D,OADI,EAAE,WAAW,GAAG,GAAK,EAAE,WAAW,GAAG,GAAK,EAAE,SAAS,GAAG,EAAU,EAC/D,IAAI,GAAmB,EAAG,CAAY,EAAE,EACjD,EAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,IACL,IAAK,KACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAAG,EAAO,CAAK,IAC/C,IAAK,KACH,MAAO,GAAG,EAAM,MAAM,EAAO,CAAK,IACpC,IAAK,WACH,MAAO,YAAY,EAAM,IAAI,EAAO,CAAK,EAAE,GAC7C,IAAK,iBACH,MAAO,aAAa,EAAM,IAAI,EAAO,CAAK,EAAE,GAC9C,IAAK,aACH,MAAO,aAAa,EAAM,IAAI,EAAO,CAAK,EAAE,GAC9C,IAAK,mBACH,MAAO,cAAc,EAAM,IAAI,EAAO,CAAK,EAAE,GAC/C,IAAK,WACH,MAAO,WAAW,EAAM,IAAI,EAAO,CAAK,EAAE,GAC5C,IAAK,iBACH,MAAO,YAAY,EAAM,IAAI,EAAO,CAAK,EAAE,GAC7C,IAAK,OACH,MAAO,UAAU,EAAM,GACzB,IAAK,UACH,MAAO,SAAS,EAAM,GACxB,IAAK,KAAM,CACT,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,GAAG,EAAM,OAAO,EAAM,KAAK,IAAI,EAAE,GADd,EAE5B,CACA,IAAK,QAAS,CACZ,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,GAAG,EAAM,WAAW,EAAM,KAAK,IAAI,EAAE,GADlB,EAE5B,CACA,IAAK,UAAW,CACd,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,GAAG,EAAM,MAAM,EAAO,EAAI,EAAE,EAAE,MAAM,EAAM,MAAM,EAAO,EAAI,EAAE,GACtE,CACA,IAAK,aAAc,CACjB,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,IAAI,EAAM,KAAK,EAAO,EAAI,EAAE,EAAE,MAAM,EAAM,KAAK,EAAO,EAAI,EAAE,EAAE,EACvE,CACA,QACE,MAAO,GAAG,EAAM,GAAG,EAAS,GAAG,EAAO,CAAK,GAC/C,CACF,EClFa,IACX,EACA,IAC+B,CAE/B,GAAM,CAAE,eAAc,qBAAoB,UAAU,CAAC,GADxC,GAA+C,CAAC,EAEvD,EAAM,EAAQ,oBACd,EAAO,EAAQ,gBACf,EAAiC,EAAQ,sBAE/C,GAAI,CAAC,GAAO,CAAC,GAAQ,CAAC,EAAY,OAElC,GAAM,CAAE,MAAK,KAAI,KAAI,MAAK,UAAS,SAAQ,OAAM,KAAI,MAAK,OAAQ,EAK5D,EAAgB,GAAsB,CAC1C,IAAM,EAAS,EAAU,QAAQ,GAAG,EACpC,GAAI,EAAS,EAAG,CACd,IAAM,EAAS,EAAU,MAAM,EAAG,CAAM,EAClC,EAAO,EAAU,MAAM,EAAS,CAAC,EACvC,GAAI,EAAK,GAAS,OAAO,EAAK,EAAO,CAAC,EACxC,CAEA,OAAO,EAAK,EAAW,CAAC,EAC1B,EAEM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAS,EAAa,CAAK,EAC3B,EAAa,EAAG,CAAQ,EAExB,EAAe,IAAgB,QAC/B,EAAkB,GAAgB,EAAe,EAAa,CAAW,EAAI,EAG7E,EAAoB,GACpB,GAAgB,CAAC,EAAqB,EAAe,CAAC,EACnD,EAAqB,EAAG,EAAI,EAAI,EAAY,EAAG,CAAE,aAAc,EAAK,CAAC,EAAI,EAGlF,OAAQ,EAAR,CACE,IAAK,IACH,OAAO,EAAG,EAAQ,EAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAI,EAAG,EAAQ,EAAiB,CAAK,CAAC,CAAC,EAChD,IAAK,IACH,OAAO,EAAG,EAAQ,EAAiB,CAAK,CAAC,EAC3C,IAAK,IACH,OAAO,EAAG,EAAQ,EAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAI,EAAQ,EAAiB,CAAK,CAAC,EAC5C,IAAK,KACH,OAAO,EAAI,EAAQ,EAAiB,CAAK,CAAC,EAC5C,IAAK,aACL,IAAK,mBAAoB,CAEvB,IAAM,EAAO,EAAK,EADF,EAAe,IAAA,GAAY,GAAG,EAAM,EACnB,EACjC,OAAO,IAAe,mBAAqB,EAAI,CAAI,EAAI,CACzD,CACA,IAAK,WACL,IAAK,iBAAkB,CAErB,IAAM,EAAO,EAAK,EADF,EAAe,IAAA,GAAY,IAAI,EAAM,EACpB,EACjC,OAAO,IAAe,iBAAmB,EAAI,CAAI,EAAI,CACvD,CACA,IAAK,WACL,IAAK,iBAAkB,CAErB,IAAM,EAAO,EAAK,EADF,EAAe,IAAA,GAAY,IAAI,GACd,EACjC,OAAO,IAAe,iBAAmB,EAAI,CAAI,EAAI,CACvD,CACA,IAAK,OACH,OAAO,EAAO,CAAM,EACtB,IAAK,UACH,OAAO,EAAI,EAAO,CAAM,CAAC,EAC3B,IAAK,KACL,IAAK,QAAS,CAEZ,IAAM,EAAO,EAAQ,EADA,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,EAAiB,CAAC,CACvB,CAAC,EACzC,OAAO,IAAe,QAAU,EAAI,CAAI,EAAI,CAC9C,CACA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAI,CAAC,EAAO,GAAU,EAChB,EAAuB,IAAiB,GAC9C,GACE,CAAC,GACD,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,MAAW,IACT,EAAQ,EAAe,CAAK,EAC5B,EAAS,EAAe,CAAM,GAEhC,IAAM,EAAO,EAAI,EAAI,EAAQ,CAAK,EAAG,EAAI,EAAQ,CAAM,CAAC,EACxD,OAAO,IAAe,aAAe,EAAI,CAAI,EAAI,CACnD,CACA,MACF,CACA,QACE,MACJ,CACF,EChDa,GAA2D,CACtE,KAAM,CAAC,EACP,OAAQ,CACN,iBAAkB,EACpB,EACA,OAAQ,CAAC,EACT,MAAO,CACL,eAAgB,IAChB,oBAAqB,CAAC,IAAK,GAAG,EAC9B,yBAA0B,IAC1B,YAAa,GACf,EACA,MAAO,CACL,eAAgB,QAClB,EACA,WAAY,CACV,oBAAqB,IACrB,eAAgB,GAChB,YAAa,GACf,CACF,EAOa,GAA+D,CAC1E,GAAG,EACL,EAEM,GAAwB,CAC5B,IAAK,GACL,QAAS,GACT,cAAe,GACf,iBAAkB,GAClB,KAAM,GACN,QAAS,GACT,UAAW,GACX,KAAM,GACN,cAAe,GACf,QAAS,GACT,iBAAkB,GAClB,oBAAqB,GACrB,cAAe,GACf,OAAQ,GACR,UAAW,GACX,KAAM,GACN,IAAK,GACL,YAAa,GACb,OAAQ,GACR,IAAK,GACL,OAAQ,GACR,QAAS,GACT,YAAa,EACf,EAGM,EAA0C,GAAK,EAAE,SACjD,GAA4B,CAChC,IAAK,EACL,QAAS,EACT,cAAe,EACf,iBAAkB,EAClB,KAAM,EACN,QAAS,EACT,UAAW,EACX,KAAM,EACN,cAAe,EACf,QAAS,EACT,iBAAkB,GAClB,oBAAqB,GACrB,cAAe,GACf,OAAQ,EACR,UAAW,EACX,KAAM,EACN,IAAK,GACL,YAAa,EACb,OAAQ,EACR,IAAK,EACL,OAAQ,EACR,QAAS,EACT,YAAa,CACf,EAEM,GAAoE,CACxE,IAAK,SACL,KAAM,GACN,QAAS,0BACT,iBAAkB,SAClB,OAAQ,QACR,QAAS,GACT,KAAM,SACN,IAAK,SACP,EAgBM,GAA4B,CAChC,OAAQ,OACR,OAAQ,CAAC,EACT,oBAAqB,CAAC,GAAI,EAAE,EAC5B,yBAA0B,GAC1B,iBAAoB,CAAC,EACrB,YAAa,IACb,iBAAkB,GAClB,eAAgB,GAChB,mBAAoB,GACpB,qBAAA,IACA,wBAAA,IACA,gBAAiB,IACjB,eAAgB,KAChB,OAAQ,OACR,UAAW,MACX,aAAc,CAAC,EACf,YAAa,CAAC,CAChB,EAEM,GAAsC,IAAI,IAAkB,CAChE,MACA,UACA,gBACA,UACA,YACA,OACA,gBACA,UACA,SACA,YACA,OACA,aACF,CAAC,EAEK,GAAa,IAAI,IAAkB,CACvC,MACA,gBACA,sBACA,UACA,SACA,WACF,CAAC,EAmLD,SAAS,GACP,EACA,EAAiD,CAAC,EAClD,CACA,IAAM,EAAU,OAAO,GAAgB,SAAW,CAAE,OAAQ,EAAG,CAAW,CAAE,EAAI,EAE1E,EAAiC,CACrC,GAAG,GACH,GAAI,CAAC,EAAQ,QAAU,GAAW,IAAI,EAAQ,MAAM,EAC/C,GAAkB,EAAQ,QAAU,SAAW,KAChD,KACJ,GAAG,EACH,GAAI,CAAC,EAAQ,SACV,OAAO,KAAK,EAAiB,CAAC,CAAC,SAAS,EAAQ,QAAU,EAAE,EAAI,CAAE,OAAQ,KAAM,EAAI,KACzF,EAEM,EAAS,EAAG,EAAO,MAAM,EAEzB,CACJ,mBAAoB,EACpB,aAAc,EACd,kBAAmB,EACnB,eACA,oBAAqB,EACrB,mBAAoB,EACpB,cAAe,EACf,YACA,eAAgB,EAChB,WACE,EAEE,EAAyB,GAEtB,OADmB,GAAqB,CAAE,eAAc,WAAU,CAC3C,GAAM,SAChC,GACA,OAAO,GAAiB,UACtB,EACA,IAAA,GAGF,EACJ,OAAO,GAA6B,WAChC,EACC,GAA0B,IAAW,EAEtC,EACJ,OAAO,GAA0B,WAC7B,GAAuB,CAAqB,EAC1C,GAAK,EAAsB,EAAE,MAAO,EAAE,SAAU,EAAE,MAAO,EAAE,WAAW,EACtE,EACF,IAAW,mBACT,GACA,GAAoC,IAAI,CAAM,EAC3C,GAAwB,GAAsB,GAC/C,GAEJ,GACH,OAAO,GAAyB,WAAa,EAAuB,QACpE,GAAoC,IAAI,CAAM,GAC/C,OAAO,GAAyB,YAChC,EACI,EACA,OACJ,GAAsB,IACtB,GAEI,EAAsB,GAA4B,CAA0B,EAC5E,EAAS,EAAiB,EAAO,MAAM,EACvC,GAAoD,EAAG,IAC3D,EACE,EAAoB,EAAG,CAAC,GACa,CAAC,CACxC,EAEI,EACJ,GACA,GAA2B,IAC3B,GAA2B,IAGzB,EAA+B,CAAC,EAGpC,GAAI,OAAO,GAAc,WAAY,CACnC,IAAM,EAAmB,EAAU,CAAS,EAC5C,GAAI,OAAO,GAAqB,UAE1B,IAAA,CAAC,GAGC,IAAW,cACb,OAAO,IAAW,gBACd,CAAE,IAAK,EAAoB,OAAQ,CAAC,CAAE,EACtC,IAAW,sBACT,CAAE,IAAK,EAAoB,OAAQ,CAAC,CAAE,EACtC,IAAW,UACT,IAAI,EAAmB,GACvB,IAAW,gBACT,GACA,IAAW,SACT,GACA,IAAW,YACT,GACA,IAAW,gBACT,CAAC,EACD,IAAW,WAAa,IAAW,aAAe,IAAW,cAC3D,IAAA,GACA,CACpB,KAGF,GAAgB,CAEpB,CAEA,IAAM,EAA8C,CAAC,EAC/C,EAAe,GAAkB,CAAM,EAC7C,IAAK,IAAM,KAAK,EAEV,OAAO,EAAE,WAAc,aACzB,EACE,EAAE,OAA4C,EAAE,MAC9C,EAAE,WAIV,IAAM,EAAgB,GAAmB,CACvC,IAAI,EACA,EAIJ,GAHI,EAAK,KACP,EAAmB,EAAc,EAAK,KAEpC,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAW,EAAa,OAAO,GAAK,EAAE,OAAS,EAAK,KAAK,EAC/D,GAAI,EAAS,OAAS,EAAG,CACvB,IAAM,EAAQ,EAAS,GAEnB,OAAO,EAAM,WAAc,aAC7B,EAAiB,EAAM,UAE3B,CACF,CAEA,GAAI,EAAK,cAAgB,aAAe,OAAO,EAAO,eAAkB,WAAY,CAClF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAMzC,IALuB,IAC1B,GACE,EAAiB,EAAO,cAAc,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,CAAC,CACjF,CAAC,CAAC,IAAI,GAAK,GAAiB,EAAE,MAAO,EAAO,WAAW,CAAC,CAEvC,CAAC,CAAC,IAAI,GAAiB,EAAK,MAAO,EAAO,WAAW,CAAC,IACvE,EAAmB,GAEvB,CACA,MAAO,CAAC,EAAkB,CAAc,CAC1C,EAGM,EAAwC,CAC5C,GAAG,EACH,qBACA,SACA,SACA,eACA,wBACA,sBACA,oBACA,gBACA,iBACA,eACA,gBACA,SACF,EAEA,GAAI,OAAO,GAA8B,WACvC,OAAO,EAA0B,EAAW,CAAY,EAG1D,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,mBAAoB,CACvB,IAAM,EAAK,EAAe,GAAe,EAAW,CAAY,EAAI,EAOpE,OANI,IAAW,mBACN,KAAK,UAAU,GAAK,EAAK,IAE9B,IAAQ,MAAQ,IAAQ,OAAS,IAAA,GAAY,GAA4B,EAAK,CAAK,CACrF,EAEK,KAAK,UAAU,EAAI,GAA6B,CAAC,CAC1D,CAEA,IAAK,MACH,OAAO,GAA6B,EAAW,CAAY,EAE7D,IAAK,gBACL,IAAK,sBACH,OAAO,GAAuC,EAAW,CAAY,EAEvE,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,gBACH,OAAO,GAAsC,EAAW,CAAY,EAEtE,IAAK,MACH,OAAO,GAA6B,EAAW,CAAY,EAE7D,IAAK,OACH,OAAO,GAA8B,EAAW,CAAY,EAE9D,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,YACH,OAAO,GAAmC,EAAW,CAAY,EAEnE,IAAK,gBACH,OAAO,GAAuC,EAAW,CAAY,EAEvE,IAAK,mBACH,OAAO,GAA4B,EAAW,CAAY,EAE5D,IAAK,OACH,OAAO,GAA8B,EAAW,CAAY,EAE9D,IAAK,SACH,OAAO,GAAgC,EAAW,CAAY,EAEhE,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,cACH,OAAO,GAAoC,EAAW,CAAY,EAEpE,IAAK,YACH,OAAO,GAAmC,EAAW,CAAY,EAEnE,IAAK,SACL,IAAK,MACH,OAAO,GAAgC,EAAW,CAAY,EAEhE,IAAK,SACH,OAAO,GAAgC,EAAW,CAAY,EAEhE,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,cACH,OAAO,GAAqC,EAAW,CAAY,EAErE,QACE,MAAO,EACX,CACF,CC/oBA,MAAM,GACH,IACA,EAAO,EAAU,EAAO,IACvB,EAAK,CAAE,QAAO,WAAU,QAAO,aAAY,EAAG,CAAE,aAAc,EAAM,CAAC,EAQ5D,GAA8C,GACzD,EACF,EAMa,GAAqD,GAChE,EACF,EAMa,GACX,GAAuB,EAAuB,EAMnC,GACX,GAAuB,EAAwB,EAkDpC,GAAgD,GAMhD,GAAoD,GAMpD,GAAiD,GChGjD,GAAY,EAAY,IAAgD,CACnF,IAAI,EAA6B,EAC7B,EAAQ,EACZ,KAAO,EAAQ,EAAK,QAAU,GAAU,EAAY,CAAM,GAAG,CAC3D,IAAM,EAA0C,EAAO,MAAM,EAAK,IAClE,EAAS,OAAO,GAAM,SAAW,KAAO,EACxC,GACF,CAEA,OAAO,EAAQ,EAAK,OAAS,KAAO,CACtC,EAMa,IAAU,EAAY,IAAgD,CACjF,GAAI,EAAM,KAAO,EACf,OAAO,EAGT,IAAK,IAAM,KAAQ,EAAM,MACnB,UAAO,GAAS,SACpB,IAAI,EAAK,KAAO,EACd,OAAO,EACF,GAAI,EAAY,CAAI,EAAG,CAC5B,IAAM,EAAU,GAAO,EAAI,CAAI,EAC/B,GAAI,EACF,OAAO,CAEX,EAGF,OAAO,IACT,EAMa,IAAe,EAAY,IAAyC,CAC/E,GAAI,EAAM,KAAO,EAAI,MAAO,CAAC,EAE7B,IAAM,EAAM,EAAM,MAAM,UAAU,GAAO,OAAO,GAAM,UAAa,EAAE,KAAO,CAAE,EAE9E,GAAI,GAAO,EACT,MAAO,CAAC,CAAG,EAGb,IAAK,GAAM,CAAC,EAAG,KAAM,OAAO,QAAQ,EAAM,KAAK,EAC7C,GAAI,EAAY,CAAC,EAAG,CAClB,IAAM,EAAU,GAAY,EAAI,CAAC,EACjC,GAAI,MAAM,QAAQ,CAAO,EACvB,MAAO,CAAC,OAAO,SAAS,CAAC,EAAG,GAAG,CAAO,CAE1C,CAGF,OAAO,IACT,EAKa,EAAiB,GAAqB,EAAK,MAAM,EAAG,EAAE,EAKtD,IAAiB,EAAa,IAAyB,CAClE,GAAI,EAAM,SAAW,EAAM,OAAQ,MAAO,GAC1C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAChC,GAAI,EAAM,KAAO,EAAM,GAAI,MAAO,GAEpC,MAAO,EACT,EAMa,IAAc,EAAqB,IAAwB,CACtE,GAAI,EAAc,QAAU,EAAK,OAAQ,MAAO,GAChD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAc,OAAQ,IACxC,GAAI,EAAc,KAAO,EAAK,GAAI,MAAO,GAE3C,MAAO,EACT,EAKa,IAAyB,EAAa,IAAsB,CACvE,IAAM,EAA2B,CAAC,EAC5B,EAAc,EAAc,CAAK,EACjC,EAAc,EAAc,CAAK,EACnC,EAAI,EAER,KAAO,EAAI,EAAY,QAAU,EAAI,EAAY,QAAU,EAAY,KAAO,EAAY,IACxF,EAAmB,KAAK,EAAY,EAAE,EACtC,IAGF,OAAO,CACT,EAMa,IAAkB,EAAY,IAAqC,CAC9E,IAAI,EAAW,CAAC,CAAC,EAAM,SACnB,EAAsC,EACtC,EAAQ,EACZ,KAAO,EAAQ,EAAK,QAAU,CAAC,GAAY,EAAY,CAAM,GAAG,CAC9D,IAAM,EAA0C,EAAO,MAAM,EAAK,IAC9D,EAAO,CAAC,IAAM,EAAY,CAAC,GAAM,UAAW,GAAO,EAAE,SACvD,EAAW,CAAC,CAAC,EAAE,SACf,EAAS,GAEX,GACF,CACA,OAAO,CACT,EAUa,IAAyB,EAAY,EAAwB,CAAC,IACzE,EAAc,KAAK,GAAK,GAAc,EAAG,CAAI,GAAK,GAAW,EAAG,CAAI,CAAC,EAa1D,IACX,EACA,EACA,CAAE,WAAW,GAAO,gBAAgB,CAAC,GAAsD,CAAC,IAC7E,CACf,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,IAAK,CACnC,IAAM,EAAW,CAAC,GAAG,EAAM,CAAC,EAC5B,EAAM,GAAK,CACT,KAAM,EACN,SAAU,GAAY,EAAc,KAAK,GAAK,GAAc,EAAU,CAAC,CAAC,CAC1E,CACF,CACA,OAAO,CACT,ECrKa,GAAqC,GAChD,GAAc,CAAC,EAAG,EAAO,IAAI,EAAI,gBAAkB,sBAAsB,EAAO,KAAK,KAAK,GAAG,ICNzF,GAAe,WAAW,OAEnB,GACX,oEAaF,IAAW,MACT,eAAe,WAAW,QAAS,KAC9B,KAAK,OAAO,EAAI,KAAK,MAAM,CAAsB,GAAK,OAAc,OAAO,SAAS,CAAC,EAAA,CACrF,SAAS,EAAE,CAAC,CACZ,SAAS,EAAG,GAAG,CACpB,EAIF,GAAI,GAAc,CAEhB,GAAI,OAAO,GAAa,YAAe,WACrC,MAAmB,GAAa,WAAW,OACtC,GAAI,OAAO,GAAa,iBAAoB,WAAY,CAO7D,IACM,EAAY,IAAI,YAAY,EAAE,EAEpC,MAAmB,CACjB,GAAa,gBAAgB,CAAS,EACtC,IAAI,GAAM,EAAU,GAAK,GAAA,CAAI,SAAS,EAAE,EACxC,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IACtB,AAKE,EALE,IAAM,GACH,GAAG,EAAA,GACC,IAAM,GACV,GAAG,IAAK,OAAe,EAAU,IAAM,KAEvC,GAAG,KAAM,EAAU,GAAK,GAAA,CAAI,SAAS,EAAE,KAG1C,IAAM,GAAK,IAAM,IAAM,IAAM,IAAM,IAAM,MAC3C,EAAK,GAAG,EAAA,IAGZ,OAAO,CACT,CACF,CACF,CC/CA,MAAa,GAA+CC,EAKtD,GAAgB,IAAI,EAAM,CAAE,WAAY,EAAM,CAAC,EAOxC,IAAe,EAAS,KACnC,EAAS,EAAU,GAAc,QCjB7BC,GAAU,CACd,KAAM,OACN,MAAO,OACP,WAAY,KACZ,MAAO,OACT,EAQa,IACX,EACA,IAIqB,CAKrB,IAAM,EAAK,EAAY,EAAa,CAAS,EAAsCA,GAE/E,EAAkE,EAAG,YAAc,GAkBvF,MAhBI,CAAC,GAAc,IACjB,EAAa,EAAc,EAAG,MAAqC,CACjE,UAAW,CACb,CAAC,GAGC,IAAe,GACV,GACE,IAAe,GACjB,CAAC,EAGN,GAAsB,CAAU,EAC3B,EAAiB,CAAU,EAG5B,GAAY,IAClB,GACE,GAAkB,KAAK,GAAO,EAAI,QAAU,EAAG,CAAE,CAAC,GAAK,CACrD,KAAM,EACN,MAAO,EACP,MAAO,CACT,CACJ,GAAK,CAAC,CACR,EClDM,IAAuB,EAAkB,EAAa,IAA4B,CACtF,IAAM,EAAc,EAAe,CAAI,EAEvC,GAAI,EAAE,WAAa,WAAa,EAAE,WAAa,aAAc,CAC3D,IAAM,EAAe,CAAC,EAAa,CAAW,EAC9C,OAAO,EACH,EACA,GACE,EAAa,IACX,GAAK,GAAwC,EAC/C,EACA,GACF,CACN,CAEA,OAAO,CACT,EAkCa,IACX,EACA,IACY,CACZ,GAAM,CACJ,YACA,SACA,qBACA,YACA,kBACA,gBACA,iBACE,EAEJ,GAAI,GAAW,eAAiB,IAAA,IAAa,EAAU,eAAiB,KACtE,OAAO,EAAU,aACZ,GAAI,EACT,OAAO,EAAgB,EAAM,CAAE,WAAU,CAAC,EAG5C,IAAI,EAAqD,GAEnD,EAAS,EAAU,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAEjE,GAAI,EAAK,cAAgB,QAAS,CAChC,IAAM,EAAiB,GAAyB,EAAW,EAAQ,EAAK,QAAQ,EAChF,EACE,EAAe,OAAS,EAAI,GAAoB,EAAgB,EAAM,CAAa,EAAI,EAC3F,MAAO,GAAI,EAAK,cAAgB,YAAa,CAC3C,IAAM,EAAa,EACf,EAAc,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EACtD,KACJ,EAAQ,GAAc,EAAW,OAAS,EAAI,EAAe,CAAU,EAAI,EAC7E,MAAO,GAAI,EAAO,OAAS,EAAG,CAC5B,IAAM,EAAa,EAAmB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAC1E,IAAe,cACjB,EAAQ,EAAgB,CAAC,EAAI,IACpB,IAAe,UAAY,IAAe,WACnD,EAAQ,GAAoB,EAAQ,EAAM,CAAa,EAE3D,MACqB,EAAmB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAChE,IAAM,aACjB,EAAQ,IAIZ,OAAO,CACT,ECxGa,GACX,GACuF,CACvF,IAAM,EACJ,OAAO,GAAqB,UACxB,EACA,OAAO,GAAqB,UAAY,EACtC,EAAiB,MACjB,KACR,OAAO,OAAO,GAAU,UACpB,EACE,GAAmB,MACnB,GAAmB,QACrB,EACN,ECXM,GAAmD,CACvD,CAAE,KAAM,QAAS,MAAO,QAAS,MAAO,OAAQ,CAClD,EAEM,GAAU,CACd,KAAM,OACN,MAAO,OACP,aAAc,KACd,MAAO,OACT,EASa,IACX,EACA,EACA,IAK2B,CAK3B,IAAM,EAAK,EAAY,EAAa,CAAS,EAAI,GAE7C,EAIoE,EAAG,cAAgB,GAoB3F,OAlBI,OAAO,GAAoB,aAC7B,EAAkB,EAAgB,CAAQ,GAGxC,CAAC,GAAmB,IACtB,EAAkB,EAAgB,EAAG,MAAqC,EAAe,CACvF,UAAW,CACb,CAAC,GAGE,EAID,GAAsB,CAAe,EAChC,EAAiB,CAAyC,EAG5D,EAAgB,IACrB,GACE,GAAyB,KAAK,GAAO,EAAI,QAAU,EAAG,CAAE,CAAC,GAAK,CAC5D,KAAM,EACN,MAAO,EACP,MAAO,CACT,CACJ,EAdS,EAeX,ECtEa,IACX,EACA,GAAG,IACyC,CAC5C,IAAM,EAAS,CAAE,GAAG,CAAK,EAEzB,IAAK,IAAM,KAAgB,EAEzB,GAAI,EACF,IAAK,IAAM,KAAO,GAAW,CAAY,EACnC,GAAY,CAAG,IACnB,AAGE,EAAO,GAHL,EAAO,GACK,CAAE,GAAG,EAAO,GAAM,GAAG,EAAa,EAAK,EAEvC,CAAE,GAAG,EAAa,EAAK,GAM7C,OAAO,CACT,EAEa,IACX,EACA,EACA,IACwD,CACxD,GAAI,GAAY,CAAE,EAAG,OACrB,IAAM,EAAY,GAAc,CAAiB,CAAC,CAC/C,KAAK,CAAC,EAAK,CAAC,EAAI,MAAS,CAAC,EAAK,GAAM,GAAM,IAAW,EAAG,GAAG,EAAI,CAAC,CAAC,CAClE,OAAO,GAAK,CAAC,GAAY,EAAE,EAAY,GAAK,CAAC,CAAC,EAAE,EAAE,EACrD,GAAI,EAAU,OAAS,GAAK,EAAU,CACpC,IAAM,EAAoB,IAAW,IAAO,CAAC,EACvC,EAAc,OAAO,OAAO,CAAC,EAAG,EAAmB,OAAO,YAAY,CAAS,CAAC,EACtF,MAAO,EAAG,GAAK,CAAY,CAC7B,CAEF,ECtCM,GAAwB,EAAwB,IAAgC,CACpF,IAAI,EAAS,GACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAI,EAAK,EAAE,GAAG,GACpB,GAAI,CAAC,EAAG,SAER,IAAM,EAAI,OAAO,GAAM,SAAW,EAAI,GAAK,CAAC,EACxC,IAAG,EAAS,EAAS,GAAG,EAAO,GAAG,IAAM,EAC9C,CACA,OAAO,CACT,EAKa,IAAmB,GAAG,KAA6C,CAC9E,aAAc,EAAqB,eAAgB,CAAI,EACvD,UAAW,EAAqB,YAAa,CAAI,EACjD,OAAQ,EAAqB,SAAU,CAAI,EAC3C,KAAM,EAAqB,OAAQ,CAAI,EACvC,YAAa,EAAqB,cAAe,CAAI,EACrD,QAAS,EAAqB,UAAW,CAAI,EAC7C,SAAU,EAAqB,WAAY,CAAI,EAC/C,UAAW,EAAqB,YAAa,CAAI,EACjD,WAAY,EAAqB,aAAc,CAAI,EACnD,YAAa,EAAqB,cAAe,CAAI,EACrD,KAAM,EAAqB,OAAQ,CAAI,EACvC,OAAQ,EAAqB,SAAU,CAAI,EAC3C,UAAW,EAAqB,YAAa,CAAI,EACjD,MAAO,EAAqB,QAAS,CAAI,EACzC,WAAY,EAAqB,aAAc,CAAI,EACnD,UAAW,EAAqB,YAAa,CAAI,EACjD,aAAc,EAAqB,eAAgB,CAAI,EACvD,gBAAiB,EAAqB,kBAAmB,CAAI,EAC7D,WAAY,EAAqB,aAAc,CAAI,EACnD,WAAY,EAAqB,aAAc,CAAI,EACnD,WAAY,EAAqB,aAAc,CAAI,EACnD,SAAU,EAAqB,WAAY,CAAI,EAC/C,UAAW,EAAqB,YAAa,CAAI,EACjD,SAAU,EAAqB,WAAY,CAAI,EAC/C,UAAW,EAAqB,YAAa,CAAI,EACjD,MAAO,EAAqB,QAAS,CAAI,EACzC,YAAa,EAAqB,cAAe,CAAI,EACrD,cAAe,EAAqB,gBAAiB,CAAI,EACzD,cAAe,EAAqB,gBAAiB,CAAI,EACzD,aAAc,EAAqB,eAAgB,CAAI,EACvD,MAAO,EAAqB,QAAS,CAAI,EACzC,QAAS,EAAqB,UAAW,CAAI,EAC7C,YAAa,EAAqB,cAAe,CAAI,EACrD,QAAS,EAAqB,UAAW,CAAI,EAC7C,QAAS,EAAqB,UAAW,CAAI,EAC7C,SAAU,EAAqB,WAAY,CAAI,EAC/C,kBAAmB,EAAqB,oBAAqB,CAAI,EACjE,mBAAoB,EAAqB,qBAAsB,CAAI,EACnE,UAAW,EAAqB,YAAa,CAAI,EACjD,SAAU,EAAqB,WAAY,CAAI,EAC/C,cAAe,EAAqB,gBAAiB,CAAI,EACzD,UAAW,EAAqB,YAAa,CAAI,EACjD,eAAgB,EAAqB,iBAAkB,CAAI,EAC3D,SAAU,EAAqB,WAAY,CAAI,EAC/C,YAAa,EAAqB,cAAe,CAAI,EACrD,QAAS,EAAqB,UAAW,CAAI,EAC7C,sBAAuB,EAAqB,wBAAyB,CAAI,CAC3E,GChCa,IAGX,CACA,QACA,YACA,eACA,YACA,cACA,aACA,sBAOA,GAAqB,CACnB,WAAa,GAAW,WACtB,IAAe,EAAO,CAAE,WAAU,CAAC,GACnC,EACF,cACA,aACA,SAAU,EACV,kBACF,CAAC,CAAC,CAAC,WASQ,IAA2D,CACtE,QACA,YACA,qBACA,kBAQI,GAAW,gBAAwB,EAAU,gBAE7C,EACK,OAAO,GAAuB,WACjC,EAAmB,EAAO,CAAE,WAAU,CAAC,EACvC,EAGC,EAAe,EAAa,EAAO,CAAE,WAAU,CAAC,CAAC,GAAK,GAUlD,IAA2D,CACtE,QACA,WACA,YACA,wBAOI,GAAW,gBACN,OAAO,EAAU,iBAAoB,WACxC,EAAU,gBAAgB,CAAQ,EAClC,EAAU,gBAGT,IAAqB,EAAO,EAAU,CAAE,WAAU,CAAC,GAAK,OAUpD,IAAqD,CAChE,QACA,WACA,YACA,YACA,cACA,aACA,sBAWA,GAA8B,CAC5B,WAAY,GAAW,QAAU,IAAY,EAAO,EAAU,CAAE,WAAU,CAAC,GAAK,CAAC,EACjF,cACA,aACA,kBACF,CAAC,CAAC,CAAC,WClJC,GAAiB,GAAuB,CAC5C,IAAM,EAAQ,OAAO,eAAe,CAAC,EACrC,OAAO,IAAU,MAAQ,IAAU,OAAO,SAC5C,EAgBa,IAAe,EAAY,IAAwB,CAC9D,GAAI,OAAO,GAAG,EAAG,CAAC,EAAG,MAAO,GAE5B,GAAI,MAAM,QAAQ,CAAC,GAAK,MAAM,QAAQ,CAAC,EACrC,OACE,MAAM,QAAQ,CAAC,GACf,MAAM,QAAQ,CAAC,GACf,EAAE,SAAW,EAAE,QACf,EAAE,OAAO,EAAG,IAAM,GAAY,EAAG,EAAE,EAAE,CAAC,EAS1C,GALI,OAAO,GAAM,UAAY,OAAO,GAAM,UAAY,IAAM,MAAQ,IAAM,MAKtE,OAAO,eAAe,CAAC,IAAM,OAAO,eAAe,CAAC,GAAK,CAAC,GAAc,CAAC,EAAG,MAAO,GAEvF,IAAM,EAAQ,OAAO,KAAK,CAAC,EAC3B,OACE,EAAM,SAAW,OAAO,KAAK,CAAC,CAAC,CAAC,QAChC,EAAM,MAAM,GACV,GAAa,EAA8B,GAAK,EAA8B,EAAE,CAClF,CAEJ,EAaa,IAKX,EACA,IACY,GAAY,EAAG,CAAC,ECjExB,IAAyB,EAAgB,IAC7C,IAAS,GAAQ,GAAQ,EAAO,GAAS,IAAY,GAEjD,IAA0B,EAAgB,IAC9C,EAAO,GAAO,IAAS,IAAgB,CAAC,CAAC,EAM9B,IACX,EACA,EACA,EACA,IAEC,EAII,GAAS,EAHV,EACE,GAAsB,EAAM,CAAO,EACnC,GAAuB,EAAM,CAAO,EAQ/B,IAAiB,EAAW,EAAY,IACnD,IAAS,IAAA,IAAa,GAAQ,KAC1B,EACA,IAAY,IAAA,IAAa,GAAW,KAClC,EACA,EAMK,IACX,EAA2B,CAAC,EAC5B,EAAiC,CAAC,EAClC,IAEA,GAAc,EAAwB,CAAC,CAAC,QAA2B,EAAK,CAAC,EAAK,MAC5E,EAAI,GAAO,GAAW,EAAK,EAAM,GAAM,EAAY,GAAM,CAAC,CAAQ,EAC3D,GACN,CAAC,CAAC,EC5BM,IACX,EACA,CAAE,cAAc,GAAgC,CAAC,IACpC,CACb,IAAM,EAAU,CAAC,EAAK,GAChB,EAAe,EAAiB,CAAI,EAM1C,MAJI,CAAC,GAAW,CAAC,EACR,EAGF,CACL,GAAG,EACH,GAAI,GAAW,CAAE,GAAI,EAAY,CAAE,EACnC,GAAI,GAAgB,CAAE,MAAO,GAAiB,EAAK,MAAO,CAAE,aAAY,CAAC,CAAE,CAC7E,CACF,EAMa,IACX,EACA,CAAE,cAAc,GAAgC,CAAC,IAC1C,CACP,IAAM,EAAU,CAAC,EAAY,GACzB,EAAe,GACb,EAAqD,CAAC,EAE5D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,MAAM,OAAQ,IAAK,CACjD,IAAM,EAAI,EAAY,MAAM,GAC5B,GAAI,OAAO,GAAM,SACf,EAAS,KAAK,CAAC,MACV,CACL,IAAM,EAAW,EAAY,CAAC,EAC1B,GAAiB,EAAG,CAAE,aAAY,CAAC,EACnC,GAAY,EAAG,CAAE,aAAY,CAAC,EAClC,EAAS,KAAK,CAAQ,EAClB,IAAa,IACf,EAAe,GAEnB,CACF,CAMA,MAJI,CAAC,GAAW,CAAC,EACR,EAGF,CACL,GAAG,EACH,GAAI,GAAW,CAAE,GAAI,EAAY,CAAE,EACnC,MAAO,CACT,CACF,EAKa,IACX,EACA,CAAE,cAAc,GAAgC,CAAC,IAEjD,EAAY,CAAE,EAAI,GAAiB,EAAI,CAAE,aAAY,CAAC,EAAI,GAAY,EAAI,CAAE,aAAY,CAAC,EAa9E,IACX,EAMA,IACO,CACP,IAAM,EACJ,EAAQ,OAAS,EAAQ,YAAc,EAAQ,cAAgB,EAAQ,cAEzE,OAAO,EAAe,GAAK,EAAiB,GAAiB,EAAgB,CAAO,CACtF,EC/Fa,IACX,EACA,CAAE,cAAc,GAAoC,CAAC,IAC5B,gBAAgB,CAAE,GAAG,EAAM,GAAI,EAAY,CAAE,CAAyB,EAKpF,IACX,EACA,CAAE,cAAc,GAAoC,CAAC,IAC7B,CACxB,GAAI,CAAC,EAAO,CAAO,EAAG,OAAO,EAE7B,GAAI,CAAC,EAAY,CAAO,EACtB,OAAO,gBAAgB,CACrB,GAAG,EACH,GAAI,EAAY,CAClB,CAAC,EAGH,IAAM,EAAW,CAAE,GAAG,EAAS,GAAI,EAAY,CAAE,EAcjD,OAXI,MAAM,QAAQ,EAAS,KAAK,IAE9B,EAAU,MAAgB,EAAQ,MAAM,IAAK,GAC3C,OAAO,GAAM,SACT,EACA,EAAY,CAAC,EACX,GAAc,EAAG,CAAE,aAAY,CAAC,EAChC,GAAa,EAAe,CAAE,aAAY,CAAC,CACnD,GAGK,CACT,ECwGa,IACX,EACA,EACA,EAAuB,CAAC,EACxB,CAAE,WAAW,IAAkC,CAAC,IACzB,CACvB,GAAI,EAAO,cAAe,OAAO,EAAW,kBAAoB,kBAEhE,GAAI,CAAC,EAAO,iBAAmB,IAAa,IAAA,GAAW,OAAO,KAE9D,IAAM,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAK7E,OAJI,IAAS,GAAe,EAAM,CAAK,GAAK,GAAsB,EAAM,EAAO,aAAa,GACnF,EAAW,kBAAoB,kBAGjC,IACT,EAOa,IACX,EACA,CAAE,YAAY,KAA2B,CAAC,IAC9B,CAAC,CAAC,GAAc,EAAW,QAAU,EA+CtC,IAAkB,EAAO,EAAa,EAAgB,EAAU,CAAC,IAC5E,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GACjC,GAAW,EAAG,EAAyB,EAAgB,CAAO,CAChE,EASW,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,cAAc,EACd,sBACA,cAAc,EACd,WACE,EACE,EAAS,MAAM,QAAQ,CAAc,EACvC,EAAS,EAAgB,CAAK,EAC9B,GAAO,EAAgB,CAAK,EAEhC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,MAAO,SAAU,CAAe,CAAC,EAC7E,EAGT,GAAI,CAAC,EAAY,CAAM,EAErB,OADA,IAAU,CAAE,OAAQ,qBAAsB,UAAW,MAAO,SAAU,CAAe,CAAC,EAC/E,EAIT,IAAM,EACJ,MAAM,QAAQ,CAAc,EAAI,EAAiB,GAAY,EAAgB,CAAK,EAG9E,EAAiB,GAAoB,EAAO,EAAY,EAAS,CAAE,SAAU,EAAK,CAAC,EACzF,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAgB,UAAW,MAAO,SAAU,CAAe,CAAC,EACzE,EAGT,GAAI,EAAY,CAAW,GAAK,GAAiB,EAAY,CAAO,EAElE,OADA,IAAU,CAAE,OAAQ,sBAAuB,UAAW,MAAO,SAAU,CAAe,CAAC,EAChF,EAGT,GAAI,EAAkB,CAAM,GAAK,EAAO,MAAM,OAAS,EAAG,CACxD,IAAM,EAAiB,EAAO,MAAM,GAAG,EAAE,EACzC,EAAO,MAAM,KAIX,IACG,OAAO,GAAmB,SAAW,EAAiB,EAAe,CAAW,EACrF,CACF,CAIA,OAFA,EAAO,MAAM,KAAK,GAAmB,EAAa,CAAE,aAAY,CAAC,CAAa,EAEvE,CACT,EA6FM,GAAyC,CAAE,MAAO,EAAG,SAAU,EAAG,YAAa,EAAG,MAAO,CAAE,EAG3F,GAAsB,GAC1B,EAAQ,UAAU,EAAG,KAAO,GAAe,EAAE,KAAO,IAAM,GAAe,EAAE,KAAO,EAAE,EAOhF,IACJ,EACA,EACA,EACA,IACsF,CAEtF,GAAI,OAAO,GAAM,SACf,MAAO,CAAE,QAAS,CAAC,CAAC,EAAG,CAAC,CAAC,EAAG,SAAU,EAAoB,QAAU,GAAuB,CAAC,CAAE,EAGhG,GAAI,MAAM,QAAQ,CAAC,EAAG,CACpB,IAAM,EAAS,EACf,MAAO,CACL,QAAS,GAAmB,EAAE,KAAK,EAAM,IAAyB,CAAC,EAAM,EAAO,EAAE,CAAC,CAAC,EACpF,SAAU,EACV,QAAU,GAAuB,CAAC,CACpC,CACF,CAEA,MAAO,CACL,QAAS,GAAmB,OAAO,QAAQ,CAA4B,CAAC,EACxE,SAAU,EACV,QAAU,GAAuB,CAAC,CACpC,CACF,EAMM,IAAmB,EAAY,EAAY,EAAY,KACzD,OAAO,GAAM,UAAY,MAAM,QAAQ,CAAC,EAAI,EAAI,IAAwB,CAAC,EAMvE,IACJ,EACA,EACA,EACA,EACA,IACO,CACP,GAAM,CAAE,UAAS,WAAU,WAAY,GAAoB,EAAG,EAAG,EAAG,CAAC,EACrE,IAAK,GAAM,CAAC,EAAM,KAAU,EAC1B,GAAoB,EAAO,EAAM,EAAO,EAAU,CAAO,EAE3D,OAAO,CACT,EAca,KACX,EACA,EACA,EACA,EACA,IAEA,GAAY,GAAgB,EAAG,EAAG,EAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAO,GAAK,CAC1D,GAAoB,EAAG,EAAG,EAAG,EAAG,CAAC,CACnC,CAAC,GAUU,KACX,EACA,EACA,EACA,EACA,IACO,GAAoB,EAAO,EAAG,EAAG,EAAG,CAAC,GAKxC,IACJ,EACA,EAEA,EACA,EACA,EAAyB,CAAC,IACnB,CACP,GAAM,CACJ,mBAAoB,EAAsB,GAC1C,wBAAwB,GACxB,6BAA+B,IAC/B,sBAAwB,CAAC,OAAO,EAChC,0BAA4B,GAC5B,oBAAsB,CAAC,EACvB,WACE,EAEA,EAAqB,EAEnB,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAG7E,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAKT,IAAM,EACJ,IAAS,WAAa,CAAE,cAAe,EAAQ,aAAc,EAAK,EAC9D,EAAoB,GAAoB,EAAO,EAAM,CAAY,EACvE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAmB,UAAW,SAAU,UAAS,CAAC,EAC/D,EAIT,GAAI,IAAS,cAAgB,CAAC,EAAgB,CAAK,EAAG,CAGpD,IAAM,EAAS,EAAS,EAAc,CAAI,EAAG,CAAK,EAClD,GAAI,CAAC,GAAU,CAAC,EAAY,CAAM,EAEhC,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAET,IAAM,EAAc,EAAO,MAW3B,OATI,EAAK,GAAG,EAAE,EAAK,GAAM,EACnB,EAAY,EAAK,GAAG,EAAE,KAAQ,EAChC,IAAU,CAAE,OAAQ,YAAa,UAAW,SAAU,UAAS,CAAC,EAEhE,EAAY,EAAK,GAAG,EAAE,GAAM,EAG9B,IAAU,CAAE,OAAQ,wBAAyB,UAAW,SAAU,UAAS,CAAC,EAEvE,CACT,CAEA,IAAM,EAAc,EAAS,EAAM,CAAK,EAGxC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAGT,IAAM,EAAU,EAAY,CAAW,EAIvC,GAAI,EAAY,KAAU,EAExB,OADA,IAAU,CAAE,OAAQ,YAAa,UAAW,SAAU,UAAS,CAAC,EACzD,EAUT,GANI,IAAS,gBAEX,EAAY,GAAQ,GAIlB,EAAS,OAAO,EAEpB,IAAI,EAAmB,GACnB,EAAa,GAEjB,GAAI,IAAS,QAAS,CACpB,IAAM,EAAsB,EAAc,EAAY,KAAK,EACrD,EAAoB,EAAc,CAAK,EAE7C,GAAI,EAAkB,SAAW,EAC/B,OAAO,EAAY,UACd,CACL,IAAM,EACJ,EAAY,OAAO,MAAQ,EAAU,EAAmB,EAAY,MAAM,IAAI,EAC1E,KACA,EAAe,CAAiB,EAClC,IACF,EAAY,MAAQ,CAAE,KAAM,EAAe,UAAW,CAAE,EAE5D,EAEI,EAAoB,OAAS,GAAK,EAAkB,OAAS,KAE/D,EAAqB,GAEzB,CAGI,GAAsB,IAAS,UACjC,EAAY,SAAW,EAAuB,CAAK,EACnD,EAAmB,GACnB,EAAa,IAIX,GAAyB,IAAS,aACpC,EAAmB,GACnB,EAAa,IAQf,IAAM,EAAqB,EALN,GACnB,CAAE,KAAM,EAAY,MAAO,MAAO,EAAY,MAAO,MAAO,EAAG,EAC/D,EAAY,SACZ,CAEwC,CAAY,EAoBtD,OAlBG,GACC,EAAY,aACZ,IAAuB,EAAY,aACpC,IAAS,eAAiB,IAAU,EAAY,eAKjD,EACE,CAAC,CAAC,EAAY,aAAgB,CAAC,EAAY,aAAe,IAAU,EACtE,EAAY,YAAc,EAAmB,EAAqB,GAGhE,IAEF,EAAY,MAAQ,EAAoB,CAAW,GAG9C,CACT,EA2Ba,IAAwB,EAAO,EAAU,EAAU,CAAC,IAC/D,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAc,EAAG,EAAU,CAAO,CAAC,EAShE,IAA+B,EAAO,EAAU,EAAU,CAAC,IAAoB,CAC1F,GAAM,CAAE,WAAY,EACd,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAG7E,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAIT,GAAI,EAAK,SAAW,EAElB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAGT,IAAM,EAAoB,GAAoB,EAAO,EAAM,CAAO,EAClE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAmB,UAAW,SAAU,UAAS,CAAC,EAC/D,EAMT,GAAI,CAAC,EAAS,EAAM,CAAK,EAEvB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAIT,IAAM,EAAQ,EAAK,GAAG,EAAE,EAClB,EAAS,EAAS,EAAc,CAAI,EAAG,CAAK,EAClD,GAAI,CAAC,EAAgB,CAAM,GAAK,EAAO,MAAM,OAAS,EAAG,CACvD,IAAM,EAAiB,IAAU,EAAI,EAAI,EAAQ,EACjD,EAAO,MAAM,OAAO,EAAgB,CAAC,CACvC,MACE,EAAO,MAAM,OAAO,EAAO,CAAC,EAG9B,OAAO,CACT,EAEM,IACJ,EACA,EACA,IACS,CACT,GAAI,MAAM,QAAQ,CAAuB,EACvC,OAAO,EAGT,IAAM,EAAK,EAAkB,CAAK,EAElC,GAAI,IAA4B,KAAM,CACpC,GAAI,GAAc,EAAa,CAAC,CAAC,CAAC,EAChC,OAAO,EACF,GAAI,EAAY,GAAG,EAAE,IAAM,EAAG,CACnC,IAAM,EAAa,EAAc,CAAW,EAC5C,MAAO,CAAC,GAAG,EAAc,CAAU,EAAG,KAAK,IAAI,EAAG,EAAW,GAAG,EAAE,EAAM,IAAW,CAAC,CACtF,CAAO,CACL,IAAM,EAAiB,CACrB,GAAG,EAAc,CAAW,EAC5B,KAAK,IAAI,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EAAE,CAChD,EACM,EAAiB,EAAS,EAAgB,CAAK,EAQnD,OAPE,EAAY,CAAc,EACrB,CAAC,GAAG,EAAgB,EAAe,MAAM,MAAM,EAM/C,CAHL,GAAG,EAAc,CAAW,EAC5B,KAAK,IAAI,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EAAE,CAEhC,CAEpB,CACF,CAAO,GAAI,IAA4B,OAAQ,CAC7C,GAAI,GAAc,CAAC,EAAM,MAAM,OAAS,CAAC,EAAG,CAAW,EACrD,OAAO,EACF,GACL,EAAY,GAAG,EAAE,IAChB,EAAS,EAAc,CAAW,EAAG,CAAK,CAAC,CAAsB,MAAM,OAAS,EACjF,CACA,IAAM,EAAa,EAAc,CAAW,EAC5C,MAAO,CAAC,GAAG,EAAc,CAAU,EAAG,EAAW,GAAG,EAAE,EAAK,CAAC,CAC9D,CAAO,CACL,IAAM,EAAiB,CAAC,GAAG,EAAc,CAAW,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EAAE,EACnF,EAAmB,EAAS,EAAgB,CAAK,EAKrD,OAJE,EAAY,CAAgB,EACvB,CAAC,GAAG,EAAgB,CAAC,EAGrB,CADa,GAAG,EAAc,CAAW,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EACnE,CAEpB,CACF,CAEA,OAAO,CACT,EA6Ca,IAAoB,EAAO,EAAa,EAAS,EAAU,CAAC,IACvE,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAY,EAAG,EAAa,EAAS,CAAO,CAAC,EAU1E,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,QAAQ,GACR,cAAc,EACd,cAAc,EACd,WACE,EACE,EAAU,MAAM,QAAQ,CAAW,EAAI,EAAc,GAAY,EAAa,CAAK,EAGzF,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,OAAQ,SAAU,CAAY,CAAC,EAC3E,EAKT,IAAM,EAAsB,EAAS,EAAS,CAAK,EACnD,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,OAAQ,SAAU,CAAY,CAAC,EAC3E,EAGT,IAAM,EAAW,GAAY,EAAO,EAAS,CAAO,EAGpD,GAAI,EAAQ,SAAW,EAErB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,OAAQ,SAAU,CAAY,CAAC,EAC3E,EAGT,IAAM,EAAkB,GAAoB,EAAO,EAAS,CAAO,EACnE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAiB,UAAW,OAAQ,SAAU,CAAY,CAAC,EACxE,EAIT,GAAI,GAAc,EAAS,CAAQ,EAEjC,OADA,IAAU,CAAE,OAAQ,gBAAiB,UAAW,OAAQ,SAAU,CAAY,CAAC,EACxE,EAYT,GARI,CAAC,EAAS,EAAc,CAAQ,EAAG,CAAK,GAQxC,CAAC,GAAS,GAAW,EAAS,CAAQ,EAExC,OADA,IAAU,CAAE,OAAQ,wBAAyB,UAAW,OAAQ,SAAU,CAAQ,CAAC,EAC5E,EAGT,IAAM,EAAc,EAChB,GACE,EAAQ,CAAmB,EAAI,EAAQ,CAAmB,EAAI,EAC9D,CAAE,aAAY,CAChB,EACA,EAEE,EAAyB,EAAkB,CAAK,EAChD,EAAuB,EAAS,EAAc,CAAO,EAAG,CAAK,EAC7D,EAAoB,EAAQ,GAAG,EAAE,EACjC,EACJ,GAA0B,EAAoB,EACzC,EAAqB,MAAM,EAAoB,GAChD,KACA,EACJ,GAA0B,EAAoB,EAAqB,MAAM,OAAS,EAC7E,EAAqB,MAAM,EAAoB,GAChD,KAGN,GAAI,CAAC,EAAO,CACV,IAAM,EAAiB,EACnB,KAAK,IAAI,EAAG,EAAoB,CAAC,EACjC,EACE,EAAe,EAAyB,EAAI,EAClD,EAAqB,MAAM,OAAO,EAAgB,CAAY,CAChE,CAEA,IAAM,EAAa,CAAC,GAAG,CAAQ,EAC3B,GAA0B,EAAW,GAAG,EAAE,EAAK,GAAM,IAMvD,EAAW,EAAW,OAAS,IAAM,GAEvC,IAAM,EAAqB,GAAsB,EAAS,CAAQ,EAEhE,CAAC,GACD,EAAQ,SAAW,EAAmB,OAAS,GAC/C,EAAW,EAAmB,QAAU,EAAQ,EAAmB,UAKnE,EAAW,EAAmB,SAAW,EAAyB,EAAI,GAExE,IAAM,EAAmB,EAAc,CAAU,EAC3C,EAAqB,EAAS,EAAkB,CAAK,EACrD,EAAW,EAAW,GAAG,EAAE,EAI3B,EAAc,GAA0B,EAAW,EAAI,EAAW,EAAI,EAOtE,GAAqB,GAAG,IAC5B,EAAmB,MAAM,OAAO,EAAa,EAAG,GAAG,CAAI,EA2BzD,OAxBI,EAAmB,MAAM,SAAW,GAAK,CAAC,EAC5C,EAAkB,CAAW,EAEzB,IAAa,EACX,IAAsB,GAAK,EAC7B,EAAkB,EAAa,CAAiB,EAIhD,EAAkB,EADhB,EAAmB,MAAM,IAAM,GAAqB,EAAe,CAAW,CAChC,EAIhD,EADE,IAIA,EAAmB,MAAM,EAAc,IACvC,GACA,EAAe,CAAW,GALS,CAMW,EAK/C,CACT,EA6Da,IAAwB,EAAO,EAAa,EAAM,EAAU,CAAC,IACxE,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAc,EAAG,EAAyB,EAAM,CAAO,CAAC,EASrF,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,cAAc,EACd,sBACA,uBACA,cAAc,EACd,UAAU,GACV,WACE,EAEE,EAAqB,EAAS,EAAc,CAAI,EAAG,CAAK,EAC9D,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,SAAU,CAAK,CAAC,EACtE,EAGT,GAAI,CAAC,EAAY,CAAkB,EAEjC,OADA,IAAU,CAAE,OAAQ,qBAAsB,UAAW,SAAU,SAAU,CAAK,CAAC,EACxE,EAGT,IAAM,EAAa,EAAc,CAAI,EAC/B,EAAoB,GAAoB,EAAO,EAAY,EAAS,CAAE,SAAU,EAAK,CAAC,EAC5F,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAmB,UAAW,SAAU,SAAU,CAAK,CAAC,EACrE,EAGT,GAAI,EAAY,CAAW,GAAK,GAAiB,EAAY,CAAO,EAElE,OADA,IAAU,CAAE,OAAQ,sBAAuB,UAAW,SAAU,SAAU,CAAK,CAAC,EACzE,EAGT,IAAM,EAAO,GAAc,EAAa,CAAE,aAAY,CAAC,EACjD,EAAyB,EAAkB,CAAK,EAChD,EAAW,EAAK,GAAG,EAAE,EAOrB,GAAqB,EAAa,GAAG,IACzC,EAAmB,MAAM,OAAO,EAAK,EAAU,EAAK,OAAS,EAAG,GAAG,CAAI,EAGzE,GAAI,EAAmB,MAAM,SAAW,GAAK,CAAC,EAC5C,EAAkB,EAAU,CAAI,OAC3B,GAAI,GAAW,EACpB,EAAkB,EAAY,EAAW,EAAI,CAAI,OAEjD,GAAI,IAAa,EACX,EAAK,MAAM,GAAG,EAAE,IAAM,GAAK,EAC7B,EAAkB,EAAU,EAAM,CAAoB,EAItD,EAAkB,EAAU,EAD1B,EAAmB,MAAM,IAAM,GAAuB,EAAe,CAAW,CAC/B,MAEhD,CACL,IAAM,EAAqB,EAAW,GAAM,EAAI,EAAW,EAAI,EAC3D,EACF,EAAkB,EAAoB,EAAqB,CAAI,EAM/D,EAAkB,EAHhB,EAAmB,MAAM,EAAqB,IAC9C,GACA,EAAe,CAAW,EAC6B,CAAI,CAEjE,CAGF,OAAO,CACT,EA8Ca,IACX,EACA,EACA,EACA,EAAU,CAAC,IAEX,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAa,EAAG,EAAgB,EAAgB,CAAO,CAAC,EAWrF,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,QAAQ,GACR,cAAc,EACd,cAAc,EACd,WACE,EACE,EAAa,MAAM,QAAQ,CAAc,EAC3C,EACA,GAAY,EAAgB,CAAK,EAC/B,EAAa,MAAM,QAAQ,CAAc,EAC3C,EACA,GAAY,EAAgB,CAAK,EAGrC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,IAAM,EAAW,GAAY,EAAO,EAAY,CAAU,EAG1D,GAAI,EAAW,SAAW,EAExB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,IAAM,EAAmB,GAAoB,EAAO,EAAY,CAAO,EACvE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAkB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC7E,EAIT,GAAI,GAAc,EAAY,CAAQ,EAEpC,OADA,IAAU,CAAE,OAAQ,gBAAiB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC5E,EAUT,GANI,CAAC,EAAS,EAAc,CAAQ,EAAG,CAAK,GAMxC,CAAC,GAAS,GAAW,EAAY,CAAQ,EAE3C,OADA,IAAU,CAAE,OAAQ,wBAAyB,UAAW,QAAS,SAAU,CAAe,CAAC,EACpF,EAGT,IAAM,EAA4B,EAAS,EAAY,CAAK,EACtD,EAAoB,EAAS,EAAY,CAAK,EACpD,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAET,IAAM,EAAoB,EACtB,GACE,EAAQ,CAAyB,EAC7B,EAAQ,CAAyB,EACjC,EACJ,CAAE,aAAY,CAChB,EACA,EAEE,EAAyB,EAAkB,CAAK,EAChD,EAAuB,EAAS,EAAc,CAAU,EAAG,CAAK,EAChE,EAAoB,EAAW,GAAG,EAAE,EAG1C,GAAI,CAAC,EAAO,CACV,IAAM,EAAiB,EACnB,KAAK,IAAI,EAAG,EAAoB,CAAC,EACjC,EACE,EAAe,EAAyB,EAAI,EAClD,EAAqB,MAAM,OAAO,EAAgB,CAAY,CAChE,CAEA,IAAM,EAAa,CAAC,GAAG,CAAQ,EACzB,EAAqB,GAAsB,EAAY,CAAQ,EAEnE,CAAC,GACD,EAAW,SAAW,EAAmB,OAAS,GAClD,EAAS,EAAmB,QAAU,EAAW,EAAmB,UAKpE,EAAW,EAAmB,SAAW,EAAyB,EAAI,GAExE,IAAM,EAAmB,EAAc,CAAU,EAC3C,EAAqB,EAAS,EAAkB,CAAK,EACrD,EAAkB,EAAW,GAAG,EAAE,EAmBxC,OAhBA,EAAmB,MAAM,OACvB,EACA,EACA,GACG,EACG,CAAE,MAAO,CAAC,EAAmB,EAAe,CAAW,EAAG,CAAiB,CAAE,EAC7E,CACE,WAAY,EAAe,CAAW,EACtC,MAAO,CAAC,EAAmB,CAAiB,CAE9C,EACJ,CAAE,aAAY,CAEhB,CACF,EAEO,CACT,ECnrCa,IAAsB,EAA6B,CAAC,IAA2B,CAC1F,GAAM,CACJ,OACA,cACA,cACA,YAAY,IACZ,gBACA,kBAAkB,GAClB,gBACA,qBACA,wBACA,yBACA,kBACA,sBACA,gBACA,SACA,YACA,aACA,WACA,aACA,cACA,cACA,eACA,SACE,EAEE,EAAO,GAAiC,IAAQ,CAAE,OAAM,GAAG,CAAQ,CAAC,EAEpE,EAAS,CAAE,kBAAiB,gBAAe,eAAc,EAGzD,GAAW,EAAyB,EAAY,EAAW,KAC/D,CAAC,CAAC,GAAoB,EAAO,EAAM,EAAQ,CAAE,UAAS,CAAC,EAEzD,MAAO,CACL,SAAU,EAAO,EAAM,EAAY,IAAY,CAC7C,GAAI,EAAQ,EAAO,EAAY,EAAI,EAAG,CACpC,EAAI,CAAE,KAAM,EAAQ,mBAAoB,OAAM,aAAY,OAAM,CAAC,EACjE,MACF,CAEA,IAAM,EAAW,IAAY,EAAU,EAAM,EAAY,EAAO,CAAO,EACvE,GAAI,CAAC,EAAU,CACb,EAAI,CAAE,KAAM,EAAQ,eAAgB,OAAM,aAAY,OAAM,CAAC,EAC7D,MACF,CAEA,IAAM,EAAU,IAAa,GAAO,EAAO,EACrC,EAAW,GAAI,EAAO,EAAS,EAAY,CAC/C,cACA,oBAAsB,EAAuC,oBAC7D,cACA,QACF,CAAC,EAED,OADA,EAAI,CAAE,KAAM,EAAQ,IAAK,QAAO,WAAU,UAAS,YAAW,CAAC,EACxD,CACT,EAEA,UAAW,EAAO,EAAW,EAAY,IAAY,CAEnD,GAAI,EAAW,QAAU,EAAW,OAEpC,GAAI,EAAQ,EAAO,EAAY,EAAI,EAAG,CACpC,EAAI,CAAE,KAAM,EAAQ,mBAAoB,YAAW,aAAY,OAAM,CAAC,EACtE,MACF,CAEA,IAAM,EAAY,IAAa,EAAW,EAAW,EAAY,EAAO,CAAO,EAC/E,GAAI,CAAC,EAAW,CACd,EAAI,CAAE,KAAM,EAAQ,gBAAiB,YAAW,aAAY,OAAM,CAAC,EACnE,MACF,CAEA,IAAM,EAAW,IAAc,GAAO,EAAY,EAC5C,EAAW,GAAI,EAAO,EAAU,EAAY,CAChD,cACA,oBAAsB,EAA6B,qBAAuB,IAAA,GAC1E,cACA,QACF,CAAC,EAED,OADA,EAAI,CAAE,KAAM,EAAQ,IAAK,QAAO,WAAU,WAAU,YAAW,CAAC,EACzD,CACT,EAEA,YAAa,EAAO,EAAM,EAAO,IAAS,CAIxC,GAAI,GAAoB,EAAO,EADZ,IAAS,WAAa,CAAE,eAAc,EAAI,CACd,EAAG,CAChD,EAAI,CAAE,KAAM,EAAQ,aAAc,OAAM,OAAM,QAAO,OAAM,CAAC,EAC5D,MACF,CAEA,IAAM,EAAW,GAAO,EAAO,EAAM,EAAO,EAAM,CAChD,qBACA,wBACA,yBACA,kBACA,sBACA,gBACA,QACF,CAAC,EAED,OADA,EAAI,CAAE,KAAM,EAAQ,OAAQ,QAAO,WAAU,OAAM,QAAO,MAAK,CAAC,EACzD,CACT,EAEA,mBAAoB,EAAO,EAAM,IAAY,CAC3C,GAAI,EAAQ,EAAO,CAAI,EAAG,CACxB,EAAI,CAAE,KAAM,EAAQ,aAAc,OAAM,OAAM,CAAC,EAC/C,MACF,CAEA,IAAM,EAAc,EAAS,EAAM,CAAK,EAExC,GAAI,CAAC,EAAa,OAElB,GAAI,GAAY,CAAC,EAAS,EAAa,EAAM,EAAO,CAAO,EAAG,CAC5D,EAAI,CAAE,KAAM,EAAQ,cAAe,cAAa,OAAM,OAAM,CAAC,EAC7D,MACF,CAEA,IAAM,EAAW,GAAO,EAAO,EAAM,CAAE,QAAO,CAAC,EAE/C,OADA,EAAI,CAAE,KAAM,EAAQ,OAAQ,QAAO,WAAU,OAAM,aAAY,CAAC,EACzD,CACT,EAEA,UAAW,EAAO,EAAS,EAAS,EAAO,IAAY,CACrD,GAAI,EAAQ,EAAO,CAAO,EAAG,CAC3B,EAAI,CAAE,KAAM,EAAQ,aAAc,UAAS,UAAS,OAAM,CAAC,EAC3D,MACF,CAIA,IAAM,EAAc,EAAS,EAAS,CAAK,EAC3C,GAAI,CAAC,EAAa,OAGlB,IAAM,EAAY,GAAK,EAAO,EAAS,EAAS,CAAE,QAAO,cAAa,cAAa,QAAO,CAAC,EACrF,EAAU,EAAY,CAAW,EACjC,EAAW,EAAU,EAAc,EACnC,EAAiB,IACnB,EAAS,EAAa,EAAS,EAAS,EAAO,EAAW,CAAE,QAAO,aAAY,EAAG,CAAO,EAG7F,GAAI,CAAC,EAAgB,CACnB,EAAI,CACF,KAAM,EAAU,EAAQ,iBAAmB,EAAQ,gBACnD,cACA,UACA,UACA,QACA,QACA,WACF,CAAC,EACD,MACF,CAEA,IAAM,EAAW,EAAY,CAAc,EAAI,EAAiB,EAEhE,OADA,EAAI,CAAE,KAAM,EAAQ,KAAM,QAAO,WAAU,UAAS,UAAS,OAAM,CAAC,EAC7D,CACT,EAEA,WAAY,EAAO,EAAY,EAAY,EAAO,IAAY,CAC5D,GAAI,EAAQ,EAAO,CAAU,EAAG,CAC9B,EAAI,CAAE,KAAM,EAAQ,aAAc,aAAY,aAAY,OAAM,CAAC,EACjE,MACF,CAIA,IAAM,EAAc,EAAS,EAAY,CAAK,EAC9C,GAAI,CAAC,EAAa,OAGlB,IAAM,EAAY,GAAM,EAAO,EAAY,EAAY,CACrD,QACA,cACA,cACA,QACF,CAAC,EACK,EAAU,EAAY,CAAW,EACjC,EAAW,EAAU,EAAe,EACpC,EAAiB,IACnB,EACE,EACA,EACA,EACA,EACA,EACA,CAAE,QAAO,aAAY,EACrB,CACF,EAGJ,GAAI,CAAC,EAAgB,CACnB,EAAI,CACF,KAAM,EAAU,EAAQ,kBAAoB,EAAQ,iBACpD,cACA,aACA,aACA,QACA,QACA,WACF,CAAC,EACD,MACF,CAEA,IAAM,EAAW,EAAY,CAAc,EAAI,EAAiB,EAEhE,OADA,EAAI,CAAE,KAAM,EAAQ,MAAO,QAAO,WAAU,aAAY,aAAY,OAAM,CAAC,EACpE,CACT,CACF,CACF,EC5Sa,IAA+C,CAC1D,SACA,kBACA,yBACA,kBACA,gBACA,sBACA,cAAc,KACsB,CACpC,IAAI,EAAQ,EAAe,CAAM,GAAK,GAEtC,GAAI,EAAiB,CACnB,GAAI,OAAO,GAAoB,WAAY,CACzC,IAAM,EAAe,EAAgB,CAAM,EAEvC,IAAc,EAAQ,EAC5B,KACE,GAAQ,CAEZ,CAEA,IAAM,EAAY,EAAU,EAAQ,CAAK,EACnC,EAAW,EAAuB,CAAK,EACvC,EAAc,EAAe,EAAgB,EAAO,EAAU,CAAE,WAAU,CAAC,CAAC,GAAK,QACjF,EAAY,EAAe,EAAc,EAAO,CAAE,WAAU,CAAC,CAAC,EAE9D,EAAoB,CACxB,GAAI,EAAY,EAChB,QACA,WACA,cACA,MAAO,GACP,GAAI,EAAY,CAAE,MAAO,CAAE,KAAM,EAAW,UAAW,CAAE,CAAE,EAAI,IACjE,EAEA,MAAO,CAAE,GAAG,EAAS,MAAO,EAAoB,CAAO,CAAE,CAC3D,EAwBa,IACX,CACE,cACA,qBACA,WAAY,EACZ,cAAc,GAEhB,IACqB,CAErB,IAAM,EAAK,EAAY,EACjB,EAAQ,EAAqB,CAAC,EAAe,CAAC,EAAI,CAAC,EAMzD,OAJI,EACK,CAAE,KAAI,QAAO,IAAK,EAAM,EAG1B,CACL,KACA,QACA,WAAY,EAAe,CAAW,GAAK,GAC3C,IAAK,EACP,CACF,ECvBA,IAAa,GAAb,MAAa,UAA0B,KAAM,CAE3C,KAEA,KAEA,YAAY,EAAiB,CAC3B,MACE,kBAAkB,EAAK,UAAU,aAAa,EAAK,OAAO,GACxD,EAAK,WAAa,IAAA,GAAY,GAAK,eAAe,KAAK,UAAU,EAAK,QAAQ,IAC/E,EACH,EACA,KAAK,KAAO,oBACZ,KAAK,KAAO,EAAK,OACjB,KAAK,KAAO,EAEZ,OAAO,eAAe,KAAM,EAAkB,SAAS,CACzD,CACF,EA8RA,MAAM,GAAwB,OAAO,oBAAoB,EAInD,GAAkC,EAAO,CAAE,MAAO,GAAM,OAAQ,EAAM,CAAC,EACvE,GAAmC,EAAO,CAAE,MAAO,GAAO,OAAQ,EAAK,CAAC,EACxE,GAA2C,EAAO,CAAE,MAAO,GAAM,OAAQ,EAAK,CAAC,EA6D/E,OAK4B,CAChC,IAAM,EAAQ,CACZ,UAAW,IAAI,IACf,cAAe,EACf,KAAM,CAAC,EACP,OAAQ,CAAC,EACT,OAAQ,EACR,WAAY,EACZ,gBAAiB,GACjB,oBAAqB,EACvB,EASA,OAFA,OAAO,eAAe,EAAO,WAAY,CAAE,MAAO,GAAM,WAAY,EAAM,CAAC,EAEpE,CACT,EA0BA,IAAa,GAAb,MAAa,CAKX,CAUA,IAAY,OAAmC,CAC7C,OAAQ,KAAqE,GAC/E,CAEA,YAAY,EAAY,EAAwC,CAAC,EAAG,CAGlE,OAAO,eAAe,KAAM,GAAQ,CAClC,MAAO,GAAgC,EACvC,WAAY,GACZ,SAAU,GACV,aAAc,EAChB,CAAC,EAED,KAAK,aAAa,CAAO,EAEzB,KAAK,MAAM,MAAQ,KAAK,OACtB,EACI,GAAiB,EAAO,CAAE,YAAa,KAAK,MAAM,WAAY,CAAC,EAC/D,KAAK,gBAAgB,CAC3B,CACF,CAOA,OAAkB,EAAS,CACzB,OAAO,KAAK,MAAM,cAAgB,EAAO,EAAG,EAAI,EAAI,CACtD,CAOA,aAAqB,EAA6C,CAChE,KAAK,MAAM,QAAU,EACrB,KAAK,MAAM,cAAgB,EAAQ,QAAU,GAC7C,KAAK,MAAM,YAAc,EAAQ,aAAe,EAChD,KAAK,MAAM,UAAY,EAAQ,WAAa,GAC5C,KAAK,MAAM,OAAS,EAAQ,QAAU,GACtC,KAAK,MAAM,gBAAkB,EAAQ,iBAAmB,GACxD,KAAK,MAAM,gBAAkB,EAAQ,gBAErC,IAAM,EAAU,EAAQ,SAAW,GAC7B,EAAsC,OAAO,GAAY,SAAW,EAAU,CAAC,EACrF,KAAK,MAAM,eAAiB,IAAY,GACxC,KAAK,MAAM,WAAa,EAAe,YAAA,GACvC,KAAK,MAAM,WAAa,EAAe,YAAA,IACvC,KAAK,MAAM,IAAM,EAAQ,KAAO,KAAK,IAErC,GAAM,CAAE,WAAY,EAAQ,WAAY,GAAa,GAAqB,CACxE,WAAY,EAAQ,OACpB,WAAY,EAAQ,UACpB,iBAAkB,EAAQ,gBAC1B,YAAa,EAAQ,cAAc,MACrC,CAAC,EAID,KAAK,MAAM,OAAS,KAAK,OAAO,CAAM,EACtC,KAAK,MAAM,SAAW,KAAK,OAAO,CAAQ,EAE1C,KAAK,MAAM,UAAY,GAAqB,CAC1C,WAAa,EAAQ,WAAa,EAClC,WAAY,EAAQ,aACpB,SAAU,EACV,iBAAkB,EAAQ,mBAC1B,YAAa,EAAQ,cAAc,SACrC,CAAC,CAAC,CAAC,WAGH,KAAK,MAAM,YAAc,KAAK,OAC5B,GAAqB,CACnB,WAAa,EAAQ,aAAe,EACpC,WAAY,EAAQ,cACtB,CAAC,CAAC,CAAC,UACL,CACF,CAKA,UAAkB,EAAkB,CAClC,OAAS,KAAK,MAAM,SAA2C,IAAU,CAAC,CAC5E,CAGA,aAAqB,EAAkC,CACrD,OAAO,GAA0B,CAC/B,QACA,UAAW,KAAK,UAAU,CAAK,EAC/B,aAAc,KAAK,MAAM,QAAQ,aACjC,UAAW,KAAK,MAAM,UACtB,WAAY,KAAK,MAAM,QAAQ,aAC/B,iBAAkB,KAAK,MAAM,QAAQ,mBACrC,YAAa,KAAK,MAAM,QAAQ,cAAc,SAChD,CAAC,CACH,CAGA,gBAAwB,EAAuB,CAC7C,OAAO,GAA0B,CAC/B,QACA,UAAW,KAAK,UAAU,CAAK,EAC/B,mBAAoB,KAAK,MAAM,QAAQ,mBACvC,aAAe,GAAc,KAAK,aAAa,CAAC,CAClD,CAAC,CACH,CAEA,gBAAwB,EAAe,EAAkB,CACvD,OAAO,GACL,KAAK,UAAU,CAAK,EACpB,EACA,KAAK,MAAM,QAAQ,eACrB,CACF,CAEA,cAAsB,EAAiC,CACrD,OAAO,GAAqB,KAAK,UAAU,CAAK,EAAG,KAAK,MAAM,QAAQ,aAAa,CACrF,CAEA,UAAkB,EAAe,EAA0C,CACzE,OAAO,GAAoB,CACzB,QACA,WACA,UAAW,KAAK,UAAU,CAAK,EAC/B,UAAW,KAAK,MAAM,QAAQ,UAC9B,iBAAkB,KAAK,MAAM,QAAQ,gBACrC,YAAa,KAAK,MAAM,QAAQ,cAAc,MAChD,CAAC,CACH,CAEA,mBAA2B,EAAe,EAAmC,CAC3E,OAAO,GAA0B,CAC/B,QACA,WACA,UAAW,KAAK,UAAU,CAAK,EAC/B,mBAAoB,KAAK,MAAM,QAAQ,kBACzC,CAAC,CACH,CAGA,aAAqB,EAAyB,CAC5C,GAAM,CAAE,kBAAiB,gBAAe,iBAAkB,KAAK,MAAM,QACrE,OAAO,GAAuB,EAAM,CAClC,UAAW,KAAK,UAAU,EAAK,KAAK,EACpC,OAAQ,KAAK,MAAM,OACnB,gBACA,oBAAqB,EAAG,IAAM,KAAK,mBAAmB,EAAG,CAAC,EAC1D,WAAY,EAAG,IAAM,KAAK,UAAU,EAAG,CAAC,EACxC,gBAAiB,KAAqB,EAAG,IAAS,EAAgB,EAAG,CAAI,GACzE,cAAe,KAAmB,EAAG,EAAG,IAAS,KAAK,cAAc,EAAG,EAAG,CAAI,EAChF,CAAC,CACH,CAOA,cACE,EACA,EACA,EACwB,CACxB,OAAO,GAA8B,CACnC,WAAY,KAAK,MAAM,QAAQ,gBAAgB,EAAO,EAAU,CAAI,GAAK,CAAC,EAC1E,iBAAkB,KAAK,MAAM,QAAQ,eACvC,CAAC,CAAC,CAAC,UACL,CAGA,cAA2D,CACzD,GAAM,CAAE,aAAc,KAAK,MAAM,QAEjC,MAAO,CAGL,OAAQ,KAAK,MAAM,cAEnB,WAAY,GAAa,GAAK,EAAI,OAAO,CAAS,EAAI,IACtD,gBAAiB,KAAK,MAAM,gBAC5B,cAAe,KAAK,MAAM,QAAQ,cAClC,cAAe,KAAK,MAAM,QAAQ,aACpC,CACF,CAEA,aAAsB,CACpB,MAAO,CACL,YAAa,KAAK,MAAM,YACxB,YAAa,KAAK,MAAM,YACxB,GAAG,KAAK,aAAa,CACvB,CACF,CAMA,QAAgB,CAAE,SAAQ,mBAA6D,CACrF,IAAM,EAAa,GAAU,KAAK,MAAM,OAClC,EAAU,GAAmB,KAAK,MAAM,gBAE9C,MAAO,IAAQ,CAIb,GAFA,IAAU,CAAI,EAEV,GAAc,GAAqB,IAAI,EAAK,MAAM,EACpD,MAAM,IAAI,GAAkB,CAAI,CAEpC,CACF,CAGA,eAAuC,CACrC,MAAO,CACL,uBAAwB,GAAK,KAAK,gBAAgB,CAAC,EACnD,oBAAqB,GAAK,KAAK,aAAa,CAAC,EAC7C,iBAAkB,EAAG,IAAM,KAAK,gBAAgB,EAAG,CAAC,EACpD,cAAe,GAAK,KAAK,cAAc,CAAC,EACxC,mBAAoB,KAAK,MAAM,QAAQ,mBACvC,sBAAuB,KAAK,MAAM,QAAQ,sBAC1C,GAAG,KAAK,aAAa,CACvB,CACF,CAOA,OAAe,EAAgB,CAC7B,IAAM,EAAO,KAAK,MAAM,MACpB,IAAS,IAEb,KAAK,MAAM,MAAQ,EAIf,OAAK,MAAM,WAAa,KAE5B,KAAK,OAAO,EAAM,CAAI,EACtB,KAAK,OAAO,EAAW,GACzB,CAMA,OAAe,EAAU,EAAgB,CACvC,GAAI,CAAC,KAAK,MAAM,eAAgB,OAEhC,IAAM,EAAM,GAAY,EAAM,CAAI,EAIlC,GAAI,IAAA,GAA4B,OAEhC,IAAM,EAAM,KAAK,MAAM,IAAI,EACP,GAClB,KAAK,MAAM,QACX,EACA,KAAK,MAAM,OACX,EACA,KAAK,MAAM,UAGE,IACb,KAAK,MAAM,KAAK,KAAK,CAAI,EACrB,KAAK,MAAM,KAAK,OAAS,KAAK,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,EAC1E,KAAK,MAAM,OAAS,CAAC,GAGvB,KAAK,MAAM,QAAU,EACrB,KAAK,MAAM,OAAS,CACtB,CAEA,OAAe,EAAkC,CAC/C,IAAK,IAAM,KAAY,KAAK,MAAM,UAAW,EAAS,CAAM,CAC9D,CAQA,qBAAoC,CAC9B,KAAK,MAAM,WAAa,IAAG,KAAK,MAAM,gBAAkB,GAC9D,CAMA,aAA4B,CACtB,KAAK,MAAM,WAAa,KAAK,MAAM,QAEvC,KAAK,MAAM,SAAW,KAAK,MAAM,MACjC,KAAK,MAAM,YAAc,IAAA,GACzB,KAAK,MAAM,WAAa,IAAA,GAC1B,CAQA,CAAS,SAAS,EAAqB,EAAY,EAA6C,CAG9F,GAFA,KAAM,CAAE,OAAM,OAAM,QAAO,EAEvB,CAAC,EAAY,CAAI,EAAG,OAExB,IAAM,EAAa,EACnB,IAAK,GAAM,CAAC,EAAO,KAAU,EAAW,MAAM,QAAQ,EAEhD,OAAO,GAAU,WACrB,MAAO,KAAK,SAAS,EAAwB,CAAC,GAAG,EAAM,CAAK,EAAG,CAAU,EAE7E,CAGA,OAAmC,CAGjC,GAFA,KAAK,YAAY,EAEb,CAAC,KAAK,MAAM,YAAa,CAC3B,IAAM,EAAQ,IAAI,IAClB,IAAK,GAAM,CAAE,OAAM,UAAU,KAAK,SAAS,KAAK,MAAM,MAAO,CAAC,EAAG,IAAI,EAE/D,EAAK,KAAO,IAAA,IAAa,CAAC,EAAM,IAAI,EAAK,EAAE,GAAG,EAAM,IAAI,EAAK,GAAI,CAAI,EAE3E,KAAK,MAAM,YAAc,CAC3B,CAEA,OAAO,KAAK,MAAM,WACpB,CAGA,OAAe,EAAsC,CACnD,OAAO,OAAO,GAAa,SAAY,KAAK,MAAM,CAAC,CAAC,IAAI,CAAQ,GAAK,KAAQ,CAC/E,CAcA,aAAqB,KAAK,MAAM,MAGhC,SAAS,EAAiB,CAExB,OADA,KAAK,OAAO,KAAK,OAAO,GAAiB,EAAO,CAAE,YAAa,KAAK,MAAM,WAAY,CAAC,CAAC,CAAC,EAClF,IACT,CAUA,YAAuB,CACrB,OAAO,GAAc,CACnB,OAAQ,KAAK,MAAM,OACnB,gBAAiB,KAAK,MAAM,QAAQ,gBACpC,uBAAwB,GAAK,KAAK,gBAAgB,CAAC,EACnD,iBAAkB,EAAG,IAAM,KAAK,gBAAgB,EAAG,CAAC,EACpD,cAAe,GAAK,KAAK,cAAc,CAAC,EACxC,oBAAqB,GAAK,KAAK,aAAa,CAAC,EAC7C,YAAa,KAAK,MAAM,WAC1B,CAAC,CACH,CAMA,gBAAgB,EAAsC,CACpD,OAAO,GACL,CACE,YAAa,KAAK,MAAM,YACxB,mBAAoB,KAAK,MAAM,QAAQ,mBACvC,eAAkB,KAAK,WAAW,EAClC,YAAa,KAAK,MAAM,WAC1B,EACA,CACF,CACF,CAUA,IACE,EACA,EAAgC,CAAC,EACjC,EAAsC,CAAC,EACjC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAI,KAAK,MAAM,MAAO,EAAa,EAAgB,CACjD,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAGA,OAAO,EAAyB,EAAyC,CAAC,EAAS,CACjF,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAO,KAAK,MAAM,MAAO,EAAU,CACjC,GAAG,KAAK,aAAa,EACrB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAsBA,OAAO,EAAY,EAAa,EAAa,EAAmB,CAE9D,IAAM,EAAe,OAAO,GAAM,UAAY,MAAM,QAAQ,CAAC,EAAI,EAAI,EAC/D,EAAO,CAAC,EAAG,EAAG,EAAG,CAAC,EAClB,CAAE,SAAQ,kBAAiB,GAAG,GAClC,EAAK,IAAiB,CAAC,EASzB,MARA,GAAK,GAAgB,CACnB,GAAG,KAAK,cAAc,EACtB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,EAGA,KAAK,OAAQ,GAAe,KAAK,MAAM,MAAO,GAAG,EAAK,MAAM,EAAG,EAAe,CAAC,CAAC,CAAC,EAC1E,IACT,CAGA,KACE,EACA,EACA,EAAuC,CAAC,EAClC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAK,KAAK,MAAM,MAAO,EAAa,EAAS,CAC3C,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAMA,OACE,EACA,EACA,EAAyC,CAAC,EACpC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAO,KAAK,MAAM,MAAO,EAAa,EAAM,CAC1C,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAMA,MACE,EACA,EACA,EAAwC,CAAC,EACnC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAM,KAAK,MAAM,MAAO,EAAgB,EAAgB,CACtD,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAWA,YAAqD,CACnD,OAAO,EAAO,CAAE,GAAG,KAAK,MAAM,OAAQ,CAAC,CACzC,CAqCA,YACE,EACA,EACM,CACN,IAAM,EAAS,GAAQ,QAAU,CAAE,GAAG,CAAQ,EAAI,CAAE,GAAG,KAAK,MAAM,QAAS,GAAG,CAAQ,EA4BtF,OAtBI,GAAa,KAAK,MAAM,QAAS,CAAM,EAAU,MAErD,KAAK,aAAa,EAAO,CAAM,CAAC,EAKhC,KAAK,MAAM,WAAa,IAAA,GAExB,KAAK,uBAAuB,EAE5B,EAAE,KAAK,MAAM,cAKT,KAAK,MAAM,WAAa,EAC1B,KAAK,MAAM,oBAAsB,GAEjC,KAAK,OAAO,EAAY,EAGnB,KACT,CAYA,wBAAuC,CACjC,KAAK,MAAM,eAET,KAAK,MAAM,KAAK,OAAS,KAAK,MAAM,YACtC,KAAK,MAAM,KAAK,OAAO,EAAG,KAAK,MAAM,KAAK,OAAS,KAAK,MAAM,UAAU,GAG1E,KAAK,MAAM,KAAO,CAAC,EACnB,KAAK,MAAM,OAAS,CAAC,EACrB,KAAK,MAAM,QAAU,IAAA,GAEzB,CAWA,qBAAiC,KAAK,MAAM,cAgB5C,MAAM,EAAkE,CACtE,IAAM,EAAQ,GAAS,cACnB,GAAc,KAAK,MAAM,MAAO,CAAE,YAAa,KAAK,MAAM,WAAY,CAAC,EACvE,KAAK,MAAM,MACf,OAAO,IAAI,EAA0B,EAAO,KAAK,MAAM,OAAO,CAChE,CAyBA,UAAa,IACX,KAAK,MAAM,UAAU,IAAI,CAAQ,MACpB,CACX,KAAK,MAAM,UAAU,OAAO,CAAQ,CACtC,GAqBF,MAAM,EAAsB,CAC1B,KAAK,MAAM,aACP,KAAK,MAAM,aAAe,IAC5B,KAAK,MAAM,cAAgB,CACzB,MAAO,KAAK,MAAM,MAClB,KAAM,CAAC,GAAG,KAAK,MAAM,IAAI,EACzB,OAAQ,CAAC,GAAG,KAAK,MAAM,MAAM,EAC7B,QAAS,KAAK,MAAM,QACpB,OAAQ,KAAK,MAAM,MACrB,GAGF,GAAI,CACF,EAAG,CACL,OAAS,EAAO,CAEd,GAAI,KAAK,MAAM,aAAe,EAAG,CAC/B,IAAM,EAAW,KAAK,MAAM,cAG5B,KAAK,MAAM,MAAQ,EAAS,MAC5B,KAAK,MAAM,KAAO,EAAS,KAC3B,KAAK,MAAM,OAAS,EAAS,OAC7B,KAAK,MAAM,QAAU,EAAS,QAC9B,KAAK,MAAM,OAAS,EAAS,OAG7B,KAAK,uBAAuB,CAC9B,CACA,MAAM,CACR,QAAU,CAGR,GAFA,KAAK,MAAM,aAEP,KAAK,MAAM,aAAe,EAAG,CAC/B,GAAM,CAAE,MAAO,GAAS,KAAK,MAAM,cACnC,KAAK,MAAM,cAAgB,IAAA,GAE3B,IAAM,EAAe,IAAS,KAAK,MAAM,MAInC,EAAgB,KAAK,MAAM,oBACjC,KAAK,MAAM,oBAAsB,GAE7B,IAGG,KAAK,MAAM,iBAAiB,KAAK,OAAO,EAAM,KAAK,MAAM,KAAK,IAGjE,GAAgB,IAClB,KAAK,OACH,EAAgB,EAAgB,GAAuB,GAAe,EACxE,EAEF,KAAK,MAAM,gBAAkB,EAC/B,CACF,CAEA,OAAO,IACT,CAOA,SAAmB,CACjB,OAAO,KAAK,MAAM,KAAK,OAAS,CAClC,CAGA,SAAmB,CACjB,OAAO,KAAK,MAAM,OAAO,OAAS,CACpC,CAGA,MAAa,CAWX,OAVI,KAAK,MAAM,KAAK,SAAW,EAAU,MAEzC,KAAK,MAAM,OAAO,QAAQ,KAAK,MAAM,KAAK,EAC1C,KAAK,MAAM,MAAQ,KAAK,MAAM,KAAK,IAAI,EAEvC,KAAK,MAAM,QAAU,IAAA,GACrB,KAAK,oBAAoB,EAErB,KAAK,MAAM,aAAe,GAAG,KAAK,OAAO,EAAW,EAEjD,KACT,CAGA,MAAa,CASX,OARI,KAAK,MAAM,OAAO,SAAW,EAAU,MAE3C,KAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,EACrC,KAAK,MAAM,MAAQ,KAAK,MAAM,OAAO,MAAM,EAC3C,KAAK,MAAM,QAAU,IAAA,GACrB,KAAK,oBAAoB,EACrB,KAAK,MAAM,aAAe,GAAG,KAAK,OAAO,EAAW,EAEjD,KACT,CAGA,cAAqB,CAKnB,OAJA,KAAK,oBAAoB,EACzB,KAAK,MAAM,KAAO,CAAC,EACnB,KAAK,MAAM,OAAS,CAAC,EACrB,KAAK,MAAM,QAAU,IAAA,GACd,IACT,CAMA,YAA2C,CACzC,MAAO,CAAE,KAAM,CAAC,GAAG,KAAK,MAAM,IAAI,EAAG,OAAQ,CAAC,GAAG,KAAK,MAAM,MAAM,CAAE,CACtE,CAYA,UAAoC,CAGlC,OAFA,KAAK,YAAY,EACjB,KAAK,MAAM,aAAe,KAAK,MAAM,UAAU,KAAK,MAAM,KAAK,EACxD,KAAK,MAAM,UACpB,CA6DA,OAAO,EAAsD,CAC3D,OAAO,GAAY,KAAK,MAAM,MAAO,CAA6B,CACpE,CAsBA,CAAC,KAAK,EAAuB,CAAC,EAA6B,CACzD,GAAM,CAAE,OAAM,YAAW,cAAe,EAEpC,EAAuB,KAAK,MAAM,MAClC,EAAkB,CAAC,EACnB,EAAyB,KAE7B,GAAI,IAAS,IAAA,GAAW,CACtB,IAAM,EAAO,KAAK,OAAO,CAAI,EACvB,EAAO,GAAQ,EAAS,EAAM,KAAK,MAAM,KAAK,EAEpD,GAAI,CAAC,GAAQ,CAAC,EAAM,OACpB,EAAQ,EACR,EAAY,EACZ,EACE,EAAK,SAAW,EAAI,KAAQ,EAAS,EAAc,CAAI,EAAG,KAAK,MAAM,KAAK,CAC9E,CAEA,IAAK,IAAM,KAAS,KAAK,SAAS,EAAO,EAAW,CAAW,EACzD,GAAa,EAAY,EAAM,IAAI,GACnC,GAAc,CAAC,EAAY,EAAM,IAAI,IACzC,MAAM,EAEV,CAGA,MAAM,EAAyD,CAAC,EAA6B,CAC3F,OAAO,KAAK,KAAK,CAAE,GAAG,EAAS,UAAW,EAAK,CAAC,CAClD,CAMA,OAAO,EAAyD,CAAC,EAA6B,CAC5F,OAAO,KAAK,KAAK,CAAE,GAAG,EAAS,WAAY,EAAK,CAAC,CACnD,CAGA,KACE,EACA,EAAuB,CAAC,EACF,CACtB,IAAK,IAAM,KAAS,KAAK,KAAK,CAAO,EACnC,GAAI,EAAU,CAAK,EAAG,OAAO,EAE/B,OAAO,IACT,CAGA,OAAO,EAA8C,EAAuB,CAAC,EAAoB,CAC/F,IAAM,EAA2B,CAAC,EAClC,IAAK,IAAM,KAAS,KAAK,KAAK,CAAO,EAC/B,EAAU,CAAK,GAAG,EAAQ,KAAK,CAAK,EAE1C,OAAO,CACT,CAGA,CAAC,OAAO,WAAsC,CAC5C,OAAO,KAAK,KAAK,CACnB,CAYA,SAAS,EAAgC,CACvC,OAAO,EAAS,EAAM,KAAK,MAAM,KAAK,GAAK,IAC7C,CAMA,OAAO,EAAgC,CACrC,IAAM,EAAO,KAAK,MAAM,CAAC,CAAC,IAAI,CAAE,EAEhC,OAAO,IAAS,IAAA,GAAY,KAAO,EAAS,EAAM,KAAK,MAAM,KAAK,CACpE,CAMA,YAAY,EAAyB,CACnC,OAAO,KAAK,MAAM,CAAC,CAAC,IAAI,CAAE,GAAK,IACjC,CAMA,eAAe,EAAqB,CAClC,OAAO,GAAe,EAAM,KAAK,MAAM,KAAK,CAC9C,CAGA,QAAQ,EAA6C,CACnD,IAAM,EAAO,KAAK,OAAO,CAAQ,EACjC,OAAO,IAAS,KAAO,KAAQ,EAAS,EAAM,KAAK,MAAM,KAAK,GAAK,IACrE,CAMA,QAAQ,EAA0C,CAChD,IAAM,EAAO,KAAK,QAAQ,CAAQ,EAClC,OAAO,GAAQ,CAAC,EAAY,CAAI,EAAI,EAAO,IAC7C,CAMA,SAAS,EAAoC,CAC3C,IAAM,EAAO,KAAK,QAAQ,CAAQ,EAClC,OAAO,GAAQ,EAAY,CAAI,EAAK,EAAc,IACpD,CAMA,UAAU,EAAoC,CAC5C,IAAM,EAAO,KAAK,OAAO,CAAQ,EAKjC,OAJI,IAAS,MAAQ,EAAK,SAAW,GAEjC,CAAC,EAAS,EAAM,KAAK,MAAM,KAAK,EAAU,KAEvC,EAAS,EAAc,CAAI,EAAG,KAAK,MAAM,KAAK,CACvD,CAUA,WAA+B,CAC7B,OAAO,KAAK,MAAM,MACpB,CAMA,gBAAoC,CAClC,OAAO,KAAK,MAAM,WACpB,CAOA,aAAa,EAAkB,CAC7B,OAAO,GAAa,EAAO,KAAK,MAAM,QAAQ,CAChD,CAGA,aAAa,EAAkC,CAC7C,OAAO,KAAK,aAAa,CAAK,CAChC,CAGA,gBAAgB,EAAe,EAA0C,CACvE,OAAO,KAAK,gBAAgB,EAAO,CAAQ,CAC7C,CAGA,cAAc,EAAiC,CAC7C,OAAO,KAAK,cAAc,CAAK,CACjC,CAGA,UAAU,EAAe,EAA0C,CACjE,OAAO,KAAK,UAAU,EAAO,CAAQ,CACvC,CAGA,mBAAmB,EAAe,EAAmC,CACnE,OAAO,KAAK,mBAAmB,EAAO,CAAQ,CAChD,CAMA,uBAAuB,EAAuB,CAC5C,OAAO,KAAK,gBAAgB,CAAK,CACnC,CAMA,oBAAoB,EAAyB,CAC3C,OAAO,KAAK,aAAa,CAAI,CAC/B,CASA,aAA4C,CAC1C,OAAO,KAAK,MAAM,QACpB,CAUA,eAAe,EAAgD,CAC7D,IAAM,EAAO,KAAK,QAAQ,CAAQ,EAClC,GAAI,CAAC,EAAM,OAAO,KAElB,IAAM,EAAa,KAAK,SAAS,EAEjC,OAAO,GACL,EACA,CACE,OAAQ,KAAK,MAAM,OACnB,SAAU,KAAK,MAAM,SACrB,cAAe,EAAW,EAAW,IACnC,KAAK,MAAM,QAAQ,eAAe,EAAG,EAAG,CAAI,GAAK,KACnD,cAAgB,GAAc,KAAK,cAAc,CAAC,EAClD,aAAe,GAAc,KAAK,aAAa,CAAC,EAChD,eAAgB,EAAW,EAAW,IACpC,KAAK,cAAc,EAAG,EAAG,CAAI,EAC/B,oBAAqB,EAAW,IAAc,KAAK,mBAAmB,EAAG,CAAC,EAC1E,WAAY,EAAW,IAAc,KAAK,UAAU,EAAG,CAAC,EACxD,iBAAkB,EAAW,IAAc,KAAK,gBAAgB,EAAG,CAAC,EACpE,yBAA0B,EAAW,IACnC,KAAK,MAAM,QAAQ,0BAA0B,EAAG,CAAI,GAAK,CAAC,CAC9D,EACA,CACE,cAAe,OAAO,GAAe,UAAY,CAAC,EAAI,EACtD,GAAI,EAAK,EACX,CACF,CACF,CAQA,oBAAoB,EAA0B,CAAC,EAA+B,CAC5E,IAAM,EAAY,KAAK,SAAS,CAAQ,EACxC,GAAI,CAAC,EAAW,OAAO,KAEvB,IAAM,EAAa,KAAK,SAAS,EAEjC,OAAO,GAA0B,EAAW,KAAK,MAAM,YAAa,CAClE,cAAe,OAAO,GAAe,UAAY,CAAC,EAAI,EACtD,GAAI,EAAU,EAChB,CAAC,CACH,CAOA,MAAgB,CACd,OAAO,EAAkB,KAAK,MAAM,KAAK,CAC3C,CAMA,YAAY,EAAiC,CAC3C,OAAO,GAAY,KAAK,MAAM,MAAO,CAAK,CAC5C,CAGA,aAAiC,CAC/B,OAAO,GAAY,KAAK,MAAM,MAAO,aAAa,CACpD,CAMA,QAAa,CACX,OAAO,KAAK,MAAM,KACpB,CAWA,MAAkE,CAChE,OAAO,IAAI,EACT,GAAY,KAAK,MAAM,KAAK,EAC5B,KAAK,MAAM,OACb,CACF,CAOA,QAAkE,CAChE,OAAO,IAAI,EACT,EAAc,KAAK,MAAM,KAAK,EAC9B,KAAK,MAAM,OACb,CACF,CAUA,UAAmB,EAAwC,CAEzD,OAAQ,EAAuB,KAAK,MAAM,MAAO,CAAO,CAC1D,CAGF"}
1
+ {"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 'ungroupAction',\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 'ungroup',\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 'ungroup',\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 ungroupAction: [\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 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 ungroupAction: 'action',\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 ungroupRuleGroup: { label: '⊟', title: 'Ungroup' } 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 ungroup: 'ruleGroup-ungroup',\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 ungroup: '',\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 ungroup: 'ungroup',\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 onUngroupFalse: 'onUngroup 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 ungroup: 'group replaced by its own rules',\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 showUngroupButtons: 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 'target-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 | 'ungroup'\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 ungroup: ['actionElement', 'ungroup'],\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. Since `not()` accepts exactly one\n * traversal, negated groups with multiple predicates wrap them in a single\n * `__.and()`/`__.or()` sub-traversal.\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\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\n // `not()` accepts exactly one traversal, so multiple predicates must be\n // combined into a single `__.and()`/`__.or()` sub-traversal first.\n if (rg.not) {\n return predicates.length === 1 ? `.not(${args})` : `.not(__.${combinator}(${args}))`;\n }\n\n return `.${combinator}(${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 ungroup: joinClassnamesByName('ungroup', 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 given path or `id` refers to a rule rather than a group. */\n | 'target-not-a-group'\n /** The destination's parent group does not exist. */\n | 'destination-not-found'\n /** The root group cannot be removed, moved, grouped, or ungrouped. */\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' | 'ungroup';\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\n/**\n * Options for {@link ungroup}.\n *\n * @group Query Tools\n */\nexport interface UngroupOptions extends QueryToolOptions {}\n\nexport interface UngroupMethod {\n <RG extends RuleGroupTypeAny>(\n /** The query to update. */\n query: RG,\n /** The path or ID of the group to ungroup. */\n pathOrID: Path | string,\n /** Options. */\n options?: UngroupOptions\n ): RG;\n}\n\n/**\n * Replaces a group with its own rules in its parent group, without mutating the original query.\n *\n * The group's `combinator`, `not`, `id`, `muted`, and `disabled` properties are discarded; its\n * rules keep their `id`s since they remain in the same query. An empty group is simply removed.\n *\n * @returns A new query with the group's rules promoted into its parent group.\n *\n * @group Query Tools\n */\nexport const ungroup: UngroupMethod = (query, pathOrID, options = {}): typeof query =>\n producerFor(options.freeze)(query, q => ungroupInPlace(q, pathOrID, options));\n\n/**\n * Replaces a group with its own rules in its parent group, in place.\n *\n * @returns The query (mutated in place) with the group's rules promoted into its parent group.\n *\n * @group Query Tools\n */\nexport const ungroupInPlace: UngroupMethod = (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: 'ungroup', pathOrID });\n return query;\n }\n\n // Can't ungroup the root group\n if (path.length === 0) {\n onAbort?.({ reason: 'root-not-allowed', operation: 'ungroup', pathOrID });\n return query;\n }\n\n const ungroupGuardReason = getGuardAbortReason(query, path, options);\n if (ungroupGuardReason) {\n onAbort?.({ reason: ungroupGuardReason, operation: 'ungroup', 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.\n const target = findPath(path, query);\n if (!target) {\n onAbort?.({ reason: 'target-not-found', operation: 'ungroup', pathOrID });\n return query;\n }\n\n // Only groups can be ungrouped.\n if (!isRuleGroup(target)) {\n onAbort?.({ reason: 'target-not-a-group', operation: 'ungroup', 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\n // An empty group degenerates to a plain removal, including the adjacent-combinator cleanup\n // independent combinator queries require.\n if (target.rules.length === 0) {\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 return query;\n }\n\n // For independent combinators, the group's rules are already in `[rule, comb, rule, ...]` form,\n // so splicing them in place preserves the parent's alternation.\n type AnyRules = (RuleType | RuleGroupTypeAny | string)[];\n (parent.rules as AnyRules).splice(index, 1, ...(target.rules as AnyRules));\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, ungroup, 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 * - `onUngroup` may return `true` to proceed, a falsy value to cancel, or a _replacement query_\n * 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 onUngroup?: (...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 seven 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 ungroupRuleGroup: (query: any, path: Path, context?: any) => any;\n}\n\n/**\n * Builds the query builder's seven 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 onUngroup,\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 ungroupRuleGroup: (query, path, context) => {\n if (blocked(query, path)) {\n log({ type: LogType.pathDisabled, path, 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 ruleGroup = findPath(path, query);\n if (path.length === 0 || !isRuleGroup(ruleGroup)) return undefined;\n\n // Computed before the callback so it can inspect the prospective result, e.g. to decline\n // when the group's `not` property would otherwise be discarded.\n const nextQuery = ungroup(query, path, { freeze });\n const callbackResult = onUngroup\n ? onUngroup(ruleGroup, path, query, nextQuery, context)\n : true;\n\n if (!callbackResult) {\n log({ type: LogType.onUngroupFalse, ruleGroup, path, query, nextQuery });\n return undefined;\n }\n\n const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;\n log({ type: LogType.ungroup, query, newQuery, path, ruleGroup });\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 UngroupOptions,\n GuardOptions,\n InsertOptions,\n MoveOptions,\n RemoveOptions,\n UpdateOptions,\n} from './queryTools';\nimport { add, group, insert, move, remove, ungroup, 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 /**\n * Replaces the group at `pathOrID` with its own rules in the parent group. The group's\n * `combinator`, `not`, `id`, `muted`, and `disabled` properties are discarded; an empty group\n * is simply removed.\n */\n ungroup(pathOrID: Path | string, options: UngroupOptions & StrictOptions = {}): this {\n const { strict, onInvalidTarget, ...toolOptions } = options;\n this.commit(\n ungroup(this.state.query, pathOrID, {\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,sbA6B3B,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,8jBA+CvB,EACA,wBAAyB,8jBA+CzB,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,cAAe,CACb,YACA,UACA,WACA,sBACA,gBACA,QACA,QACA,OACA,cACA,QACA,SACA,SACA,QACA,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,SACjB,eAAgB,SAChB,UAAW,KACX,iBAAkB,WAClB,kBAAmB,SACnB,iBAAkB,SAClB,KAAM,KACN,UAAW,KACX,sBAAuB,KACvB,wBAAyB,KACzB,aAAc,KACd,gBAAiB,KACjB,cAAe,SACf,YAAa,KACb,cAAe,KACf,oBAAqB,UACvB,EC1oBa,EAAyB,IAIzB,EAA0B,SAM1B,EAAA,IAMA,EAA+D,EAM/D,EACX,EAMW,EAAA,IAMA,EACX,EAMW,EACX,EAMW,EAAA,IAMA,EAA+D,EAM/D,EACX,EAQW,EAA4C,CACvD,OAAQ,CACN,MAAO,QACP,gBAAA,IACA,iBAAkB,EAClB,sBAAuB,CACzB,EACA,UAAW,CACT,MAAO,WACP,gBAAA,IACA,iBAAkB,EAClB,sBAAuB,CACzB,EACA,OAAQ,CACN,MAAO,SACP,gBAAA,IACA,iBAAkB,EAClB,sBAAuB,CACzB,EACA,UAAW,CAAE,MAAO,YAAa,EACjC,eAAgB,CAAE,MAAO,kBAAmB,gBAAiB,GAAI,EACjE,MAAO,CAAE,MAAO,OAAQ,EACxB,WAAY,CAAE,MAAO,IAAK,MAAO,aAAc,EAC/C,YAAa,CAAE,MAAO,IAAK,MAAO,cAAe,EACjD,QAAS,CAAE,MAAO,SAAU,MAAO,UAAW,EAC9C,SAAU,CAAE,MAAO,UAAW,MAAO,WAAY,EACjD,YAAa,CAAE,MAAO,YAAa,EACnC,UAAW,CAAE,MAAO,MAAO,MAAO,mBAAoB,EACtD,UAAW,CAAE,MAAO,IAAK,MAAO,YAAa,EAC7C,eAAgB,CAAE,MAAO,IAAK,MAAO,aAAc,EACnD,iBAAkB,CAAE,MAAO,IAAK,MAAO,SAAU,EACjD,cAAe,CAAE,MAAO,IAAK,MAAO,UAAW,EAC/C,gBAAiB,CAAE,MAAO,IAAK,MAAO,YAAa,EACnD,KAAM,CAAE,MAAO,IAAK,MAAO,MAAO,EAClC,KAAM,CAAE,MAAO,IAAK,MAAO,MAAO,EAClC,WAAY,CAAE,MAAO,KAAM,MAAO,aAAc,EAChD,SAAU,CAAE,MAAO,KAAM,MAAO,WAAY,EAC5C,UAAW,CAAE,MAAO,KAAM,MAAO,YAAa,EAC9C,iBAAkB,CAAE,MAAO,KAAM,MAAO,aAAc,EACtD,kBAAmB,CAAE,MAAO,KAAM,MAAO,cAAe,EACxD,SAAU,CAAE,MAAO,KAAM,MAAO,WAAY,EAC5C,UAAW,CAAE,MAAO,KAAM,MAAO,YAAa,EAC9C,WAAY,CAAE,MAAO,KAAM,MAAO,aAAc,EAChD,YAAa,CAAE,MAAO,KAAM,MAAO,cAAe,EAClD,oBAAqB,CAAE,MAAO,cAAe,CAC/C,EAQa,EAAkB,IAIlB,EAA+D,CAC1E,IAAK,IACL,KAAM,KACN,IAAK,IACL,IAAK,IACL,KAAM,KACN,KAAM,KACN,SAAU,WACV,WAAY,cACZ,SAAU,YACV,eAAgB,mBAChB,iBAAkB,sBAClB,eAAgB,oBAChB,KAAM,UACN,QAAS,cACT,GAAI,KACJ,MAAO,SACP,QAAS,UACT,WAAY,aACd,EAEa,EAA2E,CACtF,IAAK,MACL,GAAI,KACJ,IAAK,KACP,EAQa,EAAqC,CAChD,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,GAAI,EACpC,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,GAAI,EACpC,CAAE,KAAM,IAAK,MAAO,IAAK,MAAO,GAAI,EACpC,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,WAAY,MAAO,WAAY,MAAO,UAAW,EACzD,CAAE,KAAM,aAAc,MAAO,aAAc,MAAO,aAAc,EAChE,CAAE,KAAM,WAAY,MAAO,WAAY,MAAO,WAAY,EAC1D,CAAE,KAAM,iBAAkB,MAAO,iBAAkB,MAAO,kBAAmB,EAC7E,CAAE,KAAM,mBAAoB,MAAO,mBAAoB,MAAO,qBAAsB,EACpF,CAAE,KAAM,iBAAkB,MAAO,iBAAkB,MAAO,mBAAoB,EAC9E,CAAE,KAAM,OAAQ,MAAO,OAAQ,MAAO,SAAU,EAChD,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,aAAc,EAC1D,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,EACvC,CAAE,KAAM,QAAS,MAAO,QAAS,MAAO,QAAS,EACjD,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,SAAU,EACtD,CAAE,KAAM,aAAc,MAAO,aAAc,MAAO,aAAc,CAClE,EAQa,EAA+E,CAC1F,IAAK,KACL,KAAM,IACN,IAAK,KACL,KAAM,IACN,IAAK,KACL,KAAM,IACN,WAAY,mBACZ,iBAAkB,aAClB,SAAU,iBACV,eAAgB,WAChB,SAAU,iBACV,eAAgB,WAChB,QAAS,aACT,WAAY,UACZ,GAAI,QACJ,MAAO,KACP,QAAS,OACT,KAAM,SACR,EAOa,EAAgD,IAAI,IAAI,CACnE,IACA,KACA,IACA,IACA,KACA,IACF,CAAC,EAOY,GAA+C,IAAI,IAAI,CAClE,WACA,aACA,WACA,iBACA,mBACA,gBACF,CAAC,EAOY,GAA0C,IAAI,IAAI,CAAC,OAAQ,SAAS,CAAC,EAOrE,GAAwC,IAAI,IAAI,CAAC,KAAM,OAAO,CAAC,EAO/D,GAA6C,IAAI,IAAI,CAAC,UAAW,YAAY,CAAC,EAU9E,EAAyC,CACpD,CAAE,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,EAC1C,CAAE,KAAM,KAAM,MAAO,KAAM,MAAO,IAAK,CACzC,EAWa,GAAyD,CACpE,GAAG,EACH,CAAE,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,CAC5C,EAUa,GAAuC,CAClD,CAAE,KAAM,MAAO,MAAO,MAAO,MAAO,KAAM,EAC1C,CAAE,KAAM,OAAQ,MAAO,OAAQ,MAAO,MAAO,EAC7C,CAAE,KAAM,OAAQ,MAAO,OAAQ,MAAO,MAAO,EAC7C,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,UAAW,EACvD,CAAE,KAAM,SAAU,MAAO,SAAU,MAAO,SAAU,EACpD,CAAE,KAAM,UAAW,MAAO,UAAW,MAAO,SAAU,CACxD,EASa,GAAqB,CAChC,aAAc,eACd,UAAW,YACX,OAAQ,mBACR,KAAM,iBACN,YAAa,wBACb,QAAS,oBACT,SAAU,qBACV,UAAW,iBACX,WAAY,uBACZ,QAAS,oBACT,YAAa,mBACb,UAAW,sBACX,KAAM,OACN,OAAQ,cACR,UAAW,iBACX,eAAgB,sBAChB,UAAW,iBACX,MAAO,aACP,WAAY,cACZ,aAAc,eACd,MAAO,qBACP,QAAS,uBACT,aAAc,eACd,gBAAiB,kBACjB,WAAY,uBACZ,WAAY,uBACZ,YAAa,cACb,QAAS,UACT,QAAS,UACT,SAAU,WACV,kBAAmB,oBACnB,mBAAoB,qBACpB,UAAW,YACX,WAAY,0BACZ,SAAU,wBACV,MAAO,qBACP,SAAU,YACV,UAAW,iBACX,SAAU,YACV,UAAW,iBACX,YAAa,mBACb,cAAe,uBACf,SAAU,wBACV,UAAW,yBACX,WAAY,0BACZ,YAAa,mBACb,QAAS,uBACT,sBAAuB,6BACzB,EAQa,GAAuC,CAClD,aAAc,GACd,UAAW,GACX,OAAQ,GACR,KAAM,GACN,YAAa,GACb,QAAS,GACT,SAAU,GACV,UAAW,GACX,WAAY,GACZ,QAAS,GACT,YAAa,GACb,UAAW,GACX,KAAM,GACN,OAAQ,GACR,UAAW,GACX,eAAgB,GAChB,UAAW,GACX,MAAO,GACP,WAAY,GACZ,aAAc,GACd,gBAAiB,GACjB,WAAY,GACZ,WAAY,GACZ,WAAY,GACZ,SAAU,GACV,UAAW,GACX,SAAU,GACV,UAAW,GACX,MAAO,GACP,YAAa,GACb,cAAe,GACf,cAAe,GACf,aAAc,GACd,MAAO,GACP,QAAS,GACT,YAAa,GACb,QAAS,GACT,SAAU,GACV,QAAS,GACT,kBAAmB,GACnB,mBAAoB,GACpB,UAAW,GACX,SAAU,GACV,cAAe,GACf,SAAU,GACV,YAAa,GACb,QAAS,GACT,sBAAuB,EACzB,EAOa,GAAsB,CACjC,MAAO,QACP,kBAAmB,qBACnB,8BAA+B,iCACjC,EAOa,GAAS,CACpB,KAAM,OACN,UAAW,aACX,iBAAkB,oBAClB,SAAU,YACV,YAAa,eACb,WAAY,cACZ,QAAS,UACT,UAAW,aACX,QAAS,WACT,WAAY,cACZ,YAAa,cACb,OAAQ,SACR,UAAW,YACX,YAAa,eACb,UAAW,aACX,aAAc,gBACd,gBAAiB,oBACjB,WAAY,cACZ,WAAY,cACZ,WAAY,cACZ,SAAU,YACV,UAAW,aACX,SAAU,YACV,UAAW,aACX,oBAAqB,wBACrB,gBAAiB,mBACnB,EAEa,EAAU,CACrB,mBAAoB,uCACpB,aAAc,mCACd,YAAa,gBACb,eAAgB,oCAChB,gBAAiB,qCACjB,iBAAkB,sCAClB,kBAAmB,uCACnB,gBAAiB,qCACjB,iBAAkB,sCAClB,cAAe,mCACf,eAAgB,oCAChB,IAAK,sBACL,OAAQ,wBACR,OAAQ,wBACR,KAAM,sBACN,MAAO,qCACP,QAAS,iCACX,EAOa,GAAiB,CAAC,EAQlB,GAAwD,CACnE,mBAAoB,GACpB,gBAAiB,GACjB,mBAAoB,GACpB,gBAAiB,GACjB,UAAW,GACX,kBAAmB,GACnB,uBAAwB,GACxB,cAAe,GACf,4BAA6B,GAC7B,mBAAoB,GACpB,sBAAuB,GACvB,iBAAkB,GAClB,4BAA6B,GAC7B,gBAAiB,GACjB,gBAAiB,GACjB,cAAe,GACf,iBAAkB,GAClB,aAAc,GACd,mBAAoB,GACpB,2BAA4B,EAC9B,EAOa,GAAoB,GAQpB,GAAoB,ICxhBpB,GAA6C,CACxD,mBACA,mBACA,qBACA,qBACA,wBACA,mBACA,wBACA,kBACA,kBACA,qBACF,EAGa,GAAiD,IAAI,IAChE,EACF,ECda,IAAW,EAAc,EAAA,MACpC,OAAO,GAAQ,SACX,EACG,MAAM,KAAK,GAAW,CAAC,CACvB,IAAI,GAAK,EAAE,MAAM,CAAS,CAAC,CAAC,CAC5B,QAAQ,EAAM,EAAM,IACf,IAAQ,EACH,EAEF,CAAC,GAAG,EAAK,MAAM,EAAG,EAAE,EAAG,GAAG,EAAK,GAAG,EAAE,IAAI,IAAY,EAAK,KAAM,GAAG,EAAK,MAAM,CAAC,CAAC,EACrF,CAAC,CAAC,EACP,CAAC,EAeM,IAAY,EAAmB,EAAA,MAC1C,EAAO,IAAI,GAAO,GAAG,GAAO,KAAK,WAAW,EAAS,GAAI,KAAK,EAAS,IAAI,CAAC,CAAC,CAAC,KAAK,CAAQ,EAQhF,EAAmB,GAC7B,OAAO,GAAQ,SAAW,EAAI,KAAK,EAAI,EAiB7B,GACX,EACA,CAAE,sBAAyD,CAAC,IAE3D,MAAM,QAAQ,CAAC,EACZ,EAAE,IAAI,CAAY,EAClB,OAAO,GAAM,SACX,GAAQ,EAAA,GAAkB,CAAC,CACxB,OAAO,MAA2B,GAAO,GAAK,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAC/D,IAAI,GAAK,EAAE,KAAK,CAAC,EACpB,OAAO,GAAM,SACX,CAAC,CAAC,EACF,CAAC,EAKE,GAAoB,GAC/B,EAAI,MAAM,GAAM,IAAO,KAAU,GAAM,MAAW,EAAK,ECrFzD,SAAS,GAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,GAAa,OAAO,GAAjB,UAA8B,OAAO,GAAjB,SAAmB,GAAG,OAAO,GAAa,OAAO,GAAjB,SAAmB,IAAG,MAAM,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAE,EAAE,EAAE,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE,MAAM,IAAI,KAAK,EAAE,EAAE,KAAK,IAAI,GAAG,KAAK,GAAG,EAAA,CAAG,OAAO,CAAC,CAAC,SAAgB,IAAM,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,OAAO,EAAE,EAAE,KAAK,EAAE,UAAU,MAAM,EAAE,GAAE,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG,OAAO,CAAC,CCM/W,MAAa,EAAS,GAAa,OAAO,GAAM,SAAY,EAAE,YAAY,EAAU,EAMvE,GAAuB,IAAI,OACtCA,EAAqB,OAAO,QAAQ,MAAO,OAAO,GAAG,MAAM,CAAC,CAAC,QAAQ,MAAO,OAAO,GAAG,MAAM,CAC9F,EAMa,EAAU,GACL,OAAO,GAAQ,YAA/B,GAA2C,OAAO,eAAe,CAAG,IAAM,OAAO,UAKtE,GAA0B,GACrC,GAAU,MAA+B,IAAU,GCrBxC,GAAc,GACzB,EAAO,CAAC,GAAK,UAAW,GAAK,OAAO,EAAE,OAAU,SAKrC,EAAe,GAC1B,EAAO,CAAE,GAAK,MAAM,QAAQ,EAAG,KAAK,EAKzB,EAAmB,GAC9B,EAAY,CAAE,GAAK,OAAO,EAAG,YAAe,SAKjC,EAAqB,GAChC,EAAY,CAAE,GAAK,EAAG,aAAe,IAAA,GCjB1B,GAAsB,cAMtB,GAAqB,GAM5B,IAAgB,EAAc,IAA2B,CAC7D,IAAM,EAAO,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAI,EAAG,GAAG,OAAO,KAAK,CAAI,CAAC,CAAC,EACjE,EAAK,OAAO,OAAO,EACnB,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAM,KAAO,EACX,OAAO,GAAG,EAAK,GAAsB,EAAK,EAAoB,GACjE,EAAQ,KAAK,CAAG,EAGpB,OAAO,EAAQ,SAAS,CAC1B,EAEM,IACJ,EACA,EAEA,EAEA,IACW,CAGX,GAAI,IAAS,EAAM,MAAA,GAGnB,GAAI,OAAO,GAAS,UAAY,OAAO,GAAS,SAC9C,OAAO,OAAO,GAAS,OAAO,EAAO,GAAG,EAAS,cAAc,EAAM,GAAK,GAG5E,IAAM,EAAc,EAAY,CAAI,EAC9B,EAAc,EAAY,CAAI,EAEpC,GAAI,IAAgB,EAAa,OAAO,GAExC,GAAI,CAAC,GAAe,CAAC,EAAa,CAChC,IAAM,EAAQ,GAAa,EAAM,CAAI,EACrC,OAAO,EAAM,SAAW,EAAA,GAAyB,GAAG,EAAK,IAAM,GAAG,GAAG,EAAM,KAAK,GAAG,GACrF,CAGA,GAAI,EAAK,MAAM,SAAW,EAAK,MAAM,OAAQ,OAAO,GAEpD,IAAM,EAAW,GAAa,EAAM,CAAI,EAEpC,EAAe,GACnB,IAAK,GAAM,CAAC,EAAG,KAAa,EAAK,MAAM,QAAQ,EAC7C,GAAI,IAAa,EAAK,MAAM,GAAI,CAE9B,GAAI,IAAiB,GAAI,OAAO,GAChC,EAAe,CACjB,CAWF,OARI,IAAiB,GACZ,EAAS,SAAW,EAAA,GAAyB,GAAG,EAAK,IAAM,GAAG,GAAG,EAAS,KAAK,GAAG,IAKvF,EAAS,OAAS,EAAU,GAEzB,GACL,EAAK,MAAM,GACX,EAAK,MAAM,GACX,EAAK,IAAM,GACX,CACF,CACF,EAqBa,IAAe,EAAwB,IAClD,GAAgB,EAAM,EAAM,GAAI,EAAE,ECtFvB,IACX,EACA,EACA,EACA,EACA,EAAA,MAEA,IAAA,eACA,IAAY,GACZ,GAAO,GACP,EAAM,EAAS,ECpBX,GAAmB,CAAC,KAAM,MAAO,KAAK,EAEtC,IAAgB,EAAY,IAAc,EAAG,CAAC,IAAM,EAEpD,IACJ,EACA,EAA8B,IACV,CACpB,IAAM,EAAiB,GAAiB,GAGxC,GAAI,CAAC,EAAG,MAAM,SAAS,CAAqB,EAG1C,OAAO,EAAsB,GAAiB,OAAS,EACnD,GAA6C,EAAI,EAAsB,CAAC,EACxE,EAGN,IAAM,EAAW,CAAC,GAAG,EAAG,KAAK,EACzB,EAAS,EAGb,KAAO,EAAS,EAAS,OAAS,GAAG,CACnC,GAAI,GAAa,EAAS,EAAS,GAAI,CAAc,EAAG,CACtD,GAAU,EACV,QACF,CAEA,IAAI,EAA0B,GAC9B,IAAK,IAAI,EAAI,EAAS,EAAG,EAAI,EAAS,OAAQ,IAC5C,GAAI,OAAO,EAAS,IAAO,UAAY,EAAG,EAAS,EAAE,IAAM,EAAgB,CACzE,EAA0B,EAC1B,KACF,CAGF,GAAI,IAA4B,GAAI,CAElC,EAAS,OACP,EACA,EAAS,OACT,GAEE,CAAE,MAAO,EAAS,MAAM,CAAM,CAAS,EACvC,EAAsB,CACxB,CACF,EACA,KACF,CAEE,EAAS,OACP,EACA,EAA0B,EAC1B,GAEE,CAAE,MAAO,EAAS,MAAM,EAAQ,CAAuB,CAAS,EAChE,EAAsB,CACxB,CACF,CAEJ,CAEA,MAAO,CAAE,GAAG,EAAI,MAAO,CAAS,CAClC,EAUa,EAA8C,GAAgC,CACzF,GAAI,EAAgB,CAAE,EACpB,OAAO,EAET,IAAM,EAAc,GAA6C,CAAE,EAC7D,EAAwB,CAAC,EAC3B,EAAa,MACjB,IAAK,GAAM,CAAC,EAAK,KAAM,EAAY,MAAM,QAAQ,EAC3C,OAAO,GAAM,SACX,IAAQ,IAAG,EAAa,GAE5B,EAAM,KAAK,EAAY,CAAC,EAAI,EAAc,CAAC,EAAI,CAAC,EAGpD,MAAO,CAAE,GAAG,EAAa,aAAY,OAAM,CAC7C,EAUa,GAA4C,GAAkC,CACzF,GAAI,EAAkB,CAAE,EACtB,OAAO,EAET,GAAM,CAAE,aAAY,GAAG,GAA2B,EAC5C,EAAiD,CAAC,EAClD,CAAE,UAAW,EAAG,MACtB,IAAK,IAAI,EAAM,EAAG,EAAM,EAAQ,IAAO,CACrC,IAAM,EAAI,EAAG,MAAM,GACf,EAAY,CAAC,EACf,EAAM,KAAK,GAAY,CAAC,CAAC,EAEzB,EAAM,KAAK,CAAC,EAEV,GAAc,EAAM,EAAS,GAC/B,EAAM,KAAK,CAAU,CAEzB,CACA,MAAO,CAAE,GAAG,EAAwB,OAAM,CAC5C,EAgBA,SAAS,GAAa,EAAyE,CAC7F,OAAO,EAAkB,CAAK,EAAI,EAAc,CAAK,EAAI,GAAY,CAAK,CAC5E,CC/DA,MAAM,GAA+E,CACnF,aAAc,CAAC,cAAc,EAC7B,WAAY,CAAC,YAAY,EACzB,OAAQ,CAAC,gBAAiB,QAAQ,EAClC,UAAW,CAAC,gBAAiB,WAAW,EACxC,eAAgB,CAAC,gBAAiB,gBAAgB,EAClD,UAAW,CAAC,gBAAiB,WAAW,EACxC,YAAa,CAAC,gBAAiB,aAAa,EAC5C,MAAO,CAAC,OAAO,EACf,UAAW,CAAC,gBAAiB,WAAW,EACxC,SAAU,CAAC,gBAAiB,UAAU,EACtC,SAAU,CAAC,gBAAiB,UAAU,EACtC,WAAY,CAAC,gBAAiB,YAAY,EAC1C,cAAe,CAAC,eAAe,CACjC,EAEM,GAAwF,CAC5F,OAAQ,CACN,QAAS,CAAC,QAAQ,EAClB,WAAY,CAEV,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,OAAQ,aAAc,EAAK,EAC1D,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,QAAU,EAAE,aAAe,MAAO,EACjE,CAAE,IAAK,oBAAqB,KAAM,GAAK,EAAE,cAAe,CAC1D,CACF,EACA,aAAc,CAAC,cAAc,EAC7B,gBAAiB,CAAC,iBAAiB,EACnC,WAAY,CAAC,gBAAiB,YAAY,EAC1C,WAAY,CAAC,gBAAiB,YAAY,EAC1C,WAAY,CAAC,YAAY,EACzB,YAAa,CAAC,gBAAiB,aAAa,EAC5C,UAAW,CAAC,WAAW,EACvB,QAAS,CAAC,gBAAiB,SAAS,EACpC,SAAU,CAAC,gBAAiB,UAAU,EACtC,WAAY,CAAC,gBAAiB,YAAY,EAC1C,QAAS,CAAC,gBAAiB,SAAS,EACpC,UAAW,CAAC,gBAAiB,WAAW,EACxC,UAAW,CAAC,gBAAiB,WAAW,EACxC,YAAa,CAAC,gBAAiB,aAAa,EAC5C,KAAM,CAAC,MAAM,CACf,EASM,GAAyE,CAC7E,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAS,EACzC,CAAE,IAAK,QAAS,KAAM,GAAK,EAAE,KAAM,EACnC,CAAE,IAAK,cAAe,KAAM,GAAK,EAAE,UAAW,EAC9C,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,MAAO,EACtC,CAAE,IAAK,UAAW,KAAM,GAAK,EAAE,QAAU,EAAE,aAAe,MAAO,EACjE,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAU,EAAE,UAAW,EACvD,CAAE,IAAK,oBAAqB,KAAM,GAAK,EAAE,cAAe,EACxD,CAAE,IAAK,cAAe,KAAM,GAAK,EAAE,WAAY,CACjD,EAGM,GAA8E,CAClF,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAS,EACzC,CAAE,IAAK,QAAS,KAAM,GAAK,EAAE,KAAM,EACnC,CAAE,IAAK,cAAe,KAAM,GAAK,EAAE,UAAW,EAC9C,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAU,EAAE,UAAW,CACzD,EAcM,GAAyF,CAC7F,CAAE,IAAK,WAAY,KAAM,GAAK,EAAE,QAAS,EACzC,CAAE,IAAK,QAAS,KAAM,GAAK,OAAO,EAAE,kBAAqB,WAAa,EAAE,gBAAiB,EACzF,CAAE,IAAK,UAAW,KAAM,GAAK,OAAO,EAAE,kBAAqB,WAAa,CAAC,EAAE,gBAAiB,CAC9F,EAcM,IACJ,EACA,EACA,CAAE,aAAY,gCACG,CACjB,IAAM,EAAY,EAAW,IAAI,GAAa,CAAC,EAAW,CAAC,CAAC,EAAU,KAAK,CAAK,CAAC,CAAU,EAE3F,MAAO,CACL,GAAG,EACA,QAAQ,CAAC,KAAe,CAAC,EAAU,YAAY,CAAC,CAChD,KAAK,CAAC,EAAW,KAAY,GAAU,IAAa,EAAU,IAAI,EACrE,GACE,OAAO,YACL,EAAU,KAAK,CAAC,EAAW,KAAY,CAAC,GAAmB,EAAU,KAAM,CAAM,CAAC,CACpF,CACJ,CACF,EAGM,IACJ,EACA,EACA,EACA,IACW,CACX,GAAM,CAAE,UAAS,cAAiC,MAAM,QAAQ,CAAI,EAChE,CAAE,QAAS,CAAK,EACf,EAGL,OAAO,GACL,EAAQ,4BACN,GAAmB,GACrB,GAAG,EAAQ,IAAI,GAAU,EAAQ,aAAa,EAAO,EACrD,GAAI,EAAa,GAAc,EAAY,EAAO,CAAO,EAAI,CAAC,CAChE,CACF,EAEM,IACJ,EACA,EACA,IACsB,CACtB,IAAM,EAAS,CAAC,EAEhB,IAAK,GAAM,CAAC,EAAK,KAAS,OAAO,QAAQ,CAAK,EAI5C,EAAO,GAAO,GAAe,EAAK,EAAM,EAAO,CAAO,EAGxD,OAAO,CACT,EAQa,GACX,GACqC,GAAgB,GAAsB,CAAC,EAAG,CAAO,EAS3E,IACX,EACA,IACW,GAAe,EAAK,GAAqB,GAAM,CAAC,EAAG,CAAO,EAS1D,GACX,GAEA,GAAgB,GAA2B,EAAS,CAAO,EAiBvD,IACJ,EACA,EACA,IACW,CACX,GAAM,CACJ,aACA,6BACA,oBAAoB,CAAC,EACrB,uBACE,EAEJ,OAAO,GACL,GAAG,EACH,GAA8B,GAAmB,GACjD,IAAa,GACb,GAAG,GAAc,EAAY,EAAS,CAAO,EAC7C,CACF,CACF,EAOa,GAA4B,GACvC,GAAqB,OAAQ,GAAqB,CAAO,EAW9C,GAAiC,GAC5C,GAAqB,YAAa,GAA0B,CAAO,EAQxD,GACX,GACW,GAAqB,eAAgB,GAA6B,CAAO,ECzUzE,GAAmC,GAAS,CACvD,IAAM,EAAwB,CAAC,EAKzB,EAAgB,GAAmB,CAMnC,EAAK,IAAI,EAAO,EAAK,GAE3B,EAEM,EAAiB,GAAyB,CAE9C,IAAM,EAAiB,CAAC,EACxB,GAAI,EAAG,MAAM,SAAW,EACtB,EAAQ,KAAK,GAAoB,KAAK,OACjC,GAAI,CAAC,EAAgB,CAAE,EAAG,CAE/B,IAAI,EAAa,GACjB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,MAAM,QAAU,CAAC,EAAY,KAE/C,EAAI,GAAM,GAAK,OAAO,EAAG,MAAM,IAAO,UACtC,EAAI,GAAM,GAAK,OAAO,EAAG,MAAM,IAAO,UACtC,EAAI,GAAM,GACT,OAAO,EAAG,MAAM,IAAO,UACvB,CAAC,EAAmB,IAAI,GAAK,EAAE,IAAc,CAAC,CAAC,SAAS,EAAG,MAAM,EAAY,KAE/E,EAAa,IAGb,GACF,EAAQ,KAAK,GAAoB,6BAA6B,CAElE,CAIE,EAAgB,CAAE,GAClB,CAAC,EAAmB,IAAI,GAAK,EAAE,IAAc,CAAC,CAAC,SAAS,EAAG,UAAU,GACrE,EAAG,MAAM,OAAS,GAElB,EAAQ,KAAK,GAAoB,iBAAiB,EAGhD,EAAG,KACL,EAAO,EAAG,IAAM,EAAQ,OAAS,EAAI,CAAE,MAAO,GAAO,SAAQ,EAAI,IAEnE,IAAK,IAAM,KAAK,EAAG,MACb,OAAO,GAAM,WAEN,EAAY,CAAC,EACtB,EAAc,CAAC,EAEf,EAAa,CAAC,EAGpB,EAIA,OAFA,EAAc,CAAK,EAEZ,CAMT,EC/Da,GAAa,OAAO,KASpB,GAAgB,OAAO,QAQvB,GAAe,GAC1B,IAAQ,aAAe,IAAQ,eAAiB,IAAQ,YCXpD,GAAoB,GACxB,EAAO,CAAG,GAAK,SAAU,GAAO,OAAO,EAAI,MAAS,SAChD,GAAqB,GACzB,EAAO,CAAG,GAAK,UAAW,GAAO,OAAO,EAAI,OAAU,SAQxD,SAAgB,EACd,EACA,EACA,EACmB,CACnB,GAAI,OAAO,GAAQ,SACjB,MAAO,CACL,GAAG,EACH,KAAM,EACN,MAAO,EACP,MAAO,IAAW,IAAQ,CAC5B,EAGF,IAAM,EAA2C,CAAC,EAC9C,EAAgB,CAAC,CAAC,EActB,OAZI,GAAiB,CAAG,GAAK,CAAC,GAAkB,CAAG,GACjD,EAAM,MAAQ,EAAI,KAClB,EAAgB,IACP,CAAC,GAAiB,CAAG,GAAK,GAAkB,CAAG,IACxD,EAAM,KAAO,EAAI,MACjB,EAAgB,IAGd,EACK,OAAO,OAAO,CAAC,EAAG,EAAgB,EAAK,CAAK,EAG9C,CACT,CAQA,SAAgB,EACd,EACA,EACA,EACqB,CACrB,GAAI,CAAC,MAAM,QAAQ,CAAO,EACxB,MAAO,CAAC,EAGV,IAAM,EAAO,EASb,OAPI,GAA2B,CAAI,EAC1B,EAAK,IAAI,IAAa,CAC3B,GAAG,EACH,QAAS,EAAS,QAAQ,IAAI,GAAO,EAAa,EAAK,EAAgB,CAAQ,CAAC,CAClF,EAAE,EAGI,EAAe,IAAI,GACzB,EAAa,EAAK,EAAgB,CAAQ,CAC5C,CACF,CAQA,SAAgB,GACd,EACA,EAC8F,CAM9F,OAAO,OAAO,YACX,OAAO,QAAQ,CAAM,CAAC,CAAgC,KAAK,CAAC,EAAG,KAAO,CACrE,EACA,EAAa,EAAG,CAAc,CAChC,CAAC,CACH,CACF,CAOA,MAAa,GAGX,GACQ,GAAiB,CAAa,EAQ3B,GAGX,GACQ,CACR,IAAM,EAAQ,IAAI,IACZ,EAAgB,CAAC,EACvB,IAAK,IAAM,KAAM,EACV,EAAM,IAAK,EAAG,OAAS,EAAG,IAAM,IACnC,EAAM,IAAK,EAAG,OAAS,EAAG,IAAM,EAChC,EAAS,KAAK,CAAE,GAGpB,OAAO,EAAc,SAAW,EAAS,OAAS,EAAgB,CACpE,EAOa,GAAsB,GACjC,MAAM,QAAQ,CAAG,GACjB,EAAI,OAAS,GACb,EAAO,EAAI,EAAE,GACb,YAAa,EAAI,IACjB,MAAM,QAAQ,EAAI,EAAE,CAAC,OAAO,EAOjB,GAAyB,GAA0C,CAC9E,IAAI,EAAQ,GACZ,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAK,EACd,GAAI,GAAiB,CAAC,GAAK,GAAkB,CAAC,EAC5C,EAAQ,QAER,MAAO,GAIb,OAAO,CACT,EAOa,GAAqB,GAAsC,CACtE,IAAI,EAAQ,GACZ,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAK,EACd,GAAI,GAAiB,CAAC,GAAK,GAAkB,CAAC,EAC5C,EAAQ,QAER,MAAO,GAIb,OAAO,CACT,EAOa,IACX,EACA,CAAE,aAAa,IAAoC,CAAC,IACnB,CACjC,IAAI,EAAS,GACb,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAM,EACf,GACE,EAAO,CAAE,GACT,YAAa,IACZ,GAAsB,EAAG,OAAO,GAC9B,GAAc,MAAM,QAAQ,EAAG,OAAO,GAAK,EAAG,QAAQ,SAAW,GAEpE,EAAS,QAET,MAAO,GAIb,OAAO,CACT,EAOa,IACX,EACA,CAAE,aAAa,IAAoC,CAAC,IACf,CACrC,IAAI,EAAS,GACb,GAAI,MAAM,QAAQ,CAAG,EACnB,IAAK,IAAM,KAAM,EACf,GACE,EAAO,CAAE,GACT,YAAa,IACZ,GAAkB,EAAG,OAAO,GAC1B,GAAc,MAAM,QAAQ,EAAG,OAAO,GAAK,EAAG,QAAQ,SAAW,GAEpE,EAAS,QAET,MAAO,GAIb,OAAO,CACT,EAoBA,SAAgB,EACd,EACA,EACqB,CAIrB,OAHgB,GAA2B,EAAK,CAAE,WAAY,EAAK,CAAC,EAChE,EAAI,QAAQ,GAAM,EAAG,OAAO,EAC5B,EAAA,CACW,KAAK,GAAM,EAAG,QAAU,GAAQ,EAAG,OAAS,CAAI,CACjE,CAgBA,SAAgB,EACd,EACqC,CACrC,GAAI,CAAC,MAAM,QAAQ,CAAG,GAAK,EAAI,SAAW,EACxC,OAAO,KACF,GAAI,GAA2B,EAAK,CAAE,WAAY,EAAK,CAAC,EAAG,CAChE,IAAK,IAAM,KAAM,EACf,GAAI,EAAG,QAAQ,OAAS,EACtB,OAAQ,EAAG,QAAQ,EAAE,CAAC,OAAS,EAAG,QAAQ,EAAE,CAAC,KAIjD,OAAO,IACT,CAEA,OAAQ,EAAI,EAAE,CAAC,OAAS,EAAI,EAAE,CAAC,IACjC,CAQA,MAAa,GAA2C,GACtD,GAAiB,GAAmB,CAAG,EAAI,EAAI,QAAQ,GAAM,EAAG,OAAO,EAAI,CAAG,EAQnE,GACX,GACmC,CAEnC,IAAM,EAAS,IAAI,IACb,EAAQ,IAAI,IACZ,EAA2C,CAAC,EAClD,IAAK,IAAM,KAAM,EACf,GAAI,CAAC,EAAO,IAAI,EAAG,KAAK,EAAG,CACzB,EAAO,IAAI,EAAG,KAAK,EACnB,IAAM,EAA2D,CAAC,EAClE,IAAK,IAAM,KAAO,EAAG,QACd,EAAM,IAAK,EAAI,OAAS,EAAI,IAAU,IACzC,EAAM,IAAK,EAAI,OAAS,EAAI,IAAU,EACtC,EAAoB,KAAK,EAAa,CAAG,CAAsC,GAGnF,EAAS,KAAK,CAAE,GAAG,EAAI,QAAS,CAAoB,CAAC,CACvD,CAEF,OAAO,CACT,EAQa,GACX,GAEI,GAA2B,CAAa,EACnC,GAAc,CAAa,EAE7B,GAAkB,EAA+B,IAAI,GAAK,EAAa,CAAC,CAAC,CAAC,EAiCtE,GACX,GAC0B,CAI1B,GAAM,CACJ,WAAY,EACZ,aAAa,CAAC,EACd,WAAW,CAAC,EACZ,YAAa,CACX,kBAAA,IACA,mBAAmB,EACnB,wBAAwB,GACtB,CAAC,EACL,mBAAmB,IACjB,EAEE,EAAgB,CACpB,GAAI,EACJ,KAAM,EACN,MAAO,EACP,MAAO,CACT,EAEM,EAAc,GAA2B,CAAC,CAAa,EAEzD,EACE,EACJ,MAAM,QAAQ,CAAW,EACrB,EAAiB,EAAa,EAAY,CAAQ,EACjD,GAAW,GAAgB,EAAa,CAAU,CAAC,CAAC,CAElD,IAAkC,IAAQ,CACzC,GAAG,EAAY,GACf,KAAM,EACN,MAAO,CACT,EAAE,CAAC,CAEF,MAAM,EAAG,IAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC,EAEtD,AAWE,EAXE,GAA2B,CAAI,EAE5B,GADQ,EACM,EACA,CACb,CACE,MAAO,EACP,QAAS,CAAC,CAAa,CACzB,EACA,GAAG,CACL,CAAC,EAGA,GADQ,EACS,EACA,CAAC,EAAe,GAAI,CAAY,CAAC,EAGzD,IAAI,EAA2C,CAAC,EAChD,GAAI,CAAC,MAAM,QAAQ,CAAW,EAAG,CAC/B,IAAM,EAAK,GAAgB,EAAa,CAAU,EAClD,EAAa,EAAmB,EAAK,CAAE,GAAG,GAAK,GAAkB,CAAc,CACjF,MACE,GAAI,GAA2B,CAAU,EACvC,IAAK,IAAM,KAAM,EACf,IAAK,IAAM,KAAO,EAAG,QACnB,EACG,EAAI,OACgC,EAAI,MACvC,EAAa,EAAK,CAAU,OAIpC,IAAK,IAAM,KAAO,EAChB,EACG,EAAI,OACgC,EAAI,MACvC,EAAa,EAAK,CAAU,EAKtC,MAAO,CAAE,gBAAe,aAAY,YAAW,CACjD,EC9dM,IAAsB,EAAkB,EAAkB,IAA8B,CAC5F,IAAM,EAAY,EAAa,CAAK,EAC9B,EAAqB,EAAa,CAAc,EAOtD,OANI,EAAU,QAAU,EAAmB,MAClC,GAEL,OAAO,EAAU,YAAe,SAC3B,EAAU,EAAU,cAAgB,EAAmB,EAAU,YAGxE,EAAU,aAAa,EAAoB,CAAQ,GAChB,EAEvC,EAaa,IAEX,EAEA,EACA,IAMS,CACT,GAAI,CAAC,EAAM,WAAY,CACrB,IAAM,EAAsB,IACzB,EAAE,OAA4C,EAAE,SAChD,EAAM,OAC8B,EAAM,MAO7C,OANI,GAA2B,CAAM,EAC5B,EAAO,IAAI,IAAO,CACvB,GAAG,EACH,QAAS,EAAG,QAAQ,OAAO,GAAK,EAAmB,CAAC,CAAC,CACvD,EAAE,EAEG,EAAO,OAAO,GAAK,EAAmB,CAAC,CAAC,CACjD,CAWA,OATI,GAA2B,CAAM,EAC5B,EACJ,IAAI,IAAO,CACV,GAAG,EACH,QAAS,EAAG,QAAQ,OAAO,GAAK,GAAmB,EAAO,EAAU,CAAC,CAAC,CACxE,EAAE,CAAC,CACF,OAAO,GAAM,EAAG,QAAQ,OAAS,CAAC,EAGhC,EAAO,OAAO,GAAK,GAAmB,EAAO,EAAU,CAAC,CAAC,CAClE,ECkBa,IACX,EACA,IACc,IAAW,IAAU,CAAE,KAAM,EAAO,MAAO,EAAO,MAAO,CAAM,EAKlE,IACX,EACA,EACA,EACA,IACqB,EAAU,WAAa,EAAa,EAAO,EAAU,CAAE,WAAU,CAAC,EAK5E,GAAgC,GAA2C,CACtF,IAAM,EAAQ,GAAgB,MAC9B,OACG,OAAO,GAAU,UAAY,IAAU,SAAa,OAAO,GAAU,UAAY,EAAQ,CAE9F,EAaa,IACX,EACA,EACA,IAC2B,CAC3B,IAAM,EAAgB,EAAgB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAO9E,OANI,EAAK,aAAe,CAAC,EAAU,EAAe,EAAK,WAAW,EACzD,CACL,GAAG,EACH,CAAE,KAAM,EAAK,YAAa,MAAO,EAAK,YAAa,MAAO,EAAK,WAAY,CAC7E,EAEK,CACT,EAKa,GACX,GACuC,GAAc,EAAW,OAAS,EAAI,EAAa,KAM/E,IACX,EACA,EACA,EACA,IAEA,EAAK,cAAgB,QACjB,SACA,EAAK,cAAgB,YACnB,EACE,EAAG,EAAK,QAAQ,IAAM,MAAQ,EAAG,EAAK,QAAQ,IAAM,QAClD,cACA,SACF,OACF,EAAmB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAKtD,IACX,EACA,EACA,EACA,EACA,IAC+B,CAC/B,IAAM,EACJ,EAAK,cAAgB,QACjB,GAAyB,EAAW,EAAQ,EAAK,QAAQ,EACzD,EAAK,cAAgB,YAClB,GAAoB,CAAC,EACtB,EAAU,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAC1D,OAAO,GAAsB,CAAC,GAAK,GAA2B,CAAC,EAAI,EAAiB,CAAC,EAAI,CAC3F,EAMa,IACX,EACA,EACA,EAA+B,CAAC,EAChC,EAAa,EAAK,IAAM,KAExB,EAAc,KACb,OAAO,EAAU,WAAc,WAAa,EAAU,UAAU,CAAI,EAAI,MAa9D,IACX,EACA,EACA,EAA0D,CAAC,IACxC,CACnB,GAAM,CACJ,SACA,WACA,eACA,gBACA,eACA,gBACA,qBACA,YACA,kBACA,2BACE,EAEE,EAAY,GAAa,EAAK,MAAO,CAAQ,EAC7C,EAAY,EAAU,WAAa,EAAa,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EACxF,EAAa,EAAc,EAAK,MAAO,CAAE,WAAU,CAAC,EACpD,EAAY,EAAa,EAAK,MAAO,CAAE,WAAU,CAAC,EAClD,EAAiB,EAAU,EAAW,EAAK,QAAQ,EACnD,EAAqB,GAA0B,EAAM,EAAW,CAAe,EAC/E,EAAa,GAAoB,EAAc,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,CAAC,EAE9F,MAAO,CACL,YACA,kBAAmB,GAA6B,CAAc,EAC9D,YACA,aACA,iBACA,YACA,aACA,iBAAkB,GAAwB,EAAM,EAAW,EAAQ,cAAe,EAAQ,EAAE,EAC5F,gBAAiB,GAAuB,EAAM,EAAW,EAAY,CAAkB,EACvF,OAAQ,GAAc,EAAM,EAAW,EAAQ,EAAY,CAAS,EACpE,qBACA,aAAc,EAAmB,KAAK,CAAE,WAAY,CAAK,EACzD,qBAAsB,IAA0B,EAAK,MAAO,CAAE,WAAU,CAAC,GAAK,CAAC,CACjF,CACF,EAsBa,IACX,EACA,IAEA,EAAgB,CAAS,EAAI,EAAU,WAAc,EAAe,CAAW,GAAK,GAWzE,IACX,EACA,EACA,EAA0D,CAAC,IACnC,CACxB,IAAM,EAAyB,EAAkB,CAAS,EACpD,EAAa,GAAuB,EAAW,CAAW,EAC1D,EAAmB,EAAU,EAAa,CAAU,EAE1D,MAAO,CACL,aACA,mBACA,cACA,yBAA0B,EAAyB,KAAQ,GAAkB,WAAa,GAC1F,yBACA,kBAAmB,EAAQ,eAAiB,CAAC,EAAA,CAAG,EAAQ,IAAM,EAAU,IAAM,KAAO,IACvF,CACF,ECtRa,GACX,EACA,CAAE,eAAc,oBAAyC,CAAC,IAElD,CACR,GAAI,CAAC,GAAgB,OAAO,GAAQ,UAAY,OAAO,GAAQ,SAC7D,OAAO,EAGT,GAAI,IAAiB,SACnB,OAAO,OAAO,WAAW,CAAa,EAGxC,IAAM,EAEJ,EAAgB,EAAK,CACnB,qBAAsB,IAAiB,WACvC,mBACA,cAAe,GACf,MAAO,EACT,CAAC,EAEH,OAAO,OAAO,GAAa,UAAY,CAAC,OAAO,MAAM,CAAQ,EAAI,EAAW,CAC9E,ECtCM,GAAsB,IAAI,IAAI,CAAC,UAAW,aAAc,KAAM,OAAO,CAAC,EAO/D,GAAqB,GAChC,IAAa,WAAa,IAAa,aAgB5B,IAAuB,CAClC,WACA,OACA,WACA,QACA,eASE,CAAC,GACD,IAAS,eACT,CAAC,GAAoB,IAAI,CAAQ,IAChC,MAAM,QAAQ,CAAK,GACjB,IAAc,UAAY,OAAO,GAAU,UAAY,EAAM,SAAS,GAAG,GAG1E,CAAE,MAAO,GAAM,MAAO,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,CAAC,CAAC,IAAM,EAAG,EAC5E,CAAE,MAAO,GAAO,OAAM,EAYf,IAAuB,CAClC,QACA,QACA,eACA,WACA,SACA,gBACA,uBAWa,CACb,IAAM,EAAY,EAAY,EAAO,CAAE,aAAc,CAAkB,CAAC,EAClE,EACJ,IAAU,GACV,GAAkB,CAAQ,IACzB,EAAa,OAAS,GAAK,EAAa,KAAO,IAAA,IAGlD,GAAI,EAAa,KAAW,GAAa,CAAC,EACxC,OAAO,EAAgB,EAAe,GAAS,EAAc,GAAG,EAGlE,IAAM,EAAI,CAAC,GAAG,CAAY,EAQ1B,MAPA,GAAE,GAAS,EACP,IAGF,EAAE,GAAK,EAAe,CAAM,GAAK,IAG5B,EAAgB,EAAI,GAAS,EAAG,GAAG,CAC5C,EAQa,IACX,EACA,IACY,CACZ,IAAM,EAAmB,EAAY,EAAO,CAC1C,aAAc,EACd,iBAAkB,EACpB,CAAC,EAED,GAAI,CACF,OAAO,OAAO,CAA4C,CAC5D,MAAQ,CACN,OAAO,CACT,CACF,EAQa,IACX,EACA,IAEA,IAAc,UAAY,IAAa,MAAQ,IAAa,QACxD,OACA,GAAa,OAQN,IACX,EACA,CAAE,WAAU,iBAAmE,CAAC,IAC1D,CACtB,GAAI,CAAC,EAAU,OAAO,EAEtB,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,EAAgB,EAAe,GAAS,EAAc,GAAG,CAClE,EAQa,IACX,EACA,IAES,EAAW,EAAQ,CAAK,CAAC,CAAC,IAAI,MAAM,EAAI,EC3J7C,IACJ,EACA,EACA,IAC4B,CAC5B,IAAM,EAAkC,CAAC,EAEzC,IAAK,IAAM,KAAO,EAAK,CACrB,GAAI,GAAY,CAAG,EAAG,SACtB,IAAM,EAAY,EAAY,GAC1B,IAAc,KAGd,GAAa,IAAQ,GAClB,GAAY,CAAS,IACxB,EAAO,GAAa,EAAI,IAErB,IACH,EAAO,GAAO,EAAI,KAGpB,EAAO,GAAO,EAAI,GAEtB,CAEA,OAAO,CACT,EA4HA,SAAgB,EACd,EACA,EAAqC,CAAC,EACtC,CACA,GAAM,CACJ,gBAAgB,GAAK,EACrB,qBAAqB,GAAM,EAC3B,cAAc,CAAC,EACf,gBAAgB,CAAC,EACjB,cAAc,CAAC,EACf,WAAW,GACX,2BAA2B,IACzB,EAGE,EAAgB,IAA+B,CACnD,GAAG,EACD,GACE,CACE,GAAG,EACH,GAAI,EAAgB,CAAE,EAClB,CAAE,WAAY,EAAc,EAAG,aAAe,EAAG,UAAW,EAC5D,CAAC,CACP,EACA,EACA,CACF,CACF,EACA,GAAI,EAAY,QAAa,GACzB,KACA,EAEG,EAAY,OAAY,SAAU,EAAG,MAAM,KAAK,EAAQ,IAAQ,CAC/D,IAAM,EAAa,EAAW,KAAO,CAAE,KAAM,CAAC,GAAG,EAAG,KAAO,CAAG,CAAE,EAShE,OARI,OAAO,GAAM,SAER,EAAc,IAAM,EAClB,EAAY,CAAC,EAEf,EAAa,CAAE,GAAG,EAAG,GAAG,CAAW,CAAC,EAGtC,EACL,GACE,CACE,GAAG,EACH,GAAG,EACH,GAAI,aAAc,EAAI,CAAE,SAAU,EAAY,EAAE,WAAa,EAAE,QAAS,EAAI,CAAC,CAC/E,EACA,EACA,CACF,CACF,CACF,CAAC,CACH,CACN,GAEA,OAAO,EAAa,CAAE,GAAG,EAAO,GAAI,EAAW,KAAO,CAAE,KAAM,CAAC,CAAE,CAAG,CAAC,CACvE,CCrNA,MAAa,GAAsB,GACjC,EAAO,CAAE,GAAK,OAAO,EAAG,OAAU,UAOvB,GACX,EACA,EACA,IACY,CACZ,GAAI,EAAG,MACL,MAAO,GAET,GAAI,OAAO,GAAqB,UAC9B,OAAO,EAET,GAAI,GAAmB,CAAgB,EACrC,OAAO,EAAiB,MAE1B,GAAI,OAAO,GAAc,YAAc,CAAC,EAAY,CAAE,EAAG,CACvD,IAAM,EAAK,EAAU,CAAE,EACvB,GAAI,OAAO,GAAO,UAChB,OAAO,EAGT,GAAI,GAAmB,CAAE,EACvB,OAAO,EAAG,KAEd,CACA,MAAO,EACT,ECtCa,IAAwB,CACnC,eACA,eAIuB,CACvB,GAAI,OAAO,GAAiB,SAAU,CACpC,GAAM,CAAC,EAAQ,GAAS,EAAa,MAAM,GAAG,EAO9C,OAJI,IAAU,UACL,IAAc,UAAW,EAG3B,CACT,CAEA,OAAO,EAAe,SAAW,EACnC,ECQa,GAAkB,GAAgC,CAC7D,OAAQ,EAAG,CAAW,EAAtB,CACE,IAAK,OACH,MAAO,UACT,IAAK,UACH,MAAO,cACT,IAAK,QACH,MAAO,SACT,IAAK,aACH,MAAO,cACT,IAAK,WACL,IAAK,aACL,IAAK,WACH,MAAO,OACT,IAAK,iBACL,IAAK,mBACL,IAAK,iBACH,MAAO,WACT,QACE,OAAO,CACX,CACF,EASa,IACV,EAAiB,QACjB,GAAG,IACF,EAAe,YAAY,IAAM,SAC7B,UAAU,EAAO,KAAK,IAAI,EAAE,GAC5B,EAAO,KAAK,IAAI,EAAe,EAAE,EAS5B,GAAoB,GAAyC,CACxE,OAAQ,EAAR,CACE,IAAK,WACL,IAAK,iBACH,MAAO,CAAC,IAAK,GAAG,EAClB,IAAK,aACL,IAAK,mBACH,MAAO,CAAC,GAAI,GAAG,EACjB,IAAK,WACL,IAAK,iBACH,MAAO,CAAC,IAAK,EAAE,EACjB,QACE,MAAO,CAAC,GAAI,EAAE,CAClB,CACF,EAUa,IACX,EACA,EACA,CACE,iBAAiB,KACjB,kBACA,gBAAgB,CAAC,GAAI,EAAE,GAKrB,CAAC,IACM,CACX,GAAM,CAAC,EAAK,GAAQ,GAAiB,CAAU,EACzC,EAAY,GAAmB,IAC/B,EAAS,GAAc,GAAG,EAAc,KAAK,IAAY,IAAI,IAAY,EAAc,KACvF,EAAQ,CAAC,GAAO,EAAM,CAAG,EAAG,EAAU,GAAQ,EAAM,CAAI,CAAC,CAAC,CAAC,OAAO,OAAO,EAC/E,OAAO,EAAM,OAAS,EAAI,GAAa,CAAc,CAAC,CAAC,GAAG,CAAK,EAAI,CACrE,EAOa,GAAiB,CAC5B,IAAK,MACL,KAAM,MACN,IAAK,MACL,KAAM,OACN,IAAK,MACL,KAAM,OACN,GAAI,MACJ,MAAO,OACP,MAAO,MACT,EAOa,GAAkB,CAC7B,IAAK,SACL,KAAM,MACN,IAAK,KACL,KAAM,MACN,IAAK,KACL,KAAM,MACN,GAAI,KACJ,MAAO,OACT,EAOa,GAGT,CACF,IAAK,KACL,GAAI,IACN,EAgBa,GAGT,CACF,YAAa,EAAW,IAAc,OAAO,GAAM,UAAY,EAAE,WAAW,CAAC,EAC7E,UAAW,EAAW,IAAc,OAAO,GAAM,UAAY,EAAE,SAAS,CAAC,CAC3E,EAUa,IACX,EACA,KACsB,CACtB,GAAG,EAEH,MAAO,EAAG,MAAM,IAAI,GAAK,CACvB,GAAI,OAAO,GAAM,SACf,OAAO,EAGT,GAAI,EAAY,CAAC,EACf,OAAO,GAAe,EAAG,CAAO,EAGlC,IAAM,EAAY,EAAU,EAAQ,OAAiC,EAAE,KAAK,EACtE,EAAe,GAAqB,CACxC,aAAc,EAAQ,aACtB,UAAW,GAAW,SACxB,CAAC,EAED,GAAI,MAAM,QAAQ,EAAE,KAAK,EACvB,MAAO,CAAE,GAAG,EAAG,MAAO,EAAE,MAAM,IAAI,GAAK,EAAY,EAAG,CAAE,cAAa,CAAC,CAAC,CAAE,EAG3E,IAAM,EAAa,EAAQ,EAAE,MAAO,CAAE,mBAAoB,EAAK,CAAC,CAAC,CAAC,IAAI,GACpE,EAAY,EAAG,CAAE,cAAa,CAAC,CACjC,EACA,GAAI,EAAW,MAAM,GAAK,OAAO,GAAM,QAAQ,EAAG,CAEhD,GAAI,EAAW,OAAS,EACtB,MAAO,CAAE,GAAG,EAAG,MAAO,CAAW,EAC5B,GAAI,EAAW,SAAW,EAC/B,MAAO,CAAE,GAAG,EAAG,MAAO,EAAW,EAAG,CAExC,CAEA,OAAO,CACT,CAAC,CACH,GAOa,EAAgB,GAC1B,OAAO,GAAU,UAAY,EAAM,OAAS,GAC5C,OAAO,GAAU,UAAY,CAAC,OAAO,MAAM,CAAK,GAChD,OAAO,GAAU,UAAY,OAAO,GAAU,SASpC,GAAwB,EAAgB,IACnD,CAAC,CAAC,IACD,OAAO,GAAU,UAChB,OAAO,GAAU,UAChB,OAAO,GAAU,UAAY,GAAa,KAAK,CAAK,GAU5C,GACX,GAC2C,EAAe,QAAU,EAWzD,IAEX,EAAwD,CAAC,GAAI,EAAE,IAE/D,MAAM,QAAQ,CAAmB,EAC7B,EACA,OAAO,GAAwB,SAC7B,CAAC,EAAqB,CAAmB,EACxC,GAAuB,CAAC,GAAI,EAAE,EAQ1B,IACX,EACA,CAAE,sBAAqB,8BACZ,CACX,GAAM,CAAC,EAAM,GAAS,GAA4B,CAAmB,EACrE,OAAO,OAAO,GAA6B,UAAY,EAAyB,OAAS,EACrF,GACE,GAAQ,EAAW,CAAwB,CAAC,CAAC,IAAI,GAAQ,GAAG,IAAO,IAAO,GAAO,EACjF,CACF,EACA,GAAG,IAAO,IAAY,GAC5B,EAEM,GAAmB,CAAC,IAAK,IAAK,GAAG,EAW1B,GAAiC,GAAwC,CACpF,IAAM,EAAmB,CAAC,EACpB,EAAY,IAAI,IAAI,EAAgB,EAE1C,IAAK,IAAM,KAAQ,EAAM,YAAY,EACnC,GAAI,EAAU,IAAI,CAAI,IACpB,EAAO,KAAK,CAAI,EAChB,EAAU,OAAO,CAAI,EACjB,EAAU,OAAS,GAAG,MAK9B,IAAK,IAAM,KAAU,GACf,EAAU,IAAI,CAAM,GACtB,EAAO,KAAK,CAAM,EAItB,OAAO,CACT,EASa,IAAmB,EAAgB,EAAc,MAAgB,CAC5E,IAAM,EAAI,GAAG,GAAS,KACtB,OAAO,GAAe,EAAE,WAAW,CAAW,EAAI,EAAI,GAAG,IAAc,GACzE,EAQa,IAAoB,EAAgB,EAAc,MAAgB,CAC7E,IAAM,EAAI,GAAG,GAAS,KACtB,OAAO,GAAe,EAAE,WAAW,CAAW,EAAI,EAAE,MAAM,EAAY,MAAM,EAAI,CAClF,EASa,GAAwC,CAKnD,YAAa,GAEb,oBAAqB,kCACrB,gBAAiB,iBACjB,YAAa,UACb,gBAAiB,aAGnB,EAKM,IACJ,EACA,EACA,IAGA,EAAU,WAAW,CAAG,GAExB,EAAW,MACT,GAEE,EAAU,SAAS,IAAI,GAAG,GAE1B,EAAU,MAAM,IAAI,CAAC,EAAE,SAAW,EAAW,MACjD,EAQW,IACX,EACA,EACA,EAAsC,CAAC,IAEvC,EAAW,SAAW,EACjB,EAAa,IACd,GAAsB,IACa,GAClC,OAAO,QAAQ,CAAY,CAAC,CAAC,MAAM,CAAC,KACnC,GAAuB,EAAK,EAAW,CAAU,CACnD,CAAC,GAAG,IACJ,OAAO,QAAQ,EAAqB,CAAC,CAAC,MAAM,CAAC,KAC3C,GAAuB,EAAK,EAAW,CAAU,CACnD,CAAC,GAAG,IACJ,GAAsB,IACY,GAsB3B,EAAoB,GAAsD,CACrF,GAAM,CAAE,OAAM,aAAc,EAAK,OAAS,CAAC,EAE3C,GAAI,CAAC,EAAM,OAAO,KAElB,GAAI,CAAC,EAAY,EAAK,KAAK,EAAG,MAAO,GAErC,IAAM,EAAc,EAAG,CAAI,EAErB,EACJ,IAAgB,WAAa,IAAc,EACvC,OACA,IAAgB,UAAY,IAAc,EACxC,OACA,EAWR,OARG,IAAqB,WACpB,IAAqB,UACrB,IAAqB,aACtB,OAAO,GAAc,UAAY,EAAY,GAEvC,GAGF,CAAE,KAAM,EAA6B,WAAW,CACzD,EAMa,GAA2B,aAW3B,IAA2B,EAAgB,IACtD,EAAgB,EAAI,GAAG,GAAyB,GAAG,IAAkB,GAW1D,IAA+B,EAAc,IACxD,OAAO,GAAU,SAAW,CAAE,QAAS,EAAM,SAAS,CAAE,EAAI,EAUjD,IAA0B,EAAc,IACnD,EAAO,CAAK,GAAK,OAAO,KAAK,CAAK,CAAC,CAAC,SAAW,GAAK,OAAO,EAAM,SAAY,SACzE,OAAO,EAAM,OAAO,EACpB,EC1fO,IAA4D,EAAW,IAAY,CAC9F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,GAAiB,GACvC,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAChC,EAAgB,CAAE,EAAI,IAAI,GAAiB,EAAG,YAAqC,GAAK,GAC1F,EAEM,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,IAAM,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAExF,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC7FMC,GAAgB,GAAe,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAE9EC,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAO9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,eAAc,sBAAuB,EACrD,CAAE,QAAO,WAAU,QAAO,eAAgB,EAG1C,EAAe,IAAgB,SAAW,IAAgB,YAC1D,EAAa,EAAG,IAAa,IAAM,KAAO,CAAQ,EAClD,EACJ,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,OAAO,GAAU,UACjB,EAAqB,EAAO,CAAY,EAEpC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,EAAW,EAAe,EAAK,MAAwB,CAC3D,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,GAAG,IAAoB,EAAE,MAAQ,IAAI,EAAE,QAAU,IAAK,EAC5F,CAAC,EACK,EAAoB,GAA6B,EAAU,CAC/D,GAAI,EACJ,cAAe,EAAgB,CACjC,CAAC,EAED,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,GAAG,EAAM,OAAO,EAAkB,IAAI,EAAkB,GAEjE,IAAK,OACL,IAAK,OACH,MAAO,GAAG,IAAS,OAAS,IAAM,KAAK,EAAM,UAAU,EAAkB,IAAI,EAAkB,GAEjG,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAa,UAAU,EAAM,UAC7B,EAAgB,GAAG,EAAM,UAAU,EAAkB,IAAI,EAAkB,UAE3E,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,KAKlE,OAHI,EAAY,GAAK,EAAY,EACxB,UAAU,EAAc,IAAI,EAAG,IAAI,EAAW,KAAK,EAAU,GAE/D,GAAG,EAAc,GAAG,EAAG,GAAG,GACnC,CACF,CACF,CAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAC5B,GAAgB,EACZ,EAAa,CAAK,EAClB,IAAIA,GAAmB,EAAO,CAAY,EAAE,KAGpD,IAAK,WACL,IAAK,iBAEH,MAAO,GADQD,GAAa,CAAU,EAAI,IAAM,KAC7B,EAAM,YACvB,EAAe,EAAa,CAAK,EAAI,IAAIC,GAAmB,EAAO,CAAY,EAAE,GAClF,GAGH,IAAK,aACL,IAAK,mBAEH,MAAO,GADQD,GAAa,CAAU,EAAI,IAAM,KAC7B,EAAM,cACvB,EAAe,EAAa,CAAK,EAAI,IAAIC,GAAmB,EAAO,CAAY,EAAE,GAClF,GAGH,IAAK,WACL,IAAK,iBAEH,MAAO,GADQD,GAAa,CAAU,EAAI,IAAM,KAC7B,EAAM,YACvB,EAAe,EAAa,CAAK,EAAI,IAAIC,GAAmB,EAAO,CAAY,EAAE,GAClF,GAGH,IAAK,OACH,MAAO,GAAG,EAAM,UAElB,IAAK,UACH,MAAO,GAAG,EAAM,UAElB,IAAK,KACL,IAAK,QAAS,CACZ,GAAM,CAAC,EAAQ,GAAUD,GAAa,CAAU,EAAI,CAAC,KAAM,GAAG,EAAI,CAAC,GAAI,EAAE,EAEzE,MAAO,GAAG,IAAS,EAAM,OADJ,EAAQ,CACc,CAAC,CACzC,IAAI,GACH,GAAgB,EAAqB,EAAK,CAAY,EAClD,GAAG,EAAa,CAAG,IACnB,IAAIC,GAAmB,EAAK,CAAY,EAAE,EAChD,CAAC,CACA,KAAK,IAAI,EAAE,GAAG,GACnB,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,CAAC,GAAuB,EAAa,EAAE,GACvC,CAAC,GAAuB,EAAa,EAAE,EACvC,CACA,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EACvD,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EACxD,IACA,EAAa,OAAO,MAAM,CAAQ,EAClC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAO,CAAY,EAAE,GAC9C,EACA,EAAc,OAAO,MAAM,CAAS,EACpC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAQ,CAAY,EAAE,GAC/C,EAEJ,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,OAAO,IAAe,UAClB,IAAI,EAAM,MAAM,EAAW,MAAM,EAAM,MAAM,EAAY,GACzD,IAAI,EAAM,KAAK,EAAW,MAAM,EAAM,KAAK,EAAY,EAC7D,CACE,MAAO,EAEX,CACF,CACA,MAAO,EACT,EC1Ka,GAAkB,CAAE,KAAM,CAAC,CAAE,MAAO,EAAK,CAAC,CAAE,EAO5C,IACX,EACA,EACA,IACG,CACH,GAAM,CACJ,UACA,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,CAAE,uBAAyB,GAAW,CAAC,EAEvC,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,GAAkB,GAGvC,IAAM,EAAa,IAAI,EAAG,EAAG,UAAU,IACnC,EAAgB,GAEd,EAAyC,EAAG,MAC/C,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAKhD,OAJI,GACF,EAAgB,GACT,GAEF,EACT,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EACL,EACA,CACE,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,EACA,CACF,CACF,CAAC,CAAC,CACD,OAAO,OAAO,EAEX,EACJ,EAAY,OAAS,EACjB,EAAY,SAAW,GAAK,CAAC,EAC3B,EAAY,GACZ,EAAG,GAAa,CAAY,EAC9B,GAEN,OAAO,EAAG,IAAO,EAAsB,CAAE,KAAM,CAAO,EAAI,CAAE,KAAM,CAAC,CAAM,CAAE,EAAK,CAClF,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,ECzFMC,IAAoB,EAAgB,EAAa,EAAe,KACpE,EAAqB,EAAO,GAAgB,OAAO,GAAU,QAAQ,EACjE,OAAO,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,CAAC,EACrD,EAOO,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,qBAAoB,WAAY,EAChD,EAAe,IAAgB,QAE/B,CAAE,qBAAuB,GAAW,CAAC,EAErC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAa,CAAE,MAAO,CAAE,QAAS,CAAC,IAAI,IAAS,CAAC,CAAC,CAAE,CAAE,EACrD,EAAmB,GACvB,EAAe,EAAwB,CACrC,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,GAAG,EAAM,GAAG,EAAE,QAAU,CAAM,EAC9E,CAAC,EACD,CACE,GAAI,EAEJ,cAAe,GACf,QAAS,CAAE,GAAG,EAAQ,QAAS,kBAAmB,EAAM,CAC1D,CACF,EACM,EAAqB,GACzB,EAAe,EAAwB,CACrC,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,SAAS,EAAE,QAAU,OAAQ,EAC7E,CAAC,EACD,CACE,GAAI,EAEJ,cAAe,GACf,QAAS,CAAE,GAAG,EAAQ,QAAS,kBAAmB,GAAM,oBAAqB,EAAK,CACpF,CACF,EAEM,EAAgB,CACpB,MAAO,CACL,QAAS,CACP,CAAE,QAAS,CAAE,MAAO,IAAI,IAAS,GAAI,OAAQ,KAAM,CAAE,KAAM,CAAC,CAAkB,CAAE,CAAE,CAAE,EACpF,CAAC,CACH,CACF,CACF,EAEA,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,CAAE,MAAO,CAAE,IAAK,CAAC,EAAe,CAAU,CAAE,CAAE,EAEvD,IAAK,OACH,MAAO,CAAE,KAAM,CAAC,CAAgB,CAAE,EAEpC,IAAK,OACH,OAAO,EAET,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EACJ,IAAS,UACL,GAAe,MACf,IAAS,SACP,GAAe,MACf,GAAe,KAKvB,OAHI,EAAY,GAAK,EAAY,EACxB,CAAE,MAAO,EAAG,GAAK,CAAC,EAAe,CAAE,UAAW,CAAC,EAAY,CAAS,CAAE,CAAC,CAAE,CAAE,EAE7E,CAAE,MAAO,EAAG,GAAK,CAAC,EAAe,CAAS,CAAE,CAAE,CACvD,CACF,CACF,CAEA,GAAI,IAAa,KAAO,CAAC,EACvB,OAAO,EACH,CAAE,IAAK,CAAC,IAAI,IAASA,GAAc,EAAO,EAAO,CAAY,CAAC,CAAE,EAChE,EAAG,GAAQA,GAAc,EAAO,EAAO,CAAY,CAAE,EAG3D,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAgB,GAAe,GACrC,OAAO,EACH,EAAG,GAAgB,CAAC,IAAI,IAAS,IAAI,GAAO,CAAE,EAC9C,EACE,CACE,KAAM,CACJ,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,CAAE,EAC3B,EAAG,GAAgB,CAAC,IAAI,IAASA,GAAc,EAAO,EAAO,CAAY,CAAC,CAAE,CAC9E,CACF,EACA,EAAG,GAAQ,EAAG,GAAgBA,GAAc,EAAO,EAAO,CAAY,CAAE,CAAE,CAClF,CAEA,IAAK,WACH,OAAO,EACH,CAAE,OAAQ,QAAQ,EAAM,iBAAiB,EAAM,EAAG,EAClD,EACE,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,CAAM,CAAE,EACpD,EAAG,GAAQ,CAAE,OAAQ,CAAM,CAAE,EAErC,IAAK,aACH,OAAO,EACH,CAAE,OAAQ,QAAQ,EAAM,mBAAmB,EAAM,EAAG,EACpD,EACE,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,IAAI,GAAQ,CAAE,EAC1D,EAAG,GAAQ,CAAE,OAAQ,IAAI,GAAQ,CAAE,EAE3C,IAAK,WACH,OAAO,EACH,CAAE,OAAQ,QAAQ,EAAM,iBAAiB,EAAM,EAAG,EAClD,EACE,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,GAAG,EAAM,EAAG,CAAE,EAC1D,EAAG,GAAQ,CAAE,OAAQ,GAAG,EAAM,EAAG,CAAE,EAE3C,IAAK,iBACH,OAAO,EACH,CAAE,OAAQ,SAAS,EAAM,iBAAiB,EAAM,EAAG,EACnD,EACE,CAAE,KAAM,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,CAAM,CAAE,CAAE,EAC9D,EAAG,GAAQ,CAAE,KAAM,CAAE,OAAQ,CAAM,CAAE,CAAE,EAE/C,IAAK,mBACH,OAAO,EACH,CAAE,OAAQ,SAAS,EAAM,mBAAmB,EAAM,EAAG,EACrD,EACE,CAAE,KAAM,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,IAAI,GAAQ,CAAE,CAAE,EACpE,EAAG,GAAQ,CAAE,KAAM,CAAE,OAAQ,IAAI,GAAQ,CAAE,CAAE,EAErD,IAAK,iBACH,OAAO,EACH,CAAE,OAAQ,SAAS,EAAM,iBAAiB,EAAM,EAAG,EACnD,EACE,CAAE,KAAM,CAAE,YAAa,CAAE,MAAO,IAAI,IAAS,MAAO,GAAG,EAAM,EAAG,CAAE,CAAE,EACpE,EAAG,GAAQ,CAAE,KAAM,CAAE,OAAQ,GAAG,EAAM,EAAG,CAAE,CAAE,EAErD,IAAK,OACH,OAAO,EAAoB,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,CAAE,EAAI,EAAG,GAAQ,IAAK,EAE5E,IAAK,UACH,OAAO,EAAoB,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,CAAE,EAAI,EAAG,GAAQ,CAAE,IAAK,IAAK,CAAE,EAErF,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,EACH,CACE,OAAQ,GAAG,IAAe,QAAU,IAAM,GAAG,GAAG,EAC7C,IAAI,GAAO,QAAQ,GAAK,CAAC,CACzB,KAAK,GAAG,EAAE,kBAAkB,EAAM,EACvC,EACA,EACE,IAAe,QACb,CACE,KAAM,EACH,GAAe,IAAK,CACnB,IAAI,IACJ,EAAa,IAAI,GAAOA,GAAc,EAAK,EAAK,CAAY,CAAC,CAC/D,CACF,CACF,EACA,EACG,GAAe,IAAc,CAC5B,IAAI,IACJ,EAAa,IAAI,GAAOA,GAAc,EAAK,EAAK,CAAY,CAAC,CAC/D,CACF,EACF,EACG,GAAQ,EACN,GAAe,IAAc,EAAa,IAAI,GAC7CA,GAAc,EAAK,EAAK,CAAY,CACtC,CACF,CACF,CACR,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAM,CAAC,EAAO,GAAU,EAClB,EAAWA,GAAc,EAAO,IAAY,EAAI,EAChD,EAAYA,GAAc,EAAQ,IAAY,EAAI,EACpD,EAAa,GAAuB,OAAO,MAAM,CAAQ,EAA7B,EAAyC,EACrE,EAAc,GAAwB,OAAO,MAAM,CAAS,EAA/B,EAA4C,EAC7E,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAWE,OATE,IAAe,UACV,EACH,CAAE,KAAM,CAAC,IAAI,IAAS,IAAI,GAAY,EAAG,KAAM,CAAC,IAAI,IAAS,IAAI,GAAa,CAAE,EAChF,EACE,CACE,KAAM,CAAC,CAAE,KAAM,CAAC,IAAI,IAAS,CAAU,CAAE,EAAG,CAAE,KAAM,CAAC,IAAI,IAAS,CAAW,CAAE,CAAC,CAClF,EACA,EAAG,GAAQ,CAAE,KAAM,EAAY,KAAM,CAAY,CAAE,EAElD,EACH,CACE,IAAK,CACH,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,GAAY,CAAE,EACvC,CAAE,IAAK,CAAC,IAAI,IAAS,IAAI,GAAa,CAAE,CAC1C,CACF,EACA,EACE,CACE,IAAK,CAAC,CAAE,IAAK,CAAC,IAAI,IAAS,CAAU,CAAE,EAAG,CAAE,IAAK,CAAC,IAAI,IAAS,CAAW,CAAE,CAAC,CAC/E,EACA,CAAE,IAAK,CAAC,EAAG,GAAQ,CAAE,IAAK,CAAW,CAAE,EAAG,EAAG,GAAQ,CAAE,IAAK,CAAY,CAAE,CAAC,CAAE,CAEvF,CACE,MAAO,EAEX,CACF,CACA,MAAO,EACT,ECxPa,IAA8C,EAAM,IAAY,CAC3E,IAAM,EAAW,GAAiC,EAAM,CAAO,EAC/D,OAAO,EAAW,KAAK,UAAU,CAAQ,EAAI,EAC/C,ECHa,IAA6D,EAAW,IAAY,CAC/F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAEjF,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,IAAM,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAExF,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC1FMC,GAAgB,GAAe,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAE9E,IAAkB,EAAgB,IAAqB,EAAS,KAAK,EAAO,GAAK,EAEjFC,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAO9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,eAAc,sBAAuB,EAGrD,EAAe,IAAgB,SAAW,IAAgB,YAC1D,EAAa,EAAG,IAAa,IAAM,KAAO,CAAQ,EAClD,EACJ,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,OAAO,GAAU,UACjB,EAAqB,EAAO,CAAY,EAEpC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAoB,GACxB,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,OAAS,OAAQ,EACzD,CAAC,EACD,CACF,EAEM,EAAa,GAAG,EAAM,SACtB,EAAgB,GAAG,EAAM,KAAK,EAAkB,UAEtD,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,GAAG,EAAc,MAAM,IAEhC,IAAK,OACH,MAAO,GAAG,EAAc,OAE1B,IAAK,OACH,MAAO,GAAG,EAAc,OAE1B,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,KAKlE,OAHI,EAAY,GAAK,EAAY,EACxB,GAAG,EAAc,GAAG,EAAG,IAAI,EAAW,KAAK,EAAU,GAEvD,GAAG,EAAc,GAAG,EAAG,GAAG,GACnC,CACF,CACF,CAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAC5B,GAAgB,EACZ,EAAa,CAAK,EAClB,IAAIA,GAAmB,EAAO,CAAY,EAAE,KAGpD,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAU,EACZ,eAAe,EAAa,CAAK,EAAE,gBACnC,MAAMA,GAAmB,EAAO,CAAY,EAAE,KAElD,OAAO,GAAe,GAAG,EAAM,WAAW,IAAWD,GAAa,CAAU,CAAC,CAC/E,CAEA,IAAK,aACL,IAAK,mBAAoB,CACvB,IAAM,EAAU,EACZ,cAAc,EAAa,CAAK,EAAE,gBAClC,IAAK,OAAO,GAAU,UAAY,CAAC,EAAM,WAAW,GAAG,GAAM,EAAe,IAAM,KAAKC,GAAmB,EAAO,CAAY,EAAE,KAEnI,OAAO,GAAe,GAAG,EAAM,WAAW,IAAWD,GAAa,CAAU,CAAC,CAC/E,CAEA,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAU,EACZ,eAAe,EAAa,CAAK,EAAE,eACnC,MAAMC,GAAmB,EAAO,CAAY,IAAK,OAAO,GAAU,UAAY,CAAC,EAAM,SAAS,GAAG,GAAM,EAAe,IAAM,GAAG,GAEnI,OAAO,GAAe,GAAG,EAAM,WAAW,IAAWD,GAAa,CAAU,CAAC,CAC/E,CAEA,IAAK,OACH,MAAO,GAAG,EAAM,UAElB,IAAK,UACH,MAAO,GAAG,EAAM,UAElB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAASA,GAAa,CAAU,EAAI,IAAM,GAC1C,EAAe,EAAQ,CAAK,EAClC,OAAO,EAAa,OAAS,EACzB,GAAG,EAAO,GAAG,EACV,IACC,GACE,GAAG,EAAM,MACP,GAAgB,EAAqB,EAAK,CAAY,EAClD,GAAG,EAAa,CAAG,IACnB,IAAIC,GAAmB,EAAK,CAAY,EAAE,IAEpD,CAAC,CACA,KAAK,MAAM,EAAE,GAChB,EACN,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,CAAC,GAAuB,EAAa,EAAE,GACvC,CAAC,GAAuB,EAAa,EAAE,EACvC,CACA,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EACvD,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EACxD,IACA,EAAa,OAAO,MAAM,CAAQ,EAClC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAO,CAAY,EAAE,GAC9C,EACA,EAAc,OAAO,MAAM,CAAS,EACpC,EACE,GAAG,IACH,IAAIA,GAAmB,EAAQ,CAAY,EAAE,GAC/C,EACJ,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CACA,OAAO,IAAe,UAClB,IAAI,EAAM,MAAM,EAAW,OAAO,EAAM,MAAM,EAAY,GAC1D,IAAI,EAAM,KAAK,EAAW,MAAM,EAAM,KAAK,EAAY,EAC7D,CACE,MAAO,EAEX,CACF,CAEA,MAAO,EACT,ECjLMC,IAA2B,EAAY,EAAmB,IAC9D,GAAgB,OAAO,GAAM,SACzB,EAAE,WAAW,GAAG,IAAa,GAAG,IAAY,GAAW,EACvD,EAOO,IACX,CAAE,WAAU,QAAO,eAEnB,CACE,eACA,eACA,qBACA,sBACA,kBACA,iBAAiB,KACjB,2BACA,cACA,gBAAgB,CAAC,GAAI,EAAE,EACvB,gBACE,CAAC,IACF,CAEH,GAAI,IAAgB,YAAa,CAC/B,IAAM,EAAoB,EAAG,CAAQ,EACrC,GAAI,IAAsB,WAAa,IAAsB,aAAc,CACzE,IAAM,EAAe,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,EAChE,GACE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAE7B,MAAO,GAET,GAAM,CAAC,EAAO,GAAU,EAGxB,MAAO,CAAC,GAAgB,EAAO,CAAW,EAAG,GAAgB,EAAQ,CAAW,CAAC,CAAC,CAAC,KACjF,IAAI,GAAc,YAAc,GAAc,KAAO,MAAM,EAC7D,CACF,CACA,GAAI,IAAsB,MAAQ,IAAsB,QAAS,CAC/D,IAAM,EAAe,EAAQ,CAAK,EAIlC,OAHI,EAAa,SAAW,EACnB,GAEF,IAAI,EAAa,IAAI,GAAK,GAAgB,EAAG,CAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAC/E,CACA,IAAM,EAAW,GAAgB,EAAO,CAAW,EAEnD,OAAQ,EAAR,CACE,IAAK,WACL,IAAK,iBACL,IAAK,aACL,IAAK,mBACL,IAAK,WACL,IAAK,iBACH,OAAO,GAAiB,EAAU,EAAmB,CACnD,iBACA,kBACA,eACF,CAAC,CACL,CACA,OAAO,CACT,CAEA,IAAM,EAAe,IAAgB,QAC/B,EAAoB,EAAG,CAAQ,EAC/B,EAAY,GAAmB,IAE/B,EAAc,GAClB,GAAG,EAAc,KAAK,IAAY,IAAI,IAAY,EAAc,KAC5D,EAAe,GAAeA,GAAwB,EAAG,EAAW,CAAY,EAChF,EAAiB,GAAe,EAAW,EAAY,CAAC,CAAC,EACzD,EAAiB,GACrB,GAAmB,EAAa,CAAE,sBAAqB,0BAAyB,CAAC,EAC7E,EAAW,CAAE,iBAAgB,kBAAiB,eAAc,EAElE,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,UACH,MAAO,GAGT,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAYlC,OAXI,EAAa,OAAS,EACjB,IAAI,EACR,IAAI,GACH,EACI,EAAc,CAAC,EACf,EAAqB,EAAG,CAAY,EAClC,GAAG,EAAa,CAAC,IACjB,GAAG,EAAc,CAAC,GAC1B,CAAC,CACA,KAAK,IAAI,EAAE,GAET,EACT,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,EAChE,GACE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAE7B,MAAO,GAGT,GAAM,CAAC,EAAO,GAAU,EAElB,EAAW,EAAqB,EAAO,CAAY,EACrD,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,EAC7C,IACE,EAAY,EAAqB,EAAQ,CAAY,EACvD,EAAY,EAAQ,CAAE,aAAc,QAAS,CAAC,EAC9C,IACE,EAAa,OAAO,MAAM,CAAQ,EAAK,EAAe,GAAG,IAAU,EAAS,EAC5E,EAAc,OAAO,MAAM,CAAS,EACtC,EACE,GAAG,IACH,EACF,EAEE,EAAoB,CAAC,EAAY,CAAW,EAWlD,MATE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,IAEZ,EAAkB,GAAK,EACvB,EAAkB,GAAK,IAKrB,EACI,EAAkB,IAAI,GAAK,EAAc,CAAC,CAAC,EAC3C,EAAkB,MAAM,GAAK,EAAqB,EAAG,CAAY,CAAC,EAChE,EAAkB,IAAI,GAAK,EAAY,EAAG,CAAE,aAAc,QAAS,CAAC,CAAC,EACrE,EAAkB,IAAI,GAAK,EAAc,CAAC,CAAC,EAAA,CAIhD,KAAK,IAAI,GAAc,YAAc,GAAc,KAAO,MAAM,EAAE,CAEzE,CAEA,IAAK,WACL,IAAK,iBACH,OAAO,EACH,GAAiB,EAAc,CAAK,EAAG,EAAmB,CAAQ,EAClE,EAAW,IAAI,EAAY,CAAK,EAAE,EAAE,EAE1C,IAAK,aACL,IAAK,mBACH,OAAO,EACH,GAAiB,EAAc,CAAK,EAAG,EAAmB,CAAQ,EAClE,EAAW,GAAG,EAAY,CAAK,EAAE,EAAE,EAEzC,IAAK,WACL,IAAK,iBACH,OAAO,EACH,GAAiB,EAAc,CAAK,EAAG,EAAmB,CAAQ,EAClE,EAAW,IAAI,EAAY,CAAK,GAAG,CAC3C,CAMA,OAJI,OAAO,GAAU,UACZ,EAAQ,OAAS,QAGnB,EACH,EAAc,CAAK,EACnB,EAAqB,EAAO,CAAY,EACtC,GAAG,EAAa,CAAK,IACrB,GAAG,EAAc,CAAK,GAC9B,EC1La,GAGT,CACF,IAAK,MACL,GAAI,IACN,EAOa,IAA+D,EAAW,IAAY,CACjG,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,GAAoB,GAC1C,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAChC,EAAgB,CAAE,EAAI,IAAI,GAAoB,EAAG,YAAqC,GAAK,GAC7F,EAEM,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,OAAS,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAE3F,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EClEa,IACX,EACA,EACA,MAEE,EAAyC,IAAgC,CACzE,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,eACA,gBACA,iBACE,EAEJ,GAAI,CAAC,GAAW,CAAC,EAAkB,OAEnC,GAAM,CAAE,MAAK,MAAK,MAAO,EAEnB,GAAoB,EAAmB,IAA0C,CACrF,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAGF,IAAM,EAAiB,EAAG,MACvB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,YACA,QAAS,CAAE,GAAG,EAAQ,QAAS,UAAS,kBAAiB,CAC3D,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAe,SAAW,EAC5B,OAGF,IAAM,EACJ,EAAG,aAAe,KAAO,EAAG,GAAG,CAAc,EAAK,EAAI,GAAG,CAAc,EAEzE,OAAO,EAAG,IAAM,EAAI,CAAY,EAAI,CACtC,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,GCzGW,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAGE,EAAoB,GAAmD,CAC3E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,MAAO,GAGT,IAAM,EAAiB,EAAG,MACvB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAMjB,OAJI,EAAe,SAAW,GAIvB,CACL,KAAM,EAAG,IACL,CACE,SAAU,QAAQ,KAAK,EAAG,UAAU,EAChC,CAAE,KAAM,CAAE,OAAQ,CAAe,CAAE,EACnC,CACN,EACA,EAAG,QAAQ,KAAK,EAAG,UAAU,EAAI,SAAW,QAAS,CAAe,CAC1E,CACF,EAEM,EAAqB,EAAiB,EAAc,CAAS,CAAC,EACpE,OAAO,IAAuB,GAAQ,CAAC,EAAI,CAC7C,EChEa,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,EAAsB,GAA2C,CAErE,GAAI,OAAO,GAAS,UAAY,EAAY,CAAI,EAAG,OAEnD,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAE1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,CACH,EAGM,EAAiB,GAAiC,CACtD,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,MAAO,GAGT,IAAM,EAAuB,CAAC,EAE9B,IAAK,IAAM,KAAQ,EAAG,MAAO,CAC3B,GAAI,OAAO,GAAS,SAAU,SAE9B,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAS,EAAc,CAAI,EAC7B,GAAQ,EAAW,KAAK,CAAM,EAClC,QACF,CAEA,IAAM,EAAY,EAAmB,CAAI,EACrC,GAAW,EAAW,KAAK,CAAS,CAC1C,CAEA,GAAI,EAAW,SAAW,EAAG,MAAO,GAEpC,IAAM,EAAc,EAAqB,YAAc,MAEvD,GAAI,EAAW,SAAW,GAAK,CAAC,EAAG,IAAK,OAAO,EAAW,GAG1D,IAAM,EAAO,EAAW,IAAI,GAAM,EAAE,WAAW,GAAG,EAAI,KAAK,IAAM,CAAE,CAAC,CAAC,KAAK,IAAI,EAQ9E,OAJI,EAAG,IACE,EAAW,SAAW,EAAI,QAAQ,EAAK,GAAK,WAAW,EAAW,GAAG,EAAK,IAG5E,IAAI,EAAW,GAAG,EAAK,EAChC,EAGA,GACE,CAAC,EACC,EACA,EACE,EAAU,IAAyC,GAEvD,EAEA,OAAO,EAGT,IAAM,EAAkB,CAAC,EAEzB,IAAK,IAAM,KAAQ,EAAU,MAAO,CAClC,GAAI,OAAO,GAAS,SAAU,SAE9B,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAW,EAAc,CAAI,EAC/B,GAAU,EAAM,KAAK,CAAQ,EACjC,QACF,CAEA,IAAM,EAAY,EAAmB,CAAI,EACrC,GAAW,EAAM,KAAK,CAAS,CACrC,CAIA,OAFI,EAAM,SAAW,EAAU,EAExB,EAAM,KAAK,EAAE,CACtB,EC3Ha,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAEjF,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,OAAS,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAE3F,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,ECrFa,IACX,EACA,IACG,CACH,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,EAAQ,EAAc,CAAS,EAE/B,GAAoB,EAAmB,IAAuC,CAClF,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,MAAO,GAGT,IAAM,EAAiB,EAAG,MACvB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAe,SAAW,EAC5B,MAAO,GAGT,IAAM,EAA8B,EAAG,EAAG,YAAa,CAAe,EAItE,OAAO,EAAG,IAAM,CAAE,IAAK,CAAc,EAAI,CAC3C,EAEA,OAAO,EAAiB,EAAO,EAAI,CACrC,ECtEa,IAA6D,EAAW,IAAY,CAC/F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAkB,EAAG,MACxB,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEX,EAAa,EAAM,KAAK,EAAE,EAE1B,CAAC,EAAW,GAAa,EAAG,IAAM,CAAC,KAAM,GAAG,EAAI,CAAC,GAAI,EAAE,EACvD,CAAC,EAAQ,GACb,EAAM,OAAS,EACX,CAAC,GAAG,EAAU,GAAG,EAAG,aAAe,KAAO,IAAM,MAAO,IAAI,GAAW,EACtE,CAAC,EAAW,CAAS,EAE3B,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,EClEM,GAAe,GAAgB,EAAI,WAAW,GAAG,GAAK,EAAI,SAAS,GAAG,EAS/D,IACX,EACA,EACA,IACG,CACH,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAa,KAAK,EAAG,EAAG,UAAU,EAAE,GACtC,EAAgB,GAEd,EAAwB,EAAG,MAC9B,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAMhD,OALI,GACF,EAAgB,GAET,GAAY,CAAkB,EAAI,EAAqB,IAAI,EAAmB,IAEhF,EACT,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,MAAO,GAET,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EACL,EACA,CACE,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,EACA,CACF,CACF,CAAC,CAAC,CACD,OAAO,OAAO,EAEX,EACJ,EAAY,OAAS,EACjB,EAAY,SAAW,GAAK,CAAC,EAC3B,EAAY,GACZ,GAAG,EAAW,IAAI,EAAY,KAAK,GAAG,EAAE,GAC1C,EAEN,OAAO,EAAG,IAAM,WAAW,GAAY,CAAM,EAAI,EAAS,IAAI,EAAO,GAAG,GAAK,CAC/E,EAEM,EAAiB,EAAiB,EAAc,CAAS,EAAG,EAAI,EACtE,OAAO,GAAY,CAAc,EAAI,EAAiB,IAAI,EAAe,EAC3E,ECjFa,IAA2D,EAAW,IAAY,CAC7F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAA+C,CAC7F,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAA2B,EAAqB,GAGzD,IAAM,EACJ,EAAkB,CAAE,GAAK,EAAG,MAAM,KAAK,GAAK,OAAO,GAAM,UAAY,EAAG,CAAC,IAAM,KAAK,EAChF,EAAc,CAAE,EAChB,EAEA,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAI,MAAO,CAE5B,GAAI,OAAO,GAAS,SAAU,CAE5B,EAAsB,GADV,EAAa,eAAiB,OACX,EAAa,IAA6B,EAAK,GAC9E,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EACrB,EACA,EAAI,MAAM,SAAW,GACnB,EACE,EAAI,KACJ,SAAS,KACP,EAAI,YACiC,EACvC,EAEN,EAEI,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,GAAgB,EAAK,aAAe,WAAa,QAEjD,EAAY,EAAU,EAAQ,EAAK,KAAK,EAExC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,eACA,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,GAAI,EAAe,SAAW,EAC5B,OAAO,EAGT,IAAM,EAAQ,EAAG,EAAI,YAAc,EAAE,IAAM,MACrC,EAAa,EAAQ,EAAI,WAAY,MAAM,CAAC,EAAI,EAAI,WACpD,EAAW,EAAI,KAAO,CAAC,GAA6B,GAAS,EAAe,OAAS,EAErF,CAAC,EAAU,GAAa,CAAC,cAAe,aAAa,CAAC,CAAW,IAAI,GACzE,EAAI,IACA,EACE,GAAkB,EAAK,EAAc,CAAC,MAAO,KAAK,CAAC,EACnD,GAAkB,EAAK,EAAc,CAAC,KAAK,CAAC,EAC9C,EACE,GAAkB,EAAK,EAAc,CAAC,KAAK,CAAC,EAC5C,GAAkB,EAAK,CAAY,CAC3C,EAEM,EAAS,EAAW,GAAG,EAAS,IAAI,KAAK,EAAI,GAC7C,EAAS,EAAW,KAAK,IAAW,KAAK,EAAI,GAE7C,EAAM,EAAa,eAAiB,KAE1C,MAAO,GAAG,IAAS,EAAe,KAChC,EAAgB,CAAG,EACf,GAAG,IAAM,EAAa,IAAmC,EAAW,GACpE,EACN,IAAI,GACN,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC/Ha,IAER,EAAW,IAAY,CAC1B,GAAM,CACJ,SACA,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,EAAgB,IAAW,gBAE3B,EAAgB,CAAC,EAEjB,EAAmC,CAAC,EACpC,EAAwC,IAAI,IAE5C,EAAqB,GAAkB,CACtC,EAAY,IAAI,CAAK,GACxB,EAAY,IAAI,EAAO,IAAI,GAAK,EAElC,IAAM,EAAiB,GAAG,EAAM,GAAG,EAAY,IAAI,CAAK,CAAC,CAAE,KAAO,IAElE,OADA,EAAY,IAAI,CAAK,CAAC,CAAE,IAAI,CAAc,EACnC,CACT,EAEM,EAAe,GAAmB,CACtC,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAGtD,MAAO,GAGT,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAExC,EAAkB,OAAO,YAC5B,CAAC,GAAG,EAAY,QAAQ,CAAC,CAAC,CAA6B,KAAK,CAAC,EAAG,KAAO,CAAC,EAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CACrF,EAEM,EAAgB,EACpB,EACA,CACE,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,oBACA,kBACA,WACF,EACA,CAAE,gBAAiB,CAAO,CAC5B,EAEA,GAAI,CAAC,EAAO,CAAa,EACvB,MAAO,GAGT,GAAM,CAAE,MAAK,OAAQ,GAAiB,EAEtC,GAAI,OAAO,GAAQ,UAAY,CAAC,EAC9B,MAAO,GAIT,GAAI,IAAW,iBAAmB,MAAM,QAAQ,CAAY,EAC1D,EAAO,KAAK,GAAG,CAAY,OACtB,GAAI,IAAW,uBAAyB,EAAO,CAAY,EAAG,CACnE,OAAO,OAAO,EAAa,CAAY,EAIvC,IAAK,IAAM,KAAK,OAAO,KAAK,CAAY,EAAG,EAAY,IAAI,EAAK,KAAK,CAAC,EAAE,IAAI,CAAC,CAC/E,CAEA,OAAO,CACT,EAEM,GAAoB,EAAsB,IAA+C,CAC7F,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAA2B,EAAqB,GAGzD,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,EAAM,EAAG,MAAM,SAAW,CAAC,EAE/D,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,IAAM,EAAgB,EAAY,CAAI,EAClC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAMA,OAJI,EAAe,SAAW,EACrB,EAGF,GAAG,EAAG,IAAM,OAAS,GAAG,GAAG,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAAE,EAC1G,EAKA,OAHI,EACK,CAAE,IAAK,EAAiB,EAAW,EAAI,EAAG,QAAO,EAEnD,CAAE,IAAK,EAAiB,EAAW,EAAI,EAAG,OAAQ,CAAY,CACvE,EC3Ja,GAAiB,CAAC,EAOlB,IAER,EAAW,IAAY,CAC1B,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAmB,IAAwB,CACnE,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,GAAiB,IAAA,GAGtC,IAAM,EAAa,EAAG,WAAW,YAAY,EACzC,EAAgB,GAEd,EAAyC,EAAG,MAC/C,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAKhD,OAJI,GACF,EAAgB,GACT,GAET,MACF,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,OAAO,EAAY,OAAS,EACxB,EAAY,SAAW,GAAK,CAAC,EAC3B,EAAY,GACZ,EAAG,GAAa,CAAY,EAC9B,EACN,EAEM,EAAS,EAAiB,EAAc,CAAS,EAAG,EAAI,EAE9D,OAAO,EAAU,IAAM,CAAE,IAAK,CAAO,EAAI,CAC3C,EC3Da,IAER,EAAW,IAAY,CAE1B,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,gBACA,UAAU,CAAC,GACT,EAEE,CAAE,mBAAoB,GAAO,EAInC,GAAI,CAAC,EAAI,OAET,IAAM,GACJ,EACA,IAC0C,CAC1C,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAGF,IAAM,EAAa,EAAG,WAAW,YAAY,EACzC,EAAgB,GAEd,EAAyC,EAAG,MAC/C,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAqB,EAAiB,CAAI,EAKhD,OAJI,GACF,EAAgB,GACT,GAET,MACF,CACA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,WACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAY,SAAW,EAAG,OAE9B,IAAM,EACJ,EAAY,SAAW,GAAK,CAAC,EACzB,EAAY,GACZ,EAAG,EAAG,CAAU,IAAM,KAAO,EAAG,GAAK,EAAG,KAAM,CAAY,EAEhE,OAAO,EAAG,IAAM,EAAG,EAAG,KAAM,CAAO,EAAI,CACzC,EAEA,OAAO,EAAiB,EAAc,CAAS,EAAG,EAAI,CACxD,EC9Fa,IAA+D,EAAW,IAAY,CACjG,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAAgC,CAC9E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAAY,EAAqB,GAG1C,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,GAAiB,GACvC,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,CAAI,EACxC,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EACxC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,cAAe,EAAK,aAAe,WAAa,QAChD,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAEA,IAAM,EAAa,EAAe,KAChC,EAAgB,CAAE,EAAI,IAAI,GAAiB,EAAG,YAAqC,GAAK,GAC1F,EAEM,CAAC,EAAQ,GAAU,EAAG,KAAO,CAAC,EAAY,CAAC,GAAG,EAAG,IAAM,IAAM,GAAG,GAAI,GAAG,EAAI,CAAC,GAAI,EAAE,EAExF,OAAO,EAAa,GAAG,IAAS,IAAa,IAAW,CAC1D,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,EC7Fa,IAA4D,EAAW,IAAY,CAC9F,GAAM,CACJ,SACA,qBACA,wBACA,uBACA,0BACA,uBACA,gBACA,eACA,iBACE,EAEE,GAAoB,EAAsB,IAA+C,CAC7F,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAAO,EAA2B,EAAqB,GAGzD,IAAM,EAAiB,CAAC,EACpB,EAAsB,GACtB,EAAY,GAEhB,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAsB,EACtB,QACF,CAGA,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,EAAM,EAAG,MAAM,SAAW,CAAC,EAE/D,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAc,GAEpC,QACF,CAGA,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GACjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,SAGF,IAAM,GAAgB,EAAK,aAAe,WAAa,QAEjD,EAAY,EAAU,EAAQ,EAAK,KAAK,EAExC,EAAgB,EAAc,EAAM,CACxC,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,eACA,WACF,CAAC,EAEG,IACE,CAAC,GAAa,IAChB,EAAe,KAAK,CAAmB,EACvC,EAAsB,IAExB,EAAY,GACZ,EAAe,KAAK,CAAa,EAErC,CAMA,OAJI,EAAe,SAAW,EACrB,EAGF,GAAG,EAAG,IAAM,OAAS,GAAG,GAAG,EAAe,KAAK,EAAgB,CAAE,EAAI,IAAI,EAAG,WAAW,GAAK,GAAG,EAAE,EAC1G,EAEA,OAAO,EAAiB,EAAW,EAAI,CACzC,ECpFa,IACV,EAAW,IAAY,GAAQ,CAC9B,GAAM,CACJ,SACA,wBACA,uBACA,0BACA,uBACA,eACA,gBACA,UAAU,CAAC,EACX,iBACE,EAEE,EAAM,EAAQ,oBAEpB,GAAI,CAAC,EAAK,OAEV,GAAM,CAAE,MAAK,KAAI,MAAK,MAAO,EAEvB,EAAW,EAAG,EAAG,CAAC,EAGlB,EAAU,OAAO,KAAK,CAAI,EAGhC,GAAI,EAAQ,SAAW,EAAG,OAAO,EAEjC,IAAM,EAAoB,GAAkD,CAC1E,GACE,CAAC,EACC,EACA,EACE,EAAG,IAAyC,GAEhD,EAEA,OAGF,IAAM,EAAmC,EAAG,MACzC,IAAI,GAAQ,CACX,GAAI,EAAY,CAAI,EAClB,OAAO,EAAiB,CAAI,EAE9B,GAAM,CAAC,EAAkB,GAAkB,EAAa,CAAI,EAC5D,GACE,CAAC,EAAmB,EAAM,EAAkB,CAAc,GAC1D,EAAK,QAAU,GACf,EAAK,WAAa,GAEjB,IAAyB,IAAA,IAAa,EAAK,QAAU,EAEtD,OAEF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAC9C,OAAO,EAAc,EAAM,CACzB,GAAG,EACH,aAAc,EAAsB,GAAW,SAAS,EACxD,YACA,QAAS,CACP,GAAG,EACH,gBAAiB,EACjB,sBAAuB,EAAQ,EACjC,CACF,CAAC,CACH,CAAC,CAAC,CACD,OAAO,OAAO,EAEjB,GAAI,EAAe,SAAW,EAC5B,OAAO,EAIT,IAAM,EACJ,EAAe,SAAW,EACtB,EAAe,GACf,EAAG,aAAe,KAChB,EAAG,GAAI,CAAwC,EAC/C,EAAI,GAAI,CAAyC,EAEzD,OAAO,EAAG,IAAM,EAAI,CAAa,EAAI,CACvC,EAEA,OAAO,EAAiB,EAAc,CAAS,CAAC,GAAK,CACvD,ECjFI,GAAoB,IAAI,IAAI,CAAC,SAAU,QAAS,QAAQ,CAAC,EAEzD,GAAY,sBACZ,GAAY,iCACZ,GAAa,gBACb,GAAY,iBACZ,GAAa,gCACb,GAAa,6BAEb,IAAyB,EAAW,EAAW,IAAuB,CAC1E,IAAM,EAAO,IAAI,KAAK,KAAK,IAAI,EAAG,EAAI,EAAG,CAAC,CAAC,EAC3C,OAAO,EAAK,eAAe,IAAM,GAAK,EAAK,YAAY,IAAM,EAAI,GAAK,EAAK,WAAW,IAAM,CAC9F,EAEM,GAAyB,GAAuB,CACpD,IAAM,EAAQ,EAAE,MAAM,GAAG,EACnB,EAAI,OAAO,EAAM,EAAE,EACnB,EAAI,OAAO,EAAM,EAAE,EACnB,EAAM,EAAM,GAAK,OAAO,WAAW,EAAM,EAAE,EAAI,EACrD,OAAO,GAAK,GAAK,GAAK,IAAM,GAAK,GAAK,GAAK,IAAM,GAAO,GAAK,EAAM,EACrE,EAMM,IAA0B,EAAgB,IAA0C,CACpF,MAAU,MAA+B,IAAU,GAEvD,IAAI,GAAkB,IAAI,CAAS,EAAG,CACpC,IAAM,EAAI,OAAO,GAAU,SAAW,EAAM,KAAK,EAAI,EAGrD,OAFI,OAAO,GAAM,UAAY,OAAO,GAAM,UACtC,OAAO,GAAM,UAAY,GAAa,KAAK,CAAC,EAAG,OAC5C,qBACT,CAEA,GAAI,IAAc,OAAQ,CACxB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EACrB,GAAI,CAAC,GAAU,KAAK,CAAC,EAAG,MAAO,sBAC/B,GAAM,CAAC,EAAG,EAAG,GAAK,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,EACzC,OAAO,GAAsB,EAAG,EAAG,CAAC,EAAI,IAAA,GAAY,qBACtD,CAEA,GAAI,IAAc,iBAAkB,CAClC,GAAI,OAAO,GAAU,SAAU,MAAO,sBAEtC,IAAM,EAAO,EAAM,KAAK,CAAC,CAAC,QAAQ,kCAAmC,EAAE,EACjE,EAAS,EAAK,QAAQ,GAAG,EAC/B,GAAI,IAAW,GAAI,MAAO,sBAC1B,IAAM,EAAW,EAAK,MAAM,EAAG,CAAM,EAC/B,EAAW,EAAK,MAAM,EAAS,CAAC,EACtC,GAAI,CAAC,GAAU,KAAK,CAAQ,GAAK,CAAC,GAAU,KAAK,CAAQ,EAAG,MAAO,sBACnE,GAAM,CAAC,EAAG,EAAG,GAAK,EAAS,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM,EAEhD,OADK,GAAsB,EAAG,EAAG,CAAC,GAC3B,GAAsB,CAAQ,EAAI,IAAA,GAAY,qBACvD,CAEA,GAAI,IAAc,OAAQ,CACxB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EAErB,OADK,GAAU,KAAK,CAAC,GACd,GAAsB,CAAC,EAAI,IAAA,GAAY,qBAChD,CAEA,GAAI,IAAc,QAAS,CACzB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EACrB,GAAI,CAAC,GAAW,KAAK,CAAC,EAAG,MAAO,sBAChC,IAAM,EAAI,OAAO,EAAE,MAAM,CAAC,CAAC,EAC3B,OAAO,GAAK,GAAK,GAAK,GAAK,IAAA,GAAY,qBACzC,CAEA,GAAI,IAAc,OAAQ,CACxB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,IAAM,EAAI,EAAM,KAAK,EACrB,GAAI,CAAC,GAAU,KAAK,CAAC,EAAG,MAAO,sBAC/B,IAAM,EAAI,OAAO,EAAE,MAAM,CAAC,CAAC,EAC3B,OAAO,GAAK,GAAK,GAAK,GAAK,IAAA,GAAY,qBACzC,CAEA,GAAI,IAAc,QAEhB,OADI,OAAO,GAAU,UACd,GAAW,KAAK,EAAM,KAAK,CAAC,EAAI,IAAA,GAAY,sBAGrD,GAAI,IAAc,MAAO,CACvB,GAAI,OAAO,GAAU,SAAU,MAAO,sBACtC,GAAI,CACF,IAAS,IAAI,EAAM,KAAK,CAAC,EACzB,MACF,MAAQ,CACN,MAAO,qBACT,CACF,CAEA,GAAI,IAAc,QAEhB,OADI,OAAO,GAAU,UACd,GAAW,KAAK,EAAM,KAAK,CAAC,EAAI,IAAA,GAAY,qBAhErD,CAoEF,EAYa,IACX,EACA,IACG,CACH,GAAM,CACJ,OAAQ,EACR,uBACA,0BACA,uBACA,eACA,iBACE,EAEE,EAAiC,CAAC,EAClC,EAA0B,CAC9B,WAAY,EACZ,YAAa,EACb,WAAY,EACZ,aAAc,EACd,YAAa,EACb,cAAe,CACjB,EACM,EAA6D,CAAC,EAE9D,EAAe,GAAkB,CAAY,EAC7C,EAAe,IAAI,IACzB,IAAK,IAAM,KAAK,EACd,EAAa,IAAI,EAAE,KAAM,CAAC,EAE5B,IAAM,EAAkB,EAAa,KAAO,EAEtC,GACJ,EACA,IAC8D,CAC9D,EAAM,cACN,IAAM,EAAQ,EAAK,OACb,EAAuB,EAAc,EAAG,IAAM,IAC9C,EAAiB,EAAmB,EAAI,CAAoB,EAE5D,EAAe,GAAW,CAAoB,EAGhD,EAAG,MACL,EAAY,KAAK,CACf,GAAI,EAAG,IAAM,GACb,OACA,KAAM,QACN,QAAS,iBACT,OAAQ,OACV,CAAC,EACQ,CAAC,GAAkB,IAAyB,IAAA,IACrD,EAAY,KAAK,CACf,GAAI,EAAG,IAAM,GACb,OACA,KAAM,mBACN,QAAS,EAAe,YAAY,EAAa,KAAK,IAAI,IAAM,0BAChE,OAAQ,iBACV,CAAC,EAGH,IAAI,EAAmB,GACnB,EAAY,EACV,EAKA,CAAC,EAEP,IAAK,IAAM,KAAQ,EAAG,MAAO,CAE3B,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAe,KAAK,CAAI,EACxB,IACA,QACF,CAEA,IAAM,EAAY,CAAC,GAAG,EAAM,CAAS,EAGrC,GAAI,EAAY,CAAI,EAAG,CACrB,IAAM,EAAiB,EAAiB,EAAM,CAAS,EAClD,EAAe,QAClB,EAAmB,IAErB,EAAe,KAAK,CAAc,EAClC,IACA,QACF,CAGA,EAAM,aACN,IAAM,EAAa,EAAU,OACvB,CAAC,EAAkB,GAAkB,EAAa,CAAI,EACtD,EACJ,EAAmB,EAAM,EAAkB,CAAc,GACzD,EAAK,QAAU,GACf,EAAK,WAAa,IAChB,IAAyB,IAAA,IAAa,EAAK,QAAU,GAGzD,GACE,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,EAEK,EAIH,EAAM,cAHN,EAAmB,GACnB,EAAM,gBAMR,IAAM,EAAY,EAAK,MAClB,EAAa,KAChB,EAAa,GAAa,CAAE,UAAW,EAAG,aAAc,CAAE,GAE5D,EAAa,EAAU,CAAC,YACnB,GACH,EAAa,EAAU,CAAC,eAG1B,IAAM,EACJ,GAAW,CAAgB,GAAK,GAAyB,EAAM,CAAc,EAEzE,EAAuC,CAC3C,GAAG,EACH,MAAO,EACP,GAAI,EAAc,CAAE,QAAS,CAAY,EAAI,KAC7C,KAAM,EACN,MAAO,CACT,EAEA,EAAe,KAAK,CAAa,EACjC,GACF,CAEA,IAAM,EAAa,GAAkB,EA4BrC,OA1BI,EACF,EAAM,cAEN,EAAM,gBAGJ,EAAgB,CAAE,EASb,CAPL,GAAG,EACH,MAAO,EACP,GAAI,EAAe,CAAE,QAAS,CAAa,EAAI,KAC/C,OACA,QACA,MAAO,CAEG,CAYhB,EAEM,EAAQ,EAAiB,EAAW,CAAC,CAAC,EAG5C,GAAI,EAAiB,CACnB,IAAM,EAAmB,IAAI,IAAI,OAAO,KAAK,CAAY,CAAC,EAC1D,IAAK,GAAM,CAAC,KAAc,EACnB,EAAiB,IAAI,CAAS,GACjC,EAAY,KAAK,CACf,GAAI,GACJ,KAAM,CAAC,EACP,KAAM,qBACN,QAAS,UAAU,EAAU,6DAC7B,OAAQ,aACV,CAAC,CAGP,CAEA,MAAO,CAAE,QAAO,cAAa,QAAO,cAAa,CACnD,EAKM,IACJ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACS,CACT,IAAM,EAAK,EAAK,IAAM,GA2CtB,GAzCI,EAAK,OACP,EAAY,KAAK,CACf,KACA,OACA,KAAM,QACN,QAAS,gBACT,OAAQ,OACV,CAAC,EAGC,EAAK,QAAU,GACjB,EAAY,KAAK,CACf,KACA,OACA,KAAM,oBACN,QAAS,+BACT,OAAQ,aACV,CAAC,EAGC,EAAK,WAAa,GACpB,EAAY,KAAK,CACf,KACA,OACA,KAAM,uBACN,QAAS,kCACT,OAAQ,aACV,CAAC,EAGC,IAAyB,IAAA,IAAa,EAAK,QAAU,GACvD,EAAY,KAAK,CACf,KACA,OACA,KAAM,oBACN,QAAS,+BACT,OAAQ,aACV,CAAC,EAKD,CAAC,EAAK,OACN,EAAK,QAAU,GACf,EAAK,WAAa,IAChB,IAAyB,IAAA,IAAa,EAAK,QAAU,GACvD,CACA,GAAI,OAAO,GAAqB,WAAa,CAAC,EAC5C,EAAY,KAAK,CACf,KACA,OACA,KAAM,mBACN,QAAS,yBACT,OAAQ,iBACV,CAAC,OACI,GACL,OAAO,GAAqB,WAC5B,GAAmB,CAAgB,GACnC,CAAC,EAAiB,MAClB,CACA,IAAM,EAAU,EAAiB,QACjC,EAAY,KAAK,CACf,KACA,OACA,KAAM,mBACN,QAAS,EAAU,YAAY,EAAQ,KAAK,IAAI,IAAM,yBACtD,OAAQ,iBACV,CAAC,CACH,MAAO,GAAI,CAAC,GAAa,OAAO,GAAmB,WAAY,CAC7D,IAAM,EAAK,EAAe,CAAI,EACxB,EACJ,OAAO,GAAO,WAAa,GAAmB,CAAE,GAAK,CAAC,EAAG,MAAQ,EAAG,QAAU,IAAA,GAChF,EAAY,KAAK,CACf,KACA,OACA,KAAM,mBACN,QAAS,EAAU,YAAY,EAAQ,KAAK,IAAI,IAAM,+BACtD,OAAQ,iBACV,CAAC,CACH,CACF,CAcA,GAXI,GAAmB,CAAC,EAAa,IAAI,EAAK,KAAK,GAAK,EAAK,QAAU,GACrE,EAAY,KAAK,CACf,KACA,OACA,KAAM,kBACN,QAAS,UAAU,EAAK,MAAM,uCAC9B,OAAQ,aACV,CAAC,EAIC,EAAiB,CACnB,IAAM,EAAW,EAAa,IAAI,EAAK,KAAK,EAC5C,GAAI,GAAU,UAAW,CACvB,IAAM,EAAe,GAAuB,EAAK,MAAO,EAAS,SAAS,EACtE,GACF,EAAY,KAAK,CACf,KACA,OACA,KAAM,EACN,QAAS,UAAU,EAAK,MAAM,uCAAuC,EAAS,UAAU,GACxF,OAAQ,YACV,CAAC,CAEL,CACF,CACF,EAKM,GACJ,GAEsB,CACtB,GACE,OAAO,GAAqB,WAC5B,GAAmB,CAAgB,GACnC,CAAC,EAAiB,OAClB,EAAiB,QAEjB,OAAO,EAAiB,OAG5B,EAKM,IACJ,EACA,IAEsB,CACtB,GAAI,OAAO,GAAmB,WAAY,CACxC,IAAM,EAAK,EAAe,CAAI,EAC9B,GAAI,OAAO,GAAO,WAAa,GAAmB,CAAE,GAAK,CAAC,EAAG,OAAS,EAAG,QACvE,OAAO,EAAG,OAEd,CAEF,EC7eMC,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAO9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,gBAAiB,EACjC,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAe,IAAgB,QAC/B,EAAa,EAAS,YAAY,EAElC,EAAU,GACV,GAAM,KAAgC,OACtC,OAAO,GAAM,WAAa,OAAO,GAAM,SAAiB,OAAO,CAAC,EAChE,GACA,OAAO,GAAM,UAAY,EAAqB,EAAG,CAAY,EACxD,EAAa,CAAC,EAChB,IAAIA,GAAmB,EAAG,CAAY,EAAE,GAGjD,OAAQ,EAAR,CACE,IAAK,IACH,MAAO,GAAG,EAAM,KAAK,EAAO,CAAK,IACnC,IAAK,KACL,IAAK,KACH,MAAO,GAAG,EAAM,MAAM,EAAO,CAAK,IACpC,IAAK,IACL,IAAK,IACL,IAAK,KACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAAG,EAAO,CAAK,IAC/C,IAAK,WACH,MAAO,GAAG,EAAM,YAAY,EAAO,CAAK,IAC1C,IAAK,iBACH,MAAO,OAAO,EAAM,YAAY,EAAO,CAAK,IAC9C,IAAK,aACH,MAAO,GAAG,EAAM,eAAe,EAAO,CAAK,IAC7C,IAAK,mBACH,MAAO,OAAO,EAAM,eAAe,EAAO,CAAK,IACjD,IAAK,WACH,MAAO,GAAG,EAAM,aAAa,EAAO,CAAK,IAC3C,IAAK,iBACH,MAAO,OAAO,EAAM,aAAa,EAAO,CAAK,IAC/C,IAAK,OACH,MAAO,GAAG,EAAM,UAClB,IAAK,UACH,MAAO,GAAG,EAAM,cAClB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAS,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAGxC,OAFK,EAAO,OAEL,GADQ,IAAe,QAAU,OAAS,KAC9B,EAAM,OAAO,EAAO,KAAK,IAAI,EAAE,GAFvB,EAG7B,CACA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAM,EAAQ,CAAK,EACzB,GAAI,EAAI,OAAS,EAAG,MAAO,GAC3B,GAAM,CAAC,EAAK,GAAQ,CAAC,EAAO,EAAI,EAAE,EAAG,EAAO,EAAI,EAAE,CAAC,EAC7C,EAAO,GAAG,EAAI,MAAM,EAAM,OAAO,EAAM,MAAM,IACnD,OAAO,IAAe,aAAe,QAAQ,EAAK,GAAK,CACzD,CACA,QACE,MAAO,GAAG,EAAM,GAAG,EAAS,GAAG,EAAO,CAAK,GAC/C,CACF,ECzDa,IAA8C,EAAM,IAA8B,CAC7F,IAAM,EAAO,GAA+C,CAAC,EAEvD,CAAE,eAAc,qBAAoB,UAAU,CAAC,GAAM,EACrD,CAAE,UAAS,mBAAkB,gBAAiB,EAMpD,GAAI,CAAC,GAAW,CAAC,EAAkB,OAEnC,GAAM,CACJ,UACA,KACA,KACA,MACA,UACA,YACA,SACA,OACA,KACA,MACA,KACA,aACA,aACA,UACA,OACE,EAEE,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EACJ,GAAgB,uBAAuB,KAAK,CAAK,EAC5C,EAAI,IAAI,CAAK,EACd,EAAQ,GACR,GAAa,EAAG,CAAQ,EAExB,GAAe,IAAgB,QAC/B,GAAkB,GAAwB,GAAe,EAAQ,GAAK,EAGtE,GAAoB,GACpB,IAAgB,CAAC,EAAqB,GAAe,CAAW,EAC7D,EAAqB,EAAG,EAAI,EAAI,EAAY,EAAG,CAAE,aAAc,EAAK,CAAC,EAAI,EAGlF,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAY,EAAiB,CAAI,EAEnC,OAAc,GAEX,IAAI,EAAW,CAEpB,GAAI,EAAK,SAAW,aAAc,OAElC,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,EAAW,EAAe,EAAK,MAAwB,CAC3D,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,CAAkB,EACxD,CAAC,EAEK,EAAoB,GAAiC,EAAU,CACnE,GAAI,EACJ,QAAS,CAAE,GAAG,EAAK,QAAS,aAAc,EAAK,EAC/C,cAAe,EAAgB,CACjC,CAAC,EAED,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,EAAG,gCAAgC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,mBAAmB,EAAO,MAEhK,IAAK,OACH,MAAO,EAAG,oCAAoC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,GAE1I,IAAK,OACH,MAAO,EAAG,gCAAgC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,GAEtI,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAElE,OAAO,EAAY,GAAK,EAAY,EAChC,CAAG,0CAA0C,EAAO,mBAAmB,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,IAAI,EAAI,IAAI,GAAG,EAAG,GAAG,GAAW,IACjM,CAAG,gCAAgC,EAAO,OAAO,EAAI,IAAI,CAAiB,EAAE,SAAS,EAAkB,CAAC,EAAG,CAAgB,EAAE,IAAI,EAAI,IAAI,GAAG,EAAG,GAAG,GAAW,GACnK,CACF,CACF,CAEA,OAAQ,GAAR,CACE,IAAK,IACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,IACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,IACH,OAAO,EAAG,EAAQ,GAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAI,EAAQ,GAAiB,CAAK,CAAC,EAC5C,IAAK,KACH,OAAO,EAAI,EAAQ,GAAiB,CAAK,CAAC,EAC5C,IAAK,aACL,IAAK,mBACH,OAAQ,KAAe,mBAAqB,EAAU,EAAA,CACpD,EACA,GAAe,CAAG,GAAG,GAAe,CAAK,EAAE,SAAW,GAAG,EAAM,EACjE,EACF,IAAK,WACL,IAAK,iBACH,OAAQ,KAAe,iBAAmB,EAAU,EAAA,CAClD,EACA,GAAe,CAAG,UAAU,GAAe,CAAK,EAAE,SAAW,IAAI,EAAM,EACzE,EACF,IAAK,WACL,IAAK,iBACH,OAAQ,KAAe,iBAAmB,EAAU,EAAA,CAClD,EACA,GAAe,CAAG,UAAU,GAAe,CAAK,IAAM,IAAI,GAC5D,EACF,IAAK,OACH,OAAO,EAAO,CAAM,EACtB,IAAK,UACH,OAAO,EAAU,CAAM,EACzB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,GAAiB,CAAC,CAAC,EAChE,OAAO,KAAe,QAClB,EAAW,EAAQ,CAAY,EAC/B,EAAQ,EAAQ,CAAY,CAClC,CACA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CAGA,GAAI,CAAC,EAAO,GAAwB,EAG9B,EAAuB,IAAiB,GAC9C,GACE,CAAC,IACD,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,MAEM,KACF,EAAQ,GAAe,CAAK,EAC5B,EAAS,GAAe,CAAM,GAGlC,OAAO,KAAe,aAClB,EAAW,EAAQ,EAAO,CAAM,EAChC,EAAQ,EAAQ,EAAO,CAAM,CACnC,CACA,MACF,CACA,QACE,MACJ,CAxFA,CAyFF,EC7JM,GAAmB,CAAE,IAAK,KAAM,KAAM,MAAO,IAAK,KAAM,KAAM,KAAM,EAKpEC,IACJ,EACA,IAEA,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAC3C,CAAE,KAAM,CAAE,SAAU,CAAkB,CAAE,EACxC,EAEA,GAAY,GAAc,GAAG,QAAQ,UAAW,MAAM,EAEtD,GAA2E,CAC/E,WAAY,aACZ,iBAAkB,aAClB,eAAgB,WAChB,eAAgB,WAChB,SAAU,UACZ,EACM,IAAiB,EAAW,EAAmC,IAAc,CACjF,IAAM,EAAS,QAAQ,EAAE,WAAW,GAAgB,IAAM,EAAE,QAAQ,EAAE,WACtE,OAAO,EAAE,WAAW,GAAG,EAAI,IAAI,IAAW,CAC5C,EAEM,IAAiB,EAAY,IACjC,OAAO,GAAM,UACT,EACA,EAAqB,EAAG,CAAY,EAClC,EAAY,EAAG,CAAE,cAAa,CAAC,EAC/B,EAOK,IACX,EACA,EAAU,CAAC,IACwC,CACnD,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,sBAAuB,EACvC,EAAa,EAAG,CAAQ,EAExB,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,QAAS,EAEX,EAAW,GACf,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,GAAG,EAAM,GAAG,EAAE,QAAU,CAAM,EAC9E,CAAC,EACD,CACF,EAGA,GAAI,OAAO,KAAK,CAAQ,CAAC,CAAC,SAAW,EACnC,MAAO,GAGT,OAAQ,EAAR,CACE,IAAK,OACH,MAAO,CACL,OAAQ,CACN,KAAM,EACN,MAAO,CACT,CACF,EAGF,IAAK,OACH,MAAO,CACL,KAAM,CACJ,SAAU,CACR,OAAQ,CACN,KAAM,EACN,MAAO,CACT,CACF,CACF,CACF,EAIF,IAAK,MAKL,IAAK,UACL,IAAK,SACL,IAAK,UACH,MAAO,EAEX,CACF,CAEA,GAAI,IAAgB,QAAS,CAE3B,GAAI,EAAQ,CAAK,CAAC,CAAC,KAAK,GAAK,OAAO,GAAM,QAAQ,EAAG,MAAO,GAE5D,IAAM,EAAiB,GAAS,CAAK,EAErC,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAoB,IAAe,IAAM,KAAO,EAChD,EAAiB,GAAS,CAAK,EACrC,OAAO,EACH,CACE,KAAM,CACJ,OAAQ,CACN,OAAQ,CACN,OAAQ,QAAQ,EAAe,WAAW,EAAkB,QAAQ,EAAe,SACrF,CACF,CACF,CACF,EACA,EACN,CAEA,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,GAAI,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAM,EAAa,IAAI,IAAM,CACjC,KAAM,CACJ,OAAQ,CAAE,OAAQ,CAAE,OAAQ,QAAQ,EAAe,mBAAmB,EAAE,SAAU,CAAE,CACtF,CACF,EAAE,EACF,MAAO,CAAE,KAAM,IAAe,KAAO,CAAE,OAAQ,CAAI,EAAI,CAAE,SAAU,CAAI,CAAE,CAC3E,CACA,MAAO,EACT,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GAAI,EAAa,QAAU,GAAK,EAAa,IAAM,EAAa,GAAI,CAClE,IAAM,EAAS,QAAQ,EAAe,mBAAmB,EAAa,GAAG,mBAAmB,EAAe,mBAAmB,EAAa,GAAG,UAC9I,MAAO,CACL,KAAM,CACJ,OAAQ,CAAE,OAAQ,CAAE,OAAQ,IAAe,aAAe,KAAK,EAAO,GAAK,CAAO,CAAE,CACtF,CACF,CACF,CACA,MAAO,EACT,CAEA,IAAK,WACL,IAAK,iBACL,IAAK,aACL,IAAK,mBACL,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAiB,GAAS,CAAK,EAGrC,OAFK,EAEE,CACL,KAAM,CACJ,OAAQ,CACN,OAAQ,CACN,OALO,GAAc,EAAgB,EAAY,CAK5C,CACP,CACF,CACF,CACF,EAV4B,EAW9B,CACF,CACF,CAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,CACL,MAAO,EACJ,GAAQ,EACN,GAAiB,IAAc,GAAc,EAAO,CAAY,CACnE,CACF,CACF,EAEF,IAAK,IACH,MAAO,CAAE,KAAM,EAAG,GAAQ,GAAc,EAAO,CAAY,CAAE,CAAE,EAEjE,IAAK,KACH,MAAO,CAAE,KAAM,CAAE,SAAU,CAAE,KAAM,EAAG,GAAQ,GAAc,EAAO,CAAY,CAAE,CAAE,CAAE,CAAE,EAEzF,IAAK,OACH,MAAO,CAAE,KAAM,CAAE,SAAU,CAAE,OAAQ,CAAE,OAAM,CAAE,CAAE,CAAE,EAErD,IAAK,UACH,MAAO,CAAE,OAAQ,CAAE,OAAM,CAAE,EAE7B,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,GAAc,EAAG,CAAY,CAAC,EAC3E,GAAI,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAM,EAAa,IAAI,IAAM,CAAE,KAAM,EAAG,GAAQ,GAAc,EAAG,CAAY,CAAE,CAAE,EAAE,EACzF,MAAO,CAAE,KAAM,IAAe,KAAO,CAAE,OAAQ,CAAI,EAAI,CAAE,SAAU,CAAI,CAAE,CAC3E,CACA,MAAO,EACT,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAI,CAAC,EAAO,GAAU,EAGhB,EAAuB,IAAiB,GAC9C,GACE,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,CACA,OAAOA,GAAc,EAAY,CAAE,MAAO,EAAG,GAAQ,CAAE,IAAK,EAAO,IAAK,CAAO,CAAE,CAAE,CAAC,CACtF,CACA,MAAO,EACT,CAEA,IAAK,WACL,IAAK,iBACH,OAAOA,GAAc,EAAY,CAAE,OAAQ,EAAG,GAAQ,CAAE,MAAO,KAAK,EAAM,GAAI,CAAE,CAAE,CAAC,EAErF,IAAK,aACL,IAAK,mBACH,OAAOA,GAAc,EAAY,CAAE,OAAQ,EAAG,GAAQ,CAAE,MAAO,GAAG,EAAM,GAAI,CAAE,CAAE,CAAC,EAEnF,IAAK,WACL,IAAK,iBACH,OAAOA,GAAc,EAAY,CAAE,OAAQ,EAAG,GAAQ,CAAE,MAAO,KAAK,GAAQ,CAAE,CAAE,CAAC,CACrF,CACA,MAAO,EACT,EC3SM,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAS9D,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,gBAAiB,EACjC,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAe,IAAgB,QAC/B,EAAa,EAAS,YAAY,EAGlC,EAAO,EAAM,SAAS,GAAG,EAAI,EAAM,MAAM,GAAG,CAAC,CAAC,IAAI,EAAK,EAEvD,EAAU,GACV,GAAM,KAAgC,OACtC,OAAO,GAAM,WAAa,OAAO,GAAM,SAAiB,OAAO,CAAC,EAChE,GACA,OAAO,GAAM,UAAY,EAAqB,EAAG,CAAY,EACxD,EAAa,CAAC,EAChB,IAAI,GAAmB,EAAG,CAAY,EAAE,GAGjD,OAAQ,EAAR,CACE,IAAK,IACH,MAAO,SAAS,EAAK,KAAK,EAAO,CAAK,EAAE,GAC1C,IAAK,KACL,IAAK,KACH,MAAO,SAAS,EAAK,SAAS,EAAO,CAAK,EAAE,IAC9C,IAAK,IACH,MAAO,SAAS,EAAK,QAAQ,EAAO,CAAK,EAAE,IAC7C,IAAK,IACH,MAAO,SAAS,EAAK,QAAQ,EAAO,CAAK,EAAE,IAC7C,IAAK,KACH,MAAO,SAAS,EAAK,SAAS,EAAO,CAAK,EAAE,IAC9C,IAAK,KACH,MAAO,SAAS,EAAK,SAAS,EAAO,CAAK,EAAE,IAC9C,IAAK,WACH,MAAO,SAAS,EAAK,gBAAgB,EAAO,CAAK,EAAE,IACrD,IAAK,iBACH,MAAO,SAAS,EAAK,mBAAmB,EAAO,CAAK,EAAE,IACxD,IAAK,aACH,MAAO,SAAS,EAAK,kBAAkB,EAAO,CAAK,EAAE,IACvD,IAAK,mBACH,MAAO,SAAS,EAAK,qBAAqB,EAAO,CAAK,EAAE,IAC1D,IAAK,WACH,MAAO,SAAS,EAAK,gBAAgB,EAAO,CAAK,EAAE,IACrD,IAAK,iBACH,MAAO,SAAS,EAAK,mBAAmB,EAAO,CAAK,EAAE,IACxD,IAAK,OACH,MAAO,YAAY,EAAK,IAC1B,IAAK,UACH,MAAO,SAAS,EAAK,IACvB,IAAK,KAAM,CACT,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,SAAS,EAAK,YAAY,EAAM,KAAK,IAAI,EAAE,IADxB,EAE5B,CACA,IAAK,QAAS,CACZ,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,SAAS,EAAK,aAAa,EAAM,KAAK,IAAI,EAAE,IADzB,EAE5B,CACA,IAAK,UAAW,CACd,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,SAAS,EAAK,aAAa,EAAO,EAAI,EAAE,EAAE,IAAI,EAAO,EAAI,EAAE,EAAE,GACtE,CACA,IAAK,aAAc,CACjB,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,SAAS,EAAK,aAAa,EAAO,EAAI,EAAE,EAAE,IAAI,EAAO,EAAI,EAAE,EAAE,GACtE,CACA,QACE,MAAO,SAAS,EAAK,KAAK,EAAO,CAAK,EAAE,EAC5C,CACF,ECjFM,GAAgB,GAAe,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAE9E,IAAS,EAAY,IACzB,IAAI,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAAE,GAE3E,IAAU,EAAgB,IAAkB,EAAM,QAAQ,EAAO,GAAK,EAEtE,GAAqB,GACzB,GAAG,IAAI,WAAW,uBAAwB,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,IAAK,OAAO,GAAG,MAAM,EAOhF,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CACJ,eACA,eACA,qBACA,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BAA2B,IACzB,EAEE,EAAe,IAAgB,QAC/B,EACJ,OAAO,GAAU,UACjB,OAAO,GAAU,WACjB,OAAO,GAAU,UACjB,EAAqB,EAAO,CAAY,EAEpC,EAAO,GACX,GAAmB,EAAa,CAAE,sBAAqB,0BAAyB,CAAC,EAE7E,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAa,UAAU,EAAI,CAAK,EAAE,GAClC,EAAgB,kBAAkB,EAAI,CAAK,EAAE,kBAAkB,GACnE,EAAe,EAAwB,CACrC,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,EAAE,MAAQ,MAAM,EAAE,QAAU,IAAK,EACvE,CAAC,EACD,CACF,EAAE,KAEF,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,GAAG,EAAc,KAAK,IAE/B,IAAK,OACH,MAAO,GAAG,EAAc,MAE1B,IAAK,OACH,MAAO,GAAG,EAAc,MAE1B,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAKlE,OAHI,EAAY,GAAK,EAAY,EACxB,GAAG,EAAc,GAAG,EAAG,IAAI,EAAW,KAAK,EAAU,GAEvD,GAAG,EAAc,GAAG,EAAG,GAAG,GACnC,CACF,CACF,CAEA,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,GAAG,EAAI,CAAK,EAAE,GAAG,EAAW,GACjC,EACI,EAAI,EAAa,CAAK,CAAC,EACvB,EACE,EAAa,CAAK,EAClB,GAAM,EAAO,CAAY,IAGnC,IAAK,WACL,IAAK,iBACH,OAAO,GACL,aAAa,EAAI,CAAK,EAAE,IAAI,EAAe,EAAI,EAAa,CAAK,CAAC,EAAI,GAAM,EAAO,CAAY,EAAE,GACjG,GAAa,CAAU,CACzB,EAEF,IAAK,aACL,IAAK,mBACH,OAAO,GACL,EACI,cAAc,EAAI,CAAK,EAAE,eAAe,EAAI,EAAa,CAAK,CAAC,EAAE,OAAO,EAAI,EAAa,CAAK,CAAC,IAC/F,aAAa,EAAI,CAAK,EAAE,MAAM,GAAkB,CAAK,EAAE,IAC3D,GAAa,CAAU,CACzB,EAEF,IAAK,WACL,IAAK,iBACH,OAAO,GACL,EACI,cAAc,EAAI,CAAK,EAAE,YAAY,EAAI,CAAK,EAAE,cAAc,EAAI,EAAa,CAAK,CAAC,EAAE,OAAO,EAAI,EAAa,CAAK,CAAC,IACrH,aAAa,EAAI,CAAK,EAAE,KAAK,GAAkB,CAAK,EAAE,KAC1D,GAAa,CAAU,CACzB,EAEF,IAAK,OACH,MAAO,GAAG,EAAI,CAAK,EAAE,SAEvB,IAAK,UACH,MAAO,GAAG,EAAI,CAAK,EAAE,UAEvB,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,GACL,GAAG,EAAI,CAAK,EAAE,OAAO,EAClB,IAAI,GACH,EACI,GAAG,EAAI,EAAa,CAAG,CAAC,IACxB,EAAqB,EAAK,CAAY,EACpC,GAAG,EAAa,CAAG,IACnB,GAAM,EAAK,CAAY,CAC/B,CAAC,CACA,KAAK,IAAI,EAAE,GACd,GAAa,CAAU,CACzB,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,OAAS,GACtB,GAAuB,EAAa,EAAE,GACtC,GAAuB,EAAa,EAAE,EAEtC,MAAO,GAGT,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EACvD,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EACxD,IACA,EAAa,OAAO,MAAM,CAAQ,EAAK,EAAe,GAAG,IAAU,EAAS,EAC5E,EAAc,OAAO,MAAM,CAAS,EAAK,EAAe,GAAG,IAAW,EAAU,EAEpF,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,IAAM,EACJ,EAAqB,EAAO,CAAY,GAAK,EAAqB,EAAQ,CAAY,EAClF,GAAkB,EAAc,IACpC,EAAe,EAAI,CAAG,EAAI,EAAkB,EAAM,GAAM,EAAK,CAAY,EAErE,EAAa,GAAG,EAAI,CAAK,EAAE,MAAM,EAAe,EAAO,CAAU,EAAE,OAAO,EAAI,CAAK,EAAE,MAAM,EAAe,EAAQ,CAAW,IAEnI,OAAO,IAAe,UAAY,IAAI,EAAW,GAAK,GAAO,EAAY,EAAI,CAC/E,CACF,CAEA,MAAO,EACT,ECvLM,GAAmB,GACvB,EACG,QAAQ,QAAS,KAAK,CAAC,CACvB,QAAQ,aAAc,IAAI,CAAC,CAC3B,QAAQ,UAAW,IAAI,EAEtB,IAAiB,EAAY,IACjC,EAAG,WAAW,KAAK,GAAK,EAAG,WAAW,SAAS,EAAI,CAAE,IAAK,CAAS,EAAI,EAO5D,IAAgD,EAAM,EAAU,CAAC,IAAoB,CAChG,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,eAAc,sBAAuB,EACvC,EAAe,IAAgB,QAC/B,EAA4B,CAAE,IAAK,CAAM,EACzC,EAAyB,GAC7B,EACI,CAAE,IAAK,GAAG,GAAI,EACd,EAAqB,EAAG,CAAY,EAClC,EAAY,EAAG,CAAE,cAAa,CAAC,EAC/B,EAEF,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAE5B,OAAQ,EAAR,CACE,IAAK,MACL,IAAK,OACL,IAAK,OACH,MAAO,EACJ,GAAO,CACN,CAAE,IAAK,CAAM,EACb,EAAM,MAAM,SAAW,GAAK,CAAC,EAAY,EAAM,MAAM,EAAE,EACnD,GAA8B,EAAM,MAAM,GAAI,CAAO,EACrD,GAAmC,EAAO,CAAkC,CAClF,CACF,EAEF,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,KAE5D,EAAgB,CACpB,OAAQ,CACN,CACE,OAAQ,CACN,CAAE,IAAK,CAAM,EACb,EAAM,MAAM,SAAW,GAAK,CAAC,EAAY,EAAM,MAAM,EAAE,EACnD,GAA8B,EAAM,MAAM,GAAI,CAAO,EACrD,GAAmC,EAAO,CAAkC,CAClF,CACF,EACA,CAAE,IAAK,CAAC,EAAG,CAAE,IAAK,aAAc,CAAC,CAAE,EACnC,CACF,CACF,EAEA,GAAI,EAAY,GAAK,EAAY,EAAG,CAClC,IAAM,EAAa,CACjB,OAAQ,CAAC,CAAE,IAAK,CAAM,EAAG,CAAE,IAAK,CAAC,EAAG,CAAE,IAAK,aAAc,CAAC,CAAE,EAAG,CAAC,CAClE,EACA,MAAO,EAAG,GAAK,CAAC,EAAe,CAAE,IAAK,CAAC,EAAY,CAAS,CAAE,CAAC,CAAE,CACnE,CACA,MAAO,EAAG,GAAK,CAAC,EAAe,CAAS,CAAE,CAC5C,CACF,CACF,CAEA,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACH,MAAO,EACJ,GAAgB,CAAU,GAAI,CAAC,EAAa,EAAsB,CAAK,CAAC,CAC3E,EAEF,IAAK,OACL,IAAK,UACH,MAAO,EACJ,GAAG,IAAe,UAAY,IAAM,IAAI,IAAK,CAAC,EAAa,IAAI,CAClE,EAGF,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,EAAsB,CAAC,CAAC,EACrE,OAAO,GAAc,EAAY,CAAE,GAAI,CAAC,EAAa,CAAY,CAAE,CAAC,CACtE,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CAEA,GAAI,CAAC,EAAO,GAAwB,EAG9B,EAAuB,IAAiB,GAC9C,GACE,CAAC,GACD,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,MAAW,IACT,EAAQ,CAAE,IAAK,CAAM,EACrB,EAAS,CAAE,IAAK,CAAO,GAGzB,OAAO,GAAc,EAAY,CADA,KAAM,CAAC,EAAO,EAAa,CAAM,CAC1B,CAAC,CAC3C,CACA,MAAO,EACT,CAEA,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAyB,CAC7B,GAAI,CAAC,EAAsB,CAAK,EAAG,CAAW,CAChD,EACA,OAAO,GAAc,EAAY,CAAQ,CAC3C,CAEA,IAAK,aACL,IAAK,mBAAoB,CACvB,IAAM,EAAyB,CAC7B,WAAY,CAAC,EAAa,EAAsB,CAAK,CAAC,CACxD,EACA,OAAO,GAAc,EAAY,CAAQ,CAC3C,CAEA,IAAK,WACL,IAAK,iBAAkB,CACrB,IAAM,EAAyB,CAC7B,SAAU,CAAC,EAAa,EAAsB,CAAK,CAAC,CACtD,EACA,OAAO,GAAc,EAAY,CAAQ,CAC3C,CACF,CACA,MAAO,EACT,EC5KM,IAAY,EAAgB,IAAqB,EAAS,KAAK,EAAO,GAAK,GAAG,IAE9E,GAAc,GAClB,GAAG,EAAa,CAAC,IAAI,WACnB,kBACC,GAAc,KAAK,EAAE,YAAY,CAAC,CAAC,CAAE,SAAS,EAAE,GACnD,EAOW,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,CAAE,sBAAuB,EACzB,EAAa,EAAG,CAAQ,EAG9B,GAEE,IAAgB,SAEf,GAAuB,CAAK,GAAK,IAAe,QAAU,IAAe,WAE1E,EAAiB,CAAI,EAErB,MAAO,GAGT,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACH,OAAO,GAAS,IAAI,EAAM,GAAG,GAAW,CAAK,EAAE,GAAI,IAAe,IAAI,EAExE,IAAK,IACL,IAAK,KACH,MAAO,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,GAEzC,IAAK,IACL,IAAK,KACH,MAAO,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,GAEzC,IAAK,WACL,IAAK,iBACH,OAAO,GAAS,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,IAAK,IAAe,gBAAgB,EAEtF,IAAK,aACL,IAAK,mBACH,OAAO,GAAS,IAAI,EAAM,GAAG,GAAW,CAAK,EAAE,IAAK,IAAe,kBAAkB,EAEvF,IAAK,WACL,IAAK,iBACH,OAAO,GAAS,IAAI,EAAM,IAAI,GAAW,CAAK,EAAE,GAAI,IAAe,gBAAgB,EAErF,IAAK,OACL,IAAK,UACH,OAAO,GAAS,IAAI,EAAM,KAAM,IAAe,SAAS,EAE1D,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,OAAO,GACL,KAAK,EAAa,IAAI,GAAO,IAAI,EAAM,GAAG,GAAW,CAAG,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,GACvE,IAAe,OACjB,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,OAAS,GACtB,GAAuB,EAAa,EAAE,GACtC,GAAuB,EAAa,EAAE,EAEtC,MAAO,GAGT,GAAM,CAAC,EAAO,GAAU,EAClB,EAAW,EAAqB,EAAO,EAAI,EAC7C,EAAY,EAAO,CAAE,aAAc,EAAK,CAAC,EACzC,IACE,EAAY,EAAqB,EAAQ,EAAI,EAC/C,EAAY,EAAQ,CAAE,aAAc,EAAK,CAAC,EAC1C,IACA,EAAa,OAAO,MAAM,CAAQ,EAAI,EAAQ,EAC9C,EAAc,OAAO,MAAM,CAAS,EAAI,EAAS,EAErD,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,OAAO,GACL,MAAM,EAAM,IAAI,GAAW,CAAU,EAAE,IAAI,EAAM,IAAI,GAAW,CAAW,EAAE,IAC7E,IAAe,YACjB,CACF,CACF,CAGA,MAAO,EACT,EChHM,IAA2B,EAAY,EAAmB,IAC9D,GAAgB,OAAO,GAAM,SACzB,EAAE,WAAW,GAAG,IAAa,GAAG,IAAY,GAAW,EACrB,EAO3B,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CACJ,eACA,SACA,eACA,sBACA,kBACA,2BACA,gBACE,EACE,EAAe,EAAK,cAAgB,QACpC,EAAoB,EAAG,EAAK,QAAQ,EACpC,EACJ,GAAsD,IAElD,EAAc,GAAe,GAAG,IAAY,IAAI,IAChD,EAAe,GAAe,GAAwB,EAAG,EAAW,CAAY,EAChF,EAAiB,GAAe,EAAW,EAAY,CAAC,CAAC,EACzD,EAAiB,GACrB,GAAmB,EAAG,CAAE,sBAAqB,0BAAyB,CAAC,EAEnE,EAAI,GAAmD,CAAC,EACxD,EAAO,EAAE,IAAM,KACf,EAAS,EAAE,MAAQ,OACnB,EAAU,EAAE,OAAS,QACrB,EAAU,EAAE,eAAiB,KAC7B,EAAiB,CAAC,EAAE,cAE1B,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,UACH,MAAO,GAGT,IAAK,UACL,IAAK,aAAc,CACjB,GAAI,CAAC,EACH,OAAO,GAA4B,EAAM,CAAI,EAG/C,IAAM,EAAe,EAAQ,EAAK,MAAO,CAAE,mBAAoB,EAAK,CAAC,CAAC,CACnE,MAAM,EAAG,CAAC,CAAC,CACX,IAAI,GACH,EACE,EACG,GACoC,CAAC,EACtC,CACF,CAAC,EAAE,OAAS,CACd,CACF,EAQF,OANE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAEtB,GAEF,GAA4B,CAAE,GAAG,EAAM,MAAO,CAAa,EAAG,CAAI,CAC3E,CAEA,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,EAAK,KAAK,EACvC,GAAI,EAAa,SAAW,EAAG,MAAO,GACtC,IAAM,EAAiB,EAAa,IAAI,GACtC,EACI,EACE,EACG,GACoC,CAAC,EACtC,CACF,CAAC,EAAE,OAAS,CACd,EACA,EAAqB,EAAG,CAAY,EAClC,GAAG,EAAa,CAAC,IACjB,GAAG,EAAc,CAAC,GAC1B,EACA,GAAI,EAAe,SAAW,EAC5B,OAAO,EAAe,GAExB,IAAM,EAAc,GAAkB,EAAe,OAAS,EAAI,IAAM,GAExE,MAAO,IAAI,GADK,EAAe,MAAM,EAAG,EAAE,CAAC,CAAC,KAAK,CAAO,IAAI,EAAY,GAAG,EAAK,GAAG,EAAe,GAAG,EAAE,IACvF,EAClB,CACF,CAMA,OAJI,OAAO,EAAK,OAAU,UACjB,EAAK,MAAQ,EAAS,EAGxB,EACH,EACE,EACG,GACoC,CAAC,EACtC,EAAK,KACP,CAAC,EAAE,OAAS,EAAK,KACnB,EACA,EAAqB,EAAK,MAAO,CAAY,EAC3C,GAAG,EAAa,EAAK,KAAK,IAC1B,GAAG,EAAc,EAAK,KAAK,GACnC,ECxGa,GAA8C,CACzD,IAAK,CAAC,KAAM,6BAA6B,EACzC,KAAM,CAAC,SAAU,iCAAiC,EAClD,IAAK,CAAC,eAAgB,2BAA2B,EACjD,IAAK,CAAC,kBAAmB,8BAA8B,EACvD,KAAM,CAAC,2BAA4B,uCAAuC,EAC1E,KAAM,CAAC,8BAA+B,0CAA0C,EAChF,SAAU,CAAC,WAAY,uBAAuB,EAC9C,WAAY,CAAC,cAAe,0BAA0B,EACtD,SAAU,CAAC,YAAa,wBAAwB,EAChD,eAAgB,CAAC,mBAAoB,+BAA+B,EACpE,iBAAkB,CAAC,sBAAuB,kCAAkC,EAC5E,eAAgB,CAAC,oBAAqB,gCAAgC,EACtE,KAAM,UACN,QAAS,cACT,GAAI,CAAC,uBAAwB,2BAA2B,EACxD,MAAO,CAAC,2BAA4B,iCAAiC,EACrE,QAAS,CAAC,aAAc,0BAA0B,EAClD,WAAY,CAAC,iBAAkB,8BAA8B,CAC/D,EAGM,OAA4B,CAAC,EAOtB,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,QAAO,WAAU,cAAc,SAAY,EAE7C,CACJ,eAAe,GACf,YAAa,EAAmB,IAC9B,EAGE,EAAoB,IAAI,IAC5B,OAAO,QAAQ,EAAwB,CACzC,EACA,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAgB,EACxD,EAAkB,IAAI,EAAG,CAAG,EAAG,CAAK,EAEtC,IAAM,EAAc,OAAO,YAAY,CAAiB,EAGlD,EAAa,EAAG,CAAQ,EAE9B,IAAI,EAAqB,EAEzB,IAAM,EAAiB,EAAQ,EAAK,KAAK,CAAC,CAAC,SAAW,EAElD,IAAe,MAAQ,EACzB,EAAqB,IACZ,IAAe,SAAW,IACnC,EAAqB,MAGvB,GAAM,CAAE,MAAO,EAAY,SAAU,EACnC,EACE,EAAa,EAAO,CAClB,UAAW,EAAK,WAAa,CAC3B,KAAM,EACN,MAAO,EACP,MAAO,CACT,CACF,CAAC,GAAwC,CAAC,CAC5C,EACA,CACF,GAAK,CACH,KAAM,EACN,MAAO,EACP,MAAO,CACT,EAGM,EAAa,EAAY,IAC7B,EAAY,EAAG,CAAU,IAAwC,CAAC,EAAO,CAAK,EAGhF,OAAO,OAAO,GAAe,SAAW,EAAa,EAAW,MAAgB,SAClF,EAOa,IAAyC,EAAM,IAAS,CACnE,GAAM,CAAE,QAAO,YAAa,EAEtB,CACJ,YACA,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BAA2B,GAC3B,kBAAkB,IAClB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,KACjB,YAAY,OACV,GAA2C,CAAC,EAE1C,EAAiB,GAAmB,GAAW,OAAS,EAAO,CACnE,sBACA,0BACF,CAAC,EAEK,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,MAAO,GACF,GAAI,EAAW,CACpB,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAoB,GAA4B,EAAK,MAAO,CAChE,GAAI,EACJ,OAAQ,EAAiB,GAAW,eAAiB,CAAC,CAAC,CACzD,CAAC,EAGK,GAAO,GAAW,eAAe,QAAU,GAAK,EAEtD,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,IAAI,EAAM,OAAS,GAAG,gBAAgB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAEpG,IAAK,OACH,MAAO,IAAI,EAAM,OAAS,GAAG,aAAa,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAEjG,IAAK,OACH,MAAO,IAAI,EAAM,OAAS,GAAG,uBAAuB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAE3G,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,EAAK,QAAQ,KAAM,KAAK,EAInC,OAHI,EAAY,GAAK,EAAY,EACxB,IAAI,EAAM,OAAS,KAAK,EAAG,GAAG,EAAY,IAAI,oBAAoB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,GAEzH,IAAI,EAAM,OAAS,KAAK,EAAG,GAAG,EAAU,mBAAmB,IAAiB,EAAM,IAAM,GAAG,GAAG,EAAkB,EACzH,CACF,CACF,CAEA,IAAM,EAAQ,EAAe,EAAM,CACjC,GAAG,EACH,sBACA,2BACA,kBACA,gBACF,CAAC,EAEK,EAAa,EAAG,CAAQ,EAC9B,IACG,IAAe,MACd,IAAe,SACf,IAAe,WACf,IAAe,eACjB,CAAC,EAED,MAAO,GAKT,IAAM,EAAe,CACnB,EAAG,EACH,EAJwB,EAAkB,EAAM,CAI7B,EACnB,EAAG,CACL,EAEM,EAAe,GAAM,cAAgB,CAAC,EACtC,EAAoC,CACxC,EAAG,EAAa,cAAgB,IAChC,EAAG,EAAa,WAAa,IAC7B,EAAG,EAAa,aAAe,GACjC,EAEM,EAAiB,GAA8B,CAAS,CAAC,CAAC,OAC9D,GAAQ,EAAa,KAAU,EACjC,EACA,OAAO,EACJ,KACE,EAAM,IAAM,GAAG,EAAa,KAAQ,EAAI,EAAe,OAAS,EAAI,EAAU,GAAQ,IACzF,CAAC,CACA,KAAK,EAAE,CAAC,CACR,KAAK,CACV,EClMa,GAA6C,GAAQ,EAAG,GAAe,EAAK,QAAQ,CAAC,EAOrF,IAA0C,EAAM,EAAO,CAAC,IAAM,CACzE,GAAM,CACJ,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BAA2B,GAC3B,kBAAkB,IAClB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,MACf,EAEE,EAAiB,GACrB,GAAmB,EAAG,CAAE,sBAAqB,0BAAyB,CAAC,EAEnE,EAAY,EAAc,EAAK,KAAK,EAEpC,EAAY,EAAiB,CAAI,EAEvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CAEpB,GAAI,GAAM,SAAW,aAAc,MAAO,GAE1C,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,EAAoB,GACxB,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,CAAkB,EACxD,CAAC,EACD,CAAE,GAAI,EAAkC,cAAe,EAAgB,CAAE,CAC3E,EAEA,OAAQ,EAAR,CACE,IAAK,MACH,MAAO,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,mBAAmB,EAAU,MAEnJ,IAAK,OACH,MAAO,oCAAoC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,GAE1H,IAAK,OACH,MAAO,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,GAEtH,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAElE,MAAO,mBAAmB,EAAY,GAAK,EAAY,EAAI,0BAA0B,EAAU,MAAQ,GAAG,eAAe,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAkB,IAAI,EAAG,GAAG,GAClN,CACF,CACF,CAEA,IAAM,EAAQ,EAAe,EAAM,CACjC,GAAG,EACH,sBACA,2BACA,kBACA,gBACF,CAAC,EAEK,EAAW,EAAkB,EAAM,CAAI,EAEvC,EAAoB,EAAG,CAAQ,EAWrC,OATG,IAAsB,MACrB,IAAsB,UACtB,IAAsB,WACtB,IAAsB,gBACxB,CAAC,EAEM,GAGF,GAAG,EAAU,GAAG,EAAS,GAAG,IAAQ,KAAK,CAClD,EC7Ea,IAAoD,EAAM,EAAM,IAAS,CAEpF,GAAM,CACJ,YACA,SACA,oBACA,eACA,cACA,mBACA,iBACA,sBAAsB,CAAC,GAAI,EAAE,EAC7B,2BACA,iBACA,oBAAoB,GACpB,iBAAiB,IACf,GAAQ,CAAC,EAEP,CAAE,kBAAkB,CAAC,GAAM,GAAQ,CAAC,EAEpC,EAAgB,IAAW,gBAE3B,EAAgB,CAAC,EAEjB,EAAmC,CAAC,EAEpC,EAAY,GAChB,EAAgB,CAAE,MAAK,QAAO,EAAI,CAAE,MAAK,OAAQ,CAAY,EAEzD,EAAiB,GACrB,GAAmB,EAAG,CAAE,sBAAqB,0BAAyB,CAAC,EAEnE,EAAY,EAAc,EAAK,KAAK,EAEpC,EAAY,EAAiB,CAAI,EAGvC,GAAI,IAAc,GAChB,OACK,GAAI,EAAW,CAEpB,GAAI,GAAM,SAAW,aAAc,OAAO,EAAS,EAAE,EAErD,GAAM,CAAE,OAAM,aAAc,EAEtB,EAAgB,EAAK,eAAiB,EACtC,EAAoB,GAAwB,CAAa,EAEzD,CAAE,IAAK,EAAW,OAAQ,GAAiB,GAC/C,EAAe,EAAK,MAAwB,CAC1C,cAAe,IAAM,CAAE,GAAG,EAAG,MAAO,CAAkB,EACxD,CAAC,EACD,CACE,GAAI,EACJ,OAAQ,CAAC,EACT,cAAe,EAAgB,CACjC,CACF,EAQA,OANI,MAAM,QAAQ,CAAY,EAC5B,EAAO,KAAK,GAAG,CAAY,EAE3B,OAAO,OAAO,EAAa,CAAY,EAGjC,EAAR,CACE,IAAK,MACH,OAAO,EACL,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,mBAAmB,EAAU,KACpI,EAEF,IAAK,OACH,OAAO,EACL,oCAAoC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,EAC3G,EAEF,IAAK,OACH,OAAO,EACL,gCAAgC,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,EACvG,EAEF,IAAK,UACL,IAAK,SACL,IAAK,UAAW,CACd,IAAM,EAAK,IAAS,UAAY,KAAO,IAAS,SAAW,KAAO,IAElE,OAAO,EACL,mBAAmB,EAAY,GAAK,EAAY,EAAI,0BAA0B,EAAU,MAAQ,GAAG,eAAe,EAAU,OAAO,EAAc,CAAiB,EAAE,SAAS,EAAU,IAAI,EAAG,GAAG,GACnM,CACF,CACF,CACF,CAGA,IAAM,EAAQ,EAAe,EAAM,CACjC,eACA,sBACA,iBACA,YACA,QACF,CAAC,EAEK,EAAc,EAAkB,EAAM,CAAI,EAC1C,EAAuB,EAAG,CAAW,EACrC,CAAC,EAAM,GAAS,EAEtB,IACG,IAAyB,MACxB,IAAyB,UACzB,IAAyB,WACzB,IAAyB,gBAC3B,CAAC,EAED,OAAO,EAAS,EAAE,EACb,GAAI,IAAyB,WAAa,IAAyB,cACxE,OAAO,EAAS,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,GAAa,EACxD,GAAI,EAAK,cAAgB,YAAa,CAM3C,IAAM,EAAiB,GAAe,CACpC,IAAM,EAAM,GAAgB,EAAG,CAAW,EAI1C,OAHK,IACH,EAAY,EAAmB,EAAM,GAAiB,EAAG,CAAW,GAAK,MAEpE,CACT,EACA,GAAI,IAAyB,WAAa,IAAyB,cAAe,CAEhF,GAAM,CAAC,EAAO,GADO,EAAQ,EAAK,MAAO,CAAE,mBAAoB,EAAK,CACjC,CAAC,CAAC,MAAM,EAAG,CAAC,EAC/C,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,EAAc,CAAK,EAAE,OAAO,EAAc,CAAM,IAAI,KAAK,CAC1G,CACF,CACA,GAAI,IAAyB,MAAQ,IAAyB,SAAU,CACtE,IAAM,EAAa,EAAQ,EAAK,KAAK,EACrC,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,IAAI,EAAW,IAAI,GAAK,EAAc,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EACnG,CACF,CAGA,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,GAAiB,EAAc,EAAK,KAAK,EAAG,EAAG,EAAK,QAAQ,EAAG,CAAE,gBAAe,CAAC,IAAI,KAAK,CAC3I,CACF,CAAO,GAAI,EAAK,cAAgB,QAC9B,OAAO,EAAS,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,IAAQ,KAAK,CAAC,EACxE,GAAI,IAAyB,MAAQ,IAAyB,SAAU,CAC7E,IAAM,EAAa,EAAQ,EAAK,KAAK,EACrC,GAAI,EAAe,CACjB,IAAK,IAAM,KAAK,EACd,EAAO,KAAK,EAAqB,EAAG,CAAY,EAAI,EAAY,EAAG,CAAE,cAAa,CAAC,EAAI,CAAC,EAE1F,OAAO,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,IAAI,EAC7C,KAAK,EAAI,IACR,EACI,GAAG,IAAc,EAAgB,OAAS,EAAI,EAAW,QAAU,EAAW,OAAS,KACvF,GACN,CAAC,CACA,KAAK,IAAI,EAAE,EAChB,CACF,CACA,IAAM,EAAqB,CAAC,EAC5B,IAAK,IAAM,KAAK,EAAY,CAC1B,IAAM,EAAgB,EAAmB,EAAK,KAAK,EACnD,EAAS,KAAK,GAAG,IAAc,GAAe,EAC9C,EAAY,GAAG,EAAmB,EAAc,KAAK,KAAmB,EACtE,EACA,CACF,EACI,EAAY,EAAG,CAAE,cAAa,CAAC,EAC/B,CACN,CACA,OAAO,EAAS,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,IAAI,EAAS,KAAK,IAAI,EAAE,EAAE,CACxF,CAAO,GAAI,IAAyB,WAAa,IAAyB,cAAe,CAEvF,GAAM,CAAC,EAAO,GADO,EAAQ,EAAK,MAAO,CAAE,mBAAoB,EAAK,CACjC,CAAC,CACjC,MAAM,EAAG,CAAC,CAAC,CACX,IAAI,GAAM,EAAqB,EAAG,CAAY,EAAI,EAAY,EAAG,CAAE,cAAa,CAAC,EAAI,CAAE,EAC1F,GAAI,EAEF,OADA,EAAO,KAAK,EAAO,CAAM,EAClB,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAC1C,EAAiB,GAAG,IAAc,EAAgB,OAAS,IAAM,IAClE,OAAO,EAAiB,GAAG,IAAc,EAAgB,OAAS,IAAM,KAC3E,EAEF,IAAM,EAAiB,EAAmB,EAAK,KAAK,EAC9C,EAAkB,EAAmB,EAAK,KAAK,EAGrD,MAFA,GAAY,GAAG,EAAmB,EAAc,KAAK,KAAoB,EACzE,EAAY,GAAG,EAAmB,EAAc,KAAK,KAAqB,EACnE,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAAG,IAAc,EAAe,OAAO,IAAc,GACnG,CACF,CAEA,IAAI,EAAa,EAAK,MAClB,OAAO,EAAK,OAAU,WACxB,AAKE,EALE,EAAqB,EAAK,MAAO,CAAY,EAClC,EAAY,EAAK,MAAO,CAAE,cAAa,CAAC,EAIxC,UAAU,KAAK,CAAK,EAC7B,EAAM,WAAW,WAAY,EAAE,EACG,GAI1C,IAAI,GAAY,GAQhB,OAPI,EACF,EAAO,KAAK,CAAU,GAEtB,GAAY,EAAmB,EAAK,KAAK,EACzC,EAAY,GAAG,EAAmB,EAAc,KAAK,MAAe,GAG/D,EACL,GAAG,IAAO,EAAK,QAAQ,EAAM,GAAG,EAAY,GAC1C,EACI,EACE,GAAG,IAAc,EAAgB,OAAS,IAC1C,IACF,GAAG,IAAc,OACpB,KAAK,CACV,CACF,ECtPM,IAAoB,EAAgB,EAAa,IACrD,EAAqB,EAAO,CAAC,CAAC,GAAgB,OAAO,GAAU,QAAQ,EACnE,OAAO,EAAY,EAAO,CAAE,aAAc,CAAC,CAAC,CAAa,CAAC,CAAC,EAC3D,EAOO,IACX,EAEA,EAAU,CAAC,IACR,CACH,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAE1C,CAAE,eAAc,sBAAuB,EAG7C,GAAI,IAAgB,SAAW,EAAiB,CAAI,EAAG,OAEvD,IAAM,EAAa,EAAG,CAAQ,EAC9B,OAAQ,EAAR,CACE,IAAK,IACH,MAAO,EAAG,GAAQ,GAAc,EAAO,EAAO,CAAY,CAAE,EAE9D,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAiB,GAAgB,GACvC,MAAO,EACJ,GAAQ,EACN,GAAiB,GAAc,EAAO,EAAO,CAAY,CAC5D,CACF,CACF,CAEA,IAAK,WACH,MAAO,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,EAExC,IAAK,aACH,MAAO,EAAG,GAAQ,CAAE,WAAY,CAAM,CAAE,EAE1C,IAAK,WACH,MAAO,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,EAExC,IAAK,iBACH,MAAO,CAAE,IAAK,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,CAAE,EAEjD,IAAK,mBACH,MAAO,CAAE,IAAK,EAAG,GAAQ,CAAE,WAAY,CAAM,CAAE,CAAE,EAEnD,IAAK,iBACH,MAAO,CAAE,IAAK,EAAG,GAAQ,CAAE,SAAU,CAAM,CAAE,CAAE,EAEjD,IAAK,OACH,MAAO,EAAG,GAAQ,IAAK,EAEzB,IAAK,UACH,MAAO,EAAG,GAAQ,CAAE,IAAK,IAAK,CAAE,EAElC,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,MAAO,EACJ,GAAQ,EACN,GAAgB,IAAc,EAAa,IAAI,GAC9C,GAAc,EAAK,EAAK,CAAY,CACtC,CACF,CACF,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAM,CAAC,EAAO,GAAU,EAGlB,EAAuB,IAAiB,GACxC,EAAW,EAAqB,EAAO,CAAkB,EAC3D,EAAY,EAAO,CAAE,cAAa,CAAC,EACnC,IACE,EAAY,EAAqB,EAAQ,CAAkB,EAC7D,EAAY,EAAQ,CAAE,cAAa,CAAC,EACpC,IACA,EAAa,OAAO,MAAM,CAAQ,EAAI,EAAQ,EAC9C,EAAc,OAAO,MAAM,CAAS,EAAI,EAAS,EACrD,GACE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,EACZ,CACA,IAAM,EAAU,EAChB,EAAc,EACd,EAAa,CACf,CAEA,OAAO,IAAe,UAClB,EAAG,GAAQ,CAAE,IAAK,EAAY,IAAK,CAAY,CAAE,EACjD,CAAE,GAAI,CAAC,EAAG,GAAQ,CAAE,GAAI,CAAW,CAAE,EAAG,EAAG,GAAQ,CAAE,GAAI,CAAY,CAAE,CAAC,CAAE,CAChF,CACE,MAAO,EAEX,CACF,CACA,MAAO,EACT,ECzGa,IACX,EAEA,CAAE,eAAc,qBAAoB,UAAU,CAAC,GAAM,CAAC,IACd,CACxC,GAAM,CACJ,mBAAoB,EACpB,aAAc,EACd,YAAa,GACX,EAOJ,GAAI,EAAiB,CAAI,EAAG,OAE5B,GAAM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAe,IAAgB,QAE/B,EAAa,EAAG,CAAQ,EAI5B,MAAC,GAEA,IACE,CAAC,GAGC,CAAC,GACA,CACE,WACA,iBACA,aACA,mBACA,WACA,gBACF,CAAC,CAAC,SAAS,CAAU,IAK7B,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,KAAM,CACT,IAAM,EAAoB,CACxB,IAAK,EAAG,GACR,KAAM,EAAG,GACT,IAAK,EAAG,GACR,KAAM,EAAG,IACT,IAAK,EAAG,GACR,KAAM,EAAG,GACX,EAAE,GACF,MAAO,EACJ,GACC,GAAgB,IAAe,IAC3B,EAAG,EAAG,KAAM,CAAM,EAClB,EACG,GAAoB,EACjB,EAAK,CAAK,EACV,EAAqB,EAAO,CAAY,EACtC,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,EAC7C,CACR,CACR,CACF,CAEA,IAAK,WACH,MAAO,EACJ,GAAQ,EACN,EAAe,EAAG,KAAO,EAAG,WAAY,EACrC,EAAI,SAAU,IAAK,EAAK,CAAK,EAAG,GAAG,EACnC,GAAG,GACT,CACF,EAEF,IAAK,aACH,MAAO,EACJ,GAAQ,EACN,EAAe,EAAG,KAAO,EAAG,YAAa,EACtC,EAAI,SAAU,EAAK,CAAK,EAAG,GAAG,EAC9B,GAAG,GACT,CACF,EAEF,IAAK,WACH,MAAO,EACJ,GAAQ,EACN,EAAe,EAAG,KAAO,EAAG,UAAW,EACpC,EAAI,SAAU,IAAK,EAAK,CAAK,CAAC,EAC9B,GAAG,GACT,CACF,EAEF,IAAK,iBACH,MAAO,EACJ,GAAQ,EACN,EAAG,SAAU,EAAe,EAAI,SAAU,IAAK,EAAK,CAAK,EAAG,GAAG,EAAI,IAAI,EAAM,EAChF,CACF,EAEF,IAAK,mBACH,MAAO,EACJ,GAAQ,EAAG,EAAG,SAAU,EAAe,EAAI,SAAU,EAAK,CAAK,EAAG,GAAG,EAAI,GAAG,EAAM,EAAG,CACxF,EAEF,IAAK,iBACH,MAAO,EACJ,GAAQ,EAAG,EAAG,SAAU,EAAe,EAAI,SAAU,IAAK,EAAK,CAAK,CAAC,EAAI,IAAI,GAAQ,CACxF,EAEF,IAAK,OACH,MAAO,EAAG,GAAQ,EAAG,EAAG,IAAK,IAAK,CAAE,EAEtC,IAAK,UACH,MAAO,EAAG,GAAQ,EAAG,EAAG,KAAM,IAAK,CAAE,EAEvC,IAAK,KACL,IAAK,QAAS,CACZ,IAAM,EAAe,EAAQ,CAAK,EAClC,MAAO,EACJ,GAAQ,EACN,IAAe,KAAO,EAAG,GAAK,EAAG,OAAQ,EAAa,IAAI,GACzD,EACI,EAAK,CAAG,EACR,EAAqB,EAAK,CAAY,EACpC,EAAY,EAAK,CAAE,aAAc,QAAS,CAAC,EAC3C,CACR,CACF,CACF,CACF,CAEA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,EAAO,CAAE,mBAAoB,EAAK,CAAC,EAChE,GACE,EAAa,OAAS,GACtB,CAAC,EAAa,EAAa,EAAE,GAC7B,CAAC,EAAa,EAAa,EAAE,EAE7B,OAGF,GAAM,CAAC,EAAO,GAAU,EAElB,EAAW,EAAqB,EAAO,CAAY,EACrD,EAAY,EAAO,CAAE,aAAc,QAAS,CAAC,EAC7C,IACE,EAAY,EAAqB,EAAQ,CAAY,EACvD,EAAY,EAAQ,CAAE,aAAc,QAAS,CAAC,EAC9C,IACE,EAAa,OAAO,MAAM,CAAQ,EAAI,EAAQ,EAC9C,EAAc,OAAO,MAAM,CAAS,EAAI,EAAS,EACjD,EAAoB,CAAC,EAAY,CAAW,EAWlD,MATE,CAAC,GACD,IAAe,GACf,IAAgB,GAChB,EAAY,IAEZ,EAAkB,GAAK,EACvB,EAAkB,GAAK,GAGlB,EACJ,GAAQ,EACN,IAAe,UAAY,EAAG,QAAU,EAAG,YAAa,EACrD,EAAkB,IAAI,GAAK,EAAK,CAAC,CAAC,EAClC,EAAkB,MAAM,GAAK,EAAqB,EAAG,CAAY,CAAC,EAChE,EAAkB,IAAI,GAAK,EAAY,EAAG,CAAE,aAAc,QAAS,CAAC,CAAC,EACrE,CACR,CACF,CACF,CACF,CAEF,ECpMM,IAAsB,EAAY,IACtC,OAAO,GAAM,UAAY,CAAC,EAAe,GAAG,IAAM,EAAE,WAAW,IAAK,KAAK,EAM9D,GAAa,GACxB,QAAQ,KAAK,CAAI,GAAK,EAAK,SAAS,GAAG,EAAI,EAAO,IAAI,IAO3C,IACX,EAEA,EAAO,CAAC,IACL,CACH,GAAM,CAAE,eAAc,gBAAiB,EACjC,CAAE,MAAO,EAAU,WAAU,QAAO,eAAgB,EACpD,EAAe,IAAgB,QAC/B,EAAa,EAAS,YAAY,EAClC,EAAQ,GAAU,CAAQ,EAE1B,EAAU,GAAuB,CACrC,GAAI,GAAM,KAAyB,MAAO,KAC1C,GAAI,OAAO,GAAM,UAAW,MAAO,IAAI,EAAE,gBACzC,GAAI,OAAO,GAAM,SAAU,OAAO,OAAO,CAAC,EAC1C,GAAI,EAAc,OAAO,GAAU,EAAa,CAAC,CAAW,EAC5D,GAAI,OAAO,GAAM,UAAY,EAAqB,EAAG,CAAY,EAC/D,OAAO,EAAa,CAAC,EAEvB,IAAM,EAAI,OAAO,GAAM,SAAW,EAAK,KAAK,UAAU,CAAC,GAAK,GAI5D,OADI,EAAE,WAAW,GAAG,GAAK,EAAE,WAAW,GAAG,GAAK,EAAE,SAAS,GAAG,EAAU,EAC/D,IAAI,GAAmB,EAAG,CAAY,EAAE,EACjD,EAEA,OAAQ,EAAR,CACE,IAAK,IACL,IAAK,KACL,IAAK,IACL,IAAK,IACL,IAAK,KACL,IAAK,KACH,MAAO,GAAG,EAAM,GAAG,EAAW,GAAG,EAAO,CAAK,IAC/C,IAAK,KACH,MAAO,GAAG,EAAM,MAAM,EAAO,CAAK,IACpC,IAAK,WACH,MAAO,YAAY,EAAM,IAAI,EAAO,CAAK,EAAE,GAC7C,IAAK,iBACH,MAAO,aAAa,EAAM,IAAI,EAAO,CAAK,EAAE,GAC9C,IAAK,aACH,MAAO,aAAa,EAAM,IAAI,EAAO,CAAK,EAAE,GAC9C,IAAK,mBACH,MAAO,cAAc,EAAM,IAAI,EAAO,CAAK,EAAE,GAC/C,IAAK,WACH,MAAO,WAAW,EAAM,IAAI,EAAO,CAAK,EAAE,GAC5C,IAAK,iBACH,MAAO,YAAY,EAAM,IAAI,EAAO,CAAK,EAAE,GAC7C,IAAK,OACH,MAAO,UAAU,EAAM,GACzB,IAAK,UACH,MAAO,SAAS,EAAM,GACxB,IAAK,KAAM,CACT,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,GAAG,EAAM,OAAO,EAAM,KAAK,IAAI,EAAE,GADd,EAE5B,CACA,IAAK,QAAS,CACZ,IAAM,EAAQ,EAAQ,CAAK,CAAC,CAAC,IAAI,CAAM,EAEvC,OADK,EAAM,OACJ,GAAG,EAAM,WAAW,EAAM,KAAK,IAAI,EAAE,GADlB,EAE5B,CACA,IAAK,UAAW,CACd,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,GAAG,EAAM,MAAM,EAAO,EAAI,EAAE,EAAE,MAAM,EAAM,MAAM,EAAO,EAAI,EAAE,GACtE,CACA,IAAK,aAAc,CACjB,IAAM,EAAM,EAAQ,CAAK,EAEzB,OADI,EAAI,OAAS,EAAU,GACpB,IAAI,EAAM,KAAK,EAAO,EAAI,EAAE,EAAE,MAAM,EAAM,KAAK,EAAO,EAAI,EAAE,EAAE,EACvE,CACA,QACE,MAAO,GAAG,EAAM,GAAG,EAAS,GAAG,EAAO,CAAK,GAC/C,CACF,EClFa,IACX,EACA,IAC+B,CAE/B,GAAM,CAAE,eAAc,qBAAoB,UAAU,CAAC,GADxC,GAA+C,CAAC,EAEvD,EAAM,EAAQ,oBACd,EAAO,EAAQ,gBACf,EAAiC,EAAQ,sBAE/C,GAAI,CAAC,GAAO,CAAC,GAAQ,CAAC,EAAY,OAElC,GAAM,CAAE,MAAK,KAAI,KAAI,MAAK,UAAS,SAAQ,OAAM,KAAI,MAAK,OAAQ,EAK5D,EAAgB,GAAsB,CAC1C,IAAM,EAAS,EAAU,QAAQ,GAAG,EACpC,GAAI,EAAS,EAAG,CACd,IAAM,EAAS,EAAU,MAAM,EAAG,CAAM,EAClC,EAAO,EAAU,MAAM,EAAS,CAAC,EACvC,GAAI,EAAK,GAAS,OAAO,EAAK,EAAO,CAAC,EACxC,CAEA,OAAO,EAAK,EAAW,CAAC,EAC1B,EAEM,CAAE,QAAO,WAAU,QAAO,eAAgB,EAC1C,EAAS,EAAa,CAAK,EAC3B,EAAa,EAAG,CAAQ,EAExB,EAAe,IAAgB,QAC/B,EAAkB,GAAgB,EAAe,EAAa,CAAW,EAAI,EAG7E,EAAoB,GACpB,GAAgB,CAAC,EAAqB,EAAe,CAAC,EACnD,EAAqB,EAAG,EAAI,EAAI,EAAY,EAAG,CAAE,aAAc,EAAK,CAAC,EAAI,EAGlF,OAAQ,EAAR,CACE,IAAK,IACH,OAAO,EAAG,EAAQ,EAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAI,EAAG,EAAQ,EAAiB,CAAK,CAAC,CAAC,EAChD,IAAK,IACH,OAAO,EAAG,EAAQ,EAAiB,CAAK,CAAC,EAC3C,IAAK,IACH,OAAO,EAAG,EAAQ,EAAiB,CAAK,CAAC,EAC3C,IAAK,KACH,OAAO,EAAI,EAAQ,EAAiB,CAAK,CAAC,EAC5C,IAAK,KACH,OAAO,EAAI,EAAQ,EAAiB,CAAK,CAAC,EAC5C,IAAK,aACL,IAAK,mBAAoB,CAEvB,IAAM,EAAO,EAAK,EADF,EAAe,IAAA,GAAY,GAAG,EAAM,EACnB,EACjC,OAAO,IAAe,mBAAqB,EAAI,CAAI,EAAI,CACzD,CACA,IAAK,WACL,IAAK,iBAAkB,CAErB,IAAM,EAAO,EAAK,EADF,EAAe,IAAA,GAAY,IAAI,EAAM,EACpB,EACjC,OAAO,IAAe,iBAAmB,EAAI,CAAI,EAAI,CACvD,CACA,IAAK,WACL,IAAK,iBAAkB,CAErB,IAAM,EAAO,EAAK,EADF,EAAe,IAAA,GAAY,IAAI,GACd,EACjC,OAAO,IAAe,iBAAmB,EAAI,CAAI,EAAI,CACvD,CACA,IAAK,OACH,OAAO,EAAO,CAAM,EACtB,IAAK,UACH,OAAO,EAAI,EAAO,CAAM,CAAC,EAC3B,IAAK,KACL,IAAK,QAAS,CAEZ,IAAM,EAAO,EAAQ,EADA,EAAQ,CAAK,CAAC,CAAC,IAAI,GAAK,EAAiB,CAAC,CACvB,CAAC,EACzC,OAAO,IAAe,QAAU,EAAI,CAAI,EAAI,CAC9C,CACA,IAAK,UACL,IAAK,aAAc,CACjB,IAAM,EAAe,EAAQ,CAAK,EAClC,GACE,EAAa,QAAU,GACvB,EAAa,EAAa,EAAE,GAC5B,EAAa,EAAa,EAAE,EAC5B,CACA,GAAI,CAAC,EAAO,GAAU,EAChB,EAAuB,IAAiB,GAC9C,GACE,CAAC,GACD,EAAqB,EAAO,CAAkB,GAC9C,EAAqB,EAAQ,CAAkB,EAC/C,CACA,IAAM,EAAW,EAAY,EAAO,CAAE,aAAc,CAAmB,CAAC,EAClE,EAAY,EAAY,EAAQ,CAAE,aAAc,CAAmB,CAAC,EAC1E,GAAI,CAAC,GAAsB,EAAY,EAAU,CAC/C,IAAM,EAAU,EAChB,EAAS,EACT,EAAQ,CACV,KACE,GAAQ,EACR,EAAS,CAEb,MAAW,IACT,EAAQ,EAAe,CAAK,EAC5B,EAAS,EAAe,CAAM,GAEhC,IAAM,EAAO,EAAI,EAAI,EAAQ,CAAK,EAAG,EAAI,EAAQ,CAAM,CAAC,EACxD,OAAO,IAAe,aAAe,EAAI,CAAI,EAAI,CACnD,CACA,MACF,CACA,QACE,MACJ,CACF,EChDa,GAA2D,CACtE,KAAM,CAAC,EACP,OAAQ,CACN,iBAAkB,EACpB,EACA,OAAQ,CAAC,EACT,MAAO,CACL,eAAgB,IAChB,oBAAqB,CAAC,IAAK,GAAG,EAC9B,yBAA0B,IAC1B,YAAa,GACf,EACA,MAAO,CACL,eAAgB,QAClB,EACA,WAAY,CACV,oBAAqB,IACrB,eAAgB,GAChB,YAAa,GACf,CACF,EAOa,GAA+D,CAC1E,GAAG,EACL,EAEM,GAAwB,CAC5B,IAAK,GACL,QAAS,GACT,cAAe,GACf,iBAAkB,GAClB,KAAM,GACN,QAAS,GACT,UAAW,GACX,KAAM,GACN,cAAe,GACf,QAAS,GACT,iBAAkB,GAClB,oBAAqB,GACrB,cAAe,GACf,OAAQ,GACR,UAAW,GACX,KAAM,GACN,IAAK,GACL,YAAa,GACb,OAAQ,GACR,IAAK,GACL,OAAQ,GACR,QAAS,GACT,YAAa,EACf,EAGM,EAA0C,GAAK,EAAE,SACjD,GAA4B,CAChC,IAAK,EACL,QAAS,EACT,cAAe,EACf,iBAAkB,EAClB,KAAM,EACN,QAAS,EACT,UAAW,EACX,KAAM,EACN,cAAe,EACf,QAAS,EACT,iBAAkB,GAClB,oBAAqB,GACrB,cAAe,GACf,OAAQ,EACR,UAAW,EACX,KAAM,EACN,IAAK,GACL,YAAa,EACb,OAAQ,EACR,IAAK,EACL,OAAQ,EACR,QAAS,EACT,YAAa,CACf,EAEM,GAAoE,CACxE,IAAK,SACL,KAAM,GACN,QAAS,0BACT,iBAAkB,SAClB,OAAQ,QACR,QAAS,GACT,KAAM,SACN,IAAK,SACP,EAgBM,GAA4B,CAChC,OAAQ,OACR,OAAQ,CAAC,EACT,oBAAqB,CAAC,GAAI,EAAE,EAC5B,yBAA0B,GAC1B,iBAAoB,CAAC,EACrB,YAAa,IACb,iBAAkB,GAClB,eAAgB,GAChB,mBAAoB,GACpB,qBAAA,IACA,wBAAA,IACA,gBAAiB,IACjB,eAAgB,KAChB,OAAQ,OACR,UAAW,MACX,aAAc,CAAC,EACf,YAAa,CAAC,CAChB,EAEM,GAAsC,IAAI,IAAkB,CAChE,MACA,UACA,gBACA,UACA,YACA,OACA,gBACA,UACA,SACA,YACA,OACA,aACF,CAAC,EAEK,GAAa,IAAI,IAAkB,CACvC,MACA,gBACA,sBACA,UACA,SACA,WACF,CAAC,EAmLD,SAAS,GACP,EACA,EAAiD,CAAC,EAClD,CACA,IAAM,EAAU,OAAO,GAAgB,SAAW,CAAE,OAAQ,EAAG,CAAW,CAAE,EAAI,EAE1E,EAAiC,CACrC,GAAG,GACH,GAAI,CAAC,EAAQ,QAAU,GAAW,IAAI,EAAQ,MAAM,EAC/C,GAAkB,EAAQ,QAAU,SAAW,KAChD,KACJ,GAAG,EACH,GAAI,CAAC,EAAQ,SACV,OAAO,KAAK,EAAiB,CAAC,CAAC,SAAS,EAAQ,QAAU,EAAE,EAAI,CAAE,OAAQ,KAAM,EAAI,KACzF,EAEM,EAAS,EAAG,EAAO,MAAM,EAEzB,CACJ,mBAAoB,EACpB,aAAc,EACd,kBAAmB,EACnB,eACA,oBAAqB,EACrB,mBAAoB,EACpB,cAAe,EACf,YACA,eAAgB,EAChB,WACE,EAEE,EAAyB,GAEtB,OADmB,GAAqB,CAAE,eAAc,WAAU,CAC3C,GAAM,SAChC,GACA,OAAO,GAAiB,UACtB,EACA,IAAA,GAGF,EACJ,OAAO,GAA6B,WAChC,EACC,GAA0B,IAAW,EAEtC,EACJ,OAAO,GAA0B,WAC7B,GAAuB,CAAqB,EAC1C,GAAK,EAAsB,EAAE,MAAO,EAAE,SAAU,EAAE,MAAO,EAAE,WAAW,EACtE,EACF,IAAW,mBACT,GACA,GAAoC,IAAI,CAAM,EAC3C,GAAwB,GAAsB,GAC/C,GAEJ,GACH,OAAO,GAAyB,WAAa,EAAuB,QACpE,GAAoC,IAAI,CAAM,GAC/C,OAAO,GAAyB,YAChC,EACI,EACA,OACJ,GAAsB,IACtB,GAEI,EAAsB,GAA4B,CAA0B,EAC5E,EAAS,EAAiB,EAAO,MAAM,EACvC,GAAoD,EAAG,IAC3D,EACE,EAAoB,EAAG,CAAC,GACa,CAAC,CACxC,EAEI,EACJ,GACA,GAA2B,IAC3B,GAA2B,IAGzB,EAA+B,CAAC,EAGpC,GAAI,OAAO,GAAc,WAAY,CACnC,IAAM,EAAmB,EAAU,CAAS,EAC5C,GAAI,OAAO,GAAqB,UAE1B,IAAA,CAAC,GAGC,IAAW,cACb,OAAO,IAAW,gBACd,CAAE,IAAK,EAAoB,OAAQ,CAAC,CAAE,EACtC,IAAW,sBACT,CAAE,IAAK,EAAoB,OAAQ,CAAC,CAAE,EACtC,IAAW,UACT,IAAI,EAAmB,GACvB,IAAW,gBACT,GACA,IAAW,SACT,GACA,IAAW,YACT,GACA,IAAW,gBACT,CAAC,EACD,IAAW,WAAa,IAAW,aAAe,IAAW,cAC3D,IAAA,GACA,CACpB,KAGF,GAAgB,CAEpB,CAEA,IAAM,EAA8C,CAAC,EAC/C,EAAe,GAAkB,CAAM,EAC7C,IAAK,IAAM,KAAK,EAEV,OAAO,EAAE,WAAc,aACzB,EACE,EAAE,OAA4C,EAAE,MAC9C,EAAE,WAIV,IAAM,EAAgB,GAAmB,CACvC,IAAI,EACA,EAIJ,GAHI,EAAK,KACP,EAAmB,EAAc,EAAK,KAEpC,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAW,EAAa,OAAO,GAAK,EAAE,OAAS,EAAK,KAAK,EAC/D,GAAI,EAAS,OAAS,EAAG,CACvB,IAAM,EAAQ,EAAS,GAEnB,OAAO,EAAM,WAAc,aAC7B,EAAiB,EAAM,UAE3B,CACF,CAEA,GAAI,EAAK,cAAgB,aAAe,OAAO,EAAO,eAAkB,WAAY,CAClF,IAAM,EAAY,EAAU,EAAQ,EAAK,KAAK,EAMzC,IALuB,IAC1B,GACE,EAAiB,EAAO,cAAc,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,CAAC,CACjF,CAAC,CAAC,IAAI,GAAK,GAAiB,EAAE,MAAO,EAAO,WAAW,CAAC,CAEvC,CAAC,CAAC,IAAI,GAAiB,EAAK,MAAO,EAAO,WAAW,CAAC,IACvE,EAAmB,GAEvB,CACA,MAAO,CAAC,EAAkB,CAAc,CAC1C,EAGM,EAAwC,CAC5C,GAAG,EACH,qBACA,SACA,SACA,eACA,wBACA,sBACA,oBACA,gBACA,iBACA,eACA,gBACA,SACF,EAEA,GAAI,OAAO,GAA8B,WACvC,OAAO,EAA0B,EAAW,CAAY,EAG1D,OAAQ,EAAR,CACE,IAAK,OACL,IAAK,mBAAoB,CACvB,IAAM,EAAK,EAAe,GAAe,EAAW,CAAY,EAAI,EAOpE,OANI,IAAW,mBACN,KAAK,UAAU,GAAK,EAAK,IAE9B,IAAQ,MAAQ,IAAQ,OAAS,IAAA,GAAY,GAA4B,EAAK,CAAK,CACrF,EAEK,KAAK,UAAU,EAAI,GAA6B,CAAC,CAC1D,CAEA,IAAK,MACH,OAAO,GAA6B,EAAW,CAAY,EAE7D,IAAK,gBACL,IAAK,sBACH,OAAO,GAAuC,EAAW,CAAY,EAEvE,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,gBACH,OAAO,GAAsC,EAAW,CAAY,EAEtE,IAAK,MACH,OAAO,GAA6B,EAAW,CAAY,EAE7D,IAAK,OACH,OAAO,GAA8B,EAAW,CAAY,EAE9D,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,YACH,OAAO,GAAmC,EAAW,CAAY,EAEnE,IAAK,gBACH,OAAO,GAAuC,EAAW,CAAY,EAEvE,IAAK,mBACH,OAAO,GAA4B,EAAW,CAAY,EAE5D,IAAK,OACH,OAAO,GAA8B,EAAW,CAAY,EAE9D,IAAK,SACH,OAAO,GAAgC,EAAW,CAAY,EAEhE,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,cACH,OAAO,GAAoC,EAAW,CAAY,EAEpE,IAAK,YACH,OAAO,GAAmC,EAAW,CAAY,EAEnE,IAAK,SACL,IAAK,MACH,OAAO,GAAgC,EAAW,CAAY,EAEhE,IAAK,SACH,OAAO,GAAgC,EAAW,CAAY,EAEhE,IAAK,UACH,OAAO,GAAiC,EAAW,CAAY,EAEjE,IAAK,cACH,OAAO,GAAqC,EAAW,CAAY,EAErE,QACE,MAAO,EACX,CACF,CC/oBA,MAAM,GACH,IACA,EAAO,EAAU,EAAO,IACvB,EAAK,CAAE,QAAO,WAAU,QAAO,aAAY,EAAG,CAAE,aAAc,EAAM,CAAC,EAQ5D,GAA8C,GACzD,EACF,EAMa,GAAqD,GAChE,EACF,EAMa,GACX,GAAuB,EAAuB,EAMnC,GACX,GAAuB,EAAwB,EAkDpC,GAAgD,GAMhD,GAAoD,GAMpD,GAAiD,GChGjD,GAAY,EAAY,IAAgD,CACnF,IAAI,EAA6B,EAC7B,EAAQ,EACZ,KAAO,EAAQ,EAAK,QAAU,GAAU,EAAY,CAAM,GAAG,CAC3D,IAAM,EAA0C,EAAO,MAAM,EAAK,IAClE,EAAS,OAAO,GAAM,SAAW,KAAO,EACxC,GACF,CAEA,OAAO,EAAQ,EAAK,OAAS,KAAO,CACtC,EAMa,IAAU,EAAY,IAAgD,CACjF,GAAI,EAAM,KAAO,EACf,OAAO,EAGT,IAAK,IAAM,KAAQ,EAAM,MACnB,UAAO,GAAS,SACpB,IAAI,EAAK,KAAO,EACd,OAAO,EACF,GAAI,EAAY,CAAI,EAAG,CAC5B,IAAM,EAAU,GAAO,EAAI,CAAI,EAC/B,GAAI,EACF,OAAO,CAEX,EAGF,OAAO,IACT,EAMa,IAAe,EAAY,IAAyC,CAC/E,GAAI,EAAM,KAAO,EAAI,MAAO,CAAC,EAE7B,IAAM,EAAM,EAAM,MAAM,UAAU,GAAO,OAAO,GAAM,UAAa,EAAE,KAAO,CAAE,EAE9E,GAAI,GAAO,EACT,MAAO,CAAC,CAAG,EAGb,IAAK,GAAM,CAAC,EAAG,KAAM,OAAO,QAAQ,EAAM,KAAK,EAC7C,GAAI,EAAY,CAAC,EAAG,CAClB,IAAM,EAAU,GAAY,EAAI,CAAC,EACjC,GAAI,MAAM,QAAQ,CAAO,EACvB,MAAO,CAAC,OAAO,SAAS,CAAC,EAAG,GAAG,CAAO,CAE1C,CAGF,OAAO,IACT,EAKa,EAAiB,GAAqB,EAAK,MAAM,EAAG,EAAE,EAKtD,IAAiB,EAAa,IAAyB,CAClE,GAAI,EAAM,SAAW,EAAM,OAAQ,MAAO,GAC1C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAChC,GAAI,EAAM,KAAO,EAAM,GAAI,MAAO,GAEpC,MAAO,EACT,EAMa,IAAc,EAAqB,IAAwB,CACtE,GAAI,EAAc,QAAU,EAAK,OAAQ,MAAO,GAChD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAc,OAAQ,IACxC,GAAI,EAAc,KAAO,EAAK,GAAI,MAAO,GAE3C,MAAO,EACT,EAKa,IAAyB,EAAa,IAAsB,CACvE,IAAM,EAA2B,CAAC,EAC5B,EAAc,EAAc,CAAK,EACjC,EAAc,EAAc,CAAK,EACnC,EAAI,EAER,KAAO,EAAI,EAAY,QAAU,EAAI,EAAY,QAAU,EAAY,KAAO,EAAY,IACxF,EAAmB,KAAK,EAAY,EAAE,EACtC,IAGF,OAAO,CACT,EAMa,IAAkB,EAAY,IAAqC,CAC9E,IAAI,EAAW,CAAC,CAAC,EAAM,SACnB,EAAsC,EACtC,EAAQ,EACZ,KAAO,EAAQ,EAAK,QAAU,CAAC,GAAY,EAAY,CAAM,GAAG,CAC9D,IAAM,EAA0C,EAAO,MAAM,EAAK,IAC9D,EAAO,CAAC,IAAM,EAAY,CAAC,GAAM,UAAW,GAAO,EAAE,SACvD,EAAW,CAAC,CAAC,EAAE,SACf,EAAS,GAEX,GACF,CACA,OAAO,CACT,EAUa,IAAyB,EAAY,EAAwB,CAAC,IACzE,EAAc,KAAK,GAAK,GAAc,EAAG,CAAI,GAAK,GAAW,EAAG,CAAI,CAAC,EAa1D,IACX,EACA,EACA,CAAE,WAAW,GAAO,gBAAgB,CAAC,GAAsD,CAAC,IAC7E,CACf,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,IAAK,CACnC,IAAM,EAAW,CAAC,GAAG,EAAM,CAAC,EAC5B,EAAM,GAAK,CACT,KAAM,EACN,SAAU,GAAY,EAAc,KAAK,GAAK,GAAc,EAAU,CAAC,CAAC,CAC1E,CACF,CACA,OAAO,CACT,ECrKa,GAAqC,GAChD,GAAc,CAAC,EAAG,EAAO,IAAI,EAAI,gBAAkB,sBAAsB,EAAO,KAAK,KAAK,GAAG,ICNzF,GAAe,WAAW,OAEnB,GACX,oEAaF,IAAW,MACT,eAAe,WAAW,QAAS,KAC9B,KAAK,OAAO,EAAI,KAAK,MAAM,CAAsB,GAAK,OAAc,OAAO,SAAS,CAAC,EAAA,CACrF,SAAS,EAAE,CAAC,CACZ,SAAS,EAAG,GAAG,CACpB,EAIF,GAAI,GAAc,CAEhB,GAAI,OAAO,GAAa,YAAe,WACrC,MAAmB,GAAa,WAAW,OACtC,GAAI,OAAO,GAAa,iBAAoB,WAAY,CAO7D,IACM,EAAY,IAAI,YAAY,EAAE,EAEpC,MAAmB,CACjB,GAAa,gBAAgB,CAAS,EACtC,IAAI,GAAM,EAAU,GAAK,GAAA,CAAI,SAAS,EAAE,EACxC,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IACtB,AAKE,EALE,IAAM,GACH,GAAG,EAAA,GACC,IAAM,GACV,GAAG,IAAK,OAAe,EAAU,IAAM,KAEvC,GAAG,KAAM,EAAU,GAAK,GAAA,CAAI,SAAS,EAAE,KAG1C,IAAM,GAAK,IAAM,IAAM,IAAM,IAAM,IAAM,MAC3C,EAAK,GAAG,EAAA,IAGZ,OAAO,CACT,CACF,CACF,CC/CA,MAAa,GAA+CC,EAKtD,GAAgB,IAAI,EAAM,CAAE,WAAY,EAAM,CAAC,EAOxC,IAAe,EAAS,KACnC,EAAS,EAAU,GAAc,QCjB7BC,GAAU,CACd,KAAM,OACN,MAAO,OACP,WAAY,KACZ,MAAO,OACT,EAQa,IACX,EACA,IAIqB,CAKrB,IAAM,EAAK,EAAY,EAAa,CAAS,EAAsCA,GAE/E,EAAkE,EAAG,YAAc,GAkBvF,MAhBI,CAAC,GAAc,IACjB,EAAa,EAAc,EAAG,MAAqC,CACjE,UAAW,CACb,CAAC,GAGC,IAAe,GACV,GACE,IAAe,GACjB,CAAC,EAGN,GAAsB,CAAU,EAC3B,EAAiB,CAAU,EAG5B,GAAY,IAClB,GACE,GAAkB,KAAK,GAAO,EAAI,QAAU,EAAG,CAAE,CAAC,GAAK,CACrD,KAAM,EACN,MAAO,EACP,MAAO,CACT,CACJ,GAAK,CAAC,CACR,EClDM,IAAuB,EAAkB,EAAa,IAA4B,CACtF,IAAM,EAAc,EAAe,CAAI,EAEvC,GAAI,EAAE,WAAa,WAAa,EAAE,WAAa,aAAc,CAC3D,IAAM,EAAe,CAAC,EAAa,CAAW,EAC9C,OAAO,EACH,EACA,GACE,EAAa,IACX,GAAK,GAAwC,EAC/C,EACA,GACF,CACN,CAEA,OAAO,CACT,EAkCa,IACX,EACA,IACY,CACZ,GAAM,CACJ,YACA,SACA,qBACA,YACA,kBACA,gBACA,iBACE,EAEJ,GAAI,GAAW,eAAiB,IAAA,IAAa,EAAU,eAAiB,KACtE,OAAO,EAAU,aACZ,GAAI,EACT,OAAO,EAAgB,EAAM,CAAE,WAAU,CAAC,EAG5C,IAAI,EAAqD,GAEnD,EAAS,EAAU,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAEjE,GAAI,EAAK,cAAgB,QAAS,CAChC,IAAM,EAAiB,GAAyB,EAAW,EAAQ,EAAK,QAAQ,EAChF,EACE,EAAe,OAAS,EAAI,GAAoB,EAAgB,EAAM,CAAa,EAAI,EAC3F,MAAO,GAAI,EAAK,cAAgB,YAAa,CAC3C,IAAM,EAAa,EACf,EAAc,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EACtD,KACJ,EAAQ,GAAc,EAAW,OAAS,EAAI,EAAe,CAAU,EAAI,EAC7E,MAAO,GAAI,EAAO,OAAS,EAAG,CAC5B,IAAM,EAAa,EAAmB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAAC,EAC1E,IAAe,cACjB,EAAQ,EAAgB,CAAC,EAAI,IACpB,IAAe,UAAY,IAAe,WACnD,EAAQ,GAAoB,EAAQ,EAAM,CAAa,EAE3D,MACqB,EAAmB,EAAK,MAAO,EAAK,SAAU,CAAE,WAAU,CAChE,IAAM,aACjB,EAAQ,IAIZ,OAAO,CACT,ECxGa,GACX,GACuF,CACvF,IAAM,EACJ,OAAO,GAAqB,UACxB,EACA,OAAO,GAAqB,UAAY,EACtC,EAAiB,MACjB,KACR,OAAO,OAAO,GAAU,UACpB,EACE,GAAmB,MACnB,GAAmB,QACrB,EACN,ECXM,GAAmD,CACvD,CAAE,KAAM,QAAS,MAAO,QAAS,MAAO,OAAQ,CAClD,EAEM,GAAU,CACd,KAAM,OACN,MAAO,OACP,aAAc,KACd,MAAO,OACT,EASa,IACX,EACA,EACA,IAK2B,CAK3B,IAAM,EAAK,EAAY,EAAa,CAAS,EAAI,GAE7C,EAIoE,EAAG,cAAgB,GAoB3F,OAlBI,OAAO,GAAoB,aAC7B,EAAkB,EAAgB,CAAQ,GAGxC,CAAC,GAAmB,IACtB,EAAkB,EAAgB,EAAG,MAAqC,EAAe,CACvF,UAAW,CACb,CAAC,GAGE,EAID,GAAsB,CAAe,EAChC,EAAiB,CAAyC,EAG5D,EAAgB,IACrB,GACE,GAAyB,KAAK,GAAO,EAAI,QAAU,EAAG,CAAE,CAAC,GAAK,CAC5D,KAAM,EACN,MAAO,EACP,MAAO,CACT,CACJ,EAdS,EAeX,ECtEa,IACX,EACA,GAAG,IACyC,CAC5C,IAAM,EAAS,CAAE,GAAG,CAAK,EAEzB,IAAK,IAAM,KAAgB,EAEzB,GAAI,EACF,IAAK,IAAM,KAAO,GAAW,CAAY,EACnC,GAAY,CAAG,IACnB,AAGE,EAAO,GAHL,EAAO,GACK,CAAE,GAAG,EAAO,GAAM,GAAG,EAAa,EAAK,EAEvC,CAAE,GAAG,EAAa,EAAK,GAM7C,OAAO,CACT,EAEa,IACX,EACA,EACA,IACwD,CACxD,GAAI,GAAY,CAAE,EAAG,OACrB,IAAM,EAAY,GAAc,CAAiB,CAAC,CAC/C,KAAK,CAAC,EAAK,CAAC,EAAI,MAAS,CAAC,EAAK,GAAM,GAAM,IAAW,EAAG,GAAG,EAAI,CAAC,CAAC,CAClE,OAAO,GAAK,CAAC,GAAY,EAAE,EAAY,GAAK,CAAC,CAAC,EAAE,EAAE,EACrD,GAAI,EAAU,OAAS,GAAK,EAAU,CACpC,IAAM,EAAoB,IAAW,IAAO,CAAC,EACvC,EAAc,OAAO,OAAO,CAAC,EAAG,EAAmB,OAAO,YAAY,CAAS,CAAC,EACtF,MAAO,EAAG,GAAK,CAAY,CAC7B,CAEF,ECtCM,GAAwB,EAAwB,IAAgC,CACpF,IAAI,EAAS,GACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAI,EAAK,EAAE,GAAG,GACpB,GAAI,CAAC,EAAG,SAER,IAAM,EAAI,OAAO,GAAM,SAAW,EAAI,GAAK,CAAC,EACxC,IAAG,EAAS,EAAS,GAAG,EAAO,GAAG,IAAM,EAC9C,CACA,OAAO,CACT,EAKa,IAAmB,GAAG,KAA6C,CAC9E,aAAc,EAAqB,eAAgB,CAAI,EACvD,UAAW,EAAqB,YAAa,CAAI,EACjD,OAAQ,EAAqB,SAAU,CAAI,EAC3C,KAAM,EAAqB,OAAQ,CAAI,EACvC,YAAa,EAAqB,cAAe,CAAI,EACrD,QAAS,EAAqB,UAAW,CAAI,EAC7C,SAAU,EAAqB,WAAY,CAAI,EAC/C,UAAW,EAAqB,YAAa,CAAI,EACjD,WAAY,EAAqB,aAAc,CAAI,EACnD,QAAS,EAAqB,UAAW,CAAI,EAC7C,YAAa,EAAqB,cAAe,CAAI,EACrD,KAAM,EAAqB,OAAQ,CAAI,EACvC,OAAQ,EAAqB,SAAU,CAAI,EAC3C,UAAW,EAAqB,YAAa,CAAI,EACjD,MAAO,EAAqB,QAAS,CAAI,EACzC,WAAY,EAAqB,aAAc,CAAI,EACnD,UAAW,EAAqB,YAAa,CAAI,EACjD,aAAc,EAAqB,eAAgB,CAAI,EACvD,gBAAiB,EAAqB,kBAAmB,CAAI,EAC7D,WAAY,EAAqB,aAAc,CAAI,EACnD,WAAY,EAAqB,aAAc,CAAI,EACnD,WAAY,EAAqB,aAAc,CAAI,EACnD,SAAU,EAAqB,WAAY,CAAI,EAC/C,UAAW,EAAqB,YAAa,CAAI,EACjD,SAAU,EAAqB,WAAY,CAAI,EAC/C,UAAW,EAAqB,YAAa,CAAI,EACjD,MAAO,EAAqB,QAAS,CAAI,EACzC,YAAa,EAAqB,cAAe,CAAI,EACrD,cAAe,EAAqB,gBAAiB,CAAI,EACzD,cAAe,EAAqB,gBAAiB,CAAI,EACzD,aAAc,EAAqB,eAAgB,CAAI,EACvD,MAAO,EAAqB,QAAS,CAAI,EACzC,QAAS,EAAqB,UAAW,CAAI,EAC7C,YAAa,EAAqB,cAAe,CAAI,EACrD,QAAS,EAAqB,UAAW,CAAI,EAC7C,QAAS,EAAqB,UAAW,CAAI,EAC7C,SAAU,EAAqB,WAAY,CAAI,EAC/C,kBAAmB,EAAqB,oBAAqB,CAAI,EACjE,mBAAoB,EAAqB,qBAAsB,CAAI,EACnE,UAAW,EAAqB,YAAa,CAAI,EACjD,SAAU,EAAqB,WAAY,CAAI,EAC/C,cAAe,EAAqB,gBAAiB,CAAI,EACzD,UAAW,EAAqB,YAAa,CAAI,EACjD,eAAgB,EAAqB,iBAAkB,CAAI,EAC3D,SAAU,EAAqB,WAAY,CAAI,EAC/C,YAAa,EAAqB,cAAe,CAAI,EACrD,QAAS,EAAqB,UAAW,CAAI,EAC7C,sBAAuB,EAAqB,wBAAyB,CAAI,CAC3E,GCjCa,IAGX,CACA,QACA,YACA,eACA,YACA,cACA,aACA,sBAOA,GAAqB,CACnB,WAAa,GAAW,WACtB,IAAe,EAAO,CAAE,WAAU,CAAC,GACnC,EACF,cACA,aACA,SAAU,EACV,kBACF,CAAC,CAAC,CAAC,WASQ,IAA2D,CACtE,QACA,YACA,qBACA,kBAQI,GAAW,gBAAwB,EAAU,gBAE7C,EACK,OAAO,GAAuB,WACjC,EAAmB,EAAO,CAAE,WAAU,CAAC,EACvC,EAGC,EAAe,EAAa,EAAO,CAAE,WAAU,CAAC,CAAC,GAAK,GAUlD,IAA2D,CACtE,QACA,WACA,YACA,wBAOI,GAAW,gBACN,OAAO,EAAU,iBAAoB,WACxC,EAAU,gBAAgB,CAAQ,EAClC,EAAU,gBAGT,IAAqB,EAAO,EAAU,CAAE,WAAU,CAAC,GAAK,OAUpD,IAAqD,CAChE,QACA,WACA,YACA,YACA,cACA,aACA,sBAWA,GAA8B,CAC5B,WAAY,GAAW,QAAU,IAAY,EAAO,EAAU,CAAE,WAAU,CAAC,GAAK,CAAC,EACjF,cACA,aACA,kBACF,CAAC,CAAC,CAAC,WClJC,GAAiB,GAAuB,CAC5C,IAAM,EAAQ,OAAO,eAAe,CAAC,EACrC,OAAO,IAAU,MAAQ,IAAU,OAAO,SAC5C,EAgBa,IAAe,EAAY,IAAwB,CAC9D,GAAI,OAAO,GAAG,EAAG,CAAC,EAAG,MAAO,GAE5B,GAAI,MAAM,QAAQ,CAAC,GAAK,MAAM,QAAQ,CAAC,EACrC,OACE,MAAM,QAAQ,CAAC,GACf,MAAM,QAAQ,CAAC,GACf,EAAE,SAAW,EAAE,QACf,EAAE,OAAO,EAAG,IAAM,GAAY,EAAG,EAAE,EAAE,CAAC,EAS1C,GALI,OAAO,GAAM,UAAY,OAAO,GAAM,UAAY,IAAM,MAAQ,IAAM,MAKtE,OAAO,eAAe,CAAC,IAAM,OAAO,eAAe,CAAC,GAAK,CAAC,GAAc,CAAC,EAAG,MAAO,GAEvF,IAAM,EAAQ,OAAO,KAAK,CAAC,EAC3B,OACE,EAAM,SAAW,OAAO,KAAK,CAAC,CAAC,CAAC,QAChC,EAAM,MAAM,GACV,GAAa,EAA8B,GAAK,EAA8B,EAAE,CAClF,CAEJ,EAaa,IAKX,EACA,IACY,GAAY,EAAG,CAAC,ECjExB,IAAyB,EAAgB,IAC7C,IAAS,GAAQ,GAAQ,EAAO,GAAS,IAAY,GAEjD,IAA0B,EAAgB,IAC9C,EAAO,GAAO,IAAS,IAAgB,CAAC,CAAC,EAM9B,IACX,EACA,EACA,EACA,IAEC,EAII,GAAS,EAHV,EACE,GAAsB,EAAM,CAAO,EACnC,GAAuB,EAAM,CAAO,EAQ/B,IAAiB,EAAW,EAAY,IACnD,IAAS,IAAA,IAAa,GAAQ,KAC1B,EACA,IAAY,IAAA,IAAa,GAAW,KAClC,EACA,EAMK,IACX,EAA2B,CAAC,EAC5B,EAAiC,CAAC,EAClC,IAEA,GAAc,EAAwB,CAAC,CAAC,QAA2B,EAAK,CAAC,EAAK,MAC5E,EAAI,GAAO,GAAW,EAAK,EAAM,GAAM,EAAY,GAAM,CAAC,CAAQ,EAC3D,GACN,CAAC,CAAC,EC5BM,IACX,EACA,CAAE,cAAc,GAAgC,CAAC,IACpC,CACb,IAAM,EAAU,CAAC,EAAK,GAChB,EAAe,EAAiB,CAAI,EAM1C,MAJI,CAAC,GAAW,CAAC,EACR,EAGF,CACL,GAAG,EACH,GAAI,GAAW,CAAE,GAAI,EAAY,CAAE,EACnC,GAAI,GAAgB,CAAE,MAAO,GAAiB,EAAK,MAAO,CAAE,aAAY,CAAC,CAAE,CAC7E,CACF,EAMa,IACX,EACA,CAAE,cAAc,GAAgC,CAAC,IAC1C,CACP,IAAM,EAAU,CAAC,EAAY,GACzB,EAAe,GACb,EAAqD,CAAC,EAE5D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,MAAM,OAAQ,IAAK,CACjD,IAAM,EAAI,EAAY,MAAM,GAC5B,GAAI,OAAO,GAAM,SACf,EAAS,KAAK,CAAC,MACV,CACL,IAAM,EAAW,EAAY,CAAC,EAC1B,GAAiB,EAAG,CAAE,aAAY,CAAC,EACnC,GAAY,EAAG,CAAE,aAAY,CAAC,EAClC,EAAS,KAAK,CAAQ,EAClB,IAAa,IACf,EAAe,GAEnB,CACF,CAMA,MAJI,CAAC,GAAW,CAAC,EACR,EAGF,CACL,GAAG,EACH,GAAI,GAAW,CAAE,GAAI,EAAY,CAAE,EACnC,MAAO,CACT,CACF,EAKa,IACX,EACA,CAAE,cAAc,GAAgC,CAAC,IAEjD,EAAY,CAAE,EAAI,GAAiB,EAAI,CAAE,aAAY,CAAC,EAAI,GAAY,EAAI,CAAE,aAAY,CAAC,EAa9E,IACX,EAMA,IACO,CACP,IAAM,EACJ,EAAQ,OAAS,EAAQ,YAAc,EAAQ,cAAgB,EAAQ,cAEzE,OAAO,EAAe,GAAK,EAAiB,GAAiB,EAAgB,CAAO,CACtF,EC/Fa,IACX,EACA,CAAE,cAAc,GAAoC,CAAC,IAC5B,gBAAgB,CAAE,GAAG,EAAM,GAAI,EAAY,CAAE,CAAyB,EAKpF,IACX,EACA,CAAE,cAAc,GAAoC,CAAC,IAC7B,CACxB,GAAI,CAAC,EAAO,CAAO,EAAG,OAAO,EAE7B,GAAI,CAAC,EAAY,CAAO,EACtB,OAAO,gBAAgB,CACrB,GAAG,EACH,GAAI,EAAY,CAClB,CAAC,EAGH,IAAM,EAAW,CAAE,GAAG,EAAS,GAAI,EAAY,CAAE,EAcjD,OAXI,MAAM,QAAQ,EAAS,KAAK,IAE9B,EAAU,MAAgB,EAAQ,MAAM,IAAK,GAC3C,OAAO,GAAM,SACT,EACA,EAAY,CAAC,EACX,GAAc,EAAG,CAAE,aAAY,CAAC,EAChC,GAAa,EAAe,CAAE,aAAY,CAAC,CACnD,GAGK,CACT,EC0Ga,IACX,EACA,EACA,EAAuB,CAAC,EACxB,CAAE,WAAW,IAAkC,CAAC,IACzB,CACvB,GAAI,EAAO,cAAe,OAAO,EAAW,kBAAoB,kBAEhE,GAAI,CAAC,EAAO,iBAAmB,IAAa,IAAA,GAAW,OAAO,KAE9D,IAAM,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAK7E,OAJI,IAAS,GAAe,EAAM,CAAK,GAAK,GAAsB,EAAM,EAAO,aAAa,GACnF,EAAW,kBAAoB,kBAGjC,IACT,EAOa,IACX,EACA,CAAE,YAAY,KAA2B,CAAC,IAC9B,CAAC,CAAC,GAAc,EAAW,QAAU,EA+CtC,IAAkB,EAAO,EAAa,EAAgB,EAAU,CAAC,IAC5E,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GACjC,GAAW,EAAG,EAAyB,EAAgB,CAAO,CAChE,EASW,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,cAAc,EACd,sBACA,cAAc,EACd,WACE,EACE,EAAS,MAAM,QAAQ,CAAc,EACvC,EAAS,EAAgB,CAAK,EAC9B,GAAO,EAAgB,CAAK,EAEhC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,MAAO,SAAU,CAAe,CAAC,EAC7E,EAGT,GAAI,CAAC,EAAY,CAAM,EAErB,OADA,IAAU,CAAE,OAAQ,qBAAsB,UAAW,MAAO,SAAU,CAAe,CAAC,EAC/E,EAIT,IAAM,EACJ,MAAM,QAAQ,CAAc,EAAI,EAAiB,GAAY,EAAgB,CAAK,EAG9E,EAAiB,GAAoB,EAAO,EAAY,EAAS,CAAE,SAAU,EAAK,CAAC,EACzF,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAgB,UAAW,MAAO,SAAU,CAAe,CAAC,EACzE,EAGT,GAAI,EAAY,CAAW,GAAK,GAAiB,EAAY,CAAO,EAElE,OADA,IAAU,CAAE,OAAQ,sBAAuB,UAAW,MAAO,SAAU,CAAe,CAAC,EAChF,EAGT,GAAI,EAAkB,CAAM,GAAK,EAAO,MAAM,OAAS,EAAG,CACxD,IAAM,EAAiB,EAAO,MAAM,GAAG,EAAE,EACzC,EAAO,MAAM,KAIX,IACG,OAAO,GAAmB,SAAW,EAAiB,EAAe,CAAW,EACrF,CACF,CAIA,OAFA,EAAO,MAAM,KAAK,GAAmB,EAAa,CAAE,aAAY,CAAC,CAAa,EAEvE,CACT,EA6FM,GAAyC,CAAE,MAAO,EAAG,SAAU,EAAG,YAAa,EAAG,MAAO,CAAE,EAG3F,GAAsB,GAC1B,EAAQ,UAAU,EAAG,KAAO,GAAe,EAAE,KAAO,IAAM,GAAe,EAAE,KAAO,EAAE,EAOhF,IACJ,EACA,EACA,EACA,IACsF,CAEtF,GAAI,OAAO,GAAM,SACf,MAAO,CAAE,QAAS,CAAC,CAAC,EAAG,CAAC,CAAC,EAAG,SAAU,EAAoB,QAAU,GAAuB,CAAC,CAAE,EAGhG,GAAI,MAAM,QAAQ,CAAC,EAAG,CACpB,IAAM,EAAS,EACf,MAAO,CACL,QAAS,GAAmB,EAAE,KAAK,EAAM,IAAyB,CAAC,EAAM,EAAO,EAAE,CAAC,CAAC,EACpF,SAAU,EACV,QAAU,GAAuB,CAAC,CACpC,CACF,CAEA,MAAO,CACL,QAAS,GAAmB,OAAO,QAAQ,CAA4B,CAAC,EACxE,SAAU,EACV,QAAU,GAAuB,CAAC,CACpC,CACF,EAMM,IAAmB,EAAY,EAAY,EAAY,KACzD,OAAO,GAAM,UAAY,MAAM,QAAQ,CAAC,EAAI,EAAI,IAAwB,CAAC,EAMvE,IACJ,EACA,EACA,EACA,EACA,IACO,CACP,GAAM,CAAE,UAAS,WAAU,WAAY,GAAoB,EAAG,EAAG,EAAG,CAAC,EACrE,IAAK,GAAM,CAAC,EAAM,KAAU,EAC1B,GAAoB,EAAO,EAAM,EAAO,EAAU,CAAO,EAE3D,OAAO,CACT,EAca,KACX,EACA,EACA,EACA,EACA,IAEA,GAAY,GAAgB,EAAG,EAAG,EAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAO,GAAK,CAC1D,GAAoB,EAAG,EAAG,EAAG,EAAG,CAAC,CACnC,CAAC,GAUU,KACX,EACA,EACA,EACA,EACA,IACO,GAAoB,EAAO,EAAG,EAAG,EAAG,CAAC,GAKxC,IACJ,EACA,EAEA,EACA,EACA,EAAyB,CAAC,IACnB,CACP,GAAM,CACJ,mBAAoB,EAAsB,GAC1C,wBAAwB,GACxB,6BAA+B,IAC/B,sBAAwB,CAAC,OAAO,EAChC,0BAA4B,GAC5B,oBAAsB,CAAC,EACvB,WACE,EAEA,EAAqB,EAEnB,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAG7E,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAKT,IAAM,EACJ,IAAS,WAAa,CAAE,cAAe,EAAQ,aAAc,EAAK,EAC9D,EAAoB,GAAoB,EAAO,EAAM,CAAY,EACvE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAmB,UAAW,SAAU,UAAS,CAAC,EAC/D,EAIT,GAAI,IAAS,cAAgB,CAAC,EAAgB,CAAK,EAAG,CAGpD,IAAM,EAAS,EAAS,EAAc,CAAI,EAAG,CAAK,EAClD,GAAI,CAAC,GAAU,CAAC,EAAY,CAAM,EAEhC,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAET,IAAM,EAAc,EAAO,MAW3B,OATI,EAAK,GAAG,EAAE,EAAK,GAAM,EACnB,EAAY,EAAK,GAAG,EAAE,KAAQ,EAChC,IAAU,CAAE,OAAQ,YAAa,UAAW,SAAU,UAAS,CAAC,EAEhE,EAAY,EAAK,GAAG,EAAE,GAAM,EAG9B,IAAU,CAAE,OAAQ,wBAAyB,UAAW,SAAU,UAAS,CAAC,EAEvE,CACT,CAEA,IAAM,EAAc,EAAS,EAAM,CAAK,EAGxC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAGT,IAAM,EAAU,EAAY,CAAW,EAIvC,GAAI,EAAY,KAAU,EAExB,OADA,IAAU,CAAE,OAAQ,YAAa,UAAW,SAAU,UAAS,CAAC,EACzD,EAUT,GANI,IAAS,gBAEX,EAAY,GAAQ,GAIlB,EAAS,OAAO,EAEpB,IAAI,EAAmB,GACnB,EAAa,GAEjB,GAAI,IAAS,QAAS,CACpB,IAAM,EAAsB,EAAc,EAAY,KAAK,EACrD,EAAoB,EAAc,CAAK,EAE7C,GAAI,EAAkB,SAAW,EAC/B,OAAO,EAAY,UACd,CACL,IAAM,EACJ,EAAY,OAAO,MAAQ,EAAU,EAAmB,EAAY,MAAM,IAAI,EAC1E,KACA,EAAe,CAAiB,EAClC,IACF,EAAY,MAAQ,CAAE,KAAM,EAAe,UAAW,CAAE,EAE5D,EAEI,EAAoB,OAAS,GAAK,EAAkB,OAAS,KAE/D,EAAqB,GAEzB,CAGI,GAAsB,IAAS,UACjC,EAAY,SAAW,EAAuB,CAAK,EACnD,EAAmB,GACnB,EAAa,IAIX,GAAyB,IAAS,aACpC,EAAmB,GACnB,EAAa,IAQf,IAAM,EAAqB,EALN,GACnB,CAAE,KAAM,EAAY,MAAO,MAAO,EAAY,MAAO,MAAO,EAAG,EAC/D,EAAY,SACZ,CAEwC,CAAY,EAoBtD,OAlBG,GACC,EAAY,aACZ,IAAuB,EAAY,aACpC,IAAS,eAAiB,IAAU,EAAY,eAKjD,EACE,CAAC,CAAC,EAAY,aAAgB,CAAC,EAAY,aAAe,IAAU,EACtE,EAAY,YAAc,EAAmB,EAAqB,GAGhE,IAEF,EAAY,MAAQ,EAAoB,CAAW,GAG9C,CACT,EA2Ba,IAAwB,EAAO,EAAU,EAAU,CAAC,IAC/D,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAc,EAAG,EAAU,CAAO,CAAC,EAShE,IAA+B,EAAO,EAAU,EAAU,CAAC,IAAoB,CAC1F,GAAM,CAAE,WAAY,EACd,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAG7E,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAIT,GAAI,EAAK,SAAW,EAElB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAGT,IAAM,EAAoB,GAAoB,EAAO,EAAM,CAAO,EAClE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAmB,UAAW,SAAU,UAAS,CAAC,EAC/D,EAMT,GAAI,CAAC,EAAS,EAAM,CAAK,EAEvB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,UAAS,CAAC,EAChE,EAIT,IAAM,EAAQ,EAAK,GAAG,EAAE,EAClB,EAAS,EAAS,EAAc,CAAI,EAAG,CAAK,EAClD,GAAI,CAAC,EAAgB,CAAM,GAAK,EAAO,MAAM,OAAS,EAAG,CACvD,IAAM,EAAiB,IAAU,EAAI,EAAI,EAAQ,EACjD,EAAO,MAAM,OAAO,EAAgB,CAAC,CACvC,MACE,EAAO,MAAM,OAAO,EAAO,CAAC,EAG9B,OAAO,CACT,EA8Ba,IAA0B,EAAO,EAAU,EAAU,CAAC,IACjE,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAe,EAAG,EAAU,CAAO,CAAC,EASjE,IAAiC,EAAO,EAAU,EAAU,CAAC,IAAoB,CAC5F,GAAM,CAAE,WAAY,EACd,EAAO,MAAM,QAAQ,CAAQ,EAAI,EAAW,GAAY,EAAU,CAAK,EAG7E,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,UAAW,UAAS,CAAC,EACjE,EAIT,GAAI,EAAK,SAAW,EAElB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,UAAW,UAAS,CAAC,EACjE,EAGT,IAAM,EAAqB,GAAoB,EAAO,EAAM,CAAO,EACnE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAoB,UAAW,UAAW,UAAS,CAAC,EACjE,EAKT,IAAM,EAAS,EAAS,EAAM,CAAK,EACnC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,UAAW,UAAS,CAAC,EACjE,EAIT,GAAI,CAAC,EAAY,CAAM,EAErB,OADA,IAAU,CAAE,OAAQ,qBAAsB,UAAW,UAAW,UAAS,CAAC,EACnE,EAIT,IAAM,EAAQ,EAAK,GAAG,EAAE,EAClB,EAAS,EAAS,EAAc,CAAI,EAAG,CAAK,EAIlD,GAAI,EAAO,MAAM,SAAW,EAAG,CAC7B,GAAI,CAAC,EAAgB,CAAM,GAAK,EAAO,MAAM,OAAS,EAAG,CACvD,IAAM,EAAiB,IAAU,EAAI,EAAI,EAAQ,EACjD,EAAO,MAAM,OAAO,EAAgB,CAAC,CACvC,MACE,EAAO,MAAM,OAAO,EAAO,CAAC,EAE9B,OAAO,CACT,CAOA,OAFA,EAAQ,MAAmB,OAAO,EAAO,EAAG,GAAI,EAAO,KAAkB,EAElE,CACT,EAEM,IACJ,EACA,EACA,IACS,CACT,GAAI,MAAM,QAAQ,CAAuB,EACvC,OAAO,EAGT,IAAM,EAAK,EAAkB,CAAK,EAElC,GAAI,IAA4B,KAAM,CACpC,GAAI,GAAc,EAAa,CAAC,CAAC,CAAC,EAChC,OAAO,EACF,GAAI,EAAY,GAAG,EAAE,IAAM,EAAG,CACnC,IAAM,EAAa,EAAc,CAAW,EAC5C,MAAO,CAAC,GAAG,EAAc,CAAU,EAAG,KAAK,IAAI,EAAG,EAAW,GAAG,EAAE,EAAM,IAAW,CAAC,CACtF,CAAO,CACL,IAAM,EAAiB,CACrB,GAAG,EAAc,CAAW,EAC5B,KAAK,IAAI,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EAAE,CAChD,EACM,EAAiB,EAAS,EAAgB,CAAK,EAQnD,OAPE,EAAY,CAAc,EACrB,CAAC,GAAG,EAAgB,EAAe,MAAM,MAAM,EAM/C,CAHL,GAAG,EAAc,CAAW,EAC5B,KAAK,IAAI,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EAAE,CAEhC,CAEpB,CACF,CAAO,GAAI,IAA4B,OAAQ,CAC7C,GAAI,GAAc,CAAC,EAAM,MAAM,OAAS,CAAC,EAAG,CAAW,EACrD,OAAO,EACF,GACL,EAAY,GAAG,EAAE,IAChB,EAAS,EAAc,CAAW,EAAG,CAAK,CAAC,CAAsB,MAAM,OAAS,EACjF,CACA,IAAM,EAAa,EAAc,CAAW,EAC5C,MAAO,CAAC,GAAG,EAAc,CAAU,EAAG,EAAW,GAAG,EAAE,EAAK,CAAC,CAC9D,CAAO,CACL,IAAM,EAAiB,CAAC,GAAG,EAAc,CAAW,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EAAE,EACnF,EAAmB,EAAS,EAAgB,CAAK,EAKrD,OAJE,EAAY,CAAgB,EACvB,CAAC,GAAG,EAAgB,CAAC,EAGrB,CADa,GAAG,EAAc,CAAW,EAAG,EAAY,GAAG,EAAE,GAAM,EAAK,EAAI,EACnE,CAEpB,CACF,CAEA,OAAO,CACT,EA6Ca,IAAoB,EAAO,EAAa,EAAS,EAAU,CAAC,IACvE,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAY,EAAG,EAAa,EAAS,CAAO,CAAC,EAU1E,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,QAAQ,GACR,cAAc,EACd,cAAc,EACd,WACE,EACE,EAAU,MAAM,QAAQ,CAAW,EAAI,EAAc,GAAY,EAAa,CAAK,EAGzF,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,OAAQ,SAAU,CAAY,CAAC,EAC3E,EAKT,IAAM,EAAsB,EAAS,EAAS,CAAK,EACnD,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,OAAQ,SAAU,CAAY,CAAC,EAC3E,EAGT,IAAM,EAAW,GAAY,EAAO,EAAS,CAAO,EAGpD,GAAI,EAAQ,SAAW,EAErB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,OAAQ,SAAU,CAAY,CAAC,EAC3E,EAGT,IAAM,EAAkB,GAAoB,EAAO,EAAS,CAAO,EACnE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAiB,UAAW,OAAQ,SAAU,CAAY,CAAC,EACxE,EAIT,GAAI,GAAc,EAAS,CAAQ,EAEjC,OADA,IAAU,CAAE,OAAQ,gBAAiB,UAAW,OAAQ,SAAU,CAAY,CAAC,EACxE,EAYT,GARI,CAAC,EAAS,EAAc,CAAQ,EAAG,CAAK,GAQxC,CAAC,GAAS,GAAW,EAAS,CAAQ,EAExC,OADA,IAAU,CAAE,OAAQ,wBAAyB,UAAW,OAAQ,SAAU,CAAQ,CAAC,EAC5E,EAGT,IAAM,EAAc,EAChB,GACE,EAAQ,CAAmB,EAAI,EAAQ,CAAmB,EAAI,EAC9D,CAAE,aAAY,CAChB,EACA,EAEE,EAAyB,EAAkB,CAAK,EAChD,EAAuB,EAAS,EAAc,CAAO,EAAG,CAAK,EAC7D,EAAoB,EAAQ,GAAG,EAAE,EACjC,EACJ,GAA0B,EAAoB,EACzC,EAAqB,MAAM,EAAoB,GAChD,KACA,EACJ,GAA0B,EAAoB,EAAqB,MAAM,OAAS,EAC7E,EAAqB,MAAM,EAAoB,GAChD,KAGN,GAAI,CAAC,EAAO,CACV,IAAM,EAAiB,EACnB,KAAK,IAAI,EAAG,EAAoB,CAAC,EACjC,EACE,EAAe,EAAyB,EAAI,EAClD,EAAqB,MAAM,OAAO,EAAgB,CAAY,CAChE,CAEA,IAAM,EAAa,CAAC,GAAG,CAAQ,EAC3B,GAA0B,EAAW,GAAG,EAAE,EAAK,GAAM,IAMvD,EAAW,EAAW,OAAS,IAAM,GAEvC,IAAM,EAAqB,GAAsB,EAAS,CAAQ,EAEhE,CAAC,GACD,EAAQ,SAAW,EAAmB,OAAS,GAC/C,EAAW,EAAmB,QAAU,EAAQ,EAAmB,UAKnE,EAAW,EAAmB,SAAW,EAAyB,EAAI,GAExE,IAAM,EAAmB,EAAc,CAAU,EAC3C,EAAqB,EAAS,EAAkB,CAAK,EACrD,EAAW,EAAW,GAAG,EAAE,EAI3B,EAAc,GAA0B,EAAW,EAAI,EAAW,EAAI,EAOtE,GAAqB,GAAG,IAC5B,EAAmB,MAAM,OAAO,EAAa,EAAG,GAAG,CAAI,EA2BzD,OAxBI,EAAmB,MAAM,SAAW,GAAK,CAAC,EAC5C,EAAkB,CAAW,EAEzB,IAAa,EACX,IAAsB,GAAK,EAC7B,EAAkB,EAAa,CAAiB,EAIhD,EAAkB,EADhB,EAAmB,MAAM,IAAM,GAAqB,EAAe,CAAW,CAChC,EAIhD,EADE,IAIA,EAAmB,MAAM,EAAc,IACvC,GACA,EAAe,CAAW,GALS,CAMW,EAK/C,CACT,EA6Da,IAAwB,EAAO,EAAa,EAAM,EAAU,CAAC,IACxE,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAc,EAAG,EAAyB,EAAM,CAAO,CAAC,EASrF,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,cAAc,EACd,sBACA,uBACA,cAAc,EACd,UAAU,GACV,WACE,EAEE,EAAqB,EAAS,EAAc,CAAI,EAAG,CAAK,EAC9D,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,SAAU,SAAU,CAAK,CAAC,EACtE,EAGT,GAAI,CAAC,EAAY,CAAkB,EAEjC,OADA,IAAU,CAAE,OAAQ,qBAAsB,UAAW,SAAU,SAAU,CAAK,CAAC,EACxE,EAGT,IAAM,EAAa,EAAc,CAAI,EAC/B,EAAoB,GAAoB,EAAO,EAAY,EAAS,CAAE,SAAU,EAAK,CAAC,EAC5F,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAmB,UAAW,SAAU,SAAU,CAAK,CAAC,EACrE,EAGT,GAAI,EAAY,CAAW,GAAK,GAAiB,EAAY,CAAO,EAElE,OADA,IAAU,CAAE,OAAQ,sBAAuB,UAAW,SAAU,SAAU,CAAK,CAAC,EACzE,EAGT,IAAM,EAAO,GAAc,EAAa,CAAE,aAAY,CAAC,EACjD,EAAyB,EAAkB,CAAK,EAChD,EAAW,EAAK,GAAG,EAAE,EAOrB,GAAqB,EAAa,GAAG,IACzC,EAAmB,MAAM,OAAO,EAAK,EAAU,EAAK,OAAS,EAAG,GAAG,CAAI,EAGzE,GAAI,EAAmB,MAAM,SAAW,GAAK,CAAC,EAC5C,EAAkB,EAAU,CAAI,OAC3B,GAAI,GAAW,EACpB,EAAkB,EAAY,EAAW,EAAI,CAAI,OAEjD,GAAI,IAAa,EACX,EAAK,MAAM,GAAG,EAAE,IAAM,GAAK,EAC7B,EAAkB,EAAU,EAAM,CAAoB,EAItD,EAAkB,EAAU,EAD1B,EAAmB,MAAM,IAAM,GAAuB,EAAe,CAAW,CAC/B,MAEhD,CACL,IAAM,EAAqB,EAAW,GAAM,EAAI,EAAW,EAAI,EAC3D,EACF,EAAkB,EAAoB,EAAqB,CAAI,EAM/D,EAAkB,EAHhB,EAAmB,MAAM,EAAqB,IAC9C,GACA,EAAe,CAAW,EAC6B,CAAI,CAEjE,CAGF,OAAO,CACT,EA8Ca,IACX,EACA,EACA,EACA,EAAU,CAAC,IAEX,GAAY,EAAQ,MAAM,CAAC,CAAC,EAAO,GAAK,GAAa,EAAG,EAAgB,EAAgB,CAAO,CAAC,EAWrF,IACX,EACA,EACA,EACA,EAAU,CAAC,IACM,CACjB,GAAM,CACJ,QAAQ,GACR,cAAc,EACd,cAAc,EACd,WACE,EACE,EAAa,MAAM,QAAQ,CAAc,EAC3C,EACA,GAAY,EAAgB,CAAK,EAC/B,EAAa,MAAM,QAAQ,CAAc,EAC3C,EACA,GAAY,EAAgB,CAAK,EAGrC,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,IAAM,EAAW,GAAY,EAAO,EAAY,CAAU,EAG1D,GAAI,EAAW,SAAW,EAExB,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,IAAM,EAAmB,GAAoB,EAAO,EAAY,CAAO,EACvE,GAAI,EAEF,OADA,IAAU,CAAE,OAAQ,EAAkB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC7E,EAIT,GAAI,GAAc,EAAY,CAAQ,EAEpC,OADA,IAAU,CAAE,OAAQ,gBAAiB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC5E,EAUT,GANI,CAAC,EAAS,EAAc,CAAQ,EAAG,CAAK,GAMxC,CAAC,GAAS,GAAW,EAAY,CAAQ,EAE3C,OADA,IAAU,CAAE,OAAQ,wBAAyB,UAAW,QAAS,SAAU,CAAe,CAAC,EACpF,EAGT,IAAM,EAA4B,EAAS,EAAY,CAAK,EACtD,EAAoB,EAAS,EAAY,CAAK,EACpD,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAGT,GAAI,CAAC,EAEH,OADA,IAAU,CAAE,OAAQ,mBAAoB,UAAW,QAAS,SAAU,CAAe,CAAC,EAC/E,EAET,IAAM,EAAoB,EACtB,GACE,EAAQ,CAAyB,EAC7B,EAAQ,CAAyB,EACjC,EACJ,CAAE,aAAY,CAChB,EACA,EAEE,EAAyB,EAAkB,CAAK,EAChD,EAAuB,EAAS,EAAc,CAAU,EAAG,CAAK,EAChE,EAAoB,EAAW,GAAG,EAAE,EAG1C,GAAI,CAAC,EAAO,CACV,IAAM,EAAiB,EACnB,KAAK,IAAI,EAAG,EAAoB,CAAC,EACjC,EACE,EAAe,EAAyB,EAAI,EAClD,EAAqB,MAAM,OAAO,EAAgB,CAAY,CAChE,CAEA,IAAM,EAAa,CAAC,GAAG,CAAQ,EACzB,EAAqB,GAAsB,EAAY,CAAQ,EAEnE,CAAC,GACD,EAAW,SAAW,EAAmB,OAAS,GAClD,EAAS,EAAmB,QAAU,EAAW,EAAmB,UAKpE,EAAW,EAAmB,SAAW,EAAyB,EAAI,GAExE,IAAM,EAAmB,EAAc,CAAU,EAC3C,EAAqB,EAAS,EAAkB,CAAK,EACrD,EAAkB,EAAW,GAAG,EAAE,EAmBxC,OAhBA,EAAmB,MAAM,OACvB,EACA,EACA,GACG,EACG,CAAE,MAAO,CAAC,EAAmB,EAAe,CAAW,EAAG,CAAiB,CAAE,EAC7E,CACE,WAAY,EAAe,CAAW,EACtC,MAAO,CAAC,EAAmB,CAAiB,CAE9C,EACJ,CAAE,aAAY,CAEhB,CACF,EAEO,CACT,ECnxCa,IAAsB,EAA6B,CAAC,IAA2B,CAC1F,GAAM,CACJ,OACA,cACA,cACA,YAAY,IACZ,gBACA,kBAAkB,GAClB,gBACA,qBACA,wBACA,yBACA,kBACA,sBACA,gBACA,SACA,YACA,aACA,WACA,aACA,cACA,cACA,eACA,YACA,SACE,EAEE,EAAO,GAAiC,IAAQ,CAAE,OAAM,GAAG,CAAQ,CAAC,EAEpE,EAAS,CAAE,kBAAiB,gBAAe,eAAc,EAGzD,GAAW,EAAyB,EAAY,EAAW,KAC/D,CAAC,CAAC,GAAoB,EAAO,EAAM,EAAQ,CAAE,UAAS,CAAC,EAEzD,MAAO,CACL,SAAU,EAAO,EAAM,EAAY,IAAY,CAC7C,GAAI,EAAQ,EAAO,EAAY,EAAI,EAAG,CACpC,EAAI,CAAE,KAAM,EAAQ,mBAAoB,OAAM,aAAY,OAAM,CAAC,EACjE,MACF,CAEA,IAAM,EAAW,IAAY,EAAU,EAAM,EAAY,EAAO,CAAO,EACvE,GAAI,CAAC,EAAU,CACb,EAAI,CAAE,KAAM,EAAQ,eAAgB,OAAM,aAAY,OAAM,CAAC,EAC7D,MACF,CAEA,IAAM,EAAU,IAAa,GAAO,EAAO,EACrC,EAAW,GAAI,EAAO,EAAS,EAAY,CAC/C,cACA,oBAAsB,EAAuC,oBAC7D,cACA,QACF,CAAC,EAED,OADA,EAAI,CAAE,KAAM,EAAQ,IAAK,QAAO,WAAU,UAAS,YAAW,CAAC,EACxD,CACT,EAEA,UAAW,EAAO,EAAW,EAAY,IAAY,CAEnD,GAAI,EAAW,QAAU,EAAW,OAEpC,GAAI,EAAQ,EAAO,EAAY,EAAI,EAAG,CACpC,EAAI,CAAE,KAAM,EAAQ,mBAAoB,YAAW,aAAY,OAAM,CAAC,EACtE,MACF,CAEA,IAAM,EAAY,IAAa,EAAW,EAAW,EAAY,EAAO,CAAO,EAC/E,GAAI,CAAC,EAAW,CACd,EAAI,CAAE,KAAM,EAAQ,gBAAiB,YAAW,aAAY,OAAM,CAAC,EACnE,MACF,CAEA,IAAM,EAAW,IAAc,GAAO,EAAY,EAC5C,EAAW,GAAI,EAAO,EAAU,EAAY,CAChD,cACA,oBAAsB,EAA6B,qBAAuB,IAAA,GAC1E,cACA,QACF,CAAC,EAED,OADA,EAAI,CAAE,KAAM,EAAQ,IAAK,QAAO,WAAU,WAAU,YAAW,CAAC,EACzD,CACT,EAEA,YAAa,EAAO,EAAM,EAAO,IAAS,CAIxC,GAAI,GAAoB,EAAO,EADZ,IAAS,WAAa,CAAE,eAAc,EAAI,CACd,EAAG,CAChD,EAAI,CAAE,KAAM,EAAQ,aAAc,OAAM,OAAM,QAAO,OAAM,CAAC,EAC5D,MACF,CAEA,IAAM,EAAW,GAAO,EAAO,EAAM,EAAO,EAAM,CAChD,qBACA,wBACA,yBACA,kBACA,sBACA,gBACA,QACF,CAAC,EAED,OADA,EAAI,CAAE,KAAM,EAAQ,OAAQ,QAAO,WAAU,OAAM,QAAO,MAAK,CAAC,EACzD,CACT,EAEA,mBAAoB,EAAO,EAAM,IAAY,CAC3C,GAAI,EAAQ,EAAO,CAAI,EAAG,CACxB,EAAI,CAAE,KAAM,EAAQ,aAAc,OAAM,OAAM,CAAC,EAC/C,MACF,CAEA,IAAM,EAAc,EAAS,EAAM,CAAK,EAExC,GAAI,CAAC,EAAa,OAElB,GAAI,GAAY,CAAC,EAAS,EAAa,EAAM,EAAO,CAAO,EAAG,CAC5D,EAAI,CAAE,KAAM,EAAQ,cAAe,cAAa,OAAM,OAAM,CAAC,EAC7D,MACF,CAEA,IAAM,EAAW,GAAO,EAAO,EAAM,CAAE,QAAO,CAAC,EAE/C,OADA,EAAI,CAAE,KAAM,EAAQ,OAAQ,QAAO,WAAU,OAAM,aAAY,CAAC,EACzD,CACT,EAEA,UAAW,EAAO,EAAS,EAAS,EAAO,IAAY,CACrD,GAAI,EAAQ,EAAO,CAAO,EAAG,CAC3B,EAAI,CAAE,KAAM,EAAQ,aAAc,UAAS,UAAS,OAAM,CAAC,EAC3D,MACF,CAIA,IAAM,EAAc,EAAS,EAAS,CAAK,EAC3C,GAAI,CAAC,EAAa,OAGlB,IAAM,EAAY,GAAK,EAAO,EAAS,EAAS,CAAE,QAAO,cAAa,cAAa,QAAO,CAAC,EACrF,EAAU,EAAY,CAAW,EACjC,EAAW,EAAU,EAAc,EACnC,EAAiB,IACnB,EAAS,EAAa,EAAS,EAAS,EAAO,EAAW,CAAE,QAAO,aAAY,EAAG,CAAO,EAG7F,GAAI,CAAC,EAAgB,CACnB,EAAI,CACF,KAAM,EAAU,EAAQ,iBAAmB,EAAQ,gBACnD,cACA,UACA,UACA,QACA,QACA,WACF,CAAC,EACD,MACF,CAEA,IAAM,EAAW,EAAY,CAAc,EAAI,EAAiB,EAEhE,OADA,EAAI,CAAE,KAAM,EAAQ,KAAM,QAAO,WAAU,UAAS,UAAS,OAAM,CAAC,EAC7D,CACT,EAEA,WAAY,EAAO,EAAY,EAAY,EAAO,IAAY,CAC5D,GAAI,EAAQ,EAAO,CAAU,EAAG,CAC9B,EAAI,CAAE,KAAM,EAAQ,aAAc,aAAY,aAAY,OAAM,CAAC,EACjE,MACF,CAIA,IAAM,EAAc,EAAS,EAAY,CAAK,EAC9C,GAAI,CAAC,EAAa,OAGlB,IAAM,EAAY,GAAM,EAAO,EAAY,EAAY,CACrD,QACA,cACA,cACA,QACF,CAAC,EACK,EAAU,EAAY,CAAW,EACjC,EAAW,EAAU,EAAe,EACpC,EAAiB,IACnB,EACE,EACA,EACA,EACA,EACA,EACA,CAAE,QAAO,aAAY,EACrB,CACF,EAGJ,GAAI,CAAC,EAAgB,CACnB,EAAI,CACF,KAAM,EAAU,EAAQ,kBAAoB,EAAQ,iBACpD,cACA,aACA,aACA,QACA,QACA,WACF,CAAC,EACD,MACF,CAEA,IAAM,EAAW,EAAY,CAAc,EAAI,EAAiB,EAEhE,OADA,EAAI,CAAE,KAAM,EAAQ,MAAO,QAAO,WAAU,aAAY,aAAY,OAAM,CAAC,EACpE,CACT,EAEA,kBAAmB,EAAO,EAAM,IAAY,CAC1C,GAAI,EAAQ,EAAO,CAAI,EAAG,CACxB,EAAI,CAAE,KAAM,EAAQ,aAAc,OAAM,OAAM,CAAC,EAC/C,MACF,CAIA,IAAM,EAAY,EAAS,EAAM,CAAK,EACtC,GAAI,EAAK,SAAW,GAAK,CAAC,EAAY,CAAS,EAAG,OAIlD,IAAM,EAAY,GAAQ,EAAO,EAAM,CAAE,QAAO,CAAC,EAC3C,EAAiB,IACnB,EAAU,EAAW,EAAM,EAAO,EAAW,CAAO,EAGxD,GAAI,CAAC,EAAgB,CACnB,EAAI,CAAE,KAAM,EAAQ,eAAgB,YAAW,OAAM,QAAO,WAAU,CAAC,EACvE,MACF,CAEA,IAAM,EAAW,EAAY,CAAc,EAAI,EAAiB,EAEhE,OADA,EAAI,CAAE,KAAM,EAAQ,QAAS,QAAO,WAAU,OAAM,WAAU,CAAC,EACxD,CACT,CACF,CACF,EC7Ua,IAA+C,CAC1D,SACA,kBACA,yBACA,kBACA,gBACA,sBACA,cAAc,KACsB,CACpC,IAAI,EAAQ,EAAe,CAAM,GAAK,GAEtC,GAAI,EAAiB,CACnB,GAAI,OAAO,GAAoB,WAAY,CACzC,IAAM,EAAe,EAAgB,CAAM,EAEvC,IAAc,EAAQ,EAC5B,KACE,GAAQ,CAEZ,CAEA,IAAM,EAAY,EAAU,EAAQ,CAAK,EACnC,EAAW,EAAuB,CAAK,EACvC,EAAc,EAAe,EAAgB,EAAO,EAAU,CAAE,WAAU,CAAC,CAAC,GAAK,QACjF,EAAY,EAAe,EAAc,EAAO,CAAE,WAAU,CAAC,CAAC,EAE9D,EAAoB,CACxB,GAAI,EAAY,EAChB,QACA,WACA,cACA,MAAO,GACP,GAAI,EAAY,CAAE,MAAO,CAAE,KAAM,EAAW,UAAW,CAAE,CAAE,EAAI,IACjE,EAEA,MAAO,CAAE,GAAG,EAAS,MAAO,EAAoB,CAAO,CAAE,CAC3D,EAwBa,IACX,CACE,cACA,qBACA,WAAY,EACZ,cAAc,GAEhB,IACqB,CAErB,IAAM,EAAK,EAAY,EACjB,EAAQ,EAAqB,CAAC,EAAe,CAAC,EAAI,CAAC,EAMzD,OAJI,EACK,CAAE,KAAI,QAAO,IAAK,EAAM,EAG1B,CACL,KACA,QACA,WAAY,EAAe,CAAW,GAAK,GAC3C,IAAK,EACP,CACF,ECtBA,IAAa,GAAb,MAAa,UAA0B,KAAM,CAE3C,KAEA,KAEA,YAAY,EAAiB,CAC3B,MACE,kBAAkB,EAAK,UAAU,aAAa,EAAK,OAAO,GACxD,EAAK,WAAa,IAAA,GAAY,GAAK,eAAe,KAAK,UAAU,EAAK,QAAQ,IAC/E,EACH,EACA,KAAK,KAAO,oBACZ,KAAK,KAAO,EAAK,OACjB,KAAK,KAAO,EAEZ,OAAO,eAAe,KAAM,EAAkB,SAAS,CACzD,CACF,EA8RA,MAAM,GAAwB,OAAO,oBAAoB,EAInD,GAAkC,EAAO,CAAE,MAAO,GAAM,OAAQ,EAAM,CAAC,EACvE,GAAmC,EAAO,CAAE,MAAO,GAAO,OAAQ,EAAK,CAAC,EACxE,GAA2C,EAAO,CAAE,MAAO,GAAM,OAAQ,EAAK,CAAC,EA6D/E,OAK4B,CAChC,IAAM,EAAQ,CACZ,UAAW,IAAI,IACf,cAAe,EACf,KAAM,CAAC,EACP,OAAQ,CAAC,EACT,OAAQ,EACR,WAAY,EACZ,gBAAiB,GACjB,oBAAqB,EACvB,EASA,OAFA,OAAO,eAAe,EAAO,WAAY,CAAE,MAAO,GAAM,WAAY,EAAM,CAAC,EAEpE,CACT,EA0BA,IAAa,GAAb,MAAa,CAKX,CAUA,IAAY,OAAmC,CAC7C,OAAQ,KAAqE,GAC/E,CAEA,YAAY,EAAY,EAAwC,CAAC,EAAG,CAGlE,OAAO,eAAe,KAAM,GAAQ,CAClC,MAAO,GAAgC,EACvC,WAAY,GACZ,SAAU,GACV,aAAc,EAChB,CAAC,EAED,KAAK,aAAa,CAAO,EAEzB,KAAK,MAAM,MAAQ,KAAK,OACtB,EACI,GAAiB,EAAO,CAAE,YAAa,KAAK,MAAM,WAAY,CAAC,EAC/D,KAAK,gBAAgB,CAC3B,CACF,CAOA,OAAkB,EAAS,CACzB,OAAO,KAAK,MAAM,cAAgB,EAAO,EAAG,EAAI,EAAI,CACtD,CAOA,aAAqB,EAA6C,CAChE,KAAK,MAAM,QAAU,EACrB,KAAK,MAAM,cAAgB,EAAQ,QAAU,GAC7C,KAAK,MAAM,YAAc,EAAQ,aAAe,EAChD,KAAK,MAAM,UAAY,EAAQ,WAAa,GAC5C,KAAK,MAAM,OAAS,EAAQ,QAAU,GACtC,KAAK,MAAM,gBAAkB,EAAQ,iBAAmB,GACxD,KAAK,MAAM,gBAAkB,EAAQ,gBAErC,IAAM,EAAU,EAAQ,SAAW,GAC7B,EAAsC,OAAO,GAAY,SAAW,EAAU,CAAC,EACrF,KAAK,MAAM,eAAiB,IAAY,GACxC,KAAK,MAAM,WAAa,EAAe,YAAA,GACvC,KAAK,MAAM,WAAa,EAAe,YAAA,IACvC,KAAK,MAAM,IAAM,EAAQ,KAAO,KAAK,IAErC,GAAM,CAAE,WAAY,EAAQ,WAAY,GAAa,GAAqB,CACxE,WAAY,EAAQ,OACpB,WAAY,EAAQ,UACpB,iBAAkB,EAAQ,gBAC1B,YAAa,EAAQ,cAAc,MACrC,CAAC,EAID,KAAK,MAAM,OAAS,KAAK,OAAO,CAAM,EACtC,KAAK,MAAM,SAAW,KAAK,OAAO,CAAQ,EAE1C,KAAK,MAAM,UAAY,GAAqB,CAC1C,WAAa,EAAQ,WAAa,EAClC,WAAY,EAAQ,aACpB,SAAU,EACV,iBAAkB,EAAQ,mBAC1B,YAAa,EAAQ,cAAc,SACrC,CAAC,CAAC,CAAC,WAGH,KAAK,MAAM,YAAc,KAAK,OAC5B,GAAqB,CACnB,WAAa,EAAQ,aAAe,EACpC,WAAY,EAAQ,cACtB,CAAC,CAAC,CAAC,UACL,CACF,CAKA,UAAkB,EAAkB,CAClC,OAAS,KAAK,MAAM,SAA2C,IAAU,CAAC,CAC5E,CAGA,aAAqB,EAAkC,CACrD,OAAO,GAA0B,CAC/B,QACA,UAAW,KAAK,UAAU,CAAK,EAC/B,aAAc,KAAK,MAAM,QAAQ,aACjC,UAAW,KAAK,MAAM,UACtB,WAAY,KAAK,MAAM,QAAQ,aAC/B,iBAAkB,KAAK,MAAM,QAAQ,mBACrC,YAAa,KAAK,MAAM,QAAQ,cAAc,SAChD,CAAC,CACH,CAGA,gBAAwB,EAAuB,CAC7C,OAAO,GAA0B,CAC/B,QACA,UAAW,KAAK,UAAU,CAAK,EAC/B,mBAAoB,KAAK,MAAM,QAAQ,mBACvC,aAAe,GAAc,KAAK,aAAa,CAAC,CAClD,CAAC,CACH,CAEA,gBAAwB,EAAe,EAAkB,CACvD,OAAO,GACL,KAAK,UAAU,CAAK,EACpB,EACA,KAAK,MAAM,QAAQ,eACrB,CACF,CAEA,cAAsB,EAAiC,CACrD,OAAO,GAAqB,KAAK,UAAU,CAAK,EAAG,KAAK,MAAM,QAAQ,aAAa,CACrF,CAEA,UAAkB,EAAe,EAA0C,CACzE,OAAO,GAAoB,CACzB,QACA,WACA,UAAW,KAAK,UAAU,CAAK,EAC/B,UAAW,KAAK,MAAM,QAAQ,UAC9B,iBAAkB,KAAK,MAAM,QAAQ,gBACrC,YAAa,KAAK,MAAM,QAAQ,cAAc,MAChD,CAAC,CACH,CAEA,mBAA2B,EAAe,EAAmC,CAC3E,OAAO,GAA0B,CAC/B,QACA,WACA,UAAW,KAAK,UAAU,CAAK,EAC/B,mBAAoB,KAAK,MAAM,QAAQ,kBACzC,CAAC,CACH,CAGA,aAAqB,EAAyB,CAC5C,GAAM,CAAE,kBAAiB,gBAAe,iBAAkB,KAAK,MAAM,QACrE,OAAO,GAAuB,EAAM,CAClC,UAAW,KAAK,UAAU,EAAK,KAAK,EACpC,OAAQ,KAAK,MAAM,OACnB,gBACA,oBAAqB,EAAG,IAAM,KAAK,mBAAmB,EAAG,CAAC,EAC1D,WAAY,EAAG,IAAM,KAAK,UAAU,EAAG,CAAC,EACxC,gBAAiB,KAAqB,EAAG,IAAS,EAAgB,EAAG,CAAI,GACzE,cAAe,KAAmB,EAAG,EAAG,IAAS,KAAK,cAAc,EAAG,EAAG,CAAI,EAChF,CAAC,CACH,CAOA,cACE,EACA,EACA,EACwB,CACxB,OAAO,GAA8B,CACnC,WAAY,KAAK,MAAM,QAAQ,gBAAgB,EAAO,EAAU,CAAI,GAAK,CAAC,EAC1E,iBAAkB,KAAK,MAAM,QAAQ,eACvC,CAAC,CAAC,CAAC,UACL,CAGA,cAA2D,CACzD,GAAM,CAAE,aAAc,KAAK,MAAM,QAEjC,MAAO,CAGL,OAAQ,KAAK,MAAM,cAEnB,WAAY,GAAa,GAAK,EAAI,OAAO,CAAS,EAAI,IACtD,gBAAiB,KAAK,MAAM,gBAC5B,cAAe,KAAK,MAAM,QAAQ,cAClC,cAAe,KAAK,MAAM,QAAQ,aACpC,CACF,CAEA,aAAsB,CACpB,MAAO,CACL,YAAa,KAAK,MAAM,YACxB,YAAa,KAAK,MAAM,YACxB,GAAG,KAAK,aAAa,CACvB,CACF,CAMA,QAAgB,CAAE,SAAQ,mBAA6D,CACrF,IAAM,EAAa,GAAU,KAAK,MAAM,OAClC,EAAU,GAAmB,KAAK,MAAM,gBAE9C,MAAO,IAAQ,CAIb,GAFA,IAAU,CAAI,EAEV,GAAc,GAAqB,IAAI,EAAK,MAAM,EACpD,MAAM,IAAI,GAAkB,CAAI,CAEpC,CACF,CAGA,eAAuC,CACrC,MAAO,CACL,uBAAwB,GAAK,KAAK,gBAAgB,CAAC,EACnD,oBAAqB,GAAK,KAAK,aAAa,CAAC,EAC7C,iBAAkB,EAAG,IAAM,KAAK,gBAAgB,EAAG,CAAC,EACpD,cAAe,GAAK,KAAK,cAAc,CAAC,EACxC,mBAAoB,KAAK,MAAM,QAAQ,mBACvC,sBAAuB,KAAK,MAAM,QAAQ,sBAC1C,GAAG,KAAK,aAAa,CACvB,CACF,CAOA,OAAe,EAAgB,CAC7B,IAAM,EAAO,KAAK,MAAM,MACpB,IAAS,IAEb,KAAK,MAAM,MAAQ,EAIf,OAAK,MAAM,WAAa,KAE5B,KAAK,OAAO,EAAM,CAAI,EACtB,KAAK,OAAO,EAAW,GACzB,CAMA,OAAe,EAAU,EAAgB,CACvC,GAAI,CAAC,KAAK,MAAM,eAAgB,OAEhC,IAAM,EAAM,GAAY,EAAM,CAAI,EAIlC,GAAI,IAAA,GAA4B,OAEhC,IAAM,EAAM,KAAK,MAAM,IAAI,EACP,GAClB,KAAK,MAAM,QACX,EACA,KAAK,MAAM,OACX,EACA,KAAK,MAAM,UAGE,IACb,KAAK,MAAM,KAAK,KAAK,CAAI,EACrB,KAAK,MAAM,KAAK,OAAS,KAAK,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,EAC1E,KAAK,MAAM,OAAS,CAAC,GAGvB,KAAK,MAAM,QAAU,EACrB,KAAK,MAAM,OAAS,CACtB,CAEA,OAAe,EAAkC,CAC/C,IAAK,IAAM,KAAY,KAAK,MAAM,UAAW,EAAS,CAAM,CAC9D,CAQA,qBAAoC,CAC9B,KAAK,MAAM,WAAa,IAAG,KAAK,MAAM,gBAAkB,GAC9D,CAMA,aAA4B,CACtB,KAAK,MAAM,WAAa,KAAK,MAAM,QAEvC,KAAK,MAAM,SAAW,KAAK,MAAM,MACjC,KAAK,MAAM,YAAc,IAAA,GACzB,KAAK,MAAM,WAAa,IAAA,GAC1B,CAQA,CAAS,SAAS,EAAqB,EAAY,EAA6C,CAG9F,GAFA,KAAM,CAAE,OAAM,OAAM,QAAO,EAEvB,CAAC,EAAY,CAAI,EAAG,OAExB,IAAM,EAAa,EACnB,IAAK,GAAM,CAAC,EAAO,KAAU,EAAW,MAAM,QAAQ,EAEhD,OAAO,GAAU,WACrB,MAAO,KAAK,SAAS,EAAwB,CAAC,GAAG,EAAM,CAAK,EAAG,CAAU,EAE7E,CAGA,OAAmC,CAGjC,GAFA,KAAK,YAAY,EAEb,CAAC,KAAK,MAAM,YAAa,CAC3B,IAAM,EAAQ,IAAI,IAClB,IAAK,GAAM,CAAE,OAAM,UAAU,KAAK,SAAS,KAAK,MAAM,MAAO,CAAC,EAAG,IAAI,EAE/D,EAAK,KAAO,IAAA,IAAa,CAAC,EAAM,IAAI,EAAK,EAAE,GAAG,EAAM,IAAI,EAAK,GAAI,CAAI,EAE3E,KAAK,MAAM,YAAc,CAC3B,CAEA,OAAO,KAAK,MAAM,WACpB,CAGA,OAAe,EAAsC,CACnD,OAAO,OAAO,GAAa,SAAY,KAAK,MAAM,CAAC,CAAC,IAAI,CAAQ,GAAK,KAAQ,CAC/E,CAcA,aAAqB,KAAK,MAAM,MAGhC,SAAS,EAAiB,CAExB,OADA,KAAK,OAAO,KAAK,OAAO,GAAiB,EAAO,CAAE,YAAa,KAAK,MAAM,WAAY,CAAC,CAAC,CAAC,EAClF,IACT,CAUA,YAAuB,CACrB,OAAO,GAAc,CACnB,OAAQ,KAAK,MAAM,OACnB,gBAAiB,KAAK,MAAM,QAAQ,gBACpC,uBAAwB,GAAK,KAAK,gBAAgB,CAAC,EACnD,iBAAkB,EAAG,IAAM,KAAK,gBAAgB,EAAG,CAAC,EACpD,cAAe,GAAK,KAAK,cAAc,CAAC,EACxC,oBAAqB,GAAK,KAAK,aAAa,CAAC,EAC7C,YAAa,KAAK,MAAM,WAC1B,CAAC,CACH,CAMA,gBAAgB,EAAsC,CACpD,OAAO,GACL,CACE,YAAa,KAAK,MAAM,YACxB,mBAAoB,KAAK,MAAM,QAAQ,mBACvC,eAAkB,KAAK,WAAW,EAClC,YAAa,KAAK,MAAM,WAC1B,EACA,CACF,CACF,CAUA,IACE,EACA,EAAgC,CAAC,EACjC,EAAsC,CAAC,EACjC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAI,KAAK,MAAM,MAAO,EAAa,EAAgB,CACjD,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAGA,OAAO,EAAyB,EAAyC,CAAC,EAAS,CACjF,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAO,KAAK,MAAM,MAAO,EAAU,CACjC,GAAG,KAAK,aAAa,EACrB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAsBA,OAAO,EAAY,EAAa,EAAa,EAAmB,CAE9D,IAAM,EAAe,OAAO,GAAM,UAAY,MAAM,QAAQ,CAAC,EAAI,EAAI,EAC/D,EAAO,CAAC,EAAG,EAAG,EAAG,CAAC,EAClB,CAAE,SAAQ,kBAAiB,GAAG,GAClC,EAAK,IAAiB,CAAC,EASzB,MARA,GAAK,GAAgB,CACnB,GAAG,KAAK,cAAc,EACtB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,EAGA,KAAK,OAAQ,GAAe,KAAK,MAAM,MAAO,GAAG,EAAK,MAAM,EAAG,EAAe,CAAC,CAAC,CAAC,EAC1E,IACT,CAGA,KACE,EACA,EACA,EAAuC,CAAC,EAClC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAK,KAAK,MAAM,MAAO,EAAa,EAAS,CAC3C,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAMA,OACE,EACA,EACA,EAAyC,CAAC,EACpC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAO,KAAK,MAAM,MAAO,EAAa,EAAM,CAC1C,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAMA,MACE,EACA,EACA,EAAwC,CAAC,EACnC,CACN,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAM,KAAK,MAAM,MAAO,EAAgB,EAAgB,CACtD,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAOA,QAAQ,EAAyB,EAA0C,CAAC,EAAS,CACnF,GAAM,CAAE,SAAQ,kBAAiB,GAAG,GAAgB,EAQpD,OAPA,KAAK,OACH,GAAQ,KAAK,MAAM,MAAO,EAAU,CAClC,GAAG,KAAK,YAAY,EACpB,GAAG,EACH,QAAS,KAAK,QAAQ,CAAE,SAAQ,iBAAgB,CAAC,CACnD,CAAC,CACH,EACO,IACT,CAWA,YAAqD,CACnD,OAAO,EAAO,CAAE,GAAG,KAAK,MAAM,OAAQ,CAAC,CACzC,CAqCA,YACE,EACA,EACM,CACN,IAAM,EAAS,GAAQ,QAAU,CAAE,GAAG,CAAQ,EAAI,CAAE,GAAG,KAAK,MAAM,QAAS,GAAG,CAAQ,EA4BtF,OAtBI,GAAa,KAAK,MAAM,QAAS,CAAM,EAAU,MAErD,KAAK,aAAa,EAAO,CAAM,CAAC,EAKhC,KAAK,MAAM,WAAa,IAAA,GAExB,KAAK,uBAAuB,EAE5B,EAAE,KAAK,MAAM,cAKT,KAAK,MAAM,WAAa,EAC1B,KAAK,MAAM,oBAAsB,GAEjC,KAAK,OAAO,EAAY,EAGnB,KACT,CAYA,wBAAuC,CACjC,KAAK,MAAM,eAET,KAAK,MAAM,KAAK,OAAS,KAAK,MAAM,YACtC,KAAK,MAAM,KAAK,OAAO,EAAG,KAAK,MAAM,KAAK,OAAS,KAAK,MAAM,UAAU,GAG1E,KAAK,MAAM,KAAO,CAAC,EACnB,KAAK,MAAM,OAAS,CAAC,EACrB,KAAK,MAAM,QAAU,IAAA,GAEzB,CAWA,qBAAiC,KAAK,MAAM,cAgB5C,MAAM,EAAkE,CACtE,IAAM,EAAQ,GAAS,cACnB,GAAc,KAAK,MAAM,MAAO,CAAE,YAAa,KAAK,MAAM,WAAY,CAAC,EACvE,KAAK,MAAM,MACf,OAAO,IAAI,EAA0B,EAAO,KAAK,MAAM,OAAO,CAChE,CAyBA,UAAa,IACX,KAAK,MAAM,UAAU,IAAI,CAAQ,MACpB,CACX,KAAK,MAAM,UAAU,OAAO,CAAQ,CACtC,GAqBF,MAAM,EAAsB,CAC1B,KAAK,MAAM,aACP,KAAK,MAAM,aAAe,IAC5B,KAAK,MAAM,cAAgB,CACzB,MAAO,KAAK,MAAM,MAClB,KAAM,CAAC,GAAG,KAAK,MAAM,IAAI,EACzB,OAAQ,CAAC,GAAG,KAAK,MAAM,MAAM,EAC7B,QAAS,KAAK,MAAM,QACpB,OAAQ,KAAK,MAAM,MACrB,GAGF,GAAI,CACF,EAAG,CACL,OAAS,EAAO,CAEd,GAAI,KAAK,MAAM,aAAe,EAAG,CAC/B,IAAM,EAAW,KAAK,MAAM,cAG5B,KAAK,MAAM,MAAQ,EAAS,MAC5B,KAAK,MAAM,KAAO,EAAS,KAC3B,KAAK,MAAM,OAAS,EAAS,OAC7B,KAAK,MAAM,QAAU,EAAS,QAC9B,KAAK,MAAM,OAAS,EAAS,OAG7B,KAAK,uBAAuB,CAC9B,CACA,MAAM,CACR,QAAU,CAGR,GAFA,KAAK,MAAM,aAEP,KAAK,MAAM,aAAe,EAAG,CAC/B,GAAM,CAAE,MAAO,GAAS,KAAK,MAAM,cACnC,KAAK,MAAM,cAAgB,IAAA,GAE3B,IAAM,EAAe,IAAS,KAAK,MAAM,MAInC,EAAgB,KAAK,MAAM,oBACjC,KAAK,MAAM,oBAAsB,GAE7B,IAGG,KAAK,MAAM,iBAAiB,KAAK,OAAO,EAAM,KAAK,MAAM,KAAK,IAGjE,GAAgB,IAClB,KAAK,OACH,EAAgB,EAAgB,GAAuB,GAAe,EACxE,EAEF,KAAK,MAAM,gBAAkB,EAC/B,CACF,CAEA,OAAO,IACT,CAOA,SAAmB,CACjB,OAAO,KAAK,MAAM,KAAK,OAAS,CAClC,CAGA,SAAmB,CACjB,OAAO,KAAK,MAAM,OAAO,OAAS,CACpC,CAGA,MAAa,CAWX,OAVI,KAAK,MAAM,KAAK,SAAW,EAAU,MAEzC,KAAK,MAAM,OAAO,QAAQ,KAAK,MAAM,KAAK,EAC1C,KAAK,MAAM,MAAQ,KAAK,MAAM,KAAK,IAAI,EAEvC,KAAK,MAAM,QAAU,IAAA,GACrB,KAAK,oBAAoB,EAErB,KAAK,MAAM,aAAe,GAAG,KAAK,OAAO,EAAW,EAEjD,KACT,CAGA,MAAa,CASX,OARI,KAAK,MAAM,OAAO,SAAW,EAAU,MAE3C,KAAK,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,EACrC,KAAK,MAAM,MAAQ,KAAK,MAAM,OAAO,MAAM,EAC3C,KAAK,MAAM,QAAU,IAAA,GACrB,KAAK,oBAAoB,EACrB,KAAK,MAAM,aAAe,GAAG,KAAK,OAAO,EAAW,EAEjD,KACT,CAGA,cAAqB,CAKnB,OAJA,KAAK,oBAAoB,EACzB,KAAK,MAAM,KAAO,CAAC,EACnB,KAAK,MAAM,OAAS,CAAC,EACrB,KAAK,MAAM,QAAU,IAAA,GACd,IACT,CAMA,YAA2C,CACzC,MAAO,CAAE,KAAM,CAAC,GAAG,KAAK,MAAM,IAAI,EAAG,OAAQ,CAAC,GAAG,KAAK,MAAM,MAAM,CAAE,CACtE,CAYA,UAAoC,CAGlC,OAFA,KAAK,YAAY,EACjB,KAAK,MAAM,aAAe,KAAK,MAAM,UAAU,KAAK,MAAM,KAAK,EACxD,KAAK,MAAM,UACpB,CA6DA,OAAO,EAAsD,CAC3D,OAAO,GAAY,KAAK,MAAM,MAAO,CAA6B,CACpE,CAsBA,CAAC,KAAK,EAAuB,CAAC,EAA6B,CACzD,GAAM,CAAE,OAAM,YAAW,cAAe,EAEpC,EAAuB,KAAK,MAAM,MAClC,EAAkB,CAAC,EACnB,EAAyB,KAE7B,GAAI,IAAS,IAAA,GAAW,CACtB,IAAM,EAAO,KAAK,OAAO,CAAI,EACvB,EAAO,GAAQ,EAAS,EAAM,KAAK,MAAM,KAAK,EAEpD,GAAI,CAAC,GAAQ,CAAC,EAAM,OACpB,EAAQ,EACR,EAAY,EACZ,EACE,EAAK,SAAW,EAAI,KAAQ,EAAS,EAAc,CAAI,EAAG,KAAK,MAAM,KAAK,CAC9E,CAEA,IAAK,IAAM,KAAS,KAAK,SAAS,EAAO,EAAW,CAAW,EACzD,GAAa,EAAY,EAAM,IAAI,IACnC,IAAe,EAAY,EAAM,IAAI,KACzC,MAAM,EAEV,CAGA,MAAM,EAAyD,CAAC,EAA6B,CAC3F,OAAO,KAAK,KAAK,CAAE,GAAG,EAAS,UAAW,EAAK,CAAC,CAClD,CAMA,OAAO,EAAyD,CAAC,EAA6B,CAC5F,OAAO,KAAK,KAAK,CAAE,GAAG,EAAS,WAAY,EAAK,CAAC,CACnD,CAGA,KACE,EACA,EAAuB,CAAC,EACF,CACtB,IAAK,IAAM,KAAS,KAAK,KAAK,CAAO,EACnC,GAAI,EAAU,CAAK,EAAG,OAAO,EAE/B,OAAO,IACT,CAGA,OAAO,EAA8C,EAAuB,CAAC,EAAoB,CAC/F,IAAM,EAA2B,CAAC,EAClC,IAAK,IAAM,KAAS,KAAK,KAAK,CAAO,EAC/B,EAAU,CAAK,GAAG,EAAQ,KAAK,CAAK,EAE1C,OAAO,CACT,CAGA,CAAC,OAAO,WAAsC,CAC5C,OAAO,KAAK,KAAK,CACnB,CAYA,SAAS,EAAgC,CACvC,OAAO,EAAS,EAAM,KAAK,MAAM,KAAK,GAAK,IAC7C,CAMA,OAAO,EAAgC,CACrC,IAAM,EAAO,KAAK,MAAM,CAAC,CAAC,IAAI,CAAE,EAEhC,OAAO,IAAS,IAAA,GAAY,KAAO,EAAS,EAAM,KAAK,MAAM,KAAK,CACpE,CAMA,YAAY,EAAyB,CACnC,OAAO,KAAK,MAAM,CAAC,CAAC,IAAI,CAAE,GAAK,IACjC,CAMA,eAAe,EAAqB,CAClC,OAAO,GAAe,EAAM,KAAK,MAAM,KAAK,CAC9C,CAGA,QAAQ,EAA6C,CACnD,IAAM,EAAO,KAAK,OAAO,CAAQ,EACjC,OAAO,IAAS,KAAO,KAAQ,EAAS,EAAM,KAAK,MAAM,KAAK,GAAK,IACrE,CAMA,QAAQ,EAA0C,CAChD,IAAM,EAAO,KAAK,QAAQ,CAAQ,EAClC,OAAO,GAAQ,CAAC,EAAY,CAAI,EAAI,EAAO,IAC7C,CAMA,SAAS,EAAoC,CAC3C,IAAM,EAAO,KAAK,QAAQ,CAAQ,EAClC,OAAO,GAAQ,EAAY,CAAI,EAAK,EAAc,IACpD,CAMA,UAAU,EAAoC,CAC5C,IAAM,EAAO,KAAK,OAAO,CAAQ,EAKjC,OAJI,IAAS,MAAQ,EAAK,SAAW,GAEjC,CAAC,EAAS,EAAM,KAAK,MAAM,KAAK,EAAU,KAEvC,EAAS,EAAc,CAAI,EAAG,KAAK,MAAM,KAAK,CACvD,CAUA,WAA+B,CAC7B,OAAO,KAAK,MAAM,MACpB,CAMA,gBAAoC,CAClC,OAAO,KAAK,MAAM,WACpB,CAOA,aAAa,EAAkB,CAC7B,OAAO,GAAa,EAAO,KAAK,MAAM,QAAQ,CAChD,CAGA,aAAa,EAAkC,CAC7C,OAAO,KAAK,aAAa,CAAK,CAChC,CAGA,gBAAgB,EAAe,EAA0C,CACvE,OAAO,KAAK,gBAAgB,EAAO,CAAQ,CAC7C,CAGA,cAAc,EAAiC,CAC7C,OAAO,KAAK,cAAc,CAAK,CACjC,CAGA,UAAU,EAAe,EAA0C,CACjE,OAAO,KAAK,UAAU,EAAO,CAAQ,CACvC,CAGA,mBAAmB,EAAe,EAAmC,CACnE,OAAO,KAAK,mBAAmB,EAAO,CAAQ,CAChD,CAMA,uBAAuB,EAAuB,CAC5C,OAAO,KAAK,gBAAgB,CAAK,CACnC,CAMA,oBAAoB,EAAyB,CAC3C,OAAO,KAAK,aAAa,CAAI,CAC/B,CASA,aAA4C,CAC1C,OAAO,KAAK,MAAM,QACpB,CAUA,eAAe,EAAgD,CAC7D,IAAM,EAAO,KAAK,QAAQ,CAAQ,EAClC,GAAI,CAAC,EAAM,OAAO,KAElB,IAAM,EAAa,KAAK,SAAS,EAEjC,OAAO,GACL,EACA,CACE,OAAQ,KAAK,MAAM,OACnB,SAAU,KAAK,MAAM,SACrB,cAAe,EAAW,EAAW,IACnC,KAAK,MAAM,QAAQ,eAAe,EAAG,EAAG,CAAI,GAAK,KACnD,cAAgB,GAAc,KAAK,cAAc,CAAC,EAClD,aAAe,GAAc,KAAK,aAAa,CAAC,EAChD,eAAgB,EAAW,EAAW,IACpC,KAAK,cAAc,EAAG,EAAG,CAAI,EAC/B,oBAAqB,EAAW,IAAc,KAAK,mBAAmB,EAAG,CAAC,EAC1E,WAAY,EAAW,IAAc,KAAK,UAAU,EAAG,CAAC,EACxD,iBAAkB,EAAW,IAAc,KAAK,gBAAgB,EAAG,CAAC,EACpE,yBAA0B,EAAW,IACnC,KAAK,MAAM,QAAQ,0BAA0B,EAAG,CAAI,GAAK,CAAC,CAC9D,EACA,CACE,cAAe,OAAO,GAAe,UAAY,CAAC,EAAI,EACtD,GAAI,EAAK,EACX,CACF,CACF,CAQA,oBAAoB,EAA0B,CAAC,EAA+B,CAC5E,IAAM,EAAY,KAAK,SAAS,CAAQ,EACxC,GAAI,CAAC,EAAW,OAAO,KAEvB,IAAM,EAAa,KAAK,SAAS,EAEjC,OAAO,GAA0B,EAAW,KAAK,MAAM,YAAa,CAClE,cAAe,OAAO,GAAe,UAAY,CAAC,EAAI,EACtD,GAAI,EAAU,EAChB,CAAC,CACH,CAOA,MAAgB,CACd,OAAO,EAAkB,KAAK,MAAM,KAAK,CAC3C,CAMA,YAAY,EAAiC,CAC3C,OAAO,GAAY,KAAK,MAAM,MAAO,CAAK,CAC5C,CAGA,aAAiC,CAC/B,OAAO,GAAY,KAAK,MAAM,MAAO,aAAa,CACpD,CAMA,QAAa,CACX,OAAO,KAAK,MAAM,KACpB,CAWA,MAAkE,CAChE,OAAO,IAAI,EACT,GAAY,KAAK,MAAM,KAAK,EAC5B,KAAK,MAAM,OACb,CACF,CAOA,QAAkE,CAChE,OAAO,IAAI,EACT,EAAc,KAAK,MAAM,KAAK,EAC9B,KAAK,MAAM,OACb,CACF,CAUA,UAAmB,EAAwC,CAEzD,OAAQ,EAAuB,KAAK,MAAM,MAAO,CAAO,CAC1D,CAGF"}