This repository has been archived by the owner. It is now read-only.
Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
19752 lines (16181 sloc)
421 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 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/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/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/tapstream":80,"./lib/trakio":81,"./lib/twitter-ads":82,"./lib/userlike":83,"./lib/uservoice":84,"./lib/vero":85,"./lib/visual-website-optimizer":86,"./lib/webengage":87,"./lib/woopra":88,"./lib/yandex-metrica":89}], | |
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; | |
/** | |
* HOP | |
*/ | |
var has = Object.prototype.hasOwnProperty; | |
/** | |
* Expose `AdRoll` integration. | |
*/ | |
var AdRoll = module.exports = integration('AdRoll') | |
.assumesPageview() | |
.global('__adroll_loaded') | |
.global('adroll_adv_id') | |
.global('adroll_pix_id') | |
.global('adroll_custom_data') | |
.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/ | |
* | |
* @param {Object} page | |
*/ | |
AdRoll.prototype.initialize = function(page){ | |
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? | |
* | |
* @return {Boolean} | |
*/ | |
AdRoll.prototype.loaded = function(){ | |
return window.__adroll; | |
}; | |
/** | |
* Page. | |
* | |
* http://support.adroll.com/segmenting-clicks/ | |
* | |
* @param {Page} page | |
*/ | |
AdRoll.prototype.page = function(page){ | |
var name = page.fullName(); | |
this.track(page.track(name)); | |
}; | |
/** | |
* Track. | |
* | |
* @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":90,"to-snake-case":91,"use-https":92,"each":4,"is":93,"obj-case":94}], | |
90: [function(require, module, exports) { | |
/** | |
* Module dependencies. | |
*/ | |
var bind = require('bind'); | |
var callback = require('callback'); | |
var clone = require('clone'); | |
var debug = require('debug'); | |
var defaults = require('defaults'); | |
var protos = require('./protos'); | |
var slug = require('slug'); | |
var statics = require('./statics'); | |
/** | |
* Expose `createIntegration`. | |
*/ | |
module.exports = createIntegration; | |
/** | |
* Create a new `Integration` constructor. | |
* | |
* @param {String} name | |
* @return {Function} Integration | |
*/ | |
function createIntegration(name){ | |
/** | |
* Initialize a new `Integration`. | |
* | |
* @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; | |
for (var key in statics) Integration[key] = statics[key]; | |
for (var key in protos) Integration.prototype[key] = protos[key]; | |
return Integration; | |
} | |
}, {"bind":95,"callback":96,"clone":97,"debug":98,"defaults":99,"./protos":100,"slug":101,"./statics":102}], | |
95: [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":103,"bind-all":104}], | |
103: [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))); | |
} | |
}; | |
}, {}], | |
104: [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":103,"type":7}], | |
96: [function(require, module, exports) { | |
var next = require('next-tick'); | |
/** | |
* Expose `callback`. | |
*/ | |
module.exports = callback; | |
/** | |
* Call an `fn` back synchronously if it exists. | |
* | |
* @param {Function} fn | |
*/ | |
function callback (fn) { | |
if ('function' === typeof fn) fn(); | |
} | |
/** | |
* Call an `fn` back asynchronously if it exists. If `wait` is ommitted, the | |
* `fn` will be called on next tick. | |
* | |
* @param {Function} fn | |
* @param {Number} wait (optional) | |
*/ | |
callback.async = function (fn, wait) { | |
if ('function' !== typeof fn) return; | |
if (!wait) return next(fn); | |
setTimeout(fn, wait); | |
}; | |
/** | |
* Symmetry. | |
*/ | |
callback.sync = callback; | |
}, {"next-tick":105}], | |
105: [function(require, module, exports) { | |
"use strict" | |
if (typeof setImmediate == 'function') { | |
module.exports = function(f){ setImmediate(f) } | |
} | |
// legacy node.js | |
else if (typeof process != 'undefined' && typeof process.nextTick == 'function') { | |
module.exports = process.nextTick | |
} | |
// fallback for other environments / postMessage behaves badly on IE8 | |
else if (typeof window == 'undefined' || window.ActiveXObject || !window.postMessage) { | |
module.exports = function(f){ setTimeout(f) }; | |
} else { | |
var q = []; | |
window.addEventListener('message', function(){ | |
var i = 0; | |
while (i < q.length) { | |
try { q[i++](); } | |
catch (e) { | |
q = q.slice(i); | |
window.postMessage('tic!', '*'); | |
throw e; | |
} | |
} | |
q.length = 0; | |
}, true); | |
module.exports = function(fn){ | |
if (!q.length) window.postMessage('tic!', '*'); | |
q.push(fn); | |
} | |
} | |
}, {}], | |
97: [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}], | |
98: [function(require, module, exports) { | |
if ('undefined' == typeof window) { | |
module.exports = require('./lib/debug'); | |
} else { | |
module.exports = require('./debug'); | |
} | |
}, {"./lib/debug":106,"./debug":107}], | |
106: [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; | |
} | |
}, {}], | |
107: [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){} | |
}, {}], | |
99: [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; | |
}, {}], | |
100: [function(require, module, exports) { | |
/** | |
* Module dependencies. | |
*/ | |
var loadScript = require('load-script'); | |
var loadIframe = require('load-iframe'); | |
var events = require('analytics-events'); | |
var normalize = require('to-no-case'); | |
var callback = require('callback'); | |
var Emitter = require('emitter'); | |
var tick = require('next-tick'); | |
var after = require('after'); | |
var each = require('each'); | |
var type = require('type'); | |
var fmt = require('fmt'); | |
/** | |
* Noop. | |
*/ | |
function noop(){} | |
/** | |
* Window defaults. | |
*/ | |
var setTimeout = window.setTimeout; | |
var setInterval = window.setInterval; | |
var onerror = window.onerror; | |
var onload = null; | |
/** | |
* Mixin emitter. | |
*/ | |
Emitter(exports); | |
/** | |
* Initialize. | |
*/ | |
exports.initialize = function(){ | |
var ready = this.ready; | |
tick(ready); | |
}; | |
/** | |
* Loaded? | |
* | |
* @return {Boolean} | |
* @api private | |
*/ | |
exports.loaded = function(){ | |
return false; | |
}; | |
/** | |
* Page. | |
* | |
* @param {Page} page | |
*/ | |
exports.page = function(page){}; | |
/** | |
* Track. | |
* | |
* @param {Track} track | |
*/ | |
exports.track = function(track){}; | |
/** | |
* Get events that match `str`. | |
* | |
* Examples: | |
* | |
* events = { my_event: 'a4991b88' } | |
* .map(events, 'My Event'); | |
* // => ["a4991b88"] | |
* .map(events, 'whatever'); | |
* // => [] | |
* | |
* events = [{ key: 'my event', value: '9b5eb1fa' }] | |
* .map(events, 'my_event'); | |
* // => ["9b5eb1fa"] | |
* .map(events, 'whatever'); | |
* // => [] | |
* | |
* @param {String} str | |
* @return {Array} | |
* @api public | |
*/ | |
exports.map = function(obj, str){ | |
var a = normalize(str); | |
var ret = []; | |
// noop | |
if (!obj) return ret; | |
// object | |
if ('object' == type(obj)) { | |
for (var k in obj) { | |
var item = obj[k]; | |
var b = normalize(k); | |
if (b == a) ret.push(item); | |
} | |
} | |
// array | |
if ('array' == type(obj)) { | |
if (!obj.length) return ret; | |
if (!obj[0].key) return ret; | |
for (var i = 0; i < obj.length; ++i) { | |
var item = obj[i]; | |
var b = normalize(item.key); | |
if (b == a) ret.push(item.value); | |
} | |
} | |
return ret; | |
}; | |
/** | |
* 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. | |
* | |
* @param {String} method | |
* @param {Mixed} args... | |
* @api private | |
*/ | |
exports.invoke = function(method){ | |
if (!this[method]) return; | |
var args = [].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. | |
* | |
* @param {String} method | |
* @param {Array} args | |
* @api private | |
*/ | |
exports.queue = function(method, args){ | |
if ('page' == method && 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 call; | |
while (call = this._queue.shift()) this[call.method].apply(this, call.args); | |
}; | |
/** | |
* Reset the integration, removing its global variables. | |
* | |
* @api private | |
*/ | |
exports.reset = function(){ | |
for (var i = 0, key; key = this.globals[i]; i++) window[key] = undefined; | |
window.setTimeout = setTimeout; | |
window.setInterval = setInterval; | |
window.onerror = onerror; | |
window.onload = onload; | |
}; | |
/** | |
* Load a tag by `name`. | |
* | |
* @param {String} name | |
* @param {Function} [fn] | |
*/ | |
exports.load = function(name, locals, fn){ | |
if ('function' == typeof name) fn = name, locals = null, name = null; | |
if (name && 'object' == typeof name) fn = locals, locals = name, name = null; | |
if ('function' == typeof locals) fn = locals, locals = null; | |
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); | |
var fn = fn || noop; | |
var self = this; | |
var el; | |
switch (template.type) { | |
case 'img': | |
attrs.width = 1; | |
attrs.height = 1; | |
el = loadImage(attrs, fn); | |
break; | |
case 'script': | |
el = loadScript(attrs, function(err){ | |
if (!err) return fn(); | |
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, fn); | |
break; | |
} | |
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. | |
*/ | |
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) { | |
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; | |
}; | |
}; | |
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; | |
} | |
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. | |
* | |
* @param {Object} template | |
* @param {Object} locals | |
* @return {Object} | |
*/ | |
function render(template, locals) { | |
var attrs = {}; | |
each(template.attrs, function(key, val){ | |
attrs[key] = val.replace(/\{\{\ *(\w+)\ *\}\}/g, function(_, $1){ | |
return locals[$1]; | |
}); | |
}); | |
return attrs; | |
} | |
}, {"load-script":108,"load-iframe":109,"analytics-events":110,"to-no-case":111,"callback":96,"emitter":112,"next-tick":105,"after":113,"each":114,"type":115,"fmt":116}], | |
108: [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 loadScript(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 `<script>` element and insert it before the first script on the | |
// page, which is guaranteed to exist since this Javascript is running. | |
var script = document.createElement('script'); | |
script.type = 'text/javascript'; | |
script.async = true; | |
script.src = options.src; | |
// 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(script, fn); | |
} | |
tick(function(){ | |
// Append after event listeners are attached for IE. | |
var firstScript = document.getElementsByTagName('script')[0]; | |
firstScript.parentNode.insertBefore(script, firstScript); | |
}); | |
// Return the script element in case they want to do anything special, like | |
// give it an ID or attributes. | |
return script; | |
}; | |
}, {"script-onload":117,"next-tick":105,"type":7}], | |
117: [function(require, module, exports) { | |
// https://github.com/thirdpartyjs/thirdpartyjs-code/blob/master/examples/templates/02/loading-files/index.php | |
/** | |
* Invoke `fn(err)` when the given `el` script loads. | |
* | |
* @param {Element} el | |
* @param {Function} fn | |
* @api public | |
*/ | |
module.exports = function(el, fn){ | |
return el.addEventListener | |
? add(el, fn) | |
: attach(el, fn); | |
}; | |
/** | |
* Add event listener to `el`, `fn()`. | |
* | |
* @param {Element} el | |
* @param {Function} fn | |
* @api private | |
*/ | |
function add(el, fn){ | |
el.addEventListener('load', function(_, e){ fn(null, e); }, false); | |
el.addEventListener('error', function(e){ | |
var err = new Error('script error "' + el.src + '"'); | |
err.event = e; | |
fn(err); | |
}, false); | |
} | |
/** | |
* Attach event. | |
* | |
* @param {Element} el | |
* @param {Function} fn | |
* @api private | |
*/ | |
function attach(el, fn){ | |
el.attachEvent('onreadystatechange', function(e){ | |
if (!/complete|loaded/.test(el.readyState)) return; | |
fn(null, e); | |
}); | |
el.attachEvent('onerror', function(e){ | |
var err = new Error('failed to load the script "' + el.src + '"'); | |
err.event = e || window.event; | |
fn(err); | |
}); | |
} | |
}, {}], | |
109: [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":117,"next-tick":105,"type":7}], | |
110: [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 | |
}; | |
}, {}], | |
111: [function(require, module, exports) { | |
/** | |
* Expose `toNoCase`. | |
*/ | |
module.exports = toNoCase; | |
/** | |
* Test whether a string is camel-case. | |
*/ | |
var hasSpace = /\s/; | |
var hasSeparator = /[\W_]/; | |
/** | |
* Remove any starting case from a `string`, like camel or snake, but keep | |
* spaces and punctuation that may be important otherwise. | |
* | |
* @param {String} string | |
* @return {String} | |
*/ | |
function toNoCase (string) { | |
if (hasSpace.test(string)) return string.toLowerCase(); | |
if (hasSeparator.test(string)) return unseparate(string).toLowerCase(); | |
return uncamelize(string).toLowerCase(); | |
} | |
/** | |
* Separator splitter. | |
*/ | |
var separatorSplitter = /[\W_]+(.|$)/g; | |
/** | |
* Un-separate a `string`. | |
* | |
* @param {String} string | |
* @return {String} | |
*/ | |
function unseparate (string) { | |
return string.replace(separatorSplitter, function (m, next) { | |
return next ? ' ' + next : ''; | |
}); | |
} | |
/** | |
* Camelcase splitter. | |
*/ | |
var camelSplitter = /(.)([A-Z]+)/g; | |
/** | |
* Un-camelcase a `string`. | |
* | |
* @param {String} string | |
* @return {String} | |
*/ | |
function uncamelize (string) { | |
return string.replace(camelSplitter, function (m, previous, uppers) { | |
return previous + ' ' + uppers.toLowerCase().split('').join(' '); | |
}); | |
} | |
}, {}], | |
112: [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":118}], | |
118: [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; | |
}; | |
}, {}], | |
113: [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); | |
} | |
}; | |
}; | |
}, {}], | |
114: [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":115,"component-type":115,"to-function":119}], | |
115: [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; | |
}; | |
}, {}], | |
119: [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":120,"component-props":120}], | |
120: [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 + _; | |
}; | |
} | |
}, {}], | |
116: [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; | |
}); | |
} | |
}, {}], | |
101: [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 || '-') | |
}; | |
}, {}], | |
102: [function(require, module, exports) { | |
/** | |
* Module dependencies. | |
*/ | |
var after = require('after'); | |
var domify = require('domify'); | |
var each = require('each'); | |
var Emitter = require('emitter'); | |
/** | |
* Mixin emitter. | |
*/ | |
Emitter(exports); | |
/** | |
* Add a new option to the integration by `key` with default `value`. | |
* | |
* @param {String} key | |
* @param {Mixed} value | |
* @return {Integration} | |
*/ | |
exports.option = function(key, value){ | |
this.prototype.defaults[key] = value; | |
return this; | |
}; | |
/** | |
* Add a new mapping option. | |
* | |
* This will create a method `name` that will return a mapping | |
* for you to use. | |
* | |
* Example: | |
* | |
* Integration('My Integration') | |
* .mapping('events'); | |
* | |
* new MyIntegration().track('My Event'); | |
* | |
* .track = function(track){ | |
* var events = this.events(track.event()); | |
* each(events, send); | |
* }; | |
* | |
* @param {String} name | |
* @return {Integration} | |
*/ | |
exports.mapping = function(name){ | |
this.option(name, []); | |
this.prototype[name] = function(str){ | |
return this.map(this.options[name], str); | |
}; | |
return this; | |
}; | |
/** | |
* Register a new global variable `key` owned by the integration, which will be | |
* used to test whether the integration is already on the page. | |
* | |
* @param {String} global | |
* @return {Integration} | |
*/ | |
exports.global = function(key){ | |
this.prototype.globals.push(key); | |
return this; | |
}; | |
/** | |
* Mark the integration as assuming an initial pageview, so to defer loading | |
* the script until the first `page` call, noop the first `initialize`. | |
* | |
* @return {Integration} | |
*/ | |
exports.assumesPageview = function(){ | |
this.prototype._assumesPageview = true; | |
return this; | |
}; | |
/** | |
* Mark the integration as being "ready" once `load` is called. | |
* | |
* @return {Integration} | |
*/ | |
exports.readyOnLoad = function(){ | |
this.prototype._readyOnLoad = true; | |
return this; | |
}; | |
/** | |
* Mark the integration as being "ready" once `initialize` is called. | |
* | |
* @return {Integration} | |
*/ | |
exports.readyOnInitialize = function(){ | |
this.prototype._readyOnInitialize = true; | |
return this; | |
}; | |
/** | |
* Define a tag to be loaded. | |
* | |
* @param {String} str DOM tag as string or URL | |
* @return {Integration} | |
*/ | |
exports.tag = function(name, str){ | |
if (null == str) { | |
str = name; | |
name = 'library'; | |
} | |
this.prototype.templates[name] = objectify(str); | |
return this; | |
}; | |
/** | |
* Given a string, give back DOM attributes. | |
* | |
* Do it in a way where the browser doesn't load images or iframes. | |
* It turns out, domify will load images/iframes, because | |
* whenever you construct those DOM elements, | |
* the browser immediately loads them. | |
* | |
* @param {String} str | |
* @return {Object} | |
*/ | |
function objectify(str) { | |
// replace `src` with `data-src` to prevent image loading | |
str = str.replace(' src="', ' data-src="'); | |
var el = domify(str); | |
var attrs = {}; | |
each(el.attributes, function(attr){ | |
// then replace it back | |
var name = 'data-src' == attr.name ? 'src' : attr.name; | |
if (!~str.indexOf(attr.name + '=')) return; | |
attrs[name] = attr.value; | |
}); | |
return { | |
type: el.tagName.toLowerCase(), | |
attrs: attrs | |
}; | |
} | |
}, {"after":113,"domify":121 |