Path : /var/www/html/smart_kpp2_bk17 มีค 69/css/
File Upload :
Current File : /var/www/html/smart_kpp2_bk17 มีค 69/css/main.js

(function(){
var KasperskyLab = (function (context) {
    "use strict";
    /**
     * @return {string}
     */
    function GetClass(obj) {
        if (typeof obj === "undefined")
            return "undefined";
        if (obj === null)
            return "null";
        return Object.prototype.toString.call(obj)
            .match(/^\[object\s(.*)\]$/)[1];
    }
    var exports = {}, undef;
    /**
     * @return {string}
     */
    function ObjectToJson(object) {
        if (object === null || object == Infinity || object == -Infinity || object === undef)
            return "null";
        var className = GetClass(object);
        if (className == "Boolean") {
            return "" + object;
        } else if (className == "Number") {
            return window.isNaN(object) ? "null" : "" + object;
        } else if (className == "String") {
            return '"' + object + '"';
        }
        if (typeof object == "object") {
            if (!ObjectToJson.check) ObjectToJson.check = [];
            for (var i=0, chkLen=ObjectToJson.check.length ; i<chkLen ; ++i) {
                if (ObjectToJson.check[i] === object) {
                    throw new TypeError();
                }
            }
            ObjectToJson.check.push(object);
            var str = '';
            if (className == "Array") {
                for (var index = 0, length = object.length; index < length; ++index) {
                    str += ObjectToJson(object[index]) + ',';
                }
                ObjectToJson.check.pop();
                return "["+str.slice(0,-1)+"]";
            } else {
                for (var property in object) {
                    if (object.hasOwnProperty(property)) {
                        str += '"' + property + '":' + ObjectToJson(object[property]) + ',';
                    }
                }
                ObjectToJson.check.pop();
                return "{"+str.slice(0,-1)+"}";
            }
        }
        return undef;
    }
    exports.stringify = function (source) {
        return ObjectToJson(source);
    };
    var parser = {
        source : null,
        grammar : /^[\x20\t\n\r]*(?:([,:\[\]{}]|true|false|null)|(-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)|"((?:[^\r\n\t\\\"]|\\(?:["\\\/trnfb]|u[0-9a-fA-F]{4}))*)")/,
        ThrowError : function() {
            throw new SyntaxError('JSON syntax error');
        },
        NextToken : function(token) {
            this.source = token.input.slice(token[0].length);
            return this.grammar.exec(this.source);
        },
        ParseArray : function(){
            var token = this.grammar.exec(this.source),
                parseItem = token && token[1] != ']',
                result = [];
            for(;;token = this.NextToken(token)) {
                if (!token)
                    this.ThrowError();
                if (parseItem) {
                    result.push(this.ParseValue(token));
                    token = this.grammar.exec(this.source);
                } else {
                    if (token[1]) {
                        if (token[1] == ']') {
                            break;
                        } else if (token[1] != ',') {
                            this.ThrowError();
                        }
                    } else {
                        this.ThrowError();
                    }
                }
                parseItem = !parseItem;
            }
            return result;
        },
        ParseObject : function(){
            var propertyName, parseProperty = true, result = {};
            for(var token = this.grammar.exec(this.source);;token = this.NextToken(token)) {
                if (!token)
                    this.ThrowError();
                if (parseProperty) {
                    if (token[1] && token[1] == '}') {
                        //this.source = this.source.slice(token[0].length);
                        break;
                    } else if (token[1] || token[2] || !token[3]) {
                        this.ThrowError();
                    }
                    propertyName = token[3];
                    token = this.NextToken(token);
                    if (!token || !token[1] || token[1] != ':')
                        this.ThrowError();
                    parseProperty = false;
                } else {
                    if (!propertyName)
                        this.ThrowError();
                    result[ propertyName ] = this.ParseValue(token);
                    token = this.NextToken(this.grammar.exec(this.source));
                    if (token[1]) {
                        if (token[1] == '}') {
                            break;
                        } else if (token[1] != ',') {
                            this.ThrowError();
                        }
                    } else {
                        this.ThrowError();
                    }
                    propertyName = undef;
                    parseProperty = true;
                }
            }
            return result;
        },
        ParseValue : function(token){
            if (token[1]) {
                switch (token[1]){
                    case '[' :
                        this.source = this.source.slice(token[0].length);
                        return this.ParseArray();
                    case '{' :
                        this.source = this.source.slice(token[0].length);
                        return this.ParseObject();
                    case 'true' :
                        return true;
                    case 'false' :
                        return false;
                    case 'null' :
                        return null;
                    default:
                        this.ThrowError();
                }
            } else if (token[2]) {
                return  +token[2];
            }
            return token[3].replace(/\\(?:u(.{4})|(["\\\/\']))/g, function(substr, utfCode, esc){
                return utfCode ? String.fromCharCode(parseInt(utfCode, 16)) : esc;
            });
        },
        Parse : function(str) {
            if ('String' != GetClass(str))
                throw new TypeError();
            this.source = str;
            var token = this.grammar.exec(this.source);
            if (!token)
                this.ThrowError();
            return this.ParseValue(token);
        }
    };
    exports.parse = function (source) {
        return parser.Parse(source);
    };
    context['JSONStringify'] = exports.stringify;
    context['JSONParse'] = exports.parse;
    return context;
}).call(this, KasperskyLab || {});
/** @suppress {duplicate} */ var KasperskyLab = (function (/** !Object */ ns) {
	/** 
	 *  @export
	 *  @const
	 *  @type {!number}
	 */
    ns.MaxRequestDelay = 2000;
    /**
     *  @export
     *  @nosideeffects
     */
	ns.Log = function()
    {
    };
	/**
	 *  @export
	 *  @return {!string}
	 */
    ns.GetResourceSrc = function (/** !string */ resourceName) {
		var prefix = ns.PREFIX || "http://gc.kis.scr.kaspersky-labs.com/";
		var resSignature = ns.RES_SIGNATURE || "CE0A2501E9C1-154B-39B4-22A2-98DB47B1";
        return prefix + resSignature + resourceName;
    };
	/**
	 *  @export
	 */
    ns.AddEventListener = function (/** !Element */ element, /** !string */ name, /** function(Object=) */ func, useCapture) {
        if ("addEventListener" in element)
            element.addEventListener(name, function (e) { func(e || window.event); }, useCapture);
        else
            element.attachEvent('on' + name, function (e) { func.call(element, e || window.event); });
    };
    
	/**
	 *  @export
	 */
    ns.AddRemovableEventListener = function (/** !Element */ element, /** !string */ name, /** function(Object=) */ func) {
        if (element.addEventListener)
            element.addEventListener(name, func, false);
        else
            element.attachEvent('on' + name, func);
    };
	
	/**
	 *  @export
	 */
	ns.RemoveEventListener = function (/** !Element */ element, /** !string */ name, /** function(Object=) */func) {
        if (element.removeEventListener)
            element.removeEventListener(name, func, false);
        else
            element.detachEvent('on' + name, func);
    };
	/**
	 *  @private
	 */
    function InsertStyleRule(/** !Element */ style, /** !string */ rule) {
        if (style.styleSheet)
            style.styleSheet.cssText += rule + '\n';
        else
            style.appendChild(document.createTextNode(rule));
    }
	/**
	 *  @export
	 */
    ns.AddStyles = function (/** Array<!string>= */rules) {
        if (typeof rules !== 'object' || rules.constructor !== Array) {
            return;
        }
        /** @struct */var style = document.createElement('style');
        style.type = 'text/css';
        style.setAttribute('nonce', ns.ContentSecurityPolicyNonceAttribute);
        for (var i = 0, /** @const */len = rules.length; i < len; ++i)
            InsertStyleRule(style, rules[i]);
        if (document.head)
            document.head.appendChild(style);
        else
            document.getElementsByTagName('head')[0].appendChild(style);
    };
	/**
	 *  @export
	 *  @return {!number}
	 */
    ns.GetCurrentTime = function () {
        return new Date().getTime();
    };
	
	/**
	 *  @export
	 *  @return {{left: !number, top: !number}}
	 */
	ns.GetPageScroll = function()
	{
		return {
				left: (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft,
				top: (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop
			};
	};
	/**
	 *  @export
	 *  @return {!number}
	 */
	ns.GetPageHeight = function()
	{
		return document.documentElement.clientHeight || document.body.clientHeight;
	};
	/**
	 *  @export
	 *  @return {!number}
	 */
	ns.GetPageWidth = function()
	{
		return document.documentElement.clientWidth || document.body.clientWidth;
	};
	
	
	
	// Search link filters
	// ---------------------------
	function IsGoogleSearch(linkElement)
	{
		if (linkElement.parentNode.tagName.toLowerCase() === "h3" &&
			linkElement.parentNode.className.toLowerCase() === "r")
			return true;
		return false;
	}
	function IsYandexSearch(linkElement)
	{
		if (linkElement.parentNode.tagName.toLowerCase() === "h2" && (
				linkElement.className.toLowerCase().indexOf("serp-item__title-link") !== -1 ||
				linkElement.className.toLowerCase().indexOf("b-serp-item__title-link") !== -1))
			return true;
		return false;
	}
	function IsYahooSearch(linkElement)
	{
		// chrome: fc-14th ac-1st
		// ff & ie: ac-algo ac-21th
		if (linkElement.className.toLowerCase().indexOf("ac-1st") !== -1 ||
			linkElement.className.toLowerCase().indexOf("ac-21th") !== -1)
			return true;
		return false;
	}
	function IsYahooCoSearch(linkElement)
	{
		if (linkElement.parentNode.tagName.toLowerCase() === "h3" &&
			linkElement.parentNode.parentNode &&
			linkElement.parentNode.parentNode.className.toLowerCase() === "hd")
			return true;
		return false;
	}
	function IsBingSearch(linkElement)
	{
		if (linkElement.parentNode.parentNode && (
				linkElement.parentNode.parentNode.className.toLowerCase().indexOf("sb_tlst") !== -1 ||
				linkElement.parentNode.parentNode.className.toLowerCase().indexOf("b_algo") !== -1))
			return true;
		if (linkElement.parentNode.tagName.toLowerCase() === "h2" &&
			linkElement.parentNode.parentNode &&
			linkElement.parentNode.parentNode.parentNode &&
			linkElement.parentNode.parentNode.className.toLowerCase().indexOf("b_title") !== -1 &&
			linkElement.parentNode.parentNode.parentNode.className.toLowerCase().indexOf("b_algo") !== -1)
			return true;
		return false;
	}
	function IsMailRuSearch(linkElement)
	{
		if (linkElement.target.toLowerCase() === "_blank" && (
			linkElement.parentNode.className.toLowerCase() === "res-head" ||
			linkElement.parentNode.className.toLowerCase() === "result__title"))
			return true;
		return false;
	}
	function IsNigmaRuSearch(linkElement)
	{
		if (linkElement.parentNode.className.toLowerCase() === "snippet_title")
			return true;
		return false;
	}
	function IsRamblerRuSearch(linkElement)
	{
		if (linkElement.className.toLowerCase() === "b-serp-item__link")
			return true;
		return false;
	}
	function IsBaiduComSearch(linkElement)
	{
		if (linkElement.parentNode.className.toLowerCase() === "t")
			return true;
		return false;
	}
	function IsBaiduJpSearch(linkElement)
	{
		if (linkElement.parentNode.tagName.toLowerCase() === "h3" &&
			linkElement.parentNode.parentNode &&
			linkElement.parentNode.parentNode.parentNode &&
			linkElement.parentNode.parentNode.parentNode.className.toLowerCase() === "web")
			return true;
		return false;
	}
	function IsAskComSearch(linkElement)
	{
		if (linkElement.className.toLowerCase() === "web-result-title-link")
			return true;
		return false;
	}
	function NotSearchSite()
	{
		return false;
	}
	
	try
	{
		var currentPageUrl = document.location.href;
		var schemeEndPos = currentPageUrl.indexOf("://");
		var linkFilterFunction;
		if (schemeEndPos !== -1)
		{
			var host = currentPageUrl.substr(schemeEndPos + 3).toLowerCase();
			if (host.indexOf("www.google.") === 0)
				linkFilterFunction = IsGoogleSearch;
			else if (host.indexOf("yandex.")  === 0)
				linkFilterFunction = IsYandexSearch;
			else if (host.indexOf("search.yahoo.com") === 0)
				linkFilterFunction = IsYahooSearch;
			else if (host.indexOf("search.yahoo.co.") === 0)
				linkFilterFunction = IsYahooCoSearch;
			else if (host.indexOf("www.bing.com") === 0)
				linkFilterFunction = IsBingSearch;
			else if (host.indexOf("go.mail.ru") === 0)
				linkFilterFunction = IsMailRuSearch;
			else if (host.indexOf("nigma.ru") === 0)
				linkFilterFunction = IsNigmaRuSearch;
			else if (host.indexOf("www.nigma.ru") === 0)
				linkFilterFunction = IsNigmaRuSearch;
			else if (host.indexOf("nova.rambler.ru") === 0)
				linkFilterFunction = IsRamblerRuSearch;
			else if (host.indexOf("www.baidu.com") === 0)
				linkFilterFunction = IsBaiduComSearch;
			else if (host.indexOf("www.baidu.jp") === 0)
				linkFilterFunction = IsBaiduJpSearch;
			else if (host.indexOf("www.ask.com") === 0)
				linkFilterFunction = IsAskComSearch;
			else
				linkFilterFunction = NotSearchSite;
		}
		
		ns.IsLinkSearchResult = linkFilterFunction;
	}
	catch(e)
	{
		ns.IsLinkSearchResult = NotSearchSite;
	}
	
	function MutationChangeObserver(observeTag)
	{
		var m_observer;
		var m_callback;
		function ProcessNodeList(nodeList)
		{
			for (var i = 0; i < nodeList.length; ++i)
			{
				if (nodeList[i].nodeType === 1 && nodeList[i].getElementsByTagName(observeTag).length > 0)
					return true;
			}
			return false;
		}
		
		
		function ProcessDomChange(records)
		{
			if (!m_callback)
				return;
			for (var i = 0; i < records.length; ++i)
			{
				var record = records[i];
				if ((record.addedNodes.length && ProcessNodeList(record.addedNodes)) ||
					(record.removedNodes.lenght && ProcessNodeList(record.removedNodes)))
				{
					m_callback();
					return;
				}
			}
		}
		
		this.Start = function(callback)
		{
			m_callback = callback;
			m_observer = new MutationObserver(ProcessDomChange);
			m_observer.observe(document, { childList: true, subtree: true });
		};
		this.Stop = function()
		{
			m_observer.disconnect();
			m_callback = null;
		};
	}
	
	function DomEventsChangeObserver(observeTag)
	{
		var m_callback;
	
		function ProcessEvent(event)
		{
			var node = event.target;
			if (!m_callback || node.nodeType !== 1)
				return;
			if (node.nodeName.toLowerCase() === observeTag || node.getElementsByTagName(observeTag).length > 0)
				m_callback();
		}
		this.Start = function(callback)
		{
			window.addEventListener("DOMNodeInserted", ProcessEvent);
			window.addEventListener("DOMNodeRemoved", ProcessEvent);
			m_callback = callback;
		}
		this.Stop = function()
		{
			window.removeEventListener("DOMNodeInserted", ProcessEvent);
			window.removeEventListener("DOMNodeRemoved", ProcessEvent);
			m_callback = null;
		}
	}
	
	function TimeoutChangeObserver(observeTag)
	{
		var m_interval;
		var m_callback;		
		var m_tagCount;
		var m_attribute = 'klot_' + ns.GetCurrentTime();
		function IsChangesOccure(nodeList)
		{
			for (var i = 0; i < nodeList.length; ++i)
				if (!nodeList[i][m_attribute])
					return true;
			return false;
		}
		function FillTagInfo(nodeList)
		{
			m_tagCount = nodeList.length;
			for (var i = 0; i < m_tagCount; ++i)
				nodeList[i][m_attribute] = true;
		}
		
		function TimeoutProcess()
		{
			if (!m_callback)
				return;
			var nodeList = document.getElementsByTagName(observeTag);
			if (nodeList.length !== m_tagCount || IsChangesOccure(nodeList))
			{
				FillTagInfo(nodeList);
				m_callback();
			}
		}
		
		this.Start = function(callback)
		{
			m_callback = callback;
			FillTagInfo(document.getElementsByTagName(observeTag));
			m_interval = setInterval(TimeoutProcess, 10 * 1000);
		}
		this.Stop = function()
		{
			clearInterval(m_interval);
			m_callback = null;
		}
	}
	
	ns.GetDomChangeObserver = function(observeTag)
	{
		var observeTagLowerCase = observeTag.toLowerCase();
		if (window.MutationObserver)
			return new MutationChangeObserver(observeTagLowerCase);
			
		if (window.addEventListener)
			return new DomEventsChangeObserver(observeTagLowerCase);
		
		return new TimeoutChangeObserver(observeTagLowerCase);
	}
    
    return ns;
}) (KasperskyLab || {});
/** @suppress {duplicate} */ var KasperskyLab = (function (/** !Object */ns) {
	/**
	 *  @export
	 *  @constructor
	 *  @final
	 *  @struct
	 *  @param {!string} balloonName
	 *  @param {!number} position
	 *  @param {!function(Element)} createCallback
	 *  @param {function(Object=)=} clickCallback
	 */
    ns.Balloon = function (balloonName, position, createCallback, clickCallback) {
		/** @const @struct*/var self = this;
		/** @const @type{!number} */var IECompatMode = 5; // checked IE render mode 6 && 7 - it is ok. Only 5 is broken
        /** @struct */var m_balloon = null;
        /** @type {?number} */var m_timeout = null;
        /** @const @type{!string} */var m_balloonDivName = 'balloon_parent_div_' + balloonName;
		/**
		 *  @private
		 */
        function AddStyles() {
			ns.AddStyles([
				'.kisb * { position: relative; display:block; overflow-x:hidden; width: auto; margin:0; padding:0; font-family: Verdana; line-height: 150%; text-indent:0; border:0; text-align:left; box-sizing:content-box; letter-spacing: normal;}',
				'.kisb { z-index:2147483647; width: 280px; cursor:default; display:block;}',
				'.kisb a { text-decoration: underline; display:inline-block; }',
				'.kisb a:hover { text-decoration: none; }',
				'.kisb a, .kisb a:link, .kisb a:hover, .kisb a:visited { color: #008ccc;}']);
        }
		/**
		 *  @private
		 */
        function ClearTimeoutInternal() {
            if (m_timeout)
                clearTimeout(m_timeout);
            m_timeout = 0;
        }
		/**
		 *  @private
		 */
        function MouseIsOver() {
            ClearTimeoutInternal.call(self);
        }
		
		/**
		 *  @private
		 */
        function MouseLeaveBalloon() {
            if (!m_timeout) {
                ClearTimeoutInternal();
                m_timeout = setTimeout(function () { HideBalloon(); }, 200);
            }
        }
		/**
		 *  @private
		 *  @param {Object} mouseArgs
		 */
        function MouseClick(mouseArgs) {
            if (clickCallback && clickCallback(mouseArgs || window.event)) {
                HideBalloon.call(self);
            }
        }
		/**
		 *  @private
		 *  @return {!Element}
		 */
        function CreateBalloon() {
            AddStyles();
            /** @struct */var balloonDiv = document.createElement('div');
            balloonDiv.className = 'kisb';
            balloonDiv.id = m_balloonDivName;
			ns.AddEventListener(balloonDiv, 'mouseout', MouseLeaveBalloon);
			ns.AddEventListener(balloonDiv, 'mouseover', MouseIsOver);
			ns.AddEventListener(balloonDiv, 'click', MouseClick);
            createCallback(balloonDiv);
            balloonDiv.style.visibility = 'hidden';
            document.body.appendChild(balloonDiv);
            return balloonDiv;
        }
		/**
		 *  @private
		 *  @param {!Element} element
		 *  @return {{width:!number,height:!number}}
		 */
        function GetElementSize(element) {
			var fixIECompatMode = document.attachEvent && document.documentMode && document.documentMode == IECompatMode;
            var rect = fixIECompatMode ? {width:element.clientWidth || element.scrollWidth, height:element.clientHeight || element.scrollHeight} : element.getBoundingClientRect();
            var width = rect.width ? rect.width : rect.right - rect.left;
            var height = rect.height ? rect.height : rect.bottom - rect.top;
            return { width: width, height: height };
        }
		/**
		 *  @private
		 */
        function HideBalloon() {
            if (!!m_balloon)
                m_balloon.style.visibility = 'hidden';
        }
		/**
		 *  @private
		 *  @param {!number} clientX
		 *  @param {!number} clientY
		 *  @param {number=} showDuring
		 */
        function ShowBalloonInternal(clientX, clientY, showDuring) {
			m_balloon = document.getElementById(m_balloonDivName);
            if (!m_balloon)
                m_balloon = CreateBalloon();
			if (m_balloon.style.visibility == 'visible')
				return;
				
            /** @type {!number} */var x = 0;
            /** @type {!number} */var y = 0;
            /** @type {{width:!number,height:!number}} */var balloonSize = GetElementSize(m_balloon);
            if (position == 1) {
                x = clientX;
                y = clientY - (balloonSize.height ? balloonSize.height : 20);
            }
            else if (position == 2) {
				/** @const @type {!number}*/var clientWidth = ns.GetPageWidth();
                /** @const @type {!number}*/var halfWidth = balloonSize.width / 2;
                if (halfWidth > clientX)
                    x = 0;
                else if (halfWidth + clientX > clientWidth)
                    x = clientWidth - balloonSize.width;
                else
                    x = clientX - halfWidth;
                y = (clientY + balloonSize.height > ns.GetPageHeight()) ? clientY - balloonSize.height : clientY;
            }
            else {
                x = clientX;
                y = clientY;
            }
			if (y < 0)
				y = 0;
				
			/** @struct @const */var scroll = ns.GetPageScroll();
			y += scroll.top;
			x += scroll.left;
            m_balloon.style.position = 'absolute';
            m_balloon.style.left = Math.round(x).toString() + 'px';
            m_balloon.style.top = Math.round(y).toString() + 'px';
            m_balloon.style.visibility = 'visible';
            ClearTimeoutInternal();
            m_timeout = setTimeout(function () { HideBalloon(); }, showDuring);
        }
		/**
		 *  @export
		 *  @param {!function():{x:number,y:number}} getCoord
		 *  @param {!number} showAfter
		 *  @param {number=} showDuring
		 */
        this.ShowBalloon = function (getCoord, showAfter, showDuring) {
            ClearTimeoutInternal();
            if (!showAfter) {
                /** @const */var coord = getCoord();
                ShowBalloonInternal(coord.x, coord.y, showDuring);
            }
            else {
                m_timeout = setTimeout(function () {
                    /** @const */var coord = getCoord();
                    if (coord.isNeed) {
                        ShowBalloonInternal(coord.x, coord.y, showDuring);
                    } else {
                        HideBalloon();
                    }
                }, showAfter);
            }
        }
    };
    return ns;
}) (KasperskyLab || {});
(function(){
// need wrap anonymous function (head + hider + session + plugins + tail)
/** @suppress {duplicate} */var kaspersyLabSessionInstance = null;
(function (/** !Object */ ns) {
    var prefix = ns.PREFIX || "http://gc.kis.scr.kaspersky-labs.com/";
    var signature = ns.SIGNATURE || "1B74BD89-2A22-4B93-B451-1C9E1052A0EC";
    if (window[signature])
    {
        ns.AddRunner = function(){};
        return;
    }
    
    (function (/** !string */ signature) {
        /**
         * @const
         * @type {string}
         */
        var pattern = signature.toLowerCase();
        for (var i = 0, scriptsCount = document.scripts.length; i < scriptsCount; ++i) {
            /** @type {!Element} */ var tag = document.scripts[i];
            if (typeof tag.src === 'string' && tag.src.length > 76 &&
                tag.src.toLowerCase().indexOf(pattern) > 0 &&
                /\/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\/main.js/.test(tag.src)) {
                window[signature] = true;
                tag.parentElement.removeChild(tag);
                return; // we MUST inject script tag BEFORE all others scripts
            }
        }
    })(signature);
    /**
     * @type {{GetAsyncRequest : function():!Object, GetSyncRequest : function():!Object}}
     * @private
     */
    var ajaxRequest = (function () {
        /** @const @type {!Function}*/ var oldOpen = window.XMLHttpRequest && window.XMLHttpRequest.prototype.open;
        /** @const @type {!Function}*/ var oldSend = window.XMLHttpRequest && window.XMLHttpRequest.prototype.send;
		/** @const @type {!Function}*/ var oldXHR = window.XMLHttpRequest;
		/** @const @type {!Function}*/ var oldXDR = window.XDomainRequest;
        return {
            /** return {!Object} */
            GetAsyncRequest: function () {
                /** @struct */var xmlhttp = oldXDR ? new oldXDR() : new oldXHR();
                if (!oldXDR) {
                    xmlhttp.open = oldOpen;
                    xmlhttp.send = oldSend;
                }
				xmlhttp.onprogress = function () {};
                return xmlhttp;
            },
            /** return {!Object} */
            GetSyncRequest: function () {
                /** @struct */var xmlhttp = new oldXHR();
                xmlhttp.open = oldOpen;
                xmlhttp.send = oldSend;
				xmlhttp.onprogress = function () {};
                return xmlhttp;
            }
        };
    })();
	function NoCacheParameter() 
	{
		return "&nocache=" + Math.floor((1 + Math.random()) * 0x10000).toString(16);
	}	
	
    /**
     *  @private
     *  @param {!string} address
     */
    function SendAsync(address) {
        try {
			/** @struct */var request = ajaxRequest.GetAsyncRequest();
			if (request) {
				request.open("GET", address);
				request.send();
			} else {
				ns.Log("Ajax is not supported. Cannot send to product request: " + address);
			}
        }
        catch (e) {
            ns.Log("Sending error: " + (e.message || e) + " for: " + address);
        }
    }
    /**
     *  @private
     *  @param {!string} address
	 *  @return {!boolean}
     */
    function SendSync(address) {
        try {
			/** @struct */var request = ajaxRequest.GetSyncRequest();
			if (request) {
				request.open("GET", address, false);
				request.send();
				return request.status === 200;
			}
        }
        catch (e) {
            ns.Log("Sending error: " + (e.message || e) + " for: " + address);
        }
		return false;
    }
    /**
     *  @private
     *  @param {!string} address
     *  @param {string} msg
     */
    function SendLog(address, msg) {
		try {
			ns.Log(msg);
			setTimeout(function () {
				SendAsync(address + '/log?' + encodeURIComponent(msg));
			}, 0);
		}
		catch (e) {
			ns.Log('Sending log error: ' + (e.message || e));
		}
	}
	
    /**
     *  @private
     *  @final
     *  @constructor
     *  @struct
     *  @param {!string} ajaxPath
     */
    var CallReceiver = function (ajaxPath) {
        /** @const @type {!string} */ var m_path = ajaxPath + '/from';
        /** @type{Object<string,Object>} */  var m_plugins = {};
        /** @type{!number} */  var m_requestDelay = ns.MaxRequestDelay;
        /** @type{?number} */ var m_requestTimer = null;
        /** @type{Object} */ var m_request = null;
		/** @type{!boolean} */ var m_isProductConnected = false;
        /**
         *  @private
         *  @param {!string} methodName
         *  @param {!Function} callback
         *  @throws {!string}
         */
        this.RegisterMethod = function (methodName, callback) {
            /** @const @type{?string} */var pluginId = GetPluginIdFromMethodName(methodName);
            if (pluginId) {
                /** @type {Object<string,Function>} */var methods = GetPluginMethods(pluginId);
                if (methods) {
                    if (methods[methodName]) {
                        throw 'Already registered method ' + methodName;
                    }
                    methods[methodName] = callback;
                }
                else {
                    throw 'Cannot registered ' + methodName;
                }
            }
        };
        /**
         *  @private
         *  @param {!string} pluginId
         *  @param {null|undefined|function(number):number} callbackPing
         *  @param {null|undefined|function((number|string|null))} callbackError
         *  @throws {!string}
         */
        this.RegisterPlugin = function (pluginId, callbackPing, callbackError) {
            if (m_plugins[pluginId]) {
                throw 'Already started plugin ' + pluginId;
            }
            /** @struct */
            var plugin = {
                onError: callbackError,
                onPing: callbackPing,
                methods: {}
            };
            m_plugins[pluginId] = plugin;
            if (m_requestTimer === null) {
                UpdateDelay();
                if (IsPluginListEmpty())
                    return;
                m_requestTimer = setTimeout(function ping() {
                    try {
                        UpdateDelay();
                        if (IsPluginListEmpty())
                            return;
                        m_request = m_request || ajaxRequest.GetAsyncRequest();
                        SendRequest(m_request, m_path);
                        m_requestTimer = setTimeout(ping, m_requestDelay);
                    }
                    catch (e) {
                        ReportError('Send ping request: ' + (e.message || e));
                    }
                }, m_requestDelay);
            }
        };
        /**
         *  @private
         *  @param {!string} pluginId
         */
        this.UnregisterPlugin = function (pluginId) {
            delete m_plugins[pluginId];
            if (IsPluginListEmpty())
                ClearTimer();
        };
        /**
         *  @private
         */
        this.UnregisterAll = function () {
            if (m_plugins.length === 0)
                return;
            ClearTimer();
            m_plugins = {};
        };
        /**
         *  @private
         */
        function ClearTimer() {
            try {
                if (m_requestTimer) clearTimeout(m_requestTimer);
            } catch (e) {
            }
            try {
                if (m_request) {
                    m_request.onload = function () {
                    };
                    m_request.onerror = function () {
                    };
                    m_request.abort();
                }
            }
            catch (e) {
            }
            m_requestTimer = null;
            m_request = null;
        }
        /**
         *  @package
         *  @return {!boolean}
         */
        this.IsEmpty = IsPluginListEmpty;
        /**
         *  @private
         *  @return {!boolean}
         */
        function IsPluginListEmpty() {
            for (/** @type{!string} @const*/var key in m_plugins) {
                if (m_plugins.hasOwnProperty(key))
                    return false;
            }
            return true;
        }
		
		/**
		 *	@return {!boolean}
		 */
		this.IsProductConnected = function()
		{
			return m_isProductConnected;
		}
        /**
         *  @private
         */
        function UpdateDelay() {
            /** @type {!number} */var newDelay = ns.MaxRequestDelay;
            /** @const @type {!number} */var currentTime = ns.GetCurrentTime();
            for (/** @type{!string} @const*/var pluginId in m_plugins) {
                try {
                    /**@type {function(number):number}*/var onPing = m_plugins[pluginId].onPing;
                    if (onPing) {
                        /**@const @type{!number}*/var delay = onPing(currentTime);
                        if (delay < newDelay && delay > 0 && delay < ns.MaxRequestDelay) {
                            newDelay = delay;
                        }
                    }
                }
                catch (e) {
                    ReportPluginError(pluginId, 'UpdateDelay: ' + (e.message || e));
                }
            }
            m_requestDelay = newDelay;
        }
        /**
         *  @private
         *  @param {!string} pluginId
         *  @param {(string|number|null)} status
         */
        function ReportPluginError(pluginId, status) {
            /** @const @type{function((string|number|null))}*/var onError = m_plugins[pluginId].onError;
            if (onError)
                onError(status);
        }
        /**
         *  @private
         *  @param {(string|number|null)} status
         */
        function ReportError(status) {
            for (var pluginId in m_plugins)
                ReportPluginError(pluginId, status);
        }
        /**
         *  @private
         *  @param {?string} methodName
         *  @return {(string|null)}
         */
        function GetPluginIdFromMethodName(methodName) {
            if (methodName) {
                /** @const @type{Array<!string>}*/var names = methodName.split('.', 2);
                if (names.length === 2) {
                    return names[0];
                }
            }
            return null;
        }
        /**
         *  @private
         *  @param {!string} pluginId
         *  @return {Object<string,Function>}
         */
        function GetPluginMethods(pluginId) {
            /** @const @struct*/var plugin = m_plugins[pluginId];
            return plugin ? plugin.methods : null;
        }
        /**
         *  @private
         *  @param {!string} pluginId
         *  @param {!string} methodName
         *  @param {Array<string>} args
         *  @return {!boolean}
         */
        function CallPluginMethod(pluginId, methodName, args) {
            /** @const @dict*/var methods = GetPluginMethods(pluginId);
            if (methods) {
                /** @const @type{Function}*/var callback = methods[methodName];
                if (callback) {
                    try {
                        callback(args);
                        SendLog(ajaxPath, methodName + ' executed.');
                        return true;
                    }
                    catch (e) {
                        SendLog(ajaxPath, 'Call ' + methodName + ' in plugin ' + pluginId + ' error: ' + (e.message || e));
                    }
                }
            }
            SendLog(ajaxPath, 'Cannot call ' + methodName + ' for plugin ' + pluginId);
            return false;
        }
        /**
         *  @private
         *  @param {!Object} request
         *  @param {!string} path
         */
        function SendRequest(request, path) {
            try {
                request.open('GET', path);
                request.onerror = function () {
					m_isProductConnected = false;
					PostponeInit();
                    ReportError('AJAX ping network error!');
                };
                request.onload = function () {
					try
					{
						m_isProductConnected = true;
						/**
						 *  @const
						 *  @struct
						 *  @type {null|undefined|{result:number,method:string,parameters:Array<string>}}
						 */
						var command = request.responseText && ns.JSONParse(request.responseText);
						if (!command || typeof command.parameters === "undefined" || typeof command.method === "undefined") {
							ReportError('AJAX pong is not received. Product is deactivated');
							return;
						}
						if (command.method.length) {
							setTimeout(function () { m_request && SendRequest(m_request, m_path); }, 0);
							ns.Log('Try to find js callback ' + command.method);
							/** @const @type{?string}*/var pluginId = GetPluginIdFromMethodName(command.method);
							if (pluginId) {
								CallPluginMethod(pluginId, command.method, command.parameters);
							}
						}
					}
					catch (e)
					{
						ReportError("onload error " + (e.message || e));
					}
                };
                request.send(null);
            }
            catch (e) {
                ReportError('Ajax send ping exception: ' + (e.message || e));
            }
        }
    };
    /**
     *  @private
     *  @final
     *  @constructor
     *  @struct
     *  @param {!string} ajaxId
     *  @param {!string} sessionId
     *  @param {?string} prefix
     */
    var KasperskyLabSessionClass = function (ajaxId, sessionId, prefix) {
        /** @const @struct*/var self = this;
        /** @const @type{!string}*/var m_path = (prefix || '/') + ajaxId + '/' + sessionId;
        /** @const @type{!CallReceiver}*/var m_callReceiver = new CallReceiver(m_path);
        /**
         *  @private
         *  @param {!string} methodName
         *  @param {Array<string>} arrayOfArgs
         *  @param {?function(number=, Array<string>=)} callbackResult
         *  @param {?function(string=)} callbackError
         */
        function Call(methodName, arrayOfArgs, callbackResult, callbackError) {
            try {
                /** @struct */var request = ajaxRequest.GetAsyncRequest();
                if (!request) {
                    callbackError && callbackError('Cannot create AJAX request!');
                }
                /** @const @type{boolean} */ var noParameters = !arrayOfArgs || arrayOfArgs.length === 0;
                if (noParameters) {
                    request.open('GET', m_path + '/to/' + methodName + '/?get' + NoCacheParameter());
                } else {
                    request.open('POST', m_path + '/to/' + methodName);
                }
                /** type{?number} */
                var timeout = setTimeout(function () {
                    request.abort();
                    callbackError && callbackError('Cannot send AJAX request for calling ' + methodName);
                }, 120000);
                request.onerror = function () {
                    request.onerror = function () {
                    };
                    request.onload = function () {
                    };
                    callbackError && callbackError('AJAX request error for calling ' + methodName);
                };
                request.onload = function () {
                    clearTimeout(timeout);
                    timeout = null;
                    request.onload = function () {
                    };
                    request.onerror = function () {
                    };
                    if (request.responseText) {
                        if (callbackResult) {
                            /**
                             *  @const
                             *  @struct
                             *  @type {{result:!number,method:!string,parameters:Array<!string>}}
                             */
                            var command = ns.JSONParse(request.responseText);
                            callbackResult(command.result, command.parameters);
                        }
                        request = null;
                        return;
                    }
                    request = null;
                    if (callbackError) {
                        callbackError('AJAX request with unsupported url type!'); // when unsupported url type (file://) status == 0
                    }
                };
                request.send(noParameters ? null : ns.JSONStringify({
                    result: 0,
                    method: methodName,
                    parameters: arrayOfArgs
                }));
                ns.Log('Call native function ' + methodName);
            }
            catch (e) {
                if (callbackError) {
                    callbackError('AJAX request ' + methodName + ' exception: ' + (e.message || e));
                }
            }
        }
        /**
         *  @private
         *  @param {!string} methodName
         *  @param {Array<string>} arrayOfArgs
         *  @param {?function(number=, Array<string>=)=} callbackResult
         *  @param {?function(string=)=} callbackError
         *  @return {!boolean}
         */
        function SyncCall(methodName, arrayOfArgs, callbackResult, callbackError) {
            try {
                /** @struct */var request = ajaxRequest.GetSyncRequest();
                if (!request) {
                    callbackError && callbackError('Cannot create AJAX request!');
                    return false;
                }
                /** @const @type{boolean} */ var noParameters = !arrayOfArgs || arrayOfArgs.length === 0;
                if (noParameters) {
                    request.open('GET', m_path + '/to/' + methodName + '/?get' + NoCacheParameter(), false);
                } else {
                    request.open('POST', m_path + '/to/' + methodName, false);
                }
                ns.Log('SyncCall native function ' + methodName);
                request.send(noParameters ? null : ns.JSONStringify({
                    result: 0,
                    method: methodName,
                    parameters: arrayOfArgs
                }));
                if (request.status === 200 && request.responseText) {
                    if (callbackResult) {
                        /**
                         *  @const
                         *  @struct
                         *  @type {{result:!number,method:!string,parameters:Array<!string>}}
                         */
                        var command = ns.JSONParse(request.responseText);
                        callbackResult(command.result, command.parameters);
                    }
                    request = null;
                    return true;
                }
            }
            catch (e) {
                if (callbackError)
                    callbackError('AJAX request ' + methodName + ' exception: ' + (e.message || e));
            }
            return false;
        }
        /**
         *  @private
         */
        function Stop() {
            try {
                m_callReceiver.UnregisterAll();
                ns.Log("session stopped");
			    
				if (m_callReceiver.IsProductConnected())
				{
					var shutdownCommandPath = m_path + "/shutdown?get" + NoCacheParameter();
					if (!SendSync(shutdownCommandPath))
						SendAsync(shutdownCommandPath);
				}
            }
            catch (e) {
            }
        }
        /**
         *  @private
         *  @param {!string} pluginId
         */
        function DeactivatePlugin(pluginId) {
            ns.Log('DeactivatePlugin ' + pluginId);
            m_callReceiver.UnregisterPlugin(pluginId);
            if (m_callReceiver.IsEmpty()) {
                Stop();
            }
        }
        /**
         *  @private
         *  @param {!string} pluginId
         *  @param {null|undefined|function(number):number} callbackPing
         *  @param {null|undefined|function((number|string|null))} callbackError
         */
        function ActivatePlugin(pluginId, callbackPing, callbackError) {
            ns.Log('ActivatePlugin ' + pluginId);
            m_callReceiver.RegisterPlugin(pluginId, callbackPing, function (e) {
                callbackError && callbackError(e);
                m_callReceiver.UnregisterPlugin(pluginId);
                if (m_callReceiver.IsEmpty()) {
                    Stop();
                }
            });
        }
        /**
         *  @private
         *  @param {!string} methodName
         *  @param {!Function} callback
         */
        function RegisterMethod(methodName, callback) {
            ns.Log('RegisterMethod ' + methodName);
            m_callReceiver.RegisterMethod(methodName, callback);
        }
        /**
         *  @export
         *  @param {!string} msg
         */
        this.Log = function (msg) {
            msg && SendLog(m_path, msg);
        };
        /**
         *  @export
         *  @param {!function(Function=, Function=, Function=, Function=, Function=)} init
         */
        this.InitializePlugin = function (init) {
            init(
                function () {
                    ActivatePlugin.apply(self, arguments);
                },
                function () {
                    RegisterMethod.apply(self, arguments);
                },
                function () {
                    Call.apply(self, arguments);
                },
                function () {
                    DeactivatePlugin.apply(self, arguments);
                },
                function () {
                    return SyncCall.apply(self, arguments);
                }
            );
        };
		
		ns.AddEventListener(window, "beforeunload", function() 
			{
				if (!m_callReceiver.IsEmpty())
					Stop();
			});
    };
	var runners = {};
	var pluginsInitData = [];
	ns.AddRunner = function(pluginName, runnerFunc, initParameters)
	{
		runners[pluginName] = runnerFunc;
		if (initParameters)
		{
			pluginsInitData.push({plugin: pluginName, parameters: initParameters});
		}
	};
	
	ns.ContentSecurityPolicyNonceAttribute = signature;
	function GetSpecialPlugins(predefined) 
	{
		return (predefined) ? "&plugins=" + encodeURIComponent(predefined) : "";    				
	}
	function IsDefined(variable)
	{
	    return "undefined" !== typeof(variable);
	}
	function Init()
	{
		var specialPlugins = IsDefined(ns.PLUGINS_LIST) ? GetSpecialPlugins(ns.PLUGINS_LIST) : GetSpecialPlugins("");
		var connectRequest = ajaxRequest.GetAsyncRequest();
		var serializedInitData = (pluginsInitData.length) ? "&data=" + encodeURIComponent(ns.JSONStringify({data : pluginsInitData})) : "";
		var initTimeout = setTimeout(function ()
			{
				connectRequest.abort();
				PostponeInit();
			}, 120000);
		
		connectRequest.open("GET", prefix + signature + "/init?url=" + encodeURIComponent(document.location.href) + specialPlugins + serializedInitData + NoCacheParameter());
		connectRequest.onload = function()
			{
				clearTimeout(initTimeout);
				/**
				*  @const
				*  @struct
				*  @type {{ajaxId:string,localization:string,plugins:Array<{name:string,localization:string,settings:Object}>}}
				*/
				var initSettings = connectRequest.responseText && ns.JSONParse(connectRequest.responseText);
				kaspersyLabSessionInstance = new KasperskyLabSessionClass(initSettings.ajaxId, initSettings.sessionId, prefix);
				var plugins = initSettings.plugins;
				for (var i = 0, pluginsCount = plugins.length; i < pluginsCount; ++i)
				{
					var plugin = plugins[i];
					var pluginRunnerFunction = runners[plugin.name];
					if (pluginRunnerFunction)
						pluginRunnerFunction(KasperskyLab, kaspersyLabSessionInstance, plugin.settings, plugin.localization);
				}
				
				connectRequest.onload = function(){};
				connectRequest.onerror = function(){};
			};
		connectRequest.onerror = function()
			{
				clearTimeout(initTimeout);
				connectRequest.onload = function(){};
				connectRequest.onerror = function(){};
				PostponeInit();
			};
		connectRequest.send(null);
	}
	
	var postponedInitTimeout = null;
	function PostponeInit()
	{
		clearTimeout(postponedInitTimeout)
		postponedInitTimeout = setTimeout(function () { Init(); }, 60 * 1000);
	}
	
	setTimeout(function () { Init(); }, 0);
})(KasperskyLab);
(function (ns) 
{
ns.waitForApiInjection = function(isApiInjected, eventName, callback)
{
    if (isApiInjected())
    {
        callback();
        return;
    }
    var subscription = createSubscription(eventName, onApiInjected)
    function onApiInjected()
    {
        if (isApiInjected())
        {
            subscription.unsubscribe();
            callback();
        }
    }
}
function createSubscription(eventName, callback)
{
    var windowEventsSupported = document.createEvent || window.addEventListener;
    return new (windowEventsSupported ? ModernSubscription : IeLegacySubscription)(eventName, callback);
}
function ModernSubscription(eventName, callback)
{
    ns.AddRemovableEventListener(window, eventName, callback);
    this.unsubscribe = function()
    {
        ns.RemoveEventListener(window, eventName, callback);
    }
}
function IeLegacySubscription(eventName, callback)
{
    ns.AddRemovableEventListener(document.documentElement, 'propertychange', onPropertyChange);
    this.unsubscribe = function()
    {
        ns.RemoveEventListener(document.documentElement, 'propertychange', onPropertyChange);
    }
    function onPropertyChange(event)
    {
        if (event.propertyName == eventName)
            callback();
    }
}
})(KasperskyLab || {});
var tabIdPropertyName = KasperskyLab.LIGHT_PLUGIN_API_KEY || 'klTabId_kis';
var scriptPluginId = Math.floor((1 + Math.random()) * 0x10000).toString(16);
function isApiInjected()
{
    return !!window[tabIdPropertyName];
}
function makeTopLevelArgument()
{
    return window == window.top ? 'true' : 'false';
}
function removeTabIdProperty()
{
	try {
		delete window[tabIdPropertyName];
	} catch (e) {
		window[tabIdPropertyName] = undefined;
	}	
}
var documentInitParameters = isApiInjected() ? [String(window[tabIdPropertyName]), makeTopLevelArgument(), scriptPluginId] : null;
KasperskyLab.AddRunner("light_doc", function (ns, session)
{
session.InitializePlugin(function(activatePlugin, _, callFunction)
{
	activatePlugin('light_doc');
	
	if (documentInitParameters)
	{
		removeTabIdProperty();
		return;
	}
	
	ns.waitForApiInjection(isApiInjected, tabIdPropertyName, function()
	{
		var tabId = String(window[tabIdPropertyName]);
		removeTabIdProperty();
		callFunction("light_doc.registerDocument", [
			tabId, 
			document.URL,
			makeTopLevelArgument(),
            scriptPluginId
			]);
	});	
});
}, documentInitParameters);
(function (ns)
{
ns.IsPositionEqual = function(prevPos, currentPos)
{
	return prevPos && currentPos && prevPos.top === currentPos.top && prevPos.left === currentPos.left;
};
	
ns.GetAbsoluteElementPosition = function(element)
{
	var box = element.getBoundingClientRect();
	var scroll = ns.GetPageScroll();
	return {
			left: box.left + scroll.left,
			top: box.top + scroll.top,
			right: box.right + scroll.left,
			bottom: box.bottom + scroll.top
		};
};
})(KasperskyLab || {});
(function (ns) 
{
ns.ProtectableElementDetector = function(protectMode)
{
	var m_typesForbidden = ['hidden', 'submit', 'radio', 'checkbox', 'button', 'image', 'number', 'email'];
	var m_protectMode = protectMode;
	/**
	 * @return {boolean}
	 */
	this.Test = function(element)
	{
		if (m_protectMode < 2 || m_protectMode > 3)
			return false;
			
		var elementType = element.getAttribute('type');
		elementType = elementType && elementType.toLowerCase();
		if (m_protectMode === 2)
		{
			if (elementType != 'password')
				return false;
		}
		else if (Includes(m_typesForbidden, elementType))
		{
			return false;
		}
		if (GetComputedStyle(element, 'display') === 'none')
			return false;
		var maxLength = parseInt(element.getAttribute('maxlength'), 10);
		return typeof maxLength === 'number' && maxLength <= 3 ? false : !element.readOnly;
	};
	/**
	 * @return {boolean}
	 */
	function Includes(list, text)
	{
		var i = 0, count = list.length;
		for (; i < count; ++i)
		    if (list[i] === text)
				return true;
		return false;
	}
	/**
	 * @return {string}
	 */
	function GetComputedStyle(element, property)
	{
		var value;
		if (element.currentStyle)
		{
			value = element.currentStyle[property];
		}
		else
		{
			var styles = window.getComputedStyle(element, '');
			if (styles)
				value = styles.getPropertyValue(property);
		}
		return typeof value !== 'string' ? '' : value.toLowerCase();
	}
}
})(KasperskyLab || {});
(function (ns)
{
ns.SecureInputTooltip = function(locales)
{
	var m_tooltip,
		// position helpers
		m_curPosition,
		m_top,
		m_bottom,
		m_pointer,
		m_needRestoreFocus,
		that = this;
	function CreateDivWithStyle(cssText)
	{
		var div = document.createElement('div');
		div.style.cssText = cssText;
		return div;
	}
	
	function CreateTooltip()
	{
		var balloonDiv = CreateDivWithStyle("position:absolute;display:block;width:auto;height:auto;padding:0;margin:0;text-align:left;border:none;border-radius:0;background:#transparent;z-index:2147483646;font-size:0px");
		var iconDiv = CreateDivWithStyle("position:relative;display:block;height:auto;width:auto;padding:35px 10px 11px;margin:0;text-align:left;border:1px solid #B2B2B2;border-radius:5px;background:#fff url(" + KasperskyLab.GetResourceSrc('/vk/VkTooltipBanner.png') + ") 10px 9px no-repeat;z-index:2147483646;");
		var close = CreateDivWithStyle("position:absolute;right:10px;top:6px;display:inline-block;height:16px;width:8px;padding:0;margin:0;text-align:left;background:url(" + KasperskyLab.GetResourceSrc('/vk/close_icon.png') + ") right center no-repeat;cursor:pointer;border:none;border-radius:0;white-space:nowrap;z-index:2147483646;");
		var contentText = CreateDivWithStyle("position:static;display:block;width:auto;height:auto;padding:0;margin:0;font:11px/1 Arial,Helvetica,sans-serif;text-align:left;color:#000;border:none;border-radius:0;background:#transparent;white-space:nowrap;z-index:2147483646;");
		m_top = CreateDivWithStyle("position:relative;display:block;width:32px;height:12px;padding:0;margin:0 0 -1px;text-align:left;border:none;border-radius:0;background:#transparent;z-index:2147483647;");
		m_bottom = CreateDivWithStyle("position:relative;display:block;width:32px;height:12px;padding:0;margin:-1px 0 0;text-align:left;border:none;border-radius:0;background:#transparent;z-index:2147483647;");
		m_pointer = CreateDivWithStyle("position:static;display:block;padding:0;margin:0;height:12px;width:100%;z-index:2147483647;");
		
		balloonDiv.appendChild(m_top);
		balloonDiv.appendChild(iconDiv);
		balloonDiv.appendChild(m_bottom);
		
		iconDiv.appendChild(close);
		iconDiv.appendChild(contentText);
		
		contentText.appendChild(document.createTextNode(locales["VkTooltipText"]));
		
		close.onmouseover = function(){m_needRestoreFocus = true;};
		close.onmouseout = function(){m_needRestoreFocus = false;};
		
		m_tooltip = balloonDiv;
	}
    function PositionTooltipPointer(position)
	{
		if (m_pointer.parentNode)
			m_pointer.parentNode.removeChild(m_pointer);
		
		var destinationDiv, pointerBackgroundImage;
		if (position === "top")
		{
			pointerBackgroundImage = "url(" + ns.GetResourceSrc('/vk/pointer_top.png') + ") no-repeat right bottom";
			destinationDiv = m_top;
        } 
		else if (position === "bottom") 
		{
			pointerBackgroundImage = "url(" + ns.GetResourceSrc('/vk/pointer_bottom.png') + ") no-repeat right top";
            destinationDiv = m_bottom;
        }
		m_pointer.style.background = pointerBackgroundImage;
		destinationDiv.appendChild(m_pointer);
    }
    function PositionTooltip(element)
	{
        var inputPosition = ns.GetAbsoluteElementPosition(element);
        if (!ns.IsPositionEqual(m_curPosition, inputPosition))
		{
            m_tooltip.style.left = inputPosition.left + "px";
			
			var tooltipHeight = m_tooltip.offsetHeight;
			var inputTopRelative = inputPosition.top - ns.GetPageScroll().top;
			var clientHeightUnderInput = ns.GetPageHeight() - inputTopRelative - element.offsetHeight;
            if ((clientHeightUnderInput > tooltipHeight - 1) || 
				(inputPosition.top - tooltipHeight + 1 < 0))
			{
                m_tooltip.style.top = (inputPosition.top + element.offsetHeight - 1) + "px";
                PositionTooltipPointer("top");
            }
			else
			{
                m_tooltip.style.top = (inputPosition.top - tooltipHeight + 1) + "px";
                PositionTooltipPointer("bottom");
            }
            m_curPosition = inputPosition;
        }
	}
	this.Show = function(element)
	{
		document.body.appendChild(m_tooltip);
		PositionTooltip(element);
		var timer = setInterval(function() { PositionTooltip(element); }, 100);
		this.Hide = function()
		{
			clearInterval(timer);
			document.body.removeChild(m_tooltip);
			if (m_needRestoreFocus)
				setTimeout(function(){element.focus();}, 0);
			m_tooltip = null;
			this.Show = function(){};
			this.Hide = function(){};
		};
		setTimeout(function()
		{
			that.Hide();
		}, 3000);
	};
	this.Hide = function(){};
	CreateTooltip();
};
})(KasperskyLab || {});
(function (ns)
{
ns.VirtualKeyboardInputIcon = function(clickCallback)
{
	var m_curPosition,
		m_iconDiv,
		m_element;
	
	function CreateDivWithStyle(cssText)
	{
		var div = document.createElement('div');
		div.style.cssText = cssText;
		return div;
	}
	function PositionIcon()
	{
		var iconStyle = m_iconDiv.style,
			inputPosition = ns.GetAbsoluteElementPosition(m_element);
		if (!ns.IsPositionEqual(m_curPosition, inputPosition))
		{
			iconStyle.left = inputPosition.left + m_element.offsetWidth - 20 + 'px';
			iconStyle.top = inputPosition.top + (m_element.offsetHeight - 16) / 2 + 'px';
			m_curPosition = inputPosition;
		}
	}
	
	function CreateIcon()
	{
		m_iconDiv = CreateDivWithStyle('position:absolute;display:block;width:16px;height:16px;background:url(' + ns.GetResourceSrc('/vk/VkInputFieldIcon.png') + ') no-repeat center center;cursor:pointer;z-index:2147483647;font-size:0px');
		ns.AddEventListener(m_iconDiv, 'mouseover', function ()
		{
			m_iconDiv.style.filter = 'alpha(opacity=60)';	// IE8
			m_iconDiv.style.opacity = 0.6;
		});
		ns.AddEventListener(m_iconDiv, 'mouseout', function()
		{
			m_iconDiv.style.filter = 'alpha(opacity=100)';	// IE8
			m_iconDiv.style.opacity = 1;
		});
		ns.AddEventListener(m_iconDiv, 'click', clickCallback);
	}
	
	CreateIcon();
	
	// showing icon
	this.Show = function(element)
	{
		this.Hide();
		m_element = element;
		document.body.appendChild(m_iconDiv);
		PositionIcon();
		var timer = setInterval(PositionIcon, 100);
		this.Hide = function()
		{
			clearInterval(timer);
			document.body.removeChild(m_iconDiv);
			this.Hide = function(){};
		};
	};
	this.Hide = function(){};
};
})(KasperskyLab || {});
KasperskyLab.AddRunner("vk", function (ns, session, settings, locales)
{
var VirtualKeyboard = function()
{
	var m_callFunction, m_syncCallFunction;
	var m_virtualKeyboardIconShowMode = 0;
	var m_secureInputProtectMode = 0;
	var m_activeElement = null;
	var m_lastFocusedElement = null;
	
	// 0 - not protected
	// 1 - starting protect
	// 2 - protected
	// 3 - stopping protect
	var m_protectedState = 0;
	var m_enabledSecureInput = false;
	var m_protectChangeTimeout;
	
	var m_protectableVirtualKeyboardChecker = new ns.ProtectableElementDetector(settings.vkProtectMode);
	var m_protectableSecureInputChecker = null;
	var m_protectableVirtualKeyboardIconChecker = null;
	
	var m_attributeName = "vk_" + Math.floor((1 + Math.random()) * 0x10000).toString(16);
	
	function ShowVirtualKeyboard()
	{
		if (m_lastFocusedElement)
			m_lastFocusedElement.focus();
		m_callFunction("vk.showKeyboard");
	}
	var m_tooltip = new ns.SecureInputTooltip(locales);
	var m_icon = new ns.VirtualKeyboardInputIcon(ShowVirtualKeyboard);
	var m_iconHideTimer;
	var m_postponeStart;
	var m_shutdown = false;
	session.InitializePlugin(function(activatePlugin, registerMethod, callFunction, deactivatePlugin, syncCallFunction){
		m_callFunction = callFunction;
		m_syncCallFunction = syncCallFunction;
		activatePlugin('vk', OnPing);
		registerMethod('vk.settings', SetSettings);
	});
	/**
	 * @return {number}
	 */
	function OnPing()
	{
		return ns.MaxRequestDelay;
	}
	
	function SetSettings(argumentList)
	{
		var newVirtualKeyboardIconShowMode = parseInt(argumentList[0], 10);
		var newSecureInputProtectMode = parseInt(argumentList[1], 10);
		SetSettingsImpl(newVirtualKeyboardIconShowMode, newSecureInputProtectMode);
	}
	
	function SetSettingsImpl(newVirtualKeyboardIconShowMode, newSecureInputProtectMode)
	{
		if (newSecureInputProtectMode != m_secureInputProtectMode)
			m_protectableSecureInputChecker = new ns.ProtectableElementDetector(newSecureInputProtectMode);
		if (newVirtualKeyboardIconShowMode != m_virtualKeyboardIconShowMode)
			m_protectableVirtualKeyboardIconChecker = new ns.ProtectableElementDetector(newVirtualKeyboardIconShowMode);
		
		if (newSecureInputProtectMode > m_secureInputProtectMode ||
			newVirtualKeyboardIconShowMode > m_virtualKeyboardIconShowMode)
		{
			SetEventListenersToElements(document.getElementsByTagName('input'),
				function(event) { OnElementFocus(event.target || event.srcElement); },
				function() { OnElementBlur(); });
		}
		// TODO: may be need send blur if current active element don't need protect
		
		m_secureInputProtectMode = newSecureInputProtectMode;
		m_virtualKeyboardIconShowMode = newVirtualKeyboardIconShowMode;
	}
	
	function NeedProtectElement(element)
	{
		return m_protectableSecureInputChecker.Test(element) || m_protectableVirtualKeyboardChecker.Test(element);
	}
	
	function SetEventListenersToElement(element, focusHandler, blurHandler, currentFocusedElement)
	{
		if (!NeedProtectElement(element))
			return;
		
		var secureInputValue = element.getAttribute(m_attributeName);
		if (secureInputValue && secureInputValue === "subscribed")
			return;
		element.setAttribute(m_attributeName, "subscribed");
		ns.AddEventListener(element, "focus", focusHandler, true);
		ns.AddEventListener(element, "blur", blurHandler, true);
		if (element === currentFocusedElement)
			OnElementFocus(element);
	}
	
	function SetEventListenersToElements(elements, focusHandler, blurHandler)
	{
		var currentFocusedElement = GetFocusedElement();
		var i = 0, count = elements.length;
		for (; i < count; ++i)
			SetEventListenersToElement(elements[i], focusHandler, blurHandler, currentFocusedElement);
	}
	function GetFocusedElement()
	{
		var element = document.activeElement;
		if (document.hasFocus() &&
			element &&
			element.tagName.toLowerCase() === 'input')
		{
			return element;
		}
		return null;
	}
	
	function HandleStartProtectCallback(result, args, needSecureInputCall)
	{
		if (m_protectedState === 3)	// 3 - stopping protect
		{
			if (result === 0)
				StopProtect();
			else
				m_protectedState = 0;	// 0 - not protected
			return;
		}
		if (result === 0)
		{
			if (!args || args.length < 1)
			{
				session.Log("ERR VK - unexpected arguments");
				return;
			}
			
			m_enabledSecureInput = args[0] === "true";
			m_protectedState = 2;	// 2 - protected
			
			var needSecureInput = m_protectableSecureInputChecker.Test(m_activeElement);
			if (needSecureInput === needSecureInputCall)
				ShowBalloons();
			else
				CheckProtectModeAndShowBalloons();
			return;
		}
		else if (result === 1)
		{
			m_postponeStart = setTimeout(function() {OnElementFocus(m_activeElement);}, 100);
		}
		m_protectedState = 0;	// 0 - not protected
	}
	function StartProtect()
	{
		var needSecureInput = m_protectableSecureInputChecker.Test(m_activeElement);
		m_protectedState = 1;	// 1 - starting protect
		m_callFunction("vk.startProtect", [needSecureInput.toString()], function(result, args) { HandleStartProtectCallback(result, args, needSecureInput);});
	}
	
	function ChangeMode()
	{
		var needSecureInput = m_protectableSecureInputChecker.Test(m_activeElement);
		m_protectedState = 1;	// 1 - starting protect
		m_callFunction("vk.changeMode", [needSecureInput.toString()], function(result, args) { HandleStartProtectCallback(result, args, needSecureInput);});
	}
	function StopProtect()
	{
  	    m_protectedState = 3;	// 3 - stopping protect
	    m_callFunction("vk.stopProtect", [], function (result)
			{
				if (m_protectedState === 1 && result === 0)	// 1 - starting protect
				{
					StartProtect();
					return;
				}
				m_protectedState = 0;		// 0 - not protected
				m_activeElement = null;
			});
	}
	
	function ShowBalloons()
	{
		if (m_enabledSecureInput)
			m_tooltip.Show(m_activeElement);
		if (m_protectableVirtualKeyboardIconChecker.Test(m_activeElement))
			m_icon.Show(m_activeElement, ShowVirtualKeyboard);
	}
	
	function CheckProtectModeAndShowBalloons()
	{
		var needSecureInput = m_protectableSecureInputChecker.Test(m_activeElement);
		if (needSecureInput != m_enabledSecureInput)
			ChangeMode();
		else
			ShowBalloons();
	}
	function OnElementFocus(element)
	{
		if (m_shutdown)
			return;
		if (m_iconHideTimer)
		{
			clearTimeout(m_iconHideTimer);
			m_iconHideTimer = null;
			m_icon.Hide();
		}
		if (!NeedProtectElement(element))
		{
			m_activeElement = null;
			return;
		}
		m_activeElement = element;
		m_lastFocusedElement = element;
		clearTimeout(m_postponeStart);
		clearTimeout(m_protectChangeTimeout);
		m_protectChangeTimeout = setTimeout(function(){ProcessFocus();}, 0);
	}
	function OnElementBlur()
	{
		if (m_shutdown)
			return;
		clearTimeout(m_postponeStart);
		m_iconHideTimer = setTimeout(function() {m_icon.Hide();}, 500);
		m_tooltip.Hide();
		clearTimeout(m_protectChangeTimeout);
		m_protectChangeTimeout = setTimeout(function(){ProcessBlur();}, 0);
	}
	function ProcessFocus()
	{
		if (m_protectedState === 0)			// 0 - not protected
			StartProtect();
		else if (m_protectedState === 2) 	// 2 - protected
			CheckProtectModeAndShowBalloons();
		else if (m_protectedState === 3)	// 3 - stopping protect
			m_protectedState = 1;			// 1 - starting protect
	}
	function ProcessBlur()
	{
		if (m_protectedState === 2)	// 2 - protected
			StopProtect();
		else if (m_protectedState === 1)	// 1 - starting protect
			m_protectedState = 3;	// 3 - stopping protect
	}
	SetSettingsImpl(settings.vkMode, settings.skMode);
	ns.AddEventListener(window, 'beforeunload', function()
		{
			clearTimeout(m_protectChangeTimeout);
			clearTimeout(m_postponeStart);
			m_shutdown = true;
	});
};
var instance = null;
if (document.readyState === "complete")
{
	instance = new VirtualKeyboard();
}
else
{
	ns.AddEventListener(window, "load", function(){
		if (!instance)
			instance = new VirtualKeyboard();
	});
}
});
KasperskyLab.AddRunner("ob", function (ns, session)
{
/**
 *  @constructor
 *  @struct
 *  @private
 */
var OnlineBanking = function()
{
    /** type{!number} */ var m_idleStartTime = ns.GetCurrentTime();
	/** type{!boolean} */var m_isInFrame = true;
		
    try {
        m_isInFrame = window != window.top;
    } catch (e) {
        session.Log('Online banking cross domain frame! ' + (e.message || e));
    }
    session.InitializePlugin(function(activatePlugin, registerMethod, callFunction, deactivatePlugin){
        if (m_isInFrame) {
            callFunction('ob.disconnect', []);
        } else {
            activatePlugin('ob', OnPing, OnError);
            registerMethod('ob.navigate', NavigateTo);
            registerMethod('ob.shutdown',
                function(){
                    deactivatePlugin('ob');
                }
            );
            callFunction('ob.connect', [],
                function(result){
                    // check eka::sOk
                    if (result != 0) {
                        deactivatePlugin('ob');
                    }
                },
                OnError);
        }
    });
	/**
	 *  @private
	 *  @param {!Object} e
	 */
    function OnError(e) {
        session.Log('ERR OB - ' + (e.message || e));
    }
    /**
     *  @private
     *  @param  {!number} currentTime
     *  @return {!number}
     */
    function OnPing(currentTime) {
        /** @const @type {!number} */var idleTime = (currentTime >= m_idleStartTime) ? currentTime - m_idleStartTime : 0;
        // first 10s pin delay == 500ms
        return idleTime <= 10000 ? 500 : ns.MaxRequestDelay;
    }
	
	/**
	 *  @private
	 *  @param {Array<string>} args
	 */
	function NavigateTo(args) {
		if (args.length < 1)
		{
			session.Log("Wrong arguments for navigate" + args.length);
			return;
		}
		document.location.href = args[0];
   }
};
try
{
    /** @const @struct */ var instance = new OnlineBanking();
}
catch(e)
{
    session.Log('Online banking exception ' + (e.message || e));
}
});
KasperskyLab.AddRunner("ab", function (ns, session, settings, locales)
{
    var AntiBanner = function (state, keyCode) {
        var m_currentSrc = 0,
            m_mouseX = 0,
            m_mouseY = 0,
            m_needToShowMenu = false,
            m_state = state === 'Enabled',
            m_hotKeyPressed = false,
            hidden = "hidden",
            m_callFunction;
        session.InitializePlugin(function(activatePlugin, registerMethod, callFunction){
            m_callFunction = callFunction;
            activatePlugin('ab', OnPing, OnError);
            registerMethod('ab.setstate', function(argumentList) { m_state = argumentList.length && argumentList[0] === 'Enabled'; } );
        });
        //noinspection JSLint
        var m_balloon = new ns.Balloon("ab", 1, OnCreateBalloon, OnClickBalloon);
        SetEventListenersToWindow(window);
        /**
         * @return {number}
         */
        function OnPing() {
            return ns.MaxRequestDelay;
        }
        function OnError(e) {
            session.Log('ERR AB - ' + (e.message || e));
        }
        function ShowBalloon(timeout) {
            m_balloon.ShowBalloon(function () { return {isNeed:true, x:m_mouseX, y:m_mouseY}; }, timeout, 2000);
        }
        function HideBalloon() {
            m_balloon.ShowBalloon(function () { return {isNeed:false}; }, 500); // bad balloon interface!
        }
        function FocusChange (evt) {
            var evtMap = {
                focus:true, focusin:true, pageshow:true, blur:false, focusout:false, pagehide:false
            };
            evt = evt || window.event;
            var documentIsActive = evtMap.hasOwnProperty(evt.type) ? evtMap[evt.type] : document[hidden];
            if (!documentIsActive) {
                HideBalloon();
            }
        }
        function OnCreateBalloon(element) {
            ns.AddStyles(['.kisb .kl_abmenu { font-size:12px; font-family: "Segoe UI", Arial, sans-serif; color: #FFFFFF; float: left; padding: 8px; border: 1px solid #FFFFFF; background: #057662; background: -moz-linear-gradient(#057662, #1a8171);background: -ms-linear-gradient(#057662, #1a8171);background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #057662), color-stop(100%, #1a8171)); background: -webkit-linear-gradient(#057662, #1a8171); background: -o-linear-gradient(#057662, #1a8171);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#057662", endColorstr="#1a8171"); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr="#057662", endColorstr="#1a8171")";background: linear-gradient(#057662, #1a8171);border-radius: 8px;}']);
            var mainDiv = document.createElement('div');
            mainDiv.className = 'kl_abmenu';
            mainDiv.appendChild(document.createTextNode(locales["AntiBannerContextMenuPrompt"]));
            element.appendChild(mainDiv);
        }
        /**
         * @return {boolean}
         */
        function OnClickBalloon(e) {
			SetKeyboardStatus(!!e.ctrlKey);
            if (m_state && m_currentSrc) {
                m_callFunction("ab.AddToBlockList", [m_currentSrc], null, OnError);
            }
            return true;
        }
        function OnMouseOver(e) {
			SetKeyboardStatus(!!e.ctrlKey);
			var element = e.target || e.srcElement;
            if (!!element) {
                m_currentSrc = element.src;
                if (m_state) {
                    m_needToShowMenu = true;
                    if (m_hotKeyPressed) {
                        ShowBalloon(500);
                    }
                }
            }
        }
        function OnMouseOut() {
            m_needToShowMenu = false;
        }
        function OnMouseMove(event) {
            m_mouseX = event.clientX;
            m_mouseY = event.clientY;
			SetKeyboardStatus(!!event.ctrlKey);
        }
        function AddEventListeners(element, attributeName) {
            var attribute = element.attributes.getNamedItem(attributeName);
            if (attribute !== null && attribute.value === "on") {
                return;
            }
            element.setAttribute(attributeName, "on");
            ns.AddEventListener(element, 'mouseover', OnMouseOver); 
            ns.AddEventListener(element, 'mouseout', OnMouseOut);
            ns.AddEventListener(element, 'mousemove', OnMouseMove);
        }
        function SetEventListenersToElements(elements) {
            //noinspection JSLint
            for (var i = 0, len = elements.length; i < len; ++i) {
                AddEventListeners(elements[i], "KasperskyLab_AntiBanner");
            }
        }
		function SetKeyboardStatus(keyPressed) {
			m_hotKeyPressed = keyPressed;
			if (m_hotKeyPressed) {
				ns.RemoveEventListener(document, "keydown", OnKeyDown);
				ns.AddRemovableEventListener(document, "keyup", OnKeyUp);
			} else { 
				ns.RemoveEventListener(document, "keyup", OnKeyUp);
				ns.AddRemovableEventListener(document, "keydown", OnKeyDown);
			}
		}
		
		function OnKeyDown(e) {
			var evt = e || window.event;
			if (evt.keyCode === keyCode) {
				SetKeyboardStatus(true);
				if (m_state && m_needToShowMenu) {
                    ShowBalloon(500);
                }				
			}
			return true;
		}
		
		function OnKeyUp() {
			SetKeyboardStatus(false);
			return true;
		}
		
        function SetVisibilityHandlers(document) {
            // Standards:
            if (hidden in document)
                document.addEventListener("visibilitychange", FocusChange);
            else if ((hidden = "mozHidden") in document)
                document.addEventListener("mozvisibilitychange", FocusChange);
            else if ((hidden = "webkitHidden") in document)
                document.addEventListener("webkitvisibilitychange", FocusChange);
            else if ((hidden = "msHidden") in document)
                document.addEventListener("msvisibilitychange", FocusChange);
            // IE 9 and lower:
            else if ("onfocusin" in document)
                document.onfocusin = document.onfocusout = FocusChange;
            // All others:
            else
                window.onpageshow = window.onpagehide = window.onfocus = window.onblur = FocusChange;
            // set the initial state (but only if browser supports the Page Visibility API)
            if( document[hidden] !== undefined )
                FocusChange({type: document[hidden] ? 'blur' : 'focus'});
        }
        function SetEventListenersToDocument(document) {
            ns.AddRemovableEventListener(document, "keydown", OnKeyDown);
            SetVisibilityHandlers(document);
            SetEventListenersToElements(document.getElementsByTagName('img'));
        }
        function SetEventListenersToWindow(window) {
            if (window.document)
                SetEventListenersToDocument(window.document);
        }        
    };
    var instance = null;
	if (document.readyState === "complete")
	{
		instance = new AntiBanner(settings.state, 17);
	}
	else
	{
		ns.AddEventListener(window, 'load', function () {
			// TODO: SetState can be called after 'DOMContentLoaded' but before 'load' event
			try
			{
				if (!instance) {
					instance = new AntiBanner(settings.state, 17); // CTRL scan code
				}
			}
			catch(e)
			{
				session.Log('Antibanner exception: ' + (e.message || e));
			}
		});
	}
});
KasperskyLab.AddRunner("cb", function (ns, session, settings, locales)
{
/**
 *  @constructor
 *  @struct
 *  @private
 */
var ContentBlocker = function()
{
    /** 
     * @type {!number}
     */
	var m_idleStartTime = ns.GetCurrentTime();
	var m_signRequest = [];
	var m_callFunction;
	 
	/**
	 *  @const
	 *  @type {function(!string)}
	 */
	var m_deactivateFunction;
    session.InitializePlugin(function(activatePlugin, registerMethod, callFunction, deactivatePlugin){
        m_deactivateFunction = deactivatePlugin;
        m_callFunction = callFunction;
        activatePlugin('cb', OnPing, OnError);
        registerMethod('cb.reloadUrl', ReloadUrl);
        registerMethod('cb.signReady', SignReady);
        registerMethod('cb.shutdown',
                function(){
                    deactivatePlugin('cb');
                }
        );
        callFunction('cb.connect', [],
            function(result){
                // check eka::sOk
                if (result != 0) {
                    deactivatePlugin('cb');
                }
            },
            function(e){
                OnError(e);
                deactivatePlugin('cb');
            });
    });
	/**
	 *  @private
	 *  @param {Object} e
	 */
    function OnError(e) {
        session.Log('ERR CB - ' + (e.message || e));
    }
    /**
     * @private
	 * @param  {!number} currentTime
     * @return {!number}
     */
    function OnPing(currentTime) {
        /** @const @type{!number} */var idleTime = (currentTime >= m_idleStartTime) ? currentTime - m_idleStartTime : 0;
        // first 10s pin delay == 500ms
        return idleTime <= 10000 ? 500 : ns.MaxRequestDelay;
    }
	/**
	 *  @private
	 */
    function ReloadUrl() {
		session.Log("Start reload url " + document.readyState);
        m_idleStartTime = ns.GetCurrentTime();
        document.location.href = document.location.href;
    }
    /**
     *  @private
     *  @param {Array<!string>} args
     */
    function SignReady(args) {
        m_idleStartTime = ns.GetCurrentTime();
    
        if (args.length !== 2) {
            session.Log('ContentBlocker error: invalid parameter count ' + args.length);
            return;
        }
        if (!m_signRequest[args[0]]){
            session.Log('ContentBlocker error: invalid challenge');
            return;            
        }
        m_signRequest[args[0]](args[1]);
    }
	
	if (settings.isProductInfoRequired)
	{
		window.KasperskyLab = (function (object)
		{
			var thisProductId = locales["ProductName"] + " " + locales["ProductVersion"];
			var thisProduct = {
				'productName': locales["ProductName"],
				'productVersion': locales["ProductVersion"],
				'productPPCSID': locales["ProductPPCSID"],
				'deviceId': locales["DeviceId"],
				'features': {
					'isSafeMoneyInstalled': locales["IsSafeMoneyInstalled"],
					'isSafeMoneyProtectionEnabled': settings.isSafeMoneyProtectionEnabled
				}
			};
			object._products = object._products || {};
			object._products[thisProductId] = thisProduct;
			object.getInstalledProducts = function() {
				var products = [];
				for (var productId in object._products) {
					products.push(object._products[productId]);
				}
				return products;
			};
			object.initProductInfoProvider = function (signedProductInfoProvider) {
				delete object.initProductInfoProvider;
				object._products2 = object._products2 || {};
				object._products2[thisProductId] = signedProductInfoProvider;
				object.getInstalledProducts2 = function (challenge, timeoutMs, callback) {
					for (var productId in object._products2) {
						object._products2[productId](challenge, timeoutMs, callback);
					}
				};
			};
			return object;
		})(window.KasperskyLab || {});
		window.KasperskyLab.initProductInfoProvider(function(challenge, timeoutMs, callback){
			m_signRequest[challenge] = callback;
			m_callFunction('cb.signedProductInfo', [challenge, timeoutMs],
				function (result) {
					// check eka::sOk
					if (result != 0) {
						m_signRequest[challenge] = null;
					}
				},
				function (e) {
					OnError(e);
					m_deactivateFunction('cb');
				});                                   
		});
	}
};
try
{
    new ContentBlocker();
    if (window.dispatchEvent) {
        window.dispatchEvent(new CustomEvent("cb.ready"));
    }
}
catch(e)
{
    session.Log('ContentBlocker exception ' + (e.message || e));
}
});
(function (ns) {
/**
 *  @private
 *  @final
 *  @constructor
 *  @struct
 */
ns.UrlAdvisorBalloon = function (locales)
{
	/** 
	 *  @const
	 *  @type {Array<{name:string,bit:number}>}
	 */
	var threatTypes = [
		{name:'Unknown', bit:-1},
		{name:locales["PhishingName"], bit:62},
		{name:locales["MalwareName"], bit:63}
	];
	
	/** 
	 *  @const
	 *  @type {Array<{headerClass:string,headerNode:string,textNode:string,marker:string}>}
	 */
	var ratingIds = [
		{headerClass:'kl_header green', headerNode:locales["UrlAdvisorBalloonHeaderGood"], textNode : locales["UrlAdvisorSetLocalContentOnlineGood"], marker:'kl_marker allow'},
		{headerClass:'kl_header grey', headerNode:locales["UrlAdvisorBalloonHeaderSuspicious"], textNode:locales["UrlAdvisorSetLocalContentOnlineSuspicious"], marker:'kl_marker unknown'},
		{headerClass:'kl_header red', headerNode:locales["UrlAdvisorBalloonHeaderDanger"], textNode:locales["UrlAdvisorSetLocalContentOnlineDanger"], marker:'kl_marker disallow'}
	];
	/**
	 *  @private
	 *  @param {string} imageName
	 */
	function GetImageSrc(imageName)
	{
		return ns.GetResourceSrc('/ua/' + imageName);
	}
	/**
	 *  @private
	 */
	function AddStyles()
	{
		ns.AddStyles([
			'.kisb * { position: relative; display:block; overflow-x:hidden; width: auto; margin:0; padding:0; font-family: Verdana; line-height: 150%; text-indent:0; border:0; box-sizing:content-box; color:#000000; letter-spacing: normal; ' + locales["RtlStyle"] + '}',
			'.kisb { z-index:2147483647; width: 280px; cursor:default; display:block;}',
			'.kisb .kl_header { padding:27px 26px 10px 26px;  }',
			'.kisb .kl_header.red { background-image:url(' + GetImageSrc('header_red.png') + ');}',
			'.kisb .kl_header.grey { background-image:url(' + GetImageSrc('header_grey.png') + ');}',
			'.kisb .kl_header.green { background-image:url(' + GetImageSrc('header_green.png') + ');}',
			'.kisb .kl_content { background: url(' + GetImageSrc('content.png') + ') repeat-y top left; padding:10px 26px 10px 26px;}',
			'.kisb .kl_content .block { width: 228px!important; }',
			'.kisb .kl_marker { margin-top: 5px; margin-bottom:10px; padding-top:2px; padding-left:25px; background-position-x: 0; background-position-y: 0; background-repeat: no-repeat; word-wrap: break-word;}',
			'.kisb .kl_marker.allow { background-image: url( ' + GetImageSrc('allow.png') + ')}',
			'.kisb .kl_marker.disallow { background-image: url(' + GetImageSrc('disallow.png') + ')}',
			'.kisb .kl_marker.unknown { background-image: url(' + GetImageSrc('unknown.png') + ')}',
			'.kisb .kl_tag { display:inline-block; background: left top url(' + GetImageSrc('tag.png') + ') no-repeat; padding-left:12px; padding-right:5px; margin-right:5px; margin-bottom:5px; font-size: 7.5pt;}',
			'.kisb .kl_external { margin-top: 15px; padding-top:2px; padding-left:20px; background-position-x: left; background-position-y: top; background-repeat: no-repeat;}',
			'.kisb .kl_external { background-image: url(' + GetImageSrc('external.png') + ')}',
			'.kisb .kl_footer { background: url(' + GetImageSrc('footer.png') + ') no-repeat bottom left; padding:6px 26px 22px 26px;}',
			'.kisb .kl_content * { font-size:8pt; }',
			'.kisb a { text-decoration: underline; display:inline-block; }',
			'.kisb a:hover { text-decoration: none; }',
			'.kisb a, .kisb a:link, .kisb a:hover, .kisb a:visited { color: #008ccc;}',
			'.kisb .kl_header { font-size:12pt; color: #ffffff;  }',
			'.kisb .kl_footer a { font-size:8pt; color: #4d4d4d; text-decoration:underline; }'
		]);
	}
	
	/**
	 *  @private
	 *  @param {{high:number,low:number}} bigInt
	 */
	function FixBigInt(bigInt)
	{
		if (bigInt.low >= 10000000000)
		{
			var addedHigh = Math.floor(bigInt.low / 10000000000);
			bigInt.low = bigInt.low % 10000000000;
			bigInt.high += addedHigh;
		}
	}
	
	/**
	 *  @private
	 *  @param {{high:number,low:number}} bigInt
	 *  @return {string}
	 */
	function BigIntToString(bigInt)
	{
		/** type {string} */var result = '';
		if (bigInt.high)
		{
			result += bigInt.high;
			for (var /** type {number} */i = bigInt.low.toString().length; i < 10; ++i)
				result += '0';
		}
		result += bigInt.low;
		return result;
	}
	
	/**
	 *  @private
	 *  @param {number} bit
	 *  @return {{high:number,low:number}}
	 */
	function GetMask(bit)
	{
		if (bit < 0 || bit >= 64)
			return {high: 0, low: 0};
		/**
		 *  @type {{high:number,low:number}}
		 */
		var mask = {
			high: 0,
			low: Math.pow(2, Math.min(50, bit))
		};
		FixBigInt(mask);
		
		if (bit > 50)
		{
			mask.low *= Math.pow(2, bit - 50);
			mask.high *= Math.pow(2, bit - 50);
			FixBigInt(mask);
		}
		return mask;
	}
	
	/**
	 *  @private
	 *  @param {Array<number>} threats
	 *  @param {Array<number>} categories
	 *  @return {string}
	 */
	function GetCategoriesMask(threats, categories)
	{
		/** @type {{high:number,low:number}}*/var mask = {high: 0, low: 0};
		/** @type Array<number> */var bits = [];
		var i, count;
		if (threats)
			for (i = 0, count = threats.length; i < count; ++i)
				bits.push(threatTypes[threats[i]].bit);
		if (categories)
			for (i = 0, count = categories.length; i < count; ++i)
				bits.push(categories[i] - 1);
		for (i = 0, count = bits.length; i < count; ++i)
		{
			/** 
			 *  @const
			 *  @type {{high:number,low:number}}
			 */
			var addingMask = GetMask(bits[i]);
			mask.high += addingMask.high;
			mask.low += addingMask.low;
			FixBigInt(mask);
		}
		return BigIntToString(mask);
	}
	
	/**
	 *  @private
	 *  @param {number} threat
	 *  @return {string}
	 */
	function ConvertThreat(threat)
	{
		return threatTypes[threat].name;
	}
	/**
	 *  @private
	 *  @param {number} category
	 *  @return {string}
	 */
	function ConvertCategory(category)
	{
		return locales["CAT_" + category];
	}
    /**
     *  @private
     *  @param {Node} parentElement
     *  @param {Array<number>} list
     *  @param {function(number):string} converter
     */
	function AddTagsFromList(parentElement, list, converter)
	{
		if (!list)
			return;
		for (var i = 0, count = list.length; i < count; ++i)
		{
			/**
			 *  @const
			 *  @type {Element}
			 */
			var spanElement = document.createElement('span');
			spanElement.className = 'kl_tag';
			spanElement.appendChild(document.createTextNode(converter(list[i])));
			parentElement.appendChild(spanElement);
		}
	}
	
	/**
	 *  @private
	 *  @param {Element} parentElement
	 *  @param {{categories:Array<number>,threats:Array<number>}} verdict
	 */
	function AddVerdictTags(parentElement, verdict)
	{
		if ((!verdict.categories || verdict.categories.length == 0) && (!verdict.threats || verdict.threats.length == 0))
			return;
		parentElement.appendChild(document.createElement('br'));
		parentElement.appendChild(document.createElement('br'));
		parentElement.appendChild(document.createTextNode(locales["UrlAdvisorDescribeCategories"] + ": "));
		
		/**
		 *  @const
		 *  @type {Node}
		 */
		var divElement = parentElement.appendChild(document.createElement('div'));
		AddTagsFromList(divElement, verdict.categories, ConvertCategory);
		AddTagsFromList(divElement, verdict.threats, ConvertThreat);
	}
	
	/**
	 *  @private
	 *  @param {Element} element
	 */
	function RemoveAllChilds(element)
	{
		while (element.childNodes.length > 0)
			element.removeChild(element.childNodes[0]);
	}
	
	/**
	 *  @private
	 *  @param {{url:string, rating:number, threats:Array<number>, categories:Array<number>}} verdict
	 *  @param {string} additionalInfoLink
	 *  @param {string} termsLink
	 */
	function UpdateBalloon(verdict, additionalInfoLink, termsLink)
	{
		/** @type {Element}*/var headerElement = document.getElementById('balloon_header');
		/** @type {Element}*/var contentElement = document.getElementById('balloon_content');
		/** @type {Element}*/var markerElement = document.getElementById('balloon_marker');
		/** @type {Element}*/var tagElement = document.getElementById('balloon_tags');
		/** @type {Element}*/var externalElement = document.getElementById('balloon_external');
		/** @type {Element}*/var termsElement = document.getElementById('balloon_terms');
		RemoveAllChilds(headerElement);
		RemoveAllChilds(contentElement);
		RemoveAllChilds(markerElement);
		RemoveAllChilds(tagElement);
		headerElement.className = ratingIds[verdict.rating-1].headerClass;
		headerElement.appendChild(document.createTextNode(ratingIds[verdict.rating-1].headerNode));
		contentElement
			.appendChild(document.createElement('b'))
			.appendChild(document.createTextNode(ratingIds[verdict.rating-1].textNode));
		markerElement.className = ratingIds[verdict.rating-1].marker;
		markerElement.appendChild(document.createTextNode(verdict.url));
		AddVerdictTags(tagElement, verdict);
		externalElement.href = additionalInfoLink + '&act-exturl=' + encodeURIComponent(verdict.url) + '&act-threat-cat=' + (verdict.rating - 1) + '&act-content-cat=' + GetCategoriesMask(verdict.threats, verdict.categories) + '&rpe=1';
		termsElement.href = termsLink;
	}
	
	/**
	 *  @private
	 */
	function CheckMouseOverBalloon(mouseArgs)
	{
		if (m_balloon)
		{
			/**@const @struct*/var args = mouseArgs || window.event;
			/**@const @struct*/var rect = m_balloon.getBoundingClientRect();
			if (args.clientX > rect.left &&
				args.clientX < rect.right &&
				args.clientY > rect.top &&
				args.clientY < rect.bottom)
			{
				return;
			}
			HideBalloon();
		}
	}
	/**
	 *  @private
	 *  @param {Element} balloonDiv
	 */
	function CreateHeaderDiv(balloonDiv)
	{
		/** @const @struct*/var headerDiv = document.createElement('div');
		headerDiv.id = 'balloon_header';
		
		balloonDiv.appendChild(headerDiv);
	}
	
	/**
	 *  @private
	 *  @param {Element} balloonDiv
	 */
	function CreateContentDiv(balloonDiv)
	{
		/** @const @type {Element}*/var contentDiv = document.createElement('div');
		contentDiv.className = 'kl_content';
		/** @const @type {Element}*/var blockDiv = document.createElement('div');
		blockDiv.className = 'block';
		contentDiv.appendChild(blockDiv);
		/** @const @type {Element}*/var contentTypeDiv = document.createElement('div');
		contentTypeDiv.className = 'block';
		contentTypeDiv.id = 'balloon_content';
		blockDiv.appendChild(contentTypeDiv);
		/** @const @type {Element}*/var markerDiv = document.createElement('div');
		markerDiv.className = 'kl_marker allow';
		markerDiv.id = 'balloon_marker';
		blockDiv.appendChild(markerDiv);
		/** @const @type {Element}*/var tagsDiv = document.createElement('div');
		tagsDiv.id = 'balloon_tags';
		blockDiv.appendChild(tagsDiv);
		/** @const @type {Element}*/var infoLink = document.createElement('a');
		infoLink.href = '#';
		infoLink.id = 'balloon_external';
		infoLink.className = 'kl_external';
		infoLink.target = '_blank';
		infoLink.appendChild(document.createTextNode(locales["UrlAdvisorSetLocalContentGotoForInfo"]));
		blockDiv.appendChild(infoLink);
		
		balloonDiv.appendChild(contentDiv);
	}
	
	/**
	 *  @private
	 *  @param {Element} balloonDiv
	 */
	function CreateFooterDiv(balloonDiv)
	{
		/** @const @type {Element}*/var footerDiv = document.createElement('div');
		footerDiv.className = 'kl_footer';
		footerDiv.id = 'balloon_footer';
		/** @const @type {Element}*/var termsLink = document.createElement('a');
		termsLink.id = 'balloon_terms';
		termsLink.target = '_blank';
		termsLink.appendChild(document.createTextNode(locales["UrlAdvisorSetLocalContentTermsOfUsage"]));
		// TODO: add terms onclick like in previous version
		footerDiv.appendChild(termsLink);
		
		balloonDiv.appendChild(footerDiv);
	}
	
	/**
	 *  @private
	 *  @return {Element}
	 */
	function CreateBalloon()
	{
		AddStyles();
	
		/** @const @type {Element}*/var balloonDiv = document.createElement('div');
		balloonDiv.className = 'kisb';
		balloonDiv.id = 'balloon_parent_div';
		balloonDiv.onmouseout = CheckMouseOverBalloon;
		
		CreateHeaderDiv(balloonDiv);
		CreateContentDiv(balloonDiv);
		CreateFooterDiv(balloonDiv);
		
		balloonDiv.style.visibility = 'hidden';
		document.body.appendChild(balloonDiv);
		return balloonDiv;
	}
	/**@struct*/var m_balloon = null;
	/**
	 *  @private
	 *  @param {Element} element
	 *  @return {{width: number, height: number}}
	 */
	function GetElementSize(element)
	{
		/**@const @struct*/var rect = element.getBoundingClientRect();
		/**@const @type{number}*/var width = rect.width ? rect.width : rect.right - rect.left;
		/**@const @type{number}*/var height = rect.height ? rect.height : rect.bottom - rect.top;
			
		return {width: width, height: height};
	}
	
	/**
	 *  @param {number} clientX
	 *  @param {number} clientY
	 *  @param {{url:string, rating:number, threats:Array<number>, categories:Array<number>}} verdict
	 *  @param {string} additionalInfoLink
	 *  @param {string} termsLink
	 */
	this.ShowBalloon = function(clientX, clientY, verdict, additionalInfoLink, termsLink)
	{
		m_balloon = document.getElementById('balloon_parent_div');
		if (!m_balloon)
			m_balloon = CreateBalloon();
		UpdateBalloon(verdict, additionalInfoLink, termsLink);
		
		/** @const @type{number}*/var clientWidth = ns.GetPageWidth();
		/** @const @type{{width: number, height: number}}*/var balloonSize = GetElementSize(m_balloon);
		/** @const @type{number}*/var halfWidth = balloonSize.width / 2;
		/** @type{number}*/var x;
		if (halfWidth > clientX)
			x = 0;
		else if (halfWidth + clientX > clientWidth)
			x = clientWidth - balloonSize.width;
		else
			x = clientX - halfWidth;
		
		/** @const @type{number}*/var clientHeight = ns.GetPageHeight();
		/** @type{number}*/var y = (clientY + balloonSize.height > clientHeight) ? clientY - balloonSize.height : clientY;
		if (y < 0)
			y = 0;
		/** @const @type{{top:number,left:number}}*/var scroll = ns.GetPageScroll();
		y += scroll.top;
		x += scroll.left;
		m_balloon.style.position = 'absolute';
		m_balloon.style.top = Math.round(y).toString() + 'px';
		m_balloon.style.left = Math.round(x).toString() + 'px';
		m_balloon.style.visibility = 'visible';
	}
	
	/**
	 *  @private
	 */
	function HideBalloon()
	{
		if (m_balloon)
			m_balloon.style.visibility = 'hidden';
	}
};
}) (KasperskyLab || {});
KasperskyLab.AddRunner("ua", function (ns, session, settings, locales) {
/**
 *  @private
 *  @final
 *  @constructor
 *  @struct
 */
var UrlAdvisor = function()
{
	/** @struct @const */var m_urlAdvisorBalloon = new ns.UrlAdvisorBalloon(locales);
	/** @type {boolean}*/var m_settingsEnabled = settings.enable;
	/** @type {boolean}*/var m_enabled = m_settingsEnabled && (settings.state === 'Enabled');
	/** @type {boolean}*/var m_checkOnlySearchResults = settings.mode;
	/** @type {string}*/var m_additionalInfoUrl = settings.infoUrl;
	/** @type {string}*/var m_termsUrl = settings.termsUrl;
	/** @type {boolean}*/var m_postponeCategorizeStarted = false;
	/** @type {number}*/var m_urlCategorizeRequestTime = 0;
	/** @const @type {string}*/var m_checkedAtributeName = 'kl_' + ns.GetCurrentTime();
	/** @const @type {string}*/var m_iconName = 'kl_' + ns.GetCurrentTime();
	var m_observer;
    
	
	var m_state = settings.state,
		m_callFunction;
	session.InitializePlugin(function(activatePlugin, registerMethod, callFunction){
		m_callFunction = callFunction;
		activatePlugin('ua', OnPing, OnError);
		registerMethod('ua.verdict', SetVerdict);
		registerMethod('ua.settings', SetSettings);
		registerMethod('ua.state', SetState);
	});
	Run();
	
	/**
	 * @private
	 * @param {number} currentTime
	 * @return {number}
	*/
	function OnPing(currentTime)
	{
		/**
		 *  @const
		 *  @type {number}
		 */
		var timeFormRequest = (currentTime >= m_urlCategorizeRequestTime) ? currentTime - m_urlCategorizeRequestTime : 0;
		return timeFormRequest <= 10000 ? 500 : ns.MaxRequestDelay;
	}
	/**
	 *  @private
	 *  @param {Object} e
	 */
	function OnError(e) {
		session.Log('ERR UA - ' + (e.message || e));
	}
	/**
	 *  @private
	 *  @return {string}
	 */
	function GetHref(link)
	{
		try	{ return link.href;	} catch(e){}
		try	{ return link.getAttribute('href');	} catch(e){}
		return '';
	}
	
	/**
	 *  @private
	 *  @param {Node} linkElement
	 *  @return {!boolean}
	 */
	function IsLinkHighlighted(linkElement)
	{
		/** @const @type {Node} */var nextElement = linkElement.nextSibling;
		return nextElement !== null && nextElement.name == m_iconName;
	}
	
	/**
	 *  @private
	 *  @param {Element} linkElement
	 *  @return {Node}
	 */
	function GetLinkIcon(linkElement)
	{
		if (!IsLinkHighlighted(linkElement))
		{
			/** @type {Element} */var icon = document.createElement('img');
			icon.name = m_iconName;
			icon.width = 12;
			icon.height = 12;
			linkElement.parentNode.insertBefore(icon, linkElement.nextSibling);
		}
		return linkElement.nextSibling;
	}
	
	/**
	 *  @private
	 *  @param {Node} icon
	 *  @param {{rating:number, url:string}} verdict
	 */
	function UpdateIconImage(icon, verdict)
	{
		if (verdict.rating === 1)
		{
			icon.src = ns.GetResourceSrc('/ua/UrlAdvisorGoodImage.png');
			icon['kis_status'] = 16;
		}
		else if (verdict.rating === 2)
		{
			icon.src = ns.GetResourceSrc('/ua/UrlAdvisorSuspiciousImage.png');
			icon['kis_status'] = 8;
		}
		else if (verdict.rating === 3)
		{
			icon.src = ns.GetResourceSrc('/ua/UrlAdvisorDangerImage.png');
			icon['kis_status'] = 4;
		}
	}
	
	/**
	 *  @private
	 *  @param {Node} icon
	 *  @param {{rating:number, url:string}} verdict
	 */
	function SubscribeIconOnMouseEvents(icon, verdict)
	{
		/** type {number} */var balloonTimerId = 0;
		icon.onmouseout = function()
		{
			if (balloonTimerId)
			{
				window.clearTimeout(balloonTimerId);
				balloonTimerId = 0;
			}
		};
		icon.onmouseover = function(mouseArgs)
		{
			if (!balloonTimerId)
			{
				/** @const @struct */var args = mouseArgs || window.event;
				balloonTimerId = window.setTimeout(function(/**number*/clientX, /**number*/clientY)
					{
						return function()
						{
							m_urlAdvisorBalloon.ShowBalloon(clientX, clientY, verdict, m_additionalInfoUrl, m_termsUrl);
						}
					}(args.clientX, args.clientY),
					300);
			}
		};
	}
	
	/**
	 *  @private
	 */
	function SetVerdict(argumentsList)
	{
		for (/**type {number}*/var currentVerdict = 0; currentVerdict < argumentsList.length; currentVerdict++)
		{
			/**
			 *  @const
			 *  @type {{rating:number, url:string}}
			 */
			var verdict = ns.JSONParse(argumentsList[currentVerdict]);
			for (/**type {number}*/var currentLinkIndex = 0; currentLinkIndex < document.links.length; currentLinkIndex++)
			{
				/**
				 *  @const
				 *  @type {!Element}
				 */
				var linkElement = document.links[currentLinkIndex];
				if (verdict.url === GetHref(linkElement) && (!m_checkOnlySearchResults || ns.IsLinkSearchResult(linkElement)))
				{
					/**
					 *  @const
					 *  @type {Node}
					 */
					var icon = GetLinkIcon(linkElement);
					if (!!icon)
					{
						UpdateIconImage(icon, verdict);
						SubscribeIconOnMouseEvents(icon, verdict);
					}
				}
			}
		}
	}
	/**
	 *  @private
	 */
	function SetSettingsImpl(argumentList)
	{
		if (argumentList.length > 0)
		{
			m_settingsEnabled = (argumentList[0] != '0');
			m_enabled = m_settingsEnabled && (m_state == 'Enabled');
	 	}
		if (!m_enabled)
			return;
		m_checkOnlySearchResults = !!(argumentList.length > 1 && argumentList[1] == 1);
		
		if (argumentList.length > 2)
			m_termsUrl = argumentList[2];
			
		if (argumentList.length > 3)
			m_additionalInfoUrl = argumentList[3];
	}
	/**
	 *  @private
	 */
	function ClearImages()
	{
		/**
		 *  @const
		 *  @type {NodeList}
		 */
		var images = document.getElementsByName(m_iconName);
		while (images.length > 0)
			images[0].parentNode.removeChild(images[0]);
	}	
	
	/**
	 *  @private
	 */
	function SetSettings(argumentList)
	{
		ClearImages();
		SetSettingsImpl(argumentList);
		CategorizeUrl();
	}
	/**
	 *  @private
	 *  @param {Array<string>} argumentList
	 */
	function SetState(argumentList)
	{
		if (argumentList.length > 0)
		{
			ClearImages();	
			m_state = argumentList[0];
			m_enabled = m_settingsEnabled && (m_state == 'Enabled');
			CategorizeUrl();
		}
	}
	/**
	 * @private
	 * @param {Element} linkElement
	 * @return {!boolean}
	 */
	function IsNeedCategorizeLink(linkElement)
	{
		try
		{
			return !linkElement.isContentEditable && !!linkElement.parentNode && !IsLinkHighlighted(linkElement) &&
				(!m_checkOnlySearchResults || ns.IsLinkSearchResult(linkElement)) &&
				linkElement.id !== 'balloon_external' &&
				linkElement.id !== 'balloon_terms';
		}
		catch(e)
		{
			session.Log('check link exception: ' + (e.message || e));
			return false;
		}
	}
	/**
	 *  @private
	 */
	function ProcessDomChange()
	{
		if (!m_postponeCategorizeStarted)
		{
			setTimeout(CategorizeUrl, 500);
			m_postponeCategorizeStarted = true;
		}
		
		var images = document.getElementsByName(m_iconName);
		for (var i = 0; i < images.length; ++i)
		{
			var linkNode = images[i].previousSibling;
			if (!linkNode || !linkNode.nodeName || linkNode.nodeName.toLowerCase() !== "a")
			{
				var imageNode = images[i];
				imageNode.parentNode.removeChild(imageNode);
			}
		}
	}
	
	/**
	 *  @private
	 */
	function CategorizeUrl()
	{
		if (!m_enabled)
		{
			session.Log('skip categorize links because UA disabled');
			return;
		}
			
		m_postponeCategorizeStarted = false;
		var linksForCategorize = [];
		
		try
		{
			for (var i = 0; i < document.links.length; i++)
			{
				/** @const @type {Element} */var link = document.links[i];
				if (IsNeedCategorizeLink(link))
				{
					link[m_checkedAtributeName] = true; 
					/** @const @type {string} */var href = GetHref(link);
					if (!!href) {
						linksForCategorize.push(href); 
					} else {
						ns.Log('access to href blocked by browser'); 
					}
				}
			}
		}
		catch(e)
		{
			session.Log('find links exception: ' + (e.message || e));
		}
		
		if (linksForCategorize.length)
		{
			m_callFunction("ua.categorize", linksForCategorize, null, OnError);
			m_urlCategorizeRequestTime = ns.GetCurrentTime();
		}
		else
		{
			session.Log('UA not found links for categorization');
		}
	}
	/**
	 *  @private
	 */
	function Run()
	{
		CategorizeUrl();
		m_observer = ns.GetDomChangeObserver("a");
		m_observer.Start(ProcessDomChange);
		ns.AddEventListener(window, "unload", 
			function()
			{
				if (m_observer)
					m_observer.Stop();
			});
	};
};
/** type {UrlAdvisor} */var instance = null;
function RunUrlAdvisor() {
	try
	{
		if (!instance) {
			instance = new UrlAdvisor();
		}
	}
	catch(e)
	{
		session.Log('UrlAdvisor exception ' + (e.message || e));
	}
}
if (document.readyState === "loading")
{
	if (document.addEventListener)
	{
		document.addEventListener('DOMContentLoaded', RunUrlAdvisor, true);
	}
	else if (document.all)
	{
		document.write("<script type=\"text/javascript\" id=\"DeferLoadTagName\" defer=\"defer\" src=\"javascript:void(0)\"><\/script>");
		/** @const @struct */var contentloadtag = document.getElementById("DeferLoadTagName");
		contentloadtag.onreadystatechange = function(){
			if (this.readyState=="complete")
					RunUrlAdvisor();
			};
	}
}
else
{
	RunUrlAdvisor();
}
});

 })();

 })();