// KABIKADJ (c) Vlad ATANASIU 2001
// Search of query in catalog files

var ms = 0;							// Globale variabeln bestimmen
var DataAbkz = "";
var lastChar = "";
var queryFound = 0;
var naData = 0;							// out of range of the query set as '0' i.e. 'YES'
var wildcard = "";
var logicOp = "";
var temp = "";
var NombreRubriques = 0;						// 'buttons' muessen dekrementiert werden, boxes compris
var queryFieldLength = 0;						// zaehlt wieviele Eingabefelder gechoosen worden sind
var CatalogLength = MsNr + 1;
var CatalogFin = CatalogLength - 1;
var QueryExistenz = 0;						// QueryArray in DataArray Flag
var descriptor = 0;
var DateCheckOK = 0;
var DateRanges = new Array();
var INPUT = parent.frames['Search'].document;				// Frames
var OUTPUT = parent.frames['Results'].document;
var language = "";							// get language of interface
uri = window.location.href;
language = uri.substring(uri.lastIndexOf("SEARCH.HTM")-3,uri.lastIndexOf("SEARCH.HTM")-1);

// ----------------------------------------------------------
// Zugriff ueber die HTML-Form QueryForm bei "Rechercher"-icon clicking
// ----------------------------------------------------------

function Validator() {
    ms = 0;								// Reseting variables for second & subsequent queries
    DataAbkz = "";
    lastChar = "";
    queryFound = 0;
    naData = 0;							// out of range of the query set as '0' i.e. 'YES'
    wildcard = "";
    logicOp = "";
    temp = "";
    NombreRubriques = 0;						// 'buttons' muessen dekrementiert werden, boxes compris
    queryFieldLength = 0;
    CatalogLength = MsNr + 1;
    CatalogFin = CatalogLength - 1;
    QueryExistenz = 0;						// QueryArray in DataArray Flag
    QueryToDataEquivalenz();						// Equivalenztable zw Queryeingabefeldernstruktur und Datastruktur
    FeldDetermine();							// Eingabefeld ermitteln
    QueryStringPrepare();						// Eingabe bearbeiten
    ListSearch();
}

// ----------------------------------------------------------
// Equivalenztable zw Queryeingabefeldernstruktur und Datastruktur
// ----------------------------------------------------------

function QueryToDataEquivalenz() {
    QueryFieldNr = new Array();
    QueryValue = new Array();
    QueryNrRangeFields = new Array();					// Eine EquivalenzTable zwischen die Query Array & Data Array errichten
    QueryEqvDataFieldsNr = new Array();				// folgendes suit l'ordre des eingabefaelder in die 'search.htm'
    wasNumberRange = 0;
    wasNumberRangeOK = 0;
    i = 0;
    j = 0;

    QueryEqvDataFieldsNr[i] = NomCollFullOrig ;				// Reference
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = NomCollFullTranslit ;	
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = NomCollFullTranslated ;	
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = CoteMsOrig ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = CoteMsTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = VilleCollOrig ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = VilleCollTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = PaysColl ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Biblio ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = NoticeCataloger ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = AuteurOrig ;				// Content & History
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = AuteurTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = TitreOrig ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = TitreTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = TitreTranslated ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Sujet ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Langue ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DateRecordY ;				// min
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DateRecordY ;				// max
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DateEquivAdY ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DateEquivAdY ;	
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DateVraisembla ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DateVraisembla ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = LieuCopieVilleOrig ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = LieuCopieVilleTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = LieuCopiePays ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = LieuVraisembla ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = CopisteOrig ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = CopisteTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DedicataireOrig ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DedicataireTranslit ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = OwnerReader ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Waqf ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportMatiere ;				// Material aspects
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportCouleur ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportEpaiss ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportFiligrane ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportVergDisp ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportVergDens ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = SupportVergDens ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = SupportFils ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DimSuppH ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DimSuppH ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DimSuppW ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DimSuppW ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DimSuppD ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DimSuppD ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DimTexteH ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DimTexteH ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = DimTexteW ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = DimTexteW ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Folios ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = Folios ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Cahiers ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = Cahiers ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = FoliotationOr ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = NumrtCahiers ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Reclames ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Piqures ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = ReglureLines ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = ReglureFrame ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Lignes ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = Lignes ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Colonnes ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = Colonnes ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Cadre ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Enluminure ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Dessin ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Miniatures ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelMatiere ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelRabat ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelColPlate ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelColSpine ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelDecorAbstr ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelDecorVeget ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelDecorAnima ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelDecorHumain ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = RelDecorScript ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Poids ;
    QueryFieldNr[i] = 0;
    QueryNrRangeFields[j] = i;
    NombreRubriques++;
    i++;
    j++;
    QueryEqvDataFieldsNr[i] = Poids ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = StyleTexte ;				// Script
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = StyleTitrage ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = QualiteScript ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = ColTexte ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = ColTitrage ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Serif ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = Descendante ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
    QueryEqvDataFieldsNr[i] = NonArabicScripts ;
    QueryFieldNr[i] = 0;
    NombreRubriques++;
    i++;
}

// ----------------------------------------------------------
// Hier wird ermittelt welches Feld der Form gefillt wurde
// ----------------------------------------------------------

function FeldDetermine() {
    for ( i = 0; i < NombreRubriques; i++ ) {
        if ( INPUT.forms[0].elements[i].value ) {
            QueryFieldNr[queryFieldLength] = i;
            QueryValue[queryFieldLength] = INPUT.forms[0].elements[i].value;
            queryFieldLength++;
        }
    }
}

// ----------------------------------------------------------
// Query string auf Suche vorbereiten:
// ----------------------------------------------------------

function QueryStringPrepare() {
    for ( i = 0; i < queryFieldLength; i++ ) {				// auf wildcard in Query pruefen
        logicOp = " | ";							// a dummy logicOp is added if there's none
        if ( QueryValue[i].indexOf(" & ") != -1 ) { logicOp = " & "; }		// logical 'and'
        if ( QueryValue[i].indexOf(" | ") != -1 ) { logicOp = " | "; }		// logical 'or'
        while( QueryValue[i].charAt( QueryValue[i].length-1 ) == " " )		// remove trailing spaces
            QueryValue[i] = QueryValue[i].substring(0,QueryValue[i].length-1)

        if ( language != "EN" ) {						// do translation to EN only if language not EN
            if (QueryEqvDataFieldsNr[QueryFieldNr[i]] == PaysColl ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == Sujet ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == Langue ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == LieuCopiePays ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == LieuVraisembla ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == SupportMatiere ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == SupportCouleur ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == QualiteScript ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == ColTexte ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == ColTitrage ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == Serif ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == Descendante ||
                QueryEqvDataFieldsNr[QueryFieldNr[i]] == NonArabicScripts)
                    QueryValue[i] = Translation(QueryValue[i]);
        }
        else if ( QueryEqvDataFieldsNr[QueryFieldNr[i]] == NomCollFullTranslated ||
            QueryEqvDataFieldsNr[QueryFieldNr[i]] == TitreTranslated )		// do translation to EN
            QueryValue[i] = Translation(QueryValue[i]);

        QueryValue[i] = QueryValue[i].toLowerCase();			// alles LowerCase setzen
    }
}

// --------------------------------------------------------------
// Translation to English
// --------------------------------------------------------------

function Translation( str ) {
    temp = "";
    strNew = "";
    str = str + logicOp;						// dummy logicOp
    while( str.indexOf(logicOp) != -1 ) {					// here a restriction to one type of logicOp per field is introduced
        temp = str.substring( 0, str.indexOf(logicOp) );			// chop multiple query in individual queryies
        str = str.substring( str.indexOf(logicOp)+3, str.length );
        if (temp.charAt(0) == "-" || temp.charAt(0) == "!")			// remove logicNot/Only & wildcards if any
            temp = temp.substring( 1, temp.length);
        if (temp.charAt(temp.length) == "*" || temp.charAt(temp.length) == "%")
            temp = temp.substring( 0, temp.length-1);
        if (typeof( Dictionary[temp] ) != "undefined")				// translate individual query
            temp = Dictionary[temp];
        strNew = strNew + logicOp + temp;				// recompose translated multiple query
    }
    str = strNew.substring(3,strNew.length);				// remove dummy logicOp
    return str;
}

// ----------------------------------------------------------
// Ermitteln und Ausgabe der Suchergebnisse
// ----------------------------------------------------------

function ListSearch() {
   var tempQ1 = "";							// local variables
   var tempQ2 = "";
   var tempD1 = "";
   var tempD2 = "";

   with ( OUTPUT ) {
        open();
        HTMLtop();
        writeln("<b>Answers :</b>");
        writeln("<ol>");

        for ( ms = 0; ms <= CatalogFin; ms++ ) {
            queryFound = 0;
            wasNumberRange = 0;
            wasNumberRangeOK = 0;

            for ( i = 0; i < queryFieldLength; i++ ) {
                if ( wasNumberRange == 2 ) {					// skip 2nd numeric query field			
                    queryFound++;
                    wasNumberRange = 0;					
                    continue;						// go to next query field
                }

                DataStringPrepare();					// remarks removal, translations, lower case...

                if ( DataAbkz == "-" || DataAbkz == "?" || DataAbkz == "*" ) {	// search for 'non available data'
                    naData++;
                    break;							// go to next data file
                }

                for ( m = 0; m < QueryNrRangeFields.length; m++ ) {		// 1. --- Numeric query fields
                    if ( QueryFieldNr[i] == QueryNrRangeFields[m] ) {
                        while( DataAbkz.indexOf(" ;") != -1 ) {			// multiple data per field
                            temp = DataAbkz;
                            DataAbkz = DataAbkz.substring( 0, DataAbkz.indexOf(" ;") );
                            NumberRange();
                            DataAbkz = temp.substring( temp.indexOf(" ;")+3, temp.length );
                        }
                        NumberRange();
                        if ( wasNumberRangeOK == 1 )
                            queryFound++;
                        break;
                    }
                }

                if ( wasNumberRange == 0 ) {					// 2. --- Alphanumeric query fields
                    var k = 0;						// je nach logical operator typ entzweigen
                    wildcard = "";
                    logicNot = 0;
                    logicOp = " | ";
                    if (QueryValue[i].indexOf(" & ") != -1) { logicOp = " & " }	// logical 'and'
                    if (QueryValue[i].indexOf(" | ") != -1) { logicOp = " | " }	// logical 'or'

                    tempQ1 = QueryValue[i];					// Query zerteilen
                    QueryValue[i] = QueryValue[i] + logicOp;
                    while(QueryValue[i].indexOf(logicOp) != -1) {
                        if ( logicOp != " | " ) { k = 0; }
                        wildcard = "";
                        logicNot = 0;
                        logicOnly = 0;
                        tempQ2 = QueryValue[i];
                        QueryValue[i] = QueryValue[i].substring( 0, QueryValue[i].indexOf(logicOp) );

                        firstChar = QueryValue[i].charAt(0);			// auf logicNot in Query pruefen
                        if ( firstChar == "-" ) {
                            QueryValue[i] = QueryValue[i].substring( 1, QueryValue[i].length );
                            logicNot = 1;
                        }
                        else if ( firstChar == "!" ) {				// auf logicOnly in Query pruefen
                            QueryValue[i] = QueryValue[i].substring( 1, QueryValue[i].length );
                            logicOnly = 1;
                        }
                        lastChar = QueryValue[i].charAt( QueryValue[i].length - 1 );	// auf wildcard in Query pruefen
                        if ( lastChar == "*" || lastChar == "%" ) {
                            QueryValue[i] = QueryValue[i].substring( 0, QueryValue[i].length - 1 );
                            wildcard = lastChar;
                        }

                        tempD1 = DataAbkz;					// Data zerteilen
                        DataAbkz = DataAbkz + " ;";
                        while( DataAbkz.indexOf(" ;") != -1 ) {
                            tempD2 = DataAbkz;
                            DataAbkz =  DataAbkz.substring(0,DataAbkz.indexOf(" ;"));
                            switch (wildcard) {
                                case "":						// no wildcard in query
                                    if ( DataAbkz == QueryValue[i] ) { k = 1; }
                                    break;
                                case "*":						// wildcard : word starting with ...
                                    if ( DataAbkz.substring(0,QueryValue[i].length ) == QueryValue[i]) { k = 1; }
                                    break;
                                case "%":					// wildcard : word containing at any location ...
                                    if ( DataAbkz.indexOf(QueryValue[i]) != -1 ) { k = 1; }
                                    break;
                            }
                            if ( k == 1 ) { break; }
                            DataAbkz = tempD2.substring(tempD2.indexOf(" ;")+3,tempD2.length);
                        }

                        DataAbkz = tempD1;
                        if ( logicNot == 1 ) {
                            if ( k == 1 ) { k = 0; }
                            else { k = 1; }
                        }
                        if ( logicOnly == 1 && k == 1 && DataAbkz.indexOf(" ;") != -1 ) { k = 0; }
                        if ( logicOp == " & " && k == 0 ) { break; }
                        QueryValue[i] = tempQ2.substring(tempQ2.indexOf(logicOp)+3,tempQ2.length);
                    }
                    QueryValue[i] = tempQ1;					// reestablish the query value as before it was modified in order zu zerteil it
                    if ( k == 0 ) { break; }
                    queryFound++;						// wenn coinzidenz of query & data > OK
                }
            }
            								// 3. --- Results erwagen: only if alle durchsuchFeldern einstimmen Antwort schreiben
            if (queryFound == queryFieldLength) {
                FormatOutput();
                QueryExistenz++;						// Flag setzen :  "Das QueryArray wurde im DataArray gefunden"
            }
        }
        writeln("</ol>");

        if ( QueryExistenz == 0 )
            writeln("<p>Query not found.");
        PourcentageBar()
        HTMLbottom();
        close();
    }
}

// ----------------------------------------------------------
// Top of Datei schreiben
// ----------------------------------------------------------

function HTMLtop() {
    with ( OUTPUT ) {
        writeln("<html>");
        writeln("<head>");
        writeln("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\">");
        writeln("<link rel=stylesheet type=\"text/css\" href=\"../../CSS/RESULTS.CSS\">");
        writeln("</head>");
        writeln("<body style=\"background-image:url(../../IMAGES/KBK_BIG.GIF); background-attachment:fixed; background-repeat:no-repeat; background-position:center; background-position:top;\">");
    }
}

// --------------------------------------------------------------
// Bottom of Datei schreiben
// --------------------------------------------------------------

function HTMLbottom() {
    with ( OUTPUT ) {
        writeln("<p></body></html>");
    }
}

// ----------------------------------------------------------
// Data string auf Suche vorbereiten
// ----------------------------------------------------------

function DataStringPrepare() {
    if ( QueryEqvDataFieldsNr[QueryFieldNr[i]] == NomCollFullTranslated ||
        QueryEqvDataFieldsNr[QueryFieldNr[i]] == TitreTranslated )		// Translation fields
        DataAbkz = Catalog[ms][QueryEqvDataFieldsNr[QueryFieldNr[i]-2]]
    else
        DataAbkz = Catalog[ms][QueryEqvDataFieldsNr[QueryFieldNr[i]]];

    if ( DataAbkz.charAt(DataAbkz.length-1) == ")" )			// Remarks zwischen klammern am ende der zeile entfernen
        DataAbkz = DataAbkz.substring(0,DataAbkz.lastIndexOf("(")-1);
   
    DataAbkz = DataAbkz.toLowerCase();				// alles LowerCase setzen
}

// ----------------------------------------------------------
// ZahlenRange abzweigung
// ----------------------------------------------------------

function NumberRange() {
  
    QueryRangeMin = Number(QueryValue[i]);
    QueryRangeMax = QueryRangeMin;

    if ( QueryValue[i+1] ) {						// Range case:
        wasNumberRange = 2;
        QueryRangeMax = Number(QueryValue[i+1]);
    }
    else								// Einzelnes Nr case:
        wasNumberRange = 1;

    if ( QueryEqvDataFieldsNr[QueryFieldNr[i]] == DateRecordY ||
        QueryEqvDataFieldsNr[QueryFieldNr[i]] == DateEquivAdY ||
        QueryEqvDataFieldsNr[QueryFieldNr[i]] == DateVraisembla )		// For date fields there is a special handling of numbers
        DateCheck()

    if ( DateCheckOK == 1 || 
        ( DataAbkz >= QueryRangeMin && DataAbkz <= QueryRangeMax ) ) {
        if ( QueryValue[i+1] )
            wasNumberRangeOK = 1;
        else
            queryFound++;
    }
}

// ----------------------------------------------------------
// Search query in dates
// ----------------------------------------------------------

function DateCheck() {   						// This function transforms the compact date notation (ex: 1234/5),
     								// containing symbols (delimatators <([{> and range specifiers <...?/->),
    								// into a list of numerical vectors, by splitting each date so long
    var s1, s2, s11, s12, s21, s22;					// as it contains these semantical operation symbols.
    DateRanges[0] = new Array();					// minimum & ...
    DateRanges[1] = new Array();					// maximum of a date range


    if ( isNaN(DataAbkz) == false ) {					// 1. --- Simple date
        if (DataAbkz >= QueryRangeMin && 
            DataAbkz <= QueryRangeMax )				// In case there is complete, unambigous, one-year span evidence for the date
            DateCheckOK = 1;
        DateRanges[0] = DataAbkz;
        DateRanges[1] = DataAbkz;
        return
    }
    								// 2. --- Reduce symbols
    while ( DataAbkz.indexOf("{") != -1 ) { DataAbkz = DataAbkz.replace( /\{/, ""); }		// <{> specifies a date recorded in a special notation (abreviated, acrostich...)
    while ( DataAbkz.indexOf("}") != -1 ) { DataAbkz = DataAbkz.replace( /\}/,""); }
    while ( DataAbkz.indexOf("/") != -1 ) { DataAbkz = DataAbkz.replace( /\//, "-"); }		// </> date spaning over two years
    while ( DataAbkz.indexOf("[?]") != -1 ) { DataAbkz = DataAbkz.replace( /\[\?\]/, "\[0-9\]"); }	// <[?]> one missing digit
    while ( DataAbkz.indexOf("[??]") != -1 ) { DataAbkz = DataAbkz.replace( /\[?\?\]/, "\[0-9\]\[0-9\]"); }
    while ( DataAbkz.indexOf("[???]") != -1 ) { DataAbkz = DataAbkz.replace( /\[?\?\?\]/, "\[0-9\]\[0-9\]\[0-9\]"); }
    while (DataAbkz.charAt(0) == "<" &&
        DataAbkz.charAt( DataAbkz.length-1 ) == ">" ) {					// <<>> centuries
        DataAbkz = DataAbkz.replace( /</, "" );
        if ( DataAbkz.indexOf("-") != -1 ) {
            DataAbkz = DataAbkz.replace( /-/, "00-" );
            DataAbkz = DataAbkz.replace( />/, "99" );
        }
        else
            DataAbkz = DataAbkz.replace( />/, "00-99" );
    }

    DateList = new Array();						// 3. --- Multiplication of dates
    DateList.push(DataAbkz);

    if ( DataAbkz.indexOf("(...)") != -1 ) {					// symbol: vectorizer: <...> : unknown number of missing digits      
        DateList.shift();
        temp = DataAbkz;
        while ( temp.indexOf("(...)") != -1 )
            temp = temp.replace(/\(\.\.\.\)/,"\[0-9\]");
        DateList.push(temp);
        temp = DataAbkz;
        while ( temp.indexOf("(...)") != -1 )
            temp = temp.replace(/\(\.\.\.\)/,"\[0-9\]\[0-9\]");
        DateList.push(temp);
        temp = DataAbkz;
        while ( temp.indexOf("(...)") != -1 )
            temp = temp.replace(/\(\.\.\.\)/,"\[0-9\]\[0-9\]\[0-9\]");			// dates can have a maximum of four digits
        DateList.push(temp);
    }

    for ( n = 0; n <= DateList.length-1; n++ ) {				// symbol: vectorizer: <#?#> : ambigous reading of the date : can be either digit on the sides of the symbol
        while ( DateList[n].indexOf("?") != -1 ) {
            s1 = DateList[n].substring( 0, DateList[n].indexOf("?") );
            s2 = DateList[n].substring( DateList[n].indexOf("?")+1, DateList[n].length );

            if ( s1.indexOf("(") != -1 ) {					// case type <(#?#)> : stands for only one digit
                s11 = s1.substring( 0, s1.indexOf("(") );
                s12 = s1.substring( s1.indexOf("(")+1, s1.length );
                s21 = s2.substring( 0, s2.indexOf(")") );
                s22 = s2.substring( s2.indexOf(")")+1, s2.length );

                s1 = s11+s12+s22;
                s2 = s11+s21+s22;
            }
            DateList.push(s1);						// else: case type <####?####> : stands for all digits
            DateList.push(s2);
            DateList.shift();
        }
    }
    								// 4. --- Split dates to ranges
    								// From here on all dates will be expressed as vectors
    for ( n = 0; n <= DateList.length-1; n++ ) {				// symbol: vectorizer: <->
        if ( DateList[n].indexOf("-") != -1 ) {
            s1 = DateList[n].substring( 0, DateList[n].indexOf("-") );
            s2 = DateList[n].substring( DateList[n].indexOf("-")+1, DateList[n].length );

            if ( s1.indexOf("[") != -1 ) {					// case type <#[#-#]#[#-#]> : <-> notation for ranges
                s11 = s1.substring( 0, s1.indexOf("[") );
                s12 = s1.substring( s1.indexOf("[")+1, s1.length );
                s21 = s2.substring( 0, s2.indexOf("]") );
                s22 = s2.substring( s2.indexOf("]")+1, s2.length );

                if (s11.indexOf("[") != -1 ||
                    s22.indexOf("[") != -1 ) {
                    DateList.push( s11+s12+s22 );
                    DateList.push( s11+s21+s22 );
                }
                else {
                    DateRanges[0].push( s11+s12+s22 );
                    DateRanges[1].push( s11+s21+s22 );
                }
            }
            else {							// case type <####-##>
                DateRanges[0].push(s1);
                s2 = s1.substring( 0, s1.length - s2.length ) + s2;
                DateRanges[1].push(s2);
            }
        }
        else {							// one-year date has vector ending equal vector start
            DateRanges[0].push(DateList[n]);
            DateRanges[1].push(DateList[n]);
        }
    }

    DateCheckOK = 0;						// 5. --- Check existence of query in list of dates
    for ( n = 0; n <= DateRanges[0].length-1; n++ ) {
        if ( QueryRangeMin > DateRanges[1][n] ||
            QueryRangeMax < DateRanges[0][n] ) {				// The section of the Query and Date Mengen...
        }
        else {							// ... must be non-empty ...
            DateCheckOK = 1;						// ... so that the search criteria match the recorded data
            break;
        }
    }
}

// ----------------------------------------------------------
// Das Resultat formatieren
// ----------------------------------------------------------

function FormatOutput() {
    with ( OUTPUT ) {
        writeln("<li><p>");						// CollSigle & Cote des Ms im Output einschreiben
        var i1 = Catalog[ms][FolderColl];					// adresse der betroffene FicheDescriptive des aktuellen Ms
        var i2 = Catalog[ms][FolderMs];

        write("<a href=\"javascript:ms_file=window.open('../../DATA/");
        write(i1 + "/" + i2 + "/CATALOG/FILE_EN.HTM','','width=440,resizable=yes,scrollbars=yes,status=yes');ms_file.focus()\">");

        write(Catalog[ms][NomCollPart] + " ");				// in case Cote=ArabicScript for LatinUser Cote in transliteration displayen
        if (Catalog[ms][CoteMsTranslit] == "-")
            writeln(Catalog[ms][CoteMsOrig] + "</a>");
        else
            writeln(Catalog[ms][CoteMsTranslit] + "</a>");
        writeln("</p></li>");
    }
}

// ----------------------------------------------------------
// Pourcentage fuer one field query
// ----------------------------------------------------------

function PourcentageBar() {
    with ( OUTPUT ) {
           var outOfRange = CatalogLength - QueryExistenz - naData;
           var queryPercent = Math.round((QueryExistenz/CatalogLength)*100);
           var outOfRangePercent = Math.round((outOfRange/CatalogLength)*100);
           var naDataPercent = Math.round((naData/CatalogLength)*100);

            writeln("<br>&nbsp<p><b>Percentage :</b>");
            write("<hr size=1 noshade width=250 align=left>");
            writeln("<table border=0 cellspacing=0 callpadding=0>");
								// --- Zahlen
            writeln("<tr><td align=right><b><font color=#800000 size=-2 face=\"Arial,Helvetica,Sans-Serif\"> ");
            write(QueryExistenz + "</b></font></td>");

            if ( outOfRange > 0 ) {
                write("<td align=right><b><font color=#3366FF size=-2 face=\"Arial,Helvetica,Sans-Serif\">");
                write(outOfRange + "</b></font></td>");
            }

            if ( naData > 0 )
                writeln("<td align=right><font color=#C0C0C0 size=-2 face=\"Arial,Helvetica,Sans-Serif\">" + naData + "</td>");
            
            writeln("<td><b><font size=-2 face=\"Arial,Helvetica,Sans-Serif\" color=\"#000000\">&nbsp;/ " +
            CatalogLength + " Mss</font></b></td></tr>");
								// --- Color Bars
            write("<tr style={line-height:5px;}><td WIDTH=\"");
            write(queryPercent + "%\" BGCOLOR=");
            if ( QueryExistenz == 0 )
                writeln("\"#0099CC\">");
            else

                writeln("\"#FF0080\">");
            writeln("&nbsp;</td>")

            if ( outOfRange > 0 ) {
                write("<td WIDTH=\"");
                write(outOfRangePercent);
                writeln("%\" BGCOLOR=\"#0099CC\">&nbsp;</td>");
            }

            if ( naData > 0 ) {
                write("<td WIDTH=\"");
                write(naDataPercent);
                writeln("%\" BGCOLOR=\"#C0C0C0\">&nbsp;</td>");
            }

            writeln("<td></td></tr>");
								// --- Pourcentage
            write("<tr><td align=right><font color=#800000 size=-2 face=\"Arial,Helvetica,Sans-Serif\">");
            write(queryPercent);
            writeln("%</font></td>");

            if ( outOfRange > 0 ) {
                write("<td align=right><font color=#3366FF size=-2 face=\"Arial,Helvetica,Sans-Serif\">");
                write(outOfRangePercent);
                writeln("%</font></td>");
            }

            if ( naData > 0 ) {
                write("<td align=right><font color=#C0C0C0 size=-2 face=\"Arial,Helvetica,Sans-Serif\">");
                write(naDataPercent);
                writeln("%</font></td>");
            }            
            writeln("<td><b><font size=-2 face=\"Arial,Helvetica,Sans-Serif\" color=\"#000000\">&nbsp;100%&nbsp;&nbsp;&nbsp;&nbsp;<font color=\"#FFFFFF\">.</font></font></b></td></tr></table>");
								// --- Legende
            writeln("<table border=0 cellspacing=5 cellpadding=0>");
            writeln("<tr align=left valign=baseline>");
            writeln("<td><img src=\"../../IMAGES/PTRED.GIF\" width=10 height=10></td>");
            writeln("<td><font style=\"font-size:8pt;\" color=\"#000000\">query found</font></td></tr>");

            writeln("<tr align=left valign=baseline>");
            writeln("<td><img src=\"../../IMAGES/PTBLUE.GIF\" width=10 height=10></td>");
            writeln("<td><font style=\"font-size:8pt;\" color=\"#000000\">data type exists in mss,");
            writeln("but with a different content from the query</font></td></tr>");

            writeln("<tr align=left valign=baseline>");
            writeln("<td><img src=\"../../IMAGES/PTGREY.GIF\" width=10 height=10></td>");
            writeln("<td><font style=\"font-size:8pt;\" color=\"#000000\">data not available in mss</font></td></tr>");

            writeln("<tr align=left valign=baseline>");
            writeln("<td><img src=\"../../IMAGES/PTBLACK.GIF\" width=10 height=10></td>");
            writeln("<td><font style=\"font-size:8pt;\" color=\"#000000\">total number of queried mss</font></td>");
            writeln("</tr></table>&nbsp;<br>");
    }
}

// =============================
// Output all availiable values of a field (Index)
// =============================

function IndexOutput(look) {
    var mss = 0;
    var QueryExistenz = 0;
    while (look.indexOf("_") != -1)					// Name ermitteln
        look = look.replace(/_/, " ");

    with ( OUTPUT )  {						// Ecriture de la liste des termes
        open();
        HTMLtop();
        write("<b>Index : " + look + "</b>");
        write("<hr size=1 noshade width=250 align=left>");

        if (IndexArray[0]) {
            writeln("<ol>");
            for (i = 0; i < IndexArray.length; i++) {
                var iOld = "";

                writeln("<li><p>");						// All terms of a field im Output einschreiben
                if (typeof(Dictionary[IndexArray[i][0]]) != "undefined" && 
                    descriptor != NomCollFullOrig && 
                    descriptor != NomCollFullTranslit && 
                    descriptor != CoteMsOrig && 
                    descriptor != CoteMsTranslit && 
                    descriptor != VilleCollOrig && 
                    descriptor != VilleCollTranslit && 
                    descriptor != AuteurOrig && 
                    descriptor != AuteurTranslit && 
                    descriptor != TitreOrig && 
                    descriptor != TitreTranslit && 
                    descriptor != LieuCopieVilleOrig && 
                    descriptor != LieuCopieVilleTranslit && 
                    descriptor != CopisteOrig && 
                    descriptor != CopisteTranslit && 
                    descriptor != DedicataireOrig && 
                    descriptor != DedicataireTranslit )
                    writeln(Dictionary[IndexArray[i][0]]);
                else
                    writeln(IndexArray[i][0]);

                writeln("<br><font size=-2>");
                for (j = 1; j < IndexArray[i].length; j++) {				// hervorkommende mss
                    var i1 = Catalog[IndexArray[i][j]][FolderColl];			// adresse der betroffene FicheDescriptive des aktuellen Ms...
                    var i2 = Catalog[IndexArray[i][j]][FolderMs];

                   if ( i1 + i2 != iOld ) {					// write ms name only if not already written
                        if ( j != 1 )
                            var del = ", ";
                        else
                            var del = " ";

                         var i3 = Catalog[IndexArray[i][j]][NomCollPart];		// ...und dessen namen
                         x = CoteMsOrig;
                         if ( Catalog[IndexArray[i][j]][CoteMsTranslit] != "-" ) { x = CoteMsTranslit };
                         var i4 = Catalog[IndexArray[i][j]][x];

                         write(del);
                         write("<a href=\"javascript:ms_file=window.open('../../DATA/");
                         write(i1 + "/" + i2 + "/CATALOG/FILE_EN.HTM','','width=440,resizable=yes,scrollbars=yes,status=yes');ms_file.focus()\">");
                         write(i3 + " " + i4 + "</a>");
                         mss++;
                     } 
                     iOld = i1 + i2; 
                 }

                writeln("<br>( ");                
                write(IndexArray[i].length - 1);				// Anzahl der Antworten fuer die jeweilige Frage
                if (IndexArray[i].length - 1 == 1)				// Plural setzen oder nicht
                    write(" occurence in ");
                else
                    write(" occurences in ");
                write(mss + " ms");
                if (mss > 1) { write("s"); }
                write(" out of " + CatalogLength + " )");
                writeln("</font></p></li>");
                mss = 0;
            }
            writeln("</ol>");
            QueryExistenz = 1;
       }
       if ( QueryExistenz == 0 )
           writeln("<p>Data not found.</p>");

       HTMLbottom();
       close();
    }
}

// ----------------------------------------------------------
// Determines all availiable values of a field
// ----------------------------------------------------------

function Index() {
    IndexArray = new Array();						// Bereiten fur a list of terms
    var len = IndexArray.length;
    var naData = 0;
    var temp = "";
    var IndexDateRecordY = 0;
    var StatistikDateRecordY = 0;
    var DataAbkzBis = "";
    var tempBis = "";
    var tempTer = "";
    if ( descriptor == DateRecordY )					// This introduces the code for the DataRecordY field
        IndexDateRecordY = 1;
								// Ecriture du array des termes
    for ( ms = 0; ms <= CatalogFin; ms++ ) {				// from ms to ms skippen
        DataAbkz = Catalog[ms][descriptor];
        if (DataAbkz == "" || 
            DataAbkz.charAt(0) == "-" || 
            DataAbkz.charAt(0) == "?" )
            naData++;
        if (DataAbkz != "" && 
            DataAbkz.charAt(0) != "-" && 
            DataAbkz.charAt(0) != "?" ) {
            if ( DataAbkz.charAt(DataAbkz.length-1) == ")" )			// Remarks ausschneiden
                DataAbkz = DataAbkz.substring(0,DataAbkz.lastIndexOf("(")-1);
            if ( IndexDateRecordY == 1 ) {
                DataAbkzBis = Catalog[ms][descriptor-1];
                if ( DataAbkz.charAt(DataAbkz.length-1) == ")" )			// Remarks ausschneiden
                    DataAbkzBis = DataAbkzBis.substring(0,DataAbkzBis.lastIndexOf("(")-1);
            }

            DataAbkzMultiple = new Array();				// transform multiple eintraege in list
            DataAbkz = DataAbkz + " ;";
            var i = 0;
            if ( IndexDateRecordY == 1 ) {
                DataAbkzMultipleBis = new Array();
                DataAbkzBis = DataAbkzBis + " ;";
            }

            while ( DataAbkz.indexOf(" ;") != -1 ) {
                temp = DataAbkz.substring(0,DataAbkz.indexOf(" ;"));
                DataAbkz = DataAbkz.substring(DataAbkz.indexOf(" ;")+3,DataAbkz.length);
                if ( IndexDateRecordY == 1 || StatistikDateRecordY == 1 ) {
                    tempBis = DataAbkzBis.substring(0,DataAbkzBis.indexOf(" ;"));
                    DataAbkzBis = DataAbkzBis.substring(DataAbkzBis.indexOf(" ;")+3,DataAbkzBis.length);
                }
                if ( temp == "*" )						// data to skip:
                    continue;						// "not cataloged data" & not AHq in case of Statistik of DateRecordY
                if ( IndexDateRecordY == 0 )
                    DataAbkzMultiple[i] = temp;
                else {
                    if ( temp.length < 4 ) {
                        for ( j = 1; j <= 4 - temp.length; j++ )
                            tempTer = tempTer + " ";
                     }
                    DataAbkzMultiple[i] = tempBis + " " + tempTer + temp;
                }
                i++;
                tempTer = "";
            }

            if ( i == 0 ) {							// catch ms with no data at all
                naData++;
                continue;
            }

            for ( j = 0; j < DataAbkzMultiple.length; j++ ) {			// im List Array nach term & ms# suchen
                for ( i = 0; i <= len; i++ ) {
	    len = IndexArray.length;
                    if ( !IndexArray[0] ) {					// creer la premiere entree
                        IndexArray[i] = new Array();
                        IndexArray[i][0] = DataAbkzMultiple[j];
                        IndexArray[i][1] = ms;
                        break;
                    }          
                    if ( IndexArray[i][0] == DataAbkzMultiple[j] ) {			// append ms# if term allready exists
                        IndexArray[i][IndexArray[i].length] = ms;
                        break;
                    }
                    if ( i == len - 1 ) {						// append new term if new
                        IndexArray[i+1] = new Array();
                        IndexArray[i+1][0] = DataAbkzMultiple[j];
                        IndexArray[i+1][1] = ms;
                        break;
                    }
                }
            }
        }
    }
    len = IndexArray.length;

    if (descriptor != SupportVergDens && 
        descriptor != DimSuppH && 
        descriptor != DimSuppW &&
        descriptor != DimSuppD && 
        descriptor != DimTexteH && 
        descriptor != DimTexteW &&
        descriptor != Folios && 
        descriptor != Cahiers && 
        descriptor != Lignes &&
        descriptor != Colonnes && 
        descriptor != Poids)						// sort as buchstaben
        IndexArray.sort();
    else {								// sort als numerics																// sort as chiffres
        for ( j = 0; j < len; j++ ) {
            if ( IndexArray[j][0].indexOf(",") != -1 )				// replace virgule with dot
                IndexArray[j][0] = IndexArray[j][0].replace(/,/,".");			// for different numerical format compability
        }
        for ( i = 1; i < len; i++ ) {						// bubble sorting
            for ( j = 0; j < len-1; j++ ) {
                if ( Number(IndexArray[j][0]) > Number(IndexArray[j+1][0]) ) {
                    temp = IndexArray[j+1];
                    IndexArray[j+1] = IndexArray[j];
                    IndexArray[j] = temp;
                }
            }
        }
        for ( j = 0; j < len; j++ ) {						// replace dot with comma
            if ( IndexArray[j][0].indexOf(".") != -1 )
            	IndexArray[j][0] = IndexArray[j][0].replace(/\./,",");
        }
    }
    return naData;
}

// =============================
// Distribution des data sur 100% scale
// =============================

function Statistik() {
    var minNr = 0;
    var maxNr = 0;
    var range = 0;
    var steps = 10;
    var total = 0;
    var temp = "";
    naData = 0;
    DateVectors = new Array();					// contains the DataRanges from all the Mss
    DateVectors[0] = new Array();					// minimum & ...
    DateVectors[1] = new Array();					// maximum of a date range
    var bin = 0;
    PercentArray = new Array();
    NombreRubriques = 0;
    QueryExistenz = 0;						// QueryArray in DataArray Flag
    QueryToDataEquivalenz()						// load eingabefield anordnung

    for ( i = 0; i < NombreRubriques; i++ ) {				// etablieren asked statistiks fields
        if ( QueryEqvDataFieldsNr[i] == descriptor ) {
            while ( NameStatistikField.indexOf("_") != -1 )			// Name formatieren
            	NameStatistikField = NameStatistikField.replace(/_/, " ");
             break;
        }
     }

    if (descriptor == DateRecordY ||
        descriptor == DateEquivAdY ||
        descriptor == DateVraisembla ) {					// --- 1. Date numeric fields
								// ----------------------------------------------------------------
        minNr = Number(INPUT.forms[0].elements[i].value);			// get min & max range fields
        maxNr = Number(INPUT.forms[0].elements[i+1].value);

        if ( descriptor == DateEquivAdY &&
            minNr == 0 && maxNr == 0 ) {					// default range for equivalent AD dates
            if ( minNr == "" ) { minNr = 600 }
            if ( maxNr == "" ) { maxNr = 1999 }
            if ( minNr == "600" && maxNr == "1999" ) { steps = 14 }
        }

        QueryRangeMin = Number.MIN_VALUE;           			// default range for building the vector array
        QueryRangeMax = Number.MAX_VALUE;

        for ( ms = 0; ms <= CatalogFin; ms++ ) {
            DataAbkz = Catalog[ms][descriptor];				// build a vector array of all the dates in the mss files

            if ( DataAbkz.charAt(DataAbkz.length-1) == ")" )			// remove remarks at end of lines
                DataAbkz = DataAbkz.substring(0,DataAbkz.lastIndexOf("(")-1);

            if ( DataAbkz == "-" || DataAbkz == "?" || DataAbkz == "*" ) {		// search for 'non available data'
                naData++;
                continue;
            }

            while( DataAbkz.indexOf(" ;") != -1 ) {				// multiple data per field
                temp = DataAbkz;
                DataAbkz = DataAbkz.substring( 0, DataAbkz.indexOf(" ;") );
                DateCheck();						// make list of date ranges for individual mss...
                DateVectors[0].push(DateRanges[0]);				// ... and add them to a general list
                DateVectors[1].push(DateRanges[1]);
                DataAbkz = temp.substring( temp.indexOf(" ;")+3, temp.length );
            }
            DateCheck();
            DateVectors[0].push(DateRanges[0]);
            DateVectors[1].push(DateRanges[1]);
            if ( DateCheckOK == 1 )
                QueryExistenz++;
        }

        if ( minNr == 0 && maxNr == 0 ) {					// in case no date range given in query,
            minNr = Number( DateVectors[0][0] );					// establish it from the data limits
            maxNr = Number( DateVectors[1][0] );
            for ( i = 1; i < DateVectors[0].length; i++ ) {				// find min & max
                if ( Number( DateVectors[0][i] ) < minNr )
                    minNr = Number( DateVectors[0][i] );
                if ( Number( DateVectors[1][i] ) > maxNr )
                    maxNr = Number( DateVectors[1][i] );
            }
        }
        range = maxNr - minNr + 1;

        for ( i = 0; i < steps; i++ )						// Bar-array set to zero
            PercentArray[i] = 0;

        for ( i = 0; i < DateVectors[0].length; i++ ) {				// Load array with data
            for ( bin = 1; bin <= steps; bin++ ) {				// for all bins...

                binMin = minNr + ( range/steps ) * ( bin-1 );

                binMax = binMin + range/steps - 1;				// bin goes from lower limit to the upper -1
                if ( bin == steps )						// the highest bin includes also the upper range limit
                    binMax = binMin + range/steps;


                if ( binMin > DateVectors[1][i] || 

                    binMax < DateVectors[0][i] ) {				// ... check if current date range overlaps current bin

                }

                else
                    PercentArray[bin-1]++;       	         				// if yes, write results in PercentArray
            }
        }
    }
    else {								// --- 2. Non-date numeric fields
								// ----------------------------------------------------------------
        naData = Index(descriptor);					// faire un array avec toutes les valeurs du champ

        if ( IndexArray[0] ) {						// go on if index has data
            minNr = Number( INPUT.forms[0].elements[i].value );		// trouver les min & max
            maxNr = Number( INPUT.forms[0].elements[i+1].value );

            if ( minNr == 0 && maxNr == 0 ) {				// default range is set by the data range
                minNr = Number( IndexArray[0][0].replace( /,/, "." ) );
                maxNr = minNr;
                for ( i = 1; i < IndexArray.length; i++ ) {				// get min and max numbers from data
                    k = Number( IndexArray[i][0].replace( /,/, "." ) );
                    if ( k < minNr )
	        minNr = k;
                    if ( k > maxNr )
                        maxNr = k;
                }
            }
            range = maxNr - minNr;

            for ( i = 0; i < steps; i++ )					// Bar-array set to zero
                PercentArray[i] = 0;

            for ( i = 0; i < IndexArray.length; i++ ) {				// Load array with data
                k = Number( IndexArray[i][0].replace( /,/, "." ) );
                if (k >= minNr &&
                    k <= maxNr ) {
                    bin = parseInt( ( k - minNr ) * steps / range ); 			// find to which bin it belongs
                    if ( bin == steps )
                        bin = steps - 1;					// last bin includes upper limit too

                    n = IndexArray[i].length-1;					// write results in PercentArray
                    PercentArray[bin]+=n;                
								// find the number of diffrent mss in this range
                    for ( j = 1; j < IndexArray[i].length; j++ ) {			// check if current data exists in tempArray _***,
                        if ( temp.indexOf(" " + IndexArray[i][j] + ",") == -1 )		// if yes skip
                           temp = temp + " " + IndexArray[i][j] +",";			// if not append data
                    }
                }
            }
        }

        while ( temp.indexOf(",") != -1 ) {					// outside loop calculate nbr. QueryExistenz
            QueryExistenz++;
            temp = temp.replace( /,/, "" );
        }
    }

    if ( PercentArray.length > 0 ) {					// ---- 3. Transform bin frequency to percentage
        for ( i = 0; i < steps; i++ )						// ----------------------------------------------------------------
            total = total + PercentArray[i];					// total of datas for the range
        
        for ( i = 0; i < steps; i++ ) {					// distribute in bins of steps/100
            var barLength = String(( PercentArray[i] * 100 ) / total );		// Integer function
            barLength = Math.floor(barLength);
            PercentArray[i] = barLength;
        }
    }

    with ( OUTPUT ) {						// --- 4. Output der statistik
        open();							// ----------------------------------------------------------------
        HTMLtop();
        writeln("<b>Statistics:</b>");
        write("<hr size=1 noshade width=250 align=left><p></p>");

        if ( PercentArray.length > 0 ) {
            writeln("<font style=\"font-size:8pt\">" + NameStatistikField + "</font><br>");
            writeln("<table><tr><td align=right><font color=\"#000000\">");
            writeln(Number(maxNr) + " -<br>");

            for ( i = steps-1; i >= 0; i-- ) {					// 1. Dates
                n = Number(minNr) + i*range/steps;
                if ( range > steps )
                    n = Math.floor( n );					// increase digits if range extremities too close
                temp = 0;							// integer numbers
    	if (descriptor != DateRecordY && 
                    descriptor != DateEquivAdY && 
                    descriptor != DateVraisembla && 
        	    descriptor != Folios && 
                    descriptor != Cahiers && 
                    descriptor != Lignes &&
        	    descriptor != Colonnes )
                    temp = 1;						// one decimal numbers
	write(n.toFixed(temp) + " -<br>");
            }
            writeln("</td><td>");

            for ( i = steps-1; i >= 0; i-- ) {					// 2. Bars & Values of fields
                n = Math.round(PercentArray[i]);
                if ( n != 0 ) {
                    write(" <img src=\"../../IMAGES/PTRED.GIF\" width=");
                    write(n);
                    writeln(" height=5> ");
                }
                write("<font size=-2 color=\"#000000\">" + n);
                writeln("%</font>&nbsp;<br>");
            }
            writeln("</td></tr></table>");
            writeln("<font style=\"font-size:8pt\">100% = " + total + " occurences (in " + QueryExistenz + " mss)</font>");
        }
        else
        writeln("<p>Query not found.</p>");

        PourcentageBar();
        HTMLbottom();
        close();
    }
    NameStatistikField = "";
}
