/***** en_US/components/video/javascripts/player/config/jw_config.js *****/
Syn.VideoPlayer.Config.JwConfig = Class.extend(
{
	init: function(config)
	{
		for (var prop in config)
		{
			switch(prop)
			{
				case "item":
					this[prop] = Syn.VideoPlayer.Config.JwConfig.convertItem(config[prop]);
					break;
				case "scaling":
					this[prop] = Syn.VideoPlayer.Config.JwConfig.convertScaling(config[prop]);
					break;
				default:
					this[prop] = config[prop];
					break;
			}
		}
	}	
});
/**
 * Converts an item specified in the Synacor format to a file in the
 * format as requested by the JW Player.  The Synacor format is:
 *
 * 1) A URL to the media
 * 2) An object with {url: "url", type: "type", image: "image"}
 *
 * The JW Player format is similar, taking either
 *
 * 1) A URL to the media
 * 2) An object like {file: "url", type: "type", image: "image"}
 *
 * @param item A file to be played in the general Synacor format
 * @return An item congruent to the input but in the JW player format
 *
 **/
Syn.VideoPlayer.Config.JwConfig.convertItem = function(item)
{
	// JW player requires a streamer property to be set for RTMP
	// videos.  So (1) must be converted to (2):
	// (1) {file:"rtmp://path/to/video.flv"}
	// (2) {file:"video.flv", streamer:"rtmp://path/to/"}
	var convertRtmp = function (obj)
	{
		if (obj.file && obj.file.match(/^rtmp:\/\//))
		{
			obj.streamer = obj.file.match(/^.*\//)[0];
			obj.file = obj.file.match(/[^\/]+$/)[0];
			obj.type = "rtmp";
		}
		return obj;
	};

	if(typeof(item) == "string")
	{
		return convertRtmp({file:item, type:"video"});
	}

	if(item instanceof Array)
	{
		var n = item.length;
		for(var i = 0; i < n; i++)
		{
			item[i] = Syn.VideoPlayer.Config.JwConfig.convertItem(item[i]);
		}
		return item;
	}

	if(item)
	{
		var jw = {
			file:item.url,
			type:Syn.VideoPlayer.Config.JwConfig.convertType(item.type),
			image:item.image,
			ads:item.ads,
			cdn:item.cdn,
			tags:item.tags,
			title:item.title,
			flashreport_url:item.flashreport_url,
			id:item.id,
			e:item.e,
			client:item.client,
			uuid:item.uuid,
			vam_id:item.vam_id
		};

		convertRtmp(jw);

		// Convert each of the fallback CDN items too!
		if (jw.cdn)
		{
			jw.cdn = Syn.VideoPlayer.Config.JwConfig.convertItem(jw.cdn);
		}

		return jw;
	}
	return null;
};

/**
 * The Synacor acceptable values for media types are:
 * - video
 * - audio
 * - image
 *
 * The Jw Player acceptable types are:
 * - video
 * - sound
 * - image
 *
 * @param The type of media to be played defined in Synacor format
 * @return The media type of the input as a JW Player value
 */
Syn.VideoPlayer.Config.JwConfig.convertType = function(type)
{
	if(!type)
	{
		type = "video";
	}
	else if(type == "audio")
	{
		type = "sound";
	}
	return type;
};

/**
 * Converts a Synacor specified scaling into the JW Player expected
 * format of scaling.
 *
 * The Synacor values for scaling are:
 * - fit
 * - stretch
 * - original
 *
 * This JW Player expeected values are:
 * - none ~= original
 * - exactfit ~= stretch
 * - uniform ?? fit
 * - fill ?? fit
 *
 * @param scaling The scaling of the video specified in Synacor values
 * @return the scaling of the video in JW Player values
 */
Syn.VideoPlayer.Config.JwConfig.convertScaling = function(scaling)
{
	switch(scaling)
	{
		case "stretch":
			return "exactfit";
		case "original":
			return "none";
	}

	return "uniform";
};
;
/***** en_US/components/video/javascripts/player/decorators/plugins/plugins.js *****/
Syn.VideoPlayer.Plugins = {};
Syn.VideoPlayer.Plugins.ADS = "ads";
;
/***** en_US/components/video/javascripts/player/decorators/abstract_decorator.js *****/
Syn.VideoPlayer.AbstractDecorator = Class.extend(
{
	init: function(adapter)
	{
		this.adapter = adapter;
	},

	insertVideoPlayer: function(div, config)
	{
		this.adapter.insertVideoPlayer(div, config);
	},

	/*
	Control the player
	*/
	load: function(item)
	{
		this.adapter.load(item);
	},

	play: function(item)
	{
		this.adapter.play(item);
	},

	pause: function()
	{
		this.adapter.pause();
	},

	stop: function()
	{
		this.adapter.stop();
	},

	mute: function()
	{
		this.adapter.mute();
	},
	
	unmute: function()
	{
		this.adapter.unmute();
	},

	next: function()
	{
		this.adapter.next();
	},

	previous: function()
	{
		this.adapter.previous();
	},

	error: function(msg)
	{
		this.adapter.error(msg);
	},
	

	/*
	Helper functions for handling Synacor video
	*/

	/**
	 * Passes our own success and error functions to playVideoId so that the
	 * callbacks are override-able by any decorator classes.  Otherwise, only
	 * the adapters have access to the callbacks, and that made things tough.
	 *
	 * <p>
	 * For example, the ads plugin class is a decorator.  Since it did not inherit
	 * from the adapter class (it is composed of one), we couldn't simply override
	 * the onPlayApiSuccess method to get access to the results.
	 * </p>
	 *
	 * @see #onPlayApiSuccess
	 */
	playVideoId: function(id)
	{
		this.adapter.playVideoId(id, this, this.onPlayApiSuccess, this.onPlayApiError);
	},
	/**
	 * Default success handler for playVideoId().  Since this AbstractDecorator
	 * class is the base class for all decorators, we passed our own callbacks
	 * to playVideoId() so that they could be overridden by any subclass so that
	 * they could have access to the Play API results.
	 *
	 * @see #playVideoId
	 */
	onPlayApiSuccess: function(result)
	{
		this.adapter.onPlayApiSuccess(result);
	},
	/**
	 * Default error handler for playVideoId().
	 */
	onPlayApiError: function(result)
	{
		this.adapter.onPlayApiError(result);
	},


	/*
	Event Handling
	*/
	addCallback: function(type, scopeObj, func)
	{
		this.adapter.addCallback(type, scopeObj, func);
	},
	removeCallback: function(type, scopeObj, func)
	{
		this.adapter.removeCallback(type, scopeObj, func);
	},
	notifyCallbacks: function(type, args)
	{
		this.adapter.notifyCallbacks(type, args);
	},

	/*
	Queue method call if player is not ready
	*/
	maybeQueue: function(func, args)
	{
		return this.adapter.maybeQueue(func, args);
	},

	/*
	Provide access to player
	*/
	getPlayer: function()
	{
		return this.adapter.getPlayer();
	},
	getPlayerId: function()
	{
		return this.adapter.getPlayerId();
	}
});
;
/***** en_US/components/video/javascripts/player/decorators/plugins/ads/abstract_ads.js *****/
Syn.VideoPlayer.Plugins.AbstractAds = Syn.VideoPlayer.AbstractDecorator.extend(
{
	/**
	 * @constructor
	 */
	init: function(adapter)
	{
		this._super(adapter);
	},

	/*
	Companion Banner Ad
	*/

	/**
	 * Called by the ads plugin when we are to display a banner ad.  We forward
	 * this event to any listeners.  The implementation should listen for the
	 * SHOW_BANNER_AD event and act appropriately.
	 *
	 * @param {String} displayURL The URL of the banner ad to be shown
	 * @param {String} clickURL The URL to direct the user to if they click on the ad
	 */
	showBannerAd: function(displayURL, clickURL)
	{
		this.notifyCallbacks(Syn.VideoPlayer.Events.SHOW_BANNER_AD, [displayURL, clickURL]);
	},
	/**
	 * Called by the ads plugin when we are to hide the banner ad.  We forward
	 * this event to any listeners.  The implementation should listen for the
	 * HIDE_BANNER_AD event and act appropriately.
	 */
	hideBannerAd: function()
	{
		this.notifyCallbacks(Syn.VideoPlayer.Events.HIDE_BANNER_AD);
	},
	/**
	 * Called by the ads plugin after video ads were requested, but no ads were
	 * returned.  The implemetation may listen for the NO_AD_LOADED event.
	 */
	noAdLoaded: function()
	{
		this.notifyCallbacks(Syn.VideoPlayer.Events.NO_AD_LOADED);
	},


	/*
	Sort ads by priority
	*/

	/**
	 * An array sort function that orders the array so that the highest priority
	 * ad providers are first.  When we pass the array to the ads plugin, it cycles
	 * through the array, finding the highest priority provider that returns an ad.
	 *
	 * @param {Object} a An ad with the provider property set
	 * @param {Object} b An ad with the provider property set
	 * @returns -1(if a is higher priority), 1(if b is higher), 0 if it doesn't matter
	 * @type int
	 */
	sortAds: function(a, b)
	{
		if (a.provider == "doubleclick")
		{
			return -1;
		}
		if (b.provider == "doubleclick")
		{
			return 1;
		}

		return 0;
	}
});
;
/***** en_US/components/video/javascripts/player/decorators/plugins/ads/jw_ads.js *****/
/**
 * Wraps the JwAdapter class to provide video advertising within the JW
 * Player.  The responsibilities of this class are to:
 *
 * 1) Modify the config so that the player loads the ads.swf plugin
 * 2) Modify the config to remove the item if it has an ad (play it later).
 * 3) Intercept responses from the Play API and grab the ad xml.
 * 4) Re-route play() calls to the ads SWF plugin if the item has an ad.
 */
Syn.VideoPlayer.Plugins.JwAds = Syn.VideoPlayer.Plugins.AbstractAds.extend(
{
	/**
	 * @constructor
	 */
	init: function(adapter)
	{
		this._super(adapter);
	},

	/**
	 * Override the super method in order to modify the config to make the
	 * player load the ads.swf plugin.  Also, if the config item contains
	 * an ad, remove it from the config (or else the ad won't play), and
	 * play it manually once the player it loaded.
	 *
	 * @param {String} div The HTML DIV the player will be loaded into
	 * @param {Object} config The configuration vars for the player
	 */
	insertVideoPlayer: function(div, config)
	{
		//add plugin to flashVars
		if(!config.flashVars)
		{
			config.flashVars = {};
		}
		if(!config.flashVars.plugins)
		{
			config.flashVars.plugins = "";
		}
		else
		{
			config.flashVars.plugins += ",";
		}

		config.flashVars.plugins += Syn.Config.Framework.AssetsRoot + "en_US/components/video/players/jw_player/plugins/ads/v5/1/ads.swf";

		//pass on debug param
		if(config.plugins && config.plugins.ads && config.plugins.ads.debug)
		{
			config.flashVars["ads.debug"] = true;
		}

		this._super(div, config);

		//Register this instance globally so that the plugin can communicate
		//with this javascript instance.  Must be done after the _super call
		//is made since JwAdapter sets the uniqueId.
		Syn.VideoPlayer.Plugins.JwAds.setInstance(this.getPlayerId(), this);
	},

	/**
	 * Overridden method to intercept the result of the Play API call.
	 * Parse the results for ad parameters, and play an ad if it is
	 * requested.
	 *
	 * @param {Object} result The data returned from the Play API
	 */
	onPlayApiSuccess: function(result)
	{
		var ads = [];

		var n = result && result.ads ? result.ads.length : 0;
		for(var i = 0; i < n; i++)
		{
			var ad = result.ads[i];
			ads.push({provider:ad.provider, affiliate_level:ad.affiliate_level});
		}

		ads.sort(this.sortAds);

		this.play({file:result.url, type:"video", ads:ads});
	}
});

/*
Manage instances of the JwAds class so that they are globally
accessible by id.  This is so the JW Player can communicate
with the instance that owns it.
*/
Syn.VideoPlayer.Plugins.JwAds.instances = [];
Syn.VideoPlayer.Plugins.JwAds.setInstance = function(id, instance)
{
	Syn.VideoPlayer.Plugins.JwAds.instances[id] = instance;
};
Syn.VideoPlayer.Plugins.JwAds.getInstance = function(id)
{
	return Syn.VideoPlayer.Plugins.JwAds.instances[id];
};


/*
JW Player javascript callbacks
*/
Syn.VideoPlayer.Plugins.JwAds.showBannerAd = function(dat)
{
	Syn.VideoPlayer.Plugins.JwAds.getInstance(dat.id).showBannerAd(dat.displayURL, dat.clickURL);
};
Syn.VideoPlayer.Plugins.JwAds.hideBannerAd = function(dat)
{
	Syn.VideoPlayer.Plugins.JwAds.getInstance(dat.id).hideBannerAd();
};
Syn.VideoPlayer.Plugins.JwAds.noAdLoaded = function(dat)
{
	Syn.VideoPlayer.Plugins.JwAds.getInstance(dat.id).noAdLoaded();
};
;
/***** en_US/components/video/javascripts/player/decorators/plugins/controls/jw_controls.js *****/
Syn.VideoPlayer.Plugins.JwControls = Syn.VideoPlayer.AbstractDecorator.extend(
{
	/**
	 * @constructor
	 */
	init: function(adapter)
	{
		this._super(adapter);
	},

	/**
	 * Override the super method in order to modify the config to make the
	 * player load the controls.swf plugin.
	 *
	 * @param {String} div The HTML DIV the player will be loaded into
	 * @param {Object} config The configuration vars for the player
	 */
	insertVideoPlayer: function(div, config)
	{
		//add plugin to flashVars
		if(!config.flashVars)
		{
			config.flashVars = {};
		}
		if(!config.flashVars.plugins)
		{
			config.flashVars.plugins = "";
		}
		else
		{
			config.flashVars.plugins += ",";
		}

		config.flashVars.plugins += Syn.Config.Framework.AssetsRoot + "en_US/components/video/players/jw_player/plugins/controls/v5/controls.swf";

		//pass on controls params
		if (config.plugins && config.plugins.controls)
		{
			if (config.plugins.controls.share)
			{
				config.flashVars["controls.share"] = true;
			}
			if (config.plugins.controls["alert"])
			{
				config.flashVars["controls.alert"] = true;
			}
			if (config.plugins.controls.addtodesktop)
			{
				config.flashVars["controls.addtodesktop"] = true;
			}
			if (config.plugins.controls.debug)
			{
				config.flashVars["controls.debug"] = true;
			}
		}

		this._super(div, config);

		//Register global instance
		Syn.VideoPlayer.Plugins.JwControls.setInstance(this.getPlayerId(), this);
	},

	/**
	 * This method is called when the user clicks the "email" button
	 * on the controlBar in the video player.
	 */
	email: function()
	{
		this.notifyCallbacks(Syn.VideoPlayer.Events.EMAIL);
	}
});

/*
Manage instances of the JwControls class so that they are globally
accessible by id.  This is so the JW Player can communicate
with the instance that owns it.
*/
Syn.VideoPlayer.Plugins.JwControls.instances = [];
Syn.VideoPlayer.Plugins.JwControls.setInstance = function(id, instance)
{
	Syn.VideoPlayer.Plugins.JwControls.instances[id] = instance;
};
Syn.VideoPlayer.Plugins.JwControls.getInstance = function(id)
{
	return Syn.VideoPlayer.Plugins.JwControls.instances[id];
};

/*
JW Player javascript callbacks
*/
Syn.VideoPlayer.Plugins.JwControls.email = function(dat)
{
	Syn.VideoPlayer.Plugins.JwControls.getInstance(dat.id).email();
};
;
/***** en_US/components/video/javascripts/player/decorators/plugins/controller/jw_controller.js *****/
Syn.VideoPlayer.Plugins.JwController = Syn.VideoPlayer.AbstractDecorator.extend(
{
	/**
	 * @constructor
	 */
	init: function(adapter)
	{
		this._super(adapter);
	},

	/**
	 * Override the super method in order to modify the config to make the
	 * player load the controller.swf plugin.
	 *
	 * @param {String} div The HTML DIV into which the player will be loaded
	 * @param {Object} config The configuration vars for the player
	 */
	insertVideoPlayer: function(div, config)
	{
		//add plugin to flashVars
		if(!config.flashVars)
		{
			config.flashVars = {};
		}
		if(!config.flashVars.plugins)
		{
			config.flashVars.plugins = "";
		}
		else
		{
			config.flashVars.plugins += ",";
		}

		config.flashVars.plugins += Syn.Config.Framework.AssetsRoot + "en_US/components/video/players/jw_player/plugins/controller/v5/1/controller.swf";

		//pass config parameters to controller plugin
		if(config.plugins && config.plugins.controller)
		{
			config.flashVars["controller.debug"] = config.plugins.controller.debug;
			config.flashVars["controller.mediation_api"] = config.plugins.controller.mediation_api;
			config.flashVars["controller.vam_api"] = config.plugins.controller.vam_api;
		}

		//remove item from config, play it on READY so it goes through our overridden play() method
		if(config.item)
		{
			var self = this;
			var item = config.item;
			config.item = null;

			this.addCallback(Syn.VideoPlayer.Events.READY, null, function(){
				self.play(item);
				item = null;
			});
		}

		this._super(div, config);

		//Register this instance globally so that the plugin can communicate
		//with this javascript instance.  Must be done after the _super call
		//is made since JwAdapter sets the uniqueId.
		Syn.VideoPlayer.Plugins.JwController.setInstance(this.getPlayerId(), this);
	},

	/**
	 * Overrides the play() function to call the controller plugin.
	 * Checks to see that the player is ready, if not, it queues the
	 * method to be called later.
	 *
	 * @param {Object} item
	 */
	play: function(item)
	{
		// This is a dirty hack.  For some reason, in Flash Player 9,0,45,0 (and possibly
		// some others) having an object with a property that is an array causes invalid
		// JavaScript -> ActionScript conversion.  To get around this, move the cdn array
		// into its own argument and delete it from the item object.  The object is
		// reassembled on the flash side.
		var cdn = item.cdn;
		delete item.cdn;

		if (this.maybeQueue(this.play, arguments))
		{
			var player = this.getPlayer();
			if(player && player.playSynItem)
			{
				// Second part of above hack.  Pass the cdn array as its own argument.
				player.playSynItem(item, cdn);
			}
			else
			{
				this._super(item);
			}
		}
	},

	entitlementsError: function(info)
	{
		this.notifyCallbacks("entitlementsError", [info]);
	},

	netStreamInfo: function(info)
	{
		this.notifyCallbacks("netStreamInfo", [info]);
	}
});

/*
Manage instances of the JwController class so that they are
globally accessible by id.  This is so the JW Player can
communicate with the instance that owns it.
*/
Syn.VideoPlayer.Plugins.JwController.instances = [];
Syn.VideoPlayer.Plugins.JwController.setInstance = function(id, instance)
{
	Syn.VideoPlayer.Plugins.JwController.instances[id] = instance;
};
Syn.VideoPlayer.Plugins.JwController.getInstance = function(id)
{
	return Syn.VideoPlayer.Plugins.JwController.instances[id];
};

/*
JW Player javascript callbacks
*/
Syn.VideoPlayer.Plugins.JwController.entitlementsError = function(dat)
{
	Syn.VideoPlayer.Plugins.JwController.getInstance(dat.id).entitlementsError(dat);
};
Syn.VideoPlayer.Plugins.JwController.netStreamInfo = function(dat)
{
	Syn.VideoPlayer.Plugins.JwController.getInstance(dat.id).netStreamInfo(dat);
};
;
/***** en_US/components/video/javascripts/player/adapters/abstract_adapter.js *****/
Syn.VideoPlayer.AbstractAdapter = Class.extend(
{
	/**
	 * @constructor
	 */
	init: function()
	{
		this.isPlayerReady = false;
		this.listeners = [];
		this.queuedEvents = [];
		this.playApi = new Syn.VideoPlayer.PlayApi();
	},
	
	/**
	 * Adds the video player SWF into an HTML div element.  Must be overridden
	 * in a subclass to do the actual work.  This method merely saves a reference
	 * to this instance so it can be accessed by the player later.
	 *
	 * Takes as its argument a config object that contains all settings for the
	 * video player.  This instance should be of Syn.VideoPlayer.Config or one of
	 * it's subclasses that is specifically for this type of adapter.
	 *
	 * @param {Object} config Usually a subclass of Syn.VideoPlayer.Config (e.g. JwConfig)
	 */
	insertVideoPlayer: function(div, config)
	{
		this.uniqueId = div;
		Syn.VideoPlayer.AbstractAdapter.setInstance(this.uniqueId, this);
	},

	
	/*
	These methods can be used to control the player.
	*/

	/**
	 * Load a video, but do not play unless autostart is set to true.
	 *
	 * <p>
	 * This abstract method queues this method invokation if the player
	 * is not loaded yet.  If the method is queued, this returns false
	 * so that the super method will not carry out its actions.  The
	 * queued methods are called once the player fires its ready event.
	 * </p>
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 */
	load: function(video)
	{
		return this.maybeQueue(this.load, arguments);
	},
	/**
	 * If the item parameter is null, resumes the playback of the currently
	 * loaded file.  If not null, the item is loaded then played.
	 *
	 * <p>See comments in video_player.js for item format info</p>
	 *
	 * @param {String|Object} (optional) The video to play
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 * @see Syn.VideoPlayer#play
	 */
	play: function(video)
	{
		return this.maybeQueue(this.play, arguments);
	},
	/**
	 * Pause.
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	pause: function()
	{
		return this.maybeQueue(this.pause, arguments);
	},
	/**
	 * Stop the video. Set the playhead position back to the start.
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	stop: function()
	{
		return this.maybeQueue(this.stop, arguments);
	},
	/**
	 * Mute.
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	mute: function()
	{
		return this.maybeQueue(this.mute, arguments);
	},
	/**
	 * Unmute.
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	unmute: function()
	{
		return this.maybeQueue(this.unmute, arguments);
	},
	/**
	 * Advances the player to the next item in its playlist.  This might not
	 * be enabled for all players since most of the playlisting will be done
	 * in javascript.  This is only for player-internal playlists.
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	next: function()
	{
		return this.maybeQueue(this.next, arguments);
	},
	/**
	 * Retreats the player to the previous item in its playlist.  This might
	 * not be enabled for all playlist since most playlisting will be done
	 * in javascript.  This is only for player-internal playlists.
	 *
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	previous: function()
	{
		return this.maybeQueue(this.previous, arguments);
	},
	/**
	 * @return Whether or not the super method should perform its actions
	 * @type Boolean
	 * @see #load
	 */
	error: function()
	{
		return this.maybeQueue(this.error, arguments);
	},


	/*
	Helper methods for handling Synacor video
	*/

	/**
	 * Plays a video id.  Calls the Play API to get the URL for a video id.
	 *
	 * @param {String} id The id of the video
	 * @param {Object} (optional) scope_obj The scope of the callback
	 * @param {function} (optional) success_callback The callback for Play  API success
	 * @param {function} (optional) error_callback The callback for Play API failure
	 */
	playVideoId: function(id, scope_obj, success_callback, error_callback)
	{
		var playerReady = this.maybeQueue(this.playVideoId, arguments);

		if (playerReady)
		{
			if(!scope_obj && !success_callback && !error_callback)
			{
				scope_obj = this;
				success_callback = this.onPlayApiSuccess;
				error_callback = this.onPlayApiError;
			}

			this.playApi.getUrlFromId(id, scope_obj, success_callback, error_callback);
		}
	},
	/**
	 * Default success callback for the Play API as invoked by playVideoId()
	 *
	 * @param {Object} result The result of the Play API request
	 * @see #playVideoId
	 */
	onPlayApiSuccess: function(result)
	{
		this.play(result.url);
	},
	/**
	 * Default error callback for the Play API as invoked by playVideoId()
	 *
	 * @param {Object} result The result of the Play API request
	 * @see #playVideoId
	 */
	onPlayApiError: function(result)
	{
		this.error(result);
	},


	/*
	Queue methods
	*/

	/**
	 * Checks to see if the player has been initialized and is ready
	 * for interaction.  If not, this adds the command to a queue to be
	 * called later once the player is initialized.
	 *
	 * @param {function} func The function to be queued if the player is not ready
	 * @param {Array} args Arguments to be passed to the function
	 * @returns whether or not the player is ready for communication
	 * @type Boolean
	 */
	maybeQueue: function(func, args)
	{	
		if(!this.isPlayerReady)
		{
			this.queuedEvents.push({"func":func, "args":args});
		}
		return this.isPlayerReady;
	},
	/**
	 * When the player notifies us that it is initialized and ready, we
	 * invoke this method to call all the methods (with their args) that
	 * were queued up while the player was not yet ready.
	 *
	 * @see #setPlayerReady
	 */
	processQueuedEvents: function()
	{
		if(this.isPlayerReady)
		{
			while(this.queuedEvents.length > 0)
			{
				var obj = this.queuedEvents.shift();
				obj.func.apply(this, obj.args);
			}
		}
	},


	/*
	Event Handling
	*/

	/**
	 * A function to be called when we want to listen for a specific event
	 * from the video player.
	 *
	 * @param {String} type The type of event (listed in Syn.VideoPlayer.Events)
	 * @param {Object} scopeObj The object on which to call func
	 * @param {function} func The func to be called (on scopeObj) when the event occurs
	 * @see #removeCallback
	 */
	addCallback: function(type, scopeObj, func)
	{
		this.listeners.push({type:type,scopeObj:scopeObj,func:func});
	},
	/**
	 * Removes a callback that was added with addCallback(). Will only
	 * remove one matching listener.  If addCallback() was called more
	 * than once with the same paramters, removeCallback() must be
	 * called the same number of times.
	 *
	 * @param {String} type The type of event (in Syn.VideoPlayer.Events)
	 * @param {Object} scopeObj The object passed to addCallback()
	 * @param {function} func The func passed to addCallback()
	 * @see #addCallback
	 */
	removeCallback: function(type, scopeObj, func)
	{
		var n = this.listeners.length;
		for (var i = 0; i < n; i++)
		{
			var obj = this.listeners[i];
			if (obj.type == type && obj.scopeObj == scopeObj && obj.func == func)
			{
				this.listeners.splice(i, 1);
				return true;
			}
		}
		return false;
	},
	/**
	 * When a video player event occurs, we call this method which
	 * invokes all callbacks listening for that specific event type.
	 *
	 * @param {String} type The type of event (in Syn.VideoPlayer.Events)
	 * @param {Array} (optional) args Arguments to be passed to the callbacks
	 */
	notifyCallbacks: function(type, args)
	{
		//IE does not like null args
		if(!args)
		{
			args = [];
		}

		//IE also does not like for each
		var n = this.listeners.length;
		for (var i = 0; i < n; i++)
		{
			var obj = this.listeners[i];

			if(obj.type == type)
			{
				obj.func.apply(obj.scopeObj, args);
			}
		}
	},


	/**
	 * Call this when the player has initialized and is ready for
	 * interaction. Processes any method invokations that occurred
	 * while the player was initializing and notifies any listeners
	 * that the player is now ready.
	 */
	setPlayerReady: function()
	{
		if(!this.isPlayerReady)
		{
			this.isPlayerReady = true;
			this.processQueuedEvents();
			this.notifyCallbacks(Syn.VideoPlayer.Events.READY);
		}
	},

	/**
	 * Allow access to the id of the player.  Enables communication
	 * between Flash and JavaScript.
	 */
	getPlayerId: function()
	{
		return this.uniqueId;
	}
});

Syn.VideoPlayer.AbstractAdapter.instances = [];
Syn.VideoPlayer.AbstractAdapter.setInstance = function(id, instance)
{
	Syn.VideoPlayer.AbstractAdapter.instances[id] = instance;
};
Syn.VideoPlayer.AbstractAdapter.getInstance = function(id)
{
	return Syn.VideoPlayer.AbstractAdapter.instances[id];
};
;
/***** en_US/components/video/javascripts/player/adapters/jw_adapter.js *****/
Syn.VideoPlayer.JwAdapter = Syn.VideoPlayer.AbstractAdapter.extend(
{
	HOME_DIR: Syn.Config.Framework.AssetsRoot + "en_US/components/video/players/jw_player/",
	SKINS_DIR: Syn.Config.Framework.AssetsRoot + "en_US/components/video/players/jw_player/skins/",

	/**
	 * @constructor
	 */
	init: function()
	{
		this._super();
	},

	/**
	 * Inserts the video player into a div with the specified configuration
	 *
	 * @param {String} div HTML DIV that the player should be inserted into
	 * @param {Object} config The configuration object for the player
	 */
	insertVideoPlayer: function(div, config)
	{
		//The uniqueId for the jw_wrapper should not contain any ":"s. They
		//were making it hard to reference the player.  So strip the value
		//passed as the uniqueId, but make sure the div value is unchanged
		//so the the player is still written into a valid div.
		this._super(div.concat("_player").replace(/:/g,""), config);

		var so = new SWFObject(
				this.HOME_DIR + "player_v5.swf",
				this.uniqueId,
				"100%",
				"100%",
				config.version,
				"#000000");

		if (config.autostart === true)
		{
			config.flashVars.autostart = "true";
		}
		if (config.scaling && !config.flashVars.stretching)
		{
			config.flashVars.stretching = config.scaling;
		}
		config.flashVars.skin = this.SKINS_DIR + "stylish_small.swf";

		for (var key in config.flashVars)
		{
			if (config.flashVars.hasOwnProperty(key))
			{
				so.addVariable(key, config.flashVars[key]);
			}
		}
		for (key in config.params)
		{
			if (config.params.hasOwnProperty(key))
			{
				so.addParam(key, config.params[key]);
			}
		}
		for (key in config.attributes)
		{
			if (config.attributes.hasOwnProperty(key))
			{
				so.addAttribute(key, config.attributes[key]);
			}
		}

		so.write(div);

		//Mimic configuration
		if (config.item)
		{
			this.load(config.item);
		}
		if (config.mute === true)
		{
			this.mute();
		}
		else if (config.mute === false)
		{
			this.unmute();
		}
	},

	/**
	 * Loads an item into the player.  The call to the super method sees
	 * if the player is ready to be communicated with.  If so, call the
	 * method on the player to load the item.  If not, do nothing, as the
	 * call has been queued and will be invoked once the player is ready.
	 *
	 * @param {String|Object} The item to load
	 */
	load: function(item)
	{
		if (this._super(item))
		{
			if (item)
			{
				this.getPlayer().sendEvent('LOAD', item);
			}
		}
	},
	/**
	 * Loads then plays the item if an item is specified.  Otherwise,
	 * resumes the playback of the currently loaded item.
	 *
	 * @param {String|Object} (optional) The item to play
	 */
	play: function(item)
	{
		if (this._super(item))
		{
			this.load(item);
			this.getPlayer().sendEvent('PLAY', 'true');
		}
	},
	/**
	 * Pauses the currently playing item.
	 */
	pause: function()
	{
		if (this._super())
		{
			this.getPlayer().sendEvent('PLAY', 'false');
		}
	},
	/**
	 * Stops the currently loaded item and sets the playhead back to
	 * the start.
	 */
	stop: function()
	{
		if (this._super())
		{
			this.getPlayer().sendEvent('STOP');
		}
	},
	/**
	 * Mute
	 */
	mute: function()
	{
		if (this._super())
		{
			this.getPlayer().sendEvent('MUTE', 'true');
		}	
	},
	/**
	 * Unmute
	 */
	unmute: function()
	{
		if (this._super())
		{
			this.getPlayer().sendEvent('MUTE', 'false');
		}
	},
	/**
	 * Advances the player to the next item in the playlist.  This
	 * is only for player-internal playlists.  Keep in mind that most
	 * of our playlisting is done in javascript, so the player knows
	 * nothing about them.
	 */
	next: function()
	{
		if (this._super())
		{
			this.getPlayer().sendEvent('NEXT');
		}
	},
	/**
	 * Retreats the player to the previous item in the playlist. This
	 * is only for player-internal playlist.  Keep in mind that most
	 * of our playlisting in done in javascript, so the player knows
	 * nothing about them.
	 */
	previous: function()
	{
		if (this._super())
		{
			this.getPlayer().sendEvent('PREV');
		}
	},
	/**
	 * A generic error handler
	 *
	 * @param {String} msg The error message
	 */
	error: function(msg)
	{
		if (this._super(msg))
		{
			//this.getPlayer().sendEvent('LOAD', msg);
		}
	},


	/*
	Event Handling
	*/

	/**
	 * Called by the global handler playerReady() when the JW Player is
	 * fully initialized and ready to be communicated with.  Call the setPlayerReady()
	 * function to process the queued method calls, then add our event listeners to
	 * the player itself.
	 *
	 * @param {Object} obj Info sent from the player.  See JW Player docs for its contents.
	 */
	playerReady: function(obj)
	{
		this.setPlayerReady();

		var player = this.getPlayer();
		player.addModelListener("ERROR", "Syn.VideoPlayer.JwAdapter.modelErrorHandler");
		player.addModelListener("STATE", "Syn.VideoPlayer.JwAdapter.modelStateHandler");
	},
	/**
	 * Handles error events broadcast by the JW Player.
	 *
	 * @param {Object} dat Info sent from the JW Player.  See JW Player docs for its contents.
	 */
	modelErrorHandler: function(dat)
	{
		this.notifyCallbacks(Syn.VideoPlayer.Events.ERROR);
	},
	/**
	 * Handles state change events broadcast by the JW Player.
	 *
	 * @param {Object} dat Info sent from the JW Player.  See JW Player docs for its contents.
	 */
	modelStateHandler: function(dat)
	{
		if (dat.newstate == "COMPLETED")
		{
			this.notifyCallbacks(Syn.VideoPlayer.Events.COMPLETE);
		}
	},

	/**
	 * Player Accessor.
	 *
	 * @return The JW Player SWF instance
	*/
	getPlayer: function()
	{
		return document.getElementById(this.uniqueId);
	}
});

/*
Global Handlers
*/
Syn.VideoPlayer.JwAdapter.modelErrorHandler = function(dat)
{
	Syn.VideoPlayer.AbstractAdapter.getInstance(dat.id).modelErrorHandler(dat);
};
Syn.VideoPlayer.JwAdapter.modelStateHandler = function(dat)
{
	Syn.VideoPlayer.AbstractAdapter.getInstance(dat.id).modelStateHandler(dat);
};

/**
 * JW Player hardcoded handler.  This method cannot be namespaced since the JW Player
 * calls the playerReady function in the global namesapce by default and it cannot be
 * changed.
 *
 * @param {Object} obj Info sent by the JW Player. Contains the id of the player.
 */
var playerReady = function(obj)
{
	Syn.VideoPlayer.AbstractAdapter.getInstance(obj.id).playerReady(obj);
};
;
/***** en_US/globals/javascripts/3rdparty/jquery/jcarousellite_1.0.1.js *****/
/**
 * jCarouselLite - jQuery plugin to navigate images/any content in a carousel style widget.
 * @requires jQuery v1.2 or above
 *
 * http://gmarwaha.com/jquery/jcarousellite/
 *
 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 1.0.1
 * Note: Requires jquery 1.2 or above from version 1.0.1
 */

/**
 * Creates a carousel-style navigation widget for images/any-content from a simple HTML markup.
 *
 * The HTML markup that is used to build the carousel can be as simple as...
 *
 *  <div class="carousel">
 *      <ul>
 *          <li><img src="image/1.jpg" alt="1"></li>
 *          <li><img src="image/2.jpg" alt="2"></li>
 *          <li><img src="image/3.jpg" alt="3"></li>
 *      </ul>
 *  </div>
 *
 * As you can see, this snippet is nothing but a simple div containing an unordered list of images.
 * You don't need any special "class" attribute, or a special "css" file for this plugin.
 * I am using a class attribute just for the sake of explanation here.
 *
 * To navigate the elements of the carousel, you need some kind of navigation buttons.
 * For example, you will need a "previous" button to go backward, and a "next" button to go forward.
 * This need not be part of the carousel "div" itself. It can be any element in your page.
 * Lets assume that the following elements in your document can be used as next, and prev buttons...
 *
 * <button class="prev">&lt;&lt;</button>
 * <button class="next">&gt;&gt;</button>
 *
 * Now, all you need to do is call the carousel component on the div element that represents it, and pass in the
 * navigation buttons as options.
 *
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev"
 * });
 *
 * That's it, you would have now converted your raw div, into a magnificient carousel.
 *
 * There are quite a few other options that you can use to customize it though.
 * Each will be explained with an example below.
 *
 * @param an options object - You can specify all the options shown below as an options object param.
 *
 * @option btnPrev, btnNext : string - no defaults
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev"
 * });
 * @desc Creates a basic carousel. Clicking "btnPrev" navigates backwards and "btnNext" navigates forward.
 *
 * @option btnGo - array - no defaults
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      btnGo: [".0", ".1", ".2"]
 * });
 * @desc If you don't want next and previous buttons for navigation, instead you prefer custom navigation based on
 * the item number within the carousel, you can use this option. Just supply an array of selectors for each element
 * in the carousel. The index of the array represents the index of the element. What i mean is, if the
 * first element in the array is ".0", it means that when the element represented by ".0" is clicked, the carousel
 * will slide to the first element and so on and so forth. This feature is very powerful. For example, i made a tabbed
 * interface out of it by making my navigation elements styled like tabs in css. As the carousel is capable of holding
 * any content, not just images, you can have a very simple tabbed navigation in minutes without using any other plugin.
 * The best part is that, the tab will "slide" based on the provided effect. :-)
 *
 * @option mouseWheel : boolean - default is false
 * @example
 * $(".carousel").jCarouselLite({
 *      mouseWheel: true
 * });
 * @desc The carousel can also be navigated using the mouse wheel interface of a scroll mouse instead of using buttons.
 * To get this feature working, you have to do 2 things. First, you have to include the mouse-wheel plugin from brandon.
 * Second, you will have to set the option "mouseWheel" to true. That's it, now you will be able to navigate your carousel
 * using the mouse wheel. Using buttons and mouseWheel or not mutually exclusive. You can still have buttons for navigation
 * as well. They complement each other. To use both together, just supply the options required for both as shown below.
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      mouseWheel: true
 * });
 *
 * @option auto : number - default is null, meaning autoscroll is disabled by default
 * @example
 * $(".carousel").jCarouselLite({
 *      auto: 800,
 *      speed: 500
 * });
 * @desc You can make your carousel auto-navigate itself by specfying a millisecond value in this option.
 * The value you specify is the amount of time between 2 slides. The default is null, and that disables auto scrolling.
 * Specify this value and magically your carousel will start auto scrolling.
 *
 * @option speed : number - 200 is default
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      speed: 800
 * });
 * @desc Specifying a speed will slow-down or speed-up the sliding speed of your carousel. Try it out with
 * different speeds like 800, 600, 1500 etc. Providing 0, will remove the slide effect.
 *
 * @option easing : string - no easing effects by default.
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      easing: "bounceout"
 * });
 * @desc You can specify any easing effect. Note: You need easing plugin for that. Once specified,
 * the carousel will slide based on the provided easing effect.
 *
 * @option vertical : boolean - default is false
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      vertical: true
 * });
 * @desc Determines the direction of the carousel. true, means the carousel will display vertically. The next and
 * prev buttons will slide the items vertically as well. The default is false, which means that the carousel will
 * display horizontally. The next and prev items will slide the items from left-right in this case.
 *
 * @option circular : boolean - default is true
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      circular: false
 * });
 * @desc Setting it to true enables circular navigation. This means, if you click "next" after you reach the last
 * element, you will automatically slide to the first element and vice versa. If you set circular to false, then
 * if you click on the "next" button after you reach the last element, you will stay in the last element itself
 * and similarly for "previous" button and first element.
 *
 * @option visible : number - default is 3
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      visible: 4
 * });
 * @desc This specifies the number of items visible at all times within the carousel. The default is 3.
 * You are even free to experiment with real numbers. Eg: "3.5" will have 3 items fully visible and the
 * last item half visible. This gives you the effect of showing the user that there are more images to the right.
 *
 * @option start : number - default is 0
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      start: 2
 * });
 * @desc You can specify from which item the carousel should start. Remember, the first item in the carousel
 * has a start of 0, and so on.
 *
 * @option scrool : number - default is 1
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      scroll: 2
 * });
 * @desc The number of items that should scroll/slide when you click the next/prev navigation buttons. By
 * default, only one item is scrolled, but you may set it to any number. Eg: setting it to "2" will scroll
 * 2 items when you click the next or previous buttons.
 *
 * @option beforeStart, afterEnd : function - callbacks
 * @example
 * $(".carousel").jCarouselLite({
 *      btnNext: ".next",
 *      btnPrev: ".prev",
 *      beforeStart: function(a) {
 *          alert("Before animation starts:" + a);
 *      },
 *      afterEnd: function(a) {
 *          alert("After animation ends:" + a);
 *      }
 * });
 * @desc If you wanted to do some logic in your page before the slide starts and after the slide ends, you can
 * register these 2 callbacks. The functions will be passed an argument that represents an array of elements that
 * are visible at the time of callback.
 *
 *
 * @cat Plugins/Image Gallery
 * @author Ganeshji Marwaha/ganeshread@gmail.com
 */

(function($) {                                          // Compliant with jquery.noConflict()
$.fn.jCarouselLite = function(o) {
    o = $.extend({
        btnPrev: null,
        btnNext: null,
        btnGo: null,
        mouseWheel: false,
        auto: null,

        speed: 200,
        easing: null,

        vertical: false,
        circular: true,
        visible: 3,
        start: 0,
        scroll: 1,

        beforeStart: null,
        afterEnd: null
    }, o || {});

    return this.each(function() {                           // Returns the element collection. Chainable.
		this.o = o;

        var running = false, animCss=o.vertical?"top":"left", sizeCss=o.vertical?"height":"width";
        var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible;

        if(o.circular) {
            ul.prepend(tLi.slice(tl-v-1+1).clone())
              .append(tLi.slice(0,v).clone());
            o.start += v;
        }

        var li = $("li", ul), itemLength = li.size(), curr = o.start;
        div.css("visibility", "visible");

        li.css({overflow: "hidden", float: o.vertical ? "none" : "left"});
        ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
        div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

        var liSize = o.vertical ? height(li) : width(li);   // Full li size(incl margin)-Used for animation
        var ulSize = liSize * itemLength;                   // size of full ul(total length, not just for the visible items)
        var divSize = liSize * v;                           // size of entire div(total length for just the visible items)

        li.css({width: li.width(), height: li.height()});
        ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

        div.css(sizeCss, divSize+"px");                     // Width of the DIV. length of visible images

		var self = this;
        if(o.btnPrev)
            $(o.btnPrev).click(function() {
                return self.go(curr-o.scroll);
            });

        if(o.btnNext)
            $(o.btnNext).click(function() {
                return self.go(curr+o.scroll);
            });

        if(o.btnGo)
            $.each(o.btnGo, function(i, val) {
                $(val).click(function() {
                    return self.go(o.circular ? o.visible+i : i);
                });
            });

        if(o.mouseWheel && div.mousewheel)
            div.mousewheel(function(e, d) {
                return d>0 ? self.go(curr-o.scroll) : self.go(curr+o.scroll);
            });

        if(o.auto)
            setInterval(function() {
                self.go(curr+o.scroll);
            }, o.auto+o.speed);

        function vis() {
            return li.slice(curr).slice(0,v);
        };

        this.go = function(to) {
            if(!running) {

                if(o.beforeStart)
                    o.beforeStart.call(this, vis());

                if(o.circular) {            // If circular we are in first or last, then goto the other end
                    if(to<=o.start-v-1) {           // If first, then goto last
                        ul.css(animCss, -((itemLength-(v*2))*liSize)+"px");
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
                        curr = to==o.start-v-1 ? itemLength-(v*2)-1 : itemLength-(v*2)-o.scroll;
                    } else if(to>=itemLength-v+1) { // If last, then goto first
                        ul.css(animCss, -( (v) * liSize ) + "px" );
                        // If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
                        curr = to==itemLength-v+1 ? v+1 : v+o.scroll;
                    } else curr = to;
                } else {                    // If non-circular and to points to first or last, we just return.
                    if(to<0 || to>itemLength-v) return;
                    else curr = to;
                }                           // If neither overrides it, the curr will still be "to" and we can proceed.

                running = true;

                ul.animate(
                    animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
                    function() {
                        if(o.afterEnd)
                            o.afterEnd.call(this, vis());
                        running = false;
                    }
                );
                // Disable buttons when the carousel reaches the last/first, and enable when not
                if(!o.circular) {
                    $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
                    $( (curr-o.scroll<0 && o.btnPrev)
                        ||
                       (curr+o.scroll > itemLength-v && o.btnNext)
                        ||
                       []
                     ).addClass("disabled");
                }

            }
            return false;
        };
    });
};

function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
};
function width(el) {
    return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
};
function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
};

})(jQuery);
;
/***** en_US/components/video/embedded/scripts/videoembedded-base.js *****/
/**
 * Video Embedded Component JavaScript - No player
 */
Syn.VideoEmbeddedBase = Syn.Component.extend(
{
	/**
	 * Callback for jCarouselLite beforeStart.
	 * @param {String} id Id of the carousel
	 */
	beforeStartCallback: function(id)
	{
		if (!this.uniqueElmt(id).data("deferred_images_loaded"))
		{
			this.uniqueElmt(id).data("deferred_images_loaded", true);
			$("#" + this.uniqueKey(id) + " span.deferred_image").each(function()
			{
				var child = this.firstChild;
				if (child.nodeType === 8) // comment node
				{
					this.innerHTML = ''; // ie fix
					$(this).replaceWith(child.nodeValue);
				}
			});
		}
	}
});
;
/***** en_US/components/video/embedded/scripts/videoembedded.js *****/
/**
 * Video Embedded Component JavaScript
 */
Syn.VideoEmbedded = Syn.VideoEmbeddedBase.extend(
{
/**
	 * Contains a reference to the javascript interval or timeout used to assist banner ad display.
	 * @var mixed
	 */
	ad_animation_timeout: 0,

	/**
	 * Contains the click url of the preroll ad companion banner, which should be opened in a new window when the banner is clicked.
	 * Sent from ad provider to Flash player, which sets this var.
	 * @var string
	 */
	ad_clickurl: "",

	/**
	 * The height of the preroll ad companion banner, in pixels.
	 * @var integer
	 */
	ad_h: 250,

	/**
	 * Ad playing
	 * @var bool
	 */
	ad_playing: false,

	/**
	 * Contains a reference to the SWFObject that is used to write a Flash companion banner, if necessary.
	 * @var mixed
	 */
	ad_so: null,

	/**
	 * Contains the url of the source of the preroll ad companion banner.  Sent from ad provider to Flash player, which sets this var.
	 * @var string
	 */
	ad_url: "",

	/**
	 * The width of the preroll ad companion banner, in pixels.
	 * @var integer
	 */
	ad_w: 300,

	/**
	 * Carousel
	 * @var bool
	 */
	carousel: false,

	/**
	 * Playlist ID
	 * @var string
	 */
	pid: '',

	/**
	 * Video player object.
	 * @var object
	 */
	video_player: null,

	/**
	 * This holds the video ID that is currently being played (or, the initial video ID that will load when the player initializes).
	 * @var integer
	 */
	player_vid_id: 0,

	/**
	 * Contains a path to the video api that will convey skin and video information to the Flash player.
	 * @var string
	 */
	player_video_api_url: Syn.Config.Framework.PortalRoot + "files/video/video_api.php",

	/**
	 * Contains the selected plist item
	 * @var mixed
	 */
	selected_plist_item: 0,

	/**
	 * Tracking ID
	 * @var string
	 */
	tid: '',

	/**
	 * Is the carousel vertical?
	 * @var bool
	 */
	vertical: false,

	/**
	 * Visible videos
	 * @var int
	 */
	visible: 3,

	/**
	 * Constructor
	 * @param {object} config
	 */
	init: function(config)
	{
		this._super(config);
		var self = this;

		// Setup configuration
		this.carousel       = (config.carousel) ? config.carousel : false;
		this.pid            = (config.pid) ? config.pid : '';
		this.player_skin_id = (config.sid) ? config.sid : this.player_skin_id;
		this.tid            = (config.tid) ? config.tid : '';
		this.vertical       = (config.vertical) ? config.vertical : this.vertical;
		this.visible        = (config.visible) ? config.visible : this.visible;
		this.player_height  = (config.player_height) ? config.player_height : this.player_height;
		this.player_width   = (config.player_width) ? config.player_width : this.player_width;
		this.video_ads      = (config.video_ads) ? config.video_ads : {};
		this.video_urls     = (config.video_urls) ? config.video_urls : {};

		if ($.browser.msie && parseFloat($.browser.version) < 7.0)
		{
			var fn = function()
			{
				this.style.backgroundImage = '';
				$(this).toggleClass("embd_flash_play_on");
				self.uniqueElmt("flash_placeholder").find(".embd_flash_play").fixPngBackground();
			};
			this.uniqueElmt("flash_placeholder").find(".embd_flash_play").mouseover(fn).mouseout(fn);
		}

		if (this.carousel)
		{
			this.uniqueElmt("carousel").jCarouselLite({
				btnPrev: "#"+this.uniqueKey("previous"),
				btnNext: "#"+this.uniqueKey("next"),
				circular: false,
				scroll: parseFloat(this.visible),
				vertical: this.vertical,
				visible: parseFloat(this.visible),
				beforeStart: function()
				{
					self.beforeStartCallback("carousel");
				}
			});
			var retfalse = function()
			{
				return false;
			};
			this.uniqueElmt("previous").click(retfalse);
			this.uniqueElmt("next").click(retfalse);
		}

		var i = 0;
		this.uniqueElmt("carousel").find(">ul>li").each(function()
		{
			this.lipos = i++;
		});

		// Depending on the playlist, the title may be shown in the player area.  We
		// only need to worry about it if that element (embd_flash_title) exists.
		if (this.uniqueElmt("flash_placeholder").find(".embd_flash_placeholder_title").size())
		{
			if ($(this.selected_plist_item).size())
			{
				this.uniqueElmt("flash_placeholder").find(".embd_flash_placeholder_title span").html($(this.selected_plist_item).find("a.title").attr("title"));
				this.uniqueElmt("flash_placeholder").find(".embd_flash_placeholder_provider_date").html($(this.selected_plist_item).find("div.provider_date").html());
			}
		}

		// We need to politely ask the user to upgrade flash
		if (this.userHasFlash())
		{
			this.uniqueElmt("install").hide();
			this.uniqueElmt("flash_container").show();
			this.find("li.plist-item").connect("click", this, "playVideo");
			this.uniqueElmt("flash_placeholder").connect("click", this, "startVideo");
			this.uniqueElmt("flash_ad_close").connect("click", this, "hideBannerAd");
			this.uniqueElmt("flash_placeholder").find(".embd_flash_play").fixPngBackground();
		}
		else
		{
			var retfalse = function()
			{
				return false;
			};

			this.find("li.plist-item").click(retfalse);
			this.uniqueElmt("flash_placeholder").click(retfalse);
		}

		// First video will be loaded in a stopped state with no preroll ad.
		this.playNextVideo(true);
	},

	/**
	 * Plays the next video in the playlist
	 * @param {bool} dont_play
	 */
	playNextVideo: function(dont_play)
	{
		var element = (this.selected_plist_item) ? $(this.selected_plist_item).next() : this.uniqueElmt().find("li.plist-item").eq(0);
		if (element.size() && !element.hasClass("void"))
		{
			if (!dont_play && this.carousel)
			{
				// maybe animate the jCarouselLite maybe?
				var lipos = element.get(0).lipos;
				var to = lipos - (lipos % this.uniqueElmt("carousel").get(0).o.scroll);
				this.uniqueElmt("carousel").get(0).go( to );
			}
			this.playVideo(element, null, dont_play);
		}
	},

	/**
	 * Plays the next video in the playlist
	 */
	startVideo: function(dont_play)
	{
		var element = this.uniqueElmt().find(".vidembd-plist li").eq(0);
		if (element.size())
		{
			this.playVideo(element, null);
		}
	},

	/**
	 * Plays a video
	 * @param {Object} element The element which was clicked
	 * @param {Object} e An event object
	 * @param {bool} dont_play
	 */
	playVideo: function(element, e, dont_play)
	{
		if (!dont_play && !this.video_player)
		{
			this.createPlayer();
		}

		if (this.selected_plist_item)
		{
			if (this.selected_plist_item.display_title)
			{
				$(this.selected_plist_item).find("a.title").html(this.selected_plist_item.display_title);
			}
		}

		$(this.selected_plist_item).removeClass("plist-item-selected");
		this.selected_plist_item = element;
		$(element).addClass("plist-item-selected");

		var video_id      	= $(element).find("img").attr("alt");
		this.player_vid_id	= video_id;
		var title         	= $(element).find("a.title").attr("title");
		var display_title 	= $(element).find("a.title").html();
		var desc          	= $(element).find("div.desc").html();
		var duration      	= $(element).find("span.duration").html();

		element.display_title = display_title;
		$(element).find("a.title").html($("<strong></strong>").html("Now Playing..."));
		this.uniqueElmt("playing-video-title").html(title);
		this.uniqueElmt("playing-video-desc").html(desc);
		this.uniqueElmt("playing-video-duration").html(duration);

		// Aw man! a double negative - only log if you are playing a video
		if (!dont_play)
		{
			var lipos = (element.lipos >= 0) ? element.lipos : element.get(0).lipos;
			// Log
			this.log(video_id, this.pid, this.tid, lipos+1);

			this.video_player.play(
			{
				url: this.video_urls[video_id],
				ads: this.video_ads[video_id],
				type: 'video'
			});
		}
	},

	/**
	 * Creates the Flash video player instance with SWFObject and writes it to the appropriate div.
	 */
	createPlayer: function()
	{
		if (this.video_player)
		{
			return;
		}

		var video_config = new Syn.VideoPlayer.Config();
		video_config.plugins = {
			ads: true
		};

		this.video_player   = new Syn.VideoPlayer(
		{
			targetdiv: this.uniqueKey('flash_container', true),
			videoConfig: video_config
		});

		this.video_player.addCallback("showBannerAd", this, this.showBannerAd);
		this.video_player.addCallback("hideBannerAd", this, this.hideBannerAd);
		this.video_player.addCallback('complete', this, this.videoComplete);
		this.uniqueElmt("flash_container").css("background", "transparent");
	},

	/**
	 * Shows a banner ad
	 */
	showBannerAd: function(display_url, click_url)
	{
		// If the ad is currently playing, then we shouldn't animate the ad
		var should_animate_ad = !this.ad_playing;
		this.ad_playing = true;

		if (should_animate_ad)
		{
			var self = this;
			var anicoords = this.getAdAnimationCoords();
			var animation_object = {
				width: "311px",
				height: "260px",
				left: anicoords.left + "px"
			};

			var callback_fn = function()
			{
				self.insertAd(display_url, click_url);
			};

			// Only perform the slideout animation if the slideout isn't visible right now.
			this.uniqueElmt('flash_ad').css({
				"width": "1px",
				"left": anicoords.start_left + "px",
				"display": "block"
			}).animate(animation_object, 1500, callback_fn);
		}
		else
		{
			// No Animation
			this.insertAd(display_url, click_url);
		}

	},

	/**
	 * Does the actual inserting of the ad
	 */
	insertAd: function(display_url, click_url)
	{
		this.video_player.insertAd(this.uniqueElmt("flash_ad_container"), display_url, click_url, this.ad_w, this.ad_h);
	},

	/**
	 * Hides the banner ad
	 */
	hideBannerAd: function()
	{
		this.ad_playing = false;
		this.uniqueElmt("flash_ad_container").html("");

		if (this.uniqueElmt('flash_ad').css("display") == "block")
		{
			this.hideAd_animate();
		}
	},

	/**
	 * Logs a video
	 * @param {vid} vid
	 * @param {String} pid
	 * @param {String} tid
	 * @param {int} pos Position of the video clicked
	 */
	log: function(vid, pid, tid, pos)
	{
		// Post the video and playlist_id to the api
		$.get(this.player_video_api_url, {
			op: "log",
			vid: vid,
			pid: pid,
			tid: tid,
			pos: pos,
			source: "playlist"
		});
	},

	/**
	 * Video complete event received from the Flash video player. Actions that should occur when a video has completed playback should occur here.
	 */
	videoComplete: function()
	{
		this.playNextVideo(false);
	},

	/**
	 * Animate banner ad flyout to closed (invisible) state.  Called by hideAd to retract
	 * the companion banner flyout.
	 */
	hideAd_animate: function()
	{
		var self = this;
		var anicoords = this.getAdAnimationCoords();

		// The jQuery animation object
		var animation_obj = {
			width: "1px",
			height: "260px",
			left: anicoords.start_left //this.uniqueElmt('flash_ad_popoutloc').offset().left  + "px"
		};

		// Callback when the animation ends
		var callback_fn = function()
		{
			self.hideAd_finish();
		};

		this.uniqueElmt('flash_ad').animate(animation_obj, 400, callback_fn);

		clearInterval(this.ad_animation_timeout);
	},

	/**
	 * Finish up hiding companion banner ad.  Assures banner ad flyout is not visible and cleans up
	 * the timeout.
	 */
	hideAd_finish: function()
	{
		this.uniqueElmt("flash_ad").css("display", "none").css("width", "0px");
		this.uniqueElmt("flash_ad_container").html("");
		clearInterval(this.ad_animation_timeout);
	},

	/**
	 * Retrieve the starting and ending coordinates for the ad animation
	 * @return {Object}
	 */
	getAdAnimationCoords: function()
	{
		var comp_container = this.wrapper().eq(0);
		var offset = comp_container.getPosition();
		var border_left = parseFloat(comp_container.css("border-left-width")).NaN0();

		var start_left = offset.left - 6 + border_left;
		var left = offset.left - 317 + border_left;

		if (left < 0)
		{
			var border_right = parseFloat(comp_container.css("border-right-width")).NaN0();
			left = offset.left + comp_container.outerWidth();
			start_left = left;
			this.uniqueElmt("flash_ad").addClass("embd_player_ad_right");
		}
		else
		{
			this.uniqueElmt("flash_ad").removeClass("embd_player_ad_right");
		}

		return {
			left: left,
			start_left: start_left
		};
	},

	/**
	 * Detects whether the user has flash.
	 * @return bool
	 */
	userHasFlash: function()
	{
		var version = deconcept.SWFObjectUtil.getPlayerVersion();
		return (version.major >= 9);
	}
});
;
/***** en_US/components/facebook/javascripts/facebook_init.js *****/
/**
 * The Syn.FacebookInit Component Class
 */

/**
 * Create a Syn.FacebookInit component instance
 * @constrctor
 */
Syn.FacebookInit = Syn.Component.extend({

	init: function (config)
	{
		this._super(config);
		this.uniqueElmt('fb_static_connect_button').liveConnect('click', this, 'loadAuthentication');
	},

	/**
	 * Called when the static facebook connect button is clicked
	 * Refreshes the component using the actual authentication template
	 * @param {Object} target
	 * @param {Object} event
	 */
	loadAuthentication: function(target, event)
	{
		this.showLoading();
		this.submit({
			'action': 'auth'
		});
	}
});
;
/***** en_US/components/twitter/scripts/twitter.js *****/
/**
 * The Syn.Twitter Component Class
 */

/**
 * Create a Syn.Twitter component instance
 * @constructor
 */
Syn.Twitter = Syn.Component.extend(
{
	/**
	 * Initialize the component class. This is called automatically by the default constructor.
	 * @member Syn.Twitter
	 * @param {Object} config The configuration data structure
	 */
	init: function(config)
	{
		//Init parent class
		this._super(config);
		this.onAjaxUpdate(config);
	},

	/**
	 * Called by init and when an ajax update occurs.
	 * @member Syn.Twitter
	 * @param {Object} config The configuration data structure
	 */
	onAjaxUpdate: function(config)
	{
		this.auto_retry_handle = [];
		this.logged_in = config['logged_in'] || false;
		this.auto_refresh = config['auto_refresh'] * 1000|| false;
		this.twitter_username = config['twitter_username'] || false;
		this.request_url = Syn.Config.Framework.AppServer+'projects/twitter/request.php';
		this.ck = config['ck'] || false;
		this.cks = config['cks'] || false;

		//Default state
		this.current_state = 'getFriendsTimeline';
		this.page = 0;
		this.max_pages = 0;
		this.resetRefreshTimer();
		if (this.logged_in)
		{
			this.updateUi();
		}

		this.uniqueElmt('tweet_box').connect('keyup', this, 'checkRemainingChars');
		this.uniqueElmt('tweet_box').connect('click', this, 'checkRemainingChars');
		this.uniqueElmt('tweet_box').connect('focus', this, 'tweetBoxFocus');
		this.uniqueElmt('tweet_box').connect('blur', this, 'tweetBoxBlur');

		this.uniqueElmt('nav').find('li a')
			.connect('click', this, 'clickNav')
			.connect('click', this, 'resetRefreshTimer');

		this.uniqueElmt('submit')
			.connect('click', this, 'clickSubmit')
			.connect('click', this, 'resetRefreshTimer');

		this.uniqueElmt('refresh')
			.connect('click', this, 'doRefresh')
			.connect('click', this, 'resetRefreshTimer');

		this.uniqueElmt('logout').connect('click', this, 'clickLogout');

		this.uniqueElmt('login_button').connect('click', this, 'clickLogin');

		this.find('.twitter_name_cont:first > strong:first').html(this.twitter_username);

		var self = this;
		this.find('a[rel=external]').each(function () {
			$(this).connect('click', self, 'newWindow');
		});

	},

	/**
	 * Makes a jsonp request given parameters and a callback.
	 * Since every twiter request must have a jsonp + sid parameter these should
	 * NOT be passed to this function.
	 * @member Syn.Twitter
	 * @param {Object} params The parameters data structure
	 * @param {Function} callback The callback function to be executred
	 */
	makeRequest: function(params, callback, count)
	{
		var method = params['method'];

		if (count === null || !count)
		{
			count = 1;
		}

		var json_request = this.request_url + '?';

		for (var key in params)
		{
			json_request+=key + '=' + encodeURIComponent(params[key]) + '&';
		}
		json_request+='ck='+ encodeURIComponent(this.ck)+
		'&cks='+ encodeURIComponent(this.cks)+
		'&callback=?';

		// With jsonp having the possibility of silently failing we set a reasonably long timeout, retry once if needed, and then error.
		if (this.auto_retry_handle[method])
		{
			window.clearTimeout(this.auto_retry_handle[method]);
			this.auto_retry_handle[method] = null;
		}

		var that = this;

		this.auto_retry_handle[method] = window.setTimeout(function() {

			if (count < 2)
			{
				that.makeRequest(params, callback, count + 1);
			}
			else
			{
				// If here then we have received no response.

				window.setTimeout(function() {
					that.getComponent('component://Synacor/Portal/Components/Monitoring/Twitter/', that.config.parent_uri, {}, null, function(){});
				}, 0);

				var result = {
					error: 'Unable to connect to Twitter.  Please try again.'
				};

				callback(result);
			}
		}, 30000); // 30 Seconds

		$.getJSON(json_request, function(result)
		{
			// Stop the auto retry since we got a response
			window.clearTimeout(that.auto_retry_handle[method]);
			that.auto_retry_handle[method] = null;

			// Hide the error message in case we got data after the 30 seconds.  The error message will get displayed
			// again if an error was returned from Twitter
			that.uniqueElmt('twitter_api_error').hide();

			// Deal with the response
			if (result && result.valid_cookie !== null && result.valid_cookie == false)
			{
				$.cookie('twitter_session', null);
				that.submit();
			}
			else if (!result || (result.error && result.error == 'twitter_session_expired'))
			{
				that.submit();
			}
			else
			{
				callback(result);
			}
		});
	},

	/**
	 * Resets the refresh timer by first stopping the timer and then starting it back up again
	 * @member Syn.Twitter
	 */
	resetRefreshTimer: function()
	{
		if (this.auto_refresh)
		{
			var that = this;
			this.stopRefreshTimer();
			this.auto_refresh_timer = setInterval(function(){that.doRefresh();}, this.auto_refresh);
		}
	},

	/**
	 * Stops the frefresh timer
	 * @member Syn.Twitter
	 */
	stopRefreshTimer: function()
	{
		if (this.auto_refresh_timer)
		{
			clearInterval(this.auto_refresh_timer);
		}
	},

	/**
	 * Checks the twitter rate limit status, if the limit has been reached an error message
	 * is shown to the user.
	 * @member Syn.Twitter
	 */
	checkRateLimit: function()
	{
		var that = this;
		this.makeRequest({'method': 'rateLimitStatus'}, function(result)
		{
			if (result.remaining_hits == 0)
			{
				that.twitterTrack('error_rate_limit');
				that.uniqueElmt('twitter_api_error').text('! You exceeded Twitter\'s API limit. Check back at '+that.getUserResetTime(result.reset_time)).show();
			}
		});
	},

	/**
	 * Gets the user reset time in a human readable format. (ex: 12:01 PM)
	 * @param {String} reset_time The reset time in GMT. (This needs to be convereted to local time)
	 * @member Syn.Twitter
	 */
	getUserResetTime: function(reset_time)
	{
		var milis = Date.parse(reset_time);

		if (isNaN(milis))
		{
			return "Unknown";
		}

		var reset_date = new Date(milis);
		var hours = reset_date.getHours();
		var minutes = reset_date.getMinutes();
		var timeStr = (hours % 12 === 0 ? 12 : hours % 12) + ':' + (minutes < 10 ? '0' + minutes : minutes) + ' ' + (hours >= 12 ? 'PM' : 'AM');

		return timeStr;

	},

	/**
	 * Updates the interface based on the current state by making a request and parsing the results
	 * @member Syn.Twitter
	 */
	updateUi: function()
	{
		var that = this;
		this.showLoading();
		this.uniqueElmt('twitter_api_error').hide();
		this.makeRequest({'method': this.current_state,'page': this.page}, function(result)
		{
			if (result && result.error)
			{
				that.uniqueElmt('twitter_api_error').text(result.error).show();
			}
			else
			{
				that.page = result['page'];

				//If we receive no data and we are not on the first page already then we need to decrement a page and try again
				if (that.page > 0 && (result === null || result['data'] === null || result['data'] == ''))
				{
					that.page -= 1;
					that.updateUi();
				}

				that.max_pages = result['max_pages'];
				that.processPagination(result['page'] + 1, result['max_pages']);
				that.processData(result['data']);
				that.checkRemainingChars(that.uniqueElmt('tweet_box')[0]);

				//Hide certain items if the state is getDirects
				if (that.current_state == 'getDirects')
				{
					that.uniqueElmt('twitter_post').nextAll().find('.twitter_post_retweet, .twitter_post_reply').parent().hide();
					that.uniqueElmt('twitter_post').nextAll().find('.twitter_fav').hide();
				}
			}

			that.hideLoading();
			that.resizeColumns();
		});
	},

	/**
	 * Sets up pagination given the current page and the allowed pages
	 * @param {String} page The current page number
	 * @param {String} max_pages The max number of pages
	 * @member Syn.Twitter
	 */
	processPagination: function(page, max_pages)
	{
		var rel_page_number = (page -1) % 5;
		var page_start = 0;
		var page_end = 0;

		// Remove the pagination items that is NOT the template, or prev/next buttons
		this.uniqueElmt('twitter_pagination').empty();

		// Sliding window pagination logic - Page is not near end points
		if (page >= 3 && ((page + 2) <= max_pages))
		{
			page_start = page - 2;
			page_end = page + 2;
		}
		else //Otherwise, we have to do some fancy math as we are near an endpoint
		{
			page_start = Math.max(1, Math.min(page - rel_page_number, max_pages - 4));
			page_end = Math.min(page_start + 4, max_pages);
		}

		//The logic below is for showing/hiding the prev/next active/inactive states
		if (page == 1)
		{
			this.uniqueElmt('twitter_pagination').append('<span class="twitter_pag_prev">&laquo; Prev</span>');
		}
		else
		{
			this.uniqueElmt('twitter_pagination').append('<a href="#" class="twitter_pag_prev">&laquo; Prev</a>');
		}

		if (page == max_pages)
		{
			this.uniqueElmt('twitter_pagination').append('<span class="twitter_pag_next">Next &raquo</span>');
		}
		else
		{
			this.uniqueElmt('twitter_pagination').append('<a href="#" class="twitter_pag_next">Next &raquo</a>');
		}

		this.uniqueElmt('twitter_pagination').find('a.twitter_pag_prev')
			.connect("click", this, "clickPrev")
			.connect("click", this, "resetRefreshTimer");

		this.uniqueElmt('twitter_pagination').find('a.twitter_pag_next')
			.connect("click", this, "clickNext")
			.connect("click", this, "resetRefreshTimer");

		for (var k = page_start; k<=page_end; k++)
		{
			var elem;

			if (k == page)
			{
				elem = $(document.createElement('span')).text(k);
			}
			else
			{
				elem = $(document.createElement('a')).text(k).attr('rel', k - 1).connect('click', this, 'clickPage');
			}

			elem.show();
			this.uniqueElmt('twitter_pagination').find('.twitter_pag_next').before(elem);
		}
	},

	/**
	 * Processes the data returned from a jsonp request and creates the interface
	 * @param {Object} data The data returned from the API
	 * @member Syn.Twitter
	 */
	processData: function(data)
	{
		if (data && !data.error)
		{
			this.uniqueElmt('twitter_post').nextAll().remove();

			for (var k=0; k<data.length; k++)
			{
				var item = data[k];
				var cloned_template = this.uniqueElmt('twitter_post').clone()
					.find('img.twitter_post_img')
						.attr('src', item.user.profile_image_url)
						.attr('rel', item.user.screen_name)
						.attr('title', 'Reply to ' + item.user.screen_name)
						.connect('click', this, 'clickReply')
						.end()
					.find('div.twitter_post_text a.twitter_name')
						.attr('href', 'http://www.twitter.com/' + item.user.screen_name)
						.text(item.user.screen_name)
						.end()
					.find('p.twitter_status_text')
						.html(this.breakWords(item.text) + " <cite>" + item.created_at + "</cite>")
						.end()
					.find('a.twitter_fav')
						.attr('rel', (item.favorited ? 'destroyFavorite' : 'createFavorite') + '_' + item.id)
						.connect('click', this, 'clickFavorite')
						.connect('click', this, 'resetRefreshTimer')
						.end()
					.find('a.twitter_post_reply')
						.attr('rel', item.user.screen_name)
						.attr('title', 'Reply to ' + item.user.screen_name)
						.connect('click', this, 'clickReply')
						.end()
					.find('a.twitter_post_direct_message')
						.attr('rel', item.user.screen_name)
						.connect('click', this, 'clickDirectMessage')
						.end()
					.find('a.twitter_post_retweet')
						.attr('rel', item.user.screen_name)
						.connect('click', this, 'clickRetweet')
						.end()
					.css('display', '')
					.attr('id','');

				if (item.favorited)
				{
					cloned_template.find('a.twitter_fav').addClass('twitter_fav_on');
				}

				if (item.user.screen_name == this.twitter_username)
				{
					cloned_template.find('a.twitter_post_direct_message, a.twitter_post_reply, a.twitter_post_retweet').parent().css('display', 'none');
				}
				this.uniqueElmt('twitter_posts').append(cloned_template);
			}
		}
		else
		{
			this.checkRateLimit();
		}
	},

	/**
	 * Update remaining character count on keyup
	 * @member Syn.Twitter
	 * @param {Object} t DOM element
	 * @param {Object} e Event object
	 */
	checkRemainingChars: function(t,e)
	{
		if (t)
		{
			var remaining = 140 - t.value.length;
			var label = this.uniqueElmt('remaining_label');
			if (remaining < 0)
			{
				label.addClass('twitter_char_count_neg');
				this.uniqueElmt('tweet_box').addClass('twitter_over_limit_input');
				this.uniqueElmt('submit').attr('disabled', 'disabled');
				this.uniqueElmt('submit').addClass('submit_disabled');
			}
			else
			{
				label.removeClass('twitter_char_count_neg');
				this.uniqueElmt('tweet_box').removeClass('twitter_over_limit_input');
				this.uniqueElmt('submit').attr('disabled', '');
				this.uniqueElmt('submit').removeClass('submit_disabled');
			}
			label.html(remaining + '');
		}
	},

	/**
	 * Called when the tweet box gains focus
	 * @member Syn.Twitter
	 * @param {Object} dom DOM element
	 * @param {Object} event Event object
	 */
	tweetBoxFocus: function(dom,event)
	{
		if ($(dom).val() == 'What are you doing?')
		{
			$(dom).val("");
		}
		return true;
	},

	/**
	 * Called when the tweet box loses focus
	 * @member Syn.Twitter
	 * @param {Object} dom DOM element
	 * @param {Object} event Event object
	 */
	tweetBoxBlur: function(dom, event)
	{
		if ($(dom).val() === '')
		{
			$(dom).val('What are you doing?');
		}
		this.checkRemainingChars(this.uniqueElmt('tweet_box')[0]);
		return true;
	},

	/**
	 * Called when the user submits their new status
	 * @member Syn.Twitter
	 * @param {Object} dom DOM element
	 * @param {Object} event Event object
	 */
	clickSubmit: function(dom, event)
	{
		var that = this;
		this.showLoading();
		this.makeRequest({'method': 'updateStatus', 'text': this.uniqueElmt('tweet_box').val()}, function(result)
		{
			if (!result.error)
			{
				var text = that.uniqueElmt('tweet_box').val();

				if (text.substr(0,2) == 'RT')
				{
					that.twitterTrack('retweet');
				}
				else if (text.substr(0, 2) == 'D ')
				{
					that.twitterTrack('direct_message');
				}
				else if (text.substr(0,1) == '@')
				{
					that.twitterTrack('reply');
				}
				else
				{
					that.twitterTrack('status');
				}

				//Update rel attribute so home button tracking does not trigger on update
				that.uniqueElmt('home')
					.attr('rel', 'getFriendsTimeline')
					.trigger('click');
				that.uniqueElmt('tweet_box').val('What are you doing?');
			}
			else
			{
				that.checkRateLimit();
			}
		});
	},

	/**
	 * Does a refresh (either automatic or manual) clears cache then updates the UI.
	 * @member Syn.Twitter
	 */
	doRefresh: function()
	{
		var that = this;

		this.makeRequest({'method': 'clearCache'}, function(result)
		{
			that.page = 0;
			that.updateUi();
		});
	},


	/**
	 * Called when the prev buttion is clicked.
	 * @member Syn.Twitter
	 */
	clickPrev: function()
	{
		if (this.page > 0)
		{
			this.twitterTrack('prev_page');
			this.page--;
			this.updateUi();
		}
	},

	/**
	 * Called when the next buttion is clicked.
	 * @member Syn.Twitter
	 */
	clickNext: function()
	{
		if (this.page + 1 < this.max_pages)
		{
			this.twitterTrack('next_page');
			this.page++;
			this.updateUi();
		}
	},

	/**
	 * Called when a page link is clicked.
	 * @member Syn.Twitter
	 */
	clickPage: function(dom, event)
	{
		this.twitterTrack('specific_page');
		this.page = $(dom).attr('rel');
		this.updateUi();
	},

	/**
	 * Called when the reply button is clicked
	 * @member Syn.Twitter
	 * @param {Object} t DOM element
	 * @param {Object} e Event object
	 */
	clickReply: function(t,e)
	{
		this.uniqueElmt('tweet_box').val('@'+$(t).attr('rel')+' ').focus().keyup();
	},

	/**
	 * Called when the direct message button is clicked
	 * @member Syn.Twitter
	 * @param {Object} t DOM element
	 * @param {Object} e Event object
	 */
	clickDirectMessage: function(t,e)
	{
		this.uniqueElmt('tweet_box').val('D '+$(t).attr('rel')+' ').focus().keyup();
	},

	/**
	 * Called when the retweet button is clicked
	 * @member Syn.Twitter
	 * @param {Object} t DOM element
	 * @param {Object} e Event object
	 */
	clickRetweet: function(t,e)
	{
		var p = $(t).parent().parent().parent().find('p').clone();
		p.find('cite').remove();
		var tweet_text = p.text();
		this.uniqueElmt('tweet_box').val('RT @'+$(t).attr('rel')+' '+tweet_text).focus().keyup();
	},

	/**
	 * Called when the favorite buttion is clicked
	 * @member Syn.Twitter
	 * @param {Object} dom DOM element
	 * @param {Object} event Event object
	 */
	clickFavorite: function(dom, event)
	{
		var that = this;
		var parts = $(dom).attr('rel').split('_', 2);
		var method = parts[0];
		var status_id = parts[1];
		this.uniqueElmt('twitter_api_error').hide();
		this.showLoading();
		this.makeRequest({'method': method, 'status_id': status_id}, function(result)
		{
			if (result.error)
			{
				that.twitterTrack('error_favorite_status');
				that.uniqueElmt('twitter_api_error').text('Unable to change favorite status, please try again').show();
				that.hideLoading();
			}
			else
			{
				if (that.current_state == 'getFavorites')
				{
					that.updateUi();
				}
				else
				{
					that.hideLoading();
					if (method == 'createFavorite')
					{
						$(dom).removeClass().addClass('twitter_fav_on')
							.attr('rel', 'destroyFavorite'+ '_' + status_id);

						that.twitterTrack('favorite');
					}
					else if (method == 'destroyFavorite')
					{
						$(dom).removeClass().addClass('twitter_fav')
							.attr('rel', 'createFavorite'+ '_' + status_id);

						that.twitterTrack('unfavorite');
					}
				}
			}
		});
	},

	/**
	 * Called when the login button is clicked
	 * @member Syn.Twitter
	 */
	clickLogin: function()
	{
		var that = this;
		this.showLoading();

		//Get request_token and open the window to Twitter on success
		that.makeRequest({'method': 'verifyCredentials'}, function(result)
		{
			if (!result.authorization_url)
			{
				that.twitterTrack('error_login');
				that.uniqueElmt('twitter_login_error').show();
				that.hideLoading();
			}
			else
			{
				that.twitterTrack('login');
				that.popup = window.open(result.authorization_url, '_blank','height=550,width=750,status=yes');

				var interval_callback = function()
				{
					if (!that.popup || that.popup.closed)
					{
						clearInterval(that.interval);

						that.makeRequest({'method': 'loginStatus'}, function(result)
						{
							if (result.status === true)
							{
								$.cookie('twitter_session', result.twitter_username);
							}

							that.submit();
						});
					}
				};

				if (that.interval)
				{
					clearInterval(that.interval);
				}

				that.interval = setInterval(interval_callback, 100);
			}
		});
	},

	/**
	 * Called when the logout button is clicked
	 * @member Syn.Twitter
	 */
	clickLogout: function()
	{
		var that = this;
		this.showLoading();
		this.stopRefreshTimer();
		this.makeRequest({'method': 'logout'}, function(result)
		{
			that.twitterTrack('logout');
			$.cookie('twitter_session', null);
			that.hideLoading();
			that.submit();
		});
	},

	/**
	 * Called when a nav button is clicked
	 * @member Syn.Twitter
	 * @param {Object} dom DOM element
	 * @param {Object} event Event object
	 */
	clickNav: function(dom, event)
	{
		$(dom).parent().parent().find('li').removeClass('on');
		$(dom).parent().addClass('on');
		this.current_state = $(dom).attr('rel');

		switch (this.current_state)
		{
			case 'getFriendsTimeline':
				this.twitterTrack('nav_home');
				break;
			case 'getMentions':
				this.twitterTrack('nav_mentions');
				break;
			case 'getDirects':
				this.twitterTrack('nav_direct');
				break;
			case 'getFavorites':
				this.twitterTrack('nav_favorite');
				break;
			case 'update':
				//Update rel attribute so home button tracking will trigger the next time it is clicked
				this.uniqueElmt('home').attr('rel', 'getFriendsTimeline');
				break;
		}

		this.page = 0;
		this.updateUi();
	},

	/**
	 * Shows the loading
	 * @member Syn.Twitter
	 */
	showLoading: function()
	{
		this.uniqueElmt('loading')
			.height(this.container().height())
			.show();
	},

	/**
	 * Hides the loading
	 * @member Syn.Twitter
	 */
	hideLoading: function()
	{
		this.uniqueElmt('loading').hide();
	},

	/**
	 * Called to track an action the user has taken
	 * @member Syn.Twitter
	 * @param {String} action The user action to log
	 */
	twitterTrack: function(action)
	{
		$(document).track({
			'args' : {'track' : 'twitter', 'action' : action},
			'event' : 'instant',
			'defer' : '0'
		});
	},

	/**
	 * Used to resize columns after the component has changed its size
	 */
	resizeColumns: function()
	{
		var cdr = Syn.ComponentMgr.getInstancesByClass('Syn.ComponentDiscoveryReveal');

		if (cdr[0])
		{
			cdr[0].resizeColumns();
		}
	},

	/**
	 * Takes a string and insert breaks into words that are too long
	 * @param {string} text The text with words that need to be broken
	 * @return {string} The input string returned with breaks inserted where needed
	 */
	breakWords: function(text)
	{
		var maxWordLength = 30;
		var stringWords = text.split(' ');
		var length = 0;
		var check = 0;

		for (var i = 0; i < stringWords.length; i++)
		{
			length = stringWords[i].length;
			check = (length < 5) ? length : 5;

			if (length > maxWordLength && stringWords[i].substr(0,check) != 'href=')
			{
				for (var j = maxWordLength; j < stringWords[i].length; j += maxWordLength)
				{
					stringWords[i] = stringWords[i].substr(0, j) + '<wbr />' + stringWords[i].substr(j, stringWords[i].length);
				}
			}
		}

		return stringWords.join(' ');
	},

	/**
	 * Monitor the fact that we failed to get a connection from Twitter
	 */
	monitorAction: function()
	{
		var self = this;
		window.setTimeout(function() {
			self.getComponent('component://Synacor/Portal/Components/Monitoring/Twitter/', self.config.parent_uri, {}, null, function(){});
		}, 0);
	}
});
;
/***** en_US/components/free_games_promo/javascripts/free_games_promo.js *****/
/**
 * @version $id $
 *
 * Flash games javascript class
 */

/**
 * Create a Syn.FreeGamesPromo component instance
 * @constructor
 */
Syn.FreeGamesPromo = Syn.Component.extend (
{
	/**
	 * Initialize the component class. This is called automatically by the default constructor.
	 * @member Syn.FreeGamesPromo
	 * @param {Object} config The configuration data structure
 	*/
	init: function(config)
	{
		this._super(config);

		this.hrefToAjax(this.find('.pagination_bullets a'));

		// Bind 'change' event to the <select> dropdown.
		this.bindDropdownMenu();

		/**
		 * Note: keeping the reccently played games logic here while waiting to integrate this component
		 * fully with the Games MochiAds integration.  The recently played games functionality will need
		 * to be reapplied for this.
		 * 
		for (var i=0; this.uniqueElmt('games_thumbnail_a'+i).length; i++)
		{
			this.uniqueElmt('games_thumbnail_a'+i).liveConnect('click',this,'launchGame');
		}

		// Note that this index begins at 1 because the element number is printed next to the game link.
		for (var i=1; this.uniqueElmt('games_recent_col1_a'+i).length; i++)
		{
			this.uniqueElmt('games_recent_col1_a'+i).liveConnect('click',this,'launchGame');
		}
		// Note that this index begins at 1 because the element number is printed next to the game link.
		for (var i=1; this.uniqueElmt('games_recent_col2_a'+i).length; i++)
		{
			this.uniqueElmt('games_recent_col2_a'+i).liveConnect('click',this,'launchGame');
		}
		*/
	},

	/**
	 * 
	 */
	onAjaxUpdate: function(config)
	{
		this.config = config;

		this.hrefToAjax(this.find('.pagination_bullets a'));

		// Re-bind 'change' event to the <select> dropdown.
		this.bindDropdownMenu();
	},

	bindDropdownMenu: function()
	{
		this.uniqueElmt('games_dropdown_select').connect('change',this,'dropdownLaunchGame');
	},

	/**
	 * Submit a new thumbnailsPageIndex as per carousel pagination bullet.
	 */
	updateThumbnailsPage: function(elmt,ev)
	{
		this.submit({'action':'loadThumbnailsPage', 'thumbnails_page_index':$(elmt).html()});
	},

	/**
	 * Shows loading graphic when retrieving data
	 * @member Syn.FreeGamesPromo
	 */
	showLoading: function()
	{
		var ga = this.uniqueElmt('free_games_promo_thumbnails');
		this.uniqueElmt('free_games_promo_loading').css({'width':ga.width(),'height':ga.height()}).toggle();
	},

	/**
	 * Launches the popup window with the flash game
	 * @member Syn.FreeGamesPromo
	 */
	launchGame: function (elmt,ev)
	{
		this.submit({'action':'addRecentlyPlayedGame', 'game_token':$(elmt).attr('rel'), 'thumbnails_page_index':this.config['thumbnails_page_index']}, {norender:false});
		window.open($(elmt).attr('href'), 'gamewrapper', 'menubar=0,toolbar=0,location=0,status=0,scrollbars=0,resizable=1,directories=0,width=742,height=700');
	},

	/**
	 * Launches the popup window with the flash game
	 * @member Syn.FreeGamesPromo
	 */
	dropdownLaunchGame: function (elmt,ev)
	{
		//this.submit({'action':'addRecentlyPlayedGame', 'game_slug':$(elmt).attr('value'), 'thumbnails_page_index':this.config['thumbnails_page_index']}, {norender:false});
		window.location = Syn.Config.Framework.PortalRoot+this.config['games_channel_directory_path']+this.config['play_flash_game_page_path']+'?game_slug='+$(elmt).attr('value');
	}

});

;
/***** en_US/components/pagination/javascripts/pagination.js *****/
/**
 * The Syn.Pagination component.
 */

/**
 * Contructs a new instance of the Pagination component
 */
Syn.Pagination = Syn.Component.extend({

	/**
	 * Tracking metadata.
	 *
	 * @member Syn.Pagination
	 * @type string
	 */
	tracking_area: null,

	/**
	 * Maximum page depth.
	 *
	 * @member Syn.Pagination
	 * @type Integer
	 */
	max_page_depth: 1,

	/**
	 * Initialize the pagination component - called
	 * automatically by the default constructor.
	 *
	 * @member Syn.Pagination
	 * @param {Object} config The configuration data structure.
	 */
	init: function(config)
	{
		this._super(config);
		this.tracking_area = config.tracking_area;

		this.find('li.next a').liveConnect('click', this, 'nextPage');
		this.find('li.prev a').liveConnect('click', this, 'prevPage');
		this.find('li.page_link a').liveConnect('click', this, 'specificPage');
	},

	/**
	 * next page callback
	 *
	 * @member Syn.Pagination
	 */
	nextPage: function(target, event)
	{
		// update maximum page depth
		var next_page = this.find('li.current_page span').html() + 1;
		if (next_page > this.max_page_depth)
		{
			this.max_page_depth = next_page;
		}

		// track the click
		this.doTracking({action: 'next-page'});

		return true;
	},

	/**
	 * previous page callback
	 *
	 * @member Syn.Pagination
	 */
	prevPage: function(target, event)
	{
		// track the click
		this.doTracking({action: 'prev-page'});

		return true;
	},

	/**
	 * page number callback
	 *
	 * @member Syn.Pagination
	 */
	specificPage: function(target, event)
	{
		// update maximum page depth
		if ($(target).html() > this.max_page_depth)
		{
			this.max_page_depth = $(target).html();
		}

		// track the click
		this.doTracking({link: 'page-'+$(target).html()});

		return true;
	},

	/**
	 * sets up a tracking event
	 *
	 * @member Syn.Pagination
	 */
	doTracking: function(meta)
	{
		meta.area = this.tracking_area;
		meta.context = 'pagination';
		meta.max_page_depth = this.max_page_depth;

		// fire or bind tracking event
		$(this).track({
			pageUri: Syn.Config.Framework.Page,
			args: meta,
			module: 'Image',
			toLower: true,
			event: 'instant'
		});
	}
});

;
/***** en_US/components/PremiumMenu/js/PremiumMenu.js *****/
/**
 * Accordion Menu
 */
function initMenu()
{
	// Initialize Click events for the package headers
	$('#my_premiums .premium_item > a').click(
		function() 
		{
			$(this).next().slideToggle('normal');
			return false;
		}
		
	);
}

$(document).ready(function()
{
	initMenu();
});
;
/***** en_US/components/services/scripts/services_hover.js *****/
/**
 * The Syn.ServicesComponent Class
 */

/**
 * Create a Syn.ServicesComponent instance
 * @constructor
 */
Syn.ServicesComponentHover = Syn.Component.extend(
{
	/**
	 * Component area name - for tracking
	 */
	area: '',

	/**
	 * Meta data for each tab to use as tracking params
	 */
	meta: '',

	/**
	 * Initialize the component class. This is called automatically by the default constructor.
	 * @member Syn.ServicesComponent
	 * @param {Object} config The configuration data structure
	 */
	init: function(config)
	{
		this._super(config);
		this.clicked_components = [];
		this.active_tab = '';
		this.performUpdate();
		this.updatable = config.updatable;
		this.area = config.area;
		this.meta = config.meta;
		var self = this;
		$(window).load( function(){ self.openByDefault('serv_mail'); } );
	},

	/**
	 * A utility function to attach tracking to an element
	 *
	 * @member Syn.Services
	 * @param {String} element the element to attach tracking to
	 * @param {String} link Identify what was clicked
	 */
	attachTracking: function(element, track_data)
	{
		track_data.area = this.area;
		element.track({
			args:  track_data,
			pageUri: Syn.Config.Framework.Page,
			event: 'instant',
			toLower: true,
			module: 'Image'
		});
	},

	/**
	 * A utility function to calculate the position of a tab
	 *
	 * @member Syn.Services
	 * @param {Object} element to determine position
	 * @return {String} the position of the element
	 */
	getTabPosition: function(tab)
	{
		var horizontal = /\bservices_(left|center|right)\b/.exec(tab.attr('class'));
		var vertical = /\bservices_list_(top|bot)\b/.exec(tab.parent().parent().attr('class'));
		var position = (typeof horizontal === 'object' && typeof vertical === 'object') ? position = vertical[1] + '-' + horizontal[1] : 'unknown';
		return position;
	},

	onAjaxUpdate: function(config)
	{
		this.config = config;
		this.performUpdate();
	},

	performUpdate: function()
	{
		//hook events up
		// hook up all the tabs except tabs that have the 'services_tab_bare_link' classed anchor tags
		var that = this;
		this.uniqueElmt().find('.services_tab').each(
			function () {
				if ($(this).find('a[class="services_tab_bare_link"]').length == 0)
				{
					$(this).connect('click', that, 'linkClick');
				}
			}
		);
		//this.uniqueElmt().find('.services_tab').connect('mouseover', that, 'linkHoverEvent');
		//this.uniqueElmt().find('.services_list_nav > div').connect('mouseover', this, 'linkHover');
		//this.uniqueElmt().find('.services_list_nav > div').connect('mouseout', this, 'linkHoverOut');
		this.uniqueElmt().find('.car_arrow_next').connect('click', this, 'nextPage');
		this.uniqueElmt().find('.car_arrow_prev').connect('click', this, 'prevPage');
	},

	nextPage: function()
	{
		this.attachTracking($(this),{context: 'pagination', action: 'next'});
		this.removeCurrentInstances();
		this.submit({action: 'default', start: this.config.start, direction: 'next'});
	},

	prevPage: function()
	{
		this.attachTracking($(this),{context: 'pagination', action: 'prev'});
		this.removeCurrentInstances();
		this.submit({action: 'default', start: this.config.start, direction: 'prev'});
	},

	removeCurrentInstances: function()
	{
		this.active_tab = '';
		for (var k=0;k<this.clicked_components.length;k++)
		{
			Syn.ComponentMgr.remove(this.clicked_components[k]);
		}
		this.clicked_components = [];
	},
	
	linkHoverEvent: function(target, event)
	{
		var self = this;
		var tab = $(target);
		var uri = tab.attr('rel');
		this.uniqueElmt().find('.services_list_wrap').removeClass('on');
		this.uniqueElmt().find('.services_list_nav > div').removeClass('on');

		if (uri != '')
		{
			var zone = tab.parent().parent().find('.services_list_cont');
			zone.children('div').hide();
			var target_div = zone.find('[rel='+uri+']');
			var content_load_function = function (result)
			{
				zone.children('div').hide();
				new_target = zone.find('[rel='+uri+']');
				if (!new_target.size())
				{
					zone.append('<div rel="' + uri + '">' + result.content + '</div>');
					new_target = zone.find('[rel='+uri+']');
					new_target.show();
				}
				var instance = Syn.ComponentMgr.getInstanceByUid(result.init.event_id);
				if (instance != undefined)
				{
					self.clicked_components.push(instance);
				}
			};

			var pos = 'left';
			if (tab.prev().size())
			{
				if (tab.next().size())
				{
					pos = 'center';
				}
				else
				{
					pos = 'right';
				}
			}

			if (uri != this.active_tab)
			{
				if (target_div.size())
				{
					target_div.show();
				}
				else
				{
					zone.find('.services_loading').show();
					this.getComponent(uri, zone.attr('rel'), {'action': 'expanded'}, this, content_load_function);
				}
				this.attachTracking($(this),{
					tab: self.meta[uri].title,
					uri: uri,
					position: this.getTabPosition(tab),
					action: 'open'
				});

				this.active_tab = uri;

				zone.parent().addClass('on');
		
				zone.parent().find('.services_list_head').removeClass().addClass('services_list_head').addClass(pos);

				tab.addClass('on');
			}
			else
			{
				this.active_tab = '';
				this.attachTracking($(this),{
					tab: self.meta[uri].title,
					uri: uri,
					position: this.getTabPosition(tab),
					action: 'close'
				});
			}
		}

		this.refreshTabs();
		
	},
	
	linkClick: function(target, event)
	{
		var self = this;
		var tab = $(target);
		var uri = tab.attr('rel');
		this.uniqueElmt().find('.services_list_wrap').removeClass('on');
		this.uniqueElmt().find('.services_list_nav > div').removeClass('on');

		if (uri != '')
		{
			var zone = tab.parent().parent().find('.services_list_cont');
			zone.children('div').hide();
			var target_div = zone.find('[rel='+uri+']');
			var content_load_function = function (result)
			{
				zone.children('div').hide();
				new_target = zone.find('[rel='+uri+']');
				if (!new_target.size())
				{
					zone.append('<div rel="' + uri + '">' + result.content + '</div>');
					new_target = zone.find('[rel='+uri+']');
					new_target.show();
				}
				var instance = Syn.ComponentMgr.getInstanceByUid(result.init.event_id);
				if (instance != undefined)
				{
					self.clicked_components.push(instance);
				}
			};

			var pos = 'left';
			if (tab.prev().size())
			{
				if (tab.next().size())
				{
					pos = 'center';
				}
				else
				{
					pos = 'right';
				}
			}

			if (uri != this.active_tab)
			{
				if (target_div.size())
				{
					target_div.show();
				}
				else
				{
					zone.find('.services_loading').show();
					this.getComponent(uri, zone.attr('rel'), {'action': 'expanded'}, this, content_load_function);
				}
				this.attachTracking($(this),{
					tab: self.meta[uri].title,
					uri: uri,
					position: this.getTabPosition(tab),
					action: 'open'
				});

				this.active_tab = uri;

				zone.parent().addClass('on');

				zone.parent().find('.services_list_head').removeClass().addClass('services_list_head').addClass(pos);

				tab.addClass('on');
			}
			else
			{
				this.active_tab = '';
				this.attachTracking($(this),{
					tab: self.meta[uri].title,
					uri: uri,
					position: this.getTabPosition(tab),
					action: 'close'
				});
			}
		}

		this.refreshTabs();
	},

	linkHover: function(target, event)
	{
		if (!$(target).hasClass('on'))
		{
			$(target).addClass('services_hover');
		}
	},

	linkHoverOut: function(target, event)
	{
		$(target).removeClass('services_hover');
	},

	refreshTabs: function()
	{
		var that = this;
		this.uniqueElmt().find('.services_list_nav > div').each(function(i, elem)
		{
			var uri = $(elem).attr('rel');
			if (uri)
			{
				var key = '';
				for (key in that.updatable)
				{
					if (that.updatable[key] === uri)
					{
						that.getComponent(uri, '', {'action': 'thumbnail'}, that, function(result) {
							$(elem).html(result.content);
						});
					}
				}
			}
		});
	},

	openByDefault: function(tab_class)
	{
		$('.services_hover .services_tab .'+tab_class).click();
	}
});
;
/***** en_US/components/services/scripts/services_carousel.js *****/
/**
 * The Syn.ServicesComponent Class
 */

/**
 * Create a Syn.ServicesComponent instance
 * @constructor
 */
Syn.ServicesComponentCarousel = Syn.Component.extend(
{
	/**
	 * Component area name - for tracking
	 */
	area: '',

	/**
	 * Meta data for each tab to use as tracking params
	 */
	meta: '',

	/**
	 * Initialize the component class. This is called automatically by the default constructor.
	 * @member Syn.ServicesComponent
	 * @param {Object} config The configuration data structure
	 */
	init: function(config)
	{
		this._super(config);
		this.clicked_components = [];
		this.active_tab = '';
		this.performUpdate();
		this.updatable = config.updatable;
		this.area = config.area;
		this.meta = config.meta;
	},

	/**
	 * A utility function to attach tracking to an element
	 *
	 * @member Syn.Services
	 * @param {String} element the element to attach tracking to
	 * @param {String} link Identify what was clicked
	 */
	attachTracking: function(element, track_data)
	{
		track_data.area = this.area;
		element.track({
			args:  track_data,
			pageUri: Syn.Config.Framework.Page,
			event: 'instant',
			toLower: true,
			module: 'Image'
		});
	},

	/**
	 * A utility function to calculate the position of a tab
	 *
	 * @member Syn.Services
	 * @param {Object} element to determine position
	 * @return {String} the position of the element
	 */
	getTabPosition: function(tab)
	{
		var horizontal = /\bservices_(left|center|right)\b/.exec(tab.attr('class'));
		var vertical = /\bservices_list_(top|bot)\b/.exec(tab.parent().parent().attr('class'));
		var position = (typeof horizontal === 'object' && typeof vertical === 'object') ? position = vertical[1] + '-' + horizontal[1] : 'unknown';
		return position;
	},

	onAjaxUpdate: function(config)
	{
		this.config = config;
		this.performUpdate();
	},

	performUpdate: function()
	{
		//hook events up
		// hook up all the tabs except tabs that have the 'services_tab_bare_link' classed anchor tags
		var that = this;
		this.uniqueElmt().find('.services_tab').each(
			function () {
				if ($(this).find('a[class="services_tab_bare_link"]').length == 0)
				{
					$(this).connect('click', that, 'linkClick');
				}
			}
		);
		
		//this.uniqueElmt().find('.services_list_nav > div').connect('mouseover', this, 'linkHover');
		//this.uniqueElmt().find('.services_list_nav > div').connect('mouseout', this, 'linkHoverOut');
		this.uniqueElmt().find('.car_arrow_next').connect('click', this, 'nextPage');
		this.uniqueElmt().find('.car_arrow_prev').connect('click', this, 'prevPage');
	},

	nextPage: function()
	{
		this.attachTracking($(this),{context: 'pagination', action: 'next'});
		this.removeCurrentInstances();
		this.submit({action: 'default', start: this.config.start, direction: 'next'});
	},

	prevPage: function()
	{
		this.attachTracking($(this),{context: 'pagination', action: 'prev'});
		this.removeCurrentInstances();
		this.submit({action: 'default', start: this.config.start, direction: 'prev'});
	},

	removeCurrentInstances: function()
	{
		this.active_tab = '';
		for (var k=0;k<this.clicked_components.length;k++)
		{
			Syn.ComponentMgr.remove(this.clicked_components[k]);
		}
		this.clicked_components = [];
	},

	linkClick: function(target, event)
	{
		var self = this;
		var tab = $(target);
		var uri = tab.attr('rel');
		this.uniqueElmt().find('.services_list_wrap').removeClass('on');
		this.uniqueElmt().find('.services_list_nav > div').removeClass('on');

		if (uri != '')
		{
			var zone = tab.parent().parent().find('.services_list_cont');
			zone.children('div').hide();
			var target_div = zone.find('[rel='+uri+']');
			var content_load_function = function (result)
			{
				zone.children('div').hide();
				new_target = zone.find('[rel='+uri+']');
				if (!new_target.size())
				{
					zone.append('<div rel="' + uri + '">' + result.content + '</div>');
					new_target = zone.find('[rel='+uri+']');
					new_target.show();
				}
				var instance = Syn.ComponentMgr.getInstanceByUid(result.init.event_id);
				if (instance != undefined)
				{
					self.clicked_components.push(instance);
				}
			};

			var pos = 'left';
			if (tab.prev().size())
			{
				if (tab.next().size())
				{
					pos = 'center';
				}
				else
				{
					pos = 'right';
				}
			}

			if (uri != this.active_tab)
			{
				if (target_div.size())
				{
					target_div.show();
				}
				else
				{
					zone.find('.services_loading').show();
					this.getComponent(uri, zone.attr('rel'), {'action': 'expanded'}, this, content_load_function);
				}
				this.attachTracking($(this),{
					tab: self.meta[uri].title,
					uri: uri,
					position: this.getTabPosition(tab),
					action: 'open'
				});

				this.active_tab = uri;

				zone.parent().addClass('on');

				zone.parent().find('.services_list_head').removeClass().addClass('services_list_head').addClass(pos);

				tab.addClass('on');
			}
			else
			{
				this.active_tab = '';
				this.attachTracking($(this),{
					tab: self.meta[uri].title,
					uri: uri,
					position: this.getTabPosition(tab),
					action: 'close'
				});
			}
		}

		this.refreshTabs();
	},

	linkHover: function(target, event)
	{
		if (!$(target).hasClass('on'))
		{
			$(target).addClass('services_hover');
		}
	},

	linkHoverOut: function(target, event)
	{
		$(target).removeClass('services_hover');
	},

	refreshTabs: function()
	{
		var that = this;
		this.uniqueElmt().find('.services_list_nav > div').each(function(i, elem)
		{
			var uri = $(elem).attr('rel');
			if (uri)
			{
				var key = '';
				for (key in that.updatable)
				{
					if (that.updatable[key] === uri)
					{
						that.getComponent(uri, '', {'action': 'thumbnail'}, that, function(result) {
							$(elem).html(result.content);
						});
					}
				}
			}
		});
	}
});
;
/***** en_US/components/footer_nav/javascripts/footer_nav.js *****/
/**
 * The Syn.FooterNav component controller.
 */

/**
 * Construct a Syn.FooterNav instance.
 */
Syn.FooterNav = Syn.Component.extend({

	/**
	 * Tracking metadata.
	 */
	tracking_area: null,

	/**
	 * Initialization
	 *
	 * @member Syn.FooterNav
	 * @param {Object} config The configuration data structure.
	 */
	init: function(config)
	{
		this._super(config);
		this.tracking_area = config.tracking_area;

		this.setupTracking();
		this.uniqueElmt('makeHome').liveConnect('click', this, 'makeHome');
		this.setupTracking();
	},

	/**
	 * Method to make passed in url the homepage for the user
	 * @param {object} target The targeted dom object
	 * @param {object} event The event dom object
	 */
	makeHome: function(target, event)
	{
		// Handle IE
		if (document.all)
		{
			document.body.style.behavior = 'url(#default#homepage)';
			document.body.setHomePage($(target).attr('href'));
			return false;
		}

		// Fall back to Firefox
		alert('To make ' + $(target).attr('rel') + ' your homepage - \nGo to "Options" in the "Tools" Menu. Choose the "Main" Tab from the list on the top. Click on the "Use Current Page(s)" button.');
		return false;
	},

	/**
	 * Attaches tracking events to links.
	 *
	 * @member Syn.FooterNav
	 */
	setupTracking: function()
	{
		var self = this;
		var c = 1;

		this.find('div.footer_nav_list ul').each(function()
		{
			var i = 1;
			$(this).find('li a').each(function()
			{
				$(this).track({
					pageUri: Syn.Config.Framework.Page,
					args: {
						area: self.tracking_area,
						context: 'column-'+c,
						position: i++,
						link: $(this).html()
					},
					event: 'click',
					toLower: true
				});
			});

			c++;
		});
	}

});
;
/***** en_US/components/omniture/javascripts/omniture.js *****/
/**
 * omniture.js
 * Initialize the Omniture SiteCatalyst code
 * and call the $.track function on document.ready.
 */

/**
 * Global Omniture variables
 * This are global on purpose so that Omniture will work correctly.
 */
var s_account;
var s;

/**
 * @constructor
 */
Syn.Omniture = Syn.Component.extend (
{
	/**
	 * Used to track how long we've been locked,
	 * and if it's more than a few seconds, automatically
	 * unlock.
	 */
	intervalCount: 0,

	/**
	 * Init function to setup the class.
	 * This sets up any default params to pass to
	 * Omniture, and then on document ready, it initializes
	 * the Omniture code into the s object. And finnaly,
	 * it fires the initial page level tracking call to Omniture.
	 * @member Syn.Omniture
	 * @access public
	 * @param (object) config The configuration data structure.
	 * @return NULL
	 */
	init: function(config)
	{
		this._super(config);
		this.intervalId;
		var self = this;
		Syn.Tracking.Omniture.setSValues(config.s);

		/**
		 * On document.ready, setup Omniture.
		 */
		$(document).ready(function()
		{
			/**
			 * Add link tracking to all links on the page.
			 * This must be here (instead of further down in this file).
			 */
			if (self.config.track_links && self.config.track_links === true)
			{
				self.config.track_links_title_svalue = (self.config.track_links_title_svalue) ? self.config.track_links_title_svalue : 'prop1';
				self.config.track_links_pageName_svalue = (self.config.track_links_pageName_svalue) ? self.config.track_links_pageName_svalue : 'prop2';
				$('a').each(function()
					{
						if ($(this).attr('href') !== '' && $(this).attr('href') !== '#')
						{
							var svalues = {};
							svalues[self.config.track_links_pageName_svalue] = (Syn.Config.Omniture.s.pageName) ? Syn.Config.Omniture.s.pageName : '';
							if ($(this).attr('title') !== '')
							{
								svalues[self.config.track_links_title_svalue] = $(this).attr('title');
							}
							else if ($(this).text() !== '')
							{
								svalues[self.config.track_links_title_svalue] = $(this).text();
							}
							else
							{
								svalues[self.config.track_links_title_svalue] = '';
							}
							$(this).track(
								{
									'event' : 'click',
									'module' : 'Omniture',
									'args' :
									{
										'svalues' : svalues
									},
									'defer' : 'load'
								}
							);
						}
					}
				);
			}
			if (Syn.Config.Omniture.lockCount > 0)
			{
				/**
				 * If we are supposed to pause, start an interval
				 * to keep checking the pause variable.
				 */
				self.intervalId = setInterval(function()
				{
					self.pauseHandler(config);
				}, 100);
			}
			else
			{
				/**
				 * Initialize omniture right now.
				 */
				self.pauseHandler(config);
			}
		});
	},

	pauseHandler : function(config)
	{
		if (Syn.Config.Omniture.lockCount > 0 && this.intervalCount < 50) //50 * 100ms = 5 seconds
		{
			this.intervalCount++;
			return;
		}
		else
		{
			clearInterval(this.intervalId);
		}

		var self = this;

		/**
		 * Use setTimeout before initializing
		 * Omniture so that any other $track events
		 * that have been defined get called first.
		 * This is so that we only make a single call
		 * to Omniture on document.ready.
		 */
		setTimeout(function(){
			/**
			 * Set global Omniture variables.
			 */
			s_account = self.config.account;
			s=s_gi(s_account);

			/**
			 * NOTE:
			 * The following functions are from Omniture.
			 * They are defined here on purpose.
			 */

			/**
			 * Start of 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 ''");
			/**
			 * End of plugin.
			 */

			/**
			 * Start of Plugin: Days since last Visit 1.1.H - capture time from last visit
			 */
			s.getDaysSinceLastVisit=new Function("c",""
			+"if(!c){c='dslv';};"
			+"var s=this,e=new Date(),es=new Date(),cval,cval_s,cval_ss,ct=e.getT"
			+"ime(),day=24*60*60*1000,f1,f2,f3,f4,f5;e.setTime(ct+3*365*day);es.s"
			+"etTime(ct+30*60*1000);f0='Cookies Not Supported';f1='First Visit';f"
			+"2='More than 30 days';f3='More than 7 days';f4='Less than 7 days';f"
			+"5='Less than 1 day';cval=s.c_r(c);if(cval.length==0){s.c_w(c,ct,e);"
			+"s.c_w(c+'_s',f1,es);}else{var d=ct-cval;if(d>30*60*1000){if(d>30*da"
			+"y){s.c_w(c,ct,e);s.c_w(c+'_s',f2,es);}else if(d<30*day+1 && d>7*day"
			+"){s.c_w(c,ct,e);s.c_w(c+'_s',f3,es);}else if(d<7*day+1 && d>day){s."
			+"c_w(c,ct,e);s.c_w(c+'_s',f4,es);}else if(d<day+1){s.c_w(c,ct,e);s.c"
			+"_w(c+'_s',f5,es);}}else{s.c_w(c,ct,e);cval_ss=s.c_r(c+'_s');s.c_w(c"
			+"+'_s',cval_ss,es);}}cval_s=s.c_r(c+'_s');if(cval_s.length==0) retur"
			+"n f0;else if(cval_s!=f1&&cval_s!=f2&&cval_s!=f3&&cval_s!=f4&&cval_s"
			+"!=f5) return '';else return cval_s;");
			/**
			 * End of plugin.
			 */

			/**
			 * Start of Plugin: getNewRepeat 1.0 - Return whether user is new or repeat
			 */
			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';");
			/**
			 * End of plugin.
			 */

			/**
			 * Start of Plugin: Visit Number By Month 2.0 - Return the user visit number
			 */
			s.getVisitNum=new Function(""
			+"var s=this,e=new Date(),cval,cvisit,ct=e.getTime(),c='s_vnum',c2='s"
			+"_invisit';e.setTime(ct+30*24*60*60*1000);cval=s.c_r(c);if(cval){var"
			+" i=cval.indexOf('&vn='),str=cval.substring(i+4,cval.length),k;}cvis"
			+"it=s.c_r(c2);if(cvisit){if(str){e.setTime(ct+30*60*1000);s.c_w(c2,'"
			+"true',e);return str;}else return 'unknown visit number';}else{if(st"
			+"r){str++;k=cval.substring(0,i);e.setTime(k);s.c_w(c,k+'&vn='+str,e)"
			+";e.setTime(ct+30*60*1000);s.c_w(c2,'true',e);return str;}else{s.c_w"
			+"(c,ct+30*24*60*60*1000+'&vn=1',e);e.setTime(ct+30*60*1000);s.c_w(c2"
			+",'true',e);return 1;}}"
			);
			/**
			 * End of plugin.
			 */

			/**
			 * Start of Custom Plugin: Page Tag - Return the page_tag meta tag.
			 */
			s.getPageTag=new Function (""
			+"var pt = $(\"head meta[name='page_tag']\").attr('content');"
			+"return (pt) ? pt : '';"
			);
			/**
			 * End of plugin.
			 */

			/**
			 * Eval any customProps (in self.config.cp) and write their output
			 * to the svalues array.
			 */
			if (self.config.cp)
			{
				var tmps = {};
				var cp = self.config.cp;
				for (var k in cp)
				{
					if (cp.hasOwnProperty(k))
					{
						tmps[k] = s[cp[k]]();
					}
				}
				Syn.Tracking.Omniture.setSValues(tmps);
			}

			/**
			 * Do initial page tracking now.
			 * I am calling the record function directly, because
			 * at this point, I can not call document.ready.
			 * It has already happened, so if I bound a handler
			 * to it, it would never fire. I can not use
			 * the 'instant' event. I must use 'ready' for this to
			 * work.
			 */
			Syn.Tracking.Omniture.record({
				'module' : 'Omniture',
				'event' : 'ready',
				'args' : {},
				'defer' : '0'
			});
		}, 0);
	}
});

;
/***** en_US/components/omniture/javascripts/sitecatalyst.js *****/
/* SiteCatalyst code version: H.21. */
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(){var s=this,i,k,v,c=s_gi+'var s=s_gi(\"'+s.oun+'\");s.sa(\"'+s.un+'\");';for(i=0;i<s.va_g.length;i++){k=s.va"
+"_g[i];v=s[k];if(v!=undefined){if(typeof(v)=='string')c+='s.'+k+'=\"'+s_fe(v)+'\";';else c+='s.'+k+'='+v+';'}}c+=\"s.lnk=s.eo=s.linkName=s.linkType=s.wd.s_objectID=s.ppu=s.pe=s.pev1=s.pev2=s.pev3=''"
+";\";return c};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.cookieDomainPerio"
+"ds;if(d&&!s.c_d){n=n?parseInt(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=funct"
+"ion(k){var s=this;k=s.ape(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)}cat"
+"ch(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=th"
+"is;return s.tfs};s.gtfsoe=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.gtfs"
+"f=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.br"
+"l;if(br){if(!s.disableBufferedRequests)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.trackingServerBa"
+"se,p='.sc',ns=s.visitorNamespace,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'){if(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.21/'+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(\"'+un+'\");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.n"
+"ame))){b=e=new Date;while(!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]='';return 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=this,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.sub"
+"string(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.linkTrackVars,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+',').in"
+"dexOf(','+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=='visitorMigrationServ"
+"erSecure'){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=='cookieDomainPeriods')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=='browserWidth')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.toL"
+"owerCase():'';h=h?h.toLowerCase():'';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.locatio"
+"n.hostname;h=h.toLowerCase();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)))return '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 Functi"
+"on('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'||t=='BUTTON')&&o.type&&o.type.toUppe"
+"rCase)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(t=='INPUT'||t=='SUBMIT'){if(o.value)n=o.value;"
+"else if(o.innerText)n=o.innerText;else if(o.textContent)n=o.textContent;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.epa(t.substring(e+1));s.sqq[q]='';if(e>=0)s.pt(t.substring(0,e),',','sqs',q);return 0};s.s"
+"qs=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.sqq=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.l"
+"inks.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=functio"
+"n(){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.e"
+"h(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.dyna"
+"micAccountMatch,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.oun+',').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.toUpperCase())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).indexOf('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.sub"
+"string(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.createElement){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=f2;o.l=0;':'')+'o.src=u;c.appendChild(o);'+(n?'o.c=0;o.i=setTimeout(f2,100)':'')+'}}catc"
+"h(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.d"
+"ll)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.max"
+"Delay)s.maxDelay=250;s.dlt()};s.t=function(vo,id){var s=this,trk=1,tm=new Date,sed=Math&&Math.random?Math.floor(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.getMinutes()+':'+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 Objec"
+"t;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.plugins}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.p"
+"l)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.colorDepth=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)ret"
+"urn '';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(\".tl(\")>=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 tr"
+"k=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('objectID');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',vb);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.userAgen"
+"t;s.ns6=s.u.indexOf('Netscape6/');var apn=s.n.appName,v=s.n.appVersion,ie=v.indexOf('MSIE '),o=s.u.indexOf('Opera '),i;if(v.indexOf('Opera')>=0||o>0)apn='Opera';s.isie=(apn=='Microsoft Internet Exp"
+"lorer');s.isns=(apn=='Netscape');s.isopera=(apn=='Opera');s.ismac=(s.u.indexOf('Mac')>=0);if(o>0)s.apv=parseFloat(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,visitorMigrationServer,visitorMigrationServerSecure,ppu,charSet,visitorNamespace,cookieDomainPeriods,"
+"cookieLifetime,pageName,pageURL,referrer,currencyCode';s.va_l=s.sp(s.vl_l,',');s.vl_t=s.vl_l+',variableProvider,channel,server,pageType,transactionID,purchaseID,campaign,state,zip,events,products,l"
+"inkName,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,pev2,pev3,resolution,colorDepth,javascriptVersion,javaEnabled,cookiesEnabled,browserWidt"
+"h,browserHeight,connectionType,homepage,plugins';s.vl_t+=s.vl_l2;s.va_t=s.sp(s.vl_t,',');s.vl_g=s.vl_t+',trackingServer,trackingServerSecure,trackingServerBase,fpCookieDomainPeriods,disableBuffered"
+"Requests,mobile,visitorSampling,visitorSamplingGroup,dynamicAccountSelection,dynamicAccountList,dynamicAccountMatch,trackDownloadLinks,trackExternalLinks,trackInlineStats,linkLeaveQueryString,linkD"
+"ownloadFileTypes,linkExternalFilters,linkInternalFilters,linkTrackVars,linkTrackEvents,linkNames,lnk,eo,_1_referrer';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)}

;
