
	var dataproject = {};
	var project = {};
	var monitorlist = [];
	var websocketmsgs = [];
	var qs = getQueryStrings();
	var pb_ready = true;
	
	var newmsgid = 1;
	
	if (qs.touchpanel === '1' || qs.wallcon === '1' || qs.wallcon === 'true') var touchpanel = true;
	else touchpanel = false;
	if (qs.preview === '1' || qs.preview === 'true' || qs.preview === true) 
		var preview = true;
	else preview = false;
	
	/*setTimeout(function(){//if (!(window.innerHeight == screen.height)){ //websocket.emit('message', {command: 'fullscreen'});
		//if ((document.fullScreenElement && document.fullScreenElement !== null) || (!document.mozFullScreen && !document.webkitIsFullScreen)){
			if (document.documentElement.requestFullScreen){  
				document.documentElement.requestFullScreen();  
			} 
			else if (document.documentElement.mozRequestFullScreen){  
				document.documentElement.mozRequestFullScreen();  
			} 
			else if (document.documentElement.webkitRequestFullScreen){  
				document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);  
			}  
		//}
	//}
	}, 4000);*/

	//setTimeout(function(){if (!(window.innerHeight == screen.height)) websocket.emit('message', {command: 'fullscreen'});}, 1000);
	
	if (!touchpanel){
	
		$('#tpstyle').remove();
		
	}
	
	if (Server) Server.inbound = Server.outbound = Server.errors = Server.warnings = Server.notices = false;
	
	$('#loadingscreen').fadeOut();
	
	if (qs.mobile === '1' || qs.mobile === 'true' || qs.mobile === true) var qs_is_mobile = true;
	else var qs_is_mobile = false;
	
	var homebuttondown = false;
	var homebuttontimer = false;
	var keydown = false;
	
	var panelswitched = false;

	if (0) cWebSocket.init();
	
	var _updating = true;
	var updateInterval = setInterval(function(){
		if (_updating) updatePanel();
	}, 1000);
	
	if (wallcon){
		var wallcontroller = {};
		$('#infopage').load("../tmp/ipSettings.html").css({fontSize: '30px'});
		getStatusOfUnit({ip: location.host, port: 50001}, function(data, status){
			wallcontroller = status;
		});
	}
	if (modero){
		var wallcontroller = {};
		$('#infopage').load("../tmp/ipSettings.html").css({fontSize: '30px'});
		getStatusOfUnit({ip: location.host, port: 50001}, function(data, status){
			wallcontroller = status;
		});
	}
	
	//console.log('starting');
	var fromDB = false;

	if (preview){
		pb.previewinterval = setInterval(function(){
			if (pb.idb){
				getLocalDBObject('projectpreview', function(data){
					project = data;
					project.panels = makePanels(project);
					
					if (!undef(qs.panel))
						setPanel(qs.panel-1);
					else {
						var found = false;
						for (var i=0;i<dataproject.panels.length;i++){
							if (dataproject.panels[i].core && dataproject.panels[i].core.defaultpanel){
								setPanel(i);
								found = true;
							}
						}
						if (!found) setPanel(0);
					}
					if (project.modulelist) for (var i=0; i<project.modulelist.length; i++){
						if (project.modulelist[i].required){
							//console.log('requiring ', project.modulelist[i].file);
							sandbox('require("'+project.modulelist[i].file+'");');
						}
					}
					if (project.core && project.core.scripts){
						console.log('running setup script'); 
						waitfor(function(){
							return (Sandbox.frame.contentWindow && Sandbox.isready);
						}, function(){
							//console.log('t',project.core && project.core.scripts);
							if (project.core && project.core.scripts){sandbox(project.core.scripts[0], 'setup');}
							Sandbox.waiting = false;
						});
						//sandbox(project.core.scripts[0]);
					}
					updatePanel();
					mouse.inittouch();
				});
				clearInterval(pb.previewinterval);
			}
		}, 200);
	}
	else {
		if (0 && useDB_read){
			queryDB({
				opts: {query: 'select', id: qs.project}, 
				callback: loadProject
			});
		}
		else {
			var opts = {};
			if (touchpanel) opts.wallcon = true;
			opts.command = 'read_project';
			opts.puid = qs.project;
			websocket.emit('message', opts, loadProject);
			/*server({
				opts: opts, 
				callback: loadProject
			});*/
		}
	}
		
	function loadProject(data){
		console.log('data '+data);
		//if (data === false) location.href = '../initial.php';
		
		if (data.substring(0, 17) == 'project_too_large'){
			$('#thebody').append('<div style="color: white; text-align: center; cursor: none;">Project too large for wall controller.</div>');
			$('head').append('<style>* {cursor: none !important;}\
				body {overflow: hidden}\
			</style>');
			$('#thebody').click();
			return;
		}
		
		if (data.substring(0, 17) == 'project_not_found'){
			//console.log('no_luck');
			queryDB({
				opts: {query: 'select', id: qs.project}, 
				callback: loadDBProject
			});
			return;
		}
		
		dataproject = json_decode(data);
		if (dataproject.core.passkey){
			window.passkey = dataproject.core.passkey;
			$('#security')[0].style.display = "block";
			$('#security-panel').center();
		}

		project.name = dataproject.name;
		project.puid = dataproject.puid;
		project.core = dataproject.core;
		project.panels = makePanels(dataproject);
		project.modulelist = dataproject.modulelist;
		
		if (project.panels.length == 1) setPanel(0);
		else {
			if (!undef(qs.panel)) setPanel(qs.panel);
			else {
				var found = false;
				for (var i=0;i<dataproject.panels.length;i++){
					if (dataproject.panels[i].core && dataproject.panels[i].core.defaultpanel){
						setPanel(i);
						found = true;
					}
				}
				if (!found) setPanel(0);
			}
		}
		if (project.modulelist) for (var i=0; i<project.modulelist.length; i++){
			if (project.modulelist[i].required){
				//console.log('requiring ', project.modulelist[i].file);
				sandbox('require("'+project.modulelist[i].file+'");');
			}
		}
		/*if (project.core && project.core.scripts){
			console.log('setup script', project.core.scripts[0]);
			sandbox(project.core.scripts[0]);
		}*/
		waitfor(function(){
			return (Sandbox.frame.contentWindow && Sandbox.isready);
		}, function(){
			if (project.core && project.core.scripts){sandbox(project.core.scripts[0], 'setup');}
			Sandbox.waiting = false;
		});
		updatePanel();
		mouse.inittouch();
	}
	
	function loadDBProject(data){
	
		fromDB = true;
	
		dataproject = json_decode(data);
		//console.log('okhey', dataproject);

		project.name = dataproject.name;
		project.puid = dataproject.puid;
		project.core = dataproject.core;
		project.panels = makePanels(dataproject);
		project.modulelist = dataproject.modulelist;
		
		for (var i=0; i<project.panels.length; i++){
			for (var j=0; j<project.panels[i].buttons.length; j++){
				for (var k=0; k<project.panels[i].buttons[j].core.scripts.length; k++){
					if (project.panels[i].buttons[j].core.scripts[k])
						project.panels[i].buttons[j].core.scripts[k] = '<nCmd>\n' +
							project.panels[i].buttons[j].core.scripts[k] + '\n</nCmd>';
				}
			}
			for (var j=0; j<project.panels[i].widgets.length; j++){
				for (var k=0; k<project.panels[i].widgets[j].core.scripts.length; k++){
					if (project.panels[i].widgets[j].core.scripts[k])
						project.panels[i].widgets[j].core.scripts[k] = '<nCmd>\n' +
							project.panels[i].widgets[j].core.scripts[k] + '\n</nCmd>';
				}
			}
		}
		
		if (project.panels.length == 1) setPanel(0);
		else {
			if (!undef(qs.panel)) setPanel(qs.panel);
			else {
				var found = false;
				for (var i=0;i<dataproject.panels.length;i++){
					if (dataproject.panels[i].core && dataproject.panels[i].core.defaultpanel){
						setPanel(i);
						found = true;
					}
				}
				if (!found) setPanel(0);
			}
		}
		if (project.modulelist) for (var i=0; i<project.modulelist.length; i++){
			if (project.modulelist[i].required){
				//console.log('requiring ', project.modulelist[i].file);
				sandbox('require("'+project.modulelist[i].file+'");');
			}
		}
		if (project.core && project.core.scripts){ console.log('rscript');
			sandbox(project.core.scripts[0]);
		}
		updatePanel();
		mouse.inittouch();
	}
	
	function makePanels(jsonobj, panelindex){
		
		try {
		
		var results = [];
		
		var length = jsonobj.panels.length;
		
		for (var jkl=0; jkl<length; jkl++){

			var ind = jkl;
			
			if (!undef(panelindex)) ind = parseInt(panelindex);
			
			if (!jsonobj.panels[ind]) ind = 0;
			
			var loadpanel = jsonobj.panels[ind];
			
			var thispanel = new Panel({
				name: loadpanel.core.name,
				id: loadpanel.core.id,
				width: loadpanel.core.width,
				height: loadpanel.core.height,
				style: loadpanel.core.style,
				autoresize: loadpanel.core.autoresize
			});
			
			thispanel.element.style.display = 'none';
			$('#thebody').append(thispanel.element);
			thispanel.element.style.backgroundSize = "100% 100%";
			setTimeout(function(){
				thispanel.element.style.background = thispanel.element.style.background;
				thispanel.element.style.backgroundSize = "100% 100%";
			}, 200);
			thispanel.scale = 1;
			$(thispanel.element).css({
				'transform': 'scale('+thispanel.scale+','+thispanel.scale+')',
				'-webkit-transform': 'scale('+thispanel.scale+','+thispanel.scale+')',
				'-moz-transform': 'scale('+thispanel.scale+','+thispanel.scale+')',
				'-ms-transform': 'scale('+thispanel.scale+','+thispanel.scale+')'
			});
			thispanel.element.style.marginTop = '0px';
			thispanel.element.style.marginLeft = '0px';
			$(thispanel.element).center();		
			thispanel.buttons = [];
			
			for (var j=0; j<loadpanel.buttons.length; j++){
				var thisbutton = new Button({core: loadpanel.buttons[j].core, copyid: true});
				thispanel.buttons.push(thisbutton);
				
				thisbutton.panel = thispanel;
				thisbutton.element.style.backgroundSize = "100% 100%";	
				thisbutton.setState(1);
				thisbutton.element.style.cursor = "pointer";
				thisbutton.textnode.style.cursor = "pointer";
				thisbutton.textnode.style.zIndex = 10;
				$(thisbutton.element).removeClass('draggable');
				if (!wallcon) $(thisbutton.element).mousedown(function(){
					websocket.emit('message', {command: 'beep'});
					this.down = true;
					this.clickEffect.down(this);
					this.clickEvent.down(this);
					if (this.core.states[this.core.currentstate].script) 
						var thisscript = this.core.states[this.core.currentstate].script;
					else var thisscript = this.core.scripts[this.core.currentstate];
					if (!thisscript) thisscript = '';
					//else var thisscript = this.scripts[this.currentstate];
					sandbox(thisscript, this, 'script');	
				}.bind(thisbutton));
				//todo: reconcile wallcon vs 8307 here
				if (wallcon) thisbutton.click = function(){
					websocket.emit('message', {command: 'beep'});
					this.down = true;
					this.clickEffect.down(this);
					this.clickEvent.down(this);
					if (this.core.states[this.core.currentstate].script) 
						var thisscript = this.core.states[this.core.currentstate].script;
					else var thisscript = this.core.scripts[this.core.currentstate];
					if (!thisscript) thisscript = '';
					//else var thisscript = this.scripts[this.currentstate];
					sandbox(thisscript, this, 'script');	
				}.bind(thisbutton);
				if (!wallcon) $(thisbutton.element).mouseup(function(){
					this.down = false;
					this.clickEffect.up(this);
					this.clickEvent.up(this);
					if (this.clickupscript){
						sandbox(this.clickupscript, this, 'script');
					}
				}.bind(thisbutton));
				if (wallcon) thisbutton.clickup = function(){
					this.down = false;
					this.clickEffect.up(this);
					this.clickEvent.up(this);
					if (this.clickupscript){
						sandbox(this.clickupscript, this, 'script');
					}
				}.bind(thisbutton);
				thisbutton.doubleclick = noop;
				thisbutton.textdoubleclick = noop;
				$(thispanel.element).append(thisbutton.element);
				$('#'+thisbutton.id+'_text').attr('contenteditable', false);
				$('#'+thisbutton.id+'_text').addClass('unselectable');
				thisbutton.textnode.onselectstart = function(e){e.preventDefault(); return false;};
				
				$(thisbutton.textnode).css('-webkit-user-select', 'none');
				$(thisbutton.textnode).css('-moz-user-select', 'none');
				$(thisbutton.textnode).css('user-select', 'none');
				
				$(thisbutton.textnode).css('-webkit-user-select', 'none');
				$(thisbutton.textnode).css('-moz-user-select', 'none');
				$(thisbutton.textnode).css('user-select', 'none');
				
				$(thisbutton.textnode).css('pointer-events', 'none');
				//$(thisbutton.textnode).css('white-space', 'nowrap');
				
				$(thisbutton.element).css('-webkit-user-select', 'none');
				$(thisbutton.element).css('-moz-user-select', 'none');
				$(thisbutton.element).css('user-select', 'none');
				
				thisbutton.element.title = '';
				
				thisbutton.core.basewidth = parseInt(thisbutton.element.style.width);
				thisbutton.core.baseheight = parseInt(thisbutton.element.style.height);
				thisbutton.core.textwidth = parseInt(thisbutton.textnode.style.width);
				setTimeout(function(){
					thisbutton.core.textheight = $(thisbutton.textnode).height();
					//console.log('core', thisbutton.core.textheight);
				}, 250);
				
				//console.log('made it to button create', j);
			}
			thispanel.widgets = [];
			for (var j=0; j < loadpanel.widgets.length; j++){
				//console.log('makewidgets', j, loadpanel.widgets[j]);
				var newparts = [];
				for (var k=0;k<loadpanel.widgets[j].parts.length;k++){
					var twidgetpart = new WidgetPart({
						copyid: true,
						core: loadpanel.widgets[j].parts[k].core,
						init: loadpanel.widgets[j].parts[k].init || noop,
						drop: loadpanel.widgets[j].parts[k].drop || noop,
						moving: loadpanel.widgets[j].parts[k].moving || noop,
						update: loadpanel.widgets[j].parts[k].update || noop,
						click: loadpanel.widgets[j].parts[k].click || noop,
						clickup: loadpanel.widgets[j].parts[k].clickup || noop,
						hoverin: loadpanel.widgets[j].parts[k].hoverin || noop,
						hoverout: loadpanel.widgets[j].parts[k].hoverout || noop,
						resize: loadpanel.widgets[j].parts[k].resize || noop,
						ontopanel: loadpanel.widgets[j].parts[k].ontopanel || noop,
						doubleclick: loadpanel.widgets[j].parts[k].doubleclick || noop
					});
					for (var property in loadpanel.widgets[j].parts[k]){
						if (loadpanel.widgets[j].parts[k].hasOwnProperty(property) && property != 'panel' &&
							property != 'core' && property != 'element' && property != 'parts' && property != 'widget') {
							twidgetpart[property] = loadpanel.widgets[j].parts[k][property];
						}
					}
					twidgetpart.moving.bind(twidgetpart);
					twidgetpart.element.style.backgroundSize = '100% 100%';
					twidgetpart.responsive = true;
					newparts.push(twidgetpart);
					//console.log(twidgetpart.click);
				}
			
			
				thispanel.widgets.push(new Widget({
					copyid: true,
					core: loadpanel.widgets[j].core,	
					init: loadpanel.widgets[j].init || noop,
					update: loadpanel.widgets[j].update || noop,
					hoverin: loadpanel.widgets[j].hoverin || noop,
					hoverout: loadpanel.widgets[j].hoverout || noop,
					resize: loadpanel.widgets[j].resize || noop,
					ontopanel: loadpanel.widgets[j].ontopanel || noop,
					doubleclick: loadpanel.widgets[j].doubleclick || noop,
					parts: newparts
				}));
				
				
				
				var thiswidget = thispanel.widgets[thispanel.widgets.length-1];
				thiswidget.responsive = true;
			
				for (var property in loadpanel.widgets[j]) {
					if (loadpanel.widgets[j].hasOwnProperty(property) && property != 'panel' &&
						property != 'core' && property != 'element' && property != 'parts') {
						thiswidget[property] = loadpanel.widgets[j][property];
					}
				}
				
				if (thiswidget.core.set === 'hslider'||thiswidget.core.set === 'hslider2'){
					thiswidget.parts[0].set = function(nval){
						var scale = this.widget.core.maxval - this.widget.core.minval;
						nval /= scale;
						
						//nval = 1.0 - nval;
						if (undef(this.core.downoffset)) this.core.downoffset = 0;
						var newpos = (nval-0.5)*$(this.widget.element).outerWidth()*0.77;
						var distance = ($(this.widget.element).outerWidth()*0.77)/2;
						if (newpos < -distance) newpos = -distance;
						if (newpos > distance) newpos = distance;
						$(this.element).css({'margin-left': newpos + 'px'});
						
						var tw = parseFloat(this.widget.element.style.width);
						tw = (tw*0.77); 
						
						var tval = parseFloat(this.element.style.marginLeft);
						var fval = ((tval + (tw/2))/tw);
						
						var scaleval = this.widget.core.maxval - this.widget.core.minval;
						var scaledval = fval * scaleval;
						scaledval += this.widget.core.minval;
						scaledval = parseFloat(Math.round(scaledval));
						
						this.widget.value = this.widget.core.maxval - (scaledval - this.widget.core.minval);
						this.widget.hexvalue = this.widget.value.toString(16);
						
						if (this.widget.realtime){
							evalJavascript(this.widget.core.scripts[0], this.widget);
						}
						
						this.core.downoffset = parseFloat($(this.element).css('margin-left'));
						
						if (this.widget.click) this.widget.click(this.widget);
						if (this.widget.sliding) this.widget.sliding(this.widget);
						if (this.widget.clickup) this.widget.clickup(this.widget);
						
						var nscaleval = 100;
						var nscaledval = fval * nscaleval;
						nscaledval = parseFloat(Math.round(nscaledval));
						this.widget.parts[2].element.style.width = (((nscaledval) * 0.77) + 11.5) + '%';
					}.bind(thiswidget.parts[0]);
					thiswidget.parts[0].get = function(){
						if (!this.element.style.marginLeft) this.element.style.marginLeft = '0px';
						var result = 0.5 + parseFloat(this.element.style.marginLeft)/($(this.widget.element).outerWidth()*0.77);
						var scaleval = this.widget.core.maxval - this.widget.core.minval;
						result = result * scaleval;
						return result;
					}.bind(thiswidget.parts[0]);
				}
				if (thiswidget.core.set === 'vslider'||thiswidget.core.set === 'vslider2'){
					thiswidget.parts[0].set = function(nval){
						
						var scale = this.widget.core.maxval - this.widget.core.minval;
						nval /= scale;
						
						nval = 1.0 - nval;
						if (undef(this.core.downoffset)) this.core.downoffset = 0;
						var newpos = (nval-0.5)*$(this.widget.element).outerHeight()*0.77;
						var distance = ($(this.widget.element).outerHeight() * 0.77)/2;
						if (newpos < -distance) newpos = -distance;
						if (newpos > distance) newpos = distance;
						$(this.element).css({'margin-top': newpos + 'px'});

						var th = parseFloat(this.widget.element.style.height);
						th = (th*0.77); 
						
						var tval = parseFloat(this.element.style.marginTop);
						var fval = ((tval + (th/2))/th);
						
						var scaleval = this.widget.core.maxval - this.widget.core.minval;
						var scaledval = fval * scaleval;
						scaledval += this.widget.core.minval;
						scaledval = parseFloat(Math.round(scaledval));
						
						this.widget.value = this.widget.core.maxval - (scaledval - this.widget.core.minval);
						this.widget.hexvalue = this.widget.value.toString(16);
						
						if (this.widget.realtime) evalJavascript(this.widget.core.scripts[0], this.widget);
						
						this.core.downoffset = parseFloat($(this.element).css('margin-top'));
						
						if (this.widget.click) this.widget.click(this.widget);
						if (this.widget.sliding) this.widget.sliding(this.widget);
						if (this.widget.clickup) this.widget.clickup(this.widget);
						
						var nscaleval = 100;
						var nscaledval = fval * nscaleval;
						nscaledval = parseFloat(Math.round(nscaledval));
						this.widget.parts[2].element.style.height = (((100 - nscaledval) * 0.77) + 11.5) + '%';
						
					}.bind(thiswidget.parts[0]);
					thiswidget.parts[0].get = function(){
						if (!this.element.style.marginTop) this.element.style.marginTop = '0px';
						var result = 0.5 - parseFloat(this.element.style.marginTop)/($(this.widget.element).outerHeight()*0.77);
						var scaleval = this.widget.core.maxval - this.widget.core.minval;
						result = result * scaleval;
						return result;
					}.bind(thiswidget.parts[0]);
				}
				
				/*if (thiswidget.core && thiswidget.core.dvrip){
					monitorUnits('['+thiswidget.core.dvrip+']');
				}*/
				
				$(thiswidget.element).removeClass('draggable');
				$(thispanel.element).append(thiswidget.element);
				
				thiswidget.element.title = '';
				
			}
			for (var i=0;i<thispanel.widgets.length; i++){
				for (var j=0;j<thispanel.widgets[i].parts.length; j++){
					thispanel.widgets[i].parts[j].init();
				}
			}
			$('.movable').removeClass('item_child');
			thispanel.subpanels = [];
			//console.log('subs', loadpanel.subpanels);
			if (loadpanel.subpanels) for (var j=0;j<loadpanel.subpanels.length;j++){
				
				if (loadpanel.subpanels[j].core){
					var thissubpanel = new SubPanel({
						core: loadpanel.subpanels[j].core,
						children: loadpanel.subpanels[j].children,
						copyid : true
					});
				}
				else {
					var thissubpanel = new SubPanel({
						id: loadpanel.subpanels[j].id,
						name: loadpanel.subpanels[j].name,
						scale: loadpanel.subpanels[j].scale,
						style: loadpanel.subpanels[j].style,
						className: loadpanel.subpanels[j].className,
						conditional: loadpanel.subpanels[j].conditional,
						touchpanelkey: loadpanel.subpanels[j].touchpanelkey,
						children: loadpanel.subpanels[j].children
					});
				}
				//continue;
				//thissubpanel.element.className = 'draggable';
				thispanel.addChild(thissubpanel);
				console.log(thissubpanel);
				//thissubpanel.makeResizable();
				/*var _bbox = thissubpanel.element.getBoundingClientRect();
				var _pbox = thispanel.element.getBoundingClientRect();
				for (var k=0; k<thissubpanel.children.length; k++){
					var child = get(thissubpanel.children[k]);
					child.subpanel = thissubpanel.core.id;
					
					var _cbox = child.element.getBoundingClientRect();
					console.log('setting', child.core.id);
					child._x = _cbox.left - _bbox.left - _pbox.left;
					child._y = _cbox.top - _bbox.top - _pbox.top;
				}*/

				
			}

			if (thispanel.core.autoresize || qs_is_mobile){
				thispanel.resize(window.innerWidth-2, window.innerHeight-2);
				thispanel.element.style.marginTop = '0px';
				thispanel.element.style.marginLeft = '0px';
				$(thispanel.element).center();
				setTimeout(function(){
					thispanel.resize(window.innerWidth-2, window.innerHeight-2);
					thispanel.element.style.marginTop = '0px';
					thispanel.element.style.marginLeft = '0px';
					$(thispanel.element).center();
					thispanel.resize(window.innerWidth-2, window.innerHeight-2);
					thispanel.element.style.marginTop = '0px';
					thispanel.element.style.marginLeft = '0px';
					$(thispanel.element).center();
				}, 500);
			}
			
			results.push(thispanel);
			
		}
		
		}
		catch (e){
			//location.href = 'initial.php';
			console.log(e);
		}
		
		return results;
		
	}
	
	function setPanel(index){
		
		if (project.currentpanel){
			$(project.currentpanel.element).css({display: 'none'});
		}

		if (!project.panels[index]) index = 0;
		project.currentpanel = project.panels[index];
		
		if (project.currentpanel.subpanel){
			$('#thebody').append(project.currentpanel.element);
			project.currentpanel.subpanel = false;
			project.currentpanel.resize(project.currentpanel.core.basewidth, project.currentpanel.core.baseheight);
			for (var i=0; i<project.currentpanel.buttons.length; i++){
				project.currentpanel.buttons[i].textnode.style.fontSize = (parseFloat(project.currentpanel.buttons[i].element.style.height)/6)+'px';
			}
		}
		
		if (project.panels[index]){
			for (var i=0; i<project.panels[index].buttons.length; i++){
				monitorUnits(project.panels[index].buttons[i].core.conditional);
			}			
		}

		$(project.currentpanel.element).center();

		if (project.currentpanel.core.autoresize){
			project.currentpanel.resize(window.innerWidth-2, window.innerHeight-2);
			project.currentpanel.element.style.marginTop = '0px';
			project.currentpanel.element.style.marginLeft = '0px';
			$(project.currentpanel.element).center();
		}

		$(project.currentpanel.element).css('display', 'block');
		
		for (var i=0; i<project.currentpanel.buttons.length; i++){	
			var thisbutton = project.currentpanel.buttons[i];
			var theight = (($(thisbutton.element).height()/2) -
				($(thisbutton.textnode).height()/2));
			$(thisbutton.textnode).css('top', theight + 'px');
			project.currentpanel.buttons[i].panel = project.currentpanel;
		}
		
		project.currentpanel.clickup = function(){
			for (var i=0; i<project.currentpanel.buttons.length; i++){
				if (project.currentpanel.buttons[i].down)
					project.currentpanel.buttons[i].clickup();
			}
		};
		
		windowResize();
		
	}
	
	function handleDeviceUpdate(msg){
		console.log('deviceUpdate', msg);
		if (parseInt(msg.msgid) === -1){
			console.log('Socket Error', msg);
			if (msg.msg == "already_open"){
				for (var i=0; i<tcpsockets.length; i++){
					if (msg.ip == tcpsockets[i].ip && msg.port == tcpsockets[i].port){
						tcpsockets[i].open = true;
					}
				}
			}
		}
		if (parseInt(msg.msgid) === -2){
			console.log('Socket Message', msg);
			if (msg.msg == "socket_open"){
				for (var i=0; i<tcpsockets.length; i++){
					if (msg.ip == tcpsockets[i].ip && msg.port == tcpsockets[i].port){
						tcpsockets[i].open = true;
					}
				}
			}
			if (msg.msg == "socket_closed"){
				for (var i=0; i<tcpsockets.length; i++){
					if (msg.ip == tcpsockets[i].ip && msg.port == tcpsockets[i].port){
						tcpsockets[i].open = false;
					}
				}
			}
		}		
		for (var i=0; i<websocketmsgs.length; i++){
			if (websocketmsgs[i].msgid == msg.msgid){
				if (websocketmsgs[i].onMessage) websocketmsgs[i].onMessage(msg.msg);
				//websocketmsgs[i].waiting = false;
			}
		}
	}
	
	function monitorUnits(str){ //deprecated
		if (1 || undef(str) || str.length <= 0) return;
		
		var tstr = str;
		//tstr = removeJavascript(tstr);
		while (tstr.indexOf("]") != -1 && tstr.length > 0){
			var tstrb = tstr.substring(tstr.indexOf("[")+1, tstr.indexOf("]"));
			if (tstrb != '127.0.0.1'){
				ws.send("monitornotify "+tstrb);
			}
			tstr = tstr.substring(tstr.indexOf("]")+1, tstr.length);
		}
	}
	
	function updatePanel(status){
		//return; console.log('up-pan?', status);
		if (!project || !project.currentpanel) return;
		
		//return;
	
		/*if (undef(status)){
			for (var i=0; i<project.currentpanel.buttons.length; i++){
				if (project.currentpanel.buttons[i].core.conditional && project.currentpanel.buttons[i].core.conditional !== '')
					sandbox('console.log("gotit");', project.currentpanel.buttons[i], 'conditional');
			}
			for (var i=0; i<project.currentpanel.widgets.length; i++){
				if (project.currentpanel.widgets[i].core.conditional && project.currentpanel.widgets[i].core.conditional !== '')
					sandbox('', project.currentpanel.widgets[i], 'conditional');
			}
			return;
		}
		if (undef(status)){
			for (var i=0; i<project.currentpanel.buttons.length; i++){
				if (project.currentpanel.buttons[i].core.conditional && project.currentpanel.buttons[i].core.conditional !== '')
					sandbox(project.currentpanel.buttons[i].core.conditional, project.currentpanel.buttons[i], 'conditional');
			}
			for (var i=0; i<project.currentpanel.widgets.length; i++){
				if (project.currentpanel.widgets[i].core.conditional && project.currentpanel.widgets[i].core.conditional !== '')
					sandbox(project.currentpanel.widgets[i].core.conditional, project.currentpanel.widgets[i], 'conditional');
			}
			return;
		}*/
		
		//return;
		
		
		if (undef(status)){
			for (var i=0; i<project.currentpanel.buttons.length; i++){
				var self = project.currentpanel.buttons[i];
				if (project.currentpanel.buttons[i].core.conditional && project.currentpanel.buttons[i].core.conditional !== '')
					sandbox(project.currentpanel.buttons[i].core.conditional, self);
			}
			for (var i=0; i<project.currentpanel.widgets.length; i++){
				var self = project.currentpanel.widgets[i];
				if (project.currentpanel.widgets[i].core.conditional && project.currentpanel.widgets[i].core.conditional !== '')
					sandbox(project.currentpanel.widgets[i].core.conditional, self);
			}
			for (var i=0; i<project.currentpanel.subpanels.length; i++){
				var self = project.currentpanel.subpanels[i];
				if (project.currentpanel.subpanels[i].core.conditional && project.currentpanel.subpanels[i].core.conditional !== '')
					sandbox(project.currentpanel.subpanels[i].core.conditional, self);
			}
			return;
		}
		
		if (status.indexOf("<device>") != -1 && status.indexOf("</device>") != -1){
		
			var tstatus = status;
			tstatus = tstatus.replace("<device>","");
			tstatus = tstatus.replace("</device>","");
			
			statusobj = {};
			
			var tint = tstatus.indexOf(' ');
			var ip = tstatus.substring(0, tint);
			tstatus = tstatus.substring(tint+1);
			tint = tstatus.indexOf(' ');
			var port = tstatus.substring(0, tint);
			tstatus = tstatus.substring(tint+1);
			tint = tstatus.indexOf(' ');
			var msgid = tstatus.substring(0, tint);
			tstatus = tstatus.substring(tint+1);
			
			statusobj.ip = ip;
			statusobj.port = port;
			statusobj.msgid = msgid;
			statusobj.msg = tstatus;
			
			handleDeviceUpdate(statusobj);
			return;
			
		}
		
		if (status.indexOf("<status>") == -1 || status.indexOf("</status>") == -1) return;
		
		var tstatus = status;
		tstatus = tstatus.replace("<status>","");
		tstatus = tstatus.replace("</status>","");
		statusobj = json_decode(tstatus);
		//console.log('decoded new status: ', statusobj);
		
		/*var isinlist = false;
		for (var lind=0; lind<monitorlist.length; lind++){
			if (statusobj.ip == monitorlist[lind].ip){
				monitorlist[lind] = statusobj;
				isinlist = true;
			}
		}
		if (!isinlist) monitorlist.push(statusobj);*/
		
		/*for (var i=0; i<project.currentpanel.buttons.length; i++){
			if (project.currentpanel.buttons[i].core.conditional && project.currentpanel.buttons[i].core.conditional !== ''){
				sandbox(project.currentpanel.buttons[i].core.conditional, project.currentpanel.buttons[i], 'conditional');
			}
		}
		for (var i=0; i<project.currentpanel.widgets.length; i++){
			if (project.currentpanel.widgets[i].core.conditional && project.currentpanel.widgets[i].core.conditional !== '')
				sandbox(project.currentpanel.widgets[i].core.conditional, project.currentpanel.widgets[i], 'conditional');
			if (statusobj.isdvr && project.currentpanel.widgets[i].type == 'dvr' && statusobj.ip == project.currentpanel.widgets[i].core.dvrip)
				project.currentpanel.widgets[i].core.statusUpdate.call(project.currentpanel.widgets[i], statusobj);
		}*/
		for (var i=0; i<project.currentpanel.buttons.length; i++){
			var self = project.currentpanel.buttons[i];
			if (project.currentpanel.buttons[i].core.conditional && project.currentpanel.buttons[i].core.conditional !== ''){
				sandbox(project.currentpanel.buttons[i].core.conditional, self);
			}
		}
		for (var i=0; i<project.currentpanel.widgets.length; i++){
			var self = project.currentpanel.widgets[i];
			if (project.currentpanel.widgets[i].core.conditional && project.currentpanel.widgets[i].core.conditional !== '')
				sandbox(project.currentpanel.widgets[i].core.conditional, self);
			if (statusobj.isdvr && project.currentpanel.widgets[i].type == 'dvr' && statusobj.ip == project.currentpanel.widgets[i].core.dvrip)
				project.currentpanel.widgets[i].core.statusUpdate.call(project.currentpanel.widgets[i], statusobj);
		}
	}
	
	function sendScript(script, self){
	
		var scriptfile = "../runscript.php";
	
		if (script.trim() == '' || script.trim() == '//') return;
		
		var modifiedscript = script;
		
		for (var t=0; t<project.currentpanel.widgets.length; t++){
			modifiedscript = modifiedscript.replace(project.currentpanel.widgets[t].id+'.value',
													project.currentpanel.widgets[t].value);
		}
		
		modifiedscript = removeComments(modifiedscript);
		
		//console.log('send script: ', modifiedscript);
		
		if (!undef(modifiedscript)){ 
		
			if (modifiedscript.indexOf('goto ') != -1){	
			
				var trimmedscripta = modifiedscript.substring(0, modifiedscript.indexOf('goto '));
				
				//TODO: THIS NEEDS TO ACCOUNT FOR ANY SPACES IN THE GOTO STATEMENT
				//BY GETTING THE NEXT /N CHARACTER AND REMOVING THE WHOLE LINE
				var gotoscripta = modifiedscript.substr(modifiedscript.indexOf('goto ')+5, 100);
				var gotoscriptb = parseInt(gotoscripta) - 1;
				
				var trimmedscriptb = modifiedscript.replace('goto '+gotoscriptb, '');
				
				for (var property in clientvars){
					if (clientvars.hasOwnProperty(property)){
						trimmedscripta = trimmedscripta.replaceAll('$'+property, clientvars[property]);
					}
				}
				for (var property in servervars){
					if (servervars.hasOwnProperty(property)){
						trimmedscripta = trimmedscripta.replaceAll('$$'+property, servervars[property]);
					}
				}
				
				$.post(scriptfile, {executescript: "yes", script: trimmedscripta}, noop);
				
				setPanel(gotoscriptb);
				
				for (var property in clientvars){
					if (clientvars.hasOwnProperty(property)){
						
						trimmedscriptb = trimmedscriptb.replaceAll('$'+property, clientvars[property]);
					}
				}
				for (var property in servervars){
					if (servervars.hasOwnProperty(property)){
						trimmedscriptb = trimmedscriptb.replaceAll('$$'+property, servervars[property]);
					}
				}
				
				$.post(scriptfile, {executescript: "yes", script: trimmedscriptb}, noop);
				
			}
			else {

				var finallines = getLines(modifiedscript);
				
				var finalscript = '';
				for (var i=0; i<finallines.length; i++){
					if (finallines[i].indexOf('this') != -1 ||
						finallines[i].indexOf('$') != -1 ||
						finallines[i].indexOf('Button-') != -1 ||
						finallines[i].indexOf('Widget-') != -1){
							evalSetStatement(finallines[i], self);
					}
					finalscript += finallines[i];
				}
				
				for (var property in clientvars){
					if (clientvars.hasOwnProperty(property)){
						
						finalscript = finalscript.replaceAll('$'+property, clientvars[property]);
					}
				}
				for (var property in servervars){
					if (servervars.hasOwnProperty(property)){
						finalscript = finalscript.replaceAll('$$'+property, servervars[property]);
					}
				}
				
				//console.log('finally sending: ', finalscript);
				
				$.post(scriptfile, { executescript: "yes", script: finalscript}, noop);
			}
		
		}
	}
	
	if (touchpanel){
	
		$('head').append('<style>* {cursor: none !important;}\
			body {overflow: hidden}\
		</style>');
		$(document).keydown(function(event){
		
			if (keydown) return;
			keydown = true;
			
			var keycode = (event.keyCode ? event.keyCode : event.which);
			var key = String.fromCharCode(keycode);
			
			if (key == '0' || key == '9'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-text').val($('#security-text').val().substring(0, $('#security-text').val().length - 1));
					$('#security-text').change();
				}
				homebuttondown = true;
				homebuttontimer = setTimeout(function(){
					if (homebuttondown){
						//todo: fix for wallcon and 8307
						//$('#infopage').load("../tmp/ipSettings.html", function(){$('#infopage').find('pre').css({fontSize: '14px'}).prepend('<img src="/panels/images/amx/amx_by_harman.png" style="width: 160px;"></img><br>'); $('#infopage').show();});
						$('#infopage').load("../tmp/ipSettings.html", function(){$('#infopage').find('pre').css({fontSize: '40px'}).prepend('<img src="/panels/images/amx/amx_by_harman.png" style="width: 600px;"></img><br>'); $('#infopage').show();});
						homebuttondown = false;
					}
					homebuttontimer = false;
				}, 4000);
			}
			
			var index = project.panels.indexOf(project.currentpanel);
		
			var keycode = (event.keyCode ? event.keyCode : event.which);
			var key = String.fromCharCode(keycode);
		
			if (key == '1'){
				
				if ($('#security')[0].style.display == 'block'){
					$('#security-1').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey === 1 ||
						project.panels[index].buttons[i].core.touchpanelkey === '1'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '2'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-2').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 2 ||
						project.panels[index].buttons[i].core.touchpanelkey == '2'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '3'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-3').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 3 ||
						project.panels[index].buttons[i].core.touchpanelkey == '3'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '4'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-4').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 4 ||
						project.panels[index].buttons[i].core.touchpanelkey == '4'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '5'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-5').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 5 ||
						project.panels[index].buttons[i].core.touchpanelkey == '5'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '6'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-6').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 6 ||
						project.panels[index].buttons[i].core.touchpanelkey == '6'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '7'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-7').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 7 ||
						project.panels[index].buttons[i].core.touchpanelkey == '7'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			if (key == '8'){
				if ($('#security')[0].style.display == 'block'){
					$('#security-8').click();
					return;
				}
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 8 ||
						project.panels[index].buttons[i].core.touchpanelkey == '8'){
						project.panels[index].buttons[i].click();
						return;
					}
				}
			}
			
		});
		
		$(document).keyup(function(event){
		
			keydown = false;
			
			var keycode = (event.keyCode ? event.keyCode : event.which);
			var key = String.fromCharCode(keycode);
			
			var index = project.panels.indexOf(project.currentpanel);
		
			if (key == '0' || key == '9'){
				
				if (homebuttontimer !== false){
					if ($('#infopage')[0].style.display == 'none') setPanel(0);
					else $('#infopage').hide();
					clearTimeout(homebuttontimer);
					homebuttontimer = false;
				}
			}
			if (key == '1'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey === 1 ||
						project.panels[index].buttons[i].core.touchpanelkey === '1'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '2'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 2 ||
						project.panels[index].buttons[i].core.touchpanelkey == '2'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '3'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 3 ||
						project.panels[index].buttons[i].core.touchpanelkey == '3'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '4'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 4 ||
						project.panels[index].buttons[i].core.touchpanelkey == '4'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '5'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 5 ||
						project.panels[index].buttons[i].core.touchpanelkey == '5'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '6'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 6 ||
						project.panels[index].buttons[i].core.touchpanelkey == '6'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '7'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 7 ||
						project.panels[index].buttons[i].core.touchpanelkey == '7'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
			if (key == '8'){
				for (var i=0; i<project.panels[index].buttons.length; i++){
					if (project.panels[index].buttons[i].core.touchpanelkey == 8 ||
						project.panels[index].buttons[i].core.touchpanelkey == '8'){
						if (panelswitched){
							panelswitched = false;
						}
						if (project.panels[index].buttons[i]) project.panels[index].buttons[i].clickup();
						return;
					}
				}
			}
		});
		
	}
	
	window.addEventListener("orientationchange", function(){
		for (var i=0; i<project.currentpanel.buttons.length; i++){
		
			var thisbutton = project.currentpanel.buttons[i];
			var theight = ($(thisbutton.element).outerHeight()/2) - ($(thisbutton.textnode).outerHeight()/2);
			
			$(thisbutton.textnode).css('top', theight + 'px');
		}
	}, false);
	
	var windowResize = resizeWindow = function(){
		for (var i=0; i<project.currentpanel.buttons.length; i++){
		
			var thisbutton = project.currentpanel.buttons[i];
			var theight = ($(thisbutton.element).outerHeight()/2) - ($(thisbutton.textnode).outerHeight()/2);
			
			$(thisbutton.textnode).css('top', theight + 'px');
		}
		for (var i=0; i<project.currentpanel.widgets.length; i++){
			var thiswidget = project.currentpanel.widgets[i];
			thiswidget.resize();
			for (var k=0;k<thiswidget.parts.length;k++){
				if (thiswidget.parts[k].resize) thiswidget.parts[k].resize();
			}
		}
	}
	
	window.addEventListener("resize", function(){
		resizeWindow();
	}, false);
	