1/** 2 * NeverBlock 3 * 4 * Version 3.7 5 * Copyright (C) 2016 EXADS 6 */ 7 8 // noinspection JSUnusedGlobalSymbols 9var ExoLoader; 10(function () { 11 var version = '3.7'; 12 13 var detection_started = false; 14 var detection_complete = false; 15 var adblock_detected = false; 16 var detector_func_queue = []; 17 18 var detector = { 19 domain_base: "exoclick.com", 20 detectCensorship: function (onComplete) { 21 detector_func_queue.push(onComplete); 22 detection_started = true; 23 var block = false; 24 var done = function () { 25 if (!detection_complete) { 26 try { 27 var checkVal = (window.document.location.protocol !== "https:" && window.document.location.protocol !== "http:") ? "https:" : window.document.location.protocol; 28 if (typeof window.exoDocumentProtocol === "undefined" 29 || window.exoDocumentProtocol !== checkVal 30 ) { 31 block = true; 32 } 33 } catch (err) { 34 block = true; 35 } 36 adblock_detected = block; 37 detection_complete = true; 38 } else { 39 block = adblock_detected; 40 } 41 do { 42 var currentFunction = detector_func_queue.shift(); 43 if (typeof currentFunction === 'function') { 44 currentFunction(block); 45 } 46 } while (typeof currentFunction !== "undefined"); 47 if (testDomEl) 48 { 49 try { 50 document.body.removeChild(testDomEl); 51 } catch (err) { 52 // element not found, possibly already removed? 53 } 54 } 55 }; 56 57 if (detection_complete) { 58 done(); 59 return; 60 } 61 62 var testDomEl = document.createElement('iframe'), 63 randomNum = Math.floor(Math.random() * (10000 - 123 + 1)) + 123, 64 protocol = window.location.protocol, 65 id = 'adsbox_ex_' + randomNum; 66 67 testDomEl.setAttribute('height', "1px"); 68 testDomEl.setAttribute('width', "1px"); 69 testDomEl.setAttribute('id', id); 70 testDomEl.setAttribute('class', 'adsBox pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links'); 71 testDomEl.setAttribute('style', "width: 1px !important; height: 1px !important; position: absolute !important; left: -10000px !important; top: -1000px !important; box-sizing: content-box !important; border-width: 0px !important;"); 72 73 try { 74 if (window.ExoLoader === null) { 75 window.ExoLoader = {'dummy': 1}; 76 if (window.ExoLoader !== {'dummy': 1}) { 77 block = true; 78 } 79 } 80 } catch (err) { 81 block = true; 82 } 83 84 var testScript = document.createElement('script'); 85 testScript.src = protocol + "//ads." + detector.domain_base + "/ads.js"; 86 testScript.onerror = function () { 87 block = true; 88 }; 89 90 document.body.appendChild(testDomEl); 91 document.head.appendChild(testScript); 92 93 var domDetect = function () { 94 try { 95 var someAd = document.getElementById(id); 96 if (someAd === null 97 || someAd.style.display === "none" 98 || someAd.style.display === "hidden" 99 || someAd.style.visibility === "hidden" 100 || someAd.offsetParent === null 101 || someAd.offsetHeight === 0 102 || someAd.offsetLeft === 0 103 || someAd.offsetTop === 0 104 || someAd.offsetWidth === 0 105 || someAd.clientHeight === 0 106 || someAd.clientWidth === 0 107 ) { 108 block = true; 109 } 110 if (window.getComputedStyle !== undefined) { 111 var style = window.getComputedStyle(someAd, null); 112 if (style && (style.getPropertyValue('display') === 'none' || style.getPropertyValue('visibility') === 'hidden')) { 113 block = true; 114 } 115 } 116 } catch (err) { 117 } 118 }; 119 120 var maxReadyCheckAttempts = 45; 121 var readyCheckInterval = setInterval(function () { 122 if (document.readyState === "complete" || maxReadyCheckAttempts == "0") { 123 domDetect(); 124 done(); 125 clearInterval(readyCheckInterval); 126 } 127 maxReadyCheckAttempts--; 128 }, 50); 129 } 130 }; 131 132 function urlDomain(url) { 133 var a = document.createElement('a'); 134 a.href = url; 135 return a.hostname; 136 } 137 138 var stylesheet = "{ %optional_styles% vertical-align:top; cursor: pointer; border: 0px solid #000000; display: inline-block; background-color: rgba(0, 0, 0, 0); margin: 0px 0px; padding: 0px 0px; }"; 139 var debug_messages = []; 140 var error_messages = []; 141 var request_stack = [];// array of request objects 142 var responses = {}; 143 var callback_function_pushed_to_detector = false;
144 var request_started = false; 145 var current_request = 0; 146 var waiting_request_queue = []; 147 var before_detect_queue = []; 148 149 var ZonesRequest = function() { 150 this.zone_params = []; 151 this.dom = []; 152 this.pushZone = function(zoneParams) { 153 this.zone_params.push(zoneParams); 154 }; 155 this.pushDom = function(domObj) { 156 this.dom.push(domObj); 157 }; 158 }; 159 160 var addDebugMessage = function (message) { 161 var date = new Date(); 162 debug_messages.push(date.toISOString() + ": " + message); 163 }; 164 var addErrorMessage = function (message) { 165 var date = new Date(); 166 error_messages.push(date.toISOString() + ": " + message); 167 console.error(message); 168 }; 169 170 var URLToArray = function(url) { 171 var request = {}; 172 var pairs = url.substring(url.indexOf('?') + 1).split('&'); 173 for (var i = 0; i < pairs.length; i++) { 174 if(!pairs[i]) 175 continue; 176 var pair = pairs[i].split('='); 177 request[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); 178 } 179 return request; 180 }; 181 182 var stringify = function (value) { 183 var reassign_when_finished = false; 184 if (typeof Array.prototype.toJSON !== 'undefined') { 185 reassign_when_finished = true; 186 var array_to_json = Array.prototype.toJSON; 187 delete Array.prototype.toJSON; 188 } 189 var val = JSON.stringify(value); 190 if (reassign_when_finished) { 191 Array.prototype.toJSON = array_to_json; 192 } 193 return val; 194 }; 195 196 var randStr = function (length, possibleChars) 197 { 198 var text = ""; 199 var possible = possibleChars || "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 200 201 for( var i=0; i < length; i++ ) 202 text += possible.charAt(Math.floor(Math.random() * possible.length)); 203 204 return text; 205 }; 206 207 var createStyle = function (doc, dom_anchor, style_text) 208 { 209 var class_name = randStr(1,"abcdefghijklmnopqrstuvwxyz") + randStr(7); 210 style_text = "." + class_name + " " + style_text; 211 var style = doc.createElement('style'); 212 style.setAttribute('type', 'text/css'); 213 style.innerHTML = style_text; 214 dom_anchor.parentNode.insertBefore(style, dom_anchor); 215 return class_name; 216 }; 217 218 // noinspection JSUnusedGlobalSymbols 219 var loader = { 220 bl_domain: null, 221 bl_cookie_domain: null, 222 no_cookie: false, 223 cookie_name: "yuo1", 224 addZone: function(params) { 225 226 if (typeof params !== 'object' 227 || typeof params.idzone === 'undefined' 228 ) { 229 addErrorMessage("addZone() invalid params"); 230 return false; 231 } 232 // noinspection JSUnresolvedVariable 233 var doc = params.doc || document; 234 var scripts = doc.getElementsByTagName('script'); 235 // The current <script> tag where the method is called 236 var here = params.here || scripts[ scripts.length - 1 ]; 237 238 if (!detection_complete) { 239 addDebugMessage("addZone() added to detect queue"); 240 params.here = here; 241 before_detect_queue.push({"func": 'addZone', "parameters": params}); 242 243 if (!callback_function_pushed_to_detector) { 244 callback_function_pushed_to_detector = true; 245 detector.detectCensorship(function(block) { 246 if (block) { 247 window.exoNoExternalUI38djdkjDDJsio96 = true; 248 for (var i = 0; i < before_detect_queue.length; i++) { 249 loader[before_detect_queue[i]['func']](before_detect_queue[i]['parameters']); 250 } 251 before_detect_queue = []; 252 } 253 }); 254 } 255 256 return false; 257 } else { 258 if (adblock_detected && !window.exoNoExternalUI38djdkjDDJsio96) { 259 window.exoNoExternalUI38djdkjDDJsio96 = true; 260 } 261 if (!adblock_detected) { 262 addDebugMessage("addZone() ad blocker not enabled"); 263 return false; 264 } 265 } 266 267 var request; 268 if (typeof request_stack[current_request] === "object") { 269 request = request_stack[current_request]; 270 } else { 271 request = new ZonesRequest(); 272 request_stack[current_request] = request; 273 } 274 request.pushZone(params); 275 276 var optional_styles = ''; 277 var displayNone = false; 278 if ( 279 typeof params.width !== 'undefined' 280 && typeof params.height !== 'undefined' 281 ) { 282 optional_styles += 'width: ' + params.width + 'px;'; 283 optional_styles += ' height: ' + params.height + 'px;'; 284 } else { 285 displayNone = true; 286 } 287 288 var style_text = stylesheet.replace('%optional_styles%', optional_styles); 289 var class_name = createStyle(doc, here, style_text); 290 291 var placeholder = doc.createElement('div'); 292 if (displayNone) { 293 placeholder.style.display = 'none'; 294 } 295 placeholder.setAttribute('class', class_name); 296 if (params.container && typeof params.container === "object" && typeof params.container.appendChild === "function") { 297 params.container.appendChild(placeholder); 298 } else { 299 if (params.containerId) { 300 var container = doc.createElement('div'); 301 container.id = params.containerId; 302 here.appendChild(container); 303 container.appendChild(placeholder); 304 } else { 305 here.parentNode.insertBefore(placeholder, here); 306 } 307 } 308 request.pushDom({'placeholder': placeholder, 'doc_reference': doc}); 309 310 addDebugMessage("addZone() " + params.idzone + " added"); 311 return true; 312 }, 313 serve: function(params) { 314 /* 315 params = { 316 script_url: 'url/of/backend_loader.php', 317 force: {false|true}, 318 no_cookie: {false|true} 319 } 320 321 Important note: 322 If backend_loader.php & frontend_loader are hosted on different domains, 323 don't forget to take care about CORS issues! 324 In case the domains are not subdomains of a common domain it's impossible to pass data through cookie. no_cookie should be set to true. 325 */ 326 327 if (!detection_complete) { 328 addDebugMessage("serve() added to detect queue"); 329 params.force = true; 330 before_detect_queue.push({"func": 'serve', "parameters": params}); 331 return false;
332 } else { 333 if (adblock_detected && !window.exoNoExternalUI38djdkjDDJsio96) { 334 window.exoNoExternalUI38djdkjDDJsio96 = true; 335 } 336 if (!adblock_detected) { 337 addDebugMessage("serve() ad blocker not enabled"); 338 return false; 339 } 340 } 341 342 var request_id = current_request; 343 var increment_current_request = true; 344 if (typeof params.request_id !== "undefined" && params.request_id !== null) { 345 request_id = params.request_id; 346 increment_current_request = false; 347 } 348 var request = request_stack[request_id]; 349 350 if (typeof request === 'undefined' 351 || request.zone_params.length < 1 352 ) { 353 addErrorMessage("serve() called but no zones added for request: " + request_id); 354 return false; 355 } 356 357 if (increment_current_request) { 358 current_request++; 359 } 360 361 if (request_started) { 362 waiting_request_queue.push({"request_id": request_id, "parameters": params}); 363 return; 364 } 365 366 addDebugMessage("serve() called for request " + request_id); 367 //Start a request. If there are several others will wait since they share a cookie. 368 request_started = true; 369 var cookie_request_obj = { 370 "objName": objName, 371 "request_id": request_id, 372 "zones": request.zone_params 373 }; 374 375 loader.bl_domain = params.bl_domain || urlDomain(params.script_url); // Domain of backend_loader.php 376 loader.bl_cookie_domain = params.bl_cookie_domain || loader.bl_domain; 377 loader.no_cookie = params.no_cookie; 378 379 var request_str = stringify(cookie_request_obj); 380 381 if (!loader.no_cookie) { 382 loader.setCookie(this.cookie_name, request_str, 5, loader.bl_cookie_domain); 383 } 384 delete request.zone_params.request_id; 385 386 var loadDataScript = function () { 387 var dataScript = document.createElement("script"); 388 dataScript.async = true; 389 dataScript.setAttribute('type', 'text/javascript'); 390 var script_url = params.script_url; 391 if (loader.no_cookie) { 392 script_url += (/\?/.test(params.script_url) ? '&' : '?') + 393 loader.cookie_name + '=' + request_str; 394 } 395 if (params.no_cache) { 396 script_url += (/\?/.test(params.script_url) ? '&' : '?') + 397 '_=' + randStr(3) + (new Date()).getTime(); // Avoid caching! 398 } 399 dataScript.setAttribute('src', script_url); 400 dataScript.onload = function(){ 401 addDebugMessage("serve() hosted script loaded"); 402 }; 403 var processNext = function() { 404 request_started = false; 405 if (waiting_request_queue.length > 0) { 406 var next_request_obj = waiting_request_queue.shift(); 407 next_request_obj.parameters.request_id = next_request_obj.request_id; 408 loader.serve(next_request_obj.parameters); 409 } 410 }; 411 dataScript.onload = processNext; 412 dataScript.onerror = processNext; 413 document.getElementsByTagName("body").item(0).appendChild(dataScript); 414 }; 415 416 if (!params.force) { 417 if (window.addEventListener) { 418 window.addEventListener("load", loadDataScript, false); 419 } else if (window.attachEvent) { 420 window.attachEvent("onload", loadDataScript); 421 } else { 422 window.onload = loadDataScript; 423 } 424 } else { 425 loadDataScript(); 426 } 427 return true; 428 }, 429 getDebug: function() { 430 for (var i = 0; i < debug_messages.length; i++) { 431 console.log(debug_messages[i]); 432 } 433 }, 434 getVersion: function() { 435 return version; 436 }, 437 pushResponseData: function(response) { 438 if ( 439 typeof response !== 'object' 440 || typeof response.request_id !== 'number' 441 || typeof request_stack[response.request_id] === 'undefined' 442 ) { 443 addErrorMessage("pushResponseData() invalid response"); 444 } 445 responses[response.request_id] = response; 446 addDebugMessage("pushResponseData() called for request " + response.request_id); 447 }, 448 getAdData: function(request_id, ad_format) { 449 var adData = { 450 'zones': [] 451 }; 452 453 if (typeof request_stack[request_id] === 'undefined' 454 || typeof responses[request_id] === 'undefined' 455 ) { 456 addErrorMessage("getAdData() data for request_id not found"); 457 return adData; 458 } 459 if (typeof responses[request_id].zones[ad_format] === 'undefined') { 460 addErrorMessage("getAdData() data for ad_format " + ad_format + " not present in response"); 461 return adData; 462 } 463 464 for (var i = 0; i < responses[request_id].zones[ad_format].length; i++) { 465 var adId = responses[request_id].zones[ad_format][i].id; 466 var zone_params = request_stack[request_id].zone_params[adId]; 467 var idzone = zone_params.idzone; 468 469 var zoneObj = { 470 "idzone": idzone, 471 "dom": request_stack[request_id].dom[adId], 472 "data": responses[request_id].zones[ad_format][i].data 473 }; 474 if (typeof zone_params.sub !== 'undefined') { 475 zoneObj.sub = zone_params.sub; 476 } 477 if (typeof zone_params.sub2 !== 'undefined') { 478 zoneObj.sub2 = zone_params.sub2; 479 } 480 if (typeof zone_params.sub3 !== 'undefined') { 481 zoneObj.sub3 = zone_params.sub3; 482 } 483 if (typeof zone_params.cat !== 'undefined') {
484 zoneObj.cat = zone_params.cat; 485 } 486 adData.zones.push(zoneObj); 487 } 488 if (typeof responses[request_id].additional_images !== 'undefined' 489 && typeof responses[request_id].additional_images[ad_format] !== 'undefined' 490 ) { 491 adData.additional_images = responses[request_id].additional_images[ad_format]; 492 } 493 494 return adData; 495 }, 496 openLink: function(event, dest, force_method) { 497 if (typeof force_method !== 'undefined' 498 && force_method !== 'get' 499 && force_method !== 'post' 500 ) { 501 addErrorMessage("openLink() trying to force invalid method"); 502 } 503 if (typeof(event) !== "undefined") { 504 event.returnValue = false; 505 if (event.preventDefault) { 506 event.preventDefault(); 507 } 508 event.stopPropagation(); 509 } 510 511 var url_parts; 512 var parameters; 513 var method; 514 if (dest.indexOf("?") !== -1) { 515 url_parts = dest.split('?', 2); 516 parameters = URLToArray(url_parts[1]); 517 method = (force_method) ? force_method : "post"; 518 } else { 519 url_parts = [dest]; 520 parameters = []; 521 method = (force_method) ? force_method : "get"; 522 } 523 var f = document.createElement("form"); 524 f.setAttribute("action", url_parts[0]); 525 f.setAttribute("method", method); 526 f.setAttribute("target", "_blank"); 527 document.getElementsByTagName("body").item(0).appendChild(f); 528 for (var i in parameters) { 529 if (!parameters.hasOwnProperty(i)) { 530 continue; 531 } 532 var input = document.createElement("input"); 533 input.setAttribute("type", "hidden"); 534 input.setAttribute("name", i); 535 input.setAttribute("value", parameters[i]); 536 f.appendChild(input); 537 } 538 f.submit(); 539 document.getElementsByTagName("body").item(0).removeChild(f); 540 return false; 541 }, 542 formatImage: function (request_id, imageReference) { 543 if (typeof request_stack[request_id] === 'undefined' 544 || typeof responses[request_id] === 'undefined' 545 ) { 546 addErrorMessage("formatImage() data for request_id not found"); 547 return false; 548 } 549 var result = responses[request_id].banner_prefix + responses[request_id].images[imageReference]; 550 if (loader.bl_domain) { 551 result = "//" + loader.bl_domain + result; 552 } 553 return result; 554 }, 555 formatLink: function (request_id, link) { 556 if (typeof request_stack[request_id] === 'undefined' 557 || typeof responses[request_id] === 'undefined' 558 ) { 559 addErrorMessage("formatLink() data for request_id not found"); 560 return false; 561 } 562 var result = responses[request_id].link_prefix + link; 563 if (loader.bl_domain) { 564 result = "//" + loader.bl_domain + result; 565 } 566 return result; 567 }, 568 setCookie: function (name, value, minutes_ttl, domain) { 569 var exdate = new Date(); 570 exdate.setMinutes(exdate.getMinutes() + minutes_ttl); 571 var c_value = encodeURI(value) + "; expires=" + exdate.toUTCString() + "; path=/"; 572 if (domain) { 573 c_value += "; domain=" + domain; 574 } 575 document.cookie = name + "=" + c_value; 576 }, 577 getCookie: function (name) { 578 var i, x, y, ARRcookies = document.cookie.split(";"); 579 for (i = 0; i < ARRcookies.length; i++) { 580 x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("=")); 581 y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1); 582 x = x.replace(/^\s+|\s+$/g, ""); 583 if (x === name) { 584 return decodeURI(y); 585 } 586 } 587 }, 588 getRandomClassName: function() { 589 return randStr(1,"abcdefghijklmnopqrstuvwxyz") + randStr(7); 590 }, 591 getRandomizedReference: function(name, reference_map) { 592 if (typeof name !== 'string' || name === '') { 593 addErrorMessage("getRandomizedReference() invalid name, non-empty string expected"); 594 return false; 595 } 596 if (typeof reference_map !== 'object') { 597 addErrorMessage("getRandomizedReference() invalid reference_map, object expected"); 598 return false; 599 } 600 if (typeof reference_map[name] === 'undefined') { 601 reference_map[name] = loader.getRandomClassName(); 602 } 603 return reference_map[name]; 604 }, 605 scrambleStyleString: function(style_str, reference_map, style_regexp) { 606 if (typeof style_str !== 'string' || style_str === '') { 607 addErrorMessage("scrambleStyleString() invalid style_str, non-empty string expected"); 608 return false;
609 } 610 if (typeof reference_map !== 'object') { 611 addErrorMessage("getRandomizedReference() invalid reference_map, object expected"); 612 return false; 613 } 614 if (style_regexp instanceof RegExp) { 615 var match; 616 while (match = style_regexp.exec(style_str)) { 617 loader.getRandomizedReference(match[1], reference_map); 618 } 619 } 620 for (var name in reference_map) { 621 if (!reference_map.hasOwnProperty(name)) { 622 continue; 623 } 624 style_str = style_str.replace(new RegExp('([#\.]{1,1})' + name + '([ :\.{])', 'g'), '$1' + reference_map[name] + '$2'); 625 } 626 return style_str; 627 }, 628 getDetector: function() { 629 return detector; 630 }, 631 cleanupPartiallyBlockedAds: function() { 632 detector.detectCensorship( 633 function(block){ if (block) { 634 var frames = document.getElementsByTagName("iframe"); 635 636 for (var iNum = 0; iNum < frames.length; ++iNum) { 637 if (frames[iNum].src.indexOf("//" + detector.domain_base + "/") > 0) { 638 frames[iNum].style.display = "none"; 639 } 640 } 641 }} 642 ); 643 } 644 }; 645 646 var objName; 647 for (var tries = 0; tries < 3; tries++) { 648 objName = randStr(1, "abcdefghijklmnopqrstuvwxyz") + randStr(Math.floor((Math.random() * 4) + 10)); 649 if (typeof window[objName] !== "undefined") { 650 continue; 651 } 652 window[objName] = loader; 653 break; 654 } 655 656 // custom event polyfill 657 (function() { 658 if (typeof window.CustomEvent === "function") return false; 659 660 function CustomEvent(event, params) { 661 params = params || {bubbles: false, cancelable: false, detail: undefined}; 662 var evt = document.createEvent('CustomEvent'); 663 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 664 return evt; 665 } 666 667 CustomEvent.prototype = window.Event.prototype; 668 669 window.CustomEvent = CustomEvent; 670 })(); 671 672 window.document.addEventListener('getexoloader', function (e) { 673 e.detail.el = loader; 674 }, false); 675 try { 676 ExoLoader = loader; 677 } catch (err) {} 678})();
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.