mixpanel-browser 2.40.1 → 2.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
 
3
3
  var Config = {
4
4
  DEBUG: false,
5
- LIB_VERSION: '2.40.1'
5
+ LIB_VERSION: '2.43.0'
6
6
  };
7
7
 
8
8
  // since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
@@ -55,7 +55,7 @@ var _ = {
55
55
  };
56
56
 
57
57
  // Console override
58
- var console$1 = {
58
+ var console = {
59
59
  /** @type {function(...*)} */
60
60
  log: function() {
61
61
  if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
@@ -112,14 +112,14 @@ var console$1 = {
112
112
  var log_func_with_prefix = function(func, prefix) {
113
113
  return function() {
114
114
  arguments[0] = '[' + prefix + '] ' + arguments[0];
115
- return func.apply(console$1, arguments);
115
+ return func.apply(console, arguments);
116
116
  };
117
117
  };
118
118
  var console_with_prefix = function(prefix) {
119
119
  return {
120
- log: log_func_with_prefix(console$1.log, prefix),
121
- error: log_func_with_prefix(console$1.error, prefix),
122
- critical: log_func_with_prefix(console$1.critical, prefix)
120
+ log: log_func_with_prefix(console.log, prefix),
121
+ error: log_func_with_prefix(console.error, prefix),
122
+ critical: log_func_with_prefix(console.critical, prefix)
123
123
  };
124
124
  };
125
125
 
@@ -281,10 +281,6 @@ _.values = function(obj) {
281
281
  return results;
282
282
  };
283
283
 
284
- _.identity = function(value) {
285
- return value;
286
- };
287
-
288
284
  _.include = function(obj, target) {
289
285
  var found = false;
290
286
  if (obj === null) {
@@ -385,9 +381,9 @@ _.safewrap = function(f) {
385
381
  try {
386
382
  return f.apply(this, arguments);
387
383
  } catch (e) {
388
- console$1.critical('Implementation error. Please turn on debug and contact support@mixpanel.com.');
384
+ console.critical('Implementation error. Please turn on debug and contact support@mixpanel.com.');
389
385
  if (Config.DEBUG){
390
- console$1.critical(e);
386
+ console.critical(e);
391
387
  }
392
388
  }
393
389
  };
@@ -948,10 +944,12 @@ _.UUID = (function() {
948
944
  // This is to block various web spiders from executing our JS and
949
945
  // sending false tracking data
950
946
  var BLOCKED_UA_STRS = [
947
+ 'ahrefsbot',
951
948
  'baiduspider',
952
949
  'bingbot',
953
950
  'bingpreview',
954
951
  'facebookexternal',
952
+ 'petalbot',
955
953
  'pinterest',
956
954
  'screaming frog',
957
955
  'yahoo! slurp',
@@ -1016,16 +1014,12 @@ _.getQueryParam = function(url, param) {
1016
1014
  try {
1017
1015
  result = decodeURIComponent(result);
1018
1016
  } catch(err) {
1019
- console$1.error('Skipping decoding for malformed query param: ' + result);
1017
+ console.error('Skipping decoding for malformed query param: ' + result);
1020
1018
  }
1021
1019
  return result.replace(/\+/g, ' ');
1022
1020
  }
1023
1021
  };
1024
1022
 
1025
- _.getHashParam = function(hash, param) {
1026
- var matches = hash.match(new RegExp(param + '=([^&]*)'));
1027
- return matches ? matches[1] : null;
1028
- };
1029
1023
 
1030
1024
  // _.cookie
1031
1025
  // Methods partially borrowed from quirksmode.org/js/cookies.html
@@ -1147,13 +1141,13 @@ _.localStorage = {
1147
1141
  is_supported: function(force_check) {
1148
1142
  var supported = localStorageSupported(null, force_check);
1149
1143
  if (!supported) {
1150
- console$1.error('localStorage unsupported; falling back to cookie store');
1144
+ console.error('localStorage unsupported; falling back to cookie store');
1151
1145
  }
1152
1146
  return supported;
1153
1147
  },
1154
1148
 
1155
1149
  error: function(msg) {
1156
- console$1.error('localStorage error: ' + msg);
1150
+ console.error('localStorage error: ' + msg);
1157
1151
  },
1158
1152
 
1159
1153
  get: function(name) {
@@ -1208,7 +1202,7 @@ _.register_event = (function() {
1208
1202
  */
1209
1203
  var register_event = function(element, type, handler, oldSchool, useCapture) {
1210
1204
  if (!element) {
1211
- console$1.error('No valid element provided to register_event');
1205
+ console.error('No valid element provided to register_event');
1212
1206
  return;
1213
1207
  }
1214
1208
 
@@ -1692,28 +1686,6 @@ var cheap_guid = function(maxlen) {
1692
1686
  return maxlen ? guid.substring(0, maxlen) : guid;
1693
1687
  };
1694
1688
 
1695
- /**
1696
- * Check deterministically whether to include or exclude from a feature rollout/test based on the
1697
- * given string and the desired percentage to include.
1698
- * @param {String} str - string to run the check against (for instance a project's token)
1699
- * @param {String} feature - name of feature (for inclusion in hash, to ensure different results
1700
- * for different features)
1701
- * @param {Number} percent_allowed - percentage chance that a given string will be included
1702
- * @returns {Boolean} whether the given string should be included
1703
- */
1704
- var determine_eligibility = _.safewrap(function(str, feature, percent_allowed) {
1705
- str = str + feature;
1706
-
1707
- // Bernstein's hash: http://www.cse.yorku.ca/~oz/hash.html#djb2
1708
- var hash = 5381;
1709
- for (var i = 0; i < str.length; i++) {
1710
- hash = ((hash << 5) + hash) + str.charCodeAt(i);
1711
- hash = hash & hash;
1712
- }
1713
- var dart = (hash >>> 0) % 100;
1714
- return dart < percent_allowed;
1715
- });
1716
-
1717
1689
  // naive way to extract domain name (example.com) from full hostname (my.sub.example.com)
1718
1690
  var SIMPLE_DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]*\.[a-z]+$/i;
1719
1691
  // this next one attempts to account for some ccSLDs, e.g. extracting oxford.ac.uk from www.oxford.ac.uk
@@ -1764,539 +1736,6 @@ _['info']['browser'] = _.info.browser;
1764
1736
  _['info']['browserVersion'] = _.info.browserVersion;
1765
1737
  _['info']['properties'] = _.info.properties;
1766
1738
 
1767
- /*
1768
- * Get the className of an element, accounting for edge cases where element.className is an object
1769
- * @param {Element} el - element to get the className of
1770
- * @returns {string} the element's class
1771
- */
1772
- function getClassName(el) {
1773
- switch(typeof el.className) {
1774
- case 'string':
1775
- return el.className;
1776
- case 'object': // handle cases where className might be SVGAnimatedString or some other type
1777
- return el.className.baseVal || el.getAttribute('class') || '';
1778
- default: // future proof
1779
- return '';
1780
- }
1781
- }
1782
-
1783
- /*
1784
- * Get the direct text content of an element, protecting against sensitive data collection.
1785
- * Concats textContent of each of the element's text node children; this avoids potential
1786
- * collection of sensitive data that could happen if we used element.textContent and the
1787
- * element had sensitive child elements, since element.textContent includes child content.
1788
- * Scrubs values that look like they could be sensitive (i.e. cc or ssn number).
1789
- * @param {Element} el - element to get the text of
1790
- * @returns {string} the element's direct text content
1791
- */
1792
- function getSafeText(el) {
1793
- var elText = '';
1794
-
1795
- if (shouldTrackElement(el) && el.childNodes && el.childNodes.length) {
1796
- _.each(el.childNodes, function(child) {
1797
- if (isTextNode(child) && child.textContent) {
1798
- elText += _.trim(child.textContent)
1799
- // scrub potentially sensitive values
1800
- .split(/(\s+)/).filter(shouldTrackValue).join('')
1801
- // normalize whitespace
1802
- .replace(/[\r\n]/g, ' ').replace(/[ ]+/g, ' ')
1803
- // truncate
1804
- .substring(0, 255);
1805
- }
1806
- });
1807
- }
1808
-
1809
- return _.trim(elText);
1810
- }
1811
-
1812
- /*
1813
- * Check whether an element has nodeType Node.ELEMENT_NODE
1814
- * @param {Element} el - element to check
1815
- * @returns {boolean} whether el is of the correct nodeType
1816
- */
1817
- function isElementNode(el) {
1818
- return el && el.nodeType === 1; // Node.ELEMENT_NODE - use integer constant for browser portability
1819
- }
1820
-
1821
- /*
1822
- * Check whether an element is of a given tag type.
1823
- * Due to potential reference discrepancies (such as the webcomponents.js polyfill),
1824
- * we want to match tagNames instead of specific references because something like
1825
- * element === document.body won't always work because element might not be a native
1826
- * element.
1827
- * @param {Element} el - element to check
1828
- * @param {string} tag - tag name (e.g., "div")
1829
- * @returns {boolean} whether el is of the given tag type
1830
- */
1831
- function isTag(el, tag) {
1832
- return el && el.tagName && el.tagName.toLowerCase() === tag.toLowerCase();
1833
- }
1834
-
1835
- /*
1836
- * Check whether an element has nodeType Node.TEXT_NODE
1837
- * @param {Element} el - element to check
1838
- * @returns {boolean} whether el is of the correct nodeType
1839
- */
1840
- function isTextNode(el) {
1841
- return el && el.nodeType === 3; // Node.TEXT_NODE - use integer constant for browser portability
1842
- }
1843
-
1844
- /*
1845
- * Check whether a DOM event should be "tracked" or if it may contain sentitive data
1846
- * using a variety of heuristics.
1847
- * @param {Element} el - element to check
1848
- * @param {Event} event - event to check
1849
- * @returns {boolean} whether the event should be tracked
1850
- */
1851
- function shouldTrackDomEvent(el, event) {
1852
- if (!el || isTag(el, 'html') || !isElementNode(el)) {
1853
- return false;
1854
- }
1855
- var tag = el.tagName.toLowerCase();
1856
- switch (tag) {
1857
- case 'html':
1858
- return false;
1859
- case 'form':
1860
- return event.type === 'submit';
1861
- case 'input':
1862
- if (['button', 'submit'].indexOf(el.getAttribute('type')) === -1) {
1863
- return event.type === 'change';
1864
- } else {
1865
- return event.type === 'click';
1866
- }
1867
- case 'select':
1868
- case 'textarea':
1869
- return event.type === 'change';
1870
- default:
1871
- return event.type === 'click';
1872
- }
1873
- }
1874
-
1875
- /*
1876
- * Check whether a DOM element should be "tracked" or if it may contain sentitive data
1877
- * using a variety of heuristics.
1878
- * @param {Element} el - element to check
1879
- * @returns {boolean} whether the element should be tracked
1880
- */
1881
- function shouldTrackElement(el) {
1882
- for (var curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode) {
1883
- var classes = getClassName(curEl).split(' ');
1884
- if (_.includes(classes, 'mp-sensitive') || _.includes(classes, 'mp-no-track')) {
1885
- return false;
1886
- }
1887
- }
1888
-
1889
- if (_.includes(getClassName(el).split(' '), 'mp-include')) {
1890
- return true;
1891
- }
1892
-
1893
- // don't send data from inputs or similar elements since there will always be
1894
- // a risk of clientside javascript placing sensitive data in attributes
1895
- if (
1896
- isTag(el, 'input') ||
1897
- isTag(el, 'select') ||
1898
- isTag(el, 'textarea') ||
1899
- el.getAttribute('contenteditable') === 'true'
1900
- ) {
1901
- return false;
1902
- }
1903
-
1904
- // don't include hidden or password fields
1905
- var type = el.type || '';
1906
- if (typeof type === 'string') { // it's possible for el.type to be a DOM element if el is a form with a child input[name="type"]
1907
- switch(type.toLowerCase()) {
1908
- case 'hidden':
1909
- return false;
1910
- case 'password':
1911
- return false;
1912
- }
1913
- }
1914
-
1915
- // filter out data from fields that look like sensitive fields
1916
- var name = el.name || el.id || '';
1917
- if (typeof name === 'string') { // it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name="name"]
1918
- var sensitiveNameRegex = /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i;
1919
- if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {
1920
- return false;
1921
- }
1922
- }
1923
-
1924
- return true;
1925
- }
1926
-
1927
- /*
1928
- * Check whether a string value should be "tracked" or if it may contain sentitive data
1929
- * using a variety of heuristics.
1930
- * @param {string} value - string value to check
1931
- * @returns {boolean} whether the element should be tracked
1932
- */
1933
- function shouldTrackValue(value) {
1934
- if (value === null || _.isUndefined(value)) {
1935
- return false;
1936
- }
1937
-
1938
- if (typeof value === 'string') {
1939
- value = _.trim(value);
1940
-
1941
- // check to see if input value looks like a credit card number
1942
- // see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html
1943
- var ccRegex = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
1944
- if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {
1945
- return false;
1946
- }
1947
-
1948
- // check to see if input value looks like a social security number
1949
- var ssnRegex = /(^\d{3}-?\d{2}-?\d{4}$)/;
1950
- if (ssnRegex.test(value)) {
1951
- return false;
1952
- }
1953
- }
1954
-
1955
- return true;
1956
- }
1957
-
1958
- var autotrack = {
1959
- _initializedTokens: [],
1960
-
1961
- _previousElementSibling: function(el) {
1962
- if (el.previousElementSibling) {
1963
- return el.previousElementSibling;
1964
- } else {
1965
- do {
1966
- el = el.previousSibling;
1967
- } while (el && !isElementNode(el));
1968
- return el;
1969
- }
1970
- },
1971
-
1972
- _loadScript: function(scriptUrlToLoad, callback) {
1973
- var scriptTag = document.createElement('script');
1974
- scriptTag.type = 'text/javascript';
1975
- scriptTag.src = scriptUrlToLoad;
1976
- scriptTag.onload = callback;
1977
-
1978
- var scripts = document.getElementsByTagName('script');
1979
- if (scripts.length > 0) {
1980
- scripts[0].parentNode.insertBefore(scriptTag, scripts[0]);
1981
- } else {
1982
- document.body.appendChild(scriptTag);
1983
- }
1984
- },
1985
-
1986
- _getPropertiesFromElement: function(elem) {
1987
- var props = {
1988
- 'classes': getClassName(elem).split(' '),
1989
- 'tag_name': elem.tagName.toLowerCase()
1990
- };
1991
-
1992
- if (shouldTrackElement(elem)) {
1993
- _.each(elem.attributes, function(attr) {
1994
- if (shouldTrackValue(attr.value)) {
1995
- props['attr__' + attr.name] = attr.value;
1996
- }
1997
- });
1998
- }
1999
-
2000
- var nthChild = 1;
2001
- var nthOfType = 1;
2002
- var currentElem = elem;
2003
- while (currentElem = this._previousElementSibling(currentElem)) { // eslint-disable-line no-cond-assign
2004
- nthChild++;
2005
- if (currentElem.tagName === elem.tagName) {
2006
- nthOfType++;
2007
- }
2008
- }
2009
- props['nth_child'] = nthChild;
2010
- props['nth_of_type'] = nthOfType;
2011
-
2012
- return props;
2013
- },
2014
-
2015
- _getDefaultProperties: function(eventType) {
2016
- return {
2017
- '$event_type': eventType,
2018
- '$ce_version': 1,
2019
- '$host': window.location.host,
2020
- '$pathname': window.location.pathname
2021
- };
2022
- },
2023
-
2024
- _extractCustomPropertyValue: function(customProperty) {
2025
- var propValues = [];
2026
- _.each(document.querySelectorAll(customProperty['css_selector']), function(matchedElem) {
2027
- var value;
2028
-
2029
- if (['input', 'select'].indexOf(matchedElem.tagName.toLowerCase()) > -1) {
2030
- value = matchedElem['value'];
2031
- } else if (matchedElem['textContent']) {
2032
- value = matchedElem['textContent'];
2033
- }
2034
-
2035
- if (shouldTrackValue(value)) {
2036
- propValues.push(value);
2037
- }
2038
- });
2039
- return propValues.join(', ');
2040
- },
2041
-
2042
- _getCustomProperties: function(targetElementList) {
2043
- var props = {};
2044
- _.each(this._customProperties, function(customProperty) {
2045
- _.each(customProperty['event_selectors'], function(eventSelector) {
2046
- var eventElements = document.querySelectorAll(eventSelector);
2047
- _.each(eventElements, function(eventElement) {
2048
- if (_.includes(targetElementList, eventElement) && shouldTrackElement(eventElement)) {
2049
- props[customProperty['name']] = this._extractCustomPropertyValue(customProperty);
2050
- }
2051
- }, this);
2052
- }, this);
2053
- }, this);
2054
- return props;
2055
- },
2056
-
2057
- _getEventTarget: function(e) {
2058
- // https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes
2059
- if (typeof e.target === 'undefined') {
2060
- return e.srcElement;
2061
- } else {
2062
- return e.target;
2063
- }
2064
- },
2065
-
2066
- _trackEvent: function(e, instance) {
2067
- /*** Don't mess with this code without running IE8 tests on it ***/
2068
- var target = this._getEventTarget(e);
2069
- if (isTextNode(target)) { // defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)
2070
- target = target.parentNode;
2071
- }
2072
-
2073
- if (shouldTrackDomEvent(target, e)) {
2074
- var targetElementList = [target];
2075
- var curEl = target;
2076
- while (curEl.parentNode && !isTag(curEl, 'body')) {
2077
- targetElementList.push(curEl.parentNode);
2078
- curEl = curEl.parentNode;
2079
- }
2080
-
2081
- var elementsJson = [];
2082
- var href, explicitNoTrack = false;
2083
- _.each(targetElementList, function(el) {
2084
- var shouldTrackEl = shouldTrackElement(el);
2085
-
2086
- // if the element or a parent element is an anchor tag
2087
- // include the href as a property
2088
- if (el.tagName.toLowerCase() === 'a') {
2089
- href = el.getAttribute('href');
2090
- href = shouldTrackEl && shouldTrackValue(href) && href;
2091
- }
2092
-
2093
- // allow users to programatically prevent tracking of elements by adding class 'mp-no-track'
2094
- var classes = getClassName(el).split(' ');
2095
- if (_.includes(classes, 'mp-no-track')) {
2096
- explicitNoTrack = true;
2097
- }
2098
-
2099
- elementsJson.push(this._getPropertiesFromElement(el));
2100
- }, this);
2101
-
2102
- if (explicitNoTrack) {
2103
- return false;
2104
- }
2105
-
2106
- // only populate text content from target element (not parents)
2107
- // to prevent text within a sensitive element from being collected
2108
- // as part of a parent's el.textContent
2109
- var elementText;
2110
- var safeElementText = getSafeText(target);
2111
- if (safeElementText && safeElementText.length) {
2112
- elementText = safeElementText;
2113
- }
2114
-
2115
- var props = _.extend(
2116
- this._getDefaultProperties(e.type),
2117
- {
2118
- '$elements': elementsJson,
2119
- '$el_attr__href': href,
2120
- '$el_text': elementText
2121
- },
2122
- this._getCustomProperties(targetElementList)
2123
- );
2124
-
2125
- instance.track('$web_event', props);
2126
- return true;
2127
- }
2128
- },
2129
-
2130
- // only reason is to stub for unit tests
2131
- // since you can't override window.location props
2132
- _navigate: function(href) {
2133
- window.location.href = href;
2134
- },
2135
-
2136
- _addDomEventHandlers: function(instance) {
2137
- var handler = _.bind(function(e) {
2138
- e = e || window.event;
2139
- this._trackEvent(e, instance);
2140
- }, this);
2141
- _.register_event(document, 'submit', handler, false, true);
2142
- _.register_event(document, 'change', handler, false, true);
2143
- _.register_event(document, 'click', handler, false, true);
2144
- },
2145
-
2146
- _customProperties: {},
2147
- init: function(instance) {
2148
- if (!(document && document.body)) {
2149
- console.log('document not ready yet, trying again in 500 milliseconds...');
2150
- var that = this;
2151
- setTimeout(function() { that.init(instance); }, 500);
2152
- return;
2153
- }
2154
-
2155
- var token = instance.get_config('token');
2156
- if (this._initializedTokens.indexOf(token) > -1) {
2157
- console.log('autotrack already initialized for token "' + token + '"');
2158
- return;
2159
- }
2160
- this._initializedTokens.push(token);
2161
-
2162
- if (!this._maybeLoadEditor(instance)) { // don't autotrack actions when the editor is enabled
2163
- var parseDecideResponse = _.bind(function(response) {
2164
- if (response && response['config'] && response['config']['enable_collect_everything'] === true) {
2165
-
2166
- if (response['custom_properties']) {
2167
- this._customProperties = response['custom_properties'];
2168
- }
2169
-
2170
- instance.track('$web_event', _.extend({
2171
- '$title': document.title
2172
- }, this._getDefaultProperties('pageview')));
2173
-
2174
- this._addDomEventHandlers(instance);
2175
-
2176
- } else {
2177
- instance['__autotrack_enabled'] = false;
2178
- }
2179
- }, this);
2180
-
2181
- instance._send_request(
2182
- instance.get_config('api_host') + '/decide/', {
2183
- 'verbose': true,
2184
- 'version': '1',
2185
- 'lib': 'web',
2186
- 'token': token
2187
- },
2188
- {method: 'GET', transport: 'XHR'},
2189
- instance._prepare_callback(parseDecideResponse)
2190
- );
2191
- }
2192
- },
2193
-
2194
- _editorParamsFromHash: function(instance, hash) {
2195
- var editorParams;
2196
- try {
2197
- var state = _.getHashParam(hash, 'state');
2198
- state = JSON.parse(decodeURIComponent(state));
2199
- var expiresInSeconds = _.getHashParam(hash, 'expires_in');
2200
- editorParams = {
2201
- 'accessToken': _.getHashParam(hash, 'access_token'),
2202
- 'accessTokenExpiresAt': (new Date()).getTime() + (Number(expiresInSeconds) * 1000),
2203
- 'bookmarkletMode': !!state['bookmarkletMode'],
2204
- 'projectId': state['projectId'],
2205
- 'projectOwnerId': state['projectOwnerId'],
2206
- 'projectToken': state['token'],
2207
- 'readOnly': state['readOnly'],
2208
- 'userFlags': state['userFlags'],
2209
- 'userId': state['userId']
2210
- };
2211
- window.sessionStorage.setItem('editorParams', JSON.stringify(editorParams));
2212
-
2213
- if (state['desiredHash']) {
2214
- window.location.hash = state['desiredHash'];
2215
- } else if (window.history) {
2216
- history.replaceState('', document.title, window.location.pathname + window.location.search); // completely remove hash
2217
- } else {
2218
- window.location.hash = ''; // clear hash (but leaves # unfortunately)
2219
- }
2220
- } catch (e) {
2221
- console.error('Unable to parse data from hash', e);
2222
- }
2223
- return editorParams;
2224
- },
2225
-
2226
- /**
2227
- * To load the visual editor, we need an access token and other state. That state comes from one of three places:
2228
- * 1. In the URL hash params if the customer is using an old snippet
2229
- * 2. From session storage under the key `_mpcehash` if the snippet already parsed the hash
2230
- * 3. From session storage under the key `editorParams` if the editor was initialized on a previous page
2231
- */
2232
- _maybeLoadEditor: function(instance) {
2233
- try {
2234
- var parseFromUrl = false;
2235
- if (_.getHashParam(window.location.hash, 'state')) {
2236
- var state = _.getHashParam(window.location.hash, 'state');
2237
- state = JSON.parse(decodeURIComponent(state));
2238
- parseFromUrl = state['action'] === 'mpeditor';
2239
- }
2240
- var parseFromStorage = !!window.sessionStorage.getItem('_mpcehash');
2241
- var editorParams;
2242
-
2243
- if (parseFromUrl) { // happens if they are initializing the editor using an old snippet
2244
- editorParams = this._editorParamsFromHash(instance, window.location.hash);
2245
- } else if (parseFromStorage) { // happens if they are initialized the editor and using the new snippet
2246
- editorParams = this._editorParamsFromHash(instance, window.sessionStorage.getItem('_mpcehash'));
2247
- window.sessionStorage.removeItem('_mpcehash');
2248
- } else { // get credentials from sessionStorage from a previous initialzation
2249
- editorParams = JSON.parse(window.sessionStorage.getItem('editorParams') || '{}');
2250
- }
2251
-
2252
- if (editorParams['projectToken'] && instance.get_config('token') === editorParams['projectToken']) {
2253
- this._loadEditor(instance, editorParams);
2254
- return true;
2255
- } else {
2256
- return false;
2257
- }
2258
- } catch (e) {
2259
- return false;
2260
- }
2261
- },
2262
-
2263
- _loadEditor: function(instance, editorParams) {
2264
- if (!window['_mpEditorLoaded']) { // only load the codeless event editor once, even if there are multiple instances of MixpanelLib
2265
- window['_mpEditorLoaded'] = true;
2266
- var editorUrl = instance.get_config('app_host')
2267
- + '/js-bundle/reports/collect-everything/editor.js?_ts='
2268
- + (new Date()).getTime();
2269
- this._loadScript(editorUrl, function() {
2270
- window['mp_load_editor'](editorParams);
2271
- });
2272
- return true;
2273
- }
2274
- return false;
2275
- },
2276
-
2277
- // this is a mechanism to ramp up CE with no server-side interaction.
2278
- // when CE is active, every page load results in a decide request. we
2279
- // need to gently ramp this up so we don't overload decide. this decides
2280
- // deterministically if CE is enabled for this project by modding the char
2281
- // value of the project token.
2282
- enabledForProject: function(token, numBuckets, numEnabledBuckets) {
2283
- numBuckets = !_.isUndefined(numBuckets) ? numBuckets : 10;
2284
- numEnabledBuckets = !_.isUndefined(numEnabledBuckets) ? numEnabledBuckets : 10;
2285
- var charCodeSum = 0;
2286
- for (var i = 0; i < token.length; i++) {
2287
- charCodeSum += token.charCodeAt(i);
2288
- }
2289
- return (charCodeSum % numBuckets) < numEnabledBuckets;
2290
- },
2291
-
2292
- isBrowserSupported: function() {
2293
- return _.isFunction(document.querySelectorAll);
2294
- }
2295
- };
2296
-
2297
- _.bind_instance_methods(autotrack);
2298
- _.safewrap_instance_methods(autotrack);
2299
-
2300
1739
  /**
2301
1740
  * DomTracker Object
2302
1741
  * @constructor
@@ -2325,7 +1764,7 @@ DomTracker.prototype.track = function(query, event_name, properties, user_callba
2325
1764
  var elements = _.dom_query(query);
2326
1765
 
2327
1766
  if (elements.length === 0) {
2328
- console$1.error('The DOM query (' + query + ') returned 0 elements');
1767
+ console.error('The DOM query (' + query + ') returned 0 elements');
2329
1768
  return;
2330
1769
  }
2331
1770
 
@@ -2985,9 +2424,9 @@ RequestBatcher.prototype.flush = function(options) {
2985
2424
  } else if (
2986
2425
  _.isObject(res) &&
2987
2426
  res.xhr_req &&
2988
- (res.xhr_req['status'] >= 500 || res.xhr_req['status'] <= 0)
2427
+ (res.xhr_req['status'] >= 500 || res.xhr_req['status'] === 429 || res.error === 'timeout')
2989
2428
  ) {
2990
- // network or API error, retry
2429
+ // network or API error, or 429 Too Many Requests, retry
2991
2430
  var retryMS = this.flushInterval * 2;
2992
2431
  var headers = res.xhr_req['responseHeaders'];
2993
2432
  if (headers) {
@@ -3117,12 +2556,12 @@ function hasOptedIn(token, options) {
3117
2556
  */
3118
2557
  function hasOptedOut(token, options) {
3119
2558
  if (_hasDoNotTrackFlagOn(options)) {
3120
- console$1.warn('This browser has "Do Not Track" enabled. This will prevent the Mixpanel SDK from sending any data. To ignore the "Do Not Track" browser setting, initialize the Mixpanel instance with the config "ignore_dnt: true"');
2559
+ console.warn('This browser has "Do Not Track" enabled. This will prevent the Mixpanel SDK from sending any data. To ignore the "Do Not Track" browser setting, initialize the Mixpanel instance with the config "ignore_dnt: true"');
3121
2560
  return true;
3122
2561
  }
3123
2562
  var optedOut = _getStorageValue(token, options) === '0';
3124
2563
  if (optedOut) {
3125
- console$1.warn('You are opted out of Mixpanel tracking. This will prevent the Mixpanel SDK from sending any data.');
2564
+ console.warn('You are opted out of Mixpanel tracking. This will prevent the Mixpanel SDK from sending any data.');
3126
2565
  }
3127
2566
  return optedOut;
3128
2567
  }
@@ -3266,7 +2705,7 @@ function _hasDoNotTrackFlagOn(options) {
3266
2705
  */
3267
2706
  function _optInOut(optValue, token, options) {
3268
2707
  if (!_.isString(token) || !token.length) {
3269
- console$1.error('gdpr.' + (optValue ? 'optIn' : 'optOut') + ' called with an invalid token');
2708
+ console.error('gdpr.' + (optValue ? 'optIn' : 'optOut') + ' called with an invalid token');
3270
2709
  return;
3271
2710
  }
3272
2711
 
@@ -3317,7 +2756,7 @@ function _addOptOutCheck(method, getConfigValue) {
3317
2756
  });
3318
2757
  }
3319
2758
  } catch(err) {
3320
- console$1.error('Unexpected error when checking tracking opt-out status: ' + err);
2759
+ console.error('Unexpected error when checking tracking opt-out status: ' + err);
3321
2760
  }
3322
2761
 
3323
2762
  if (!optedOut) {
@@ -3557,9 +2996,13 @@ MixpanelGroup.prototype.union = addOptOutCheckMixpanelGroup(function(list_name,
3557
2996
  * Permanently delete a group.
3558
2997
  *
3559
2998
  * ### Usage:
2999
+ *
3560
3000
  * mixpanel.get_group('company', 'mixpanel').delete();
3001
+ *
3002
+ * @param {Function} [callback] If provided, the callback will be called after the tracking event
3561
3003
  */
3562
3004
  MixpanelGroup.prototype['delete'] = addOptOutCheckMixpanelGroup(function(callback) {
3005
+ // bracket notation above prevents a minification error related to reserved words
3563
3006
  var data = this.delete_action();
3564
3007
  return this._send_request(data, callback);
3565
3008
  });
@@ -3659,7 +3102,7 @@ var MixpanelPersistence = function(config) {
3659
3102
 
3660
3103
  var storage_type = config['persistence'];
3661
3104
  if (storage_type !== 'cookie' && storage_type !== 'localStorage') {
3662
- console$1.critical('Unknown persistence type ' + storage_type + '; falling back to cookie');
3105
+ console.critical('Unknown persistence type ' + storage_type + '; falling back to cookie');
3663
3106
  storage_type = config['persistence'] = 'cookie';
3664
3107
  }
3665
3108
 
@@ -4017,8 +3460,8 @@ MixpanelPersistence.prototype._add_to_people_queue = function(queue, data) {
4017
3460
  this._pop_from_people_queue(UNSET_ACTION, q_data);
4018
3461
  }
4019
3462
 
4020
- console$1.log('MIXPANEL PEOPLE REQUEST (QUEUED, PENDING IDENTIFY):');
4021
- console$1.log(data);
3463
+ console.log('MIXPANEL PEOPLE REQUEST (QUEUED, PENDING IDENTIFY):');
3464
+ console.log(data);
4022
3465
 
4023
3466
  this.save();
4024
3467
  };
@@ -4061,7 +3504,7 @@ MixpanelPersistence.prototype._get_queue_key = function(queue) {
4061
3504
  } else if (queue === UNION_ACTION) {
4062
3505
  return UNION_QUEUE_KEY;
4063
3506
  } else {
4064
- console$1.error('Invalid queue:', queue);
3507
+ console.error('Invalid queue:', queue);
4065
3508
  }
4066
3509
  };
4067
3510
 
@@ -6029,7 +5472,7 @@ MixpanelPeople.prototype.increment = addOptOutCheckMixpanelPeople(function(prop,
6029
5472
  _.each(prop, function(v, k) {
6030
5473
  if (!this._is_reserved_property(k)) {
6031
5474
  if (isNaN(parseFloat(v))) {
6032
- console$1.error('Invalid increment value passed to mixpanel.people.increment - must be a number');
5475
+ console.error('Invalid increment value passed to mixpanel.people.increment - must be a number');
6033
5476
  return;
6034
5477
  } else {
6035
5478
  $add[k] = v;
@@ -6153,7 +5596,7 @@ MixpanelPeople.prototype.track_charge = addOptOutCheckMixpanelPeople(function(am
6153
5596
  if (!_.isNumber(amount)) {
6154
5597
  amount = parseFloat(amount);
6155
5598
  if (isNaN(amount)) {
6156
- console$1.error('Invalid value passed to mixpanel.people.track_charge - must be a number');
5599
+ console.error('Invalid value passed to mixpanel.people.track_charge - must be a number');
6157
5600
  return;
6158
5601
  }
6159
5602
  }
@@ -6189,7 +5632,7 @@ MixpanelPeople.prototype.clear_charges = function(callback) {
6189
5632
  */
6190
5633
  MixpanelPeople.prototype.delete_user = function() {
6191
5634
  if (!this._identify_called()) {
6192
- console$1.error('mixpanel.people.delete_user() requires you to call identify() first');
5635
+ console.error('mixpanel.people.delete_user() requires you to call identify() first');
6193
5636
  return;
6194
5637
  }
6195
5638
  var data = {'$delete': this._mixpanel.get_distinct_id()};
@@ -6263,7 +5706,7 @@ MixpanelPeople.prototype._enqueue = function(data) {
6263
5706
  } else if (UNION_ACTION in data) {
6264
5707
  this._mixpanel['persistence']._add_to_people_queue(UNION_ACTION, data);
6265
5708
  } else {
6266
- console$1.error('Invalid call to _enqueue():', data);
5709
+ console.error('Invalid call to _enqueue():', data);
6267
5710
  }
6268
5711
  };
6269
5712
 
@@ -6400,6 +5843,8 @@ var IDENTITY_FUNC = function(x) {return x;};
6400
5843
  var NOOP_FUNC = function() {};
6401
5844
 
6402
5845
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
5846
+ /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
5847
+ /** @const */ var PAYLOAD_TYPE_JSON = 'json';
6403
5848
 
6404
5849
 
6405
5850
  /*
@@ -6430,8 +5875,8 @@ var DEFAULT_CONFIG = {
6430
5875
  'api_host': 'https://api-js.mixpanel.com',
6431
5876
  'api_method': 'POST',
6432
5877
  'api_transport': 'XHR',
5878
+ 'api_payload_format': PAYLOAD_TYPE_BASE64,
6433
5879
  'app_host': 'https://mixpanel.com',
6434
- 'autotrack': true,
6435
5880
  'cdn': 'https://cdn.mxpnl.com',
6436
5881
  'cross_site_cookie': false,
6437
5882
  'cross_subdomain_cookie': true,
@@ -6462,7 +5907,7 @@ var DEFAULT_CONFIG = {
6462
5907
  'inapp_protocol': '//',
6463
5908
  'inapp_link_new_window': false,
6464
5909
  'ignore_dnt': false,
6465
- 'batch_requests': false, // for now
5910
+ 'batch_requests': true,
6466
5911
  'batch_size': 50,
6467
5912
  'batch_flush_interval_ms': 5000,
6468
5913
  'batch_request_timeout_ms': 90000,
@@ -6495,7 +5940,7 @@ var create_mplib = function(token, config, name) {
6495
5940
  instance = target;
6496
5941
  } else {
6497
5942
  if (target && !_.isArray(target)) {
6498
- console$1.error('You have already initialized ' + name);
5943
+ console.error('You have already initialized ' + name);
6499
5944
  return;
6500
5945
  }
6501
5946
  instance = new MixpanelLib();
@@ -6514,21 +5959,6 @@ var create_mplib = function(token, config, name) {
6514
5959
  // global debug to be true
6515
5960
  Config.DEBUG = Config.DEBUG || instance.get_config('debug');
6516
5961
 
6517
- instance['__autotrack_enabled'] = instance.get_config('autotrack');
6518
- if (instance.get_config('autotrack')) {
6519
- var num_buckets = 100;
6520
- var num_enabled_buckets = 100;
6521
- if (!autotrack.enabledForProject(instance.get_config('token'), num_buckets, num_enabled_buckets)) {
6522
- instance['__autotrack_enabled'] = false;
6523
- console$1.log('Not in active bucket: disabling Automatic Event Collection.');
6524
- } else if (!autotrack.isBrowserSupported()) {
6525
- instance['__autotrack_enabled'] = false;
6526
- console$1.log('Disabling Automatic Event Collection because this browser is not supported');
6527
- } else {
6528
- autotrack.init(instance);
6529
- }
6530
- }
6531
-
6532
5962
  // if target is not defined, we called init after the lib already
6533
5963
  // loaded, so there won't be an array of things to execute
6534
5964
  if (!_.isUndefined(target) && _.isArray(target)) {
@@ -6541,12 +5971,6 @@ var create_mplib = function(token, config, name) {
6541
5971
  return instance;
6542
5972
  };
6543
5973
 
6544
- var encode_data_for_request = function(data) {
6545
- var json_data = _.JSONEncode(data);
6546
- var encoded_data = _.base64Encode(json_data);
6547
- return {'data': encoded_data};
6548
- };
6549
-
6550
5974
  // Initialization methods
6551
5975
 
6552
5976
  /**
@@ -6567,11 +5991,11 @@ var encode_data_for_request = function(data) {
6567
5991
  */
6568
5992
  MixpanelLib.prototype.init = function (token, config, name) {
6569
5993
  if (_.isUndefined(name)) {
6570
- console$1.error('You must name your new library: init(token, config, name)');
5994
+ console.error('You must name your new library: init(token, config, name)');
6571
5995
  return;
6572
5996
  }
6573
5997
  if (name === PRIMARY_INSTANCE_NAME) {
6574
- console$1.error('You must initialize the main mixpanel object right after you include the Mixpanel js snippet');
5998
+ console.error('You must initialize the main mixpanel object right after you include the Mixpanel js snippet');
6575
5999
  return;
6576
6000
  }
6577
6001
 
@@ -6596,14 +6020,14 @@ MixpanelLib.prototype._init = function(token, config, name) {
6596
6020
  this['config'] = {};
6597
6021
  this['_triggered_notifs'] = [];
6598
6022
 
6599
- // rollout: enable batch_requests by default for 60% of projects
6600
- // (only if they have not specified a value in their init config
6601
- // and they aren't using a custom API host)
6602
6023
  var variable_features = {};
6603
- var api_host = config['api_host'];
6604
- var is_custom_api = !!api_host && !api_host.match(/\.mixpanel\.com$/);
6605
- if (!('batch_requests' in config) && !is_custom_api && determine_eligibility(token, 'batch', 60)) {
6606
- variable_features['batch_requests'] = true;
6024
+
6025
+ // default to JSON payload for standard mixpanel.com API hosts
6026
+ if (!('api_payload_format' in config)) {
6027
+ var api_host = config['api_host'] || DEFAULT_CONFIG['api_host'];
6028
+ if (api_host.match(/\.mixpanel\.com$/)) {
6029
+ variable_features['api_payload_format'] = PAYLOAD_TYPE_JSON;
6030
+ }
6607
6031
  }
6608
6032
 
6609
6033
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
@@ -6628,19 +6052,36 @@ MixpanelLib.prototype._init = function(token, config, name) {
6628
6052
  if (this._batch_requests) {
6629
6053
  if (!_.localStorage.is_supported(true) || !USE_XHR) {
6630
6054
  this._batch_requests = false;
6631
- console$1.log('Turning off Mixpanel request-queueing; needs XHR and localStorage support');
6055
+ console.log('Turning off Mixpanel request-queueing; needs XHR and localStorage support');
6632
6056
  } else {
6633
6057
  this.init_batchers();
6634
6058
  if (sendBeacon && window$1.addEventListener) {
6635
- window$1.addEventListener('unload', _.bind(function() {
6636
- // Before page closes, attempt to flush any events queued up via navigator.sendBeacon.
6637
- // Since sendBeacon doesn't report success/failure, events will not be removed from
6638
- // the persistent store; if the site is loaded again, the events will be flushed again
6639
- // on startup and deduplicated on the Mixpanel server side.
6059
+ // Before page closes or hides (user tabs away etc), attempt to flush any events
6060
+ // queued up via navigator.sendBeacon. Since sendBeacon doesn't report success/failure,
6061
+ // events will not be removed from the persistent store; if the site is loaded again,
6062
+ // the events will be flushed again on startup and deduplicated on the Mixpanel server
6063
+ // side.
6064
+ // There is no reliable way to capture only page close events, so we lean on the
6065
+ // visibilitychange and pagehide events as recommended at
6066
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event#usage_notes.
6067
+ // These events fire when the user clicks away from the current page/tab, so will occur
6068
+ // more frequently than page unload, but are the only mechanism currently for capturing
6069
+ // this scenario somewhat reliably.
6070
+ var flush_on_unload = _.bind(function() {
6640
6071
  if (!this.request_batchers.events.stopped) {
6641
6072
  this.request_batchers.events.flush({unloading: true});
6642
6073
  }
6643
- }, this));
6074
+ }, this);
6075
+ window$1.addEventListener('pagehide', function(ev) {
6076
+ if (ev['persisted']) {
6077
+ flush_on_unload();
6078
+ }
6079
+ });
6080
+ window$1.addEventListener('visibilitychange', function() {
6081
+ if (document$1['visibilityState'] === 'hidden') {
6082
+ flush_on_unload();
6083
+ }
6084
+ });
6644
6085
  }
6645
6086
  }
6646
6087
  }
@@ -6696,7 +6137,7 @@ MixpanelLib.prototype._dom_loaded = function() {
6696
6137
 
6697
6138
  MixpanelLib.prototype._track_dom = function(DomClass, args) {
6698
6139
  if (this.get_config('img')) {
6699
- console$1.error('You can\'t use DOM tracking functions with img = true.');
6140
+ console.error('You can\'t use DOM tracking functions with img = true.');
6700
6141
  return false;
6701
6142
  }
6702
6143
 
@@ -6806,7 +6247,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
6806
6247
  try {
6807
6248
  succeeded = sendBeacon(url, body_data);
6808
6249
  } catch (e) {
6809
- console$1.error(e);
6250
+ console.error(e);
6810
6251
  succeeded = false;
6811
6252
  }
6812
6253
  try {
@@ -6814,7 +6255,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
6814
6255
  callback(succeeded ? 1 : 0);
6815
6256
  }
6816
6257
  } catch (e) {
6817
- console$1.error(e);
6258
+ console.error(e);
6818
6259
  }
6819
6260
  } else if (USE_XHR) {
6820
6261
  try {
@@ -6846,7 +6287,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
6846
6287
  try {
6847
6288
  response = _.JSONDecode(req.responseText);
6848
6289
  } catch (e) {
6849
- console$1.error(e);
6290
+ console.error(e);
6850
6291
  if (options.ignore_json_errors) {
6851
6292
  response = req.responseText;
6852
6293
  } else {
@@ -6869,7 +6310,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
6869
6310
  } else {
6870
6311
  error = 'Bad HTTP status: ' + req.status + ' ' + req.statusText;
6871
6312
  }
6872
- console$1.error(error);
6313
+ console.error(error);
6873
6314
  if (callback) {
6874
6315
  if (verbose_mode) {
6875
6316
  callback({status: 0, error: error, xhr_req: req});
@@ -6882,7 +6323,7 @@ MixpanelLib.prototype._send_request = function(url, data, options, callback) {
6882
6323
  };
6883
6324
  req.send(body_data);
6884
6325
  } catch (e) {
6885
- console$1.error(e);
6326
+ console.error(e);
6886
6327
  succeeded = false;
6887
6328
  }
6888
6329
  } else {
@@ -6965,7 +6406,7 @@ MixpanelLib.prototype.init_batchers = function() {
6965
6406
  sendRequestFunc: _.bind(function(data, options, cb) {
6966
6407
  this._send_request(
6967
6408
  this.get_config('api_host') + attrs.endpoint,
6968
- encode_data_for_request(data),
6409
+ this._encode_data_for_request(data),
6969
6410
  options,
6970
6411
  this._prepare_callback(cb, data)
6971
6412
  );
@@ -7039,6 +6480,14 @@ MixpanelLib.prototype.disable = function(events) {
7039
6480
  }
7040
6481
  };
7041
6482
 
6483
+ MixpanelLib.prototype._encode_data_for_request = function(data) {
6484
+ var encoded_data = _.JSONEncode(data);
6485
+ if (this.get_config('api_payload_format') === PAYLOAD_TYPE_BASE64) {
6486
+ encoded_data = _.base64Encode(encoded_data);
6487
+ }
6488
+ return {'data': encoded_data};
6489
+ };
6490
+
7042
6491
  // internal method for handling track vs batch-enqueue logic
7043
6492
  MixpanelLib.prototype._track_or_batch = function(options, callback) {
7044
6493
  var truncated_data = _.truncate(options.data, 255);
@@ -7054,11 +6503,11 @@ MixpanelLib.prototype._track_or_batch = function(options, callback) {
7054
6503
  truncated_data = this._run_hook('before_send_' + options.type, truncated_data);
7055
6504
  }
7056
6505
  if (truncated_data) {
7057
- console$1.log('MIXPANEL REQUEST:');
7058
- console$1.log(truncated_data);
6506
+ console.log('MIXPANEL REQUEST:');
6507
+ console.log(truncated_data);
7059
6508
  return this._send_request(
7060
6509
  endpoint,
7061
- encode_data_for_request(truncated_data),
6510
+ this._encode_data_for_request(truncated_data),
7062
6511
  send_request_options,
7063
6512
  this._prepare_callback(callback, truncated_data)
7064
6513
  );
@@ -7121,7 +6570,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
7121
6570
  }
7122
6571
 
7123
6572
  if (_.isUndefined(event_name)) {
7124
- console$1.error('No event name provided to mixpanel.track');
6573
+ console.error('No event name provided to mixpanel.track');
7125
6574
  return;
7126
6575
  }
7127
6576
 
@@ -7162,7 +6611,7 @@ MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, pro
7162
6611
  delete properties[blacklisted_prop];
7163
6612
  });
7164
6613
  } else {
7165
- console$1.error('Invalid value for property_blacklist config: ' + property_blacklist);
6614
+ console.error('Invalid value for property_blacklist config: ' + property_blacklist);
7166
6615
  }
7167
6616
 
7168
6617
  var data = {
@@ -7407,7 +6856,7 @@ MixpanelLib.prototype.track_forms = function() {
7407
6856
  */
7408
6857
  MixpanelLib.prototype.time_event = function(event_name) {
7409
6858
  if (_.isUndefined(event_name)) {
7410
- console$1.error('No event name provided to mixpanel.time_event');
6859
+ console.error('No event name provided to mixpanel.time_event');
7411
6860
  return;
7412
6861
  }
7413
6862
 
@@ -7680,7 +7129,7 @@ MixpanelLib.prototype.alias = function(alias, original) {
7680
7129
  // mixpanel.people.identify() call made for this user. It is VERY BAD to make an alias with
7681
7130
  // this ID, as it will duplicate users.
7682
7131
  if (alias === this.get_property(PEOPLE_DISTINCT_ID_KEY)) {
7683
- console$1.critical('Attempting to create alias for existing People user - aborting.');
7132
+ console.critical('Attempting to create alias for existing People user - aborting.');
7684
7133
  return -2;
7685
7134
  }
7686
7135
 
@@ -7700,7 +7149,7 @@ MixpanelLib.prototype.alias = function(alias, original) {
7700
7149
  _this.identify(alias);
7701
7150
  });
7702
7151
  } else {
7703
- console$1.error('alias matches current distinct_id - skipping api call.');
7152
+ console.error('alias matches current distinct_id - skipping api call.');
7704
7153
  this.identify(alias);
7705
7154
  return -1;
7706
7155
  }
@@ -7883,7 +7332,7 @@ MixpanelLib.prototype.get_config = function(prop_name) {
7883
7332
  MixpanelLib.prototype._run_hook = function(hook_name) {
7884
7333
  var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
7885
7334
  if (typeof ret === 'undefined') {
7886
- console$1.error(hook_name + ' hook did not return a value');
7335
+ console.error(hook_name + ' hook did not return a value');
7887
7336
  ret = null;
7888
7337
  }
7889
7338
  return ret;
@@ -7949,7 +7398,7 @@ MixpanelLib.prototype._check_and_handle_notifications = addOptOutCheckMixpanelLi
7949
7398
  return;
7950
7399
  }
7951
7400
 
7952
- console$1.log('MIXPANEL NOTIFICATION CHECK');
7401
+ console.log('MIXPANEL NOTIFICATION CHECK');
7953
7402
 
7954
7403
  var data = {
7955
7404
  'verbose': true,