/*
 * Enumeration class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */

var undefined;

/** 
*/
function hasMoreElementsEnumeration() {

	return (this.idx+1 < this.array.length);
}

/** 
*/
function nextElementEnumeration() {

	this.idx++;
	return this.array[this.idx];
}

/** 
*/
function getArrayEnumeration() {

	return this.array;
}

/** 
*/
function getSizeEnumeration() {

	return this.array.length;
}

/** 
*/
function initEnumeration() {

	this.idx = -1;
}


/** 
Constructor
*/
function Enumeration(tab) {

	this.array = tab;

	this.hasMoreElements = hasMoreElementsEnumeration;
	this.nextElement = nextElementEnumeration;
	this.getArray = getArrayEnumeration;
	this.getSize = getSizeEnumeration;
	this.init = initEnumeration;

	this.init();
}



/*
 * HashTable class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */

/** 
*/
function putHashTable(key, value) {

	this[key] = value;
}

/** 
*/
function getHashTable(key) {

	return this[key];
}

/** 
Constructor
*/
function HashTable() {

	this.get = getHashTable;
	this.put = putHashTable;
}


/*
 * Stack class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */

/** 
*/
function emptyStack() {

	return (this.idx < 0);
}

/** 
*/
function popStack() {

	if (this.idx >= 0) {
		value = this.array[this.idx];
		this.idx--;
		return value;
	}
	else return null;
}

/** 
*/
function pushStack(value) {

	this.idx++;
	this.array[this.idx] = value;
}

/** 
*/
function getArrayStack() {

	return this.array;
}


/** 
*/
function sizeStack() {

	return this.idx + 1;
}


/** 
*/
function elementsStack() {

	return new Enumeration(this.array);
}

/** 
Constructor
*/
function Stack() {

	this.array = new Array();

	this.empty = emptyStack;
	this.pop = popStack;
	this.push = pushStack;
	this.elements = elementsStack;
	this.getArray = getArrayStack;
	this.size = sizeStack;

	this.idx = -1;
}





/*
 * StringTokenizer class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */

/** 
*/
function hasMoreTokensStringTokenizer() {

	return (this.idx+1 < this.array.length);
}

/** 
*/
function nextTokenStringTokenizer() {

	this.idx++;
	return this.array[this.idx];
}

/** 
*/
function elementsStringTokenizer() {

	return new Enumeration(this.array);
}

/** 
*/
function getArrayStringTokenizer() {

	return this.array;
}

/** 
*/
function splitStringTokenizer(string, delimit) {

	if (string == null)
		return new Array();
	else if (delimit == null)
		return new Array(string);

	var tab;
	tab = new Array();
	var idx = 0, token;

	for (var i=0; i < string.length; ) {
		token = "";
		for (; i < string.length && delimit.indexOf(string.charAt(i)) == -1; i++) {
			token = token + string.charAt(i);
		}
		if (token.length > 0) {
			tab[idx++] = token;
		}
		for (; i < string.length && delimit.indexOf(string.charAt(i)) >= 0; i++);
	}

	return tab;
}


/** 
Constructor
*/
function StringTokenizer(string, delimit, keep) {

	this.hasMoreTokens = hasMoreTokensStringTokenizer;
	this.nextToken = nextTokenStringTokenizer;
	this.elements = elementsStringTokenizer;
	this.getArray = getArrayStringTokenizer;
	this.split = splitStringTokenizer;

	var tab;
	if (keep) {
		tab = new Array();
		idx = 0;
		for (var i=0; i < string.length; ) {
			token = "";
			for (; i < string.length && delimit.indexOf(string.charAt(i)) == -1; i++) {
				token = token + string.charAt(i);
			}
			if (token.length > 0) {
				tab[idx++] = token;
			}
			for (; i < string.length && delimit.indexOf(string.charAt(i)) >= 0; i++) {
				tab[idx++] = string.charAt(i);
			}
		}
	}
	else	tab = this.split(string, delimit);

	this.array = tab;

	this.idx = -1;
}


/*
 * Unicode class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */



/** 
*/
function charCodeUnicode(string, i) {

	var cc = string.charCodeAt(i);
	if (cc < 0)
		return (cc + 256); // for netscape 4 bug (?)
	else	return cc;
}

/** 
*/
function codeUnicode(string) {

	var c, unicodeString = "";
	for (var i=0; i < string.length; i++) {
		unicodeString += String.fromCharCode(this.charCode(string, i));
	}
	return unicodeString;
}

/** 
Constructor
*/
function Unicode() {

	this.code = codeUnicode;
	this.charCode = charCodeUnicode;
}


/*
 * Mycoding class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */

/** 
*/
function codeMycoding(string) {

	var newString = string.replace(/\"/g, '{');
	newString = newString.replace(/\'/g, '}');
	newString = newString.replace(/&#34;/g, '{');
	newString = newString.replace(/&#39;/g, '}');
	return newString;
}

/** 
*/
function decodeMycoding(string) {

	var newString = string.replace(/{/g, '"');
	newString = newString.replace(/}/g, "'");
	return newString;
}

/** 
Constructor
*/
function Mycoding() {

	this.code = codeMycoding;
	this.decode = decodeMycoding;
}
















/**
*/
function getOrdIndexReader(word) {


	var l = 0, h = this.lexicon.length, c = 0;

	while ((h-l) > 1) {
		c = Math.floor((l+h) / 2);
		if (word < this.lexicon[c]) {
			h = c;
		}
		else {
			l = c;
		}
	}
	return l;
}


/**
*/
function getDocsIndexReader(word) {

	var ord = this.getOrd(word);

	var wordGroupTable = this.wordGroupTableHash.get(ord);
	var docSetTable = this.docSetTableHash.get(ord);

	var g = 0;
	for (; g < wordGroupTable.length && word > wordGroupTable[g][0]; g++);

	if (g < wordGroupTable.length && word == wordGroupTable[g][0]) {

		var nDocs = wordGroupTable[g][1];
		var ptr = wordGroupTable[g][2];
		var docs = new Array(nDocs);
		for (var d=0, i=ptr; d < nDocs; d++, i++) {
			docs[d] = docSetTable[i];
		}
		return docs;
	}
	else {
		return new Array();
	}
}

/** 
Constructor
*/
function IndexReader(lex, wgtH, dstH) {

	this.lexicon = lex;
	this.wordGroupTableHash = wgtH;
	this.docSetTableHash = dstH;

	this.getOrd = getOrdIndexReader;
	this.getDocs = getDocsIndexReader;
}









/*
 * Standardizer class
 *
 * Copyright 2008 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */


/**
static
*/
	var delimiter		= "_";

        var ARABIC		= "Arabic";

        var ARABIC_COMMA	= String.fromCharCode(1548);

        var ALIF_LAM 		= String.fromCharCode(1575) + String.fromCharCode(1604);

        var ALIF 		= String.fromCharCode(1575);
        var ALIF_VAR 		= String.fromCharCode(1571);
        var MAD 		= String.fromCharCode(1600);
        var CHADDA 		= String.fromCharCode(1617);

        var ALIF_HAMZA_ABOVE    = ALIF_VAR;
        var ALIF_HAMZA_BELOW    = String.fromCharCode(1573);
        var ALIF_MADDAH         = String.fromCharCode(1570);
	var MIN_CHARKL_CODE	= 1611;
	var MAX_CHARKL_CODE	= 1618;

/**
*/
function getNameStandardizer() {

	return this.standardizerName;
}

/**
*/
function standardizeWordStandardizer(string) {

	// trim
	var begin = 0, end = string.length-1;
	var nulls = " \t\n\r\f";
	for (; begin < string.length && nulls.indexOf(string.charAt(begin)) != -1; begin++);
	for (; end >= 0 && nulls.indexOf(string.charAt(end)) != -1; end--);

	// convert chars to standard chars
	var standString = "";
	var p, c, cc;
	for (var i=begin; i <= end; i++) {

		cc = charCodeUnicode(string, i);

		if (this.convTable[cc] != undefined)
			c = String.fromCharCode(this.convTable[cc]);
		else	c = string.charAt(i);

		if (c == ALIF_VAR || c == ALIF_HAMZA_BELOW || c == ALIF_MADDAH) {
			c = ALIF;
		}

		if (c != MAD && (cc < MIN_CHARKL_CODE || cc > MAX_CHARKL_CODE)) {
			standString = standString + c;
		}
	}
	
	if (this.standardizerName.indexOf("Text") != -1) { 
		if (standString.indexOf(ALIF_LAM) == 0) {
			standString = standString.substring(2);
		}
		if (standString.length > 0 && standString.charAt(standString.length-1) == "s") {
			standString = standString.substring(0, standString.length-1);
		}
	}
	
	if (this.isForbiddenWord(standString))
		return "";
	else	return standString;
}

/**
*/
function getWordsStandardizer(text) {

	var s = this.withoutSeparator(text);
	return new StringTokenizer(s, ' ', false);
}

/**
create a string separators replaced by ' '
*/
function withoutSeparatorStandardizer(text) {

	var s = "";
	for (var i=0; i < text.length; i++) {
		c = text.charAt(i);
		if (this.isSeparator(c))	c = ' ';
		s = s + c;
	}
	return s;
}

/**
*/
function getEquivalentsVectorStandardizer(word) {

	var equivs = new Array();
	var ew = this.equivDictionary.get(word);
	if (ew != null) {
		var st = new StringTokenizer(ew, delimiter, false);
		while (st.hasMoreTokens()) {
			equivs.push(st.nextToken());
		}
	}
	return equivs;
}

/**
*/
function isNullLetterStandardizer(c) {

	return  c.length == 1 && nullLetters.indexOf(c) != -1;
}

/**
*/
function trimStandardizer(string) {

	var begin = 0, end = string.length-1;
	for (; begin < string.length && this.isNullLetter(string.charAt(begin)); begin++);
	for (; end >= 0 && this.isNullLetter(string.charAt(end)); end--);

	if (begin <= end) return string.substring(begin, end+1);
	else	return "";
}

/**
*/
function parseCorrectNameStandardizer(term) {

	var slash = term.indexOf('/');
	if (slash > 0) {
		return term;
	}

	var dot = term.lastIndexOf(','), lastname, firstname;
	if (dot < 0) {
		dot = term.lastIndexOf(ARABIC_COMMA);
	}
	if (dot > 0) {
                lastname = this.trim(term.substring(0,dot));
                firstname = this.trim(term.substring(dot+1));
                return lastname + "/" + firstname;
	}
	return term;
}

/**
*/
function parseHypo1NameStandardizer(term) {

	var pos = term.lastIndexOf(' ');
	if (pos > 0) {
                firstname = term.substring(0,pos);
                lastname = term.substring(pos+1);
                return lastname + "/" + firstname;
	}
	else	return term;
}

/**
*/
function parseHypo2NameStandardizer(term) {

	var pos = term.lastIndexOf(' ');
	if (pos > 0) {
                part = term.substring(0,pos);
                lastname2 = term.substring(pos+1);
		pos = part.lastIndexOf(' ');
		if (pos > 0) {
			firstname = part.substring(0,pos);
			lastname1 = part.substring(pos+1);
	                return lastname1 + " " + lastname2 + "/" + firstname;
		}
	}
	return term;
}

/**
*/
function addWithEquivalentsStandardizer(equivs, word) {

	equivs.push(word);
	var eq = this.getEquivalentsVector(word);
	if (eq.length > 0) {
		equivs = equivs.concat(eq);
	}
	return equivs;
}

/**
*/
function addAlternativesStandardizer(equivs, word) {

	if ((p=word.indexOf('/')) != -1) {
		var namePart1 = word.substring(0, p);
		var namePart2 = word.substring(p+1);
		equivs = this.addWithEquivalents(equivs, namePart2 + '/' + namePart1);
		equivs = this.addWithEquivalents(equivs, namePart1 + ' ' + namePart2); // no first name 
		equivs = this.addWithEquivalents(equivs, namePart2 + ' ' + namePart1); // no first name
	}
	return equivs;
}

/**
*/
function getEquivalentsStandardizer(word) {

	var i, p;

	var equivs = this.getEquivalentsVector(word);
	i = equivs.length;

	if (this.standardizerName.indexOf("Key") != -1) {
		if ((p=word.indexOf('/')) != -1)
			equivs[i++] = word.substring(0, p);
	}
	else if (this.standardizerName.indexOf("Name") != -1) {
		var nword = this.parseCorrectName(word);
		if (word != nword) {
			equivs = this.addWithEquivalents(equivs, nword);
		}
		word = nword;
		if ((p=word.indexOf('/')) != -1) {
			equivs = this.addAlternatives(equivs, word);
		} else {
			var aword = this.parseHypo1Name(word);
			equivs = this.addWithEquivalents(equivs, aword);
			equivs = this.addAlternatives(equivs, aword);
			aword = this.parseHypo2Name(word);
			equivs = this.addWithEquivalents(equivs, aword);
			equivs = this.addAlternatives(equivs, aword);
		}
	}
	return new Enumeration(equivs);
}

/**
*/
function isSeparatorStandardizer(c) {

	var i = charCodeUnicode(c, 0);
	return (this.separatorTable[i] != undefined)
}

/**
*/
function containsSeparatorStandardizer(s) {

	var i = 0, l = s.length;
	for (; i < l && !this.isSeparator(s.charAt(i)); i++);
	return i < l;
  }


/**
*/
function isForbiddenWordStandardizer(word) {

	return this.forbidWordSet.get(word) != null;
}

/**
*/
function getCharWritingStandardizer(c) {

	var i = charCodeUnicode(c, 0);
// A FAIRE améliorer le test unicode
	if ((i >= 1563 && i <= 1957) || (i >= 64336 && i <= 65276))
		return ARABIC;
	else	return null;
}

/**
*/
function getWritingStandardizer(s) {

	var w, writing = null;
	for (var i=0; i < s.length; i++)
		if ((w=getCharWritingStandardizer(s.charAt(i))) != null)
			writing = w;
	return writing;	

}


/** 
Constructor
*/
function Standardizer(standTab) {


	this.standardizerName = standTab[0];

	this.standType = standTab[1];

	defaultCharsStand = getDelimitersSearchQuery().split("");
	defaultStandChars = new Array(defaultCharsStand.length);
	for (i=0; i < l; i++) defaultStandChars[i] = " ";

	this.charsStand = defaultCharsStand.concat(standTab[2][0]);
	this.standChars = defaultStandChars.concat(standTab[2][1]);
	
//	this.charsStand += ALIF_VAR;
//	this.standChars += ALIF;
	
	this.separators = standTab[3];

	var forbidden = standTab[4];
	this.forbidWordSet = new HashTable();
	for (i=0; i < forbidden.length; i++)
		this.forbidWordSet.put(forbidden[i], this.forbidWordSet);

	this.equivDictionary = new HashTable();
	for (i=5; i < standTab.length; i++) {
		this.equivDictionary.put(standTab[i][0], standTab[i][1]);
		this.equivDictionary.put(standTab[i][1], standTab[i][0]);
	}

	this.getName = getNameStandardizer;
	this.standardizeWord = standardizeWordStandardizer;
	this.getWords = getWordsStandardizer;
	this.withoutSeparator = withoutSeparatorStandardizer;
	this.getEquivalentsVector = getEquivalentsVectorStandardizer;
	this.getEquivalents = getEquivalentsStandardizer;
	this.isSeparator = isSeparatorStandardizer;
	this.containsSeparator = containsSeparatorStandardizer;
	this.isForbiddenWord = isForbiddenWordStandardizer;
	this.getCharWriting = getCharWritingStandardizer;
	this.getWriting = getWritingStandardizer;
	this.parseCorrectName = parseCorrectNameStandardizer;
	this.parseHypo1Name = parseHypo1NameStandardizer;
	this.parseHypo2Name = parseHypo2NameStandardizer;
	this.trim = trimStandardizer;
	this.isNullLetter = isNullLetterStandardizer;
	this.addWithEquivalents = addWithEquivalentsStandardizer;
	this.addAlternatives = addAlternativesStandardizer;

	var table = new Array(), c;
	for (var i=0, l=this.charsStand.length; i < l; i++) {
		c = this.charsStand[i];
		table[c] = this.standChars[i];
	}
	this.convTable = table;

	table = new Array();
	for (var i=0, l=this.separators.length; i < l; i++) {
		c = this.separators[i];
		table[c] = true;
	}
	this.separatorTable = table;
}





/*
 * HTML class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */


/**
static
*/
	var codes = new HashTable();
	var MAX_VALUE = 10000;
	var codesR = new Array(MAX_VALUE);

	for (var c=0; c < MAX_VALUE; c++) {
		codesR[c] = String.fromCharCode(c);
	}

        addHTML("&nbsp;",   160); 
        addHTML("&iexcl;",  161); 
        addHTML("&cent;",   162); 
        addHTML("&pound;",  163); 
        addHTML("&curren;", 164); 
        addHTML("&yen;",    165); 
        addHTML("&brvbar;", 166); 
        addHTML("&sect;",   167); 
        addHTML("&uml;",    168); 
        addHTML("&copy;",   169); 
        addHTML("&ordf;",   170); 
        addHTML("&laquo;",  171); 
        addHTML("&not;",    172); 
        addHTML("&shy;",    173); 
        addHTML("&reg;",    174); 
        addHTML("&macr;",   175); 
        addHTML("&deg;",    176); 
        addHTML("&plusmn;", 177); 
        addHTML("&sup2;",   178); 
        addHTML("&sup3;",   179); 
        addHTML("&acute;",  180); 
        addHTML("&micro;",  181); 
        addHTML("&para;",   182); 
        addHTML("&middot;", 183); 
        addHTML("&cedil;",  184); 
        addHTML("&sup1;",   185); 
        addHTML("&ordm;",   186); 
        addHTML("&raquo;",  187); 
        addHTML("&frac14;", 188); 
        addHTML("&frac12;", 189); 
        addHTML("&frac34;", 190); 
        addHTML("&iquest;", 191); 
        addHTML("&Agrave;", 192); 
        addHTML("&Aacute;", 193); 
        addHTML("&Acirc;",  194); 
        addHTML("&Atilde;", 195); 
        addHTML("&Auml;",   196); 
        addHTML("&Aring;",  197); 
        addHTML("&AElig;",  198); 
        addHTML("&Ccedil;", 199); 
        addHTML("&Egrave;", 200); 
        addHTML("&Eacute;", 201); 
        addHTML("&Ecirc;",  202); 
        addHTML("&Euml;",   203); 
        addHTML("&Igrave;", 204); 
        addHTML("&Iacute;", 205); 
        addHTML("&Icirc;",  206); 
        addHTML("&Iuml;",   207); 
        addHTML("&ETH;",    208); 
        addHTML("&Ntilde;", 209); 
        addHTML("&Ograve;", 210); 
        addHTML("&Oacute;", 211); 
        addHTML("&Ocirc;",  212); 
        addHTML("&Otilde;", 213); 
        addHTML("&Ouml;",   214); 
        addHTML("&times;",  215); 
        addHTML("&Oslash;", 216); 
        addHTML("&Ugrave;", 217); 
        addHTML("&Uacute;", 218); 
        addHTML("&Ucirc;",  219); 
        addHTML("&Uuml;",   220); 
        addHTML("&Yacute;", 221); 
        addHTML("&THORN;",  222); 
        addHTML("&szlig;",  223); 
        addHTML("&agrave;", 224); 
        addHTML("&aacute;", 225); 
        addHTML("&acirc;",  226); 
        addHTML("&atilde;", 227); 
        addHTML("&auml;",   228); 
        addHTML("&aring;",  229); 
        addHTML("&aelig;",  230); 
        addHTML("&ccedil;", 231); 
        addHTML("&egrave;", 232); 
        addHTML("&eacute;", 233); 
        addHTML("&ecirc;",  234); 
        addHTML("&euml;",   235); 
        addHTML("&igrave;", 236); 
        addHTML("&iacute;", 237); 
        addHTML("&icirc;",  238); 
        addHTML("&iuml;",   239); 
        addHTML("&eth;",    240); 
        addHTML("&ntilde;", 241); 
        addHTML("&ograve;", 242); 
        addHTML("&oacute;", 243); 
        addHTML("&ocirc;",  244); 
        addHTML("&otilde;", 245); 
        addHTML("&ouml;",   246); 
        addHTML("&divide;", 247); 
        addHTML("&oslash;", 248); 
        addHTML("&ugrave;", 249); 
        addHTML("&uacute;", 250); 
        addHTML("&ucirc;",  251); 
        addHTML("&uuml;",   252); 
        addHTML("&yacute;", 253); 
        addHTML("&thorn;",  254); 
        addHTML("&yuml;",   255); 
        addHTML("&fnof;",   402); 
        addHTML("&Alpha;",  913); 
        addHTML("&Beta;",   914); 
        addHTML("&Gamma;",  915); 
        addHTML("&Delta;",  916); 
        addHTML("&Epsilon;",917); 
        addHTML("&Zeta;",   918); 
        addHTML("&Eta;",    919); 
        addHTML("&Theta;",  920); 
        addHTML("&Iota;",   921); 
        addHTML("&Kappa;",  922); 
        addHTML("&Lambda;", 923); 
        addHTML("&Mu;",     924); 
        addHTML("&Nu;",     925); 
        addHTML("&Xi;",     926); 
        addHTML("&Omicron;",927); 
        addHTML("&Pi;",     928); 
        addHTML("&Rho;",    929); 
        addHTML("&Sigma;",  931); 
        addHTML("&Tau;",    932); 
        addHTML("&Upsilon;",933); 
        addHTML("&Phi;",    934); 
        addHTML("&Chi;",    935); 
        addHTML("&Psi;",    936); 
        addHTML("&Omega;",  937); 
        addHTML("&alpha;",  945); 
        addHTML("&beta;",   946); 
        addHTML("&gamma;",  947); 
        addHTML("&delta;",  948); 
        addHTML("&epsilon;",949); 
        addHTML("&zeta;",   950); 
        addHTML("&eta;",    951); 
        addHTML("&theta;",  952); 
        addHTML("&iota;",   953); 
        addHTML("&kappa;",  954); 
        addHTML("&lambda;", 955); 
        addHTML("&mu;",     956); 
        addHTML("&nu;",     957); 
        addHTML("&xi;",     958); 
        addHTML("&omicron;",959); 
        addHTML("&pi;",     960); 
        addHTML("&rho;",    961); 
        addHTML("&sigmaf;", 962); 
        addHTML("&sigma;",  963); 
        addHTML("&tau;",    964); 
        addHTML("&upsilon;",965); 
        addHTML("&phi;",    966); 
        addHTML("&chi;",    967); 
        addHTML("&psi;",    968); 
        addHTML("&omega;",  969); 
        addHTML("&thetasym;",977); 
        addHTML("&upsih;",  978); 
        addHTML("&piv;",    982); 
        addHTML("&bull;",   8226); 
        addHTML("&hellip;", 8230); 
        addHTML("&prime;",  8242); 
        addHTML("&Prime;",  8243); 
        addHTML("&oline;",  8254); 
        addHTML("&frasl;",  8260); 
        addHTML("&weierp;", 8472); 
        addHTML("&image;",  8465); 
        addHTML("&real;",   8476); 
        addHTML("&trade;",  8482); 
        addHTML("&alefsym;",8501); 
        addHTML("&larr;",   8592); 
        addHTML("&uarr;",   8593); 
        addHTML("&rarr;",   8594); 
        addHTML("&darr;",   8595); 
        addHTML("&harr;",   8596); 
        addHTML("&crarr;",  8629); 
        addHTML("&lArr;",   8656); 
        addHTML("&uArr;",   8657); 
        addHTML("&rArr;",   8658); 
        addHTML("&dArr;",   8659); 
        addHTML("&hArr;",   8660); 
        addHTML("&forall;", 8704); 
        addHTML("&part;",   8706); 
        addHTML("&exist;",  8707); 
        addHTML("&empty;",  8709); 
        addHTML("&nabla;",  8711); 
        addHTML("&isin;",   8712); 
        addHTML("&notin;",  8713); 
        addHTML("&ni;",     8715); 
        addHTML("&prod;",   8719); 
        addHTML("&sum;",    8721); 
        addHTML("&minus;",  8722); 
        addHTML("&lowast;", 8727); 
        addHTML("&radic;",  8730); 
        addHTML("&prop;",   8733); 
        addHTML("&infin;",  8734); 
        addHTML("&ang;",    8736); 
        addHTML("&and;",    8743); 
        addHTML("&or;",     8744); 
        addHTML("&cap;",    8745); 
        addHTML("&cup;",    8746); 
        addHTML("&int;",    8747); 
        addHTML("&there4;", 8756); 
        addHTML("&sim;",    8764); 
        addHTML("&cong;",   8773); 
        addHTML("&asymp;",  8776); 
        addHTML("&ne;",     8800); 
        addHTML("&equiv;",  8801); 
        addHTML("&le;",     8804); 
        addHTML("&ge;",     8805); 
        addHTML("&sub;",    8834); 
        addHTML("&sup;",    8835); 
        addHTML("&nsub;",   8836); 
        addHTML("&sube;",   8838); 
        addHTML("&supe;",   8839); 
        addHTML("&oplus;",  8853); 
        addHTML("&otimes;", 8855); 
        addHTML("&perp;",   8869); 
        addHTML("&sdot;",   8901); 
        addHTML("&lceil;",  8968); 
        addHTML("&rceil;",  8969); 
        addHTML("&lfloor;", 8970); 
        addHTML("&rfloor;", 8971); 
        addHTML("&lang;",   9001); 
        addHTML("&rang;",   9002); 
        addHTML("&loz;",    9674); 
        addHTML("&spades;", 9824); 
        addHTML("&clubs;",  9827); 
        addHTML("&hearts;", 9829); 
        addHTML("&diams;",  9830); 
        addHTML("&quot;",   34); 
        addHTML("&amp;",    38); 
        addHTML("&lt;",     60); 
        addHTML("&gt;",     62); 
        addHTML("&OElig;",  338); 
        addHTML("&oelig;",  339); 
        addHTML("&Scaron;", 352); 
        addHTML("&scaron;", 353); 
        addHTML("&Yuml;",   376); 
        addHTML("&circ;",   710); 
        addHTML("&tilde;",  732); 
        addHTML("&ensp;",   8194); 
        addHTML("&emsp;",   8195); 
        addHTML("&thinsp;", 8201); 
        addHTML("&zwnj;",   8204); 
        addHTML("&zwj;",    8205); 
        addHTML("&lrm;",    8206); 
        addHTML("&rlm;",    8207); 
        addHTML("&ndash;",  8211); 
        addHTML("&mdash;",  8212); 
        addHTML("&lsquo;",  8216); 
        addHTML("&rsquo;",  8217); 
        addHTML("&sbquo;",  8218); 
        addHTML("&ldquo;",  8220); 
        addHTML("&rdquo;",  8221); 
        addHTML("&bdquo;",  8222); 
        addHTML("&dagger;", 8224); 
        addHTML("&Dagger;", 8225); 
        addHTML("&permil;", 8240); 
        addHTML("&lsaquo;", 8249); 
        addHTML("&rsaquo;", 8250); 
        addHTML("&euro;",   8364); 


/**
*/
function addHTML(entity, value) {

	codes.put(entity, value); 
	codesR[value] = entity;
}

/**
*/
function decodeEntityHTML(entity) {

	var c = null;
	if (entity.charAt(1) == '#') { 
		var start = 2, stop = entity.length - 1;
		var radix = 10; 
		if (entity.charAt(2) == 'X' || entity.charAt(2) == 'x') { 
			start++; 
			radix = 16; 
		} 
		c = parseInt(entity.substring(start, stop), radix); 
	} 
	else	c = codes.get(entity); 

	return c; 
}

/** 
Constructor
*/
function HTML() {

	this.decodeEntity = decodeEntityHTML;
}



/*
 * Data class
 *
 * Copyright 2001 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet, 
 * Use is subject to license terms.
 * 
 */

/** 
static
*/


/** 
*/
function blocAtData(pos) {

	return this.data[pos];
}

/** 
Constructor
*/
function Data(data) {

	this.data = data;
	this.blocAt = blocAtData;
	this.length = data.length;
}






/*
 * SearchQuery class
 *
 * Copyright 2008 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet, 
 * Use is subject to license terms.
 * 
 */

/**
Constants
*/

	ARTICLE 	= "Article";
	KEY		= "Key";
	KEYS		= "Keys";
	THEME		= "Theme";
	AUTHORS 	= "Authors";
	NAME 		= "Name";
	FIRST_NAME 	= "FirstName";
	LAST_NAME 	= "LastName";
	SUB_TITLE	= "SubTitle";
	TITLE		= "Title";
	ABSTRACT_URL	= "AbstractURL";
	ABSTRACT	= "Abstract";
	PAGES 		= "Pages";
	DATE 		= "Date";
	YEAR 		= "Year";
	NUMBER 		= "Number";
	TYPE 		= "Type";
	ARTICLE_LEVEL	= "ArticleLevel";
	NOUNS		= "Nouns";
	METHOD		= "Method";
	METHODS		= "Methods";
	REGION		= "Region";
	REGIONS		= "Regions";
	PERIOD		= "Period";
	PERIODS		= "Periods";
	EDITION		= "Edition";

	AND 		= "AND";
	OR 		= "OR";
	NOT 		= "NOT";
	MINUS 		= "WITHOUT";
	COLON 		= ":";
	OPEN 		= "(";
	CLOSE 		= ")";
	ADJOIN 		= "-";
	LITERAL 	= "\"";

	AND_VAR 	= "ET";
	OR_VAR 		= "OU";
	NOT_VAR 	= "NON";
	MINUS_VAR 	= "SANS";
	LITERAL_VAR 	= ";";
	
	AND_ARABIC	= "\u0648";  
	OR_ARABIC	= "\u0623\u0648"; 
	NOT_ARABIC	= "\u0644\u0627"; 
	MINUS_ARABIC	= "\u0628\u062f\u0648\u0646"; 
	OR_ARABIC_VAR	= "\u0627\u0648"; 

	OPERATOR_ID	= "Operator";
	OPERATOR	= new Array(OPERATOR_ID, "", "");

	// Element Reference constants

	ELTREF_NAME 	= 0;
	ELTREF_INDEXNAME = 1;
	ELTREF_ELTID 	= 2;
	ELTREF_STANDIDENTIFIER	= 3;
	ELTREF_IDFIDX	= 4;
	ELTREF_IDFN 	= 5;


/** 
Static code
*/

	var operators = new HashTable();
	operators.put(AND, AND); 
	operators.put(AND_VAR, AND);
	operators.put(OR, OR);
	operators.put(OR_VAR, OR);
	operators.put(MINUS, MINUS);
	operators.put(MINUS_VAR, MINUS);
	operators.put(COLON, COLON);
	operators.put(OPEN, OPEN);
	operators.put(CLOSE, CLOSE);
	operators.put(ADJOIN, ADJOIN);
	operators.put(LITERAL, LITERAL);
	operators.put(LITERAL_VAR, LITERAL);

	operators.put(AND_ARABIC, AND);
	operators.put(OR_ARABIC, OR);
	operators.put(NOT_ARABIC, NOT);
	operators.put(MINUS_ARABIC, MINUS);
	operators.put(OR_ARABIC_VAR, OR);

	nullLetters = " \t\n\r\f";

	delimiters = nullLetters 
			+ADJOIN
			+COLON
			+OPEN
			+CLOSE
			+LITERAL
			+LITERAL_VAR;

	var eltVar = new HashTable();
	eltVar.put("auteur", AUTHORS); 
	eltVar.put("année", YEAR); 
	eltVar.put("annee", YEAR); 
	eltVar.put("nom", NOUNS); 
	eltVar.put("période", PERIODS); 
	eltVar.put("periode", PERIODS); 
	eltVar.put("région", REGIONS); 
	eltVar.put("region", REGIONS); 
	eltVar.put("méthode", METHODS); 
	eltVar.put("methode", METHODS); 
	eltVar.put("clé", KEYS); 
	eltVar.put("cle", KEYS); 
	eltVar.put("article", ARTICLE); 
	eltVar.put("résumé", ABSTRACT); 
	eltVar.put("resume", ABSTRACT); 
	eltVar.put("titre", TITLE); 
	eltVar.put("type", TYPE); 

	eltVar.put("\u0643\u0627\u062a\u0628", AUTHORS);  
	eltVar.put("\u0633\u0646\u0629", YEAR);  
	eltVar.put("\u0645\u0641\u062a\u0627\u062d", KEYS);  
	eltVar.put("\u0645\u0642\u0627\u0644", ARTICLE);  
	eltVar.put("\u0645\u0644\u062e\u0635", ABSTRACT);  
	eltVar.put("\u0639\u0646\u0648\u0627\u0646", TITLE);  
	eltVar.put("\u0646\u0648\u0639", TYPE);  
/**
*/
function getElementReferenceSearchQuery(eltRefName) {

	var i;
	for (i=0; i < this.elementReferenceTable.length
			&& eltRefName != this.elementReferenceTable[i][ELTREF_NAME]; i++);
	if (i < this.elementReferenceTable.length)
		return this.elementReferenceTable[i];
	else	return null;
}

/**
*/
function getStandardizerSearchQuery(eltRef, standType) {

	var standIdf = eltRef[ELTREF_STANDIDENTIFIER], standTab;
	var idfIdx = eltRef[ELTREF_IDFIDX];
	var idfNextIdx = idfIdx + eltRef[ELTREF_IDFN];
	var found = false

	for (var i=idfIdx; i < idfNextIdx && !found; i++) {
		standTab = eval(standIdf + i);
		if (standTab[1] == standType)
			found = true;
	}
	if (!found)	standTab = eval(standIdf + idfIdx);

	return new Standardizer(standTab);
}

/**
*/
function elementVarSearchQuery(elt) {

	var e = eltVar.get(elt.toLowerCase());
	if (e != null)	return e;
	else		return elt;
}


/**
*/
function getDelimitersSearchQuery() {

	return delimiters;
}

/**
*/
function isDelimiterSearchQuery(c) {

	return c.length == 1 && delimiters.indexOf(c) != -1;
}

/**
*/
function isNullLetterSearchQuery(c) {

	return  c.length == 1 && nullLetters.indexOf(c) != -1;
}

/**
*/
function trimSearchQuery(string) {

	var begin = 0, end = string.length-1;
	for (; begin < string.length && this.isNullLetter(string.charAt(begin)); begin++);
	for (; end >= 0 && this.isNullLetter(string.charAt(end)); end--);

	if (begin <= end) return string.substring(begin, end+1);
	else	return "";
}

/**
*/
function getTermsSearchQuery(squery) {

	var stack = new Stack();
	var st = new StringTokenizer(squery, delimiters, true);
	var previousTermPos = -1;

	while (st.hasMoreTokens()) {

		token = st.nextToken();
		if (this.isNullLetter(token))	continue;

		operator = operators.get(token.toUpperCase());
		if (operator != null) {
			if (operator == ADJOIN) {
				token = stack.pop();
				for (t=st.nextToken(); this.isDelimiter(t); t=st.nextToken());
				token = token + " " + t;
				if (t != null)
					stack.push(this.trim(token));
				else	return null; // literal not closed
			}
			else if (operator == LITERAL) {
				token = "";
				for (t=st.nextToken(); t != null && operators.get(t) != LITERAL; ) {
					if (this.isDelimiter(t)) {
						for (t=st.nextToken(); 
							this.isDelimiter(t)
							&& t != LITERAL;
							t=st.nextToken());
						token = token + " ";
					}
					else {
						token = token + t;
						t = st.nextToken();
					}
				}
				if (t != null && operators.get(t) == LITERAL)
					stack.push(this.trim(token));
				else	return null; // literal not closed
			}
			else if (operator == COLON) {
				if (previousTermPos != -1) { 
					stackArray = stack.getArray();
					stackArray[previousTermPos] = stackArray[previousTermPos] + COLON;
				}
				else	return null; // missing term
			}
			else	stack.push(operator);
		}
		else {
			if (!this.isDelimiter(token)) {
				previousTermPos = stack.size();
			}
			stack.push(token);
		}
	}

	return stack.elements();
}


/**
*/
function addSearchQuery(term, eltRef) {

	var qterm = new Array(term, eltRef);
	this.query.push(qterm);
	return qterm;
}

/**
*/
function parseNameSearchQuery(term) {

	var slash = term.indexOf('/');
	if (slash > 0) {
		return term;
	}

	var dot = term.lastIndexOf(','), lastname, firstname;
	if (dot < 0) {
		dot = term.lastIndexOf(ARABIC_COMMA);
	}
	if (dot > 0) {
                lastname = this.trim(term.substring(0,dot));
                firstname = this.trim(term.substring(dot+1));
                return lastname + "/" + firstname;
	}

	var pos = term.lastIndexOf(' ');
	if (pos > 0) {
                firstname = term.substring(0,pos);
                lastname = term.substring(pos+1);
                return lastname + "/" + firstname;
	}
	else	return term;
}

/**
*/
function addExtendSearchQuery(term, eltRef, defaultEltRef) {

	if (operators.get(term) != null) {
		this.add(term, OPERATOR);
		return;
	}

	name = eltRef[ELTREF_NAME];
/*
	if (name == AUTHORS || name == NOUNS)
		term = this.parseName(term);
	DONE IN STANDARDIZER 
*/ 

	var standType = getWritingStandardizer(term);
	var standardizer = getStandardizerSearchQuery(eltRef, standType);

	word = term;
	term = standardizer.standardizeWord(term);

	// bricolage !
	if (name == TYPE && (term == "article"
				|| term == "encadre"
				|| term == "fiche de lecture")) {

			al = this.getElementReference(ARTICLE_LEVEL);
 			if (term == "article") {
				this.add("principal", al);
			}
			else if (term == "encadre") {
				this.add(OPEN, OPERATOR);
				this.add(OPEN, OPERATOR);
				this.add("encart/extrait", eltRef);
				this.add(OR, OPERATOR);
				this.add("note bibliographique", eltRef);
				this.add(OR, OPERATOR);
				this.add("note methodologique", eltRef);
				this.add(OR, OPERATOR);
				this.add("interview/recit de vie", eltRef);
				this.add(CLOSE, OPERATOR);
				this.add(MINUS, OPERATOR);
				this.add("principal", al);
				this.add(CLOSE, OPERATOR);
			}
			else if (term == "fiche de lecture") {
				this.add(OPEN, OPERATOR);
				this.add("note de lecture", eltRef);
				this.add(MINUS, OPERATOR);
				this.add("principal", al);
				this.add(CLOSE, OPERATOR);
			}
		return;
	}
	else if (standardizer.getName().indexOf("Text") >= 0
			&& standardizer.containsSeparator(word)) {
		st = standardizer.getWords(term);
		this.add(OPEN, OPERATOR);
		for (w=st.nextToken();
			standardizer.standardizeWord(w) == "" && st.hasMoreTokens();
			w=st.nextToken());
		var sw = standardizer.standardizeWord(w);
		if (sw != "") 
			this.add(sw, eltRef);
		while (st.hasMoreTokens()) {
			w = st.nextToken();
			sw = standardizer.standardizeWord(w);
			if (sw != "") {
				this.add(ADJOIN, OPERATOR);
				this.add(sw, eltRef);
			}
		}
		this.add(CLOSE, OPERATOR);
		this.queryDefEltTerms.push(new Array(term, eltRef));
		this.queryDefEltWords.push(word);
		return;
	}
	equivalents = standardizer.getEquivalents(term);
	if (equivalents != null) {
		this.add(OPEN, OPERATOR);
		qterm = this.add(term, eltRef);
		while (equivalents.hasMoreElements()) {
				this.add(OR, OPERATOR);
				this.add(equivalents.nextElement(), eltRef);
		}
		this.add(CLOSE, OPERATOR);
	}
	else {
		if (term != "")
			qterm = this.add(term, eltRef);
	}

	if (standardizer.getName().indexOf("Text") >= 0) {
		this.queryDefEltTerms.push(qterm);
		this.queryDefEltWords.push(word);
	}

}

/**
*/
function parseSearchQuery(queryString) {

	this.query = new Stack();

	eltRef = this.getElementReference(this.defaultElementName);
	defaultEltRef = eltRef;

	var e = this.getTerms(queryString);
	if (e == null)	return null; // lexical error 

	while (e.hasMoreElements()) {

		term = e.nextElement();
		l = term.length;
		if (term.charAt(l-1) == COLON) {
			element = this.elementVar(term.substring(0,l-1));
			eltRef = this.getElementReference(element);
			if (eltRef == null) return null; // unknown element
			term = e.nextElement();
			while (term != null && this.isDelimiter(term) && term != OPEN) {
				this.add(term, OPERATOR);
				term = e.nextElement();
			}
			if (term == null)
				return null; // missing term
			else if (term == OPEN) {
				while (term != null && term != CLOSE) {
					this.addExtend(term, eltRef, defaultEltRef);
 					term = e.nextElement();
				}
				if (term == CLOSE) 
					this.add(term, OPERATOR); 
				else	return null; // not closed
			}
			else {
				this.addExtend(term, eltRef, defaultEltRef);
 			}
			eltRef = defaultEltRef;
		}
		else {
			this.addExtend(term, eltRef, defaultEltRef);
		}
	}

	return this.query.elements();
}

/**
*/
function isOperatorSearchQuery(term) {

	return term[1][ELTREF_NAME] == OPERATOR_ID;
}

/**
*/
function acceptSearchQuery() {

	if (this.queryTerms.hasMoreElements())
		this.queryTerm = this.queryTerms.nextElement();
	else	this.queryTerm = null;
}

/**
*/
function restrictSearchQuery(ds, eltID) {

	var i = 0, nb = ds.length;
	var nds = new Array();

	for (; i<nb && ds[i][1] < eltID; i++);
	for (var k=0; i<nb && ds[i][1] == eltID; i++, k++) {
		nds[k] = ds[i];
	}

	return nds;
}

/**
*/
function andSearchQuery(ds1, ds2) {


	var nds = new Array();
	var i1 = 0, i2 = 0, k = 0, nb1 = ds1.length, nb2 = ds2.length;

	for (; i1 < nb1 && i2 < nb2; i1++) {
		for (; i2 < nb2 && ds2[i2][0] < ds1[i1][0]; i2++);
  		if (i2 < nb2 && ds2[i2][0] == ds1[i1][0]) {
//			ds1[i1][2] += ds2[i2][2];
			nds[k++] = ds1[i1];
			i2++;
		}
	}

	return nds;
}

/**
*/
function adjoinSearchQuery(ds1, ds2) {


	var nds = new Array();
	var i1 = 0, i2 = 0, k = 0, nb1 = ds1.length, nb2 = ds2.length;

	for (; i1 < nb1 && i2 < nb2; i1++) {
		for (; i2 < nb2 && ds2[i2][0] < ds1[i1][0]; i2++);
  		if (i2 < nb2 && ds2[i2][0] == ds1[i1][0]) {
			os = this.adjOcc(ds1[i1], ds2[i2]);
			if (os[2] > 0)	nds[k++] = os;
			i2++;
		}
	}

	return nds;
}

/**
*/
function adjOccSearchQuery(os1, os2) {

	var nos = new Array();
	var oe1, oe2;
	var i1 = 3, i2 = 3, k = 3;
	var nb1 = os1.length, nb2 = os2.length;
	var pocc1 = 0, pocc2 = 0, pocc = 0;

	for (; i1 < nb1 && i2 < nb2;  pocc1=oe1, i1++) {
		oe1 =  pocc1 + os1[i1];
		for (; i2 < nb2 && (oe2=pocc2+os2[i2]) < (oe1+1);
			pocc2=oe2, i2++);
  		if (i2 < nb2 && oe2 == (oe1+1)) {
			nos[k++] = oe2 - pocc; 
			pocc = oe2;
			pocc2 = oe2; i2++;
		}
	}

	nos[0] = os2[0];
	nos[1] = os2[1];
	nos[2] = k - 3;

	return nos;
}

/**
*/
function orSearchQuery(ds1, ds2) {

	var nds = new Array();
	var i1 = 0, i2 = 0, k = 0, nb1 = ds1.length, nb2 = ds2.length;

	for (; i1 < nb1; i1++) {
		for (; i2 < nb2 &&  ds2[i2][0] < ds1[i1][0]; i2++) {
			nds[k++] = ds2[i2];
		}
		if (i2 < nb2 && ds2[i2][0] == ds1[i1][0]) {
//			ds1[i1][2] += ds2[i2][2];
			i2++;
		}
		nds[k++] = ds1[i1];
	}
	for (; i2 < nb2; i2++) {
		nds[k++] = ds2[i2];
	}

	return nds;
}

/**
*/
function minusSearchQuery(ds1, ds2) {

	var nds = new Array();
	var i1 = 0, i2 = 0, k = 0, nb1 = ds1.length, nb2 = ds2.length;

	for (; i1 < nb1; i1++) {
		for (; i2 < nb2 && ds2[i2][0] < ds1[i1][0]; i2++);
  		if (i2 < nb2 && ds2[i2][0] == ds1[i1][0]) 
			i2++;
		else	nds[k++] = ds1[i1];
	}

	return nds;
}

/**
*/
function getDocsSearchQuery(qterm) {

	var term = qterm[0];
	var eltID = qterm[1][ELTREF_ELTID];

	return this.restrict(this.indexReader.getDocs(term), eltID);
}

/**
*/
function getOccNumberSearchQuery(qterm, docID) {

	var ds = this.getDocEntry(qterm, docID);
	return ds[2];
}

/**
*/
function getDocEntrySearchQuery(qterm, docID) {

	var term = qterm[0];
	var eltID = qterm[1][ELTREF_ELTID];

	var ds = this.indexReader.getDocs(term)
	var i = 0, nb = ds.length;
	for (; i < nb && ds[i][1] < eltID; i++);
	for (; i < nb && ds[i][0] < docID && ds[i][1] == eltID; i++);

	if (i < nb && ds[i][0] == docID && ds[i][1] == eltID) 
		return ds[i];
	else {
		de = new Array(3);
		de[0] = docID;
		de[1] = eltID;
		de[2] = 0;
		return de;
	}
}

/**
*/
function exprTermSearchQuery() {

	if (this.queryTerm == null) return null;

	var term = this.queryTerm[0];
	var ds = null;

	if (term == OPEN) {
		this.accept(); 
		ds = this.expr();
		if (ds == null || this.queryTerm == null) return null; 
		term = this.queryTerm[0];
		if (term == CLOSE) {
			this.accept(); 
		}
		else	return null;
	}
	else if (!this.isOperator(this.queryTerm)) {
		ds = this.getDocs(this.queryTerm);
		if (ds == null) return null; 
		this.accept(); 
	}
	return ds;
}


/**
*/
function exprSearchQuery() {

	var ds1 = this.exprTerm(), ds2;
	if (ds1 == null) return null;
	while (this.queryTerm != null) {
		var term = this.queryTerm[0];
		if (term == ADJOIN) {
			this.accept(); 
			ds2 = this.exprTerm();
			if (ds2 == null) return null;
			ds1 = this.adjoin(ds1, ds2);
		}
		else if (term == AND) {
			this.accept(); 
			ds2 = this.exprTerm();
			if (ds2 == null) return null;
			ds1 = this.and(ds1, ds2);
		}
		else if (term == OR) {
			this.accept(); 
			ds2 = this.exprTerm();
			if (ds2 == null) return null;
			ds1 = this.or(ds1, ds2);
		}
		else if (term == MINUS) {
			this.accept(); 
			ds2 = this.exprTerm();
			if (ds2 == null) return null;
			ds1 = this.minus(ds1, ds2);
		}
		else if (!this.isOperator(this.queryTerm) || term == OPEN) {
			ds2 = this.exprTerm();
			if (ds2 == null) return null;
			ds1 = this.or(ds1, ds2);
		}
		else	break;

		if (ds1 == null) return null;
	}

	return ds1;
}

/**
*/
function evaluateSearchQuery() {


/*	if (INDEX_LOCATION.toLowerCase().indexOf("http") != -1)
		return null;
*/
		/* SUPPRIMER POUR LA VERSION RESEAU */

	if (this.queryTerms == null)
		return null; // lexical error

	this.queryTerms.init();

	if (this.queryTerms.hasMoreElements()) {
		this.queryTerm = this.queryTerms.nextElement();
		return this.expr();
	}
	else	return new Array();
}


/**
*/
function getCellOrdersSearchQuery() {

	if (this.queryTerms == null) return new Array();

	var orders = new Array();
	var tab = this.queryTerms.getArray();
	var cell, term, nterms = tab.length, idx=0;
	var hash = new HashTable();
	for (var i=0; i < nterms; i++) {
		term = tab[i];
		if (!this.isOperator(term)) {
			cell = this.indexReader.getOrd(term[0]);
			if (hash.get(cell) != "WRITTEN") {
				orders[idx++] = cell;
				hash.put(cell, "WRITTEN");
			}
		}
	}
	return orders;
}

/**
*/
function getElementValueSearchQuery(element) {
        var sign = element + COLON + LITERAL;
	if (this.queryString.indexOf(sign) >= 0) {
	        var p1 = this.queryString.indexOf(sign) + sign.length;
        	var p2 = this.queryString.indexOf(LITERAL, p1);
        	return this.queryString.substring(p1, p2);
	}
	else {
		return null;
	}
}


/** 
Constructor
*/
function SearchQuery(queryS, eltRefTab, defEltName, indexReader) {

	this.encodedQueryString = queryS;
	this.elementReferenceTable = eltRefTab;
	this.defaultElementName = defEltName;
	this.indexReader = indexReader;

	this.getElementReference = getElementReferenceSearchQuery;
	this.getStandardizer = getStandardizerSearchQuery;
	this.elementVar = elementVarSearchQuery;
	SearchQuery.getDelimiters = getDelimitersSearchQuery;
	this.isDelimiter = isDelimiterSearchQuery;
	this.isNullLetter = isNullLetterSearchQuery;
	this.trim = trimSearchQuery;
	this.getTerms = getTermsSearchQuery;
	this.add = addSearchQuery;
	this.parseName = parseNameSearchQuery;
	this.addExtend = addExtendSearchQuery;
	this.parse = parseSearchQuery;
	this.isOperator = isOperatorSearchQuery;
	this.accept = acceptSearchQuery;
	this.restrict = restrictSearchQuery;
	this.and = andSearchQuery;
	this.adjoin = adjoinSearchQuery;
	this.adjOcc = adjOccSearchQuery;
	this.or = orSearchQuery;
	this.minus = minusSearchQuery;
	this.getDocs = getDocsSearchQuery;
	this.getOccNumber = getOccNumberSearchQuery;
	this.getDocEntry = getDocEntrySearchQuery;
	this.exprTerm = exprTermSearchQuery;
	this.expr = exprSearchQuery;
	this.evaluate = evaluateSearchQuery;
	this.getCellOrders = getCellOrdersSearchQuery;
	this.getElementValue = getElementValueSearchQuery;

	this.query = new Stack();
	this.queryDefEltTerms = new Stack();
	this.queryDefEltWords = new Stack();

	this.queryString = (new Mycoding()).decode(this.encodedQueryString);
//alert(this.queryString.charAt(0));
	this.queryTerms = this.parse(this.queryString);
}



















/*
 * ResultPage class
 *
 * Copyright 2007 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet, 
 * Use is subject to license terms.
 * 
 */

/**
static
*/

RESULTS_PER_PAGE 	= 10;

/*SUMMARY			= new Array("Sommaire","Sommaire (à traduire)");
SUMMARIES 		= new Array("Sommaires","Sommaires (à traduire)");
NUMBERS			= new Array("Num&eacute;ros","Num&eacute;ros (à traduire)");
*/

SUMMARY			= "Sommaire";
SUMMARIES 		= "Sommaires";
NUMBERS			= "Num&eacute;ros";

RESULTS			= new Array("R&eacute;sultat de la recherche",
				"&#1606;&#1578;&#1610;&#1580;&#1577; &#1575;&#1604;&#1576;&#1581;&#1579;");
SEE_ALSO		= new Array("Voir aussi: ","&#1588;&#1575;&#1607;&#1583; &#1603;&#1584;&#1604;&#1603;: ");
DOCUMENTS		= new Array("documents","<b>&#1608;&#1579;&#1575;&#1574;&#1602;</b>");
TWO_DOCUMENTS		= new Array("<b> 2</b> documents","<b> &#1608;&#1579;&#1610;&#1602;&#1578;&#1575;&#1606;</b>");
ONE_DOCUMENT		= new Array("<b> 1</b> document","<b> &#1608;&#1579;&#1610;&#1602;&#1577; &#1608;&#1575;&#1581;&#1583;&#1577;</b>");
ARTICLE			= new Array("Article","&#1575;&#1604;&#1605;&#1602;&#1575;&#1604;");
ABSTRACT		= new Array("R&eacute;sum&eacute;","&#1575;&#1604;&#1605;&#1604;&#1582;&#1589;");
CARD			= new Array("Fiche de lecture",
				"&#1575;&#1604;&#1602;&#1585;&#1575;&#1569;&#1577;");
FRAMED_ARTICLE		= new Array("Article encadr&eacute;", "&#1605;&#1602;&#1575;&#1604; &#1589;&#1594;&#1610;&#1585;");
NOTE			= new Array("note de lecture","&#1602;&#1585;&#1575;&#1569;&#1577;");
MAIN_ARTICLE		= new Array("article de fond","&#1605;&#1602;&#1575;&#1604; &#1571;&#1587;&#1575;&#1587;&#1610;");
RESULT_PAGE		= new Array("Page","&#1575;&#1604;&#1589;&#1601;&#1581;&#1577;");
BACK			= new Array("pr&eacute;c&eacute;dente",
				"&#1575;&#1604;&#1587;&#1575;&#1576;&#1602;&#1577;");
NEXT			= new Array("suivante","&#1575;&#1604;&#1578;&#1575;&#1604;&#1610;&#1577;");
NUMBER			= new Array("Num&eacute;ro","&#1575;&#1604;&#1593;&#1583;&#1583;");
FROM			= new Array(" de "," &#1604;");
DOCUMENTS_		= new Array("Documents","<b>&#1575;&#1604;&#1608;&#1579;&#1575;&#1574;&#1602;</b>");
TO_			= new Array("&agrave;","&#1573;&#1604;&#1609;");
FROM_			= new Array("sur","&#1605;&#1606;");
DOCUMENT_		= new Array("Document","<b>&#1575;&#1604;&#1608;&#1579;&#1610;&#1602;&#1577;</b>");
DOC_TYPE		= new Array("Type","&nbsp;&#1606;&#1608;&#1593;");
FOUND			= new Array(" trouv&eacute; ", " &#1605;&#1608;&#1580;&#1608;&#1583; ");
TIMES			= new Array(" fois", " &#1605;&#1585;&#1575;&#1578;");
TWO_TIMES		= new Array(" 2 fois", " &#1605;&#1585;&#1578;&#1610;&#1606;");
ONE_TIME		= new Array(" 1 fois", " &#1605;&#1585;&#1577; &#1608;&#1575;&#1581;&#1583;&#1577;");
COMMA			= new Array(", ", "&#1548; ");


NOT_FOUND 		= new Array("Aucun article ne correspond aux termes de votre recherche", 
					"\u0644\u0627 \u064a\u0648\u062c\u062f \u0645\u0642\u0627\u0644 \u064a\u0646\u0627\u0633\u0628 \u0628\u062d\u062b\u0643");

BAD_QUERY 		= new Array("Erreur dans les termes de votre recherche", 
					"\u062e\u0637\u0623 \u0641\u064a \u0627\u0644\u0628\u062d\u062b");

WORD_SEPARATOR 		= "_";
FORBIDEN_CHARS 		= "\"\'";

HEADER 			= "<span class=\"AuthorsLarge\"><\/span>\
<p>&nbsp;  <\/p>\
<div align=\"center\">\
  <table width=\"80%\" height=\"220\">\
    <tr>\
      <td>";

FOOTER 			= "<\/table><\/div>";

SUMMARIES_HEADER_1 	= "<p><span class=\"Emphasis\">" + SUMMARIES + "<\/span><\/p>\
   <table border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\
	<tbody><tr><td align=\"left\" bgcolor=\"#dddddd\" nowrap=\"nowrap\"> \
              <p><b><br>&nbsp; " + NUMBERS + " : <\/b><\/p>\
              <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\
                <tbody><tr><td width=\"5%\">&nbsp;<\/td>\
                  <td width=\"45%\">";

SUMMARIES_HEADER_2 	= "                  <\/td><td width=\"45%\">";

SUMMARIES_HEADER_3 	= "                 <\/td><td width=\"5%\">&nbsp;<\/td><\/tr><\/tbody><\/table>\
              <p>&nbsp; <\/p><\/td><\/tr><\/tbody><\/table>";

ARTICLE_URL_INFO = 	0;
DATE_INFO = 		1;
NUMBER_INFO = 		2;
THEME_INFO = 		3;
AUTHORS_INFO = 		4;
NOUNS_INFO = 		5;
ABSTRACT_URL_INFO = 	6;
TITLE_INFO = 		7;
TYPE_INFO = 		8;
EDITION_INFO = 		9;
PAGES_INFO = 		10;
ARTICLE_LEVEL_INFO = 	11;

MAXIMUM_OCC_NUMBERS = 	10000;
MAXIMUM_NUMBERS = 	200;
MAXIMUM_PAGES = 	600;

MIN_NUM_ART = 		20000;
MAXIMUM_ARTICLES_BY_NUMBER = 50;

/**
*/
function pageLinkResultPage(page) {

	return "javascript:top.loadResultPage(" + this.getOrder()
				+ "," + page + ");";
}

/**
*/
function resultLinkResultPage(link) {

	if (link.charAt(0) == '/') 
		link =  link.substring(1);

	var doclink = link;
	var jslink = this.jsLink(link);

	return "javascript:top.openLink('" + doclink + "','"+ jslink + "','"+ this.wordsToMark + "');";
}

/**
*/
function jsLinkResultPage(link) {

	try {
	var name = /(Abstract|Article)/;
	var tab = link.match(name);
	var t = tab[0];
	tab = splitStringTokenizer(link, '/');
	var ntab = splitStringTokenizer(tab[0], '-');
	var n = ntab[0];
	name = /([0-9][0-9]*)/;
	ntab = tab[1].match(name);
	var a = ntab[0];
	n = n*MAXIMUM_ARTICLES_BY_NUMBER*2+a*2+MIN_NUM_ART;
	if (t == 'Abstract')	n++;
	return "i" + n + ".js";
	}
	catch (e) { return ""; };
}

/**
*/
function writeLinkResultPage(text, url) {

	this.doc.write("<a href=\"" + url + "\">" + text + "<\/a>");
}

/**
*/
function swriteLinkResultPage(s, text, url) {

	s += "<a href=\"" + url + "\">" + text + "<\/a>";
	return s;
}

/**
*/
function pageLinksResultPage(npage) {

	var 	s = "<p align=\"center\">"+RESULT_PAGE[this.codeLang]+": &nbsp;", 
		url;

	if (npage > 0) {
		url = this.pageLink(npage-1);
		s = this.swriteLink(s, BACK[this.codeLang], url);
		s += "&nbsp; ";
	}

	for (var p=0; p < this.pageNumber; p++) {
		url = this.pageLink(p);
		if (p != npage)
			s = this.swriteLink(s, (p+1), url);
		else	s += "<b>" + (p+1) + "<\/b>";
		s += " ";
	}

	if (npage < this.pageNumber-1) {
		url = this.pageLink(npage+1);
		s += "&nbsp;";
		s = this.swriteLink(s, NEXT[this.codeLang], url);
	}
	s += "<p>\n";

	return s;
}



/**
*/
function openURLResultPage(message) {

	this.doc.open();

	this.doc.writeln(HEADER);	

	this.doc.writeln("<p><span class=\"Emphasis\">"+ RESULTS[this.codeLang] +"</span> <br>\
         </p><hr noshade><p>&nbsp; </p><p>&nbsp; </p><p>&nbsp; </p><p>&nbsp; </p><p align=\"center\"><b>");

	this.doc.writeln(message);

	this.doc.writeln("</b></td></tr>");

	this.doc.writeln(FOOTER);	
	this.doc.close();


//	this.frame.location.href = url;
}

/**
*/
function emptyResultPage(string) {

	return (string == null) || (string.length == 0);
}

/**
*/
function getEltRefResultPage(element) {

	var i = 0;
	for (; i < this.elementReferenceTable.length &&
		this.elementReferenceTable[i][ELTREF_NAME] != element; i++);
	return this.elementReferenceTable[i];
}

/**
*/
function writeSummariesHeaderResultPage(resultNumber) {

	var yearNumber = 0;
	var year = 0;
	var lastYear = "";
	for (var r=0; r < resultNumber; r++) {
		var re = this.results[r];
		var docRef = this.documentReferenceTable[re[0]]; 
		var res = docRef[DATE_INFO].match(/[0-9]+/);
		if (res && res[0] != lastYear) {
			year = res[0];
			yearNumber++;
		}
		lastYear = year;
	}
	var medYear = Math.ceil(yearNumber/2);

	this.doc.writeln("<a name=\"top\"></a>");
	this.doc.writeln(SUMMARIES_HEADER_1);
	var lastNumber = "";
	lastYear = ""; 
	var yearCounter = 0;
	for (var r=0; r < resultNumber; r++) {
		var re = this.results[r];
		var docRef = this.documentReferenceTable[re[0]]; 

		var res = docRef[DATE_INFO].match(/[0-9]+/);
		if (res && res[0] != lastYear) {
			year = res[0];
			if (yearCounter == medYear) {
				this.doc.writeln(SUMMARIES_HEADER_2);
			}
			if (yearCounter != 0 && yearCounter != medYear) {
				this.doc.writeln("<br>");
			}
			this.doc.writeln("<b><span class=\"small\">" 
				+ year + ": <\/span><\/b>");
			yearCounter++;
		}

		if (docRef[NUMBER_INFO] != lastNumber) {
			this.doc.writeln("<a href=\"#" + docRef[NUMBER_INFO] + "\">"
				+ docRef[NUMBER_INFO] + "<\/a>");
		}
		lastNumber = docRef[NUMBER_INFO];
		lastYear = year;
	}

	this.doc.writeln(SUMMARIES_HEADER_3);

}

/**
*/
function writeSummariesMessageResultPage(result) {

	var re = this.results[result];
	var docRef = this.documentReferenceTable[re[0]];
	if (docRef[NUMBER_INFO] == this.lastNumber) {
		return;
	}
	this.doc.writeln("<a name=\"" + docRef[NUMBER_INFO] + "\"></a>");
	this.doc.writeln("<p>&nbsp; <\/p>");
	this.doc.writeln("<table width=100% cellspacing=0 cellpadding=2 border=0>");
     	this.doc.writeln(" <tbody><tr>");
	this.doc.writeln(" <td class=\"documents\" align=\"left\" nowrap=\"nowrap\">");
	this.doc.writeln("<p><b>&nbsp;"+NUMBER[this.codeLang]+": " + docRef[NUMBER_INFO] + ". ");
	this.doc.writeln(docRef[DATE_INFO] + ".");
	this.doc.writeln(" <\/b><\/p><\/td>");
	this.doc.writeln(" <td class=\"arrow\"><a href=\"#top\">^<\/a><\/td>");
	this.doc.writeln(" <\/tr><\/tbody><\/table>");

	var theme = docRef[THEME_INFO];
	if (!this.empty(theme)) {
		this.doc.writeln("<p class=\"Theme\">" + theme + " <\/p>");
	}
	this.lastNumber = docRef[NUMBER_INFO];
}

/**
*/
function writeMessageResultPage(resMin, resMax, resSize) {


	var oppositeAlign = this.getOppositeAlign(this.language);
	var normalAlign = this.getNormalAlign(this.language);

	this.doc.writeln("<p align=\""+normalAlign+"\"><span class=\"Emphasis\">" 
			+ this.message + "<\/span><\/p>");

	if (this.message == SUMMARY) {
		var re = this.results[0];
		var docRef = this.documentReferenceTable[re[0]];
//		if (resMin == 0 && SHOW_FIRST_PAGE) {
		if (resMin == 0) {
			this.doc.writeln("<img src=\"img\/" + docRef[NUMBER_INFO] 
				+ ".jpg\" border=\"0\" align=\""+oppositeAlign+"\">");
		}
		this.doc.writeln("<p><b>"+NUMBER[this.codeLang]+": " + docRef[NUMBER_INFO] + ". ");
 		this.doc.writeln(docRef[DATE_INFO] + ".");
		var theme = docRef[THEME_INFO];
		this.doc.writeln("<\/b><\/p>");
		if (!this.empty(theme)) {
			this.doc.writeln("<p class=\"Theme\">" + theme + " <\/p>");
		}
 	}
	else if (this.message != RESULTS[this.codeLang]) {
		var element = "Keys";
		var word = this.searchQuery.getElementValue(element);
		if (word == null) {
			element = "Authors";
			word = this.searchQuery.getElementValue(element);
		}
		if (seeAlsoHashTab != undefined && word != null) {
			var standType = getWritingStandardizer(word);
			var standardizer = getStandardizerSearchQuery(this.keysEltRef, standType);
			var stand = standardizer.standardizeWord(word);
			if (seeAlsoHashTab[stand] != undefined) {
				var seeAlsoHtmlTab = seeAlsoHashTab[stand][0];
				var seeAlsoQueryTab = seeAlsoHashTab[stand][1];
				this.doc.write("<p class=\"small\">" + SEE_ALSO[this.codeLang]);
				var encoder = new Mycoding();
				for (var i=0; i < seeAlsoHtmlTab.length; i++) {
					var message = seeAlsoHtmlTab[i];
					var linkName = message.replace(/\[/g, '&');
					var key = seeAlsoQueryTab[i];
					var query = "(" + element + ":\"" + key + "\")";
					query = encoder.code(query);
					var url = "";
					try {
						url = "javascript:top.openResultPage('"
							+ query + "', '" + message + "', 0);";
					}
					catch(e) {}
					this.writeLink(linkName, url);
					if (i < seeAlsoHtmlTab.length-1) {
						this.doc.write(", ");
					}
				}
				this.doc.writeln(" <\/p>");
			}
		}
	}
	if (this.message != SUMMARY) {
		this.doc.writeln("<table width=100% cellspacing=0 cellpadding=2 border=0>");
     		this.doc.writeln(" <tr><td  class=documents align="+oppositeAlign+" nowrap>");
		if (this.pageNumber > 1) {
		  	if (resMin != resMax) 
				this.doc.write(" "+DOCUMENTS_[this.codeLang]+" <b>" + (resMin+1) 
					+ "<\/b> "+TO_[this.codeLang]+" <b>" + (resMax+1));
			else 	this.doc.write(" "+DOCUMENT_[this.codeLang]+" <b>" + (resMin+1));
			this.doc.writeln("<\/b> "+FROM_[this.codeLang]+" <b>" + resSize + "<\/b>");
		}
		else {
			if (resSize > 2) {
	 			this.doc.writeln(" <b>" + resSize + " <\/b> " + DOCUMENTS[this.codeLang]);
			}
			else {
				if (resSize == 2) {
					this.doc.writeln(" "+TWO_DOCUMENTS[this.codeLang]);
				}
				else { // (resSize == 1)
					this.doc.writeln(" "+ONE_DOCUMENT[this.codeLang]);
				}
			}
		}
		this.doc.writeln(" <\/td><\/tr>");
		this.doc.writeln("<\/table>");
	}
}

/**
*/
function writeElementResultPage(name, prefix, value, after) {

	if (!this.empty(value))
		this.doc.write("<span class=\"" + name 
				+ "\">" + prefix+value + "<\/span>" + after);
}

/**
*/
function nOccurrencesResultPage(term, docID) {

	var word = term[0];
	var eltRef = term[1];

	var standType = getWritingStandardizer(word);
	var standardizer = getStandardizerSearchQuery(eltRef, standType);

	if (this.isText(standardizer) && standardizer.containsSeparator(word)) {
		var st = standardizer.getWords(word);
		for (w=st.nextToken();
			standardizer.standardizeWord(w) == ""
			&& st.hasMoreTokens();
			w=st.nextToken());
		var sw = standardizer.standardizeWord(w);
		if (sw != "")
			os = this.getOccSet(sw, docID, eltRef);
		while (st.hasMoreTokens()) {
			w = st.nextToken();
			sw = standardizer.standardizeWord(w);
			if (sw != "") {
				osc = this.getOccSet(sw, docID, eltRef);
				os = adjOccSearchQuery(os, osc);
			}
		}
		return os[2];
	}
	else {
		return this.searchQuery.getOccNumber(term, docID);
	}

}

/**
*/
function getOccSetResultPage(term, docID, eltRef) {

	var qterm = new Array(term, eltRef);

	return this.searchQuery.getDocEntry(qterm, docID);
}


/**
*/
function isTextResultPage(standardizer) {

	return (standardizer.getName().indexOf("Text") >= 0);
}

/**
*/
function writeOccurrencesResultPage(re) {
	
	var term, word = null;
	var nOcc, nWords = this.queryDefEltWords.length;

	var direction = this.getDirection(this.language);

	for (var i=0; i < nWords; i++) {
		term = this.queryDefEltTerms[i];
		nOcc = this.nOccurrences(term, re[0]);

		if (nOcc > 0) {
			if (!this.empty(word))
				this.doc.write(COMMA[this.codeLang]);
			else	this.doc.write("<span class=\"Occurrences\" dir=\""
						+ direction + "\">");

			word = this.queryDefEltWords[i];
			this.doc.write(word + FOUND[this.codeLang]);
			if (nOcc > 2) {
				this.doc.write(nOcc + TIMES[this.codeLang]);
			}
			else if (nOcc == 2) {
				this.doc.write(TWO_TIMES[this.codeLang]);
			}
			else { // (nOcc == 1)
				this.doc.write(ONE_TIME[this.codeLang]);
			}
		}
	}
	if (!this.empty(word))
		this.doc.write(".<\/span><br>");

}

/**
*/
function writeResultResultPage(re) {

	var docRef = this.documentReferenceTable[re[0]];
	var level = docRef[ARTICLE_LEVEL_INFO].toLowerCase();
	var type = docRef[TYPE_INFO].toLowerCase();
	var abs;

	var language = this.getLanguage(docRef[TITLE_INFO]);
	var code = this.getLanguageCode(language);
	this.writeDirection(language);

	if (!this.empty(type) && this.isNote(type)
			&& (this.empty(level) || level != "principal")) {
		this.writeElement("Authors", "", docRef[NOUNS_INFO], "<br>");
		this.writeElement("Title", "", docRef[TITLE_INFO], "<br>");
		this.writeElement("Title", "", docRef[EDITION_INFO], "<br>");
		this.writeElement("Number", NUMBER[code]+": ", docRef[NUMBER_INFO], ". ");
 		this.writeElement("Date", "", docRef[DATE_INFO], ".<br>");
		this.writeElement("Type", DOC_TYPE[code]+": ", type, "");
		var names = docRef[AUTHORS_INFO];
		if (!this.empty(names))
			this.writeElement("Authors", FROM[code], names, "<br>");
		else	this.doc.writeln("<br>");
	}
	else {
		this.writeElement("Authors", "", docRef[AUTHORS_INFO], "<br>");
		this.writeElement("Title", "", docRef[TITLE_INFO], "<br>");
		var newline = false;
		if (this.message != SUMMARY && this.message != SUMMARIES) {
			this.writeElement("Number", NUMBER[code]+": ", docRef[NUMBER_INFO], ". ");
 			this.writeElement("Date", "", docRef[DATE_INFO], ". ");
			newline = true;
		}
		if (!this.empty(type) && !this.isMainArticle(type)) {
			this.writeElement("Type", DOC_TYPE[code]+": ", type, ".");
			newline = true;
		}
		if (newline)
			this.doc.writeln("<br>");
	}

	this.writeOccurrences(re);

	if (!this.empty(level) && level== "principal") 
		this.writeLink(ARTICLE[code], this.resultLink(docRef[ARTICLE_URL_INFO]));
	else if (!this.empty(type) && this.isNote(type))
		this.writeLink(CARD[code], this.resultLink(docRef[ARTICLE_URL_INFO]));
	else	this.writeLink(FRAMED_ARTICLE[code], this.resultLink(docRef[ARTICLE_URL_INFO]));

	abs = docRef[ABSTRACT_URL_INFO];
	if (!this.empty(abs)) {
		this.doc.write(" | ");
		this.writeLink(ABSTRACT[code], this.resultLink(abs));
	}

	this.writeEndDirection();

	this.doc.writeln("<hr>");
}

/**
*/
function writePageResultPage(npage) {

	this.doc = this.frame.document;

	if (this.results == null) {
		alert(BAD_QUERY[this.codeLang]);
		top.frames[4].history.back();
		return;
	}

	var s = this.results.length;
	if (s == 0) {
		alert(NOT_FOUND[this.codeLang]);
		top.frames[4].history.back();
		return;
	}

	this.doc.open();

	this.doc.writeln(HEADER);	

	this.writeDirection(this.language);

	var resMin = 0;
	var resMax = s-1;
	if (this.message != SUMMARIES) {
		resMin = npage * RESULTS_PER_PAGE;
		resMax = Math.min(resMin+RESULTS_PER_PAGE-1, s-1);
	}

	if (this.message != SUMMARIES) {
		this.writeMessage(resMin, resMax, s);
		this.doc.writeln("<hr>");
	}
	else { // this.message == SUMMARIES
		this.writeSummariesHeader(s);
		this.lastNumber = "";
	}

	for (var r=resMin; r <= resMax; r++) {
		if (this.message == SUMMARIES) {
			this.writeSummariesMessage(r);
		}
		this.writeResult(this.results[r]);
	}

 	if (this.pageNumber > 1 && this.message != SUMMARIES)
		this.doc.write(this.pageLinks(npage));

	this.writeEndDirection();

	this.doc.writeln(FOOTER);	
	this.doc.close();
}

/**
*/
function getOrderResultPage() {

	return this.order;
}

/**
*/
function wordsToStringResultPage(termTab) {

	var nWords = termTab.length;

	if (nWords == 0)	return "";

	var words = this.stringWithoutSeparator(termTab[0]);
	for (var i=1; i < nWords; i++) {
		words += WORD_SEPARATOR;
		words += this.stringWithoutSeparator(termTab[i]);
	}

	return words;
}

/**
*/
function stringWithoutSeparatorResultPage(term) {

	var standType = getWritingStandardizer(term[0]);
	var standardizer = getStandardizerSearchQuery(term[1], standType);
	return standardizer.withoutSeparator(term[0]);
}

/**
*/
function firstIntegerResultPage(text) {

	var b, e;
	for (b=0; b < text.length && (text.charAt(b) < '0'
			|| text.charAt(b) > '9'); b++);
	for (e=b; e < text.length && text.charAt(e) >= '0'
			&& text.charAt(e) <= '9'; e++);

	if (b < text.length)	return parseInt(text.substring(b, e));
	else			return 0;
}

/**
*/
function totalNOccurrencesResultPage(re) {

	var term;
	var nWords = this.queryDefEltTerms.length, TNOcc = 0;

	for (var i=0; i < nWords; i++) {
		term = this.queryDefEltTerms[i];
		TNOcc += this.nOccurrences(term, re[0]);
	}

	return TNOcc;
}

/**
*/
function compareResultPage(a, b) {

	return b[3] - a[3];
}

/**
*/
function sortResultPage() {

	var docRef,re, pages, number, nocc, power, spages, level, type;

	for (var i=0; i < this.results.length; i++) {
		re = this.results[i];
		docRef = this.documentReferenceTable[re[0]];

		spages = docRef[PAGES_INFO];
		if (this.empty(spages)) pages = MAXIMUM_PAGES - 1;
		else	pages = this.firstInteger(spages);
		number = this.firstInteger(docRef[NUMBER_INFO]);
		nocc = this.totalNOccurrences(re);
		level = docRef[ARTICLE_LEVEL_INFO].toLowerCase();
		type = docRef[TYPE_INFO].toLowerCase();
		if (!this.empty(level) && level == "principal")
			power = 2;
		else if (!this.empty(type) && this.isNote(type))
			power = 1;
		else	power = 0;

		if (spages != null && this.language != "arabic" && spages.toLowerCase().indexOf("arab") >= 0)
			pages += (MAXIMUM_PAGES/2);
		if (spages != null && this.language == "arabic" && spages.toLowerCase().indexOf("arab") < 0)
			pages += (MAXIMUM_PAGES/2);

		re[3] = power*MAXIMUM_OCC_NUMBERS*MAXIMUM_NUMBERS*MAXIMUM_PAGES
				+ nocc*MAXIMUM_NUMBERS*MAXIMUM_PAGES
				+ (MAXIMUM_NUMBERS-number)*MAXIMUM_PAGES
				+ (MAXIMUM_PAGES-pages);
	}

	this.results.sort(this.compare);
}

/**
*/
function encodeResultPage(string) {

	var c, newString = "";
	for (var i=0; i < string.length; i++) {
		c = string.charAt(i);
		if ( FORBIDEN_CHARS.indexOf(c) != -1) {
			if (c == '"')
				newString += ';';
			else	newString += '\\' + c;
		}
		else	newString += c;
	}
	return newString;
}

/**
*/
function isNoteResultPage(type) {

	return isFromTypeResultPage(type, NOTE);
}

/**
*/
function isMainArticleResultPage(type) {

	return isFromTypeResultPage(type, MAIN_ARTICLE);
}

/**
*/
function isFromTypeResultPage(type, TYPE) {

	var i=0;
	var n=TYPE.length;
	for (; i < n; i++) {
		if (TYPE[i] == type) {
			return true;
		}
	}
	return false;
}

/**
*/
function getDirectionResultPage(language) {

	if (language == "arabic") {
		return "rtl";
	}
	else {
		return "ltr";
	}
}

/**
*/
function writeDirectionResultPage(language) {

	this.doc.writeln("<div dir=\"" + this.getDirection(language) + "\">");
}

/**
*/
function writeEndDirectionResultPage() {

	this.doc.writeln("</div>");
}

/**
*/
function getLanguageResultPage(string) {

	// trim
	var begin = 0, end = string.length-1;
	var nulls = " \t\n\r\f";
	for (; begin < string.length && nulls.indexOf(string.charAt(begin)) != -1; begin++);
	for (; end >= 0 && nulls.indexOf(string.charAt(end)) != -1; end--);

	//
	var s = string.substring(begin, end+1);
	if (s.length == 0) {
		return "french";
	}

	//
	var p = s.indexOf(';');
	var c = s.charAt(0);
	if (c == '&' && p > 0) {
		var entity = s.substring(0, p+1);
		var i = decodeEntityHTML(entity);
		if ((i >= 1563 && i <= 1957) || (i >= 64336 && i <= 65276)) { // arabic
			return "arabic";
		}
	}

	// 
	s = s.substring(p+1);
	var p = s.indexOf(';');
	var c = s.charAt(0);
	if (c == '&' && p > 0) {
		var entity = s.substring(0, p+1);
		var i = decodeEntityHTML(entity);
		if ((i >= 1563 && i <= 1957) || (i >= 64336 && i <= 65276)) { // arabic
			return "arabic";
		}
	}
	return "french";
}

/**
*/
function getLanguageCodeResultPage(language) {

	if (language != undefined && language == "arabic") {
		return 1;
	}
	else {
		return 0;
	}
}

/**
*/
function getOppositeAlignResultPage(language) {

	if (language != undefined && language == "arabic") {
		return "left";
	}
	else {
		return "right";
	}
}

/**
*/
function getNormalAlignResultPage(language) {

	if (language != undefined && language == "arabic") {
		return "right";
	}
	else {
		return "left";
	}
}

/** 
Constructor
*/
function ResultPage(order, resu, mess, theframe, squery, eltRefTab, docRefTab) {

	this.order = order;
	this.results = resu;
	this.message = mess;
	this.frame = theframe;
	this.searchQuery = squery;
	this.elementReferenceTable = eltRefTab;
	this.documentReferenceTable = docRefTab;

	this.pageLink = pageLinkResultPage;
	this.resultLink = resultLinkResultPage;
	this.writeLink = writeLinkResultPage;
	this.swriteLink = swriteLinkResultPage;
	this.pageLinks = pageLinksResultPage;
	this.openURL = openURLResultPage;
	this.empty = emptyResultPage;
	this.getEltRef = getEltRefResultPage;
	this.writeSummariesMessage = writeSummariesMessageResultPage;
	this.writeSummariesHeader = writeSummariesHeaderResultPage;
	this.writeMessage = writeMessageResultPage;
	this.writeElement = writeElementResultPage;
	this.nOccurrences = nOccurrencesResultPage;
	this.getOccSet = getOccSetResultPage;
	this.isText = isTextResultPage;
	this.writeOccurrences = writeOccurrencesResultPage;
	this.writeResult = writeResultResultPage;
	this.writePage = writePageResultPage;
	this.getOrder = getOrderResultPage;
	this.wordsToString = wordsToStringResultPage;
	this.stringWithoutSeparator = stringWithoutSeparatorResultPage;
	this.firstInteger = firstIntegerResultPage;
	this.totalNOccurrences = totalNOccurrencesResultPage;
	this.compare = compareResultPage;
	this.sort = sortResultPage;
	this.encode = encodeResultPage;
	this.jsLink = jsLinkResultPage;
	this.isNote = isNoteResultPage;
	this.isMainArticle = isMainArticleResultPage;
	this.isFromType = isFromTypeResultPage;
	this.getDirection = getDirectionResultPage;
	this.writeDirection = writeDirectionResultPage;
	this.writeEndDirection = writeEndDirectionResultPage;
	this.getLanguage = getLanguageResultPage;
	this.getLanguageCode = getLanguageCodeResultPage;
	this.getOppositeAlign = getOppositeAlignResultPage;
	this.getNormalAlign = getNormalAlignResultPage;

	if (this.results != null) 
		this.pageNumber = Math.ceil(this.results.length / RESULTS_PER_PAGE);
	else	this.pageNumber = 0;

	this.queryDefEltTerms = this.searchQuery.queryDefEltTerms.getArray();
	this.queryDefEltWords = this.searchQuery.queryDefEltWords.getArray();
	this.wordsToMark = this.wordsToString(this.queryDefEltTerms);

	this.keysEltRef = this.getEltRef("Keys");
	this.lastNumber = "";

	this.language = OUTPUT_LANGUAGE;
	this.codeLang = this.getLanguageCode(this.language);

	if (this.results != null) 
		this.sort();
}
/*
 * Viewer class
 *
 * Copyright 2007 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet, 
 * Use is subject to license terms.
 * 
 */

TOP_PAGE  = "<a name=\"top\">";

PAGE_PREFIX =	"<table width=\"400\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\">\
  <tr>\
  <tr>\
    <td>&nbsp;<\/td>\
    <td>\
    <a href=\"#top\"><img src=\"../img/top.gif\" border=\"0\" align=\"absbottom\"><\/a>\
    <\/td>\
  <\/tr>\
    <td width=\"386\" class=\"page\">";

PAGE_SUFFIX =	"<\/td>\
    <td>&nbsp;<\/td>\
  <\/tr>\
<\/table>";


/** 
*/
function printViewer(ddata) {

	var data = new Data(ddata), markpos, begin, end, bloc;

	this.doc.open("replace");

	var l = data.length;

	for (var i=0; i < l; i++) {
		bloc = data.blocAt(i); // line number i
		
		markpos = this.linePositions.get(i);
		if (markpos == null) {
			var result = bloc.match(/<!\-\-p([0-9]+)/i);
			var pageString = "page ";
			if (result == null) {
				result = bloc.match(/<!\-\-&#1589;([0-9]+)/i);
				pageString = "&#1589;&#1601;&#1581;&#1577; ";
			}
			if (result == null) {
				result = bloc.match(/<!\-\-([0-9]+)&#1589;/i);
				pageString = "&#1589;&#1601;&#1581;&#1577; ";
			}
			if (result == null) {
				this.doc.writeln(bloc);
			}
			else { // page number comment
				var pageNumber = result[1];
				this.doc.write(PAGE_PREFIX + pageString);
				this.doc.write(pageNumber);
				this.doc.writeln(PAGE_SUFFIX);
				this.doc.writeln(bloc);
			}
		}
		else {
			end = 0;
			for (var k=0; k < markpos.length; k += 2) {
				begin = markpos[k];
				this.doc.write(bloc.substring(end, begin));
				end = begin + markpos[k+1];
				this.doc.write(this.beginMark);
				this.doc.write(bloc.substring(begin,end));
				this.doc.write(this.endMark);
			}
			this.doc.write(bloc.substring(end, bloc.length));
		}
	}

	this.doc.close();
}



/**
*/
function getEltRefViewer(element) {

	var i = 0;
	for (; i < this.elementReferenceTable.length &&
		this.elementReferenceTable[i][ELTREF_NAME] != element; i++);
	return this.elementReferenceTable[i];
}

/**
*/
function compareViewer(a, b) {

	if (a[0] != b[0])
		return a[0] - b[0];
	else	return a[1] - b[1];
}

/**
*/
function getPositionsViewer(word, index, standardizer) {

	var st = standardizer.getWords(word);
	var w, positions;

	for (w=st.nextToken(); standardizer.standardizeWord(w) == "" 
			&& st.hasMoreTokens(); w=st.nextToken());

	if (standardizer.standardizeWord(w) != "")
		positions = this.getWordPositions(w, index);
	else	positions = null;

	if (positions == null)	return null;

	var hash = new HashTable();
	for (n=1; st.hasMoreTokens(); ) {
		w = st.nextToken();
		if (standardizer.standardizeWord(w) != "") {
			pos = this.getWordPositions(w, index);
			positions = this.adjoinWordPositions(positions, pos, hash);
			n++;
		}
	}
	beforePos = new Array();
	for (p=1; p < n; p++) {
		for (k=0; k < positions.length; k+=4) {
			wp = positions[k+3] - p;
			pos3 = hash.get(wp);
			beforePos = beforePos.concat(pos3);
			beforePos = beforePos.concat(wp);
		}
	}
	positions = positions.concat(beforePos);
	return positions;
}

/**
*/
function adjoinWordPositionsViewer(pos1, pos2, hash) {

	var npos = new Array();
	var oe1, oe2;
	var i1 = 0, i2 = 0, k = 0;
	var nb1 = pos1.length, nb2 = pos2.length;

	for (; i1 < nb1 && i2 < nb2; i1+=4) {
		oe1 =  pos1[i1+3];
		for (; i2 < nb2 && 
			(oe2=pos2[i2+3]) < (oe1+1);
			i2+=4);
  		if (i2 < nb2 && oe2 == (oe1+1)) {
			npos[k] = pos2[i2];
			npos[k+1] = pos2[i2+1];
			npos[k+2] = pos2[i2+2];
			npos[k+3] = oe2;
			pos3 = new Array(pos1[i1], pos1[i1+1], pos1[i1+2]);
			hash.put(oe1, pos3);
			k += 4;
			i2 += 4;
		}
	}

	return npos;
}

/**
*/
function getWordPositionsViewer(word, index) {

	var idx = this.getWordIndex(word, index);
	return this.getWordPositionsWithIdx(idx, index);
}

/**
*/
function getWordPositionsWithIdxViewer(idx, index) {

	if (idx >= 0) {
		var pair = splitStringTokenizer(index[idx], '|');
		return eval("new Array("+pair[1]+")"); 
	}
	else	return null;
}

/**
*/
function getWordIndexViewer(word, index) {

	var l = 0, h = index.length, c = 0, pair;

	while ((h-l) > 1) {
		c = Math.floor((l+h) / 2);
		pair = splitStringTokenizer(index[c], '|');
		if (word < pair[0]) {
			h = c;
		}
		else {
			l = c;
		}
	}
	pair = splitStringTokenizer(index[l], '|');
	if (word == pair[0])
		return l;
	else	return -1;
}

/**
*/
function getLinePositionsViewer(words, index) {

	var number = words.length, line;
	var markpos = new Array(), idx = 0;
	var positions, position;

	for (var i=0; i < number; i++) {

		var s = words[i];
		var standType = getWritingStandardizer(s);
		var standardizer = getStandardizerSearchQuery(this.articleEltRef, standType);
		s = standardizer.standardizeWord(s);

		if (s != "" && (positions=this.getPositions(s, index, standardizer)) != null) {
			for (k=0; k < positions.length; k += 4) {
				position = new Array(positions[k], positions[k+1], 
						positions[k+2], positions[k+3]);
				markpos[idx++] = position;
			}
		}
	}
	markpos.sort(this.compare);

	var linePositions = new HashTable();
	for (var i=0; i < markpos.length; ) {
		positions = new Array(); idx = 0;
		line = markpos[i][0]; 
		for (; i < markpos.length && markpos[i][0] == line; i++) {
			positions[idx++] = markpos[i][1];
			positions[idx++] = markpos[i][2];
		}
		linePositions.put(line, positions);
	}
	return linePositions;
}

/** 
Constructor
*/
function Viewer(frame, words, eltRefTab, mark, index) {

	this.words = words; // array of strings
	this.elementReferenceTable = eltRefTab;
	this.mark = mark;
	this.frame = frame;
	this.index = index;

	this.print = printViewer;
	this.getEltRef = getEltRefViewer;
	this.compare = compareViewer;
	this.getPositions = getPositionsViewer;
	this.adjoinWordPositions = adjoinWordPositionsViewer;
	this.getWordPositions = getWordPositionsViewer;
	this.getWordPositionsWithIdx= getWordPositionsWithIdxViewer;
	this.getWordIndex = getWordIndexViewer;
	this.getLinePositions = getLinePositionsViewer;

	this.articleEltRef = this.getEltRef("Article");

	this.linePositions = this.getLinePositions(this.words, this.index);
	this.beginMark = "<span class=\"" + this.mark + "\">";
	this.endMark = "</span>";

	this.doc = this.frame.document;
}












/*
 *
 * Copyright 2006 Bled Internet, Inc. All Rights Reserved.
 * 
 * This software is the proprietary information of Bled Internet,   
 * Use is subject to license terms.
 * 
 */

var 	SEARCH_QUERY, 
	MESSAGE, 
	CELLS, 
	NEW_QUERY = false, 
	RESULTS = new Array(100), 
	ORDER = -1;

var PAGE_LINK, WORDS;
var PAGE = 0;
var INDEX_LOCATION = this.location.href;

/**
*/
function openResultPage(stringQuery, message, page) {

	message = message.replace(/\[/g, '&');

	var wgtH = new HashTable(), dstH = new HashTable();
	var indexReader = new IndexReader(IL, wgtH, dstH);
	var searchQuery = new SearchQuery(stringQuery, BE, "Article", indexReader);

	SEARCH_QUERY = searchQuery; MESSAGE = message; ;
	CELLS = searchQuery.getCellOrders();
	ORDER = (ORDER + 1) % 100;
	NEW_QUERY = true;

	loadResultPage(ORDER, page);
}

/**
*/
function loadResultPage(order, page) {

//	var loc = INDEX_LOCATION.replace(/index\.html/,
//				"Result.html?order=" + order + "&page=" + page);


	var resultHtml = "Result.html";
	if (OUTPUT_LANGUAGE == "arabic") {
		resultHtml = "ResultA.html";
	}
	var loc = INDEX_LOCATION.replace(/index\.html/, resultHtml);
	loc = loc.replace(/indexAR\.html/, resultHtml);
	top.mainFrame.location.href = loc;
	PAGE = page;
}

/**
*/
function execResultPage() {

	var resp = SEARCH_QUERY.evaluate();
	var result = new ResultPage(ORDER, resp, MESSAGE, top.mainFrame, SEARCH_QUERY, BE, BD);
	RESULTS[ORDER] = result;
}


/**
*/
function viewResultPage(order, page) {

	if (RESULTS != undefined && RESULTS[order] != undefined) {
		RESULTS[order].writePage(page);
	}
}


/**
*/
function openLink(doclink, jslink, wordsToMark) {

	PAGE_LINK = "../js/" + jslink;
	WORDS = wordsToMark;

	if (doclink.indexOf('Article') >= 0) {
		doclink = 'demo.html';
	}
	
	var loc = INDEX_LOCATION.replace(/index\.html/, doclink);
	loc = loc.replace(/indexAR\.html/, doclink);
	top.mainFrame.location.href = loc;
}

/**
*/
function execLink(doc, data, index, wordsToMark) {

	var st = new StringTokenizer(wordsToMark, "_");
	var viewer = new Viewer(doc, st.getArray(), BE, "mark", index);
	viewer.print(data);
}
