{"version":3,"file":"analytics-utils.cjs","sources":["../src/decodeUri.js","../src/isExternalReferrer.js","../src/paramsClean.js","../src/paramsParse.js","../src/url.js","../src/parseReferrer.js","../src/getBrowserLocale.js","../src/getTimeZone.js","../src/isScriptLoaded.js","../src/paramsGet.js","../src/paramsRemove.js","../src/throttle.js","../src/uuid.js"],"sourcesContent":["/**\n * Decode URI string\n *\n * @param {String} s string to decode\n * @returns {String} decoded string\n * @example\n * decode(\"Bought%20keyword)\n * => \"Bought keyword\"\n */\nexport function decodeUri(s) {\n  try {\n    return decodeURIComponent(s.replace(/\\+/g, ' '))\n  } catch (e) {\n    return null\n  }\n}\n","import { isBrowser } from '@analytics/type-utils'\n\n/**\n * @param {string | null | undefined} ref\n * @returns {boolean | undefined}\n */\nexport function isExternalReferrer(ref) {\n  if (!isBrowser) return false\n  const referrer = ref || document.referrer\n  if (referrer) {\n    const port = window.document.location.port\n    let ref = referrer.split('/')[2]\n    if (port) {\n      ref = ref.replace(`:${port}`, '')\n    }\n    return ref !== window.location.hostname\n  }\n  return false\n}\n","\n/**\n * Strip a query parameter from a url string\n * @param  {string} url   - url with query parameters\n * @param  {string} param - parameter to strip\n * @return {string} cleaned url\n */\nexport function paramsClean(url, param) {\n  const search = (url.split('?') || [ , ])[1] // eslint-disable-line\n  if (!search || search.indexOf(param) === -1) {\n    return url\n  }\n  // remove all utm params from URL search\n  const regex = new RegExp(`(\\\\&|\\\\?)${param}([_A-Za-z0-9\"+=.\\\\/\\\\-@%]+)`, 'g')\n  const cleanSearch = `?${search}`.replace(regex, '').replace(/^&/, '?')\n  // replace search params with clean params\n  const cleanURL = url.replace(`?${search}`, cleanSearch)\n  // use browser history API to clean the params\n  return cleanURL\n}\n","import { isBrowser } from '@analytics/type-utils'\nimport { decodeUri } from './decodeUri.js'\n\n/**\n * Get search string from given url\n * @param  {string} [url] - optional url string. If no url, window.location.search will be used\n * @return {string} url search string\n */\nfunction getSearchString(url) {\n  if (url) {\n    const p = url.match(/\\?(.*)/)\n    return (p && p[1]) ? p[1].split('#')[0] : ''\n  }\n  return isBrowser && window.location.search.substring(1)\n}\n\n/**\n * Parse url parameters into javascript object\n * @param  {string} [url] - URI to parse. If no url supplied window.location will be used\n * @return {object} parsed url parameters\n */\nexport function paramsParse(url) {\n  return getParamsAsObject(getSearchString(url))\n}\n\n/*\n?first=abc&a[]=123&a[]=false&b[]=str&c[]=3.5&a[]=last\nhttps://random.url.com?Target=Report&Method=getStats&fields%5B%5D=Offer.name&fields%5B%5D=Advertiser.company&fields%5B%5D=Stat.clicks&fields%5B%5D=Stat.conversions&fields%5B%5D=Stat.cpa&fields%5B%5D=Stat.payout&fields%5B%5D=Stat.date&fields%5B%5D=Stat.offer_id&fields%5B%5D=Affiliate.company&groups%5B%5D=Stat.offer_id&groups%5B%5D=Stat.date&filters%5BStat.affiliate_id%5D%5Bconditional%5D=EQUAL_TO&filters%5BStat.affiliate_id%5D%5Bvalues%5D=1831&limit=9999\nhttps://random.url.com?Target=Offer&Method=findAll&filters%5Bhas_goals_enabled%5D%5BTRUE%5D=1&filters%5Bstatus%5D=active&fields%5B%5D=id&fields%5B%5D=name&fields%5B%5D=default_goal_name\nhttp://localhost:3000/?Target=Offer&Method=findAll&filters[has_goals_enabled][TRUE]=1&filters[status]=active&filters[wow]arr[]=yaz&filters[wow]arr[]=naz&fields[]=id&fields[]=name&fields[]=default_goal_name */\n\n\nfunction getParamsAsObject(query) {\n  let params = Object.create(null)\n  let temp\n  const re = /([^&=]+)=?([^&]*)/g\n\n  while (temp = re.exec(query)) {\n    var k = decodeUri(temp[1])\n    var v = decodeUri(temp[2])\n    if (!k) continue\n    if (k.substring(k.length - 2) === '[]') {\n      k = k.substring(0, k.length - 2);\n      var arrVal = params[k] || (params[k] = [])\n      params[k] = Array.isArray(arrVal) ? arrVal : []\n      params[k].push(v)\n    } else {\n      params[k] = (v === '') ? true : v\n    }\n  }\n\n  for (var prop in params) {\n    var arr = prop.split('[')\n    if (arr.length > 1) {\n      assign(params, arr.map((x) => x.replace(/[?[\\]\\\\ ]/g, '')), params[prop])\n      delete params[prop]\n    }\n  }\n  return params\n}\n\nfunction assign(obj, keyPath, value) {\n  var lastKeyIndex = keyPath.length - 1\n  for (var i = 0; i < lastKeyIndex; ++i) {\n    var key = keyPath[i]\n    if (key === '__proto__' || key === 'constructor') {\n      break;\n    }\n    if (!(key in obj)) { \n      obj[key] = {} \n    }\n    obj = obj[key]\n  }\n  obj[keyPath[lastKeyIndex]] = value\n}\n\n\n/*\nhttps://github.com/choojs/nanoquery/blob/791cbdfe49cc380f0b2f93477572128946171b46/browser.js\nvar reg = /([^?=&]+)(=([^&]*))?/g\n\nfunction qs (url) {\n  var obj = {}\n  url.replace(/^.*\\?/, '').replace(reg, function (a0, a1, a2, a3) {\n    var value = decodeURIComponent(a3)\n    var key = decodeURIComponent(a1)\n    if (obj.hasOwnProperty(key)) {\n      if (Array.isArray(obj[key])) obj[key].push(value)\n      else obj[key] = [obj[key], value]\n    } else {\n      obj[key] = value\n    }\n  })\n  return obj\n}\n*/","import { isBrowser } from '@analytics/type-utils'\n\n/**\n * Get host domain of url\n * @param  {String} url - href of page\n * @return {String} hostname of page\n *\n * @example\n *  getDomainHost('https://subdomain.my-site.com/')\n *  > subdomain.my-site.com\n */\nexport function getDomainHost(url) {\n  if (!isBrowser) return null\n  const a = document.createElement('a')\n  a.setAttribute('href', url)\n  return a.hostname\n}\n\n/**\n * Get host domain of url\n * @param  {String} url - href of page\n * @return {String} base hostname of page\n *\n * @example\n *  getDomainBase('https://subdomain.my-site.com/')\n *  > my-site.com\n */\nexport function getDomainBase(url) {\n  const host = getDomainHost(url) || ''\n  return host.split('.').slice(-2).join('.')\n}\n\n/**\n * Remove TLD from domain string\n * @param  {String} baseDomain - host name of site\n * @return {String}\n * @example\n *  trimTld('google.com')\n *  > google\n */\nexport function trimTld(baseDomain) {\n  const arr = baseDomain.split('.')\n  return (arr.length > 1) ? arr.slice(0, -1).join('.') : baseDomain\n}\n\nexport default {\n  trimTld,\n  getDomainBase,\n  getDomainHost\n}\n","import { isBrowser } from '@analytics/type-utils'\nimport { paramsParse } from './paramsParse.js'\nimport { isExternalReferrer } from './isExternalReferrer.js'\nimport { trimTld, getDomainBase } from './url.js'\n\nconst googleKey = 'google'\n\n/**\n * @typedef {{\n *  campaign: string,\n *  referrer?: string,\n * } & DomainObject & Object.<string, any>} ReferrerObject\n */\n\n/**\n * Checks a given url and parses referrer data\n * @param  {String} [referrer] - (optional) referring URL\n * @param  {String} [currentUrl] - (optional) the current url\n * @return {ReferrerObject}     [description]\n */\nexport function parseReferrer(referrer, currentUrl) {\n  if (!isBrowser) return false\n  // default referral data\n  let refData = {\n    'source': '(direct)',\n    'medium': '(none)',\n    'campaign': '(not set)'\n  }\n  // Add raw ref url if external\n  if (referrer && isExternalReferrer(referrer)) {\n    refData.referrer = referrer\n  }\n\n  const domainInfo = parseDomain(referrer)\n  // Read referrer URI and infer source\n  if (domainInfo && Object.keys(domainInfo).length) {\n    refData = Object.assign({}, refData, domainInfo)\n  }\n\n  // Read URI params and use set utm params\n  const params = paramsParse(currentUrl)\n  const paramKeys = Object.keys(params)\n  if (!paramKeys.length) {\n    return refData\n  }\n\n  // set campaign params off GA matches\n  const gaParams = paramKeys.reduce((acc, key) => {\n    // match utm params & dclid (display) & gclid (cpc)\n    if (key.match(/^utm_/)) {\n      acc[`${key.replace(/^utm_/, '')}`] = params[key]\n    }\n    // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters\n    // dclid - cpc Cost-Per-Thousand Impressions\n    // gclid - cpc Cost per Click\n    if (key.match(/^(d|g)clid/)) {\n      acc['source'] = googleKey\n      acc['medium'] = (params.gclid) ? 'cpc' : 'cpm'\n      acc[key] = params[key]\n    }\n    return acc\n  }, {})\n\n  return Object.assign({}, refData, gaParams)\n}\n\n/**\n * @typedef {{\n *  source: string,\n *  medium: string,\n *  term?: string\n * }} DomainObject\n */\n\n/**\n * Client side domain parser for determining marketing data.\n * @param  {String} referrer - ref url\n * @return {DomainObject | boolean}\n */\nfunction parseDomain(referrer) {\n  if (!referrer || !isBrowser) return false\n\n  let referringDomain = getDomainBase(referrer)\n  const a = document.createElement('a')\n  a.href = referrer\n\n  // Shim for the billion google search engines\n  if (a.hostname.indexOf(googleKey) > -1) {\n    referringDomain = googleKey\n  }\n\n  // If is search engine\n  if (searchEngines[referringDomain]) {\n    const searchEngine = searchEngines[referringDomain]\n    const queryParam = (typeof searchEngine === 'string') ? searchEngine : searchEngine.p\n    const termRegex = new RegExp(queryParam + '=.*?([^&#]*|$)', 'gi')\n    const term = a.search.match(termRegex)\n\n    return {\n      source: searchEngine.n || trimTld(referringDomain),\n      medium: 'organic',\n      term: (term ? term[0].split('=')[1] : '') || '(not provided)'\n    }\n  }\n\n  // Default\n  const medium = (!isExternalReferrer(referrer)) ? 'internal' : 'referral'\n  return {\n    source: a.hostname,\n    medium: medium\n  }\n}\n\n/**\n * Search engine query string data\n * @type {Object}\n */\nconst Q = 'q'\nconst QUERY = 'query'\nconst searchEngines = {\n  'daum.net': Q,\n  'eniro.se': 'search_word',\n  'naver.com': QUERY,\n  'yahoo.com': 'p',\n  'msn.com': Q,\n  'aol.com': Q,\n  'ask.com': Q,\n  'baidu.com': 'wd',\n  'yandex.com': 'text',\n  'rambler.ru': 'words',\n  'google': Q,\n  'bing.com': {\n    'p': Q,\n    'n': 'live'\n  },\n}\n","import { isBrowser } from '@analytics/type-utils'\n\n/**\n * @returns {string | undefined}\n */\nexport function getBrowserLocale() {\n  if (!isBrowser) return\n  const { language, languages, userLanguage } = navigator\n  if (userLanguage) return userLanguage // IE only\n  return (languages && languages.length) ? languages[0] : language\n}\n","\n/**\n * @returns {string | undefined}\n */\nexport function getTimeZone() {\n  try {\n    return Intl.DateTimeFormat().resolvedOptions().timeZone\n  } catch (error) {}\n}\n","import { isBrowser, isString, isRegex } from '@analytics/type-utils'\n\n/**\n * Check if a script is loaded\n * @param  {String|RegExp} script - Script src as string or regex\n * @return {Boolean} is script loaded\n */\nexport function isScriptLoaded(script) {\n  if (!isBrowser) return true\n  const scripts = document.getElementsByTagName('script')\n  return !!Object.keys(scripts).filter((key) => {\n    const { src } = scripts[key]\n    if (isString(script)) {\n      return src.indexOf(script) !== -1\n    } else if (isRegex(script)) {\n      return src.match(script)\n    }\n    return false\n  }).length\n}\n","import {decodeUri} from './decodeUri.js'\n\n/**\n * Get a given query parameter value\n * @param  {string} param - Key of parameter to find\n * @param  {string} url - url to search\n * @return {string} match\n */\nexport function paramsGet(param, url) {\n  return decodeUri((RegExp(`${param}=(.+?)(&|$)`).exec(url) || [, ''])[1])\n}\n","import { isBrowser } from '@analytics/type-utils'\nimport { paramsClean } from './paramsClean.js'\n\n/**\n * Removes params from url in browser\n * @param  {string}   param       - param key to remove from current URL\n * @param  {() => void} [callback]  - callback function to run. Only runs in browser\n * @return {PromiseLike<void>}\n */\nexport function paramsRemove(param, callback) {\n  if (!isBrowser) return Promise.resolve()\n\n  return new Promise((resolve, reject) => {\n    if (window.history && window.history.replaceState) {\n      const url = window.location.href\n      const cleanUrl = paramsClean(url, param)\n      if (url !== cleanUrl) {\n        /* replace URL with history API */\n        // eslint-disable-next-line no-restricted-globals\n        history.replaceState({}, '', cleanUrl)\n      }\n    }\n\n    if (callback) callback()\n\n    return resolve()\n  })\n}\n","/**\n * @template {Function} F;\n * @param {F} func;\n * @param {number} wait;\n * @return {F};\n */\nexport function throttle(func, wait) {\n  var context, args, result\n  var timeout = null\n  var previous = 0\n  var later = function () {\n    previous = new Date()\n    timeout = null\n    result = func.apply(context, args)\n  };\n  return function () {\n    var now = new Date()\n    if (!previous) {\n      previous = now\n    }\n    var remaining = wait - (now - previous)\n    context = this\n    args = arguments\n    if (remaining <= 0) {\n      clearTimeout(timeout)\n      timeout = null\n      previous = now\n      result = func.apply(context, args)\n    } else if (!timeout) {\n      timeout = setTimeout(later, remaining)\n    }\n    return result\n  }\n}\n","/* ref: http://bit.ly/2daP79j */\n/**\n * @return {string}\n */\nexport function uuid() {\n  var u = '',\n  m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',\n  i = 0,\n  rb = Math.random() * 0xffffffff|0;\n\n  while (i++<36) {\n    var c = m [i-1],\n    r = rb&0xf,\n    v = c=='x' ? r : (r&0x3|0x8);\n\n    u += (c=='-' || c=='4') ? c : v.toString(16);\n    rb = i%8==0 ? Math.random() * 0xffffffff|0 : rb>>4\n  }\n  return u\n}\n"],"names":["decodeUri","s","decodeURIComponent","replace","e","isExternalReferrer","ref","isBrowser","referrer","document","port","window","location","split","hostname","paramsClean","url","param","search","indexOf","regex","RegExp","cleanSearch","paramsParse","query","temp","params","Object","create","re","exec","k","v","substring","length","arrVal","Array","isArray","push","prop","arr","assign","map","x","getParamsAsObject","p","match","getSearchString","obj","keyPath","value","lastKeyIndex","i","key","getDomainHost","a","createElement","setAttribute","getDomainBase","slice","join","trimTld","baseDomain","googleKey","Q","searchEngines","google","n","_navigator","navigator","languages","userLanguage","language","Intl","DateTimeFormat","resolvedOptions","timeZone","error","script","scripts","getElementsByTagName","keys","filter","src","isString","isRegex","callback","Promise","resolve","reject","history","replaceState","href","cleanUrl","currentUrl","refData","source","medium","campaign","domainInfo","referringDomain","searchEngine","termRegex","term","parseDomain","paramKeys","gaParams","reduce","acc","gclid","func","wait","context","args","result","timeout","previous","later","Date","apply","now","remaining","this","arguments","clearTimeout","setTimeout","u","rb","Math","random","c","r","toString"],"mappings":"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"}