1(function (doc, win) { 2 var ID = "0d76349b4550007f9e8c70640a49ba00"; 3 4 win.reviveAsync = win.reviveAsync || {}; 5 6 /* 7 * IE backwards compatibility 8 */ 9 (function (w) { 10 11 if ( typeof w.CustomEvent === "function" ) return false; 12 13 function CustomEvent ( event, params ) { 14 params = params || { bubbles: false, cancelable: false, detail: undefined }; 15 var evt = document.createEvent( 'CustomEvent' ); 16 evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); 17 return evt; 18 } 19 20 CustomEvent.prototype = w.Event.prototype; 21 22 w.CustomEvent = CustomEvent; 23 })(win); 24 25 try { 26 if (!win.reviveAsync.hasOwnProperty(ID)) { 27 var rv = win.reviveAsync[ID] = { 28 id: Object.keys(win.reviveAsync).length, 29 name: "revive", 30 seq: 0, 31 32 /** 33 * Initialise the async delivery mechanism. 34 */ 35 main: function () { 36 var domCallback = function () { 37 var done = false; 38 39 try { 40 // Ensure we execute the following just once 41 if (!done) { 42 done = true; 43 44 // Clear main event listeners 45 doc.removeEventListener("DOMContentLoaded", domCallback, false); 46 win.removeEventListener("load", domCallback, false); 47 48 // Listen for the start and refresh events 49 rv.addEventListener('start', rv.start); 50 rv.addEventListener('refresh', rv.refresh); 51 52 // Start delivery 53 rv.dispatchEvent('start', { 54 start: true 55 }); 56 } 57 } catch (e) { 58 console.log(e); 59 } 60 }; 61 62 // Library has been initialized, someone (e.g. Tag Manager) might need to know 63 rv.dispatchEvent('init'); 64 65 // Wait for the DOM to be loaded or execute asynchronously if we were late to the party 66 if (doc.readyState === "complete") { 67 setTimeout(domCallback); 68 } else { 69 doc.addEventListener("DOMContentLoaded", domCallback, false); 70 win.addEventListener("load", domCallback, false); 71 } 72 }, 73 74 /** 75 * The start event handler. Delivery can be prevented by setting e.detail.start = false. 76 * 77 * @param {CustomEvent} e 78 */ 79 start: function (e) 80 { 81 e.detail.start = false;
82 if (e.detail && e.detail.hasOwnProperty('start') && !e.detail.start) { 83 return; 84 } 85 86 rv.removeEventListener('start', rv.start); 87 88 rv.dispatchEvent('refresh'); 89 }, 90 91 /** 92 * The refresh event handler. 93 * 94 * @param {CustomEvent} e 95 */ 96 refresh: function (e) 97 { 98 rv.apply(rv.detect()); 99 }, 100 101 /** 102 * Perform the AJAX call. 103 * 104 * @param {string} url 105 * @param {Object} data 106 */ 107 ajax: function (url, data) { 108 var xhr = new XMLHttpRequest(); 109 110 xhr.onreadystatechange = function() { 111 if (4 === this.readyState) { 112 if (200 === this.status) { 113 rv.spc(JSON.parse(this.responseText)); 114 } 115 } 116 }; 117 118 // Pre-ajax hook 119 this.dispatchEvent('send', data); 120 121 xhr.open("GET", url + "?" + rv.encode(data).join("&"), true); 122 xhr.withCredentials = true; 123 xhr.send(); 124 }, 125 126 /** 127 * Utility method to generate the query string. 128 * 129 * @param {Object} data the input hash 130 * @param {string} arrayName the variable "array" name (optional) 131 * @returns {Array} 132 */ 133 encode: function (data, arrayName){ 134 var qs = [], k, j; 135 136 for (k in data) { 137 if (data.hasOwnProperty(k)) { 138 var key = arrayName ? arrayName + "[" + k + "]" : k; 139 140 if ((/^(string|number|boolean)$/).test(typeof data[k])) { 141 qs.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[k])); 142 } else { 143 var a = rv.encode(data[k], key); 144 for (j in a) { 145 qs.push(a[j]); 146 } 147 } 148 } 149 } 150 151 return qs; 152 }, 153 154 /** 155 * Start the asynchronous process to fill the <ins> tags. 156 * 157 * @param {Array} data 158 */ 159 apply: function (data) { 160 if (data.zones.length) { 161 var url = 'http:' === doc.location.protocol ? 162 "http://mktadv.cittanet.com/asyncspc.php" : 163 "https://mktadv.cittanet.com/asyncspc.php"; 164 165 data.zones = data.zones.join("|"); 166 data.loc = doc.location.href; 167 if (doc.referrer) { 168 data.referer = doc.referrer; 169 } 170 171 rv.ajax(url, data); 172 } 173 }, 174 175 /** 176 * Search the DOM for <ins> tags that need to be filled. 177 * 178 * @returns {{zones: Array, prefix: string}} 179 */ 180 detect: function () { 181 var elements = doc.querySelectorAll("ins[" + rv.getDataAttr("id") + "='" + ID + "']"); 182 var data = { 183 zones: [], 184 prefix: rv.name + "-" + rv.id + "-" 185 }; 186 187 for (var idx = 0; idx < elements.length; idx++) { 188 var zoneidAttr = rv.getDataAttr("zoneid"), 189 seqAttr = rv.getDataAttr("seq"), 190 i = elements[idx], 191 seq; 192 193 if (i.hasAttribute(seqAttr)) { 194 seq = i.getAttribute(seqAttr); 195 } else { 196 seq = rv.seq++; 197 i.setAttribute(seqAttr, seq); 198 i.id = data.prefix + seq; 199 } 200 201 if (i.hasAttribute(zoneidAttr)) { 202 var loadedAttr = rv.getDataAttr("loaded"), 203 regex = new RegExp("^" + rv.getDataAttr("(.*)") + "$"), 204 m; 205 206 if (i.hasAttribute(loadedAttr) && i.getAttribute(loadedAttr)) { 207 // The tag has already been loaded, skip 208 continue; 209 } 210 211 i.setAttribute(rv.getDataAttr("loaded"), "1"); 212 213 for (var j = 0; j < i.attributes.length; j++) { 214 if (m = i.attributes[j].name.match(regex)) { 215 if ('zoneid' === m[1]) { 216 data.zones[seq] = i.attributes[j].value; 217 } else if (!(/^(id|seq|loaded)$/).test(m[1])) { 218 data[m[1]] = i.attributes[j].value; 219 } 220 } 221 } 222 } 223 } 224 225 return data; 226 }, 227 228 /** 229 * Create and return a new iframe. 230 * 231 * @param {Object} data 232 * @returns {Element} 233 */ 234 createFrame: function (data) { 235 var i = doc.createElement('IFRAME'), s = i.style; 236 237 i.scrolling = "no"; 238 i.frameBorder = 0; 239 i.allow = "autoplay"; 240 i.width = data.width > 0 ? data.width : 0; 241 i.height = data.height > 0 ? data.height : 0; 242 s.border = 0; 243 s.overflow = "hidden"; 244 245 return i; 246 }, 247 248 /** 249 * Inject the HTML into the iframe. 250 * 251 * @param {Element} iframe 252 * @param {string} html 253 */ 254 loadFrame: function (iframe, html) { 255 var srcdoc = '<!DOCTYPE html>'; 256 srcdoc += '<html>'; 257 srcdoc += '<head><base target="_top"><meta charset="UTF-8"></head>'; 258 srcdoc += '<body border="0" margin="0" style="margin: 0;padding: 0;">'; 259 srcdoc += html; 260 srcdoc += '<body>'; 261 srcdoc += '</html>'; 262 263 if ('srcdoc' in iframe && "1" === iframe.parentElement.getAttribute(this.getDataAttr('srcdoc'))) { 264 iframe.srcdoc = srcdoc;
264 // If srcdoc is supported and enabled we can just assign it 265 } else { 266 var d = iframe.contentWindow.document || iframe.contentDocument; 267 d.open(); 268 d.write(srcdoc); // If srcdoc is not supported write entire srcdoc string to document 269 d.close(); 270 } 271 }, 272 273 /** 274 * The AJAX Callback. 275 * 276 * @param {Object} data 277 */ 278 spc: function (data) { 279 // Post-ajax hook 280 this.dispatchEvent('receive', data); 281 282 for (var id in data) { 283 if (data.hasOwnProperty(id)) { 284 var d = data[id]; 285 var ins = doc.getElementById(id); 286 287 if (ins) { 288 var newIns = ins.cloneNode(false); 289 290 if (d.iframeFriendly) { 291 var ifr = rv.createFrame(d); 292 newIns.appendChild(ifr); 293 ins.parentNode.replaceChild(newIns, ins); 294 rv.loadFrame(ifr, d.html); 295 } else { 296 newIns.style.textDecoration = 'none'; 297 newIns.innerHTML = d.html; 298 var scripts = newIns.getElementsByTagName('SCRIPT'); 299 300 for (var i = 0; i < scripts.length; i++) { 301 var s = document.createElement('SCRIPT'); 302 var a = scripts[i].attributes; 303 for (var j = 0; j < a.length; j++) { 304 s[a[j].nodeName] = a[j].value; 305 } 306 if (scripts[i].innerHTML) { 307 s.text = scripts[i].innerHTML; 308 } 309 310 scripts[i].parentNode.replaceChild(s, scripts[i]); 311 } 312 313 ins.parentNode.replaceChild(newIns, ins); 314 } 315 316 this.dispatchEvent('loaded', { 317 "id": id, 318 "data": d 319 }); 320 } 321 } 322 } 323 324 this.dispatchEvent('completed', data); 325 }, 326 327 /** 328 * Returnrs the data HTML attribute name. 329 * 330 * @param {string} name 331 * @returns {string} 332 */ 333 getDataAttr: function (name) { 334 return 'data-' + rv.name + '-' + name; 335 }, 336 337 /** 338 * Returns the custom event name. 339 * 340 * @param {string} eventName 341 * @returns {string} 342 */ 343 getEventName: function (eventName) 344 { 345 return this.name + '-' + ID + '-' + eventName; 346 }, 347 348 /** 349 * Listen for a custom event. 350 * 351 * @param {string} eventName 352 * @param {EventListener|Function} callback 353 */ 354 addEventListener: function (eventName, callback) 355 { 356 doc.addEventListener(this.getEventName(eventName), callback); 357 }, 358 359 /** 360 * Remove an existing listener. 361 * 362 * @param {string} eventName 363 * @param {EventListener|Function} callback 364 */ 365 removeEventListener: function (eventName, callback) 366 { 367 doc.removeEventListener(this.getEventName(eventName), callback, true); 368 }, 369 370 /**
371 * Dispatch a custom event. 372 * 373 * @param {string} eventName 374 * @param {Object} [data] 375 */ 376 dispatchEvent: function (eventName, data) { 377 doc.dispatchEvent(new CustomEvent(this.getEventName(eventName), { 378 detail: data || {} 379 })); 380 } 381 }; 382 383 // Register the DOM event listeners or start if the DOM is already loaded 384 rv.main(); 385 } 386 } catch (e) { 387 if (console.log) { 388 console.log(e); 389 } 390 } 391})(document, window);
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.