Filenames=new Array();
Titles=new Array();
Filenames[1]="SRD/Basics.html";
Titles[1]="SRD 3.5 > Basic Rules > Basics";
Filenames[8]="SRD/Description.html";
Titles[8]="SRD 3.5 > Basic Rules > Description";
Filenames[0]="SRD/AbilitiesandConditions.html";
Titles[0]="SRD 3.5 > Basic Rules > Special Abilities and Conditions";
Filenames[81]="SRD/TypesSubtypesAbilities.html";
Titles[81]="SRD 3.5 > Basic Rules > Types, Subtypes, and Special Abilities";
Filenames[15]="SRD/EpicLevelBasics.html";
Titles[15]="SRD 3.5 > Basic Rules > Epic Level Basics";
Filenames[66]="SRD/Races.html";
Titles[66]="SRD 3.5 > Races > Races";
Filenames[63]="SRD/PsionicRaces.html";
Titles[63]="SRD 3.5 > Races > Psionic Races";
Filenames[50]="SRD/MonstersasRaces.html";
Titles[50]="SRD 3.5 > Races > Monsters as Races";
Filenames[3]="SRD/ClassesI.html";
Titles[3]="SRD 3.5 > Classes > Classes I";
Filenames[4]="SRD/ClassesII.html";
Titles[4]="SRD 3.5 > Classes > Classes II";
Filenames[55]="SRD/PrestigeClasses.html";
Titles[55]="SRD 3.5 > Classes > Prestige Classes";
Filenames[13]="SRD/EpicClasses.html";
Titles[13]="SRD 3.5 > Classes > Epic Class Progressions";
Filenames[21]="SRD/EpicPrestigeClasses.html";
Titles[21]="SRD 3.5 > Classes > Epic Prestige Class Progressions";
Filenames[56]="SRD/PsionicClasses.html";
Titles[56]="SRD 3.5 > Classes > Psionic Classes";
Filenames[51]="SRD/NPCClasses.html";
Titles[51]="SRD 3.5 > Classes > NPC Classes";
Filenames[7]="SRD/CombinedSkills.html";
Titles[7]="SRD 3.5 > Skills > Combined Skills";
Filenames[24]="SRD/Feats.html";
Titles[24]="SRD 3.5 > Feats > Feats";
Filenames[14]="SRD/EpicFeats.html";
Titles[14]="SRD 3.5 > Feats > Epic Feats";
Filenames[65]="SRD/PsionicsFeats.html";
Titles[65]="SRD 3.5 > Feats > Psionic Feats";
Filenames[34]="SRD/MonsterFeats.html";
Titles[34]="SRD 3.5 > Feats > Monster Feats";
Filenames[5]="SRD/CombatI.html";
Titles[5]="SRD 3.5 > Combat > Combat I";
Filenames[6]="SRD/CombatII.html";
Titles[6]="SRD 3.5 > Combat > Combat II";
Filenames[23]="SRD/Equipment.html";
Titles[23]="SRD 3.5 > Equipment and Gear > Equipment";
Filenames[67]="SRD/SpecialMaterials.html";
Titles[67]="SRD 3.5 > Equipment and Gear > Special Materials";
Filenames[27]="SRD/MagicItemsI.html";
Titles[27]="SRD 3.5 > Equipment and Gear > Magic Items I";
Filenames[28]="SRD/MagicItemsII.html";
Titles[28]="SRD 3.5 > Equipment and Gear > Magic Items II";
Filenames[29]="SRD/MagicItemsIII.html";
Titles[29]="SRD 3.5 > Equipment and Gear > Magic Items III";
Filenames[30]="SRD/MagicItemsIV.html";
Titles[30]="SRD 3.5 > Equipment and Gear > Magic Items IV";
Filenames[31]="SRD/MagicItemsV.html";
Titles[31]="SRD 3.5 > Equipment and Gear > Magic Items V";
Filenames[32]="SRD/MagicItemsVI.html";
Titles[32]="SRD 3.5 > Equipment and Gear > Magic Items VI";
Filenames[16]="SRD/EpicMagicItems1.html";
Titles[16]="SRD 3.5 > Equipment and Gear > Epic Magic Items 1";
Filenames[17]="SRD/EpicMagicItems2.html";
Titles[17]="SRD 3.5 > Equipment and Gear > Epic Magic Items 2";
Filenames[57]="SRD/PsionicItems.html";
Titles[57]="SRD 3.5 > Equipment and Gear > Psionic Items";
Filenames[2]="SRD/CarryingandExploration.html";
Titles[2]="SRD 3.5 > Adventuring > Carrying, Movement, and Exploration";
Filenames[52]="SRD/Planes.html";
Titles[52]="SRD 3.5 > Adventuring > Planes";
Filenames[79]="SRD/Traps.html";
Titles[79]="SRD 3.5 > Adventuring > Traps";
Filenames[80]="SRD/Treasure.html";
Titles[80]="SRD 3.5 > Adventuring > Treasure";
Filenames[82]="SRD/WildernessandEnvironment.html";
Titles[82]="SRD 3.5 > Adventuring > Wilderness, Weather, and Environment";
Filenames[20]="SRD/EpicObstacles.html";
Titles[20]="SRD 3.5 > Adventuring > Epic Obstacles";
Filenames[33]="SRD/MagicOverview.html";
Titles[33]="SRD 3.5 > Spells > Magic Overview";
Filenames[68]="SRD/SpellListI.html";
Titles[68]="SRD 3.5 > Spells > Spell List I";
Filenames[69]="SRD/SpellListII.html";
Titles[69]="SRD 3.5 > Spells > Spell List II";
Filenames[70]="SRD/SpellsA-B.html";
Titles[70]="SRD 3.5 > Spells > Spells";
Filenames[71]="SRD/SpellsC.html";
Titles[71]="SRD 3.5 > Spells > Spells";
Filenames[72]="SRD/SpellsD-E.html";
Titles[72]="SRD 3.5 > Spells > Spells";
Filenames[73]="SRD/SpellsF-G.html";
Titles[73]="SRD 3.5 > Spells > Spells";
Filenames[74]="SRD/SpellsH-L.html";
Titles[74]="SRD 3.5 > Spells > Spells";
Filenames[75]="SRD/SpellsM-O.html";
Titles[75]="SRD 3.5 > Spells > Spells";
Filenames[76]="SRD/SpellsP-R.html";
Titles[76]="SRD 3.5 > Spells > Spells";
Filenames[77]="SRD/SpellsS.html";
Titles[77]="SRD 3.5 > Spells > Spells";
Filenames[78]="SRD/SpellsT-Z.html";
Titles[78]="SRD 3.5 > Spells > Spells";
Filenames[22]="SRD/EpicSpells.html";
Titles[22]="SRD 3.5 > Spells > Epic Spells";
Filenames[64]="SRD/PsionicSpells.html";
Titles[64]="SRD 3.5 > Spells > Psionic Spells";
Filenames[54]="SRD/PowersOverview.html";
Titles[54]="SRD 3.5 > Psionics > Psionic Powers Overview";
Filenames[53]="SRD/PowerList.html";
Titles[53]="SRD 3.5 > Psionics > Power List";
Filenames[59]="SRD/PsionicPowersA-C.html";
Titles[59]="SRD 3.5 > Psionics > Psionic Powers";
Filenames[60]="SRD/PsionicPowersD-F.html";
Titles[60]="SRD 3.5 > Psionics > Psionic Powers";
Filenames[61]="SRD/PsionicPowersG-P.html";
Titles[61]="SRD 3.5 > Psionics > Psionic Powers";
Filenames[62]="SRD/PsionicPowersQ-W.html";
Titles[62]="SRD 3.5 > Psionics > Psionic Powers";
Filenames[43]="SRD/MonstersIntro-A.html";
Titles[43]="SRD 3.5 > Monsters > Monsters";
Filenames[36]="SRD/MonstersB-C.html";
Titles[36]="SRD 3.5 > Monsters > Monsters";
Filenames[37]="SRD/MonstersD-De.html";
Titles[37]="SRD 3.5 > Monsters > Monsters";
Filenames[38]="SRD/MonstersDi-Do.html";
Titles[38]="SRD 3.5 > Monsters > Monsters";
Filenames[39]="SRD/MonstersDr-Dw.html";
Titles[39]="SRD 3.5 > Monsters > Monsters";
Filenames[40]="SRD/MonstersE-F.html";
Titles[40]="SRD 3.5 > Monsters > Monsters";
Filenames[41]="SRD/MonstersG.html";
Titles[41]="SRD 3.5 > Monsters > Monsters";
Filenames[42]="SRD/MonstersH-I.html";
Titles[42]="SRD 3.5 > Monsters > Monsters";
Filenames[44]="SRD/MonstersK-L.html";
Titles[44]="SRD 3.5 > Monsters > Monsters";
Filenames[45]="SRD/MonstersM-N.html";
Titles[45]="SRD 3.5 > Monsters > Monsters";
Filenames[46]="SRD/MonstersO-R.html";
Titles[46]="SRD 3.5 > Monsters > Monsters";
Filenames[47]="SRD/MonstersS.html";
Titles[47]="SRD 3.5 > Monsters > Monsters";
Filenames[48]="SRD/MonstersT-Z.html";
Titles[48]="SRD 3.5 > Monsters > Monsters";
Filenames[35]="SRD/MonstersAnimals.html";
Titles[35]="SRD 3.5 > Monsters > Monsters";
Filenames[49]="SRD/MonstersVermin.html";
Titles[49]="SRD 3.5 > Monsters > Monsters";
Filenames[18]="SRD/EpicMonsters(A-E).html";
Titles[18]="SRD 3.5 > Monsters > Epic Monsters";
Filenames[19]="SRD/EpicMonsters(G-W).html";
Titles[19]="SRD 3.5 > Monsters > Epic Monsters";
Filenames[58]="SRD/PsionicMonsters.html";
Titles[58]="SRD 3.5 > Monsters > Psionic Monsters";
Filenames[25]="SRD/Improving Monsters.html";
Titles[25]="SRD 3.5 > Monsters > Improving Monsters";
Filenames[12]="SRD/DivineRanksandPowers.html";
Titles[12]="SRD 3.5 > Divine Characters > Divine Ranks and Powers";
Filenames[9]="SRD/DivineAbilitiesandFeats.html";
Titles[9]="SRD 3.5 > Divine Characters > Salient Divine Abilities";
Filenames[10]="SRD/DivineDomainsandSpells.html";
Titles[10]="SRD 3.5 > Divine Characters > Domains and Spells";
Filenames[11]="SRD/DivineMinions.html";
Titles[11]="SRD 3.5 > Divine Characters > Divine Minions";
Filenames[26]="SRD/Legal.html";
Titles[26]="SRD 3.5 > Legal > Legal Information";
Topics=new Array();
TopicNames=new Array();
Keywords=new Array();
FetchedBlocks = new Array();
FetchedTopics = new Array();


// Porter Stemming stuff
step2list = new Array();
step2list["ational"]="ate";
step2list["tional"]="tion";
step2list["enci"]="ence";
step2list["anci"]="ance";
step2list["izer"]="ize";
step2list["bli"]="ble";
step2list["alli"]="al";
step2list["entli"]="ent";
step2list["eli"]="e";
step2list["ousli"]="ous";
step2list["ization"]="ize";
step2list["ation"]="ate";
step2list["ator"]="ate";
step2list["alism"]="al";
step2list["iveness"]="ive";
step2list["fulness"]="ful";
step2list["ousness"]="ous";
step2list["aliti"]="al";
step2list["iviti"]="ive";
step2list["biliti"]="ble";
step2list["logi"]="log";

step3list = new Array();
step3list["icate"]="ic";
step3list["ative"]="";
step3list["alize"]="al";
step3list["iciti"]="ic";
step3list["ical"]="ic";
step3list["ful"]="";
step3list["ness"]="";

c = "[^aeiou]";          // consonant
v = "[aeiouy]";          // vowel
C = c + "[^aeiouy]*";    // consonant sequence
V = v + "[aeiou]*";      // vowel sequence

mgr0 = "^(" + C + ")?" + V + C;               // [C]VC... is m>0
meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";  // [C]VC[V] is m=1
mgr1 = "^(" + C + ")?" + V + C + V + C;       // [C]VCVC... is m>1
s_v   = "^(" + C + ")?" + v;                   // vowel in stem

currentSearch = "";
currentMode = "";
currentTopic = "";

resultPages = new Array();
resultSearch = new Array();
resultMode = new Array();
resultID = new Array();

origSearch = "";

var numbits=10;
var numbitsize = 1 << numbits;
var addrsize = 16;
var posmask = 0xFFFF;

NS4 = (document.layers);
IE4 = (document.all);

Netscape = navigator.appName == "Netscape";
MSIE = navigator.appName == "Microsoft Internet Explorer";

exclude_words = new RegExp("^(and|or|the|it|is|an|on|we|us|to|of|has|be|all|for|in|as|so|are|that|can|you|at|its|by|have|with|into)$","i");
exclude_words2 = new RegExp("\\b(and|or|the|it|is|an|on|we|us|to|of|has|be|all|for|in|as|so|are|that|can|you|at|its|by|have|with|into)\\b","gmi");
normalizeSpaces = new RegExp("\\s+","gm");

docurl = "doc/";

bookmarks = null;
bookmarkArray = new Array();
bookMarkIndex = 0;
bookMarkPath = "";
bookMarkURI = "";
lastBookmark = 0;
var now = new Date();
today = new Date();
maxExpire = new Date(today.getTime() + 365*60*60*24*1000);
cookiesEnabled = testCookies();
startDragID = -1;
endDragID = -1;
dragdropObj = null;
visibleNodes = new Array();
visibleNodesByName = new Array();

curframesizes = null;
frameSize = null;
curFrameSize = null;
minFrameSize = 25;

storagePath = "";
maxStorage = 9;
storageArray = null;
storageBasePath = "";
storageURI = "";

function hideFrame(framename) {
	if (!curframesizes) {
		curframesizes = top.document.getElementById("left_column").getAttribute('rows').split(",");
		frameSize = new Array();
		curFrameSize = new Array();
		var frames = top.document.getElementById("left_column").getElementsByTagName('frame');
		for(var i=0;i<frames.length;i++) {
			var fname = frames[i].getAttribute('name');
			frameSize[fname] = curframesizes[i];
			curFrameSize[fname] = curframesizes[i];
		}		
	}
	
	if (curFrameSize[framename] > minFrameSize) {
		curFrameSize[framename] = minFrameSize;
		var res = "";
		for (var i in curFrameSize) {
			if (res != "") res += ",";
			res += curFrameSize[i];
		}
		top.document.getElementById("left_column").setAttribute('rows',res);
		top.frames[framename].document.getElementById("show").innerHTML = "<a href=\"javascript:top.hideFrame('" + framename + "');\">Show</a>";
	} else {
		curFrameSize[framename] = frameSize[framename];
		var res = "";
		for (var i in curFrameSize) {
			if (res != "") res += ",";
			res += curFrameSize[i];
		}
		top.document.getElementById("left_column").setAttribute('rows',res);
		top.frames[framename].document.getElementById("show").innerHTML = "<a href=\"javascript:top.hideFrame('" + framename + "');\">Hide</a>";		
	}
}



function onNewURL() {
	currentTopic = top.frames.contents.document.location.href.split('#')[1];
	var fullURL = top.frames.contents.document.location.href.split('#')[0];
	var urlArray = fullURL.split('/');
	var curPath = new Array();
	for(var i=urlArray.length-1;i>=0;i--) {
		var cur = urlArray.pop();
		if (cur != "doc") {
			curPath.unshift(cur);	
		} else {
			break;
		}
	}
	var curPage = curPath.join('/');
	
	
	if (currentSearch.length > 0) {
		var cmd = "searchHighlight(currentSearch, currentTopic, currentMode);";
		setTimeout(cmd,1);
	}
	
	top.frames.path.document.getElementById("docpath").innerHTML = "<b>" + top.frames.contents.document.title + "</b>";

	var divs = top.frames.contents.document.getElementsByTagName("div");
	var i;
	for (i=0;i<divs.length;i++) {
		var node = divs[i];
		var level = node.getAttribute('level');
		if (level && level > 0 && level < 8) {
			var anchor = node.getElementsByTagName("a")[0];
			var n = node.getElementsByTagName('h' + level)[0];
			
			if (n) {
				
				var bm = top.frames.contents.document.createElement("a");
				bm.href = "javascript:top.addBookmark('" + anchor.getAttribute('topic') + "','" + curPage + "#" + anchor.getAttribute('name') + "');";
				
				var text = top.frames.contents.document.createTextNode(" [bookmark]");
				bm.appendChild(text);

				var font = top.frames.contents.document.createElement("font");
				font.style.fontSize = "10px";
				font.appendChild(bm);
				
				n.appendChild(font);
			}
		}
		
	}


}

function doSearch(SearchWord,matchType,contentFilter,resultsPerPage,currentPage,currentIndex) {
	currentSearch = "";
	currentMode = "";
	currentTopic = "";
	
	SearchWord = unescape(SearchWord);
	matchType = unescape(matchType);
	contentFilter = unescape(contentFilter);
	resultsPerPage = unescape(resultsPerPage);
	currentPage = unescape(currentPage);
	
	if (typeof(currentIndex) == "undefined") { 
		currentIndex = 0;
	}
	
	var cmd = "top.doSearch2('" + escape(SearchWord) + "','" + escape(matchType) + "','" + escape(contentFilter) + "','" + escape(resultsPerPage) + "','" + escape(currentPage) + "'," + currentIndex + ");";
	top.setTimeout(cmd,1);
	top.frames.path.document.getElementById("docpath").innerHTML = "<b>Searching, please wait...</b>";
}

function doSearch2(SearchWord,matchType,contentFilter,resultsPerPage,currentPage,currentIndex) {
	
	SearchWord = unescape(SearchWord);
	matchType = unescape(matchType);
	contentFilter = unescape(contentFilter);
	resultsPerPage = unescape(resultsPerPage);
	currentPage = unescape(currentPage);
	
	var AltSearchWord="";
	var ResFound=false;
	var SamePage=false;
	origSearch=SearchWord;
	var Result2="";
	var Result3="";
	var MinResults=Number(currentPage)*Number(resultsPerPage);
	var MaxResults=MinResults+Number(resultsPerPage);
	var NrRes=0;
	var resCount = 0;
	var excluded = "";
	
	var searchID = origSearch + '|' + matchType + '|' + contentFilter + '|' + resultsPerPage;
	if (searchID in resultID && currentIndex == 0) {
		top.frames.contents.document.location.href = "search/search_results.html?searchid=" + resultID[searchID];
		return;
	}
	
	if(SearchWord.length>=1){
		SearchWord=SearchWord.toLowerCase();
	
		while(SearchWord.indexOf("<")>-1 || SearchWord.indexOf(">")>-1 || SearchWord.indexOf('"')>-1) {
			SearchWord=SearchWord.replace("<","&lt;").replace(">","&gt;").replace('"',"&quot;");
		}
		
		try {
			this.status="Searching, please wait...";
		} catch(e) {
			//alert(e);
		}
		BeginTime=new Date();
		
		var k;
		var l;
		var normalizeSpaces = new RegExp("\\s+","gm");
		var dashes = new RegExp("\\-","g");
		var stripQuote = new RegExp("^(.+?)[^a-zA-Z0-9]([a-zA-Z0-9])$");
		var isnumber = new RegExp("^[0-9]+");
		var hasdash = new RegExp("-");
		var fr_a = new RegExp ("[âà]","gm");
		var fr_e = new RegExp ("[êèéë]","gm");
		var fr_i = new RegExp ("[îï]","gm");
		var fr_o = new RegExp ("[ôö]","gm");
		var fr_u = new RegExp ("[ûùü]","gm");
		SearchWord = SearchWord.replace(normalizeSpaces," ");
		AltSearchWord = SearchWord.replace(dashes," ").replace(normalizeSpaces," ").replace(fr_a,"a").replace(fr_e,"e").replace(fr_i,"i").replace(fr_o,"o").replace(fr_u,"u");
		var exactMatch = new RegExp("\\b("+SearchWord+")\\b","mi");
		var altMatch = new RegExp("\\b("+AltSearchWord+")\\b","mi");
		
		
		var origwords = AltSearchWord.split(" ");
		var words = new Array();
		var nwlen = 0;
		for(k=0;k<origwords.length;k++) {
			if (exclude_words.test(origwords[k].toLowerCase())) {
				excluded = excluded + origwords[k] + " ";
			} else {
				if (isnumber.test(origwords[k])) {
					words[nwlen++] = origwords[k];
				} else {
					if (matchType == "exact") {
						words[nwlen] = origwords[k];
					} else {
						words[nwlen] = stemWord(origwords[k].toLowerCase().replace(stripQuote,"$1$2"));
						//alert(words[nwlen]);
					}
					if (words[nwlen] == "length") {
						words[nwlen] = "length_";	
					}
					nwlen++;
				}
			}
		}

		var respos = new Array();
		var matched = 0;
		for(k=0;k<words.length;k++) {
			if (!(words[k] in Keywords)) {
				var ret = fetchWebPage("keywords/k_" + words[k].substr(0,2) + ".js");
				//var ret = fetchWebPage("keywords/k_" + words[k] + ".js");
				if (ret.length > 0) {
					eval(ret);	
				}
			}
			
			var maxmatch = 0;
			if (words[k] in Keywords) {
				for(l=0;l<Keywords[words[k]].length;l++) {
					var f = String(Keywords[words[k]][l]);
					if (typeof(respos[f]) == "undefined") { respos[f] = 1; }
					else { respos[f]++; }
					ResFound = true;
					matched++;
					if (respos[f] > maxmatch) { maxmatch = respos[f]; }
				}
			} else {
				if (matchType == "all" || matchType == "exact") {
					ResFound = false;
					break;
				}
			}
			
		}
		if (matched == 0) { ResFound = false; }
		else {
			if (matchType == "any") {
				respos = sortByValue(respos,maxmatch);	
			}
		}
		
		var index = 0;
		var matchindex = 0;
		resCount = MinResults;
		if (ResFound) {
			var results = new Array();
			
			var docFilter = new RegExp(contentFilter,"mi");
			var found = false;
			
			for(k in respos) {
				if (index >= currentIndex && (matchType == "any" || ((matchType == "all" || matchType == "exact") && Number(respos[k]) >= words.length)) ) {
					var docnum = Number(k) >> addrsize;
					if (resCount < MaxResults) {
						if (docFilter.test(Filenames[docnum])) {
							if (matchType == "exact") {
								var res = fetchBlock(getHexAddress(k));
								var normMatch = exactMatch.test(res);
								var otherMatch = altMatch.test(res);
								var matchTerm = "";
								if (normMatch) matchTerm = SearchWord;
								else if (otherMatch) matchTerm = AltSearchWord;
									
								if (normMatch || otherMatch) {
									var re = new RegExp("(\\b.{0,50}\\b" + matchTerm + "\\b.{0,50}\\b)","mi");
									if (re.test(res)) {
										var fp = re.exec(res);
										res = "<b>...</b> " + fp[1] + " <b>...</b>";
										
										re = new RegExp("(\\b" + matchTerm + ".*?\\b)","gmi");
										res = res.replace(re,"<b>$1</b>");
									
										cururl = fetchURLName(k,matchType);
									
										if (!(cururl in results)) {
											results[cururl] = new Array();
										}					
										results[cururl].push(res);
										found = true;
										resCount++;
										matchindex = index;
									}
								}
							} else {
								var ok = false;
								var res = fetchBlock(getHexAddress(k));
	
								var resstr = "";
								for(l=0;l<words.length;l++) {
									var re = new RegExp("(\\b.{0,50}\\b" + words[l] + ".{0,50}\\b)","mi");
									if (re.test(res)) {
										ok = true;
										var fp = re.exec(res);
										resstr = resstr + "<b>...</b> " + fp[1];
									}
								}
								
								res = resstr + " <b>...</b>";						
																
								for(l=0;l<words.length;l++) {
									var re = new RegExp("(\\b" + words[l] + ".*?\\b)","gmi");
									res = res.replace(re,"<b>$1</b>");
								}
								if (ok) {
									cururl = fetchURLName(k,matchType);
									if (!(cururl in results)) {
										results[cururl] = new Array();
									}					
									results[cururl].push(res);
									found = true;
									resCount++;
									matchindex = index;
								}
							}
						}
					} else {
						resCount++;	
					}
				}
				index++;				
			}

			var resNumber = MinResults + 1;
			for(var curl in results) {
				if (results[curl].length > 0) {
					Result3 += "<p>\n";
					Result3 += resNumber++ + ". " + curl + "<br>\n";
					for (var z=0;z<results[curl].length;z++) {
						Result3 += results[curl][z];
					}
				}
			}
			
			
			
		}
		if(!ResFound) {
			Result3+="<CENTER><U>No results found!</U></CENTER>\n";
		}
		Result3+="<P><CENTER>"
	
		Result3+="<form name='search' action='javascript:top.doSearch(document.search.query.value,document.search.match.value,document.search.where.value,document.search.max.value,document.search.curpage.value," + Number(matchindex+1) + ");'>\n";
		Result3+="<input type='hidden' name='query' value=\"" + escape(origSearch) + "\">\n";
		Result3+="<input type='hidden' name='match' value='" + escape(matchType) + "'>\n";
		Result3+="<input type='hidden' name='where' value='" + escape(contentFilter) + "'>\n";
		Result3+="<input type='hidden' name='max' value='" + resultsPerPage + "'>\n";
		Result3+="<input type='hidden' name='curpage' value='" + String(Number(currentPage)+1) + "'>\n";
		Result3+="</form>\n";
		
		Result3+="<a href='javascript:history.back()'>Go Back</a>&nbsp;|&nbsp;\n";
		Result3+="<a href='#'>Go to Top</a>\n";
		if (resNumber < resCount) {
			Result3+="&nbsp;|&nbsp;<a href='javascript:document.search.submit()'>Next " + resultsPerPage + "</a>\n";
		}
		
		//Result3+="</CENTER></td></tr></table></center></BODY></HTML>";
		Result2="<center>About <B>"+ Number(resCount) +"</B> result(s) found";
		Result2+=" for <B>"+SearchWord+"</B>. Search took <B>";
		Result2+=(Math.floor((new Date()-BeginTime)/10)/100)+"</B> second(s).";
		if (excluded.length > 0) {
			Result2+="<br>The following words were excluded from the search: <b>" + excluded + "</b>";
		}
		Result2+="</center><P>";
		
		try {
			this.status="Done";
		} catch(e) {
		
		}
		
		top.frames.contents.document.location.href = "search/search_results.html?searchid=" + resultPages.length;
		if (!(searchID in resultID)) resultID[searchID] = resultPages.length;
		resultPages.push(Result2+Result3);
		resultSearch.push(origSearch);
		resultMode.push(matchType);
		
	} else {
		this.status="Error: You must enter at least 1 character(s)!";
	}
	
	origSearch = "";
	matchType = "";
}  

function setSearchContent() {
	var pageNum = query(top.frames.contents,'searchid');
	var cmd;
	if (pageNum in resultPages) {
		currentSearch = resultSearch[pageNum];
		currentMode = resultMode[pageNum];
		cmd = 'top.frames.contents.document.getElementById("search_results").innerHTML = resultPages[' + pageNum + '];';
	} else {
		cmd = 'top.frames.contents.document.getElementById("search_results").innerHTML = "<b>This search has expired. Please start a new search.</b>";';
	}
	
	top.setTimeout(cmd,1);
}

 function query(targetWindow,element){
        var queryString = queryParse(targetWindow.document.location.href);
        for (varval in queryString) {
                varvalArray = queryString[varval].split('=');
                if ( varvalArray[0] == element ) {
                        return varvalArray[1];
                }
        }
        return '';
 }

function queryParse(queryString){
    queryStr = '' + queryString;
    querySpg = queryStr.lastIndexOf('?')+1;
    if ( querySpg > 0 ) {
            queryStr = queryStr.substring(querySpg);
    } else {
            queryStr = '';
    }
    return unescape(queryStr).split('&');
 }

function sortByValue(myArray,maxValue) {
	var result = new Array();
	for (var i=maxValue;i>0;i--) {
		for (var j in myArray) {
			if (myArray[j] == i) {
				result[String(j)] = i;
			}	
		}
	}
	return result;
}

function getHexAddress(text) {
	var result = Number(text).toString(16);
	while (result.length < 5) {
		result = "0" + result;	
	} 	
	
	result = "0x" + result.toUpperCase();
	
	return result;
}

function fetchURLName(addr,matchType) {
	var docnum = Number(addr) >> addrsize;
	var topic = "";
	var topIndex = getHexAddress(addr);
	
	if (!(topIndex in Topics)) {
		var ret = fetchWebPage("topics/" + topIndex.substr(0,4) + ".js");
		if (ret.length > 0) {
			eval(ret);	
		}
	}
	
	if (topIndex in Topics) {
		topic = Topics[topIndex];	
	}
	
	var cururl;
	var title = "";;		
	if (topic.length > 1) {
		if (topIndex in Topics) { title = unescape(TopicNames[topIndex]); }
		else { title = Filenames[docnum] + "#" + topic; }
	} else {
		var title;
		if (docnum in Titles) { title = Titles[docnum]; }
		else { title = Filenames[docnum]; }
		//cururl = "<a href='../" + docurl + escape(Filenames[docnum]) + "#" + topic + "' target='contents'>" + title + "</a>";
	}
	
	cururl = "<a href='../" + docurl + escape(Filenames[docnum]) + "#" + topic + "' target='contents'>" + title + "</a>";
	//TopicNamesURL[topic] = title;
	
	return cururl;
}

function fetchBlock(blocknum) {

	var result = "";	
	if (typeof(blocknum) != "undefined") {
		var res;
		if (blocknum in FetchedBlocks) {
			res = FetchedBlocks[blocknum];
		} else {
			res = fetchWebPage("blocks/" + blocknum + ".txt");
			FetchedBlocks[blocknum] = res;
		}
		result = res;
	}
	return result;
}

function fetchWebPage(url) {
	if (typeof(url) != "undefined") {
		url = "search/" + url;	

		var p;
		try {
	  		p = new XMLHttpRequest();
		} catch (e) {
	  		p = new ActiveXObject("Msxml2.XMLHTTP");
		}
		
		p.open("GET", url, false);
		
		try {
			p.send(null);
			return p.responseText;
		} catch (e) {
			return "";
		}
	} else {
		return "";	
	}

}

function fetchWebPageAny(url) {
	if (typeof(url) != "undefined") {
		//url = "search/" + url;	

		var p;
		try {
	  		p = new XMLHttpRequest();
		} catch (e) {
	  		p = new ActiveXObject("Msxml2.XMLHTTP");
		}
		
		p.open("GET", url, false);
		
		try {
			p.send(null);
			return p.responseText;
		} catch (e) {
			return "";
		}
	} else {
		return "";	
	}

}

function stemWord(w) {
	var stem;
	var suffix;
	var firstch;
	var origword = w;
	
	if (w.length < 3) { return w; }
   	
   	var re;
   	var re2;
   	var re3;
   	var re4;

	firstch = w.substr(0,1);
	if (firstch == "y") {
		w = firstch.toUpperCase() + w.substr(1);
	}

	// Step 1a
   	re = /^(.+?)(ss|i)es$/;
   	re2 = /^(.+?)([^s])s$/;
   	
   	if (re.test(w)) { w = w.replace(re,"$1$2"); }
   	else if (re2.test(w)) {	w = w.replace(re2,"$1$2"); }

	// Step 1b
	re = /^(.+?)eed$/;
	re2 = /^(.+?)(ed|ing)$/;
	if (re.test(w)) {
		var fp = re.exec(w);
		re = new RegExp(mgr0);
		if (re.test(fp[1])) {
			re = /.$/;
			w = w.replace(re,"");
		}
	} else if (re2.test(w)) {
		var fp = re2.exec(w);
		stem = fp[1];
		re2 = new RegExp(s_v);
		if (re2.test(stem)) {
			w = stem;
			re2 = /(at|bl|iz)$/;
			re3 = new RegExp("([^aeiouylsz])\\1$");
			re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
			if (re2.test(w)) {	w = w + "e"; }	
			else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); }
			else if (re4.test(w)) { w = w + "e"; }
		}
	}

	// Step 1c
	re = /^(.+?)y$/;
	if (re.test(w)) {
		var fp = re.exec(w);
		stem = fp[1];
		re = new RegExp(s_v);
		if (re.test(stem)) { w = stem + "i"; }
	} 

	// Step 2
	re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
	if (re.test(w)) {
		var fp = re.exec(w);
		stem = fp[1];
		suffix = fp[2];
		re = new RegExp(mgr0);
		if (re.test(stem)) {
			w = stem + step2list[suffix];	
		}
	}

	// Step 3
	re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
	if (re.test(w)) {
		var fp = re.exec(w);
		stem = fp[1];
		suffix = fp[2];
		re = new RegExp(mgr0);
		if (re.test(stem)) {
			w = stem + step3list[suffix];	
		}			
	}

	// Step 4
	re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
	re2 = /^(.+?)(s|t)(ion)$/;
	if (re.test(w)) {
		var fp = re.exec(w);
		stem = fp[1];
		re = new RegExp(mgr1);
		if (re.test(stem)) {
			w = stem;
		}	
	} else if (re2.test(w)) {
		var fp = re2.exec(w);
		stem = fp[1] + fp[2];
		re2 = new RegExp(mgr1);
		if (re2.test(stem)) {
			w = stem;	
		}	
	}

	// Step 5
	re = /^(.+?)e$/;
	if (re.test(w)) {
		var fp = re.exec(w);
		stem = fp[1];
		re = new RegExp(mgr1);
		re2 = new RegExp(meq1);
		re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
		if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
			w = stem;
		}
	}	
	
	re = /ll$/;
	re2 = new RegExp(mgr1);
	if (re.test(w) && re2.test(w)) {
		re = /.$/;
		w = w.replace(re,"");		
	}

	// and turn initial Y back to y

	if (firstch == "y") {
		w = firstch.toLowerCase() + w.substr(1);
	}
		
	return w;	
	
}

function isLetter(c) { 
  return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}

/* http://www.kryogenix.org/code/browser/searchhi/ */
/* Modified 20021006 to fix query string parsing and add case insensitivity */
function highlightWord(node,word) {
	var doc = top.frames.contents.document;

	// Iterate into this nodes childNodes
	if (node.hasChildNodes) {
		var hi_cn;
		for (hi_cn=0;hi_cn<node.childNodes.length;hi_cn++) {
			highlightWord(node.childNodes[hi_cn],word);
		}
	}
	
	// And do this node itself
	if (node.nodeType == 3) { // text node
		tempNodeVal = node.nodeValue.toLowerCase();
		if (tempNodeVal.length >= word.length) {
			tempWordVal = word.toLowerCase();
			if (tempNodeVal.indexOf(tempWordVal.substr(0,4)) != 1) {
				var ni = tempNodeVal.indexOf(tempWordVal);
				if (ni != -1) {
					pn = node.parentNode;
					if (pn.className != "searchword") {
						// word has not already been highlighted!
						nv = node.nodeValue;
						// Create a load of replacement nodes
						before = doc.createTextNode(nv.substr(0,ni));
						docWordVal = nv.substr(ni,word.length);
						after = doc.createTextNode(nv.substr(ni+word.length));
						hiwordtext = doc.createTextNode(docWordVal);
						hiword = doc.createElement("span");
						hiword.setAttribute('name','searchspan');
						hiword.className = "searchword";
						hiword.appendChild(hiwordtext);
						pn.insertBefore(before,node);
						pn.insertBefore(hiword,node);
						pn.insertBefore(after,node);
						pn.removeChild(node);
					}
				}
			}
		}
	}
}

function searchHighlight(toFind, theTopic, searchMode) {
	if( !toFind || !theTopic) { return; }

	var doc = top.frames.contents.document;

	if (!doc.createElement) return;
	var words = new Array();
	if (searchMode == "exact") {
		words[0] = toFind;
	} else {
		words = toFind.split(" ");		
	}

	var node = doc.getElementsByName(theTopic)[0];
	var i;
	var sibprev	= node.previousSibling;
	var sibnext	= node.nextSibling;
	for(i=0;i<50;i++) {
		if (sibprev) {
			if (sibprev.nodeName.toLowerCase() == "p" || sibprev.nodeName.toLowerCase() == "ul" || sibprev.nodeName.toLowerCase() == "table") {
				var w;
				for (w=0;w<words.length;w++) highlightWord(sibprev,unescape(words[w]));
			}
			sibprev = sibprev.previousSibling;
		}
		
		if (sibnext) {
			if (sibnext.nodeName.toLowerCase() == "p" || sibnext.nodeName.toLowerCase() == "ul" || sibnext.nodeName.toLowerCase() == "table") {
				var w;
				for (w=0;w<words.length;w++) highlightWord(sibnext,unescape(words[w]));
			}
			sibnext = sibnext.nextSibling;
		}
	}

	currentSearch = "";
	currentMode = "";
	currentTopic = "";

}

function removeHighlights() {
	var doc = top.frames.contents.document;
	var nodes = doc.getElementsByTagName("span");
	var i;
	for (i=0;i<nodes.length;i++) {
		nodes[i].className = "XXX";	
	}
	
}


/////// Bookmark and drag and drop stuff

function testCookies() {
	var str = "teststring";
	setCookie("testcookie",str);
	var res = getCookie("testcookie");
	clearCookie("testcookie");

	if (str == res) return true;
	return false;
}

function saveFile(filename, contents) {
	if (!xulFileWrite(filename,contents)) {
		if (!saveTextFile(filename,contents,true)) {
			alert("Failed to save bookmarks. Sorry, but I don't think I can save them on your browser...");	
		}
	}	
}

function loadStorage(uri,data) {
	var geturi = new RegExp("^(.+?\\\\)[^\\\\]+$");
	storageBasePath = uri.replace(geturi,"$1");
	storageURI = uri;
}

function getStorage() {
	storageArray = new Array();
	for(var i=0;i<=maxStorage;i++) {
		var fname = "storage" + i;
		var data = getCookieDataPlain(top.frames[fname].getCookie(),"s");
		//alert(top.frames[fname].getCookie());
		//alert(fname + " : " + data);
		if (data != "") storageArray.push(data);
		else break;
	}
}

function isParent(pid,cid) {
	if (pid == 0) return true;
	
	var up = cid;
	for(i=0;i<10;i++) {
		if (bookmarkArray[up-1]) up = bookmarkArray[up-1].parentid;
		else return false;
		//alert("PID " + pid + " CID " + cid + " UP " + up);
		if (up == 0 || typeof(up) == "undefined") return false;
		if (pid == up) return true;
	}
	
	return false;
}

function getBookmarkPath() {
	var bmpath = top.frames.bookmarks_window.document.location.pathname.split("/");
	var respath = new Array();
	for(var i=1;i<bmpath.length-1;i++) {
		respath.push(bmpath[i]);
	}
	
	respath.push("bookmarks.txt");
	
	return respath.join("\\\\");
}

function getBookmarkURI() {
	var bmpath = top.frames.bookmarks_window.document.location.href.split(".html");

	return bmpath[0] + ".txt";
}


function loadBookmarks() {
	cookiesEnabled = testCookies();
	
	var doc = XmlDocument.create();
	var ok = false;
	if (cookiesEnabled) {
		var str = "";
		
		getStorage();
		
		if (storageArray) {
			str = unescape(storageArray.join(""));
		}
		
		if (str) {
			//alert(str);
			ok = true;
			doc.loadXML(str);
		}
	} else {
		bookmarkURI = getBookmarkURI();
   		var str = fetchWebPageAny(bookmarkURI);
		if (str) {
			ok = true;
			doc.loadXML(str);
		}
	}
	
	if (ok) {
		var nodes = doc.getElementsByTagName("bookmark");
		if (nodes.length > 0) {
			bookmarkArray = new Array();
			for(var i=0;i<nodes.length;i++) {
				var items = nodes[i].getElementsByTagName("item");
				if (items.length > 0) {
					var bm = new Array();
					for(var j=0;j<items.length;j++) {
						var attr = items[j].getAttribute('name');
						bm[attr] = (items[j].textContent ? unescape(items[j].textContent) : unescape(items[j].text));
					}
					bookmarkArray.push(bm);
				}
				
			}
		}
	}
}


function saveBookmarks() {
	cookiesEnabled = testCookies();
	
	var doc = XmlDocument.create();
	var root = doc.createElement("bookmarks");
	doc.appendChild(root);
	for (var i=0;i<bookmarkArray.length;i++) {
		var j;
		var record = doc.createElement("bookmark");
		for (j in bookmarkArray[i]) {
			var n = doc.createElement("item");
			n.setAttribute('name',j);
			var text = doc.createTextNode(bookmarkArray[i][j]);
			n.appendChild(text);
			record.appendChild(n);
		}
		root.appendChild(record);
	}
	
	if (cookiesEnabled) {
		var xmlBM = escape(doc.xml);
		var xmllen = xmlBM.length;
		var blocksize = 3500;
		var start = 0;
		var end = blocksize;
		var ok = true;
		
		if (xmlBM.length > blocksize*(maxStorage+1)) {
			alert("Too many bookmarks. The last added bookmarks were not saved.");	
		} else {
			for(var z=0;z<=maxStorage;z++) {
				if (!ok) {
					clearCookie("s",storageBasePath + String(z) + "\\");
				} else {
					var res = "";
					res = xmlBM.substring(start,end);
					start += blocksize;
					end += blocksize;
					setCookiePlain("s",res,maxExpire,storageBasePath + String(z) + "\\");
					//setCookie("usestorage","yes",maxExpire,"/");
					if (start > xmllen) ok = false;
				}
			}
		}
	} else {
		bookmarkPath = getBookmarkPath();
		saveFile(bookmarkPath,doc.xml);
	}
}





function registerBookmarks(obj) {
	bookmarks = obj;
	bookMarkIndex = 0;
	startDragID = -1;
	endDragID = -1;

	loadBookmarks();

	var sel = top.frames.bookmarks_window.document.getElementById("targetselect");
	
	/*
	//var curopt = sel.getElementsByTagName('option');
	alert(sel.length);
	for(var t=sel.length-1;t>0;t--) {
		alert(t);
		//sel.removeChild(curopt[t]);
		sel.options[i] = null;
	}
	*/
	
	var options = new Array();
	var opt_text = new Array();
	var opt = top.frames.bookmarks_window.document.createElement("option");
	opt.value = 0;
	opt.text = "Top level";
	opt.selected = true;

	if (MSIE) sel.add(opt);	
	else sel.appendChild(opt);
	
	opt = top.frames.bookmarks_window.document.createElement("option");
	opt.value = "selected";
	opt.text = "Selected item";

	if (MSIE) sel.add(opt);	
	else sel.appendChild(opt);
	
	for (var i=0;i<bookmarkArray.length;i++) {
		var thisid = addBookmarkEntry(bookmarkArray[i].parentid,bookmarkArray[i].name,bookmarkArray[i].url,bookmarkArray[i].isfolder);
		opt = top.frames.bookmarks_window.document.createElement("option");
		opt.value = thisid;
		
		if (bookmarkArray[i].parentid > 0) {
			var parentChain = new Array();
			parentChain.push(bookmarkArray[i].name);
			var cn = bookmarkArray[i];
			for(var j=0;j<10;j++) {
				if (cn.parentid > 0) {
					cn = bookmarkArray[cn.parentid-1];
					parentChain.unshift(cn.name);
				} else break;
			}
			opt.text = parentChain.join("/");
		} else {
			opt.text = bookmarkArray[i].name;
		}
		opt_text.push(opt.text + "|" + options.length);
		options.push(opt);
	}
	
	opt_text.sort(pathCompare);
	for(var o in opt_text) {
		var dat = opt_text[o].split('|');
		if (MSIE) sel.add(options[dat[1]]);	
		else sel.appendChild(options[dat[1]]);
	}
	
	top.frames.bookmarks_window.document.write(bookmarks);
	bookmarks.openTo(lastBookmark);
}

function pathCompare(a,b) {
	var res = 0;
	var strip = new RegExp("\\/","g");
	var strip2 = new RegExp("\\|.+$");
	var left = a.replace(strip,'').replace(strip2,'');
	var right = b.replace(strip,'').replace(strip2,'');
	if (left.toLowerCase() < right.toLowerCase()) res = -1
	if (left.toLowerCase() > right.toLowerCase()) res =  1

	return res;
}

function reloadBookmarks() {
	top.frames.bookmarks_window.document.location.reload();
}

function bookmarkAction(action,parentid,foldername) {
	if (action) {
		if (action == "folder" && typeof(parentid) != "undefined" && foldername) {
			var id;
			if (parentid == "selected") {
				var bm = bookmarks.getChecked();
				if (bm.length > 0) {
					createBookmarkFolder(bm[0].id,foldername);
					lastBookmark = bookmarkArray.length;
				}
			} else {
				createBookmarkFolder(parentid,foldername);
				lastBookmark = bookmarkArray.length;
			}
		} else if (action == "move") {
			var bm = bookmarks.getChecked();
			if (bm.length > 0) {
				for(i=0;i<bm.length;i++) {
					if (bm[i].id > 0 && parentid != bm[i].id && !isParent(bm[i].id,parentid)) {
						var n = bookmarkArray[bm[i].id-1];
						n.parentid = parentid;
					}
				}
				lastBookmark = parentid;
				saveBookmarks();
				dragdropObj = null;
				reloadBookmarks();
			}
		} else if (action == "delete") {
			
			var bm = bookmarks.getChecked();
			if (bm.length > 0) {
				var i,j;
			
				for(i=0;i<bm.length;i++) {
					if (bm[i].id > 0) {
						bookmarkArray[bm[i].id-1].del = true;
					}	
				}
				
				for (j=0;j<10;j++) {
					for(i=0;i<bookmarkArray.length;i++) {
						if (bookmarkArray[i].parentid > 0) {
							var n = bookmarkArray[bookmarkArray[i].parentid-1];
							if (n.del) bookmarkArray[i].del = true;
						}
					}
				}
			
				var pruned = new Array();
				for(i=0;i<bookmarkArray.length;i++) {
					var n = bookmarkArray[i];
					if (!(n.del)) {
						pruned.push(n);
					}
				}
				
				bookmarkArray = pruned;
				lastBookmark = 0;
				saveBookmarks();
				dragdropObj = null;
				visibleNodes = getVisibleNodes();
				reloadBookmarks();
			}
		} else if (action == "rename") {
			var bm = bookmarks.getChecked();
			if (bm.length > 0) {
				if (bm[0].id > 0) {
					bookmarkArray[bm[0].id-1].name = foldername;
				}
				lastBookmark = bm[0].id;
				saveBookmarks();
				dragdropObj = null;
				reloadBookmarks();
			}
		}
	}
}



function attachEventHandler(obj, evt, fn) {
	if (document.all){
		obj.attachEvent("on" + evt, fn);
	} else {
		obj.addEventListener(evt, fn, false);
	}
}



function actionOnChange() {
	if (top.frames.bookmarks_window.document.bmaction.action.value == "folder") {
		top.frames.bookmarks_window.document.bmaction.parentid.disabled = false;
		top.frames.bookmarks_window.document.bmaction.foldername.disabled = false;
	} else if (top.frames.bookmarks_window.document.bmaction.action.value == "move") {
		top.frames.bookmarks_window.document.bmaction.parentid.disabled = false;
		top.frames.bookmarks_window.document.bmaction.foldername.disabled = true;
	} else if (top.frames.bookmarks_window.document.bmaction.action.value == "rename") {
		top.frames.bookmarks_window.document.bmaction.parentid.disabled = true;
		top.frames.bookmarks_window.document.bmaction.foldername.disabled = false;
	} else if (top.frames.bookmarks_window.document.bmaction.action.value == "delete") {
		top.frames.bookmarks_window.document.bmaction.parentid.disabled = true;
		top.frames.bookmarks_window.document.bmaction.foldername.disabled = true;	
	}
}

function bookmarkSelectAll() {
	bookmarks.selectAll();
}

function bookmarkClearSelection() {
	bookmarks.clearAll();
}

function addBookmarkEntry (parentid,name,url,isfolder) {
	bookMarkIndex++;

	bookmarks.add(bookMarkIndex,parentid,name,url,isfolder);
	if (isfolder) bookmarks.setFolderIcon(bookMarkIndex);
	
	return bookMarkIndex;
}

function createBookmarkFolder(id,foldername) {
	if (foldername && typeof(id) != "undefined") {
		var bm = { parentid:id , name:foldername, isfolder:1 };
		bookmarkArray.push(bm);
		saveBookmarks();
		dragdropObj = null;
		reloadBookmarks();
	}
	
}

function addBookmark(bmname,bmurl) {
	if (bmname && bmurl) {
		var bm = { parentid:0 , name:bmname, url:bmurl};
		lastBookmark = bookmarkArray.length;
		bookmarkArray.push(bm);
		saveBookmarks();
		dragdropObj = null;
		//top.frames.bookmarks_window.document.location.reload();
		lastBookmark = 0;
		reloadBookmarks();
	}	
}

function initDragDrop(obj) {
	if (obj) {
		dragdropObj = obj;
		
		var res = new Array();
		visibleNodes = getVisibleNodes();
		visibleNodesByName = new Array();
		for (var i=0;i<visibleNodes.length;i++) {
			res.push(visibleNodes[i]);
			visibleNodesByName[visibleNodes[i]] = i;
		}
		res.unshift("c:hand");
		dragdropObj.set_dhtml(res);
	} else {
		dragdropObj = null;
	}
}

function getVisibleNodes() {
	var idres = new Array();
	
	var tree = top.frames.bookmarks_window.document.getElementById("bookmark_tree");
	var nodes = tree.getElementsByTagName("img");
	var isimg = new RegExp("^ib\\d+$");
	for (var j=0;j<nodes.length;j++) {
		var id = nodes[j].getAttribute('id');
		if (isimg.test(id)) {
			idres.push(id);	
		}
	}
	
	return idres;
}

function nodeOpen(obj,id,status) {
	if (dragdropObj) {
		var newnodes = new Array();
		visibleNodes = getVisibleNodes();	
		for (var i=0;i<visibleNodes.length;i++) {
			if (!(visibleNodes[i] in visibleNodesByName)) {
				visibleNodesByName[visibleNodes[i]] = i;
				newnodes.push(visibleNodes[i]);
			}
		}
		
		for(var j=0;j<newnodes.length;j++) {
			dragdropObj.add_dhtml(newnodes[j]);
		}
	}
	
	lastBookmark = obj.pid;
}
function startDrag(objname) {
	var id = -1;
	var strip = new RegExp("^ib(\\d+)$");
	if (strip.test(objname)) {
		id = objname.replace(strip,"$1");
	}
	
	if (id > -1) {
		startDragID = id;
		if (MSIE) doDrag();
	} else {
		startDragID = -1;
		endDragID = -1;		
	}
	
	if (MSIE) {
		startDragID = -1;
		endDragID = -1;
	}	
	
	return false;
}

function doDrag() {
	if (startDragID != endDragID && startDragID > -1 && endDragID > -1) {
		if (startDragID > 0) {
			var n = bookmarkArray[startDragID-1];
			dragdropObj = null;
			if (!isParent(startDragID,endDragID)) {
				n.parentid = endDragID;
				lastBookmark = endDragID;
				saveBookmarks();
				//dragdropObj = null;
				reloadBookmarks();
			}
			startDragID = -1;
			endDragID = -1;
			return true;
		} else {
			startDragID = -1;
			endDragID = -1;
		}
	}
	
	return false;
}

function endDrag(e) {
	var obj;
	if (MSIE) obj = e.srcElement;
	else obj = e.target;
	
	if (obj) {
		if (obj.nodeName.toLowerCase() == "img") {
			var id = getImgID(obj);
			
			if (id > -1) {
				endDragID = id;
				if (Netscape) doDrag();
			} else {
				startDragID = -1;
				endDragID = -1;				
			}
		}	
	}

	if (Netscape) {
		startDragID = -1;
		endDragID = -1;
	}				

	return false;
}

function getImgID(obj) {
	var id = -1;
	var strip = new RegExp("^ib(\\d+)$");
	if (strip.test(obj.getAttribute('id'))) {
		id = obj.getAttribute('id').replace(strip,"$1");
	}
	
	return Number(id);
}





// [Cookie] Clears a cookie
function clearCookie(cookieName, path) {
	var now = new Date();
	var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
	if (path) {
		setCookie(cookieName,'done', yesterday,path);
	} else {
		setCookie(cookieName,'done', yesterday);
	}
};

// [Cookie] Sets value in a cookie
function setCookie(cookieName, cookieValue, expires, path, domain, secure) {
	document.cookie =
		escape(cookieName) + '=' + escape(cookieValue)
		+ (expires ? '; expires=' + expires.toGMTString() : '')
		+ (path ? '; path=' + path : '')
		+ (domain ? '; domain=' + domain : '')
		+ (secure ? '; secure' : '');
};

// [Cookie] Sets value in a cookie, no escaping
function setCookiePlain(cookieName, cookieValue, expires, path, domain, secure) {
	document.cookie =
		cookieName + '=' + cookieValue
		+ (expires ? '; expires=' + expires.toGMTString() : '')
		+ (path ? '; path=' + path : '')
		+ (domain ? '; domain=' + domain : '')
		+ (secure ? '; secure' : '');
};

// [Cookie] Gets a value from a cookie
function getCookie(cookieName) {
	var cookieValue = '';
	var posName = document.cookie.indexOf(escape(cookieName) + '=');
	if (posName != -1) {
		var posValue = posName + (escape(cookieName) + '=').length;
		var endPos = document.cookie.indexOf(';', posValue);
		if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
		else cookieValue = unescape(document.cookie.substring(posValue));
	}
	return (cookieValue);
};

// [Cookie] Gets a value from a cookie, no escaping
function getCookiePlain(cookieName) {
	var cookieValue = '';
	var posName = document.cookie.indexOf(cookieName + '=');
	if (posName != -1) {
		var posValue = posName + (cookieName + '=').length;
		var endPos = document.cookie.indexOf(';', posValue);
		if (endPos != -1) cookieValue = document.cookie.substring(posValue, endPos);
		else cookieValue = document.cookie.substring(posValue);
	}
	return (cookieValue);
};

function getCookieData(cookiedata,cookieName) {
	var cookieValue = '';
	var posName = cookiedata.indexOf(escape(cookieName) + '=');
	if (posName != -1) {
		var posValue = posName + (escape(cookieName) + '=').length;
		var endPos = cookiedata.indexOf(';', posValue);
		if (endPos != -1) cookieValue = unescape(cookiedata.substring(posValue, endPos));
		else cookieValue = unescape(cookiedata.substring(posValue));
	}
	return (cookieValue);
};

function getCookieDataPlain(cookiedata,cookieName) {
	var cookieValue = '';
	var posName = cookiedata.indexOf(cookieName + '=');
	if (posName != -1) {
		var posValue = posName + (cookieName + '=').length;
		var endPos = cookiedata.indexOf(';', posValue);
		if (endPos != -1) cookieValue = cookiedata.substring(posValue, endPos);
		else cookieValue = cookiedata.substring(posValue);
	}
	return (cookieValue);
};

function saveTextFile( strFullPath, strContent, bOverwrite ) {
   if ( ( navigator.appName != "Netscape" )
     && ( navigator.appName != "Microsoft Internet Explorer" ) )
   {
     alert( "This method works only in Netscape 4.* "
       + "and Internet Explorer" );
     return;
   }

   if ( ( navigator.appName == "Netscape" )
     && ( parseFloat( navigator.appVersion ) >= 5 ) )
   {
     alert( "This method works only in Netscape 4.* "
       + "and Internet Explorer" );
     return;
   }

   if ( navigator.platform.indexOf( "Win" ) == -1 )
   {
     alert( "This method works only on Windows platforms." );
     return;
   }

   if ( navigator.appName.indexOf( "Netscape" ) == -1 )
   {
     var fso = new ActiveXObject( "Scripting.FileSystemObject" );

     if ( bOverwrite
       || !fso.FileExists( strFullPath )
       || confirm( "The file already exists, overwrite?" ) )
     {
       var flOutput = fso.CreateTextFile( strFullPath, true );
       flOutput.Write( strContent );
       flOutput.Close();
       return true;
     }
     else
     {
       return false;
     }
   }
   else
   {
     netscape.security.PrivilegeManager.enablePrivilege(
       "UniversalFileRead" );

     var flCheck = new java.io.File( strFullPath );

     if ( bOverwrite
       || !flCheck.exists()
       || confirm( CExplorer.ALERT002 ) )
     {
       netscape.security.PrivilegeManager.enablePrivilege(
         "UniversalFileWrite" );
       var fsOutput = new java.io.FileOutputStream( strFullPath );
       var flOutput = new java.io.DataOutputStream( fsOutput );

       flOutput.writeBytes( strContent );

       flOutput.flush();
       fsOutput.close();
       return true;
     }
     else
     {
       return false;
     }
   }
}


function xulFileWrite(filePath, content) {
	if (window.netscape) {
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			file.initWithPath(filePath);
			if (!file.exists()) {
				//alert('Creating new file ' + filePath);
				file.create(0x00, 0644);
			}
			var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
			outputStream.init(file, 0x20 | 0x04, 00004, null);
			outputStream.write(content, content.length);
			outputStream.flush();
			outputStream.close();
			return true;
		}
		catch (e) {
			alert(e);
			return false;
		}
	} else {
		return false;	
	}
}

//<script>
//////////////////
// Helper Stuff //
//////////////////

// used to find the Automation server name
function getDomDocumentPrefix() {
	if (getDomDocumentPrefix.prefix)
		return getDomDocumentPrefix.prefix;
	
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".DomDocument");
			return getDomDocumentPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	
	throw new Error("Could not find an installed XML parser");
}

function getXmlHttpPrefix() {
	if (getXmlHttpPrefix.prefix)
		return getXmlHttpPrefix.prefix;
	
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			return getXmlHttpPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	
	throw new Error("Could not find an installed XML parser");
}

//////////////////////////
// Start the Real stuff //
//////////////////////////


// XmlHttp factory
function XmlHttp() {}

XmlHttp.create = function () {
	try {
		if (window.XMLHttpRequest) {
			var req = new XMLHttpRequest();
			
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (req.readyState == null) {
				req.readyState = 1;
				req.addEventListener("load", function () {
					req.readyState = 4;
					if (typeof req.onreadystatechange == "function")
						req.onreadystatechange();
				}, false);
			}
			
			return req;
		}
		if (window.ActiveXObject) {
			return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
		}
	}
	catch (ex) {}
	// fell through
	throw new Error("Your browser does not support XmlHttp objects");
};

// XmlDocument factory
function XmlDocument() {}

XmlDocument.create = function () {
	try {
		// DOM2
		if (document.implementation && document.implementation.createDocument) {
			var doc = document.implementation.createDocument("", "", null);
			
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (doc.readyState == null) {
				doc.readyState = 1;
				doc.addEventListener("load", function () {
					doc.readyState = 4;
					if (typeof doc.onreadystatechange == "function")
						doc.onreadystatechange();
				}, false);
			}
			
			return doc;
		}
		if (window.ActiveXObject)
			return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
	}
	catch (ex) {}
	throw new Error("Your browser does not support XmlDocument objects");
};

// Create the loadXML method and xml getter for Mozilla
if (window.DOMParser &&
	window.XMLSerializer &&
	window.Node && Node.prototype && Node.prototype.__defineGetter__) {

	// XMLDocument did not extend the Document interface in some versions
	// of Mozilla. Extend both!
	//XMLDocument.prototype.loadXML = 
	Document.prototype.loadXML = function (s) {
		
		// parse the string to a new doc	
		var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
		
		// remove all initial children
		while (this.hasChildNodes())
			this.removeChild(this.lastChild);
			
		// insert and import nodes
		for (var i = 0; i < doc2.childNodes.length; i++) {
			this.appendChild(this.importNode(doc2.childNodes[i], true));
		}
	};
	
	
	/*
	 * xml getter
	 *
	 * This serializes the DOM tree to an XML String
	 *
	 * Usage: var sXml = oNode.xml
	 *
	 */
	// XMLDocument did not extend the Document interface in some versions
	// of Mozilla. Extend both!
	/*
	XMLDocument.prototype.__defineGetter__("xml", function () {
		return (new XMLSerializer()).serializeToString(this);
	});
	*/
	Document.prototype.__defineGetter__("xml", function () {
		return (new XMLSerializer()).serializeToString(this);
	});
}