Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
bc7ce1d352
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
20259 lines (16637 sloc) 431 KB
(function umd(require){
if ('object' == typeof exports) {
module.exports = require('1');
} else if ('function' == typeof define && define.amd) {
define(function(){ return require('1'); });
} else {
this['analytics'] = require('1');
}
})((function outer(modules, cache, entries){
/**
* Global
*/
var global = (function(){ return this; })();
/**
* Require `name`.
*
* @param {String} name
* @param {Boolean} jumped
* @api public
*/
function require(name, jumped){
if (cache[name]) return cache[name].exports;
if (modules[name]) return call(name, require);
throw new Error('cannot find module "' + name + '"');
}
/**
* Call module `id` and cache it.
*
* @param {Number} id
* @param {Function} require
* @return {Function}
* @api private
*/
function call(id, require){
var m = cache[id] = { exports: {} };
var mod = modules[id];
var name = mod[2];
var fn = mod[0];
fn.call(m.exports, function(req){
var dep = modules[id][1][req];
return require(dep ? dep : req);
}, m, m.exports, outer, modules, cache, entries);
// expose as `name`.
if (name) cache[name] = cache[id];
return cache[id].exports;
}
/**
* Require all entries exposing them on global if needed.
*/
for (var id in entries) {
if (entries[id]) {
global[entries[id]] = require(id);
} else {
require(id);
}
}
/**
* Duo flag.
*/
require.duo = true;
/**
* Expose cache.
*/
require.cache = cache;
/**
* Expose modules
*/
require.modules = modules;
/**
* Return newest require.
*/
return require;
})({
1: [function(require, module, exports) {
/**
* Analytics.js
*
* (C) 2013 Segment.io Inc.
*/
var _analytics = window.analytics;
var Integrations = require('analytics.js-integrations');
var Analytics = require('./analytics');
var each = require('each');
/**
* Expose the `analytics` singleton.
*/
var analytics = module.exports = exports = new Analytics();
/**
* Expose require
*/
analytics.require = require;
/**
* Expose `VERSION`.
*/
exports.VERSION = require('../bower.json').version;
/**
* Add integrations.
*/
each(Integrations, function (name, Integration) {
analytics.use(Integration);
});
}, {"analytics.js-integrations":2,"./analytics":3,"each":4,"../bower.json":5}],
2: [function(require, module, exports) {
/**
* Module dependencies.
*/
var each = require('each');
var plugins = require('./integrations.js');
/**
* Expose the integrations, using their own `name` from their `prototype`.
*/
each(plugins, function(plugin){
var name = (plugin.Integration || plugin).prototype.name;
exports[name] = plugin;
});
}, {"each":4,"./integrations.js":6}],
4: [function(require, module, exports) {
/**
* Module dependencies.
*/
var type = require('type');
/**
* HOP reference.
*/
var has = Object.prototype.hasOwnProperty;
/**
* Iterate the given `obj` and invoke `fn(val, i)`.
*
* @param {String|Array|Object} obj
* @param {Function} fn
* @api public
*/
module.exports = function(obj, fn){
switch (type(obj)) {
case 'array':
return array(obj, fn);
case 'object':
if ('number' == typeof obj.length) return array(obj, fn);
return object(obj, fn);
case 'string':
return string(obj, fn);
}
};
/**
* Iterate string chars.
*
* @param {String} obj
* @param {Function} fn
* @api private
*/
function string(obj, fn) {
for (var i = 0; i < obj.length; ++i) {
fn(obj.charAt(i), i);
}
}
/**
* Iterate object keys.
*
* @param {Object} obj
* @param {Function} fn
* @api private
*/
function object(obj, fn) {
for (var key in obj) {
if (has.call(obj, key)) {
fn(key, obj[key]);
}
}
}
/**
* Iterate array-ish.
*
* @param {Array|Object} obj
* @param {Function} fn
* @api private
*/
function array(obj, fn) {
for (var i = 0; i < obj.length; ++i) {
fn(obj[i], i);
}
}
}, {"type":7}],
7: [function(require, module, exports) {
/**
* toString ref.
*/
var toString = Object.prototype.toString;
/**
* Return the type of `val`.
*
* @param {Mixed} val
* @return {String}
* @api public
*/
module.exports = function(val){
switch (toString.call(val)) {
case '[object Date]': return 'date';
case '[object RegExp]': return 'regexp';
case '[object Arguments]': return 'arguments';
case '[object Array]': return 'array';
case '[object Error]': return 'error';
}
if (val === null) return 'null';
if (val === undefined) return 'undefined';
if (val !== val) return 'nan';
if (val && val.nodeType === 1) return 'element';
val = val.valueOf
? val.valueOf()
: Object.prototype.valueOf.apply(val)
return typeof val;
};
}, {}],
6: [function(require, module, exports) {
/**
* DON'T EDIT THIS FILE. It's automatically generated!
*/
module.exports = [
require('./lib/adroll'),
require('./lib/adwords'),
require('./lib/alexa'),
require('./lib/amplitude'),
require('./lib/appcues'),
require('./lib/atatus'),
require('./lib/autosend'),
require('./lib/awesm'),
require('./lib/bing-ads'),
require('./lib/blueshift'),
require('./lib/bronto'),
require('./lib/bugherd'),
require('./lib/bugsnag'),
require('./lib/chameleon'),
require('./lib/chartbeat'),
require('./lib/clicktale'),
require('./lib/clicky'),
require('./lib/comscore'),
require('./lib/crazy-egg'),
require('./lib/curebit'),
require('./lib/customerio'),
require('./lib/drip'),
require('./lib/errorception'),
require('./lib/evergage'),
require('./lib/extole'),
require('./lib/facebook-conversion-tracking'),
require('./lib/foxmetrics'),
require('./lib/frontleaf'),
require('./lib/fullstory'),
require('./lib/gauges'),
require('./lib/get-satisfaction'),
require('./lib/google-analytics'),
require('./lib/google-tag-manager'),
require('./lib/gosquared'),
require('./lib/heap'),
require('./lib/hellobar'),
require('./lib/hittail'),
require('./lib/hubspot'),
require('./lib/improvely'),
require('./lib/insidevault'),
require('./lib/inspectlet'),
require('./lib/intercom'),
require('./lib/keen-io'),
require('./lib/kenshoo'),
require('./lib/kissmetrics'),
require('./lib/klaviyo'),
require('./lib/livechat'),
require('./lib/lucky-orange'),
require('./lib/lytics'),
require('./lib/mixpanel'),
require('./lib/mojn'),
require('./lib/mouseflow'),
require('./lib/mousestats'),
require('./lib/navilytics'),
require('./lib/nudgespot'),
require('./lib/olark'),
require('./lib/optimizely'),
require('./lib/outbound'),
require('./lib/perfect-audience'),
require('./lib/pingdom'),
require('./lib/piwik'),
require('./lib/preact'),
require('./lib/qualaroo'),
require('./lib/quantcast'),
require('./lib/rollbar'),
require('./lib/saasquatch'),
require('./lib/satismeter'),
require('./lib/segmentio'),
require('./lib/sentry'),
require('./lib/snapengage'),
require('./lib/spinnakr'),
require('./lib/supporthero'),
require('./lib/taplytics'),
require('./lib/tapstream'),
require('./lib/trakio'),
require('./lib/twitter-ads'),
require('./lib/userlike'),
require('./lib/uservoice'),
require('./lib/vero'),
require('./lib/visual-website-optimizer'),
require('./lib/webengage'),
require('./lib/woopra'),
require('./lib/wootric'),
require('./lib/yandex-metrica')
];
}, {"./lib/adroll":8,"./lib/adwords":9,"./lib/alexa":10,"./lib/amplitude":11,"./lib/appcues":12,"./lib/atatus":13,"./lib/autosend":14,"./lib/awesm":15,"./lib/bing-ads":16,"./lib/blueshift":17,"./lib/bronto":18,"./lib/bugherd":19,"./lib/bugsnag":20,"./lib/chameleon":21,"./lib/chartbeat":22,"./lib/clicktale":23,"./lib/clicky":24,"./lib/comscore":25,"./lib/crazy-egg":26,"./lib/curebit":27,"./lib/customerio":28,"./lib/drip":29,"./lib/errorception":30,"./lib/evergage":31,"./lib/extole":32,"./lib/facebook-conversion-tracking":33,"./lib/foxmetrics":34,"./lib/frontleaf":35,"./lib/fullstory":36,"./lib/gauges":37,"./lib/get-satisfaction":38,"./lib/google-analytics":39,"./lib/google-tag-manager":40,"./lib/gosquared":41,"./lib/heap":42,"./lib/hellobar":43,"./lib/hittail":44,"./lib/hubspot":45,"./lib/improvely":46,"./lib/insidevault":47,"./lib/inspectlet":48,"./lib/intercom":49,"./lib/keen-io":50,"./lib/kenshoo":51,"./lib/kissmetrics":52,"./lib/klaviyo":53,"./lib/livechat":54,"./lib/lucky-orange":55,"./lib/lytics":56,"./lib/mixpanel":57,"./lib/mojn":58,"./lib/mouseflow":59,"./lib/mousestats":60,"./lib/navilytics":61,"./lib/nudgespot":62,"./lib/olark":63,"./lib/optimizely":64,"./lib/outbound":65,"./lib/perfect-audience":66,"./lib/pingdom":67,"./lib/piwik":68,"./lib/preact":69,"./lib/qualaroo":70,"./lib/quantcast":71,"./lib/rollbar":72,"./lib/saasquatch":73,"./lib/satismeter":74,"./lib/segmentio":75,"./lib/sentry":76,"./lib/snapengage":77,"./lib/spinnakr":78,"./lib/supporthero":79,"./lib/taplytics":80,"./lib/tapstream":81,"./lib/trakio":82,"./lib/twitter-ads":83,"./lib/userlike":84,"./lib/uservoice":85,"./lib/vero":86,"./lib/visual-website-optimizer":87,"./lib/webengage":88,"./lib/woopra":89,"./lib/wootric":90,"./lib/yandex-metrica":91}],
8: [function(require, module, exports) {
/**
* Module dependencies.
*/
var integration = require('analytics.js-integration');
var snake = require('to-snake-case');
var useHttps = require('use-https');
var each = require('each');
var is = require('is');
var del = require('obj-case').del;
/**
* Expose `AdRoll` integration.
*/
var AdRoll = module.exports = integration('AdRoll')
.assumesPageview()
.global('__adroll')
.global('__adroll_loaded')
.global('adroll_adv_id')
.global('adroll_custom_data')
.global('adroll_pix_id')
.option('advId', '')
.option('pixId', '')
.tag('http', '<script src="http://a.adroll.com/j/roundtrip.js">')
.tag('https', '<script src="https://s.adroll.com/j/roundtrip.js">')
.mapping('events');
/**
* Initialize.
*
* http://support.adroll.com/getting-started-in-4-easy-steps/#step-one
* http://support.adroll.com/enhanced-conversion-tracking/
*
* @api public
*/
AdRoll.prototype.initialize = function(){
window.adroll_adv_id = this.options.advId;
window.adroll_pix_id = this.options.pixId;
window.__adroll_loaded = true;
var name = useHttps() ? 'https' : 'http';
this.load(name, this.ready);
};
/**
* Loaded?
*
* @api private
* @return {boolean}
*/
AdRoll.prototype.loaded = function(){
return !!window.__adroll;
};
/**
* Page.
*
* http://support.adroll.com/segmenting-clicks/
*
* @api public
* @param {Page} page
*/
AdRoll.prototype.page = function(page){
var name = page.fullName();
this.track(page.track(name));
};
/**
* Track.
*
* @api public
* @param {Track} track
*/
AdRoll.prototype.track = function(track){
var event = track.event();
var user = this.analytics.user();
var events = this.events(event);
var total = track.revenue() || track.total() || 0;
var orderId = track.orderId() || 0;
var productId = track.id();
var sku = track.sku();
var customProps = track.properties();
var data = {};
if (user.id()) data.user_id = user.id();
if (orderId) data.order_id = orderId;
if (productId) data.product_id = productId;
if (sku) data.sku = sku;
if (total) data.adroll_conversion_value_in_dollars = total;
del(customProps, 'revenue');
del(customProps, 'total');
del(customProps, 'orderId');
del(customProps, 'id');
del(customProps, 'sku');
if (!is.empty(customProps)) data.adroll_custom_data = customProps;
each(events, function(event){
// the adroll interface only allows for
// segment names which are snake cased.
data.adroll_segments = snake(event);
window.__adroll.record_user(data);
});
// no events found
if (!events.length) {
data.adroll_segments = snake(event);
window.__adroll.record_user(data);
}
};
}, {"analytics.js-integration":92,"to-snake-case":93,"use-https":94,"each":4,"is":95,"obj-case":96}],
92: [function(require, module, exports) {
/**
* Module dependencies.
*/
var bind = require('bind');
var clone = require('clone');
var debug = require('debug');
var defaults = require('defaults');
var extend = require('extend');
var slug = require('slug');
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;
}, {"bind":97,"clone":98,"debug":99,"defaults":100,"extend":101,"slug":102,"./protos":103,"./statics":104}],
97: [function(require, module, exports) {
var bind = require('bind')
, bindAll = require('bind-all');
/**
* Expose `bind`.
*/
module.exports = exports = bind;
/**
* Expose `bindAll`.
*/
exports.all = bindAll;
/**
* Expose `bindMethods`.
*/
exports.methods = bindMethods;
/**
* Bind `methods` on `obj` to always be called with the `obj` as context.
*
* @param {Object} obj
* @param {String} methods...
*/
function bindMethods (obj, methods) {
methods = [].slice.call(arguments, 1);
for (var i = 0, method; method = methods[i]; i++) {
obj[method] = bind(obj, obj[method]);
}
return obj;
}
}, {"bind":105,"bind-all":106}],
105: [function(require, module, exports) {
/**
* Slice reference.
*/
var slice = [].slice;
/**
* Bind `obj` to `fn`.
*
* @param {Object} obj
* @param {Function|String} fn or string
* @return {Function}
* @api public
*/
module.exports = function(obj, fn){
if ('string' == typeof fn) fn = obj[fn];
if ('function' != typeof fn) throw new Error('bind() requires a function');
var args = slice.call(arguments, 2);
return function(){
return fn.apply(obj, args.concat(slice.call(arguments)));
}
};
}, {}],
106: [function(require, module, exports) {
try {
var bind = require('bind');
var type = require('type');
} catch (e) {
var bind = require('bind-component');
var type = require('type-component');
}
module.exports = function (obj) {
for (var key in obj) {
var val = obj[key];
if (type(val) === 'function') obj[key] = bind(obj, obj[key]);
}
return obj;
};
}, {"bind":105,"type":7}],
98: [function(require, module, exports) {
/**
* Module dependencies.
*/
var type;
try {
type = require('type');
} catch(e){
type = require('type-component');
}
/**
* Module exports.
*/
module.exports = clone;
/**
* Clones objects.
*
* @param {Mixed} any object
* @api public
*/
function clone(obj){
switch (type(obj)) {
case 'object':
var copy = {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = clone(obj[key]);
}
}
return copy;
case 'array':
var copy = new Array(obj.length);
for (var i = 0, l = obj.length; i < l; i++) {
copy[i] = clone(obj[i]);
}
return copy;
case '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);
case 'date':
return new Date(obj.getTime());
default: // string, number, boolean, …
return obj;
}
}
}, {"type":7}],
99: [function(require, module, exports) {
if ('undefined' == typeof window) {
module.exports = require('./lib/debug');
} else {
module.exports = require('./debug');
}
}, {"./lib/debug":107,"./debug":108}],
107: [function(require, module, exports) {
/**
* Module dependencies.
*/
var tty = require('tty');
/**
* Expose `debug()` as the module.
*/
module.exports = debug;
/**
* Enabled debuggers.
*/
var names = []
, skips = [];
(process.env.DEBUG || '')
.split(/[\s,]+/)
.forEach(function(name){
name = name.replace('*', '.*?');
if (name[0] === '-') {
skips.push(new RegExp('^' + name.substr(1) + '$'));
} else {
names.push(new RegExp('^' + name + '$'));
}
});
/**
* Colors.
*/
var colors = [6, 2, 3, 4, 5, 1];
/**
* Previous debug() call.
*/
var prev = {};
/**
* Previously assigned color.
*/
var prevColor = 0;
/**
* Is stdout a TTY? Colored output is disabled when `true`.
*/
var isatty = tty.isatty(2);
/**
* Select a color.
*
* @return {Number}
* @api private
*/
function color() {
return colors[prevColor++ % colors.length];
}
/**
* Humanize the given `ms`.
*
* @param {Number} m
* @return {String}
* @api private
*/
function humanize(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';
}
/**
* Create a debugger with the given `name`.
*
* @param {String} name
* @return {Type}
* @api public
*/
function debug(name) {
function disabled(){}
disabled.enabled = false;
var match = skips.some(function(re){
return re.test(name);
});
if (match) return disabled;
match = names.some(function(re){
return re.test(name);
});
if (!match) return disabled;
var c = color();
function colored(fmt) {
fmt = coerce(fmt);
var curr = new Date;
var ms = curr - (prev[name] || curr);
prev[name] = curr;
fmt = ' \u001b[9' + c + 'm' + name + ' '
+ '\u001b[3' + c + 'm\u001b[90m'
+ fmt + '\u001b[3' + c + 'm'
+ ' +' + humanize(ms) + '\u001b[0m';
console.error.apply(this, arguments);
}
function plain(fmt) {
fmt = coerce(fmt);
fmt = new Date().toUTCString()
+ ' ' + name + ' ' + fmt;
console.error.apply(this, arguments);
}
colored.enabled = plain.enabled = true;
return isatty || process.env.DEBUG_COLORS
? colored
: plain;
}
/**
* Coerce `val`.
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
}, {}],
108: [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){}
}, {}],
100: [function(require, module, exports) {
'use strict';
/**
* Merge default values.
*
* @param {Object} dest
* @param {Object} defaults
* @return {Object}
* @api public
*/
var defaults = function (dest, src, recursive) {
for (var prop in src) {
if (recursive && dest[prop] instanceof Object && src[prop] instanceof Object) {
dest[prop] = defaults(dest[prop], src[prop], true);
} else if (! (prop in dest)) {
dest[prop] = src[prop];
}
}
return dest;
};
/**
* Expose `defaults`.
*/
module.exports = defaults;
}, {}],
101: [function(require, module, exports) {
module.exports = function extend (object) {
// Takes an unlimited number of extenders.
var args = Array.prototype.slice.call(arguments, 1);
// For each extender, copy their properties on our object.
for (var i = 0, source; source = args[i]; i++) {
if (!source) continue;
for (var property in source) {
object[property] = source[property];
}
}
return object;
};
}, {}],
102: [function(require, module, exports) {
/**
* Generate a slug from the given `str`.
*
* example:
*
* generate('foo bar');
* // > foo-bar
*
* @param {String} str
* @param {Object} options
* @config {String|RegExp} [replace] characters to replace, defaulted to `/[^a-z0-9]/g`
* @config {String} [separator] separator to insert, defaulted to `-`
* @return {String}
*/
module.exports = function (str, options) {
options || (options = {});
return str.toLowerCase()
.replace(options.replace || /[^a-z0-9]/g, ' ')
.replace(/^ +| +$/g, '')
.replace(/ +/g, options.separator || '-')
};
}, {}],
103: [function(require, module, exports) {
/* global setInterval:true setTimeout:true */
/**
* Module dependencies.
*/
var Emitter = require('emitter');
var after = require('after');
var each = require('each');
var events = require('analytics-events');
var fmt = require('fmt');
var foldl = require('foldl');
var loadIframe = require('load-iframe');
var loadScript = require('load-script');
var normalize = require('to-no-case');
var nextTick = require('next-tick');
var type = require('type');
/**
* Noop.
*/
function noop(){}
/**
* hasOwnProperty reference.
*/
var has = Object.prototype.hasOwnProperty;
/**
* Window defaults.
*/
var onerror = window.onerror;
var onload = null;
var setInterval = window.setInterval;
var setTimeout = window.setTimeout;
/**
* 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 events that match `event`.
*
* @api public
* @param {Object|Object[]} events An object or array of objects pulled from
* settings.mapping.
* @param {string} event The name of the event whose metdata we're looking for.
* @return {Array} An array of settings that match the input `event` name.
* @example
* var events = { my_event: 'a4991b88' };
* .map(events, 'My Event');
* // => ["a4991b88"]
* .map(events, 'whatever');
* // => []
*
* var events = [{ key: 'my event', value: '9b5eb1fa' }];
* .map(events, 'my_event');
* // => ["9b5eb1fa"]
* .map(events, 'whatever');
* // => []
*/
exports.map = function(events, event){
var normalizedEvent = normalize(event);
return foldl(function(matchingEvents, val, key, events) {
// If true, this is a `mixed` value, which is structured like so:
// { key: 'testEvent', value: { event: 'testEvent', someValue: 'xyz' } }
// We need to extract the key, which we use to match against
// `normalizedEvent`, and return `value` as part of `matchingEvents` if that
// match succeds.
if (type(events) === 'array') {
// If there's no key attached to this event mapping (unusual), skip this
// item.
if (!val.key) return matchingEvents;
// Extract the key and value from the `mixed` object.
key = val.key;
val = val.value;
}
if (normalize(key) === normalizedEvent) {
matchingEvents.push(val);
}
return matchingEvents;
}, [], events);
};
/**
* 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);
var ret;
try {
this.debug('%s with %o', method, args);
ret = this[method].apply(this, args);
} catch (e) {
this.debug('error %o calling %s with %o', e, method, args);
}
return ret;
};
/**
* 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(this._queue, function(call){
self[call.method].apply(self, call.args);
});
// 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.setTimeout = setTimeout;
window.setInterval = setInterval;
window.onerror = onerror;
window.onload = onload;
};
/**
* Load a tag by `name`.
*
* @param {string} name The name of the tag.
* @param {Object} locals Locals used to populate the tag's template variables
* (e.g. `userId` in '<img src="https://whatever.com/{{ userId }}">').
* @param {Function} [callback=noop] A callback, invoked when the tag finishes
* loading.
*/
exports.load = function(name, locals, callback){
// Argument shuffling
if (typeof name === 'function') { callback = name; locals = null; name = null; }
if (name && typeof name === 'object') { callback = locals; locals = name; name = null; }
if (typeof locals === 'function') { callback = locals; locals = null; }
// Default arguments
name = name || 'library';
locals = locals || {};
locals = this.locals(locals);
var template = this.templates[name];
if (!template) throw new Error(fmt('template "%s" not defined.', name));
var attrs = render(template, locals);
callback = callback || noop;
var self = this;
var el;
switch (template.type) {
case 'img':
attrs.width = 1;
attrs.height = 1;
el = loadImage(attrs, callback);
break;
case 'script':
el = loadScript(attrs, function(err){
if (!err) return callback();
self.debug('error loading "%s" error="%s"', self.name, err);
});
// TODO: hack until refactoring load-script
delete attrs.src;
each(attrs, function(key, val){
el.setAttribute(key, val);
});
break;
case 'iframe':
el = loadIframe(attrs, callback);
break;
default:
// No default case
}
return el;
};
/**
* Locals for tag templates.
*
* By default it includes a cache buster and all of the options.
*
* @param {Object} [locals]
* @return {Object}
*/
exports.locals = function(locals){
locals = locals || {};
var cache = Math.floor(new Date().getTime() / 3600000);
if (!locals.hasOwnProperty('cache')) locals.cache = cache;
each(this.options, function(key, val){
if (!locals.hasOwnProperty(key)) locals[key] = val;
});
return locals;
};
/**
* Simple way to emit ready.
*
* @api public
*/
exports.ready = function(){
this.emit('ready');
};
/**
* Wrap the initialize method in an exists check, so we don't have to do it for
* every single integration.
*
* @api private
*/
exports._wrapInitialize = function(){
var initialize = this.initialize;
this.initialize = function(){
this.debug('initialize');
this._initialized = true;
var ret = initialize.apply(this, arguments);
this.emit('initialize');
return ret;
};
if (this._assumesPageview) this.initialize = after(2, this.initialize);
};
/**
* Wrap the page method to call `initialize` instead if the integration assumes
* a pageview.
*
* @api private
*/
exports._wrapPage = function(){
var page = this.page;
this.page = function(){
if (this._assumesPageview && !this._initialized) {
return this.initialize.apply(this, arguments);
}
return page.apply(this, arguments);
};
};
/**
* Wrap the track method to call other ecommerce methods if available depending
* on the `track.event()`.
*
* @api private
*/
exports._wrapTrack = function(){
var t = this.track;
this.track = function(track){
var event = track.event();
var called;
var ret;
for (var method in events) {
if (has.call(events, method)) {
var regexp = events[method];
if (!this[method]) continue;
if (!regexp.test(event)) continue;
ret = this[method].apply(this, arguments);
called = true;
break;
}
}
if (!called) ret = t.apply(this, arguments);
return ret;
};
};
/**
* TODO: Document me
*
* @api private
* @param {Object} attrs
* @param {Function} fn
* @return {undefined}
*/
function loadImage(attrs, fn){
fn = fn || function(){};
var img = new Image();
img.onerror = error(fn, 'failed to load pixel', img);
img.onload = function(){ fn(); };
img.src = attrs.src;
img.width = 1;
img.height = 1;
return img;
}
/**
* TODO: Document me
*
* @api private
* @param {Function} fn
* @param {string} message
* @param {Element} img
* @return {Function}
*/
function error(fn, message, img){
return function(e){
e = e || window.event;
var err = new Error(message);
err.event = e;
err.source = img;
fn(err);
};
}
/**
* Render template + locals into an `attrs` object.
*
* @api private
* @param {Object} template
* @param {Object} locals
* @return {Object}
*/
function render(template, locals){
return foldl(function(attrs, val, key) {
attrs[key] = val.replace(/\{\{\ *(\w+)\ *\}\}/g, function(_, $1){
return locals[$1];
});
return attrs;
}, {}, template.attrs);
}
}, {"emitter":109,"after":110,"each":111,"analytics-events":112,"fmt":113,"foldl":114,"load-iframe":115,"load-script":116,"to-no-case":117,"next-tick":118,"type":119}],
109: [function(require, module, exports) {
/**
* Module dependencies.
*/
var index = require('indexof');
/**
* Expose `Emitter`.
*/
module.exports = Emitter;
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks[event] = this._callbacks[event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
var self = this;
this._callbacks = this._callbacks || {};
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
fn._off = on;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks[event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks[event];
return this;
}
// remove specific handler
var i = index(callbacks, fn._off || fn);
if (~i) callbacks.splice(i, 1);
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks[event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks[event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
}, {"indexof":120}],
120: [function(require, module, exports) {
module.exports = function(arr, obj){
if (arr.indexOf) return arr.indexOf(obj);
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) return i;
}
return -1;
};
}, {}],
110: [function(require, module, exports) {
module.exports = function after (times, func) {
// After 0, really?
if (times <= 0) return func();
// That's more like it.
return function() {
if (--times < 1) {
return func.apply(this, arguments);
}
};
};
}, {}],
111: [function(require, module, exports) {
/**
* Module dependencies.
*/
try {
var type = require('type');
} catch (err) {
var type = require('component-type');
}
var toFunction = require('to-function');
/**
* HOP reference.
*/
var has = Object.prototype.hasOwnProperty;
/**
* Iterate the given `obj` and invoke `fn(val, i)`
* in optional context `ctx`.
*
* @param {String|Array|Object} obj
* @param {Function} fn
* @param {Object} [ctx]
* @api public
*/
module.exports = function(obj, fn, ctx){
fn = toFunction(fn);
ctx = ctx || this;
switch (type(obj)) {
case 'array':
return array(obj, fn, ctx);
case 'object':
if ('number' == typeof obj.length) return array(obj, fn, ctx);
return object(obj, fn, ctx);
case 'string':
return string(obj, fn, ctx);
}
};
/**
* Iterate string chars.
*
* @param {String} obj
* @param {Function} fn
* @param {Object} ctx
* @api private
*/
function string(obj, fn, ctx) {
for (var i = 0; i < obj.length; ++i) {
fn.call(ctx, obj.charAt(i), i);
}
}
/**
* Iterate object keys.
*
* @param {Object} obj
* @param {Function} fn
* @param {Object} ctx
* @api private
*/
function object(obj, fn, ctx) {
for (var key in obj) {
if (has.call(obj, key)) {
fn.call(ctx, key, obj[key]);
}
}
}
/**
* Iterate array-ish.
*
* @param {Array|Object} obj
* @param {Function} fn
* @param {Object} ctx
* @api private
*/
function array(obj, fn, ctx) {
for (var i = 0; i < obj.length; ++i) {
fn.call(ctx, obj[i], i);
}
}
}, {"type":119,"component-type":119,"to-function":121}],
119: [function(require, module, exports) {
/**
* toString ref.
*/
var toString = Object.prototype.toString;
/**
* Return the type of `val`.
*
* @param {Mixed} val
* @return {String}
* @api public
*/
module.exports = function(val){
switch (toString.call(val)) {
case '[object Function]': return 'function';
case '[object Date]': return 'date';
case '[object RegExp]': return 'regexp';
case '[object Arguments]': return 'arguments';
case '[object Array]': return 'array';
case '[object String]': return 'string';
}
if (val === null) return 'null';
if (val === undefined) return 'undefined';
if (val && val.nodeType === 1) return 'element';
if (val === Object(val)) return 'object';
return typeof val;
};
}, {}],
121: [function(require, module, exports) {
/**
* Module Dependencies
*/
var expr;
try {
expr = require('props');
} catch(e) {
expr = require('component-props');
}
/**
* Expose `toFunction()`.
*/
module.exports = toFunction;
/**
* Convert `obj` to a `Function`.
*
* @param {Mixed} obj
* @return {Function}
* @api private
*/
function toFunction(obj) {
switch ({}.toString.call(obj)) {
case '[object Object]':
return objectToFunction(obj);
case '[object Function]':
return obj;
case '[object String]':
return stringToFunction(obj);
case '[object RegExp]':
return regexpToFunction(obj);
default:
return defaultToFunction(obj);
}
}
/**
* Default to strict equality.
*
* @param {Mixed} val
* @return {Function}
* @api private
*/
function defaultToFunction(val) {
return function(obj){
return val === obj;
};
}
/**
* Convert `re` to a function.
*
* @param {RegExp} re
* @return {Function}
* @api private
*/
function regexpToFunction(re) {
return function(obj){
return re.test(obj);
};
}
/**
* Convert property `str` to a function.
*
* @param {String} str
* @return {Function}
* @api private
*/
function stringToFunction(str) {
// immediate such as "> 20"
if (/^ *\W+/.test(str)) return new Function('_', 'return _ ' + str);
// properties such as "name.first" or "age > 18" or "age > 18 && age < 36"
return new Function('_', 'return ' + get(str));
}
/**
* Convert `object` to a function.
*
* @param {Object} object
* @return {Function}
* @api private
*/
function objectToFunction(obj) {
var match = {};
for (var key in obj) {
match[key] = typeof obj[key] === 'string'
? defaultToFunction(obj[key])
: toFunction(obj[key]);
}
return function(val){
if (typeof val !== 'object') return false;
for (var key in match) {
if (!(key in val)) return false;
if (!match[key](val[key])) return false;
}
return true;
};
}
/**
* Built the getter function. Supports getter style functions
*
* @param {String} str
* @return {String}
* @api private
*/
function get(str) {
var props = expr(str);
if (!props.length) return '_.' + str;
var val, i, prop;
for (i = 0; i < props.length; i++) {
prop = props[i];
val = '_.' + prop;
val = "('function' == typeof " + val + " ? " + val + "() : " + val + ")";
// mimic negative lookbehind to avoid problems with nested properties
str = stripNested(prop, str, val);
}
return str;
}
/**
* Mimic negative lookbehind to avoid problems with nested properties.
*
* See: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
*
* @param {String} prop
* @param {String} str
* @param {String} val
* @return {String}
* @api private
*/
function stripNested (prop, str, val) {
return str.replace(new RegExp('(\\.)?' + prop, 'g'), function($0, $1) {
return $1 ? $0 : val;
});
}
}, {"props":122,"component-props":122}],
122: [function(require, module, exports) {
/**
* Global Names
*/
var globals = /\b(this|Array|Date|Object|Math|JSON)\b/g;
/**
* Return immediate identifiers parsed from `str`.
*
* @param {String} str
* @param {String|Function} map function or prefix
* @return {Array}
* @api public
*/
module.exports = function(str, fn){
var p = unique(props(str));
if (fn && 'string' == typeof fn) fn = prefixed(fn);
if (fn) return map(str, p, fn);
return p;
};
/**
* Return immediate identifiers in `str`.
*
* @param {String} str
* @return {Array}
* @api private
*/
function props(str) {
return str
.replace(/\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\//g, '')
.replace(globals, '')
.match(/[$a-zA-Z_]\w*/g)
|| [];
}
/**
* Return `str` with `props` mapped with `fn`.
*
* @param {String} str
* @param {Array} props
* @param {Function} fn
* @return {String}
* @api private
*/
function map(str, props, fn) {
var re = /\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\/|[a-zA-Z_]\w*/g;
return str.replace(re, function(_){
if ('(' == _[_.length - 1]) return fn(_);
if (!~props.indexOf(_)) return _;
return fn(_);
});
}
/**
* Return unique array.
*
* @param {Array} arr
* @return {Array}
* @api private
*/
function unique(arr) {
var ret = [];
for (var i = 0; i < arr.length; i++) {
if (~ret.indexOf(arr[i])) continue;
ret.push(arr[i]);
}
return ret;
}
/**
* Map with prefix `str`.
*/
function prefixed(str) {
return function(_){
return str + _;
};
}
}, {}],
112: [function(require, module, exports) {
module.exports = {
removedProduct: /^[ _]?removed[ _]?product[ _]?$/i,
viewedProduct: /^[ _]?viewed[ _]?product[ _]?$/i,
viewedProductCategory: /^[ _]?viewed[ _]?product[ _]?category[ _]?$/i,
addedProduct: /^[ _]?added[ _]?product[ _]?$/i,
completedOrder: /^[ _]?completed[ _]?order[ _]?$/i,
startedOrder: /^[ _]?started[ _]?order[ _]?$/i,
updatedOrder: /^[ _]?updated[ _]?order[ _]?$/i,
refundedOrder: /^[ _]?refunded?[ _]?order[ _]?$/i,
viewedProductDetails: /^[ _]?viewed[ _]?product[ _]?details?[ _]?$/i,
clickedProduct: /^[ _]?clicked[ _]?product[ _]?$/i,
viewedPromotion: /^[ _]?viewed[ _]?promotion?[ _]?$/i,
clickedPromotion: /^[ _]?clicked[ _]?promotion?[ _]?$/i,
viewedCheckoutStep: /^[ _]?viewed[ _]?checkout[ _]?step[ _]?$/i,
completedCheckoutStep: /^[ _]?completed[ _]?checkout[ _]?step[ _]?$/i
};
}, {}],
113: [function(require, module, exports) {
/**
* toString.
*/
var toString = window.JSON
? JSON.stringify
: function(_){ return String(_); };
/**
* Export `fmt`
*/
module.exports = fmt;
/**
* Formatters
*/
fmt.o = toString;
fmt.s = String;
fmt.d = parseInt;
/**
* Format the given `str`.
*
* @param {String} str
* @param {...} args
* @return {String}
* @api public
*/
function fmt(str){
var args = [].slice.call(arguments, 1);
var j = 0;
return str.replace(/%([a-z])/gi, function(_, f){
return fmt[f]
? fmt[f](args[j++])
: _ + f;
});
}
}, {}],
114: [function(require, module, exports) {
'use strict';
/**
* Module dependencies.
*/
// XXX: Hacky fix for Duo not supporting scoped modules
var each; try { each = require('@ndhoule/each'); } catch(e) { each = require('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;
}, {"each":123}],
123: [function(require, module, exports) {
'use strict';
/**
* Module dependencies.
*/
// XXX: Hacky fix for Duo not supporting scoped modules
var keys; try { keys = require('@ndhoule/keys'); } catch(e) { keys = require('keys'); }
/**
* Object.prototype.toString reference.
*/
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;
}, {"keys":124}],
124: [function(require, module, exports) {
'use strict';
/**
* charAt reference.
*/
var strCharAt = String.prototype.charAt;
/**
* 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 reference.
*/
var hop = Object.prototype.hasOwnProperty;
/**
* Object.prototype.toString reference.
*/
var toStr = Object.prototype.toString;
/**
* 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 {} 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 all the owned
*
* @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']
*/
module.exports = 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);
};
}, {}],
115: [function(require, module, exports) {
/**
* Module dependencies.
*/
var onload = require('script-onload');
var tick = require('next-tick');
var type = require('type');
/**
* Expose `loadScript`.
*
* @param {Object} options
* @param {Function} fn
* @api public
*/
module.exports = function loadIframe(options, fn){
if (!options) throw new Error('Cant load nothing...');
// Allow for the simplest case, just passing a `src` string.
if ('string' == type(options)) options = { src : options };
var https = document.location.protocol === 'https:' ||
document.location.protocol === 'chrome-extension:';
// If you use protocol relative URLs, third-party scripts like Google
// Analytics break when testing with `file:` so this fixes that.
if (options.src && options.src.indexOf('//') === 0) {
options.src = https ? 'https:' + options.src : 'http:' + options.src;
}
// Allow them to pass in different URLs depending on the protocol.
if (https && options.https) options.src = options.https;
else if (!https && options.http) options.src = options.http;
// Make the `<iframe>` element and insert it before the first iframe on the
// page, which is guaranteed to exist since this Javaiframe is running.
var iframe = document.createElement('iframe');
iframe.src = options.src;
iframe.width = options.width || 1;
iframe.height = options.height || 1;
iframe.style.display = 'none';
// If we have a fn, attach event handlers, even in IE. Based off of
// the Third-Party Javascript script loading example:
// https://github.com/thirdpartyjs/thirdpartyjs-code/blob/master/examples/templates/02/loading-files/index.php
if ('function' == type(fn)) {
onload(iframe, fn);
}
tick(function(){
// Append after event listeners are attached for IE.
var firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(iframe, firstScript);
});
// Return the iframe element in case they want to do anything special, like
// give it an ID or attributes.
return iframe;
};
}, {"script-onload":125,"next-tick":118,"type":7}],
125: [function(require, module, exports) {
// https://github.com/thirdpartyjs/thirdpartyjs-code/blob/master/examples/templates/02/loading-files/index.php
/**
* Invoke `fn