/**
 * Rian Player Source start cap
 *	wa-fixes: 
 * 	3785 +_wrapper.className = _container.className;
 *  3575,3971 + mamage interactive html5 player size;
 *
 */
/* Examples
   rianplayer("rianMediaPlayer").setup({
    height: 410,
    width: 640,
    size_mode: 'Custom', // fix for injects
    'modes': [
    {
            type: 'flash',
            src: '/rian-media-player/MediaPlayer.swf',
            config: {
                flashvars: {
                    playlistUrl: 'http://www.ria.ru/services/smil_conf.xml?art_id=470769866&smil=smil_facebook.xml',
                    libraryPath: '/rian-media-player/lib',
                    id: 'mediaPlayer',
                    info_id: 357751752,
                    autostart:0,
                    version: '1.5.19'
                }
            }
        },

        {
          type: 'html5',
          config: {
            sources: [
               { file: 'http://nfw.content-video.ru/flv/file.aspx?ID=21701090&amp;type=iPad' },
               { file: 'http://nfw.content-video.ru/flv/file.aspx?ID=21701090&amp;type=mp4_1000' },
               { file: 'http://nfw.content-video.ru/flv/file.aspx?ID=21701090&amp;type=webm' }
            ],
          }
        },


    ]
    });
*/

 if (typeof rianplayer == "undefined") {/**
 * Rian Player namespace definition
 * @version 5.8
 */
var rianplayer = function(container) {
	if (rianplayer.api){
		return rianplayer.api.selectPlayer(container);
	}

	if (ASXLoader != undefined) {
		this.asxLoader;
	} else {
		if (console && console.log){
			console.error('Please, include ASXLoader.js to Page')
		}
	}
};


// "Shiv" method for older IE browsers; required for parsing media tags
rianplayer.vid = document.createElement("video");
rianplayer.audio = document.createElement("audio");
rianplayer.source = document.createElement("source");/**
 * Utility methods for the Rian Player.
 *
 * @author zach, pablo
 * @version 5.9
 */
(function(rianplayer) {

	rianplayer.utils = function() {
	};

	/** Returns the true type of an object * */

	/**
	 *
	 * @param {Object}
	 *            value
	 */
	rianplayer.utils.typeOf = function(value) {
		var s = typeof value;
		if (s === 'object') {
			if (value) {
				if (value instanceof Array) {
					s = 'array';
				}
			} else {
				s = 'null';
			}
		}
		return s;
	};

	/** Merges a list of objects * */
	rianplayer.utils.extend = function() {
		var args = rianplayer.utils.extend['arguments'];
		if (args.length > 1) {
			for ( var i = 1; i < args.length; i++) {
				for ( var element in args[i]) {
					args[0][element] = args[i][element];
				}
			}
			return args[0];
		}
		return null;
	};

	/**
	 * Returns a deep copy of an object.
	 *
	 * @param {Object}
	 *            obj
	 */
	rianplayer.utils.clone = function(obj) {
		var result;
		var args = rianplayer.utils.clone['arguments'];
		if (args.length == 1) {
			switch (rianplayer.utils.typeOf(args[0])) {
			case "object":
				result = {};
				for ( var element in args[0]) {
					result[element] = rianplayer.utils.clone(args[0][element]);
				}
				break;
			case "array":
				result = [];
				for ( var element in args[0]) {
					result[element] = rianplayer.utils.clone(args[0][element]);
				}
				break;
			default:
				return args[0];
				break;
			}
		}
		return result;
	};

	/** Returns the extension of a file name * */
	rianplayer.utils.extension = function(path) {
		if (!path) { return ""; }
		path = path.substring(path.lastIndexOf("/") + 1, path.length);
		path = path.split("?")[0];
		if (path.lastIndexOf('.') > -1) {
			return path.substr(path.lastIndexOf('.') + 1, path.length)
					.toLowerCase();
		}
		return;
	};

	/** Updates the contents of an HTML element * */
	rianplayer.utils.html = function(element, content) {
		element.innerHTML = content;
	};

	/** Wraps an HTML element with another element * */
	rianplayer.utils.wrap = function(originalElement, appendedElement) {
		if (originalElement.parentNode) {
			originalElement.parentNode.replaceChild(appendedElement,
					originalElement);
		}
		appendedElement.appendChild(originalElement);
	};

	/** Loads an XML file into a DOM object * */
	rianplayer.utils.ajax = function(xmldocpath, completecallback, errorcallback) {
		var xmlhttp;
		if (window.XMLHttpRequest) {
			// IE>7, Firefox, Chrome, Opera, Safari
			xmlhttp = new XMLHttpRequest();
		} else {
			// IE6
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState === 4) {
				if (xmlhttp.status === 200) {
					if (completecallback) {
						// Handle the case where an XML document was returned with an incorrect MIME type.
						if (!rianplayer.utils.exists(xmlhttp.responseXML)) {
							try {
								if (window.DOMParser) {
									var parsedXML = (new DOMParser()).parseFromString(xmlhttp.responseText,"text/xml");
									if (parsedXML) {
										xmlhttp = rianplayer.utils.extend({}, xmlhttp, {responseXML:parsedXML});
									}
								} else {
									// Internet Explorer
									parsedXML = new ActiveXObject("Microsoft.XMLDOM");
									parsedXML.async="false";
									parsedXML.loadXML(xmlhttp.responseText);
									xmlhttp = rianplayer.utils.extend({}, xmlhttp, {responseXML:parsedXML});
								}
							} catch(e) {
								if (errorcallback) {
									errorcallback(xmldocpath);
								}
							}
						}
						completecallback(xmlhttp);
					}
				} else {
					if (errorcallback) {
						errorcallback(xmldocpath);
					}
				}
			}
		};
		try {
			xmlhttp.open("GET", xmldocpath, true);
			xmlhttp.send(null);
		} catch (error) {
			if (errorcallback) {
				errorcallback(xmldocpath);
			}
		}
		return xmlhttp;
	};

	/** Loads a file * */
	rianplayer.utils.load = function(domelement, completecallback, errorcallback) {
		domelement.onreadystatechange = function() {
			if (domelement.readyState === 4) {
				if (domelement.status === 200) {
					if (completecallback) {
						completecallback();
					}
				} else {
					if (errorcallback) {
						errorcallback();
					}
				}
			}
		};
	};

	/** Finds tags in a DOM, returning a new DOM * */
	rianplayer.utils.find = function(dom, tag) {
		return dom.getElementsByTagName(tag);
	};

	/** * */

	/** Appends an HTML element to another element HTML element * */
	rianplayer.utils.append = function(originalElement, appendedElement) {
		originalElement.appendChild(appendedElement);
	};

	/**
	 * Detects whether the current browser is IE !+"\v1" technique from
	 * http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
	 * Note - this detection no longer works for IE9, hence the detection for
	 * window.ActiveXObject
	 */
	rianplayer.utils.isIE = function() {
		return ((!+"\v1") || (typeof window.ActiveXObject != "undefined"));
	};

	rianplayer.utils.userAgentMatch = function(regex) {
		var agent = navigator.userAgent.toLowerCase();
		return (agent.match(regex) !== null);
	};

	/**
	 * Detects whether the current browser is mobile Safari.
	 */
	rianplayer.utils.isIOS = function() {
		return rianplayer.utils.userAgentMatch(/iP(hone|ad|od)/i);
	};

	rianplayer.utils.isIPad = function() {
		return rianplayer.utils.userAgentMatch(/iPad/i);
	};

	rianplayer.utils.isIPod = function() {
		return rianplayer.utils.userAgentMatch(/iP(hone|od)/i);
	};

	rianplayer.utils.isAndroid = function() {
		return rianplayer.utils.userAgentMatch(/android/i);
	};

	/**
	 * Detects whether the current browser is Android 2.0, 2.1 or 2.2 which do
	 * have some support for HTML5
	 */
	rianplayer.utils.isLegacyAndroid = function() {
		return rianplayer.utils.userAgentMatch(/android 2.[012]/i);
	};


	rianplayer.utils.isBlackberry = function() {
		return rianplayer.utils.userAgentMatch(/blackberry/i);
	};

	/** Matches iOS and Android devices **/
	rianplayer.utils.isMobile = function() {
		return rianplayer.utils.userAgentMatch(/(iP(hone|ad|od))|android/i);
	}


	rianplayer.utils.getFirstPlaylistItemFromConfig = function(config) {
		var item = {};
		var playlistItem;
		if (config.playlist && config.playlist.length) {
			playlistItem = config.playlist[0];
		} else {
			playlistItem = config;
		}
		item.file = playlistItem.file;
		item.levels = playlistItem.levels;
		item.streamer = playlistItem.streamer;
		item.playlistfile = playlistItem.playlistfile;

		item.provider = playlistItem.provider;
		if (!item.provider) {
			if (item.file
					&& (item.file.toLowerCase().indexOf("youtube.com") > -1 || item.file
							.toLowerCase().indexOf("youtu.be") > -1)) {
				item.provider = "youtube";
			}
			if (item.streamer
					&& item.streamer.toLowerCase().indexOf("rtmp://") == 0) {
				item.provider = "rtmp";
			}
			if (playlistItem.type) {
				item.provider = playlistItem.type.toLowerCase();
			}
		}

		if (item.provider == "audio") {
			item.provider = "sound";
		}

		return item;
	}

	/**
	 * Replacement for "outerHTML" getter (not available in FireFox)
	 */
	rianplayer.utils.getOuterHTML = function(element) {
		if (element.outerHTML) {
			return element.outerHTML;
		} else {
			try {
				return new XMLSerializer().serializeToString(element);
			} catch (err) {
				return "";
			}
		}
	};

	/**
	 * Replacement for outerHTML setter (not available in FireFox)
	 */
	rianplayer.utils.setOuterHTML = function(element, html) {
		if (element.outerHTML) {
			element.outerHTML = html;
		} else {
			var el = document.createElement('div');
			el.innerHTML = html;
			var range = document.createRange();
			range.selectNodeContents(el);
			var documentFragment = range.extractContents();
			element.parentNode.insertBefore(documentFragment, element);
			element.parentNode.removeChild(element);
		}
	};

	/**
	 * Detects whether or not the current player has flash capabilities TODO:
	 * Add minimum flash version constraint: 9.0.115
	 */
	rianplayer.utils.hasFlash = function() {
		if (typeof navigator.plugins != "undefined"
				&& typeof navigator.plugins['Shockwave Flash'] != "undefined") {
			return true;
		}
		if (typeof window.ActiveXObject != "undefined") {
			try {
				new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
				return true
			} catch (err) {
			}
		}
		return false;
	};

	/**
	 * Extracts a plugin name from a string
	 */
	rianplayer.utils.getPluginName = function(pluginName) {
		if (pluginName.lastIndexOf("/") >= 0) {
			pluginName = pluginName.substring(pluginName.lastIndexOf("/") + 1,
					pluginName.length);
		}
		if (pluginName.lastIndexOf("-") >= 0) {
			pluginName = pluginName.substring(0, pluginName.lastIndexOf("-"));
		}
		if (pluginName.lastIndexOf(".swf") >= 0) {
			pluginName = pluginName
					.substring(0, pluginName.lastIndexOf(".swf"));
		}
		if (pluginName.lastIndexOf(".js") >= 0) {
			pluginName = pluginName.substring(0, pluginName.lastIndexOf(".js"));
		}
		return pluginName;
	};

	/**
	 * Extracts a plugin version from a string
	 */
	rianplayer.utils.getPluginVersion = function(pluginName) {
		if (pluginName.lastIndexOf("-") >= 0) {
			if (pluginName.lastIndexOf(".js") >= 0) {
				return pluginName.substring(pluginName.lastIndexOf("-") + 1,
						pluginName.lastIndexOf(".js"));
			} else if (pluginName.lastIndexOf(".swf") >= 0) {
				return pluginName.substring(pluginName.lastIndexOf("-") + 1,
						pluginName.lastIndexOf(".swf"));
			} else {
				return pluginName.substring(pluginName.lastIndexOf("-") + 1);
			}
		}
		return "";
	};

	/** Gets an absolute file path based on a relative filepath * */
	rianplayer.utils.getAbsolutePath = function(path, base) {
		if (!rianplayer.utils.exists(base)) {
			base = document.location.href;
		}
		if (!rianplayer.utils.exists(path)) {
			return undefined;
		}
		if (isAbsolutePath(path)) {
			return path;
		}
		var protocol = base.substring(0, base.indexOf("://") + 3);
		var domain = base.substring(protocol.length, base.indexOf('/',
				protocol.length + 1));
		var patharray;
		if (path.indexOf("/") === 0) {
			patharray = path.split("/");
		} else {
			var basepath = base.split("?")[0];
			basepath = basepath.substring(protocol.length + domain.length + 1,
					basepath.lastIndexOf('/'));
			patharray = basepath.split("/").concat(path.split("/"));
		}
		var result = [];
		for ( var i = 0; i < patharray.length; i++) {
			if (!patharray[i] || !rianplayer.utils.exists(patharray[i])
					|| patharray[i] == ".") {
				continue;
			} else if (patharray[i] == "..") {
				result.pop();
			} else {
				result.push(patharray[i]);
			}
		}
		return protocol + domain + "/" + result.join("/");
	};

	function isAbsolutePath(path) {
		if (!rianplayer.utils.exists(path)) {
			return;
		}
		var protocol = path.indexOf("://");
		var queryparams = path.indexOf("?");
		return (protocol > 0 && (queryparams < 0 || (queryparams > protocol)));
	}

	/**
	 * Types of plugin paths
	 */
	rianplayer.utils.pluginPathType = {
		// TODO: enum
		ABSOLUTE : "ABSOLUTE",
		RELATIVE : "RELATIVE",
		CDN : "CDN"
	}

	/*
	 * Test cases getPathType('hd') getPathType('hd-1') getPathType('hd-1.4')
	 *
	 * getPathType('http://plugins.longtailvideo.com/5/hd/hd.swf')
	 * getPathType('http://plugins.longtailvideo.com/5/hd/hd-1.swf')
	 * getPathType('http://plugins.longtailvideo.com/5/hd/hd-1.4.swf')
	 *
	 * getPathType('./hd.swf') getPathType('./hd-1.swf')
	 * getPathType('./hd-1.4.swf')
	 */
	rianplayer.utils.getPluginPathType = function(path) {
		if (typeof path != "string") {
			return;
		}
		path = path.split("?")[0];
		var protocol = path.indexOf("://");
		if (protocol > 0) {
			return rianplayer.utils.pluginPathType.ABSOLUTE;
		}
		var folder = path.indexOf("/");
		var extension = rianplayer.utils.extension(path);
		if (protocol < 0 && folder < 0 && (!extension || !isNaN(extension))) {
			return rianplayer.utils.pluginPathType.CDN;
		}
		return rianplayer.utils.pluginPathType.RELATIVE;
	};

	rianplayer.utils.mapEmpty = function(map) {
		for ( var val in map) {
			return false;
		}
		return true;
	};

	rianplayer.utils.mapLength = function(map) {
		var result = 0;
		for ( var val in map) {
			result++;
		}
		return result;
	};

	/** Logger * */
	rianplayer.utils.log = function(msg, obj) {
		if (typeof console != "undefined" && typeof console.log != "undefined") {
			if (obj) {
				console.log(msg, obj);
			} else {
				console.log(msg);
			}
		}
	};

	/**
	 *
	 * @param {Object}
	 *            domelement
	 * @param {Object}
	 *            styles
	 * @param {Object}
	 *            debug
	 */
	rianplayer.utils.css = function(domelement, styles, debug) {
		if (rianplayer.utils.exists(domelement)) {
			for ( var style in styles) {
				try {
					if (typeof styles[style] === "undefined") {
						continue;
					} else if (typeof styles[style] == "number"
							&& !(style == "zIndex" || style == "opacity")) {
						if (isNaN(styles[style])) {
							continue;
						}
						if (style.match(/color/i)) {
							styles[style] = "#"
									+ rianplayer.utils.strings.pad(styles[style]
											.toString(16), 6);
						} else {
							styles[style] = Math.ceil(styles[style]) + "px";
						}
					}
					domelement.style[style] = styles[style];
				} catch (err) {
				}
			}
		}
	};

	rianplayer.utils.isYouTube = function(path) {
		return (path.indexOf("youtube.com") > -1 || path.indexOf("youtu.be") > -1);
	};

	/**
	 *
	 * @param {Object}
	 *            domelement
	 * @param {Object}
	 *            xscale
	 * @param {Object}
	 *            yscale
	 * @param {Object}
	 *            xoffset
	 * @param {Object}
	 *            yoffset
	 */
	rianplayer.utils.transform = function(domelement, xscale, yscale, xoffset, yoffset) {
		// Set defaults
		if (!rianplayer.utils.exists(xscale)) xscale = 1;
		if (!rianplayer.utils.exists(yscale)) yscale = 1;
		if (!rianplayer.utils.exists(xoffset)) xoffset = 0;
		if (!rianplayer.utils.exists(yoffset)) yoffset = 0;

		if (xscale == 1 && yscale == 1 && xoffset == 0 && yoffset == 0) {
			domelement.style.webkitTransform = "";
			domelement.style.MozTransform = "";
			domelement.style.OTransform = "";
		} else {
			var value = "scale("+xscale+","+yscale+") translate("+xoffset+"px,"+yoffset+"px)";

			domelement.style.webkitTransform = value;
			domelement.style.MozTransform = value;
			domelement.style.OTransform = value;
		}
	};

	/**
	 * Stretches domelement based on stretching. parentWidth, parentHeight,
	 * elementWidth, and elementHeight are required as the elements dimensions
	 * change as a result of the stretching. Hence, the original dimensions must
	 * always be supplied.
	 *
	 * @param {String}
	 *            stretching
	 * @param {DOMElement}
	 *            domelement
	 * @param {Number}
	 *            parentWidth
	 * @param {Number}
	 *            parentHeight
	 * @param {Number}
	 *            elementWidth
	 * @param {Number}
	 *            elementHeight
	 */
	rianplayer.utils.stretch = function(stretching, domelement, parentWidth,
			parentHeight, elementWidth, elementHeight) {
		if (typeof parentWidth == "undefined"
				|| typeof parentHeight == "undefined"
				|| typeof elementWidth == "undefined"
				|| typeof elementHeight == "undefined") {
			return;
		}
		var xscale = parentWidth / elementWidth;
		var yscale = parentHeight / elementHeight;
		var x = 0;
		var y = 0;
		var transform = false;
		var style = {};

		if (domelement.parentElement) {
			domelement.parentElement.style.overflow = "hidden";
		}

		rianplayer.utils.transform(domelement);

		switch (stretching.toUpperCase()) {
		case rianplayer.utils.stretching.NONE:
			// Maintain original dimensions
			style.width = elementWidth;
			style.height = elementHeight;
			style.top = (parentHeight - style.height) / 2;
			style.left = (parentWidth - style.width) / 2;
			break;
		case rianplayer.utils.stretching.UNIFORM:
			// Scale on the dimension that would overflow most
			if (xscale > yscale) {
				// Taller than wide
				style.width = elementWidth * yscale;
				style.height = elementHeight * yscale;
				if (style.width/parentWidth > 0.95) {
					transform = true;
					xscale = Math.ceil(100 * parentWidth / style.width) / 100;
					yscale = 1;
					style.width = parentWidth;
				}
			} else {
				// Wider than tall
				style.width = elementWidth * xscale;
				style.height = elementHeight * xscale;
				if (style.height/parentHeight > 0.95) {
					transform = true;
					xscale = 1;
					yscale = Math.ceil(100 * parentHeight / style.height) / 100;
					style.height = parentHeight;
				}
			}
			style.top = (parentHeight - style.height) / 2;
			style.left = (parentWidth - style.width) / 2;
			break;
		case rianplayer.utils.stretching.FILL:
			// Scale on the smaller dimension and crop
			if (xscale > yscale) {
				style.width = elementWidth * xscale;
				style.height = elementHeight * xscale;
			} else {
				style.width = elementWidth * yscale;
				style.height = elementHeight * yscale;
			}
			style.top = (parentHeight - style.height) / 2;
			style.left = (parentWidth - style.width) / 2;
			break;
		case rianplayer.utils.stretching.EXACTFIT:
			// Distort to fit
//			rianplayer.utils.transform(domelement, [ "scale(", xscale, ",",
//					yscale, ")", " translate(0px,0px)" ].join(""));
			style.width = elementWidth;
			style.height = elementHeight;

			var xoff = Math.round((elementWidth / 2) * (1-1/xscale));
			var yoff = Math.round((elementHeight / 2) * (1-1/yscale));

			transform = true;
			//style.width = style.height = "100%";
			style.top = style.left = 0;

			break;
		default:
			break;
		}

		if (transform) {
			rianplayer.utils.transform(domelement, xscale, yscale, xoff, yoff);
		}

		rianplayer.utils.css(domelement, style);
	};

	// TODO: enum
	rianplayer.utils.stretching = {
		NONE : "NONE",
		FILL : "FILL",
		UNIFORM : "UNIFORM",
		EXACTFIT : "EXACTFIT"
	};

	/**
	 * Recursively traverses nested object, replacing key names containing a
	 * search string with a replacement string.
	 *
	 * @param searchString
	 *            The string to search for in the object's key names
	 * @param replaceString
	 *            The string to replace in the object's key names
	 * @returns The modified object.
	 */
	rianplayer.utils.deepReplaceKeyName = function(obj, searchString, replaceString) {
		switch (rianplayer.utils.typeOf(obj)) {
		case "array":
			for ( var i = 0; i < obj.length; i++) {
				obj[i] = rianplayer.utils.deepReplaceKeyName(obj[i],
						searchString, replaceString);
			}
			break;
		case "object":
			for ( var key in obj) {
				var searches, replacements;
				if (searchString instanceof Array && replaceString instanceof Array) {
					if (searchString.length != replaceString.length)
						continue;
					else {
						searches = searchString;
						replacements = replaceString;
					}
				} else {
					searches = [searchString];
					replacements = [replaceString];
				}
				var newkey = key;
				for (var i=0; i < searches.length; i++) {
					newkey = newkey.replace(new RegExp(searchString[i], "g"), replaceString[i]);
				}
				obj[newkey] = rianplayer.utils.deepReplaceKeyName(obj[key], searchString, replaceString);
				if (key != newkey) {
					delete obj[key];
				}
			}
			break;
		}
		return obj;
	}

	/**
	 * Returns true if an element is found in a given array
	 *
	 * @param array
	 *            The array to search
	 * @param search
	 *            The element to search
	 */
	rianplayer.utils.isInArray = function(array, search) {
		if (!(array) || !(array instanceof Array)) {
			return false;
		}

		for ( var i = 0; i < array.length; i++) {
			if (search === array[i]) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Returns true if the value of the object is null, undefined or the empty
	 * string
	 *
	 * @param a
	 *            The variable to inspect
	 */
	rianplayer.utils.exists = function(a) {
		switch (typeof (a)) {
		case "string":
			return (a.length > 0);
			break;
		case "object":
			return (a !== null);
		case "undefined":
			return false;
		}
		return true;
	}

	/**
	 * Removes all of an HTML container's child nodes
	 **/
	rianplayer.utils.empty = function(elem) {
		if (typeof elem.hasChildNodes == "function") {
			while(elem.hasChildNodes()) {
				elem.removeChild(elem.firstChild);
			}
		}
	}

	/**
	 * Cleans up a css dimension (e.g. '420px') and returns an integer.
	 */
	rianplayer.utils.parseDimension = function(dimension) {
		if (typeof dimension == "string") {
			if (dimension === "") {
				return 0;
			} else if (dimension.lastIndexOf("%") > -1) {
				return dimension;
			} else {
				return parseInt(dimension.replace("px", ""), 10);
			}
		}
		return dimension;
	}

	/**
	 * Returns dimensions (x,y,width,height) of a display object
	 */
	rianplayer.utils.getDimensions = function(obj) {
		if (obj && obj.style) {
			return {
				x: rianplayer.utils.parseDimension(obj.style.left),
				y: rianplayer.utils.parseDimension(obj.style.top),
				width: rianplayer.utils.parseDimension(obj.style.width),
				height: rianplayer.utils.parseDimension(obj.style.height)
			};
		} else {
			return {};
		}
	}

	/**
	 * Gets the clientWidth of an element, or returns its style.width
	 */
	rianplayer.utils.getElementWidth = function(obj) {
		if (!obj) {
			return null;
		} else if (obj == document.body) {
			return rianplayer.utils.parentNode(obj).clientWidth;
		} else if (obj.clientWidth > 0) {
			return obj.clientWidth;
		} else if (obj.style) {
			return rianplayer.utils.parseDimension(obj.style.width);
		} else {
			return null;
		}
	}

	/**
	 * Gets the clientHeight of an element, or returns its style.height
	 */
	rianplayer.utils.getElementHeight = function(obj) {
		if (!obj) {
			return null;
		} else if (obj == document.body) {
			return rianplayer.utils.parentNode(obj).clientHeight;
		} else if (obj.clientHeight > 0) {
			return obj.clientHeight;
		} else if (obj.style) {
			return rianplayer.utils.parseDimension(obj.style.height);
		} else {
			return null;
		}
	}



	/** Format the elapsed / remaining text. **/
	rianplayer.utils.timeFormat = function(sec) {
		str = "00:00";
		if (sec > 0) {
			str = Math.floor(sec / 60) < 10 ? "0" + Math.floor(sec / 60) + ":" : Math.floor(sec / 60) + ":";
			str += Math.floor(sec % 60) < 10 ? "0" + Math.floor(sec % 60) : Math.floor(sec % 60);
		}
		return str;
	}


	/** Returns true if the player should use the browser's native fullscreen mode **/
	rianplayer.utils.useNativeFullscreen = function() {
		//return rianplayer.utils.isIOS(); // Only use iOS for now -- Safari's video.webkitRequestFullScreen is buggy
		return (navigator && navigator.vendor && navigator.vendor.indexOf("Apple") == 0);
	}

	/** Returns an element's parent element.  If no parent is available, return the element itself **/
	rianplayer.utils.parentNode = function(element) {
		if (!element) {
			return document.body;
		} else if (element.parentNode) {
			return element.parentNode;
		} else if (element.parentElement) {
			return element.parentElement;
		} else {
			return element;
		}
	}

	/** Replacement for getBoundingClientRect, which isn't supported in iOS 3.1.2 **/
	rianplayer.utils.getBoundingClientRect = function(element) {
		if (typeof element.getBoundingClientRect == "function") {
			return element.getBoundingClientRect();
		} else {
			return {
				left: element.offsetLeft + document.body.scrollLeft,
				top: element.offsetTop + document.body.scrollTop,
				width: element.offsetWidth,
				height: element.offsetHeight
			};
		}
	}

	/* Normalizes differences between Flash and HTML5 internal players' event responses. */
	rianplayer.utils.translateEventResponse = function(type, eventProperties) {
		var translated = rianplayer.utils.extend({}, eventProperties);
		if (type == rianplayer.api.events.rianplayer_FULLSCREEN && !translated.fullscreen) {
			translated.fullscreen = translated.message == "true" ? true : false;
			delete translated.message;
		} else if (typeof translated.data == "object") {
			// Takes ViewEvent "data" block and moves it up a level
			translated = rianplayer.utils.extend(translated, translated.data);
			delete translated.data;
		} else if (typeof translated.metadata == "object") {
			rianplayer.utils.deepReplaceKeyName(translated.metadata, ["__dot__","__spc__","__dsh__"], ["."," ","-"]);
		}

		var rounders = ["position", "duration", "offset"];
		for (var rounder in rounders) {
			if (translated[rounders[rounder]]) {
				translated[rounders[rounder]] = Math.round(translated[rounders[rounder]] * 1000) / 1000;
			}
		}

		return translated;
	}

	rianplayer.utils.saveCookie = function(name, value) {
		document.cookie = "rianplayer." + name + "=" + value + "; path=/";
	}

	rianplayer.utils.getCookies = function() {
		var rianCookies = {};
		var cookies = document.cookie.split('; ');
		for (var i=0; i<cookies.length; i++) {
			var split = cookies[i].split('=');
			if (split[0].indexOf("rianplayer.") == 0) {
				rianCookies[split[0].substring(9, split[0].length)] = split[1];
			}
		}
		return rianCookies;
	}

	rianplayer.utils.readCookie = function(name) {
		return rianplayer.utils.getCookies()[name];
	}

	rianplayer.utils.createASXLoader = function(callback) {
		if (ASXLoader && typeof(ASXLoader) == 'function'){
			var asx = new ASXLoader(callback);
			return asx;
		} else {
			return false;
		}
	}


	/* Crate Polling services for Live video and start it */
	rianplayer.utils.startLiveViewsPolling = function(config,callback) {
		if (!config.hasOwnProperty('mediaId') || !config.hasOwnProperty('articleId')) { throw "mediaID or articleID is not defined in rianplayer.utils.startLiveMetaPolling"; return;}
		var mediaId  = config.mediaId,
			articleId = config.articleId;
			pollingInterval = config.pollingInterval || 30000

		if (!rianplayer.utils.livePollingService) {
			rianplayer.utils.livePollingService = setInterval(ajaxPolling, pollingInterval)
			ajaxPolling.call(this);
		}

		function ajaxPolling() {
			var URL = '/services/media/' + mediaId + '-info.html?page_type=json&article_id=' + articleId;
			$.ajax({url: URL, dataType: 'json', success:callback})
		}
	}

	/* Stop Polling services for Live video */
	rianplayer.utils.stopLiveViewsPolling = function(config) {
		if (rianplayer.utils.livePollingService) {
			clearInterval(rianplayer.utils.livePollingService);
		}
	}


})(rianplayer);
/**
 * Event namespace defintion for the Rian Player
 *
 * @author zach
 * @version 5.5
 */
(function(rianplayer) {
	rianplayer.events = function() {
	};

	rianplayer.events.COMPLETE = "COMPLETE";
	rianplayer.events.ERROR = "ERROR";
})(rianplayer);
/**
 * Event dispatcher for the Rian Player
 *
 * @author zach
 * @version 5.5
 */
(function(rianplayer) {
	rianplayer.events.eventdispatcher = function(debug) {
		var _debug = debug;
		var _listeners;
		var _globallisteners;

		/** Clears all event listeners **/
		this.resetEventListeners = function() {
			_listeners = {};
			_globallisteners = [];
		};

		this.resetEventListeners();

		/** Add an event listener for a specific type of event. **/
		this.addEventListener = function(type, listener, count) {
			try {
				if (!rianplayer.utils.exists(_listeners[type])) {
					_listeners[type] = [];
				}

				if (typeof(listener) == "string") {
					eval("listener = " + listener);
				}
				_listeners[type].push({
					listener: listener,
					count: count
				});
			} catch (err) {
				rianplayer.utils.log("error", err);
			}
			return false;
		};


		/** Remove an event listener for a specific type of event. **/
		this.removeEventListener = function(type, listener) {
			if (!_listeners[type]) {
				return;
			}
			try {
				for (var listenerIndex = 0; listenerIndex < _listeners[type].length; listenerIndex++) {
					if (_listeners[type][listenerIndex].listener.toString() == listener.toString()) {
						_listeners[type].splice(listenerIndex, 1);
						break;
					}
				}
			} catch (err) {
				rianplayer.utils.log("error", err);
			}
			return false;
		};

		/** Add an event listener for all events. **/
		this.addGlobalListener = function(listener, count) {
			try {
				if (typeof(listener) == "string") {
					eval("listener = " + listener);
				}
				_globallisteners.push({
					listener: listener,
					count: count
				});
			} catch (err) {
				rianplayer.utils.log("error", err);
			}
			return false;
		};

		/** Add an event listener for all events. **/
		this.removeGlobalListener = function(listener) {
			if (!listener) {
				return;
			}
			try {
				for (var globalListenerIndex = 0; globalListenerIndex < _globallisteners.length; globalListenerIndex++) {
					if (_globallisteners[globalListenerIndex].listener.toString() == listener.toString()) {
						_globallisteners.splice(globalListenerIndex, 1);
						break;
					}
				}
			} catch (err) {
				rianplayer.utils.log("error", err);
			}
			return false;
		};


		/** Send an event **/
		this.sendEvent = function(type, data) {
			if (!rianplayer.utils.exists(data)) {
				data = {};
			}
			if (_debug) {
				rianplayer.utils.log(type, data);
			}
			if (typeof _listeners[type] != "undefined") {
				for (var listenerIndex = 0; listenerIndex < _listeners[type].length; listenerIndex++) {
					try {
						_listeners[type][listenerIndex].listener(data);
					} catch (err) {
						rianplayer.utils.log("There was an error while handling a listener: " + err.toString(), _listeners[type][listenerIndex].listener);
					}
					if (_listeners[type][listenerIndex]) {
						if (_listeners[type][listenerIndex].count === 1) {
							delete _listeners[type][listenerIndex];
						} else if (_listeners[type][listenerIndex].count > 0) {
							_listeners[type][listenerIndex].count = _listeners[type][listenerIndex].count - 1;
						}
					}
				}
			}
			for (var globalListenerIndex = 0; globalListenerIndex < _globallisteners.length; globalListenerIndex++) {
				try {
					_globallisteners[globalListenerIndex].listener(data);
				} catch (err) {
					rianplayer.utils.log("There was an error while handling a listener: " + err.toString(), _globallisteners[globalListenerIndex].listener);
				}
				if (_globallisteners[globalListenerIndex]) {
					if (_globallisteners[globalListenerIndex].count === 1) {
						delete _globallisteners[globalListenerIndex];
					} else if (_globallisteners[globalListenerIndex].count > 0) {
						_globallisteners[globalListenerIndex].count = _globallisteners[globalListenerIndex].count - 1;
					}
				}
			}
		};
	};
})(rianplayer);
/**
 * Utility methods for the Rian Player.
 *
 * @author zach
 * @version 5.4
 */
(function(rianplayer) {
	var _animations = {};

	rianplayer.utils.animations = function() {
	};

	rianplayer.utils.animations.transform = function(domelement, value) {
		domelement.style.webkitTransform = value;
		domelement.style.MozTransform = value;
		domelement.style.OTransform = value;
		domelement.style.msTransform = value;
	};

	rianplayer.utils.animations.transformOrigin = function(domelement, value) {
		domelement.style.webkitTransformOrigin = value;
		domelement.style.MozTransformOrigin = value;
		domelement.style.OTransformOrigin = value;
		domelement.style.msTransformOrigin = value;
	};

	rianplayer.utils.animations.rotate = function(domelement, deg) {
		rianplayer.utils.animations.transform(domelement, ["rotate(", deg, "deg)"].join(""));
	};

	rianplayer.utils.cancelAnimation = function(domelement) {
		delete _animations[domelement.id];
	};

	rianplayer.utils.fadeTo = function(domelement, endAlpha, time, startAlpha, delay, startTime) {
		// Interrupting
		if (_animations[domelement.id] != startTime && rianplayer.utils.exists(startTime)) {
			return;
		}
		// No need to fade if the opacity is already where we're going
		if (domelement.style.opacity == endAlpha) {
			return;
		}

		var currentTime = new Date().getTime();
		if (startTime > currentTime) {
			setTimeout(function() {
				rianplayer.utils.fadeTo(domelement, endAlpha, time, startAlpha, 0, startTime);
			}, startTime - currentTime);
		}
		if (domelement.style.display == "none") {
			domelement.style.display = "block";
		}
		if (!rianplayer.utils.exists(startAlpha)) {
			startAlpha = domelement.style.opacity === "" ? 1 : domelement.style.opacity;
		}
		if (domelement.style.opacity == endAlpha && domelement.style.opacity !== "" && rianplayer.utils.exists(startTime)) {
			if (endAlpha === 0) {
				domelement.style.display = "none";
			}
			return;
		}
		if (!rianplayer.utils.exists(startTime)) {
			startTime = currentTime;
			_animations[domelement.id] = startTime;
		}
		if (!rianplayer.utils.exists(delay)) {
			delay = 0;
		}
		var percentTime = (time > 0) ? ((currentTime - startTime) / (time * 1000)) : 0;
		percentTime = percentTime > 1 ? 1 : percentTime;
		var delta = endAlpha - startAlpha;
		var alpha = startAlpha + (percentTime * delta);
		if (alpha > 1) {
			alpha = 1;
		} else if (alpha < 0) {
			alpha = 0;
		}
		domelement.style.opacity = alpha;
		if (delay > 0) {
			_animations[domelement.id] = startTime + delay * 1000;
			rianplayer.utils.fadeTo(domelement, endAlpha, time, startAlpha, 0, _animations[domelement.id]);
			return;
		}
		setTimeout(function() {
			rianplayer.utils.fadeTo(domelement, endAlpha, time, startAlpha, 0, startTime);
		}, 10);
	};
})(rianplayer);
/**
 * Arrays utility class
 *
 * @author zach
 * @version 5.5
 */
(function(rianplayer) {
	rianplayer.utils.arrays = function(){};

	/**
	 * Finds an element in an Array
	 *
	 * @param {Object} haystack
	 * @param {Object} needle
	 * @return {Number} int
	 */
	rianplayer.utils.arrays.indexOf = function(haystack, needle){
		for (var i = 0; i < haystack.length; i++){
			if (haystack[i] == needle){
				return i;
			}
		}
		return -1;
	};

	/**
	 * Removes and element from an array
	 *
	 * @param {Object} haystack
	 * @param {Object} needle
	 */
	rianplayer.utils.arrays.remove = function(haystack, needle){
		var neeedleIndex = rianplayer.utils.arrays.indexOf(haystack, needle);
		if (neeedleIndex > -1){
			haystack.splice(neeedleIndex, 1);
		}
	};
})(rianplayer);
/**
 * Rian Player Media Extension to Mime Type mapping
 *
 * @author zach
 * @version 5.4
 */
(function(rianplayer) {
	rianplayer.utils.extensionmap = {
		"3gp": {
			"html5": "video/3gpp",
			"flash": "video"
		},
		"3gpp": {
			"html5": "video/3gpp"
		},
		"3g2": {
			"html5": "video/3gpp2",
			"flash": "video"
		},
		"3gpp2": {
			"html5": "video/3gpp2"
		},
		"flv": {
			"flash": "video"
		},
		"f4a": {
			"html5": "audio/mp4"
		},
		"f4b": {
			"html5": "audio/mp4",
			"flash": "video"
		},
		"f4v": {
			"html5": "video/mp4",
			"flash": "video"
		},
		"mov": {
			"html5": "video/quicktime",
			"flash": "video"
		},
		"m4a": {
			"html5": "audio/mp4",
			"flash": "video"
		},
		"m4b": {
			"html5": "audio/mp4"
		},
		"m4p": {
			"html5": "audio/mp4"
		},
		"m4v": {
			"html5": "video/mp4",
			"flash": "video"
		},
		"mp4": {
			"html5": "video/mp4",
			"flash": "video"
		},
		"rbs":{
			"flash": "sound"
		},
		"aac": {
			"html5": "audio/aac",
			"flash": "video"
		},
		"mp3": {
			"html5": "audio/mp3",
			"flash": "sound"
		},
		"ogg": {
			"html5": "audio/ogg"
		},
		"oga": {
			"html5": "audio/ogg"
		},
		"ogv": {
			"html5": "video/ogg"
		},
		"webm": {
			"html5": "video/webm"
		},
		"m3u8": {
			"html5": "audio/x-mpegurl"
		},
		"gif": {
			"flash": "image"
		},
		"jpeg": {
			"flash": "image"
		},
		"jpg": {
			"flash": "image"
		},
		"swf":{
			"flash": "image"
		},
		"png":{
			"flash": "image"
		},
		"wav":{
			"html5": "audio/x-wav"
		}
	};
})(rianplayer);
/**
 * Parser for the Rian Player.
 *
 * @author zach
 * @version 5.4
 */
(function(rianplayer) {

	rianplayer.utils.mediaparser = function() {};

	var elementAttributes = {
		element: {
			width: 'width',
			height: 'height',
			id: 'id',
			'class': 'className',
			name: 'name'
		},
		media: {
			src: 'file',
			preload: 'preload',
			autoplay: 'autostart',
			loop: 'repeat',
			controls: 'controls'
		},
		source: {
			src: 'file',
			type: 'type',
			media: 'media',
			'data-rian-width': 'width',
			'data-rian-bitrate': 'bitrate'

		},
		video: {
			poster: 'image'
		}
	};

	var parsers = {};

	rianplayer.utils.mediaparser.parseMedia = function(element) {
		return parseElement(element);
	};

	function getAttributeList(elementType, attributes) {
		if (!rianplayer.utils.exists(attributes)) {
			attributes = elementAttributes[elementType];
		} else {
			rianplayer.utils.extend(attributes, elementAttributes[elementType]);
		}
		return attributes;
	}

	function parseElement(domElement, attributes) {
		if (parsers[domElement.tagName.toLowerCase()] && !rianplayer.utils.exists(attributes)) {
			return parsers[domElement.tagName.toLowerCase()](domElement);
		} else {
			attributes = getAttributeList('element', attributes);
			var configuration = {};
			for (var attribute in attributes) {
				if (attribute != "length") {
					var value = domElement.getAttribute(attribute);
					if (rianplayer.utils.exists(value)) {
						configuration[attributes[attribute]] = value;
					}
				}
			}
			var bgColor = domElement.style['#background-color'];
			if (bgColor && !(bgColor == "transparent" || bgColor == "rgba(0, 0, 0, 0)")) {
				configuration.screencolor = bgColor;
			}
			return configuration;
		}
	}

	function parseMediaElement(domElement, attributes) {
		attributes = getAttributeList('media', attributes);
		var sources = [];
		var sourceTags = rianplayer.utils.selectors("source", domElement);
		for (var i in sourceTags) {
			if (!isNaN(i)){
				sources.push(parseSourceElement(sourceTags[i]));
			}
		}
		var configuration = parseElement(domElement, attributes);
		if (rianplayer.utils.exists(configuration.file)) {
			sources[0] = {
				'file': configuration.file
			};
		}
		configuration.levels = sources;
		return configuration;
	}

	function parseSourceElement(domElement, attributes) {
		attributes = getAttributeList('source', attributes);
		var result = parseElement(domElement, attributes);
		result.width = result.width ? result.width : 0;
		result.bitrate = result.bitrate ? result.bitrate : 0;
		return result;
	}

	function parseVideoElement(domElement, attributes) {
		attributes = getAttributeList('video', attributes);
		var result = parseMediaElement(domElement, attributes);
		return result;
	}

	parsers.media = parseMediaElement;
	parsers.audio = parseMediaElement;
	parsers.source = parseSourceElement;
	parsers.video = parseVideoElement;


})(rianplayer);
/**
 * Loads a <script> tag
 * @author zach
 * @version 5.5
 */
(function(rianplayer) {
	//TODO: Enum
	rianplayer.utils.loaderstatus = {
		NEW: "NEW",
		LOADING: "LOADING",
		ERROR: "ERROR",
		COMPLETE: "COMPLETE"
	};

	rianplayer.utils.scriptloader = function(url) {
		var _status = rianplayer.utils.loaderstatus.NEW;
		var _eventDispatcher = new rianplayer.events.eventdispatcher();
		rianplayer.utils.extend(this, _eventDispatcher);

		this.load = function() {
			if (_status == rianplayer.utils.loaderstatus.NEW) {
				_status = rianplayer.utils.loaderstatus.LOADING;
				var scriptTag = document.createElement("script");
				// Most browsers
				scriptTag.onload = function(evt) {
					_status = rianplayer.utils.loaderstatus.COMPLETE;
					_eventDispatcher.sendEvent(rianplayer.events.COMPLETE);
				}
				scriptTag.onerror = function(evt) {
					_status = rianplayer.utils.loaderstatus.ERROR;
					_eventDispatcher.sendEvent(rianplayer.events.ERROR);
				}
				// IE
				scriptTag.onreadystatechange = function() {
					if (scriptTag.readyState == 'loaded' || scriptTag.readyState == 'complete') {
						_status = rianplayer.utils.loaderstatus.COMPLETE;
						_eventDispatcher.sendEvent(rianplayer.events.COMPLETE);
					}
					// Error?
				}
				document.getElementsByTagName("head")[0].appendChild(scriptTag);
				scriptTag.src = url;
			}

		};

		this.getStatus = function() {
			return _status;
		}
	}
})(rianplayer);
/**
 * Selectors for the Rian Player.
 *
 * @author zach
 * @version 5.4
 */
(function(rianplayer) {
	rianplayer.utils.selectors = function(selector, parent) {
		if (!rianplayer.utils.exists(parent)) {
			parent = document;
		}
		selector = rianplayer.utils.strings.trim(selector);
		var selectType = selector.charAt(0);
		if (selectType == "#") {
			return parent.getElementById(selector.substr(1));
		} else if (selectType == ".") {
			if (parent.getElementsByClassName) {
				return parent.getElementsByClassName(selector.substr(1));
			} else {
				return rianplayer.utils.selectors.getElementsByTagAndClass("*", selector.substr(1));
			}
		} else {
			if (selector.indexOf(".") > 0) {
				var selectors = selector.split(".");
				return rianplayer.utils.selectors.getElementsByTagAndClass(selectors[0], selectors[1]);
			} else {
				return parent.getElementsByTagName(selector);
			}
		}
		return null;
	};

	rianplayer.utils.selectors.getElementsByTagAndClass = function(tagName, className, parent) {
		var elements = [];
		if (!rianplayer.utils.exists(parent)) {
			parent = document;
		}
		var selected = parent.getElementsByTagName(tagName);
		for (var i = 0; i < selected.length; i++) {
			if (rianplayer.utils.exists(selected[i].className)) {
				var classes = selected[i].className.split(" ");
				for (var classIndex = 0; classIndex < classes.length; classIndex++) {
					if (classes[classIndex] == className) {
						elements.push(selected[i]);
					}
				}
			}
		}
		return elements;
	};
})(rianplayer);
/**
 * String utilities for the Rian Player.
 *
 * @author zach
 * @version 5.8
 */
(function(rianplayer) {

	rianplayer.utils.strings = function() {
	};

	/** Removes whitespace from the beginning and end of a string **/
	rianplayer.utils.strings.trim = function(inputString) {
		return inputString.replace(/^\s*/, "").replace(/\s*$/, "");
	};

	/**
	 * Pads a string
	 * @param {String} string
	 * @param {Number} length
	 * @param {String} padder
	 */
	rianplayer.utils.strings.pad = function (string, length, padder) {
		if (!padder){
			padder = "0";
		}
		while (string.length < length) {
			string = padder + string;
		}
		return string;
	}

		/**
	 * Basic serialization: string representations of booleans and numbers are returned typed;
	 * strings are returned urldecoded.
	 *
	 * @param {String} val	String value to serialize.
	 * @return {Object}		The original value in the correct primitive type.
	 */
	rianplayer.utils.strings.serialize = function(val) {
		if (val == null) {
			return null;
		} else if (val == 'true') {
			return true;
		} else if (val == 'false') {
			return false;
		} else if (isNaN(Number(val)) || val.length > 5 || val.length == 0) {
			return val;
		} else {
			return Number(val);
		}
	}


	/**
	 * Convert a time-representing string to a number.
	 *
	 * @param {String}	The input string. Supported are 00:03:00.1 / 03:00.1 / 180.1s / 3.2m / 3.2h
	 * @return {Number}	The number of seconds.
	 */
	rianplayer.utils.strings.seconds = function(str) {
		str = str.replace(',', '.');
		var arr = str.split(':');
		var sec = 0;
		if (str.substr(-1) == 's') {
			sec = Number(str.substr(0, str.length - 1));
		} else if (str.substr(-1) == 'm') {
			sec = Number(str.substr(0, str.length - 1)) * 60;
		} else if (str.substr(-1) == 'h') {
			sec = Number(str.substr(0, str.length - 1)) * 3600;
		} else if (arr.length > 1) {
			sec = Number(arr[arr.length - 1]);
			sec += Number(arr[arr.length - 2]) * 60;
			if (arr.length == 3) {
				sec += Number(arr[arr.length - 3]) * 3600;
			}
		} else {
			sec = Number(str);
		}
		return sec;
	}


	/**
	 * Get the value of a case-insensitive attribute in an XML node
	 * @param {XML} xml
	 * @param {String} attribute
	 * @return {String} Value
	 */
	rianplayer.utils.strings.xmlAttribute = function(xml, attribute) {
		for (var attrib = 0; attrib < xml.attributes.length; attrib++) {
			if (xml.attributes[attrib].name && xml.attributes[attrib].name.toLowerCase() == attribute.toLowerCase())
				return xml.attributes[attrib].value.toString();
		}
		return "";
	}

	/**
	 * Converts a JSON object into its string representation.
	 * @param obj {Object} String, Number, Array or nested Object to serialize
	 * Serialization code borrowed from
	 */
	rianplayer.utils.strings.jsonToString = function(obj) {
		// Use browser's native JSON implementation if it exists.
		var JSON = JSON || {}
		if (JSON && JSON.stringify) {
				return JSON.stringify(obj);
		}

		var type = typeof (obj);
		if (type != "object" || obj === null) {
			// Object is string or number
			if (type == "string") {
				obj = '"'+obj.replace(/"/g, '\\"')+'"';
			} else {
				return String(obj);
			}
		}
		else {
			// Object is an array or object
			var toReturn = [],
				isArray = (obj && obj.constructor == Array);

			for (var item in obj) {
				var value = obj[item];

				switch (typeof(value)) {
					case "string":
						value = '"' + value.replace(/"/g, '\\"') + '"';
						break;
					case "object":
						if (rianplayer.utils.exists(value)) {
							value = rianplayer.utils.strings.jsonToString(value);
						}
						break;
				}
				if (isArray) {
					// Array
					if (typeof(value) != "function") {
						toReturn.push(String(value));
					}
				} else {
					// Object
					if (typeof(value) != "function") {
						toReturn.push('"' + item + '":' + String(value));
					}
				}
			}

			if (isArray) {
				return "[" + String(toReturn) + "]";
			} else {
				return "{" + String(toReturn) + "}";
			}
		}
	}

})(rianplayer);
/**
 * Utility methods for the Rian Player.
 *
 * @author zach
 * @version 5.4
 */
(function(rianplayer) {
	var _colorPattern = new RegExp(/^(#|0x)[0-9a-fA-F]{3,6}/);

	rianplayer.utils.typechecker = function(value, type) {
		type = !rianplayer.utils.exists(type) ? _guessType(value) : type;
		return _typeData(value, type);
	};

	function _guessType(value) {
		var bools = ["true", "false", "t", "f"];
		if (bools.toString().indexOf(value.toLowerCase().replace(" ", "")) >= 0) {
			return "boolean";
		} else if (_colorPattern.test(value)) {
			return "color";
		} else if (!isNaN(parseInt(value, 10)) && parseInt(value, 10).toString().length == value.length) {
			return "integer";
		} else if (!isNaN(parseFloat(value)) && parseFloat(value).toString().length == value.length) {
			return "float";
		}
		return "string";
	}

	function _typeData(value, type) {
		if (!rianplayer.utils.exists(type)) {
			return value;
		}

		switch (type) {
			case "color":
				if (value.length > 0) {
					return _stringToColor(value);
				}
				return null;
			case "integer":
				return parseInt(value, 10);
			case "float":
				return parseFloat(value);
			case "boolean":
				if (value.toLowerCase() == "true") {
					return true;
				} else if (value == "1") {
					return true;
				}
				return false;
		}
		return value;
	}

	function _stringToColor(value) {
		switch (value.toLowerCase()) {
			case "blue":
				return parseInt("0000FF", 16);
			case "green":
				return parseInt("00FF00", 16);
			case "red":
				return parseInt("FF0000", 16);
			case "cyan":
				return parseInt("00FFFF", 16);
			case "magenta":
				return parseInt("FF00FF", 16);
			case "yellow":
				return parseInt("FFFF00", 16);
			case "black":
				return parseInt("000000", 16);
			case "white":
				return parseInt("FFFFFF", 16);
			default:
				value = value.replace(/(#|0x)?([0-9A-F]{3,6})$/gi, "$2");
				if (value.length == 3) {
					value = value.charAt(0) + value.charAt(0) + value.charAt(1) + value.charAt(1) + value.charAt(2) + value.charAt(2);
				}
				return parseInt(value, 16);
		}

		return parseInt("000000", 16);
	}

})(rianplayer);
/**
 * Parser class definition
 *
 * @author zach
 * @version 5.7
 */
(function(rianplayer) {

	rianplayer.utils.parsers = function() {
	};

	rianplayer.utils.parsers.localName = function(node) {
		if(!node) {
			return "";
		} else if (node.localName) {
			return node.localName;
		} else if (node.baseName) {
			return node.baseName;
		} else {
			return "";
		}
	}

	rianplayer.utils.parsers.textContent = function(node) {
		if(!node) {
			return "";
		} else if (node.textContent) {
			return node.textContent;
		} else if (node.text) {
			return node.text;
		} else {
			return "";
		}
	}

})(rianplayer);
/**
 * Parse a feed item for rianplayer content.
 *
 * @author zach
 * @version 5.7
 */
(function(rianplayer) {

	rianplayer.utils.parsers.rianparser = function() {
	};

	rianplayer.utils.parsers.rianparser.PREFIX = 'rianplayer';

	/**
	 * Parse a feed entry for rianplayer content.
	 *
	 * @param	{XML}		obj	The XML object to parse.
	 * @param	{Object}	itm	The playlistentry to amend the object to.
	 * @return	{Object}		The playlistentry, amended with the rianplayer info.
	 * @see			ASXParser
	 * @see			ATOMParser
	 * @see			RSSParser
	 * @see			SMILParser
	 * @see			XSPFParser
	 */
	rianplayer.utils.parsers.rianparser.parseEntry = function(obj, itm) {
		for (var i = 0; i < obj.childNodes.length; i++) {
			if (obj.childNodes[i].prefix == rianplayer.utils.parsers.rianparser.PREFIX) {
				itm[rianplayer.utils.parsers.localName(obj.childNodes[i])] = rianplayer.utils.strings.serialize(rianplayer.utils.parsers.textContent(obj.childNodes[i]));
				if (rianplayer.utils.parsers.localName(obj.childNodes[i]) == "file" && itm.levels) {
					// rianplayer namespace file should override existing level (probably set in MediaParser)
					delete itm.levels;
				}
			}
			if (!itm['file'] && String(itm['link']).toLowerCase().indexOf('youtube') > -1) {
				itm['file'] = itm['link'];
			}
		}
		return itm;
	}

	/**
	 * Determine the provider of an item
	 * @param {Object} item
	 * @return {String} provider
	 */
	rianplayer.utils.parsers.rianparser.getProvider = function(item) {
		if (item['type']) {
			return item['type'];
		} else if (item['file'].indexOf('youtube.com/w') > -1
					|| item['file'].indexOf('youtube.com/v') > -1
					|| item['file'].indexOf('youtu.be/') > -1 ) {
			return "youtube";
		} else if (item['streamer'] && item['streamer'].indexOf('rtmp') == 0) {
			return "rtmp";
		} else if (item['streamer'] && item['streamer'].indexOf('http') == 0) {
			return "http";
		} else {
			var ext = rianplayer.utils.strings.extension(item['file']);
			if (extensions.hasOwnProperty(ext)) {
				return extensions[ext];
			}
		}
		return "";
	}

})(rianplayer);
/**
 * Parse a MRSS group into a playlistitem (used in RSS and ATOM).
 *
 * author zach
 * version 5.7
 */
(function(rianplayer) {

	rianplayer.utils.parsers.mediaparser = function() {
	};

	/** Prefix for the Rian Player namespace. **/
	rianplayer.utils.parsers.mediaparser.PREFIX = 'media';

	/**
	 * Parse a feeditem for Yahoo MediaRSS extensions.
	 * The 'content' and 'group' elements can nest other MediaRSS elements.
	 * @param	{XML}		obj		The entire MRSS XML object.
	 * @param	{Object}	itm		The playlistentry to amend the object to.
	 * @return	{Object}			The playlistentry, amended with the MRSS info.
	 * @see ATOMParser
	 * @see RSSParser
	 **/
	rianplayer.utils.parsers.mediaparser.parseGroup = function(obj, itm) {
		var ytp = false;

		for (var i = 0; i < obj.childNodes.length; i++) {
			if (obj.childNodes[i].prefix == rianplayer.utils.parsers.mediaparser.PREFIX) {
				if (!rianplayer.utils.parsers.localName(obj.childNodes[i])){
					continue;
				}
				switch (rianplayer.utils.parsers.localName(obj.childNodes[i]).toLowerCase()) {
					case 'content':
						if (!ytp) {
							itm['file'] = rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'url');
						}
						if (rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'duration')) {
							itm['duration'] = rianplayer.utils.strings.seconds(rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'duration'));
						}
						if (rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'start')) {
							itm['start'] = rianplayer.utils.strings.seconds(rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'start'));
						}
						if (obj.childNodes[i].childNodes && obj.childNodes[i].childNodes.length > 0) {
							itm = rianplayer.utils.parsers.mediaparser.parseGroup(obj.childNodes[i], itm);
						}
						if (rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'width')
								|| rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'bitrate')
								|| rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'url')) {
							if (!itm.levels) {
								itm.levels = [];
							}
							itm.levels.push({
								width: rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'width'),
								bitrate: rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'bitrate'),
								file: rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'url')
							});
						}
						break;
					case 'title':
						itm['title'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
						break;
					case 'description':
						itm['description'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
						break;
					case 'keywords':
						itm['tags'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
						break;
					case 'thumbnail':
						itm['image'] = rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'url');
						break;
					case 'credit':
						itm['author'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
						break;
					case 'player':
						var url = obj.childNodes[i].url;
						if (url.indexOf('youtube.com') >= 0 || url.indexOf('youtu.be') >= 0) {
							ytp = true;
							itm['file'] = rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'url');
						}
						break;
					case 'group':
						rianplayer.utils.parsers.mediaparser.parseGroup(obj.childNodes[i], itm);
						break;
				}
			}
		}
		return itm;
	}

})(rianplayer);
/**
 * Parse an RSS feed and translate it to a playlist.
 *
 * @author zach
 * @version 5.7
 */
(function(rianplayer) {

	rianplayer.utils.parsers.rssparser = function() {
	};

	/**
	 * Parse an RSS playlist for feed items.
	 *
	 * @param {XML} dat
	 * @reuturn {Array} playlistarray
	 */
	rianplayer.utils.parsers.rssparser.parse = function(dat) {
		var arr = [];
		for (var i = 0; i < dat.childNodes.length; i++) {
			if (rianplayer.utils.parsers.localName(dat.childNodes[i]).toLowerCase() == 'channel') {
				for (var j = 0; j < dat.childNodes[i].childNodes.length; j++) {
					if (rianplayer.utils.parsers.localName(dat.childNodes[i].childNodes[j]).toLowerCase() == 'item') {
						arr.push(_parseItem(dat.childNodes[i].childNodes[j]));
					}
				}
			}
		}
		return arr;
	};


	/**
	 * Translate RSS item to playlist item.
	 *
	 * @param {XML} obj
	 * @return {PlaylistItem} PlaylistItem
	 */
	function _parseItem(obj) {
		var itm = {};
		for (var i = 0; i < obj.childNodes.length; i++) {
			if (!rianplayer.utils.parsers.localName(obj.childNodes[i])){
				continue;
			}
			switch (rianplayer.utils.parsers.localName(obj.childNodes[i]).toLowerCase()) {
				case 'enclosure':
					itm['file'] = rianplayer.utils.strings.xmlAttribute(obj.childNodes[i], 'url');
					break;
				case 'title':
					itm['title'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
					break;
				case 'pubdate':
					itm['date'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
					break;
				case 'description':
					itm['description'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
					break;
				case 'link':
					itm['link'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
					break;
				case 'category':
					if (itm['tags']) {
						itm['tags'] += rianplayer.utils.parsers.textContent(obj.childNodes[i]);
					} else {
						itm['tags'] = rianplayer.utils.parsers.textContent(obj.childNodes[i]);
					}
					break;
			}
		}
//		itm = rianplayer.utils.parsers.itunesparser.parseEntry(obj, itm);
		itm = rianplayer.utils.parsers.mediaparser.parseGroup(obj, itm);
		itm = rianplayer.utils.parsers.rianparser.parseEntry(obj, itm);

		return new rianplayer.html5.playlistitem(itm);
	}


})(rianplayer);
/**
 * Plugin package definition
 * @author zach
 * @version 5.5
 */
(function(rianplayer) {
	var _plugins = {};
	var _pluginLoaders = {};

	rianplayer.plugins = function() {
	}

	rianplayer.plugins.loadPlugins = function(id, config) {
		_pluginLoaders[id] = new rianplayer.plugins.pluginloader(new rianplayer.plugins.model(_plugins), config);
		return _pluginLoaders[id];
	}

	rianplayer.plugins.registerPlugin = function(id, arg1, arg2) {
		var pluginId = rianplayer.utils.getPluginName(id);
		if (_plugins[pluginId]) {
			_plugins[pluginId].registerPlugin(id, arg1, arg2);
		} else {
			rianplayer.utils.log("A plugin ("+id+") was registered with the player that was not loaded. Please check your configuration.");
			for (var pluginloader in _pluginLoaders){
				_pluginLoaders[pluginloader].pluginFailed();
			}
		}
	}
})(rianplayer);
/**
 * Model that manages all plugins
 * @author zach
 * @version 5.5
 */
(function(rianplayer) {
	rianplayer.plugins.model = function(plugins) {
		this.addPlugin = function(url) {
			var pluginName = rianplayer.utils.getPluginName(url);
			if (!plugins[pluginName]) {
				plugins[pluginName] = new rianplayer.plugins.plugin(url);
			}
			return plugins[pluginName];
		}
	}
})(rianplayer);
/**
 * Internal plugin model
 * @author zach
 * @version 5.8
 */
(function(rianplayer) {
	rianplayer.plugins.pluginmodes = {
		FLASH: "FLASH",
		JAVASCRIPT: "JAVASCRIPT",
		HYBRID: "HYBRID"
	}

	rianplayer.plugins.plugin = function(url) {
		var _repo = "http://plugins.longtailvideo.com"
		var _status = rianplayer.utils.loaderstatus.NEW;
		var _flashPath;
		var _js;
		var _completeTimeout;

		var _eventDispatcher = new rianplayer.events.eventdispatcher();
		rianplayer.utils.extend(this, _eventDispatcher);

		function getJSPath() {
			switch (rianplayer.utils.getPluginPathType(url)) {
				case rianplayer.utils.pluginPathType.ABSOLUTE:
					return url;
				case rianplayer.utils.pluginPathType.RELATIVE:
					return rianplayer.utils.getAbsolutePath(url, window.location.href);
				case rianplayer.utils.pluginPathType.CDN:
					var pluginName = rianplayer.utils.getPluginName(url);
					var pluginVersion = rianplayer.utils.getPluginVersion(url);
					var repo = (window.location.href.indexOf("https://") == 0) ? _repo.replace("http://", "https://secure") : _repo;
					return repo + "/" + rianplayer.version.split(".")[0] + "/" + pluginName + "/"
							+ pluginName + (pluginVersion !== "" ? ("-" + pluginVersion) : "") + ".js";
			}
		}

		function completeHandler(evt) {
			_completeTimeout = setTimeout(function(){
				_status = rianplayer.utils.loaderstatus.COMPLETE;
				_eventDispatcher.sendEvent(rianplayer.events.COMPLETE);
			}, 1000);
		}

		function errorHandler(evt) {
			_status = rianplayer.utils.loaderstatus.ERROR;
			_eventDispatcher.sendEvent(rianplayer.events.ERROR);
		}

		this.load = function() {
			if (_status == rianplayer.utils.loaderstatus.NEW) {
				if (url.lastIndexOf(".swf") > 0) {
					_flashPath = url;
					_status = rianplayer.utils.loaderstatus.COMPLETE;
					_eventDispatcher.sendEvent(rianplayer.events.COMPLETE);
					return;
				}
				_status = rianplayer.utils.loaderstatus.LOADING;
				var _loader = new rianplayer.utils.scriptloader(getJSPath());
				// Complete doesn't matter - we're waiting for registerPlugin
				_loader.addEventListener(rianplayer.events.COMPLETE, completeHandler);
				_loader.addEventListener(rianplayer.events.ERROR, errorHandler);
				_loader.load();
			}
		}

		this.registerPlugin = function(id, arg1, arg2) {
			if (_completeTimeout){
				clearTimeout(_completeTimeout);
				_completeTimeout = undefined;
			}
			if (arg1 && arg2) {
				_flashPath = arg2;
				_js = arg1;
			} else if (typeof arg1 == "string") {
				_flashPath = arg1;
			} else if (typeof arg1 == "function") {
				_js = arg1;
			} else if (!arg1 && !arg2) {
				_flashPath = id;
			}
			_status = rianplayer.utils.loaderstatus.COMPLETE;
			_eventDispatcher.sendEvent(rianplayer.events.COMPLETE);
		}

		this.getStatus = function() {
			return _status;
		}

		this.getPluginName = function() {
			return rianplayer.utils.getPluginName(url);
		}

		this.getFlashPath = function() {
			if (_flashPath) {
				switch (rianplayer.utils.getPluginPathType(_flashPath)) {
					case rianplayer.utils.pluginPathType.ABSOLUTE:
						return _flashPath;
					case rianplayer.utils.pluginPathType.RELATIVE:
						if (url.lastIndexOf(".swf") > 0) {
							return rianplayer.utils.getAbsolutePath(_flashPath, window.location.href);
						}
						return rianplayer.utils.getAbsolutePath(_flashPath, getJSPath());
					case rianplayer.utils.pluginPathType.CDN:
						if (_flashPath.indexOf("-") > -1){
							return _flashPath+"h";
						}
						return _flashPath+"-h";
				}
			}
			return null;
		}

		this.getJS = function() {
			return _js;
		}

		this.getPluginmode = function() {
			if (typeof _flashPath != "undefined"
			 && typeof _js != "undefined") {
				return rianplayer.plugins.pluginmodes.HYBRID;
			 } else if (typeof _flashPath != "undefined") {
				return rianplayer.plugins.pluginmodes.FLASH;
			 } else if (typeof _js != "undefined") {
				return rianplayer.plugins.pluginmodes.JAVASCRIPT;
			 }
		}

		this.getNewInstance = function(api, config, div) {
			return new _js(api, config, div);
		}

		this.getURL = function() {
			return url;
		}
	}

})(rianplayer);
/**
 * Loads plugins for a player
 * @author zach
 * @version 5.6
 */
(function(rianplayer) {

	rianplayer.plugins.pluginloader = function(model, config) {
		var _plugins = {};
		var _status = rianplayer.utils.loaderstatus.NEW;
		var _loading = false;
		var _iscomplete = false;
		var _eventDispatcher = new rianplayer.events.eventdispatcher();
		rianplayer.utils.extend(this, _eventDispatcher);

		/*
		 * Plugins can be loaded by multiple players on the page, but all of them use
		 * the same plugin model singleton. This creates a race condition because
		 * multiple players are creating and triggering loads, which could complete
		 * at any time. We could have some really complicated logic that deals with
		 * this by checking the status when it's created and / or having the loader
		 * redispatch its current status on load(). Rather than do this, we just check
		 * for completion after all of the plugins have been created. If all plugins
		 * have been loaded by the time checkComplete is called, then the loader is
		 * done and we fire the complete event. If there are new loads, they will
		 * arrive later, retriggering the completeness check and triggering a complete
		 * to fire, if necessary.
		 */
		function _complete() {
			if (!_iscomplete) {
				_iscomplete = true;
				_status = rianplayer.utils.loaderstatus.COMPLETE;
				_eventDispatcher.sendEvent(rianplayer.events.COMPLETE);
			}
		}

		// This is not entirely efficient, but it's simple
		function _checkComplete() {
			if (!_iscomplete) {
				var incomplete = 0;
				for (plugin in _plugins) {
					var status = _plugins[plugin].getStatus();
					if (status == rianplayer.utils.loaderstatus.LOADING
							|| status == rianplayer.utils.loaderstatus.NEW) {
						incomplete++;
					}
				}

				if (incomplete == 0) {
					_complete();
				}
			}
		}

		this.setupPlugins = function(api, config, resizer) {
			var flashPlugins = {
				length: 0,
				plugins: {}
			};
			var jsplugins = {
				length: 0,
				plugins: {}
			};
			for (var plugin in _plugins) {
				var pluginName = _plugins[plugin].getPluginName();
				if (_plugins[plugin].getFlashPath()) {
					flashPlugins.plugins[_plugins[plugin].getFlashPath()] = config.plugins[plugin];
					flashPlugins.plugins[_plugins[plugin].getFlashPath()].pluginmode = _plugins[plugin].getPluginmode();
					flashPlugins.length++;
				}
				if (_plugins[plugin].getJS()) {
					var div = document.createElement("div");
					div.id = api.id + "_" + pluginName;
					div.style.position = "absolute";
					div.style.zIndex = jsplugins.length + 10;
					jsplugins.plugins[pluginName] = _plugins[plugin].getNewInstance(api, config.plugins[plugin], div);
					jsplugins.length++;
					if (typeof jsplugins.plugins[pluginName].resize != "undefined") {
						api.onReady(resizer(jsplugins.plugins[pluginName], div, true));
						api.onResize(resizer(jsplugins.plugins[pluginName], div));
					}
				}
			}

			api.plugins = jsplugins.plugins;

			return flashPlugins;
		};

		this.load = function() {
			_status = rianplayer.utils.loaderstatus.LOADING;
			_loading = true;

			/** First pass to create the plugins and add listeners **/
			for (var plugin in config) {
				if (rianplayer.utils.exists(plugin)) {
					_plugins[plugin] = model.addPlugin(plugin);
					_plugins[plugin].addEventListener(rianplayer.events.COMPLETE, _checkComplete);
					_plugins[plugin].addEventListener(rianplayer.events.ERROR, _checkComplete);
				}
			}

			/** Second pass to actually load the plugins **/
			for (plugin in _plugins) {
				// Plugin object ensures that it's only loaded once
				_plugins[plugin].load();
			}

			_loading = false;

			// Make sure we're not hanging around waiting for plugins that already finished loading
			_checkComplete();
		}

		this.pluginFailed = function() {
			_complete();
		}

		this.getStatus = function() {
			return _status;
		}

	}
})(rianplayer);
/**
 * API for the Rian Player
 *
 * @author Pablo
 * @version 5.8
 */
(function(rianplayer) {
	var _players = [];

	rianplayer.api = function(container) {
		this.container = container;
		this.id = container.id;

		var _listeners = {};
		var _stateListeners = {};
		var _componentListeners = {};
		var _readyListeners = [];
		var _player = undefined;
		var _playerReady = false;
		var _queuedCalls = [];
		var _instream = undefined;

		var _originalHTML = rianplayer.utils.getOuterHTML(container);

		var _itemMeta = {};
		var _callbacks = {};

		// Player Getters
		this.getBuffer = function() {
			return this.callInternal('rianGetBuffer');
		};
		this.getContainer = function() {
			return this.container;
		};

		function _setButton(ref, plugin) {
			return function(id, handler, outGraphic, overGraphic) {
				if (ref.renderingMode == "flash" || ref.renderingMode == "html5") {
					var handlerString;
					if (handler) {
						_callbacks[id] = handler;
						handlerString = "rianplayer('" + ref.id + "').callback('" + id + "')";
					} else if (!handler && _callbacks[id]) {
						delete _callbacks[id];
					}
					_player.rianDockSetButton(id, handlerString, outGraphic, overGraphic);
				}
				return plugin;
			};
		}

		this.getPlugin = function(pluginName) {
			var _this = this;
			var _plugin = {};
			if (pluginName == "dock") {
				return rianplayer.utils.extend(_plugin, {
					setButton: _setButton(_this, _plugin),
					show: function() { _this.callInternal('rianDockShow'); return _plugin; },
					hide: function() { _this.callInternal('rianDockHide'); return _plugin; },
					onShow: function(callback) {
						_this.componentListener("dock", rianplayer.api.events.rianplayer_COMPONENT_SHOW, callback);
						return _plugin;
					},
					onHide: function(callback) {
						_this.componentListener("dock", rianplayer.api.events.rianplayer_COMPONENT_HIDE, callback);
						return _plugin;
					}
				});
			} else if (pluginName == "controlbar") {
				return rianplayer.utils.extend(_plugin, {
					show: function() { _this.callInternal('rianControlbarShow'); return _plugin; },
					hide: function() { _this.callInternal('rianControlbarHide'); return _plugin; },
					onShow: function(callback) {
						_this.componentListener("controlbar", rianplayer.api.events.rianplayer_COMPONENT_SHOW, callback);
						return _plugin;
					},
					onHide: function(callback) {
						_this.componentListener("controlbar", rianplayer.api.events.rianplayer_COMPONENT_HIDE, callback);
						return _plugin;
					}
				});
			} else if (pluginName == "display") {
				return rianplayer.utils.extend(_plugin, {
					show: function() { _this.callInternal('rianDisplayShow'); return _plugin; },
					hide: function() { _this.callInternal('rianDisplayHide'); return _plugin; },
					onShow: function(callback) {
						_this.componentListener("display", rianplayer.api.events.rianplayer_COMPONENT_SHOW, callback);
						return _plugin;
					},
					onHide: function(callback) {
						_this.componentListener("display", rianplayer.api.events.rianplayer_COMPONENT_HIDE, callback);
						return _plugin;
					}
				});
			} else {
				return this.plugins[pluginName];
			}
		};

		this.callback = function(id) {
			if (_callbacks[id]) {
				return _callbacks[id]();
			}
		};
		this.getDuration = function() {
			return this.callInternal('rianGetDuration');
		};
		this.getFullscreen = function() {
			return this.callInternal('rianGetFullscreen');
		};
		this.getHeight = function() {
			return this.callInternal('rianGetHeight');
		};
		this.getLockState = function() {
			return this.callInternal('rianGetLockState');
		};
		this.getMeta = function() {
			return this.getItemMeta();
		};
		this.getMute = function() {
			return this.callInternal('rianGetMute');
		};
		this.getPlaylist = function() {
			var playlist = this.callInternal('rianGetPlaylist');
			if (this.renderingMode == "flash") {
				rianplayer.utils.deepReplaceKeyName(playlist, ["__dot__","__spc__","__dsh__"], ["."," ","-"]);
			}
			for (var i = 0; i < playlist.length; i++) {
				if (!rianplayer.utils.exists(playlist[i].index)) {
					playlist[i].index = i;
				}
			}
			return playlist;
		};
		this.getPlaylistItem = function(item) {
			if (!rianplayer.utils.exists(item)) {
				item = this.getCurrentItem();
			}
			return this.getPlaylist()[item];
		};
		this.getPosition = function() {
			return this.callInternal('rianGetPosition');
		};
		this.getRenderingMode = function() {
			return this.renderingMode;
		};
		this.getState = function() {
			return this.callInternal('rianGetState');
		};
		this.getVolume = function() {
			return this.callInternal('rianGetVolume');
		};
		this.getWidth = function() {
			return this.callInternal('rianGetWidth');
		};
		// Player Public Methods
		this.setFullscreen = function(fullscreen) {
			if (!rianplayer.utils.exists(fullscreen)) {
				this.callInternal("rianSetFullscreen", !this.callInternal('rianGetFullscreen'));
			} else {
				this.callInternal("rianSetFullscreen", fullscreen);
			}
			return this;
		};
		this.setMute = function(mute) {
			if (!rianplayer.utils.exists(mute)) {
				this.callInternal("rianSetMute", !this.callInternal('rianGetMute'));
			} else {
				this.callInternal("rianSetMute", mute);
			}
			return this;
		};
		this.lock = function() {
			return this;
		};
		this.unlock = function() {
			return this;
		};
		this.load = function(toLoad) {
			this.callInternal("rianLoad", toLoad);
			return this;
		};
		this.playlistItem = function(item) {
			this.callInternal("rianPlaylistItem", item);
			return this;
		};
		this.playlistPrev = function() {
			this.callInternal("rianPlaylistPrev");
			return this;
		};
		this.playlistNext = function() {
			this.callInternal("rianPlaylistNext");
			return this;
		};
		this.resize = function(width, height) {
			if (this.renderingMode == "html5") {
				_player.rianResize(width, height);
			} else {
				this.container.width = width;
				this.container.height = height;
				var wrapper = document.getElementById(this.id + "_wrapper");
				if (wrapper) {
					wrapper.style.width = width + "px";
					wrapper.style.height = height + "px";
				}
			}
			return this;
		};
		this.play = function(state) {
			if (typeof state == "undefined") {
				state = this.getState();
				if (state == rianplayer.api.events.state.PLAYING || state == rianplayer.api.events.state.BUFFERING) {
					this.callInternal("rianPause");
				} else {
					this.callInternal("rianPlay");
				}
			} else {
				this.callInternal("rianPlay", state);
			}
			return this;
		};
		this.pause = function(state) {
			if (typeof state == "undefined") {
				state = this.getState();
				if (state == rianplayer.api.events.state.PLAYING || state == rianplayer.api.events.state.BUFFERING) {
					this.callInternal("rianPause");
				} else {
					this.callInternal("rianPlay");
				}
			} else {
				this.callInternal("rianPause", state);
			}
			return this;
		};
		this.stop = function() {
			this.callInternal("rianStop");
			return this;
		};
		this.seek = function(position) {
			this.callInternal("rianSeek", position);
			return this;
		};
		this.setVolume = function(volume) {
			this.callInternal("rianSetVolume", volume);
			return this;
		};
		this.loadInstream = function(item, instreamOptions) {
			_instream = new rianplayer.api.instream(this, _player, item, instreamOptions);
			return _instream;
		};
		// Player Events
		this.onBufferChange = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_BUFFER, callback);
		};
		this.onBufferFull = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_BUFFER_FULL, callback);
		};
		this.onError = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_ERROR, callback);
		};
		this.onFullscreen = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_FULLSCREEN, callback);
		};
		this.onMeta = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_META, callback);
		};
		this.onMute = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_MUTE, callback);
		};
		this.onPlaylist = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_PLAYLIST_LOADED, callback);
		};
		this.onPlaylistItem = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_PLAYLIST_ITEM, callback);
		};
		this.onReady = function(callback) {
			return this.eventListener(rianplayer.api.events.API_READY, callback);
		};
		this.onResize = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_RESIZE, callback);
		};
		this.onComplete = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_COMPLETE, callback);
		};
		this.onSeek = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_SEEK, callback);
		};
		this.onTime = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_TIME, callback);
		};
		this.onVolume = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_VOLUME, callback);
		};
		this.onBeforePlay = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_BEFOREPLAY, callback);
		};
		this.onBeforeComplete = function(callback) {
			return this.eventListener(rianplayer.api.events.rianplayer_MEDIA_BEFORECOMPLETE, callback);
		};
		// State events
		this.onBuffer = function(callback) {
			return this.stateListener(rianplayer.api.events.state.BUFFERING, callback);
		};
		this.onPause = function(callback) {
			return this.stateListener(rianplayer.api.events.state.PAUSED, callback);
		};
		this.onPlay = function(callback) {
			return this.stateListener(rianplayer.api.events.state.PLAYING, callback);
		};
		this.onIdle = function(callback) {
			return this.stateListener(rianplayer.api.events.state.IDLE, callback);
		};
		this.remove = function() {
			if (!_playerReady) {
				throw "Cannot call remove() before player is ready";
				return;
			}
			_remove(this);
		};

		function _remove(player) {
			_queuedCalls = [];
			if (rianplayer.utils.getOuterHTML(player.container) != _originalHTML) {
				rianplayer.api.destroyPlayer(player.id, _originalHTML);
			}
		}

		this.setup = function(options) {
			if (rianplayer.embed) {
				// Destroy original API on setup() to remove existing listeners
				var newId = this.id;
				_remove(this);
				var newApi = rianplayer(newId);
				newApi.config = options;
				return new rianplayer.embed(newApi);
			}
			return this;
		};
		this.registerPlugin = function(id, arg1, arg2) {
			rianplayer.plugins.registerPlugin(id, arg1, arg2);
		};

		/** Use this function to set the internal low-level player.  This is a javascript object which contains the low-level API calls. **/
		this.setPlayer = function(player, renderingMode) {
			_player = player;
			this.renderingMode = renderingMode;
		};

		this.stateListener = function(state, callback) {
			if (!_stateListeners[state]) {
				_stateListeners[state] = [];
				this.eventListener(rianplayer.api.events.rianplayer_PLAYER_STATE, stateCallback(state));
			}
			_stateListeners[state].push(callback);
			return this;
		};

		this.detachMedia = function() {
			if (this.renderingMode == "html5") {
				return this.callInternal("rianDetachMedia");
			}
		}

		this.attachMedia = function() {
			if (this.renderingMode == "html5") {
				return this.callInternal("rianAttachMedia");
			}
		}

		function stateCallback(state) {
			return function(args) {
				var newstate = args.newstate, oldstate = args.oldstate;
				if (newstate == state) {
					var callbacks = _stateListeners[newstate];
					if (callbacks) {
						for (var c = 0; c < callbacks.length; c++) {
							if (typeof callbacks[c] == 'function') {
								callbacks[c].call(this, {
									oldstate: oldstate,
									newstate: newstate
								});
							}
						}
					}
				}
			};
		}

		this.componentListener = function(component, type, callback) {
			if (!_componentListeners[component]) {
				_componentListeners[component] = {};
			}
			if (!_componentListeners[component][type]) {
				_componentListeners[component][type] = [];
				this.eventListener(type, _componentCallback(component, type));
			}
			_componentListeners[component][type].push(callback);
			return this;
		};

		function _componentCallback(component, type) {
			return function(event) {
				if (component == event.component) {
					var callbacks = _componentListeners[component][type];
					if (callbacks) {
						for (var c = 0; c < callbacks.length; c++) {
							if (typeof callbacks[c] == 'function') {
								callbacks[c].call(this, event);
							}
						}
					}
				}
			};
		}

		this.addInternalListener = function(player, type) {
			try {
				player.rianAddEventListener(type, 'function(dat) { rianplayer("' + this.id + '").dispatchEvent("' + type + '", dat); }');
			} catch(e) {
				rianplayer.utils.log("Could not add internal listener");
			}
		};

		this.eventListener = function(type, callback) {
			if (!_listeners[type]) {
				_listeners[type] = [];
				if (_player && _playerReady) {
					this.addInternalListener(_player, type);
				}
			}
			_listeners[type].push(callback);
			return this;
		};

		this.dispatchEvent = function(type) {
			if (_listeners[type]) {
				var args = _utils.translateEventResponse(type, arguments[1]);
				for (var l = 0; l < _listeners[type].length; l++) {
					if (typeof _listeners[type][l] == 'function') {
						_listeners[type][l].call(this, args);
					}
				}
			}
		};

		this.dispatchInstreamEvent = function(type) {
			if (_instream) {
				_instream.dispatchEvent(type, arguments);
			}
		};

		this.callInternal = function() {
			if (_playerReady) {
				var funcName = arguments[0],
				args = [];

				for (var argument = 1; argument < arguments.length; argument++) {
					args.push(arguments[argument]);
				}

				if (typeof _player != "undefined" && typeof _player[funcName] == "function") {
					if (args.length == 2) {
						return (_player[funcName])(args[0], args[1]);
					} else if (args.length == 1) {
						return (_player[funcName])(args[0]);
					} else {
						return (_player[funcName])();
					}
				}
				return null;
			} else {
				_queuedCalls.push(arguments);
			}
		};

		this.playerReady = function(obj) {
			_playerReady = true;

			if (!_player) {
				this.setPlayer(document.getElementById(obj.id));
			}
			this.container = document.getElementById(this.id);

			for (var eventType in _listeners) {
				this.addInternalListener(_player, eventType);
			}

			this.eventListener(rianplayer.api.events.rianplayer_PLAYLIST_ITEM, function(data) {
				_itemMeta = {};
			});

			this.eventListener(rianplayer.api.events.rianplayer_MEDIA_META, function(data) {
				rianplayer.utils.extend(_itemMeta, data.metadata);
			});

			this.dispatchEvent(rianplayer.api.events.API_READY);

			while (_queuedCalls.length > 0) {
				this.callInternal.apply(this, _queuedCalls.shift());
			}
		};

		this.getItemMeta = function() {
			return _itemMeta;
		};

		this.getCurrentItem = function() {
			return this.callInternal('rianGetPlaylistIndex');
		};

		/** Using this function instead of array.slice since Arguments are not an array **/
		function slice(list, from, to) {
			var ret = [];
			if (!from) {
				from = 0;
			}
			if (!to) {
				to = list.length - 1;
			}
			for (var i = from; i <= to; i++) {
				ret.push(list[i]);
			}
			return ret;
		}
		return this;
	};

	rianplayer.api.selectPlayer = function(identifier) {
		var _container;

		if (!rianplayer.utils.exists(identifier)) {
			identifier = 0;
		}

		if (identifier.nodeType) {
			// Handle DOM Element
			_container = identifier;
		} else if (typeof identifier == 'string') {
			// Find container by ID
			_container = document.getElementById(identifier);
		}

		if (_container) {
			var foundPlayer = rianplayer.api.playerById(_container.id);
			if (foundPlayer) {
				return foundPlayer;
			} else {
				// Todo: register new object
				return rianplayer.api.addPlayer(new rianplayer.api(_container));
			}
		} else if (typeof identifier == 'number') {
			return rianplayer.getPlayers()[identifier];
		}

		return null;
	};

	rianplayer.api.events = {
		API_READY: 'rianplayerAPIReady',
		rianplayer_READY: 'rianplayerReady',
		rianplayer_FULLSCREEN: 'rianplayerFullscreen',
		rianplayer_RESIZE: 'rianplayerResize',
		rianplayer_ERROR: 'rianplayerError',
		rianplayer_MEDIA_BEFOREPLAY: 'rianplayerMediaBeforePlay',
		rianplayer_MEDIA_BEFORECOMPLETE: 'rianplayerMediaBeforeComplete',
		rianplayer_COMPONENT_SHOW: 'rianplayerComponentShow',
		rianplayer_COMPONENT_HIDE: 'rianplayerComponentHide',
		rianplayer_MEDIA_BUFFER: 'rianplayerMediaBuffer',
		rianplayer_MEDIA_BUFFER_FULL: 'rianplayerMediaBufferFull',
		rianplayer_MEDIA_ERROR: 'rianplayerMediaError',
		rianplayer_MEDIA_LOADED: 'rianplayerMediaLoaded',
		rianplayer_MEDIA_COMPLETE: 'rianplayerMediaComplete',
		rianplayer_MEDIA_SEEK: 'rianplayerMediaSeek',
		rianplayer_MEDIA_TIME: 'rianplayerMediaTime',
		rianplayer_MEDIA_VOLUME: 'rianplayerMediaVolume',
		rianplayer_MEDIA_META: 'rianplayerMediaMeta',
		rianplayer_MEDIA_MUTE: 'rianplayerMediaMute',
		rianplayer_PLAYER_STATE: 'rianplayerPlayerState',
		rianplayer_PLAYLIST_LOADED: 'rianplayerPlaylistLoaded',
		rianplayer_PLAYLIST_ITEM: 'rianplayerPlaylistItem',
		rianplayer_INSTREAM_CLICK: 'rianplayerInstreamClicked',
		rianplayer_INSTREAM_DESTROYED: 'rianplayerInstreamDestroyed'
	};

	rianplayer.api.events.state = {
		BUFFERING: 'BUFFERING',
		IDLE: 'IDLE',
		PAUSED: 'PAUSED',
		PLAYING: 'PLAYING'
	};

	rianplayer.api.playerById = function(id) {
		for (var p = 0; p < _players.length; p++) {
			if (_players[p].id == id) {
				return _players[p];
			}
		}
		return null;
	};

	rianplayer.api.addPlayer = function(player) {
		for (var p = 0; p < _players.length; p++) {
			if (_players[p] == player) {
				return player; // Player is already in the list;
			}
		}

		_players.push(player);
		return player;
	};

	rianplayer.api.destroyPlayer = function(playerId, replacementHTML) {
		var index = -1;
		for (var p = 0; p < _players.length; p++) {
			if (_players[p].id == playerId) {
				index = p;
				continue;
			}
		}
		if (index >= 0) {
			try {
				_players[index].callInternal("rianDestroy");
			} catch (e) {}
			var toDestroy = document.getElementById(_players[index].id);
			if (document.getElementById(_players[index].id + "_wrapper")) {
				toDestroy = document.getElementById(_players[index].id + "_wrapper");
			}
			if (toDestroy) {
				if (replacementHTML) {
					rianplayer.utils.setOuterHTML(toDestroy, replacementHTML);
				} else {
					var replacement = document.createElement('div');
					var newId = toDestroy.id;
					if (toDestroy.id.indexOf("_wrapper") == toDestroy.id.length - 8) {
						newID = toDestroy.id.substring(0, toDestroy.id.length - 8);
					}
					replacement.setAttribute('id', newId);
					toDestroy.parentNode.replaceChild(replacement, toDestroy);
				}
			}
			_players.splice(index, 1);
		}

		return null;
	};

	// Can't make this a read-only getter, thanks to IE incompatibility.
	rianplayer.getPlayers = function() {
		return _players.slice(0);
	};

})(rianplayer);

var _userPlayerReady = (typeof playerReady == 'function') ? playerReady : undefined;

playerReady = function(obj) {
	var api = rianplayer.api.playerById(obj.id);

	if (api) {
		api.playerReady(obj);
	} else {
		rianplayer.api.selectPlayer(obj.id).playerReady(obj);
	}

	if (_userPlayerReady) {
		_userPlayerReady.call(this, obj);
	}
};
/**
 * InStream API
 *
 * @author Pablo
 * @version 5.9
 */
(function(rianplayer) {

	rianplayer.api.instream = function(api, player, item, options) {

		var _api = api;
		var _player = player;
		var _item = item;
		var _options = options;
		var _listeners = {};
		var _stateListeners = {};

		function _init() {
			_api.callInternal("rianLoadInstream", item, options);
		}

		function _addInternalListener(player, type) {
			_player.rianInstreamAddEventListener(type, 'function(dat) { rianplayer("' + _api.id + '").dispatchInstreamEvent("' + type + '", dat); }');
		};

		function _eventListener(type, callback) {
			if (!_listeners[type]) {
				_listeners[type] = [];
				_addInternalListener(_player, type);
			}
			_listeners[type].push(callback);
			return this;
		};

		function _stateListener(state, callback) {
			if (!_stateListeners[state]) {
				_stateListeners[state] = [];
				_eventListener(rianplayer.api.events.rianplayer_PLAYER_STATE, _stateCallback(state));
			}
			_stateListeners[state].push(callback);
			return this;
		};

		function _stateCallback(state) {
			return function(args) {
				var newstate = args.newstate, oldstate = args.oldstate;
				if (newstate == state) {
					var callbacks = _stateListeners[newstate];
					if (callbacks) {
						for (var c = 0; c < callbacks.length; c++) {
							if (typeof callbacks[c] == 'function') {
								callbacks[c].call(this, {
									oldstate: oldstate,
									newstate: newstate,
									type: args.type
								});
							}
						}
					}
				}
			};
		}
		this.dispatchEvent = function(type, calledArguments) {
			if (_listeners[type]) {
				var args = _utils.translateEventResponse(type, calledArguments[1]);
				for (var l = 0; l < _listeners[type].length; l++) {
					if (typeof _listeners[type][l] == 'function') {
						_listeners[type][l].call(this, args);
					}
				}
			}
		}


		this.onError = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_ERROR, callback);
		};
		this.onFullscreen = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_FULLSCREEN, callback);
		};
		this.onMeta = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_MEDIA_META, callback);
		};
		this.onMute = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_MEDIA_MUTE, callback);
		};
		this.onComplete = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_MEDIA_COMPLETE, callback);
		};
		this.onSeek = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_MEDIA_SEEK, callback);
		};
		this.onTime = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_MEDIA_TIME, callback);
		};
		this.onVolume = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_MEDIA_VOLUME, callback);
		};
		// State events
		this.onBuffer = function(callback) {
			return _stateListener(rianplayer.api.events.state.BUFFERING, callback);
		};
		this.onPause = function(callback) {
			return _stateListener(rianplayer.api.events.state.PAUSED, callback);
		};
		this.onPlay = function(callback) {
			return _stateListener(rianplayer.api.events.state.PLAYING, callback);
		};
		this.onIdle = function(callback) {
			return _stateListener(rianplayer.api.events.state.IDLE, callback);
		};
		// Instream events
		this.onInstreamClick = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_INSTREAM_CLICK, callback);
		};
		this.onInstreamDestroyed = function(callback) {
			return _eventListener(rianplayer.api.events.rianplayer_INSTREAM_DESTROYED, callback);
		};

		this.play = function(state) {
			_player.rianInstreamPlay(state);
		};
		this.pause= function(state) {
			_player.rianInstreamPause(state);
		};
		this.seek = function(pos) {
			_player.rianInstreamSeek(pos);
		};
		this.destroy = function() {
			_player.rianInstreamDestroy();
		};
		this.getState = function() {
			return _player.rianInstreamGetState();
		}
		this.getDuration = function() {
			return _player.rianInstreamGetDuration();
		}
		this.getPosition = function() {
			return _player.rianInstreamGetPosition();
		}

		_init();


	}

})(rianplayer);

/**
 * Embedder for the Rian Player
 * @author Zach
 * @version 5.8
 */
(function(rianplayer) {
	var _utils = rianplayer.utils;

	rianplayer.embed = function(playerApi) {
		var _defaults = {
			width: 400,
			height: 300,
			components: {

				controlbar: {
					position: 'over'
				}
			}
		};
		var mediaConfig = _utils.mediaparser.parseMedia(playerApi.container);
		var _config = new rianplayer.embed.config(_utils.extend(_defaults, mediaConfig, playerApi.config), this);
		var _pluginloader = rianplayer.plugins.loadPlugins(playerApi.id, _config.plugins);


		function _setupEvents(api, events) {
			for (var evt in events) {
				if (typeof api[evt] == "function") {
					(api[evt]).call(api, events[evt]);
				}
			}
		}

		function _embedPlayer() {
			if (_pluginloader.getStatus() == _utils.loaderstatus.COMPLETE) {
				for (var mode = 0; mode < _config.modes.length; mode++) {
					if (_config.modes[mode].type && rianplayer.embed[_config.modes[mode].type]) {
						var modeconfig = _config.modes[mode].config;
						var configClone = _config;
						if (modeconfig) {
							configClone = _utils.extend(_utils.clone(_config), modeconfig);

							/** Remove fields from top-level config which are overridden in mode config **/
							var overrides = ["file", "levels", "playlist"];
							for (var i=0; i < overrides.length; i++) {
								var field = overrides[i];
								if (_utils.exists(modeconfig[field])) {
									for (var j=0; j < overrides.length; j++) {
										if (j != i) {
											var other = overrides[j];
											if (_utils.exists(configClone[other]) && !_utils.exists(modeconfig[other])) {
												delete configClone[other];
											}
										}
									}
								}
							}
						}
						var embedder = new rianplayer.embed[_config.modes[mode].type](document.getElementById(playerApi.id), _config.modes[mode], configClone, _pluginloader, playerApi);
						if (embedder.supportsConfig()) {
							embedder.embed();

							_setupEvents(playerApi, _config.events);

							return playerApi;
						}
					}
				}
				_utils.log("No suitable players found");
				new rianplayer.embed.logo(_utils.extend({
					hide: true
				}, _config.components.logo), "none", playerApi.id);
			}
		};

		_pluginloader.addEventListener(rianplayer.events.COMPLETE, _embedPlayer);
		_pluginloader.addEventListener(rianplayer.events.ERROR, _embedPlayer);
		_pluginloader.load();

		return playerApi;
	};

	function noviceEmbed() {
		if (!document.body) {
			return setTimeout(noviceEmbed, 15);
		}
		var videoTags = _utils.selectors.getElementsByTagAndClass('video', 'rianplayer');
		for (var i = 0; i < videoTags.length; i++) {
			var video = videoTags[i];
			if (video.id == "") {
				video.id = "rianplayer_" + Math.round(Math.random()*100000);
			}
			rianplayer(video.id).setup({});
		}
	}

	noviceEmbed();


})(rianplayer);
/**
 * Configuration for the Rian Player Embedder
 * @author Zach
 * @version 5.9
 */
(function(rianplayer) {
	var _utils = rianplayer.utils;

	function _playerDefaults(flashplayer) {
		var modes = [{
			type: "flash",
			src: flashplayer ? flashplayer : ""
		}, {
			type: 'html5'
		},{
			type: 'download'
		}];
		if (_utils.isAndroid()) {
			// If Android, then swap html5 and flash modes - default should be HTML5
			modes[0] = modes.splice(1, 1, modes[0])[0];
		}

		return modes;
	}

	var _aliases = {
		'players': 'modes',
		'autoplay': 'autostart'
	};

	function _isPosition(string) {
		var lower = string.toLowerCase();
		var positions = ["left", "right", "top", "bottom"];

		for (var position = 0; position < positions.length; position++) {
			if (lower == positions[position]) {
				return true;
			}
		}

		return false;
	}

	function _isPlaylist(property) {
		var result = false;
		// XML Playlists
		// (typeof property == "string" && !_isPosition(property)) ||
		// JSON Playlist
		result = (property instanceof Array) ||
		// Single playlist item as an Object
		(typeof property == "object" && !property.position && !property.size);
		return result;
	}

	function getSize(size) {
		if (typeof size == "string") {
			if (parseInt(size).toString() == size || size.toLowerCase().indexOf("px") > -1) {
				return parseInt(size);
			}
		}
		return size;
	}

	var components = ["playlist", "dock", /*"controlbar", "logo"*/, "display"];

	function getPluginNames(config) {
		var pluginNames = {};
		switch(_utils.typeOf(config.plugins)){
			case "object":
				for (var plugin in config.plugins) {
					pluginNames[_utils.getPluginName(plugin)] = plugin;
				}
				break;
			case "string":
				var pluginArray = config.plugins.split(",");
				for (var i=0; i < pluginArray.length; i++) {
					pluginNames[_utils.getPluginName(pluginArray[i])] = pluginArray[i];
				}
				break;
		}
		return pluginNames;
	}

	function addConfigParameter(config, componentType, componentName, componentParameter){
		if (_utils.typeOf(config[componentType]) != "object"){
			config[componentType] = {};
		}
		var componentConfig = config[componentType][componentName];

		if (_utils.typeOf(componentConfig) != "object") {
			config[componentType][componentName] = componentConfig = {};
		}

		if (componentParameter) {
			if (componentType == "plugins") {
				var pluginName = _utils.getPluginName(componentName);
				componentConfig[componentParameter] = config[pluginName+"."+componentParameter];
				delete config[pluginName+"."+componentParameter];
			} else {
				componentConfig[componentParameter] = config[componentName+"."+componentParameter];
				delete config[componentName+"."+componentParameter];
			}
		}
	}

	rianplayer.embed.deserialize = function(config){
		var pluginNames = getPluginNames(config);

		for (var pluginId in pluginNames) {
			addConfigParameter(config, "plugins", pluginNames[pluginId]);
		}

		for (var parameter in config) {
			if (parameter.indexOf(".") > -1) {
				var path = parameter.split(".");
				var prefix = path[0];
				var parameter = path[1];

				if (_utils.isInArray(components, prefix)) {
					addConfigParameter(config, "components", prefix, parameter);
				} else if (pluginNames[prefix]) {
					addConfigParameter(config, "plugins", pluginNames[prefix], parameter);
				}
			}
		}
		return config;
	}

	rianplayer.embed.config = function(config, embedder) {
		var parsedConfig = _utils.extend({}, config);

		var _tempPlaylist;

		if (_isPlaylist(parsedConfig.playlist)){
			_tempPlaylist = parsedConfig.playlist;
			delete parsedConfig.playlist;
		}

		parsedConfig = rianplayer.embed.deserialize(parsedConfig);

		parsedConfig.height = getSize(parsedConfig.height);
		parsedConfig.width = getSize(parsedConfig.width);

		if (typeof parsedConfig.plugins == "string") {
			var pluginArray = parsedConfig.plugins.split(",");
			if (typeof parsedConfig.plugins != "object") {
				parsedConfig.plugins = {};
			}
			for (var plugin = 0; plugin < pluginArray.length; plugin++) {
				var pluginName = _utils.getPluginName(pluginArray[plugin]);
				if (typeof parsedConfig[pluginName] == "object") {
					parsedConfig.plugins[pluginArray[plugin]] = parsedConfig[pluginName];
					delete parsedConfig[pluginName];
				} else {
					parsedConfig.plugins[pluginArray[plugin]] = {};
				}
			}
		}

		for (var component = 0; component < components.length; component++) {
			var comp = components[component];
			if (_utils.exists(parsedConfig[comp])) {
				if (typeof parsedConfig[comp] != "object") {
					if (!parsedConfig.components[comp]) {
						parsedConfig.components[comp] = {};
					}
					if (comp == "logo") {
						parsedConfig.components[comp].file = parsedConfig[comp];
					} else {
						parsedConfig.components[comp].position = parsedConfig[comp];
					}
					delete parsedConfig[comp];
				} else {
					if (!parsedConfig.components[comp]) {
						parsedConfig.components[comp] = {};
					}
					_utils.extend(parsedConfig.components[comp], parsedConfig[comp]);
					delete parsedConfig[comp];
				}
			}

			if (typeof parsedConfig[comp+"size"] != "undefined") {
				if (!parsedConfig.components[comp]) {
					parsedConfig.components[comp] = {};
				}
				parsedConfig.components[comp].size = parsedConfig[comp+"size"];
				delete parsedConfig[comp+"size"];
			}
		}

		// Special handler for the display icons setting
		if (typeof parsedConfig.icons != "undefined"){
			if (!parsedConfig.components.display) {
					parsedConfig.components.display = {};
				}
			parsedConfig.components.display.icons = parsedConfig.icons;
			delete parsedConfig.icons;
		}

		for (var alias in _aliases)
		if (parsedConfig[alias]) {
			if (!parsedConfig[_aliases[alias]]) {
				parsedConfig[_aliases[alias]] = parsedConfig[alias];
			}
			delete parsedConfig[alias];
		}

		var _modes;
		if (parsedConfig.flashplayer && !parsedConfig.modes) {
			_modes = _playerDefaults(parsedConfig.flashplayer);
			delete parsedConfig.flashplayer;
		} else if (parsedConfig.modes) {
			if (typeof parsedConfig.modes == "string") {
				_modes = _playerDefaults(parsedConfig.modes);
			} else if (parsedConfig.modes instanceof Array) {
				_modes = parsedConfig.modes;
			} else if (typeof parsedConfig.modes == "object" && parsedConfig.modes.type) {
				_modes = [parsedConfig.modes];
			}
			delete parsedConfig.modes;
		} else {
			_modes = _playerDefaults();
		}
		parsedConfig.modes = _modes;

		if (_tempPlaylist) {
			parsedConfig.playlist = _tempPlaylist;
		}

		return parsedConfig;
	};

})(rianplayer);



(function(rianplayer) {

	rianplayer.embed.download = function(_container, _player, _options, _loader, _api) {
		this.embed = function() {
			_container.innerHTML = "";

			var playerOptions = rianplayer.utils.extend({
				screencolor: '0x000000'
			}, _options);

			var toDelete = ["plugins", "modes", "events"];

			for (var i = 0; i < toDelete.length; i++){
				delete playerOptions[toDelete[i]];
			}
			if (_options && _options.containerId)
			var getFlashPlayer = document.getElementById(_options.containerId);
			getFlashPlayer.style.display = 'block';

			return getFlashPlayer;
		};

		this.supportsConfig = function() {
			return true;
		};
	};
})(rianplayer);



/**
 * Flash mode embedder the Rian Player
 * @author Zach
 * @version 5.5
 */
(function(rianplayer) {

	rianplayer.embed.flash = function(_container, _player, _options, _loader, _api) {
		var self = this;
		function appendAttribute(object, name, value) {
			var param = document.createElement('param');
			param.setAttribute('name', name);
			param.setAttribute('value', value);
			object.appendChild(param);
		};

		function jsonToFlashvars(json) {
			var flashvars = '';
			if (json.hasOwnProperty('flashvars') == undefined) return '';
			var configFlashvars = json.flashvars;
			for (var key in configFlashvars) {
				if (typeof(configFlashvars[key]) == "object") {
					flashvars += key + '=' + encodeURIComponent("[[JSON]]"+rianplayer.utils.strings.jsonToString(configFlashvars[key])) + '&';
				} else {
					flashvars += key + '=' + encodeURIComponent(configFlashvars[key]) + '&';
				}
			}
			return flashvars.substring(0, flashvars.length - 1);
		};

		// Check every time, what state has asxLoader
		function asxLoadedHandler(data, type) {
			 //jQMethod
			rianplayer.embed.flash.contentType = $('asx config', data).attr('contenttype');
			rianplayer.embed.flash.videoStatus = $('asx config', data).attr('status');
			rianplayer.embed.flash.videoASXUrl = $('asx entry ref', data).attr('href');

			var smartTagId = $('asx entry param[name=smartag_id]', data).attr('value');

			// Choose player Type
			if (smartTagId) {
				// TODO: ADD smartag video here
			_options.id = _api.id;
			var params = rianplayer.utils.extend({}, _options);
				
				var width = 640;
				var height = 440;
				if (params.size_mode == 'Custom') 
				{
					width = params.width;
					height = params.height;
				}
				
				var smarttagIframe =
					'<iframe style="border:none;width:' +
						width + 'px;height:' +
						height + 'px" ' +
						'src="http://smartag.tv/external/' + smartTagId	+ '" ' +
						'allowFullScreen="true" webkitallowfullscreen="true" mozallowfullscreen="true">' +
					'</iframe>';

				_container.innerHTML = smarttagIframe;

			} else {
				continueEmbed();

				// Start polling LiveViews
				if (rianplayer.embed.flash.contentType == 'live') {
					rianplayer.utils.startLiveViewsPolling({
						mediaId:   _player.config.id,
						articleId: _player.config.article_id
					},updateLiveViews);
				}
			}
		}

		function updateLiveViews(data) {
			if (data.views != undefined && typeof(data.views == 'number')) {
				$('.video_info .html5info' , '.article_video').text("(сейчас смотрят: " + data.views + ")");
			}
		}

		function makePlaylistUrl () {
			var asxLoader = rianplayer.embed.flash.asxLoader;
			var asxURL;

			var mediaType = rianplayer.embed.flash.contentType;
			var playlistUrl = '';
			if (!_player || !_player.config || !_player.config.playlistUrl) return;

			playlistUrl += _player.config.playlistUrl + '?playlist=' + _player.config.playlistParams;

			if (_player.config.article_id) {
				playlistUrl += '&article_id=' + _player.config.article_id;
			}

			if (_player.config.info_id) {
				playlistUrl += '&info_id=' + _player.config.info_id;
			}

			if (_player.config.adv) {
				playlistUrl += '&adv=' + _player.config.adv;
			}

			if (_player.config.directLink) {
				playlistUrl += '&directLink=' + _player.config.directLink;
			}



			playlistUrl += '&' + mediaType +'=1';

			return playlistUrl
		}

		this.embed = function() {

			if (_player && _player.config && _player.config.sourceId) {
				var sourceId = _player.config.sourceId


				if (_player.config.media_type && _player.config.media_type == 'audio') {
					// Check if media_type is audio - skip load ASX
					asxURL = '/aurora/flv/media.aspx?ID=' + sourceId + '&type=MP3';
				} else {
					// load ASX playlist
					asxURL = '/aurora/flv/media.aspx?ID=' + sourceId + '&protocol=RTMP';
				}

				$.ajax({url:asxURL,
					dataType: "xml",
					success: asxLoadedHandler}
				)

				return true;
			} else return false;
		}



		function continueEmbed() {
			// TODO: Make custom SMIL config!
			var playlistUrl = makePlaylistUrl();

			// Make sure we're passing the correct ID into Flash for Linux API support
			_options.id = _api.id;

			var _wrapper;

			var params = rianplayer.utils.extend({}, _options);

			params.flashvars.playlistUrl = playlistUrl;

			var width = params.width;
			var height = params.height;

			// Hack for when adding / removing happens too quickly
			if (_container.id + "_wrapper" == _container.parentNode.id) {
				_wrapper = document.getElementById(_container.id + "_wrapper");
			} else {
				_wrapper = document.createElement("div");
				_wrapper.id = _container.id + "_wrapper";
				_wrapper.className = _container.className;
				rianplayer.utils.wrap(_container, _wrapper);
				rianplayer.utils.css(_wrapper, {
					position: "relative",
					width: width,
					height: height
				});
			}

			var toDelete = ["height", "width", "modes", "events"];

			for (var i = 0; i < toDelete.length; i++) {
				delete params[toDelete[i]];
			}

			var wmode = "opaque";
			if (params.wmode) {
				wmode = params.wmode;
			}


			var flashPlayer;
			if (rianplayer.utils.isIE()) {
				var html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ' +
				'bgcolor="#000000" width="100%" height="100%" ' +
				'id="' +
				_container.id +
				'" name="' +
				_container.id +
				'" tabindex=0"' +
				'">';
				html += '<param name="movie" value="' + _player.src + '">';
				html += '<param name="allowfullscreen" value="true">';
				html += '<param name="allowscriptaccess" value="always">';
				html += '<param name="seamlesstabbing" value="true">';
				html += '<param name="wmode" value="' + wmode + '">';
				html += '<param name="flashvars" value="' +
				jsonToFlashvars(params) +
				'">';
				html += '</object>';

				rianplayer.utils.setOuterHTML(_container, html);

				flashPlayer = document.getElementById(_container.id);
			} else {
				var obj = document.createElement('object');
				obj.setAttribute('type', 'application/x-shockwave-flash');
				obj.setAttribute('data', _player.src);
				obj.setAttribute('width', "100%");
				obj.setAttribute('height', "100%");
				obj.setAttribute('bgcolor', '#000000');
				obj.setAttribute('id', _container.id);
				obj.setAttribute('name', _container.id);
				obj.setAttribute('tabindex', 0);
				appendAttribute(obj, 'allowfullscreen', 'true');
				appendAttribute(obj, 'allowscriptaccess', 'always');
				appendAttribute(obj, 'seamlesstabbing', 'true');
				appendAttribute(obj, 'wmode', wmode);
				appendAttribute(obj, 'flashvars', jsonToFlashvars(params));
				_container.parentNode.replaceChild(obj, _container);
				flashPlayer = obj;
			}

			_api.container = flashPlayer;
			_api.setPlayer(flashPlayer, "flash");
		}
		/**
		 * Detects whether Flash supports this configuration
		 */
		this.supportsConfig = function() {
			if (rianplayer.utils.hasFlash()) {
				if (_options) {
					var item = rianplayer.utils.getFirstPlaylistItemFromConfig(_options);
					if (typeof item.file == "undefined" && typeof item.levels == "undefined") {
						return true;
					} else if (item.file) {
						return flashCanPlay(item.file, item.provider);
					} else if (item.levels && item.levels.length) {
						for (var i = 0; i < item.levels.length; i++) {
							if (item.levels[i].file && flashCanPlay(item.levels[i].file, item.provider)) {
								return true;
							}
						}
					}
				} else {
					return true;
				}
			}
			return false;
		}

		/**
		 * Determines if a Flash can play a particular file, based on its extension
		 */
		flashCanPlay = function(file, provider) {
			var providers = ["video", "http", "sound", "image"];
			// Provider is set, and is not video, http, sound, image - play in Flash
			if (provider && (providers.toString().indexOf(provider) < 0) ) {
				return true;
			}
			var extension = rianplayer.utils.extension(file);
			// If there is no extension, use Flash
			if (!extension) {
				return true;
			}
			// Extension is in the extension map, but not supported by Flash - fail
			if (rianplayer.utils.exists(rianplayer.utils.extensionmap[extension]) &&
					!rianplayer.utils.exists(rianplayer.utils.extensionmap[extension].flash)) {
				return false;
			}
			return true;
		};
	};

})(rianplayer);
/**
 * HTML5 mode embedder for the Rian Player
 * @author Zach
 * @version 5.8
 */
(function(rianplayer) {

	rianplayer.embed.html5 = function(_container, _player, _options, _loader, _api) {

		function _resizePlugin (plugin, div, onready) {
			return function(evt) {
				var displayarea = document.getElementById(_container.id + "_displayarea");
				if (onready) {
					displayarea.appendChild(div);
				}
				plugin.resize(displayarea.clientWidth, displayarea.clientHeight);
				div.left = displayarea.style.left;
				div.top = displayarea.style.top;
			}
		}

		function setSource (src) {
			$('video', rianplayer.html5.html5Video).attr({
				src: src
			});
			// $('video', rianplayer.html5.html5Video).append(sourceTag);
		}

		function forceSetSource(obj) {
			if (obj == undefined || typeof obj != 'object') return;

			if (rianplayer.utils.isIOS() && obj.hasOwnProperty('ios')) {
				setSource(obj.ios)
			}

			if (rianplayer.utils.isAndroid() && obj.hasOwnProperty('android')) {
				setSource(obj.android)
			}
		}

		function asxLoadedHandler(data, type) {
			//jQMethod
			rianplayer.embed.html5.contentType = $('asx config', data).attr('contenttype');
			rianplayer.embed.html5.videoStatus = $('asx config', data).attr('status');
			rianplayer.embed.html5.videoASXUrl = $('asx entry ref', data).attr('href');

			var smartTagId = $('asx entry param[name=smartag_id]', data).attr('value');

			// Choose player Type
			if (smartTagId) {
				// TODO: ADD smartag video here
				_options.id = _api.id;
				var params = rianplayer.utils.extend({}, _options);
				
				var width = 640;
				var height = 440;
				if (params.size_mode == 'Custom') 
				{
					width = params.width;
					height = params.height;
				}
				var smarttagIframe =
					'<iframe style="border:none;width:' +
						width + 'px;height:' +
						height + 'px" ' +
						'src="http://smartag.tv/external/' + smartTagId	+ '" ' +
						'allowFullScreen="true" webkitallowfullscreen="true" mozallowfullscreen="true">' +
					'</iframe>';
				$('video', rianplayer.html5.html5Video).hide();
				rianplayer.html5.html5Video.html(smarttagIframe);
				return;
			} else {
				continueEmbed();
				// Start polling LiveViews
				if (rianplayer.embed.html5.contentType == 'live') {
					rianplayer.utils.startLiveViewsPolling({
						mediaId:   _player.config.id,
						articleId: _player.config.article_id
					},updateLiveViews);
				}
				return;
			}
		}

		function updateLiveViews(data) {
			if (data.views != undefined && typeof(data.views == 'number')) {
				$('.video_info .html5info' , '.article_video').text("(сейчас смотрят: " + data.views + ")");
			}
		}

		function continueEmbed(data,type) {
			$.ajax({
				url:rianplayer.embed.html5.videoASXUrl,
				dataType: "xml",
				success: asxVideoLoadedHandler}
			)
		}

		function asxVideoLoadedHandler (data) {

			rianplayer.embed.html5.contentType = $('asx config', data).attr('contenttype');
			rianplayer.embed.html5.videoStatus = $('asx config', data).attr('status');
			rianplayer.embed.html5.videoUrl = $('asx entry ref', data).attr('href');
			setSource(rianplayer.embed.html5.videoUrl);
		}

		this.embed = function() {
			if (_player && _player.config && _player.config.sourceId) {
				var sourceId = _player.config.sourceId

			} else return false;

			if (_options.hasOwnProperty('containerId')) {
				rianplayer.html5.html5Video = $('#' + _options.containerId);
				containerId = _options.containerId;
			} else {
				throw new Errror('missed containerID attribut for html5 player');
				return;
			}

			var html5video = document.getElementById(containerId);
			// Check for live
			// if (options.hasOwnProperty('live') && options.live && options.hasOwnProperty('sourceId') && options.sourceId) {

			if (rianplayer.utils.isAndroid()) { // Support Stream for Android
				asxURL = '/aurora/flv/media.aspx?ID=' + sourceId + '&protocol=RTSP';
			} else {
				asxURL = '/aurora/flv/media.aspx?ID=' + sourceId + '&protocol=HTTP';
			}

			// Check if forceSource URL is Present
			if (_options.hasOwnProperty('forceSource')) {
				forceSetSource(_options.forceSource);
			} else {
				$.ajax({url:asxURL,
					dataType: "xml",
					success: asxLoadedHandler}
				)
			}


			html5video.style.display = 'block';

			rianplayer.html5.thePlayer = $('video', html5video);

			rianplayer.html5.thePlayer
			.bind('playing', function() {
				$('.html5video_end', html5video).fadeOut();
			})
			.one('play', function(){
				//run handler once for ADRiver
				playerStartHandler();
				rianplayer.html5.checkMidPlay = true;
			})
			.one('ended', function(){
				playerEndHandler();
			})
			.bind('ended', function() {
				//$(this).attr('controls', false);
				$('.html5video_end', html5video).fadeIn();
			})
			.bind('play', function(){
				bindPlayHeadTime();
			})
			.bind('pause', function(){
				unBindPlayHeadTime();
			});

			function playerStartHandler() {
				pingAdRiver('pre');
			}
			function playerMidHandler () {
				pingAdRiver('mid');
			}
			function playerEndHandler() {
				pingAdRiver('post');
			}

			function pingAdRiver(state) {
				if (!state) return;

				var adRiverURL    = 'http://ad.adriver.ru/cgi-bin/rle.cgi',
					arTail       = 'unknown',
					RndNum4NoCash = Math.round(Math.random() * 1000000000),
					sid           = 166081,
					bt            = 21,
					pz            = 0,
					bn            = 28; // default for event 'play'

				if (document.referrer) ar_Tail = escape(document.referrer);

				switch (state) {
					case 'pre':
						bn = 28;
					break;
					case 'mid':
						bn = 29;
					break;
					case 'post':
						bn = 30;
					break;
				}

				var img = $('<img/>').attr({
					src: adRiverURL + '?' +
						'sid='      + sid +
						'&bn='      + bn +
						'&bt='      + bt +
						'&pz='      + pz +
						'&rnd='     + RndNum4NoCash +
						'&tail256=' + arTail,
					border: 0,
					width: 1,
					height: 1
				})

				$('body').append(img);
			}

			function bindPlayHeadTime() {
				if (!rianplayer.html5.playingStatus) {
					rianplayer.html5.playingStatus = true;

					rianplayer.html5.playheadInterval = setInterval(playheadChangeHandler,200)
				}

			}

			function unBindPlayHeadTime() {
				if (rianplayer.html5.playingStatus) {
					rianplayer.html5.playingStatus = false;
					clearInterval(rianplayer.html5.playheadInterval);
				}
			}

			function playheadChangeHandler() {
				rianplayer.html5.totalTime   = rianplayer.html5.thePlayer.prop('duration');
				rianplayer.html5.currentTime = rianplayer.html5.thePlayer.prop('currentTime');

				if (rianplayer.html5.checkMidPlay && rianplayer.html5.currentTime >= rianplayer.html5.totalTime * 0.5) {
					rianplayer.html5.checkMidPlay = false;
					playerMidHandler();
				}
			}

			if (rianplayer.html5) {
				_loader.setupPlugins(_api, _options, _resizePlugin);
				_container.innerHTML = "";


				var playerOptions = rianplayer.utils.extend({
					screencolor: '0x000000'
				}, _options);

				var toDelete = ["plugins", "modes", "events"];

				for (var i = 0; i < toDelete.length; i++){
					delete playerOptions[toDelete[i]];
				}
				// TODO: remove this requirement from the html5 _player (sources instead of levels)
				if (playerOptions.levels && !playerOptions.sources) {
					playerOptions.sources = _options.levels;
				}

				var html5player = new rianplayer.html5(_container,_options);
				_api.container = document.getElementById(_api.id);
				_api.setPlayer(html5player, "html5");
			} else {
				return null;
			}
		}

		/**
		 * Detects whether the html5 player supports this configuration.
		 *
		 * @return {Boolean}
		 */
		this.supportsConfig = function() {
			if (!rianplayer.utils.isMobile()) {
				return false;
			}
			if (!!rianplayer.vid.canPlayType) {
				if (_options) {
					var item = rianplayer.utils.getFirstPlaylistItemFromConfig(_options);
					if (typeof item.file == "undefined" && typeof item.levels == "undefined") {
						return true;
					} else if (item.file) {
						return html5CanPlay(rianplayer.vid, item.file, item.provider, item.playlistfile);
					} else if (item.levels && item.levels.length) {
						for (var i = 0; i < item.levels.length; i++) {
							if (item.levels[i].file && html5CanPlay(rianplayer.vid, item.levels[i].file, item.provider, item.playlistfile)) {
								return true;
							}
						}
					}
				} else {
					return true;
				}
			}

			return false;
		}

		/**
		 * Determines if a video element can play a particular file, based on its extension
		 * @param {Object} video
		 * @param {Object} file
		 * @param {Object} provider
		 * @param {Object} playlistfile
		 * @return {Boolean}
		 */
		html5CanPlay = function(video, file, provider, playlistfile) {
			// Don't support playlists
			if (playlistfile) {
				return false;
			}

			// YouTube is supported
			if (provider && provider == "youtube") {
				return true;
			}

			// If a provider is set, only proceed if video or HTTP or sound
			if (provider && provider != "video" && provider != "http" && provider != "sound") {
				return false;
			}

			// HTML5 playback is not sufficiently supported on Blackberry devices; should fail over automatically.
			if(navigator.userAgent.match(/BlackBerry/i) !== null) { return false; }

			var extension = rianplayer.utils.extension(file);
			// If no extension or unrecognized extension, allow to play
			if (!rianplayer.utils.exists(extension) || !rianplayer.utils.exists(rianplayer.utils.extensionmap[extension])){
				return true;
			}

			// If extension is defined but not supported by HTML5, don't play
			if (!rianplayer.utils.exists(rianplayer.utils.extensionmap[extension].html5)) {
				return false;
			}

			// Check for Android, which returns false for canPlayType
			if (rianplayer.utils.isLegacyAndroid() && extension.match(/m4v|mp4/)) {
				return true;
			}

			// Last, but not least, we ask the browser
			// (But only if it's a video with an extension known to work in HTML5)
			return browserCanPlay(video, rianplayer.utils.extensionmap[extension].html5);
		};

		/**
		 *
		 * @param {DOMMediaElement} video
		 * @param {String} mimetype
		 * @return {Boolean}
		 */
		browserCanPlay = function(video, mimetype) {
			// OK to use HTML5 with no extension
			if (!mimetype) {
				return true;
			}

			if (video.canPlayType(mimetype)) {
				return true;
			} else if (mimetype == "audio/mp3" && navigator.userAgent.match(/safari/i)) {
				// Work around Mac Safari bug
				return video.canPlayType("audio/mpeg");
			} else {
				return false;
			}

		}
	};

})(rianplayer);

/**
 * Core component of the Rian Player (initialization, API).
 */
(function(rianplayer) {
	rianplayer.html5 = function(container,options) {
		if (!options.hasOwnProperty('containerId')) {
			throw('missed required property "containerId" in rianplayer.html5 (4129)');
			return false;
		}
		var _container = container,
		_options =  options;

		return this;
	};

})(rianplayer);
}

