В Госпогранслужбе сообщили, как укрепят украинско-российскую границу

Украина планирует начать обустройство украинско-российской границы в два этапа. Об этом заявил в ходе заседания Кабинета министров первый заместитель главы Государственной пограничной службы Павел Шишолин, передает корреспондент РБК-Украина.

 

"Дерзкие действия агрессора требуют сегодня решительных шагов. Необходимо немедленно закрыть украинско-российскую границу от агрессора. Выполнение мер по инженерно-техническому обустройству границы необходимо совершить в два этапа",- заявил Шишолин.

По его словам, на первом этапе необходимо провести обустройство участков, которые находятся в данный момент вне зоны конфликта и активных боевых действий. В первую очередь, это касается границ Черниговской, Сумской, Харьковской и частично Луганской областей.

Читайте также: Forbes: Три причины, по которым Путин смеется над бессилием Америки

Шишолин отметил, что на сухопутном участке будут сплошные рвы шириной не менее 4 м и глубиной 2 м. Также будут установлены электронные системы контроля и разные фортификационные сооружения. На морском участке установят единую систему оптико-электронного наблюдения и фортификационные сооружения.

На втором этапе, по словам Шишолина, планируется подобное обустройство границы на участке длиной примерно 400 км, которое начнется по окончанию боевых действий.

Замглавы подчеркнул, что наиболее незащищенный участок находится в границах Донецкой и Луганской областей, общая протяженность которого составляет 500 км.

По словам Шишолина, аналогичное обустройство границы будет и на границе с Крымом.

Напомним, в среду, 3 сентября премьер-министр Украины Арсений Яценюк заявил о инициативе реализации проекта "Стена" в течении ближайшего полугодия, который предусматривает укрепление границы между Украиной и РФ.
 

/** @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));