// This file temporarily contains all of "qbw.js" to aid in the transition. It's at the bottom and will be coming out shortly.


/****************************************************************\
	All code copyright (c) 2003 Intuit Canada Ltd.
	Any unauthorized duplication or reuse of this code
	is a violation of applicable laws.
	Coded by Peter Harris, June 2003.
   ============================================================
		JavaScript Toolkit for HTML Help
   ------------------------------------------------------------
   This toolkit contains routines for the following features:
	== Environment detection scripts.
		- getTopicFilename()
		- getTopicPath()
		- getTopicCHM()
		- getTopicExternalPath()
		- getTopicSKUs()
		- getQuickBooksSKU()
	== Conditional text & variables.
		- conditionalText()
		- setHTMLvariable( obj )
		- fetchAttributeValue( obj, attName )
		- validateSKUs( str )
		- flattenSKUs( source )
		- addUnique( tArray, tElement )
		- string_caps( str, delim )
		- string_trim( str )
		- convertNumberToText( str )
		- convertThousandsToText( num )
		- convertDecadesToText( num )
		- convertNumberToOrdinal( str )
	== Expando text.
		- makeExpandoLink( linkObj, divID )
		- makeMultiExpandoLink( linkObj, divID )
		- makeExpando_DivPrep( divObj, startOpen )
		- expandoText()
		- multiExpandoText()
		- expandoMouseOver()
		- expandoMouseOut()
		- findExpandoDiv( anchorObj, divID )
		- resizeExpandoFrame( frameName )
		- expandoText_nestedFrames( divObj )
	== Popup windows.
		- MarkPopup()
		- Popup( targetURL )
		- FixURL( targetURL )
		- MakePopup( targetURL )
		- CreatePopup( targetURL )
		- FinishPopup( idx )
		- MovePopup( idx )
		- ResizePopup( idx )
		- qsortShrinkPopup( popupObj, constrainX, constrainY )
		- fixPopupTopicLinks( targetContainer )
		- ClosePopups()
		- ParentClosePopups()
	== User Feedback interface.
		- makeFeedbackAndHelpSupportLink( divObj )
		- feedback_yesno()
		- feedback_submit()
	== Miscellaneous.
		- qbcommand( param )
		- run_qbcommand( param )
		- qbcommand_redirect( param )
		- openURL( param )
		- QBURL( param )
		- displaytopic( param )
	== Internal Help for HTML extensions.
		- displaySKU()
		- displayAllSKUSs()
		- displayAllMods()
		- displayHelp()

   ------------------------------------------------------------
   _____________________ Version History ______________________
	Version 2.10 - August 28, 2003
	 - Create a multi-capacitant environment where the script can link to files whether from Perforce, from CHM, or from /updates.
	Version 2.07 - July 17, 2003
	 - Reformat all links to explicitly include the CHM file, if there is one. Fixes broken expando and popup links.
	Version 2.06 - July 10, 2003
	 - Hide <H?> title and <H4>Related Topics</H4> when in an expando window.
	Version 2.05 - July 9, 2003
	 - Made SKU.js an override to ActiveX detection; added <detectsku> tag for showing detected info.
	Version 2.04 - June 12, 2003
	 - Added automatic lightning bolt to irefs linking to "http://"
	Version 2.03 - June 10, 2003
	 - Added multisectional, radio button based expando tag <a multiexpando="basename">.
	Version 2.02 - June 9, 2003
	 - Extended Strata (and Flavours) handling:
		- All codes now in arrays QUICKBOOKS_ALLSTRATA, QUICKBOOKS_STRATAWITHFLAVOUR and QUICKBOOKS_ALLFLAVOURS
		- Added (+) operator; i.e. PRO+ = PRO, PREMIER, ENTERPRISE
		- Added (-) operator; i.e. PRO- = LITE, BASIC, PRO
		- Added (:) operator; i.e. PREMIER: = PREMIER but only with no Flavour
		- Added NOT() operator; i.e. skus="NOT(ENTERPRISE,CONTRACTOR)" = anything that isn't QBES or CONTRACTOR
	 - Added automatic tooltips for expando sections. Requires <html xmlns:qb> header tag.
	Version 2.01 - June 3, 2003
	 - Added new Flavors: PROFESSIONAL, WHOLESALE, RETAIL.
	 - Added text mods "2TEXT" and "ORDINAL" for working with numbers.
	 - Added rollovers for expando graphic.
	 - Added support for multiple expando graphics (use attribute icon="", e.g. <a expando icon="green">).
	Version 2.0 - June 2003
	 - Taking what we learned in v.1, this is a complete
	   rewrite, with lots of new and wonderful stuff.
	   For information about previous versions, check
	   qbw.js from Gecko/Godzilla.

\****************************************************************/
// The following variable contains the hardcoded date of the build
// of the CHM. The reason for this that the ".lastModified" property
// doesn't work inside HTMLHelp and we need to submit this for VOC data
// from inside HTML Help (embedded browser) for the 'yes'/'no' feedback.
// We should find an automated workaround for this manual fix, to avoid
// constant updating of this value. -MTK 2-20-2003
CHM_DATE	= "3,17,2004";
// ------------------------------------------------------------ \\
// ----- DEFINE ALL TEXT RESOURCES HERE (FOR TRANSLATION) ----- \\
TEXT = new Array();
TEXT["printericontext"] =		"Print Topic";
TEXT["tooltip_expando"] =		"Expand/Collapse Text";
TEXT["tooltip_multiexpando"] =		"Display details";



// Code added by Peter Harris 10/4/2006
//----- Define "apex" to be the topmost frame that doesn't throw a zone error -----\\
//----- Use it to replace "top" everywhere (specifically, Expando global tracking -----\\
var apex = window.self;
var tempObj = window.self;
while (tempObj) {
	apex = tempObj;
	tempObj = tempObj.parent;
	try {
		var tmp = tempObj.name;
	}
	catch (e) {
		tempObj = null;
	}
	if (apex == tempObj) {		// You've reached "top." without a zone crash. Stop looping.
		tempObj = null;
	}
}

// ============================================================ \\
// =====           GLOBAL ENVIRONMENT VARIABLES           ===== \\
// ============================================================ \\
// --  Any variable that is available for all functions, or  -- \\
// --  any function that's executed automatically when this  -- \\
// --  file is loaded, should be put here in this section.   -- \\

QUICKBOOKS_ALLFLAVOURS		= new Array("ACCOUNTANT", "CONTRACTOR", "NONPROFIT", "HEALTHCARE", "PROFESSIONAL", "WHOLESALE", "RETAIL");
QUICKBOOKS_ALLSTRATA		= new Array("LITE", "BASIC", "PRO", "PREMIER", "ENTERPRISE");
QUICKBOOKS_STRATAWITHFLAVOUR	= new Array("", "", "", "PREMIER", "ENTERPRISE");

TOPIC_FILENAME		= getTopicFilename();		// --  topicname.html 
TOPIC_PATH		= getTopicPath();		// --  topicpath/
TOPIC_CHM		= getTopicCHM();		// --  helpfile.chm::/
TOPIC_EXTPATH		= getTopicExternalPath();	// --  C:/Program Files/QuickBooks/
TOPIC_SKUS		= new getTopicSKUs();

// ------------------------------------------------------------ \\
// ---  DEFINE THE FILE-LINK PREFIXES FOR THIS ENVIRONMENT  --- \\

IS_POPUP_FRAME		= ( window.name.indexOf("popup__") > -1 );
IS_EXPANDO_FRAME	= ( window.name.indexOf("_expando_") > -1 );

if ( TOPIC_CHM ) {
	// ----- We are inside a CHM ----- \\
	ENVIRONMENT = "CHM";

	PATH_PREFIX_STYLESHEET = "/";
	PATH_PREFIX_IMAGES = "/";
	PATH_PREFIX_BEHAVIORS = "/";
	PATH_PREFIX_VARIABLES = "file:///" + TOPIC_EXTPATH;
	PATH_PREFIX_HELPDEBUG = "file:///" + TOPIC_EXTPATH;

} else if (	( !IS_POPUP_FRAME && (apex.Hidden) && (apex.Hidden.TOPIC_REVERSEPATH) ) ||
		( IS_POPUP_FRAME && (apex.HiddenPopup) && (apex.HiddenPopup.TOPIC_REVERSEPATH) )
	) {
	// ----- We are an update file ----- \\
	ENVIRONMENT = "UPDATE";

	if (IS_POPUP_FRAME) {
		var tReversePath = apex.HiddenPopup.TOPIC_REVERSEPATH;
	} else {
		var tReversePath = apex.Hidden.TOPIC_REVERSEPATH;
	}

	PATH_PREFIX_STYLESHEET = "ms-its:" + TOPIC_EXTPATH + "core.chm::/";
	PATH_PREFIX_IMAGES = "ms-its:" + TOPIC_EXTPATH + "core.chm::/";
	PATH_PREFIX_BEHAVIORS = "ms-its:" + TOPIC_EXTPATH + "core.chm::/";
	PATH_PREFIX_VARIABLES = tReversePath;
	PATH_PREFIX_HELPDEBUG = tReversePath;

} else {
	// ----- We are in development environment ----- \\
	ENVIRONMENT = "DEVELOPMENT";

	PATH_PREFIX_STYLESHEET = "../../_HeaderFiles/StyleSheet/";
	PATH_PREFIX_IMAGES = "../../_HeaderFiles/Images/";
	PATH_PREFIX_BEHAVIORS = "../../_HeaderFiles/JavaScript/";
	PATH_PREFIX_VARIABLES = "../../_HeaderFiles/JavaScript/";
	PATH_PREFIX_HELPDEBUG = "../../_HeaderFiles/Tools/";
}
// ------------------------------------------------------------ \\

QUICKBOOKS_VERSION	= new getQuickBooksSKU();

// -----  Define the array for variables, and then link   ----- \\
// -----  in the external file for the actual data.       ----- \\
QB_VARS = new Array();
document.writeln("<script language=\"JavaScript\" src=\"" + PATH_PREFIX_VARIABLES + "variables.js\"></script>");

// -----  Set up a link to "helpDebug.js" external file   ----- \\
document.writeln("<script language=\"JavaScript\" src=\"" + PATH_PREFIX_HELPDEBUG + "helpDebug.js\"></script>");

// ---  Define all graphics' paths (or image objects.src)   --- \\

EXPANDO_GRAPHIC = new Array();
EXPANDO_GRAPHIC["default"] = "green";
EXPANDO_GRAPHIC[0] = new Array();
  EXPANDO_GRAPHIC[0]["name"] = "green";
 EXPANDO_GRAPHIC[0]["open"] = new Image();	EXPANDO_GRAPHIC[0]["open"].src = PATH_PREFIX_IMAGES + "button_expand_green_open_lo.gif";
 EXPANDO_GRAPHIC[0]["close"] = new Image();	EXPANDO_GRAPHIC[0]["close"].src = PATH_PREFIX_IMAGES + "button_expand_green_close_lo.gif";
 EXPANDO_GRAPHIC[0]["openover"] = new Image();	EXPANDO_GRAPHIC[0]["openover"].src = PATH_PREFIX_IMAGES + "button_expand_green_open_hi.gif";
 EXPANDO_GRAPHIC[0]["closeover"] = new Image();	EXPANDO_GRAPHIC[0]["closeover"].src = PATH_PREFIX_IMAGES + "button_expand_green_close_hi.gif";
/*
 EXPANDO_GRAPHIC[1] = new Array();
 EXPANDO_GRAPHIC[1]["name"] = "white";
 EXPANDO_GRAPHIC[1]["open"] = new Image();	EXPANDO_GRAPHIC[1]["open"].filename = PATH_PREFIX_IMAGES + "button_expand_white_open_lo.gif";
 EXPANDO_GRAPHIC[1]["close"] = new Image();	EXPANDO_GRAPHIC[1]["close"].filename = PATH_PREFIX_IMAGES + "button_expand_white_close_lo.gif";
 EXPANDO_GRAPHIC[1]["openover"] = new Image();	EXPANDO_GRAPHIC[1]["openover"].filename = PATH_PREFIX_IMAGES + "button_expand_white_open_hi.gif";
 EXPANDO_GRAPHIC[1]["closeover"] = new Image();	EXPANDO_GRAPHIC[1]["closeover"].filename = PATH_PREFIX_IMAGES + "button_expand_white_close_hi.gif";
*/

ICON_PRINTER		= PATH_PREFIX_IMAGES + "icon_printer.gif";
ICON_FEEDBACK		= PATH_PREFIX_IMAGES + "icon_feedback_email.gif";
ICON_LIGHTNING		= PATH_PREFIX_IMAGES + "icon_lightningbolt.gif";
ICON_PDF			= PATH_PREFIX_IMAGES + "icon_pdf.gif";
ICON_HELP_FEEDBACK	= PATH_PREFIX_IMAGES + "icon_help_feedback.gif";
ICON_HELP_SUPPORT	= PATH_PREFIX_IMAGES + "icon_help_support.gif";


// ------------------------------------------------------------ \\
// ---      DISABLE THE "RIGHT-CLICK" MENU IN THE HELP      --- \\
document.onmousedown = rightclick;
// this only works because it provides an alternate window (the alert box) for the mouseup to trigger in.
// it would be better to intercept and stop the onmouseup event instead, but I can't do it yet.
function rightclick(e) {
  if (event.button == 2) {
//	alert("Right-click disabled");
//	event.returnValue = false;
//	event.cancelBubble = true;
	return false;
  }
}

// ------------------------------------------------------------ \\
// ---  INCLUDE STYLE SHEET BEHAVIORS WITH RELATIVE PATHS   --- \\
var txt = "";
txt += "<style>\n";
txt += "qb\\:tooltip { behavior: url(" + PATH_PREFIX_BEHAVIORS + "tooltip.htc); }\n";
txt += ".stripes { behavior: url(" + PATH_PREFIX_BEHAVIORS + "stripes.htc); margin-bottom: 0em; margin-top: 1em; }\n";
txt += "</style>";
document.writeln(txt);

// ------------------------------------------------------------ \\
// ----- DEFINE ALL TEXT RESOURCES HERE (FOR TRANSLATION) ----- \\
TEXT = new Array();
TEXT["feedback_ratetopic"] =		"Tell us how we can improve QuickBooks.";
TEXT["helpsupport_linktext"] =		"Do you need more information? Try the Support Center.";
TEXT["printericontext"] =		"Print Topic";
TEXT["tooltip_expando"] =		"Expand/Collapse Text";
TEXT["tooltip_multiexpando"] =		"Display details";

// ------------------------------------------------------------ \\
// -----   DISPLAY PRINTER ICON AND ADD ACTIVEX CONTROL   ----- \\
var txt = "";
txt += "<object classid=clsid:596801D8-2C9D-4627-9C67-195CB81B655A id=xobj></object>";
txt += "<object classid=clsid:c1908682-7b2c-4ab0-b98e-183649a0bf84 id=aw></object>";
if ( !IS_EXPANDO_FRAME ) {
	txt += "<a href=\"javascript:print()\"><img src=\"" + ICON_PRINTER + "\" name=\"printicon\" align=\"right\" width=\"18\" height=\"18\" border=\"0\" alt=\"" + TEXT["printericontext"] + "\"></a>";
}
document.writeln(txt);

// ------------------------------------------------------------ \\
// -----   DATA FETCHING ROUTINES FOR GLOBAL VARIABLES    ----- \\

function getTopicFilename() {
	var loci = document.location.toString().match(/[^\/\\]*\.html/);
	return loci;
}

function getTopicPath() {
	var loci = document.location.toString();
	if (getTopicCHM()) {
		// ----- there is a CHM ----- \\
		var Y = loci.lastIndexOf("/");
		var t = loci.substring(0,Y);
		var Y2 = loci.indexOf("::/");
		var t = loci.substring(Y2+3,Y+1);
	} else {
		// ----- there is no CHM ----- \\
		if (window.TOPIC_UPDATEPATH && window.QUICKPATCH_codeVersion) {
			// ----- we're a patched topic ----- \\
			var Y = loci.indexOf(TOPIC_UPDATEPATH) + TOPIC_UPDATEPATH.length;
			var t = loci.substring(Y,loci.length);
			var Y2 = t.lastIndexOf("/");
			var t = t.substring(0,Y2+1);
		} else {
			// ----- development enviroment, or unknown ----- \\
			// ----- just assume one dir up ----- \\
			var Y = loci.lastIndexOf("/");
			var t = loci.substring(0,Y);
			var Y2 = t.lastIndexOf("/");
			var t = loci.substring(Y2+1,Y+1);
		}
	}
	return t;
}

function getTopicCHM() {
	var loci = document.location.toString().match(/[^\/\\]*\.chm\:\:\//i);
	if (loci) {
		return loci;
	} else {
		return "";
	}
}

function getTopicExternalPath() {
	if (window.TOPIC_EXTPATH && window.QUICKPATCH_codeVersion) {
		// ----- "_updated.js" has already calculated TOPIC_EXTPATH; just use it ----- \\
		var tPath = window.TOPIC_EXTPATH;
	} else {
		// ----- figure out path on our own ----- \\
		var tPath = "";
		var loci = document.location.toString().replace(/\\/g, "/");
		switch ( loci.search(":") ) {
			case 2:		// mk:@MSITStore:
				var X = 14;
				break;
			case 6:		// ms-its:
				var X = 7;
				break;
			case 4:		// file:///
				var X = 8;
				break;
		}

		if (X==8) {	// "file:///"
			// ----- C:/Development/QuickBooks/Help/ (Y2) internalpath/ (Y3) topicfile.html (Y4) #bookmarkdata
			var Y4 = loci.indexOf("#");		Y4 = (Y4 < 0) ? loci.length : Y4;
			tPath = loci.substring(X,Y4);
			var Y3 = tPath.lastIndexOf("/")+1;
			tPath = tPath.substring(0,Y3);
			var Y2 = tPath.lastIndexOf("/",tPath.length-2)+1;
			tPath = tPath.substring(0,Y2);
		} else {
			// ----- do the calc ----- \\
			// ----- C:/ProgramFiles/IntuitProgram/ (Y1) help.chm::/ (Y2) internalpath/ (Y3) topicfile.html (Y4) #bookmarkdata
			var Y2 = loci.indexOf("::/");
			tPath = loci.substring(X,Y2);
			var Y1 = tPath.lastIndexOf("/")+1;
			tPath = tPath.substring(0,Y1);
		}
	}
	return tPath;
}

function getTopicSKUs() {
	var tSKU = "";
	if (window.XML) {
		// ----- check XML from topic header ----- \\
		for (var i=0; i < XML.childNodes.length; i++) {
			if (XML.childNodes(i).tagName.toUpperCase() == "SKU")  {
				tSKU = XML.childNodes(i).text;
				i = XML.childNodes.length;
			}
		}
	}

	return new flattenSKUs( tSKU );
}

function getQuickBooksSKU() {
	var tStratum = "";
	var tFlavour = "";
	// ----- Omitted; for use in U.K. ----- \\
	// var tBrand = "";

	var tError = "";

	// ----- For a current list of SKUs that the product reports,   ----- \\
	// ----- check the file FlavorInstaller_common.h. Currently in  ----- \\
	// ----- QB2004Dev/installsource/ishield6/core/script files/    ----- \\

	try {
		var objLocator = new ActiveXObject("QuickBooks.CoLocator");
		var objProfile = objLocator.Create("QBPrefs.AppParameters"); 

		var flavor = objProfile.Flavor;  // a string value; eg. "accountant"

		if (flavor == "lite") {
			tStratum = "LITE";
			tFlavour = "";
		} else if (flavor == "pro") {
			tStratum = "PRO";
			tFlavour = "";
		} else if (flavor == "superpro") {
			tStratum = "PREMIER";
			tFlavour = "";
		} else if (flavor == "accountant") {
			tStratum = "PREMIER";
			tFlavour = "ACCOUNTANT";
		} else if (flavor == "contractor") {
			tStratum = "PREMIER";
			tFlavour = "CONTRACTOR";
		} else if (flavor == "nonprofit") {
			tStratum = "PREMIER";
			tFlavour = "NONPROFIT";
		} else if (flavor == "healthcare") {
			tStratum = "PREMIER";
			tFlavour = "HEALTHCARE";
		} else if (flavor == "professional") {
			tStratum = "PREMIER";
			tFlavour = "PROFESSIONAL";
		} else if (flavor == "wholesale") {
			tStratum = "PREMIER";
			tFlavour = "WHOLESALE";
		} else if (flavor == "retail") {
			tStratum = "PREMIER";
			tFlavour = "RETAIL";
		} else if (flavor == "bel") {
			tStratum = "ENTERPRISE";
			tFlavour = "";
		} else if (flavor == "belacct") {
			tStratum = "ENTERPRISE";
			tFlavour = "ACCOUNTANT";
		} else if (flavor == "belcontractor") {
			tStratum = "ENTERPRISE";
			tFlavour = "CONTRACTOR";
		} else if (flavor == "belnonprofit") {
			tStratum = "ENTERPRISE";
			tFlavour = "NONPROFIT";
		} else if (flavor == "belhealthcare") {
			tStratum = "ENTERPRISE";
			tFlavour = "HEALTHCARE";
		} else if (flavor == "belprofessional") {
			tStratum = "ENTERPRISE";
			tFlavour = "PROFESSIONAL";
		} else if (flavor == "belwholesale") {
			tStratum = "ENTERPRISE";
			tFlavour = "WHOLESALE";
		} else if (flavor == "belretail") {
			tStratum = "ENTERPRISE";
			tFlavour = "RETAIL";
		} else {
			tStratum = "BASIC";
			tFlavour = "";
			tError = "Unrecognized QuickBooks.CoLocator response";
		}
	}
	catch (e) {
		tError = "Couldn't find QuickBooks.ActiveXObject";

		tStratum = "BASIC";
		tFlavour = "";
	}

	if (TOPIC_EXTPATH) {
		// ----- if there's an external path, try linking in the SKU.js override file ----- \\
		document.writeln("<script language=\"JavaScript\" src=\"" + PATH_PREFIX_VARIABLES + "SKU.js\"></script>");

		// ----- Format of SKU.js file: it must contain the following lines: ----- \\
		// -----   window.QUICKBOOKS_VERSION.Stratum = "PRO";                ----- \\
		// -----   window.QUICKBOOKS_VERSION.Flavour = "";                   ----- \\
		// -----   window.QUICKBOOKS_VERSION.Error = "Loaded from SKU.js";   ----- \\
	}

	this.Stratum = tStratum.toUpperCase();
	this.Flavour = tFlavour.toUpperCase();
	this.Error = tError;
}

// ------------------------------------------------------------ \\
// ============================================================ \\
// =====           CONDITIONAL & VARIABLE TEXT            ===== \\
// ============================================================ \\

function conditionalText() {
	// ----- first off, let's find the _expando_ parent frame ----- \\
	// ----- might not be _top, but first above "_expando_"s  ----- \\
	var iTargetObj = self;
	while ( iTargetObj.name.indexOf("_expando_") >= 0 ) {
		iTargetObj = iTargetObj.parent;
	}
	var iTarget = iTargetObj.name;
	if (iTargetObj == top || iTarget == "") {
		iTarget = "_top";
	}
	if (iTargetObj == self) {
		iTarget = "";
	}

	// -----  This function scans through every HTML DOM node in the file.   ----- \\
	// -----  NB: HTML attributes are case-sensitive! 'Name' is not 'name'.  ----- \\

	var at_body = "";
	var at_relatedtopics = "";

	for (var i=0; i<document.all.length; i++) {
		nodeObj = document.all(i);
		tNode = nodeObj.nodeName.toUpperCase();

		if (tNode.substring(0,1) != "#") {
			// ----- Only check if not XML object ----- \\
			tSKUs = "";
			if ( nodeObj.attributes["skus"] ) { tSKUs = nodeObj.attributes["skus"].value; }
			if ( nodeObj.attributes["Skus"] ) { tSKUs = nodeObj.attributes["Skus"].value; }
			if ( nodeObj.attributes["SKUS"] ) { tSKUs = nodeObj.attributes["SKUS"].value; }
			if (tSKUs) {
				// ----- make this item conditional ----- \\
				if ( validateSKUs(tSKUs) ) {
					nodeObj.style.display = (tNode=="SPAN" || tNode=="A") ? "inline" : "block";
				} else {
					nodeObj.style.display = "none";
				}
			}
		}

		if ( tNode == "VAR" ) {
			// ----- evaluate variable ----- \\
			setHTMLvariable( nodeObj );
		}

		if ( tNode == "A" ) {
			linkObj = nodeObj;

			if (iTarget) {
				if ( !(linkObj.target) ) {
					linkObj.target = iTarget;
				}
			}

			// ----- scan links; implement "iref"s ("Intelligent" or "Intuit" References) ----- \\
			// ----- if the target of the link is appropriate for this SKU, turn it on.   ----- \\
			var tIref = "";
			if ( linkObj.attributes["iref"] ) { tIref = linkObj.attributes["iref"].value; }
			if ( linkObj.attributes["iRef"] ) { tIref = linkObj.attributes["iRef"].value; }
			if ( linkObj.attributes["Iref"] ) { tIref = linkObj.attributes["Iref"].value; }
			if ( linkObj.attributes["IREF"] ) { tIref = linkObj.attributes["IREF"].value; }
			if (tIref) {
				var tTargetSKUs = fetchAttributeValue( linkObj, "targetSKUs" );
				if ( !tTargetSKUs ||
				     ( tTargetSKUs && validateSKUs(tTargetSKUs) )
				   ) {
					linkObj.href = tIref;
				}
			}

			// ----- popups are irefs too, just ones that call a popup window. ----- \\
			// ----- much the same code as above.                              ----- \\
			var tPop = "";
			if ( linkObj.attributes["popup"] ) { tPop = linkObj.attributes["popup"].value; }
			if ( linkObj.attributes["Popup"] ) { tPop = linkObj.attributes["Popup"].value; }
			if ( linkObj.attributes["POPUP"] ) { tPop = linkObj.attributes["POPUP"].value; }
			if (tPop) {
				var tTargetSKUs = fetchAttributeValue( linkObj, "targetSKUs" );
				if ( !tTargetSKUs ||
				     ( tTargetSKUs && validateSKUs(tTargetSKUs) )
				   ) {
					linkObj.href = tPop;
					// ----- set up an "onclick" call to get the mouse X+Y ----- \\
					// ----- also, reformat the link to use dotted line.   ----- \\
					linkObj.onclick = MarkPopup;
					linkObj.style.textDecoration = "none";
					// ----- linkObj.style.borderBottom = "1px dotted"; ----- \\
				}
			}

			// ----- it's linking to the outside world; add bolt ----- \\
			if ( linkObj.href.search( /^http:\/\//i ) >= 0 ) {
				linkObj.outerHTML = "<img src=\"" + ICON_LIGHTNING + "\" width=8 height=12>" + linkObj.outerHTML;
				// ----- we've added a new tag, so increment i to skip over the link ----- \\
				i++;
			} else {
				// ----- this is an internal link.                      ----- \\
				// ----- make the link include the CHM name explicitly  ----- \\
				// ----- this fixes broken links in expandos and popups ----- \\
				if ( TOPIC_CHM && linkObj.href
				      && ( linkObj.href.substr(0,11).toLowerCase() != "javascript:" )
				      && ( linkObj.href.indexOf("::") < 0 )
				   ) {
					linkObj.href = TOPIC_CHM + TOPIC_PATH  + linkObj.href;

				}
			}

			// ----- encase popup URL in popup calling code ----- \\
			if (tPop) {
				linkObj.href = "javascript:Popup('" + linkObj.href + "')";
			}

			// ----- implement expando text links here ----- \\
			var tDivID = "";
			if ( linkObj.attributes["expando"] ) { tDivID = linkObj.attributes["expando"].value; }
			if ( linkObj.attributes["Expando"] ) { tDivID = linkObj.attributes["Expando"].value; }
			if ( linkObj.attributes["EXPANDO"] ) { tDivID = linkObj.attributes["EXPANDO"].value; }
			if ( linkObj.attributes["expando"] || linkObj.attributes["Expando"] || linkObj.attributes["EXPANDO"] ) {
				makeExpandoLink( linkObj, tDivID );
			}

			// ----- implement radio button expando text links here ----- \\
			var tDivID = "";
			if ( linkObj.attributes["multiexpando"] ) { tDivID = linkObj.attributes["multiexpando"].value; }
			if ( linkObj.attributes["MULTIEXPANDO"] ) { tDivID = linkObj.attributes["MULTIEXPANDO"].value; }
			if ( tDivID ) {
				makeMultiExpandoLink( linkObj, tDivID );
			}

		}

		if (nodeObj.id.toLowerCase() == "help_feedback_link") {
			// ----- Add the help feedback link to the bottom of the topic ----- \\
			if ( !IS_EXPANDO_FRAME ) {
				makeFeedbackAndHelpSupportLink( nodeObj );
			}
		}

		// -----  Hide certain segments in the case of expando frames  ----- \\
		if (IS_EXPANDO_FRAME) {
			// ----- hide the first content tag after the body if it's an <H#> tag. ----- \\
			if ( at_body == "AT" && nodeObj.innerHTML ) {
				at_body = "PAST";
				if (tNode.substring(0,1) == "H") {
					nodeObj.style.display = "none";
				}
			}

			if ( !at_body && tNode == "BODY" ) {
				at_body = "AT";
			}

			// ----- hide any <h4>Related Topics</h4> blocks along with the following list ----- \\
			if ( !at_relatedtopics && tNode == "H4" ) {
				at_relatedtopics = "AT";
			}

			if ( at_relatedtopics == "AT" ) {
				if ( tNode == "H4" ) {
					nodeObj.style.display = "none";
				}
				if ( tNode == "OL" || tNode == "UL" ) {
					nodeObj.style.display = "none";
				}
				if ( tNode != "H4" && tNode != "OL" && tNode != "UL" ) {
					at_relatedtopics = "";
				}
			}
		}



		// ------------------------------------------------------------ \\
		// ---  Include self-reporting tags for helping developers  --- \\

		if (tNode == "DETECTSKU") {
			nodeObj.outerHTML = displaySKU();
		}

		if (tNode == "LISTALLSKUS") {
			nodeObj.outerHTML = displayAllSKUs();
		}

		if (tNode == "LISTALLMODS") {
			nodeObj.outerHTML = displayAllMods();
		}

		if (tNode == "HELP") {
			nodeObj.outerHTML = displayHelp();
		}
	}
	
}

function setHTMLvariable ( obj ) {
	// -----  NB: HTML attributes are case-sensitive! 'Name' is not 'name'.  ----- \\

	var tOriginal = obj.innerHTML;
	var tOutput = tOriginal;
	var tOut = "";

	var tName = ""
	if ( obj.attributes["name"] ) { tName = obj.attributes["name"].value; }
	if ( obj.attributes["Name"] ) { tName = obj.attributes["Name"].value; }
	if ( obj.attributes["NAME"] ) { tName = obj.attributes["NAME"].value; }
	if (tName) {
		// ----- search for variable; does it exist? ----- \\
		tOut = QB_VARS[tName.toLowerCase()];
		if ( tOut ) {
			tOutput = tOut["word"];
		} else {
			if (window.HELP_DEBUG) {
				tOutput  = "<font color=\"red\">(" + tOriginal + ") ";
				tOutput += "<span style=\"font-family:Arial;font-size:9pt\">";
				tOutput += "<i>Error!:</i> " + tName + " <i>not found</i></span></font>";
			} else {
				// ----- leaving this "else" clause in for potential action ----- \\
				tOutput  = tOriginal;
			}
		}
	} else {
		// ----- you can apply mods to non-variables if you want ----- \\
		tOut = "OK";
		tOutput = string_trim(tOutput);
	}

	var tMods = "";
	if ( obj.attributes["mods"] ) { tMods = obj.attributes["mods"].value; }
	if ( obj.attributes["Mods"] ) { tMods = obj.attributes["Mods"].value; }
	if ( obj.attributes["MODS"] ) { tMods = obj.attributes["MODS"].value; }
	if (tOut && tMods) {
		var tMarks = tMods.split(",");
		var tAnAdd = "";
		for (var j=0; j < tMarks.length; j++) {
			switch ( string_trim(tMarks[j].toUpperCase()) ) {
			  case "A/N":
				if (tMarks[j] == "a/n") {
					tAnAdd = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "a" : "an";
				}
				if (tMarks[j] == "A/n") {
					tAnAdd = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "A" : "An";
				}
				if (tMarks[j] == "A/N") {
					tAnAdd = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "A" : "AN";
				}
			  break;
			  case "AN":
				tOutput = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "a "+tOutput : "an "+tOutput;
			  break;
			  case "CAPALL":
				tOutput = string_caps(tOutput," ");
			  break;
			  case "CAPFIRST":
				tOutput = tOutput.substring(0,1).toUpperCase() + tOutput.substring(1,tOutput.length);
			  break;
			  case "PLURAL":
				if ( tOut["plural"] ) {
					// ----- use predefined value ----- \\
					tOutput = tOut["plural"];
				} else {
					// ----- calculate it using grammar rule ----- \\
					if ( tOutput.substring(tOutput.length-1,tOutput.length).toUpperCase() ==  "S" ) {
						tOutput = tOutput + "es";
					} else {
						tOutput = tOutput + "s";
					}
				}
			  break;
			  case "POSS":
				if ( tOut["poss"] ) {
					// ----- use predefined value ----- \\
					tOutput = tOut["poss"];
				} else {
					// ----- calculate it using grammar rule ----- \\
					if ( tOutput.substring(tOutput.length-1,tOutput.length).toUpperCase() ==  "S" ) {
						tOutput = tOutput + "'";
					} else {
						tOutput = tOutput + "'s";
					}
				}
			  break;
			  case "LOWER":
				tOutput = tOutput.toLowerCase();
			  break;
			  case "UPPER":
				tOutput = tOutput.toUpperCase();
			  break;
			  case "2TEXT":
				tOutput = convertNumberToText( tOutput );
			  break;
			  case "ORDINAL":
				tOutput = convertNumberToOrdinal( tOutput );
			  break;
			}
		}
		if (tAnAdd) {
			tOutput = tAnAdd + " " + tOutput;
		}
	}

	if (obj.attributes["money"] || obj.attributes["Money"] || obj.attributes["MONEY"]) {
		// -----  display money here.  ----- \\
		// ----- US/Canada:	$1000  ----- \\
		// ----- U.K.:		£1000  ----- \\
		// ----- Québec:	1000 $ ----- \\
		tOutput = "$" + tOutput;
	}

	obj.innerHTML = tOutput;
}

function fetchAttributeValue ( obj, attName ) {
	for (var j=0; j < obj.attributes.length; j++) {
		if (obj.attributes[j].name.toUpperCase() == attName.toUpperCase()) {
			return obj.attributes[j].value;
		}
	}
}

function validateSKUs ( str ) {
	var tLists = new flattenSKUs(tSKUs);
	var tValid = false;
	if (tLists.valid) {
		if (	(tLists.valid.indexOf(","+QUICKBOOKS_VERSION.Stratum+",") >= 0) ||
			(tLists.valid.indexOf(","+QUICKBOOKS_VERSION.Flavour+",") >= 0) ||
			( (tLists.valid.indexOf(","+QUICKBOOKS_VERSION.Stratum+":,") >= 0 ) &&
			  (!QUICKBOOKS_VERSION.Flavour) )
		) {
			tValid = true;
		}
	}
	if (tLists.invalid) {
		if (	(tLists.invalid.indexOf(","+QUICKBOOKS_VERSION.Stratum+",") < 0) &&
			(tLists.invalid.indexOf(","+QUICKBOOKS_VERSION.Flavour+",") < 0) &&
			( (tLists.invalid.indexOf(","+QUICKBOOKS_VERSION.Stratum+":,") < 0) ||
			  (QUICKBOOKS_VERSION.Flavour) )
		) {
			tValid = true;
		}
	}
	return tValid;
}

function flattenSKUs ( source ) {
	// ----- expand expression into two flat, complete lists of SKUs  ----- \\
	// ----- and flavours, separated and bookended by commas; i.e. ----- \\
	// ----- list = ",BASIC,PRO,PREMIER,CONTRACTOR,ACCOUNTANT,".      ----- \\
	// ----- there is a ".valid" list string and an ".invalid" one.   ----- \\

	var tNots = source.match( /NOT\(([\w,]*)\)/i );
	if (tNots) {
		var tTokens = tNots[0].substring(4,tNots[0].length-1).split(",");
	} else {
		var tTokens = source.split(",");
	}

	var tList = new Array();
	for (var j=0; j < tTokens.length; j++) {
		tOut = string_trim(tTokens[j].toUpperCase());

		// ----- convert synonyms to proper code ----- \\
		var tSynOut = tOut.replace( /^(\w*)[+-:]?$/i, "$1" );
		if (tSynOut == "BEL") { tSynOut = "ENTERPRISE"; }
		if (tSynOut == "QBES") { tSynOut = "ENTERPRISE"; }
		if (tSynOut == "ACCT") { tSynOut = "ACCOUNTANT"; }
		tOut = tOut.replace( /^(\w*)([+-:]?)$/, tSynOut+"$2" );

		// -----  search for +/- extensors to STRATUM; i.e. "PRO+" means PRO, PREMIER, etc. ----- \\
		// -----  pointless for top and bottom of list; no "MINIMUM-" or "MAXIMUM+"         ----- \\
		for (var k=1; k < QUICKBOOKS_ALLSTRATA.length-1; k++) {
			if ( tOut == QUICKBOOKS_ALLSTRATA[k] + "+" ) {
				// ----- "STRATUM+"; include this stratum and all above it ----- \\
				for ( var n=k; n < QUICKBOOKS_ALLSTRATA.length; n++ ) {
					var tStrat = QUICKBOOKS_ALLSTRATA[n];
					if ( (tList.toString()+",").indexOf(tStrat+",") < 0 )	{ tList.push( tStrat ); }
				}
				k = QUICKBOOKS_ALLSTRATA.length;
			}
			if ( tOut == QUICKBOOKS_ALLSTRATA[k] + "-" ) {
				// ----- "STRATUM-"; include this stratum and all below it ----- \\
				for ( var n=0; n <= k; n++ ) {
					var tStrat = QUICKBOOKS_ALLSTRATA[n];
					if ( (tList.toString()+",").indexOf(tStrat+",") < 0 )	{ tList.push( tStrat ); }
				}
				k = QUICKBOOKS_ALLSTRATA.length;
			}
		}

		// ----- if all else fails, just add the code you were passed ----- \\
		if ( (tList.toString()+",").indexOf(tOut+",") < 0 )		{ tList.push( tOut ); }
	}

	if (tNots) {
		this.valid = "";
		this.invalid = "," + tList.toString() + ",";
	} else {
		this.valid = "," + tList.toString() + ",";
		this.invalid = "";
	}
}

function addUnique ( tArray, tElement ) {
	for (var j=0; j<tArray.length; j++) {
		if (tArray[j] == tElement) {
			return tArray;
		}
	}
	tArray[tArray.length] = tElement;
	return tArray;
}

function string_caps ( str, delim ) {
	var txt = "";
	var tmp = str.split(delim);
	for (var i=0; i < tmp.length; i++) {
		if (tmp[i]) {
			txt += tmp[i].substring(0,1).toUpperCase();
			txt += tmp[i].substring(1,tmp[i].length);
			txt += delim;
		}
	}

	return txt;
}

function string_trim ( str ) {
	str = str.replace( /^\s*/ , "" );
	str = str.replace( /\s*$/ , "" );
	return str;
}

function convertNumberToText ( str ) {
	var tNum = parseInt(str);

	// ----- if it's not a number, just return the string ----- \\
	if ( isNaN(tNum) ) {
	return str;
	}

	var tOut = "";

	// ----- if it's zero, then return zero ----- \\
	if (tNum == 0) {
		tOut = "zero";
	}

	while ( tNum ) {
		var tNumStartLoop = tNum;

		if ( tNum > 999999999 ) {
			// ----- too big; just return the string ----- \\
			tOut = str;
			tNum = 0;
		}

		if ( tNum > 999999 ) {
			// ----- we're in the millions; find how many ----- \\
			var t1 = Math.floor( tNum / 1000000 );
			var t2 = convertThousandsToText(t1);
			if (tOut) { tOut += ","; }
			tOut += t2 + " million";

			tNum = tNum % 1000000;
		}

		if ( tNum > 999 ) {
			// ----- we're in the thousands; find how many ----- \\
			var t1 = Math.floor( tNum / 1000 );
			var t2 = convertThousandsToText(t1);
			if ( (tOut) && (t2) ) { tOut += ","; }
			tOut += t2 + " thousand";

			tNum = tNum % 1000;
		}

		if ( tNum < 1000 ) {
			// ----- we're under a thousand; finish ----- \\
			var t2 = convertThousandsToText(tNum);
			if ( (tOut) && (t2) ) { tOut += ","; }
			tOut += t2;

			tNum = 0;
		}

		// ----- do a final comparison to prevent infinite looping ----- \\
		if (tNumStartLoop == tNum) {
			// ----- if nothing happened to tNum then we're looping; kill ----- \\
			tNum = 0;
			tOut = str;
		}
	}

	return tOut;
}

function convertThousandsToText ( num ) {
	var tOut = "";
	if ( num > 999 ) {
		num = num % 1000;
	}

	if ( num > 99 ) {
		// ----- we're in the hundreds; find how many ----- \\
		var t1 = Math.floor( num / 100 );
		var t2 = convertDecadesToText(t1);
		tOut += t2 + " hundred";

		num = num % 100;
	}

	if ( num > 0 ) {
		// ----- we're under a hundred; finish ----- \\
		var t2 = convertDecadesToText(num);
		if (tOut) { tOut += " and "; }
		tOut += t2;
	}

	return tOut;
}

function convertDecadesToText ( num ) {
	var numbers = new Array("", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen");
	var decades = new Array("", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety");

	var tOut = "";
	if ( num > 99 ) {
		num = num % 100;
	}

	if ( num > 19 ) {
		// ----- set up the decade ----- \\
		var t1 = Math.floor( num / 10 );
		tOut += decades[t1];

		num = num % 10;
	}

	if ( num > 0 ) {
		// ----- all that remains is teens or singles ----- \\
		if (tOut) { tOut += "-"; }
		tOut += numbers[num];
	}

	return tOut;
}

function convertNumberToOrdinal ( str ) {
	var tNum = parseInt(str);

	if ( isNaN(tNum) ) {
		// ----- number is written as text ----- \\

		if ( str.substr(str.length-3) == "one" ) {
			return str.substring(0,str.length-3) + "first";
		}
		if ( str.substr(str.length-3) == "two" ) {
			return str.substring(0,str.length-3) + "second";
		}
		if ( str.substr(str.length-5) == "three" ) {
			return str.substring(0,str.length-5) + "third";
		}
		if ( str.substr(str.length-2) == "ty" ) {
			return str.substring(0,str.length-2) + "tieth";
		}

		return str + "th";

	} else {
		// ----- number is in numeric form ----- \\
		tLast = tNum % 10;

		if ( tLast == 1 ) {
			return str + "st";
		}
		if ( tLast == 2 ) {
			return str + "nd";
		}
		if ( tLast == 3 ) {
			return str + "rd";
		}

		return str + "th";
	}
}

// ------------------------------------------------------------ \\
// ============================================================ \\
// =====                EXPANDO SECTIONS                  ===== \\
// ============================================================ \\
// ------------------------------------------------------------ \\
// -----     INSERT CODE FOR EXPANDO AND MULTIEXPANDO     ----- \\

if (!(apex.GLOBAL_EXPANDO_FRAMES)) { apex.GLOBAL_EXPANDO_FRAMES = 0; }
if (!(apex.GLOBAL_EXPANDOFRAME_DATA)) { apex.GLOBAL_EXPANDOFRAME_DATA = new Array(); }
if (!(window.GLOBAL_MULTIEXPANDOS)) { GLOBAL_MULTIEXPANDOS = new Array(); }

function makeExpandoLink ( linkObj, divID ) {
	var tDivObj = findExpandoDiv( linkObj, divID );

	// -----  If there's no valid target zone for this link,       ----- \\
	// -----  then we don't activate the href, and it's just text. ----- \\
	if (tDivObj) {
		// ----- is there a specific icon= being asked for? ----- \\
		var myIcon = fetchAttributeValue( linkObj, "icon" );
		if (!myIcon) {
			myIcon = EXPANDO_GRAPHIC["default"];
		}

		// ----- get the index of the chosen expando icon ----- \\
		var iconIndex = 0;
		for (var i=0; i < EXPANDO_GRAPHIC.length; i++) {
			if ( myIcon == EXPANDO_GRAPHIC[i]["name"] ) {
				iconIndex = i;
				i = EXPANDO_GRAPHIC.length;
			}
		}

		// ----- does it default to open or closed? ----- \\
		var tStartOpen = ( linkObj.attributes["open"] || linkObj.attributes["Open"] || linkObj.attributes["OPEN"] ) ? "YES" : "";

		// ----- try to implement the DIV; it may yet be illegal ----- \\
		if ( !makeExpando_DivPrep( tDivObj, tStartOpen ) ) {
			return;
		}

		// ----- add open/close graphic to link ----- \\
		if ( tStartOpen ) {
			linkObj.innerHTML += "<img src=\"" + EXPANDO_GRAPHIC[iconIndex]["close"].src + "\" border=0 style=\"margin-left: 4\">";
		} else {
			linkObj.innerHTML += "<img src=\"" + EXPANDO_GRAPHIC[iconIndex]["open"].src + "\" border=0 style=\"margin-left: 4\">";
		}

		// ----- generate a unique ID if the link doesn't have one ----- \\
		if (!linkObj.id) { linkObj.id = document.uniqueID; }
		// ----- now generate the tooltip for this expando link    ----- \\
		var t = "<qb:tooltip element=\"" + linkObj.id + "\" delay=\"3000\" avoidmouse=\"false\">" + TEXT["tooltip_expando"] + "</qb:tooltip>";
		document.body.insertAdjacentHTML("beforeEnd", t);

		// ----- set custom attributes in the <A> tag ----- \\
		// ----- for the DIV ID and the iconIndex     ----- \\
		linkObj.divID = divID;
		linkObj.iconIndex = iconIndex;

		linkObj.href = "javascript:";
		linkObj.onclick = expandoText;
		linkObj.onmouseover = expandoMouseOver;
		linkObj.onmouseout = expandoMouseOut;
	}
}

function makeMultiExpandoLink ( linkObj, divID ) {
	if (!(GLOBAL_MULTIEXPANDOS[divID])) { GLOBAL_MULTIEXPANDOS[divID] = 0; }
	var tID = GLOBAL_MULTIEXPANDOS[divID] + 1;

	// ----- Div IDs for multi-expandos are made like this: "name(1)" ----- \\
	var uniqueDivID = divID+"("+tID+")";
	var tDivObj = document.all[uniqueDivID];

	// -----  If there's no valid target zone for this link,       ----- \\
	// -----  then we don't activate the href, and it's just text. ----- \\
	if (tDivObj) {
		GLOBAL_MULTIEXPANDOS[divID] = tID;

		var tStartOpen = ( linkObj.attributes["open"] || linkObj.attributes["Open"] || linkObj.attributes["OPEN"] ) ? "YES" : "";

		// ----- try to implement the DIV; it may yet be illegal ----- \\
		if ( !makeExpando_DivPrep( tDivObj, tStartOpen ) ) {
			return;
		}

		// ----- add radio button to link ----- \\
		linkObj.innerHTML = "<input type=\"radio\" name=\"" + divID + "\">" + linkObj.innerHTML;

		// ----- generate a unique ID if the link doesn't have one ----- \\
		if (!linkObj.id) { linkObj.id = document.uniqueID; }
		// ----- now generate the tooltip for this expando link    ----- \\
		var t = "<qb:tooltip element=\"" + linkObj.id + "\" delay=\"3000\" avoidmouse=\"false\">" + TEXT["tooltip_multiexpando"] + "</qb:tooltip>";
		document.body.insertAdjacentHTML("beforeEnd", t);

		// ----- set custom attributes in the <A> tag ----- \\
		// ----- for the base DIV name and # index    ----- \\
		linkObj.DivBase = divID;
		linkObj.DivIndex = tID;

		linkObj.href = "javascript:";
		linkObj.onclick = multiExpandoText;
	}
}

function makeExpando_DivPrep ( divObj, startOpen ) {
	// ----- See if this is a simple DIV or an IFRAME include file ----- \\

	tFile = "";
	if ( divObj.attributes["file"] ) { tFile = divObj.attributes["file"].value; }
	if ( divObj.attributes["File"] ) { tFile = divObj.attributes["File"].value; }
	if ( divObj.attributes["FILE"] ) { tFile = divObj.attributes["FILE"].value; }
		if (tFile) {
		// ----- There's an external file referenced by the DIV.   ----- \\
		// ----- Create and size an IFRAME for the included file.  ----- \\
		tFile = tFile.replace(/\\/g, "/");

		// ----- Convert link to explicit CHM reference.           ----- \\
//		--- Unnecessary; handled later by FixURL(). Leave out.
//		--- Keeping a copy in case problems arise in the cyclical check.
//		if ( tFile.indexOf("::") < 0 ) {
//			var tSub = TOPIC_PATH;
//			while ( tFile.substr(0,3) == "../" ) {
//				tSub = tSub.substring(0,tSub.lastIndexOf("/",tSub.length-2));
//				tFile = tFile.substring(3,tFile.length);
//			}
//			tFile = TOPIC_CHM + tSub + tFile;
//		}


		// ----- Make sure it's not a cyclical reference.          ----- \\
		// ----- walk up the "_expando_" tree and check all src.   ----- \\
		
		// 9-20-2005 mkronber:  modified this code because was not working in some cases.
		// Changed the logic to strip all compares down to the raw file name "xyz.html"
		// e.g. no leading "../" or "directory/" before the topics. This fixed the issue
		// we were seeing, also this should suffice since we have unique topic names.
		
		
		var tMe = self;
		var tLoc = "";
		var tBase = (tFile.indexOf("::/") < 0) ? tFile : tFile.substring(tFile.indexOf("::/")+3,tFile.length);
		// remove the leading "../" if present. mkronber 9-20-2005
		if ( tBase.substr(0,3) == "../" ) {
			tBase = tBase.substring(3,tBase.length);
		}
		// change "\" to "/"		
		tBase = tBase.replace(/\\/g,"/");
		// Remove directory "dir/" from file name for compare, since tBase doesn't have it.
		// mkronber 9-20-2005
		tBase = (tBase.indexOf("/") < 0) ? tBase : tBase.substring(tBase.indexOf("/")+1,tBase.length);


		var cyclical = false;
		while ( tMe.name.indexOf("_expando_") >= 0 ) {
			tLoc = unescape(tMe.location);
			tLoc = (tLoc.indexOf("::/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("::/")+3,tLoc.length);
			tLoc = tLoc.replace(/\\/g,"/");
			// remove the leading ../ if present MTK
			if ( tLoc.substr(0,3) == "../" ) {
				tLoc = tLoc.substring(3,tLoc.length);
			}
			// Remove directory from file name for compare, since tBase doesn't have it.
			// mkronber 9-20-2005
			tLoc = (tLoc.indexOf("/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("/")+1,tLoc.length);
			cyclical = cyclical || (tLoc.toLowerCase() == tBase.toLowerCase());
			tMe = tMe.parent;
		}
		// ----- also have to check against ultimate parent.       ----- \\
		tLoc = unescape(tMe.location);
		tLoc = (tLoc.indexOf("::/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("::/")+3,tLoc.length);
		tLoc = tLoc.replace(/\\/g,"/");
		// Remove directory "dir/" from file name for compare, since tBase doesn't have it.
		// mkronber 9-20-2005
		tLoc = (tLoc.indexOf("/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("/")+1,tLoc.length);
		cyclical = cyclical || (tLoc.toLowerCase() == tBase.toLowerCase());

		if ( cyclical ) {
			// ----- Cyclical reference!!!, fail and return false. ----- \\
			// If this does not properly catch a circular reference and return false, 		
			// the Javascript will enter an infinite loop!(e.g. QBW036130) mkronber 9-20-2005
			return false;
		}

		// v Celia remove it to make external expando to work Nov 21, 2005
		//tFile = FixURL( tFile );
		// ^ Celia remove it to make external expando to work Nov 21, 2005

		// ----- Note: a link to the <iframe> node is not the same ----- \\
		// ----- as a link to the frame object; which is to say    ----- \\
		// ----- divObj.all(0) != document.frames(tIFName).        ----- \\
		// ----- Which is why the iframe needs a name.             ----- \\

		apex.GLOBAL_EXPANDO_FRAMES++;
		var tIFName = "_expando_" + apex.GLOBAL_EXPANDO_FRAMES;
		var t = "<iframe name=\"" + tIFName + "\" frameborder=\"0\" scrolling=\"auto\"></iframe>";
		divObj.innerHTML = t;

		divObj.style.position = "absolute";
		divObj.style.top = -10000;
		divObj.style.left = -10000;
		divObj.style.display = "block";

		if ( tFile.indexOf("::") > 0 ) {
			tFile = "ms-its:" + TOPIC_EXTPATH + tFile;
		}
		document.frames(tIFName).location = tFile;

		// ----- store info we need later in global variables  ----- \\
		apex.GLOBAL_EXPANDOFRAME_DATA[tIFName] = new Array();
		apex.GLOBAL_EXPANDOFRAME_DATA[tIFName]["startOpen"] = startOpen;
		apex.GLOBAL_EXPANDOFRAME_DATA[tIFName]["outerDiv"] = divObj;

		resizeExpandoFrame( tIFName );

	} else {
		// ----- It's important to explicitly set the .style.display property, ----- \\
		// ----- so that it can be checked later by the show/hide script.      ----- \\

		if ( startOpen ) {
			// ----- Start this expando block open ----- \\
			divObj.style.display = "block";
		} else {
			divObj.style.display = "none";
		}
	}

	return true;
}

// ------------------------------------------------------------ \\
// -----       "ONCLICK" OPERATING CODE FOR EXPANDOS      ----- \\

function expandoText() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var divID = anchor.divID;
	var iconIndex = anchor.iconIndex;
	var divTag = findExpandoDiv( anchor, divID );

	if (divTag) {
		// ----- Find the open/close image in the link, if there is one  ----- \\
		// ----- it will be at the end of the <A> tag, so count backward ----- \\
		tPicObj = "";
		for (j=anchor.all.length-1; j >= 0; j-- ) {
			if (anchor.all(j).tagName == "IMG") {
				var tAnchor = unescape(anchor.all(j).src);
				if ( ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["open"].src) )
				  || ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["close"].src) )
				  || ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["openover"].src) )
				  || ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["closeover"].src) )
				) {
					tPicObj = anchor.all(j);
					j = -1;
				}
			}
		}

		// ----- Use the .style.display property to determine open/closed status    ----- \\
		// ----- It must be set explicitly by the setup code; it defaults to blank. ----- \\
		if (divTag.style.display == "none") {
			divTag.style.display = "block";
			if (tPicObj) {
				tPicObj.src = EXPANDO_GRAPHIC[iconIndex]["close"].src;
			}
		} else if (divTag.style.display == "block") {
			divTag.style.display = "none";
			if (tPicObj) {
				tPicObj.src = EXPANDO_GRAPHIC[iconIndex]["open"].src;
			}
		}

		// ----- need to resize parent frames, if any ----- \\
		//expandoText_nestedFrames( divTag );
		
	}
}

function multiExpandoText() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var tDivBase = anchor.DivBase;
	var tDivIndex = anchor.DivIndex;

	// ----- set the radio button to this entry ----- \\
	if ( GLOBAL_MULTIEXPANDOS[tDivBase] > 1 ) {
		document.all[tDivBase][tDivIndex-1].checked = true;
	} else {
		document.all[tDivBase].checked = true;
	}

	for (var i=1; i <= GLOBAL_MULTIEXPANDOS[tDivBase]; i++) {
		var uniqueDivID = tDivBase + "(" + i + ")";
		var tDivObj = document.all[uniqueDivID];

		if (i == tDivIndex) {
			// ----- this is the selected DIV; make visible ----- \\
			tDivObj.style.display = "block";
		} else {
			// ----- turn all others invisible ----- \\
			tDivObj.style.display = "none";
		}

		// ----- need to resize parent frames, if any ----- \\
		expandoText_nestedFrames( tDivObj );
	}
}


function expandoMouseOver() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var iconIndex = anchor.iconIndex;

	// ----- Find the open/close image in the link, if there is one  ----- \\
	// ----- it will be at the end of the <A> tag, so count backward ----- \\
	tPicObj = "";
	for (j=anchor.all.length-1; j >= 0; j-- ) {
		var imgObj = anchor.all(j);
		if (imgObj.tagName == "IMG") {
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["open"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["openover"].src;
				j = -1;
			}
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["close"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["closeover"].src;
				j = -1;
			}
		}
	}
}

function expandoMouseOut() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var iconIndex = anchor.iconIndex;

	// ----- Find the open/close image in the link, if there is one  ----- \\
	// ----- it will be at the end of the <A> tag, so count backward ----- \\
	tPicObj = "";
	for (j=anchor.all.length-1; j >= 0; j-- ) {
		var imgObj = anchor.all(j);
		if (imgObj.tagName == "IMG") {
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["openover"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["open"].src;
				j = -1;
			}
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["closeover"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["close"].src;
				j = -1;
			}
		}
	}
}

// ------------------------------------------------------------ \\
// -----         SUPPORTING FUNCTIONS FOR EXPANDOS        ----- \\

function findExpandoDiv ( anchorObj, divID ) {
	// ----- If there's a "divID", then find that DIV ID. Otherwise,  ----- \\
	// ----- search forward in the DOM for the next valid target tag. ----- \\
	// ----- Valid:  DIV tag or LI tag with "expando" class           ----- \\
	var divTag = "";

	if (divID) {
		divTag = document.all[divID];
	} else {
		for (var j=anchorObj.sourceIndex+1; j < document.all.length; j++ ) {
			var tg = document.all(j);
			if ( (tg.tagName == "DIV" || tg.tagName == "LI") &&
			      tg.className.toLowerCase() == "expando" ) {
				divTag = tg;
				j = document.all.length;
			}
		}
	}
	return divTag;
}

function resizeExpandoFrame ( frameName ) {
	// ----- Note: passing a string (frameName), rather than a window ----- \\
	// ----- handle, allows us to set a callback with setTimeout().   ----- \\

	var iframeObj = document.frames(frameName);
	if ( (iframeObj.document != null ) &&
	     (iframeObj.document.readyState == "complete") &&
	     (iframeObj.document.body != null) )  {
		// ----- page is finished loading; polish it off ----- \\

		// ----- find top-level frame that's not an "_expando_" frame ----- \\
		var tTop = iframeObj;
		while (tTop.name.indexOf("_expando_") >= 0) {
			tTop = tTop.parent;
		}
		// ----- find the window width less the nested margins ----- \\
		var parentWidth = tTop.document.body.clientWidth;
		var tWin = iframeObj;
		while (tWin != tTop) {
			var scrollbarWidth = tWin.document.body.offsetWidth - tWin.document.body.clientWidth;
			parentWidth = parentWidth - tWin.document.body.leftMargin;
			parentWidth = parentWidth - tWin.document.body.rightMargin;
			parentWidth = parentWidth - scrollbarWidth;
			parentWidth = parentWidth - 3;
			tWin = tWin.parent;
		}
		var parentHeight = apex.document.body.clientHeight;
		var maxWidthRatio = 1.0;
		var maxWidth = parentWidth * maxWidthRatio;

		// ----- (resize once to SET the scrollHeight, once to USE the scrollHeight) ----- \\
		// ----- requires third pass because of in-line rewriting of include topics  ----- \\
		try {		
		    iframeObj.resizeTo(maxWidth, iframeObj.document.body.scrollHeight);
		    iframeObj.resizeTo(maxWidth, iframeObj.document.body.scrollHeight);
		    iframeObj.resizeTo(maxWidth, iframeObj.document.body.scrollHeight);
		}
		catch (e) {
			// produced script error, prevent by using try/catch. taskID:182337 
		}

		// ----- since we know scroll bars are unnecessary, turn them off ----- \\
		iframeObj.document.body.scroll = 'no';

		// ----- this is the final size; now bring DIV back inline ----- \\
		apex.GLOBAL_EXPANDOFRAME_DATA[frameName]["outerDiv"].style.position = "static";
		if ( !(apex.GLOBAL_EXPANDOFRAME_DATA[frameName]["startOpen"]) ) {
			apex.GLOBAL_EXPANDOFRAME_DATA[frameName]["outerDiv"].style.display = "none";
		}
	} else {
		setTimeout("resizeExpandoFrame('" + frameName + "')", 100);
	}
}

function expandoText_nestedFrames ( divObj ) {
	// ----- if this is inside an included frame,     ----- \\
	// ----- keep expanding the parent frames to fit. ----- \\
	var tMe = self;
	while ( tMe.name.indexOf("_expando_") >= 0 ) {
		// -----
		tMe.resizeTo(tMe.document.body.scrollWidth, tMe.document.body.scrollHeight);
		tMe = tMe.parent;
	}
	// ----- if we're expanding, and the bottom will  ----- \\
	// ----- go past the bottom of the window, then   ----- \\
	// ----- scroll it up so it's visible.            ----- \\
	if (divObj.style.display == "block") {
		if (divObj.offsetHeight < document.body.clientHeight) {
			// ----- if the expando section is bigger than the window, don't bother ----- \\
			var tZoneBottom = divObj.offsetTop + divObj.offsetHeight;
			var tZoneY = tZoneBottom - document.body.scrollTop;
			if (tZoneY > document.body.clientHeight) {
				window.scrollTo( 0,document.body.scrollTop + (tZoneY - document.body.clientHeight) );
			}
		}
	}
}

// ------------------------------------------------------------ \\
// ============================================================ \\
// =====                  POPUP WINDOWS                   ===== \\
// ============================================================ \\
// Works with v2.3 of _updated.js.

// ----- set DEPTH_LIMIT to -1 if you want infinite popups;        ----- \\
// ----- otherwise it will be the maximum number of nested popups. ----- \\
DEPTH_LIMIT = -1;

// ----- user numeric array indexes to make array code compatible with earlier browsers. ----- \\
// ----- probably wasted effort, since some part of the DOM is bound to be incompatible. ----- \\
POPUP_OBJ	= 0;
CONTAIN_OBJ	= 1;
SHADOW_OBJ	= 2;
CONTENT_OBJ	= 3;
POPUP_IDX	= 4;
POPUP_VISIBLE	= 5;

if ((window.name.substring(0,7) != "popup__") && (window.name.substring(0,9) != "_expando_") && (window.name != "HiddenPopup")) {
	apex.globalPopupList = null;
}

function MarkPopup () {
	apex.globalMouseX = event.x;
	apex.globalMouseY = event.y;
}

function Popup ( targetURL ) {

// celia - remove Nov 21, 2005
//	var fixedURL = FixURL(targetURL);
//	if (fixedURL) { MakePopup(fixedURL); }

	MakePopup(targetURL);  // celia added
}

function FixURL( targetURL ) {
	myloc = self.location.toString();
	if (myloc.indexOf("::")>=0) {
	// ----- This is a CHM file ----- \\
		if (targetURL.indexOf("::")>=0) {
		// ----- You are calling a popup in a CHM file ----- \\
			t1 = myloc.substring(0,myloc.indexOf("::"));
			t2 = t1.substring(0,t1.lastIndexOf("\\")+1);
			newURL = t2 + targetURL;
		} else {
		// ----- Just a regular popup call ----- \\
			newURL = targetURL;
		}
	} else {
		// ----- this is a file on the hard drive ----- \\
		if (window.TOPIC_EXTPATH) {
			// ----- This is a patched file ----- \\
			TOPIC_EXTPATH = TOPIC_EXTPATH.replace(/\//g,"\\");
			if (targetURL.indexOf("::")>=0) {
				// ----- You already know the name of the CHM file ----- \\
				newURL = ("ms-its:" + TOPIC_EXTPATH + targetURL);
			} else {
				// ----- find the subfolder and make sure that "chmFile" is defined ----- \\
				try {
					t = myloc.substr(myloc.indexOf(TOPIC_UPDATEPATH)+TOPIC_UPDATEPATH.length,myloc.length);
					t = t.substr(0,t.lastIndexOf("/")+1);
					newURL = ("ms-its:" + TOPIC_EXTPATH + chmFile + t + targetURL);
				}
				catch (e) {
					newURL = "";
				}
			}
		} else {
			// ----- don't know anything about the environment ----- \\
			newURL = targetURL;
		}
	}
	return newURL;
}

function MakePopup ( targetURL ) {
	if (DEPTH_LIMIT == 0) {	open(targetURL,"_self"); return; }
	if (apex.globalPopupList == null) { apex.globalPopupList = new Array(); }

	var hPopup = null;
	var tLen = apex.globalPopupList.length;
	if (DEPTH_LIMIT == tLen) {
		apex.globalPopupList[tLen-1][POPUP_OBJ].location = targetURL;
		hPopup = apex.globalPopupList[tLen-1][POPUP_OBJ];
		FinishPopup(tLen-1);
	} else {
		for (var i=0; i<apex.globalPopupList.length; i++) {
			// ----- the window is already defined; maybe it's empty ----- \\
			if (!apex.globalPopupList[i][POPUP_VISIBLE]) {
				apex.globalPopupList[i][POPUP_OBJ].location = targetURL;
				hPopup = apex.globalPopupList[i][POPUP_OBJ];
				FinishPopup(i);
				i = apex.globalPopupList.length+1;
			}
		}
	}
	if (hPopup == null) {
		if (apex.globalPopupList.length == 0) {
			document.body.onclick = ParentClosePopups;
//			PETE:	Why is this code even here? If there's no "globalPopupList",
//				then there are no _expando_ frames. Seems simple. Test.
//			for (var j=1; j <= apex.GLOBAL_EXPANDO_FRAMES; j++) {
//				document.frames["_expando_"+j].document.body.onclick = ParentClosePopups;
//			}
		}
		hPopup = CreatePopup(targetURL);
	}
}

function CreatePopup ( targetURL ) {
	// ----- Need to create a new Popup Window ------ \\

	var idx = apex.globalPopupList.length;

	var t = "";
	t += "<div id=\"contain"+idx+"\" style=\"visibility:hidden;\">";
	t += "<div id=\"shadow_"+idx+"\" style=";
	t +=   "\"position:absolute; top:4; left:4; background-color:#C0C0C0;\"></div>";
	t += "<div id=\"content"+idx+"\" style=";
	t +=   "\"position:absolute; top:0; left:0; background-color:#FFFFFF;";
	t +=   " border:1px #000000 outset;\">";
	t += "<iframe name=\"popup__"+idx+"\" src=\"" + targetURL + "\" frameborder=\"0\" scrolling=\"auto\"></iframe>";
	t += "</div></div>";
	document.body.insertAdjacentHTML("beforeEnd", t);

	var popupObjArray = new Array();
	popupObjArray[POPUP_OBJ] = eval("popup__"+idx);
	popupObjArray[CONTAIN_OBJ] = eval("contain"+idx);
	popupObjArray[SHADOW_OBJ] = eval("shadow_"+idx);
	popupObjArray[CONTENT_OBJ] = eval("content"+idx);
	popupObjArray[POPUP_IDX] = idx;
	popupObjArray[POPUP_VISIBLE] = false;

	apex.globalPopupList[idx] = popupObjArray;

	popupObjArray[POPUP_OBJ].document.location = targetURL;
	FinishPopup(idx);

	return popupObjArray[POPUP_OBJ];
}

function FinishPopup ( idx ) {
	popupObj = apex.globalPopupList[idx][POPUP_OBJ];
	if ( (popupObj.document.readyState == "complete") &&
	     (popupObj.document.body != null) )  {
		// ----- page is finished loading; polish it off ----- \\

		fixPopupTopicLinks(popupObj.document);
		popupObj.document.body.onclick = ClosePopups;

		ResizePopup(idx);

		apex.globalPopupList[idx][CONTAIN_OBJ].style.visibility = "visible";
		apex.globalPopupList[idx][POPUP_VISIBLE] = true;

		MovePopup(idx);

	} else {
		setTimeout("FinishPopup("+idx+")", 1000);
	}
}

function MovePopup ( idx ) {
	popupObj = apex.globalPopupList[idx][POPUP_OBJ];
	contentObj = apex.globalPopupList[idx][CONTENT_OBJ];
	shadowObj = apex.globalPopupList[idx][SHADOW_OBJ];

	var nWidth = popupObj.document.body.offsetWidth;
	var nHeight = popupObj.document.body.offsetHeight;
	var parentWidth = document.body.clientWidth - 6;
	var parentHeight = document.body.clientHeight - 16;

	// ----- where would we like the popup? Centered beneath the mouse ----- \\
	var nLeft = apex.globalMouseX - (nWidth/2);
	var nTop = apex.globalMouseY + document.body.scrollTop;

	// ----- now bring it in to fit in the parent window properly ----- \\
	if ( (apex.globalMouseX + (nWidth/2)) > parentWidth ) {
		nLeft = parentWidth - nWidth;
	}
	if ( apex.globalMouseX < (nWidth/2) ) {
		nLeft = 2;
	}
	if ( (apex.globalMouseY + nHeight ) > parentHeight ) {
		nTop = parentHeight - nHeight + document.body.scrollTop;
	}

	contentObj.style.left = nLeft;
	contentObj.style.top = nTop;

	// ----- update shadow info ----- \\
	shadowObj.style.width = contentObj.style.width;
	shadowObj.style.height = contentObj.style.height;
	shadowObj.style.left = nLeft + 6;
	shadowObj.style.top = nTop + 6;

}

function ResizePopup ( idx ) {
	popupObj = apex.globalPopupList[idx][POPUP_OBJ];

	parentWidth = document.body.clientWidth;
	parentHeight = document.body.clientHeight;
	maxWidthRatio = 0.8;
	maxHeightRatio = 0.8;
	maxWidth = parentWidth * maxWidthRatio;
	maxHeight = parentHeight * maxHeightRatio;
	parentSlope = parentHeight/parentWidth;
	idealSlope = 0.65;

	// ----- start popup size at the max size, constrained by the ideal ratio ----- \\
	var popX = maxWidth;
	var popY = maxHeight;
	if (parentSlope > idealSlope) {
		popY = popX * idealSlope;
	} else {
		popX = popY / idealSlope;
	}

	// ----- test shrinking the Y to the minimum and see where that gets us ----- \\
	// ----- (resize once to SET the scrollHeight, once to USE the scrollHeight) ----- \\
	popupObj.resizeTo(popX, popupObj.document.body.scrollHeight);
	popupObj.resizeTo(popX, popupObj.document.body.scrollHeight);
	var minY = popupObj.document.body.scrollHeight;

	if (minY > popY) {
		// ----- content doesn't fit the maximum "ideal ratio" window, ----- \\
		// ----- so let's dissolve ideal ratio constraint and try again ----- \\
		popupObj.resizeTo(maxWidth, popupObj.document.body.scrollHeight);
		popupObj.resizeTo(maxWidth, popupObj.document.body.scrollHeight);
		var minY = popupObj.document.body.scrollHeight;

		if (maxHeight > minY) {
			// ----- there's still room to maneuver; ----- \\
			// ----- let's try the parent ratio ----- \\
			popupObj.resizeTo(maxWidth, maxHeight);
			qsortShrinkPopup( popupObj, 0, 0 );

			// ----- since we know scroll bars are unnecessary, turn them off ----- \\
			// ----- in case another popup DIV is added to the bottom of it ----- \\
			popupObj.document.body.scroll = 'no';
		} else {
			// ----- scroll bars are inevitable; make the window fit ----- \\
			popupObj.resizeTo(maxWidth, maxHeight);
		}
	} else {
		// ----- content does fit within the "ideal ratio", ----- \\
		// ----- now how small can we make it before scroll bars appear ----- \\
		// ----- first, reset it to fit the ideal ratio once again ----- \\
		popupObj.resizeTo(popX,popY);
		qsortShrinkPopup ( popupObj, 0, 0 );

		// ----- since we know scroll bars are unnecessary, turn them off ----- \\
		// ----- in case another popup DIV is added to the bottom of it ----- \\
		popupObj.document.body.scroll = 'no';
	}

}

function qsortShrinkPopup ( popupObj, constrainX, constrainY ) {
	// ----- this function will shrink the popupObj window towards ----- \\
	// ----- (constrainX, constrainY) using a binary qsort search ----- \\
	// ----- if called initially with 0,0 as the constraint, then ----- \\
	// ----- the aspect ratio of the window will be preserved. ----- \\

	var nowX = popupObj.document.body.clientWidth;
	var nowY = popupObj.document.body.clientHeight;

	var tryX = nowX - ((nowX - constrainX) / 2);
	var tryY = nowY - ((nowY - constrainY) / 2);
	if ( (Math.abs(nowX - constrainX) < 16) || (Math.abs(nowY - constrainY) < 16) ) {
		// ----- too small a difference; time to escape ----- \\
		return;
	}

	popupObj.resizeTo(tryX, tryY);

	if (popupObj.document.body.scrollHeight > popupObj.document.body.clientHeight) {
		// ----- (tryX,tryY) is too small; reset window and make "tryX/Y" the constraint ----- \\
		popupObj.resizeTo(nowX, nowY);
		qsortShrinkPopup( popupObj, tryX, tryY );
	} else {
		// ----- (tryX, tryY) is still legal; keep going ----- \\
		qsortShrinkPopup( popupObj, constrainX, constrainY );
	}
}


function fixPopupTopicLinks ( targetContainer ) {
	var anchors = targetContainer.all.tags("A");
	for (var i=0; i<anchors.length; i++) {
		var t = anchors[i].href.toLowerCase();
		if (t.indexOf("javascript:") == -1) {
			if (anchors[i].target == "") {
				anchors[i].target = "_parent";
			}
		}
	}
}

function ClosePopups() {
	subPops = apex.globalPopupList.length + 1;
	for (var i=0; i<apex.globalPopupList.length; i++) {
		var hPopup = apex.globalPopupList[i][POPUP_OBJ];
		if ((hPopup.event != null) && (hPopup.event.type == "click")) {
			// ----- Found the popup with the event in it ----- \\

			var myElement = hPopup.event.srcElement;
			while ((myElement.tagName != "BODY") && (myElement.tagName != "A")) {
				myElement = myElement.parentElement;
			}

			if (myElement.tagName != "A") {
				// ----- If it's not a link, vanish the current window ----- \\
				apex.globalPopupList[i][CONTAIN_OBJ].style.visibility = "hidden";
				apex.globalPopupList[i][POPUP_VISIBLE] = false;
				subPops = i+1;
			} else {
				// ----- Otherwise, vanish a subwindow ----- \\
				if (i+1 < apex.globalPopupList.length) {
					apex.globalPopupList[i+1][CONTAIN_OBJ].style.visibility = "hidden";
					apex.globalPopupList[i+1][POPUP_VISIBLE] = false;
					subPops = i+2;
				}
			}
			// ----- any sub-(sub-)popups can be eliminated; their objects will die ----- \\

			if (subPops<apex.globalPopupList.length) {
				apex.globalPopupList.length = subPops;
			}

			// ----- end loop early ----- \\
			i = apex.globalPopupList.length;
		}
	}
}

function ParentClosePopups() {
	if ( apex.globalPopupList.length > 0 ) {
		// ----- Vanish the primary popup window and truncate popup object list ----- \\
		apex.globalPopupList[0][CONTAIN_OBJ].style.visibility = "hidden";
		apex.globalPopupList[0][POPUP_VISIBLE] = false;
		apex.globalPopupList.length = 1;
	}
}


// ------------------------------------------------------------ \\
// ============================================================ \\
// =====             "RATE THIS TOPIC" CODE               ===== \\
// ============================================================ \\

function makeFeedbackAndHelpSupportLink( divObj ) {
	var t = "";
	t += "<br><br><table class='feedback'>";
	t += "<tr><td width='15'><a href='javascript:run_qbcommand(\"qbw:informationandsupport\");'><img src='" + ICON_HELP_SUPPORT + "' border='0' align='left'></a>";
	t += "<td><a href='javascript:run_qbcommand(\"qbw:informationandsupport\");'>" + TEXT["helpsupport_linktext"] + "</a><br></table>";
	t += "<IFRAME STYLE='border-width:0px; margin:0px; padding:0px; visibility:hidden; width:1px; height:1px;' name='submitTarget' ></IFRAME>"
    t +="<div id=\"yes_no_feedback\"></div>";
	t += "<form name='yesno_feedback_form' action='http://dwww.intuit.com/company/quickbooks/help_submit.cfm'  target='submitTarget'>"
	t += "<div id='source'></div>"
	t += "<div id='sku'></div>"
	t += "<div id='doc_name'></div>"
	t += "<div id='doc_chm'></div>"	
	t += "<div id='doc_date'></div>"	
	t += "<div id='rating'></div>"	
	t += "<div id='last_search'></div>"	
	t += "</form>"
	divObj.innerHTML = t;

	var s = "";


	s += "<table class='feedback'>";
	s += "<tr><td width='15'><a href='javascript:alert(\"Please click Yes or No\");'><img src='" + ICON_HELP_FEEDBACK + "' border='0' align='left'></a>";
	s += "<td><b>Did this help information resolve your issue?</b>";
	s += "</table>";
	s += "<table class='feedback'><tr><td width='20'><td>";
	s += "<a href='javascript:click_yes();'><img src='/feedback_yes.gif' border='0'></a>&nbsp;&nbsp;";
	s += "<a href='javascript:click_no();'><img src='/feedback_no.gif' border='0'></a>";
	s += "</table><br><br>";
	yes_no_feedback.innerHTML = s;

}

function click_yes (){
	// populate all the inputs for the form, them submit
	// get the CHM name and topic name
	var doc = unescape(document.URL);
	var cut_start = doc.lastIndexOf("\\") + 1;
	var to_colon = doc.lastIndexOf("::");
	var from_colon = doc.lastIndexOf("::") + 2;
	var to_end = doc.lastIndexOf(".html");
	var chm_file = doc.substring(cut_start,to_colon);
	var file_name = doc.substring(from_colon,to_end);
	var chmText =	"<input type=hidden name=doc_chm value=" + chm_file + ">";
	var topicText =	"<input type=hidden name=doc_name value=" + file_name + ">";
	doc_chm.innerHTML =  chmText;
	doc_name.innerHTML =  topicText;

	// get the SKU
	var objLocator	= new ActiveXObject("QuickBooks.CoLocator");
	var objProfile	= objLocator.Create("QBPrefs.AppParameters"); 
	var skuText		= "<input type=hidden name=sku value=" + objProfile.Flavor + ">";
	sku.innerHTML	= skuText;

	// get release version i.e. "12.R3"
	var ver = objProfile.ProductVersion;  
	var rel = objProfile.Release; 
	var version = ver + "." + rel;
	var versionText =	"<input type=hidden name=source value=" + version + ">";
	source.innerHTML =  versionText;

	// add rating to form... always 1, since 'yes' was clicked, also add novote/yesvote label to name
	var ratingText =	"<input type=hidden name=score value='1'><input type=hidden name='name' value='yesvote'>";
	rating.innerHTML =  ratingText;

	// get document date, get from document object.
	var filedate = 	CHM_DATE;	
	var docdateText =	"<input type=hidden name=doc_date value=" + filedate + ">";
	doc_date.innerHTML =  docdateText;

	// get last search
	
	var chmname;
	var awHelpSystem;
	var flavor = objProfile.Flavor;
	 if ( flavor.search(/atom/) >= 0  ) { 
		chmname = "atomcore.chm"
	 } else {
		chmname = "core.chm"
	 }
	 
	awHelpSystem =  TOPIC_EXTPATH + chmname;
	 
	var sSeedQuestion = aw.GetSeedQuery (awHelpSystem);
	var lastsearchText =	"<input type=hidden name=last_search value=" + escape(sSeedQuestion) + ">";
	last_search.innerHTML =  lastsearchText;
   
	// submit the form to hidden frame.
	document.yesno_feedback_form.submit(); 

	// remove the buttons, and replace with the "thank you" message
	var t = "";
	t+= "<table class='feedback'><tr><td width='15'><a href='javascript:alert(\"Your feedback has already been submitted. Thank you!\");'><img src='" + ICON_HELP_FEEDBACK + "' border='0' align='left'></a>"
	t+= "<td><b>Thanks for your feedback!</table>";
	yes_no_feedback.innerHTML = t;
}

function click_no (){

	// Just launch the ratetopic feedback form.

	var doc = unescape(document.URL);
	var cut_start = doc.lastIndexOf("\\") + 1;
	var to_colon = doc.lastIndexOf("::");
	var from_colon = doc.lastIndexOf("::") + 2;
	var to_end = doc.lastIndexOf(".html");
	var chm_file = doc.substring(cut_start,to_colon);
	var file_name = doc.substring(from_colon,to_end);

	var qbw_command="qbw:help/?rateTopic=rateTopic.chm::/help_feedback.html#" + chm_file + "$0" +  file_name + "$1";
	run_qbcommand(qbw_command); 

}


// ------------------------------------------------------------ \\
// ============================================================ \\
// =====           ACTIVEX QUICKBOOKS COMMANDS            ===== \\
// ============================================================ \\

function qbcommand ( param ) {
	var current_url = document.URL;
	var cut_start = 0;
	var cut_end = current_url.lastIndexOf("::");
	var curpath = current_url.substring(cut_start,cut_end);
	var window_path = curpath + "::/qbcommand_msg.html";
	var w = window.open(window_path,"temp_window","width=4,height=1 top=10000 left=10000");
	w.close();
	var ret = xobj.RunQBCommand(param);
}

function qbcommand2 ( param ) {
	var current_url = document.URL;
	var cut_start = 0;
	var cut_end = current_url.lastIndexOf("::");
	var curpath = current_url.substring(cut_start,cut_end);
	var window_path = curpath + "::/qbcommand_msg.html";
	var w = window.open(window_path,"temp_window","width=4,height=1 top=10000 left=10000");
	w.close();
	var ret = xobj.RunQBCommand2(param);
}


function run_qbcommand ( param )	{ var ret = xobj.RunQBCommand(param); }
function qbcommand_redirect ( param )	{ var ret = xobj.RunQBCommand(param); }
function openURL ( param )		{ var ret = xobj.OpenURL(param); }
function QBURL ( param )		{ var ret = xobj.OpenURL(param); }
function displaytopic ( param )		{ var ret = xobj.DisplayHTMLHelpTopic(param); }


// ------------------------------------------------------------ \\
// ============================================================ \\
// =====         GENERATE HELP FOR THIS TOOLKIT           ===== \\
// ============================================================ \\

function displaySKU() {
	var t = "";
	t += "<div style=\"font-family: 'MS Sans Serif'; font-size: 10pt; font-weight: bold;\"><hr>";
	t += "<font color='darkred'>SHOW THE DETECTED SKU INFORMATION</font> <br>";
	t += "Stratum: '" + QUICKBOOKS_VERSION.Stratum + "' <br>";
	t += "Flavor: '" + QUICKBOOKS_VERSION.Flavour + "' <br>";
	if (QUICKBOOKS_VERSION.Error) {
		t += "Error: " + QUICKBOOKS_VERSION.Error + " <br>";
	}
	t += "<hr></div>";
	return t;
}

function displayAllSKUs() {
	var t = "";
	t += "<div style=\"font-family: 'MS Sans Serif'; font-size: 10pt; font-weight: bold;\"><hr>";
	t += "<font color='darkred'>LIST ALL SKU TAGS</font> <br>";
	t += "<font color='darkred'>(\"Strata\")</font> <br>";
	for (var i=0; i < QUICKBOOKS_ALLSTRATA.length; i++ ) {
		t += QUICKBOOKS_ALLSTRATA[i];
		if (QUICKBOOKS_ALLSTRATA[i] == "PREMIER" || QUICKBOOKS_ALLSTRATA[i] == "ENTERPRISE") {
			t += " (includes flavors)";
		}
		t += " <br>";
	}
	t += "<br>";
	t += "BEL (synonym for ENTERPRISE) <br>";
	t += "QBES (synonym for ENTERPRISE) <br>";
	t += "<br>";
	for (var i=1; i < QUICKBOOKS_ALLSTRATA.length; i++ ) {
		t += QUICKBOOKS_ALLSTRATA[i] + "+ = ";
		for (var j=i; j < QUICKBOOKS_ALLSTRATA.length; j++) {
			t += QUICKBOOKS_ALLSTRATA[j];
			if ( j < QUICKBOOKS_ALLSTRATA.length-1 ) { t += ", "; }
		}
		t += " <br>";
	}
	t += "<br>";
	for (var i=0; i < QUICKBOOKS_ALLSTRATA.length-1; i++ ) {
		t += QUICKBOOKS_ALLSTRATA[i] + "- = ";
		for (var j=0; j <= i ; j++) {
			t += QUICKBOOKS_ALLSTRATA[j];
			if ( j < i ) { t += ", "; }
		}
		t += " <br>";
	}
	t += "<br>";
	t += "PREMIER: = PREMIER without any flavor <br>";
	t += "ENTERPRISE: = ENTERPRISE without any flavor <br>";
	t += "<br>";

	t += "<font color='darkred'>(\"Flavors\")</font> <br>";
	for (var i=0; i < QUICKBOOKS_ALLFLAVOURS.length; i++ ) {
		t += QUICKBOOKS_ALLFLAVOURS[i] + " <br>";
	}
	t += "<hr></div>";
	return t;
}

function displayAllMods() {
	var t = "";
	t += "<div style=\"font-family: 'MS Sans Serif'; font-size: 10pt; font-weight: bold;\"><hr>";
	t += "<font color='darkred'>LIST ALL TEXT 'MODS'</font> <br>";
	t += "<font color='blue'>AN</font> - add 'a' or 'an' prefix <br>";
	t += " &nbsp; Special case-sensitive versions: <br>";
	t += " &nbsp; <font color='blue'>a/n</font> - add 'a' or 'an' prefix <br>";
	t += " &nbsp; <font color='blue'>A/n</font> - add 'A' or 'An' prefix <br>";
	t += " &nbsp; <font color='blue'>A/N</font> - add 'A' or 'AN' prefix <br>";
	t += "<font color='blue'>CAPALL</font> - capitalize first letter of every word <br>";
	t += "<font color='blue'>CAPFIRST</font> - capitalize first letter of phrase <br>";
	t += "<font color='blue'>PLURAL</font> - make variable plural <br>";
	t += "<font color='blue'>POSS</font> - make variable possessive <br>";
	t += "<font color='blue'>UPPER</font> - make text upper case <br>";
	t += "<font color='blue'>LOWER</font> - make text lower case <br>";
	t += "<font color='blue'>2TEXT</font> - convert a number (15) to text (fifteen) <br>";
	t += "<font color='blue'>ORDINAL</font> - make number ordinal (15th or fifteenth) <br>";
	t += "<hr></div>";
	return t;
}

function displayHelp() {
	var t = "";
	t += "<div style=\"font-family: 'Arial'; font-size: 10pt;\"><hr>";
	t += "<b><font color='darkred'>INTUIT'S HTML TOOLKIT HELP</font></b> <br>";
	t += "<b><font color='blue'>&lt;listallskus&gt;</font></b> - display a report of all SKU codes available. <br>";
	t += "<b><font color='blue'>&lt;listallmods&gt;</font></b> - display a report of all text mods for variables. <br>\n";

	t += "<p><b><u> Conditional text syntax: </u></b><br>";
	t += "<b>&lt;p <font color='green'>skus=\"PRO,PREMIER\"</font>&gt;</b><br>";
	t += "- this paragraph will only appear in Pro or Premier. <br>";
	t += "<b>&lt;p <font color='green'>skus=\"PRO+\"</font>&gt;</b><br>";
	t += " - this paragraph will appear in Pro or higher (Pro, Premier, Enterprise). <br>";
	t += "<b>&lt;p <font color='green'>skus=\"PRO-\"</font>&gt;</b><br>";
	t += " - this paragraph will only appear Pro or lower (Atom, Basic, Pro). <br>";
	t += "<b>&lt;p <font color='green'>skus=\"PREMIER:\"</font>&gt;</b><br>";
	t += " - this paragraph will only appear Premier without a flavor. <br>";
	t += "<b>&lt;p <font color='green'>skus=\"NOT(PREMIER,CONTRACTOR)\"</font>&gt;</b><br>";
	t += " - this paragraph will only appear if the build is not Premier and not Contractor. <br>";
	t += "</p>\n";

	t += "<p><b><u> Variable syntax: </u></b><br>";
	t += "<b>&lt;var <font color='green'>name=\"CustomerTerm\"</font>&gt; client &lt;/var&gt;</b><br>";
	t += "- the word <i>client</i> will be replaced with whatever $CustomerTerm is set to at runtime. <br>";
	t += "<b>&lt;var name=\"CustomerTerm\" <font color='green'>mods=\"AN,CAPALL\"</font>&gt; client &lt;/var&gt;</b><br>";
	t += "- the $CustomerTerm (<i>customer</i>, for example) will be displayed as \"<i>A Customer</i>\". <br>";
	t += "<b>&lt;var <font color='green'>mods=\"AN,CAPALL\"</font>&gt; client &lt;/var&gt;</b><br>";
	t += "- without a variable, the mods will be applied to the text: \"<i>A Client</i>\". <br>";
	t += "<b>&lt;var <font color='green'>money</font>&gt; 10,000 &lt;/var&gt;</b><br>";
	t += "- a special mod, <b>money</b>, will place the appropriate currency mark in the right location. <br>";
	t += "- it can be used in conjunction with all the others. <br>";
	t += "</p>\n";

	t += "<p><b><u> IREFs: \"Intelligent\" References </u></b><br>";
	t += "<b>&lt;a <font color='green'>iref=\"other_topic.html\"</font>&gt;click here&lt;/a&gt;</b><br>";
	t += "- an IREF can be used just like a normal HREF. <br>";
	t += "<b>&lt;a iref=\"other_topic.html\" <font color='green'>targetskus=\"PREMIER\"</font>&gt;click here&lt;/a&gt;</b><br>";
	t += "- you can specify a list of valid SKUs for the target. <br>";
	t += "- if the current SKU is valid, the link will work normally. If not, it appears as plain text. <br>";
	t += "<b>&lt;a <font color='green'>popup=\"other_topic.html\"</font> targetskus=\"PREMIER\"&gt;click here&lt;/a&gt;</b><br>";
	t += "- if you use <b>popup</b> in place of <b>iref</b>, the target will appear in a popup window. <br>";
	t += "</p>\n";

	t += "<p><b><u> \"Expando\" Text and Files </u></b><br>";
	t += "<b>&lt;a <font color='green'>expando</font>&gt;click here&lt;/a&gt;</b><br>";
	t += "<b>&lt;<font color='green'>div class=\"expando\"</font>&gt; Show or hide this text &lt;/div&gt;</b><br>";
	t += "- an open/close graphic (<img src=\"" + EXPANDO_GRAPHIC[0]["open"].src + "\">) ";
	t += "is inserted into the &lt;a expando&gt; tag automatically. <br>";
	t += "- the expando link will apply to the next DIV tag with the class set to \"expando\". <br>";
	t += "<b>&lt;a expando <font color='green'>open</font>&gt;click here&lt;/a&gt;</b><br>";
	t += "- you can specify that the DIV will start shown as opposed to hidden (the default). <br>";
	t += "<b>&lt;a expando <font color='green'>icon=\"white\"</font>&gt;click here&lt;/a&gt;</b><br>";
	t += "- you can specify which expando icons you want to use. Here's the current supported list: <br>";
	for (var k=0; k < EXPANDO_GRAPHIC.length; k++) {
		t += "&nbsp; &nbsp; \"" + EXPANDO_GRAPHIC[k]["name"] + "\" <br>";
	}
	t += "<b>&lt;a expando&gt;click here&lt;/a&gt;</b><br>";
	t += "<b>&lt;div class=\"expando\" <font color='green'>file=\"external_file.html\"</font>&gt; This will be erased &lt;/div&gt;</b><br>";
	t += "- you can link in the contents of an external file into the DIV. This will overwrite any text in the DIV. <br>";
	t += "<b>&lt;div class=\"expando\" <font color='purple'>id=\"somedivid\"</font>&gt; Show or hide this text &lt;/div&gt;</b><br>";
	t += "<b>&lt;p&gt; Some intervening HTML, it doesn't matter &lt;/p&gt;</b><br>";
	t += "<b>&lt;a <font color='purple'>expando=\"somedivid\"</font>&gt;click here&lt;/a&gt;</b><br>";
	t += "- you can specify a DIV ID if you want to affect a DIV that's located elsewhere in your HTML. <br>";
	t += "</p>\n";

	t += "<p><b><u> Notes: </u></b><br>";
	t += "<li>Custom HTML tags are case-sensitive: <i>name</i> is not the same as <i>Name</i>. The scripts have been written to recognize either full uppercase (<i>IREF</i>) or full lowercase (<i>iref</i>), but be careful of irregular capitalization.</li>";
	t += "</p>";
	t += "<hr></div>";
	return t;
}

// ------------------------------------------------------------ \\






//
// Old "QBW.JS" file, to aid in transition. Take this out when conversion is complete.
//

// Javascript for QB commands.  Created by Ione Pang on 5/15/02

// All code copyright (c) 2001-2002 Intuit Canada Ltd.
// Any unauthorized duplication or reuse of this code
// is a violation of applicable laws.
// Coded by Peter Harris.
// Version 1.41 - Feb. 24, 2003 - Added "SlectSKUversion2" for more granular calls.
// Version 1.4 - Feb 14, 2003 - Added Nonprofit and Medical Flavors - Jeff Taggart
//  - Currently the script is treating the Lightning flavors for Premier and Enterprise as one SKU (Healthcare, for example). (i.e. it is not making a distinction betweeen Prem Healtcare and Ent Healthcare, even though they are technically different SKUs.)
// Version 1.35 - Dec 31, 2002
//	- fixed bug in popup code for patched popup topics regarding top.globalPopupList existing.
//	- fixed popup calls from patched files in FixURL(). Again; was done previously and lost.
// Version 1.2 -- Added by Brenda Bowden on Sept. 17, 2002
//  - Added JavaScript from Jeff Taggert for additional SKU management functions.
// Version 1.1b - Sep 16, 2002
//	- added FixURL() function to allow for cross-CHM and patched popup links.
//	- made SKU detect fault-tolerant to allow CHM to be opened without the product running.
// Version 1.1a - Aug 1, 2002
//	- modified Popup Code: checks Click event srcElement for parental <A>; allows tags within links.
// Version 1.1 - Jul 11, 2002
//	- added Popup code
// Version 1.0 - Mar 20, 2002

// ----------------------------------------------------------------- \\
// ================================================================= \\
// =====     SKU MANAGEMENT FUNCTIONS FROM JEFF TAGGART        ===== \\
// ================================================================= \\

var BASIC = 1;
var PRO = 2;
var PREMIER = 3;
var ACCOUNTANT = 4;
var BEL = 5;
var CONT = 6;
var BELAE = 7;
var NONPROFIT = 8;
var HEALTHCARE = 9;
var SKUversion;

function selectSKUVersion () {

		var objLocator = new ActiveXObject("QuickBooks.CoLocator");
		var objProfile = objLocator.Create("QBPrefs.AppParameters"); 

		flavor = objProfile.Flavor;  // a string value; eg. "accountant"

		if (flavor == "pro") {
			SKUversion = PRO;
		} else if (flavor == "superpro") {
			SKUversion = PREMIER;	
		} else if (flavor == "accountant") {
			SKUversion = ACCOUNTANT; 
		} else if (flavor == "bel") {
			SKUversion = BEL;
		} else if (flavor == "contractor") {
			SKUversion = CONT; 
		} else if (flavor == "belcontractor") {
			SKUversion = CONT; 
		} else if (flavor == "belacct") {
			SKUversion = BELAE; 
		} else if (flavor == "nonprofit") {
			SKUversion = NONPROFIT; 
		} else if (flavor == "belnonprofit") {
			SKUversion = NONPROFIT; 
		} else if (flavor == "healthcare") {
			SKUversion = HEALTHCARE; 
		} else if (flavor == "belhealthcare") {
			SKUversion = HEALTHCARE; 
		} else {
			SKUversion = BASIC; 
		}

}

function showSKUcontent(n,display,SKU1,SKU2,SKU3,SKU4,SKU5,SKU6,SKU7,SKU8,SKU9) {
	selectSKUVersion();
    eval('thisItem=n');
	var displayType=display;
	// for debugging
	// document.write(SKUversion, n, display, SKU1, SKU2, SKU3, SKU4, SKU5, SKU6, SKU7, SKU8, SKU9);
	if (SKUversion==SKU1 || SKUversion==SKU2 || SKUversion==SKU3 || SKUversion==SKU4 || SKUversion==SKU5 || SKUversion==SKU6 || SKUversion==SKU7 || SKUversion==SKU8 || SKUversion==SKU9)
		{thisItem.style.display = displayType;}
	else 
	{thisItem.style.display = "none";}
}

function switchSKUimage(imgID,BASICsrc,PROsrc,PREMIERsrc,ACCOUNTANTsrc,BELsrc,CONTsrc,BELAEsrc,NONPROFITsrc,HEALTHCAREsrc) {
	selectSKUVersion();
	var dir = "images/"
    eval('thisItem=imgID');
	// document.write(version);
	if (SKUversion==BASIC)
	{thisItem.src = dir + eval('BASICsrc');}
	if (SKUversion==PRO)
	{thisItem.src = dir + eval('PROsrc');}
	if (SKUversion==PREMIER)
	{thisItem.src = dir + eval('PREMIERsrc');}
	if (SKUversion==ACCOUNTANT)
	{thisItem.src = dir + eval('ACCOUNTANTsrc');}
	if (SKUversion==BEL)
	{thisItem.src = dir + eval('BELsrc');}
	if (SKUversion==CONT)
	{thisItem.src = dir + eval('CONTsrc');}
	if (SKUversion==BELAE)
	{thisItem.src = dir + eval('BELAEsrc');}
	if (SKUversion==NONPROFIT)
	{thisItem.src = dir + eval('NONPROFITsrc');}
	if (SKUversion==HEALTHCARE)
	{thisItem.src = dir + eval('HEALTHCAREsrc');}
}

var BASIC2 = 1;
var PRO2 = 2;
var PREMIER2 = 3;
var ACCOUNTANT2 = 4;
var BEL2 = 5;
var CONT2 = 6;
var BELAE2 = 7;
var NONPROFIT2 = 8;
var HEALTHCARE2 = 9;
var BELNONPROFIT2 = 10;
var BELHEALTHCARE2 = 11;
var BELCONT2 = 12;
var SKUversion2;

function selectSKUVersion2 () {
    var obj = new ActiveXObject("QuickBooks.CoLocator");
    var myQBPrefs = obj.Create("QBPrefs.Preferences");

	if (myQBPrefs.ProductIsPRO)
	{
		SKUversion2 = PRO2;
		if (myQBPrefs.QBOL("Application.SKU='superpro'"))
		SKUversion2 = PREMIER2;	
		if (myQBPrefs.QBOL("Application.SKU='accountant'"))
		SKUversion2 = ACCOUNTANT2; 
		if (myQBPrefs.QBOL("Application.SKU='bel'"))
		SKUversion2 = BEL2;
		if (myQBPrefs.QBOL("Application.SKU='contractor'"))
		SKUversion2 = CONT2; 
		if (myQBPrefs.QBOL("Application.SKU='belcontractor'"))
		SKUversion2 = BELCONT2; 
		if (myQBPrefs.QBOL("Application.SKU='belacct'"))
		SKUversion2 = BELAE2; 
		if (myQBPrefs.QBOL("Application.SKU='nonprofit'"))
		SKUversion2 = NONPROFIT2; 
		if (myQBPrefs.QBOL("Application.SKU='belnonprofit'"))
		SKUversion2 = BELNONPROFIT2; 
		if (myQBPrefs.QBOL("Application.SKU='healthcare'"))
		SKUversion2 = HEALTHCARE2; 
		if (myQBPrefs.QBOL("Application.SKU='belhealthcare'"))
		SKUversion2 = BELHEALTHCARE2; 
	}
	else
	{ 
		SKUversion2 = BASIC2; 
	}
}

function showSKUcontent2(n,display,SKU1,SKU2,SKU3,SKU4,SKU5,SKU6,SKU7,SKU8,SKU9,SKU10,SKU11,SKU12) {
	selectSKUVersion2();
    eval('thisItem=n');
	var displayType=display;
	// for debugging
	// document.write(SKUversion, n, display, SKU1, SKU2, SKU3, SKU4, SKU5, SKU6, SKU7, SKU8, SKU9);
	if (SKUversion2==SKU1 || SKUversion2==SKU2 || SKUversion2==SKU3 || SKUversion2==SKU4 || SKUversion2==SKU5 || SKUversion2==SKU6 || SKUversion2==SKU7 || SKUversion2==SKU8 || SKUversion2==SKU9 || SKUversion2==SKU10 || SKUversion2==SKU11 || SKUversion2==SKU12)
		{thisItem.style.display = displayType;}
	else 
	{thisItem.style.display = "none";}
}
