{"version":3,"file":"algoliasearch-helper-XaGrLYXT.js","sources":["../../../node_modules/algoliasearch-helper/src/functions/merge.js","../../../node_modules/algoliasearch-helper/src/functions/defaultsPure.js","../../../node_modules/algoliasearch-helper/src/functions/intersection.js","../../../node_modules/algoliasearch-helper/src/functions/find.js","../../../node_modules/algoliasearch-helper/src/functions/valToNumber.js","../../../node_modules/algoliasearch-helper/src/functions/omit.js","../../../node_modules/algoliasearch-helper/src/functions/objectHasKeys.js","../../../node_modules/algoliasearch-helper/src/utils/isValidUserToken.js","../../../node_modules/algoliasearch-helper/src/SearchParameters/RefinementList.js","../../../node_modules/algoliasearch-helper/src/SearchParameters/index.js","../../../node_modules/algoliasearch-helper/src/functions/orderBy.js","../../../node_modules/algoliasearch-helper/src/functions/compact.js","../../../node_modules/algoliasearch-helper/src/functions/findIndex.js","../../../node_modules/algoliasearch-helper/src/functions/formatSort.js","../../../node_modules/algoliasearch-helper/src/SearchResults/generate-hierarchical-tree.js","../../../node_modules/algoliasearch-helper/src/SearchResults/index.js","../../../node_modules/algoliasearch-helper/src/functions/inherits.js","../../../node_modules/algoliasearch-helper/src/DerivedHelper/index.js","../../../node_modules/algoliasearch-helper/src/requestBuilder.js","../../../node_modules/algoliasearch-helper/src/version.js","../../../node_modules/algoliasearch-helper/src/algoliasearch.helper.js","../../../node_modules/algoliasearch-helper/index.js"],"sourcesContent":["'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 for (var key in source) {\n if (\n !Object.prototype.hasOwnProperty.call(source, key) ||\n key === '__proto__'\n ) {\n continue;\n }\n\n var sourceVal = source[key];\n var targetVal = target[key];\n\n if (typeof targetVal !== 'undefined' && typeof sourceVal === 'undefined') {\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} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n */\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\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\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\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","'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('The value should be a number, a parsable string or an array of those.');\n}\n\nmodule.exports = valToNumber;\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 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 objectHasKeys(obj) {\n return obj && Object.keys(obj).length > 0;\n}\n\nmodule.exports = objectHasKeys;\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\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.} SearchParameters.refinementList.RefinementList\n */\n\nvar defaultsPure = require('../functions/defaultsPure');\nvar omit = require('../functions/omit');\nvar objectHasKeys = require('../functions/objectHasKeys');\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(refinementList, attribute, value) {\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(refinementList, attribute, value) {\n if (value === undefined) 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(refinementList, attribute, refinementType) {\n if (attribute === undefined) {\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(memo, key) {\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 memo[key] = facetList;\n\n return memo;\n }, {});\n\n if (hasChanged) return newRefinementList;\n return refinementList;\n }\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}\n */\n isRefined: function isRefined(refinementList, attribute, refinementValue) {\n var containsRefinements = !!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 merge = require('../functions/merge');\nvar defaultsPure = require('../functions/defaultsPure');\nvar intersection = require('../functions/intersection');\nvar find = require('../functions/find');\nvar valToNumber = require('../functions/valToNumber');\nvar omit = require('../functions/omit');\nvar objectHasKeys = require('../functions/objectHasKeys');\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 */\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.>} 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 SearchParameters of the first query in\n * the instant search demo\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 ? SearchParameters._parseNumbers(newParameters) : {};\n\n if (params.userToken !== undefined && !isValidUserToken(params.userToken)) {\n console.warn('[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\\n - Format: [a-zA-Z0-9_-]{1,64}');\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.}\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.}\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.}\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.}\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.}\n */\n this.hierarchicalFacetsRefinements = params.hierarchicalFacetsRefinements || {};\n\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 reparse numbers 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(geoRect) {\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 (currentRefinement.length > 0 && currentRefinement[0].indexOf(facet.rootPath) !== 0) {\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(facet.name, facet.rootPath);\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 (currentState.tagFilters && params.tagRefinements && params.tagRefinements.length > 0) {\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 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 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 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}\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 === 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}\n */\n clearTags: function clearTags() {\n if (this.tagFilters === undefined && this.tagRefinements.length === 0) 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}\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}\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}\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}\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}\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}\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}\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}\n * @example\n * // for price = 50 or 40\n * searchparameter.addNumericRefinement('price', '=', [50, 40]);\n * @example\n * // for size = 38 and 40\n * searchparameter.addNumericRefinement('size', '=', 38);\n * searchparameter.addNumericRefinement('size', '=', 40);\n */\n addNumericRefinement: function(attribute, operator, v) {\n var value = valToNumber(v);\n\n if (this.isNumericRefined(attribute, operator, value)) 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(value);\n } else {\n mod[attribute][operator] = [value];\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}\n */\n removeNumericRefinement: function(attribute, operator, paramValue) {\n if (paramValue !== undefined) {\n if (!this.isNumericRefined(attribute, operator, paramValue)) {\n return this;\n }\n return this.setQueryParameters({\n numericRefinements: this._clearNumericRefinements(function(value, key) {\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(value, key) {\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.} refined values\n */\n getNumericRefinement: function(attribute, operator) {\n return this.numericRefinements[attribute] && this.numericRefinements[attribute][operator];\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.}\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(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({val: value, op: operator}, key, 'numeric');\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 if (hasChanged) return newNumericRefinements;\n return this.numericRefinements;\n }\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}\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}\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}\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: `' + hierarchicalFacet.name + '`');\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}\n */\n addFacetRefinement: function addFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (RefinementList.isRefined(this.facetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsRefinements: RefinementList.addRefinement(this.facetsRefinements, facet, value)\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}\n */\n addExcludeRefinement: function addExcludeRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (RefinementList.isRefined(this.facetsExcludes, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsExcludes: RefinementList.addRefinement(this.facetsExcludes, facet, value)\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}\n */\n addDisjunctiveFacetRefinement: function addDisjunctiveFacetRefinement(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration');\n }\n\n if (RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n disjunctiveFacetsRefinements: RefinementList.addRefinement(\n this.disjunctiveFacetsRefinements, facet, value)\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}\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}\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}\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}\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}\n */\n removeFacetRefinement: function removeFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (!RefinementList.isRefined(this.facetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsRefinements: RefinementList.removeRefinement(this.facetsRefinements, facet, value)\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}\n */\n removeExcludeRefinement: function removeExcludeRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n if (!RefinementList.isRefined(this.facetsExcludes, facet, value)) return this;\n\n return this.setQueryParameters({\n facetsExcludes: RefinementList.removeRefinement(this.facetsExcludes, facet, value)\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}\n */\n removeDisjunctiveFacetRefinement: function removeDisjunctiveFacetRefinement(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration');\n }\n if (!RefinementList.isRefined(this.disjunctiveFacetsRefinements, facet, value)) return this;\n\n return this.setQueryParameters({\n disjunctiveFacetsRefinements: RefinementList.removeRefinement(\n this.disjunctiveFacetsRefinements, facet, value)\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}\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}\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}\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('Cannot refine the undeclared facet ' + facet +\n '; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets');\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}\n */\n toggleConjunctiveFacetRefinement: function toggleConjunctiveFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n\n return this.setQueryParameters({\n facetsRefinements: RefinementList.toggleRefinement(this.facetsRefinements, facet, value)\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}\n */\n toggleExcludeFacetRefinement: function toggleExcludeFacetRefinement(facet, value) {\n if (!this.isConjunctiveFacet(facet)) {\n throw new Error(facet + ' is not defined in the facets attribute of the helper configuration');\n }\n\n return this.setQueryParameters({\n facetsExcludes: RefinementList.toggleRefinement(this.facetsExcludes, facet, value)\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}\n */\n toggleDisjunctiveFacetRefinement: function toggleDisjunctiveFacetRefinement(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration');\n }\n\n return this.setQueryParameters({\n disjunctiveFacetsRefinements: RefinementList.toggleRefinement(\n this.disjunctiveFacetsRefinements, facet, value)\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}\n */\n toggleHierarchicalFacetRefinement: function toggleHierarchicalFacetRefinement(facet, value) {\n if (!this.isHierarchicalFacet(facet)) {\n throw new Error(\n facet + ' is not defined in the hierarchicalFacets attribute of the helper configuration');\n }\n\n var separator = this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(facet));\n\n var mod = {};\n\n var upOneOrMultipleLevel = 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(value + separator) === 0\n );\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({}, mod, this.hierarchicalFacetsRefinements)\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(facet + ' is not defined in the hierarchicalFacets attribute of the helper configuration.');\n }\n var mod = {};\n mod[facet] = [path];\n return this.setQueryParameters({\n hierarchicalFacetsRefinements: defaultsPure({}, mod, this.hierarchicalFacetsRefinements)\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({}, mod, this.hierarchicalFacetsRefinements)\n });\n },\n /**\n * Switch the tag refinement\n * @method\n * @param {string} tag the tag to remove or add\n * @return {SearchParameters}\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}\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}\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}\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}\n */\n isDisjunctiveFacetRefined: function isDisjunctiveFacetRefined(facet, value) {\n if (!this.isDisjunctiveFacet(facet)) {\n return false;\n }\n return RefinementList.isRefined(this.disjunctiveFacetsRefinements, 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}\n */\n isHierarchicalFacetRefined: function isHierarchicalFacetRefined(facet, value) {\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 !!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}\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[]}\n */\n getRefinedDisjunctiveFacets: function getRefinedDisjunctiveFacets() {\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).filter(function(facet) {\n return self.disjunctiveFacetsRefinements[facet].length > 0;\n })\n .concat(disjunctiveNumericRefinedFacets)\n .concat(this.getRefinedHierarchicalFacets());\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[]}\n */\n getRefinedHierarchicalFacets: function getRefinedHierarchicalFacets() {\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) { return facet.name; }),\n Object.keys(this.hierarchicalFacetsRefinements).filter(function(facet) {\n return self.hierarchicalFacetsRefinements[facet].length > 0;\n })\n );\n },\n /**\n * Returned the list of all disjunctive facets not refined\n * @method\n * @return {string[]}\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 getQueryParams: function getQueryParams() {\n var managedParameters = this.managedParameters;\n\n var queryParams = {};\n\n var self = this;\n Object.keys(this).forEach(function(paramName) {\n var paramValue = self[paramName];\n if (managedParameters.indexOf(paramName) === -1 && paramValue !== undefined) {\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 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(\n function(previous, key) {\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\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\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\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\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\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\n * @return {object} a hierarchicalFacet\n */\n getHierarchicalFacetByName: function(hierarchicalFacetName) {\n return find(\n this.hierarchicalFacets,\n function(f) {\n return f.name === hierarchicalFacetName;\n }\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.} 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\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} collection object with keys in attributes\n * @param {Array} iteratees attributes\n * @param {Array} orders asc | desc\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\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// @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","'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.} 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(defaultInstructions, function(\n defaultInstruction\n ) {\n return defaultInstruction[0] === sortInstruction[0];\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\nmodule.exports = generateTrees;\n\nvar orderBy = require('../functions/orderBy');\nvar find = require('../functions/find');\nvar prepareHierarchicalFacetSortBy = require('../functions/formatSort');\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 = state._getHierarchicalFacetSeparator(\n hierarchicalFacet\n );\n var hierarchicalRootPath = state._getHierarchicalRootPath(\n hierarchicalFacet\n );\n var hierarchicalShowParentLevel = state._getHierarchicalShowParentLevel(\n hierarchicalFacet\n );\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 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 currentRefinement,\n hierarchicalFacetResult.exhaustive\n );\n }),\n sortBy[0],\n sortBy[1]\n );\n }\n\n return hierarchicalTree;\n };\n}\n\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 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 merge = require('../functions/merge');\nvar defaultsPure = require('../functions/defaultsPure');\nvar orderBy = require('../functions/orderBy');\nvar compact = require('../functions/compact');\nvar find = require('../functions/find');\nvar findIndex = require('../functions/findIndex');\nvar formatSort = require('../functions/formatSort');\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 * @param {string[]} attributes\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\n * @param {string} hierarchicalAttributeName\n */\nfunction findMatchingHierarchicalFacetFromAttributeName(\n hierarchicalFacets,\n hierarchicalAttributeName\n) {\n return find(hierarchicalFacets, function facetKeyMatchesAttribute(\n hierarchicalFacet\n ) {\n var facetNames = hierarchicalFacet.attributes || [];\n return facetNames.indexOf(hierarchicalAttributeName) > -1;\n });\n}\n\n/*eslint-disable */\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.} results the results from algolia client\n * @example SearchResults of the first query in\n * the instant search demo\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 **/\n/*eslint-enable */\nfunction SearchResults(state, results) {\n var mainSubResponse = results[0];\n\n this._rawResults = results;\n\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 /**\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 * @member {number}\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(function initFutureTree() {\n return [];\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(self.disjunctiveFacets[position], mainSubResponse.facets_stats, facetKey);\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(self.facets[position], mainSubResponse.facets_stats, facetKey);\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(self.hierarchicalFacets[position], function(f) {\n return f.attribute === dfacet;\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 = 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(self.disjunctiveFacets[position], result.facets_stats, dfacet);\n\n if (state.disjunctiveFacetsRefinements[dfacet]) {\n state.disjunctiveFacetsRefinements[dfacet].forEach(function(refinementValue) {\n // add the disjunctive refinements if it is no more retrieved\n if (!self.disjunctiveFacets[position].data[refinementValue] &&\n state.disjunctiveFacetsRefinements[dfacet].indexOf(refinementValue) > -1) {\n self.disjunctiveFacets[position].data[refinementValue] = 0;\n }\n });\n }\n }\n });\n nextDisjunctiveResult++;\n });\n\n // if we have some root 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 (currentRefinement.length === 0 || currentRefinement[0].split(separator).length < 2) {\n return;\n }\n\n var result = results[nextDisjunctiveResult];\n var facets = result && result.facets\n ? 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(self.hierarchicalFacets[position], function(f) {\n return f.attribute === dfacet;\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 var defaultData = {};\n\n if (currentRefinement.length > 0) {\n var root = currentRefinement[0].split(separator)[0];\n defaultData[root] = 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 // 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: mainSubResponse.facets[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(generateHierarchicalTree(state));\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 find(this.facets, predicate) ||\n find(this.disjunctiveFacets, predicate) ||\n find(this.hierarchicalFacets, predicate);\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 return {\n name: name,\n count: facet.data[name],\n isRefined: results._state.isFacetRefined(attribute, name),\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 return {\n name: name,\n count: disjunctiveFacet.data[name],\n isRefined: results._state.isDisjunctiveFacetRefined(attribute, name)\n };\n });\n } else if (results._state.isHierarchicalFacet(attribute)) {\n return find(results.hierarchicalFacets, predicate);\n }\n}\n\n/**\n * Sort nodes of a hierarchical or disjunctive facet results\n * @private\n * @param {function} sortFn\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 */\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}\n */\nfunction sortViaFacetOrdering(facetValues, facetOrdering) {\n var orderedFacets = [];\n var remainingFacets = [];\n\n var order = facetOrdering.order || [];\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 if (reverseOrder[name] !== undefined) {\n orderedFacets[reverseOrder[name]] = item;\n } else {\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 = [['path', 'name'], ['asc', 'asc']];\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=}\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. | 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 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(function(data, facetName) {\n if (options.facetOrdering) {\n var facetOrdering = getFacetOrdering(results, facetName);\n if (Boolean(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 }, facetValues, attributes);\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\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.} all the refinements\n */\nSearchResults.prototype.getRefinements = function() {\n var state = this._state;\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(getRefinement(state, 'facet', attributeName, name, results.facets));\n });\n });\n\n Object.keys(state.facetsExcludes).forEach(function(attributeName) {\n state.facetsExcludes[attributeName].forEach(function(name) {\n res.push(getRefinement(state, 'exclude', attributeName, name, results.facets));\n });\n });\n\n Object.keys(state.disjunctiveFacetsRefinements).forEach(function(attributeName) {\n state.disjunctiveFacetsRefinements[attributeName].forEach(function(name) {\n res.push(getRefinement(state, 'disjunctive', attributeName, name, results.disjunctiveFacets));\n });\n });\n\n Object.keys(state.hierarchicalFacetsRefinements).forEach(function(attributeName) {\n state.hierarchicalFacetsRefinements[attributeName].forEach(function(name) {\n res.push(getHierarchicalRefinement(state, attributeName, name, results.hierarchicalFacets));\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 {*} state\n * @param {*} type\n * @param {string} attributeName\n * @param {*} name\n * @param {Facet[]} resultsFacets\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 {*} state\n * @param {string} attributeName\n * @param {*} name\n * @param {Facet[]} resultsFacets\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 && 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\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\nvar EventEmitter = require('@algolia/events');\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 */\nfunction DerivedHelper(mainHelper, fn) {\n this.main = mainHelper;\n this.fn = fn;\n this.lastResults = 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\nmodule.exports = DerivedHelper;\n","'use strict';\n\nvar merge = require('./functions/merge');\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 * @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(state, refinedFacet)\n });\n });\n\n // maybe more to get the root level of hierarchical facets when activated\n state.getRefinedHierarchicalFacets().forEach(function(refinedFacet) {\n var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);\n\n var currentRefinement = state.getHierarchicalRefinement(refinedFacet);\n // if we are deeper than level 0 (starting from `beer > IPA`)\n // we want to get the root values\n var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);\n if (currentRefinement.length > 0 && currentRefinement[0].split(separator).length > 1) {\n queries.push({\n indexName: index,\n params: requestBuilder._getDisjunctiveFacetSearchParams(state, refinedFacet, true)\n });\n }\n });\n\n return queries;\n },\n\n /**\n * Build search parameters used to fetch hits\n * @private\n * @return {object.}\n */\n _getHitsSearchParams: function(state) {\n var facets = state.facets\n .concat(state.disjunctiveFacets)\n .concat(requestBuilder._getHitsHierarchicalFacetsAttributes(state));\n\n\n var facetFilters = requestBuilder._getFacetFilters(state);\n var numericFilters = requestBuilder._getNumericFilters(state);\n var tagFilters = requestBuilder._getTagFilters(state);\n var additionalParams = {\n facets: facets.indexOf('*') > -1 ? ['*'] : facets,\n 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 merge({}, state.getQueryParams(), additionalParams);\n },\n\n /**\n * Build search parameters used to fetch a disjunctive facet\n * @private\n * @param {string} facet the associated facet name\n * @param {boolean} hierarchicalRootLevel ?? FIXME\n * @return {object}\n */\n _getDisjunctiveFacetSearchParams: function(state, facet, hierarchicalRootLevel) {\n var facetFilters = requestBuilder._getFacetFilters(state, facet, hierarchicalRootLevel);\n var numericFilters = requestBuilder._getNumericFilters(state, facet);\n var tagFilters = requestBuilder._getTagFilters(state);\n var additionalParams = {\n hitsPerPage: 1,\n page: 0,\n attributesToRetrieve: [],\n attributesToHighlight: [],\n attributesToSnippet: [],\n tagFilters: tagFilters,\n analytics: false,\n clickAnalytics: false\n };\n\n var hierarchicalFacet = state.getHierarchicalFacetByName(facet);\n\n if (hierarchicalFacet) {\n additionalParams.facets = 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 merge({}, state.getQueryParams(), additionalParams);\n },\n\n /**\n * Return the numeric filters in an algolia request fashion\n * @private\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\n * @private\n * @return {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 /**\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 {string} [facet] if set, the current disjunctive facet\n * @return {array.}\n */\n _getFacetFilters: function(state, facet, hierarchicalRootLevel) {\n var facetFilters = [];\n\n var facetsRefinements = state.facetsRefinements || {};\n Object.keys(facetsRefinements).forEach(function(facetName) {\n var facetValues = facetsRefinements[facetName] || [];\n facetValues.forEach(function(facetValue) {\n facetFilters.push(facetName + ':' + facetValue);\n });\n });\n\n var facetsExcludes = state.facetsExcludes || {};\n Object.keys(facetsExcludes).forEach(function(facetName) {\n var facetValues = facetsExcludes[facetName] || [];\n facetValues.forEach(function(facetValue) {\n facetFilters.push(facetName + ':-' + facetValue);\n });\n });\n\n var disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements || {};\n Object.keys(disjunctiveFacetsRefinements).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.forEach(function(facetValue) {\n orFilters.push(facetName + ':' + facetValue);\n });\n\n facetFilters.push(orFilters);\n });\n\n var hierarchicalFacetsRefinements = state.hierarchicalFacetsRefinements || {};\n Object.keys(hierarchicalFacetsRefinements).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 (facetValue.indexOf(separator) === -1 || (!rootPath && hierarchicalRootLevel === true) ||\n (rootPath && rootPath.split(separator).length === facetValue.split(separator).length)) {\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(allAttributes, hierarchicalFacet) {\n var hierarchicalRefinement = state.getHierarchicalRefinement(hierarchicalFacet.name)[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 }, out);\n },\n\n _getDisjunctiveHierarchicalFacetAttribute: function(state, hierarchicalFacet, rootLevel) {\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 = 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 merge(\n {},\n requestBuilder._getHitsSearchParams(stateForSearchForFacetValues),\n searchForFacetSearchParameters\n );\n }\n};\n\nmodule.exports = requestBuilder;\n","'use strict';\n\nmodule.exports = '3.7.0';\n","'use strict';\n\nvar SearchParameters = require('./SearchParameters');\nvar SearchResults = require('./SearchResults');\nvar DerivedHelper = require('./DerivedHelper');\nvar requestBuilder = require('./requestBuilder');\n\nvar EventEmitter = require('@algolia/events');\nvar inherits = require('./functions/inherits');\nvar objectHasKeys = require('./functions/objectHasKeys');\nvar omit = require('./functions/omit');\nvar merge = require('./functions/merge');\n\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 */\nfunction AlgoliaSearchHelper(client, index, options) {\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.lastResults = null;\n this._queryId = 0;\n this._lastQueryIdReceived = -1;\n this.derivedHelpers = [];\n this._currentNbQueries = 0;\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}\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 * 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} [callback] 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 ? this.state : this.state.setQueryParameters(options);\n var queries = requestBuilder._getQueries(tempState.index, tempState);\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(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 }, function(e) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n throw e;\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 */\nAlgoliaSearchHelper.prototype.findAnswers = function(options) {\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' // FIXME remove this line once the engine is fixed.\n ])\n }\n );\n\n var errorMessage = '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.} the results of the search\n */\nAlgoliaSearchHelper.prototype.searchForFacetValues = function(facet, query, maxFacetHits, userState) {\n var clientHasSFFV = typeof this.client.searchForFacetValues === 'function';\n if (\n !clientHasSFFV &&\n typeof this.client.initIndex !== '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 var state = this.state.setQueryParameters(userState || {});\n var isDisjunctive = state.isDisjunctiveFacet(facet);\n var algoliaQuery = requestBuilder.getSearchForFacetQuery(facet, query, maxFacetHits, state);\n\n this._currentNbQueries++;\n var self = this;\n\n this.emit('searchForFacetValues', {\n state: state,\n facet: facet,\n query: query\n });\n\n var searchForFacetValuesPromise = clientHasSFFV\n ? this.client.searchForFacetValues([{indexName: state.index, params: algoliaQuery}])\n : this.client.initIndex(state.index).searchForFacetValues(algoliaQuery);\n\n return searchForFacetValuesPromise.then(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.isRefined = isDisjunctive\n ? state.isDisjunctiveFacetRefined(facet, f.value)\n : state.isFacetRefined(facet, f.value);\n });\n\n return content;\n }, function(e) {\n self._currentNbQueries--;\n if (self._currentNbQueries === 0) self.emit('searchQueueEmpty');\n throw e;\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}\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}\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}\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}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addDisjunctiveFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().addDisjunctiveFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\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}\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(facet, value) {\n this._change({\n state: this.state.resetPage().addHierarchicalFacetRefinement(facet, value),\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}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.addNumericRefinement = function(attribute, operator, value) {\n this._change({\n state: this.state.resetPage().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}\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/**\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/**\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}\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/**\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}\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 * 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}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeNumericRefinement = function(attribute, operator, value) {\n this._change({\n state: this.state.resetPage().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}\n * @fires change\n * @chainable\n */\nAlgoliaSearchHelper.prototype.removeDisjunctiveFacetRefinement = function(facet, value) {\n this._change({\n state: this.state.resetPage().removeDisjunctiveFacetRefinement(facet, value),\n isPageReset: true\n });\n\n return this;\n};\n\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}\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(facet) {\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}\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/**\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}\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/**\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}\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 * 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}\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/**\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}\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}\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/**\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}\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}\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}\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 */\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}\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}\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}\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}\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}\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}\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 = 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/**\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}\n */\nAlgoliaSearchHelper.prototype.hasTag = function(tag) {\n return this.state.isTagRefined(tag);\n};\n\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/**\n * Get the name of the currently used index.\n * @return {string}\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.} 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 disjRefinements = this.state.getDisjunctiveRefinements(facetName);\n\n disjRefinements.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.} refined values\n */\nAlgoliaSearchHelper.prototype.getNumericRefinement = function(attribute, operator) {\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.} the path as an array of string\n */\nAlgoliaSearchHelper.prototype.getHierarchicalFacetBreadcrumb = function(facetName) {\n return this.state.getHierarchicalFacetBreadcrumb(facetName);\n};\n\n// /////////// PRIVATE\n\n/**\n * Perform the underlying queries\n * @private\n * @return {undefined}\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 = requestBuilder._getQueries(derivedState.index, derivedState);\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 var queryId = this._queryId++;\n\n this._currentNbQueries++;\n\n try {\n this.client.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\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}>}\n * state state used for 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(states, queryId, content) {\n // FIXME 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 var formattedResponse = helper.lastResults = new SearchResults(state, specificResults);\n\n helper.emit('result', {\n results: formattedResponse,\n state: state\n });\n });\n};\n\nAlgoliaSearchHelper.prototype._dispatchAlgoliaError = function(queryId, error) {\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.containsRefinement = function(query, facetFilters, numericFilters, tagFilters) {\n return query ||\n facetFilters.length !== 0 ||\n numericFilters.length !== 0 ||\n tagFilters.length !== 0;\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}\n */\nAlgoliaSearchHelper.prototype._hasDisjunctiveRefinements = function(facet) {\n return this.state.disjunctiveRefinements[facet] &&\n this.state.disjunctiveRefinements[facet].length > 0;\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\n/**\n * Clears the cache of the underlying Algolia client.\n * @return {AlgoliaSearchHelper}\n */\nAlgoliaSearchHelper.prototype.clearCache = function() {\n 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}\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}\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 * @return {DerivedHelper}\n */\nAlgoliaSearchHelper.prototype.derive = function(fn) {\n var derivedHelper = new DerivedHelper(this, fn);\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 * @return {undefined}\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\nvar AlgoliaSearchHelper = require('./src/algoliasearch.helper');\n\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 * @return {AlgoliaSearchHelper}\n */\nfunction algoliasearchHelper(client, index, opts) {\n return new AlgoliaSearchHelper(client, index, opts);\n}\n\n/**\n * The version currently used\n * @member module:algoliasearchHelper.version\n * @type {number}\n */\nalgoliasearchHelper.version = require('./src/version.js');\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 the results of the search.\n * @member module:algoliasearchHelper.SearchResults\n * @type {SearchResults}\n */\nalgoliasearchHelper.SearchResults = SearchResults;\n\nmodule.exports = algoliasearchHelper;\n"],"names":["clone","value","_merge","isObjectOrArrayOrFunction","target","source","key","sourceVal","targetVal","merge","i","l","merge_1","defaultsPure","sources","acc","intersection","arr1","arr2","index","intersection_1","find","array","comparator","valToNumber","v","valToNumber_1","_objectWithoutPropertiesLoose","excluded","sourceKeys","omit","objectHasKeys","obj","objectHasKeys_1","isValidUserToken","userToken","require$$0","require$$1","require$$2","lib","refinementList","attribute","valueAsString","facetRefinement","mod","f","refinementType","hasChanged","newRefinementList","memo","values","facetList","refinementValue","containsRefinements","refinementValueAsString","RefinementList","require$$3","require$$4","require$$5","require$$6","require$$7","require$$8","isEqualNumericRefinement","a","b","el","findArray","searchedValue","currentValue","SearchParameters","newParameters","params","self","paramName","isKeyKnown","isValueDefined","partialState","numbers","numberKeys","k","parsedValue","geoRect","numericRefinements","operators","operator","parsedValues","vPrime","instance","hierarchicalFacets","facet","currentRefinement","currentState","parameters","patch","newQuery","newPage","facets","n","typoTolerance","facetName","paramValue","newNumericRefinements","operatorList","outValues","predicateResult","hierarchicalFacet","tag","modification","t","separator","upOneOrMultipleLevel","path","refinements","isOperatorDefined","isAttributeValueDefined","disjunctiveNumericRefinedFacets","refinedFacets","managedParameters","queryParams","parameter","error","nextWithNumbers","previousPlainObject","nextPlainObject","previous","isPreviousValueDefined","isNextValueDefined","hierarchicalFacetName","refinement","part","SearchParameters_1","compareAscending","other","valIsDefined","valIsNull","othIsDefined","othIsNull","orderBy","collection","iteratees","orders","result","iteratee","object","res","orderBy_1","compact","findIndex","formatSort","sortBy","defaults","defaultInstructions","sort","out","sortInstruction","matchingDefault","defaultInstruction","generateHierarchicalTree_1","generateTrees","prepareHierarchicalFacetSortBy","state","hierarchicalFacetResult","hierarchicalFacetIndex","hierarchicalFacetRefinement","hierarchicalSeparator","hierarchicalRootPath","hierarchicalShowParentLevel","rootExhaustive","facetResult","generateTreeFn","generateHierarchicalTree","results","hierarchicalTree","currentHierarchicalLevel","parent","level","data","subtree","picked","facetValue","tuple","onlyMatchingTree","facetCount","format","parentPath","exhaustive","parts","getIndices","attributes","indices","val","idx","assignFacetStats","dest","facetStats","findMatchingHierarchicalFacetFromAttributeName","hierarchicalAttributeName","facetNames","SearchResults","mainSubResponse","sum","disjunctiveFacets","facetsIndices","disjunctiveFacetsIndices","nextDisjunctiveResult","mainFacets","facetKey","facetValueObject","facetIndex","idxAttributeName","isFacetDisjunctive","isFacetConjunctive","position","disjunctiveFacet","dfacet","facetResults","attributeIndex","dataFromMainRequest","refinedFacet","defaultData","root","excludes","name","predicate","extractNormalizedFacetValues","recSort","sortFn","node","names","children","childNode","sortedChildren","newNode","vanillaSortFn","order","sortViaFacetOrdering","facetValues","facetOrdering","orderedFacets","remainingFacets","reverseOrder","item","sortRemainingBy","ordering","getFacetOrdering","opts","options","config","getFacetStatsIfAvailable","attributeName","getRefinement","getHierarchicalRefinement","type","resultsFacets","count","facetDeclaration","split","rootFacet","intermediateFacet","newFacet","SearchResults_1","inherits","ctor","superCtor","inherits_1","EventEmitter","DerivedHelper","mainHelper","fn","DerivedHelper_1","requestBuilder","queries","facetFilters","numericFilters","tagFilters","additionalParams","hierarchicalRootLevel","vs","facetsRefinements","facetsExcludes","disjunctiveFacetsRefinements","orFilters","hierarchicalFacetsRefinements","rootPath","attributeToRefine","attributesIndex","allAttributes","hierarchicalRefinement","newAttributes","rootLevel","parentLevel","query","maxFacetHits","stateForSearchForFacetValues","searchForFacetSearchParameters","requestBuilder_1","version","require$$9","AlgoliaSearchHelper","client","cb","tempState","content","err","e","derivedHelper","derivedState","errorMessage","userState","clientHasSFFV","isDisjunctive","algoliaQuery","searchForFacetValuesPromise","q","page","setCurrentPage","newState","getCurrentPage","conjRefinements","r","excludeRefinements","disjRefinements","states","mainQueries","derivedQueries","derivedStateQueries","queryId","s","queriesCount","helper","specificResults","formattedResponse","event","isPageReset","newClient","pos","algoliasearch_helper","algoliasearchHelper","algoliasearchHelper_1"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]}