/**
 * $Id: dropshadowinterface.js 66632 2009-04-09 21:44:43Z kchiu $
 * $Author: kchiu $
 * $Revision: 66632 $
 * $Name$
 * $Date: 2009-04-09 14:44:43 -0700 (Thu, 09 Apr 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire interfaces.Interface
 * @jsRequire classes.Browser
 * @jsRequire classes.EventManager
 * @jsRequire classes.ResourceManager
 *
 *
 * @version    $Revision: 66632 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        interfaces.Interface
 */

/**
 * DropShadowInterface Constructor / Definition
 *
 * This interface is built on top of the Interface object
 * and is NOT intended to be instantiated directly. See
 * documentation on interfaces.Interface for a complete
 * explanation.
 *
 * @access public
 * @since  v1.1
 * @return DropShadowInterface
 */
function DropShadowInterface(color, xOffset, yOffset, blur, opacity, xShrink, yShrink) {
    this.dropShadowId = null;
    this.elemId       = null;
    this.color        = null;
    this.xOffset      = null;
    this.yOffset      = null;
    this.xShrink      = null;
    this.yShrink      = null;
    this.blur         = null;
    this.opacity      = null;
    this.shadowStyle  = null;
    this.images       = new Array;
    this.draw         = DropShadowInterface_Draw;
    this.erase        = DropShadowInterface_Erase;
    this.init         = DropShadowInterface_Init;
    this.setBlur      = DropShadowInterface_SetBlur;
    this.alignElement = DropShadowInterface_AlignElement;
    return this;
} // End DropShadowInterface

// Setup DropShadowInterface prototype chain
DropShadowInterface.prototype             = new Interface;
DropShadowInterface.prototype.constructor = DropShadowInterface;
DropShadowInterface.superclass            = Interface.prototype;




/****** BEGIN EDIT SECTION ******/

/**
 * Drop shadow style definitions.
 *
 * This data structure allows for the definition of various different
 * drop shadow "styles" that can be applied by setting the shadowStyle
 * of the object implementing DropShadowInterface.
 *
 * Example:
 *
 *    <script language="JavaScript">
 *    var popup = new DropShadowPopup();
 *    popup.shadowStyle = 'Default';
 *    </script>
 *
 * You can also define a shadow style at any time after inclusion of
 * this file and then reference that style instead if you like.
 *
 * @access public
 * @since  v1.1
 * @var    DropShadowInterface.styles   struct
 */
DropShadowInterface.styles = {
    DefaultMenu: { color: 'rgb(0,0,0)', xOffset: 10, yOffset: 15, blur: { iRadius: 12, iSigma: 20}, opacity: .2, xShrink: 16, yShrink: 20 },
    Default:     { color: 'rgb(0,0,0)', xOffset: 17, yOffset: 17, blur: { iRadius: 20, iSigma: 20}, opacity: .2, xShrink: 29, yShrink: 24 },
    IEDefault:   { color: 'rgb(0,0,0)', xOffset:  7, yOffset: 10, blur: { iRadius: 10, iSigma: 20}, opacity: .2, xShrink:  9, yShrink: 10 },
    CheckAll:    { color: 'rgb(0,0,0)', xOffset:  7, yOffset:  7, blur: { iRadius: 10, iSigma: 10}, opacity: .2, xShrink:  9, yShrink:  4 },
    oldIe:       { color: 'rgb(0,0,0)', xOffset:  7, yOffset: 10, blur: { iRadius: 10, iSigma: 20}, opacity: .2, xShrink:  9, yShrink: 10 }
};

/**
 * engineUrl holds the path to the php gradient script.
 *
 * This value can be changed at any time after this file
 * is included as follows:
 *
 * <script>
 *  DropShadowInterface.engineUrl = '/any/url/you/want.php';
 * </script>
 *
 * @access public
 * @since  v1.1
 * @var    string
 */
DropShadowInterface.engineUrl = '/gfx/gradient.php';

/****** END EDIT SECTION ******/




/**
 * Internal image ids used for keeping track of image resources.
 *
 * !DO NOT MODIFY THIS!
 *
 * @access private
 * @since  v1.1
 * @var    DropShadowInterface.imgIds   struct
 */
//DropShadowInterface.imgIds = { top: 0, left: 1, bottom: 2, right: 3, topLeft: 4, bottomLeft: 5, bottomRight: 6, topRight: 7, callout: 8 };
DropShadowInterface.imgIds = { top: 0, left: 1, bottom: 2, right: 3, topLeft: 4, bottomLeft: 5, bottomRight: 6, topRight: 7 };






/**
 * Initializes an object that implements the DropShadowInterface.
 * Call this function prior to any draw() functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function DropShadowInterface_Init(color, xOffset, yOffset, blur, opacity, xShrink, yShrink) {
    //window.messageQueue.add( new Message('DropShadowInterface_Init', 'called') );

    if (!this.shadowStyle && DomUtils.browser.isIE()) this.shadowStyle = 'IEDefault';
    else if (!this.shadowStyle)              this.shadowStyle = 'Default';
    var shadowStyle  = DropShadowInterface.styles[this.shadowStyle];
    this.color       = (color)          ? color   : shadowStyle.color;
    this.xOffset     = !isNaN(xOffset)  ? xOffset : shadowStyle.xOffset;
    this.yOffset     = !isNaN(yOffset)  ? yOffset : shadowStyle.yOffset;
    this.blur        = isString(blur)   ? blur    : shadowStyle.blur;
    this.opacity     = isFloat(opacity) ? opacity : shadowStyle.opacity;
    this.xShrink     = !isNaN(xShrink)  ? xShrink : shadowStyle.xShrink;
    this.yShrink     = !isNaN(yShrink)  ? yShrink : shadowStyle.yShrink;

    /**
     * Handle color parameter
     */
    this.hexColor = '';
    this.rgbColor = '';
    var  rgbRegex = /^rgb\(\s?([0-9]{1,3})\s?\,\s?([0-9]{1,3})\s?\,\s?([0-9]{1,3})\s?\)/;
    var  hexRegex = /^\#?[0-9A-Fa-f]{3}$|\#[0-9A-Fa-f]{6}$/;
    if (hexRegex.test(this.color)) {
        var triplets = new Array;
        if (this.color.length > 4) {
            this.hexColor = this.color;
            for (var start=1; start+2<=this.color.length; start += 2) triplets[triplets.length] = this.color.substr(start, 2);
            for (var i=0;     i<triplets.length;          i++)        triplets[i] = parseInt(triplets[i], 16);
            this.rgbColor = triplets.join(',');
        } else if (this.color.length == 4) {
            for (var start=1; start+1<=this.color.length; start++) triplets[triplets.length] = this.color.substr(start, 1)+this.color.substr(start, 1);
            this.hexColor = '#'+triplets.join('');
            for (var i=0;     i<triplets.length;          i++)     triplets[i] = parseInt(triplets[i], 16);
            this.rgbColor = triplets.join(',');
        } else throw new Error('No valid color setting defined! color: '+this.color);
    } else {
        var matches = this.color.match(rgbRegex);
        if (matches && matches.length > 1) {
            matches.shift();
            for (var i=0; i<matches.length; i++) {
                if (parseInt(matches[i]) > 255) throw new Error('Invalid RGB color specified: '+this.color);
            }
            this.rgbColor = matches.join(',');
        } else throw new Error('No valid color setting defined! color: '+this.color);
    }
    /**
     * Handle blur parameter
     */
    if (isString(this.blur)) {
        var radius = parseInt(this.blur);
        var sigma  = 0;
        if (this.blur.indexOf('x') > 0) sigma = parseInt(this.blur.split('x')[1]);
        this.setBlur(radius, sigma);
    }
    
    this.images = new Array;
    this.images[DropShadowInterface.imgIds.top]         = DropShadowInterface.engineUrl+'?grad=linear&dir=btt&height='+this.blur.iRadius+
         '&width='+this.blur.iRadius+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma+'&opacity='+this.opacity;
    this.images[DropShadowInterface.imgIds.bottom]      = DropShadowInterface.engineUrl+'?grad=linear&dir=ttb&height='+this.blur.iRadius+
         '&width='+this.blur.iRadius+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma+'&opacity='+this.opacity;
    this.images[DropShadowInterface.imgIds.left]        = DropShadowInterface.engineUrl+'?grad=linear&dir=rtl&height='+this.blur.iRadius+
         '&width='+this.blur.iRadius+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma+'&opacity='+this.opacity;
    this.images[DropShadowInterface.imgIds.right]       = DropShadowInterface.engineUrl+'?grad=linear&dir=ltr&height='+this.blur.iRadius+
         '&width='+this.blur.iRadius+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma+'&opacity='+this.opacity;
    this.images[DropShadowInterface.imgIds.bottomRight] = DropShadowInterface.engineUrl+'?grad=radial&radius='+(this.blur.iRadius*2)+
         '&height='+this.blur.iRadius+'&width='+this.blur.iRadius+'&opacity='+this.opacity+
         '&x=0&y=0'+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma;
    this.images[DropShadowInterface.imgIds.topRight]    = DropShadowInterface.engineUrl+'?grad=radial&radius='+(this.blur.iRadius*2)+
         '&height='+this.blur.iRadius+'&width='+this.blur.iRadius+'&opacity='+this.opacity+
         '&x=0&y='+(this.blur.iRadius+1)+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma;
    this.images[DropShadowInterface.imgIds.bottomLeft]  = DropShadowInterface.engineUrl+'?grad=radial&radius='+(this.blur.iRadius*2)+
         '&height='+this.blur.iRadius+'&width='+this.blur.iRadius+'&opacity='+this.opacity+
         '&x='+(this.blur.iRadius+1)+'&y=0'+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma;
    this.images[DropShadowInterface.imgIds.topLeft]     = DropShadowInterface.engineUrl+'?grad=radial&radius='+(this.blur.iRadius*2)+
         '&height='+this.blur.iRadius+'&width='+this.blur.iRadius+'&opacity='+this.opacity+
         '&x='+(this.blur.iRadius+1)+'&y='+(this.blur.iRadius+1)+'&color='+this.rgbColor+'&gaussian='+this.blur.iRadius+'x'+this.blur.iSigma;
    //this.images[DropShadowInterface.imgIds.callout]     = '/images/callout_right.png';
    if (typeof(window.preloadImage) == 'function') {
        for (i=0; i<this.images.length; i++) {
            util.resourceManager.get(this.images[i]);
            //util.resourceManager.get(this.images[i], this.blur.iRadius, this.blur.iRadius);
        }
    }

    //window.messageQueue.add( new Message('DropShadowInterface_Init', 'finished') );
} // End DropShadowInterface_Init




/**
 * "Draws" the actual drop shadow by creating the necessary dom elements and applying them to
 * the object's element.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function DropShadowInterface_Draw() {
    //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'called') );
    var opacity = this.opacity;
    // remove the old drop shadow if it exists
    var dropShadow = document.getElementById(this.dropShadowId);
    if (dropShadow) {
        DomUtils.removeElement(dropShadow);
        dropShadow = null;
    }
    var elem = document.getElementById(this.elemId);
    if (elem) {
        // Clone the elem node now before any other draw changes it.
        var zIndex                       = parseInt(DomUtils.getZIndex(elem))-2;
        this.dropShadowId                = this.id+'_DropShadow';
        var dropShadow                   = elem.cloneNode(false);
        dropShadow.id                    = this.dropShadowId;
        dropShadow.style.visibility      = 'hidden';
        dropShadow.style.zIndex          = zIndex;
        dropShadow.className             = '';
        dropShadow.style.position        = 'absolute';
        dropShadow.style.backgroundColor = 'transparent';
        dropShadow.style.border          = 'none';
        dropShadow.style.left            = parseInt(DomUtils.getElementLeft(elem))+'px';
        dropShadow.style.top             = parseInt(DomUtils.getElementTop(elem))+'px';
        dropShadow.xOffset               = parseInt(this.xOffset);
        dropShadow.yOffset               = parseInt(this.yOffset);
        dropShadow.overflow              = 'visible !important';
        // DO NOT move this to the end since it messes up dimension calculations in IE
        //elem.parentNode.appendChild(dropShadow);
        document.getElementsByTagName('body')[0].appendChild(dropShadow);
/**
 * This is the BETTER / easier way to make the drop shadow follow
 * the element. However, this doesn't work on IE. Retain code for
 * possible future uses.
 */
//    if (!DomUtils.browser.isIE()) {
//        window.addEvent(this.elem, 'DOMAttrModified', function(e) {
//            if (e.type == 'DOMAttrModified' && e.attrName == 'style') {
//                dropShadow.setAttribute('style', e.newValue);
//                dropShadow.style.zIndex   = parseInt(this.style.zIndex)-2;
//                dropShadow.style.overflow = 'visible !important';
//                dropShadow.style.border   = 'none';
//                dropShadow.style.left     = DomUtils.getElementLeft(this)+'px';
//                dropShadow.style.top      = DomUtils.getElementTop(this)+'px';
//            }
//        }, this.elem, true);
//    }
//    this.elem.parentNode.insertBefore(this.dropShadow, this.elem.nextSibling);
        if (this.xShrink) {
            //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting drop shadow width') );
            dropShadow.style.width = parseInt(parseInt(DomUtils.getElementWidth(elem))+(parseInt(this.xShrink)/2))+'px';
        }
        if (this.yShrink) {
            //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting drop shadow height') );
            dropShadow.style.height = parseInt(parseInt(DomUtils.getElementHeight(elem))+(parseInt(this.yShrink)/2))+'px';
        }
    
        if (DomUtils.browser.isIE()) {
            var eStyle = DomUtils.getCurrentStyle(elem);
            pLeft   = parseInt(eStyle.paddingLeft);
            pRight  = parseInt(eStyle.paddingRight);
            pTop    = parseInt(eStyle.paddingTop);
            pBottom = parseInt(eStyle.paddingBottom);
            pWidth  = parseInt((!isNaN(pLeft) ? pLeft : 0)+(!isNaN(pRight)  ? pRight  : 0));
            pHeight = parseInt((!isNaN(pTop)  ? pTop  : 0)+(!isNaN(pBottom) ? pBottom : 0));
        } else {
            pHeight = 0;
            pWidth  = 0;
        }
        
        var img;
        var shadow                         = document.createElement('div');
        shadow.id                          = this.id+'_DropShadow_Main';
        shadow.style.position              = 'absolute';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting shadow width') );
        shadow.style.width                 = parseInt(parseInt(DomUtils.getElementWidth(elem))-parseInt(this.xShrink))+'px';
        shadow.style.height                = parseInt(parseInt(DomUtils.getElementHeight(elem))-parseInt(this.yShrink))+'px';
        shadow.style.left                  = parseInt(this.xOffset)+'px';
        shadow.style.top                   = parseInt(this.yOffset)+'px';
        shadow.style.border                = 'none';
        shadow.style.backgroundColor       = 'rgb('+this.rgbColor+')';
        shadow.style.zIndex                = zIndex;
        if (DomUtils.browser.isIE()) shadow.style.filter    += 'progid:DXImageTransform.Microsoft.Alpha(opacity='+(this.opacity*100)+')';
        else                         shadow.style.MozOpacity = this.opacity;
        dropShadow.appendChild(shadow);
    
        var bottomEdge                     = document.createElement('div');
        bottomEdge.id                      = this.id+'_DropShadow_Bottom';
        bottomEdge.className               = 'shadow';
        bottomEdge.style.position          = 'absolute';
        bottomEdge.style.top               = parseInt(parseInt(DomUtils.getElementHeight(shadow))+parseInt(this.yOffset))+'px';
        bottomEdge.style.left              = parseInt(this.xOffset)+'px';
        bottomEdge.style.height            = parseInt(this.blur.iRadius)+'px';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting bottom width') );
        bottomEdge.style.width             = parseInt(DomUtils.getElementWidth(shadow))+'px';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'bottom width: '+bottomEdge.style.width) );
        bottomEdge.style.zIndex            = zIndex;
        img                                = document.createElement('img');
        img.src                            = util.resourceManager.get(this.images[DropShadowInterface.imgIds.bottom]);
        img.height                         = parseInt(this.blur.iRadius);
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting image width') );
        img.width                          = parseInt(DomUtils.getElementWidth(shadow));
        img.style.position                 = 'absolute';
        img.style.left                     = '0px';
        img.style.top                      = '0px';

        DropShadowInterface_FixPNG(img);

        bottomEdge.appendChild(img);
        dropShadow.appendChild(bottomEdge);
    
        var rightEdge                      = document.createElement('div');
        rightEdge.id                       = this.id+'_DropShadow_Right';
        rightEdge.className                = 'shadow';
        rightEdge.style.position           = 'absolute';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting right width') );
        rightEdge.style.left               = parseInt(parseInt(DomUtils.getElementWidth(shadow))+parseInt(this.xOffset))+'px';
        rightEdge.style.top                = parseInt(this.yOffset)+'px';
        rightEdge.style.height             = parseInt(DomUtils.getElementHeight(shadow))+'px';
        rightEdge.style.width              = parseInt(this.blur.iRadius)+'px';
        rightEdge.style.zIndex             = zIndex;
        img                                = document.createElement('img');
        img.src                            = util.resourceManager.get(this.images[DropShadowInterface.imgIds.right]);
        img.height                         = parseInt(DomUtils.getElementHeight(shadow));
        img.width                          = parseInt(this.blur.iRadius);
        img.style.position                 = 'absolute';
        img.style.left                     = '0px';
        img.style.top                      = '0px';

        DropShadowInterface_FixPNG(img);

        rightEdge.appendChild(img);
        dropShadow.appendChild(rightEdge);
    
        var leftEdge                       = document.createElement('div');
        leftEdge.id                        = this.id+'_DropShadow_Left';
        leftEdge.className                 = 'shadow';
        leftEdge.style.position            = 'absolute';
        leftEdge.style.left                = parseInt(parseInt(this.xOffset)-parseInt(this.blur.iRadius))+'px';
        leftEdge.style.top                 = parseInt(this.yOffset)+'px';
        leftEdge.style.height              = parseInt(DomUtils.getElementHeight(shadow))+'px';
        leftEdge.style.width               = parseInt(this.blur.iRadius)+'px';
        leftEdge.style.zIndex              = zIndex;
        img                                = document.createElement('img');
        img.src                            = util.resourceManager.get(this.images[DropShadowInterface.imgIds.left]);
        img.height                         = parseInt(DomUtils.getElementHeight(shadow));
        img.width                          = parseInt(this.blur.iRadius);
        img.style.position                  = 'absolute';
        img.style.left                      = '0px';
        img.style.top                       = '0px';

        DropShadowInterface_FixPNG(img);

        leftEdge.appendChild(img);
        dropShadow.appendChild(leftEdge);
    
        var topEdge                         = document.createElement('div');
        topEdge.id                          = this.id+'_DropShadow_Top';
        topEdge.className                   = 'shadow';
        topEdge.style.position              = 'absolute';
        topEdge.style.left                  = parseInt(this.xOffset)+'px';
        topEdge.style.top                   = parseInt(parseInt(this.yOffset)-parseInt(this.blur.iRadius))+'px';
        topEdge.style.height                = parseInt(this.blur.iRadius)+'px';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting top width') );
        topEdge.style.width                 = parseInt(DomUtils.getElementWidth(shadow))+'px';
        topEdge.style.zIndex                = zIndex;
        img                                 = document.createElement('img');
        img.src                             = util.resourceManager.get(this.images[DropShadowInterface.imgIds.top]);
        img.height                          = parseInt(this.blur.iRadius);
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting image width') );
        img.width                           = parseInt(DomUtils.getElementWidth(shadow));
        img.style.position                  = 'absolute';
        img.style.left                      = '0px';
        img.style.top                       = '0px';

        DropShadowInterface_FixPNG(img);

        topEdge.appendChild(img);
        dropShadow.appendChild(topEdge);
    
        var brCorner                        = document.createElement('div');
        brCorner.id                         = this.id+'_DropShadow_BottomRightCorner';
        brCorner.className                  = 'shadow';
        brCorner.style.position             = 'absolute';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting br width') );
        brCorner.style.top                  = parseInt(parseInt(DomUtils.getElementHeight(shadow))+parseInt(this.yOffset))+'px';
        brCorner.style.left                 = parseInt(parseInt(DomUtils.getElementWidth(shadow))+parseInt(this.xOffset))+'px';
        brCorner.style.height               = parseInt(this.blur.iRadius)+'px';
        brCorner.style.width                = parseInt(this.blur.iRadius)+'px';
        brCorner.style.zIndex               = zIndex;
        img                                 = document.createElement('img');
        img.src                             = util.resourceManager.get(this.images[DropShadowInterface.imgIds.bottomRight]);
        img.height                          = parseInt(this.blur.iRadius);
        img.width                           = parseInt(this.blur.iRadius);
        img.style.position                  = 'absolute';
        img.style.left                      = '0px';
        img.style.top                       = '0px';
        
        DropShadowInterface_FixPNG(img);

        brCorner.appendChild(img);
        dropShadow.appendChild(brCorner);
    
        var trCorner                        = document.createElement('div');
        trCorner.id                         = this.id+'_DropShadow_TopRightCorner';
        trCorner.className                  = 'shadow';
        trCorner.style.position             = 'absolute';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting tr width') );
        trCorner.style.left                 = parseInt(parseInt(DomUtils.getElementWidth(shadow))+parseInt(this.xOffset))+'px';
        trCorner.style.top                  = parseInt(parseInt(this.yOffset)-parseInt(this.blur.iRadius))+'px';
        trCorner.style.height               = parseInt(this.blur.iRadius)+'px';
        trCorner.style.width                = parseInt(this.blur.iRadius)+'px';
        trCorner.style.zIndex               = zIndex;
        img                                 = document.createElement('img');
        img.src                             = util.resourceManager.get(this.images[DropShadowInterface.imgIds.topRight]);
        img.height                          = parseInt(this.blur.iRadius);
        img.width                           = parseInt(this.blur.iRadius);
        img.style.position                  = 'absolute';
        img.style.left                      = '0px';
        img.style.top                       = '0px';

        DropShadowInterface_FixPNG(img);

        trCorner.appendChild(img);
        dropShadow.appendChild(trCorner);
    
        var blCorner                        = document.createElement('div');
        blCorner.id                         = this.id+'_DropShadow_BottomLeftCorner';
        blCorner.className                  = 'shadow';
        blCorner.style.position             = 'absolute';
        blCorner.style.left                 = parseInt(parseInt(this.xOffset)-parseInt(this.blur.iRadius))+'px';
        //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'getting bl width') );
        blCorner.style.top                  = parseInt(parseInt(DomUtils.getElementHeight(shadow))+parseInt(this.yOffset))+'px';
        blCorner.style.height               = parseInt(this.blur.iRadius)+'px';
        blCorner.style.width                = parseInt(this.blur.iRadius)+'px';
        blCorner.style.zIndex               = zIndex;
        img                                 = document.createElement('img');
        img.src                             = util.resourceManager.get(this.images[DropShadowInterface.imgIds.bottomLeft]);
        img.height                          = parseInt(this.blur.iRadius);
        img.width                           = parseInt(this.blur.iRadius);
        img.style.position                  = 'absolute';
        img.style.left                      = '0px';
        img.style.top                       = '0px';

        DropShadowInterface_FixPNG(img);

        blCorner.appendChild(img);
        dropShadow.appendChild(blCorner);
    
        var tlCorner                        = document.createElement('div');
        tlCorner.id                         = this.id+'_DropShadow_TopLeftCorner';
        tlCorner.className                  = 'shadow';
        tlCorner.style.position             = 'absolute';
        tlCorner.style.left                 = parseInt(parseInt(this.xOffset)-parseInt(this.blur.iRadius))+'px';
        tlCorner.style.top                  = parseInt(parseInt(this.yOffset)-parseInt(this.blur.iRadius))+'px';
        tlCorner.style.height               = parseInt(this.blur.iRadius)+'px';
        tlCorner.style.width                = parseInt(this.blur.iRadius)+'px';
        tlCorner.style.zIndex               = zIndex;
        img                                 = document.createElement('img');
        img.src                             = util.resourceManager.get(this.images[DropShadowInterface.imgIds.topLeft]);
        img.height                          = parseInt(this.blur.iRadius);
        img.width                           = parseInt(this.blur.iRadius);
        img.style.position                  = 'absolute';
        img.style.left                      = '0px';
        img.style.top                       = '0px';

        DropShadowInterface_FixPNG(img);

        tlCorner.appendChild(img);
        dropShadow.appendChild(tlCorner);
        dropShadow.style.visibility = DomUtils.getCurrentStyle(elem).visibility;

    } else {
        throw new Error('unable to find content element');
    }
    //window.messageQueue.add( new Message('DropShadowInterface_Draw', 'finished') );
} // End DropShadowInterface_Draw




/**
 * "Erases" the drop shadow by removing the dom elements created with DropShadowInterface.draw().
 *
 * @access public
 * @since  v0.0.1a
 * @return void
 */
function DropShadowInterface_Erase() {
    //window.messageQueue.add( new Message('DropShadowInterface_Erase', 'called') );
    var dropShadow = document.getElementById(this.dropShadowId);
    if (dropShadow) DomUtils.removeElement(dropShadow);
    // Clean up dom references for IE
    dropShadow = null;
    //window.messageQueue.add( new Message('DropShadowInterface_Erase', 'finished') );
} // End DropShadowInterface_Erase




/**
 * Aligns the object's element by adjusting its left & top by the proper calculations (which are done
 * in this function) on the left & top of the element.
 *
 * @access public
 * @since  v0.0.1a
 * @return void
 */
function DropShadowInterface_AlignElement(pos) {
    //window.messageQueue.add( new Message('DropShadowInterface_AlignElement', 'called') );
    var elem       = document.getElementById(this.elemId);
    if (!elem)       throw new Error('Unable to find element: '+this.elemId);
    var dropShadow = document.getElementById(this.dropShadowId);
    if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);
    // Align the drop shadow with the main element
    dropShadow.style.position = 'absolute';
    dropShadow.style.left     = DomUtils.getElementLeft(elem)+'px';
    dropShadow.style.top      = DomUtils.getElementTop(elem)+'px';
    // fanatic memory cleanup
    dropShadow = null;
    elem       = null;
    //window.messageQueue.add( new Message('DropShadowInterface_AlignElement', 'finished') );
} // End DropShadowInterface_AlignElement




/**
 * Sets the blur values of the drop shadow.
 *
 * radius:   radius of area to blur
 * sigma:    amount of pixels to consider when
 *           averaging pixel values
 *
 * @access public
 * @since  v1.1
 * @param  integer  radius   radius of area to blur
 * @param  integer  sigma    amount of pixels to consider when averaging pixel values
 * @return void
 */
function DropShadowInterface_SetBlur(radius, sigma) {
    this.blur = { iRadius: radius, iSigma: sigma };
} // End DropShadowInterface_SetBlur


/**
 * Fixes alpha transparency issue with PNGs on Microsoft Internet Explorer.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function DropShadowInterface_FixPNG(img) {
    if (DomUtils.browser.isIE()) {
        var arVersion = navigator.appVersion.split("MSIE");
        var version = 0.0;
        if (arVersion && arVersion.length > 1) version = parseFloat(arVersion[1]);
        if ((version >= 5.5) && (version < 7) && (document.body.filters)) {
            var imgID    = (img.id) ? "id='" + img.id + "' " : "";
            var imgClass = (img.className) ? "class='" + img.className + "' " : "";
            var imgTitle = (img.title)                    ?
                            "title='" + img.title  + "' " :
                            "title='" + img.alt    + "' " ;
            var imgStyle = "display:inline-block;";
            if (img && img.style) { 
              imgStyle += img.style.cssText || ''; 
              img.style.cssText = "display: none";
            }
            var strNewHTML = "<span " + imgID + imgClass + imgTitle
                           + " style=\"" + "width:" + img.width 
                           + "px; height:" + img.height 
                           + "px;" + imgStyle + ";"
                           + "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader"
                           + "(src=\'"+img.src+"\', sizingMethod='scale');\"></span>";
            img.src = "";
            img.outerHTML = strNewHTML;
        }
    }
}
/**
 * $Id: popupinterface.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire interfaces.Interface
 * @jsRequire interfaces.PopupInterface
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        interfaces.Interface
 */

/**
 * PopupInterface Constructor / Definition
 *
 * This interface is built on top of the Interface object
 * and is NOT intended to be instantiated directly. See
 * documentation on interfaces.Interface for a complete
 * explanation.
 *
 * @access public
 * @since  v1.1
 * @return PopupInterface
 */
function PopupInterface() {
    this.elemId  = null;
    this.visible = false;
    this.linked  = new Array;
    this.hide    = PopupInterface_Hide;
    this.show    = PopupInterface_Show;
    this.toggle  = PopupInterface_Toggle;
}

// Setup PopupInterface prototype chain
PopupInterface.prototype             = new Interface;
PopupInterface.prototype.constructor = PopupInterface;
PopupInterface.superclass            = Interface.prototype;

/**
 * Makes the object's element invisible.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function PopupInterface_Hide() {
    this.visible = false;
    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);
    elem.style.visibility = 'hidden';
    elem.style.left       = '0px';
    elem.style.top        = '0px';
    for (var i=0; i<this.linked.length; i++) {
        var elem = document.getElementById(this.linked[i]);
        elem.style.visibility = 'hidden';
        elem.style.left       = '0px';
        elem.style.top        = '0px';
    }
    return true;
}

/**
 * Makes the object's element visibile.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function PopupInterface_Show() {
    this.visible = true;
    if (document.getElementById(this.elemId)) document.getElementById(this.elemId).style.visibility = 'visible';
    for (var i=0; i<this.linked.length; i++) document.getElementById(this.linked[i]).style.visibility = 'visible';
    return true;
}

/**
 * Toggles the object's visibility.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function PopupInterface_Toggle() {
    if (this.visible) return this.hide();
    else              return this.show();
}
/**
 * $Id: delayedpopupinterface.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire interfaces.Interface
 * @jsRequire interfaces.PopupInterface
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        interfaces.Interface
 */

/**
 * DelayedPopupInterface Constructor / Definition
 *
 * This interface is built on top of the Interface object
 * and is NOT intended to be instantiated directly. See
 * documentation on interfaces.Interface for a complete
 * explanation.
 *
 * @access public
 * @since  v1.1
 * @return DelayedPopupInterface
 */
function DelayedPopupInterface() {
    this.elemId      = null;
    this.visible     = false;
    this.linked      = new Array;
    this.timer       = null;
    this.delay       = null;
    this.hide        = DelayedPopupInterface_Hide;
    this.show        = DelayedPopupInterface_Show;
    this.toggle      = PopupInterface_Toggle;
    this.cancelTimer = DelayedPopupInterface_CancelTimer;
    this.implement(PopupInterface);
    return this;
}

// Setup DelayedPopupInterface prototype chain
DelayedPopupInterface.prototype             = new PopupInterface;
DelayedPopupInterface.prototype.constructor = DelayedPopupInterface;
DelayedPopupInterface.superclass            = PopupInterface.prototype;

/**
 * Calls PopupInterface_Hide after timer runs out.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function DelayedPopupInterface_Hide() {
    this.cancelTimer();
    var obj = this;
    this.timer = setTimeout(function() {
        PopupInterface_Hide.call(obj);
        obj.timer = null;
    }, this.delay);
    return true;
}

/**
 * Calls PopupInterface_Show after timer runs out.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function DelayedPopupInterface_Show() {
    this.cancelTimer();
    var obj = this;
    this.timer = setTimeout(function() {
        PopupInterface_Show.call(obj);
        obj.timer = null;
    }, this.delay);
    return true;
}

/**
 * Cancels any currently running timers.
 *
 * This effectively stops the show / hide / toggle
 * functions in their tracks, allowing us to cancel
 * them at any time.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function DelayedPopupInterface_CancelTimer() {
    if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
    }
    return true;
}
/**
 * $Id: roundedcornersinterface.js 76074 2009-11-19 20:53:10Z kchiu $
 * $Author: kchiu $
 * $Revision: 76074 $
 * $Name$
 * $Date: 2009-11-19 12:53:10 -0800 (Thu, 19 Nov 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire interfaces.Interface
 * @jsRequire classes.ResourceManager
 *
 *
 * @version    $Revision: 76074 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        interfaces.Interface
 */

/**
 * RoundedCornersInterface Constructor / Definition
 *
 * This interface is built on top of the Interface object
 * and is NOT intended to be instantiated directly. See
 * documentation on interfaces.Interface for a complete
 * explanation.
 *
 * @access public
 * @since  v1.1
 * @return RoundedCornersInterface
 */
function RoundedCornersInterface() {
    this.elemId       = null;
    this.cornerStyle  = null;
    this.init         = RoundedCornersInterface_Init;
    this.draw         = RoundedCornersInterface_Draw;
    this.erase        = RoundedCornersInterface_Erase;
    this.cornersDrawn = false;
    this.init();
}

// Setup RoundedCornersInterface prototype chain
RoundedCornersInterface.prototype             = new Interface;
RoundedCornersInterface.prototype.constructor = RoundedCornersInterface;
RoundedCornersInterface.superclass            = Interface.prototype;






/****** BEGIN EDIT SECTION ******/

/**
 * Rounded corners style definitions.
 *
 * This data structure allows for the definition of various different
 * rounded corners "styles" that can be applied by setting the roundedCornersStyle
 * of the object implementing RoundedCornersInterface.
 *
 * Example:
 *
 *    <script language="JavaScript">
 *    RoundedCornersInterface.settings.style = 'Default';
 *    var popup = new RoundedCornersPopup();
 *    </script>
 *
 * You can also define a rounded corner style at any time after
 * inclusion of this file and then reference that style instead if you
 * like.
 *
 * Note: This style definition is site-wide, not object specific. This
 * will be changing in the near future as this interface adopts the
 * same style interface that DropShadowInterface uses.
 *
 * @access public
 * @since  v1.1
 * @todo   Add .roundedCornersStyle to interface (see DropShadowInterface)
 * @var    RoundedCornersInterface.styles   struct
 */
RoundedCornersInterface.styles = {
    Default: {
        images: {
            tr: { src: 'http://i.pgcdn.com/images/balloon/top_right_6x6.gif',    width: 6, height: 6 },
            tl: { src: 'http://i.pgcdn.com/images/balloon/top_left_6x6.gif',     width: 6, height: 6 },
            bl: { src: 'http://i.pgcdn.com/images/balloon/bottom_left_6x6.gif',  width: 6, height: 6 },
            br: { src: 'http://i.pgcdn.com/images/balloon/bottom_right_6x6.gif', width: 6, height: 6 }
        }
    }
};

/**
 * General settings struct.
 *
 * @access public
 * @since  v1.1
 * @var    RoundedCornersInterface.settings  struct
 *
 */
RoundedCornersInterface.settings = { style: 'Default' };

/****** END EDIT SECTION ******/








/**
 * Internal image ids used for keeping track of image resources.
 *
 * !DO NOT MODIFY THIS!
 *
 * @access private
 * @since  v1.1
 * @var    RoundedCornersInterface.imgIds   struct
 */
RoundedCornersInterface.imgIds   = { tr: 0, tl: 1, bl: 2, br: 3 };

/**
 * Initializes an object that implements the RoundedCornersInterface.
 * Call this function prior to any draw() functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function RoundedCornersInterface_Init() {
    var style = RoundedCornersInterface.styles[RoundedCornersInterface.settings.style];
    if (typeof(window.preloadImage) == 'function') {
        window.preloadImage(style.images.tr.src, style.images.tr.width, style.images.tr.height);
        window.preloadImage(style.images.tl.src, style.images.tl.width, style.images.tl.height);
        window.preloadImage(style.images.bl.src, style.images.bl.width, style.images.bl.height);
        window.preloadImage(style.images.br.src, style.images.br.width, style.images.br.height);
    }
} // End RoundedCornersInterface_Init

/**
 * "Draws" the actual rounded corners by creating the necessary dom elements and applying them to
 * the object's element.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function RoundedCornersInterface_Draw() {
    //window.messageQueue.add( new Message('RoundedCornersInterface_Draw', 'called') );
    if (this.cornersDrawn) { RoundedCornersInterface_Erase.call(this); }
    var elem = document.getElementById(this.elemId);
    if (elem) {
        //if (typeof(writeDebug) == 'function') writeDebug('drawing background...');
        var style = RoundedCornersInterface.styles[RoundedCornersInterface.settings.style];
        /** BACKGROUND **/
        var div                   = document.createElement('div');
        div.id                    = 'roundedCorners_Background';
        div.style.position        = 'absolute';
        div.style.left            = style.images.tl.width+'px';
        div.style.top             = style.images.tl.height+'px';
        var eHeight  = DomUtils.getElementHeight(elem);
        var tlHeight = style.images.tl.height;
        var blHeight = style.images.bl.height;
        //window.messageQueue.add( new Message(funcname(this), 'getting width') );
        var eWidth   = DomUtils.getElementWidth(elem);
        var tlWidth  = style.images.tl.width;
        var blWidth  = style.images.bl.width;
        div.style.height          = (parseInt(eHeight)-tlHeight-blHeight)+'px';
        div.style.width           = (parseInt(eWidth)-tlWidth-blWidth)+'px';
        div.style.backgroundColor = '#ffffff';
        div.style.zIndex          = '-1';
        //if (typeof(writeDebug) == 'function') writeDebug('background zIndex: '+div.style.zIndex);
        elem.appendChild(div);
        elem.style.backgroundColor = 'transparent';
        
        /** EDGES **/
        //if (typeof(writeDebug) == 'function') writeDebug('drawing bottom edge...');
        // Bottom edge
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_BottomEdge';
        div.style.position        = 'absolute';
        div.style.left            = style.images.bl.width+'px';
        div.style.top             = (parseInt(DomUtils.getElementHeight(elem))-style.images.bl.height)+'px';
        div.style.height          = (style.images.bl.height)+'px'; // -1 accounts for bottom border
        //window.messageQueue.add( new Message(funcname(this), 'getting bottom width') );
        div.style.width           = (parseInt(DomUtils.getElementWidth(elem)) - style.images.bl.width - style.images.br.width)+'px';
        div.style.borderBottom    = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing top edge...');
        // Top edge
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_TopEdge';
        div.style.position        = 'absolute';
        div.style.left            = style.images.tl.width+'px';
        div.style.top             = '0px';
        div.style.height          = (style.images.tl.height)+'px'; // -1 accounts for top border
        //window.messageQueue.add( new Message(funcname(this), 'getting top width') );
        div.style.width           = (parseInt(DomUtils.getElementWidth(elem))-style.images.tl.width-style.images.tr.width)+'px';
        div.style.borderTop       = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        // Left edge
        //if (typeof(writeDebug) == 'function') writeDebug('drawing left edge...');
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_LeftEdge';
        div.style.position        = 'absolute';
        div.style.left            = '0px';
        div.style.top             = style.images.tl.height+'px';
        div.style.width           = (style.images.tl.width)+'px'; // -1 accounts for left border
        div.style.height          = (parseInt(DomUtils.getElementHeight(elem)) - style.images.tl.height - style.images.bl.height)+'px';
        div.style.borderLeft      = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing right edge...');
        // Right edge
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_RightEdge';
        div.style.position        = 'absolute';
        //window.messageQueue.add( new Message(funcname(this), 'getting right width') );
        div.style.left            = (parseInt(DomUtils.getElementWidth(elem))-style.images.tr.width)+'px';
        div.style.top             = style.images.tr.height+'px';
        div.style.width           = (style.images.tr.width)+'px';
        div.style.height          = (parseInt(DomUtils.getElementHeight(elem))-style.images.tr.height-style.images.br.height)+'px';
        div.style.borderRight     = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        /** CORNERS **/
        //if (typeof(writeDebug) == 'function') writeDebug('drawing top right corner...');
        // Top right
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_TopRightCorner';
        img.src                   = style.images.tr.src;
        img.height                = style.images.tr.height;
        img.width                 = style.images.tr.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        //window.messageQueue.add( new Message(funcname(this), 'getting tr width') );
        img.style.left            = parseInt(parseInt(DomUtils.getElementWidth(elem))-(img.width))+'px';
        img.style.top             = '0px';
        elem.appendChild(img);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing top left corner...');
        // Top left
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_TopLeftCorner';
        img.src                   = style.images.tl.src;
        img.height                = style.images.tl.height;
        img.width                 = style.images.tl.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        img.style.left            = '0px';
        img.style.top             = '0px';
        elem.appendChild(img);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing bottom left corner...');
        // Bottom left
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_BottomLeftCorner';
        img.src                   = style.images.bl.src;
        img.height                = style.images.bl.height;
        img.width                 = style.images.bl.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        img.style.left            = '0px';
        img.style.top             = parseInt(parseInt(DomUtils.getElementHeight(elem))-parseInt(img.height))+'px';
        elem.appendChild(img);
        // Bottom right
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_BottomRightCorner';
        img.src                   = style.images.br.src;
        img.height                = style.images.br.height;
        img.width                 = style.images.br.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        //window.messageQueue.add( new Message(funcname(this), 'getting br width') );
        img.style.left            = parseInt(parseInt(DomUtils.getElementWidth(elem))-(img.width))+'px';
        img.style.top             = parseInt(parseInt(DomUtils.getElementHeight(elem))-(img.height))+'px';
        elem.appendChild(img);
        
        this.cornersDrawn = true;
    }
    //window.messageQueue.add( new Message('RoundedCornersInterface_Draw', 'finished') );
} // End RoundedCornersInterface_Draw

/**
 * "Erases" the rounded corners by removing the dom elements created with RoundedCornersInterface.draw().
 *
 * @access public
 * @since  v0.0.1a
 * @return void
 */
function RoundedCornersInterface_Erase() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> RoundedCornersInterface_Erase() called.', '#000000', '#ffff00');
    var elem = document.getElementById(this.elemId);
    if (elem.hasChildNodes()) {
        //if (typeof(writeDebug) == 'function') writeDebug('elem has child nodes: '+elem.childNodes.length);
        for (var i=elem.childNodes.length; i>0; i--) {
            var nodeId = elem.childNodes[i-1].id;
            var eq = '!=';
            var idPre = 'roundedCorners_';
            if (nodeId && nodeId.substr(0, idPre.length) == idPre) {
                eq = '==';
                //elem.removeChild(elem.childNodes[i-1]);
                DomUtils.removeElement(elem.childNodes[i-1]);
            }
            //if (typeof(writeDebug) == 'function') writeDebug(nodeId.substr(0, idPre.length)+' '+eq+' '+idPre);
        }
    } //else if (typeof(writeDebug) == 'function') writeDebug('no child nodes!');
    this.cornersDrawn = false;
    //if (typeof(writeDebug) == 'function') writeDebug('<< RoundedCornersInterface_Erase() finished.', '#000000', '#ffff00');
} // End RoundedCornersInterface_Erase







function ResourceManager() {

    var resourceManager = this;

    this.preloadedImages = new Array;


    window.preloadImage = ResourceManager_PreloadImage;
    window.getImage     = ResourceManager_GetImage;
    window.getImageSrc  = ResourceManager_GetImageSrc;
    window.swapImageSrc = ResourceManager_SwapImageSrc;


    return this;
}




function ResourceManager_PreloadImage(url, width, height) {
    if (!window.resourceManager.preloadedImages) window.resourceManager.preloadedImages = new Array;
//    if (typeof(writeDebug) == 'function') writeDebug('ResourceManager_PreloadImage(): checking for preloaded '+url);
    if (!window.resourceManager.preloadedImages[url]) {
//        if (typeof(writeDebug) == 'function') { writeDebug('ResourceManager_PreloadImage(): preloading '+url+', w: '+width+', h: '+height); }
        var image = new Image(width, height);
        image.src = url;
        window.resourceManager.preloadedImages[url] = image;
    }// else if (typeof(writeDebug) == 'function') writeDebug('ResourceManager_PreloadImage(): image already preloaded: '+url);
    return window.resourceManager.preloadedImages[url];
}

function ResourceManager_GetImage(url, width, height) {
    return window.preloadImage(url, width, height);
}

function ResourceManager_GetImageSrc(url) {
    return window.getImage(url).src;
}

function ResourceManager_SwapImageSrc(imgElem, url) {
    if (imgElem && imgElem.nodeType == 'IMG') {
        imgElem.oldSrc = imgElem.src;
        imgElem.src    = window.getImageSrc(url);
    }
}




window.resourceManager = new ResourceManager();/**
 * $Id: imagepopup.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire classes.BaseObject
 * @jsRequire classes.EventManager
 * @jsRequire interfaces.DropShadowInterface
 * @jsRequire interfaces.CalloutInterface
 * @jsRequire interfaces.PopupInterface
 * @jsRequire interfaces.AnchoredInterface
 * @jsRequire interfaces.RoundedCornersInterface
 *
 *
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        classes.BaseObject
 * @see        interfaces.DropShadowInterface
 * @see        interfaces.CalloutInterface
 * @see        interfaces.PopupInterface
 * @see        interfaces.AnchoredInterface
 * @see        interfaces.RoundedCornersInterface
 */

/**
 * ImagePopup Constructor / Definition
 *
 * This is NOT intended to be instantiated directly. Instead, use the
 * singleton accessor methods ImagePopup.getInstance(),
 * ImagePopup.show(), ImagePopup.hide() and ImagePopup.toggle().
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement       anchor
 * @return ImagePopup
 */
function ImagePopup(anchor) {
    this.elemId            = null;
    //this.elem              = null;
    // Callout interface implementation
    this.calloutId         = null;
    //this.callout           = null;
    this.calloutPadding    = 0;
    // Drop shadow interface implementation
    this.dropShadowId      = null;
    //this.dropShadow        = null;
    this.color             = null;
    this.xOffset           = null;
    this.yOffset           = null;
    this.blur              = { iRadius: null, iSigma: null };
    this.opacity           = null;
    this.xShrink           = null;
    this.yShrink           = null;
    this.shadowStyle       = null;
    this.images            = new Array;
    this.setBlur           = DropShadowInterface_SetBlur;
    // Popup interface implementation
    this.visible           = false;
    this.linked            = new Array;
    this.hide              = PopupInterface_Hide;
    this.show              = PopupInterface_Show;
    this.toggle            = PopupInterface_Toggle;
    // Anchored interface implementation
    this.anchorId          = null;
    //this.anchor            = anchor || null;
    this.getAnchorX        = AnchoredInterface_GetAnchorX;
    this.getAnchorY        = AnchoredInterface_GetAnchorY;
    this.getAnchorZ        = AnchoredInterface_GetAnchorZ;
    this.getAnchorWidth    = AnchoredInterface_GetAnchorWidth;
    this.getAnchorHeight   = AnchoredInterface_GetAnchorHeight;
    this.getAnchorPosition = AnchoredInterface_GetAnchorPosition;
    this.getElemWidth      = AnchoredInterface_GetElemWidth;
    this.getElemHeight     = AnchoredInterface_GetElemHeight;
    this.setAnchor         = AnchoredInterface_SetAnchor;
    this.disableScroll     = true;
    // Rounded corners interface implementation
    this.cornerStyle       = null;
    this.cornersDrawn      = false;
    // Drop shadow interface && Callout interface joint implementation
    this.erase             = ImagePopup_Erase;
    this.draw              = ImagePopup_Draw;
    this.init              = ImagePopup_Init;
    // Drop shadow interface && popup interface joint implementation
    this.show              = ImagePopup_Show;
    // Drop shadow interface && Anchored interface joint implementation
    this.alignElement      = ImagePopup_AlignElement;
    
    this.contentId         = null;
    //this.content           = null;
    this.onMouseOver       = null;
    this.onMouseOut        = null;
    this.setElement        = ImagePopup_SetElement;
    this.setContent        = ImagePopup_SetContent;
    this.setMouseOver      = ImagePopup_SetMouseOver;
    this.setMouseOut       = ImagePopup_SetMouseOut;

    this.implement(DropShadowInterface);
    this.implement(CalloutInterface);
    this.implement(PopupInterface);
    this.implement(AnchoredInterface);
    this.implement(RoundedCornersInterface);
    
    this.id           = 'ImagePopup';
    this.elemId       = this.id;
    this.contentId    = this.elemId+'_content';
    this.dropShadowId = this.elemId+'_dropShadow';
    this.style       = 'Default';
    this.delay       = 500;
    this.init();
} // End ImagePopup

// Setup ImagePopup prototype chain
ImagePopup.prototype             = new BaseObject;
ImagePopup.prototype.constructor = ImagePopup;
ImagePopup.superclass            = BaseObject.prototype;









/****** BEGIN EDIT SECTION ******/

/**
 * Style definitions for ImagePopup widget.
 *
 * These style settings can be overridden by a simple variable set call.
 * Note that if you set the backgroundColor to anything other than #ffffff
 * you will most likely want to create some rounded corner images and define
 * them too.
 * 
 * Example:
 *   <?php
 *   if (!$pricegrabber_site)
 *       echo "    ImagePopup.styles.Default.term.color = '".$color."';\n";
 *   ?>
 */
ImagePopup.styles = {
    Default: {
        term: {
            font: {
                family:  'Arial, Helvetica, sans-serif',
                size:    '13px',
                weight:  'bold'
            },
            color:       '#589c1c'
        },
        font: {
            family:      'Arial, Helvetica, sans-serif',
            size:        '13px',
            weight:      'normal'
        },
        backgroundColor: '#ffffff',
        color:           '#656565'
    }
} // End ImagePopup.styles

/****** END EDIT SECTION ******/


















/**
 * Sets the DOMElement that the ImagePopup works with.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_SetElement(elem) {
    if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_SetContent() called.');
    this.elemId = elem.id;
    //this.elem = elem;
    if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_SetContent() finished.');
}

/**
 * Initializes the ImagePopup in preparation for drawing.
 *
 * Call this method before any draw methods as it handles initialization of
 * any implemented interfaces as well.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_Init() {
    //if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_Init() called.');
    var elem = document.getElementById(this.elemId);
    if (!elem) {
        elem                       = document.createElement('div');
        document.getElementsByTagName('body')[0].appendChild(elem);
        elem.id                    = this.elemId;
    }

    var content = document.getElementById(this.contentId);
    if (!content) {
        content = document.createElement('div');
        elem.appendChild(content);
        content.id = this.contentId;
    }

    elem.style.backgroundColor = ImagePopup.styles[this.style].backgroundColor;
    content.style.color        = ImagePopup.styles[this.style].color;
    content.style.fontFamily   = ImagePopup.styles[this.style].font.family;
    content.style.fontSize     = ImagePopup.styles[this.style].font.size;
    content.style.fontWeight   = ImagePopup.styles[this.style].font.weight;
 
    this.calloutPadding = 20;
    this.cornerStyle = 'Default';
    RoundedCornersInterface_Init.call(this);
    this.shadowStyle = 'Default';
    DropShadowInterface_Init.call(this);
    //if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_Init() finished.');
} // End ImagePopup_Init

/**
 * Erases the popup by removing the dom elements created in ImagePopup_Draw.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_Erase() {
    CalloutInterface_Erase.call(this);
    DropShadowInterface_Erase.call(this);
    RoundedCornersInterface_Erase.call(this);
    this.linked = new Array;
} // End ImagePopup_Erase

/**
 * Draws the image popup by creating the necessary dom elements and attaching them to the document accordingly.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_Draw() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_Draw() called.', '#ffffff', '#0000ff');
    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);

    this.linked = new Array;
    bHeight = 2;
    elem.style.border          = '1px solid '+ImagePopup.styles[this.style].backgroundColor;
    elem.style.backgroundColor = ImagePopup.styles[this.style].backgroundColor;
    elem.style.color           = ImagePopup.styles[this.style].color;
    window.addEvent(elem, 'click', this.hide, this, true);
    CalloutInterface_Draw.call(this);
    RoundedCornersInterface_Draw.call(this);
    DropShadowInterface_Draw.call(this);
    elem.style.border          = 'none';
    elem.style.backgroundColor = 'transparent';

    this.linked.push(this.dropShadowId);
    this.linked.push(this.calloutId);

/*
    var callout = document.getElementById(this.calloutId);
    if (!callout) throw new Error('Unable to find callout element: '+this.calloutId);

    var dropShadow = document.getElementById(this.dropShadowId);
    if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);


    var pos = this.getAnchorPosition();
    AnchoredInterface_AlignElement.call(this);
    if (pos == AnchoredInterface.ALIGN.LEFT_TOP || pos == AnchoredInterface.ALIGN.RIGHT_TOP) {
        callout.style.top = (parseInt(callout.style.top)-(bHeight))+'px'; // Due to removal of 1px border
        elem.style.top = (parseInt(elem.style.top)+(bHeight))+'px';
        dropShadow.style.top = elem.style.top;
    } else {
        elem.style.top = (parseInt(elem.style.top)-(bHeight*2))+'px'; // Due to removal of 1px border
        dropShadow.style.top = elem.style.top;
    }
*/
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_Draw() finished.', '#ffffff', '#0000ff');
} // End ImagePopup_Draw

/**
 * Shows the image popup on the screen.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function ImagePopup_Show() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_Show() called.', '#ffffff', '#0000ff');
    var wasVisible = this.visible;
    if (wasVisible) {
        PopupInterface_Hide.call(this);
        this.erase();
    }
    this.draw();

    var anchor     = document.getElementById(this.anchorId);
    if (!anchor)     throw new Error('Unable to find anchor element: '+this.anchorId);

    var elem       = document.getElementById(this.elemId);
    if (!elem)       throw new Error('Unable to find element: '+this.elemId);

    var dropShadow = document.getElementById(this.dropShadowId);
    if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);

    var callout    = document.getElementById(this.calloutId);
    if (!callout)    throw new Error('Unable to find callout element: '+this.calloutId);

    // Get the z-index of our anchor element
    var zIndex = parseInt(DomUtils.getZIndex(anchor));
    // If it doesn't have one make it 1000
    if (zIndex == 0) {
        zIndex = 1000;
        anchor.style.zIndex = zIndex;
    }
    dropShadow.style.zIndex = zIndex+1;
    callout.style.zIndex    = zIndex+2;
    elem.style.zIndex       = zIndex+3;

    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_Show() finished.', '#ffffff', '#0000ff');
    this.alignElement();
    PopupInterface_Show.call(this);
    return true;
} // End ImagePopup_Show

/**
 * Aligns the image popup by calling implemented interfaces' AlignElement functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_AlignElement() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_AlignElement() called.', '#ffffff', '#0000ff');
    AnchoredInterface_AlignElement.call(this);
    CalloutInterface_AlignElement.call(this);
    DropShadowInterface_AlignElement.call(this);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_AlignElement() finished.', '#ffffff', '#0000ff');
} // End ImagePopup_AlignElement

/**
 * Sets the content in the image popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_SetContent(contentString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_SetContent() called.', '#ff0000', '#ffffff');
    var content = document.getElementById(this.contentId);
    if (!content) throw new Error('Unable to find content element: '+this.contentId);
    content.innerHTML = contentString;
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_SetContent() finished.', '#ff0000', '#ffffff');
}

/**
 * Sets the onMouseOver event for the image popup.
 *
 * @access public
 * @since  v1.3
 * @param  reference  funcRef    A function reference (just the unquoted name), scope being the image popup.
 * @return void
 */
function ImagePopup_SetMouseOver(funcRef) {
    this.onMouseOver = funcRef;
}

/**
 * Sets the onMouseOut event for the image popup.
 * @access public
 * @since  v1.3
 * @param  reference  funcRef    A function reference (just the unquoted name), scope being the image popup.
 * @return void
 */
function ImagePopup_SetMouseOut(funcRef) {
    this.onMouseOut = funcRef;
}








/****** SINGLETON ACCESSORS SECTION ******/

/**
 * Singleton instance variable.
 *
 * @access public
 * @since  v1.1
 * @var    instance   ImagePopup
 */
ImagePopup.instance = null;

/**
 * Singleton accessor for retrieving the image popup instance.
 *
 * @access public
 * @since  v1.1
 * @return ImagePopup
 */
ImagePopup.getInstance = function() {
    if (!ImagePopup.instance) ImagePopup.instance = new ImagePopup();
    return ImagePopup.instance;
} // End ImagePopup.getInstance

/**
 * Singleton accessor for showing the image popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ImagePopup.show = function(anchorElement, contentString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup.show() called.', '#ff0000', '#ffff00');
    ImagePopup.getInstance().setAnchor(anchorElement);
    ImagePopup.getInstance().setContent(contentString);
    ImagePopup.getInstance().show();
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup.show() finished.', '#ff0000', '#ffff00');
} // End ImagePopup.show

/**
 * Singleton accessor for hiding the image popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ImagePopup.hide = function() {
    PopupInterface_Hide.call(ImagePopup.getInstance());
} // End ImagePopup.hide

/**
 * Singleton accessor for toggling the image popup.
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement  anchorElement
 * @param  string      contentString
 * @return void
 */
ImagePopup.toggle = function(anchorElement, contentString) {
    if (ImagePopup.getInstance().visible) ImagePopup.hide();
    else                                  ImagePopup.show(anchorElement, contentString);
}

/**
 * $Id: reportreviewpopup.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire classes.BaseObject
 * @jsRequire classes.EventManager
 * @jsRequire interfaces.DropShadowInterface
 * @jsRequire interfaces.CalloutInterface
 * @jsRequire interfaces.DelayedPopupInterface
 *
 *
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        classes.BaseObject
 * @see        interfaces.DropShadowInterface
 * @see        interfaces.CalloutInterface
 * @see        interfaces.DelayedPopupInterface
 */

/**
 * ReportReviewPopup Constructor / ReportReview
 *
 * This is NOT intended to be instantiated directly. Instead, use the
 * singleton accessor methods ReportReviewPopup.getInstance(),
 * ReportReviewPopup.show(), ReportReviewPopup.hide() and ReportReviewPopup.toggle().
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement       anchor
 * @return ReportReviewPopup
 */
function ReportReviewPopup(anchor) {
    this.elemId            = null;
//    this.elem              = null;
    // Callout interface implementation
    this.calloutId         = null;
//    this.callout           = null;
    this.calloutPadding    = 0;
    // Drop shadow interface implementation
    this.dropShadowId      = null;
//    this.dropShadow        = null;
    this.color             = null;
    this.xOffset           = null;
    this.yOffset           = null;
    this.blur              = { iRadius: null, iSigma: null };
    this.opacity           = null;
    this.xShrink           = null;
    this.yShrink           = null;
    this.shadowStyle       = null;
    this.images            = new Array;
    this.setBlur           = DropShadowInterface_SetBlur;
    // Delayed popup interface implementation
    this.timer             = null;
    this.visible           = false;
    this.delay             = null;
    this.linked            = new Array;
    this.cancelTimer       = DelayedPopupInterface_CancelTimer;
    this.hide              = DelayedPopupInterface_Hide;
    this.toggle            = PopupInterface_Toggle;
    // Anchored interface implementation
    this.anchorId          = null;
//    this.anchor            = anchor || null;
    this.getAnchorX        = AnchoredInterface_GetAnchorX;
    this.getAnchorY        = AnchoredInterface_GetAnchorY;
    this.getAnchorZ        = AnchoredInterface_GetAnchorZ;
    this.getAnchorWidth    = AnchoredInterface_GetAnchorWidth;
    this.getAnchorHeight   = AnchoredInterface_GetAnchorHeight;
    this.getAnchorPosition = AnchoredInterface_GetAnchorPosition;
    this.getElemWidth      = AnchoredInterface_GetElemWidth;
    this.getElemHeight     = AnchoredInterface_GetElemHeight;
    this.setAnchor         = AnchoredInterface_SetAnchor;
    this.disableScroll     = true;
    // Rounded corners interface implementation
//    this.cornerStyle       = null;
//    this.cornersDrawn      = false;
    // Drop shadow interface && Callout interface joint implementation
    this.erase             = ReportReviewPopup_Erase;
    this.draw              = ReportReviewPopup_Draw;
    this.init              = ReportReviewPopup_Init;
    // Drop shadow interface && Delayed popup interface joint implementation
    this.show              = ReportReviewPopup_Show;
    // Drop shadow interface && Anchored interface joint implementation
    this.alignElement      = ReportReviewPopup_AlignElement;
    
    this.def               = null;
    this.term              = null;
    this.setElement        = ReportReviewPopup_SetElement;
    this.setDefinition     = ReportReviewPopup_SetDefinition;
    this.setTerm           = ReportReviewPopup_SetTerm;
    this.setTermColor      = ReportReviewPopup_SetTermColor;

    this.implement(DropShadowInterface);
    this.implement(CalloutInterface);
    this.implement(DelayedPopupInterface);
    this.implement(AnchoredInterface);
//    this.implement(RoundedCornersInterface);
    
    this.id    = 'ReportReviewPopup';
    this.style = 'Default';
    this.delay = 0;
    this.init();
} // End ReportReviewPopup

// Setup ReportReviewPopup prototype chain
ReportReviewPopup.prototype             = new BaseObject;
ReportReviewPopup.prototype.constructor = ReportReviewPopup;
ReportReviewPopup.superclass            = BaseObject.prototype;









/****** BEGIN EDIT SECTION ******/

/**
 * Style definitions for ReportReviewPopup widget.
 *
 * These style settings can be overridden by a simple variable set call.
 * Note that if you set the backgroundColor to anything other than #ffffff
 * you will most likely want to create some rounded corner images and define
 * them too.
 * 
 * Example:
 *   <?php
 *   if (!$pricegrabber_site)
 *       echo "    ReportReviewPopup.styles.Default.term.color = '".$color."';\n";
 *   ?>
 */
ReportReviewPopup.styles = {
    Default: {
        term: {
            font: {
                family:  'Verdana, Arial, Helvetica, sans-serif',
                size:    '11px',
                weight:  'bold'
            },
            color:       '#589c1c'
        },
        font: {
            family:      'Verdana, Arial, Helvetica, sans-serif',
            size:        '11px',
            weight:      'normal'
        },
        backgroundColor: '#ffffff',
		borderColor: '#E9E9E9',
        weight:  'bold',
        color:           '#000000'
    }
} // End ReportReviewPopup.styles

/****** END EDIT SECTION ******/



/**
 * Sets the DOMElement that the ReportReviewPopup works with.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetElement(elem) {
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_SetContent() called.');
    //this.elem = elem;
    this.elemId = elem.id;
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_SetContent() finished.');
}

/**
 * Initializes the ReportReviewPopup in preparation for drawing.
 *
 * Call this method before any draw methods as it handles initialization of
 * any implemented interfaces as well.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_Init() {
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_Init() called.');
    //this.elem                       = document.createElement('div');
    var elem = document.createElement('div');
    document.getElementsByTagName('body')[0].appendChild(elem);
    //this.elem.id                    = 'report_review_content';
    this.elemId = 'report_review_content';
    elem.id = this.elemId;
    //this.elem.style.backgroundColor = ReportReviewPopup.styles[this.style].backgroundColor;
    elem.style.backgroundColor = ReportReviewPopup.styles[this.style].backgroundColor;
    
    //this.term                       = document.createElement('span');
    var term = document.createElement('span');
    //this.term.id                    = this.id+'_term';
    this.termId = this.elemId+'_term';
    term.id = this.termId;
    if (typeof(writeDebug) == 'function') writeDebug('style name: '+this.style+"\ncolor: "+ReportReviewPopup.styles[this.style].term.color);
    term.style.color           = ReportReviewPopup.styles[this.style].term.color;
    term.style.paddingBottom   = '5px';
    term.style.fontFamily      = ReportReviewPopup.styles[this.style].term.font.family;
    term.style.fontSize        = ReportReviewPopup.styles[this.style].term.font.size;
    term.style.fontWeight      = ReportReviewPopup.styles[this.style].term.font.weight;
//    term.style.backgroundColor  = "#ffffff";
    elem.appendChild(term);
    
    //this.def                        = document.createElement('div');
    var def = document.createElement('div');
    //this.def.id                     = this.id+'_def';
    this.defId = this.elemId+'_def';
    def.id = this.defId;
    def.style.color            = ReportReviewPopup.styles[this.style].color;
    def.style.fontFamily       = ReportReviewPopup.styles[this.style].font.family;
    def.style.fontSize         = ReportReviewPopup.styles[this.style].font.size;
    def.style.fontWeight       = ReportReviewPopup.styles[this.style].font.weight;
//    this.def.style.backgroundColor  = "#ffffff";
    elem.appendChild(def);
    
    this.calloutPadding = 10;
    this.cornerStyle = 'Default';
//    RoundedCornersInterface_Init.call(this);
    this.shadowStyle = 'Default';
    DropShadowInterface_Init.call(this);
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_Init() finished.');
} // End ReportReviewPopup_Init

/**
 * Erases the definition popup by removing the dom elements created in ReportReviewPopup_Draw.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_Erase() {
    CalloutInterface_Erase.call(this);
    DropShadowInterface_Erase.call(this);
//    RoundedCornersInterface_Erase.call(this);
    this.linked = new Array;
} // End ReportReviewPopup_Erase

/**
 * Draws the definition popup by creating the necessary dom elements and attaching them to the document accordingly.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_Draw() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_Draw() called.', '#ffffff', '#0000ff');
    this.linked = new Array;

    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);
    var anchor = document.getElementById(this.anchorId);
    if (!anchor) throw new Error('Unable to find anchor element: '+this.anchorId);

    bHeight = 2;
    elem.style.border = '1px solid '+ReportReviewPopup.styles[this.style].borderColor;
    elem.style.backgroundColor = ReportReviewPopup.styles[this.style].backgroundColor;
    elem.style.color = ReportReviewPopup.styles[this.style].color;
//    RoundedCornersInterface_Draw.call(this);
//    CalloutInterface_Draw.call(this);

    var pos = this.getAnchorPosition();

    var aLeft   = DomUtils.getElementLeft(anchor);
    var aTop    = DomUtils.getElementTop(anchor);
    var aHeight = DomUtils.getElementHeight(anchor);
    var aWidth  = DomUtils.getElementWidth(anchor);
    var eHeight = DomUtils.getElementHeight(elem);
    var eWidth  = DomUtils.getElementWidth(elem);
    switch (pos) {
        case AnchoredInterface.ALIGN.RIGHT_TOP:
            elem.style.left = parseInt(aLeft)+'px';
            elem.style.top  = parseInt(aTop-eHeight - 8)+'px';
            break;
        case AnchoredInterface.ALIGN.RIGHT_BOTTOM:
            elem.style.left = parseInt(aLeft)+'px';
            elem.style.top  = parseInt(aTop+aHeight + 8)+'px';
            break;
        case AnchoredInterface.ALIGN.LEFT_TOP:
            elem.style.left = parseInt(aLeft+aWidth-eWidth)+'px';
            elem.style.top  = parseInt(aTop-eHeight)+'px';
            break;
        case AnchoredInterface.ALIGN.LEFT_BOTTOM:
        default:
            elem.style.left = parseInt(aLeft+aWidth-eWidth)+'px';
            elem.style.top  = parseInt(aTop+aHeight)+'px';
            break;
    }
	
    DropShadowInterface_Draw.call(this);
    window.addEvent(elem, 'mouseover', this.cancelTimer, this, true);
    window.addEvent(elem, 'mouseout',  this.hide,        this, true);
//    this.elem.style.borderWidth = '1px';
//    this.elem.style.border = 'solid';
//    this.elem.style.backgroundColor = 'white';
    //this.linked.push(this.dropShadow);
    this.linked.push(this.dropShadowId);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_Draw() finished.', '#ffffff', '#0000ff');
} // End ReportReviewPopup_Draw

/**
 * Shows the definition popup on the screen.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function ReportReviewPopup_Show() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_Show() called.', '#ffffff', '#0000ff');
    this.cancelTimer();

    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);
    var anchor = document.getElementById(this.anchorId);
    if (!anchor) throw new Error('Unable to find anchor element: '+this.anchorId);

//    if (!this.anchor) {
//        throw new Error('ReportReviewPopup.anchor not set, unable to show.');
//        return false;
//    }
    var wasVisible = this.visible;
    if (this.visible) PopupInterface_Hide.call(this);
    if (!this.visible) {
        this.erase();
//        this.elem.style.zIndex       = parseInt(this.getAnchorZ()+3); // +3 so the drop shadow & rounded corner content has room
        elem.style.zIndex       = parseInt(DomUtils.getZIndex(elem)+3); // +3 so the drop shadow & rounded corner content has room
        this.draw();
//        this.callout.style.zIndex    = parseInt(DomUtils.getZIndex(this.elem))-1;
        var dropShadow = document.getElementById(this.dropShadowId);
        if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);
        dropShadow.style.zIndex = parseInt(DomUtils.getZIndex(elem))-2;
        if (wasVisible) PopupInterface_Show.call(this);
        else            DelayedPopupInterface_Show.call(this);
    }
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_Show() finished.', '#ffffff', '#0000ff');
    return true;
} // End ReportReviewPopup_Show

/**
 * Aligns the definition popup by calling implemented interfaces' AlignElement functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_AlignElement(pos) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_AlignElement() called.', '#ffffff', '#0000ff');
    CalloutInterface_AlignElement.call(this, pos);
    DropShadowInterface_AlignElement.call(this, pos);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_AlignElement() finished.', '#ffffff', '#0000ff');
} // End ReportReviewPopup_AlignElement

/**
 * Sets the definition in the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetDefinition(definitionString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_SetDefinition() called.', '#ff0000', '#ffffff');
    var def = document.getElementById(this.defId);
    if (!def) throw new Error('Unable to find definition element: '+this.defId);
    def.innerHTML = definitionString;
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_SetDefinition() finished.', '#ff0000', '#ffffff');
}

/**
 * Sets the term in the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetTerm(termString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_SetTerm() called.', '#ff0000', '#ffffff');
    var term = document.getElementById(this.termId);
    if (!term) throw new Error('Unable to find term element: '+this.termId);

    while (term.hasChildNodes()) term.removeChild(term.firstChild);
    var txtTerm = document.createTextNode(termString);
    term.appendChild(txtTerm);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_SetTerm() finished.', '#ff0000', '#ffffff');
}

/**
 * Sets the term color of the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetTermColor(color) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_SetTermColor() called.', '#ff0000', '#ffffff');
    var term = document.getElementById(this.termId);
    if (!term) throw new Error('Unable to find term element: '+this.termId);
    term.style.color = color;
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_SetTermColor() finished.', '#ff0000', '#ffffff');
}



/****** SINGLETON ACCESSORS SECTION ******/

/**
 * Singleton instance variable.
 *
 * @access public
 * @since  v1.1
 * @var    instance   ReportReviewPopup
 */
ReportReviewPopup.instance = null;

/**
 * Singleton accessor for retrieving the definition popup instance.
 *
 * @access public
 * @since  v1.1
 * @return ReportReviewPopup
 */
ReportReviewPopup.getInstance = function() {
    if (!ReportReviewPopup.instance) ReportReviewPopup.instance = new ReportReviewPopup();
    return ReportReviewPopup.instance;
} // End ReportReviewPopup.getInstance

/**
 * Singleton accessor for initializing the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
//ReportReviewPopup.initInstance = function() {
//    if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup.init() called.', '#ff0000', '#ffff00');
//    ReportReviewPopup.instance = new ReportReviewPopup();
//    if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup.init() finished.', '#ff0000', '#ffff00');
//} // End ReportReviewPopup.init

/**
 * Singleton accessor for showing the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ReportReviewPopup.show = function(anchorElement, termString, definitionString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup.show() called.', '#ff0000', '#ffff00');
    ReportReviewPopup.getInstance().setAnchor(anchorElement);
    ReportReviewPopup.getInstance().setDefinition(definitionString);
    ReportReviewPopup.getInstance().setTerm(termString);
    ReportReviewPopup_Show.call(ReportReviewPopup.getInstance());
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup.show() finished.', '#ff0000', '#ffff00');
} // End ReportReviewPopup.show

/**
 * Singleton accessor for hiding the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ReportReviewPopup.hide = function() {
    DelayedPopupInterface_Hide.call(ReportReviewPopup.getInstance());
} // End ReportReviewPopup.hide

/**
 * Singleton accessor for toggling the definition popup.
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement  anchorElement
 * @param  string      termString
 * @param  string      definitionString
 * @return void
 */
ReportReviewPopup.toggle = function(anchorElement, termString, definitionString) {
    if (ReportReviewPopup.getInstance().visible) ReportReviewPopup.hide();
    else                                         ReportReviewPopup.show(anchorElement, termString, definitionString);
}
/* http://youngpup.net/2001/ypslideoutmenus */
var ypSlideOutMenuRegistry=[]; // global var

var ypSlideOutMenuConfig = new Array(); // global var
	ypSlideOutMenuConfig['aniLen'] = 250;
	ypSlideOutMenuConfig['hideDelay'] = 1000;
	ypSlideOutMenuConfig['minCPUResolution'] = 10;

function ypSlideOutMenu(id, _2, _3, _4, _5, _6) {
	
	this.selectedIndex;
	this.ie = document.all ? 1:0;
	this.ns4 = document.layers ? 1:0;
	this.dom = document.getElementById ? 1:0;
	if (this.ie || this.ns4 || this.dom) {
		this.id = id;
		this.dir = _2;
		this.orientation =_2 == "left" || _2 == "right" ? "h" : "v";
		this.dirType = _2 == "right" || _2 == "down" ? "-" : "+";
		this.dim = this.orientation == "h" ? _5 : _6;
		this.hideTimer = false;
		this.aniTimer = false;
		this.open = false;
		this.over = false;
		this.startTime = 0;
		this.gRef = "ypSlideOutMenu_"+ id;
		eval(this.gRef + "=this");
		ypSlideOutMenuRegistry[id] = this;
		
		this.cssFuncBody = "var elContainer = document.getElementById(elContainerId);\n"
		+"var elContent = document.getElementById(elContentId);\n"
		+"elContainer.style.visibility = 'hidden';\n"
		+"elContainer.style.left = '"+ _3 +"px';\n"
		+"elContainer.style.top = '"+ _4 +"px';\n"
		+"elContainer.style.overflow = 'hidden';\n"
		+"elContainer.style.zIndex = '10000';\n"
		+"elContainer.style.position = 'absolute';\n"
		+"elContainer.style.width = '"+ _5 +"px';\n"
		+"elContainer.style.height = '"+ _6 +"px';\n"
		+"elContainer.style.clip = 'rect(0px, "+ (_5 + 2) +"px, "+ (_6 + 2) +"px, 0px)';\n"
		
		+"elContent.style.position = 'absolute';\n"
		+"elContent.style.width = '"+ _5 +"px';\n"
		+"elContent.style.height = '"+ _6 +"px';\n"
		+"elContent.style.clip = 'rect(0px, "+ _5 +"px, "+ _6 +"px, 0px)';\n"
		
		this.load();
	}
}

ypSlideOutMenu.prototype.load = function() {
	
	var d = document;
	var _10 = this.id +"Container";
	var _11 = this.id +"Content";
	
	var cssFunc = new Function('elContainerId', 'elContentId', this.cssFuncBody);
	
	// defines css for menus
	cssFunc(_10, _11);
	
	var _12 = this.dom ? d.getElementById(_10):
	this.ie ? d.all[_10] : d.layers[_10];
	if (_12) {
		var _13 = this.ns4 ? _12.layers[_11] : this.ie ? d.all[_11] : d.getElementById(_11);
	}
	var _14;
	if (!_12 || !_13) {
		window.setTimeout(this.gRef +".load()", 100);
	}
	else {
		this.container = _12;
		this.menu = _13;
		this.style = this.ns4 ? this.menu : this.menu.style;
		this.homePos = eval("0"+ this.dirType + this.dim);
		this.outPos = 0;
		this.accelConst = (this.outPos - this.homePos) /ypSlideOutMenuConfig['aniLen'] /ypSlideOutMenuConfig['aniLen'];
		if (this.ns4) {
			this.menu.captureEvents(Event.MOUSEOVER|Event.MOUSEOUT);
		}
		this.menu.onmouseover = new Function("ypSlideOutMenu.showMenu('"+ this.id +"')");
		this.menu.onmouseout = new Function("ypSlideOutMenu.hideMenu('"+ this.id +"')");
		this.endSlide();
	}
};

ypSlideOutMenu.repositionMenu = function(id, left, top) {

	var obj = ypSlideOutMenuRegistry[id];
	
	if (obj) {
		objStyle = this.ns4 ? obj.container : obj.container.style;
		if (objStyle) {
			objStyle.left = left + 'px';
			objStyle.top = top + 'px';
		}
	}
};
ypSlideOutMenu.showMenu = function(id) { 
	
	var obj = ypSlideOutMenuRegistry[id];
	
	if (obj.container) {
		
		ypSlideOutMenu.resetHandlers(id)
		
		obj.over = true;
		
		// hide menus
		
		for (menu in ypSlideOutMenuRegistry) {
			
			if (ypSlideOutMenuRegistry[menu]) {
				if (id != menu) {
					ypSlideOutMenu.hide(menu);
				}
			}
		}
		if (obj.hideTimer) {
			obj.hideTimer = window.clearTimeout(obj.hideTimer);
		}
		if (! obj.open && ! obj.aniTimer ) {
			obj.startSlide(true);
		}
	}
};
ypSlideOutMenu.hideMenu = function(id) {
	var obj = ypSlideOutMenuRegistry[id];
	if (obj.container) {
		if (obj.hideTimer) {
			window.clearTimeout(obj.hideTimer);
		}
		obj.hideTimer = window.setTimeout("ypSlideOutMenu.hide('"+ id +"')", ypSlideOutMenuConfig['hideDelay']);
	}
};
ypSlideOutMenu.resetHandlers = function(id) {
	var obj = ypSlideOutMenuRegistry[id];
	if (obj.container) {
		if (! obj.menu.onmouseover) {
			obj.menu.onmouseover = new Function("ypSlideOutMenu.showMenu('"+ id +"')");
		}
		if (! obj.menu.onmouseout) {
			obj.menu.onmouseout = new Function("ypSlideOutMenu.hideMenu('"+ id +"')");
		}
	}
};
ypSlideOutMenu.setSelectedIndex = function(id, index) {
	var obj = ypSlideOutMenuRegistry[id];
	if (obj.container) {
		obj.selectedIndex = index;
	}
};
ypSlideOutMenu.hideMenuAfterSelection = function(id) {
	var obj = ypSlideOutMenuRegistry[id];
	if (obj.container) {
		if (obj.hideTimer) {
			window.clearTimeout(obj.hideTimer);
		}		
		// nullify event handlers
		obj.menu.onmouseover = null;
		obj.menu.onmouseout = null;
		
		ypSlideOutMenu.hide(id);
		
		obj.hideTimer = window.setTimeout("ypSlideOutMenu.resetHandlers('"+ id +"')", 500);
		
	}
};
ypSlideOutMenu.hideAll = function() {
	var reg = ypSlideOutMenuRegistry;
	for(menu in reg) { 
		ypSlideOutMenu.hide(menu);
		if (menu.hideTimer) {
			window.clearTimeout(menu.hideTimer);
		}
	}
};
ypSlideOutMenu.hide = function(id) {
	var obj = ypSlideOutMenuRegistry[id];
	obj.over = false;
	if (obj.hideTimer) {
		window.clearTimeout(obj.hideTimer);
	}
	obj.hideTimer=0;
	if (obj.open&&!obj.aniTimer) { 
		obj.startSlide(false);
	}
};
ypSlideOutMenu.prototype.startSlide = function(_21) {
	this[_21?"onactivate":"ondeactivate"]();
	this.open=_21;
	if (_21) {
		this.setVisibility(true);
	}
	this.startTime = (new Date()).getTime();
	this.aniTimer = window.setInterval(this.gRef+".slide()", ypSlideOutMenuConfig['minCPUResolution']);
};
ypSlideOutMenu.prototype.slide = function() {
	var _22 = (new Date()).getTime() - this.startTime;
	if (_22 > ypSlideOutMenuConfig['aniLen']) {
		this.endSlide();
	}
	else {
		var d = Math.round(Math.pow(ypSlideOutMenuConfig['aniLen']-_22,2)*this.accelConst);
		if (this.open && this.dirType == "-") {
			d =- d;
		}
		else {
			if (this.open && this.dirType == "+") {
				d =- d;
			}
			else {
				if (!this.open && this.dirType == "-") {
					d =- this.dim + d;
				}
				else {
					d = this.dim + d;
				}
			}
		}
		this.moveTo(d);
	}
};
ypSlideOutMenu.prototype.endSlide = function() { 
	this.aniTimer = window.clearTimeout(this.aniTimer);
	this.moveTo(this.open ? this.outPos : this.homePos);
	if (!this.open) {
		this.setVisibility(false);
	}
	if ((this.open && !this.over) || (!this.open && this.over)) {
		this.startSlide(this.over);
	}
};
ypSlideOutMenu.prototype.setVisibility = function(_24) {
	var s = this.ns4 ? this.container : this.container.style;
	s.visibility = _24 ? 'visible' : 'hidden';
};
ypSlideOutMenu.prototype.moveTo = function(p) {
	this.style[this.orientation == 'h' ? 'left' : 'top'] = this.ns4 ? p : p +"px";
};
ypSlideOutMenu.prototype.getPos = function(c) {
	return parseInt(this.style[c]);
};
ypSlideOutMenu.prototype.onactivate = function() {};
ypSlideOutMenu.prototype.ondeactivate = function() {};/* Omniture H.20.3 code */

var om_track = "prop1,prop3,prop7,prop5,prop6,prop9,prop10,prop11,prop13,prop16,prop20,prop32,prop34,prop41,prop42,prop43,prop46,eVar5,eVar6,eVar12,eVar13,eVar14,eVar16,eVar17,eVar18,eVar20,eVar25,eVar26,eVar38,eVar44,eVar46,eVar47,eVar48,s_products,s_purchaseID,events";
var om_events="purchase,event2,event11";

function om_clear_s_history(){
        if(typeof(s) == 'object'){
           // dumped_text = '';
           for(var item in s) {
              var value = s[item];
              if(typeof(value) == 'string' && ( /^(prop|eVar)[0-9]{1,2}$/i.test(item) || item=='pageName' || item=='pageType') ){
                 // dumped_text += "'" + item + "' => \"" + value + "\"\n";
                 delete s[item];
              }
           }
           // alert(dumped_text);
        }
}

function om_H_link_p(reportsuite_ids, propname, propval, linkName, VisitorID) {
        om_clear_s_history();
	s = s_gi(reportsuite_ids); 
	s[propname] = propval;
	s.linkTrackVars=om_track+","+propname;
	s.linkTrackEvents=om_events;
	if (VisitorID) {
		s.visitorID = VisitorID;
	}
	s.tl(true, 'o', linkName);
}

function om_G_link_p(reportsuite_ids, propname, propval, linkName) {
	eval("s_"+propname+"='"+propval+"';");
	s_linkTrackVars=om_track;
	s_linkType = 'o';
	s_linkName = linkName;
	// s_link = s_co(this);
	s_lnk = s_co(this);
	s_gs(reportsuite_ids); 
}

function om_H_link_multi_p(reportsuite_ids, props, linkName, visitorId) {
        om_clear_s_history();
	s = s_gi(reportsuite_ids);
	s.linkTrackVars=om_track;
	s.linkTrackEvents=om_events;
	for (key in props) {
		s[key] = props[key];
		s.linkTrackVars=s.linkTrackVars+","+key;
	}
	if (visitorId) {
		s.visitorID = visitorId;
	}
	s.tl(true, 'o', linkName);
}
 	
function goToLink(loc) {
	//setTimeout("goToLink('"+ href +"')", 500);
	//alert('GO TO LINK: '+ loc);
	window.location = loc;
}

function om_dual_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_G_link_p(reporting_suite, propname, propval, linkName);
	om_H_link_p(override_suite, propname, propval, linkName, VisitorID);
}

// Both H - neither UT
function om_doubleH_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_H_link_p(reporting_suite, propname, propval, linkName);
	om_H_link_p(override_suite, propname, propval, linkName);
}

// Both H - both UT
function om_doubleHut_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_H_link_p(reporting_suite, propname, propval, linkName, VisitorID);
	om_H_link_p(override_suite, propname, propval, linkName, VisitorID);
}

// Both H - primary UT
function om_doublePut_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_H_link_p(reporting_suite, propname, propval, linkName, VisitorID);
	om_H_link_p(override_suite, propname, propval, linkName);
}

//Both H - override UT
function om_doubleOut_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_H_link_p(reporting_suite, propname, propval, linkName);
	om_H_link_p(override_suite, propname, propval, linkName, VisitorID);
}

function om_single_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_G_link_p(reporting_suite, propname, propval, linkName);
}

function om_singleH_link(reporting_suite, override_suite, propname, propval, linkName, VisitorID) {
	om_H_link_p(reporting_suite, propname, propval, linkName, VisitorID);
}

// Multiple params
function om_singleH_mlink(reporting_suite, override_suite, VisitorID, props, linkName, linkto) {
	om_H_link_multi_p(reporting_suite, props, linkName, VisitorID);
	if (linkto) {
		goToLink(linkto); }
}

// Multiple Params - Both H - neither UT
function om_doubleH_mlink(reporting_suite, override_suite, VisitorID, props, linkName, linkto) {
	om_H_link_multi_p(reporting_suite, props, linkName);
	om_H_link_multi_p(override_suite, props, linkName);
	if (linkto) {
		goToLink(linkto); }
}

// Multiple Params - Both H - both UT
function om_doubleHut_mlink(reporting_suite, override_suite, VisitorID, props, linkName, linkto) {
	om_H_link_multi_p(reporting_suite, props, linkName, VisitorID);
	om_H_link_multi_p(override_suite, props, linkName, VisitorID);
	if (linkto) {
		goToLink(linkto); }
}

// Multiple Params - Both H - primary UT
function om_doublePut_mlink(reporting_suite, override_suite, VisitorID, props, linkName, linkto) {
	om_H_link_multi_p(reporting_suite, props, linkName, VisitorID);
	om_H_link_multi_p(override_suite, props, linkName);
	if (linkto) {
		goToLink(linkto); }
}

// Multiple Params - Both H - override UT
function om_doubleOut_mlink(reporting_suite, override_suite, VisitorID, props, linkName, linkto) {
	om_H_link_multi_p(reporting_suite, props, linkName);
	om_H_link_multi_p(override_suite, props, linkName, VisitorID);
	if (linkto) {
		goToLink(linkto); }
}


function om_setup(s, charSet, currencyCode) {
s.charSet=charSet;
s.currencyCode=currencyCode;
/* Link Tracking Config */
s.trackDownloadLinks=true
s.trackExternalLinks=true
s.trackInlineStats=true
s.linkDownloadFileTypes="exe,zip,wav,mp3,mov,mpg,avi,wmv,doc,pdf,xls"
s.linkInternalFilters="javascript:,bottomdollar,pricegrabber"
s.linkLeaveQueryString=false;
s.linkTrackVars=om_track;
s.linkTrackEvents=om_events;

/* WARNING: Changing any of the below variables will cause drastic
changes to how your visitor data is collected.  Changes should only be
made when instructed to do so by your account manager.*/
s.dc=112;

/* Plugins Section */

s.usePlugins=true;
s.doPlugins=s_do_H_Plugins;

/************************** PLUGINS SECTION *************************/
/* You may insert any plugins you wish to use here.                 */

/*
* TNT Integration Pluginv1.0
* v -Name of the javascriptvariable that is used. Defaults to s_tnt(optional)
* p -Name of the urlparameter. Defaults to s_tnt(optional)
* b -Blank Global variable after pluginruns. Defaults to true (Optional)
*/
s.trackTNT= function(v, p, b)
{
vars=this, n="s_tnt", p=(p)?p:n, v=(v)?v:n, r="",pm=false, b=(b)?b:true;
if(s.getQueryParam)
pm = s.getQueryParam(p); //grab the parameter
if(pm)
r += (pm + ","); // append the parameter
if(s.wd[v] != undefined)
r += s.wd[v]; // get the global variable
if(b)
s.wd[v] = ""; // Blank out the global variable for ajaxrequests
return r;
}

/*
 * Plugin: getQueryParam 2.3
 */
s.getQueryParam=new Function("p","d","u",""
+"var s=this,v='',i,t;d=d?d:'';u=u?u:(s.pageURL?s.pageURL:s.wd.locati"
+"on);if(u=='f')u=s.gtfs().location;while(p){i=p.indexOf(',');i=i<0?p"
+".length:i;t=s.p_gpv(p.substring(0,i),u+'');if(t){t=t.indexOf('#')>-"
+"1?t.substring(0,t.indexOf('#')):t;}if(t)v+=v?d+t:t;p=p.substring(i="
+"=p.length?i:i+1)}return v");
s.p_gpv=new Function("k","u",""
+"var s=this,v='',i=u.indexOf('?'),q;if(k&&i>-1){q=u.substring(i+1);v"
+"=s.pt(q,'&','p_gvf',k)}return v");
s.p_gvf=new Function("t","k",""
+"if(t){var s=this,i=t.indexOf('='),p=i<0?t:t.substring(0,i),v=i<0?'T"
+"rue':t.substring(i+1);if(p.toLowerCase()==k.toLowerCase())return s."
+"epa(v)}return ''");

/*
 * Plugin: getNewRepeat
 */
s.getNewRepeat=new Function(""
+"var s=this,e=new Date(),cval,ct=e.getTime(),y=e.getYear();e.setTime"
+"(ct+30*24*60*60*1000);cval=s.c_r('s_nr');if(cval.length==0){s.c_w("
+"'s_nr',ct,e);return 'New';}if(cval.length!=0&&ct-cval<30*60*1000){s"
+".c_w('s_nr',ct,e);return 'New';}if(cval<1123916400001){e.setTime(cv"
+"al+30*24*60*60*1000);s.c_w('s_nr',ct,e);return 'Repeat';}else retur"
+"n 'Repeat';");

}

function s_do_H_Plugins(s) {
	/* Add calls to plugins here */
	/* s.campaign=s.getQueryParam('source');*/
	s.eVar28=s.getNewRepeat();
	s.prop27=s.eVar28;
	/* Omniture Test&Target */
	s.tnt=s.trackTNT();
}

function om_cookie(s, cookie_host) {
if (navigator.cookieEnabled) {
	var theCookie = "event1H=";
	var allcookies = document.cookie;
	var pos = allcookies.indexOf(theCookie);
	if (pos != -1)
	{
    	var start = pos + theCookie.length;
		var end = allcookies.indexOf(";", start);
		if (end == -1) end = allcookies.length;
		var value = allcookies.substring(start, end);
		value = unescape(value);
	}
	if (value=="1")
	{
		document.cookie = "event1H=2;path=/;domain="+cookie_host+";";
	}
	else
	{
		if (s.events) {
			var myArray = s.events.split(",");
			var new_s_events = new Array();
			for (var i= 0; i<myArray.length; i++)
			{
				if (myArray[i]!="event1") new_s_events[new_s_events.length] = myArray[i];
			}
			s.events = new_s_events.join(",");
		}
	}
}
}

/* SiteCatalyst code version: H.20.3.
Copyright 1997-2009 Omniture, Inc. More info available at
http://www.omniture.com */

/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code='',s_objectID;function s_gi(un,pg,ss){var c="s._c='s_c';s.wd=window;if(!s.wd.s_c_in){s.wd.s_c_il=new Array;s.wd.s_c_in=0;}s._il=s.wd.s_c_il;s._in=s.wd.s_c_in;s._il[s._in]=s;s.wd.s_c_in++;s"
+".an=s_an;s.cls=function(x,c){var i,y='';if(!c)c=this.an;for(i=0;i<x.length;i++){n=x.substring(i,i+1);if(c.indexOf(n)>=0)y+=n}return y};s.fl=function(x,l){return x?(''+x).substring(0,l):x};s.co=func"
+"tion(o){if(!o)return o;var n=new Object,x;for(x in o)if(x.indexOf('select')<0&&x.indexOf('filter')<0)n[x]=o[x];return n};s.num=function(x){x=''+x;for(var p=0;p<x.length;p++)if(('0123456789').indexO"
+"f(x.substring(p,p+1))<0)return 0;return 1};s.rep=s_rep;s.sp=s_sp;s.jn=s_jn;s.ape=function(x){var s=this,h='0123456789ABCDEF',i,c=s.charSet,n,l,e,y='';c=c?c.toUpperCase():'';if(x){x=''+x;if(c=='AUTO"
+"'&&('').charCodeAt){for(i=0;i<x.length;i++){c=x.substring(i,i+1);n=x.charCodeAt(i);if(n>127){l=0;e='';while(n||l<4){e=h.substring(n%16,n%16+1)+e;n=(n-n%16)/16;l++}y+='%u'+e}else if(c=='+')y+='%2B';"
+"else y+=escape(c)}x=y}else{x=x?s.rep(escape(''+x),'+','%2B'):x;if(x&&c&&s.em==1&&x.indexOf('%u')<0&&x.indexOf('%U')<0){i=x.indexOf('%');while(i>=0){i++;if(h.substring(8).indexOf(x.substring(i,i+1)."
+"toUpperCase())>=0)return x.substring(0,i)+'u00'+x.substring(i);i=x.indexOf('%',i)}}}}return x};s.epa=function(x){var s=this;return x?unescape(s.rep(''+x,'+',' ')):x};s.pt=function(x,d,f,a){var s=th"
+"is,t=x,z=0,y,r;while(t){y=t.indexOf(d);y=y<0?t.length:y;t=t.substring(0,y);r=s[f](t,a);if(r)return r;z+=y+d.length;t=x.substring(z,x.length);t=z<x.length?t:''}return ''};s.isf=function(t,a){var c=a"
+".indexOf(':');if(c>=0)a=a.substring(0,c);if(t.substring(0,2)=='s_')t=t.substring(2);return (t!=''&&t==a)};s.fsf=function(t,a){var s=this;if(s.pt(a,',','isf',t))s.fsg+=(s.fsg!=''?',':'')+t;return 0}"
+";s.fs=function(x,f){var s=this;s.fsg='';s.pt(x,',','fsf',f);return s.fsg};s.si=function(wd){var s=this,c=''+s_gi,a=c.indexOf(\"{\"),b=c.lastIndexOf(\"}\"),m;c=s_fe(a>0&&b>0?c.substring(a+1,b):0);if"
+"(wd&&wd.document&&c){wd.setTimeout('function s_sv(o,n,k){var v=o[k],i;if(v){if(typeof(v)==\"string\"||typeof(v)==\"number\")n[k]=v;else if (typeof(v)==\"array\"){n[k]=new Array;for(i=0;i<v.length;i"
+"++)s_sv(v,n[k],i)}else if (typeof(v)==\"object\"){n[k]=new Object;for(i in v)s_sv(v,n[k],i)}}}function s_si(t){var wd=window,s,i,j,c,a,b;wd.s_gi=new Function(\"un\",\"pg\",\"ss\",\"'+c+'\");wd.s=s_"
+"gi(\"'+s.oun+'\");s=wd.s;s.sa(\"'+s.un+'\");s.tfs=wd;s.pt(s.vl_g,\",\",\"vo1\",t);s.lnk=s.eo=s.linkName=s.linkType=s.wd.s_objectID=s.ppu=s.pe=s.pev1=s.pev2=s.pev3=\\'\\';if(t.m_l&&t.m_nl)for(i=0;i<"
+"t.m_nl.length;i++){n=t.m_nl[i];if(n){m=t[n];c=t[\"m_\"+n];if(m&&c){c=\"\"+c;if(c.indexOf(\"function\")>=0){a=c.indexOf(\"{\");b=c.lastIndexOf(\"}\");c=a>0&&b>0?c.substring(a+1,b):0;s[\"m_\"+n+\"_c"
+"\"]=c;if(m._e)s.loadModule(n);if(s[n])for(j=0;j<m._l.length;j++)s_sv(m,s[n],m._l[j])}}}}}var e,o,t;try{o=window.opener;if(o&&o.s_gi){t=o.s_gi(\"'+s.un+'\");if(t)s_si(t)}}catch(e){}',1)}};s.c_d='';s"
+".c_gdf=function(t,a){var s=this;if(!s.num(t))return 1;return 0};s.c_gd=function(){var s=this,d=s.wd.location.hostname,n=s.fpCookieDomainPeriods,p;if(!n)n=s.cookieDomainPeriods;if(d&&!s.c_d){n=n?par"
+"seInt(n):2;n=n>2?n:2;p=d.lastIndexOf('.');if(p>=0){while(p>=0&&n>1){p=d.lastIndexOf('.',p-1);n--}s.c_d=p>0&&s.pt(d,'.','c_gdf',0)?d.substring(p):d}}return s.c_d};s.c_r=function(k){var s=this;k=s.ap"
+"e(k);var c=' '+s.d.cookie,i=c.indexOf(' '+k+'='),e=i<0?i:c.indexOf(';',i),v=i<0?'':s.epa(c.substring(i+2+k.length,e<0?c.length:e));return v!='[[B]]'?v:''};s.c_w=function(k,v,e){var s=this,d=s.c_gd("
+"),l=s.cookieLifetime,t;v=''+v;l=l?(''+l).toUpperCase():'';if(e&&l!='SESSION'&&l!='NONE'){t=(v!=''?parseInt(l?l:0):-60);if(t){e=new Date;e.setTime(e.getTime()+(t*1000))}}if(k&&l!='NONE'){s.d.cookie="
+"k+'='+s.ape(v!=''?v:'[[B]]')+'; path=/;'+(e&&l!='SESSION'?' expires='+e.toGMTString()+';':'')+(d?' domain='+d+';':'');return s.c_r(k)==v}return 0};s.eh=function(o,e,r,f){var s=this,b='s_'+e+'_'+s._"
+"in,n=-1,l,i,x;if(!s.ehl)s.ehl=new Array;l=s.ehl;for(i=0;i<l.length&&n<0;i++){if(l[i].o==o&&l[i].e==e)n=i}if(n<0){n=i;l[n]=new Object}x=l[n];x.o=o;x.e=e;f=r?x.b:f;if(r||f){x.b=r?0:o[e];x.o[e]=f}if(x"
+".b){x.o[b]=x.b;return b}return 0};s.cet=function(f,a,t,o,b){var s=this,r,tcf;if(s.apv>=5&&(!s.isopera||s.apv>=7)){tcf=new Function('s','f','a','t','var e,r;try{r=s[f](a)}catch(e){r=s[t](e)}return r"
+"');r=tcf(s,f,a,t)}else{if(s.ismac&&s.u.indexOf('MSIE 4')>=0)r=s[b](a);else{s.eh(s.wd,'onerror',0,o);r=s[f](a);s.eh(s.wd,'onerror',1)}}return r};s.gtfset=function(e){var s=this;return s.tfs};s.gtfso"
+"e=new Function('e','var s=s_c_il['+s._in+'],c;s.eh(window,\"onerror\",1);s.etfs=1;c=s.t();if(c)s.d.write(c);s.etfs=0;return true');s.gtfsfb=function(a){return window};s.gtfsf=function(w){var s=this"
+",p=w.parent,l=w.location;s.tfs=w;if(p&&p.location!=l&&p.location.host==l.host){s.tfs=p;return s.gtfsf(s.tfs)}return s.tfs};s.gtfs=function(){var s=this;if(!s.tfs){s.tfs=s.wd;if(!s.etfs)s.tfs=s.cet("
+"'gtfsf',s.tfs,'gtfset',s.gtfsoe,'gtfsfb')}return s.tfs};s.mrq=function(u){var s=this,l=s.rl[u],n,r;s.rl[u]=0;if(l)for(n=0;n<l.length;n++){r=l[n];s.mr(0,0,r.r,0,r.t,r.u)}};s.br=function(id,rs){var s"
+"=this;if(s.disableBufferedRequests||!s.c_w('s_br',rs))s.brl=rs};s.flushBufferedRequests=function(){this.fbr(0)};s.fbr=function(id){var s=this,br=s.c_r('s_br');if(!br)br=s.brl;if(br){if(!s.disableBu"
+"fferedRequests)s.c_w('s_br','');s.mr(0,0,br)}s.brl=0};s.mr=function(sess,q,rs,id,ta,u){var s=this,dc=s.dc,t1=s.trackingServer,t2=s.trackingServerSecure,tb=s.trackingServerBase,p='.sc',ns=s.visitorN"
+"amespace,un=s.cls(u?u:(ns?ns:s.fun)),r=new Object,l,imn='s_i_'+(un),im,b,e;if(!rs){if(t1){if(t2&&s.ssl)t1=t2}else{if(!tb)tb='2o7.net';if(dc)dc=(''+dc).toLowerCase();else dc='d1';if(tb=='2o7.net'){i"
+"f(dc=='d1')dc='112';else if(dc=='d2')dc='122';p=''}t1=un+'.'+dc+'.'+p+tb}rs='http'+(s.ssl?'s':'')+'://'+t1+'/b/ss/'+s.un+'/'+(s.mobile?'5.1':'1')+'/H.20.3/'+sess+'?AQB=1&ndh=1'+(q?q:'')+'&AQE=1';if"
+"(s.isie&&!s.ismac){if(s.apv>5.5)rs=s.fl(rs,4095);else rs=s.fl(rs,2047)}if(id){s.br(id,rs);return}}if(s.d.images&&s.apv>=3&&(!s.isopera||s.apv>=7)&&(s.ns6<0||s.apv>=6.1)){if(!s.rc)s.rc=new Object;if"
+"(!s.rc[un]){s.rc[un]=1;if(!s.rl)s.rl=new Object;s.rl[un]=new Array;setTimeout('if(window.s_c_il)window.s_c_il['+s._in+'].mrq(\"'+un+'\")',750)}else{l=s.rl[un];if(l){r.t=ta;r.u=un;r.r=rs;l[l.length]"
+"=r;return ''}imn+='_'+s.rc[un];s.rc[un]++}im=s.wd[imn];if(!im)im=s.wd[imn]=new Image;im.s_l=0;im.onload=new Function('e','this.s_l=1;var wd=window,s;if(wd.s_c_il){s=wd.s_c_il['+s._in+'];s.mrq(\"'+u"
+"n+'\");s.nrs--;if(!s.nrs)s.m_m(\"rr\")}');if(!s.nrs){s.nrs=1;s.m_m('rs')}else s.nrs++;im.src=rs;if(rs.indexOf('&pe=')>=0&&(!ta||ta=='_self'||ta=='_top'||(s.wd.name&&ta==s.wd.name))){b=e=new Date;wh"
+"ile(!im.s_l&&e.getTime()-b.getTime()<500)e=new Date}return ''}return '<im'+'g sr'+'c=\"'+rs+'\" width=1 height=1 border=0 alt=\"\">'};s.gg=function(v){var s=this;if(!s.wd['s_'+v])s.wd['s_'+v]='';re"
+"turn s.wd['s_'+v]};s.glf=function(t,a){if(t.substring(0,2)=='s_')t=t.substring(2);var s=this,v=s.gg(t);if(v)s[t]=v};s.gl=function(v){var s=this;if(s.pg)s.pt(v,',','glf',0)};s.rf=function(x){var s=t"
+"his,y,i,j,h,l,a,b='',c='',t;if(x){y=''+x;i=y.indexOf('?');if(i>0){a=y.substring(i+1);y=y.substring(0,i);h=y.toLowerCase();i=0;if(h.substring(0,7)=='http://')i+=7;else if(h.substring(0,8)=='https://"
+"')i+=8;h=h.substring(i);i=h.indexOf(\"/\");if(i>0){h=h.substring(0,i);if(h.indexOf('google')>=0){a=s.sp(a,'&');if(a.length>1){l=',q,ie,start,search_key,word,kw,cd,';for(j=0;j<a.length;j++){t=a[j];i"
+"=t.indexOf('=');if(i>0&&l.indexOf(','+t.substring(0,i)+',')>=0)b+=(b?'&':'')+t;else c+=(c?'&':'')+t}if(b&&c){y+='?'+b+'&'+c;if(''+x!=y)x=y}}}}}}return x};s.hav=function(){var s=this,qs='',fv=s.link"
+"TrackVars,fe=s.linkTrackEvents,mn,i;if(s.pe){mn=s.pe.substring(0,1).toUpperCase()+s.pe.substring(1);if(s[mn]){fv=s[mn].trackVars;fe=s[mn].trackEvents}}fv=fv?fv+','+s.vl_l+','+s.vl_l2:'';for(i=0;i<s"
+".va_t.length;i++){var k=s.va_t[i],v=s[k],b=k.substring(0,4),x=k.substring(4),n=parseInt(x),q=k;if(v&&k!='linkName'&&k!='linkType'){if(s.pe||s.lnk||s.eo){if(fv&&(','+fv+',').indexOf(','+k+',')<0)v='"
+"';if(k=='events'&&fe)v=s.fs(v,fe)}if(v){if(k=='dynamicVariablePrefix')q='D';else if(k=='visitorID')q='vid';else if(k=='pageURL'){q='g';v=s.fl(v,255)}else if(k=='referrer'){q='r';v=s.fl(s.rf(v),255)"
+"}else if(k=='vmk'||k=='visitorMigrationKey')q='vmt';else if(k=='visitorMigrationServer'){q='vmf';if(s.ssl&&s.visitorMigrationServerSecure)v=''}else if(k=='visitorMigrationServerSecure'){q='vmf';if("
+"!s.ssl&&s.visitorMigrationServer)v=''}else if(k=='charSet'){q='ce';if(v.toUpperCase()=='AUTO')v='ISO8859-1';else if(s.em==2)v='UTF-8'}else if(k=='visitorNamespace')q='ns';else if(k=='cookieDomainPe"
+"riods')q='cdp';else if(k=='cookieLifetime')q='cl';else if(k=='variableProvider')q='vvp';else if(k=='currencyCode')q='cc';else if(k=='channel')q='ch';else if(k=='transactionID')q='xact';else if(k=='"
+"campaign')q='v0';else if(k=='resolution')q='s';else if(k=='colorDepth')q='c';else if(k=='javascriptVersion')q='j';else if(k=='javaEnabled')q='v';else if(k=='cookiesEnabled')q='k';else if(k=='browse"
+"rWidth')q='bw';else if(k=='browserHeight')q='bh';else if(k=='connectionType')q='ct';else if(k=='homepage')q='hp';else if(k=='plugins')q='p';else if(s.num(x)){if(b=='prop')q='c'+n;else if(b=='eVar')"
+"q='v'+n;else if(b=='list')q='l'+n;else if(b=='hier'){q='h'+n;v=s.fl(v,255)}}if(v)qs+='&'+q+'='+(k.substring(0,3)!='pev'?s.ape(v):v)}}}return qs};s.ltdf=function(t,h){t=t?t.toLowerCase():'';h=h?h.to"
+"LowerCase():'';var qi=h.indexOf('?');h=qi>=0?h.substring(0,qi):h;if(t&&h.substring(h.length-(t.length+1))=='.'+t)return 1;return 0};s.ltef=function(t,h){t=t?t.toLowerCase():'';h=h?h.toLowerCase():'"
+"';if(t&&h.indexOf(t)>=0)return 1;return 0};s.lt=function(h){var s=this,lft=s.linkDownloadFileTypes,lef=s.linkExternalFilters,lif=s.linkInternalFilters;lif=lif?lif:s.wd.location.hostname;h=h.toLower"
+"Case();if(s.trackDownloadLinks&&lft&&s.pt(lft,',','ltdf',h))return 'd';if(s.trackExternalLinks&&h.substring(0,1)!='#'&&(lef||lif)&&(!lef||s.pt(lef,',','ltef',h))&&(!lif||!s.pt(lif,',','ltef',h)))re"
+"turn 'e';return ''};s.lc=new Function('e','var s=s_c_il['+s._in+'],b=s.eh(this,\"onclick\");s.lnk=s.co(this);s.t();s.lnk=0;if(b)return this[b](e);return true');s.bc=new Function('e','var s=s_c_il['"
+"+s._in+'],f,tcf;if(s.d&&s.d.all&&s.d.all.cppXYctnr)return;s.eo=e.srcElement?e.srcElement:e.target;tcf=new Function(\"s\",\"var e;try{if(s.eo&&(s.eo.tagName||s.eo.parentElement||s.eo.parentNode))s.t"
+"()}catch(e){}\");tcf(s);s.eo=0');s.oh=function(o){var s=this,l=s.wd.location,h=o.href?o.href:'',i,j,k,p;i=h.indexOf(':');j=h.indexOf('?');k=h.indexOf('/');if(h&&(i<0||(j>=0&&i>j)||(k>=0&&i>k))){p=o"
+".protocol&&o.protocol.length>1?o.protocol:(l.protocol?l.protocol:'');i=l.pathname.lastIndexOf('/');h=(p?p+'//':'')+(o.host?o.host:(l.host?l.host:''))+(h.substring(0,1)!='/'?l.pathname.substring(0,i"
+"<0?0:i)+'/':'')+h}return h};s.ot=function(o){var t=o.tagName;t=t&&t.toUpperCase?t.toUpperCase():'';if(t=='SHAPE')t='';if(t){if(t=='INPUT'&&o.type&&o.type.toUpperCase)t=o.type.toUpperCase();else if("
+"!t&&o.href)t='A';}return t};s.oid=function(o){var s=this,t=s.ot(o),p,c,n='',x=0;if(t&&!o.s_oid){p=o.protocol;c=o.onclick;if(o.href&&(t=='A'||t=='AREA')&&(!c||!p||p.toLowerCase().indexOf('javascript"
+"')<0))n=s.oh(o);else if(c){n=s.rep(s.rep(s.rep(s.rep(''+c,\"\\r\",''),\"\\n\",''),\"\\t\",''),' ','');x=2}else if(o.value&&(t=='INPUT'||t=='SUBMIT')){n=o.value;x=3}else if(o.src&&t=='IMAGE')n=o.src"
+";if(n){o.s_oid=s.fl(n,100);o.s_oidt=x}}return o.s_oid};s.rqf=function(t,un){var s=this,e=t.indexOf('='),u=e>=0?','+t.substring(0,e)+',':'';return u&&u.indexOf(','+un+',')>=0?s.epa(t.substring(e+1))"
+":''};s.rq=function(un){var s=this,c=un.indexOf(','),v=s.c_r('s_sq'),q='';if(c<0)return s.pt(v,'&','rqf',un);return s.pt(un,',','rq',0)};s.sqp=function(t,a){var s=this,e=t.indexOf('='),q=e<0?'':s.ep"
+"a(t.substring(e+1));s.sqq[q]='';if(e>=0)s.pt(t.substring(0,e),',','sqs',q);return 0};s.sqs=function(un,q){var s=this;s.squ[un]=q;return 0};s.sq=function(q){var s=this,k='s_sq',v=s.c_r(k),x,c=0;s.sq"
+"q=new Object;s.squ=new Object;s.sqq[q]='';s.pt(v,'&','sqp',0);s.pt(s.un,',','sqs',q);v='';for(x in s.squ)if(x&&(!Object||!Object.prototype||!Object.prototype[x]))s.sqq[s.squ[x]]+=(s.sqq[s.squ[x]]?'"
+",':'')+x;for(x in s.sqq)if(x&&(!Object||!Object.prototype||!Object.prototype[x])&&s.sqq[x]&&(x==q||c<2)){v+=(v?'&':'')+s.sqq[x]+'='+s.ape(x);c++}return s.c_w(k,v,0)};s.wdl=new Function('e','var s=s"
+"_c_il['+s._in+'],r=true,b=s.eh(s.wd,\"onload\"),i,o,oc;if(b)r=this[b](e);for(i=0;i<s.d.links.length;i++){o=s.d.links[i];oc=o.onclick?\"\"+o.onclick:\"\";if((oc.indexOf(\"s_gs(\")<0||oc.indexOf(\".s"
+"_oc(\")>=0)&&oc.indexOf(\".tl(\")<0)s.eh(o,\"onclick\",0,s.lc);}return r');s.wds=function(){var s=this;if(s.apv>3&&(!s.isie||!s.ismac||s.apv>=5)){if(s.b&&s.b.attachEvent)s.b.attachEvent('onclick',s"
+".bc);else if(s.b&&s.b.addEventListener)s.b.addEventListener('click',s.bc,false);else s.eh(s.wd,'onload',0,s.wdl)}};s.vs=function(x){var s=this,v=s.visitorSampling,g=s.visitorSamplingGroup,k='s_vsn_"
+"'+s.un+(g?'_'+g:''),n=s.c_r(k),e=new Date,y=e.getYear();e.setYear(y+10+(y<1900?1900:0));if(v){v*=100;if(!n){if(!s.c_w(k,x,e))return 0;n=x}if(n%10000>v)return 0}return 1};s.dyasmf=function(t,m){if(t"
+"&&m&&m.indexOf(t)>=0)return 1;return 0};s.dyasf=function(t,m){var s=this,i=t?t.indexOf('='):-1,n,x;if(i>=0&&m){var n=t.substring(0,i),x=t.substring(i+1);if(s.pt(x,',','dyasmf',m))return n}return 0}"
+";s.uns=function(){var s=this,x=s.dynamicAccountSelection,l=s.dynamicAccountList,m=s.dynamicAccountMatch,n,i;s.un=s.un.toLowerCase();if(x&&l){if(!m)m=s.wd.location.host;if(!m.toLowerCase)m=''+m;l=l."
+"toLowerCase();m=m.toLowerCase();n=s.pt(l,';','dyasf',m);if(n)s.un=n}i=s.un.indexOf(',');s.fun=i<0?s.un:s.un.substring(0,i)};s.sa=function(un){var s=this;s.un=un;if(!s.oun)s.oun=un;else if((','+s.ou"
+"n+',').indexOf(','+un+',')<0)s.oun+=','+un;s.uns()};s.m_i=function(n,a){var s=this,m,f=n.substring(0,1),r,l,i;if(!s.m_l)s.m_l=new Object;if(!s.m_nl)s.m_nl=new Array;m=s.m_l[n];if(!a&&m&&m._e&&!m._i"
+")s.m_a(n);if(!m){m=new Object,m._c='s_m';m._in=s.wd.s_c_in;m._il=s._il;m._il[m._in]=m;s.wd.s_c_in++;m.s=s;m._n=n;m._l=new Array('_c','_in','_il','_i','_e','_d','_dl','s','n','_r','_g','_g1','_t','_"
+"t1','_x','_x1','_rs','_rr','_l');s.m_l[n]=m;s.m_nl[s.m_nl.length]=n}else if(m._r&&!m._m){r=m._r;r._m=m;l=m._l;for(i=0;i<l.length;i++)if(m[l[i]])r[l[i]]=m[l[i]];r._il[r._in]=r;m=s.m_l[n]=r}if(f==f.t"
+"oUpperCase())s[n]=m;return m};s.m_a=new Function('n','g','e','if(!g)g=\"m_\"+n;var s=s_c_il['+s._in+'],c=s[g+\"_c\"],m,x,f=0;if(!c)c=s.wd[\"s_\"+g+\"_c\"];if(c&&s_d)s[g]=new Function(\"s\",s_ft(s_d"
+"(c)));x=s[g];if(!x)x=s.wd[\\'s_\\'+g];if(!x)x=s.wd[g];m=s.m_i(n,1);if(x&&(!m._i||g!=\"m_\"+n)){m._i=f=1;if((\"\"+x).indexOf(\"function\")>=0)x(s);else s.m_m(\"x\",n,x,e)}m=s.m_i(n,1);if(m._dl)m._dl"
+"=m._d=0;s.dlt();return f');s.m_m=function(t,n,d,e){t='_'+t;var s=this,i,x,m,f='_'+t,r=0,u;if(s.m_l&&s.m_nl)for(i=0;i<s.m_nl.length;i++){x=s.m_nl[i];if(!n||x==n){m=s.m_i(x);u=m[t];if(u){if((''+u).in"
+"dexOf('function')>=0){if(d&&e)u=m[t](d,e);else if(d)u=m[t](d);else u=m[t]()}}if(u)r=1;u=m[t+1];if(u&&!m[f]){if((''+u).indexOf('function')>=0){if(d&&e)u=m[t+1](d,e);else if(d)u=m[t+1](d);else u=m[t+"
+"1]()}}m[f]=1;if(u)r=1}}return r};s.m_ll=function(){var s=this,g=s.m_dl,i,o;if(g)for(i=0;i<g.length;i++){o=g[i];if(o)s.loadModule(o.n,o.u,o.d,o.l,o.e,1);g[i]=0}};s.loadModule=function(n,u,d,l,e,ln){"
+"var s=this,m=0,i,g,o=0,f1,f2,c=s.h?s.h:s.b,b,tcf;if(n){i=n.indexOf(':');if(i>=0){g=n.substring(i+1);n=n.substring(0,i)}else g=\"m_\"+n;m=s.m_i(n)}if((l||(n&&!s.m_a(n,g)))&&u&&s.d&&c&&s.d.createElem"
+"ent){if(d){m._d=1;m._dl=1}if(ln){if(s.ssl)u=s.rep(u,'http:','https:');i='s_s:'+s._in+':'+n+':'+g;b='var s=s_c_il['+s._in+'],o=s.d.getElementById(\"'+i+'\");if(s&&o){if(!o.l&&s.wd.'+g+'){o.l=1;if(o."
+"i)clearTimeout(o.i);o.i=0;s.m_a(\"'+n+'\",\"'+g+'\"'+(e?',\"'+e+'\"':'')+')}';f2=b+'o.c++;if(!s.maxDelay)s.maxDelay=250;if(!o.l&&o.c<(s.maxDelay*2)/100)o.i=setTimeout(o.f2,100)}';f1=new Function('e"
+"',b+'}');tcf=new Function('s','c','i','u','f1','f2','var e,o=0;try{o=s.d.createElement(\"script\");if(o){o.type=\"text/javascript\";'+(n?'o.id=i;o.defer=true;o.onload=o.onreadystatechange=f1;o.f2=f"
+"2;o.l=0;':'')+'o.src=u;c.appendChild(o);'+(n?'o.c=0;o.i=setTimeout(f2,100)':'')+'}}catch(e){o=0}return o');o=tcf(s,c,i,u,f1,f2)}else{o=new Object;o.n=n+':'+g;o.u=u;o.d=d;o.l=l;o.e=e;g=s.m_dl;if(!g)"
+"g=s.m_dl=new Array;i=0;while(i<g.length&&g[i])i++;g[i]=o}}else if(n){m=s.m_i(n);m._e=1}return m};s.vo1=function(t,a){if(a[t]||a['!'+t])this[t]=a[t]};s.vo2=function(t,a){if(!a[t]){a[t]=this[t];if(!a"
+"[t])a['!'+t]=1}};s.dlt=new Function('var s=s_c_il['+s._in+'],d=new Date,i,vo,f=0;if(s.dll)for(i=0;i<s.dll.length;i++){vo=s.dll[i];if(vo){if(!s.m_m(\"d\")||d.getTime()-vo._t>=s.maxDelay){s.dll[i]=0;"
+"s.t(vo)}else f=1}}if(s.dli)clearTimeout(s.dli);s.dli=0;if(f){if(!s.dli)s.dli=setTimeout(s.dlt,s.maxDelay)}else s.dll=0');s.dl=function(vo){var s=this,d=new Date;if(!vo)vo=new Object;s.pt(s.vl_g,','"
+",'vo2',vo);vo._t=d.getTime();if(!s.dll)s.dll=new Array;s.dll[s.dll.length]=vo;if(!s.maxDelay)s.maxDelay=250;s.dlt()};s.t=function(vo,id){var s=this,trk=1,tm=new Date,sed=Math&&Math.random?Math.floo"
+"r(Math.random()*10000000000000):tm.getTime(),sess='s'+Math.floor(tm.getTime()/10800000)%10+sed,y=tm.getYear(),vt=tm.getDate()+'/'+tm.getMonth()+'/'+(y<1900?y+1900:y)+' '+tm.getHours()+':'+tm.getMin"
+"utes()+':'+tm.getSeconds()+' '+tm.getDay()+' '+tm.getTimezoneOffset(),tcf,tfs=s.gtfs(),ta='',q='',qs='',code='',vb=new Object;s.gl(s.vl_g);s.uns();s.m_ll();if(!s.td){var tl=tfs.location,a,o,i,x='',"
+"c='',v='',p='',bw='',bh='',j='1.0',k=s.c_w('s_cc','true',0)?'Y':'N',hp='',ct='',pn=0,ps;if(String&&String.prototype){j='1.1';if(j.match){j='1.2';if(tm.setUTCDate){j='1.3';if(s.isie&&s.ismac&&s.apv>"
+"=5)j='1.4';if(pn.toPrecision){j='1.5';a=new Array;if(a.forEach){j='1.6';i=0;o=new Object;tcf=new Function('o','var e,i=0;try{i=new Iterator(o)}catch(e){}return i');i=tcf(o);if(i&&i.next)j='1.7'}}}}"
+"}if(s.apv>=4)x=screen.width+'x'+screen.height;if(s.isns||s.isopera){if(s.apv>=3){v=s.n.javaEnabled()?'Y':'N';if(s.apv>=4){c=screen.pixelDepth;bw=s.wd.innerWidth;bh=s.wd.innerHeight}}s.pl=s.n.plugin"
+"s}else if(s.isie){if(s.apv>=4){v=s.n.javaEnabled()?'Y':'N';c=screen.colorDepth;if(s.apv>=5){bw=s.d.documentElement.offsetWidth;bh=s.d.documentElement.offsetHeight;if(!s.ismac&&s.b){tcf=new Function"
+"('s','tl','var e,hp=0;try{s.b.addBehavior(\"#default#homePage\");hp=s.b.isHomePage(tl)?\"Y\":\"N\"}catch(e){}return hp');hp=tcf(s,tl);tcf=new Function('s','var e,ct=0;try{s.b.addBehavior(\"#default"
+"#clientCaps\");ct=s.b.connectionType}catch(e){}return ct');ct=tcf(s)}}}else r=''}if(s.pl)while(pn<s.pl.length&&pn<30){ps=s.fl(s.pl[pn].name,100)+';';if(p.indexOf(ps)<0)p+=ps;pn++}s.resolution=x;s.c"
+"olorDepth=c;s.javascriptVersion=j;s.javaEnabled=v;s.cookiesEnabled=k;s.browserWidth=bw;s.browserHeight=bh;s.connectionType=ct;s.homepage=hp;s.plugins=p;s.td=1}if(vo){s.pt(s.vl_g,',','vo2',vb);s.pt("
+"s.vl_g,',','vo1',vo)}if(s.usePlugins)s.doPlugins(s);var l=s.wd.location,r=tfs.document.referrer;if(!s.pageURL)s.pageURL=l.href?l.href:l;if(!s.referrer&&!s._1_referrer){s.referrer=r;s._1_referrer=1}"
+"if((vo&&vo._t)||!s.m_m('d')){s.m_m('g');if(s.lnk||s.eo){var o=s.eo?s.eo:s.lnk;if(!o)return '';var p=s.pageName,w=1,t=s.ot(o),n=s.oid(o),x=o.s_oidt,h,l,i,oc;if(s.eo&&o==s.eo){while(o&&!n&&t!='BODY')"
+"{o=o.parentElement?o.parentElement:o.parentNode;if(!o)return '';t=s.ot(o);n=s.oid(o);x=o.s_oidt}oc=o.onclick?''+o.onclick:'';if((oc.indexOf(\"s_gs(\")>=0&&oc.indexOf(\".s_oc(\")<0)||oc.indexOf(\".t"
+"l(\")>=0)return ''}ta=n?o.target:1;h=s.oh(o);i=h.indexOf('?');h=s.linkLeaveQueryString||i<0?h:h.substring(0,i);l=s.linkName;t=s.linkType?s.linkType.toLowerCase():s.lt(h);if(t&&(h||l))q+='&pe=lnk_'+"
+"(t=='d'||t=='e'?s.ape(t):'o')+(h?'&pev1='+s.ape(h):'')+(l?'&pev2='+s.ape(l):'');else trk=0;if(s.trackInlineStats){if(!p){p=s.pageURL;w=0}t=s.ot(o);i=o.sourceIndex;if(s.gg('objectID')){n=s.gg('objec"
+"tID');x=1;i=1}if(p&&n&&t)qs='&pid='+s.ape(s.fl(p,255))+(w?'&pidt='+w:'')+'&oid='+s.ape(s.fl(n,100))+(x?'&oidt='+x:'')+'&ot='+s.ape(t)+(i?'&oi='+i:'')}}if(!trk&&!qs)return '';s.sampled=s.vs(sed);if("
+"trk){if(s.sampled)code=s.mr(sess,(vt?'&t='+s.ape(vt):'')+s.hav()+q+(qs?qs:s.rq(s.un)),0,id,ta);qs='';s.m_m('t');if(s.p_r)s.p_r();s.referrer=''}s.sq(qs);}else{s.dl(vo);}if(vo)s.pt(s.vl_g,',','vo1',v"
+"b);s.lnk=s.eo=s.linkName=s.linkType=s.wd.s_objectID=s.ppu=s.pe=s.pev1=s.pev2=s.pev3='';if(s.pg)s.wd.s_lnk=s.wd.s_eo=s.wd.s_linkName=s.wd.s_linkType='';if(!id&&!s.tc){s.tc=1;s.flushBufferedRequests("
+")}return code};s.tl=function(o,t,n,vo){var s=this;s.lnk=s.co(o);s.linkType=t;s.linkName=n;s.t(vo)};if(pg){s.wd.s_co=function(o){var s=s_gi(\"_\",1,1);return s.co(o)};s.wd.s_gs=function(un){var s=s_"
+"gi(un,1,1);return s.t()};s.wd.s_dc=function(un){var s=s_gi(un,1);return s.t()}}s.ssl=(s.wd.location.protocol.toLowerCase().indexOf('https')>=0);s.d=document;s.b=s.d.body;if(s.d.getElementsByTagName"
+"){s.h=s.d.getElementsByTagName('HEAD');if(s.h)s.h=s.h[0]}s.n=navigator;s.u=s.n.userAgent;s.ns6=s.u.indexOf('Netscape6/');var apn=s.n.appName,v=s.n.appVersion,ie=v.indexOf('MSIE '),o=s.u.indexOf('Op"
+"era '),i;if(v.indexOf('Opera')>=0||o>0)apn='Opera';s.isie=(apn=='Microsoft Internet Explorer');s.isns=(apn=='Netscape');s.isopera=(apn=='Opera');s.ismac=(s.u.indexOf('Mac')>=0);if(o>0)s.apv=parseFl"
+"oat(s.u.substring(o+6));else if(ie>0){s.apv=parseInt(i=v.substring(ie+5));if(s.apv>3)s.apv=parseFloat(i)}else if(s.ns6>0)s.apv=parseFloat(s.u.substring(s.ns6+10));else s.apv=parseFloat(v);s.em=0;if"
+"(String.fromCharCode){i=escape(String.fromCharCode(256)).toUpperCase();s.em=(i=='%C4%80'?2:(i=='%U0100'?1:0))}s.sa(un);s.vl_l='dynamicVariablePrefix,visitorID,vmk,visitorMigrationKey,visitorMigrati"
+"onServer,visitorMigrationServerSecure,ppu,charSet,visitorNamespace,cookieDomainPeriods,cookieLifetime,pageName,pageURL,referrer,currencyCode';s.va_l=s.sp(s.vl_l,',');s.vl_t=s.vl_l+',variableProvide"
+"r,channel,server,pageType,transactionID,purchaseID,campaign,state,zip,events,products,linkName,linkType';for(var n=1;n<51;n++)s.vl_t+=',prop'+n+',eVar'+n+',hier'+n+',list'+n;s.vl_l2=',tnt,pe,pev1,p"
+"ev2,pev3,resolution,colorDepth,javascriptVersion,javaEnabled,cookiesEnabled,browserWidth,browserHeight,connectionType,homepage,plugins';s.vl_t+=s.vl_l2;s.va_t=s.sp(s.vl_t,',');s.vl_g=s.vl_t+',track"
+"ingServer,trackingServerSecure,trackingServerBase,fpCookieDomainPeriods,disableBufferedRequests,mobile,visitorSampling,visitorSamplingGroup,dynamicAccountSelection,dynamicAccountList,dynamicAccount"
+"Match,trackDownloadLinks,trackExternalLinks,trackInlineStats,linkLeaveQueryString,linkDownloadFileTypes,linkExternalFilters,linkInternalFilters,linkTrackVars,linkTrackEvents,linkNames,lnk,eo,_1_ref"
+"errer';s.va_g=s.sp(s.vl_g,',');s.pg=pg;s.gl(s.vl_g);if(!ss)s.wds()",
w=window,l=w.s_c_il,n=navigator,u=n.userAgent,v=n.appVersion,e=v.indexOf('MSIE '),m=u.indexOf('Netscape6/'),a,i,s;if(un){un=un.toLowerCase();if(l)for(i=0;i<l.length;i++){s=l[i];if(!s._c||s._c=='s_c'){if(s.oun==un)return s;else if(s.fs&&s.sa&&s.fs(s.oun,un)){s.sa(un);return s}}}}w.s_an='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
w.s_sp=new Function("x","d","var a=new Array,i=0,j;if(x){if(x.split)a=x.split(d);else if(!d)for(i=0;i<x.length;i++)a[a.length]=x.substring(i,i+1);else while(i>=0){j=x.indexOf(d,i);a[a.length]=x.subst"
+"ring(i,j<0?x.length:j);i=j;if(i>=0)i+=d.length}}return a");
w.s_jn=new Function("a","d","var x='',i,j=a.length;if(a&&j>0){x=a[0];if(j>1){if(a.join)x=a.join(d);else for(i=1;i<j;i++)x+=d+a[i]}}return x");
w.s_rep=new Function("x","o","n","return s_jn(s_sp(x,o),n)");
w.s_d=new Function("x","var t='`^@$#',l=s_an,l2=new Object,x2,d,b=0,k,i=x.lastIndexOf('~~'),j,v,w;if(i>0){d=x.substring(0,i);x=x.substring(i+2);l=s_sp(l,'');for(i=0;i<62;i++)l2[l[i]]=i;t=s_sp(t,'');d"
+"=s_sp(d,'~');i=0;while(i<5){v=0;if(x.indexOf(t[i])>=0) {x2=s_sp(x,t[i]);for(j=1;j<x2.length;j++){k=x2[j].substring(0,1);w=t[i]+k;if(k!=' '){v=1;w=d[b+l2[k]]}x2[j]=w+x2[j].substring(1)}}if(v)x=s_jn("
+"x2,'');else{w=t[i]+' ';if(x.indexOf(w)>=0)x=s_rep(x,w,t[i]);i++;b+=62}}}return x");
w.s_fe=new Function("c","return s_rep(s_rep(s_rep(c,'\\\\','\\\\\\\\'),'\"','\\\\\"'),\"\\n\",\"\\\\n\")");
w.s_fa=new Function("f","var s=f.indexOf('(')+1,e=f.indexOf(')'),a='',c;while(s>=0&&s<e){c=f.substring(s,s+1);if(c==',')a+='\",\"';else if((\"\\n\\r\\t \").indexOf(c)<0)a+=c;s++}return a?'\"'+a+'\"':"
+"a");
w.s_ft=new Function("c","c+='';var s,e,o,a,d,q,f,h,x;s=c.indexOf('=function(');while(s>=0){s++;d=1;q='';x=0;f=c.substring(s);a=s_fa(f);e=o=c.indexOf('{',s);e++;while(d>0){h=c.substring(e,e+1);if(q){i"
+"f(h==q&&!x)q='';if(h=='\\\\')x=x?0:1;else x=0}else{if(h=='\"'||h==\"'\")q=h;if(h=='{')d++;if(h=='}')d--}if(d>0)e++}c=c.substring(0,s)+'new Function('+(a?a+',':'')+'\"'+s_fe(c.substring(o+1,e))+'\")"
+"'+c.substring(e+1);s=c.indexOf('=function(')}return c;");
c=s_d(c);if(e>0){a=parseInt(i=v.substring(e+5));if(a>3)a=parseFloat(i)}else if(m>0)a=parseFloat(u.substring(m+10));else a=parseFloat(v);if(a>=5&&v.indexOf('Opera')<0&&u.indexOf('Opera')<0){w.s_c=new Function("un","pg","ss","var s=this;"+c);return new s_c(un,pg,ss)}else s=new Function("un","pg","ss","var s=new Object;"+s_ft(c)+";return s");return s(un,pg,ss)}
