{"version":3,"file":"static/js/426.3ac027f3.chunk.js","mappings":"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","sources":["../node_modules/@algolia/events/events.js","../node_modules/algoliasearch-helper/index.js","../node_modules/algoliasearch-helper/src/DerivedHelper/index.js","../node_modules/algoliasearch-helper/src/RecommendParameters/index.js","../node_modules/algoliasearch-helper/src/RecommendResults/index.js","../node_modules/algoliasearch-helper/src/SearchParameters/RefinementList.js","../node_modules/algoliasearch-helper/src/SearchParameters/index.js","../node_modules/algoliasearch-helper/src/SearchResults/generate-hierarchical-tree.js","../node_modules/algoliasearch-helper/src/SearchResults/index.js","../node_modules/algoliasearch-helper/src/algoliasearch.helper.js","../node_modules/algoliasearch-helper/src/functions/compact.js","../node_modules/algoliasearch-helper/src/functions/defaultsPure.js","../node_modules/algoliasearch-helper/src/functions/escapeFacetValue.js","../node_modules/algoliasearch-helper/src/functions/find.js","../node_modules/algoliasearch-helper/src/functions/findIndex.js","../node_modules/algoliasearch-helper/src/functions/flat.js","../node_modules/algoliasearch-helper/src/functions/formatSort.js","../node_modules/algoliasearch-helper/src/functions/inherits.js","../node_modules/algoliasearch-helper/src/functions/intersection.js","../node_modules/algoliasearch-helper/src/functions/merge.js","../node_modules/algoliasearch-helper/src/functions/objectHasKeys.js","../node_modules/algoliasearch-helper/src/functions/omit.js","../node_modules/algoliasearch-helper/src/functions/orderBy.js","../node_modules/algoliasearch-helper/src/functions/valToNumber.js","../node_modules/algoliasearch-helper/src/requestBuilder.js","../node_modules/algoliasearch-helper/src/utils/isValidUserToken.js","../node_modules/algoliasearch-helper/src/utils/sortAndMergeRecommendations.js","../node_modules/algoliasearch-helper/src/version.js"],"sourcesContent":["// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n  this._events = this._events || {};\n  this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\n// EventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n  if (!isNumber(n) || n < 0 || isNaN(n))\n    throw TypeError('n must be a positive number');\n  this._maxListeners = n;\n  return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n  var er, handler, len, args, i, listeners;\n\n  if (!this._events)\n    this._events = {};\n\n  // If there is no 'error' event listener then throw.\n  if (type === 'error') {\n    if (!this._events.error ||\n        (isObject(this._events.error) && !this._events.error.length)) {\n      er = arguments[1];\n      if (er instanceof Error) {\n        throw er; // Unhandled 'error' event\n      } else {\n        // At least give some kind of context to the user\n        var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n        err.context = er;\n        throw err;\n      }\n    }\n  }\n\n  handler = this._events[type];\n\n  if (isUndefined(handler))\n    return false;\n\n  if (isFunction(handler)) {\n    switch (arguments.length) {\n      // fast cases\n      case 1:\n        handler.call(this);\n        break;\n      case 2:\n        handler.call(this, arguments[1]);\n        break;\n      case 3:\n        handler.call(this, arguments[1], arguments[2]);\n        break;\n      // slower\n      default:\n        args = Array.prototype.slice.call(arguments, 1);\n        handler.apply(this, args);\n    }\n  } else if (isObject(handler)) {\n    args = Array.prototype.slice.call(arguments, 1);\n    listeners = handler.slice();\n    len = listeners.length;\n    for (i = 0; i < len; i++)\n      listeners[i].apply(this, args);\n  }\n\n  return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n  var m;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events)\n    this._events = {};\n\n  // To avoid recursion in the case that type === \"newListener\"! Before\n  // adding it to the listeners, first emit \"newListener\".\n  if (this._events.newListener)\n    this.emit('newListener', type,\n              isFunction(listener.listener) ?\n              listener.listener : listener);\n\n  if (!this._events[type])\n    // Optimize the case of one listener. Don't need the extra array object.\n    this._events[type] = listener;\n  else if (isObject(this._events[type]))\n    // If we've already got an array, just append.\n    this._events[type].push(listener);\n  else\n    // Adding the second element, need to change to array.\n    this._events[type] = [this._events[type], listener];\n\n  // Check for listener leak\n  if (isObject(this._events[type]) && !this._events[type].warned) {\n    if (!isUndefined(this._maxListeners)) {\n      m = this._maxListeners;\n    } else {\n      m = EventEmitter.defaultMaxListeners;\n    }\n\n    if (m && m > 0 && this._events[type].length > m) {\n      this._events[type].warned = true;\n      console.error('(node) warning: possible EventEmitter memory ' +\n                    'leak detected. %d listeners added. ' +\n                    'Use emitter.setMaxListeners() to increase limit.',\n                    this._events[type].length);\n      if (typeof console.trace === 'function') {\n        // not supported in IE 10\n        console.trace();\n      }\n    }\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  var fired = false;\n\n  function g() {\n    this.removeListener(type, g);\n\n    if (!fired) {\n      fired = true;\n      listener.apply(this, arguments);\n    }\n  }\n\n  g.listener = listener;\n  this.on(type, g);\n\n  return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n  var list, position, length, i;\n\n  if (!isFunction(listener))\n    throw TypeError('listener must be a function');\n\n  if (!this._events || !this._events[type])\n    return this;\n\n  list = this._events[type];\n  length = list.length;\n  position = -1;\n\n  if (list === listener ||\n      (isFunction(list.listener) && list.listener === listener)) {\n    delete this._events[type];\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n\n  } else if (isObject(list)) {\n    for (i = length; i-- > 0;) {\n      if (list[i] === listener ||\n          (list[i].listener && list[i].listener === listener)) {\n        position = i;\n        break;\n      }\n    }\n\n    if (position < 0)\n      return this;\n\n    if (list.length === 1) {\n      list.length = 0;\n      delete this._events[type];\n    } else {\n      list.splice(position, 1);\n    }\n\n    if (this._events.removeListener)\n      this.emit('removeListener', type, listener);\n  }\n\n  return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n  var key, listeners;\n\n  if (!this._events)\n    return this;\n\n  // not listening for removeListener, no need to emit\n  if (!this._events.removeListener) {\n    if (arguments.length === 0)\n      this._events = {};\n    else if (this._events[type])\n      delete this._events[type];\n    return this;\n  }\n\n  // emit removeListener for all listeners on all events\n  if (arguments.length === 0) {\n    for (key in this._events) {\n      if (key === 'removeListener') continue;\n      this.removeAllListeners(key);\n    }\n    this.removeAllListeners('removeListener');\n    this._events = {};\n    return this;\n  }\n\n  listeners = this._events[type];\n\n  if (isFunction(listeners)) {\n    this.removeListener(type, listeners);\n  } else if (listeners) {\n    // LIFO order\n    while (listeners.length)\n      this.removeListener(type, listeners[listeners.length - 1]);\n  }\n  delete this._events[type];\n\n  return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n  var ret;\n  if (!this._events || !this._events[type])\n    ret = [];\n  else if (isFunction(this._events[type]))\n    ret = [this._events[type]];\n  else\n    ret = this._events[type].slice();\n  return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n  if (this._events) {\n    var evlistener = this._events[type];\n\n    if (isFunction(evlistener))\n      return 1;\n    else if (evlistener)\n      return evlistener.length;\n  }\n  return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n  return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n  return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n  return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n  return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n  return arg === void 0;\n}\n","'use strict';\n\nvar AlgoliaSearchHelper = require('./src/algoliasearch.helper');\nvar RecommendParameters = require('./src/RecommendParameters');\nvar RecommendResults = require('./src/RecommendResults');\nvar SearchParameters = require('./src/SearchParameters');\nvar SearchResults = require('./src/SearchResults');\n\n/**\n * The algoliasearchHelper module is the function that will let its\n * contains everything needed to use the Algoliasearch\n * Helper. It is a also a function that instanciate the helper.\n * To use the helper, you also need the Algolia JS client v3.\n * @example\n * //using the UMD build\n * var client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76');\n * var helper = algoliasearchHelper(client, 'bestbuy', {\n *   facets: ['shipping'],\n *   disjunctiveFacets: ['category']\n * });\n * helper.on('result', function(event) {\n *   console.log(event.results);\n * });\n * helper\n *   .toggleFacetRefinement('category', 'Movies & TV Shows')\n *   .toggleFacetRefinement('shipping', 'Free shipping')\n *   .search();\n * @example\n * // The helper is an event emitter using the node API\n * helper.on('result', updateTheResults);\n * helper.once('result', updateTheResults);\n * helper.removeListener('result', updateTheResults);\n * helper.removeAllListeners('result');\n * @module algoliasearchHelper\n * @param  {AlgoliaSearch} client an AlgoliaSearch client\n * @param  {string} index the name of the index to query\n * @param  {SearchParameters|object} opts an object defining the initial config of the search. It doesn't have to be a {SearchParameters}, just an object containing the properties you need from it.\n * @param {SearchResultsOptions|object} searchResultsOptions an object defining the options to use when creating the search results.\n * @return {AlgoliaSearchHelper} The helper instance\n */\nfunction algoliasearchHelper(client, index, opts, searchResultsOptions) {\n  return new AlgoliaSearchHelper(client, index, opts, searchResultsOptions);\n}\n\n/**\n * The version currently used\n * @member module:algoliasearchHelper.version\n * @type {number}\n */\nalgoliasearchHelper.version = require('./src/version');\n\n/**\n * Constructor for the Helper.\n * @member module:algoliasearchHelper.AlgoliaSearchHelper\n * @type {AlgoliaSearchHelper}\n */\nalgoliasearchHelper.AlgoliaSearchHelper = AlgoliaSearchHelper;\n\n/**\n * Constructor for the object containing all the parameters of the search.\n * @member module:algoliasearchHelper.SearchParameters\n * @type {SearchParameters}\n */\nalgoliasearchHelper.SearchParameters = SearchParameters;\n\n/**\n * Constructor for the object containing all the parameters for Recommend.\n * @member module:algoliasearchHelper.RecommendParameters\n * @type {RecommendParameters}\n */\nalgoliasearchHelper.RecommendParameters = RecommendParameters;\n\n/**\n * Constructor for the object containing the results of the search.\n * @member module:algoliasearchHelper.SearchResults\n * @type {SearchResults}\n */\nalgoliasearchHelper.SearchResults = SearchResults;\n\n/**\n * Constructor for the object containing the results for Recommend.\n * @member module:algoliasearchHelper.RecommendResults\n * @type {RecommendResults}\n */\nalgoliasearchHelper.RecommendResults = RecommendResults;\n\nmodule.exports = algoliasearchHelper;\n","'use strict';\n\nvar EventEmitter = require('@algolia/events');\n\nvar inherits = require('../functions/inherits');\n\n/**\n * A DerivedHelper is a way to create sub requests to\n * Algolia from a main helper.\n * @class\n * @classdesc The DerivedHelper provides an event based interface for search callbacks:\n *  - search: when a search is triggered using the `search()` method.\n *  - result: when the response is retrieved from Algolia and is processed.\n *    This event contains a {@link SearchResults} object and the\n *    {@link SearchParameters} corresponding to this answer.\n * @param {AlgoliaSearchHelper} mainHelper the main helper\n * @param {function} fn the function to create the derived state for search\n * @param {function} recommendFn the function to create the derived state for recommendations\n */\nfunction DerivedHelper(mainHelper, fn, recommendFn) {\n  this.main = mainHelper;\n  this.fn = fn;\n  this.recommendFn = recommendFn;\n  this.lastResults = null;\n  this.lastRecommendResults = null;\n}\n\ninherits(DerivedHelper, EventEmitter);\n\n/**\n * Detach this helper from the main helper\n * @return {undefined}\n * @throws Error if the derived helper is already detached\n */\nDerivedHelper.prototype.detach = function () {\n  this.removeAllListeners();\n  this.main.detachDerivedHelper(this);\n};\n\nDerivedHelper.prototype.getModifiedState = function (parameters) {\n  return this.fn(parameters);\n};\n\nDerivedHelper.prototype.getModifiedRecommendState = function (parameters) {\n  return this.recommendFn(parameters);\n};\n\nmodule.exports = DerivedHelper;\n","'use strict';\n\n/**\n * RecommendParameters is the data structure that contains all the information\n * usable for getting recommendations from the Algolia API. It doesn't do the\n * search itself, nor does it contains logic about the parameters.\n * It is an immutable object, therefore it has been created in a way that each\n * changes does not change the object itself but returns a copy with the\n * modification.\n * This object should probably not be instantiated outside of the helper. It\n * will be provided when needed.\n * @constructor\n * @classdesc contains all the parameters for recommendations\n * @param {RecommendParametersOptions} opts the options to create the object\n */\nfunction RecommendParameters(opts) {\n  opts = opts || {};\n  this.params = opts.params || [];\n}\n\nRecommendParameters.prototype = {\n  constructor: RecommendParameters,\n\n  addParams: function (params) {\n    var newParams = this.params.slice();\n\n    newParams.push(params);\n\n    return new RecommendParameters({ params: newParams });\n  },\n\n  removeParams: function (id) {\n    return new RecommendParameters({\n      params: this.params.filter(function (param) {\n        return param.$$id !== id;\n      }),\n    });\n  },\n\n  addFrequentlyBoughtTogether: function (params) {\n    return this.addParams(\n      Object.assign({}, params, { model: 'bought-together' })\n    );\n  },\n\n  addRelatedProducts: function (params) {\n    return this.addParams(\n      Object.assign({}, params, { model: 'related-products' })\n    );\n  },\n\n  addTrendingItems: function (params) {\n    return this.addParams(\n      Object.assign({}, params, { model: 'trending-items' })\n    );\n  },\n\n  addTrendingFacets: function (params) {\n    return this.addParams(\n      Object.assign({}, params, { model: 'trending-facets' })\n    );\n  },\n\n  addLookingSimilar: function (params) {\n    return this.addParams(\n      Object.assign({}, params, { model: 'looking-similar' })\n    );\n  },\n\n  _buildQueries: function (indexName, cache) {\n    return this.params\n      .filter(function (params) {\n        return cache[params.$$id] === undefined;\n      })\n      .map(function (params) {\n        var query = Object.assign({}, params, {\n          indexName: indexName,\n          // @TODO: remove this if it ever gets handled by the API\n          threshold: params.threshold || 0,\n        });\n        delete query.$$id;\n\n        return query;\n      });\n  },\n};\n\nmodule.exports = RecommendParameters;\n","'use strict';\n\n/**\n * Constructor for SearchResults\n * @class\n * @classdesc SearchResults contains the results of a query to Algolia using the\n * {@link AlgoliaSearchHelper}.\n * @param {RecommendParameters} state state that led to the response\n * @param {Record<string,RecommendResultItem>} results the results from algolia client\n **/\nfunction RecommendResults(state, results) {\n  this._state = state;\n  this._rawResults = {};\n\n  // eslint-disable-next-line consistent-this\n  var self = this;\n\n  state.params.forEach(function (param) {\n    var id = param.$$id;\n    self[id] = results[id];\n    self._rawResults[id] = results[id];\n  });\n}\n\nRecommendResults.prototype = {\n  constructor: RecommendResults,\n};\n\nmodule.exports = RecommendResults;\n","'use strict';\n\n/**\n * Functions to manipulate refinement lists\n *\n * The RefinementList is not formally defined through a prototype but is based\n * on a specific structure.\n *\n * @module SearchParameters.refinementList\n *\n * @typedef {string[]} SearchParameters.refinementList.Refinements\n * @typedef {Object.<string, SearchParameters.refinementList.Refinements>} SearchParameters.refinementList.RefinementList\n */\n\nvar defaultsPure = require('../functions/defaultsPure');\nvar objectHasKeys = require('../functions/objectHasKeys');\nvar omit = require('../functions/omit');\n\nvar lib = {\n  /**\n   * Adds a refinement to a RefinementList\n   * @param {RefinementList} refinementList the initial list\n   * @param {string} attribute the attribute to refine\n   * @param {string} value the value of the refinement, if the value is not a string it will be converted\n   * @return {RefinementList} a new and updated refinement list\n   */\n  addRefinement: function addRefinement(refinementList, attribute, value) {\n    if (lib.isRefined(refinementList, attribute, value)) {\n      return refinementList;\n    }\n\n    var valueAsString = '' + value;\n\n    var facetRefinement = !refinementList[attribute]\n      ? [valueAsString]\n      : refinementList[attribute].concat(valueAsString);\n\n    var mod = {};\n\n    mod[attribute] = facetRefinement;\n\n    return defaultsPure({}, mod, refinementList);\n  },\n  /**\n   * Removes refinement(s) for an attribute:\n   *  - if the value is specified removes the refinement for the value on the attribute\n   *  - if no value is specified removes all the refinements for this attribute\n   * @param {RefinementList} refinementList the initial list\n   * @param {string} attribute the attribute to refine\n   * @param {string} [value] the value of the refinement\n   * @return {RefinementList} a new and updated refinement lst\n   */\n  removeRefinement: function removeRefinement(\n    refinementList,\n    attribute,\n    value\n  ) {\n    if (value === undefined) {\n      // we use the \"filter\" form of clearRefinement, since it leaves empty values as-is\n      // the form with a string will remove the attribute completely\n      return lib.clearRefinement(refinementList, function (v, f) {\n        return attribute === f;\n      });\n    }\n\n    var valueAsString = '' + value;\n\n    return lib.clearRefinement(refinementList, function (v, f) {\n      return attribute === f && valueAsString === v;\n    });\n  },\n  /**\n   * Toggles the refinement value for an attribute.\n   * @param {RefinementList} refinementList the initial list\n   * @param {string} attribute the attribute to refine\n   * @param {string} value the value of the refinement\n   * @return {RefinementList} a new and updated list\n   */\n  toggleRefinement: function toggleRefinement(\n    refinementList,\n    attribute,\n    value\n  ) {\n    if (value === undefined)\n      throw new Error('toggleRefinement should be used with a value');\n\n    if (lib.isRefined(refinementList, attribute, value)) {\n      return lib.removeRefinement(refinementList, attribute, value);\n    }\n\n    return lib.addRefinement(refinementList, attribute, value);\n  },\n  /**\n   * Clear all or parts of a RefinementList. Depending on the arguments, three\n   * kinds of behavior can happen:\n   *  - if no attribute is provided: clears the whole list\n   *  - if an attribute is provided as a string: clears the list for the specific attribute\n   *  - if an attribute is provided as a function: discards the elements for which the function returns true\n   * @param {RefinementList} refinementList the initial list\n   * @param {string} [attribute] the attribute or function to discard\n   * @param {string} [refinementType] optional parameter to give more context to the attribute function\n   * @return {RefinementList} a new and updated refinement list\n   */\n  clearRefinement: function clearRefinement(\n    refinementList,\n    attribute,\n    refinementType\n  ) {\n    if (attribute === undefined) {\n      // return the same object if the list is already empty\n      // this is mainly for tests, as it doesn't have much impact on performance\n      if (!objectHasKeys(refinementList)) {\n        return refinementList;\n      }\n      return {};\n    } else if (typeof attribute === 'string') {\n      return omit(refinementList, [attribute]);\n    } else if (typeof attribute === 'function') {\n      var hasChanged = false;\n\n      var newRefinementList = Object.keys(refinementList).reduce(function (\n        memo,\n        key\n      ) {\n        var values = refinementList[key] || [];\n        var facetList = values.filter(function (value) {\n          return !attribute(value, key, refinementType);\n        });\n\n        if (facetList.length !== values.length) {\n          hasChanged = true;\n        }\n\n        memo[key] = facetList;\n\n        return memo;\n      },\n      {});\n\n      if (hasChanged) return newRefinementList;\n      return refinementList;\n    }\n\n    // We return nothing if the attribute is not undefined, a string or a function,\n    // as it is not a valid value for a refinement\n    return undefined;\n  },\n  /**\n   * Test if the refinement value is used for the attribute. If no refinement value\n   * is provided, test if the refinementList contains any refinement for the\n   * given attribute.\n   * @param {RefinementList} refinementList the list of refinement\n   * @param {string} attribute name of the attribute\n   * @param {string} [refinementValue] value of the filter/refinement\n   * @return {boolean} true if the attribute is refined, false otherwise\n   */\n  isRefined: function isRefined(refinementList, attribute, refinementValue) {\n    var containsRefinements =\n      Boolean(refinementList[attribute]) &&\n      refinementList[attribute].length > 0;\n\n    if (refinementValue === undefined || !containsRefinements) {\n      return containsRefinements;\n    }\n\n    var refinementValueAsString = '' + refinementValue;\n\n    return refinementList[attribute].indexOf(refinementValueAsString) !== -1;\n  },\n};\n\nmodule.exports = lib;\n","'use strict';\n\nvar defaultsPure = require('../functions/defaultsPure');\nvar find = require('../functions/find');\nvar intersection = require('../functions/intersection');\nvar merge = require('../functions/merge');\nvar objectHasKeys = require('../functions/objectHasKeys');\nvar omit = require('../functions/omit');\nvar valToNumber = require('../functions/valToNumber');\nvar isValidUserToken = require('../utils/isValidUserToken');\n\nvar RefinementList = require('./RefinementList');\n\n/**\n * isEqual, but only for numeric refinement values, possible values:\n * - 5\n * - [5]\n * - [[5]]\n * - [[5,5],[4]]\n * @param {any} a numeric refinement value\n * @param {any} b numeric refinement value\n * @return {boolean} true if the values are equal\n */\nfunction isEqualNumericRefinement(a, b) {\n  if (Array.isArray(a) && Array.isArray(b)) {\n    return (\n      a.length === b.length &&\n      a.every(function (el, i) {\n        return isEqualNumericRefinement(b[i], el);\n      })\n    );\n  }\n  return a === b;\n}\n\n/**\n * like _.find but using deep equality to be able to use it\n * to find arrays.\n * @private\n * @param {any[]} array array to search into (elements are base or array of base)\n * @param {any} searchedValue the value we're looking for (base or array of base)\n * @return {any} the searched value or undefined\n */\nfunction findArray(array, searchedValue) {\n  return find(array, function (currentValue) {\n    return isEqualNumericRefinement(currentValue, searchedValue);\n  });\n}\n\n/**\n * The facet list is the structure used to store the list of values used to\n * filter a single attribute.\n * @typedef {string[]} SearchParameters.FacetList\n */\n\n/**\n * Structure to store numeric filters with the operator as the key. The supported operators\n * are `=`, `>`, `<`, `>=`, `<=` and `!=`.\n * @typedef {Object.<string, Array.<number|number[]>>} SearchParameters.OperatorList\n */\n\n/**\n * SearchParameters is the data structure that contains all the information\n * usable for making a search to Algolia API. It doesn't do the search itself,\n * nor does it contains logic about the parameters.\n * It is an immutable object, therefore it has been created in a way that each\n * changes does not change the object itself but returns a copy with the\n * modification.\n * This object should probably not be instantiated outside of the helper. It will\n * be provided when needed. This object is documented for reference as you'll\n * get it from events generated by the {@link AlgoliaSearchHelper}.\n * If need be, instantiate the Helper from the factory function {@link SearchParameters.make}\n * @constructor\n * @classdesc contains all the parameters of a search\n * @param {object|SearchParameters} newParameters existing parameters or partial object\n * for the properties of a new SearchParameters\n * @see SearchParameters.make\n * @example <caption>SearchParameters of the first query in\n *   <a href=\"http://demos.algolia.com/instant-search-demo/\">the instant search demo</a></caption>\n{\n   \"query\": \"\",\n   \"disjunctiveFacets\": [\n      \"customerReviewCount\",\n      \"category\",\n      \"salePrice_range\",\n      \"manufacturer\"\n  ],\n   \"maxValuesPerFacet\": 30,\n   \"page\": 0,\n   \"hitsPerPage\": 10,\n   \"facets\": [\n      \"type\",\n      \"shipping\"\n  ]\n}\n */\nfunction SearchParameters(newParameters) {\n  var params = newParameters\n    ? SearchParameters._parseNumbers(newParameters)\n    : {};\n\n  if (params.userToken !== undefined && !isValidUserToken(params.userToken)) {\n    // eslint-disable-next-line no-console\n    console.warn(\n      '[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\\n  - Format: [a-zA-Z0-9_-]{1,64}'\n    );\n  }\n  /**\n   * This attribute contains the list of all the conjunctive facets\n   * used. This list will be added to requested facets in the\n   * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia.\n   * @member {string[]}\n   */\n  this.facets = params.facets || [];\n  /**\n   * This attribute contains the list of all the disjunctive facets\n   * used. This list will be added to requested facets in the\n   * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia.\n   * @member {string[]}\n   */\n  this.disjunctiveFacets = params.disjunctiveFacets || [];\n  /**\n   * This attribute contains the list of all the hierarchical facets\n   * used. This list will be added to requested facets in the\n   * [facets attribute](https://www.algolia.com/doc/rest-api/search#param-facets) sent to algolia.\n   * Hierarchical facets are a sub type of disjunctive facets that\n   * let you filter faceted attributes hierarchically.\n   * @member {string[]|object[]}\n   */\n  this.hierarchicalFacets = params.hierarchicalFacets || [];\n\n  // Refinements\n  /**\n   * This attribute contains all the filters that need to be\n   * applied on the conjunctive facets. Each facet must be properly\n   * defined in the `facets` attribute.\n   *\n   * The key is the name of the facet, and the `FacetList` contains all\n   * filters selected for the associated facet name.\n   *\n   * When querying algolia, the values stored in this attribute will\n   * be translated into the `facetFilters` attribute.\n   * @member {Object.<string, SearchParameters.FacetList>}\n   */\n  this.facetsRefinements = params.facetsRefinements || {};\n  /**\n   * This attribute contains all the filters that need to be\n   * excluded from the conjunctive facets. Each facet must be properly\n   * defined in the `facets` attribute.\n   *\n   * The key is the name of the facet, and the `FacetList` contains all\n   * filters excluded for the associated facet name.\n   *\n   * When querying algolia, the values stored in this attribute will\n   * be translated into the `facetFilters` attribute.\n   * @member {Object.<string, SearchParameters.FacetList>}\n   */\n  this.facetsExcludes = params.facetsExcludes || {};\n  /**\n   * This attribute contains all the filters that need to be\n   * applied on the disjunctive facets. Each facet must be properly\n   * defined in the `disjunctiveFacets` attribute.\n   *\n   * The key is the name of the facet, and the `FacetList` contains all\n   * filters selected for the associated facet name.\n   *\n   * When querying algolia, the values stored in this attribute will\n   * be translated into the `facetFilters` attribute.\n   * @member {Object.<string, SearchParameters.FacetList>}\n   */\n  this.disjunctiveFacetsRefinements = params.disjunctiveFacetsRefinements || {};\n  /**\n   * This attribute contains all the filters that need to be\n   * applied on the numeric attributes.\n   *\n   * The key is the name of the attribute, and the value is the\n   * filters to apply to this attribute.\n   *\n   * When querying algolia, the values stored in this attribute will\n   * be translated into the `numericFilters` attribute.\n   * @member {Object.<string, SearchParameters.OperatorList>}\n   */\n  this.numericRefinements = params.numericRefinements || {};\n  /**\n   * This attribute contains all the tags used to refine the query.\n   *\n   * When querying algolia, the values stored in this attribute will\n   * be translated into the `tagFilters` attribute.\n   * @member {string[]}\n   */\n  this.tagRefinements = params.tagRefinements || [];\n  /**\n   * This attribute contains all the filters that need to be\n   * applied on the hierarchical facets. Each facet must be properly\n   * defined in the `hierarchicalFacets` attribute.\n   *\n   * The key is the name of the facet, and the `FacetList` contains all\n   * filters selected for the associated facet name. The FacetList values\n   * are structured as a string that contain the values for each level\n   * separated by the configured separator.\n   *\n   * When querying algolia, the values stored in this attribute will\n   * be translated into the `facetFilters` attribute.\n   * @member {Object.<string, SearchParameters.FacetList>}\n   */\n  this.hierarchicalFacetsRefinements =\n    params.hierarchicalFacetsRefinements || {};\n\n  // eslint-disable-next-line consistent-this\n  var self = this;\n  Object.keys(params).forEach(function (paramName) {\n    var isKeyKnown = SearchParameters.PARAMETERS.indexOf(paramName) !== -1;\n    var isValueDefined = params[paramName] !== undefined;\n\n    if (!isKeyKnown && isValueDefined) {\n      self[paramName] = params[paramName];\n    }\n  });\n}\n\n/**\n * List all the properties in SearchParameters and therefore all the known Algolia properties\n * This doesn't contain any beta/hidden features.\n * @private\n */\nSearchParameters.PARAMETERS = Object.keys(new SearchParameters());\n\n/**\n * @private\n * @param {object} partialState full or part of a state\n * @return {object} a new object with the number keys as number\n */\nSearchParameters._parseNumbers = function (partialState) {\n  // Do not parse numbers again in SearchParameters, they ought to be parsed already\n  if (partialState instanceof SearchParameters) return partialState;\n\n  var numbers = {};\n\n  var numberKeys = [\n    'aroundPrecision',\n    'aroundRadius',\n    'getRankingInfo',\n    'minWordSizefor2Typos',\n    'minWordSizefor1Typo',\n    'page',\n    'maxValuesPerFacet',\n    'distinct',\n    'minimumAroundRadius',\n    'hitsPerPage',\n    'minProximity',\n  ];\n\n  numberKeys.forEach(function (k) {\n    var value = partialState[k];\n    if (typeof value === 'string') {\n      var parsedValue = parseFloat(value);\n      // global isNaN is ok to use here, value is only number or NaN\n      numbers[k] = isNaN(parsedValue) ? value : parsedValue;\n    }\n  });\n\n  // there's two formats of insideBoundingBox, we need to parse\n  // the one which is an array of float geo rectangles\n  if (Array.isArray(partialState.insideBoundingBox)) {\n    numbers.insideBoundingBox = partialState.insideBoundingBox.map(function (\n      geoRect\n    ) {\n      if (Array.isArray(geoRect)) {\n        return geoRect.map(function (value) {\n          return parseFloat(value);\n        });\n      }\n      return geoRect;\n    });\n  }\n\n  if (partialState.numericRefinements) {\n    var numericRefinements = {};\n    Object.keys(partialState.numericRefinements).forEach(function (attribute) {\n      var operators = partialState.numericRefinements[attribute] || {};\n      numericRefinements[attribute] = {};\n      Object.keys(operators).forEach(function (operator) {\n        var values = operators[operator];\n        var parsedValues = values.map(function (v) {\n          if (Array.isArray(v)) {\n            return v.map(function (vPrime) {\n              if (typeof vPrime === 'string') {\n                return parseFloat(vPrime);\n              }\n              return vPrime;\n            });\n          } else if (typeof v === 'string') {\n            return parseFloat(v);\n          }\n          return v;\n        });\n        numericRefinements[attribute][operator] = parsedValues;\n      });\n    });\n    numbers.numericRefinements = numericRefinements;\n  }\n\n  return merge(partialState, numbers);\n};\n\n/**\n * Factory for SearchParameters\n * @param {object|SearchParameters} newParameters existing parameters or partial\n * object for the properties of a new SearchParameters\n * @return {SearchParameters} frozen instance of SearchParameters\n */\nSearchParameters.make = function makeSearchParameters(newParameters) {\n  var instance = new SearchParameters(newParameters);\n\n  var hierarchicalFacets = newParameters.hierarchicalFacets || [];\n  hierarchicalFacets.forEach(function (facet) {\n    if (facet.rootPath) {\n      var currentRefinement = instance.getHierarchicalRefinement(facet.name);\n\n      if (\n        currentRefinement.length > 0 &&\n        currentRefinement[0].indexOf(facet.rootPath) !== 0\n      ) {\n        instance = instance.clearRefinements(facet.name);\n      }\n\n      // get it again in case it has been cleared\n      currentRefinement = instance.getHierarchicalRefinement(facet.name);\n      if (currentRefinement.length === 0) {\n        instance = instance.toggleHierarchicalFacetRefinement(\n          facet.name,\n          facet.rootPath\n        );\n      }\n    }\n  });\n\n  return instance;\n};\n\n/**\n * Validates the new parameters based on the previous state\n * @param {SearchParameters} currentState the current state\n * @param {object|SearchParameters} parameters the new parameters to set\n * @return {Error|null} Error if the modification is invalid, null otherwise\n */\nSearchParameters.validate = function (currentState, parameters) {\n  var params = parameters || {};\n\n  if (\n    currentState.tagFilters &&\n    params.tagRefinements &&\n    params.tagRefinements.length > 0\n  ) {\n    return new Error(\n      '[Tags] Cannot switch from the managed tag API to the advanced API. It is probably ' +\n        'an error, if it is really what you want, you should first clear the tags with clearTags method.'\n    );\n  }\n\n  if (currentState.tagRefinements.length > 0 && params.tagFilters) {\n    return new Error(\n      '[Tags] Cannot switch from the advanced tag API to the managed API. It is probably ' +\n        'an error, if it is not, you should first clear the tags with clearTags method.'\n    );\n  }\n\n  if (\n    currentState.numericFilters &&\n    params.numericRefinements &&\n    objectHasKeys(params.numericRefinements)\n  ) {\n    return new Error(\n      \"[Numeric filters] Can't switch from the advanced to the managed API. It\" +\n        ' is probably an error, if this is really what you want, you have to first' +\n        ' clear the numeric filters.'\n    );\n  }\n\n  if (objectHasKeys(currentState.numericRefinements) && params.numericFilters) {\n    return new Error(\n      \"[Numeric filters] Can't switch from the managed API to the advanced. It\" +\n        ' is probably an error, if this is really what you want, you have to first' +\n        ' clear the numeric filters.'\n    );\n  }\n\n  return null;\n};\n\nSearchParameters.prototype = {\n  constructor: SearchParameters,\n\n  /**\n   * Remove all refinements (disjunctive + conjunctive + excludes + numeric filters)\n   * @method\n   * @param {undefined|string|SearchParameters.clearCallback} [attribute] optional string or function\n   * - If not given, means to clear all the filters.\n   * - If `string`, means to clear all refinements for the `attribute` named filter.\n   * - If `function`, means to clear all the refinements that return truthy values.\n   * @return {SearchParameters} new instance with filters cleared\n   */\n  clearRefinements: function clearRefinements(attribute) {\n    var patch = {\n      numericRefinements: this._clearNumericRefinements(attribute),\n      facetsRefinements: RefinementList.clearRefinement(\n        this.facetsRefinements,\n        attribute,\n        'conjunctiveFacet'\n      ),\n      facetsExcludes: RefinementList.clearRefinement(\n        this.facetsExcludes,\n        attribute,\n        'exclude'\n      ),\n      disjunctiveFacetsRefinements: RefinementList.clearRefinement(\n        this.disjunctiveFacetsRefinements,\n        attribute,\n        'disjunctiveFacet'\n      ),\n      hierarchicalFacetsRefinements: RefinementList.clearRefinement(\n        this.hierarchicalFacetsRefinements,\n        attribute,\n        'hierarchicalFacet'\n      ),\n    };\n    if (\n      patch.numericRefinements === this.numericRefinements &&\n      patch.facetsRefinements === this.facetsRefinements &&\n      patch.facetsExcludes === this.facetsExcludes &&\n      patch.disjunctiveFacetsRefinements ===\n        this.disjunctiveFacetsRefinements &&\n      patch.hierarchicalFacetsRefinements === this.hierarchicalFacetsRefinements\n    ) {\n      return this;\n    }\n    return this.setQueryParameters(patch);\n  },\n  /**\n   * Remove all the refined tags from the SearchParameters\n   * @method\n   * @return {SearchParameters} new instance with tags cleared\n   */\n  clearTags: function clearTags() {\n    if (this.tagFilters === undefined && this.tagRefinements.length === 0)\n      return this;\n\n    return this.setQueryParameters({\n      tagFilters: undefined,\n      tagRefinements: [],\n    });\n  },\n  /**\n   * Set the index.\n   * @method\n   * @param {string} index the index name\n   * @return {SearchParameters} new instance\n   */\n  setIndex: function setIndex(index) {\n    if (index === this.index) return this;\n\n    return this.setQueryParameters({\n      index: index,\n    });\n  },\n  /**\n   * Query setter\n   * @method\n   * @param {string} newQuery value for the new query\n   * @return {SearchParameters} new instance\n   */\n  setQuery: function setQuery(newQuery) {\n    if (newQuery === this.query) return this;\n\n    return this.setQueryParameters({\n      query: newQuery,\n    });\n  },\n  /**\n   * Page setter\n   * @method\n   * @param {number} newPage new page number\n   * @return {SearchParameters} new instance\n   */\n  setPage: function setPage(newPage) {\n    if (newPage === this.page) return this;\n\n    return this.setQueryParameters({\n      page: newPage,\n    });\n  },\n  /**\n   * Facets setter\n   * The facets are the simple facets, used for conjunctive (and) faceting.\n   * @method\n   * @param {string[]} facets all the attributes of the algolia records used for conjunctive faceting\n   * @return {SearchParameters} new instance\n   */\n  setFacets: function setFacets(facets) {\n    return this.setQueryParameters({\n      facets: facets,\n    });\n  },\n  /**\n   * Disjunctive facets setter\n   * Change the list of disjunctive (or) facets the helper chan handle.\n   * @method\n   * @param {string[]} facets all the attributes of the algolia records used for disjunctive faceting\n   * @return {SearchParameters} new instance\n   */\n  setDisjunctiveFacets: function setDisjunctiveFacets(facets) {\n    return this.setQueryParameters({\n      disjunctiveFacets: facets,\n    });\n  },\n  /**\n   * HitsPerPage setter\n   * Hits per page represents the number of hits retrieved for this query\n   * @method\n   * @param {number} n number of hits retrieved per page of results\n   * @return {SearchParameters} new instance\n   */\n  setHitsPerPage: function setHitsPerPage(n) {\n    if (this.hitsPerPage === n) return this;\n\n    return this.setQueryParameters({\n      hitsPerPage: n,\n    });\n  },\n  /**\n   * typoTolerance setter\n   * Set the value of typoTolerance\n   * @method\n   * @param {string} typoTolerance new value of typoTolerance (\"true\", \"false\", \"min\" or \"strict\")\n   * @return {SearchParameters} new instance\n   */\n  setTypoTolerance: function setTypoTolerance(typoTolerance) {\n    if (this.typoTolerance === typoTolerance) return this;\n\n    return this.setQueryParameters({\n      typoTolerance: typoTolerance,\n    });\n  },\n  /**\n   * Add a numeric filter for a given attribute\n   * When value is an array, they are combined with OR\n   * When value is a single value, it will combined with AND\n   * @method\n   * @param {string} attribute attribute to set the filter on\n   * @param {string} operator operator of the filter (possible values: =, >, >=, <, <=, !=)\n   * @param {number | number[]} value value of the filter\n   * @return {SearchParameters} new instance\n   * @example\n   * // for price = 50 or 40\n   * state.addNumericRefinement('price', '=', [50, 40]);\n   * @example\n   * // for size = 38 and 40\n   * state.addNumericRefinement('size', '=', 38);\n   * state.addNumericRefinement('size', '=', 40);\n   */\n  addNumericRefinement: function (attribute, operator, value) {\n    var val = valToNumber(value);\n\n    if (this.isNumericRefined(attribute, operator, val)) return this;\n\n    var mod = merge({}, this.numericRefinements);\n\n    mod[attribute] = merge({}, mod[attribute]);\n\n    if (mod[attribute][operator]) {\n      // Array copy\n      mod[attribute][operator] = mod[attribute][operator].slice();\n      // Add the element. Concat can't be used here because value can be an array.\n      mod[attribute][operator].push(val);\n    } else {\n      mod[attribute][operator] = [val];\n    }\n\n    return this.setQueryParameters({\n      numericRefinements: mod,\n    });\n  },\n  /**\n   * Get the list of conjunctive refinements for a single facet\n   * @param {string} facetName name of the attribute used for faceting\n   * @return {string[]} list of refinements\n   */\n  getConjunctiveRefinements: function (facetName) {\n    if (!this.isConjunctiveFacet(facetName)) {\n      return [];\n    }\n    return this.facetsRefinements[facetName] || [];\n  },\n  /**\n   * Get the list of disjunctive refinements for a single facet\n   * @param {string} facetName name of the attribute used for faceting\n   * @return {string[]} list of refinements\n   */\n  getDisjunctiveRefinements: function (facetName) {\n    if (!this.isDisjunctiveFacet(facetName)) {\n      return [];\n    }\n    return this.disjunctiveFacetsRefinements[facetName] || [];\n  },\n  /**\n   * Get the list of hierarchical refinements for a single facet\n   * @param {string} facetName name of the attribute used for faceting\n   * @return {string[]} list of refinements\n   */\n  getHierarchicalRefinement: function (facetName) {\n    // we send an array but we currently do not support multiple\n    // hierarchicalRefinements for a hierarchicalFacet\n    return this.hierarchicalFacetsRefinements[facetName] || [];\n  },\n  /**\n   * Get the list of exclude refinements for a single facet\n   * @param {string} facetName name of the attribute used for faceting\n   * @return {string[]} list of refinements\n   */\n  getExcludeRefinements: function (facetName) {\n    if (!this.isConjunctiveFacet(facetName)) {\n      return [];\n    }\n    return this.facetsExcludes[facetName] || [];\n  },\n\n  /**\n   * Remove all the numeric filter for a given (attribute, operator)\n   * @method\n   * @param {string} attribute attribute to set the filter on\n   * @param {string} [operator] operator of the filter (possible values: =, >, >=, <, <=, !=)\n   * @param {number} [number] the value to be removed\n   * @return {SearchParameters} new instance\n   */\n  removeNumericRefinement: function (attribute, operator, number) {\n    var paramValue = number;\n    if (paramValue !== undefined) {\n      if (!this.isNumericRefined(attribute, operator, paramValue)) {\n        return this;\n      }\n      return this.setQueryParameters({\n        numericRefinements: this._clearNumericRefinements(function (\n          value,\n          key\n        ) {\n          return (\n            key === attribute &&\n            value.op === operator &&\n            isEqualNumericRefinement(value.val, valToNumber(paramValue))\n          );\n        }),\n      });\n    } else if (operator !== undefined) {\n      if (!this.isNumericRefined(attribute, operator)) return this;\n      return this.setQueryParameters({\n        numericRefinements: this._clearNumericRefinements(function (\n          value,\n          key\n        ) {\n          return key === attribute && value.op === operator;\n        }),\n      });\n    }\n\n    if (!this.isNumericRefined(attribute)) return this;\n    return this.setQueryParameters({\n      numericRefinements: this._clearNumericRefinements(function (value, key) {\n        return key === attribute;\n      }),\n    });\n  },\n  /**\n   * Get the list of numeric refinements for a single facet\n   * @param {string} facetName name of the attribute used for faceting\n   * @return {SearchParameters.OperatorList} list of refinements\n   */\n  getNumericRefinements: function (facetName) {\n    return this.numericRefinements[facetName] || {};\n  },\n  /**\n   * Return the current refinement for the (attribute, operator)\n   * @param {string} attribute attribute in the record\n   * @param {string} operator operator applied on the refined values\n   * @return {Array.<number|number[]>} refined values\n   */\n  getNumericRefinement: function (attribute, operator) {\n    return (\n      this.numericRefinements[attribute] &&\n      this.numericRefinements[attribute][operator]\n    );\n  },\n  /**\n   * Clear numeric filters.\n   * @method\n   * @private\n   * @param {string|SearchParameters.clearCallback} [attribute] optional string or function\n   * - If not given, means to clear all the filters.\n   * - If `string`, means to clear all refinements for the `attribute` named filter.\n   * - If `function`, means to clear all the refinements that return truthy values.\n   * @return {Object.<string, OperatorList>} new numeric refinements\n   */\n  _clearNumericRefinements: function _clearNumericRefinements(attribute) {\n    if (attribute === undefined) {\n      if (!objectHasKeys(this.numericRefinements)) {\n        return this.numericRefinements;\n      }\n      return {};\n    } else if (typeof attribute === 'string') {\n      return omit(this.numericRefinements, [attribute]);\n    } else if (typeof attribute === 'function') {\n      var hasChanged = false;\n      var numericRefinements = this.numericRefinements;\n      var newNumericRefinements = Object.keys(numericRefinements).reduce(\n        function (memo, key) {\n          var operators = numericRefinements[key];\n          var operatorList = {};\n\n          operators = operators || {};\n          Object.keys(operators).forEach(function (operator) {\n            var values = operators[operator] || [];\n            var outValues = [];\n            values.forEach(function (value) {\n              var predicateResult = attribute(\n                { val: value, op: operator },\n                key,\n                'numeric'\n              );\n              if (!predicateResult) outValues.push(value);\n            });\n            if (outValues.length !== values.length) {\n              hasChanged = true;\n            }\n            operatorList[operator] = outValues;\n          });\n\n          memo[key] = operatorList;\n\n          return memo;\n        },\n        {}\n      );\n\n      if (hasChanged) return newNumericRefinements;\n      return this.numericRefinements;\n    }\n\n    // We return nothing if the attribute is not undefined, a string or a function,\n    // as it is not a valid value for a refinement\n    return undefined;\n  },\n  /**\n   * Add a facet to the facets attribute of the helper configuration, if it\n   * isn't already present.\n   * @method\n   * @param {string} facet facet name to add\n   * @return {SearchParameters} new instance\n   */\n  addFacet: function addFacet(facet) {\n    if (this.isConjunctiveFacet(facet)) {\n      return this;\n    }\n\n    return this.setQueryParameters({\n      facets: this.facets.concat([facet]),\n    });\n  },\n  /**\n   * Add a disjunctive facet to the disjunctiveFacets attribute of the helper\n   * configuration, if it isn't already present.\n   * @method\n   * @param {string} facet disjunctive facet name to add\n   * @return {SearchParameters} new instance\n   */\n  addDisjunctiveFacet: function addDisjunctiveFacet(facet) {\n    if (this.isDisjunctiveFacet(facet)) {\n      return this;\n    }\n\n    return this.setQueryParameters({\n      disjunctiveFacets: this.disjunctiveFacets.concat([facet]),\n    });\n  },\n  /**\n   * Add a hierarchical facet to the hierarchicalFacets attribute of the helper\n   * configuration.\n   * @method\n   * @param {object} hierarchicalFacet hierarchical facet to add\n   * @return {SearchParameters} new instance\n   * @throws will throw an error if a hierarchical facet with the same name was already declared\n   */\n  addHierarchicalFacet: function addHierarchicalFacet(hierarchicalFacet) {\n    if (this.isHierarchicalFacet(hierarchicalFacet.name)) {\n      throw new Error(\n        'Cannot declare two hierarchical facets with the same name: `' +\n          hierarchicalFacet.name +\n          '`'\n      );\n    }\n\n    return this.setQueryParameters({\n      hierarchicalFacets: this.hierarchicalFacets.concat([hierarchicalFacet]),\n    });\n  },\n  /**\n   * Add a refinement on a \"normal\" facet\n   * @method\n   * @param {string} facet attribute to apply the faceting on\n   * @param {string} value value of the attribute (will be converted to string)\n   * @return {SearchParameters} new instance\n   */\n  addFacetRefinement: function addFacetRefinement(facet, value) {\n    if (!this.isConjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the facets attribute of the helper configuration'\n      );\n    }\n    if (RefinementList.isRefined(this.facetsRefinements, facet, value))\n      return this;\n\n    return this.setQueryParameters({\n      facetsRefinements: RefinementList.addRefinement(\n        this.facetsRefinements,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Exclude a value from a \"normal\" facet\n   * @method\n   * @param {string} facet attribute to apply the exclusion on\n   * @param {string} value value of the attribute (will be converted to string)\n   * @return {SearchParameters} new instance\n   */\n  addExcludeRefinement: function addExcludeRefinement(facet, value) {\n    if (!this.isConjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the facets attribute of the helper configuration'\n      );\n    }\n    if (RefinementList.isRefined(this.facetsExcludes, facet, value))\n      return this;\n\n    return this.setQueryParameters({\n      facetsExcludes: RefinementList.addRefinement(\n        this.facetsExcludes,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Adds a refinement on a disjunctive facet.\n   * @method\n   * @param {string} facet attribute to apply the faceting on\n   * @param {string} value value of the attribute (will be converted to string)\n   * @return {SearchParameters} new instance\n   */\n  addDisjunctiveFacetRefinement: function addDisjunctiveFacetRefinement(\n    facet,\n    value\n  ) {\n    if (!this.isDisjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the disjunctiveFacets attribute of the helper configuration'\n      );\n    }\n\n    if (\n      RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value)\n    )\n      return this;\n\n    return this.setQueryParameters({\n      disjunctiveFacetsRefinements: RefinementList.addRefinement(\n        this.disjunctiveFacetsRefinements,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * addTagRefinement adds a tag to the list used to filter the results\n   * @param {string} tag tag to be added\n   * @return {SearchParameters} new instance\n   */\n  addTagRefinement: function addTagRefinement(tag) {\n    if (this.isTagRefined(tag)) return this;\n\n    var modification = {\n      tagRefinements: this.tagRefinements.concat(tag),\n    };\n\n    return this.setQueryParameters(modification);\n  },\n  /**\n   * Remove a facet from the facets attribute of the helper configuration, if it\n   * is present.\n   * @method\n   * @param {string} facet facet name to remove\n   * @return {SearchParameters} new instance\n   */\n  removeFacet: function removeFacet(facet) {\n    if (!this.isConjunctiveFacet(facet)) {\n      return this;\n    }\n\n    return this.clearRefinements(facet).setQueryParameters({\n      facets: this.facets.filter(function (f) {\n        return f !== facet;\n      }),\n    });\n  },\n  /**\n   * Remove a disjunctive facet from the disjunctiveFacets attribute of the\n   * helper configuration, if it is present.\n   * @method\n   * @param {string} facet disjunctive facet name to remove\n   * @return {SearchParameters} new instance\n   */\n  removeDisjunctiveFacet: function removeDisjunctiveFacet(facet) {\n    if (!this.isDisjunctiveFacet(facet)) {\n      return this;\n    }\n\n    return this.clearRefinements(facet).setQueryParameters({\n      disjunctiveFacets: this.disjunctiveFacets.filter(function (f) {\n        return f !== facet;\n      }),\n    });\n  },\n  /**\n   * Remove a hierarchical facet from the hierarchicalFacets attribute of the\n   * helper configuration, if it is present.\n   * @method\n   * @param {string} facet hierarchical facet name to remove\n   * @return {SearchParameters} new instance\n   */\n  removeHierarchicalFacet: function removeHierarchicalFacet(facet) {\n    if (!this.isHierarchicalFacet(facet)) {\n      return this;\n    }\n\n    return this.clearRefinements(facet).setQueryParameters({\n      hierarchicalFacets: this.hierarchicalFacets.filter(function (f) {\n        return f.name !== facet;\n      }),\n    });\n  },\n  /**\n   * Remove a refinement set on facet. If a value is provided, it will clear the\n   * refinement for the given value, otherwise it will clear all the refinement\n   * values for the faceted attribute.\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {string} [value] value used to filter\n   * @return {SearchParameters} new instance\n   */\n  removeFacetRefinement: function removeFacetRefinement(facet, value) {\n    if (!this.isConjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the facets attribute of the helper configuration'\n      );\n    }\n    if (!RefinementList.isRefined(this.facetsRefinements, facet, value))\n      return this;\n\n    return this.setQueryParameters({\n      facetsRefinements: RefinementList.removeRefinement(\n        this.facetsRefinements,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Remove a negative refinement on a facet\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {string} value value used to filter\n   * @return {SearchParameters} new instance\n   */\n  removeExcludeRefinement: function removeExcludeRefinement(facet, value) {\n    if (!this.isConjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the facets attribute of the helper configuration'\n      );\n    }\n    if (!RefinementList.isRefined(this.facetsExcludes, facet, value))\n      return this;\n\n    return this.setQueryParameters({\n      facetsExcludes: RefinementList.removeRefinement(\n        this.facetsExcludes,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Remove a refinement on a disjunctive facet\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {string} value value used to filter\n   * @return {SearchParameters} new instance\n   */\n  removeDisjunctiveFacetRefinement: function removeDisjunctiveFacetRefinement(\n    facet,\n    value\n  ) {\n    if (!this.isDisjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the disjunctiveFacets attribute of the helper configuration'\n      );\n    }\n    if (\n      !RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value)\n    )\n      return this;\n\n    return this.setQueryParameters({\n      disjunctiveFacetsRefinements: RefinementList.removeRefinement(\n        this.disjunctiveFacetsRefinements,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Remove a tag from the list of tag refinements\n   * @method\n   * @param {string} tag the tag to remove\n   * @return {SearchParameters} new instance\n   */\n  removeTagRefinement: function removeTagRefinement(tag) {\n    if (!this.isTagRefined(tag)) return this;\n\n    var modification = {\n      tagRefinements: this.tagRefinements.filter(function (t) {\n        return t !== tag;\n      }),\n    };\n\n    return this.setQueryParameters(modification);\n  },\n  /**\n   * Generic toggle refinement method to use with facet, disjunctive facets\n   * and hierarchical facets\n   * @param  {string} facet the facet to refine\n   * @param  {string} value the associated value\n   * @return {SearchParameters} new instance\n   * @throws will throw an error if the facet is not declared in the settings of the helper\n   * @deprecated since version 2.19.0, see {@link SearchParameters#toggleFacetRefinement}\n   */\n  toggleRefinement: function toggleRefinement(facet, value) {\n    return this.toggleFacetRefinement(facet, value);\n  },\n  /**\n   * Generic toggle refinement method to use with facet, disjunctive facets\n   * and hierarchical facets\n   * @param  {string} facet the facet to refine\n   * @param  {string} value the associated value\n   * @return {SearchParameters} new instance\n   * @throws will throw an error if the facet is not declared in the settings of the helper\n   */\n  toggleFacetRefinement: function toggleFacetRefinement(facet, value) {\n    if (this.isHierarchicalFacet(facet)) {\n      return this.toggleHierarchicalFacetRefinement(facet, value);\n    } else if (this.isConjunctiveFacet(facet)) {\n      return this.toggleConjunctiveFacetRefinement(facet, value);\n    } else if (this.isDisjunctiveFacet(facet)) {\n      return this.toggleDisjunctiveFacetRefinement(facet, value);\n    }\n\n    throw new Error(\n      'Cannot refine the undeclared facet ' +\n        facet +\n        '; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets'\n    );\n  },\n  /**\n   * Switch the refinement applied over a facet/value\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {value} value value used for filtering\n   * @return {SearchParameters} new instance\n   */\n  toggleConjunctiveFacetRefinement: function toggleConjunctiveFacetRefinement(\n    facet,\n    value\n  ) {\n    if (!this.isConjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the facets attribute of the helper configuration'\n      );\n    }\n\n    return this.setQueryParameters({\n      facetsRefinements: RefinementList.toggleRefinement(\n        this.facetsRefinements,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Switch the refinement applied over a facet/value\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {value} value value used for filtering\n   * @return {SearchParameters} new instance\n   */\n  toggleExcludeFacetRefinement: function toggleExcludeFacetRefinement(\n    facet,\n    value\n  ) {\n    if (!this.isConjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the facets attribute of the helper configuration'\n      );\n    }\n\n    return this.setQueryParameters({\n      facetsExcludes: RefinementList.toggleRefinement(\n        this.facetsExcludes,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Switch the refinement applied over a facet/value\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {value} value value used for filtering\n   * @return {SearchParameters} new instance\n   */\n  toggleDisjunctiveFacetRefinement: function toggleDisjunctiveFacetRefinement(\n    facet,\n    value\n  ) {\n    if (!this.isDisjunctiveFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the disjunctiveFacets attribute of the helper configuration'\n      );\n    }\n\n    return this.setQueryParameters({\n      disjunctiveFacetsRefinements: RefinementList.toggleRefinement(\n        this.disjunctiveFacetsRefinements,\n        facet,\n        value\n      ),\n    });\n  },\n  /**\n   * Switch the refinement applied over a facet/value\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {value} value value used for filtering\n   * @return {SearchParameters} new instance\n   */\n  toggleHierarchicalFacetRefinement: function toggleHierarchicalFacetRefinement(\n    facet,\n    value\n  ) {\n    if (!this.isHierarchicalFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the hierarchicalFacets attribute of the helper configuration'\n      );\n    }\n\n    var separator = this._getHierarchicalFacetSeparator(\n      this.getHierarchicalFacetByName(facet)\n    );\n\n    var mod = {};\n\n    var upOneOrMultipleLevel =\n      this.hierarchicalFacetsRefinements[facet] !== undefined &&\n      this.hierarchicalFacetsRefinements[facet].length > 0 &&\n      // remove current refinement:\n      // refinement was 'beer > IPA', call is toggleRefine('beer > IPA'), refinement should be `beer`\n      (this.hierarchicalFacetsRefinements[facet][0] === value ||\n        // remove a parent refinement of the current refinement:\n        //  - refinement was 'beer > IPA > Flying dog'\n        //  - call is toggleRefine('beer > IPA')\n        //  - refinement should be `beer`\n        this.hierarchicalFacetsRefinements[facet][0].indexOf(\n          value + separator\n        ) === 0);\n\n    if (upOneOrMultipleLevel) {\n      if (value.indexOf(separator) === -1) {\n        // go back to root level\n        mod[facet] = [];\n      } else {\n        mod[facet] = [value.slice(0, value.lastIndexOf(separator))];\n      }\n    } else {\n      mod[facet] = [value];\n    }\n\n    return this.setQueryParameters({\n      hierarchicalFacetsRefinements: defaultsPure(\n        {},\n        mod,\n        this.hierarchicalFacetsRefinements\n      ),\n    });\n  },\n\n  /**\n   * Adds a refinement on a hierarchical facet.\n   * @param {string} facet the facet name\n   * @param {string} path the hierarchical facet path\n   * @return {SearchParameter} the new state\n   * @throws Error if the facet is not defined or if the facet is refined\n   */\n  addHierarchicalFacetRefinement: function (facet, path) {\n    if (this.isHierarchicalFacetRefined(facet)) {\n      throw new Error(facet + ' is already refined.');\n    }\n    if (!this.isHierarchicalFacet(facet)) {\n      throw new Error(\n        facet +\n          ' is not defined in the hierarchicalFacets attribute of the helper configuration.'\n      );\n    }\n    var mod = {};\n    mod[facet] = [path];\n    return this.setQueryParameters({\n      hierarchicalFacetsRefinements: defaultsPure(\n        {},\n        mod,\n        this.hierarchicalFacetsRefinements\n      ),\n    });\n  },\n\n  /**\n   * Removes the refinement set on a hierarchical facet.\n   * @param {string} facet the facet name\n   * @return {SearchParameter} the new state\n   * @throws Error if the facet is not defined or if the facet is not refined\n   */\n  removeHierarchicalFacetRefinement: function (facet) {\n    if (!this.isHierarchicalFacetRefined(facet)) {\n      return this;\n    }\n    var mod = {};\n    mod[facet] = [];\n    return this.setQueryParameters({\n      hierarchicalFacetsRefinements: defaultsPure(\n        {},\n        mod,\n        this.hierarchicalFacetsRefinements\n      ),\n    });\n  },\n  /**\n   * Switch the tag refinement\n   * @method\n   * @param {string} tag the tag to remove or add\n   * @return {SearchParameters} new instance\n   */\n  toggleTagRefinement: function toggleTagRefinement(tag) {\n    if (this.isTagRefined(tag)) {\n      return this.removeTagRefinement(tag);\n    }\n\n    return this.addTagRefinement(tag);\n  },\n  /**\n   * Test if the facet name is from one of the disjunctive facets\n   * @method\n   * @param {string} facet facet name to test\n   * @return {boolean} true if facet is a disjunctive facet\n   */\n  isDisjunctiveFacet: function (facet) {\n    return this.disjunctiveFacets.indexOf(facet) > -1;\n  },\n  /**\n   * Test if the facet name is from one of the hierarchical facets\n   * @method\n   * @param {string} facetName facet name to test\n   * @return {boolean} true if facetName is a hierarchical facet\n   */\n  isHierarchicalFacet: function (facetName) {\n    return this.getHierarchicalFacetByName(facetName) !== undefined;\n  },\n  /**\n   * Test if the facet name is from one of the conjunctive/normal facets\n   * @method\n   * @param {string} facet facet name to test\n   * @return {boolean} true if facet is a conjunctive facet\n   */\n  isConjunctiveFacet: function (facet) {\n    return this.facets.indexOf(facet) > -1;\n  },\n  /**\n   * Returns true if the facet is refined, either for a specific value or in\n   * general.\n   * @method\n   * @param {string} facet name of the attribute for used for faceting\n   * @param {string} value, optional value. If passed will test that this value\n   * is filtering the given facet.\n   * @return {boolean} returns true if refined\n   */\n  isFacetRefined: function isFacetRefined(facet, value) {\n    if (!this.isConjunctiveFacet(facet)) {\n      return false;\n    }\n    return RefinementList.isRefined(this.facetsRefinements, facet, value);\n  },\n  /**\n   * Returns true if the facet contains exclusions or if a specific value is\n   * excluded.\n   *\n   * @method\n   * @param {string} facet name of the attribute for used for faceting\n   * @param {string} [value] optional value. If passed will test that this value\n   * is filtering the given facet.\n   * @return {boolean} returns true if refined\n   */\n  isExcludeRefined: function isExcludeRefined(facet, value) {\n    if (!this.isConjunctiveFacet(facet)) {\n      return false;\n    }\n    return RefinementList.isRefined(this.facetsExcludes, facet, value);\n  },\n  /**\n   * Returns true if the facet contains a refinement, or if a value passed is a\n   * refinement for the facet.\n   * @method\n   * @param {string} facet name of the attribute for used for faceting\n   * @param {string} value optional, will test if the value is used for refinement\n   * if there is one, otherwise will test if the facet contains any refinement\n   * @return {boolean} true if the facet is refined\n   */\n  isDisjunctiveFacetRefined: function isDisjunctiveFacetRefined(facet, value) {\n    if (!this.isDisjunctiveFacet(facet)) {\n      return false;\n    }\n    return RefinementList.isRefined(\n      this.disjunctiveFacetsRefinements,\n      facet,\n      value\n    );\n  },\n  /**\n   * Returns true if the facet contains a refinement, or if a value passed is a\n   * refinement for the facet.\n   * @method\n   * @param {string} facet name of the attribute for used for faceting\n   * @param {string} value optional, will test if the value is used for refinement\n   * if there is one, otherwise will test if the facet contains any refinement\n   * @return {boolean} true if the facet is refined\n   */\n  isHierarchicalFacetRefined: function isHierarchicalFacetRefined(\n    facet,\n    value\n  ) {\n    if (!this.isHierarchicalFacet(facet)) {\n      return false;\n    }\n\n    var refinements = this.getHierarchicalRefinement(facet);\n\n    if (!value) {\n      return refinements.length > 0;\n    }\n\n    return refinements.indexOf(value) !== -1;\n  },\n  /**\n   * Test if the triple (attribute, operator, value) is already refined.\n   * If only the attribute and the operator are provided, it tests if the\n   * contains any refinement value.\n   * @method\n   * @param {string} attribute attribute for which the refinement is applied\n   * @param {string} [operator] operator of the refinement\n   * @param {string} [value] value of the refinement\n   * @return {boolean} true if it is refined\n   */\n  isNumericRefined: function isNumericRefined(attribute, operator, value) {\n    if (value === undefined && operator === undefined) {\n      return Boolean(this.numericRefinements[attribute]);\n    }\n\n    var isOperatorDefined =\n      this.numericRefinements[attribute] &&\n      this.numericRefinements[attribute][operator] !== undefined;\n\n    if (value === undefined || !isOperatorDefined) {\n      return isOperatorDefined;\n    }\n\n    var parsedValue = valToNumber(value);\n    var isAttributeValueDefined =\n      findArray(this.numericRefinements[attribute][operator], parsedValue) !==\n      undefined;\n\n    return isOperatorDefined && isAttributeValueDefined;\n  },\n  /**\n   * Returns true if the tag refined, false otherwise\n   * @method\n   * @param {string} tag the tag to check\n   * @return {boolean} true if tag is refined\n   */\n  isTagRefined: function isTagRefined(tag) {\n    return this.tagRefinements.indexOf(tag) !== -1;\n  },\n  /**\n   * Returns the list of all disjunctive facets refined\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {value} value value used for filtering\n   * @return {string[]} returns the list of refinements\n   */\n  getRefinedDisjunctiveFacets: function getRefinedDisjunctiveFacets() {\n    // eslint-disable-next-line consistent-this\n    var self = this;\n\n    // attributes used for numeric filter can also be disjunctive\n    var disjunctiveNumericRefinedFacets = intersection(\n      Object.keys(this.numericRefinements).filter(function (facet) {\n        return Object.keys(self.numericRefinements[facet]).length > 0;\n      }),\n      this.disjunctiveFacets\n    );\n\n    return Object.keys(this.disjunctiveFacetsRefinements)\n      .filter(function (facet) {\n        return self.disjunctiveFacetsRefinements[facet].length > 0;\n      })\n      .concat(disjunctiveNumericRefinedFacets)\n      .concat(this.getRefinedHierarchicalFacets())\n      .sort();\n  },\n  /**\n   * Returns the list of all disjunctive facets refined\n   * @method\n   * @param {string} facet name of the attribute used for faceting\n   * @param {value} value value used for filtering\n   * @return {string[]} returns the list of refinements\n   */\n  getRefinedHierarchicalFacets: function getRefinedHierarchicalFacets() {\n    // eslint-disable-next-line consistent-this\n    var self = this;\n    return intersection(\n      // enforce the order between the two arrays,\n      // so that refinement name index === hierarchical facet index\n      this.hierarchicalFacets.map(function (facet) {\n        return facet.name;\n      }),\n      Object.keys(this.hierarchicalFacetsRefinements).filter(function (facet) {\n        return self.hierarchicalFacetsRefinements[facet].length > 0;\n      })\n    ).sort();\n  },\n  /**\n   * Returned the list of all disjunctive facets not refined\n   * @method\n   * @return {string[]} returns the list of facets that are not refined\n   */\n  getUnrefinedDisjunctiveFacets: function () {\n    var refinedFacets = this.getRefinedDisjunctiveFacets();\n\n    return this.disjunctiveFacets.filter(function (f) {\n      return refinedFacets.indexOf(f) === -1;\n    });\n  },\n\n  managedParameters: [\n    'index',\n\n    'facets',\n    'disjunctiveFacets',\n    'facetsRefinements',\n    'hierarchicalFacets',\n    'facetsExcludes',\n\n    'disjunctiveFacetsRefinements',\n    'numericRefinements',\n    'tagRefinements',\n    'hierarchicalFacetsRefinements',\n  ],\n\n  getQueryParams: function getQueryParams() {\n    var managedParameters = this.managedParameters;\n\n    var queryParams = {};\n\n    // eslint-disable-next-line consistent-this\n    var self = this;\n    Object.keys(this).forEach(function (paramName) {\n      var paramValue = self[paramName];\n      if (\n        managedParameters.indexOf(paramName) === -1 &&\n        paramValue !== undefined\n      ) {\n        queryParams[paramName] = paramValue;\n      }\n    });\n\n    return queryParams;\n  },\n  /**\n   * Let the user set a specific value for a given parameter. Will return the\n   * same instance if the parameter is invalid or if the value is the same as the\n   * previous one.\n   * @method\n   * @param {string} parameter the parameter name\n   * @param {any} value the value to be set, must be compliant with the definition\n   * of the attribute on the object\n   * @return {SearchParameters} the updated state\n   */\n  setQueryParameter: function setParameter(parameter, value) {\n    if (this[parameter] === value) return this;\n\n    var modification = {};\n\n    modification[parameter] = value;\n\n    return this.setQueryParameters(modification);\n  },\n  /**\n   * Let the user set any of the parameters with a plain object.\n   * @method\n   * @param {object} params all the keys and the values to be updated\n   * @return {SearchParameters} a new updated instance\n   */\n  setQueryParameters: function setQueryParameters(params) {\n    if (!params) return this;\n\n    var error = SearchParameters.validate(this, params);\n\n    if (error) {\n      throw error;\n    }\n\n    // eslint-disable-next-line consistent-this\n    var self = this;\n    var nextWithNumbers = SearchParameters._parseNumbers(params);\n    var previousPlainObject = Object.keys(this).reduce(function (acc, key) {\n      acc[key] = self[key];\n      return acc;\n    }, {});\n\n    var nextPlainObject = Object.keys(nextWithNumbers).reduce(function (\n      previous,\n      key\n    ) {\n      var isPreviousValueDefined = previous[key] !== undefined;\n      var isNextValueDefined = nextWithNumbers[key] !== undefined;\n\n      if (isPreviousValueDefined && !isNextValueDefined) {\n        return omit(previous, [key]);\n      }\n\n      if (isNextValueDefined) {\n        previous[key] = nextWithNumbers[key];\n      }\n\n      return previous;\n    },\n    previousPlainObject);\n\n    return new this.constructor(nextPlainObject);\n  },\n\n  /**\n   * Returns a new instance with the page reset. Two scenarios possible:\n   * the page is omitted -> return the given instance\n   * the page is set -> return a new instance with a page of 0\n   * @return {SearchParameters} a new updated instance\n   */\n  resetPage: function () {\n    if (this.page === undefined) {\n      return this;\n    }\n\n    return this.setPage(0);\n  },\n\n  /**\n   * Helper function to get the hierarchicalFacet separator or the default one (`>`)\n   * @param  {object} hierarchicalFacet the hierarchicalFacet object\n   * @return {string} returns the hierarchicalFacet.separator or `>` as default\n   */\n  _getHierarchicalFacetSortBy: function (hierarchicalFacet) {\n    return hierarchicalFacet.sortBy || ['isRefined:desc', 'name:asc'];\n  },\n\n  /**\n   * Helper function to get the hierarchicalFacet separator or the default one (`>`)\n   * @private\n   * @param  {object} hierarchicalFacet the hierarchicalFacet object\n   * @return {string} returns the hierarchicalFacet.separator or `>` as default\n   */\n  _getHierarchicalFacetSeparator: function (hierarchicalFacet) {\n    return hierarchicalFacet.separator || ' > ';\n  },\n\n  /**\n   * Helper function to get the hierarchicalFacet prefix path or null\n   * @private\n   * @param  {object} hierarchicalFacet the hierarchicalFacet object\n   * @return {string} returns the hierarchicalFacet.rootPath or null as default\n   */\n  _getHierarchicalRootPath: function (hierarchicalFacet) {\n    return hierarchicalFacet.rootPath || null;\n  },\n\n  /**\n   * Helper function to check if we show the parent level of the hierarchicalFacet\n   * @private\n   * @param  {object} hierarchicalFacet the hierarchicalFacet object\n   * @return {string} returns the hierarchicalFacet.showParentLevel or true as default\n   */\n  _getHierarchicalShowParentLevel: function (hierarchicalFacet) {\n    if (typeof hierarchicalFacet.showParentLevel === 'boolean') {\n      return hierarchicalFacet.showParentLevel;\n    }\n    return true;\n  },\n\n  /**\n   * Helper function to get the hierarchicalFacet by it's name\n   * @param  {string} hierarchicalFacetName the hierarchicalFacet name\n   * @return {object} a hierarchicalFacet\n   */\n  getHierarchicalFacetByName: function (hierarchicalFacetName) {\n    return find(this.hierarchicalFacets, function (f) {\n      return f.name === hierarchicalFacetName;\n    });\n  },\n\n  /**\n   * Get the current breadcrumb for a hierarchical facet, as an array\n   * @param  {string} facetName Hierarchical facet name\n   * @return {array.<string>} the path as an array of string\n   */\n  getHierarchicalFacetBreadcrumb: function (facetName) {\n    if (!this.isHierarchicalFacet(facetName)) {\n      return [];\n    }\n\n    var refinement = this.getHierarchicalRefinement(facetName)[0];\n    if (!refinement) return [];\n\n    var separator = this._getHierarchicalFacetSeparator(\n      this.getHierarchicalFacetByName(facetName)\n    );\n    var path = refinement.split(separator);\n    return path.map(function (part) {\n      return part.trim();\n    });\n  },\n\n  toString: function () {\n    return JSON.stringify(this, null, 2);\n  },\n};\n\n/**\n * Callback used for clearRefinement method\n * @callback SearchParameters.clearCallback\n * @param {OperatorList|FacetList} value the value of the filter\n * @param {string} key the current attribute name\n * @param {string} type `numeric`, `disjunctiveFacet`, `conjunctiveFacet`, `hierarchicalFacet` or `exclude`\n * depending on the type of facet\n * @return {boolean} `true` if the element should be removed. `false` otherwise.\n */\nmodule.exports = SearchParameters;\n","'use strict';\n\nmodule.exports = generateTrees;\n\nvar fv = require('../functions/escapeFacetValue');\nvar find = require('../functions/find');\nvar prepareHierarchicalFacetSortBy = require('../functions/formatSort');\nvar orderBy = require('../functions/orderBy');\nvar escapeFacetValue = fv.escapeFacetValue;\nvar unescapeFacetValue = fv.unescapeFacetValue;\n\nfunction generateTrees(state) {\n  return function generate(hierarchicalFacetResult, hierarchicalFacetIndex) {\n    var hierarchicalFacet = state.hierarchicalFacets[hierarchicalFacetIndex];\n    var hierarchicalFacetRefinement =\n      (state.hierarchicalFacetsRefinements[hierarchicalFacet.name] &&\n        state.hierarchicalFacetsRefinements[hierarchicalFacet.name][0]) ||\n      '';\n    var hierarchicalSeparator =\n      state._getHierarchicalFacetSeparator(hierarchicalFacet);\n    var hierarchicalRootPath =\n      state._getHierarchicalRootPath(hierarchicalFacet);\n    var hierarchicalShowParentLevel =\n      state._getHierarchicalShowParentLevel(hierarchicalFacet);\n    var sortBy = prepareHierarchicalFacetSortBy(\n      state._getHierarchicalFacetSortBy(hierarchicalFacet)\n    );\n\n    var rootExhaustive = hierarchicalFacetResult.every(function (facetResult) {\n      return facetResult.exhaustive;\n    });\n\n    var generateTreeFn = generateHierarchicalTree(\n      sortBy,\n      hierarchicalSeparator,\n      hierarchicalRootPath,\n      hierarchicalShowParentLevel,\n      hierarchicalFacetRefinement\n    );\n\n    var results = hierarchicalFacetResult;\n\n    if (hierarchicalRootPath) {\n      results = hierarchicalFacetResult.slice(\n        hierarchicalRootPath.split(hierarchicalSeparator).length\n      );\n    }\n\n    return results.reduce(generateTreeFn, {\n      name: state.hierarchicalFacets[hierarchicalFacetIndex].name,\n      count: null, // root level, no count\n      isRefined: true, // root level, always refined\n      path: null, // root level, no path\n      escapedValue: null,\n      exhaustive: rootExhaustive,\n      data: null,\n    });\n  };\n}\n\nfunction generateHierarchicalTree(\n  sortBy,\n  hierarchicalSeparator,\n  hierarchicalRootPath,\n  hierarchicalShowParentLevel,\n  currentRefinement\n) {\n  return function generateTree(\n    hierarchicalTree,\n    hierarchicalFacetResult,\n    currentHierarchicalLevel\n  ) {\n    var parent = hierarchicalTree;\n\n    if (currentHierarchicalLevel > 0) {\n      var level = 0;\n\n      parent = hierarchicalTree;\n\n      while (level < currentHierarchicalLevel) {\n        /**\n         * @type {object[]]} hierarchical data\n         */\n        var data = parent && Array.isArray(parent.data) ? parent.data : [];\n        parent = find(data, function (subtree) {\n          return subtree.isRefined;\n        });\n        level++;\n      }\n    }\n\n    // we found a refined parent, let's add current level data under it\n    if (parent) {\n      // filter values in case an object has multiple categories:\n      //   {\n      //     categories: {\n      //       level0: ['beers', 'bières'],\n      //       level1: ['beers > IPA', 'bières > Belges']\n      //     }\n      //   }\n      //\n      // If parent refinement is `beers`, then we do not want to have `bières > Belges`\n      // showing up\n\n      var picked = Object.keys(hierarchicalFacetResult.data)\n        .map(function (facetValue) {\n          return [facetValue, hierarchicalFacetResult.data[facetValue]];\n        })\n        .filter(function (tuple) {\n          var facetValue = tuple[0];\n          return onlyMatchingTree(\n            facetValue,\n            parent.path || hierarchicalRootPath,\n            currentRefinement,\n            hierarchicalSeparator,\n            hierarchicalRootPath,\n            hierarchicalShowParentLevel\n          );\n        });\n\n      parent.data = orderBy(\n        picked.map(function (tuple) {\n          var facetValue = tuple[0];\n          var facetCount = tuple[1];\n\n          return format(\n            facetCount,\n            facetValue,\n            hierarchicalSeparator,\n            unescapeFacetValue(currentRefinement),\n            hierarchicalFacetResult.exhaustive\n          );\n        }),\n        sortBy[0],\n        sortBy[1]\n      );\n    }\n\n    return hierarchicalTree;\n  };\n}\n\n// eslint-disable-next-line max-params\nfunction onlyMatchingTree(\n  facetValue,\n  parentPath,\n  currentRefinement,\n  hierarchicalSeparator,\n  hierarchicalRootPath,\n  hierarchicalShowParentLevel\n) {\n  // we want the facetValue is a child of hierarchicalRootPath\n  if (\n    hierarchicalRootPath &&\n    (facetValue.indexOf(hierarchicalRootPath) !== 0 ||\n      hierarchicalRootPath === facetValue)\n  ) {\n    return false;\n  }\n\n  // we always want root levels (only when there is no prefix path)\n  return (\n    (!hierarchicalRootPath &&\n      facetValue.indexOf(hierarchicalSeparator) === -1) ||\n    // if there is a rootPath, being root level mean 1 level under rootPath\n    (hierarchicalRootPath &&\n      facetValue.split(hierarchicalSeparator).length -\n        hierarchicalRootPath.split(hierarchicalSeparator).length ===\n        1) ||\n    // if current refinement is a root level and current facetValue is a root level,\n    // keep the facetValue\n    (facetValue.indexOf(hierarchicalSeparator) === -1 &&\n      currentRefinement.indexOf(hierarchicalSeparator) === -1) ||\n    // currentRefinement is a child of the facet value\n    currentRefinement.indexOf(facetValue) === 0 ||\n    // facetValue is a child of the current parent, add it\n    (facetValue.indexOf(parentPath + hierarchicalSeparator) === 0 &&\n      (hierarchicalShowParentLevel ||\n        facetValue.indexOf(currentRefinement) === 0))\n  );\n}\n\nfunction format(\n  facetCount,\n  facetValue,\n  hierarchicalSeparator,\n  currentRefinement,\n  exhaustive\n) {\n  var parts = facetValue.split(hierarchicalSeparator);\n  return {\n    name: parts[parts.length - 1].trim(),\n    path: facetValue,\n    escapedValue: escapeFacetValue(facetValue),\n    count: facetCount,\n    isRefined:\n      currentRefinement === facetValue ||\n      currentRefinement.indexOf(facetValue + hierarchicalSeparator) === 0,\n    exhaustive: exhaustive,\n    data: null,\n  };\n}\n","'use strict';\n\nvar compact = require('../functions/compact');\nvar defaultsPure = require('../functions/defaultsPure');\nvar fv = require('../functions/escapeFacetValue');\nvar find = require('../functions/find');\nvar findIndex = require('../functions/findIndex');\nvar formatSort = require('../functions/formatSort');\nvar merge = require('../functions/merge');\nvar orderBy = require('../functions/orderBy');\nvar escapeFacetValue = fv.escapeFacetValue;\nvar unescapeFacetValue = fv.unescapeFacetValue;\n\nvar generateHierarchicalTree = require('./generate-hierarchical-tree');\n\n/**\n * @typedef SearchResults.Facet\n * @type {object}\n * @property {string} name name of the attribute in the record\n * @property {object} data the faceting data: value, number of entries\n * @property {object} stats undefined unless facet_stats is retrieved from algolia\n */\n\n/**\n * @typedef SearchResults.HierarchicalFacet\n * @type {object}\n * @property {string} name name of the current value given the hierarchical level, trimmed.\n * If root node, you get the facet name\n * @property {number} count number of objects matching this hierarchical value\n * @property {string} path the current hierarchical value full path\n * @property {boolean} isRefined `true` if the current value was refined, `false` otherwise\n * @property {HierarchicalFacet[]} data sub values for the current level\n */\n\n/**\n * @typedef SearchResults.FacetValue\n * @type {object}\n * @property {string} name the facet value itself\n * @property {number} count times this facet appears in the results\n * @property {boolean} isRefined is the facet currently selected\n * @property {boolean} isExcluded is the facet currently excluded (only for conjunctive facets)\n */\n\n/**\n * @typedef Refinement\n * @type {object}\n * @property {string} type the type of filter used:\n * `numeric`, `facet`, `exclude`, `disjunctive`, `hierarchical`\n * @property {string} attributeName name of the attribute used for filtering\n * @property {string} name the value of the filter\n * @property {number} numericValue the value as a number. Only for numeric filters.\n * @property {string} operator the operator used. Only for numeric filters.\n * @property {number} count the number of computed hits for this filter. Only on facets.\n * @property {boolean} exhaustive if the count is exhaustive\n */\n\n/**\n * Turn an array of attributes in an object of attributes with their position in the array as value\n * @param {string[]} attributes the list of attributes in the record\n * @return {object} the list of attributes indexed by attribute name\n */\nfunction getIndices(attributes) {\n  var indices = {};\n\n  attributes.forEach(function (val, idx) {\n    indices[val] = idx;\n  });\n\n  return indices;\n}\n\nfunction assignFacetStats(dest, facetStats, key) {\n  if (facetStats && facetStats[key]) {\n    dest.stats = facetStats[key];\n  }\n}\n\n/**\n * @typedef {Object} HierarchicalFacet\n * @property {string} name\n * @property {string[]} attributes\n */\n\n/**\n * @param {HierarchicalFacet[]} hierarchicalFacets All hierarchical facets\n * @param {string} hierarchicalAttributeName The name of the hierarchical attribute\n * @return {HierarchicalFacet} The hierarchical facet matching the attribute name\n */\nfunction findMatchingHierarchicalFacetFromAttributeName(\n  hierarchicalFacets,\n  hierarchicalAttributeName\n) {\n  return find(\n    hierarchicalFacets,\n    function facetKeyMatchesAttribute(hierarchicalFacet) {\n      var facetNames = hierarchicalFacet.attributes || [];\n      return facetNames.indexOf(hierarchicalAttributeName) > -1;\n    }\n  );\n}\n\n/**\n * Constructor for SearchResults\n * @class\n * @classdesc SearchResults contains the results of a query to Algolia using the\n * {@link AlgoliaSearchHelper}.\n * @param {SearchParameters} state state that led to the response\n * @param {array.<object>} results the results from algolia client\n * @param {object} options options to control results content\n * @example <caption>SearchResults of the first query in\n * <a href=\"http://demos.algolia.com/instant-search-demo\">the instant search demo</a></caption>\n{\n   \"hitsPerPage\": 10,\n   \"processingTimeMS\": 2,\n   \"facets\": [\n      {\n         \"name\": \"type\",\n         \"data\": {\n            \"HardGood\": 6627,\n            \"BlackTie\": 550,\n            \"Music\": 665,\n            \"Software\": 131,\n            \"Game\": 456,\n            \"Movie\": 1571\n         },\n         \"exhaustive\": false\n      },\n      {\n         \"exhaustive\": false,\n         \"data\": {\n            \"Free shipping\": 5507\n         },\n         \"name\": \"shipping\"\n      }\n  ],\n   \"hits\": [\n      {\n         \"thumbnailImage\": \"http://img.bbystatic.com/BestBuy_US/images/products/1688/1688832_54x108_s.gif\",\n         \"_highlightResult\": {\n            \"shortDescription\": {\n               \"matchLevel\": \"none\",\n               \"value\": \"Safeguard your PC, Mac, Android and iOS devices with comprehensive Internet protection\",\n               \"matchedWords\": []\n            },\n            \"category\": {\n               \"matchLevel\": \"none\",\n               \"value\": \"Computer Security Software\",\n               \"matchedWords\": []\n            },\n            \"manufacturer\": {\n               \"matchedWords\": [],\n               \"value\": \"Webroot\",\n               \"matchLevel\": \"none\"\n            },\n            \"name\": {\n               \"value\": \"Webroot SecureAnywhere Internet Security (3-Device) (1-Year Subscription) - Mac/Windows\",\n               \"matchedWords\": [],\n               \"matchLevel\": \"none\"\n            }\n         },\n         \"image\": \"http://img.bbystatic.com/BestBuy_US/images/products/1688/1688832_105x210_sc.jpg\",\n         \"shipping\": \"Free shipping\",\n         \"bestSellingRank\": 4,\n         \"shortDescription\": \"Safeguard your PC, Mac, Android and iOS devices with comprehensive Internet protection\",\n         \"url\": \"http://www.bestbuy.com/site/webroot-secureanywhere-internet-security-3-devi…d=1219060687969&skuId=1688832&cmp=RMX&ky=2d3GfEmNIzjA0vkzveHdZEBgpPCyMnLTJ\",\n         \"name\": \"Webroot SecureAnywhere Internet Security (3-Device) (1-Year Subscription) - Mac/Windows\",\n         \"category\": \"Computer Security Software\",\n         \"salePrice_range\": \"1 - 50\",\n         \"objectID\": \"1688832\",\n         \"type\": \"Software\",\n         \"customerReviewCount\": 5980,\n         \"salePrice\": 49.99,\n         \"manufacturer\": \"Webroot\"\n      },\n      ....\n  ],\n   \"nbHits\": 10000,\n   \"disjunctiveFacets\": [\n      {\n         \"exhaustive\": false,\n         \"data\": {\n            \"5\": 183,\n            \"12\": 112,\n            \"7\": 149,\n            ...\n         },\n         \"name\": \"customerReviewCount\",\n         \"stats\": {\n            \"max\": 7461,\n            \"avg\": 157.939,\n            \"min\": 1\n         }\n      },\n      {\n         \"data\": {\n            \"Printer Ink\": 142,\n            \"Wireless Speakers\": 60,\n            \"Point & Shoot Cameras\": 48,\n            ...\n         },\n         \"name\": \"category\",\n         \"exhaustive\": false\n      },\n      {\n         \"exhaustive\": false,\n         \"data\": {\n            \"> 5000\": 2,\n            \"1 - 50\": 6524,\n            \"501 - 2000\": 566,\n            \"201 - 500\": 1501,\n            \"101 - 200\": 1360,\n            \"2001 - 5000\": 47\n         },\n         \"name\": \"salePrice_range\"\n      },\n      {\n         \"data\": {\n            \"Dynex™\": 202,\n            \"Insignia™\": 230,\n            \"PNY\": 72,\n            ...\n         },\n         \"name\": \"manufacturer\",\n         \"exhaustive\": false\n      }\n  ],\n   \"query\": \"\",\n   \"nbPages\": 100,\n   \"page\": 0,\n   \"index\": \"bestbuy\"\n}\n **/\nfunction SearchResults(state, results, options) {\n  var mainSubResponse = results[0] || {};\n\n  this._rawResults = results;\n\n  // eslint-disable-next-line consistent-this\n  var self = this;\n\n  // https://www.algolia.com/doc/api-reference/api-methods/search/#response\n  Object.keys(mainSubResponse).forEach(function (key) {\n    self[key] = mainSubResponse[key];\n  });\n\n  // Make every key of the result options reachable from the instance\n  var opts = merge(\n    {\n      persistHierarchicalRootCount: false,\n    },\n    options\n  );\n  Object.keys(opts).forEach(function (key) {\n    self[key] = opts[key];\n  });\n\n  /**\n   * query used to generate the results\n   * @name query\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * The query as parsed by the engine given all the rules.\n   * @name parsedQuery\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * all the records that match the search parameters. Each record is\n   * augmented with a new attribute `_highlightResult`\n   * which is an object keyed by attribute and with the following properties:\n   * - `value` : the value of the facet highlighted (html)\n   * - `matchLevel`: `full`, `partial` or `none`, depending on how the query terms match\n   * @name hits\n   * @member {object[]}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * index where the results come from\n   * @name index\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * number of hits per page requested\n   * @name hitsPerPage\n   * @member {number}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * total number of hits of this query on the index\n   * @name nbHits\n   * @member {number}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * total number of pages with respect to the number of hits per page and the total number of hits\n   * @name nbPages\n   * @member {number}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * current page\n   * @name page\n   * @member {number}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * The position if the position was guessed by IP.\n   * @name aroundLatLng\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   * @example \"48.8637,2.3615\",\n   */\n  /**\n   * The radius computed by Algolia.\n   * @name automaticRadius\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   * @example \"126792922\",\n   */\n  /**\n   * String identifying the server used to serve this request.\n   *\n   * getRankingInfo needs to be set to `true` for this to be returned\n   *\n   * @name serverUsed\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   * @example \"c7-use-2.algolia.net\",\n   */\n  /**\n   * Boolean that indicates if the computation of the counts did time out.\n   * @deprecated\n   * @name timeoutCounts\n   * @member {boolean}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * Boolean that indicates if the computation of the hits did time out.\n   * @deprecated\n   * @name timeoutHits\n   * @member {boolean}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * True if the counts of the facets is exhaustive\n   * @name exhaustiveFacetsCount\n   * @member {boolean}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * True if the number of hits is exhaustive\n   * @name exhaustiveNbHits\n   * @member {boolean}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * Contains the userData if they are set by a [query rule](https://www.algolia.com/doc/guides/query-rules/query-rules-overview/).\n   * @name userData\n   * @member {object[]}\n   * @memberof SearchResults\n   * @instance\n   */\n  /**\n   * queryID is the unique identifier of the query used to generate the current search results.\n   * This value is only available if the `clickAnalytics` search parameter is set to `true`.\n   * @name queryID\n   * @member {string}\n   * @memberof SearchResults\n   * @instance\n   */\n\n  /**\n   * sum of the processing time of all the queries\n   * @name processingTimeMS\n   * @member {number}\n   * @memberof SearchResults\n   * @instance\n   */\n  this.processingTimeMS = results.reduce(function (sum, result) {\n    return result.processingTimeMS === undefined\n      ? sum\n      : sum + result.processingTimeMS;\n  }, 0);\n\n  /**\n   * disjunctive facets results\n   * @member {SearchResults.Facet[]}\n   */\n  this.disjunctiveFacets = [];\n  /**\n   * disjunctive facets results\n   * @member {SearchResults.HierarchicalFacet[]}\n   */\n  this.hierarchicalFacets = state.hierarchicalFacets.map(\n    function initFutureTree() {\n      return [];\n    }\n  );\n  /**\n   * other facets results\n   * @member {SearchResults.Facet[]}\n   */\n  this.facets = [];\n\n  var disjunctiveFacets = state.getRefinedDisjunctiveFacets();\n\n  var facetsIndices = getIndices(state.facets);\n  var disjunctiveFacetsIndices = getIndices(state.disjunctiveFacets);\n  var nextDisjunctiveResult = 1;\n\n  // Since we send request only for disjunctive facets that have been refined,\n  // we get the facets information from the first, general, response.\n\n  var mainFacets = mainSubResponse.facets || {};\n\n  Object.keys(mainFacets).forEach(function (facetKey) {\n    var facetValueObject = mainFacets[facetKey];\n\n    var hierarchicalFacet = findMatchingHierarchicalFacetFromAttributeName(\n      state.hierarchicalFacets,\n      facetKey\n    );\n\n    if (hierarchicalFacet) {\n      // Place the hierarchicalFacet data at the correct index depending on\n      // the attributes order that was defined at the helper initialization\n      var facetIndex = hierarchicalFacet.attributes.indexOf(facetKey);\n      var idxAttributeName = findIndex(state.hierarchicalFacets, function (f) {\n        return f.name === hierarchicalFacet.name;\n      });\n      self.hierarchicalFacets[idxAttributeName][facetIndex] = {\n        attribute: facetKey,\n        data: facetValueObject,\n        exhaustive: mainSubResponse.exhaustiveFacetsCount,\n      };\n    } else {\n      var isFacetDisjunctive = state.disjunctiveFacets.indexOf(facetKey) !== -1;\n      var isFacetConjunctive = state.facets.indexOf(facetKey) !== -1;\n      var position;\n\n      if (isFacetDisjunctive) {\n        position = disjunctiveFacetsIndices[facetKey];\n        self.disjunctiveFacets[position] = {\n          name: facetKey,\n          data: facetValueObject,\n          exhaustive: mainSubResponse.exhaustiveFacetsCount,\n        };\n        assignFacetStats(\n          self.disjunctiveFacets[position],\n          mainSubResponse.facets_stats,\n          facetKey\n        );\n      }\n      if (isFacetConjunctive) {\n        position = facetsIndices[facetKey];\n        self.facets[position] = {\n          name: facetKey,\n          data: facetValueObject,\n          exhaustive: mainSubResponse.exhaustiveFacetsCount,\n        };\n        assignFacetStats(\n          self.facets[position],\n          mainSubResponse.facets_stats,\n          facetKey\n        );\n      }\n    }\n  });\n\n  // Make sure we do not keep holes within the hierarchical facets\n  this.hierarchicalFacets = compact(this.hierarchicalFacets);\n\n  // aggregate the refined disjunctive facets\n  disjunctiveFacets.forEach(function (disjunctiveFacet) {\n    var result = results[nextDisjunctiveResult];\n    var facets = result && result.facets ? result.facets : {};\n    var hierarchicalFacet = state.getHierarchicalFacetByName(disjunctiveFacet);\n\n    // There should be only item in facets.\n    Object.keys(facets).forEach(function (dfacet) {\n      var facetResults = facets[dfacet];\n\n      var position;\n\n      if (hierarchicalFacet) {\n        position = findIndex(state.hierarchicalFacets, function (f) {\n          return f.name === hierarchicalFacet.name;\n        });\n        var attributeIndex = findIndex(\n          self.hierarchicalFacets[position],\n          function (f) {\n            return f.attribute === dfacet;\n          }\n        );\n\n        // previous refinements and no results so not able to find it\n        if (attributeIndex === -1) {\n          return;\n        }\n\n        self.hierarchicalFacets[position][attributeIndex].data = merge(\n          {},\n          self.hierarchicalFacets[position][attributeIndex].data,\n          facetResults\n        );\n      } else {\n        position = disjunctiveFacetsIndices[dfacet];\n\n        var dataFromMainRequest =\n          (mainSubResponse.facets && mainSubResponse.facets[dfacet]) || {};\n\n        self.disjunctiveFacets[position] = {\n          name: dfacet,\n          data: defaultsPure({}, facetResults, dataFromMainRequest),\n          exhaustive: result.exhaustiveFacetsCount,\n        };\n        assignFacetStats(\n          self.disjunctiveFacets[position],\n          result.facets_stats,\n          dfacet\n        );\n\n        if (state.disjunctiveFacetsRefinements[dfacet]) {\n          state.disjunctiveFacetsRefinements[dfacet].forEach(function (\n            refinementValue\n          ) {\n            // add the disjunctive refinements if it is no more retrieved\n            if (\n              !self.disjunctiveFacets[position].data[refinementValue] &&\n              state.disjunctiveFacetsRefinements[dfacet].indexOf(\n                unescapeFacetValue(refinementValue)\n              ) > -1\n            ) {\n              self.disjunctiveFacets[position].data[refinementValue] = 0;\n            }\n          });\n        }\n      }\n    });\n    nextDisjunctiveResult++;\n  });\n\n  // if we have some parent level values for hierarchical facets, merge them\n  state.getRefinedHierarchicalFacets().forEach(function (refinedFacet) {\n    var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);\n    var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n\n    var currentRefinement = state.getHierarchicalRefinement(refinedFacet);\n    // if we are already at a root refinement (or no refinement at all), there is no\n    // root level values request\n    if (\n      currentRefinement.length === 0 ||\n      currentRefinement[0].split(separator).length < 2\n    ) {\n      return;\n    }\n\n    results.slice(nextDisjunctiveResult).forEach(function (result) {\n      var facets = result && result.facets ? result.facets : {};\n\n      Object.keys(facets).forEach(function (dfacet) {\n        var facetResults = facets[dfacet];\n        var position = findIndex(state.hierarchicalFacets, function (f) {\n          return f.name === hierarchicalFacet.name;\n        });\n        var attributeIndex = findIndex(\n          self.hierarchicalFacets[position],\n          function (f) {\n            return f.attribute === dfacet;\n          }\n        );\n\n        // previous refinements and no results so not able to find it\n        if (attributeIndex === -1) {\n          return;\n        }\n\n        // when we always get root levels, if the hits refinement is `beers > IPA` (count: 5),\n        // then the disjunctive values will be `beers` (count: 100),\n        // but we do not want to display\n        //   | beers (100)\n        //     > IPA (5)\n        // We want\n        //   | beers (5)\n        //     > IPA (5)\n        // @MAJOR: remove this legacy behaviour in next major version\n        var defaultData = {};\n\n        if (\n          currentRefinement.length > 0 &&\n          !self.persistHierarchicalRootCount\n        ) {\n          var root = currentRefinement[0].split(separator)[0];\n          defaultData[root] =\n            self.hierarchicalFacets[position][attributeIndex].data[root];\n        }\n\n        self.hierarchicalFacets[position][attributeIndex].data = defaultsPure(\n          defaultData,\n          facetResults,\n          self.hierarchicalFacets[position][attributeIndex].data\n        );\n      });\n\n      nextDisjunctiveResult++;\n    });\n  });\n\n  // add the excludes\n  Object.keys(state.facetsExcludes).forEach(function (facetName) {\n    var excludes = state.facetsExcludes[facetName];\n    var position = facetsIndices[facetName];\n\n    self.facets[position] = {\n      name: facetName,\n      data: mainFacets[facetName],\n      exhaustive: mainSubResponse.exhaustiveFacetsCount,\n    };\n    excludes.forEach(function (facetValue) {\n      self.facets[position] = self.facets[position] || { name: facetName };\n      self.facets[position].data = self.facets[position].data || {};\n      self.facets[position].data[facetValue] = 0;\n    });\n  });\n\n  /**\n   * @type {Array}\n   */\n  this.hierarchicalFacets = this.hierarchicalFacets.map(\n    generateHierarchicalTree(state)\n  );\n\n  /**\n   * @type {Array}\n   */\n  this.facets = compact(this.facets);\n  /**\n   * @type {Array}\n   */\n  this.disjunctiveFacets = compact(this.disjunctiveFacets);\n\n  this._state = state;\n}\n\n/**\n * Get a facet object with its name\n * @deprecated\n * @param {string} name name of the faceted attribute\n * @return {SearchResults.Facet} the facet object\n */\nSearchResults.prototype.getFacetByName = function (name) {\n  function predicate(facet) {\n    return facet.name === name;\n  }\n\n  return (\n    find(this.facets, predicate) ||\n    find(this.disjunctiveFacets, predicate) ||\n    find(this.hierarchicalFacets, predicate)\n  );\n};\n\n/**\n * Get the facet values of a specified attribute from a SearchResults object.\n * @private\n * @param {SearchResults} results the search results to search in\n * @param {string} attribute name of the faceted attribute to search for\n * @return {array|object} facet values. For the hierarchical facets it is an object.\n */\nfunction extractNormalizedFacetValues(results, attribute) {\n  function predicate(facet) {\n    return facet.name === attribute;\n  }\n\n  if (results._state.isConjunctiveFacet(attribute)) {\n    var facet = find(results.facets, predicate);\n    if (!facet) return [];\n\n    return Object.keys(facet.data).map(function (name) {\n      var value = escapeFacetValue(name);\n      return {\n        name: name,\n        escapedValue: value,\n        count: facet.data[name],\n        isRefined: results._state.isFacetRefined(attribute, value),\n        isExcluded: results._state.isExcludeRefined(attribute, name),\n      };\n    });\n  } else if (results._state.isDisjunctiveFacet(attribute)) {\n    var disjunctiveFacet = find(results.disjunctiveFacets, predicate);\n    if (!disjunctiveFacet) return [];\n\n    return Object.keys(disjunctiveFacet.data).map(function (name) {\n      var value = escapeFacetValue(name);\n      return {\n        name: name,\n        escapedValue: value,\n        count: disjunctiveFacet.data[name],\n        isRefined: results._state.isDisjunctiveFacetRefined(attribute, value),\n      };\n    });\n  } else if (results._state.isHierarchicalFacet(attribute)) {\n    var hierarchicalFacetValues = find(results.hierarchicalFacets, predicate);\n    if (!hierarchicalFacetValues) return hierarchicalFacetValues;\n\n    var hierarchicalFacet =\n      results._state.getHierarchicalFacetByName(attribute);\n    var separator =\n      results._state._getHierarchicalFacetSeparator(hierarchicalFacet);\n    var currentRefinement = unescapeFacetValue(\n      results._state.getHierarchicalRefinement(attribute)[0] || ''\n    );\n\n    if (currentRefinement.indexOf(hierarchicalFacet.rootPath) === 0) {\n      currentRefinement = currentRefinement.replace(\n        hierarchicalFacet.rootPath + separator,\n        ''\n      );\n    }\n\n    var currentRefinementSplit = currentRefinement.split(separator);\n    currentRefinementSplit.unshift(attribute);\n\n    setIsRefined(hierarchicalFacetValues, currentRefinementSplit, 0);\n\n    return hierarchicalFacetValues;\n  }\n\n  return undefined;\n}\n\n/**\n * Set the isRefined of a hierarchical facet result based on the current state.\n * @param {SearchResults.HierarchicalFacet} item Hierarchical facet to fix\n * @param {string[]} currentRefinement array of parts of the current hierarchical refinement\n * @param {number} depth recursion depth in the currentRefinement\n * @return {undefined} function mutates the item\n */\nfunction setIsRefined(item, currentRefinement, depth) {\n  item.isRefined =\n    item.name === (currentRefinement[depth] && currentRefinement[depth].trim());\n  if (item.data) {\n    item.data.forEach(function (child) {\n      setIsRefined(child, currentRefinement, depth + 1);\n    });\n  }\n}\n\n/**\n * Sort nodes of a hierarchical or disjunctive facet results\n * @private\n * @param {function} sortFn sort function to apply\n * @param {HierarchicalFacet|Array} node node upon which we want to apply the sort\n * @param {string[]} names attribute names\n * @param {number} [level=0] current index in the names array\n * @return {HierarchicalFacet|Array} sorted node\n */\nfunction recSort(sortFn, node, names, level) {\n  level = level || 0;\n\n  if (Array.isArray(node)) {\n    return sortFn(node, names[level]);\n  }\n\n  if (!node.data || node.data.length === 0) {\n    return node;\n  }\n\n  var children = node.data.map(function (childNode) {\n    return recSort(sortFn, childNode, names, level + 1);\n  });\n  var sortedChildren = sortFn(children, names[level]);\n  var newNode = defaultsPure({ data: sortedChildren }, node);\n  return newNode;\n}\n\nSearchResults.DEFAULT_SORT = ['isRefined:desc', 'count:desc', 'name:asc'];\n\nfunction vanillaSortFn(order, data) {\n  return data.sort(order);\n}\n\n/**\n * @typedef FacetOrdering\n * @type {Object}\n * @property {string[]} [order]\n * @property {'count' | 'alpha' | 'hidden'} [sortRemainingBy]\n */\n\n/**\n * Sorts facet arrays via their facet ordering\n * @param {Array} facetValues the values\n * @param {FacetOrdering} facetOrdering the ordering\n * @returns {Array} the sorted facet values\n */\nfunction sortViaFacetOrdering(facetValues, facetOrdering) {\n  var orderedFacets = [];\n  var remainingFacets = [];\n  var hide = facetOrdering.hide || [];\n  var order = facetOrdering.order || [];\n\n  /**\n   * an object with the keys being the values in order, the values their index:\n   * ['one', 'two'] -> { one: 0, two: 1 }\n   */\n  var reverseOrder = order.reduce(function (acc, name, i) {\n    acc[name] = i;\n    return acc;\n  }, {});\n\n  facetValues.forEach(function (item) {\n    // hierarchical facets get sorted using their raw name\n    var name = item.path || item.name;\n    var hidden = hide.indexOf(name) > -1;\n    if (!hidden && reverseOrder[name] !== undefined) {\n      orderedFacets[reverseOrder[name]] = item;\n    } else if (!hidden) {\n      remainingFacets.push(item);\n    }\n  });\n\n  orderedFacets = orderedFacets.filter(function (facet) {\n    return facet;\n  });\n\n  var sortRemainingBy = facetOrdering.sortRemainingBy;\n  var ordering;\n  if (sortRemainingBy === 'hidden') {\n    return orderedFacets;\n  } else if (sortRemainingBy === 'alpha') {\n    ordering = [\n      ['path', 'name'],\n      ['asc', 'asc'],\n    ];\n  } else {\n    ordering = [['count'], ['desc']];\n  }\n\n  return orderedFacets.concat(\n    orderBy(remainingFacets, ordering[0], ordering[1])\n  );\n}\n\n/**\n * @param {SearchResults} results the search results class\n * @param {string} attribute the attribute to retrieve ordering of\n * @returns {FacetOrdering | undefined} the facet ordering\n */\nfunction getFacetOrdering(results, attribute) {\n  return (\n    results.renderingContent &&\n    results.renderingContent.facetOrdering &&\n    results.renderingContent.facetOrdering.values &&\n    results.renderingContent.facetOrdering.values[attribute]\n  );\n}\n\n/**\n * Get a the list of values for a given facet attribute. Those values are sorted\n * refinement first, descending count (bigger value on top), and name ascending\n * (alphabetical order). The sort formula can overridden using either string based\n * predicates or a function.\n *\n * This method will return all the values returned by the Algolia engine plus all\n * the values already refined. This means that it can happen that the\n * `maxValuesPerFacet` [configuration](https://www.algolia.com/doc/rest-api/search#param-maxValuesPerFacet)\n * might not be respected if you have facet values that are already refined.\n * @param {string} attribute attribute name\n * @param {object} opts configuration options.\n * @param {boolean} [opts.facetOrdering]\n * Force the use of facetOrdering from the result if a sortBy is present. If\n * sortBy isn't present, facetOrdering will be used automatically.\n * @param {Array.<string> | function} opts.sortBy\n * When using strings, it consists of\n * the name of the [FacetValue](#SearchResults.FacetValue) or the\n * [HierarchicalFacet](#SearchResults.HierarchicalFacet) attributes with the\n * order (`asc` or `desc`). For example to order the value by count, the\n * argument would be `['count:asc']`.\n *\n * If only the attribute name is specified, the ordering defaults to the one\n * specified in the default value for this attribute.\n *\n * When not specified, the order is\n * ascending.  This parameter can also be a function which takes two facet\n * values and should return a number, 0 if equal, 1 if the first argument is\n * bigger or -1 otherwise.\n *\n * The default value for this attribute `['isRefined:desc', 'count:desc', 'name:asc']`\n * @return {FacetValue[]|HierarchicalFacet|undefined} depending on the type of facet of\n * the attribute requested (hierarchical, disjunctive or conjunctive)\n * @example\n * helper.on('result', function(event){\n *   //get values ordered only by name ascending using the string predicate\n *   event.results.getFacetValues('city', {sortBy: ['name:asc']});\n *   //get values  ordered only by count ascending using a function\n *   event.results.getFacetValues('city', {\n *     // this is equivalent to ['count:asc']\n *     sortBy: function(a, b) {\n *       if (a.count === b.count) return 0;\n *       if (a.count > b.count)   return 1;\n *       if (b.count > a.count)   return -1;\n *     }\n *   });\n * });\n */\nSearchResults.prototype.getFacetValues = function (attribute, opts) {\n  var facetValues = extractNormalizedFacetValues(this, attribute);\n  if (!facetValues) {\n    return undefined;\n  }\n\n  var options = defaultsPure({}, opts, {\n    sortBy: SearchResults.DEFAULT_SORT,\n    // if no sortBy is given, attempt to sort based on facetOrdering\n    // if it is given, we still allow to sort via facet ordering first\n    facetOrdering: !(opts && opts.sortBy),\n  });\n\n  // eslint-disable-next-line consistent-this\n  var results = this;\n  var attributes;\n  if (Array.isArray(facetValues)) {\n    attributes = [attribute];\n  } else {\n    var config = results._state.getHierarchicalFacetByName(facetValues.name);\n    attributes = config.attributes;\n  }\n\n  return recSort(\n    function (data, facetName) {\n      if (options.facetOrdering) {\n        var facetOrdering = getFacetOrdering(results, facetName);\n        if (facetOrdering) {\n          return sortViaFacetOrdering(data, facetOrdering);\n        }\n      }\n\n      if (Array.isArray(options.sortBy)) {\n        var order = formatSort(options.sortBy, SearchResults.DEFAULT_SORT);\n        return orderBy(data, order[0], order[1]);\n      } else if (typeof options.sortBy === 'function') {\n        return vanillaSortFn(options.sortBy, data);\n      }\n      throw new Error(\n        'options.sortBy is optional but if defined it must be ' +\n          'either an array of string (predicates) or a sorting function'\n      );\n    },\n    facetValues,\n    attributes\n  );\n};\n\n/**\n * Returns the facet stats if attribute is defined and the facet contains some.\n * Otherwise returns undefined.\n * @param {string} attribute name of the faceted attribute\n * @return {object} The stats of the facet\n */\nSearchResults.prototype.getFacetStats = function (attribute) {\n  if (this._state.isConjunctiveFacet(attribute)) {\n    return getFacetStatsIfAvailable(this.facets, attribute);\n  } else if (this._state.isDisjunctiveFacet(attribute)) {\n    return getFacetStatsIfAvailable(this.disjunctiveFacets, attribute);\n  }\n\n  return undefined;\n};\n\n/**\n * @typedef {Object} FacetListItem\n * @property {string} name\n */\n\n/**\n * @param {FacetListItem[]} facetList (has more items, but enough for here)\n * @param {string} facetName The attribute to look for\n * @return {object|undefined} The stats of the facet\n */\nfunction getFacetStatsIfAvailable(facetList, facetName) {\n  var data = find(facetList, function (facet) {\n    return facet.name === facetName;\n  });\n  return data && data.stats;\n}\n\n/**\n * Returns all refinements for all filters + tags. It also provides\n * additional information: count and exhaustiveness for each filter.\n *\n * See the [refinement type](#Refinement) for an exhaustive view of the available\n * data.\n *\n * Note that for a numeric refinement, results are grouped per operator, this\n * means that it will return responses for operators which are empty.\n *\n * @return {Array.<Refinement>} all the refinements\n */\nSearchResults.prototype.getRefinements = function () {\n  var state = this._state;\n  // eslint-disable-next-line consistent-this\n  var results = this;\n  var res = [];\n\n  Object.keys(state.facetsRefinements).forEach(function (attributeName) {\n    state.facetsRefinements[attributeName].forEach(function (name) {\n      res.push(\n        getRefinement(state, 'facet', attributeName, name, results.facets)\n      );\n    });\n  });\n\n  Object.keys(state.facetsExcludes).forEach(function (attributeName) {\n    state.facetsExcludes[attributeName].forEach(function (name) {\n      res.push(\n        getRefinement(state, 'exclude', attributeName, name, results.facets)\n      );\n    });\n  });\n\n  Object.keys(state.disjunctiveFacetsRefinements).forEach(function (\n    attributeName\n  ) {\n    state.disjunctiveFacetsRefinements[attributeName].forEach(function (name) {\n      res.push(\n        getRefinement(\n          state,\n          'disjunctive',\n          attributeName,\n          name,\n          results.disjunctiveFacets\n        )\n      );\n    });\n  });\n\n  Object.keys(state.hierarchicalFacetsRefinements).forEach(function (\n    attributeName\n  ) {\n    state.hierarchicalFacetsRefinements[attributeName].forEach(function (name) {\n      res.push(\n        getHierarchicalRefinement(\n          state,\n          attributeName,\n          name,\n          results.hierarchicalFacets\n        )\n      );\n    });\n  });\n\n  Object.keys(state.numericRefinements).forEach(function (attributeName) {\n    var operators = state.numericRefinements[attributeName];\n    Object.keys(operators).forEach(function (operator) {\n      operators[operator].forEach(function (value) {\n        res.push({\n          type: 'numeric',\n          attributeName: attributeName,\n          name: value,\n          numericValue: value,\n          operator: operator,\n        });\n      });\n    });\n  });\n\n  state.tagRefinements.forEach(function (name) {\n    res.push({ type: 'tag', attributeName: '_tags', name: name });\n  });\n\n  return res;\n};\n\n/**\n * @typedef {Object} Facet\n * @property {string} name\n * @property {Object} data\n * @property {boolean} exhaustive\n */\n\n/**\n * @param {SearchParameters} state the current state\n * @param {string} type the type of the refinement\n * @param {string} attributeName The attribute of the facet\n * @param {*} name The name of the facet\n * @param {Facet[]} resultsFacets facets from the results\n * @return {Refinement} the refinement\n */\nfunction getRefinement(state, type, attributeName, name, resultsFacets) {\n  var facet = find(resultsFacets, function (f) {\n    return f.name === attributeName;\n  });\n  var count = facet && facet.data && facet.data[name] ? facet.data[name] : 0;\n  var exhaustive = (facet && facet.exhaustive) || false;\n\n  return {\n    type: type,\n    attributeName: attributeName,\n    name: name,\n    count: count,\n    exhaustive: exhaustive,\n  };\n}\n\n/**\n * @param {SearchParameters} state the current state\n * @param {string} attributeName the attribute of the hierarchical facet\n * @param {string} name the name of the facet\n * @param {Facet[]} resultsFacets facets from the results\n * @return {HierarchicalFacet} the hierarchical facet\n */\nfunction getHierarchicalRefinement(state, attributeName, name, resultsFacets) {\n  var facetDeclaration = state.getHierarchicalFacetByName(attributeName);\n  var separator = state._getHierarchicalFacetSeparator(facetDeclaration);\n  var split = name.split(separator);\n  var rootFacet = find(resultsFacets, function (facet) {\n    return facet.name === attributeName;\n  });\n\n  var facet = split.reduce(function (intermediateFacet, part) {\n    var newFacet =\n      intermediateFacet &&\n      find(intermediateFacet.data, function (f) {\n        return f.name === part;\n      });\n    return newFacet !== undefined ? newFacet : intermediateFacet;\n  }, rootFacet);\n\n  var count = (facet && facet.count) || 0;\n  var exhaustive = (facet && facet.exhaustive) || false;\n  var path = (facet && facet.path) || '';\n\n  return {\n    type: 'hierarchical',\n    attributeName: attributeName,\n    name: path,\n    count: count,\n    exhaustive: exhaustive,\n  };\n}\n\nmodule.exports = SearchResults;\n","'use strict';\n\nvar EventEmitter = require('@algolia/events');\n\nvar DerivedHelper = require('./DerivedHelper');\nvar escapeFacetValue = require('./functions/escapeFacetValue').escapeFacetValue;\nvar inherits = require('./functions/inherits');\nvar merge = require('./functions/merge');\nvar objectHasKeys = require('./functions/objectHasKeys');\nvar omit = require('./functions/omit');\nvar RecommendParameters = require('./RecommendParameters');\nvar RecommendResults = require('./RecommendResults');\nvar requestBuilder = require('./requestBuilder');\nvar SearchParameters = require('./SearchParameters');\nvar SearchResults = require('./SearchResults');\nvar sortAndMergeRecommendations = require('./utils/sortAndMergeRecommendations');\nvar version = require('./version');\n\n/**\n * Event triggered when a parameter is set or updated\n * @event AlgoliaSearchHelper#event:change\n * @property {object} event\n * @property {SearchParameters} event.state the current parameters with the latest changes applied\n * @property {SearchResults} event.results the previous results received from Algolia. `null` before the first request\n * @example\n * helper.on('change', function(event) {\n *   console.log('The parameters have changed');\n * });\n */\n\n/**\n * Event triggered when a main search is sent to Algolia\n * @event AlgoliaSearchHelper#event:search\n * @property {object} event\n * @property {SearchParameters} event.state the parameters used for this search\n * @property {SearchResults} event.results the results from the previous search. `null` if it is the first search.\n * @example\n * helper.on('search', function(event) {\n *   console.log('Search sent');\n * });\n */\n\n/**\n * Event triggered when a search using `searchForFacetValues` is sent to Algolia\n * @event AlgoliaSearchHelper#event:searchForFacetValues\n * @property {object} event\n * @property {SearchParameters} event.state the parameters used for this search it is the first search.\n * @property {string} event.facet the facet searched into\n * @property {string} event.query the query used to search in the facets\n * @example\n * helper.on('searchForFacetValues', function(event) {\n *   console.log('searchForFacetValues sent');\n * });\n */\n\n/**\n * Event triggered when a search using `searchOnce` is sent to Algolia\n * @event AlgoliaSearchHelper#event:searchOnce\n * @property {object} event\n * @property {SearchParameters} event.state the parameters used for this search it is the first search.\n * @example\n * helper.on('searchOnce', function(event) {\n *   console.log('searchOnce sent');\n * });\n */\n\n/**\n * Event triggered when the results are retrieved from Algolia\n * @event AlgoliaSearchHelper#event:result\n * @property {object} event\n * @property {SearchResults} event.results the results received from Algolia\n * @property {SearchParameters} event.state the parameters used to query Algolia. Those might be different from the one in the helper instance (for example if the network is unreliable).\n * @example\n * helper.on('result', function(event) {\n *   console.log('Search results received');\n * });\n */\n\n/**\n * Event triggered when Algolia sends back an error. For example, if an unknown parameter is\n * used, the error can be caught using this event.\n * @event AlgoliaSearchHelper#event:error\n * @property {object} event\n * @property {Error} event.error the error returned by the Algolia.\n * @example\n * helper.on('error', function(event) {\n *   console.log('Houston we got a problem.');\n * });\n */\n\n/**\n * Event triggered when the queue of queries have been depleted (with any result or outdated queries)\n * @event AlgoliaSearchHelper#event:searchQueueEmpty\n * @example\n * helper.on('searchQueueEmpty', function() {\n *   console.log('No more search pending');\n *   // This is received before the result event if we're not expecting new results\n * });\n *\n * helper.search();\n */\n\n/**\n * Initialize a new AlgoliaSearchHelper\n * @class\n * @classdesc The AlgoliaSearchHelper is a class that ease the management of the\n * search. It provides an event based interface for search callbacks:\n *  - change: when the internal search state is changed.\n *    This event contains a {@link SearchParameters} object and the\n *    {@link SearchResults} of the last result if any.\n *  - search: when a search is triggered using the `search()` method.\n *  - result: when the response is retrieved from Algolia and is processed.\n *    This event contains a {@link SearchResults} object and the\n *    {@link SearchParameters} corresponding to this answer.\n *  - error: when the response is an error. This event contains the error returned by the server.\n * @param  {AlgoliaSearch} client an AlgoliaSearch client\n * @param  {string} index the index name to query\n * @param  {SearchParameters | object} options an object defining the initial\n * config of the search. It doesn't have to be a {SearchParameters},\n * just an object containing the properties you need from it.\n * @param {SearchResultsOptions|object} searchResultsOptions an object defining the options to use when creating the search results.\n */\nfunction AlgoliaSearchHelper(client, index, options, searchResultsOptions) {\n  if (typeof client.addAlgoliaAgent === 'function') {\n    client.addAlgoliaAgent('JS Helper (' + version + ')');\n  }\n\n  this.setClient(client);\n  var opts = options || {};\n  opts.index = index;\n  this.state = SearchParameters.make(opts);\n  this.recommendState = new RecommendParameters({\n    params: opts.recommendState,\n  });\n  this.lastResults = null;\n  this.lastRecommendResults = null;\n  this._queryId = 0;\n  this._recommendQueryId = 0;\n  this._lastQueryIdReceived = -1;\n  this._lastRecommendQueryIdReceived = -1;\n  this.derivedHelpers = [];\n  this._currentNbQueries = 0;\n  this._currentNbRecommendQueries = 0;\n  this._searchResultsOptions = searchResultsOptions;\n  this._recommendCache = {};\n}\n\ninherits(AlgoliaSearchHelper, EventEmitter);\n\n/**\n * Start the search with the parameters set in the state. When the\n * method is called, it triggers a `search` event. The results will\n * be available through the `result` event. If an error occurs, an\n * `error` will be fired instead.\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires search\n * @fires result\n * @fires error\n * @chainable\n */\nAlgoliaSearchHelper.prototype.search = function () {\n  this._search({ onlyWithDerivedHelpers: false });\n  return this;\n};\n\nAlgoliaSearchHelper.prototype.searchOnlyWithDerivedHelpers = function () {\n  this._search({ onlyWithDerivedHelpers: true });\n  return this;\n};\n\n/**\n * Sends the recommendation queries set in the state. When the method is\n * called, it triggers a `fetch` event. The results will be available through\n * the `result` event. If an error occurs, an `error` will be fired instead.\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires fetch\n * @fires result\n * @fires error\n * @chainable\n */\nAlgoliaSearchHelper.prototype.recommend = function () {\n  this._recommend();\n  return this;\n};\n\n/**\n * Gets the search query parameters that would be sent to the Algolia Client\n * for the hits\n * @return {object} Query Parameters\n */\nAlgoliaSearchHelper.prototype.getQuery = function () {\n  var state = this.state;\n  return requestBuilder._getHitsSearchParams(state);\n};\n\n/**\n * Start a search using a modified version of the current state. This method does\n * not trigger the helper lifecycle and does not modify the state kept internally\n * by the helper. This second aspect means that the next search call will be the\n * same as a search call before calling searchOnce.\n * @param {object} options can contain all the parameters that can be set to SearchParameters\n * plus the index\n * @param {function} [cb] optional callback executed when the response from the\n * server is back.\n * @return {promise|undefined} if a callback is passed the method returns undefined\n * otherwise it returns a promise containing an object with two keys :\n *  - content with a SearchResults\n *  - state with the state used for the query as a SearchParameters\n * @example\n * // Changing the number of records returned per page to 1\n * // This example uses the callback API\n * var state = helper.searchOnce({hitsPerPage: 1},\n *   function(error, content, state) {\n *     // if an error occurred it will be passed in error, otherwise its value is null\n *     // content contains the results formatted as a SearchResults\n *     // state is the instance of SearchParameters used for this search\n *   });\n * @example\n * // Changing the number of records returned per page to 1\n * // This example uses the promise API\n * var state1 = helper.searchOnce({hitsPerPage: 1})\n *                 .then(promiseHandler);\n *\n * function promiseHandler(res) {\n *   // res contains\n *   // {\n *   //   content : SearchResults\n *   //   state   : SearchParameters (the one used for this specific search)\n *   // }\n * }\n */\nAlgoliaSearchHelper.prototype.searchOnce = function (options, cb) {\n  var tempState = !options\n    ? this.state\n    : this.state.setQueryParameters(options);\n  var queries = requestBuilder._getQueries(tempState.index, tempState);\n  // eslint-disable-next-line consistent-this\n  var self = this;\n\n  this._currentNbQueries++;\n\n  this.emit('searchOnce', {\n    state: tempState,\n  });\n\n  if (cb) {\n    this.client\n      .search(queries)\n      .then(function (content) {\n        self._currentNbQueries--;\n        if (self._currentNbQueries === 0) {\n          self.emit('searchQueueEmpty');\n        }\n\n        cb(null, new SearchResults(tempState, content.results), tempState);\n      })\n      .catch(function (err) {\n        self._currentNbQueries--;\n        if (self._currentNbQueries === 0) {\n          self.emit('searchQueueEmpty');\n        }\n\n        cb(err, null, tempState);\n      });\n\n    return undefined;\n  }\n\n  return this.client.search(queries).then(\n    function (content) {\n      self._currentNbQueries--;\n      if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n      return {\n        content: new SearchResults(tempState, content.results),\n        state: tempState,\n        _originalResponse: content,\n      };\n    },\n    function (e) {\n      self._currentNbQueries--;\n      if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n      throw e;\n    }\n  );\n};\n\n/**\n * Start the search for answers with the parameters set in the state.\n * This method returns a promise.\n * @param {Object} options - the options for answers API call\n * @param {string[]} options.attributesForPrediction - Attributes to use for predictions. If empty, `searchableAttributes` is used instead.\n * @param {string[]} options.queryLanguages - The languages in the query. Currently only supports ['en'].\n * @param {number} options.nbHits - Maximum number of answers to retrieve from the Answers Engine. Cannot be greater than 1000.\n *\n * @return {promise} the answer results\n * @deprecated answers is deprecated and will be replaced with new initiatives\n */\nAlgoliaSearchHelper.prototype.findAnswers = function (options) {\n  // eslint-disable-next-line no-console\n  console.warn('[algoliasearch-helper] answers is no longer supported');\n  var state = this.state;\n  var derivedHelper = this.derivedHelpers[0];\n  if (!derivedHelper) {\n    return Promise.resolve([]);\n  }\n  var derivedState = derivedHelper.getModifiedState(state);\n  var data = merge(\n    {\n      attributesForPrediction: options.attributesForPrediction,\n      nbHits: options.nbHits,\n    },\n    {\n      params: omit(requestBuilder._getHitsSearchParams(derivedState), [\n        'attributesToSnippet',\n        'hitsPerPage',\n        'restrictSearchableAttributes',\n        'snippetEllipsisText',\n      ]),\n    }\n  );\n\n  var errorMessage =\n    'search for answers was called, but this client does not have a function client.initIndex(index).findAnswers';\n  if (typeof this.client.initIndex !== 'function') {\n    throw new Error(errorMessage);\n  }\n  var index = this.client.initIndex(derivedState.index);\n  if (typeof index.findAnswers !== 'function') {\n    throw new Error(errorMessage);\n  }\n  return index.findAnswers(derivedState.query, options.queryLanguages, data);\n};\n\n/**\n * Structure of each result when using\n * [`searchForFacetValues()`](reference.html#AlgoliaSearchHelper#searchForFacetValues)\n * @typedef FacetSearchHit\n * @type {object}\n * @property {string} value the facet value\n * @property {string} highlighted the facet value highlighted with the query string\n * @property {number} count number of occurrence of this facet value\n * @property {boolean} isRefined true if the value is already refined\n */\n\n/**\n * Structure of the data resolved by the\n * [`searchForFacetValues()`](reference.html#AlgoliaSearchHelper#searchForFacetValues)\n * promise.\n * @typedef FacetSearchResult\n * @type {object}\n * @property {FacetSearchHit} facetHits the results for this search for facet values\n * @property {number} processingTimeMS time taken by the query inside the engine\n */\n\n/**\n * Search for facet values based on an query and the name of a faceted attribute. This\n * triggers a search and will return a promise. On top of using the query, it also sends\n * the parameters from the state so that the search is narrowed down to only the possible values.\n *\n * See the description of [FacetSearchResult](reference.html#FacetSearchResult)\n * @param {string} facet the name of the faceted attribute\n * @param {string} query the string query for the search\n * @param {number} [maxFacetHits] the maximum number values returned. Should be > 0 and <= 100\n * @param {object} [userState] the set of custom parameters to use on top of the current state. Setting a property to `undefined` removes\n * it in the generated query.\n * @return {promise.<FacetSearchResult>} the results of the search\n */\nAlgoliaSearchHelper.prototype.searchForFacetValues = function (\n  facet,\n  query,\n  maxFacetHits,\n  userState\n) {\n  var clientHasSFFV = typeof this.client.searchForFacetValues === 'function';\n  var clientHasInitIndex = typeof this.client.initIndex === 'function';\n  if (\n    !clientHasSFFV &&\n    !clientHasInitIndex &&\n    typeof this.client.search !== 'function'\n  ) {\n    throw new Error(\n      'search for facet values (searchable) was called, but this client does not have a function client.searchForFacetValues or client.initIndex(index).searchForFacetValues'\n    );\n  }\n\n  var state = this.state.setQueryParameters(userState || {});\n  var isDisjunctive = state.isDisjunctiveFacet(facet);\n  var algoliaQuery = requestBuilder.getSearchForFacetQuery(\n    facet,\n    query,\n    maxFacetHits,\n    state\n  );\n\n  this._currentNbQueries++;\n  // eslint-disable-next-line consistent-this\n  var self = this;\n  var searchForFacetValuesPromise;\n  // newer algoliasearch ^3.27.1 - ~4.0.0\n  if (clientHasSFFV) {\n    searchForFacetValuesPromise = this.client.searchForFacetValues([\n      { indexName: state.index, params: algoliaQuery },\n    ]);\n    // algoliasearch < 3.27.1\n  } else if (clientHasInitIndex) {\n    searchForFacetValuesPromise = this.client\n      .initIndex(state.index)\n      .searchForFacetValues(algoliaQuery);\n    // algoliasearch ~5.0.0\n  } else {\n    // @MAJOR only use client.search\n    delete algoliaQuery.facetName;\n    searchForFacetValuesPromise = this.client\n      .search([\n        {\n          type: 'facet',\n          facet: facet,\n          indexName: state.index,\n          params: algoliaQuery,\n        },\n      ])\n      .then(function processResponse(response) {\n        return response.results[0];\n      });\n  }\n\n  this.emit('searchForFacetValues', {\n    state: state,\n    facet: facet,\n    query: query,\n  });\n\n  return searchForFacetValuesPromise.then(\n    function addIsRefined(content) {\n      self._currentNbQueries--;\n      if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n\n      content = Array.isArray(content) ? content[0] : content;\n\n      content.facetHits.forEach(function (f) {\n        f.escapedValue = escapeFacetValue(f.value);\n        f.isRefined = isDisjunctive\n          ? state.isDisjunctiveFacetRefined(facet, f.escapedValue)\n          : state.isFacetRefined(facet, f.escapedValue);\n      });\n\n      return content;\n    },\n    function (e) {\n      self._currentNbQueries--;\n      if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n      throw e;\n    }\n  );\n};\n\n/**\n * Sets the text query used for the search.\n *\n * This method resets the current page to 0.\n * @param  {string} q the user query\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setQuery = function (q) {\n  this._change({\n    state: this.state.resetPage().setQuery(q),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Remove all the types of refinements except tags. A string can be provided to remove\n * only the refinements of a specific attribute. For more advanced use case, you can\n * provide a function instead. This function should follow the\n * [clearCallback definition](#SearchParameters.clearCallback).\n *\n * This method resets the current page to 0.\n * @param {string} [name] optional name of the facet / attribute on which we want to remove all refinements\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n * @example\n * // Removing all the refinements\n * helper.clearRefinements().search();\n * @example\n * // Removing all the filters on a the category attribute.\n * helper.clearRefinements('category').search();\n * @example\n * // Removing only the exclude filters on the category facet.\n * helper.clearRefinements(function(value, attribute, type) {\n *   return type === 'exclude' && attribute === 'category';\n * }).search();\n */\nAlgoliaSearchHelper.prototype.clearRefinements = function (name) {\n  this._change({\n    state: this.state.resetPage().clearRefinements(name),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Remove all the tag filters.\n *\n * This method resets the current page to 0.\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.clearTags = function () {\n  this._change({\n    state: this.state.resetPage().clearTags(),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Adds a disjunctive filter to a faceted attribute with the `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} value the associated value (will be converted to string)\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addDisjunctiveFacetRefinement = function (\n  facet,\n  value\n) {\n  this._change({\n    state: this.state.resetPage().addDisjunctiveFacetRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#addDisjunctiveFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.addDisjunctiveRefine = function () {\n  return this.addDisjunctiveFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Adds a refinement on a hierarchical facet. It will throw\n * an exception if the facet is not defined or if the facet\n * is already refined.\n *\n * This method resets the current page to 0.\n * @param {string} facet the facet name\n * @param {string} path the hierarchical facet path\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @throws Error if the facet is not defined or if the facet is refined\n * @chainable\n * @fires change\n */\nAlgoliaSearchHelper.prototype.addHierarchicalFacetRefinement = function (\n  facet,\n  path\n) {\n  this._change({\n    state: this.state.resetPage().addHierarchicalFacetRefinement(facet, path),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Adds a an numeric filter to an attribute with the `operator` and `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param  {string} attribute the attribute on which the numeric filter applies\n * @param  {string} operator the operator of the filter\n * @param  {number} value the value of the filter\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addNumericRefinement = function (\n  attribute,\n  operator,\n  value\n) {\n  this._change({\n    state: this.state\n      .resetPage()\n      .addNumericRefinement(attribute, operator, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Adds a filter to a faceted attribute with the `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} value the associated value (will be converted to string)\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addFacetRefinement = function (facet, value) {\n  this._change({\n    state: this.state.resetPage().addFacetRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#addFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.addRefine = function () {\n  return this.addFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Adds a an exclusion filter to a faceted attribute with the `value` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} value the associated value (will be converted to string)\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addFacetExclusion = function (facet, value) {\n  this._change({\n    state: this.state.resetPage().addExcludeRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#addFacetExclusion}\n */\nAlgoliaSearchHelper.prototype.addExclude = function () {\n  return this.addFacetExclusion.apply(this, arguments);\n};\n\n/**\n * Adds a tag filter with the `tag` provided. If the\n * filter is already set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} tag the tag to add to the filter\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addTag = function (tag) {\n  this._change({\n    state: this.state.resetPage().addTagRefinement(tag),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Adds a \"frequently bought together\" recommendation query.\n *\n * @param {FrequentlyBoughtTogetherQuery} params the parameters for the recommendation\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addFrequentlyBoughtTogether = function (params) {\n  this._recommendChange({\n    state: this.recommendState.addFrequentlyBoughtTogether(params),\n  });\n\n  return this;\n};\n\n/**\n * Adds a \"related products\" recommendation query.\n *\n * @param {RelatedProductsQuery} params the parameters for the recommendation\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addRelatedProducts = function (params) {\n  this._recommendChange({\n    state: this.recommendState.addRelatedProducts(params),\n  });\n\n  return this;\n};\n\n/**\n * Adds a \"trending items\" recommendation query.\n *\n * @param {TrendingItemsQuery} params the parameters for the recommendation\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addTrendingItems = function (params) {\n  this._recommendChange({\n    state: this.recommendState.addTrendingItems(params),\n  });\n\n  return this;\n};\n\n/**\n * Adds a \"trending facets\" recommendation query.\n *\n * @param {TrendingFacetsQuery} params the parameters for the recommendation\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addTrendingFacets = function (params) {\n  this._recommendChange({\n    state: this.recommendState.addTrendingFacets(params),\n  });\n\n  return this;\n};\n\n/**\n * Adds a \"looking similar\" recommendation query.\n *\n * @param {LookingSimilarQuery} params the parameters for the recommendation\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addLookingSimilar = function (params) {\n  this._recommendChange({\n    state: this.recommendState.addLookingSimilar(params),\n  });\n\n  return this;\n};\n\n/**\n * Removes an numeric filter to an attribute with the `operator` and `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * Some parameters are optional, triggering different behavior:\n *  - if the value is not provided, then all the numeric value will be removed for the\n *  specified attribute/operator couple.\n *  - if the operator is not provided either, then all the numeric filter on this attribute\n *  will be removed.\n *\n * This method resets the current page to 0.\n * @param  {string} attribute the attribute on which the numeric filter applies\n * @param  {string} [operator] the operator of the filter\n * @param  {number} [value] the value of the filter\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeNumericRefinement = function (\n  attribute,\n  operator,\n  value\n) {\n  this._change({\n    state: this.state\n      .resetPage()\n      .removeNumericRefinement(attribute, operator, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Removes a disjunctive filter to a faceted attribute with the `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * If the value is omitted, then this method will remove all the filters for the\n * attribute.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} [value] the associated value\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeDisjunctiveFacetRefinement = function (\n  facet,\n  value\n) {\n  this._change({\n    state: this.state\n      .resetPage()\n      .removeDisjunctiveFacetRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#removeDisjunctiveFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.removeDisjunctiveRefine = function () {\n  return this.removeDisjunctiveFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Removes the refinement set on a hierarchical facet.\n * @param {string} facet the facet name\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @throws Error if the facet is not defined or if the facet is not refined\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeHierarchicalFacetRefinement = function (\n  facet\n) {\n  this._change({\n    state: this.state.resetPage().removeHierarchicalFacetRefinement(facet),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Removes a filter to a faceted attribute with the `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * If the value is omitted, then this method will remove all the filters for the\n * attribute.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} [value] the associated value\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeFacetRefinement = function (facet, value) {\n  this._change({\n    state: this.state.resetPage().removeFacetRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#removeFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.removeRefine = function () {\n  return this.removeFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Removes an exclusion filter to a faceted attribute with the `value` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * If the value is omitted, then this method will remove all the filters for the\n * attribute.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} [value] the associated value\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeFacetExclusion = function (facet, value) {\n  this._change({\n    state: this.state.resetPage().removeExcludeRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#removeFacetExclusion}\n */\nAlgoliaSearchHelper.prototype.removeExclude = function () {\n  return this.removeFacetExclusion.apply(this, arguments);\n};\n\n/**\n * Removes a tag filter with the `tag` provided. If the\n * filter is not set, it doesn't change the filters.\n *\n * This method resets the current page to 0.\n * @param {string} tag tag to remove from the filter\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeTag = function (tag) {\n  this._change({\n    state: this.state.resetPage().removeTagRefinement(tag),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Removes a \"frequently bought together\" recommendation query.\n *\n * @param {number} id identifier of the recommendation widget\n * @returns {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeFrequentlyBoughtTogether = function (id) {\n  this._recommendChange({\n    state: this.recommendState.removeParams(id),\n  });\n\n  return this;\n};\n\n/**\n * Removes a \"related products\" recommendation query.\n *\n * @param {number} id identifier of the recommendation widget\n * @returns {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeRelatedProducts = function (id) {\n  this._recommendChange({\n    state: this.recommendState.removeParams(id),\n  });\n\n  return this;\n};\n\n/**\n * Removes a \"trending items\" recommendation query.\n *\n * @param {number} id identifier of the recommendation widget\n * @returns {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeTrendingItems = function (id) {\n  this._recommendChange({\n    state: this.recommendState.removeParams(id),\n  });\n\n  return this;\n};\n\n/**\n * Removes a \"trending facets\" recommendation query.\n *\n * @param {number} id identifier of the recommendation widget\n * @returns {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeTrendingFacets = function (id) {\n  this._recommendChange({\n    state: this.recommendState.removeParams(id),\n  });\n\n  return this;\n};\n\n/**\n * Removes a \"looking similar\" recommendation query.\n *\n * @param {number} id identifier of the recommendation widget\n * @returns {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeLookingSimilar = function (id) {\n  this._recommendChange({\n    state: this.recommendState.removeParams(id),\n  });\n\n  return this;\n};\n\n/**\n * Adds or removes an exclusion filter to a faceted attribute with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} value the associated value\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.toggleFacetExclusion = function (facet, value) {\n  this._change({\n    state: this.state.resetPage().toggleExcludeFacetRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#toggleFacetExclusion}\n */\nAlgoliaSearchHelper.prototype.toggleExclude = function () {\n  return this.toggleFacetExclusion.apply(this, arguments);\n};\n\n/**\n * Adds or removes a filter to a faceted attribute with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method can be used for conjunctive, disjunctive and hierarchical filters.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} value the associated value\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @throws Error will throw an error if the facet is not declared in the settings of the helper\n * @fires change\n * @chainable\n * @deprecated since version 2.19.0, see {@link AlgoliaSearchHelper#toggleFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.toggleRefinement = function (facet, value) {\n  return this.toggleFacetRefinement(facet, value);\n};\n\n/**\n * Adds or removes a filter to a faceted attribute with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method can be used for conjunctive, disjunctive and hierarchical filters.\n *\n * This method resets the current page to 0.\n * @param  {string} facet the facet to refine\n * @param  {string} value the associated value\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @throws Error will throw an error if the facet is not declared in the settings of the helper\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.toggleFacetRefinement = function (facet, value) {\n  this._change({\n    state: this.state.resetPage().toggleFacetRefinement(facet, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since version 2.4.0, see {@link AlgoliaSearchHelper#toggleFacetRefinement}\n */\nAlgoliaSearchHelper.prototype.toggleRefine = function () {\n  return this.toggleFacetRefinement.apply(this, arguments);\n};\n\n/**\n * Adds or removes a tag filter with the `value` provided. If\n * the value is set then it removes it, otherwise it adds the filter.\n *\n * This method resets the current page to 0.\n * @param {string} tag tag to remove or add\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.toggleTag = function (tag) {\n  this._change({\n    state: this.state.resetPage().toggleTagRefinement(tag),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Increments the page number by one.\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n * @example\n * helper.setPage(0).nextPage().getPage();\n * // returns 1\n */\nAlgoliaSearchHelper.prototype.nextPage = function () {\n  var page = this.state.page || 0;\n  return this.setPage(page + 1);\n};\n\n/**\n * Decrements the page number by one.\n * @fires change\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @chainable\n * @example\n * helper.setPage(1).previousPage().getPage();\n * // returns 0\n */\nAlgoliaSearchHelper.prototype.previousPage = function () {\n  var page = this.state.page || 0;\n  return this.setPage(page - 1);\n};\n\n/**\n * @private\n * @param {number} page The page number\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @chainable\n * @fires change\n */\nfunction setCurrentPage(page) {\n  if (page < 0) throw new Error('Page requested below 0.');\n\n  this._change({\n    state: this.state.setPage(page),\n    isPageReset: false,\n  });\n\n  return this;\n}\n\n/**\n * Change the current page\n * @deprecated\n * @param  {number} page The page number\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setCurrentPage = setCurrentPage;\n\n/**\n * Updates the current page.\n * @function\n * @param  {number} page The page number\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setPage = setCurrentPage;\n\n/**\n * Updates the name of the index that will be targeted by the query.\n *\n * This method resets the current page to 0.\n * @param {string} name the index name\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setIndex = function (name) {\n  this._change({\n    state: this.state.resetPage().setIndex(name),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Update a parameter of the search. This method reset the page\n *\n * The complete list of parameters is available on the\n * [Algolia website](https://www.algolia.com/doc/rest#query-an-index).\n * The most commonly used parameters have their own [shortcuts](#query-parameters-shortcuts)\n * or benefit from higher-level APIs (all the kind of filters and facets have their own API)\n *\n * This method resets the current page to 0.\n * @param {string} parameter name of the parameter to update\n * @param {any} value new value of the parameter\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n * @example\n * helper.setQueryParameter('hitsPerPage', 20).search();\n */\nAlgoliaSearchHelper.prototype.setQueryParameter = function (parameter, value) {\n  this._change({\n    state: this.state.resetPage().setQueryParameter(parameter, value),\n    isPageReset: true,\n  });\n\n  return this;\n};\n\n/**\n * Set the whole state (warning: will erase previous state)\n * @param {SearchParameters} newState the whole new state\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.setState = function (newState) {\n  this._change({\n    state: SearchParameters.make(newState),\n    isPageReset: false,\n  });\n\n  return this;\n};\n\n/**\n * Override the current state without triggering a change event.\n * Do not use this method unless you know what you are doing. (see the example\n * for a legit use case)\n * @param {SearchParameters} newState the whole new state\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n * @example\n *  helper.on('change', function(state){\n *    // In this function you might want to find a way to store the state in the url/history\n *    updateYourURL(state)\n *  })\n *  window.onpopstate = function(event){\n *    // This is naive though as you should check if the state is really defined etc.\n *    helper.overrideStateWithoutTriggeringChangeEvent(event.state).search()\n *  }\n * @chainable\n */\nAlgoliaSearchHelper.prototype.overrideStateWithoutTriggeringChangeEvent =\n  function (newState) {\n    this.state = new SearchParameters(newState);\n    return this;\n  };\n\n/**\n * Check if an attribute has any numeric, conjunctive, disjunctive or hierarchical filters.\n * @param {string} attribute the name of the attribute\n * @return {boolean} true if the attribute is filtered by at least one value\n * @example\n * // hasRefinements works with numeric, conjunctive, disjunctive and hierarchical filters\n * helper.hasRefinements('price'); // false\n * helper.addNumericRefinement('price', '>', 100);\n * helper.hasRefinements('price'); // true\n *\n * helper.hasRefinements('color'); // false\n * helper.addFacetRefinement('color', 'blue');\n * helper.hasRefinements('color'); // true\n *\n * helper.hasRefinements('material'); // false\n * helper.addDisjunctiveFacetRefinement('material', 'plastic');\n * helper.hasRefinements('material'); // true\n *\n * helper.hasRefinements('categories'); // false\n * helper.toggleFacetRefinement('categories', 'kitchen > knife');\n * helper.hasRefinements('categories'); // true\n *\n */\nAlgoliaSearchHelper.prototype.hasRefinements = function (attribute) {\n  if (objectHasKeys(this.state.getNumericRefinements(attribute))) {\n    return true;\n  } else if (this.state.isConjunctiveFacet(attribute)) {\n    return this.state.isFacetRefined(attribute);\n  } else if (this.state.isDisjunctiveFacet(attribute)) {\n    return this.state.isDisjunctiveFacetRefined(attribute);\n  } else if (this.state.isHierarchicalFacet(attribute)) {\n    return this.state.isHierarchicalFacetRefined(attribute);\n  }\n\n  // there's currently no way to know that the user did call `addNumericRefinement` at some point\n  // thus we cannot distinguish if there once was a numeric refinement that was cleared\n  // so we will return false in every other situations to be consistent\n  // while what we should do here is throw because we did not find the attribute in any type\n  // of refinement\n  return false;\n};\n\n/**\n * Check if a value is excluded for a specific faceted attribute. If the value\n * is omitted then the function checks if there is any excluding refinements.\n *\n * @param  {string}  facet name of the attribute for used for faceting\n * @param  {string}  [value] optional value. If passed will test that this value\n * is filtering the given facet.\n * @return {boolean} true if refined\n * @example\n * helper.isExcludeRefined('color'); // false\n * helper.isExcludeRefined('color', 'blue') // false\n * helper.isExcludeRefined('color', 'red') // false\n *\n * helper.addFacetExclusion('color', 'red');\n *\n * helper.isExcludeRefined('color'); // true\n * helper.isExcludeRefined('color', 'blue') // false\n * helper.isExcludeRefined('color', 'red') // true\n */\nAlgoliaSearchHelper.prototype.isExcluded = function (facet, value) {\n  return this.state.isExcludeRefined(facet, value);\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since 2.4.0, see {@link AlgoliaSearchHelper#hasRefinements}\n */\nAlgoliaSearchHelper.prototype.isDisjunctiveRefined = function (facet, value) {\n  return this.state.isDisjunctiveFacetRefined(facet, value);\n};\n\n/**\n * Check if the string is a currently filtering tag.\n * @param {string} tag tag to check\n * @return {boolean} true if the tag is currently refined\n */\nAlgoliaSearchHelper.prototype.hasTag = function (tag) {\n  return this.state.isTagRefined(tag);\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @deprecated since 2.4.0, see {@link AlgoliaSearchHelper#hasTag}\n */\nAlgoliaSearchHelper.prototype.isTagRefined = function () {\n  return this.hasTagRefinements.apply(this, arguments);\n};\n\n/**\n * Get the name of the currently used index.\n * @return {string} name of the index\n * @example\n * helper.setIndex('highestPrice_products').getIndex();\n * // returns 'highestPrice_products'\n */\nAlgoliaSearchHelper.prototype.getIndex = function () {\n  return this.state.index;\n};\n\nfunction getCurrentPage() {\n  return this.state.page;\n}\n\n/**\n * Get the currently selected page\n * @deprecated\n * @return {number} the current page\n */\nAlgoliaSearchHelper.prototype.getCurrentPage = getCurrentPage;\n/**\n * Get the currently selected page\n * @function\n * @return {number} the current page\n */\nAlgoliaSearchHelper.prototype.getPage = getCurrentPage;\n\n/**\n * Get all the tags currently set to filters the results.\n *\n * @return {string[]} The list of tags currently set.\n */\nAlgoliaSearchHelper.prototype.getTags = function () {\n  return this.state.tagRefinements;\n};\n\n/**\n * Get the list of refinements for a given attribute. This method works with\n * conjunctive, disjunctive, excluding and numerical filters.\n *\n * See also SearchResults#getRefinements\n *\n * @param {string} facetName attribute name used for faceting\n * @return {Array.<FacetRefinement|NumericRefinement>} All Refinement are objects that contain a value, and\n * a type. Numeric also contains an operator.\n * @example\n * helper.addNumericRefinement('price', '>', 100);\n * helper.getRefinements('price');\n * // [\n * //   {\n * //     \"value\": [\n * //       100\n * //     ],\n * //     \"operator\": \">\",\n * //     \"type\": \"numeric\"\n * //   }\n * // ]\n * @example\n * helper.addFacetRefinement('color', 'blue');\n * helper.addFacetExclusion('color', 'red');\n * helper.getRefinements('color');\n * // [\n * //   {\n * //     \"value\": \"blue\",\n * //     \"type\": \"conjunctive\"\n * //   },\n * //   {\n * //     \"value\": \"red\",\n * //     \"type\": \"exclude\"\n * //   }\n * // ]\n * @example\n * helper.addDisjunctiveFacetRefinement('material', 'plastic');\n * // [\n * //   {\n * //     \"value\": \"plastic\",\n * //     \"type\": \"disjunctive\"\n * //   }\n * // ]\n */\nAlgoliaSearchHelper.prototype.getRefinements = function (facetName) {\n  var refinements = [];\n\n  if (this.state.isConjunctiveFacet(facetName)) {\n    var conjRefinements = this.state.getConjunctiveRefinements(facetName);\n\n    conjRefinements.forEach(function (r) {\n      refinements.push({\n        value: r,\n        type: 'conjunctive',\n      });\n    });\n\n    var excludeRefinements = this.state.getExcludeRefinements(facetName);\n\n    excludeRefinements.forEach(function (r) {\n      refinements.push({\n        value: r,\n        type: 'exclude',\n      });\n    });\n  } else if (this.state.isDisjunctiveFacet(facetName)) {\n    var disjunctiveRefinements =\n      this.state.getDisjunctiveRefinements(facetName);\n\n    disjunctiveRefinements.forEach(function (r) {\n      refinements.push({\n        value: r,\n        type: 'disjunctive',\n      });\n    });\n  }\n\n  var numericRefinements = this.state.getNumericRefinements(facetName);\n\n  Object.keys(numericRefinements).forEach(function (operator) {\n    var value = numericRefinements[operator];\n\n    refinements.push({\n      value: value,\n      operator: operator,\n      type: 'numeric',\n    });\n  });\n\n  return refinements;\n};\n\n/**\n * Return the current refinement for the (attribute, operator)\n * @param {string} attribute attribute in the record\n * @param {string} operator operator applied on the refined values\n * @return {Array.<number|number[]>} refined values\n */\nAlgoliaSearchHelper.prototype.getNumericRefinement = function (\n  attribute,\n  operator\n) {\n  return this.state.getNumericRefinement(attribute, operator);\n};\n\n/**\n * Get the current breadcrumb for a hierarchical facet, as an array\n * @param  {string} facetName Hierarchical facet name\n * @return {array.<string>} the path as an array of string\n */\nAlgoliaSearchHelper.prototype.getHierarchicalFacetBreadcrumb = function (\n  facetName\n) {\n  return this.state.getHierarchicalFacetBreadcrumb(facetName);\n};\n\n// /////////// PRIVATE\n\n/**\n * Perform the underlying queries\n * @private\n * @param {object} options options for the query\n * @param {boolean} [options.onlyWithDerivedHelpers=false] if true, only the derived helpers will be queried\n * @return {undefined} does not return anything\n * @fires search\n * @fires result\n * @fires error\n */\nAlgoliaSearchHelper.prototype._search = function (options) {\n  var state = this.state;\n  var states = [];\n  var mainQueries = [];\n\n  if (!options.onlyWithDerivedHelpers) {\n    mainQueries = requestBuilder._getQueries(state.index, state);\n\n    states.push({\n      state: state,\n      queriesCount: mainQueries.length,\n      helper: this,\n    });\n\n    this.emit('search', {\n      state: state,\n      results: this.lastResults,\n    });\n  }\n\n  var derivedQueries = this.derivedHelpers.map(function (derivedHelper) {\n    var derivedState = derivedHelper.getModifiedState(state);\n    var derivedStateQueries = derivedState.index\n      ? requestBuilder._getQueries(derivedState.index, derivedState)\n      : [];\n\n    states.push({\n      state: derivedState,\n      queriesCount: derivedStateQueries.length,\n      helper: derivedHelper,\n    });\n\n    derivedHelper.emit('search', {\n      state: derivedState,\n      results: derivedHelper.lastResults,\n    });\n\n    return derivedStateQueries;\n  });\n\n  var queries = Array.prototype.concat.apply(mainQueries, derivedQueries);\n\n  var queryId = this._queryId++;\n  this._currentNbQueries++;\n\n  if (!queries.length) {\n    return Promise.resolve({ results: [] }).then(\n      this._dispatchAlgoliaResponse.bind(this, states, queryId)\n    );\n  }\n\n  try {\n    this.client\n      .search(queries)\n      .then(this._dispatchAlgoliaResponse.bind(this, states, queryId))\n      .catch(this._dispatchAlgoliaError.bind(this, queryId));\n  } catch (error) {\n    // If we reach this part, we're in an internal error state\n    this.emit('error', {\n      error: error,\n    });\n  }\n\n  return undefined;\n};\n\nAlgoliaSearchHelper.prototype._recommend = function () {\n  var searchState = this.state;\n  var recommendState = this.recommendState;\n  var index = this.getIndex();\n  var states = [{ state: recommendState, index: index, helper: this }];\n  var ids = recommendState.params.map(function (param) {\n    return param.$$id;\n  });\n\n  this.emit('fetch', {\n    recommend: {\n      state: recommendState,\n      results: this.lastRecommendResults,\n    },\n  });\n\n  var cache = this._recommendCache;\n\n  var derivedQueries = this.derivedHelpers.map(function (derivedHelper) {\n    var derivedIndex = derivedHelper.getModifiedState(searchState).index;\n    if (!derivedIndex) {\n      return [];\n    }\n\n    // Contrary to what is done when deriving the search state, we don't want to\n    // provide the current recommend state to the derived helper, as it would\n    // inherit unwanted queries. We instead provide an empty recommend state.\n    var derivedState = derivedHelper.getModifiedRecommendState(\n      new RecommendParameters()\n    );\n    states.push({\n      state: derivedState,\n      index: derivedIndex,\n      helper: derivedHelper,\n    });\n\n    ids = Array.prototype.concat.apply(\n      ids,\n      derivedState.params.map(function (param) {\n        return param.$$id;\n      })\n    );\n\n    derivedHelper.emit('fetch', {\n      recommend: {\n        state: derivedState,\n        results: derivedHelper.lastRecommendResults,\n      },\n    });\n\n    return derivedState._buildQueries(derivedIndex, cache);\n  });\n\n  var queries = Array.prototype.concat.apply(\n    this.recommendState._buildQueries(index, cache),\n    derivedQueries\n  );\n\n  if (queries.length === 0) {\n    return;\n  }\n\n  if (\n    queries.length > 0 &&\n    typeof this.client.getRecommendations === 'undefined'\n  ) {\n    // eslint-disable-next-line no-console\n    console.warn(\n      'Please update algoliasearch/lite to the latest version in order to use recommend widgets.'\n    );\n    return;\n  }\n\n  var queryId = this._recommendQueryId++;\n  this._currentNbRecommendQueries++;\n\n  try {\n    this.client\n      .getRecommendations(queries)\n      .then(this._dispatchRecommendResponse.bind(this, queryId, states, ids))\n      .catch(this._dispatchRecommendError.bind(this, queryId));\n  } catch (error) {\n    // If we reach this part, we're in an internal error state\n    this.emit('error', {\n      error: error,\n    });\n  }\n\n  return;\n};\n\n/**\n * Transform the responses as sent by the server and transform them into a user\n * usable object that merge the results of all the batch requests. It will dispatch\n * over the different helper + derived helpers (when there are some).\n * @private\n * @param {array.<{SearchParameters, AlgoliaQueries, AlgoliaSearchHelper}>} states state used to generate the request\n * @param {number} queryId id of the current request\n * @param {object} content content of the response\n * @return {undefined}\n */\nAlgoliaSearchHelper.prototype._dispatchAlgoliaResponse = function (\n  states,\n  queryId,\n  content\n) {\n  // eslint-disable-next-line consistent-this\n  var self = this;\n\n  // @TODO remove the number of outdated queries discarded instead of just one\n\n  if (queryId < this._lastQueryIdReceived) {\n    // Outdated answer\n    return;\n  }\n\n  this._currentNbQueries -= queryId - this._lastQueryIdReceived;\n  this._lastQueryIdReceived = queryId;\n\n  if (this._currentNbQueries === 0) this.emit('searchQueueEmpty');\n\n  var results = content.results.slice();\n\n  states.forEach(function (s) {\n    var state = s.state;\n    var queriesCount = s.queriesCount;\n    var helper = s.helper;\n    var specificResults = results.splice(0, queriesCount);\n\n    if (!state.index) {\n      helper.emit('result', {\n        results: null,\n        state: state,\n      });\n      return;\n    }\n\n    helper.lastResults = new SearchResults(\n      state,\n      specificResults,\n      self._searchResultsOptions\n    );\n\n    helper.emit('result', {\n      results: helper.lastResults,\n      state: state,\n    });\n  });\n};\n\nAlgoliaSearchHelper.prototype._dispatchRecommendResponse = function (\n  queryId,\n  states,\n  ids,\n  content\n) {\n  // @TODO remove the number of outdated queries discarded instead of just one\n\n  if (queryId < this._lastRecommendQueryIdReceived) {\n    // Outdated answer\n    return;\n  }\n\n  this._currentNbRecommendQueries -=\n    queryId - this._lastRecommendQueryIdReceived;\n  this._lastRecommendQueryIdReceived = queryId;\n\n  if (this._currentNbRecommendQueries === 0) this.emit('recommendQueueEmpty');\n\n  var cache = this._recommendCache;\n\n  var idsMap = {};\n  ids\n    .filter(function (id) {\n      return cache[id] === undefined;\n    })\n    .forEach(function (id, index) {\n      if (!idsMap[id]) idsMap[id] = [];\n\n      idsMap[id].push(index);\n    });\n\n  Object.keys(idsMap).forEach(function (id) {\n    var indices = idsMap[id];\n    var firstResult = content.results[indices[0]];\n    if (indices.length === 1) {\n      cache[id] = firstResult;\n      return;\n    }\n    cache[id] = Object.assign({}, firstResult, {\n      hits: sortAndMergeRecommendations(\n        indices.map(function (idx) {\n          return content.results[idx].hits;\n        })\n      ),\n    });\n  });\n\n  var results = {};\n  ids.forEach(function (id) {\n    results[id] = cache[id];\n  });\n\n  states.forEach(function (s) {\n    var state = s.state;\n    var helper = s.helper;\n\n    if (!s.index) {\n      // eslint-disable-next-line no-warning-comments\n      // TODO: emit \"result\" event when events for Recommend are implemented\n      helper.emit('recommend:result', {\n        results: null,\n        state: state,\n      });\n      return;\n    }\n\n    helper.lastRecommendResults = new RecommendResults(state, results);\n\n    // eslint-disable-next-line no-warning-comments\n    // TODO: emit \"result\" event when events for Recommend are implemented\n    helper.emit('recommend:result', {\n      recommend: {\n        results: helper.lastRecommendResults,\n        state: state,\n      },\n    });\n  });\n};\n\nAlgoliaSearchHelper.prototype._dispatchAlgoliaError = function (\n  queryId,\n  error\n) {\n  if (queryId < this._lastQueryIdReceived) {\n    // Outdated answer\n    return;\n  }\n\n  this._currentNbQueries -= queryId - this._lastQueryIdReceived;\n  this._lastQueryIdReceived = queryId;\n\n  this.emit('error', {\n    error: error,\n  });\n\n  if (this._currentNbQueries === 0) this.emit('searchQueueEmpty');\n};\n\nAlgoliaSearchHelper.prototype._dispatchRecommendError = function (\n  queryId,\n  error\n) {\n  if (queryId < this._lastRecommendQueryIdReceived) {\n    // Outdated answer\n    return;\n  }\n\n  this._currentNbRecommendQueries -=\n    queryId - this._lastRecommendQueryIdReceived;\n  this._lastRecommendQueryIdReceived = queryId;\n\n  this.emit('error', {\n    error: error,\n  });\n\n  if (this._currentNbRecommendQueries === 0) this.emit('recommendQueueEmpty');\n};\n\nAlgoliaSearchHelper.prototype.containsRefinement = function (\n  query,\n  facetFilters,\n  numericFilters,\n  tagFilters\n) {\n  return (\n    query ||\n    facetFilters.length !== 0 ||\n    numericFilters.length !== 0 ||\n    tagFilters.length !== 0\n  );\n};\n\n/**\n * Test if there are some disjunctive refinements on the facet\n * @private\n * @param {string} facet the attribute to test\n * @return {boolean} true if there are refinements on this attribute\n */\nAlgoliaSearchHelper.prototype._hasDisjunctiveRefinements = function (facet) {\n  return (\n    this.state.disjunctiveRefinements[facet] &&\n    this.state.disjunctiveRefinements[facet].length > 0\n  );\n};\n\nAlgoliaSearchHelper.prototype._change = function (event) {\n  var state = event.state;\n  var isPageReset = event.isPageReset;\n\n  if (state !== this.state) {\n    this.state = state;\n\n    this.emit('change', {\n      state: this.state,\n      results: this.lastResults,\n      isPageReset: isPageReset,\n    });\n  }\n};\n\nAlgoliaSearchHelper.prototype._recommendChange = function (event) {\n  var state = event.state;\n\n  if (state !== this.recommendState) {\n    this.recommendState = state;\n\n    // eslint-disable-next-line no-warning-comments\n    // TODO: emit \"change\" event when events for Recommend are implemented\n    this.emit('recommend:change', {\n      search: {\n        results: this.lastResults,\n        state: this.state,\n      },\n      recommend: {\n        results: this.lastRecommendResults,\n        state: this.recommendState,\n      },\n    });\n  }\n};\n\n/**\n * Clears the cache of the underlying Algolia client.\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n */\nAlgoliaSearchHelper.prototype.clearCache = function () {\n  if (this.client.clearCache) this.client.clearCache();\n  return this;\n};\n\n/**\n * Updates the internal client instance. If the reference of the clients\n * are equal then no update is actually done.\n * @param  {AlgoliaSearch} newClient an AlgoliaSearch client\n * @return {AlgoliaSearchHelper} Method is chainable, it returns itself\n */\nAlgoliaSearchHelper.prototype.setClient = function (newClient) {\n  if (this.client === newClient) return this;\n\n  if (typeof newClient.addAlgoliaAgent === 'function') {\n    newClient.addAlgoliaAgent('JS Helper (' + version + ')');\n  }\n  this.client = newClient;\n\n  return this;\n};\n\n/**\n * Gets the instance of the currently used client.\n * @return {AlgoliaSearch} the currently used client\n */\nAlgoliaSearchHelper.prototype.getClient = function () {\n  return this.client;\n};\n\n/**\n * Creates an derived instance of the Helper. A derived helper\n * is a way to request other indices synchronised with the lifecycle\n * of the main Helper. This mechanism uses the multiqueries feature\n * of Algolia to aggregate all the requests in a single network call.\n *\n * This method takes a function that is used to create a new SearchParameter\n * that will be used to create requests to Algolia. Those new requests\n * are created just before the `search` event. The signature of the function\n * is `SearchParameters -> SearchParameters`.\n *\n * This method returns a new DerivedHelper which is an EventEmitter\n * that fires the same `search`, `result` and `error` events. Those\n * events, however, will receive data specific to this DerivedHelper\n * and the SearchParameters that is returned by the call of the\n * parameter function.\n * @param {function} fn SearchParameters -> SearchParameters\n * @param {function} recommendFn RecommendParameters -> RecommendParameters\n * @return {DerivedHelper} a new DerivedHelper\n */\nAlgoliaSearchHelper.prototype.derive = function (fn, recommendFn) {\n  var derivedHelper = new DerivedHelper(this, fn, recommendFn);\n  this.derivedHelpers.push(derivedHelper);\n  return derivedHelper;\n};\n\n/**\n * This method detaches a derived Helper from the main one. Prefer using the one from the\n * derived helper itself, to remove the event listeners too.\n * @private\n * @param  {DerivedHelper} derivedHelper the derived helper to detach\n * @return {undefined} nothing is returned\n * @throws Error\n */\nAlgoliaSearchHelper.prototype.detachDerivedHelper = function (derivedHelper) {\n  var pos = this.derivedHelpers.indexOf(derivedHelper);\n  if (pos === -1) throw new Error('Derived helper already detached');\n  this.derivedHelpers.splice(pos, 1);\n};\n\n/**\n * This method returns true if there is currently at least one on-going search.\n * @return {boolean} true if there is a search pending\n */\nAlgoliaSearchHelper.prototype.hasPendingRequests = function () {\n  return this._currentNbQueries > 0;\n};\n\n/**\n * @typedef AlgoliaSearchHelper.NumericRefinement\n * @type {object}\n * @property {number[]} value the numbers that are used for filtering this attribute with\n * the operator specified.\n * @property {string} operator the faceting data: value, number of entries\n * @property {string} type will be 'numeric'\n */\n\n/**\n * @typedef AlgoliaSearchHelper.FacetRefinement\n * @type {object}\n * @property {string} value the string use to filter the attribute\n * @property {string} type the type of filter: 'conjunctive', 'disjunctive', 'exclude'\n */\n\nmodule.exports = AlgoliaSearchHelper;\n","'use strict';\n\nmodule.exports = function compact(array) {\n  if (!Array.isArray(array)) {\n    return [];\n  }\n\n  return array.filter(Boolean);\n};\n","'use strict';\n\n// NOTE: this behaves like lodash/defaults, but doesn't mutate the target\n// it also preserve keys order\nmodule.exports = function defaultsPure() {\n  var sources = Array.prototype.slice.call(arguments);\n\n  return sources.reduceRight(function (acc, source) {\n    Object.keys(Object(source)).forEach(function (key) {\n      if (source[key] === undefined) {\n        return;\n      }\n      if (acc[key] !== undefined) {\n        // remove if already added, so that we can add it in correct order\n        delete acc[key];\n      }\n      acc[key] = source[key];\n    });\n    return acc;\n  }, {});\n};\n","'use strict';\n\n/**\n * Replaces a leading - with \\-\n * @private\n * @param {any} value the facet value to replace\n * @returns {any} the escaped facet value or the value if it was not a string\n */\nfunction escapeFacetValue(value) {\n  if (typeof value !== 'string') return value;\n\n  return String(value).replace(/^-/, '\\\\-');\n}\n\n/**\n * Replaces a leading \\- with -\n * @private\n * @param {any} value the escaped facet value\n * @returns {any} the unescaped facet value or the value if it was not a string\n */\nfunction unescapeFacetValue(value) {\n  if (typeof value !== 'string') return value;\n\n  return value.replace(/^\\\\-/, '-');\n}\n\nmodule.exports = {\n  escapeFacetValue: escapeFacetValue,\n  unescapeFacetValue: unescapeFacetValue,\n};\n","'use strict';\n\n// @MAJOR can be replaced by native Array#find when we change support\nmodule.exports = function find(array, comparator) {\n  if (!Array.isArray(array)) {\n    return undefined;\n  }\n\n  for (var i = 0; i < array.length; i++) {\n    if (comparator(array[i])) {\n      return array[i];\n    }\n  }\n\n  return undefined;\n};\n","'use strict';\n\n// @MAJOR can be replaced by native Array#findIndex when we change support\nmodule.exports = function find(array, comparator) {\n  if (!Array.isArray(array)) {\n    return -1;\n  }\n\n  for (var i = 0; i < array.length; i++) {\n    if (comparator(array[i])) {\n      return i;\n    }\n  }\n  return -1;\n};\n","// @MAJOR: remove this function and use Array.prototype.flat\nmodule.exports = function flat(arr) {\n  return arr.reduce(function (acc, val) {\n    return acc.concat(val);\n  }, []);\n};\n","'use strict';\n\nvar find = require('./find');\n\n/**\n * Transform sort format from user friendly notation to lodash format\n * @param {string[]} sortBy array of predicate of the form \"attribute:order\"\n * @param {string[]} [defaults] array of predicate of the form \"attribute:order\"\n * @return {array.<string[]>} array containing 2 elements : attributes, orders\n */\nmodule.exports = function formatSort(sortBy, defaults) {\n  var defaultInstructions = (defaults || []).map(function (sort) {\n    return sort.split(':');\n  });\n\n  return sortBy.reduce(\n    function preparePredicate(out, sort) {\n      var sortInstruction = sort.split(':');\n\n      var matchingDefault = find(\n        defaultInstructions,\n        function (defaultInstruction) {\n          return defaultInstruction[0] === sortInstruction[0];\n        }\n      );\n\n      if (sortInstruction.length > 1 || !matchingDefault) {\n        out[0].push(sortInstruction[0]);\n        out[1].push(sortInstruction[1]);\n        return out;\n      }\n\n      out[0].push(matchingDefault[0]);\n      out[1].push(matchingDefault[1]);\n      return out;\n    },\n    [[], []]\n  );\n};\n","'use strict';\n\nfunction inherits(ctor, superCtor) {\n  ctor.prototype = Object.create(superCtor.prototype, {\n    constructor: {\n      value: ctor,\n      enumerable: false,\n      writable: true,\n      configurable: true,\n    },\n  });\n}\n\nmodule.exports = inherits;\n","'use strict';\n\nfunction intersection(arr1, arr2) {\n  return arr1.filter(function (value, index) {\n    return (\n      arr2.indexOf(value) > -1 &&\n      arr1.indexOf(value) === index /* skips duplicates */\n    );\n  });\n}\n\nmodule.exports = intersection;\n","'use strict';\n\nfunction clone(value) {\n  if (typeof value === 'object' && value !== null) {\n    return _merge(Array.isArray(value) ? [] : {}, value);\n  }\n  return value;\n}\n\nfunction isObjectOrArrayOrFunction(value) {\n  return (\n    typeof value === 'function' ||\n    Array.isArray(value) ||\n    Object.prototype.toString.call(value) === '[object Object]'\n  );\n}\n\nfunction _merge(target, source) {\n  if (target === source) {\n    return target;\n  }\n\n  // eslint-disable-next-line no-restricted-syntax\n  for (var key in source) {\n    if (\n      !Object.prototype.hasOwnProperty.call(source, key) ||\n      key === '__proto__' ||\n      key === 'constructor'\n    ) {\n      // eslint-disable-next-line no-continue\n      continue;\n    }\n\n    var sourceVal = source[key];\n    var targetVal = target[key];\n\n    if (typeof targetVal !== 'undefined' && typeof sourceVal === 'undefined') {\n      // eslint-disable-next-line no-continue\n      continue;\n    }\n\n    if (\n      isObjectOrArrayOrFunction(targetVal) &&\n      isObjectOrArrayOrFunction(sourceVal)\n    ) {\n      target[key] = _merge(targetVal, sourceVal);\n    } else {\n      target[key] = clone(sourceVal);\n    }\n  }\n  return target;\n}\n\n/**\n * This method is like Object.assign, but recursively merges own and inherited\n * enumerable keyed properties of source objects into the destination object.\n *\n * NOTE: this behaves like lodash/merge, but:\n * - does mutate functions if they are a source\n * - treats non-plain objects as plain\n * - does not work for circular objects\n * - treats sparse arrays as sparse\n * - does not convert Array-like objects (Arguments, NodeLists, etc.) to arrays\n *\n * @param {Object} target The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n */\nfunction merge(target) {\n  if (!isObjectOrArrayOrFunction(target)) {\n    target = {};\n  }\n\n  for (var i = 1, l = arguments.length; i < l; i++) {\n    var source = arguments[i];\n\n    if (isObjectOrArrayOrFunction(source)) {\n      _merge(target, source);\n    }\n  }\n  return target;\n}\n\nmodule.exports = merge;\n","'use strict';\n\nfunction objectHasKeys(obj) {\n  return obj && Object.keys(obj).length > 0;\n}\n\nmodule.exports = objectHasKeys;\n","'use strict';\n\n// https://github.com/babel/babel/blob/3aaafae053fa75febb3aa45d45b6f00646e30ba4/packages/babel-helpers/src/helpers.js#L604-L620\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n  if (source === null) return {};\n  var target = {};\n  var sourceKeys = Object.keys(source);\n  var key;\n  var i;\n  for (i = 0; i < sourceKeys.length; i++) {\n    key = sourceKeys[i];\n    // eslint-disable-next-line no-continue\n    if (excluded.indexOf(key) >= 0) continue;\n    target[key] = source[key];\n  }\n  return target;\n}\n\nmodule.exports = _objectWithoutPropertiesLoose;\n","'use strict';\n\nfunction compareAscending(value, other) {\n  if (value !== other) {\n    var valIsDefined = value !== undefined;\n    var valIsNull = value === null;\n\n    var othIsDefined = other !== undefined;\n    var othIsNull = other === null;\n\n    if (\n      (!othIsNull && value > other) ||\n      (valIsNull && othIsDefined) ||\n      !valIsDefined\n    ) {\n      return 1;\n    }\n    if (\n      (!valIsNull && value < other) ||\n      (othIsNull && valIsDefined) ||\n      !othIsDefined\n    ) {\n      return -1;\n    }\n  }\n  return 0;\n}\n\n/**\n * @param {Array<object>} collection object with keys in attributes\n * @param {Array<string>} iteratees attributes\n * @param {Array<string>} orders asc | desc\n * @return {Array<object>} sorted collection\n */\nfunction orderBy(collection, iteratees, orders) {\n  if (!Array.isArray(collection)) {\n    return [];\n  }\n\n  if (!Array.isArray(orders)) {\n    orders = [];\n  }\n\n  var result = collection.map(function (value, index) {\n    return {\n      criteria: iteratees.map(function (iteratee) {\n        return value[iteratee];\n      }),\n      index: index,\n      value: value,\n    };\n  });\n\n  result.sort(function comparer(object, other) {\n    var index = -1;\n\n    while (++index < object.criteria.length) {\n      var res = compareAscending(object.criteria[index], other.criteria[index]);\n      if (res) {\n        if (index >= orders.length) {\n          return res;\n        }\n        if (orders[index] === 'desc') {\n          return -res;\n        }\n        return res;\n      }\n    }\n\n    // This ensures a stable sort in V8 and other engines.\n    // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n    return object.index - other.index;\n  });\n\n  return result.map(function (res) {\n    return res.value;\n  });\n}\n\nmodule.exports = orderBy;\n","'use strict';\n\nfunction valToNumber(v) {\n  if (typeof v === 'number') {\n    return v;\n  } else if (typeof v === 'string') {\n    return parseFloat(v);\n  } else if (Array.isArray(v)) {\n    return v.map(valToNumber);\n  }\n\n  throw new Error(\n    'The value should be a number, a parsable string or an array of those.'\n  );\n}\n\nmodule.exports = valToNumber;\n","'use strict';\n\nvar merge = require('./functions/merge');\n\nfunction sortObject(obj) {\n  return Object.keys(obj)\n    .sort()\n    .reduce(function (acc, curr) {\n      acc[curr] = obj[curr];\n      return acc;\n    }, {});\n}\n\nvar requestBuilder = {\n  /**\n   * Get all the queries to send to the client, those queries can used directly\n   * with the Algolia client.\n   * @private\n   * @param  {string} index The name of the index\n   * @param  {SearchParameters} state The state from which to get the queries\n   * @return {object[]} The queries\n   */\n  _getQueries: function getQueries(index, state) {\n    var queries = [];\n\n    // One query for the hits\n    queries.push({\n      indexName: index,\n      params: requestBuilder._getHitsSearchParams(state),\n    });\n\n    // One for each disjunctive facets\n    state.getRefinedDisjunctiveFacets().forEach(function (refinedFacet) {\n      queries.push({\n        indexName: index,\n        params: requestBuilder._getDisjunctiveFacetSearchParams(\n          state,\n          refinedFacet\n        ),\n      });\n    });\n\n    // More to get the parent levels of the hierarchical facets when refined\n    state.getRefinedHierarchicalFacets().forEach(function (refinedFacet) {\n      var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);\n      var currentRefinement = state.getHierarchicalRefinement(refinedFacet);\n      var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n\n      // If we are deeper than level 0 (starting from `beer > IPA`)\n      // we want to get all parent values\n      if (\n        currentRefinement.length > 0 &&\n        currentRefinement[0].split(separator).length > 1\n      ) {\n        // We generate a map of the filters we will use for our facet values queries\n        var filtersMap = currentRefinement[0]\n          .split(separator)\n          .slice(0, -1)\n          .reduce(function createFiltersMap(map, segment, level) {\n            return map.concat({\n              attribute: hierarchicalFacet.attributes[level],\n              value:\n                level === 0\n                  ? segment\n                  : [map[map.length - 1].value, segment].join(separator),\n            });\n          }, []);\n\n        filtersMap.forEach(function (filter, level) {\n          var params = requestBuilder._getDisjunctiveFacetSearchParams(\n            state,\n            filter.attribute,\n            level === 0\n          );\n\n          // Keep facet filters unrelated to current hierarchical attributes\n          function hasHierarchicalFacetFilter(value) {\n            return hierarchicalFacet.attributes.some(function (attribute) {\n              return attribute === value.split(':')[0];\n            });\n          }\n\n          var filteredFacetFilters = (params.facetFilters || []).reduce(\n            function (acc, facetFilter) {\n              if (Array.isArray(facetFilter)) {\n                var filtered = facetFilter.filter(function (filterValue) {\n                  return !hasHierarchicalFacetFilter(filterValue);\n                });\n\n                if (filtered.length > 0) {\n                  acc.push(filtered);\n                }\n              }\n\n              if (\n                typeof facetFilter === 'string' &&\n                !hasHierarchicalFacetFilter(facetFilter)\n              ) {\n                acc.push(facetFilter);\n              }\n\n              return acc;\n            },\n            []\n          );\n\n          var parent = filtersMap[level - 1];\n          if (level > 0) {\n            params.facetFilters = filteredFacetFilters.concat(\n              parent.attribute + ':' + parent.value\n            );\n          } else {\n            params.facetFilters =\n              filteredFacetFilters.length > 0\n                ? filteredFacetFilters\n                : undefined;\n          }\n\n          queries.push({ indexName: index, params: params });\n        });\n      }\n    });\n\n    return queries;\n  },\n\n  /**\n   * Build search parameters used to fetch hits\n   * @private\n   * @param  {SearchParameters} state The state from which to get the queries\n   * @return {object.<string, any>} The search parameters for hits\n   */\n  _getHitsSearchParams: function (state) {\n    var facets = state.facets\n      .concat(state.disjunctiveFacets)\n      .concat(requestBuilder._getHitsHierarchicalFacetsAttributes(state))\n      .sort();\n\n    var facetFilters = requestBuilder._getFacetFilters(state);\n    var numericFilters = requestBuilder._getNumericFilters(state);\n    var tagFilters = requestBuilder._getTagFilters(state);\n    var additionalParams = {};\n\n    if (facets.length > 0) {\n      additionalParams.facets = facets.indexOf('*') > -1 ? ['*'] : facets;\n    }\n\n    if (tagFilters.length > 0) {\n      additionalParams.tagFilters = tagFilters;\n    }\n\n    if (facetFilters.length > 0) {\n      additionalParams.facetFilters = facetFilters;\n    }\n\n    if (numericFilters.length > 0) {\n      additionalParams.numericFilters = numericFilters;\n    }\n\n    return sortObject(merge({}, state.getQueryParams(), additionalParams));\n  },\n\n  /**\n   * Build search parameters used to fetch a disjunctive facet\n   * @private\n   * @param  {SearchParameters} state The state from which to get the queries\n   * @param  {string} facet the associated facet name\n   * @param  {boolean} hierarchicalRootLevel ?? FIXME\n   * @return {object} The search parameters for a disjunctive facet\n   */\n  _getDisjunctiveFacetSearchParams: function (\n    state,\n    facet,\n    hierarchicalRootLevel\n  ) {\n    var facetFilters = requestBuilder._getFacetFilters(\n      state,\n      facet,\n      hierarchicalRootLevel\n    );\n    var numericFilters = requestBuilder._getNumericFilters(state, facet);\n    var tagFilters = requestBuilder._getTagFilters(state);\n    var additionalParams = {\n      hitsPerPage: 0,\n      page: 0,\n      analytics: false,\n      clickAnalytics: false,\n    };\n\n    if (tagFilters.length > 0) {\n      additionalParams.tagFilters = tagFilters;\n    }\n\n    var hierarchicalFacet = state.getHierarchicalFacetByName(facet);\n\n    if (hierarchicalFacet) {\n      additionalParams.facets =\n        requestBuilder._getDisjunctiveHierarchicalFacetAttribute(\n          state,\n          hierarchicalFacet,\n          hierarchicalRootLevel\n        );\n    } else {\n      additionalParams.facets = facet;\n    }\n\n    if (numericFilters.length > 0) {\n      additionalParams.numericFilters = numericFilters;\n    }\n\n    if (facetFilters.length > 0) {\n      additionalParams.facetFilters = facetFilters;\n    }\n\n    return sortObject(merge({}, state.getQueryParams(), additionalParams));\n  },\n\n  /**\n   * Return the numeric filters in an algolia request fashion\n   * @private\n   * @param {SearchParameters} state the state from which to get the filters\n   * @param {string} [facetName] the name of the attribute for which the filters should be excluded\n   * @return {string[]} the numeric filters in the algolia format\n   */\n  _getNumericFilters: function (state, facetName) {\n    if (state.numericFilters) {\n      return state.numericFilters;\n    }\n\n    var numericFilters = [];\n\n    Object.keys(state.numericRefinements).forEach(function (attribute) {\n      var operators = state.numericRefinements[attribute] || {};\n      Object.keys(operators).forEach(function (operator) {\n        var values = operators[operator] || [];\n        if (facetName !== attribute) {\n          values.forEach(function (value) {\n            if (Array.isArray(value)) {\n              var vs = value.map(function (v) {\n                return attribute + operator + v;\n              });\n              numericFilters.push(vs);\n            } else {\n              numericFilters.push(attribute + operator + value);\n            }\n          });\n        }\n      });\n    });\n\n    return numericFilters;\n  },\n\n  /**\n   * Return the tags filters depending on which format is used, either tagFilters or tagRefinements\n   * @private\n   * @param {SearchParameters} state the state from which to get the filters\n   * @return {string} Tag filters in a single string\n   */\n  _getTagFilters: function (state) {\n    if (state.tagFilters) {\n      return state.tagFilters;\n    }\n\n    return state.tagRefinements.join(',');\n  },\n\n  /**\n   * Build facetFilters parameter based on current refinements. The array returned\n   * contains strings representing the facet filters in the algolia format.\n   * @private\n   * @param  {SearchParameters} state The state from which to get the queries\n   * @param  {string} [facet] if set, the current disjunctive facet\n   * @param  {boolean} [hierarchicalRootLevel] ?? FIXME\n   * @return {array.<string>} The facet filters in the algolia format\n   */\n  _getFacetFilters: function (state, facet, hierarchicalRootLevel) {\n    var facetFilters = [];\n\n    var facetsRefinements = state.facetsRefinements || {};\n    Object.keys(facetsRefinements)\n      .sort()\n      .forEach(function (facetName) {\n        var facetValues = facetsRefinements[facetName] || [];\n        facetValues\n          .slice()\n          .sort()\n          .forEach(function (facetValue) {\n            facetFilters.push(facetName + ':' + facetValue);\n          });\n      });\n\n    var facetsExcludes = state.facetsExcludes || {};\n    Object.keys(facetsExcludes)\n      .sort()\n      .forEach(function (facetName) {\n        var facetValues = facetsExcludes[facetName] || [];\n        facetValues.sort().forEach(function (facetValue) {\n          facetFilters.push(facetName + ':-' + facetValue);\n        });\n      });\n\n    var disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements || {};\n    Object.keys(disjunctiveFacetsRefinements)\n      .sort()\n      .forEach(function (facetName) {\n        var facetValues = disjunctiveFacetsRefinements[facetName] || [];\n        if (facetName === facet || !facetValues || facetValues.length === 0) {\n          return;\n        }\n        var orFilters = [];\n\n        facetValues\n          .slice()\n          .sort()\n          .forEach(function (facetValue) {\n            orFilters.push(facetName + ':' + facetValue);\n          });\n\n        facetFilters.push(orFilters);\n      });\n\n    var hierarchicalFacetsRefinements =\n      state.hierarchicalFacetsRefinements || {};\n    Object.keys(hierarchicalFacetsRefinements)\n      .sort()\n      .forEach(function (facetName) {\n        var facetValues = hierarchicalFacetsRefinements[facetName] || [];\n        var facetValue = facetValues[0];\n\n        if (facetValue === undefined) {\n          return;\n        }\n\n        var hierarchicalFacet = state.getHierarchicalFacetByName(facetName);\n        var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n        var rootPath = state._getHierarchicalRootPath(hierarchicalFacet);\n        var attributeToRefine;\n        var attributesIndex;\n\n        // we ask for parent facet values only when the `facet` is the current hierarchical facet\n        if (facet === facetName) {\n          // if we are at the root level already, no need to ask for facet values, we get them from\n          // the hits query\n          if (\n            facetValue.indexOf(separator) === -1 ||\n            (!rootPath && hierarchicalRootLevel === true) ||\n            (rootPath &&\n              rootPath.split(separator).length ===\n                facetValue.split(separator).length)\n          ) {\n            return;\n          }\n\n          if (!rootPath) {\n            attributesIndex = facetValue.split(separator).length - 2;\n            facetValue = facetValue.slice(0, facetValue.lastIndexOf(separator));\n          } else {\n            attributesIndex = rootPath.split(separator).length - 1;\n            facetValue = rootPath;\n          }\n\n          attributeToRefine = hierarchicalFacet.attributes[attributesIndex];\n        } else {\n          attributesIndex = facetValue.split(separator).length - 1;\n\n          attributeToRefine = hierarchicalFacet.attributes[attributesIndex];\n        }\n\n        if (attributeToRefine) {\n          facetFilters.push([attributeToRefine + ':' + facetValue]);\n        }\n      });\n\n    return facetFilters;\n  },\n\n  _getHitsHierarchicalFacetsAttributes: function (state) {\n    var out = [];\n\n    return state.hierarchicalFacets.reduce(\n      // ask for as much levels as there's hierarchical refinements\n      function getHitsAttributesForHierarchicalFacet(\n        allAttributes,\n        hierarchicalFacet\n      ) {\n        var hierarchicalRefinement = state.getHierarchicalRefinement(\n          hierarchicalFacet.name\n        )[0];\n\n        // if no refinement, ask for root level\n        if (!hierarchicalRefinement) {\n          allAttributes.push(hierarchicalFacet.attributes[0]);\n          return allAttributes;\n        }\n\n        var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n        var level = hierarchicalRefinement.split(separator).length;\n        var newAttributes = hierarchicalFacet.attributes.slice(0, level + 1);\n\n        return allAttributes.concat(newAttributes);\n      },\n      out\n    );\n  },\n\n  _getDisjunctiveHierarchicalFacetAttribute: function (\n    state,\n    hierarchicalFacet,\n    rootLevel\n  ) {\n    var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n    if (rootLevel === true) {\n      var rootPath = state._getHierarchicalRootPath(hierarchicalFacet);\n      var attributeIndex = 0;\n\n      if (rootPath) {\n        attributeIndex = rootPath.split(separator).length;\n      }\n      return [hierarchicalFacet.attributes[attributeIndex]];\n    }\n\n    var hierarchicalRefinement =\n      state.getHierarchicalRefinement(hierarchicalFacet.name)[0] || '';\n    // if refinement is 'beers > IPA > Flying dog',\n    // then we want `facets: ['beers > IPA']` as disjunctive facet (parent level values)\n\n    var parentLevel = hierarchicalRefinement.split(separator).length - 1;\n    return hierarchicalFacet.attributes.slice(0, parentLevel + 1);\n  },\n\n  getSearchForFacetQuery: function (facetName, query, maxFacetHits, state) {\n    var stateForSearchForFacetValues = state.isDisjunctiveFacet(facetName)\n      ? state.clearRefinements(facetName)\n      : state;\n    var searchForFacetSearchParameters = {\n      facetQuery: query,\n      facetName: facetName,\n    };\n    if (typeof maxFacetHits === 'number') {\n      searchForFacetSearchParameters.maxFacetHits = maxFacetHits;\n    }\n    return sortObject(\n      merge(\n        {},\n        requestBuilder._getHitsSearchParams(stateForSearchForFacetValues),\n        searchForFacetSearchParameters\n      )\n    );\n  },\n};\n\nmodule.exports = requestBuilder;\n","'use strict';\n\nmodule.exports = function isValidUserToken(userToken) {\n  if (userToken === null) {\n    return false;\n  }\n  return /^[a-zA-Z0-9_-]{1,64}$/.test(userToken);\n};\n","'use strict';\n\nvar find = require('../functions/find');\nvar flat = require('../functions/flat');\n\nfunction getAverageIndices(indexTracker, nrOfObjs) {\n  var avgIndices = [];\n\n  Object.keys(indexTracker).forEach(function (key) {\n    if (indexTracker[key].count < 2) {\n      indexTracker[key].indexSum += 100;\n    }\n    avgIndices.push({\n      objectID: key,\n      avgOfIndices: indexTracker[key].indexSum / nrOfObjs,\n    });\n  });\n\n  return avgIndices.sort(function (a, b) {\n    return a.avgOfIndices > b.avgOfIndices ? 1 : -1;\n  });\n}\n\nfunction sortAndMergeRecommendations(results) {\n  var indexTracker = {};\n\n  results.forEach(function (hits) {\n    hits.forEach(function (hit, index) {\n      if (!indexTracker[hit.objectID]) {\n        indexTracker[hit.objectID] = { indexSum: index, count: 1 };\n      } else {\n        indexTracker[hit.objectID] = {\n          indexSum: indexTracker[hit.objectID].indexSum + index,\n          count: indexTracker[hit.objectID].count + 1,\n        };\n      }\n    });\n  });\n\n  var sortedAverageIndices = getAverageIndices(indexTracker, results.length);\n\n  var finalOrder = sortedAverageIndices.reduce(function (\n    orderedHits,\n    avgIndexRef\n  ) {\n    var result = find(flat(results), function (hit) {\n      return hit.objectID === avgIndexRef.objectID;\n    });\n    return result ? orderedHits.concat(result) : orderedHits;\n  },\n  []);\n\n  return finalOrder;\n}\n\nmodule.exports = sortAndMergeRecommendations;\n","'use strict';\n\nmodule.exports = '3.22.2';\n"],"names":["EventEmitter","this","_events","_maxListeners","undefined","isFunction","arg","isObject","isUndefined","module","exports","prototype","defaultMaxListeners","setMaxListeners","n","isNaN","TypeError","emit","type","er","handler","len","args","i","listeners","error","length","arguments","Error","err","context","call","Array","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","fired","g","removeListener","list","position","splice","removeAllListeners","key","listenerCount","evlistener","emitter","AlgoliaSearchHelper","require","RecommendParameters","RecommendResults","SearchParameters","SearchResults","algoliasearchHelper","client","index","opts","searchResultsOptions","version","DerivedHelper","mainHelper","fn","recommendFn","main","lastResults","lastRecommendResults","inherits","detach","detachDerivedHelper","getModifiedState","parameters","getModifiedRecommendState","params","constructor","addParams","newParams","removeParams","id","filter","param","$$id","addFrequentlyBoughtTogether","Object","assign","model","addRelatedProducts","addTrendingItems","addTrendingFacets","addLookingSimilar","_buildQueries","indexName","cache","map","query","threshold","state","results","_state","_rawResults","self","forEach","defaultsPure","objectHasKeys","omit","lib","addRefinement","refinementList","attribute","value","isRefined","valueAsString","facetRefinement","concat","mod","removeRefinement","clearRefinement","v","f","toggleRefinement","refinementType","hasChanged","newRefinementList","keys","reduce","memo","values","facetList","refinementValue","containsRefinements","Boolean","refinementValueAsString","indexOf","find","intersection","merge","valToNumber","isValidUserToken","RefinementList","isEqualNumericRefinement","a","b","isArray","every","el","newParameters","_parseNumbers","userToken","warn","facets","disjunctiveFacets","hierarchicalFacets","facetsRefinements","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements","paramName","isKeyKnown","PARAMETERS","isValueDefined","partialState","numbers","k","parsedValue","parseFloat","insideBoundingBox","geoRect","operators","operator","parsedValues","vPrime","make","instance","facet","rootPath","currentRefinement","getHierarchicalRefinement","name","clearRefinements","toggleHierarchicalFacetRefinement","validate","currentState","tagFilters","numericFilters","patch","_clearNumericRefinements","setQueryParameters","clearTags","setIndex","setQuery","newQuery","setPage","newPage","page","setFacets","setDisjunctiveFacets","setHitsPerPage","hitsPerPage","setTypoTolerance","typoTolerance","addNumericRefinement","val","isNumericRefined","getConjunctiveRefinements","facetName","isConjunctiveFacet","getDisjunctiveRefinements","isDisjunctiveFacet","getExcludeRefinements","removeNumericRefinement","number","paramValue","op","getNumericRefinements","getNumericRefinement","newNumericRefinements","operatorList","outValues","addFacet","addDisjunctiveFacet","addHierarchicalFacet","hierarchicalFacet","isHierarchicalFacet","addFacetRefinement","addExcludeRefinement","addDisjunctiveFacetRefinement","addTagRefinement","tag","isTagRefined","modification","removeFacet","removeDisjunctiveFacet","removeHierarchicalFacet","removeFacetRefinement","removeExcludeRefinement","removeDisjunctiveFacetRefinement","removeTagRefinement","t","toggleFacetRefinement","toggleConjunctiveFacetRefinement","toggleDisjunctiveFacetRefinement","toggleExcludeFacetRefinement","separator","_getHierarchicalFacetSeparator","getHierarchicalFacetByName","lastIndexOf","addHierarchicalFacetRefinement","path","isHierarchicalFacetRefined","removeHierarchicalFacetRefinement","toggleTagRefinement","isFacetRefined","isExcludeRefined","isDisjunctiveFacetRefined","refinements","isOperatorDefined","array","searchedValue","isAttributeValueDefined","currentValue","getRefinedDisjunctiveFacets","disjunctiveNumericRefinedFacets","getRefinedHierarchicalFacets","sort","getUnrefinedDisjunctiveFacets","refinedFacets","managedParameters","getQueryParams","queryParams","setQueryParameter","parameter","nextWithNumbers","previousPlainObject","acc","nextPlainObject","previous","isPreviousValueDefined","isNextValueDefined","resetPage","_getHierarchicalFacetSortBy","sortBy","_getHierarchicalRootPath","_getHierarchicalShowParentLevel","showParentLevel","hierarchicalFacetName","getHierarchicalFacetBreadcrumb","refinement","split","part","trim","toString","JSON","stringify","hierarchicalFacetResult","hierarchicalFacetIndex","hierarchicalFacetRefinement","hierarchicalSeparator","hierarchicalRootPath","hierarchicalShowParentLevel","prepareHierarchicalFacetSortBy","rootExhaustive","facetResult","exhaustive","generateTreeFn","hierarchicalTree","currentHierarchicalLevel","parent","level","data","subtree","picked","facetValue","tuple","parentPath","onlyMatchingTree","orderBy","facetCount","parts","escapedValue","escapeFacetValue","count","format","unescapeFacetValue","generateHierarchicalTree","fv","compact","findIndex","formatSort","getIndices","attributes","indices","idx","assignFacetStats","dest","facetStats","stats","options","mainSubResponse","persistHierarchicalRootCount","processingTimeMS","sum","result","facetsIndices","disjunctiveFacetsIndices","nextDisjunctiveResult","mainFacets","facetKey","hierarchicalAttributeName","facetValueObject","facetIndex","idxAttributeName","exhaustiveFacetsCount","isFacetDisjunctive","isFacetConjunctive","facets_stats","disjunctiveFacet","dfacet","facetResults","attributeIndex","dataFromMainRequest","refinedFacet","defaultData","root","excludes","extractNormalizedFacetValues","predicate","isExcluded","hierarchicalFacetValues","replace","currentRefinementSplit","unshift","setIsRefined","item","depth","child","recSort","sortFn","node","names","children","childNode","sortedChildren","getFacetStatsIfAvailable","getRefinement","attributeName","resultsFacets","getFacetByName","DEFAULT_SORT","getFacetValues","facetValues","facetOrdering","renderingContent","getFacetOrdering","orderedFacets","remainingFacets","hide","reverseOrder","order","hidden","ordering","sortRemainingBy","sortViaFacetOrdering","vanillaSortFn","getFacetStats","getRefinements","res","facetDeclaration","rootFacet","intermediateFacet","newFacet","numericValue","requestBuilder","sortAndMergeRecommendations","addAlgoliaAgent","setClient","recommendState","_queryId","_recommendQueryId","_lastQueryIdReceived","_lastRecommendQueryIdReceived","derivedHelpers","_currentNbQueries","_currentNbRecommendQueries","_searchResultsOptions","_recommendCache","setCurrentPage","_change","isPageReset","getCurrentPage","search","_search","onlyWithDerivedHelpers","searchOnlyWithDerivedHelpers","recommend","_recommend","getQuery","_getHitsSearchParams","searchOnce","cb","tempState","queries","_getQueries","then","content","_originalResponse","e","catch","findAnswers","derivedHelper","Promise","resolve","derivedState","attributesForPrediction","nbHits","errorMessage","initIndex","queryLanguages","searchForFacetValues","maxFacetHits","userState","clientHasSFFV","clientHasInitIndex","isDisjunctive","algoliaQuery","getSearchForFacetQuery","searchForFacetValuesPromise","response","facetHits","q","addDisjunctiveRefine","addRefine","addFacetExclusion","addExclude","addTag","_recommendChange","removeDisjunctiveRefine","removeRefine","removeFacetExclusion","removeExclude","removeTag","removeFrequentlyBoughtTogether","removeRelatedProducts","removeTrendingItems","removeTrendingFacets","removeLookingSimilar","toggleFacetExclusion","toggleExclude","toggleRefine","toggleTag","nextPage","previousPage","setState","newState","overrideStateWithoutTriggeringChangeEvent","hasRefinements","isDisjunctiveRefined","hasTag","hasTagRefinements","getIndex","getPage","getTags","r","states","mainQueries","queriesCount","helper","derivedQueries","derivedStateQueries","queryId","_dispatchAlgoliaResponse","bind","_dispatchAlgoliaError","searchState","ids","derivedIndex","getRecommendations","_dispatchRecommendResponse","_dispatchRecommendError","s","specificResults","idsMap","firstResult","hits","containsRefinement","facetFilters","_hasDisjunctiveRefinements","disjunctiveRefinements","event","clearCache","newClient","getClient","derive","pos","hasPendingRequests","sources","reduceRight","source","String","comparator","arr","defaults","defaultInstructions","out","sortInstruction","matchingDefault","defaultInstruction","ctor","superCtor","create","enumerable","writable","configurable","arr1","arr2","isObjectOrArrayOrFunction","_merge","target","hasOwnProperty","sourceVal","targetVal","l","obj","excluded","sourceKeys","compareAscending","other","valIsDefined","valIsNull","othIsDefined","othIsNull","collection","iteratees","orders","criteria","iteratee","object","sortObject","curr","_getDisjunctiveFacetSearchParams","filtersMap","segment","join","hasHierarchicalFacetFilter","some","filteredFacetFilters","facetFilter","filtered","filterValue","_getHitsHierarchicalFacetsAttributes","_getFacetFilters","_getNumericFilters","_getTagFilters","additionalParams","hierarchicalRootLevel","analytics","clickAnalytics","_getDisjunctiveHierarchicalFacetAttribute","vs","orFilters","attributeToRefine","attributesIndex","allAttributes","hierarchicalRefinement","newAttributes","rootLevel","parentLevel","stateForSearchForFacetValues","searchForFacetSearchParameters","facetQuery","test","flat","indexTracker","hit","objectID","indexSum","sortedAverageIndices","nrOfObjs","avgIndices","avgOfIndices","getAverageIndices","orderedHits","avgIndexRef"],"sourceRoot":""}