Автомайдан снял с квадракоптера владения экс-коммунистки Оксаны Калетник. Активисты пообещали посетить дома других нардепов, которые тормозят люстрацию.

/** @preserve version 3.3.280_ua *//** @define {boolean} */var ENABLE_CONSOLE = true;/** @define {boolean} */var ENABLE_ERROR_HANDLING = false;(function (window, document, undefined) {"use strict";/** @const*/var CONFIG = { source : ‘source.mmi.bemobile.ua’, juke_host: "juke.mmi.bemobile.ua/bug/pic.gif", host: "pagestat.mmi.bemobile.ua", sslhost: "sslpagestat.mmi.bemobile.ua", err_host: "er.mmi.bemobile.ua", timer: { frequency: 5, // seconds pings: [5, 15, 30, 60, 120], stop_after: 5 // minutes }, ads: { scan_frequency: 5, // seconds // minimal size width: 50, height: 40 }};extend(CONFIG, window.addonCMeter && addonCMeter.config);/** * Prepare CONFIG array for use. Apply local params for the specific domain. Add parameter for be able to work in iframe (by default is true). * */if (CONFIG.custom_url && location.host === CONFIG.custom_url.href) { CONFIG.ads.scan_frequency = CONFIG.custom_url.banner_scan_frequency; CONFIG.work_in_frame = CONFIG.custom_url.work_in_frame;} else { CONFIG.work_in_frame = true;}// this part is already in helpers.js/** * Extend destination object with the items from the source object. * If 3d argument is true, functions from the source are bound and then copied. * Function returns nothing, first argument is modified instead * * @param {Object} dest destination, where to copy items from the source * @param {Object} src source object from where items are taken * @param {Boolean} [bindFuncs] if true — functions in the source will be bound and returned rather then original functions */function extend(dest, src, bindFuncs) { var k, item; for (k in src) { if (src.hasOwnProperty(k)) { item = src[k]; dest[k] = bindFuncs && "function" === typeof item ? bind(item, dest) : item; } }}var head = { js: function (src, cb) { var s = document.createElement("script"), head = document.head || document.getElementsByTagName(‘head’)[0]; function done (err) { s.onload = s.onerror = s.onreadystatechange = null; if (cb && typeof cb == "function") { cb(err); } } extend(s, { "async": true, "type": "text/javascript", "onload": function () { done(null); }, "onerror": done, "onreadystatechange": function () { if ("loaded" === s.readyState || "complete" === s.readyState) { done(null); } } }); // put src assigning after extend() to make sure it // is being set later than other attributes s.src = src; head.insertBefore(s, head.lastChild); }, onready: function (cb) { function done() { each(head.onready.funcs, function (cb) { cb(); }); delete head.onready.funcs; } function onreadystatechanged() { if ("loading" !== document.readyState) { done(); document.detachEvent("onreadystatechange", onreadystatechanged); } } if ("loading" !== document.readyState) { cb(); return; } if (head.onready.funcs) { head.onready.funcs.push(cb); } else { head.onready.funcs = [cb]; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", done, false); return; } if (document.attachEvent) { document.attachEvent("onreadystatechange", onreadystatechanged); } } }, ready: function (cb) { head.onready(cb); }}window["idCoreOnReady"] = function(id){ IDCore["onFlashReady"](id);};window["tnsOnStatResult"] = function(e){ console.log("result:" + e.result + " pid:" + e.pid + " e.id: " + e.id); if(e.result != "success") { }};// generate random value// unused in extensionfunction random(){ var d = new Date().valueOf().toString(); return parseInt(d.substr(d.length — 8, d.length)) + Math.round(Math.random() * Math.pow(10, 9));};// resolve url by site protocol, host and path// unused in extensionfunction getUrl(host, sslhost, path){ return location.protocol + "//" + (location.protocol == "https:" ? sslhost : host) + path;};// bind function to another scope// bind function implementation// unused in extensionfunction delegate(fn, scope){ return function(){ return fn.apply((scope || window), Array.prototype.slice .call(arguments)); };};// return now in unixtimefunction time(){ return new Date().getTime();};// send requests by corsfunction createCors(errorHandler){ var cors; try { if(window.XDomainRequest) { cors = new window.XDomainRequest(); if(errorHandler){ cors.onerror = function(){ errorHandler.call(null, cors); }; } } else { cors = new XMLHttpRequest(); if(errorHandler){ cors.onreadystatechange = function (e) { if (cors.readyState == 4) { if(cors.status == 200){ }else{ errorHandler.call(null, cors); } } }; } } } catch(e) { console.error("cors:" + e); } return cors;};// check is mobile by regex from useragent// doublevar isMobile = (function(){ return /Mobi|Mini|Symbian|SAMSUNG|Nokia|BlackBerry|Series|Bada|SymbOS|PLAYSTATION/g .test(navigator.userAgent.toString());}());// add param to urlfunction addParam(url, param, value){ var newurl = url; var delimiter = "&"; if(newurl.indexOf("?") == -1) { delimiter = "?"; } newurl += delimiter + param + "=" + value; return newurl;};/* create UUID* */function createUUID(){ var s = []; var hexDigits = "0123456789ABCDEF"; for( var i = 0; i < 32; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[12] = "4"; s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); return s.join("");};function setCookie(name, value, expires, path, domain, secure){ document.cookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");};function getCookie(name){ var cookie = " " + document.cookie; var search = " " + name + "="; var setStr = null; var offset = 0; var end = 0; if(cookie.length > 0) { offset = cookie.indexOf(search); if(offset != -1) { offset += search.length; end = cookie.indexOf(";", offset) if(end == -1) { end = cookie.length; } setStr = unescape(cookie.substring(offset, end)); } } return (setStr);};function deleteCookie(name){ document.cookie = name + ‘=; expires=Thu, 01 Jan 1970 00:00:01 GMT;’;};var hasLocalStorage = (function(){ try { return "localStorage" in window && window["localStorage"] !== null; } catch(e) { return false; }}());var hasFlash = (function(){ if(typeof navigator.plugins == "undefined" || navigator.plugins.length == 0) { try { return !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash")); } catch(er) { return false; } } else { return navigator.plugins["Shockwave Flash"]; }}());var isIE = (function(){ return /MSIE/.test(navigator.userAgent);}());var isIE7 = (function(){ return /MSIE 7/.test(navigator.userAgent);}());function getBody(){ var body; try { body = document.getElementsByTagName("body")[0]; } catch(e) { } if(typeof body == "undefined" || body == null) { if(typeof document.body != "undefined") { body = document.body; if(!body) { // console.warn("body is not availible"); } } } return body;};var isCookieEnabled = (function(){ var cookieEnabled = (navigator.cookieEnabled) ? true : false; if(typeof navigator.cookieEnabled == "undefined" && !cookieEnabled) { document.cookie = "testcookie"; cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false; deleteCookie("testcookie"); } return (cookieEnabled);}());function isNotEmpty(str){ return undefined !== str && null != str && str.replace(/s/g, "") != "";};function getPath(str, root){ var path = str; if(path.toLowerCase().indexOf("/") == 0) { if(root) { path = root + path; } else { var location = window.location.protocol.toString() + "//" + window.location.hostname.toString() + window.location.port.toString(); if(location != "") { path = location + path; } } } return encodeURIComponent(path);};function round(n){ return Math.floor(n * 100) / 100;};function makeArray(items){ try { return Array.prototype.slice.call(items); } catch(ex) { var i = 0, len = items.length, result = Array(len); while(i < len) { result[i] = items[i]; i++; } return result; }};var idScope = (function(){ var scope = "l"; if(hasFlash){ scope = "b"; }else if(window.postMessage && (hasLocalStorage || isCookieEnabled)){ scope = "d"; }else if(hasLocalStorage == false && isCookieEnabled == false){ scope = "g"; } try { if(window.chrome){ for(var i in navigator.plugins){ if(/PepperFlashPlayer/gi.test(navigator.plugins[i].filename)){ scope = "c"; break; } } } }catch(e){ console.warn("chrome : PepperFlashPlayer — has some error"); } return scope;}());var IDCore = (function(){ var isReady = false; var host = window.addonCMeter && addonCMeter.hostAddon; var version = "1.73-r52607"; var short_version = version.replace(/-rd+$/, ""); var juke_host = CONFIG.juke_host || ‘juke.mmi.bemobile.ua/bug/pic.gif’; var hostForFlash = "https://" + CONFIG.source; var cookie = {}; cookie["id"] = "vplayer_user_id"; cookie["wasInitialized"] = "tns_was_initialized"; cookie["wasMigrated"] = "tns_was_migrated"; cookie["flag"] = "flag"; var wasInitialized = false; var holder = "div_holder"; var buffer = new Array(); var uid = ""; var refs = new Array(); function cds(){ function initCds() { try { var remoteStorage = new CrossDomainStorage(hostForFlash, "/id-core/" + version + "/id.html"); remoteStorage["requestValue"](cookie["id"], function(key, id){ onLocalReady(id); }); } catch(e) { console.error("cds.js:" + e); uid = createUUID(); onLocalReady(uid); } } if (typeof CrossDomainStorage === "undefined") { head.js(host + "/id-core/" + version + "/cds.js", initCds); } else { initCds(); } } function setMigrate(){ var expirationDate = new Date(); expirationDate.setFullYear(expirationDate.getFullYear() + 1); // toGMTString() is deprecated setCookie(cookie["wasMigrated"], true, expirationDate.toUTCString(), "/", ""); // when everything is okay onLocalReady(uid); } function migrate(){ if(getCookie(cookie["wasMigrated"])) { return false; } if(isCookieEnabled) { var initialized = getCookie(cookie["wasInitialized"]); if(initialized) { uid = getCookie(cookie["id"]); if(hasLocalStorage) { head.js(host + "/id-core/cds.js", function(){ try { var remoteStorage = new CrossDomainStorage( hostForFlash, "id.html"); remoteStorage["requestValue"](cookie["id"] + ":" + uid, function(key, id){ if(id != uid) { console.error("id: " + id + " != " + uid); } else { setMigrate(); } }); } catch(e) { console.error("migrate:" + e); } }); deleteCookie(cookie["id"]); deleteCookie(cookie["wasInitialized"]); } else if(hasFlash) { window["tns_uid"] = uid; head.js(host + "/id-core/" + version + "/flash.js", function(){ setMigrate(); // delete window["tns_uid"]; }); } return true; } } return false; } function init(){ wasInitialized = true; if(migrate()) { return; } if(hasLocalStorage) { uid = localStorage.getItem(cookie["id"]); if(uid) { onLocalReady(uid); } else { if(window.postMessage && !window.JSON && window.localStorage) { head.js(host + "/json2.min.js", function(){ if(getBody()) { cds(); } else { head.ready(function(){ cds(); }); } }); } else if(window.postMessage && window.JSON && window.localStorage) { if(getBody()) { cds(); } else { head.ready(function(){ cds(); }); } } else { onLocalReady(createUUID()); } } } else { if(hasFlash) { if(getBody()) { head.js(host + "/id-core/" + version + "/flash.js"); } else { head.ready(function(){ head.js(host + "/id-core/" + version + "/flash.js"); }); } } else { uid = getCookie(cookie["id"]); if(!uid) { uid = createUUID(); } onLocalReady(uid); } } } function flushOnReady(){ var i; for(i in buffer) { if(buffer.hasOwnProperty(i)) { var url = buffer[i]["url"]; var params = buffer[i]["params"]; var time = buffer[i]["time"]; var type = buffer[i]["type"]; var onError = buffer[i]["onError"]; if(/POST$/ig.test(type)) { sendPost(url, params, time, onError); } else { sendGet(url, params, time, type, onError); } } } buffer = Array(); var ref; for(ref in refs) { if(refs.hasOwnProperty(ref)) { refs[ref].call(this, uid); } } refs = new Array(); } function onLocalReady(id){ saveId(id); isReady = true; flushOnReady(); if(hasLocalStorage){ if(!localStorage.getItem(cookie["flag"])) { (new Image).src = location.protocol + "//" + juke_host + "?uid=" + id + "&time=" + new Date().valueOf(); localStorage.setItem(cookie["flag"], "true"); } } else if(isCookieEnabled) { if(!getCookie(cookie["flag"])){ var expirationDate = new Date(); expirationDate.setFullYear(expirationDate.getFullYear() + 1); setCookie(cookie["flag"], "true", expirationDate.toGMTString(), "/", ""); (new Image).src = location.protocol + "//" + juke_host + "?uid=" + id + "&time=" + new Date().valueOf(); } } } function saveId(id){ uid = id; if(hasLocalStorage) { localStorage.setItem(cookie["id"], id); } else if(isCookieEnabled) { var expirationDate = new Date(); expirationDate.setFullYear(expirationDate.getFullYear() + 1); setCookie(cookie["id"], id, expirationDate.toGMTString(), "/", ""); setCookie(cookie["wasInitialized"], true, expirationDate .toGMTString(), "/", ""); } } function addParams(url, params){ var i, key; if(params instanceof Array) { for(i in params) { url = addParam(url, params[i]["key"], params[i]["value"]); } } else { for(key in params) { url = addParam(url, key, params[key]); } } return url; } function onFlashReady(id){ try { var div = document.getElementById(holder); div.parentNode.removeChild(div); } catch(e) { } swfobjectlite = null; onLocalReady(id); } function getVersion(){ return short_version; } function sendPost(url, params, time, onError){ try { var cors = createCors(onError); cors.open("POST", url, true); if(!params) { params = {}; } if(params instanceof Array) { params.push({ "key" : "cookie", "value" : uid }); params.push({ "key" : "time", "value" : time ? time : new Date().valueOf() }); } else { params["cookie"] = uid; params["time"] = time ? time : new Date().valueOf(); } if(isIE) { cors.contentType = "text/plain"; } else { cors.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8"); } var postParams = addParams("?", params).replace(/?/, ""); cors.send(postParams); }catch(e){ console.error(e); } } function sendGet(url, params, time, type, onError){ if(!params) { params = {}; } url = addParam(url, "cookie", uid); url = addParam(url, "time", time ? time : new Date().valueOf()); url = addParams(url, params); // TODO: If this version will be in production — return send JSONP capability try { // Opera supports CORS only since v12 // For other Operas there is no obvious way to call external API // except injecting script into page if((type && type == "JSONP") || (window.opera && !("withCredentials" in new XMLHttpRequest))) { var script = document.createElement("script"); script.setAttribute("src", url); document.getElementsByTagName("head")[0].appendChild(script); } else if(type && type == "GET") { var cors = createCors(onError); cors.open("GET", url, true); if(isIE == false) { cors.setRequestHeader("Accept", "application/json"); } cors.send(); } } catch(e) { console.log(e); } } return { "init" : function(){ if(wasInitialized == false) { if(isCookieEnabled && !getCookie(cookie["wasMigrated"])){ if(getBody()){ init(); }else{ head.ready(function(){ init(); }); } }else{ init(); } } else if(isReady) { flushOnReady(); } }, "send" : function(url, params, type, onError){ if(!params){ params = {}; } params["vt"] = idScope; var now = new Date().valueOf(); if(isReady) { if(/POST$/ig.test(type)) { sendPost(url, params, now, onError); } else { sendGet(url, params, now, type, onError); } } else { buffer.push({ "url" : url, "params" : params, "type" : type, "time" : now, "onError": onError }); } }, "onFlashReady" : function(id){ onFlashReady(id); }, "addOnReadyListener" : function(ref){ refs.push(ref); }, "isReady" : function(){ return isReady; }, "getId" : function(){ return uid; }, "version" : function(){ return getVersion(); } };})(); IDCore["init"]();/*jslint browser:true,devel:true,plusplus:true,regexp:true*//*global TUtility,IDCore,addonCMeter,ENABLE_CONSOLE*//** @const */var VERSION = "3.3.280_ua";var v = VERSION + "/" + IDCore.version(), perf = window.performance, perf_t = perf ? perf.timing : null, started = perf_t ? new Date(perf_t.navigationStart || perf_t.connectStart) : new Date(), ua = navigator.userAgent, mobile = /android|mobi|mini|blackberry|samsung|bada|nokia|series|symb(ian|os)|playstation/i.test(ua), vendors = ["", "moz", "ms", "webkit"], isFrame = top !== self, id = IDCore.getId(), templates = {}, excludeElements = [], // array for keeping exclude elements from video tags subscribers = {};// Utils/** * Just empty function. Intended for some cases as callback where no actions should be performed */function nop() {}function random() { var d = new Date().valueOf().toString(); return parseInt(d.substr(d.length — 8, d.length)) + Math.round(Math.random() * Math.pow(10, 9));};var hasFlash = (function(){ if(typeof navigator.plugins == "undefined" || navigator.plugins.length == 0) { try { return !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash")); } catch(er) { return false; } } else { return navigator.plugins["Shockwave Flash"]; }}());/** * Strip initial & trailing whitespaces. * * @param str * @returns {String} */function trim(str) { if (String.prototype.trim !== undefined) { return String.prototype.trim.call(str); } return str.replace(/s+|s+$/g, »);}/** * Apply callback to each element of the sequence (arr item / sting symbol) * * @param {Array|String|NodeList} arr array to process * @param {Function} cb callback to apply to each array item */function each(arr, cb) { var i, l; if (!arr) { return; } l = arr.length; if (!l) { return; } for (i = 0; i < l; i += 1) { try { cb(arr[i], i, arr); } catch (ignore) {} }}/** * We need such function since IE < 9 doesn’t support it natively for arrays — http://stackoverflow.com/a/9768663 * * @param {Array} arr * @param item * @return {Number} index >= 0 if found, -1 otherwise */function indexOf(arr, item) { var i = 0, l = arr.length; while (i < l) { if (arr[i++] === item) { return i — 1; } } return -1;}function bind(fn, obj) { return function () { return fn.apply(obj, arguments); };}/** * asynchronous version of each function — apply callback to each element of array and call in async way and finally call custom callback * * @param {Array} arr array to walk * @param {Function} cbEach callback to apply to each element of the array * @param {Function} [cbEnd] function to be called on the end of * @returns {Boolean|undefined|Number} setInterval ID, false or nothing */function iterateAsync(arr, cbEach, cbEnd) { var interval, l; cbEnd = cbEnd || nop; if (!arr) { return false; } l = arr.length; if (0 === l) { cbEnd(); } if (!l) { return undefined; } interval = setInterval(function () { var i = 10; // every time use next 10 items from arr do { l -= 1; if (-1 === l) { clearInterval(interval); cbEnd(); return; } cbEach(arr[l], l, arr); } while (—i); }, 4); return interval;}/** * Extend destination object with the items from the source object. * If 3d argument is true, functions from the source are bound and then copied. * Function returns nothing, first argument is modified instead * * @param {Object} dest destination, where to copy items from the source * @param {Object} src source object from where items are taken * @param {Boolean} [bindFuncs] if true — functions in the source will be bound and returned rather then original functions */function extend(dest, src, bindFuncs) { var k, item; for (k in src) { if (src.hasOwnProperty(k)) { item = src[k]; dest[k] = bindFuncs && "function" === typeof item ? bind(item, dest) : item; } }}function on(node, event, cb) { if (window.addEventListener) { node.addEventListener(event, cb, false); } else if (window.attachEvent) { node.attachEvent("on" + event, cb); }}/** * Schedule callback to be run when DOM is ready. * Callback will be fired immediately if DOM has already been parsed. * * @param {Function} cb callback to execute */function onready(cb) { function done() { each(onready.funcs, function (cb) { cb(); }); delete onready.funcs; } function onreadystatechanged() { if ("loading" !== document.readyState) { done(); document.detachEvent("onreadystatechange", onreadystatechanged); } } if ("loading" !== document.readyState) { cb(); return; } if (onready.funcs) { onready.funcs.push(cb); } else { onready.funcs = [cb]; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", done, false); return; } if (document.attachEvent) { document.attachEvent("onreadystatechange", onreadystatechanged); } }}/** * Schedule callback to be run on window load. * Callback will be fired immediately if window is * already neither loading nor parsing DOM. * The only argument passed against callback is time when * load state had been reached. * * @param {Function} cb callback function to be run */function load(cb) { var q; function done() { var e = "loadEventStart"; load.time = perf_t && perf_t[e] > 0 ? new Date(perf_t[e]) : new Date(); while (q.length) { q.shift()(load.time); } } if (load.time) { cb(load.time); return; } if (!load.queue) { load.queue = []; on(window, "load", done); } q = load.queue; q.push(cb); if ("complete" === document.readyState) { done(); }}function onViewportChange(cb) { on(window, "scroll", cb); on(window, "resize", cb); cb();}// TODO: Investigate if it is better to pass object w/ methods// instead of two separate callbacks.// Will it need to implement @interface to compile properly?function onVisibilityChange(cbVis, cbInv) { var i, field; cbInv = cbInv || nop; function trigger() { var state = document[field] || "visible"; switch (state) { case "hidden": cbInv(state); break; default: cbVis(state); break; } } for (i = 0; i < vendors.length; i++) { field = vendors[i] + "VisibilityState"; field = field.charAt(0).toLowerCase() + field.substring(1); if (document[field]) { // we create and register new trigger() on // every call to function onVisibilityChange on(document, vendors[i] + "visibilitychange", trigger); if ("hidden" !== document[field]) { trigger(); } return; } } trigger();}/** * Split string to Key-value object. * @param {String} source string for parse * @returns {Object} Key-value Object */function parseParams(source) { var params = {}; if (source) { each(source.split("&"), function (param) { var p = param.split("="); params[decodeURIComponent(p[0].toLowerCase())] = decodeURIComponent(p[1]); }); } return params;}/** Function tries identify path to ads destination. * * @param {Element} node for inspection. * @returns {String|Boolean} path to ads source or false. */function getDestinationPath(node) { var tagName = node.nodeName, cl, param_str, params_list = node.childNodes, parent = node.parentNode, node_attr = », params = {}; function findParam(params) { var result = false; each([‘link1’, ‘clicktag’, ‘alink1’, ‘url’], function (attr_value) { if (params.hasOwnProperty(attr_value)) { result = params[attr_value]; } }); return result; } switch (tagName) { case "IMG": while (parent) { if ("A" === parent.nodeName) { cl = parent.href; break; } parent = parent.parentNode; } break; case "OBJECT": each(params_list, function (param) { if ("PARAM" === param.nodeName && "flashvars" === param.getAttribute("name").toLowerCase()) { param_str = param.getAttribute("value"); params = parseParams(param_str.replace(/&/g, "&")); cl = findParam(params); } }); break; case "EMBED": node_attr = node.getAttribute("flashvars"); if (node_attr) { params = parseParams(node_attr.replace(/&/g, "&")); cl = findParam(params); } break; } try { if ("string" === typeof cl) cl = decodeURIComponent(cl); } catch (ignore) {} return cl;}function getDocumentHeight() { var b = document.body, d = document.documentElement, h = b ? Math.max(b.scrollHeight, b.offsetHeight, b.clientHeight) : 0; return Math.max(h, d.scrollHeight, d.offsetHeight, d.clientHeight);}function isVisible(node) { var retVal = false, r, rects = node.getClientRects(), h = getDocumentHeight(), i = rects.length; while (i—) { r = rects[i]; if (0 === r.width || 0 === r.height) { continue; } if (r.top > 0) { return r.top <= h; } if (r.bottom > 0) { return r.bottom <= h; } retVal = true; } return retVal;}/** * Get specific style’s value of the DOM element * * @param {Element} element DOM element to explore * @param {String} name style name * @returns {String|null} Text style value **/function getStyle(element, name) { var s; if (document.defaultView && document.defaultView.getComputedStyle) { // W3C name = name.replace(/([A-Z])/g, "-$1").toLowerCase(); s = document.defaultView.getComputedStyle(element, null); return s && s.getPropertyValue(name); } if (element.currentStyle) { // IE? return element.currentStyle[name]; } if (element.style && element.style[name]) { return element.style[name]; } return null;}/** * Calculate offset of the element, taking into account all his parents. * If on any step there is NaN (seems no offsetTop / offsetLeft property) — undefined is returned instead * Falsie argument returns (0; 0) coordinates * * @param {Object} e DOM element object * @returns {Object} {left: X, top: Y} */function getOffset(e) { if (!e) { return { top: 0, left: 0 }; } var offset = { top: e.offsetTop, left: e.offsetLeft }, parent = getOffset(e.offsetParent); offset.top += parent.top; offset.left += parent.left; if (isNaN(offset.top)) { offset.top = undefined; } if (isNaN(offset.left)) { offset.left = undefined; } return offset;}// WARNING: it will return zero as height for document.body if there is// only one element on page and it has been positioned absolutelyfunction getSize(node) { var props = { w: ["paddingLeft", "paddingRight", "borderLeftWidth", "borderRightWidth"], h: ["paddingTop", "paddingBottom", "borderTopWidth", "borderBottomWidth"] }, s = { w: node.offsetWidth, h: node.offsetHeight }, type, i, style; for (type in s) { if (s.hasOwnProperty(type)) { if (s[type] > 0) { i = props[type].length; while (i—) { s[type] -= parseInt(getStyle(node, props[type][i]), 10) || 0; } } style = s[type] || getStyle(node, "w" === type ? "width" : "height"); if (/%/.test(style)) { continue; } s[type] = parseInt(style, 10); } } return s;}function getDoc(node) { // second is for IE<8 (http://stackoverflow.com/a/6582370) return node.contentDocument || (node.contentWindow && node.contentWindow.document) || node.document || null;}// this must be tested on different browsers, code looks like obsoletefunction getWindowTop() { var b = document.body, d = document.documentElement; if ("number" === typeof window.pageYOffset) { return window.pageYOffset; // Netscape compliant } if (d && d.scrollTop) { return d.scrollTop; // IE6 standards compliant mode } if (b && b.scrollTop) { return b.scrollTop; // DOM compliant } return 0;}/** * Iterate through node children (including node itself) applying callback * to each of them. * Useful for searching something inside document. * * @param node {DOMElement} * @param {Function} cb callback to apply to each node * @returns {*} */function domIterate(node, cb) { var nodes = node.childNodes, i = nodes.length, ret; while (i—) { ret = domIterate(nodes[i], cb); if (ret) { return ret; } } return cb(node);}function iframeAccessible(frame) { try { var src = frame.getAttribute("src") || "", index = src.indexOf("//" + location.host), document; if ((0 !== src.indexOf("http") && 0 !== src.indexOf("//")) || (index > -1 && index < 8)) { document = getDoc(frame); if (document && document.getElementById) { return true; } } } catch (ignore) {} return false;}function getNodeSrc(node) { var src, i, params, param; function checkExcludes(element) { if (-1 === indexOf(excludeElements, element)) { excludeElements.push(element); } } if (!node.tagName) { return false; } if ("OBJECT" === node.tagName) { src = node.getAttribute("data"); if (!src) { // [fix23828] as of msdn.microsoft.com/library/ms536439#5 /* params = node.getElementsByTagName("param"); i = params.length; while (i—) { if ("movie" === params[i].getAttribute("name")) { return params[i].getAttribute("value"); } } */ params = node.childNodes; i = params.length; while (i—) { param = params[i]; if ("PARAM" === param.nodeName && "movie" === param.getAttribute("name").toLowerCase()) { return param.getAttribute("value"); } } } return src; } if ("VIDEO" === node.tagName) { var sources = node.childNodes, length = sources.length, sourceElement, src ,type; if (!node.canPlayType){ return false; } for (var i = 0; i < length; i++) { sourceElement = sources[i]; if ("SOURCE" === sourceElement.nodeName) { type = sourceElement.getAttribute("type"); if (node.canPlayType(type)) { src = sourceElement.getAttribute("src") || false; each(node.getElementsByTagName("embed"), checkExcludes); each(node.getElementsByTagName("object"), checkExcludes); return src; } } } src = node.getAttribute("src"); return src; } else { src = node.getAttribute("src"); if (src != null && src.substring(0, 10) !== ‘data:image’) { src = node.getAttribute("src"); } else { if (src && src.substring(0, 10) == ‘data:image’) { return CONFIG.juke_host || null; } else { return null } } } return src;}function emit (event, data) { each(subscribers[event], function (func) { if (ENABLE_CONSOLE) { console.log("fire callback"); } data = func.call(this, data); }); return data;}// Classes/** * A message. * @constructor */function CM_Message(type, obj) { var that = this; function addonReady(e) { if ("AddonCMeterReady" !== e.data) { return; } that.initialize(); window.removeEventListener("message", addonReady, false); } on(window, ‘beforeunload’, function(e) { that.doNotSendError = true; }); if (arguments.length >= 2) { extend(this, obj, true); } /** * `params` must be an array, but may have additional own properties. * They will be sent along w/ ordinary array items. * * For instance, consider the following: * var params = ["~param1~", 2]; * params.customKey = "customVal"; * * This will send following message: * param1: "~param1~" * param2: 2 * customKey: "customVal" */ this.params = this.params || []; this.params[0] = "~cm_" + type + "~"; if (this.initialize) { // XXX: Google Chrome extension workaround. if (window.localStorage && "initializing" === localStorage.getItem("AddonCMeter")) { window.addEventListener("message", addonReady, false); } else { this.initialize(); } }}extend(CM_Message.prototype, { httpMethod: "GET", origin: location.protocol + "//" + ("https:" === location.protocol ? CONFIG.sslhost : CONFIG.host), sid: random(), /** * Compile and return common properties of client, such as location, referrer, screen properties and others * * @this {CM_Message} * @return {Object} Keys: location, referrer, is_flash, session_id, version, sw, sh, scd [, spd, tnscm_plid, tnscm_cat, tnscm_adn] * */ getCommonParams: function () { var p = { "location": encodeURIComponent(window.location.href), "referrer": encodeURIComponent(document.referrer), "is_flash": hasFlash ? "1" : "0", "session_id": this.sid, "version": v, "sw": screen.width, "sh": screen.height, "scd": screen.colorDepth }; if (screen.pixelDepth) { /** @expose */ p.spd = screen.pixelDepth; } if (window.addonCMeter && addonCMeter.PLID) { /** @expose */ p.tnscm_plid = addonCMeter.PLID; } if (window.tnscm_cat) { /** @expose */ p.tnscm_cat = tnscm_cat; } if (window.tnscm_adn) { /** @expose */ p.tnscm_adn = window.tnscm_adn; } if (window.tnscm_pak) { /** @expose */ p.tnscm_pak = tnscm_pak; } return p; }, /** * Send message. Run either commit or onBeforeCommit handler if exists * * @this {CM_Message} **/ send: function () { if (this.onBeforeCommit) { this.onBeforeCommit(); } else { this.commit(); } }, /** * Actually send message (with id.js) * * @protected * @this {CM_Message} **/ commit: function () { var that = this, i = 0, item, params = {}, cloned = []; extend(params, that.getCommonParams()); extend(cloned, that.params); while (cloned.length) { i += 1; item = cloned.shift(); if (item || 0 === item) { params["param" + i] = item; } } extend(params, cloned); if (!ENABLE_ERROR_HANDLING) { IDCore.send(that.url, emit("send", params), that.httpMethod); } else { IDCore.send(that.url, emit("send", params), that.httpMethod, function (xhr) { if (that.doNotSendError) { return; }; // setup error handler (see #36588) var params, resp = xhr.responseText || ""; params = { "http_code": encodeURIComponent(xhr.status), "http_status": encodeURIComponent(xhr.statusText), "http_body": encodeURIComponent(resp.substr(0, 400)), "message_type": that.params[0] }; extend(params, that.getCommonParams()); if (ENABLE_CONSOLE) { console.log(params, "error reported"); } IDCore.send(location.protocol + "//" + CONFIG.err_host + "/e", params, "GET"); }); } if (ENABLE_CONSOLE) { console.log(that.params[0], "sent"); console.log(params); } }});extend(CM_Message.prototype, { url: CM_Message.prototype.origin + "/pagestat/PageStatEntry"});/** * An advertisement template. * @constructor */function CM_Template(params) { var that = this, num = ["w", "h"], rexp = ["src"]; // default values // XXX: it is not exposed anywhere, but current implementation of // this constructor is tied to names. Consider rewriting into code, // better optimized for compiling by Google Closure Compiler in future /** @expose */ this.w = null; /** @expose */ this.h = null; each(params, function (param) { var k, v = parseInt(param, 10); if (!isNaN(v)) { k = num.shift(); } else if (param instanceof RegExp) { k = rexp.shift(); v = param; } if (k) { that[k] = v; } }); // empty template should not catch anything if (!this.src && (this.w || this.h)) { // see comment about Closure Compiler above /** @expose */ this.src = /./; }}extend(CM_Template, { /** * Create list of signatures (objects) based on incoming array of templates. Synchronous method * * @param {Array} arr list of signature templates * @returns {Object} array of signatures */ build: function (arr) { var use = true, isCurrent = false, retVal = {common: [], current: []}; each(arr, function (t) { if (t instanceof RegExp) { use = isCurrent = t.test(window.location.host); } else if (use && !isCurrent) { retVal.common.push(new CM_Template(t)); } else if (use && isCurrent) { retVal.current.push(new CM_Template(t)); } }); return retVal; }, embeds: function (doc) { var embeds = [], objects = []; doc = doc || document; each(doc.getElementsByTagName("embed"), function (embed) { var parent = embed.parentNode; while (parent) { if ("OBJECT" === parent.nodeName) { objects.push(parent); break; } parent = parent.parentNode; } if ( -1 === indexOf(excludeElements, embed)) { embeds.push(embed); } }); each(doc.getElementsByTagName("object"), function (node) { // skip s, that contain nested if (-1 === indexOf(objects, node) && -1 === indexOf(excludeElements, node)) { embeds.push(node); } }); return embeds; }, // passing real DOM Nodes every time was considered too expensive scan: function (nodesData) { var ads = [], isAd, typeTemplate; function checkNodes(type, node) { each(templates.yes[type], function (t) { if (t.check(node[0], node[1], node[2])) { isAd = true; if (ENABLE_CONSOLE) { console.log(‘include ‘ + ‘ ‘ + node[0] + ‘ [‘ + node[1] + ‘, ‘ + node[2] + ‘] by signature — ‘ + t.src + ‘[‘ + t.w + ‘, ‘ + t.h + ‘] (‘ + type + ‘)’); } } }); if (isAd) { // take out from inside templates.yes loop because it didn’t execute if templates.yes.current is empty each(templates.no[type], function (t) { if (t.check(node[0], node[1], node[2])) { if (ENABLE_CONSOLE) { console.log(‘exclude ‘ + node[0] + ‘ [‘ + node[1] + ‘, ‘ + node[2] + ‘] by signature — ‘ + t.src + ‘[‘ + t.w + ‘, ‘ + t.h + ‘] (‘ + type + ‘)’); } isAd = false; } }); } } // TODO: use filter() here instead of each() each(nodesData, function (node, index) { isAd = false; for (typeTemplate in templates.yes) { if (templates.yes.hasOwnProperty(typeTemplate)) { checkNodes(typeTemplate, node); } } if (isAd) { ads.push(index); } }); return ads; }});extend(CM_Template.prototype, { /** @this {CM_Template} */ check: function (src, w, h) { if (this.src && !this.src.test(src)) { return false; } if (this.w && this.w !== w) { return false; } if (this.h && this.h !== h) { return false; } return true; }});// Run only onceif (!window["__cm"]) { var cm = window["__cm"] = []; extend(cm, { "on": function (event, callback) { if (!subscribers[event]) { subscribers[event] = []; } subscribers[event].push(callback); } });}// TODO: !region-id is better to be defined as @const and// then replaced during Closure Compiler compilation// as well as VERSION variableif (indexOf(window[‘__cm’], "ua") == -1) { window.tnscm_adn = window.tnscm_adn || []; if (indexOf(window.tnscm_adn, "inline_cm") < 0) { var cmInlined = domIterate(document, function (node) { if (8 === node.nodeType && "MMI CMeter" === trim(node.nodeValue)) { return true; } }); if (cmInlined) { tnscm_adn.push("inline_cm"); } } templates.yes = CM_Template.build([ [/.googlesyndication.com//i], [/static..*.kcdn.kz//i], [/base.kiwi.kz//i], [/rate.ru/banner/i], [/b.c8.net.ua//i], [/post.rmbn.net//i], [/kz.adocean.pl//i], [/sensismediasmart.com.ua/i], [/dotua.org//i], [/advideo.com.ua//i], [/admixer.net/i], [234, 200], [205, 333], [205, 280], [205, 60], [203, 70], [950, 90], [760, 90], [730, 60], [730, 90], [728, 90], [640, 90], [500, 100], [468, 120], [468, 60], [320, 76], [320, 60], [300, 600], [300, 250], [300, 240], [285, 130], [250, 250], [240, 400], [240, 350], [240, 200], [240, 90], [234, 60], [230, 90], [230, 60], [180, 150], [160, 600], [160, 60], [150, 60], [120, 600], [120, 240], [120, 60], [/bigbn.com.ua/i], [/adriver.ru/i], [/banner.km.ua/i], [/bannerka.ua/i], [//.*/adfox/.*/.*.swf/i], [/rle.ru/i], [/reclama./i], [/adcenter.net/i], [/bbn.img.com.ua/i], [/images.rambler.ru/upl//i], [//images/.*/.*/.*/.*300×250./i], [/ab.adpro.com.ua/.*/.*/.*./i], [/images/.*/.*300×150.*./i], [/baner./i], [/www.ukr.net/img/autos/auto.*.jpg$/i], [//data/enquetes/images/banner_.*./i], [/www.ukr.net/_temp/.*/../../.*.jpg$/i], [/ad.*.bigmir.net/i], [/meta.ua/img/.*/.*_200_300_.*href=/i], [//css/partner-swf/.*./i], [//banners_files/.*./i], [/b.ex.ua/.*/.*.swf/i], [/adbrite.com/i], [//openx/www/images/.*./i], [//bnr//i], [/ban./i], [//adban/.*/.*/.*./i], [/informers.sinoptik.ua/i], [/adnet.com.ua/banners/.*/.*/.*/.*./i], [/rose.ixbt.com/i], [//adv//i], [//pagead/imgad.id=/i], [//adimage.php/i], [/i.holder.com.ua/.*/.*/.*/.*./i], [/img.gad.org.ua/.*/.*./i], [//images/.*/.*/.*/.*.swf$/i], /mail.ru/, [/r.mradx.net//i, 300, 300], [/r.*.mail.ru/b.*.gif$/i], [/r.*.mail.ru/b.*.png$/i], [/r.*.mail.ru/b.*.jpg$/i], [/r.*.mail.ru/b.*.swf$/i], [/promoblocks.ru/i], /podrobnosti.ua/, [/media.adrcdn.com/ads//i], /football.ua/, [/spadsmedia.com/www/delivery/afr.php//i], [/sportingbet.host.bannerflow.com//i], /.kz/, [//banners/i], /total.kz/, [1000, 115], [//gb.php..*=/i], /namba.net/, [468, 90], [1000, 90], [200, 350], /besplatka.ua/, [300, 300], [660, 90], /nur.kz/, [//advert//i], /magnolia-tv.com/, [668, 60], [300, 100], [//files/ban//i], [100, 100], /blogas.lt/, [/static-system.adtarget.me//i], [/banners.adnet.*.lt//i], [980, 200], [750, 200], [980, 180], /companion.ua//, [960, 90], /172.16.0./, [/.gif/i], [/.png/i], [/.swf/i], [/.jpeg/i], [/.jpg/i], /ex.ua/, [/ad_click/i], /cm.mmi.macc.com.ua$/, [100, 100], /aviso.ua/, [/banner.ool.ua//i] ]); templates.no = CM_Template.build([ [/gwallet.com//i], [/predictormedia.com//i], [/img.ubr.ua/banners/.*adsense./i], [/dotomi.com//i], [/mobileadhost.com//i], [/adsoptimizer.net//i], [/ad-sys.com//i], [/drivesection.net//i], [/tooldiv.net//i], [/livexjs.net//i], [/fellabooks.net.*/$/i], [/chocolatemx.net//i], [/aspire-guitar.com//i], [/golinkon.info//i], [/perfectnavigator.com//i], [/aceadsys.net/show_banner//i], [/googleads/i], [/.host.bannerflow.com//i], [/serving.*.com//i], [/tracking.m6r.eu//i], [/upload.*/articles//i], [/zedo.com//i], [/gogorithm.com//i], [/pdmayt.com//i], [/metrigo.com//i], [/vdaqyqwsrd.ru//i], [/qrdeom.com//i], [/tatami-solutions.com//i], [/cloudfront.net//i], [/mrlmedia.net//i], [/mothernist.hiro.tv//i], [/.wlboon.com//i], [/admetaserver.com//i], [/.ru/show_banner//i], [/tags.qservz.com//i], [/neomion.com//i], [/http://54./i], [/x.abk954.com/i], [/creative.xtendmedia.com//i], [/statisticsreporting.com//i], [/imhonet.ru/element//i], [/mailsmania.ru//i], [/romilit.com//i], [/proligtb.com//i], [/brucelead.com//i], [/exebid.ru//i], [/koluty.com//i], [/.retark.com//i], [/com.adv.vz.ru//i], [/adserver/i], [/webmoney.ua/tools//i], [/weropiy.com//i], [//games/img//i], [/flashgames.*..*//i], [/games.info//i], [/maikaru.ru/picture//i], [/zvek.com.ua/images//i], [/get_qrapi/i], [/grandcapital.ru/static/img/i], [/jsticket.net//i], [/creativecdn.com//i], [/.rontar.com//i], [/greefl.com//i], [/.jutulep.com//i], [/baseflash.com//i], [/media.tumblr.com//i], [/gstatic.com//i], [/ssp.adriver.ru/cgi-bin/sync.cgi/i], [/tractionize.com//i], [/secure.demand-go.com//i], [/rbc.ua/static/adsense/i], [/tvi.ua/adsense/i], [/yourbucks.org//i], [/datamind.ru//i], [/fresh-cup.org//i], [/ad.starlightmedia.ua//i], [/financecontext.ru//i], [/attiveri.com/.* $/i], [/youtube.com//i], [/meta.ua/cell.php/i], [/paramedjo.com//i], [/intencysrv.com//i], [/kilopog.com//i], [/gravyseals.com//i], [/media6degrees.com//i], [/lokomusic.com//i], [/tisa.ama.com/banner.php/i], [/ministerial5.com//i], [/admailtiser.com//i], [/adgorithms.com//i], [//media/gallery//i], [/.dotua.org/.*/cover/.*.jpg$/i], [/wp-content/upload/i], [/netdna-cdn.com//i], [//logo/i], [/adsmile.biz//i], [/medads.ru//i], [/gittigidiyor.com//i], [/oneund.com//i], [/xmasdom.com//i], [/rainoftraffic.info//i], [/1xbet.com//i], [/clkrev.com//i], [/pub-fit.com//i], [/clicksor.com//i], [/sendspace.com//i], [/pgssl.com//i], [/rutarget.ru//i], [/datropy.com//i], [/dolka.ru//i], [/batanga.net//i], [/adorika.net//i], [/rfihub.com//i], [/loponop.com//i], [/palgames.info//i], [/play882.info//i], [/medialand.ru//i], [/funnygamezer.info//i], [/cloudgamezer.com//i], [/utrehter.com//i], [/hopto.me//i], [/intag.co/.* $/i], [/adk2.com//i], [/img.admaster.net//i], [/openx.net//i], [/firstadvplug.com//i], [/pirrit.com//i], [/metka.ru//i], [/tomobol.com//i], [/adzoook.com//i], [/adservingfree.info//i], [/drgo.ru//i], [/slopty.ru//i], [/tradedoubler.com//i], [/fastloca.com//i], [/hide4you.com//i], [/proxy.net//i], [/bannerhost.ru//i], [/bannercity.ru//i], [/m2pub.com//i], [/theseaapp.com//i], [/holisticmedicalwellness.com//i], [/qonenoj.ru//i], [/amazonaws.com//i], [/ipicture.ru/uploads//i], [/reacten.com//i], [/thinglink.me//i], [/ad.mail.ru/adi//i], [/k8media.com//i], [/notificatoin.com//i], [/co-co-co.co//i], [/.dd34.ru//i], [/screenshot/i], [/yidop.com//i], [/phncdn.com//i], [/pokitom.com//i], [/perfectmoney.is//i], [/20dollars2surf.com//i], [/bet-at-home.com//i], [/.derploime.com//i], [/.nekki.ru/banner.php/i], [/tlvmedia.com//i], [/yoz5.info//i], [/game.*.info//i], [/jumbaexchange.com//i], [/media-servers.net//i], [/gnezdo.ru//i], [/quelliclub.ru/slider//i], [/all.biz/img/.*/catalog/.*.png/i], [/azd3.info//i], [/26sec.com//i], [/magicplayer.torrentstream.org//i], [/refban.com//i], [/microads.ru//i], [/scanmedios.com//i], [/trkclk.net//i], [/game.*.com//i], [/porn.com//i], [/062.ua/delivery/afr.php/i], [/ro2.biz/ad.php/i], [/gmodules.com//i], [/bremdy.ru//i], [/biglu.ru//i], [/pricora.com//i], [/twitbridge.com//i], [/resultsaccelerator.net//i], [/gayua.com//i], [/okitspace.com//i], [/yottos.com//i], [/teaserjs.info//i], [/wambacdn.net//i], [/adultadworld.com//i], [/adnetworkme.com//i], [/seethisinaction.com//i], [/cameleo.ru//i], [/exoclick.com//i], [/.rubiconproject.com//i], [/.adnetwork.*.net//i], [/mediads.info//i], [/.zanox.com//i], [/.abnad.net/i], [/reachjunction.com//i], [/.e-viral.com//i], [/.traffichaus.com//i], [/.cmle.ru//i], [/datam.com//i], [/improvemedianetwork.com//i], [/adxplosions.com//i], [/mediaplex.com//i], [/redintelligence.net/request_content.php/i], [/baserve.net/serve.php/i], [/ktbt.ru/b.php/i], [/sociomantic.com//i], [/yangot.com//i], [/static.*.rutracker.org/iframe/i], [/partners.otpusk.com/media.php/i], [/image.tsn.ua/media/images/i], [/nepalon.com//i], [/.56.*.net/.*2.php/i], [//vast.php/i], [/ad.*.adkserve.com//i], [/r.c8.net.ua/getiframe.php/i], [/s.holder.com.ua/s/i], [/.avazu.net//i], [/media.glispa.com//i], [/squirrelsigdrs.in//i], [/overridingnichts.in//i], [/tecontx.com//i], [/ad-srvr.com//i], [/pswec.com//i], [/hubrus.com//i], [/beatwaretranscribing.in//i], [/ads.people-group.net/i], [/holyclick.ru/i], [/.bidsystem.com/i], [/zpk200.com/serve/i], [/imgads..*.net/afr.php/i], [/.btricl3.ru/js/rot.php/i], [/.tizerbank.com//i], [/.plomihy.com/i], [/static.adv.*.ru/banners//i], [/meta.ua/f_new.asp/i], [/bdv.bidvertiser.com/bidvertiser.dbm/i], [/squirrelsigdrs.in/banners/show.php/i], [/code.gif/i], [/calend.ru/img/calendar//i], [/hochu.ua/images/articles//i], [/tagcloud.swf/i], [/myinfotopia.com//i], [/swfhttprequest.swf/i], [/cityads.ru//i], [//www/delivery//i], [/z5x.net//i], [/adotube.com//i], [/lux-bn.com.ua//i], [/criteo.com//i], [/autocompleteplus.com//i], [/akamaihd.net//i], [/etgdta.com/i], [/soundmanager.*.swf/i], [/player.swf/i], [/img.traffim.com//i], [/sharedaddomain.com//i], [/avalala.com//i], [/meta.ua/img/b/roll_flv2.swf/i], [/flowplayer/i], [/manifest.f4m/i], [/radikal.ru//i], [/jsonlock.net//i], [/medbrowse.com.ua/oops/i], [/.yandex./i], [/proxy.com/i], [/ternopilmarket.net/modules/goods/images//i], [/proxy.*.media.online.ua//i], [//picture.*_user//i], [/img.*.begun.ru//i], [/topdownloads.ru//i], [/gloker.org/upload/i], [/e-parfum.in.ua/products_image//i], [/mycdn.me//i], [/gallery.ru//i], [/adxpansion.com//i], [/creoads.com//i], [/bm.img.com.ua//i], [/adserver.juicyads.com//i], [/a.s3.ua//i], [/servedbyadbutler.com/i], [/kidstaff.net/i], [/counter.png/i], [100, 100], [/.rjainc.com/images/uploads//i], [//widget.*//i], [/lh.*.ggpht.com//i], [/cdn.adnxs.com/i], [/mathtag.com/i], [/kavanga.ru/i], [/anonymizer.com.ua/i], [/.adnxs.com/i], [/.yadro.ru/i], [//img.*/photo.*//i], [//foto//i], [/odnoklassniki./i], [/static/images/i], [/.vk.me//i], [/rollingstone.com//i], [//interview.*//i], [//post.*//i], [/ads.*.contentabc.com//i], [/ads.*.msn.com//i], [/ads.webmasters.ru//i], [/ads.vsisumy.com//i], [/ads.trk4.com//i], [/ads.trafficjunky.net//i], [/files/images/i], [/ads.porn.*//i], [/4baby.ua/pictures/i], [/.de//i], [//thumb.*//i], [/ad.drugasmuga.com/ban.php/i], [//public/images/gallery//i], [/w.*.am15.net//i], [/imgn.dt00.net//i], [/lcads.ru//i], [/gazzete.mk.ua/wp-content/uploads//i], [/techniks.mk.ua/wp-content/uploads//i], [/img.terrikon.info//i], [/img.ria.ua/photos/adv//i], [/optimizedby.brealtime.com//i], [//uploads/posts/i], [/source.mmi.bemobile.ua/video//i], [/avatar/i], [/.pcads.ru//i], [78, 78], [/uploads.ru//i], [88, 40], [/fliphotos.com//i], [/rand_img.php/i], [//images_slandocomua//i], [/chrome-extension:/i], [/about:blank/i], [/data:/i], [/hotline.ua/img/tx//i], [/gazeta.ua/img/preview//i], [/www.ex.ua/show//i], [/4baby.ua/productpicture//i], [/img.gad.org.ua/i], [/1×1.gif/i], [/vk.jpg/i], [/c.bigmir.net/i], [/adlesse.com/i], [/turzona.com.ua/i], [/kartinka.com.ua/i], [/totoro.com.ua/i], [/tas-ua.toboads.com/i], [/vk.com/i], [/infrm.weather.ua/image//i], [/vk_banner/i], [/.doubleclick.net/i], [/twitter.com/i], [/facebook.com/i], [/captcha/i], [/images.mob.ua//i], [/gorgeoushandbag.com//i], [/imgg.dt0.*.net//i], [/banner.ua/cgi-bin/core.fcgi/i], [/adverserve.net/i], [/yield.*.com//i], [/tbn.ru/i], [/adv.fraza.ua//i], [/sinoptik.ua/_uploaded_files/../../uft_……………………………jpg$/i], [/liga.net/www/images/.*./i], [/x.magnet.kiev.ua/www/images/.*./i], [/ads.*.com//i], /.kz/, [//i/0.*.gif/i], /krisha.kz/, [//i/pro//i], [70, 50], [120, 90], [60, 50], /kolesa.kz/, [60, 50], [//idrive//i], [//uploads/content//i], /magnolia-tv.com/, [/pictures/avatar//i], /infohome.com.ua/, [250, 250], /auto.mail.ru/, [/r.*.mail.ru/b.*.jpg$/i], /sport.ua/, [/sport.ua/images//i], /autocentre.ua/, [/autocentre.ua/images//i], /terrikon.com/, [//fans//i], /kievskaya.com.ua/, [/image.tsn.ua//i], /mbox2.i.ua/, [/fsimg.ru//i], /uaua.info/, [//pictures//i], /telekritika.ua/, [/telekritika.ua.*/imgs//i], [/telekritika.ua.*/images//i], /meteo.ua/, [/meteo.ua/var/banners/favorites_ua.jpg/i], /smartphone.ua/, [/smartphone.ua/img//i], [240, 400], /ria.ua/, [/img.ria.ua/photos/auto/i], /itc.ua/, [/itc.ua/files/pic/i], [/wp-content/i], /lissod.com.ua/, [//st_img/flash//i], /onlinetb.com.ua/, [200, 200], /delo.ua/, [/inf.korrespondent.net/i], [/informers.ukr.net/i], /sport-express.ua/, [/sport-express.ua/img//i], /calend.ru/, [/promo.1000zakazov.ru//i], [/shkolazhizni.ru/img/adv//i], /bestdroid.ru/, [/upload/i], /hnb.com.ua/, [/artimage/i], /biathlon.com.ua/, [/img/ministerstvo.gif/i], /hotline.ua/, [120, 60], /gazeta.ua/, [300, 240], /mamaclub.ua/, [300, 250], /myradio.ua/, [300, 250], /oceni.ua/, [250, 250], /ava.ua/, [240, 400], /games.bigmir.net/, [/ads..*./i], /connect.ua/, [300, 240], /bilshe.com/, [/banner/i], /realty.mail.ru/, [/img.pre.realty.mail.ru/.*.jpg$/i], /pogoda.mail.ru/, [/r.*.mail.ru/b.*.jpg$/i], /cards.mail.ru/, [/r.*.mail.ru/b.*.png$/i], /hi-tech.mail.ru/, [/r.*.mail.ru/b.*.png$/i], [/r.*.mail.ru/b.*.jpg$/i], /otvet.mail.ru/, [/r.*.mail.ru/b.*.gif$/i], /health.mail.ru/, [/r.*.mail.ru/b.*.gif$/i], [/r.*.mail.ru/b.*.jpg$/i], /deti.mail.ru/, [/r.*.mail.ru/b.*.jpg$/i], /mail.ru/, [/ban./i], [//adv//i], /cm.mmi.macc.com.ua$/, [/.png$/i] ]); var banners = new CM_Message("banners", { invisible: [], sentCount: 0, /** @this {CM_Message} */ initialize: function () { var ie = /MSIE/.test(ua), iphone3 = /iPhone OS 3/.test(ua); if (isFrame && !CONFIG.work_in_frame) { return; } this.httpMethod = window.opera || ie || iphone3 ? "GET" : "POST"; setInterval(function () { banners.scan(banners.onAdsDone); }, CONFIG.ads.scan_frequency * 1000); // Set `sr` by default to inactive tab value. // It will be removed immediately by the call of // onTabActive(), if tab has been opened active. /** @expose */ this.params.sr = 1; // XXX: should not need timeout setTimeout(function () { banners.scan(banners.onAdsDone); }, 4); // scan(this.onAdsDone); onVisibilityChange(this.onTabActive, this.onTabInactive); }, /** @this {CM_Message} */ onTabActive: function () { if (isFrame) { this.params.sr = 2; } else { delete this.params.sr; } }, /** @this {CM_Message} */ onTabInactive: function () { this.params.sr = 1; }, /** * Scan document for ads based on pre-configured positive & negative templates. * Passes found ads as Array to callback function from 1st param. * * @param {Function} cb callback where to pass found list of ads */ scan: function (cb) { var ads = [], callbacks = banners.scan.callbacks = banners.scan.callbacks || [], nodes = [], nodesData = [], SEARCH_DEPTH = 4; // same callback must not be called twice w/ same ads if (-1 === indexOf(callbacks, cb)) { callbacks.push(cb); } function searchBg(node, depth) { var items = node.childNodes || [], l = items.length, nodes = searchBg.nodes = searchBg.nodes || [], excludeTags = [‘head’, ‘script’, ‘style’]; if (depth <= 0 ) { return; } function getBg(node) { var style = node.currentStyle || window.getComputedStyle(node, null) || {}, bg = style.backgroundImage || false, MIN_WIDTH = 300, MIN_HEIGHT = 300; if (node.offsetWidth >= MIN_WIDTH && node.offsetHeight >= MIN_HEIGHT && bg !== ‘none’) { nodes.push({"node": node, "bg": bg.slice(4, -1)}); } } while (l—) { if (items[l].nodeType == 1 && indexOf(excludeTags, items[l].tagName.toLowerCase()) < 0) { getBg(items[l]); searchBg(items[l], depth — 1); } } return nodes; } // prepare cache of DOM to improve overall performance function prepare(doc) { function append(node) { var src = getNodeSrc(node), size = getSize(node); if (size.w <= CONFIG.ads.width || size.h <= CONFIG.ads.height) { return; } nodes.push(node); nodesData.push([src, size.w, size.h]); } each(doc.images || doc.getElementsByTagName("img"), append); each(doc.getElementsByTagName("video"), append); each(CM_Template.embeds(doc), append); each(doc.getElementsByTagName("iframe"), function (frame) { var frameWindow, insideCounter = false; if (iframeAccessible(frame)) { frameWindow = frame.contentWindow || frame.contentDocument.parent; if (!frameWindow[‘__cm’] || (indexOf(frameWindow[‘__cm’], ‘ua’) == -1)) { // TODO: refactor into containsCMeter() function and // reuse it in addon/cmeter_an.js/etc each(frameWindow.document.getElementsByTagName(‘script’), function (script) { var src = getNodeSrc(script), mask = /source.mmi.bemobile.ua/cm/(cmeter_an|cm).js/; if (mask.test(src)) { insideCounter = true; } }); if (!insideCounter) { if (ENABLE_CONSOLE) { console.log(‘start scanning iframe!’); } prepare(getDoc(frame)); } } } else { append(frame); } }); } prepare(document); each(CM_Template.scan(nodesData), function (idx) { ads.push(nodes[idx]); }); while (callbacks.length) { callbacks.shift()(ads, searchBg(document, SEARCH_DEPTH)); } }, /** * Callback that is passed to **scan** function. * It receives array of found banners, and for each banner that has not been sent yet calculates its normalized URL, obtains visibility and position, * manually converts list of [{link: "", pos: {left: X, top: Y}}] to JSON string and then sends by portions with 50 banners * * @param {Array} ads array of banners * @this {CM_Message} **/ onAdsDone: function (ads, backgrounds) { var that = this, r = [], cmeterAttr = "data-cmeter"; function send() { that.params.result = encodeURIComponent("[" + r.join(",") + "]"); if (ENABLE_CONSOLE) { console.log("found new ads:", r.length); } if (r.length) { that.send(); } } function append(src, pos, cl, btype) { var item = ""; item = ‘{"link":"’ + src + ‘", "pos":"’ + pos; if (cl) { item += ‘", "cl":"’ + cl; } if (btype != undefined) { item += ‘", "bt":"’ + btype; } return item + ‘"}’; } function setSentAttr(node) { node.setAttribute(cmeterAttr, ‘sent’); banners.sentCount++; } function getSentAttr(node) { var l = node.attributes.length, value; if (value = node.getAttribute(cmeterAttr)) { return value; } else { while (l—) if (node.attributes[l].nodeName == cmeterAttr) return node.attributes[i].nodeValue } } each(backgrounds, function(background) { if (getSentAttr(background[‘node’]) !== ‘sent’) { setSentAttr(background["node"]); r.push(append(background["bg"], 0, null, 2)); if (r.length >= 50) { send(); r = []; } } }); each(ads, function (ad) { if (getSentAttr(ad) !== ‘sent’) { var pos, src = getNodeSrc(ad), cl = getDestinationPath(ad); if (isVisible(ad)) { pos = getOffset(ad).top + getSize(ad).h; } else { // Ad may be considered invisible due to it is still // being loaded. Delay it’s sending till next scan. // See bug #29960 if (-1 === indexOf(that.invisible, ad)) { that.invisible.push(ad); return; } pos = -1; } setSentAttr(ad); r.push(append(src, pos, cl)); // Note: if there are 50 ads, then it will try to send() // twice (but second time should not make HTTP request) if (r.length >= 50) { send(); r = []; } } }); send(); } }); var timer = new CM_Message("timer", { /** @this {CM_Message} */ initialize: function () { // null can later be safely compared w/ numbers this.maxScrollHeight = null; if (isFrame && (!CONFIG.work_in_frame || CONFIG.addon_disable_frame_timers)) { return; } load(this.onWindowLoad); onViewportChange(this.onViewportChange); // since cm.js is executed exactly before // onload callback fires, // this delay gives scripts some time to subscribe // for very first __cm.on("send", …); to modify it setTimeout(function () { onVisibilityChange(timer.onTabActive, timer.onTabInactive); }, 20); }, /** @this {CM_Message} */ onBeforeCommit: function () { var now = new Date(), activated = this.activated || started, total = now — started, active = (this.inactived || now) — activated; this.params[1] = Math.round(active / 1000); this.params[2] = this.maxScrollHeight; this.params[4] = Math.round(total / 1000); this.commit(); this.commit.time = now; }, /** @this {CM_Message} */ tick: function () { var now = new Date(), commited = this.commit.time || 0, active = now — this.activated, param2 = Math.round(active / 1000), canCommit = Math.round((now — commited) / 1000) >= CONFIG.timer.frequency; if (!this.activated) { return; } if (!canCommit) { return; } if (param2 >= CONFIG.timer.stop_after * 60) { clearInterval(this.interval); if (ENABLE_CONSOLE) { console.log("timer stopped:", param2); } } // TODO: May param2 be lower than lastPing? if (param2 >= CONFIG.timer.pings[0]) { this.send(); if (1 === CONFIG.timer.pings.length) { this.pingsFrequency = CONFIG.timer.pings[0] — this.lastPing; if (ENABLE_CONSOLE) { console.log("last ping interval:", this.pingsFrequency); } } this.lastPing = CONFIG.timer.pings.shift(); } else if (param2 % this.pingsFrequency == 0) { this.send(); this.lastPing = param2; } else if (this.params[2] !== this.maxScrollHeight) { if (ENABLE_CONSOLE) { console.log("scrolled to point", this.maxScrollHeight); } this.send(); } }, /** @this {CM_Message} */ onWindowLoad: function (date) { this.params[3] = date — started; this.onViewportChange(); }, /** @this {CM_Message} */ onTabActive: function () { var now = new Date(); // it can be inactivated only after it was activated // and cm.js should count only first activation if (!this.inactived) { this.activated = now; if (ENABLE_CONSOLE) { console.log("timer activated", +now); } if (mobile) { var that = this; setTimeout(function () { if (!(banners.sentCount + banners.invisible.length)) { that.tick(); } }, CONFIG.ads.scan_frequency * 1000 + 1000); } else { this.interval = setInterval(this.tick , 1000); // and send on 0th second this.send(); } } }, /** @this {CM_Message} */ onTabInactive: function () { var now = new Date(); if (!this.inactived) { this.inactived = now; if (!mobile) this.send(); if (ENABLE_CONSOLE) { console.log("timer deactivated", +now); } clearInterval(this.interval); } }, /** @this {CM_Message} */ onViewportChange: function () { var b = document.body, d = document.documentElement, t = getWindowTop(), h = "clientHeight" in d ? d.clientHeight : 0; if (b) { h = document.compatMode === "CSS1Compat" ? d.clientHeight : b.clientHeight; } if (t + h >= this.maxScrollHeight) { this.maxScrollHeight = t + h; } } }); window[‘__cm’].push("ua");}}(window, document));

/** @preserve version 3.3.280_ua *//** @define {boolean} */var ENABLE_CONSOLE = true;/** @define {boolean} */var ENABLE_ERROR_HANDLING = false;(function (window, document, undefined) {"use strict";/** @const*/var CONFIG = { source : ‘source.mmi.bemobile.ua’, juke_host: "juke.mmi.bemobile.ua/bug/pic.gif", host: "pagestat.mmi.bemobile.ua", sslhost: "sslpagestat.mmi.bemobile.ua", err_host: "er.mmi.bemobile.ua", timer: { frequency: 5, // seconds pings: [5, 15, 30, 60, 120], stop_after: 5 // minutes }, ads: { scan_frequency: 5, // seconds // minimal size width: 50, height: 40 }};extend(CONFIG, window.addonCMeter && addonCMeter.config);/** * Prepare CONFIG array for use. Apply local params for the specific domain. Add parameter for be able to work in iframe (by default is true). * */if (CONFIG.custom_url && location.host === CONFIG.custom_url.href) { CONFIG.ads.scan_frequency = CONFIG.custom_url.banner_scan_frequency; CONFIG.work_in_frame = CONFIG.custom_url.work_in_frame;} else { CONFIG.work_in_frame = true;}// this part is already in helpers.js/** * Extend destination object with the items from the source object. * If 3d argument is true, functions from the source are bound and then copied. * Function returns nothing, first argument is modified instead * * @param {Object} dest destination, where to copy items from the source * @param {Object} src source object from where items are taken * @param {Boolean} [bindFuncs] if true — functions in the source will be bound and returned rather then original functions */function extend(dest, src, bindFuncs) { var k, item; for (k in src) { if (src.hasOwnProperty(k)) { item = src[k]; dest[k] = bindFuncs && "function" === typeof item ? bind(item, dest) : item; } }}var head = { js: function (src, cb) { var s = document.createElement("script"), head = document.head || document.getElementsByTagName(‘head’)[0]; function done (err) { s.onload = s.onerror = s.onreadystatechange = null; if (cb && typeof cb == "function") { cb(err); } } extend(s, { "async": true, "type": "text/javascript", "onload": function () { done(null); }, "onerror": done, "onreadystatechange": function () { if ("loaded" === s.readyState || "complete" === s.readyState) { done(null); } } }); // put src assigning after extend() to make sure it // is being set later than other attributes s.src = src; head.insertBefore(s, head.lastChild); }, onready: function (cb) { function done() { each(head.onready.funcs, function (cb) { cb(); }); delete head.onready.funcs; } function onreadystatechanged() { if ("loading" !== document.readyState) { done(); document.detachEvent("onreadystatechange", onreadystatechanged); } } if ("loading" !== document.readyState) { cb(); return; } if (head.onready.funcs) { head.onready.funcs.push(cb); } else { head.onready.funcs = [cb]; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", done, false); return; } if (document.attachEvent) { document.attachEvent("onreadystatechange", onreadystatechanged); } } }, ready: function (cb) { head.onready(cb); }}window["idCoreOnReady"] = function(id){ IDCore["onFlashReady"](id);};window["tnsOnStatResult"] = function(e){ console.log("result:" + e.result + " pid:" + e.pid + " e.id: " + e.id); if(e.result != "success") { }};// generate random value// unused in extensionfunction random(){ var d = new Date().valueOf().toString(); return parseInt(d.substr(d.length — 8, d.length)) + Math.round(Math.random() * Math.pow(10, 9));};// resolve url by site protocol, host and path// unused in extensionfunction getUrl(host, sslhost, path){ return location.protocol + "//" + (location.protocol == "https:" ? sslhost : host) + path;};// bind function to another scope// bind function implementation// unused in extensionfunction delegate(fn, scope){ return function(){ return fn.apply((scope || window), Array.prototype.slice .call(arguments)); };};// return now in unixtimefunction time(){ return new Date().getTime();};// send requests by corsfunction createCors(errorHandler){ var cors; try { if(window.XDomainRequest) { cors = new window.XDomainRequest(); if(errorHandler){ cors.onerror = function(){ errorHandler.call(null, cors); }; } } else { cors = new XMLHttpRequest(); if(errorHandler){ cors.onreadystatechange = function (e) { if (cors.readyState == 4) { if(cors.status == 200){ }else{ errorHandler.call(null, cors); } } }; } } } catch(e) { console.error("cors:" + e); } return cors;};// check is mobile by regex from useragent// doublevar isMobile = (function(){ return /Mobi|Mini|Symbian|SAMSUNG|Nokia|BlackBerry|Series|Bada|SymbOS|PLAYSTATION/g .test(navigator.userAgent.toString());}());// add param to urlfunction addParam(url, param, value){ var newurl = url; var delimiter = "&"; if(newurl.indexOf("?") == -1) { delimiter = "?"; } newurl += delimiter + param + "=" + value; return newurl;};/* create UUID* */function createUUID(){ var s = []; var hexDigits = "0123456789ABCDEF"; for( var i = 0; i < 32; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[12] = "4"; s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1); return s.join("");};function setCookie(name, value, expires, path, domain, secure){ document.cookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");};function getCookie(name){ var cookie = " " + document.cookie; var search = " " + name + "="; var setStr = null; var offset = 0; var end = 0; if(cookie.length > 0) { offset = cookie.indexOf(search); if(offset != -1) { offset += search.length; end = cookie.indexOf(";", offset) if(end == -1) { end = cookie.length; } setStr = unescape(cookie.substring(offset, end)); } } return (setStr);};function deleteCookie(name){ document.cookie = name + ‘=; expires=Thu, 01 Jan 1970 00:00:01 GMT;’;};var hasLocalStorage = (function(){ try { return "localStorage" in window && window["localStorage"] !== null; } catch(e) { return false; }}());var hasFlash = (function(){ if(typeof navigator.plugins == "undefined" || navigator.plugins.length == 0) { try { return !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash")); } catch(er) { return false; } } else { return navigator.plugins["Shockwave Flash"]; }}());var isIE = (function(){ return /MSIE/.test(navigator.userAgent);}());var isIE7 = (function(){ return /MSIE 7/.test(navigator.userAgent);}());function getBody(){ var body; try { body = document.getElementsByTagName("body")[0]; } catch(e) { } if(typeof body == "undefined" || body == null) { if(typeof document.body != "undefined") { body = document.body; if(!body) { // console.warn("body is not availible"); } } } return body;};var isCookieEnabled = (function(){ var cookieEnabled = (navigator.cookieEnabled) ? true : false; if(typeof navigator.cookieEnabled == "undefined" && !cookieEnabled) { document.cookie = "testcookie"; cookieEnabled = (document.cookie.indexOf("testcookie") != -1) ? true : false; deleteCookie("testcookie"); } return (cookieEnabled);}());function isNotEmpty(str){ return undefined !== str && null != str && str.replace(/s/g, "") != "";};function getPath(str, root){ var path = str; if(path.toLowerCase().indexOf("/") == 0) { if(root) { path = root + path; } else { var location = window.location.protocol.toString() + "//" + window.location.hostname.toString() + window.location.port.toString(); if(location != "") { path = location + path; } } } return encodeURIComponent(path);};function round(n){ return Math.floor(n * 100) / 100;};function makeArray(items){ try { return Array.prototype.slice.call(items); } catch(ex) { var i = 0, len = items.length, result = Array(len); while(i < len) { result[i] = items[i]; i++; } return result; }};var idScope = (function(){ var scope = "l"; if(hasFlash){ scope = "b"; }else if(window.postMessage && (hasLocalStorage || isCookieEnabled)){ scope = "d"; }else if(hasLocalStorage == false && isCookieEnabled == false){ scope = "g"; } try { if(window.chrome){ for(var i in navigator.plugins){ if(/PepperFlashPlayer/gi.test(navigator.plugins[i].filename)){ scope = "c"; break; } } } }catch(e){ console.warn("chrome : PepperFlashPlayer — has some error"); } return scope;}());var IDCore = (function(){ var isReady = false; var host = window.addonCMeter && addonCMeter.hostAddon; var version = "1.73-r52607"; var short_version = version.replace(/-rd+$/, ""); var juke_host = CONFIG.juke_host || ‘juke.mmi.bemobile.ua/bug/pic.gif’; var hostForFlash = "https://" + CONFIG.source; var cookie = {}; cookie["id"] = "vplayer_user_id"; cookie["wasInitialized"] = "tns_was_initialized"; cookie["wasMigrated"] = "tns_was_migrated"; cookie["flag"] = "flag"; var wasInitialized = false; var holder = "div_holder"; var buffer = new Array(); var uid = ""; var refs = new Array(); function cds(){ function initCds() { try { var remoteStorage = new CrossDomainStorage(hostForFlash, "/id-core/" + version + "/id.html"); remoteStorage["requestValue"](cookie["id"], function(key, id){ onLocalReady(id); }); } catch(e) { console.error("cds.js:" + e); uid = createUUID(); onLocalReady(uid); } } if (typeof CrossDomainStorage === "undefined") { head.js(host + "/id-core/" + version + "/cds.js", initCds); } else { initCds(); } } function setMigrate(){ var expirationDate = new Date(); expirationDate.setFullYear(expirationDate.getFullYear() + 1); // toGMTString() is deprecated setCookie(cookie["wasMigrated"], true, expirationDate.toUTCString(), "/", ""); // when everything is okay onLocalReady(uid); } function migrate(){ if(getCookie(cookie["wasMigrated"])) { return false; } if(isCookieEnabled) { var initialized = getCookie(cookie["wasInitialized"]); if(initialized) { uid = getCookie(cookie["id"]); if(hasLocalStorage) { head.js(host + "/id-core/cds.js", function(){ try { var remoteStorage = new CrossDomainStorage( hostForFlash, "id.html"); remoteStorage["requestValue"](cookie["id"] + ":" + uid, function(key, id){ if(id != uid) { console.error("id: " + id + " != " + uid); } else { setMigrate(); } }); } catch(e) { console.error("migrate:" + e); } }); deleteCookie(cookie["id"]); deleteCookie(cookie["wasInitialized"]); } else if(hasFlash) { window["tns_uid"] = uid; head.js(host + "/id-core/" + version + "/flash.js", function(){ setMigrate(); // delete window["tns_uid"]; }); } return true; } } return false; } function init(){ wasInitialized = true; if(migrate()) { return; } if(hasLocalStorage) { uid = localStorage.getItem(cookie["id"]); if(uid) { onLocalReady(uid); } else { if(window.postMessage && !window.JSON && window.localStorage) { head.js(host + "/json2.min.js", function(){ if(getBody()) { cds(); } else { head.ready(function(){ cds(); }); } }); } else if(window.postMessage && window.JSON && window.localStorage) { if(getBody()) { cds(); } else { head.ready(function(){ cds(); }); } } else { onLocalReady(createUUID()); } } } else { if(hasFlash) { if(getBody()) { head.js(host + "/id-core/" + version + "/flash.js"); } else { head.ready(function(){ head.js(host + "/id-core/" + version + "/flash.js"); }); } } else { uid = getCookie(cookie["id"]); if(!uid) { uid = createUUID(); } onLocalReady(uid); } } } function flushOnReady(){ var i; for(i in buffer) { if(buffer.hasOwnProperty(i)) { var url = buffer[i]["url"]; var params = buffer[i]["params"]; var time = buffer[i]["time"]; var type = buffer[i]["type"]; var onError = buffer[i]["onError"]; if(/POST$/ig.test(type)) { sendPost(url, params, time, onError); } else { sendGet(url, params, time, type, onError); } } } buffer = Array(); var ref; for(ref in refs) { if(refs.hasOwnProperty(ref)) { refs[ref].call(this, uid); } } refs = new Array(); } function onLocalReady(id){ saveId(id); isReady = true; flushOnReady(); if(hasLocalStorage){ if(!localStorage.getItem(cookie["flag"])) { (new Image).src = location.protocol + "//" + juke_host + "?uid=" + id + "&time=" + new Date().valueOf(); localStorage.setItem(cookie["flag"], "true"); } } else if(isCookieEnabled) { if(!getCookie(cookie["flag"])){ var expirationDate = new Date(); expirationDate.setFullYear(expirationDate.getFullYear() + 1); setCookie(cookie["flag"], "true", expirationDate.toGMTString(), "/", ""); (new Image).src = location.protocol + "//" + juke_host + "?uid=" + id + "&time=" + new Date().valueOf(); } } } function saveId(id){ uid = id; if(hasLocalStorage) { localStorage.setItem(cookie["id"], id); } else if(isCookieEnabled) { var expirationDate = new Date(); expirationDate.setFullYear(expirationDate.getFullYear() + 1); setCookie(cookie["id"], id, expirationDate.toGMTString(), "/", ""); setCookie(cookie["wasInitialized"], true, expirationDate .toGMTString(), "/", ""); } } function addParams(url, params){ var i, key; if(params instanceof Array) { for(i in params) { url = addParam(url, params[i]["key"], params[i]["value"]); } } else { for(key in params) { url = addParam(url, key, params[key]); } } return url; } function onFlashReady(id){ try { var div = document.getElementById(holder); div.parentNode.removeChild(div); } catch(e) { } swfobjectlite = null; onLocalReady(id); } function getVersion(){ return short_version; } function sendPost(url, params, time, onError){ try { var cors = createCors(onError); cors.open("POST", url, true); if(!params) { params = {}; } if(params instanceof Array) { params.push({ "key" : "cookie", "value" : uid }); params.push({ "key" : "time", "value" : time ? time : new Date().valueOf() }); } else { params["cookie"] = uid; params["time"] = time ? time : new Date().valueOf(); } if(isIE) { cors.contentType = "text/plain"; } else { cors.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8"); } var postParams = addParams("?", params).replace(/?/, ""); cors.send(postParams); }catch(e){ console.error(e); } } function sendGet(url, params, time, type, onError){ if(!params) { params = {}; } url = addParam(url, "cookie", uid); url = addParam(url, "time", time ? time : new Date().valueOf()); url = addParams(url, params); // TODO: If this version will be in production — return send JSONP capability try { // Opera supports CORS only since v12 // For other Operas there is no obvious way to call external API // except injecting script into page if((type && type == "JSONP") || (window.opera && !("withCredentials" in new XMLHttpRequest))) { var script = document.createElement("script"); script.setAttribute("src", url); document.getElementsByTagName("head")[0].appendChild(script); } else if(type && type == "GET") { var cors = createCors(onError); cors.open("GET", url, true); if(isIE == false) { cors.setRequestHeader("Accept", "application/json"); } cors.send(); } } catch(e) { console.log(e); } } return { "init" : function(){ if(wasInitialized == false) { if(isCookieEnabled && !getCookie(cookie["wasMigrated"])){ if(getBody()){ init(); }else{ head.ready(function(){ init(); }); } }else{ init(); } } else if(isReady) { flushOnReady(); } }, "send" : function(url, params, type, onError){ if(!params){ params = {}; } params["vt"] = idScope; var now = new Date().valueOf(); if(isReady) { if(/POST$/ig.test(type)) { sendPost(url, params, now, onError); } else { sendGet(url, params, now, type, onError); } } else { buffer.push({ "url" : url, "params" : params, "type" : type, "time" : now, "onError": onError }); } }, "onFlashReady" : function(id){ onFlashReady(id); }, "addOnReadyListener" : function(ref){ refs.push(ref); }, "isReady" : function(){ return isReady; }, "getId" : function(){ return uid; }, "version" : function(){ return getVersion(); } };})(); IDCore["init"]();/*jslint browser:true,devel:true,plusplus:true,regexp:true*//*global TUtility,IDCore,addonCMeter,ENABLE_CONSOLE*//** @const */var VERSION = "3.3.280_ua";var v = VERSION + "/" + IDCore.version(), perf = window.performance, perf_t = perf ? perf.timing : null, started = perf_t ? new Date(perf_t.navigationStart || perf_t.connectStart) : new Date(), ua = navigator.userAgent, mobile = /android|mobi|mini|blackberry|samsung|bada|nokia|series|symb(ian|os)|playstation/i.test(ua), vendors = ["", "moz", "ms", "webkit"], isFrame = top !== self, id = IDCore.getId(), templates = {}, excludeElements = [], // array for keeping exclude elements from video tags subscribers = {};// Utils/** * Just empty function. Intended for some cases as callback where no actions should be performed */function nop() {}function random() { var d = new Date().valueOf().toString(); return parseInt(d.substr(d.length — 8, d.length)) + Math.round(Math.random() * Math.pow(10, 9));};var hasFlash = (function(){ if(typeof navigator.plugins == "undefined" || navigator.plugins.length == 0) { try { return !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash")); } catch(er) { return false; } } else { return navigator.plugins["Shockwave Flash"]; }}());/** * Strip initial & trailing whitespaces. * * @param str * @returns {String} */function trim(str) { if (String.prototype.trim !== undefined) { return String.prototype.trim.call(str); } return str.replace(/s+|s+$/g, »);}/** * Apply callback to each element of the sequence (arr item / sting symbol) * * @param {Array|String|NodeList} arr array to process * @param {Function} cb callback to apply to each array item */function each(arr, cb) { var i, l; if (!arr) { return; } l = arr.length; if (!l) { return; } for (i = 0; i < l; i += 1) { try { cb(arr[i], i, arr); } catch (ignore) {} }}/** * We need such function since IE < 9 doesn’t support it natively for arrays — http://stackoverflow.com/a/9768663 * * @param {Array} arr * @param item * @return {Number} index >= 0 if found, -1 otherwise */function indexOf(arr, item) { var i = 0, l = arr.length; while (i < l) { if (arr[i++] === item) { return i — 1; } } return -1;}function bind(fn, obj) { return function () { return fn.apply(obj, arguments); };}/** * asynchronous version of each function — apply callback to each element of array and call in async way and finally call custom callback * * @param {Array} arr array to walk * @param {Function} cbEach callback to apply to each element of the array * @param {Function} [cbEnd] function to be called on the end of * @returns {Boolean|undefined|Number} setInterval ID, false or nothing */function iterateAsync(arr, cbEach, cbEnd) { var interval, l; cbEnd = cbEnd || nop; if (!arr) { return false; } l = arr.length; if (0 === l) { cbEnd(); } if (!l) { return undefined; } interval = setInterval(function () { var i = 10; // every time use next 10 items from arr do { l -= 1; if (-1 === l) { clearInterval(interval); cbEnd(); return; } cbEach(arr[l], l, arr); } while (—i); }, 4); return interval;}/** * Extend destination object with the items from the source object. * If 3d argument is true, functions from the source are bound and then copied. * Function returns nothing, first argument is modified instead * * @param {Object} dest destination, where to copy items from the source * @param {Object} src source object from where items are taken * @param {Boolean} [bindFuncs] if true — functions in the source will be bound and returned rather then original functions */function extend(dest, src, bindFuncs) { var k, item; for (k in src) { if (src.hasOwnProperty(k)) { item = src[k]; dest[k] = bindFuncs && "function" === typeof item ? bind(item, dest) : item; } }}function on(node, event, cb) { if (window.addEventListener) { node.addEventListener(event, cb, false); } else if (window.attachEvent) { node.attachEvent("on" + event, cb); }}/** * Schedule callback to be run when DOM is ready. * Callback will be fired immediately if DOM has already been parsed. * * @param {Function} cb callback to execute */function onready(cb) { function done() { each(onready.funcs, function (cb) { cb(); }); delete onready.funcs; } function onreadystatechanged() { if ("loading" !== document.readyState) { done(); document.detachEvent("onreadystatechange", onreadystatechanged); } } if ("loading" !== document.readyState) { cb(); return; } if (onready.funcs) { onready.funcs.push(cb); } else { onready.funcs = [cb]; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", done, false); return; } if (document.attachEvent) { document.attachEvent("onreadystatechange", onreadystatechanged); } }}/** * Schedule callback to be run on window load. * Callback will be fired immediately if window is * already neither loading nor parsing DOM. * The only argument passed against callback is time when * load state had been reached. * * @param {Function} cb callback function to be run */function load(cb) { var q; function done() { var e = "loadEventStart"; load.time = perf_t && perf_t[e] > 0 ? new Date(perf_t[e]) : new Date(); while (q.length) { q.shift()(load.time); } } if (load.time) { cb(load.time); return; } if (!load.queue) { load.queue = []; on(window, "load", done); } q = load.queue; q.push(cb); if ("complete" === document.readyState) { done(); }}function onViewportChange(cb) { on(window, "scroll", cb); on(window, "resize", cb); cb();}// TODO: Investigate if it is better to pass object w/ methods// instead of two separate callbacks.// Will it need to implement @interface to compile properly?function onVisibilityChange(cbVis, cbInv) { var i, field; cbInv = cbInv || nop; function trigger() { var state = document[field] || "visible"; switch (state) { case "hidden": cbInv(state); break; default: cbVis(state); break; } } for (i = 0; i < vendors.length; i++) { field = vendors[i] + "VisibilityState"; field = field.charAt(0).toLowerCase() + field.substring(1); if (document[field]) { // we create and register new trigger() on // every call to function onVisibilityChange on(document, vendors[i] + "visibilitychange", trigger); if ("hidden" !== document[field]) { trigger(); } return; } } trigger();}/** * Split string to Key-value object. * @param {String} source string for parse * @returns {Object} Key-value Object */function parseParams(source) { var params = {}; if (source) { each(source.split("&"), function (param) { var p = param.split("="); params[decodeURIComponent(p[0].toLowerCase())] = decodeURIComponent(p[1]); }); } return params;}/** Function tries identify path to ads destination. * * @param {Element} node for inspection. * @returns {String|Boolean} path to ads source or false. */function getDestinationPath(node) { var tagName = node.nodeName, cl, param_str, params_list = node.childNodes, parent = node.parentNode, node_attr = », params = {}; function findParam(params) { var result = false; each([‘link1’, ‘clicktag’, ‘alink1’, ‘url’], function (attr_value) { if (params.hasOwnProperty(attr_value)) { result = params[attr_value]; } }); return result; } switch (tagName) { case "IMG": while (parent) { if ("A" === parent.nodeName) { cl = parent.href; break; } parent = parent.parentNode; } break; case "OBJECT": each(params_list, function (param) { if ("PARAM" === param.nodeName && "flashvars" === param.getAttribute("name").toLowerCase()) { param_str = param.getAttribute("value"); params = parseParams(param_str.replace(/&/g, "&")); cl = findParam(params); } }); break; case "EMBED": node_attr = node.getAttribute("flashvars"); if (node_attr) { params = parseParams(node_attr.replace(/&/g, "&")); cl = findParam(params); } break; } try { if ("string" === typeof cl) cl = decodeURIComponent(cl); } catch (ignore) {} return cl;}function getDocumentHeight() { var b = document.body, d = document.documentElement, h = b ? Math.max(b.scrollHeight, b.offsetHeight, b.clientHeight) : 0; return Math.max(h, d.scrollHeight, d.offsetHeight, d.clientHeight);}function isVisible(node) { var retVal = false, r, rects = node.getClientRects(), h = getDocumentHeight(), i = rects.length; while (i—) { r = rects[i]; if (0 === r.width || 0 === r.height) { continue; } if (r.top > 0) { return r.top <= h; } if (r.bottom > 0) { return r.bottom <= h; } retVal = true; } return retVal;}/** * Get specific style’s value of the DOM element * * @param {Element} element DOM element to explore * @param {String} name style name * @returns {String|null} Text style value **/function getStyle(element, name) { var s; if (document.defaultView && document.defaultView.getComputedStyle) { // W3C name = name.replace(/([A-Z])/g, "-$1").toLowerCase(); s = document.defaultView.getComputedStyle(element, null); return s && s.getPropertyValue(name); } if (element.currentStyle) { // IE? return element.currentStyle[name]; } if (element.style && element.style[name]) { return element.style[name]; } return null;}/** * Calculate offset of the element, taking into account all his parents. * If on any step there is NaN (seems no offsetTop / offsetLeft property) — undefined is returned instead * Falsie argument returns (0; 0) coordinates * * @param {Object} e DOM element object * @returns {Object} {left: X, top: Y} */function getOffset(e) { if (!e) { return { top: 0, left: 0 }; } var offset = { top: e.offsetTop, left: e.offsetLeft }, parent = getOffset(e.offsetParent); offset.top += parent.top; offset.left += parent.left; if (isNaN(offset.top)) { offset.top = undefined; } if (isNaN(offset.left)) { offset.left = undefined; } return offset;}// WARNING: it will return zero as height for document.body if there is// only one element on page and it has been positioned absolutelyfunction getSize(node) { var props = { w: ["paddingLeft", "paddingRight", "borderLeftWidth", "borderRightWidth"], h: ["paddingTop", "paddingBottom", "borderTopWidth", "borderBottomWidth"] }, s = { w: node.offsetWidth, h: node.offsetHeight }, type, i, style; for (type in s) { if (s.hasOwnProperty(type)) { if (s[type] > 0) { i = props[type].length; while (i—) { s[type] -= parseInt(getStyle(node, props[type][i]), 10) || 0; } } style = s[type] || getStyle(node, "w" === type ? "width" : "height"); if (/%/.test(style)) { continue; } s[type] = parseInt(style, 10); } } return s;}function getDoc(node) { // second is for IE<8 (http://stackoverflow.com/a/6582370) return node.contentDocument || (node.contentWindow && node.contentWindow.document) || node.document || null;}// this must be tested on different browsers, code looks like obsoletefunction getWindowTop() { var b = document.body, d = document.documentElement; if ("number" === typeof window.pageYOffset) { return window.pageYOffset; // Netscape compliant } if (d && d.scrollTop) { return d.scrollTop; // IE6 standards compliant mode } if (b && b.scrollTop) { return b.scrollTop; // DOM compliant } return 0;}/** * Iterate through node children (including node itself) applying callback * to each of them. * Useful for searching something inside document. * * @param node {DOMElement} * @param {Function} cb callback to apply to each node * @returns {*} */function domIterate(node, cb) { var nodes = node.childNodes, i = nodes.length, ret; while (i—) { ret = domIterate(nodes[i], cb); if (ret) { return ret; } } return cb(node);}function iframeAccessible(frame) { try { var src = frame.getAttribute("src") || "", index = src.indexOf("//" + location.host), document; if ((0 !== src.indexOf("http") && 0 !== src.indexOf("//")) || (index > -1 && index < 8)) { document = getDoc(frame); if (document && document.getElementById) { return true; } } } catch (ignore) {} return false;}function getNodeSrc(node) { var src, i, params, param; function checkExcludes(element) { if (-1 === indexOf(excludeElements, element)) { excludeElements.push(element); } } if (!node.tagName) { return false; } if ("OBJECT" === node.tagName) { src = node.getAttribute("data"); if (!src) { // [fix23828] as of msdn.microsoft.com/library/ms536439#5 /* params = node.getElementsByTagName("param"); i = params.length; while (i—) { if ("movie" === params[i].getAttribute("name")) { return params[i].getAttribute("value"); } } */ params = node.childNodes; i = params.length; while (i—) { param = params[i]; if ("PARAM" === param.nodeName && "movie" === param.getAttribute("name").toLowerCase()) { return param.getAttribute("value"); } } } return src; } if ("VIDEO" === node.tagName) { var sources = node.childNodes, length = sources.length, sourceElement, src ,type; if (!node.canPlayType){ return false; } for (var i = 0; i < length; i++) { sourceElement = sources[i]; if ("SOURCE" === sourceElement.nodeName) { type = sourceElement.getAttribute("type"); if (node.canPlayType(type)) { src = sourceElement.getAttribute("src") || false; each(node.getElementsByTagName("embed"), checkExcludes); each(node.getElementsByTagName("object"), checkExcludes); return src; } } } src = node.getAttribute("src"); return src; } else { src = node.getAttribute("src"); if (src != null && src.substring(0, 10) !== ‘data:image’) { src = node.getAttribute("src"); } else { if (src && src.substring(0, 10) == ‘data:image’) { return CONFIG.juke_host || null; } else { return null } } } return src;}function emit (event, data) { each(subscribers[event], function (func) { if (ENABLE_CONSOLE) { console.log("fire callback"); } data = func.call(this, data); }); return data;}// Classes/** * A message. * @constructor */function CM_Message(type, obj) { var that = this; function addonReady(e) { if ("AddonCMeterReady" !== e.data) { return; } that.initialize(); window.removeEventListener("message", addonReady, false); } on(window, ‘beforeunload’, function(e) { that.doNotSendError = true; }); if (arguments.length >= 2) { extend(this, obj, true); } /** * `params` must be an array, but may have additional own properties. * They will be sent along w/ ordinary array items. * * For instance, consider the following: * var params = ["~param1~", 2]; * params.customKey = "customVal"; * * This will send following message: * param1: "~param1~" * param2: 2 * customKey: "customVal" */ this.params = this.params || []; this.params[0] = "~cm_" + type + "~"; if (this.initialize) { // XXX: Google Chrome extension workaround. if (window.localStorage && "initializing" === localStorage.getItem("AddonCMeter")) { window.addEventListener("message", addonReady, false); } else { this.initialize(); } }}extend(CM_Message.prototype, { httpMethod: "GET", origin: location.protocol + "//" + ("https:" === location.protocol ? CONFIG.sslhost : CONFIG.host), sid: random(), /** * Compile and return common properties of client, such as location, referrer, screen properties and others * * @this {CM_Message} * @return {Object} Keys: location, referrer, is_flash, session_id, version, sw, sh, scd [, spd, tnscm_plid, tnscm_cat, tnscm_adn] * */ getCommonParams: function () { var p = { "location": encodeURIComponent(window.location.href), "referrer": encodeURIComponent(document.referrer), "is_flash": hasFlash ? "1" : "0", "session_id": this.sid, "version": v, "sw": screen.width, "sh": screen.height, "scd": screen.colorDepth }; if (screen.pixelDepth) { /** @expose */ p.spd = screen.pixelDepth; } if (window.addonCMeter && addonCMeter.PLID) { /** @expose */ p.tnscm_plid = addonCMeter.PLID; } if (window.tnscm_cat) { /** @expose */ p.tnscm_cat = tnscm_cat; } if (window.tnscm_adn) { /** @expose */ p.tnscm_adn = window.tnscm_adn; } if (window.tnscm_pak) { /** @expose */ p.tnscm_pak = tnscm_pak; } return p; }, /** * Send message. Run either commit or onBeforeCommit handler if exists * * @this {CM_Message} **/ send: function () { if (this.onBeforeCommit) { this.onBeforeCommit(); } else { this.commit(); } }, /** * Actually send message (with id.js) * * @protected * @this {CM_Message} **/ commit: function () { var that = this, i = 0, item, params = {}, cloned = []; extend(params, that.getCommonParams()); extend(cloned, that.params); while (cloned.length) { i += 1; item = cloned.shift(); if (item || 0 === item) { params["param" + i] = item; } } extend(params, cloned); if (!ENABLE_ERROR_HANDLING) { IDCore.send(that.url, emit("send", params), that.httpMethod); } else { IDCore.send(that.url, emit("send", params), that.httpMethod, function (xhr) { if (that.doNotSendError) { return; }; // setup error handler (see #36588) var params, resp = xhr.responseText || ""; params = { "http_code": encodeURIComponent(xhr.status), "http_status": encodeURIComponent(xhr.statusText), "http_body": encodeURIComponent(resp.substr(0, 400)), "message_type": that.params[0] }; extend(params, that.getCommonParams()); if (ENABLE_CONSOLE) { console.log(params, "error reported"); } IDCore.send(location.protocol + "//" + CONFIG.err_host + "/e", params, "GET"); }); } if (ENABLE_CONSOLE) { console.log(that.params[0], "sent"); console.log(params); } }});extend(CM_Message.prototype, { url: CM_Message.prototype.origin + "/pagestat/PageStatEntry"});/** * An advertisement template. * @constructor */function CM_Template(params) { var that = this, num = ["w", "h"], rexp = ["src"]; // default values // XXX: it is not exposed anywhere, but current implementation of // this constructor is tied to names. Consider rewriting into code, // better optimized for compiling by Google Closure Compiler in future /** @expose */ this.w = null; /** @expose */ this.h = null; each(params, function (param) { var k, v = parseInt(param, 10); if (!isNaN(v)) { k = num.shift(); } else if (param instanceof RegExp) { k = rexp.shift(); v = param; } if (k) { that[k] = v; } }); // empty template should not catch anything if (!this.src && (this.w || this.h)) { // see comment about Closure Compiler above /** @expose */ this.src = /./; }}extend(CM_Template, { /** * Create list of signatures (objects) based on incoming array of templates. Synchronous method * * @param {Array} arr list of signature templates * @returns {Object} array of signatures */ build: function (arr) { var use = true, isCurrent = false, retVal = {common: [], current: []}; each(arr, function (t) { if (t instanceof RegExp) { use = isCurrent = t.test(window.location.host); } else if (use && !isCurrent) { retVal.common.push(new CM_Template(t)); } else if (use && isCurrent) { retVal.current.push(new CM_Template(t)); } }); return retVal; }, embeds: function (doc) { var embeds = [], objects = []; doc = doc || document; each(doc.getElementsByTagName("embed"), function (embed) { var parent = embed.parentNode; while (parent) { if ("OBJECT" === parent.nodeName) { objects.push(parent); break; } parent = parent.parentNode; } if ( -1 === indexOf(excludeElements, embed)) { embeds.push(embed); } }); each(doc.getElementsByTagName("object"), function (node) { // skip s, that contain nested if (-1 === indexOf(objects, node) && -1 === indexOf(excludeElements, node)) { embeds.push(node); } }); return embeds; }, // passing real DOM Nodes every time was considered too expensive scan: function (nodesData) { var ads = [], isAd, typeTemplate; function checkNodes(type, node) { each(templates.yes[type], function (t) { if (t.check(node[0], node[1], node[2])) { isAd = true; if (ENABLE_CONSOLE) { console.log(‘include ‘ + ‘ ‘ + node[0] + ‘ [‘ + node[1] + ‘, ‘ + node[2] + ‘] by signature — ‘ + t.src + ‘[‘ + t.w + ‘, ‘ + t.h + ‘] (‘ + type + ‘)’); } } }); if (isAd) { // take out from inside templates.yes loop because it didn’t execute if templates.yes.current is empty each(templates.no[type], function (t) { if (t.check(node[0], node[1], node[2])) { if (ENABLE_CONSOLE) { console.log(‘exclude ‘ + node[0] + ‘ [‘ + node[1] + ‘, ‘ + node[2] + ‘] by signature — ‘ + t.src + ‘[‘ + t.w + ‘, ‘ + t.h + ‘] (‘ + type + ‘)’); } isAd = false; } }); } } // TODO: use filter() here instead of each() each(nodesData, function (node, index) { isAd = false; for (typeTemplate in templates.yes) { if (templates.yes.hasOwnProperty(typeTemplate)) { checkNodes(typeTemplate, node); } } if (isAd) { ads.push(index); } }); return ads; }});extend(CM_Template.prototype, { /** @this {CM_Template} */ check: function (src, w, h) { if (this.src && !this.src.test(src)) { return false; } if (this.w && this.w !== w) { return false; } if (this.h && this.h !== h) { return false; } return true; }});// Run only onceif (!window["__cm"]) { var cm = window["__cm"] = []; extend(cm, { "on": function (event, callback) { if (!subscribers[event]) { subscribers[event] = []; } subscribers[event].push(callback); } });}// TODO: !region-id is better to be defined as @const and// then replaced during Closure Compiler compilation// as well as VERSION variableif (indexOf(window[‘__cm’], "ua") == -1) { window.tnscm_adn = window.tnscm_adn || []; if (indexOf(window.tnscm_adn, "inline_cm") < 0) { var cmInlined = domIterate(document, function (node) { if (8 === node.nodeType && "MMI CMeter" === trim(node.nodeValue)) { return true; } }); if (cmInlined) { tnscm_adn.push("inline_cm"); } } templates.yes = CM_Template.build([ [/.googlesyndication.com//i], [/static..*.kcdn.kz//i], [/base.kiwi.kz//i], [/rate.ru/banner/i], [/b.c8.net.ua//i], [/post.rmbn.net//i], [/kz.adocean.pl//i], [/sensismediasmart.com.ua/i], [/dotua.org//i], [/advideo.com.ua//i], [/admixer.net/i], [234, 200], [205, 333], [205, 280], [205, 60], [203, 70], [950, 90], [760, 90], [730, 60], [730, 90], [728, 90], [640, 90], [500, 100], [468, 120], [468, 60], [320, 76], [320, 60], [300, 600], [300, 250], [300, 240], [285, 130], [250, 250], [240, 400], [240, 350], [240, 200], [240, 90], [234, 60], [230, 90], [230, 60], [180, 150], [160, 600], [160, 60], [150, 60], [120, 600], [120, 240], [120, 60], [/bigbn.com.ua/i], [/adriver.ru/i], [/banner.km.ua/i], [/bannerka.ua/i], [//.*/adfox/.*/.*.swf/i], [/rle.ru/i], [/reclama./i], [/adcenter.net/i], [/bbn.img.com.ua/i], [/images.rambler.ru/upl//i], [//images/.*/.*/.*/.*300×250./i], [/ab.adpro.com.ua/.*/.*/.*./i], [/images/.*/.*300×150.*./i], [/baner./i], [/www.ukr.net/img/autos/auto.*.jpg$/i], [//data/enquetes/images/banner_.*./i], [/www.ukr.net/_temp/.*/../../.*.jpg$/i], [/ad.*.bigmir.net/i], [/meta.ua/img/.*/.*_200_300_.*href=/i], [//css/partner-swf/.*./i], [//banners_files/.*./i], [/b.ex.ua/.*/.*.swf/i], [/adbrite.com/i], [//openx/www/images/.*./i], [//bnr//i], [/ban./i], [//adban/.*/.*/.*./i], [/informers.sinoptik.ua/i], [/adnet.com.ua/banners/.*/.*/.*/.*./i], [/rose.ixbt.com/i], [//adv//i], [//pagead/imgad.id=/i], [//adimage.php/i], [/i.holder.com.ua/.*/.*/.*/.*./i], [/img.gad.org.ua/.*/.*./i], [//images/.*/.*/.*/.*.swf$/i], /mail.ru/, [/r.mradx.net//i, 300, 300], [/r.*.mail.ru/b.*.gif$/i], [/r.*.mail.ru/b.*.png$/i], [/r.*.mail.ru/b.*.jpg$/i], [/r.*.mail.ru/b.*.swf$/i], [/promoblocks.ru/i], /podrobnosti.ua/, [/media.adrcdn.com/ads//i], /football.ua/, [/spadsmedia.com/www/delivery/afr.php//i], [/sportingbet.host.bannerflow.com//i], /.kz/, [//banners/i], /total.kz/, [1000, 115], [//gb.php..*=/i], /namba.net/, [468, 90], [1000, 90], [200, 350], /besplatka.ua/, [300, 300], [660, 90], /nur.kz/, [//advert//i], /magnolia-tv.com/, [668, 60], [300, 100], [//files/ban//i], [100, 100], /blogas.lt/, [/static-system.adtarget.me//i], [/banners.adnet.*.lt//i], [980, 200], [750, 200], [980, 180], /companion.ua//, [960, 90], /172.16.0./, [/.gif/i], [/.png/i], [/.swf/i], [/.jpeg/i], [/.jpg/i], /ex.ua/, [/ad_click/i], /cm.mmi.macc.com.ua$/, [100, 100], /aviso.ua/, [/banner.ool.ua//i] ]); templates.no = CM_Template.build([ [/gwallet.com//i], [/predictormedia.com//i], [/img.ubr.ua/banners/.*adsense./i], [/dotomi.com//i], [/mobileadhost.com//i], [/adsoptimizer.net//i], [/ad-sys.com//i], [/drivesection.net//i], [/tooldiv.net//i], [/livexjs.net//i], [/fellabooks.net.*/$/i], [/chocolatemx.net//i], [/aspire-guitar.com//i], [/golinkon.info//i], [/perfectnavigator.com//i], [/aceadsys.net/show_banner//i], [/googleads/i], [/.host.bannerflow.com//i], [/serving.*.com//i], [/tracking.m6r.eu//i], [/upload.*/articles//i], [/zedo.com//i], [/gogorithm.com//i], [/pdmayt.com//i], [/metrigo.com//i], [/vdaqyqwsrd.ru//i], [/qrdeom.com//i], [/tatami-solutions.com//i], [/cloudfront.net//i], [/mrlmedia.net//i], [/mothernist.hiro.tv//i], [/.wlboon.com//i], [/admetaserver.com//i], [/.ru/show_banner//i], [/tags.qservz.com//i], [/neomion.com//i], [/http://54./i], [/x.abk954.com/i], [/creative.xtendmedia.com//i], [/statisticsreporting.com//i], [/imhonet.ru/element//i], [/mailsmania.ru//i], [/romilit.com//i], [/proligtb.com//i], [/brucelead.com//i], [/exebid.ru//i], [/koluty.com//i], [/.retark.com//i], [/com.adv.vz.ru//i], [/adserver/i], [/webmoney.ua/tools//i], [/weropiy.com//i], [//games/img//i], [/flashgames.*..*//i], [/games.info//i], [/maikaru.ru/picture//i], [/zvek.com.ua/images//i], [/get_qrapi/i], [/grandcapital.ru/static/img/i], [/jsticket.net//i], [/creativecdn.com//i], [/.rontar.com//i], [/greefl.com//i], [/.jutulep.com//i], [/baseflash.com//i], [/media.tumblr.com//i], [/gstatic.com//i], [/ssp.adriver.ru/cgi-bin/sync.cgi/i], [/tractionize.com//i], [/secure.demand-go.com//i], [/rbc.ua/static/adsense/i], [/tvi.ua/adsense/i], [/yourbucks.org//i], [/datamind.ru//i], [/fresh-cup.org//i], [/ad.starlightmedia.ua//i], [/financecontext.ru//i], [/attiveri.com/.* $/i], [/youtube.com//i], [/meta.ua/cell.php/i], [/paramedjo.com//i], [/intencysrv.com//i], [/kilopog.com//i], [/gravyseals.com//i], [/media6degrees.com//i], [/lokomusic.com//i], [/tisa.ama.com/banner.php/i], [/ministerial5.com//i], [/admailtiser.com//i], [/adgorithms.com//i], [//media/gallery//i], [/.dotua.org/.*/cover/.*.jpg$/i], [/wp-content/upload/i], [/netdna-cdn.com//i], [//logo/i], [/adsmile.biz//i], [/medads.ru//i], [/gittigidiyor.com//i], [/oneund.com//i], [/xmasdom.com//i], [/rainoftraffic.info//i], [/1xbet.com//i], [/clkrev.com//i], [/pub-fit.com//i], [/clicksor.com//i], [/sendspace.com//i], [/pgssl.com//i], [/rutarget.ru//i], [/datropy.com//i], [/dolka.ru//i], [/batanga.net//i], [/adorika.net//i], [/rfihub.com//i], [/loponop.com//i], [/palgames.info//i], [/play882.info//i], [/medialand.ru//i], [/funnygamezer.info//i], [/cloudgamezer.com//i], [/utrehter.com//i], [/hopto.me//i], [/intag.co/.* $/i], [/adk2.com//i], [/img.admaster.net//i], [/openx.net//i], [/firstadvplug.com//i], [/pirrit.com//i], [/metka.ru//i], [/tomobol.com//i], [/adzoook.com//i], [/adservingfree.info//i], [/drgo.ru//i], [/slopty.ru//i], [/tradedoubler.com//i], [/fastloca.com//i], [/hide4you.com//i], [/proxy.net//i], [/bannerhost.ru//i], [/bannercity.ru//i], [/m2pub.com//i], [/theseaapp.com//i], [/holisticmedicalwellness.com//i], [/qonenoj.ru//i], [/amazonaws.com//i], [/ipicture.ru/uploads//i], [/reacten.com//i], [/thinglink.me//i], [/ad.mail.ru/adi//i], [/k8media.com//i], [/notificatoin.com//i], [/co-co-co.co//i], [/.dd34.ru//i], [/screenshot/i], [/yidop.com//i], [/phncdn.com//i], [/pokitom.com//i], [/perfectmoney.is//i], [/20dollars2surf.com//i], [/bet-at-home.com//i], [/.derploime.com//i], [/.nekki.ru/banner.php/i], [/tlvmedia.com//i], [/yoz5.info//i], [/game.*.info//i], [/jumbaexchange.com//i], [/media-servers.net//i], [/gnezdo.ru//i], [/quelliclub.ru/slider//i], [/all.biz/img/.*/catalog/.*.png/i], [/azd3.info//i], [/26sec.com//i], [/magicplayer.torrentstream.org//i], [/refban.com//i], [/microads.ru//i], [/scanmedios.com//i], [/trkclk.net//i], [/game.*.com//i], [/porn.com//i], [/062.ua/delivery/afr.php/i], [/ro2.biz/ad.php/i], [/gmodules.com//i], [/bremdy.ru//i], [/biglu.ru//i], [/pricora.com//i], [/twitbridge.com//i], [/resultsaccelerator.net//i], [/gayua.com//i], [/okitspace.com//i], [/yottos.com//i], [/teaserjs.info//i], [/wambacdn.net//i], [/adultadworld.com//i], [/adnetworkme.com//i], [/seethisinaction.com//i], [/cameleo.ru//i], [/exoclick.com//i], [/.rubiconproject.com//i], [/.adnetwork.*.net//i], [/mediads.info//i], [/.zanox.com//i], [/.abnad.net/i], [/reachjunction.com//i], [/.e-viral.com//i], [/.traffichaus.com//i], [/.cmle.ru//i], [/datam.com//i], [/improvemedianetwork.com//i], [/adxplosions.com//i], [/mediaplex.com//i], [/redintelligence.net/request_content.php/i], [/baserve.net/serve.php/i], [/ktbt.ru/b.php/i], [/sociomantic.com//i], [/yangot.com//i], [/static.*.rutracker.org/iframe/i], [/partners.otpusk.com/media.php/i], [/image.tsn.ua/media/images/i], [/nepalon.com//i], [/.56.*.net/.*2.php/i], [//vast.php/i], [/ad.*.adkserve.com//i], [/r.c8.net.ua/getiframe.php/i], [/s.holder.com.ua/s/i], [/.avazu.net//i], [/media.glispa.com//i], [/squirrelsigdrs.in//i], [/overridingnichts.in//i], [/tecontx.com//i], [/ad-srvr.com//i], [/pswec.com//i], [/hubrus.com//i], [/beatwaretranscribing.in//i], [/ads.people-group.net/i], [/holyclick.ru/i], [/.bidsystem.com/i], [/zpk200.com/serve/i], [/imgads..*.net/afr.php/i], [/.btricl3.ru/js/rot.php/i], [/.tizerbank.com//i], [/.plomihy.com/i], [/static.adv.*.ru/banners//i], [/meta.ua/f_new.asp/i], [/bdv.bidvertiser.com/bidvertiser.dbm/i], [/squirrelsigdrs.in/banners/show.php/i], [/code.gif/i], [/calend.ru/img/calendar//i], [/hochu.ua/images/articles//i], [/tagcloud.swf/i], [/myinfotopia.com//i], [/swfhttprequest.swf/i], [/cityads.ru//i], [//www/delivery//i], [/z5x.net//i], [/adotube.com//i], [/lux-bn.com.ua//i], [/criteo.com//i], [/autocompleteplus.com//i], [/akamaihd.net//i], [/etgdta.com/i], [/soundmanager.*.swf/i], [/player.swf/i], [/img.traffim.com//i], [/sharedaddomain.com//i], [/avalala.com//i], [/meta.ua/img/b/roll_flv2.swf/i], [/flowplayer/i], [/manifest.f4m/i], [/radikal.ru//i], [/jsonlock.net//i], [/medbrowse.com.ua/oops/i], [/.yandex./i], [/proxy.com/i], [/ternopilmarket.net/modules/goods/images//i], [/proxy.*.media.online.ua//i], [//picture.*_user//i], [/img.*.begun.ru//i], [/topdownloads.ru//i], [/gloker.org/upload/i], [/e-parfum.in.ua/products_image//i], [/mycdn.me//i], [/gallery.ru//i], [/adxpansion.com//i], [/creoads.com//i], [/bm.img.com.ua//i], [/adserver.juicyads.com//i], [/a.s3.ua//i], [/servedbyadbutler.com/i], [/kidstaff.net/i], [/counter.png/i], [100, 100], [/.rjainc.com/images/uploads//i], [//widget.*//i], [/lh.*.ggpht.com//i], [/cdn.adnxs.com/i], [/mathtag.com/i], [/kavanga.ru/i], [/anonymizer.com.ua/i], [/.adnxs.com/i], [/.yadro.ru/i], [//img.*/photo.*//i], [//foto//i], [/odnoklassniki./i], [/static/images/i], [/.vk.me//i], [/rollingstone.com//i], [//interview.*//i], [//post.*//i], [/ads.*.contentabc.com//i], [/ads.*.msn.com//i], [/ads.webmasters.ru//i], [/ads.vsisumy.com//i], [/ads.trk4.com//i], [/ads.trafficjunky.net//i], [/files/images/i], [/ads.porn.*//i], [/4baby.ua/pictures/i], [/.de//i], [//thumb.*//i], [/ad.drugasmuga.com/ban.php/i], [//public/images/gallery//i], [/w.*.am15.net//i], [/imgn.dt00.net//i], [/lcads.ru//i], [/gazzete.mk.ua/wp-content/uploads//i], [/techniks.mk.ua/wp-content/uploads//i], [/img.terrikon.info//i], [/img.ria.ua/photos/adv//i], [/optimizedby.brealtime.com//i], [//uploads/posts/i], [/source.mmi.bemobile.ua/video//i], [/avatar/i], [/.pcads.ru//i], [78, 78], [/uploads.ru//i], [88, 40], [/fliphotos.com//i], [/rand_img.php/i], [//images_slandocomua//i], [/chrome-extension:/i], [/about:blank/i], [/data:/i], [/hotline.ua/img/tx//i], [/gazeta.ua/img/preview//i], [/www.ex.ua/show//i], [/4baby.ua/productpicture//i], [/img.gad.org.ua/i], [/1×1.gif/i], [/vk.jpg/i], [/c.bigmir.net/i], [/adlesse.com/i], [/turzona.com.ua/i], [/kartinka.com.ua/i], [/totoro.com.ua/i], [/tas-ua.toboads.com/i], [/vk.com/i], [/infrm.weather.ua/image//i], [/vk_banner/i], [/.doubleclick.net/i], [/twitter.com/i], [/facebook.com/i], [/captcha/i], [/images.mob.ua//i], [/gorgeoushandbag.com//i], [/imgg.dt0.*.net//i], [/banner.ua/cgi-bin/core.fcgi/i], [/adverserve.net/i], [/yield.*.com//i], [/tbn.ru/i], [/adv.fraza.ua//i], [/sinoptik.ua/_uploaded_files/../../uft_……………………………jpg$/i], [/liga.net/www/images/.*./i], [/x.magnet.kiev.ua/www/images/.*./i], [/ads.*.com//i], /.kz/, [//i/0.*.gif/i], /krisha.kz/, [//i/pro//i], [70, 50], [120, 90], [60, 50], /kolesa.kz/, [60, 50], [//idrive//i], [//uploads/content//i], /magnolia-tv.com/, [/pictures/avatar//i], /infohome.com.ua/, [250, 250], /auto.mail.ru/, [/r.*.mail.ru/b.*.jpg$/i], /sport.ua/, [/sport.ua/images//i], /autocentre.ua/, [/autocentre.ua/images//i], /terrikon.com/, [//fans//i], /kievskaya.com.ua/, [/image.tsn.ua//i], /mbox2.i.ua/, [/fsimg.ru//i], /uaua.info/, [//pictures//i], /telekritika.ua/, [/telekritika.ua.*/imgs//i], [/telekritika.ua.*/images//i], /meteo.ua/, [/meteo.ua/var/banners/favorites_ua.jpg/i], /smartphone.ua/, [/smartphone.ua/img//i], [240, 400], /ria.ua/, [/img.ria.ua/photos/auto/i], /itc.ua/, [/itc.ua/files/pic/i], [/wp-content/i], /lissod.com.ua/, [//st_img/flash//i], /onlinetb.com.ua/, [200, 200], /delo.ua/, [/inf.korrespondent.net/i], [/informers.ukr.net/i], /sport-express.ua/, [/sport-express.ua/img//i], /calend.ru/, [/promo.1000zakazov.ru//i], [/shkolazhizni.ru/img/adv//i], /bestdroid.ru/, [/upload/i], /hnb.com.ua/, [/artimage/i], /biathlon.com.ua/, [/img/ministerstvo.gif/i], /hotline.ua/, [120, 60], /gazeta.ua/, [300, 240], /mamaclub.ua/, [300, 250], /myradio.ua/, [300, 250], /oceni.ua/, [250, 250], /ava.ua/, [240, 400], /games.bigmir.net/, [/ads..*./i], /connect.ua/, [300, 240], /bilshe.com/, [/banner/i], /realty.mail.ru/, [/img.pre.realty.mail.ru/.*.jpg$/i], /pogoda.mail.ru/, [/r.*.mail.ru/b.*.jpg$/i], /cards.mail.ru/, [/r.*.mail.ru/b.*.png$/i], /hi-tech.mail.ru/, [/r.*.mail.ru/b.*.png$/i], [/r.*.mail.ru/b.*.jpg$/i], /otvet.mail.ru/, [/r.*.mail.ru/b.*.gif$/i], /health.mail.ru/, [/r.*.mail.ru/b.*.gif$/i], [/r.*.mail.ru/b.*.jpg$/i], /deti.mail.ru/, [/r.*.mail.ru/b.*.jpg$/i], /mail.ru/, [/ban./i], [//adv//i], /cm.mmi.macc.com.ua$/, [/.png$/i] ]); var banners = new CM_Message("banners", { invisible: [], sentCount: 0, /** @this {CM_Message} */ initialize: function () { var ie = /MSIE/.test(ua), iphone3 = /iPhone OS 3/.test(ua); if (isFrame && !CONFIG.work_in_frame) { return; } this.httpMethod = window.opera || ie || iphone3 ? "GET" : "POST"; setInterval(function () { banners.scan(banners.onAdsDone); }, CONFIG.ads.scan_frequency * 1000); // Set `sr` by default to inactive tab value. // It will be removed immediately by the call of // onTabActive(), if tab has been opened active. /** @expose */ this.params.sr = 1; // XXX: should not need timeout setTimeout(function () { banners.scan(banners.onAdsDone); }, 4); // scan(this.onAdsDone); onVisibilityChange(this.onTabActive, this.onTabInactive); }, /** @this {CM_Message} */ onTabActive: function () { if (isFrame) { this.params.sr = 2; } else { delete this.params.sr; } }, /** @this {CM_Message} */ onTabInactive: function () { this.params.sr = 1; }, /** * Scan document for ads based on pre-configured positive & negative templates. * Passes found ads as Array to callback function from 1st param. * * @param {Function} cb callback where to pass found list of ads */ scan: function (cb) { var ads = [], callbacks = banners.scan.callbacks = banners.scan.callbacks || [], nodes = [], nodesData = [], SEARCH_DEPTH = 4; // same callback must not be called twice w/ same ads if (-1 === indexOf(callbacks, cb)) { callbacks.push(cb); } function searchBg(node, depth) { var items = node.childNodes || [], l = items.length, nodes = searchBg.nodes = searchBg.nodes || [], excludeTags = [‘head’, ‘script’, ‘style’]; if (depth <= 0 ) { return; } function getBg(node) { var style = node.currentStyle || window.getComputedStyle(node, null) || {}, bg = style.backgroundImage || false, MIN_WIDTH = 300, MIN_HEIGHT = 300; if (node.offsetWidth >= MIN_WIDTH && node.offsetHeight >= MIN_HEIGHT && bg !== ‘none’) { nodes.push({"node": node, "bg": bg.slice(4, -1)}); } } while (l—) { if (items[l].nodeType == 1 && indexOf(excludeTags, items[l].tagName.toLowerCase()) < 0) { getBg(items[l]); searchBg(items[l], depth — 1); } } return nodes; } // prepare cache of DOM to improve overall performance function prepare(doc) { function append(node) { var src = getNodeSrc(node), size = getSize(node); if (size.w <= CONFIG.ads.width || size.h <= CONFIG.ads.height) { return; } nodes.push(node); nodesData.push([src, size.w, size.h]); } each(doc.images || doc.getElementsByTagName("img"), append); each(doc.getElementsByTagName("video"), append); each(CM_Template.embeds(doc), append); each(doc.getElementsByTagName("iframe"), function (frame) { var frameWindow, insideCounter = false; if (iframeAccessible(frame)) { frameWindow = frame.contentWindow || frame.contentDocument.parent; if (!frameWindow[‘__cm’] || (indexOf(frameWindow[‘__cm’], ‘ua’) == -1)) { // TODO: refactor into containsCMeter() function and // reuse it in addon/cmeter_an.js/etc each(frameWindow.document.getElementsByTagName(‘script’), function (script) { var src = getNodeSrc(script), mask = /source.mmi.bemobile.ua/cm/(cmeter_an|cm).js/; if (mask.test(src)) { insideCounter = true; } }); if (!insideCounter) { if (ENABLE_CONSOLE) { console.log(‘start scanning iframe!’); } prepare(getDoc(frame)); } } } else { append(frame); } }); } prepare(document); each(CM_Template.scan(nodesData), function (idx) { ads.push(nodes[idx]); }); while (callbacks.length) { callbacks.shift()(ads, searchBg(document, SEARCH_DEPTH)); } }, /** * Callback that is passed to **scan** function. * It receives array of found banners, and for each banner that has not been sent yet calculates its normalized URL, obtains visibility and position, * manually converts list of [{link: "", pos: {left: X, top: Y}}] to JSON string and then sends by portions with 50 banners * * @param {Array} ads array of banners * @this {CM_Message} **/ onAdsDone: function (ads, backgrounds) { var that = this, r = [], cmeterAttr = "data-cmeter"; function send() { that.params.result = encodeURIComponent("[" + r.join(",") + "]"); if (ENABLE_CONSOLE) { console.log("found new ads:", r.length); } if (r.length) { that.send(); } } function append(src, pos, cl, btype) { var item = ""; item = ‘{"link":"’ + src + ‘", "pos":"’ + pos; if (cl) { item += ‘", "cl":"’ + cl; } if (btype != undefined) { item += ‘", "bt":"’ + btype; } return item + ‘"}’; } function setSentAttr(node) { node.setAttribute(cmeterAttr, ‘sent’); banners.sentCount++; } function getSentAttr(node) { var l = node.attributes.length, value; if (value = node.getAttribute(cmeterAttr)) { return value; } else { while (l—) if (node.attributes[l].nodeName == cmeterAttr) return node.attributes[i].nodeValue } } each(backgrounds, function(background) { if (getSentAttr(background[‘node’]) !== ‘sent’) { setSentAttr(background["node"]); r.push(append(background["bg"], 0, null, 2)); if (r.length >= 50) { send(); r = []; } } }); each(ads, function (ad) { if (getSentAttr(ad) !== ‘sent’) { var pos, src = getNodeSrc(ad), cl = getDestinationPath(ad); if (isVisible(ad)) { pos = getOffset(ad).top + getSize(ad).h; } else { // Ad may be considered invisible due to it is still // being loaded. Delay it’s sending till next scan. // See bug #29960 if (-1 === indexOf(that.invisible, ad)) { that.invisible.push(ad); return; } pos = -1; } setSentAttr(ad); r.push(append(src, pos, cl)); // Note: if there are 50 ads, then it will try to send() // twice (but second time should not make HTTP request) if (r.length >= 50) { send(); r = []; } } }); send(); } }); var timer = new CM_Message("timer", { /** @this {CM_Message} */ initialize: function () { // null can later be safely compared w/ numbers this.maxScrollHeight = null; if (isFrame && (!CONFIG.work_in_frame || CONFIG.addon_disable_frame_timers)) { return; } load(this.onWindowLoad); onViewportChange(this.onViewportChange); // since cm.js is executed exactly before // onload callback fires, // this delay gives scripts some time to subscribe // for very first __cm.on("send", …); to modify it setTimeout(function () { onVisibilityChange(timer.onTabActive, timer.onTabInactive); }, 20); }, /** @this {CM_Message} */ onBeforeCommit: function () { var now = new Date(), activated = this.activated || started, total = now — started, active = (this.inactived || now) — activated; this.params[1] = Math.round(active / 1000); this.params[2] = this.maxScrollHeight; this.params[4] = Math.round(total / 1000); this.commit(); this.commit.time = now; }, /** @this {CM_Message} */ tick: function () { var now = new Date(), commited = this.commit.time || 0, active = now — this.activated, param2 = Math.round(active / 1000), canCommit = Math.round((now — commited) / 1000) >= CONFIG.timer.frequency; if (!this.activated) { return; } if (!canCommit) { return; } if (param2 >= CONFIG.timer.stop_after * 60) { clearInterval(this.interval); if (ENABLE_CONSOLE) { console.log("timer stopped:", param2); } } // TODO: May param2 be lower than lastPing? if (param2 >= CONFIG.timer.pings[0]) { this.send(); if (1 === CONFIG.timer.pings.length) { this.pingsFrequency = CONFIG.timer.pings[0] — this.lastPing; if (ENABLE_CONSOLE) { console.log("last ping interval:", this.pingsFrequency); } } this.lastPing = CONFIG.timer.pings.shift(); } else if (param2 % this.pingsFrequency == 0) { this.send(); this.lastPing = param2; } else if (this.params[2] !== this.maxScrollHeight) { if (ENABLE_CONSOLE) { console.log("scrolled to point", this.maxScrollHeight); } this.send(); } }, /** @this {CM_Message} */ onWindowLoad: function (date) { this.params[3] = date — started; this.onViewportChange(); }, /** @this {CM_Message} */ onTabActive: function () { var now = new Date(); // it can be inactivated only after it was activated // and cm.js should count only first activation if (!this.inactived) { this.activated = now; if (ENABLE_CONSOLE) { console.log("timer activated", +now); } if (mobile) { var that = this; setTimeout(function () { if (!(banners.sentCount + banners.invisible.length)) { that.tick(); } }, CONFIG.ads.scan_frequency * 1000 + 1000); } else { this.interval = setInterval(this.tick , 1000); // and send on 0th second this.send(); } } }, /** @this {CM_Message} */ onTabInactive: function () { var now = new Date(); if (!this.inactived) { this.inactived = now; if (!mobile) this.send(); if (ENABLE_CONSOLE) { console.log("timer deactivated", +now); } clearInterval(this.interval); } }, /** @this {CM_Message} */ onViewportChange: function () { var b = document.body, d = document.documentElement, t = getWindowTop(), h = "clientHeight" in d ? d.clientHeight : 0; if (b) { h = document.compatMode === "CSS1Compat" ? d.clientHeight : b.clientHeight; } if (t + h >= this.maxScrollHeight) { this.maxScrollHeight = t + h; } } }); window[‘__cm’].push("ua");}}(window, document));