//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Funktionen fuer das Menü
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var undefined;
var istbild=0;
var warbild=0;
var fristbild=0;
var frwarbild=0;

var browser = navigator.appVersion;
var browserausgabe = browser.substring(27,30);
var browser_safari = false;
var safaribrowser = 0;
var safari = browser.indexOf("Safari");


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Allgemeine Funktionen
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// onMouseover Funktion Hauptmenü deutsch
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var menu=new Array;
var menu2=new Array;

for (var i=1;i<5;i++){
  menu[i] = new Image();
  menu2[i] = new Image();
  menu[i].src="/kiosk/grafik/h_menue_"+i+".gif";
  menu2[i].src="/kiosk/grafik/h_menue_"+i+"_.gif";
}

function over(x){
  document.images["hmen"+x].src=menu2[x].src;
}

function out(x){
  warbild=istbild;
  if (warbild != x){
    document.images["hmen"+x].src=menu[x].src;
  }
}

function fix(x){
  if (safari == "79") {
    browser_safari = true;
    var safaribrowser = 1;
    warbild=istbild;
  }
  else{
    browser_safari = false;
    if (moveISRunning){
    return;
    }
    warbild=istbild;
  }

  if (warbild != 0){
    document.images["hmen"+warbild].src=menu[warbild].src;
  }
  if (x != 0){
    document.images["hmen"+x].src=menu2[x].src;
  }
  istbild=x;
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// onMouseover Funktion Hauptmenü französisch
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var frmenu=new Array;
var frmenu2=new Array;

for (var i=1;i<5;i++){
  frmenu[i] = new Image();
  frmenu2[i] = new Image();
  frmenu[i].src="/kiosk/grafik/fr/h_menue_"+i+".gif";
  frmenu2[i].src="/kiosk/grafik/fr/h_menue_"+i+"_.gif";
}

function over_fr(x){
  document.images["frhmen"+x].src=frmenu2[x].src;
}

function out_fr(x){
  frwarbild=fristbild;
  if (frwarbild != x){
    document.images["frhmen"+x].src=frmenu[x].src;
  }
}

function fix_fr(x){
  if (safari == "79") {
    browser_safari = true;
    var safaribrowser = 1;
    frwarbild=fristbild;
  }
  else{
    browser_safari = false;
    if (moveISRunning){
    return;
    }
    frwarbild=fristbild;
  }

  if (frwarbild != 0){
    document.images["frhmen"+frwarbild].src=frmenu[frwarbild].src;
  }
  if (x != 0){
    document.images["frhmen"+x].src=frmenu2[x].src;
  }
  fristbild=x;
}


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Funktion zum dynamischen Setzen eines layer-Ausdrucks
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++

function ausdruckSetzen()
{

  var idname = ausdruckSetzen.arguments[0];

  if (document.getElementById(idname))
  {
    return document.getElementById(idname);
  }
  else
  {
    //alert('Es gibt keinen Layer mit der id \'' + idname + '\'');
    return undefined;
  }

}


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Untermenü ein-/ausblenden
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++

var waruntermen = 0;
var istuntermen = 0;
var moveISRunning = false;

  if (safari == "79") {
    browser_safari = true;
    var safaribrowser = 1;
    
      function untermenue(name,x) {
    
      waruntermen = istuntermen;
    
      if (waruntermen != 0)
      {
        var id = String(name + waruntermen);
        var ausdruck = ausdruckSetzen(id);
    
        if (ausdruck != undefined)
        {
          ausdruck.style.display = 'none';
        }
      }
    
      if (x != 0)
      {
        if (x != waruntermen)
        {
          var id = String(name + x);
          var ausdruck = ausdruckSetzen(id);
    
          if (ausdruck != undefined)
          {
            ausdruck.style.display = 'block';
          }
        }
      }
      else
      {
        for (var i=1; i<6; i++)
        {
          var id = String(name + i);
          var ausdruck = ausdruckSetzen(id);
    
          if (ausdruck != undefined)
          {
            ausdruck.style.display = 'none';
          }
        }
      }
    
      if (waruntermen == x)
      {
        istuntermen = 0;
      }
      else
      {
        istuntermen = x;
      }
    
    }
    
  }
  else{
    
    function untermenue(name,x,event) {
      
      if (moveISRunning){
        return;
      }
      waruntermen = istuntermen;
    
      if (waruntermen != 0)
      {
        var id = String(name + waruntermen);
        var ausdruck = ausdruckSetzen(id);
    
        if (ausdruck != undefined)
        {
         
          var origHeight = getElementHeight(ausdruck);
          var timeoutHide = undefined;   
          function moveUntermenuHide(elem, origHeight, e){
            moveISRunning = true;
            if (timeoutHide){
              window.clearTimeout(timeoutHide);
            }
            if (parseFloat(elem.style.height) <= 0) {
              elem.style.display = 'none';
              elem.style.height = 'auto';
              moveISRunning = false;
              return;
            }
            var diff = 3;
            if (parseFloat(elem.style.height) < diff){
              diff = parseFloat(elem.style.height);
            }
            elem.style.display = 'block';
            elem.style.height = parseFloat(parseFloat(elem.style.height) - diff) + 'px';
            var f = function (e) {moveUntermenuHide(elem, origHeight, e)};
            return timeoutHide = window.setTimeout(f,'1');
          }
          moveUntermenuHide(ausdruck, origHeight, event);
          //ausdruck.style.display = 'none';
        }
      }
    
      if (x != 0)
      {
        if (x != waruntermen)
        {
          var id = String(name + x);
          var ausdruck = ausdruckSetzen(id);
    
          if (ausdruck != undefined)
          {
            var origHeight = getElementHeight(ausdruck);
            ausdruck.style.height = '0px';
            ausdruck.style.overflow = 'hidden';
         
            var timeoutShow = undefined;   
            function moveUntermenuVisible(elem, origHeight, e){
              moveISRunning = true;
              if (timeoutShow){
                window.clearTimeout(timeoutShow);
              }
              if (parseFloat(elem.style.height) >= origHeight) {
                moveISRunning = false;
                return;
              }
              var diff = 3;
              if (parseFloat(origHeight - parseFloat(elem.style.height)) < diff){
                diff = parseFloat(origHeight - parseFloat(elem.style.height));
              }
              elem.style.display = 'block';
              elem.style.height = parseFloat(parseFloat(elem.style.height) + diff) + 'px';
              var f = function (e) {moveUntermenuVisible(elem, origHeight, e)};
              return timeoutShow = window.setTimeout(f,'1');
            }
            moveUntermenuVisible(ausdruck, origHeight, event);
          }
        }
      }
    
      if (waruntermen == x)
      {
        istuntermen = 0;
      }
      else
      {
        istuntermen = x;
      }
    
    }
    
    function getElementHeight(elem){
      if (! elem){
        return;
      }
      var clone = elem.cloneNode(true);
      clone.style.visibility = 'visible';
      clone.style.display = 'block';
      document.getElementsByTagName("body")[0].appendChild(clone);
      var h =  parseFloat(clone.offsetHeight);
      document.getElementsByTagName("body")[0].removeChild(clone);
      return h;
    }

}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Funktionen des Projekts (ausser Menue)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var undefined;


function banner_schliessen (){
  var element = document.getElementById('banner');
  element.style.display = 'none';
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// PopUp-Funktion
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var popupSettings = {};

popupSettings['default'] = '';

popupSettings['Ansprechpartner'] = 'width=566,height=400';
popupSettings['Artikel versenden'] = 'width=566,height=600';
popupSettings['Fotogalerie'] = 'width=569,height=600';

function openPopup(url,windowName,settingsID) {

  var settings;
  var newWindow;

  if (popupSettings[settingsID]) {
    settings = popupSettings[settingsID];
  } else {
    settings = popupSettings['default'];
  }

  newWindow = window.open(url,windowName,settings);
  newWindow.focus();

}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Funktion zum Bildertausch
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var zaehler = 1;

function tausche_bilder() {

	var richtung = tausche_bilder.arguments[0];
	var bildid = tausche_bilder.arguments[1];
	var pfadname = tausche_bilder.arguments[2];
	var maximum = tausche_bilder.arguments[3];
	var pfad = new String();

	if (richtung == 'vor') {

		zaehler += 1;

	} else {

		zaehler -= 1;

	}

	if (zaehler == 0) {

		zaehler = maximum;

	}

	if (zaehler > maximum) {

		zaehler = 1;

	}

	pfad = String(pfadname + zaehler + '.jpg');

	document.images[bildid].src = pfad;

}






// ============================================================
// Globale Deklarationen
// ============================================================

// den undefinierten Wert deklarieren
var undefined;


// ============================================================
// Klasse Form
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Form(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
function Form(id) {
  // Attribute
  this._id = undefined;
  this._childElementList = [];
  // Initialisierungen
  this.id(id);
  this._setChildElementList();
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// id(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Form.prototype.id = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Form.prototype.id meldet: Argument ist nicht vom Typ string!');
    }
    this._id = str;
  }
  return this._id;
}

// -----------
// addChildElementList(Field)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Form.prototype.addChildElementList = function(obj) {
  if (arguments.length) {
    if (! obj instanceof Field) {
      throw new Error("Form.prototype.addChildElementList meldet: Argument ist nicht Instanz von Field!");
    }
    this._childElementList.push(obj);
  }
  return this._childElementList;
}

// -----------
// getChildElementList()
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Form.prototype.getChildElementList = function() {
  return this._childElementList;
}

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ---------------------------------------
// _setChildElementList()
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.prototype._setChildElementList = function() {

  var newElement;
  var currentFormDomPath = document.getElementById(this.id());
  var inputElements = currentFormDomPath.getElementsByTagName('input');
  var selectElements = currentFormDomPath.getElementsByTagName('select');
  var textareaElements = currentFormDomPath.getElementsByTagName('textarea');

  for (var i=0; i<inputElements.length; i++) {
    if (inputElements[i].type != 'hidden' && inputElements[i].type != 'submit' && inputElements[i].type != 'reset' && inputElements[i].type != 'image' && inputElements[i].type != 'button') {
      if (inputElements[i].id) {
        newElement = Field.createInstance(inputElements[i].id);
        this.addChildElementList(newElement);
      }
    }
  }

  for (var i=0; i<selectElements.length; i++) {
    if (selectElements[i].id) {
      newElement = Field.createInstance(selectElements[i].id);
      this.addChildElementList(newElement);
    }
  }

  for (var i=0; i<textareaElements.length; i++) {
    if (textareaElements[i].id) {
      newElement = Field.createInstance(textareaElements[i].id);
      this.addChildElementList(newElement);
    }
  }

}

// ---------------------------------------
// _setCurrentValues()
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.prototype._setCurrentValues = function() {

  var childElementList = this.getChildElementList();

  for (var i=0; i<childElementList.length; i++) {

    var currentElementDomPath = document.getElementById(childElementList[i].id());

    if (childElementList[i].type() == 'select') {
      childElementList[i].currentValue(currentElementDomPath.options[currentElementDomPath.options.selectedIndex].value);
    } else {
      childElementList[i].currentValue(currentElementDomPath.value);
    }

  }

  return childElementList;

}


// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------


// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

Form._registeredElementsList = {};
Form._errorLogList = {};


// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// ---------------------------------------
// initForms()
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.initForms = function() {

  var currentFormsDomPath = [];

  currentFormsDomPath = document.getElementsByTagName('form');

  for (var i=0; i<currentFormsDomPath.length; i++) {
    Form.createInstance(currentFormsDomPath[i].id);
  }

  return currentFormsDomPath;

}

// ---------------------------------------
// createInstance(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.createInstance = function(id) {

  if (!id) {
    throw new Error('Form.createInstance meldet: Es wurde keine ID übergeben');
  }

  if (Form._registeredElementsList[id]) {
    throw new Error('Form.createInstance meldet: Die ID "' + id + '" ist bereits vergeben.');
  }

  Form._registeredElementsList[id] = new Form(id);

  return Form._registeredElementsList[id];

}

// ---------------------------------------
// getFormInstanceById(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.getFormInstanceById = function(id) {
  return Form._registeredElementsList[id];
}

// ---------------------------------------
// standardCheck(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.standardCheck = function(id) {

  var currentFormInstance = Form.getFormInstanceById(id);
  var errorLog = {};

  if (!currentFormInstance) {
    throw new Error('Form.standardCheck meldet: Die ID "' + id + '" ist nicht vergeben.');
  }

  errorLog = Form.getErrorLog(id);

  if (errorLog['id']) {
    Form.setErrorMessage(errorLog);
    return false;
  }

  return true;

}

// ---------------------------------------
// getErrorLog(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.getErrorLog = function(id) {

  var currentForm = Form.getFormInstanceById(id);
  var childElementList = currentForm.getChildElementList();
  var currentFormDomPath = document.getElementById(currentForm.id());
  var isError;
  var errorLog = {};

  currentForm._setCurrentValues();

  for (var i=0; i<childElementList.length; i++) {

    if (childElementList[i].required() == true) {

      isError = Form._checkRequired(currentFormDomPath,childElementList[i]);

      if (isError == true) {
        errorLog['id'] = childElementList[i].id();
        errorLog['type'] = childElementList[i].type();
        errorLog['errorType'] = 'required';
        errorLog['expected'] = '';
        break;
      }

    }

    if (childElementList[i].contentType()) {

      isError = Form._checkContentType(childElementList[i]);

      if (isError == true) {
        errorLog['id'] = childElementList[i].id();
        errorLog['type'] = childElementList[i].type();
        errorLog['errorType'] = 'contentType';
        errorLog['expected'] = childElementList[i].contentType();
        break;
      }

    }

    if (childElementList[i].contentSyntax()) {

      isError = Form._checkContentSyntax(childElementList[i]);

      if (isError == true) {
        errorLog['id'] = childElementList[i].id();
        errorLog['type'] = childElementList[i].type();
        errorLog['errorType'] = 'contentSyntax';
        errorLog['expected'] = childElementList[i].contentSyntax();
        break;
      }

    }

  }

  return errorLog;

}

// ---------------------------------------
// setErrorMessage(array)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form.setErrorMessage = function(errorLog) {

  var errorString = '';
  var currentFormFieldDomPath = document.getElementById(errorLog['id']);
  var currentFormFieldName = currentFormFieldDomPath.name;

  errorString += 'Fehler im Formular\n';

  if (errorLog['errorType'] == 'required') {
    errorString += 'Das Feld "' + currentFormFieldName + '" ist ein Pflichtfeld.';
  }

  if (errorLog['errorType'] == 'contentType') {
    if (errorLog['expected'] == 'number') {
      errorString += 'Bitte geben Sie im Feld "' + currentFormFieldName + '" eine Zahl ein.';
    }
  }

  if (errorLog['errorType'] == 'contentSyntax') {
    if (errorLog['expected'] == 'e-mail') {
      errorString += 'Bitte geben Sie im Feld "' + currentFormFieldName + '" eine gültige E-Mail-Adresse ein.';
    }
    if (errorLog['expected'] == 'date') {
      errorString += 'Bitte geben Sie im Feld "' + currentFormFieldName + '" ein Datum im Format tt.mm.jjjj ein.';
    }
    if (errorLog['expected'] == 'plz') {
      errorString += 'Bitte geben Sie im Feld "' + currentFormFieldName + '" eine Postleitzahl ein.';
    }
    if (errorLog['expected'] == 'telefon') {
      errorString += 'Bitte geben Sie im Feld "' + currentFormFieldName + '" eine Telefonnummer ein.';
    }
  }

  alert(errorString);

  currentFormFieldDomPath.focus();

  if (errorLog['type'] == 'text' || errorLog['type'] == 'textarea') {
    currentFormFieldDomPath.select();
  }

  return errorString;

}

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ---------------------------------------
// _checkRequired(object,object)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form._checkRequired = function(currentFormDomPath,currentFieldInstance) {

  var isError;

  if (currentFieldInstance.type() == 'radio' || currentFieldInstance.type() == 'checkbox') {
    isError = Form._checkRadioCheckBoxes(currentFormDomPath,currentFieldInstance);
    return isError;
  }

  isError = Form._checkFormFields(currentFieldInstance);
  return isError;

}

// ---------------------------------------
// _checkRadioCheckBoxes(object,object)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form._checkRadioCheckBoxes = function(currentFormDomPath,currentFieldInstance) {

  var elementList = currentFormDomPath[currentFieldInstance.name()];
  var isError = true;

  if (elementList.length) {
    for (var i=0; i<elementList.length; i++) {
      if (elementList[i].checked) {
        isError = false;
        break;
      }
    }
  } else {
    if (elementList.checked) {
      isError = false;
    }
  }

  return isError;

}

// ---------------------------------------
// _checkFormFields(object)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form._checkFormFields = function(currentFieldInstance) {

  var isError = false;
  var defaultValue = currentFieldInstance.defaultValue();
  var currentValue = currentFieldInstance.currentValue();
  var regularExpressionValue = /^\s*$/;
  var isEmptyString = regularExpressionValue.test(currentValue);

  /*if (isEmptyString == true || currentValue == defaultValue) {
    isError = true;
  }*/

  if (isEmptyString == true) {
    isError = true;
  }

  return isError;

}

// ---------------------------------------
// _checkContentType(object)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form._checkContentType = function(currentFieldInstance) {

  var isError = false;
  var currentContentType = currentFieldInstance.contentType();
  var currentValue = currentFieldInstance.currentValue();
  var regularExpressionNumber = /^\d+([.,]\d+)?$/;
  var isNumber = regularExpressionNumber.test(currentValue);

  if (currentValue) {
    if (currentContentType == 'number' && isNumber != true) {
      isError = true;
    }
  }

  return isError;

}

// ---------------------------------------
// _checkContentSyntax(object)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Form._checkContentSyntax = function(currentFieldInstance) {

  var isError = false;
  var currentContentSyntax = currentFieldInstance.contentSyntax();
  var currentValue = currentFieldInstance.currentValue();
  var regularExpressionEmail = /^\s*[a-zA-Z0-9_][-.a-zA-Z0-9_]*\@[\-a-zA-Z0-9]+(?:\.[\-a-zA-z0-9]+)*\.([a-z]{2,4})\s*$/;
  var regularExpressionDate = /^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$/;
  var regularExpressionPlz = /^[0-9]{5}$/;
  var regularExpressionTelefon = /^[0-9\s-\/\+\(\)]+$/;
  var isEmail = regularExpressionEmail.test(currentValue);
  var isDate = regularExpressionDate.test(currentValue);
  var isPlz = regularExpressionPlz.test(currentValue);
  var isTelefon = regularExpressionTelefon.test(currentValue);

  if (currentValue) {

    if (currentContentSyntax == 'e-mail' && isEmail != true) {
      isError = true;
    }

    if (currentContentSyntax == 'date' && isDate != true) {
      isError = true;
    }

    if (currentContentSyntax == 'plz' && isPlz != true) {
      isError = true;
    }

    if (currentContentSyntax == 'telefon' && isTelefon != true) {
      isError = true;
    }

  }

  return isError;

}

// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Form.prototype.toString = function() {
  // zunaechst an Methode der Basisklasse weiterleiten
  return Object.prototype.toString.apply(this);
}




// ============================================================
// Klasse Field
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

// ---------------------------------------
// Field(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
function Field(id) {
  // Attribute
  this._id = undefined;
  this._name = undefined;
  this._type = undefined;
  this._className = undefined;
  this._required = false;
  this._contentType = undefined;
  this._contentSyntax = undefined;
  this._defaultValue = undefined;
  this._currentValue = undefined;
  // Initialisierungen
  this.id(id);
  this._setAttributes();
}

// ------------------------------------------------------------
// Zugriffsfunktionen
// ------------------------------------------------------------

// -----------
// id(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.id = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.id meldet: Argument ist nicht vom Typ string!');
    }
    this._id = str;
  }
  return this._id;
}

// -----------
// name(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.name = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.name meldet: Argument ist nicht vom Typ string!');
    }
    this._name = str;
  }
  return this._name;
}

// -----------
// type(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.type = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.type meldet: Argument ist nicht vom Typ string!');
    }
    this._type = str;
  }
  return this._type;
}

// -----------
// className(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.className = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.className meldet: Argument ist nicht vom Typ string!');
    }
    this._className = str;
  }
  return this._className;
}

// -----------
// required(boolean)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.required = function(b) {
  if (arguments.length) {
    if (typeof b != 'boolean') {
      throw new Error('Field.prototype.required meldet: Argument ist nicht vom Typ boolean!');
    }
    this._required = b;
  }
  return this._required;
}

// -----------
// contentType(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.contentType = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.contentType meldet: Argument ist nicht vom Typ string!');
    }
    this._contentType = str;
  }
  return this._contentType;
}

// -----------
// contentSyntax(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.contentSyntax = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.contentSyntax meldet: Argument ist nicht vom Typ string!');
    }
    this._contentSyntax = str;
  }
  return this._contentSyntax;
}

// -----------
// defaultValue(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.defaultValue = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.defaultValue meldet: Argument ist nicht vom Typ string!');
    }
    this._defaultValue = str;
  }
  return this._defaultValue;
}

// -----------
// currentValue(string)
// -----------
//
// Beschreibung:
// -------------
//   ...
//
Field.prototype.currentValue = function(str) {
  if (arguments.length) {
    if (typeof str != 'string') {
      throw new Error('Field.prototype.currentValue meldet: Argument ist nicht vom Typ string!');
    }
    this._currentValue = str;
  }
  return this._currentValue;
}

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// ---------------------------------------
// xxx(VariablenTypXxx1, VariablenTypXxx2)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ---------------------------------------
// _setAttributes()
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Field.prototype._setAttributes = function() {

  var element = document.getElementById(this.id());

  // Name setzen

  if (element.name) {
    this.name(element.name);
  }

  // Typ setzen

  if (element.tagName.toLowerCase() == 'input') {
    this.type(element.type.toLowerCase());
  } else {
    this.type(element.tagName.toLowerCase());
  }

  // Klassenname auslesen

  var elementClassName = element.className;

  this.className(elementClassName);

  // Required setzen

  var regularExpressionRequired = /(^|\s)required($|\s)/;
  var typeRequired = regularExpressionRequired.test(elementClassName);

  if (typeRequired == true) {
    this.required(true);
  }

  // Content-Typ setzen

  var regularExpressionNumber = /(^|\s)number($|\s)/;
  var typeNumber = regularExpressionNumber.test(elementClassName);

  if (typeNumber == true) {
    this.contentType('number');
  }

  // Content-Syntax setzen

  var regularExpressionEmail = /(^|\s)e\-mail($|\s)/;
  var regularExpressionDate = /(^|\s)date($|\s)/;
  var regularExpressionPlz = /(^|\s)plz($|\s)/;
  var regularExpressionTelefon = /(^|\s)telefon($|\s)/;
  var typeEmail = regularExpressionEmail.test(elementClassName);
  var typeDate = regularExpressionDate.test(elementClassName);
  var typePlz = regularExpressionPlz.test(elementClassName);
  var typeTelefon = regularExpressionTelefon.test(elementClassName);

  if (typeEmail == true) {
    this.contentSyntax('e-mail');
  }

  if (typeDate == true) {
    this.contentSyntax('date');
  }

  if (typePlz == true) {
    this.contentSyntax('plz');
  }

  if (typeTelefon == true) {
    this.contentSyntax('telefon');
  }

  // Value setzen

  if (this.type() == 'select') {
    this.defaultValue(element.options[element.options.selectedIndex].value);
  } else {
    this.defaultValue(element.value);
  }

}


// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------


// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

Field._registeredElementsList = {};


// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// ---------------------------------------
// createInstance(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Field.createInstance = function(id) {

  if (!id) {
    throw new Error('Field.createInstanceField meldet: Es wurde keine ID übergeben');
  }

  if (Field._registeredElementsList[id]) {
    throw new Error('Field.createInstance meldet: Die ID "' + id + '" ist bereits vergeben.');
  }

  Field._registeredElementsList[id] = new Field(id);

  return Field._registeredElementsList[id];

}

// ---------------------------------------
// getFieldInstanceById(string)
// ---------------------------------------
//
// Beschreibung:
// -------------
//   ...
//
// Beispiel:
// ---------
//   ...
//
Field.getFieldInstanceById = function(id) {
  return Field._registeredElementsList[id];
}

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------


// ------------------------------------------------------------
// toString()
// ------------------------------------------------------------

Field.prototype.toString = function() {

  var meinString = '';

  meinString += String('ID: ' + this.id() + '\n');
  meinString += String('Type: ' + this.type() + '\n');
  meinString += String('ClassName: ' + this.className() + '\n');
  meinString += String('Required: ' + this.required() + '\n');
  meinString += String('ContentType: ' + this.contentType() + '\n');
  meinString += String('Value: ' + this.value() + '\n');

  return meinString;

}



//==================================================================================
//==================================================================================
//
// Ajax-MODUL Projektbezogene Methoden und Objekte
// OO-PROGRAMMIERUNG
// AUTOR: DF
// ERSTELLT: 31.01.2007
//
//==================================================================================
//==================================================================================

/*
XMLHttpRequest-Properties:
open
onreadystatechange
send
readyState
channel
responseXML
responseText
status
statusText
abort
getAllResponseHeaders
getResponseHeader
setRequestHeader
overrideMimeType
multipart
onload
onerror
onprogress
addEventListener
removeEventListener
dispatchEvent
getInterface
*/

var undefined;

function Ajax(id) {
  this.id;
  this.req = undefined;
  this.url = '';
  this.asynchron = true;
  this.parameter = {};
  this.parameterLength = [];
  this.mimeType = 'text/xml';
  this.requestHeader = 'application/x-www-form-urlencoded';
  this.callBackFunction = undefined;
  this.method = 'POST';

  this._setID(id);
}

Ajax.prototype._setID = function (str) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->_setID: Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Ajax->_setID: Argument str ist nicht vom Typ String!");
  }
  this.id = str;
}

Ajax.prototype.createRequest = function () {
  var req;
  if (window.ActiveXObject) {
    try {
      req = new ActiveXObject("Microsoft.XMLHTTP");
    } catch(e) {
      req = new ActiveXObject("Msxml2.XMLHTTP");
    }
  } else if (typeof XMLHttpRequest != undefined) {
    req = new XMLHttpRequest();
    /*
    if (this.mimeType){
      req.overrideMimeType(this.mimeType);
    }*/
  } else {
    focus();
    throw new Error("Ajax->createRequest: Der Browser unterstützt die Methode nicht!");
  }
  return req;
}

Ajax.prototype.addParameter = function (strKey, strValue) {
  if (arguments.length != 2) {
    focus();
    throw new Error("Ajax->addParameter: Falsche Anzahl von Argumenten!");
  }
  if (typeof strKey != "string") {
    focus();
    throw new Error("Ajax->addParameter: Argument strKey ist nicht vom Typ String!");
  }
  if (typeof strValue != "string") {
    focus();
    throw new Error("Ajax->addParameter: Argument strValue ist nicht vom Typ String!");
  }
  this.parameter[strKey] = strValue;
  this.parameterLength.push(strKey);
}

Ajax.prototype.setRequestHeader = function (str) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->setRequestHeader: Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Ajax->setRequestHeader: Argument str ist nicht vom Typ String!");
  }
  this.requestHeader = str;
}

Ajax.prototype.setAsynchron = function (b) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->setAsynchron: Falsche Anzahl von Argumenten!");
  }
  if (typeof b != "boolean") {
    focus();
    throw new Error("Ajax->setAsynchron: Argument str ist nicht vom Typ Boolean!");
  }
  this.asynchron = b;
}

Ajax.prototype.setMethod = function (str) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->setMethod: Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Ajax->setMethod: Argument str ist nicht vom Typ String!");
  }
  if (str!='GET' && str!='POST' && str!='HEAD'){
    focus();
    throw new Error("Ajax->setMethod: Argument str muss Wert GET oder POST oder HEAD haben!");
  }
  this.method = str;
}

Ajax.prototype.setURL = function (str) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->setURL: Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Ajax->setURL: Argument str ist nicht vom Typ String!");
  }
  this.url = str;
}

Ajax.prototype.setCallBackFunction = function (func) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->setCallBackFunction: Falsche Anzahl von Argumenten!");
  }
  if (typeof func != "function") {
    focus();
    throw new Error("Ajax->setCallBackFunction: Argument func ist nicht vom Typ Function!");
  }
  this.callBackFunction = func;
}

Ajax.prototype.open = function () {
  this.req = this.createRequest();
  if (this.method == 'POST'){
    if (! this.requestHeader){
      focus();
      throw new Error("Ajax->open: Mehtod=POST requires requestHeader !");
    }
  }
  try {
    this.req.open(this.method, this.url, this.asynchron);
    if (this.callBackFunction){
      this.req.onreadystatechange = this.callBackFunction;
    }
  } catch(e){
    Ajax._getNavigatorPrivilege(this);
  }
}

Ajax.prototype.sendAll = function () {
  var _req = '';
  for (var i in this.parameter){
    if (Ajax.getCharset() == 'utf-8' || Ajax.getCharset() == 'utf-16'){
      _req += '&' + i + '=' + encodeURIComponent(this.parameter[i]);
    } else {
      _req += '&' + i + '=' + escape(this.parameter[i]);
    }
  }
  _req = _req.replace(/^\&/,'');
  this.req.send(_req);
}

Ajax.prototype.sendNull = function () {
  this.req.send(null);
}

Ajax.prototype.send = function (strKey, strValue) {
  if (arguments.length != 2) {
    focus();
    throw new Error("Ajax->send: Falsche Anzahl von Argumenten!");
  }
  if (typeof strKey != "string") {
    focus();
    throw new Error("Ajax->send: Argument strKey ist nicht vom Typ String!");
  }
  if (typeof strValue != "string") {
    focus();
    throw new Error("Ajax->send: Argument strValue ist nicht vom Typ String!");
  }
  if (Ajax.getCharset() == 'utf-8' || Ajax.getCharset() == 'utf-16'){
    this.req.send(strKey + '=' + encodeURIComponent(strValue));
  } else {
    this.req.send(strKey + '=' + escape(strValue));
  }
}

Ajax.prototype.getReadyState = function () {
  if (this.req.readyState == undefined){
    return undefined;
  }
  return this.req.readyState;
}

Ajax.prototype.getStatus = function () {
  if (this.req.status == undefined){
    return undefined;
  }
  return this.req.status;
}

Ajax.prototype.getResponseXML = function () {
  return this.req.responseXML;
}

Ajax.prototype.getResponseText = function () {
  return this.req.responseText;
}

Ajax.prototype.getXML = function (str) {
  str = Ajax.stripSpace(str);
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->getXML: Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("Ajax->send: Argument str ist nicht vom Typ String!");
  }
  var xml = '';
  if (window.DOMParser){
    var parser = new DOMParser();
    xml = parser.parseFromString(str, "text/xml");
  } else {
    xml = new ActiveXObject("Microsoft.XMLDOM");
    xml.async="false";
    xml.loadXML(str);
  }
  return xml;
}

Ajax.prototype.getReadableXMLNode = function () {
  if (! this.req.responseXML){
    focus();
    throw new Error("Ajax->getReadableXMLNode: INVALID XML, SERVER-REQUEST-STATUS: " + this.getStatus());
    return undefined;
  }
  return this.req.responseXML.documentElement;
}

Ajax.prototype.getSingleNodeValue = function (name) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->getSingleNodeValue: Falsche Anzahl von Argumenten!");
  }
  if (typeof name != "string") {
    focus();
    throw new Error("Ajax->getSingleNodeValue: Argument name ist nicht vom Typ String!");
  }
  var xml = this.getReadableXMLNode();
  if (! xml){
    return undefined;
  }
  for (var i=0; i<xml.childNodes.length; i++) {
    var node = xml.childNodes[i];
    if (node.nodeType != 1){
      continue;
    }
    if (node.nodeName.toLowerCase() != name){
      continue;
    }
    return this.getValueFromXMLNode(node);
  }
  return undefined;
}

Ajax.prototype.getValueFromXMLNode = function (node) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->getValueFromXMLNode: Falsche Anzahl von Argumenten!");
  }
  return node.firstChild.nodeValue;
}

Ajax.prototype.getIdenticalNodeArray = function (name) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax->getIdenticalNodeArray: Falsche Anzahl von Argumenten!");
  }
  if (typeof name != "string") {
    focus();
    throw new Error("Ajax->getIdenticalNodeArray: Argument name ist nicht vom Typ String!");
  }
  var xml = this.getReadableXMLNode();
  if (! xml){
    return undefined;
  }
  return xml.getElementsByTagName(name);
}

Ajax._increment = [];
Ajax._registerInstance = {};
Ajax._registerInstanceLength = [];

Ajax._getNavigatorPrivilege = function (obj) {
  if (arguments.length != 1) {
    focus();
    throw new Error("Ajax._getNavigatorPrivilege: Falsche Anzahl von Argumenten!");
  }
  if (! (obj instanceof Ajax)) {
    focus();
    throw new Error("Ajax._getNavigatorPrivilege: Argument obj ist keine Instance von Ajax!");
  }
  if (obj.req) {
    if (typeof netscape != 'undefined' && typeof netscape.security != 'undefined' && typeof netscape.security.PrivilegeManager != 'undefined') {
      netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
      obj.open();
    } else {
      focus();
      throw new Error("Ajax._getNavigatorPrivilege: Das Ajax-Progamm läuft in diesem Kontext nicht. bitte wenden Sie sich an Ihren Administrator!");
    }
  }
}

Ajax.stripSpace = function(attr){
  var result = '';
  if (attr){
    attr = new String(attr);
    result = attr.replace(/^\s+/,'');
    result = result.replace(/\s+$/,'');
  }
  if (result.match(/^\s+/) || result.match(/\s+$/)){
    return Ajax.stripSpace(result);
  }
  return result;
}

Ajax.getInstance = function(id) {
  if (arguments.length!=1) {
    throw new Error("Falsche Anzahl von Argumenten!");
  }
  if (! (Ajax._registerInstance[id])){
    focus();
    throw new Error("Es ist keine Ajax.Instance mit id=" + id + " registriert!");
  }
  return Ajax._registerInstance[id];
}

Ajax.createInstance = function(id) {
  if (!arguments.length) {
    id = 'Ajax' + Ajax._increment.length;
    Ajax._increment.push(1);
  }
  if (! (Ajax._registerInstance[id])){
    Ajax._registerInstance[id] = new Ajax(id);
    Ajax._registerInstanceLength.push(id);
  } else {
    focus();
    throw new Error("Ajax.createInstance: id schon vorhanden!");
  }
  return Ajax.getInstance(id);
}

Ajax.cursorWait = function () {
  if (! document.getElementsByTagName('body').length){
    return;
  }
  document.getElementsByTagName('body')[0].style.cursor = 'wait';
}

Ajax.cursorFinished = function () {
  if (! document.getElementsByTagName('body').length){
    return;
  }
  document.getElementsByTagName('body')[0].style.cursor = 'auto';
}

Ajax.getCharset = function () {
  if (document.charset){
    // IE
    return document.charset.toLowerCase();
  } else if (document.characterSet) {
    return document.characterSet.toLowerCase();
  } else {
    return undefined;
  }
}



//==================================================================================
//==================================================================================
//
// Tools-MODUL Projektbezogene Methoden und Objekte
// OO-PROGRAMMIERUNG
// AUTOR: DF
// ERSTELLT: 09.05.2005
//
//==================================================================================
//==================================================================================

// ============================================================
// Klasse Tools
// ============================================================

function Tools() {
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

Tools.openMicrosite = function(htmlElement, properties) {
  if (!arguments.length) {
    return false;
  }
  var url = '';
  var docSource = '';
  var tagName = htmlElement['tagName'];
  tagName = tagName.toLowerCase();
  if (tagName == 'form'){
    var nameValuePeer = [];
    for (var i=0; i<htmlElement.elements.length; i++){
      nameValuePeer[i] = {};
      if (htmlElement.elements[i].name.length){
        if (htmlElement.elements[i].type == 'select-one'){
            nameValuePeer[i]['name'] = htmlElement.elements[i].name;
            nameValuePeer[i]['value'] = htmlElement.elements[i].options[htmlElement.elements[i].selectedIndex].value;
        } else if (htmlElement.elements[i].type == 'select-multiple'){
          nameValuePeer[i]['name'] = htmlElement.elements[i].name;
          nameValuePeer[i]['value'] = [];
          for (var ii=0; ii<htmlElement.elements[i].options.length; ii++){
            if (htmlElement.elements[i].options[ii].selected){
              nameValuePeer[i]['value'][ii] = htmlElement.elements[i].options[ii].value;
            }
          }
        } else if (htmlElement.elements[i].type == 'radio'){
          nameValuePeer[i]['name'] = htmlElement.elements[i].name;
          if (htmlElement.elements[i].length){
            nameValuePeer[i]['value'] = [];
            for (var ii=0; ii<htmlElement.elements[i].length; ii++){
              if (htmlElement.elements[i][ii].checked){
                nameValuePeer[i]['value'][ii] = htmlElement.elements[i][ii].value;
              }
            }
          } else {
            if (htmlElement.elements[i].checked){
              nameValuePeer[i]['value'] = htmlElement.elements[i].value;
            }
          }
        } else if (htmlElement.elements[i].type == 'checkbox'){
          nameValuePeer[i]['name'] = htmlElement.elements[i].name;
          if (htmlElement.elements[i].length){
            nameValuePeer[i]['value'] = [];
            for (var ii=0; ii<htmlElement.elements[i].length; ii++){
              if (htmlElement.elements[i][ii].checked){
                nameValuePeer[i]['value'][ii] = htmlElement.elements[i][ii].value;
              }
            }
          } else {
            if (htmlElement.elements[i].checked){
              nameValuePeer[i]['value'] = htmlElement.elements[i].value;
            }
          }
        } else {
          nameValuePeer[i]['name'] = htmlElement.elements[i].name;
          nameValuePeer[i]['value'] = htmlElement.elements[i].value;
        }
      }
    }
    if (!htmlElement.method || htmlElement.method.toLowerCase() != 'post'){
      url += htmlElement.action + '?';
      for (var f=0; f<nameValuePeer.length; f++){
        if (typeof nameValuePeer[f]['value'] == 'object'){
          for (var ff=0; ff<nameValuePeer[f]['value'].length; ff++){
            if (nameValuePeer[f]['value'][ff]){
              url += '&' + encodeURIComponent(nameValuePeer[f]['name']);
              url += '=' + encodeURIComponent(nameValuePeer[f]['value'][ff]);
            }
          }
        } else {
          if (nameValuePeer[f]['value']){
            url += '&' + encodeURIComponent(nameValuePeer[f]['name']);
            url += '=' + encodeURIComponent(nameValuePeer[f]['value']);
          }
        }
      }
    } else {
      var charsetting = 'ISO-8859-1';
      if (document.charset){
        if (document.charset != charsetting){
          charsetting = document.charset;
        }
      } else if (document.characterSet){
        if (document.characterSet != charsetting){
          charsetting = document.characterSet;
        }
      }
      docSource += '<html>\n<head><title></title><meta http-equiv="content-type" content="text/html; charset='+ charsetting +'"/></head>\n<body background-color="#ffffff" onload="document.forms[\'myform\'].submit();"><div style="display: none;">\n';
      docSource += '<form name="myform" action="'+ htmlElement.action +'" method="post">\n';
      for (var f=0; f<nameValuePeer.length; f++){
        if (typeof nameValuePeer[f]['value'] == 'object'){
          for (var ff=0; ff<nameValuePeer[f]['value'].length; ff++){
            if (nameValuePeer[f]['value'][ff]){
              docSource += '<input type="checkbox" name="'+ nameValuePeer[f]['name'] +'" value="'+ nameValuePeer[f]['value'][ff] +'" checked="checked"/>\n';
            }
          }
        } else {
          if (nameValuePeer[f]['value']){
            docSource += '<input type="checkbox" name="'+ nameValuePeer[f]['name'] +'" value="'+ nameValuePeer[f]['value'] +'" checked="checked"/>\n';
          }
        }
      }
      docSource += '</form>\n</div></body>\n</html>';
    }
    try {
      htmlElement.reset();
    } catch(e){
    }
  } else if (tagName == 'a' || tagName == 'area'){
    url += htmlElement.href;
  }
  var windowProps = '';
  if (arguments[1]){
    windowProps = properties;
  } else {
    windowProps = 'width=800,height=600,scrollbars=yes,locationbar=no,menubar=no';
  }
  var fenster = window.open(url, 'Micorsite', windowProps);
  if (docSource.length){
    var doc = fenster.document;
    doc.open();
    doc.write(docSource);
    doc.close();
  }
  fenster.focus();
  return false;
}

Tools.getCookieValue = function(cookieName){
  var cookieValue = '';
  if (! navigator.cookieEnabled){
    alert('Ihr Browser erlaubt keine Cookies!');
    return cookieValue;
  }
  if (! cookieName){
    return cookieValue;
  }
  var allCookies = document.cookie;
  var allCookiesArr = allCookies.split(/\;/);
  var regExp = new RegExp('^' + cookieName + '=');
  for (var i=0; i<allCookiesArr.length; i++){
    var _val = Tools.stripSpace(allCookiesArr[i]);
    if (! _val.match(regExp)){
      continue;
    }
    cookieValue = _val.replace(regExp,'');
  }
  if (cookieValue.match(/^"/) && cookieValue.match(/"$/)){
    cookieValue = cookieValue.replace(/^"/,'');
    cookieValue = cookieValue.replace(/"$/,'');
  }
  cookieValue = cookieValue.replace(/###/,';');
  return cookieValue;
}

Tools.setCookieValue = function(cookieValue, cookieName, expiresDate, path, version, valueType){
  if (! navigator.cookieEnabled){
    alert('Ihr Browser erlaubt keine Cookies!');
    return false;
  }
  if (! cookieValue.length){
    //return false;
  }
  if(! cookieName){
    cookieName = 'myCookie';
  }
  var expDate = Tools.DateToGMTStringCookie(expiresDate);
  if (cookieValue.length >= 4000){
    alert('Das Cookie kann nicht gespeichert werden.\nDie Datenmenge übersteigt die maximal zu speichernde Datenmenge eines Cookies.\nBitte überprüfen Sie Ihre Daten.');
    return false;
  }
  cookieValue = cookieValue.replace(/;/,'###');
  var cookieStr = '';
  if (valueType == 'int'){
    cookieStr = cookieName +'=' + cookieValue +';';
  } else {
    cookieStr = cookieName +'="' + cookieValue +'";';
  }
  if (expDate){
    cookieStr += ' expires='+ expDate +';';
  }
  if (path){
    cookieStr += ' path='+ path + ';';
  }
  version = 3;
  if (version && version.toString().length){
    cookieStr += ' version="'+ version + '";';
  }
  document.cookie = cookieStr;
}

Tools.DateToGMTStringCookie = function(date){
  if (! date){
    return false;
  }
  var str = '';
  var gtm = '';
  var gtmJS = date.toGMTString();
  var gtmArr = gtmJS.split(/ /);
  for (var i=0; i<gtmArr.length; i++){
    if (i>1 && i<4){
      gtm += '-';
    } else if (i > 0){
      gtm += ' ';
    }
    gtm += gtmArr[i];
  }
  return gtm;
}

Tools.confirmURL = function(url){
  if (! url){
    return false;
  }
  var conf = confirm('Möchten Sie den Datensatz wirklich löschen?');
  if (conf) {
    return url;
  }
}

Tools.checkRequiredData = function(htmlElement) {
  if (!arguments.length) {
    return false;
  }
  var _dataType = new RegExp(' \\[datatype\\=');
  var _required = new RegExp(' \\[required');
  var _requiredOn = new RegExp(' \\[requiredOn\\]');
  var _requiredOr = new RegExp(' \\[requiredOr\\]');
  var tagName = htmlElement['tagName'];
  tagName = tagName.toLowerCase();
  if (tagName == 'form'){
    for (var i=0; i<htmlElement.elements.length; i++){
      var idRequiredOn = undefined;
      var elemRequiredOn = undefined;
      var idRequiredOr = undefined;
      var elemRequiredOr = undefined;
      var mulitple = undefined;
      if(htmlElement.elements[i].nodeName.toLowerCase() == 'fieldset'){
        continue;
      }
      if (!htmlElement.elements[i].name.length || (!htmlElement.elements[i].className.length || (!htmlElement.elements[i].className.toString().match(_required) && !htmlElement.elements[i].className.toString().match(_dataType))) ){
        continue;
      }
      var requiredElemHasValue = false;
      var dataTypeElemHasDataTypeValue = true;
      if (htmlElement.elements[i].className.toString().match(_dataType)){
        if (! Tools.checkDataTypeElement(htmlElement.elements[i])) {
          dataTypeElemHasDataTypeValue = false;
        }
      }
      if (htmlElement.elements[i].className.toString().match(_requiredOn)){
        idRequiredOn = htmlElement.elements[i].className.toString().split(_requiredOn)[1].toString().replace(/[\[\]]/gi,'');
        elemRequiredOn = document.getElementById(idRequiredOn);
        if (Tools.checkRequiredElement(elemRequiredOn)){
          requiredElemHasValue = Tools.checkRequiredElement(htmlElement.elements[i]);
        } else {
          requiredElemHasValue = true;
        }
      } else if (htmlElement.elements[i].className.toString().match(_requiredOr)){
        idRequiredOr = htmlElement.elements[i].className.toString().split(_requiredOr)[1].toString().replace(/[\[\]]/gi,'');
        elemRequiredOr = document.getElementById(idRequiredOr);
        if (Tools.checkRequiredElement(elemRequiredOr)){
          requiredElemHasValue = true;
        } else {
          requiredElemHasValue = Tools.checkRequiredElement(htmlElement.elements[i]);
        }
      } else {
        requiredElemHasValue = Tools.checkRequiredElement(htmlElement.elements[i]);
      }
      if (!requiredElemHasValue){
        var shownElemName = htmlElement.elements[i].name;
        if (htmlElement.elements[i].title){
          shownElemName = htmlElement.elements[i].title;
        }
        if (elemRequiredOr != undefined){
          var shownElemNameOr = elemRequiredOr.name;
          if (elemRequiredOr.title){
            shownElemNameOr = elemRequiredOr.title;
          }
          alert('Bitte füllen Sie das Feld >>'+ shownElemName +'<< oder >>'+ shownElemNameOr +'<< aus!');
        } else {
          alert('Bitte füllen Sie das Feld >>'+ shownElemName +'<< aus!');
        }
        if (htmlElement.elements[i].type != 'hidden') {
          htmlElement.elements[i].focus();
        }
        return false;
      }
      if (!dataTypeElemHasDataTypeValue){
        var shownElemName = htmlElement.elements[i].name;
        if (htmlElement.elements[i].title){
          shownElemName = htmlElement.elements[i].title;
        }
        if (htmlElement.elements[i].type != 'hidden') {
          htmlElement.elements[i].focus();
        }
        return false;
      }
    }
    return true;
  }
}

Tools.checkRequiredDataFormFragment = function(htmlElement, elem) {
  if (arguments.length != 2) {
    return false;
  }
  var _dataType = new RegExp(' \\[datatype\\=');
  var _required = new RegExp(' \\[required');
  var _requiredOn = new RegExp(' \\[requiredOn\\]');
  var _requiredOr = new RegExp(' \\[requiredOr\\]');
  var tagName = htmlElement['tagName'];
  tagName = tagName.toLowerCase();
  if (tagName == 'form'){
    for (var i=0; i<htmlElement.elements.length; i++){
      var idRequiredOn = undefined;
      var elemRequiredOn = undefined;
      var idRequiredOr = undefined;
      var elemRequiredOr = undefined;
      if(htmlElement.elements[i].nodeName.toLowerCase() == 'fieldset'){
        continue;
      }
      if (!htmlElement.elements[i].name.length || (!htmlElement.elements[i].className.length || (!htmlElement.elements[i].className.toString().match(_required) && !htmlElement.elements[i].className.toString().match(_dataType))) ){
        continue;
      }
      if (! Tools.isChildOfElement(elem, htmlElement.elements[i])) {
        continue;
      }
      var requiredElemHasValue = false;
      var dataTypeElemHasDataTypeValue = true;
      if (htmlElement.elements[i].className.toString().match(_dataType)){
        if (! Tools.checkDataTypeElement(htmlElement.elements[i])) {
          dataTypeElemHasDataTypeValue = false;
        }
      }
      if (htmlElement.elements[i].className.toString().match(_requiredOn)){
        var idRequiredOn = htmlElement.elements[i].className.toString().split(_requiredOn)[1].toString().replace(/[\[\]]/gi,'');
        var elemRequiredOn = document.getElementById(idRequiredOn);
        if (Tools.checkRequiredElement(elemRequiredOn)){
          requiredElemHasValue = Tools.checkRequiredElement(htmlElement.elements[i]);
        } else {
          requiredElemHasValue = true;
        }
      } else if (htmlElement.elements[i].className.toString().match(_requiredOr)){
        var idRequiredOr = htmlElement.elements[i].className.toString().split(_requiredOr)[1].toString().replace(/[\[\]]/gi,'');
        var elemRequiredOr = document.getElementById(idRequiredOr);
        if (Tools.checkRequiredElement(elemRequiredOr)){
          requiredElemHasValue = true;
        } else {
          requiredElemHasValue = Tools.checkRequiredElement(htmlElement.elements[i]);
        }
      } else {
        requiredElemHasValue = Tools.checkRequiredElement(htmlElement.elements[i]);
      }
      if (!requiredElemHasValue){
        var shownElemName = htmlElement.elements[i].name;
        if (htmlElement.elements[i].title){
          shownElemName = htmlElement.elements[i].title;
        }
        if (elemRequiredOr != undefined){
          var shownElemNameOr = elemRequiredOr.name;
          if (elemRequiredOr.title){
            shownElemNameOr = elemRequiredOr.title;
          }
          alert('Bitte füllen Sie das Feld >>'+ shownElemName +'<< oder >>'+ shownElemNameOr +'<< aus!');
        } else {
          alert('Bitte füllen Sie das Feld >>'+ shownElemName +'<< aus!');
        }
        if (htmlElement.elements[i].type != 'hidden') {
          htmlElement.elements[i].focus();
        }
        return false;
      }
      if (!dataTypeElemHasDataTypeValue){
        var shownElemName = htmlElement.elements[i].name;
        if (htmlElement.elements[i].title){
          shownElemName = htmlElement.elements[i].title;
        }
        if (htmlElement.elements[i].type != 'hidden') {
          htmlElement.elements[i].focus();
        }
        return false;
      }
    }
    return true;
  }
}

Tools.isChildOfElement = function(parentElem, childElem) {
  if (arguments.length != 2) {
    return false;
  }
  var nextElem = childElem;
  while (nextElem && nextElem.nodeName.toLowerCase() != 'body'){
    if (nextElem == parentElem){
      return true;
    }
    nextElem = nextElem.parentNode;
  }
  return false;
}

Tools.checkDataTypeElement = function(elem) {
  if (!arguments.length) {
    return false;
  }
  if (elem == undefined){
    return false;
  }
  var _dataTypeDE = new RegExp(' \\[datatype\\=Date\\_DE\\]');
  var _dataTypeCMS = new RegExp(' \\[datatype\\=Date\\_CMS\\]');
  var _dataTypeMail = new RegExp(' \\[datatype\\=Mail\\]');
  var _dataTypeAge = new RegExp(' \\[datatype\\=Age\\]');
  var _dataTypeLedgerNr = new RegExp(' \\[datatype\\=LedgerNr\\]');
  var _dataTypeInteger = new RegExp(' \\[datatype\\=Integer\\]');
  var _value = '';
  if (elem.type == 'select-one'){
    if (elem.selectedIndex < 0){
      return false;
    }
    _value = Tools.stripSpace(elem.options[elem.selectedIndex].value);
  } else if (elem.type == 'select-multiple'){
    for (var ii=0; ii<elem.options.length; ii++){
      if (elem.options[ii].selected){
        _value += Tools.stripSpace(elem.options[ii].value);
      }
    }
  } else if (elem.type == 'radio'){
    if (elem.length){
      for (var ii=0; ii<elem.length; ii++){
        if (elem[ii].checked){
          _value += Tools.stripSpace(elem[ii].value);
        }
      }
    } else {
      if (elem.checked){
        _value = Tools.stripSpace(elem.value);
      }
    }
  } else if (elem.type == 'checkbox'){
    if (elem.length){
      for (var ii=0; ii<elem.length; ii++){
        if (elem[ii].checked){
          _value += Tools.stripSpace(elem[ii].value);
        }
      }
    } else {
      if (elem.checked){
        _value = Tools.stripSpace(elem.value);
      }
    }
  } else {
    _value = Tools.stripSpace(elem.value);
  }
  if (! _value.length){
    return true;
  }
  if (elem.className.toString().match(_dataTypeDE)){
    return Tools.validateDateFormat(_value, 'DE');
  }
  if (elem.className.toString().match(_dataTypeCMS)){
    return Tools.validateDateFormat(_value, 'CMS');
  }
  if (elem.className.toString().match(_dataTypeMail)){
    return Tools.validateMailFormat(_value);
  }
  if (elem.className.toString().match(_dataTypeLedgerNr)){
    return Tools.validateLedgerNumber(_value);
  }
  if (elem.className.toString().match(_dataTypeAge)){
    return Tools.validateAge(_value);
  }
  if (elem.className.toString().match(_dataTypeInteger)){
    return Tools.validateInteger(_value);
  }
  return true;
}

Tools.validateInteger = function(value) {
  if (! arguments.length) {
    return;
  }
  if (! value.match(/^[+-]?\d\d*$/)) {
    alert('Bitte geben Sie nur ganze Zahlen ein!');
    return false;
  }
  return true;
}

Tools.validateAge = function(value) {
  if (! arguments.length) {
    return;
  }
  if (! Tools.validateInteger(value)) {
    return false;
  }
  if (! (parseInt(value) > 0 && parseInt(value) < 130)) {
    var str = '';
    if (parseInt(value) > 120){
      str += 'Herzlichen Glückwunsch zu Ihrem sehr hohen Alter!!\n'
    } else {
      str += 'Sie sind leider noch nicht geboren!!\n';
    }
    str += 'Bitte geben Sie eine Zahl zwischen 1 und 130 ein!'
    alert(str);
    return false;
  }
  return true;
}

Tools.validateLedgerNumber = function(value) {
  if (! arguments.length) {
    return;
  }
  if (! value.match(/^(\d\d?\d?\d?\d?\d?\d?\d?\d?\d?)$/)) {
    alert('Bitte geben Sie eine Zahl mit 1 - 10 Stellen ein!');
    return false;
  }
  return true;
}

Tools.validateDateFormat = function(value, variant) {
  if (! arguments.length) {
    return;
  }
  if (variant == 'CMS'){
    if (! value.match(/^(\d\d\d\d)\-(\d\d)\-(\d\d)$/)) {
      alert('Bitte geben Sie das Datum im Format jjjj-mm-dd an!');
      return false;
    }
  } else {
    if (! value.match(/^(\d\d?)\.(\d\d?)\.(\d\d\d\d)$/)) {
      alert('Bitte geben Sie das Datum im Format tt.mm.jjjj an!');
      return false;
    }
  }
  return true;
}

Tools.validateMailFormat = function(value) {
  if (!arguments.length) {
    return false;
  }
  var regEx = new RegExp('^([a-zA-Z0-9\\-\\.\\_]+)(\\@)([a-zA-Z0-9\\-\\.]+)(\\.)([a-zA-Z]{2,4})$');
  if (! value.match(regEx)){
    alert('Bitte geben Sie eine gültige E-Mail-Adresse an!');
    return false;
  }
  return true;
}

Tools.checkRequiredElement = function(elem) {
  if (!arguments.length) {
    return false;
  }
  if (elem == undefined){
    return false;
  }
  var _multipleRegEx = new RegExp(' \\[multiple\\]');
  var _multiple = false;
  if(elem.className.toString().match(_multipleRegEx)){
    _multiple = true;
  }
  if (_multiple){
    return Tools.checkRequiredElementMultiple(elem);
  }
  return Tools.checkRequiredElementSingle(elem);
}

Tools.checkRequiredElementMultiple = function(elem) {
  if (!arguments.length) {
    return false;
  }
  if (elem == undefined){
    return false;
  }
  var requiredValue = '';
  var arr = document.getElementsByName(elem.name);
  for (var i=0; i<arr.length; i++) {
    var multipleElem = arr[i];
    if (! Tools.checkRequiredElementSingle(multipleElem)){
      continue;
    }
    return true;
  }
  return false;
}

Tools.checkRequiredElementSingle = function(elem) {
  if (!arguments.length) {
    return false;
  }
  if (elem == undefined){
    return false;
  }
  var requiredValue = '';
  if (elem.type == 'select-one'){
    if (elem.selectedIndex < 0){
      return false;
    }
    requiredValue = Tools.stripSpace(elem.options[elem.selectedIndex].value);
  } else if (elem.type == 'select-multiple'){
    for (var ii=0; ii<elem.options.length; ii++){
      if (elem.options[ii].selected){
        requiredValue += Tools.stripSpace(elem.options[ii].value);
      }
    }
  } else if (elem.type == 'radio'){
    if (elem.length){
      for (var ii=0; ii<elem.length; ii++){
        if (elem[ii].checked){
          requiredValue += Tools.stripSpace(elem[ii].value);
        }
      }
    } else {
      if (elem.checked){
        requiredValue = Tools.stripSpace(elem.value);
      }
    }
  } else if (elem.type == 'checkbox'){
    if (elem.length){
      for (var ii=0; ii<elem.length; ii++){
        if (elem[ii].checked){
          requiredValue += Tools.stripSpace(elem[ii].value);
        }
      }
    } else {
      if (elem.checked){
        requiredValue = Tools.stripSpace(elem.value);
      }
    }
  } else {
    requiredValue = Tools.stripSpace(elem.value);
  }
  if (!requiredValue.length){
    return false;
  }
  return true;
}

Tools.resetFormElement = function(elem) {
  if (!arguments.length) {
    return false;
  }
  if (elem == undefined){
    return false;
  }
  var requiredValue = '';
  if (elem.type == 'select-one'){
    elem.options[0].selected = 'selected';
  } else if (elem.type == 'select-multiple'){
    elem.options[0].selected = 'selected';
  } else if (elem.type == 'radio'){
    if (elem.length){
      for (var ii=0; ii<elem.length; ii++){
        elem[ii].checked = false;
      }
    } else {
      elem.checked = false;
    }
  } else if (elem.type == 'checkbox'){
    if (elem.length){
      for (var ii=0; ii<elem.length; ii++){
        elem[ii].checked = false;
      }
    } else {
      elem.checked = false;
    }
  } else {
    elem.value = '';
  }
  return true;
}

Tools.stripSpace = function(attr){
  var result = '';
  if (attr){
    attr = new String(attr);
    result = attr.replace(/^\s+/,'');
    result = result.replace(/\s+$/,'');
  }
  return result;
}

Tools.checkDataSize = function(elem, size) {
  if (!arguments.length) {
    return false;
  }
  var _type = elem.type.toLowerCase();
  var _value = Tools.stripSpace(elem.value);
  if (_type == 'textarea'){
    if (_value.length >= size){
      elem.value = _value.substring(0, size);
    }
  }
}

Tools.validateEmail = function(elem) {
  if (!arguments.length) {
    return false;
  }
  var _value = Tools.stripSpace(elem.value);
  var regEx = new RegExp('^([a-zA-Z0-9\\-\\.\\_]+)(\\@)([a-zA-Z0-9\\-\\.]+)(\\.)([a-zA-Z]{2,4})$');
  if (! _value.match(regEx)){
    alert('Bitte geben Sie eine gültige E-Mail-Adresse an!');
    elem.focus();
  }
}

Tools.validateURL = function(elem) {
  if (!arguments.length) {
    return false;
  }
  var _value = Tools.stripSpace(elem.value);
  var regEx = new RegExp('^(http:\/\/|https:\/\/|mailto:\/\/|ftp:\/\/|\/)');
  if (! _value.match(regEx)){
    alert('Bitte geben Sie eine gültige URL an!\nEine gültige URL muß mit http://, https://, etc. anfangen');
    elem.focus();
  }
}

Tools.openLinkinOpener = function(url) {
  if (!arguments.length) {
    return false;
  }
  var root;
  if (window.opener){
    root = window.opener;
  }
  if (parent.opener){
    root = parent.opener;
  }
  if (parent.top.opener){
    root = parent.top.opener;
  }
  if (! root){
    return true;
  }
  root.location = url;
  root.focus();
  return false;
}

Tools.submitQuichsearch = function(htmlElement) {
  if (!arguments.length) {
    return false;
  }
  var tagName = htmlElement['tagName'];
  tagName = tagName.toLowerCase();
  if (tagName == 'form'){
    var regExp = new RegExp('Stichwort|Stichwort eingeben|Suchwort|Suchwort eingeben|Suchbegriff|Suchbegriff eingeben');
    for (var i=0; i<htmlElement.elements.length; i++){
      var _value = Tools.stripSpace(htmlElement.elements[i].value);
      if(! _value.match(regExp)){
        continue;
      }
      htmlElement.elements[i].value = '';
    }
    return true;
  }
}

Tools.formatCashFloat = function(n){
  cash_float = parseFloat(new String(n).replace(/\,/,'.'));
  cash_float = parseFloat(cash_float * 100);
  cash_float = parseFloat(Math.round(cash_float) / 100);
  cash_float = new String(cash_float);
  if (!cash_float.match(/\./)){
    cash_float = cash_float + '.00';
  }
  if (cash_float.split(/\./)[1].length == 1){
    cash_float = cash_float + '0';
  }
  cash_float = cash_float.replace(/\./,',');
  return cash_float;
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.addEvent = function(oneEvent, obj, handler, bol, ieWindow){
  if (arguments.length < 3) {
    focus();
    throw new Error('Tools.addEvent: Falsche Anzahl von Argumenten!');
  }
  if(window.addEventListener){
    // Other
    obj.addEventListener(oneEvent, handler, bol);
  } else if(obj.attachEvent){
    // IE
    var win = window;
    if (ieWindow) {
      win = ieWindow;
    }
    obj['e' + oneEvent + handler] = handler;
    obj[oneEvent + handler] = function() { obj['e' + oneEvent + handler] ( win.event ); win.event.cancelBubble = true;};
    obj.attachEvent('on' + oneEvent, obj[oneEvent + handler]);
  }
  return true;
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.removeEvent = function(oneEvent, obj, handler, bol){
  if (arguments.length < 3) {
    focus();
    throw new Error('Tools.removeEvent: Falsche Anzahl von Argumenten!');
  }
  if(window.removeEventListener){
    // Other
    obj.removeEventListener(oneEvent, handler, bol);
  } else if(obj.detachEvent){
    // IE
    obj.detachEvent( "on"+ oneEvent, obj[oneEvent + handler] );
    obj[oneEvent + handler] = undefined;
    obj["e" + oneEvent + handler] = undefined;
  }
  return true;
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.eventStopPropagation = function(event){
  if (arguments.length!=1){
    focus();
    throw new Error("Tools:eventStopPropagation: Falsche Anzahl von Argumenten!");
  }
  if (event.stopPropagation){
    // Other
    event.stopPropagation();
  } else {
    // IE
    event.cancelBubble = true;
  }
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.eventPreventDefault = function(event){
  if (arguments.length!=1){
    focus();
    throw new Error("Tools:eventPreventDefault: Falsche Anzahl von Argumenten!");
  }
  if (event.preventDefault){
    // Other
    event.preventDefault();
  } else {
    // IE
    event.returnValue = false;
  }
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.jumpForwardInput = function(e, elem){
 if (arguments.length != 2) {
   focus();
   throw new Error('Tools.jumpForwardInput: Falsche Anzahl von Argumenten!');
 }
 if (! elem){
   return;
 }
 Tools.eventPreventDefault(e);
 if (! window.addEventListener)  {
  // IE
  e = window.event;
  key = e.keyCode;
 } else {
   // OTHER
   key = e.which;
 }
 if (key != 8 && key < 48 || key > 122){
   return;
 }
 var idPostfix = elem.id.toString().replace(/_token/,'');
 if (key == 8){
   var nextIdx = '_token' + parseFloat(parseFloat(idPostfix) - 1);
   var nextElem = document.getElementById(nextIdx);
   if (elem.value){
     elem.value = '';
     return;
   }
 } else {
   var nextIdx = '_token' + parseFloat(parseFloat(idPostfix) + 1);
   var nextElem = document.getElementById(nextIdx);
   elem.value = String.fromCharCode(key);
 }
 if (nextElem){
   nextElem.focus();
   return;
 }
 var submitBut = document.getElementById('submit-form');
 if (submitBut && parseFloat(idPostfix) >= 4){
   submitBut.focus();
 }
 return;
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.reloadCounter = 0;

Tools.reloadCodeField = function(url){
  if (arguments.length != 1) {
    return;
  }
  Ajax.cursorWait();
  Tools.reloadCounter++;
  url += '&__RC=' + Tools.reloadCounter;
  //alert('aufruf: ' + url);
  var img = new Image();
  img.className = "form-code-validate-secure";
  img.onload = function () {Tools.drawCodeField(this);}
  img.src = url;
  return false;
}

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Tools.drawCodeField = function(img){
  if (arguments.length != 1) {
    return;
  }
  //alert('nach bild-onload: ' + img.src);
  img.onload = '';
  var elem = document.getElementById('_sicherheitscode_');
  elem.innerHTML = '';
  elem.appendChild(img);
  /*
  var str = '<img src="'+ img.src +'" border="0" class="form-code-validate-secure" /><br />';
  elem.innerHTML = str;
  */
  Ajax.cursorFinished();
  return false;
}

Tools.setBank = function(elem, url){
  if (arguments.length != 2) {
    return;
  }
  var reqUrl = url + elem.value;
  Ajax.cursorWait();
  var myAjax = Ajax.createInstance();
  myAjax.setAsynchron(false);
  myAjax.setMethod('GET');
  myAjax.setURL(reqUrl);
  myAjax.open();
  myAjax.sendNull();
  var setBank = Tools._setBank(myAjax, elem);
  Ajax.cursorFinished();
}

Tools._setBank = function(ajax, elem){
  if (arguments.length != 2) {
    return;
  }
  if (ajax.getReadyState() != 4){
    return Ajax.cursorWait();
  }
  if (ajax.getReadyState() == 4){
    Ajax.cursorFinished();
    var xml = ajax.getReadableXMLNode();
    //alert(ajax.getResponseText());
    //alert(xml);
    if (! xml){
      alert('Es ist ein Fehler aufgetreten!');
      return;
    }
    var bankAnzeigeElem = document.getElementById('_Kreditinstitut_');
    var bankCGIElem = document.getElementById('konto_bank');
    var code = ajax.getSingleNodeValue('code');
    if (code == 'fail'){
      alert('Die Bankleitzahl konnte nicht ermittelt werden.\nBitte überprüfen Sie Ihre Angaben');
      bankAnzeigeElem.innerHTML = 'wird automatisch eingefügt';
      bankCGIElem.value = '';
      elem.value = '';
      elem.focus();
      return false;
    }
    var bankName = ajax.getSingleNodeValue('bank');
    bankCGIElem.value = bankName;
    if (bankAnzeigeElem) {
      bankAnzeigeElem.innerHTML = bankName;
    }
  }
  return true;
}




/////////////////////////////////////////////////////////////////////////////////////////////////////////////



/*  Prototype JavaScript framework, version 1.4.0
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *
 *  THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
 *  against the source tree, available from the Prototype darcs repository.
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *
 *  For details, see the Prototype web site: http://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.4.0',
  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',

  emptyFunction: function() {},
  K: function(x) {return x}
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

var Abstract = new Object();

Object.extend = function(destination, source) {
  for (property in source) {
    destination[property] = source[property];
  }
  return destination;
}

Object.inspect = function(object) {
  try {
    if (object == undefined) return 'undefined';
    if (object == null) return 'null';
    return object.inspect ? object.inspect() : object.toString();
  } catch (e) {
    if (e instanceof RangeError) return '...';
    throw e;
  }
}

Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

Function.prototype.bindAsEventListener = function(object) {
  var __method = this;
  return function(event) {
    return __method.call(object, event || window.event);
  }
}

Object.extend(Number.prototype, {
  toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  }
});

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }

    return returnValue;
  }
}

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.callback();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
}

/*--------------------------------------------------------------------------*/

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1)
      return element;

    elements.push(element);
  }

  return elements;
}
Object.extend(String.prototype, {
  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(eval);
  },

  escapeHTML: function() {
    var div = document.createElement('div');
    var text = document.createTextNode(this);
    div.appendChild(text);
    return div.innerHTML;
  },

  unescapeHTML: function() {
    var div = document.createElement('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
  },

  toQueryParams: function() {
    var pairs = this.match(/^\??(.*)$/)[1].split('&');
    return pairs.inject({}, function(params, pairString) {
      var pair = pairString.split('=');
      params[pair[0]] = pair[1];
      return params;
    });
  },

  toArray: function() {
    return this.split('');
  },

  camelize: function() {
    var oStringList = this.split('-');
    if (oStringList.length == 1) return oStringList[0];

    var camelizedString = this.indexOf('-') == 0
      ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
      : oStringList[0];

    for (var i = 1, len = oStringList.length; i < len; i++) {
      var s = oStringList[i];
      camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
    }

    return camelizedString;
  },

  inspect: function() {
    return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
  }
});

String.prototype.parseQuery = String.prototype.toQueryParams;

var $break    = new Object();
var $continue = new Object();

var Enumerable = {
  each: function(iterator) {
    var index = 0;
    try {
      this._each(function(value) {
        try {
          iterator(value, index++);
        } catch (e) {
          if (e != $continue) throw e;
        }
      });
    } catch (e) {
      if (e != $break) throw e;
    }
  },

  all: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      result = result && !!(iterator || Prototype.K)(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      if (result = !!(iterator || Prototype.K)(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      results.push(iterator(value, index));
    });
    return results;
  },

  detect: function (iterator) {
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(pattern, iterator) {
    var results = [];
    this.each(function(value, index) {
      var stringValue = value.toString();
      if (stringValue.match(pattern))
        results.push((iterator || Prototype.K)(value, index));
    })
    return results;
  },

  include: function(object) {
    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inject: function(memo, iterator) {
    this.each(function(value, index) {
      memo = iterator(memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.collect(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (value >= (result || value))
        result = value;
    });
    return result;
  },

  min: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (value <= (result || value))
        result = value;
    });
    return result;
  },

  partition: function(iterator) {
    var trues = [], falses = [];
    this.each(function(value, index) {
      ((iterator || Prototype.K)(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value, index) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator) {
    return this.collect(function(value, index) {
      return {value: value, criteria: iterator(value, index)};
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.collect(Prototype.K);
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (typeof args.last() == 'function')
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      iterator(value = collections.pluck(index));
      return value;
    });
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
}

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
    return iterable.toArray();
  } else {
    var results = [];
    for (var i = 0; i < iterable.length; i++)
      results.push(iterable[i]);
    return results;
  }
}

Object.extend(Array.prototype, Enumerable);

Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0; i < this.length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != undefined || value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(value.constructor == Array ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  indexOf: function(object) {
    for (var i = 0; i < this.length; i++)
      if (this[i] == object) return i;
    return -1;
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  shift: function() {
    var result = this[0];
    for (var i = 0; i < this.length - 1; i++)
      this[i] = this[i + 1];
    this.length--;
    return result;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  }
});
var Hash = {
  _each: function(iterator) {
    for (key in this) {
      var value = this[key];
      if (typeof value == 'function') continue;

      var pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  },

  keys: function() {
    return this.pluck('key');
  },

  values: function() {
    return this.pluck('value');
  },

  merge: function(hash) {
    return $H(hash).inject($H(this), function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  toQueryString: function() {
    return this.map(function(pair) {
      return pair.map(encodeURIComponent).join('=');
    }).join('&');
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }
}

function $H(object) {
  var hash = Object.extend({}, object || {});
  Object.extend(hash, Enumerable);
  Object.extend(hash, Hash);
  return hash;
}
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    do {
      iterator(value);
      value = value.succ();
    } while (this.include(value));
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
}

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
      function() {return new XMLHttpRequest()}
    ) || false;
  },

  activeRequestCount: 0
}

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responderToAdd) {
    if (!this.include(responderToAdd))
      this.responders.push(responderToAdd);
  },

  unregister: function(responderToRemove) {
    this.responders = this.responders.without(responderToRemove);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (responder[callback] && typeof responder[callback] == 'function') {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) {}
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate: function() {
    Ajax.activeRequestCount++;
  },

  onComplete: function() {
    Ajax.activeRequestCount--;
  }
});

Ajax.Base = function() {};
Ajax.Base.prototype = {
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      parameters:   ''
    }
    Object.extend(this.options, options || {});
  },

  responseIsSuccess: function() {
    return this.transport.status == undefined
        || this.transport.status == 0
        || (this.transport.status >= 200 && this.transport.status < 300);
  },

  responseIsFailure: function() {
    return !this.responseIsSuccess();
  }
}

Ajax.Request = Class.create();
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
    this.request(url);
  },

  request: function(url) {
    var parameters = this.options.parameters || '';
    if (parameters.length > 0) parameters += '&_=';

    try {
      this.url = url;
      if (this.options.method == 'get' && parameters.length > 0)
        this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;

      Ajax.Responders.dispatch('onCreate', this, this.transport);

      this.transport.open(this.options.method, this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) {
        this.transport.onreadystatechange = this.onStateChange.bind(this);
        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
      }

      this.setRequestHeaders();

      var body = this.options.postBody ? this.options.postBody : parameters;
      this.transport.send(this.options.method == 'post' ? body : null);

    } catch (e) {
      this.dispatchException(e);
    }
  },

  setRequestHeaders: function() {
    var requestHeaders =
      ['X-Requested-With', 'XMLHttpRequest',
       'X-Prototype-Version', Prototype.Version];

    if (this.options.method == 'post') {
      requestHeaders.push('Content-type',
        'application/x-www-form-urlencoded');

      /* Force "Connection: close" for Mozilla browsers to work around
       * a bug where XMLHttpReqeuest sends an incorrect Content-length
       * header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType)
        requestHeaders.push('Connection', 'close');
    }

    if (this.options.requestHeaders)
      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);

    for (var i = 0; i < requestHeaders.length; i += 2)
      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState != 1)
      this.respondToReadyState(this.transport.readyState);
  },

  header: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) {}
  },

  evalJSON: function() {
    try {
      return eval(this.header('X-JSON'));
    } catch (e) {}
  },

  evalResponse: function() {
    try {
      return eval(this.transport.responseText);
    } catch (e) {
      this.dispatchException(e);
    }
  },

  respondToReadyState: function(readyState) {
    var event = Ajax.Request.Events[readyState];
    var transport = this.transport, json = this.evalJSON();

    if (event == 'Complete') {
      try {
        (this.options['on' + this.transport.status]
         || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(transport, json);
      } catch (e) {
        this.dispatchException(e);
      }

      if ((this.header('Content-type') || '').match(/^text\/javascript/i))
        this.evalResponse();
    }

    try {
      (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
      Ajax.Responders.dispatch('on' + event, this, transport, json);
    } catch (e) {
      this.dispatchException(e);
    }

    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
    if (event == 'Complete')
      this.transport.onreadystatechange = Prototype.emptyFunction;
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
  initialize: function(container, url, options) {
    this.containers = {
      success: container.success ? $(container.success) : $(container),
      failure: container.failure ? $(container.failure) :
        (container.success ? null : $(container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, object) {
      this.updateContent();
      onComplete(transport, object);
    }).bind(this);

    this.request(url);
  },

  updateContent: function() {
    var receiver = this.responseIsSuccess() ?
      this.containers.success : this.containers.failure;
    var response = this.transport.responseText;

    if (!this.options.evalScripts)
      response = response.stripScripts();

    if (receiver) {
      if (this.options.insertion) {
        new this.options.insertion(receiver, response);
      } else {
        Element.update(receiver, response);
      }
    }

    if (this.responseIsSuccess()) {
      if (this.onComplete)
        setTimeout(this.onComplete.bind(this), 10);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
  initialize: function(container, url, options) {
    this.setOptions(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = {};
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(request) {
    if (this.options.decay) {
      this.decay = (request.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = request.responseText;
    }
    this.timer = setTimeout(this.onTimerEvent.bind(this),
      this.decay * this.frequency * 1000);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
document.getElementsByClassName = function(className, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  return $A(children).inject([], function(elements, child) {
    if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
      elements.push(child);
    return elements;
  });
}

/*--------------------------------------------------------------------------*/

if (!window.Element) {
  var Element = new Object();
}

Object.extend(Element, {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      Element[Element.visible(element) ? 'hide' : 'show'](element);
    }
  },

  hide: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 'none';
    }
  },

  show: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = '';
    }
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
  },

  update: function(element, html) {
    $(element).innerHTML = html.stripScripts();
    setTimeout(function() {html.evalScripts()}, 10);
  },

  getHeight: function(element) {
    element = $(element);
    return element.offsetHeight;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element.classNames(element).include(className);
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element.classNames(element).add(className);
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element.classNames(element).remove(className);
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    for (var i = 0; i < element.childNodes.length; i++) {
      var node = element.childNodes[i];
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        Element.remove(node);
    }
  },

  empty: function(element) {
    return $(element).innerHTML.match(/^\s*$/);
  },

  scrollTo: function(element) {
    element = $(element);
    var x = element.x ? element.x : element.offsetLeft,
        y = element.y ? element.y : element.offsetTop;
    window.scrollTo(x, y);
  },

  getStyle: function(element, style) {
    element = $(element);
    var value = element.style[style.camelize()];
    if (!value) {
      if (document.defaultView && document.defaultView.getComputedStyle) {
        var css = document.defaultView.getComputedStyle(element, null);
        value = css ? css.getPropertyValue(style) : null;
      } else if (element.currentStyle) {
        value = element.currentStyle[style.camelize()];
      }
    }

    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
      if (Element.getStyle(element, 'position') == 'static') value = 'auto';

    return value == 'auto' ? null : value;
  },

  setStyle: function(element, style) {
    element = $(element);
    for (name in style)
      element.style[name.camelize()] = style[name];
  },

  getDimensions: function(element) {
    element = $(element);
    if (Element.getStyle(element, 'display') != 'none')
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = '';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = 'none';
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return;
    element._overflow = element.style.overflow;
    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
      element.style.overflow = 'hidden';
  },

  undoClipping: function(element) {
    element = $(element);
    if (element._overflow) return;
    element.style.overflow = element._overflow;
    element._overflow = undefined;
  }
});

var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content.stripScripts();

    if (this.adjacency && this.element.insertAdjacentHTML) {
      try {
        this.element.insertAdjacentHTML(this.adjacency, this.content);
      } catch (e) {
        if (this.element.tagName.toLowerCase() == 'tbody') {
          this.insertContent(this.contentFromAnonymousTable());
        } else {
          throw e;
        }
      }
    } else {
      this.range = this.element.ownerDocument.createRange();
      if (this.initializeRange) this.initializeRange();
      this.insertContent([this.range.createContextualFragment(this.content)]);
    }

    setTimeout(function() {content.evalScripts()}, 10);
  },

  contentFromAnonymousTable: function() {
    var div = document.createElement('div');
    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
    return $A(div.childNodes[0].childNodes[0].childNodes);
  }
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment, this.element);
    }).bind(this));
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },

  insertContent: function(fragments) {
    fragments.reverse(false).each((function(fragment) {
      this.element.insertBefore(fragment, this.element.firstChild);
    }).bind(this));
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.appendChild(fragment);
    }).bind(this));
  }
});

Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment,
        this.element.nextSibling);
    }).bind(this));
  }
});

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set(this.toArray().concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set(this.select(function(className) {
      return className != classNameToRemove;
    }).join(' '));
  },

  toString: function() {
    return this.toArray().join(' ');
  }
}

Object.extend(Element.ClassNames.prototype, Enumerable);
var Field = {
  clear: function() {
    for (var i = 0; i < arguments.length; i++)
      $(arguments[i]).value = '';
  },

  focus: function(element) {
    $(element).focus();
  },

  present: function() {
    for (var i = 0; i < arguments.length; i++)
      if ($(arguments[i]).value == '') return false;
    return true;
  },

  select: function(element) {
    $(element).select();
  },

  activate: function(element) {
    element = $(element);
    element.focus();
    if (element.select)
      element.select();
  }
}

/*--------------------------------------------------------------------------*/

var Form = {
  serialize: function(form) {
    var elements = Form.getElements($(form));
    var queryComponents = new Array();

    for (var i = 0; i < elements.length; i++) {
      var queryComponent = Form.Element.serialize(elements[i]);
      if (queryComponent)
        queryComponents.push(queryComponent);
    }

    return queryComponents.join('&');
  },

  getElements: function(form) {
    form = $(form);
    var elements = new Array();

    for (tagName in Form.Element.Serializers) {
      var tagElements = form.getElementsByTagName(tagName);
      for (var j = 0; j < tagElements.length; j++)
        elements.push(tagElements[j]);
    }
    return elements;
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name)
      return inputs;

    var matchingInputs = new Array();
    for (var i = 0; i < inputs.length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) ||
          (name && input.name != name))
        continue;
      matchingInputs.push(input);
    }

    return matchingInputs;
  },

  disable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.blur();
      element.disabled = 'true';
    }
  },

  enable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.disabled = '';
    }
  },

  findFirstElement: function(form) {
    return Form.getElements(form).find(function(element) {
      return element.type != 'hidden' && !element.disabled &&
        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    Field.activate(Form.findFirstElement(form));
  },

  reset: function(form) {
    $(form).reset();
  }
}

Form.Element = {
  serialize: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);

    if (parameter) {
      var key = encodeURIComponent(parameter[0]);
      if (key.length == 0) return;

      if (parameter[1].constructor != Array)
        parameter[1] = [parameter[1]];

      return parameter[1].map(function(value) {
        return key + '=' + encodeURIComponent(value);
      }).join('&');
    }
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);

    if (parameter)
      return parameter[1];
  }
}

Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'submit':
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.Serializers.textarea(element);
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
    }
    return false;
  },

  inputSelector: function(element) {
    if (element.checked)
      return [element.name, element.value];
  },

  textarea: function(element) {
    return [element.name, element.value];
  },

  select: function(element) {
    return Form.Element.Serializers[element.type == 'select-one' ?
      'selectOne' : 'selectMany'](element);
  },

  selectOne: function(element) {
    var value = '', opt, index = element.selectedIndex;
    if (index >= 0) {
      opt = element.options[index];
      value = opt.value;
      if (!value && !('value' in opt))
        value = opt.text;
    }
    return [element.name, value];
  },

  selectMany: function(element) {
    var value = new Array();
    for (var i = 0; i < element.length; i++) {
      var opt = element.options[i];
      if (opt.selected) {
        var optValue = opt.value;
        if (!optValue && !('value' in opt))
          optValue = opt.text;
        value.push(optValue);
      }
    }
    return [element.name, value];
  }
}

/*--------------------------------------------------------------------------*/

var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;

    this.lastValue = this.getValue();
    this.registerCallback();
  },

  registerCallback: function() {
    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  onTimerEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
}

Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    var elements = Form.getElements(this.element);
    for (var i = 0; i < elements.length; i++)
      this.registerCallback(elements[i]);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        case 'password':
        case 'text':
        case 'textarea':
        case 'select-one':
        case 'select-multiple':
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
}

Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) {
  var Event = new Object();
}

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,

  element: function(event) {
    return event.target || event.srcElement;
  },

  isLeftClick: function(event) {
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },

  pointerX: function(event) {
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

  pointerY: function(event) {
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

  stop: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },

  // find the first node with the given tagName, starting from the
  // node the event was triggered on; traverses the DOM upwards
  findElement: function(event, tagName) {
    var element = Event.element(event);
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  },

  observers: false,

  _observeAndCache: function(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      this.observers.push([element, name, observer, useCapture]);
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      this.observers.push([element, name, observer, useCapture]);
      element.attachEvent('on' + name, observer);
    }
  },

  unloadCache: function() {
    if (!Event.observers) return;
    for (var i = 0; i < Event.observers.length; i++) {
      Event.stopObserving.apply(this, Event.observers[i]);
      Event.observers[i][0] = null;
    }
    Event.observers = false;
  },

  observe: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    this._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      element.detachEvent('on' + name, observer);
    }
  }
});

/* prevent memory leaks in IE */
Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  realOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return [valueL, valueT];
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return [valueL, valueT];
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        p = Element.getStyle(element, 'position');
        if (p == 'relative' || p == 'absolute') break;
      }
    } while (element);
    return [valueL, valueT];
  },

  offsetParent: function(element) {
    if (element.offsetParent) return element.offsetParent;
    if (element == document.body) return element;

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return element;

    return document.body;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = this.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = this.realOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = this.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  clone: function(source, target) {
    source = $(source);
    target = $(target);
    target.style.position = 'absolute';
    var offsets = this.cumulativeOffset(source);
    target.style.top    = offsets[1] + 'px';
    target.style.left   = offsets[0] + 'px';
    target.style.width  = source.offsetWidth + 'px';
    target.style.height = source.offsetHeight + 'px';
  },

  page: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent==document.body)
        if (Element.getStyle(element,'position')=='absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      valueT -= element.scrollTop  || 0;
      valueL -= element.scrollLeft || 0;
    } while (element = element.parentNode);

    return [valueL, valueT];
  },

  clone: function(source, target) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || {})

    // find page position of source
    source = $(source);
    var p = Position.page(source);

    // find coordinate system to use
    target = $(target);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(target,'position') == 'absolute') {
      parent = Position.offsetParent(target);
      delta = Position.page(parent);
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
  },

  absolutize: function(element) {
    element = $(element);
    if (element.style.position == 'absolute') return;
    Position.prepare();

    var offsets = Position.positionedOffset(element);
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';;
    element.style.left   = left + 'px';;
    element.style.width  = width + 'px';;
    element.style.height = height + 'px';;
  },

  relativize: function(element) {
    element = $(element);
    if (element.style.position == 'relative') return;
    Position.prepare();

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
  }
}

// Safari returns margins on body which is incorrect if the child is absolutely
// positioned.  For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
  Position.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return [valueL, valueT];
  }
}

// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

var Scriptaculous = {
  Version: '1.5.1',
  require: function(libraryName) {
    // inserting via DOM fails in Safari 2.0, so brute force approach
    document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
  },
  load: function() {
    if((typeof Prototype=='undefined') ||
      parseFloat(Prototype.Version.split(".")[0] + "." +
                 Prototype.Version.split(".")[1]) < 1.4)
      throw("script.aculo.us requires the Prototype JavaScript framework >= 1.4.0");
    
    $A(document.getElementsByTagName("script")).findAll( function(s) {
      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
    }).each( function(s) {
      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
      var includes = s.src.match(/\?.*load=([a-z,]*)/);
      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
       function(include) { Scriptaculous.require(path+include+'.js') });
    });
  }
}

Scriptaculous.load();



// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
//  Justin Palmer (http://encytemedia.com/)
//  Mark Pilgrim (http://diveintomark.org/)
//  Martin Bialasinki
// 
// See scriptaculous.js for full license.  

/* ------------- element ext -------------- */  
 
// converts rgb() and #xxx to #xxxxxx format,  
// returns self (or first argument) if not convertable  
String.prototype.parseColor = function() {  
  var color = '#';  
  if(this.slice(0,4) == 'rgb(') {  
    var cols = this.slice(4,this.length-1).split(',');  
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
  } else {  
    if(this.slice(0,1) == '#') {  
      if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
      if(this.length==7) color = this.toLowerCase();  
    }  
  }  
  return(color.length==7 ? color : (arguments[0] || this));  
}

Element.collectTextNodes = function(element) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
  }).flatten().join('');
}

Element.collectTextNodesIgnoreClass = function(element, className) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
        Element.collectTextNodes(node) : ''));
  }).flatten().join('');
}

Element.setStyle = function(element, style) {
  element = $(element);
  for(k in style) element.style[k.camelize()] = style[k];
}

Element.setContentZoom = function(element, percent) {  
  Element.setStyle(element, {fontSize: (percent/100) + 'em'});   
  if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);  
}

Element.getOpacity = function(element){  
  var opacity;
  if (opacity = Element.getStyle(element, 'opacity'))  
    return parseFloat(opacity);  
  if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))  
    if(opacity[1]) return parseFloat(opacity[1]) / 100;  
  return 1.0;  
}

Element.setOpacity = function(element, value){  
  element= $(element);  
  if (value == 1){
    Element.setStyle(element, { opacity: 
      (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 
      0.999999 : null });
    if(/MSIE/.test(navigator.userAgent))  
      Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
  } else {  
    if(value < 0.00001) value = 0;  
    Element.setStyle(element, {opacity: value});
    if(/MSIE/.test(navigator.userAgent))  
     Element.setStyle(element, 
       { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
                 'alpha(opacity='+value*100+')' });  
  }   
}  
 
Element.getInlineOpacity = function(element){  
  return $(element).style.opacity || '';
}  

Element.childrenWithClassName = function(element, className) {  
  return $A($(element).getElementsByTagName('*')).select(
    function(c) { return Element.hasClassName(c, className) });
}

Array.prototype.call = function() {
  var args = arguments;
  this.each(function(f){ f.apply(this, args) });
}

/*--------------------------------------------------------------------------*/

var Effect = {
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
    element = $(element);
    $A(element.childNodes).each( function(child) {
      if(child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            Builder.node('span',{style: tagifyStyle},
              character == ' ' ? String.fromCharCode(160) : character), 
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if(((typeof element == 'object') || 
        (typeof element == 'function')) && 
       (element.length))
      elements = element;
    else
      elements = $(element).childNodes;
      
    var options = Object.extend({
      speed: 0.1,
      delay: 0.0
    }, arguments[2] || {});
    var masterDelay = options.delay;

    $A(elements).each( function(element, index) {
      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
    });
  },
  PAIRS: {
    'slide':  ['SlideDown','SlideUp'],
    'blind':  ['BlindDown','BlindUp'],
    'appear': ['Appear','Fade']
  },
  toggle: function(element, effect) {
    element = $(element);
    effect = (effect || 'appear').toLowerCase();
    var options = Object.extend({
      queue: { position:'end', scope:(element.id || 'global') }
    }, arguments[2] || {});
    Effect[Element.visible(element) ? 
      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
  }
};

var Effect2 = Effect; // deprecated

/* ------------- transitions ------------- */

Effect.Transitions = {}

Effect.Transitions.linear = function(pos) {
  return pos;
}
Effect.Transitions.sinoidal = function(pos) {
  return (-Math.cos(pos*Math.PI)/2) + 0.5;
}
Effect.Transitions.reverse  = function(pos) {
  return 1-pos;
}
Effect.Transitions.flicker = function(pos) {
  return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
}
Effect.Transitions.wobble = function(pos) {
  return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
}
Effect.Transitions.pulse = function(pos) {
  return (Math.floor(pos*10) % 2 == 0 ? 
    (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
}
Effect.Transitions.none = function(pos) {
  return 0;
}
Effect.Transitions.full = function(pos) {
  return 1;
}

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
  initialize: function() {
    this.effects  = [];
    this.interval = null;
  },
  _each: function(iterator) {
    this.effects._each(iterator);
  },
  add: function(effect) {
    var timestamp = new Date().getTime();
    
    var position = (typeof effect.options.queue == 'string') ? 
      effect.options.queue : effect.options.queue.position;
    
    switch(position) {
      case 'front':
        // move unstarted effects after this effect  
        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
            e.startOn  += effect.finishOn;
            e.finishOn += effect.finishOn;
          });
        break;
      case 'end':
        // start effect after last queued effect has finished
        timestamp = this.effects.pluck('finishOn').max() || timestamp;
        break;
    }
    
    effect.startOn  += timestamp;
    effect.finishOn += timestamp;
    this.effects.push(effect);
    if(!this.interval) 
      this.interval = setInterval(this.loop.bind(this), 40);
  },
  remove: function(effect) {
    this.effects = this.effects.reject(function(e) { return e==effect });
    if(this.effects.length == 0) {
      clearInterval(this.interval);
      this.interval = null;
    }
  },
  loop: function() {
    var timePos = new Date().getTime();
    this.effects.invoke('loop', timePos);
  }
});

Effect.Queues = {
  instances: $H(),
  get: function(queueName) {
    if(typeof queueName != 'string') return queueName;
    
    if(!this.instances[queueName])
      this.instances[queueName] = new Effect.ScopedQueue();
      
    return this.instances[queueName];
  }
}
Effect.Queue = Effect.Queues.get('global');

Effect.DefaultOptions = {
  transition: Effect.Transitions.sinoidal,
  duration:   1.0,   // seconds
  fps:        25.0,  // max. 25fps due to Effect.Queue implementation
  sync:       false, // true for combining
  from:       0.0,
  to:         1.0,
  delay:      0.0,
  queue:      'parallel'
}

Effect.Base = function() {};
Effect.Base.prototype = {
  position: null,
  start: function(options) {
    this.options      = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
    this.currentFrame = 0;
    this.state        = 'idle';
    this.startOn      = this.options.delay*1000;
    this.finishOn     = this.startOn + (this.options.duration*1000);
    this.event('beforeStart');
    if(!this.options.sync)
      Effect.Queues.get(typeof this.options.queue == 'string' ? 
        'global' : this.options.queue.scope).add(this);
  },
  loop: function(timePos) {
    if(timePos >= this.startOn) {
      if(timePos >= this.finishOn) {
        this.render(1.0);
        this.cancel();
        this.event('beforeFinish');
        if(this.finish) this.finish(); 
        this.event('afterFinish');
        return;  
      }
      var pos   = (timePos - this.startOn) / (this.finishOn - this.startOn);
      var frame = Math.round(pos * this.options.fps * this.options.duration);
      if(frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  render: function(pos) {
    if(this.state == 'idle') {
      this.state = 'running';
      this.event('beforeSetup');
      if(this.setup) this.setup();
      this.event('afterSetup');
    }
    if(this.state == 'running') {
      if(this.options.transition) pos = this.options.transition(pos);
      pos *= (this.options.to-this.options.from);
      pos += this.options.from;
      this.position = pos;
      this.event('beforeUpdate');
      if(this.update) this.update(pos);
      this.event('afterUpdate');
    }
  },
  cancel: function() {
    if(!this.options.sync)
      Effect.Queues.get(typeof this.options.queue == 'string' ? 
        'global' : this.options.queue.scope).remove(this);
    this.state = 'finished';
  },
  event: function(eventName) {
    if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
    if(this.options[eventName]) this.options[eventName](this);
  },
  inspect: function() {
    return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
}

Effect.Parallel = Class.create();
Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
  initialize: function(effects) {
    this.effects = effects || [];
    this.start(arguments[1]);
  },
  update: function(position) {
    this.effects.invoke('render', position);
  },
  finish: function(position) {
    this.effects.each( function(effect) {
      effect.render(1.0);
      effect.cancel();
      effect.event('beforeFinish');
      if(effect.finish) effect.finish(position);
      effect.event('afterFinish');
    });
  }
});

Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    // make this work on IE on elements without 'layout'
    if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
      Element.setStyle(this.element, {zoom: 1});
    var options = Object.extend({
      from: Element.getOpacity(this.element) || 0.0,
      to:   1.0
    }, arguments[1] || {});
    this.start(options);
  },
  update: function(position) {
    Element.setOpacity(this.element, position);
  }
});

Effect.Move = Class.create();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || {});
    this.start(options);
  },
  setup: function() {
    // Bug in Opera: Opera returns the "real" position of a static element or
    // relative element that does not have top/left explicitly set.
    // ==> Always set top and left for position relative elements in your stylesheets 
    // (to 0 if you do not need them) 
    Element.makePositioned(this.element);
    this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
    this.originalTop  = parseFloat(Element.getStyle(this.element,'top')  || '0');
    if(this.options.mode == 'absolute') {
      // absolute movement, so we need to calc deltaX and deltaY
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    Element.setStyle(this.element, {
      left: this.options.x  * position + this.originalLeft + 'px',
      top:  this.options.y  * position + this.originalTop  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element, 
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
};

Effect.Scale = Class.create();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
  initialize: function(element, percent) {
    this.element = $(element)
    var options = Object.extend({
      scaleX: true,
      scaleY: true,
      scaleContent: true,
      scaleFromCenter: false,
      scaleMode: 'box',        // 'box' or 'contents' or {} with provided values
      scaleFrom: 100.0,
      scaleTo:   percent
    }, arguments[2] || {});
    this.start(options);
  },
  setup: function() {
    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    this.elementPositioning = Element.getStyle(this.element,'position');
    
    this.originalStyle = {};
    ['top','left','width','height','fontSize'].each( function(k) {
      this.originalStyle[k] = this.element.style[k];
    }.bind(this));
      
    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;
    
    var fontSize = Element.getStyle(this.element,'font-size') || '100%';
    ['em','px','%'].each( function(fontSizeType) {
      if(fontSize.indexOf(fontSizeType)>0) {
        this.fontSize     = parseFloat(fontSize);
        this.fontSizeType = fontSizeType;
      }
    }.bind(this));
    
    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
    
    this.dims = null;
    if(this.options.scaleMode=='box')
      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
    if(/^content/.test(this.options.scaleMode))
      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
    if(!this.dims)
      this.dims = [this.options.scaleMode.originalHeight,
                   this.options.scaleMode.originalWidth];
  },
  update: function(position) {
    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
    if(this.options.scaleContent && this.fontSize)
      Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType });
    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
  },
  finish: function(position) {
    if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);
  },
  setDimensions: function(height, width) {
    var d = {};
    if(this.options.scaleX) d.width = width + 'px';
    if(this.options.scaleY) d.height = height + 'px';
    if(this.options.scaleFromCenter) {
      var topd  = (height - this.dims[0])/2;
      var leftd = (width  - this.dims[1])/2;
      if(this.elementPositioning == 'absolute') {
        if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
        if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
      } else {
        if(this.options.scaleY) d.top = -topd + 'px';
        if(this.options.scaleX) d.left = -leftd + 'px';
      }
    }
    Element.setStyle(this.element, d);
  }
});

Effect.Highlight = Class.create();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
    this.start(options);
  },
  setup: function() {
    // Prevent executing on elements not in the layout flow
    if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; }
    // Disable background image during the effect
    this.oldStyle = {
      backgroundImage: Element.getStyle(this.element, 'background-image') };
    Element.setStyle(this.element, {backgroundImage: 'none'});
    if(!this.options.endcolor)
      this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
    if(!this.options.restorecolor)
      this.options.restorecolor = Element.getStyle(this.element, 'background-color');
    // init color calculations
    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
  },
  update: function(position) {
    Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){
      return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
  },
  finish: function() {
    Element.setStyle(this.element, Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = Class.create();
Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    this.start(arguments[1] || {});
  },
  setup: function() {
    Position.prepare();
    var offsets = Position.cumulativeOffset(this.element);
    if(this.options.offset) offsets[1] += this.options.offset;
    var max = window.innerHeight ? 
      window.height - window.innerHeight :
      document.body.scrollHeight - 
        (document.documentElement.clientHeight ? 
          document.documentElement.clientHeight : document.body.clientHeight);
    this.scrollStart = Position.deltaY;
    this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
  },
  update: function(position) {
    Position.prepare();
    window.scrollTo(Position.deltaX, 
      this.scrollStart + (position*this.delta));
  }
});

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
  var oldOpacity = Element.getInlineOpacity(element);
  var options = Object.extend({
  from: Element.getOpacity(element) || 1.0,
  to:   0.0,
  afterFinishInternal: function(effect) { with(Element) { 
    if(effect.options.to!=0) return;
    hide(effect.element);
    setStyle(effect.element, {opacity: oldOpacity}); }}
  }, arguments[1] || {});
  return new Effect.Opacity(element,options);
}

Effect.Appear = function(element) {
  var options = Object.extend({
  from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
  to:   1.0,
  beforeSetup: function(effect) { with(Element) {
    setOpacity(effect.element, effect.options.from);
    show(effect.element); }}
  }, arguments[1] || {});
  return new Effect.Opacity(element,options);
}

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200, 
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
     Object.extend({ duration: 1.0, 
      beforeSetupInternal: function(effect) { with(Element) {
        setStyle(effect.effects[0].element, {position: 'absolute'}); }},
      afterFinishInternal: function(effect) { with(Element) {
         hide(effect.effects[0].element);
         setStyle(effect.effects[0].element, oldStyle); }}
     }, arguments[1] || {})
   );
}

Effect.BlindUp = function(element) {
  element = $(element);
  Element.makeClipping(element);
  return new Effect.Scale(element, 0, 
    Object.extend({ scaleContent: false, 
      scaleX: false, 
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) { with(Element) {
        [hide, undoClipping].call(effect.element); }} 
    }, arguments[1] || {})
  );
}

Effect.BlindDown = function(element) {
  element = $(element);
  var oldHeight = Element.getStyle(element, 'height');
  var elementDimensions = Element.getDimensions(element);
  return new Effect.Scale(element, 100, 
    Object.extend({ scaleContent: false, 
      scaleX: false,
      scaleFrom: 0,
      scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
      restoreAfterFinish: true,
      afterSetup: function(effect) { with(Element) {
        makeClipping(effect.element);
        setStyle(effect.element, {height: '0px'});
        show(effect.element); 
      }},  
      afterFinishInternal: function(effect) { with(Element) {
        undoClipping(effect.element);
        setStyle(effect.element, {height: oldHeight});
      }}
    }, arguments[1] || {})
  );
}

Effect.SwitchOff = function(element) {
  element = $(element);
  var oldOpacity = Element.getInlineOpacity(element);
  return new Effect.Appear(element, { 
    duration: 0.4,
    from: 0,
    transition: Effect.Transitions.flicker,
    afterFinishInternal: function(effect) {
      new Effect.Scale(effect.element, 1, { 
        duration: 0.3, scaleFromCenter: true,
        scaleX: false, scaleContent: false, restoreAfterFinish: true,
        beforeSetup: function(effect) { with(Element) {
          [makePositioned,makeClipping].call(effect.element);
        }},
        afterFinishInternal: function(effect) { with(Element) {
          [hide,undoClipping,undoPositioned].call(effect.element);
          setStyle(effect.element, {opacity: oldOpacity});
        }}
      })
    }
  });
}

Effect.DropOut = function(element) {
  element = $(element);
  var oldStyle = {
    top: Element.getStyle(element, 'top'),
    left: Element.getStyle(element, 'left'),
    opacity: Element.getInlineOpacity(element) };
  return new Effect.Parallel(
    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    Object.extend(
      { duration: 0.5,
        beforeSetup: function(effect) { with(Element) {
          makePositioned(effect.effects[0].element); }},
        afterFinishInternal: function(effect) { with(Element) {
          [hide, undoPositioned].call(effect.effects[0].element);
          setStyle(effect.effects[0].element, oldStyle); }} 
      }, arguments[1] || {}));
}

Effect.Shake = function(element) {
  element = $(element);
  var oldStyle = {
    top: Element.getStyle(element, 'top'),
    left: Element.getStyle(element, 'left') };
	  return new Effect.Move(element, 
	    { x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
	  new Effect.Move(effect.element,
	    { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
	  new Effect.Move(effect.element,
	    { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
	  new Effect.Move(effect.element,
	    { x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
	  new Effect.Move(effect.element,
	    { x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
	  new Effect.Move(effect.element,
	    { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
        undoPositioned(effect.element);
        setStyle(effect.element, oldStyle);
  }}}) }}) }}) }}) }}) }});
}

Effect.SlideDown = function(element) {
  element = $(element);
  Element.cleanWhitespace(element);
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
  var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
  var elementDimensions = Element.getDimensions(element);
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false, 
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) { with(Element) {
      makePositioned(effect.element);
      makePositioned(effect.element.firstChild);
      if(window.opera) setStyle(effect.element, {top: ''});
      makeClipping(effect.element);
      setStyle(effect.element, {height: '0px'});
      show(element); }},
    afterUpdateInternal: function(effect) { with(Element) {
      setStyle(effect.element.firstChild, {bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
    afterFinishInternal: function(effect) { with(Element) {
      undoClipping(effect.element); 
      undoPositioned(effect.element.firstChild);
      undoPositioned(effect.element);
      setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
    }, arguments[1] || {})
  );
}
  
Effect.SlideUp = function(element) {
  element = $(element);
  Element.cleanWhitespace(element);
  var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
  return new Effect.Scale(element, 0, 
   Object.extend({ scaleContent: false, 
    scaleX: false, 
    scaleMode: 'box',
    scaleFrom: 100,
    restoreAfterFinish: true,
    beforeStartInternal: function(effect) { with(Element) {
      makePositioned(effect.element);
      makePositioned(effect.element.firstChild);
      if(window.opera) setStyle(effect.element, {top: ''});
      makeClipping(effect.element);
      show(element); }},  
    afterUpdateInternal: function(effect) { with(Element) {
      setStyle(effect.element.firstChild, {bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
    afterFinishInternal: function(effect) { with(Element) {
        [hide, undoClipping].call(effect.element); 
        undoPositioned(effect.element.firstChild);
        undoPositioned(effect.element);
        setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
   }, arguments[1] || {})
  );
}

// Bug in opera makes the TD containing this element expand for a instance after finish 
Effect.Squish = function(element) {
  return new Effect.Scale(element, window.opera ? 1 : 0, 
    { restoreAfterFinish: true,
      beforeSetup: function(effect) { with(Element) {
        makeClipping(effect.element); }},  
      afterFinishInternal: function(effect) { with(Element) {
        hide(effect.element); 
        undoClipping(effect.element); }}
  });
}

Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransistion: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || {});
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: Element.getInlineOpacity(element) };

  var dims = Element.getDimensions(element);    
  var initialMoveX, initialMoveY;
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0; 
      break;
    case 'top-right':
      initialMoveX = dims.width;
      initialMoveY = moveY = 0;
      moveX = -dims.width;
      break;
    case 'bottom-left':
      initialMoveX = moveX = 0;
      initialMoveY = dims.height;
      moveY = -dims.height;
      break;
    case 'bottom-right':
      initialMoveX = dims.width;
      initialMoveY = dims.height;
      moveX = -dims.width;
      moveY = -dims.height;
      break;
    case 'center':
      initialMoveX = dims.width / 2;
      initialMoveY = dims.height / 2;
      moveX = -dims.width / 2;
      moveY = -dims.height / 2;
      break;
  }
  
  return new Effect.Move(element, {
    x: initialMoveX,
    y: initialMoveY,
    duration: 0.01, 
    beforeSetup: function(effect) { with(Element) {
      hide(effect.element);
      makeClipping(effect.element);
      makePositioned(effect.element);
    }},
    afterFinishInternal: function(effect) {
      new Effect.Parallel(
        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
          new Effect.Scale(effect.element, 100, {
            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
        ], Object.extend({
             beforeSetup: function(effect) { with(Element) {
               setStyle(effect.effects[0].element, {height: '0px'});
               show(effect.effects[0].element); }},
             afterFinishInternal: function(effect) { with(Element) {
               [undoClipping, undoPositioned].call(effect.effects[0].element); 
               setStyle(effect.effects[0].element, oldStyle); }}
           }, options)
      )
    }
  });
}

Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransistion: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || {});
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: Element.getInlineOpacity(element) };

  var dims = Element.getDimensions(element);
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':
      moveX = dims.width;
      moveY = 0;
      break;
    case 'bottom-left':
      moveX = 0;
      moveY = dims.height;
      break;
    case 'bottom-right':
      moveX = dims.width;
      moveY = dims.height;
      break;
    case 'center':  
      moveX = dims.width / 2;
      moveY = dims.height / 2;
      break;
  }
  
  return new Effect.Parallel(
    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    ], Object.extend({            
         beforeStartInternal: function(effect) { with(Element) {
           [makePositioned, makeClipping].call(effect.effects[0].element) }},
         afterFinishInternal: function(effect) { with(Element) {
           [hide, undoClipping, undoPositioned].call(effect.effects[0].element);
           setStyle(effect.effects[0].element, oldStyle); }}
       }, options)
  );
}

Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || {};
  var oldOpacity = Element.getInlineOpacity(element);
  var transition = options.transition || Effect.Transitions.sinoidal;
  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
  reverser.bind(transition);
  return new Effect.Opacity(element, 
    Object.extend(Object.extend({  duration: 3.0, from: 0,
      afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); }
    }, options), {transition: reverser}));
}

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  Element.makeClipping(element);
  return new Effect.Scale(element, 5, Object.extend({   
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, { 
      scaleContent: false, 
      scaleY: false,
      afterFinishInternal: function(effect) { with(Element) {
        [hide, undoClipping].call(effect.element); 
        setStyle(effect.element, oldStyle);
      }} });
  }}, arguments[1] || {}));
}



// -----------------------------------------------------------------------------------
//
//	Lightbox v2.03.3
//	by Lokesh Dhakar - http://www.huddletogether.com
//	5/21/06
//
//	For more information on this script, visit:
//	http://huddletogether.com/projects/lightbox2/
//
//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
//	
//	Credit also due to those who have helped, inspired, and made their code available to the public.
//	Including: Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), Thomas Fuchs(mir.aculo.us), and others.
//
//
// -----------------------------------------------------------------------------------
/*

	Table of Contents
	-----------------
	Configuration
	Global Variables

	Extending Built-in Objects	
	- Object.extend(Element)
	- Array.prototype.removeDuplicates()
	- Array.prototype.empty()

	Lightbox Class Declaration
	- initialize()
	- updateImageList()
	- start()
	- changeImage()
	- resizeImageContainer()
	- showImage()
	- updateDetails()
	- updateNav()
	- enableKeyboardNav()
	- disableKeyboardNav()
	- keyboardAction()
	- preloadNeighborImages()
	- end()
	
	Miscellaneous Functions
	- getPageScroll()
	- getPageSize()
	- getKey()
	- listenKey()
	- showSelectBoxes()
	- hideSelectBoxes()
	- showFlash()
	- hideFlash()
	- pause()
	- initLightbox()
	
	Function Calls
	- addLoadEvent(initLightbox)
	
*/
// -----------------------------------------------------------------------------------

//
//	Configuration
//
var fileLoadingImage = "/kiosk/grafik/loading.gif";		
var fileBottomNavCloseImage = "/kiosk/grafik/schliessen.gif";

var overlayOpacity = 0.8;	// controls transparency of shadow overlay

var animate = true;			// toggles resizing animations
var resizeSpeed = 7;		// controls the speed of the image resizing animations (1=slowest and 10=fastest)

var borderSize = 10;		//if you adjust the padding in the CSS, you will need to update this variable

// -----------------------------------------------------------------------------------

//
//	Global Variables
//
var imageArray = new Array;
var activeImage;

if(animate == true){
	overlayDuration = 0.2;	// shadow fade in/out duration
	if(resizeSpeed > 10){ resizeSpeed = 10;}
	if(resizeSpeed < 1){ resizeSpeed = 1;}
	resizeDuration = (11 - resizeSpeed) * 0.15;
} else { 
	overlayDuration = 0;
	resizeDuration = 0;
}

// -----------------------------------------------------------------------------------

//
//	Additional methods for Element added by SU, Couloir
//	- further additions by Lokesh Dhakar (huddletogether.com)
//
Object.extend(Element, {
	getWidth: function(element) {
	   	element = $(element);
	   	return element.offsetWidth; 
	},
	setWidth: function(element,w) {
	   	element = $(element);
    	element.style.width = w +"px";
	},
	setHeight: function(element,h) {
   		element = $(element);
    	element.style.height = h +"px";
	},
	setTop: function(element,t) {
	   	element = $(element);
    	element.style.top = t +"px";
	},
	setLeft: function(element,l) {
	   	element = $(element);
    	element.style.left = l +"px";
	},
	setSrc: function(element,src) {
    	element = $(element);
    	element.src = src; 
	},
	setHref: function(element,href) {
    	element = $(element);
    	element.href = href; 
	},
	setInnerHTML: function(element,content) {
		element = $(element);
		element.innerHTML = content;
	}
});

// -----------------------------------------------------------------------------------

//
//	Extending built-in Array object
//	- array.removeDuplicates()
//	- array.empty()
//
Array.prototype.removeDuplicates = function () {
    for(i = 0; i < this.length; i++){
        for(j = this.length-1; j>i; j--){        
            if(this[i][0] == this[j][0]){
                this.splice(j,1);
            }
        }
    }
}

// -----------------------------------------------------------------------------------

Array.prototype.empty = function () {
	for(i = 0; i <= this.length; i++){
		this.shift();
	}
}

// -----------------------------------------------------------------------------------

//
//	Lightbox Class Declaration
//	- initialize()
//	- start()
//	- changeImage()
//	- resizeImageContainer()
//	- showImage()
//	- updateDetails()
//	- updateNav()
//	- enableKeyboardNav()
//	- disableKeyboardNav()
//	- keyboardNavAction()
//	- preloadNeighborImages()
//	- end()
//
//	Structuring of code inspired by Scott Upton (http://www.uptonic.com/)
//
var Lightbox = Class.create();

Lightbox.prototype = {
	
	// initialize()
	// Constructor runs on completion of the DOM loading. Calls updateImageList and then
	// the function inserts html at the bottom of the page which is used to display the shadow 
	// overlay and the image container.
	//
	initialize: function() {	
		
		this.updateImageList();

		// Code inserts html at the bottom of the page that looks similar to this:
		//
		//	<div id="overlay"></div>
		//	<div id="lightbox">
		//		<div id="outerImageContainer">
		//			<div id="imageContainer">
		//				<img id="lightboxImage">
		//				<div style="" id="hoverNav">
		//					<a href="#" id="prevLink"></a>
		//					<a href="#" id="nextLink"></a>
		//				</div>
		//				<div id="loading">
		//					<a href="#" id="loadingLink">
		//						<img src="grafik/loading.gif">
		//					</a>
		//				</div>
		//			</div>
		//		</div>
		//		<div id="imageDataContainer">
		//			<div id="imageData">
		//				<div id="imageDetails">
		//					<span id="caption"></span>
		//					<span id="numberDisplay"></span>
		//				</div>
		//				<div id="bottomNav">
		//					<a href="#" id="bottomNavClose">
		//						<img src="grafik/close.gif">
		//					</a>
		//				</div>
		//			</div>
		//		</div>
		//	</div>


		var objBody = document.getElementsByTagName("body").item(0);
		
		var objOverlay = document.createElement("div");
		objOverlay.setAttribute('id','overlay');
		objOverlay.style.display = 'none';
		objOverlay.onclick = function() { myLightbox.end(); }
		objBody.appendChild(objOverlay);
		
		var objLightbox = document.createElement("div");
		objLightbox.setAttribute('id','lightbox');
		objLightbox.style.display = 'none';
		objLightbox.onclick = function(e) {	// close Lightbox is user clicks shadow overlay
			if (!e) var e = window.event;
			var clickObj = Event.element(e).id;
			if ( clickObj == 'lightbox') {
				myLightbox.end();
			}
		};
		objBody.appendChild(objLightbox);
			
		var objOuterImageContainer = document.createElement("div");
		objOuterImageContainer.setAttribute('id','outerImageContainer');
		objLightbox.appendChild(objOuterImageContainer);

		// When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
		// If animations are turned off, it will be hidden as to prevent a flicker of a
		// white 250 by 250 box.
		if(animate){
			Element.setWidth('outerImageContainer', 250);
			Element.setHeight('outerImageContainer', 250);			
		} else {
			Element.setWidth('outerImageContainer', 1);
			Element.setHeight('outerImageContainer', 1);			
		}

		var objImageContainer = document.createElement("div");
		objImageContainer.setAttribute('id','imageContainer');
		objOuterImageContainer.appendChild(objImageContainer);
	
		var objLightboxImage = document.createElement("img");
		objLightboxImage.setAttribute('id','lightboxImage');
		objImageContainer.appendChild(objLightboxImage);
	
		var objHoverNav = document.createElement("div");
		objHoverNav.setAttribute('id','hoverNav');
		objImageContainer.appendChild(objHoverNav);
	
		var objPrevLink = document.createElement("a");
		objPrevLink.setAttribute('id','prevLink');
		objPrevLink.setAttribute('href','#');
		objHoverNav.appendChild(objPrevLink);
		
		var objNextLink = document.createElement("a");
		objNextLink.setAttribute('id','nextLink');
		objNextLink.setAttribute('href','#');
		objHoverNav.appendChild(objNextLink);
	
		var objLoading = document.createElement("div");
		objLoading.setAttribute('id','loading');
		objImageContainer.appendChild(objLoading);
	
		var objLoadingLink = document.createElement("a");
		objLoadingLink.setAttribute('id','loadingLink');
		objLoadingLink.setAttribute('href','#');
		objLoadingLink.onclick = function() { myLightbox.end(); return false; }
		objLoading.appendChild(objLoadingLink);
	
		var objLoadingImage = document.createElement("img");
		objLoadingImage.setAttribute('src', fileLoadingImage);
		objLoadingLink.appendChild(objLoadingImage);

		var objImageDataContainer = document.createElement("div");
		objImageDataContainer.setAttribute('id','imageDataContainer');
		objLightbox.appendChild(objImageDataContainer);

		var objImageData = document.createElement("div");
		objImageData.setAttribute('id','imageData');
		objImageDataContainer.appendChild(objImageData);
	
		var objImageDetails = document.createElement("div");
		objImageDetails.setAttribute('id','imageDetails');
		objImageData.appendChild(objImageDetails);
	
		var objCaption = document.createElement("span");
		objCaption.setAttribute('id','caption');
		objImageDetails.appendChild(objCaption);
	
		var objNumberDisplay = document.createElement("span");
		objNumberDisplay.setAttribute('id','numberDisplay');
		objImageDetails.appendChild(objNumberDisplay);
		
		var objBottomNav = document.createElement("div");
		objBottomNav.setAttribute('id','bottomNav');
		objImageData.appendChild(objBottomNav);
	
		var objBottomNavCloseLink = document.createElement("a");
		objBottomNavCloseLink.setAttribute('id','bottomNavClose');
		objBottomNavCloseLink.setAttribute('href','#');
		objBottomNavCloseLink.onclick = function() { myLightbox.end(); return false; }
		objBottomNav.appendChild(objBottomNavCloseLink);
	
		var objBottomNavCloseImage = document.createElement("img");
		objBottomNavCloseImage.setAttribute('src', fileBottomNavCloseImage);
		objBottomNavCloseLink.appendChild(objBottomNavCloseImage);
	},


	//
	// updateImageList()
	// Loops through anchor tags looking for 'lightbox' references and applies onclick
	// events to appropriate links. You can rerun after dynamically adding images w/ajax.
	//
	updateImageList: function() {	
		if (!document.getElementsByTagName){ return; }
		var anchors = document.getElementsByTagName('a');
		var areas = document.getElementsByTagName('area');

		// loop through all anchor tags
		for (var i=0; i<anchors.length; i++){
			var anchor = anchors[i];
			
			var relAttribute = String(anchor.getAttribute('rel'));
			
			// use the string.match() method to catch 'lightbox' references in the rel attribute
			if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
				anchor.onclick = function () {myLightbox.start(this); return false;}
			}
		}

		// loop through all area tags
		// todo: combine anchor & area tag loops
		for (var i=0; i< areas.length; i++){
			var area = areas[i];
			
			var relAttribute = String(area.getAttribute('rel'));
			
			// use the string.match() method to catch 'lightbox' references in the rel attribute
			if (area.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
				area.onclick = function () {myLightbox.start(this); return false;}
			}
		}
	},
	
	
	//
	//	start()
	//	Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
	//
	start: function(imageLink) {	

		hideSelectBoxes();
		hideFlash();

		// stretch overlay to fill page and fade in
		var arrayPageSize = getPageSize();
		Element.setWidth('overlay', arrayPageSize[0]);
		Element.setHeight('overlay', arrayPageSize[1]);

		new Effect.Appear('overlay', { duration: overlayDuration, from: 0.0, to: overlayOpacity });

		imageArray = [];
		imageNum = 0;		

		if (!document.getElementsByTagName){ return; }
		var anchors = document.getElementsByTagName( imageLink.tagName);

		// if image is NOT part of a set..
		if((imageLink.getAttribute('rel') == 'lightbox')){
			// add single image to imageArray
			imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title')));			
		} else {
		// if image is part of a set..

			// loop through anchors, find other images in set, and add them to imageArray
			for (var i=0; i<anchors.length; i++){
				var anchor = anchors[i];
				if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){
					imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
				}
			}
			imageArray.removeDuplicates();
			while(imageArray[imageNum][0] != imageLink.getAttribute('href')) { imageNum++;}
		}

		// calculate top and left offset for the lightbox 
		var arrayPageScroll = getPageScroll();
		var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 10);
		var lightboxLeft = arrayPageScroll[0];
		Element.setTop('lightbox', lightboxTop);
		Element.setLeft('lightbox', lightboxLeft);
		
		Element.show('lightbox');
		
		this.changeImage(imageNum);
	},

	//
	//	changeImage()
	//	Hide most elements and preload image in preparation for resizing image container.
	//
	changeImage: function(imageNum) {	
		
		activeImage = imageNum;	// update global var

		// hide elements during transition
		if(animate){ Element.show('loading');}
		Element.hide('lightboxImage');
		Element.hide('hoverNav');
		Element.hide('prevLink');
		Element.hide('nextLink');
		Element.hide('imageDataContainer');
		Element.hide('numberDisplay');		
		
		imgPreloader = new Image();
		
		// once image is preloaded, resize image container
		imgPreloader.onload=function(){
			Element.setSrc('lightboxImage', imageArray[activeImage][0]);
			myLightbox.resizeImageContainer(imgPreloader.width, imgPreloader.height);
			
			imgPreloader.onload=function(){};	//	clear onLoad, IE behaves irratically with animated gifs otherwise 
		}
		imgPreloader.src = imageArray[activeImage][0];
	},

	//
	//	resizeImageContainer()
	//
	resizeImageContainer: function( imgWidth, imgHeight) {

		// get curren width and height
		this.widthCurrent = Element.getWidth('outerImageContainer');
		this.heightCurrent = Element.getHeight('outerImageContainer');

		// get new width and height
		var widthNew = (imgWidth  + (borderSize * 2));
		var heightNew = (imgHeight  + (borderSize * 2));

		// scalars based on change from old to new
		this.xScale = ( widthNew / this.widthCurrent) * 100;
		this.yScale = ( heightNew / this.heightCurrent) * 100;

		// calculate size difference between new and old image, and resize if necessary
		wDiff = this.widthCurrent - widthNew;
		hDiff = this.heightCurrent - heightNew;

		if(!( hDiff == 0)){ new Effect.Scale('outerImageContainer', this.yScale, {scaleX: false, duration: resizeDuration, queue: 'front'}); }
		if(!( wDiff == 0)){ new Effect.Scale('outerImageContainer', this.xScale, {scaleY: false, delay: resizeDuration, duration: resizeDuration}); }

		// if new and old image are same size and no scaling transition is necessary, 
		// do a quick pause to prevent image flicker.
		if((hDiff == 0) && (wDiff == 0)){
			if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);} 
		}

		Element.setHeight('prevLink', imgHeight);
		Element.setHeight('nextLink', imgHeight);
		Element.setWidth( 'imageDataContainer', widthNew);

		this.showImage();
	},
	
	//
	//	showImage()
	//	Display image and begin preloading neighbors.
	//
	showImage: function(){
		Element.hide('loading');
		new Effect.Appear('lightboxImage', { duration: resizeDuration, queue: 'end', afterFinish: function(){	myLightbox.updateDetails(); } });
		this.preloadNeighborImages();
	},

	//
	//	updateDetails()
	//	Display caption, image number, and bottom nav.
	//
	updateDetails: function() {
	
		// if caption is not null
		if(imageArray[activeImage][1]){
			Element.show('caption');
			Element.setInnerHTML( 'caption', imageArray[activeImage][1]);
		}
		
		// if image is part of set display 'Image x of x' 
		if(imageArray.length > 1){
			Element.show('numberDisplay');
			Element.setInnerHTML( 'numberDisplay', "Bild " + eval(activeImage + 1) + " von " + imageArray.length);
		}

		new Effect.Parallel(
			[ new Effect.SlideDown( 'imageDataContainer', { sync: true, duration: resizeDuration, from: 0.0, to: 1.0 }), 
			  new Effect.Appear('imageDataContainer', { sync: true, duration: resizeDuration }) ], 
			{ duration: resizeDuration, afterFinish: function() {
				// update overlay size and update nav
				var arrayPageSize = getPageSize();
				Element.setHeight('overlay', arrayPageSize[1]);
				myLightbox.updateNav();
				}
			} 
		);
	},

	//
	//	updateNav()
	//	Display appropriate previous and next hover navigation.
	//
	updateNav: function() {

		Element.show('hoverNav');				

		// if not first image in set, display prev image button
		if(activeImage != 0){
			Element.show('prevLink');
			document.getElementById('prevLink').onclick = function() {
				myLightbox.changeImage(activeImage - 1); return false;
			}
		}

		// if not last image in set, display next image button
		if(activeImage != (imageArray.length - 1)){
			Element.show('nextLink');
			document.getElementById('nextLink').onclick = function() {
				myLightbox.changeImage(activeImage + 1); return false;
			}
		}
		
		this.enableKeyboardNav();
	},

	//
	//	enableKeyboardNav()
	//
	enableKeyboardNav: function() {
		document.onkeydown = this.keyboardAction; 
	},

	//
	//	disableKeyboardNav()
	//
	disableKeyboardNav: function() {
		document.onkeydown = '';
	},

	//
	//	keyboardAction()
	//
	keyboardAction: function(e) {
		if (e == null) { // ie
			keycode = event.keyCode;
			escapeKey = 27;
		} else { // mozilla
			keycode = e.keyCode;
			escapeKey = e.DOM_VK_ESCAPE;
		}

		key = String.fromCharCode(keycode).toLowerCase();
		
		if((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)){	// close lightbox
			myLightbox.end();
		} else if((key == 'p') || (keycode == 37)){	// display previous image
			if(activeImage != 0){
				myLightbox.disableKeyboardNav();
				myLightbox.changeImage(activeImage - 1);
			}
		} else if((key == 'n') || (keycode == 39)){	// display next image
			if(activeImage != (imageArray.length - 1)){
				myLightbox.disableKeyboardNav();
				myLightbox.changeImage(activeImage + 1);
			}
		}

	},

	//
	//	preloadNeighborImages()
	//	Preload previous and next images.
	//
	preloadNeighborImages: function(){

		if((imageArray.length - 1) > activeImage){
			preloadNextImage = new Image();
			preloadNextImage.src = imageArray[activeImage + 1][0];
		}
		if(activeImage > 0){
			preloadPrevImage = new Image();
			preloadPrevImage.src = imageArray[activeImage - 1][0];
		}
	
	},

	//
	//	end()
	//
	end: function() {
		this.disableKeyboardNav();
		Element.hide('lightbox');
		new Effect.Fade('overlay', { duration: overlayDuration});
		showSelectBoxes();
		showFlash();
	}
}

// -----------------------------------------------------------------------------------

//
// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.com
//
function getPageScroll(){

	var xScroll, yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
		xScroll = self.pageXOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
		xScroll = document.documentElement.scrollLeft;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
		xScroll = document.body.scrollLeft;	
	}

	arrayPageScroll = new Array(xScroll,yScroll) 
	return arrayPageScroll;
}

// -----------------------------------------------------------------------------------

//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.com
// Edit for Firefox by pHaez
//
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = window.innerWidth + window.scrollMaxX;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	
//	console.log(self.innerWidth);
//	console.log(document.documentElement.clientWidth);

	if (self.innerHeight) {	// all except Explorer
		if(document.documentElement.clientWidth){
			windowWidth = document.documentElement.clientWidth; 
		} else {
			windowWidth = self.innerWidth;
		}
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

//	console.log("xScroll " + xScroll)
//	console.log("windowWidth " + windowWidth)

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = xScroll;		
	} else {
		pageWidth = windowWidth;
	}
//	console.log("pageWidth " + pageWidth)

	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}

// -----------------------------------------------------------------------------------

//
// getKey(key)
// Gets keycode. If 'x' is pressed then it hides the lightbox.
//
function getKey(e){
	if (e == null) { // ie
		keycode = event.keyCode;
	} else { // mozilla
		keycode = e.which;
	}
	key = String.fromCharCode(keycode).toLowerCase();
	
	if(key == 'x'){
	}
}

// -----------------------------------------------------------------------------------

//
// listenKey()
//
function listenKey () {	document.onkeypress = getKey; }
	
// ---------------------------------------------------

function showSelectBoxes(){
	var selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
}

// ---------------------------------------------------

function hideSelectBoxes(){
	var selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "hidden";
	}
}

// ---------------------------------------------------

function showFlash(){
	var flashObjects = document.getElementsByTagName("object");
	for (i = 0; i < flashObjects.length; i++) {
		flashObjects[i].style.visibility = "visible";
	}

	var flashEmbeds = document.getElementsByTagName("embed");
	for (i = 0; i < flashEmbeds.length; i++) {
		flashEmbeds[i].style.visibility = "visible";
	}
}

// ---------------------------------------------------

function hideFlash(){
	var flashObjects = document.getElementsByTagName("object");
	for (i = 0; i < flashObjects.length; i++) {
		flashObjects[i].style.visibility = "hidden";
	}

	var flashEmbeds = document.getElementsByTagName("embed");
	for (i = 0; i < flashEmbeds.length; i++) {
		flashEmbeds[i].style.visibility = "hidden";
	}

}


// ---------------------------------------------------

//
// pause(numberMillis)
// Pauses code execution for specified time. Uses busy code, not good.
// Help from Ran Bar-On [ran2103@gmail.com]
//

function pause(ms){
	var date = new Date();
	curDate = null;
	do{var curDate = new Date();}
	while( curDate - date < ms);
}
/*
function pause(numberMillis) {
	var curently = new Date().getTime() + sender;
	while (new Date().getTime();	
}
*/
// ---------------------------------------------------



function initLightbox() { myLightbox = new Lightbox(); }
Event.observe(window, 'load', initLightbox, false);





/* This notice must be untouched at all times.

wz_dragdrop.js	v. 4.88
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de

Copyright (c) 2002-2007 Walter Zorn. All rights reserved.
Created 26. 8. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 31. 1. 2007

This DHTML & Drag&Drop Library adds Drag&Drop functionality
to the following types of html-elements:
- images, even if not positioned via layers,
  nor via stylesheets or any other kind of "hard-coding"
- relatively and absolutely positioned layers (DIV elements).
Moreover, it provides extended DHTML abilities.

LICENSE: LGPL

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 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.

For more details on the GNU Lesser General Public License,
see http://www.gnu.org/copyleft/lesser.html
*/


// PATH TO THE TRANSPARENT 1*1 PX IMAGE (required by NS 4 as spacer)
var spacer = 'grafik/trans.gif';




//window.onerror = new Function('return true;');


// Optional commands passed to SET_DHTML() on the html-page (g: may be applied globally, i: individually)
var CLONE			= 'C10nE';   // i  img	  clone image
var COPY			= 'C0pY';	// i  img	  create copies
var DETACH_CHILDREN = 'd37aCH';  // i  lyr	  detach images
var HORIZONTAL		= 'H0r1Z';   // i  img,lyr  horizontally draggable only
var MAXHEIGHT		= 'm7x8I';   // i  img,lyr  maximum height limit, "
var MAXOFFBOTTOM	= 'm7xd0wN'; // i  img,lyr  downward offset limit
var MAXOFFLEFT		= 'm7x23Ft'; // i  img,lyr  leftward offset limit
var MAXOFFRIGHT		= 'm7x0Ff8'; // i  img,lyr  rightward offset limit
var MAXOFFTOP		= 'm7xu9';   // i  img,lyr  upward offset limit
var MAXWIDTH		= 'm7xW1';   // i  img,lyr  maximum width limit, use with resizable or scalable
var MINWIDTH		= 'm1nw1';   // i  img,lyr  minimum width limit, "
var MINHEIGHT		= 'm1n8I';   // i  img,lyr  minimum height limit, "
var NO_ALT			= 'no81T';   // gi img	  disable alt and title attributes
var NO_DRAG			= 'N0d4Ag';  // i  img,lyr  disable draggability
var RESET_Z			= 'r35E7z';  // gi img,lyr  reset z-index when dropped
var RESIZABLE		= 'r5IZbl';  // gi img,lyr  resizable if <ctrl> or <shift> pressed
var SCALABLE		= 'SCLbl';   // gi img,lyr  scalable		   "
var SCROLL			= 'sC8lL';   // gi img,lyr  enable auto scroll functionality
var TRANSPARENT		= 'dIApHAn'; // gi img,lyr  translucent while dragged
var VERTICAL		= 'V3Rt1C';  // i  img,lyr  vertically draggable only
var dd_cursors = new Array(
	'c:default',
	'c:crosshair',
	'c:e-resize',
	'c:hand',
	'c:help',
	'c:move',
	'c:n-resize',
	'c:ne-resize',
	'c:nw-resize',
	'c:s-resize',
	'c:se-resize',
	'c:sw-resize',
	'c:text',
	'c:w-resize',
	'c:wait'
);
for(var dd_i = dd_cursors.length; dd_i;)
{--dd_i;
	eval('var CURSOR_' + (dd_cursors[dd_i].substring(2).toUpperCase().replace('-', '_')) + ' = "' + dd_cursors[dd_i] + '";');
}
var dd_u = "undefined";
function WZDD()
{
	this.elements = new Array(0);
	this.obj = null;
	this.n = navigator.userAgent.toLowerCase();
	this.db = (document.compatMode && document.compatMode.toLowerCase() != "backcompat")?
		document.documentElement
		: (document.body || null);
	this.op = !!(window.opera && document.getElementById);
	if(this.op) document.onmousedown = new Function('e',
		'if(((e = e || window.event).target || e.srcElement).tagName == "IMAGE") return false;');
	this.ie = !!(this.n.indexOf("msie") >= 0 && document.all && this.db && !this.op);
	this.iemac = !!(this.ie && this.n.indexOf("mac") >= 0);
	this.ie4 = !!(this.ie && !document.getElementById);
	this.n4 = !!(document.layers && typeof document.classes != dd_u);
	this.n6 = !!(typeof window.getComputedStyle != dd_u && typeof document.createRange != dd_u);
	this.w3c = !!(!this.op && !this.ie && !this.n6 && document.getElementById);
	this.ce = !!(document.captureEvents && document.releaseEvents && !this.n6);
	this.px = this.n4? '' : 'px';
	this.tiv = this.w3c? 40 : 10;
}
var dd = new WZDD();

dd.Int = function(d_x, d_y)
{
	return isNaN(d_y = parseInt(d_x))? 0 : d_y;
};
dd.getWndW = function()
{
	return dd.Int(
		(dd.db && !dd.op && !dd.w3c && dd.db.clientWidth)? dd.db.clientWidth
		: (window.innerWidth || 0)
	);
};
dd.getWndH = function()
{
	return dd.Int(
		(dd.db && !dd.op && !dd.w3c && dd.db.clientHeight)? dd.db.clientHeight
		: (window.innerHeight || 0)
	);
};
dd.getScrollX = function()
{
	return dd.Int(window.pageXOffset || (dd.db? dd.db.scrollLeft : 0));
};
dd.getScrollY = function()
{
	return dd.Int(window.pageYOffset || (dd.db? dd.db.scrollTop : 0));
};
dd.getPageXY = function(d_o)
{
	if(dd.n4 && d_o)
	{
		dd.x = d_o.pageX || 0;
		dd.y = d_o.pageY || 0;
	}
	else
	{
		dd.x = dd.y = 0; //global helper vars
		while(d_o)
		{
			dd.x += dd.Int(d_o.offsetLeft);
			dd.y += dd.Int(d_o.offsetTop);
			d_o = d_o.offsetParent || null;
		}
	}
};
dd.getCssXY = function(d_o)
{
	if(d_o.div)
	{
		if(dd.n4)
		{
			d_o.cssx = d_o.div.x;
			d_o.cssy = d_o.div.y;
		}
		else if(dd.ie4)
		{
			d_o.cssx = d_o.css.pixelLeft;
			d_o.cssy = d_o.css.pixelTop;
		}
		else
		{
			d_o.css.left = d_o.css.top = 0 + dd.px;
			dd.getPageXY(d_o.div);
			d_o.cssx = d_o.x - dd.x;
			d_o.cssy = d_o.y - dd.y;
			d_o.css.left = d_o.cssx + dd.px;
			d_o.css.top = d_o.cssy + dd.px;
		}
	}
	else
	{
		d_o.cssx = 0;
		d_o.cssy = 0;
	}
};
dd.getImgW = function(d_o)
{
	return d_o? dd.Int(d_o.width) : 0;
};
dd.getImgH = function(d_o)
{
	return d_o? dd.Int(d_o.height) : 0;
};
dd.getDivW = function(d_o)
{
	return dd.Int(
		dd.n4? (d_o.div? d_o.div.clip.width : 0)
		: d_o.div? (d_o.div.offsetWidth || d_o.css.pixelWidth || d_o.css.width || 0)
		: 0
	);
};
dd.getDivH = function(d_o)
{
	return dd.Int(
		dd.n4? (d_o.div? d_o.div.clip.height : 0)
		: d_o.div? (d_o.div.offsetHeight || d_o.css.pixelHeight || d_o.css.height || 0)
		: 0
	);
};
dd.getWH = function(d_o)
{
	d_o.w = dd.getDivW(d_o);
	d_o.h = dd.getDivH(d_o);
	if(d_o.css)
	{
		d_o.css.width = d_o.w + dd.px;
		d_o.css.height = d_o.h + dd.px;
		d_o.dw = dd.getDivW(d_o)-d_o.w;
		d_o.dh = dd.getDivH(d_o)-d_o.h;
		d_o.css.width = (d_o.w-d_o.dw) + dd.px;
		d_o.css.height = (d_o.h-d_o.dh) + dd.px;
	}
	else d_o.dw = d_o.dh = 0;
};
dd.getCssProp = function(d_o, d_pn6, d_pstyle, d_pn4)
{
	if(d_o && dd.n6) return ''+window.getComputedStyle(d_o, null).getPropertyValue(d_pn6);
	if(d_o && d_o.currentStyle) return ''+eval('d_o.currentStyle.'+d_pstyle);
	if(d_o && d_o.style) return ''+eval('d_o.style.'+d_pstyle);
	if(d_o && dd.n4) return ''+eval('d_o.'+d_pn4);
	return '';
};
dd.getDiv = function(d_x, d_d)
{
	d_d = d_d || document;
	if(dd.n4)
	{
		if(d_d.layers[d_x]) return d_d.layers[d_x];
		for(var d_i = d_d.layers.length; d_i;)
		{
			var d_y = dd.getDiv(d_x, d_d.layers[--d_i].document);
			if(d_y) return d_y;
		}
	}
	if(dd.ie) return d_d.all[d_x] || null;
	if(d_d.getElementById) return d_d.getElementById(d_x) || null;
	return null;
};
dd.getImg = function(d_o, d_nm, d_xy, d_w)
{
	d_w = d_w || window;
	var d_img;
	if(document.images && (d_img = d_w.document.images[d_nm]))
	{
		if(d_xy)
		{
			if(dd.n4)
			{
				dd.getPageXY(d_w);
				d_o.defx = d_img.x + dd.x;
				d_o.defy = d_img.y + dd.y;
			}
			else
			{
				dd.getPageXY(d_img);
				d_o.defx = dd.x;
				d_o.defy = dd.y;
			}
		}
		return d_img;
	}
	if(dd.n4) for(var d_i = d_w.document.layers.length; d_i;)
	{
		var d_y = dd.getImg(d_o, d_nm, d_xy, d_w.document.layers[--d_i]);
		if(d_y) return d_y;
	}
	return null;
};
dd.getParent = function(d_o, d_p)
{
	if(dd.n4)
	{
		for(var d_i = dd.elements.length; d_i;)
		{
			if(!((d_p = dd.elements[--d_i]).is_image) && d_p.div && (d_p.div.document.layers[d_o.name] || d_o.oimg && d_p.div.document.images[d_o.oimg.name]))
				d_p.addChild(d_o, d_p.detach, 1);
		}
	}
	else
	{
		d_p = d_o.is_image? dd.getImg(d_o, d_o.oimg.name) : (d_o.div || null);
		while(d_p && !!(d_p = d_p.offsetParent || d_p.parentNode || null))
		{
			if(d_p.ddObj)
			{
				d_p.ddObj.addChild(d_o, d_p.ddObj.detach, 1);
				break;
			}
		}
	}
};
dd.getCmd = function(d_o, d_cmd, d_cmdStr)
{
	var d_i = d_o.id.indexOf(d_cmd), d_j,
	d_y = (d_i >= 0)*1;
	if(d_y)
	{
		d_j = d_i+d_cmd.length;
		if(d_cmdStr) d_o.cmd += d_o.id.substring(d_i, d_j);
		d_o.id = d_o.id.substring(0, d_i) + d_o.id.substring(d_j);
	}
	return d_y;
};
dd.getCmdVal = function(d_o, d_cmd, d_cmdStr, int0)
{
	var d_i = d_o.id.indexOf(d_cmd), d_j,
	d_y = (d_o.id.indexOf(d_cmd) >= 0)? dd.Int(d_o.id.substring(d_o.id.indexOf(d_cmd)+d_cmd.length)) : int0? -1 : 0;
	if(!int0 && d_y || int0 && d_y >= 0)
	{
		d_j = d_i+d_cmd.length+(""+d_y).length;
		if(d_cmdStr) d_o.cmd += d_o.id.substring(d_i, d_j);
		d_o.id = d_o.id.substring(0, d_i) + d_o.id.substring(d_j);
	}
	return d_y;
};
dd.addElt = function(d_o, d_p)
{
	dd.elements[d_o.name] = dd.elements[d_o.index = dd.elements.length] = d_o;
	if(d_p) d_p.copies[d_o.name] = d_p.copies[d_p.copies.length] = d_o;
};
dd.mkWzDom = function()
{
	var d_o, d_l = dd.elements.length, d_i;
	for(d_i = d_l; d_i;) dd.getParent(dd.elements[--d_i]);
	for(d_i = d_l; d_i;)
	{
		if((d_o = dd.elements[--d_i]).children && !d_o.parent)
		{
			for(var d_j = d_o.children.length; d_j;)
			{--d_j;
				d_o.children[d_j].setZ(d_o.z+d_o.children[d_j].z, 1);
			}
		}
	}
};
dd.addProps = function(d_o)
{
	if(d_o.is_image)
	{
		d_o.div = dd.getDiv(d_o.id);
		d_o.css = (d_o.div && typeof d_o.div.style != dd_u)? d_o.div.style : null;
		d_o.nimg = (dd.n4 && d_o.div)? d_o.div.document.images[0] : (document.images[d_o.id+"NI1m6G"] || null);
		if(!d_o.noalt && !dd.noalt && d_o.nimg && d_o.oimg)
		{
			d_o.nimg.alt = d_o.oimg.alt || '';
			if(d_o.oimg.title) d_o.nimg.title = d_o.oimg.title;
		}
		d_o.bgColor = '';
	}
	else
	{
		d_o.bgColor = dd.getCssProp(d_o.div, 'background-color','backgroundColor','bgColor').toLowerCase();
		if(dd.n6 && d_o.div)
		{
			var d_c = d_o.bgColor.toLowerCase();
			if(d_c.indexOf('rgb') >= 0)
			{
				d_c = d_c.substring(4, d_c.length-1).split(',');
				d_o.bgColor = '#';
				for(var d_l = d_c.length, d_i = 0; d_i < d_l; d_i++) d_o.bgColor += parseInt(d_c[d_i]).toString(0x10);
			}
			else d_o.bgColor = d_c;
		}
	}
	if(dd.scalable) d_o.scalable = d_o.resizable^1;
	else if(dd.resizable) d_o.resizable = d_o.scalable^1;
	d_o.setZ(d_o.defz);
	d_o.cursor = d_o.cursor || dd.cursor || 'auto';
	d_o._setCrs(d_o.nodrag? 'auto' : d_o.cursor);
	d_o.diaphan = d_o.diaphan || dd.diaphan || 0;
	d_o.opacity = 1.0;
	d_o.visible = true;
};
dd.initz = function()
{
	if(!(dd && (dd.n4 || dd.n6 || dd.ie || dd.op || dd.w3c))) return;
	else if(dd.n6 || dd.ie || dd.op || dd.w3c) dd.recalc(1);
	var d_drag = (document.onmousemove == DRAG),
	d_resize = (document.onmousemove == RESIZE);
	if(dd.loadFunc) dd.loadFunc();
	if(d_drag) dd.setMovHdl(DRAG);
	else if(d_resize) dd.setMovHdl(RESIZE);
	if(d_drag || d_resize) dd.setUpHdl(DROP);
	dd.setDwnHdl(PICK);
};
dd.finlz = function()
{
	if(dd.ie && dd.elements)
	{
		for(var d_i = dd.elements.length; d_i;)
			dd.elements[--d_i].del();
	}
	if(dd.uloadFunc) dd.uloadFunc();
};
dd.setCe = function(d_e, d_fnc)
{
	d_fnc? document.captureEvents(d_e) : document.releaseEvents(d_e);
};
dd.setDwnHdl = function(d_x)
{
	if(document.onmousedown != d_x)
	{
		dd.downFunc = document.onmousedown;
		document.onmousedown = d_x;
		if(dd.ce) dd.setCe(Event.MOUSEDOWN, d_x);
	}
};
dd.setMovHdl = function(d_x)
{
	if(document.onmousemove != d_x)
	{
		dd.moveFunc = document.onmousemove;
		document.onmousemove = d_x;
		if(dd.ce) dd.setCe(Event.MOUSEMOVE, d_x);
	}
};
dd.setUpHdl = function(d_x)
{
	if(document.onmouseup != d_x)
	{
		dd.upFunc = document.onmouseup;
		document.onmouseup = d_x;
		if(dd.ce) dd.setCe(Event.MOUSEUP, d_x);
	}
};
dd.evt = function(d_e)
{
	this.but = (this.e = d_e || window.event).which || this.e.button || 0;
	this.button = (this.e.type == 'mousedown')? this.but
		: (dd.e && dd.e.button)? dd.e.button
		: 0;
	this.src = this.e.target || this.e.srcElement || null;
	this.src.tag = ("" + (this.src.tagName || this.src)).toLowerCase();
	this.x = dd.Int(this.e.pageX || this.e.clientX || 0);
	this.y = dd.Int(this.e.pageY || this.e.clientY || 0);
	if(dd.ie)
	{
		this.x += dd.getScrollX() - (dd.ie && !dd.iemac)*1;
		this.y += dd.getScrollY() - (dd.ie && !dd.iemac)*1;
	}
	this.modifKey = this.e.modifiers? this.e.modifiers&Event.SHIFT_MASK : (this.e.shiftKey || false);
};
dd.getEventTarget = function(d_e, d_s, d_n)
{
	d_e = d_e || window.event;
	if(d_e && (d_s = d_e.target || d_e.srcElement || null) != null)
	{
		if(null != (d_n = d_s.id || d_s.name || null))
		{
			if(d_n.indexOf("dIi15vNI1m6G") == d_n.length-12)
				return dd.elements[d_n.substring(0, d_n.length-12)] || null;
			if(d_n.indexOf("dIi15v") == d_n.length-6)
				return dd.elements[d_n.substring(0, d_n.length-6)] || null;
			return dd.elements[d_n] || null;
		}
	}
	return null;
};
dd.recalc = function(d_x)
{
	for(var d_o, d_i = dd.elements.length; d_i;)
	{
		if(!(d_o = dd.elements[--d_i]).is_image && d_o.div)
		{
			dd.getWH(d_o);
			if(d_o.div.pos_rel)
			{
				dd.getPageXY(d_o.div);
				var d_dx = dd.x - d_o.x, d_dy = dd.y - d_o.y;
				d_o.defx += d_dx;
				d_o.x += d_dx;
				d_o.defy += d_dy;
				d_o.y += d_dy;
				for(var d_p, d_j = d_o.children.length; d_j;)
				{
					if(!(d_p = d_o.children[--d_j]).detached && (d_o != d_p.defparent || !(d_p.is_image && dd.getImg(d_p, d_p.oimg.name, 1))))
					{
						d_p.defx += d_dx;
						d_p.defy += d_dy;
						d_p.moveBy(d_dx, d_dy);
					}
				}
			}
		}
		else if(d_o.is_image && !dd.n4)
		{
			if(dd.n6 && d_x && !d_o.defw) d_o.resizeTo(d_o.defw = dd.getImgW(d_o.oimg), d_o.defh = dd.getImgH(d_o.oimg));
			var d_defx = d_o.defx, d_defy = d_o.defy;
			if(!(d_o.parent && d_o.parent != d_o.defparent) && (d_x || !d_o.detached || d_o.horizontal || d_o.vertical) && dd.getImg(d_o, d_o.oimg.name, 1))
				d_o.moveBy(d_o.defx-d_defx, d_o.defy-d_defy);
		}
	}
};
function WINSZ(d_x)
{
	if(d_x)
	{
		if(dd.n4)
		{
			dd.iW = innerWidth;
			dd.iH = innerHeight;
		}
		window.onresize = new Function('WINSZ();');
	}
	else if(dd.n4 && (innerWidth != dd.iW || innerHeight != dd.iH)) location.reload();
	else if(!dd.n4) setTimeout('dd.recalc()', 0xa);
}
WINSZ(1);

function DDObj(d_o, d_i)
{
	this.id = d_o;
	this.cmd = '';
	this.cpy_n = dd.getCmdVal(this, COPY);
	this.maxoffb = dd.getCmdVal(this, MAXOFFBOTTOM, 0, 1);
	this.maxoffl = dd.getCmdVal(this, MAXOFFLEFT, 0, 1);
	this.maxoffr = dd.getCmdVal(this, MAXOFFRIGHT, 0, 1);
	this.maxofft = dd.getCmdVal(this, MAXOFFTOP, 0, 1);
	var d_j = dd_cursors.length; while(d_j--)
		if(dd.getCmd(this, dd_cursors[d_j], 1)) this.cursor = dd_cursors[d_j].substring(2);
	this.clone = dd.getCmd(this, CLONE, 1);
	this.detach = dd.getCmd(this, DETACH_CHILDREN);
	this.scalable = dd.getCmd(this, SCALABLE, 1);
	this.horizontal = dd.getCmd(this, HORIZONTAL);
	this.noalt = dd.getCmd(this, NO_ALT, 1);
	this.nodrag = dd.getCmd(this, NO_DRAG);
	this.scroll = dd.getCmd(this, SCROLL, 1);
	this.resizable = dd.getCmd(this, RESIZABLE, 1);
	this.re_z = dd.getCmd(this, RESET_Z, 1);
	this.diaphan = dd.getCmd(this, TRANSPARENT, 1);
	this.vertical = dd.getCmd(this, VERTICAL);
	this.maxw = dd.getCmdVal(this, MAXWIDTH, 1, 1);
	this.minw = Math.abs(dd.getCmdVal(this, MINWIDTH, 1, 1));
	this.maxh = dd.getCmdVal(this, MAXHEIGHT, 1, 1);
	this.minh = Math.abs(dd.getCmdVal(this, MINHEIGHT, 1, 1));
	this.pickFunc = this.dragFunc = this.resizeFunc = this.dropFunc = null;

	this.name = this.id + (d_i || '');
	this.oimg = dd.getImg(this, this.id, 1);
	this.is_image = !!this.oimg;
	this.copies = new Array();
	this.children = new Array();
	this.parent = this.original = null;
	if(this.oimg)
	{
		this.id = this.name + "dIi15v";
		this.w = dd.getImgW(this.oimg);
		this.h = dd.getImgH(this.oimg);
		this.dw = this.dh = 0;
		this.defz = dd.Int(dd.getCssProp(this.oimg, 'z-index','zIndex','zIndex')) || 1;
		this.defsrc = this.src = this.oimg.src;
		this.htm = '<img name="' + this.id + 'NI1m6G"'+
			' src="' + this.oimg.src + '" '+
			'width="' + this.w + '" height="' + this.h + '">';
		this.t_htm = '<div id="' + this.id +
			'" style="position:absolute;'+
			'left:' + (this.cssx = this.x = this.defx) + 'px;'+
			'top:' + (this.cssy = this.y = this.defy) + 'px;'+
			'width:' + this.w + 'px;'+
			'height:' + this.h + 'px;">'+
			this.htm + '</div>';
	}
	else
	{
		if(!!(this.div = dd.getDiv(this.id)) && typeof this.div.style != dd_u) this.css = this.div.style;
		dd.getWH(this);
		if(this.div)
		{
			this.div.ddObj = this;
			this.div.pos_rel = ("" + (this.div.parentNode? this.div.parentNode.tagName : this.div.parentElement? this.div.parentElement.tagName : '').toLowerCase().indexOf('body') < 0);
		}
		dd.getPageXY(this.div);
		this.defx = this.x = dd.x;
		this.defy = this.y = dd.y;
		dd.getCssXY(this);
		this.defz = dd.Int(dd.getCssProp(this.div, 'z-index','zIndex','zIndex'));
	}
	this.defw = this.w || 0;
	this.defh = this.h || 0;
}
DDObj.prototype.setPickFunc = function(d_x)
{
	this.pickFunc = d_x;
};
DDObj.prototype.setDragFunc = function(d_x)
{
	this.dragFunc = d_x;
};
DDObj.prototype.setResizeFunc = function(d_x)
{
	this.resizeFunc = d_x;
};
DDObj.prototype.setDropFunc = function(d_x)
{
	this.dropFunc = d_x;
};
DDObj.prototype.moveBy = function(d_x, d_y, d_kds, d_o)
{
	if(!this.div) return;
	this.x += (d_x = dd.Int(d_x));
	this.y += (d_y = dd.Int(d_y));
	if(!d_kds || this.is_image || this.parent != this.defparent)
	{
		(d_o = this.css || this.div).left = (this.cssx += d_x) + dd.px;
		d_o.top = (this.cssy += d_y) + dd.px;
	}
	for(var d_i = this.children.length; d_i;)
	{
		if(!(d_o = this.children[--d_i]).detached) d_o.moveBy(d_x, d_y, 1);
		d_o.defx += d_x;
		d_o.defy += d_y;
	}
};

DDObj.prototype.moveTo = function(d_x, d_y)
{
	this.moveBy(dd.Int(d_x)-this.x, dd.Int(d_y)-this.y);
};
DDObj.prototype.hide = function(d_m, d_o, d_p)
{
	if(this.div && this.visible)
	{
		d_p = this.css || this.div;
		if(d_m && !dd.n4)
		{
			this.display = dd.getCssProp(this.div, "display", "display", "display");
			if(this.oimg)
			{
				this.oimg.display = dd.getCssProp(this.oimg, "display", "display", "display");
				this.oimg.style.display = "none";
			}
			d_p.display = "none";
			dd.recalc();
		}
		else d_p.visibility = "hidden";
	}
	this.visible = false;
	for(var d_i = this.children.length; d_i;)
		if(!(d_o = this.children[--d_i]).detached) d_o.hide(d_m);
};
DDObj.prototype.show = function(d_o, d_p)
{
	if(this.div)
	{
		d_p = this.css || this.div;
		if(d_p.display && d_p.display == "none")
		{
			d_p.display = this.display || "block";
			if(this.oimg) this.oimg.style.display = this.oimg.display || "inline";
			dd.recalc();
		}
		else d_p.visibility = "visible";
	}
	this.visible = true;
	for(var d_i = this.children.length; d_i;)
		if(!(d_o = this.children[--d_i]).detached) d_o.show();
};
DDObj.prototype.resizeTo = function(d_w, d_h, d_o)
{
	if(!this.div) return;
	d_w = (this.w = dd.Int(d_w))-this.dw;
	d_h = (this.h = dd.Int(d_h))-this.dh;
	if(dd.n4)
	{
		this.div.resizeTo(d_w, d_h);
		if(this.is_image)
		{
			this.write('<img src="' + this.src + '" width="' + d_w + '" height="' + d_h + '">');
			(this.nimg = this.div.document.images[0]).src = this.src;
		}
	}
	else if(typeof this.css.pixelWidth != dd_u)
	{
		this.css.pixelWidth = d_w;
		this.css.pixelHeight = d_h;
		if(this.is_image)
		{
			(d_o = this.nimg.style).pixelWidth = d_w;
			d_o.pixelHeight = d_h;
		}
	}
	else
	{
		this.css.width = d_w + dd.px;
		this.css.height = d_h + dd.px;
		if(this.is_image)
		{
			(d_o = this.nimg).width = d_w;
			d_o.height = d_h;
			if(!d_o.complete) d_o.src = this.src;
		}
	}
};
DDObj.prototype.resizeBy = function(d_dw, d_dh)
{
	this.resizeTo(this.w+dd.Int(d_dw), this.h+dd.Int(d_dh));
};
DDObj.prototype.swapImage = function(d_x, d_cp)
{
	if(!this.nimg) return;
	this.nimg.src = d_x;
	this.src = this.nimg.src;
	if(d_cp)
	{
		for(var d_i = this.copies.length; d_i;)
		{--d_i;
			this.copies[d_i].src = this.copies[d_i].nimg.src = this.nimg.src;
		}
	}
};
DDObj.prototype.setBgColor = function(d_x)
{
	if(dd.n4 && this.div) this.div.bgColor = d_x;
	else if(this.css) this.css.background = d_x;
	this.bgColor = d_x;
};
DDObj.prototype.write = function(d_x, d_o)
{
	this.text = d_x;
	if(!this.div) return;
	if(dd.n4)
	{
		(d_o = this.div.document).open();
		d_o.write(d_x);
		d_o.close();
		dd.getWH(this);
	}
	else
	{
		this.css.height = 'auto';
		this.div.innerHTML = d_x;
		if(!dd.ie4) dd.recalc();
		if(dd.ie4 || dd.n6) setTimeout('dd.recalc();', 0); // n6.0: recalc twice
	}
};
DDObj.prototype.copy = function(d_n, d_p, d_b)
{
	if(!this.oimg) return;
	d_b = (dd.ie && document.all.tags('body'))? document.all.tags('body')[0] : document.getElementsByTagName? (document.getElementsByTagName('body')[0] || dd.db) : dd.db;
	for(d_n = d_n || 1; d_n > 0; --d_n)
	{
		var d_l = this.copies.length,
		d_o = new DDObj(this.name+this.cmd, d_l+1);
		if(dd.n4)
		{
			d_o.id = (d_p = new Layer(d_o.w)).name;
			d_p.clip.height = d_o.h;
			d_p.visibility = 'show';
			(d_p = d_p.document).open();
			d_p.write(d_o.htm);
			d_p.close();
		}
		else if(d_b && d_b.insertAdjacentHTML) d_b.insertAdjacentHTML("AfterBegin", d_o.t_htm);
		else if(document.createElement && d_b && d_b.appendChild)
		{
			d_b.appendChild(d_p = document.createElement("dIi15v"));
			d_p.innerHTML = d_o.htm;
			d_p.id = d_o.id;
			d_p.style.position = 'absolute';
			d_p.style.width = d_o.w + 'px';
			d_p.style.height = d_o.h + 'px';
		}
		else if(d_b && d_b.innerHTML) d_b.innerHTML += d_o.t_htm;
		d_o.defz = this.defz+1+d_l;
		dd.addProps(d_o);
		d_o.original = this;
		dd.addElt(d_o, this);
		if(this.parent)
		{
			this.parent.addChild(d_o, this.detached);
			d_o.defparent = this.defparent;
		}
		d_o.moveTo(d_o.defx = this.defx, d_o.defy = this.defy);
		if(dd.n4) d_o.defsrc = d_o.src = this.defsrc;
		d_o.swapImage(this.src);
	}
};
DDObj.prototype.addChild = function(d_kd, detach, defp)
{
	if(typeof d_kd != "object") d_kd = dd.elements[d_kd];
	if(d_kd.parent && d_kd.parent == this || d_kd == this || !d_kd.is_image && d_kd.defparent && !defp) return;

	this.children[this.children.length] = this.children[d_kd.name] = d_kd;
	d_kd.detached = detach || 0;
	if(defp) d_kd.defparent = this;
	else if(this == d_kd.defparent && d_kd.is_image) dd.getImg(this, d_kd.oimg.name, 1);
	if(!d_kd.defparent || this != d_kd.defparent)
	{
		d_kd.defx = d_kd.x;
		d_kd.defy = d_kd.y;
	}
	if(!detach)
	{
		d_kd.defz = d_kd.defz+this.defz-(d_kd.parent? d_kd.parent.defz : 0)+(!d_kd.is_image*1);
		d_kd.setZ(d_kd.z+this.z-(d_kd.parent? d_kd.parent.z : 0)+(!d_kd.is_image*1), 1);
	}
	if(d_kd.parent) d_kd.parent._removeChild(d_kd, 1);
	d_kd.parent = this;
};
DDObj.prototype._removeChild = function(d_kd, d_newp)
{
	if(typeof d_kd != "object") d_kd = this.children[d_kd];
	var d_oc = this.children, d_nc = new Array();
	for(var d_i = 0; d_i < d_oc.length; d_i++)
		if(d_oc[d_i] != d_kd) d_nc[d_nc.length] = d_oc[d_i];
	this.children = d_nc;
	d_kd.parent = null;
	if(!d_newp)
	{
		d_kd.detached = d_kd.defp = 0;
		if(d_kd.is_image) dd.getImg(d_kd, d_kd.oimg.name, 1);
	}
};
DDObj.prototype.attachChild = function(d_kd)
{
	(d_kd = (typeof d_kd != "object")? this.children[d_kd]: d_kd).detached = 0;
	d_kd.setZ(d_kd.defz + this.z-this.defz, 1);
};
DDObj.prototype.detachChild = function(d_kd)
{
	(d_kd = (typeof d_kd != "object")? this.children[d_kd]: d_kd).detached = 1;
};
DDObj.prototype.setZ = function(d_x, d_kds, d_o)
{
	if(d_kds)
	{
		for(var d_dz = d_x-this.z, d_i = this.children.length; d_i;)
			if(!(d_o = this.children[--d_i]).detached) d_o.setZ(d_o.z+d_dz, 1);
	}
	dd.z = Math.max(dd.z, this.z = this.div? ((this.css || this.div).zIndex = d_x) : 0);
};
DDObj.prototype.maximizeZ = function()
{
	this.setZ(dd.z+1, 1);
};
DDObj.prototype._resetZ = function(d_o)
{
	if(this.re_z || dd.re_z)
	{
		this.setZ(this.defz);
		for(var d_i = this.children.length; d_i;)
			if(!(d_o = this.children[--d_i]).detached) d_o.setZ(d_o.defz);
	}
};
DDObj.prototype.setOpacity = function(d_x)
{
	this.opacity = d_x;
	this._setOpaRel(1.0, 1);
};
DDObj.prototype._setOpaRel = function(d_x, d_kd, d_y, d_o)
{
	if(this.css && (this.diaphan || d_kd))
	{
		d_y = this.opacity*d_x;
		if(typeof this.css.MozOpacity != dd_u) this.css.MozOpacity = d_y;
		else if(typeof this.css.filter != dd_u)
			this.css.filter = "Alpha(opacity="+parseInt(100*d_y)+")";
		else this.css.opacity = d_y;
		for(var d_i = this.children.length; d_i;)
			if(!(d_o = this.children[--d_i]).detached) d_o._setOpaRel(d_x, 1);
	}
};
DDObj.prototype.setCursor = function(d_x)
{
	this._setCrs(this.cursor = (d_x.indexOf('c:')+1)? d_x.substring(2) : d_x);
};
DDObj.prototype._setCrs = function(d_x)
{
	if(this.css) this.css.cursor = ((!dd.ie || dd.iemac) && d_x == 'hand')? 'pointer' : d_x;
};
DDObj.prototype.setDraggable = function(d_x)
{
	this.nodrag = !d_x*1;
	this._setCrs(d_x? this.cursor : 'auto');
};
DDObj.prototype.setResizable = function(d_x)
{
	this.resizable = d_x*1;
	if(d_x) this.scalable = 0;
};
DDObj.prototype.setScalable = function(d_x)
{
	this.scalable = d_x*1;
	if(d_x) this.resizable = 0;
};
DDObj.prototype.setHorizontal = function(d_x)
{
	this.horizontal = d_x*1;
};
DDObj.prototype.setVertical = function(d_x)
{
	this.vertical = d_x*1;
};
DDObj.prototype.getEltBelow = function(d_ret, d_x, d_y)
{
	var d_o, d_cmp = -1, d_i = dd.elements.length; while(d_i--)
	{
		d_o = dd.elements[d_i];
		d_x = d_o.x-this.w/2;
		d_y = d_o.y-this.h/2;
		if(d_o.visible && d_o.z < this.z && this.x >= d_x && this.x <= d_x+d_o.w && this.y >= d_y && this.y <= d_y+d_o.h)
		{
			if(d_o.z > d_cmp)
			{
				d_cmp = d_o.z;
				d_ret = d_o;
			}
		}
	}
	return d_ret;
};
DDObj.prototype.del = function(d_os, d_o)
{
	var d_i, d_l;
	if(this.parent && this.parent._removeChild) this.parent._removeChild(this);
	if(this.original)
	{
		this.hide();
		if(this.original.copies)
		{
			d_os = new Array();
			for(d_l = this.original.copies.length, d_i = 0; d_i < d_l; d_i++)
				if((d_o = this.original.copies[d_i]) != this) d_os[d_o.name] = d_os[d_os.length] = d_o;
			this.original.copies = d_os;
		}
	}
	else if(this.is_image)
	{
		this.hide();
		if(this.oimg)
		{
		  if(dd.n4) this.oimg.src = this.defsrc;
		  else this.oimg.style.visibility = 'visible';
		}
	}
	else if(this.moveTo)
	{
		if(this.css) this.css.cursor = 'default';
		this.moveTo(this.defx, this.defy);
		this.resizeTo(this.defw, this.defh);
	}
	d_os = new Array();
	for(d_l = dd.elements.length, d_i = 0; d_i < d_l; d_i++)
	{
		if((d_o = dd.elements[d_i]) != this) d_os[d_o.name] = d_os[d_o.index = d_os.length] = d_o;
		else d_o._free();
	}
	dd.elements = d_os;
	if(!dd.n4) dd.recalc();
};
DDObj.prototype._free = function()
{
	for(var d_i in this)
		this[d_i] = null;
	dd.elements[this.name] = null;
};
dd.n4RectVis = function(vis)
{
	for(var d_i = 4; d_i;)
	{--d_i;
		dd.rectI[d_i].visibility = dd.rectA[d_i].visibility = vis? 'show' : 'hide';
		if(vis) dd.rectI[d_i].zIndex = dd.rectA[d_i].zIndex = dd.z+2;
	}
};
dd.n4RectPos = function(d_o, d_x, d_y, d_w, d_h)
{
	d_o.x = d_x;
	d_o.y = d_y;
	d_o.clip.width = d_w;
	d_o.clip.height = d_h;
};
// NN4: Draw img sizing rect
dd.n4Rect = function(d_w, d_h)
{
	var d_i;
	if(!dd.rectI)
	{
		dd.rectI = new Array();
		dd.rectA = new Array();
	}
	if(!dd.rectI[0])
	{
		for(d_i = 4; d_i;)
		{
			(dd.rectI[--d_i] = new Layer(1)).bgColor = '#000000';
			(dd.rectA[d_i] = new Layer(1)).bgColor = '#ffffff';
		}
	}
	if(!dd.rectI[0].visibility || dd.rectI[0].visibility == 'hide') dd.n4RectVis(1);
	dd.obj.w = d_w;
	dd.obj.h = d_h;
	for(d_i = 4; d_i;)
	{--d_i;
		dd.n4RectPos(dd.rectI[d_i], dd.obj.x + (!(d_i-1)? (dd.obj.w-1) : 0), dd.obj.y + (!(d_i-2)? (dd.obj.h-1) : 0), d_i&1 || dd.obj.w, !(d_i&1) || dd.obj.h);
		dd.n4RectPos(dd.rectA[d_i], !(d_i-1)? dd.rectI[1].x+1 : (dd.obj.x-1), !(d_i-2)? dd.rectI[2].y+1 : (dd.obj.y-1), d_i&1 || dd.obj.w+2, !(d_i&1) || dd.obj.h+2);
	}
};
dd.reszTo = function(d_w, d_h)
{
	if(dd.n4 && dd.obj.is_image) dd.n4Rect(d_w, d_h);
	else dd.obj.resizeTo(d_w, d_h);
};
dd.embedVis = function(d_vis)
{
	var d_o = new Array('iframe', 'applet', 'embed', 'object');
	for(var d_i = d_o.length; d_i;)
	{--d_i;
		var d_p = dd.ie? document.all.tags(d_o[d_i]) : document.getElementsByTagName? document.getElementsByTagName(d_o[d_i]) : null;
		if(d_p)
		{
			for(var d_j = d_p.length; d_j;)
			{
				var d_q = d_p[--d_j];
				while(d_q.offsetParent || d_q.parentNode)
				{
					if((d_q = d_q.parentNode || d_q.offsetParent || null) == dd.obj.div)
					{
						d_p[d_j].style.visibility = d_vis;
						break;
					}
				}
			}
		}
	}
};

dd.maxOffX = function(d_x, d_y)
{
	return(
		(dd.obj.maxoffl+1 && (d_y = dd.obj.defx-dd.obj.maxoffl)-d_x > 0
		|| dd.obj.maxoffr+1 && (d_y = dd.obj.defx+dd.obj.maxoffr)-d_x < 0)? d_y
		: d_x
	);
};
dd.maxOffY = function(d_x, d_y)
{
	return(
		(dd.obj.maxofft+1 && (d_y = dd.obj.defy-dd.obj.maxofft)-d_x > 0
		|| dd.obj.maxoffb+1 && (d_y = dd.obj.defy+dd.obj.maxoffb)-d_x < 0)? d_y
		: d_x
	);
};
dd.inWndW = function(d_x, d_y)
{
	var d_wx = dd.getScrollX(),
	d_ww = dd.getWndW();
	return(
		((d_y = d_wx+2)-d_x > 0) || ((d_y = d_wx+d_ww+dd.obj.w-2)-d_x < 0)? d_y
		: d_x
	);
};
dd.inWndH = function(d_x, d_y)
{
	var d_wy = dd.getScrollY(),
	d_wh = dd.getWndH();
	return(
		((d_y = d_wy+2)-d_x > 0) || ((d_y = d_wy+d_wh+dd.obj.h-2)-d_x < 0)? d_y
		: d_x
	);
};
// These two funcs limit the size of element when mouseresized.
// Implemented 22.5.2003 by Gregor Ltolf, modified by Walter Zorn
dd.limW = function(d_w)
{
	return(
		(dd.obj.minw-d_w > 0)? dd.obj.minw
		: (dd.obj.maxw > 0 && dd.obj.maxw-d_w < 0)? dd.obj.maxw
		: d_w
	);
};
dd.limH = function(d_h)
{
	return(
		(dd.obj.minh-d_h > 0)? dd.obj.minh
		: (dd.obj.maxh > 0 && dd.obj.maxh-d_h < 0)? dd.obj.maxh
		: d_h
	);
};
// Optional autoscroll-page functionality. Courtesy Cedric Savarese.
// Modified by Walter Zorn.
function DDScroll()
{
	if(!dd.obj || !dd.obj.scroll && !dd.scroll || dd.ie4 || dd.whratio)
	{
		dd.scrx = dd.scry = 0;
		return;
	}
	var d_bnd = 0x1c,
	d_wx = dd.getScrollX(), d_wy = dd.getScrollY();
	if(dd.msmoved)
	{
		var d_ww = dd.getWndW(), d_wh = dd.getWndH(), d_y;
		dd.scrx = ((d_y = dd.e.x-d_ww-d_wx+d_bnd) > 0)? (d_y>>=2)*d_y
			: ((d_y = d_wx+d_bnd-dd.e.x) > 0)? -(d_y>>=2)*d_y
			: 0;
		dd.scry = ((d_y = dd.e.y-d_wh-d_wy+d_bnd) > 0)? (d_y>>=2)*d_y
			: ((d_y = d_wy+d_bnd-dd.e.y) > 0)? -(d_y>>=2)*d_y
			: 0;
	}
	if(dd.scrx || dd.scry)
	{
		window.scrollTo(
			d_wx + (dd.scrx = dd.obj.is_resized? dd.limW(dd.obj.w+dd.scrx)-dd.obj.w : dd.obj.vertical? 0 : (dd.maxOffX(dd.obj.x+dd.scrx)-dd.obj.x)),
			d_wy + (dd.scry = dd.obj.is_resized? dd.limH(dd.obj.h+dd.scry)-dd.obj.h : dd.obj.horizontal? 0 : (dd.maxOffY(dd.obj.y+dd.scry)-dd.obj.y))
		);
		dd.obj.is_dragged? dd.obj.moveTo(dd.obj.x+dd.getScrollX()-d_wx, dd.obj.y+dd.getScrollY()-d_wy)
			: dd.reszTo(dd.obj.w+dd.getScrollX()-d_wx, dd.obj.h+dd.getScrollY()-d_wy);
	}
	dd.msmoved = 0;
	window.setTimeout('DDScroll()', 0x33);
}
function PICK(d_ev)
{
	dd.e = new dd.evt(d_ev);
	if(dd.e.x >= dd.getWndW()+dd.getScrollX() || dd.e.y >= dd.getWndH()+dd.getScrollY()) return true; // on scrollbar
	for(var d_o, d_t, d_cmp = -1, d_i = dd.elements.length; d_i;)
	{
		d_o = dd.elements[--d_i];
		if(dd.n4 && dd.e.but > 1 && dd.e.src == d_o.oimg && !d_o.clone) return false;
		if(d_o.visible && dd.e.but <= 1 && dd.e.x >= d_o.x && dd.e.x <= d_o.x+d_o.w && dd.e.y >= d_o.y && dd.e.y <= d_o.y+d_o.h)
		{
			if(d_o.z > d_cmp && (d_t = dd.e.src.tag).indexOf('inpu') < 0 && d_t.indexOf('texta') < 0 && d_t.indexOf('sele') < 0 && d_t.indexOf('opti') < 0 && d_t.indexOf('scrol') < 0)
			{
				d_cmp = d_o.z;
				dd.obj = d_o;
			}
		}
	}
	if(dd.obj)
	{
		if(dd.obj.nodrag) dd.obj = null;
		else
		{
			dd.e.e.cancelBubble = true;
			var d_rsz = dd.e.modifKey && (dd.obj.resizable || dd.obj.scalable);
			if(dd.op)
			{
				(d_o = document.getElementById('OpBlUr')).style.pixelLeft = dd.e.x;
				d_o.style.pixelTop = dd.e.y;
				(d_o = d_o.children[0].children[0]).focus();
				d_o.blur();
			}
			else if(dd.ie && !dd.ie4)
			{
				if(document.selection && document.selection.empty) document.selection.empty();
				dd.db.onselectstart = function()
				{
					event.returnValue = false;
				};
			}
			if(d_rsz)
			{
				dd.obj._setCrs('se-resize');
				dd.obj.is_resized = 1;
				dd.whratio = dd.obj.scalable? dd.obj.defw/dd.obj.defh : 0;
				if(dd.ie)
				{
					if(dd.ie4)
					{
						window.dd_x = dd.getScrollX();
						window.dd_y = dd.getScrollY();
					}
					setTimeout(
						'if(dd.obj && document.selection && document.selection.empty)'+
						'{'+
							'document.selection.empty();'+
							'if(dd.ie4) window.scrollTo(window.dd_x, window.dd_y);'+
						'}'
					,0);
				}
				dd.setMovHdl(RESIZE);
				dd.reszTo(dd.obj.w, dd.obj.h);
			}
			else
			{
				dd.obj.is_dragged = 1;
				dd.setMovHdl(DRAG);
			}
			dd.setUpHdl(DROP);
			dd.embedVis('hidden');
			dd.obj._setOpaRel(0.7);
			dd.obj.maximizeZ();
			dd.ofx = dd.obj.x+dd.obj.w-dd.e.x;
			dd.ofy = dd.obj.y+dd.obj.h-dd.e.y;
			if(window.my_PickFunc) my_PickFunc();
			if(dd.obj.pickFunc) dd.obj.pickFunc();
			DDScroll();
			return !(
				dd.obj.is_resized
				|| dd.n4 && dd.obj.is_image
				|| dd.n6 || dd.w3c
			);
		}
	}
	if(dd.downFunc) return dd.downFunc(d_ev);
	return true;
}
function DRAG(d_ev)
{
	if(!dd.obj || !dd.obj.visible) return true;
	if(dd.ie4 || dd.w3c || dd.n6 || dd.obj.children.length > 0xf)
	{
		if(dd.wait) return false;
		dd.wait = 1;
		setTimeout('dd.wait = 0;', dd.tiv);
	}
	dd.e = new dd.evt(d_ev);
	if(dd.ie && !dd.e.but)
	{
		DROP(d_ev);
		return true;
	}
	dd.msmoved = 1;
	dd.obj.moveTo(
		dd.obj.vertical? dd.obj.x : dd.maxOffX(dd.inWndW(dd.ofx+dd.e.x)-dd.obj.w),
		dd.obj.horizontal? dd.obj.y : dd.maxOffY(dd.inWndH(dd.ofy+dd.e.y)-dd.obj.h)
	);

	if(window.my_DragFunc) my_DragFunc();
	if(dd.obj.dragFunc) dd.obj.dragFunc();
	if(dd.moveFunc) return dd.moveFunc(d_ev);
	return false;
}
function RESIZE(d_ev)
{
	if(!dd.obj || !dd.obj.visible) return true;
	if(dd.wait) return false;
	dd.wait = 1;
	setTimeout('dd.wait = 0;', dd.tiv);
	dd.e = new dd.evt(d_ev);
	if(dd.ie && !dd.e.but)
	{
		DROP(d_ev);
		return true;
	}
	dd.msmoved = 1;
	var d_w = dd.limW(dd.inWndW(dd.ofx+dd.e.x)-dd.obj.x), d_h;
	if(!dd.whratio) d_h = dd.limH(dd.inWndH(dd.ofy+dd.e.y)-dd.obj.y);
	else
	{
		d_h = dd.limH(dd.inWndH(Math.round(d_w/dd.whratio)+dd.obj.y)-dd.obj.y);
		d_w = Math.round(d_h*dd.whratio);
	}
	dd.reszTo(d_w, d_h);
	if(window.my_ResizeFunc) my_ResizeFunc();
	if(dd.obj.resizeFunc) dd.obj.resizeFunc();
	if(dd.moveFunc) return dd.moveFunc(d_ev);
	return false;
}
function DROP(d_ev)
{
	if(dd.obj)
	{
		if(dd.obj.is_dragged)
		{
			if(!dd.obj.is_image) dd.getWH(dd.obj);
		}
		else if(dd.n4)
		{
			if(dd.obj.is_image)
			{
				dd.n4RectVis(0);
				dd.obj.resizeTo(dd.obj.w, dd.obj.h);
			}
		}
		if(!dd.n4 || !dd.obj.is_image) dd.recalc();
		dd.setMovHdl(dd.moveFunc);
		dd.setUpHdl(dd.upFunc);
		if(dd.db) dd.db.onselectstart = null;
		dd.obj._setOpaRel(1.0);
		dd.obj._setCrs(dd.obj.cursor);
		dd.embedVis('visible');
		dd.obj._resetZ();
		dd.e = new dd.evt(d_ev);
		if(window.my_DropFunc) my_DropFunc();
		if(dd.obj.dropFunc) dd.obj.dropFunc();
		dd.msmoved = dd.obj.is_dragged = dd.obj.is_resized = dd.whratio = 0;
		dd.obj = null;
	}
	dd.setDwnHdl(PICK);
}
function SET_DHTML()
{
	var d_a = arguments, d_ai, d_htm = '', d_o, d_i = d_a.length;
	while(d_i)
	{
		if(!(d_ai = d_a[--d_i]).indexOf('c:')) dd.cursor = d_ai.substring(2);
		else if(d_ai == NO_ALT) dd.noalt = 1;
		else if(d_ai == SCROLL) dd.scroll = 1;
		else if(d_ai == RESET_Z) dd.re_z = 1;
		else if(d_ai == RESIZABLE) dd.resizable = 1;
		else if(d_ai == SCALABLE) dd.scalable = 1;
		else if(d_ai == TRANSPARENT) dd.diaphan = 1;
		else
		{
			d_o = new DDObj(d_ai);
			dd.addElt(d_o);
			d_htm += d_o.t_htm || '';
			if(d_o.oimg && d_o.cpy_n)
			{
				for(var d_l = d_o.cpy_n, d_j = 0; d_j < d_l;)
				{
					var d_p = new DDObj(d_o.name+d_o.cmd, ++d_j);
					dd.addElt(d_p, d_o);
					d_p.defz = d_o.defz+d_j;
					d_p.original = d_o;
					d_htm += d_p.t_htm;
				}
			}
		}
	}
	if (dd.n4 || dd.n6 || dd.ie || dd.op || dd.w3c) document.write(
		(dd.n4? '<div style="position:absolute;"><\/div>\n'
		: (dd.op && !dd.op6)? '<div id="OpBlUr" style="position:absolute;visibility:hidden;width:0px;height:0px;"><form><input type="text" style="width:0px;height:0px;"><\/form><\/div>'
		: '') + d_htm
	);
	dd.z = 0x33;
	for(d_i = dd.elements.length; d_i;)
	{
		dd.addProps(d_o = dd.elements[--d_i]);
		if(d_o.is_image && !d_o.original && !d_o.clone)
			dd.n4? d_o.oimg.src = spacer : d_o.oimg.style.visibility = 'hidden';
	}
	dd.mkWzDom();
	if(window.onload) dd.loadFunc = window.onload;
	if(window.onunload) dd.uloadFunc = window.onunload;
	window.onload = dd.initz;
	window.onunload = dd.finlz;
	dd.setDwnHdl(PICK);
}
function ADD_DHTML() // layers only!
{
	var d_a = arguments, d_o, d_i = d_a.length; while(d_i)
	{
		d_o = new DDObj(d_a[--d_i]);
		dd.addElt(d_o);
		dd.addProps(d_o);
	}
	dd.mkWzDom();
}




////////////////////////////////////////////////////////////
// If not needed, all code below this line may be removed


// For backward compatibility
dd.d = document;			// < v. 2.72
var RESET_ZINDEX = RESET_Z; // < 3.44
var KEYDOWN_RESIZE = RESIZABLE; // < 4.43
var CURSOR_POINTER = CURSOR_HAND; // < 4.44
var NO_SCROLL = '';		 // < v. 4.49




////////////////////////////////////////////////////////////
// FUNCTIONS FOR EXTENDED SCRIPTING
// Use these for your own extensions,
// or to call functions defined elsewhere



/* my_PickFunc IS AUTOMATICALLY CALLED WHEN AN ITEM STARTS TO BE DRAGGED.
The following objects/properties are accessible from here:

- dd.e: current mouse event
- dd.e.property: access to a property of the current mouse event.
  Mostly requested properties:
  - dd.e.x: document-related x co-ordinate
  - dd.e.y: document-related y co-ord
  - dd.e.src: target of mouse event (not identical with the drag drop object itself).
  - dd.e.button: currently pressed mouse button. Left button: dd.e.button <= 1

- dd.obj: reference to currently dragged item.
- dd.obj.property: access to any property of that item.
- dd.obj.method(): for example dd.obj.resizeTo() or dd.obj.swapImage() .
  Mostly requested properties:
	- dd.obj.name: image name or layer ID passed to SET_DHTML();
	- dd.obj.x and dd.obj.y: co-ordinates;
	- dd.obj.w and dd.obj.h: size;
	- dd.obj.is_dragged: 1 while item is dragged, else 0;
	- dd.obj.is_resized: 1 while item is resized, i.e. if <ctrl> or <shift> is pressed, else 0

For more properties and details, visit the API documentation
at http://www.walterzorn.com/dragdrop/api_e.htm (english) or
http://www.walterzorn.de/dragdrop/api.htm (german)	*/
function my_PickFunc()
{
}




/* my_DragFunc IS CALLED WHILE AN ITEM IS DRAGGED
See the description of my_PickFunc above for what's accessible from here. */
function my_DragFunc()
{
	//window.status = 'dd.elements.' + dd.obj.name + '.x  = ' + dd.obj.x + '	 dd.elements.' + dd.obj.name + '.y = ' + dd.obj.y;
}




/* my_ResizeFunc IS CALLED WHILE AN ITEM IS RESIZED
See the description of my_PickFunc above for what's accessible from here. */
function my_ResizeFunc()
{
	//window.status = 'dd.elements.' + dd.obj.name + '.w  = ' + dd.obj.w + '	 dd.elements.' + dd.obj.name + '.h = ' + dd.obj.h;
}




/* THIS ONE IS CALLED ONCE AN ITEM IS DROPPED
See the description of my_PickFunc for what's accessible from here.
Here may be investigated, for example, what's the name (dd.obj.name)
of the dropped item, and where (dd.obj.x, dd.obj.y) it has been dropped... */
function my_DropFunc()
{
}
