Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

autotrack

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

autotrack - npm Package Compare versions

Comparing version 2.0.4 to 2.1.0

test/unit/plugins/page-visibility-tracker-test.js

109

autotrack.js

@@ -1,54 +0,57 @@

(function(){var f,aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},k="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this;function l(){l=function(){};k.Symbol||(k.Symbol=ba)}var ca=0;function ba(a){return"jscomp_symbol_"+(a||"")+ca++}
function m(){l();var a=k.Symbol.iterator;a||(a=k.Symbol.iterator=k.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&aa(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return da(this)}});m=function(){}}function da(a){var b=0;return ea(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})}function ea(a){m();a={next:a};a[k.Symbol.iterator]=function(){return this};return a}
function n(a){if(!(a instanceof Array)){m();var b=a[Symbol.iterator];a=b?b.call(a):da(a);for(var c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}function fa(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a;for(var d in b)if(Object.defineProperties){var e=Object.getOwnPropertyDescriptor(b,d);e&&Object.defineProperty(a,d,e)}else a[d]=b[d]}
var p=window.Element.prototype,ha=p.matches||p.matchesSelector||p.webkitMatchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector;function ia(a,b){if(a&&1==a.nodeType&&b){if("string"==typeof b||1==b.nodeType)return a==b||ja(a,b);if("length"in b)for(var c=0,d;d=b[c];c++)if(a==d||ja(a,d))return!0}return!1}function ja(a,b){if("string"!=typeof b)return!1;if(ha)return ha.call(a,b);b=a.parentNode.querySelectorAll(b);for(var c=0,d;d=b[c];c++)if(d==a)return!0;return!1}
function ka(a){for(var b=[];a&&a.parentNode&&1==a.parentNode.nodeType;)a=a.parentNode,b.push(a);return b}
function q(a,b,c){function d(a){var d;if(g.composed&&"function"==typeof a.composedPath)for(var e=a.composedPath(),h=0,E;E=e[h];h++)1==E.nodeType&&ia(E,b)&&(d=E);else a:{if((d=a.target)&&1==d.nodeType&&b)for(d=[d].concat(ka(d)),e=0;h=d[e];e++)if(ia(h,b)){d=h;break a}d=void 0}d&&c.call(d,a,d)}var e=document,g={composed:!0,P:!0},g=void 0===g?{}:g;e.addEventListener(a,d,g.P);return{j:function(){e.removeEventListener(a,d,g.P)}}}
function la(a){var b={};if(!a||1!=a.nodeType)return b;a=a.attributes;if(!a.length)return{};for(var c=0,d;d=a[c];c++)b[d.name]=d.value;return b}var ma=/:(80|443)$/,r=document.createElement("a"),t={};
function u(a){a=a&&"."!=a?a:location.href;if(t[a])return t[a];r.href=a;if("."==a.charAt(0)||"/"==a.charAt(0))return u(r.href);var b="80"==r.port||"443"==r.port?"":r.port,b="0"==b?"":b,c=r.host.replace(ma,"");return t[a]={hash:r.hash,host:c,hostname:r.hostname,href:r.href,origin:r.origin?r.origin:r.protocol+"//"+c,pathname:"/"==r.pathname.charAt(0)?r.pathname:"/"+r.pathname,port:b,protocol:r.protocol,search:r.search}}var v=[];
function na(a,b){var c=this;this.context=a;this.N=b;this.f=(this.c=/Task$/.test(b))?a.get(b):a[b];this.b=[];this.a=[];this.i=function(a){for(var b=[],d=0;d<arguments.length;++d)b[d-0]=arguments[d];return c.a[c.a.length-1].apply(null,[].concat(n(b)))};this.c?a.set(b,this.i):a[b]=this.i}function w(a,b){a.b.push(b);oa(a)}function x(a,b){b=a.b.indexOf(b);-1<b&&(a.b.splice(b,1),0<a.b.length?oa(a):a.j())}
function oa(a){a.a=[];for(var b,c=0;b=a.b[c];c++){var d=a.a[c-1]||a.f.bind(a.context);a.a.push(b(d))}}na.prototype.j=function(){var a=v.indexOf(this);-1<a&&(v.splice(a,1),this.c?this.context.set(this.N,this.f):this.context[this.N]=this.f)};function y(a,b){var c=v.filter(function(c){return c.context==a&&c.N==b})[0];c||(c=new na(a,b),v.push(c));return c}
function z(a,b,c,d,e){if("function"==typeof d){var g=c.get("buildHitTask");return{buildHitTask:function(c){c.set(a,null,!0);c.set(b,null,!0);d(c,e);g(c)}}}return A({},a,b)}function B(a,b){var c=la(a),d={};Object.keys(c).forEach(function(a){if(!a.indexOf(b)&&a!=b+"on"){var e=c[a];"true"==e&&(e=!0);"false"==e&&(e=!1);a=pa(a.slice(b.length));d[a]=e}});return d}
function qa(a){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",function c(){document.removeEventListener("DOMContentLoaded",c);a()}):a()}function ra(a,b){var c;return function(d){for(var e=[],g=0;g<arguments.length;++g)e[g-0]=arguments[g];clearTimeout(c);c=setTimeout(function(){return a.apply(null,[].concat(n(e)))},b)}}function sa(a){function b(){c||(c=!0,a())}var c=!1;setTimeout(b,2E3);return b}
var A=Object.assign||function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];for(var e=0;d=c[e];e++)for(var g in d)Object.prototype.hasOwnProperty.call(d,g)&&(a[g]=d[g]);return a};function pa(a){return a.replace(/[\-\_]+(\w?)/g,function(a,c){return c.toUpperCase()})}function C(a){return"object"==typeof a&&null!==a}
function F(a,b){var c=window.GoogleAnalyticsObject||"ga";window[c]=window[c]||function(a){for(var b=[],d=0;d<arguments.length;++d)b[d-0]=arguments[d];(window[c].q=window[c].q||[]).push(b)};window.gaDevIds=window.gaDevIds||[];0>window.gaDevIds.indexOf("i5iSjo")&&window.gaDevIds.push("i5iSjo");window[c]("provide",a,b);window.gaplugins=window.gaplugins||{};window.gaplugins[a.charAt(0).toUpperCase()+a.slice(1)]=b}var G={R:1,S:2,T:3,V:4,W:5,X:6,Y:7,Z:8,$:9,U:10},H=Object.keys(G).length;
function I(a,b){a.set("\x26_av","2.0.4");var c=a.get("\x26_au"),c=parseInt(c||"0",16).toString(2);if(c.length<H)for(var d=H-c.length;d;)c="0"+c,d--;b=H-b;c=c.substr(0,b)+1+c.substr(b+1);a.set("\x26_au",parseInt(c||"0",2).toString(16))}function J(a,b){I(a,G.R);this.a=A({},b);this.i=a;this.b=this.a.stripQuery&&this.a.queryDimensionIndex?"dimension"+this.a.queryDimensionIndex:null;this.f=this.f.bind(this);this.c=this.c.bind(this);b=this.f;w(y(a,"get"),b);b=this.c;w(y(a,"buildHitTask"),b)}
J.prototype.f=function(a){var b=this;return function(c){if("page"==c||c==b.b){var d={location:a("location"),page:a("page")};return ta(b,d)[c]}return a(c)}};J.prototype.c=function(a){var b=this;return function(c){var d=ta(b,{location:c.get("location"),page:c.get("page")});c.set(d,null,!0);a(c)}};
function ta(a,b){var c=u(b.page||b.location),d=c.pathname;if(a.a.indexFilename){var e=d.split("/");a.a.indexFilename==e[e.length-1]&&(e[e.length-1]="",d=e.join("/"))}"remove"==a.a.trailingSlash?d=d.replace(/\/+$/,""):"add"==a.a.trailingSlash&&(/\.\w+$/.test(d)||"/"==d.substr(-1)||(d+="/"));d={page:d+(a.a.stripQuery?"":c.search)};b.location&&(d.location=b.location);a.b&&(d[a.b]=c.search.slice(1)||"(not set)");return"function"==typeof a.a.urlFieldsFilter?(b=a.a.urlFieldsFilter(d,u),c={},c.page=b.page,
c.location=b.location,c[a.b]=b[a.b],c):d}J.prototype.remove=function(){var a=this.f;x(y(this.i,"get"),a);a=this.c;x(y(this.i,"buildHitTask"),a)};F("cleanUrlTracker",J);function K(a,b){var c=this;I(a,G.S);if(window.addEventListener){this.a=A({events:["click"],fieldsObj:{},attributePrefix:"ga-"},b);this.f=a;this.c=this.c.bind(this);var d="["+this.a.attributePrefix+"on]";this.b={};this.a.events.forEach(function(a){c.b[a]=q(a,d,c.c)})}}
K.prototype.c=function(a,b){var c=this.a.attributePrefix;a.type==b.getAttribute(c+"on")&&(a=B(b,c),c=A({},this.a.fieldsObj,a),this.f.send(a.hitType||"event",z({transport:"beacon"},c,this.f,this.a.hitFilter,b)))};K.prototype.remove=function(){var a=this;Object.keys(this.b).forEach(function(b){a.b[b].j()})};F("eventTracker",K);
function ua(a,b){var c=this;I(a,G.T);window.IntersectionObserver&&window.MutationObserver&&(this.a=A({rootMargin:"0px",fieldsObj:{},attributePrefix:"ga-"},b),this.c=a,this.K=this.K.bind(this),this.M=this.M.bind(this),this.I=this.I.bind(this),this.J=this.J.bind(this),this.b=null,this.items=[],this.h={},this.g={},qa(function(){return c.observeElements(c.a.elements)}))}f=ua.prototype;
f.observeElements=function(a){var b=this;a=L(this,a);this.items=this.items.concat(a.items);this.h=A({},a.h,this.h);this.g=A({},a.g,this.g);a.items.forEach(function(a){var c=b.g[a.threshold]=b.g[a.threshold]||new IntersectionObserver(b.M,{rootMargin:b.a.rootMargin,threshold:[+a.threshold]});(a=b.h[a.id]||(b.h[a.id]=document.getElementById(a.id)))&&c.observe(a)});this.b||(this.b=new MutationObserver(this.K),this.b.observe(document.body,{childList:!0,subtree:!0}));requestAnimationFrame(function(){})};
f.unobserveElements=function(a){var b=[],c=[];this.items.forEach(function(d){a.some(function(a){a=va(a);return a.id===d.id&&a.threshold===d.threshold&&a.trackFirstImpressionOnly===d.trackFirstImpressionOnly})?c.push(d):b.push(d)});if(b.length){var d=L(this,b),e=L(this,c);this.items=d.items;this.h=d.h;this.g=d.g;c.forEach(function(a){if(!d.h[a.id]){var b=e.g[a.threshold],c=e.h[a.id];c&&b.unobserve(c);d.g[a.threshold]||e.g[a.threshold].disconnect()}})}else this.unobserveAllElements()};
f.unobserveAllElements=function(){var a=this;Object.keys(this.g).forEach(function(b){a.g[b].disconnect()});this.b.disconnect();this.b=null;this.items=[];this.h={};this.g={}};function L(a,b){var c=[],d={},e={};b.length&&b.forEach(function(b){b=va(b);c.push(b);e[b.id]=a.h[b.id]||null;d[b.threshold]=a.g[b.threshold]||null});return{items:c,h:e,g:d}}f.K=function(a){for(var b=0,c;c=a[b];b++){for(var d=0,e;e=c.removedNodes[d];d++)M(this,e,this.J);for(d=0;e=c.addedNodes[d];d++)M(this,e,this.I)}};
function M(a,b,c){1==b.nodeType&&b.id in a.h&&c(b.id);for(var d=0,e;e=b.childNodes[d];d++)M(a,e,c)}
f.M=function(a){for(var b=[],c=0,d;d=a[c];c++)for(var e=0,g;g=this.items[e];e++){var h;if(h=d.target.id===g.id)(h=g.threshold)?h=d.intersectionRatio>=h:(h=d.intersectionRect,h=0<h.top||0<h.bottom||0<h.left||0<h.right);if(h){var D=g.id;h=document.getElementById(D);var D={transport:"beacon",eventCategory:"Viewport",eventAction:"impression",eventLabel:D,nonInteraction:!0},Ea=A({},this.a.fieldsObj,B(h,this.a.attributePrefix));this.c.send("event",z(D,Ea,this.c,this.a.hitFilter,h));g.trackFirstImpressionOnly&&
b.push(g)}}b.length&&this.unobserveElements(b)};f.I=function(a){var b=this,c=this.h[a]=document.getElementById(a);this.items.forEach(function(d){a==d.id&&b.g[d.threshold].observe(c)})};f.J=function(a){var b=this,c=this.h[a];this.items.forEach(function(d){a==d.id&&b.g[d.threshold].unobserve(c)});this.h[a]=null};f.remove=function(){this.unobserveAllElements()};F("impressionTracker",ua);function va(a){"string"==typeof a&&(a={id:a});return A({threshold:0,trackFirstImpressionOnly:!0},a)}
function wa(){this.a={}}wa.prototype.aa=function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];(this.a[a]=this.a[a]||[]).forEach(function(a){return a.apply(null,[].concat(n(c)))})};var N={},O=!1;function P(a,b){this.a={};this.key=a;this.H=b||{}}fa(P,wa);function Q(a,b,c){a=["autotrack",a,b].join(":");N[a]||(N[a]=new P(a,c),N[a].key=a,O||(window.addEventListener("storage",xa),O=!0));return N[a]}
P.prototype.get=function(){try{var a=String(window.localStorage.getItem(this.key));return R(a,this.H)}catch(b){return{}}};P.prototype.set=function(a){var b=this.get();a=A(b,a);try{window.localStorage.setItem(this.key,JSON.stringify(a))}catch(c){}};function ya(a){try{window.localStorage.removeItem(a.key)}catch(b){}}P.prototype.j=function(){delete N[this.key];Object.keys(N).length||(window.removeEventListener("storage",xa),O=!1)};
function xa(a){var b=N[a.key];if(b){var c=R(a.oldValue,b.H);a=R(a.newValue,b.H);b.aa("externalSet",a,c)}}function R(a,b){var c;try{c=JSON.parse(a)}catch(d){c={}}return A({},b,c)}var za={};function S(a,b,c){this.f=a;this.timeout=b||T;this.timeZone=c;b=this.b=this.b.bind(this);w(y(a,"sendHitTask"),b);try{this.c=new Intl.DateTimeFormat("en-US",{timeZone:this.timeZone})}catch(d){}this.a=Q(a.get("trackingId"),"session",{hitTime:0,isExpired:!1})}
S.prototype.isExpired=function(a){a=a?a:this.a.get();if(a.isExpired)return!0;var b=new Date,c=(a=a.hitTime)&&new Date(a);return a&&(b-c>6E4*this.timeout||this.c&&this.c.format(b)!=this.c.format(c))?!0:!1};S.prototype.b=function(a){var b=this;return function(c){a(c);var d=b.a.get(),e=b.isExpired(d);c=c.get("sessionControl");d.hitTime=+new Date;if("start"==c||e)d.isExpired=!1;"end"==c&&(d.isExpired=!0);b.a.set(d)}};S.prototype.j=function(){var a=this.b;x(y(this.f,"sendHitTask"),a);this.a.j();delete za[this.f.get("trackingId")]};
var T=30;function U(a,b){I(a,G.U);window.addEventListener&&(this.a=A({increaseThreshold:20,sessionTimeout:T,fieldsObj:{}},b),this.c=a,this.b=Aa(this),this.f=ra(this.f.bind(this),500),this.s=this.s.bind(this),this.i=Q(a.get("trackingId"),"plugins/max-scroll-tracker"),this.O=new S(a,this.a.sessionTimeout,this.a.timeZone),b=this.s,w(y(a,"set"),b),Ba(this))}function Ba(a){100>(a.i.get()[a.b]||0)&&window.addEventListener("scroll",a.f)}
U.prototype.f=function(){var a=document.documentElement,b=document.body,a=Math.min(100,Math.max(0,Math.round(window.pageYOffset/(Math.max(a.offsetHeight,a.scrollHeight,b.offsetHeight,b.scrollHeight)-window.innerHeight)*100)));if(this.O.isExpired())ya(this.i);else if(b=this.i.get()[this.b]||0,a>b&&(100!=a&&100!=b||window.removeEventListener("scroll",this.f),b=a-b,100==a||b>=this.a.increaseThreshold)){var c={};this.i.set((c[this.b]=a,c));a={transport:"beacon",eventCategory:"Max Scroll",eventAction:"increase",
eventValue:b,eventLabel:String(a),nonInteraction:!0};this.a.maxScrollMetricIndex&&(a["metric"+this.a.maxScrollMetricIndex]=b);this.c.send("event",z(a,this.a.fieldsObj,this.c,this.a.hitFilter))}};U.prototype.s=function(a){var b=this;return function(c,d){a(c,d);var e={};(C(c)?c:(e[c]=d,e)).page&&(c=b.b,b.b=Aa(b),b.b!=c&&Ba(b))}};function Aa(a){a=u(a.c.get("page")||a.c.get("location"));return a.pathname+a.search}
U.prototype.remove=function(){this.O.j();window.removeEventListener("scroll",this.f);var a=this.s;x(y(this.c,"set"),a)};F("maxScrollTracker",U);var Ca={};function V(a,b){I(a,G.V);window.matchMedia&&(this.a=A({changeTemplate:this.changeTemplate,changeTimeout:1E3,fieldsObj:{}},b),C(this.a.definitions)&&(b=this.a.definitions,this.a.definitions=Array.isArray(b)?b:[b],this.b=a,this.c=[],Da(this)))}
function Da(a){a.a.definitions.forEach(function(b){if(b.name&&b.dimensionIndex){var c=Fa(b);a.b.set("dimension"+b.dimensionIndex,c);Ga(a,b)}})}function Fa(a){var b;a.items.forEach(function(a){Ha(a.media).matches&&(b=a)});return b?b.name:"(not set)"}
function Ga(a,b){b.items.forEach(function(c){c=Ha(c.media);var d=ra(function(){var c=Fa(b),d=a.b.get("dimension"+b.dimensionIndex);c!==d&&(a.b.set("dimension"+b.dimensionIndex,c),c={transport:"beacon",eventCategory:b.name,eventAction:"change",eventLabel:a.a.changeTemplate(d,c),nonInteraction:!0},a.b.send("event",z(c,a.a.fieldsObj,a.b,a.a.hitFilter)))},a.a.changeTimeout);c.addListener(d);a.c.push({ca:c,ba:d})})}V.prototype.remove=function(){for(var a=0,b;b=this.c[a];a++)b.ca.removeListener(b.ba)};
V.prototype.changeTemplate=function(a,b){return a+" \x3d\x3e "+b};F("mediaQueryTracker",V);function Ha(a){return Ca[a]||(Ca[a]=window.matchMedia(a))}function W(a,b){I(a,G.W);window.addEventListener&&(this.a=A({formSelector:"form",shouldTrackOutboundForm:this.shouldTrackOutboundForm,fieldsObj:{},attributePrefix:"ga-"},b),this.b=a,this.c=q("submit",this.a.formSelector,this.f.bind(this)))}
W.prototype.f=function(a,b){var c={transport:"beacon",eventCategory:"Outbound Form",eventAction:"submit",eventLabel:u(b.action).href};this.a.shouldTrackOutboundForm(b,u)&&(navigator.sendBeacon||(a.preventDefault(),c.hitCallback=sa(function(){b.submit()})),a=A({},this.a.fieldsObj,B(b,this.a.attributePrefix)),this.b.send("event",z(c,a,this.b,this.a.hitFilter,b)))};W.prototype.shouldTrackOutboundForm=function(a,b){a=b(a.action);return a.hostname!=location.hostname&&"http"==a.protocol.slice(0,4)};
W.prototype.remove=function(){this.c.j()};F("outboundFormTracker",W);function X(a,b){var c=this;I(a,G.X);window.addEventListener&&(this.a=A({events:["click"],linkSelector:"a, area",shouldTrackOutboundLink:this.shouldTrackOutboundLink,fieldsObj:{},attributePrefix:"ga-"},b),this.f=a,this.c=this.c.bind(this),this.b={},this.a.events.forEach(function(a){c.b[a]=q(a,c.a.linkSelector,c.c)}))}
X.prototype.c=function(a,b){if(this.a.shouldTrackOutboundLink(b,u)){var c=b.getAttribute("href")||b.getAttribute("xlink:href"),d=u(c),e={transport:"beacon",eventCategory:"Outbound Link",eventAction:a.type,eventLabel:d.href};navigator.sendBeacon||"click"!=a.type||"_blank"==b.target||a.metaKey||a.ctrlKey||a.shiftKey||a.altKey||1<a.which||window.addEventListener("click",function(a){a.defaultPrevented||(a.preventDefault(),e.hitCallback=sa(function(){location.href=c}))});a=A({},this.a.fieldsObj,B(b,this.a.attributePrefix));
this.f.send("event",z(e,a,this.f,this.a.hitFilter,b))}};X.prototype.shouldTrackOutboundLink=function(a,b){a=a.getAttribute("href")||a.getAttribute("xlink:href");b=b(a);return b.hostname!=location.hostname&&"http"==b.protocol.slice(0,4)};X.prototype.remove=function(){var a=this;Object.keys(this.b).forEach(function(b){a.b[b].j()})};F("outboundLinkTracker",X);var Y=function Ia(b){return b?(b^16*Math.random()>>b/4).toString(16):"10000000-1000-4000-8000-100000000000".replace(/[018]/g,Ia)}();
function Ja(a,b){I(a,G.Y);if(window.addEventListener){this.a=A({sessionTimeout:T,fieldsObj:{}},b);this.c=a;this.f=null;this.o=this.o.bind(this);this.l=this.l.bind(this);this.C=this.C.bind(this);this.L=this.L.bind(this);this.b=Q(a.get("trackingId"),"plugins/page-visibility-tracker");b=this.L;var c=this.b;(c.a.externalSet=c.a.externalSet||[]).push(b);this.i=new S(a,this.a.sessionTimeout,this.a.timeZone);b=this.o;w(y(a,"set"),b);document.addEventListener("visibilitychange",this.l);window.addEventListener("unload",
this.C);"visible"==document.visibilityState&&this.l()}}f=Ja.prototype;f.l=function(){var a=this.b.get();"visible"==this.f&&"hidden"==a.state&&a.pageId!=Y&&(a.state="visible",a.pageId=Y,this.b.set(a));var b={time:+new Date,state:document.visibilityState,pageId:Y};this.i.isExpired()?"hidden"==document.visibilityState?ya(this.b):(this.c.send("pageview",z({transport:"beacon"},this.a.fieldsObj,this.c,this.a.hitFilter)),this.b.set(b)):(a.pageId==Y&&"visible"==a.state&&Ka(this,a),this.b.set(b));this.f=document.visibilityState};
function Ka(a,b,c){var d={transport:"beacon",nonInteraction:!0,eventCategory:"Page Visibility",eventAction:"track",eventLabel:"(not set)"};c&&(d.da=+new Date-c);var e=c,e=void 0===e?+new Date:e;c=!a.i.isExpired();b=b.time&&Math.round((e-b.time)/1E3);if(b=c&&0<b?b:0)d.eventValue=b,a.a.visibleMetricIndex&&(d["metric"+a.a.visibleMetricIndex]=b);a.c.send("event",z(d,a.a.fieldsObj,a.c,a.a.hitFilter))}
f.o=function(a){var b=this;return function(c,d){var e={},e=C(c)?c:(e[c]=d,e);e.page&&e.page!==b.c.get("page")&&"visible"==b.f&&b.l();a(c,d)}};f.L=function(a,b){a.time!=b.time&&b.pageId==Y&&"visible"==b.state&&Ka(this,b,a.time)};f.C=function(){"hidden"!=this.f&&this.l()};f.remove=function(){this.i.j();var a=this.o;x(y(this.c,"set"),a);window.removeEventListener("unload",this.C);document.removeEventListener("visibilitychange",this.l)};F("pageVisibilityTracker",Ja);
function La(a,b){I(a,G.Z);window.addEventListener&&(this.a=A({fieldsObj:{},hitFilter:null},b),this.b=a,this.m=this.m.bind(this),this.G=this.G.bind(this),this.A=this.A.bind(this),this.u=this.u.bind(this),this.v=this.v.bind(this),this.B=this.B.bind(this),"complete"!=document.readyState?window.addEventListener("load",this.m):this.m())}f=La.prototype;
f.m=function(){if(window.FB)try{window.FB.Event.subscribe("edge.create",this.v),window.FB.Event.subscribe("edge.remove",this.B)}catch(a){}window.twttr&&this.G()};f.G=function(){var a=this;try{window.twttr.ready(function(){window.twttr.events.bind("tweet",a.A);window.twttr.events.bind("follow",a.u)})}catch(b){}};function Ma(a){try{window.twttr.ready(function(){window.twttr.events.unbind("tweet",a.A);window.twttr.events.unbind("follow",a.u)})}catch(b){}}
f.A=function(a){"tweet"==a.region&&(a={transport:"beacon",socialNetwork:"Twitter",socialAction:"tweet",socialTarget:a.data.url||a.target.getAttribute("data-url")||location.href},this.b.send("social",z(a,this.a.fieldsObj,this.b,this.a.hitFilter)))};f.u=function(a){"follow"==a.region&&(a={transport:"beacon",socialNetwork:"Twitter",socialAction:"follow",socialTarget:a.data.screen_name||a.target.getAttribute("data-screen-name")},this.b.send("social",z(a,this.a.fieldsObj,this.b,this.a.hitFilter)))};
f.v=function(a){this.b.send("social",z({transport:"beacon",socialNetwork:"Facebook",socialAction:"like",socialTarget:a},this.a.fieldsObj,this.b,this.a.hitFilter))};f.B=function(a){this.b.send("social",z({transport:"beacon",socialNetwork:"Facebook",socialAction:"unlike",socialTarget:a},this.a.fieldsObj,this.b,this.a.hitFilter))};f.remove=function(){window.removeEventListener("load",this.m);try{window.FB.Event.unsubscribe("edge.create",this.v),window.FB.Event.unsubscribe("edge.remove",this.B)}catch(a){}Ma(this)};
F("socialWidgetTracker",La);function Na(a,b){I(a,G.$);history.pushState&&window.addEventListener&&(this.a=A({shouldTrackUrlChange:this.shouldTrackUrlChange,trackReplaceState:!1,fieldsObj:{},hitFilter:null},b),this.b=a,this.c=location.pathname+location.search,this.D=this.D.bind(this),this.F=this.F.bind(this),this.w=this.w.bind(this),a=this.D,w(y(history,"pushState"),a),a=this.F,w(y(history,"replaceState"),a),window.addEventListener("popstate",this.w))}f=Na.prototype;
f.D=function(a){var b=this;return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];a.apply(null,[].concat(n(d)));Z(b,!0)}};f.F=function(a){var b=this;return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];a.apply(null,[].concat(n(d)));Z(b,!1)}};f.w=function(){Z(this,!0)};
function Z(a,b){setTimeout(function(){var c=a.c,d=location.pathname+location.search;c!=d&&a.a.shouldTrackUrlChange.call(a,d,c)&&(a.c=d,a.b.set({page:d,title:document.title}),(b||a.a.trackReplaceState)&&a.b.send("pageview",z({transport:"beacon"},a.a.fieldsObj,a.b,a.a.hitFilter)))},0)}f.shouldTrackUrlChange=function(a,b){return!(!a||!b)};f.remove=function(){var a=this.D;x(y(history,"pushState"),a);a=this.F;x(y(history,"replaceState"),a);window.removeEventListener("popstate",this.w)};
F("urlChangeTracker",Na);})();
(function(){var f,aa="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},k="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this;function ba(){ba=function(){};k.Symbol||(k.Symbol=ca)}var da=0;function ca(a){return"jscomp_symbol_"+(a||"")+da++}
function l(){ba();var a=k.Symbol.iterator;a||(a=k.Symbol.iterator=k.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&aa(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return ea(this)}});l=function(){}}function ea(a){var b=0;return fa(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})}function fa(a){l();a={next:a};a[k.Symbol.iterator]=function(){return this};return a}
function m(a){if(!(a instanceof Array)){l();var b=a[Symbol.iterator];a=b?b.call(a):ea(a);for(var c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}function ha(a,b){function c(){}c.prototype=b.prototype;a.prototype=new c;a.prototype.constructor=a;for(var d in b)if(Object.defineProperties){var e=Object.getOwnPropertyDescriptor(b,d);e&&Object.defineProperty(a,d,e)}else a[d]=b[d]}
var n=window.Element.prototype,ia=n.matches||n.matchesSelector||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector;function ja(a,b){if(a&&1==a.nodeType&&b){if("string"==typeof b||1==b.nodeType)return a==b||ka(a,b);if("length"in b)for(var c=0,d;d=b[c];c++)if(a==d||ka(a,d))return!0}return!1}function ka(a,b){if("string"!=typeof b)return!1;if(ia)return ia.call(a,b);b=a.parentNode.querySelectorAll(b);for(var c=0,d;d=b[c];c++)if(d==a)return!0;return!1}
function la(a){for(var b=[];a&&a.parentNode&&1==a.parentNode.nodeType;)a=a.parentNode,b.push(a);return b}
function p(a,b,c){function d(a){var d;if(h.composed&&"function"==typeof a.composedPath)for(var e=a.composedPath(),g=0,F;F=e[g];g++)1==F.nodeType&&ja(F,b)&&(d=F);else a:{if((d=a.target)&&1==d.nodeType&&b)for(d=[d].concat(la(d)),e=0;g=d[e];e++)if(ja(g,b)){d=g;break a}d=void 0}d&&c.call(d,a,d)}var e=document,h={composed:!0,R:!0},h=void 0===h?{}:h;e.addEventListener(a,d,h.R);return{j:function(){e.removeEventListener(a,d,h.R)}}}
function ma(a){var b={};if(!a||1!=a.nodeType)return b;a=a.attributes;if(!a.length)return{};for(var c=0,d;d=a[c];c++)b[d.name]=d.value;return b}var na=/:(80|443)$/,q=document.createElement("a"),r={};
function t(a){a=a&&"."!=a?a:location.href;if(r[a])return r[a];q.href=a;if("."==a.charAt(0)||"/"==a.charAt(0))return t(q.href);var b="80"==q.port||"443"==q.port?"":q.port,b="0"==b?"":b,c=q.host.replace(na,"");return r[a]={hash:q.hash,host:c,hostname:q.hostname,href:q.href,origin:q.origin?q.origin:q.protocol+"//"+c,pathname:"/"==q.pathname.charAt(0)?q.pathname:"/"+q.pathname,port:b,protocol:q.protocol,search:q.search}}var u=[];
function oa(a,b){var c=this;this.context=a;this.O=b;this.f=(this.c=/Task$/.test(b))?a.get(b):a[b];this.b=[];this.a=[];this.i=function(a){for(var b=[],d=0;d<arguments.length;++d)b[d-0]=arguments[d];return c.a[c.a.length-1].apply(null,[].concat(m(b)))};this.c?a.set(b,this.i):a[b]=this.i}function v(a,b){a.b.push(b);pa(a)}function w(a,b){b=a.b.indexOf(b);-1<b&&(a.b.splice(b,1),0<a.b.length?pa(a):a.j())}
function pa(a){a.a=[];for(var b,c=0;b=a.b[c];c++){var d=a.a[c-1]||a.f.bind(a.context);a.a.push(b(d))}}oa.prototype.j=function(){var a=u.indexOf(this);-1<a&&(u.splice(a,1),this.c?this.context.set(this.O,this.f):this.context[this.O]=this.f)};function x(a,b){var c=u.filter(function(c){return c.context==a&&c.O==b})[0];c||(c=new oa(a,b),u.push(c));return c}
function y(a,b,c,d,e){if("function"==typeof d){var h=c.get("buildHitTask");return{buildHitTask:function(c){c.set(a,null,!0);c.set(b,null,!0);d(c,e);h(c)}}}return z({},a,b)}function A(a,b){var c=ma(a),d={};Object.keys(c).forEach(function(a){if(!a.indexOf(b)&&a!=b+"on"){var e=c[a];"true"==e&&(e=!0);"false"==e&&(e=!1);a=qa(a.slice(b.length));d[a]=e}});return d}
function ra(a){"loading"==document.readyState?document.addEventListener("DOMContentLoaded",function c(){document.removeEventListener("DOMContentLoaded",c);a()}):a()}function sa(a,b){var c;return function(d){for(var e=[],h=0;h<arguments.length;++h)e[h-0]=arguments[h];clearTimeout(c);c=setTimeout(function(){return a.apply(null,[].concat(m(e)))},b)}}function ta(a){function b(){c||(c=!0,a())}var c=!1;setTimeout(b,2E3);return b}
var z=Object.assign||function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];for(var d=0,e=c.length;d<e;d++){var h=Object(c[d]),g;for(g in h)Object.prototype.hasOwnProperty.call(h,g)&&(a[g]=h[g])}return a};function qa(a){return a.replace(/[\-\_]+(\w?)/g,function(a,c){return c.toUpperCase()})}function B(a){return"object"==typeof a&&null!==a}
function C(a,b){var c=window.GoogleAnalyticsObject||"ga";window[c]=window[c]||function(a){for(var b=[],d=0;d<arguments.length;++d)b[d-0]=arguments[d];(window[c].q=window[c].q||[]).push(b)};window.gaDevIds=window.gaDevIds||[];0>window.gaDevIds.indexOf("i5iSjo")&&window.gaDevIds.push("i5iSjo");window[c]("provide",a,b);window.gaplugins=window.gaplugins||{};window.gaplugins[a.charAt(0).toUpperCase()+a.slice(1)]=b}var D={S:1,T:2,U:3,W:4,X:5,Y:6,Z:7,$:8,aa:9,V:10},G=Object.keys(D).length;
function H(a,b){a.set("\x26_av","2.1.0");var c=a.get("\x26_au"),c=parseInt(c||"0",16).toString(2);if(c.length<G)for(var d=G-c.length;d;)c="0"+c,d--;b=G-b;c=c.substr(0,b)+1+c.substr(b+1);a.set("\x26_au",parseInt(c||"0",2).toString(16))}function I(a,b){H(a,D.S);this.a=z({},b);this.i=a;this.b=this.a.stripQuery&&this.a.queryDimensionIndex?"dimension"+this.a.queryDimensionIndex:null;this.f=this.f.bind(this);this.c=this.c.bind(this);b=this.f;v(x(a,"get"),b);b=this.c;v(x(a,"buildHitTask"),b)}
I.prototype.f=function(a){var b=this;return function(c){if("page"==c||c==b.b){var d={location:a("location"),page:a("page")};return ua(b,d)[c]}return a(c)}};I.prototype.c=function(a){var b=this;return function(c){var d=ua(b,{location:c.get("location"),page:c.get("page")});c.set(d,null,!0);a(c)}};
function ua(a,b){var c=t(b.page||b.location),d=c.pathname;if(a.a.indexFilename){var e=d.split("/");a.a.indexFilename==e[e.length-1]&&(e[e.length-1]="",d=e.join("/"))}"remove"==a.a.trailingSlash?d=d.replace(/\/+$/,""):"add"==a.a.trailingSlash&&(/\.\w+$/.test(d)||"/"==d.substr(-1)||(d+="/"));d={page:d+(a.a.stripQuery?"":c.search)};b.location&&(d.location=b.location);a.b&&(d[a.b]=c.search.slice(1)||"(not set)");return"function"==typeof a.a.urlFieldsFilter?(b=a.a.urlFieldsFilter(d,t),c={},c.page=b.page,
c.location=b.location,c[a.b]=b[a.b],c):d}I.prototype.remove=function(){var a=this.f;w(x(this.i,"get"),a);a=this.c;w(x(this.i,"buildHitTask"),a)};C("cleanUrlTracker",I);function J(a,b){var c=this;H(a,D.T);if(window.addEventListener){this.a=z({events:["click"],fieldsObj:{},attributePrefix:"ga-"},b);this.f=a;this.c=this.c.bind(this);var d="["+this.a.attributePrefix+"on]";this.b={};this.a.events.forEach(function(a){c.b[a]=p(a,d,c.c)})}}
J.prototype.c=function(a,b){var c=this.a.attributePrefix;a.type==b.getAttribute(c+"on")&&(a=A(b,c),c=z({},this.a.fieldsObj,a),this.f.send(a.hitType||"event",y({transport:"beacon"},c,this.f,this.a.hitFilter,b)))};J.prototype.remove=function(){var a=this;Object.keys(this.b).forEach(function(b){a.b[b].j()})};C("eventTracker",J);
function va(a,b){var c=this;H(a,D.U);window.IntersectionObserver&&window.MutationObserver&&(this.a=z({rootMargin:"0px",fieldsObj:{},attributePrefix:"ga-"},b),this.c=a,this.L=this.L.bind(this),this.N=this.N.bind(this),this.J=this.J.bind(this),this.K=this.K.bind(this),this.b=null,this.items=[],this.h={},this.g={},ra(function(){return c.observeElements(c.a.elements)}))}f=va.prototype;
f.observeElements=function(a){var b=this;a=K(this,a);this.items=this.items.concat(a.items);this.h=z({},a.h,this.h);this.g=z({},a.g,this.g);a.items.forEach(function(a){var c=b.g[a.threshold]=b.g[a.threshold]||new IntersectionObserver(b.N,{rootMargin:b.a.rootMargin,threshold:[+a.threshold]});(a=b.h[a.id]||(b.h[a.id]=document.getElementById(a.id)))&&c.observe(a)});this.b||(this.b=new MutationObserver(this.L),this.b.observe(document.body,{childList:!0,subtree:!0}));requestAnimationFrame(function(){})};
f.unobserveElements=function(a){var b=[],c=[];this.items.forEach(function(d){a.some(function(a){a=wa(a);return a.id===d.id&&a.threshold===d.threshold&&a.trackFirstImpressionOnly===d.trackFirstImpressionOnly})?c.push(d):b.push(d)});if(b.length){var d=K(this,b),e=K(this,c);this.items=d.items;this.h=d.h;this.g=d.g;c.forEach(function(a){if(!d.h[a.id]){var b=e.g[a.threshold],c=e.h[a.id];c&&b.unobserve(c);d.g[a.threshold]||e.g[a.threshold].disconnect()}})}else this.unobserveAllElements()};
f.unobserveAllElements=function(){var a=this;Object.keys(this.g).forEach(function(b){a.g[b].disconnect()});this.b.disconnect();this.b=null;this.items=[];this.h={};this.g={}};function K(a,b){var c=[],d={},e={};b.length&&b.forEach(function(b){b=wa(b);c.push(b);e[b.id]=a.h[b.id]||null;d[b.threshold]=a.g[b.threshold]||null});return{items:c,h:e,g:d}}f.L=function(a){for(var b=0,c;c=a[b];b++){for(var d=0,e;e=c.removedNodes[d];d++)L(this,e,this.K);for(d=0;e=c.addedNodes[d];d++)L(this,e,this.J)}};
function L(a,b,c){1==b.nodeType&&b.id in a.h&&c(b.id);for(var d=0,e;e=b.childNodes[d];d++)L(a,e,c)}
f.N=function(a){for(var b=[],c=0,d;d=a[c];c++)for(var e=0,h;h=this.items[e];e++){var g;if(g=d.target.id===h.id)(g=h.threshold)?g=d.intersectionRatio>=g:(g=d.intersectionRect,g=0<g.top||0<g.bottom||0<g.left||0<g.right);if(g){var E=h.id;g=document.getElementById(E);var E={transport:"beacon",eventCategory:"Viewport",eventAction:"impression",eventLabel:E,nonInteraction:!0},Ga=z({},this.a.fieldsObj,A(g,this.a.attributePrefix));this.c.send("event",y(E,Ga,this.c,this.a.hitFilter,g));h.trackFirstImpressionOnly&&
b.push(h)}}b.length&&this.unobserveElements(b)};f.J=function(a){var b=this,c=this.h[a]=document.getElementById(a);this.items.forEach(function(d){a==d.id&&b.g[d.threshold].observe(c)})};f.K=function(a){var b=this,c=this.h[a];this.items.forEach(function(d){a==d.id&&b.g[d.threshold].unobserve(c)});this.h[a]=null};f.remove=function(){this.unobserveAllElements()};C("impressionTracker",va);function wa(a){"string"==typeof a&&(a={id:a});return z({threshold:0,trackFirstImpressionOnly:!0},a)}
function xa(){this.a={}}xa.prototype.ba=function(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];(this.a[a]=this.a[a]||[]).forEach(function(a){return a.apply(null,[].concat(m(c)))})};var M={},N=!1,O;function P(a,b){b=void 0===b?{}:b;this.a={};this.b=a;this.v=b;this.l=null}ha(P,xa);function Q(a,b,c){a=["autotrack",a,b].join(":");M[a]||(M[a]=new P(a,c),N||(window.addEventListener("storage",ya),N=!0));return M[a]}
function R(){if(null!=O)return O;try{window.localStorage.setItem("autotrack","autotrack"),window.localStorage.removeItem("autotrack"),O=!0}catch(a){O=!1}return O}P.prototype.get=function(){if(this.l)return this.l;if(R())try{this.l=S(window.localStorage.getItem(this.b))}catch(a){}return this.l=z({},this.v,this.l)};P.prototype.set=function(a){this.l=z({},this.v,this.l,a);if(R())try{var b=JSON.stringify(this.l);window.localStorage.setItem(this.b,b)}catch(c){}};
function za(a){a.l={};if(R())try{window.localStorage.removeItem(a.b)}catch(b){}}P.prototype.j=function(){delete M[this.b];Object.keys(M).length||(window.removeEventListener("storage",ya),N=!1)};function ya(a){var b=M[a.key];if(b){var c=z({},b.v,S(a.oldValue));a=z({},b.v,S(a.newValue));b.l=a;b.ba("externalSet",a,c)}}function S(a){var b={};if(a)try{b=JSON.parse(a)}catch(c){}return b}var Aa={};
function T(a,b,c){this.f=a;this.timeout=b||U;this.timeZone=c;b=this.b=this.b.bind(this);v(x(a,"sendHitTask"),b);try{this.c=new Intl.DateTimeFormat("en-US",{timeZone:this.timeZone})}catch(d){}this.a=Q(a.get("trackingId"),"session",{hitTime:0,isExpired:!1})}T.prototype.isExpired=function(a){a=a?a:this.a.get();if(a.isExpired)return!0;var b=new Date,c=(a=a.hitTime)&&new Date(a);return a&&(b-c>6E4*this.timeout||this.c&&this.c.format(b)!=this.c.format(c))?!0:!1};
T.prototype.b=function(a){var b=this;return function(c){a(c);var d=b.a.get(),e=b.isExpired(d);c=c.get("sessionControl");d.hitTime=+new Date;if("start"==c||e)d.isExpired=!1;"end"==c&&(d.isExpired=!0);b.a.set(d)}};T.prototype.j=function(){var a=this.b;w(x(this.f,"sendHitTask"),a);this.a.j();delete Aa[this.f.get("trackingId")]};var U=30;
function V(a,b){H(a,D.V);window.addEventListener&&(this.a=z({increaseThreshold:20,sessionTimeout:U,fieldsObj:{}},b),this.c=a,this.b=Ba(this),this.f=sa(this.f.bind(this),500),this.m=this.m.bind(this),this.i=Q(a.get("trackingId"),"plugins/max-scroll-tracker"),this.P=new T(a,this.a.sessionTimeout,this.a.timeZone),b=this.m,v(x(a,"set"),b),Ca(this))}function Ca(a){100>(a.i.get()[a.b]||0)&&window.addEventListener("scroll",a.f)}
V.prototype.f=function(){var a=document.documentElement,b=document.body,a=Math.min(100,Math.max(0,Math.round(window.pageYOffset/(Math.max(a.offsetHeight,a.scrollHeight,b.offsetHeight,b.scrollHeight)-window.innerHeight)*100)));if(this.P.isExpired())za(this.i);else if(b=this.i.get()[this.b]||0,a>b&&(100!=a&&100!=b||window.removeEventListener("scroll",this.f),b=a-b,100==a||b>=this.a.increaseThreshold)){var c={};this.i.set((c[this.b]=a,c));a={transport:"beacon",eventCategory:"Max Scroll",eventAction:"increase",
eventValue:b,eventLabel:String(a),nonInteraction:!0};this.a.maxScrollMetricIndex&&(a["metric"+this.a.maxScrollMetricIndex]=b);this.c.send("event",y(a,this.a.fieldsObj,this.c,this.a.hitFilter))}};V.prototype.m=function(a){var b=this;return function(c,d){a(c,d);var e={};(B(c)?c:(e[c]=d,e)).page&&(c=b.b,b.b=Ba(b),b.b!=c&&Ca(b))}};function Ba(a){a=t(a.c.get("page")||a.c.get("location"));return a.pathname+a.search}
V.prototype.remove=function(){this.P.j();window.removeEventListener("scroll",this.f);var a=this.m;w(x(this.c,"set"),a)};C("maxScrollTracker",V);var Da={};function W(a,b){H(a,D.W);window.matchMedia&&(this.a=z({changeTemplate:this.changeTemplate,changeTimeout:1E3,fieldsObj:{}},b),B(this.a.definitions)&&(b=this.a.definitions,this.a.definitions=Array.isArray(b)?b:[b],this.b=a,this.c=[],Ea(this)))}
function Ea(a){a.a.definitions.forEach(function(b){if(b.name&&b.dimensionIndex){var c=Fa(b);a.b.set("dimension"+b.dimensionIndex,c);Ha(a,b)}})}function Fa(a){var b;a.items.forEach(function(a){Ia(a.media).matches&&(b=a)});return b?b.name:"(not set)"}
function Ha(a,b){b.items.forEach(function(c){c=Ia(c.media);var d=sa(function(){var c=Fa(b),d=a.b.get("dimension"+b.dimensionIndex);c!==d&&(a.b.set("dimension"+b.dimensionIndex,c),c={transport:"beacon",eventCategory:b.name,eventAction:"change",eventLabel:a.a.changeTemplate(d,c),nonInteraction:!0},a.b.send("event",y(c,a.a.fieldsObj,a.b,a.a.hitFilter)))},a.a.changeTimeout);c.addListener(d);a.c.push({da:c,ca:d})})}W.prototype.remove=function(){for(var a=0,b;b=this.c[a];a++)b.da.removeListener(b.ca)};
W.prototype.changeTemplate=function(a,b){return a+" \x3d\x3e "+b};C("mediaQueryTracker",W);function Ia(a){return Da[a]||(Da[a]=window.matchMedia(a))}function X(a,b){H(a,D.X);window.addEventListener&&(this.a=z({formSelector:"form",shouldTrackOutboundForm:this.shouldTrackOutboundForm,fieldsObj:{},attributePrefix:"ga-"},b),this.b=a,this.c=p("submit",this.a.formSelector,this.f.bind(this)))}
X.prototype.f=function(a,b){var c={transport:"beacon",eventCategory:"Outbound Form",eventAction:"submit",eventLabel:t(b.action).href};this.a.shouldTrackOutboundForm(b,t)&&(navigator.sendBeacon||(a.preventDefault(),c.hitCallback=ta(function(){b.submit()})),a=z({},this.a.fieldsObj,A(b,this.a.attributePrefix)),this.b.send("event",y(c,a,this.b,this.a.hitFilter,b)))};X.prototype.shouldTrackOutboundForm=function(a,b){a=b(a.action);return a.hostname!=location.hostname&&"http"==a.protocol.slice(0,4)};
X.prototype.remove=function(){this.c.j()};C("outboundFormTracker",X);function Y(a,b){var c=this;H(a,D.Y);window.addEventListener&&(this.a=z({events:["click"],linkSelector:"a, area",shouldTrackOutboundLink:this.shouldTrackOutboundLink,fieldsObj:{},attributePrefix:"ga-"},b),this.f=a,this.c=this.c.bind(this),this.b={},this.a.events.forEach(function(a){c.b[a]=p(a,c.a.linkSelector,c.c)}))}
Y.prototype.c=function(a,b){if(this.a.shouldTrackOutboundLink(b,t)){var c=b.getAttribute("href")||b.getAttribute("xlink:href"),d=t(c),e={transport:"beacon",eventCategory:"Outbound Link",eventAction:a.type,eventLabel:d.href};navigator.sendBeacon||"click"!=a.type||"_blank"==b.target||a.metaKey||a.ctrlKey||a.shiftKey||a.altKey||1<a.which||window.addEventListener("click",function(a){a.defaultPrevented||(a.preventDefault(),e.hitCallback=ta(function(){location.href=c}))});a=z({},this.a.fieldsObj,A(b,this.a.attributePrefix));
this.f.send("event",y(e,a,this.f,this.a.hitFilter,b))}};Y.prototype.shouldTrackOutboundLink=function(a,b){a=a.getAttribute("href")||a.getAttribute("xlink:href");b=b(a);return b.hostname!=location.hostname&&"http"==b.protocol.slice(0,4)};Y.prototype.remove=function(){var a=this;Object.keys(this.b).forEach(function(b){a.b[b].j()})};C("outboundLinkTracker",Y);var Z=function Ja(b){return b?(b^16*Math.random()>>b/4).toString(16):"10000000-1000-4000-8000-100000000000".replace(/[018]/g,Ja)}();
function Ka(a,b){H(a,D.Z);if(document.visibilityState){this.a=z({sessionTimeout:U,visibleThreshold:5E3,fieldsObj:{}},b);this.c=a;this.i=this.f=null;this.u=this.u.bind(this);this.o=this.o.bind(this);this.F=this.F.bind(this);this.M=this.M.bind(this);this.b=Q(a.get("trackingId"),"plugins/page-visibility-tracker");b=this.M;var c=this.b;(c.a.externalSet=c.a.externalSet||[]).push(b);this.m=new T(a,this.a.sessionTimeout,this.a.timeZone);b=this.u;v(x(a,"set"),b);window.addEventListener("unload",this.F);document.addEventListener("visibilitychange",
this.o);"visible"==document.visibilityState&&this.o()}}f=Ka.prototype;
f.o=function(){var a=this;if("visible"==document.visibilityState||"hidden"==document.visibilityState){var b=La(this,this.b.get()),c={time:+new Date,state:document.visibilityState,pageId:Z};this.i&&"hidden"==document.visibilityState&&clearTimeout(this.i);this.m.isExpired()?"hidden"==this.f&&"visible"==document.visibilityState?(clearTimeout(this.i),this.i=setTimeout(function(){a.c.send("pageview",y({transport:"beacon",queueTime:+new Date-c.time},a.a.fieldsObj,a.c,a.a.hitFilter));a.b.set(c)},this.a.visibleThreshold)):
"hidden"==document.visibilityState&&za(this.b):(b.pageId==Z&&"visible"==b.state&&Ma(this,b),this.b.set(c));this.f=document.visibilityState}};function La(a,b){"visible"==a.f&&"hidden"==b.state&&b.pageId!=Z&&(b.state="visible",b.pageId=Z,a.b.set(b));return b}
function Ma(a,b,c){var d=c,d=void 0===d?+new Date:d,e=!a.m.isExpired();b=b.time&&d-b.time;(e=e&&0<b?b:0)&&e>=a.a.visibleThreshold&&(e=Math.round(e/1E3),b={transport:"beacon",nonInteraction:!0,eventCategory:"Page Visibility",eventAction:"track",eventValue:e,eventLabel:"(not set)"},c&&(b.queueTime=+new Date-c),a.a.visibleMetricIndex&&(b["metric"+a.a.visibleMetricIndex]=e),a.c.send("event",y(b,a.a.fieldsObj,a.c,a.a.hitFilter)))}
f.u=function(a){var b=this;return function(c,d){var e={},e=B(c)?c:(e[c]=d,e);e.page&&e.page!==b.c.get("page")&&"visible"==b.f&&b.o();a(c,d)}};f.M=function(a,b){a.time!=b.time&&b.pageId==Z&&"visible"==b.state&&Ma(this,b,a.time)};f.F=function(){"hidden"!=this.f&&this.o()};f.remove=function(){this.b.j();this.m.j();var a=this.u;w(x(this.c,"set"),a);window.removeEventListener("unload",this.F);document.removeEventListener("visibilitychange",this.o)};C("pageVisibilityTracker",Ka);
function Na(a,b){H(a,D.$);window.addEventListener&&(this.a=z({fieldsObj:{},hitFilter:null},b),this.b=a,this.s=this.s.bind(this),this.I=this.I.bind(this),this.C=this.C.bind(this),this.w=this.w.bind(this),this.A=this.A.bind(this),this.D=this.D.bind(this),"complete"!=document.readyState?window.addEventListener("load",this.s):this.s())}f=Na.prototype;
f.s=function(){if(window.FB)try{window.FB.Event.subscribe("edge.create",this.A),window.FB.Event.subscribe("edge.remove",this.D)}catch(a){}window.twttr&&this.I()};f.I=function(){var a=this;try{window.twttr.ready(function(){window.twttr.events.bind("tweet",a.C);window.twttr.events.bind("follow",a.w)})}catch(b){}};function Oa(a){try{window.twttr.ready(function(){window.twttr.events.unbind("tweet",a.C);window.twttr.events.unbind("follow",a.w)})}catch(b){}}
f.C=function(a){"tweet"==a.region&&(a={transport:"beacon",socialNetwork:"Twitter",socialAction:"tweet",socialTarget:a.data.url||a.target.getAttribute("data-url")||location.href},this.b.send("social",y(a,this.a.fieldsObj,this.b,this.a.hitFilter)))};f.w=function(a){"follow"==a.region&&(a={transport:"beacon",socialNetwork:"Twitter",socialAction:"follow",socialTarget:a.data.screen_name||a.target.getAttribute("data-screen-name")},this.b.send("social",y(a,this.a.fieldsObj,this.b,this.a.hitFilter)))};
f.A=function(a){this.b.send("social",y({transport:"beacon",socialNetwork:"Facebook",socialAction:"like",socialTarget:a},this.a.fieldsObj,this.b,this.a.hitFilter))};f.D=function(a){this.b.send("social",y({transport:"beacon",socialNetwork:"Facebook",socialAction:"unlike",socialTarget:a},this.a.fieldsObj,this.b,this.a.hitFilter))};f.remove=function(){window.removeEventListener("load",this.s);try{window.FB.Event.unsubscribe("edge.create",this.A),window.FB.Event.unsubscribe("edge.remove",this.D)}catch(a){}Oa(this)};
C("socialWidgetTracker",Na);function Pa(a,b){H(a,D.aa);history.pushState&&window.addEventListener&&(this.a=z({shouldTrackUrlChange:this.shouldTrackUrlChange,trackReplaceState:!1,fieldsObj:{},hitFilter:null},b),this.b=a,this.c=location.pathname+location.search,this.G=this.G.bind(this),this.H=this.H.bind(this),this.B=this.B.bind(this),a=this.G,v(x(history,"pushState"),a),a=this.H,v(x(history,"replaceState"),a),window.addEventListener("popstate",this.B))}f=Pa.prototype;
f.G=function(a){var b=this;return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];a.apply(null,[].concat(m(d)));Qa(b,!0)}};f.H=function(a){var b=this;return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];a.apply(null,[].concat(m(d)));Qa(b,!1)}};f.B=function(){Qa(this,!0)};
function Qa(a,b){setTimeout(function(){var c=a.c,d=location.pathname+location.search;c!=d&&a.a.shouldTrackUrlChange.call(a,d,c)&&(a.c=d,a.b.set({page:d,title:document.title}),(b||a.a.trackReplaceState)&&a.b.send("pageview",y({transport:"beacon"},a.a.fieldsObj,a.b,a.a.hitFilter)))},0)}f.shouldTrackUrlChange=function(a,b){return!(!a||!b)};f.remove=function(){var a=this.G;w(x(history,"pushState"),a);a=this.H;w(x(history,"replaceState"),a);window.removeEventListener("popstate",this.B)};
C("urlChangeTracker",Pa);})();
//# sourceMappingURL=autotrack.js.map

@@ -90,3 +90,3 @@ /**

});
source = path.relative('.', path.resolve(__dirname, source));
source = path.relative('.', path.resolve(__dirname, '..', source));
return {type, line, column, source, desc: item.description};

@@ -93,0 +93,0 @@ };

@@ -5,2 +5,7 @@ # Changelog

### 2.1.0 (2017-03-06)
- Fix a double-pageview bug on pageload after session timeout (#150).
- Add a visibleThreshold option to pageVisibilityTracker (#148).
### 2.0.4 (2017-02-24)

@@ -7,0 +12,0 @@

@@ -87,2 +87,10 @@ # `pageVisibilityTracker`

<tr valign="top">
<td><code>visibleThreshold</code></td>
<td><code>number</code></td>
<td>
The time in milliseconds to wait before sending a Page Visibility event (or a new pageview in the case of a session timeout). This helps prevent unwanted events from being sent in cases where a user is quickly switching tabs or closing tabs they no longer want open.<br>
<strong>Default:</strong> <code>5000</code>
</td>
</tr>
<tr valign="top">
<td><code>visibleMetricIndex</code></td>

@@ -89,0 +97,0 @@ <td><code>number</code></td>

@@ -88,3 +88,3 @@ /**

return webpack({
entry: glob.sync('./test/unit/*-test.js'),
entry: glob.sync('./test/unit/**/*-test.js'),
output: {

@@ -175,2 +175,3 @@ path: 'test/unit',

verbose: true,
verboseDebugging: true,
};

@@ -177,0 +178,0 @@ sauceConnectLauncher(opts, (err, sauceConnectProcess) => {

@@ -18,3 +18,3 @@ /**

export const VERSION = '2.0.4';
export const VERSION = '2.1.0';
export const DEV_ID = 'i5iSjo';

@@ -21,0 +21,0 @@

/**
* Fields used by analytics.js.
* This is not an extensive list of all anlaytics.js fields, just the ones
* referenced by autotrack plugins.
* @typedef {{
* allowAnchor: (boolean|undefined),
* allowLinker: (boolean|undefined),
* alwaysSendReferrer: (boolean|undefined),
* anonymizeIp: (boolean|undefined),
* appId: (string|undefined),
* appInstallerId: (string|undefined),
* appName: (string|undefined),
* appVersion: (string|undefined),
* buildHitTask: (Function|undefined),
* campaignContent: (string|undefined),
* campaignId: (string|undefined),
* campaignKeyword: (string|undefined),
* campaignMedium: (string|undefined),
* campaignName: (string|undefined),
* campaignSource: (string|undefined),
* checkProtocolTask: (Function|undefined),
* checkStorageTask: (Function|undefined),
* clientId: (string|undefined),
* contentGroup: (string|undefined),
* cookieDomain: (string|undefined),
* cookieExpires: (number|undefined),
* cookieName: (string|undefined),
* cookiePath: (string|undefined),
* currencyCode: (string|undefined),
* dataSource: (string|undefined),
* devIdTask: (Function|undefined),
* displayFeaturesTask: (Function|undefined),
* encoding: (string|undefined),
* eventAction: (string|undefined),

@@ -11,12 +36,53 @@ * eventCategory: (string|undefined),

* eventValue: (number|undefined),
* exDescription: (string|undefined),
* exFatal: (boolean|undefined),
* exp: (string|undefined),
* expId: (string|undefined),
* expVar: (string|undefined),
* flashVersion: (string|undefined),
* forceSSL: (boolean|undefined),
* historyImportTask: (Function|undefined),
* hitCallback: (Function|undefined),
* hitPayload: (string|undefined),
* hitType: (string|undefined),
* hitCallback: (Function|undefined),
* hostname: (string|undefined),
* javaEnabled: (boolean|undefined),
* language: (string|undefined),
* legacyCookieDomain: (string|undefined),
* legacyHistoryImport: (boolean|undefined),
* linkerParam: (string|undefined),
* linkid: (string|undefined),
* location: (string|undefined),
* name: (string|undefined),
* nonInteraction: (boolean|undefined),
* page: (string|undefined),
* previewTask: (Function|undefined),
* queueTime: (number|undefined),
* referrer: (string|undefined),
* sampleRate: (number|undefined),
* samplerTask: (Function|undefined),
* screenColors: (string|undefined),
* screenName: (string|undefined),
* screenResolution: (string|undefined),
* sendHitTask: (Function|undefined),
* sessionControl: (string|undefined),
* sessionGroup: (string|undefined),
* siteSpeedSampleRate: (number|undefined),
* socialAction: (string|undefined),
* socialNetwork: (string|undefined),
* socialTarget: (string|undefined),
* storage: (string|undefined),
* timingCategory: (string|undefined),
* timingLabel: (string|undefined),
* timingTask: (Function|undefined),
* timingValue: (number|undefined),
* timingVar: (string|undefined),
* title: (string|undefined),
* trackingId: (string|undefined),
* transport: (string|undefined),
* transportUrl: (string|undefined),
* useBeacon: (boolean|undefined),
* userId: (string|undefined),
* validationTask: (Function|undefined),
* viewportSize: (string|undefined),
* }}

@@ -23,0 +89,0 @@ */

@@ -5,2 +5,3 @@ /**

* sessionTimeout: (number),
* visibleThreshold: (number),
* timeZone: (string|undefined),

@@ -7,0 +8,0 @@ * visibleMetricIndex: (number|undefined),

@@ -47,3 +47,3 @@ /**

// Feature detects to prevent errors in unsupporting browsers.
if (!window.addEventListener) return;
if (!document.visibilityState) return;

@@ -53,2 +53,3 @@ /** @type {PageVisibilityTrackerOpts} */

sessionTimeout: Session.DEFAULT_TIMEOUT,
visibleThreshold: 5 * SECONDS,
// timeZone: undefined,

@@ -65,2 +66,3 @@ // visibleMetricIndex: undefined,

this.lastPageState = null;
this.visibleThresholdTimeout_ = null;

@@ -85,4 +87,5 @@ // Binds methods to `this`.

window.addEventListener('unload', this.handleWindowUnload);
document.addEventListener('visibilitychange', this.handleChange);
window.addEventListener('unload', this.handleWindowUnload);
if (document.visibilityState == VISIBLE) {

@@ -104,2 +107,7 @@ this.handleChange();

handleChange() {
if (!(document.visibilityState == VISIBLE ||
document.visibilityState == HIDDEN)) {
return;
}
const lastStoredChange = this.validateChangeData(this.store.get());

@@ -114,21 +122,39 @@

// If the visibilityState has changed to hidden, clear any scheduled
// pageviews waiting for the visibleThreshold timeout.
if (this.visibleThresholdTimeout_ && document.visibilityState == HIDDEN) {
clearTimeout(this.visibleThresholdTimeout_);
}
if (this.session.isExpired()) {
if (document.visibilityState == HIDDEN) {
// Hidden events should never be sent if a session has expired (if
// they are, they'll likely start a new session with just this event).
this.store.clear();
} else {
// If the session has expired, changes to visible should be considered
// a new pageview rather than a visibility event.
if (this.lastPageState == HIDDEN &&
document.visibilityState == VISIBLE) {
// If the session has expired, changes from hidden to visible should
// be considered a new pageview rather than a visibility event.
// This behavior ensures all sessions contain a pageview so
// session-level page dimensions and metrics (e.g. ga:landingPagePath
// and ga:entrances) are correct.
// Also, in order to prevent false positives, we add a small timeout
// that is cleared if the visibilityState changes to hidden shortly
// after the change to visible. This can happen if a user is quickly
// switching through their open tabs but not actually interacting with
// and of them. It can also happen when a user goes to a tab just to
// immediately close it. Such cases should not be considered pageviews.
clearTimeout(this.visibleThresholdTimeout_);
this.visibleThresholdTimeout_ = setTimeout(() => {
/** @type {FieldsObj} */
const defaultFields = {
transport: 'beacon',
queueTime: now() - change.time,
};
this.tracker.send('pageview',
createFieldsObj(defaultFields, this.opts.fieldsObj,
this.tracker, this.opts.hitFilter));
/** @type {FieldsObj} */
const defaultFields = {transport: 'beacon'};
this.tracker.send('pageview',
createFieldsObj(defaultFields, this.opts.fieldsObj,
this.tracker, this.opts.hitFilter));
this.store.set(change);
this.store.set(change);
}, this.opts.visibleThreshold);
} else if (document.visibilityState == HIDDEN) {
// Hidden events should never be sent if a session has expired (if
// they are, they'll likely start a new session with just this event).
this.store.clear();
}

@@ -183,29 +209,31 @@ } else {

sendPageVisibilityEvent(lastStoredChange, hitTime = undefined) {
/** @type {FieldsObj} */
const defaultFields = {
transport: 'beacon',
nonInteraction: true,
eventCategory: 'Page Visibility',
eventAction: 'track',
eventLabel: NULL_DIMENSION,
};
if (hitTime) {
defaultFields.queueTime = now() - hitTime;
}
const delta = this.getTimeSinceLastStoredChange(lastStoredChange, hitTime);
// If at least a one second delta exists, report it.
if (delta) {
defaultFields.eventValue = delta;
// If the detla is greater than the visibileThreshold, report it.
if (delta && delta >= this.opts.visibleThreshold) {
const deltaInSeconds = Math.round(delta / SECONDS);
/** @type {FieldsObj} */
const defaultFields = {
transport: 'beacon',
nonInteraction: true,
eventCategory: 'Page Visibility',
eventAction: 'track',
eventValue: deltaInSeconds,
eventLabel: NULL_DIMENSION,
};
if (hitTime) {
defaultFields.queueTime = now() - hitTime;
}
// If a custom metric was specified, set it equal to the event value.
if (this.opts.visibleMetricIndex) {
defaultFields['metric' + this.opts.visibleMetricIndex] = delta;
defaultFields['metric' + this.opts.visibleMetricIndex] = deltaInSeconds;
}
this.tracker.send('event',
createFieldsObj(defaultFields, this.opts.fieldsObj,
this.tracker, this.opts.hitFilter));
}
this.tracker.send('event',
createFieldsObj(defaultFields, this.opts.fieldsObj,
this.tracker, this.opts.hitFilter));
}

@@ -243,4 +271,4 @@

const isSessionActive = !this.session.isExpired();
const timeSinceLastStoredChange = lastStoredChange.time &&
Math.round((hitTime - lastStoredChange.time) / SECONDS);
const timeSinceLastStoredChange =
lastStoredChange.time && hitTime - lastStoredChange.time;

@@ -296,2 +324,3 @@ return isSessionActive &&

remove() {
this.store.destroy();
this.session.destroy();

@@ -298,0 +327,0 @@ MethodChain.remove(this.tracker, 'set', this.trackerSetOverride);

@@ -27,2 +27,6 @@ /**

/** @type {boolean|undefined} */
let browserSupportsLocalStorage;
/**

@@ -46,3 +50,2 @@ * A storage object to simplify interacting with localStorage.

instances[key] = new Store(key, defaults);
instances[key].key = key;
if (!isListening) initStorageListener();

@@ -54,23 +57,85 @@ }

/**
* Returns true if the browser supports and can successfully write to
* localStorage. The results is cached so this method can be invoked many
* times with no extra performance cost.
* @private
* @return {boolean}
*/
static isSupported_() {
if (browserSupportsLocalStorage != null) {
return browserSupportsLocalStorage;
}
try {
window.localStorage.setItem(AUTOTRACK_PREFIX, AUTOTRACK_PREFIX);
window.localStorage.removeItem(AUTOTRACK_PREFIX);
browserSupportsLocalStorage = true;
} catch (err) {
browserSupportsLocalStorage = false;
}
return browserSupportsLocalStorage;
}
/**
* Wraps the native localStorage method for each stubbing in tests.
* @private
* @param {string} key The store key.
* @return {string|null} The stored value.
*/
static get_(key) {
return window.localStorage.getItem(key);
}
/**
* Wraps the native localStorage method for each stubbing in tests.
* @private
* @param {string} key The store key.
* @param {string} value The value to store.
*/
static set_(key, value) {
window.localStorage.setItem(key, value);
}
/**
* Wraps the native localStorage method for each stubbing in tests.
* @private
* @param {string} key The store key.
*/
static clear_(key) {
window.localStorage.removeItem(key);
}
/**
* @param {string} key A key unique to this store.
* @param {Object=} defaults An optional object of key/value defaults.
*/
constructor(key, defaults) {
constructor(key, defaults = {}) {
super();
this.key = key;
this.defaults = defaults || {};
this.key_ = key;
this.defaults_ = defaults;
/** @type {?Object} */
this.cache_ = null; // Will be set after the first get.
}
/**
* Gets the data stored in localStorage for this store.
* Gets the data stored in localStorage for this store. If the cache is
* already populated, return it as is (since it's always kept up-to-date
* and in sync with activity in other windows via the `storage` event).
* TODO(philipwalton): Implement schema migrations if/when a new
* schema version is introduced.
* @return {!Object} The stored data merged with the defaults.
*/
get() {
try {
// TODO(philipwalton): Implement schema migrations if/when a new
// schema version is introduced.
const storedItem = String(window.localStorage.getItem(this.key));
return parse(storedItem, this.defaults);
} catch(err) {
return {};
if (this.cache_) {
return this.cache_;
} else {
if (Store.isSupported_()) {
try {
this.cache_ = parse(Store.get_(this.key_));
} catch(err) {
// Do nothing.
}
}
return this.cache_ = assign({}, this.defaults_, this.cache_);
}

@@ -85,9 +150,10 @@ }

set(newData) {
const oldData = this.get();
const mergedData = assign(oldData, newData);
this.cache_ = assign({}, this.defaults_, this.cache_, newData);
try {
window.localStorage.setItem(this.key, JSON.stringify(mergedData));
} catch(err) {
// Do nothing.
if (Store.isSupported_()) {
try {
Store.set_(this.key_, JSON.stringify(this.cache_));
} catch(err) {
// Do nothing.
}
}

@@ -100,6 +166,9 @@ }

clear() {
try {
window.localStorage.removeItem(this.key);
} catch(err) {
// Do nothing.
this.cache_ = {};
if (Store.isSupported_()) {
try {
Store.clear_(this.key_);
} catch(err) {
// Do nothing.
}
}

@@ -114,3 +183,3 @@ }

destroy() {
delete instances[this.key];
delete instances[this.key_];
if (!Object.keys(instances).length) {

@@ -150,4 +219,6 @@ removeStorageListener();

if (store) {
const oldData = parse(event.oldValue, store.defaults);
const newData = parse(event.newValue, store.defaults);
const oldData = assign({}, store.defaults_, parse(event.oldValue));
const newData = assign({}, store.defaults_, parse(event.newValue));
store.cache_ = newData;
store.emit('externalSet', newData, oldData);

@@ -159,16 +230,16 @@ }

/**
* Parses a source string as JSON and merges the result with the passed
* defaults object. If an error occurs while
* @param {string} source A JSON string of data.
* @param {!Object} defaults An object of key/value defaults.
* @return {!Object} The parsed data object merged with the passed defaults.
* Parses a source string as JSON
* @param {string|null} source
* @return {!Object} The JSON object.
*/
function parse(source, defaults) {
let data;
try {
data = /** @type {!Object} */ (JSON.parse(source));
} catch(err) {
data = {};
function parse(source) {
let data = {};
if (source) {
try {
data = /** @type {!Object} */ (JSON.parse(source));
} catch(err) {
// Do nothing.
}
}
return assign({}, defaults, data);
return data;
}

@@ -146,8 +146,9 @@ /**

* @param {!Object} target The target object to assign to.
* @param {...Object} sources Additional objects who properties should be
* assigned to target.
* @param {...?Object} sources Additional objects who properties should be
* assigned to target. Non-objects are converted to objects.
* @return {!Object} The modified target object.
*/
export const assign = Object.assign || function(target, ...sources) {
for (let source, i = 0; source = sources[i]; i++) {
for (let i = 0, len = sources.length; i < len; i++) {
const source = Object(sources[i]);
for (let key in source) {

@@ -154,0 +155,0 @@ if (Object.prototype.hasOwnProperty.call(source, key)) {

{
"name": "autotrack",
"version": "2.0.4",
"version": "2.1.0",
"description": "Automatic and enhanced Google Analytics tracking for common user interactions on the web",

@@ -10,3 +10,3 @@ "main": "lib",

"start": "gulp watch",
"test": "gulp test:e2e"
"test": "gulp test"
},

@@ -13,0 +13,0 @@ "repository": {

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
let testId;

@@ -40,3 +47,3 @@ let log;

browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -43,0 +50,0 @@ });

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
let testId;

@@ -40,3 +47,3 @@ let log;

browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -43,0 +50,0 @@ });

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
let testId;

@@ -63,3 +70,3 @@ let log;

browser.scroll(0, 0);
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -66,0 +73,0 @@ });

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
let testId;

@@ -89,3 +96,3 @@ let log;

browser.url('/test/e2e/fixtures/autotrack.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -111,3 +118,3 @@ browser.execute(ga.run, 'require', 'cleanUrlTracker');

browser.url('/test/e2e/fixtures/autotrack-rename.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -133,3 +140,3 @@ browser.execute(ga.run, 'require', 'cleanUrlTracker');

browser.url('/test/e2e/fixtures/autotrack.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -136,0 +143,0 @@ browser.execute(ga.run, 'require', 'cleanUrlTracker');

@@ -55,5 +55,3 @@ /**

browser.scroll(0, 0);
browser.execute(() => {
localStorage.clear();
});
clearStorage();

@@ -316,13 +314,40 @@ browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);

/**
* Forces the session to expire by changing the stored last hit time.
* Manually clear all stores.
*/
function clearStorage() {
setStoreData('autotrack:UA-12345-1:session', {});
setStoreData('autotrack:UA-12345-1:plugins/max-scroll-tracker', {});
}
/**
* Manually expires the session.
*/
function expireSession() {
browser.execute(() => {
const storedSessionData = JSON.parse(
localStorage.getItem('autotrack:UA-12345-1:session')) || {};
setStoreData('autotrack:UA-12345-1:session', {isExpired: true});
}
storedSessionData.isExpired = true;
localStorage.setItem('autotrack:UA-12345-1:session',
JSON.stringify(storedSessionData));
});
/**
* Manually set a value for store in all open windows/tabs.
* @param {string} key
* @param {!Object} value
*/
function setStoreData(key, value) {
browser.execute((key, value) => {
const oldValue = localStorage.getItem(key);
const newValue = JSON.stringify(value);
// IE11 doesn't support event constructors.
try {
// Set the value on localStorage so it triggers the storage event in
// other tabs. Also, manually dispatch the event in this tab since just
// writing to localStorage won't update the locally cached values.
window.localStorage.setItem(key, newValue);
window.dispatchEvent(
new StorageEvent('storage', {key, oldValue, newValue}));
} catch(err) {
// Do nothing
}
}, key, value);
}

@@ -26,4 +26,12 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
const TIMEOUT = 1000;
const opts = {

@@ -67,3 +75,3 @@ definitions: [

browser.setViewportSize({width: 800, height: 600}, false);
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -140,3 +148,3 @@ });

browser.execute(ga.run, 'remove');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -143,0 +151,0 @@ browser.setViewportSize({width: 800, height: 600}, false);

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
const baseUrl = browser.options.baseUrl;

@@ -42,3 +49,3 @@

browser.url('/test/e2e/fixtures/outbound-form-tracker.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -92,3 +99,3 @@ });

browser.url('/test/e2e/fixtures/outbound-form-tracker.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -95,0 +102,0 @@ browser.execute(ga.run, 'require', 'outboundFormTracker', {

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
const baseUrl = browser.options.baseUrl;

@@ -42,3 +49,3 @@

browser.url('/test/e2e/fixtures/outbound-link-tracker.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -150,3 +157,3 @@ });

browser.url('/test/e2e/fixtures/outbound-link-tracker.html');
browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -153,0 +160,0 @@ browser.execute(ga.run, 'require', 'outboundLinkTracker', {

@@ -28,2 +28,3 @@ /**

const SESSION_TIMEOUT_IN_MINUTES = (1/60) * 3; // 3 seconds
const VISIBLE_THRESHOLD = 2000; // 2 seconds

@@ -37,3 +38,7 @@

const TEST_OPTS = {
visibleThreshold: 0,
};
let testId;

@@ -50,5 +55,3 @@ let log;

browser.url('/test/e2e/fixtures/autotrack.html?tab=1');
browser.execute(() => {
localStorage.clear();
});
clearStorage();
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);

@@ -66,3 +69,3 @@ browser.execute(ga.logHitData, testId);

browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
openNewTab();

@@ -80,3 +83,3 @@

browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.pause(2000);

@@ -94,3 +97,3 @@ openNewTab();

browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
openNewTab();

@@ -111,2 +114,3 @@ closeAllButFirstTab();

browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
visibleThreshold: 0,
visibleMetricIndex: 1,

@@ -129,2 +133,3 @@ });

browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
visibleThreshold: 0,
sessionTimeout: SESSION_TIMEOUT_IN_MINUTES,

@@ -141,9 +146,6 @@ });

it('sends a pageview when changing to visible if the session has expired',
function() {
it('sends a pageview on session-expiry when changing to visible', function() {
if (!browserSupportsTabs()) return this.skip();
browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
sessionTimeout: SESSION_TIMEOUT_IN_MINUTES,
});
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);

@@ -163,2 +165,18 @@ expireSession();

it('does not send a session-expiry pageview on initial pageload', function() {
if (!browserSupportsTabs()) return this.skip();
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
expireSession();
log.removeHits();
openNewWindow('/test/e2e/fixtures/autotrack.html?window=1');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
log.assertNoHitsReceived();
});
it('resets the session timeout when other hits are sent', function() {

@@ -168,2 +186,3 @@ if (!browserSupportsTabs()) return this.skip();

browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
visibleThreshold: 0,
sessionTimeout: SESSION_TIMEOUT_IN_MINUTES,

@@ -195,2 +214,52 @@ });

it('only sends events when the visibleThreshold is met', function() {
if (!browserSupportsTabs()) return this.skip();
browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
visibleThreshold: VISIBLE_THRESHOLD,
sessionTimeout: SESSION_TIMEOUT_IN_MINUTES,
});
openNewTab();
closeAllButFirstTab();
openNewTab();
closeAllButFirstTab();
openNewTab();
closeAllButFirstTab();
log.assertNoHitsReceived();
browser.pause(VISIBLE_THRESHOLD);
openNewTab();
browser.waitUntil(log.hitCountEquals(1));
const hits = log.getHits();
assert.strictEqual(hits[0].ec, 'Page Visibility');
assert.strictEqual(hits[0].ea, 'track');
});
it('waits to send pageviews until the visibleThreshold is met', function() {
if (!browserSupportsTabs()) return this.skip();
browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
visibleThreshold: VISIBLE_THRESHOLD,
sessionTimeout: SESSION_TIMEOUT_IN_MINUTES,
});
expireSession();
log.removeHits();
openNewTab();
closeAllButFirstTab();
const start = Date.now();
browser.waitUntil(log.hitCountEquals(1));
const end = Date.now();
// Expects non-pageview hits queued to be sent after the session has timed
// out to include a pageview immediately before them.
const hits = log.getHits();
assert.strictEqual(hits[0].t, 'pageview');
assert(hits[0].qt >= VISIBLE_THRESHOLD);
assert(end - start >= VISIBLE_THRESHOLD);
});
it('handles closing a window/tab when a visible window is still open',

@@ -201,3 +270,3 @@ function() {

const tab1 = browser.getCurrentTabId();
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);

@@ -207,3 +276,3 @@ const window1 = openNewWindow('/test/e2e/fixtures/autotrack.html?window=1');

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);

@@ -235,3 +304,3 @@ browser.close(tab1); // Close window1 and switch to tab1.

browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -278,3 +347,3 @@ browser.pause(randomInteger(500, 2000));

const tab1 = browser.getCurrentTabId();
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -289,3 +358,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -329,3 +398,3 @@ browser.pause(randomInteger(500, 2000));

const tab1 = browser.getCurrentTabId();
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -337,3 +406,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -348,3 +417,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -403,3 +472,3 @@ browser.pause(randomInteger(500, 2000));

const tab1 = browser.getCurrentTabId();
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -414,3 +483,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -422,3 +491,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -430,3 +499,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -499,3 +568,3 @@ browser.pause(randomInteger(500, 2000));

const tab1 = browser.getCurrentTabId();
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -510,3 +579,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -518,3 +587,3 @@ browser.pause(randomInteger(500, 2000));

browser.execute(ga.logHitData, testId);
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -525,2 +594,3 @@ browser.pause(randomInteger(500, 2000));

expireSession();
browser.pause(randomInteger(500, 2000));

@@ -581,2 +651,3 @@ browser.close(tab3); // Close tab4 and go to tab3.

browser.execute(ga.run, 'require', 'pageVisibilityTracker', {
visibleThreshold: 0,
fieldsObj: {

@@ -615,3 +686,3 @@ dimension1: 'pageVisibilityTracker',

it('includes usage params with all hits', () => {
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -631,3 +702,3 @@ browser.waitUntil(log.hitCountEquals(1));

it('destroys all bound events and functionality', () => {
browser.execute(ga.run, 'require', 'pageVisibilityTracker');
browser.execute(ga.run, 'require', 'pageVisibilityTracker', TEST_OPTS);
browser.execute(ga.run, 'send', 'pageview');

@@ -743,13 +814,40 @@

/**
* Forces the session to expire by changing the stored last hit time.
* Manually clear all stores.
*/
function clearStorage() {
setStoreData('autotrack:UA-12345-1:session', {});
setStoreData('autotrack:UA-12345-1:plugins/page-visibility-tracker', {});
}
/**
* Manually expires the session.
*/
function expireSession() {
browser.execute(() => {
const storedSessionData = JSON.parse(
localStorage.getItem('autotrack:UA-12345-1:session')) || {};
setStoreData('autotrack:UA-12345-1:session', {isExpired: true});
}
storedSessionData.isExpired = true;
localStorage.setItem('autotrack:UA-12345-1:session',
JSON.stringify(storedSessionData));
});
/**
* Manually set a value for store in all open windows/tabs.
* @param {string} key
* @param {!Object} value
*/
function setStoreData(key, value) {
browser.execute((key, value) => {
const oldValue = window.localStorage.getItem(key);
const newValue = JSON.stringify(value);
// IE11 doesn't support event constructors.
try {
// Set the value on localStorage so it triggers the storage event in
// other tabs. Also, manually dispatch the event in this tab since just
// writing to localStorage won't update the locally cached values.
window.localStorage.setItem(key, newValue);
window.dispatchEvent(
new StorageEvent('storage', {key, oldValue, newValue}));
} catch(err) {
// Do nothing
}
}, key, value);
}

@@ -765,2 +863,3 @@

ga('require', 'pageVisibilityTracker', {
visibleThreshold: 0,
hitFilter: (model) => {

@@ -767,0 +866,0 @@ const eventValue = model.get('eventValue');

@@ -26,2 +26,9 @@ /**

const DEFAULT_TRACKER_FIELDS = {
trackingId: 'UA-12345-1',
cookieDomain: 'auto',
siteSpeedSampleRate: 0,
};
let testId;

@@ -40,3 +47,3 @@ let log;

browser.execute(ga.run, 'create', 'UA-XXXXX-Y', 'auto');
browser.execute(ga.run, 'create', DEFAULT_TRACKER_FIELDS);
browser.execute(ga.logHitData, testId);

@@ -43,0 +50,0 @@ });

@@ -46,22 +46,25 @@ /**

},
{
browserName: 'firefox',
platform: 'OS X 10.11',
version: 'latest',
},
{
browserName: 'safari',
platform: 'OS X 10.12',
version: '10.0',
},
{
browserName: 'safari',
platform: 'OS X 10.11',
version: '9',
},
{
browserName: 'internet explorer',
platform: 'Windows 8.1',
version: '11',
},
// TODO(philipwalton): other browsers have been too flaky to run on
// every push. Uncomment and test manually before making releases, but
// for now there's too much failure noise to run on these browsers.
// {
// browserName: 'firefox',
// platform: 'OS X 10.11',
// version: 'latest',
// },
// {
// browserName: 'safari',
// platform: 'OS X 10.12',
// version: '10.0',
// },
// {
// browserName: 'safari',
// platform: 'OS X 10.11',
// version: '9',
// },
// {
// browserName: 'internet explorer',
// platform: 'Windows 8.1',
// version: '11',
// },
// TODO(philipwalton) Edge webdriver does not fully support enough of the

@@ -68,0 +71,0 @@ // webdriver features to rely on. Wait for full support and then re-add:

@@ -192,4 +192,5 @@ /**

const originalDateTimeFormatDescriptor = Object.getOwnPropertyDescriptor(
Intl.DateTimeFormat.prototype, 'format');
const originalDateTimeFormatDescriptor = window.Intl &&
window.Intl.DateTimeFormat && Object.getOwnPropertyDescriptor(
Intl.DateTimeFormat.prototype, 'format');

@@ -196,0 +197,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc