http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/b4b0560b/extensions/web-tracker/wab/src/main/webapp/javascript/unomi-tracker.js ---------------------------------------------------------------------- diff --git a/extensions/web-tracker/wab/src/main/webapp/javascript/unomi-tracker.js b/extensions/web-tracker/wab/src/main/webapp/javascript/unomi-tracker.js deleted file mode 100644 index ae4bf20..0000000 --- a/extensions/web-tracker/wab/src/main/webapp/javascript/unomi-tracker.js +++ /dev/null @@ -1,12453 +0,0 @@ -/*! - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @license Apache-2.0 - */ - -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.unomiTracker = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var arity = require('@ndhoule/arity'); - -var objToString = Object.prototype.toString; - -/** - * Determine if a value is a function. - * - * @param {*} val - * @return {boolean} - */ -// TODO: Move to lib -var isFunction = function(val) { - return typeof val === 'function'; -}; - -/** - * Determine if a value is a number. - * - * @param {*} val - * @return {boolean} - */ -// TODO: Move to lib -var isNumber = function(val) { - var type = typeof val; - return type === 'number' || (type === 'object' && objToString.call(val) === '[object Number]'); -}; - -/** - * Wrap a function `fn` in a function that will invoke `fn` when invoked `n` or - * more times. - * - * @name after - * @api public - * @category Function - * @param {Number} n The number of - * @param {Function} fn The function to wrap. - * @return {Function} A function that will call `fn` after `n` or more - * invocations. - * @example - */ -var after = function after(n, fn) { - if (!isNumber(n)) { - throw new TypeError('Expected a number but received ' + typeof n); - } - - if (!isFunction(fn)) { - throw new TypeError('Expected a function but received ' + typeof fn); - } - - var callCount = 0; - - return arity(fn.length, function() { - callCount += 1; - - if (callCount < n) { - return; - } - - return fn.apply(this, arguments); - }); -}; - -/* - * Exports. - */ - -module.exports = after; - -},{"@ndhoule/arity":2}],2:[function(require,module,exports){ -'use strict'; - -var objToString = Object.prototype.toString; - -/** - * Determine if a value is a function. - * - * @param {*} val - * @return {boolean} - */ -// TODO: Move to lib -var isFunction = function(val) { - return typeof val === 'function'; -}; - -/** - * Determine if a value is a number. - * - * @param {*} val - * @return {boolean} - */ -// TODO: Move to lib -var isNumber = function(val) { - var type = typeof val; - return type === 'number' || (type === 'object' && objToString.call(val) === '[object Number]'); -}; - - /** - * Creates an array of generic, numbered argument names. - * - * @name createParams - * @api private - * @param {number} n - * @return {Array} - * @example - * argNames(2); - * //=> ['arg1', 'arg2'] - */ -var createParams = function createParams(n) { - var args = []; - - for (var i = 1; i <= n; i += 1) { - args.push('arg' + i); - } - - return args; -}; - - /** - * Dynamically construct a wrapper function of `n` arity that. - * - * If at all possible, prefer a function from the arity wrapper cache above to - * avoid allocating a new function at runtime. - * - * @name createArityWrapper - * @api private - * @param {number} n - * @return {Function(Function)} - */ -var createArityWrapper = function createArityWrapper(n) { - var paramNames = createParams(n).join(', '); - var wrapperBody = ''.concat( - ' return function(', paramNames, ') {\n', - ' return func.apply(this, arguments);\n', - ' };' - ); - - /* eslint-disable no-new-func */ - return new Function('func', wrapperBody); - /* eslint-enable no-new-func */ -}; - -// Cache common arity wrappers to avoid constructing them at runtime -var arityWrapperCache = [ - /* eslint-disable no-unused-vars */ - function(fn) { - return function() { - return fn.apply(this, arguments); - }; - }, - - function(fn) { - return function(arg1) { - return fn.apply(this, arguments); - }; - }, - - function(fn) { - return function(arg1, arg2) { - return fn.apply(this, arguments); - }; - }, - - function(fn) { - return function(arg1, arg2, arg3) { - return fn.apply(this, arguments); - }; - }, - - function(fn) { - return function(arg1, arg2, arg3, arg4) { - return fn.apply(this, arguments); - }; - }, - - function(fn) { - return function(arg1, arg2, arg3, arg4, arg5) { - return fn.apply(this, arguments); - }; - } - /* eslint-enable no-unused-vars */ -]; - -/** - * Takes a function and an [arity](https://en.wikipedia.org/wiki/Arity) `n`, and returns a new - * function that expects `n` arguments. - * - * @name arity - * @api public - * @category Function - * @see {@link curry} - * @param {Number} n The desired arity of the returned function. - * @param {Function} fn The function to wrap. - * @return {Function} A function of n arity, wrapping `fn`. - * @example - * var add = function(a, b) { - * return a + b; - * }; - * - * // Check the number of arguments this function expects by accessing `.length`: - * add.length; - * //=> 2 - * - * var unaryAdd = arity(1, add); - * unaryAdd.length; - * //=> 1 - */ -var arity = function arity(n, func) { - if (!isFunction(func)) { - throw new TypeError('Expected a function but got ' + typeof func); - } - - n = Math.max(isNumber(n) ? n : 0, 0); - - if (!arityWrapperCache[n]) { - arityWrapperCache[n] = createArityWrapper(n); - } - - return arityWrapperCache[n](func); -}; - -/* - * Exports. - */ - -module.exports = arity; - -},{}],3:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var type = require('component-type'); - -/** - * Deeply clone an object. - * - * @param {*} obj Any object. - */ - -var clone = function clone(obj) { - var t = type(obj); - - if (t === 'object') { - var copy = {}; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - copy[key] = clone(obj[key]); - } - } - return copy; - } - - if (t === 'array') { - var copy = new Array(obj.length); - for (var i = 0, l = obj.length; i < l; i++) { - copy[i] = clone(obj[i]); - } - return copy; - } - - if (t === 'regexp') { - // from millermedeiros/amd-utils - MIT - var flags = ''; - flags += obj.multiline ? 'm' : ''; - flags += obj.global ? 'g' : ''; - flags += obj.ignoreCase ? 'i' : ''; - return new RegExp(obj.source, flags); - } - - if (t === 'date') { - return new Date(obj.getTime()); - } - - // string, number, boolean, etc. - return obj; -}; - -/* - * Exports. - */ - -module.exports = clone; - -},{"component-type":53}],4:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var drop = require('@ndhoule/drop'); -var rest = require('@ndhoule/rest'); - -var has = Object.prototype.hasOwnProperty; -var objToString = Object.prototype.toString; - -/** - * Returns `true` if a value is an object, otherwise `false`. - * - * @name isObject - * @api private - * @param {*} val The value to test. - * @return {boolean} - */ -// TODO: Move to a library -var isObject = function isObject(value) { - return Boolean(value) && typeof value === 'object'; -}; - -/** - * Returns `true` if a value is a plain object, otherwise `false`. - * - * @name isPlainObject - * @api private - * @param {*} val The value to test. - * @return {boolean} - */ -// TODO: Move to a library -var isPlainObject = function isPlainObject(value) { - return Boolean(value) && objToString.call(value) === '[object Object]'; -}; - -/** - * Assigns a key-value pair to a target object when the value assigned is owned, - * and where target[key] is undefined. - * - * @name shallowCombiner - * @api private - * @param {Object} target - * @param {Object} source - * @param {*} value - * @param {string} key - */ -var shallowCombiner = function shallowCombiner(target, source, value, key) { - if (has.call(source, key) && target[key] === undefined) { - target[key] = value; - } - return source; -}; - -/** - * Assigns a key-value pair to a target object when the value assigned is owned, - * and where target[key] is undefined; also merges objects recursively. - * - * @name deepCombiner - * @api private - * @param {Object} target - * @param {Object} source - * @param {*} value - * @param {string} key - * @return {Object} - */ -var deepCombiner = function(target, source, value, key) { - if (has.call(source, key)) { - if (isPlainObject(target[key]) && isPlainObject(value)) { - target[key] = defaultsDeep(target[key], value); - } else if (target[key] === undefined) { - target[key] = value; - } - } - - return source; -}; - -/** - * TODO: Document - * - * @name defaultsWith - * @api private - * @param {Function} combiner - * @param {Object} target - * @param {...Object} sources - * @return {Object} Return the input `target`. - */ -var defaultsWith = function(combiner, target /*, ...sources */) { - if (!isObject(target)) { - return target; - } - - combiner = combiner || shallowCombiner; - var sources = drop(2, arguments); - - for (var i = 0; i < sources.length; i += 1) { - for (var key in sources[i]) { - combiner(target, sources[i], sources[i][key], key); - } - } - - return target; -}; - -/** - * Copies owned, enumerable properties from a source object(s) to a target - * object when the value of that property on the source object is `undefined`. - * Recurses on objects. - * - * @name defaultsDeep - * @api public - * @param {Object} target - * @param {...Object} sources - * @return {Object} The input `target`. - */ -var defaultsDeep = function defaultsDeep(target /*, sources */) { - // TODO: Replace with `partial` call? - return defaultsWith.apply(null, [deepCombiner, target].concat(rest(arguments))); -}; - -/** - * Copies owned, enumerable properties from a source object(s) to a target - * object when the value of that property on the source object is `undefined`. - * - * @name defaults - * @api public - * @param {Object} target - * @param {...Object} sources - * @return {Object} - * @example - * var a = { a: 1 }; - * var b = { a: 2, b: 2 }; - * - * defaults(a, b); - * console.log(a); //=> { a: 1, b: 2 } - */ -var defaults = function(target /*, ...sources */) { - // TODO: Replace with `partial` call? - return defaultsWith.apply(null, [null, target].concat(rest(arguments))); -}; - -/* - * Exports. - */ - -module.exports = defaults; -module.exports.deep = defaultsDeep; - -},{"@ndhoule/drop":5,"@ndhoule/rest":14}],5:[function(require,module,exports){ -'use strict'; - -var max = Math.max; - -/** - * Produce a new array composed of all but the first `n` elements of an input `collection`. - * - * @name drop - * @api public - * @param {number} count The number of elements to drop. - * @param {Array} collection The collection to iterate over. - * @return {Array} A new array containing all but the first element from `collection`. - * @example - * drop(0, [1, 2, 3]); // => [1, 2, 3] - * drop(1, [1, 2, 3]); // => [2, 3] - * drop(2, [1, 2, 3]); // => [3] - * drop(3, [1, 2, 3]); // => [] - * drop(4, [1, 2, 3]); // => [] - */ -var drop = function drop(count, collection) { - var length = collection ? collection.length : 0; - - if (!length) { - return []; - } - - // Preallocating an array *significantly* boosts performance when dealing with - // `arguments` objects on v8. For a summary, see: - // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments - var toDrop = max(Number(count) || 0, 0); - var resultsLength = max(length - toDrop, 0); - var results = new Array(resultsLength); - - for (var i = 0; i < resultsLength; i += 1) { - results[i] = collection[i + toDrop]; - } - - return results; -}; - -/* - * Exports. - */ - -module.exports = drop; - -},{}],6:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var keys = require('@ndhoule/keys'); - -var objToString = Object.prototype.toString; - -/** - * Tests if a value is a number. - * - * @name isNumber - * @api private - * @param {*} val The value to test. - * @return {boolean} Returns `true` if `val` is a number, otherwise `false`. - */ -// TODO: Move to library -var isNumber = function isNumber(val) { - var type = typeof val; - return type === 'number' || (type === 'object' && objToString.call(val) === '[object Number]'); -}; - -/** - * Tests if a value is an array. - * - * @name isArray - * @api private - * @param {*} val The value to test. - * @return {boolean} Returns `true` if the value is an array, otherwise `false`. - */ -// TODO: Move to library -var isArray = typeof Array.isArray === 'function' ? Array.isArray : function isArray(val) { - return objToString.call(val) === '[object Array]'; -}; - -/** - * Tests if a value is array-like. Array-like means the value is not a function and has a numeric - * `.length` property. - * - * @name isArrayLike - * @api private - * @param {*} val - * @return {boolean} - */ -// TODO: Move to library -var isArrayLike = function isArrayLike(val) { - return val != null && (isArray(val) || (val !== 'function' && isNumber(val.length))); -}; - -/** - * Internal implementation of `each`. Works on arrays and array-like data structures. - * - * @name arrayEach - * @api private - * @param {Function(value, key, collection)} iterator The function to invoke per iteration. - * @param {Array} array The array(-like) structure to iterate over. - * @return {undefined} - */ -var arrayEach = function arrayEach(iterator, array) { - for (var i = 0; i < array.length; i += 1) { - // Break iteration early if `iterator` returns `false` - if (iterator(array[i], i, array) === false) { - break; - } - } -}; - -/** - * Internal implementation of `each`. Works on objects. - * - * @name baseEach - * @api private - * @param {Function(value, key, collection)} iterator The function to invoke per iteration. - * @param {Object} object The object to iterate over. - * @return {undefined} - */ -var baseEach = function baseEach(iterator, object) { - var ks = keys(object); - - for (var i = 0; i < ks.length; i += 1) { - // Break iteration early if `iterator` returns `false` - if (iterator(object[ks[i]], ks[i], object) === false) { - break; - } - } -}; - -/** - * Iterate over an input collection, invoking an `iterator` function for each element in the - * collection and passing to it three arguments: `(value, index, collection)`. The `iterator` - * function can end iteration early by returning `false`. - * - * @name each - * @api public - * @param {Function(value, key, collection)} iterator The function to invoke per iteration. - * @param {Array|Object|string} collection The collection to iterate over. - * @return {undefined} Because `each` is run only for side effects, always returns `undefined`. - * @example - * var log = console.log.bind(console); - * - * each(log, ['a', 'b', 'c']); - * //-> 'a', 0, ['a', 'b', 'c'] - * //-> 'b', 1, ['a', 'b', 'c'] - * //-> 'c', 2, ['a', 'b', 'c'] - * //=> undefined - * - * each(log, 'tim'); - * //-> 't', 2, 'tim' - * //-> 'i', 1, 'tim' - * //-> 'm', 0, 'tim' - * //=> undefined - * - * // Note: Iteration order not guaranteed across environments - * each(log, { name: 'tim', occupation: 'enchanter' }); - * //-> 'tim', 'name', { name: 'tim', occupation: 'enchanter' } - * //-> 'enchanter', 'occupation', { name: 'tim', occupation: 'enchanter' } - * //=> undefined - */ -var each = function each(iterator, collection) { - return (isArrayLike(collection) ? arrayEach : baseEach).call(this, iterator, collection); -}; - -/* - * Exports. - */ - -module.exports = each; - -},{"@ndhoule/keys":11}],7:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var each = require('@ndhoule/each'); - -/** - * Check if a predicate function returns `true` for all values in a `collection`. - * Checks owned, enumerable values and exits early when `predicate` returns - * `false`. - * - * @name every - * @param {Function} predicate The function used to test values. - * @param {Array|Object|string} collection The collection to search. - * @return {boolean} True if all values passes the predicate test, otherwise false. - * @example - * var isEven = function(num) { return num % 2 === 0; }; - * - * every(isEven, []); // => true - * every(isEven, [1, 2]); // => false - * every(isEven, [2, 4, 6]); // => true - */ -var every = function every(predicate, collection) { - if (typeof predicate !== 'function') { - throw new TypeError('`predicate` must be a function but was a ' + typeof predicate); - } - - var result = true; - - each(function(val, key, collection) { - result = !!predicate(val, key, collection); - - // Exit early - if (!result) { - return false; - } - }, collection); - - return result; -}; - -/* - * Exports. - */ - -module.exports = every; - -},{"@ndhoule/each":6}],8:[function(require,module,exports){ -'use strict'; - -var has = Object.prototype.hasOwnProperty; - -/** - * Copy the properties of one or more `objects` onto a destination object. Input objects are iterated over - * in left-to-right order, so duplicate properties on later objects will overwrite those from - * erevious ones. Only enumerable and own properties of the input objects are copied onto the - * resulting object. - * - * @name extend - * @api public - * @category Object - * @param {Object} dest The destination object. - * @param {...Object} sources The source objects. - * @return {Object} `dest`, extended with the properties of all `sources`. - * @example - * var a = { a: 'a' }; - * var b = { b: 'b' }; - * var c = { c: 'c' }; - * - * extend(a, b, c); - * //=> { a: 'a', b: 'b', c: 'c' }; - */ -var extend = function extend(dest /*, sources */) { - var sources = Array.prototype.slice.call(arguments, 1); - - for (var i = 0; i < sources.length; i += 1) { - for (var key in sources[i]) { - if (has.call(sources[i], key)) { - dest[key] = sources[i][key]; - } - } - } - - return dest; -}; - -/* - * Exports. - */ - -module.exports = extend; - -},{}],9:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var each = require('@ndhoule/each'); - -/** - * Reduces all the values in a collection down into a single value. Does so by iterating through the - * collection from left to right, repeatedly calling an `iterator` function and passing to it four - * arguments: `(accumulator, value, index, collection)`. - * - * Returns the final return value of the `iterator` function. - * - * @name foldl - * @api public - * @param {Function} iterator The function to invoke per iteration. - * @param {*} accumulator The initial accumulator value, passed to the first invocation of `iterator`. - * @param {Array|Object} collection The collection to iterate over. - * @return {*} The return value of the final call to `iterator`. - * @example - * foldl(function(total, n) { - * return total + n; - * }, 0, [1, 2, 3]); - * //=> 6 - * - * var phonebook = { bob: '555-111-2345', tim: '655-222-6789', sheila: '655-333-1298' }; - * - * foldl(function(results, phoneNumber) { - * if (phoneNumber[0] === '6') { - * return results.concat(phoneNumber); - * } - * return results; - * }, [], phonebook); - * // => ['655-222-6789', '655-333-1298'] - */ -var foldl = function foldl(iterator, accumulator, collection) { - if (typeof iterator !== 'function') { - throw new TypeError('Expected a function but received a ' + typeof iterator); - } - - each(function(val, i, collection) { - accumulator = iterator(accumulator, val, i, collection); - }, collection); - - return accumulator; -}; - -/* - * Exports. - */ - -module.exports = foldl; - -},{"@ndhoule/each":6}],10:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var each = require('@ndhoule/each'); - -var strIndexOf = String.prototype.indexOf; - -/** - * Object.is/sameValueZero polyfill. - * - * @api private - * @param {*} value1 - * @param {*} value2 - * @return {boolean} - */ -// TODO: Move to library -var sameValueZero = function sameValueZero(value1, value2) { - // Normal values and check for 0 / -0 - if (value1 === value2) { - return value1 !== 0 || 1 / value1 === 1 / value2; - } - // NaN - return value1 !== value1 && value2 !== value2; -}; - -/** - * Searches a given `collection` for a value, returning true if the collection - * contains the value and false otherwise. Can search strings, arrays, and - * objects. - * - * @name includes - * @api public - * @param {*} searchElement The element to search for. - * @param {Object|Array|string} collection The collection to search. - * @return {boolean} - * @example - * includes(2, [1, 2, 3]); - * //=> true - * - * includes(4, [1, 2, 3]); - * //=> false - * - * includes(2, { a: 1, b: 2, c: 3 }); - * //=> true - * - * includes('a', { a: 1, b: 2, c: 3 }); - * //=> false - * - * includes('abc', 'xyzabc opq'); - * //=> true - * - * includes('nope', 'xyzabc opq'); - * //=> false - */ -var includes = function includes(searchElement, collection) { - var found = false; - - // Delegate to String.prototype.indexOf when `collection` is a string - if (typeof collection === 'string') { - return strIndexOf.call(collection, searchElement) !== -1; - } - - // Iterate through enumerable/own array elements and object properties. - each(function(value) { - if (sameValueZero(value, searchElement)) { - found = true; - // Exit iteration early when found - return false; - } - }, collection); - - return found; -}; - -/* - * Exports. - */ - -module.exports = includes; - -},{"@ndhoule/each":6}],11:[function(require,module,exports){ -'use strict'; - -var hop = Object.prototype.hasOwnProperty; -var strCharAt = String.prototype.charAt; -var toStr = Object.prototype.toString; - -/** - * Returns the character at a given index. - * - * @param {string} str - * @param {number} index - * @return {string|undefined} - */ -// TODO: Move to a library -var charAt = function(str, index) { - return strCharAt.call(str, index); -}; - -/** - * hasOwnProperty, wrapped as a function. - * - * @name has - * @api private - * @param {*} context - * @param {string|number} prop - * @return {boolean} - */ - -// TODO: Move to a library -var has = function has(context, prop) { - return hop.call(context, prop); -}; - -/** - * Returns true if a value is a string, otherwise false. - * - * @name isString - * @api private - * @param {*} val - * @return {boolean} - */ - -// TODO: Move to a library -var isString = function isString(val) { - return toStr.call(val) === '[object String]'; -}; - -/** - * Returns true if a value is array-like, otherwise false. Array-like means a - * value is not null, undefined, or a function, and has a numeric `length` - * property. - * - * @name isArrayLike - * @api private - * @param {*} val - * @return {boolean} - */ -// TODO: Move to a library -var isArrayLike = function isArrayLike(val) { - return val != null && (typeof val !== 'function' && typeof val.length === 'number'); -}; - - -/** - * indexKeys - * - * @name indexKeys - * @api private - * @param {} target - * @param {Function} pred - * @return {Array} - */ -var indexKeys = function indexKeys(target, pred) { - pred = pred || has; - - var results = []; - - for (var i = 0, len = target.length; i < len; i += 1) { - if (pred(target, i)) { - results.push(String(i)); - } - } - - return results; -}; - -/** - * Returns an array of an object's owned keys. - * - * @name objectKeys - * @api private - * @param {*} target - * @param {Function} pred Predicate function used to include/exclude values from - * the resulting array. - * @return {Array} - */ -var objectKeys = function objectKeys(target, pred) { - pred = pred || has; - - var results = []; - - for (var key in target) { - if (pred(target, key)) { - results.push(String(key)); - } - } - - return results; -}; - -/** - * Creates an array composed of all keys on the input object. Ignores any non-enumerable properties. - * More permissive than the native `Object.keys` function (non-objects will not throw errors). - * - * @name keys - * @api public - * @category Object - * @param {Object} source The value to retrieve keys from. - * @return {Array} An array containing all the input `source`'s keys. - * @example - * keys({ likes: 'avocado', hates: 'pineapple' }); - * //=> ['likes', 'pineapple']; - * - * // Ignores non-enumerable properties - * var hasHiddenKey = { name: 'Tim' }; - * Object.defineProperty(hasHiddenKey, 'hidden', { - * value: 'i am not enumerable!', - * enumerable: false - * }) - * keys(hasHiddenKey); - * //=> ['name']; - * - * // Works on arrays - * keys(['a', 'b', 'c']); - * //=> ['0', '1', '2'] - * - * // Skips unpopulated indices in sparse arrays - * var arr = [1]; - * arr[4] = 4; - * keys(arr); - * //=> ['0', '4'] - */ -var keys = function keys(source) { - if (source == null) { - return []; - } - - // IE6-8 compatibility (string) - if (isString(source)) { - return indexKeys(source, charAt); - } - - // IE6-8 compatibility (arguments) - if (isArrayLike(source)) { - return indexKeys(source, has); - } - - return objectKeys(source); -}; - -/* - * Exports. - */ - -module.exports = keys; - -},{}],12:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var each = require('@ndhoule/each'); - -/** - * Produce a new array by passing each value in the input `collection` through a transformative - * `iterator` function. The `iterator` function is passed three arguments: - * `(value, index, collection)`. - * - * @name map - * @api public - * @param {Function} iterator The transformer function to invoke per iteration. - * @param {Array} collection The collection to iterate over. - * @return {Array} A new array containing the results of each `iterator` invocation. - * @example - * var square = function(x) { return x * x; }; - * - * map(square, [1, 2, 3]); - * //=> [1, 4, 9] - */ -var map = function map(iterator, collection) { - if (typeof iterator !== 'function') { - throw new TypeError('Expected a function but received a ' + typeof iterator); - } - - var result = []; - - each(function(val, i, collection) { - result.push(iterator(val, i, collection)); - }, collection); - - return result; -}; - -/* - * Exports. - */ - -module.exports = map; - -},{"@ndhoule/each":6}],13:[function(require,module,exports){ -'use strict'; - -var objToString = Object.prototype.toString; - -// TODO: Move to lib -var existy = function(val) { - return val != null; -}; - -// TODO: Move to lib -var isArray = function(val) { - return objToString.call(val) === '[object Array]'; -}; - -// TODO: Move to lib -var isString = function(val) { - return typeof val === 'string' || objToString.call(val) === '[object String]'; -}; - -// TODO: Move to lib -var isObject = function(val) { - return val != null && typeof val === 'object'; -}; - -/** - * Returns a copy of the new `object` containing only the specified properties. - * - * @name pick - * @api public - * @param {string|string[]} props The property or properties to keep. - * @param {Object} object The object to iterate over. - * @return {Object} A new object containing only the specified properties from `object`. - * @example - * var person = { name: 'Tim', occupation: 'enchanter', fears: 'rabbits' }; - * - * pick('name', person); - * //=> { name: 'Tim' } - * - * pick(['name', 'fears'], person); - * //=> { name: 'Tim', fears: 'rabbits' } - */ -var pick = function pick(props, object) { - if (!existy(object) || !isObject(object)) { - return {}; - } - - if (isString(props)) { - props = [props]; - } - - if (!isArray(props)) { - props = []; - } - - var result = {}; - - for (var i = 0; i < props.length; i += 1) { - if (isString(props[i]) && props[i] in object) { - result[props[i]] = object[props[i]]; - } - } - - return result; -}; - -/* - * Exports. - */ - -module.exports = pick; - -},{}],14:[function(require,module,exports){ -'use strict'; - -var max = Math.max; - -/** - * Produce a new array by passing each value in the input `collection` through a transformative - * `iterator` function. The `iterator` function is passed three arguments: - * `(value, index, collection)`. - * - * @name rest - * @api public - * @param {Array} collection The collection to iterate over. - * @return {Array} A new array containing all but the first element from `collection`. - * @example - * rest([1, 2, 3]); // => [2, 3] - */ -var rest = function rest(collection) { - if (collection == null || !collection.length) { - return []; - } - - // Preallocating an array *significantly* boosts performance when dealing with - // `arguments` objects on v8. For a summary, see: - // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments - var results = new Array(max(collection.length - 2, 0)); - - for (var i = 1; i < collection.length; i += 1) { - results[i - 1] = collection[i]; - } - - return results; -}; - -/* - * Exports. - */ - -module.exports = rest; - -},{}],15:[function(require,module,exports){ -(function (global){ -'use strict'; - -var _analytics = global.analytics; - -/* - * Module dependencies. - */ - -var Alias = require('segmentio-facade').Alias; -var Emitter = require('component-emitter'); -var Group = require('segmentio-facade').Group; -var Identify = require('segmentio-facade').Identify; -var Page = require('segmentio-facade').Page; -var Track = require('segmentio-facade').Track; -var after = require('@ndhoule/after'); -var bindAll = require('bind-all'); -var clone = require('@ndhoule/clone'); -var extend = require('extend'); -var cookie = require('./cookie'); -var metrics = require('./metrics'); -var debug = require('debug'); -var defaults = require('@ndhoule/defaults'); -var each = require('@ndhoule/each'); -var foldl = require('@ndhoule/foldl'); -var group = require('./group'); -var is = require('is'); -var isMeta = require('@segment/is-meta'); -var keys = require('@ndhoule/keys'); -var memory = require('./memory'); -var nextTick = require('next-tick'); -var normalize = require('./normalize'); -var on = require('component-event').bind; -var pageDefaults = require('./pageDefaults'); -var pick = require('@ndhoule/pick'); -var prevent = require('@segment/prevent-default'); -var querystring = require('component-querystring'); -var store = require('./store'); -var user = require('./user'); -var type = require('component-type'); - -/** - * Initialize a new `Analytics` instance. - */ - -function Analytics() { - this._options({}); - this.Integrations = {}; - this._integrations = {}; - this._readied = false; - this._timeout = 300; - // XXX: BACKWARDS COMPATIBILITY - this._user = user; - this.log = debug('analytics.js'); - bindAll(this); - - var self = this; - this.on('initialize', function(settings, options) { - if (options.initialPageview) self.page(); - self._parseQuery(window.location.search); - }); -} - -/** - * Mix in event emitter. - */ - -Emitter(Analytics.prototype); - -/** - * Use a `plugin`. - * - * @param {Function} plugin - * @return {Analytics} - */ - -Analytics.prototype.use = function(plugin) { - plugin(this); - return this; -}; - -/** - * Define a new `Integration`. - * - * @param {Function} Integration - * @return {Analytics} - */ - -Analytics.prototype.addIntegration = function(Integration) { - var name = Integration.prototype.name; - if (!name) throw new TypeError('attempted to add an invalid integration'); - this.Integrations[name] = Integration; - return this; -}; - -/** - * Initialize with the given integration `settings` and `options`. - * - * Aliased to `init` for convenience. - * - * @param {Object} [settings={}] - * @param {Object} [options={}] - * @return {Analytics} - */ - -Analytics.prototype.init = Analytics.prototype.initialize = function( - settings, - options -) { - settings = settings || {}; - options = options || {}; - - this._options(options); - this._readied = false; - - // clean unknown integrations from settings - var self = this; - each(function(opts, name) { - var Integration = self.Integrations[name]; - if (!Integration) delete settings[name]; - }, settings); - - // add integrations - each(function(opts, name) { - // Don't load disabled integrations - if (options.integrations) { - if ( - options.integrations[name] === false || - (options.integrations.All === false && !options.integrations[name]) - ) { - return; - } - } - - var Integration = self.Integrations[name]; - var clonedOpts = {}; - extend(true, clonedOpts, opts); // deep clone opts - var integration = new Integration(clonedOpts); - self.log('initialize %o - %o', name, opts); - self.add(integration); - }, settings); - - var integrations = this._integrations; - - // load user now that options are set - user.load(); - group.load(); - - // make ready callback - var integrationCount = keys(integrations).length; - var ready = after(integrationCount, function() { - self._readied = true; - self.emit('ready'); - }); - - // init if no integrations - if (integrationCount <= 0) { - ready(); - } - - // initialize integrations, passing ready - // create a list of any integrations that did not initialize - this will be passed with all events for replay support: - this.failedInitializations = []; - each(function(integration) { - if ( - options.initialPageview && - integration.options.initialPageview === false - ) { - integration.page = after(2, integration.page); - } - - integration.analytics = self; - integration.once('ready', ready); - try { - metrics.increment('analytics_js.integration.invoke', { - method: 'initialize', - integration_name: integration.name - }); - integration.initialize(); - } catch (e) { - var integrationName = integration.name; - metrics.increment('analytics_js.integration.invoke.error', { - method: 'initialize', - integration_name: integration.name - }); - self.failedInitializations.push(integrationName); - self.log('Error initializing %s integration: %o', integrationName, e); - // Mark integration as ready to prevent blocking of anyone listening to analytics.ready() - integration.ready(); - } - }, integrations); - - // backwards compat with angular plugin. - // TODO: remove - this.initialized = true; - - this.emit('initialize', settings, options); - return this; -}; - -/** - * Set the user's `id`. - * - * @param {Mixed} id - */ - -Analytics.prototype.setAnonymousId = function(id) { - this.user().anonymousId(id); - return this; -}; - -/** - * Add an integration. - * - * @param {Integration} integration - */ - -Analytics.prototype.add = function(integration) { - this._integrations[integration.name] = integration; - return this; -}; - -/** - * Identify a user by optional `id` and `traits`. - * - * @param {string} [id=user.id()] User ID. - * @param {Object} [traits=null] User traits. - * @param {Object} [options=null] - * @param {Function} [fn] - * @return {Analytics} - */ - -Analytics.prototype.identify = function(id, traits, options, fn) { - // Argument reshuffling. - /* eslint-disable no-unused-expressions, no-sequences */ - if (is.fn(options)) (fn = options), (options = null); - if (is.fn(traits)) (fn = traits), (options = null), (traits = null); - if (is.object(id)) (options = traits), (traits = id), (id = user.id()); - /* eslint-enable no-unused-expressions, no-sequences */ - - // clone traits before we manipulate so we don't do anything uncouth, and take - // from `user` so that we carryover anonymous traits - user.identify(id, traits); - - var msg = this.normalize({ - options: options, - traits: user.traits(), - userId: user.id() - }); - - // Add the initialize integrations so the server-side ones can be disabled too - if (this.options.integrations) { - defaults(msg.integrations, this.options.integrations); - } - - this._invoke('identify', new Identify(msg)); - - // emit - this.emit('identify', id, traits, options); - this._callback(fn); - return this; -}; - -/** - * Return the current user. - * - * @return {Object} - */ - -Analytics.prototype.user = function() { - return user; -}; - -/** - * Identify a group by optional `id` and `traits`. Or, if no arguments are - * supplied, return the current group. - * - * @param {string} [id=group.id()] Group ID. - * @param {Object} [traits=null] Group traits. - * @param {Object} [options=null] - * @param {Function} [fn] - * @return {Analytics|Object} - */ - -Analytics.prototype.group = function(id, traits, options, fn) { - /* eslint-disable no-unused-expressions, no-sequences */ - if (!arguments.length) return group; - if (is.fn(options)) (fn = options), (options = null); - if (is.fn(traits)) (fn = traits), (options = null), (traits = null); - if (is.object(id)) (options = traits), (traits = id), (id = group.id()); - /* eslint-enable no-unused-expressions, no-sequences */ - - // grab from group again to make sure we're taking from the source - group.identify(id, traits); - - var msg = this.normalize({ - options: options, - traits: group.traits(), - groupId: group.id() - }); - - // Add the initialize integrations so the server-side ones can be disabled too - if (this.options.integrations) { - defaults(msg.integrations, this.options.integrations); - } - - this._invoke('group', new Group(msg)); - - this.emit('group', id, traits, options); - this._callback(fn); - return this; -}; - -/** - * Track an `event` that a user has triggered with optional `properties`. - * - * @param {string} event - * @param {Object} [properties=null] - * @param {Object} [options=null] - * @param {Function} [fn] - * @return {Analytics} - */ - -Analytics.prototype.track = function(event, properties, options, fn) { - // Argument reshuffling. - /* eslint-disable no-unused-expressions, no-sequences */ - if (is.fn(options)) (fn = options), (options = null); - if (is.fn(properties)) - (fn = properties), (options = null), (properties = null); - /* eslint-enable no-unused-expressions, no-sequences */ - - // figure out if the event is archived. - var plan = this.options.plan || {}; - var events = plan.track || {}; - var planIntegrationOptions = {}; - - // normalize - var msg = this.normalize({ - properties: properties, - options: options, - event: event - }); - - // plan. - plan = events[event]; - if (plan) { - this.log('plan %o - %o', event, plan); - if (plan.enabled === false) { - // Disabled events should always be sent to Segment. - planIntegrationOptions = { All: false, 'Segment.io': true }; - } else { - planIntegrationOptions = plan.integrations || {}; - } - } else { - var defaultPlan = events.__default || { enabled: true }; - if (!defaultPlan.enabled) { - // Disabled events should always be sent to Segment. - planIntegrationOptions = { All: false, 'Segment.io': true }; - } - } - - // Add the initialize integrations so the server-side ones can be disabled too - defaults( - msg.integrations, - this._mergeInitializeAndPlanIntegrations(planIntegrationOptions) - ); - - this._invoke('track', new Track(msg)); - - this.emit('track', event, properties, options); - this._callback(fn); - return this; -}; - -/** - * Helper method to track an outbound link that would normally navigate away - * from the page before the analytics calls were sent. - * - * BACKWARDS COMPATIBILITY: aliased to `trackClick`. - * - * @param {Element|Array} links - * @param {string|Function} event - * @param {Object|Function} properties (optional) - * @return {Analytics} - */ - -Analytics.prototype.trackClick = Analytics.prototype.trackLink = function( - links, - event, - properties -) { - if (!links) return this; - // always arrays, handles jquery - if (type(links) === 'element') links = [links]; - - var self = this; - each(function(el) { - if (type(el) !== 'element') { - throw new TypeError('Must pass HTMLElement to `analytics.trackLink`.'); - } - on(el, 'click', function(e) { - var ev = is.fn(event) ? event(el) : event; - var props = is.fn(properties) ? properties(el) : properties; - var href = - el.getAttribute('href') || - el.getAttributeNS('http://www.w3.org/1999/xlink', 'href') || - el.getAttribute('xlink:href'); - - self.track(ev, props); - - if (href && el.target !== '_blank' && !isMeta(e)) { - prevent(e); - self._callback(function() { - window.location.href = href; - }); - } - }); - }, links); - - return this; -}; - -/** - * Helper method to track an outbound form that would normally navigate away - * from the page before the analytics calls were sent. - * - * BACKWARDS COMPATIBILITY: aliased to `trackSubmit`. - * - * @param {Element|Array} forms - * @param {string|Function} event - * @param {Object|Function} properties (optional) - * @return {Analytics} - */ - -Analytics.prototype.trackSubmit = Analytics.prototype.trackForm = function( - forms, - event, - properties -) { - if (!forms) return this; - // always arrays, handles jquery - if (type(forms) === 'element') forms = [forms]; - - var self = this; - each(function(el) { - if (type(el) !== 'element') - throw new TypeError('Must pass HTMLElement to `analytics.trackForm`.'); - function handler(e) { - prevent(e); - - var ev = is.fn(event) ? event(el) : event; - var props = is.fn(properties) ? properties(el) : properties; - self.track(ev, props); - - self._callback(function() { - el.submit(); - }); - } - - // Support the events happening through jQuery or Zepto instead of through - // the normal DOM API, because `el.submit` doesn't bubble up events... - var $ = window.jQuery || window.Zepto; - if ($) { - $(el).submit(handler); - } else { - on(el, 'submit', handler); - } - }, forms); - - return this; -}; - -/** - * Trigger a pageview, labeling the current page with an optional `category`, - * `name` and `properties`. - * - * @param {string} [category] - * @param {string} [name] - * @param {Object|string} [properties] (or path) - * @param {Object} [options] - * @param {Function} [fn] - * @return {Analytics} - */ - -Analytics.prototype.page = function(category, name, properties, options, fn) { - // Argument reshuffling. - /* eslint-disable no-unused-expressions, no-sequences */ - if (is.fn(options)) (fn = options), (options = null); - if (is.fn(properties)) (fn = properties), (options = properties = null); - if (is.fn(name)) (fn = name), (options = properties = name = null); - if (type(category) === 'object') - (options = name), (properties = category), (name = category = null); - if (type(name) === 'object') - (options = properties), (properties = name), (name = null); - if (type(category) === 'string' && type(name) !== 'string') - (name = category), (category = null); - /* eslint-enable no-unused-expressions, no-sequences */ - - properties = clone(properties) || {}; - if (name) properties.name = name; - if (category) properties.category = category; - - // Ensure properties has baseline spec properties. - // TODO: Eventually move these entirely to `options.context.page` - var defs = pageDefaults(); - defaults(properties, defs); - - // Mirror user overrides to `options.context.page` (but exclude custom properties) - // (Any page defaults get applied in `this.normalize` for consistency.) - // Weird, yeah--moving special props to `context.page` will fix this in the long term. - var overrides = pick(keys(defs), properties); - if (!is.empty(overrides)) { - options = options || {}; - options.context = options.context || {}; - options.context.page = overrides; - } - - var msg = this.normalize({ - properties: properties, - category: category, - options: options, - name: name - }); - - // Add the initialize integrations so the server-side ones can be disabled too - if (this.options.integrations) { - defaults(msg.integrations, this.options.integrations); - } - - this._invoke('page', new Page(msg)); - - this.emit('page', category, name, properties, options); - this._callback(fn); - return this; -}; - -/** - * FIXME: BACKWARDS COMPATIBILITY: convert an old `pageview` to a `page` call. - * - * @param {string} [url] - * @return {Analytics} - * @api private - */ - -Analytics.prototype.pageview = function(url) { - var properties = {}; - if (url) properties.path = url; - this.page(properties); - return this; -}; - -/** - * Merge two previously unassociated user identities. - * - * @param {string} to - * @param {string} from (optional) - * @param {Object} options (optional) - * @param {Function} fn (optional) - * @return {Analytics} - */ - -Analytics.prototype.alias = function(to, from, options, fn) { - // Argument reshuffling. - /* eslint-disable no-unused-expressions, no-sequences */ - if (is.fn(options)) (fn = options), (options = null); - if (is.fn(from)) (fn = from), (options = null), (from = null); - if (is.object(from)) (options = from), (from = null); - /* eslint-enable no-unused-expressions, no-sequences */ - - var msg = this.normalize({ - options: options, - previousId: from, - userId: to - }); - - // Add the initialize integrations so the server-side ones can be disabled too - if (this.options.integrations) { - defaults(msg.integrations, this.options.integrations); - } - - this._invoke('alias', new Alias(msg)); - - this.emit('alias', to, from, options); - this._callback(fn); - return this; -}; - -/** - * Register a `fn` to be fired when all the analytics services are ready. - * - * @param {Function} fn - * @return {Analytics} - */ - -Analytics.prototype.ready = function(fn) { - if (is.fn(fn)) { - if (this._readied) { - nextTick(fn); - } else { - this.once('ready', fn); - } - } - return this; -}; - -/** - * Set the `timeout` (in milliseconds) used for callbacks. - * - * @param {Number} timeout - */ - -Analytics.prototype.timeout = function(timeout) { - this._timeout = timeout; -}; - -/** - * Enable or disable debug. - * - * @param {string|boolean} str - */ - -Analytics.prototype.debug = function(str) { - if (!arguments.length || str) { - debug.enable('analytics:' + (str || '*')); - } else { - debug.disable(); - } -}; - -/** - * Apply options. - * - * @param {Object} options - * @return {Analytics} - * @api private - */ - -Analytics.prototype._options = function(options) { - options = options || {}; - this.options = options; - cookie.options(options.cookie); - metrics.options(options.metrics); - store.options(options.localStorage); - user.options(options.user); - group.options(options.group); - return this; -}; - -/** - * Callback a `fn` after our defined timeout period. - * - * @param {Function} fn - * @return {Analytics} - * @api private - */ - -Analytics.prototype._callback = function(fn) { - if (is.fn(fn)) { - this._timeout ? setTimeout(fn, this._timeout) : nextTick(fn); - } - return this; -}; - -/** - * Call `method` with `facade` on all enabled integrations. - * - * @param {string} method - * @param {Facade} facade - * @return {Analytics} - * @api private - */ - -Analytics.prototype._invoke = function(method, facade) { - var self = this; - metrics.increment('analytics_js.invoke', { - method: method - }); - this.emit('invoke', facade); - - var failedInitializations = self.failedInitializations || []; - each(function(integration, name) { - if (!facade.enabled(name)) return; - // Check if an integration failed to initialize. - // If so, do not process the message as the integration is in an unstable state. - if (failedInitializations.indexOf(name) >= 0) { - self.log( - 'Skipping invokation of .%s method of %s integration. Integation failed to initialize properly.', - method, - name - ); - } else { - try { - metrics.increment('analytics_js.integration.invoke', { - method: method, - integration_name: integration.name - }); - integration.invoke.call(integration, method, facade); - } catch (e) { - metrics.increment('analytics_js.integration.invoke.error', { - method: method, - integration_name: integration.name - }); - self.log( - 'Error invoking .%s method of %s integration: %o', - method, - name, - e - ); - } - } - }, this._integrations); - - return this; -}; - -/** - * Push `args`. - * - * @param {Array} args - * @api private - */ - -Analytics.prototype.push = function(args) { - var method = args.shift(); - if (!this[method]) return; - this[method].apply(this, args); -}; - -/** - * Reset group and user traits and id's. - * - * @api public - */ - -Analytics.prototype.reset = function() { - this.user().logout(); - this.group().logout(); -}; - -/** - * Parse the query string for callable methods. - * - * @param {String} query - * @return {Analytics} - * @api private - */ - -Analytics.prototype._parseQuery = function(query) { - // Parse querystring to an object - var q = querystring.parse(query); - // Create traits and properties objects, populate from querysting params - var traits = pickPrefix('ajs_trait_', q); - var props = pickPrefix('ajs_prop_', q); - // Trigger based on callable parameters in the URL - if (q.ajs_uid) this.identify(q.ajs_uid, traits); - if (q.ajs_event) this.track(q.ajs_event, props); - if (q.ajs_aid) user.anonymousId(q.ajs_aid); - return this; - - /** - * Create a shallow copy of an input object containing only the properties - * whose keys are specified by a prefix, stripped of that prefix - * - * @param {String} prefix - * @param {Object} object - * @return {Object} - * @api private - */ - - function pickPrefix(prefix, object) { - var length = prefix.length; - var sub; - return foldl( - function(acc, val, key) { - if (key.substr(0, length) === prefix) { - sub = key.substr(length); - acc[sub] = val; - } - return acc; - }, - {}, - object - ); - } -}; - -/** - * Normalize the given `msg`. - * - * @param {Object} msg - * @return {Object} - */ - -Analytics.prototype.normalize = function(msg) { - msg = normalize(msg, keys(this._integrations)); - if (msg.anonymousId) user.anonymousId(msg.anonymousId); - msg.anonymousId = user.anonymousId(); - - // Ensure all outgoing requests include page data in their contexts. - msg.context.page = defaults(msg.context.page || {}, pageDefaults()); - - return msg; -}; - -/** - * Merges the tracking plan and initialization integration options. - * - * @param {Object} planIntegrations Tracking plan integrations. - * @return {Object} The merged integrations. - */ -Analytics.prototype._mergeInitializeAndPlanIntegrations = function( - planIntegrations -) { - // Do nothing if there are no initialization integrations - if (!this.options.integrations) { - return planIntegrations; - } - - // Clone the initialization integrations - var integrations = extend({}, this.options.integrations); - var integrationName; - - // Allow the tracking plan to disable integrations that were explicitly - // enabled on initialization - if (planIntegrations.All === false) { - integrations = { All: false }; - } - - for (integrationName in planIntegrations) { - if (planIntegrations.hasOwnProperty(integrationName)) { - // Don't allow the tracking plan to re-enable disabled integrations - if (this.options.integrations[integrationName] !== false) { - integrations[integrationName] = planIntegrations[integrationName]; - } - } - } - - return integrations; -}; - -/** - * No conflict support. - */ - -Analytics.prototype.noConflict = function() { - window.analytics = _analytics; - return this; -}; - -/* - * Exports. - */ - -module.exports = Analytics; -module.exports.cookie = cookie; -module.exports.memory = memory; -module.exports.store = store; -module.exports.metrics = metrics; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./cookie":16,"./group":18,"./memory":20,"./metrics":21,"./normalize":22,"./pageDefaults":23,"./store":24,"./user":25,"@ndhoule/after":1,"@ndhoule/clone":3,"@ndhoule/defaults":4,"@ndhoule/each":6,"@ndhoule/foldl":9,"@ndhoule/keys":11,"@ndhoule/pick":13,"@segment/is-meta":34,"@segment/prevent-default":38,"bind-all":43,"component-emitter":48,"component-event":49,"component-querystring":51,"component-type":53,"debug":26,"extend":58,"is":62,"next-tick":71,"segmentio-facade":81}],16:[function(require,module,exports){ -'use strict'; - -/** - * Module dependencies. - */ - -var bindAll = require('bind-all'); -var clone = require('@ndhoule/clone'); -var cookie = require('component-cookie'); -var debug = require('debug')('analytics.js:cookie'); -var defaults = require('@ndhoule/defaults'); -var json = require('json3'); -var topDomain = require('@segment/top-domain'); - -/** - * Initialize a new `Cookie` with `options`. - * - * @param {Object} options - */ - -function Cookie(options) { - this.options(options); -} - -/** - * Get or set the cookie options. - * - * @param {Object} options - * @field {Number} maxage (1 year) - * @field {String} domain - * @field {String} path - * @field {Boolean} secure - */ - -Cookie.prototype.options = function(options) { - if (arguments.length === 0) return this._options; - - options = options || {}; - - var domain = '.' + topDomain(window.location.href); - if (domain === '.') domain = null; - - this._options = defaults(options, { - // default to a year - maxage: 31536000000, - path: '/', - domain: domain - }); - - // http://curl.haxx.se/rfc/cookie_spec.html - // https://publicsuffix.org/list/effective_tld_names.dat - // - // try setting a dummy cookie with the options - // if the cookie isn't set, it probably means - // that the domain is on the public suffix list - // like myapp.herokuapp.com or localhost / ip. - this.set('ajs:test', true); - if (!this.get('ajs:test')) { - debug('fallback to domain=null'); - this._options.domain = null; - } - this.remove('ajs:test'); -}; - -/** - * Set a `key` and `value` in our cookie. - * - * @param {String} key - * @param {Object} value - * @return {Boolean} saved - */ - -Cookie.prototype.set = function(key, value) { - try { - value = json.stringify(value); - cookie(key, value, clone(this._options)); - return true; - } catch (e) { - return false; - } -}; - -/** - * Get a value from our cookie by `key`. - * - * @param {String} key - * @return {Object} value - */ - -Cookie.prototype.get = function(key) { - try { - var value = cookie(key); - value = value ? json.parse(value) : null; - return value; - } catch (e) { - return null; - } -}; - -/** - * Remove a value from our cookie by `key`. - * - * @param {String} key - * @return {Boolean} removed - */ - -Cookie.prototype.remove = function(key) { - try { - cookie(key, null, clone(this._options)); - return true; - } catch (e) { - return false; - } -}; - -/** - * Expose the cookie singleton. - */ - -module.exports = bindAll(new Cookie()); - -/** - * Expose the `Cookie` constructor. - */ - -module.exports.Cookie = Cookie; - -},{"@ndhoule/clone":3,"@ndhoule/defaults":4,"@segment/top-domain":41,"bind-all":43,"component-cookie":45,"debug":26,"json3":63}],17:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var clone = require('@ndhoule/clone'); -var cookie = require('./cookie'); -var debug = require('debug')('analytics:entity'); -var defaults = require('@ndhoule/defaults'); -var extend = require('@ndhoule/extend'); -var memory = require('./memory'); -var store = require('./store'); -var isodateTraverse = require('@segment/isodate-traverse'); - -/** - * Expose `Entity` - */ - -module.exports = Entity; - -/** - * Initialize new `Entity` with `options`. - * - * @param {Object} options - */ - -function Entity(options) { - this.options(options); - this.initialize(); -} - -/** - * Initialize picks the storage. - * - * Checks to see if cookies can be set - * otherwise fallsback to localStorage. - */ - -Entity.prototype.initialize = function() { - cookie.set('ajs:cookies', true); - - // cookies are enabled. - if (cookie.get('ajs:cookies')) { - cookie.remove('ajs:cookies'); - this._storage = cookie; - return; - } - - // localStorage is enabled. - if (store.enabled) { - this._storage = store; - return; - } - - // fallback to memory storage. - debug( - 'warning using memory store both cookies and localStorage are disabled' - ); - this._storage = memory; -}; - -/** - * Get the storage. - */ - -Entity.prototype.storage = function() { - return this._storage; -}; - -/** - * Get or set storage `options`. - * - * @param {Object} options - * @property {Object} cookie - * @property {Object} localStorage - * @property {Boolean} persist (default: `true`) - */ - -Entity.prototype.options = function(options) { - if (arguments.length === 0) return this._options; - this._options = defaults(options || {}, this.defaults || {}); -}; - -/** - * Get or set the entity's `id`. - * - * @param {String} id - */ - -Entity.prototype.id = function(id) { - switch (arguments.length) { - case 0: - return this._getId(); - case 1: - return this._setId(id); - default: - // No default case - } -}; - -/** - * Get the entity's id. - * - * @return {String} - */ - -Entity.prototype._getId = function() { - var ret = this._options.persist - ? this.storage().get(this._options.cookie.key) - : this._id; - return ret === undefined ? null : ret; -}; - -/** - * Set the entity's `id`. - * - * @param {String} id - */ - -Entity.prototype._setId = function(id) { - if (this._options.persist) { - this.storage().set(this._options.cookie.key, id); - } else { - this._id = id; - } -}; - -/** - * Get or set the entity's `traits`. - * - * BACKWARDS COMPATIBILITY: aliased to `properties` - * - * @param {Object} traits - */ - -Entity.prototype.properties = Entity.prototype.traits = function(traits) { - switch (arguments.length) { - case 0: - return this._getTraits(); - case 1: - return this._setTraits(traits); - default: - // No default case - } -}; - -/** - * Get the entity's traits. Always convert ISO date strings into real dates, - * since they aren't parsed back from local storage. - * - * @return {Object} - */ - -Entity.prototype._getTraits = function() { - var ret = this._options.persist - ? store.get(this._options.localStorage.key) - : this._traits; - return ret ? isodateTraverse(clone(ret)) : {}; -}; - -/** - * Set the entity's `traits`. - * - * @param {Object} traits - */ - -Entity.prototype._setTraits = function(traits) { - traits = traits || {}; - if (this._options.persist) { - store.set(this._options.localStorage.key, traits); - } else { - this._traits = traits; - } -}; - -/** - * Identify the entity with an `id` and `traits`. If we it's the same entity, - * extend the existing `traits` instead of overwriting. - * - * @param {String} id - * @param {Object} traits - */ - -Entity.prototype.identify = function(id, traits) { - traits = traits || {}; - var current = this.id(); - if (current === null || current === id) - traits = extend(this.traits(), traits); - if (id) this.id(id); - this.debug('identify %o, %o', id, traits); - this.traits(traits); - this.save(); -}; - -/** - * Save the entity to local storage and the cookie. - * - * @return {Boolean} - */ - -Entity.prototype.save = function() { - if (!this._options.persist) return false; - cookie.set(this._options.cookie.key, this.id()); - store.set(this._options.localStorage.key, this.traits()); - return true; -}; - -/** - * Log the entity out, reseting `id` and `traits` to defaults. - */ - -Entity.prototype.logout = function() { - this.id(null); - this.traits({}); - cookie.remove(this._options.cookie.key); - store.remove(this._options.localStorage.key); -}; - -/** - * Reset all entity state, logging out and returning options to defaults. - */ - -Entity.prototype.reset = function() { - this.logout(); - this.options({}); -}; - -/** - * Load saved entity `id` or `traits` from storage. - */ - -Entity.prototype.load = function() { - this.id(cookie.get(this._options.cookie.key)); - this.traits(store.get(this._options.localStorage.key)); -}; - -},{"./cookie":16,"./memory":20,"./store":24,"@ndhoule/clone":3,"@ndhoule/defaults":4,"@ndhoule/extend":8,"@segment/isodate-traverse":35,"debug":26}],18:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var Entity = require('./entity'); -var bindAll = require('bind-all'); -var debug = require('debug')('analytics:group'); -var inherit = require('inherits'); - -/** - * Group defaults - */ - -Group.defaults = { - persist: true, - cookie: { - key: 'ajs_group_id' - }, - localStorage: { - key: 'ajs_group_properties' - } -}; - -/** - * Initialize a new `Group` with `options`. - * - * @param {Object} options - */ - -function Group(options) { - this.defaults = Group.defaults; - this.debug = debug; - Entity.call(this, options); -} - -/** - * Inherit `Entity` - */ - -inherit(Group, Entity); - -/** - * Expose the group singleton. - */ - -module.exports = bindAll(new Group()); - -/** - * Expose the `Group` constructor. - */ - -module.exports.Group = Group; - -},{"./entity":17,"bind-all":43,"debug":26,"inherits":60}],19:[function(require,module,exports){ -'use strict'; - -/** - * Analytics.js - * - * (C) 2013-2016 Segment.io Inc. - */ - -var Analytics = require('./analytics'); - -// Create a new `analytics` singleton. -var analytics = new Analytics(); - -// Expose `require`. -// TODO(ndhoule): Look into deprecating, we no longer need to expose it in tests -//analytics.require = require; - -// Expose package version. -analytics.VERSION = require('../package.json').version; - -/* - * Exports. - */ - -module.exports = analytics; - -},{"../package.json":27,"./analytics":15}],20:[function(require,module,exports){ -'use strict'; - -/* - * Module Dependencies. - */ - -var bindAll = require('bind-all'); -var clone = require('@ndhoule/clone'); - -/** - * HOP. - */ - -var has = Object.prototype.hasOwnProperty; - -/** - * Expose `Memory` - */ - -module.exports = bindAll(new Memory()); - -/** - * Initialize `Memory` store - */ - -function Memory() { - this.store = {}; -} - -/** - * Set a `key` and `value`. - * - * @param {String} key - * @param {Mixed} value - * @return {Boolean} - */ - -Memory.prototype.set = function(key, value) { - this.store[key] = clone(value); - return true; -}; - -/** - * Get a `key`. - * - * @param {String} key - */ - -Memory.prototype.get = function(key) { - if (!has.call(this.store, key)) return; - return clone(this.store[key]); -}; - -/** - * Remove a `key`. - * - * @param {String} key - * @return {Boolean} - */ - -Memory.prototype.remove = function(key) { - delete this.store[key]; - return true; -}; - -},{"@ndhoule/clone":3,"bind-all":43}],21:[function(require,module,exports){ -'use strict'; - -var bindAll = require('bind-all'); -var send = require('@segment/send-json'); -var debug = require('debug')('analytics.js:metrics'); - -function Metrics(options) { - this.options(options); -} - -/** - * Set the metrics options. - * - * @param {Object} options - * @field {String} host - * @field {Number} sampleRate - * @field {Number} flushTimer - */ - -Metrics.prototype.options = function(options) { - options = options || {}; - - this.host = options.host || 'api.segment.io/v1'; - this.sampleRate = options.sampleRate || 0; // disable metrics by default. - this.flushTimer = options.flushTimer || 30 * 1000 /* 30s */; - this.maxQueueSize = options.maxQueueSize || 20; - - this.queue = []; - - if (this.sampleRate > 0) { - var self = this; - setInterval(function() { - self._flush(); - }, this.flushTimer); - } -}; - -/** - * Increments the counter identified by name and tags by one. - * - * @param {String} metric Name of the metric to increment. - * @param {Object} tags Dimensions associated with the metric. - */ -Metrics.prototype.increment = function(metric, tags) { - if (Math.random() > this.sampleRate) { - return; - } - - if (this.queue.length >= this.maxQueueSize) { - return; - } - - this.queue.push({ type: 'Counter', metric: metric, value: 1, tags: tags }); - - // Trigger a flush if this is an error metric. - if (metric.indexOf('error') > 0) { - this._flush(); - } -}; - -/** - * Flush all queued metrics. - */ -Metrics.prototype._flush = function() { - var self = this; - - if (self.queue.length <= 0) { - return; - } - - var payload = { series: this.queue }; - var headers = { 'Content-Type': 'text/plain' }; - - self.queue = []; - - // This endpoint does not support jsonp, so only proceed if the browser - // supports xhr. - if (send.type !== 'xhr') return; - - send('https://' + this.host + '/m', payload, headers, function(err, res) { - debug('sent %O, received %O', payload, [err, res]); - }); -}; - -/** - * Expose the metrics singleton. - */ - -module.exports = bindAll(new Metrics()); - -/** - * Expose the `Metrics` constructor. - */ - -module.exports.Metrics = Metrics; - -},{"@segment/send-json":39,"bind-all":43,"debug":26}],22:[function(require,module,exports){ -'use strict'; - -/** - * Module Dependencies. - */ - -var debug = require('debug')('analytics.js:normalize'); -var defaults = require('@ndhoule/defaults'); -var each = require('@ndhoule/each'); -var includes = require('@ndhoule/includes'); -var map = require('@ndhoule/map'); -var type = require('component-type'); - -/** - * HOP. - */ - -var has = Object.prototype.hasOwnProperty; - -/** - * Expose `normalize` - */ - -module.exports = normalize; - -/** - * Toplevel properties. - */ - -var toplevel = ['integrations', 'anonymousId', 'timestamp', 'context']; - -/** - * Normalize `msg` based on integrations `list`. - * - * @param {Object} msg - * @param {Array} list - * @return {Function} - */ - -function normalize(msg, list) { - var lower = map(function(s) { - return s.toLowerCase(); - }, list); - var opts = msg.options || {}; - var integrations = opts.integrations || {}; - var providers = opts.providers || {}; - var context = opts.context || {}; - var ret = {}; - debug('<-', msg); - - // integrations. - each(function(value, key) { - if (!integration(key)) return; - if (!has.call(integrations, key)) integrations[key] = value; - delete opts[key]; - }, opts); - - // providers. - delete opts.providers; - each(function(value, key) { - if (!integration(key)) return; - if (type(integrations[key]) === 'object') return; - if (has.call(integrations, key) && typeof providers[key] === 'boolean') - return; - integrations[key] = value; - }, providers); - - // move all toplevel options to msg - // and the rest to context. - each(function(value, key) { - if (includes(key, toplevel)) { - ret[key] = opts[key]; - } else { - context[key] = opts[key]; - } - }, opts); - - // cleanup - delete msg.options; - ret.integrations = integrations; - ret.context = context; - ret = defaults(ret, msg); - debug('->', ret); - return ret; - - function integration(name) { - return !!( - includes(name, list) || - name.toLowerCase() === 'all' || - includes(name.toLowerCase(), lower) - ); - } -} - -},{"@ndhoule/defaults":4,"@ndhoule/each":6,"@ndhoule/includes":10,"@ndhoule/map":12,"component-type":53,"debug":26}],23:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var canonical = require('@segment/canonical'); -var includes = require('@ndhoule/includes'); -var url = require('component-url'); - -/** - * Return a default `options.context.page` object. - * - * https://segment.com/docs/spec/page/#properties - * - * @return {Object} - */ - -function pageDefaults() { - return { - path: canonicalPath(), - referrer: document.referrer, - search: location.search, - title: document.title, - url: canonicalUrl(location.search) - }; -} - -/** - * Return the canonical path for the page. - * - * @return {string} - */ - -function canonicalPath() { - var canon = canonical(); - if (!canon) return window.location.pathname; - var parsed = url.parse(canon); - return parsed.pathname; -} - -/** - * Return the canonical URL for the page concat the given `search` - * and strip the hash. - * - * @param {string} search - * @return {string} - */ - -function canonicalUrl(search) { - var canon = canonical(); - if (canon) return includes('?', canon) ? canon : canon + search; - var url = window.location.href; - var i = url.indexOf('#'); - return i === -1 ? url : url.slice(0, i); -} - -/* - * Exports. - */ - -module.exports = pageDefaults; - -},{"@ndhoule/includes":10,"@segment/canonical":32,"component-url":54}],24:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var bindAll = require('bind-all'); -var defaults = require('@ndhoule/defaults'); -var store = require('@segment/store'); - -/** - * Initialize a new `Store` with `options`. - * - * @param {Object} options - */ - -function Store(options) { - this.options(options); -} - -/** - * Set the `options` for the store. - * - * @param {Object} options - * @field {Boolean} enabled (true) - */ - -Store.prototype.options = function(options) { - if (arguments.length === 0) return this._options; - - options = options || {}; - defaults(options, { enabled: true }); - - this.enabled = options.enabled && store.enabled; - this._options = options; -}; - -/** - * Set a `key` and `value` in local storage. - * - * @param {string} key - * @param {Object} value - */ - -Store.prototype.set = function(key, value) { - if (!this.enabled) return false; - return store.set(key, value); -}; - -/** - * Get a value from local storage by `key`. - * - * @param {string} key - * @return {Object} - */ - -Store.prototype.get = function(key) { - if (!this.enabled) return null; - return store.get(key); -}; - -/** - * Remove a value from local storage by `key`. - * - * @param {string} key - */ - -Store.prototype.remove = function(key) { - if (!this.enabled) return false; - return store.remove(key); -}; - -/** - * Expose the store singleton. - */ - -module.exports = bindAll(new Store()); - -/** - * Expose the `Store` constructor. - */ - -module.exports.Store = Store; - -},{"@ndhoule/defaults":4,"@segment/store":40,"bind-all":43}],25:[function(require,module,exports){ -'use strict'; - -/* - * Module dependencies. - */ - -var Entity = require('./entity'); -var bindAll = require('bind-all'); -var cookie = require('./cookie'); -var debug = require('debug')('analytics:user'); -var inherit = require('inherits'); -var rawCookie = require('component-cookie'); -var uuid = require('uuid'); - -/** - * User defaults - */ - -User.defaults = { - persist: true, - cookie: { - key: 'ajs_user_id', - oldKey: 'ajs_user' - }, - localStorage: { - key: 'ajs_user_traits' - } -}; - -/** - * Initialize a new `User` with `options`. - * - * @param {Object} options - */ - -function User(options) { - this.defaults = User.defaults; - this.debug = debug; - Entity.call(this, options); -} - -/** - * Inherit `Entity` - */ - -inherit(User, Entity); - -/** - * Set/get the user id. - * - * When the user id changes, the method will reset his anonymousId to a new one. - * - * // FIXME: What are the mixed types? - * @param {string} id - * @return {Mixed} - * @example - * // didn't change because the user didn't have previous id. - * anonymousId = user.anonymousId(); - * user.id('foo'); - * assert.equal(anonymousId, user.anonymousId()); - * - * // didn't change because the user id changed to null. - * anonymousId = user.anonymousId(); - * user.id('foo'); - * user.id(null); - * assert.equal(anonymousId, user.anonymousId()); - * - * // change because the user had previous id. - * anonymousId = user.anonymousId(); - * user.id('foo'); - * user.id('baz'); // triggers change - * user.id('baz'); // no change - * assert.notEqual(anonymousId, user.anonymousId()); - */ - -User.prototype.id = function(id) { - var prev = this._getId(); - var ret = Entity.prototype.id.apply(this, arguments); - if (prev == null) return ret; - // FIXME: We're relying on coercion here (1 == "1"), but our API treats these - // two values differently. Figure out what will break if we remove this and - // change to strict equality - /* eslint-disable eqeqeq */ - if (prev != id && id) this.anonymousId(null); - /* eslint-enable eqeqeq */ - return ret; -}; - -/** - * Set / get / remove anonymousId. - * - * @param {String} anonymousId - * @return {String|User} - */ - -User.prototype.anonymousId = function(anonymousId) { - var store = this.storage(); - - // set / remove - if (arguments.length) { - store.set('ajs_anonymous_id', anonymousId); - return this; - } - - // new - anonymousId = store.get('ajs_anonymous_id'); - if (anonymousId) { - return anonymousId; - } - - // old - it is not stringified so we use the raw cookie. - anonymousId = rawCookie('_sio'); - if (anonymousId) { - anonymousId = anonymousId.split('----')[0]; - store.set('ajs_anonymous_id', anonymousId); - store.remove('_sio'); - return anonymousId; - } - - // empty - anonymousId = uuid.v4(); - store.set('ajs_anonymous_id', anonymousId); - return store.get('ajs_anonymous_id'); -}; - -/** - * Remove anonymous id on logout too. - */ - -User.prototype.logout = function() { - Entity.prototype.logout.call(this); - this.anonymousId(null); -}; - -/** - * Load saved user `id` or `traits` from storage. - */ - -User.prototype.load = function() { - if (this._loadOldCookie()) return; - Entity.prototype.load.call(this); -}; - -/** - * BACKWARDS COMPATIBILITY: Load the old user from the cookie. - * - * @api private - * @return {boolean} - */ - -User.prototype._loadOldCookie = function() { - var user = cookie.get(this._options.cookie.oldKey); - if (!user) return false; - - this.id(user.id); - this.traits(user.traits); - cookie.remove(this._options.cookie.oldKey); - return true; -}; - -/** - * Expose the user singleton. - */ - -module.exports = bindAll(new User()); - -/** - * Expose the `User` constructor. - */ - -module.exports.User = User; - -},{"./cookie":16,"./entity":17,"bind-all":43,"component-cookie":45,"debug":26,"inherits":60,"uuid":95}],26:[function(require,module,exports){ - -/** - * Expose `debug()` as the module. - */ - -module.exports = debug; - -/** - * Create a debugger with the given `name`. - * - * @param {String} name - * @return {Type} - * @api public - */ - -function debug(name) { - if (!debug.enabled(name)) return function(){}; - - return function(fmt){ - fmt = coerce(fmt); - - var curr = new Date; - var ms = curr - (debug[name] || curr); - debug[name] = curr; - - fmt = name - + ' ' - + fmt - + ' +' + debug.humanize(ms); - - // This hackery is required for IE8 - // where `console.log` doesn't have 'apply' - window.console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); - } -} - -/** - * The currently active debug mode names. - */ - -debug.names = []; -debug.skips = []; - -/** - * Enables a debug mode by name. This can include modes - * separated by a colon and wildcards. - * - * @param {String} name - * @api public - */ - -debug.enable = function(name) { - try { - localStorage.debug = name; - } catch(e){} - - var split = (name || '').split(/[\s,]+/) - , len = split.length; - - for (var i = 0; i < len; i++) { - name = split[i].replace('*', '.*?'); - if (name[0] === '-') { - debug.skips.push(new RegExp('^' + name.substr(1) + '$')); - } - else { - debug.names.push(new RegExp('^' + name + '$')); - } - } -}; - -/** - * Disable debug output. - * - * @api public - */ - -debug.disable = function(){ - debug.enable(''); -}; - -/** - * Humanize the given `ms`. - * - * @param {Number} m - * @return {String} - * @api private - */ - -debug.humanize = function(ms) { - var sec = 1000 - , min = 60 * 1000 - , hour = 60 * min; - - if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; - if (ms >= min) return (ms / min).toFixed(1) + 'm'; - if (ms >= sec) return (ms / sec | 0) + 's'; - return ms + 'ms'; -}; - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -debug.enabled = function(name) { - for (var i = 0, len = debug.skips.length; i < len; i++) { - if (debug.skips[i].test(name)) { - return false; - } - } - for (var i = 0, len = debug.names.length; i < len; i++) { - if (debug.names[i].test(name)) { - return true; - } - } - return false; -}; - -/** - * Coerce `val`. - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} - -// persist - -try { - if (window.localStorage) debug.enable(localStorage.debug); -} catch(e){} - -},{}],27:[function(require,module,exports){ -module.exports={ - "name": "@segment/analytics.js-core", - "author": "Segment <frie...@segment.com>", - "version": "3.7.2", - "description": "The hassle-free way to integrate analytics into any web application.", - "keywords": [ - "analytics", - "analytics.js", - "segment", - "segment.io" - ], - "main": "lib/index.js", - "scripts": { - "test": "make test", - "lint": "eslint \"./{lib,test}/**/*.js\"", - "format": "prettier-eslint --write --list-different \"./{lib,test}/**/*.{js,json,md}\"", - "precommit": "lint-staged", - "np": "np --no-publish" - }, - "lint-staged": { - "linters": { - "*.{js,json,md}": [ - "prettier-eslint --write", - "git add" - ] - } - }, - "repository": { - "type": "git", - "url": "https://github.com/segmentio/analytics.js-core" - }, - "license": "SEE LICENSE IN LICENSE", - "bugs": { - "url": "https://github.com/segmentio/analytics.js-core/issues" - }, - "homepage": "https://github.com/segmentio/analytics.js-core#readme", - "dependencies": { - "@ndhoule/after": "^1.0.0", - "@ndhoule/clone": "^1.0.0", - "@ndhoule/defaults": "^2.0.1", - "@ndhoule/each": "^2.0.1", - "@ndhoule/extend": "^2.0.0", - "@ndhoule/foldl": "^2.0.1", - "@ndhoule/includes": "^2.0.1", - "@ndhoule/keys": "^2.0.0", - "@ndhoule/map": "^2.0.1", - "@ndhoule/pick": "^2.0.0", - "@segment/canonical": "^1.0.0", - "@segment/is-meta": "^1.0.0", - "@segment/isodate": "^1.0.2", - "@segment/isodate-traverse": "^1.0.1", - "@segment/prevent-default": "^1.0.0", - "@segment/send-json": "^3.0.0", - "@segment/store": "^1.3.20", - "@segment/top-domain": "^3.0.0", - "bind-all": "^1.0.0", - "component-cookie": "^1.1.2", - "component-emitter": "^1.2.1", - "component-event": "^0.1.4", - "component-querystring": "^2.0.0", - "component-type": "^1.2.1", - "component-url": "^0.2.1", - "debug": "^0.7.4", - "extend": "3.0.1", - "inherits": "^2.0.1", - "install": "^0.7.3", - "is": "^3.1.0", - "json3": "^3.3.2", - "new-date": "^1.0.0", - "next-tick": "^0.2.2", - "segmentio-facade": "^3.0.2", - "uuid": "^2.0.2" - }, - "devDependencies": { - "@segment/analytics.js-integration": "^3.2.1", - "@segment/eslint-config": "^4.0.0", - "browserify": "13.0.0", - "browserify-istanbul": "^2.0.0", - "codecov": "^3.0.2", - "compat-trigger-event": "^1.0.0", - "component-each": "^0.2.6", - "eslint": "^4.19.1", - "eslint-config-prettier": "^2.9.0", - "eslint-plugin-mocha": "^5.0.0", - "eslint-plugin-react": "^7.9.1", - "eslint-plugin-require-path-exists": "^1.1.8", - "husky": "^0.14.3", - "istanbul": "^0.4.3", - "jquery": "^3.2.1", - "karma": "1.3.0", - "karma-browserify": "^5.0.4", - "karma-chrome-launcher": "^1.0.1", - "karma-coverage": "^1.0.0", - "karma-junit-reporter": "^1.0.0", - "karma-mocha": "1.0.1", - "karma-phantomjs-launcher": "^1.0.0", - "karma-sauce-launcher": "^1.0.0", - "karma-spec-reporter": "0.0.26", - "karma-summary-reporter": "^1.5.0", - "lint-staged": "^7.2.0", - "mocha": "^2.2.5", - "np": "^3.0.4", - "phantomjs-prebuilt": "^2.1.7", - "prettier-eslint-cli": "^4.7.1", - "proclaim": "^3.4.1", - "sinon": "^1.7.3", - "snyk": "^1.83.0", - "watchify": "^3.7.0" - } -} - -},{}],28:[function(require,module,exports){ -'use strict'; - -/** - * Module dependencies. - */ - -var bind = require('component-bind'); -var clone = require('@ndhoule/clone'); -var debug = require('debug'); -var defaults = require('@ndhoule/defaults'); -var extend = require('@ndhoule/extend'); -var slug = require('slug-component'); -var protos = require('./protos'); -var statics = require('./statics'); - -/** - * Create a new `Integration` constructor. - * - * @constructs Integration - * @param {string} name - * @return {Function} Integration - */ - -function createIntegration(name) { - /** - * Initialize a new `Integration`. - * - * @class - * @param {Object} options - */ - - function Integration(options) { - if (options && options.addIntegration) { - // plugin - return options.addIntegration(Integration); - } - this.debug = debug('analytics:integration:' + slug(name)); - this.options = defaults(clone(options) || {}, this.defaults); - this._queue = []; - this.once('ready', bind(this, this.flush)); - - Integration.emit('construct', this); - this.ready = bind(this, this.ready); - this._wrapInitialize(); - this._wrapPage(); - this._wrapTrack(); - } - - Integration.prototype.defaults = {}; - Integration.prototype.globals = []; - Integration.prototype.templates = {}; - Integration.prototype.name = name; - extend(Integration, statics); - extend(Integration.prototype, protos); - - return Integration; -} - -/** - * Exports. - */ - -module.exports = createIntegration; - -},{"./protos":29,"./statics":30,"@ndhoule/clone":3,"@ndhoule/defaults":4,"@ndhoule/extend":8,"component-bind":44,"debug":55,"slug-component":87}],29:[function(require,module,exports){ -'use strict'; - -/** - * Module dependencies. - */ - -var Emitter = require('component-emitter'); -var after = require('@ndhoule/after'); -var each = require('@ndhoule/each'); -var events = require('analytics-events'); -var every = require('@ndhoule/every'); -var fmt = require('@segment/fmt'); -var foldl = require('@ndhoule/foldl'); -var is = require('is'); -var loadIframe = require('load-iframe'); -var loadScript = require('@segment/load-script'); -var nextTick = require('next-tick'); -var normalize = require('to-no-case'); - -/** - * hasOwnProperty reference. - */ - -var has = Object.prototype.hasOwnProperty; - -/** - * No operation. - */ - -var noop = function noop() {}; - -/** - * Window defaults. - */ - -var onerror = window.onerror; -var onload = null; - -/** - * Mixin emitter. - */ - -/* eslint-disable new-cap */ -Emitter(exports); -/* eslint-enable new-cap */ - -/** - * Initialize. - */ - -exports.initialize = function() { - var ready = this.ready; - nextTick(ready); -}; - -/** - * Loaded? - * - * @api private - * @return {boolean} - */ - -exports.loaded = function() { - return false; -}; - -/** - * Page. - * - * @api public - * @param {Page} page - */ - -/* eslint-disable no-unused-vars */ -exports.page = function(page) {}; -/* eslint-enable no-unused-vars */ - -/** - * Track. - * - * @api public - * @param {Track} track - */ - -/* eslint-disable no-unused-vars */ -exports.track = function(track) {}; -/* eslint-enable no-unused-vars */ - -/** - * Get values from items in `options` that are mapped to `key`. - * `options` is an integration setting which is a collection - * of type 'map', 'array', or 'mixed' - * - * Use cases include mapping events to pixelIds (map), sending generic - * conversion pixels only for specific events (array), or configuring dynamic - * mappings of event properties to query string parameters based on event (mixed) - * - * @api public - * @param {Object|Object[]|String[]} options An object, array of objects, or - * array of strings pulled from settings.mapping. - * @param {string} key The name of the item in options whose metadata - * we're looking for. - * @return {Array} An array of settings that match the input `key` name. - * @example - * - * // 'Map' - * var events = { my_event: 'a4991b88' }; - * .map(events, 'My Event'); - * // => ["a4991b88"] - * .map(events, 'whatever'); - * // => [] - * - * // 'Array' - * * var events = ['Completed Order', 'My Event']; - * .map(events, 'My Event'); - * // => ["My Event"] - * .map(events, 'whatever'); - * // => [] - * - * // 'Mixed' - * var events = [{ key: 'my event', value: '9b5eb1fa' }]; - * .map(events, 'my_event'); - * // => ["9b5eb1fa"] - * .map(events, 'whatever'); - * // => [] - */ - -exports.map = function(options, key) { - var normalizedComparator = normalize(key); - var mappingType = getMappingType(options); - - if (mappingType === 'unknown') { - return []; - } - - return foldl(function(matchingValues, val, key) { - var compare; - var result; - - if (mappingType === 'map') { - compare = key; - result = val; - } - - if (mappingType === 'array') { - compare = val; - result = val; - } - - if (mappingType === 'mixed') { - compare = val.key; - result = val.value; - } - - if (normalize(compare) === normalizedComparator) { - matchingValues.push(result); - } - - return matchingValues; - }, [], options); -}; - -/** - * Invoke a `method` that may or may not exist on the prototype with `args`, - * queueing or not depending on whether the integration is "ready". Don't - * trust the method call, since it contains integration party code. - * - * @api private - * @param {string} method - * @param {...*} args - */ - -exports.invoke = function(method) { - if (!this[method]) return; - var args = Array.prototype.slice.call(arguments, 1); - if (!this._ready) return this.queue(method, args); - - this.debug('%s with %o', method, args); - return this[method].apply(this, args); -}; - -/** - * Queue a `method` with `args`. If the integration assumes an initial - * pageview, then let the first call to `page` pass through. - * - * @api private - * @param {string} method - * @param {Array} args - */ - -exports.queue = function(method, args) { - if (method === 'page' && this._assumesPageview && !this._initialized) { - return this.page.apply(this, args); - } - - this._queue.push({ method: method, args: args }); -}; - -/** - * Flush the internal queue. - * - * @api private - */ - -exports.flush = function() { - this._ready = true; - var self = this; - - each(function(call) { - self[call.method].apply(self, call.args); - }, this._queue); - - // Empty the queue. - this._queue.length = 0; -}; - -/** - * Reset the integration, removing its global variables. - * - * @api private - */ - -exports.reset = function() { - for (var i = 0; i < this.globals.length; i++) { - window[this.globals[i]] = undefined; - } - - window.onerror = onerror; - window.onload = onload; -}; - -/** - * Load a tag
<TRUNCATED>