var drex_node_times;
var drex_node_links;
var drex_node_names;
var vjwTutorial = false;
var lastSelectIndex = 1;
var position = 0;

function timedCount() {
	var t = setTimeout("timedCount()", 500);
	position = jwplayer().getPosition();
	for (var i = 1; i < drex_node_times.length; i++) {
		if (position < drex_node_times[i]) continue;
		var next = drex_node_times.length;
		for (var j = i + 1; j < drex_node_times.length; j++) {
			if (drex_node_times[j] == drex_node_times[i]) continue;
			next = j;
			break;
		}
		if (next == drex_node_times.length || position < drex_node_times[next]) {
			if (lastSelectIndex != i) {
				lastSelectIndex = i;
				var app = SAN_WHOLE;
				app.navTree_Menu.init();
				if (app.tabController.isMenuTabShown()) app.navTree_Menu.show();
			}
			break;
		}
	}
}

function equalString(str1, str2) {
	if (str1.length != str2.length) return false;
	if (str1.length == 0 && str2.length == 0) return true;
	str1 = str1.toLowerCase();
	str2 = str2.toLowerCase();
	var match = true;
	for (var i = 0; i < str1.length; i++) {
		if (str1[i] == str2[i]) continue;
		if (str1[i] == '_' || str2[i] == '_') {
			var ch = str1[i] == '_' ? str2[i] : str1[i];
			if (ch == ':' || ch == ',') continue;
		}
		if (str1[i] == '-' || str2[i] == '-') {
			var ch = str1[i] == '-' ? str2[i] : str1[i];
			if (ch == ' ' || ch == ',') continue;
		}
		match = false;
		break;
	}
	return match;
}

function getMainTimeIndex(time) {
	for (var i = 1; i < drex_node_times.length; i++) {
		if (drex_node_times[i] == time) return i;
	}
	return 0;
}

function getPageIndex(pagename) {
	for (var i = 1; i < drex_node_links.length; i++) {
		if (equalString(pagename, drex_node_links[i])) return i;
	}
	var str1 = pagename.substring(0, pagename.length - 5);
	for (var i = 1; i < drex_node_names.length; i++) {
		if (!equalString(str1, drex_node_names[i])) continue;
		var index = getMainTimeIndex(drex_node_times[i]);
		if (index > 0) return index;
	}
	return 0;
}

function initMenuTime() {
	vjwTutorial = (window['drex_file_type'] !== undefined && window.drex_file_type == "vomedia");
	for (var i in drex_node_names) {
		drex_node_times[i] = -1;
		var n1 = drex_node_links[i].indexOf("-");
		var n2 = drex_node_links[i].indexOf("_");
		if (n1 == 5 && n2 == 2) {
			var v1 = parseInt(drex_node_links[i].substring(0, 2));
			var v2 = parseInt(drex_node_links[i].substring(3, 5));
			var v3 = v1 * 60 + v2;
			if (v3 == 0 && i > 1) drex_node_times[i] = drex_node_times[i - 1];
			else drex_node_times[i] = v3;
		} else if (i > 1) drex_node_times[i] = drex_node_times[i - 1];
	}
	if (vjwTutorial) timedCount();
}
SAN_WHOLE.namespace('SAN_WHOLE.dataManager');
SAN_WHOLE.dataManager = (function () {
	var data_resize = SAN_WHOLE.data_resize;
	var data_search = SAN_WHOLE.data_search;
	var data_menu = SAN_WHOLE.data_menu;
	drex_node_names = data_menu.DREX_NODE_NAMES;
	drex_node_links = data_menu.DREX_NODE_LINKS;
	drex_node_paths = data_menu.DREX_NODE_PATHS;
	drex_node_times = new Array(data_menu.DREX_NODE_LINKS.length);
	var drex_node_child_start = data_menu.DREX_NODE_CHILD_START;
	var drex_node_child_end = data_menu.DREX_NODE_CHILD_END;
	var drex_node_parent = new Array();
	var drex_node_deep = new Array();
	var drex = {};

	function drex_node(ndx) {
		this.node_index = ndx;
		this.title = drex_node_names[this.node_index];
		this.link = drex_node_links[this.node_index];
		this.deep = drex_node_deep[this.node_index];
		this.children = function () {
			var result = new Array();
			for (var i = drex_node_child_start[this.node_index]; i < drex_node_child_end[this.node_index]; i++)
				result.push(new drex_node(i));
			return result;
		};
		this.childrenCount = function () {
			if (drex_node_child_start[this.node_index] >= drex_node_child_end[this.node_index])
				return 0;
			return drex_node_child_end[this.node_index] - drex_node_child_start[this.node_index];
		};
		this.parent = function () {
			if (drex_node_parent[this.node_index] == -1)
				return null;
			return new drex_node(drex_node_parent[this.node_index]);
		};
		this.isActive = function () {
			if (!drex.active_node)
				return false;
			return (this.node_index == drex.active_node.node_index);
		};
	};
	var initMenu = function () {
		initMenuTime();
		drex_node_parent[0] = -1;
		drex_node_deep[0] = 0;
		for (var i in drex_node_names) {
			for (var j = drex_node_child_start[i]; j < drex_node_child_end[i]; j++) {
				drex_node_parent[j] = i;
				drex_node_deep[j] = drex_node_deep[i] + 1;
			}
		}
		drex = new Object();
		drex.nodes_count = drex_node_names.length;
		drex.root_node = function () {
			return new drex_node(0);
		};
		drex.active_node = null;
		for (var i in drex_node_links) {
			if (drex_node_links[i] == getPageFilename())
				drex.active_node = new drex_node(i);
		}

		function drex_resultContainer() {
			this.result = "";
		}
	};

	function drex_keyword(ndx) {
		this.keyword_index = ndx;
		this.title = drex_keyword_names[this.keyword_index];
		this.deep = drex_keyword_deep[this.keyword_index];
		this.children = function () {
			var result = new Array();
			for (var i = drex_keyword_child_start[this.keyword_index]; i < drex_keyword_child_end[this.keyword_index]; i++)
				result.push(new drex_keyword(i));
			return result;
		};
		this.childrenSorted = function () {
			var result = this.children();
			result.sort(function (a, b) {
				if (a.title < b.title)
					return -1;
				if (a.title > b.title)
					return 1;
				return 0;
			});
			return result;
		};
		this.childrenCount = function () {
			if (drex_keyword_child_start[this.keyword_index] >= drex_keyword_child_end[this.keyword_index])
				return 0;
			return drex_keyword_child_start[this.keyword_index] - drex_keyword_child_end[this.keyword_index];
		}
		this.parent = function () {
			if (drex_keyword_parent[this.keyword_index] == -1)
				return null;
			return new drex_keyword(drex_keyword_parent[this.keyword_index]);
		};
		this.nodes = function () {
			var result = new Array();
			for (var i = drex_keyword_nodes_start[this.keyword_index]; i < drex_keyword_nodes_end[this.keyword_index]; i++)
				result.push(new drex_node(drex_keyword_nodes[i]));
			return result;
		};
		this.isActive = function () {
			return this.keyword_index != 0;
		};
	};
	var data_index = SAN_WHOLE.data_index;
	var drex_node_keywords = data_index.DREX_NODE_KEYWORDS;
	var drex_node_keywords_start = data_index.DREX_NODE_KEYWORDS_START;
	var drex_node_keywords_end = data_index.DREX_NODE_KEYWORDS_END;
	var drex_keyword_names = data_index.DREX_KEYWORD_NAMES;
	var drex_keyword_child_start = data_index.DREX_KEYWORD_CHILD_START;
	var drex_keyword_child_end = data_index.DREX_KEYWORD_CHILD_END;
	var drex_keyword_parent = new Array();
	var drex_keyword_deep = new Array();
	var drex_keyword_nodes = new Array(drex_node_keywords.length);
	var drex_keyword_nodes_start = new Array(drex_keyword_names.length);
	var drex_keyword_nodes_end = new Array(drex_keyword_names.length);
	var initIndex = function () {
		//keyword tree structure
		drex_keyword_parent[0] = -1;
		drex_keyword_deep[0] = 0;
		for (var i in drex_keyword_names) {
			for (var j = drex_keyword_child_start[i]; j < drex_keyword_child_end[i]; j++) {
				drex_keyword_parent[j] = i;
				drex_keyword_deep[j] = drex_keyword_deep[i] + 1;
			}
		}
		drex.keywords_count = drex_keyword_names.length;
		//making drex_keyword_nodes from drex_node_keywords
		var temp_drex_keyword_write_pos = new Array(drex.keywords_count + 1);
		for (var i = 0; i < temp_drex_keyword_write_pos.length; i++)
			temp_drex_keyword_write_pos[i] = 0;
		for (var i in drex_node_keywords)
			++temp_drex_keyword_write_pos[drex_node_keywords[i] + 1];
		for (var i = 1; i < temp_drex_keyword_write_pos.length; i++)
			temp_drex_keyword_write_pos[i] += temp_drex_keyword_write_pos[i - 1];
		for (var i = 0; i < drex.keywords_count; i++)
			drex_keyword_nodes_start[i] = temp_drex_keyword_write_pos[i];
		for (var i = 0; i < drex.nodes_count; i++)
			for (var j = drex_node_keywords_start[i]; j < drex_node_keywords_end[i]; j++) {
				var kw = drex_node_keywords[j];
				drex_keyword_nodes[temp_drex_keyword_write_pos[kw]] = i;
				++temp_drex_keyword_write_pos[kw];
			}
		for (var i = 0; i < drex.keywords_count; i++)
			drex_keyword_nodes_end[i] = temp_drex_keyword_write_pos[i];
		drex_node.prototype.keywords = function () {
			var result = new Array();
			for (var i = drex_node_keywords_start[this.node_index]; i < drex_node_keywords_end[this.node_index]; i++)
				result.push(new drex_keyword(drex_node_keywords[i]));
			return result;
		};
		//interface
		drex.root_keyword = function () {
			return new drex_keyword(0);
		};
	};
	var getPageFilename = function () {
		if (window['drex_file_name'] !== undefined) {
			return window.drex_file_name;
		} else {
			return null;
		}
	};
	var API = {
		init: function () {
			initMenu();
			initIndex();
		},
		isFrameModeEnabled: function () {
			if (data_resize.SANWHOLE_FIT_HEIGHT_TO_WINDOW === 1) {
				return true;
			} else {
				return false;
			}
		},
		getStartingMenuWidth: function () {
			return parseInt(data_resize.DREX_INITIAL_MENU_WIDTH);
		},
		getSearchTextNoResults: function () {
			return data_search.SANWHOLE_NOT_FOUND;
		},

		getSearchTextInPreviewMode: function () {
			return data_search.SANWHOLE_PREVIEW_MODE_SEARCH_IS_DISABLED_NOTICE;
		},

		getErrorInLocalSearch: function () {
			return data_search.SANWHOLE_ERROR_LOCAL_SEARCH;
		},
		getSearchTextEmptyString: function () {
			return data_search.SANWHOLE_EMPTY_STRING;
		},
		getSearchTextInProgress: function () {
			return data_search.SANWHOLE_IN_PROGRESS;
		},
		getPageFilename: function () {
			return getPageFilename();
		},
		//drex.nodes_count
		getNodesCount: function () {
			return drex.nodes_count;
		},
		//drex.root_node()
		getRootNode: function () {
			return drex.root_node();
		},
		//drex.root_node()
		getRootNodesArray: function () {
			if (!data_menu.DREX_HAS_ROOT_NODE)
				return drex.root_node().children();
			return [drex.root_node()];
		},
		//drex.active_node
		getSelectedNode: function () {
			return drex.active_node;
		},
		//!drex.active_node
		isSelectedNodeExists: function () {
			if (!drex.active_node) {
				return false;
			} else {
				return true;
			}
		},
		//function drex_node(ndx)
		createNodeClassByIndex: function (nodeIndex) {
			return new drex_node(nodeIndex);
		},
		getNodeDeepByIndex: function (nodeIndex) {
			return drex_node_deep[nodeIndex];
		},
		getIndexByNode: function (node) {
			return node.node_index;
		},
		getDrex: function () {
			return drex;
		},
		getDrexNode: function (ndx) {
			return drex_node(ndx);
		},

		getDrexMenuType: function () {
			return data_menu.DREX_MENU_TYPE;
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.dom');
SAN_WHOLE.dom = {
	PAGE_CONTENT_HEADER__HIDDEN_CLASS: "m-pageContent__withoutHeader",
	PAGE_CONTENT_FOOTER__HIDDEN_CLASS: "m-pageContent__withoutFooter",
	PAGE_CONTENT_LEFT__HIDDEN_CLASS: "m-pageContent__withoutRight",
	PAGE_CONTENT_RIGHT__HIDDEN_CLASS: "m-pageContent__withoutLeft",
	TAB_WRAPPER_ITEM__SELECTED_CLASS: "m-tabs__wrapperItem__selected",
	TAB_SELECTOR_ITEM__SELECTED_CLASS: "m-tabs__selectorItem__selected",
	FRAME_ENABLED_CLASS: "m-pageView__state__frame",
	_isIeLessThan9: null,
	_isIe: null,
	init: function () {
		this.$html = $("html");
		this.$body = $("body");
		this.$internal_wrapper = $("#internal_wrapper");
		this.$pageContent = $("#pageContent");
		this.$pageContentHeader = $("#pageContentHeader");
		this.$pageContentFooter = $("#pageContentFooter");
		this.$pageContentArticleSide = $("#pageContentArticleSide");
		this.$pageContentLeft = $("#pageContentLeft");
		this.$pageContentRight = $("#pageContentRight");
		this.$tabWrapperItems = $("#tabWrapperItems");
		this.$article = $("#article");
		this.$articleHeader = $("#article__header");
		this.$articlePreWrapper = this.$article.children(".b-article__preWrapper");
		this.$articleWrapper = this.$article.find(".b-article__wrapper");
		this.$articleInnerWrapper = this.$article.find(".b-article__innerWrapper");
		this.$articleGeneratorCopyright = this.$article.find(".b-article__generatorCopyright");
		this.$headerSide__nav = $("#headerSide__nav");
		this.$headerSide__nav__breadCrumbs = $("#headerSide__nav__breadCrumbs");
		this.$headerSide__buttons = $("#headerSide__buttons");

		this.$splitter = $("#splitter");
		this.$workZone = $("#workZone");
		this.$workZoneSideNav = $("#workZone_nav");
		this.$workZoneSideNavContent = $("#workZone_nav_content");
		this.$workZoneSideArticle = $("#workZone_article");
		this.$workZoneSideArticleContent = $("#workZone_article__content");
		this.$tabsWrapperItems = $("#tabsWrapperItems");
		this.tabs = {};
		this.tabs.menu = {};
		this.tabs.menu.$selectorItem = $("#tabSelector_menu");
		this.tabs.menu.$wrapperItem = $("#tabWrapper_menu");
		this.tabs.menu.$wrapperItemInner = this.tabs.menu.$wrapperItem.children(".b-tabs__wrapperItemInner");
		this.tabs.menu.$tree = this.tabs.menu.$wrapperItemInner.children(".b-tree");
		this.tabs.index = {};
		this.tabs.index.$selectorItem = $("#tabSelector_index");
		this.tabs.index.$wrapperItem = $("#tabWrapper_index");
		this.tabs.index.$wrapperItemInner = this.tabs.index.$wrapperItem.children(".b-tabs__wrapperItemInner");
		this.tabs.index.$tree = this.tabs.index.$wrapperItemInner.children(".b-tree");
		this.tabs.search = {};
		this.tabs.search.$selectorItem = $("#tabSelector_search");
		this.tabs.search.$wrapperItem = $("#tabWrapper_search");
		this.tabs.search.$wrapperItemInner = this.tabs.search.$wrapperItem.children(".b-tabs__wrapperItemInner");
		this.tabs.search.$tree = this.tabs.search.$wrapperItemInner.children(".b-tree");

		this.$tabWrapperItemArr = this.tabs.menu.$wrapperItem.add(this.tabs.index.$wrapperItem).add(this.tabs.search.$wrapperItem);
		this.$tabWrapperItemInnerArr = this.tabs.menu.$wrapperItemInner.add(this.tabs.index.$wrapperItemInner).add(this.tabs.search.$wrapperItemInner);
		this.$treeArr = this.$tabWrapperItemInnerArr.find(".b-tree");
		this.$tabWrapperMenu = this.tabs.menu.$wrapperItem;
		this.$tabWrapperIndex = this.tabs.index.$wrapperItem;
		this.$tabWrapperSearch = this.tabs.search.$wrapperItem;
		this.$tabSelectorMenu = this.tabs.menu.$selectorItem;
		this.$tabSelectorIndex = this.tabs.index.$selectorItem;
		this.$tabSelectorSearch = this.tabs.search.$selectorItem;
		//
		this.$tabSearchFormWrapper = $("#tabs_searchFormWrapper");
		this.$tabSearchSubmit = $("#tabs_searchSubmit");
		this.$tabSearchInput = $("#tabs_searchInput");
		this.$tabSearchInputLabel = $("#tabs_searchInput_label");
		this.$workZoneSearchSubmit = $("#workZone_searchSubmit");
		this.$workZoneSearchInput = $("#workZone_searchInput");
		this.$workZoneSearchInputLabel = $("#workZone_searchInput_label");
		this.$keywordContextMenu = $("#keywordContextMenu");
		this.$searchProgress = $("#searchProgress");
		this.$hasVerticalScrollbar = {};
		this.$hasHorizontalScrollbar = {};

	},
	isIe: function () {
		if (this._isIe === null) {
			if (this.$html.hasClass("ie")) {
				this._isIe = true;
			} else {
				this._isIe = false;
			}
		}
		return this._isIeLessThan9;
	},
	isIeLessThan9: function () {
		if (this._isIeLessThan9 === null) {
			if (this.$html.hasClass("ie6") || this.$html.hasClass("ie7") || this.$html.hasClass("ie8")) {
				this._isIeLessThan9 = true;
			} else {
				this._isIeLessThan9 = false;
			}
		}
		return this._isIeLessThan9;
	},
	getVisibleTab: function () {
		if (this.isTabVisible(this.tabs.menu)) {
			return this.tabs.menu;
		} else if (this.isTabVisible(this.tabs.index)) {
			return this.tabs.index;
		} else if (this.isTabVisible(this.tabs.search)) {
			return this.tabs.search;
		} else {
			return null;
		}
	},
	getVisibleItemWrapperInner: function () {
		var visibleTab = this.getVisibleTab();
		if (visibleTab !== null) {
			return visibleTab.$wrapperItemInner;
		} else {
			return null;
		}
	},
	isTabVisible: function (tab) {
		if (tab.$wrapperItem.hasClass(this.TAB_WRAPPER_ITEM__SELECTED_CLASS)) {
			return true;
		} else {
			return false;
		}
	},
	isKeywordContextMenuVisible: function () {
		if (this.$keywordContextMenu.hasClass("m-tree__contextMenu__visible")) {
			return true;
		} else {
			return false;
		}
	},
	getCssNumericValue: function ($elem, cssProp) {
		return parseInt($elem.css(cssProp), 10);
	},
	isPageHeaderVisible: function () {
		if (this.$pageContent.hasClass(this.PAGE_CONTENT_HEADER__HIDDEN_CLASS)) {
			return false;
		} else {
			return true;
		}
	},
	isPageFooterVisible: function () {
		if (this.$pageContent.hasClass(this.PAGE_CONTENT_FOOTER__HIDDEN_CLASS)) {
			return false;
		} else {
			return true;
		}
	},
	isPageLeftVisible: function () {
		if (this.$pageContent.hasClass(this.PAGE_CONTENT_LEFT__HIDDEN_CLASS)) {
			return false;
		} else {
			return true;
		}
	},
	isPageRightVisible: function () {
		if (this.$pageContent.hasClass(this.PAGE_CONTENT_RIGHT__HIDDEN_CLASS)) {
			return false;
		} else {
			return true;
		}
	}
};
SAN_WHOLE.namespace('SAN_WHOLE.searchEngine');
SAN_WHOLE.searchEngine = (function () {
	function isLocalSearch() {
		var local = /file:/i;
		return local.test(dirname());
	}

	function setTag(tags, items, tag) {
		for (var i = 0; i < items.length; i++) {
			var item = items[i];
			if (tags.hasOwnProperty(item)) {
				tags[item] += tag;
			} else {
				tags[item] = tag;
			}
		}
	}

	function filter(tags, matchFunction) {
		var result = [];
		for (var p in tags) {
			if (matchFunction(tags[p])) {
				result.push(p);
			}
		}
		return result;
	}

	function intersect(setA, setB) {
		var tags = {};
		setTag(tags, setA, "A");
		setTag(tags, setB, "B");
		return filter(tags, function (value) {
			return value == "AB"
		});
	}

	function difference(setA, setB) {
		var tags = {};
		setTag(tags, setA, "A");
		setTag(tags, setB, "B");
		return filter(tags, function (value) {
			return value != "AB"
		});
	}

	function remove(setA, setB) {
		var tags = {};
		setTag(tags, setA, "A");
		setTag(tags, setB, "B");
		return filter(tags, function (value) {
			return value == "B"
		});
	}

	function unite(setA, setB) {
		var tags = {};
		setTag(tags, setA, "A");
		setTag(tags, setB, "B");
		return filter(tags, function (value) {
			return true;
		});
	}
	var IndexOfFiles = new Array();
	var StringsForSearch = new Array();
	var StringPairArray = new Array();
	var SearchResults = new Array();
	var strSearchLine = "";

	var iStringToSearch = 0;
	var HTTP = {};
	HTTP.newRequest = function () {
		var xmlhttp = false;;

		if (!xmlhttp) try {
			xmlhttp = new XMLHttpRequest();
		} catch (e) {
			xmlhttp = false;
		}

		if (typeof ActiveXObject != "undefined") {
			if (!xmlhttp) try {
				xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
			} catch (e) {
				xmlhttp = false;
			}
			if (!xmlhttp) try {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {
				xmlhttp = false;
			}
		}

		if (!xmlhttp) try {
			xmlhttp = createRequest();
		} catch (e) {
			xmlhttp = false;
		}
		if (!xmlhttp) {
			throw new Error("Failed to initialize XMLHttpRequest");
		}
		return xmlhttp;
	};
	var request = HTTP.newRequest();

	function ID() {
		if (!SearchResults.length) getSearchResultOutput();
		var sID = dirname() + "/SanwholeData/ids.txt";
		request.open("GET", sID, true);
		request.onreadystatechange = function () {
			if (request.readyState == 4)
				if (request.status == 200 || request.status == 0) {
					var arrFileId = (request.responseText).split(/\s*\n\s*/);
					var h;
					for (var i = 0; i < SearchResults.length; i++) {
						h = (SearchResults[i] - 1) * 3;
						SearchResults[i] = new Array();
						if (!arrFileId[h + 1] || !arrFileId[h + 2]) {
							if (!!arrFileId[h + 2]) {
								SearchResults[i][0] = arrFileId[h + 2];
								SearchResults[i][1] = arrFileId[h + 2];
							} else {
								if (!SearchResults[1])
									SearchResults[1] = new Array();
								SearchResults.length = 1;
								SearchResults[1][0] = "Error!";
								return;
							}
						} else {
							SearchResults[i][0] = arrFileId[h + 1];
							SearchResults[i][1] = arrFileId[h + 2];
						}
					}
					getSearchResultOutput();
				}
		}
		request.send(null);
	}

	function getSearchResultOutput() {
		$(document).trigger("searchComplete");
	}

	function SearchInFile() {
		if (request.readyState != 4) return;
		if (request.status != 200 && request.status != 0) return;
		var arrFileStrings = (request.responseText).split(/\s*;\s*/);
		var stToSearch = StringPairArray[iStringToSearch][0];
		var isFirstIteration = true;
		var wasFound = false;
		var curResults = new Array();
		for (var i = 0; i < arrFileStrings.length; i += 2) {
			if (arrFileStrings[i].indexOf(stToSearch) == 0) {
				var pages = arrFileStrings[i + 1];
				pages = pages.split(/\s*,\s*/);
				curResults = unite(curResults, pages);
				wasFound = true;
			}
		}
		if (iStringToSearch == 0) //this is first result - adding all curResults to SearchResults
			SearchResults = SearchResults.concat(curResults);
		else
			SearchResults = intersect(SearchResults, curResults);
		if (!SearchResults.length) return getSearchResultOutput();
		iStringToSearch++;
		SearchForNextString();
	}

	function SearchForNextString() {
		if (iStringToSearch >= StringsForSearch.length) return ID();
		var sURL = dirname() + "/SanwholeData/" + StringPairArray[iStringToSearch][1];
		request.open("GET", sURL, true);
		request.onreadystatechange = SearchInFile;
		request.send(null);
	}

	function strcmp(str1, str2) {
		//
		return ((str1 == str2) ? 0 : ((str1 > str2) ? 1 : -1));
	}

	function AttachFilesToStrings() {
		for (var i = 0; i < StringsForSearch.length; i++) {
			var st = StringsForSearch[i].toUpperCase();
			var st1 = st.substr(0, 1);
			var j = 0;
			var bFound = -1;
			while (j < IndexOfFiles.length && bFound == -1) {
				switch (strcmp(st1, IndexOfFiles[j].first.substr(0, 1))) {
					case 0:
						bFound = true;
						break;
					case -1:
						bFound = false;
						break;
					case 1:
						++j;
				}
			}
			if (bFound == -1 || bFound == false) {
				getSearchResultOutput();
				return;
			}
			//We have found words beginning with first letter of st
			bFound = false;
			switch (strcmp(st, IndexOfFiles[j].first)) {
				case -1: {
					if (IndexOfFiles[j].first.indexOf(st) == 0) //st = 'skin', IndexOfFiles[j].first = 'skinner'
						bFound = true;
					break;
				}
				case 0: {
					bFound = true;
					break;
				}
				case 1: //st = 'skinner', IndexOfFiles[j].first = 'skin'
				{
					switch (strcmp(st, IndexOfFiles[j].last)) {
						case -1:
						case 0: {
							bFound = true;
							break;
						}
						case 1: {
							if (st.indexOf(IndexOfFiles[j].last) == 0) //st = 'skinner', IndexOfFiles[j].last = 'skin'
								bFound = true;
							break;
						}
					}
				}
			}
			if (!bFound) {
				getSearchResultOutput();
				return;
			}
			//Replace strings for search with pairs (string,index file)
			StringPairArray[i] = new Array();
			StringPairArray[i][0] = st;
			StringPairArray[i][1] = IndexOfFiles[j].fileName;
		}
		SearchResults = new Array();
		iStringToSearch = 0;
		SearchForNextString();
	}
	//Downloads prefixes.txt
	//Fills IndexOfFiles array
	function GetIndex() {
		SearchResults = new Array();
		NextStringToSearch = 0; //?
		var sURL = dirname() + "/SanwholeData/prefixes.txt";
		request.open("GET", sURL);
		request.onreadystatechange = function () {
			if (request.readyState == 4)
				if (request.status == 200 || request.status == 0) {
					var arPrefixes = (request.responseText.toLowerCase()).split(/\s*;\s*/);
					var j = 0;
					SearchResults = new Array();
					var strsearch = strSearchLine.toLowerCase();
					for (var i = 0; i + 2 < arPrefixes.length; i += 3) {
						var n = arPrefixes[i + 2].indexOf(strsearch);
						if (n != -1) {
							SearchResults.push(new Array());
							SearchResults[j].push(arPrefixes[i + 0]);
							SearchResults[j].push(arPrefixes[i + 1]);
							SearchResults[j].push(arPrefixes[i + 2]);
							++j;
						}
					}
					getSearchResultOutput();

				}
		};
		request.send(null);
	}

	function dirname() {
		var retValue = window.location.href;
		retValue = retValue.substring(0, retValue.lastIndexOf('/'));
		var l = window['drex_file_path'];//N2201011758
		while (true) {
			var n = l.lastIndexOf('/');
			if (n == -1) break;
			l = l.substring(0, n);
			retValue = retValue.substring(0, retValue.lastIndexOf('/'));
		}
		return retValue;
	}

	function reverse(str) {
		if (!str) return str;
		return str.charAt(str.length - 1) + reverse(str.substring(0, str.length - 1));
	}

	function trimLeft(str) {
		for (var i = 0; str.charAt(i) == ' '; i++);
		return str.substring(i, str.length);
	}

	function trimRight(str) {
		return reverse(trimLeft(reverse(str)));
	}

	function trim(str) {
		return trimRight(trimLeft(str));
	}

	function isEmpty(sToCheck) {
		var sTest;
		sTest = trim(sToCheck)
		if (sTest == null || sTest == "") {
			return true;
		}
		return false;
	}

	function DoesNotOperaSupportLocalSearch() {
		var version = jQuery.browser.version || "0";
		var splitVersion = version.split('.');
		return $.browser.opera && ((parseInt(splitVersion[0]) > 12) || ((parseInt(splitVersion[0]) == 12) && (parseInt(splitVersion[1]) >= 2)))
	}

	function searchmain(str) {

		if (isLocalSearch() && ($.browser.chrome || DoesNotOperaSupportLocalSearch()))
			throw Error("LocalSearchNotSupportedInCurrentBrowser");
		$(document).trigger("searchBegin");
		SearchResults = new Array();
		iStringToSearch = 0;
		//Split the string into words
		strSearchLine = str;
		var strs = str.split(/\s/g);

		StringsForSearch = new Array();
		for (var i = 0; i < strs.length; ++i)
			if (!isEmpty(strs[i]))
				StringsForSearch.push(strs[i]);
		//Download index.txt asyncronously and fill array of indexes
		GetIndex();
		return 1;
	}
	var querySplitter = /\s+/;

	function max(a, b) {
		return a > b ? a : b;
	}

	function min(a, b) {
		return a < b ? a : b;
	}
	var API = {
		trim: function (str) {
			return trim(str);
		},
		doSearch: function (str) {
			return searchmain(str);
		},
		querySplitter: function () {
			return querySplitter;
		},
		getSearchResults: function () {
			return SearchResults;
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.searchManager');
SAN_WHOLE.searchManager = (function () {
	var _class = {
		elementsArr: null,
		isFirstSearch: true,
		dom: null,
		highlightManager: null,
		dataManager: null,
		urlEncoder: null,
		searchEngine: null,
		init: function () {
			this.doSetDom();
			this.doSetHighlightManager();
			this.doSetDataManager();
			this.doSetNavTreeSearch();
			this.doSetUrlEncoder();
			this.doSetSearchEngine();
			this.doSetSearchInProgressText();
		},
		doSetSearchInProgressText: function () {
			this.dom.$searchProgress.prop("alt", this.dataManager.getSearchTextInProgress());
		},
		doSetHighlightManager: function () {
			this.highlightManager = SAN_WHOLE.highlightManager;
		},
		doSetDataManager: function () {
			this.dataManager = SAN_WHOLE.dataManager;
		},
		doSearchIfQueryStringNotEmpty: function () {
			this.doSetQueryStringByUrlEncoder();
			if (this.elementsArr[0].$input.prop("value") !== '') {
				this.elementsArr[0].$submit.trigger("click");
			}
		},
		runCustomButtons: function () {
			var searchInWorkZone = new CustomButton(this.dom.$workZoneSearchSubmit);
			searchInWorkZone.run();
			var searchInTab = new CustomButton(this.dom.$tabSearchSubmit);
			searchInTab.run();
		},
		runInputPlaceholders: function () {
			var searchInTabPlaceholder = new InputPlaceholder(this.dom.$tabSearchInput, this.dom.$tabSearchInputLabel, true);
			searchInTabPlaceholder.run();
			var searchInWorkZonePlaceholder = new InputPlaceholder(this.dom.$workZoneSearchInput, this.dom.$workZoneSearchInputLabel, true);
			searchInWorkZonePlaceholder.run();
		},
		runInputSync: function () {
			var that = this;
			var $inputArr = this.dom.$tabSearchInput.add(this.dom.$workZoneSearchInput);
			var inputSync = new InputSync($inputArr);
			inputSync.run();
			this.dom.$workZoneSearchSubmit.on("click", function () {
				that.dom.$tabSelectorSearch.click();
			});
		},
		doSetNavTreeSearch: function () {
			this.navTreeSearch = SAN_WHOLE.navTree_Search;
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
			this.elementsArr = [{
					$input: this.dom.$tabSearchInput,
					$submit: this.dom.$tabSearchSubmit
				},
				{
					$input: this.dom.$workZoneSearchInput,
					$submit: this.dom.$workZoneSearchSubmit
				}
			];
		},
		doSetUrlEncoder: function () {
			var that = this;
			this.urlEncoder = SAN_WHOLE.urlEncoder;
			this.urlEncoder.addSaveFunc(
				function () {
					if (that.isSearchTabSelected()) {
						return that.getSearchQuery();
					} else {
						return "";
					}
				},
				this.urlEncoder.KEY_NAME__SEARCH_QUERY
			);
		},
		doSetSearchEngine: function () {
			this.searchEngine = SAN_WHOLE.searchEngine;
		},
		setUrlEncoder: function (urlEncoder, urlEncoderKeyName) {
			this.urlEncoder = urlEncoder;
			this.urlEncoderKey = urlEncoderKeyName;
		},
		doSetQueryStringByUrlEncoder: function () {
			if (this.urlEncoder !== null) {
				var queryString = this.urlEncoder.getValueByKey(this.urlEncoder.KEY_NAME__SEARCH_QUERY);
				if (queryString !== null) {
					for (var index = 0; index < this.elementsArr.length; index += 1) {
						this.elementsArr[index].$input.prop("value", queryString);
						this.elementsArr[index].$input.trigger("keypressSync");
					}
				}
			}
		},
		doBindEvents: function () {
			for (var index = 0; index < this.elementsArr.length; index += 1) {
				this.bindEventToElement(this.elementsArr[index]);
			}
			var that = this;
			$(document).on("searchComplete.search", function () {
				that.searchComplete();
				that.hideSearchProgress();
			});
			$(document).on("searchBegin.search", function () {
				that.showSearchProgress();
			});
			$(document).on("searchError.search", function () {
				that.hideSearchProgress();
			});
		},
		hideSearchProgress: function () {
			if (this.dom.$searchProgress.is(":visible")) {
				this.dom.$searchProgress.fadeOut(333);
			} else {
				this.dom.$searchProgress.css("display", "none");
			}
		},
		showSearchProgress: function () {
			$("#searchProgress").fadeIn(333);
		},
		bindEventToElement: function (elem) {
			var that = this;
			elem.$submit.closest("form").on("submit", function (e) {
				that.dom.$tabSelectorSearch.click();
				that.onClick(elem);
				return false;
			});
		},
		onClick: function (elem) {
			var s = this.searchEngine.trim(document.getElementById(elem.$input.prop("id")).value).replace(/\r/g, '').replace(/\n/g, '').replace(/\t/g, ' ').replace(/\u00A0/g, '');
			s = s.replace(/[,;]/g, ' ');
			this.performSearch(s);
		},
		performSearch: function (s) {
			var queryArray = this.searchEngine.trim(s).split(this.searchEngine.querySplitter());
			var output = '';
			if (queryArray.length == 0 || queryArray[0] == '')
				this.showSearchTextEmptyString();
			else {
				try {
					this.searchEngine.doSearch(s);
				} catch (e) {
					if (e.message == "LocalSearchNotSupportedInCurrentBrowser") {
						var $msg = $('<div class="b-tree__searchResultText">' + this.dataManager.getErrorInLocalSearch() + '</div>');
						this.dom.tabs.search.$tree.html($msg);
						$(document).trigger("searchCompleteBuildTree");
					}
				}
			}
		},
		searchComplete: function () {
			this.highlightManager.hide();
			var searchResultsArr = this.searchEngine.getSearchResults();
			if (searchResultsArr.length > 0) {
				this.navTreeSearch.setNewContentBySearchResults(searchResultsArr);
				this.navTreeSearch.show();
				$(document).trigger("searchCompleteBuildTree");
				var searchQuery = this.getSearchQuery();
				var searchQueryArr = this.searchEngine.trim(searchQuery).split(this.searchEngine.querySplitter());
				searchQueryArr = new Array(searchQuery);
				this.highlightManager.show(searchQueryArr);
				if (this.isFirstSearch && this.isSearchTabSelectedOnStart()) {
					if (this.isFirstSearch) {
						$(document).trigger("firstSearchCompleteWithSelectedSearchTab");
						this.isFirstSearch = false;
					}
				}
			} else {
				var $msg = $('<div class="b-tree__searchResultText">' + this.dataManager.getSearchTextNoResults() + '</div>');
				this.dom.tabs.search.$tree.html($msg);
				$(document).trigger("searchCompleteBuildTree");
			}
		},
		showSearchTextEmptyString: function () {
			this.highlightManager.hide();
			var $msg = $('<div class="b-tree__searchResultText">' + this.dataManager.getSearchTextEmptyString() + '</div>');
			this.dom.tabs.search.$tree.html($msg);
			$(document).trigger("searchCompleteBuildTree");
		},
		isSearchTabSelected: function () {
			var $navTree_search = this.dom.tabs.search.$wrapperItem;
			if ($navTree_search.hasClass("m-tabs__wrapperItem__selected")) {
				return true;
			} else {
				return false;
			}
		},
		isSearchTabSelectedOnStart: function () {
			var $navTree_search = this.dom.tabs.search.$wrapperItem;
			if ($navTree_search.index() === parseInt(this.urlEncoder.getValueByKey(this.urlEncoder.KEY_NAME__TAB_INDEX))) {
				return true;
			} else {
				return false;
			}
		},
		getSearchQuery: function () {
			if (this.elementsArr[0] !== undefined) {
				return this.elementsArr[0].$input.prop("value");
			} else {
				return null;
			}
		},
		isSearchQueryNotEmpty: function () {
			var query = this.getSearchQuery();
			if (query !== null) {
				if (query !== '') {
					return true;
				}
			}
			return false;
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		runCustomButtons: function () {
			_class.runCustomButtons();
		},
		runInputSync: function () {
			_class.runInputSync();
		},
		runInputPlaceholders: function () {
			_class.runInputPlaceholders();
		},
		doBindEvents: function () {
			_class.doBindEvents();
		},
		doSearchIfQueryStringNotEmpty: function () {
			_class.doSearchIfQueryStringNotEmpty();
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.highlightManager');
SAN_WHOLE.highlightManager = (function () {
	var _class = {
		dom: null,
		$content: null,
		init: function () {
			this.doSetDom();
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
			this.$content = this.dom.$articleInnerWrapper;
		},
		show: function (wordsArr) {
			this.hide();
			for (var index = 0; index < wordsArr.length; index += 1) {
				this.$content.highlight(wordsArr[index]);
			}
			this.hideFromCopyright();
		},
		hide: function () {
			this.$content.removeHighlight();
		},
		hideFromCopyright: function () {
			this.dom.$articleGeneratorCopyright.removeHighlight();
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		show: function (wordsArr) {
			_class.show(wordsArr);
		},
		hide: function () {
			_class.hide();
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.tabController');
SAN_WHOLE.tabController = (function () {
	var _class = {
		DREX_SHOW_MENU: 1,
		DREX_SHOW_SEARCH: 1,
		DREX_SHOW_INDEX: 0,

		tabArr: [],
		urlEncoder: null,
		dom: null,
		init: function () {
			this.doSetDom();
			this.doSetUrlEncoder();
			this.doAddTabs();
		},
		addTab: function ($tabSelector, $tabWrapper, $tabWrapperInner) {
			this.tabArr.push({
				$selector: $tabSelector,
				$wrapper: $tabWrapper,
				$wrapperInner: $tabWrapperInner,
				scrollTop: 0
			});
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
		},
		doAddTabs: function () {
			if (this.DREX_SHOW_MENU)
				this.addTab(this.dom.tabs.menu.$selectorItem, this.dom.tabs.menu.$wrapperItem, this.dom.tabs.menu.$wrapperItemInner);
			if (this.DREX_SHOW_INDEX)
				this.addTab(this.dom.tabs.index.$selectorItem, this.dom.tabs.index.$wrapperItem, this.dom.tabs.index.$wrapperItemInner);
			if (this.DREX_SHOW_SEARCH)
				this.addTab(this.dom.tabs.search.$selectorItem, this.dom.tabs.search.$wrapperItem, this.dom.tabs.search.$wrapperItemInner);
		},
		doSetUrlEncoder: function () {
			var that = this;
			this.urlEncoder = SAN_WHOLE.urlEncoder;
			this.urlEncoder.addSaveFunc(
				function () {
					return that.getSelectedTabIndex();
				},
				that.urlEncoder.KEY_NAME__TAB_INDEX
			);
			this.urlEncoder.addSaveFunc(
				function () {
					return that.getVisibleTabScrollTop();
				},
				that.urlEncoder.KEY_NAME__MENU_SCROLL_TOP
			);
		},
		getVisibleTabScrollTop: function () {
			var selectedTab = this.getSelectedTab();
			if (!selectedTab)
				return 0;
			var $wrapperItemInner = selectedTab.$wrapperInner;
			var scrollTop = 0;
			if ($wrapperItemInner !== null) {
				scrollTop = $wrapperItemInner.scrollTop();
			}
			return scrollTop;
		},
		doSetScrollTopByUrlEncoder: function () {
			if (this.urlEncoder !== null) {
				var scrollTop = this.urlEncoder.getValueByKey(this.urlEncoder.KEY_NAME__MENU_SCROLL_TOP);
				if (scrollTop !== null) {
					var selectedTab = this.getSelectedTab();
					if (!selectedTab)
						return;
					var $visibleWrapperItemInner = selectedTab.$wrapperInner;
					$visibleWrapperItemInner.scrollTop(scrollTop).trigger("scroll");
				} else {
					var $selectedTreeElem = this.dom.tabs.menu.$tree.find(".m-tree__itemContent__selected");
					if ($selectedTreeElem.length > 0) {
						var selectedTreeElemTop = ($selectedTreeElem.offset()).top - (this.dom.$tabWrapperItems.offset()).top - $selectedTreeElem.height() / 2;
						this.dom.tabs.menu.$wrapperItemInner.scrollTop(selectedTreeElemTop).trigger("scroll");
					}
				}
			}
		},
		doSetTabIndexByUrlEncoder: function () {
			if (this.urlEncoder !== null) {
				var tabIndex = this.urlEncoder.getValueByKey(this.urlEncoder.KEY_NAME__TAB_INDEX);
				if (tabIndex !== null) {
					if (this.tabArr[tabIndex] !== undefined) {
						this.toggleTabState(this.tabArr[tabIndex].$selector);
					}
				}
			}
		},
		doBindEvents: function () {
			for (var index = 0; index < this.tabArr.length; index += 1) {
				this.doBindEventToggleState(index);
				this.doBindScrollTopSaver(index);
			}
			this.doBindEventHover();
			var that = this;
			$(document).on("navResize", function () {
				that.doSetScrollPositionToSelectedTab();
			});
			$(document).on("firstSearchCompleteWithSelectedSearchTab", function () {
				that.doSetScrollTopByUrlEncoder();
			});
		},
		doBindEventToggleState: function (index) {
			var that = this;
			this.tabArr[index].$selector.click(function () {
				if (!$(this).hasClass("m-tabs__selectorItem__selected")) {
					that.toggleTabState($(this));
					$(window).resize();
				}
			});
		},
		doBindScrollTopSaver: function (index) {
			var that = this;
			this.tabArr[index].$wrapperInner.on("scroll", function () {
				that.tabArr[index].scrollTop = $(this).scrollTop();
			});
		},
		doBindEventHover: function () {
			if (this.tabArr.length == 0)
				return;

			var $selectorItems = this.tabArr[0].$selector.parent();
			$selectorItems.on("mouseenter", ".b-tabs__selectorItem", function () {
				if ($(this).hasClass("m-tabs__selectorItem__selected"))
					return false;
				$(this).addClass("m-tabs__selectorItem__hovered");
			});
			$selectorItems.on("mouseleave", ".b-tabs__selectorItem", function () {
				if ($(this).hasClass("m-tabs__selectorItem__selected"))
					return false;
				$(this).removeClass("m-tabs__selectorItem__hovered");
			});
		},
		toggleTabState: function ($selectedTabSelector) {
			for (var index = 0; index < this.tabArr.length; index += 1) {
				var $currTabSelector = this.tabArr[index].$selector;
				if ($currTabSelector.prop("id") === $selectedTabSelector.prop("id")) {
					this.showTabByIndex(index);
				} else {
					this.hideTabByIndex(index);
				}
			}
			$(document).trigger("newTabSelected.tabs");
		},
		showTabByIndex: function (index) {
			if (index == -1)
				return;
			var $tabSelector = this.tabArr[index].$selector;
			var $tabWrapper = this.tabArr[index].$wrapper;
			var $tabWrapperInner = this.tabArr[index].$wrapperInner;
			var scrollTop = this.tabArr[index].scrollTop;
			//console.log( 'show tab: %s %s', $tabSelector.prop( "id" ), $tabWrapper.prop( "id" ) );
			$tabSelector.
			addClass("m-tabs__selectorItem__selected").
			removeClass("m-tabs__selectorItem__hovered").
			removeClass("m-tabs__selectorItem__unselected");
			$tabWrapper.addClass("m-tabs__wrapperItem__selected");
			$tabWrapperInner.scrollTop(scrollTop);
		},
		hideTabByIndex: function (index) {
			var $tabSelector = this.tabArr[index].$selector;
			var $tabWrapper = this.tabArr[index].$wrapper;
			//console.log( 'hide tab: %s %s', $tabSelector.prop( "id" ), $tabWrapper.prop( "id" ) );
			$tabSelector.
			removeClass("m-tabs__selectorItem__selected").
			addClass("m-tabs__selectorItem__unselected");
			$tabWrapper.removeClass("m-tabs__wrapperItem__selected");
		},
		getSelectedTabIndex: function () {
			for (var index = 0; index < this.tabArr.length; index += 1) {
				var $currTabSelector = this.tabArr[index].$selector;
				if ($currTabSelector.hasClass("m-tabs__selectorItem__selected")) {
					return index;
				}
			}
			if (this.tabArr.length == 0)
				return -1;
			return 0;
		},
		getSelectedTab: function () {
			var selectedTabIndex = this.getSelectedTabIndex();
			if (selectedTabIndex == -1)
				return null;
			return this.tabArr[selectedTabIndex];
		},
		doSetScrollPositionToSelectedTab: function () {
			var selectedTabIndex = this.getSelectedTabIndex();
			this.showTabByIndex(selectedTabIndex);
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		doBindEvents: function () {
			_class.doBindEvents();
		},
		doSetTabIndexByUrlEncoder: function () {
			_class.doSetTabIndexByUrlEncoder();
		},
		doSetScrollTopByUrlEncoder: function () {
			_class.doSetScrollTopByUrlEncoder();
		},


		isMenuTabShown: function () {
			return _class.DREX_SHOW_MENU != 0;
		},
		isSearchTabShown: function () {
			return _class.DREX_SHOW_SEARCH != 0;
		},
		isIndexTabShown: function () {
			return _class.DREX_SHOW_INDEX != 0;
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.urlEncoder');
SAN_WHOLE.urlEncoder = (function () {
	var _class = {
		urlDecoded: null,
		funcArr: [],
		utils: null,
		dom: null,
		init: function () {
			this.utils = SAN_WHOLE.utils;
			this.dom = SAN_WHOLE.dom;
		},
		doBindOpenNextPageWithEncodedStringToLinks: function () {
			var that = this;
			this.dom.$internal_wrapper.on("click", "a.local_link, a.b-breadCrumbs__link, a.b-controlButtons__link, a.b-tree__itemLink", function (e) {
				that.openNextPage($(this).prop("href"), $(this).attr("href"), $(this).prop("target") == "_new");
				e.preventDefault();
				return false;
			});
		},
		doBindOpenNextPageWithEncodedStringToLinksInClonedNode: function () {
			var that = this;
			$(".cloned_node").on("click", "a", function (e) {
				that.openNextPage($(this).prop("href"), $(this).attr("href"), $(this).prop("target") == "_new");
				e.preventDefault();
				return false;
			});
		},

		doBindOpenNextPageWithEncodedStringToLinksInKeywordContextMenu: function () {
			var that = this;
			this.dom.$keywordContextMenu.on("click", "a.b-tree__itemLink", function (e) {
				that.openNextPage($(this).prop("href"), $(this).attr("href"), $(this).prop("target") == "_new");
				e.preventDefault();
				return false;
			});
		},

		openNextPage: function (nextpage, nextPageHref, atNewPage) {
			atNewPage = typeof (atNewPage) != 'undefined' ? atNewPage : false;
			var stateParams = this.getEncodedUrl();
			var targetUrl = nextpage;
			if (nextPageHref && nextPageHref.length > 0 && nextPageHref.charAt(0) == '#') {
				targetUrl = nextPageHref;
				nextpage = nextPageHref;
			}
			if ($("html").hasClass("ie"))
				targetUrl = this.utils.escapeXml(nextpage);
			var anch = "";
			var anchPos = -1;
			if ((anchPos = nextpage.indexOf("#")) != -1) {
				targetUrl = nextpage.substr(0, anchPos);
				anch = nextpage.substr(anchPos);
			}
			targetUrl += "?" + stateParams + anch;
			if (vjwTutorial) {
				if (nextPageHref.length > 0) {
					var index = getPageIndex(nextPageHref);
					jwplayer().seek(drex_node_times[index]);
				}
			} else {
				window.open(targetUrl, atNewPage ? "_new" : "_self");
			}

		},
		doDecodeUrl: function () {
			var map = [];
			var urlParams = {};
			var e,
				a = /\+/g,
				r = /([^&=]+)=?([^&]*)/g,
				d = function (s) {
					return decodeURIComponent(s.replace(a, " "));
				},
				q = window.location.search.substring(1);
			while (e = r.exec(q))
				urlParams[d(e[1])] = d(e[2]);
			for (var key in urlParams) {
				var value = this.decodeString(urlParams[key]);
				map[key] = value;
			}
			this.urlDecoded = map;
		},
		getValueByKey: function (key) {
			if (this.urlDecoded[key] !== undefined) {
				return this.urlDecoded[key];
			} else {
				return null;
			}
		},
		addSaveFunc: function (func, key) {
			this.funcArr[key] = func;
		},
		getEncodedUrl: function () {
			var result = "";
			for (var key in this.funcArr) {
				var currFunc = this.funcArr[key];
				var value = currFunc();
				value = this.encodeString(value.toString());
				if (value.toString().length > 0) {
					if (result != "") {
						result += "&";
					}
					result += key + "=" + value;
				}
			}
			return result;
		},
		decodeString: function (str) {
			var bits = this.utils.base64.decode(str, 0, true, true);
			if (bits === null) {
				return null;
			}
			var result = this.utils.ar2str(bits);
			result = this.utils.utf8.decode(result);
			return result;
		},
		encodeString: function (str) {
			var compressedStr = str;
			var utfEncodedStr = this.utils.utf8.encode(compressedStr);
			var bitArray = this.utils.str2ar(utfEncodedStr);
			return this.utils.base64.encode(bitArray, false, true);
		}
	};
	var API = {
		KEY_NAME__MENU_WIDTH: "mw",
		KEY_NAME__MENU_STATE: "ms",
		KEY_NAME__TAB_INDEX: "st",
		KEY_NAME__MENU_SCROLL_TOP: "sct",
		KEY_NAME__SEARCH_QUERY: "q",
		init: function () {
			_class.init();
		},
		doBindOpenNextPageWithEncodedStringToLinks: function () {
			_class.doBindOpenNextPageWithEncodedStringToLinks();
		},
		doBindOpenNextPageWithEncodedStringToLinksInClonedNode: function () {
			_class.doBindOpenNextPageWithEncodedStringToLinksInClonedNode();
		},

		doBindOpenNextPageWithEncodedStringToLinksInKeywordContextMenu: function () {
			_class.doBindOpenNextPageWithEncodedStringToLinksInKeywordContextMenu();
		},

		doDecodeUrl: function () {
			_class.doDecodeUrl();
		},
		getValueByKey: function (key) {
			return _class.getValueByKey(key);
		},
		addSaveFunc: function (func, key) {
			_class.addSaveFunc(func, key);
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.workZoneSizer');
SAN_WHOLE.workZoneSizer = (function () {
	var _class = {
		NAV_MIN_WIDTH_DEFAULT: 250,
		ARTICLE_MIN_WIDTH_DEFAULT: 400,
		//IE_SCROLLBAR_SIZE: 24,
		dom: null,
		dataManager: null,
		currNavWidth: 0,
		minNavWidth: null,
		maxNavWidth: null,
		minArticleWidth: null,
		navArticlePaddingSize: 0,
		visibleTabLongestTreeItemWidth: null,
		timeoutId: null,
		WINDOW_RECALCULATING_DELAY: 100,
		init: function () {
			this.doSetCachedDom();
			this.doSetUrlEncoder();
			this.doSetDataManager();
			this.doSetNavArticlePaddingSize();
			this.doSetNavMinWidth();
			this.doSetArticleMinWidth();
			this.doSetSplitter();
			this.doSetFrameModeSizer();
			this.doSetCurrNavWidth();
		},
		doSetCachedDom: function () {
			this.dom = SAN_WHOLE.dom;
		},
		doSetDataManager: function () {
			this.dataManager = SAN_WHOLE.dataManager;
		},
		doSetUrlEncoder: function () {
			var that = this;
			this._urlEncoder = SAN_WHOLE.urlEncoder;
			this._urlEncoder.addSaveFunc(function () {
				return that.currNavWidth;
			}, that._urlEncoder.KEY_NAME__MENU_WIDTH);
		},
		doSetCurrNavWidth: function () {
			var currNavWidth = null;
			if (this._urlEncoder !== null) {
				currNavWidth = this._urlEncoder.getValueByKey(this._urlEncoder.KEY_NAME__MENU_WIDTH);
				if (currNavWidth !== null) {
					this.currNavWidth = currNavWidth;
				}
			}
			if (currNavWidth === null) {
				var startingMenuWidth = this.dataManager.getStartingMenuWidth();
				if ($.isNumeric(startingMenuWidth)) {
					this.currNavWidth = startingMenuWidth;
				} else {
					this.currNavWidth = this.dom.$workZoneSideNav.width();
				}
			}
		},
		doSetNavArticlePaddingSize: function () {
			var navRightPadding = this.dom.$workZoneSideNav.css("paddingRight");
			var articleLeftPadding = this.dom.$workZoneSideArticle.css("paddingLeft");
			this.navArticlePaddingSize = navRightPadding + articleLeftPadding;
		},
		getTabWidth: function (tabId) {
			var curTab = document.getElementById(tabId);
			if (curTab)
				return $('#' + tabId).outerWidth(true);
			return 0;
		},

		doSetNavMinWidth: function () {
			var minWidth = parseInt(this.dom.$workZoneSideNav.css("minWidth"), 10);
			if ($.isNumeric(minWidth) && (minWidth !== 0)) {
				this.minNavWidth = minWidth;
			} else {
				this.minNavWidth = this.NAV_MIN_WIDTH_DEFAULT;
			}
			var summaryTabWidth = 0;
			summaryTabWidth += this.getTabWidth("tabSelector_menu");
			summaryTabWidth += this.getTabWidth("tabSelector_index");
			summaryTabWidth += this.getTabWidth("tabSelector_search");
			this.minNavWidth = Math.max(this.minNavWidth, summaryTabWidth + 20);
		},

		doSetArticleMinWidth: function () {
			var minWidth = parseInt(this.dom.$workZoneSideArticle.css("minWidth"), 10);
			if ($.isNumeric(minWidth) && (minWidth !== 0)) {
				this.minArticleWidth = minWidth;
			} else {
				this.minArticleWidth = this.ARTICLE_MIN_WIDTH_DEFAULT;
			}
		},
		recalculateNavMaxWidth: function () {
			var userLeftSideWidth = 0;
			var userRightSideWidth = 0;
			var isUserLeftSideExistsAndVisible = ((this.dom.$pageContentLeft.length) > 0 && this.dom.isPageLeftVisible());
			var isUserRightSideExistsAndVisible = ((this.dom.$pageContentRight.length) > 0 && this.dom.isPageRightVisible());
			if (isUserLeftSideExistsAndVisible) {
				userLeftSideWidth = this.dom.$pageContentLeft.outerWidth(true);
			}
			if (isUserRightSideExistsAndVisible) {
				userRightSideWidth = this.dom.$pageContentRight.outerWidth(true);
			}
			var windowWidth = $(window).width();
			var minArticleWidth = this.minArticleWidth;
			if (this.dom.$headerSide__nav.length) {
				var headerSide__buttons_width = this.dom.$headerSide__buttons.outerWidth();

				var headerSide__nav_paddings = this.dom.$headerSide__nav.outerWidth() - this.dom.$headerSide__nav.width();
				var maxBreadCrumbWidth = 0;
				this.dom.$headerSide__nav__breadCrumbs.find("li").each(function (index) {
					maxBreadCrumbWidth = Math.max(maxBreadCrumbWidth, $(this).outerWidth())
				});
				var headerSide__nav__breadCrumbs_width = maxBreadCrumbWidth;
				var articlePaddings = this.dom.$article.outerWidth() - this.dom.$article.width();
				var workZoneSideArticlePaddings = this.dom.$workZoneSideArticle.outerWidth() - this.dom.$workZoneSideArticle.width();
				var workZoneSideArticleContentPaddings = this.dom.$workZoneSideArticleContent.outerWidth() - this.dom.$workZoneSideArticleContent.width();
				var workZoneNavPaddings = this.dom.$workZoneSideNav.outerWidth() - this.dom.$workZoneSideNav.width();

				minArticleWidth = Math.max(minArticleWidth, headerSide__buttons_width + headerSide__nav__breadCrumbs_width + headerSide__nav_paddings + articlePaddings + workZoneSideArticlePaddings + workZoneSideArticleContentPaddings + workZoneNavPaddings);
			}
			var maxContentAreaWidth = this.dom.$internal_wrapper.css("width");
			if (!maxContentAreaWidth || maxContentAreaWidth.length < 2) {
				maxContentAreaWidth = windowWidth;
			} else {
				if (maxContentAreaWidth.charAt(maxContentAreaWidth.length - 1) == '%') {
					maxContentAreaWidth = parseInt(maxContentAreaWidth, 10) * windowWidth / 100;
				} else {
					maxContentAreaWidth = parseInt(maxContentAreaWidth, 10);
				}
			}
			var maxWidth = maxContentAreaWidth - minArticleWidth - userLeftSideWidth - userRightSideWidth;
			if (maxWidth < this.NAV_MIN_WIDTH_DEFAULT) {
				maxWidth = this.NAV_MIN_WIDTH_DEFAULT;
			}
			this.maxNavWidth = maxWidth;
			//console.log( [windowWidth,minArticleWidth,userLeftSideWidth,userRightSideWidth, maxWidth, this.minArticleWidth ] );
		},
		recalculateAll: function () {
			this.recalculateNavMaxWidth();
			this.recalculateVisibleTabLongestTreeItemWidth();
			this.dom.$hasHorizontalScrollbar = {};
			this.dom.$hasVerticalScrollbar = {};
			this.setNewNavWidth(this.currNavWidth);
			this.frameModeSizer.recalculateIfEnabled();
			this.setNewNavWidth(this.currNavWidth);
			this.frameModeSizer.recalculateIfEnabled();
		},
		doBindEvents: function () {
			this.doBindEventsSizer();
			this.splitter.doBindEvents();
			if (this.dataManager.isFrameModeEnabled()) {
				this.frameModeSizer.enableRecalculatingEvents();
			}
		},
		doBindEventsSizer: function () {
			var that = this;
			$(document).on("newTabSelected.tabs", function () {
				that.recalculateAll();
			});
			$(document).on("nodeVisibleChanged", function () {
				that.recalculateAll();
			});
			$(document).on("searchCompleteBuildTree", function () {
				that.recalculateAll();
			});
			$(window).resize(function () {
				clearTimeout(that.timeoutId);
				that.timeoutId = setTimeout(function () {
					that.recalculateAll();
				}, that.WINDOW_RECALCULATING_DELAY);
			});
		},
		doSetSplitter: function () {
			var that = this;
			this.splitter = SAN_WHOLE.workZoneSizer_Splitter;
			this.splitter.setOnMouseMoveCallback(function (newWidth) {
				that.changeWorkZoneSizeOnMouseMove(newWidth);
				that.recalculateAll();
			});
			this.splitter.setOnMouseUpCallback(function () {
				that.recalculateAll();
			});
			this.splitter.init();
		},
		doSetFrameModeSizer: function () {
			this.frameModeSizer = SAN_WHOLE.workZoneSizer_FrameMode;
			this.frameModeSizer.init();
		},
		changeWorkZoneSizeOnMouseMove: function (newWidth) {
			this.setNewNavWidth(newWidth);
		},
		setNewNavWidth: function (newNavWidth) {
			var finalNewNavWidth = this.getFinalNewNavWidth(newNavWidth);
			var longestTreeItemWidthWithPaddings = this.visibleTabLongestTreeItemWidth;
			var selectedTab = this.dom.getVisibleTab();
			var tabId = null;
			if (selectedTab)
				tabId = selectedTab.$wrapperItem.prop("id");
			//console.log("setNewNavWidth: this.dom.$hasVerticalScrollbar[" + tabId + "] = " + this.dom.$hasVerticalScrollbar[tabId]);

			if (this.dom.$hasVerticalScrollbar[tabId])
				longestTreeItemWidthWithPaddings += $.getScrollbarWidth() * 1;
			var dx = finalNewNavWidth - this.dom.$workZoneSideNav.width();

			var finalTreeWidth = 0;
			if (selectedTab) {
				//console.log("setNewNavWidth: " + tabId);
				var $wrapperItem = selectedTab.$wrapperItem;

				finalTreeWidth += $wrapperItem.width();
			}
			finalTreeWidth += dx;
			this.dom.$hasHorizontalScrollbar[tabId] = finalTreeWidth < longestTreeItemWidthWithPaddings;
			//console.log("setNewNavWidth: this.dom.$hasHorizontalScrollbar[" + tabId + "] = " + this.dom.$hasHorizontalScrollbar[tabId]);
			if (!this.dom.$hasHorizontalScrollbar[tabId]) {
				this.dom.$treeArr.css("width", "auto");
			} else {
				this.dom.$treeArr.css({
					width: this.visibleTabLongestTreeItemWidth + "px"
				});
			}
			this.dom.$workZoneSideNav.css("width", finalNewNavWidth + "px");
			this.currNavWidth = finalNewNavWidth;
		},
		getFinalNewNavWidth: function (newNavWidth) {
			var finalNewNavWidth = newNavWidth;
			if (newNavWidth > this.maxNavWidth) {
				finalNewNavWidth = this.maxNavWidth;
			} else if (newNavWidth < this.minNavWidth) {
				finalNewNavWidth = this.minNavWidth;
			}
			return finalNewNavWidth;
		},
		recalculateVisibleTabLongestTreeItemWidth: function () {
			var $visibleTab = this.dom.getVisibleItemWrapperInner();
			if ($visibleTab) {
				var $tree = $visibleTab.children("div");
				var $treeTable = $tree.children("table");
				$treeTable.css("width", "auto");
				var treeTableWidth = $treeTable.width();
				$treeTable.css("width", "100%");
				this.visibleTabLongestTreeItemWidth = treeTableWidth;
			} else {
				this.visibleTabLongestTreeItemWidth = 0;
			}
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		recalculateAll: function () {
			_class.recalculateAll();
		},
		doBindEvents: function () {
			_class.doBindEvents();
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.workZoneSizer_Splitter');
SAN_WHOLE.workZoneSizer_Splitter = (function () {
	var _class = {
		$splitter: null,
		$resizable: null,
		$body: null,
		splitterOldX: 0,
		timeoutId: null,
		dom: null,
		DELAY: 1,
		onMouseDownCallback: null,
		onMouseMoveCallback: null,
		onMouseUpCallback: null,
		init: function () {
			this.doSetDom();
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
			this.$splitter = this.dom.$splitter;
			this.$resizable = this.dom.$workZoneSideNav;
			this.$body = this.dom.$body;
		},
		doBindEvents: function () {
			var that = this;
			$(this.$splitter).on("mousedown.splitter", function (e) {
				that.onMouseDown(e);
			});
		},
		bindMouseEvents: function () {
			var that = this;
			$(document).on("mouseup.splitter", function () {
				that.onMouseUp();
			});
			$(document).on("mousemove.splitter", function (e) {
				clearTimeout(that.timeoutId);
				that.timeoutId = setTimeout(function () {
					that.onMouseMove(e);
				}, that.DELAY);
			});
		},
		unbindMouseEvents: function () {
			$(document).off(".splitter");
		},
		onMouseDown: function (e) {
			this.splitterOldX = e.pageX;
			this._resizableOldWidth = this.$resizable.width();
			this.addCursorIconToBody();
			this.disableSelection();
			this.bindMouseEvents();
		},
		onMouseUp: function () {
			this.removeCursorIconFromBody();
			this.enableSelection();
			this.unbindMouseEvents();
			return this.onMouseUpCallback();
		},
		onMouseMove: function (e) {
			if ($.browser.msie && !(document.documentMode >= 9) && !e.button) {
				return this.onMouseUp();
			}
			var delta = e.pageX - this.splitterOldX;
			var newWidth = this._resizableOldWidth + delta;
			return this.onMouseMoveCallback(newWidth);
		},
		setOnMouseMoveCallback: function (callback) {
			this.onMouseMoveCallback = callback;
		},
		setOnMouseUpCallback: function (callback) {
			this.onMouseUpCallback = callback;
		},
		getResizableWidth: function () {
			return parseInt(this.$resizable.css("width"), 10);
		},
		addCursorIconToBody: function () {
			this.$body.css("cursor", "e-resize");
		},
		removeCursorIconFromBody: function () {
			this.$body.css("cursor", "auto");
		},
		disableSelection: function () {
			this.$body.disableTextSelect();
		},
		enableSelection: function () {
			this.$body.enableTextSelect();
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		doBindEvents: function () {
			_class.doBindEvents();
		},
		setOnMouseMoveCallback: function (callback) {
			_class.setOnMouseMoveCallback(callback);
		},
		setOnMouseUpCallback: function (callback) {
			_class.setOnMouseUpCallback(callback);
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.workZoneSizer_FrameMode');
SAN_WHOLE.workZoneSizer_FrameMode = (function () {
	var _class = {
		dom: null,
		timeoutId: null,
		isRecalculatingEventsEnabled: false,
		recalculateDomNodes: [],
		RESIZE_TIME_INTERVAL: 50,
		init: function () {
			this.doSetDom();
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
		},
		doBindEvents: function () {
			this.doBindKeywordContextEvents();
		},
		doBindKeywordContextEvents: function () {
			var that = this;
			this.dom.$keywordContextMenu.on("show.contextMenu", function (e, $elemInTree) {
				that.dom.$keywordContextMenu_elemInTree = $elemInTree;
				that.recalculate();
			});
			this.dom.tabs.index.$wrapperItemInner.on("scroll.contextMenu", function () {
				that.recalculateIndexContextMenu();
			});
		},
		addDomNodeToRecalculate: function ($dom, newValue) {
			this.recalculateDomNodes.push({
				$dom: $dom,
				value: newValue
			});
		},
		enableRecalculatingEvents: function () {
			this.isRecalculatingEventsEnabled = true;
			this.dom.$html.addClass(this.dom.FRAME_ENABLED_CLASS);
			this.doBindEvents();
		},
		disableRecalculatingEvents: function () {
			this.isRecalculatingEventsEnabled = false;
			$(window).off(".contextMenu");
			this.dom.$html.removeClass(this.dom.FRAME_ENABLED_CLASS);
			this.dom.$workZone.css("height", "auto");
			this.dom.$article.css("height", "auto");
			this.dom.$articleWrapper.css("height", "auto");
			this.dom.$articlePreWrapper.css("height", "auto");
			this.dom.$articleInnerWrapper.css("height", "auto");
			this.dom.$tabWrapperItemInnerArr.css({
				height: "auto",
				overflow: "auto"
			});
			this.dom.$treeArr.css("height", "auto");
			this.dom.$keywordContextMenu.css("height", "auto");
		},
		toggleRecalculatingEvents: function () {
			if (this.isRecalculatingEventsEnabled) {
				this.disableRecalculatingEvents();
			} else {
				this.enableRecalculatingEvents();
			}
		},
		recalculateIfEnabled: function () {
			if (this.isRecalculatingEventsEnabled) {
				this.recalculate();
			}
		},
		recalculate: function () {
			if (!this.isRecalculatingEventsEnabled) {
				return false;
			}
			this.recalculateWorkZone();
			this.recalculateArticle();
			this.recalculateNav();
			this.recalculateIndexContextMenu();
			for (var index = 0; index < this.recalculateDomNodes.length; index += 1) {
				var node = this.recalculateDomNodes[index];
				if (typeof (node.value) === "object") {
					node.$dom.css(node.value);
				} else {
					node.$dom.css("height", node.value + "px");
				}
			}
			this.recalculateDomNodes = [];
			//console.log( this.getHeaderHeight() );
		},
		recalculateIndexContextMenu: function () {
			if (this.dom.$keywordContextMenu_elemInTree === undefined) {
				return false;
			}
			var $contextMenu = this.dom.$keywordContextMenu;
			if (!this.dom.isKeywordContextMenuVisible()) {
				return false;
			}
			$contextMenu.css({
				height: "auto",
				overflow: "visible"
			});
			var $workZone = this.dom.getVisibleItemWrapperInner();
			var $elemInTree = this.dom.$keywordContextMenu_elemInTree;
			var elemInTreePos = $elemInTree.offset();
			var elemInTreeHeight = $elemInTree.height();
			var elemInTreePosTop = elemInTreePos.top;
			var workZonePos = $workZone.offset();
			var workZoneHeight = $workZone.height();
			var contextMenuHeight = $contextMenu.height();
			if ((elemInTreePosTop < workZonePos.top) || (elemInTreePosTop > workZonePos.top + workZoneHeight)) {
				this.dom.$keywordContextMenu_elemInTree.trigger("click");
				return false;
				//elemInTreePosTop = workZonePos.top;

			} else {
				//$contextMenu.show();
			}
			var topSpaceHeight = elemInTreePosTop - workZonePos.top;
			var bottomSpaceHeight = workZoneHeight - topSpaceHeight - elemInTreeHeight;
			var contextMenuNewTop = 0;
			var contextMenuNewLeft = elemInTreePos.left;
			var contextMenuNewWidth = "auto";
			var contextMenuNewHeight = "auto";
			var contextMenuNewOverflow = "hidden";
			var contextMenuPadding = "0";
			var isContextMenuBiggerThenBottomSpace = (contextMenuHeight > bottomSpaceHeight);
			var isContextMenuBiggerThenTopSpace = (contextMenuHeight > topSpaceHeight);
			var isBottomSpaceBiggerThenTopSpace = (bottomSpaceHeight > topSpaceHeight);
			var isContextMenuHeightInContainer = (!isContextMenuBiggerThenBottomSpace && !isContextMenuBiggerThenTopSpace);
			if (!isContextMenuBiggerThenBottomSpace) {
				contextMenuNewTop = elemInTreePosTop + elemInTreeHeight;
			} else if (!isContextMenuBiggerThenTopSpace) {
				contextMenuNewTop = elemInTreePosTop - contextMenuHeight;
			} else {
				if (isBottomSpaceBiggerThenTopSpace) {
					contextMenuNewHeight = bottomSpaceHeight;
					contextMenuNewTop = elemInTreePosTop + elemInTreeHeight;
				} else {
					contextMenuNewHeight = topSpaceHeight;
					contextMenuNewTop = elemInTreePosTop - contextMenuNewHeight;
				}
				contextMenuNewOverflow = "scroll";
				contextMenuPadding = "0 20px 0px 0";
			}
			if (contextMenuNewHeight !== "auto") {
				contextMenuNewHeight += "px";
			}
			$contextMenu.css({
				top: contextMenuNewTop + "px",
				left: contextMenuNewLeft + "px",
				height: contextMenuNewHeight,
				overflow: contextMenuNewOverflow,
				padding: contextMenuPadding
			});

		},
		recalculateWorkZone: function () {
			var newWorkZoneHeight = $(window).height() - this.getHeaderHeight() - this.getFooterHeight();
			//this.dom.$workZone.css( "height", newWorkZoneHeight + "px" );
			this.addDomNodeToRecalculate(this.dom.$workZone, newWorkZoneHeight);
		},
		recalculateArticle: function () {
			var newArticleHeight = $(window).height() -
				(this.dom.$article.offset()).top -
				this.dom.getCssNumericValue(this.dom.$workZoneSideArticleContent, "paddingBottom") -
				this.dom.getCssNumericValue(this.dom.$article, "paddingBottom") -
				this.dom.getCssNumericValue(this.dom.$article, "paddingTop") -
				this.getFooterHeight();
			var newArticleInnerWrapperHeight = $(window).height() -
				(this.dom.$articleWrapper.offset()).top -
				this.dom.getCssNumericValue(this.dom.$articleWrapper, "paddingTop")
				//- this.dom.getCssNumericValue( this.dom.$articleWrapper, "marginTop" )
				-
				this.dom.getCssNumericValue(this.dom.$articleWrapper, "paddingBottom") -
				this.dom.getCssNumericValue(this.dom.$article, "paddingBottom") -
				this.dom.getCssNumericValue(this.dom.$workZoneSideArticleContent, "paddingBottom") -
				this.getFooterHeight() -
				0;
			var newArticleWrapperHeight = newArticleHeight -
				this.dom.$articleHeader.outerHeight(true) -
				this.dom.getCssNumericValue(this.dom.$articleWrapper, "borderTopWidth") -
				this.dom.getCssNumericValue(this.dom.$articleWrapper, "borderBottomWidth");
			newArticleInnerWrapperHeight = newArticleHeight +
				this.dom.getCssNumericValue(this.dom.$articleInnerWrapper, "paddingBottom");

			this.addDomNodeToRecalculate(this.dom.$article, newArticleHeight);
			this.addDomNodeToRecalculate(this.dom.$articlePreWrapper, newArticleHeight);
			this.addDomNodeToRecalculate(this.dom.$articleWrapper, newArticleWrapperHeight);
			//console.log( 'article newArticleHeight', newArticleHeight, 'newArticleInnerWrapperHeight', newArticleInnerWrapperHeight );
		},
		recalculateNav: function () {
			var that = this;
			this.recalculateMenuNav();
			this.recalculateIndexNav();
			this.recalculateSearchNav();
			$(document).trigger("navResize");
		},
		recalculateMenuNav: function () {
			this.recalculateNavWithTreeOnly(this.dom.tabs.menu);
		},
		recalculateIndexNav: function () {
			this.recalculateNavWithTreeOnly(this.dom.tabs.index);
		},
		recalculateSearchNav: function () {
			this.recalculateNavWithTreeAndSearchInput(this.dom.tabs.search);
		},
		recalculateNavWithTreeOnly: function (tab) {
			var workZoneHeight = this.dom.$workZone.height();
			var navOuterPaddingTop = (this.dom.$tabWrapperItems.offset()).top;
			var navOuterPaddingBottom = this.dom.getCssNumericValue(this.dom.$workZoneSideNavContent, "paddingBottom") + this.getFooterHeight();
			var navInnerPaddingTop = this.dom.getCssNumericValue(tab.$wrapperItem, "paddingTop");
			var navInnerPaddingBottom = this.dom.getCssNumericValue(tab.$wrapperItem, "paddingBottom");
			tab.$tree.css("height", "auto");
			var realTreeHeight = tab.$tree.height();
			var newTotalNavHeight = $(window).height() -
				navInnerPaddingTop -
				navInnerPaddingBottom -
				navOuterPaddingBottom -
				navOuterPaddingTop;

			var newNavHeightWithoutHorizontalScrollbar = newTotalNavHeight;
			var tabId = tab.$wrapperItem.prop("id");
			if (this.dom.$hasHorizontalScrollbar[tabId])
				newNavHeightWithoutHorizontalScrollbar -= $.getScrollbarWidth() * 1;
			//console.log("recalculateNavWithTreeOnly(" + tabId + "): (realTreeHeight > newNavHeightWithoutHorizontalScrollbar) <=> " + realTreeHeight + " > " + newNavHeightWithoutHorizontalScrollbar);
			this.dom.$hasVerticalScrollbar[tabId] = realTreeHeight > newNavHeightWithoutHorizontalScrollbar;
			//console.log("recalculateNavWithTreeOnly: this.dom.$hasVerticalScrollbar[" + tabId + "] = " + this.dom.$hasVerticalScrollbar[tabId]);
			//console.log("recalculateNavWithTreeOnly: this.dom.$hasHorizontalScrollbar[" + tabId + "] = " + this.dom.$hasHorizontalScrollbar[tabId]);
			if (!this.dom.$hasVerticalScrollbar[tabId]) {
				var SCROLL_COMPENSATION = 0;
				if (this.dom.isIeLessThan9()) {
					SCROLL_COMPENSATION += 2;
				}
				//tab.$tree.css( "height", newTotalNavHeight - SCROLL_COMPENSATION + "px" );
				this.addDomNodeToRecalculate(tab.$tree, newNavHeightWithoutHorizontalScrollbar - SCROLL_COMPENSATION);
			} else {
				//tab.$wrapperItemInner.css( "overflow", "auto" );
				this.addDomNodeToRecalculate(tab.$wrapperItemInner, {
					overflow: "auto"
				});
			}
			//tab.$wrapperItemInner.css( "height", newTotalNavHeight + "px" );
			this.addDomNodeToRecalculate(tab.$wrapperItemInner, newTotalNavHeight);
		},
		recalculateNavWithTreeAndSearchInput: function (tab) {
			if (!this.dom.isTabVisible(tab)) {
				return false;
			}
			var workZoneHeight = this.dom.$workZone.height();
			var navOuterPaddingTop = (this.dom.$tabWrapperItems.offset()).top;
			var navOuterPaddingBottom = this.dom.getCssNumericValue(this.dom.$workZoneSideNavContent, "paddingBottom") + this.getFooterHeight();
			var navInnerPaddingTop = this.dom.getCssNumericValue(tab.$wrapperItem, "paddingTop") + this.dom.$tabSearchFormWrapper.height() + this.dom.getCssNumericValue(this.dom.$tabSearchFormWrapper, "marginBottom");
			var navInnerPaddingBottom = this.dom.getCssNumericValue(tab.$wrapperItem, "paddingBottom");
			tab.$tree.css("height", "auto");
			var realTreeHeight = tab.$tree.height();
			var newTotalNavHeight = $(window).height() - navInnerPaddingTop - navInnerPaddingBottom - navOuterPaddingBottom - navOuterPaddingTop;
			var newNavHeightWithoutHorizontalScrollbar = newTotalNavHeight;
			var tabId = tab.$wrapperItem.prop("id");
			if (this.dom.$hasHorizontalScrollbar[tabId])
				newNavHeightWithoutHorizontalScrollbar -= $.getScrollbarWidth() * 1;
			this.dom.$hasVerticalScrollbar[tabId] = realTreeHeight > newNavHeightWithoutHorizontalScrollbar;
			if (!this.dom.$hasVerticalScrollbar[tabId]) {
				var SCROLL_COMPENSATION = 0;
				if (this.dom.isIeLessThan9()) {
					SCROLL_COMPENSATION += 2;
				}
				//tab.$tree.css( "height", newTotalNavHeight - SCROLL_COMPENSATION + "px" );
				this.addDomNodeToRecalculate(tab.$tree, newNavHeightWithoutHorizontalScrollbar - SCROLL_COMPENSATION);
			} else {
				//tab.$wrapperItemInner.css( "overflow", "auto" );
				this.addDomNodeToRecalculate(tab.$wrapperItemInner, {
					overflow: "auto"
				});
			}
			//tab.$wrapperItemInner.css( "height", newTotalNavHeight + "px" );
			this.addDomNodeToRecalculate(tab.$wrapperItemInner, newTotalNavHeight);
		},
		getHeaderHeight: function () {
			if (this.dom.isPageHeaderVisible()) {
				return this.dom.$pageContentHeader.height();
			} else {
				return 0;
			}
		},
		getFooterHeight: function () {
			if (this.dom.isPageFooterVisible()) {
				return this.dom.$pageContentFooter.height();
			} else {
				return 0;
			}
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		enableRecalculatingEvents: function () {
			_class.enableRecalculatingEvents();
		},
		disableRecalculatingEvents: function () {
			_class.disableRecalculatingEvents();
		},
		recalculateIfEnabled: function () {
			_class.recalculateIfEnabled();
		},
		toggleRecalculatingEvents: function () {
			_class.toggleRecalculatingEvents();
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.navTree_Menu');
SAN_WHOLE.navTree_Menu = (function () {
	var _class = {
		$navTree: null,
		urlEncoder: null,
		dom: null,
		navTreeView: null,
		nodeVisibleStatusArr: [],
		init: function () {
			this.doSetDom();
			this.doSetUtils();
			this.doSetUrlEncoder();
			this.doSetDataManager();
			this.doSetNodeVisibleStatusArrByUrlEncoder();
			var navArr = this.populateTable(this.dataManager.getRootNodesArray(), true);
			var navTreeItemsCollection = this.getNavCollection(navArr, null);
			this.navTreeView = navTreeView = new NavTree__View({
				collection: navTreeItemsCollection,
				$navTree: this.$navTree
			});
			var flatCollection = new NavTree__ItemsNodes_Collection(this.navTreeView.models);
			flatCollection.on(
				"change:isVisible",
				this.onNodeVisibleChange,
				this
			);
		},
		show: function () {
			this.navTreeView.render();
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
			this.$navTree = this.dom.tabs.menu.$wrapperItem;
		},
		doSetDataManager: function () {
			this.dataManager = SAN_WHOLE.dataManager;
		},
		doSetUtils: function () {
			this.utils = SAN_WHOLE.utils;
		},
		doSetUrlEncoder: function () {
			var that = this;
			this.urlEncoder = SAN_WHOLE.urlEncoder;
			this.urlEncoder.addSaveFunc(
				function () {
					return that.getCurrVisibleStatusArrAsString();
				},
				that.urlEncoder.KEY_NAME__MENU_STATE
			);
		},
		getDefaultNodeVisibleStatusArr: function () {
			var result = new Array(this.dataManager.getNodesCount());
			if (this.dataManager.getDrexMenuType() == 3 || this.dataManager.getDrexMenuType() == 1) {
				for (var i = 0; i < this.dataManager.getDrex().nodes_count; i++)
					result[i] = 1;
			} else {
				for (var i = 0; i < this.dataManager.getDrex().nodes_count; i++) {
					result[i] = (this.dataManager.getNodeDeepByIndex(i) <= 0 ? 1 : 0);
				}
			}
			return result;
		},
		getCurrVisibleStatusArrAsString: function () {
			var menuMinimized = this.getDefaultNodeVisibleStatusArr();
			var VarTOpnd = this.nodeVisibleStatusArr;

			var nSum = menuMinimized.length>VarTOpnd.length?VarTOpnd.length:menuMinimized.length;//S202201032157
			for (var i = 0; i < nSum; i++)
				menuMinimized[i] ^= VarTOpnd[i];
			var bits = new Array();
			for (var i = 0; i < menuMinimized.length; i++)//S202201032157
				bits.push(menuMinimized[i]);
			var bytes = this.utils.bitsToByte(bits, 7);
			bits = new Array();
			for (var i = 0; i < bytes.length; i++)
				if (bytes[i] == 0)
					bits.push(0);
				else
					bits.push(1);
			var result = this.utils.bitsToByte(bits, 7);
			for (var i = 0; i < bytes.length; i++)
				if (bytes[i] != 0)
					result.push(bytes[i]);
			var str = "";
			for (var i = 0; i < result.length; ++i) {
				str += String.fromCharCode(result[i]);
			}
			var menuStateString = str;
			if (menuStateString != "") {
				return menuStateString;
			} else {
				return null;
			}
		},
		doSetNodeVisibleStatusArrByUrlEncoder: function () {
			var t = this.urlEncoder.getValueByKey(this.urlEncoder.KEY_NAME__MENU_STATE);
			var VarTOpnd = this.getDefaultNodeVisibleStatusArr();
			if (t !== null) {
				var bytes = t;
				bytes = this.utils.str2ar(bytes);
				var bits = this.utils.byteToBits(bytes, 7);
				var prefixLen = this.utils.encodingPrefixLen(VarTOpnd.length, 7);
				var readPos = prefixLen;
				var result = new Array();
				for (var i = 0; i < prefixLen * 8; i++)
					if (bits[i] == 0)
						result.push(0);
					else
						result.push(bytes[readPos++]);
				var MyBB = this.utils.byteToBits(result, 7);
				for (var i = 0; i < VarTOpnd.length; ++i)
					VarTOpnd[i] ^= MyBB[i];
			}
			this.nodeVisibleStatusArr = VarTOpnd;
			this.validateOpenState();
		},
		onNodeVisibleChange: function (model, newValue) {
			this.nodeVisibleStatusArr[model.get("nodeIndex")] = newValue;
			$(document).trigger("nodeVisibleChanged");
		},
		validateOpenState: function () {
			var VarTOpnd = this.nodeVisibleStatusArr;
			var rootNodeIndex = this.dataManager.getIndexByNode(this.dataManager.getRootNode());
			VarTOpnd[rootNodeIndex] = 1;
			if (!this.dataManager.isSelectedNodeExists()) {
				return;
			}
			var currentNode = this.dataManager.getSelectedNode().parent();
			while (currentNode) {
				VarTOpnd[currentNode.node_index] = 1;
				currentNode = currentNode.parent();
			}
			//console.log( 'validateOpenState:', VarTOpnd );
		},
		populateTable: function (nodeArr, isVisible) {
			if (nodeArr.length === 0) {
				return null;
			}
			var itemArr = [];
			for (var index = 0; index < nodeArr.length; index += 1) {
				var node = nodeArr[index];
				var isOpened = this.nodeVisibleStatusArr[node.node_index];
				var isNodeVisible = !!(isVisible && isOpened);
				itemArr.push({
					'title': node.title,
					'link': node.link,
					'nodeIndex': node.node_index,
					'childs': this.populateTable(node.children(), isNodeVisible),
					'isVisible': isNodeVisible,
					'isSelected': vjwTutorial ? drex_node_times[lastSelectIndex] == drex_node_times[index + 1] : (node.link === this.dataManager.getPageFilename()),
					'noIcon': vjwTutorial ? drex_node_links[index + 1].length == 0 : false
				});
			}
			return itemArr;
		},
		getNavCollection: function (navArr, parentModel) {
			if (navArr === null) {
				return null;
			}
			var that = this;
			var collection = new NavTree__ItemsNodes_Collection(navArr);
			_.each(collection.models, function (model, index) {
				model.set({
					childs: that.getNavCollection(model.get("childs"), model),
					parent: parentModel
				});
			});
			return collection;
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		show: function () {
			_class.show();
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.navTree_Index');
SAN_WHOLE.navTree_Index = (function () {
	var _class = {
		$navTree: null,
		navTreeView: null,
		init: function () {
			this.doSetDom();
			this.doSetDataManager();
			var navArr = this.populateTable([this.dataManager.getDrex().root_keyword()]);
			var navTreeItemsCollection = this.getNavCollection(navArr, null);
			this.navTreeView = new NavTree__Keywords_View({
				collection: navTreeItemsCollection,
				$navTree: this.$navTree
			});
		},
		show: function () {
			this.navTreeView.render();
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
			this.$navTree = this.dom.tabs.index.$wrapperItem;
		},
		doSetDataManager: function () {
			this.dataManager = SAN_WHOLE.dataManager;
		},
		populateTable: function (keywordArr) {
			if (keywordArr.length === 0) {
				return null;
			}
			var itemArr = [];
			for (var index = 0; index < keywordArr.length; index += 1) {
				var keyword = keywordArr[index];
				if (keyword.isActive()) {
					itemArr.push({
						'title': keyword.title,
						'keywordIndex': keyword.keyword_index,
						'childs': this.populateTable(keyword.childrenSorted()),
						'links': this.getLinks(keyword)
					});
				} else {
					var childrenArr = this.populateTable(keyword.childrenSorted());
					if (childrenArr !== null)
						itemArr = itemArr.concat(childrenArr);
				}
			}
			return itemArr;
		},
		getLinks: function (keyword) {
			var links = keyword.nodes();
			var itemArr = [];
			for (var i = 0; i < links.length; i++) {
				itemArr.push({
					title: links[i].title,
					link: links[i].link,
					nodeIndex: links[i].node_index
				});
			}
			return itemArr;
		},
		getNavCollection: function (navArr, parentModel) {
			if (navArr === null) {
				return null;
			}
			var that = this;
			var collection = new NavTree__ItemsKeywords_Collection(navArr);
			_.each(collection.models, function (model, index) {
				model.set({
					childs: that.getNavCollection(model.get("childs"), model),
					links: new NavTree__ItemsNodes_Collection(model.get("links")),
					parent: parentModel
				});
			});
			return collection;
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		show: function () {
			_class.show();
		}
	};
	return API;
})();
SAN_WHOLE.namespace('SAN_WHOLE.navTree_Search');
SAN_WHOLE.navTree_Search = (function () {
	var _class = {
		$navTree: null,
		navTreeView: null,
		init: function () {
			this.doSetDom();
			this.doSetDataManager();
		},
		setNewContentBySearchResults: function (searchResultsArr) {
			var navArr = this.getNavArr(searchResultsArr);
			var navTreeItemsCollection = this.getNavCollection(navArr, null);
			var navTreeView = new NavTree__Search_View({
				collection: navTreeItemsCollection,
				$navTree: this.$navTree
			});
			this.navTreeView = navTreeView;
		},
		show: function () {
			this.navTreeView.render();
		},
		doSetDom: function () {
			this.dom = SAN_WHOLE.dom;
			this.$navTree = this.dom.tabs.search.$wrapperItem;
		},
		doSetDataManager: function () {
			this.dataManager = SAN_WHOLE.dataManager;
		},
		getNavCollection: function (navArr, parentModel) {
			if (navArr === null) {
				return null;
			}
			var that = this;
			var collection = new NavTree__ItemsNodes_Collection(navArr);
			_.each(collection.models, function (model, index) {
				model.set({
					childs: that.getNavCollection(model.get("childs"), model),
					parent: parentModel
				});
			});
			return collection;
		},
		getNavArr: function (searchResultsArr) {
			var itemArr = [];

			//N2201011758
			var retValue = window.location.href;
			retValue = retValue.substring(0, retValue.lastIndexOf('/'));
			var l = window['drex_file_path'];
			while (true) {
				var n = l.lastIndexOf('/');
				if (n == -1) break;
				l = l.substring(0, n);
				retValue = retValue.substring(0, retValue.lastIndexOf('/'));
			}
			for (var index = 0; index < searchResultsArr.length; index++) {
				var currNode = searchResultsArr[index];
				itemArr.push({
					'title': currNode[0],
					'link': retValue + '/' + currNode[1],//N2201011758
					'childs': null,
					'isSelected': (currNode[1] === this.dataManager.getPageFilename())
				});
			}
			return itemArr;
		}
	};
	var API = {
		init: function () {
			_class.init();
		},
		setNewContentBySearchResults: function (searchResultsArr) {
			_class.setNewContentBySearchResults(searchResultsArr);
		},
		show: function () {
			_class.show();
		}
	};
	return API;
})();

function initialSizing() {
	if (0 == 1) {
		$("#pageContentMiddle").removeClass("hidden");
		$("#pageContentFooter").removeClass("hidden");
	}
	var app = SAN_WHOLE;
	app.dataManager.init();
	app.dom.init();
	app.searchManager.init();
	app.searchManager.runCustomButtons();
	app.urlEncoder.init();
	app.urlEncoder.doDecodeUrl();

	if (0 == 1) {
		app.navTree_Menu.init();
		app.navTree_Index.init();
		app.navTree_Search.init();
		if (app.tabController.isMenuTabShown())
			app.navTree_Menu.show();
		if (app.tabController.isIndexTabShown())
			app.navTree_Index.show();
	}
	app.workZoneSizer.init();
	if (0 == 1) {
		app.workZoneSizer.doBindEvents();
	}
	app.workZoneSizer.recalculateAll();
}

function hideContentMiddle() {
	$("#pageContentMiddle").addClass("hidden");
}

function hideContentFooter() {
	$("#pageContentFooter").addClass("hidden");
}

function resizeArticle() {
	var article = $("#article");
	var articleOffset = article.offset();
	var articleOuterHeight = article.outerHeight(true);

	var bTabs = $(".b-tabs");
	var bTabsOffset = bTabs.offset();
	var bTabsCurrentLowestPoint = bTabsOffset.top + bTabs.outerHeight(true);
	var articleLowestPointMustBe = bTabsCurrentLowestPoint;
	var articleCurrentLowestPoint = articleOffset.top + articleOuterHeight;
	var articleWrapper = $(".b-article__wrapper");
	var articleMustBeResizedBy = articleLowestPointMustBe - articleCurrentLowestPoint;

	var articleWrapperHeight = articleWrapper.height();
	articleWrapper.css("min-height", Math.max(articleWrapperHeight + articleMustBeResizedBy, 0));
}

function initResizeArticleArticle() {
	resizeArticle();

	$(document).on("newTabSelected.tabs", function () {
		resizeArticle();
	});
	$(document).on("nodeVisibleChanged", function () {
		resizeArticle();
	});
	$(document).on("searchCompleteBuildTree", function () {
		resizeArticle();
	});
	var that = {
		timeoutId: null,
		DELAY: 1
	};
	$(SAN_WHOLE.dom.$splitter).on("mousedown.splitter", function () {

		$(document).on("mousemove.splitter", function (e) {
			clearTimeout(that.timeoutId);
			that.timeoutId = setTimeout(function () {
				resizeArticle();
			}, that.DELAY);
		});

		$(document).on("mouseup.splitter", function () {
			resizeArticle();
		});
	});
}
$(document).ready(function () {
	//sunny
	var path = window['drex_file_path'];
	for (i = 0; i < SAN_WHOLE.data_menu.DREX_NODE_LINKS.length; i++) {
		SAN_WHOLE.data_menu.DREX_NODE_LINKS[i] = path + SAN_WHOLE.data_menu.DREX_NODE_LINKS[i];
	}

	if (0 == 1 && !is_touch_device()) {
		$("iframe").each(function () {
			$(this).prop("real_src", $(this).prop("src"));
			$(this).prop("src", "about:blank");
		});
	}
	var app = SAN_WHOLE;
	app.dom.init();
	app.urlEncoder.doBindOpenNextPageWithEncodedStringToLinks();
	app.highlightManager.init();
	app.searchManager.runInputSync();
	app.searchManager.runInputPlaceholders();
	app.tabController.init();
	app.tabController.doBindEvents();
	app.tabController.doSetTabIndexByUrlEncoder();
	app.workZoneSizer.init();
	app.workZoneSizer.recalculateAll();
	if (0 == 0) {
		app.navTree_Menu.init();
		app.navTree_Index.init();
		app.navTree_Search.init();

		if (app.tabController.isMenuTabShown())
			app.navTree_Menu.show();
		if (app.tabController.isIndexTabShown())
			app.navTree_Index.show();
	} else {
		var $hc = $("#hiddenContent");
		$hc.detach();
		$hc.removeClass("hiddenContent");
		$hc.appendTo("#description_on_page_placeholder");
		$("iframe").each(function () {
			$(this).prop("src", $(this).prop("real_src"));
		});
	}
	app.searchManager.doBindEvents();
	app.searchManager.doSearchIfQueryStringNotEmpty();
	app.workZoneSizer.doBindEvents();
	app.workZoneSizer.recalculateAll();
	app.tabController.doSetScrollTopByUrlEncoder();

	if (0 == 0 || is_touch_device())
		initResizeArticleArticle();
});