1//global vars 2var pl = { 3 fontLoadState: 1, 4 locMarkers: [] 5}; 6 7//youtube tracking installed at window level - needs to be activated at closing body tag 8 9var gtmYTListeners = []; // support multiple players on the same page 10// attach our YT listener once the API is loaded 11function onYouTubeIframeAPIReady() { 12 for (var e = document.getElementsByTagName("iframe"), x = e.length; x--;) { 13 if (/youtube.com\/embed/.test(e[x].src)) { 14 gtmYTListeners.push(new YT.Player(e[x], { 15 events: { 16 onStateChange: onPlayerStateChange, 17 onError: onPlayerError 18 } 19 })); 20 YT.gtmLastAction = "p"; 21 } 22 } 23} 24 25function onYouTubeIframePlayerAdded(ifrm) { 26 gtmYTListeners.push(new YT.Player(ifrm, { 27 events: { 28 onStateChange: onPlayerStateChange, 29 onError: onPlayerError 30 } 31 })); 32 YT.gtmLastAction = "p"; 33} 34 35// listen for play/pause, other states such as rewind and end could also be added 36// also report % played every second 37function onPlayerStateChange(e) { 38 e["data"] == YT.PlayerState.PLAYING && setTimeout(onPlayerPercent, 1000, e["target"]); 39 var video_data = e.target["getVideoData"](), 40 ytLabel = video_data.title + ' (youtube.com/watch?v=' + video_data.video_id + ')'; 41 if (e["data"] == YT.PlayerState.PLAYING && YT.gtmLastAction == "p") { 42 dataLayer.push({ 43 event: "YouTube", 44 ytAction: "Play", 45 ytLabel: ytLabel 46 }); 47 YT.gtmLastAction = ""; 48 } 49 if (e["data"] == YT.PlayerState.PAUSED) { 50 dataLayer.push({ 51 event: "YouTube", 52 ytAction: "Pause", 53 ytLabel: ytLabel 54 }); 55 YT.gtmLastAction = "p"; 56 } 57} 58 59// catch all to report errors through the GTM data layer 60// once the error is exposed to GTM, it can be tracked in UA as an event! 61function onPlayerError(e) { 62 dataLayer.push({ 63 event: "YouTubeError", 64 ytAction: "GTM YouTube Error", 65 ytLabel: "YouTube:" + e["target"]["src"] + "-" + e["data"] 66 }) 67} 68 69// report the % played if it matches 0%, 25%, 50%, 75% or completed 70function onPlayerPercent(e) { 71 if (e["getPlayerState"]() == YT.PlayerState.PLAYING) { 72 var t = e["getDuration"]() - e["getCurrentTime"]() <= 1.5 ? 1 : (Math.floor(e["getCurrentTime"]() / e["getDuration"]() * 4) / 4).toFixed(2); if (!e["lastP"] || t > e["lastP"]) { 73 var video_data = e["getVideoData"](), 74 ytLabel = video_data.title+' (youtube.com/watch?v='+video_data.video_id+')'; 75 e["lastP"] = t; 76 dataLayer.push({ 77 event: "YouTube", 78 ytAction: t * 100 + "%", 79 ytLabel: ytLabel 80 }) 81 } 82 e["lastP"] != 1 && setTimeout(onPlayerPercent, 1000, e); 83 } 84} 85 86 87//primitive + native prototypes 88Date.prototype.addDays = function (days) { 89 var dat = new Date(this.valueOf()); 90 dat.setDate(dat.getDate() + days); 91 return dat; 92} 93 94//IE polyfills 95if (!Array.prototype.find) { 96 Object.defineProperty(Array.prototype, 'find', { 97 value: function (predicate) { 98 // 1. Let O be ? ToObject(this value). 99 if (this == null) { 100 throw new TypeError('"this" is null or not defined'); 101 } 102 103 var o = Object(this); 104 105 // 2. Let len be ? ToLength(? Get(O, "length")). 106 var len = o.length >>> 0; 107 108 // 3. If IsCallable(predicate) is false, throw a TypeError exception. 109 if (typeof predicate !== 'function') { 110 throw new TypeError('predicate must be a function'); 111 } 112 113 // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. 114 var thisArg = arguments[1]; 115 116 // 5. Let k be 0. 117 var k = 0; 118 119 // 6. Repeat, while k < len 120 while (k < len) { 121 // a. Let Pk be ! ToString(k). 122 // b. Let kValue be ? Get(O, Pk). 123 // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). 124 // d. If testResult is true, return kValue. 125 var kValue = o[k]; 126 if (predicate.call(thisArg, kValue, k, o)) { 127 return kValue; 128 } 129 // e. Increase k by 1. 130 k++; 131 } 132 133 // 7. Return undefined. 134 return undefined; 135 } 136 }); 137}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.