/*
 * Copyright (c) 1995-2015 by 4system Polska Sp. z o.o.
 * All Rights Reserved. v4
 */
if (typeof(moduleDone) != "undefined") moduleDone("page.js");
//consts
STEPS_HIDDEN = -1;
STEPS_LAST_STEP = -2;
if (typeof(log) != 'undefined') log.info("Location: " + location.href);
var ANS_SEP = '#|#'; //pg2

function getPageUrl() {
	var href = location.href; 
	if (!is.ie) {
		var ind = href.indexOf(':');
		var protocol = href.substring(0, ind+2);
		href = href.slice(ind+2, href.length);
		href = protocol+ escape(href); //pg2- w przyp. Firefox i narodowych znakow w sciezce np. offline- nie dzialaja komponenty - location.href zwraca encodeURI() a nie jak w IE zwykla sciezke
	};

	var index = href.indexOf('?');
	if (index > 0) {
		href = href.substr(0, href.indexOf('?'));
	};
	var index = href.lastIndexOf("/");
	if (index > 0) {
		href = href.substr(0, index);
	};
	return href + '/';
};

function getPagesUrl()
{
	var href = location.href;
	if (!is.ie) {
		var ind = href.indexOf(':');
		var protocol = href.substring(0, ind+2);
		href = href.slice(ind+2, href.length);
		href = protocol+ escape(href); //pg2- w przyp. Firefox i narodowych znakow w sciezce np. offline- nie dzialaja komponenty - location.href zwraca encodeURI() a nie jak w IE zwykla sciezke
	};

	var index = href.indexOf('?');
	if (index > 0) {
		href = href.substr(0, href.indexOf('?'));
	};
	var index = href.lastIndexOf("/pages/");
	if (index > 0) {
		href = href.substr(0, index + "/pages/".length);
	};
	return href;
};

function getExtrasUrl()
{
	var href = getPagesUrl() + "extras/";
	return href;
};

function urlCanonicalize(url, absolute)
{
	if (!absolute) return unescape(url);
	
	//pg2-BM_lex_long_keywords_extras -fix pageURL for good
	var qmPos = pageURL.indexOf('%3F');
	if (qmPos > -1) {
		pageURL = pageURL.substring(0,qmPos-1);
		qmPos = pageURL.lastIndexOf('/');
		if (qmPos != pageURL.length) {
			pageURL = pageURL.substring(0,qmPos+1);
		};
	};
	//---
	var a_url = pageURL;
	var a_url_arr = a_url.split('/');
	while (a_url_arr[a_url_arr.length - 1] == "") {
		a_url_arr.splice(a_url_arr.length - 1, 1);
	};
	var srch = '../';
	while (url.indexOf(srch) > -1) {
		a_url_arr.splice(a_url_arr.length - 1, 1);
		url = url.substr(0, url.indexOf(srch)) + url.substr(url.indexOf(srch) + srch.length, url.length);
	};
	a_url = "";
	for (var i=0; i<a_url_arr.length; i++) {
		a_url += a_url_arr[i] + "/";
	};
	url = a_url + url;
	//pg2-BM_lex_long_keyword_extras
	if (url.indexOf('/pages/extras/resources/') > -1) url = url.replace('/pages/extras/resources/', '/pages/resources/');
	
	//pg2- aby we Firefox dzialal offline w przyp. sciezki ze znakami narodowymi
	if (!is.ie && lms.name == "lmsOffline") {
		return (decodeURI(unescape(url))); 
	} else {
		return (unescape(url));
	};
};

function replaceWBTProtocol(url)
{
	return validateURL(url);
};

var me = new Array();
var sys = new Array();
var pageURL = getPageUrl();

Vars = function() {};

Vars.prototype.get = function(struct)
{
	var result = new Array();
	for (var k in struct) {
		var val = struct[k].toString();
		val = val.replace(/,/g, "%2C");
		val = val.replace(/#/g, "%23");
		val = val.replace(/=/g, "%3D");
		val = val.replace(/\|/g, "%7C");
		result[result.length] = val;
	};
	return result.toString();
};

Vars.prototype.getExt = function(struct)
{
	var result = new Array();
	for (var k in struct) {
		var val = struct[k].toString();
		val = val.replace(/,/g, "%2C");
		val = val.replace(/#/g, "%23");
		val = val.replace(/=/g, "%3D");
		val = val.replace(/\|/g, "%7C");
		result[result.length] = k + "#" + val;
	};
	return result.toString();
};

Vars.prototype.set = function(struct, v)
{
	if (typeof(v) != "string" || v == "") return;
	var arr = v.split(",");
	var i = 0;
	for (var k in struct) {
		struct[k] = unescape(arr[i++]);
		if (i >= arr.length) break;
	};
};

Vars.prototype.setExt = function(struct, v)
{
	if (typeof(v) != "string" || v == "") return;
	var arr = v.split(",");
	var i = 0;
	for (var i=0; i<arr.length; i++) {
		var k = unescape(arr[i].substr(0, arr[i].indexOf("#")));
		var val = unescape(arr[i].substr(arr[i].indexOf("#") + 1, arr[i].length));
		struct[k] = val;
	};
};

Vars.prototype.init = function(v)
{
	var result = new Array();
	for (var k in v) {
		result[k] = v[k];
	};
	return result;
};

Vars.prototype.load = function(struct, name, init)
{
	if (typeof(lms.getCourseDataSD) == 'function') { //pg2-multi_me
		var v = lms.getCourseDataSD(name);
	} else {
		var v = lms.getCourseData(name);
	};
	if (v != null) {
		if (init) this.setExt(struct, v); else this.set(struct, v);
	};
};

Vars.prototype.save = function(struct, name, init)
{
	var s = "";
	if (init) s = this.getExt(struct); else s = this.get(struct);
	if (typeof(lms.setCourseDataSD) == 'function') { //pg2-multi_me
		lms.setCourseDataSD(name, s);
	} else {
		lms.setCourseData(name, s);
	};
};

vars = new Vars();

WBTESelection = function()
{
	this.bookmark = null;
	this.color = "#000000"
};

MarkersItem = function()
{
	this.id = null;
	this.selections = null;
};

function interfacesInitialize()
{
	try { //pg2-
		if (!page) {
			page = getPage();
			if (!page) pageInitialize();
		};
	} catch(e) {};

	PageInterface.Initialize(page);
	PlayerInterface.Initialize(page);
	PlayerInterface.Execute("loadLMS");
};

function interfacesTerminate()
{
	if (typeof(PageInterface) != "undefined" && PageInterface.Terminate) {
		PageInterface.Terminate(page);
	};
	if (typeof(PlayerInterface) != "undefined" && PlayerInterface.Terminate) {
		PlayerInterface.Terminate(page);
	};
};

resourcesURL = '';
page = null;
pageWBT = null;

function pageInitialize()
{
	if (typeof(log) != 'undefined') log.info("pageInitialize begin");
	if ((this.__wbtlinfo == 0 || this.__wbtlinfo == 2) && (lms.name == "lmsScorm") && (typeof(top.isWBTServer) == 'undefined')) {
		lms = new dummyLMSManager();
	} else {
		lms = new LMSManager();
	};
	var allowSeparateWork = false;
	if (getCommandUrl("asw") == "1") {
		allowSeparateWork = true;
	};
	var uelo = getUELO(); //pg2-secured from exception if in some case uelo object won't be found
	if (uelo) {
		project.pageIsHidden = uelo.IsHidden(project.pageGlobalIndex); //pg2-new
		//project.pageIsHidden = getUELO().IsHidden(project.pageGlobalIndex); //pg2-removed (AW)
	} else project.pageIsHidden = false;
	
	
	var allowCommunicationVar = !(allowSeparateWork || (project.pageIsHidden && !config.sendDataFromHiddenPages));
	if (allowCommunicationVar) {
		lms.initialize();
	};
	page = new componentPage();
	pageWBT = page; //pg2-prov_moodle_new_test
	page.setID("page01");
	page.allowSeparateWork = allowSeparateWork;
	page.is_hidden_page = project.pageIsHidden;
	if (typeof(log) != 'undefined') log.info("pageInitialize end lms.name=" + lms.name);
	var sd = getSuspendData();
	if (sd) {
		me = sd.me;
		sys = sd.sys;
	} else {
		me = vars.init(config.meVars);
		vars.load(me, "me");
		sys = vars.init(config.sysVars);
		vars.load(sys, "sys"); 
	};

	//pg2- we can not use it, 'cause in multiSCO, exam - pages' visited status isn't stroed and at pages with ActiveXAudioRecorder - must be invoked unload of ocx control
	//if ((is.ie6 || is.ie7) && (checkExportType(config.exportDetails, "multi")))
	//{
		//document.body.onbeforeunload = document.body.onunload; //pg2- in case of exam or multi sco, in ie6/7, when you'll start it, then Alt+Tab, click in (ex) Notepad, Alt+Tab, return to course, fast click on OK...and "out of memory"
		//document.body.onunload = null;
	//}
};

function pageCreate()
{
	if (typeof(log) != 'undefined') log.info("Page create begin");
	if (config.disableRightClick) {
		document.body.oncontextmenu = function(e) {return false;};
	};

	page.preloadState=1;
	page.skipFirstStep=0;
	page.skipLastStep=0;
	page.p_index = project.pageIndex;
	page.p_globalIndex = project.pageGlobalIndex;
	page.p_pageName = project.pageName;
	page.is_hidden_page = project.pageIsHidden;
	if (getCommandUrl("asw") == "1") {
		page.allowSeparateWork = true;
	};
	page.create();
	page.showFreeWatermarks();
	if (typeof(log) != 'undefined') log.info("Page create end");
};

function clearOFTable()
{
	for (var k in __of) {
		if (typeof(__of[k]) == "object") {

			for (var i in __of[k]) {
				if (typeof(__of[k][i]) == "object" || typeof(__of[k][i]) == "function" || typeof(__of[k][i]) == "array" || typeof(__of[k][i]) == "string") {
					__of[k][i] = null;
					delete __of[k][i];
				};
			};
			__of[k] = null;
			delete __of[k];
		};
	};
};

var __of = new Array();

function pageDestroy()
{
	if (typeof(log) != "undefined" && log) log.info("Page destroy begin");
	var allowCommunicationVar = true;
	if (typeof(page) != "undefined" && page) {
		allowCommunicationVar = page.allowCommunication();
		page.free();
	};
	if (typeof(lms) != "undefined" && lms) {
		if (allowCommunicationVar) lms.free();
	};
	interfacesTerminate();
	document.body.onunload = null;
	if (project) project.font = null;
	WBTObject.all = null;
	clearOFTable();
	delete WBTObject.all;
	pc = null; 	delete pc;
	__of = null; delete __of; 
	action = null; delete action;
	is = null; delete is;
	config = null; delete config;
	log = null; delete log;
	lms = null; delete lms;
	dictionary = null; delete dictionary;
	grammar = null; delete grammar;
	lexicon = null; delete lexicon;
	PageInterface = null; delete PageInterface;
	PlayerInterface = null; delete PlayerInterface;
	mouseEvent = null; delete mouseEvent;
	udf = null; delete udf;
	page = null; delete page;
};

function setAdditionalStyles4AllChildren_Unselectable(obj, value) //pg2-set those styles to all elements - in Safari, moving imageWithBlanks' elements causes select of all divs
{
	if (!obj) return;
	try {
		//var value = "none"; //pg2-input 4 iPad
		if (typeof(value) == 'undefined') value = 'none';
		if (is.mobile) value = "auto";
		try {
			if (obj.type && (obj.type == 'componentInput' || obj.type == 'componentTextarea')) value = 'auto';
		} catch(e) {};
		//...
		obj.style.userSelect = value; //"none";
		obj.style.MozUserSelect = value; //"none";
		obj.style.KhtmlUserSelect = value; //"none";
		obj.style.WebkitUserSelect = value;  //"none";
		obj.style.OUserSelect = value; //"none";
		if (obj.contentObj) setAdditionalStyles4AllChildren_Unselectable(obj.contentObj, value); //pg2-input 4 iPad

		for (var i=0; i<obj.children.length; i++) {
			var obj2 = obj.children[i];
			if (obj2) setAdditionalStyles4AllChildren_Unselectable(obj2);
		};
	} catch(e) {
		alert('error: ' + e.message);
	};
};

componentPage = function()
{
	if (typeof(log) != 'undefined') log.info("componentPage begin");
	this.connected = false;
	this.p_index = -1;
	this.p_globalIndex = -1;
	this.p_pageName = "";
	this.doc = self.document;
	this.body = this.doc.body;
	this.style = null;
	this.obj = null;
	this.filters = null;
	this.style = (is.ns4) ? self : null;
	if (is.ie) {
		this.style = this.body.style;
		try {
			this.filters = this.body.filters;
		} catch(e) {
			this.filters = null;
		};
	};
	this.obj = (is.ns4) ? self : null;
	this.startTime = null;
	this.WBTObject = WBTObject;
	this.WBTObject();
	this.feedbackOkName = "feedbackOk";
	this.feedbackBadName = "feedbackBad";
	this.feedbackLastBadName = "feedbackLastBad";
	this.feedbackNotOkName = "feedbackNotOk";
	//variables
	this.countAnswers = 2;
	this.grantedAnswers = 0;
	this.maxScore = 100;
	this.masteryScore = 100;
	this.userScore = 0;
	this.allowGetMaxScore = false;
	this.isMulti = checkExportType(config.exportDetails, 'multi');
	//counters
	this._countAnswers = 2;
	this._countQuestion = 0;
	this._countCorrectQuestion = 0;
	this._countAnswerQuestion = 0;
	this._showCorrectAnswerIndicator = false;
	this.tryNumber = 0;
	this.reductionScoring = false;
	this.pageScroll = null;
	this.pageType = "Information";
	this.isExam = false;
	this.name = "";
	this.pageWidth = 800;
	this.pageHeight = 600;
	this.autoNextPage = false;
	this._loaded = false;
	this.isRuning = false;
	this.stepsRunAutomate = true;
	this.stepIndex = 0;
	this.stepsTimer = null;
	this.stepTime = 0;
	this.steps = new Array();
	this.expoType = 0;
	this.pageIndex = null; // use only with AICC comunication
	this.all = WBTObject.all;
	this.previewElementsInStep = "";
	this.previewElementsInStepTo = false;
	this.previewShowHiddenElements = true;
	this.prepareNextStep = true;
	this.pageStatus = "not attempted";
	this.initPageStatus = "not attempted";
	this.terminated = false;
	this.solved = false;
	this.passed = false;
	this.paintIncorrectCAI = true;
	this.offsetLeft = 0;
	this.offsetTop = 0;
	this.offsetRight = 0;
	this.offsetBottom = 0;
	this.lockElementsAfterGivenAnswer = true;
	this.checkHiddenElementsAnswer = false;
	this.warning_NO_ACTIVEX_ERROR_Showed = false;
	this.locked = false;
	this.tempShowCorrectAnswerIndicator = false;
	this.groups = new Object();
	this.groupsNames = new Object(); //pg2-groups_names -with .shGroup() action- there are still used names in 'shGroup()' action
	this.enableSelection = false;
	this.selectionColor = "#FF00FF";
	this.storedSelections = new Array();
	this.typingSLWComponentID = "";
	//this.focusedInput = ""; //pg2-removed, 'lastFocusedInput' is now in use //pg2-remove focus from input
	this.ignoreKeyPressActions = false;
	this.cursorX = 0;
	this.cursorY = 0;
	this.debugString = '';
	this.preloadState = 0;
	this.stopPageSteps = false;
	this.pageIsShow = false;
	this.allowPreload = true;
	this.waitingForRun = false;
	this.pageIsCreated = false;
	this.pageVisited = false;
	this.keydownListeners = new Array();
	this.warningPopupID = "__warningPopup1";
	this.endLessonPopupID = "__warningPopup2";
	this.offsetAlreadyInitialized = false; //pg2- if preloader is enabled, do not calculate this again- only if it's for the first time or page was removed from preloader's set
	this.hideFeedbacksTimer = null;
	//this.stepFirstInputFocus = null; //pg2-removed, 'lastFocusedInput' is now in use //pg2-remove focus from input
	this.isExec = false;
	this.lastFocusedInput = null; //pg2-remove focus from input
	this.repeatModeFirstPage = false;
	this.repeatModeLastPage = false;
	//stepbystep
	this.sbsStagePassed = false;
	this.sbsLastExerciseStep = -1;
	this.sbsLastStepLocked = -1;
	this.allowResetAction = true; //pg2-while page unloading, if 'onUnLoad' will be invoked, resetPage() and refreshPage() could be invoked from action - it will be blocked to avoid situation that after page close, its statuses (completion, exercises score) will be removed
	this.tabOverrideComponent = null; //pg2-aps
	this.resetTabComponent = null; //pg2-aps_test
	this.focusTimer = null;
	this.componentFlashChecked = null; //pg2-aps_test
	this.componentFlashUnchecked = null;
	this.invokeClearForExerciseComponents = false; //pg2- in case of inputs with 'clearIncorectAnswer=1', answer is cleared, then interaction is build and... user answer is empty (only if some chances are left)
	this.navigationStarted = true; //pg2- it will be false after page is loaded
	this.inactivityPopup = null; //pg2-inactivity_control
	this.showConfirmation = true; //wl - 201401 for config.temp_BSH201401
	
	this.integrateWithStepsEl = null; //pg2-BI_stepsIntegration
	this.integrateWithStepsLockUpdate = false; //pg2-BI_stepsIntegration -to distinguish between event from page and from trackbar
	
	//pg2-UR_miniStatistics
	this.visibleItemsIndex = -1;
	this.visibleItemsCount = -1;
	this.totalScore = -1;
	this.possibleScore = -1;
	this.chapterNumbering = -1;
	this.currentCompletionProgress = -1;
	this.currentPageNumber = -1;
	this.totalPagesNumber = -1;
	this.studentName = '';
	this.computerName = '';
	this.points = -1;
	this.passingScore = -1;
	//...
	
	if (typeof(log) != 'undefined') log.info("componentPage end");
};

componentPage.prototype = new WBTObject();

componentPage.prototype.type = "componentPage";

var psNormal=0;
var psDesigning=1;
var psPreview=2;
var psView=3;
componentPage.prototype.state = psNormal;
var firstWait = false;

componentPage.prototype.gotoPage = function(globalIndex, pageNum, pageIndex, pageName, projectName)
{
	if (this.navigationStarted) return; //pg2-prevent from double click on next/prevPage
	this.navigationStarted = true;
	//
	if (!this.sendDataToLMSOnline()) { //pg2-BI_iPad_connection
		this.navigationStarted = false;
		return;
	};
	
	if (typeof(this.onUnLoad) == 'function') { //pg2-if there is '.actionCheckAnswer()' in 'onUnLoad' event, it won't be invoked 'cause navigation has started, so do nothing and check answer here
		var s = this.onUnLoad.toString();
		if (s.indexOf('.actionCheckAnswer') > -1) {
			s = s.replace(new RegExp('.actionCheckAnswer', "g"), '.doNothing'); //s = s.replace(new RegExp('.actionCheckAnswer', "g"), '.checkAnswer');
			var f;
			eval("f=" + s);
			this.onUnLoad = f;
			this.checkAnswer();
		};
	};
	
	if (config.DetectBrokenConnection) { //pg2-BV
		//this.navigationStarted = false;
		var imgID = 'testConectionImage';
		var imageCheckConnectionName = 'check_connection_image.gif';
		var imgSrc = resourcesURL + imageCheckConnectionName + '?' + (+new Date);
		var imgObj = document.getElementById(imgID);
		
		if (imgObj) {
			var detectProgressName = 'detectConnectionProgressPopup';
			var progressComp = getComponentByPartialId(detectProgressName);
			if (progressComp) {
				progressComp.show();
				progressComp.bringToFront();
			};
			
			imgObj.onload = function() {
				try {
					var p = getPage();
					if (p) {
						if (p.pageType == 'Poll') p.checkAnswer();
						if (sys) sys.backToPage = p.p_globalIndex;
						if (lms) return (lms.gotoPage(globalIndex, pageNum, pageIndex, pageName, projectName));
					};
				} catch(e) {};
			};
			imgObj.onerror = function() {
				try {
					var p = getPage();
					if (p) {
						p.brokenConnectionInfoShow();
					};
				} catch(e) {};
			};
			imgObj.src = imgSrc;
			return;
		};
	};
	//
	sys.backToPage = this.p_globalIndex;
	if (this.pageType == 'Poll') this.checkAnswer(); //pg2-it was in nextPage,prevPage, wasn't in here
	if (lms) return (lms.gotoPage(globalIndex, pageNum, pageIndex, pageName, projectName));
	return false;
};

componentPage.prototype.backToPage = function()
{
	var gidx = sys.backToPage;
	sys.backToPage = "";
	if (lms) return (lms.gotoPage(gidx));
	return false;
};

componentPage.prototype.isAppServ = function()
{
	return lms.name == "LMSApp" && this.state == psView;
};

componentPage.prototype.allowCommunication = function()
{
	var result = !(this.allowSeparateWork || (this.is_hidden_page && !config.sendDataFromHiddenPages))
				|| (this.is_hidden_page && this.navigationStarted) //pg2-bsh -if page is hidden and user invokes next/prevPage, allow it
				|| (this.is_hidden_page && this.allowSeparateWork && config.sendDataFromHiddenPages && !this.navigationStarted); //pg2-pcen_courseTree_navi_from_hidden_page
	return result;
};

componentPage.prototype.loadContent = function()
{
	if (!this.pageIsCreated) return;	
	//pg2-qr -check parameters, and if course has mixed structure, currently loaded page is in drawed pool and none of those pages was in this session visited- reset all pages in drawed pool
	if (PlayerInterface) PlayerInterface.CompleteInitialization(); //pg2-speed up
	//displayCheckingConnectionIcon(false); //pg2-BI_iPad_connection_test
	var isMixed = false;
	var wasSolved = false;
	var isCurrentInPool = false;
	var pUeloStatus = 'C';
	if (PlayerInterface.connectedStruct && PlayerInterface.connectedPlayer) {
		isMixed = PlayerInterface.connectedStruct.isCourseMixed;
		if (isMixed) { //otherwise, it's not necessary to invoke a method that scans all pages
			wasSolved = PlayerInterface.connectedPlayer.checkExamWasSolved();
			isCurrentInPool = PlayerInterface.isQuizPageToReset(this.p_globalIndex);
			pUeloStatus = PlayerInterface.getUeloPageStatus(this.p_globalIndex); //pg2-qr-completion -sometimes (propably preloader after several rebuilding operations) page in pool isn't reseted
		};
	};

	if (config.resetExercisePages) {
		this.clearAnswer();
	};

	this.waitingForRun = false;
	var startpage = findFrame('startpage', top);
	if (startpage && startpage.isFirstPage) {
		this.stopPageSteps = true;
		startpage.coursePage = page;
	};

	if (this.stepByStepExercise) {
		this.reductionScoring = false;
	} else {
		this.reductionScoring = config.reductionScoring;
	};

	if (this.reductionScoring) {
		this.masteryScore = Math.floor(this.maxScore / this.countAnswers);
	};

	this._countAnswers = this.countAnswers;
	this._showCorrectAnswerIndicator = this.showCorrectAnswerIndicator;
	this.tempShowCorrectAnswerIndicator = this.showCorrectAnswerIndicator;
	this.stepsRunAutomate = this.automateStepsRun && !this.stepByStepExercise;

	if (config.slwrecmode == true) {
		this.stepsRunAutomate = true;
		this.skipFirstStep = 1;
		this.skipLastStep = 1;
	};
	PlayerInterface.Execute("initializeUELOVars", true);
	this.preloadState = 0;
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].p_checkMarkers) this.children[i].repaint();
	};
	var userHasChances = PlayerInterface.GetValue("userHasChances");
	if (userHasChances) {
		this.showCorrectAnswerIndicator = false;
	} else {
		this.showCorrectAnswerIndicator = (((config.rememberAnswers || this.rememberAnswer) || this.state == psView) && this.showCorrectAnswerIndicator) ? true : false;
		this.tempShowCorrectAnswerIndicator = this.showCorrectAnswerIndicator;
	};
	if (this.state == psDesigning || this.state == psPreview) {
		for (var i=0; i<this.children.length; i++) {
			var obj = this.children[i];
			if (this.state == psDesigning) obj.show(); else obj.paint();
		};
	} else
	if (!this.offsetAlreadyInitialized) { //pg2- if preloader is enabled, do not calculate this again- only if it's for the first time or page was removed from preloader's set
		this.offsetInit();
		this.offsetDraw();
	};
	if (udf && udf.loadPage) udf.loadPage(this);
	if (this.pageType != 'Exercise') {
		PlayerInterface.SetValue("setPoints", "");
	} else {
		var points = PlayerInterface.GetValue("getPoints");
	};
	//this.checkPageVisited(); //pg2-moved below
	this.setPageStatus(PlayerInterface.GetValue("getStatus"));
	this.initPageStatus = this.pageStatus;
	this.checkPageVisited(); //pg2- now it depends of pageStatus
	if (this.pageStatus == null) this.pageStatus = "not attempted";
	var pagePassed = this.checkLastVisitPageWasPassed();
	this.setPagePassed(pagePassed);
	var pageSolved = ((this.pageType == "Exercise") && (pagePassed || !userHasChances)); //kr- //pg2-comment -previously here was  this.getPagePassedFromUELO(); 
	this.setPageSolved(pageSolved);

	if (this.pageStatus == PlayerInterface.GetValue("getConst", "STATUS_NOT_ATTEMPTED")) {
		PlayerInterface.SetValue("setStatus", PlayerInterface.GetValue("getConst", "STATUS_INCOMPLETE"));
	};

	PlayerInterface.Execute("initializeUELO", (this.pageType == 'Poll' || this.pageType == 'Exercise') && !this.getPageSolved());

	for (var i=0; i<this.children.length; i++) {
		this.children[i].isCreated = true;
		this.children[i].actionOn = true;
		this.children[i].unselectable();
		this.children[i].invokeEvent("PageReady");
	};
	var pageTryNumber = parseInt(PlayerInterface.GetValue("pageTryNumber"));
	if (pageTryNumber > -1) this.setTryLeft(pageTryNumber);

	PlayerInterface.Execute("initializeYellowCards");
	PlayerInterface.Execute("pageReady");
	PlayerInterface.SetValue("setTextMarkers");
	if (this.allowMarkTexts) {
		this.loadMarkers();
	};
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].load) this.children[i].load();
		this.children[i].invokeEvent("Load");
	};
	this.invokeEvent("Load");
	//this.pageIsShow = true; //pg2-aps -moved below (at the end of the method)

	var p = PlayerInterface.connectedUELO.FindPage(this.p_globalIndex);
	if (typeof(p) != 'undefined' && p != null && typeof(p.visitedCount) != 'undefined') p.visitedCount++;

	//pg2-qr
	var allowResetPage = false;
	var allowShowAnswer = true;
	if (isMixed && wasSolved == false && isCurrentInPool && PlayerInterface.connectedUELO) { //pg2-qr -reset all pages in pool, but just once and if none of those pages weren't visited/solved. Next page reset while next visit on page(s) depends of 'config.resetExercisePages'
		PlayerInterface.connectedUELO.resetAllPagesInPool(this.p_globalIndex);
		allowResetPage = true;
		allowShowAnswer = false;
	} else
	if (isMixed && isCurrentInPool && pUeloStatus == 'N') allowResetPage = true; //pg2-qr-completion -sometimes (propably preloader after several rebuilding operations) page in pool isn't reseted
	if (isMixed && wasSolved && isCurrentInPool) {
		allowShowAnswer = this.checkBlockAttempts();
	};
	//pg2-pga -back2PageReset
	if (PlayerInterface.connectedPlayer) {
		if (typeof(PlayerInterface.connectedPlayer.deleteBackToPageAddress) != 'undefined' && PlayerInterface.connectedPlayer.deleteBackToPageAddress == true) {
			PlayerInterface.connectedPlayer.deleteBackToPageAddress = false;
			sys.backToPage = '';
		};
	};
	//
	if (this.state == psView || this.state == psNormal) {
		var navigationStartedBackup = this.navigationStarted; //pg2-temp. change it (otherwise reset won't be invoked)
		this.navigationStarted = false;
		if (this.pageType == "Exercise") {
			//if (config.resetExercisePages || PlayerInterface.isQuizPageToReset(this.p_globalIndex)) { //pg2-bsh quiz -reset page also after drawing action, otherwise elments will be locked //pg2-qr -replaced with below one
			if (config.resetExercisePages || allowResetPage) { //pg2-qr -new
				this.resetPage(true);
				//this.isExec = !allowResetPage; //true; //pg2-qr -test //pg2-removed-mdk
			} else
			if (this.checkBlockAttempts()) {
				this.runCompleted();
				this.isExec = true;
			};
		};
		if (!this.isExec && !this.stopPageSteps) {
			this.runSteps();
		} else {
			this.stepIndex = this.steps.length; //pg2- according to aw, it is needed, but in this case, line marked as 'pg2-removed-mdk' can not be active
		};
		this.navigationStarted = navigationStartedBackup; //pg2-restore (to prevent 'OnLoad -> Reset/Refresh')
	};

	if ((this.state == psNormal || this.isAppServ()) && /*!config.resetExercisePages &&*/ 
		this.pageType != "Information" && !allowResetPage && allowShowAnswer && //pg2-qr -do not try to set answer, 'cause page is in quiz block
//		this.pageType != "Poll" && //pg2-in this case, reset previous answer
		(config.rememberAnswers || this.rememberAnswer))
	{
		this.setUserAnswer();
	};
	/*else i f (checkExportType(config.exportDetails, 'poll')) { //pg2-test
		if (this.pageType == 'Poll') {
			this.resetPage(true);
		}
	}*/
	switch (this.pageExtrasType) {
		case "lexicon":
			if (lexicon) lexicon.setActiveKey(unescape(getCommandUrl("key")));
			break;
		case "dictionary":
			if (dictionary) dictionary.setActiveKey(unescape(getCommandUrl("key")));
			break;
		case "grammar":
			if (grammar) grammar.setActiveKey(unescape(getCommandUrl("key")));
			break;
	};
	if (sys.repMode=="on") {
		var p2r = PlayerInterface.connectedUELO.FindPage(sys.repBackPage).pagesToRepeat;
		if (p2r.length >= 1) {
			this.repeatModeFirstPage = p2r[0] == this.p_globalIndex;
			this.repeatModeLastPage = p2r[p2r.length-1] == this.p_globalIndex;
		};
	};
	
	/*if (config && config.SetPassedAndCompletedAtTheEnd) { //pg2
		var player = getPlayer();
		if (player) {
			if (player.lastPageGIX == -1) player.findLastPageGIX();
			if (player.lastPageGIX == this.p_globalIndex) player.setCourseCompletedAndPassed(true);
		};
	};*/
	
	if (!config.disableRightClick) this.setSelectionEnable(); else this.setSelectionDisable(); //pg2-context_menu_ON-OFF -'config.disableRightClick' sets page.enableSelection, now it's independend within page from config's property
	
	for (var i=0; i<this.children.length; i++) {
		var child = this.children[i];
		child.invokeEvent("AfterLoad"); //pg2-child instead of this.children
		
		if (typeof(child.integrateWithSteps) != 'undefined' && child.type == 'componentTrackBar' &&
			child.integrateWithSteps == true && this.integrateWithStepsEl == null) this.integrateWithStepsEl = child; //pg2-BI_stepsIntegration
		
		try { $EL.eshPageInit(child); } catch(e) {}; //pg2- try-catch, child instead of this.children
	};
	if (!(this.pageType == "Exercise" && (config.resetExercisePages || allowResetPage))) this.invokeEvent("AfterLoad");
	
	if (this.pageVisited) {
		this.invokeEvent("Visited");
	};
	PlayerInterface.SetValue("setPageVisited"); //pg2-ewspa
	//kr - turn off preloader in SLW mode - keyboard listening
	this.allowPreload = (this.recordedInSLW == this.isSLWPresentation);
	this.isRuning = true;

	//pg2- if option is checked, then COMPLETED status is set (only Information page type, or incoplete Exercise page) for a page at its startup
	if (config) {
		if (config.setCompleteStatusAtPageStartup) { // && lms.name != "lmsExam") { //pg2-test
			if (this.pageType == "Information") {
				this.setPageStatus("completed");
			} else
			if (this.pageType == "Exercise") {
				if (this.pageStatus != "passed" && this.pageStatus != "failed") this.setPageStatus("completed");
			};
		};
	};
	if (is.safari) setAdditionalStyles4AllChildren_Unselectable(this); //pg2-read description near definition of the function

	if (config.keyboardNavigation || config.FireOnClickOnReturnKey || (this.state == psView || (typeof(config.DebugMode) != 'undefined' && config.DebugMode))) {
		addKeyDownListener(this.id); //pg2-add navigation via Ctrl and arrows: left (previous page) and right (next page) //checkExportType(config.exportDetails, 'multi')
	};
	this.pageIsShow = true; //pg2-aps -moved here

	PlayerInterface.Execute("pageLoaded");
	PlayerInterface.Execute("debugCourse");
	if (config && config.FocusManegementForSynthesizer) {
		this.setupFocused();
		this.startFocusTimer(); //pg2-aps, instead of plain 'setTimeout' without savin its pointer
		this.processRadiobuttons(); //pg2-aps_test
	};

	if (config.inactivityEnabled) PlayerInterface.SetValue("studentActive"); //pg2-knf -inactivity timer
	this.navigationStarted = false; //pg2-prevent from double click on next/prevPage //pg2- moved to the beginning
	if (typeof(config) != 'undefined' && config.showPageInLastStepAtStartup) {
		try { //pg2-internal
			this.goToChosenStep(this.steps.length);
		} catch(e) {};
	};
	
	if (config && config.SetPassedAndCompletedAtTheEnd) { //pg2-moved here so in case of last page being 'exercise' it would be set as well
		var player = getPlayer();
		if (player) {
			if (player.lastPageGIX == -1) player.findLastPageGIX();
			if (player.lastPageGIX == this.p_globalIndex) player.setCourseCompletedAndPassed(true);
		};
	};
	this.navigationStarted = false; //pg2-knf_completion\
	this.stepsIntegrationExecute('init'); //pg2-BI_stepsIntegration
	this.sendLessonLocation() //pg2-BI_iPad_onunload
};

componentPage.prototype.stepsIntegrationExecute = function(command, value) //pg2-BI_stepsIntegration
{
	if (this.integrateWithStepsEl == null || typeof(command) == 'undefined' || command == '') return;
	if (this.integrateWithStepsLockUpdate) { //do not update if event was invoked by trackbar itself
		this.integrateWithStepsLockUpdate = false;
		return;
	};
	var obj = this.integrateWithStepsEl;
	if (command == 'init') {
		obj.position = 0; //this.stepIndex
		obj.positionStep = 1;
		obj.positionMin = 0;
		obj.oldPosition = -1; //pg2-BI_stepsIntegration2 -without it, sometimes it ain't working
		obj.positionMax = this.steps.length-2;
		obj.paint();
	} else
	if (command == 'update') {
		obj.position = this.stepIndex-1;
		obj.paint();
	} else
	if (command == 'setStep' && typeof(value) != 'undefined') {
		value = parseInt(value);
		if (value >= 0 && value <=this.steps.length-2) {
			this.integrateWithStepsLockUpdate = true;
			this.goToChosenStep(value);
		};
	};
};

componentPage.prototype.processRadiobuttons = function(tryToPlayAudioCheckedUnchecked, elementState) //pg2-aps
{
	if (typeof(tryToPlayAudioCheckedUnchecked) == 'undefined') tryToPlayAudioCheckedUnchecked = false;
	var pElem = null;
	var obj = null;
	var objTextDiv = null;
	var objImgDiv = null;
	var optionText = '';
	var checkedStr = ' <font style="color: #FFFFFF"> odpowiedź jest zaznaczona</font>';
	var uncheckedStr = ' <font style="color: #FFFFFF"> odpowiedź jest odznaczona</font>';
	var checkedStrAlt = ' odpowiedź jest zaznaczona';
	var uncheckedStrAlt = ' odpowiedź jest odznaczona';
	for (var i in pc) {
		pElem = pc[i];
		if (pElem && (pElem.type == 'componentRadioButton' || pElem.type == 'componentCheckBox')) { //pg2-aps_test -todo -dodac checkbox 'componentCheckBox'
			optionText = pElem.answerValuesString;
			objTextDiv = document.getElementById(pElem.id + '_textDIV_contentObj');
			if (objTextDiv && objTextDiv.innerHTML != '&nbsp;') {
				if (pElem.checked) objTextDiv.innerHTML = pElem.answerValuesString + checkedStr;
				else objTextDiv.innerHTML = pElem.answerValuesString + uncheckedStr;
			} else {
				objImgDiv = document.getElementById(pElem.id + '_contentObj');
				if (objImgDiv) {
					if (pElem.checked) objImgDiv.alt = pElem.obj.title + checkedStrAlt;
					else objImgDiv.alt = pElem.obj.title + uncheckedStrAlt;
				};
			};
		} else
		if ((this.componentFlashChecked == null || this.componentFlashUnchecked == null) && (pElem && pElem.type == 'componentFlash')) {
			if (pElem.id.indexOf('flash_checked') > -1) this.componentFlashChecked = pElem; else
			if (pElem.id.indexOf('flash_unchecked') > -1) this.componentFlashUnchecked = pElem;
		};
	};
	
	if (typeof(elementState) != 'undefined' && tryToPlayAudioCheckedUnchecked && page.componentFlashChecked != null && page.componentFlashUnchecked != null) {
		page.componentFlashChecked.clearObject(); //hide();
		page.componentFlashUnchecked.clearObject(); //hide();
		if (elementState) page.componentFlashChecked.show(); else page.componentFlashUnchecked.show();
	};
};

componentPage.prototype.stopFocusTimer = function() { //pg2-aps
	if (this.focusTimer != null) clearTimeout(this.focusTimer);
	this.focusTimer = null;
};

componentPage.prototype.killFocusTimer = function() { //pg2-aps
	if (this.focusTimer != null) window.clearTimeout(this.focusTimer);
	this.focusTimer = null;
	this.tabOverrideComponent = null;
};

componentPage.prototype.startFocusTimer = function(debugInfo) { //pg2-aps
	if (!config || !config.FocusManegementForSynthesizer) return;
	this.stopFocusTimer();
	if (typeof(debugInfo) == 'undefined') debugInfo = 0;
	this.focusTimer = window.setTimeout( function() { page.setFocusOnFirstTabIndex(debugInfo); }, 1000 );
};

componentPage.prototype.getNextElementToBeFocused = function(elem) { //pg2-TEST_EM -focus on input (it was set to its 'obj' and not main div- so cursor was hidden
	if (elem == null || typeof(elem) == 'undefined') return null;
	if (elem.obj.tabIndex == '') return null;
	var currentElementTabIndex = elem.obj.tabIndex;
	var nextElement = null;
	
	var firstElement = null;
	var firstElementTabIndex = 999999;
	for (var i in pc) {
		var comp = pc[i];
		if (comp && comp.obj && comp.obj.tabIndex != '' && comp.visible) {
			if (comp.obj.tabIndex > currentElementTabIndex) {
				if (nextElement == null) nextElement = comp; else
				if (nextElement.obj.tabIndex > comp.obj.tabIndex) nextElement = comp;
			};
			
			var intTabIndex = parseInt(comp.obj.tabIndex);
			if (intTabIndex < firstElementTabIndex) {
				firstElementTabIndex = intTabIndex;
				firstElement = comp;
			};
		};
	};
	if (nextElement == null) nextElement = firstElement;
	return nextElement;
};

componentPage.prototype.setFocusOnFirstTabIndex = function(debugInfo) {
	if (!this.pageIsShow || !config || !config.FocusManegementForSynthesizer) return;
	this.stopFocusTimer();
	
	if (this.tabOverrideComponent != null && this.tabOverrideComponent.visible) { //pg2-aps -test
		try {
			window.focus();
			document.body.focus();
			this.tabOverrideComponent.obj.focus();
			if (typeof(debugInfo) != 'undefined' && debugInfo == 1) alert(this.tabOverrideComponent.id);
		} catch(e) {};
		return;
	};
	
	var ti = 999999;
	var o = null;
	/* //pg2-find first element with lowest tabIndex, including those from backgrounds
	for (var i in pc) {
		if (pc[i].obj != null && pc[i].obj.tabIndex != "" && 
			pc[i].type == 'componentText' && pc[i].id.indexOf("__bckg__") == -1 && pc[i].visible) //pg2-aps -otherwise focus could be set to some background image element
		{
			var s = pc[i].obj.tabIndex;
			if (s != '') {
				var v = parseInt(s);
				if (v > 0 && v < ti) {
					ti = v;
					o = pc[i];
				};
			};
		};
	};*/
	
	if (!o) {
		ti = 999999;
		o = null;
		for (var i in pc) {
			if (pc[i].obj != null && pc[i].obj.tabIndex != "" && pc[i].visible) //pg2- if no text was found, set it on another visible element
			{
				var s = pc[i].obj.tabIndex;
				if (s != '') {
					var v = parseInt(s);
					if (v > 0 && v < ti) {
						ti = v;
						o = pc[i];
					};
				};
			};
		};
	};
	
	if (o) {
		try {
			window.focus();
			document.body.focus();
			o.obj.focus();
			if (o.type == 'componentInput' && !o.locked) o.focus(); //pg2-TEST_EM -focus on input (it was set to its 'obj' and not main div- so cursor was hidden
			this.tabOverrideComponent = o; //pg2-aps
			document.title = o.id;
		} catch(e) {}; //tryIsIE7fix
	} else this.tabOverrideComponent = null;
};

componentPage.prototype.setupFocused = function() {
	for (var i in pc) {
		if (pc[i].contentObj != null && pc[i].obj.tabIndex != "") {
			var o = pc[i].obj;
			if (o) {
				o.focused = false;
				o.onfocus = function(){
					this.focused = true;
				};
				o.onblur = function(){
					this.focused = false;
				};
			};
		};
	};
};

componentPage.prototype.mediaStop = function()
{
	var l = this.children.length;
	for (var i = 0; i < l; i++) {
		var child = this.children[i]; //pg2- to simplyfy debug (child instead 'this.child[i]' each time
		if (child.actionMediaStop) {
			child.actionMediaStop();
			if (this.navigationStarted && is.ie11up) child.hide(); //pg2-ie11_preloader and "leftovers" after video from previous page
		};
		if (child.type == "componentFlash" || child.type == "componentFlashAudioPlayer" ||
			child.type == "componentSimpleFlash" || child.type == "componentSimpleFlashMoviePlayer") //pg2-flv player too... 
		{ //pg2-simpleFlash
			if (child.actionFlashRewind) child.actionFlashRewind(this); //pg2-only FLASH and FlashAudioPlayer  have this method, but stop must be invoked for all flash-alike components
			if (child.actionFlashStop) child.actionFlashStop(this); //pg2-if
		};
	};
};

componentPage.prototype.childMediaStop = function(child) //pg2
{
	if (typeof(child) == 'undefined' || !child) return;
	try {
		if (child.actionMediaStop) child.actionMediaStop();
		if (child.type == "componentFlash" || child.type == "componentFlashAudioPlayer" ||
			child.type == "componentSimpleFlash" || child.type == "componentSimpleFlashMoviePlayer") //pg2-flv player too
		{
			if (child.actionFlashRewind) child.actionFlashRewind(this); //pg2-only FLASH and FlashAudioPlayer  have this method, but stop must be invoked for all flash-alike components
			if (child.actionFlashStop) child.actionFlashStop(this);
		};
	} catch(e) {};
};

componentPage.prototype.unloadContent = function()
{
	if (config.keyboardNavigation || config.FireOnClickOnReturnKey || (this.state == psView || (typeof(config.DebugMode) != 'undefined' && config.DebugMode))) {
		removeKeyDownListener(this.id); //pg2-add navigation via Ctrl and arrows: left (previous page) and right (next page)
	};
	page.resetTabComponent = null; //pg2-aps
	page.tabOverrideComponent = null;
	
	this.killFocusTimer(); //pg2-aps
	
	this.invokeEvent("UnLoad"); //pg2-axa_OnUnload -moved here because any reading of components' props (ex.answer) might return - here - an empty value; ex. ddbasket; -it wasn't invoked during 'next/prev/gotoPage', only on course close
	
	this.mediaStop();
	
	this.waitingForRun = true;
	this.pageIsShow = false;
	this.showCorrectAnswerIndicator = false;
	for (var i in this.children) {
		var child = this.children[i];
		if (child.resetElement && (child.type == 'componentVisualTimer' && child.globalTimer != 1 || (child.type != 'componentVisualTimer')) ) { //pg2-wsptwp_visualTimer
			child.resetElement();
		};
		if (child.refreshElement) {
			child.refreshElement()
		} else {
			if (child.type == "componentFlash" || child.type == "componentFlashAudioPlayer" ||
				child.type == "componentSimpleFlash" || child.type == "componentSimpleFlashMoviePlayer") { //pg2-stop SimpleFlashPlayer too, now it has the method //pg2-flv player too...
				//child.actionFlashRewind(this);
				if (child.actionFlashStop) child.actionFlashStop(this); //pg2-if...
			};
			//child.hide();
		};
		child.hideWithoutInvoking(); //aw - it is not hiding, it is remove object  //child.hide(); //pg2
	};
	this.countAnswers = this._countAnswers;
	this.showCorrectAnswerIndicator = this._showCorrectAnswerIndicator;
	this.tempShowCorrectAnswerIndicator = this.showCorrectAnswerIndicator;
	this._countQuestion = 0;
	this._countCorrectQuestion = 0;
	this._countAnswerQuestion = 0;
	this.stepIndex = 0;
	this.allowPreload = true;
	this.onBeforeRemove();
};

componentPage.prototype.onCreate = function(counter)
{
	var counter2 = parseInt(counter); //pg2- 'cause counter is passed as an object
	if (isNaN(counter2)) counter2 = 0;
	counter = counter2;
	if (typeof(log) != 'undefined') log.info("page onCreate begin");
	//if (counter == null || typeof(counter) == 'undefined') counter = 0;
	if (firstWait == null || typeof(firstWait) == 'undefined') firstWait = false;
	var waitlayer = document.getElementById("waitlayer");
	var progresslayer = document.getElementById("progresslayer");
	var progressTable = document.getElementById("progressTable");
	var prDIV = document.getElementById("progressDIV");
	var prDIVRest = document.getElementById("progressDIVRest");

	if (this.onlyTwoFeedbacks) {
		this.feedbackBadName = "feedbackLastBad";
	};
	if (this.pageType != 'Exercise') {
		this.stepByStepExercise = false;
	};
	if (this.stepByStepExercise) {
		this.feedbacksShow = false;
		this.checkHiddenElementsAnswer = true;
	};
	
	//pg2-iPad
	var maxCounter = 50;
	if (is.safari && is.mobile) maxCounter = 2; 
	//

	var prNr = document.getElementById("progressNumber");
	if (!is.ie10 && (config.usePagePreloader || (is.safari && is.mobile)) && counter < maxCounter) { //pg2-iPad //pg2-IE10 - do not use it in case of IE10, it's very slow then
		var waitingElements = this.children.length;
		for (var i=0; i<this.children.length; i++) {
			var obj = this.children[i];
			
			if (is.mobile && is.safari && (obj.type == 'componentAudio' || obj.type == 'componentVideo')) { //pg2-bi_completion
				//waitingElements--;
				continue;
			};
			if (this.isTopElement(obj) && obj.isReady() == false) {
				//alert(obj.type + ', isReady= ' + obj.isReady());
				counter++;
				setTimeout("page.onCreate(" + counter + ");", 250);
				if (!firstWait) {
					firstWait = true;
				} else {
					if (config.slwrecmode == false) {
						if (waitlayer) waitlayer.style.visibility = "inherit";
						if (progresslayer) progresslayer.style.display = 'block';
						if (progressTable) progressTable.style.display = 'block';
					};
					this.children[i].checkloadedCouter++;
					if (this.children[i].checkloadedCouter > 30 && config.showComponentWithMissingResources) {
						var child = this.children[i];
						var obj = document.getElementById("mediawaitlayer"+child.id);
						if (!obj) {
							var waitlayer = document.getElementById('waitlayer');
							var newdiv = document.createElement('div');
							newdiv.setAttribute("id", "mediawaitlayer"+child.id);
							waitlayer.appendChild(newdiv);
							var obj = document.getElementById("mediawaitlayer"+child.id);
							obj.innerHTML = 'A problem occured during loading following component: '+child.id;
						};
					};
					var prDIV = document.getElementById("progressDIV");
					if (prDIV) {
						var diff = this.children.length-waitingElements;
						if (diff == 0 ) diff = 1;
						var progressWidth = Math.floor((500 / this.children.length) * (diff));
						prDIV.style.width = progressWidth;
						if (prDIVRest) {
							prDIVRest.style.width = 500 - progressWidth;
						};
					};

					if (prNr) {
						prNr.innerHTML = (diff/this.children.length*100).toFixed(0)+'%';
					};
				};
				return (0);
			} else {
				waitingElements--;
			};
		};
	} else {
		if (typeof(log) != 'undefined') log.warning("Page preloader not used");
	};

	this.pageIsCreated = true;
	// hide progress wait layer
	if (waitlayer) waitlayer.style.visibility = "hidden";
	if (progresslayer) progresslayer.style.display = 'none';
	if (progressTable) progressTable.style.display = 'none';
	this.style = (is.ns4) ? self : this.doc.body.style;
	this.obj = (is.ns4) ? self : this.doc.body;
	if (is.ie) {
		this.obj.unselectable = "on";
		try{
			this.obj.focus();
		} catch(e) {};
		document.onselectstart = function(e) {
			if (document.activeElement && page.checkCanSelect(document.activeElement)) {
				return true;
			} else {
				return false;
			};
		};
		document.onselect = function(e) {
			if (document.activeElement && page.checkCanSelect(document.activeElement)) {
				return true;
			} else return false;
		};
	} else
	if (is.moz) {
		this.obj.style.setProperty("-moz-user-select", config.disableRightClick?"none":"auto", ""); //this.obj.style.setProperty("-moz-user-select", "None", ""); //pg2-context_menu_test
	};
	//pg2-context_menu_test
	if (config.disableRightClick && !is.ie) {
		this.obj.style.setProperty("-khtml-user-select", "none", "");
		this.obj.style.setProperty("-webkit-user-select", "none", "");
		this.obj.style.setProperty("user-select", "none", "");
		this.obj.style.setProperty("-ms-user-select", "none", ""); //pg2-ie11
	} else
	if (!is.ie) {
		this.obj.style.setProperty("-khtml-user-select", "auto", "");
		this.obj.style.setProperty("-webkit-user-select", "auto", "");
		this.obj.style.setProperty("user-select", "auto", "");
		this.obj.style.setProperty("-ms-user-select", "auto", ""); //pg2-ie11
	};
	
	if (this.backgroundStyle == 0) {
		this.style.backgroundPosition = 'center';
		this.style.backgroundRepeat = 'no-repeat';
	};
	this.style.backgroundColor = this.backgroundColor;
	if (this.backgroundImage != "") {
		this.style.backgroundImage = 'url(' + resourcesURL + this.backgroundImage + ')';
	};
	this.autoNextPage = this.autoNextPage || (this.isExam && lms.name == "lmsExam");
	if (PlayerInterface.GetValue("isRegistred") || !config.usePlayerPreloader || this.allowSeparateWork || is.ie10) { //pg2-IE10 has problem with refreshing frameset
		this.loadContent();
	} else {
		this.waitingForRun = true;
	};
	if (typeof(log) != 'undefined') log.info("page onCreate end");
};

/*componentPage.prototype.iPadMediaStop = function() //removed for now
{
	if (!is.safari && !is.mobile) return;
	var l = this.children.length;
	for (var i = 0; i < l; i++) {
		var child = this.children[i]; //pg2- to simplyfy debug (child instead 'this.child[i]' each time
		if (typeof(child.actionMediaStop) == 'function' && typeof(child.hardUnload) == 'function') child.hardUnload();
	};
};*/

componentPage.prototype.onBeforeRemove = function()
{
	//this.iPadMediaStop(); //pg2-bi_completion -removed for now
	if (typeof(log) != 'undefined') log.info("componentPage onBeforeRemove begin");
	this.allowResetAction = false; //pg2-block 'reset/refresh page()'
	this.terminated = true;
	this._stepsTimerStop();
	if (PlayerInterface.GetValue("isRegistred") || !config.usePlayerPreloader || this.allowSeparateWork || is.ie10 || //pg2-IE10 has problem with refreshing frameset
	   (this.is_hidden_page && config.usePlayerPreloader)) //pg2-bsh-hidden_pages -if preloader is enabled, second launch of hidden page will not show any of elements (this.steps[0][2] is 1 -what means step was already launched -we must set 0 to it)
	{
		for (var i=0; i<this.children.length; i++) {
			var child = this.children[i];
			if (child.unload) child.unload();
			child.invokeEvent("UnLoad");
		};
		//this.invokeEvent("UnLoad"); //pg2-axa_OnUnload -moved to '.unloadContent' because any reading of components' props (ex.answer) might return - here - an empty value; ex. ddbasket; -it wasn't invoked during 'next/prev/gotoPage', only on course close
		if (this.allowMarkTexts) {
			this.unloadMarkers();
		};
		if (udf && udf.onBeforeRemove) udf.onBeforeRemove(this);
		if (this.isMulti){
			vars.save(me, "me");
			vars.save(sys, "sys");
		};
		switch (this.pageStatus) {
			case "browsed" :
				this.setPageStatusInUELO('N');
				break;
			case "completed" :
				this.setPageStatusInUELO('C');
				break;
			case "failed" :
				this.setPageStatusInUELO('F');
				break;
			case "incomplete" :
				this.setPageStatusInUELO('I');
				break;
			case "not attempted" :
				this.setPageStatusInUELO('N');
				break;
			case "passed" :
				this.setPageStatusInUELO('P');
				break;
			case "unknown" :
				this.setPageStatusInUELO('N');
				break;
		};

		this.clearNextStepsExecuted(0);
		this.sendDataToUELO(false);
		PlayerInterface.SetValue("setTryNumber", this.getTryNumber());

		//save user answer
		if ((this.state == psNormal || this.isAppServ()) && (config.rememberAnswers || this.rememberAnswer)) {
			if (this.pageType == 'Exercise') {
				PlayerInterface.SetValue("setLastUserAnswer", null);
			} else {
				PlayerInterface.SetValue("setLastUserAnswer", this.getAnswerString());
			};
		};
		
		//send data to lms after page exit
		try {
			PlayerInterface.Execute("sendSubDataToLMS");
		} catch(e) {};

		PlayerInterface.Execute("unloadLMS");
		if (typeof(log) != 'undefined') log.info("componentPage onBeforeRemove end");
	};
	this.allowResetAction = true; //pg2
};

componentPage.prototype.onFree = function()
{
	if (typeof(log) != 'undefined') log.info("Page free");
	if (udf && udf.onFree) udf.onFree(this);
	this.deleteAllChildren();
	for (var i=0; i<this.storedSelections.length; i++) {
		this.storedSelections[i] = null;
	};
	this.storedSelections = null;
	for (var k in this.groups) {
		this.groups[k] = null;
	};
	this.groups = null;

	//pg2-groups_names -with .shGroup() action- there are still used names in 'shGroup()' action
	for (var k in this.groupsNames) {
		this.groupsNames[k] = null;
	};
	this.groupsNames = null;

	this.pageIndex = null;
	for (var i=0; i<this.steps.length; i++) {
		this.steps[i] = null;
	};
	if (this.hideFeedbacksTimer != null) {
		clearTimeout(this.hideFeedbacksTimer);
		this.hideFeedbacksTimer = null;
	};
	this.steps = null;
	this.stepsTimer = null;
	this.pageScroll = null;
	this.WBTObject = null;
	this.all = null;
	this.obj = null;
	this.filters = null;
	this.style = null;
	this.body = null;
	this.doc = null;
};

componentPage.prototype.findTypeAndCallFunc = function(type, func)
{
	for (var i in pc) {
		var child = pc[i];
		try {
			if (child.type == type) {
				eval("child." + func + "()");
			};
		} catch(e) {};
	};
};

componentPage.prototype.loadMarkers = function()
{
	var mar_str = PlayerInterface.GetValue("getPageMarkers");
	if (mar_str != null && mar_str != "") {
		var bv_str = mar_str.split("&");
		if (is.ie && bv_str[0] == "ie") {
			var items = bv_str[1].split("##");
			for (var i=0; i<items.length; i++) {
				var item = items[i].split("=");
				this.setMarker(item[0], item[1]);
			};
		} else 
		if (is.moz && bv_str[0] == "moz") {
			//pg2-todo -why it was left empty?
		};
	};
};

componentPage.prototype.unloadMarkers = function()
{
	var mar_str = "";
	for (var i=0; i<this.storedSelections.length; i++) {
		var item = this.storedSelections[i];
		if (item.id != null && item.selections != null) {
			if (mar_str != "") mar_str += "##";
			mar_str += item.id + "=" + item.selections;
		};
	};
	if (mar_str != "") {
		mar_str = ((is.moz) ? "moz&" : "ie&") + mar_str;
	};
	PlayerInterface.SetValue("setPageMarkers", mar_str);
};

componentPage.prototype.getMarker = function(id)
{
	var result = null;
	for (var i=0; i<this.storedSelections.length; i++) {
		var item = this.storedSelections[i];
		if (item.id == id) {
			result = item;
			break;
		};
	};
	return result;
};

componentPage.prototype.setMarker = function(id, value)
{
	var found = false;
	var item = this.getMarker(id);
	if (item) {
		found = true;
		item.selections = value;
	};
	if (!found) {
		var item = new MarkersItem();
		item.id = id;
		item.selections = value;
		this.storedSelections[this.storedSelections.length] = item;
	};
};

componentPage.prototype.hideConfirmAnswerElements = function()
{
	for (var i in pc) {
		var child = pc[i];
  		if (child.confirmAnswer) { //pg2- divided into two 'if' blocks, 'cause it was reguired for debug
			if (child.step <= page.stepIndex-1  //pg2- "<=" instead "<" -if 'checkAnswer was invoked during audio playing, button wasn't hidden
				|| child.step == 0) //pg2-or if element is visible from the start - energa
			{
				child.hideConfirmButton();
			};
		};
	};
	if (config.temp_BSH201401) { //pg2-update to WL's changes
		this.showConfirmation = false; //wl - 201401 for config.temp_BSH201401
		this.onHideConfirmAnswerElementsEvent(); //wl - 201401 for config.temp_BSH201401
	};
};

componentPage.prototype.showCorrectAnswer = function()
{
	if (typeof(log) != 'undefined') log.info("Show correct answer");
	for (var i in pc) {
		var child = pc[i];
		if (child && child.setAnswer) {
			if ((is.ie10 || is.ie11up) && child.type == 'componentPage') continue; //pg2-IE10 fix, IE11 Fix
			child.setAnswer(child.correctAnswer, true);
		};
	};
};

componentPage.prototype.showAnswersIndicators = function()
{
	if (this.pageStatus != 'failed' && this.pageStatus != 'passed') return;
	var caiTemp = this.showCorrectAnswerIndicator;
	this.showCorrectAnswerIndicator = true;
	this.repaintPageElements();
	this.showCorrectAnswerIndicator = caiTemp;
};

componentPage.prototype.showUserAnswer = function()
{
	if (typeof(log) != 'undefined') log.info("Show last user answer");
	var ans = PlayerInterface.GetValue("getLastUserAnswer");
	if (typeof(ans) == "string") {
		if (ans != "") {
			try { //pg2- data from lms had "~", but current answer separator is ANS_SEP = #|#
				ans2 = ans;
				ans2 = ans2.replace(new RegExp('~', "g"), ANS_SEP); //pg2-replacing '#&034' with quotation marks
				ans = ans2;
			} catch(e) {};
			//this.setAnswer("", false, ans.split(ANS_SEP)); //pg2-removed -parameters of method not respond to the method definition !!! - this.setAnswer(answer, showCorrect, separator) -separator only, not answer.split(separator)
			this.setAnswer(ans, false, ANS_SEP); //pg2-new
		};
	};
};

componentPage.prototype.enableDisableAnswerIndicator = function(v)
{
	if (v == null || typeof(v) == 'undefined') v = true;
	this.showCorrectAnswerIndicator = v;
	//this.setPagePassed(v);
	this.repaintPageElements();
};

componentPage.prototype.setPaintIncorrectCAI = function(v)
{
	if (v == null || typeof(v) == 'undefined') v = true;
	this.paintIncorrectCAI = v;
	this.repaintPageElements();
};

componentPage.prototype.runCompleted = function()
{
	for (var i=0; i<this.children.length; i++) {
		var child = this.children[i];
		if (child.checkAnswer || child.type == "componentDDElement") {
			child.show();
			//pg2-in case of checkbox/radiobutton are checked+pages' preloader, if config.rememberAnswers=false, checkAnswer -> gotoNextPage -> prewPage i...checkbox i radio are checked!!! mltp_choice and others - are not (correct)
			if (child.setAnswer) child.setAnswer("", false); 

			if (this.lockElementsAfterGivenAnswer) {
				child.lock();
			};
		} else
		if (child.confirmAnswer || child.step == -1 || child.isCore) {
			child.hideConfirmButton();
		} else child.show();
		
		if (config.temp_BSH201401) { //pg2-update to WL's changes
			//wl - 201401 for config.temp_BSH201401
			if (child.step == -1 || child.isCore) {
				this.showConfirmation = false;
				this.onHideConfirmAnswerElementsEvent();
			};
		};
		//

	};
	this.locked = true;
};

/************************** Steps **************************/
componentPage.prototype.clearNextStepsExecuted = function(stepIndex)
{
	for (var i=stepIndex; i<this.steps.length; i++) {
		this.steps[i][2] = 0;
	};
};

componentPage.prototype.addStep = function(time, execJS)
{
	var st = parseInt(time);
	if (isNaN(st) || st <= 0) st = 100;
	this.steps[this.steps.length] = new Array(st, execJS, 0);
};

componentPage.prototype.runSteps = function()
{
	this.sendFirstStepEventToPlayer();
	if (typeof(log) != 'undefined') log.info("runSteps begin");
	this.stepIndex = this.skipFirstStep;
	this._initSteps();
	if (typeof(log) != 'undefined') log.info("runSteps init begin");
	this._nextStep();
	if (typeof(log) != 'undefined') log.info("runSteps end next");
};

componentPage.prototype._initSteps = function()
{
	while (this.steps.length > 0) {
		if (this.steps[this.steps.length - 1][1] != "") break;
		this.steps.pop();
	};
};

componentPage.prototype._runStep = function()
{
	if (this.startTime == null) this.startTime = new Date();
	if (typeof(log) != 'undefined') log.info("_runStep begin");
	var stepAlreadyRun = false;
	if (this.stepIndex < this.steps.length) stepAlreadyRun = (this.steps[this.stepIndex][2] == 1);
	if (stepAlreadyRun) return;
	if (this.stepIndex >= this.steps.length) {
		var status = PlayerInterface.GetValue("getStatus");
		if (status == PlayerInterface.GetValue("getConst", "STATUS_INCOMPLETE") ||
		    status == PlayerInterface.GetValue("getConst", "STATUS_NOT_ATTEMPTED"))
		{
			PlayerInterface.SetValue("setStatus", PlayerInterface.GetValue("getConst", "STATUS_COMPLETED"));
		};
		return;
	};
	this.stepTime = Math.floor(this.steps[this.stepIndex][0]);
	this.steps[this.stepIndex][2] = 1;
	var evalStr = this.steps[this.stepIndex][1];
	try {
		eval(evalStr);
	} catch (e) {
		var errStr = "Step error !\n\n" + e.message + "\n\n" + evalStr;
		if (typeof(log) != 'undefined') log.error(errStr);
	};
	//this.stepFirstInputFocus = null;
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		try { $EL.eshStep(child); } catch(e) {}; //pg2-added try-catch to aw modyfication ...for use in firefox
		child.invokeEvent("Step"); //pg2-it was missing!!! ...look into instruction component
	};
	if (typeof(log) != 'undefined') log.info("_runStep end");
};

componentPage.prototype._showNextStep = function(stepNo)
{
	var l = this.children.length;
	for (var i = 0; i < l; i++) this.children[i].hide();
	this.stepIndex = 0;
	this._nextStep();
	for (var i = 0; i < stepNo; i++) {
		this._nextStep();
	};
};

componentPage.prototype._showSingleStep = function(stepNo)
{
	this.goToChosenStep(stepNo); //pg2-go to next not seen step- the code below- blank screen has been shown
	/* //pg2-removed
	var l = this.children.length;
	for (var i = 0; i < l; i++) this.children[i].hide();
	this.stepIndex = 0;
	this._nextStep();
	this.stepIndex = stepNo;
	if (this.stepIndex < 0) this.stepIndex = 0;
	this._nextStep();*/
};

componentPage.prototype._getLastNotVisitedStep = function()
{
	var result = 0;
	for (var i=0; i<this.steps.length; i++) {
		if (this.steps[i][2] == 0) {
			result = i;
			break;
		};
	};
	return result;
};

componentPage.prototype._isEveryPageVisited = function()
{
	var result = true;
	if (this.steps.length > 0) { //pg2
		for (var i=0; i<this.steps.length-1; i++) { //pg2-BSH_stepButto - "length-1" -for last step it was never set...
			if (this.steps[i][2] == 0) {
				result = false;
				break;
			};
		};
	};
	return result;
};

componentPage.prototype.sendFirstStepEventToPlayer = function() 
{
	var p = getPlayer();
	if (p && typeof(p.eventPageFirstStep) == "function") {
		p.eventPageFirstStep();
	};
};

componentPage.prototype.sendLastStepEventToPlayer = function() 
{
	var p = getPlayer();
	if (p && typeof(p.eventPageLastStep) == "function") {
		p.eventPageLastStep();
	};
};

componentPage.prototype.isStepByStepExerciseStep = function(step)
{
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.isComponentElement && child.checkAnswer) {
			if (child.step == step) return true;
		};
	};
	return false;
};

componentPage.prototype.mediaAvailable = function() //wl - 201401 for config.temp_BSH201401
{
	if (!config.temp_BSH201401) return; //pg2-update to WL's changes
	
	var bRes = false;
	var l = this.children.length;
	for (var i=0; i < l; i++) {
		var child = this.children[i];
		if (child.type == "componentFlash" 		 || child.type == "componentFlashAudioPlayer" ||
			child.type == "componentSimpleFlash" || child.type == "componentSimpleFlashMoviePlayer" || //pg2-flv player too... 
			child.type == 'componentAudio')
		{ 
			bRes = true;
		};
	};
	return bRes;
};

componentPage.prototype.isAnswerElement = function() //wl - 201401 for config.temp_BSH201401
{
	if (!config.temp_BSH201401) return; //pg2-update to WL's changes
	
	var bRes = false;
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.visible && (child.checkAnswer || child.confirmAnswer || child.lockAfterGivenAnswer)) {
			bRes=true;
			break;
		};
	};
	return bRes;
};

function sleep(milliseconds) //wl - 201401 for config.temp_BSH201401
{
	if (!config.temp_BSH201401) return; //pg2-update to WL's changes
	
	var start = new Date().getTime();
	for (var i = 0; i < 1e7; i++) {
		if ((new Date().getTime() - start) > milliseconds) break;
	};
};

componentPage.prototype.onHideConfirmAnswerElementsEvent = function() //wl - 201401 for config.temp_BSH201401
{
};

componentPage.prototype.onLastStepEvent = function() //wl - 201401 for config.temp_BSH201401
{
};

componentPage.prototype.onPrevStepEvent = function() //wl - 201401 for config.temp_BSH201401
{
};

componentPage.prototype.onResetPageEvent = function() //wl - 201401 for config.temp_BSH201401
{
};

componentPage.prototype._nextStep = function()
{
	if (typeof(log) != 'undefined') log.info("_nextStep begin");
	this._stepsTimerStop();
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		//if ((!child.allowNextStep) || child.anim.animated) {
		if (((!child.allowNextStep) || (child.anim && child.anim.animated)) && (child.type != "componentContainer")) { //pg2-ep -if container and "gotochosenstep", skip it
			this._stepsTimerRun("page._nextStep()", 100);
			return;
		};
		if (child.type == 'componentContainer') child.showChildren(); //pg2-audio2fap_container -fap.step=5 in container - if visible, play it in step #5
		//pg2-BI_iPad_test
		 if (!this.automateStepsRun && (child.type == 'componentVideo' || child.type == 'componentAudio') && child.nextStepWaitToEnd && child.step >= 0 && child.step == this.stepIndex-1) {
			if (is.safari && is.mobile) child.actionMediaStop();
		}
		//...
	};
	this._runStep();
	this.stepIndex++;
	if (this.steps.length > 1 && this.stepIndex == this.steps.length-1) { //pg2-BSH_stepButton -otherwise the flag of last step wasn't marked as 'done'
		this.steps[this.stepIndex][2] = 1;
	};
	this.stepsIntegrationExecute('update'); //pg2-BI_stepsIntegration
	if (this.stepIndex >= this.steps.length - 1 - this.skipLastStep) { //pg2- '>=' instead of '>' - if config.setCompleteStatusAtPageStartup is false, something (click, etc) pushes nextStep forward, it will be never set to last step nor page status set to 'completed'...
		this.isRuning = true;
		var isOnLastStepEvent = false; //wl - 201401 for config.temp_BSH201401
		if (this.pageType == "Information") {
			for (var i = 0; i < this.children.length; i++) this.children[i].invokeEvent("LastStep");
			this.sendLastStepEventToPlayer();
			isOnLastStepEvent=true; //wl - 201401 for config.temp_BSH201401
		};
		var status = PlayerInterface.GetValue("getStatus");
		if (status == PlayerInterface.GetValue("getConst", "STATUS_INCOMPLETE") || status == PlayerInterface.GetValue("getConst", "STATUS_NOT_ATTEMPTED"))
		{
			var statusCompl = PlayerInterface.GetValue("getConst", "STATUS_COMPLETED");
			this.setPageStatus(statusCompl);
		};

		if (config.slwrecmode == true) {
			this.unloadContent();
		};
		
		if (config.temp_BSH201401) { //pg2-update to WL's changes
			//wl - 201401 for config.temp_BSH201401
			if (isOnLastStepEvent) {
				if (this.steps.length>2) {
					var iTime = Math.floor(this.steps[this.stepIndex][0]);
					sleep(iTime); 
				};
				this.onLastStepEvent();
			};
		};
		//
		return;
	};
	this.stepTime = Math.floor(this.steps[this.stepIndex][0]);
	this._stepsTimerRun("page._nextStep()", this.stepTime);
	if (typeof(log) != 'undefined') log.info("_nextStep end");
};

componentPage.prototype._stepsTimerRun = function(call, interval)
{
	var st = parseInt(interval);
	if (st == 0) st = 100;
	if ((this.stepsTimer == null) && (this.stepsRunAutomate) ) {
		if (interval) this.stepsTimer = window.setTimeout(call, st);
	};
};

componentPage.prototype._stepsTimerStop = function()
{
	if (this.stepsTimer != null) {
		window.clearTimeout(this.stepsTimer);
		this.stepsTimer = null;
	};
};

componentPage.prototype._prevStep = function()
{
	this._stepsTimerStop();
	if (this.stepIndex > 1) this.stepIndex -= 2; else this.stepIndex = 0; //pg2-'if' to prevent decrement .stepIndex below 0
	this.steps[this.stepIndex][2] = 0; //pg2-otherwise actions from steps list will not be invoked, 'cause in method '_runStep' variable 'stepAlreadyRun' will be '1' and 'return' (skip eval) will be invoked

	if (this.stepIndex < 0) this.stepIndex = 0;
	this.steps[this.stepIndex+1][2] = 0;

	var l = this.children.length;
	for (var i = 0; i < l; i++) {
		var child = this.children[i]; //pg2
	    if (child.step > this.stepIndex) {
	        child.hideWithoutInvoking();
			this.childMediaStop(child); //pg2
	    } else
		if (child.step == STEPS_LAST_STEP && this.stepIndex < this.steps.length) {
			child.hideWithoutInvoking();
			this.childMediaStop(child); //pg2
		} else
		if (child.step == this.stepIndex) { //pg2- when pages steps back to prev step, elements with "visible" in this step must be shown
			child.show();
		};
	};
	this.nextStep();
};

componentPage.prototype.prevStep = function()
{
	this._prevStep();
	if (config.temp_BSH201401) { //pg2-update to WL's changes
		this.onPrevStepEvent(); //wl - 201401 for config.temp_BSH201401
	};
};

componentPage.prototype.stopSteps = function()
{
	this._stepsTimerStop();
	this.stepsRunAutomate = false;
};

componentPage.prototype.actionRunSteps = function()
{
	this.stepsRunAutomate = true;
	this._nextStep();
};

componentPage.prototype.nextStep = function()
{
	if (this.lastFocusedInput != null) { //pg2-remove focus from input
		try {
			this.lastFocusedInput.removeCursorFromObject();
			this.lastFocusedInput = null;
		} catch(e) {};
	};

	if (this.stepIndex + 1 >= this.steps.length) return;
	this._stepsTimerStop();
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		//if ((!child.allowNextStep) || child.anim.animated) {
		if (((!child.allowNextStep) || (child.anim && child.anim.animated)) && (child.type != "componentContainer")) { //pg2-ep -if container and "gotochosenstep", skip it //pg2- check if 'child.anim' exists
			child.stepStop();
		};
	};
	this._nextStep();
};

componentPage.prototype.backwards = function()
{
	this._stepsTimerStop();
	if (this.stepIndex - 2 < 0) {
		this.prevPage();
	} else {
		this.prevStep();
	};
};
componentPage.prototype.further = function()
{
	var result = false;
	if (this.stepByStepExercise) {
		if (this.isStepByStepExerciseStep(this.stepIndex - 1) && this.sbsLastStepLocked < this.stepIndex) {
			this.checkAnswer(this); //pg2-in case of pageType == 'poll' will be without an object
			return result;
		};
	};
	this._stepsTimerStop();
	if (this.stepIndex + 1 >= this.steps.length) {
		this.nextPage(); 
	} else {
		this.nextStep();
		result = true;
	};
	return result;
};

componentPage.prototype.goToChosenStep = function(step)
{
	step = parseInt(step);
	if (step > this.steps.length) step = this.steps.length-1;
	if (this.stepIndex > step) {
		this._stepsTimerStop();
		while (this.stepIndex > step + 1 && this.stepIndex > 0) {
			this.prevStep();
		};
	} else
	if (this.stepIndex <= step) {
		this._stepsTimerStop();
		while (this.stepIndex <= step && this.stepIndex < (this.steps.length-1)) {
			this.nextStep();
		};
	};
};

componentPage.prototype.skipToChosenStep = function(step)
{
	step = parseInt(step);
	if (this.stepIndex > step) {
		this.goToChosenStep(step);
		this.clearNextStepsExecuted(step+1);
	} else
	if (this.stepIndex <= step) {
		this._stepsTimerStop();
		this.stepIndex = step;
		this._nextStep();
	};
};

componentPage.prototype.refreshPage = function(allowExecute)
{
	if (!this.allowResetAction || this.navigationStarted) return; //pg2-while unloading page, it's forbidden

	if (typeof(log) != 'undefined') log.info("refreshPage begin");
	if (typeof(allowExecute) == "undefined") allowExecute = true;
	if (allowExecute || this.isRuning) {
		var lastIsRuning = this.isRuning;
		if (!allowExecute) this.isRuning = false;
		this.showCorrectAnswerIndicator = this._showCorrectAnswerIndicator;
		this.tempShowCorrectAnswerIndicator = this.showCorrectAnswerIndicator;
		this._countQuestion = 0;
		this._countCorrectQuestion = 0;
		this._countAnswerQuestion = 0;
		this.stepIndex = 0;
		this.clearNextStepsExecuted(0);
		for (var i = 0; i < this.children.length; i++) {
			var child = this.children[i];
			if (child && child.hideWithoutInvoking) child.hideWithoutInvoking(); //pg2-without checking in last iteration an exception was thrown
			//this.children[i].hideWithoutInvoking(); //pg2-removed aw's change, the line above is correct
		};
		this.invokeEvent("Load");
		//this.invokeEvent("AfterLoad"); //pg2-odznaczenie
		this.stepsRunAutomate = this.automateStepsRun && !this.stepByStepExercise; //pg2-after 'refresh' restore page's original steps launching
		this._nextStep();
		this.isRuning = lastIsRuning;

		if (this.lockElementsAfterGivenAnswer && this.pageType == "Exercise" && this.checkBlockAttempts()) { //pg2- if page type is exercise, refresh elements, but if user has used all chances to solve exercise, block
			this.runCompleted();																			 // elements - if page option is enabled
			this.isExec = true;
		};
		this.invokeEvent("AfterLoad");//pg2
	};
	if (typeof(log) != 'undefined') log.info("refreshPage end");
};

componentPage.prototype.resetPage = function(allowExecute)
{
	if (!this.allowResetAction || this.navigationStarted) return; //pg2-while unloading page, it's forbidden

	if (!this.automateStepsRun) { //pg2-if page has flashAudioPlayer and it is played, it ain't acting properly- after 'reset' it plays again from step0
		this.stopSteps();
		this.goToChosenStep(0);
	};
	
	if (typeof(log) != 'undefined') log.info("resetPage begin");
	if (typeof(allowExecute) == "undefined") allowExecute = true;
	if (allowExecute || this.isRuning) {
		if (config.temp_BSH201401) { //pg2-update to WL's changes
			this.onResetPageEvent(); //wl - 201401 for config.temp_BSH201401
		};
		var lastIsRuning = this.isRuning;
		if (!allowExecute) this.isRuning = false;
		PlayerInterface.SetValue("setStatus", PlayerInterface.GetValue("getConst", "STATUS_NOT_ATTEMPTED"));
		this.setPageStatus(PlayerInterface.GetValue("getConst", "STATUS_NOT_ATTEMPTED"));

		PlayerInterface.SetValue("setLastUserAnswer", "", true);
		
		if (PlayerInterface.connectedUELO.resetOverride && PlayerInterface.connectedUELO.currentUELOPage.lockPageScore) { //pg2-courseReport_af
			this.unlockElements();
		} else
		this.resetInteractionsInUELO(); //default
		
		this.showCorrectAnswerIndicator = false;
		this.setPagePassed(false);
		this.setPageSolved(false);//pg2- 'cause reset page doesn't set it as 'not solved'
		this.setAnswer("", false);
//		this.setTryCount(this.baseTryCount);
		this.setTryLeft(0);
		this.grantedAnswers = 0;
//		this.setTryNumber(0);
		this.locked = false;
		this.userScore = 0;
		var child = null;
		for (var i = 0; i < this.children.length; i++) {
			child =	this.children[i];
			child.invokeEvent("Load");
			if (child.animationStop) child.animationStop();
			if (child.resetElement && (child.type == 'componentVisualTimer' && child.globalTimer != 1 || (child.type != 'componentVisualTimer')) ) { //pg2-wsptwp_visualTimer
				child.resetElement();
			} else {
				if (child.checkAnswer && child.visible) {
					child.repaint();
				};
			};
			child.unlock();
			child.invokeEvent("PageReady");
			if (child.refreshElement) {
				child.refreshElement()
			} else {
				/*if (child.type == "componentFlash" || child.type == "componentFlashAudioPlayer" || //pg2-otherwise during "resetPage" FAP components didn't stop
					child.type == "componentSimpleFlash" || child.type == "componentSimpleFlashMoviePlayer") //pg2-simple flash and flv player too...
				{
					if (child.actionFlashRewind) child.actionFlashRewind(this); //pg2-only FLASH and FlashAudioPlayer  have this method, but stop must be invoked for all flash-alike components
					child.actionFlashStop(this);
				};*/
				this.childMediaStop(child);
				if (child && child.hideWithoutInvoking) child.hideWithoutInvoking(); //pg2-added 'if'
			};
			if (child.confirmAnswer) child.show();
			child.invokeEvent("AfterLoad");
		};
		if (!allowExecute && lastIsRuning) {
			this.refreshPage(true);
		} else {
			this.refreshPage(allowExecute);
		};
		this.isRuning = lastIsRuning;
	};
	if (typeof(log) != 'undefined') log.info("resetPage end");
};

function resizeIntegerArray(arr, newLength, defaultValue)
{
	var i;
	if (arr.length <= newLength) {
		for (i=arr.length; i<newLength+1; i++) {
			arr[i] = defaultValue;
		};
	};
};

componentPage.prototype.setSize = function(w, h)
{
	this.pageWidth = w;
	this.pageHeight = h;
};

componentPage.prototype.getPageSolved = function()
{
	return this.solved;
};

componentPage.prototype.setPageSolved = function(solved)
{
	this.solved = solved;
};

componentPage.prototype.getPagePassed = function()
{
	return this.passed;
};

//true if page is passed 
componentPage.prototype.setPagePassed = function(passed)
{
	this.passed = passed;
	this.setPagePassedInUELO(passed);
};

componentPage.prototype.getTryNumber = function()
{
	return this.baseTryCount - this.countAnswers;
};

componentPage.prototype.setTryNumber = function(tryNumber)
{
	this.tryNumber = tryNumber;
	PlayerInterface.SetValue("setTryNumber", tryNumber);
};

componentPage.prototype.setTryLeft = function(tryNumber)
{
	this.setTryNumber(tryNumber);
	var tryLeft = this.baseTryCount - tryNumber;
	this.countAnswers = tryLeft;
};

componentPage.prototype.getTryLeft = function()
{
	return this.countAnswers;
};

componentPage.prototype.getBaseTryCount = function()
{
	return this.baseTryCount;
};

componentPage.prototype.setTryCount = function(tryCount)
{
	this.countAnswers = tryCount;
};

componentPage.prototype.setIsExam = function(isExam)
{
	this.isExam = isExam;
};

componentPage.prototype.setPageIndex = function(i)
{
	this.pageIndex = i;
};

componentPage.prototype.hideFeedbacks = function()
{
	if (this.hideFeedbacksTimer != null) {
		clearTimeout(this.hideFeedbacksTimer);
		this.hideFeedbacksTimer = null;
	};

	if (this.pageType == "Exercise") {
		var feedback = this.findChildByName(this.feedbackOkName);
		if (typeof(feedback) != "undefined") feedback.hide();
		feedback = this.findChildByName(this.feedbackBadName);
		if (typeof(feedback) != "undefined") feedback.hide();
		feedback = this.findChildByName(this.feedbackLastBadName);
		if (typeof(feedback) != "undefined") feedback.hide();
		feedback = this.findChildByName(this.feedbackNotOkName);
		if (typeof(feedback) != "undefined") feedback.hide();
	};
};

componentPage.prototype.hideFeedbacksForTime = function(t)
{
	this.hideFeedbacksTimer = setTimeout("page.hideFeedbacks()", t);
};

componentPage.prototype.getElementsType = function(elemType)
{
	var result = new Array();
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].isComponentElement	&& this.children[i].type == elemType) {
			result[result.length] = this.children[i];
		};
	};
	return result;
};

componentPage.prototype.shObjects = function(objectType, sh)
{
	var shBool = (sh == "true") || (sh == true);
	for (var i=0; i<this.children.length; i++) {
		var child = this.children[i]; //pg2-BI
		if (child.isComponentElement && child.type == objectType && !child.backgroundElement) {
			//pg2-BI_run_stop_objects
			if (typeof(child.actionMediaPlay) != 'undefined') {
				if (child.step == this.stepIndex-1) {
					if (shBool) child.actionMediaPlay(); else child.actionMediaStop();
				};
				continue;
			};
			//...
			if (shBool) {
				if (child.actionRun) {
					child.actionRun();
				} else
				if (child.actionMediaPlay) {
					child.actionMediaPlay();
				} else {
					if (shBool) child.show(); else child.hide();
				};
			} else {
				if (child.actionStop) {
					child.actionStop();
				} else
				if (child.actionMediaStop) {
					child.actionMediaStop();
				} else {
					if (shBool) {
						child.show();
					} else {
						child.hide();
					};
				};
			};
		};
	};
};

componentPage.prototype.rsObjects = function(objectType, rs)
{
	this.shObjects(objectType, rs)
};

componentPage.prototype.shChosenObjects = function(chosenObjects, sh)
{
	if (chosenObjects == null || chosenObjects == "" || sh == null || sh == "") return;
	chosenObjects = unescape(chosenObjects);
	var shBool = (sh == "true");
	var chosenObjectsArr = new Array();
	chosenObjectsArr = chosenObjects.split("|");
	for (var i=0; i<this.children.length; i++) {
		for (var j=0; j<chosenObjectsArr.length; j++) {
			if (this.children[i].isComponentElement && this.children[i].id == chosenObjectsArr[j]) {
				if (shBool) {
					if (this.children[i].actionRun) {
						this.children[i].actionRun();
					} else
					if (this.children[i].actionMediaPlay) {
						this.children[i].actionMediaPlay();
					} else {
						if (shBool) {
							this.children[i].show();
						} else {
							this.children[i].hide();
						};
					};
				} else {
					if (this.children[i].actionStop) {
						this.children[i].actionStop();
					} else 
					if (this.children[i].actionMediaStop) {
						this.children[i].actionMediaStop();
					} else {
						if (shBool) {
							this.children[i].show();
						} else {
							this.children[i].hide();
						};
					};
				};
			};
		};
	};
};

componentPage.prototype.checkBlockAttempts = function()
{
	var userHasChances = PlayerInterface.GetValue("userHasChances");
	// passed || 0
	return (this.getPagePassed() || !userHasChances);
};

componentPage.prototype.checkPageVisited = function()
{
	this.pageVisited = (PlayerInterface.GetValue("getPageVisited") == 1 || this.pageStatus != "not attempted"); //pg2-ewspa -with next session .pageVisited must be true
};

componentPage.prototype.getPageStatus = function()
{
	return this.pageStatus;
};

componentPage.prototype.setPageStatus = function(status)
{
	if (typeof(status) != 'undefined' && this.pageStatus != status) {
		if (!(this.stepByStepExercise && (status == 'failed' || status == 'completed'))) { //completed, not complIted
			for (var i in this.children) {
				try { $EL.eshSetStatus(this.children[i], status); } catch(e) {}; //pg2
			};
		};
	};

	var statusLetter = convertStatusToLetter(status);
	this.pageStatus = status;
	PlayerInterface.SetValue("setStatus", status);
	this.setPageStatusInUELO(statusLetter);
	PlayerInterface.Execute("debugCourse");
};

componentPage.prototype.setExercisePassed = function(points)
{
	if (typeof(log) != 'undefined') log.info("Exercise passed");
	PlayerInterface.SetValue("setPoints", points);
	this.setPageStatus('passed');
	this.setPagePassed(true);
};

componentPage.prototype.setExerciseFailed = function(points)
{
	if (typeof(log) != 'undefined') log.info("Exercise failed");
	PlayerInterface.SetValue("setPoints", points);
	this.setPageStatus('failed');
};

componentPage.prototype.showFeedbackOk = function(answer)
{
	this.hideFeedbacks();
	var e = this.findChildByName(this.feedbackOkName);
	if (this.feedbacksShow && e) {
		e.show();
	};
	return true;
};

componentPage.prototype.showFeedbackBad = function(answer)
{
	this.hideFeedbacks();
	var e = this.findChildByName(this.feedbackBadName);
	if (this.feedbacksShow && e) {
		e.show();
	};
	return true;
};

componentPage.prototype.showFeedbackLastBad = function(answer)
{
	this.hideFeedbacks();
	var e = this.findChildByName(this.feedbackLastBadName);
	if (this.feedbacksShow && e) {
		e.show();
	};
	return true;
};

componentPage.prototype.showFeedbackNotOk = function(answer)
{
	this.hideFeedbacks();
	var e = this.findChildByName(this.feedbackNotOkName);
	if (this.feedbacksShow && e) {
		e.show();
	};
	return true;
};

componentPage.prototype.countAnswer = function()
{
	this.countAnswers--;
	this.grantedAnswers++;
	this._countQuestion = 0;
	this._countCorrectQuestion = 0;
	this._countAnswerQuestion = 0;
	this.sbsStagePassed = true;
	//loop over all components and call checkAnswer functions
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.isComponentElement && child.checkAnswer && (child.visible || this.checkHiddenElementsAnswer)) {
			var ansVal = child.checkAnswer();
			if (child.clearIncorectAnswer && this.getTryLeft() > 0) {
				this.invokeClearForExerciseComponents = true; //pg2- new
				//child.invokeEvent("Clear"); //pg2- removed -look into declaration of 'this.invokeClearForExerciseComponents'
			};
			if (!child.ignoreAnswer && !child.checkLock) {
				this._countQuestion++;
				if (ansVal == true || ansVal == "true") {
					this._countCorrectQuestion++;
				};
			};
			if (child.checkIsAnswer && (child.checkIsAnswer() == true)) {
				this._countAnswerQuestion++;
			};
			//StepByStep
			if (this.stepByStepExercise && child.step == this.stepIndex - 1) {
				this.sbsStagePassed = this.sbsStagePassed && ansVal;
			};
		};
	};

	if (!this.stepByStepExercise) {
		for (var i = 0; i < this.children.length; i++) {
			if (this.children[i].isComponentElement && this.children[i].afterCheckAnswer) {
				this.children[i].afterCheckAnswer();
			};
		};
	};

	var ans = 0;
	if (this.reductionScoring) {
		ans = Math.floor((this.maxScore / this._countQuestion) * this._countCorrectQuestion);
		if (this.grantedAnswers > 1) {
			ans = Math.floor(ans -  (ans / this._countAnswers * (this.grantedAnswers - 1)));
		};
		this.masteryScore = Math.floor((this.maxScore / this._countAnswers) * (this._countAnswers - this.grantedAnswers + 1));
	} else {
		//count percent result of answer - 100% all ok
		//the less 100 than more bad
		ans = Math.floor((this.maxScore / this._countQuestion) * this._countCorrectQuestion);
	};

	this.userScore = ans;
	return ans;
};

componentPage.prototype.showAnswer = function(answer)
{
	if (typeof(log) != 'undefined') log.info("Show answer");
	var corAns = (this.answerWeighting)?(answer >= this.masteryScore):(answer >= this.masteryScore);

	if (!corAns && !this.answerWeighting && !this.reductionScoring) {
		answer = 0;
	};
	if (corAns && !this.answerWeighting && !this.reductionScoring) {
		answer = this.maxScore;
	};

	//before feedback
	if (this.countAnswers < -1) this.countAnswers = -1;
	if (this.countAnswers <= 0) {
		if (corAns) {
			this.invokeEvent("BeforePageCorrectAnswer");
		} else {
			if (this.baseTryCount == 0) this.invokeEvent("BeforePageIncorrectAnswer"); //pg2-event try again -added 'if' -it is invoked few lines below, but must be here in case of infinite try count
		};
	};
	// show pops
	if (this.countAnswers > 0) {
		if (corAns) {
			if (!this.reductionScoring && answer != 100) {
				this.showFeedbackNotOk(answer);
			} else {
				this.showFeedbackOk(answer);
				this.countAnswers = 0;
			};
			if (this.pageType == "Exercise") {
				this.setExercisePassed(answer);
			};
		} else {
			this.showFeedbackBad(answer);
			if (this.pageType == "Exercise") {
				this.invokeEvent("BeforePageIncorrectAnswer"); //pg2-event try again
				this.setExerciseFailed(answer);
			};
		};
	} else {
		if (corAns) {
			this.showFeedbackOk(answer);
			if (this.pageType == "Exercise") {
				this.setExercisePassed(answer);
			};
		} else {
			if (this.baseTryCount == 0) { //pg2-in case of wrong answer and infinite try count- display 'try again'
				this.showFeedbackBad(answer);
			} else {
				this.showFeedbackLastBad(answer);
				if (this.pageType == "Exercise") {
					this.setExerciseFailed(answer);
				};
			};
		};

		if (this.lockElementsAfterGivenAnswer && !this.stepByStepExercise && this.pageType != 'Poll') { //pg2-otherwise pool page is locked
			if ((corAns) || (!corAns && this.baseTryCount > 0)) {
				this.lockElements(); //pg2-qr -fix to .baseTryCount = 0 (try count = infinity)
			};
		};
	};
	//after feedbackach
	if (this.countAnswers <= 0) {
		if (corAns) {
			this.invokeEvent("AfterPageCorrectAnswer");
		} else {
			this.invokeEvent("AfterPageIncorrectAnswer");
		};

		if (this.pageType == "Exercise") {
			for (var i = 0; i < this.children.length; i++) {
				this.children[i].invokeEvent("LastStep");
			};
			this.sendLastStepEventToPlayer();
		};
	};
	return true;
};

componentPage.prototype.runStepAudio = function(answer)
{
	var child = null;
	var audioCompArr = new Array();

	for (var i=0; i < this.children.length; i++) {
		child = this.children[i];
		if (child.type == 'componentAudio' || child.type == 'componentFlashAudioPlayer') {
			if (!audioCompArr[child.step]) {
				audioCompArr[child.step] = new Array();
			};
			audioCompArr[child.step].push(child.id);
		};
	};

	if (typeof(audioCompArr[this.stepIndex-1])) {
		var audioArr = audioCompArr[this.stepIndex-1];
		for (var k in audioArr) {
			try{
				eval('pc.' + audioArr[k] + '.show();');
			} catch(e) {};
		};
	};
};

componentPage.prototype.getName = function()
{
	//return project.pageName; //pg2-removed
	var result = ''; //pg2-new
	if (project) {
		result = project.pageName;
	};
	return result;
};

componentPage.prototype.sendDataToUELO = function(sendInteractions)
{
	//if (this.pageType == 'Poll' || this.pageType == 'Exercise') { //pg2-removed -if page is the 'Information' one and there are some user vars changed (me.var1, etc), on page closing, they will not be stored - at next page they (user vars) will have initial values
		PlayerInterface.Execute("sendDataToUELO", sendInteractions);
	//};
};

componentPage.prototype.initializeUELO = function(initInteractions)
{
	if (typeof(initInteractions) == "undefined") {
		initInteractions = ((this.pageType == 'Poll' || this.pageType == 'Exercise') && !this.getPageSolved());
	};
	PlayerInterface.Execute("initializeUELO", initInteractions);
};

componentPage.prototype.getValueFromSCO = function(valueParam)
{
	if (lms && lms.LMSGetValue) return lms.LMSGetValue(valueParam); //pg2
	return "";
	//return (lms)?lms.LMSGetValue(valueParam):""; //pg2-removed -in case of encyclopedia there is no such a method. Replaced with two lines above
};

componentPage.prototype.getSCOStatus = function(pageIndex)
{
	var SCOStatus = "";
	var isExam = PageInterface.GetValue("isExam");

	if (isExam) {
		SCOStatus = "not attempted"; //in exam page has unlimited try count
	} else {
		if (config && (config.exportDetails.toLowerCase().indexOf('scorm2004') > -1 || config.exportDetails.toLowerCase().indexOf('wbtserver') > -1)) { //pg2
			SCOStatus = this.getValueFromSCO('cmi.completion_status');
		} else {
			SCOStatus = this.getValueFromSCO('cmi.core.lesson_status');
		};
	};
	if (SCOStatus == null || SCOStatus.toString() == "null") {
		SCOStatus = this.getValueFromSCO('cmi.success_status');
		if (SCOStatus == 'unknown' || SCOStatus == null) {
			SCOStatus = this.getValueFromSCO('cmi.completion_status');
		};
		if (SCOStatus == 'unknown' || SCOStatus == null) {
			SCOStatus = this.getValueFromSCO('lesson_status');
		};
	};
	return SCOStatus;
};

componentPage.prototype.checkLastVisitPageWasPassed = function()
{
	if (this.isMulti) {
		var pageStatus = this.getSCOStatus();
		return (pageStatus == "passed");
	} else {
		return this.getPagePassedFromUELO();
	};
};

componentPage.prototype.getPagePassedFromUELO = function()
{
	return PlayerInterface.GetValue("getPagePassedFromUELO");
};

componentPage.prototype.setPagePassedInUELO = function(passed)
{
	PlayerInterface.SetValue("setPagePassedInUELO", passed);
};

componentPage.prototype.setPageStatusInUELO = function(newStatus)
{
	PlayerInterface.SetValue("setUELOStatus", newStatus);
};

componentPage.prototype.resetInteractionsInUELO = function()
{
	PlayerInterface.SetValue("resetInteractionsInUELO");
};

componentPage.prototype.getPageStatusFromUELO = function()
{
	return PlayerInterface.GetValue("getUELOStatus");
};

componentPage.prototype.userHasTry = function()
{
	return PlayerInterface.GetValue("userHasTry");
};

componentPage.prototype.setUserAnswer = function()
{
	PlayerInterface.Execute("setUserAnswer");
};

componentPage.prototype.setSLWSimulation = function(value)
{
	this.SLWSimulation = value;
};

componentPage.prototype.getLastExerciseStep = function()
{
	var step = 0;

	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.isComponentElement && child.checkAnswer) {
			step = Math.max(step, child.step);
		};
	};
	return step;
};

componentPage.prototype.checkAnswer = function(obj)
{
	var origNavigationStarted = this.navigationStarted; //pg2-BI_iPad_onunload
	this.navigationStarted = false; //pg2-knf_completion
	if (typeof(obj) != 'undefined') { //pg2-in case of pageType == 'poll', it will be without an object and action invoked in .nextPage/.prevPage will be executed; otherwise (action invoked by click- won't be after navigation has been started)
		if ((!this.pageIsShow || this.navigationStarted) /*&& this.pageType != 'Poll'*/) return; //pg2-to prevent checking answer when page isn't loaded or- next/prev page has been invoked; allow for poll page
	};
	
	for (var i = 0; i < this.children.length; i++) {
		if (this.children[i].isComponentElement && this.children[i].beforeCheckAnswer) {
			this.children[i].beforeCheckAnswer();
		};
	};

	if (checkExportType(config.exportDetails, 'poll')) { //pg2
		if (this.pageType == 'Poll') {
			//this.setAnswer("", false, ""); //ANS_SEP
			var userAnswer = this.getAnswerString('');
			if (userAnswer == "" || userAnswer == ANS_SEP) return;
		};
	};

	//pg2-qr -completion
	var uelo = PlayerInterface.connectedUELO;
	if (uelo) {
		var p = uelo.FindPage(this.p_globalIndex);
		if (p) {
			if (p.isAssessment && p.visible) uelo.pageInAssessmentCheckAnswerInSession = true;
		};
	};
	//
	this.invokeClearForExerciseComponents = false; //pg2-look into its declaration

	if (typeof(log) != 'undefined') log.info("Checking answers");
	var udChAns = E_NOTIMPL;
	if (udf.checkAnswers) udChAns = udf.checkAnswers(this, obj);
	if (udChAns == E_NOTIMPL) {
		if (this.isExam) {
			this.sendDataToUELO(true);
			lms.checkAnswer();
		} else {
			this.invokeEvent("CheckAnswer"); //pg2-event try again -moved here, so invoked as first is 'checkAnswer' event, then- 'correct/incorrect again/incorrect'
			if (this.SLWSimulation) {
				var ans = this.checkSimulationAnswer();
			} else {
				var ans = this.countAnswer();
			};
			
			var udRes = E_NOTIMPL;
			if (udf.countAnswer) udRes = udf.countAnswer(this);
			if (udRes != E_NOTIMPL) ans = udRes;
			if (udf.showAnswer) {
				udRes = udf.showAnswer(this, ans);
			};
			if (udRes == E_NOTIMPL && !this.isExam && !this.stepByStepExercise) {
				this.showAnswer(ans);
			};
			if (!this.stepByStepExercise && !this.allowGetMaxScore) {
				this.repaintAndLockElements(obj);
			};

			//this.invokeEvent("CheckAnswer"); //pg2-event try again -removed, moved few lines up
			// if (this.isExam) {
				// this.sendDataToUELO(true);
				// lms.checkAnswer();
			// } else
			if (lms.name == "lmsExplorer" && this.autoNextPage) {
				this.nextPage();
			} else
			if (this.countAnswers && this.autoNextPage) {
				this.nextPage();
			};
			for (var i in this.children) {
				try { $EL.eshAnswer(this.children[i]); } catch(e) {}; //pg2
			};

			//StepByStep
			if (this.stepByStepExercise) {
				this.hideFeedbacks();

				if (this.pageType == "Exercise") {
					if (ans >= this.masteryScore) {
						this.setExercisePassed(ans);
					} else {
						this.setExerciseFailed(ans);
					};
				};
				var sbsStageEnd = this.grantedAnswers >= this._countAnswers || this.sbsStagePassed;
				var e = null;
				if (this.sbsStagePassed) {
					e = this.findChildByName(this.feedbackOkName);
					if (e) e.show();
				} else {
					if (sbsStageEnd) {
						e = this.findChildByName(this.feedbackLastBadName);
					} else {
						e = this.findChildByName(this.feedbackBadName);
					};
					if (e) e.show();
				};

				this.hideFeedbacksForTime(3000);
				for (var i = 0; i < this.children.length; i++) {
					if (this.children[i].isComponentElement && this.children[i].afterCheckAnswer) {
						this.children[i].afterCheckAnswer();
					};
				};

				if (sbsStageEnd) {
					this.lockVisibleElements();
					this.sbsLastStepLocked = this.stepIndex;
					this.showCAIInVisibleElements();
					if (this.sbsLastStepLocked == this.getLastExerciseStep() + 1) {
						for (var i in this.children) {
							try { $EL.eshSetStatus(this.children[i],this.pageStatus); } catch(e) {}; //pg2
						};
					};
					this.nextStep();
					this.grantedAnswers = 0;
					this.setTryLeft(0);
					if (this.stepIndex >= this.getLastExerciseStep() + 1) {
						this.countAnswers = 0;
					};
				};
			};
			try { //pg2-courseReport_af
				if (!PlayerInterface.connectedUELO.currentUELOPage.lockPageScore) this.sendDataToUELO(true);
			} catch(e) {
				this.sendDataToUELO(true); //default
			};
			//---
			if (this.invokeClearForExerciseComponents) { //pg2-look to its declaration
				var thisTryLeft = this.getTryLeft();
				for (var i = 0; i < this.children.length; i++) {
					var child = this.children[i];
					if (child.isComponentElement && child.checkAnswer && (child.visible || this.checkHiddenElementsAnswer)) {
						if (child.clearIncorectAnswer && thisTryLeft > 0) {
							child.invokeEvent("Clear");
						};
					};
				};
				this.invokeClearForExerciseComponents = false;
			};
			//---
		};
	};

	if (this.isMulti) { //pg2-in case multiSCO, if answer was checked, user has no more chances and performing "RefreshPage"- hidden checkAnswer-button will be shown (tryNumber wasn't sent to lms)
		PlayerInterface.SetValue("setTryNumber", this.getTryNumber());
	};

	if (PlayerInterface.connectedUELO.resetOverride) { //pg2-courseReport_af
		if (this.pageStatus == 'passed') PlayerInterface.connectedUELO.currentUELOPage.lockPageScore = true;
	};
	
	if (!origNavigationStarted) { //pg2-BI_iPad_onunload
		this.sendDataToLMSOnlineAfterGivenAnswer();
	};
	
	if (udChAns == E_NOTIMPL) {
		// return result
		//	'1' if exercise was passed
		//	'0' if exercise was failed or when wasn't exercise on page
		if (this._countQuestion == 0) return 0;
		if (this._countCorrectQuestion == this._countQuestion) {
			return 1;
		} else {
			return 0;
		};
	};
	return udChAns;
};

componentPage.prototype.checkSimulationAnswer = function(obj)
{
	var exerciseHotspot = null;
	var child = null;

	for (var i = 0; i < this.children.length; i++) {
		child = this.children[i];
		if (child.type == "componentExerciseHotspot") {
			exerciseHotspot = child;
			break;
		};
	};

	if (!exerciseHotspot) {
		return this.countAnswer();
	};
	this.countAnswers--;

	var pageTryCount = this.getBaseTryCount();
	var allowTry = exerciseHotspot.maxClicks;
	var tryUsed = exerciseHotspot.howManyClicks;
	var wrongClicks =  (((tryUsed - allowTry) < 0) ? 0 : tryUsed - allowTry);
	var result = 0;

	if (wrongClicks == 0) {
		result = 100;
	};
	if (wrongClicks <= pageTryCount) {
		var percWrong = ((wrongClicks/pageTryCount)*100).toFixed(0);
		result = 100 - percWrong;
	};
	return result;
};

componentPage.prototype.repaintAndLockElements = function(obj)
{
	var lockRepaint = (this.getPagePassed() || this.getTryLeft() == 0);
	if (lockRepaint) {
		this.setPageSolved(true);
		//send actions
		this.showCorrectAnswerIndicator = this.tempShowCorrectAnswerIndicator;
		this.sendAnswerEvent();
		//blockade
		if (obj && ((obj.isComponentElement) || (obj.type == 'componentPage'))) {
			if (!this.isExam) {
				this.repaintPageElements();
				this.hideConfirmAnswerElements();
				if (this.lockElementsAfterGivenAnswer) {
					this.lockElements();
				};
			};
		};
	};
};

componentPage.prototype.repaintPageElements = function()
{
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (!(is.ie11up && (child.type == 'componentAudio' || child.type == 'componentVideo'))) { //pg2-ie11_audio -exercise page, config.resetExercisePages = true;
			child.repaint();
		};
		//this.children[i].repaint();
	};
};

/**
 * rozsyla zdarzenia po komponentach
 **/
componentPage.prototype.sendAnswerEvent = function()
{
	for (var i = 0; i < this.children.length; i++) {
		if (this.children[i].isComponentElement && this.children[i].checkAnswer && 
			(this.children[i].visible || this.checkHiddenElementsAnswer) && this.children[i].inputFixKeyControl)
		{
			if (this.children[i].checkAnswer()) {
				this.children[i].invokeEvent("CorrectAnswer");
			} else {
				this.children[i].invokeEvent("IncorrectAnswer");
			};
		};
	};
};

componentPage.prototype.getElementsGroups = function()
{
	var groups = new Array();
	for (var i=0; i<this.children.length; i++) {
		var elem = this.children[i];
		if (elem.isComponentElement && elem.visible) {
			if (elem.group && elem.group != "") {
				var exists = false;
				for (var j=0; j<groups.length; j++) {
					if (groups[j] == elem.group) {
						exists = true;
						break;
					};
				};
				if (!exists) {
					groups[groups.length] = elem.group;
				};
			};
		};
	};
	return groups;
};

componentPage.prototype.groupCheckIsChanged = function(groupName)
{
	var res = false;
	for (var i = 0; i < this.children.length; i++) {
		var elem = this.children[i];
		if (elem.isComponentElement && elem.group == groupName && elem.visible && elem.checkIsChanged) {
			res = elem.checkIsChanged() || res;
		};
	};
	return res;
};

//check correct of group 
componentPage.prototype.groupCountAnswer = function(groupName, maxScore)
{
	if (groupName == null || typeof(groupName) == "undefined") groupName = "";
	if (maxScore == null || typeof(maxScore) == "undefined") maxScore = 100;
	countQuestion = 0;
	countCorrectQuestion = 0;
	countAnswerQuestion = 0;
	//loop throught all registred components in group
	//call function checkAnswer
	for (var i = 0; i < this.children.length; i++) {
		if (this.children[i].isComponentElement && this.children[i].checkAnswer && this.children[i].group == groupName &&
		    (this.children[i].visible || this.checkHiddenElementsAnswer))
		{
			var ansVal = this.children[i].checkAnswer();
			if (this.children[i].clearIncorectAnswer) {
				this.children[i].invokeEvent("Clear");
			};
			if (!this.children[i].ignoreAnswer && !this.children[i].checkLock) {
				countQuestion++;
				if (ansVal == true ) {
					countCorrectQuestion++;
				};
			};
			if (this.children[i].checkIsAnswer && (this.children[i].checkIsAnswer() == true)) {
				countAnswerQuestion++;
			};
		}; // IF(...)
	}; // FOR(...)
	//count percent result of answer - 100% all ok
	//the less 100 than more bad
	ans = Math.floor((maxScore / countQuestion) * countCorrectQuestion);
	return ans;
};

//check if group is correct
componentPage.prototype.groupCheckAnswer = function(groupName, maxScore)
{
	if (groupName == null || typeof(groupName) == "undefined") groupName = "";
	if (maxScore == null || typeof(maxScore) == "undefined") maxScore = 100;
	var ans = this.groupCountAnswer(groupName, maxScore);
	countAnswers = 0;
	var corAns = (ans == maxScore);
	if (corAns) countAnswers = 0;
	this.invokeEvent("GroupCheckAnswer");
	// return result
	//	'1' if exercise was passed
	//	'0' if exercise was failed or when wasn't exercise on page
	//if (this._countQuestion == 0) return 0;
	return corAns;
	//if (this._countCorrectQuestion == this._countQuestion) return 1;
	//else return 0;
};

componentPage.prototype.getGroupElementsType = function(groupName)
{
	if (groupName == null || typeof(groupName) == "undefined" || groupName == "") return "";
	for (var i=0; i<this.children.length; i++) {
		var elem = this.children[i];
		if (elem.group && elem.group == groupName) return elem.type;
	};
};

componentPage.prototype.getCountCorrectAnswerOfElementsType = function(elemType, groupName, ifWasChanged)
{
	if (elemType == null || typeof(elemType) == "undefined" || elemType == "") return 0;
	if (ifWasChanged == null || typeof(ifWasChanged) == "undefined" || ifWasChanged == "") ifWasChanged = 0;
	if (groupName == null || typeof(groupName) == "undefined") groupName = "";
	var list = new Array();
	for (var i=0; i<this.children.length; i++) {
		var elem = this.children[i];
		if (elem.type == elemType) {
			if (groupName != "" && elem.group == groupName) {
				list[list.length] = elem.id;
			} else {
				list[list.length] = elem.id;
			};
		};
	};
	var result = 0;
	for (var i=0; i<list.length; i++) {
		var elem = this.all[list[i]];
		if (elem && (elem.visible || this.checkHiddenElementsAnswer)) {
			switch (ifWasChanged) {
				case 1:
					if (elem.isChanged && elem.checkAnswer()) result += 1;
					break;
				case 2:
					if (elem.correctAnswer == 1 && elem.checkAnswer()) result += 1;
					break;
				case 3:
					if (elem.correctAnswer == 0 && !elem.checkAnswer()) result += 1;
					break;
				default:
					if (elem.checkAnswer()) result += 1;
					break;
			};
		};
	};
	return result;
};

componentPage.prototype.showCAIInVisibleElements = function()
{
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.visible && (child.showCAI) && (child.showCorrectAnswerIndicator)) {
			child.showCAI();
		};
	};
};

componentPage.prototype.lockElements = function()
{
	if (this.pageType == 'Poll') return; //pg2-new
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.checkAnswer || child.confirmAnswer || child.lockAfterGivenAnswer) {
			child.lock();
		};
	};
	this.locked = true;
	this.invokeEvent("Lock");
};

componentPage.prototype.lockVisibleElements = function()
{
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child.visible && (child.checkAnswer || child.confirmAnswer || child.lockAfterGivenAnswer)) {
			child.lock();
		};
	};
};

componentPage.prototype.lock = function()
{
	this.lockElements();
};

componentPage.prototype.unlockElements = function()
{
	for (var i = 0; i < this.children.length; i++) {
		this.children[i].unlock();
	};
	this.locked = false;
	this.invokeEvent("UnLock");
};

componentPage.prototype.unlock = function()
{
	this.unlockElements();
};

componentPage.prototype.getUserValue = function(name)
{
	return me[name];
};

componentPage.prototype.setUserValue = function(name, value)
{
	me[name] = unescape(value); //pg2-unescape, 'cause while page is loaded and me[x] will be changed and text repainted, some signs might be encoded
};

componentPage.prototype.modifyUserValue = function(name, operate, value)
{
	var oldValue = me[name];
	if (!isNaN(oldValue) && !isNaN(value)) {
		try {
			me[name] = eval(oldValue+operate+value);
		} catch(e) {};
	};
};

componentPage.prototype.getValue = function(name)
{
	if (!this.allowCommunication()) {
		return null;
	};
	return (lms.getValue('_' + this.pageIndex + name));
};

componentPage.prototype.setValue = function(name, value)
{
	if (!this.allowCommunication()) {
		return;
	};
	lms.setValue('_' + this.pageIndex + name, value);
};

componentPage.prototype.getAnswer = function()
{
	var answer = new Array();
	var ai = 0;
	for (var i=0; i<page.children.length; i++) {
		if (!page.children[i].isGroup) {
			if (page.children[i].getAnswer) {
				answer[ai++] = page.children[i].getAnswer();
			};
		};
	};
	return answer;
};

componentPage.prototype.getAnswerString = function(sep)
{
	var answerStr = "";
	if (sep == null) sep = ANS_SEP;
	for (var i = 0; i < this.children.length; i++) {
		if (!this.children[i].isGroup) {
			if (this.children[i].getAnswerString) {
				answerStr += this.children[i].getAnswerString() + sep;
			} else
			if (this.children[i].getAnswer) {
				answerStr += this.children[i].getAnswer() + sep;
			};
		};
	};
	return answerStr;
};

componentPage.prototype.setAnswer = function(answer, showCorrect, sep)
{
	var ans = new Array();
	this.clearAnswer();
	if (typeof(answer) == "string") {
		if (sep == null) sep = ANS_SEP;
		ans = answer.split(sep);
	} else
	if (typeof(answer) == "array" || typeof(answer) == "object") {
		ans = answer;
	};
	var ai = 0;
	for (var i = 0; i < page.children.length; i++) {
		if (page.children[i].setAnswer) {
			if (ai >= ans.length-1) break; //if (ai >= ans.length) break; //pg2-axa_OnUnload -in case of list exercise components, radio at the beginning, at first it is checked on, then - for group - checked off
			//page.children[i].setAnswer("", ans[ai++], showCorrect); //pg2-removed -parameters of method not respond to definition of components  OBJ.setAnswer(answer [,showCorrect])  !!!
			page.children[i].setAnswer(ans[ai++], showCorrect); //pg2-new, look above
		};
	};
	this.repaintPageElements();
};

componentPage.prototype.clearAnswer = function()
{
	for (var i=0; i<page.children.length; i++) {
		if (page.children[i].clearAnswer) page.children[i].clearAnswer(); else
		if (page.children[i].setAnswer) page.children[i].setAnswer("", false);
	};
};

componentPage.prototype.actionCheckAnswer = function()
{
	this.checkAnswer(this);
};

componentPage.prototype.setPageType = function(pageType)
{
	this.pageType = pageType;
};

componentPage.prototype.findChildByPosAndType = function(x, y, type)
{
	var obj = null;
	for(var i=0; i<this.children.length; i++) {
		var child = this.children[i];
		if (x >= child.x && x <= child.x + child.w && y >= child.y && y <= child.y + child.h && type == child.type) {
			if ((!obj) || (obj && child.z > obj.z)) obj = child;
		};
	};
	return (obj);
};

componentPage.prototype.openDialog = function(url, w, h, toolbar, menubar, status, scrollbars, resizable)
{
	//ver < 6.0 fix
	if (url.substr(0, sProtoWBTRes.length) != sProtoWBTRes) {
		if (url.indexOf('/_page.html') > -1) {
			url = url.replace('/_page.html', '/_page.0.html');
		};
		if (url.indexOf('_page', 0)>-1 && url.indexOf('?asw=1', 0)==-1) url += "?asw=1"; //pg2-bsh-hidden_pages - if suffix exists, do not add one
		if (url.indexOf('/_page.0.html') > -1) {
			if (this.allowCommunication()) {
				url = url.replace('/_page.0.html', '/_page.' + PlayerInterface.GetValue("getCourseVersion") + '.html');
			};
			if (page.state != psNormal) {
				this.showInfoAboutHtmlInNewWindow(); //pg2
				return;
			};
		};
	};
	if (url.indexOf('http://') == 0) {
		return openDialog(url, w, h, toolbar, menubar, status, scrollbars, resizable);
	} else
	if (lms.useExternalLexicon()) {
		lms.callExternalWindowOpen(validateURL(url), w , h);
	} else {
		return openDialog(url, w, h, toolbar, menubar, status, scrollbars, resizable);
	};
	return;
};

componentPage.prototype.openExtrasPage = function(url, w, h, toolbar, menubar, status, scrollbars, resizable)
{
	if (page.state != psNormal) {
		this.showInfoAboutHtmlInNewWindow(); //pg2
		return;
	};
	if (url.indexOf('asw=1', 0) == -1) {
		url += "?asw=1";
	};
	if (url.indexOf('http://') == 0) {
		url = url.replace('.0.html', '.' + PlayerInterface.GetValue("getCourseVersion") + '.html'); //pg2-open additional page in proper lang version
		return openDialog(url, w, h, toolbar, menubar, status, scrollbars, resizable);
	} else
	if (lms.useExternalLexicon()) {
		//lms.callExternalWindowOpen(validateURL(url), w , h);        //pg2- zamienione na ponizsze, bo nie chce dzialac - wywala ze blad przy inicjalizacji PlayerInterface
		window.open(validateURL(url), w, h);
		window.external.WindowSetSize(w, h);
	} else {
		url = url.replace('.0.html', '.' + PlayerInterface.GetValue("getCourseVersion") + '.html'); //pg2-open additional page in proper lang version
		return openDialog(url, w, h, toolbar, menubar, status, scrollbars, resizable);
	};
	return;
};

componentPage.prototype.mediaAlert = function(w, h, chb)
{
	return (openDialog(mediaAlert.html, w, h));
};

componentPage.prototype.setContentMode = function(i)
{
	sys.contentMode = i;
};

componentPage.prototype.brokenConnectionInfoShow = function() //pg2-BV
{
	this.navigationStarted = false;
	
	var detectProgressName = 'detectConnectionProgressPopup';
	var progressComp = getComponentByPartialId(detectProgressName);
	if (progressComp) progressComp.hide();
	
	var infoBrokenConnectionCompName = 'brokenConnectionPopup';
	var infoComp = getComponentByPartialId(infoBrokenConnectionCompName);
	if (infoComp) {
		infoComp.show();
	} else {
		alert('Problem with navigation - please, check your internet/intranet connection');
	};
};

componentPage.prototype.sendLessonLocation = function() //pg2-BI_iPad_onunload
{
	var isAICC = (config.exportDetails.indexOf('AICC') == 0);
	if (isAICC && is.safari && is.mobile && this.pageExtrasType == 'none') {
		PlayerInterface.connectedUELO.sendLessonLocationToServerAtOnce();
	};
};

componentPage.prototype.sendDataToLMSOnlineAfterGivenAnswer = function() //pg2-BI_iPad_onunload
{
	var isAICC = (config.exportDetails.indexOf('AICC') == 0);
	if (isAICC && is.safari && is.mobile && this.pageExtrasType == 'none' && (this.pageType == 'Exercise' || this.pageType == 'Poll')) {
		PlayerInterface.connectedUELO.sendSubDataToServerAtOnce();
	};
};

componentPage.prototype.sendDataToLMSOnline = function() //pg2-BI_iPad_connection -4 now checking state in AICC only
{
	var allowNavigation = true;
	if (config.sendDataToServerOnEachPage) {
		var isAICC = (config.exportDetails.indexOf('AICC') == 0);
		//if (isAICC) displayCheckingConnectionIcon(true); //AICC 4 BI only ...for now _test
		PlayerInterface.connectedUELO.sendSubDataToServerAtOnce();
		if (!PlayerInterface.connectedPlayer.sendingData2LMS_OK) {
			if (isAICC) displayConnectionInfo(); //AICC 4 BI only ...for now
			allowNavigation = false;
		}
	};
	return allowNavigation;
};

componentPage.prototype.nextPage = function()
{
	if (this.navigationStarted) return; //pg2-prevent from double click on next/prevPage
	this.navigationStarted = true;
	
	if (this.pageExtrasType == 'none' && PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.gix = this.p_globalIndex; //pg2-bps -if extras was loaded, gix==1 and .nextPage goes to gix='2'
	
	if (!this.sendDataToLMSOnline()) { //pg2-BI_iPad_connection
		this.navigationStarted = false;
		return;
	};
	
	if (typeof(this.onUnLoad) == 'function') { //pg2-if there is '.actionCheckAnswer()' in 'onUnLoad' event, it won't be invoked 'cause navigation has started, so do nothing and check answer here
		var s = this.onUnLoad.toString();
		if (s.indexOf('.actionCheckAnswer') > -1) {
			s = s.replace(new RegExp('.actionCheckAnswer', "g"), '.doNothing'); //s = s.replace(new RegExp('.actionCheckAnswer', "g"), '.checkAnswer');
			var f;
			eval("f=" + s);
			this.onUnLoad = f;
			this.checkAnswer();
		};
	};
	//
	if (config.DetectBrokenConnection) { //pg2-BV
		//this.navigationStarted = false;
		var imgID = 'testConectionImage';
		var imageCheckConnectionName = 'check_connection_image.gif';
		var imgSrc = resourcesURL + imageCheckConnectionName + '?' + (+new Date);
		var imgObj = document.getElementById(imgID);
		if (imgObj) {
			var detectProgressName = 'detectConnectionProgressPopup';
			var progressComp = getComponentByPartialId(detectProgressName);
			if (progressComp) {
				progressComp.show();
				progressComp.bringToFront();
			};
			
			imgObj.onload = function() {
				try {
					var p = getPage();
					if (p) {
						if (p.pageType == 'Poll') p.checkAnswer();
						if (PlayerInterface) PlayerInterface.Execute("nextPage");
					};
				} catch(e) {};
			};
			imgObj.onerror = function() {
				try {
					var p = getPage();
					if (p) {
						p.brokenConnectionInfoShow();
					};
				} catch(e) {};
			};
			imgObj.src = imgSrc;
			return;
		};
	};
	//
	if (this.pageType == 'Poll') this.checkAnswer(); //this.actionCheckAnswer(); //pg2-only check, without an object
	if (!PlayerInterface.Execute("nextPage")) this.navigationStarted = false; //pg2-bsh
};

componentPage.prototype.prevPage = function()
{
	if (this.navigationStarted) return; //pg2-prevent from double click on next/prevPage
	this.navigationStarted = true;
	
	if (this.pageExtrasType == 'none' && PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.gix = this.p_globalIndex; //pg2-bps -if extras was loaded, gix==1 and .nextPage goes to gix='2'
	
	if (!this.sendDataToLMSOnline()) { //pg2-BI_iPad_connection
		this.navigationStarted = false;
		return;
	};
	
	if (typeof(this.onUnLoad) == 'function') { //pg2-if there is '.actionCheckAnswer()' in 'onUnLoad' event, it won't be invoked 'cause navigation has started, so do nothing and check answer here
		var s = this.onUnLoad.toString();
		if (s.indexOf('.actionCheckAnswer') > -1) {
			s = s.replace(new RegExp('.actionCheckAnswer', "g"), '.doNothing'); //s = s.replace(new RegExp('.actionCheckAnswer', "g"), '.checkAnswer');
			var f;
			eval("f=" + s);
			this.onUnLoad = f;
			this.checkAnswer();
		};
	};
	//
	if (config.DetectBrokenConnection) { //pg2-BV
		//this.navigationStarted = false;
		var imgID = 'testConectionImage';
		var imageCheckConnectionName = 'check_connection_image.gif';
		var imgSrc = resourcesURL + imageCheckConnectionName + '?' + (+new Date);
		var imgObj = document.getElementById(imgID);
		if (imgObj) {
			var detectProgressName = 'detectConnectionProgressPopup';
			var progressComp = getComponentByPartialId(detectProgressName);
			if (progressComp) {
				progressComp.show();
				progressComp.bringToFront();
			};
			
			imgObj.onload = function() {
				try {
					var p = getPage();
					if (p) {
						if (p.pageType == 'Poll') p.checkAnswer();
						if (PlayerInterface) PlayerInterface.Execute("prevPage");
					};
				} catch(e) {};
			};
			imgObj.onerror = function() {
				try {
					var p = getPage();
					if (p) {
						p.brokenConnectionInfoShow();
					};
				} catch(e) {};
			};
			imgObj.src = imgSrc;
			return;
		};
	};
	//
	if (this.pageType == 'Poll') this.checkAnswer(); //this.actionCheckAnswer(); //pg2-only check, without an object
	if (!PlayerInterface.Execute("prevPage")) this.navigationStarted = false; //pg2-bsh
};

componentPage.prototype.nextSCO = function()
{
	PlayerInterface.Execute("nextSCO");
};

componentPage.prototype.prevSCO = function()
{
	PlayerInterface.Execute("prevSCO");
};

componentPage.prototype.runRepeatMode = function()
{
	var p = getPlayer();
	if (p && typeof(p.runRepeatMode) == "function") {
		p.runRepeatMode();
	};
};

componentPage.prototype.exitRepeatMode = function()
{
	var p = getPlayer();
	if (p && typeof(p.exitRepeatMode) == "function") {
		p.exitRepeatMode();
	};
};

componentPage.prototype.getPageWidth = function()
{
	var pageWidth = 0;
	for (var i=0; i<page.children.length; i++) {
		if (pageWidth < page.children[i].x + page.children[i].w) {
			pageWidth = page.children[i].x + page.children[i].w;
		};
	};
	return pageWidth;
};

componentPage.prototype.getPageHeight = function()
{
	var pageHeight = 0;
	for (var i=0; i<page.children.length; i++) {
		if (pageHeight < page.children[i].y + page.children[i].h) {
			pageHeight = page.children[i].y + page.children[i].h;
		};
	};
	return pageHeight;
};

componentPage.prototype.offsetSet = function(offset, value)
{
	switch (offset) {
		case "left": 
			this.offsetLeft = value;
			break;
		case "top":
			this.offsetTop = vlue;
			break;
		case "right":
			this.offsetRight = vlue;
			break;
		case "bottom":
			this.offsetBottom = vlue;
			break;
	};
};

componentPage.prototype.offsetInit = function()
{
	this.offsetLeft = 0;
	this.offsetTop = 0;
	this.offsetRight = 0;
	this.offsetBottom = 0;
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].docked && this.children[i].docked != "free") {
			switch (this.children[i].docked) {
				case "left":
					if (this.offsetLeft < this.children[i].w) {
						this.offsetLeft = this.children[i].w;
					};
					this.offsetAlreadyInitialized = true; //pg2- if preloader is enabled, do not calculate this again- only if it's for the first time or page was removed from preloader's set
					break;
				case "top":
					if (this.offsetTop < this.children[i].h) {
						this.offsetTop = this.children[i].h;
					};
					this.offsetAlreadyInitialized = true; //pg2- if preloader is enabled, do not calculate this again- only if it's for the first time or page was removed from preloader's set
					break;
				case "right":
					if (this.offsetRight < this.children[i].w) {
						this.offsetRight = this.children[i].w;
					};
					this.offsetAlreadyInitialized = true; //pg2- if preloader is enabled, do not calculate this again- only if it's for the first time or page was removed from preloader's set
					break;
				case "bottom":
					if (this.offsetBottom < this.children[i].h) {
						this.offsetBottom = this.children[i].h;
					};
					this.offsetAlreadyInitialized = true; //pg2- if preloader is enabled, do not calculate this again- only if it's for the first time or page was removed from preloader's set
					break;
			};
		};
	};
};

componentPage.prototype.offsetDraw = function()
{
	for (var i=0; i<this.children.length; i++) {
		this.children[i].x = this.children[i].x + this.offsetLeft;
		this.children[i].y = this.children[i].y + this.offsetTop;
	};
	var pageWidth = this.getPageWidth() + this.offsetRight;
	var pageHeight = this.getPageHeight() + this.offsetBottom;
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].docked && this.children[i].docked != "free") {
			var obj = this.children[i];
			switch (obj.docked) {
				case "left":
					obj.x = 0;
					obj.w = this.offsetLeft;
					obj.y = this.offsetTop;
					obj.h = pageHeight - this.offsetTop - this.offsetBottom;
					break;
				case "top":
					obj.x = 0;
					obj.w = pageWidth;
					obj.y = 0;
					obj.h = this.offsetTop;
					break;
				case "right":
					obj.x = pageWidth - this.offsetRight;
					obj.w = this.offsetRight;
					obj.y = this.offsetTop;
					obj.h = pageHeight - this.offsetTop - this.offsetBottom;
					break;
				case "bottom":
					obj.x = 0;
					obj.w = pageWidth;
					obj.y = pageHeight - this.offsetBottom;
					obj.h = this.offsetBottom;
					break;
			};
		};
	};
};

componentPage.prototype.checkCanSelect = function(obj)
{
	var result = (obj.unselectable != "on");
	if (result) {
		result = (obj.owner && obj.owner.isComponentElement && obj.owner.unselectable != "on");
	};
	return result;
};

componentPage.prototype.isTopElement = function(element)
{
	if (element.parent.isComponentElement) return false;
	return true;
};

componentPage.prototype.getTopElement = function(element)
{
	if (element == null || element == "undefined" || element == "") return null;
	while (element.parent.isComponentElement) {
		element = element.parent;
	};
	return element;
};

componentPage.prototype.getWBTEElement = function(obj)
{
	if (obj == null || obj == "undefined" || obj == "") return null;
	if (typeof(obj.isComponentElement) != "undefined" && obj.isComponentElement) return obj;
	if (typeof(obj.owner.isComponentElement) != "undefined" && obj.owner.isComponentElement) return obj.owner;
	return null; //pg2-todo -why is it in here?

	var obj = obj.parent;
	while (typeof(obj.isComponentElement) == "undefined" && !obj.isComponentElement && obj != document.body) {
		obj = obj.parent;
	};
	if (obj != document.body && typeof(obj.isComponentElement) != "undefined" && obj.isComponentElement) {
		return obj;
	} else {
		return null;
	};
};

componentPage.prototype.getElementXPath = function(element)
{
	var result = "";
	if (element == null || element == "undefined" || element == "") return result;
	result = element.id;
	while (element.parent.isComponentElement && element.parent.type != this.type) {
		element = element.parent;
		if (element.isComponentElement && element.type != this.type) {
			result = element.id + "." + result;
		};
	};
	return result;
};

componentPage.prototype.getMaxZPos = function()
{
	var allElems = this.children;
	var maxZIndex = 0;
	var elem = null;
	for (var i=0; i < allElems.length; i++) {
		elem = allElems[i];
		maxZIndex = Math.max(maxZIndex,elem.z);
	};
	return maxZIndex;
};

componentPage.prototype.setOnTop = function(element)
{
	if (element == null || element == "undefined" || element == "") return;
	try {
		if (element.parent) { //pg2-test_yellowcard
			while (element.parent.isComponentElement) {
				try {
					element = element.parent;
				} catch(e) {
					break;
				};
			};
		};
	} catch(e) {};
	var pos = parseInt(this.getMaxZPos());
	element.setZIndex(pos + 1);
};

componentPage.prototype.getFocusedElement = function(onlyName)
{
	var res = null;
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].checkIsFocused && page.children[i].checkIsFocused()) {
			res = this.children[i];
			break;
		};
	};
	if (res != null && onlyName) {
		res = res.id;
	};
	return res;
};

componentPage.prototype.shGroup = function(groupName, action)
{
	var groupElements = this.groups[unescape(groupName)];

	if (groupElements == null && typeof(this.groupsNames) != "undefined") { //pg2-groups_names -with .shGroup() action- there are still used names in 'shGroup()' action
		var groupId = this.groupsNames[groupName];
		if (groupId != null) {
			groupElements = this.groups[groupId];
		};
	};

	if (groupElements != null && typeof(groupElements) != "undefined" && groupElements != "") {
		var elArr = groupElements.split(",");
		for (var i=0; i<elArr.length; i++) {
			var elem = this.all[elArr[i]];
			if (elem && action) {
				if (action == "true") {
					elem.show();
				} else {
					elem.hide();
				};
			};
		};
	};
};

componentPage.prototype.getUEDO = function()
{
	if (lms) {
		return lms.getUEDO();
	};
};

componentPage.prototype.getUELO = function()
{
	if (typeof(PlayerInterface) != 'undefined') {
		return PlayerInterface.connectedUELO;
	};
	return null;
};

componentPage.prototype.getSW = function()
{
	return PlayerInterface.connectedSW;
};

componentPage.prototype.close = function()
{
	if (config.DetectBrokenConnection) { //pg2-BV
		var imgID = 'testConectionImage';
		var imageCheckConnectionName = 'check_connection_image.gif';
		var imgSrc = resourcesURL + imageCheckConnectionName + '?' + (+new Date);
		var imgObj = document.getElementById(imgID);
		if (imgObj) {
			var detectProgressName = 'detectConnectionProgressPopup';
			var progressComp = getComponentByPartialId(detectProgressName);
			if (progressComp) {
				progressComp.show();
				progressComp.bringToFront();
			};
			
			imgObj.onload = function() {
				try {
					if (PlayerInterface) PlayerInterface.Execute("closeCourse");
				} catch(e) {};
			};
			imgObj.onerror = function() {
				try {
					var p = getPage();
					if (p) {
						p.brokenConnectionInfoShow();
					};
				} catch(e) {};
			};
			imgObj.src = imgSrc;
			return;
		};
	};
	
	PlayerInterface.Execute("closeCourse");
};

componentPage.prototype.runEmbeddedAction = function(name)
{
	if (this.all[name]) {
		this.all[name].runAction();
	};
};

componentPage.prototype.showYellowCards = function()
{
	if (typeof(sys.yellowCards) != "boolean") {
		sys.yellowCards = (sys.yellowCards == "true");
	};
	sys.yellowCards = this.checkYCradsVisible();
	this.shObjects("__componentYellowCard", sys.yellowCards);
};

componentPage.prototype.checkYCradsVisible  = function()
{
	var YCardsArr = PlayerInterface.GetValue('getYellowCardsFromPage');
	var result = true;
	var child = null;
	for (var i=0; i<YCardsArr.length; i++) {
		child = PageInterface.GetValue("getChild", YCardsArr[i].id);
		childMini = PageInterface.GetValue("getChild", YCardsArr[i].id+'_mini');
		if (child.visible || childMini.visible) {
			result = false;
			break;
		};
	};
	return result;
};

componentPage.prototype.removeYellowCards = function()
{
	var is_clear = false;
	while (!is_clear) {
		is_clear = true;
		for (var i=0; i<this.children.length; i++) {
			if (this.children[i].type == "__componentYellowCard") {
				this.removeChild(this.children[i]);
				is_clear = false;
				break;
			};
		};
	};
};

componentPage.prototype.saveYellowCards = function()
{
	for (var i=0; i<this.children.length; i++) {
		if (this.children[i].type == "__componentYellowCard") {
			this.children[i].saveCard();
		};
	};
};

componentPage.prototype.storeSelection = function()
{
};

componentPage.prototype.restoreSelection = function()
{
	if (this.storedSelections) {
		for (var i=0; i<this.storedSelections.length; i++) {
			this._restoreSelection(this.storedSelections[i]);
		};
	};
};

componentPage.prototype.clearSelections = function()
{
	if (this.storedSelections) {
		for (var i=0; i<this.storedSelections.length; i++) {
			this.storedSelections[i] = null;
		};
		this.storedSelections = new Array();
	};
};

componentPage.prototype.showFreeWatermarks = function()
{
	if ((project.programOverdueFreeVersion=='T') && (project.programVersion=='F')) {
		freeInfo = document.getElementById("wbteFreeWatermarkBig");
		if (freeInfo) {
			freeInfo.style.visibility = "inherit";
			if (is.ie55UP && !is.ie7UP) {
				var img = document.getElementById("wbteFreeWatermarkBigImg");
				var new_html = '<span '
					+ ' style="width:233; height:229;'
					+ 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader'
					+ '(src=\'' + img.src + '\', sizingMethod=\'image\');"></span>';
				img.outerHTML = new_html;
			};
		};
	} else
	if (project.programVersion == 'F') {
		var freeInfo = document.getElementById("wbteFreeWatermarkSmall");
		if (freeInfo) {
			freeInfo.style.visibility = "inherit";
			var img = document.getElementById("wbteFreeWatermarkSmallImg");
			if (is.ie55UP && !is.ie7UP) {
				var new_html = '<span '
					+ ' style="width:105; height:23;'
					+ 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader'
					+ '(src=\'' + img.src + '\', sizingMethod=\'image\');"></span>';
				img.outerHTML = new_html;
			};
		};
	} else
	if (project.demoExport == "T") {
		var freeInfo = document.getElementById("wbteDemoWatermark");
		if (freeInfo) {
			freeInfo.style.display = "";
			freeInfo.style.zIndex = 1000;
			var fr = findFrame('content', top);
			if (fr) {
				var w = fr.style.width;
				var h = fr.style.height;
			} else {
				var w = 800;
				var h = 600;
			};
			freeInfo.style.left = parseInt(w/2-265);
			freeInfo.style.top = parseInt(h/2-44);

			var img = document.getElementById("wbteDemoWatermarkImg");
			if (is.ie55UP && !is.ie7UP) {
				var new_html = '<span '
					+ ' style="width:105; height:23;'
					+ 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader'
					+ '(src=\'' + img.src + '\', sizingMethod=\'image\');"></span>';
				img.outerHTML = new_html;
			};
		};
	};
};

componentPage.prototype.doNothing = function() //pg2-required when replacing .resetPage() / .refreshPage() in the same event with 'next/prevPage / gotoPage()
{
	return true;
};

componentPage.prototype.showLexiconHint = function(key, type) //pg2-giub_lexicon
{
	var result = false;
	if (key == '' || typeof(key) == 'undefined') return result;
	var LEX_HINT_DIV = 'LEX_HINT_DIV';
	
	//-------------------------------------------------------
	var LEX_HINT_DIV_PATTERN = LEX_HINT_DIV + '_PATTERN';
	var lexHintDivPattern = document.getElementById(LEX_HINT_DIV_PATTERN);
	if (!lexHintDivPattern) {
		var bodyObj = document.getElementsByTagName('body')[0];
		if (bodyObj) {
			var nDiv = document.createElement('div');
			if (nDiv) {
				nDiv.setAttribute('id', LEX_HINT_DIV_PATTERN);
				
				nDiv.style.position = 'absolute';
				nDiv.style.visibility = 'hidden'; //'hidden';
				nDiv.style.width = 'auto';
				nDiv.style.height = 'auto';
				nDiv.style.left = '0px';
				nDiv.style.top = '0px';
				nDiv.style.borderStyle = 'solid';
				nDiv.style.borderWidth = '2px';
				nDiv.style.borderColor = 'black';
				nDiv.style.color = 'black';
				nDiv.style.background = '#FFFFE1';
				nDiv.style.paddingLeft = '5px';
				nDiv.style.paddingRight = '5px';
				if (is.ie) nDiv.style.paddingBottom = '5px';
				nDiv.style.paddingTop = '5px';
				nDiv.style.fontFamily = 'Verdana';
				nDiv.style.fontSize = '12px';
				
				nDiv.innerHTML = '';
				bodyObj.appendChild(nDiv);
				lexHintDivPattern = document.getElementById(LEX_HINT_DIV_PATTERN);
			};
		};
	};
	if (lexHintDivPattern) {
		var item = null;
		if (type == 'lexicon' && lexicon) item = lexicon.getItem(key); else
		if (type == 'dictionary' && dictionary) item = dictionary.getItem(key);
		if (item) {
			var desc = item.description;
			while (desc.indexOf('\\n') > -1) desc = desc.replace('\\n', '<br>');
			lexHintDivPattern.innerHTML = desc;
			result = true;
		};
	};
	//-------------------------------------------------------
	
	var lexHintDiv = document.getElementById(LEX_HINT_DIV);
	if (!lexHintDiv) {
		var bodyObj = document.getElementsByTagName('body')[0];
		if (bodyObj) {
			var nDiv = document.createElement('div');
			if (nDiv) {
				nDiv.setAttribute('id', LEX_HINT_DIV);
				
				nDiv.style.position = 'absolute';
				nDiv.style.visibility = 'hidden'; //'hidden';
				//nDiv.style.width = 'auto';
				//nDiv.style.height = 'auto';
				nDiv.style.left = '300px';
				nDiv.style.top = '300px';
				nDiv.style.borderStyle = 'solid';
				nDiv.style.borderWidth = '2px';
				nDiv.style.borderColor = 'black';
				nDiv.style.color = 'black';
				nDiv.style.background = '#FFFFE1';
				nDiv.style.paddingLeft = '5px';
				nDiv.style.paddingRight = '5px';
				if (is.ie) nDiv.style.paddingBottom = '5px';
				nDiv.style.paddingTop = '5px';
				nDiv.style.fontFamily = 'Verdana';
				nDiv.style.fontSize = '12px';
				
				nDiv.innerHTML = '';
				bodyObj.appendChild(nDiv);
				lexHintDiv = document.getElementById(LEX_HINT_DIV);
			};
		};
	};
	
	//top.window.document.title = document.body.scrollTop + ', ' + document.body.scrollLeft + ' ::: ' + getDateStr();
	
	if (lexHintDiv && lexHintDivPattern && result) {
		lexHintDiv.innerHTML = lexHintDivPattern.innerHTML;
		lexHintDiv.style.visibility = 'visible';
		
		this.cursorX = window.event.clientX; //pg2-giub_lexicon5 -after moving feedback (exercise page) the value isn't real -for now
		this.cursorY = window.event.clientY;
		
		var xH = this.cursorX + 15 + document.body.scrollLeft;
		var yH = this.cursorY + 15 + document.body.scrollTop;
		var wH = lexHintDivPattern.offsetWidth;
		var hH = lexHintDivPattern.offsetHeight;

		if (xH+wH > this.pageWidth-20) {
			xH -= wH;
			if (xH+wH > this.cursorX) xH = xH - ((xH+wH)-this.cursorX) + document.body.scrollLeft - 20;
		};
		if (yH+hH+20 > this.pageHeight-20) {
			yH -= hH;
			if (yH+hH > this.cursorY) yH = yH - ((yH+hH)-this.cursorY) + document.body.scrollTop - 20;
		};
		
		if (xH < 0) xH = 0;
		if (yH < 0) yH = 0;
		if (xH - document.body.scrollLeft < 0) xH = document.body.scrollLeft;
		if (yH - document.body.scrollTop < 0) yH = document.body.scrollTop;
		
		lexHintDiv.style.left = xH + 'px';
		lexHintDiv.style.top = yH + 'px';
		lexHintDiv.style.width = wH + 'px';
		lexHintDiv.style.height = hH + 'px';
			
		var pos = parseInt(this.getMaxZPos()) + 1;
		lexHintDiv.style.zIndex = pos;
	};
	return result;
};

componentPage.prototype.hideLexiconHint = function() //pg2-giub_lexicon
{
	var result = false;
	var LEX_HINT_DIV = 'LEX_HINT_DIV';
	var lexHintDiv = document.getElementById(LEX_HINT_DIV);
	if (lexHintDiv) {
		lexHintDiv.style.visibility = 'hidden';
		result = true;
	};
	return result;
};

/********************************************************************/
var sProtoWBTRes = 'wbtres://';
var sProtoWBTPages = 'wbtpages://';
var sProtoWBTExtras = "wbtextras://";
var dialogWin = null;
function validateURL(url)
{
	if (url.substr(0,sProtoWBTRes.length).toLowerCase() == sProtoWBTRes) {
		return (lms.resourcesURL() + url.substr(sProtoWBTRes.length,url.length));
	};
	if (url.substr(0,sProtoWBTPages.length).toLowerCase() == sProtoWBTPages) {
		return (getPagesUrl() + url.substr(sProtoWBTPages.length,url.length));
	};
	if (url.substr(0,sProtoWBTExtras.length).toLowerCase() == sProtoWBTExtras) {
		return (getExtrasUrl() + url.substr(sProtoWBTExtras.length,url.length));
	};
	return (url);
};

function __checkModal() {
   setTimeout("__finishChecking()", 50);
   return true;
};

function __finishChecking() {
	if (dialogWin != null && !dialogWin.closed) {
		try {
			dialogWin.win.focus();
		} catch (e) {
			if (typeof(log) != 'undefined') log.error(e.message);
		};
	} else {
		dialogWin = null;
		window.onfocus = null;
	};
};

function openDialog(url, w, h, toolbar, menubar, status, scrollbars, resizable)
{
	var x = (screen.width/2)-(w/2);
	var y = (screen.height/2)-(h/2);
	var opt = 'location=no, personalbar=no, directories=no';
	opt += (toolbar != null) ? ', toolbar=' + toolbar :'';
	opt += (menubar != null) ? ', menubar=' + menubar :'';
	opt += (status != null) ? ', status=' + status :'';
	opt += (scrollbars != null) ? ', scrollbars=' + scrollbars :'';
	opt += (resizable != null) ? ', resizable=' + resizable :'';
	opt += (x != null) ? ', left=' + x:'';
	opt += (y != null) ? ', top=' + y:'';
	opt += (w != null) ? ', width=' + w:'';
	opt += (h != null) ? ', height=' + h:'';
	dialogWin = window.open(unescape(validateURL(url)), '', opt);

	try {
		var p = PlayerInterface.connectedPlayer;
		if (p) {
			p.openWindows[p.openWindows.length] = dialogWin;
		};
	} catch(e) {};

	//dialogWin.focus();
	//window.onfocus = __checkModal;
	return (dialogWin);
};

function openWindow(url, options)
{
	return (window.open(validateURL(url), '', options));
};

function calculateTime(timeStart, timeEnd, format)
{
	var dd = Math.abs(timeEnd.getTime() - timeStart.getTime());
	var ts = Math.floor((((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) % (60 * 1000)) / 1000 * 1);
	var tm = Math.floor(((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) / (60 * 1000) * 1);
	var th = Math.floor((dd % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000) * 1);
	switch(format) {
		case "ms":
			var m = (tm + th * 60);
			var sm = ((m < 10) ? "0" : "") + m;
			var ss = ((ts < 10) ? "0" : "") + ts;
			return (sm+':'+ss);
			break;
		case "s":
			return ((th*60*60) + (tm*60) + ts);
			break;
		default:
			var sh = ((th < 10) ? "0" : "") + th;
			var sm = ((tm < 10) ? "0" : "") + tm;
			var ss = ((ts < 10) ? "0" : "") + ts;
			return (sh+':'+sm+':'+ss);
	};
	return ('');
};

/********************************************************************/
//<!--DSFunctions.js-->
/*********************************************************************
**
** Old Functions
**
*********************************************************************/
function getFileNameFromPath(path)
{
	while(path.indexOf('/')>-1) {
		path=path.substring(path.indexOf('/')+1,path.length);
	};
	return path;
};

function getPageDirFromPath(path)
{
	path = path.substring(0, path.lastIndexOf('/'));
	path = path.substring(path.lastIndexOf('/') + 1, path.length);
	return path;
};

// ****************************************************************
function getVideoPath(fullpath)
{
	if ((!parent) && ((!parent.dsBrowser) || (!parent.isWBTServer))) return fullpath;
	if (parent.videoSelected) {
		var videoSelected = parent.videoSelected;
		if (videoSelected == "off") {
			path = "OFF";
		} else
		if (videoSelected == "online") {
			path = fullpath;
		} else
		if (videoSelected == "offline") {
			if ((parent.pathToVideos) != null) {
				path = parent.pathToVideos+'/'+getPageDirFromPath(""+document.location)+'/'+getFileNameFromPath(fullpath);
			};
		};
		return path;
	} else {
		var videoSelected = cookie.get("videoSelected");
		if (videoSelected == "off") {
			path = "OFF";
		} else
		if (videoSelected == "online") {
			path = fullpath;
		} else
		if (videoSelected == "offline") {
			if (cookie.get("pathToVideos") != null) {
				path = cookie.get("pathToVideos") + '/' + getPageDirFromPath("" + document.location)
					+ '/' + getFileNameFromPath(fullpath);
			};
		} else {
			path = fullpath;
		};
		return path;
	};
};

//-------------------------------------
// Function gets element type "moveable". It can be moved
//-------------------------------------
function getParent(element)
{
	temp = element;
	while ((temp != null) && (temp.tagName != "BODY")) {
		if (temp.className == "moveable") {
			element = temp;
			return element;
		} else {
			temp = temp.parentElement;
		};
	};
	return element;
};

function getParentDiv(element)
{
	temp = element;
	while ((temp != null) && (temp.tagName != "BODY")) {
		if (temp.tagName == "DIV") {
			element = temp;
			return element;
		} else {
			temp = temp.parentElement;
		};
	};
	return element;
};

function getMaxZPos()
{
	max = 0;
	tmp = document.getElementsByTagName("*");
	for (i=0; i<tmp.length; i++) {
		if (tmp[i].style.zIndex > max) {
			max = tmp[i].style.zIndex;
		};
	};
	return max;
};

function setOnTop(element)
{
	max = 0;
	tmp = document.getElementsByTagName("*");
	for (i=0; i<tmp.length; i++) {
		if ((tmp[i].style.zIndex > max) && (tmp[i].className == "moveable")) {
			max = tmp[i].style.zIndex;
		};
	};
	element.style.zIndex = max + 2;
};

//-------------------------------------------
// Array management functions
//-------------------------------------------
function push(arrName, element)
{
	var i = arrName.length;
	arrName[i] = element;
};

function pushArrays(arrName, arrValue, element1, element2)
{
	var i = arrName.length;
	var j = arrValue.length;
	arrName[i] = element1;
	arrValue[j] = element2;
};

function getValueFromArray(arrName, arrValue, element)
{
	var i=0;
	for (i=0; i<arrName.length; i++) {
		if (arrName[i] == element) {
			return arrValue[i];
		};
	};
};

function pop(arrName, element)
{
	var i=0;
	var newArr = new Array();
	for (i=0; i<arrName.length; i++) {
		if (arrName[i] != element) {
			push(newArray,arrName[i]);
		};
	};
	return newArr;
};

function actionHideObject(objectName)
{
	elements = document.getElementsByTagName("*");
	if (elements['div_'+objectName]) {
		if (elements['div_'+objectName].tagName == 'DIV') {
			elements['div_'+objectName].style.setAttribute("visibility","hidden","false");
			return false;
		};
	};
};

function actionShowObject(objectName)
{
	elements = document.getElementsByTagName("*");
	if (elements['div_'+objectName]) {
		if (elements['div_'+objectName].tagName == 'DIV') {
			elements['div_'+objectName].style.setAttribute("visibility","visible","false");
			return false;
		};
	};
};

function getIndex(arrayName, objectName, idx)
{
	if (idx+1 >= arrayName.length) return -2;
	for (x=idx+1; x<arrayName.length; x++) {
		//if (objectName == 'div_'+arrayName[x] )
		if (objectName.indexOf('div_' + arrayName[x]) == 0) {
			return x;
		};
	};
	return -2;
};

function makeAmpersand(s)
{
	if (s.charAt(0) != '"') {
		s = '"' + s + '"';
	};
	return s;
};

function onClickObject(object)
{
	if (!object) return false;
	elements = document.getElementsByTagName("*");
	index = -1;
	window.status = object.id;
	if (elements[object.id]) {
		if (elements[object.id].tagName == 'DIV') {
			index = getIndex(onClickObjects,object.id,index);
			while (index > -2) {
				if (index > -2) {
					action = onClickActions[index] + "(" + makeAmpersand(onClickParams[index]) + ")";
					try { //pg2-eval_action
						eval(action);
					} catch(e) {};
					//return true;
				};
				index = getIndex(onClickObjects,object.id,index);
			};
			return false;
		};
	};
	return false;
};

function onMouseOverObject(object)
{
	object = getParentDiv(event.srcElement);
	if (!object) return false;
	elements = document.getElementsByTagName("*");
	index = -1;
	window.status = object.id;
	if (elements[object.id]) {
		if (elements[object.id].tagName == 'DIV') {
			index = getIndex(onMouseOverObjects,object.id,index);
			while (index > -2) {
				if (index > -2) {
					action = onMouseOverActions[index] + "(" + makeAmpersand(onMouseOverParams[index]) + ")";
					try { //pg2-eval_action
						eval(action);
					} catch(e) {};
				};
				index = getIndex(onMouseOverObjects,object.id,index);
			};
			return false;
		};
	};
	return false;
};

function onMouseOutObject(object)
{
	object = getParentDiv(event.srcElement);
	if (!object) return false;
	elements = document.getElementsByTagName("*");
	index = -1;
	window.status = object.id;
	if (elements[object.id]) {
		if (elements[object.id].tagName == 'DIV') {
			index = getIndex(onMouseOutObjects, object.id, index);
			while (index > -2) {
				if (index > -2) {
					action = onMouseOutActions[index] + "(" + makeAmpersand(onMouseOutParams[index]) + ")";
					try { //pg2-eval_action
						eval(action);
					} catch(e) {};
				};
				index = getIndex(onMouseOutObjects,object.id,index);
			};
			return false;
		};
	};
	return false;
};

// Radio handling function
var resetRadioFunctions = new Array();
function resetRadios(obj)
{
	var groupName=''+obj.substr(obj.indexOf('_g_'),obj.length);
	var i = 0;
	var count = resetRadioFunctions.length;
	for (i=0; i<count; i++) {
		var cnt = i;
		var fn = resetRadioFunctions[cnt];
		if (fn.indexOf(groupName)>-1) eval(fn);
	};
};

// Form checking and changing functions
var formFieldNames = new Array();
var formCorrectAnswers = new Array();

function actionChangeFieldValue(fieldname,state)
{
	document.forms['pageForm'].elements[fieldname].value = state;
};

//start MK: ******************************************************************************
// audio video functions
var videoObjects = new Array();
var videoFileNames = new Array();

function actionPlay(which) {
	var orygVideopath=getValueFromArray(videoObjects,videoFileNames,which);
	var videopath = getVideoPath(orygVideopath);
	if (videopath != "OFF") {
		if (videopath != orygVideopath) {
			try {
				eval("media_" + which + ".FileName = videopath");
			} catch(e) {}; //pg2-eval_action
		};
		showTextToMedia(which);
		try { //pg2-eval_action
			eval("media_" + which + ".play();");
		} catch(e) {};
	} else {
		// here show image instead of video:
		actionShowObject ("img_video");
		actionHideObject ("video1");
	};
};
//end MK: ******************************************************************************

function actionStop(which)
{
	eval("media_" + which + ".stop();");
};

function actionPause(which)
{
	try { //pg2-eval_action
		if (eval("media_" + which + ".SendPlayStateChangeEvents")) {
			if (eval("media_" + which + ".PlayState==1"))  {
				eval("media_" + which + ".play();")
			} else {
				eval("media_" + which + ".Pause();")
			};
		};
	} catch(e) {};
};

// other functions
var ObjNames = new Array();
var ObjValues = new Array();

// show correct answer
function actionShowAnswer(obj)
{
	if (showAnswers) {
		var _obj = eval('div_CorrAns_' + obj);
		if (_obj) {
			setOnTop(_obj);
			_obj.style.setAttribute("left", window.event.clientX + 10, "false");
			_obj.style.setAttribute("top", window.event.clientY - 10, "false");
			actionShowObject('CorrAns_' + obj);
		};
	};
};

function FileExists(strURL) //pg2-check if file exists
{
	try {
	    oHttp = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();    
	    oHttp.open("HEAD", strURL, false);
		oHttp.send();
		return (oHttp.status==404) ? false : true;
	} catch(e) {
		return true;
	};
};

//-------------------------------------------
// Opens lexicon and sets it to selected keyword
//-------------------------------------------
function openLexicon(path, keyword)
{
	if (lms.useExternalLexicon()) {
		var lexType = path.substr(3, path.length);
		lexType = lexType.substr(0, lexType.lastIndexOf("/"));
		lms.callExternalLexicon(keyword, lexType);
	} else {
		if (config.ShowLexiconAsHint) return; //pg2-giub_lexicon
		var winWidth = 600;
		var winHeight = 400;
		var windowName = '';
		if (path.indexOf('lexicon') > -1) {
			windowName = 'lexicon';
		} else
		if (path.indexOf('dictionary') > -1) {
			windowName = 'dictionary';
		} else
		if (path.indexOf('grammar') > -1) {
			windowName = 'grammar';
		};
		switch (windowName) {
			case 'lexicon' :
				//winWidth = config.lexiconWindowWidth; //pg2-moved below, 'cause in standard lexicon it overwrites its size!!!
				//winHeight = config.lexiconWindowHeight;
				if (config.useExtrasLexiconAsDefault && config.extrasLexiconFile != "") {
					winWidth = config.lexiconWindowWidth; //pg2
					winHeight = config.lexiconWindowHeight;
					if (page.state != psNormal) {
						page.showInfoAboutHtmlInNewWindow(); //pg2
						return;
					};
					var url = decodeURI(unescape(getExtrasUrl()) + config.extrasLexiconFile) + "?asw=1&key=" + escape(keyword);
					if (FileExists(url)) { //pg2-file exists
						var win = window.open(url, 'wbte_lex', 'width=' + winWidth + ',height=' + winHeight);
						win.focus();
						if (PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.addSubWindowToList(win); //pg2-close win when main window is closed
					};
				} else {
					if (!is.ie) { //pg2-restored, modyfied
						winHeight = 408;
					};
					var url = path + 'index.html?keyword=' + keyword;
					if (FileExists(url)) { //pg2-file exists
						var win = window.open(unescape(url), 'wbte_lex', 'width=' + winWidth + ',height=' + winHeight);
						win.focus();
						if (PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.addSubWindowToList(win); //pg2-close win when main window is closed
					};
				};
				break;
			case 'dictionary' :
				//winWidth = config.dictionaryWindowWidth; //pg2-moved below
				//winHeight = config.dictionaryWindowHeight;
				if (config.useExtrasDictionaryAsDefault && config.extrasDictionaryFile != "") {
					winWidth = config.dictionaryWindowWidth; //pg2
					winHeight = config.dictionaryWindowHeight;
					if (page.state != psNormal) {
						page.showInfoAboutHtmlInNewWindow(); //pg2
						return;
					};
					var url = decodeURI(unescape(getExtrasUrl()) + config.extrasDictionaryFile) + "?asw=1&key=" + escape(keyword);
					if (FileExists(url)) { //pg2-file exists
						var win = window.open(url, 'wbte_dict', 'width=' + winWidth + ',height=' + winHeight);
						win.focus();
						if (PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.addSubWindowToList(win); //pg2-close win when main window is closed
					};
				} else {
					if (!is.ie) { //pg2-restored, modyfied
						winHeight = 418;
					} else {
						winHeight = 423;
					};
					winWidth = 640; //pg2- I don't know what has changed, but now it's apropriate width

					var url = path + 'index.html?keyword=' + keyword;

					if (FileExists(url)) { //pg2-file exists
						var win = window.open(unescape(url), 'wbte_dict', 'width=' + winWidth + ',height=' + winHeight);
						win.focus();
						if (PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.addSubWindowToList(win); //pg2-close win when main window is closed
					};
				};
				break;
			case 'grammar' :
				//winWidth = config.grammarWindowWidth; //pg2- moved below
				//winHeight = config.grammarWindowHeight;
				if (config.useExtrasGrammarAsDefault && config.extrasGrammarFile != "") {
					winWidth = config.grammarWindowWidth; //pg2
					winHeight = config.grammarWindowHeight;
					if (page.state != psNormal) {
						page.showInfoAboutHtmlInNewWindow(); //pg2
						return;
					};
					var url = decodeURI(unescape(getExtrasUrl()) + config.extrasGrammarFile) + "?asw=1&key=" + escape(keyword);
					if (FileExists(url)) { //pg2-file exists
						var win = window.open(url, 'wbte_gram', 'width=' + winWidth + ',height=' + winHeight);
						win.focus();
						if (PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.addSubWindowToList(win); //pg2-close win when main window is closed
					};
				} else {
					if (!is.ie) { //pg2-restored, modyfied
						winHeight = 408;
					};

					var url = path + 'index.html?keyword=' + keyword;
					if (FileExists(url)) { //pg2-file exists
						var win = window.open(unescape(url), 'wbte_gram', 'width=' + winWidth + ',height=' + winHeight);
						win.focus();
						if (PlayerInterface && PlayerInterface.connectedPlayer) PlayerInterface.connectedPlayer.addSubWindowToList(win); //pg2-close win when main window is closed
					};
				};
				break;
		};
	};
	return;
};

function setParentObjHint(obj, hint)
{
	if (!obj) return;
	if (obj.localName == 'body') return;
	
	obj.title = hint;
	setParentObjHint(obj.parentElement, hint);
};

function lex_link_over(obj, type, key)
{
	var showAltHint = true;
	var altHint = "";
	
	if (config.ShowLexiconAsHint && page) { //pg2-giub_lexicon
		showAltHint = !page.showLexiconHint(key, type);
		if (!showAltHint && obj) setParentObjHint(obj, ''); //obj.title = '';
	};
	
	if (pc.__core_lex_hint && showAltHint) { //pg2-giub_lexicon -if 'showAltHint, showing it as hint failed- disabled in config, etc
		var text = "";
		if (type == "lexicon") {
			var lex_item = lexicon.getItem(key);
			if (lex_item != null) {
				var _key = lex_item.key.substr(0, pc.__core_lex_hint.hintKeyLength);
				var _desc = lex_item.description.substr(0, pc.__core_lex_hint.hintDescLength);
				var text = "<center><strong>" + _key + "</strong></center>" + _desc
					+ ' <a ' + getAttributeText(obj, "href") + ' ' + getAttributeText(obj, "onclick") + '>...</a>';
				showAltHint = false;
			};
		} else
		if (type == "dictionary") {
			var dic_item = dictionary.getItem(key);
			if (dic_item != null) {
				var _key = dic_item.key.substr(0, pc.__core_lex_hint.hintKeyLength);
				var _desc = dic_item.description.substr(0, pc.__core_lex_hint.hintDescLength);
				var text = "<center><strong>" + _key + "</strong></center>" + _desc
					+ ' <a ' + getAttributeText(obj, "href") + ' ' + getAttributeText(obj, "onclick") + '>...</a>';
				showAltHint = false;
			};
		};
		if (!showAltHint) {
			pc.__core_lex_hint.automaticHideTimerInterval = 0;
			pc.__core_lex_hint.showHint(text, type);
		};
	};
	if (showAltHint) {
		if (altHint == "") altHint = key;
		obj.title = altHint;
	};
};

function lex_link_out(obj)
{
	obj.title = "";
	var hiddenHint = false;
	if (config.ShowLexiconAsHint && page) { //pg2-giub_lexicon
		hiddenHint = page.hideLexiconHint();
	};
	if (pc.__core_lex_hint && !hiddenHint) { //pg2-giub_lexicon -hiddenHint
		pc.__core_lex_hint.automaticHideTimerInterval = pc.__core_lex_hint._automaticHideTimerInterval;
		pc.__core_lex_hint._automaticHideTimerRun();
	};
};

function checkIsScenario()
{
	str = '' + document.location;
	if (str.indexOf('scenario=true') > 0) isScenario=true;
};

function setDSTimeout(action, object, time)
{
	if (isScenario) time = 0;
	var timeAction = 'setTimeout(\"' + action + '(\'' + object + '\')\"' + ',' + time + ')';
	eval(timeAction);
};

componentPage.prototype.createScrollLayer = function(contentText)
{
	var w = (me.__audioTextScrollerWidth)?parseInt(me.__audioTextScrollerWidth):700;
	var h = (me.__audioTextScrollerHeight)?parseInt(me.__audioTextScrollerHeight):50;
	var l = (me.__audioTextScrollerLeft)?parseInt(me.__audioTextScrollerLeft):25;
	var t = (me.__audioTextScrollerTop)?parseInt(me.__audioTextScrollerTop):530;
	this.pageScroll = new newScrollLayer(l, t, w, h, resourcesURL + "___.media.scroller", 12, 12, contentText);
};

function setScrollText(text)
{
	if (text == null) return false;
	if (text == '') return false;
	if (pageScroll != null) {
		pageScroll.setContent(text);
		pageScroll.setThumbPos(pageScroll.maxThumb);
		pageScroll.showScrollbar(true);
	};
};

componentPage.prototype.addScrollText = function(text)
{
	if (text == null || text == "") return false;
	if (this.pageScroll == null) {
		var w = (me.__audioTextScrollerWidth)?parseInt(me.__audioTextScrollerWidth):700;
		var h = (me.__audioTextScrollerHeight)?parseInt(me.__audioTextScrollerHeight):50;
		var l = (me.__audioTextScrollerLeft)?parseInt(me.__audioTextScrollerLeft):25;
		var t = (me.__audioTextScrollerTop)?parseInt(me.__audioTextScrollerTop):530;
		this.pageScroll = new newScrollLayer(l, t, w, h, resourcesURL + "___.media.scroller", 12, 12, '');
	};
	if (this.pageScroll != null) {
		this.pageScroll.addContent(text);
		this.pageScroll.setThumbPos(this.pageScroll.maxThumb);
		this.pageScroll.showScrollbar(true);
	};
};

function showScroll()
{
	if (pageScroll != null) pageScroll.showScrollbar(true);
};

function hideScroll()
{
	if (pageScroll != null) pageScroll.showScrollbar(false);
};

function newScrollLayer(nLeft, nTop, nWidth, nHeight, imagePath, buttonWidth, buttonHeight,contentText)
{
	this.id = newScrollLayer.instanceNr++;
	newScrollLayer.layers[this.id] = this;
	this.objectName = 'newScrollLayer.layers[' + this.id + ']';
	this.imagePath = imagePath;
	this.left = nLeft;
	this.top = nTop;
	this.width = nWidth;
	this.height = nHeight;
	this.scrollOffset = 0;
	this.buttonWidth = buttonWidth?buttonWidth:16;
	this.buttonHeight = buttonHeight?buttonHeight:16;
	this.timer = 0;
	this.content = '';
	this.thumbDown = true;
	this.maxThumb = this.height - 3 * this.buttonHeight;
	this.thumbOffset = 0;
	this.layer = createLayer('scroller' + this.id, null, this.left, this.top, this.width, this.height,'', null, 'inherit', 100);
	if (this.layer.style) this.layer.style.overflow = "hidden";
	this.contentLayer = createLayer('content' + this.id, 'scroller' + this.id, 0, 0, this.width-this.buttonWidth, null, contentText, null, 'visible', 1);
	var downBtn = '<img src="' + imagePath + 'down0.gif" width="' + this.buttonWidth + '" height="' + this.buttonHeight + '">';
	var upBtn =  '<img src="' + imagePath + 'up0.gif" width="' + this.buttonWidth + '" height="' + this.buttonHeight + '">';
	var thumbBtn = '<img src="' + imagePath + 'thumb.gif" width="' + this.buttonWidth + '" height="' + this.buttonHeight + '">';
	var nothingBtn = '<img src="' + imagePath + 'nothing.gif" name="nix" width="' + this.buttonWidth + '" height="' + this.height + '">';
	this.down = createLayer('scrollerdown' + this.id, 'scroller' + this.id, this.width - this.buttonWidth, this.height - this.buttonHeight, this.buttonWidth, this.buttonHeight, downBtn, null, 'inherit', 2);
	this.up = createLayer('scrollerup' + this.id, 'scroller' + this.id, this.width - this.buttonWidth, 0, this.buttonWidth, this.buttonHeight, upBtn, null, 'inherit', 2);
	this.thumb = createLayer('thumb' + this.id, 'scroller' + this.id, this.width - this.buttonWidth, this.buttonHeight, this.buttonWidth, this.buttonHeight, thumbBtn, null, 'inherit', 2);
	this.nothinglayer = createLayer('nothing' + this.id, 'scroller' + this.id, this.width - this.buttonWidth, 0, this.buttonWidth, this.height, nothingBtn, null, 'inherit', 3);
	this.hrtop = createLayer('hrtop' + this.id,null, this.left, this.top-10, this.width,8, '<HR>', null, 'visible', 4);
	this.setContentPos = sl_setContentPos;
	this.setContentPosIntern = sl_setContentPosIntern;
	this.setThumbPos = sl_setThumbPos;
	this.setThumbPosIntern = sl_setThumbPosIntern;
	this.scroll = sl_scroll;
	this.setContent = sl_setContent;
	this.addContent = sl_addContent;
	this.getContent = sl_getContent;
	this.onThumbMove = sl_onThumbMove;
	this.onThumbDown = sl_onThumbDown;
	this.onThumbUp = sl_onThumbUp;
	this.update = sl_update;
	this.showScrollbar = sl_showScrollbar;
	routeLayerEvent(this.nothinglayer, 'onmousemove', this.objectName + ".onThumbMove");
	routeLayerEvent(this.nothinglayer, 'onmousedown', this.objectName + ".onThumbDown");
	routeLayerEvent(this.nothinglayer, 'onmouseup', this.objectName + ".onThumbUp");
	routeLayerEvent(this.nothinglayer, 'onmouseout', this.objectName + ".onThumbUp");
	this.update();
	this.setThumbPos(this.maxThumb);
	this.showScrollbar(false);
};

newScrollLayer.instanceNr = 0;
newScrollLayer.layers = new Array();

function routeLayerEvent(layerObj, eventName, handler, params) 
{
	if (is.moz) {
		layerObj[eventName] = new Function(handler + "(0, 0, event);return false;");
	} else {
		layerObj[eventName] = new Function(handler + "(window.event.offsetX, window.event.offsetY, event);return false;");
	};
};

function sl_update()
{
	this.contentHeight = this.contentLayer.offsetHeight;
	this.maxScrollOffset = Math.max(this.contentHeight-this.height, 0);
	if (this.maxScrollOffset == 0) {
		this.showScrollbar(false);
	} else {
		this.showScrollbar(true);
	};
	this.setContentPos(this.scrollOffset);
};

function sl_setContent(newContent)
{
	this.content = newContent;
	setLayerText(this.contentLayer, newContent);
	this.update();
};

function sl_addContent(newContent)
{
	this.content = newContent;
	addLayerText(this.contentLayer, newContent);
	this.update();
};

function sl_getContent()
{
	return this.content;
};

function sl_setContentPos(newPos)
{
	this.setContentPosIntern(newPos);
	if (this.maxScrollOffset > 0) {
		this.setThumbPosIntern(Math.round(this.maxThumb * newPos / this.maxScrollOffset));
	};
};
function sl_setContentPosIntern(newPos)
{
	if (newPos < 0) newPos = 0;
	if (newPos > this.maxScrollOffset) newPos = this.maxScrollOffset;
	this.scrollOffset = newPos;
	this.contentLayer.style.top = -this.scrollOffset;
};

function sl_scroll(delta)
{
	this.setContentPos(this.scrollOffset + delta);
};

function sl_onThumbDown(x, y, e)
{
	if (is.moz) {
		var curleft = 0;
		var curtop = 0;
		var obj = e.target;
		if (obj.offsetParent) {
			while (obj.offsetParent) {
				curleft += obj.offsetLeft
				curtop += obj.offsetTop
				obj = obj.offsetParent;
			};
		};
		x = e.pageX - curleft;
		y = e.pageY - curtop;
		moveScroll(x, y, this);
	} else {
		moveScroll(x, y, this);
	};
};

function moveScroll(x, y, elem)
{
	if (y <= elem.buttonHeight) {
		elem.scroll(-5);
	} else
	if (y >= elem.height-elem.buttonHeight) {
		elem.scroll(5);
	} else {
		elem.thumbDown = true;
		elem.oldy = -1;
	};
};

function sl_onThumbUp(x, y)
{
	if (this.timer != 0) {
		clearInterval(this.timer);
		this.timer = 0;
	};
	this.thumbDown = false;
};

function sl_setThumbPos(newPos)
{
	this.setThumbPosIntern(newPos);
	this.setContentPosIntern( Math.round(this.maxScrollOffset * (this.thumbOffset / this.maxThumb)) );
};

function sl_setThumbPosIntern(newPos)
{
	if (newPos < 0) newPos = 0;
	if (newPos > this.maxThumb) newPos = this.maxThumb;
	this.thumbOffset = newPos;
	this.thumb.style.top = this.buttonHeight + this.thumbOffset;
};

function sl_onThumbMove(x, y)
{
	if (this.thumbDown) {
		if (this.oldy > 0) {
			var newThumby = this.thumbOffset + y - this.oldy;
			this.setThumbPos(newThumby);
		};
		this.oldy = y;
	};
};

function createLayer(id, nestref, left, top, width, height, content, bgColor, visibility, zIndex)
{
	var lyr;
	var audioTextDIV = document.createElement("DIV");
	audioTextDIV.setAttribute("id", id);
	audioTextDIV.style.left = left;
	audioTextDIV.style.top = top;
	audioTextDIV.style.width = width;
	if (height != null) {
		audioTextDIV.style.height = height;
		audioTextDIV.style.clip = 'rect(0px '+width+'px '+height+'px 0px)';
	};
	if (bgColor != null) audioTextDIV.style.background = bgColor;
	if (zIndex != null) audioTextDIV.style.zIndex = zIndex;
	if (visibility) audioTextDIV.style.visibility = visibility;
	audioTextDIV.style.position = 'absolute';
	if (content) audioTextDIV.innerHTML = content;
	var beforeElem = null;
	if (nestref) {
		index = nestref.lastIndexOf(".");
		var nestlyr = (index != -1)? nestref.substr(index+1) : nestref;
		var obj = getObject2(nestlyr);
		if (obj) { //pg2
			if (obj.childNodes.length > 0) {
				beforeElem = obj.childNodes[0];
				obj.insertBefore(audioTextDIV, beforeElem)
			} else {
				obj.appendChild(audioTextDIV);  
			};
		};
	} else {
		beforeElem = document.body.childNodes[document.body.childNodes.length-1];
		document.body.insertBefore(audioTextDIV, beforeElem)
	};
	lyr = getObject2(id);
	return lyr;
};

function getObject2(r, d)
{
	if (!d) d=document;
	return elem = d.getElementById(r);
};

function setLayerText(aLayer, aText)
{
	if (typeof(aLayer) == 'string') {
		aLayer = getObject2(aLayer);
	};
	if (aLayer) {
		aLayer.innerHTML = aText;
	};
};

function addLayerText(aLayer, aText)
{
	if (typeof(aLayer) == 'string') aLayer = getObject2(aLayer);
	if (aLayer) {
		if (aLayer.innerHTML == '') {
			aLayer.innerHTML = aText;
		} else {
			aLayer.innerHTML += '<BR>--------------------<BR>' + aText;
		};
	};
};

function setLayerVisible(aLayer, aState)
{
	if (typeof(aLayer) == 'string') {
		aLayer = getObject2(aLayer);
	};
	if (aLayer) {
		if (aLayer.style) {aLayer.style.visibility = (aState)?'inherit':'hidden'};
		if (!aLayer.style) {aLayer.visibility = (aState)?'inherit':'hide'};
	};
};

function sl_showScrollbar(visible)
{
	setLayerVisible(this.contentLayer, visible);
	setLayerVisible(this.down, visible);
	setLayerVisible(this.up, visible);
	setLayerVisible(this.thumb, visible);
	setLayerVisible(this.hrtop, visible);
};

function showTextToMedia(mediaName)
{
	for (i=0; i<videoObjects.length; i++) {
		if (videoObjects[i] == mediaName) {
			if (i <= scrollTexts.length) addScrollText(scrollTexts[i]);
			break;
		};
	};
};

//********************************************************************
var aPanelKey = new Array(65,68,77,73,78,80,65,78,69,76,18);
var iKeyIndex = 0;
//var keydownListeners = [];
var keyAltDown = false;

function addKeyDownListener(listener)
{
	var p = getPage();
	if (!p) return;
	for (var i=0; i<p.keydownListeners.length; i++) {
		if (p.keydownListeners[i] == listener) return;
	};
	p.keydownListeners[p.keydownListeners.length]=listener;
};

function removeKeyDownListener(listener)
{
	var p = getPage();
	if (!p) return;
	for (var i = 0; i < p.keydownListeners.length; i++) {
		if (p.keydownListeners[i] == listener) p.keydownListeners.splice(i, 1);
	};
};

function disableHotKey(evt)
{
	var disabled = {a:0, c:0, x:0, v:0, d:0, p:0, s:0, r:0, w:0};
	var ctrlMod = (window.event)? window.event.ctrlKey : evt.ctrlKey;
	var altMod = (window.event)? window.event.altKey : evt.altKey;
	var altLeftMod = (window.event)? window.event.altLeft : evt.altLeft;
	// sometimes right ALT present state as CRTL
	if (altMod && !altLeftMod && ctrlMod) ctrlMod = false;
	var key = (window.event)? window.event.keyCode : evt.which;
	key = String.fromCharCode(key).toLowerCase();
	return (ctrlMod && (key in disabled))? false : true;
};

document.onkeypress = function(e)
{
	var ev = (window.event) ? event : e;
	var p = getPage();
	if (!p) return;
	for(var i=0; i<p.keydownListeners.length; i++) {
		p.all[p.keydownListeners[i]].invokeEvent("KeyPress", ev);
	};
};

var touchStartEvent = function(e) { //pg2-PCEN_DND
	//do nothing, element will capture it
};

var touchMoveEvent = function(e) { //pg2-PCEN_DND
	//do nothing, element will capture it
};

var touchEndEvent = function(e) { //pg2-PCEN_DND
	//do nothing, element will capture it
};

var keyDownEvent = function(e)
{
	var ev = (window.event)?event:e;
	var key = (window.event)?event.keyCode:e.keyCode;
	if (typeof(adminPanel) != "undefined" && adminPanel) {
		if (key == (aPanelKey[iKeyIndex])) {
			iKeyIndex++
			if (aPanelKey.length == iKeyIndex) {
				iKeyIndex = 0;
				adminPanel.showWindow();
			};
		};
	};

	if (key == 9 && config.FocusManegementForSynthesizer) { //pg2-TEST_EM -focus on input (it was set to its 'obj' and not main div- so cursor was hidden
		if (page.tabOverrideComponent != null && page.resetTabComponent == null) {
			var nextOne = page.getNextElementToBeFocused(page.tabOverrideComponent);
			if (nextOne != null) {
				var str = 'pc.' + nextOne.id + '.obj.focus();';
				if (nextOne.type == 'componentInput' && !nextOne.locked) {
					str += ' pc.' + nextOne.id + '.focus();';
				};
				str += ' page.processRadiobuttons();';
				window.setTimeout(str , 50);
				top.window.document.title = page.tabOverrideComponent.id + ', ' + nextOne.id;
				page.tabOverrideComponent = nextOne;
				//if (page.tabOverrideComponent.id == 'input2') page.tabOverrideComponent = null; //test
				if (nextOne.resetFocus) nextOne.resetFocus = false;
			};
		} else {
			if (page.resetTabComponent == null) page.startFocusTimer();
		};
	};
	
	var p = getPage();
	if (!p) return;
	for (var i=0; i<p.keydownListeners.length; i++) {
		p.all[p.keydownListeners[i]].invokeEvent("KeyDown", ev);
	};
	PlayerInterface.SetValue("studentActive");
	return disableHotKey(e);
};

var keyUpEvent = function(e)
{
	if(!e) var e = event;
	//pg2-add navigation via Ctrl and arrows: left (previous page) and right (next page)
	var keyCode = (window.event)?event.keyCode:e.keyCode;
	var isCtrlPressed = (window.event)? window.event.ctrlKey : evt.ctrlKey;
	var isAlt = (window.event)? window.event.altKey : evt.altKey;
	var isShiftPressed = e?e.shiftKey:window.event.shiftKey; //pg2-UnRz_keyboardNavi -a little bit different way, but standard didn't work in Firefox
	
	if (isAlt && keyCode == 190/*>*/) {
		page.nextStep();
	}
	if (isAlt && keyCode == 188/*<*/) {
		page.prevStep();
	}
	
	if (keyCode == 9 && page.resetTabComponent != null) { //pg2-aps_test
		page.resetTabComponent.resetFocus = false;
		page.resetTabComponent = null;
		page.tabOverrideComponent = null;
		page.setFocusOnFirstTabIndex();
		//page.startFocusTimer();
	} else
	if (config.FireOnClickOnReturnKey || config.FocusManegementForSynthesizer) { // && is.ie) { //pg2-in new Firefox it also is working
		if (keyCode == 13 || keyCode == 32) { //pg2-APS - in IE if focus is given to some component (via TAB key) and it has "OnClick", if 'ENTER' will be pressed, invoke 'OnClick'
			var actElem = '';
			try {
				actElem = document.activeElement.id;
			} catch(e) {};
			var pElem = null;
			try {
				actElem = actElem.replace('_contentObj', ''); //pg2-TEST_EM -focus on input (it was set to its 'obj' and not main div- so cursor was hidden
				if (actElem != null) eval('pElem = pc.' + actElem + ';');
				
				if (pElem.type == 'componentInput' && keyCode == 32) { //pg2-TEST_EM -focus on input (it was set to its 'obj' and not main div- so cursor was hidden
					//pg2-do nothing...for now
				} else {
				
					if ((pElem.type == 'componentShowExerciseFeedback' || pElem.type == 'componentShowExerciseFeedbackExt') && (typeof(pElem.eventClick) == 'function')) {
						pElem.eventClick();
					} else
					if (typeof(pElem.confirmAnswer) != 'undefined' && pElem.confirmAnswer) {
						var p = getPage();
						if (p) p.checkAnswer();
					} else
					if (pElem != null && typeof(pElem.onClick) == 'function') {
						if (typeof(pElem.changeChecked) != 'undefined') {
							pElem.changeChecked();
						} else {
							pElem.invokeEvent("Click");
						};
					};
					
					if (config.FocusManegementForSynthesizer) page.processRadiobuttons(); //pg2-aps_test
					
					if (pElem != null && pElem.resetFocus) {
						page.tabOverrideComponent = null;
						pElem.resetFocus = false;
						//this.startFocusTimer();
						page.setFocusOnFirstTabIndex();
					} else {				
						try {
							if (page.tabOverrideComponent) page.tabOverrideComponent.obj.focus();
						} catch(e) {};
					};
				}; //...
				
			} catch(e) {};
		} else
		if (keyCode == 9) { //pg2-aps -tab
			/* 
			 //pg2-TEST_EM -focus on input (it was set to its 'obj' and not main div- so cursor was hidden -removed, new interception in 'keyDownEvent'
			var actElem = '';
			try {
				actElem = document.activeElement.id;
				if (config.FocusManegementForSynthesizer) page.processRadiobuttons(); //pg2-aps_test
			} catch(e) {};
			var pElem = null;
			try {
				actElem = actElem.replace('_contentObj', ''); //pg2-TEST_EM
				if (actElem != null) eval('pElem = pc.' + actElem + ';');
				if (pElem && pElem.tabIndex != '') {
					page.tabOverrideComponent = pElem;
					pElem.obj.focus();
					//this.startFocusTimer();
					if (pElem.resetFocus) pElem.resetFocus = false;
				};
			} catch(e) {};
			if (!pElem) {
				page.tabOverrideComponent = null;
				page.setFocusOnFirstTabIndex();
			};
			*/
		};
	};
	//pg2- Ctrl+Q in debug mode - show correct answer
	if (keyCode == 81 && isCtrlPressed) {
		var p = getPage();
		if (p && p.showCorrectAnswer) {
			if (p.state == psView || (typeof(config.DebugMode) != 'undefined' && config.DebugMode)) p.showCorrectAnswer();
		};
	};
	if (config.keyboardNavigation) {
		if (keyCode == 39 && isCtrlPressed) { //Ctrl + ArrowRight
			var p = getPage();
			if (p && p.nextPage) {
				p.nextPage();
			};
		} else
		if (keyCode == 37 && isCtrlPressed) { //Ctrl + ArrowLeft
			var p = getPage();
			if (p && p.prevPage) {
				p.prevPage();
			};
		} else
		if (keyCode == 39 && isShiftPressed) { //pg2-UnRz_keyboardNavi -Shift + ArrowRight = NextStep
			var p = getPage();
			if (p && p.nextStep) {
				p.nextStep();
			};
		} else
		if (keyCode == 37 && isShiftPressed) { //pg2-UnRz_keyboardNavi -Shift + ArrowLeft = PrevStep
			var p = getPage();
			if (p && p.prevStep) {
				p.prevStep();
			};
		};
	};
	return disableHotKey(e);
};

(function() {
	if (document.addEventListener) {
		document.addEventListener('keydown', keyDownEvent, false);
		document.addEventListener('keyup', keyUpEvent, false);
		
		if (is.mobile && is.android) { //pg2-PCEN_DND
			document.addEventListener('touchstart', touchStartEvent, false);
			document.addEventListener('touchmove', touchMoveEvent, false);
			document.addEventListener('touchend', touchEndEvent, false);
		};
	} else {
		document.attachEvent('onkeydown', keyDownEvent);
		document.attachEvent('onkeyup', keyUpEvent);
	};
})();
//********************************************************************
componentPage.prototype.setSizes = function()
{
	for (var i=0; i<this.children.length; i++) {
		var child = this.children[i];
		if (child.setSizes) {
			child.setSizes();
			if (!child.execution) {
				child.paint();
			} else {
				child.style.left = child.x;
				child.style.top = child.y;
				child.style.width = child.w-2*child.borderWidth;
				child.style.height = child.h-2*child.borderWidth;
				child.repaint();
			};
		};
	};
};

window.onhelp = function()
{
	return false;
};

window.onresize = function(e)
{
	if (typeof(page) != "undefined" && page) {
		page.resize();
	};
};
componentPage.prototype.resize = function(obj)
{
	for (var i = 0; i < this.children.length; i++) {
		if (this.children[i] != obj) this.children[i].invokeEvent("Resize");
	};
};

componentPage.prototype.clickOutside = function(obj)
{
	for (var i = 0; i < this.children.length; i++) {
		var child = this.children[i];
		if (child != obj) {
			if (!child.confirmAnswer && child.visible) child.invokeEvent("ClickOutside"); //pg2-events, pg2- invoke 'ClickOutside' only if element with this event is visible
		};
	};
};

componentPage.prototype.changeCourseVersion = function(versionId)
{
	if (PlayerInterface.GetValue("getCourseVersion") != versionId) PlayerInterface.SetValue("setCourseVersion", versionId); //pg2-now it can be used in events 'onLoad/onAfterLoad'
};

componentPage.prototype.setSelectionEnable = function()
{
	this.enableSelection = true;

	//pg2-context_menu_ON-OFF
	document.body.oncontextmenu = null;
	
	if (is.ie) this.obj.unselectable = ""; else
	if (is.moz) this.obj.style.setProperty("-moz-user-select", "auto", "");
	if (!is.ie) {
		this.obj.style.setProperty("-khtml-user-select", "auto", "");
		this.obj.style.setProperty("-webkit-user-select", "auto", "");
		this.obj.style.setProperty("user-select", "auto", "");
		this.obj.style.setProperty("-ms-user-select", "auto", ""); //pg2-ie11
	};
	for (var i=0; i<this.children.length; i++) {
		this.children[i].unselectable();
	};
	//...
};

componentPage.prototype.setSelectionDisable = function()
{
	this.enableSelection = false;

	//pg2-context_menu_ON-OFF
	document.body.oncontextmenu = function(e) {return false;};
	
	if (is.ie) this.obj.unselectable = "on"; else
	if (is.moz) this.obj.style.setProperty("-moz-user-select", "none", "");
	if (!is.ie) {
		this.obj.style.setProperty("-khtml-user-select", "none", "");
		this.obj.style.setProperty("-webkit-user-select", "none", "");
		this.obj.style.setProperty("user-select", "none", "");
		this.obj.style.setProperty("-ms-user-select", "none", ""); //pg2-ie11
	};
	for (var i=0; i<this.children.length; i++) {
		this.children[i].unselectable();
	};
	//
};

componentPage.prototype.setSelectionColor = function(value)
{
	this.selectionColor = value;
};

componentPage.prototype.showWarningPopup = function()
{
	//if (!config.showInternalInactivityPopup) return; //pg2-inactivity time
	if (!config.inactivityEnabled) return; //pg2-inactivity_control
	if (config.showInternalInactivityPopup) {
		var obj = this.all[this.warningPopupID];
		if (obj) {
			obj.show();
		} else {
			var newObj = PageInterface.Execute("createChild", "__warningPopup", this.warningPopupID);
			if (newObj) {
				newObj.w = this.body.clientWidth;
				newObj.h = this.body.clientHeight;
				newObj.bgColor = "transparent"; //"#000000";
				newObj.z = 999;
				newObj.setOKFunction('this.ImActiveNow();');
				var lang = getLang();
				if (lang != null) {
					newObj.setOKCaption(getLang().getMessage("PAGE_POPUP_CLOSE"));
				} else {
					newObj.setOKCaption('Close');
				};
				var warningPopup = PageInterface.Execute("addChild", newObj);
				if (warningPopup) {
					warningPopup.show();
				};
			};
		};
	} else { //pg2-inactivity_control
		var inactiveComponentName = 'inactivityWarningPopup';
		if (this.inactivityPopup == null) {
			this.inactivityPopup = getComponentByPartialId(inactiveComponentName);
		};
		if (this.inactivityPopup != null) this.inactivityPopup.show();
	};
};

componentPage.prototype.hideWarningPopup = function()
{
	var obj = this.all[this.warningPopupID];
	if (obj) {
		obj.hide(); //displayHTMLElement(obj, "");
	};
};

componentPage.prototype.showEndLessonPopup = function()
{
	this.hideWarningPopup();
	var obj = this.all[this.endLessonPopupID];
	if (obj) {
		obj.show();
	} else {
		var newObj = PageInterface.Execute("createChild", "__warningPopup", this.endLessonPopupID);
		if (newObj) {
			newObj.w = this.body.clientWidth;
			newObj.h = this.body.clientHeight;
			newObj.bgColor = "#000000";
			newObj.z = 999;
			newObj.enableJumping = false;
			newObj.setPopupType(2, true, true);
			var warningPopup = PageInterface.Execute("addChild", newObj);
			warningPopup.show();
		};
	};
};

componentPage.prototype.showInfoAboutHtmlInNewWindow = function() //pg2
{
	try {
		var msgPart1 = window.external.GetLangText("COMPONENT_ACTION_OPEN_DIALOG");
		var msgPart2 = window.external.GetLangText("ACTION_WORKS_AFTER_EXPORT_INFO");
		alert(msgPart1 + ".\n" + msgPart2 + ".");
	} catch(e) {
		alert("HTML Document in New Window.\nThis action works fine only after course export.");
	};
};

document.onclick = function(e)
{
	if (typeof(page) != "undefined" && page) {
		page.clickOutside();
	};
	PlayerInterface.SetValue("studentActive");
};

function onMouseMoveFromPage(e) //pg2-d'n'd feedback and mousemove restore -to be able to restore it without typing entire code (mouseevent.js)
{
	if (typeof(page) != "undefined" && page) {
		if (!e) var e = window.event;
		if (e) {
			page.cursorX = e.clientX;
			page.cursorY = e.clientY;
		};
	};
};

document.onmousemove = onMouseMoveFromPage; //pg2-d'n'd feedback and mousemove restore

/*document.onmousemove = function(e)
{
	if (typeof(page) != "undefined" && page) {
		if (!e) var e = window.event;
		if (e) {
			page.cursorX = e.clientX;
			page.cursorY = e.clientY;
			//top.window.document.title = page.cursorX + ', ' + page.cursorY; //pg2-giub_lexicon_test
		};
	};
};*/
//********************************************************************Fisread
