{"version":3,"sources":["node_modules/browser-pack/_prelude.js","index.js","node_modules/events/events.js","src/DerivedHelper/index.js","src/SearchParameters/RefinementList.js","src/SearchParameters/index.js","src/SearchResults/generate-hierarchical-tree.js","src/SearchResults/index.js","src/algoliasearch.helper.js","src/functions/compact.js","src/functions/defaultsPure.js","src/functions/find.js","src/functions/findIndex.js","src/functions/formatSort.js","src/functions/inherits.js","src/functions/intersection.js","src/functions/merge.js","src/functions/objectHasKeys.js","src/functions/omit.js","src/functions/orderBy.js","src/functions/valToNumber.js","src/requestBuilder.js","src/version.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","algoliasearchHelper","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length","1","client","index","opts","AlgoliaSearchHelper","SearchParameters","SearchResults","version","EventEmitter","_events","_maxListeners","undefined","isFunction","arg","isNumber","isObject","isUndefined","prototype","defaultMaxListeners","setMaxListeners","isNaN","TypeError","emit","type","er","handler","len","args","listeners","error","arguments","err","context","Array","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","removeListener","fired","list","position","splice","removeAllListeners","key","listenerCount","evlistener","emitter","DerivedHelper","mainHelper","fn","main","lastResults","events","detach","detachDerivedHelper","getModifiedState","parameters","defaultsPure","omit","objectHasKeys","lib","addRefinement","refinementList","attribute","value","isRefined","valueAsString","facetRefinement","concat","mod","removeRefinement","clearRefinement","v","toggleRefinement","refinementType","hasChanged","newRefinementList","Object","keys","reduce","memo","values","facetList","filter","refinementValue","containsRefinements","refinementValueAsString","indexOf","isEqualNumericRefinement","b","isArray","every","el","findArray","array","searchedValue","find","currentValue","newParameters","params","_parseNumbers","facets","disjunctiveFacets","hierarchicalFacets","facetsRefinements","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements","forEach","paramName","isKeyKnown","PARAMETERS","isValueDefined","merge","intersection","valToNumber","RefinementList","partialState","numbers","k","parsedValue","parseFloat","insideBoundingBox","map","geoRect","operators","operator","parsedValues","vPrime","make","instance","facet","rootPath","currentRefinement","getHierarchicalRefinement","name","clearRefinements","toggleHierarchicalFacetRefinement","validate","currentState","tagFilters","numericFilters","constructor","patch","_clearNumericRefinements","setQueryParameters","clearTags","setIndex","setQuery","newQuery","query","setPage","newPage","page","setFacets","setDisjunctiveFacets","setHitsPerPage","hitsPerPage","setTypoTolerance","typoTolerance","addNumericRefinement","isNumericRefined","getConjunctiveRefinements","facetName","isConjunctiveFacet","getDisjunctiveRefinements","isDisjunctiveFacet","getExcludeRefinements","removeNumericRefinement","paramValue","op","val","getNumericRefinements","getNumericRefinement","newNumericRefinements","operatorList","outValues","addFacet","addDisjunctiveFacet","addHierarchicalFacet","hierarchicalFacet","isHierarchicalFacet","addFacetRefinement","addExcludeRefinement","addDisjunctiveFacetRefinement","addTagRefinement","tag","isTagRefined","modification","removeFacet","removeDisjunctiveFacet","removeHierarchicalFacet","removeFacetRefinement","removeExcludeRefinement","removeDisjunctiveFacetRefinement","removeTagRefinement","toggleFacetRefinement","toggleConjunctiveFacetRefinement","toggleDisjunctiveFacetRefinement","toggleExcludeFacetRefinement","separator","_getHierarchicalFacetSeparator","getHierarchicalFacetByName","lastIndexOf","addHierarchicalFacetRefinement","path","isHierarchicalFacetRefined","removeHierarchicalFacetRefinement","toggleTagRefinement","isFacetRefined","isExcludeRefined","isDisjunctiveFacetRefined","refinements","isOperatorDefined","isAttributeValueDefined","getRefinedDisjunctiveFacets","disjunctiveNumericRefinedFacets","getRefinedHierarchicalFacets","getUnrefinedDisjunctiveFacets","refinedFacets","managedParameters","getQueryParams","queryParams","setQueryParameter","parameter","nextWithNumbers","previousPlainObject","acc","nextPlainObject","previous","isPreviousValueDefined","isNextValueDefined","resetPage","_getHierarchicalFacetSortBy","sortBy","_getHierarchicalRootPath","_getHierarchicalShowParentLevel","showParentLevel","hierarchicalFacetName","getHierarchicalFacetBreadcrumb","refinement","split","part","trim","toString","JSON","stringify","generateTrees","state","hierarchicalFacetResult","hierarchicalFacetIndex","hierarchicalFacetRefinement","hierarchicalSeparator","hierarchicalRootPath","hierarchicalShowParentLevel","prepareHierarchicalFacetSortBy","rootExhaustive","facetResult","exhaustive","generateTreeFn","generateHierarchicalTree","results","count","data","hierarchicalTree","currentHierarchicalLevel","parent","level","subtree","picked","facetValue","tuple","onlyMatchingTree","orderBy","format","parentPath","facetCount","parts","getIndices","attributes","indices","idx","assignFacetStats","dest","facetStats","stats","findMatchingHierarchicalFacetFromAttributeName","hierarchicalAttributeName","mainSubResponse","_rawResults","parsedQuery","hits","nbHits","nbPages","processingTimeMS","sum","result","aroundLatLng","automaticRadius","serverUsed","timeoutCounts","timeoutHits","exhaustiveFacetsCount","exhaustiveNbHits","userData","queryID","facetsIndices","disjunctiveFacetsIndices","nextDisjunctiveResult","mainFacets","facetKey","facetValueObject","facetIndex","idxAttributeName","findIndex","isFacetDisjunctive","isFacetConjunctive","facets_stats","compact","disjunctiveFacet","dfacet","facetResults","attributeIndex","dataFromMainRequest","refinedFacet","defaultData","root","excludes","_state","extractNormalizedFacetValues","predicate","isExcluded","recSort","sortFn","node","children","childNode","sortedChildren","vanillaSortFn","order","sort","getFacetStatsIfAvailable","getRefinement","attributeName","resultsFacets","facetDeclaration","rootFacet","intermediateFacet","newFacet","formatSort","getFacetByName","DEFAULT_SORT","getFacetValues","facetValues","options","hierarchicalFacetValues","getFacetStats","getRefinements","res","numericValue","addAlgoliaAgent","setClient","_queryId","_lastQueryIdReceived","derivedHelpers","_currentNbQueries","setCurrentPage","_change","isPageReset","getCurrentPage","requestBuilder","inherits","search","_search","onlyWithDerivedHelpers","searchOnlyWithDerivedHelpers","getQuery","_getHitsSearchParams","searchOnce","cb","tempState","queries","_getQueries","then","content","catch","_originalResponse","searchForFacetValues","maxFacetHits","userState","clientHasSFFV","initIndex","isDisjunctive","algoliaQuery","getSearchForFacetQuery","indexName","facetHits","q","addDisjunctiveRefine","addRefine","addFacetExclusion","addExclude","addTag","removeDisjunctiveRefine","removeRefine","removeFacetExclusion","removeExclude","removeTag","toggleFacetExclusion","toggleExclude","toggleRefine","toggleTag","nextPage","previousPage","setState","newState","overrideStateWithoutTriggeringChangeEvent","hasRefinements","isDisjunctiveRefined","hasTag","hasTagRefinements","getIndex","getPage","getTags","disjRefinements","states","mainQueries","queriesCount","helper","derivedQueries","derivedHelper","derivedState","derivedStateQueries","queryId","_dispatchAlgoliaResponse","bind","_dispatchAlgoliaError","specificResults","formattedResponse","containsRefinement","facetFilters","_hasDisjunctiveRefinements","disjunctiveRefinements","event","clearCache","newClient","getClient","derive","pos","hasPendingRequests","Boolean","source","hasOwnProperty","comparator","defaults","defaultInstructions","out","sortInstruction","matchingDefault","defaultInstruction","ctor","superCtor","create","enumerable","writable","configurable","arr1","arr2","clone","_merge","isObjectOrArrayOrFunction","target","sourceVal","targetVal","obj","_objectWithoutPropertiesLoose","excluded","sourceKeys","compareAscending","other","valIsDefined","valIsNull","othIsDefined","othIsNull","collection","iteratees","orders","criteria","iteratee","object","_getDisjunctiveFacetSearchParams","_getHitsHierarchicalFacetsAttributes","_getFacetFilters","_getNumericFilters","_getTagFilters","additionalParams","hierarchicalRootLevel","attributesToRetrieve","attributesToHighlight","attributesToSnippet","analytics","clickAnalytics","_getDisjunctiveHierarchicalFacetAttribute","vs","join","orFilters","attributeToRefine","attributesIndex","allAttributes","hierarchicalRefinement","newAttributes","rootLevel","parentLevel","stateForSearchForFacetValues","searchForFacetSearchParameters","facetQuery"],"mappings":"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","file":"dist/algoliasearch.helper.min.js","sourceRoot":"","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","'use strict';\n\nvar events = require('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, events.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\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');\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 /**\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 return geoRect.map(function(value) {\n return parseFloat(value);\n });\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 if (!objectHasKeys(this.numericRefinements[attribute])) {\n return this.numericRefinements;\n }\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 'facets', 'disjunctiveFacets', 'facetsRefinements',\n 'facetsExcludes', 'disjunctiveFacetsRefinements',\n 'numericRefinements', 'tagRefinements', 'hierarchicalFacets', '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\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 /**\n * query used to generate the results\n * @member {string}\n */\n this.query = mainSubResponse.query;\n /**\n * The query as parsed by the engine given all the rules.\n * @member {string}\n */\n this.parsedQuery = mainSubResponse.parsedQuery;\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 * @member {object[]}\n */\n this.hits = mainSubResponse.hits;\n /**\n * index where the results come from\n * @member {string}\n */\n this.index = mainSubResponse.index;\n /**\n * number of hits per page requested\n * @member {number}\n */\n this.hitsPerPage = mainSubResponse.hitsPerPage;\n /**\n * total number of hits of this query on the index\n * @member {number}\n */\n this.nbHits = mainSubResponse.nbHits;\n /**\n * total number of pages with respect to the number of hits per page and the total number of hits\n * @member {number}\n */\n this.nbPages = mainSubResponse.nbPages;\n /**\n * current page\n * @member {number}\n */\n this.page = mainSubResponse.page;\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 * The position if the position was guessed by IP.\n * @member {string}\n * @example \"48.8637,2.3615\",\n */\n this.aroundLatLng = mainSubResponse.aroundLatLng;\n /**\n * The radius computed by Algolia.\n * @member {string}\n * @example \"126792922\",\n */\n this.automaticRadius = mainSubResponse.automaticRadius;\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 * @member {string}\n * @example \"c7-use-2.algolia.net\",\n */\n this.serverUsed = mainSubResponse.serverUsed;\n /**\n * Boolean that indicates if the computation of the counts did time out.\n * @deprecated\n * @member {boolean}\n */\n this.timeoutCounts = mainSubResponse.timeoutCounts;\n /**\n * Boolean that indicates if the computation of the hits did time out.\n * @deprecated\n * @member {boolean}\n */\n this.timeoutHits = mainSubResponse.timeoutHits;\n\n /**\n * True if the counts of the facets is exhaustive\n * @member {boolean}\n */\n this.exhaustiveFacetsCount = mainSubResponse.exhaustiveFacetsCount;\n\n /**\n * True if the number of hits is exhaustive\n * @member {boolean}\n */\n this.exhaustiveNbHits = mainSubResponse.exhaustiveNbHits;\n\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 * @member {object[]}\n */\n this.userData = mainSubResponse.userData;\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 * @member {string}\n */\n this.queryID = mainSubResponse.queryID;\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 var self = this;\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 facet results\n * @private\n * @param {HierarchicalFacet} node node to upon which we want to apply the sort\n */\nfunction recSort(sortFn, node) {\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);\n });\n var sortedChildren = sortFn(children);\n var newNode = merge({}, node, {data: sortedChildren});\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 * 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 {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, {sortBy: SearchResults.DEFAULT_SORT});\n\n if (Array.isArray(options.sortBy)) {\n var order = formatSort(options.sortBy, SearchResults.DEFAULT_SORT);\n if (Array.isArray(facetValues)) {\n return orderBy(facetValues, order[0], order[1]);\n }\n // If facetValues is not an array, it's an object thus a hierarchical facet object\n return recSort(function(hierarchicalFacetValues) {\n return orderBy(hierarchicalFacetValues, order[0], order[1]);\n }, facetValues);\n } else if (typeof options.sortBy === 'function') {\n if (Array.isArray(facetValues)) {\n return facetValues.sort(options.sortBy);\n }\n // If facetValues is not an array, it's an object thus a hierarchical facet object\n return recSort(function(data) {\n return vanillaSortFn(options.sortBy, data);\n }, facetValues);\n }\n throw new Error(\n 'options.sortBy is optional but if defined it must be ' +\n 'either an array of string (predicates) or a sorting function'\n );\n};\n\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\nvar SearchParameters = require('./SearchParameters');\nvar SearchResults = require('./SearchResults');\nvar DerivedHelper = require('./DerivedHelper');\nvar requestBuilder = require('./requestBuilder');\n\nvar events = require('events');\nvar inherits = require('./functions/inherits');\nvar objectHasKeys = require('./functions/objectHasKeys');\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, events.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 * 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\nmodule.exports = function compact(array) {\n if (!Array.isArray(array)) {\n return [];\n }\n\n return array.filter(Boolean);\n};\n","'use strict';\n\n// NOTE: this behaves like lodash/defaults, but doesn't mutate the target\n// it also preserve keys order\nmodule.exports = function defaultsPure() {\n var sources = Array.prototype.slice.call(arguments);\n return sources.reduce(function(acc, source) {\n Object.keys(Object(source)).forEach(function(key) {\n if (source[key] !== undefined && !Object.hasOwnProperty.call(acc, key)) {\n acc[key] = source[key];\n }\n });\n return acc;\n }, {});\n};\n","'use strict';\n\n// @MAJOR can be replaced by native Array#find when we change support\nmodule.exports = function find(array, comparator) {\n if (!Array.isArray(array)) {\n return undefined;\n }\n\n for (var i = 0; i < array.length; i++) {\n if (comparator(array[i])) {\n return array[i];\n }\n }\n};\n","'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\nfunction inherits(ctor, superCtor) {\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n}\n\nmodule.exports = inherits;\n","'use strict';\n\nfunction intersection(arr1, arr2) {\n return arr1.filter(function(value, index) {\n return (\n arr2.indexOf(value) > -1 &&\n arr1.indexOf(value) === index /* skips duplicates */\n );\n });\n}\n\nmodule.exports = intersection;\n","'use strict';\n\nfunction clone(value) {\n if (typeof value === 'object' && value !== null) {\n return _merge(Array.isArray(value) ? [] : {}, value);\n }\n return value;\n}\n\nfunction isObjectOrArrayOrFunction(value) {\n return (\n typeof value === 'function' ||\n Array.isArray(value) ||\n Object.prototype.toString.call(value) === '[object Object]'\n );\n}\n\nfunction _merge(target, source) {\n if (target === source) {\n return target;\n }\n\n for (var key in source) {\n if (!Object.prototype.hasOwnProperty.call(source, key)) {\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 (isObjectOrArrayOrFunction(targetVal) && isObjectOrArrayOrFunction(sourceVal)) {\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\nfunction objectHasKeys(obj) {\n return obj && Object.keys(obj).length > 0;\n}\n\nmodule.exports = objectHasKeys;\n","'use strict';\n\n// https://github.com/babel/babel/blob/3aaafae053fa75febb3aa45d45b6f00646e30ba4/packages/babel-helpers/src/helpers.js#L604-L620\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source === null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key;\n var i;\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n return target;\n}\n\nmodule.exports = _objectWithoutPropertiesLoose;\n","'use strict';\n\nfunction compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined;\n var valIsNull = value === null;\n\n var othIsDefined = other !== undefined;\n var othIsNull = other === null;\n\n if (\n (!othIsNull && value > other) ||\n (valIsNull && othIsDefined) ||\n !valIsDefined\n ) {\n return 1;\n }\n if (\n (!valIsNull && value < other) ||\n (othIsNull && valIsDefined) ||\n !othIsDefined\n ) {\n return -1;\n }\n }\n return 0;\n}\n\n/**\n * @param {Array} 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\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\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,\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.1.2';\n"]}