function JSON(Daten)
  {
  function Escape(Daten)
    {
    function ZuHex(Daten)
      {
      // Wert als Zahl behandeln
      var Ausgabe = Number(Daten);
      
      // Zahl in Hex umwandeln
      Ausgabe = Ausgabe.toString(16);
      
      // auffüllen der Hex-Wertes
      while (Ausgabe.length < 4) Ausgabe = "0" + Ausgabe;
      
      // zurückgeben des vierstelligen Hex-Wertes
      return Ausgabe.toLowerCase();
      }
    
    // ersetzen aller Escapesequenzen
    var Ausgabe = "";
    for (var Index = 0; Index < Daten.length; Index++)
      {
      // prüfen ob das Zeichen als UNICODE ausgegeben werden muss
      if ((Daten.charCodeAt(Index) < 32) || (Daten.charCodeAt(Index) > 127)) Ausgabe += "\\u" + ZuHex(Daten.charCodeAt(Index));
      else if ((Daten.charAt(Index) == "\\") || (Daten.charAt(Index) == "\"")) Ausgabe += "\\" + Daten.charAt(Index);
      else Ausgabe += Daten.charAt(Index);
      }
      
    // zurückgeben der Zeichenkette
    return Ausgabe;
    }
  
  // je nach Datentyp die Darstellung als JSON ausgeben
  switch (typeof Daten)
    {
    case "boolean"   : return (Daten) ? "true" : "false"; break;
    case "string"    : return "\"" + Escape(Daten) + "\""; break;
    case "number"    : return Daten; break;
    case "function"  : return "[function]"; break;
    case "undefined" : return "[undefined]"; break;
    case "object"    :
      {
      // prüfen ob ein Null-Wert vorliegt
      if (Daten == null) return "null";
      else if (Daten.join)
        {
        // einleiten der Zeichenkette
        var Ausgabe = "[";
        
        // ermitteln aller Werte
        for (var Index = 0; Index < Daten.length; Index++) Ausgabe += JSON(Daten[Index]) + ", ";
          
        // zurückgeben der kompletten Zeichenkette
        return Ausgabe.substr(0, Ausgabe.length - 2) + "]";
        }
      else
        {
        // einleiten der Zeichenkette
        var Ausgabe = "{";
        
        // ermitteln aller Werte
        for (Feld in Daten) Ausgabe += "\"" + Escape(Feld) + "\" : " + JSON(Daten[Feld]) + ", ";
          
        // zurückgeben der kompletten Zeichenkette
        return Ausgabe.substr(0, Ausgabe.length - 2) + "}";
        }
        
      // CASE beenden
      break;
      }
    default          : return "[unknown]"; break;
    }
  }
  
function ZeigeFehler(Code, Daten)
  {
  // ausgeben der Fehlermeldung
  alert("Fehler: #" + Code + " (Unterfehler: #" + Daten.code + ")\r\nMeldung: " + Daten.message + "\r\n\r\nDump: " + JSON(Daten));
  }

function SetzeEigenschaften(Element, Eigenschaften)
  {
  // prüfen ob Eigenschaften angegeben sind, wenn ja diese setzen
  if (((typeof Eigenschaften) == "object") && (Eigenschaften != null)) for (Eigenschaft in Eigenschaften)
    { 
    // prüfen ob die Eigenschaft eine Einheit benötigt
    if (parseInt(Eigenschaften[Eigenschaft]) == Eigenschaften[Eigenschaft]) switch (Eigenschaft)
      {
      case "height" :
      case "width"  : Eigenschaften[Eigenschaft] += "px"; break;
      }
    
    // setzen der Eigenschaft
    Element[Eigenschaft] = Eigenschaften[Eigenschaft];
    }
  }
  
function SetzeCSS(Element, CSS)
  {
  // prüfen ob Stylesheets angegeben sind, wenn ja diese setzen
  if (((typeof CSS) == "object") && (CSS != null)) for (Eigenschaft in CSS)
    {
    // prüfen ob die CSS-Eigenschaft eine Einheit benötigt
    if (parseInt(CSS[Eigenschaft]) == CSS[Eigenschaft]) switch (Eigenschaft)
      {
      case "height" :
      case "left"   :
      case "top"    :
      case "width"  : CSS[Eigenschaft] += "px"; break;
      }
    
    // prüfen ob Transparenz gesetzt werden soll oder normaler Wert
    if (Eigenschaft == "opacity")
      {
      // prüfen welcher Grad der Transparenz gesetzt werden sol
      if (CSS[Eigenschaft] >= 1)
        {
        // Transparenz auf keine setzen
        Element.style.opacity = 1;
        Element.style.filter = null;
        }
      else
        {
        // Transparenz setzen
        Element.style.opacity = CSS[Eigenschaft];
        Element.style.filter = "Alpha(opacity=" + Math.floor(CSS[Eigenschaft] * 100) + ")";
        }
      }
    else Element.style[Eigenschaft] = CSS[Eigenschaft];
    }
  }
  
function ErzeugeElement(Tag, Vater, Eigenschaften, CSS)
  {
  // erzeugen des neuen Elements
  var Element = document.createElement(Tag);

  // setzen der Eigenschaften des Elements
  SetzeEigenschaften(Element, Eigenschaften);
  
  // setzen des CSS des Elements
  SetzeCSS(Element, CSS);
  
  // zuweisen eines Elternelements
  if (Vater == null) document.getElementsByTagName("body")[0].appendChild(Element);
  else Vater.appendChild(Element);
  
  // zurückgeben des Elements
  return Element;
  }
  
function LeereElement(Element, Schutz)
  {
  // ermitteln des Body-Elements
  if (Element == null) Element = document.getElementsByTagName("body")[0];
  
  // ermitteln aller zu schützenden Elemente
  if (Schutz != null) for (var Index = 0; Index < Schutz.length; Index++)
    {
    // ermitteln des Elements
    var SchutzElement = document.getElementById(Schutz[Index]);
    
    // prüfen ob das Element gefunden wurde
    if (((typeof SchutzElement) == "undefined") || (SchutzElement.parentNode != Element)) Schutz[Index] = null;
    else Schutz[Index] = SchutzElement;
    }
    
  // leeren des Elementes
  while (Element.firstChild != null) Element.removeChild(Element.firstChild);
  
  // wiederherstellen der zu schützenden Elemente
  if (Schutz != null) for (var Index = 0; Index < Schutz.length; Index++) if (Schutz[Index] != null) Element.appendChild(Schutz[Index]);
  }
  
function SetzeTextElement(Element, Text)
  {
  // leeren des Elementes
  LeereElement(Element, null);
  
  // ermitteln der Textzeilen
  var Zeilen = (Text.indexOf("\r\n") == -1) ? [Text] : Text.split("\r\n");
  
  // hinzufügen der Textzeilen
  for (var Index = 0; Index < Zeilen.length ; Index++)
    {
    // hinzufügen der Textzeile
    Element.appendChild(document.createTextNode(Zeilen[Index]));
    
    // hinzufügen des Zeilenumbruchs, wenn eine weitere Zeile folgt
    if (Index < Zeilen.length - 1) ErzeugeElement("br", Element, null, null);
    }
  
  // zurückgeben der eingefügten Zeilen
  return Zeilen.length;
  }