{"version":3,"file":"analytics-DY7ul3HC.js","sources":["../../../node_modules/lodash-es/differenceWith.js","../../../node_modules/lodash-es/uniqWith.js","../../../app/javascript/modules/analytics.js"],"sourcesContent":["import baseDifference from './_baseDifference.js';\nimport baseFlatten from './_baseFlatten.js';\nimport baseRest from './_baseRest.js';\nimport isArrayLikeObject from './isArrayLikeObject.js';\nimport last from './last.js';\n\n/**\n * This method is like `_.difference` except that it accepts `comparator`\n * which is invoked to compare elements of `array` to `values`. The order and\n * references of result values are determined by the first array. The comparator\n * is invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n *\n * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }]\n */\nvar differenceWith = baseRest(function(array, values) {\n  var comparator = last(values);\n  if (isArrayLikeObject(comparator)) {\n    comparator = undefined;\n  }\n  return isArrayLikeObject(array)\n    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n    : [];\n});\n\nexport default differenceWith;\n","import baseUniq from './_baseUniq.js';\n\n/**\n * This method is like `_.uniq` except that it accepts `comparator` which\n * is invoked to compare elements of `array`. The order of result values is\n * determined by the order they occur in the array.The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.uniqWith(objects, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n */\nfunction uniqWith(array, comparator) {\n  comparator = typeof comparator == 'function' ? comparator : undefined;\n  return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n}\n\nexport default uniqWith;\n","import { uniqWith, isEqual, differenceWith, groupBy } from \"lodash-es\";\nimport { on, ready } from \"../utils/listeners\";\n\non(\"click\", \".js-mega-nav-item\", el => {\n  analytics.track(\"Clicked Mega Nav\", {\n    name: el.dataset.name,\n    number: el.dataset.number,\n    situation: el.dataset.situation\n  });\n});\n\non(\"click\", \".js-open-menu\", () => {\n  analytics.track(\"Opened Menu\");\n});\n\non(\"click\", \".js-nav-group-item\", el => {\n  analytics.track(\"Clicked Nav Group Item\", {\n    megaNavItemName: el.dataset.megaNavItemName,\n    navGroupName: el.dataset.navGroupName,\n    navGroupPosition: el.dataset.navGroupPosition,\n    navGroupItemName: el.dataset.navGroupItemName,\n    navGroupItemPosition: el.dataset.navGroupItemPosition\n  });\n});\n\non(\"click\", \".js-book-builder-link\", async el => {\n  await analytics.track(\"Book Builder CTA Clicked on PLP\", {\n    category: el.dataset.categoryName\n  });\n  window.location = el.dataset.bookBuilderPath;\n});\n\non(\"click\", \".js-collection-drawer-link\", () => {\n  analytics.track(\"Clicked View the Full Collection on PLP\");\n});\n\non(\"click\", \".js-collection-modal-listing .product\", el => {\n  analytics.track(\"Clicked Product in PLP Collection Modal\", {\n    analytics_id: el.dataset.id\n  });\n});\n\non(\"click\", \".js-collection-drawer-favourites-cta\", () => {\n  analytics.track(\"Add All to Favourites (Collection Modal)\");\n});\n\non(\"click\", \".js-collection-drawer-close-button\", () => {\n  analytics.track(\"Closed PLP Collection Modal\");\n});\n\non(\"click\", \".js-comparison-link\", el => {\n  analytics.track(\"Clicked Size Guide\", {\n    productId: el.dataset.productId\n  });\n});\n\non(\"click\", \".js-event-carousel-item\", el => {\n  analytics.track(\"Clicked Event Reminder Carousel Item\", {\n    type: el.dataset.eventType\n  });\n});\n\non(\"click\", \"[data-event]\", el => {\n  const { event, ...props } = el.dataset;\n\n  // Take all data attributes, filter out ones that don't start with 'event',\n  // remove the event prefix and lowercase the first letter.\n  // IN: data-event-country=\"UK\" data-event-category-name=\"Notebooks\"\n  // OUT: { country: \"UK\", categoryName: \"Notebooks\" }\n  const filteredProps = Object.keys(props).reduce((acc, key) => {\n    if (key.startsWith(\"event\")) {\n      const newKey =\n        key.replace(\"event\", \"\").charAt(0).toLowerCase() + key.slice(6);\n      acc[newKey] = props[key];\n    }\n    return acc;\n  }, {});\n  analytics.track(event, filteredProps);\n});\n\non(\"click\", \".product\", (p, e) => {\n  if (![\"IMG\", \"A\"].includes(e.target.tagName)) {\n    return;\n  }\n\n  const impressionList = p.closest(\".js-impression-list\");\n\n  const click = {\n    productId: p.dataset.id,\n    analyticsId: p.dataset.id\n  };\n\n  if (impressionList) {\n    Object.assign(click, impressionList.dataset);\n\n    const position = [...impressionList.querySelectorAll(\".product\")].indexOf(\n      p\n    );\n\n    if (position > -1) click.position = position + 1;\n  }\n\n  Object.keys(click).forEach(k => {\n    if (k.startsWith(\"v\")) delete click[k];\n  });\n\n  if (!click.analyticsId) {\n    analytics.track(\"Clicked Product - Undefined Analytics ID\", {\n      classList: e.target.classList,\n      tagName: e.target.tagName,\n      dataSet: p.dataset\n    });\n  } else {\n    analytics.track(\"Clicked Product\", click);\n  }\n});\n\n// Set up an intersection observer which reports product listing impressions to\n// our analytics services. This needs to be rerun each time additional product cards\n// have been added to the page, because of the way IntersectionObservers work\n\nconst viewedProducts = [];\nlet previouslyTrackedProducts = [];\n\nconst options = {\n  root: null,\n  rootMargin: \"0px\",\n  threshold: [0.0, 0.75]\n};\n\nconst callback = entries => {\n  entries.forEach(entry => {\n    const product = entry.target;\n\n    if (entry.isIntersecting) {\n      if (entry.intersectionRatio > 0.75) {\n        product.dataset.lastViewStarted = entry.time;\n        product.dataset.lastViewEnded = undefined;\n      } else if (product.dataset.lastViewStarted) {\n        product.dataset.lastViewEnded = entry.time;\n      }\n    }\n  });\n};\n\nconst alreadyTracked = product =>\n  viewedProducts.some(p => p.id === product.dataset.id);\n\nconst observer = new IntersectionObserver(callback, options);\n\nconst handleRefreshInterval = () => {\n  const currentTime = performance.now();\n\n  document.querySelectorAll(\".product\").forEach(p => {\n    const { lastViewStarted, lastViewEnded } = p.dataset;\n    if (!lastViewStarted) return;\n    if (alreadyTracked(p)) return;\n\n    if (currentTime - parseFloat(lastViewStarted) > 150) {\n      const ended = parseFloat(lastViewEnded) || currentTime;\n      if (ended - parseFloat(lastViewStarted) > 150) {\n        const impressionList = p.closest(\".js-impression-list\");\n\n        const impression = { id: p.dataset.id };\n\n        if (impressionList) {\n          Object.assign(impression, impressionList.dataset);\n\n          const position = [\n            ...impressionList.querySelectorAll(\".product\")\n          ].indexOf(p);\n\n          if (position > -1) impression.position = position + 1;\n        }\n\n        viewedProducts.push(impression);\n      }\n    }\n  });\n};\n\nconst handleTracking = () => {\n  const difference = uniqWith(\n    differenceWith(viewedProducts, previouslyTrackedProducts, (p1, p2) => {\n      return p1.id === p2.id;\n    }),\n    isEqual\n  );\n\n  previouslyTrackedProducts = [...viewedProducts];\n\n  if (difference.length) {\n    const groups = groupBy(difference, i => [i.situation, i.term]);\n\n    Object.keys(groups).forEach(key => {\n      const impressions = groups[key];\n      const products = impressions.map(i => [i.id, i.position]);\n\n      const { id, position, ...other } = impressions[0];\n\n      const track = {\n        products,\n        ...other\n      };\n\n      // Vue adds data-v-xxx to tags, which isn't something we want to track (these get converted to columns\n      // in the warehouse). Just remove anything beginning with v-\n      Object.keys(track).forEach(k => {\n        if (k.startsWith(\"v\")) delete track[k];\n      });\n\n      analytics.track(\"Product Impression\", track);\n    });\n  }\n};\n\nconst setupImpressionTracker = () => {\n  const products = document.querySelectorAll(\".product\");\n  products.forEach(p => observer.observe(p));\n};\n\nwindow.setInterval(handleRefreshInterval, 100);\nwindow.setInterval(handleTracking, 1000);\n\nready(() => {\n  setupImpressionTracker();\n});\n\nwindow.addEventListener(\"htmlChanged\", () => {\n  setupImpressionTracker();\n});\n"],"names":["differenceWith","baseRest","array","values","comparator","last","isArrayLikeObject","baseDifference","baseFlatten","uniqWith","baseUniq","on","el","event","props","filteredProps","acc","key","newKey","p","impressionList","click","position","k","viewedProducts","previouslyTrackedProducts","options","callback","entries","entry","product","alreadyTracked","observer","handleRefreshInterval","currentTime","lastViewStarted","lastViewEnded","impression","handleTracking","difference","p1","p2","isEqual","groups","groupBy","i","impressions","products","id","other","track","setupImpressionTracker","ready"],"mappings":"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","x_google_ignoreList":[0,1]}