changeset 7:0330b2138c87

add collecting post data from LGDataverse
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Fri, 04 Sep 2015 16:16:10 +0200
parents 30b59e7b88c0
children 8f05c2a84bba
files config/config.php coordinates/map.js geotemco/platin.js map.js map.php
diffstat 5 files changed, 4888 insertions(+), 4785 deletions(-) [+]
line wrap: on
line diff
--- a/config/config.php	Thu Jun 25 17:47:11 2015 +0200
+++ b/config/config.php	Fri Sep 04 16:16:10 2015 +0200
@@ -10,7 +10,7 @@
 	$mysql_password = "admin";
 	$server_host = "http://localgazetteers.mpiwg-berlin.mpg.de/";
 	$lgserver_url = $server_host."LGServices/";
-
+	$lgdataverse_url = $server_host."dvn/";	// TODO
 
 } else {
 	// localhost
@@ -19,8 +19,8 @@
 	$mysql_user = "root";
 	$mysql_password = "root";
 	$server_host = "http://localhost:1080/localgazetteers-dev/";
-	//$lgserver_url = "http://localgazetteers-dev/LGServices/";
 	$lgserver_url = "http://localhost:8080/LGServices/";
+	$lgdataverse_url = "http://localhost:8082/";
 }
 
 $systemNAME = "interface";
--- a/coordinates/map.js	Thu Jun 25 17:47:11 2015 +0200
+++ b/coordinates/map.js	Fri Sep 04 16:16:10 2015 +0200
@@ -43,7 +43,7 @@
 	var overlayLoaderWidget=new OverlayloaderWidget(overlayLoader,overlayLoaderElem);
 	overlayLoaderWidget.attachMapWidget(mapWidget);
 	overlayLoaderWidget.overlayLoader.distributeArcGISWMS("http://geoserver.mpiwg-berlin.mpg.de/geoserver/China_Monograph_Project/ows",
-	"China_Monograph_Project:monograph_distribution_prov");	
+	"China_Monograph_Project:monograph_distribution_prov_x");	
 	//overlayLoaderWidget.overlayLoader.distributeArcGISWMS("http://geoserver.mpiwg-berlin.mpg.de/geoserver/China_Monograph_Project/ows",
 	//"China_Monograph_Project:all_monographs_capital_points");	
 	//"mpiwg:chgis_v4_time_prov_pgn_utf_188");
@@ -60,7 +60,7 @@
 	$("#mapContainer .overlayVisibility").click(function(){
 		if($(this).is(":checked")){//selected
 			overlayLoaderWidget.overlayLoader.distributeArcGISWMS("http://geoserver.mpiwg-berlin.mpg.de/geoserver/China_Monograph_Project/ows",
-        		"China_Monograph_Project:monograph_distribution_prov");
+        		"China_Monograph_Project:monograph_distribution_prov_x");
 		}else{
 			while($("#overlayLoaderContainer div:last-child a").length!=0){
                         	$("#overlayLoaderContainer div a:nth-child(1)").click();
--- a/geotemco/platin.js	Thu Jun 25 17:47:11 2015 +0200
+++ b/geotemco/platin.js	Fri Sep 04 16:16:10 2015 +0200
@@ -1,58 +1,58 @@
 (function($){
 
 var jQuery = $;
-/*
-* basic.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * basic code which is included first for the minified version
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-
-var arrayIndex = function(array, obj) {
-	if (Array.indexOf) {
-		return array.indexOf(obj);
-	}
-	for (var i = 0; i < array.length; i++) {
-		if (array[i] == obj) {
-			return i;
-		}
-	}
-	return -1;
-}
-var GeoTemCoMinifier_urlPrefix;
-for (var i = 0; i < document.getElementsByTagName("script").length; i++) {
-	var script = document.getElementsByTagName("script")[i];
-	var index = script.src.indexOf("platin.js");
-	if (index == -1) {
-		index = script.src.indexOf("platin-min.js");
-	}
-	if (index != -1) {
-		GeoTemCoMinifier_urlPrefix = script.src.substring(0, index);
-		break;
-	}
-}
+/*
+* basic.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * basic code which is included first for the minified version
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+
+var arrayIndex = function(array, obj) {
+	if (Array.indexOf) {
+		return array.indexOf(obj);
+	}
+	for (var i = 0; i < array.length; i++) {
+		if (array[i] == obj) {
+			return i;
+		}
+	}
+	return -1;
+}
+var GeoTemCoMinifier_urlPrefix;
+for (var i = 0; i < document.getElementsByTagName("script").length; i++) {
+	var script = document.getElementsByTagName("script")[i];
+	var index = script.src.indexOf("platin.js");
+	if (index == -1) {
+		index = script.src.indexOf("platin-min.js");
+	}
+	if (index != -1) {
+		GeoTemCoMinifier_urlPrefix = script.src.substring(0, index);
+		break;
+	}
+}
 // Copyright 2006 Google Inc.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -977,694 +977,694 @@
 })();
 
 } // if
-/*----------------------------------------------------------------------------\
-|                                Range Class                                  |
-|-----------------------------------------------------------------------------|
-|                         Created by Erik Arvidsson                           |
-|                  (http://webfx.eae.net/contact.html#erik)                   |
-|                      For WebFX (http://webfx.eae.net/)                      |
-|-----------------------------------------------------------------------------|
-| Used to  model the data  used  when working  with  sliders,  scrollbars and |
-| progress bars.  Based  on  the  ideas of  the javax.swing.BoundedRangeModel |
-| interface  defined  by  Sun  for  Java;   http://java.sun.com/products/jfc/ |
-| swingdoc-api-1.0.3/com/sun/java/swing/BoundedRangeModel.html                |
-|-----------------------------------------------------------------------------|
-|                Copyright (c) 2002, 2005, 2006 Erik Arvidsson                |
-|-----------------------------------------------------------------------------|
-| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
-| use this file except in compliance with the License.  You may obtain a copy |
-| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
-| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
-| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
-| License  for the  specific language  governing permissions  and limitations |
-| under the License.                                                          |
-|-----------------------------------------------------------------------------|
-| 2002-10-14 | Original version released                                      |
-| 2005-10-27 | Use Math.round instead of Math.floor                           |
-| 2006-05-28 | Changed license to Apache Software License 2.0.                |
-|-----------------------------------------------------------------------------|
-| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |
-\----------------------------------------------------------------------------*/
-
-
-function Range() {
-	this._value = 0;
-	this._minimum = 0;
-	this._maximum = 100;
-	this._extent = 0;
-
-	this._isChanging = false;
-}
-
-Range.prototype.setValue = function (value) {
-	value = Math.round(parseFloat(value));
-	if (isNaN(value)) return;
-	if (this._value != value) {
-		if (value + this._extent > this._maximum)
-			this._value = this._maximum - this._extent;
-		else if (value < this._minimum)
-			this._value = this._minimum;
-		else
-			this._value = value;
-		if (!this._isChanging && typeof this.onchange == "function")
-			 this.onchange();
-	}
-};
-
-Range.prototype.getValue = function () {
-	return this._value;
-};
-
-Range.prototype.setExtent = function (extent) {
-	if (this._extent != extent) {
-		if (extent < 0)
-			this._extent = 0;
-		else if (this._value + extent > this._maximum)
-			this._extent = this._maximum - this._value;
-		else
-			this._extent = extent;
-		if (!this._isChanging && typeof this.onchange == "function")
-			this.onchange();
-	}
-};
-
-Range.prototype.getExtent = function () {
-	return this._extent;
-};
-
-Range.prototype.setMinimum = function (minimum) {
-	if (this._minimum != minimum) {
-		var oldIsChanging = this._isChanging;
-		this._isChanging = true;
-
-		this._minimum = minimum;
-
-		if (minimum > this._value)
-			this.setValue(minimum);
-		if (minimum > this._maximum) {
-			this._extent = 0;
-			this.setMaximum(minimum);
-			this.setValue(minimum)
-		}
-		if (minimum + this._extent > this._maximum)
-			this._extent = this._maximum - this._minimum;
-
-		this._isChanging = oldIsChanging;
-		if (!this._isChanging && typeof this.onchange == "function")
-			this.onchange();
-	}
-};
-
-Range.prototype.getMinimum = function () {
-	return this._minimum;
-};
-
-Range.prototype.setMaximum = function (maximum) {
-	if (this._maximum != maximum) {
-		var oldIsChanging = this._isChanging;
-		this._isChanging = true;
-
-		this._maximum = maximum;
-
-		if (maximum < this._value)
-			this.setValue(maximum - this._extent);
-		if (maximum < this._minimum) {
-			this._extent = 0;
-			this.setMinimum(maximum);
-			this.setValue(this._maximum);
-		}
-		if (maximum < this._minimum + this._extent)
-			this._extent = this._maximum - this._minimum;
-		if (maximum < this._value + this._extent)
-			this._extent = this._maximum - this._value;
-
-		this._isChanging = oldIsChanging;
-		if (!this._isChanging && typeof this.onchange == "function")
-			this.onchange();
-	}
-};
-
-Range.prototype.getMaximum = function () {
-	return this._maximum;
-};
-/*----------------------------------------------------------------------------\
-|                                Slider 1.02                                  |
-|-----------------------------------------------------------------------------|
-|                         Created by Erik Arvidsson                           |
-|                  (http://webfx.eae.net/contact.html#erik)                   |
-|                      For WebFX (http://webfx.eae.net/)                      |
-|-----------------------------------------------------------------------------|
-| A  slider  control that  degrades  to an  input control  for non  supported |
-| browsers.                                                                   |
-|-----------------------------------------------------------------------------|
-|                Copyright (c) 2002, 2003, 2006 Erik Arvidsson                |
-|-----------------------------------------------------------------------------|
-| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
-| use this file except in compliance with the License.  You may obtain a copy |
-| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
-| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
-| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
-| License  for the  specific language  governing permissions  and limitations |
-| under the License.                                                          |
-|-----------------------------------------------------------------------------|
-| Dependencies: timer.js - an OO abstraction of timers                        |
-|               range.js - provides the data model for the slider             |
-|               winclassic.css or any other css file describing the look      |
-|-----------------------------------------------------------------------------|
-| 2002-10-14 | Original version released                                      |
-| 2003-03-27 | Added a test in the constructor for missing oElement arg       |
-| 2003-11-27 | Only use mousewheel when focused                               |
-| 2006-05-28 | Changed license to Apache Software License 2.0.                |
-|-----------------------------------------------------------------------------|
-| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |
-\----------------------------------------------------------------------------*/
-
-Slider.isSupported = typeof document.createElement != "undefined" &&
-	typeof document.documentElement != "undefined" &&
-	typeof document.documentElement.offsetWidth == "number";
-
-
-function Slider(oElement, oInput, sOrientation) {
-	if (!oElement) return;
-	this._orientation = sOrientation || "horizontal";
-	this._range = new Range();
-	this._range.setExtent(0);
-	this._blockIncrement = 10;
-	this._unitIncrement = 1;
-	this._timer = new Timer(100);
-
-
-	if (Slider.isSupported && oElement) {
-
-		this.document = oElement.ownerDocument || oElement.document;
-
-		this.element = oElement;
-		this.element.slider = this;
-		this.element.unselectable = "on";
-
-		// add class name tag to class name
-		this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className;
-
-		// create line
-		this.line = this.document.createElement("DIV");
-		this.line.className = "line";
-		this.line.unselectable = "on";
-		this.line.appendChild(this.document.createElement("DIV"));
-		this.element.appendChild(this.line);
-
-		// create handle
-		this.handle = this.document.createElement("DIV");
-		this.handle.className = "handle";
-		this.handle.unselectable = "on";
-		this.handle.appendChild(this.document.createElement("DIV"));
-		this.handle.firstChild.appendChild(
-			this.document.createTextNode(String.fromCharCode(160)));
-		this.element.appendChild(this.handle);
-	}
-
-	this.input = oInput;
-
-	// events
-	var oThis = this;
-	this._range.onchange = function () {
-		oThis.recalculate();
-		if (typeof oThis.onchange == "function")
-			oThis.onchange();
-	};
-
-	if (Slider.isSupported && oElement) {
-		this.element.onfocus		= Slider.eventHandlers.onfocus;
-		this.element.onblur			= Slider.eventHandlers.onblur;
-		this.element.onmousedown	= Slider.eventHandlers.onmousedown;
-		this.element.onmouseover	= Slider.eventHandlers.onmouseover;
-		this.element.onmouseout		= Slider.eventHandlers.onmouseout;
-		this.element.onkeydown		= Slider.eventHandlers.onkeydown;
-		this.element.onkeypress		= Slider.eventHandlers.onkeypress;
-		this.element.onmousewheel	= Slider.eventHandlers.onmousewheel;
-		this.handle.onselectstart	=
-		this.element.onselectstart	= function () { return false; };
-
-		this._timer.ontimer = function () {
-			oThis.ontimer();
-		};
-
-		// extra recalculate for ie
-		window.setTimeout(function() {
-			oThis.recalculate();
-		}, 1);
-	}
-	else {
-		this.input.onchange = function (e) {
-			oThis.setValue(oThis.input.value);
-		};
-	}
-}
-
-Slider.eventHandlers = {
-
-	// helpers to make events a bit easier
-	getEvent:	function (e, el) {
-		if (!e) {
-			if (el)
-				e = el.document.parentWindow.event;
-			else
-				e = window.event;
-		}
-		if (!e.srcElement) {
-			var el = e.target;
-			while (el != null && el.nodeType != 1)
-				el = el.parentNode;
-			e.srcElement = el;
-		}
-		if (typeof e.offsetX == "undefined") {
-			e.offsetX = e.layerX;
-			e.offsetY = e.layerY;
-		}
-
-		return e;
-	},
-
-	getDocument:	function (e) {
-		if (e.target)
-			return e.target.ownerDocument;
-		return e.srcElement.document;
-	},
-
-	getSlider:	function (e) {
-		var el = e.target || e.srcElement;
-		while (el != null && el.slider == null)	{
-			el = el.parentNode;
-		}
-		if (el)
-			return el.slider;
-		return null;
-	},
-
-	getLine:	function (e) {
-		var el = e.target || e.srcElement;
-		while (el != null && el.className != "line")	{
-			el = el.parentNode;
-		}
-		return el;
-	},
-
-	getHandle:	function (e) {
-		var el = e.target || e.srcElement;
-		var re = /handle/;
-		while (el != null && !re.test(el.className))	{
-			el = el.parentNode;
-		}
-		return el;
-	},
-	// end helpers
-
-	onfocus:	function (e) {
-		var s = this.slider;
-		s._focused = true;
-		s.handle.className = "handle hover";
-	},
-
-	onblur:	function (e) {
-		var s = this.slider
-		s._focused = false;
-		s.handle.className = "handle";
-	},
-
-	onmouseover:	function (e) {
-		e = Slider.eventHandlers.getEvent(e, this);
-		var s = this.slider;
-		if (e.srcElement == s.handle)
-			s.handle.className = "handle hover";
-	},
-
-	onmouseout:	function (e) {
-		e = Slider.eventHandlers.getEvent(e, this);
-		var s = this.slider;
-		if (e.srcElement == s.handle && !s._focused)
-			s.handle.className = "handle";
-	},
-
-	onmousedown:	function (e) {
-		e = Slider.eventHandlers.getEvent(e, this);
-		var s = this.slider;
-		if (s.element.focus)
-			s.element.focus();
-
-		Slider._currentInstance = s;
-		var doc = s.document;
-
-		if (doc.addEventListener) {
-			doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true);
-			doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true);
-		}
-		else if (doc.attachEvent) {
-			doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove);
-			doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup);
-			doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup);
-			s.element.setCapture();
-		}
-
-		if (Slider.eventHandlers.getHandle(e)) {	// start drag
-			Slider._sliderDragData = {
-				screenX:	e.screenX,
-				screenY:	e.screenY,
-				dx:			e.screenX - s.handle.offsetLeft,
-				dy:			e.screenY - s.handle.offsetTop,
-				startValue:	s.getValue(),
-				slider:		s
-			};
-		}
-		else {
-			return;
-			var lineEl = Slider.eventHandlers.getLine(e);
-			s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);
-			s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);
-			s._increasing = null;
-			s.ontimer();
-		}
-	},
-
-	onmousemove:	function (e) {
-		e = Slider.eventHandlers.getEvent(e, this);
-
-		if (Slider._sliderDragData) {	// drag
-			var s = Slider._sliderDragData.slider;
-
-			var boundSize = s.getMaximum() - s.getMinimum();
-			var size, pos, reset;
-
-			if (s._orientation == "horizontal") {
-				size = s.element.offsetWidth - s.handle.offsetWidth;
-				pos = e.screenX - Slider._sliderDragData.dx;
-				reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100;
-			}
-			else {
-				size = s.element.offsetHeight - s.handle.offsetHeight;
-				pos = s.element.offsetHeight - s.handle.offsetHeight -
-					(e.screenY - Slider._sliderDragData.dy);
-				reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100;
-			}
-			s.setValue(reset ? Slider._sliderDragData.startValue :
-						s.getMinimum() + boundSize * pos / size);
-			return false;
-		}
-		else {
-			return;
-			var s = Slider._currentInstance;
-			if (s != null) {
-				var lineEl = Slider.eventHandlers.getLine(e);
-				s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);
-				s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);
-			}
-		}
-
-	},
-
-	onmouseup:	function (e) {
-		e = Slider.eventHandlers.getEvent(e, this);
-		var s = Slider._currentInstance;
-		var doc = s.document;
-		if (doc.removeEventListener) {
-			doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true);
-			doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true);
-		}
-		else if (doc.detachEvent) {
-			doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove);
-			doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup);
-			doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup);
-			s.element.releaseCapture();
-		}
-
-		if (Slider._sliderDragData) {	// end drag
-			Slider._sliderDragData = null;
-		}
-		else {
-			return;
-			s._timer.stop();
-			s._increasing = null;
-		}
-		Slider._currentInstance = null;
-	},
-
-	onkeydown:	function (e) {
-		return;
-		e = Slider.eventHandlers.getEvent(e, this);
-		//var s = Slider.eventHandlers.getSlider(e);
-		var s = this.slider;
-		var kc = e.keyCode;
-		switch (kc) {
-			case 33:	// page up
-				s.setValue(s.getValue() + s.getBlockIncrement());
-				break;
-			case 34:	// page down
-				s.setValue(s.getValue() - s.getBlockIncrement());
-				break;
-			case 35:	// end
-				s.setValue(s.getOrientation() == "horizontal" ?
-					s.getMaximum() :
-					s.getMinimum());
-				break;
-			case 36:	// home
-				s.setValue(s.getOrientation() == "horizontal" ?
-					s.getMinimum() :
-					s.getMaximum());
-				break;
-			case 38:	// up
-			case 39:	// right
-				s.setValue(s.getValue() + s.getUnitIncrement());
-				break;
-
-			case 37:	// left
-			case 40:	// down
-				s.setValue(s.getValue() - s.getUnitIncrement());
-				break;
-		}
-
-		if (kc >= 33 && kc <= 40) {
-			return false;
-		}
-	},
-
-	onkeypress:	function (e) {
-		return;
-		e = Slider.eventHandlers.getEvent(e, this);
-		var kc = e.keyCode;
-		if (kc >= 33 && kc <= 40) {
-			return false;
-		}
-	},
-
-	onmousewheel:	function (e) {
-		return;
-		e = Slider.eventHandlers.getEvent(e, this);
-		var s = this.slider;
-		if (s._focused) {
-			s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement());
-			// windows inverts this on horizontal sliders. That does not
-			// make sense to me
-			return false;
-		}
-	}
-};
-
-
-
-Slider.prototype.classNameTag = "dynamic-slider-control",
-
-Slider.prototype.setValue = function (v) {
-	this._range.setValue(v);
-	this.input.value = this.getValue();
-};
-
-Slider.prototype.getValue = function () {
-	return this._range.getValue();
-};
-
-Slider.prototype.setMinimum = function (v) {
-	this._range.setMinimum(v);
-	this.input.value = this.getValue();
-};
-
-Slider.prototype.getMinimum = function () {
-	return this._range.getMinimum();
-};
-
-Slider.prototype.setMaximum = function (v) {
-	this._range.setMaximum(v);
-	this.input.value = this.getValue();
-};
-
-Slider.prototype.getMaximum = function () {
-	return this._range.getMaximum();
-};
-
-Slider.prototype.setUnitIncrement = function (v) {
-	this._unitIncrement = v;
-};
-
-Slider.prototype.getUnitIncrement = function () {
-	return this._unitIncrement;
-};
-
-Slider.prototype.setBlockIncrement = function (v) {
-	this._blockIncrement = v;
-};
-
-Slider.prototype.getBlockIncrement = function () {
-	return this._blockIncrement;
-};
-
-Slider.prototype.getOrientation = function () {
-	return this._orientation;
-};
-
-Slider.prototype.setOrientation = function (sOrientation) {
-	if (sOrientation != this._orientation) {
-		if (Slider.isSupported && this.element) {
-			// add class name tag to class name
-			this.element.className = this.element.className.replace(this._orientation,
-									sOrientation);
-		}
-		this._orientation = sOrientation;
-		this.recalculate();
-
-	}
-};
-
-Slider.prototype.recalculate = function() {
-	if (!Slider.isSupported || !this.element) return;
-
-	var w = this.element.offsetWidth;
-	var h = this.element.offsetHeight;
-	var hw = this.handle.offsetWidth;
-	var hh = this.handle.offsetHeight;
-	var lw = this.line.offsetWidth;
-	var lh = this.line.offsetHeight;
-
-	// this assumes a border-box layout
-
-	if (this._orientation == "horizontal") {
-		this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) /
-			(this.getMaximum() - this.getMinimum()) + "px";
-		this.handle.style.top = (h - hh) / 2 + "px";
-
-		this.line.style.top = (h - lh) / 2 + "px";
-		this.line.style.left = hw / 2 + "px";
-		//this.line.style.right = hw / 2 + "px";
-		this.line.style.width = Math.max(0, w - hw - 2)+ "px";
-		this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px";
-	}
-	else {
-		this.handle.style.left = (w - hw) / 2 + "px";
-		this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) /
-			(this.getMaximum() - this.getMinimum()) + "px";
-
-		this.line.style.left = (w - lw) / 2 + "px";
-		this.line.style.top = hh / 2 + "px";
-		this.line.style.height = Math.max(0, h - hh - 2) + "px";	//hard coded border width
-		//this.line.style.bottom = hh / 2 + "px";
-		this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px";	//hard coded border width
-	}
-};
-
-Slider.prototype.ontimer = function () {
-	var hw = this.handle.offsetWidth;
-	var hh = this.handle.offsetHeight;
-	var hl = this.handle.offsetLeft;
-	var ht = this.handle.offsetTop;
-
-	if (this._orientation == "horizontal") {
-		if (this._mouseX > hl + hw &&
-			(this._increasing == null || this._increasing)) {
-			this.setValue(this.getValue() + this.getBlockIncrement());
-			this._increasing = true;
-		}
-		else if (this._mouseX < hl &&
-			(this._increasing == null || !this._increasing)) {
-			this.setValue(this.getValue() - this.getBlockIncrement());
-			this._increasing = false;
-		}
-	}
-	else {
-		if (this._mouseY > ht + hh &&
-			(this._increasing == null || !this._increasing)) {
-			this.setValue(this.getValue() - this.getBlockIncrement());
-			this._increasing = false;
-		}
-		else if (this._mouseY < ht &&
-			(this._increasing == null || this._increasing)) {
-			this.setValue(this.getValue() + this.getBlockIncrement());
-			this._increasing = true;
-		}
-	}
-
-	this._timer.start();
-};
-/*----------------------------------------------------------------------------\
-|                                 Timer Class                                 |
-|-----------------------------------------------------------------------------|
-|                         Created by Erik Arvidsson                           |
-|                  (http://webfx.eae.net/contact.html#erik)                   |
-|                      For WebFX (http://webfx.eae.net/)                      |
-|-----------------------------------------------------------------------------|
-| Object Oriented Encapsulation  of setTimeout  fires ontimer when the  timer |
-| is triggered. Does not work in IE 5.00                                      |
-|-----------------------------------------------------------------------------|
-|                   Copyright (c) 2002, 2006 Erik Arvidsson                   |
-|-----------------------------------------------------------------------------|
-| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
-| use this file except in compliance with the License.  You may obtain a copy |
-| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
-| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
-| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
-| License  for the  specific language  governing permissions  and limitations |
-| under the License.                                                          |
-|-----------------------------------------------------------------------------|
-| 2002-10-14 | Original version released                                      |
-| 2006-05-28 | Changed license to Apache Software License 2.0.                |
-|-----------------------------------------------------------------------------|
-| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |
-\----------------------------------------------------------------------------*/
-
-function Timer(nPauseTime) {
-	this._pauseTime = typeof nPauseTime == "undefined" ? 1000 : nPauseTime;
-	this._timer = null;
-	this._isStarted = false;
-}
-
-Timer.prototype.start = function () {
-	if (this.isStarted())
-		this.stop();
-	var oThis = this;
-	this._timer = window.setTimeout(function () {
-		if (typeof oThis.ontimer == "function")
-			oThis.ontimer();
-	}, this._pauseTime);
-	this._isStarted = false;
-};
-
-Timer.prototype.stop = function () {
-	if (this._timer != null)
-		window.clearTimeout(this._timer);
-	this._isStarted = false;
-};
-
-Timer.prototype.isStarted = function () {
-	return this._isStarted;
-};
-
-Timer.prototype.getPauseTime = function () {
-	return this._pauseTime;
-};
-
-Timer.prototype.setPauseTime = function (nPauseTime) {
-	this._pauseTime = nPauseTime;
+/*----------------------------------------------------------------------------\
+|                                Range Class                                  |
+|-----------------------------------------------------------------------------|
+|                         Created by Erik Arvidsson                           |
+|                  (http://webfx.eae.net/contact.html#erik)                   |
+|                      For WebFX (http://webfx.eae.net/)                      |
+|-----------------------------------------------------------------------------|
+| Used to  model the data  used  when working  with  sliders,  scrollbars and |
+| progress bars.  Based  on  the  ideas of  the javax.swing.BoundedRangeModel |
+| interface  defined  by  Sun  for  Java;   http://java.sun.com/products/jfc/ |
+| swingdoc-api-1.0.3/com/sun/java/swing/BoundedRangeModel.html                |
+|-----------------------------------------------------------------------------|
+|                Copyright (c) 2002, 2005, 2006 Erik Arvidsson                |
+|-----------------------------------------------------------------------------|
+| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
+| use this file except in compliance with the License.  You may obtain a copy |
+| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
+| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
+| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
+| License  for the  specific language  governing permissions  and limitations |
+| under the License.                                                          |
+|-----------------------------------------------------------------------------|
+| 2002-10-14 | Original version released                                      |
+| 2005-10-27 | Use Math.round instead of Math.floor                           |
+| 2006-05-28 | Changed license to Apache Software License 2.0.                |
+|-----------------------------------------------------------------------------|
+| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |
+\----------------------------------------------------------------------------*/
+
+
+function Range() {
+	this._value = 0;
+	this._minimum = 0;
+	this._maximum = 100;
+	this._extent = 0;
+
+	this._isChanging = false;
+}
+
+Range.prototype.setValue = function (value) {
+	value = Math.round(parseFloat(value));
+	if (isNaN(value)) return;
+	if (this._value != value) {
+		if (value + this._extent > this._maximum)
+			this._value = this._maximum - this._extent;
+		else if (value < this._minimum)
+			this._value = this._minimum;
+		else
+			this._value = value;
+		if (!this._isChanging && typeof this.onchange == "function")
+			 this.onchange();
+	}
+};
+
+Range.prototype.getValue = function () {
+	return this._value;
+};
+
+Range.prototype.setExtent = function (extent) {
+	if (this._extent != extent) {
+		if (extent < 0)
+			this._extent = 0;
+		else if (this._value + extent > this._maximum)
+			this._extent = this._maximum - this._value;
+		else
+			this._extent = extent;
+		if (!this._isChanging && typeof this.onchange == "function")
+			this.onchange();
+	}
+};
+
+Range.prototype.getExtent = function () {
+	return this._extent;
+};
+
+Range.prototype.setMinimum = function (minimum) {
+	if (this._minimum != minimum) {
+		var oldIsChanging = this._isChanging;
+		this._isChanging = true;
+
+		this._minimum = minimum;
+
+		if (minimum > this._value)
+			this.setValue(minimum);
+		if (minimum > this._maximum) {
+			this._extent = 0;
+			this.setMaximum(minimum);
+			this.setValue(minimum)
+		}
+		if (minimum + this._extent > this._maximum)
+			this._extent = this._maximum - this._minimum;
+
+		this._isChanging = oldIsChanging;
+		if (!this._isChanging && typeof this.onchange == "function")
+			this.onchange();
+	}
+};
+
+Range.prototype.getMinimum = function () {
+	return this._minimum;
+};
+
+Range.prototype.setMaximum = function (maximum) {
+	if (this._maximum != maximum) {
+		var oldIsChanging = this._isChanging;
+		this._isChanging = true;
+
+		this._maximum = maximum;
+
+		if (maximum < this._value)
+			this.setValue(maximum - this._extent);
+		if (maximum < this._minimum) {
+			this._extent = 0;
+			this.setMinimum(maximum);
+			this.setValue(this._maximum);
+		}
+		if (maximum < this._minimum + this._extent)
+			this._extent = this._maximum - this._minimum;
+		if (maximum < this._value + this._extent)
+			this._extent = this._maximum - this._value;
+
+		this._isChanging = oldIsChanging;
+		if (!this._isChanging && typeof this.onchange == "function")
+			this.onchange();
+	}
+};
+
+Range.prototype.getMaximum = function () {
+	return this._maximum;
+};
+/*----------------------------------------------------------------------------\
+|                                Slider 1.02                                  |
+|-----------------------------------------------------------------------------|
+|                         Created by Erik Arvidsson                           |
+|                  (http://webfx.eae.net/contact.html#erik)                   |
+|                      For WebFX (http://webfx.eae.net/)                      |
+|-----------------------------------------------------------------------------|
+| A  slider  control that  degrades  to an  input control  for non  supported |
+| browsers.                                                                   |
+|-----------------------------------------------------------------------------|
+|                Copyright (c) 2002, 2003, 2006 Erik Arvidsson                |
+|-----------------------------------------------------------------------------|
+| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
+| use this file except in compliance with the License.  You may obtain a copy |
+| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
+| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
+| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
+| License  for the  specific language  governing permissions  and limitations |
+| under the License.                                                          |
+|-----------------------------------------------------------------------------|
+| Dependencies: timer.js - an OO abstraction of timers                        |
+|               range.js - provides the data model for the slider             |
+|               winclassic.css or any other css file describing the look      |
+|-----------------------------------------------------------------------------|
+| 2002-10-14 | Original version released                                      |
+| 2003-03-27 | Added a test in the constructor for missing oElement arg       |
+| 2003-11-27 | Only use mousewheel when focused                               |
+| 2006-05-28 | Changed license to Apache Software License 2.0.                |
+|-----------------------------------------------------------------------------|
+| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |
+\----------------------------------------------------------------------------*/
+
+Slider.isSupported = typeof document.createElement != "undefined" &&
+	typeof document.documentElement != "undefined" &&
+	typeof document.documentElement.offsetWidth == "number";
+
+
+function Slider(oElement, oInput, sOrientation) {
+	if (!oElement) return;
+	this._orientation = sOrientation || "horizontal";
+	this._range = new Range();
+	this._range.setExtent(0);
+	this._blockIncrement = 10;
+	this._unitIncrement = 1;
+	this._timer = new Timer(100);
+
+
+	if (Slider.isSupported && oElement) {
+
+		this.document = oElement.ownerDocument || oElement.document;
+
+		this.element = oElement;
+		this.element.slider = this;
+		this.element.unselectable = "on";
+
+		// add class name tag to class name
+		this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className;
+
+		// create line
+		this.line = this.document.createElement("DIV");
+		this.line.className = "line";
+		this.line.unselectable = "on";
+		this.line.appendChild(this.document.createElement("DIV"));
+		this.element.appendChild(this.line);
+
+		// create handle
+		this.handle = this.document.createElement("DIV");
+		this.handle.className = "handle";
+		this.handle.unselectable = "on";
+		this.handle.appendChild(this.document.createElement("DIV"));
+		this.handle.firstChild.appendChild(
+			this.document.createTextNode(String.fromCharCode(160)));
+		this.element.appendChild(this.handle);
+	}
+
+	this.input = oInput;
+
+	// events
+	var oThis = this;
+	this._range.onchange = function () {
+		oThis.recalculate();
+		if (typeof oThis.onchange == "function")
+			oThis.onchange();
+	};
+
+	if (Slider.isSupported && oElement) {
+		this.element.onfocus		= Slider.eventHandlers.onfocus;
+		this.element.onblur			= Slider.eventHandlers.onblur;
+		this.element.onmousedown	= Slider.eventHandlers.onmousedown;
+		this.element.onmouseover	= Slider.eventHandlers.onmouseover;
+		this.element.onmouseout		= Slider.eventHandlers.onmouseout;
+		this.element.onkeydown		= Slider.eventHandlers.onkeydown;
+		this.element.onkeypress		= Slider.eventHandlers.onkeypress;
+		this.element.onmousewheel	= Slider.eventHandlers.onmousewheel;
+		this.handle.onselectstart	=
+		this.element.onselectstart	= function () { return false; };
+
+		this._timer.ontimer = function () {
+			oThis.ontimer();
+		};
+
+		// extra recalculate for ie
+		window.setTimeout(function() {
+			oThis.recalculate();
+		}, 1);
+	}
+	else {
+		this.input.onchange = function (e) {
+			oThis.setValue(oThis.input.value);
+		};
+	}
+}
+
+Slider.eventHandlers = {
+
+	// helpers to make events a bit easier
+	getEvent:	function (e, el) {
+		if (!e) {
+			if (el)
+				e = el.document.parentWindow.event;
+			else
+				e = window.event;
+		}
+		if (!e.srcElement) {
+			var el = e.target;
+			while (el != null && el.nodeType != 1)
+				el = el.parentNode;
+			e.srcElement = el;
+		}
+		if (typeof e.offsetX == "undefined") {
+			e.offsetX = e.layerX;
+			e.offsetY = e.layerY;
+		}
+
+		return e;
+	},
+
+	getDocument:	function (e) {
+		if (e.target)
+			return e.target.ownerDocument;
+		return e.srcElement.document;
+	},
+
+	getSlider:	function (e) {
+		var el = e.target || e.srcElement;
+		while (el != null && el.slider == null)	{
+			el = el.parentNode;
+		}
+		if (el)
+			return el.slider;
+		return null;
+	},
+
+	getLine:	function (e) {
+		var el = e.target || e.srcElement;
+		while (el != null && el.className != "line")	{
+			el = el.parentNode;
+		}
+		return el;
+	},
+
+	getHandle:	function (e) {
+		var el = e.target || e.srcElement;
+		var re = /handle/;
+		while (el != null && !re.test(el.className))	{
+			el = el.parentNode;
+		}
+		return el;
+	},
+	// end helpers
+
+	onfocus:	function (e) {
+		var s = this.slider;
+		s._focused = true;
+		s.handle.className = "handle hover";
+	},
+
+	onblur:	function (e) {
+		var s = this.slider
+		s._focused = false;
+		s.handle.className = "handle";
+	},
+
+	onmouseover:	function (e) {
+		e = Slider.eventHandlers.getEvent(e, this);
+		var s = this.slider;
+		if (e.srcElement == s.handle)
+			s.handle.className = "handle hover";
+	},
+
+	onmouseout:	function (e) {
+		e = Slider.eventHandlers.getEvent(e, this);
+		var s = this.slider;
+		if (e.srcElement == s.handle && !s._focused)
+			s.handle.className = "handle";
+	},
+
+	onmousedown:	function (e) {
+		e = Slider.eventHandlers.getEvent(e, this);
+		var s = this.slider;
+		if (s.element.focus)
+			s.element.focus();
+
+		Slider._currentInstance = s;
+		var doc = s.document;
+
+		if (doc.addEventListener) {
+			doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true);
+			doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true);
+		}
+		else if (doc.attachEvent) {
+			doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove);
+			doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup);
+			doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup);
+			s.element.setCapture();
+		}
+
+		if (Slider.eventHandlers.getHandle(e)) {	// start drag
+			Slider._sliderDragData = {
+				screenX:	e.screenX,
+				screenY:	e.screenY,
+				dx:			e.screenX - s.handle.offsetLeft,
+				dy:			e.screenY - s.handle.offsetTop,
+				startValue:	s.getValue(),
+				slider:		s
+			};
+		}
+		else {
+			return;
+			var lineEl = Slider.eventHandlers.getLine(e);
+			s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);
+			s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);
+			s._increasing = null;
+			s.ontimer();
+		}
+	},
+
+	onmousemove:	function (e) {
+		e = Slider.eventHandlers.getEvent(e, this);
+
+		if (Slider._sliderDragData) {	// drag
+			var s = Slider._sliderDragData.slider;
+
+			var boundSize = s.getMaximum() - s.getMinimum();
+			var size, pos, reset;
+
+			if (s._orientation == "horizontal") {
+				size = s.element.offsetWidth - s.handle.offsetWidth;
+				pos = e.screenX - Slider._sliderDragData.dx;
+				reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100;
+			}
+			else {
+				size = s.element.offsetHeight - s.handle.offsetHeight;
+				pos = s.element.offsetHeight - s.handle.offsetHeight -
+					(e.screenY - Slider._sliderDragData.dy);
+				reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100;
+			}
+			s.setValue(reset ? Slider._sliderDragData.startValue :
+						s.getMinimum() + boundSize * pos / size);
+			return false;
+		}
+		else {
+			return;
+			var s = Slider._currentInstance;
+			if (s != null) {
+				var lineEl = Slider.eventHandlers.getLine(e);
+				s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);
+				s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);
+			}
+		}
+
+	},
+
+	onmouseup:	function (e) {
+		e = Slider.eventHandlers.getEvent(e, this);
+		var s = Slider._currentInstance;
+		var doc = s.document;
+		if (doc.removeEventListener) {
+			doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true);
+			doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true);
+		}
+		else if (doc.detachEvent) {
+			doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove);
+			doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup);
+			doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup);
+			s.element.releaseCapture();
+		}
+
+		if (Slider._sliderDragData) {	// end drag
+			Slider._sliderDragData = null;
+		}
+		else {
+			return;
+			s._timer.stop();
+			s._increasing = null;
+		}
+		Slider._currentInstance = null;
+	},
+
+	onkeydown:	function (e) {
+		return;
+		e = Slider.eventHandlers.getEvent(e, this);
+		//var s = Slider.eventHandlers.getSlider(e);
+		var s = this.slider;
+		var kc = e.keyCode;
+		switch (kc) {
+			case 33:	// page up
+				s.setValue(s.getValue() + s.getBlockIncrement());
+				break;
+			case 34:	// page down
+				s.setValue(s.getValue() - s.getBlockIncrement());
+				break;
+			case 35:	// end
+				s.setValue(s.getOrientation() == "horizontal" ?
+					s.getMaximum() :
+					s.getMinimum());
+				break;
+			case 36:	// home
+				s.setValue(s.getOrientation() == "horizontal" ?
+					s.getMinimum() :
+					s.getMaximum());
+				break;
+			case 38:	// up
+			case 39:	// right
+				s.setValue(s.getValue() + s.getUnitIncrement());
+				break;
+
+			case 37:	// left
+			case 40:	// down
+				s.setValue(s.getValue() - s.getUnitIncrement());
+				break;
+		}
+
+		if (kc >= 33 && kc <= 40) {
+			return false;
+		}
+	},
+
+	onkeypress:	function (e) {
+		return;
+		e = Slider.eventHandlers.getEvent(e, this);
+		var kc = e.keyCode;
+		if (kc >= 33 && kc <= 40) {
+			return false;
+		}
+	},
+
+	onmousewheel:	function (e) {
+		return;
+		e = Slider.eventHandlers.getEvent(e, this);
+		var s = this.slider;
+		if (s._focused) {
+			s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement());
+			// windows inverts this on horizontal sliders. That does not
+			// make sense to me
+			return false;
+		}
+	}
+};
+
+
+
+Slider.prototype.classNameTag = "dynamic-slider-control",
+
+Slider.prototype.setValue = function (v) {
+	this._range.setValue(v);
+	this.input.value = this.getValue();
+};
+
+Slider.prototype.getValue = function () {
+	return this._range.getValue();
+};
+
+Slider.prototype.setMinimum = function (v) {
+	this._range.setMinimum(v);
+	this.input.value = this.getValue();
+};
+
+Slider.prototype.getMinimum = function () {
+	return this._range.getMinimum();
+};
+
+Slider.prototype.setMaximum = function (v) {
+	this._range.setMaximum(v);
+	this.input.value = this.getValue();
+};
+
+Slider.prototype.getMaximum = function () {
+	return this._range.getMaximum();
+};
+
+Slider.prototype.setUnitIncrement = function (v) {
+	this._unitIncrement = v;
+};
+
+Slider.prototype.getUnitIncrement = function () {
+	return this._unitIncrement;
+};
+
+Slider.prototype.setBlockIncrement = function (v) {
+	this._blockIncrement = v;
+};
+
+Slider.prototype.getBlockIncrement = function () {
+	return this._blockIncrement;
+};
+
+Slider.prototype.getOrientation = function () {
+	return this._orientation;
+};
+
+Slider.prototype.setOrientation = function (sOrientation) {
+	if (sOrientation != this._orientation) {
+		if (Slider.isSupported && this.element) {
+			// add class name tag to class name
+			this.element.className = this.element.className.replace(this._orientation,
+									sOrientation);
+		}
+		this._orientation = sOrientation;
+		this.recalculate();
+
+	}
+};
+
+Slider.prototype.recalculate = function() {
+	if (!Slider.isSupported || !this.element) return;
+
+	var w = this.element.offsetWidth;
+	var h = this.element.offsetHeight;
+	var hw = this.handle.offsetWidth;
+	var hh = this.handle.offsetHeight;
+	var lw = this.line.offsetWidth;
+	var lh = this.line.offsetHeight;
+
+	// this assumes a border-box layout
+
+	if (this._orientation == "horizontal") {
+		this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) /
+			(this.getMaximum() - this.getMinimum()) + "px";
+		this.handle.style.top = (h - hh) / 2 + "px";
+
+		this.line.style.top = (h - lh) / 2 + "px";
+		this.line.style.left = hw / 2 + "px";
+		//this.line.style.right = hw / 2 + "px";
+		this.line.style.width = Math.max(0, w - hw - 2)+ "px";
+		this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px";
+	}
+	else {
+		this.handle.style.left = (w - hw) / 2 + "px";
+		this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) /
+			(this.getMaximum() - this.getMinimum()) + "px";
+
+		this.line.style.left = (w - lw) / 2 + "px";
+		this.line.style.top = hh / 2 + "px";
+		this.line.style.height = Math.max(0, h - hh - 2) + "px";	//hard coded border width
+		//this.line.style.bottom = hh / 2 + "px";
+		this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px";	//hard coded border width
+	}
+};
+
+Slider.prototype.ontimer = function () {
+	var hw = this.handle.offsetWidth;
+	var hh = this.handle.offsetHeight;
+	var hl = this.handle.offsetLeft;
+	var ht = this.handle.offsetTop;
+
+	if (this._orientation == "horizontal") {
+		if (this._mouseX > hl + hw &&
+			(this._increasing == null || this._increasing)) {
+			this.setValue(this.getValue() + this.getBlockIncrement());
+			this._increasing = true;
+		}
+		else if (this._mouseX < hl &&
+			(this._increasing == null || !this._increasing)) {
+			this.setValue(this.getValue() - this.getBlockIncrement());
+			this._increasing = false;
+		}
+	}
+	else {
+		if (this._mouseY > ht + hh &&
+			(this._increasing == null || !this._increasing)) {
+			this.setValue(this.getValue() - this.getBlockIncrement());
+			this._increasing = false;
+		}
+		else if (this._mouseY < ht &&
+			(this._increasing == null || this._increasing)) {
+			this.setValue(this.getValue() + this.getBlockIncrement());
+			this._increasing = true;
+		}
+	}
+
+	this._timer.start();
+};
+/*----------------------------------------------------------------------------\
+|                                 Timer Class                                 |
+|-----------------------------------------------------------------------------|
+|                         Created by Erik Arvidsson                           |
+|                  (http://webfx.eae.net/contact.html#erik)                   |
+|                      For WebFX (http://webfx.eae.net/)                      |
+|-----------------------------------------------------------------------------|
+| Object Oriented Encapsulation  of setTimeout  fires ontimer when the  timer |
+| is triggered. Does not work in IE 5.00                                      |
+|-----------------------------------------------------------------------------|
+|                   Copyright (c) 2002, 2006 Erik Arvidsson                   |
+|-----------------------------------------------------------------------------|
+| Licensed under the Apache License, Version 2.0 (the "License"); you may not |
+| use this file except in compliance with the License.  You may obtain a copy |
+| of the License at http://www.apache.org/licenses/LICENSE-2.0                |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| Unless  required  by  applicable law or  agreed  to  in  writing,  software |
+| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
+| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
+| License  for the  specific language  governing permissions  and limitations |
+| under the License.                                                          |
+|-----------------------------------------------------------------------------|
+| 2002-10-14 | Original version released                                      |
+| 2006-05-28 | Changed license to Apache Software License 2.0.                |
+|-----------------------------------------------------------------------------|
+| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |
+\----------------------------------------------------------------------------*/
+
+function Timer(nPauseTime) {
+	this._pauseTime = typeof nPauseTime == "undefined" ? 1000 : nPauseTime;
+	this._timer = null;
+	this._isStarted = false;
+}
+
+Timer.prototype.start = function () {
+	if (this.isStarted())
+		this.stop();
+	var oThis = this;
+	this._timer = window.setTimeout(function () {
+		if (typeof oThis.ontimer == "function")
+			oThis.ontimer();
+	}, this._pauseTime);
+	this._isStarted = false;
+};
+
+Timer.prototype.stop = function () {
+	if (this._timer != null)
+		window.clearTimeout(this._timer);
+	this._isStarted = false;
+};
+
+Timer.prototype.isStarted = function () {
+	return this._isStarted;
+};
+
+Timer.prototype.getPauseTime = function () {
+	return this._pauseTime;
+};
+
+Timer.prototype.setPauseTime = function (nPauseTime) {
+	this._pauseTime = nPauseTime;
 };
 /*
 
@@ -30622,10 +30622,11 @@
 		}
 		
 		dataObject["tableContent"] = tableContent;
-		
+
 		json.push(dataObject);
 	}
-	
+
+
 	return json;
 };
 
@@ -30720,14 +30721,17 @@
     var json;
     req.onload = function() {
     	json = GeoTemConfig.convertCsv(req.response);
+    	
     	if( asyncFunc )
     		asyncFunc(json);
     };
+
 	req.send();
 	
-	if( !async ){
+	if( !async ){ 
 		return json;
 	}
+
 };
 
 /**
@@ -32430,723 +32434,724 @@
 	};
 
 };
-/*
-* MapConfig.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class MapConfig
- * Map Configuration File
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-function MapConfig(options) {
-
-	this.options = {
-		mapWidth : false, // false or desired width css definition for the map
-		mapHeight : false, // false or desired height css definition for the map
-		mapTitle : 'GeoTemCo Map View', // title will be shown in map header
-		mapIndex : 0, // index = position in location array; for multiple locations the 2nd map refers to index 1
-		alternativeMap :  [
-		/*		{
-					name: 'Barrington Roman Empire',
-					url: 'http://pelagios.dme.ait.ac.at/tilesets/imperium/${z}/${x}/${y}.png',
-					type:'XYZ',
-					attribution: "(c) Barrington Roman Empiry, <a href='http://pelagios.dme.ait.ac.at/maps/greco-roman/'>Pelagios</a>"
-				},
-				{
-					name: 'Maps-for-Free Relief Map',
-					url: 'http://maps-for-free.com/layer/relief/z${z}/row${y}/${z}_${x}-${y}.jpg',
-					type:'XYZ',
-					attribution: "(c) <a href='http://www.maps-for-free.com/html/about.html'>Maps for Free</a>"
-				},
-				{
-					name: 'Contemporary Map (2010)',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry2010',
-					attribution: "(c) <a href='http://epp.eurostat.ec.europa.eu/portal/page/portal/gisco_Geographical_information_maps/popups/references/administrative_units_statistical_units_1'>EuroStat</a>"
-				},
-				{
-					name: 'Historical Map of 2006',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry2006',
-					attribution: "(c) <a href='http://epp.eurostat.ec.europa.eu/portal/page/portal/gisco_Geographical_information_maps/popups/references/administrative_units_statistical_units_1'>EuroStat</a>"
-				},
-				{
-					name: 'Historical Map of 1994',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1994',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1945',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1945',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1938',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1938',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1920',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1920',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1914',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1914',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1880',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1880',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1815',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1815',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1783',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1783',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1715',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1715',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1650',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1650',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1530',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1530',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1492',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1492',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1279',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1279',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1000',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1000',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 800',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry800',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 600',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry600',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 400',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry400',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 1 BC',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1bc',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 200 BC',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry200bc',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 323 BC',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry323bc',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 500 BC',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry500bc',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
*/
-				{
-					name: 'Historical Map of 1000 BC',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry1000bc',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-				{
-					name: 'Historical Map of 2000 BC',
-					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
-					layer: 'historic:cntry2000bc',
-					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
-				},
-		],
-		legend : true, // if a legend at the bottom of the map should be shown or not
-		mapMerge : false, // if the elements of distinct datasets should be merged into one set or not
-		useGraphics : false,  // if different graphics should represent different datasets or not
-		graphics : [
-			{
-				shape: "circle",
-				rotation: 0
-			},
-			{
-				shape: "square",
-				rotation: 0
-			},
-			{
-				shape: "triangle",
-				rotation: 0
-			},
-			{
-				shape: "square",
-				rotation: 45
-			}
-		],
-		googleMaps : false, // enable/disable Google maps (actually, no Google Maps API key is required)
-		bingMaps : false, // enable/disable Bing maps (you need to set the Bing Maps API key below)
-		bingApiKey : 'none', // bing maps api key, see informations at http://bingmapsportal.com/
-		osmMaps : true, // enable/disable OSM maps
-		osmMapsMapQuest : true, // enable/disable OSM maps with MapQuest tiles
-		baseLayer : 'Open Street Map', // initial layer to show (e.g. 'Google Streets')
-		resetMap : true, // show/hide map reset button
-		countrySelect : true, // show/hide map country selection control button
-		polygonSelect : true, // show/hide map polygon selection control button
-		circleSelect : true, // show/hide map circle selection control button
-		squareSelect : true, // show/hide map square selection control button
-		multiSelection : true, // true, if multiple polygons or multiple circles should be selectable
-		popups : true, // enabled popups will show popup windows for circles on the map
-		olNavigation : false, // show/hide OpenLayers navigation panel
-		olLayerSwitcher : false, // show/hide OpenLayers layer switcher
-		olMapOverview : false, // show/hide OpenLayers map overview
-		olKeyboardDefaults : true, // (de)activate Openlayers keyboard defaults
-		olScaleLine : false, // (de)activate Openlayers keyboard defaults
-		geoLocation : true, // show/hide GeoLocation feature
-		boundaries : {
-			minLon : -29,
-			minLat : 35,
-			maxLon : 44,
-			maxLat : 67
-		}, // initial map boundaries or 'false' for no boundaries
-		mapBackground : '#bbd0ed',
-		labelGrid : true, // show label grid on hover
-		maxPlaceLabels : 6, // Integer value for fixed number of place labels: 0 --> unlimited, 1 --> 1 label (won't be shown in popup, 2 --> is not possible because of others & all labels --> 3 labels, [3,...,N] --> [3,...,N] place labels)
-		selectDefault : true, // true, if strongest label should be selected as default
-		maxLabelIncrease : 2, // maximum increase (in em) for the font size of a label
-		labelHover : false, // true, to update on label hover
-		ieHighlightLabel : "color: COLOR1; background-color: COLOR0; filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';", // css code for a highlighted place label in IE
-		highlightLabel : "color: COLOR0; text-shadow: 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em COLOR0;", // css code for a highlighted place label
-		ieSelectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label in IE
-		selectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label
-		ieUnselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label in IE
-		unselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label
-		ieHoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label in IE
-		hoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label
-		circleGap : 0, // gap between the circles on the map (>=0)
-		circleOverlap : {
-			type: 'area', // 'area' or 'diameter' is possible
-			overlap: 1 // the percentage of allowed overlap (0<=overlap<=1)
-		}, // maximum allowed overlap in percent (if circleGap = 0, circleOverlap will be used)
-		minimumRadius : 1, // minimum radius of a circle with mimimal weight (>0)
-		circleOutline : 2, // false for no outline or a pixel value v with 0 < v
-		circleOpacity : 'balloon', // 'balloon' for dynamic opacity of the circles or a value t with 0 <= t <= 1
-		minTransparency : 0.55, // maximum transparency of a circle
-		maxTransparency : 0.8, // minimum transparency of a circle
-		binning : 'generic', // binning algorithm for the map, possible values are: 'generic', 'square', 'hexagonal', 'triangular' or false for 'no binning'
-		noBinningRadii : 'dynamic', // for 'no binning': 'static' for only minimum radii, 'dynamic' for increasing radii for increasing weights
-		circlePackings : true, // if circles of multiple result sets should be displayed in circle packs, if a binning is performed
-		binCount : 10, // number of bins for x and y dimension for lowest zoom level
-		showDescriptions : true, // true to show descriptions of data items (must be provided by kml/json), false if not
-		mapSelection : true, // show/hide select map dropdown
-		binningSelection : false, // show/hide binning algorithms dropdown
-		mapSelectionTools : true, // show/hide map selector tools
-		dataInformation : true, // show/hide data information
-		overlayVisibility : false, // initial visibility of additional overlays
-		//proxyHost : 'php/proxy.php?address=',	//required for selectCountry feature, if the requested GeoServer and GeoTemCo are NOT on the same server
-		placenameTagsStyle : 'value' // the style of the placenames "surrounding" a circle on hover. 'zoom' for tags based on zoom level (old behaviour), 'value' for new value-based
-
-	};
-	if ( typeof options != 'undefined') {
-		$.extend(this.options, options);
-	}
-	
-	//if the user can change shape/color graphics have to be used
-	//but this will use circles as default shape
-	if (GeoTemConfig.allowUserShapeAndColorChange){
-		this.options.useGraphics = true;
-	}
-
-};
-
-MapConfig.prototype.getGraphic = function(id){
-	var dataset = GeoTemConfig.datasets[id];
-
-	var graphic;
-	if (typeof dataset.graphic !== "undefined"){
-		graphic = dataset.graphic;
-	} else{
-		graphic = this.options.graphics[id % this.options.graphics.length];
-	}
-	
-	var color;
-	if (typeof dataset.color !== "undefined"){
-		color = dataset.color;
-	} else{
-		color = GeoTemConfig.getColor(id);
-	}
-	return {
-		shape: graphic.shape,
-		rotation: graphic.rotation,
-		color: color
-	};
-};
-/*
-* MapGui.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class MapGui
- * Map GUI Implementation
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- *
- * @param {MapWidget} parent map widget object
- * @param {HTML object} div parent div to append the map gui
- * @param {JSON} options map configuration
- */
-function MapGui(map, div, options, iid) {
-
-	this.map = map;
-
-	this.container = div;
-	if (options.mapWidth) {
-		this.container.style.width = options.mapWidth;
-	}
-	if (options.mapHeight) {
-		this.container.style.height = options.mapHeight;
-	}
-	this.container.style.position = 'relative';
-
-	this.mapWindow = document.createElement("div");
-	this.mapWindow.setAttribute('class', 'mapWindow');
-	this.mapWindow.id = "mapWindow"+iid;
-	this.mapWindow.style.background = options.mapBackground;
-	this.container.appendChild(this.mapWindow);
-
-	this.mapContainer = document.createElement("div");
-	this.mapContainer.setAttribute('class', 'mapContainer');
-	this.mapContainer.id = "mapContainer"+iid;
-	this.mapContainer.style.position = "absolute";
-	this.mapContainer.style.zIndex = 0;
-	this.mapWindow.appendChild(this.mapContainer);
-
-	var toolbarTable = document.createElement("table");
-	toolbarTable.setAttribute('class', 'absoluteToolbar ddbToolbar');
-	this.container.appendChild(toolbarTable);
-	this.mapToolbar = toolbarTable;
-
-	var titles = document.createElement("tr");
-	toolbarTable.appendChild(titles);
-	var tools = document.createElement("tr");
-	toolbarTable.appendChild(tools);
-
-	if (options.mapSelection) {
-		this.mapTypeTitle = document.createElement("td");
-		titles.appendChild(this.mapTypeTitle);
-		this.mapTypeTitle.innerHTML = GeoTemConfig.getString('mapType');
-		this.mapTypeSelector = document.createElement("td");
-		tools.appendChild(this.mapTypeSelector);
-	}
-
-	if (options.mapSelectionTools) {
-		this.mapSelectorTitle = document.createElement("td");
-		titles.appendChild(this.mapSelectorTitle);
-		this.mapSelectorTitle.innerHTML = GeoTemConfig.getString('mapSelectorTools');
-		var mapSelectorTools = document.createElement("td");
-		var selectorTools = this.map.initSelectorTools();
-		for (var i in selectorTools ) {
-			mapSelectorTools.appendChild(selectorTools[i].button);
-		}
-		tools.appendChild(mapSelectorTools);
-	}
-
-	if (options.binningSelection) {
-		this.binningTitle = document.createElement("td");
-		titles.appendChild(this.binningTitle);
-		this.binningTitle.innerHTML = GeoTemConfig.getString('binningType');
-		this.binningSelector = document.createElement("td");
-		tools.appendChild(this.binningSelector);
-	}
-
-	if (GeoTemConfig.allowFilter) {
-		this.filterTitle = document.createElement("td");
-		titles.appendChild(this.filterTitle);
-		this.filterTitle.innerHTML = GeoTemConfig.getString('filter');
-		this.filterOptions = document.createElement("td");
-		tools.appendChild(this.filterOptions);
-	}
-
-	if (options.dataInformation) {
-		this.infoTitle = document.createElement("td");
-		this.infoTitle.innerHTML = options.mapTitle;
-		titles.appendChild(this.infoTitle);
-		var mapSum = document.createElement("td");
-		this.mapElements = document.createElement("div");
-		this.mapElements.setAttribute('class', 'ddbElementsCount');
-		mapSum.appendChild(this.mapElements);
-		tools.appendChild(mapSum);
-	}
-	
-	this.lockTitle = document.createElement("td");
-	titles.appendChild(this.lockTitle);
-	this.lockIcon = document.createElement("td");
-	var lockButton = document.createElement("div");
-	$(lockButton).addClass('mapControl');
-	var activateLock = function() {
-		map.navigation.deactivate();
-	}
-	var deactivateLock = function() {
-		map.navigation.activate();
-	}
-	var lockMapControl = new MapControl(this.map, lockButton, 'lock', activateLock, deactivateLock);
-	tools.appendChild(lockMapControl.button);
-
-
-	var gui = this;
-	if (navigator.geolocation && options.geoLocation) {
-		this.geoActive = false;
-		this.geoLocation = document.createElement("div");
-		this.geoLocation.setAttribute('class', 'geoLocationOff');
-		this.geoLocation.title = GeoTemConfig.getString('activateGeoLocation');
-		this.container.appendChild(this.geoLocation);
-		this.geoLocation.style.left = "20px";
-		this.geoLocation.onclick = function() {
-			var changeStyle = function() {
-				if (gui.geoActive) {
-					gui.geoLocation.setAttribute('class', 'geoLocationOn');
-					gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'deactivateGeoLocation');
-				} else {
-					gui.geoLocation.setAttribute('class', 'geoLocationOff');
-					gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'activateGeoLocation');
-				}
-			}
-			if (!gui.geoActive) {
-				if ( typeof gui.longitude == 'undefined') {
-					navigator.geolocation.getCurrentPosition(function(position) {
-						gui.longitude = position.coords.longitude;
-						gui.latitude = position.coords.latitude;
-						gui.map.setMarker(gui.longitude, gui.latitude);
-						gui.geoActive = true;
-						changeStyle();
-					}, function(msg) {
-						console.log( typeof msg == 'string' ? msg : "error");
-					});
-				} else {
-					gui.map.setMarker(gui.longitude, gui.latitude);
-					gui.geoActive = true;
-					changeStyle();
-				}
-			} else {
-				gui.map.removeMarker();
-				gui.geoActive = false;
-				changeStyle();
-			}
-		}
-	}
-
-	if (!options.olNavigation) {
-		this.map.zoomSlider = new MapZoomSlider(this.map, "vertical");
-		this.container.appendChild(this.map.zoomSlider.div);
-		this.map.zoomSlider.div.style.left = "20px";
-	}
-
-	if (options.resetMap) {
-		this.homeButton = document.createElement("div");
-		this.homeButton.setAttribute('class', 'mapHome');
-		this.homeButton.title = GeoTemConfig.getString('home');
-		this.container.appendChild(this.homeButton);
-		this.homeButton.style.left = "20px";
-		this.homeButton.onclick = function() {
-			if (map.mds.getAllObjects() == null){
-				map.openlayersMap.setCenter(new OpenLayers.LonLat(0, 0));
-				map.openlayersMap.zoomTo(0);
-			}
-			gui.map.drawObjectLayer(true);
-		}
-	}
-
-	if (options.legend) {
-		this.legendDiv = document.createElement("div");
-		this.legendDiv.setAttribute('class', 'mapLegend');
-		this.mapWindow.appendChild(this.legendDiv);
-	}
-
-	var linkForOsm = 'http://www.openstreetmap.org/';
-	var linkForLicense = 'http://creativecommons.org/licenses/by-sa/2.0/';
-	this.osmLink = document.createElement("div");
-	this.osmLink.setAttribute('class', 'osmLink');
-	this.osmLink.innerHTML = '(c) <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>';
-	this.mapWindow.appendChild(this.osmLink);
-	this.osmMapQuestLink = document.createElement("div");
-	this.osmMapQuestLink.setAttribute('class', 'osmLink');
-	this.osmMapQuestLink.innerHTML = '(c) Data, imagery and map information provided by MapQuest <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png"> <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>';
-	this.mapWindow.appendChild(this.osmMapQuestLink);
-
-	//		var tooltip = document.createElement("div");
-	//		tooltip.setAttribute('class','ddbTooltip');
-	//		toolbarTable.appendChild(tooltip);
-
-	//		var tooltip = document.createElement("div");
-	//		tooltip.setAttribute('class','ddbTooltip');
-	//		toolbarTable.appendChild(tooltip);
-	//
-	//		tooltip.onmouseover = function(){
-	//			/*
-	//		    Publisher.Publish('TooltipContent', {
-	//						content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'),
-	//						target: $(tooltip)
-	//					    });
-	//			*/
-	//		}
-	//		tooltip.onmouseout = function(){
-	//		 //   Publisher.Publish('TooltipContent');
-	//		}
-	//		//vhz tooltip on click should open a help file if defined in GeoTemConfig
-	//		if(GeoTemConfig.helpURL) {
-	//			tooltip.onclick = function () {
-	//
-	//			}
-	//		}
-
-	//		}
-	//		tooltip.onmouseout = function(){
-	//   			Publisher.Publish('TooltipContent');
-	//		}
-
-	this.resize = function() {
-		var w = this.container.offsetWidth;
-		var h = this.container.offsetHeight;
-//		this.mapWindow.style.width = w + "px";
-		this.mapWindow.style.height = h + "px";
-//		this.mapContainer.style.width = w + "px";
-		this.mapContainer.style.height = h + "px";
-		var top = toolbarTable.offsetHeight + 20;
-		if (options.olLayerSwitcher) {
-			var switcherDiv = $('.olControlLayerSwitcher')[0];
-			$(switcherDiv).css('top', top + "px");
-		}
-		if ( typeof this.geoLocation != "undefined") {
-			this.geoLocation.style.top = top + "px";
-			top += this.geoLocation.offsetHeight + 4;
-		}
-		if (options.olNavigation) {
-			var panZoomBar = $('.olControlPanZoom')[0];
-			$(panZoomBar).css('top', top + 'px');
-			$(panZoomBar).css('left', '12px');
-			var zoomOut = document.getElementById('OpenLayers.Control.PanZoom_23_zoomout');
-			top += $(zoomOut).height() + $(zoomOut).position().top + 4;
-		} else {
-			this.map.zoomSlider.div.style.top = top + "px";
-			top += this.map.zoomSlider.div.offsetHeight + 2;
-		}
-		if (options.resetMap) {
-			this.homeButton.style.top = top + "px";
-		}
-		this.headerHeight = toolbarTable.offsetHeight;
-		this.headerWidth = toolbarTable.offsetWidth;
-		this.map.openlayersMap.updateSize();
-		this.map.drawObjectLayer(true);
-	};
-
-	this.updateLegend = function(datasets){
-		$(this.legendDiv).empty();
-		var table = $('<table style="margin:10px"/>').appendTo(this.legendDiv);
-		for( var i=0; i<datasets.length; i++ ){
-			var row = $('<tr/>').appendTo(table);
-			if( options.useGraphics ){
-				var graphic = map.config.getGraphic(i);
-				var fill = 'rgb(' + graphic.color.r0 + ',' + graphic.color.g0 + ',' + graphic.color.b0 + ')';
-				var stroke = 'rgb(' + graphic.color.r1 + ',' + graphic.color.g1 + ',' + graphic.color.b1 + ')';
-				var rot = graphic.rotation;
-				var svg;
-				if( graphic.shape == 'circle' ){
-					svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>';
-				}
-				else if( graphic.shape == 'square' ){
-					svg = '<svg style="width:20px;height:20px;"><polygon points="4,4 16,4 16,16 4,16" style="fill:'+fill+';stroke:'+stroke+';stroke-width:2" transform="rotate('+rot+' 10,10)"/></svg>';
-				}
-				else if( graphic.shape == 'triangle' ){
-					svg = '<svg style="width:20px;height:20px;"><polygon points="3,17 17,17 10,5" style="fill:'+fill+';stroke:'+stroke+';stroke-width:2" transform="rotate('+rot+' 10,10)"/></svg>';
-				}
-				$('<td>'+svg+'</td>').appendTo(row);
-			}
-			else {
-				var c = GeoTemConfig.getColor(i);
-				var fill = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')';
-				var stroke = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')';
-				var svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>';
-				$('<td>'+svg+'</td>').appendTo(row);
-			}			
-			$('<td>'+datasets[i].label+'</td>').appendTo(row);
-		}
-	};
-
-	this.updateSpaceQuantity = function(count) {
-		if (!options.dataInformation) {
-			return;
-		}
-		this.mapCount = count;
-		if (count != 1) {
-			this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results');
-		} else {
-			this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result');
-		}
-	}
-
-	this.setMapsDropdown = function() {
-		if (!options.mapSelection) {
-			return;
-		}
-		$(this.mapTypeSelector).empty();
-		var maps = [];
-		var gui = this;
-		var addMap = function(name, index) {
-			var setMap = function() {
-				gui.map.setMap(index);
-			}
-			maps.push({
-				name : name,
-				onclick : setMap
-			});
-		}
-		for (var i = 0; i < this.map.baseLayers.length; i++) {
-			addMap(this.map.baseLayers[i].name, i);
-		}
-		this.mapTypeDropdown = new Dropdown(this.mapTypeSelector, maps, GeoTemConfig.getString('selectMapType'));
-	}
-
-	this.setMap = function() {
-		if (options.mapSelection) {
-			this.mapTypeDropdown.setEntry(this.map.baselayerIndex);
-		}
-	}
-
-	this.setBinningDropdown = function() {
-		if (!options.binningSelection) {
-			return;
-		}
-		$(this.binningSelector).empty();
-		var binnings = [];
-		var gui = this;
-		var index = 0;
-		var entry;
-		var addBinning = function(name, id) {
-			if (options.binning == id) {
-				entry = index;
-			} else {
-				index++;
-			}
-			var setBinning = function() {
-				options.binning = id;
-				gui.map.initWidget(gui.map.datasets, false);
-				gui.map.riseLayer();
-			}
-			binnings.push({
-				name : name,
-				onclick : setBinning
-			});
-		}
-		addBinning(GeoTemConfig.getString('genericBinning'), 'generic');
-		addBinning(GeoTemConfig.getString('squareBinning'), 'square');
-		addBinning(GeoTemConfig.getString('hexagonalBinning'), 'hexagonal');
-		addBinning(GeoTemConfig.getString('triangularBinning'), 'triangular');
-		addBinning(GeoTemConfig.getString('noBinning'), false);
-		var binningDropdown = new Dropdown(this.binningSelector, binnings, GeoTemConfig.getString('binningTooltip'));
-		binningDropdown.setEntry(entry);
-	}
-	this.setBinningDropdown();
-
-	this.beautifyCount = function(count) {
-		var c = count + '';
-		var p = 0;
-		var l = c.length;
-		while (l - p > 3) {
-			p += 3;
-			c = c.substring(0, l - p) + "." + c.substring(l - p);
-			p++;
-			l++;
-		}
-		return c;
-	}
-
-};
+/*
+* MapConfig.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class MapConfig
+ * Map Configuration File
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+function MapConfig(options) {
+
+	this.options = {
+		mapWidth : false, // false or desired width css definition for the map
+		mapHeight : false, // false or desired height css definition for the map
+		mapTitle : 'GeoTemCo Map View', // title will be shown in map header
+		mapIndex : 0, // index = position in location array; for multiple locations the 2nd map refers to index 1
+		alternativeMap :  [
+		/*		{
+					name: 'Barrington Roman Empire',
+					url: 'http://pelagios.dme.ait.ac.at/tilesets/imperium/${z}/${x}/${y}.png',
+					type:'XYZ',
+					attribution: "(c) Barrington Roman Empiry, <a href='http://pelagios.dme.ait.ac.at/maps/greco-roman/'>Pelagios</a>"
+				},
+				{
+					name: 'Maps-for-Free Relief Map',
+					url: 'http://maps-for-free.com/layer/relief/z${z}/row${y}/${z}_${x}-${y}.jpg',
+					type:'XYZ',
+					attribution: "(c) <a href='http://www.maps-for-free.com/html/about.html'>Maps for Free</a>"
+				},
+				{
+					name: 'Contemporary Map (2010)',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry2010',
+					attribution: "(c) <a href='http://epp.eurostat.ec.europa.eu/portal/page/portal/gisco_Geographical_information_maps/popups/references/administrative_units_statistical_units_1'>EuroStat</a>"
+				},
+				{
+					name: 'Historical Map of 2006',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry2006',
+					attribution: "(c) <a href='http://epp.eurostat.ec.europa.eu/portal/page/portal/gisco_Geographical_information_maps/popups/references/administrative_units_statistical_units_1'>EuroStat</a>"
+				},
+				{
+					name: 'Historical Map of 1994',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1994',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1945',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1945',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1938',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1938',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1920',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1920',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1914',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1914',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1880',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1880',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1815',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1815',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1783',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1783',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1715',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1715',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1650',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1650',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1530',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1530',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1492',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1492',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1279',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1279',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1000',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1000',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 800',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry800',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 600',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry600',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 400',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry400',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 1 BC',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1bc',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 200 BC',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry200bc',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 323 BC',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry323bc',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 500 BC',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry500bc',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+*/
+				{
+					name: 'Historical Map of 1000 BC',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry1000bc',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+				{
+					name: 'Historical Map of 2000 BC',
+					url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms',
+					layer: 'historic:cntry2000bc',
+					attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>"
+				},
+		],
+		legend : true, // if a legend at the bottom of the map should be shown or not
+		mapMerge : false, // if the elements of distinct datasets should be merged into one set or not
+		useGraphics : false,  // if different graphics should represent different datasets or not
+		graphics : [
+			{
+				shape: "circle",
+				rotation: 0
+			},
+			{
+				shape: "square",
+				rotation: 0
+			},
+			{
+				shape: "triangle",
+				rotation: 0
+			},
+			{
+				shape: "square",
+				rotation: 45
+			}
+		],
+		googleMaps : false, // enable/disable Google maps (actually, no Google Maps API key is required)
+		bingMaps : false, // enable/disable Bing maps (you need to set the Bing Maps API key below)
+		bingApiKey : 'none', // bing maps api key, see informations at http://bingmapsportal.com/
+		osmMaps : true, // enable/disable OSM maps
+		osmMapsMapQuest : true, // enable/disable OSM maps with MapQuest tiles
+		baseLayer : 'Open Street Map', // initial layer to show (e.g. 'Google Streets')
+		resetMap : true, // show/hide map reset button
+		countrySelect : true, // show/hide map country selection control button
+		polygonSelect : true, // show/hide map polygon selection control button
+		circleSelect : true, // show/hide map circle selection control button
+		squareSelect : true, // show/hide map square selection control button
+		multiSelection : true, // true, if multiple polygons or multiple circles should be selectable
+		popups : true, // enabled popups will show popup windows for circles on the map
+		olNavigation : false, // show/hide OpenLayers navigation panel
+		olLayerSwitcher : false, // show/hide OpenLayers layer switcher
+		olMapOverview : false, // show/hide OpenLayers map overview
+		olKeyboardDefaults : true, // (de)activate Openlayers keyboard defaults
+		olScaleLine : false, // (de)activate Openlayers keyboard defaults
+		geoLocation : true, // show/hide GeoLocation feature
+		boundaries : {
+			minLon : -29,
+			minLat : 35,
+			maxLon : 44,
+			maxLat : 67
+		}, // initial map boundaries or 'false' for no boundaries
+		mapBackground : '#bbd0ed',
+		labelGrid : true, // show label grid on hover
+		maxPlaceLabels : 6, // Integer value for fixed number of place labels: 0 --> unlimited, 1 --> 1 label (won't be shown in popup, 2 --> is not possible because of others & all labels --> 3 labels, [3,...,N] --> [3,...,N] place labels)
+		selectDefault : true, // true, if strongest label should be selected as default
+		maxLabelIncrease : 2, // maximum increase (in em) for the font size of a label
+		labelHover : false, // true, to update on label hover
+		ieHighlightLabel : "color: COLOR1; background-color: COLOR0; filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';", // css code for a highlighted place label in IE
+		highlightLabel : "color: COLOR0; text-shadow: 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em COLOR0;", // css code for a highlighted place label
+		ieSelectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label in IE
+		selectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label
+		ieUnselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label in IE
+		unselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label
+		ieHoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label in IE
+		hoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label
+		circleGap : 0, // gap between the circles on the map (>=0)
+		circleOverlap : {
+			type: 'area', // 'area' or 'diameter' is possible
+			overlap: 1 // the percentage of allowed overlap (0<=overlap<=1)
+		}, // maximum allowed overlap in percent (if circleGap = 0, circleOverlap will be used)
+		minimumRadius : 1, // minimum radius of a circle with mimimal weight (>0)
+		circleOutline : 2, // false for no outline or a pixel value v with 0 < v
+		circleOpacity : 'balloon', // 'balloon' for dynamic opacity of the circles or a value t with 0 <= t <= 1
+		minTransparency : 0.55, // maximum transparency of a circle
+		maxTransparency : 0.8, // minimum transparency of a circle
+		binning : 'generic', // binning algorithm for the map, possible values are: 'generic', 'square', 'hexagonal', 'triangular' or false for 'no binning'
+		noBinningRadii : 'dynamic', // for 'no binning': 'static' for only minimum radii, 'dynamic' for increasing radii for increasing weights
+		circlePackings : true, // if circles of multiple result sets should be displayed in circle packs, if a binning is performed
+		binCount : 10, // number of bins for x and y dimension for lowest zoom level
+		showDescriptions : true, // true to show descriptions of data items (must be provided by kml/json), false if not
+		mapSelection : true, // show/hide select map dropdown
+		binningSelection : false, // show/hide binning algorithms dropdown
+		mapSelectionTools : true, // show/hide map selector tools
+		dataInformation : true, // show/hide data information
+		overlayVisibility : false, // initial visibility of additional overlays
+		//proxyHost : 'php/proxy.php?address=',	//required for selectCountry feature, if the requested GeoServer and GeoTemCo are NOT on the same server
+		placenameTagsStyle : 'value' // the style of the placenames "surrounding" a circle on hover. 'zoom' for tags based on zoom level (old behaviour), 'value' for new value-based
+
+	};
+	if ( typeof options != 'undefined') {
+		$.extend(this.options, options);
+	}
+	
+	//if the user can change shape/color graphics have to be used
+	//but this will use circles as default shape
+	if (GeoTemConfig.allowUserShapeAndColorChange){
+		this.options.useGraphics = true;
+	}
+
+};
+
+MapConfig.prototype.getGraphic = function(id){
+	var dataset = GeoTemConfig.datasets[id];
+
+	var graphic;
+	if (typeof dataset.graphic !== "undefined"){
+		graphic = dataset.graphic;
+	} else{
+		graphic = this.options.graphics[id % this.options.graphics.length];
+	}
+	
+	var color;
+	if (typeof dataset.color !== "undefined"){
+		color = dataset.color;
+	} else{
+		color = GeoTemConfig.getColor(id);
+	}
+	return {
+		shape: graphic.shape,
+		rotation: graphic.rotation,
+		color: color
+	};
+};
+/*
+* MapGui.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class MapGui
+ * Map GUI Implementation
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ *
+ * @param {MapWidget} parent map widget object
+ * @param {HTML object} div parent div to append the map gui
+ * @param {JSON} options map configuration
+ */
+function MapGui(map, div, options, iid) {
+
+	this.map = map;
+
+	this.container = div;
+	if (options.mapWidth) {
+		this.container.style.width = options.mapWidth;
+	}
+	if (options.mapHeight) {
+		this.container.style.height = options.mapHeight;
+	}
+	this.container.style.position = 'relative';
+
+	this.mapWindow = document.createElement("div");
+	this.mapWindow.setAttribute('class', 'mapWindow');
+	this.mapWindow.id = "mapWindow"+iid;
+	this.mapWindow.style.background = options.mapBackground;
+	this.container.appendChild(this.mapWindow);
+
+	this.mapContainer = document.createElement("div");
+	this.mapContainer.setAttribute('class', 'mapContainer');
+	this.mapContainer.id = "mapContainer"+iid;
+	this.mapContainer.style.position = "absolute";
+	this.mapContainer.style.zIndex = 0;
+	this.mapWindow.appendChild(this.mapContainer);
+
+	var toolbarTable = document.createElement("table");
+	toolbarTable.setAttribute('class', 'absoluteToolbar ddbToolbar');
+	this.container.appendChild(toolbarTable);
+	this.mapToolbar = toolbarTable;
+
+	var titles = document.createElement("tr");
+	toolbarTable.appendChild(titles);
+	var tools = document.createElement("tr");
+	toolbarTable.appendChild(tools);
+
+	if (options.mapSelection) {
+		this.mapTypeTitle = document.createElement("td");
+		titles.appendChild(this.mapTypeTitle);
+		this.mapTypeTitle.innerHTML = GeoTemConfig.getString('mapType');
+		this.mapTypeSelector = document.createElement("td");
+		tools.appendChild(this.mapTypeSelector);
+	}
+
+	if (options.mapSelectionTools) {
+		this.mapSelectorTitle = document.createElement("td");
+		titles.appendChild(this.mapSelectorTitle);
+		this.mapSelectorTitle.innerHTML = GeoTemConfig.getString('mapSelectorTools');
+		var mapSelectorTools = document.createElement("td");
+		var selectorTools = this.map.initSelectorTools();
+		for (var i in selectorTools ) {
+			mapSelectorTools.appendChild(selectorTools[i].button);
+		}
+		tools.appendChild(mapSelectorTools);
+	}
+
+	if (options.binningSelection) {
+		this.binningTitle = document.createElement("td");
+		titles.appendChild(this.binningTitle);
+		this.binningTitle.innerHTML = GeoTemConfig.getString('binningType');
+		this.binningSelector = document.createElement("td");
+		tools.appendChild(this.binningSelector);
+	}
+
+	if (GeoTemConfig.allowFilter) {
+		this.filterTitle = document.createElement("td");
+		titles.appendChild(this.filterTitle);
+		this.filterTitle.innerHTML = GeoTemConfig.getString('filter');
+		this.filterOptions = document.createElement("td");
+		tools.appendChild(this.filterOptions);
+	}
+
+	if (options.dataInformation) {
+		this.infoTitle = document.createElement("td");
+		this.infoTitle.innerHTML = options.mapTitle;
+		titles.appendChild(this.infoTitle);
+		var mapSum = document.createElement("td");
+		this.mapElements = document.createElement("div");
+		this.mapElements.setAttribute('class', 'ddbElementsCount');
+		mapSum.appendChild(this.mapElements);
+		tools.appendChild(mapSum);
+	}
+	
+	this.lockTitle = document.createElement("td");
+	titles.appendChild(this.lockTitle);
+	this.lockIcon = document.createElement("td");
+	var lockButton = document.createElement("div");
+	$(lockButton).addClass('mapControl');
+	var activateLock = function() {
+		map.navigation.deactivate();
+	}
+	var deactivateLock = function() {
+		map.navigation.activate();
+	}
+	var lockMapControl = new MapControl(this.map, lockButton, 'lock', activateLock, deactivateLock);
+	tools.appendChild(lockMapControl.button);
+
+
+	var gui = this;
+	if (navigator.geolocation && options.geoLocation) {
+		this.geoActive = false;
+		this.geoLocation = document.createElement("div");
+		this.geoLocation.setAttribute('class', 'geoLocationOff');
+		this.geoLocation.title = GeoTemConfig.getString('activateGeoLocation');
+		this.container.appendChild(this.geoLocation);
+		this.geoLocation.style.left = "20px";
+		this.geoLocation.onclick = function() {
+			var changeStyle = function() {
+				if (gui.geoActive) {
+					gui.geoLocation.setAttribute('class', 'geoLocationOn');
+					gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'deactivateGeoLocation');
+				} else {
+					gui.geoLocation.setAttribute('class', 'geoLocationOff');
+					gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'activateGeoLocation');
+				}
+			}
+			if (!gui.geoActive) {
+				if ( typeof gui.longitude == 'undefined') {
+					navigator.geolocation.getCurrentPosition(function(position) {
+						gui.longitude = position.coords.longitude;
+						gui.latitude = position.coords.latitude;
+						gui.map.setMarker(gui.longitude, gui.latitude);
+						gui.geoActive = true;
+						changeStyle();
+					}, function(msg) {
+						console.log( typeof msg == 'string' ? msg : "error");
+					});
+				} else {
+					gui.map.setMarker(gui.longitude, gui.latitude);
+					gui.geoActive = true;
+					changeStyle();
+				}
+			} else {
+				gui.map.removeMarker();
+				gui.geoActive = false;
+				changeStyle();
+			}
+		}
+	}
+
+	if (!options.olNavigation) {
+		this.map.zoomSlider = new MapZoomSlider(this.map, "vertical");
+		this.container.appendChild(this.map.zoomSlider.div);
+		this.map.zoomSlider.div.style.left = "20px";
+	}
+
+	if (options.resetMap) {
+		this.homeButton = document.createElement("div");
+		this.homeButton.setAttribute('class', 'mapHome');
+		this.homeButton.title = GeoTemConfig.getString('home');
+		this.container.appendChild(this.homeButton);
+		this.homeButton.style.left = "20px";
+		this.homeButton.onclick = function() {
+			if (map.mds.getAllObjects() == null){
+				map.openlayersMap.setCenter(new OpenLayers.LonLat(0, 0));
+				map.openlayersMap.zoomTo(0);
+			}
+			gui.map.drawObjectLayer(true);
+		}
+	}
+
+	if (options.legend) {
+		this.legendDiv = document.createElement("div");
+		this.legendDiv.setAttribute('class', 'mapLegend');
+		this.mapWindow.appendChild(this.legendDiv);
+	}
+
+	var linkForOsm = 'http://www.openstreetmap.org/';
+	var linkForLicense = 'http://creativecommons.org/licenses/by-sa/2.0/';
+	this.osmLink = document.createElement("div");
+	this.osmLink.setAttribute('class', 'osmLink');
+	this.osmLink.innerHTML = '(c) <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>';
+	this.mapWindow.appendChild(this.osmLink);
+	this.osmMapQuestLink = document.createElement("div");
+	this.osmMapQuestLink.setAttribute('class', 'osmLink');
+	this.osmMapQuestLink.innerHTML = '(c) Data, imagery and map information provided by MapQuest <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png"> <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>';
+	this.mapWindow.appendChild(this.osmMapQuestLink);
+
+	//		var tooltip = document.createElement("div");
+	//		tooltip.setAttribute('class','ddbTooltip');
+	//		toolbarTable.appendChild(tooltip);
+
+	//		var tooltip = document.createElement("div");
+	//		tooltip.setAttribute('class','ddbTooltip');
+	//		toolbarTable.appendChild(tooltip);
+	//
+	//		tooltip.onmouseover = function(){
+	//			/*
+	//		    Publisher.Publish('TooltipContent', {
+	//						content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'),
+	//						target: $(tooltip)
+	//					    });
+	//			*/
+	//		}
+	//		tooltip.onmouseout = function(){
+	//		 //   Publisher.Publish('TooltipContent');
+	//		}
+	//		//vhz tooltip on click should open a help file if defined in GeoTemConfig
+	//		if(GeoTemConfig.helpURL) {
+	//			tooltip.onclick = function () {
+	//
+	//			}
+	//		}
+
+	//		}
+	//		tooltip.onmouseout = function(){
+	//   			Publisher.Publish('TooltipContent');
+	//		}
+
+	this.resize = function() {
+		var w = this.container.offsetWidth;
+		var h = this.container.offsetHeight;
+//		this.mapWindow.style.width = w + "px";
+		this.mapWindow.style.height = h + "px";
+//		this.mapContainer.style.width = w + "px";
+		this.mapContainer.style.height = h + "px";
+		var top = toolbarTable.offsetHeight + 20;
+		if (options.olLayerSwitcher) {
+			var switcherDiv = $('.olControlLayerSwitcher')[0];
+			$(switcherDiv).css('top', top + "px");
+		}
+		if ( typeof this.geoLocation != "undefined") {
+			this.geoLocation.style.top = top + "px";
+			top += this.geoLocation.offsetHeight + 4;
+		}
+		if (options.olNavigation) {
+			var panZoomBar = $('.olControlPanZoom')[0];
+			$(panZoomBar).css('top', top + 'px');
+			$(panZoomBar).css('left', '12px');
+			var zoomOut = document.getElementById('OpenLayers.Control.PanZoom_23_zoomout');
+			top += $(zoomOut).height() + $(zoomOut).position().top + 4;
+		} else {
+			this.map.zoomSlider.div.style.top = top + "px";
+			top += this.map.zoomSlider.div.offsetHeight + 2;
+		}
+		if (options.resetMap) {
+			this.homeButton.style.top = top + "px";
+		}
+		this.headerHeight = toolbarTable.offsetHeight;
+		this.headerWidth = toolbarTable.offsetWidth;
+		this.map.openlayersMap.updateSize();
+		this.map.drawObjectLayer(true);
+	};
+
+	this.updateLegend = function(datasets){
+		$(this.legendDiv).empty();
+		var table = $('<table style="margin:10px"/>').appendTo(this.legendDiv);
+		for( var i=0; i<datasets.length; i++ ){
+			var row = $('<tr/>').appendTo(table);
+			if( options.useGraphics ){
+				var graphic = map.config.getGraphic(i);
+				var fill = 'rgb(' + graphic.color.r0 + ',' + graphic.color.g0 + ',' + graphic.color.b0 + ')';
+				var stroke = 'rgb(' + graphic.color.r1 + ',' + graphic.color.g1 + ',' + graphic.color.b1 + ')';
+				var rot = graphic.rotation;
+				var svg;
+				if( graphic.shape == 'circle' ){
+					svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>';
+				}
+				else if( graphic.shape == 'square' ){
+					svg = '<svg style="width:20px;height:20px;"><polygon points="4,4 16,4 16,16 4,16" style="fill:'+fill+';stroke:'+stroke+';stroke-width:2" transform="rotate('+rot+' 10,10)"/></svg>';
+				}
+				else if( graphic.shape == 'triangle' ){
+					svg = '<svg style="width:20px;height:20px;"><polygon points="3,17 17,17 10,5" style="fill:'+fill+';stroke:'+stroke+';stroke-width:2" transform="rotate('+rot+' 10,10)"/></svg>';
+				}
+				$('<td>'+svg+'</td>').appendTo(row);
+			}
+			else {
+				var c = GeoTemConfig.getColor(i);
+				var fill = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')';
+				var stroke = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')';
+				var svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>';
+				$('<td>'+svg+'</td>').appendTo(row);
+			}			
+			$('<td>'+datasets[i].label+'</td>').appendTo(row);
+		}
+	};
+
+	this.updateSpaceQuantity = function(count) {
+		if (!options.dataInformation) {
+			return;
+		}
+		this.mapCount = count;
+		if (count != 1) {
+			this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results');
+		} else {
+			this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result');
+		}
+	}
+
+	this.setMapsDropdown = function() {
+		if (!options.mapSelection) {
+			return;
+		}
+		$(this.mapTypeSelector).empty();
+		var maps = [];
+		var gui = this;
+		var addMap = function(name, index) {
+			var setMap = function() {
+				gui.map.setMap(index);
+			}
+			maps.push({
+				name : name,
+				onclick : setMap
+			});
+		}
+		for (var i = 0; i < this.map.baseLayers.length; i++) {
+			addMap(this.map.baseLayers[i].name, i);
+		}
+		this.mapTypeDropdown = new Dropdown(this.mapTypeSelector, maps, GeoTemConfig.getString('selectMapType'));
+	}
+
+	this.setMap = function() {
+		if (options.mapSelection) {
+			this.mapTypeDropdown.setEntry(this.map.baselayerIndex);
+		}
+	}
+
+	this.setBinningDropdown = function() {
+		if (!options.binningSelection) {
+			return;
+		}
+		$(this.binningSelector).empty();
+		var binnings = [];
+		var gui = this;
+		var index = 0;
+		var entry;
+		var addBinning = function(name, id) {
+			if (options.binning == id) {
+				entry = index;
+			} else {
+				index++;
+			}
+			var setBinning = function() {
+				options.binning = id;
+				gui.map.initWidget(gui.map.datasets, false);
+				gui.map.riseLayer();
+			}
+			binnings.push({
+				name : name,
+				onclick : setBinning
+			});
+		}
+		addBinning(GeoTemConfig.getString('genericBinning'), 'generic');
+		addBinning(GeoTemConfig.getString('squareBinning'), 'square');
+		addBinning(GeoTemConfig.getString('hexagonalBinning'), 'hexagonal');
+		addBinning(GeoTemConfig.getString('triangularBinning'), 'triangular');
+		addBinning(GeoTemConfig.getString('noBinning'), false);
+		var binningDropdown = new Dropdown(this.binningSelector, binnings, GeoTemConfig.getString('binningTooltip'));
+		binningDropdown.setEntry(entry);
+	}
+	this.setBinningDropdown();
+
+	this.beautifyCount = function(count) {
+		var c = count + '';
+		var p = 0;
+		var l = c.length;
+		while (l - p > 3) {
+			p += 3;
+			c = c.substring(0, l - p) + "." + c.substring(l - p);
+			p++;
+			l++;
+		}
+		return c;
+	}
+
+};
 /*
 * MapWidget.js
 *
@@ -34678,1765 +34683,1765 @@
 		}
 	}
 }
-/*
-* TimeConfig.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class TimeConfig
- * Time Configuration File
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-function TimeConfig(options) {
-
-	this.options = {
-		timeTitle : 'GeoTemCo Time View', // title will be shown in timeplot header
-		timeIndex : 0, // index = position in date array; for multiple dates the 2nd timeplot refers to index 1
-		timeWidth : false, // false or desired width css definition for the timeplot
-		timeHeight : '100px', // false or desired height css definition for the timeplot
-		defaultMinDate : new Date(2012, 0, 1), // required, when empty timelines are possible
-		defaultMaxDate : new Date(), // required, when empty timelines are possible
-		timeCanvasFrom : '#EEE', // time widget background gradient color top
-		timeCanvasTo : '#EEE', // time widget background gradient color bottom
-		rangeBoxColor : "white", // fill color for time range box
-		rangeBorder : "1px solid #de7708", // border of frames
-		dataInformation : true, // show/hide data information
-		rangeAnimation : true, // show/hide animation buttons
-		scaleSelection : true, // show/hide scale selection buttons
-		linearScale : true, // true for linear value scaling, false for logarithmic
-		unitSelection : true, // show/hide time unit selection dropdown
-		timeUnit : -1, // minimum temporal unit (SimileAjax.DateTime or -1 if none) of the data
-		timeMerge : false // if the elements of distinct datasets should be merged into one set or not
-	};
-	if ( typeof options != 'undefined') {
-		$.extend(this.options, options);
-	}
-
-};
-/*
-* TimeGui.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class TimeGui
- * Time GUI Implementation
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- *
- * @param {TimeWidget} parent time widget object
- * @param {HTML object} div parent div to append the time gui
- * @param {JSON} options time configuration
- */
-function TimeGui(plot, div, options, iid) {
-
-	var gui = this;
-
-	this.plot = plot;
-
-	this.container = div;
-	if (options.timeWidth) {
-		this.container.style.width = options.timeWidth;
-	}
-	if (options.timeHeight) {
-		this.container.style.height = options.timeHeight;
-	}
-	this.container.style.position = 'relative';
-
-	var w = this.container.offsetWidth;
-	var h = this.container.offsetHeight;
-
-	var toolbarTable = document.createElement("table");
-	toolbarTable.setAttribute('class', 'ddbToolbar');
-	this.container.appendChild(toolbarTable);
-
-	this.plotWindow = document.createElement("div");
-	this.plotWindow.id = "plotWindow"+iid;
-	this.plotWindow.setAttribute('class', 'plotWindow');
-//	this.plotWindow.style.width = w + "px";
-
-	this.plotWindow.style.height = (h + 12) + "px";
-	this.container.style.height = (h + 12) + "px";
-
-	this.plotWindow.onmousedown = function() {
-		return false;
-	}
-
-	this.plotContainer = document.createElement("div");
-	this.plotContainer.id = "plotContainer"+iid;
-	this.plotContainer.setAttribute('class', 'plotContainer');
-//	this.plotContainer.style.width = w + "px";
-	this.plotContainer.style.height = h + "px";
-	this.plotContainer.style.position = "absolute";
-	this.plotContainer.style.zIndex = 0;
-	this.plotContainer.style.top = "12px";
-	this.plotWindow.appendChild(this.plotContainer);
-	this.container.appendChild(this.plotWindow);
-
-	this.timeplotDiv = document.createElement("div");
-	this.timeplotDiv.style.left = "16px";
-	this.timeplotDiv.style.width = (w - 32) + "px";
-	this.timeplotDiv.style.height = h + "px";
-	this.plotContainer.appendChild(this.timeplotDiv);
-
-	var cv = document.createElement("canvas");
-	cv.setAttribute('class', 'plotCanvas');
-	this.plotWindow.appendChild(cv);
-	if (!cv.getContext && G_vmlCanvasManager)
-		cv = G_vmlCanvasManager.initElement(cv);
-	var ctx = cv.getContext('2d');
-
-	var setCanvas = function(){
-		cv.width = gui.plotWindow.clientWidth;
-		cv.height = gui.plotWindow.clientHeight;
-		var gradient = ctx.createLinearGradient(0, 0, 0, gui.plotWindow.clientHeight);
-		gradient.addColorStop(0, options.timeCanvasFrom);
-		gradient.addColorStop(1, options.timeCanvasTo);
-		ctx.fillStyle = gradient;
-		ctx.fillRect(0, 0, gui.plotWindow.clientWidth, gui.plotWindow.clientHeight);
-	}
-	setCanvas();
-
-	this.resize = function(){
-		gui.timeplotDiv.style.width = (gui.container.offsetWidth - 32) + "px";
-		ctx.clearRect(0,0,gui.plotWindow.clientWidth, gui.plotWindow.clientHeight);
-		if( typeof plot.datasets != "undefined" ){
-			plot.redrawPlot();
-			plot.resetOpacityPlots();
-		}
-		setCanvas();
-	};
-
-	var titles = document.createElement("tr");
-	toolbarTable.appendChild(titles);
-	var tools = document.createElement("tr");
-	toolbarTable.appendChild(tools);
-
-	this.timeUnitTitle = document.createElement("td");
-	this.timeUnitTitle.innerHTML = GeoTemConfig.getString('timeUnit');
-	this.timeUnitSelector = document.createElement("td");
-	if (options.unitSelection) {
-		tools.appendChild(this.timeUnitSelector);
-		titles.appendChild(this.timeUnitTitle);
-	}
-
-	this.timeAnimation = document.createElement("td");
-	this.timeAnimation.innerHTML = GeoTemConfig.getString('timeAnimation');
-	var timeAnimationTools = document.createElement("td");
-
-	var status;
-	this.updateAnimationButtons = function(s) {
-		status = s;
-		if (status == 0) {
-			gui.playButton.setAttribute('class', 'smallButton playDisabled');
-			gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled');
-		} else if (status == 1) {
-			gui.playButton.setAttribute('class', 'smallButton playEnabled');
-			gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled');
-		} else {
-			gui.playButton.setAttribute('class', 'smallButton playDisabled');
-			gui.pauseButton.setAttribute('class', 'smallButton pauseEnabled');
-		}
-	};
-	this.playButton = document.createElement("div");
-	this.playButton.title = GeoTemConfig.getString('playButton');
-	timeAnimationTools.appendChild(this.playButton);
-	this.playButton.onclick = function() {
-		if (status == 1) {
-			plot.play();
-		}
-	}
-
-	this.pauseButton = document.createElement("div");
-	this.pauseButton.title = GeoTemConfig.getString('pauseButton');
-	timeAnimationTools.appendChild(this.pauseButton);
-	this.pauseButton.onclick = function() {
-		if (status == 2) {
-			plot.stop();
-		}
-	}
-
-	this.valueScale = document.createElement("td");
-	this.valueScale.innerHTML = GeoTemConfig.getString('valueScale');
-	var valueScaleTools = document.createElement("td");
-
-	var linearPlot;
-	var setValueScale = function(linScale) {
-		if (linearPlot != linScale) {
-			linearPlot = linScale;
-			if (linearPlot) {
-				gui.linButton.setAttribute('class', 'smallButton linearPlotActivated');
-				gui.logButton.setAttribute('class', 'smallButton logarithmicPlotDeactivated');
-				plot.drawLinearPlot();
-			} else {
-				gui.linButton.setAttribute('class', 'smallButton linearPlotDeactivated');
-				gui.logButton.setAttribute('class', 'smallButton logarithmicPlotActivated');
-				plot.drawLogarithmicPlot();
-			}
-		}
-	};
-	this.linButton = document.createElement("div");
-	this.linButton.title = GeoTemConfig.getString('linearPlot');
-	valueScaleTools.appendChild(this.linButton);
-	this.linButton.onclick = function() {
-		setValueScale(true);
-	}
-
-	this.logButton = document.createElement("div");
-	this.logButton.title = GeoTemConfig.getString('logarithmicPlot');
-	valueScaleTools.appendChild(this.logButton);
-	this.logButton.onclick = function() {
-		setValueScale(false);
-	}
-	if (options.rangeAnimation) {
-		titles.appendChild(this.timeAnimation);
-		tools.appendChild(timeAnimationTools);
-		this.updateAnimationButtons(0);
-	}
-
-	if (options.scaleSelection) {
-		titles.appendChild(this.valueScale);
-		tools.appendChild(valueScaleTools);
-		setValueScale(options.linearScale);
-	}
-
-	if (GeoTemConfig.allowFilter) {
-		this.filterTitle = document.createElement("td");
-		titles.appendChild(this.filterTitle);
-		this.filterTitle.innerHTML = GeoTemConfig.getString('filter');
-		this.filterOptions = document.createElement("td");
-		tools.appendChild(this.filterOptions);
-	}
-
-	if (options.dataInformation) {
-		this.infoTitle = document.createElement("td");
-		this.infoTitle.innerHTML = options.timeTitle;
-		titles.appendChild(this.infoTitle);
-		var timeSum = document.createElement("td");
-		this.timeElements = document.createElement("div");
-		this.timeElements.setAttribute('class', 'ddbElementsCount');
-		timeSum.appendChild(this.timeElements);
-		tools.appendChild(timeSum);
-	}
-
-	/*
-	 var tooltip = document.createElement("div");
-	 tooltip.setAttribute('class','ddbTooltip');
-	 toolbarTable.appendChild(tooltip);
-
-	 tooltip.onmouseover = function(){
-	 /*
-	 getPublisher().Publish('TooltipContent', {
-	 content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'),
-	 target: $(tooltip)
-	 });
-
-	 }
-	 tooltip.onmouseout = function(){
-	 //getPublisher().Publish('TooltipContent');
-	 }
-	 */
-
-	this.setHeight = function() {
-		this.container.style.height = (this.plotWindow.offsetHeight + toolbarTable.offsetHeight) + "px";
-	};
-
-	this.updateTimeQuantity = function(count) {
-		if (options.dataInformation) {
-			this.plotCount = count;
-			if (count != 1) {
-				this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results');
-			} else {
-				this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result');
-			}
-		}
-	}
-
-	this.setTimeUnitDropdown = function(units) {
-		$(this.timeUnitSelector).empty();
-		var gui = this;
-		var timeUnits = [];
-		var addUnit = function(unit, index) {
-			var setUnit = function() {
-				gui.plot.setTimeUnit(unit.unit);
-			}
-			timeUnits.push({
-				name : unit.label,
-				onclick : setUnit
-			});
-		}
-		for (var i = 0; i < units.length; i++) {
-			addUnit(units[i], i);
-		}
-		this.timeUnitDropdown = new Dropdown(this.timeUnitSelector, timeUnits, GeoTemConfig.getString('selectTimeUnit'), '100px');
-		this.timeUnitDropdown.setEntry(0);
-	}
-	this.setTimeUnitDropdown([{
-		name : 'none',
-		id : -1
-	}]);
-
-	this.beautifyCount = function(count) {
-		var c = count + '';
-		var p = 0;
-		var l = c.length;
-		while (l - p > 3) {
-			p += 3;
-			c = c.substring(0, l - p) + "." + c.substring(l - p);
-			p++;
-			l++;
-		}
-		return c;
-	}
-
-	this.hideTimeUnitSelection = function() {
-		this.timeUnitTitle.style.display = 'none';
-		this.timeUnitSelector.style.display = 'none';
-	}
-};
-/*
-* TimeWidget.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class TimeWidget
- * TableWidget Implementation
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- *
- * @param {TimeWrapper} core wrapper for interaction to other widgets
- * @param {HTML object} div parent div to append the time widget div
- * @param {JSON} options user specified configuration that overwrites options in TimeConfig.js
- */
-TimeWidget = function(core, div, options) {
-
-	this.core = core;
-	this.core.setWidget(this);
-	this.timeplot
-	this.dataSources
-	this.eventSources
-	this.tds
-	this.timeGeometry
-	this.valueGeometry
-	this.canvas
-
-	this.leftFlagPole
-	this.rightFlagPole
-	this.rangeBox
-	this.leftHandle
-	this.rightHandle
-
-	this.leftFlagPos = null;
-	this.leftFlagTime = null;
-	this.rightFlagPos = null;
-	this.rightFlagTime = null;
-
-	this.mouseDownTime
-	this.mouseUpTime
-	this.mouseTempTime
-	this.mouseDownPos
-	this.mouseUpPos
-	this.mouseTempPos
-
-	this.status
-	this.slider
-
-	this.iid = GeoTemConfig.getIndependentId('time');
-	this.options = (new TimeConfig(options)).options;
-	this.gui = new TimeGui(this, div, this.options, this.iid);
-	this.initialize();
-
-}
-
-TimeWidget.prototype = {
-
-	/**
-	 * clears the timeplot canvas and the timeGeometry properties
-	 */
-	clearTimeplot : function() {
-		this.timeplot._clearCanvas();
-		this.timeGeometry._earliestDate = null;
-		this.timeGeometry._latestDate = null;
-		this.valueGeometry._minValue = 0;
-		this.valueGeometry._maxValue = 0;
-		this.highlightedSlice = undefined;
-		this.timeGeometry._clearLabels();
-		this.selection = new Selection();
-	},
-
-	/**
-	 * initializes the timeplot elements with arrays of time objects
-	 * @param {TimeObject[][]} timeObjects an array of time objects from different (1-4) sets
-	 */
-	initWidget : function(datasets) {
-		this.datasets = datasets;
-		var timeObjects = [];
-		for (var i = 0; i < datasets.length; i++) {
-			timeObjects.push(datasets[i].objects);
-		}
-		this.clearTimeplot();
-		this.reset();
-		for (var i = 0; i < this.timeplot._plots.length; i++) {
-			this.timeplot._plots[i].dispose();
-		}
-		this.dataSources = new Array();
-		this.plotInfos = new Array();
-		this.eventSources = new Array();
-		var granularity = 0;
-		this.count = 0;
-		for (var i = 0; i < timeObjects.length; i++) {
-			if( i==0 || !this.options.timeMerge ){
-				var eventSource = new Timeplot.DefaultEventSource();
-				var dataSource = new Timeplot.ColumnSource(eventSource, 1);
-				this.dataSources.push(dataSource);
-				this.eventSources.push(eventSource);
-				var c = GeoTemConfig.getColor(i);
-				var plotInfo = Timeplot.createPlotInfo({
-					id : "plot" + i,
-					dataSource : dataSource,
-					timeGeometry : this.timeGeometry,
-					valueGeometry : this.valueGeometry,
-					fillGradient : false,
-					lineColor : 'rgba(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ', 1)',
-					fillColor : 'rgba(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ', 0.3)',
-					showValues : true
-				});
-				this.plotInfos.push(plotInfo);
-			}
-			for (var j = 0; j < timeObjects[i].length; j++) {
-				var o = timeObjects[i][j];
-				if (o.isTemporal) {
-					var g = o.dates[this.options.timeIndex].granularity;
-					if (g == null) {
-						continue;
-					} else if (g > granularity) {
-						granularity = g;
-					}
-					this.count += o.weight;
-				}
-			}
-		}
-		this.timeGeometry._granularity = granularity;
-		this.timeGeometry._clearLabels();
-		this.timeplot.resetPlots(this.plotInfos);
-		if (this.plotInfos.length == 0) {
-			this.initLabels(this.timeplot.regularGrid());
-			return;
-		}
-		this.timeGeometry.extendedDataSource = this.tds;
-		this.tds.initialize(this.dataSources, this.eventSources, timeObjects, granularity, this.options.timeUnit, this.gui.timeplotDiv.offsetWidth);
-		this.gui.setTimeUnitDropdown(this.tds.availableUnits);
-		this.gui.timeUnitDropdown.setEntry(this.tds.getUnitIndex());
-		var plots = this.timeplot._plots;
-		for (var i = 0; i < plots.length; i++) {
-			plots[i].pins = [];
-			plots[i].style = this.style;
-			for (var j = 0; j < this.tds.getSliceNumber(); j++) {
-				plots[i].pins.push({
-					height : 0,
-					count : 0
-				});
-			}
-		}
-		/*
-		 var levels = Math.round( (this.tds.timeSlices.length-3)/2 );
-		 if( GeoTemConfig.timeZoom ){
-		 this.zoomSlider.setMaxAndLevels(levels,levels);
-		 }
-		 */
-		this.timeplot.repaint();
-		this.timeplot._resizeCanvas();
-		// set maximum number of slider steps
-		var slices = this.tds.timeSlices.length;
-		var numSlices = Math.floor(slices / this.canvas.width * this.canvas.height + 0.5);
-
-		this.initLabels([]);
-		this.initOverview();
-		this.gui.updateTimeQuantity(this.count);
-
-	},
-
-	setTimeUnit : function(unit) {
-		this.clearTimeplot();
-		this.reset();
-		this.tds.setTimeUnit(unit);
-		var plots = this.timeplot._plots;
-		for (var i = 0; i < plots.length; i++) {
-			plots[i].pins = [];
-			plots[i].style = this.style;
-			for (var j = 0; j < this.tds.getSliceNumber(); j++) {
-				plots[i].pins.push({
-					height : 0,
-					count : 0
-				});
-			}
-		}
-		this.initLabels([]);
-	},
-
-	/**
-	 * initializes the timeplot for the Spatio Temporal Interface.
-	 * all elements (including their events) that are needed for user interaction are instantiated here, the slider element as well
-	 */
-	initialize : function() {
-
-		this.status = 0;
-		this.selection = new Selection();
-		this.paused = true;
-		this.dataSources = new Array();
-		this.plotInfos = new Array();
-		this.eventSources = new Array();
-		this.timeGeometry = new Timeplot.DefaultTimeGeometry({
-			gridColor : "#000000",
-			axisLabelsPlacement : "top"
-		});
-		this.style = 'graph';
-		this.timeGeometry._hideLabels = true;
-		this.timeGeometry._granularity = 0;
-		this.valueGeometry = new Timeplot.LogarithmicValueGeometry({
-			min : 0
-		});
-		this.valueGeometry.actLinear();
-
-		var plot = this;
-
-		this.timeplot = Timeplot.create(this.gui.timeplotDiv, this.plotInfos);
-		this.tds = new TimeDataSource(this.options);
-
-		this.canvas = this.timeplot.getCanvas();
-
-		this.leftFlagPole = this.timeplot.putDiv("leftflagpole", "timeplot-dayflag-pole");
-		this.rightFlagPole = this.timeplot.putDiv("rightflagpole", "timeplot-dayflag-pole");
-		SimileAjax.Graphics.setOpacity(this.leftFlagPole, 50);
-		SimileAjax.Graphics.setOpacity(this.rightFlagPole, 50);
-
-		this.rangeBox = this.timeplot.putDiv("rangebox", "range-box");
-		this.rangeBox.style.backgroundColor = plot.options.rangeBoxColor;
-		this.rangeBox.style.border = plot.options.rangeBorder;
-
-		this.leftHandle = document.createElement("div");
-		this.rightHandle = document.createElement("div");
-		this.gui.plotWindow.appendChild(this.leftHandle);
-		this.gui.plotWindow.appendChild(this.rightHandle);
-		this.leftHandle.title = GeoTemConfig.getString('leftHandle');
-		this.rightHandle.title = GeoTemConfig.getString('rightHandle');
-
-		this.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")";
-		this.leftHandle.setAttribute('class', 'plotHandle plotHandleIcon');
-		this.rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")";
-		this.rightHandle.setAttribute('class', 'plotHandle plotHandleIcon');
-
-		this.poles = this.timeplot.putDiv("poles", "pole");
-		this.timeplot.placeDiv(this.poles, {
-			left : 0,
-			bottom : 0,
-			width : this.canvas.width,
-			height : this.canvas.height,
-			display : "block"
-		});
-		this.poles.appendChild(document.createElement("canvas"));
-
-		this.filterBar = new FilterBar(this, this.gui.filterOptions);
-
-		var plot = this;
-
-		this.dragButton = document.createElement("div");
-		this.dragButton.title = GeoTemConfig.getString('dragTimeRange');
-		this.cancelButton = document.createElement("div");
-		this.cancelButton.title = GeoTemConfig.getString('clearSelection');
-		this.cancelButton.onclick = function() {
-			plot.deselection();
-		}
-
-		this.toolbar = document.createElement("div");
-		this.toolbar.setAttribute('class', 'plotToolbar');
-		this.toolbar.style.borderTop = plot.options.rangeBorder;
-		this.toolbar.style.textAlign = "center";
-		this.gui.plotWindow.appendChild(this.toolbar);
-
-		this.toolbarAbsoluteDiv = document.createElement("div");
-		this.toolbarAbsoluteDiv.setAttribute('class', 'absoluteToolbar');
-		this.toolbar.appendChild(this.toolbarAbsoluteDiv);
-
-		this.dragButton.setAttribute('class', 'dragTimeRangeAlt');
-		this.dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")";
-		//        	this.zoomButton.setAttribute('class','zoomRangeAlt');
-		this.cancelButton.setAttribute('class', 'cancelRangeAlt');
-		this.toolbarAbsoluteDiv.appendChild(this.dragButton);
-		this.toolbarAbsoluteDiv.style.width = this.dragButton.offsetWidth + "px";
-		//	        this.gui.plotWindow.appendChild(this.zoomButton);
-		this.gui.plotWindow.appendChild(this.cancelButton);
-
-		this.overview = document.createElement("div");
-		this.overview.setAttribute('class', 'timeOverview');
-		this.gui.plotWindow.appendChild(this.overview);
-
-		var mousedown = false;
-		this.shift = function(shift) {
-			if (!mousedown) {
-				return;
-			}
-			if (plot.tds.setShift(shift)) {
-				plot.redrawPlot();
-			}
-			setTimeout(function() {
-				plot.shift(shift);
-			}, 200);
-		}
-		var shiftPressed = function(shift) {
-			mousedown = true;
-			document.onmouseup = function() {
-				mousedown = false;
-				document.onmouseup = null;
-			}
-			plot.shift(shift);
-		}
-
-		this.shiftLeft = document.createElement("div");
-		this.shiftLeft.setAttribute('class', 'shiftLeft');
-		this.gui.plotWindow.appendChild(this.shiftLeft);
-		this.shiftLeft.onmousedown = function() {
-			shiftPressed(1);
-		}
-
-		this.shiftRight = document.createElement("div");
-		this.shiftRight.setAttribute('class', 'shiftRight');
-		this.gui.plotWindow.appendChild(this.shiftRight);
-		this.shiftRight.onmousedown = function() {
-			shiftPressed(-1);
-		}
-
-		this.plotLabels = document.createElement("div");
-		this.plotLabels.setAttribute('class', 'plotLabels');
-		this.gui.plotWindow.appendChild(this.plotLabels);
-
-		this.initLabels(this.timeplot.regularGrid());
-
-		//Finds the time corresponding to the position x on the timeplot
-		var getCorrelatedTime = function(x) {
-			if (x >= plot.canvas.width)
-				x = plot.canvas.width;
-			if (isNaN(x) || x < 0)
-				x = 0;
-			var t = plot.timeGeometry.fromScreen(x);
-			if (t == 0)
-				return;
-			return plot.dataSources[0].getClosestValidTime(t);
-		}
-		//Finds the position corresponding to the time t on the timeplot
-		var getCorrelatedPosition = function(t) {
-			var x = plot.timeGeometry.toScreen(t);
-			if (x >= plot.canvas.width)
-				x = plot.canvas.width;
-			if (isNaN(x) || x < 0)
-				x = 0;
-			return x;
-		}
-		//Maps the 2 positions in the right order to left and right bound of the chosen timeRange
-		var mapPositions = function(pos1, pos2) {
-			if (pos1 > pos2) {
-				plot.leftFlagPos = pos2;
-				plot.rightFlagPos = pos1;
-			} else {
-				plot.leftFlagPos = pos1;
-				plot.rightFlagPos = pos2;
-			}
-			plot.leftFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.leftFlagPos));
-			plot.rightFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.rightFlagPos));
-		}
-		//Sets the divs corresponding to the actual chosen timeRange
-		var setRangeDivs = function() {
-			plot.leftFlagPole.style.visibility = "visible";
-			plot.rightFlagPole.style.visibility = "visible";
-			plot.rangeBox.style.visibility = "visible";
-			plot.timeplot.placeDiv(plot.leftFlagPole, {
-				left : plot.leftFlagPos,
-				bottom : 0,
-				height : plot.canvas.height,
-				display : "block"
-			});
-			plot.timeplot.placeDiv(plot.rightFlagPole, {
-				left : plot.rightFlagPos,
-				bottom : 0,
-				height : plot.canvas.height,
-				display : "block"
-			});
-			var boxWidth = plot.rightFlagPos - plot.leftFlagPos;
-			if (plot.popup) {
-				plot.popupClickDiv.style.visibility = "visible";
-				plot.timeplot.placeDiv(plot.popupClickDiv, {
-					left : plot.leftFlagPos,
-					width : boxWidth + 1,
-					height : plot.canvas.height,
-					display : "block"
-				});
-			}
-			plot.timeplot.placeDiv(plot.rangeBox, {
-				left : plot.leftFlagPos,
-				width : boxWidth + 1,
-				height : plot.canvas.height,
-				display : "block"
-			});
-			var plots = plot.timeplot._plots;
-			for ( i = 0; i < plots.length; i++) {
-				plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i));
-				plots[i].opacityPlot.style.visibility = "visible";
-			}
-			var unit = plot.tds.unit;
-
-			var top = plot.gui.plotContainer.offsetTop;
-			var left = plot.gui.plotContainer.offsetLeft;
-			var leftPos = plot.leftFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft;
-			var rightPos = plot.rightFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft;
-			var rW = rightPos - leftPos;
-			var pW = plot.canvas.width;
-			var pL = plot.timeplot.getElement().offsetLeft;
-
-			var handleTop = top + Math.floor(plot.gui.timeplotDiv.offsetHeight / 2 - plot.leftHandle.offsetHeight / 2);
-			plot.leftHandle.style.visibility = "visible";
-			plot.rightHandle.style.visibility = "visible";
-			plot.leftHandle.style.left = (leftPos - plot.leftHandle.offsetWidth / 2) + "px";
-			plot.rightHandle.style.left = (rightPos - plot.rightHandle.offsetWidth + 1 + plot.rightHandle.offsetWidth / 2) + "px";
-			plot.leftHandle.style.top = handleTop + "px";
-			plot.rightHandle.style.top = handleTop + "px";
-			if (rightPos == leftPos) {
-				plot.rightHandle.style.visibility = "hidden";
-				plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "mergedHandle.png" + ")";
-			} else {
-				plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")";
-			}
-			plot.cancelButton.style.visibility = "visible";
-			plot.cancelButton.style.top = top + "px";
-
-			if (rW > plot.cancelButton.offsetWidth) {
-				plot.cancelButton.style.left = (left + rightPos - plot.cancelButton.offsetWidth) + "px";
-			} else {
-				plot.cancelButton.style.left = (left + rightPos) + "px";
-			}
-			var tW = plot.toolbarAbsoluteDiv.offsetWidth;
-			if (rW >= tW) {
-				plot.toolbar.style.left = leftPos + "px";
-				plot.toolbar.style.width = (rW + 1) + "px";
-				plot.toolbarAbsoluteDiv.style.left = ((rW - tW) / 2) + "px";
-			} else {
-				plot.toolbar.style.left = (pL + plot.leftFlagPos * (pW - tW) / (pW - rW)) + "px";
-				plot.toolbar.style.width = (tW + 2) + "px";
-				plot.toolbarAbsoluteDiv.style.left = "0px";
-			}
-			plot.toolbar.style.top = (top + plot.timeplot.getElement().offsetHeight) + "px";
-			plot.toolbar.style.visibility = "visible";
-			plot.toolbarAbsoluteDiv.style.visibility = "visible";
-
-		}
-		var getAbsoluteLeft = function(div) {
-			var left = 0;
-			while (div) {
-				left += div.offsetLeft;
-				div = div.offsetParent;
-			}
-			return left;
-		}
-		var timeplotLeft = getAbsoluteLeft(plot.timeplot.getElement());
-
-		var checkPolesForStyle = function(x) {
-			if (plot.style == 'bars' && plot.leftFlagTime == plot.rightFlagTime) {
-				var index = plot.tds.getSliceIndex(plot.leftFlagTime);
-				var time1 = plot.leftFlagTime;
-				var pos1 = plot.leftFlagPos;
-				var time2, pos2;
-				if (index == 0) {
-					time2 = plot.tds.getSliceTime(index + 1);
-				} else if (index == plot.tds.getSliceNumber() - 1) {
-					time2 = plot.tds.getSliceTime(index - 1);
-				} else {
-					if (x < plot.leftFlagPos) {
-						time2 = plot.tds.getSliceTime(index - 1);
-					} else {
-						time2 = plot.tds.getSliceTime(index + 1);
-					}
-				}
-				pos2 = plot.timeGeometry.toScreen(time2);
-				mapPositions(pos1, pos2, time1, time2);
-			}
-		}
-		var startX, startY, multiplier;
-
-		// mousemove function that causes moving selection of objects and toolbar divs
-		var moveToolbar = function(start, actual) {
-			var pixelShift = actual - start;
-			if (plot.status == 2) {
-				var newTime = getCorrelatedTime(startX + pixelShift);
-				if (newTime == plot.mouseTempTime) {
-					return;
-				}
-				plot.mouseTempTime = newTime;
-				plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime);
-				mapPositions(plot.mouseDownPos, plot.mouseTempPos);
-			} else if (plot.status == 3) {
-				pixelShift *= multiplier;
-				var plotPos = actual - timeplotLeft;
-				if (plotPos <= plot.canvas.width / 2) {
-					var newTime = getCorrelatedTime(startX + pixelShift);
-					if (newTime == plot.leftFlagTime) {
-						return;
-					}
-					plot.leftFlagTime = newTime;
-					var diff = plot.leftFlagPos;
-					plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime);
-					diff -= plot.leftFlagPos;
-					plot.rightFlagTime = getCorrelatedTime(plot.rightFlagPos - diff);
-					plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime);
-				} else {
-					var newTime = getCorrelatedTime(startY + pixelShift);
-					if (newTime == plot.rightFlagTime) {
-						return;
-					}
-					plot.rightFlagTime = newTime;
-					var diff = plot.rightFlagPos;
-					plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime);
-					diff -= plot.rightFlagPos;
-					plot.leftFlagTime = getCorrelatedTime(plot.leftFlagPos - diff);
-					plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime);
-				}
-			}
-			checkPolesForStyle(actual - timeplotLeft);
-			setRangeDivs();
-			plot.timeSelection();
-		}
-		// fakes user interaction mouse move
-		var playIt = function(start, actual, reset) {
-			if (!plot.paused) {
-				var pixel = plot.canvas.width / (plot.tds.timeSlices.length - 1 ) / 5;
-				var wait = 20 * pixel;
-				if (reset) {
-					actual = 0;
-				}
-				moveToolbar(start, actual);
-				if (plot.rightFlagPos >= plot.canvas.width) {
-					reset = true;
-					wait = 1000;
-				} else {
-					reset = false;
-				}
-				setTimeout(function() {
-					playIt(start, actual + pixel, reset)
-				}, wait);
-			}
-		}
-		var setMultiplier = function() {
-			var rangeWidth = plot.rightFlagPos - plot.leftFlagPos;
-			var toolbarWidth = plot.toolbarAbsoluteDiv.offsetWidth;
-			var plotWidth = plot.canvas.width;
-			if (rangeWidth < toolbarWidth) {
-				multiplier = (plotWidth - rangeWidth) / (plotWidth - toolbarWidth);
-			} else {
-				multiplier = 1;
-			}
-		}
-		/**
-		 * starts the animation
-		 */
-		this.play = function() {
-			if (this.leftFlagPos == null) {
-				return;
-			}
-			plot.paused = false;
-			plot.gui.updateAnimationButtons(2);
-			plot.status = 3;
-			setMultiplier();
-			startX = plot.leftFlagPos;
-			startY = plot.rightFlagPos;
-			var position = Math.round(plot.leftFlagPos);
-			playIt(position, position + 1, false);
-		}
-		/**
-		 * stops the animation
-		 */
-		this.stop = function() {
-			plot.paused = true;
-			plot.status = 0;
-			plot.gui.updateAnimationButtons(1);
-		}
-		// triggers the mousemove function to move the range and toolbar
-		var toolbarEvent = function(evt) {
-			var left = GeoTemConfig.getMousePosition(evt).left;
-			document.onmousemove = function(evt) {
-				moveToolbar(left, GeoTemConfig.getMousePosition(evt).left);
-				if (plot.popup) {
-					plot.popup.reset();
-				}
-			}
-		}
-		var initializeLeft = function() {
-			plot.mouseDownTime = plot.rightFlagTime;
-			plot.mouseTempTime = plot.leftFlagTime;
-			plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime);
-			startX = plot.leftFlagPos;
-		}
-		var initializeRight = function() {
-			plot.mouseDownTime = plot.leftFlagTime;
-			plot.mouseTempTime = plot.rightFlagTime;
-			plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime);
-			startX = plot.rightFlagPos;
-		}
-		var initializeDrag = function() {
-			startX = plot.leftFlagPos;
-			startY = plot.rightFlagPos;
-			setMultiplier();
-		}
-		var checkBorders = function() {
-			if (plot.style == 'bars' && plot.mouseUpTime == plot.mouseDownTime) {
-				var index = plot.tds.getSliceIndex(plot.mouseUpTime);
-				if (index == 0) {
-					plot.mouseUpTime = plot.tds.getSliceTime(index + 1);
-				} else if (index == plot.tds.getSliceNumber() - 1) {
-					plot.mouseUpTime = plot.tds.getSliceTime(index - 1);
-				} else {
-					if (plot.x < plot.leftFlagPos) {
-						plot.mouseUpTime = plot.tds.getSliceTime(index - 1);
-					} else {
-						plot.mouseUpTime = plot.tds.getSliceTime(index + 1);
-					}
-				}
-			}
-		}
-		// handles mousedown on left handle
-		this.leftHandle.onmousedown = function(evt) {
-			if (plot.status != 2) {
-
-				initializeLeft();
-				plot.status = 2;
-				toolbarEvent(evt);
-				document.onmouseup = function() {
-					document.onmousemove = null;
-					document.onmouseup = null;
-					plot.stop();
-				}
-			}
-		}
-		// handles mousedown on right handle
-		this.rightHandle.onmousedown = function(evt) {
-			if (plot.status != 2) {
-				initializeRight();
-				plot.status = 2;
-				toolbarEvent(evt);
-				document.onmouseup = function() {
-					document.onmousemove = null;
-					document.onmouseup = null;
-					plot.stop();
-				}
-			}
-		}
-		// handles mousedown on drag button
-		this.dragButton.onmousedown = function(evt) {
-			if (plot.status != 3) {
-				plot.status = 3;
-				initializeDrag();
-				toolbarEvent(evt);
-				document.onmouseup = function() {
-					document.onmousemove = null;
-					document.onmouseup = null;
-					plot.stop();
-				}
-			}
-		}
-		// handles mousedown-Event on timeplot
-		var mouseDownHandler = function(elmt, evt, target) {
-			if (plot.dataSources.length > 0) {
-
-				plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
-				if (plot.status == 0) {
-					var time = getCorrelatedTime(plot.x);
-					if (plot.leftFlagPos != null && plot.popup && time >= plot.leftFlagTime && time <= plot.rightFlagTime) {
-						var x = plot.leftFlagPos + (plot.rightFlagPos - plot.leftFlagPos) / 2;
-						var elements = [];
-						for (var i = 0; i < plot.dataSources.length; i++) {
-							elements.push([]);
-						}
-						for (var i = 0; i < plot.selectedObjects.length; i++) {
-							if (plot.selectedObjects[i].value == 1) {
-								for (var j = 0; j < plot.selectedObjects[i].objects.length; j++) {
-									elements[j] = elements[j].concat(plot.selectedObjects[i].objects[j]);
-								}
-							}
-						}
-						var labels = [];
-						for (var i = 0; i < elements.length; i++) {
-							if (elements[i].length == 0) {
-								continue;
-							}
-							var c = GeoTemConfig.getColor(i);
-							var color = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')';
-							var div = document.createElement("div");
-							div.setAttribute('class', 'tagCloudItem');
-							div.style.color = color;
-							var label = {
-								div : div,
-								elements : elements[i]
-							};
-							var weight = 0;
-							for (j in elements[i] ) {
-								weight += elements[i][j].weight;
-							}
-							var fs = 2 * weight / 1000;
-							if (fs > 2) {
-								fs = 2;
-							}
-							div.style.fontSize = (1 + fs) + "em";
-							div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + c.hex;
-							if (weight == 1) {
-								div.innerHTML = weight + " object";
-							} else {
-								div.innerHTML = weight + " objects";
-							}
-							var appendMouseFunctions = function(label, div, color) {
-								div.onclick = function() {
-									plot.popup.showLabelContent(label);
-									div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color;
-								}
-								div.onmouseover = function() {
-									div.style.textShadow = "0 -1px " + color + ", 1px 0 " + color + ", 0 1px " + color + ", -1px 0 " + color;
-								}
-								div.onmouseout = function() {
-									div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color;
-								}
-							}
-							appendMouseFunctions(label, div, c.hex);
-							labels.push(label);
-						}
-						if (labels.length > 0) {
-							plot.popup.createPopup(x + 20, 0, labels);
-						}
-					} else {
-						plot.deselection();
-						plot.status = 1;
-						plot.mouseDownTime = time;
-						plot.mouseTempTime = plot.mouseDownTime;
-						plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime);
-						mapPositions(plot.mouseDownPos, plot.mouseDownPos, plot.mouseDownTime, plot.mouseDownTime);
-						// handles mouseup-Event on timeplot
-						document.onmouseup = function() {
-							if (plot.status == 1) {
-								plot.mouseUpTime = plot.mouseTempTime;
-								plot.mouseUpPos = plot.timeGeometry.toScreen(plot.mouseUpTime);
-								mapPositions(plot.mouseDownPos, plot.mouseUpPos, plot.mouseDownTime, plot.mouseUpTime);
-								checkPolesForStyle(plot.x);
-								setRangeDivs();
-								plot.timeSelection();
-								plot.gui.updateAnimationButtons(1);
-								document.onmouseup = null;
-								plot.status = 0;
-							}
-						}
-					}
-				}
-			}
-		}
-		// handles mousemove-Event on timeplot
-		var mouseMoveHandler = function(elmt, evt, target) {
-			if (plot.dataSources.length > 0) {
-				plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
-				if (plot.status == 1) {
-					plot.mouseTempTime = getCorrelatedTime(plot.x);
-					plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime);
-					mapPositions(plot.mouseDownPos, plot.mouseTempPos, plot.mouseDownTime, plot.mouseTempTime);
-					checkPolesForStyle(plot.x);
-					setRangeDivs();
-				}
-			}
-		}
-		// handles mouseout-Event on timeplot
-		var mouseOutHandler = function(elmt, evt, target) {
-			if (plot.dataSources.length > 0) {
-				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
-				var y = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).y);
-				if (x > plot.canvas.width - 2 || isNaN(x) || x < 2) {
-					plot.timeHighlight(true);
-					plot.highlightedSlice = undefined;
-				} else if (y > plot.canvas.height - 2 || isNaN(y) || y < 2) {
-					plot.timeHighlight(true);
-					plot.highlightedSlice = undefined;
-				}
-			}
-		}
-		// handles mouse(h)over-Event on timeplot
-		var mouseHoverHandler = function(elmt, evt, target) {
-			if (plot.dataSources.length > 0) {
-				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
-				var time = getCorrelatedTime(x);
-				if (time == undefined) {
-					return;
-				}
-				var highlightSlice;
-				var slices = plot.tds.timeSlices;
-				var index = plot.tds.getSliceIndex(time);
-				if (plot.style == 'graph') {
-					highlightSlice = slices[index];
-				}
-				if (plot.style == 'bars') {
-					var pos = plot.timeGeometry.toScreen(time);
-					if (x < pos && index > 0) {
-						highlightSlice = slices[index - 1];
-					} else {
-						highlightSlice = slices[index];
-					}
-				}
-				if (plot.highlightedSlice == undefined || plot.highlightedSlice != highlightSlice) {
-					plot.highlightedSlice = highlightSlice;
-					plot.timeHighlight(false);
-				}
-			}
-		}
-
-		this.redrawPlot = function() {
-			plot.clearTimeplot();
-			plot.tds.reset(this.timeGeometry);
-			plot.timeplot._prepareCanvas();
-			plot.timeplot.repaint();
-			if (plot.leftFlagPos != null) {
-				plot.leftFlagPos = getCorrelatedPosition(plot.leftFlagTime);
-				plot.rightFlagPos = getCorrelatedPosition(plot.rightFlagTime);
-				setRangeDivs();
-			} else {
-				plot.displayOverlay();
-			}
-			plot.initLabels([]);
-			plot.updateOverview();
-		}
-
-		this.resetOpacityPlots = function() {
-			var plots = plot.timeplot._plots;
-			for ( var i = 0; i < plots.length; i++) {
-				plots[i]._opacityCanvas.width = this.canvas.width;
-				plots[i]._opacityCanvas.height = this.canvas.height;
-				if( plot.leftFlagTime != null ){
-					plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i));
-				}
-			}
-		}
-
-		/**
-		 * handles zoom of the timeplot
-		 * @param {int} delta the change of zoom
-		 * @param {Date} time a time that corresponds to a slice, that was clicked
-		 */
-		/*
-		this.zoom = function(delta,time){
-		if( this.eventSources.length == 0 ){
-		if( GeoTemConfig.timeZoom ){
-		this.zoomSlider.setValue(0);
-		}
-		return false;
-		}
-		if( time == null ){
-		time = getCorrelatedTime(this.canvas.width/2);
-		}
-		if( this.tds.setZoom(delta,time,this.leftFlagTime,this.rightFlagTime) ){
-		this.redrawPlot();
-		}
-		if( GeoTemConfig.timeZoom ){
-		this.zoomSlider.setValue(this.tds.getZoom());
-		}
-		return true;
-		}
-		*/
-
-		// handles mousewheel event on the timeplot
-		var mouseWheelHandler = function(elmt, evt, target) {
-			if (evt.preventDefault) {
-				evt.preventDefault();
-			}
-			if (plot.dataSources.length == 0) {
-				return;
-			}
-			var delta = 0;
-			if (!evt)
-				evt = window.event;
-			if (evt.wheelDelta) {
-				delta = evt.wheelDelta / 120;
-				if (window.opera)
-					delta = -delta;
-			} else if (evt.detail) {
-				delta = -evt.detail / 3;
-			}
-			if (delta) {
-				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
-				var time = getCorrelatedTime(x);
-				plot.zoom(delta, time);
-			}
-		}
-		var timeplotElement = this.timeplot.getElement();
-		SimileAjax.DOM.registerEvent(timeplotElement, "mousedown", mouseDownHandler);
-		SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler);
-		SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseHoverHandler);
-		SimileAjax.DOM.registerEvent(timeplotElement, "mouseout", mouseOutHandler);
-		if (GeoTemConfig.mouseWheelZoom) {
-			//SimileAjax.DOM.registerEvent(timeplotElement, "mousewheel", mouseWheelHandler);
-		}
-
-		this.gui.setHeight();
-
-	},
-
-	resetOverlay : function() {
-		this.poles.style.visibility = "hidden";
-		var plots = this.timeplot._plots;
-		for (var i = 0; i < plots.length; i++) {
-			for (var j = 0; j < plots[i].pins.length; j++) {
-				plots[i].pins[j] = {
-					height : 0,
-					count : 0
-				};
-			}
-		}
-	},
-
-	/**
-	 * resets the timeplot to non selection status
-	 */
-	reset : function() {
-
-		this.leftFlagPole.style.visibility = "hidden";
-		this.rightFlagPole.style.visibility = "hidden";
-		this.rangeBox.style.visibility = "hidden";
-		this.leftHandle.style.visibility = "hidden";
-		this.rightHandle.style.visibility = "hidden";
-		this.toolbar.style.visibility = "hidden";
-		this.toolbarAbsoluteDiv.style.visibility = "hidden";
-		this.cancelButton.style.visibility = "hidden";
-
-		var plots = this.timeplot._plots;
-		for (var i = 0; i < plots.length; i++) {
-			plots[i].opacityPlot.style.visibility = "hidden";
-		}
-		this.resetOverlay();
-		this.filterBar.reset(false);
-
-		var slices = this.tds.timeSlices;
-		if (slices != undefined) {
-			for (var i = 0; i < slices.length; i++) {
-				slices[i].reset();
-			}
-		}
-
-		this.status = 0;
-		this.stop();
-		this.gui.updateAnimationButtons(0);
-
-		this.leftFlagPos = null;
-		this.leftFlagTime = null;
-		this.rightFlagPos = null;
-		this.rightFlagTime = null;
-
-		this.mouseDownTime = null;
-		this.mouseUpTime = null;
-		this.mouseTempTime = null;
-
-		this.mouseDownPos = null;
-		this.mouseUpPos = null;
-		this.mouseTempPos = null;
-
-		if (this.popup) {
-			this.popup.reset();
-			this.popupClickDiv.style.visibility = "hidden";
-		}
-
-	},
-
-	/**
-	 * sets a pole on the timeplot
-	 * @param {Date} time the time of the specific timeslice
-	 * @param {int[]} the number of selected elements per dataset
-	 */
-	displayOverlay : function() {
-		this.poles.style.visibility = "visible";
-		var cv = this.poles.getElementsByTagName("canvas")[0];
-		cv.width = this.canvas.width;
-		cv.height = this.canvas.height;
-		if (!cv.getContext && G_vmlCanvasManager) {
-			cv = G_vmlCanvasManager.initElement(cv);
-		}
-		var ctx = cv.getContext('2d');
-		ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
-		var plots = this.timeplot._plots;
-		var slices = this.tds.timeSlices;
-		for (var i = 0; i < slices.length; i++) {
-			if (this.style == 'bars' && i + 1 == slices.length) {
-				return;
-			}
-			if (slices[i].overlay() == 0) {
-				continue;
-			}
-			var projStacks = slices[i].projStacks;
-			var time = slices[i].date;
-			var pos;
-			if (this.style == 'graph') {
-				pos = this.timeGeometry.toScreen(time);
-			} else if (this.style == 'bars') {
-				var x1 = this.timeGeometry.toScreen(time);
-				var x2 = this.timeGeometry.toScreen(slices[i + 1].date);
-				pos = (x1 + x2 ) / 2;
-			}
-			var heights = [];
-			var h = 0;
-			for (var j = 0; j < projStacks.length; j++) {
-				var data = plots[j]._dataSource.getData();
-				for (var k = 0; k < data.times.length; k++) {
-					if (data.times[k].getTime() == time.getTime()) {
-						var height = plots[j]._valueGeometry.toScreen(plots[j]._dataSource.getData().values[k]) * projStacks[j].overlay / projStacks[j].value;
-						heights.push(height);
-						plots[j].pins[i] = {
-							height : height,
-							count : projStacks[j].overlay
-						};
-						if (height > h) {
-							h = height;
-						}
-						break;
-					}
-				}
-			}
-			ctx.fillStyle = "rgb(102,102,102)";
-			ctx.beginPath();
-			ctx.rect(pos - 1, this.canvas.height - h, 2, h);
-			ctx.fill();
-			for (var j = 0; j < heights.length; j++) {
-				if (heights[j] > 0) {
-					var color = GeoTemConfig.getColor(j);
-					ctx.fillStyle = "rgba(" + color.r1 + "," + color.g1 + "," + color.b1 + ",0.6)";
-					ctx.beginPath();
-					ctx.arc(pos, this.canvas.height - heights[j], 2.5, 0, Math.PI * 2, true);
-					ctx.closePath();
-					ctx.fill();
-				}
-			}
-		}
-	},
-
-	/**
-	 * updates the timeplot by displaying place poles, after a selection had been executed in another widget
-	 */
-	highlightChanged : function(timeObjects) {
-		if( !GeoTemConfig.highlightEvents ){
-			return;
-		}
-		this.resetOverlay();
-		if (this.selection.valid()) {
-			if (!this.selection.equal(this)) {
-				this.tds.setOverlay(GeoTemConfig.mergeObjects(timeObjects, this.selection.getObjects(this)));
-			} else {
-				this.tds.setOverlay(timeObjects);
-			}
-		} else {
-			this.tds.setOverlay(timeObjects);
-		}
-		this.displayOverlay();
-	},
-
-	/**
-	 * updates the timeplot by displaying place poles, after a selection had been executed in another widget
-	 */
-	selectionChanged : function(selection) {
-		if( !GeoTemConfig.selectionEvents ){
-			return;
-		}
-		this.reset();
-		this.selection = selection;
-		this.tds.setOverlay(selection.objects);
-		this.displayOverlay();
-	},
-
-	/**
-	 * returns the approximate left position of a slice inside the overview representation
-	 * @param {Date} time time of the slice
-	 */
-	getOverviewLeft : function(time) {
-		var w = this.overview.offsetWidth;
-		var s = this.tds.earliest().getTime();
-		var e = this.tds.latest().getTime();
-		var t = time.getTime();
-		return Math.round(w * (t - s) / (e - s));
-	},
-
-	/**
-	 * visualizes the overview div (shows viewable part of zoomed timeplot)
-	 */
-	initOverview : function() {
-		var labels = this.timeGeometry._grid;
-		if (labels.length == 0) {
-			var plot = this;
-			setTimeout(function() {
-				plot.initOverview();
-			}, 10);
-			return;
-		}
-
-		this.overview.style.width = this.canvas.width + "px";
-		var left = this.gui.timeplotDiv.offsetLeft;
-		this.overview.innerHTML = "";
-		this.overview.style.left = left + "px";
-
-		this.overviewRange = document.createElement("div");
-		this.overviewRange.setAttribute('class', 'overviewRange');
-		this.overview.appendChild(this.overviewRange);
-
-		for (var i = 0; i < labels.length; i++) {
-			var label = document.createElement("div");
-			label.setAttribute('class', 'overviewLabel');
-			label.innerHTML = labels[i].label;
-			label.style.left = Math.floor(labels[i].x) + "px";
-			this.overview.appendChild(label);
-		}
-
-		this.updateOverview();
-	},
-
-	/**
-	 * visualizes the labels of the timeplot
-	 */
-	initLabels : function(labels) {
-		if (labels.length == 0) {
-			labels = this.timeGeometry._grid;
-			if (labels.length == 0) {
-				var plot = this;
-				setTimeout(function() {
-					plot.initLabels([]);
-				}, 10);
-				return;
-			}
-		}
-		this.plotLabels.style.width = this.canvas.width + "px";
-		var left = this.gui.timeplotDiv.offsetLeft;
-		this.plotLabels.style.left = left + "px";
-		this.plotLabels.innerHTML = "";
-		for (var i = 0; i < labels.length; i++) {
-			var label = document.createElement("div");
-			label.setAttribute('class', 'plotLabel');
-			label.innerHTML = labels[i].label;
-			label.style.left = Math.floor(labels[i].x) + "px";
-			this.plotLabels.appendChild(label);
-		}
-	},
-
-	/**
-	 * updates the overview div
-	 */
-	updateOverview : function() {
-		if (this.tds.getZoom() > 0) {
-			this.plotLabels.style.visibility = "hidden";
-			this.timeGeometry._hideLabels = false;
-			this.overview.style.visibility = "visible";
-			this.shiftLeft.style.visibility = "visible";
-			this.shiftRight.style.visibility = "visible";
-			var left = this.getOverviewLeft(this.tds.timeSlices[this.tds.leftSlice].date);
-			var right = this.getOverviewLeft(this.tds.timeSlices[this.tds.rightSlice].date);
-			this.overviewRange.style.left = left + "px";
-			this.overviewRange.style.width = (right - left) + "px";
-		} else {
-			this.timeGeometry._hideLabels = true;
-			this.plotLabels.style.visibility = "visible";
-			this.overview.style.visibility = "hidden";
-			this.shiftLeft.style.visibility = "hidden";
-			this.shiftRight.style.visibility = "hidden";
-		}
-	},
-
-	/**
-	 * returns the time slices which are created by the extended data source
-	 */
-	getSlices : function() {
-		return this.tds.timeSlices;
-	},
-
-	timeSelection : function() {
-		var slices = this.tds.timeSlices;
-		var ls, rs;
-		for (var i = 0; i < slices.length; i++) {
-			if (slices[i].date.getTime() == this.leftFlagTime.getTime())
-				ls = i;
-			if (slices[i].date.getTime() == this.rightFlagTime.getTime()) {
-				if (this.style == 'graph') {
-					rs = i;
-				}
-				if (this.style == 'bars') {
-					rs = i - 1;
-				}
-			}
-		}
-		var selectedObjects = [];
-		for (var i = 0; i < GeoTemConfig.datasets.length; i++) {
-			selectedObjects.push([]);
-		}
-		for (var i = 0; i < slices.length; i++) {
-			if (i >= ls && i <= rs) {
-				for (var j in slices[i].stacks ) {
-					selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements);
-				}
-			}
-		}
-		this.selection = new Selection(selectedObjects, this);
-		this.core.triggerSelection(this.selection);
-		this.filterBar.reset(true);
-	},
-
-	deselection : function() {
-		this.reset();
-		this.selection = new Selection();
-		this.core.triggerSelection(this.selection);
-	},
-
-	filtering : function() {
-		for (var i = 0; i < this.datasets.length; i++) {
-			this.datasets[i].objects = this.selection.objects[i];
-		}
-		this.core.triggerRefining(this.datasets);
-	},
-
-	inverseFiltering : function() {
-		var slices = this.tds.timeSlices;
-		var ls, rs;
-		for (var i = 0; i < slices.length; i++) {
-			if (slices[i].date.getTime() == this.leftFlagTime.getTime())
-				ls = i;
-			if (slices[i].date.getTime() == this.rightFlagTime.getTime()) {
-				if (this.style == 'graph') {
-					rs = i;
-				}
-				if (this.style == 'bars') {
-					rs = i - 1;
-				}
-			}
-		}
-		var selectedObjects = [];
-		for (var i = 0; i < GeoTemConfig.datasets.length; i++) {
-			selectedObjects.push([]);
-		}
-		for (var i = 0; i < slices.length; i++) {
-			if (i >= ls && i <= rs) {
-				continue;
-			}
-			for (var j in slices[i].stacks ) {
-				selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements);
-			}
-		}
-		this.selection = new Selection(selectedObjects, this);
-		this.filtering();
-	},
-
-	timeHighlight : function(undo) {
-		if (this.status == 0) {
-			var s = this.highlightedSlice;
-			var timeObjects = [];
-			for (var i = 0; i < this.tds.size(); i++) {
-				timeObjects.push([]);
-			}
-			var add = true;
-			if (this.leftFlagTime != null) {
-				if (this.style == 'graph' && s.date >= this.leftFlagTime && s.date <= this.rightFlagTime) {
-					add = false;
-				}
-				if (this.style == 'bars' && s.date >= this.leftFlagTime && s.date < this.rightFlagTime) {
-					add = false;
-				}
-			}
-			if (!undo && add) {
-				for (var i in s.stacks ) {
-					timeObjects[i] = timeObjects[i].concat(s.stacks[i].elements);
-				}
-			}
-			this.core.triggerHighlight(timeObjects);
-		}
-	},
-
-	timeRefining : function() {
-		this.core.triggerRefining(this.selection.objects);
-	},
-
-	setStyle : function(style) {
-		this.style = style;
-	},
-
-	drawLinearPlot : function() {
-		if ( typeof this.valueGeometry != 'undefined') {			
-			this.valueGeometry.actLinear();
-			this.timeplot.repaint();
-			this.resetOpacityPlots();
-			this.displayOverlay();
-		}
-	},
-
-	drawLogarithmicPlot : function() {
-		if ( typeof this.valueGeometry != 'undefined') {
-			this.valueGeometry.actLogarithmic();
-			this.timeplot.repaint();
-			this.resetOpacityPlots();
-			this.displayOverlay();
-		}
-	}
-}
-/*
-* TableConfig.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class TableConfig
- * Table Configuration File
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-function TableConfig(options) {
-
-	this.options = {
-		tableWidth : false, // false or desired width css definition for the table
-		tableHeight : false, // false or desired height css definition for the table
-		validResultsPerPage : [10, 20, 50, 100], // valid number of elements per page
-		initialResultsPerPage : 10, // initial number of elements per page
-		tableSorting : true, // true, if sorting of columns should be possible
-		tableContentOffset : 250, // maximum display number of characters in a table cell
-		tableSelectPage : true, // selection of complete table pages
-		tableSelectAll : false, // selection of complete tables
-		tableShowSelected : true, // show selected objects only option
-		tableKeepShowSelected : true, // don't revert to show all on "reset" (e.g. selection)
-		tableInvertSelection : true, // show invert selection option
-		tableSelectByText : true, // select objects by full-text search
-		tableCreateNewFromSelected : true, // create new dataset from selected objects
-		unselectedCellColor : '#EEE', // color for an unselected row/tab
-		verticalAlign : 'top', // vertical alignment of the table cells ('top','center','bottom')
-	};
-	if ( typeof options != 'undefined') {
-		$.extend(this.options, options);
-	}
-
-};
-/*
-* TableGui.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class TableGui
- * Table GUI Implementation
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- *
- * @param {TableWidget} parent table widget object
- * @param {HTML object} div parent div to append the table gui
- * @param {JSON} options table configuration
- */
-function TableGui(table, div, options) {
-
-	this.tableContainer = div;
-	if (options.tableWidth) {
-		this.tableContainer.style.width = options.tableWidth;
-	}
-	if (options.tableHeight) {
-		this.tableContainer.style.height = options.tableHeight;
-	}
-	this.tableContainer.style.position = 'relative';
-
-	this.tabs = document.createElement('div');
-	this.tabs.setAttribute('class', 'tableTabs');
-	div.appendChild(this.tabs);
-
-	this.input = document.createElement('div');
-	this.input.setAttribute('class', 'tableInput');
-	div.appendChild(this.input);
-
-};
+/*
+* TimeConfig.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class TimeConfig
+ * Time Configuration File
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+function TimeConfig(options) {
+
+	this.options = {
+		timeTitle : 'GeoTemCo Time View', // title will be shown in timeplot header
+		timeIndex : 0, // index = position in date array; for multiple dates the 2nd timeplot refers to index 1
+		timeWidth : false, // false or desired width css definition for the timeplot
+		timeHeight : '100px', // false or desired height css definition for the timeplot
+		defaultMinDate : new Date(2012, 0, 1), // required, when empty timelines are possible
+		defaultMaxDate : new Date(), // required, when empty timelines are possible
+		timeCanvasFrom : '#EEE', // time widget background gradient color top
+		timeCanvasTo : '#EEE', // time widget background gradient color bottom
+		rangeBoxColor : "white", // fill color for time range box
+		rangeBorder : "1px solid #de7708", // border of frames
+		dataInformation : true, // show/hide data information
+		rangeAnimation : true, // show/hide animation buttons
+		scaleSelection : true, // show/hide scale selection buttons
+		linearScale : true, // true for linear value scaling, false for logarithmic
+		unitSelection : true, // show/hide time unit selection dropdown
+		timeUnit : -1, // minimum temporal unit (SimileAjax.DateTime or -1 if none) of the data
+		timeMerge : false // if the elements of distinct datasets should be merged into one set or not
+	};
+	if ( typeof options != 'undefined') {
+		$.extend(this.options, options);
+	}
+
+};
+/*
+* TimeGui.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class TimeGui
+ * Time GUI Implementation
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ *
+ * @param {TimeWidget} parent time widget object
+ * @param {HTML object} div parent div to append the time gui
+ * @param {JSON} options time configuration
+ */
+function TimeGui(plot, div, options, iid) {
+
+	var gui = this;
+
+	this.plot = plot;
+
+	this.container = div;
+	if (options.timeWidth) {
+		this.container.style.width = options.timeWidth;
+	}
+	if (options.timeHeight) {
+		this.container.style.height = options.timeHeight;
+	}
+	this.container.style.position = 'relative';
+
+	var w = this.container.offsetWidth;
+	var h = this.container.offsetHeight;
+
+	var toolbarTable = document.createElement("table");
+	toolbarTable.setAttribute('class', 'ddbToolbar');
+	this.container.appendChild(toolbarTable);
+
+	this.plotWindow = document.createElement("div");
+	this.plotWindow.id = "plotWindow"+iid;
+	this.plotWindow.setAttribute('class', 'plotWindow');
+//	this.plotWindow.style.width = w + "px";
+
+	this.plotWindow.style.height = (h + 12) + "px";
+	this.container.style.height = (h + 12) + "px";
+
+	this.plotWindow.onmousedown = function() {
+		return false;
+	}
+
+	this.plotContainer = document.createElement("div");
+	this.plotContainer.id = "plotContainer"+iid;
+	this.plotContainer.setAttribute('class', 'plotContainer');
+//	this.plotContainer.style.width = w + "px";
+	this.plotContainer.style.height = h + "px";
+	this.plotContainer.style.position = "absolute";
+	this.plotContainer.style.zIndex = 0;
+	this.plotContainer.style.top = "12px";
+	this.plotWindow.appendChild(this.plotContainer);
+	this.container.appendChild(this.plotWindow);
+
+	this.timeplotDiv = document.createElement("div");
+	this.timeplotDiv.style.left = "16px";
+	this.timeplotDiv.style.width = (w - 32) + "px";
+	this.timeplotDiv.style.height = h + "px";
+	this.plotContainer.appendChild(this.timeplotDiv);
+
+	var cv = document.createElement("canvas");
+	cv.setAttribute('class', 'plotCanvas');
+	this.plotWindow.appendChild(cv);
+	if (!cv.getContext && G_vmlCanvasManager)
+		cv = G_vmlCanvasManager.initElement(cv);
+	var ctx = cv.getContext('2d');
+
+	var setCanvas = function(){
+		cv.width = gui.plotWindow.clientWidth;
+		cv.height = gui.plotWindow.clientHeight;
+		var gradient = ctx.createLinearGradient(0, 0, 0, gui.plotWindow.clientHeight);
+		gradient.addColorStop(0, options.timeCanvasFrom);
+		gradient.addColorStop(1, options.timeCanvasTo);
+		ctx.fillStyle = gradient;
+		ctx.fillRect(0, 0, gui.plotWindow.clientWidth, gui.plotWindow.clientHeight);
+	}
+	setCanvas();
+
+	this.resize = function(){
+		gui.timeplotDiv.style.width = (gui.container.offsetWidth - 32) + "px";
+		ctx.clearRect(0,0,gui.plotWindow.clientWidth, gui.plotWindow.clientHeight);
+		if( typeof plot.datasets != "undefined" ){
+			plot.redrawPlot();
+			plot.resetOpacityPlots();
+		}
+		setCanvas();
+	};
+
+	var titles = document.createElement("tr");
+	toolbarTable.appendChild(titles);
+	var tools = document.createElement("tr");
+	toolbarTable.appendChild(tools);
+
+	this.timeUnitTitle = document.createElement("td");
+	this.timeUnitTitle.innerHTML = GeoTemConfig.getString('timeUnit');
+	this.timeUnitSelector = document.createElement("td");
+	if (options.unitSelection) {
+		tools.appendChild(this.timeUnitSelector);
+		titles.appendChild(this.timeUnitTitle);
+	}
+
+	this.timeAnimation = document.createElement("td");
+	this.timeAnimation.innerHTML = GeoTemConfig.getString('timeAnimation');
+	var timeAnimationTools = document.createElement("td");
+
+	var status;
+	this.updateAnimationButtons = function(s) {
+		status = s;
+		if (status == 0) {
+			gui.playButton.setAttribute('class', 'smallButton playDisabled');
+			gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled');
+		} else if (status == 1) {
+			gui.playButton.setAttribute('class', 'smallButton playEnabled');
+			gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled');
+		} else {
+			gui.playButton.setAttribute('class', 'smallButton playDisabled');
+			gui.pauseButton.setAttribute('class', 'smallButton pauseEnabled');
+		}
+	};
+	this.playButton = document.createElement("div");
+	this.playButton.title = GeoTemConfig.getString('playButton');
+	timeAnimationTools.appendChild(this.playButton);
+	this.playButton.onclick = function() {
+		if (status == 1) {
+			plot.play();
+		}
+	}
+
+	this.pauseButton = document.createElement("div");
+	this.pauseButton.title = GeoTemConfig.getString('pauseButton');
+	timeAnimationTools.appendChild(this.pauseButton);
+	this.pauseButton.onclick = function() {
+		if (status == 2) {
+			plot.stop();
+		}
+	}
+
+	this.valueScale = document.createElement("td");
+	this.valueScale.innerHTML = GeoTemConfig.getString('valueScale');
+	var valueScaleTools = document.createElement("td");
+
+	var linearPlot;
+	var setValueScale = function(linScale) {
+		if (linearPlot != linScale) {
+			linearPlot = linScale;
+			if (linearPlot) {
+				gui.linButton.setAttribute('class', 'smallButton linearPlotActivated');
+				gui.logButton.setAttribute('class', 'smallButton logarithmicPlotDeactivated');
+				plot.drawLinearPlot();
+			} else {
+				gui.linButton.setAttribute('class', 'smallButton linearPlotDeactivated');
+				gui.logButton.setAttribute('class', 'smallButton logarithmicPlotActivated');
+				plot.drawLogarithmicPlot();
+			}
+		}
+	};
+	this.linButton = document.createElement("div");
+	this.linButton.title = GeoTemConfig.getString('linearPlot');
+	valueScaleTools.appendChild(this.linButton);
+	this.linButton.onclick = function() {
+		setValueScale(true);
+	}
+
+	this.logButton = document.createElement("div");
+	this.logButton.title = GeoTemConfig.getString('logarithmicPlot');
+	valueScaleTools.appendChild(this.logButton);
+	this.logButton.onclick = function() {
+		setValueScale(false);
+	}
+	if (options.rangeAnimation) {
+		titles.appendChild(this.timeAnimation);
+		tools.appendChild(timeAnimationTools);
+		this.updateAnimationButtons(0);
+	}
+
+	if (options.scaleSelection) {
+		titles.appendChild(this.valueScale);
+		tools.appendChild(valueScaleTools);
+		setValueScale(options.linearScale);
+	}
+
+	if (GeoTemConfig.allowFilter) {
+		this.filterTitle = document.createElement("td");
+		titles.appendChild(this.filterTitle);
+		this.filterTitle.innerHTML = GeoTemConfig.getString('filter');
+		this.filterOptions = document.createElement("td");
+		tools.appendChild(this.filterOptions);
+	}
+
+	if (options.dataInformation) {
+		this.infoTitle = document.createElement("td");
+		this.infoTitle.innerHTML = options.timeTitle;
+		titles.appendChild(this.infoTitle);
+		var timeSum = document.createElement("td");
+		this.timeElements = document.createElement("div");
+		this.timeElements.setAttribute('class', 'ddbElementsCount');
+		timeSum.appendChild(this.timeElements);
+		tools.appendChild(timeSum);
+	}
+
+	/*
+	 var tooltip = document.createElement("div");
+	 tooltip.setAttribute('class','ddbTooltip');
+	 toolbarTable.appendChild(tooltip);
+
+	 tooltip.onmouseover = function(){
+	 /*
+	 getPublisher().Publish('TooltipContent', {
+	 content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'),
+	 target: $(tooltip)
+	 });
+
+	 }
+	 tooltip.onmouseout = function(){
+	 //getPublisher().Publish('TooltipContent');
+	 }
+	 */
+
+	this.setHeight = function() {
+		this.container.style.height = (this.plotWindow.offsetHeight + toolbarTable.offsetHeight) + "px";
+	};
+
+	this.updateTimeQuantity = function(count) {
+		if (options.dataInformation) {
+			this.plotCount = count;
+			if (count != 1) {
+				this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results');
+			} else {
+				this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result');
+			}
+		}
+	}
+
+	this.setTimeUnitDropdown = function(units) {
+		$(this.timeUnitSelector).empty();
+		var gui = this;
+		var timeUnits = [];
+		var addUnit = function(unit, index) {
+			var setUnit = function() {
+				gui.plot.setTimeUnit(unit.unit);
+			}
+			timeUnits.push({
+				name : unit.label,
+				onclick : setUnit
+			});
+		}
+		for (var i = 0; i < units.length; i++) {
+			addUnit(units[i], i);
+		}
+		this.timeUnitDropdown = new Dropdown(this.timeUnitSelector, timeUnits, GeoTemConfig.getString('selectTimeUnit'), '100px');
+		this.timeUnitDropdown.setEntry(0);
+	}
+	this.setTimeUnitDropdown([{
+		name : 'none',
+		id : -1
+	}]);
+
+	this.beautifyCount = function(count) {
+		var c = count + '';
+		var p = 0;
+		var l = c.length;
+		while (l - p > 3) {
+			p += 3;
+			c = c.substring(0, l - p) + "." + c.substring(l - p);
+			p++;
+			l++;
+		}
+		return c;
+	}
+
+	this.hideTimeUnitSelection = function() {
+		this.timeUnitTitle.style.display = 'none';
+		this.timeUnitSelector.style.display = 'none';
+	}
+};
+/*
+* TimeWidget.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class TimeWidget
+ * TableWidget Implementation
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ *
+ * @param {TimeWrapper} core wrapper for interaction to other widgets
+ * @param {HTML object} div parent div to append the time widget div
+ * @param {JSON} options user specified configuration that overwrites options in TimeConfig.js
+ */
+TimeWidget = function(core, div, options) {
+
+	this.core = core;
+	this.core.setWidget(this);
+	this.timeplot
+	this.dataSources
+	this.eventSources
+	this.tds
+	this.timeGeometry
+	this.valueGeometry
+	this.canvas
+
+	this.leftFlagPole
+	this.rightFlagPole
+	this.rangeBox
+	this.leftHandle
+	this.rightHandle
+
+	this.leftFlagPos = null;
+	this.leftFlagTime = null;
+	this.rightFlagPos = null;
+	this.rightFlagTime = null;
+
+	this.mouseDownTime
+	this.mouseUpTime
+	this.mouseTempTime
+	this.mouseDownPos
+	this.mouseUpPos
+	this.mouseTempPos
+
+	this.status
+	this.slider
+
+	this.iid = GeoTemConfig.getIndependentId('time');
+	this.options = (new TimeConfig(options)).options;
+	this.gui = new TimeGui(this, div, this.options, this.iid);
+	this.initialize();
+
+}
+
+TimeWidget.prototype = {
+
+	/**
+	 * clears the timeplot canvas and the timeGeometry properties
+	 */
+	clearTimeplot : function() {
+		this.timeplot._clearCanvas();
+		this.timeGeometry._earliestDate = null;
+		this.timeGeometry._latestDate = null;
+		this.valueGeometry._minValue = 0;
+		this.valueGeometry._maxValue = 0;
+		this.highlightedSlice = undefined;
+		this.timeGeometry._clearLabels();
+		this.selection = new Selection();
+	},
+
+	/**
+	 * initializes the timeplot elements with arrays of time objects
+	 * @param {TimeObject[][]} timeObjects an array of time objects from different (1-4) sets
+	 */
+	initWidget : function(datasets) {
+		this.datasets = datasets;
+		var timeObjects = [];
+		for (var i = 0; i < datasets.length; i++) {
+			timeObjects.push(datasets[i].objects);
+		}
+		this.clearTimeplot();
+		this.reset();
+		for (var i = 0; i < this.timeplot._plots.length; i++) {
+			this.timeplot._plots[i].dispose();
+		}
+		this.dataSources = new Array();
+		this.plotInfos = new Array();
+		this.eventSources = new Array();
+		var granularity = 0;
+		this.count = 0;
+		for (var i = 0; i < timeObjects.length; i++) {
+			if( i==0 || !this.options.timeMerge ){
+				var eventSource = new Timeplot.DefaultEventSource();
+				var dataSource = new Timeplot.ColumnSource(eventSource, 1);
+				this.dataSources.push(dataSource);
+				this.eventSources.push(eventSource);
+				var c = GeoTemConfig.getColor(i);
+				var plotInfo = Timeplot.createPlotInfo({
+					id : "plot" + i,
+					dataSource : dataSource,
+					timeGeometry : this.timeGeometry,
+					valueGeometry : this.valueGeometry,
+					fillGradient : false,
+					lineColor : 'rgba(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ', 1)',
+					fillColor : 'rgba(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ', 0.3)',
+					showValues : true
+				});
+				this.plotInfos.push(plotInfo);
+			}
+			for (var j = 0; j < timeObjects[i].length; j++) {
+				var o = timeObjects[i][j];
+				if (o.isTemporal) {
+					var g = o.dates[this.options.timeIndex].granularity;
+					if (g == null) {
+						continue;
+					} else if (g > granularity) {
+						granularity = g;
+					}
+					this.count += o.weight;
+				}
+			}
+		}
+		this.timeGeometry._granularity = granularity;
+		this.timeGeometry._clearLabels();
+		this.timeplot.resetPlots(this.plotInfos);
+		if (this.plotInfos.length == 0) {
+			this.initLabels(this.timeplot.regularGrid());
+			return;
+		}
+		this.timeGeometry.extendedDataSource = this.tds;
+		this.tds.initialize(this.dataSources, this.eventSources, timeObjects, granularity, this.options.timeUnit, this.gui.timeplotDiv.offsetWidth);
+		this.gui.setTimeUnitDropdown(this.tds.availableUnits);
+		this.gui.timeUnitDropdown.setEntry(this.tds.getUnitIndex());
+		var plots = this.timeplot._plots;
+		for (var i = 0; i < plots.length; i++) {
+			plots[i].pins = [];
+			plots[i].style = this.style;
+			for (var j = 0; j < this.tds.getSliceNumber(); j++) {
+				plots[i].pins.push({
+					height : 0,
+					count : 0
+				});
+			}
+		}
+		/*
+		 var levels = Math.round( (this.tds.timeSlices.length-3)/2 );
+		 if( GeoTemConfig.timeZoom ){
+		 this.zoomSlider.setMaxAndLevels(levels,levels);
+		 }
+		 */
+		this.timeplot.repaint();
+		this.timeplot._resizeCanvas();
+		// set maximum number of slider steps
+		var slices = this.tds.timeSlices.length;
+		var numSlices = Math.floor(slices / this.canvas.width * this.canvas.height + 0.5);
+
+		this.initLabels([]);
+		this.initOverview();
+		this.gui.updateTimeQuantity(this.count);
+
+	},
+
+	setTimeUnit : function(unit) {
+		this.clearTimeplot();
+		this.reset();
+		this.tds.setTimeUnit(unit);
+		var plots = this.timeplot._plots;
+		for (var i = 0; i < plots.length; i++) {
+			plots[i].pins = [];
+			plots[i].style = this.style;
+			for (var j = 0; j < this.tds.getSliceNumber(); j++) {
+				plots[i].pins.push({
+					height : 0,
+					count : 0
+				});
+			}
+		}
+		this.initLabels([]);
+	},
+
+	/**
+	 * initializes the timeplot for the Spatio Temporal Interface.
+	 * all elements (including their events) that are needed for user interaction are instantiated here, the slider element as well
+	 */
+	initialize : function() {
+
+		this.status = 0;
+		this.selection = new Selection();
+		this.paused = true;
+		this.dataSources = new Array();
+		this.plotInfos = new Array();
+		this.eventSources = new Array();
+		this.timeGeometry = new Timeplot.DefaultTimeGeometry({
+			gridColor : "#000000",
+			axisLabelsPlacement : "top"
+		});
+		this.style = 'graph';
+		this.timeGeometry._hideLabels = true;
+		this.timeGeometry._granularity = 0;
+		this.valueGeometry = new Timeplot.LogarithmicValueGeometry({
+			min : 0
+		});
+		this.valueGeometry.actLinear();
+
+		var plot = this;
+
+		this.timeplot = Timeplot.create(this.gui.timeplotDiv, this.plotInfos);
+		this.tds = new TimeDataSource(this.options);
+
+		this.canvas = this.timeplot.getCanvas();
+
+		this.leftFlagPole = this.timeplot.putDiv("leftflagpole", "timeplot-dayflag-pole");
+		this.rightFlagPole = this.timeplot.putDiv("rightflagpole", "timeplot-dayflag-pole");
+		SimileAjax.Graphics.setOpacity(this.leftFlagPole, 50);
+		SimileAjax.Graphics.setOpacity(this.rightFlagPole, 50);
+
+		this.rangeBox = this.timeplot.putDiv("rangebox", "range-box");
+		this.rangeBox.style.backgroundColor = plot.options.rangeBoxColor;
+		this.rangeBox.style.border = plot.options.rangeBorder;
+
+		this.leftHandle = document.createElement("div");
+		this.rightHandle = document.createElement("div");
+		this.gui.plotWindow.appendChild(this.leftHandle);
+		this.gui.plotWindow.appendChild(this.rightHandle);
+		this.leftHandle.title = GeoTemConfig.getString('leftHandle');
+		this.rightHandle.title = GeoTemConfig.getString('rightHandle');
+
+		this.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")";
+		this.leftHandle.setAttribute('class', 'plotHandle plotHandleIcon');
+		this.rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")";
+		this.rightHandle.setAttribute('class', 'plotHandle plotHandleIcon');
+
+		this.poles = this.timeplot.putDiv("poles", "pole");
+		this.timeplot.placeDiv(this.poles, {
+			left : 0,
+			bottom : 0,
+			width : this.canvas.width,
+			height : this.canvas.height,
+			display : "block"
+		});
+		this.poles.appendChild(document.createElement("canvas"));
+
+		this.filterBar = new FilterBar(this, this.gui.filterOptions);
+
+		var plot = this;
+
+		this.dragButton = document.createElement("div");
+		this.dragButton.title = GeoTemConfig.getString('dragTimeRange');
+		this.cancelButton = document.createElement("div");
+		this.cancelButton.title = GeoTemConfig.getString('clearSelection');
+		this.cancelButton.onclick = function() {
+			plot.deselection();
+		}
+
+		this.toolbar = document.createElement("div");
+		this.toolbar.setAttribute('class', 'plotToolbar');
+		this.toolbar.style.borderTop = plot.options.rangeBorder;
+		this.toolbar.style.textAlign = "center";
+		this.gui.plotWindow.appendChild(this.toolbar);
+
+		this.toolbarAbsoluteDiv = document.createElement("div");
+		this.toolbarAbsoluteDiv.setAttribute('class', 'absoluteToolbar');
+		this.toolbar.appendChild(this.toolbarAbsoluteDiv);
+
+		this.dragButton.setAttribute('class', 'dragTimeRangeAlt');
+		this.dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")";
+		//        	this.zoomButton.setAttribute('class','zoomRangeAlt');
+		this.cancelButton.setAttribute('class', 'cancelRangeAlt');
+		this.toolbarAbsoluteDiv.appendChild(this.dragButton);
+		this.toolbarAbsoluteDiv.style.width = this.dragButton.offsetWidth + "px";
+		//	        this.gui.plotWindow.appendChild(this.zoomButton);
+		this.gui.plotWindow.appendChild(this.cancelButton);
+
+		this.overview = document.createElement("div");
+		this.overview.setAttribute('class', 'timeOverview');
+		this.gui.plotWindow.appendChild(this.overview);
+
+		var mousedown = false;
+		this.shift = function(shift) {
+			if (!mousedown) {
+				return;
+			}
+			if (plot.tds.setShift(shift)) {
+				plot.redrawPlot();
+			}
+			setTimeout(function() {
+				plot.shift(shift);
+			}, 200);
+		}
+		var shiftPressed = function(shift) {
+			mousedown = true;
+			document.onmouseup = function() {
+				mousedown = false;
+				document.onmouseup = null;
+			}
+			plot.shift(shift);
+		}
+
+		this.shiftLeft = document.createElement("div");
+		this.shiftLeft.setAttribute('class', 'shiftLeft');
+		this.gui.plotWindow.appendChild(this.shiftLeft);
+		this.shiftLeft.onmousedown = function() {
+			shiftPressed(1);
+		}
+
+		this.shiftRight = document.createElement("div");
+		this.shiftRight.setAttribute('class', 'shiftRight');
+		this.gui.plotWindow.appendChild(this.shiftRight);
+		this.shiftRight.onmousedown = function() {
+			shiftPressed(-1);
+		}
+
+		this.plotLabels = document.createElement("div");
+		this.plotLabels.setAttribute('class', 'plotLabels');
+		this.gui.plotWindow.appendChild(this.plotLabels);
+
+		this.initLabels(this.timeplot.regularGrid());
+
+		//Finds the time corresponding to the position x on the timeplot
+		var getCorrelatedTime = function(x) {
+			if (x >= plot.canvas.width)
+				x = plot.canvas.width;
+			if (isNaN(x) || x < 0)
+				x = 0;
+			var t = plot.timeGeometry.fromScreen(x);
+			if (t == 0)
+				return;
+			return plot.dataSources[0].getClosestValidTime(t);
+		}
+		//Finds the position corresponding to the time t on the timeplot
+		var getCorrelatedPosition = function(t) {
+			var x = plot.timeGeometry.toScreen(t);
+			if (x >= plot.canvas.width)
+				x = plot.canvas.width;
+			if (isNaN(x) || x < 0)
+				x = 0;
+			return x;
+		}
+		//Maps the 2 positions in the right order to left and right bound of the chosen timeRange
+		var mapPositions = function(pos1, pos2) {
+			if (pos1 > pos2) {
+				plot.leftFlagPos = pos2;
+				plot.rightFlagPos = pos1;
+			} else {
+				plot.leftFlagPos = pos1;
+				plot.rightFlagPos = pos2;
+			}
+			plot.leftFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.leftFlagPos));
+			plot.rightFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.rightFlagPos));
+		}
+		//Sets the divs corresponding to the actual chosen timeRange
+		var setRangeDivs = function() {
+			plot.leftFlagPole.style.visibility = "visible";
+			plot.rightFlagPole.style.visibility = "visible";
+			plot.rangeBox.style.visibility = "visible";
+			plot.timeplot.placeDiv(plot.leftFlagPole, {
+				left : plot.leftFlagPos,
+				bottom : 0,
+				height : plot.canvas.height,
+				display : "block"
+			});
+			plot.timeplot.placeDiv(plot.rightFlagPole, {
+				left : plot.rightFlagPos,
+				bottom : 0,
+				height : plot.canvas.height,
+				display : "block"
+			});
+			var boxWidth = plot.rightFlagPos - plot.leftFlagPos;
+			if (plot.popup) {
+				plot.popupClickDiv.style.visibility = "visible";
+				plot.timeplot.placeDiv(plot.popupClickDiv, {
+					left : plot.leftFlagPos,
+					width : boxWidth + 1,
+					height : plot.canvas.height,
+					display : "block"
+				});
+			}
+			plot.timeplot.placeDiv(plot.rangeBox, {
+				left : plot.leftFlagPos,
+				width : boxWidth + 1,
+				height : plot.canvas.height,
+				display : "block"
+			});
+			var plots = plot.timeplot._plots;
+			for ( i = 0; i < plots.length; i++) {
+				plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i));
+				plots[i].opacityPlot.style.visibility = "visible";
+			}
+			var unit = plot.tds.unit;
+
+			var top = plot.gui.plotContainer.offsetTop;
+			var left = plot.gui.plotContainer.offsetLeft;
+			var leftPos = plot.leftFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft;
+			var rightPos = plot.rightFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft;
+			var rW = rightPos - leftPos;
+			var pW = plot.canvas.width;
+			var pL = plot.timeplot.getElement().offsetLeft;
+
+			var handleTop = top + Math.floor(plot.gui.timeplotDiv.offsetHeight / 2 - plot.leftHandle.offsetHeight / 2);
+			plot.leftHandle.style.visibility = "visible";
+			plot.rightHandle.style.visibility = "visible";
+			plot.leftHandle.style.left = (leftPos - plot.leftHandle.offsetWidth / 2) + "px";
+			plot.rightHandle.style.left = (rightPos - plot.rightHandle.offsetWidth + 1 + plot.rightHandle.offsetWidth / 2) + "px";
+			plot.leftHandle.style.top = handleTop + "px";
+			plot.rightHandle.style.top = handleTop + "px";
+			if (rightPos == leftPos) {
+				plot.rightHandle.style.visibility = "hidden";
+				plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "mergedHandle.png" + ")";
+			} else {
+				plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")";
+			}
+			plot.cancelButton.style.visibility = "visible";
+			plot.cancelButton.style.top = top + "px";
+
+			if (rW > plot.cancelButton.offsetWidth) {
+				plot.cancelButton.style.left = (left + rightPos - plot.cancelButton.offsetWidth) + "px";
+			} else {
+				plot.cancelButton.style.left = (left + rightPos) + "px";
+			}
+			var tW = plot.toolbarAbsoluteDiv.offsetWidth;
+			if (rW >= tW) {
+				plot.toolbar.style.left = leftPos + "px";
+				plot.toolbar.style.width = (rW + 1) + "px";
+				plot.toolbarAbsoluteDiv.style.left = ((rW - tW) / 2) + "px";
+			} else {
+				plot.toolbar.style.left = (pL + plot.leftFlagPos * (pW - tW) / (pW - rW)) + "px";
+				plot.toolbar.style.width = (tW + 2) + "px";
+				plot.toolbarAbsoluteDiv.style.left = "0px";
+			}
+			plot.toolbar.style.top = (top + plot.timeplot.getElement().offsetHeight) + "px";
+			plot.toolbar.style.visibility = "visible";
+			plot.toolbarAbsoluteDiv.style.visibility = "visible";
+
+		}
+		var getAbsoluteLeft = function(div) {
+			var left = 0;
+			while (div) {
+				left += div.offsetLeft;
+				div = div.offsetParent;
+			}
+			return left;
+		}
+		var timeplotLeft = getAbsoluteLeft(plot.timeplot.getElement());
+
+		var checkPolesForStyle = function(x) {
+			if (plot.style == 'bars' && plot.leftFlagTime == plot.rightFlagTime) {
+				var index = plot.tds.getSliceIndex(plot.leftFlagTime);
+				var time1 = plot.leftFlagTime;
+				var pos1 = plot.leftFlagPos;
+				var time2, pos2;
+				if (index == 0) {
+					time2 = plot.tds.getSliceTime(index + 1);
+				} else if (index == plot.tds.getSliceNumber() - 1) {
+					time2 = plot.tds.getSliceTime(index - 1);
+				} else {
+					if (x < plot.leftFlagPos) {
+						time2 = plot.tds.getSliceTime(index - 1);
+					} else {
+						time2 = plot.tds.getSliceTime(index + 1);
+					}
+				}
+				pos2 = plot.timeGeometry.toScreen(time2);
+				mapPositions(pos1, pos2, time1, time2);
+			}
+		}
+		var startX, startY, multiplier;
+
+		// mousemove function that causes moving selection of objects and toolbar divs
+		var moveToolbar = function(start, actual) {
+			var pixelShift = actual - start;
+			if (plot.status == 2) {
+				var newTime = getCorrelatedTime(startX + pixelShift);
+				if (newTime == plot.mouseTempTime) {
+					return;
+				}
+				plot.mouseTempTime = newTime;
+				plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime);
+				mapPositions(plot.mouseDownPos, plot.mouseTempPos);
+			} else if (plot.status == 3) {
+				pixelShift *= multiplier;
+				var plotPos = actual - timeplotLeft;
+				if (plotPos <= plot.canvas.width / 2) {
+					var newTime = getCorrelatedTime(startX + pixelShift);
+					if (newTime == plot.leftFlagTime) {
+						return;
+					}
+					plot.leftFlagTime = newTime;
+					var diff = plot.leftFlagPos;
+					plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime);
+					diff -= plot.leftFlagPos;
+					plot.rightFlagTime = getCorrelatedTime(plot.rightFlagPos - diff);
+					plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime);
+				} else {
+					var newTime = getCorrelatedTime(startY + pixelShift);
+					if (newTime == plot.rightFlagTime) {
+						return;
+					}
+					plot.rightFlagTime = newTime;
+					var diff = plot.rightFlagPos;
+					plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime);
+					diff -= plot.rightFlagPos;
+					plot.leftFlagTime = getCorrelatedTime(plot.leftFlagPos - diff);
+					plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime);
+				}
+			}
+			checkPolesForStyle(actual - timeplotLeft);
+			setRangeDivs();
+			plot.timeSelection();
+		}
+		// fakes user interaction mouse move
+		var playIt = function(start, actual, reset) {
+			if (!plot.paused) {
+				var pixel = plot.canvas.width / (plot.tds.timeSlices.length - 1 ) / 5;
+				var wait = 20 * pixel;
+				if (reset) {
+					actual = 0;
+				}
+				moveToolbar(start, actual);
+				if (plot.rightFlagPos >= plot.canvas.width) {
+					reset = true;
+					wait = 1000;
+				} else {
+					reset = false;
+				}
+				setTimeout(function() {
+					playIt(start, actual + pixel, reset)
+				}, wait);
+			}
+		}
+		var setMultiplier = function() {
+			var rangeWidth = plot.rightFlagPos - plot.leftFlagPos;
+			var toolbarWidth = plot.toolbarAbsoluteDiv.offsetWidth;
+			var plotWidth = plot.canvas.width;
+			if (rangeWidth < toolbarWidth) {
+				multiplier = (plotWidth - rangeWidth) / (plotWidth - toolbarWidth);
+			} else {
+				multiplier = 1;
+			}
+		}
+		/**
+		 * starts the animation
+		 */
+		this.play = function() {
+			if (this.leftFlagPos == null) {
+				return;
+			}
+			plot.paused = false;
+			plot.gui.updateAnimationButtons(2);
+			plot.status = 3;
+			setMultiplier();
+			startX = plot.leftFlagPos;
+			startY = plot.rightFlagPos;
+			var position = Math.round(plot.leftFlagPos);
+			playIt(position, position + 1, false);
+		}
+		/**
+		 * stops the animation
+		 */
+		this.stop = function() {
+			plot.paused = true;
+			plot.status = 0;
+			plot.gui.updateAnimationButtons(1);
+		}
+		// triggers the mousemove function to move the range and toolbar
+		var toolbarEvent = function(evt) {
+			var left = GeoTemConfig.getMousePosition(evt).left;
+			document.onmousemove = function(evt) {
+				moveToolbar(left, GeoTemConfig.getMousePosition(evt).left);
+				if (plot.popup) {
+					plot.popup.reset();
+				}
+			}
+		}
+		var initializeLeft = function() {
+			plot.mouseDownTime = plot.rightFlagTime;
+			plot.mouseTempTime = plot.leftFlagTime;
+			plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime);
+			startX = plot.leftFlagPos;
+		}
+		var initializeRight = function() {
+			plot.mouseDownTime = plot.leftFlagTime;
+			plot.mouseTempTime = plot.rightFlagTime;
+			plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime);
+			startX = plot.rightFlagPos;
+		}
+		var initializeDrag = function() {
+			startX = plot.leftFlagPos;
+			startY = plot.rightFlagPos;
+			setMultiplier();
+		}
+		var checkBorders = function() {
+			if (plot.style == 'bars' && plot.mouseUpTime == plot.mouseDownTime) {
+				var index = plot.tds.getSliceIndex(plot.mouseUpTime);
+				if (index == 0) {
+					plot.mouseUpTime = plot.tds.getSliceTime(index + 1);
+				} else if (index == plot.tds.getSliceNumber() - 1) {
+					plot.mouseUpTime = plot.tds.getSliceTime(index - 1);
+				} else {
+					if (plot.x < plot.leftFlagPos) {
+						plot.mouseUpTime = plot.tds.getSliceTime(index - 1);
+					} else {
+						plot.mouseUpTime = plot.tds.getSliceTime(index + 1);
+					}
+				}
+			}
+		}
+		// handles mousedown on left handle
+		this.leftHandle.onmousedown = function(evt) {
+			if (plot.status != 2) {
+
+				initializeLeft();
+				plot.status = 2;
+				toolbarEvent(evt);
+				document.onmouseup = function() {
+					document.onmousemove = null;
+					document.onmouseup = null;
+					plot.stop();
+				}
+			}
+		}
+		// handles mousedown on right handle
+		this.rightHandle.onmousedown = function(evt) {
+			if (plot.status != 2) {
+				initializeRight();
+				plot.status = 2;
+				toolbarEvent(evt);
+				document.onmouseup = function() {
+					document.onmousemove = null;
+					document.onmouseup = null;
+					plot.stop();
+				}
+			}
+		}
+		// handles mousedown on drag button
+		this.dragButton.onmousedown = function(evt) {
+			if (plot.status != 3) {
+				plot.status = 3;
+				initializeDrag();
+				toolbarEvent(evt);
+				document.onmouseup = function() {
+					document.onmousemove = null;
+					document.onmouseup = null;
+					plot.stop();
+				}
+			}
+		}
+		// handles mousedown-Event on timeplot
+		var mouseDownHandler = function(elmt, evt, target) {
+			if (plot.dataSources.length > 0) {
+
+				plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
+				if (plot.status == 0) {
+					var time = getCorrelatedTime(plot.x);
+					if (plot.leftFlagPos != null && plot.popup && time >= plot.leftFlagTime && time <= plot.rightFlagTime) {
+						var x = plot.leftFlagPos + (plot.rightFlagPos - plot.leftFlagPos) / 2;
+						var elements = [];
+						for (var i = 0; i < plot.dataSources.length; i++) {
+							elements.push([]);
+						}
+						for (var i = 0; i < plot.selectedObjects.length; i++) {
+							if (plot.selectedObjects[i].value == 1) {
+								for (var j = 0; j < plot.selectedObjects[i].objects.length; j++) {
+									elements[j] = elements[j].concat(plot.selectedObjects[i].objects[j]);
+								}
+							}
+						}
+						var labels = [];
+						for (var i = 0; i < elements.length; i++) {
+							if (elements[i].length == 0) {
+								continue;
+							}
+							var c = GeoTemConfig.getColor(i);
+							var color = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')';
+							var div = document.createElement("div");
+							div.setAttribute('class', 'tagCloudItem');
+							div.style.color = color;
+							var label = {
+								div : div,
+								elements : elements[i]
+							};
+							var weight = 0;
+							for (j in elements[i] ) {
+								weight += elements[i][j].weight;
+							}
+							var fs = 2 * weight / 1000;
+							if (fs > 2) {
+								fs = 2;
+							}
+							div.style.fontSize = (1 + fs) + "em";
+							div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + c.hex;
+							if (weight == 1) {
+								div.innerHTML = weight + " object";
+							} else {
+								div.innerHTML = weight + " objects";
+							}
+							var appendMouseFunctions = function(label, div, color) {
+								div.onclick = function() {
+									plot.popup.showLabelContent(label);
+									div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color;
+								}
+								div.onmouseover = function() {
+									div.style.textShadow = "0 -1px " + color + ", 1px 0 " + color + ", 0 1px " + color + ", -1px 0 " + color;
+								}
+								div.onmouseout = function() {
+									div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color;
+								}
+							}
+							appendMouseFunctions(label, div, c.hex);
+							labels.push(label);
+						}
+						if (labels.length > 0) {
+							plot.popup.createPopup(x + 20, 0, labels);
+						}
+					} else {
+						plot.deselection();
+						plot.status = 1;
+						plot.mouseDownTime = time;
+						plot.mouseTempTime = plot.mouseDownTime;
+						plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime);
+						mapPositions(plot.mouseDownPos, plot.mouseDownPos, plot.mouseDownTime, plot.mouseDownTime);
+						// handles mouseup-Event on timeplot
+						document.onmouseup = function() {
+							if (plot.status == 1) {
+								plot.mouseUpTime = plot.mouseTempTime;
+								plot.mouseUpPos = plot.timeGeometry.toScreen(plot.mouseUpTime);
+								mapPositions(plot.mouseDownPos, plot.mouseUpPos, plot.mouseDownTime, plot.mouseUpTime);
+								checkPolesForStyle(plot.x);
+								setRangeDivs();
+								plot.timeSelection();
+								plot.gui.updateAnimationButtons(1);
+								document.onmouseup = null;
+								plot.status = 0;
+							}
+						}
+					}
+				}
+			}
+		}
+		// handles mousemove-Event on timeplot
+		var mouseMoveHandler = function(elmt, evt, target) {
+			if (plot.dataSources.length > 0) {
+				plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
+				if (plot.status == 1) {
+					plot.mouseTempTime = getCorrelatedTime(plot.x);
+					plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime);
+					mapPositions(plot.mouseDownPos, plot.mouseTempPos, plot.mouseDownTime, plot.mouseTempTime);
+					checkPolesForStyle(plot.x);
+					setRangeDivs();
+				}
+			}
+		}
+		// handles mouseout-Event on timeplot
+		var mouseOutHandler = function(elmt, evt, target) {
+			if (plot.dataSources.length > 0) {
+				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
+				var y = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).y);
+				if (x > plot.canvas.width - 2 || isNaN(x) || x < 2) {
+					plot.timeHighlight(true);
+					plot.highlightedSlice = undefined;
+				} else if (y > plot.canvas.height - 2 || isNaN(y) || y < 2) {
+					plot.timeHighlight(true);
+					plot.highlightedSlice = undefined;
+				}
+			}
+		}
+		// handles mouse(h)over-Event on timeplot
+		var mouseHoverHandler = function(elmt, evt, target) {
+			if (plot.dataSources.length > 0) {
+				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
+				var time = getCorrelatedTime(x);
+				if (time == undefined) {
+					return;
+				}
+				var highlightSlice;
+				var slices = plot.tds.timeSlices;
+				var index = plot.tds.getSliceIndex(time);
+				if (plot.style == 'graph') {
+					highlightSlice = slices[index];
+				}
+				if (plot.style == 'bars') {
+					var pos = plot.timeGeometry.toScreen(time);
+					if (x < pos && index > 0) {
+						highlightSlice = slices[index - 1];
+					} else {
+						highlightSlice = slices[index];
+					}
+				}
+				if (plot.highlightedSlice == undefined || plot.highlightedSlice != highlightSlice) {
+					plot.highlightedSlice = highlightSlice;
+					plot.timeHighlight(false);
+				}
+			}
+		}
+
+		this.redrawPlot = function() {
+			plot.clearTimeplot();
+			plot.tds.reset(this.timeGeometry);
+			plot.timeplot._prepareCanvas();
+			plot.timeplot.repaint();
+			if (plot.leftFlagPos != null) {
+				plot.leftFlagPos = getCorrelatedPosition(plot.leftFlagTime);
+				plot.rightFlagPos = getCorrelatedPosition(plot.rightFlagTime);
+				setRangeDivs();
+			} else {
+				plot.displayOverlay();
+			}
+			plot.initLabels([]);
+			plot.updateOverview();
+		}
+
+		this.resetOpacityPlots = function() {
+			var plots = plot.timeplot._plots;
+			for ( var i = 0; i < plots.length; i++) {
+				plots[i]._opacityCanvas.width = this.canvas.width;
+				plots[i]._opacityCanvas.height = this.canvas.height;
+				if( plot.leftFlagTime != null ){
+					plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i));
+				}
+			}
+		}
+
+		/**
+		 * handles zoom of the timeplot
+		 * @param {int} delta the change of zoom
+		 * @param {Date} time a time that corresponds to a slice, that was clicked
+		 */
+		/*
+		this.zoom = function(delta,time){
+		if( this.eventSources.length == 0 ){
+		if( GeoTemConfig.timeZoom ){
+		this.zoomSlider.setValue(0);
+		}
+		return false;
+		}
+		if( time == null ){
+		time = getCorrelatedTime(this.canvas.width/2);
+		}
+		if( this.tds.setZoom(delta,time,this.leftFlagTime,this.rightFlagTime) ){
+		this.redrawPlot();
+		}
+		if( GeoTemConfig.timeZoom ){
+		this.zoomSlider.setValue(this.tds.getZoom());
+		}
+		return true;
+		}
+		*/
+
+		// handles mousewheel event on the timeplot
+		var mouseWheelHandler = function(elmt, evt, target) {
+			if (evt.preventDefault) {
+				evt.preventDefault();
+			}
+			if (plot.dataSources.length == 0) {
+				return;
+			}
+			var delta = 0;
+			if (!evt)
+				evt = window.event;
+			if (evt.wheelDelta) {
+				delta = evt.wheelDelta / 120;
+				if (window.opera)
+					delta = -delta;
+			} else if (evt.detail) {
+				delta = -evt.detail / 3;
+			}
+			if (delta) {
+				var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x);
+				var time = getCorrelatedTime(x);
+				plot.zoom(delta, time);
+			}
+		}
+		var timeplotElement = this.timeplot.getElement();
+		SimileAjax.DOM.registerEvent(timeplotElement, "mousedown", mouseDownHandler);
+		SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler);
+		SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseHoverHandler);
+		SimileAjax.DOM.registerEvent(timeplotElement, "mouseout", mouseOutHandler);
+		if (GeoTemConfig.mouseWheelZoom) {
+			//SimileAjax.DOM.registerEvent(timeplotElement, "mousewheel", mouseWheelHandler);
+		}
+
+		this.gui.setHeight();
+
+	},
+
+	resetOverlay : function() {
+		this.poles.style.visibility = "hidden";
+		var plots = this.timeplot._plots;
+		for (var i = 0; i < plots.length; i++) {
+			for (var j = 0; j < plots[i].pins.length; j++) {
+				plots[i].pins[j] = {
+					height : 0,
+					count : 0
+				};
+			}
+		}
+	},
+
+	/**
+	 * resets the timeplot to non selection status
+	 */
+	reset : function() {
+
+		this.leftFlagPole.style.visibility = "hidden";
+		this.rightFlagPole.style.visibility = "hidden";
+		this.rangeBox.style.visibility = "hidden";
+		this.leftHandle.style.visibility = "hidden";
+		this.rightHandle.style.visibility = "hidden";
+		this.toolbar.style.visibility = "hidden";
+		this.toolbarAbsoluteDiv.style.visibility = "hidden";
+		this.cancelButton.style.visibility = "hidden";
+
+		var plots = this.timeplot._plots;
+		for (var i = 0; i < plots.length; i++) {
+			plots[i].opacityPlot.style.visibility = "hidden";
+		}
+		this.resetOverlay();
+		this.filterBar.reset(false);
+
+		var slices = this.tds.timeSlices;
+		if (slices != undefined) {
+			for (var i = 0; i < slices.length; i++) {
+				slices[i].reset();
+			}
+		}
+
+		this.status = 0;
+		this.stop();
+		this.gui.updateAnimationButtons(0);
+
+		this.leftFlagPos = null;
+		this.leftFlagTime = null;
+		this.rightFlagPos = null;
+		this.rightFlagTime = null;
+
+		this.mouseDownTime = null;
+		this.mouseUpTime = null;
+		this.mouseTempTime = null;
+
+		this.mouseDownPos = null;
+		this.mouseUpPos = null;
+		this.mouseTempPos = null;
+
+		if (this.popup) {
+			this.popup.reset();
+			this.popupClickDiv.style.visibility = "hidden";
+		}
+
+	},
+
+	/**
+	 * sets a pole on the timeplot
+	 * @param {Date} time the time of the specific timeslice
+	 * @param {int[]} the number of selected elements per dataset
+	 */
+	displayOverlay : function() {
+		this.poles.style.visibility = "visible";
+		var cv = this.poles.getElementsByTagName("canvas")[0];
+		cv.width = this.canvas.width;
+		cv.height = this.canvas.height;
+		if (!cv.getContext && G_vmlCanvasManager) {
+			cv = G_vmlCanvasManager.initElement(cv);
+		}
+		var ctx = cv.getContext('2d');
+		ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+		var plots = this.timeplot._plots;
+		var slices = this.tds.timeSlices;
+		for (var i = 0; i < slices.length; i++) {
+			if (this.style == 'bars' && i + 1 == slices.length) {
+				return;
+			}
+			if (slices[i].overlay() == 0) {
+				continue;
+			}
+			var projStacks = slices[i].projStacks;
+			var time = slices[i].date;
+			var pos;
+			if (this.style == 'graph') {
+				pos = this.timeGeometry.toScreen(time);
+			} else if (this.style == 'bars') {
+				var x1 = this.timeGeometry.toScreen(time);
+				var x2 = this.timeGeometry.toScreen(slices[i + 1].date);
+				pos = (x1 + x2 ) / 2;
+			}
+			var heights = [];
+			var h = 0;
+			for (var j = 0; j < projStacks.length; j++) {
+				var data = plots[j]._dataSource.getData();
+				for (var k = 0; k < data.times.length; k++) {
+					if (data.times[k].getTime() == time.getTime()) {
+						var height = plots[j]._valueGeometry.toScreen(plots[j]._dataSource.getData().values[k]) * projStacks[j].overlay / projStacks[j].value;
+						heights.push(height);
+						plots[j].pins[i] = {
+							height : height,
+							count : projStacks[j].overlay
+						};
+						if (height > h) {
+							h = height;
+						}
+						break;
+					}
+				}
+			}
+			ctx.fillStyle = "rgb(102,102,102)";
+			ctx.beginPath();
+			ctx.rect(pos - 1, this.canvas.height - h, 2, h);
+			ctx.fill();
+			for (var j = 0; j < heights.length; j++) {
+				if (heights[j] > 0) {
+					var color = GeoTemConfig.getColor(j);
+					ctx.fillStyle = "rgba(" + color.r1 + "," + color.g1 + "," + color.b1 + ",0.6)";
+					ctx.beginPath();
+					ctx.arc(pos, this.canvas.height - heights[j], 2.5, 0, Math.PI * 2, true);
+					ctx.closePath();
+					ctx.fill();
+				}
+			}
+		}
+	},
+
+	/**
+	 * updates the timeplot by displaying place poles, after a selection had been executed in another widget
+	 */
+	highlightChanged : function(timeObjects) {
+		if( !GeoTemConfig.highlightEvents ){
+			return;
+		}
+		this.resetOverlay();
+		if (this.selection.valid()) {
+			if (!this.selection.equal(this)) {
+				this.tds.setOverlay(GeoTemConfig.mergeObjects(timeObjects, this.selection.getObjects(this)));
+			} else {
+				this.tds.setOverlay(timeObjects);
+			}
+		} else {
+			this.tds.setOverlay(timeObjects);
+		}
+		this.displayOverlay();
+	},
+
+	/**
+	 * updates the timeplot by displaying place poles, after a selection had been executed in another widget
+	 */
+	selectionChanged : function(selection) {
+		if( !GeoTemConfig.selectionEvents ){
+			return;
+		}
+		this.reset();
+		this.selection = selection;
+		this.tds.setOverlay(selection.objects);
+		this.displayOverlay();
+	},
+
+	/**
+	 * returns the approximate left position of a slice inside the overview representation
+	 * @param {Date} time time of the slice
+	 */
+	getOverviewLeft : function(time) {
+		var w = this.overview.offsetWidth;
+		var s = this.tds.earliest().getTime();
+		var e = this.tds.latest().getTime();
+		var t = time.getTime();
+		return Math.round(w * (t - s) / (e - s));
+	},
+
+	/**
+	 * visualizes the overview div (shows viewable part of zoomed timeplot)
+	 */
+	initOverview : function() {
+		var labels = this.timeGeometry._grid;
+		if (labels.length == 0) {
+			var plot = this;
+			setTimeout(function() {
+				plot.initOverview();
+			}, 10);
+			return;
+		}
+
+		this.overview.style.width = this.canvas.width + "px";
+		var left = this.gui.timeplotDiv.offsetLeft;
+		this.overview.innerHTML = "";
+		this.overview.style.left = left + "px";
+
+		this.overviewRange = document.createElement("div");
+		this.overviewRange.setAttribute('class', 'overviewRange');
+		this.overview.appendChild(this.overviewRange);
+
+		for (var i = 0; i < labels.length; i++) {
+			var label = document.createElement("div");
+			label.setAttribute('class', 'overviewLabel');
+			label.innerHTML = labels[i].label;
+			label.style.left = Math.floor(labels[i].x) + "px";
+			this.overview.appendChild(label);
+		}
+
+		this.updateOverview();
+	},
+
+	/**
+	 * visualizes the labels of the timeplot
+	 */
+	initLabels : function(labels) {
+		if (labels.length == 0) {
+			labels = this.timeGeometry._grid;
+			if (labels.length == 0) {
+				var plot = this;
+				setTimeout(function() {
+					plot.initLabels([]);
+				}, 10);
+				return;
+			}
+		}
+		this.plotLabels.style.width = this.canvas.width + "px";
+		var left = this.gui.timeplotDiv.offsetLeft;
+		this.plotLabels.style.left = left + "px";
+		this.plotLabels.innerHTML = "";
+		for (var i = 0; i < labels.length; i++) {
+			var label = document.createElement("div");
+			label.setAttribute('class', 'plotLabel');
+			label.innerHTML = labels[i].label;
+			label.style.left = Math.floor(labels[i].x) + "px";
+			this.plotLabels.appendChild(label);
+		}
+	},
+
+	/**
+	 * updates the overview div
+	 */
+	updateOverview : function() {
+		if (this.tds.getZoom() > 0) {
+			this.plotLabels.style.visibility = "hidden";
+			this.timeGeometry._hideLabels = false;
+			this.overview.style.visibility = "visible";
+			this.shiftLeft.style.visibility = "visible";
+			this.shiftRight.style.visibility = "visible";
+			var left = this.getOverviewLeft(this.tds.timeSlices[this.tds.leftSlice].date);
+			var right = this.getOverviewLeft(this.tds.timeSlices[this.tds.rightSlice].date);
+			this.overviewRange.style.left = left + "px";
+			this.overviewRange.style.width = (right - left) + "px";
+		} else {
+			this.timeGeometry._hideLabels = true;
+			this.plotLabels.style.visibility = "visible";
+			this.overview.style.visibility = "hidden";
+			this.shiftLeft.style.visibility = "hidden";
+			this.shiftRight.style.visibility = "hidden";
+		}
+	},
+
+	/**
+	 * returns the time slices which are created by the extended data source
+	 */
+	getSlices : function() {
+		return this.tds.timeSlices;
+	},
+
+	timeSelection : function() {
+		var slices = this.tds.timeSlices;
+		var ls, rs;
+		for (var i = 0; i < slices.length; i++) {
+			if (slices[i].date.getTime() == this.leftFlagTime.getTime())
+				ls = i;
+			if (slices[i].date.getTime() == this.rightFlagTime.getTime()) {
+				if (this.style == 'graph') {
+					rs = i;
+				}
+				if (this.style == 'bars') {
+					rs = i - 1;
+				}
+			}
+		}
+		var selectedObjects = [];
+		for (var i = 0; i < GeoTemConfig.datasets.length; i++) {
+			selectedObjects.push([]);
+		}
+		for (var i = 0; i < slices.length; i++) {
+			if (i >= ls && i <= rs) {
+				for (var j in slices[i].stacks ) {
+					selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements);
+				}
+			}
+		}
+		this.selection = new Selection(selectedObjects, this);
+		this.core.triggerSelection(this.selection);
+		this.filterBar.reset(true);
+	},
+
+	deselection : function() {
+		this.reset();
+		this.selection = new Selection();
+		this.core.triggerSelection(this.selection);
+	},
+
+	filtering : function() {
+		for (var i = 0; i < this.datasets.length; i++) {
+			this.datasets[i].objects = this.selection.objects[i];
+		}
+		this.core.triggerRefining(this.datasets);
+	},
+
+	inverseFiltering : function() {
+		var slices = this.tds.timeSlices;
+		var ls, rs;
+		for (var i = 0; i < slices.length; i++) {
+			if (slices[i].date.getTime() == this.leftFlagTime.getTime())
+				ls = i;
+			if (slices[i].date.getTime() == this.rightFlagTime.getTime()) {
+				if (this.style == 'graph') {
+					rs = i;
+				}
+				if (this.style == 'bars') {
+					rs = i - 1;
+				}
+			}
+		}
+		var selectedObjects = [];
+		for (var i = 0; i < GeoTemConfig.datasets.length; i++) {
+			selectedObjects.push([]);
+		}
+		for (var i = 0; i < slices.length; i++) {
+			if (i >= ls && i <= rs) {
+				continue;
+			}
+			for (var j in slices[i].stacks ) {
+				selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements);
+			}
+		}
+		this.selection = new Selection(selectedObjects, this);
+		this.filtering();
+	},
+
+	timeHighlight : function(undo) {
+		if (this.status == 0) {
+			var s = this.highlightedSlice;
+			var timeObjects = [];
+			for (var i = 0; i < this.tds.size(); i++) {
+				timeObjects.push([]);
+			}
+			var add = true;
+			if (this.leftFlagTime != null) {
+				if (this.style == 'graph' && s.date >= this.leftFlagTime && s.date <= this.rightFlagTime) {
+					add = false;
+				}
+				if (this.style == 'bars' && s.date >= this.leftFlagTime && s.date < this.rightFlagTime) {
+					add = false;
+				}
+			}
+			if (!undo && add) {
+				for (var i in s.stacks ) {
+					timeObjects[i] = timeObjects[i].concat(s.stacks[i].elements);
+				}
+			}
+			this.core.triggerHighlight(timeObjects);
+		}
+	},
+
+	timeRefining : function() {
+		this.core.triggerRefining(this.selection.objects);
+	},
+
+	setStyle : function(style) {
+		this.style = style;
+	},
+
+	drawLinearPlot : function() {
+		if ( typeof this.valueGeometry != 'undefined') {			
+			this.valueGeometry.actLinear();
+			this.timeplot.repaint();
+			this.resetOpacityPlots();
+			this.displayOverlay();
+		}
+	},
+
+	drawLogarithmicPlot : function() {
+		if ( typeof this.valueGeometry != 'undefined') {
+			this.valueGeometry.actLogarithmic();
+			this.timeplot.repaint();
+			this.resetOpacityPlots();
+			this.displayOverlay();
+		}
+	}
+}
+/*
+* TableConfig.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class TableConfig
+ * Table Configuration File
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+function TableConfig(options) {
+
+	this.options = {
+		tableWidth : false, // false or desired width css definition for the table
+		tableHeight : false, // false or desired height css definition for the table
+		validResultsPerPage : [10, 20, 50, 100], // valid number of elements per page
+		initialResultsPerPage : 10, // initial number of elements per page
+		tableSorting : true, // true, if sorting of columns should be possible
+		tableContentOffset : 250, // maximum display number of characters in a table cell
+		tableSelectPage : true, // selection of complete table pages
+		tableSelectAll : false, // selection of complete tables
+		tableShowSelected : true, // show selected objects only option
+		tableKeepShowSelected : true, // don't revert to show all on "reset" (e.g. selection)
+		tableInvertSelection : true, // show invert selection option
+		tableSelectByText : true, // select objects by full-text search
+		tableCreateNewFromSelected : true, // create new dataset from selected objects
+		unselectedCellColor : '#EEE', // color for an unselected row/tab
+		verticalAlign : 'top', // vertical alignment of the table cells ('top','center','bottom')
+	};
+	if ( typeof options != 'undefined') {
+		$.extend(this.options, options);
+	}
+
+};
+/*
+* TableGui.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class TableGui
+ * Table GUI Implementation
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ *
+ * @param {TableWidget} parent table widget object
+ * @param {HTML object} div parent div to append the table gui
+ * @param {JSON} options table configuration
+ */
+function TableGui(table, div, options) {
+
+	this.tableContainer = div;
+	if (options.tableWidth) {
+		this.tableContainer.style.width = options.tableWidth;
+	}
+	if (options.tableHeight) {
+		this.tableContainer.style.height = options.tableHeight;
+	}
+	this.tableContainer.style.position = 'relative';
+
+	this.tabs = document.createElement('div');
+	this.tabs.setAttribute('class', 'tableTabs');
+	div.appendChild(this.tabs);
+
+	this.input = document.createElement('div');
+	this.input.setAttribute('class', 'tableInput');
+	div.appendChild(this.input);
+
+};
 /*
 * TableWidget.js
 *
@@ -43583,500 +43588,500 @@
 	Publisher.Publish('dataobjectAfterCreation', this);
 };
 
-/*
-* Dataset.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class Dataset
- * GeoTemCo's Dataset class
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- *
- * @param {Array} objects data item arrays from different datasets
- * @param {String} label label for the datasets
- */
-Dataset = function(objects, label, url, type) {
-
-	this.objects = objects;
-	this.label = label;
-	this.url = url;
-	this.type = type;
-	
-	this.color;
-	
-	//if the user can change shapes, every dataset needs a default shape
-	if (GeoTemConfig.allowUserShapeAndColorChange){
-		this.graphic={
-				shape: "circle",
-				rotation: 0
-		}
-	}
-	
-	Publisher.Publish('datasetAfterCreation', this);
-}
-/*
-* TimeDataSource.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class TimeDataSource, TimeSlice, TimeStack
- * implementation for aggregation of time items
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- *
- * @param {JSON} options time configuration
- */
-function TimeDataSource(options) {
-
-	this.options = options;
-	this.timeSlices = [];
-	this.unit
-	this.minDate
-	this.maxDate
-	this.eventSources
-	this.events
-	this.leftSlice
-	this.rightSlice
-
-	this.hashMapping
-
-};
-
-TimeDataSource.prototype = {
-
-	findTimeUnits : function(granularity, timeUnit, pixels) {
-
-		var time = SimileAjax.DateTime;
-		this.availableUnits = [];
-		var givenUnits = SimileAjax.DateTime.gregorianUnitLengths;
-		for (var i = 0; i < givenUnits.length; i++) {
-			if (granularity > i) {
-				continue;
-			}
-			var slices = 0;
-			var t = new Date(this.minDate.getTime());
-			do {
-				time.roundDownToInterval(t, i, undefined, 1, 0);
-				slices++;
-				time.incrementByInterval(t, i, undefined);
-			} while( t.getTime() <= this.maxDate.getTime() && slices < pixels+2 );
-			if (slices > 0 && slices <= pixels) {
-				this.availableUnits.push({
-					unit : i,
-					slices : slices,
-					label : SimileAjax.DateTime.Strings[GeoTemConfig.language][i]
-				});
-			}
-		}
-		var unitDiff200 = pixels + 1;
-		for (var i = 0; i < this.availableUnits.length; i++) {
-			var diff = Math.abs(this.availableUnits[i].slices - 200);
-			if (diff < unitDiff200) {
-				unitDiff200 = diff;
-				this.unit = this.availableUnits[i].unit;
-			}
-		}
-
-	},
-
-	getUnitIndex : function() {
-		for (var i = 0; i < this.availableUnits.length; i++) {
-			if (this.unit == this.availableUnits[i].unit) {
-				return i;
-			}
-		}
-		return 0;
-	},
-
-	setTimeUnit : function(unit) {
-		this.unit = unit;
-		this.initializeSlices();
-	},
-
-	/**
-	 * initializes the TimeDataSource
-	 * @param {Timeplot.ColumnSource[]} dataSources the column sources corresponding to the data sets
-	 * @param {Timeplot.DefaultEventSource[]} eventSources the event sources corresponding to the column sources
-	 * @param {TimeObject[][]} timeObjects an array of time objects of different sets
-	 * @param {SimileAjax.DateTime} granularity the time granularity of the given data
-	 */
-	initialize : function(dataSources, eventSources, timeObjects, granularity, timeUnit, pixels) {
-
-		this.dataSources = dataSources;
-		this.eventSources = eventSources;
-		this.timeObjects = timeObjects;
-
-		this.minDate = undefined;
-		this.maxDate = undefined;
-		this.hashMapping = [];
-		this.projHashMapping = [];
-
-		for (var i = 0; i < timeObjects.length; i++) {
-			this.hashMapping.push([]);
-			this.projHashMapping.push([]);
-			for (var j = 0; j < timeObjects[i].length; j++) {
-				var o = timeObjects[i][j];
-				if (o.isTemporal) {
-					var g = o.dates[this.options.timeIndex].granularity;
-					//o.getTimeGranularity(this.options.timeIndex);
-					if (g == null) {
-						continue;
-					}
-					var time = o.dates[this.options.timeIndex].date;
-					//o.getDate(this.options.timeIndex);
-					if (this.minDate == undefined || time.getTime() < this.minDate.getTime()) {
-						this.minDate = time;
-					}
-					if (this.maxDate == undefined || time.getTime() > this.maxDate.getTime()) {
-						this.maxDate = time;
-					}
-				}
-			}
-		}
-
-		if (this.minDate == undefined) {
-			this.minDate = this.options.defaultMinDate;
-			this.maxDate = this.options.defaultMaxDate;
-		}
-
-		this.findTimeUnits(granularity, timeUnit, pixels);
-		this.initializeSlices();
-
-	},
-
-	initializeSlices : function() {
-		for (var i = 0; i < this.dataSources.length; i++) {
-			this.dataSources[i]._range = {
-				earliestDate : null,
-				latestDate : null,
-				min : 0,
-				max : 0
-			};
-		}
-		this.timeSlices = [];
-		var time = SimileAjax.DateTime;
-		var t = new Date(this.minDate.getTime() - 0.9 * time.gregorianUnitLengths[this.unit]);
-		do {
-			time.roundDownToInterval(t, this.unit, undefined, 1, 0);
-			var slice = new TimeSlice(SimileAjax.NativeDateUnit.cloneValue(t), this.timeObjects.length, this.dataSources.length);
-			this.timeSlices.push(slice);
-			time.incrementByInterval(t, this.unit, undefined);
-		} while (t.getTime() <= this.maxDate.getTime() + 1.1 * time.gregorianUnitLengths[this.unit]);
-
-		for (var i = 0; i < this.timeObjects.length; i++) {
-			var projId = i;
-			if( this.dataSources.length == 1 ){
-				projId = 0;
-			}
-			for (var j = 0; j < this.timeObjects[i].length; j++) {
-				var o = this.timeObjects[i][j];
-				if (o.isTemporal) {
-					var date = o.dates[this.options.timeIndex].date;
-					//o.getDate(this.options.timeIndex);
-					for (var k = 0; k < this.timeSlices.length - 1; k++) {
-						var t1 = this.timeSlices[k].date.getTime();
-						var t2 = this.timeSlices[k + 1].date.getTime();
-						var stack = null, projStack = null;
-						if (date >= t1 && date < t2) {
-							stack = this.timeSlices[k].getStack(i);
-							projStack = this.timeSlices[k].getProjStack(projId);
-						}
-						if (k == this.timeSlices.length - 2 && date >= t2) {
-							stack = this.timeSlices[k + 1].getStack(i);
-							projStack = this.timeSlices[k + 1].getProjStack(projId);
-						}
-						if (stack != null) {
-							stack.addObject(o);
-							projStack.addObject(o);
-							this.hashMapping[i][o.index] = stack;
-							this.projHashMapping[i][o.index] = projStack;
-							break;
-						}
-					}
-				}
-			}
-		}
-
-		this.events = [];
-		for (var i = 0; i < this.eventSources.length; i++) {
-			var eventSet = [];
-			for (var j = 0; j < this.timeSlices.length; j++) {
-				var value = new Array("" + this.timeSlices[j].projStacks[i].value);
-				eventSet.push({
-					date : this.timeSlices[j].date,
-					value : value
-				});
-			}
-			this.eventSources[i].loadData(eventSet);
-			this.events.push(eventSet);
-		}
-
-		this.leftSlice = 0;
-		this.rightSlice = this.timeSlices.length - 1;
-
-	},
-
-	getSliceNumber : function() {
-		return this.timeSlices.length;
-	},
-
-	/**
-	 * computes the slice index corresponding to a given time
-	 * @param {Date} time the given time
-	 * @return the corresponding slice index
-	 */
-	getSliceIndex : function(time) {
-		for (var i = 0; i < this.timeSlices.length; i++) {
-			if (time == this.timeSlices[i].date) {
-				return i;
-			}
-		}
-	},
-
-	/**
-	 * returns the time of a specific time slice
-	 * @param {int} time the given slice index
-	 * @return the corresponding slice date
-	 */
-	getSliceTime : function(index) {
-		return this.timeSlices[index].date;
-	},
-
-	/**
-	 * shifts the actual zoomed range
-	 * @param {int} delta the value to shift (negative for left shift, positive for right shift)
-	 * @return boolean value, if the range could be shifted
-	 */
-	setShift : function(delta) {
-		if (delta == 1 && this.leftSlice != 0) {
-			this.leftSlice--;
-			this.rightSlice--;
-			return true;
-		} else if (delta == -1 && this.rightSlice != this.timeSlices.length - 1) {
-			this.leftSlice++;
-			this.rightSlice++;
-			return true;
-		} else {
-			return false;
-		}
-	},
-
-	/**
-	 * zooms the actual range
-	 * @param {int} delta the value to zoom (negative for zoom out, positive for zoom in)
-	 * @param {Date} time the corresponding time of the actual mouse position on the plot
-	 * @param {Date} leftTime the time of the left border of a selected timerange or null
-	 * @param {Date} rightTime the time of the right border of a selected timerange or null
-	 * @return boolean value, if the range could be zoomed
-	 */
-	setZoom : function(delta, time, leftTime, rightTime) {
-		var n1 = 0;
-		var n2 = 0;
-		var m = -1;
-		if (delta > 0) {
-			m = 1;
-			if (leftTime != null) {
-				n1 = this.getSliceIndex(leftTime) - this.leftSlice;
-				n2 = this.rightSlice - this.getSliceIndex(rightTime);
-			} else {
-				slice = this.getSliceIndex(time);
-				if (slice == this.leftSlice || slice == this.rightSlice) {
-					return;
-				}
-				n1 = slice - 1 - this.leftSlice;
-				n2 = this.rightSlice - slice - 1;
-			}
-		} else if (delta < 0) {
-
-			n1 = this.leftSlice;
-			n2 = this.timeSlices.length - 1 - this.rightSlice;
-		}
-
-		var zoomSlices = 2 * delta;
-		if (Math.abs(n1 + n2) < Math.abs(zoomSlices)) {
-			zoomSlices = n1 + n2;
-		}
-
-		if (n1 + n2 == 0) {
-			return false;
-		}
-
-		var m1 = Math.round(n1 / (n1 + n2) * zoomSlices);
-		var m2 = zoomSlices - m1;
-
-		this.leftSlice += m1;
-		this.rightSlice -= m2;
-
-		return true;
-	},
-
-	/**
-	 * resets the plots by loading data of actual zoomed range
-	 */
-	reset : function(timeGeometry) {
-		for (var i = 0; i < this.eventSources.length; i++) {
-			this.eventSources[i].loadData(this.events[i].slice(this.leftSlice, this.rightSlice + 1));
-			if (i + 1 < this.eventSources.length) {
-				timeGeometry._earliestDate = null;
-				timeGeometry._latestDate = null;
-			}
-
-		}
-	},
-
-	/**
-	 * Getter for actual zoom
-	 * @return actual zoom value
-	 */
-	getZoom : function() {
-		if (this.timeSlices == undefined) {
-			return 0;
-		}
-		return Math.round((this.timeSlices.length - 3) / 2) - Math.round((this.rightSlice - this.leftSlice - 2) / 2);
-	},
-
-	/**
-	 * Getter for date of the first timeslice
-	 * @return date of the first timeslice
-	 */
-	earliest : function() {
-		return this.timeSlices[0].date;
-	},
-
-	/**
-	 * Getter for date of the last timeslice
-	 * @return date of the last timeslice
-	 */
-	latest : function() {
-		return this.timeSlices[this.timeSlices.length - 1].date;
-	},
-
-	setOverlay : function(timeObjects) {
-		for (var i = 0; i < this.timeSlices.length; i++) {
-			this.timeSlices[i].reset();
-		}
-		for (var j in timeObjects ) {
-			for (var k in timeObjects[j] ) {
-				var o = timeObjects[j][k];
-				if (o.isTemporal) {
-					if (o.getTimeGranularity(this.options.timeIndex) == null) {
-						continue;
-					}
-					this.hashMapping[j][o.index].overlay += o.weight;
-					this.projHashMapping[j][o.index].overlay += o.weight;
-				}
-			}
-		}
-	},
-
-	size : function() {
-		if (this.timeSlices.length == 0) {
-			return 0;
-		}
-		return this.timeSlices[0].stacks.length;
-	}
-};
-
-/**
- * small class that represents a time slice of the actual timeplot.
- * it has a specific date and contains its corrsponding data objects as well
- */
-function TimeSlice(date, rows, projRows) {
-
-	this.date = date;
-	this.selected = false;
-
-	this.stacks = [];
-	this.projStacks = [];
-	for (var i = 0; i < rows; i++) {
-		this.stacks.push(new TimeStack());
-	}
-	for (var i = 0; i < projRows; i++) {
-		this.projStacks.push(new TimeStack());
-	}
-
-	this.getStack = function(row) {
-		return this.stacks[row];
-	};
-
-	this.getProjStack = function(row) {
-		return this.projStacks[row];
-	};
-
-	this.reset = function() {
-		for (var i in this.projStacks ) {
-			this.stacks[i].overlay = 0;
-			this.projStacks[i].overlay = 0;
-		}
-	};
-
-	this.overlay = function() {
-		var value = 0;
-		for (var i in this.projStacks ) {
-			if (this.projStacks[i].overlay > value) {
-				value = this.projStacks[i].overlay;
-			}
-		}
-		return value;
-	};
-
-};
-
-/**
- * small class that represents a stack for a time slice which
- * holds items for different datasets for the specific time range
- */
-function TimeStack() {
-
-	this.overlay = 0;
-	this.value = 0;
-	this.elements = [];
-
-	this.addObject = function(object) {
-		this.elements.push(object);
-		this.value += object.weight;
-	};
-
-};
+/*
+* Dataset.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class Dataset
+ * GeoTemCo's Dataset class
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ *
+ * @param {Array} objects data item arrays from different datasets
+ * @param {String} label label for the datasets
+ */
+Dataset = function(objects, label, url, type) {
+
+	this.objects = objects;
+	this.label = label;
+	this.url = url;
+	this.type = type;
+	
+	this.color;
+	
+	//if the user can change shapes, every dataset needs a default shape
+	if (GeoTemConfig.allowUserShapeAndColorChange){
+		this.graphic={
+				shape: "circle",
+				rotation: 0
+		}
+	}
+	
+	Publisher.Publish('datasetAfterCreation', this);
+}
+/*
+* TimeDataSource.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class TimeDataSource, TimeSlice, TimeStack
+ * implementation for aggregation of time items
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ *
+ * @param {JSON} options time configuration
+ */
+function TimeDataSource(options) {
+
+	this.options = options;
+	this.timeSlices = [];
+	this.unit
+	this.minDate
+	this.maxDate
+	this.eventSources
+	this.events
+	this.leftSlice
+	this.rightSlice
+
+	this.hashMapping
+
+};
+
+TimeDataSource.prototype = {
+
+	findTimeUnits : function(granularity, timeUnit, pixels) {
+
+		var time = SimileAjax.DateTime;
+		this.availableUnits = [];
+		var givenUnits = SimileAjax.DateTime.gregorianUnitLengths;
+		for (var i = 0; i < givenUnits.length; i++) {
+			if (granularity > i) {
+				continue;
+			}
+			var slices = 0;
+			var t = new Date(this.minDate.getTime());
+			do {
+				time.roundDownToInterval(t, i, undefined, 1, 0);
+				slices++;
+				time.incrementByInterval(t, i, undefined);
+			} while( t.getTime() <= this.maxDate.getTime() && slices < pixels+2 );
+			if (slices > 0 && slices <= pixels) {
+				this.availableUnits.push({
+					unit : i,
+					slices : slices,
+					label : SimileAjax.DateTime.Strings[GeoTemConfig.language][i]
+				});
+			}
+		}
+		var unitDiff200 = pixels + 1;
+		for (var i = 0; i < this.availableUnits.length; i++) {
+			var diff = Math.abs(this.availableUnits[i].slices - 200);
+			if (diff < unitDiff200) {
+				unitDiff200 = diff;
+				this.unit = this.availableUnits[i].unit;
+			}
+		}
+
+	},
+
+	getUnitIndex : function() {
+		for (var i = 0; i < this.availableUnits.length; i++) {
+			if (this.unit == this.availableUnits[i].unit) {
+				return i;
+			}
+		}
+		return 0;
+	},
+
+	setTimeUnit : function(unit) {
+		this.unit = unit;
+		this.initializeSlices();
+	},
+
+	/**
+	 * initializes the TimeDataSource
+	 * @param {Timeplot.ColumnSource[]} dataSources the column sources corresponding to the data sets
+	 * @param {Timeplot.DefaultEventSource[]} eventSources the event sources corresponding to the column sources
+	 * @param {TimeObject[][]} timeObjects an array of time objects of different sets
+	 * @param {SimileAjax.DateTime} granularity the time granularity of the given data
+	 */
+	initialize : function(dataSources, eventSources, timeObjects, granularity, timeUnit, pixels) {
+
+		this.dataSources = dataSources;
+		this.eventSources = eventSources;
+		this.timeObjects = timeObjects;
+
+		this.minDate = undefined;
+		this.maxDate = undefined;
+		this.hashMapping = [];
+		this.projHashMapping = [];
+
+		for (var i = 0; i < timeObjects.length; i++) {
+			this.hashMapping.push([]);
+			this.projHashMapping.push([]);
+			for (var j = 0; j < timeObjects[i].length; j++) {
+				var o = timeObjects[i][j];
+				if (o.isTemporal) {
+					var g = o.dates[this.options.timeIndex].granularity;
+					//o.getTimeGranularity(this.options.timeIndex);
+					if (g == null) {
+						continue;
+					}
+					var time = o.dates[this.options.timeIndex].date;
+					//o.getDate(this.options.timeIndex);
+					if (this.minDate == undefined || time.getTime() < this.minDate.getTime()) {
+						this.minDate = time;
+					}
+					if (this.maxDate == undefined || time.getTime() > this.maxDate.getTime()) {
+						this.maxDate = time;
+					}
+				}
+			}
+		}
+
+		if (this.minDate == undefined) {
+			this.minDate = this.options.defaultMinDate;
+			this.maxDate = this.options.defaultMaxDate;
+		}
+
+		this.findTimeUnits(granularity, timeUnit, pixels);
+		this.initializeSlices();
+
+	},
+
+	initializeSlices : function() {
+		for (var i = 0; i < this.dataSources.length; i++) {
+			this.dataSources[i]._range = {
+				earliestDate : null,
+				latestDate : null,
+				min : 0,
+				max : 0
+			};
+		}
+		this.timeSlices = [];
+		var time = SimileAjax.DateTime;
+		var t = new Date(this.minDate.getTime() - 0.9 * time.gregorianUnitLengths[this.unit]);
+		do {
+			time.roundDownToInterval(t, this.unit, undefined, 1, 0);
+			var slice = new TimeSlice(SimileAjax.NativeDateUnit.cloneValue(t), this.timeObjects.length, this.dataSources.length);
+			this.timeSlices.push(slice);
+			time.incrementByInterval(t, this.unit, undefined);
+		} while (t.getTime() <= this.maxDate.getTime() + 1.1 * time.gregorianUnitLengths[this.unit]);
+
+		for (var i = 0; i < this.timeObjects.length; i++) {
+			var projId = i;
+			if( this.dataSources.length == 1 ){
+				projId = 0;
+			}
+			for (var j = 0; j < this.timeObjects[i].length; j++) {
+				var o = this.timeObjects[i][j];
+				if (o.isTemporal) {
+					var date = o.dates[this.options.timeIndex].date;
+					//o.getDate(this.options.timeIndex);
+					for (var k = 0; k < this.timeSlices.length - 1; k++) {
+						var t1 = this.timeSlices[k].date.getTime();
+						var t2 = this.timeSlices[k + 1].date.getTime();
+						var stack = null, projStack = null;
+						if (date >= t1 && date < t2) {
+							stack = this.timeSlices[k].getStack(i);
+							projStack = this.timeSlices[k].getProjStack(projId);
+						}
+						if (k == this.timeSlices.length - 2 && date >= t2) {
+							stack = this.timeSlices[k + 1].getStack(i);
+							projStack = this.timeSlices[k + 1].getProjStack(projId);
+						}
+						if (stack != null) {
+							stack.addObject(o);
+							projStack.addObject(o);
+							this.hashMapping[i][o.index] = stack;
+							this.projHashMapping[i][o.index] = projStack;
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		this.events = [];
+		for (var i = 0; i < this.eventSources.length; i++) {
+			var eventSet = [];
+			for (var j = 0; j < this.timeSlices.length; j++) {
+				var value = new Array("" + this.timeSlices[j].projStacks[i].value);
+				eventSet.push({
+					date : this.timeSlices[j].date,
+					value : value
+				});
+			}
+			this.eventSources[i].loadData(eventSet);
+			this.events.push(eventSet);
+		}
+
+		this.leftSlice = 0;
+		this.rightSlice = this.timeSlices.length - 1;
+
+	},
+
+	getSliceNumber : function() {
+		return this.timeSlices.length;
+	},
+
+	/**
+	 * computes the slice index corresponding to a given time
+	 * @param {Date} time the given time
+	 * @return the corresponding slice index
+	 */
+	getSliceIndex : function(time) {
+		for (var i = 0; i < this.timeSlices.length; i++) {
+			if (time == this.timeSlices[i].date) {
+				return i;
+			}
+		}
+	},
+
+	/**
+	 * returns the time of a specific time slice
+	 * @param {int} time the given slice index
+	 * @return the corresponding slice date
+	 */
+	getSliceTime : function(index) {
+		return this.timeSlices[index].date;
+	},
+
+	/**
+	 * shifts the actual zoomed range
+	 * @param {int} delta the value to shift (negative for left shift, positive for right shift)
+	 * @return boolean value, if the range could be shifted
+	 */
+	setShift : function(delta) {
+		if (delta == 1 && this.leftSlice != 0) {
+			this.leftSlice--;
+			this.rightSlice--;
+			return true;
+		} else if (delta == -1 && this.rightSlice != this.timeSlices.length - 1) {
+			this.leftSlice++;
+			this.rightSlice++;
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	 * zooms the actual range
+	 * @param {int} delta the value to zoom (negative for zoom out, positive for zoom in)
+	 * @param {Date} time the corresponding time of the actual mouse position on the plot
+	 * @param {Date} leftTime the time of the left border of a selected timerange or null
+	 * @param {Date} rightTime the time of the right border of a selected timerange or null
+	 * @return boolean value, if the range could be zoomed
+	 */
+	setZoom : function(delta, time, leftTime, rightTime) {
+		var n1 = 0;
+		var n2 = 0;
+		var m = -1;
+		if (delta > 0) {
+			m = 1;
+			if (leftTime != null) {
+				n1 = this.getSliceIndex(leftTime) - this.leftSlice;
+				n2 = this.rightSlice - this.getSliceIndex(rightTime);
+			} else {
+				slice = this.getSliceIndex(time);
+				if (slice == this.leftSlice || slice == this.rightSlice) {
+					return;
+				}
+				n1 = slice - 1 - this.leftSlice;
+				n2 = this.rightSlice - slice - 1;
+			}
+		} else if (delta < 0) {
+
+			n1 = this.leftSlice;
+			n2 = this.timeSlices.length - 1 - this.rightSlice;
+		}
+
+		var zoomSlices = 2 * delta;
+		if (Math.abs(n1 + n2) < Math.abs(zoomSlices)) {
+			zoomSlices = n1 + n2;
+		}
+
+		if (n1 + n2 == 0) {
+			return false;
+		}
+
+		var m1 = Math.round(n1 / (n1 + n2) * zoomSlices);
+		var m2 = zoomSlices - m1;
+
+		this.leftSlice += m1;
+		this.rightSlice -= m2;
+
+		return true;
+	},
+
+	/**
+	 * resets the plots by loading data of actual zoomed range
+	 */
+	reset : function(timeGeometry) {
+		for (var i = 0; i < this.eventSources.length; i++) {
+			this.eventSources[i].loadData(this.events[i].slice(this.leftSlice, this.rightSlice + 1));
+			if (i + 1 < this.eventSources.length) {
+				timeGeometry._earliestDate = null;
+				timeGeometry._latestDate = null;
+			}
+
+		}
+	},
+
+	/**
+	 * Getter for actual zoom
+	 * @return actual zoom value
+	 */
+	getZoom : function() {
+		if (this.timeSlices == undefined) {
+			return 0;
+		}
+		return Math.round((this.timeSlices.length - 3) / 2) - Math.round((this.rightSlice - this.leftSlice - 2) / 2);
+	},
+
+	/**
+	 * Getter for date of the first timeslice
+	 * @return date of the first timeslice
+	 */
+	earliest : function() {
+		return this.timeSlices[0].date;
+	},
+
+	/**
+	 * Getter for date of the last timeslice
+	 * @return date of the last timeslice
+	 */
+	latest : function() {
+		return this.timeSlices[this.timeSlices.length - 1].date;
+	},
+
+	setOverlay : function(timeObjects) {
+		for (var i = 0; i < this.timeSlices.length; i++) {
+			this.timeSlices[i].reset();
+		}
+		for (var j in timeObjects ) {
+			for (var k in timeObjects[j] ) {
+				var o = timeObjects[j][k];
+				if (o.isTemporal) {
+					if (o.getTimeGranularity(this.options.timeIndex) == null) {
+						continue;
+					}
+					this.hashMapping[j][o.index].overlay += o.weight;
+					this.projHashMapping[j][o.index].overlay += o.weight;
+				}
+			}
+		}
+	},
+
+	size : function() {
+		if (this.timeSlices.length == 0) {
+			return 0;
+		}
+		return this.timeSlices[0].stacks.length;
+	}
+};
+
+/**
+ * small class that represents a time slice of the actual timeplot.
+ * it has a specific date and contains its corrsponding data objects as well
+ */
+function TimeSlice(date, rows, projRows) {
+
+	this.date = date;
+	this.selected = false;
+
+	this.stacks = [];
+	this.projStacks = [];
+	for (var i = 0; i < rows; i++) {
+		this.stacks.push(new TimeStack());
+	}
+	for (var i = 0; i < projRows; i++) {
+		this.projStacks.push(new TimeStack());
+	}
+
+	this.getStack = function(row) {
+		return this.stacks[row];
+	};
+
+	this.getProjStack = function(row) {
+		return this.projStacks[row];
+	};
+
+	this.reset = function() {
+		for (var i in this.projStacks ) {
+			this.stacks[i].overlay = 0;
+			this.projStacks[i].overlay = 0;
+		}
+	};
+
+	this.overlay = function() {
+		var value = 0;
+		for (var i in this.projStacks ) {
+			if (this.projStacks[i].overlay > value) {
+				value = this.projStacks[i].overlay;
+			}
+		}
+		return value;
+	};
+
+};
+
+/**
+ * small class that represents a stack for a time slice which
+ * holds items for different datasets for the specific time range
+ */
+function TimeStack() {
+
+	this.overlay = 0;
+	this.value = 0;
+	this.elements = [];
+
+	this.addObject = function(object) {
+		this.elements.push(object);
+		this.value += object.weight;
+	};
+
+};
 /*
 * Binning.js
 *
@@ -44945,950 +44950,950 @@
 		return this.hashMapping[zoom][index][id];
 	}
 };
-/*
-* Clustering.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class Vertex, Edge, Triangle, Clustering, BinaryHeap
- * Dynamic Delaunay clustering algorithm (see GeoTemCo paper)
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-
-function Vertex(x, y, categories, binning) {
-	this.x = x;
-	this.y = y;
-	this.radius
-	this.size = 0;
-	this.elements = [];
-	this.radii = [];
-	this.weights = [];
-	this.legal = true;
-	this.binning = binning;
-	if (categories != undefined) {
-		for (var i = 0; i < categories; i++) {
-			this.elements.push([]);
-			this.weights.push(0);
-		}
-	}
-}
-
-Vertex.prototype.merge = function(v0, v1) {
-	for (var i = 0; i < v0.elements.length; i++) {
-		this.elements[i] = v0.elements[i].concat(v1.elements[i]);
-		this.weights[i] = v0.weights[i] + v1.weights[i];
-		this.size += this.weights[i];
-	}
-}
-
-Vertex.prototype.CalculateRadius = function(resolution) {
-	this.radii = [];
-	for (i in this.elements ) {
-		this.radii.push(this.binning.getRadius(this.weights[i]));
-	}
-	if (this.radii.length == 1) {
-		this.radius = this.radii[0] * resolution;
-	} else {
-		var count = 0;
-		var max1 = 0;
-		var max2 = 0;
-		for (i in this.radii ) {
-			if (this.radii[i] != 0) {
-				count++;
-			}
-			if (this.radii[i] > max1) {
-				if (max1 > max2) {
-					max2 = max1;
-				}
-				max1 = this.radii[i];
-			} else if (this.radii[i] > max2) {
-				max2 = this.radii[i];
-			}
-		}
-		if (count == 1) {
-			this.radius = max1 * resolution;
-		} else if (count == 2) {
-			this.radius = (max1 + max2) * resolution;
-		} else if (count == 3) {
-			var d = (2 / 3 * Math.sqrt(3) - 1) * max1;
-			this.radius = (d + max1 + max2) * resolution;
-		} else if (count == 4) {
-			var d = (Math.sqrt(2) - 1) * max2;
-			this.radius = (d + max1 + max2) * resolution;
-		}
-	}
-}
-
-Vertex.prototype.addElement = function(e, weight, index) {
-	this.elements[index].push(e);
-	this.size += weight;
-	this.weights[index] += weight;
-}
-function Edge(v0, v1) {
-	this.v0 = v0;
-	this.v1 = v1;
-	this.leftFace
-	this.rightFace
-	this.legal = true;
-	this.setLength();
-}
-
-Edge.prototype.setLength = function() {
-	var dx = this.v0.x - this.v1.x;
-	var dy = this.v0.y - this.v1.y;
-	this.length = Math.sqrt(dx * dx + dy * dy);
-}
-
-Edge.prototype.contains = function(v) {
-	if (this.v0 == v || this.v1 == v) {
-		return true;
-	}
-	return false;
-}
-
-Edge.prototype.replaceFace = function(f_old, f_new) {
-	if (this.leftFace == f_old) {
-		this.leftFace = f_new;
-	} else if (this.rightFace == f_old) {
-		this.rightFace = f_new;
-	}
-}
-
-Edge.prototype.setFace = function(f) {
-	if (f.leftOf(this)) {
-		this.leftFace = f;
-	} else {
-		this.rightFace = f;
-	}
-}
-
-Edge.prototype.setFaces = function(f1, f2) {
-	if (f1.leftOf(this)) {
-		this.leftFace = f1;
-		this.rightFace = f2;
-	} else {
-		this.leftFace = f2;
-		this.rightFace = f1;
-	}
-}
-
-Edge.prototype.removeFace = function(f) {
-	if (this.leftFace == f) {
-		this.leftFace = null;
-	} else {
-		this.rightFace = null;
-	}
-}
-
-Edge.prototype.equals = function(e) {
-	if (this.v0 == e.v0 && this.v1 == e.v1 || this.v0 == e.v1 && this.v1 == e.v0) {
-		return true;
-	}
-	return false;
-}
-function Triangle(edges) {
-	this.edges = edges;
-	this.setVertices();
-	this.descendants = [];
-}
-
-Triangle.prototype.getTriple = function(e) {
-	var i = arrayIndex(this.edges, e);
-	return {
-		e_s : this.edges[(i + 1) % 3],
-		e_p : this.edges[(i + 2) % 3],
-		u : this.vertices[(i + 2) % 3]
-	};
-}
-
-Triangle.prototype.leftOf = function(e) {
-	var i = arrayIndex(this.edges, e);
-	if (this.vertices[i].y != this.vertices[(i + 1) % 3].y) {
-		return this.vertices[i].y > this.vertices[(i + 1) % 3].y;
-	}
-	return this.vertices[i].y > this.vertices[(i + 2) % 3].y;
-}
-
-Triangle.prototype.getNext = function(v) {
-	var i = arrayIndex(this.vertices, v);
-	return this.vertices[(i + 1) % 3];
-}
-
-Triangle.prototype.oppositeEdge = function(v) {
-	var i = arrayIndex(this.vertices, v);
-	return this.edges[(i + 1) % 3];
-}
-
-Triangle.prototype.contains = function(v) {
-	return arrayIndex(this.vertices, v) != -1;
-}
-
-Triangle.prototype.replace = function(e_old, e_new) {
-	this.edges[arrayIndex(this.edges, e_old)] = e_new;
-}
-
-Triangle.prototype.setVertices = function() {
-	if (this.edges[1].v0 == this.edges[0].v0 || this.edges[1].v1 == this.edges[0].v0) {
-		this.vertices = [this.edges[0].v1, this.edges[0].v0];
-	} else {
-		this.vertices = [this.edges[0].v0, this.edges[0].v1];
-	}
-	if (this.edges[2].v0 == this.vertices[0]) {
-		this.vertices.push(this.edges[2].v1);
-	} else {
-		this.vertices.push(this.edges[2].v0);
-	}
-}
-
-Triangle.prototype.replaceBy = function(triangles) {
-	this.descendants = triangles;
-	this.edges[0].replaceFace(this, triangles[0]);
-	this.edges[1].replaceFace(this, triangles[1]);
-	this.edges[2].replaceFace(this, triangles[2]);
-}
-
-Triangle.prototype.CalcCircumcircle = function() {
-	var v0 = this.vertices[0];
-	var v1 = this.vertices[1];
-	var v2 = this.vertices[2];
-	var A = v1.x - v0.x;
-	var B = v1.y - v0.y;
-	var C = v2.x - v0.x;
-	var D = v2.y - v0.y;
-	var E = A * (v0.x + v1.x) + B * (v0.y + v1.y);
-	var F = C * (v0.x + v2.x) + D * (v0.y + v2.y);
-	var G = 2.0 * (A * (v2.y - v1.y) - B * (v2.x - v1.x));
-	var cx = (D * E - B * F) / G;
-	var cy = (A * F - C * E) / G;
-	this.center = new Vertex(cx, cy);
-	var dx = this.center.x - v0.x;
-	var dy = this.center.y - v0.y;
-	this.radius_squared = dx * dx + dy * dy;
-};
-
-Triangle.prototype.inCircumcircle = function(v) {
-	if (this.radius_squared == undefined) {
-		this.CalcCircumcircle();
-	}
-	var dx = this.center.x - v.x;
-	var dy = this.center.y - v.y;
-	var dist_squared = dx * dx + dy * dy;
-	return (dist_squared <= this.radius_squared );
-};
-
-Triangle.prototype.interior = function(v) {
-	var v0 = this.vertices[0];
-	var v1 = this.vertices[1];
-	var v2 = this.vertices[2];
-	var dotAB = (v.x - v0.x ) * (v0.y - v1.y ) + (v.y - v0.y ) * (v1.x - v0.x );
-	var dotBC = (v.x - v1.x ) * (v1.y - v2.y ) + (v.y - v1.y ) * (v2.x - v1.x );
-	var dotCA = (v.x - v2.x ) * (v2.y - v0.y ) + (v.y - v2.y ) * (v0.x - v2.x );
-	if (dotAB > 0 || dotBC > 0 || dotCA > 0) {
-		return null;
-	} else if (dotAB < 0 && dotBC < 0 && dotCA < 0) {
-		return this;
-	} else if (dotAB == 0) {
-		if (dotBC == 0) {
-			return this.vertices[1];
-		} else if (dotCA == 0) {
-			return this.vertices[0];
-		}
-		return this.edges[0];
-	} else if (dotBC == 0) {
-		if (dotCA == 0) {
-			return this.vertices[2];
-		}
-		return this.edges[1];
-	} else if (dotCA == 0) {
-		return this.edges[2];
-	}
-};
-
-function Clustering(xMin, yMin, xMax, yMax) {
-	this.triangles = [];
-	this.newTriangles = [];
-	this.bbox = {
-		x1 : xMin,
-		y1 : yMin,
-		x2 : xMax,
-		y2 : yMax
-	};
-	this.CreateBoundingTriangle();
-	this.edges = [];
-	this.vertices = [];
-	this.legalizes = 0;
-	this.collapses = 0;
-}
-
-Clustering.prototype.locate = function(v) {
-	if (this.boundingTriangle.descendants.length == 0) {
-		return this.boundingTriangle;
-	}
-	var triangles = this.boundingTriangle.descendants;
-	while (true) {
-		for (var i = 0; i < triangles.length; i++) {
-			var simplex = triangles[i].interior(v);
-			if (simplex == null) {
-				continue;
-			}
-			if ( simplex instanceof Vertex || this.isLeaf(triangles[i])) {
-				return simplex;
-			}
-			triangles = triangles[i].descendants;
-			break;
-		}
-	}
-}
-
-Clustering.prototype.legalize = function(v, e, t0_old) {
-	if (!e.v0.legal && !e.v1.legal) {
-		return;
-	}
-	this.legalizes++;
-	var flip = false;
-	var t1_old, tr1;
-	if (e.leftFace == t0_old && e.rightFace.inCircumcircle(v)) {
-		flip = true;
-		t1_old = e.rightFace;
-	} else if (e.rightFace == t0_old && e.leftFace.inCircumcircle(v)) {
-		flip = true;
-		t1_old = e.leftFace;
-	}
-	if (flip) {
-		var tr0 = t0_old.getTriple(e);
-		var tr1 = t1_old.getTriple(e);
-		var e_flip = new Edge(tr0.u, tr1.u);
-		var poly = [];
-		poly.push(e.v0);
-		poly.push(e_flip.v0);
-		poly.push(e.v1);
-		poly.push(e_flip.v1);
-		if (!this.JordanTest(poly, e_flip)) {
-			return;
-		}
-		e.legal = false;
-		this.edges.push(e_flip);
-		var t0_new = new Triangle([e_flip, tr0.e_p, tr1.e_s]);
-		var t1_new = new Triangle([e_flip, tr1.e_p, tr0.e_s]);
-		e_flip.setFaces(t0_new, t1_new);
-		tr0.e_p.replaceFace(t0_old, t0_new);
-		tr1.e_s.replaceFace(t1_old, t0_new);
-		tr1.e_p.replaceFace(t1_old, t1_new);
-		tr0.e_s.replaceFace(t0_old, t1_new);
-		t0_old.descendants = [t0_new, t1_new];
-		t1_old.descendants = [t0_new, t1_new];
-		this.legalize(v, t0_new.edges[2], t0_new);
-		this.legalize(v, t1_new.edges[1], t1_new);
-	}
-}
-
-Clustering.prototype.add = function(v) {
-	this.addVertex(v, this.locate(v));
-}
-
-Clustering.prototype.addVertex = function(v, simplex) {
-	if ( simplex instanceof Vertex) {
-		simplex.merge(simplex, v);
-	} else if ( simplex instanceof Edge) {
-		this.vertices.push(v);
-		simplex.legal = false;
-		var tr0 = simplex.leftFace.getTriple(simplex);
-		var tr1 = simplex.rightFace.getTriple(simplex);
-		var e0 = new Edge(v, tr0.u);
-		var e1 = new Edge(v, simplex.leftFace.getNext(tr0.u));
-		var e2 = new Edge(v, tr1.u);
-		var e3 = new Edge(v, simplex.rightFace.getNext(tr1.u));
-		var t0 = new Triangle([e0, tr0.e_p, e1]);
-		var t1 = new Triangle([e1, tr1.e_s, e2]);
-		var t2 = new Triangle([e2, tr1.e_p, e3]);
-		var t3 = new Triangle([e3, tr0.e_s, e0]);
-		simplex.leftFace.descendants = [t0, t3];
-		simplex.rightFace.descendants = [t1, t2];
-		this.edges.push(e0);
-		this.edges.push(e1);
-		this.edges.push(e2);
-		this.edges.push(e3);
-		e0.setFaces(t0, t3);
-		e1.setFaces(t0, t1);
-		e2.setFaces(t1, t2);
-		e3.setFaces(t2, t3);
-		tr0.e_p.replaceFace(simplex.leftFace, t0);
-		tr1.e_s.replaceFace(simplex.rightFace, t1);
-		tr1.e_p.replaceFace(simplex.rightFace, t2);
-		tr0.e_s.replaceFace(simplex.leftFace, t3);
-		this.legalize(v, tr0.e_p, t0);
-		this.legalize(v, tr1.e_s, t1);
-		this.legalize(v, tr1.e_p, t2);
-		this.legalize(v, tr0.e_s, t3);
-	} else {
-		this.vertices.push(v);
-		var e_i = new Edge(simplex.vertices[0], v);
-		var e_j = new Edge(simplex.vertices[1], v);
-		var e_k = new Edge(simplex.vertices[2], v);
-		this.edges.push(e_i);
-		this.edges.push(e_j);
-		this.edges.push(e_k);
-		var t0 = new Triangle([e_i, simplex.edges[0], e_j]);
-		var t1 = new Triangle([e_j, simplex.edges[1], e_k]);
-		var t2 = new Triangle([e_k, simplex.edges[2], e_i]);
-		e_i.setFaces(t0, t2);
-		e_j.setFaces(t0, t1);
-		e_k.setFaces(t1, t2);
-		simplex.replaceBy([t0, t1, t2]);
-		this.legalize(v, simplex.edges[0], t0);
-		this.legalize(v, simplex.edges[1], t1);
-		this.legalize(v, simplex.edges[2], t2);
-	}
-}
-
-Clustering.prototype.isLeaf = function(t) {
-	return t.descendants.length == 0;
-}
-
-Clustering.prototype.CreateBoundingTriangle = function() {
-	var dx = (this.bbox.x2 - this.bbox.x1 ) * 10;
-	var dy = (this.bbox.y2 - this.bbox.y1 ) * 10;
-	var v0 = new Vertex(this.bbox.x1 - dx, this.bbox.y1 - dy * 3);
-	var v1 = new Vertex(this.bbox.x2 + dx * 3, this.bbox.y2 + dy);
-	var v2 = new Vertex(this.bbox.x1 - dx, this.bbox.y2 + dy);
-	var e0 = new Edge(v1, v0);
-	var e1 = new Edge(v0, v2);
-	var e2 = new Edge(v2, v1);
-	v0.legal = false;
-	v1.legal = false;
-	v2.legal = false;
-	this.boundingTriangle = new Triangle([e0, e1, e2]);
-	var inf = new Triangle([e0, e1, e2]);
-	e0.setFaces(this.boundingTriangle, inf);
-	e1.setFaces(this.boundingTriangle, inf);
-	e2.setFaces(this.boundingTriangle, inf);
-}
-
-Clustering.prototype.mergeVertices = function(e) {
-	this.collapses++;
-	var s0 = e.v0.size;
-	var s1 = e.v1.size;
-	var x = (e.v0.x * s0 + e.v1.x * s1 ) / (s0 + s1 );
-	var y = (e.v0.y * s0 + e.v1.y * s1 ) / (s0 + s1 );
-	var v = new Vertex(x, y, e.v0.elements.length, e.v0.binning);
-	v.merge(e.v0, e.v1);
-
-	e.v0.legal = false;
-	e.v1.legal = false;
-
-	var hole = [];
-	var oldFacets = [];
-	e.legal = false;
-
-	var vertices = [];
-	var traverse = function(eLeft, eRight, triangle) {
-		eLeft.legal = false;
-		do {
-			var triple;
-			if (eLeft.leftFace == triangle) {
-				triple = eLeft.rightFace.getTriple(eLeft);
-				oldFacets.push(eLeft.rightFace);
-				triple.e_s.removeFace(eLeft.rightFace);
-				triangle = eLeft.rightFace;
-			} else {
-				triple = eLeft.leftFace.getTriple(eLeft);
-				oldFacets.push(eLeft.leftFace);
-				triple.e_s.removeFace(eLeft.leftFace);
-				triangle = eLeft.leftFace;
-			}
-			if (arrayIndex(hole, triple.e_s) == -1) {
-				hole.push(triple.e_s);
-			}
-			vertices.push(triple.u);
-			eLeft = triple.e_p;
-			eLeft.legal = false;
-		} while( eLeft != eRight );
-	}
-	var tr0 = e.leftFace.getTriple(e);
-	var tr1 = e.rightFace.getTriple(e);
-	oldFacets.push(e.leftFace);
-	oldFacets.push(e.rightFace);
-	traverse(tr0.e_p, tr1.e_s, e.leftFace);
-	traverse(tr1.e_p, tr0.e_s, e.rightFace);
-
-	var hd = new Clustering(this.bbox.x1 - 10, this.bbox.y1 - 10, this.bbox.x2 + 10, this.bbox.y2 + 10);
-	var hull = [];
-	for (var i in hole ) {
-		if (!(hole[i].leftFace == null && hole[i].rightFace == null)) {
-			hull.push(hole[i].v0);
-			hull.push(hole[i].v1);
-		}
-	}
-	var hullVertices = [];
-	var distinct = [];
-	for (var i in vertices ) {
-		if (arrayIndex(distinct, vertices[i]) == -1) {
-			hd.add(vertices[i]);
-			distinct.push(vertices[i]);
-		}
-		if (arrayIndex(hull, vertices[i]) != -1) {
-			hullVertices.push(vertices[i]);
-		}
-	}
-
-	var newFacets = [];
-	var isBoundary = function(e) {
-		for (var i = 0; i < hole.length; i++) {
-			if (hole[i].equals(e)) {
-				return i;
-			}
-		}
-		return -1;
-	}
-	var holeEdges = new Array(hole.length);
-	var nonHoleEdges = [];
-
-	for (var i = 0; i < hd.edges.length; i++) {
-		var e = hd.edges[i];
-		var b = isBoundary(e);
-		if (b != -1) {
-			if (!e.legal) {
-				var t1 = e.leftFace.getTriple(e);
-				var t2 = e.rightFace.getTriple(e);
-				var edge = new Edge(t1.u, t2.u);
-				for (var j = 0; j < hd.edges.length; j++) {
-					if (hd.edges[j].equals(edge) && hd.edges[j].legal) {
-						hd.edges[j].legal = false;
-						break;
-					}
-				}
-				t1.e_p.setFace(e.leftFace);
-				t1.e_s.setFace(e.leftFace);
-				t2.e_p.setFace(e.rightFace);
-				t2.e_s.setFace(e.rightFace);
-
-				e.legal = true;
-			}
-			holeEdges[b] = e;
-		} else {
-			nonHoleEdges.push(e);
-		}
-	}
-
-	for (var i = 0; i < holeEdges.length; i++) {
-		var e = holeEdges[i];
-		if (hole[i].leftFace == null) {
-			hole[i].leftFace = e.leftFace;
-			hole[i].leftFace.replace(e, hole[i]);
-			if (arrayIndex(newFacets, hole[i].leftFace) == -1) {
-				newFacets.push(hole[i].leftFace);
-			}
-		}
-		if (hole[i].rightFace == null) {
-			hole[i].rightFace = e.rightFace;
-			hole[i].rightFace.replace(e, hole[i]);
-			if (arrayIndex(newFacets, hole[i].rightFace) == -1) {
-				newFacets.push(hole[i].rightFace);
-			}
-		}
-	}
-
-	for (var i = 0; i < nonHoleEdges.length; i++) {
-		var e = nonHoleEdges[i];
-		if (!e.legal) {
-			continue;
-		}
-		if (this.JordanTest(hullVertices, e)) {
-			this.edges.push(e);
-			if (arrayIndex(newFacets, e.rightFace) == -1) {
-				newFacets.push(e.rightFace);
-			}
-			if (arrayIndex(newFacets, e.leftFace) == -1) {
-				newFacets.push(e.leftFace);
-			}
-		}
-	}
-
-	for (var i in oldFacets ) {
-		oldFacets[i].descendants = newFacets;
-	}
-
-	for (var i = 0; i < newFacets.length; i++) {
-		var simplex = newFacets[i].interior(v);
-		if (simplex == null) {
-			continue;
-		} else {
-			this.addVertex(v, simplex);
-			break;
-		}
-	}
-
-	return v;
-
-}
-
-Clustering.prototype.JordanTest = function(pol, e) {
-	var p = new Vertex((e.v0.x + e.v1.x) * 0.5, (e.v0.y + e.v1.y) * 0.5);
-	var inside = false;
-	var i, j = pol.length - 1;
-	for ( i = 0; i < pol.length; j = i++) {
-		var p1 = pol[i];
-		var p2 = pol[j];
-		if ((((p1.y <= p.y) && (p.y < p2.y)) || ((p2.y <= p.y) && (p.y < p1.y))) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x))
-			inside = !inside;
-	}
-	return inside;
-}
-
-Clustering.prototype.mergeForResolution = function(resolution, circleGap, circleOverlap) {
-	this.deleteEdges = new BinaryHeap(function(e) {
-		return e.weight;
-	});
-	this.weightEdges(resolution, circleGap, circleOverlap);
-	var index = 0;
-	while (this.deleteEdges.size() > 0) {
-		var e = this.deleteEdges.pop();
-		if (e.legal) {
-			var l = this.edges.length;
-			var newVertex = this.mergeVertices(e);
-			newVertex.CalculateRadius(resolution);
-			for (var k = l; k < this.edges.length; k++) {
-				var eNew = this.edges[k];
-				if (eNew.legal) {
-					if( circleGap != 0 ){
-						eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius + circleGap * resolution );
-					}
-					else if( circleOverlap.overlap == 0 ){
-						eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius);
-					}
-					else {
-						var r1 = eNew.v0.radius;
-						var r2 = eNew.v1.radius;
-						var r = eNew.length;
-						if( r < r1 + r2 ){
-							if( circleOverlap.type == 'diameter' ){
-								var ol1 = (r2-(r-r1)) / r1 / 2;
-								var ol2 = (r1-(r-r2)) / r2 / 2;
-								var ol = Math.max(ol1,ol2);
-								eNew.weight = circleOverlap.overlap / ol;
-							}
-							if( circleOverlap.type == 'area' ){								
-								if( !(r+r1 < r2 || r+r2 < r1) ){
-									var A = r2*r2*Math.acos((r*r+r2*r2-r1*r1)/(2*r*r2))+r1*r1*Math.acos((r*r+r1*r1-r2*r2)/(2*r*r1))-1/2*Math.sqrt((-r+r1+r2)*(r-r1+r2)*(r+r1-r2)*(r+r1+r2));
-									var ol1 = A / (Math.PI*r1*r1);
-									var ol2 = A / (Math.PI*r2*r2);
-									var ol = Math.max(ol1,ol2);
-									eNew.weight = circleOverlap.overlap / ol;
-								}
-								else {
-									eNew.weight = 0;
-								}
-							}
-						}
-					}
-					if (eNew.weight < 1) {
-						this.deleteEdges.push(eNew);
-					}
-				}
-			}
-		}
-	}
-}
-
-Clustering.prototype.weightEdges = function(resolution, circleGap, circleOverlap) {
-	for (var i = 0; i < this.vertices.length; i++) {
-		if (this.vertices[i].legal) {
-			this.vertices[i].CalculateRadius(resolution);
-		}
-	}
-	var newEdges = [];
-	for (var i = 0; i < this.edges.length; i++) {
-		var e = this.edges[i];
-		if (e.legal) {
-			if (!e.v0.legal || !e.v1.legal) {
-				e.weight = 1;
-			} else {
-				if( circleGap != 0 ){
-					e.weight = e.length / (e.v0.radius + e.v1.radius + circleGap * resolution );
-				}
-				else if( circleOverlap.overlap == 0 ){
-					e.weight = e.length / (e.v0.radius + e.v1.radius);
-				}
-				else {
-					var r1 = e.v0.radius;
-					var r2 = e.v1.radius;
-					var r = e.length;
-					if( r < r1 + r2 ){
-						if( circleOverlap.type == 'diameter' ){
-							var ol1 = (r2-(r-r1)) / r1 / 2;
-							var ol2 = (r1-(r-r2)) / r2 / 2;
-							var ol = Math.max(ol1,ol2);
-							e.weight = circleOverlap.overlap / ol;
-						}
-						if( circleOverlap.type == 'area' ){
-							if( !(r+r1 < r2 || r+r2 < r1) ){
-								var A = r2*r2*Math.acos((r*r+r2*r2-r1*r1)/(2*r*r2))+r1*r1*Math.acos((r*r+r1*r1-r2*r2)/(2*r*r1))-1/2*Math.sqrt((-r+r1+r2)*(r-r1+r2)*(r+r1-r2)*(r+r1+r2));
-								var ol1 = A / (Math.PI*r1*r1);
-								var ol2 = A / (Math.PI*r2*r2);
-								var ol = Math.max(ol1,ol2);
-								e.weight = circleOverlap.overlap / ol;
-							}
-							else {
-								e.weight = 0;
-							}
-						}
-					}
-				}
-				if (e.weight < 1) {
-					this.deleteEdges.push(e);
-				}
-			}
-			newEdges.push(e);
-		}
-	}
-	this.edges = newEdges;
-}
-
-Clustering.prototype.ValidityTest = function() {
-	console.info("Test 1: Valid Delaunay ...");
-	/*
-	var leafs = [];
-	var triangles = this.boundingTriangle.descendants;
-	var j = 0;
-	while( triangles.length > j ){
-	var t = triangles[j];
-	if( t.taken == undefined ){
-	t.taken = true;
-	if( this.isLeaf(t) ){
-	leafs.push(t);
-	}
-	else {
-	triangles = triangles.concat(t.descendants);
-	}
-	}
-	j++;
-	}
-	console.info("  Number of Triangles: "+leafs.length);
-
-	var c = 0;
-	for( i in this.edges ){
-	if( this.edges[i].legal ){
-	c++;
-	}
-	}
-	console.info("  Number of Edges: "+c);*/
-	/*
-
-	for( var i=0; i<leafs.length; i++ ){
-	for( var j=0; j<vertices.length; j++ ){
-	if( !leafs[i].contains(vertices[j]) && leafs[i].inCircumcircle(vertices[j]) ){
-	console.info(leafs[i],vertices[j]);
-
-	}
-	}
-	}
-	*/
-
-	//console.info("Test 2: Edges Facets (null) ...");
-	for (i in this.edges ) {
-		var e = this.edges[i];
-		if (e.leftFace == null || e.rightFace == null) {
-			console.info(e);
-			alert();
-		}
-	}
-
-	//console.info("Test 3: Edges Facets ...");
-	var leftOf = function(v1, v2, v) {
-		var x2 = v1.x - v2.x;
-		var x3 = v1.x - v.x;
-		var y2 = v1.y - v2.y;
-		var y3 = v1.y - v.y;
-		if (x2 * y3 - y2 * x3 < 0) {
-			return true;
-		}
-		return false;
-	}
-	var c = 0;
-	for (i in this.edges ) {
-		var e = this.edges[i];
-		var t1 = e.leftFace.getTriple(e);
-		var t2 = e.rightFace.getTriple(e);
-		if (e.v0.y == e.v1.y) {
-			if (t1.u.y > t2.u.y) {
-				console.info("equal y conflict ...");
-				console.info(e);
-				alert();
-				c++;
-			}
-		} else {
-			var v1, v2;
-			if (e.v0.y > e.v1.y) {
-				v1 = e.v0;
-				v2 = e.v1;
-			} else {
-				v1 = e.v1;
-				v2 = e.v0;
-			}
-			if (!leftOf(v1, v2, t1.u)) {
-				console.info("left right conflict ... left is right");
-				console.info(e);
-				alert();
-				c++;
-			}
-			if (leftOf(v1, v2, t2.u)) {
-				console.info("left right conflict ... right is left");
-				console.info(e);
-				alert();
-				c++;
-			}
-		}
-	}
-	//console.info("Number of Edges: "+this.edges.length);
-	//console.info("Number of Conflicts: "+c);
-
-	for (i in this.edges ) {
-		if (this.edges[i].legal) {
-			var e = this.edges[i];
-			var tr0 = e.leftFace.getTriple(e);
-			var tr1 = e.rightFace.getTriple(e);
-			if (!tr0.e_p.legal || !tr0.e_s.legal || !tr1.e_p.legal || !tr1.e_s.legal) {
-				console.info(e);
-				console.info("conflict in edge continuity");
-				return;
-			}
-		}
-	}
-
-}
-function BinaryHeap(scoreFunction) {
-	this.content = [];
-	this.scoreFunction = scoreFunction;
-}
-
-BinaryHeap.prototype = {
-	push : function(element) {
-		// Add the new element to the end of the array.
-		this.content.push(element);
-		// Allow it to bubble up.
-		this.bubbleUp(this.content.length - 1);
-	},
-
-	pop : function() {
-		// Store the first element so we can return it later.
-		var result = this.content[0];
-		// Get the element at the end of the array.
-		var end = this.content.pop();
-		// If there are any elements left, put the end element at the
-		// start, and let it sink down.
-		if (this.content.length > 0) {
-			this.content[0] = end;
-			this.sinkDown(0);
-		}
-		return result;
-	},
-
-	remove : function(node) {
-		var len = this.content.length;
-		// To remove a value, we must search through the array to find
-		// it.
-		for (var i = 0; i < len; i++) {
-			if (this.content[i] == node) {
-				// When it is found, the process seen in 'pop' is repeated
-				// to fill up the hole.
-				var end = this.content.pop();
-				if (i != len - 1) {
-					this.content[i] = end;
-					if (this.scoreFunction(end) < this.scoreFunction(node))
-						this.bubbleUp(i);
-					else
-						this.sinkDown(i);
-				}
-				return;
-			}
-		}
-		throw new Error("Node not found.");
-	},
-
-	size : function() {
-		return this.content.length;
-	},
-
-	bubbleUp : function(n) {
-		// Fetch the element that has to be moved.
-		var element = this.content[n];
-		// When at 0, an element can not go up any further.
-		while (n > 0) {
-			// Compute the parent element's index, and fetch it.
-			var parentN = Math.floor((n + 1) / 2) - 1, parent = this.content[parentN];
-			// Swap the elements if the parent is greater.
-			if (this.scoreFunction(element) < this.scoreFunction(parent)) {
-				this.content[parentN] = element;
-				this.content[n] = parent;
-				// Update 'n' to continue at the new position.
-				n = parentN;
-
-			}
-			// Found a parent that is less, no need to move it further.
-			else {
-				break;
-			}
-		}
-	},
-
-	sinkDown : function(n) {
-		// Look up the target element and its score.
-		var length = this.content.length, element = this.content[n], elemScore = this.scoreFunction(element);
-
-		while (true) {
-			// Compute the indices of the child elements.
-			var child2N = (n + 1) * 2, child1N = child2N - 1;
-			// This is used to store the new position of the element,
-			// if any.
-			var swap = null;
-			// If the first child exists (is inside the array)...
-			if (child1N < length) {
-				// Look it up and compute its score.
-				var child1 = this.content[child1N], child1Score = this.scoreFunction(child1);
-				// If the score is less than our element's, we need to swap.
-				if (child1Score < elemScore)
-					swap = child1N;
-			}
-			// Do the same checks for the other child.
-			if (child2N < length) {
-				var child2 = this.content[child2N], child2Score = this.scoreFunction(child2);
-				if (child2Score < (swap == null ? elemScore : child1Score))
-					swap = child2N;
-			}
-
-			// If the element needs to be moved, swap it, and continue.
-			if (swap != null) {
-				this.content[n] = this.content[swap];
-				this.content[swap] = element;
-				n = swap;
-			}
-			// Otherwise, we are done.
-			else {
-				break;
-			}
-		}
-	}
-};
+/*
+* Clustering.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class Vertex, Edge, Triangle, Clustering, BinaryHeap
+ * Dynamic Delaunay clustering algorithm (see GeoTemCo paper)
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+
+function Vertex(x, y, categories, binning) {
+	this.x = x;
+	this.y = y;
+	this.radius
+	this.size = 0;
+	this.elements = [];
+	this.radii = [];
+	this.weights = [];
+	this.legal = true;
+	this.binning = binning;
+	if (categories != undefined) {
+		for (var i = 0; i < categories; i++) {
+			this.elements.push([]);
+			this.weights.push(0);
+		}
+	}
+}
+
+Vertex.prototype.merge = function(v0, v1) {
+	for (var i = 0; i < v0.elements.length; i++) {
+		this.elements[i] = v0.elements[i].concat(v1.elements[i]);
+		this.weights[i] = v0.weights[i] + v1.weights[i];
+		this.size += this.weights[i];
+	}
+}
+
+Vertex.prototype.CalculateRadius = function(resolution) {
+	this.radii = [];
+	for (i in this.elements ) {
+		this.radii.push(this.binning.getRadius(this.weights[i]));
+	}
+	if (this.radii.length == 1) {
+		this.radius = this.radii[0] * resolution;
+	} else {
+		var count = 0;
+		var max1 = 0;
+		var max2 = 0;
+		for (i in this.radii ) {
+			if (this.radii[i] != 0) {
+				count++;
+			}
+			if (this.radii[i] > max1) {
+				if (max1 > max2) {
+					max2 = max1;
+				}
+				max1 = this.radii[i];
+			} else if (this.radii[i] > max2) {
+				max2 = this.radii[i];
+			}
+		}
+		if (count == 1) {
+			this.radius = max1 * resolution;
+		} else if (count == 2) {
+			this.radius = (max1 + max2) * resolution;
+		} else if (count == 3) {
+			var d = (2 / 3 * Math.sqrt(3) - 1) * max1;
+			this.radius = (d + max1 + max2) * resolution;
+		} else if (count == 4) {
+			var d = (Math.sqrt(2) - 1) * max2;
+			this.radius = (d + max1 + max2) * resolution;
+		}
+	}
+}
+
+Vertex.prototype.addElement = function(e, weight, index) {
+	this.elements[index].push(e);
+	this.size += weight;
+	this.weights[index] += weight;
+}
+function Edge(v0, v1) {
+	this.v0 = v0;
+	this.v1 = v1;
+	this.leftFace
+	this.rightFace
+	this.legal = true;
+	this.setLength();
+}
+
+Edge.prototype.setLength = function() {
+	var dx = this.v0.x - this.v1.x;
+	var dy = this.v0.y - this.v1.y;
+	this.length = Math.sqrt(dx * dx + dy * dy);
+}
+
+Edge.prototype.contains = function(v) {
+	if (this.v0 == v || this.v1 == v) {
+		return true;
+	}
+	return false;
+}
+
+Edge.prototype.replaceFace = function(f_old, f_new) {
+	if (this.leftFace == f_old) {
+		this.leftFace = f_new;
+	} else if (this.rightFace == f_old) {
+		this.rightFace = f_new;
+	}
+}
+
+Edge.prototype.setFace = function(f) {
+	if (f.leftOf(this)) {
+		this.leftFace = f;
+	} else {
+		this.rightFace = f;
+	}
+}
+
+Edge.prototype.setFaces = function(f1, f2) {
+	if (f1.leftOf(this)) {
+		this.leftFace = f1;
+		this.rightFace = f2;
+	} else {
+		this.leftFace = f2;
+		this.rightFace = f1;
+	}
+}
+
+Edge.prototype.removeFace = function(f) {
+	if (this.leftFace == f) {
+		this.leftFace = null;
+	} else {
+		this.rightFace = null;
+	}
+}
+
+Edge.prototype.equals = function(e) {
+	if (this.v0 == e.v0 && this.v1 == e.v1 || this.v0 == e.v1 && this.v1 == e.v0) {
+		return true;
+	}
+	return false;
+}
+function Triangle(edges) {
+	this.edges = edges;
+	this.setVertices();
+	this.descendants = [];
+}
+
+Triangle.prototype.getTriple = function(e) {
+	var i = arrayIndex(this.edges, e);
+	return {
+		e_s : this.edges[(i + 1) % 3],
+		e_p : this.edges[(i + 2) % 3],
+		u : this.vertices[(i + 2) % 3]
+	};
+}
+
+Triangle.prototype.leftOf = function(e) {
+	var i = arrayIndex(this.edges, e);
+	if (this.vertices[i].y != this.vertices[(i + 1) % 3].y) {
+		return this.vertices[i].y > this.vertices[(i + 1) % 3].y;
+	}
+	return this.vertices[i].y > this.vertices[(i + 2) % 3].y;
+}
+
+Triangle.prototype.getNext = function(v) {
+	var i = arrayIndex(this.vertices, v);
+	return this.vertices[(i + 1) % 3];
+}
+
+Triangle.prototype.oppositeEdge = function(v) {
+	var i = arrayIndex(this.vertices, v);
+	return this.edges[(i + 1) % 3];
+}
+
+Triangle.prototype.contains = function(v) {
+	return arrayIndex(this.vertices, v) != -1;
+}
+
+Triangle.prototype.replace = function(e_old, e_new) {
+	this.edges[arrayIndex(this.edges, e_old)] = e_new;
+}
+
+Triangle.prototype.setVertices = function() {
+	if (this.edges[1].v0 == this.edges[0].v0 || this.edges[1].v1 == this.edges[0].v0) {
+		this.vertices = [this.edges[0].v1, this.edges[0].v0];
+	} else {
+		this.vertices = [this.edges[0].v0, this.edges[0].v1];
+	}
+	if (this.edges[2].v0 == this.vertices[0]) {
+		this.vertices.push(this.edges[2].v1);
+	} else {
+		this.vertices.push(this.edges[2].v0);
+	}
+}
+
+Triangle.prototype.replaceBy = function(triangles) {
+	this.descendants = triangles;
+	this.edges[0].replaceFace(this, triangles[0]);
+	this.edges[1].replaceFace(this, triangles[1]);
+	this.edges[2].replaceFace(this, triangles[2]);
+}
+
+Triangle.prototype.CalcCircumcircle = function() {
+	var v0 = this.vertices[0];
+	var v1 = this.vertices[1];
+	var v2 = this.vertices[2];
+	var A = v1.x - v0.x;
+	var B = v1.y - v0.y;
+	var C = v2.x - v0.x;
+	var D = v2.y - v0.y;
+	var E = A * (v0.x + v1.x) + B * (v0.y + v1.y);
+	var F = C * (v0.x + v2.x) + D * (v0.y + v2.y);
+	var G = 2.0 * (A * (v2.y - v1.y) - B * (v2.x - v1.x));
+	var cx = (D * E - B * F) / G;
+	var cy = (A * F - C * E) / G;
+	this.center = new Vertex(cx, cy);
+	var dx = this.center.x - v0.x;
+	var dy = this.center.y - v0.y;
+	this.radius_squared = dx * dx + dy * dy;
+};
+
+Triangle.prototype.inCircumcircle = function(v) {
+	if (this.radius_squared == undefined) {
+		this.CalcCircumcircle();
+	}
+	var dx = this.center.x - v.x;
+	var dy = this.center.y - v.y;
+	var dist_squared = dx * dx + dy * dy;
+	return (dist_squared <= this.radius_squared );
+};
+
+Triangle.prototype.interior = function(v) {
+	var v0 = this.vertices[0];
+	var v1 = this.vertices[1];
+	var v2 = this.vertices[2];
+	var dotAB = (v.x - v0.x ) * (v0.y - v1.y ) + (v.y - v0.y ) * (v1.x - v0.x );
+	var dotBC = (v.x - v1.x ) * (v1.y - v2.y ) + (v.y - v1.y ) * (v2.x - v1.x );
+	var dotCA = (v.x - v2.x ) * (v2.y - v0.y ) + (v.y - v2.y ) * (v0.x - v2.x );
+	if (dotAB > 0 || dotBC > 0 || dotCA > 0) {
+		return null;
+	} else if (dotAB < 0 && dotBC < 0 && dotCA < 0) {
+		return this;
+	} else if (dotAB == 0) {
+		if (dotBC == 0) {
+			return this.vertices[1];
+		} else if (dotCA == 0) {
+			return this.vertices[0];
+		}
+		return this.edges[0];
+	} else if (dotBC == 0) {
+		if (dotCA == 0) {
+			return this.vertices[2];
+		}
+		return this.edges[1];
+	} else if (dotCA == 0) {
+		return this.edges[2];
+	}
+};
+
+function Clustering(xMin, yMin, xMax, yMax) {
+	this.triangles = [];
+	this.newTriangles = [];
+	this.bbox = {
+		x1 : xMin,
+		y1 : yMin,
+		x2 : xMax,
+		y2 : yMax
+	};
+	this.CreateBoundingTriangle();
+	this.edges = [];
+	this.vertices = [];
+	this.legalizes = 0;
+	this.collapses = 0;
+}
+
+Clustering.prototype.locate = function(v) {
+	if (this.boundingTriangle.descendants.length == 0) {
+		return this.boundingTriangle;
+	}
+	var triangles = this.boundingTriangle.descendants;
+	while (true) {
+		for (var i = 0; i < triangles.length; i++) {
+			var simplex = triangles[i].interior(v);
+			if (simplex == null) {
+				continue;
+			}
+			if ( simplex instanceof Vertex || this.isLeaf(triangles[i])) {
+				return simplex;
+			}
+			triangles = triangles[i].descendants;
+			break;
+		}
+	}
+}
+
+Clustering.prototype.legalize = function(v, e, t0_old) {
+	if (!e.v0.legal && !e.v1.legal) {
+		return;
+	}
+	this.legalizes++;
+	var flip = false;
+	var t1_old, tr1;
+	if (e.leftFace == t0_old && e.rightFace.inCircumcircle(v)) {
+		flip = true;
+		t1_old = e.rightFace;
+	} else if (e.rightFace == t0_old && e.leftFace.inCircumcircle(v)) {
+		flip = true;
+		t1_old = e.leftFace;
+	}
+	if (flip) {
+		var tr0 = t0_old.getTriple(e);
+		var tr1 = t1_old.getTriple(e);
+		var e_flip = new Edge(tr0.u, tr1.u);
+		var poly = [];
+		poly.push(e.v0);
+		poly.push(e_flip.v0);
+		poly.push(e.v1);
+		poly.push(e_flip.v1);
+		if (!this.JordanTest(poly, e_flip)) {
+			return;
+		}
+		e.legal = false;
+		this.edges.push(e_flip);
+		var t0_new = new Triangle([e_flip, tr0.e_p, tr1.e_s]);
+		var t1_new = new Triangle([e_flip, tr1.e_p, tr0.e_s]);
+		e_flip.setFaces(t0_new, t1_new);
+		tr0.e_p.replaceFace(t0_old, t0_new);
+		tr1.e_s.replaceFace(t1_old, t0_new);
+		tr1.e_p.replaceFace(t1_old, t1_new);
+		tr0.e_s.replaceFace(t0_old, t1_new);
+		t0_old.descendants = [t0_new, t1_new];
+		t1_old.descendants = [t0_new, t1_new];
+		this.legalize(v, t0_new.edges[2], t0_new);
+		this.legalize(v, t1_new.edges[1], t1_new);
+	}
+}
+
+Clustering.prototype.add = function(v) {
+	this.addVertex(v, this.locate(v));
+}
+
+Clustering.prototype.addVertex = function(v, simplex) {
+	if ( simplex instanceof Vertex) {
+		simplex.merge(simplex, v);
+	} else if ( simplex instanceof Edge) {
+		this.vertices.push(v);
+		simplex.legal = false;
+		var tr0 = simplex.leftFace.getTriple(simplex);
+		var tr1 = simplex.rightFace.getTriple(simplex);
+		var e0 = new Edge(v, tr0.u);
+		var e1 = new Edge(v, simplex.leftFace.getNext(tr0.u));
+		var e2 = new Edge(v, tr1.u);
+		var e3 = new Edge(v, simplex.rightFace.getNext(tr1.u));
+		var t0 = new Triangle([e0, tr0.e_p, e1]);
+		var t1 = new Triangle([e1, tr1.e_s, e2]);
+		var t2 = new Triangle([e2, tr1.e_p, e3]);
+		var t3 = new Triangle([e3, tr0.e_s, e0]);
+		simplex.leftFace.descendants = [t0, t3];
+		simplex.rightFace.descendants = [t1, t2];
+		this.edges.push(e0);
+		this.edges.push(e1);
+		this.edges.push(e2);
+		this.edges.push(e3);
+		e0.setFaces(t0, t3);
+		e1.setFaces(t0, t1);
+		e2.setFaces(t1, t2);
+		e3.setFaces(t2, t3);
+		tr0.e_p.replaceFace(simplex.leftFace, t0);
+		tr1.e_s.replaceFace(simplex.rightFace, t1);
+		tr1.e_p.replaceFace(simplex.rightFace, t2);
+		tr0.e_s.replaceFace(simplex.leftFace, t3);
+		this.legalize(v, tr0.e_p, t0);
+		this.legalize(v, tr1.e_s, t1);
+		this.legalize(v, tr1.e_p, t2);
+		this.legalize(v, tr0.e_s, t3);
+	} else {
+		this.vertices.push(v);
+		var e_i = new Edge(simplex.vertices[0], v);
+		var e_j = new Edge(simplex.vertices[1], v);
+		var e_k = new Edge(simplex.vertices[2], v);
+		this.edges.push(e_i);
+		this.edges.push(e_j);
+		this.edges.push(e_k);
+		var t0 = new Triangle([e_i, simplex.edges[0], e_j]);
+		var t1 = new Triangle([e_j, simplex.edges[1], e_k]);
+		var t2 = new Triangle([e_k, simplex.edges[2], e_i]);
+		e_i.setFaces(t0, t2);
+		e_j.setFaces(t0, t1);
+		e_k.setFaces(t1, t2);
+		simplex.replaceBy([t0, t1, t2]);
+		this.legalize(v, simplex.edges[0], t0);
+		this.legalize(v, simplex.edges[1], t1);
+		this.legalize(v, simplex.edges[2], t2);
+	}
+}
+
+Clustering.prototype.isLeaf = function(t) {
+	return t.descendants.length == 0;
+}
+
+Clustering.prototype.CreateBoundingTriangle = function() {
+	var dx = (this.bbox.x2 - this.bbox.x1 ) * 10;
+	var dy = (this.bbox.y2 - this.bbox.y1 ) * 10;
+	var v0 = new Vertex(this.bbox.x1 - dx, this.bbox.y1 - dy * 3);
+	var v1 = new Vertex(this.bbox.x2 + dx * 3, this.bbox.y2 + dy);
+	var v2 = new Vertex(this.bbox.x1 - dx, this.bbox.y2 + dy);
+	var e0 = new Edge(v1, v0);
+	var e1 = new Edge(v0, v2);
+	var e2 = new Edge(v2, v1);
+	v0.legal = false;
+	v1.legal = false;
+	v2.legal = false;
+	this.boundingTriangle = new Triangle([e0, e1, e2]);
+	var inf = new Triangle([e0, e1, e2]);
+	e0.setFaces(this.boundingTriangle, inf);
+	e1.setFaces(this.boundingTriangle, inf);
+	e2.setFaces(this.boundingTriangle, inf);
+}
+
+Clustering.prototype.mergeVertices = function(e) {
+	this.collapses++;
+	var s0 = e.v0.size;
+	var s1 = e.v1.size;
+	var x = (e.v0.x * s0 + e.v1.x * s1 ) / (s0 + s1 );
+	var y = (e.v0.y * s0 + e.v1.y * s1 ) / (s0 + s1 );
+	var v = new Vertex(x, y, e.v0.elements.length, e.v0.binning);
+	v.merge(e.v0, e.v1);
+
+	e.v0.legal = false;
+	e.v1.legal = false;
+
+	var hole = [];
+	var oldFacets = [];
+	e.legal = false;
+
+	var vertices = [];
+	var traverse = function(eLeft, eRight, triangle) {
+		eLeft.legal = false;
+		do {
+			var triple;
+			if (eLeft.leftFace == triangle) {
+				triple = eLeft.rightFace.getTriple(eLeft);
+				oldFacets.push(eLeft.rightFace);
+				triple.e_s.removeFace(eLeft.rightFace);
+				triangle = eLeft.rightFace;
+			} else {
+				triple = eLeft.leftFace.getTriple(eLeft);
+				oldFacets.push(eLeft.leftFace);
+				triple.e_s.removeFace(eLeft.leftFace);
+				triangle = eLeft.leftFace;
+			}
+			if (arrayIndex(hole, triple.e_s) == -1) {
+				hole.push(triple.e_s);
+			}
+			vertices.push(triple.u);
+			eLeft = triple.e_p;
+			eLeft.legal = false;
+		} while( eLeft != eRight );
+	}
+	var tr0 = e.leftFace.getTriple(e);
+	var tr1 = e.rightFace.getTriple(e);
+	oldFacets.push(e.leftFace);
+	oldFacets.push(e.rightFace);
+	traverse(tr0.e_p, tr1.e_s, e.leftFace);
+	traverse(tr1.e_p, tr0.e_s, e.rightFace);
+
+	var hd = new Clustering(this.bbox.x1 - 10, this.bbox.y1 - 10, this.bbox.x2 + 10, this.bbox.y2 + 10);
+	var hull = [];
+	for (var i in hole ) {
+		if (!(hole[i].leftFace == null && hole[i].rightFace == null)) {
+			hull.push(hole[i].v0);
+			hull.push(hole[i].v1);
+		}
+	}
+	var hullVertices = [];
+	var distinct = [];
+	for (var i in vertices ) {
+		if (arrayIndex(distinct, vertices[i]) == -1) {
+			hd.add(vertices[i]);
+			distinct.push(vertices[i]);
+		}
+		if (arrayIndex(hull, vertices[i]) != -1) {
+			hullVertices.push(vertices[i]);
+		}
+	}
+
+	var newFacets = [];
+	var isBoundary = function(e) {
+		for (var i = 0; i < hole.length; i++) {
+			if (hole[i].equals(e)) {
+				return i;
+			}
+		}
+		return -1;
+	}
+	var holeEdges = new Array(hole.length);
+	var nonHoleEdges = [];
+
+	for (var i = 0; i < hd.edges.length; i++) {
+		var e = hd.edges[i];
+		var b = isBoundary(e);
+		if (b != -1) {
+			if (!e.legal) {
+				var t1 = e.leftFace.getTriple(e);
+				var t2 = e.rightFace.getTriple(e);
+				var edge = new Edge(t1.u, t2.u);
+				for (var j = 0; j < hd.edges.length; j++) {
+					if (hd.edges[j].equals(edge) && hd.edges[j].legal) {
+						hd.edges[j].legal = false;
+						break;
+					}
+				}
+				t1.e_p.setFace(e.leftFace);
+				t1.e_s.setFace(e.leftFace);
+				t2.e_p.setFace(e.rightFace);
+				t2.e_s.setFace(e.rightFace);
+
+				e.legal = true;
+			}
+			holeEdges[b] = e;
+		} else {
+			nonHoleEdges.push(e);
+		}
+	}
+
+	for (var i = 0; i < holeEdges.length; i++) {
+		var e = holeEdges[i];
+		if (hole[i].leftFace == null) {
+			hole[i].leftFace = e.leftFace;
+			hole[i].leftFace.replace(e, hole[i]);
+			if (arrayIndex(newFacets, hole[i].leftFace) == -1) {
+				newFacets.push(hole[i].leftFace);
+			}
+		}
+		if (hole[i].rightFace == null) {
+			hole[i].rightFace = e.rightFace;
+			hole[i].rightFace.replace(e, hole[i]);
+			if (arrayIndex(newFacets, hole[i].rightFace) == -1) {
+				newFacets.push(hole[i].rightFace);
+			}
+		}
+	}
+
+	for (var i = 0; i < nonHoleEdges.length; i++) {
+		var e = nonHoleEdges[i];
+		if (!e.legal) {
+			continue;
+		}
+		if (this.JordanTest(hullVertices, e)) {
+			this.edges.push(e);
+			if (arrayIndex(newFacets, e.rightFace) == -1) {
+				newFacets.push(e.rightFace);
+			}
+			if (arrayIndex(newFacets, e.leftFace) == -1) {
+				newFacets.push(e.leftFace);
+			}
+		}
+	}
+
+	for (var i in oldFacets ) {
+		oldFacets[i].descendants = newFacets;
+	}
+
+	for (var i = 0; i < newFacets.length; i++) {
+		var simplex = newFacets[i].interior(v);
+		if (simplex == null) {
+			continue;
+		} else {
+			this.addVertex(v, simplex);
+			break;
+		}
+	}
+
+	return v;
+
+}
+
+Clustering.prototype.JordanTest = function(pol, e) {
+	var p = new Vertex((e.v0.x + e.v1.x) * 0.5, (e.v0.y + e.v1.y) * 0.5);
+	var inside = false;
+	var i, j = pol.length - 1;
+	for ( i = 0; i < pol.length; j = i++) {
+		var p1 = pol[i];
+		var p2 = pol[j];
+		if ((((p1.y <= p.y) && (p.y < p2.y)) || ((p2.y <= p.y) && (p.y < p1.y))) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x))
+			inside = !inside;
+	}
+	return inside;
+}
+
+Clustering.prototype.mergeForResolution = function(resolution, circleGap, circleOverlap) {
+	this.deleteEdges = new BinaryHeap(function(e) {
+		return e.weight;
+	});
+	this.weightEdges(resolution, circleGap, circleOverlap);
+	var index = 0;
+	while (this.deleteEdges.size() > 0) {
+		var e = this.deleteEdges.pop();
+		if (e.legal) {
+			var l = this.edges.length;
+			var newVertex = this.mergeVertices(e);
+			newVertex.CalculateRadius(resolution);
+			for (var k = l; k < this.edges.length; k++) {
+				var eNew = this.edges[k];
+				if (eNew.legal) {
+					if( circleGap != 0 ){
+						eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius + circleGap * resolution );
+					}
+					else if( circleOverlap.overlap == 0 ){
+						eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius);
+					}
+					else {
+						var r1 = eNew.v0.radius;
+						var r2 = eNew.v1.radius;
+						var r = eNew.length;
+						if( r < r1 + r2 ){
+							if( circleOverlap.type == 'diameter' ){
+								var ol1 = (r2-(r-r1)) / r1 / 2;
+								var ol2 = (r1-(r-r2)) / r2 / 2;
+								var ol = Math.max(ol1,ol2);
+								eNew.weight = circleOverlap.overlap / ol;
+							}
+							if( circleOverlap.type == 'area' ){								
+								if( !(r+r1 < r2 || r+r2 < r1) ){
+									var A = r2*r2*Math.acos((r*r+r2*r2-r1*r1)/(2*r*r2))+r1*r1*Math.acos((r*r+r1*r1-r2*r2)/(2*r*r1))-1/2*Math.sqrt((-r+r1+r2)*(r-r1+r2)*(r+r1-r2)*(r+r1+r2));
+									var ol1 = A / (Math.PI*r1*r1);
+									var ol2 = A / (Math.PI*r2*r2);
+									var ol = Math.max(ol1,ol2);
+									eNew.weight = circleOverlap.overlap / ol;
+								}
+								else {
+									eNew.weight = 0;
+								}
+							}
+						}
+					}
+					if (eNew.weight < 1) {
+						this.deleteEdges.push(eNew);
+					}
+				}
+			}
+		}
+	}
+}
+
+Clustering.prototype.weightEdges = function(resolution, circleGap, circleOverlap) {
+	for (var i = 0; i < this.vertices.length; i++) {
+		if (this.vertices[i].legal) {
+			this.vertices[i].CalculateRadius(resolution);
+		}
+	}
+	var newEdges = [];
+	for (var i = 0; i < this.edges.length; i++) {
+		var e = this.edges[i];
+		if (e.legal) {
+			if (!e.v0.legal || !e.v1.legal) {
+				e.weight = 1;
+			} else {
+				if( circleGap != 0 ){
+					e.weight = e.length / (e.v0.radius + e.v1.radius + circleGap * resolution );
+				}
+				else if( circleOverlap.overlap == 0 ){
+					e.weight = e.length / (e.v0.radius + e.v1.radius);
+				}
+				else {
+					var r1 = e.v0.radius;
+					var r2 = e.v1.radius;
+					var r = e.length;
+					if( r < r1 + r2 ){
+						if( circleOverlap.type == 'diameter' ){
+							var ol1 = (r2-(r-r1)) / r1 / 2;
+							var ol2 = (r1-(r-r2)) / r2 / 2;
+							var ol = Math.max(ol1,ol2);
+							e.weight = circleOverlap.overlap / ol;
+						}
+						if( circleOverlap.type == 'area' ){
+							if( !(r+r1 < r2 || r+r2 < r1) ){
+								var A = r2*r2*Math.acos((r*r+r2*r2-r1*r1)/(2*r*r2))+r1*r1*Math.acos((r*r+r1*r1-r2*r2)/(2*r*r1))-1/2*Math.sqrt((-r+r1+r2)*(r-r1+r2)*(r+r1-r2)*(r+r1+r2));
+								var ol1 = A / (Math.PI*r1*r1);
+								var ol2 = A / (Math.PI*r2*r2);
+								var ol = Math.max(ol1,ol2);
+								e.weight = circleOverlap.overlap / ol;
+							}
+							else {
+								e.weight = 0;
+							}
+						}
+					}
+				}
+				if (e.weight < 1) {
+					this.deleteEdges.push(e);
+				}
+			}
+			newEdges.push(e);
+		}
+	}
+	this.edges = newEdges;
+}
+
+Clustering.prototype.ValidityTest = function() {
+	console.info("Test 1: Valid Delaunay ...");
+	/*
+	var leafs = [];
+	var triangles = this.boundingTriangle.descendants;
+	var j = 0;
+	while( triangles.length > j ){
+	var t = triangles[j];
+	if( t.taken == undefined ){
+	t.taken = true;
+	if( this.isLeaf(t) ){
+	leafs.push(t);
+	}
+	else {
+	triangles = triangles.concat(t.descendants);
+	}
+	}
+	j++;
+	}
+	console.info("  Number of Triangles: "+leafs.length);
+
+	var c = 0;
+	for( i in this.edges ){
+	if( this.edges[i].legal ){
+	c++;
+	}
+	}
+	console.info("  Number of Edges: "+c);*/
+	/*
+
+	for( var i=0; i<leafs.length; i++ ){
+	for( var j=0; j<vertices.length; j++ ){
+	if( !leafs[i].contains(vertices[j]) && leafs[i].inCircumcircle(vertices[j]) ){
+	console.info(leafs[i],vertices[j]);
+
+	}
+	}
+	}
+	*/
+
+	//console.info("Test 2: Edges Facets (null) ...");
+	for (i in this.edges ) {
+		var e = this.edges[i];
+		if (e.leftFace == null || e.rightFace == null) {
+			console.info(e);
+			alert();
+		}
+	}
+
+	//console.info("Test 3: Edges Facets ...");
+	var leftOf = function(v1, v2, v) {
+		var x2 = v1.x - v2.x;
+		var x3 = v1.x - v.x;
+		var y2 = v1.y - v2.y;
+		var y3 = v1.y - v.y;
+		if (x2 * y3 - y2 * x3 < 0) {
+			return true;
+		}
+		return false;
+	}
+	var c = 0;
+	for (i in this.edges ) {
+		var e = this.edges[i];
+		var t1 = e.leftFace.getTriple(e);
+		var t2 = e.rightFace.getTriple(e);
+		if (e.v0.y == e.v1.y) {
+			if (t1.u.y > t2.u.y) {
+				console.info("equal y conflict ...");
+				console.info(e);
+				alert();
+				c++;
+			}
+		} else {
+			var v1, v2;
+			if (e.v0.y > e.v1.y) {
+				v1 = e.v0;
+				v2 = e.v1;
+			} else {
+				v1 = e.v1;
+				v2 = e.v0;
+			}
+			if (!leftOf(v1, v2, t1.u)) {
+				console.info("left right conflict ... left is right");
+				console.info(e);
+				alert();
+				c++;
+			}
+			if (leftOf(v1, v2, t2.u)) {
+				console.info("left right conflict ... right is left");
+				console.info(e);
+				alert();
+				c++;
+			}
+		}
+	}
+	//console.info("Number of Edges: "+this.edges.length);
+	//console.info("Number of Conflicts: "+c);
+
+	for (i in this.edges ) {
+		if (this.edges[i].legal) {
+			var e = this.edges[i];
+			var tr0 = e.leftFace.getTriple(e);
+			var tr1 = e.rightFace.getTriple(e);
+			if (!tr0.e_p.legal || !tr0.e_s.legal || !tr1.e_p.legal || !tr1.e_s.legal) {
+				console.info(e);
+				console.info("conflict in edge continuity");
+				return;
+			}
+		}
+	}
+
+}
+function BinaryHeap(scoreFunction) {
+	this.content = [];
+	this.scoreFunction = scoreFunction;
+}
+
+BinaryHeap.prototype = {
+	push : function(element) {
+		// Add the new element to the end of the array.
+		this.content.push(element);
+		// Allow it to bubble up.
+		this.bubbleUp(this.content.length - 1);
+	},
+
+	pop : function() {
+		// Store the first element so we can return it later.
+		var result = this.content[0];
+		// Get the element at the end of the array.
+		var end = this.content.pop();
+		// If there are any elements left, put the end element at the
+		// start, and let it sink down.
+		if (this.content.length > 0) {
+			this.content[0] = end;
+			this.sinkDown(0);
+		}
+		return result;
+	},
+
+	remove : function(node) {
+		var len = this.content.length;
+		// To remove a value, we must search through the array to find
+		// it.
+		for (var i = 0; i < len; i++) {
+			if (this.content[i] == node) {
+				// When it is found, the process seen in 'pop' is repeated
+				// to fill up the hole.
+				var end = this.content.pop();
+				if (i != len - 1) {
+					this.content[i] = end;
+					if (this.scoreFunction(end) < this.scoreFunction(node))
+						this.bubbleUp(i);
+					else
+						this.sinkDown(i);
+				}
+				return;
+			}
+		}
+		throw new Error("Node not found.");
+	},
+
+	size : function() {
+		return this.content.length;
+	},
+
+	bubbleUp : function(n) {
+		// Fetch the element that has to be moved.
+		var element = this.content[n];
+		// When at 0, an element can not go up any further.
+		while (n > 0) {
+			// Compute the parent element's index, and fetch it.
+			var parentN = Math.floor((n + 1) / 2) - 1, parent = this.content[parentN];
+			// Swap the elements if the parent is greater.
+			if (this.scoreFunction(element) < this.scoreFunction(parent)) {
+				this.content[parentN] = element;
+				this.content[n] = parent;
+				// Update 'n' to continue at the new position.
+				n = parentN;
+
+			}
+			// Found a parent that is less, no need to move it further.
+			else {
+				break;
+			}
+		}
+	},
+
+	sinkDown : function(n) {
+		// Look up the target element and its score.
+		var length = this.content.length, element = this.content[n], elemScore = this.scoreFunction(element);
+
+		while (true) {
+			// Compute the indices of the child elements.
+			var child2N = (n + 1) * 2, child1N = child2N - 1;
+			// This is used to store the new position of the element,
+			// if any.
+			var swap = null;
+			// If the first child exists (is inside the array)...
+			if (child1N < length) {
+				// Look it up and compute its score.
+				var child1 = this.content[child1N], child1Score = this.scoreFunction(child1);
+				// If the score is less than our element's, we need to swap.
+				if (child1Score < elemScore)
+					swap = child1N;
+			}
+			// Do the same checks for the other child.
+			if (child2N < length) {
+				var child2 = this.content[child2N], child2Score = this.scoreFunction(child2);
+				if (child2Score < (swap == null ? elemScore : child1Score))
+					swap = child2N;
+			}
+
+			// If the element needs to be moved, swap it, and continue.
+			if (swap != null) {
+				this.content[n] = this.content[swap];
+				this.content[swap] = element;
+				n = swap;
+			}
+			// Otherwise, we are done.
+			else {
+				break;
+			}
+		}
+	}
+};
 /*
 * Dropdown.js
 *
@@ -46442,81 +46447,81 @@
 		}
 	}
 };
-/*
-* Dropdown.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * @class Publisher
- * Publish/Subscribe mechanism
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-if ( typeof Publisher == 'undefined') {
-
-	Publisher = function() {
-
-		var topics = [];
-
-		this.Get = function(topic) {
-			var value = topics[topic];
-			if (!value || !(value instanceof Array)) {
-				value = topics[topic] = [];
-			}
-			return value;
-		};
-
-		this.Publish = function(topic, data, publisher) {
-			var subscribers = this.Get(topic);
-			for (var i = 0; i < subscribers.length; i++) {
-				if (publisher == null || subscribers[i].client != publisher) {
-					subscribers[i].callback(data);
-				}
-			}
-		};
-
-		this.Subscribe = function(topic, subscriber, callback) {
-			var subscribers = this.Get(topic);
-			subscribers.push({
-				client : subscriber,
-				callback : callback
-			});
-		};
-
-		this.Unsubscribe = function(topic, unsubscriber) {
-			var subscribers = this.Get(topic);
-			for (var i = 0; i < subscribers.length; i++) {
-				if (subscribers[i].client == unsubscriber) {
-					subscribers.splice(i, 1);
-					return;
-				}
-			}
-		};
-
-		return this;
-
-	}();
-
-}
+/*
+* Dropdown.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * @class Publisher
+ * Publish/Subscribe mechanism
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+if ( typeof Publisher == 'undefined') {
+
+	Publisher = function() {
+
+		var topics = [];
+
+		this.Get = function(topic) {
+			var value = topics[topic];
+			if (!value || !(value instanceof Array)) {
+				value = topics[topic] = [];
+			}
+			return value;
+		};
+
+		this.Publish = function(topic, data, publisher) {
+			var subscribers = this.Get(topic);
+			for (var i = 0; i < subscribers.length; i++) {
+				if (publisher == null || subscribers[i].client != publisher) {
+					subscribers[i].callback(data);
+				}
+			}
+		};
+
+		this.Subscribe = function(topic, subscriber, callback) {
+			var subscribers = this.Get(topic);
+			subscribers.push({
+				client : subscriber,
+				callback : callback
+			});
+		};
+
+		this.Unsubscribe = function(topic, unsubscriber) {
+			var subscribers = this.Get(topic);
+			for (var i = 0; i < subscribers.length; i++) {
+				if (subscribers[i].client == unsubscriber) {
+					subscribers.splice(i, 1);
+					return;
+				}
+			}
+		};
+
+		return this;
+
+	}();
+
+}
 /*
 * WidgetWrapper.js
 *
@@ -46613,42 +46618,42 @@
 	};
 
 };
-/*
-* final.js
-*
-* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-* MA 02110-1301  USA
-*/
-
-/**
- * code which is included after all other sources have been included for the minified version
- * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
- * @release 1.0
- * @release date: 2012-07-27
- * @version date: 2012-07-27
- */
-
-OpenLayers.Util.getImagesLocation = function() {
-	return GeoTemCoMinifier_urlPrefix + "lib/openlayers/img/";
-};
-
-OpenLayers._getScriptLocation = function() {
-	return GeoTemCoMinifier_urlPrefix + "lib/openlayers/";
-};
-
-GeoTemConfig.configure(GeoTemCoMinifier_urlPrefix);
+/*
+* final.js
+*
+* Copyright (c) 2012, Stefan Jänicke. All rights reserved.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301  USA
+*/
+
+/**
+ * code which is included after all other sources have been included for the minified version
+ * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de)
+ * @release 1.0
+ * @release date: 2012-07-27
+ * @version date: 2012-07-27
+ */
+
+OpenLayers.Util.getImagesLocation = function() {
+	return GeoTemCoMinifier_urlPrefix + "lib/openlayers/img/";
+};
+
+OpenLayers._getScriptLocation = function() {
+	return GeoTemCoMinifier_urlPrefix + "lib/openlayers/";
+};
+
+GeoTemConfig.configure(GeoTemCoMinifier_urlPrefix);
 })(jQuery);
--- a/map.js	Thu Jun 25 17:47:11 2015 +0200
+++ b/map.js	Fri Sep 04 16:16:10 2015 +0200
@@ -2,9 +2,10 @@
 var url="http://geoserver.mpiwg-berlin.mpg.de/geoserver/China_Monograph_Project/ows";
 
 //"name": "layer name"
-var overlayArray=[{name:"provincial distribution of local monographs",
-			file:"China_Monograph_Project:monograph_distribution_prov",
-			preload:false
+var overlayArray=[
+		{name:"provincial distribution of local monographs",
+			file:"China_Monograph_Project:monograph_distribution_prov_x",
+			preload:true
 		},
 		{
 			name:"test",
@@ -19,6 +20,7 @@
 var datasetArray=[{name:"distribution of local monographs",
 			file:"./datasets/books_coordinates.csv",
 			preload:true
+			
 		},
 		{
 			name:"distribution of local monographs (by province)",
@@ -79,6 +81,16 @@
 		var obj={name:name,file:file,preload:true};
 		datasetArray.splice(0,0,obj);
 	}
+
+	// zoe added for incoming json object from LGDataverse
+	if (urlParameter['name']!=undefined && urlParameter['file']==undefined && urlParameter['fileId']!=undefined) {
+		var file=undefined;
+		var name=decodeURI(urlParameter['name']);
+		var obj={name:name,file:file,preload:true};
+		datasetArray.splice(0,0,obj);
+	};
+	// end 
+
 	initWindowWidget();
         initWidget(); //initial Sebastian's widgets
         initToolbar(); //initial the left side icons
@@ -93,6 +105,12 @@
 			if(dataset.length==0){
 				this.checked=false;
 			}
+			// zoe added
+			if (urlParameter['file']==undefined && urlParameter['fileId']!=undefined && name==urlParameter['name']) {
+				this.checked = true;
+				this.disabled = true;
+			}
+			// end
 		});
 	});
 	$(".windowWidget").hide();
@@ -119,10 +137,74 @@
 		}
 	}
 }
+
 function loadDataset(name,fileName){
+	// zoe added
+	if (fileName==undefined) {
+		// Get file json object from POST from LGDataverse by fileId in url
+		var fileId = urlParameter['fileId'];
+		var lgdv_url = lgdataverse_url + "getDatafile?fileId="+fileId;	// lgdataverse_url is a global var
+		console.log("lgdv_url:"+lgdv_url);
+
+		var fileData = {};
+		$.ajax({
+        	url : lgdataverse_url+"getDatafile",
+        	async : false,
+	        type : 'GET',
+	        data: 'fileId='+fileId,
+	        dataType: "json",
+	        success: function (data) {
+	            console.log("getting file from LGDataverse success!");
+	            fileData = data;
+	        },
+	        error: function (data) {
+	            console.log("getting file from LGDataverse failed!" + data);
+	            alert("Data "+ urlParameter['name'] +" CANNOT be shown on the map.");
+
+	        }
+	    }).done(function(result) {
+	    	
+	    });
+
+	    if (fileData.state == "ok") {
+	    	/*
+	    	var json = [
+				{
+					// these fields are required in map
+					"description":"20卷 ╱ (民國) 崔正春修 (民國) 尚希寳纂 ╱ 民國十八年鉛印本",
+					"lat":36.974178,
+					"lon":115.259262,
+					"place":"威縣",
+					// ----
+					"tableContent":{
+						// these fields are shown as columns in the table
+						"description":"20卷 ╱ (民國) 崔正春修 (民國) 尚希寳纂 ╱ 民國十八年鉛印本",
+						"name":"(民國) 威縣志",
+						"place":"威縣",
+						"testColumn1":"content1",
+						"testColumn2":"content2",
+						"testColumn3":"content3",
+							
+					}
+				}
+			];
+			*/
+
+	    	var dataCSVformat = fileData.file.dataString;
+
+	    	//console.log(dataCSVformat);
+	    	var json = GeoTemConfig.convertCsv(dataCSVformat);
+	    	
+			GeoTemConfig.addDataset(new Dataset(GeoTemConfig.loadJson(json),name));
+
+		}
+	} else {
+	// zoe end
+
         var csvFile=GeoTemConfig.getCsv(fileName,
-                function(json){
+        	function(json){
         		GeoTemConfig.addDataset(new Dataset(GeoTemConfig.loadJson(json),name));  
+
 			//checking the checkbox has to be done here, because if done in the each loop below, it will be unchecked again in the Publisher.Subscribe function. For the Publisher.Subscribe function may be called when the dataset is not yet loaded, which causes dataset.length to be 0 and unchecks the checkbox
 			$("#datasetContainer input:checkbox[value*='"+fileName+"']").prop("checked",true); 
 			//rename the column "name" to "title"
@@ -140,6 +222,9 @@
 			pieChart.display(GeoTemConfig.datasets); */ 
                 }
         );
+   	
+   	}
+        
 }
 function closeDataset(name,fileName){
 	var idx;
--- a/map.php	Thu Jun 25 17:47:11 2015 +0200
+++ b/map.php	Fri Sep 04 16:16:10 2015 +0200
@@ -1,17 +1,29 @@
+<?php
+include_once('config/config.php');
+global $lgdataverse_url;
+
+?>
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
-        <head>
+    <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
         <link href="map.css" type="text/css" rel="stylesheet"/>
         <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript"></script>
 		<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
 		<link href="./geotemco/css/platin.css" rel="stylesheet" type="text/css">
 		<link href="WindowWidget.css" rel="stylesheet" type="text/css">
-        	<script src="./geotemco/platin.js"></script>
-        	<script src="map.js"></script>
-        	<script src="WindowWidget.js"></script>
-        </head>
-        <body>
+
+		<script type="text/javascript">
+			lgdataverse_url = JSON.parse('<?php echo json_encode($lgdataverse_url) ?>');
+		</script>
+        
+        <script src="./geotemco/platin.js"></script>
+       	<script src="map.js"></script>
+        <script src="WindowWidget.js"></script>
+    </head>
+    
+    <body>
+    
 	<div id="leftWrapper">
 		<div class="container overlayLoader">
 			<div id="overlayLoaderContainer"></div>
@@ -55,6 +67,7 @@
 					include("about.php");
 				?>
 			</div>
-		</div>	
+		</div>
+		
         </body>
 </html>