function trackingWrapper() {
	var gaToken;
	var mpToken;
	var gaRemarketing;
	var stScript = null;
	var stLoaded = false;

	function init(config, callback) {
		gaToken = config.gaToken;
		mpToken = config.mpToken;
		gaRemarketing = config.gaRemarketing;

		if (!config.stPath) {
			return console.log("ERROR: trackingWrapper.init - missing stPath");
		}

		// Mixpanel insertable script
		if (mpToken) {
			(function(f,b){if(!b.__SV){var a,e,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" "); for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__SV=1.2;a=f.createElement("script");a.type="text/javascript";a.async=!0;a.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";e=f.getElementsByTagName("script")[0];e.parentNode.insertBefore(a,e)}})(document,window.mixpanel||[]);
			window.mixpanel.init(mpToken, config.options);
		}

		// Supertracker load script
		var version = getCookie("edmAbTestingVersion");
		var stConfig = {
			basePath: config.stBaseRoute
		};
		if (version) {
			stConfig.properties = {
				edmAbTestingVersion: version
			};
		}
		stScript = document.createElement("script");
		stScript.src = config.stPath;
		document.body.appendChild(stScript);
		stScript.onload = function () {
			stLoaded = true;
			window.supertracker = supertracker();
			window.supertracker.init(stConfig, callback);
		};

		// Google Analytics load script
    
		// config.gaToken && ga("create", "config.gaToken", {"cookieDomain": "none"});
		gaToken && window.ga("create", gaToken, "auto");
		gaToken && window.ga("require", "displayfeatures");
	}

	function pageview (eventName, properties, comment, callback) {
		var gaProperties = properties && properties.gaProperties;
		gaProperties && delete properties.gaProperties;
		gaProperties = gaProperties || {};

		if (!stLoaded) {
			var origOL = stScript.onload;
			stScript.onload = function () {
				origOL();
				_pageview(eventName, properties, comment, callback);
			};
		} else {
			_pageview(eventName, properties, comment, callback);
		}

		function _pageview(eventName, properties, comment, callback) {
			gaToken && window.ga("send", "pageview");
			window.mixpanel && window.mixpanel.track(eventName, properties);
			window.supertracker.track(eventName, properties, comment, callback);
		}
	}

	function track(eventName, properties, comment, callback) {

		if (!stLoaded) {
			var origOL = stScript.onload;
			stScript.onload = function () {
				origOL();
				_track(eventName, properties, comment, callback);
			};
		} else {
			_track(eventName, properties, comment, callback);
		}
	
		function _track (eventName, properties, comment, callback) {
			var gaProperties = properties && properties.gaProperties;
			gaProperties && delete properties.gaProperties;
			gaProperties = gaProperties || {};

			window.mixpanel && window.mixpanel.track(eventName, properties);
			window.supertracker.track(eventName, properties, comment, callback);

			if (gaProperties.location) {
				gaToken && window.ga("send", "event", gaProperties.eventCategory || eventName, eventName, {
					"dimension1": gaProperties.location
				});
			} else {
				gaToken && window.ga("send", "event", gaProperties.eventCategory || eventName, eventName);
			}
		}
	}


	function track_links_ol (query) {
		var links = document.querySelectorAll(query);

		function onclickReplace (link, origOnclick) {
			var onclick = function(event) {
				var trimmedQuery = query.substring(1, query.length-1); // trimming the enclosing "[" and "]"
				var trackData = event.target.getAttribute(trimmedQuery);

				window.mixpanel && window.mixpanel.track( trackData);
				gaToken && window.ga("send", "event", trackData, trackData);
				
				if (origOnclick) {
					origOnclick(event);
				}
			};
			link.onclick = onclick;
		}

		for (var i = 0; i < links.length; i++) {
			var origOnclick = links[i].onclick;
			onclickReplace(links[i], origOnclick);
		}
	}

	function track_links (query, desc) {
		if (!stLoaded) {
			var origOL = stScript.onload;
			stScript.onload = function () {
				origOL();
				track_links_ol(query);
				window.supertracker.track_links(query);
			};
		} else {
			track_links_ol(query);
			window.supertracker.track_links(query);
		}
	}
	function identify(extUserId, extFlag, callback) {

		if (!stLoaded) {
			var origOL = stScript.onload;
			stScript.onload = function () {
				origOL();
				mixpanel && window.mixpanel.alias(extUserId);
				window.supertracker.identify(extUserId, extFlag, callback);
			};
		} else {
			window.mixpanel && window.mixpanel.alias(extUserId);
			window.supertracker.identify(extUserId, extFlag, callback);
		}
	}



	return	{
		init: init,
		track: track,
		identify: identify,
		pageview: pageview,
		track_links: track_links
	};
}

function getScript(source, callback) {
    var script = document.createElement("script");
    var prior = document.getElementsByTagName("script")[0];
    script.async = 1;
    prior.parentNode.insertBefore(script, prior);

    script.onload = script.onreadystatechange = function( _, isAbort ) {
        if(isAbort || !script.readyState || /loaded|complete/.test(script.readyState) ) {
            script.onload = script.onreadystatechange = null;
            script = undefined;

            if(!isAbort) { if(callback) callback(); }
        }
    };

    script.src = source;
}

function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(";");
    for(var i=0; i<ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)===" ") c = c.substring(1);
        if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
    }
    return "";
}