	// fügt einer Tabelle zeilen und zellen hinzu (elterelement el, einzufügender htmlcode html, [positon i (-1=ende)], [argumente name:wert;name:wert;...]
function addOneCell(el,html) {
	if (addOneCell.arguments.length>2) var i = addOneCell.arguments[2]; else var i = -1;
	var nR = el.insertRow(i);
	if (addOneCell.arguments.length>3) {
		var attr = addOneCell.arguments[3].split(";");
		for (var i in attr) {
			if (typeof(attr[i])!="string") continue;
			var at = attr[i].split(":");
			nR.setAttribute(at[0],at[1]);
		}
	}
	var nC = nR.insertCell();
	nC.innerHTML = html;
	return nC;
}

function menuX(el,content) {
	if (self.document.getElementById("menuX") && content!=self.document.getElementById("menuX").innerHTML) {
		top.document.body.removeChild(self.document.getElementById("menuX"));
	} 
	if (!self.document.getElementById("menuX")) {
		if (menuX.arguments.length>2 && menuX.arguments[2]!="") var addX = menuX.arguments[2]; else addX=false;
		if (menuX.arguments.length>3 && menuX.arguments[3]!="") var addY = menuX.arguments[3]; else addY=false;
		var smenu = top.document.createElement("DIV");
		with(smenu) {
			id="menuX";
			innerHTML = content;
			//style.left = absoluteLeft(el)+"px";
			//style.top = absoluteTop(el)+el.offsetHeight+"px";
			//style.left = self.event.x+top.screenLeft+"px";
			if (addX) style.left = (self.event.x+addX)+"px"; else style.left = (self.event.x)+"px";
			if (addY) style.top = (self.event.y+addY)+"px"; else style.top = (self.event.y)+"px";
		}
		top.document.body.appendChild(smenu);
	}
	return true;
}

function removeMenuX() {
	if (top.document.getElementById("menuX"))
		top.document.body.removeChild(top.document.getElementById("menuX"));
}

function addTableRows(rw,tb) {
	rw = rw.firstChild.firstChild;
	var n,d;
	for (var i=0;i<rw.childNodes.length;i++) {
		n = tb.insertRow(-1);
		if (rw.childNodes[i].attributes)
			for (var a=0;a<rw.childNodes[i].attributes.length;a++)
				n.setAttribute(rw.childNodes[i].attributes[a].nodeName,rw.childNodes[i].attributes[a].nodeValue);
		for (var b=0;b<rw.childNodes[i].childNodes.length;b++) {
			d = n.insertCell();
			if(rw.childNodes[i].childNodes[b].attributes)
				for (var e=0;e<rw.childNodes[i].childNodes[b].attributes.length;e++)
					d.setAttribute(rw.childNodes[i].childNodes[b].attributes[e].nodeName,rw.childNodes[i].childNodes[b].attributes[e].nodeValue);
			d.innerHTML = rw.childNodes[i].childNodes[b].innerHTML;
		}
	}
}


function tooltipX(el) {
	if (self.document.getElementById("tooltipX") && el.tooltipX!=self.document.getElementById("tooltipX").innerHTML) {
		top.document.body.removeChild(self.document.getElementById("tooltipX"));
	} 
	if (!self.document.getElementById("tooltipX")) {
		var stip = top.document.createElement("DIV"), mouseDiver = 20, upperFrameDiv = 115;
		with(stip) {
			id="tooltipX";
			innerHTML = el.tooltipX;
			//style.left = absoluteLeft(el)+"px";
			//style.top = absoluteTop(el)+el.offsetHeight+"px";
			style.left = self.event.x+self.screenLeft-6+"px";
			style.top = (self.event.y+mouseDiver+upperFrameDiv)+"px";
		}
		top.document.body.appendChild(stip);
		if((self.event.y*1+mouseDiver+stip.offsetHeight*1)>self.document.body.offsetHeight) 
			stip.style.top = (self.event.y+upperFrameDiv)-stip.offsetHeight;
		//alert("maxtiefe: "+(self.event.y*1+mouseDiver+stip.offsetHeight*1)+" (höhe: "+stip.offsetHeight+")\n\nseite: "+self.document.body.offsetHeight+"\n\nscrollHeight: "+self.document.body.scrollTop);
	}
}

function removeTooltipX() {
	if (top.document.getElementById("tooltipX"))
		top.document.body.removeChild(top.document.getElementById("tooltipX"));
}

function moveTooltipX(el) {
	if (top.document.getElementById("tooltipX") && el.tooltipX!=top.document.getElementById("tooltipX").innerHTML) {
		with(top.document.getElementById("tooltipX")) {
			style.left = self.event.x-6+"px";
			style.top = self.event.y+20+115+"px";
		}
	}
}

// liefert das mit name bezeichnete css -vorgabe
function getCssRule(win,pos,name) {
	for (var i in win.document.styleSheets(pos).rules) {
		if (win.document.styleSheets(pos).rules[i].selectorText && win.document.styleSheets(pos).rules[i].selectorText.toLowerCase()==name.toLowerCase())
			return win.document.styleSheets(pos).rules[i];
	}
	logErr("css-Name "+name+" nicht gefunden");
	return false;
}

/* ##### js_self(window) ###############################################################################################
##  gibt den ganzen pfad zur aktuellen htmlscriptvater zurück ohne window.location.search
##  bei übergabe des fensternamens (z.B. top, parent, self oder auch Name) wird der Pfad dieses Fensters ausgegeben
##  kann leider nicht selber feststellen, ob ein fenster existiert, da js schon baim aufruf einen fehler meldet.
################################################################################################################*/

function js_self() {
	if (js_self.arguments.length>0 && typeof(js_self.arguments[0])=="object") var win = js_self.arguments[0]; 
	else var win=self;
	return win.location.protocol+"//"+win.location.hostname+win.location.pathname;
}


/* ##### writeGET(str insert) ####################################################################################
##  schreibt, wenn vorhanden insert in arr GET und gibt GET als fertigen window.location.search string aus
##  schema insert "key=val" oder "key"
################################################################################################################*/

function writeGET(insert) {
	var stringGET="";
	if (insert) insert=insert.split("=");
	if (typeof(GET)=="undefined") readGET();
	if (insert) GET[insert[0]]=insert[1];
	if (GET) { for (var key in GET) { stringGET+="&"+key+"="+GET[key]; } }
	if (stringGET.length>0) return "?"+stringGET.slice(1); else return "";
}

/* ##### readGET(str ask) ########################################################################################
##  liest get parameter in Array Get[assoc] und beantwortet evetuelle str ask mit true oder false
##        schema insert "key=val" oder "key"
################################################################################################################*/

function readGET(ask) {
	if (ask) ask = ask.split("=");
	if (typeof(GET)=="undefined") GET=new Array();
	var GETlength=0;
	for (var val in GET) { GETlength++; }
	if (GETlength<1 && self.location.search) {
		var tempget = self.location.search.slice(1).split("&");
		for (var i=0;i<tempget.length;i++) { var tempkeyval=tempget[i].split("="); GET[tempkeyval[0]]=tempkeyval[1]; }
	}
	if (ask && !self.location.search) { return false; }
	else if (ask && GET[ask[0]]!=null && ask[1]==null) { return true; }
	else if (ask && ask[1]!=null && GET[ask[0]]==ask[1]) { return true; }
	else { return false; }
}

function GETarg(b) {
	var newget = "";
	var bget;
	var c=0;
	if (get!="") {
		bget = get.slice(1);
		bget = bget.split("&");
		for (var i=0;i<bget.length;i++) {
			if (bget[i].slice(0,bget[i].indexOf("="))==b.slice(0,b.indexOf("="))) {
				newget += b+"&";
			} else {
				newget += bget[i]+"&";
				c++;
			}
		}
		if (c==i) {
			newget +=b;
		} else {
			newget = newget.slice(0,-1);
		}
	} else {
		newget = b;
	}
	return("?"+newget);
}

var getarg = false;
function get(searchfor,where) {
   if (!where) var where="window";
   if (getarg==false) {
      getarg=new Array();
      if (eval(where+".location.search")=="") {
         return false;
      } else {
         var newpar = eval(where+".location.search.slice(1).split(\"&\")");
         for (var i=0;i<newpar.length;i++) {
            getarg[newpar[i].slice(0,newpar[i].indexOf("="))]=newpar[i].slice((newpar[i].indexOf("=")+1));
         }
         newpar=null;
         if (!getarg[searchfor]) return false; else return getarg[searchfor];
      }
   } else {
         if (!getarg[searchfor]) return false; else return getarg[searchfor];
   }
}




/* transAssoc(arr assoc [, str keydelemiter] [, str, valdelemiter] ) ###################################################
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## gibt assoc (assoziatives array) als string zurück. die trennung wird standardmässig mit (key:val;) gemacht.        ##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */


function transAssoc(assoc) {
	var keydelemiter = ":";
	var valdelemiter = ";";
	if (transAssoc.arguments.length>1) keydelemiter = transAssoc.arguments[1];
	if (transAssoc.arguments.length>2) valdelemiter = transAssoc.arguments[2];
	var output="";
	for (var i in assoc) output+=i+keydelemiter+assoc[i]+valdelemiter;
	return output
}

// schreibt einen string in ein array, zerteilung des strings durch key- und valdelemiter beschreibbar
function toAssoc(str) {
	var keydelemiter = ":"; if (toAssoc.arguments.length>1) keydelemiter = toAssoc.arguments[1];
	var valdelemiter = ";";	if (toAssoc.arguments.length>2) valdelemiter = toAssoc.arguments[2];
	var arr = new Array(), key="", val="", keypos=0, valpos=0;
	while (str.length>0) {
		keypos=str.indexOf(keydelemiter); valpos=str.indexOf(valdelemiter);
		if (valpos==-1) valpos=str.length;
		if (keypos>-1 && valpos>-1) {
			key = str.substring(0,keypos);
			str = str.substr(keypos+1,str.length-keypos);
			valpos=str.indexOf(valdelemiter);
			if (valpos==-1) valpos=str.length;
			val = str.substr(0,valpos);
			str = str.substr(valpos+1,str.length-valpos);
			arr[key]=val;
		}
	}
	return arr;
}

/* joinAssoc(arr assoc, valdelemiter) ##################################################################################
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## gibt assoc (assoziatives array) als string zurück.JEDOCH OHNE SCHLÜSSEl fehlkonzeption						      ##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */


function joinAssoc(assoc) {
	if (joinAssoc.arguments.length>1) var valdelemiter = joinAssoc.arguments[1]; else valdelemiter = "#";
	var output="";
	for (var i in assoc) output+=assoc[i]+valdelemiter;
	return output.slice(0,-1);
}

function splitAssoc(str) {
	return cat(str);
}

/* setcat(str ar, str p) ###############################################################################################
##                                                                                                                    ##
## ar = string wie css parament z.B. (key1:value1;key2:value2;...)                                                    ##
## p  = schlüssel der in ar gesetzt wird                                                                              ##
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## diese Funktion setzt (und überschreibt evtl vorhandene) parameter und gibt das array als string zurück             ##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */

function setcat(ar,p) {
  if(extras!=cat(ar)) var cat = new Array();
  extras[p]=ar;
  return joinAssoc(extras);
}


/* incat(str ar, str p) ################################################################################################
##                                                                                                                    ##
## ar = string wie css parament z.B. (key1:value1;key2:value2;...)                                                    ##
## p  = schlüssel der in ar gesucht wird                                                                              ##
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## diese Funktion ist ähnlich zu cat gibt aber nur den wert des gesuchten schlüssels p zurück                         ##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */

function incat(ar,p) {
  var extras = cat(ar);
  if (typeof(extras)=="object" && extras[p] && extras[p]!="") return extras[p];
  else return false;
}


/* cat(str ar) #########################################################################################################
##                                                                                                                    ##
## ar = string wie css parament z.B. (key1:value1;key2:value2;...)                                                    ##
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## das feld cat in der cms datenbank steht für freie parameter bereit. um diese dann auszwerten wird der in dem feld  ##
## enthaltene string als assoziatives array zurückgegeben (ar[key1]=value1,...).                                      ##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */

function cat(ar) {
  ar = String(ar);
  if (ar!="" & ar.indexOf(":")>-1) {
    var par = new Array();
    if (ar.indexOf(";")>-1)
    var get=ar.split(";");
    else var get = new Array(ar);
    for (var i=0;i<get.length;i++) par[get[i].substr(0,get[i].indexOf(":"))] = get[i].substr(get[i].indexOf(":")+1);
    return par;
  } else {
    return ar;
  }
}

/* getKeys(arr ar) #####################################################################################################
##                                                                                                                    ##
## ar = Array                                                                                                         ##
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## die Funktion fehlt in Javascript. durchläuft assoziatives Array und gibt alle gefundenen Schlüssel als Array zurück##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */

// gibt alle schlüssel als array zurück
function getKeys(ar) {
   var key = new Array();
   for (var c in ar) { key.push(c); }
   return key;
}


/* inar(str str, ar ar) ################################################################################################
##                                                                                                                    ##
## str = string der in ar gesucht wird                                                                                ##
## ar = array in dem nach str gesucht wird                                                                            ##
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## sucht string in array; gibt position an, wenn gefunden oder -1, wenn nicht drin,                                   ##
## wenn str ein array, ruft die funktion sich selber so oft auf bis alle element in str mit ar verglichen wurden      ##
## und gibt array mit gefundenen elementen zurück                                                                     ##
##           BUG ändert bei globalen Arrays dien Inhalt auf lowercase !!                                              ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */

	
function inar(str,ar) {
	alert("Benutzung von Fehlerhafter Funktion inar()!\nBitte Funktion ersetzen");
	if (typeof(str)=="string") str = str.toLowerCase(); 
	else if (typeof(str)=="number") str = ""+str+"";
	else var found = new Array();
	start:
	for (var c in ar) {
		if (typeof(ar[c])=="string") ar[c] = ar[c].toLowerCase();
		if (typeof(str)=="string") {
			if(str==ar[c]) { var b=c; break start; }
		} else if (typeof(str)=="object") {
			if(inar(ar[c],str)!==-1) found.push(ar[c]);
		}
	}
	if (found && found.length>0) var b = found;
	if (b) return b; else return -1;
}

// gibt erste int position des gesuchten string wertes b in array c, bei nicht vorkommen gibt arfl false zurück
function arfl(b, c) {
	var d;
	for (var i=0;i<c.length;i++) {
		if (c[i]==b) {d=true; break;}
	}
	if (d) return i; else return false;
}

// gibt erste int position des gesuchten string wertes b in array c, bei nicht vorkommen gibt arfnd -1 zurück
function arfnd(b, c) {
	var d;
	for (var i=0;i<c.length;i++) {
		if (c[i]==b) {d=true; break;}
	}
	if (d) return i; else return -1;
}


// löscht string wert b in array c und gibt array zurück
function ardl(b,c) {
	var d = new Array();
	for (var i=0;i<c.length;i++) {
		if (c[i]!=b) d[d.length]=c[i];
	}
	return d;
}

// vertauscht wert an pos int b mit wert an pos int c in array a
function arsh(a,b,c) {
	var d=a[b];
	a[b]=a[c];
	a[c]=d;
	return a;
}

// löscht alle vorkommen von string a aus string b, gibt string b zurück
function stdl(a,b) {
	while(b.indexOf(a)>-1) b = b.slice(0,b.indexOf(a))+b.slice(b.indexOf(a)+a.length);
	return b;
}

//zählt anzahl der element (gut für assoziative arrays
function ar_count(ar) {
	var c=0; for (var i in ar) c++; return c;
}

// führt ein oder mehrere Arrays zusammen, schlüssel werden neu erzeugt. Nicht für assoziative Arrays geeignet
function array_merge(ar) {
	var mar = new Array(), addar;
	for (var i=0;i<ar.length;i++) 
		mar.push(ar[i]);
	if (array_merge.arguments.length>1) {
		var i=1;
		while(addar = array_merge.arguments[i++]) {
			for (var k=0;k<addar.length;k++) {
				mar.push(addar[k]);
			}
		}
	}
	return mar;
}

function show(text) {
	window.status=text;
	return true;
}

/* nl2br(str txt) ######################################################################################################
##                                                                                                                    ##
## txt = string                                                                                                       ##
##                                                                                                                    ##
## Beschreibung:                                                                                                      ##
## wandelt \n (newlinecarier) in html <br> um                                                                         ##
##                                                                                                                    ##
######################################################################### twqm@thomsson.de 2004 ## tel.: 0172893 7979 */

function nl2br(txt) {
  txt = String(txt);
  var html="";
  for (var i=0;i<txt.length;i++) { if (txt.charCodeAt(i)==10) html+="<BR>"; else html+=txt.charAt(i); }
  return html;
}

function br2nl(html) {
	var pos=html.indexOf("<BR>");
	while (pos>-1) {
		html = html.substring(0, pos-1) + "\n" + html.substring(pos+4, html.length);
		pos = html.indexOf("<BR>");
	}
	return html;
}

// ####  jscript dom tester   #######################################################################################
//###################################################################################################################
var curobj;	

function throwobj(what) {
   var hier=new Array(); var a=0;
   if (!what) what = "window";

   if (typeof(eval(what))=="object") {
      curobj=what;
      for (var test in eval(what)) {
         hier[a++]=test;
      }
      hier.sort();

      var show=typeof(eval(what))+": "+what+"<hr>";
      for (var i=0;i<hier.length;i++) {
         show+="<a href=\"javascript:throwobj('"+what+"."+hier[i]+"');\">"+hier[i]+"</a><br>";
      }
      document.getElementById("mainarea").innerHTML=show;
   } else {
      alert(typeof(eval(what))+"=|"+eval(what)+"|");
   }

}

function writeCookie(data) {
	document.cookie=data;
}

// prüft ob variable in cockie und liest sie dann
function cookieVar(cv) {
	cv +="=";
	var b;
	if (document.cookie) {
		if (document.cookie.indexOf(cv)>-1) {
			for (var i=document.cookie.indexOf(cv);i<document.cookie.length;i++) {
				if(document.cookie.charAt(i)==";") break; 
			}
			b = document.cookie.slice(document.cookie.indexOf(cv)+cv.length,i);
			if (isFinite(b)) b=parseInt(b);
			return b;
		} else { 
			return false;
		}
	} else {
		return false;
	}
}

//    showhideEL   ################################################################
// ############### ################################################################

function showhide(el) {
	if (document.getElementById(el).style.display=='none')
		document.getElementById(el).style.display='';
	else 
		document.getElementById(el).style.display='none';
}


function browserCheck() {
	this.ie = document.all;
	this.ie4 = this.ie && !document.getElementById;
	this.ie5 = this.ie && document.getElementById;
	this.ns = document.layers;
	this.mz = !this.ie && document.getElementById;
	this.op = navigator.userAgent.indexOf("Opera");
}
var br = new browserCheck();

function alertObj(obj) {
	var str="";
	for (var i in obj) 
		if (i.indexOf("on")!=0 && i.indexOf("HTML")==-1  && i.indexOf("Text")==-1 && i.toLowerCase().indexOf("function")==-1)
			str+=i+" "+obj[i]+"\t";
	alert(str);
	return null;
}

function askObj(p) {
	/*try { if (!lastName) throw true; }
	catch (n) { if (n) lastName="self"; }
	lastName = prompt("Objektabfrage 0.2",lastName);
	var str="";
	var obj = eval(lastName);
	for (var i in obj) {
		if (!p && i.substr(0,2)!="on") str+=i+"\t";
		else str+=i+"="+obj[i]+"\t";
	} 
	alert(str);*/
}


//füllt einen string auf bestimmte länge. sehr rudimentär, nur von links
function strfill(str,ch,l) {
	if (!ch) var ch="0"; 
	if (!l) var l=2;
	str = String(str);
	while (str.length<l) str=""+ch+""+str;
	return str;
}

function str_replace(str,arr) {
	for (var i in arr) str = str.replace(i,arr[i]);
	return str;
}

// durchläuft eltern eines elemenst 
function traverse_nodes(p,i) {
	if (!p) return false;
	var found=false;
	if (typeof(i)=="string") i=document.getElementById(i);
	while (p.tagName && p.tagName!="BODY") {	
		if (p==i) { found=p; break; }
		p=p.parentNode;
	}
	return found;
}

// Fehlerausgabe
/*function ejectError(obj) {
	alert("fehler wird aufbereitet");
	var str="Fehler in Funktion: "+ejectError.caller.substr(9,+ejectError.caller.indexOf("{"));
	str+"\n\nBenutze Variablen:\n";
	str+=obj.arguments.join("\n")+"\nCaller: "+obj.caller.substr(9,+ejectError.caller.indexOf("{"));
	alert(str);
}*/

// durchläuft eltern eines elemenst (cn kann auch array sein
function traverse_nodes_by_className(p,cn) {
	var found=false;
	while (p.tagName && p.tagName!="BODY") {	
		if (p.className && ((typeof(cn)=="object" && cn[p.className]) || (typeof(cn)=="string" && p.className==cn))) {found=p; break;}
		p=p.parentNode;
	}
	return found;
}

// wie traverse_nodes_by_className, gibt aber bei nicht finden liste der gefunden classen zurück
function find_parent(p,cn) {
	var found=false; var foundClasses = new Array();
	while (p.tagName!="BODY") {	
		if (/*typeof(cn)=="string" &&*/ p.className && p.className==cn) {found=p; break;}
		//else if (typeof(cn)=="object" && p==cn) {found=p; break;}
		if (p.className) foundClasses[p.className] = p;
		p=p.parentNode;
	}
	return (found) ? found : foundClasses;
}


function checkPos(el) {
	if (br.ie) {
		var x = self.event.x;
		var y = self.event.y;
	} else if (br.mz || br.ns) { // beim netscape muss ich mir ne ganz andere methode einfallen lassen.
		var x = el.pageX;
		var y = el.pageY;
	}
	//alert(el.tagName+"\nMouse:\nx "+x+" y "+y+"\nObject:\nleft "+el.offsetLeft + " width "+el.offsetWidth+" top "+el.offsetTop+" height "+el.offsetHeight);
	if (x >= el.offsetLeft && x <= el.offsetLeft+el.offsetWidth && y >= el.offsetTop && y <= el.offsetTop+el.offsetHeight) 
		return true; 
	else return false;
}

function absoluteTop(el) {
	var offset = el.offsetTop-el.scrollTop;
	while (el.offsetParent!=null) {
		el=el.offsetParent;
		if (br.ie) offset+=el.offsetTop-el.scrollTop;
		else offset+=el.offsetTop;
	}
	offset+=el.scrollTop;
	return offset;
}
function absoluteLeft(el) {
	var offset = el.offsetLeft-el.scrollTop;
	while (el.offsetParent!=null) {
		el=el.offsetParent;
		if (br.ie) offset+=el.offsetLeft-el.scrollLeft;
		else offset+=el.offsetLeft;
	}
	offset+=el.scrollLeft;
	return offset;
}
function relativeTop(el,rel) {
	var offset = el.offsetTop-el.scrollTop;
	while (el.parentNode!=null && el.parentNode!=rel) {
		el=el.parentNode;
		if (br.ie) offset+=el.offsetTop-el.scrollTop;
		else offset+=el.offsetTop;
	}
	offset+=el.scrollTop;
	return offset;
}
function relativeLeft(el,rel) {
	var offset = el.offsetLeft-el.scrollTop;
	while (el.parentNode!=null && el.parentNode!=rel) {
		el=el.parentNode;
		if (br.ie) offset+=el.offsetLeft-el.scrollLeft;
		else offset+=el.offsetLeft;
	}
	offset+=el.scrollLeft;
	return offset;
}

function posRelative(sourceEl,targetEl,elHeight) {
	var c = 40; // keine ahnung wieso 47, noch nicht!!!
	elHeight=2;
	if (!br.ie) c=40;
	if (!sourceEl) {
		alert("Fehler in der PosRelative Funktion");
		return true;
	}
	var elTop = absoluteTop(sourceEl);
	var elLeft = absoluteLeft(sourceEl);
	var cTop = elTop-elHeight-sourceEl.offsetHeight+c;
	if (posRelative.arguments.length>3) var cLeft = elLeft+posRelative.arguments[3];
	else var cLeft = elLeft+2;
	targetEl.style.display="block";
	targetEl.style.visibility="hidden";
	if (cTop<0 && (document.body.offsetHeight-elTop-sourceEl.offsetHeight+c)>targetEl.offsetHeight)
		cTop=elTop+sourceEl.offsetHeight;
	else if ((cTop*1+targetEl.offsetHeight*1)>document.body.offsetHeight) 
		cTop += document.body.offsetHeight-(cTop*1+targetEl.offsetHeight*1);
	with (targetEl) {
		style.top = cTop+"px";
		style.left = cLeft+"px";
		style.visibility = "";
		//focus();
	}
}


function getNodeNumber(el) {
	if (el) for (var i in el.parentNode.childNodes) if (el.parentNode.childNodes[i]==el) return Number(i);
}


// under contruction: level wird noch missachtet !!!!
function iterateChilds(el,action,level) {
	if (level==1) for (var i=0;i<el.childNodes.length;i++) {
		if (el.childNodes[i].nodeType==1) eval("el.childNodes[i]."+action); 
	}
	//return true;
}

function ucwords(str) {
	var split = str.split(" ");
	for (var i=0;i<split.length;i++) {
		split[i]=split[i].substr(0,1).toUpperCase()+split[i].substr(1).toLowerCase();
	}
	return split.join(" ");
}

// Formatiert Zahlen, selbe Syntax wie in php4
function number_format(nr /*,decimal,dec_str,th_str*/ ) {
	if (isNaN(nr)) return nr;
	var dec = 2, dec_str=",",th_str="";
	if (number_format.arguments.length>1) dec = number_format.arguments[1];
	if (number_format.arguments.length>2) dec_str = number_format.arguments[2];
	if (number_format.arguments.length>3) th_str = number_format.arguments[3];
	nr = nr.toFixed(dec);
	nr = nr.replace(/\./,dec_str);
	if (th_str!="" && (nr.substr(0,nr.indexOf(dec_str)).length>3 || (dec==0 && nr.length>3))) {
		if (dec==0) nr = nr.substr(0,nr.length-3)+th_str+nr.substr(nr.length-3);
		else nr = nr.substr(0,nr.indexOf(dec_str)-3)+th_str+nr.substr(nr.indexOf(dec_str)-3);
		while (nr.substr(0,nr.indexOf(th_str)).length>3)
			nr = nr.substr(0,nr.indexOf(th_str)-3)+th_str+nr.substr(nr.indexOf(th_str));
	}
	return nr;
}

// liefert ein array values der gewählten einträge in einer SELECT -gruppe, wenn irgendein 2. parameter, dann wird der text zurückg
function selectedOptions(el) {
	var sel = new Array();
	for (var i=0;i<el.length;i++) {
		if (el.options[i].selected==true) {
			if (selectedOptions.arguments.length>1) sel[i]=el.options[i].text;
			else sel[i]=el.options[i].value;
		}
	}
	return sel;
}
function getSelVal(n) {
	if (typeof(n)=="string") n = getEl(n);
	return n.options[n.options.selectedIndex].value;
}

function getEl(name) { return self.document.getElementById(name); }
function remEl(name) { 
	if (self.document.getElementById(name))
		return self.document.getElementById(name).parentNode.removeChild(self.document.getElementById(name)); 
	else return false;
}

function encU(str) { return encodeURIComponent(str); }
function decU(str) { return decodeURIComponent(str); }

// fügt werte mit schlüsseln in array data ein, bei doppelten schlüsseln wird ein integer davor gesetzt
function addall(data,name,value) {
	var a=0;
	if (!data[name]) data[name]=value;
	else if (!data[a+""+name]) {
		while (a++ && !data[a+""+name]) void(0);
		data[a+""+name]=value; a=0;
	}
	return data;
}


// Sammelt alle values von Form-Feldern
function catch_formfields() {
	var inputs = document.getElementsByTagName("input");
	var textareas = document.getElementsByTagName("textarea");
	var selections = document.getElementsByTagName("select");
	var collected = new Array();
	for (var i=0;i<inputs.length;i++) {
		if (inputs[i].type && (inputs[i].type=="checkbox" || inputs[i].type=="radio")) {
			if (inputs[i].checked==true) collected[inputs[i].name]="checked";
			else if(!collected[inputs[i].name]) collected[inputs[i].name]="";
		} else 
			collected[inputs[i].name] = inputs[i].value;
	}
	for (var i=0;i<textareas.length;i++) {
		collected[textareas[i].name] = textareas[i].value;
	}
	for (var i=0;i<selections.length;i++) {
		if (selections[i].name && selections[i].options.selectedIndex>-1)
			collected[selections[i].name] = selections[i].options[selections[i].options.selectedIndex].value;
	}
	return collected;
}


// eventmapping	//

function brChMs(el) { 			// Maus Event-Mapping für moz und ie
	if (br.ie) return self.event.srcElement; else if (br.mz || br.ns) return el.target;
}
function brChKb(el) { 			// Tastatur Event-Mapping für moz und ie
	if (br.ie) return self.event.keyCode; else if (br.mz || br.ns) return el.which;
}

