/*
 * <copyright>
 *  Copyright (c) 2001 by Hyperwave AG
 * </copyright>
 *
 * <file>
 *  Name:        ojs.js
 *  Created:     2001-01-14
 *  Description: This library defines a set of functions which
 *               support a kind of "object javascript" and
 *               class loading.
 *  $Id: ojs1.js,v 1.1.1.1 2005/05/13 09:56:39 wlackner Exp $
 * </file>
 */

/**
 * The following functions form the environment of a kind of
 * Object JavaScript.
 *
 * DEPRECATED:
 *  Note that this library is still maintained but deprecated.
 *  Use the newer "clientlib" library (.../clientlib/ojs/Object.js)
 *  instead.
 */

//--------------------------------------------------------------------
/**
 * This function must be used to create instances of classes which are
 * not native in JavaScript (unlike Function, Object, Array,...).
 * Main point in using it over using the usual new keyword is that the
 * Netscape built in JavaScript engine of HIS 5.1.1 (and earlier) has
 * some troubles with creating the right prototype chain for instances
 * of self defined classes. This behavior is corected using this
 * function.  Nevertheless it should as well be used on the client
 * side because
 * <UL>
 *  <LI>later Netscape browsers might as well have troubles as
 *      described</LI>
 *  <LI>of beeing as consistent as possible on client and server
 *      side </LI>
 *  <LI>this provides a kind of hook where the new-function could
 *      be extended later on (eg. dynamic class loading)</LI>
 *</UL>
 *
 * @param Function: aClass: the constructor function of the class to
 *   instantiate.
 */
function newInstanceOf ( aClass )
{
  // check if something is handed over ...
  if ( typeof (aClass) == "undefined" )
  {
    // an exception should be thrown, but to use the function on
    // client and server side, returns only null
    return null;
  }
  // ... and if this something might be a constructor function of a
  // class
  if ( typeof (aClass) != "function" )
  {
    // an exception should be thrown, but to use the function on
    // client and server side, returns only null
    return null;
  }

  // create a new instance of the wished class using the new keyword
  // CAUTION: only 5 parameters are allowed in a constructor!
  var myObj;
  switch ( arguments.length - 1 )
  {
  case 0:
    myObj = new aClass ();
    break;
  case 1:
    myObj = new aClass ( arguments[1] );
    break;
  case 2:
    myObj = new aClass ( arguments[1], arguments[2] );
    break;
  case 3:
    myObj = new aClass ( arguments[1], arguments[2], arguments[3] );
    break;
  case 4:
    myObj = new aClass ( arguments[1], arguments[2], arguments[3],
                         arguments[4] );
    break;
  case 5:
    myObj = new aClass ( arguments[1], arguments[2], arguments[3],
                         arguments[4], arguments[5] );
    break;
  default:
    return null;
  }

  // due to a failure of the JavaScript engine in HIS 5.1.1, the
  // prototype chain is not build up correctly. this statement repairs
  // the chain using the Netscape internal __proto__.  Can be done on
  // clientside as well, since in all Netscape versions until now the
  // if condition never equals true and in IE the __proto__ keyword
  // has no meaning. If the condition equals true in later Netscape
  // browsers, the correction has to be done anyway.
  if ( myObj.__proto__ != aClass.prototype )
     myObj.__proto__ = aClass.prototype;

  return myObj;
}

//--------------------------------------------------------------------
/**
 * This function implements ECMA conform inheritance for JavaScript
 * classes.  This inheritance covers all topics concerning
 * prototyping, such as:
 * <UL>
 *   <LI>enables access to prototyped members of the baseClass</LI>
 *   <LI>adds a static_ object holding all static properties and
 *       methods to the derivedClass. Takes also care about retrieving
 *       static members of the baseClass by accessing it using the
 *       derived Class.</LI>
 *  <LI>adds a handle to the baseClass (super_) to enable access to
 *      eventually overridden baseClassfunctions.</LI>
 * </UL>
 *
 * @param Function: derivedClass: the constructor function of the
 *   class to derive
 * @param Function: baseClass: the constructor function of the base class
 * @dependency newInstanceOf
 */
function doInherit ( derivedClass, baseClass )
{
  // Inheritance ... ?
  if ( baseClass != null )
  {
    // ECMA Inheritance, nothing JavaScript specific used.
    // call the constructor with "__proto__" to give it a
    // chance to differ between calls for instantiation and
    // calls for inheritance (this one)
    derivedClass.prototype = newInstanceOf( baseClass, "__proto__" );

    // "Repair" constructor (a JavaScript internally used property)
    derivedClass.prototype.constructor = derivedClass;

    // Linking back the Super Class:
    derivedClass.super_ = baseClass.prototype;
  }

  // Static part: always assign a default static_ object to a new class
  var static_constructor = new Function ( "" );

  // Inherit the new static <b>OBJECT</b> from the
  // Baseclasses' static object (if existent).
  if ( baseClass != null && baseClass.static_ != null )
    static_constructor.prototype = baseClass.static_;

  // Now construct the Static object (with the inheritance
  // defined above) and link it both to the derived class
  // AND to the prototype of this class!
  derivedClass.static_ =
  derivedClass.prototype.static_ = newInstanceOf (static_constructor);

  return derivedClass.prototype;
}

//--------------------------------------------------------------------
/**
 * Initializes a <code>package</code> within the current scope.
 * The scope depends on the current environment e.g. the
 * browser JavaScript engine etc. This function has to be
 * called before each class definition.
 * @param aPackageName: String: a string defining a package
 *   name with sub-packages e.g. "com.hw.util".
 */
function initPackage ( aPackageName )
{
  var packages = aPackageName.split ( "." );
  var root_pkg_name = packages [0];
  var cur_package;

  if ( eval ( "typeof " + root_pkg_name ) == "undefined" )
    eval ( root_pkg_name + "={};" );

  cur_package = eval ( root_pkg_name );

  for ( var i = 1; i < packages.length; ++i )
  {
    if ( cur_package [ packages [i] ] == null )
      cur_package [ packages [i] ] = {};
    cur_package = cur_package [ packages [i] ];
  }
}
initPackage ( "_gCLInfo_" );

//--------------------------------------------------------------------
/**
 * Loads a class or a package into the current scope. The reaction
 * depends on the given environment.
 * <UL>
 *   <LI><I>Browsers.</I>Here the script of the class is loaded
 *     via a normal script tag. Packages will be supported by
 *     giving wildcards.
 *   <LI><I>Waveslave.</I>Here the classes are loaded into the
 *     current scope.
 * </UL>
 *
 * @param aClassName: String: a string defining a class name
 *   or even a whole package.
 */
function loadClass ( aClassName )
{
  if ( !loadClass.debug_ )
    return;

  alert ( "loadClass(check): " + aClassName );
  var class_loaded = eval ( "typeof " + aClassName + " != 'undefined'" );
  if ( class_loaded )
    return;
  alert ( "loadClass(static): " +
	  aClassName +
	  ": Error - Class dependencies will possibly not be handled correct!" );
}

loadClass.basePath_ = "/wavemaster.internal/v6.3/lib/base/v1.x/";
loadClass.error_ = null;
loadClass.debug_ = false;

//--------------------------------------------------------------------
//                   HAF Compatibility Library
//--------------------------------------------------------------------
// The following functions are used to extend the default behavior
// of the JavaScript Engine. These are mostly encoders and decoders
// for UTF8 and escaped UTF8.

// IMPORTANT:
// Note that these functions are to be synched in ojs.js, ojs1.js
// and within the Clientlib (Object.js).

// Global variable that is true if lambda expressions are
// supoorted.


//--------------------------------------------------------------------
/**
 * Checks whether Lamda expressions are supported or not.
 * @return boolean: true if lambda expressions are supported.
 */
function lambdaExpressionsSupported ()
{
  if ( lambdaExpressionsSupported.supported_ )
    return lambdaExpressionsSupported.supported_;

  lambdaExpressionsSupported.supported_ =
    (" ".replace ( " ", function () { return "x" } ) == "x" );

  return lambdaExpressionsSupported.supported_;
}

//--------------------------------------------------------------------
/**
 * Encodes a character string (that exists of UCS2 characters) to
 * a character string that is UTF8 encoded. The characters of the
 * source string are transcoded to their one, two or three "byte"
 * representation in UTF8. As a consequence the final string contains
 * only characters with codes between 0 and 255.<p>
 *
 * For example: the German umlaut &ouml; (small "o" with quotes) has
 *   the UCS2 (Unicode) character code 246. Constructing a string
 *   with this character can be done by
 *     <code>String.fromCharCode (246)</code>.
 *   If this string is converted with this function this character
 *   is transcoded to its 2-byte representation in UTF-8 (195, 182).
 *   The resulting string will contain 2 characters with the character
 *   codes above.
 *
 * This implementation uses two strategies:
 * <ul>
 *   <li>For IS6.2 and lower it uses JavaScript Lambda Expressions to get
 *     better performance for long strings (in comparision to normal
 *     string operations).
 *   <li>For DANTE+ the built in method "fromEncoding" (C++) is used
 *     to get another boost (approx. 30 times faster).
 * </ul>
 *
 * @param theText: string: The text that has to be transcoded to
 *   UTF8.
 * @return string: the converted string.
 */
if ( !lambdaExpressionsSupported () )
{
  encodeUtf8 = function ( theText )
  {
    var utf = [];
    var j = 0;
    for ( var n = 0; n < theText.length; ++n )
    {
      // ermitteln des Unicodes des aktuellen Zeichens
      var c = theText.charCodeAt(n);
      // alle Zeichen von 0-127 => 1byte
      if (c < 128)
        utf [utf.length] = String.fromCharCode(c);
      // alle Zeichen von 127 bis 2047 => 2byte
      else if (c < 2048)
      {
        utf [utf.length] = String.fromCharCode((c >> 6) | 192)
                        + String.fromCharCode((c & 63) | 128);
      }
      // alle Zeichen von 2048 bis 66536 => 3byte
      else
      {
        utf [utf.length] = String.fromCharCode((c >> 12) | 224)
                        + String.fromCharCode(((c >> 6) & 63) | 128)
                        + String.fromCharCode((c & 63) | 128);
      }
    }
    return utf.join ("");
  }
  }
else
{
  encodeUtf8 = function ( theText )
  {
    return theText.replace ( /(.)|(\s)/g, encodeUtf8.lambdaEncode );
  }

  // Internal Lambda Funtion for encodeUTF8. This Lambda function
  // matches any character and translates the character to one
  // two or three byte representations concerning to the UTF8
  // algorithm. Note that this function must be kept in sync
  // with the regular expression of the caller.
  encodeUtf8.lambdaEncode = function ( c1 )
  {
    var c = c1.charCodeAt(0);

    // alle Zeichen von 0-127 => 1byte
    if (c < 128)
      return c1;

    // alle Zeichen von 127 bis 2047 => 2byte
    if (c < 2048)
      return ( String.fromCharCode((c >> 6) | 192)
               + String.fromCharCode((c & 63) | 128) );

    // alle Zeichen von 2048 bis 66536 => 3byte
    return ( String.fromCharCode((c >> 12) | 224)
             + String.fromCharCode(((c >> 6) & 63) | 128)
             + String.fromCharCode((c & 63) | 128) );
  }
}

//--------------------------------------------------------------------
/**
 * Checks whether a string is UTF8 encoded or not. This is done
 * with a Regular Expression that matches UTF8-patterns.The following
 * constraints have to be fulfilled:
 *
 * <ul>
 *   <li>The string has to contain only characters with codes between 0 and
 *     255.
 *   <li>The patterns must be conform to the UTF8 encoding for UCS2. This
 *     means that only 1, 2 or 3 Byte representations are allowed.
 * </ul>
 *
 * @param theText: string: The text that has to be checked.
 * @return boolean: true if the text is a UTF-8 text.
 */
function testUtf8 ( theText )
{
  pattern =
    /([\x00-\x7F])|([\xC0-\xDF][\x80-\xBF])|([\xE0-\xEF][\x80-\xBF][\x80-\xBF])/g;
  var res = theText.replace ( pattern, "" );
  return res.length == 0;
}

//--------------------------------------------------------------------
/**
 * Decodes an UTF-8 encoded string into the internal JavaScript
 * (UCS-2) representation. It forms the inverse function of
 * <code>encodeUtf8</code>.
 *
 * This implementation uses either lambda expressions or simple
 * array operations.
 *
 * @param theText: string: a text that should be decoded from
 *   UTF-8 representation back to "JavaScript".
 * @return string: the decoded string. Note that the
 *   original text will be returned if the text is not a "real"
 *   UTF-8 string.
 */
if ( !lambdaExpressionsSupported () )
{
  decodeUtf8 = function ( theText )
  {
    var plaintext = [];
    var i = 0;
    var c = c1 = c2 = 0;

    while ( i < theText.length )
    {
      c = theText.charCodeAt(i);
      if (c < 128)
      {
        plaintext [plaintext.length] = String.fromCharCode(c);
        ++i;
      }
      else if ((c > 191) && (c < 224))
      {
        c2 = theText.charCodeAt(i + 1);
        if ( c2 >= 0x80 && c2 <= 0xBF  )
        {
          plaintext [plaintext.length] =
            String.fromCharCode(((c & 31) << 6) | (c2 & 63));
          i += 2;
        }
        else
          return theText;
      }
      else
      {
        c2 = theText.charCodeAt(i + 1);
        c3 = theText.charCodeAt(i + 2);
        if ( c2 >= 0x80 && c2 <= 0xBF && c3 >= 0x80 && c3 <= 0xBF )
        {
          plaintext [plaintext.length] =
            String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
          i += 3;
        }
        else
          return theText;
      }
    }
    return plaintext.join ("");
  }
}
else
{
  decodeUtf8 = function (theText)
  {
    if ( !testUtf8 ( theText ) )
      return theText;
    pattern = /([\xC0-\xDF][\x80-\xBF])|([\xE0-\xEF][\x80-\xBF][\x80-\xBF])/g;

    return theText.replace ( pattern, decodeUtf8.lambdaDecode );
  }

  // Internal lambda function that matches the two byte or three
  // byte sequences and constructs the original character.
  // The parameters of these function depend on the regular expression
  // of the decodeUtf8 function.

  decodeUtf8.lambdaDecode = function ( whole, two, three )
  {
    if ( two )
    {
      c = two.charCodeAt (0);
      c2 = two.charCodeAt(1);
      return String.fromCharCode(((c & 31) << 6) | (c2 & 63));
    }

    if ( three )
    {
      c = three.charCodeAt (0);
      c2 = three.charCodeAt(1);
      c3 = three.charCodeAt(2);
      return String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
    }
  }
}


//--------------------------------------------------------------------
/**
 * Encodes a string into its "escaped-utf-8" representation.  This
 * means that all characters are firstly encoded into utf-8 and in a
 * subsequent step the resulting bytes are "escaped" with %CC.<p>
 *
 * Additionally a set can be given that defines character codes that
 * are not to be encoded. They will be simply transferred to the
 * returned string as they are.<p>
 *
 * Normally this function will not be called directly - it is used in
 * "encodeURIxxxx" functions instead.<p>
 *
 * This implementation also defines two three sets that have been
 * produced with the following code:
 *
 * <pre>
 * function invert ( a )
 * {
 *   var o = [];
 *   for ( var i = 0; i < a.length; ++i )
 *   {
 *     o [a.charCodeAt(i)] = 1;
 *   }
 *   writeln ( "  " + o.toSource ().replace ( / /g, "" ) );
 * }
 * var s1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!*";
 * writeln ( "escapeUtf8.encodeURIComponentSet = " );
 * invert ( s1 );
 * var s2 = "()'" + ";/?:@&=+$,~" + s1 + "#";
 * writeln ( "escapeUtf8.encodeURISet = " );
 * invert ( s2 );
 * </pre>
 *
 * The sets are used to define the behavior of the
 * <code>encodeURI</code> and <code>encodeURIComponent</code>
 * functions.
 *
 * @param aString: string: the string that should be encoded.
 * @param aSet: array: an array of flags that defines the character
 *   codes of characters that should not be transcoded. Each character
 *   code with a nonzero value in the set will be simply transferred to
 *   the result without any conversion.
 * @return string: the original string in "escaped-utf-8" encoding.
 */
function escapeUtf8 ( aString, aSet )
{
  var i2a = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
  var u = encodeUtf8 ( aString );
  var a = [];
  if ( aSet == null )
    aSet = escapeUtf8.emptySet;

  for ( var i = 0; i < u.length; ++ i )
  {
    var c = u.charCodeAt (i);
    if ( aSet[c] )
      a [a.length] = u.charAt(i);
    else
      a [a.length] = "%" + i2a [c >> 4] + i2a [c & 0xf ];
  }

  return a.join ( "" );
}

// Sets for encodeURI and encodeURIComponent that are internally
// used.
escapeUtf8.emptySet = {};

escapeUtf8.encodeURIComponentSet =
  [0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,1,1,,1,1,1,1,1,1,1,1,
   1,1,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,,,,1,
   ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
escapeUtf8.encodeURISet =
  [0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
   1,1,1,1,1,1,1,1,,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
   1,1,1,,,,,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,,,1]

//--------------------------------------------------------------------
/**
 * Encodes a URI Component part into escaped UTF-8 encoding
 * as defined in ECMA 262-3. The set of reserved characters
 * is more strict as in the standard and is defined with:
 * "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*"
 *
 * @param anObject: object: an object (that is normally a portionof a
 *   URI) that should be converted to a string and
 *   escaped-utf8-encoded. In case of a string the string will be used -
 *   if an Object is used the <code>toString</code> method of the object
 *   will be called first. In the "undefined" case, or when
 *   <code>null</code> will be used "undefined" will be returned.
 *
 * @return string: the encoded URI portion in escaped-utf8 encoding.
 */
function encodeURIComponent ( anObject )
{
  switch ( typeof anObject )
  {
    case "undefined":
      return "undefined";
    case "string":
      return escapeUtf8 ( anObject, escapeUtf8.encodeURIComponentSet );
    default:
      return escapeUtf8 ( anObject.toString(), escapeUtf8.encodeURIComponentSet );
  }
}

//--------------------------------------------------------------------
/**
 * Encodes a URI as defined in ECMA 262-3. It is strongly recommended
 * that you DO NOT USE this function. Use partial escaping of URLs
 * (or classes that help you with this task) instead.
 *
 * @param aString: string: a string that contains a URI that should
 *   be encoded to be conform to RFC 2396.
 * @return string: the encoded URI
 */
function encodeURI ( aString )
{
  return escapeUtf8 ( aString, escapeUtf8.encodeURISet );
}

//--------------------------------------------------------------------
/**
 * Converts a URI that was formerly converted with <code>encodeURI</code>
 * to Escaped-UTF8 into its original form (ECMA 262-3). This function
 * works in a way that leads to undesirable results (sometimes). It is
 * strongly recommended to divide a URL into its distinct parts and
 * decode these parts in different steps.
 *
 * @deprecated since 2003-06-17
 */
function decodeURI ( aString )
{
  throw "Illegal Function (Object JavaScript Support Library.)";
}

//--------------------------------------------------------------------
/**
 * Decodes an "escaped-utf-8" encoded portion of a URL (or something
 * else) into its original character string.<p>
 *
 * Note that on the server side this implementation is NOT necessary.
 *
 * @param anObject: object: an object (that is normally a portionof a
 *   URI) that should be converted from escaped-utf8 encoding into
 *   the original string. In case of a string the string will be used -
 *   if an Object is used the <code>toString</code> method of the object
 *   will be called first. In the "undefined" case, or when
 *   <code>null</code> will be used "undefined" will be returned.
 * @return string: the original character string
 */
if ( typeof decodeURIComponent == "undefined" )
{
  decodeURIComponent = function ( anObject )
  {
    var aString;
    switch ( typeof anObject )
    {
      case "undefined":
        aString = "undefined";
      case "string":
	aString = anObject;
        break;
      default:
        aString = anObject.toString ();
    }

    var a = [];
    var conv = { "0":0,  "1":1,  "2":2,  "3":3,
                 "4":4,  "5":5,  "6":6,  "7":7,
                 "8":8,  "9":9,  "A":10, "B":11,
                 "C":12, "D":13, "E":14, "F":15 };

    var i = 0;
    while ( i < aString.length )
    {
      var c = aString.charCodeAt ( i );
      if ( c == 37 /* "=" */ )
      {
        var c1 = conv[aString.charAt ( i+1 )];
        var c2 = conv[aString.charAt ( i+2 )];
        if ( isNaN (c1) || isNaN (c2) )
        {
          a [a.length] = String.fromCharCode (c);
          ++i;
        }
        else
        {
          a [a.length] = String.fromCharCode ( (c1 << 4) + c2 );
          i += 3;
        }
      }
      else
      {
        a [a.length] = String.fromCharCode (c);
        ++i;
      }
    }
    return ( decodeUtf8 ( a.join ( "" ) ) );
  }
}

//--------------------------------------------------------------------
/**
 * Encodes an arbitrary URI path by encoding its path components.
 * The path will be splitted and then encoded by means of
 * "encodeURIComponent". Finally it will be returned by
 * joining the segments with slashes.
 *
 * @param aURI: string: the path segments that should be encoded
 * @return string: the encoded path information
 */

function encodeURIPath ( aURI )
{
  if ( !aURI )
    return aURI;

  var components = aURI.split('/');
  for (var i=0; i<components.length; i++) {

    components[i] = encodeURIComponent(components[i]);
  }
  return components.join('/');
}

var gChangeLevel1={
  "\u0041":"a",   // writing chracters in the unicode way is necessary because of PR-4581
  "\u0061":"a",   // to see the real character have a look at gChangeLevel2
  "\u00c6":"ae",
  "\u00e6":"ae",
  "\u00e1":"a",
  "\u00c1":"a",
  "\u00e0":"a",
  "\u00c0":"a",
  "\u00e2":"a",
  "\u00c2":"a",
  "\u00e5":"a",
  "\u00c5":"a",
  "\u00e4":"a",
  "\u00c4":"a",
  "\u00e3":"a",
  "\u00c3":"a",
  "\u0043":"c",
  "\u0063":"c",
  "\u00e7":"c",
  "\u00c7":"c",
  "\u0044":"d",
  "\u0064":"d",
  "\u00d0":"d",
  "\u00f0":"d",
  "\u0065":"e",
  "\u0045":"e",
  "\u00e9":"e",
  "\u00c9":"e",
  "\u00e8":"e",
  "\u00c8":"e",
  "\u00ea":"e",
  "\u00ca":"e",
  "\u00eb":"e",
  "\u00cb":"e",
  "\u0049":"i",
  "\u0069":"i",
  "\u00ed":"i",
  "\u00cd":"i",
  "\u00ec":"i",
  "\u00cc":"i",
  "\u00ee":"i",
  "\u00ce":"i",
  "\u00ef":"i",
  "\u00cf":"i",
  "\u004f":"o",
  "\u006f":"o",
  "\u00d8":"o",
  "\u00f8":"o",
  "\u00f3":"o",
  "\u00d3":"o",
  "\u00f2":"o",
  "\u00d2":"o",
  "\u00f4":"o",
  "\u00d4":"o",
  "\u00f5":"o",
  "\u00f6":"o",
  "\u00d6":"o",
  "\u0053":"s",
  "\u0073":"s",
  "\u00df":"ss",
  "\u0055":"u",
  "\u0075":"u",
  "\u00fa":"u",
  "\u00da":"u",
  "\u00f9":"u",
  "\u00d9":"u",
  "\u00fb":"u",
  "\u00db":"u",
  "\u00fc":"u",
  "\u00dc":"u",
  "\u0059":"y",
  "\u0079":"y",
  "\u00fd":"y",
  "\u00dd":"y",
  "\u00ff":"y",
  "\u00f1":"n",
  "\u00d1":"n",
  "-":"",
  "'":"",
  "!":"",
  '"':"",
  "#":"",
  "$":"",
  "%":"",
  "&":"",
  "'":"",
  "(":"",
  ")":"",
  "*":"",
  "+":"",
  ",":"",
  "-":"",
  ".":"",
  "/":"",
  ":":"",
  ";":"",
  "<":"",
  "=":"",
  ">":"",
  "?":"",
  "@":"",
  "[":"",
  "\\":"",
  "]":"",
  "^":"",
  "_":"",
  "`":"",
  "{":"",
  "|":"",
  "}":"",
  "~":""
}

var gChangeLevel2={
  "\u0041":"a\000",//A
  "\u0061":"a\000",//a
  "\u00c6":"ae",//Æ
  "\u00e6":"ae",//æ
  "\u00e1":"a\001",//á
  "\u00c1":"a\001",//Á
  "\u00e0":"a\002",//à
  "\u00c0":"a\002",//À
  "\u00e2":"a\003",//â
  "\u00c2":"a\003",//Â
  "\u00e5":"a\004",//å
  "\u00c5":"a\004",//Å
  "\u00e4":"a\005",//ä
  "\u00c4":"a\005",//Ä
  "\u00e3":"a\006",//ã
  "\u00c3":"a\006",//Ã
  "\u0043":"c\000",//C
  "\u0063":"c\000",//c
  "\u00e7":"c\001",//ç
  "\u00c7":"c\001",//Ç
  "\u0044":"d\000",//D
  "\u0064":"d\000",//d
  "\u00d0":"d\000",//Ð
  "\u00f0":"d\000",//ð
  "\u0065":"e\000",//e
  "\u0045":"e\000",//E
  "\u00e9":"e\001",//é
  "\u00c9":"e\001",//É
  "\u00e8":"e\002",//è
  "\u00c8":"e\002",//È
  "\u00ea":"e\003",//ê
  "\u00ca":"e\003",//Ê
  "\u00eb":"e\004",//ë
  "\u00cb":"e\004",//Ë
  "\u0049":"i\000",//I
  "\u0069":"i\000",//i
  "\u00ed":"i\001",//í
  "\u00cd":"i\001",//Í
  "\u00ec":"i\002",//ì
  "\u00cc":"i\002",//Ì
  "\u00ee":"i\003",//î
  "\u00ce":"i\003",//Î
  "\u00ef":"i\004",//ï
  "\u00cf":"i\004",//Ï
  "\u004f":"o\000",//O
  "\u006f":"o\000",//o
  "\u00d8":"o\000",//Ø
  "\u00f8":"o\000",//ø
  "\u00f3":"o\001",//ó
  "\u00d3":"o\001",//Ó
  "\u00f2":"o\002",//ò
  "\u00d2":"o\002",//Ò
  "\u00f4":"o\003",//ô
  "\u00d4":"o\003",//Ô
  "\u00f5":"o\004",//õ
  "\u00f6":"o\005",//ö
  "\u00d6":"o\005",//Ö
  "\u0053":"s\000",//S
  "\u0073":"s\000",//s
  "\u00df":"ss",//ß
  "\u0055":"u\001",//U
  "\u0075":"u\001",//u
  "\u00fa":"u\001",//ú
  "\u00da":"u\001",//Ú
  "\u00f9":"u\002",//ù
  "\u00d9":"u\002",//Ù
  "\u00fb":"u\003",//û
  "\u00db":"u\003",//Û
  "\u00fc":"u\004",//ü
  "\u00dc":"u\004",//Ü
  "\u0059":"y\000",//Y
  "\u0079":"y\000",//y
  "\u00fd":"y\001",//ý
  "\u00dd":"y\001",//Ý
  "\u00ff":"y\002",//ÿ
  "\u00f1":"n\001",//ñ
  "\u00d1":"n\001",//Ñ
  "-":"",
  "'":"",
  "!":"",
  '"':"",
  "#":"",
  "$":"",
  "%":"",
  "&":"",
  "'":"",
  "(":"",
  ")":"",
  "*":"",
  "+":"",
  ",":"",
  "-":"",
  ".":"",
  "/":"",
  ":":"",
  ";":"",
  "<":"",
  "=":"",
  ">":"",
  "?":"",
  "@":"",
  "[":"",
  "\\":"",
  "]":"",
  "^":"",
  "_":"",
  "`":"",
  "{":"",
  "|":"",
  "}":"",
  "~":""
}


//--------------------------------------------------------------------
/**
 * creates an simple compareable string out of an internationalized string
 * This is done using EOR conform rules
 *
 * @param aStr: string: an arbitrary stringthe path segments that should be encoded
 * @return string: the by >< compareable representation of aStr
 */

function intStrKeyLevel1(aStr)
{  // create internationalised sortable string
  var theStr=aStr.replace(/^ */g,"");
  var theStr=theStr.replace(/ *$/g,"");
  function lamdaExp(key)
  {
    var ret=gChangeLevel1[key];
    if (typeof ret !="undefined")
      return ret;
    else
      return key;
  }

  if (!lambdaExpressionsSupported())
    return theStr;

var aRegExp=new RegExp("[\u0041\u0061\u00c6\u00e6\u00e1\u00c1\u00e0\u00c0\u00e2\u00c2\u00e5\u00c5\u00e4\u00c4\u00e3\u00c3\u0043\u0063\u00e7\u00c7\u0044\u0064\u00d0\u00f0\u00e9\u0065\u0045\u00c9\u00e8\u00c8\u00ea\u00ca\u00eb\u00cb\u0049\u0069\u00ed\u00cd\u00ec\u00cc\u00ee\u00ce\u00ef\u00cf\u004f\u006f\u00d8\u00f8\u00f3\u00d3\u00f2\u00d2\u00f4\u00d4\u00f5\u00f6\u00d6\u0053\u0073\u00df\u0055\u0075\u00fa\u00da\u00f9\u00d9\u00fb\u00db\u00fc\u00dc\u0059\u0079\u00fd\u00dd\u00ff\u00f1\u00d1\\-\\'\\!\\\"\\#\\%\\&\\'\\(\\)\\*\\+,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~]","g");
  return theStr.replace ( aRegExp, lamdaExp );
}

function intStrKeyLevel2(aStr)
{  // create internationalised sortable string
  var theStr=aStr.replace(/^ */g,"");
  var theStr=theStr.replace(/ *$/g,"");
  function lamdaExp(key)
  {
    var ret=gChangeLevel2[key];
    if (typeof ret !="undefined")
      return ret;
    else
      return key;
  }

  if (!lambdaExpressionsSupported())
    return theStr;

  var aRegExp=new RegExp("[\u0041\u0061\u00c6\u00e6\u00e1\u00c1\u00e0\u00c0\u00e2\u00c2\u00e5\u00c5\u00e4\u00c4\u00e3\u00c3\u0043\u0063\u00e7\u00c7\u0044\u0064\u00d0\u00f0\u00e9\u0065\u0045\u00c9\u00e8\u00c8\u00ea\u00ca\u00eb\u00cb\u0049\u0069\u00ed\u00cd\u00ec\u00cc\u00ee\u00ce\u00ef\u00cf\u004f\u006f\u00d8\u00f8\u00f3\u00d3\u00f2\u00d2\u00f4\u00d4\u00f5\u00f6\u00d6\u0053\u0073\u00df\u0055\u0075\u00fa\u00da\u00f9\u00d9\u00fb\u00db\u00fc\u00dc\u0059\u0079\u00fd\u00dd\u00ff\u00f1\u00d1\\-\\'\\!\\\"\\#\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~]","g");

  return theStr.replace ( aRegExp, lamdaExp );
}

//--------------------------------------------------------------------
/**
 * compares two strings using EOR conform rules
 *
 * @param a,b: string: the two strings to compare
 * @return string: -1,0,1 as used for sorting
 */
function compareIntStrings(a,b)
{
  var aa=intStrKeyLevel1(a);
  var bb=intStrKeyLevel1(b);
  if (aa>bb) return 1; 
  else if (aa<bb) return -1;
  
  var aa=intStrKeyLevel2(a);
  var bb=intStrKeyLevel2(b);
  if (aa>bb) return 1; 
  else if (aa<bb) return -1;
  else return 0;
}
/* End of "ojs1.js" */
