Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Tracker/TrackerCodeGenerator.php16
-rw-r--r--js/piwik.js212
-rw-r--r--piwik.js77
-rw-r--r--plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js2
-rw-r--r--plugins/CoreAdminHome/templates/trackingCodeGenerator.twig2
-rw-r--r--plugins/Referrers/Columns/Base.php34
-rw-r--r--plugins/Referrers/Columns/Campaign.php2
-rw-r--r--plugins/Referrers/Referrers.php10
-rw-r--r--plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php127
-rw-r--r--plugins/SitesManager/API.php1
-rw-r--r--plugins/SitesManager/Model.php16
-rw-r--r--plugins/SitesManager/SiteUrls.php148
-rw-r--r--plugins/SitesManager/tests/Integration/ModelTest.php52
-rw-r--r--plugins/SitesManager/tests/Integration/SiteUrlsTest.php124
-rw-r--r--tests/javascript/enable_sqlite0
-rw-r--r--tests/javascript/index.php212
-rw-r--r--tests/javascript/piwiktest.js3
17 files changed, 957 insertions, 81 deletions
diff --git a/core/Tracker/TrackerCodeGenerator.php b/core/Tracker/TrackerCodeGenerator.php
index fbf4b4c2be..c985db88e7 100644
--- a/core/Tracker/TrackerCodeGenerator.php
+++ b/core/Tracker/TrackerCodeGenerator.php
@@ -172,13 +172,23 @@ class TrackerCodeGenerator
}
// We need to parse_url to isolate hosts
$websiteHosts = array();
+ $firstHost = null;
foreach ($websiteUrls as $site_url) {
$referrerParsed = parse_url($site_url);
- $websiteHosts[] = $referrerParsed['host'];
+
+ if (!isset($firstHost)) {
+ $firstHost = $referrerParsed['host'];
+ }
+
+ $url = $referrerParsed['host'];
+ if (!empty($referrerParsed['path'])) {
+ $url .= $referrerParsed['path'];
+ }
+ $websiteHosts[] = $url;
}
$options = '';
- if ($mergeSubdomains && !empty($websiteHosts)) {
- $options .= ' _paq.push(["setCookieDomain", "*.' . $websiteHosts[0] . '"]);' . "\n";
+ if ($mergeSubdomains && !empty($firstHost)) {
+ $options .= ' _paq.push(["setCookieDomain", "*.' . $firstHost . '"]);' . "\n";
}
if ($mergeAliasUrls && !empty($websiteHosts)) {
$urls = '["*.' . implode('","*.', $websiteHosts) . '"]';
diff --git a/js/piwik.js b/js/piwik.js
index fa9d9f57e5..344e5436e9 100644
--- a/js/piwik.js
+++ b/js/piwik.js
@@ -1021,7 +1021,7 @@ if (typeof JSON2 !== 'object' && typeof window.JSON === 'object' && window.JSON.
trackVisibleContentImpressions, isTrackOnlyVisibleContentEnabled, port, isUrlToCurrentDomain,
isNodeAuthorizedToTriggerInteraction, replaceHrefIfInternalLink, getConfigDownloadExtensions, disableLinkTracking,
substr, setAnyAttribute, wasContentTargetAttrReplaced, max, abs, childNodes, compareDocumentPosition, body,
- getConfigVisitorCookieTimeout, getRemainingVisitorCookieTimeout,
+ getConfigVisitorCookieTimeout, getRemainingVisitorCookieTimeout, getDomains, getConfigCookiePath,
newVisitor, uuid, createTs, visitCount, currentVisitTs, lastVisitTs, lastEcommerceOrderTs,
"", "\b", "\t", "\n", "\f", "\r", "\"", "\\", apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length, parse, prototype, push, replace,
@@ -1593,6 +1593,10 @@ if (typeof Piwik !== 'object') {
domain = domain.slice(1);
}
+ if (domain.indexOf('/') !== -1) {
+ domain = domain.substr(0, domain.indexOf('/'));
+ }
+
return domain;
}
@@ -3012,10 +3016,115 @@ if (typeof Piwik !== 'object') {
return baseUrl + url;
}
+ function isSameHost (hostName, alias) {
+ var offset;
+
+ hostName = String(hostName).toLowerCase();
+ alias = String(alias).toLowerCase();
+
+ if (hostName === alias) {
+ return true;
+ }
+
+ if (alias.slice(0, 1) === '.') {
+ if (hostName === alias.slice(1)) {
+ return true;
+ }
+
+ offset = hostName.length - alias.length;
+
+ if ((offset > 0) && (hostName.slice(offset) === alias)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function stringEndsWith(str, suffix) {
+ str = String(str);
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
+ }
+
+ function removeCharactersFromEndOfString(str, numCharactersToRemove) {
+ str = String(str);
+ return str.substr(0, str.length - numCharactersToRemove);
+ }
+
+ /*
+ * Extract pathname from URL. element.pathname is actually supported by pretty much all browsers including
+ * IE6 apart from some rare very old ones
+ */
+ function getPathName(url) {
+ var parser = document.createElement('a');
+ if (url.indexOf('//') !== 0 && url.indexOf('http') !== 0) {
+ url = 'http://' + url;
+ }
+
+ parser.href = content.toAbsoluteUrl(url);
+ if (parser.pathname) {
+ return parser.pathname;
+ }
+
+ return '';
+ }
+
+ function isSitePath (path, pathAlias)
+ {
+ var matchesAnyPath = (!pathAlias || pathAlias === '/');
+
+ if (matchesAnyPath) {
+ return true;
+ }
+
+ if (path === pathAlias) {
+ return true;
+ }
+
+ if (!path) {
+ return false;
+ }
+
+ pathAlias = String(pathAlias).toLowerCase();
+ path = String(path).toLowerCase();
+
+ // we need to append slashes so /foobarbaz won't match a site /foobar
+ if (!stringEndsWith(path, '/')) {
+ path += '/';
+ }
+
+ if (!stringEndsWith(pathAlias, '/')) {
+ pathAlias += '/';
+ }
+
+ return path.indexOf(pathAlias) === 0;
+ }
+
+ function isSiteHostPath(host, path)
+ {
+ var i,
+ alias,
+ configAlias,
+ aliasHost,
+ aliasPath;
+
+ for (i = 0; i < configHostsAlias.length; i++) {
+ aliasHost = domainFixup(configHostsAlias[i]);
+ aliasPath = getPathName(configHostsAlias[i]);
+
+ if (isSameHost(host, aliasHost) && isSitePath(path, aliasPath)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/*
* Is the host local? (i.e., not an outlink)
*/
function isSiteHostName(hostName) {
+
var i,
alias,
offset;
@@ -4004,6 +4113,8 @@ if (typeof Piwik !== 'object') {
return;
}
+ var originalSourcePath = sourceElement.pathname || getPathName(sourceElement.href);
+
// browsers, such as Safari, don't downcase hostname and href
var originalSourceHostName = sourceElement.hostname || getHostName(sourceElement.href);
var sourceHostName = originalSourceHostName.toLowerCase();
@@ -4014,7 +4125,7 @@ if (typeof Piwik !== 'object') {
if (!scriptProtocol.test(sourceHref)) {
// track outlinks and all downloads
- var linkType = getLinkType(sourceElement.className, sourceHref, isSiteHostName(sourceHostName), query.hasNodeAttribute(sourceElement, 'download'));
+ var linkType = getLinkType(sourceElement.className, sourceHref, isSiteHostPath(sourceHostName, originalSourcePath), query.hasNodeAttribute(sourceElement, 'download'));
if (linkType) {
return {
@@ -4780,6 +4891,60 @@ if (typeof Piwik !== 'object') {
});
}
+ /**
+ * Note: While we check whether the user is on a configHostAlias path we do not check whether the user is
+ * actually on the configHostAlias domain. This is already done where this method is called and for
+ * simplicity we do not check this again.
+ *
+ * Also we currently assume that all configHostAlias domains start with the same wild card of '*.', '.' or
+ * none. Eg either all like '*.piwik.org' or '.piwik.org' or 'piwik.org'. Piwik always adds '*.' so it
+ * should be fine.
+ */
+ function findConfigCookiePathToUse(configHostAlias, currentUrl)
+ {
+ var aliasPath = getPathName(configHostAlias);
+ var currentPath = getPathName(currentUrl);
+
+ if (!aliasPath || aliasPath === '/' || !currentPath || currentPath === '/') {
+ // no path set that would be useful for cookiePath
+ return;
+ }
+
+ var aliasDomain = domainFixup(configHostAlias);
+
+ if (isSiteHostPath(aliasDomain, '/')) {
+ // there is another configHostsAlias having same domain that allows all paths
+ // eg this alias is for piwik.org/support but there is another alias allowing
+ // piwik.org
+ return;
+ }
+
+ if (stringEndsWith(aliasPath, '/')) {
+ aliasPath = removeCharactersFromEndOfString(aliasPath, 1);
+ }
+
+ // eg if we're in the case of "apache.piwik/foo/bar" we check whether there is maybe
+ // also a config alias allowing "apache.piwik/foo". In this case we're not allowed to set
+ // the cookie for "/foo/bar" but "/foo"
+ var pathAliasParts = aliasPath.split('/');
+ var i;
+ for (i = 2; i < pathAliasParts.length; i++) {
+ var lessRestrctivePath = pathAliasParts.slice(0, i).join('/');
+ if (isSiteHostPath(aliasDomain, lessRestrctivePath)) {
+ aliasPath = lessRestrctivePath;
+ break;
+ }
+ }
+
+ if (!isSitePath(currentPath, aliasPath)) {
+ // current path of current URL does not match the alias
+ // eg user is on piwik.org/demo but configHostAlias is for piwik.org/support
+ return;
+ }
+
+ return aliasPath;
+ }
+
/*
* Browser features (plugins, resolution, cookies)
*/
@@ -4917,6 +5082,12 @@ if (typeof Piwik !== 'object') {
internalIsNodeVisible: isVisible,
isNodeAuthorizedToTriggerInteraction: isNodeAuthorizedToTriggerInteraction,
replaceHrefIfInternalLink: replaceHrefIfInternalLink,
+ getDomains: function () {
+ return configHostsAlias;
+ },
+ getConfigCookiePath: function () {
+ return configCookiePath;
+ },
getConfigDownloadExtensions: function () {
return configDownloadExtensions;
},
@@ -5347,13 +5518,44 @@ if (typeof Piwik !== 'object') {
},
/**
- * Set array of domains to be treated as local
+ * Set array of domains to be treated as local. Also supports path, eg '.piwik.org/subsite1'. In this
+ * case all links that don't go to '*.piwik.org/subsite1/ *' would be treated as outlinks.
+ * For example a link to 'piwik.org/' or 'piwik.org/subsite2' both would be treated as outlinks.
+ *
+ * We might automatically set a cookieConfigPath to avoid creating several cookies under one domain
+ * if there is a hostAlias defined with a path. Say a user is visiting 'http://piwik.org/subsite1'
+ * and '.piwik.org/subsite1' is set as a hostsAlias. Piwik will automatically use '/subsite1' as
+ * cookieConfigPath.
*
* @param string|array hostsAlias
*/
setDomains: function (hostsAlias) {
configHostsAlias = isString(hostsAlias) ? [hostsAlias] : hostsAlias;
- configHostsAlias.push(domainAlias);
+
+ var hasDomainAliasAlready = false, i;
+ for (i in configHostsAlias) {
+ if (Object.prototype.hasOwnProperty.call(configHostsAlias, i)
+ && isSameHost(domainAlias, domainFixup(String(configHostsAlias[i])))) {
+ hasDomainAliasAlready = true;
+
+ if (!configCookiePath) {
+ var path = findConfigCookiePathToUse(configHostsAlias[i], locationHrefAlias);
+ if (path) {
+ this.setCookiePath(path);
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (!hasDomainAliasAlready) {
+ /**
+ * eg if domainAlias = 'piwik.org' and someone set hostsAlias = ['piwik.org/foo'] then we should
+ * not add piwik.org as it would increase the allowed scope.
+ */
+ configHostsAlias.push(domainAlias);
+ }
},
/**
@@ -6195,7 +6397,7 @@ if (typeof Piwik !== 'object') {
asyncTracker = new Tracker();
- var applyFirst = ['disableCookies', 'setTrackerUrl', 'setAPIUrl', 'setCookiePath', 'setCookieDomain', 'setUserId', 'setSiteId', 'enableLinkTracking'];
+ var applyFirst = ['disableCookies', 'setTrackerUrl', 'setAPIUrl', 'setCookiePath', 'setCookieDomain', 'setDomains', 'setUserId', 'setSiteId', 'enableLinkTracking'];
_paq = applyMethodsInOrder(_paq, applyFirst);
// apply the queue of actions
diff --git a/piwik.js b/piwik.js
index 401ae10af1..e16b81c991 100644
--- a/piwik.js
+++ b/piwik.js
@@ -23,43 +23,44 @@ function j(Y){try{return H(Y)}catch(Z){return unescape(Y)}}function y(Z){var Y=t
R()})}else{if(w.attachEvent){w.attachEvent("onreadystatechange",function Y(){if(w.readyState==="complete"){w.detachEvent("onreadystatechange",Y);R()}});if(w.documentElement.doScroll&&I===I.top){(function Y(){if(!q){try{w.documentElement.doScroll("left")}catch(aa){setTimeout(Y,0);return}R()}}())}}}if((new RegExp("WebKit")).test(e.userAgent)){Z=setInterval(function(){if(q||/loaded|complete/.test(w.readyState)){clearInterval(Z);R()}},10)}X(I,"load",R,false)}function i(aa,Z){var Y=w.createElement("script");Y.type="text/javascript";Y.src=aa;if(Y.readyState){Y.onreadystatechange=function(){var ab=this.readyState;if(ab==="loaded"||ab==="complete"){Y.onreadystatechange=null;Z()}}}else{Y.onload=Z}w.getElementsByTagName("head")[0].appendChild(Y)}function z(){var Y="";try{Y=I.top.document.referrer}catch(aa){if(I.parent){try{Y=I.parent.document.referrer}catch(Z){Y=""}}}if(Y===""){Y=w.referrer}return Y}function l(Y){var aa=new RegExp("^([a-z]+):"),Z=aa.exec(Y);return Z?Z[1]:null}function c(Y){var aa=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),Z=aa.exec(Y);
return Z?Z[1]:Y}function K(aa,Z){var Y="[\\?&#]"+Z+"=([^&#]*)";var ac=new RegExp(Y);var ab=ac.exec(aa);return ab?H(ab[1]):""}function u(Y){return unescape(m(Y))}function W(an){var aa=function(au,at){return(au<<at)|(au>>>(32-at))},ao=function(aw){var au="",av,at;for(av=7;av>=0;av--){at=(aw>>>(av*4))&15;au+=at.toString(16)}return au},ad,aq,ap,Z=[],ah=1732584193,af=4023233417,ae=2562383102,ac=271733878,ab=3285377520,am,al,ak,aj,ai,ar,Y,ag=[];an=u(an);Y=an.length;for(aq=0;aq<Y-3;aq+=4){ap=an.charCodeAt(aq)<<24|an.charCodeAt(aq+1)<<16|an.charCodeAt(aq+2)<<8|an.charCodeAt(aq+3);ag.push(ap)}switch(Y&3){case 0:aq=2147483648;break;case 1:aq=an.charCodeAt(Y-1)<<24|8388608;break;case 2:aq=an.charCodeAt(Y-2)<<24|an.charCodeAt(Y-1)<<16|32768;break;case 3:aq=an.charCodeAt(Y-3)<<24|an.charCodeAt(Y-2)<<16|an.charCodeAt(Y-1)<<8|128;break}ag.push(aq);while((ag.length&15)!==14){ag.push(0)}ag.push(Y>>>29);ag.push((Y<<3)&4294967295);for(ad=0;ad<ag.length;ad+=16){for(aq=0;aq<16;aq++){Z[aq]=ag[ad+aq]}for(aq=16;
aq<=79;aq++){Z[aq]=aa(Z[aq-3]^Z[aq-8]^Z[aq-14]^Z[aq-16],1)}am=ah;al=af;ak=ae;aj=ac;ai=ab;for(aq=0;aq<=19;aq++){ar=(aa(am,5)+((al&ak)|(~al&aj))+ai+Z[aq]+1518500249)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}for(aq=20;aq<=39;aq++){ar=(aa(am,5)+(al^ak^aj)+ai+Z[aq]+1859775393)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}for(aq=40;aq<=59;aq++){ar=(aa(am,5)+((al&ak)|(al&aj)|(ak&aj))+ai+Z[aq]+2400959708)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}for(aq=60;aq<=79;aq++){ar=(aa(am,5)+(al^ak^aj)+ai+Z[aq]+3395469782)&4294967295;ai=aj;aj=ak;ak=aa(al,30);al=am;am=ar}ah=(ah+am)&4294967295;af=(af+al)&4294967295;ae=(ae+ak)&4294967295;ac=(ac+aj)&4294967295;ab=(ab+ai)&4294967295}ar=ao(ah)+ao(af)+ao(ae)+ao(ac)+ao(ab);return ar.toLowerCase()}function P(aa,Y,Z){if(!aa){aa=""}if(!Y){Y=""}if(aa==="translate.googleusercontent.com"){if(Z===""){Z=Y}Y=K(Y,"u");aa=c(Y)}else{if(aa==="cc.bingj.com"||aa==="webcache.googleusercontent.com"||aa.slice(0,5)==="74.6."){Y=w.links[0].href;aa=c(Y)}}return[aa,Y,Z]
-}function A(Z){var Y=Z.length;if(Z.charAt(--Y)==="."){Z=Z.slice(0,Y)}if(Z.slice(0,2)==="*."){Z=Z.slice(1)}return Z}function V(Z){Z=Z&&Z.text?Z.text:Z;if(!o(Z)){var Y=w.getElementsByTagName("title");if(Y&&y(Y[0])){Z=Y[0].text}}return Z}function E(Y){if(!Y){return[]}if(!y(Y.children)&&y(Y.childNodes)){return Y.children}if(y(Y.children)){return Y.children}return[]}function J(Z,Y){if(!Z||!Y){return false}if(Z.contains){return Z.contains(Y)}if(Z===Y){return true}if(Z.compareDocumentPosition){return !!(Z.compareDocumentPosition(Y)&16)}return false}function B(aa,ab){if(aa&&aa.indexOf){return aa.indexOf(ab)}if(!y(aa)||aa===null){return -1}if(!aa.length){return -1}var Y=aa.length;if(Y===0){return -1}var Z=0;while(Z<Y){if(aa[Z]===ab){return Z}Z++}return -1}function g(aa){if(!aa){return false}function Y(ac,ad){if(I.getComputedStyle){return w.defaultView.getComputedStyle(ac,null)[ad]}if(ac.currentStyle){return ac.currentStyle[ad]}}function ab(ac){ac=ac.parentNode;while(ac){if(ac===w){return true}ac=ac.parentNode
-}return false}function Z(ae,ak,ac,ah,af,ai,ag){var ad=ae.parentNode,aj=1;if(!ab(ae)){return false}if(9===ad.nodeType){return true}if("0"===Y(ae,"opacity")||"none"===Y(ae,"display")||"hidden"===Y(ae,"visibility")){return false}if(!y(ak)||!y(ac)||!y(ah)||!y(af)||!y(ai)||!y(ag)){ak=ae.offsetTop;af=ae.offsetLeft;ah=ak+ae.offsetHeight;ac=af+ae.offsetWidth;ai=ae.offsetWidth;ag=ae.offsetHeight}if(aa===ae&&(0===ag||0===ai)&&"hidden"===Y(ae,"overflow")){return false}if(ad){if(("hidden"===Y(ad,"overflow")||"scroll"===Y(ad,"overflow"))){if(af+aj>ad.offsetWidth+ad.scrollLeft||af+ai-aj<ad.scrollLeft||ak+aj>ad.offsetHeight+ad.scrollTop||ak+ag-aj<ad.scrollTop){return false}}if(ae.offsetParent===ad){af+=ad.offsetLeft;ak+=ad.offsetTop}return Z(ad,ak,ac,ah,af,ai,ag)}return true}return Z(aa)}var S={htmlCollectionToArray:function(aa){var Y=[],Z;if(!aa||!aa.length){return Y}for(Z=0;Z<aa.length;Z++){Y.push(aa[Z])}return Y},find:function(Y){if(!document.querySelectorAll||!Y){return[]}var Z=document.querySelectorAll(Y);
-return this.htmlCollectionToArray(Z)},findMultiple:function(aa){if(!aa||!aa.length){return[]}var Z,ab;var Y=[];for(Z=0;Z<aa.length;Z++){ab=this.find(aa[Z]);Y=Y.concat(ab)}Y=this.makeNodesUnique(Y);return Y},findNodesByTagName:function(Z,Y){if(!Z||!Y||!Z.getElementsByTagName){return[]}var aa=Z.getElementsByTagName(Y);return this.htmlCollectionToArray(aa)},makeNodesUnique:function(Y){var ad=[].concat(Y);Y.sort(function(af,ae){if(af===ae){return 0}var ah=B(ad,af);var ag=B(ad,ae);if(ah===ag){return 0}return ah>ag?-1:1});if(Y.length<=1){return Y}var Z=0;var ab=0;var ac=[];var aa;aa=Y[Z++];while(aa){if(aa===Y[Z]){ab=ac.push(Z)}aa=Y[Z++]||null}while(ab--){Y.splice(ac[ab],1)}return Y},getAttributeValueFromNode:function(ac,aa){if(!this.hasNodeAttribute(ac,aa)){return}if(ac&&ac.getAttribute){return ac.getAttribute(aa)}if(!ac||!ac.attributes){return}var ab=(typeof ac.attributes[aa]);if("undefined"===ab){return}if(ac.attributes[aa].value){return ac.attributes[aa].value}if(ac.attributes[aa].nodeValue){return ac.attributes[aa].nodeValue
-}var Z;var Y=ac.attributes;if(!Y){return}for(Z=0;Z<Y.length;Z++){if(Y[Z].nodeName===aa){return Y[Z].nodeValue}}return null},hasNodeAttributeWithValue:function(Z,Y){var aa=this.getAttributeValueFromNode(Z,Y);return !!aa},hasNodeAttribute:function(aa,Y){if(aa&&aa.hasAttribute){return aa.hasAttribute(Y)}if(aa&&aa.attributes){var Z=(typeof aa.attributes[Y]);return"undefined"!==Z}return false},hasNodeCssClass:function(aa,Y){if(aa&&Y&&aa.className){var Z=typeof aa.className==="string"?aa.className.split(" "):[];if(-1!==B(Z,Y)){return true}}return false},findNodesHavingAttribute:function(ac,aa,Y){if(!Y){Y=[]}if(!ac||!aa){return Y}var ab=E(ac);if(!ab||!ab.length){return Y}var Z,ad;for(Z=0;Z<ab.length;Z++){ad=ab[Z];if(this.hasNodeAttribute(ad,aa)){Y.push(ad)}Y=this.findNodesHavingAttribute(ad,aa,Y)}return Y},findFirstNodeHavingAttribute:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeAttribute(aa,Z)){return aa}var Y=this.findNodesHavingAttribute(aa,Z);if(Y&&Y.length){return Y[0]}},findFirstNodeHavingAttributeWithValue:function(ab,aa){if(!ab||!aa){return
-}if(this.hasNodeAttributeWithValue(ab,aa)){return ab}var Y=this.findNodesHavingAttribute(ab,aa);if(!Y||!Y.length){return}var Z;for(Z=0;Z<Y.length;Z++){if(this.getAttributeValueFromNode(Y[Z],aa)){return Y[Z]}}},findNodesHavingCssClass:function(ac,ab,Y){if(!Y){Y=[]}if(!ac||!ab){return Y}if(ac.getElementsByClassName){var ad=ac.getElementsByClassName(ab);return this.htmlCollectionToArray(ad)}var aa=E(ac);if(!aa||!aa.length){return[]}var Z,ae;for(Z=0;Z<aa.length;Z++){ae=aa[Z];if(this.hasNodeCssClass(ae,ab)){Y.push(ae)}Y=this.findNodesHavingCssClass(ae,ab,Y)}return Y},findFirstNodeHavingClass:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeCssClass(aa,Z)){return aa}var Y=this.findNodesHavingCssClass(aa,Z);if(Y&&Y.length){return Y[0]}},isLinkElement:function(Z){if(!Z){return false}var Y=String(Z.nodeName).toLowerCase();var ab=["a","area"];var aa=B(ab,Y);return aa!==-1},setAnyAttribute:function(Z,Y,aa){if(!Z||!Y){return}if(Z.setAttribute){Z.setAttribute(Y,aa)}else{Z[Y]=aa}}};var n={CONTENT_ATTR:"data-track-content",CONTENT_CLASS:"piwikTrackContent",CONTENT_NAME_ATTR:"data-content-name",CONTENT_PIECE_ATTR:"data-content-piece",CONTENT_PIECE_CLASS:"piwikContentPiece",CONTENT_TARGET_ATTR:"data-content-target",CONTENT_TARGET_CLASS:"piwikContentTarget",CONTENT_IGNOREINTERACTION_ATTR:"data-content-ignoreinteraction",CONTENT_IGNOREINTERACTION_CLASS:"piwikContentIgnoreInteraction",location:undefined,findContentNodes:function(){var Z="."+this.CONTENT_CLASS;
-var Y="["+this.CONTENT_ATTR+"]";var aa=S.findMultiple([Z,Y]);return aa},findContentNodesWithinNode:function(ab){if(!ab){return[]}var Z=S.findNodesHavingCssClass(ab,this.CONTENT_CLASS);var Y=S.findNodesHavingAttribute(ab,this.CONTENT_ATTR);if(Y&&Y.length){var aa;for(aa=0;aa<Y.length;aa++){Z.push(Y[aa])}}if(S.hasNodeAttribute(ab,this.CONTENT_ATTR)){Z.push(ab)}else{if(S.hasNodeCssClass(ab,this.CONTENT_CLASS)){Z.push(ab)}}Z=S.makeNodesUnique(Z);return Z},findParentContentNode:function(Z){if(!Z){return}var aa=Z;var Y=0;while(aa&&aa!==w&&aa.parentNode){if(S.hasNodeAttribute(aa,this.CONTENT_ATTR)){return aa}if(S.hasNodeCssClass(aa,this.CONTENT_CLASS)){return aa}aa=aa.parentNode;if(Y>1000){break}Y++}},findPieceNode:function(Z){var Y;Y=S.findFirstNodeHavingAttribute(Z,this.CONTENT_PIECE_ATTR);if(!Y){Y=S.findFirstNodeHavingClass(Z,this.CONTENT_PIECE_CLASS)}if(Y){return Y}return Z},findTargetNodeNoDefault:function(Y){if(!Y){return}var Z=S.findFirstNodeHavingAttributeWithValue(Y,this.CONTENT_TARGET_ATTR);
-if(Z){return Z}Z=S.findFirstNodeHavingAttribute(Y,this.CONTENT_TARGET_ATTR);if(Z){return Z}Z=S.findFirstNodeHavingClass(Y,this.CONTENT_TARGET_CLASS);if(Z){return Z}},findTargetNode:function(Y){var Z=this.findTargetNodeNoDefault(Y);if(Z){return Z}return Y},findContentName:function(Z){if(!Z){return}var ac=S.findFirstNodeHavingAttributeWithValue(Z,this.CONTENT_NAME_ATTR);if(ac){return S.getAttributeValueFromNode(ac,this.CONTENT_NAME_ATTR)}var Y=this.findContentPiece(Z);if(Y){return this.removeDomainIfIsInLink(Y)}if(S.hasNodeAttributeWithValue(Z,"title")){return S.getAttributeValueFromNode(Z,"title")}var aa=this.findPieceNode(Z);if(S.hasNodeAttributeWithValue(aa,"title")){return S.getAttributeValueFromNode(aa,"title")}var ab=this.findTargetNode(Z);if(S.hasNodeAttributeWithValue(ab,"title")){return S.getAttributeValueFromNode(ab,"title")}},findContentPiece:function(Z){if(!Z){return}var ab=S.findFirstNodeHavingAttributeWithValue(Z,this.CONTENT_PIECE_ATTR);if(ab){return S.getAttributeValueFromNode(ab,this.CONTENT_PIECE_ATTR)
-}var Y=this.findPieceNode(Z);var aa=this.findMediaUrlInNode(Y);if(aa){return this.toAbsoluteUrl(aa)}},findContentTarget:function(aa){if(!aa){return}var ab=this.findTargetNode(aa);if(S.hasNodeAttributeWithValue(ab,this.CONTENT_TARGET_ATTR)){return S.getAttributeValueFromNode(ab,this.CONTENT_TARGET_ATTR)}var Z;if(S.hasNodeAttributeWithValue(ab,"href")){Z=S.getAttributeValueFromNode(ab,"href");return this.toAbsoluteUrl(Z)}var Y=this.findPieceNode(aa);if(S.hasNodeAttributeWithValue(Y,"href")){Z=S.getAttributeValueFromNode(Y,"href");return this.toAbsoluteUrl(Z)}},isSameDomain:function(Y){if(!Y||!Y.indexOf){return false}if(0===Y.indexOf(this.getLocation().origin)){return true}var Z=Y.indexOf(this.getLocation().host);if(8>=Z&&0<=Z){return true}return false},removeDomainIfIsInLink:function(aa){var Z="^https?://[^/]+";var Y="^.*//[^/]+";if(aa&&aa.search&&-1!==aa.search(new RegExp(Z))&&this.isSameDomain(aa)){aa=aa.replace(new RegExp(Y),"");if(!aa){aa="/"}}return aa},findMediaUrlInNode:function(ac){if(!ac){return
-}var aa=["img","embed","video","audio"];var Y=ac.nodeName.toLowerCase();if(-1!==B(aa,Y)&&S.findFirstNodeHavingAttributeWithValue(ac,"src")){var ab=S.findFirstNodeHavingAttributeWithValue(ac,"src");return S.getAttributeValueFromNode(ab,"src")}if(Y==="object"&&S.hasNodeAttributeWithValue(ac,"data")){return S.getAttributeValueFromNode(ac,"data")}if(Y==="object"){var ad=S.findNodesByTagName(ac,"param");if(ad&&ad.length){var Z;for(Z=0;Z<ad.length;Z++){if("movie"===S.getAttributeValueFromNode(ad[Z],"name")&&S.hasNodeAttributeWithValue(ad[Z],"value")){return S.getAttributeValueFromNode(ad[Z],"value")}}}var ae=S.findNodesByTagName(ac,"embed");if(ae&&ae.length){return this.findMediaUrlInNode(ae[0])}}},trim:function(Y){if(Y&&String(Y)===Y){return Y.replace(/^\s+|\s+$/g,"")}return Y},isOrWasNodeInViewport:function(ad){if(!ad||!ad.getBoundingClientRect||ad.nodeType!==1){return true}var ac=ad.getBoundingClientRect();var ab=w.documentElement||{};var aa=ac.top<0;if(aa&&ad.offsetTop){aa=(ad.offsetTop+ac.height)>0
-}var Z=ab.clientWidth;if(I.innerWidth&&Z>I.innerWidth){Z=I.innerWidth}var Y=ab.clientHeight;if(I.innerHeight&&Y>I.innerHeight){Y=I.innerHeight}return((ac.bottom>0||aa)&&ac.right>0&&ac.left<Z&&((ac.top<Y)||aa))},isNodeVisible:function(Z){var Y=g(Z);var aa=this.isOrWasNodeInViewport(Z);return Y&&aa},buildInteractionRequestParams:function(Y,Z,aa,ab){var ac="";if(Y){ac+="c_i="+m(Y)}if(Z){if(ac){ac+="&"}ac+="c_n="+m(Z)}if(aa){if(ac){ac+="&"}ac+="c_p="+m(aa)}if(ab){if(ac){ac+="&"}ac+="c_t="+m(ab)}return ac},buildImpressionRequestParams:function(Y,Z,aa){var ab="c_n="+m(Y)+"&c_p="+m(Z);if(aa){ab+="&c_t="+m(aa)}return ab},buildContentBlock:function(aa){if(!aa){return}var Y=this.findContentName(aa);var Z=this.findContentPiece(aa);var ab=this.findContentTarget(aa);Y=this.trim(Y);Z=this.trim(Z);ab=this.trim(ab);return{name:Y||"Unknown",piece:Z||"Unknown",target:ab||""}},collectContent:function(ab){if(!ab||!ab.length){return[]}var aa=[];var Y,Z;for(Y=0;Y<ab.length;Y++){Z=this.buildContentBlock(ab[Y]);
-if(y(Z)){aa.push(Z)}}return aa},setLocation:function(Y){this.location=Y},getLocation:function(){var Y=this.location||I.location;if(!Y.origin){Y.origin=Y.protocol+"//"+Y.hostname+(Y.port?":"+Y.port:"")}return Y},toAbsoluteUrl:function(Z){if((!Z||String(Z)!==Z)&&Z!==""){return Z}if(""===Z){return this.getLocation().href}if(Z.search(/^\/\//)!==-1){return this.getLocation().protocol+Z}if(Z.search(/:\/\//)!==-1){return Z}if(0===Z.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+Z}if(0===Z.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+Z}if(0===Z.search("^[a-zA-Z]{2,11}:")){return Z}if(Z.search(/^\//)!==-1){return this.getLocation().origin+Z}var Y="(.*/)";var aa=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(Y))[0];return aa+Z},isUrlToCurrentDomain:function(Z){var aa=this.toAbsoluteUrl(Z);if(!aa){return false}var Y=this.getLocation().origin;if(Y===aa){return true}if(0===String(aa).indexOf(Y)){if(":"===String(aa).substr(Y.length,1)){return false
-}return true}return false},setHrefAttribute:function(Z,Y){if(!Z||!Y){return}S.setAnyAttribute(Z,"href",Y)},shouldIgnoreInteraction:function(aa){var Z=S.hasNodeAttribute(aa,this.CONTENT_IGNOREINTERACTION_ATTR);var Y=S.hasNodeCssClass(aa,this.CONTENT_IGNOREINTERACTION_CLASS);return Z||Y}};function D(Y,Z){if(Z){return Z}if(Y.slice(-9)==="piwik.php"){Y=Y.slice(0,Y.length-9)}return Y}function C(ae){var ag="Piwik_Overlay";var Z=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$");var aa=Z.exec(w.referrer);if(aa){var ac=aa[1];if(ac!==String(ae)){return false}var ad=aa[2],Y=aa[3],ab=aa[4];if(!ab){ab=""}else{if(ab.indexOf("&segment=")===0){ab=ab.substr("&segment=".length)}}I.name=ag+"###"+ad+"###"+Y+"###"+ab}var af=I.name.split("###");return af.length===4&&af[0]===ag}function O(Z,af,ab){var ae=I.name.split("###"),ad=ae[1],Y=ae[2],ac=ae[3],aa=D(Z,af);i(aa+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(aa,ab,ad,Y,ac)
-})}function F(aK,bz){var af=P(w.domain,I.location.href,z()),b0=A(af[0]),cl=j(af[1]),bH=j(af[2]),cp=false,bD="GET",bF=bD,bk="application/x-www-form-urlencoded; charset=UTF-8",aQ=bk,ac=aK||"",aA="",bB="",b7=bz||"",aP="",a8="",be,aY=w.title,a0=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],bC=[b0],ak=[],bq=[],aI=[],bA=500,al,b5,bs,am,ap,a4=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],aV=["pk_kwd","piwik_kwd","utm_term"],cj="_pk_",at,ck,aq=false,cb,a6,bb,az=33955200000,aF=1800000,bi=15768000000,a7=true,aN=0,bd=false,ai=false,aw,br={},ad={},bS={},cc=200,bT={},b8={},aj=[],aC=false,bh=false,bL=false,b9=false,bO=false,bp=null,bc,bv,av,a3=W,bK;
-function bV(cy,cv,cu,cx,ct,cw){if(aq){return}var cs;if(cu){cs=new Date();cs.setTime(cs.getTime()+cu)}w.cookie=cy+"="+m(cv)+(cu?";expires="+cs.toGMTString():"")+";path="+(cx||"/")+(ct?";domain="+ct:"")+(cw?";secure":"")}function ax(cu){if(aq){return 0}var cs=new RegExp("(^|;)[ ]*"+cu+"=([^;]*)"),ct=cs.exec(w.cookie);return ct?H(ct[2]):0}function cf(cs){var ct;if(am){ct=new RegExp("#.*");return cs.replace(ct,"")}return cs}function bZ(cu,cs){var cv=l(cs),ct;if(cv){return cs}if(cs.slice(0,1)==="/"){return l(cu)+"://"+c(cu)+cs}cu=cf(cu);ct=cu.indexOf("?");if(ct>=0){cu=cu.slice(0,ct)}ct=cu.lastIndexOf("/");if(ct!==cu.length-1){cu=cu.slice(0,ct+1)}return cu+cs}function bE(cv){var ct,cs,cu;for(ct=0;ct<bC.length;ct++){cs=A(bC[ct].toLowerCase());if(cv===cs){return true}if(cs.slice(0,1)==="."){if(cv===cs.slice(1)){return true}cu=cv.length-cs.length;if((cu>0)&&(cv.slice(cu)===cs)){return true}}}return false}function cr(cs,cu){var ct=new Image(1,1);ct.onload=function(){v=0;if(typeof cu==="function"){cu()
-}};ct.src=ac+(ac.indexOf("?")<0?"?":"&")+cs}function bW(ct,cw,cs){if(!y(cs)||null===cs){cs=true}try{var cv=I.XMLHttpRequest?new I.XMLHttpRequest():I.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;cv.open("POST",ac,true);cv.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)&&cs){cr(ct,cw)}else{if(typeof cw==="function"){cw()}}};cv.setRequestHeader("Content-Type",aQ);cv.send(ct)}catch(cu){if(cs){cr(ct,cw)}}}function ce(ct){var cs=new Date();var cu=cs.getTime()+ct;if(!k||cu>k){k=cu}}function aD(cs){if(bc||!b5){return}bc=setTimeout(function ct(){bc=null;if(bs()){return}var cu=new Date(),cv=b5-(cu.getTime()-bp);cv=Math.min(b5,cv);aD(cv)},cs||b5)}function bf(){if(!bc){return}clearTimeout(bc);bc=null}function ay(){if(bs()){return}aD()}function bn(){bf()}function bG(){if(bO||!b5){return}bO=true;X(I,"focus",ay);X(I,"blur",bn);aD()}function aJ(cw){var ct=new Date();var cs=ct.getTime();bp=cs;if(bh&&cs<bh){var cu=bh-cs;setTimeout(cw,cu);ce(cu+50);bh+=50;
-return}if(bh===false){var cv=800;bh=cs+cv}cw()}function a5(ct,cs,cu){if(!cb&&ct){aJ(function(){if(bF==="POST"){bW(ct,cu)}else{cr(ct,cu)}ce(cs)})}if(!bO){bG()}else{aD()}}function bj(cs){if(cb){return false}return(cs&&cs.length)}function ar(cu,cs){if(!bj(cu)){return}var ct='{"requests":["?'+cu.join('","?')+'"]}';aJ(function(){bW(ct,null,false);ce(cs)})}function bU(cs){return cj+cs+"."+b7+"."+bK}function ag(){if(aq){return"0"}if(!y(e.cookieEnabled)){var cs=bU("testcookie");bV(cs,"1");return ax(cs)==="1"?"1":"0"}return e.cookieEnabled?"1":"0"}function bw(){bK=a3((at||b0)+(ck||"/")).slice(0,4)}function au(){var ct=bU("cvar"),cs=ax(ct);if(cs.length){cs=JSON2.parse(cs);if(L(cs)){return cs}}return{}}function ab(){if(ai===false){ai=au()}}function ch(){return a3((e.userAgent||"")+(e.platform||"")+JSON2.stringify(b8)+(new Date()).getTime()+Math.random()).slice(0,16)}function aa(){var cu=new Date(),cs=Math.round(cu.getTime()/1000),ct=bU("id"),cx=ax(ct),cw,cv;if(cx){cw=cx.split(".");cw.unshift("0");
-if(a8.length){cw[1]=a8}return cw}if(a8.length){cv=a8}else{if("0"===ag()){cv=""}else{cv=ch()}}cw=["1",cv,cs,0,cs,"",""];return cw}function bN(){var cz=aa(),cv=cz[0],cw=cz[1],ct=cz[2],cs=cz[3],cx=cz[4],cu=cz[5];if(!y(cz[6])){cz[6]=""}var cy=cz[6];return{newVisitor:cv,uuid:cw,createTs:ct,visitCount:cs,currentVisitTs:cx,lastVisitTs:cu,lastEcommerceOrderTs:cy}}function aR(){var cv=new Date(),ct=cv.getTime(),cw=bN().createTs;var cs=parseInt(cw,10);var cu=(cs*1000)+az-ct;return cu}function ao(cs){if(!b7){return}var cu=new Date(),ct=Math.round(cu.getTime()/1000);if(!y(cs)){cs=bN()}var cv=cs.uuid+"."+cs.createTs+"."+cs.visitCount+"."+ct+"."+cs.lastVisitTs+"."+cs.lastEcommerceOrderTs;bV(bU("id"),cv,aR(),ck,at)}function Z(){var cs=ax(bU("ref"));if(cs.length){try{cs=JSON2.parse(cs);if(L(cs)){return cs}}catch(ct){}}return["","",0,""]}function b6(cu,ct,cs){bV(cu,"",-86400,ct,cs)}function bo(ct){var cs="testvalue";bV("test",cs,10000,null,ct);if(ax("test")===cs){b6("test",null,ct);return true}return false
-}function Y(){var cu=aq;aq=false;var cs=["id","ses","cvar","ref"];var ct,cv;for(ct=0;ct<cs.length;ct++){cv=bU(cs[ct]);if(0!==ax(cv)){b6(cv,ck,at)}}aq=cu}function co(cs){b7=cs;ao()}function b4(cw){if(!cw||!L(cw)){return}var cv=[];var cu;for(cu in cw){if(Object.prototype.hasOwnProperty.call(cw,cu)){cv.push(cu)}}var cx={};cv.sort();var cs=cv.length;var ct;for(ct=0;ct<cs;ct++){cx[cv[ct]]=cw[cv[ct]]}return cx}function ba(){bV(bU("ses"),"*",aF,ck,at)}function aZ(cu,cP,cQ,cv){var cO,ct=new Date(),cC=Math.round(ct.getTime()/1000),cz,cN,cw=1024,cV,cD,cL=ai,cx=bU("ses"),cJ=bU("ref"),cG=bU("cvar"),cH=ax(cx),cM=Z(),cS=be||cl,cA,cs;if(aq){Y()}if(cb){return""}var cI=bN();if(!y(cv)){cv=""}var cF=w.characterSet||w.charset;if(!cF||cF.toLowerCase()==="utf-8"){cF=null}cA=cM[0];cs=cM[1];cz=cM[2];cN=cM[3];if(!cH){var cR=aF/1000;if(!cI.lastVisitTs||(cC-cI.lastVisitTs)>cR){cI.visitCount++;cI.lastVisitTs=cI.currentVisitTs}if(!bb||!cA.length){for(cO in a4){if(Object.prototype.hasOwnProperty.call(a4,cO)){cA=K(cS,a4[cO]);
-if(cA.length){break}}}for(cO in aV){if(Object.prototype.hasOwnProperty.call(aV,cO)){cs=K(cS,aV[cO]);if(cs.length){break}}}}cV=c(bH);cD=cN.length?c(cN):"";if(cV.length&&!bE(cV)&&(!bb||!cD.length||bE(cD))){cN=bH}if(cN.length||cA.length){cz=cC;cM=[cA,cs,cz,cf(cN.slice(0,cw))];bV(cJ,JSON2.stringify(cM),bi,ck,at)}}cu+="&idsite="+b7+"&rec=1&r="+String(Math.random()).slice(2,8)+"&h="+ct.getHours()+"&m="+ct.getMinutes()+"&s="+ct.getSeconds()+"&url="+m(cf(cS))+(bH.length?"&urlref="+m(cf(bH)):"")+((aP&&aP.length)?"&uid="+m(aP):"")+"&_id="+cI.uuid+"&_idts="+cI.createTs+"&_idvc="+cI.visitCount+"&_idn="+cI.newVisitor+(cA.length?"&_rcn="+m(cA):"")+(cs.length?"&_rck="+m(cs):"")+"&_refts="+cz+"&_viewts="+cI.lastVisitTs+(String(cI.lastEcommerceOrderTs).length?"&_ects="+cI.lastEcommerceOrderTs:"")+(String(cN).length?"&_ref="+m(cf(cN.slice(0,cw))):"")+(cF?"&cs="+m(cF):"")+"&send_image=0";for(cO in b8){if(Object.prototype.hasOwnProperty.call(b8,cO)){cu+="&"+cO+"="+b8[cO]}}var cU=[];if(cP){for(cO in cP){if(Object.prototype.hasOwnProperty.call(cP,cO)&&/^dimension\d+$/.test(cO)){var cy=cO.replace("dimension","");
-cU.push(parseInt(cy,10));cU.push(String(cy));cu+="&"+cO+"="+cP[cO];delete cP[cO]}}}if(cP&&s(cP)){cP=null}for(cO in bS){if(Object.prototype.hasOwnProperty.call(bS,cO)){var cE=(-1===cU.indexOf(cO));if(cE){cu+="&dimension"+cO+"="+bS[cO]}}}if(cP){cu+="&data="+m(JSON2.stringify(cP))}else{if(ap){cu+="&data="+m(JSON2.stringify(ap))}}function cB(cW,cX){var cY=JSON2.stringify(cW);if(cY.length>2){return"&"+cX+"="+m(cY)}return""}var cT=b4(br);var cK=b4(ad);cu+=cB(cT,"cvar");cu+=cB(cK,"e_cvar");if(ai){cu+=cB(ai,"_cvar");for(cO in cL){if(Object.prototype.hasOwnProperty.call(cL,cO)){if(ai[cO][0]===""||ai[cO][1]===""){delete ai[cO]}}}if(bd){bV(cG,JSON2.stringify(ai),aF,ck,at)}}if(a7){if(aN){cu+="&gt_ms="+aN}else{if(f&&f.timing&&f.timing.requestStart&&f.timing.responseEnd){cu+="&gt_ms="+(f.timing.responseEnd-f.timing.requestStart)}}}cI.lastEcommerceOrderTs=y(cv)&&String(cv).length?cv:cI.lastEcommerceOrderTs;ao(cI);ba();cu+=Q(cQ);if(bB.length){cu+="&"+bB}if(r(aw)){cu=aw(cu)}return cu}bs=function bx(){var cs=new Date();
-if(bp+b5<=cs.getTime()){var ct=aZ("ping=1",null,"ping");a5(ct,bA);return true}return false};function bY(cv,cu,cz,cw,cs,cC){var cx="idgoal=0",cy,ct=new Date(),cA=[],cB;if(String(cv).length){cx+="&ec_id="+m(cv);cy=Math.round(ct.getTime()/1000)}cx+="&revenue="+cu;if(String(cz).length){cx+="&ec_st="+cz}if(String(cw).length){cx+="&ec_tx="+cw}if(String(cs).length){cx+="&ec_sh="+cs}if(String(cC).length){cx+="&ec_dt="+cC}if(bT){for(cB in bT){if(Object.prototype.hasOwnProperty.call(bT,cB)){if(!y(bT[cB][1])){bT[cB][1]=""}if(!y(bT[cB][2])){bT[cB][2]=""}if(!y(bT[cB][3])||String(bT[cB][3]).length===0){bT[cB][3]=0}if(!y(bT[cB][4])||String(bT[cB][4]).length===0){bT[cB][4]=1}cA.push(bT[cB])}}cx+="&ec_items="+m(JSON2.stringify(cA))}cx=aZ(cx,ap,"ecommerce",cy);a5(cx,bA)}function bX(cs,cw,cv,cu,ct,cx){if(String(cs).length&&y(cw)){bY(cs,cw,cv,cu,ct,cx)}}function ci(cs){if(y(cs)){bY("",cs,"","","","")}}function bm(cu,cv){var cs=new Date(),ct=aZ("action_name="+m(V(cu||aY)),cv,"log");a5(ct,bA)}function aM(cu,ct){var cv,cs="(^| )(piwik[_-]"+ct;
-if(cu){for(cv=0;cv<cu.length;cv++){cs+="|"+cu[cv]}}cs+=")( |$)";return new RegExp(cs)}function bQ(cs){return(ac&&cs&&0===String(cs).indexOf(ac))}function b3(cw,cs,cx,ct){if(bQ(cs)){return 0}var cv=aM(bq,"download"),cu=aM(aI,"link"),cy=new RegExp("\\.("+a0.join("|")+")([?&#]|$)","i");if(cu.test(cw)){return"link"}if(ct||cv.test(cw)||cy.test(cs)){return"download"}if(cx){return 0}return"link"}function bg(ct){var cs;cs=ct.parentNode;while(cs!==null&&y(cs)){if(S.isLinkElement(ct)){break}ct=cs;cs=ct.parentNode}return ct}function bu(cw){cw=bg(cw);if(!S.hasNodeAttribute(cw,"href")){return}if(!y(cw.href)){return}var cv=S.getAttributeValueFromNode(cw,"href");if(bQ(cv)){return}var cx=cw.hostname||c(cw.href);var cy=cx.toLowerCase();var ct=cw.href.replace(cx,cy);var cu=new RegExp("^(javascript|vbscript|jscript|mocha|livescript|ecmascript|mailto):","i");if(!cu.test(ct)){var cs=b3(cw.className,ct,bE(cy),S.hasNodeAttribute(cw,"download"));if(cs){return{type:cs,href:ct}}}}function cn(cs,ct,cu,cv){var cw=n.buildInteractionRequestParams(cs,ct,cu,cv);
-if(!cw){return}return aZ(cw,null,"contentInteraction")}function cm(cu,cv,cz,cs,ct){if(!y(cu)){return}if(bQ(cu)){return cu}var cx=n.toAbsoluteUrl(cu);var cw="redirecturl="+m(cx)+"&";cw+=cn(cv,cz,cs,(ct||cu));var cy="&";if(ac.indexOf("?")<0){cy="?"}return ac+cy+cw}function a9(cs,ct){if(!cs||!ct){return false}var cu=n.findTargetNode(cs);if(n.shouldIgnoreInteraction(cu)){return false}cu=n.findTargetNodeNoDefault(cs);if(cu&&!J(cu,ct)){return false}return true}function aX(cu,ct,cw){if(!cu){return}var cs=n.findParentContentNode(cu);if(!cs){return}if(!a9(cs,cu)){return}var cv=n.buildContentBlock(cs);if(!cv){return}if(!cv.target&&cw){cv.target=cw}return n.buildInteractionRequestParams(ct,cv.name,cv.piece,cv.target)}function aU(ct){if(!aj||!aj.length){return false}var cs,cu;for(cs=0;cs<aj.length;cs++){cu=aj[cs];if(cu&&cu.name===ct.name&&cu.piece===ct.piece&&cu.target===ct.target){return true}}return false}function ae(cv){if(!cv){return false}var cy=n.findTargetNode(cv);if(!cy||n.shouldIgnoreInteraction(cy)){return false
-}var cz=bu(cy);if(b9&&cz&&cz.type){return false}if(S.isLinkElement(cy)&&S.hasNodeAttributeWithValue(cy,"href")){var cs=String(S.getAttributeValueFromNode(cy,"href"));if(0===cs.indexOf("#")){return false}if(bQ(cs)){return true}if(!n.isUrlToCurrentDomain(cs)){return false}var cw=n.buildContentBlock(cv);if(!cw){return}var cu=cw.name;var cA=cw.piece;var cx=cw.target;if(!S.hasNodeAttributeWithValue(cy,n.CONTENT_TARGET_ATTR)||cy.wasContentTargetAttrReplaced){cy.wasContentTargetAttrReplaced=true;cx=n.toAbsoluteUrl(cs);S.setAnyAttribute(cy,n.CONTENT_TARGET_ATTR,cx)}var ct=cm(cs,"click",cu,cA,cx);n.setHrefAttribute(cy,ct);return true}return false}function ah(ct){if(!ct||!ct.length){return}var cs;for(cs=0;cs<ct.length;cs++){ae(ct[cs])}}function bt(cs){return function(ct){if(!cs){return}var cw=n.findParentContentNode(cs);var cx;if(ct){cx=ct.target||ct.srcElement}if(!cx){cx=cs}if(!a9(cw,cx)){return}ce(bA);if(S.isLinkElement(cs)&&S.hasNodeAttributeWithValue(cs,"href")&&S.hasNodeAttributeWithValue(cs,n.CONTENT_TARGET_ATTR)){var cu=S.getAttributeValueFromNode(cs,"href");
-if(!bQ(cu)&&cs.wasContentTargetAttrReplaced){S.setAnyAttribute(cs,n.CONTENT_TARGET_ATTR,"")}}var cB=bu(cs);if(bL&&cB&&cB.type){return cB.type}if(ae(cw)){return"href"}var cy=n.buildContentBlock(cw);if(!cy){return}var cv=cy.name;var cC=cy.piece;var cA=cy.target;var cz=cn("click",cv,cC,cA);a5(cz,bA);return cz}}function aL(cu){if(!cu||!cu.length){return}var cs,ct;for(cs=0;cs<cu.length;cs++){ct=n.findTargetNode(cu[cs]);if(ct&&!ct.contentInteractionTrackingSetupDone){ct.contentInteractionTrackingSetupDone=true;X(ct,"click",bt(ct))}}}function aH(cu,cv){if(!cu||!cu.length){return[]}var cs,ct;for(cs=0;cs<cu.length;cs++){if(aU(cu[cs])){cu.splice(cs,1);cs--}else{aj.push(cu[cs])}}if(!cu||!cu.length){return[]}ah(cv);aL(cv);var cw=[];for(cs=0;cs<cu.length;cs++){ct=aZ(n.buildImpressionRequestParams(cu[cs].name,cu[cs].piece,cu[cs].target),undefined,"contentImpressions");cw.push(ct)}return cw}function a2(ct){var cs=n.collectContent(ct);return aH(cs,ct)}function bP(ct){if(!ct||!ct.length){return[]}var cs;
-for(cs=0;cs<ct.length;cs++){if(!n.isNodeVisible(ct[cs])){ct.splice(cs,1);cs--}}if(!ct||!ct.length){return[]}return a2(ct)}function b1(cu,cs,ct){var cv=n.buildImpressionRequestParams(cu,cs,ct);return aZ(cv,null,"contentImpression")}function a1(cv,ct){if(!cv){return}var cs=n.findParentContentNode(cv);var cu=n.buildContentBlock(cs);if(!cu){return}if(!ct){ct="Unknown"}return cn(ct,cu.name,cu.piece,cu.target)}function bJ(ct,cv,cs,cu){return"e_c="+m(ct)+"&e_a="+m(cv)+(y(cs)?"&e_n="+m(cs):"")+(y(cu)?"&e_v="+m(cu):"")}function an(cu,cw,cs,cv,cx){if(String(cu).length===0||String(cw).length===0){return false}var ct=aZ(bJ(cu,cw,cs,cv),cx,"event");a5(ct,bA)}function aT(cs,cv,ct,cw){var cu=aZ("search="+m(cs)+(cv?"&search_cat="+m(cv):"")+(y(ct)?"&search_count="+ct:""),cw,"sitesearch");a5(cu,bA)}function by(cs,cv,cu){var ct=aZ("idgoal="+cs+(cv?"&revenue="+cv:""),cu,"goal");a5(ct,bA)}function b2(cv,cs,cz,cy,cu){var cx=cs+"="+m(cf(cv));var ct=aX(cu,"click",cv);if(ct){cx+="&"+ct}var cw=aZ(cx,cz,"link");a5(cw,(cy?0:bA),cy)
-}function ca(ct,cs){if(ct!==""){return ct+cs.charAt(0).toUpperCase()+cs.slice(1)}return cs}function aS(cx){var cw,cs,cv=["","webkit","ms","moz"],cu;if(!a6){for(cs=0;cs<cv.length;cs++){cu=cv[cs];if(Object.prototype.hasOwnProperty.call(w,ca(cu,"hidden"))){if(w[ca(cu,"visibilityState")]==="prerender"){cw=true}break}}}if(cw){X(w,cu+"visibilitychange",function ct(){w.removeEventListener(cu+"visibilitychange",ct,false);cx()});return}cx()}function aW(cs){if(w.readyState==="complete"){cs()}else{if(I.addEventListener){I.addEventListener("load",cs)}else{if(I.attachEvent){I.attachEvent("onLoad",cs)}}}}function aG(ct){var cs=false;if(w.attachEvent){cs=w.readyState==="complete"}else{cs=w.readyState!=="loading"}if(cs){ct()}else{if(w.addEventListener){w.addEventListener("DOMContentLoaded",ct)}else{if(w.attachEvent){w.attachEvent("onreadystatechange",ct)}}}}function bR(cs){var ct=bu(cs);if(ct&&ct.type){ct.href=j(ct.href);b2(ct.href,ct.type,undefined,null,cs)}}function aO(){return w.all&&!w.addEventListener
-}function aE(cs){var cu=cs.which;var ct=(typeof cs.button);if(!cu&&ct!=="undefined"){if(aO()){if(cs.button&1){cu=1}else{if(cs.button&2){cu=3}else{if(cs.button&4){cu=2}}}}else{if(cs.button===0||cs.button==="0"){cu=1}else{if(cs.button&1){cu=2}else{if(cs.button&2){cu=3}}}}}return cu}function aB(cs){switch(aE(cs)){case 1:return"left";case 2:return"middle";case 3:return"right"}}function cd(cs){return cs.target||cs.srcElement}function cq(cs){return function(cv){cv=cv||I.event;var cu=aB(cv);var cw=cd(cv);if(cv.type==="click"){var ct=false;if(cs&&cu==="middle"){ct=true}if(cw&&!ct){bR(cw)}}else{if(cv.type==="mousedown"){if(cu==="middle"&&cw){bv=cu;av=cw}else{bv=av=null}}else{if(cv.type==="mouseup"){if(cu===bv&&cw===av){bR(cw)}bv=av=null}else{if(cv.type==="contextmenu"){bR(cw)}}}}}}function bM(ct,cs){X(ct,"click",cq(cs),false);if(cs){X(ct,"mouseup",cq(cs),false);X(ct,"mousedown",cq(cs),false);X(ct,"contextmenu",cq(cs),false)}}function bl(ct){if(!bL){bL=true;var cu,cs=aM(ak,"ignore"),cv=w.links;if(cv){for(cu=0;
-cu<cv.length;cu++){if(!cs.test(cv[cu].className)){bM(cv[cu],ct)}}}}}function bI(cu,cw,cx){if(aC){return true}aC=true;var cy=false;var cv,ct;function cs(){cy=true}aW(function(){function cz(cB){setTimeout(function(){if(!aC){return}cy=false;cx.trackVisibleContentImpressions();cz(cB)},cB)}function cA(cB){setTimeout(function(){if(!aC){return}if(cy){cy=false;cx.trackVisibleContentImpressions()}cA(cB)},cB)}if(cu){cv=["scroll","resize"];for(ct=0;ct<cv.length;ct++){if(w.addEventListener){w.addEventListener(cv[ct],cs)}else{I.attachEvent("on"+cv[ct],cs)}}cA(100)}if(cw&&cw>0){cw=parseInt(cw,10);cz(cw)}})}function cg(){var ct,cu,cv={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",dir:"application/x-director",fla:"application/x-shockwave-flash",java:"application/x-java-vm",gears:"application/x-googlegears",ag:"application/x-silverlight"},cs=I.devicePixelRatio||1;if(!((new RegExp("MSIE")).test(e.userAgent))){if(e.mimeTypes&&e.mimeTypes.length){for(ct in cv){if(Object.prototype.hasOwnProperty.call(cv,ct)){cu=e.mimeTypes[cv[ct]];
-b8[ct]=(cu&&cu.enabledPlugin)?"1":"0"}}}if(typeof navigator.javaEnabled!=="unknown"&&y(e.javaEnabled)&&e.javaEnabled()){b8.java="1"}if(r(I.GearsFactory)){b8.gears="1"}b8.cookie=ag()}b8.res=M.width*cs+"x"+M.height*cs}cg();bw();ao();return{getVisitorId:function(){return bN().uuid},getVisitorInfo:function(){return aa()},getAttributionInfo:function(){return Z()},getAttributionCampaignName:function(){return Z()[0]},getAttributionCampaignKeyword:function(){return Z()[1]},getAttributionReferrerTimestamp:function(){return Z()[2]},getAttributionReferrerUrl:function(){return Z()[3]},setTrackerUrl:function(cs){ac=cs},getTrackerUrl:function(){return ac},getSiteId:function(){return b7},setSiteId:function(cs){co(cs)},setUserId:function(cs){if(!y(cs)||!cs.length){return}aP=cs;a8=a3(aP).substr(0,16)},getUserId:function(){return aP},setCustomData:function(cs,ct){if(L(cs)){ap=cs}else{if(!ap){ap={}}ap[cs]=ct}},getCustomData:function(){return ap},setCustomRequestProcessing:function(cs){aw=cs},appendToTrackingUrl:function(cs){bB=cs
-},getRequest:function(cs){return aZ(cs)},addPlugin:function(cs,ct){a[cs]=ct},setCustomDimension:function(cs,ct){cs=parseInt(cs,10);if(cs>0){if(!y(ct)){ct=""}if(!o(ct)){ct=String(ct)}bS[cs]=ct}},getCustomDimension:function(cs){cs=parseInt(cs,10);if(cs>0&&Object.prototype.hasOwnProperty.call(bS,cs)){return bS[cs]}},deleteCustomDimension:function(cs){cs=parseInt(cs,10);if(cs>0){delete bS[cs]}},setCustomVariable:function(ct,cs,cw,cu){var cv;if(!y(cu)){cu="visit"}if(!y(cs)){return}if(!y(cw)){cw=""}if(ct>0){cs=!o(cs)?String(cs):cs;cw=!o(cw)?String(cw):cw;cv=[cs.slice(0,cc),cw.slice(0,cc)];if(cu==="visit"||cu===2){ab();ai[ct]=cv}else{if(cu==="page"||cu===3){br[ct]=cv}else{if(cu==="event"){ad[ct]=cv}}}}},getCustomVariable:function(ct,cu){var cs;if(!y(cu)){cu="visit"}if(cu==="page"||cu===3){cs=br[ct]}else{if(cu==="event"){cs=ad[ct]}else{if(cu==="visit"||cu===2){ab();cs=ai[ct]}}}if(!y(cs)||(cs&&cs[0]==="")){return false}return cs},deleteCustomVariable:function(cs,ct){if(this.getCustomVariable(cs,ct)){this.setCustomVariable(cs,"","",ct)
-}},storeCustomVariablesInCookie:function(){bd=true},setLinkTrackingTimer:function(cs){bA=cs},setDownloadExtensions:function(cs){if(o(cs)){cs=cs.split("|")}a0=cs},addDownloadExtensions:function(ct){var cs;if(o(ct)){ct=ct.split("|")}for(cs=0;cs<ct.length;cs++){a0.push(ct[cs])}},removeDownloadExtensions:function(cu){var ct,cs=[];if(o(cu)){cu=cu.split("|")}for(ct=0;ct<a0.length;ct++){if(B(cu,a0[ct])===-1){cs.push(a0[ct])}}a0=cs},setDomains:function(cs){bC=o(cs)?[cs]:cs;bC.push(b0)},setIgnoreClasses:function(cs){ak=o(cs)?[cs]:cs},setRequestMethod:function(cs){bF=cs||bD},setRequestContentType:function(cs){aQ=cs||bk},setReferrerUrl:function(cs){bH=cs},setCustomUrl:function(cs){be=bZ(cl,cs)},setDocumentTitle:function(cs){aY=cs},setAPIUrl:function(cs){aA=cs},setDownloadClasses:function(cs){bq=o(cs)?[cs]:cs},setLinkClasses:function(cs){aI=o(cs)?[cs]:cs},setCampaignNameKey:function(cs){a4=o(cs)?[cs]:cs},setCampaignKeywordKey:function(cs){aV=o(cs)?[cs]:cs},discardHashTag:function(cs){am=cs},setCookieNamePrefix:function(cs){cj=cs;
-ai=au()},setCookieDomain:function(cs){var ct=A(cs);if(bo(ct)){at=ct;bw()}},setCookiePath:function(cs){ck=cs;bw()},setVisitorCookieTimeout:function(cs){az=cs*1000},setSessionCookieTimeout:function(cs){aF=cs*1000},setReferralCookieTimeout:function(cs){bi=cs*1000},setConversionAttributionFirstReferrer:function(cs){bb=cs},disableCookies:function(){aq=true;b8.cookie="0";if(b7){Y()}},deleteCookies:function(){Y()},setDoNotTrack:function(ct){var cs=e.doNotTrack||e.msDoNotTrack;cb=ct&&(cs==="yes"||cs==="1");if(cb){this.disableCookies()}},addListener:function(ct,cs){bM(ct,cs)},enableLinkTracking:function(cs){b9=true;if(q){bl(cs)}else{G.push(function(){bl(cs)})}},enableJSErrorTracking:function(){if(cp){return}cp=true;var cs=I.onerror;I.onerror=function(cx,cv,cu,cw,ct){aS(function(){var cy="JavaScript Errors";var cz=cv+":"+cu;if(cw){cz+=":"+cw}an(cy,cz,cx)});if(cs){return cs(cx,cv,cu,cw,ct)}return false}},disablePerformanceTracking:function(){a7=false},setGenerationTimeMs:function(cs){aN=parseInt(cs,10)
-},enableHeartBeatTimer:function(cs){cs=Math.max(cs,1);b5=(cs||15)*1000;if(bp!==null){bG()}},killFrame:function(){if(I.location!==I.top.location){I.top.location=I.location}},redirectFile:function(cs){if(I.location.protocol==="file:"){I.location=cs}},setCountPreRendered:function(cs){a6=cs},trackGoal:function(cs,cu,ct){aS(function(){by(cs,cu,ct)})},trackLink:function(ct,cs,cv,cu){aS(function(){b2(ct,cs,cv,cu)})},trackPageView:function(cs,ct){aj=[];if(C(b7)){aS(function(){O(ac,aA,b7)})}else{aS(function(){bm(cs,ct)})}},trackAllContentImpressions:function(){if(C(b7)){return}aS(function(){aG(function(){var cs=n.findContentNodes();var ct=a2(cs);ar(ct,bA)})})},trackVisibleContentImpressions:function(cs,ct){if(C(b7)){return}if(!y(cs)){cs=true}if(!y(ct)){ct=750}bI(cs,ct,this);aS(function(){aW(function(){var cu=n.findContentNodes();var cv=bP(cu);ar(cv,bA)})})},trackContentImpression:function(cu,cs,ct){if(C(b7)){return}if(!cu){return}cs=cs||"Unknown";aS(function(){var cv=b1(cu,cs,ct);a5(cv,bA)})},trackContentImpressionsWithinNode:function(cs){if(C(b7)||!cs){return
-}aS(function(){if(aC){aW(function(){var ct=n.findContentNodesWithinNode(cs);var cu=bP(ct);ar(cu,bA)})}else{aG(function(){var ct=n.findContentNodesWithinNode(cs);var cu=a2(ct);ar(cu,bA)})}})},trackContentInteraction:function(cu,cv,cs,ct){if(C(b7)){return}if(!cu||!cv){return}cs=cs||"Unknown";aS(function(){var cw=cn(cu,cv,cs,ct);a5(cw,bA)})},trackContentInteractionNode:function(ct,cs){if(C(b7)||!ct){return}aS(function(){var cu=a1(ct,cs);a5(cu,bA)})},logAllContentBlocksOnPage:function(){var ct=n.findContentNodes();var cs=n.collectContent(ct);if(console!==undefined&&console&&console.log){console.log(cs)}},trackEvent:function(ct,cv,cs,cu,cw){aS(function(){an(ct,cv,cs,cu,cw)})},trackSiteSearch:function(cs,cu,ct,cv){aS(function(){aT(cs,cu,ct,cv)})},setEcommerceView:function(cv,cs,cu,ct){if(!y(cu)||!cu.length){cu=""}else{if(cu instanceof Array){cu=JSON2.stringify(cu)}}br[5]=["_pkc",cu];if(y(ct)&&String(ct).length){br[2]=["_pkp",ct]}if((!y(cv)||!cv.length)&&(!y(cs)||!cs.length)){return}if(y(cv)&&cv.length){br[3]=["_pks",cv]
-}if(!y(cs)||!cs.length){cs=""}br[4]=["_pkn",cs]},addEcommerceItem:function(cw,cs,cu,ct,cv){if(cw.length){bT[cw]=[cw,cs,cu,ct,cv]}},trackEcommerceOrder:function(cs,cw,cv,cu,ct,cx){bX(cs,cw,cv,cu,ct,cx)},trackEcommerceCartUpdate:function(cs){ci(cs)}}}function x(){return{push:T}}function b(ad,ac){var ae={};var aa,ab;for(aa=0;aa<ac.length;aa++){var Y=ac[aa];ae[Y]=1;for(ab=0;ab<ad.length;ab++){if(ad[ab]&&ad[ab][0]){var Z=ad[ab][0];if(Y===Z){T(ad[ab]);delete ad[ab];if(ae[Z]>1){if(console!==undefined&&console&&console.error){console.error("The method "+Z+' is registered more than once in "paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}}ae[Z]++}}}}return ad}X(I,"beforeunload",U,false);p();Date.prototype.getTimeAlias=Date.prototype.getTime;N=new F();var t=["disableCookies","setTrackerUrl","setAPIUrl","setCookiePath","setCookieDomain","setUserId","setSiteId","enableLinkTracking"];
-_paq=b(_paq,t);for(v=0;v<_paq.length;v++){if(_paq[v]){T(_paq[v])}}_paq=new x();d={addPlugin:function(Y,Z){a[Y]=Z},getTracker:function(Y,Z){if(!y(Z)){Z=this.getAsyncTracker().getSiteId()}if(!y(Y)){Y=this.getAsyncTracker().getTrackerUrl()}return new F(Y,Z)},getAsyncTracker:function(){return N}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return d})}return d}())}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);
-e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}};
+}function A(Z){var Y=Z.length;if(Z.charAt(--Y)==="."){Z=Z.slice(0,Y)}if(Z.slice(0,2)==="*."){Z=Z.slice(1)}if(Z.indexOf("/")!==-1){Z=Z.substr(0,Z.indexOf("/"))}return Z}function V(Z){Z=Z&&Z.text?Z.text:Z;if(!o(Z)){var Y=w.getElementsByTagName("title");if(Y&&y(Y[0])){Z=Y[0].text}}return Z}function E(Y){if(!Y){return[]}if(!y(Y.children)&&y(Y.childNodes)){return Y.children}if(y(Y.children)){return Y.children}return[]}function J(Z,Y){if(!Z||!Y){return false}if(Z.contains){return Z.contains(Y)}if(Z===Y){return true}if(Z.compareDocumentPosition){return !!(Z.compareDocumentPosition(Y)&16)}return false}function B(aa,ab){if(aa&&aa.indexOf){return aa.indexOf(ab)}if(!y(aa)||aa===null){return -1}if(!aa.length){return -1}var Y=aa.length;if(Y===0){return -1}var Z=0;while(Z<Y){if(aa[Z]===ab){return Z}Z++}return -1}function g(aa){if(!aa){return false}function Y(ac,ad){if(I.getComputedStyle){return w.defaultView.getComputedStyle(ac,null)[ad]}if(ac.currentStyle){return ac.currentStyle[ad]}}function ab(ac){ac=ac.parentNode;
+while(ac){if(ac===w){return true}ac=ac.parentNode}return false}function Z(ae,ak,ac,ah,af,ai,ag){var ad=ae.parentNode,aj=1;if(!ab(ae)){return false}if(9===ad.nodeType){return true}if("0"===Y(ae,"opacity")||"none"===Y(ae,"display")||"hidden"===Y(ae,"visibility")){return false}if(!y(ak)||!y(ac)||!y(ah)||!y(af)||!y(ai)||!y(ag)){ak=ae.offsetTop;af=ae.offsetLeft;ah=ak+ae.offsetHeight;ac=af+ae.offsetWidth;ai=ae.offsetWidth;ag=ae.offsetHeight}if(aa===ae&&(0===ag||0===ai)&&"hidden"===Y(ae,"overflow")){return false}if(ad){if(("hidden"===Y(ad,"overflow")||"scroll"===Y(ad,"overflow"))){if(af+aj>ad.offsetWidth+ad.scrollLeft||af+ai-aj<ad.scrollLeft||ak+aj>ad.offsetHeight+ad.scrollTop||ak+ag-aj<ad.scrollTop){return false}}if(ae.offsetParent===ad){af+=ad.offsetLeft;ak+=ad.offsetTop}return Z(ad,ak,ac,ah,af,ai,ag)}return true}return Z(aa)}var S={htmlCollectionToArray:function(aa){var Y=[],Z;if(!aa||!aa.length){return Y}for(Z=0;Z<aa.length;Z++){Y.push(aa[Z])}return Y},find:function(Y){if(!document.querySelectorAll||!Y){return[]
+}var Z=document.querySelectorAll(Y);return this.htmlCollectionToArray(Z)},findMultiple:function(aa){if(!aa||!aa.length){return[]}var Z,ab;var Y=[];for(Z=0;Z<aa.length;Z++){ab=this.find(aa[Z]);Y=Y.concat(ab)}Y=this.makeNodesUnique(Y);return Y},findNodesByTagName:function(Z,Y){if(!Z||!Y||!Z.getElementsByTagName){return[]}var aa=Z.getElementsByTagName(Y);return this.htmlCollectionToArray(aa)},makeNodesUnique:function(Y){var ad=[].concat(Y);Y.sort(function(af,ae){if(af===ae){return 0}var ah=B(ad,af);var ag=B(ad,ae);if(ah===ag){return 0}return ah>ag?-1:1});if(Y.length<=1){return Y}var Z=0;var ab=0;var ac=[];var aa;aa=Y[Z++];while(aa){if(aa===Y[Z]){ab=ac.push(Z)}aa=Y[Z++]||null}while(ab--){Y.splice(ac[ab],1)}return Y},getAttributeValueFromNode:function(ac,aa){if(!this.hasNodeAttribute(ac,aa)){return}if(ac&&ac.getAttribute){return ac.getAttribute(aa)}if(!ac||!ac.attributes){return}var ab=(typeof ac.attributes[aa]);if("undefined"===ab){return}if(ac.attributes[aa].value){return ac.attributes[aa].value
+}if(ac.attributes[aa].nodeValue){return ac.attributes[aa].nodeValue}var Z;var Y=ac.attributes;if(!Y){return}for(Z=0;Z<Y.length;Z++){if(Y[Z].nodeName===aa){return Y[Z].nodeValue}}return null},hasNodeAttributeWithValue:function(Z,Y){var aa=this.getAttributeValueFromNode(Z,Y);return !!aa},hasNodeAttribute:function(aa,Y){if(aa&&aa.hasAttribute){return aa.hasAttribute(Y)}if(aa&&aa.attributes){var Z=(typeof aa.attributes[Y]);return"undefined"!==Z}return false},hasNodeCssClass:function(aa,Y){if(aa&&Y&&aa.className){var Z=typeof aa.className==="string"?aa.className.split(" "):[];if(-1!==B(Z,Y)){return true}}return false},findNodesHavingAttribute:function(ac,aa,Y){if(!Y){Y=[]}if(!ac||!aa){return Y}var ab=E(ac);if(!ab||!ab.length){return Y}var Z,ad;for(Z=0;Z<ab.length;Z++){ad=ab[Z];if(this.hasNodeAttribute(ad,aa)){Y.push(ad)}Y=this.findNodesHavingAttribute(ad,aa,Y)}return Y},findFirstNodeHavingAttribute:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeAttribute(aa,Z)){return aa}var Y=this.findNodesHavingAttribute(aa,Z);
+if(Y&&Y.length){return Y[0]}},findFirstNodeHavingAttributeWithValue:function(ab,aa){if(!ab||!aa){return}if(this.hasNodeAttributeWithValue(ab,aa)){return ab}var Y=this.findNodesHavingAttribute(ab,aa);if(!Y||!Y.length){return}var Z;for(Z=0;Z<Y.length;Z++){if(this.getAttributeValueFromNode(Y[Z],aa)){return Y[Z]}}},findNodesHavingCssClass:function(ac,ab,Y){if(!Y){Y=[]}if(!ac||!ab){return Y}if(ac.getElementsByClassName){var ad=ac.getElementsByClassName(ab);return this.htmlCollectionToArray(ad)}var aa=E(ac);if(!aa||!aa.length){return[]}var Z,ae;for(Z=0;Z<aa.length;Z++){ae=aa[Z];if(this.hasNodeCssClass(ae,ab)){Y.push(ae)}Y=this.findNodesHavingCssClass(ae,ab,Y)}return Y},findFirstNodeHavingClass:function(aa,Z){if(!aa||!Z){return}if(this.hasNodeCssClass(aa,Z)){return aa}var Y=this.findNodesHavingCssClass(aa,Z);if(Y&&Y.length){return Y[0]}},isLinkElement:function(Z){if(!Z){return false}var Y=String(Z.nodeName).toLowerCase();var ab=["a","area"];var aa=B(ab,Y);return aa!==-1},setAnyAttribute:function(Z,Y,aa){if(!Z||!Y){return
+}if(Z.setAttribute){Z.setAttribute(Y,aa)}else{Z[Y]=aa}}};var n={CONTENT_ATTR:"data-track-content",CONTENT_CLASS:"piwikTrackContent",CONTENT_NAME_ATTR:"data-content-name",CONTENT_PIECE_ATTR:"data-content-piece",CONTENT_PIECE_CLASS:"piwikContentPiece",CONTENT_TARGET_ATTR:"data-content-target",CONTENT_TARGET_CLASS:"piwikContentTarget",CONTENT_IGNOREINTERACTION_ATTR:"data-content-ignoreinteraction",CONTENT_IGNOREINTERACTION_CLASS:"piwikContentIgnoreInteraction",location:undefined,findContentNodes:function(){var Z="."+this.CONTENT_CLASS;var Y="["+this.CONTENT_ATTR+"]";var aa=S.findMultiple([Z,Y]);return aa},findContentNodesWithinNode:function(ab){if(!ab){return[]}var Z=S.findNodesHavingCssClass(ab,this.CONTENT_CLASS);var Y=S.findNodesHavingAttribute(ab,this.CONTENT_ATTR);if(Y&&Y.length){var aa;for(aa=0;aa<Y.length;aa++){Z.push(Y[aa])}}if(S.hasNodeAttribute(ab,this.CONTENT_ATTR)){Z.push(ab)}else{if(S.hasNodeCssClass(ab,this.CONTENT_CLASS)){Z.push(ab)}}Z=S.makeNodesUnique(Z);return Z},findParentContentNode:function(Z){if(!Z){return
+}var aa=Z;var Y=0;while(aa&&aa!==w&&aa.parentNode){if(S.hasNodeAttribute(aa,this.CONTENT_ATTR)){return aa}if(S.hasNodeCssClass(aa,this.CONTENT_CLASS)){return aa}aa=aa.parentNode;if(Y>1000){break}Y++}},findPieceNode:function(Z){var Y;Y=S.findFirstNodeHavingAttribute(Z,this.CONTENT_PIECE_ATTR);if(!Y){Y=S.findFirstNodeHavingClass(Z,this.CONTENT_PIECE_CLASS)}if(Y){return Y}return Z},findTargetNodeNoDefault:function(Y){if(!Y){return}var Z=S.findFirstNodeHavingAttributeWithValue(Y,this.CONTENT_TARGET_ATTR);if(Z){return Z}Z=S.findFirstNodeHavingAttribute(Y,this.CONTENT_TARGET_ATTR);if(Z){return Z}Z=S.findFirstNodeHavingClass(Y,this.CONTENT_TARGET_CLASS);if(Z){return Z}},findTargetNode:function(Y){var Z=this.findTargetNodeNoDefault(Y);if(Z){return Z}return Y},findContentName:function(Z){if(!Z){return}var ac=S.findFirstNodeHavingAttributeWithValue(Z,this.CONTENT_NAME_ATTR);if(ac){return S.getAttributeValueFromNode(ac,this.CONTENT_NAME_ATTR)}var Y=this.findContentPiece(Z);if(Y){return this.removeDomainIfIsInLink(Y)
+}if(S.hasNodeAttributeWithValue(Z,"title")){return S.getAttributeValueFromNode(Z,"title")}var aa=this.findPieceNode(Z);if(S.hasNodeAttributeWithValue(aa,"title")){return S.getAttributeValueFromNode(aa,"title")}var ab=this.findTargetNode(Z);if(S.hasNodeAttributeWithValue(ab,"title")){return S.getAttributeValueFromNode(ab,"title")}},findContentPiece:function(Z){if(!Z){return}var ab=S.findFirstNodeHavingAttributeWithValue(Z,this.CONTENT_PIECE_ATTR);if(ab){return S.getAttributeValueFromNode(ab,this.CONTENT_PIECE_ATTR)}var Y=this.findPieceNode(Z);var aa=this.findMediaUrlInNode(Y);if(aa){return this.toAbsoluteUrl(aa)}},findContentTarget:function(aa){if(!aa){return}var ab=this.findTargetNode(aa);if(S.hasNodeAttributeWithValue(ab,this.CONTENT_TARGET_ATTR)){return S.getAttributeValueFromNode(ab,this.CONTENT_TARGET_ATTR)}var Z;if(S.hasNodeAttributeWithValue(ab,"href")){Z=S.getAttributeValueFromNode(ab,"href");return this.toAbsoluteUrl(Z)}var Y=this.findPieceNode(aa);if(S.hasNodeAttributeWithValue(Y,"href")){Z=S.getAttributeValueFromNode(Y,"href");
+return this.toAbsoluteUrl(Z)}},isSameDomain:function(Y){if(!Y||!Y.indexOf){return false}if(0===Y.indexOf(this.getLocation().origin)){return true}var Z=Y.indexOf(this.getLocation().host);if(8>=Z&&0<=Z){return true}return false},removeDomainIfIsInLink:function(aa){var Z="^https?://[^/]+";var Y="^.*//[^/]+";if(aa&&aa.search&&-1!==aa.search(new RegExp(Z))&&this.isSameDomain(aa)){aa=aa.replace(new RegExp(Y),"");if(!aa){aa="/"}}return aa},findMediaUrlInNode:function(ac){if(!ac){return}var aa=["img","embed","video","audio"];var Y=ac.nodeName.toLowerCase();if(-1!==B(aa,Y)&&S.findFirstNodeHavingAttributeWithValue(ac,"src")){var ab=S.findFirstNodeHavingAttributeWithValue(ac,"src");return S.getAttributeValueFromNode(ab,"src")}if(Y==="object"&&S.hasNodeAttributeWithValue(ac,"data")){return S.getAttributeValueFromNode(ac,"data")}if(Y==="object"){var ad=S.findNodesByTagName(ac,"param");if(ad&&ad.length){var Z;for(Z=0;Z<ad.length;Z++){if("movie"===S.getAttributeValueFromNode(ad[Z],"name")&&S.hasNodeAttributeWithValue(ad[Z],"value")){return S.getAttributeValueFromNode(ad[Z],"value")
+}}}var ae=S.findNodesByTagName(ac,"embed");if(ae&&ae.length){return this.findMediaUrlInNode(ae[0])}}},trim:function(Y){if(Y&&String(Y)===Y){return Y.replace(/^\s+|\s+$/g,"")}return Y},isOrWasNodeInViewport:function(ad){if(!ad||!ad.getBoundingClientRect||ad.nodeType!==1){return true}var ac=ad.getBoundingClientRect();var ab=w.documentElement||{};var aa=ac.top<0;if(aa&&ad.offsetTop){aa=(ad.offsetTop+ac.height)>0}var Z=ab.clientWidth;if(I.innerWidth&&Z>I.innerWidth){Z=I.innerWidth}var Y=ab.clientHeight;if(I.innerHeight&&Y>I.innerHeight){Y=I.innerHeight}return((ac.bottom>0||aa)&&ac.right>0&&ac.left<Z&&((ac.top<Y)||aa))},isNodeVisible:function(Z){var Y=g(Z);var aa=this.isOrWasNodeInViewport(Z);return Y&&aa},buildInteractionRequestParams:function(Y,Z,aa,ab){var ac="";if(Y){ac+="c_i="+m(Y)}if(Z){if(ac){ac+="&"}ac+="c_n="+m(Z)}if(aa){if(ac){ac+="&"}ac+="c_p="+m(aa)}if(ab){if(ac){ac+="&"}ac+="c_t="+m(ab)}return ac},buildImpressionRequestParams:function(Y,Z,aa){var ab="c_n="+m(Y)+"&c_p="+m(Z);if(aa){ab+="&c_t="+m(aa)
+}return ab},buildContentBlock:function(aa){if(!aa){return}var Y=this.findContentName(aa);var Z=this.findContentPiece(aa);var ab=this.findContentTarget(aa);Y=this.trim(Y);Z=this.trim(Z);ab=this.trim(ab);return{name:Y||"Unknown",piece:Z||"Unknown",target:ab||""}},collectContent:function(ab){if(!ab||!ab.length){return[]}var aa=[];var Y,Z;for(Y=0;Y<ab.length;Y++){Z=this.buildContentBlock(ab[Y]);if(y(Z)){aa.push(Z)}}return aa},setLocation:function(Y){this.location=Y},getLocation:function(){var Y=this.location||I.location;if(!Y.origin){Y.origin=Y.protocol+"//"+Y.hostname+(Y.port?":"+Y.port:"")}return Y},toAbsoluteUrl:function(Z){if((!Z||String(Z)!==Z)&&Z!==""){return Z}if(""===Z){return this.getLocation().href}if(Z.search(/^\/\//)!==-1){return this.getLocation().protocol+Z}if(Z.search(/:\/\//)!==-1){return Z}if(0===Z.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+Z}if(0===Z.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+Z}if(0===Z.search("^[a-zA-Z]{2,11}:")){return Z
+}if(Z.search(/^\//)!==-1){return this.getLocation().origin+Z}var Y="(.*/)";var aa=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(Y))[0];return aa+Z},isUrlToCurrentDomain:function(Z){var aa=this.toAbsoluteUrl(Z);if(!aa){return false}var Y=this.getLocation().origin;if(Y===aa){return true}if(0===String(aa).indexOf(Y)){if(":"===String(aa).substr(Y.length,1)){return false}return true}return false},setHrefAttribute:function(Z,Y){if(!Z||!Y){return}S.setAnyAttribute(Z,"href",Y)},shouldIgnoreInteraction:function(aa){var Z=S.hasNodeAttribute(aa,this.CONTENT_IGNOREINTERACTION_ATTR);var Y=S.hasNodeCssClass(aa,this.CONTENT_IGNOREINTERACTION_CLASS);return Z||Y}};function D(Y,Z){if(Z){return Z}if(Y.slice(-9)==="piwik.php"){Y=Y.slice(0,Y.length-9)}return Y}function C(ae){var ag="Piwik_Overlay";var Z=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$");var aa=Z.exec(w.referrer);if(aa){var ac=aa[1];if(ac!==String(ae)){return false
+}var ad=aa[2],Y=aa[3],ab=aa[4];if(!ab){ab=""}else{if(ab.indexOf("&segment=")===0){ab=ab.substr("&segment=".length)}}I.name=ag+"###"+ad+"###"+Y+"###"+ab}var af=I.name.split("###");return af.length===4&&af[0]===ag}function O(Z,af,ab){var ae=I.name.split("###"),ad=ae[1],Y=ae[2],ac=ae[3],aa=D(Z,af);i(aa+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(aa,ab,ad,Y,ac)})}function F(bH,bB){var bx=P(w.domain,I.location.href,z()),cf=A(bx[0]),bh=j(bx[1]),aW=j(bx[2]),cd=false,bL="GET",cs=bL,am="application/x-www-form-urlencoded; charset=UTF-8",bX=am,ai=bH||"",bc="",cj="",bz=bB||"",a5="",bi="",aG,aS=w.title,cp=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],ae=[cf],a6=[],bf=[],aJ=[],bd=500,b6,aH,bl,bj,Y,bT=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],bb=["pk_kwd","piwik_kwd","utm_term"],aT="_pk_",ch,aY,aU=false,cb,aQ,a2,b7=33955200000,bR=1800000,co=15768000000,aE=true,bP=0,bk=false,at=false,bE,bp={},bO={},aV={},a1=200,ck={},cq={},bD=[],bI=false,b0=false,Z=false,cr=false,aq=false,ci=null,bF,au,a7,bA=W,aX;
+function cv(cF,cC,cB,cE,cA,cD){if(aU){return}var cz;if(cB){cz=new Date();cz.setTime(cz.getTime()+cB)}w.cookie=cF+"="+m(cC)+(cB?";expires="+cz.toGMTString():"")+";path="+(cE||"/")+(cA?";domain="+cA:"")+(cD?";secure":"")}function ah(cB){if(aU){return 0}var cz=new RegExp("(^|;)[ ]*"+cB+"=([^;]*)"),cA=cz.exec(w.cookie);return cA?H(cA[2]):0}function bv(cz){var cA;if(bj){cA=new RegExp("#.*");return cz.replace(cA,"")}return cz}function bo(cB,cz){var cC=l(cz),cA;if(cC){return cz}if(cz.slice(0,1)==="/"){return l(cB)+"://"+c(cB)+cz}cB=bv(cB);cA=cB.indexOf("?");if(cA>=0){cB=cB.slice(0,cA)}cA=cB.lastIndexOf("/");if(cA!==cB.length-1){cB=cB.slice(0,cA+1)}return cB+cz}function b4(cB,cz){var cA;cB=String(cB).toLowerCase();cz=String(cz).toLowerCase();if(cB===cz){return true}if(cz.slice(0,1)==="."){if(cB===cz.slice(1)){return true}cA=cB.length-cz.length;if((cA>0)&&(cB.slice(cA)===cz)){return true}}return false}function cm(cA,cz){cA=String(cA);return cA.indexOf(cz,cA.length-cz.length)!==-1}function aP(cA,cz){cA=String(cA);
+return cA.substr(0,cA.length-cz)}function bN(cz){var cA=document.createElement("a");if(cz.indexOf("//")!==0&&cz.indexOf("http")!==0){cz="http://"+cz}cA.href=n.toAbsoluteUrl(cz);if(cA.pathname){return cA.pathname}return""}function aF(cA,cz){var cB=(!cz||cz==="/");if(cB){return true}if(cA===cz){return true}if(!cA){return false}cz=String(cz).toLowerCase();cA=String(cA).toLowerCase();if(!cm(cA,"/")){cA+="/"}if(!cm(cz,"/")){cz+="/"}return cA.indexOf(cz)===0}function ab(cD,cF){var cA,cz,cB,cC,cE;for(cA=0;cA<ae.length;cA++){cC=A(ae[cA]);cE=bN(ae[cA]);if(b4(cD,cC)&&aF(cF,cE)){return true}}return false}function ay(cC){var cA,cz,cB;for(cA=0;cA<ae.length;cA++){cz=A(ae[cA].toLowerCase());if(cC===cz){return true}if(cz.slice(0,1)==="."){if(cC===cz.slice(1)){return true}cB=cC.length-cz.length;if((cB>0)&&(cC.slice(cB)===cz)){return true}}}return false}function bS(cz,cB){var cA=new Image(1,1);cA.onload=function(){v=0;if(typeof cB==="function"){cB()}};cA.src=ai+(ai.indexOf("?")<0?"?":"&")+cz}function cn(cA,cD,cz){if(!y(cz)||null===cz){cz=true
+}try{var cC=I.XMLHttpRequest?new I.XMLHttpRequest():I.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;cC.open("POST",ai,true);cC.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)&&cz){bS(cA,cD)}else{if(typeof cD==="function"){cD()}}};cC.setRequestHeader("Content-Type",bX);cC.send(cA)}catch(cB){if(cz){bS(cA,cD)}}}function bJ(cA){var cz=new Date();var cB=cz.getTime()+cA;if(!k||cB>k){k=cB}}function bQ(cz){if(bF||!aH){return}bF=setTimeout(function cA(){bF=null;if(bl()){return}var cB=new Date(),cC=aH-(cB.getTime()-ci);cC=Math.min(aH,cC);bQ(cC)},cz||aH)}function be(){if(!bF){return}clearTimeout(bF);bF=null}function aM(){if(bl()){return}bQ()}function af(){be()}function cx(){if(aq||!aH){return}aq=true;X(I,"focus",aM);X(I,"blur",af);bQ()}function b1(cD){var cA=new Date();var cz=cA.getTime();ci=cz;if(b0&&cz<b0){var cB=b0-cz;setTimeout(cD,cB);bJ(cB+50);b0+=50;return}if(b0===false){var cC=800;b0=cz+cC}cD()}function ba(cA,cz,cB){if(!cb&&cA){b1(function(){if(cs==="POST"){cn(cA,cB)
+}else{bS(cA,cB)}bJ(cz)})}if(!aq){cx()}else{bQ()}}function bM(cz){if(cb){return false}return(cz&&cz.length)}function cw(cB,cz){if(!bM(cB)){return}var cA='{"requests":["?'+cB.join('","?')+'"]}';b1(function(){cn(cA,null,false);bJ(cz)})}function aw(cz){return aT+cz+"."+bz+"."+aX}function by(){if(aU){return"0"}if(!y(e.cookieEnabled)){var cz=aw("testcookie");cv(cz,"1");return ah(cz)==="1"?"1":"0"}return e.cookieEnabled?"1":"0"}function aR(){aX=bA((ch||cf)+(aY||"/")).slice(0,4)}function bq(){var cA=aw("cvar"),cz=ah(cA);if(cz.length){cz=JSON2.parse(cz);if(L(cz)){return cz}}return{}}function b2(){if(at===false){at=bq()}}function cc(){return bA((e.userAgent||"")+(e.platform||"")+JSON2.stringify(cq)+(new Date()).getTime()+Math.random()).slice(0,16)}function b9(){var cB=new Date(),cz=Math.round(cB.getTime()/1000),cA=aw("id"),cE=ah(cA),cD,cC;if(cE){cD=cE.split(".");cD.unshift("0");if(bi.length){cD[1]=bi}return cD}if(bi.length){cC=bi}else{if("0"===by()){cC=""}else{cC=cc()}}cD=["1",cC,cz,0,cz,"",""];return cD
+}function aA(){var cG=b9(),cC=cG[0],cD=cG[1],cA=cG[2],cz=cG[3],cE=cG[4],cB=cG[5];if(!y(cG[6])){cG[6]=""}var cF=cG[6];return{newVisitor:cC,uuid:cD,createTs:cA,visitCount:cz,currentVisitTs:cE,lastVisitTs:cB,lastEcommerceOrderTs:cF}}function al(){var cC=new Date(),cA=cC.getTime(),cD=aA().createTs;var cz=parseInt(cD,10);var cB=(cz*1000)+b7-cA;return cB}function ao(cz){if(!bz){return}var cB=new Date(),cA=Math.round(cB.getTime()/1000);if(!y(cz)){cz=aA()}var cC=cz.uuid+"."+cz.createTs+"."+cz.visitCount+"."+cA+"."+cz.lastVisitTs+"."+cz.lastEcommerceOrderTs;cv(aw("id"),cC,al(),aY,ch)}function bg(){var cz=ah(aw("ref"));if(cz.length){try{cz=JSON2.parse(cz);if(L(cz)){return cz}}catch(cA){}}return["","",0,""]}function br(cB,cA,cz){cv(cB,"",-86400,cA,cz)}function a3(cA){var cz="testvalue";cv("test",cz,10000,null,cA);if(ah("test")===cz){br("test",null,cA);return true}return false}function aj(){var cB=aU;aU=false;var cz=["id","ses","cvar","ref"];var cA,cC;for(cA=0;cA<cz.length;cA++){cC=aw(cz[cA]);if(0!==ah(cC)){br(cC,aY,ch)
+}}aU=cB}function bw(cz){bz=cz;ao()}function cy(cD){if(!cD||!L(cD)){return}var cC=[];var cB;for(cB in cD){if(Object.prototype.hasOwnProperty.call(cD,cB)){cC.push(cB)}}var cE={};cC.sort();var cz=cC.length;var cA;for(cA=0;cA<cz;cA++){cE[cC[cA]]=cD[cC[cA]]}return cE}function bG(){cv(aw("ses"),"*",bR,aY,ch)}function bU(cB,cW,cX,cC){var cV,cA=new Date(),cJ=Math.round(cA.getTime()/1000),cG,cU,cD=1024,c2,cK,cS=at,cE=aw("ses"),cQ=aw("ref"),cN=aw("cvar"),cO=ah(cE),cT=bg(),cZ=aG||bh,cH,cz;if(aU){aj()}if(cb){return""}var cP=aA();if(!y(cC)){cC=""}var cM=w.characterSet||w.charset;if(!cM||cM.toLowerCase()==="utf-8"){cM=null}cH=cT[0];cz=cT[1];cG=cT[2];cU=cT[3];if(!cO){var cY=bR/1000;if(!cP.lastVisitTs||(cJ-cP.lastVisitTs)>cY){cP.visitCount++;cP.lastVisitTs=cP.currentVisitTs}if(!a2||!cH.length){for(cV in bT){if(Object.prototype.hasOwnProperty.call(bT,cV)){cH=K(cZ,bT[cV]);if(cH.length){break}}}for(cV in bb){if(Object.prototype.hasOwnProperty.call(bb,cV)){cz=K(cZ,bb[cV]);if(cz.length){break}}}}c2=c(aW);cK=cU.length?c(cU):"";
+if(c2.length&&!ay(c2)&&(!a2||!cK.length||ay(cK))){cU=aW}if(cU.length||cH.length){cG=cJ;cT=[cH,cz,cG,bv(cU.slice(0,cD))];cv(cQ,JSON2.stringify(cT),co,aY,ch)}}cB+="&idsite="+bz+"&rec=1&r="+String(Math.random()).slice(2,8)+"&h="+cA.getHours()+"&m="+cA.getMinutes()+"&s="+cA.getSeconds()+"&url="+m(bv(cZ))+(aW.length?"&urlref="+m(bv(aW)):"")+((a5&&a5.length)?"&uid="+m(a5):"")+"&_id="+cP.uuid+"&_idts="+cP.createTs+"&_idvc="+cP.visitCount+"&_idn="+cP.newVisitor+(cH.length?"&_rcn="+m(cH):"")+(cz.length?"&_rck="+m(cz):"")+"&_refts="+cG+"&_viewts="+cP.lastVisitTs+(String(cP.lastEcommerceOrderTs).length?"&_ects="+cP.lastEcommerceOrderTs:"")+(String(cU).length?"&_ref="+m(bv(cU.slice(0,cD))):"")+(cM?"&cs="+m(cM):"")+"&send_image=0";for(cV in cq){if(Object.prototype.hasOwnProperty.call(cq,cV)){cB+="&"+cV+"="+cq[cV]}}var c1=[];if(cW){for(cV in cW){if(Object.prototype.hasOwnProperty.call(cW,cV)&&/^dimension\d+$/.test(cV)){var cF=cV.replace("dimension","");c1.push(parseInt(cF,10));c1.push(String(cF));cB+="&"+cV+"="+cW[cV];
+delete cW[cV]}}}if(cW&&s(cW)){cW=null}for(cV in aV){if(Object.prototype.hasOwnProperty.call(aV,cV)){var cL=(-1===c1.indexOf(cV));if(cL){cB+="&dimension"+cV+"="+aV[cV]}}}if(cW){cB+="&data="+m(JSON2.stringify(cW))}else{if(Y){cB+="&data="+m(JSON2.stringify(Y))}}function cI(c3,c4){var c5=JSON2.stringify(c3);if(c5.length>2){return"&"+c4+"="+m(c5)}return""}var c0=cy(bp);var cR=cy(bO);cB+=cI(c0,"cvar");cB+=cI(cR,"e_cvar");if(at){cB+=cI(at,"_cvar");for(cV in cS){if(Object.prototype.hasOwnProperty.call(cS,cV)){if(at[cV][0]===""||at[cV][1]===""){delete at[cV]}}}if(bk){cv(cN,JSON2.stringify(at),bR,aY,ch)}}if(aE){if(bP){cB+="&gt_ms="+bP}else{if(f&&f.timing&&f.timing.requestStart&&f.timing.responseEnd){cB+="&gt_ms="+(f.timing.responseEnd-f.timing.requestStart)}}}cP.lastEcommerceOrderTs=y(cC)&&String(cC).length?cC:cP.lastEcommerceOrderTs;ao(cP);bG();cB+=Q(cX);if(cj.length){cB+="&"+cj}if(r(bE)){cB=bE(cB)}return cB}bl=function aI(){var cz=new Date();if(ci+aH<=cz.getTime()){var cA=bU("ping=1",null,"ping");
+ba(cA,bd);return true}return false};function aZ(cC,cB,cG,cD,cz,cJ){var cE="idgoal=0",cF,cA=new Date(),cH=[],cI;if(String(cC).length){cE+="&ec_id="+m(cC);cF=Math.round(cA.getTime()/1000)}cE+="&revenue="+cB;if(String(cG).length){cE+="&ec_st="+cG}if(String(cD).length){cE+="&ec_tx="+cD}if(String(cz).length){cE+="&ec_sh="+cz}if(String(cJ).length){cE+="&ec_dt="+cJ}if(ck){for(cI in ck){if(Object.prototype.hasOwnProperty.call(ck,cI)){if(!y(ck[cI][1])){ck[cI][1]=""}if(!y(ck[cI][2])){ck[cI][2]=""}if(!y(ck[cI][3])||String(ck[cI][3]).length===0){ck[cI][3]=0}if(!y(ck[cI][4])||String(ck[cI][4]).length===0){ck[cI][4]=1}cH.push(ck[cI])}}cE+="&ec_items="+m(JSON2.stringify(cH))}cE=bU(cE,Y,"ecommerce",cF);ba(cE,bd)}function bs(cz,cD,cC,cB,cA,cE){if(String(cz).length&&y(cD)){aZ(cz,cD,cC,cB,cA,cE)}}function a0(cz){if(y(cz)){aZ("",cz,"","","","")}}function bt(cB,cC){var cz=new Date(),cA=bU("action_name="+m(V(cB||aS)),cC,"log");ba(cA,bd)}function aC(cB,cA){var cC,cz="(^| )(piwik[_-]"+cA;if(cB){for(cC=0;cC<cB.length;
+cC++){cz+="|"+cB[cC]}}cz+=")( |$)";return new RegExp(cz)}function ax(cz){return(ai&&cz&&0===String(cz).indexOf(ai))}function bV(cD,cz,cE,cA){if(ax(cz)){return 0}var cC=aC(bf,"download"),cB=aC(aJ,"link"),cF=new RegExp("\\.("+cp.join("|")+")([?&#]|$)","i");if(cB.test(cD)){return"link"}if(cA||cC.test(cD)||cF.test(cz)){return"download"}if(cE){return 0}return"link"}function ac(cA){var cz;cz=cA.parentNode;while(cz!==null&&y(cz)){if(S.isLinkElement(cA)){break}cA=cz;cz=cA.parentNode}return cA}function ct(cE){cE=ac(cE);if(!S.hasNodeAttribute(cE,"href")){return}if(!y(cE.href)){return}var cD=S.getAttributeValueFromNode(cE,"href");if(ax(cD)){return}var cA=cE.pathname||bN(cE.href);var cF=cE.hostname||c(cE.href);var cG=cF.toLowerCase();var cB=cE.href.replace(cF,cG);var cC=new RegExp("^(javascript|vbscript|jscript|mocha|livescript|ecmascript|mailto):","i");if(!cC.test(cB)){var cz=bV(cE.className,cB,ab(cG,cA),S.hasNodeAttribute(cE,"download"));if(cz){return{type:cz,href:cB}}}}function ar(cz,cA,cB,cC){var cD=n.buildInteractionRequestParams(cz,cA,cB,cC);
+if(!cD){return}return bU(cD,null,"contentInteraction")}function b8(cB,cC,cG,cz,cA){if(!y(cB)){return}if(ax(cB)){return cB}var cE=n.toAbsoluteUrl(cB);var cD="redirecturl="+m(cE)+"&";cD+=ar(cC,cG,cz,(cA||cB));var cF="&";if(ai.indexOf("?")<0){cF="?"}return ai+cF+cD}function aN(cz,cA){if(!cz||!cA){return false}var cB=n.findTargetNode(cz);if(n.shouldIgnoreInteraction(cB)){return false}cB=n.findTargetNodeNoDefault(cz);if(cB&&!J(cB,cA)){return false}return true}function bW(cB,cA,cD){if(!cB){return}var cz=n.findParentContentNode(cB);if(!cz){return}if(!aN(cz,cB)){return}var cC=n.buildContentBlock(cz);if(!cC){return}if(!cC.target&&cD){cC.target=cD}return n.buildInteractionRequestParams(cA,cC.name,cC.piece,cC.target)}function az(cA){if(!bD||!bD.length){return false}var cz,cB;for(cz=0;cz<bD.length;cz++){cB=bD[cz];if(cB&&cB.name===cA.name&&cB.piece===cA.piece&&cB.target===cA.target){return true}}return false}function a9(cC){if(!cC){return false}var cF=n.findTargetNode(cC);if(!cF||n.shouldIgnoreInteraction(cF)){return false
+}var cG=ct(cF);if(cr&&cG&&cG.type){return false}if(S.isLinkElement(cF)&&S.hasNodeAttributeWithValue(cF,"href")){var cz=String(S.getAttributeValueFromNode(cF,"href"));if(0===cz.indexOf("#")){return false}if(ax(cz)){return true}if(!n.isUrlToCurrentDomain(cz)){return false}var cD=n.buildContentBlock(cC);if(!cD){return}var cB=cD.name;var cH=cD.piece;var cE=cD.target;if(!S.hasNodeAttributeWithValue(cF,n.CONTENT_TARGET_ATTR)||cF.wasContentTargetAttrReplaced){cF.wasContentTargetAttrReplaced=true;cE=n.toAbsoluteUrl(cz);S.setAnyAttribute(cF,n.CONTENT_TARGET_ATTR,cE)}var cA=b8(cz,"click",cB,cH,cE);n.setHrefAttribute(cF,cA);return true}return false}function ap(cA){if(!cA||!cA.length){return}var cz;for(cz=0;cz<cA.length;cz++){a9(cA[cz])}}function aB(cz){return function(cA){if(!cz){return}var cD=n.findParentContentNode(cz);var cE;if(cA){cE=cA.target||cA.srcElement}if(!cE){cE=cz}if(!aN(cD,cE)){return}bJ(bd);if(S.isLinkElement(cz)&&S.hasNodeAttributeWithValue(cz,"href")&&S.hasNodeAttributeWithValue(cz,n.CONTENT_TARGET_ATTR)){var cB=S.getAttributeValueFromNode(cz,"href");
+if(!ax(cB)&&cz.wasContentTargetAttrReplaced){S.setAnyAttribute(cz,n.CONTENT_TARGET_ATTR,"")}}var cI=ct(cz);if(Z&&cI&&cI.type){return cI.type}if(a9(cD)){return"href"}var cF=n.buildContentBlock(cD);if(!cF){return}var cC=cF.name;var cJ=cF.piece;var cH=cF.target;var cG=ar("click",cC,cJ,cH);ba(cG,bd);return cG}}function bu(cB){if(!cB||!cB.length){return}var cz,cA;for(cz=0;cz<cB.length;cz++){cA=n.findTargetNode(cB[cz]);if(cA&&!cA.contentInteractionTrackingSetupDone){cA.contentInteractionTrackingSetupDone=true;X(cA,"click",aB(cA))}}}function a4(cB,cC){if(!cB||!cB.length){return[]}var cz,cA;for(cz=0;cz<cB.length;cz++){if(az(cB[cz])){cB.splice(cz,1);cz--}else{bD.push(cB[cz])}}if(!cB||!cB.length){return[]}ap(cC);bu(cC);var cD=[];for(cz=0;cz<cB.length;cz++){cA=bU(n.buildImpressionRequestParams(cB[cz].name,cB[cz].piece,cB[cz].target),undefined,"contentImpressions");cD.push(cA)}return cD}function bZ(cA){var cz=n.collectContent(cA);return a4(cz,cA)}function aL(cA){if(!cA||!cA.length){return[]}var cz;
+for(cz=0;cz<cA.length;cz++){if(!n.isNodeVisible(cA[cz])){cA.splice(cz,1);cz--}}if(!cA||!cA.length){return[]}return bZ(cA)}function ak(cB,cz,cA){var cC=n.buildImpressionRequestParams(cB,cz,cA);return bU(cC,null,"contentImpression")}function cu(cC,cA){if(!cC){return}var cz=n.findParentContentNode(cC);var cB=n.buildContentBlock(cz);if(!cB){return}if(!cA){cA="Unknown"}return ar(cA,cB.name,cB.piece,cB.target)}function ca(cA,cC,cz,cB){return"e_c="+m(cA)+"&e_a="+m(cC)+(y(cz)?"&e_n="+m(cz):"")+(y(cB)?"&e_v="+m(cB):"")}function ad(cB,cD,cz,cC,cE){if(String(cB).length===0||String(cD).length===0){return false}var cA=bU(ca(cB,cD,cz,cC),cE,"event");ba(cA,bd)}function bC(cz,cC,cA,cD){var cB=bU("search="+m(cz)+(cC?"&search_cat="+m(cC):"")+(y(cA)?"&search_count="+cA:""),cD,"sitesearch");ba(cB,bd)}function ce(cz,cC,cB){var cA=bU("idgoal="+cz+(cC?"&revenue="+cC:""),cB,"goal");ba(cA,bd)}function cl(cC,cz,cG,cF,cB){var cE=cz+"="+m(bv(cC));var cA=bW(cB,"click",cC);if(cA){cE+="&"+cA}var cD=bU(cE,cG,"link");ba(cD,(cF?0:bd),cF)
+}function bm(cA,cz){if(cA!==""){return cA+cz.charAt(0).toUpperCase()+cz.slice(1)}return cz}function bK(cE){var cD,cz,cC=["","webkit","ms","moz"],cB;if(!aQ){for(cz=0;cz<cC.length;cz++){cB=cC[cz];if(Object.prototype.hasOwnProperty.call(w,bm(cB,"hidden"))){if(w[bm(cB,"visibilityState")]==="prerender"){cD=true}break}}}if(cD){X(w,cB+"visibilitychange",function cA(){w.removeEventListener(cB+"visibilitychange",cA,false);cE()});return}cE()}function an(cz){if(w.readyState==="complete"){cz()}else{if(I.addEventListener){I.addEventListener("load",cz)}else{if(I.attachEvent){I.attachEvent("onLoad",cz)}}}}function aO(cA){var cz=false;if(w.attachEvent){cz=w.readyState==="complete"}else{cz=w.readyState!=="loading"}if(cz){cA()}else{if(w.addEventListener){w.addEventListener("DOMContentLoaded",cA)}else{if(w.attachEvent){w.attachEvent("onreadystatechange",cA)}}}}function b5(cz){var cA=ct(cz);if(cA&&cA.type){cA.href=j(cA.href);cl(cA.href,cA.type,undefined,null,cz)}}function bY(){return w.all&&!w.addEventListener
+}function cg(cz){var cB=cz.which;var cA=(typeof cz.button);if(!cB&&cA!=="undefined"){if(bY()){if(cz.button&1){cB=1}else{if(cz.button&2){cB=3}else{if(cz.button&4){cB=2}}}}else{if(cz.button===0||cz.button==="0"){cB=1}else{if(cz.button&1){cB=2}else{if(cz.button&2){cB=3}}}}}return cB}function bn(cz){switch(cg(cz)){case 1:return"left";case 2:return"middle";case 3:return"right"}}function aD(cz){return cz.target||cz.srcElement}function ag(cz){return function(cC){cC=cC||I.event;var cB=bn(cC);var cD=aD(cC);if(cC.type==="click"){var cA=false;if(cz&&cB==="middle"){cA=true}if(cD&&!cA){b5(cD)}}else{if(cC.type==="mousedown"){if(cB==="middle"&&cD){au=cB;a7=cD}else{au=a7=null}}else{if(cC.type==="mouseup"){if(cB===au&&cD===a7){b5(cD)}au=a7=null}else{if(cC.type==="contextmenu"){b5(cD)}}}}}}function aa(cA,cz){X(cA,"click",ag(cz),false);if(cz){X(cA,"mouseup",ag(cz),false);X(cA,"mousedown",ag(cz),false);X(cA,"contextmenu",ag(cz),false)}}function a8(cA){if(!Z){Z=true;var cB,cz=aC(a6,"ignore"),cC=w.links;if(cC){for(cB=0;
+cB<cC.length;cB++){if(!cz.test(cC[cB].className)){aa(cC[cB],cA)}}}}}function av(cB,cD,cE){if(bI){return true}bI=true;var cF=false;var cC,cA;function cz(){cF=true}an(function(){function cG(cI){setTimeout(function(){if(!bI){return}cF=false;cE.trackVisibleContentImpressions();cG(cI)},cI)}function cH(cI){setTimeout(function(){if(!bI){return}if(cF){cF=false;cE.trackVisibleContentImpressions()}cH(cI)},cI)}if(cB){cC=["scroll","resize"];for(cA=0;cA<cC.length;cA++){if(w.addEventListener){w.addEventListener(cC[cA],cz)}else{I.attachEvent("on"+cC[cA],cz)}}cH(100)}if(cD&&cD>0){cD=parseInt(cD,10);cG(cD)}})}function aK(cD,cF){var cE=bN(cD);var cC=bN(cF);if(!cE||cE==="/"||!cC||cC==="/"){return}var cB=A(cD);if(ab(cB,"/")){return}if(cm(cE,"/")){cE=aP(cE,1)}var cG=cE.split("/");var cA;for(cA=2;cA<cG.length;cA++){var cz=cG.slice(0,cA).join("/");if(ab(cB,cz)){cE=cz;break}}if(!aF(cC,cE)){return}return cE}function b3(){var cA,cB,cC={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",dir:"application/x-director",fla:"application/x-shockwave-flash",java:"application/x-java-vm",gears:"application/x-googlegears",ag:"application/x-silverlight"},cz=I.devicePixelRatio||1;
+if(!((new RegExp("MSIE")).test(e.userAgent))){if(e.mimeTypes&&e.mimeTypes.length){for(cA in cC){if(Object.prototype.hasOwnProperty.call(cC,cA)){cB=e.mimeTypes[cC[cA]];cq[cA]=(cB&&cB.enabledPlugin)?"1":"0"}}}if(typeof navigator.javaEnabled!=="unknown"&&y(e.javaEnabled)&&e.javaEnabled()){cq.java="1"}if(r(I.GearsFactory)){cq.gears="1"}cq.cookie=by()}cq.res=M.width*cz+"x"+M.height*cz}b3();aR();ao();return{getVisitorId:function(){return aA().uuid},getVisitorInfo:function(){return b9()},getAttributionInfo:function(){return bg()},getAttributionCampaignName:function(){return bg()[0]},getAttributionCampaignKeyword:function(){return bg()[1]},getAttributionReferrerTimestamp:function(){return bg()[2]},getAttributionReferrerUrl:function(){return bg()[3]},setTrackerUrl:function(cz){ai=cz},getTrackerUrl:function(){return ai},getSiteId:function(){return bz},setSiteId:function(cz){bw(cz)},setUserId:function(cz){if(!y(cz)||!cz.length){return}a5=cz;bi=bA(a5).substr(0,16)},getUserId:function(){return a5},setCustomData:function(cz,cA){if(L(cz)){Y=cz
+}else{if(!Y){Y={}}Y[cz]=cA}},getCustomData:function(){return Y},setCustomRequestProcessing:function(cz){bE=cz},appendToTrackingUrl:function(cz){cj=cz},getRequest:function(cz){return bU(cz)},addPlugin:function(cz,cA){a[cz]=cA},setCustomDimension:function(cz,cA){cz=parseInt(cz,10);if(cz>0){if(!y(cA)){cA=""}if(!o(cA)){cA=String(cA)}aV[cz]=cA}},getCustomDimension:function(cz){cz=parseInt(cz,10);if(cz>0&&Object.prototype.hasOwnProperty.call(aV,cz)){return aV[cz]}},deleteCustomDimension:function(cz){cz=parseInt(cz,10);if(cz>0){delete aV[cz]}},setCustomVariable:function(cA,cz,cD,cB){var cC;if(!y(cB)){cB="visit"}if(!y(cz)){return}if(!y(cD)){cD=""}if(cA>0){cz=!o(cz)?String(cz):cz;cD=!o(cD)?String(cD):cD;cC=[cz.slice(0,a1),cD.slice(0,a1)];if(cB==="visit"||cB===2){b2();at[cA]=cC}else{if(cB==="page"||cB===3){bp[cA]=cC}else{if(cB==="event"){bO[cA]=cC}}}}},getCustomVariable:function(cA,cB){var cz;if(!y(cB)){cB="visit"}if(cB==="page"||cB===3){cz=bp[cA]}else{if(cB==="event"){cz=bO[cA]}else{if(cB==="visit"||cB===2){b2();
+cz=at[cA]}}}if(!y(cz)||(cz&&cz[0]==="")){return false}return cz},deleteCustomVariable:function(cz,cA){if(this.getCustomVariable(cz,cA)){this.setCustomVariable(cz,"","",cA)}},storeCustomVariablesInCookie:function(){bk=true},setLinkTrackingTimer:function(cz){bd=cz},setDownloadExtensions:function(cz){if(o(cz)){cz=cz.split("|")}cp=cz},addDownloadExtensions:function(cA){var cz;if(o(cA)){cA=cA.split("|")}for(cz=0;cz<cA.length;cz++){cp.push(cA[cz])}},removeDownloadExtensions:function(cB){var cA,cz=[];if(o(cB)){cB=cB.split("|")}for(cA=0;cA<cp.length;cA++){if(B(cB,cp[cA])===-1){cz.push(cp[cA])}}cp=cz},setDomains:function(cz){ae=o(cz)?[cz]:cz;var cB=false,cA;for(cA in ae){if(Object.prototype.hasOwnProperty.call(ae,cA)&&b4(cf,A(String(ae[cA])))){cB=true;if(!aY){var cC=aK(ae[cA],bh);if(cC){this.setCookiePath(cC)}break}}}if(!cB){ae.push(cf)}},setIgnoreClasses:function(cz){a6=o(cz)?[cz]:cz},setRequestMethod:function(cz){cs=cz||bL},setRequestContentType:function(cz){bX=cz||am},setReferrerUrl:function(cz){aW=cz
+},setCustomUrl:function(cz){aG=bo(bh,cz)},setDocumentTitle:function(cz){aS=cz},setAPIUrl:function(cz){bc=cz},setDownloadClasses:function(cz){bf=o(cz)?[cz]:cz},setLinkClasses:function(cz){aJ=o(cz)?[cz]:cz},setCampaignNameKey:function(cz){bT=o(cz)?[cz]:cz},setCampaignKeywordKey:function(cz){bb=o(cz)?[cz]:cz},discardHashTag:function(cz){bj=cz},setCookieNamePrefix:function(cz){aT=cz;at=bq()},setCookieDomain:function(cz){var cA=A(cz);if(a3(cA)){ch=cA;aR()}},setCookiePath:function(cz){aY=cz;aR()},setVisitorCookieTimeout:function(cz){b7=cz*1000},setSessionCookieTimeout:function(cz){bR=cz*1000},setReferralCookieTimeout:function(cz){co=cz*1000},setConversionAttributionFirstReferrer:function(cz){a2=cz},disableCookies:function(){aU=true;cq.cookie="0";if(bz){aj()}},deleteCookies:function(){aj()},setDoNotTrack:function(cA){var cz=e.doNotTrack||e.msDoNotTrack;cb=cA&&(cz==="yes"||cz==="1");if(cb){this.disableCookies()}},addListener:function(cA,cz){aa(cA,cz)},enableLinkTracking:function(cz){cr=true;if(q){a8(cz)
+}else{G.push(function(){a8(cz)})}},enableJSErrorTracking:function(){if(cd){return}cd=true;var cz=I.onerror;I.onerror=function(cE,cC,cB,cD,cA){bK(function(){var cF="JavaScript Errors";var cG=cC+":"+cB;if(cD){cG+=":"+cD}ad(cF,cG,cE)});if(cz){return cz(cE,cC,cB,cD,cA)}return false}},disablePerformanceTracking:function(){aE=false},setGenerationTimeMs:function(cz){bP=parseInt(cz,10)},enableHeartBeatTimer:function(cz){cz=Math.max(cz,1);aH=(cz||15)*1000;if(ci!==null){cx()}},killFrame:function(){if(I.location!==I.top.location){I.top.location=I.location}},redirectFile:function(cz){if(I.location.protocol==="file:"){I.location=cz}},setCountPreRendered:function(cz){aQ=cz},trackGoal:function(cz,cB,cA){bK(function(){ce(cz,cB,cA)})},trackLink:function(cA,cz,cC,cB){bK(function(){cl(cA,cz,cC,cB)})},trackPageView:function(cz,cA){bD=[];if(C(bz)){bK(function(){O(ai,bc,bz)})}else{bK(function(){bt(cz,cA)})}},trackAllContentImpressions:function(){if(C(bz)){return}bK(function(){aO(function(){var cz=n.findContentNodes();
+var cA=bZ(cz);cw(cA,bd)})})},trackVisibleContentImpressions:function(cz,cA){if(C(bz)){return}if(!y(cz)){cz=true}if(!y(cA)){cA=750}av(cz,cA,this);bK(function(){an(function(){var cB=n.findContentNodes();var cC=aL(cB);cw(cC,bd)})})},trackContentImpression:function(cB,cz,cA){if(C(bz)){return}if(!cB){return}cz=cz||"Unknown";bK(function(){var cC=ak(cB,cz,cA);ba(cC,bd)})},trackContentImpressionsWithinNode:function(cz){if(C(bz)||!cz){return}bK(function(){if(bI){an(function(){var cA=n.findContentNodesWithinNode(cz);var cB=aL(cA);cw(cB,bd)})}else{aO(function(){var cA=n.findContentNodesWithinNode(cz);var cB=bZ(cA);cw(cB,bd)})}})},trackContentInteraction:function(cB,cC,cz,cA){if(C(bz)){return}if(!cB||!cC){return}cz=cz||"Unknown";bK(function(){var cD=ar(cB,cC,cz,cA);ba(cD,bd)})},trackContentInteractionNode:function(cA,cz){if(C(bz)||!cA){return}bK(function(){var cB=cu(cA,cz);ba(cB,bd)})},logAllContentBlocksOnPage:function(){var cA=n.findContentNodes();var cz=n.collectContent(cA);if(console!==undefined&&console&&console.log){console.log(cz)
+}},trackEvent:function(cA,cC,cz,cB,cD){bK(function(){ad(cA,cC,cz,cB,cD)})},trackSiteSearch:function(cz,cB,cA,cC){bK(function(){bC(cz,cB,cA,cC)})},setEcommerceView:function(cC,cz,cB,cA){if(!y(cB)||!cB.length){cB=""}else{if(cB instanceof Array){cB=JSON2.stringify(cB)}}bp[5]=["_pkc",cB];if(y(cA)&&String(cA).length){bp[2]=["_pkp",cA]}if((!y(cC)||!cC.length)&&(!y(cz)||!cz.length)){return}if(y(cC)&&cC.length){bp[3]=["_pks",cC]}if(!y(cz)||!cz.length){cz=""}bp[4]=["_pkn",cz]},addEcommerceItem:function(cD,cz,cB,cA,cC){if(cD.length){ck[cD]=[cD,cz,cB,cA,cC]}},trackEcommerceOrder:function(cz,cD,cC,cB,cA,cE){bs(cz,cD,cC,cB,cA,cE)},trackEcommerceCartUpdate:function(cz){a0(cz)}}}function x(){return{push:T}}function b(ad,ac){var ae={};var aa,ab;for(aa=0;aa<ac.length;aa++){var Y=ac[aa];ae[Y]=1;for(ab=0;ab<ad.length;ab++){if(ad[ab]&&ad[ab][0]){var Z=ad[ab][0];if(Y===Z){T(ad[ab]);delete ad[ab];if(ae[Z]>1){if(console!==undefined&&console&&console.error){console.error("The method "+Z+' is registered more than once in "paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')
+}}ae[Z]++}}}}return ad}X(I,"beforeunload",U,false);p();Date.prototype.getTimeAlias=Date.prototype.getTime;N=new F();var t=["disableCookies","setTrackerUrl","setAPIUrl","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","enableLinkTracking"];_paq=b(_paq,t);for(v=0;v<_paq.length;v++){if(_paq[v]){T(_paq[v])}}_paq=new x();d={addPlugin:function(Y,Z){a[Y]=Z},getTracker:function(Y,Z){if(!y(Z)){Z=this.getAsyncTracker().getSiteId()}if(!y(Y)){Y=this.getAsyncTracker().getTrackerUrl()}return new F(Y,Z)},getAsyncTracker:function(){return N}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return d})}return d}())}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);
+c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}};
/*! @license-end */
}; \ No newline at end of file
diff --git a/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js b/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js
index 87b053e980..3c983deca8 100644
--- a/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js
+++ b/plugins/CoreAdminHome/javascripts/jsTrackingGenerator.js
@@ -302,7 +302,7 @@
$('#javascript-text>textarea,#image-tracking-text>textarea').click(function () {
$(this).select();
});
-
+
// initial generation
getSiteData(
$('#js-tracker-website').attr('siteid'),
diff --git a/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig b/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig
index 25d0352733..6d66695552 100644
--- a/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig
+++ b/plugins/CoreAdminHome/templates/trackingCodeGenerator.twig
@@ -75,7 +75,7 @@
{{ 'CoreAdminHome_JSTracking_MergeAliasesDesc'|translate("<span class='current-site-alias'>"~defaultReportSiteAlias~"</span>")|raw }}
</div>
<label class="checkbox">
- <input type="checkbox" id="javascript-tracking-all-aliases"/>
+ <input type="checkbox" checked="checked" id="javascript-tracking-all-aliases"/>
{{ 'CoreAdminHome_JSTracking_MergeAliases'|translate }}
<span class='current-site-name'>{{ defaultReportSiteName|raw }}</span>
</label>
diff --git a/plugins/Referrers/Columns/Base.php b/plugins/Referrers/Columns/Base.php
index 900c7bba63..a7e7eaf1e3 100644
--- a/plugins/Referrers/Columns/Base.php
+++ b/plugins/Referrers/Columns/Base.php
@@ -12,6 +12,8 @@ use Piwik\Common;
use Piwik\Piwik;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\Referrers\SearchEngine AS SearchEngineDetection;
+use Piwik\Plugins\SitesManager\SiteUrls;
+use Piwik\Tracker\Cache;
use Piwik\Tracker\PageUrl;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visit;
@@ -251,20 +253,34 @@ abstract class Base extends VisitDimension
*/
protected function detectReferrerDirectEntry()
{
- if (!empty($this->referrerHost)) {
- // is the referrer host the current host?
- if (isset($this->currentUrlParse['host'])) {
- $currentHost = Common::mb_strtolower($this->currentUrlParse['host'], 'UTF-8');
- if ($currentHost == Common::mb_strtolower($this->referrerHost, 'UTF-8')) {
- $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY;
- return true;
- }
+ if (empty($this->referrerHost)) {
+ return false;
+ }
+
+ $cache = Cache::getCacheGeneral();
+
+ if (!empty($cache['allUrlsByHostAndIdSite'])) {
+ $directEntry = new SiteUrls();
+ $matchingSites = $directEntry->getIdSitesMatchingUrl($this->referrerUrlParse, $cache['allUrlsByHostAndIdSite']);
+
+ if (isset($matchingSites) && is_array($matchingSites) && in_array($this->idsite, $matchingSites)) {
+ $this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY;
+ return true;
+ } elseif (isset($matchingSites)) {
+ return false;
}
- if (Visit::isHostKnownAliasHost($this->referrerHost, $this->idsite)) {
+ }
+
+ // fallback logic if the referrer domain is not known to any site to not break BC
+ if (isset($this->currentUrlParse['host'])) {
+ // this might be actually buggy if first thing tracked is eg an outlink and referrer is from that site
+ $currentHost = Common::mb_strtolower($this->currentUrlParse['host']);
+ if ($currentHost == Common::mb_strtolower($this->referrerHost)) {
$this->typeReferrerAnalyzed = Common::REFERRER_TYPE_DIRECT_ENTRY;
return true;
}
}
+
return false;
}
diff --git a/plugins/Referrers/Columns/Campaign.php b/plugins/Referrers/Columns/Campaign.php
index ff2d5c2401..c29b622336 100644
--- a/plugins/Referrers/Columns/Campaign.php
+++ b/plugins/Referrers/Columns/Campaign.php
@@ -37,7 +37,7 @@ class Campaign extends Base
/**
* If we should create a new visit when the campaign changes, check if the campaign info changed and if so
- * force the tracker to create a new visit.
+ * force the tracker to create a new visit.i
*
* @param Request $request
* @param Visitor $visitor
diff --git a/plugins/Referrers/Referrers.php b/plugins/Referrers/Referrers.php
index ce8667929b..d262c79224 100644
--- a/plugins/Referrers/Referrers.php
+++ b/plugins/Referrers/Referrers.php
@@ -12,6 +12,7 @@ use Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Piwik;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
+use Piwik\Plugins\SitesManager\SiteUrls;
/**
* @see plugins/Referrers/functions.php
@@ -31,9 +32,18 @@ class Referrers extends \Piwik\Plugin
'Insights.addReportToOverview' => 'addReportToInsightsOverview',
'Live.getAllVisitorDetails' => 'extendVisitorDetails',
'Request.getRenamedModuleAndAction' => 'renameDeprecatedModuleAndAction',
+ 'Tracker.setTrackerCacheGeneral' => 'setTrackerCacheGeneral'
);
}
+ public function setTrackerCacheGeneral(&$cacheContent)
+ {
+ $siteUrls = new SiteUrls();
+ $urls = $siteUrls->getAllCachedSiteUrls();
+
+ return $cacheContent['allUrlsByHostAndIdSite'] = $siteUrls->groupUrlsByHost($urls);
+ }
+
public function renameDeprecatedModuleAndAction(&$module, &$action)
{
if($module == 'Referers') {
diff --git a/plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php b/plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php
new file mode 100644
index 0000000000..0d5e0a68ca
--- /dev/null
+++ b/plugins/Referrers/tests/Integration/Columns/ReferrerTypeTest.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\Referrers\tests\Integration\Columns;
+
+use Piwik\Common;
+use Piwik\Plugins\Referrers\Columns\ReferrerType;
+use Piwik\Tests\Framework\Fixture;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+use Piwik\Tracker\Cache;
+use Piwik\Tracker\Request;
+use Piwik\Tracker\Visit\VisitProperties;
+use Piwik\Tracker\Visitor;
+
+/**
+ * @group Referrers
+ * @group ReferrerTypeTest
+ * @group Plugins
+ */
+class ReferrerTypeTest extends IntegrationTestCase
+{
+ /**
+ * @var ReferrerType
+ */
+ private $referrerType;
+ private $idSite1 = 1;
+ private $idSite2 = 2;
+ private $idSite3 = 3;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ Cache::clearCacheGeneral();
+
+ $date = '2012-01-01 00:00:00';
+ $ecommerce = false;
+
+ Fixture::createWebsite($date, $ecommerce, $name = 'test1', $url = 'http://piwik.org/foo/bar');
+ Fixture::createWebsite($date, $ecommerce, $name = 'test2', $url = 'http://piwik.org/');
+ Fixture::createWebsite($date, $ecommerce, $name = 'test3', $url = 'http://piwik.pro/');
+
+ $this->referrerType = new ReferrerType();
+ }
+
+ public function tearDown()
+ {
+ // clean up your test here if needed
+ Cache::clearCacheGeneral();
+
+ parent::tearDown();
+ }
+
+ /**
+ * @dataProvider getReferrerUrls
+ */
+ public function test_onNewVisit_shouldDetectCorrectReferrerType($expectedType, $idSite, $url, $referrerUrl)
+ {
+ $request = $this->getRequest(array('idsite' => $idSite, 'url' => $url, 'urlref' => $referrerUrl));
+ $type = $this->referrerType->onNewVisit($request, $this->getNewVisitor(), $action = null);
+
+ $this->assertSame($expectedType, $type);
+ }
+
+ public function getReferrerUrls()
+ {
+ $url = 'http://piwik.org/foo/bar';
+ $referrer = 'http://piwik.org';
+
+ // $expectedType, $idSite, $url, $referrerUrl
+ return array(
+ // domain matches but path does not match for idsite1
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite1, $url, $referrer),
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite1, $url, $referrer . '/'),
+ // idSite2 matches any piwik.org path so this is a direct entry for it
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite2, $url, $referrer),
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite2, $url, $referrer . '/'),
+ // idSite3 has different domain so it is coming from different website
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, $url, $referrer),
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, $url, $referrer . '/'),
+
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite1, $url, $referrer . '/foo/bar/baz'),
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite1, $url, $referrer . '/foo/bar/baz/'),
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite1, $url, $referrer . '/foo/bar/baz?x=5'),
+ // /not/xyz belongs to different website
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite1, $url, $referrer . '/not/xyz'),
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite2, $url, $referrer . '/not/xyz'),
+
+ // /foo/bar/baz belongs to different website
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite2, $url, $referrer . '/foo/bar/baz'),
+
+ // website as it is from different domain anyway
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, $url, $referrer . '/foo/bar/baz'),
+
+ // should detect campaign independent of domain / path
+ array(Common::REFERRER_TYPE_CAMPAIGN, $this->idSite1, $url . '?pk_campaign=test', $referrer),
+ array(Common::REFERRER_TYPE_CAMPAIGN, $this->idSite2, $url . '?pk_campaign=test', $referrer),
+ array(Common::REFERRER_TYPE_CAMPAIGN, $this->idSite3, $url . '?pk_campaign=test', $referrer),
+
+ array(Common::REFERRER_TYPE_SEARCH_ENGINE, $this->idSite3, $url, 'http://google.com/search?q=piwik'),
+
+ // testing case for backwards compatibility where url has same domain as urlref but the domain is not known to any website
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite3, 'http://example.com/foo', 'http://example.com/bar'),
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite3, 'http://example.com/foo', 'http://example.com'),
+ array(Common::REFERRER_TYPE_DIRECT_ENTRY, $this->idSite3, 'http://example.com', 'http://example.com/bar'),
+
+ // testing case where domain of referrer is not known to any site but neither is the URL, url != urlref
+ array(Common::REFERRER_TYPE_WEBSITE, $this->idSite3, 'http://example.org', 'http://example.com/bar'),
+ );
+ }
+
+ private function getRequest($params)
+ {
+ return new Request($params);
+ }
+
+ private function getNewVisitor()
+ {
+ return new Visitor(new VisitProperties());
+ }
+
+}
diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php
index 9a6bf63469..739af7d5e9 100644
--- a/plugins/SitesManager/API.php
+++ b/plugins/SitesManager/API.php
@@ -645,6 +645,7 @@ class API extends \Piwik\Plugin\API
{
Site::clearCache();
Cache::regenerateCacheWebsiteAttributes($idSite);
+ Cache::clearCacheGeneral();
SiteUrls::clearSitesCache();
}
diff --git a/plugins/SitesManager/Model.php b/plugins/SitesManager/Model.php
index 93ddb01d8f..96062b608a 100644
--- a/plugins/SitesManager/Model.php
+++ b/plugins/SitesManager/Model.php
@@ -286,6 +286,22 @@ class Model
return $urls;
}
+ /**
+ * Returns the list of alias URLs registered for the given idSite.
+ * The website ID must be valid when calling this method!
+ *
+ * @param int $idSite
+ * @return array list of alias URLs
+ */
+ public function getAllKnownUrlsForAllSites()
+ {
+ $db = $this->getDb();
+ $mainUrls = $db->fetchAll("SELECT idsite, main_url as url FROM " . Common::prefixTable("site"));
+ $aliasUrls = $db->fetchAll("SELECT idsite, url FROM " . Common::prefixTable("site_url"));
+
+ return array_merge($mainUrls, $aliasUrls);
+ }
+
public function updateSite($site, $idSite)
{
$idSite = (int) $idSite;
diff --git a/plugins/SitesManager/SiteUrls.php b/plugins/SitesManager/SiteUrls.php
index a1fac67a89..059521a4a9 100644
--- a/plugins/SitesManager/SiteUrls.php
+++ b/plugins/SitesManager/SiteUrls.php
@@ -9,6 +9,7 @@
namespace Piwik\Plugins\SitesManager;
use Piwik\Cache;
+use Piwik\Common;
class SiteUrls
{
@@ -19,6 +20,96 @@ class SiteUrls
self::getCache()->delete(self::$cacheId);
}
+ /**
+ * Groups all URLs by host, path and idsite.
+ *
+ * @param array $urls An array containing URLs by idsite,
+ * eg array(array($idSite = 1 => array('apache.piwik', 'apache2.piwik'), 2 => array(), ...))
+ * as returned by {@link getAllCachedSiteUrls()} and {@link getAllSiteUrls}
+ * @return array All urls grouped by host => path => idSites. Path having the most '/' will be listed first
+ * array(
+ 'apache.piwik' => array(
+ '/test/two' => $idsite = array(3),
+ '/test' => $idsite = array(1),
+ '/' => $idsite = array(2),
+ ),
+ 'test.apache.piwik' => array(
+ '/test/two' => $idsite = array(3),
+ '/test' => $idsite = array(1),
+ '/' => $idsite = array(2, 3),
+ ),
+ );
+ */
+ public function groupUrlsByHost($siteUrls)
+ {
+ if (empty($siteUrls)) {
+ return array();
+ }
+
+ $allUrls = array();
+
+ foreach ($siteUrls as $idSite => $urls) {
+ $idSite = (int) $idSite;
+ foreach ($urls as $url) {
+ $urlParsed = @parse_url($url);
+
+ if ($urlParsed === false || !isset($urlParsed['host'])) {
+ continue;
+ }
+
+ $host = $this->toCanonicalHost($urlParsed['host']);
+ $path = $this->getCanonicalPathFromParsedUrl($urlParsed);
+
+ if (!isset($allUrls[$host])) {
+ $allUrls[$host] = array();
+ }
+
+ if (!isset($allUrls[$host][$path])) {
+ $allUrls[$host][$path] = array();
+ }
+
+ if (!in_array($idSite, $allUrls[$host][$path])) {
+ $allUrls[$host][$path][] = $idSite;
+ }
+ }
+ }
+
+ foreach ($allUrls as $host => $paths) {
+ uksort($paths, array($this, 'sortByPathDepth'));
+ $allUrls[$host] = $paths;
+ }
+
+ return $allUrls;
+ }
+
+ public function getIdSitesMatchingUrl($parsedUrl, $urlsGroupedByHost)
+ {
+ if (empty($parsedUrl['host'])) {
+ return null;
+ }
+
+ $urlHost = $this->toCanonicalHost($parsedUrl['host']);
+ $urlPath = $this->getCanonicalPathFromParsedUrl($parsedUrl);
+
+ $matchingSites = null;
+ if (isset($urlsGroupedByHost[$urlHost])) {
+ $paths = $urlsGroupedByHost[$urlHost];
+
+ foreach ($paths as $path => $idSites) {
+ if (0 === strpos($urlPath, $path)) {
+ $matchingSites = $idSites;
+ break;
+ }
+ }
+
+ if (!isset($matchingSites) && isset($paths['/'])) {
+ $matchingSites = $paths['/'];
+ }
+ }
+
+ return $matchingSites;
+ }
+
public function getAllCachedSiteUrls()
{
$cache = $this->getCache();
@@ -35,23 +126,66 @@ class SiteUrls
public function getAllSiteUrls()
{
$model = new Model();
- $siteIds = $model->getSitesId();
- $siteUrls = array();
+ $siteUrls = $model->getAllKnownUrlsForAllSites();
- if (empty($siteIds)) {
+ if (empty($siteUrls)) {
return array();
}
- foreach ($siteIds as $siteId) {
- $siteId = (int) $siteId;
- $siteUrls[$siteId] = $model->getSiteUrlsFromId($siteId);
+ $urls = array();
+ foreach ($siteUrls as $siteUrl) {
+ $siteId = (int) $siteUrl['idsite'];
+
+ if (!isset($urls[$siteId])) {
+ $urls[$siteId] = array();
+ }
+
+ $urls[$siteId][] = $siteUrl['url'];
}
- return $siteUrls;
+ return $urls;
}
private static function getCache()
{
return Cache::getLazyCache();
}
+
+ private function sortByPathDepth($pathA, $pathB)
+ {
+ // list first the paths with most '/' , and list path = '/' last
+ $numSlashA = substr_count($pathA, '/');
+ $numSlashB = substr_count($pathB, '/');
+
+ if ($numSlashA === $numSlashB) {
+ return -1 * strcmp($pathA, $pathB);
+ }
+
+ return $numSlashA > $numSlashB ? -1 : 1;
+ }
+
+ private function toCanonicalHost($host)
+ {
+ $host = Common::mb_strtolower($host);
+ if (strpos($host, 'www.') === 0) {
+ $host = substr($host, 4);
+ }
+
+ return $host;
+ }
+
+ private function getCanonicalPathFromParsedUrl($urlParsed)
+ {
+ $path = '/';
+
+ if (isset($urlParsed['path'])) {
+ $path = Common::mb_strtolower($urlParsed['path']);
+ if (!Common::stringEndsWith($path, '/')) {
+ $path .= '/';
+ }
+ }
+
+ return $path;
+ }
+
}
diff --git a/plugins/SitesManager/tests/Integration/ModelTest.php b/plugins/SitesManager/tests/Integration/ModelTest.php
index 45ebce2be8..7291ac346f 100644
--- a/plugins/SitesManager/tests/Integration/ModelTest.php
+++ b/plugins/SitesManager/tests/Integration/ModelTest.php
@@ -56,10 +56,56 @@ class ModelTest extends IntegrationTestCase
$this->assertSame(array('website', 'universal', 'mobileapp'), $this->model->getUsedTypeIds());
}
- private function createMeasurable($type)
+ public function test_getAllKnownUrlsForAllSites_shouldReturnAllUrls()
{
- Fixture::createWebsite('2015-01-01 00:00:00',
- $ecommerce = 0, $siteName = false, $siteUrl = false,
+ $idSite = $this->createMeasurable('website', 'http://apache.piwik');
+ $this->model->insertSiteUrl($idSite, 'http://example.apache.piwik');
+ $this->model->insertSiteUrl($idSite, 'http://example.org');
+
+ $idSite2 = $this->createMeasurable('website');
+ $this->model->insertSiteUrl($idSite2, 'http://example.org');
+ $this->model->insertSiteUrl($idSite2, 'http://example.com');
+
+ $idSite3 = $this->createMeasurable('website', 'http://example.pro');
+
+ $expected = array(
+ array(
+ 'idsite' => $idSite,
+ 'url' => 'http://apache.piwik'
+ ),
+ array(
+ 'idsite' => $idSite2,
+ 'url' => 'http://piwik.net'
+ ),
+ array(
+ 'idsite' => $idSite3,
+ 'url' => 'http://example.pro'
+ ),
+ array(
+ 'idsite' => $idSite,
+ 'url' => 'http://example.apache.piwik'
+ ),
+ array(
+ 'idsite' => $idSite,
+ 'url' => 'http://example.org'
+ ),
+ array(
+ 'idsite' => $idSite2,
+ 'url' => 'http://example.com'
+ ),
+ array(
+ 'idsite' => $idSite2,
+ 'url' => 'http://example.org'
+ )
+
+ );
+ $this->assertEquals($expected, $this->model->getAllKnownUrlsForAllSites());
+ }
+
+ private function createMeasurable($type, $siteUrl = false)
+ {
+ return Fixture::createWebsite('2015-01-01 00:00:00',
+ $ecommerce = 0, $siteName = false, $siteUrl,
$siteSearch = 1, $searchKeywordParameters = null,
$searchCategoryParameters = null, $timezone = null, $type);
}
diff --git a/plugins/SitesManager/tests/Integration/SiteUrlsTest.php b/plugins/SitesManager/tests/Integration/SiteUrlsTest.php
index f9362ae2f4..39d628197e 100644
--- a/plugins/SitesManager/tests/Integration/SiteUrlsTest.php
+++ b/plugins/SitesManager/tests/Integration/SiteUrlsTest.php
@@ -119,6 +119,130 @@ class SiteUrlsTest extends IntegrationTestCase
$this->assertEquals($urlsToFake, $actual);
}
+ public function test_groupUrlsByHost_shouldReturnEmptyArray_WhenNoUrlsGiven()
+ {
+ $this->assertSame(array(), $this->siteUrls->groupUrlsByHost(array()));
+ $this->assertSame(array(), $this->siteUrls->groupUrlsByHost(null));
+ }
+
+ public function test_groupUrlsByHost_shouldGroupByHost_WithOneSiteAndDifferentDomains_shouldRemoveWwwAndDefaultToPathSlash()
+ {
+ $idSite = 1;
+ $oneSite = array(
+ $idSite => array(
+ 'http://apache.piwik',
+ 'http://www.example.com', // should remove www.
+ 'https://example.org', // should handle https or other protocol
+ 'http://apache.piwik/', // same as initial one but with slash at the end, should not add idsite twice
+ 'http://third.www.com' // should not remove www. in the middle of a domain
+ )
+ );
+
+ $expected = array(
+ 'apache.piwik' => array('/' => array($idSite)),
+ 'example.com' => array('/' => array($idSite)),
+ 'example.org' => array('/' => array($idSite)),
+ 'third.www.com' => array('/' => array($idSite)),
+ );
+
+ $this->assertSame($expected, $this->siteUrls->groupUrlsByHost($oneSite));
+ }
+
+ public function test_groupUrlsByHost_shouldGroupByHost_WithDifferentDomainsAndPathsShouldListPathByNumberOfDirectoriesAndConvertToLowerCase()
+ {
+ $idSite = 1;
+ $idSite2 = 2;
+ $idSite3 = 3;
+ $idSite4 = 4;
+ $idSite5 = 5;
+
+ $urls = array(
+ $idSite => array(
+ 'http://apache.piwik/test', 'http://apache.piWik', 'http://apache.piwik/foo/bAr/', 'http://apache.piwik/Foo/SECOND'
+ ),
+ $idSite2 => array(
+ 'http://apache.piwik/test/', 'http://example.oRg', 'http://apache.piwik/foo/secOnd'
+ ),
+ $idSite3 => array(
+ 'http://apache.piwik/', 'http://apache.piwik/third', 'http://exampLe.com', 'http://example.org/foo/test/two'
+ ),
+ $idSite4 => array(),
+ $idSite5 => array('invalidUrl', 'ftp://example.org/'),
+ );
+
+ $expected = array(
+ 'apache.piwik' => array(
+ '/foo/second/' => array($idSite, $idSite2),
+ '/foo/bar/' => array($idSite),
+ '/third/' => array($idSite3),
+ '/test/' => array($idSite, $idSite2),
+ '/' => array($idSite, $idSite3)
+ ),
+ 'example.org' => array(
+ '/foo/test/two/' => array($idSite3),
+ '/' => array($idSite2, $idSite5)
+ ),
+ 'example.com' => array(
+ '/' => array($idSite3)
+ ),
+ );
+
+ $this->assertSame($expected, $this->siteUrls->groupUrlsByHost($urls));
+ }
+
+ /**
+ * @dataProvider getTestIdSitesMatchingUrl
+ */
+ public function test_getIdSitesMatchingUrl($expectedMatchSites, $parsedUrl)
+ {
+ $urlsGroupedByHost = array(
+ 'apache.piwik' => array(
+ '/foo/second/' => array(2),
+ '/foo/sec/' => array(4),
+ '/foo/bar/' => array(1),
+ '/third/' => array(3),
+ '/test/' => array(1, 2),
+ '/' => array(1, 3)
+ ),
+ 'example.org' => array(
+ '/foo/test/two/' => array(3),
+ '/foo/second/' => array(6),
+ '/' => array(2, 5)
+ ),
+ 'example.com' => array(
+ '/' => array(3)
+ ),
+ );
+ $matchedSites = $this->siteUrls->getIdSitesMatchingUrl($parsedUrl, $urlsGroupedByHost);
+
+ $this->assertSame($expectedMatchSites, $matchedSites);
+ }
+
+ public function getTestIdSitesMatchingUrl()
+ {
+ return array(
+ array(array(1,3), array('host' => 'apache.piwik')),
+ array(array(1,3), array('host' => 'apache.piwik', 'path' => '/')),
+ array(array(1,3), array('host' => 'apache.piwik', 'path' => 'nomatch')), // no other URL matches a site so we fall back to domain match
+ array(array(1,3), array('host' => 'apache.piwik', 'path' => '/nomatch')),
+ array(array(2), array('host' => 'apache.piwik', 'path' => '/foo/second')),
+ array(array(2), array('host' => 'apache.piwik', 'path' => '/foo/second/')), // it shouldn't matter if slash is at end or not
+ array(array(2), array('host' => 'apache.piwik', 'path' => '/foo/second/test')), // it should find best match
+ array(array(4), array('host' => 'apache.piwik', 'path' => '/foo/sec/test')), // it should not use /foo/second for these
+ array(array(4), array('host' => 'apache.piwik', 'path' => '/foo/sec/')),
+ array(array(4), array('host' => 'apache.piwik', 'path' => '/foo/sec')),
+ array(array(1,3), array('host' => 'apache.piwik', 'path' => '/foo')),
+ array(array(2,5), array('host' => 'example.org')),
+ array(array(2,5), array('host' => 'example.org', 'path' => '/')),
+ array(array(2,5), array('host' => 'example.org', 'path' => 'any/nonmatching/path')),
+ array(array(6), array('host' => 'example.org', 'path' => '/foo/second')),
+ array(array(6), array('host' => 'example.org', 'path' => '/foo/second/test')),
+ array(array(3), array('host' => 'example.com')),
+ array(null, array('host' => 'example.pro')),
+ array(null, array('host' => 'example.pro', 'path' => '/any')),
+ );
+ }
+
private function assertSiteUrls($expectedUrls)
{
$urls = $this->siteUrls->getAllSiteUrls();
diff --git a/tests/javascript/enable_sqlite b/tests/javascript/enable_sqlite
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/javascript/enable_sqlite
diff --git a/tests/javascript/index.php b/tests/javascript/index.php
index 71a125eb0c..60d7f11558 100644
--- a/tests/javascript/index.php
+++ b/tests/javascript/index.php
@@ -2242,12 +2242,48 @@ function PiwikTest() {
}
});
- test("Tracker setDomains() and isSiteHostName()", function() {
- expect(13);
+ test("Tracker setDomains(), isSiteHostName(), isSiteHostPath(), findConfigCookiePathToUse() and getLinkIfShouldBeProcessed()", function() {
+ expect(117);
var tracker = Piwik.getTracker();
+ var initialDomains = tracker.getDomains();
+ var domainAlias = initialDomains[0];
equal( typeof tracker.hook.test._isSiteHostName, 'function', "isSiteHostName" );
+ equal( typeof tracker.hook.test._isSiteHostPath, 'function', "isSiteHostPath" );
+ equal( typeof tracker.hook.test._getLinkIfShouldBeProcessed, 'function', "getLinkIfShouldBeProcessed" );
+ equal( typeof tracker.hook.test._findConfigCookiePathToUse, 'function', "findConfigCookiePathToUse" );
+
+ var isSiteHostName = tracker.hook.test._isSiteHostName;
+ var isSiteHostPath = tracker.hook.test._isSiteHostPath;
+ var getLinkIfShouldBeProcessed = tracker.hook.test._getLinkIfShouldBeProcessed;
+ var findConfigCookiePathToUse = tracker.hook.test._findConfigCookiePathToUse;
+
+ // tracker.setDomain()
+
+ // test wildcards
+ tracker.setDomains( ['*.Example.com'] );
+ propEqual(["*.Example.com", domainAlias], tracker.getDomains()), 'should add domainAlias';
+
+ tracker.setDomains( '*.Example.org' );
+ propEqual(["*.Example.org", domainAlias], tracker.getDomains()), 'should handle a string';
+
+ tracker.setDomains( ['*.Example.com', '*.example.ORG'] );
+ propEqual(["*.Example.com", '*.example.ORG', domainAlias], tracker.getDomains()), 'should be able to set many domains';
+
+ tracker.setDomains( [] );
+ propEqual([domainAlias], tracker.getDomains()), 'setting an empty array should reset the list';
+
+ tracker.setDomains( ['*.Example.com', domainAlias + '/path', '*.example.ORG'] );
+ propEqual(['*.Example.com', domainAlias + '/path', '*.example.ORG'], tracker.getDomains()), 'if domain alias is already given should not add domainAlias';
+
+ tracker.setDomains( ['.' + domainAlias + '/path'] );
+ propEqual(['.' + domainAlias + '/path'], tracker.getDomains()), 'if domain alias with subdomain is already given should not add domainAlias';
+
+
+ /**
+ * isSiteHostName ()
+ */
// test wildcards
tracker.setDomains( ['*.Example.com'] );
@@ -2255,21 +2291,171 @@ function PiwikTest() {
// skip test if testing on localhost
ok( window.location.hostname != 'localhost' ? !tracker.hook.test._isSiteHostName('localhost') : true, '!isSiteHostName("localhost")' );
- ok( !tracker.hook.test._isSiteHostName('google.com'), '!isSiteHostName("google.com")' );
- ok( tracker.hook.test._isSiteHostName('example.com'), 'isSiteHostName("example.com")' );
- ok( tracker.hook.test._isSiteHostName('www.example.com'), 'isSiteHostName("www.example.com")' );
- ok( tracker.hook.test._isSiteHostName('www.sub.example.com'), 'isSiteHostName("www.sub.example.com")' );
+ ok( !isSiteHostName('google.com'), '!isSiteHostName("google.com")' );
+ ok( isSiteHostName('example.com'), 'isSiteHostName("example.com")' );
+ ok( isSiteHostName('www.example.com'), 'isSiteHostName("www.example.com")' );
+ ok( isSiteHostName('www.sub.example.com'), 'isSiteHostName("www.sub.example.com")' );
tracker.setDomains( 'dev.piwik.org' );
- ok( !tracker.hook.test._isSiteHostName('piwik.org'), '!isSiteHostName("piwik.org")' );
- ok( tracker.hook.test._isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' );
- ok( !tracker.hook.test._isSiteHostName('piwik.example.org'), '!isSiteHostName("piwik.example.org")');
- ok( !tracker.hook.test._isSiteHostName('dev.piwik.org.com'), '!isSiteHostName("dev.piwik.org.com")');
+ ok( !isSiteHostName('piwik.org'), '!isSiteHostName("piwik.org")' );
+ ok( isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' );
+ ok( !isSiteHostName('piwik.example.org'), '!isSiteHostName("piwik.example.org")');
+ ok( !isSiteHostName('dev.piwik.org.com'), '!isSiteHostName("dev.piwik.org.com")');
tracker.setDomains( '.piwik.org' );
- ok( tracker.hook.test._isSiteHostName('piwik.org'), 'isSiteHostName("piwik.org")' );
- ok( tracker.hook.test._isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' );
- ok( !tracker.hook.test._isSiteHostName('piwik.org.com'), '!isSiteHostName("piwik.org.com")');
+ ok( isSiteHostName('piwik.org'), 'isSiteHostName("piwik.org")' );
+ ok( isSiteHostName('dev.piwik.org'), 'isSiteHostName("dev.piwik.org")' );
+ ok( !isSiteHostName('piwik.org.com'), '!isSiteHostName("piwik.org.com")');
+
+ /**
+ * isSiteHostPath ()
+ */
+
+ // with path
+ tracker.setDomains( '.piwik.org/path' );
+ ok( isSiteHostPath('piwik.org', '/path'), 'isSiteHostPath("piwik.org", "/path")' );
+ ok( isSiteHostPath('piwik.org', '/path/'), 'isSiteHostPath("piwik.org", "/path/")' );
+ ok( isSiteHostPath('piwik.org', '/path/test'), 'isSiteHostPath("piwik.org", "/path/test)' );
+ ok( isSiteHostPath('dev.piwik.org', '/path'), 'isSiteHostPath("dev.piwik.org", "/path")' );
+ ok( !isSiteHostPath('piwik.org', '/pat'), '!isSiteHostPath("piwik.org", "/pat")');
+ ok( !isSiteHostPath('piwik.org', '.com'), '!isSiteHostPath("piwik.org", ".com")');
+ ok( !isSiteHostPath('piwik.com', '/path'), '!isSiteHostPath("piwik.com", "/path")');
+ ok( !isSiteHostPath('piwik.com', '/path/test'), '!isSiteHostPath("piwik.com", "/path/test")');
+ ok( !isSiteHostPath('piwik.com', ''), '!isSiteHostPath("piwik.com", "/path/test")');
+
+ // no path
+ var domains = ['.piwik.org', 'piwik.org', '*.piwik.org', '.piwik.org/'];
+ for (var i in domains) {
+ var domain = domains[i];
+ tracker.setDomains( domain );
+ ok( isSiteHostPath('piwik.org', '/path'), 'isSiteHostPath("piwik.org", "/path"), domain: ' + domain );
+ ok( isSiteHostPath('piwik.org', '/path/'), 'isSiteHostPath("piwik.org", "/path/"), domain: ' + domain );
+ ok( isSiteHostPath('piwik.org', '/path/test'), 'isSiteHostPath("piwik.org", "/path/test), domain: ' + domain );
+
+ if (domain === 'piwik.org') {
+ ok( !isSiteHostPath('dev.piwik.org', '/path'), 'isSiteHostPath("dev.piwik.org", "/path"), domain: ' + domain );
+ } else {
+ ok( isSiteHostPath('dev.piwik.org', '/path'), 'isSiteHostPath("dev.piwik.org", "/path"), domain: ' + domain );
+ }
+ ok( isSiteHostPath('piwik.org', '/pat'), '!isSiteHostPath("piwik.org", "/pat"), domain: ' + domain );
+ ok( isSiteHostPath('piwik.org', '.com'), '!isSiteHostPath("piwik.org", ".com"), domain: ' + domain);
+ ok( isSiteHostPath('piwik.org', '/foo'), '!isSiteHostPath("piwik.com", "/foo"), domain: ' + domain);
+ ok( !isSiteHostPath('piwik.com', '/path'), '!isSiteHostPath("piwik.com", "/path"), domain: ' + domain);
+ ok( !isSiteHostPath('piwik.com', '/path/test'), '!isSiteHostPath("piwik.com", "/path/test"), domain: ' + domain);
+ ok( !isSiteHostPath('piwik.com', ''), '!isSiteHostPath("piwik.com", "/path/test"), domain: ' + domain);
+ }
+
+ // multiple paths / domains
+ tracker.setDomains( ['piwik.org/path', 'piwik.org/foo', 'piwik.org/bar/baz', '.piwik.pro/test'] );
+ ok( isSiteHostPath('piwik.pro', '/test/bar'), 'isSiteHostPath("piwik.pro", "/test/bar")' );
+ ok( !isSiteHostPath('piwik.org', '/foobar/'), 'isSiteHostPath("piwik.org", "/foobar/")' );
+ ok( isSiteHostPath('piwik.org', '/foo/bar'), 'isSiteHostPath("piwik.org", "/foo/bar")' );
+ ok( isSiteHostPath('piwik.org', '/bar/baz/foo'), 'isSiteHostPath("piwik.org", "/bar/baz/foo/")' );
+ ok( !isSiteHostPath('piwik.org', '/bar/ba'), 'isSiteHostPath("piwik.org", "/bar/ba")' );
+ ok( isSiteHostPath('piwik.org', '/path/test'), 'isSiteHostPath("piwik.org", "/path/test)' );
+ ok( isSiteHostPath('dev.piwik.pro', '/test'), 'isSiteHostPath("dev.piwik.pro", "/test")' );
+ ok( !isSiteHostPath('dev.piwik.pro', '/'), 'isSiteHostPath("dev.piwik.pro", "/")' );
+ ok( !isSiteHostPath('piwik.pro', '/'), 'isSiteHostPath("piwik.pro", "/")' );
+ ok( !isSiteHostPath('piwik.org', '/'), 'isSiteHostPath("piwik.org", "/")' );
+ ok( !isSiteHostPath('piwik.org', '/anythingelse'), 'isSiteHostPath("piwik.org", "/anythingelse")' );
+
+ // all is compared lower case
+ tracker.setDomains( '.piwik.oRg/PaTh' );
+ ok( isSiteHostPath('piwiK.org', '/pAth'), 'isSiteHostPath("piwik.org", "/path")' );
+ ok( isSiteHostPath('piwik.org', '/patH/'), 'isSiteHostPath("piwik.org", "/path/")' );
+ ok( isSiteHostPath('Piwik.ORG', '/PATH/TEST'), 'isSiteHostPath("piwik.org", "/path/test)' );
+
+ /**
+ * getLinkIfShouldBeProcessed ()
+ */
+ var getLinkIfShouldBeProcessed = tracker.hook.test._getLinkIfShouldBeProcessed;
+ function createLink(url) {
+ var link = document.createElement('a');
+ link.href = url;
+ return link;
+ }
+
+ tracker.setDomains( ['.piwik.org/path', '.piwik.org/foo', '.piwik.org/bar/baz', '.piwik.pro/test'] );
+
+ // they should not be detected as outlink as they match one of the domains
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed http://www.piwik.org/foo/bar matches .piwik.org/foo')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed http://piwik.org/foo/bar matches .piwik.org/foo')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed missing protocol only domain given')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('//piwik.org/foo/bar')), 'getLinkIfShouldBeProcessed no protcol but url starts with //')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo?x=1')), 'getLinkIfShouldBeProcessed url with query parameter should detect correct path')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo')), 'getLinkIfShouldBeProcessed path is same as allowed path')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo/')), 'getLinkIfShouldBeProcessed path is same as allowed path but with appended slash')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz/')), 'getLinkIfShouldBeProcessed multiple directories with appended slash')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz')), 'getLinkIfShouldBeProcessed multiple directories')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://WWW.PIWIK.ORG/BAR/BAZ')), 'getLinkIfShouldBeProcessed should test everything lowercase')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz/x/y/z')), 'getLinkIfShouldBeProcessed many appended paths')
+ equal(undefined, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar/baz?test=1&foo=bar')), 'getLinkIfShouldBeProcessed another test with query parameter and multiple directories')
+ propEqual({
+ "href": "http://www.piwik.org/foo/download.apk",
+ "type": "download"
+ }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foo/download.apk')), 'getLinkIfShouldBeProcessed should detect download even if it is link to same domain')
+ propEqual({
+ "href": "http://www.piwik.org/foobar/download.apk",
+ "type": "download"
+ }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/foobar/download.apk')), 'getLinkIfShouldBeProcessed should detect download even if it goes to different domain/path')
+ propEqual({
+ "href": "http://www.piwik.com/foobar/download.apk",
+ "type": "download"
+ }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.com/foobar/download.apk')), 'getLinkIfShouldBeProcessed should detect download even if it goes to different domain')
+ propEqual({
+ "href": "http://www.piwik.pro/foo/",
+ "type": "link"
+ }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.pro/foo/')), 'getLinkIfShouldBeProcessed path matches but domain not so outlink')
+ propEqual({
+ "href": "http://www.piwik.org/bar",
+ "type": "link"
+ }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/bar')), 'getLinkIfShouldBeProcessed domain matches but path not so outlink')
+ propEqual({
+ "href": "http://www.piwik.org/footer",
+ "type": "link"
+ }, getLinkIfShouldBeProcessed(createLink('http://www.piwik.org/footer')), 'getLinkIfShouldBeProcessed http://www.piwik.org/footer and there is domain piwik.org/foo but it should be outlink as path is different')
+
+
+ /**
+ * findConfigCookiePathToUse ()
+ */
+
+ tracker.setDomains( ['.piwik.org', '.piwik.pro/foo/bar', '.piwik.pro/foo', '.piwik.com/test/foo', 'example.com/foo'] );
+
+ equal(null, findConfigCookiePathToUse('.piwik.org/test', 'http://piwik.org/test/two'), 'findConfigCookiePathToUse no cookiePath because there is a domain alias given allowing them all');
+ equal('/foo', findConfigCookiePathToUse('.piwik.pro/foo', 'http://piwik.pro/foo/bar/test'), 'findConfigCookiePathToUse should find a match');
+ equal('/foo', findConfigCookiePathToUse('.piwik.pro/foo/bar/test', 'http://piwik.pro/foo/bar/test'), 'findConfigCookiePathToUse should find a less restrictive path automatically');
+ equal('/foo', findConfigCookiePathToUse('.piwik.pro/foo/bar/test', 'http://piwik.pro/foo'), 'findConfigCookiePathToUse should find a less restrictive path automatically, urlPath===domainPath');
+ equal('/test/bar/test', findConfigCookiePathToUse('.piwik.com/test/bar/test', 'http://piwik.com/test/bar/test/'), 'findConfigCookiePathToUse should use exactly given path if no less restrictive version is available');
+ equal('/test/foo', findConfigCookiePathToUse('.piwik.com/test/foo/test', 'http://piwik.com/test/foo/test'), 'findConfigCookiePathToUse should find a less restrictive path automatically, configAlias === currentUrl');
+ equal('/test/foo', findConfigCookiePathToUse('.piwik.com/test/foo', 'http://piwik.com/test/foo/test'), 'findConfigCookiePathToUse should find a less restrictive path automatically');
+ equal(null, findConfigCookiePathToUse('.piwik.pro/foo', 'http://piwik.pro/test'), 'findConfigCookiePathToUse should not return a path when user is actually not on that path');
+ equal(null, findConfigCookiePathToUse('.piwik.pro/foo', 'http://piwik.pro'), 'findConfigCookiePathToUse when there is no path set we cannot use a configPath');
+
+ /**
+ * Test sets a good cookie path automatically
+ */
+ tracker.setCookiePath(null);
+ tracker.setDomains( ['.' + domainAlias + '/tests'] );
+ equal('/tests', tracker.getConfigCookiePath()), 'should set a cookie path automatically';
+
+ tracker.setCookiePath(null);
+ tracker.setDomains( ['.' + domainAlias + '/tests/javascript'] );
+ equal('/tests/javascript', tracker.getConfigCookiePath()), 'should set a cookie path automatically, multiple directories';
+
+ tracker.setCookiePath(null);
+ tracker.setDomains( ['.' + domainAlias + '/tests/javascript', '.' + domainAlias + '/tests'] );
+ equal('/tests', tracker.getConfigCookiePath()), 'should find shortest path for possible cookie path';
+
+ tracker.setCookiePath(null);
+ tracker.setDomains( ['.' + domainAlias + '/tests/javascript', '.example.com/tests'] );
+ equal('/tests/javascript', tracker.getConfigCookiePath()), 'should not find a shorter path when no other domain matches';
+
+ tracker.setCookiePath(null);
+ tracker.setDomains( ['.' + domainAlias + '/another/one', '.example.org/tests/javascript', '.example.com/tests'] );
+ equal(null, tracker.getConfigCookiePath()), 'should not set a path when no domain and no path matches';
+
+ tracker.setCookiePath(null);
});
test("Tracker getClassesRegExp()", function() {
diff --git a/tests/javascript/piwiktest.js b/tests/javascript/piwiktest.js
index 415bd57d8a..67157c6d96 100644
--- a/tests/javascript/piwiktest.js
+++ b/tests/javascript/piwiktest.js
@@ -20,11 +20,14 @@ Piwik.addPlugin('testPlugin', {
'_isObject : isObject,' +
'_isString : isString,' +
'_isSiteHostName : isSiteHostName,' +
+ '_isSiteHostPath : isSiteHostPath,' +
'_getClassesRegExp : getClassesRegExp,' +
'_hasCookies : hasCookies,' +
'_getCookie : getCookie,' +
'_getCookieName : getCookieName,' +
'_setCookie : setCookie,' +
+ '_getLinkIfShouldBeProcessed : getLinkIfShouldBeProcessed,' +
+ '_findConfigCookiePathToUse : findConfigCookiePathToUse,' +
'_encode : encodeWrapper,' +
'_decode : decodeWrapper,' +
'_urldecode : urldecode,' +