function FDCPClient()
{
	this.cpHost = "cache-01.cleanprint.net";
	this.divid="2418";
	this.refid="2361";
	this.rt = "i";
	this.cpstatus = false;
	this.ptstatus = "y";
	this.printSpecId = 0;
	this.outputFormat = "text/html";
	this.action = "print";
	this.args = null;
	this.fdDebug = false;
	this.cpc = null;
	this.blkwidth=0;
	this.xpathLib = "https://cache-01-secure.cleanprint.net/js/cp/3.0.5.4/xpath.js";
	this.shost = "cache-01-secure.cleanprint.net";
	this.hosted = "customer";
	this.blockThreshold = 500;
	this.trackerHost = "cleanprint.net";
	this.loadDelayed = true;

	this.modes = {unset:0, printLink:1, filePrint:2, printerFriendlyViewer:3};
	this.mode = 0;//modes.unset
	this.resetMode = function(){this.mode = this.modes.unset;};
	this.cookie_flags = "pv";
	this.category = "UNKNOWN";
	this.site = "UNKNOWN";

	// moved from the printtracker FormatDynamicsPT object
	this.pthosts = "formatdynamics.com,cleanprint.net,formatdyn.hs.llnwd.net";
  	this.autoRefreshCSS = "true";
  	this.autoRefreshTime = "30000";
  
	// quantcast tracking: n => turn off qc tracking, anything else leaves it on
  	this.enableQC = "y";

	// templatetest var to pull templates from a directory
	this.templateTest = true;
	
	// 's' for standalone and 'c' for combined.  A standalone install turns off registration for
	// PrintTracker events
	this.insType = "c";

	this.colre = new RegExp(":", "g");
	this.comre = new RegExp(",", "g");

  	this.isPtCss=function(content) {
    var phosts = this.pthosts.split(',');
    for(var i = 0; i < phosts.length; i++) {
      if(content.indexOf(phosts[i]) != -1)
        return true;
    }
    return false;
  }
	
	// templatetest var to pull templates from a directory
	this.templateTest = false;
	
	// 's' for standalone and 'c' for combined.  A standalone install turns off registration for
	// PrintTracker events
	this.insType = "c";

	this.escCom = function(st) {
		st = new st.constructor(st);
		st = st.replace(this.colre, "::");
		st = st.replace(this.comre, ":,");
		return st;
	}

	this.getSegment=function () { 
		var fullHref = window.location.href;if(fullHref.indexOf("/news/") > 0){return "newsarticles,other";}if(fullHref.indexOf("entertainmentnewsarticleprint.aspx") > 0){return "newsarticles,other";}if(fullHref.indexOf("/commentator") > 0){return "bts,other";}if(fullHref.indexOf("movietheatershowtimes") > 0){return "tsp,other";}if(fullHref.toLowerCase().indexOf("theaterlistings.aspx") > 0){return "tspprint,other";}if(fullHref.indexOf("theaterlistings-prn.aspx") > 0){return "tspprint,other";}if(fullHref.indexOf("theaterpage-prn.aspx") > 0){return "tlpprint,other";}if(fullHref.indexOf("/theaterpage") > 0){return "tlp,other";}if(fullHref.indexOf("TheaterPage.aspx") > 0){return "tlp,other";}if(fullHref.indexOf("movietimes") > 0){return "mlp,other";}if(fullHref.indexOf("movieshowtimesprintable.aspx") > 0){return "mlpprint,other";}if(fullHref.indexOf("movieshowtimes.aspx") > 0){return "mlp,other";}if(fullHref.indexOf("TicketStub.aspx") > 0){return "nonregalprint,other";}if(fullHref.indexOf("UserConfirmation.aspx") > 0){return "nonregalprint,other";}if(fullHref.indexOf("TicketBoxOfficeConfFinal.aspx") > 0){return "nonregalprint,other";}if(fullHref.indexOf("ConfirmationPrint.aspx") > 0){return "nonregalprint,other";}return "other,other";
	}
	this.getCPViewerId=function(){
		
	}
	this.getPFF = function() { 
		var u=window.location.href;if(u.indexOf("UserConfirmation")>0){return "0";}else if(u.indexOf("TicketBoxOfficeConfFinal")>0){return "0";}else if(u.indexOf("TheaterPage.aspx")>0){return "0";}else if(u.indexOf("movieshowtimes.aspx")>0){return "0";}else if(u.toLowerCase().indexOf("theaterlistings.aspx")>0){return "0";}else if(u.indexOf("entertainmentnewsarticlepage.aspx")>0){return "0";}else if(u.indexOf(".aspx") > 0){return "1";}return "0";
	}

	this.getVR = function() { 
		var repVals = new Object();repVals.protocol=window.location.protocol,repVals.targeting_values = "";repVals.dma = "";repVals.zip = "";repVals.rt = "";repVals.tloc = "";if(typeof _rsisa != "undefined" && _rsisa != null){repVals.tloc = _rsisa;}// News, Commentator, Showtimesvar ret = "";try {    var s = document.getElementsByTagName('IFRAME');    var src;    for ( var i = 0; i < s.length; i++) {        if (s[i].src.indexOf('fandango.dart') > 0) {            src = s[i].src;            break;        }    }    if (typeof src != 'undefined' && src != null && src.length > 0) {        ret = src.substring(src.indexOf(";"), src.indexOf("ord"));    }} catch (e) {}if (ret != null && ret.length > 0) {    ret = ret.replace("468x60", "660x82");    ret = ret.replace("728x90", "660x82");    ret = ret.replace("160x600", "660x82");    repVals.targeting_values = ret;    return repVals;}function getCookie( check_name ) {    // first we'll split this cookie up into name/value pairs    // note: document.cookie only returns name=value, not the other components    var a_all_cookies = document.cookie.split( ';' );    var a_temp_cookie = '';    var cookie_name = '';    var cookie_value = '';    var b_cookie_found = false; // set boolean t/f default f    for ( i = 0; i < a_all_cookies.length; i++ )    {        // now we'll split apart each name=value pair        a_temp_cookie = a_all_cookies[i].split( '=' );        // and trim left/right whitespace while we're at it        cookie_name = a_temp_cookie[0].replace(/^s+|s+$/g, '');        // if the extracted name matches passed check_name        if ( cookie_name == check_name )        {            b_cookie_found = true;            // we need to handle case where cookie has no value but exists (no = sign, that is):            if ( a_temp_cookie.length > 1 )            {                cookie_value = unescape( a_temp_cookie[1].replace(/^s+|s+$/g, '') );            }            // note that in cases where cookie is initialized but no value, null is returned            return cookie_value;            break;        }        a_temp_cookie = null;        cookie_name = '';    }    if ( !b_cookie_found )    {        return null;    }}var zip = getCookie('zip');if(zip == null || zip.length == 0){    zip = getCookie('dmazip');}if(zip != null){repVals.zip = zip;}var dma = getCookie('dma');if(dma != null){repVals.dma = dma;}return repVals;
	}

	this.onPrint = function(cpdata) { 
		if(this.getCalculatedPrintSpecId() == null){return false;}try{var ticketnodexpath = {include:'outer',occurrence:'all',required:'0',query:'//div[@id="ticket"]'};var ticketnode = fdcp.getXPathNodes(ticketnodexpath);if(window.location.href.indexOf("ConfirmationPrint.aspx") > 0 && ticketnode != null && ticketnode.length == 0){return false;}}catch(e){}var fullHref = window.location.href;var ss = document.getElementsByTagName("div");for (var i = 0; i < ss.length; i++) {if(ss[i].className && ss[i].className == "regalbutton"){return false;}if(fullHref.indexOf("ConfirmationPrint.aspx") > 0 ||  fullHref.indexOf("UserConfirmation.aspx") > 0 ||  fullHref.indexOf("TicketBoxOfficeConfFinal.aspx") > 0){	if(ss[i].className && ss[i].className == "barcode_left"){		cpdata.template = '6180';      return true;	}}}try{var hiddenNodesXpath = {include:'outer',occurrence:'all',required:'0',query:'//td[@class="QRCode"]'};var hiddenNodes = fdcp.getXPathNodes(hiddenNodesXpath);if(hiddenNodes != null && hiddenNodes.length > 0){cpdata.template = '9344';}}catch(e){}try{var hiddenNodesXpath = {include:'outer',occurrence:'all',required:'0',query:'//div[@class="barcode_left"]'};var hiddenNodes = fdcp.getXPathNodes(hiddenNodesXpath);if(hiddenNodes != null && hiddenNodes.length > 0){cpdata.template = '6180';}}catch(e){}try{var regex = new RegExp("&#38;#10;", "g");cpdata.pc = cpdata.pc.replace(regex, "");regex = new RegExp("&#38;#160;","g");if(cpdata.template == "9344" || cpdata.template == "6121"){cpdata.pc = cpdata.pc.replace(regex, " ");}else{cpdata.pc = cpdata.pc.replace(regex, "");}regex = new RegExp("<paragraph[^>]*><text[^>]*>[&][#]38;[#]160[;]</text></paragraph>", "g");cpdata.pc = cpdata.pc.replace(regex, "");if(cpdata.template == "6061"){  regex = new RegExp("6pt", "g");   cpdata.pc = cpdata.pc.replace(regex, "10pt");  regex = new RegExp("9pt", "g");   cpdata.pc = cpdata.pc.replace(regex, "12pt");}}catch(e){}try{var regex = new RegExp("&#38;#10;","g");cpdata.pc = cpdata.pc.replace(regex, "");regex = new RegExp("&#38;#9;","g");cpdata.pc = cpdata.pc.replace(regex, "");var regex = new RegExp("&#38;#160;","g");cpdata.pc = cpdata.pc.replace(regex, "");regex = new RegExp("<text[^>]*>[ ]*</text>","g");cpdata.pc = cpdata.pc.replace(regex, "");regex = new RegExp("<paragraph[^>]*>[ ]*</paragraph>","g");cpdata.pc = cpdata.pc.replace(regex, "");}catch(e){}
	}
	
	this.getBlockThreshold = function() {
		return this.getCfg('blockThreshold', this.blockThreshold);
	}

	this.getCfg=function(ckey, cdef) {
		if(this.cpc != null && typeof this.cpc[ckey] != 'undefined')
			return this.cpc[ckey];
		return cdef;
	}

	this.getTHost=function() {
		if(this.shost.length > 0 && document.location.protocol == "https:")
			return this.shost;
		else
			return this.cpHost;
	}
	this.getTrackerHost=function() {
		return this.trackerHost;
	}
	this.getcpStat=function() { return this.getCfg('cpStatus', this.cpstatus); }
	this.getptStat=function() { return this.getCfg('ptStatus', this.ptstatus); }
	this.getDiv=function() { return this.getCfg('divisionId', this.divid); }
	this.getOutputFormat=function() { return this.getCfg('mimeType', this.outputFormat); }
	this.getTmpl=function() { return this.getCfg('templateId', null); }
	this.getRfmt = function() { return this.getCfg('templateId', this.refid); }  
	this.getTPath = function() { return this.getCfg('tPath', null); }
	this.getLPath = function() { return this.getCfg('lPath', null); }
	this.getTO = function() { return this.getCfg('timeout', 10000); }
	this.getTemplateTest = function() { return this.getCfg('templateTest', this.templateTest); }
	this.getXpathLib = function() { return this.getCfg('xpathLib', this.xpathLib); }
	
	this.getAutoRefreshCSS = function() { return this.getCfg('autoRefreshCSS', this.autoRefreshCSS); }
	this.getAutoRefreshTime = function() { return this.getCfg('autoRefreshTime', this.autoRefreshTime); }
	this.getPtHosts = function() { return this.getCfg('pthosts', this.pthosts); }
	this.getFDDebug = function() { return this.getCfg('fdDebug', this.fdDebug); }
	
	this.getRType= function() {
		return this.rt;
	}
	
	this.getIframeUrls=function(){
		
	}
	
	this.onCpLoad = function(){
		if(this.getPFF() == "1"){setTimeout("FDCPUrl();", 1000);}
	}
	
	this.cpServletPath=(document.location.protocol == "https:" ? "https://" : "http://") + this.getTHost() + "/cp/psj";	
	this.logUrl       =(document.location.protocol == "https:" ? "https://" : "http://") + this.getTHost() + "/cp/l";
	
	this.getCalculatedPrintSpecId = function(){
			var fullHref = window.location.href;if(fullHref.indexOf("/news/") > 0){return '173';}if(fullHref.indexOf("entertainmentnewsarticleprint.aspx") > 0){return '173';}if(fullHref.indexOf("entertainmentnewsarticlepage.aspx") > 0){return '173';}if(fullHref.indexOf("/commentator") > 0){return '172';}if(fullHref.indexOf("movietheatershowtimes") > 0){return '174';}if(fullHref.toLowerCase().indexOf("theaterlistings.aspx") > 0){return '174';}if(typeof KRUXSetup != "undefined" && typeof KRUXSetup.section != "undefined" && KRUXSetup.section.indexOf("theaterselectionpage") > 0){return '174';}if(fullHref.indexOf("theaterlistings-prn.aspx") > 0){return '175';}if(fullHref.indexOf("theaterpage-prn.aspx") > 0){return '177';}if(fullHref.indexOf("/theaterpage") > 0){return '176';}if(fullHref.indexOf("TheaterPage.aspx") > 0){return '176';}if(fullHref.indexOf("movietimes") > 0){return '178';}if(fullHref.indexOf("movieshowtimesprintable.aspx") > 0){return '203';}if(fullHref.indexOf("movieshowtimes.aspx") > 0){return '178';}if(fullHref.indexOf("TicketStub.aspx") > 0){var hs = document.getElementsByTagName("h4");for(var i=0; i<hs.length; i++){ 	if(hs[i].firstChild && hs[i].firstChild.nodeValue && hs[i].firstChild.nodeValue.indexOf("Concession Voucher")>=0) {		return "2560";	} }return '212';}if(fullHref.indexOf("UserConfirmation.aspx") > 0){return '179';}if(fullHref.indexOf("TicketBoxOfficeConfFinal.aspx") > 0){return '179';}if(fullHref.indexOf("ConfirmationPrint.aspx") > 0){return '179';}if(fullHref.indexOf("behind-the-scenes") > 0){return '172';}if(fullHref.indexOf("movieoverview") > 0){return '178';}if(fullHref.indexOf("willcallredemption.aspx") > 0){return '4096';}if(fullHref.indexOf("confnumredemption.aspx") > 0){return '4096';}if(fullHref.indexOf("ccredemption.aspx") > 0){return '4096';}return false;
	}
	this.onBeforeContentSerialization = function(){
		try {	var hs = document.getElementsByTagName("h4");	var concessions = false;	for ( var i = 0; i < hs.length; i++) {		if (hs[i].firstChild && hs[i].firstChild.nodeValue				&& hs[i].firstChild.nodeValue.indexOf("Concession Voucher") >= 0) {			concessions = true;			break;		}	}	if (concessions == true) {		var d = document.getElementsByTagName("div");		var numTickets = 0;		for ( var i = 0; i < d.length; i++) {			if (d[i].className == "logohead") {				numTickets++;			}			if (d[i].className == "barcodewrap") {				d[i].setAttribute("style", "height:1px;");			}		}		numTickets = numTickets / 2;		var wrp = document.getElementById("wrap");		d = document.createElement("div");		d.className = "logohead";		d.id = "cpdiv";		d.appendChild(document.createTextNode("Ticket #" + (numTickets + 1)));		wrp.appendChild(d);	}} catch (e) {}
	}
	this.onAfterContentSerialization = function(){
		try {	var hs = document.getElementsByTagName("h4");	var concessions = false;	for ( var i = 0; i < hs.length; i++) {		if (hs[i].firstChild && hs[i].firstChild.nodeValue				&& hs[i].firstChild.nodeValue.indexOf("Concession Voucher") >= 0) {			concessions = true;			break;		}	}	if (concessions == true) {		document.getElementById("cpdiv").parentNode.removeChild(document.getElementById("cpdiv"));	}} catch (e) {}
	}
	this.onPrintSpecLoad = function(){
		if(FDCPLoader.FDCPClient.cpc.cpStatus=='n' && this.getPFF()=="1"){window.print();}if(window.attachEvent){window.attachEvent("onafterprint", function() { setTimeout(function() {var d = document.getElementById("content");if(d!=null){d.style.display="none";d.style.display="block";}}, 250)});}
	}
	this.onBeforeCleanPrint = function(data){
		try {  if(typeof fdcp.getCpPostDataValue != "undefined" && fdcp.getCpPostDataValue != null && fdcp.getCpPostDataValue.template == "6061"){    var regex = new RegExp("line-height:18px", "g");     data = data.replace(regex, "line-height:16px");    regex = new RegExp("line-height:1.2", "g");     data = data.replace(regex, "line-height:1.1");  }  if(window.location.protocol == "https:"){    var regex = new RegExp("http://cleanprint", "g");    data = data.replace(regex, "https://cleanprint");  }}catch(e){}  return data;
	}
	this.calculateCacheKey = function(){
		return cacheKey;		
	}
	
	this.onAfterCleanPrint = function(){

		// standard behavior
		if(this.enableQC == 'y')
			this.appendQC();

		// customizations
		
	}

	this.appendQC = function() {
	}
	
	this.getRequestObject = function(){
		var act = "Unknown";
		if (this.mode == this.modes.filePrint) {
			act = "Chrome";
		} else if (this.mode == this.modes.printLink
				|| this.mode == this.modes.printerFriendlyViewer) {
			act = "Link";
		}

		var logdata = {
				d : this.getDiv(),
				a : navigator.appName + " " + navigator.userAgent,
				s : this.getSegment(),
				u : window.location.href,
				p : this.getPFF(),
				r : this.getRfmt(),
				q : "1.0",
				template : this.getTmpl(),
				act : act
			};
		return logdata;
	}
}

function FormatDynamicsPT(client) {
  this.clnt = client;
  this.pcol = document.location.protocol + "//";
  this.cstr = client.getTrackerHost() + "/pt/t/";
  this.div = "d="+this.clnt.getDiv();
  this.ua = "&a=" + escape(navigator.appName + " " + navigator.userAgent);
  this.seg = "&s="+escape(this.clnt.getSegment());
  this.ustr = "&u="+escape(window.location.href);
  this.pf = "&p="+this.clnt.getPFF();
  this.version = "&q=1.1";
  this.rtype = "&rt="+this.clnt.getRType();
  this.qstr = this.div+this.ua+this.seg+this.ustr+this.pf+this.version;
  this.pthosts = this.clnt.getPtHosts();
  this.autoRefreshCSS = this.clnt.getAutoRefreshCSS();
  this.autoRefreshTime = this.clnt.getAutoRefreshTime();
  this.cssRefreshInterval = null;
  this.rcount = 0;
  this.ptssfound = false;

  this.getTURL = function() {
    return this.pcol + this.cstr + (new Date()).getTime() + '?' + this.qstr;
  }

  this.isPtCss=function(content) {
    var phosts = this.pthosts.split(',');
    for(var i = 0; i < phosts.length; i++) {
      if(content.indexOf(phosts[i]) != -1)
        return true;
    }
    return false;
  }
  
  this.changePrintStyleSheet=function() {

	this.rcount++;

	// Change fdprint stylesheet if found
	for(i=0;i<document.styleSheets.length;i++) {
		try {
			var sheet = document.styleSheets[i];
			var agent = navigator.userAgent.toLowerCase();

			if (sheet.cssRules.length == 0 || !sheet.cssRules[0].style) continue;
			
			if((navigator.appName.indexOf("Netscape") !=-1 || agent.indexOf("firefox") !=-1 ||agent.indexOf("safari") !=-1) && this.isPtCss(sheet.cssRules[0].style.content)) {
				sheet.cssRules[0].style.content = "url("+this.getTURL()+")";
          		return;
			}
			else {
				if(this.isPtCss(sheet.cssRules[0].style.getPropertyValue('content'))) {
					if(navigator.appName.indexOf("Opera") !=-1) {
						sheet.deleteRule(0);
            		}
					else if(navigator.appName.indexOf("Konqueror") ==-1) {
						sheet.cssRules[0].style.setProperty('content', 'url('+this.getTURL()+')', null);
					}
					return;
				}
			}
		}
		catch(err) { }
	}

	// otherwise insert the stylesheet
	if(this.rcount == 1) {
		try {
			var agent = navigator.userAgent.toLowerCase();
			if((navigator.appName.indexOf("Netscape") !=-1 || agent.indexOf("firefox") !=-1 ||agent.indexOf("safari") !=-1)) {
				var s = document.createElement("style");
				s.type = "text/css";
				s.rel = "stylesheet";
				s.media = "print";
				s.appendChild(document.createTextNode("body:after {content: url(" + this.getTURL() + ")};"));
				document.getElementsByTagName("head")[0].appendChild(s);
			}
		}
		catch(err) { }
	}
	else {
		formatDynamicsPT.autoRefreshCSS = "false";
	}
  }

	this.getFDImage = function() {

		// rtype of 's' is a script-based load and 'i' is an image-based load
		if(this.clnt.getRType()=='s') {
			var hs = document.documentElement.getElementsByTagName("head");
			var h = null;

			if(hs && hs.length > 0) {
				h = hs[0];
				var script = document.createElement("script");
				script.type = 'text/javascript';
				script.src = this.getTURL() + '&rnd=' + Math.random();
			}
		}
		else {
			var fdloader = new Image();
			fdloader.src = this.getTURL();
		}
	}

	this.initIE = function()
	{
		try {
			if (navigator.appName.indexOf("Microsoft")!=-1 && parseInt(navigator.appVersion)>=4 && navigator.userAgent.indexOf("Windows") != -1)
			    window.attachEvent("onbeforeprint", function() { formatDynamicsPT.getFDImage(); } );
		}
		catch(e)
		{}
	}

	this.initX = function()
	{
		try {
			if(navigator.appName.indexOf("Konqueror") != -1) {
				formatDynamicsPT.changePrintStyleSheet();
			}
			else if (navigator.appName.indexOf("Microsoft") == -1) {
				formatDynamicsPT.changePrintStyleSheet();
				formatDynamicsPT.cssRefreshInterval = setInterval("formatDynamicsPT.refreshCSS()", formatDynamicsPT.autoRefreshTime);
			}
		}
		catch(e)
		{}
	}

	this.initAll = function() { 
		try {
			this.initIE(); 
			this.initX(); 
		}
		catch(e)
		{}
	}

	this.refreshCSS = function()
	{
		if (formatDynamicsPT.autoRefreshCSS == "true")
			formatDynamicsPT.changePrintStyleSheet();
		else
			clearInterval(formatDynamicsPT.cssRefreshInterval);
	}
}
// TODO: add 'script' mode back. also add 'auto' mode to load everything without waiting
// TODO: run through rhino
// TODO: in the print spec js, we use '1' and '0', 'y' and 'n' and true and false for boolean values. clean this up.
var FDCPLoader = {

	count: 0,
	tint: 500,
	tmax: 10000,
	tagg: 0,
	incyc: false,
	loaded: false, // TODO: rename to printSpecLoaded?
	divId: 0, // TODO: redundant
	printSpecId: 0, // TODO: have a PrintSpec class? In any case, isn't needed as an instance var
	cpDef:{}, // TODO: can print spec come back as a JSON object?
	FDCPClient:new FDCPClient(),
	printPreviewWindow: null, // TODO: remove
	printPreviewWindowOpen: false, // TODO: remove
	tester: false, // TODO: still used?
	slre: new RegExp("[^/]*$"),
	plIframe: null,
		
    // TODO: this should go away
	getCfg: function(ckey, cdef) {
		if(FDCPLoader.FDCPClient.cpc != null && typeof FDCPLoader.FDCPClient.cpc[ckey] != 'undefined')
			return FDCPLoader.FDCPClient.cpc[ckey];
		return cdef;
	},

	loadcp: function() {

		if(typeof FDCPLoader.FDCPClient.onPrintSpecLoad != "undefined"){
			FDCPLoader.FDCPClient.onPrintSpecLoad();
		}
		
		// TODO: this is stupid
		this.cpc = FDCPLoader.FDCPClient.cpc;

		if(FDCPLoader.FDCPClient.cpc.cpStatus == 'n'){
			FDCPLoader.tagg = FDCPLoader.tmax + 1;
			return;
		}

		jsloc = (document.location.protocol == "https:" ? "https://" : "http://") + FDCPLoader.FDCPClient.getTHost() + "/cp/cpjs" +
		    "?d="  + FDCPLoader.FDCPClient.divid +
			"&bn=" + FDCPLoader.browserDetect.browser +
			"&bv=" + FDCPLoader.browserDetect.version +
			"&fs=" + (FDCPLoader.hasFlash() ? "true" : "false") +
			"&rp=" + FDCPLoader.FDCPClient.cpc.rpOk;
		
		if(FDCPLoader.FDCPClient.cpc.templateTest == true){
			jsloc += "&tt=true";
		}
		
		if(typeof FDCPLoader.FDCPClient.cpc.forceProxyless != "undefined"){
			if(FDCPLoader.FDCPClient.cpc.forceProxyless == true){
				jsloc += "&fp=true";
			}
			else{
				jsloc += "&fp=false";
			}
		}
		else{
			jsloc += "&fp=false";
		}

		if(typeof FDCPLoader.FDCPClient.cpc.compressJS != "undefined"){
			if(FDCPLoader.FDCPClient.cpc.compressJS == true){
				jsloc += "&cj=true";
			}
			else{
				jsloc += "&cj=false";
			}
		}

        var e = document.createElement('script');
		e.src = jsloc;
		e.type = 'text/javascript';
		document.getElementsByTagName("head")[0].appendChild(e);
	},
	
	getPDScriptUrl: function(){
		
		var snodes = document.getElementsByName('cleanprintloader');
		var url = "";

		if(snodes.length > 0) {
			url = snodes[0].src;
		}
		else {

			snodes = document.getElementsByTagName('SCRIPT');

			for(var i = 0; i < snodes.length; i++) {
				if(snodes[i].name == 'cleanprintloader') {
					url = snodes[i].src;
					break;
				}
			}
		}
		
		return url;
	},
	
	
	loadPrintSpec: function(){

		try
		{
			formatDynamicsPT = new FormatDynamicsPT(new FDCPClient());
			formatDynamicsPT.initX();

			var psfailed = false;

			if(!this.loaded) {
				this.loaded = true; // TODO: shouldn't we set this after a successful load?
				var pdSrc = this.getPDScriptUrl();
			
				// TODO: is this still necessary?
				if (this.FDCPClient.hosted == "fd" && pdSrc.length > 0)
					this.divId = this.getDivisionId(pdSrc);
				else
					this.divId = this.FDCPClient.divid;
			
			    // TODO: get this from the client now
				this.printSpecId = this.getPrintSpecId(pdSrc);
			
				var url = this.FDCPClient.cpServletPath;
				url += "?useCache=false";
				url += "&divId=" + this.divId;

				var psid = this.printSpecId;

				// TODO: this function is now required. clean up this logic accordingly
				if(typeof this.FDCPClient.getCalculatedPrintSpecId != "undefined" && this.tester == false)
				{
					try
					{
						psid = this.FDCPClient.getCalculatedPrintSpecId();
					
						if(typeof psid == 'undefined' || psid == null || psid == false || isNaN(psid)) {
							psid = this.printSpecId;
						}
						
						if(typeof psid == 'undefined' || psid == null || psid == false || isNaN(psid)) {
							psfailed = true;
						}
					}
					catch(err)
					{
						psfailed = true; // Shouldn't we try to use the ccg supplied value?
					}
				}

				if(psfailed)
				{
					// TODO: can we always register the PT handler, and disable by setting a flag on fdcp or something? then we don't need to mess with this logic on all cp load failures
					formatDynamicsPT.initIE();
				}
				else
				{
					url += "&printSpecId=" + psid;			
			
					var cpDefScript = document.createElement('script');
					cpDefScript.src = url;
					cpDefScript.type = 'text/javascript';
					document.getElementsByTagName("head")[0].appendChild(cpDefScript);
				}
			}
		}
		catch(e)
		{
		// TODO: something. anything. 
		}
	},

	// TODO: get rid of this
	validatePath: function(path , jsFile)
	{
		if (path.indexOf(jsFile) > 1)
			return path;
		else
		{
			if (path.charAt(path.length -1) == "/")
				return path + jsFile;
			else
				return path + "/" + jsFile;
		}	
	},
	      
	// TODO: get rid of this?
	getPrintSpecId: function(pdSrc)
	{
		var pdre = new RegExp("^[^?]+\\??");
		var queryString = pdSrc.replace(pdre,'');
	
		var params = this.parseQuery( queryString );
	
		return params['ps'];
	
	},
	
	// TODO: get rid of this
	getDivisionId: function(pdSrc)
	{
		var tmpUrl = pdSrc.replace(this.slre, "");
		var lastSlashIndex = tmpUrl.search(this.slre);
		var divId = tmpUrl.substr(0, lastSlashIndex -1);
		lastSlashIndex = divId.search(this.slre);
		divId = divId.substr(lastSlashIndex, divId.length);
	
		return divId;
	},
	
	// TODO: get rid of this if you get rid of getPrintSpecId
	parseQuery: function( query ) {
	   var Params = new Object ();
	   if ( ! query ) return Params; // return empty object
	   var pre = new RegExp("[;&]");
	   var plusre = new RegExp("\\+", "g");
	   var Pairs = query.split(pre);
	   for ( var i = 0; i < Pairs.length; i++ ) {
	      var KeyVal = Pairs[i].split('=');
	      if ( ! KeyVal || KeyVal.length != 2 ) continue;
	      var key = unescape( KeyVal[0] );
	      var val = unescape( KeyVal[1] );
	      val = val.replace(plusre, ' ');
	      Params[key] = val;
	   }
	   return Params;
	},
	
	cpJsLoaded:false,
	xpathJsLoaded:navigator.appName != "Microsoft Internet Explorer",
	registerModuleLoaded: function(moduleName){
		if(moduleName == "cp.js"){
			this.cpJsLoaded = true;
		}
		else if(moduleName == "xpath.js"){
			this.xpathJsLoaded = true;
		}
		if(this.xpathJsLoaded && this.cpJsLoaded){
			fdcp.replacePrintLinks();
		}
	},
	
    fdPrintWrapper: function(theContext){
        if(this.browserDetect.browser == "Explorer"){
            if(theContext && this.browserDetect.version >= 7){
              theContext.focus();
              theContext.document.execCommand('print', false, null);
            }
            else if(theContext) {
              theContext.print();
            }
            else{
              window.print();
            }
        }
        else{
            theContext = typeof theContext == "undefined" ? window : theContext;
            theContext.print();
        }
        fdcp.bridge.printElement = null;
    },

	// TODO: still used?
	ptFailover: function() {
		formatDynamicsPT = new FormatDynamicsPT(new FDCPClient());
		formatDynamicsPT.initAll();
	},

	getFlashVersion : function(desc){
    	var matches = desc.match(/[\d]+/g);
    	matches.length = 1;  // To standardize IE vs FF
    	return matches.join('.');
    },
	
	hasFlash : function() {

		// Flash Player Version Detection - Rev 1.6
		// Detect Client Browser type
		// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
		var nn = navigator;
		var np = nn.plugins;
		var isIE  = (nn.appVersion.indexOf("MSIE") != -1) ? true : false;
		var isWin = (nn.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
		var isOpera = (nn.userAgent.indexOf("Opera") != -1) ? true : false;

		// NS/Opera version >= 3 check for Flash plugin in plugin array
		var flashVer;

		if (nn.plugins != null && np.length > 0) {
			if (np["Shockwave Flash 2.0"] || np["Shockwave Flash"]) {
				var swVer2 = np["Shockwave Flash 2.0"] ? " 2.0" : "";
				var descArray = np["Shockwave Flash" + swVer2].description.split(" ");
				var tempArrayMajor = descArray[2].split(".");			
				flashVer = tempArrayMajor[0] > 5 ? tempArrayMajor[0] : -1;
			}
		}
		else if ( isIE && isWin && !isOpera ) {
			var axo;
			var e;

			// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
			try {
				// version will be set for 7.X or greater players
				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
				flashVer = axo.GetVariable("$version");
			} catch (e) {
			}

			if (!flashVer)
			{
				try {
					// version will be set for 6.X players only
					axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
					flashVer = "6";
				} catch (e) {
				}
			}
		}
		
		if(flashVer){
		    flashVer = this.getFlashVersion(flashVer);
        }
        else {
        	flashVer = -1;
		}

		return flashVer && flashVer > 0;
	},

	browserDetect : {
			init: function () {
				this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
				this.version = this.searchVersion(navigator.userAgent)
					|| this.searchVersion(navigator.appVersion)
					|| "an unknown version";
				this.OS = this.searchString(this.dataOS) || "an unknown OS";
			},
			searchString: function (data) {
				for (var i=0;i<data.length;i++)	{
					var dataString = data[i].string;
					var dataProp = data[i].prop;
					this.versionSearchString = data[i].versionSearch || data[i].identity;
					if (dataString) {
						if (dataString.indexOf(data[i].subString) != -1)
							return data[i].identity;
					}
					else if (dataProp)
						return data[i].identity;
				}
			},
			searchVersion: function (dataString) {
				var index = dataString.indexOf(this.versionSearchString);
				if (index == -1) return;
				return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
			},
			dataBrowser: [
				{
					string: navigator.userAgent,
					subString: "Chrome",
					identity: "Chrome"
				},
				{ 	string: navigator.userAgent,
					subString: "OmniWeb",
					versionSearch: "OmniWeb/",
					identity: "OmniWeb"
				},
				{
					string: navigator.vendor,
					subString: "Apple",
					identity: "Safari",
					versionSearch: "Version"
				},
				{
					prop: window.opera,
					identity: "Opera"
				},
				{
					string: navigator.vendor,
					subString: "iCab",
					identity: "iCab"
				},
				{
					string: navigator.vendor,
					subString: "KDE",
					identity: "Konqueror"
				},
				{
					string: navigator.userAgent,
					subString: "Firefox",
					identity: "Firefox"
				},
				{
					string: navigator.vendor,
					subString: "Camino",
					identity: "Camino"
				},
				{		// for newer Netscapes (6+)
					string: navigator.userAgent,
					subString: "Netscape",
					identity: "Netscape"
				},
				{
					string: navigator.userAgent,
					subString: "MSIE",
					identity: "Explorer",
					versionSearch: "MSIE"
				},
				{
					string: navigator.userAgent,
					subString: "Gecko",
					identity: "Mozilla",
					versionSearch: "rv"
				},
				{ 		// for older Netscapes (4-)
					string: navigator.userAgent,
					subString: "Mozilla",
					identity: "Netscape",
					versionSearch: "Mozilla"
				}
			],
			dataOS : [
				{
					string: navigator.platform,
					subString: "Win",
					identity: "Windows"
				},
				{
					string: navigator.platform,
					subString: "Mac",
					identity: "Mac"
				},
				{
					   string: navigator.userAgent,
					   subString: "iPhone",
					   identity: "iPhone/iPod"
			    },
				{
					string: navigator.platform,
					subString: "Linux",
					identity: "Linux"
				}
			]

		}
}

FDCPLoader.browserDetect.init();

function CleanPrintPrintLinkError(printLink)
{
	if (typeof printLink == 'undefined' || printLink == null || printLink == '') {
		return false; // what can we do here? Alert the user?
	}
	
	// Forward to the print link the user tried to print
	document.location.href = printLink;
}

function CleanPrintPrintLink(printLink, pfLink, isViewer) {
	
	return FDCPUrl(pfLink,isViewer,"text/html","print","printLink,"+printLink);
}

function CleanPrintPrintHtml(pfLink) {
	return FDCPUrl(pfLink);
}

function CleanPrintGeneratePdf(pfLink) {
	if (typeof pfLink == "undefined") pfLink = document.location.href;
	
	return FDCPUrl(pfLink, false, 'application/pdf', 'print');
}

function CleanPrintSendEmail(pfLink) {
	if (typeof pfLink == "undefined") pfLink = document.location.href;
	
	return FDCPUrl(pfLink, false, 'email/html', 'email');
}

function FDCPUrl(pfLink, isViewer, mimeType, action, args) {
	try {
		isViewer = typeof isViewer == "undefined" ? false       : isViewer;
		mimeType = typeof mimeType == "undefined" ? "text/html" : mimeType;
		action   = typeof action   == "undefined" ? "print"     : action;
		args     = typeof args     == "undefined" ? "" : args;

		if(isViewer && (typeof pfLink == "undefined" || pfLink == null || pfLink == '')){

			// A requirement for using the viewer is that a pf link is defined. If it isn't don't do anything.
			return false;
		}

		// if fdcp hasn't loaded yet, give it some time
		if(typeof fdcp == 'undefined') {

			if(FDCPLoader.incyc == false)
				FDCPLoader.incyc = true;

			if(FDCPLoader.tagg > FDCPLoader.tmax) {

				FDCPLoader.incyc = false;
				FDCPLoader.fdPrintWrapper();
				FDCPLoader.tagg = 0;
				
			} else {
				FDCPLoader.tagg += FDCPLoader.tint;
				setTimeout("FDCPUrl('" + pfLink + "'," + isViewer +",'" + mimeType + "','" + action + "','" + args +"')", FDCPLoader.tint);
			}

			//FDCPLoader.tagg += FDCPLoader.tint;

			//setTimeout("FDCPUrl('" + pfLink + "', " + isViewer + ")", FDCPLoader.tint);

			return false;
		}
		
		if (args.indexOf("printLink") > -1)
		{
			var splits = args.split("printLink,");
			var pl = splits[1];
			
			if (fdcp.contextFrameStarted == false)
			{
				// Remove existing iframe
				if(typeof fdcp.contextFrame != 'undefined' && fdcp.contextFrame != null)
				{
					document.body.removeChild(fdcp.contextFrame);
					fdcp.contextXpath = null;
					fdcp.contextFrameLoaded = false;
				}
				
				// create the new iframe
				fdcp.contextFrame = document.createElement("iframe");
				fdcp.contextFrame.setAttribute('id', "contextFrame");
				fdcp.contextFrame.setAttribute('NAME', "contextFrame");
				fdcp.contextFrame.setAttribute('name', "contextFrame");
				fdcp.contextFrame.setAttribute('src', pl);
				if (FDCPLoader.browserDetect.browser == "Explorer") {
					fdcp.contextFrame.onreadystatechange = function() {
						if (fdcp.contextFrame.readyState == "complete") {
							fdcp.contextFrameLoaded = true;
							fdcp.contextXpath = frames[fdcp.contextFrame.name].document;
							
						}
					};
				} else {
					fdcp.contextFrame.onload = function() {
						fdcp.contextFrameLoaded = true;
						if (FDCPLoader.browserDetect.browser == "Firefox"
								&& FDCPLoader.browserDetect.version >= 3) {
							fdcp.contextXpath = fdcp.contextFrame.contentDocument;
							
						} else {
							fdcp.contextXpath = frames[fdcp.contextFrame.name].document;
							
						}
					};
				}
				
				fdcp.contextFrame.style.width = '630px';
				fdcp.contextFrame.style.height = '1px';
				fdcp.contextFrame.style.position = 'absolute';
				fdcp.contextFrame.style.top = '-3000px';
				fdcp.contextFrame.style.border = '0px';
				document.body.appendChild(fdcp.contextFrame);
			
				// Start the loading
				fdcp.contextFrameStarted = true;
			
			}
		
		    if (fdcp.contextFrameLoaded == true)
		    {
		    	fdcp.contextFrameStarted = false;
		    	FDCPUrl(pfLink,isViewer);
		    }
		    else
		    {
				if(FDCPLoader.tagg > FDCPLoader.tmax) {
	
					fdcp.contextFrameStarted = false;
					FDCPLoader.incyc = false;
					CleanPrintPrintLinkError(pl);
					FDCPLoader.tagg = 0;
					
					
				} else {
					FDCPLoader.tagg += FDCPLoader.tint;
					setTimeout("FDCPUrl('" + pfLink + "'," + isViewer +",'" + mimeType + "','" + action + "','" + args + "')", FDCPLoader.tint);
				}
				
				return false;
		  	
		    }
		}
		else
		{
			FDCPLoader.incyc = false;
			if(isViewer || (mimeType == "email/html" || mimeType == "application/pdf")) {
				var continueCp = FDCPLoader.browserDetect.browser == "Firefox"  || 
				                 FDCPLoader.browserDetect.browser == "Explorer" || 
				                 FDCPLoader.browserDetect.browser == "Chrome" || 
								(FDCPLoader.browserDetect.browser == "Safari" && FDCPLoader.browserDetect.OS == "Mac");
				
				if(!continueCp) {
					window.open(pfLink, "pf", "");
					return false;
				}
			}
			
		    if((typeof FDCPLoader.FDCPClient.cpc.rpOk != "undefined" && FDCPLoader.FDCPClient.cpc.rpOk==false) &&
	             (isViewer || mimeType == "email/html") && (!fdcp.bridge.printElement || fdcp.bridge.printElement.closed)) {
		        fdcp.bridge.printElement = window.open("about:blank", "test", "copyhistory=yes,width=1024,height=768,left=50, top=50,screenX=50,screenY=50");
		    }
	
			fdcp.clt.mode         = isViewer ? fdcp.clt.modes.printerFriendlyViewer : fdcp.clt.modes.printLink;
			fdcp.clt.outputFormat = mimeType;
			fdcp.clt.action       = action;
			fdcp.clt.args         = args;
			fdcp.linkPrintHandler(pfLink);
	
		    if(FDCPLoader.browserDetect.browser == "Explorer") {
		        fdcp.clt.resetMode();
		    }
		    
			// Force it do everything again 'cause we need to re-eval everything if its a different button 
		    fdcp.linkClicked = false;
			fdcp.getCpPostDataValue = null;
		}
	    
	} catch(e) {
		fdcp.contextFrameStarted = false;
	}
	
	return false;
}

// a simple ajax object getter
function fdGetAjaxObj() {
	if (window.XMLHttpRequest){
		return new XMLHttpRequest(); // Mozilla & Safari
	}
	
	if (window.createRequest) {
		try { return window.createRequest(); } catch (e) { } // IceBrowser
	}

	if (window.ActiveXObject) {	// IE
		try { return new ActiveXObject("Msxml2.XMLHTTP");    } catch (e) { }
		try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { }
	}
	
	return null;
}

if (window.addEventListener) {
	window.addEventListener("load", function() { FDCPLoader.loadPrintSpec(); }, true);
}
else if (window.attachEvent) {
	window.attachEvent("onload", function() { FDCPLoader.loadPrintSpec(); });
}
else
	FDCPLoader.loadPrintSpec();
