/*! @algolia/autocomplete-plugin-algolia-insights 1.19.8 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@algolia/autocomplete-plugin-algolia-insights"] = {}));
})(this, (function (exports) { 'use strict';

  function _arrayLikeToArray(r, a) {
    (null == a || a > r.length) && (a = r.length);
    for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
    return n;
  }
  function _arrayWithHoles(r) {
    if (Array.isArray(r)) return r;
  }
  function _arrayWithoutHoles(r) {
    if (Array.isArray(r)) return _arrayLikeToArray(r);
  }
  function _defineProperty(e, r, t) {
    return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
      value: t,
      enumerable: !0,
      configurable: !0,
      writable: !0
    }) : e[r] = t, e;
  }
  function _iterableToArray(r) {
    if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
  }
  function _iterableToArrayLimit(r, l) {
    var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
    if (null != t) {
      var e,
        n,
        i,
        u,
        a = [],
        f = !0,
        o = !1;
      try {
        if (i = (t = t.call(r)).next, 0 === l) {
          if (Object(t) !== t) return;
          f = !1;
        } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
      } catch (r) {
        o = !0, n = r;
      } finally {
        try {
          if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
        } finally {
          if (o) throw n;
        }
      }
      return a;
    }
  }
  function _nonIterableRest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }
  function _nonIterableSpread() {
    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }
  function ownKeys(e, r) {
    var t = Object.keys(e);
    if (Object.getOwnPropertySymbols) {
      var o = Object.getOwnPropertySymbols(e);
      r && (o = o.filter(function (r) {
        return Object.getOwnPropertyDescriptor(e, r).enumerable;
      })), t.push.apply(t, o);
    }
    return t;
  }
  function _objectSpread2(e) {
    for (var r = 1; r < arguments.length; r++) {
      var t = null != arguments[r] ? arguments[r] : {};
      r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
        _defineProperty(e, r, t[r]);
      }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
        Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
      });
    }
    return e;
  }
  function _objectWithoutProperties(e, t) {
    if (null == e) return {};
    var o,
      r,
      i = _objectWithoutPropertiesLoose(e, t);
    if (Object.getOwnPropertySymbols) {
      var n = Object.getOwnPropertySymbols(e);
      for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
    }
    return i;
  }
  function _objectWithoutPropertiesLoose(r, e) {
    if (null == r) return {};
    var t = {};
    for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
      if (-1 !== e.indexOf(n)) continue;
      t[n] = r[n];
    }
    return t;
  }
  function _slicedToArray(r, e) {
    return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
  }
  function _toConsumableArray(r) {
    return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
  }
  function _toPrimitive(t, r) {
    if ("object" != typeof t || !t) return t;
    var e = t[Symbol.toPrimitive];
    if (void 0 !== e) {
      var i = e.call(t, r || "default");
      if ("object" != typeof i) return i;
      throw new TypeError("@@toPrimitive must return a primitive value.");
    }
    return ("string" === r ? String : Number)(t);
  }
  function _toPropertyKey(t) {
    var i = _toPrimitive(t, "string");
    return "symbol" == typeof i ? i : i + "";
  }
  function _unsupportedIterableToArray(r, a) {
    if (r) {
      if ("string" == typeof r) return _arrayLikeToArray(r, a);
      var t = {}.toString.call(r).slice(8, -1);
      return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
    }
  }

  function createRef(initialValue) {
    return {
      current: initialValue
    };
  }

  function debounce(fn, time) {
    var timerId = undefined;
    return function () {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
      if (timerId) {
        clearTimeout(timerId);
      }
      timerId = setTimeout(function () {
        return fn.apply(void 0, args);
      }, time);
    };
  }

  function isPrimitive(obj) {
    return obj !== Object(obj);
  }
  function isEqual(first, second) {
    if (first === second) {
      return true;
    }
    if (isPrimitive(first) || isPrimitive(second) || typeof first === 'function' || typeof second === 'function') {
      return first === second;
    }
    if (Object.keys(first).length !== Object.keys(second).length) {
      return false;
    }
    for (var _i = 0, _Object$keys = Object.keys(first); _i < _Object$keys.length; _i++) {
      var key = _Object$keys[_i];
      if (!(key in second)) {
        return false;
      }
      if (!isEqual(first[key], second[key])) {
        return false;
      }
    }
    return true;
  }

  var noop = function noop() {};

  /**
   * Safely runs code meant for browser environments only.
   */
  function safelyRunOnBrowser(callback) {
    if (typeof window !== 'undefined') {
      return callback({
        window: window
      });
    }
    return undefined;
  }

  function createClickedEvent(_ref) {
    var item = _ref.item,
      _ref$items = _ref.items,
      items = _ref$items === void 0 ? [] : _ref$items;
    return {
      index: item.__autocomplete_indexName,
      items: [item],
      positions: [1 + items.findIndex(function (x) {
        return x.objectID === item.objectID;
      })],
      queryID: item.__autocomplete_queryID,
      algoliaSource: ['autocomplete']
    };
  }

  /**
   * Determines if a given insights `client` supports the optional call to `init`
   * and the ability to set credentials via extra parameters when sending events.
   */
  function isModernInsightsClient(client) {
    var _split$map = (client.version || '').split('.').map(Number),
      _split$map2 = _slicedToArray(_split$map, 2),
      major = _split$map2[0],
      minor = _split$map2[1];

    /* eslint-disable @typescript-eslint/camelcase */
    var v3 = major >= 3;
    var v2_4 = major === 2 && minor >= 4;
    var v1_10 = major === 1 && minor >= 10;
    return v3 || v2_4 || v1_10;
    /* eslint-enable @typescript-eslint/camelcase */
  }

  var _excluded = ["items"],
    _excluded2 = ["items"];
  function chunk(item) {
    var chunkSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20;
    var chunks = [];
    for (var i = 0; i < item.objectIDs.length; i += chunkSize) {
      chunks.push(_objectSpread2(_objectSpread2({}, item), {}, {
        objectIDs: item.objectIDs.slice(i, i + chunkSize)
      }));
    }
    return chunks;
  }
  function mapToInsightsParamsApi(params) {
    return params.map(function (_ref) {
      var items = _ref.items,
        param = _objectWithoutProperties(_ref, _excluded);
      return _objectSpread2(_objectSpread2({}, param), {}, {
        objectIDs: (items === null || items === void 0 ? void 0 : items.map(function (_ref2) {
          var objectID = _ref2.objectID;
          return objectID;
        })) || param.objectIDs
      });
    });
  }
  function createSearchInsightsApi(searchInsights) {
    var canSendHeaders = isModernInsightsClient(searchInsights);
    function sendToInsights(method, payloads, items) {
      if (canSendHeaders && typeof items !== 'undefined') {
        var _items$0$__autocomple = items[0].__autocomplete_algoliaCredentials,
          appId = _items$0$__autocomple.appId,
          apiKey = _items$0$__autocomple.apiKey;
        var headers = {
          'X-Algolia-Application-Id': appId,
          'X-Algolia-API-Key': apiKey
        };
        searchInsights.apply(void 0, [method].concat(_toConsumableArray(payloads), [{
          headers: headers
        }]));
      } else {
        searchInsights.apply(void 0, [method].concat(_toConsumableArray(payloads)));
      }
    }
    return {
      /**
       * Initializes Insights with Algolia credentials.
       */
      init: function init(appId, apiKey) {
        searchInsights('init', {
          appId: appId,
          apiKey: apiKey
        });
      },
      /**
       * Sets the authenticated user token to attach to events.
       * Unsets the authenticated token by passing `undefined`.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/set-authenticated-user-token/
       */
      setAuthenticatedUserToken: function setAuthenticatedUserToken(authenticatedUserToken) {
        searchInsights('setAuthenticatedUserToken', authenticatedUserToken);
      },
      /**
       * Sets the user token to attach to events.
       */
      setUserToken: function setUserToken(userToken) {
        searchInsights('setUserToken', userToken);
      },
      /**
       * Sends click events to capture a query and its clicked items and positions.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/clicked-object-ids-after-search/
       */
      clickedObjectIDsAfterSearch: function clickedObjectIDsAfterSearch() {
        for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
          params[_key] = arguments[_key];
        }
        if (params.length > 0) {
          sendToInsights('clickedObjectIDsAfterSearch', mapToInsightsParamsApi(params), params[0].items);
        }
      },
      /**
       * Sends click events to capture clicked items.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/clicked-object-ids/
       */
      clickedObjectIDs: function clickedObjectIDs() {
        for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
          params[_key2] = arguments[_key2];
        }
        if (params.length > 0) {
          sendToInsights('clickedObjectIDs', mapToInsightsParamsApi(params), params[0].items);
        }
      },
      /**
       * Sends click events to capture the filters a user clicks on.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/clicked-filters/
       */
      clickedFilters: function clickedFilters() {
        for (var _len3 = arguments.length, params = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
          params[_key3] = arguments[_key3];
        }
        if (params.length > 0) {
          searchInsights.apply(void 0, ['clickedFilters'].concat(params));
        }
      },
      /**
       * Sends conversion events to capture a query and its clicked items.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/converted-object-ids-after-search/
       */
      convertedObjectIDsAfterSearch: function convertedObjectIDsAfterSearch() {
        for (var _len4 = arguments.length, params = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
          params[_key4] = arguments[_key4];
        }
        if (params.length > 0) {
          sendToInsights('convertedObjectIDsAfterSearch', mapToInsightsParamsApi(params), params[0].items);
        }
      },
      /**
       * Sends conversion events to capture clicked items.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/converted-object-ids/
       */
      convertedObjectIDs: function convertedObjectIDs() {
        for (var _len5 = arguments.length, params = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
          params[_key5] = arguments[_key5];
        }
        if (params.length > 0) {
          sendToInsights('convertedObjectIDs', mapToInsightsParamsApi(params), params[0].items);
        }
      },
      /**
       * Sends conversion events to capture the filters a user uses when converting.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/converted-filters/
       */
      convertedFilters: function convertedFilters() {
        for (var _len6 = arguments.length, params = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
          params[_key6] = arguments[_key6];
        }
        if (params.length > 0) {
          searchInsights.apply(void 0, ['convertedFilters'].concat(params));
        }
      },
      /**
       * Sends view events to capture clicked items.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/viewed-object-ids/
       */
      viewedObjectIDs: function viewedObjectIDs() {
        for (var _len7 = arguments.length, params = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
          params[_key7] = arguments[_key7];
        }
        if (params.length > 0) {
          params.reduce(function (acc, _ref3) {
            var items = _ref3.items,
              param = _objectWithoutProperties(_ref3, _excluded2);
            return [].concat(_toConsumableArray(acc), _toConsumableArray(chunk(_objectSpread2(_objectSpread2({}, param), {}, {
              objectIDs: (items === null || items === void 0 ? void 0 : items.map(function (_ref4) {
                var objectID = _ref4.objectID;
                return objectID;
              })) || param.objectIDs
            })).map(function (payload) {
              return {
                items: items,
                payload: payload
              };
            })));
          }, []).forEach(function (_ref5) {
            var items = _ref5.items,
              payload = _ref5.payload;
            return sendToInsights('viewedObjectIDs', [payload], items);
          });
        }
      },
      /**
       * Sends view events to capture the filters a user uses when viewing.
       *
       * @link https://www.algolia.com/doc/api-reference/api-methods/viewed-filters/
       */
      viewedFilters: function viewedFilters() {
        for (var _len8 = arguments.length, params = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
          params[_key8] = arguments[_key8];
        }
        if (params.length > 0) {
          searchInsights.apply(void 0, ['viewedFilters'].concat(params));
        }
      }
    };
  }

  function createViewedEvents(_ref) {
    var items = _ref.items;
    var itemsByIndexName = items.reduce(function (acc, current) {
      var _acc$current$__autoco;
      acc[current.__autocomplete_indexName] = ((_acc$current$__autoco = acc[current.__autocomplete_indexName]) !== null && _acc$current$__autoco !== void 0 ? _acc$current$__autoco : []).concat(current);
      return acc;
    }, {});
    return Object.keys(itemsByIndexName).map(function (indexName) {
      var items = itemsByIndexName[indexName];
      return {
        index: indexName,
        items: items,
        algoliaSource: ['autocomplete']
      };
    });
  }

  function isAlgoliaInsightsHit(hit) {
    return hit.objectID && hit.__autocomplete_indexName && hit.__autocomplete_queryID;
  }

  var VIEW_EVENT_DELAY = 400;
  var ALGOLIA_INSIGHTS_VERSION = '2.15.0';
  var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@".concat(ALGOLIA_INSIGHTS_VERSION, "/dist/search-insights.min.js");
  var sendViewedObjectIDs = debounce(function (_ref) {
    var onItemsChange = _ref.onItemsChange,
      items = _ref.items,
      insights = _ref.insights,
      state = _ref.state;
    onItemsChange({
      insights: insights,
      insightsEvents: createViewedEvents({
        items: items
      }).map(function (event) {
        return _objectSpread2({
          eventName: 'Items Viewed'
        }, event);
      }),
      state: state
    });
  }, VIEW_EVENT_DELAY);
  function createAlgoliaInsightsPlugin(options) {
    var _getOptions = getOptions(options),
      providedInsightsClient = _getOptions.insightsClient,
      insightsInitParams = _getOptions.insightsInitParams,
      onItemsChange = _getOptions.onItemsChange,
      onSelectEvent = _getOptions.onSelect,
      onActiveEvent = _getOptions.onActive,
      __autocomplete_clickAnalytics = _getOptions.__autocomplete_clickAnalytics;
    var insightsClient = providedInsightsClient;
    if (!providedInsightsClient) {
      safelyRunOnBrowser(function (_ref2) {
        var window = _ref2.window;
        var pointer = window.AlgoliaAnalyticsObject || 'aa';
        if (typeof pointer === 'string') {
          insightsClient = window[pointer];
        }
        if (!insightsClient) {
          window.AlgoliaAnalyticsObject = pointer;
          if (!window[pointer]) {
            window[pointer] = function () {
              if (!window[pointer].queue) {
                window[pointer].queue = [];
              }
              for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
                args[_key] = arguments[_key];
              }
              window[pointer].queue.push(args);
            };
          }
          window[pointer].version = ALGOLIA_INSIGHTS_VERSION;
          insightsClient = window[pointer];
          loadInsights(window);
        }
      });
    }

    // We return an empty plugin if `insightsClient` is still undefined at
    // this stage, which can happen in server environments.
    if (!insightsClient) {
      return {};
    }
    if (insightsInitParams) {
      insightsClient('init', _objectSpread2({
        partial: true
      }, insightsInitParams));
    }
    var insights = createSearchInsightsApi(insightsClient);
    var previousItems = createRef([]);
    var debouncedOnStateChange = debounce(function (_ref3) {
      var state = _ref3.state;
      if (!state.isOpen) {
        return;
      }
      var items = state.collections.reduce(function (acc, current) {
        return [].concat(_toConsumableArray(acc), _toConsumableArray(current.items));
      }, []).filter(isAlgoliaInsightsHit);
      if (!isEqual(previousItems.current.map(function (x) {
        return x.objectID;
      }), items.map(function (x) {
        return x.objectID;
      }))) {
        previousItems.current = items;
        if (items.length > 0) {
          sendViewedObjectIDs({
            onItemsChange: onItemsChange,
            items: items,
            insights: insights,
            state: state
          });
        }
      }
    }, 0);
    return {
      name: 'aa.algoliaInsightsPlugin',
      subscribe: function subscribe(_ref4) {
        var setContext = _ref4.setContext,
          onSelect = _ref4.onSelect,
          onActive = _ref4.onActive;
        function setInsightsContext(userToken) {
          setContext({
            algoliaInsightsPlugin: {
              __algoliaSearchParameters: _objectSpread2(_objectSpread2({}, __autocomplete_clickAnalytics ? {
                clickAnalytics: true
              } : {}), userToken ? {
                userToken: normalizeUserToken(userToken)
              } : {}),
              insights: insights
            }
          });
        }
        insightsClient('addAlgoliaAgent', 'insights-plugin');
        setInsightsContext();

        // Handles user token changes
        insightsClient('onUserTokenChange', function (userToken) {
          setInsightsContext(userToken);
        });
        insightsClient('getUserToken', null, function (_error, userToken) {
          setInsightsContext(userToken);
        });
        onSelect(function (_ref5) {
          var item = _ref5.item,
            state = _ref5.state,
            event = _ref5.event,
            source = _ref5.source;
          if (!isAlgoliaInsightsHit(item)) {
            return;
          }
          onSelectEvent({
            state: state,
            event: event,
            insights: insights,
            item: item,
            insightsEvents: [_objectSpread2({
              eventName: 'Item Selected'
            }, createClickedEvent({
              item: item,
              items: source.getItems().filter(isAlgoliaInsightsHit)
            }))]
          });
        });
        onActive(function (_ref6) {
          var item = _ref6.item,
            source = _ref6.source,
            state = _ref6.state,
            event = _ref6.event;
          if (!isAlgoliaInsightsHit(item)) {
            return;
          }
          onActiveEvent({
            state: state,
            event: event,
            insights: insights,
            item: item,
            insightsEvents: [_objectSpread2({
              eventName: 'Item Active'
            }, createClickedEvent({
              item: item,
              items: source.getItems().filter(isAlgoliaInsightsHit)
            }))]
          });
        });
      },
      onStateChange: function onStateChange(_ref7) {
        var state = _ref7.state;
        debouncedOnStateChange({
          state: state
        });
      },
      __autocomplete_pluginOptions: options
    };
  }
  function getAlgoliaSources() {
    var _context$algoliaInsig;
    var algoliaSourceBase = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
    var context = arguments.length > 1 ? arguments[1] : undefined;
    return [].concat(_toConsumableArray(algoliaSourceBase), ['autocomplete-internal'], _toConsumableArray((_context$algoliaInsig = context.algoliaInsightsPlugin) !== null && _context$algoliaInsig !== void 0 && _context$algoliaInsig.__automaticInsights ? ['autocomplete-automatic'] : []));
  }
  function getOptions(options) {
    return _objectSpread2({
      onItemsChange: function onItemsChange(_ref8) {
        var insights = _ref8.insights,
          insightsEvents = _ref8.insightsEvents,
          state = _ref8.state;
        insights.viewedObjectIDs.apply(insights, _toConsumableArray(insightsEvents.map(function (event) {
          return _objectSpread2(_objectSpread2({}, event), {}, {
            algoliaSource: getAlgoliaSources(event.algoliaSource, state.context)
          });
        })));
      },
      onSelect: function onSelect(_ref9) {
        var insights = _ref9.insights,
          insightsEvents = _ref9.insightsEvents,
          state = _ref9.state;
        insights.clickedObjectIDsAfterSearch.apply(insights, _toConsumableArray(insightsEvents.map(function (event) {
          return _objectSpread2(_objectSpread2({}, event), {}, {
            algoliaSource: getAlgoliaSources(event.algoliaSource, state.context)
          });
        })));
      },
      onActive: noop,
      __autocomplete_clickAnalytics: true
    }, options);
  }
  function loadInsights(environment) {
    var errorMessage = "[Autocomplete]: Could not load search-insights.js. Please load it manually following https://alg.li/insights-autocomplete";
    try {
      var script = environment.document.createElement('script');
      script.async = true;
      script.src = ALGOLIA_INSIGHTS_SRC;
      script.onerror = function () {
        // eslint-disable-next-line no-console
        console.error(errorMessage);
      };
      document.body.appendChild(script);
    } catch (cause) {
      // eslint-disable-next-line no-console
      console.error(errorMessage);
    }
  }

  /**
   * While `search-insights` supports both string and number user tokens,
   * the Search API only accepts strings. This function normalizes the user token.
   */
  function normalizeUserToken(userToken) {
    return typeof userToken === 'number' ? userToken.toString() : userToken;
  }

  exports.createAlgoliaInsightsPlugin = createAlgoliaInsightsPlugin;

  Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=index.development.js.map
