/************************************************************************************/
<<<<<<< cmtaggingservices.js
/* $Revision: 108948 $
 * $Id: cmtaggingservices - 90224583 - 01302009.txt 108948 2009-01-30 21:09:32Z croberts $
=======
/* $Revision: 1.5 $
 * $Id: cmtaggingservices.js,v 1.5 2009/10/12 04:25:15 travis Exp $
>>>>>>> 1.5
 *
 * Author: Coremetrics/PSD 
 * Coremetrics  v1.9, 10/29/2008
 * COPYRIGHT 1999-2008 COREMETRICS, INC. 
 * ALL RIGHTS RESERVED. U.S.PATENT PENDING
 * Disclaimer: Coremetrics is not responsible for hosting or maintenance or this file
 * 20090130 CRoberts	Commented out Shopping Cart and Checkout Confirmation to stop shop, order
 *						and registration tags from being thrown from within the tagging services
 *						file.  These will be coded manually in the client HTML.
 *
 */
/************************************************************************************/
//Production data warehouse flag
//cmSetProduction();
/*===========================GLOBAL VARIABLES ===============================*/
// options for debug mode when sending tag:
// 1: only alert
// 2: only send tag
// 3: alert & send tag
var G_PS_DEBUG_MODE = 2;

// current page url
var G_PS_URL_PATH = "" + document.location;
var G_PS_PATHNAME = document.location.pathname.toLowerCase();
var G_PS_QUERYSTRING = document.location.search.toLowerCase();
var G_PS_URL_REFERRER = document.referrer.toLowerCase();
var G_PS_COOKIE_LIFETIME = 432000; // 5*24*60*60 = 5 days
// cookie name
var G_PS_COOKIE_CATID = "PS_CATID";
var G_PS_COOKIE_PROD_CATID = "PS_PROD_CATID";
var G_PS_COOKIE_PROFILE = "PS_PROFILE";
var G_PS_FLAG = "PS_FLAG";		// used as a "session" variable to handle events between pages
var G_PS_FLAG_LOGIN = "PS_FLAG_LOGIN";		// used as a "session" variable to handle events between pages
// current category ID while browsing/searching/refining, etc
var G_PS_COOKIE_SHOP9		 	= "PS_SHOP9";
var G_PS_COOKIE_PRODID		 	= "PS_PRODID";
var G_PS_COOKIE_ORDER		 	= "PS_ORDER";
/*========================= END GLOBAL VARIABLES =============================*/


/*=========================== BEGIN NAVIGATION ===============================*/
/*
 * create pageview tags for top menu pages.
*/
psSignInSuccess();
psHijackAddBoxesToCart();
if(psIsExpiredPage())
{
	psCreatePageviewTag("Expired","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/home") > -1)
{
	psCreatePageviewTag("Home","Home",null,null);
}
// Gallery-related pages
else if(document.title.toLowerCase() == "framing gallery")
{
	var pageId = "";
	var spans = document.getElementsByTagName("SPAN");
	for (var s = 0; s < spans.length; s++) 
	{
		if (spans[s].className == "pagetitle") 
		{
			pageId = psGetInnerText(spans[s]);
			psCreatePageviewTag(pageId, "My Gallery");
			psSetCookie(G_PS_COOKIE_CATID,"My Gallery");
			//post registration tags.
			if(psGetCookie(G_PS_FLAG_LOGIN) == "signed in")
			{
				var uP = new psProfile();
				uP.readProfile(); // get user profile from cookie
				// post registration tag for update profile page
				if(uP.email != null)
				{
					psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode);
					psSetCookie(G_PS_FLAG_LOGIN, "", "delete"); // turn off flag
				}
				else
				{
					psCreatePageviewTag("MyGallery:NullCustomerId","UnknownCategory");
				}
			}
			break;
		}
		else
		{
			psCreatePageviewTag("My Frame Shop Gallery", "My Gallery");
			psSetCookie(G_PS_COOKIE_CATID,"My Gallery");
			psHijackNewCustomerSignIn();
			psHijackCustomerSignIn();
			break;
		}
	}
}
// Editions-related pages
else if(document.title.toLowerCase() == "editions at pictureframes.com") 
{
	var pageId = "";
	if (document.body.innerHTML.search(/\/images\/pod2\/tabs\/image_on.gif/gi)>=0)
		pageId = "Image";
	else if (document.body.innerHTML.search(/\/images\/pod2\/tabs\/paper_on.gif/gi)>=0)
		pageId = "Paper";	
	else if (document.body.innerHTML.search(/\/images\/pod2\/tabs\/proofs_on.gif/gi)>=0)
		pageId = "Proofs";	
	else if (document.body.innerHTML.search(/\/images\/pod2\/tabs\/editions_on.gif/gi)>=0)
		pageId = "Editions";	
	else if (document.body.innerHTML.search(/\/images\/pod2_head.jpg/gi)>=0)
		pageId = "Upload my picture";
	// Post pageview tag
	psCreatePageviewTag(pageId, "Personal Frame Shop");
	psSetCookie(G_PS_COOKIE_CATID,"Personal Frame Shop");
		
}
else if(G_PS_PATHNAME.indexOf("/wa/frameshop") > -1)
{
	psCreatePageviewTag("Personal Frame Shop","Personal Frame Shop",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Personal Frame Shop");
}
else if(G_PS_PATHNAME.indexOf("/wa/viewlarge") > -1)
{
	if(psGetValueFromUrl(G_PS_URL_PATH,"sku") != null)
		psCreatePageviewTag("View Larger Image:" + psGetValueFromUrl(G_PS_URL_PATH,"sku"),psGetCookie(G_PS_COOKIE_CATID),null,null);
	else 
		psCreatePageviewTag("View Larger Image",psGetCookie(G_PS_COOKIE_CATID),null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/cmfaqs.html") > -1)
{
	psCreatePageviewTag("cmfaqs","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/customer_service.html") > -1)
{
	psCreatePageviewTag("Customer Service","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/pictureframeshome.html") > -1)
{
	psCreatePageviewTag("Picture Frame Shome","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/qdreadymades.html") > -1)
{
	psCreatePageviewTag("QdReadyMades","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/schoolmat.html") > -1)
{
	psCreatePageviewTag("School Mat","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/measure.html") > -1)
{
	psCreatePageviewTag("How to Size Your Custom Mat","Matting and Accessories",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/beginner.html") > -1)
{
	psCreatePageviewTag("Beginner","Matting and Accessories",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/matselection") > -1)
{
	psCreatePageviewTag("Select the Mat Color","Matting and Accessories",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/readysize") > -1)
{
	psCreatePageviewTag("Ready Size","Ready-Made Frames",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/readycolor") > -1)
{
	psCreatePageviewTag("Ready Color","Ready-Made Frames",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/viewprofile.html") > -1)
{
	if(sku != null)	
		psCreatePageviewTag(sku + " Profile" ,"View Profile",null,null);
	else 
		psCreatePageviewTag("View Profile" ,"View Profile",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/beginner.html") > -1)
{
	psCreatePageviewTag("Beginner","Matting and Accessories",null,null);
}
else if(document.title.toLowerCase() == "printable picture")
{
	psCreatePageviewTag("Printable Picture","Personal Frame Shop",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/frameshop/wallcolors") > -1)
{
	psCreatePageviewTag("Wall Colors","Personal Frame Shop",null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/viewprofile.html") > -1)
{
	if(sku != null)	
		psCreatePageviewTag(sku + " Profile" ,"View Profile",null,null);
}

else if(G_PS_PATHNAME.indexOf("/html/specialty_mats.html") > -1)
{
	psCreatePageviewTag("Select the Mat window","Matting and Accessories",null,null);
}

else if(G_PS_PATHNAME.indexOf("/wa/addtofavorites") > -1)
{
	psCreatePageviewTag("Add To Favorites:" + psGetValueFromUrl(G_PS_URL_PATH,"sku"),psGetCookie(G_PS_COOKIE_CATID),null,null);
}
else if(G_PS_PATHNAME.indexOf("/html/rabbet.html") > -1)
{
	psCreatePageviewTag("Rabbet", "Rabbet",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/print_frame") > -1)
{
	psCreatePageviewTag("Print & Frame Shop","Print & Frame Shop",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Print & Frame Shop");
}
else if(G_PS_PATHNAME.indexOf("/html/cornersetkits.html") > -1)
{
	psCreatePageviewTag("Corner Set Kits","Matting and Accessories",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Matting and Accessories");
}

/*
 * Great Ways to Shop by "CustomQuickShop"0.9.5.1.3.5
*/
else if(psIsCustomQuickShop())
{
	psCreatePageviewTag("Custom Quick Shop","Custom Quick Shop",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Custom Quick Shop");
	psHijackCustomQuickShop();
}
else if(G_PS_PATHNAME == "/html/business.html"
	||G_PS_PATHNAME == "/html/framers_corner.html")
{
	var pCatId = psGetCatFromBreadCrumb();
	psCreatePageviewTag(pCatId,pCatId,null,null);
	psSetCookie(G_PS_COOKIE_CATID,pCatId);
}
else if(G_PS_PATHNAME == "/html/accessories.html")
{
	psCreatePageviewTag("Matting and Accessories","Matting and Accessories",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Matting and Accessories");
}
else if(G_PS_PATHNAME == "/html/help.html"
	|| G_PS_PATHNAME == "/html/all-news.html"
	|| G_PS_PATHNAME == "/html/fc-history.html"
	)
{
	psCreatePageviewTag(psGetPageIdFromTitle(),"Home",null,null);
}

else if(G_PS_PATHNAME.indexOf("/wa/framedmirrors") > -1)
{
	psCreatePageviewTag("Mirror Size","MirrorShop",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"MirrorShop");
}
else if(G_PS_PATHNAME.indexOf("/wa/prophoto") > -1)
{
	psCreatePageviewTag("ProPhoto","ProPhotop",null,null);
}
/*
 * Post pageview tags for content of "Print & Frame" tab. 
*/
else if(G_PS_PATHNAME == "/html/stepone.html")
{
	psCreatePageviewTag("Upload Your Photo or Digital Image","Print & Frame",null,null);
}
/*
 * Post pageview tags for 4 sub tab:Image, Matting, Frame, Framing Kit
*/
else if(psIsPersonalFramePage())
{
	psPost5Frame();
}
/*
 * Post search tags.
*/
else if(G_PS_URL_PATH.toLowerCase().indexOf("search.pictureframes.com") > -1)
{	
	if(psGetValueFromUrl(G_PS_URL_PATH.toLowerCase(),"wosubmitaction").indexOf("search") > -1)
	{
		psPostSearchTag();
	}
}
else if(psIsBrowseSearch())
{
	var pPageId = psCleanHtmlTag(psGetElementValueById("rmResultsMessage_spSearchPath_lblLastEntry"));
	psCreatePageviewTag(psTrim(pPageId),"Pre-Directed Search",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Pre-Directed Search");
}
else if(psIsProductDetailPage()|| psIsOutlestProduct())
{
	psPostProductView();
    psHijackOrderLinks();
}
/*
 * Great Ways to Shop
*/
else if(G_PS_PATHNAME.indexOf("/wa/custommat") > -1)
{
	psCreatePageviewTag("Custom Matting", "Matting and Accessories",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Matting and Accessories");
	psHijackOrderLinks();
}
else if(G_PS_PATHNAME.indexOf("/wa/bulkmat") > -1)
{
	psCreatePageviewTag("Bulk Matting", "Matting and Accessories",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Matting and Accessories");
	psHijackOrderLinks();
}
/*
 * Post shop5
*/
else if(psIsShoppingCart())
{
	//comment out all SC and checkout calls, client will be manually tagging shopping cart and checkout process. -CER
	//psCreatePageviewTag("ViewCart","Cart",null,null);
	//psPostCartView();
	//psHijackSecureCheckout();
}

/*
 * Step 2: Shipping Method and Credit Card    
*/
else if(psIsShippingPage())
{
	//comment out all SC and checkout calls, client will be manually tagging shopping cart and checkout process. -CER
	//psCreatePageviewTag("Shipping address","checkout",null,null);
	//psPostPaymentRegistration();
}
else if(psIsBillingPage())
{
	//comment out all SC and checkout calls, client will be manually tagging shopping cart and checkout process. -CER
	/*
	psCreatePageviewTag("Billing address","checkout",null,null);
	if(G_PS_URL_REFERRER.indexOf("/wa/checkout") > -1 && psGetCookie(G_PS_FLAG_LOGIN) == "signed in")
	{
		var uP = new psProfile();
		uP.readProfile(); // get user profile from cookie
		// post registration tag for update profile page
		if(uP.email != null)
		{
			psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode);
			psSetCookie(G_PS_FLAG_LOGIN, '', "delete"); // turn off flag
		}
		else
		{
			psCreatePageviewTag("Billing:NullCustomerId","UnknownCategory");
		}
	}
	*/
}
/*
 * Step 3: Confirm order.
*/
else if(psIsConfirmOrder())
{
	//comment out all SC and checkout calls, client will be manually tagging shopping cart and checkout process. -CER
	//psCreatePageviewTag("Confirm order","checkout",null,null);
	//psSetOrderToCookie();
}
else if(G_PS_PATHNAME.indexOf("wa/thankyoupage") > -1)
{
	//comment out all SC and checkout calls, client will be manually tagging shopping cart and checkout process. -CER
	/*
	if(psOrderError())
	{
		psCreatePageviewTag("Thank you","checkout",null,null);
		psPostOrderView();
	}
	else
	{
		psCreatePageviewTag("Sorry","checkout",null,null);
	}
	*/
}
/*
 *Login page, save profile information to cookie.
*/
else if(psIsMyAccountPage())
{
	psCreatePageviewTag("Account Manager","Account",null,null);
	psHijackCustomerSignIn();
	psHijackNewCustomerSignIn();
	psHijackUpdateProfile();
}
/*
* flow when user select a product from rainbow,....
*/
else if(G_PS_URL_PATH.indexOf("/addToCart?sku") > -1)
{
	var pSku = psGetValueFromUrl(G_PS_URL_PATH,"sku");
	var pCatId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase())!= null?psGetValueFromCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase()):"Home";
	psCreatePageviewTag("Select a Frame Package Option",pCatId,null,null);
}
else if(psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo") && document.body.innerHTML.search(/1. Select your Frame Size/gi)>=0)
{
	psCreatePageviewTag("Select your Frame Size","Select your Frame Size",null,null);
}
else if(psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo") && document.body.innerHTML.search(/Select your Matting Options/gi)>=0)
{
	psCreatePageviewTag("Select your Matting Options","Select your Matting Options",null,null);
}
else if(psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo") && document.body.innerHTML.search(/Subtotal for your Frame Package/gi)>=0)
{
	psCreatePageviewTag("Subtotal for your Frame Package","Subtotal for your Frame Package",null,null);
}
/*
 * sign in when user check out.
*/
else if(G_PS_PATHNAME.indexOf("/wa/checkout") > -1)
{
	psCreatePageviewTag("Check out","Account",null,null);
	psHijackCustomerSignIn();
	psHijackNewCustomerSignIn()
}

else if(G_PS_PATHNAME == "/html/browse-picture-frames-selection.html"
		||G_PS_PATHNAME == "/html/contact.html"
		||G_PS_PATHNAME == "/html/copyright.html"
		||G_PS_PATHNAME == "/html/privacy.html"
		||G_PS_PATHNAME == "/html/web-specials.html")
{
	psCreatePageviewTag(psGetFileNameAsPageId(),"Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/requestcatalog") > -1)
{
	psCreatePageviewTag("requestcatalog","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/wa/editiongallery") > -1)
{
	psCreatePageviewTag("Edition Gallery","Frame shop gallery",null,null);
}
else if(psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo") && psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo").indexOf("0.9.5.3.1.3") > -1)
{
	psCreatePageviewTag("Print and Frame Gallery","Frame shop gallery",null,null);
}
else if(G_PS_PATHNAME.indexOf("/mirrorshop/faqs.html") > -1)
{
	psCreatePageviewTag("faqs","Home",null,null);
}
else if(G_PS_PATHNAME.indexOf("/editions/") > -1)
{	
	psCreatePageviewTag(psGetFileNameAsPageId(),"Home",null,null);
}
/*
 * Post pageview tags for content page and set catid to cookie
*/
else if(psIsContentPages())
{
	/*
	 * Post page view for these pages have format url /html/
	 * select id from breadcrumbs to avoid the same pageid.
	*/
	var pCatId = psGetCatFromBreadCrumb();
	if(G_PS_PATHNAME.indexOf("/html/") > -1)
	{
		psCreatePageviewTag(psGetPageIdFromBreadCrumb(),pCatId,null,null);
	}
	/*
	* Is browse pages
	* /wa/CustomCollection?sec=.....&browse=.....
	* /wa/ReadyCollection?sec=.....&browse=.....
	* /wa/MetalCollection?sec=.....&browse=.....
	* and other.
	*/
	else 
	{
		psCreatePageviewTag(psGetPageIdFromTitle(),pCatId);
	}
	psSetCookie(G_PS_COOKIE_CATID,pCatId);
	psHijackOrderButtons();
	psHijackOrderLinks();
	psHijackMetalOrder();
	psHijackOutletShop();
}
else if(G_PS_PATHNAME.indexOf("/wa/editionhome") > -1
	||G_PS_PATHNAME.indexOf("/wa/custommade") > -1
	||G_PS_PATHNAME.indexOf("/wa/readymade") > -1
	||G_PS_PATHNAME.indexOf("/wa/metal") > -1
	||G_PS_PATHNAME.indexOf("/wa/webspecials") >-1
	||G_PS_PATHNAME.indexOf("/outletshop/main.html") > -1)
{
	var pCatId = psGetCatFromBreadCrumb();
	psCreatePageviewTag(pCatId,pCatId,null,null);
	psSetCookie(G_PS_COOKIE_CATID,pCatId);
}
else 
{
	psCreatePageviewTag(G_PS_PATHNAME, "ADD URL");
}

function psGetFileNameAsPageId()
{
	return G_PS_PATHNAME.substring(G_PS_PATHNAME.lastIndexOf("/")+1, G_PS_PATHNAME.lastIndexOf("."));
}		

/*
 * Return true if the page is product detail page.
*/
function psIsProductDetailPage()
{
	var result = false;
	var pBrowser = psGetValueFromUrlFriendly(G_PS_PATHNAME,"wa");
	if(pBrowser == "readycollection" || pBrowser == "customcollection" || pBrowser == "metalcollection")
	{
		if(psGetValueFromUrl(G_PS_URL_PATH,"sku"))
			result = true;
	}
	return result;
}
/*
* Get pageid form "titleBox"
*/
function psGetPageIdFromTitle()
{
	var pPageId = psGetElementValueById("titleBox");
	return pPageId != null?psTrim(psCleanHtmlTag(pPageId)):null;
}
/*
 * Check is content pages.	
 * Return true if page exist "titleBox" id.
*/
function psIsContentPages()
{
	return psGetElementValueById("titleBox") != null? true:false;
}
/* 
 * Get value from the BreadCrumb
 */
function psGetCatFromBreadCrumb()
{
	var result = null;	
	var BreadCrumb = psGetElementValueById("subHeader");
	if (BreadCrumb) 
	{
		BreadCrumb = psHtmlDecode(BreadCrumb.toLowerCase());
		var arrBreadCrumb = BreadCrumb.split("</a>");
		result = psTrim(psCleanHtmlTag(arrBreadCrumb[1]));
	}
	else if(psGetElementsByClassName(document,"td","breadcrumbs"))
	{
		BreadCrumb = psGetElementsByClassName(document,"td","breadcrumbs")[0];
		if(BreadCrumb)
		{
			BreadCrumb = psHtmlDecode(BreadCrumb.innerHTML.toLowerCase());
			var arrBreadCrumb = BreadCrumb.split("</a>");
			result = psTrim(psCleanHtmlTag(arrBreadCrumb[1]));
		}
	}
	return result != null? result.replace('>','').replace('&',"and"): null;
}
/* 
 * Get value from the BreadCrumb
 */
function psGetPageIdFromBreadCrumb()
{
	var result = null;
	var BreadCrumb =  psGetElementValueById("subHeader");
	if(BreadCrumb)
	{
		if (BreadCrumb.search(/Framer\'s Corner/) >= 0) 
		{
			if (G_PS_PATHNAME == "/html/framers_corner.html") 
				result = "Framer Corner";
			else 
				if (document.body.innerHTML.search(/h2/gi) >= 0) 
				{
					result = psGetInnerText(document.getElementsByTagName("h2")[0]);
				}
		}
		else 
		{
			BreadCrumb = psHtmlDecode(BreadCrumb.toLowerCase());
			var arrBreadCrumb = BreadCrumb.split("</a>");
			result = psCleanHtmlTag(arrBreadCrumb[arrBreadCrumb.length - 1]);
		}
	}
	return psTrim(result.replace('>',''));
}
/*
 * Get value from friendly url.
*/
function psGetValueFromUrlFriendly(pUrl, pKey)
{
    var st = pKey + "/";
    if (typeof(pUrl.split(st)[1]) != "undefined")
    {
        return  pUrl.split(st)[1].split("/")[0];
    } 
	else 
    {
        return null;
    }
}
/*
 * Post Image, Matting, Frame, Framing Kit pageview
*/
function psPost5Frame()
{
	var pForms = document.getElementsByTagName("form");
	for (var i=0; i<pForms.length; i++)	
    {
		var pForm = pForms[i];
        if (pForm.getAttribute("name") && pForm.getAttribute("name").toLowerCase() == "pfsmainform")
		{		
			var pUrl = pForm.getAttribute("action");
			var pWo = psGetValueFromUrlFriendly(pUrl.toLowerCase(), "wo");
			if(psGetCookie(G_PS_COOKIE_CATID) == "Personal Frame Shop")
			{
				if(pWo.indexOf("9.5.1.3.0.0") > -1)
					psCreatePageviewTag("Framing Kit", "Personal Frame Shop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.1.1.0") > -1)
					psCreatePageviewTag("Image", "Personal Frame Shop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.1.0") > -1)
					psCreatePageviewTag("Matting", "Personal Frame Shop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.3.0") > -1)
					psCreatePageviewTag("Frame", "Personal Frame Shop",null,null);
			}
			else if(psGetCookie(G_PS_COOKIE_CATID) == "MirrorShop")
			{
				if(pWo.indexOf("0.9.5.1.3.1.0") > -1)
					psCreatePageviewTag("Mirror size", "MirrorShop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.3.0") > -1)
					psCreatePageviewTag("Frame", "MirrorShop",null,null);
			}
			if(psGetCookie(G_PS_COOKIE_CATID) == "Print & Frame Shop")
			{
				if(pWo.indexOf("9.5.1.3.0.0") > -1)
					psCreatePageviewTag("Paper", "Print & Frame Shop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.1.1.0") > -1)
					psCreatePageviewTag("Image", "Print & Frame Shop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.1.0") > -1)
					psCreatePageviewTag("Matting", "Print & Frame Shop",null,null);
				else if(pWo.indexOf("0.9.5.1.3.3.0") > -1)
					psCreatePageviewTag("Frame", "Print & Frame Shop",null,null);
			}
		}
	}
	
}
/*
 * http://www.pictureframes.com/scripts/WebObjects/PictureFrames.woa/wo/22.0.9.5.1.3.1.0
 * Check type url to post page view tag for 5 frame.
 * return true if the page has "wo" belong 5 values below.
*/
function psIsPersonalFramePage()
{
	var pResult = false;
	var pWo = psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo");
	if(pWo)
	{
		if(pWo.indexOf("0.9.5.1.3.1.1.0") > -1 ||pWo.indexOf("0.9.5.1.3.0.0") > -1
			||pWo.indexOf("0.9.5.1.3.1.0") > -1 || pWo.indexOf("0.9.5.3.1.3") > -1
			|| pWo.indexOf("0.9.5.1.3.3.0") > -1 )
			pResult = true;
	}
	return pResult;
}
/*
 * Check custom Quick shop
 * return true if the page is custom Quick shop
*/
function psIsCustomQuickShop()
{	
	var pResult = false;
	if(G_PS_PATHNAME.indexOf("/scripts/webobjects/pictureframes.woa/wa/customquickshop") > -1)
		pResult = true;
	else if(psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo") && psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo").indexOf("0.9.5.1.3.5") > -1 )
		pResult = true;
	return pResult;
}
/*
 * https://www.pictureframes.com/scripts/WebObjects/PictureFrames.woa/wo/0.0.9.7.3
 * Check type url to myaccount page.
 * return true if the page has "wo" belong 5 values below.
*/
function psIsMyAccountPage()
{
	var pResult = false;
	var pWo = psGetValueFromUrlFriendly(G_PS_PATHNAME, "wo");
	var pWa = psGetValueFromUrlFriendly(G_PS_PATHNAME, "wa");
	if(document.title.search(/PictureFrames.com - Account Manager/gi) > -1)
		pResult = true;
	else if(pWa && pWa.indexOf("myaccount")>-1)
		pResult = true;
	else if(pWo && pWo.indexOf("0.9.7.3") > -1)
		pResult = true;
	return pResult;
}

/* 
 * Find element by name
 */
function psGetElementsByClassName(psDocument, psElementTagName, psClassName)
{
    var arrResult = new Array();
    var index = 0;
    var arrInputs = psDocument.getElementsByTagName(psElementTagName);
    if(arrInputs == null)
    {
        return null;
    }
    for(var i = 0; i < arrInputs.length; i ++ )
    {
        if(arrInputs[i].className.toLowerCase() == psClassName)
        {
            arrResult[index ++ ] = arrInputs[i];
        }
    }
    return arrResult;
}
/*
 * Hijack order button for these pages have format url: "/html/"
 * Type input
*/ 
function psHijackOrderButtons()
{
	if(G_PS_PATHNAME != "/html/framingkits.html")
	{
		var allInputs = document.getElementsByTagName("input");
		for (var i=0; i<allInputs.length; i++)	
		{
			var items = allInputs[i];
			if (items.getAttribute("type") == "image" && items.getAttribute("src").search(/images\/order2\.gif/i) > -1)
			{
				var oldCMFunc = items.onclick; //backup the existing onclick function
				items.onclick = function()
				{
					var pTr = this.parentNode.parentNode.parentNode;
					if(pTr)
					{
						var pSelect = pTr.getElementsByTagName("select");
						var pSku="";
						for(var j = 0; j < pSelect.length;j++)
						{
							if(pSelect[j].options[pSelect[j].selectedIndex].value != "none")
								pSku += pSelect[j].options[pSelect[j].selectedIndex].value;
						}
						psSetValueToCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase(),psGetCookie(G_PS_COOKIE_CATID));
					}
					if (oldCMFunc != null)
					return oldCMFunc();
				}
			}
		}
	}
}

/* 
 * Hijack order button in outletshop.
*/ 
function psHijackOutletShop()
{
	var pLinks = document.links;
	for (var i = 0; i < pLinks.length; i++)	
    {
		if (pLinks[i].title.search(/Add to Cart/gi) > -1)
        {
			var oldCMFunc = pLinks[i].onclick; //backup the existing onclick function
			pLinks[i].onclick = function()
			{
				var pDiv = this.parentNode;
				if(pDiv)
				{
					var pSku = pDiv.getElementsByTagName("span")[0].innerHTML;
					pSku	= pSku.search(/([\d]*)\s/gi) > -1 ? psTrim(RegExp.$1) : null;
					pSku = "OL" + pSku;
					psSetValueToCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase(),psGetCookie(G_PS_COOKIE_CATID));
				}
				if (oldCMFunc != null)
					return oldCMFunc();
			}
		}
	}
}
/*
 * Hijack order button for these pages have format url: "/html/"
 * Type href
*/

function psHijackOrderLinks()
{
	var pLinks = document.links;
	for (var i = 0; i < pLinks.length; i++)	
    {
		var item = pLinks[i];
        if (item.href.toLowerCase().search(/\/wa\/addtocart/gi) > -1)
        {
			var oldCMFunc = item.onclick; //backup the existing onclick function
			item.onclick = function()
			{
                    
				var pSku = psGetValueFromUrl(this.href+"","sku");
				if(pSku)
				{
					psSetValueToCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase(),psGetCookie(G_PS_COOKIE_CATID));
				}
				if (oldCMFunc != null)
				return oldCMFunc();
			}
		}
	}
}

/*
 *http://www.pictureframes.com/html/archival-metal-photo-frames.html
 * metal-photo-frames 
*/
function psHijackMetalOrder()
{
	var allInputs = document.getElementsByTagName("input");
    for (var i=0; i<allInputs.length; i++)	
    {
        var items = allInputs[i];
        if (items.getAttribute("type") == "image" && items.getAttribute("src").search(/images\/orderNowRedArch\.gif/i) > -1)
        {
			var oldCMFunc = items.onclick; //backup the existing onclick function
            items.onclick = function()
            {
				var pForm = this.parentNode;
				if(pForm)
				{
					var pSubInput= document.getElementsByTagName("input");
					for (var j=0; j<pSubInput.length; i++)	
					{
						if(pSubInput[j].name = "sku")
						{
							var pSku = pSubInput[j].value;
							psSetValueToCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase(),psGetCookie(G_PS_COOKIE_CATID));
						}
					}
				}
				if (oldCMFunc != null)
					return oldCMFunc();
            }
        }
    }
}
/*
 * Hijack CustomQuickShop
*/
function psHijackCustomQuickShop()
{
	var allInputs = document.getElementsByTagName("input");
    for (var i=0; i<allInputs.length; i++)	
    {
        var items = allInputs[i];
        if (items.getAttribute("type") == "submit" && items.getAttribute("value").indexOf("Add To Cart") > -1)
        {
			var oldCMFunc = items.onclick; //backup the existing onclick function
            items.onclick = function()
            {
				var pSelect = document.getElementsByName("0.9.5.1.3.5.2")[0];
				var	pProduct = pSelect.options[pSelect.selectedIndex].innerHTML;
				var pSku = pProduct.search(/#\s([\S]*)/gi) > -1 ? psTrim(RegExp.$1) : null;
				psSetValueToCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase(),psGetCookie(G_PS_COOKIE_CATID));
            }
			if (oldCMFunc != null)
				return oldCMFunc();
        }
    }
}

/*
 * Get result & search term for search page
*/
function psPostSearchTag()
{
	var pTerm = psGetValueFromUrl(G_PS_URL_PATH.toLowerCase(),"search");
	var pResult = 0;
	//search unsuccessful
	if(psGetElementValueById("pageBody").toLowerCase().indexOf("did not match any of the products we carry") > -1) 
	{
		psCreatePageviewTag("SEARCH UNSUCCESSFUL","SEARCH",pTerm,pResult);
	}
	//search successfully
	else
	{
		//get result
		var pTable = document.getElementById("topTable");
		var pPage = 0;
		if(pTable)
		{
			pResult = pTable.rows[0].cells[0].getElementsByTagName('b')[0].innerHTML;
		}
		//get search term
		var pDiv = document.getElementById("NavBar1_Panel1");
		if(pDiv)
		{
			var pLinks = pDiv.getElementsByTagName('a');
			for (var i = 0; i < pLinks.length; i++)	
			{
				if (pLinks[i].href == "")
				{
					pPage = pLinks[i].innerHTML;
				}		
			}
		}	
		psCreatePageviewTag("SEARCH SUCCESSFUL PAGE " + pPage,"SEARCH",pTerm,pResult);
	}
	psSetCookie(G_PS_COOKIE_CATID,"SEARCH");
}
/*
 * function check for these catalogs page have same content as searchResults.
 * return true if the page is browse search;
*/
function psIsBrowseSearch()
{
	var pResult = false;
	if(psGetPageIdFromTitle() && psGetPageIdFromTitle().toLowerCase() == "search results" &&
		psGetValueFromUrl(G_PS_URL_PATH.toLowerCase(),"wosubmitaction") == null)
	{
		pResult = true;
	}
	return pResult;
}
/* 
 * Hijack "sign in" button when customer login.
 */
function psHijackCustomerSignIn()
{
	console.log("psHijackCustomerSignIn");
	var pInputs = document.getElementsByTagName("input");
	for (var i = 0; i < pInputs.length; i++)	
    {
        if (pInputs[i].value.toLowerCase() == "sign   in")
        {
		console.log("psHijackCustomerSignIn.firstIf");
			var oldCMFunc = pInputs[i].onclick; //backup the existing onclick function
			pInputs[i].onclick = function()
			{
				console.log("psHijackCustomerSignIn.OnClick");
				var uP = new psProfile();
				uP.email = psTrim(document.getElementsByName("0.9.7.3.3")[0].value);
				uP.city = null;

				uP.state = null;
				uP.zipcode = null
				// store on cookie
				psSetCookie(G_PS_FLAG_LOGIN, "signed in");
				console.log("psHijackCustomerSignIn.calling.writeProfile");
				uP.writeProfile();
			}
			if (oldCMFunc != null)
				return oldCMFunc();
		}
	}
}
/* 
 * Hijack "sign in" button when customer login.
 */
function psHijackUpdateProfile()
{
	console.log("psHijackUpdateProfile");
	var pInputs = document.getElementsByTagName("input");
	for (var i = 0; i < pInputs.length; i++)	
    {
        if (pInputs[i].value.toLowerCase() == "update")
        {
			var oldCMFunc = pInputs[i].onclick; //backup the existing onclick function
			pInputs[i].onclick = function()
			{
				var uP = new psProfile();
				uP.email = psTrim(document.getElementsByName("0.9.5.1.3.1.5")[0].value);
				uP.city = null;
				uP.state = null;
				uP.zipcode = null;
				// store on cookie
				//psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode);
				psSetCookie(G_PS_FLAG_LOGIN, "updated");
				uP.writeProfile();
			}
			if (oldCMFunc != null)
				return oldCMFunc();
		}
	}
}

/* 
 * Hijack "sign in" button when new customer login.
 */
function psHijackNewCustomerSignIn()
{
	console.log("psHijackNewCustomerSignin");
	var pInputs = document.getElementsByTagName("input");
	for (var i = 0; i < pInputs.length; i++)	
    {
        if (psHtmlDecode(pInputs[i].value.toLowerCase()) == "create & sign in")
        {
			var oldCMFunc = pInputs[i].onclick; //backup the existing onclick function
			pInputs[i].onclick = function()
			{
				var uP = new psProfile();
				uP.email = psTrim(document.getElementsByName("0.9.7.5.1.7")[0].value);
				uP.city = null;
				uP.state = null;
				uP.zipcode = null;
				// store on cookie
				psSetCookie(G_PS_FLAG_LOGIN, "signed in");
				uP.writeProfile();
			}
			if (oldCMFunc != null)
				return oldCMFunc();
		}
	}    
}
/*
 * Check user sign in successful
 * post registration tag if user login successful.
*/
function psSignInSuccess()
{
	var pLogOut = psGetElementsByClassName(document,"a","whitelink");
	if(pLogOut)
	{
		for (var i = 0; i < pLogOut.length; i++)	
		{
			if (psHtmlDecode(pLogOut[i].innerHTML.toLowerCase()) == "log out")
			{
				if(psGetCookie(G_PS_FLAG_LOGIN) == "signed in" ||psGetCookie(G_PS_FLAG_LOGIN) == "updated")
				{
					var uP = new psProfile();
					uP.readProfile(); // get user profile from cookie
					// post registration tag for update profile page
					if(uP.email != null)
					{
						psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode);
						psSetCookie(G_PS_FLAG_LOGIN, '', "delete"); // turn off flag
					}
					else
					{
						psCreatePageviewTag("SignedIn:NullCustomerId","UnknownCategory");
					}
				}
			}
		} 
	}
}
/*
 * Check shipping page.
 * return true if the page is shipping Step.
*/
function psIsShippingPage()
{
	var pResult = false;
	pContinue = document.getElementsByName("0.9.5.1.3.1.6.4.1.14");
	if(pContinue)
	{
		pResult = pContinue[0] != null? true:false;
	}
	return pResult
}
/*
 * Check shipping page.
 * return true if the page is shipping Step.
*/
function psIsBillingPage()
{
	var pResult = false;
	pUseAddress = document.getElementsByName("0.9.5.1.3.1.3.5.1.1.0.1.0.1.1.0.1.0.3");
	pNewAddress = document.getElementsByName("0.9.5.1.3.1.3.8.35");
	if(pUseAddress.length > 0 || pNewAddress.length > 0)
	{
		pResult = true;
	}
	return pResult
}
/*
 * Check shopping cart page.
 * return true if the page is viewcart step.
*/
function psIsShoppingCart()
{
	var result = (G_PS_PATHNAME.search(/\/viewCart/gi)>=0);
	result = result || (document.body.innerHTML.search(/<b>Your Shopping Cart<\/b>/gi)>=0);
	return result;
}
/*
 * confirm order page.
 * return true if the page is confirm order step.
*/
function psIsConfirmOrder()
{
	//|| G_PS_PATHNAME == "/scripts/webobjects/pictureframes.woa/wa/viewcart"
	//		||G_PS_PATHNAME == "/scripts/webobjects/pictureframes.woa/wa/addtocart"
	var pResult = false;
	pContinue = document.getElementsByName("0.9.5.1.3.1.6.4.4.46");
	if(pContinue)
	{
		pResult = pContinue[0] != null? true:false;
	}
	return pResult
}
/* 
 * Post registration tag again when user changed billing address.
*/
function psPostPaymentRegistration()
{
	console.log("psPostPaymentRegistration");
	var uP = new psProfile();
	uP.readProfile(); // get user profile from cookie
	if(uP.email != null)
	{
		console.log("psPostPaymentRegistration.foundEmail");
		var pEdit = document.getElementsByName("0.9.5.1.3.1.40.3.0");
		if(pEdit)
		{
			var pTable = pEdit[0].parentNode.parentNode.parentNode.parentNode;
			var pAddress = pTable.rows[0].cells[0].innerHTML;
			var lstBr = pAddress.toLowerCase().split("<br");
			pAddress = psTrim(lstBr[lstBr.length-2]);
			uP.city = pAddress.search(/>(.*)\,(\D*)(\d*)/gi) > -1 ? psTrim(RegExp.$1) : null;
			uP.city = psCleanHtmlTag(uP.city);
			uP.state = pAddress.search(/>(.*)\,(\D*)(\d*)/gi) > -1 ? psTrim(RegExp.$2) : null;
			uP.state = psCleanHtmlTag(uP.state);
			uP.zipcode = pAddress.search(/>(.*)\,(\D*)(\d*)/gi) > -1 ? psTrim(RegExp.$3) : null;
			psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode);
			// store on cookie
			uP.writeProfile();
		}
	}
	else
	{
		psCreatePageviewTag("Payment:NullCustomerId","UnknownCategory");
	}
}
/* 
 * Hijack "sign in" button when new customer login.
 */
function psHijackSecureCheckout()
{
	var pInputs = document.getElementsByTagName("input");
	for (var i = 0; i < pInputs.length; i++)	
    {
        if (psHtmlDecode(pInputs[i].value.toLowerCase()) == "secure checkout")
        {
			var oldCMFunc = pInputs[i].onclick; //backup the existing onclick function
			pInputs[i].onclick = function()
			{
				psPostCartView();
				if (oldCMFunc != null)
					return oldCMFunc();
			}
		}
	}    
}
/*
 * Set all informations of order tag to cookie.
*/
function psSetOrderToCookie()
{
	console.log("SetOrderToCookie");		
	var cusZip = null;
	var cusState = null;
	var cusCity = null;
	var cusId = null;
	pInput =  document.getElementsByName("sourceCodeField");
	pTable = pInput[0].parentNode.parentNode.parentNode.parentNode.parentNode.getElementsByTagName("table");
	if(pTable)
	{
		if(pTable[0].rows[pTable[0].rows.length - 1].cells[2])
		{
			var pSubtotal = psCleanHtmlTag(pTable[0].rows[pTable[0].rows.length - 1].cells[2].innerHTML);
			pSubtotal = psTrim(pSubtotal.replace("$",""));
		}
		if(pTable[0].rows[1].cells[2])
		{
			if(pTable[0].rows[1].cells[2].innerHTML.indexOf("...") > -1)
				var pShipping = 0;
			else
			{
				var pShipping = psCleanHtmlTag(pTable[0].rows[1].cells[2].innerHTML);
				pShipping = psTrim(pShipping.replace("$",""));
			}
		}
		else
		{
			var pSubtotal = 0;
			var pShipping = 0;
		}
	}
	var uP = new psProfile();
	uP.readProfile(); // get user profile from cookie
	console.log(uP.email);
	if(uP.email != null)
	{
		cusId = uP.email;
		cusZip = uP.zipcode;
		cusState = uP.state;
		cusCity = uP.city;
		var pValueOrder =  pSubtotal+ ":" + pShipping + ":" + cusCity + ":" + cusState + ":" + cusZip + ":" + cusId;					
		console.log(pValueOrder);
		psSetCookie(G_PS_COOKIE_ORDER,pValueOrder);	
	}
	else
	{
		psCreatePageviewTag("Order:NullCustomerId","UnknownCategory");
	}
}
function psOrderError()
{
	var pSuccess = true;
	var pImage = document.getElementsByTagName("img");
	for (var i = 0; i < pImage.length; i++)	
    {
        var items = pImage[i];
        if (items.getAttribute("src").search(/images\/sorry\.gif/gi) > -1)
        {
			pSuccess = false;
		}
	}    
	return pSuccess;
}
function psIsExpiredPage()
{
	var pResult = false;
	var pBodyText = document.getElementsByTagName("body")[0].innerHTML;
	var pExpired = pBodyText.toLowerCase().search(/(your session has expired)/gi) > -1 ? psTrim(RegExp.$1) : null;
	pResult = pExpired == "your session has expired"? true:false;
	return pResult;
}
/*
 *Check these product come back from shopping cart page.
*/
function psIsComeBackFromCart()
{
	var pResult = false;
	if(G_PS_URL_REFERRER.indexOf("/wa/viewcart") > -1
		||G_PS_URL_REFERRER.indexOf("/wa/addtocart") > -1)
		pResult = true;
	return pResult;

			
}
/*
 * Check custom product: B&W photo,color....
*/
function psIsCustomProduct(pName)
{
	var pResult = false;
	var pCheck = pName.search(/(.*)\s\-\s(Frame Package)/gi);
	if(psTrim(RegExp.$2) == "Frame Package")
		pResult = true;
	return pResult;
}
function psIsOutlestProduct()
{
	var pResult = false;
	var pCount = 0;
	if(G_PS_PATHNAME.indexOf("/outletshop/") > -1)
	{
		psSetCookie(G_PS_COOKIE_CATID,psGetCatFromBreadCrumb());
		var pLinks = document.links;
		for (var i = 0; i < pLinks.length; i++)	
		{
			var item = pLinks[i];
			if (item.href.toLowerCase().search(/\/wa\/addtocart\?sku/gi) > -1)
			{
				pCount++;
			}
		}
	}
	if(pCount == 1)
		pResult = true;
	return pResult;
}
function psIsFramingKitsProduct(pName)
{
	var pResult = false;	
	pName = psTrim(pName);
	if(pName.toLowerCase().indexOf("economy framing kit") > -1
	  ||pName.toLowerCase().indexOf("classic framing kit") > -1
	  ||pName.toLowerCase().indexOf("non-glare framing kit") > -1
	  ||pName.toLowerCase().indexOf("nonglare framing kit") > -1
	  ||pName.toLowerCase().indexOf("premium archival framing kit") > -1
	  ||pName.toLowerCase().indexOf("sample corner set") > -1)
	{
		pResult = true;
	}
	return pResult;

}
function psHijackAddBoxesToCart()
{
	var pInputs = document.getElementsByTagName("input");
	for (var i = 0; i < pInputs.length; i++)	
    {
        if (pInputs[i].getAttribute("type") == "submit" && pInputs[i].getAttribute("value").indexOf("Add box(es) to cart") > -1 )
        {
			var oldCMFunc = pInputs[i].onclick; //backup the existing onclick function
			pInputs[i].onclick = function()
			{
				psSetBoxesToCookie();
			}
		}
	}
}
function psSetBoxesToCookie()
{
	var pProInputs = document.getElementsByTagName("input");
	for (var j = 0; j < pProInputs.length; j++)	
    {
        if(pProInputs[j].getAttribute("type") == "text" && pProInputs[j].getAttribute("value") > 0 )
        {
			var pTable = pProInputs[j].parentNode.parentNode.parentNode.parentNode;
			if(pTable.rows.length > 0)
			{
				var pImages = pTable.rows[0].cells[0].getElementsByTagName("img");
				if(pImages)
				{
					var pArr = pImages[0].src.split("/");
					var pSku = pArr[pArr.length-1];
					pSku = pSku.search(/([^.]*)\.gif$/gi) > -1 ? psTrim(RegExp.$1): null;
					psSetValueToCookie(G_PS_COOKIE_PROD_CATID,pSku.toLowerCase(),"Matting and Accessories");
				}
			}
		}
	}  
}
/*============================ END NAVIGATION ================================*/


/*===================== BEGIN TAGGING BUSSINESS LOGIC ========================*/
/*
 * Process to post productview tag for the item in product detail
 */
function psPostProductView()
{
	var prd = new psProduct();
	prd.getProduct();
	// Post product view tag
	psCreateProductviewTag(prd.id, prd.id, prd.catId);
	// Store productId along with catId to cookie for use later in shop5 and shop9 views
	psSetCookie(G_PS_COOKIE_CATID,prd.catId)
	psSetValueToCookie(G_PS_COOKIE_PROD_CATID, prd.id.toLowerCase(), prd.catId);
}

/*
 * Process to post shop5tags for items in shopping cart
 */
function psPostCartView()
{
	/*
	 * Codes for posting pageview
	 * For instance: cmCreatePageviewTag("Trivita:ViewCart", "Trivita:Shop", null);
	 */
	var cartTbl = null;
	var index=0;
	var pProId_tr="";
	//var cartTbl = document.getElementsByTagName("table");
	
	cartTbl = document.getElementById("cartTable");
	
	//console.log("test");

	/*
	if (cartTbl.length < 10)
		return;
	*/
	psSetCookie(G_PS_COOKIE_SHOP9, "", "delete");
    psSetCookie(G_PS_COOKIE_ORDER, "", "delete");	
	//
	// Iterate to throw shop5 tags
	//cartTbl = cartTbl[9];
	/*
	 * Codes for locating the table containing items (each row for an item)
	 */
	if(cartTbl)
	{
		var rows = cartTbl.rows; // use rows variable for optimization
		var prd = new psProduct();
	//	console.log(rows.length);
		for (var r = 1; r < rows.length - 1; r++) // item for each row
		{
			/*
			 * Codes for skipping exceptional rows (rows don't contain items)
			 */
			//console.log(rows[r]);
			prd.getItem5(rows[r]);
			// Post shop5tag
			//console.log(prd);
			if(prd.quantity != 0 || prd.quantity != "0")
			{
				psCreateShopAction5Tag(prd.id, prd.name, prd.quantity, prd.price, prd.catId);
				if(psIsCustomProduct(prd.name) || psIsFramingKitsProduct(prd.name))
				{
					var pValueShop9 = prd.catId + "|" +  prd.name + "|" + prd.quantity +"|" + prd.price.replace("$","") + "|" + prd.catId;				
					var pProdId = prd.catId + "_" + index;
					pProId_tr+=pProdId + "--";
				}
				else
				{
					var pValueShop9 =prd.id + "|" +  prd.name + "|" + prd.quantity +"|" + prd.price.replace("$","") + "|" + prd.catId;				
					var pProdId = prd.id + "_" + index;
					pProId_tr+=pProdId + "--";
				}
				console.log(pProdId);
				console.log(pValueShop9);
				psSetValueToCookie(G_PS_COOKIE_SHOP9,pProdId,pValueShop9); 
				index+=1;
			}
		}
		// Make sure to have actual postings
		//console.log(pProId_tr);
		psSetValueToCookie(G_PS_COOKIE_PRODID,"ProLst",pProId_tr);
		// Make sure to have actual postings
			psDisplayShop5s();
	}
}
/*
 * Process to post shop9tags for items purchased
 */
function psPostOrderView()
{
	//console.log("psPostOrderView");
	var ord = new psOrder();
	var prd = new psProduct();
	ord.getOrder(); // Get order info from source code
	// Post Pageviewtag as cartview
	var strProductId = psGetValueFromCookie(G_PS_COOKIE_PRODID,"ProLst");
	var arrProduct = strProductId.split("--");
	for(var i=0; i<=arrProduct.length;i++)
	{
		if (arrProduct[i]!=null && arrProduct[i]!="")
		{
			prd.getItem9(arrProduct[i]);
			// Post shop9tag
			console.log(prd.name);
			psCreateShopAction9Tag(prd.id, prd.name, prd.quantity, prd.price, ord.cusId, ord.id, ord.subtotal, prd.catId);
		}
	}
	// Make sure to have actual postings
	psDisplayShop9s();
	// Post order tag finally
	if(ord.cusId != null)
		psCreateOrderTag(ord.id, ord.subtotal, ord.shipping, ord.cusId, ord.cusCity, ord.cusState, ord.cusZIP);
	else 
		psCreatePageviewTag("PostOrder:NullCustomerId","UnknownCategory");
	// Delete cookie after checking successfully
	psSetCookie(G_PS_COOKIE_PROD_CATID,"", "delete");	
	psSetCookie(G_PS_COOKIE_PRODID,"", "delete"); 
	psSetCookie(G_PS_COOKIE_SHOP9,"", "delete");	
	psSetCookie(G_PS_COOKIE_ORDER,"", "delete");		
}


/*====================== END TAGGING BUSSINESS LOGIC =========================*/


/*======================= GENERAL UTILITY FUNCTION ===========================*/
/* PURPOSE: constructor for product
 * Note: you can add more methods to psProduct in its prototype
 * RETURN: none
 */
function psProduct(pId, pName, pCatId, pPrice, pQuantity)
{
    this.id = pId;
    this.name = pName;
    this.catId = pCatId;
    this.price = pPrice;
    this.quantity = pQuantity;
	/*
	 * Extracting product info from source code for posting productview tag
	 */
	this.getProduct = function()
	{
		this.id = psGetValueFromUrl(G_PS_URL_PATH,"sku");
		if(this.id != null)
		{
			//this.name = psGetValueFromUrl(G_PS_URL_PATH,"sec").replace(/\+/gi, "");
			// it's false for format " sec=...."
			this.name = G_PS_URL_PATH.search(/sec=([^&]*)/gi) > -1 ? RegExp.$1 : null;
			this.name = this.name.replace(/[\+,\%20]+/gi, " ");
		}
		//is product view from outletshop.
		else 
		{
            this.id = psGetPageIdFromBreadCrumb();
			var pSpan = document.getElementById("frameTitleTable").rows[0].cells[0].getElementsByTagName("h2")[0];
            var reg = new RegExp("^" + this.id + "\\s", "gi");
            pSpan = psCleanHtmlTag(pSpan.innerHTML).replace(reg, "");
			this.name = psTrim(psHtmlDecode(pSpan));
		}
		if(psIsComeBackFromCart() && psGetValueFromCookie(G_PS_COOKIE_PROD_CATID,this.id.toLowerCase()) != null)
			this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID,this.id.toLowerCase());
		else if(psGetCookie(G_PS_COOKIE_CATID))
		{
			this.catId = psGetCookie(G_PS_COOKIE_CATID)!= null?psGetCookie(G_PS_COOKIE_CATID):"BOOKMARK";
			this.catId = (this.catId != null) ? this.catId : "BOOKMARK";
		}
		else 
			this.catId = (psGetCatFromBreadCrumb()!= null)?psGetCatFromBreadCrumb():"Home" ;
	}
	/*
	 * Extracting product info from source code specified by the "current" row
	 * of items table in the shopping cart
	 */
	this.getItem5 = function(itemRow)
	{
		if(itemRow.cells[1].getElementsByTagName("a").length > 0)
		{
			this.id = psGetValueFromUrl(itemRow.cells[1].getElementsByTagName("a")[0].href,"sku");
			this.name = psTrim(psCleanHtmlTag(itemRow.cells[1].getElementsByTagName("a")[0].innerHTML));
			this.name = psHtmlDecode(this.name);
		//console.log(this.name);
			//is framing kit product
			if(psIsFramingKitsProduct(this.name))
			{
				if(this.id == null)
				{
					this.id = this.name;
				}
				this.catId = "Matting and Accessories";
			}
			else if(this.id == null)
			{
				this.id = this.name;
				if(psIsCustomProduct(this.name))
				{
					var pName =  this.name.search(/(.*)\s\-\s(Frame Package)/gi) > -1? psTrim(RegExp.$1) : null;
					if(pName)
					{
						if(pName.indexOf("Mirror") > -1)
						{
							this.catId = "MirrorShop";	
						}
						else
						{
							this.catId = "Personal Frame Shop";	
						}
					}
				}
			}
			else if(this.id != null)
			{
				this.name = this.name.replace(this.id, "");
				this.name = this.name.replace(/[\#,-]*/gi, "");
				this.name = psTrim(this.name);
				this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id.toLowerCase()) != null? psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id.toLowerCase()): "Home";
			}
			this.price = psTrim(psCleanHtmlTag(itemRow.cells[4].innerHTML.replace('$','')));
			//this.quantity = itemRow.cells[0].getElementsByTagName("input")[0].value;
			if(itemRow.cells[3].getElementsByTagName("input").length > 0)
				this.quantity = itemRow.cells[3].getElementsByTagName("input")[0].value;
			else 
				this.quantity = psTrim(psCleanHtmlTag(itemRow.cells[3].innerHTML));
		}
	}
	/*
	 * Extract shop9 item from cookie
	 */
	this.getItem9 = function(itemRow)
	{
		var strValue = psGetValueFromCookie(G_PS_COOKIE_SHOP9,itemRow);	
		if(strValue)
		{
			var arrValue = 	strValue.split("|");
			this.id = arrValue[0]; 	
			this.name = arrValue[1]; 
			//These custom product:"MirrorShop" or "Personal Frame Shop" 
			if(psIsCustomProduct(this.name))
			{
				this.id = arrValue[1];
			}
			this.quantity =  arrValue[2]; 
			this.price =  arrValue[3]; 
			this.catId = arrValue[4];
		}
	}
}

/* PURPOSE: constructor for profile
 * Note: you can add more methods to psProfile in its prototype
 * RETURN: none
 */
function psProfile(pEmail, pCity, pState, pZip)
{
    this.email = pEmail;
    this.city = pCity;
    this.state = pState;
    this.zipcode = pZip;
	/*
	 * Get user profile from cookie
	 */
	this.readProfile = function()
	{
		this.email = psGetCookie(G_PS_COOKIE_PROFILE);
		if (this.email != null)
		{
			var buf = this.email.split('|');
			for (var i=0; i<buf.length; i++)
			{
				var tempVal = buf[i];
                // when NULL is written to cookie, it becomes string, not literal constant
				buf[i] = (tempVal=="null" ? null : tempVal); 
			}
			this.email = buf[0];
			this.city = buf[1];
			this.state = buf[2];
			this.zipcode = buf[3];
		}
	}
	/*
	 * Set user profile to cookie
	 */
	this.writeProfile = function()
	{
		console.log("writing profile - WOO HOO!!!!!");
		if (this.email == null)
			return;
		// make sure that the data contains 4 parts separated by 3 '|'
		var data = this.email + '|' + this.city + '|' + this.state + '|' + this.zipcode;
		// store on cookie
		psSetCookie(G_PS_COOKIE_PROFILE, data);
	}
}

/*
 * Order object encapsulates order Id, subtotal, shipping and customer Id
 * This design is aimed at code resuse and easy readability
 */
function psOrder(pOrderId, pSubtotal, pShipping, pCusId, pcusCity, pcusState, pcusZIP)
{
	this.id = pOrderId;
	this.subtotal = pSubtotal;
	this.shipping = pShipping;
	this.cusId = pCusId;
	this.cusCity = pcusCity;
	this.cusState = pcusState;
	this.cusZIP = pcusZIP;
	/*
	 * get order info from source code
	 */
	this.getOrder = function()
	{
		//get order id.Your order confirmation number is
		var pBodyText = document.getElementsByTagName("body")[0].innerHTML;
		this.id = pBodyText.toLowerCase().search(/your order confirmation number is:\s([^\/]*)/gi) > -1 ?RegExp.$1: null;
		this.id = psTrim(psCleanHtmlTag(this.id).replace(/[\<,.]*/gi, ""));
		var pValue = psGetCookie(G_PS_COOKIE_ORDER);
		if(pValue != null)
		{
			var arrValue = 	pValue.split(":");
			this.subtotal = arrValue[0] == "null"?null:arrValue[0].replace("$","");
			this.shipping = arrValue[1] == "null"?null:arrValue[1].replace("$","");
			this.cusCity = arrValue[2] == "null"?null:arrValue[2];
			this.cusState = arrValue[3]== "null"?null:arrValue[3];
			this.cusZIP = arrValue[4] == "null"?null:arrValue[4];		
			this.cusId =  arrValue[5] == "null"?null:arrValue[5];
		}
	}
}
/* PURPOSE: Remove all HTML tags in a string
 * RETURN: string
 */
function psCleanHtmlTag(pValue)
{
    return (pValue != null) ? pValue.replace(/\<+.+?\>+/g, "") : null;
}
/* PURPOSE: Get inner text of an object or clean remove html tags of a particular string
 * RETURN: resultant string or null object
 */
function psGetInnerText(pTagOjb)
{
	if (pTagOjb != null)
	{
		if (typeof(pTagOjb) == "object")
			return pTagOjb.innerHTML.replace(/\<+.+?\>+/g, "");
		else
			return pTagOjb.replace(/\<+.+?\>+/g, "");
	}
	return null;
}

/* PURPOSE: Remove all unaccepted characters in categoryid, including
 * [, ', ", :, comma,]
 * RETURN: string
 */
function psCleanCatId(pCatId)
{
    return (pCatId != null) ? psTrim(pCatId.replace(/[\'\":,]/g, "")) : null;
}

function psCleanPageId(pPageId)
{
	return (pPageId != null) ? psTrim(pPageId.replace(/[\n\t\v\r?\'\"]/gi, "")) : null; 
}

function psCleanProductName(pProductName)
{
	return (pProductName != null) ? psTrim(pProductName.replace(/[\n\t\v\r?\'\"]/gi, "")) : null; 
}

/* PURPOSE: Remove all leading & trailing spaces of a string
 * Note: [&nbsp;] is also considered as a space
 * RETURN: string
 */
function psTrim(pStr)
{
	if (pStr == null || typeof(pStr) != "string")
		return pStr;
	return (pStr) ? pStr.replace(/&nbsp;|\u00A0/gi, ' ').replace(/^\s+|\s+$/g, '') : null;
}

/* PURPOSE: extract value from the URL
 * in format of http://xxx.com/page.ext?key1=value1&key2=value2
 * RETURN: string value of the parameter
 */
function psGetValueFromUrl(pUrl, pKey)
{
    var re = new RegExp("[?&]" + pKey + "=([^&$]*)", "i");
    if (pUrl.search(re) == -1)
		return null;
    return unescape(RegExp.$1);
}

/* PURPOSE: returns the value of an element based on element_id
 * @pValueFlag: TRUE means VALUE  attribute of SELECT object returned, not innerHTML
 * RETURN: 
 *  Normal tag: decoded innerHTML
 *  INPUT tag: value attribute
 *  SELECT tag: decoded label of the selected option
 */
function psGetElementValueById(pTagId, pValueFlag)
{
    var tag = document.getElementById(pTagId);
    return psGetElementValue(tag, pValueFlag);
}

/* PURPOSE: returns the value of an element based on element object
 * Note: this function returns decoded text
 * to avoid "double" decode, don't invoke psHtmlDecode on returned value again
 * @pValueFlag: TRUE means VALUE  attribute of SELECT object returned, not innerHTML
 * RETURN: 
 *  Normal tag: decoded innerHTML
 *  INPUT tag: value attribute
 *  SELECT tag: decoded label of the selected option
 *  NULL: if element not exist
 */
function psGetElementValue(pTagObj, pValueFlag)
{
    var tagValue = null;
    if (pTagObj != null)
    {
        if (pTagObj.tagName.search(/^INPUT$/i) > -1)
            tagValue = pTagObj.value;
        else if (pTagObj.tagName.search(/^SELECT$/i) > -1)
        {
            if (pValueFlag == true)
                tagValue = pTagObj.options[pTagObj.selectedIndex].value;
            else
                tagValue = psHtmlDecode(pTagObj.options[pTagObj.selectedIndex].innerHTML);// return label instead of value
        }
        else
            tagValue = psHtmlDecode(pTagObj.innerHTML);
    }

    return tagValue;
}

/* PURPOSE: validate email format
 * RETURN: boolean
 */
function psCheckEmail(pEmail) 
{
    if (pEmail)
    {
        var i = pEmail.search(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/);
        return (i > -1);
    }

    return false;
}

/* PURPOSE: convert special HTML characters to normal character
 * Note: for each project, this function needs to be updated
 * RETURN: decoded string
 */
function psHtmlDecode(pValue)
{
    if (pValue)
    {
        pValue = pValue.replace(/&nbsp;/gi, " ");
        pValue = pValue.replace(/&quot;/gi, '"');
        pValue = pValue.replace(/&amp;/gi, "&");
        pValue = pValue.replace(/&lt;/gi, "<");
        pValue = pValue.replace(/&gt;/gi, ">");
    }

    return pValue;
}

/* PURPOSE: retrieve cookie value
 * RETURN: string
 */
function psGetCookie(pCookieName)
{
	var cookies = document.cookie;
	if (!pCookieName || !cookies)
		return null;

	cookies = "; " + cookies.toLowerCase();
	var key = "; " + pCookieName.toLowerCase() + "=";
	var start = cookies.lastIndexOf(key);
	if (start >= 0)
	{
		start = start + key.length;
		var end = cookies.indexOf(";", start);
		if (end == -1)
			end = cookies.length;

		return unescape(cookies.substring(start, end));
	}

    return null;
}

/* PURPOSE: set cookie value
 * Note: if the designated cookie is too big, the old items will be removed
 * because cookie size is limited to 4K
 * @pLifeTime in seconds
 * pDomain: don't specify if using current domain
 * RETURN: boolean
 */
function psSetCookie(pCookieName, pCookieValue, pLifeTime, pDomain)
{
    if (!pCookieName)
		return false;
	pDomain = ".pictureframes.com";
	if(pLifeTime == "delete") 
    {         
        CC(pCookieName, pDomain);//delete cookie by calling coremetrics's cookie function
        return true;
    }
    // set cookie by calling coremetrics's cookie function
    var expire = (pLifeTime) ? (new Date((new Date()).getTime() + (1000 * pLifeTime))).toGMTString() : null;
    
    return CB(pCookieName, escape(pCookieValue), expire, pDomain);
}

/* PURPOSE: set value in cookie in format of:
 * #key1~value1#key2~value2
 * RETURN: string
 * NOTE: Use null or '' for pValue to remove the pair specified by pKey
 */
function psSetValueToCookie(pCookieName, pKey, pValue)
{
	// "normalize" input parameters
	pCookieName = psTrim(pCookieName);
	pKey = (pKey != null ? psTrim(pKey).toLowerCase() : pKey);
	// 
	var catCookie = psGetCookie(pCookieName);
	if (catCookie == null)
		catCookie = '';

	if (catCookie.indexOf(pKey) >=0) // Store before -> remove the old value
	{
        var reg = new RegExp("#" + pKey + "~([^#]*)", "gi");
        catCookie = catCookie.replace(reg, "");
	}
	// remove the last items (eldest items) until cookie size < 3500	
	if (pValue != null && pValue != '')
	{
		catCookie = "#" + pKey + "~" + pValue + catCookie;
		var cookieArray = null;
		while (catCookie.length > 3500)
		{
			cookieArray = catCookie.split("#");
			cookieArray.pop();
			catCookie = cookieArray.join("#");
		}
	}
	// Save to cookie
	psSetCookie(pCookieName, catCookie, G_PS_COOKIE_LIFETIME);
}

/* PURPOSE: get value stored in cookie in format of:
 * #key1~value1#key2~value2
 * RETURN: string
 */
function psGetValueFromCookie(pCookieName, pKey)
{
	// "normalize" input parameters
	pCookieName = psTrim(pCookieName);
	pKey = psTrim(pKey);
	// extract catId associated with the specified key (pKey)
    var catCookie = psGetCookie(pCookieName);
    if (catCookie != null)
    {
        var re = new RegExp("#" + pKey + "~([^#$]+)", "i");
		if (catCookie.search(re) == -1)
			return null;

        return RegExp.$1;
    }
    return null;
}

/********************************************************/
/* WRAPPER FOR COREMETRICS' TAG FUNCTIONS               */
/********************************************************/
function psCreatePageviewTag(pageID, categoryID, searchString, searchResults) 
{
	pageID=psCleanPageId(pageID);
	categoryID=psCleanCatId(categoryID);
    if (searchResults != null)
        searchResults += "";
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
		alert("cmCreatePageviewTag(" + pageID + ", " + categoryID + ", " + searchString + ", " + searchResults + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreatePageviewTag(pageID, categoryID, searchString, searchResults);
}

function psCreateProductviewTag(productID, productName, categoryID) 
{
	productName = psCleanProductName(productName);
	categoryID=psCleanCatId(categoryID);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateProductviewTag(" + productID + ", " + productName + ", " + categoryID + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateProductviewTag(productID, productName, categoryID);
}

function psCreateShopAction5Tag(productID, productName, productQuantity, productPrice, categoryID) 
{
	productName = psCleanProductName(productName);
	categoryID=psCleanCatId(categoryID);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateShopAction5Tag(" + productID + ", " + productName + ", " + productQuantity + ", " + productPrice + ", " + categoryID + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)//changed productName = productID.
        cmCreateShopAction5Tag(productID, productID, productQuantity, productPrice, categoryID);
    
}

function psCreateShopAction9Tag(productID, productName, productQuantity, productPrice, customerID, orderID, orderTotal, categoryID) 
{
	productName = psCleanProductName(productName);
	categoryID=psCleanCatId(categoryID);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateShopAction9Tag(" + productID + ", " + productName + ", " + productQuantity + ", " + productPrice + ", " + customerID + ", " + orderID + ", " + orderTotal + ", " + categoryID + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)//changed productName = productID.
        cmCreateShopAction9Tag(productID, productID, productQuantity, productPrice, customerID, orderID, orderTotal, categoryID);
}

function psCreateOrderTag(orderID, orderTotal, orderShipping, customerID, customerCity, customerState, customerZIP) 
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateOrderTag(" + orderID + ", " + orderTotal + ", " + orderShipping + ", " + customerID + ", " + customerCity + ", " + customerState + ", " + customerZIP + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateOrderTag(orderID, orderTotal, orderShipping, customerID, customerCity, customerState, customerZIP);
}

function psCreateConversionEventTag(eventID, actionType, categoryID, points) 
{
	categoryID=psCleanCatId(categoryID);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateConversionEventTag(" + eventID + ", " + actionType + ", " + categoryID + ", " + points + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateConversionEventTag(eventID, actionType, categoryID, points);
}

function psCreateRegistrationTag(customerID, customerEmail, customerCity,
				customerState, customerZIP, newsletterName, 
				subscribe) 
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateRegistrationTag(" + customerID + ", " + customerEmail + ", " + customerCity + ", " + customerState + ", " + customerZIP + ", " + newsletterName + ", " + subscribe + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateRegistrationTag(customerID, customerEmail, customerCity, customerState, customerZIP, newsletterName, subscribe);
}

function psCreateErrorTag(pageID, categoryID) 
{
	pageID=psCleanPageId(pageID);
	categoryID=psCleanCatId(categoryID);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateErrorTag(" + pageID + ", " + categoryID + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateErrorTag(pageID, categoryID);
}

function psDisplayShop5s()
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmDisplayShop5s()");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmDisplayShop5s();
}

function psDisplayShop9s()
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmDisplayShop9s()");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmDisplayShop9s();
}
/*===========================END GENERAL UTILITY FUNCTION ==================*/
