/**
 * @namespace das
 */


var das={};

das.node=function(id){
	return document.getElementById(id);
};

das.nodes=function(id){
		var r=[];
		for(var i=0;i<id.length;i++){
			r.push(document.getElementById(id[i]));
		}
		return r;
};

das.nval=function(el){
	return parseInt(el.value);
};

das.rand=function(max){
	return Math.floor(Math.random()*max);
};

das.checkFormat=function(){
	for(var i=0;i<arguments.length;i+=2){
		if(typeof(arguments[i+1]) !="string" ||
			typeof(arguments[i]) != arguments[i+1]
		) return false;
	}
	return true;
};

/**
 * Embed a function in a fixed scope wrapper.
 * @param {Function} func The function to be put in a fixed scope wrapper.
 * @param {Object} scope The scope that the function should be fixed at.
 * @return {Function}
 */
das.hardScope=function(func,scope){
	if(!das.checkFormat(
		func,"function"
	)) return false;
	
	if(das.checkFormat(
		scope,"object"
	)){
		func.$instance=scope;
		return function(){
			var args = arguments;
			args[args.length] = this;
			return func.apply(scope, args);
		};
	} else return func;
}

das.hardScopeFixedParameter=function(func,scope){
	func.$instance=scope;
	var additionParameters=[];
	for(var i=2;i<arguments.length;i++)
		additionParameters.push(arguments[i]);
		
	return function(){
		var args = arguments;
		args[args.length] = this;
		args=additionParameters.concat(args);
		return func.apply(scope, args);
	};
}


das.makeDeepCopy=function(obj){
	if((typeof(obj)!="object") || (!(obj instanceof Array) && obj.constructor!=Object) || obj==null)
		return obj;
	
	var out;
	
	if(obj instanceof Array){
		out=[];
		for(var i=0;i<obj.length;i++){
			if((typeof(obj[i])=="object") && obj[i]!=null)
				out.push(das.makeDeepCopy(obj[i]));
			else
				out.push(obj[i]);
		}
	}else{
		out={};
		for(var i in obj){
			if( i!="constructor" && i!="prototype" && typeof(obj[i])=="object" && obj[i]){
				out[i]=das.makeDeepCopy(obj[i]);
			}else
				out[i]=obj[i];
		}
	}

	return out;
}

das.addEvent=function(el,type,handler,scope,userEvent){
		if(!das.checkFormat(
			el,"object",
			type,"string",
			handler,"function"
		)) return false;
		
		var encHandler=null;
		

		if(das.checkFormat(scope,"object"))
			encHandler=das.hardScope(handler,scope);
		else
			encHandler=handler;
		
		if(userEvent) encHandler[2]=das.addUserEventListener(el,type,encHandler);
		else if(el.addEventListener) el.addEventListener(type,encHandler,false);
		else if(el.attachEvent) el.attachEvent("on"+type,encHandler);
		return encHandler;
	}

	das.removeEvent=function(el,type,handler,userEvent){
		if(userEvent) das.removeUserEventListener([el,type,handler]);
		else if(el.removeEventListener) el.removeEventListener(type,handler,false);
		else if(el.detachEvent) el.detachEvent("on"+type,handler);
	}

/*
	das.encMethods
		�berschreibt alle Methoden eines Objekts mit Scope Wrappern
*/
das.encMethods=function(obj,scope,follow){
	if(!das.checkFormat(
		obj,"object"
	)) return false;
	
	
	if(typeof(scope)=="undefined") scope=obj;
	for(var i in obj){
		if(typeof(obj[i])=="function"){
			obj[i]=das.hardScope(obj[i],scope);
		}else if(typeof(obj[i])=="object"){
			if(follow) das.encMethods(obj[i],scope);
		}
	}
	
	return obj;
}

/*
	(Klasse) das.httpRequest
		sendet eine HTTP Anfrage und liefert das Ergebnis an die Handlerfunktion
*/
das.httpRequest=function(url,targetfnc,servexml,cross){
try{
				netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
}catch(e){}
	das.encMethods(this);
	
	this.targetfunc=targetfnc;
	this.servexml=servexml;
	this.http_request = new XMLHttpRequest();
	this.http_request.overrideMimeType((this.servexml?'text/xml':'text/plain'));

	
	this.http_request.open("GET", url,cross);
	this.http_request.onload = this.responseHandler;
	this.http_request.send(null);
}

das.httpRequest.prototype.responseHandler=function(response){
//				netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	if ((response.target.readyState == 4) && (response.target.status == 200 || (response.target.status == 0)))
		this.targetfunc((this.servexml?response.target:response.target.responseText));
}
			
/*
	das.walkTree
		Folgt einer Objektstruktur entsprechend des Properties die im Array angegeben wurden
*/
das.walkTree=function(obj,propTreeArray){
	for(var i=0;i<propTreeArray.length;i++){
		if(typeof(obj[propTreeArray[i]])=="undefined") return undefined;
		obj=obj[propTreeArray[i]];
	}
	return obj;
}
			


/*
	das.bubbleSort
		Sortiert ein Array
*/
das.bubbleSort=function(arr,propTreeArray){
	var ch;
	do{
		ch=false;
		for(var i=0;(i+1)<arr.length;i++){
			var ev0=das.walkTree(arr[i],propTreeArray);
			var ev1=das.walkTree(arr[i+1],propTreeArray);
			
			if(typeof(ev0)=="undefined" || typeof(ev1)=="undefined") return undefined;
			if(ev0 > ev1){
				var t=arr[i];
				arr[i]=arr[i+1];
				arr[i+1]=t;
				ch=true;
			}
		}
	}while(ch);
	
	return arr;
}

/*
	das.shuffle
		Mischt ein Array
*/
das.shuffle=function(arr,cnt){
	if(typeof(cnt)=="undefined") cnt=10;
	
	for(var i=0;i<(arr.length*cnt);i++){
		var f1=Math.floor(Math.random()*arr.length);
		var f2=Math.floor(Math.random()*arr.length);
		
		var t=arr[f1];
		arr[f1]=arr[f2];
		arr[f2]=t;
	}
	
	return arr;
}
/*
	das.getElementsByClass
		Findet alle Elemente mit angegebenem Typ und Klasse
*/
das.getElementsByClass=function(cls,el){
	if(typeof(el)!="undefined"){
		var r=[];
		var ns=document.getElementsByTagName(el);
		for(var i=0;i<ns.length;i++){
			if(ns[i].className==cls) r.push(ns[i]);
		}
		return (r);
	}
}
			
/*
	das.serialize
		Serialisiert Objekte
*/
das.serialize=function(obj,lvl){
	if(!lvl)lvl=0;
	var s="";
	for(var i=0;i<lvl;i++) s+="\t";
	var out="";
	if(obj instanceof Array){
		out+=s+"[\n";
		for(var i=0;i<obj.length;i++) out+=das.serialize(obj[i],lvl+1)+",\n";
		out+=s+"]\n";
	}else if(typeof(obj)=="string"){
		out+=s+'"';
		out+=obj.replace("\n","\\n").replace("\r","\\r").replace("\"","\\\"");
		out+='"';
	}else if(typeof(obj)=="number"){
		out+=s+obj;
	}else if(typeof(obj)=="undefined"){
		out+=s+"undefined";
	}else if(typeof(obj)=="null"){
		out+=s+"null";
	}else if(typeof(obj)=="boolean"){
		out+=s+(obj?true:false);
	}else if(typeof(obj)=="function"){
		out+=s+("null");
	}else if(typeof(obj)=="object"){
		out+=s+"{\n";
		for(var i in obj) out+="\""+i+"\": "+das.serialize(obj[i],lvl+1)+",\n";
		out+=s+"}\n";
	}
	return out;
}

/*
	das.topLeft
		Liefert die obere linke Ecke eines Elements
		Sind x und y angegeben wird die obere linke Ecke stattdessen an diese Position vershcoben
*/
das.topLeft=function(node,x,y){
	if(typeof(x)=="number" && typeof(y)=="number"){
		var offset=null;
		if(node.offsetParent)
			offset=das.topLeft(node.offsetParent);
		else
			offset={x:0,y:0};
		
		das.pAbs(node,x-offset.x,y-offset.y);
	}else{
		var x=0;
		var y=0;
		do{
			x+=node.offsetLeft-node.scrollLeft;
			y+=node.offsetTop-node.scrollTop;
		}while((node=node.offsetParent));
		return({x:x,y:y});
	}
}

/*
	das.bottomRight
		Liefert die untere rechte Ecke eines Elements
		Sind x und y angegeben wird die untere rechte Ecke stattdessen an diese Position vershcoben
*/
das.bottomRight=function(node,x,y){
	if(typeof(x)=="number" && typeof(y)=="number"){
		var offset=null;
		if(node.offsetParent)
			offset=das.topLeft(node.offsetParent);
		else
			offset={x:node.offsetWidth,y:node.offsetHeight};
		
		das.pAbs(node,x-offset.x,y-offset.y);
	}else{
		var x=node.offsetWidth;
		var y=node.offsetHeight;
		do{
			x+=node.offsetLeft;
			y+=node.offsetTop;
		}while((node=node.offsetParent));
		return({x:x,y:y});
	}
};

das.getWindowDimensions=function(){
	var base=null;
	var compat=false;
	if(document.compatMode=='BackCompat' || !document.compatMode || !document.documentElement) compat=true;
	
	base=(compat?document.body:document.documentElement);
	
	var r={"x":base.clientWidth,"y":base.clientHeight,"u":base.scrollLeft,"v":base.scrollTop};
	if(window.innerWidth){
		var w=window.innerWidth;
		var h=window.innerHeight;
		if(Math.abs(r.x-w)>20) r.x=w;
		if(Math.abs(r.y-h)>20) r.y=h;
	}
	
	return r;
}

das.pAbs=function(node,x,y,w,h,xi,yi){
	if(!node) return;
	node.style.position="absolute";
	if(x!=undefined) node.style[(xi?"right":"left")]=x+"px";
	if(y!=undefined) node.style[(yi?"bottom":"top")]=y+"px";
	if(w!=undefined) node.style.width=w+"px";
	if(h!=undefined) node.style.height=h+"px";
}

das.clone=function(obj){
	if(typeof(obj)!="object") return obj;
	
	var out={};
	
	for(var i in obj)
		if(obj.hasProperty(i))
			out[i]=obj[i];
	
	return out;
}

das.json2html=function(tree){
	if(typeof(tree)!="object") return document.createTextNode(String(tree));
	else if(tree instanceof HTMLElement) return tree;
	
	var node=document.createElement(tree[0]);
	for(var i=1;i<tree.length;i++){
		if(tree[i] instanceof Array) for(var j=0;j<tree[i].length;j++) node.appendChild(arguments.callee(tree[i][j]));
		else for(var j in tree[i]) node.setAttribute(j,String(tree[i][j]));
	}
	
	return node;
};

das.insertAfter=function(newNode,prevNode){
	if(newNode==prevNode) return;
	var next=prevNode;
	
	do{
		next=next.nextSibling;
	}while(next && next.nodeType!=1);
	if(next) next.parentNode.insertBefore(newNode,next);
	else prevNode.parentNode.appendChild(newNode);
	
	return true;
}

das.swap=function(obj,p1,p2){
	var t=obj[p1];
	obj[p1]=obj[p2];
	obj[p2]=t;
};

das.clickInEl=function(evt,el){
	var ol=das.topLeft(el);
	return !(evt.clientX<ol.x || evt.clientY<ol.y || evt.clientX>ol.x+el.offsetWidth || evt.clientY>ol.y+el.offsetHeight);
}

das.nonBlockingLoop=function(initFunc,condFunc,postFunc,bodyFunc){
	if(!(this instanceof das.nonBlockingLoop)) throw (new das.exception("das.nonBlockingLoop $constructor called as function",5,1025));
	das.encMethods(this);
	this.init=initFunc;
	this.condition=condFunc;
	this.post=postFunc;
	this.body=bodyFunc;
	this.funcVariables={};
	
	this.init.call(this.funcVariables);
	if(!this.condition.call(this.funcVariables)) return;
	
	this.runLoop();
}

das.nonBlockingLoop.prototype.runLoop=function(){
	this.body.call(this.funcVariables);
	this.post.call(this.funcVariables);
	if(this.condition.call(this.funcVariables)) window.setTimeout(this.runLoop,50);
}
			
das.timetween=function(callback,totaltime, se,mindelay){
	var animdata={};
	animdata.mindelay=(mindelay?mindelay:25);
	animdata.totaltime=totaltime;
	animdata.callback=callback;
	
	animdata.startvals=[];
	animdata.range=[];
	animdata.endvals=[];

	for(var i=0;i<se.length;i++){
		animdata.startvals.push(se[i][0]);
		animdata.range.push(se[i][1]-se[i][0]);
		animdata.endvals.push(se[i][1]);
	}
	
	var loop=null;
	loop=das.hardScope(function(){
		if(this.time>=this.totaltime) this.callback(this.endvals,true);
		else{
			var vals=[];
			var p=this.time/this.totaltime;
			for(var i=0;i<this.startvals.length;i++)
				vals.push(this.startvals[i]+this.range[i]*p);

			this.callback(vals,false);
			this.time=(new Date()).getTime()-this.start;
			window.setTimeout(loop,this.mindelay);
		}
	},animdata);
	animdata.start=(new Date()).getTime();
	animdata.time=0;
	loop(animdata);
}

das.UserEvent=function(type,param){
	this.type=type;
	this.param=param;
}

das.addUserEventListener=function(el,type,target,scope){
	if(!el) throw("addUserEventListener on non-existent element");
	var exists=false;
	if(!el.__$tw$__userEventListeners) el.__$tw$__userEventListeners={};
	
	if(scope) target=das.hardScope(target,scope);
	
	if(!el.__$tw$__userEventListeners[type]) el.__$tw$__userEventListeners[type]=target;
	else if(typeof(el.__$tw$__userEventListeners[type])=="function"){
		if(el.__$tw$__userEventListeners[type]!=target)
			el.__$tw$__userEventListeners[type]=[el.__$tw$__userEventListeners[type],target];
		else
			exists=true;
	}else if(el.__$tw$__userEventListeners[type] instanceof Array){
		for(var i=0;i<el.__$tw$__userEventListeners[type].length;i++)
			if(el.__$tw$__userEventListeners[type][i]==target) exists=true;
		
		if(!exists)el.__$tw$__userEventListeners[type].push(target);
	}
	
	if(!exists)
		return [el,type,target];
	else
		return null;
}

das.removeUserEventListener=function(el_type_target_Array){
	if(!(el_type_target_Array instanceof Array)) return false;
	
	el=el_type_target_Array[0];
	type=el_type_target_Array[1];
	target=el_type_target_Array[2];
	
	if(!el) return false;
	if(typeof(type)!="string") return false;
	if(typeof(target)!="function") return false;
	
	if(!el.__$tw$__userEventListeners) return false;
	if(!el.__$tw$__userEventListeners[type]) return false;
	
	if(typeof(el.__$tw$__userEventListeners[type])=="function"){
		if(el.__$tw$__userEventListeners[type]==target) el.__$tw$__userEventListeners[type]=null;
	}else if(el.__$tw$__userEventListeners[type] instanceof Array){
		for(var i=0;i<el.__$tw$__userEventListeners[type].length;i++)
			if(el.__$tw$__userEventListeners[type][i]==target){
				el.__$tw$__userEventListeners[type].splice(i,1);
				return;
			}
	}
}

das.dispatchUserEventToSingleElement=function(el,evt){
	if(!el.__$tw$__userEventListeners || !el.__$tw$__userEventListeners[evt.type]) return;
	if(typeof(el.__$tw$__userEventListeners[evt.type])=="function")
		el.__$tw$__userEventListeners[evt.type].call(el,evt);
	else if((el.__$tw$__userEventListeners[evt.type]) instanceof Array)
		for(var i=0;i<el.__$tw$__userEventListeners[evt.type].length;i++)
			el.__$tw$__userEventListeners[evt.type][i].call(el,evt);
}

das.dispatchUserEvent=function(el,evt){
	do{
		if(el!=window && el!=document) das.dispatchUserEventToSingleElement(el,evt);
	}while((el=el.parentNode));
	
	das.dispatchUserEventToSingleElement(document,evt);
	das.dispatchUserEventToSingleElement(window,evt);
}

das.propagateUserEvent=function(el,evt){
	var baseEl=el;

	do{
		das.dispatchUserEventToSingleElement(el,evt);
		if(el.firstChild) el=el.firstChild;
		else if(el.nextSibling) el=el.nextSibling;
		else{
			while(!el.nextSibling && el!=baseEl){ el=el.parentNode;}
			if(el!=baseEl) el=el.nextSibling;
		}
	}while(el!=baseEl)
	
}

das.makeOverload=function(){
	var innerHandlers=[];
	for(var i=0;i<arguments.length;i++){
		if(!(arguments[i] instanceof Array))
			throw("Incorrect overload definition: a parameter is not an Array");
		for(var j=0;j<arguments[i].length;j++)
			if(typeof(arguments[i][j])!="function" && typeof(arguments[i][j])!="string" && typeof(arguments[i][j])!="object")
				throw("Incorrect overload definition: a parameter element is not string or function");
		
		if(typeof(arguments[i][arguments[i].length-1])!="function")
			throw("Incorrect overload definition: last parameter element is not a function");
		
		innerHandlers.push(arguments[i]);
			
	}
	
	innerHandlers=innerHandlers.sort(function(a,b){return b.length-a.length;});

	var handler=function(){
		
		var args=[];
		for(var i=0;i<arguments.length;i++)
			args.push(arguments[i]);
		
		var match=false;
		
		for(var i=0;i<innerHandlers.length && !match;i++){
			match=true;
			for(var j=0; j<(innerHandlers[i].length-1) && match; j++){
				if(typeof(innerHandlers[i][j])=="string" && typeof(arguments[j])!=innerHandlers[i][j])
					match=false;
				if((typeof(innerHandlers[i][j])=="function" || typeof(innerHandlers[i][j])=="object") && !(arguments[j] instanceof innerHandlers[i][j]))
					match=false;
			}
			if(match){
				return innerHandlers[i][innerHandlers[i].length-1].apply(this,args);
			}
		}
		
		throw("No match for overloaded function call");
	}

	return handler;
}

das.defineClass=das.makeOverload(
	["object","function",function(prototype,inherit){
		if(inherit==Object)
			inherit=undefined;
			
		if(typeof(inherit)!="undefined" && (typeof(inherit)!="function" || inherit.isInheritable!=true))
			throw("das.defineClass can only inherit from das.defineClass created constructror.");
			
		var classCtor=function(){
			for(var i in this){
				
				var typed=(/^\$_(.*?)_(.*)$/).exec(i);
				if (typeof(this[i]) != 'function' && typed) {
					var f = function(v){
						if(arguments.length==0) return arguments.callee.propertyValue;
						
						if (typeof(v) != arguments.callee.propertyType) 
							throw ('IncorrectType Property Exception');
						else 
							arguments.callee.propertyValue = v;
					}
					f.isConstructorHandled=true;
					f.propertyName=typed[2];
					f.propertyType=typed[1];
					f.propertyValue=this[i];
					
					this.__defineSetter__(typed[2],f);
					this.__defineGetter__(typed[2],f);
					
					delete this[i];
				}
			
				if(typeof(this[i])=="function" && !this[i].isConstructorHandled)
					this[i]=das.hardScope(this[i],this);

				if( i!="constructor" &&  i!="prototype" ){
					if( this[i] && typeof(this[i])=="object")
						this[i]=das.makeDeepCopy(this[i])
					else
						this[i]=this[i];
				}

			}
			
			if(this["$ctor"])
				this.constructor=this["$ctor"].innerFunction;
			else
				this.constructor=undefined;
				
			if(this["$ctor"]){
				this["$ctor"].apply(this,arguments);
			}
		};
		
		classCtor.methods={};
		classCtor.isInheritable=true;
		
		var parentCtor=function(){};
		
		if(inherit)
			parentCtor.prototype=inherit.prototype;
			
		var parent=new parentCtor();
		classCtor.prototype=parent;
		for(var i in parent)
			if(typeof(parent[i])=="function") classCtor.methods[i]=parent[i];
		
		for(var i in prototype){
			if(typeof(prototype[i])=="function"){
				prototype[i].ownerClass=classCtor;
				prototype[i].__$parentMethod=parent[i];
				classCtor.methods[i]=prototype[i];
			}
			
			if(i!="constructor" && i!="name" && i!="$inherit" && i!="prototype")
				if(prototype[i] && typeof(prototype[i])=="object")
					classCtor.prototype[i]=das.makeDeepCopy(prototype[i]);
				else
					classCtor.prototype[i]=prototype[i];
				

		}
			
		return classCtor;
	}],
	
	
	["object",function(prototype){
		var parent=Object;
		if(typeof(prototype.$inherit)=="function"){
			parent=prototype.$inherit;
			delete prototype.$inherit;
		}
		
		return das.defineClass(prototype,parent);
	}],
	["string","object",function(name,prototype){
		return (window[name]=das.defineClass(prototype));
	}],
	["string","object","function",function(name,prototype,inherit){
		return (window[name]=das.defineClass(prototype,inherit));
	}]
);

das.EvtListener=das.defineClass({
	type:null,
	el:null,
	handler:null,
	internalhandler:null,
	isUser:false,
	
	$ctor:function(elarg,typearg,handlerarg,isUserEvent){ with(this){
		if(elarg instanceof Array) el=elarg; else el=[elarg];
		if(typearg instanceof Array) type=typearg; else type=[typearg];
		if(handlerarg instanceof Array) handler=handlerarg; else handler=[handlerarg];
		internalhandler=[];
		isUser=isUserEvent;
		
		for(var i=0;i<el.length;i++){
			if(typeof(el[i])=="string") el[i]=document.getElementById(el[i]);
			for(var j=0;j<type.length;j++)
				for(var k=0;k<handler.length;k++){
					internalhandler.push(das.addEvent(el[i],type[j],handler[k],undefined,isUser));
				}
		}
	}},
	
	cancel:function(){with(this){
		if(!internalhandler || !internalhandler.length) return;

		
		for(var i=0;i<internalhandler.length;i++){
			
			das.removeEvent(el[i],type[i],internalhandler[i],isUser);
			el[i]=null;type[i]=null;internalhandler[i]=null;handler[i]=null;
		}
		el=null;handler=null;internalhandler=null;type=null;
		
	}}

});


das.CSSForwardLookingRule=das.defineClass({
	__parseVals:/\s*([^\s:]+)\s*:\s*(.*?)\s*[;$]/g,
	$ctor:function(rule,values,baseEl){
		this.baseEl=baseEl;
		this.parseRule(rule,values);
	},
	parseRule:function(ruleStr,valueStr){
		var r;
		while (r = this.__parseVals.exec(valueStr)) {
			var t=r[1].replace(/-([a-z])/g,function(p){return p[1].toUpperCase();})
			this.styleProps[t]=r[2];
		};
		
		var sep=ruleStr.indexOf("%");
		if(sep < 0){
			this.baseRule=ruleStr;
			this.conditionRule=null;
			this.isForwardLooking=false;
		}else{
			this.baseRule=ruleStr.substring(0,sep);
			this.conditionRule=ruleStr.substring(sep+1,ruleStr.length+1);
			this.isForwardLooking=true;
		}	
	},
	applyRule:function(){
		var nodes=this.baseEl.querySelectorAll(this.baseRule);
		if(this.isForwardLooking){
			var input=nodes;
			nodes=[];
			
			for(var i=0;i<input.length;i++)
				if(input[i].querySelector(this.conditionRule))
					nodes.push(input[i]);
		}
		
		for(var i=0;i<nodes.length;i++){
			for(var j in this.styleProps){
				nodes[i].style[j]=this.styleProps[j];
			}
		}
	},
	baseEl:null,
	isForwardLooking:false,
	styleProps:{},
	baseRule:"*",
	conditionRule:"*"
});


das.CSSForwardLookingRuleset=das.defineClass({
	__parseRules:/\s*(.*?)\s*\{\s*(.*?)\s*\}/g,
	$ctor:function(rules,baseEl){
		this.baseEl=baseEl;
		this.addRules(rules);
	},
	addRules:function(ruleStr){
		ruleStr=ruleStr.replace("\n"," ");
		var r;
		while(r=this.__parseRules.exec(ruleStr)){
			this.rules.push(new das.CSSForwardLookingRule(r[1],r[2],this.baseEl));
		}
	},
	applyRules:function(){
		for(var i=0;i<this.rules.length;i++)
			this.rules[i].applyRule();
	},
	rules:[],
	baseEl:null
});

das.CanvasPath=function(absCoordArray){
	this.coords=absCoordArray;
};
das.CanvasPath.prototype={
	coords:null,
	closed:false,
	pointIsInside:function(x,y,canvas){
		var hit=false;
		var c=canvas.getContext("2d");
		c.save();
		c.beginPath();
		c.moveTo(this.coords[0][0],this.coords[0][1]);
		
		for(var i=1;i<this.coords.length;i++)
			c.lineTo(this.coords[i][0],this.coords[i][1]);

		c.closePath();
		hit=c.isPointInPath(x,y);
		c.restore();
		return(hit);
	},
	draw:function(fillStyle,strokeStyle,canvas){
		var c=canvas.getContext("2d");
		c.save();
		c.beginPath();
		c.moveTo(this.coords[0][0],this.coords[0][1]);
		
		for(var i=1;i<this.coords.length;i++)
			c.lineTo(this.coords[i][0],this.coords[i][1]);

		if(this.closed)
			c.closePath();
			
		if(fillStyle){
			c.fillStyle=fillStyle;c.fill();
		}
		
		if(strokeStyle){
			c.strokeStyle=strokeStyle;c.stroke();
		}
		
		c.restore();

	}
};

das.CanvasPathList=function(svgPathDString){
	this.loadSvgPathD(svgPathDString);
};

das.CanvasPathList.prototype={
	subPaths:null,
	loadSvgPathD:function(svgPathDString){
		this.subPaths=[];
		
		var getCmd=/(?:([zZmMlL])|([0-9.\-]+)[\s,]([0-9.\-]+))/g;
		var cmd=null;
		var mode="M";
		var action="m";
		var x=0;
		var y=0;
		var closed=false;
		var currentSubPath=[];
		while(cmd=getCmd.exec(svgPathDString)){
			if(cmd[1]){
				action=(mode=cmd[1]).toLowerCase();
				if(action=="z"){
					closed=true;
				}
			}else{
				var isRelative=mode.match(/[a-z]/);
				x=(isRelative?x:0)+window.parseFloat(cmd[2]);
				y=(isRelative?y:0)+window.parseFloat(cmd[3]);

				switch(action){
					case "m":
						if(currentSubPath.length){
							if(currentSubPath.length>1){
								var currentSubPathObject=new das.CanvasPath(currentSubPath);
								currentSubPathObject.closed=closed;
								this.subPaths.push(currentSubPathObject);
							}
							currentSubPath=[[x,y]];
						}
						closed=false;
						action=(mode=(isRelative?"l":"L")).toLowerCase();
						break;
					case "l":
						currentSubPath.push([x,y]);
						break;
				}
			}
			
		}
		if(currentSubPath.length>1){
			var currentSubPathObject=new das.CanvasPath(currentSubPath);
			currentSubPathObject.closed=closed;
			this.subPaths.push(currentSubPathObject);
		}
		return false;
	},
	pointIsInside:function(x,y,canvas){
		for(var i=0;i<this.subPaths.length;i++)
			if(this.subPaths[i].pointIsInside(x,y,canvas))
				return true;
				
		return false;
	},
	draw:function(fillStyle,strokeStyle,canvas){
		for(var i=0;i<this.subPaths.length;i++)
			this.subPaths[i].draw(fillStyle,strokeStyle,canvas);
	}
};


das.CachedVectorGraphic=das.defineClass({
		svgPath:"",
		w:0,
		h:0,
		ready:false,
		bitmapImg:null,
		canvas:null,
		iframe:null,
		$ctor:function(svgPath,w,h){
			this.svgPath=svgPath;
			this.w=w;
			this.h=h;
		}
});

das.collectPerRegExp=function(base, reg,res){
	var m;
	while(m=reg.exec(base)){ res.push(m[1]); }
}


das.FlatHttpRequest=function(url,targetfnc){
	try{
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	}catch(e){}
	das.encMethods(this);
	
	var parts=(/http:\/\/([^\/]+)(|.*)$/).exec(url);
	if(!parts)
		return;
		
	this.server=parts[1];
	this.path=(parts[2]?parts[2]:"/");
	
	this.transportService=Components.classes["@mozilla.org/network/socket-transport-service;1"] .getService(Components.interfaces.nsISocketTransportService)
	this.transport=this.transportService.createTransport(null,0,this.server,80,null);

	var out="GET "+this.path+" HTTP/1.0\n\n";
	this.outstream = this.transport.openOutputStream(0,0,0);
	this.outstream.write(out,out.length);

	this.stream = this.transport.openInputStream(0,0,0);
	this.instream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
	this.instream.init(this.stream);

	this.pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);
	this.pump.init(this.stream, -1, -1, 0, 0, false);
	this.pump.asyncRead(this,null);
	

	this.targetfunc=targetfnc;
}

das.FlatHttpRequest.prototype={
	url:"",
	server:"",
	path:"",
	data:"",
	
	transportService:null,
	transport:null,
	stream:null,
	instream:null,
	outstream:null,
	pump:null,
	
	targetfunc:null,
	onStartRequest: function(request, context){},
	onStopRequest: function(request, context, status){
		this.instream.close();
		this.outstream.close();
		this.targetfunc(this.data);
	},
	onDataAvailable: function(request, context, inputStream, offset, count){
		this.data += this.instream.read(count);
	},
}

das.limitRange=function(v,min,max){
	if(v<min) v=min;
	if(v>max) v=max;
	return v;
};

das.pad=function(str,l,pad){
	var r=str.toString();
	while(r.length<l){
		r=pad+r;
	}
	
	return r;
}